about summary refs log tree commit diff
path: root/configs/shared/emacs/.emacs.d
diff options
context:
space:
mode:
authorWilliam Carroll <wpcarro@gmail.com>2018-09-10T18·51-0400
committerWilliam Carroll <wpcarro@gmail.com>2018-09-10T18·53-0400
commit17ee0e400bef47c371afcae76037f9ea6a44ad13 (patch)
tree0e5efee6f00e402890e91f3eceb4b29408a498b6 /configs/shared/emacs/.emacs.d
parent8b2fadf4776b7ddb4a67b4bc8ff6463770e56028 (diff)
Support Vim, Tmux, Emacs with Stow
After moving off of Meta, Dotfiles has a greater responsibility to
manage configs. Vim, Tmux, and Emacs are now within Stow's purview.
Diffstat (limited to 'configs/shared/emacs/.emacs.d')
-rw-r--r--configs/shared/emacs/.emacs.d/auto-save-list/.saves-15593-wpc-mbp~0
-rw-r--r--configs/shared/emacs/.emacs.d/auto-save-list/.saves-18355-wpc-mbp~0
-rw-r--r--configs/shared/emacs/.emacs.d/auto-save-list/.saves-32097-wpc-mbp~0
-rw-r--r--configs/shared/emacs/.emacs.d/auto-save-list/.saves-8187-wpc-mbp~0
-rw-r--r--configs/shared/emacs/.emacs.d/bookmarks15
-rw-r--r--configs/shared/emacs/.emacs.d/custom.el52
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/ace-window-20180607.1223/ace-window-autoloads.el68
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/ace-window-20180607.1223/ace-window-pkg.el2
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/ace-window-20180607.1223/ace-window.el802
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/ace-window-20180607.1223/ace-window.elcbin0 -> 24056 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/add-node-modules-path-20180710.2342/add-node-modules-path-autoloads.el35
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/add-node-modules-path-20180710.2342/add-node-modules-path-pkg.el2
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/add-node-modules-path-20180710.2342/add-node-modules-path.el79
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/add-node-modules-path-20180710.2342/add-node-modules-path.elcbin0 -> 1688 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/alert-20180403.38/alert-autoloads.el94
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/alert-20180403.38/alert-pkg.el2
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/alert-20180403.38/alert.el1161
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/alert-20180403.38/alert.elcbin0 -> 41694 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/all-the-icons-20180125.757/all-the-icons-autoloads.el59
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/all-the-icons-20180125.757/all-the-icons-faces.el225
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/all-the-icons-20180125.757/all-the-icons-faces.elcbin0 -> 6114 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/all-the-icons-20180125.757/all-the-icons-pkg.el9
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/all-the-icons-20180125.757/all-the-icons.el832
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/all-the-icons-20180125.757/all-the-icons.elcbin0 -> 46626 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/all-the-icons-20180125.757/data/data-alltheicons.el70
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/all-the-icons-20180125.757/data/data-alltheicons.elcbin0 -> 1736 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/all-the-icons-20180125.757/data/data-faicons.el641
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/all-the-icons-20180125.757/data/data-faicons.elcbin0 -> 14556 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/all-the-icons-20180125.757/data/data-fileicons.el487
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/all-the-icons-20180125.757/data/data-fileicons.elcbin0 -> 9574 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/all-the-icons-20180125.757/data/data-material.el935
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/all-the-icons-20180125.757/data/data-material.elcbin0 -> 23295 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/all-the-icons-20180125.757/data/data-octicons.el165
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/all-the-icons-20180125.757/data/data-octicons.elcbin0 -> 3904 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/all-the-icons-20180125.757/data/data-weathericons.el594
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/all-the-icons-20180125.757/data/data-weathericons.elcbin0 -> 14994 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/all-the-icons-ivy-20180225.630/all-the-icons-ivy-autoloads.el22
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/all-the-icons-ivy-20180225.630/all-the-icons-ivy-pkg.el2
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/all-the-icons-ivy-20180225.630/all-the-icons-ivy.el107
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/all-the-icons-ivy-20180225.630/all-the-icons-ivy.elcbin0 -> 3336 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/archives/gnu/archive-contents1293
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/archives/gnu/archive-contents.signed1
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/archives/melpa/archive-contents2
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/async-20180527.1030/async-autoloads.el158
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/async-20180527.1030/async-bytecomp.el219
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/async-20180527.1030/async-bytecomp.elcbin0 -> 7826 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/async-20180527.1030/async-pkg.el6
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/async-20180527.1030/async.el392
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/async-20180527.1030/async.elcbin0 -> 11435 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/async-20180527.1030/dired-async.el405
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/async-20180527.1030/dired-async.elcbin0 -> 13697 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/async-20180527.1030/smtpmail-async.el73
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/async-20180527.1030/smtpmail-async.elcbin0 -> 1589 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/avy-20180615.801/avy-autoloads.el253
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/avy-20180615.801/avy-pkg.el2
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/avy-20180615.801/avy.el2001
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/avy-20180615.801/avy.elcbin0 -> 71490 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/bind-key-20180512.2130/bind-key-autoloads.el79
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/bind-key-20180512.2130/bind-key-pkg.el2
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/bind-key-20180512.2130/bind-key.el455
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/bind-key-20180512.2130/bind-key.elcbin0 -> 10971 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-apropos.el208
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-apropos.elcbin0 -> 7862 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-autoloads.el607
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-browse-ns.el232
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-browse-ns.elcbin0 -> 9612 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-browse-spec.el357
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-browse-spec.elcbin0 -> 18440 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-cheatsheet.el577
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-cheatsheet.elcbin0 -> 18044 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-classpath.el112
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-classpath.elcbin0 -> 5483 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-client.el577
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-client.elcbin0 -> 21529 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-common.el375
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-common.elcbin0 -> 12591 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-compat.el54
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-compat.elcbin0 -> 1457 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-completion.el253
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-completion.elcbin0 -> 8065 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-connection.el646
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-connection.elcbin0 -> 23008 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-debug.el755
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-debug.elcbin0 -> 25213 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-doc.el533
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-doc.elcbin0 -> 18047 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-eldoc.el481
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-eldoc.elcbin0 -> 13921 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-eval.el1098
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-eval.elcbin0 -> 39442 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-find.el220
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-find.elcbin0 -> 7873 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-format.el150
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-format.elcbin0 -> 3849 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-grimoire.el130
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-grimoire.elcbin0 -> 3711 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-inspector.el397
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-inspector.elcbin0 -> 15407 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-macroexpansion.el206
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-macroexpansion.elcbin0 -> 8154 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-mode.el1026
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-mode.elcbin0 -> 37148 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-ns.el207
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-ns.elcbin0 -> 7842 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-overlays.el311
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-overlays.elcbin0 -> 10222 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-pkg.el14
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-popup.el137
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-popup.elcbin0 -> 5345 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-profile.el208
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-profile.elcbin0 -> 6807 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-repl-history.el726
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-repl-history.elcbin0 -> 25989 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-repl.el1747
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-repl.elcbin0 -> 65863 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-resolve.el130
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-resolve.elcbin0 -> 2657 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-scratch.el98
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-scratch.elcbin0 -> 5452 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-selector.el165
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-selector.elcbin0 -> 7710 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-stacktrace.el899
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-stacktrace.elcbin0 -> 33851 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-test.el825
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-test.elcbin0 -> 30179 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-tracing.el90
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-tracing.elcbin0 -> 2701 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-util.el849
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-util.elcbin0 -> 32250 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider.el1309
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider.elcbin0 -> 48651 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/nrepl-client.el1371
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/nrepl-client.elcbin0 -> 53985 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/nrepl-dict.el187
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/nrepl-dict.elcbin0 -> 5455 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/circe-autoloads.el226
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/circe-chanop.el97
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/circe-chanop.elcbin0 -> 2336 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/circe-color-nicks.el340
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/circe-color-nicks.elcbin0 -> 11221 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/circe-compat.el53
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/circe-compat.elcbin0 -> 1242 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/circe-display-images.el197
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/circe-display-images.elcbin0 -> 5904 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/circe-lagmon.el243
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/circe-lagmon.elcbin0 -> 7888 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/circe-new-day-notifier.el86
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/circe-new-day-notifier.elcbin0 -> 1933 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/circe-pkg.el6
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/circe.el3602
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/circe.elcbin0 -> 121997 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/irc.el1413
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/irc.elcbin0 -> 60848 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/lcs.el202
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/lcs.elcbin0 -> 3292 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/lui-autopaste.el115
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/lui-autopaste.elcbin0 -> 3197 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/lui-format.el198
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/lui-format.elcbin0 -> 5257 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/lui-irc-colors.el182
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/lui-irc-colors.elcbin0 -> 4448 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/lui-logging.el201
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/lui-logging.elcbin0 -> 6174 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/lui-track-bar.el110
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/lui-track-bar.elcbin0 -> 2837 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/lui.el1513
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/lui.elcbin0 -> 40430 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/make-tls-process.el194
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/make-tls-process.elcbin0 -> 6130 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/shorten.el223
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/shorten.elcbin0 -> 6362 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/tracking.el428
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/tracking.elcbin0 -> 12739 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/clojure-mode-20180709.648/clojure-mode-autoloads.el144
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/clojure-mode-20180709.648/clojure-mode-pkg.el2
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/clojure-mode-20180709.648/clojure-mode.el2596
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/clojure-mode-20180709.648/clojure-mode.elcbin0 -> 84175 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-abbrev.el50
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-abbrev.elcbin0 -> 1172 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-autoloads.el318
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-bbdb.el61
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-bbdb.elcbin0 -> 1721 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-capf.el189
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-capf.elcbin0 -> 3785 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-clang.el350
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-clang.elcbin0 -> 13557 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-cmake.el206
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-cmake.elcbin0 -> 6064 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-css.el446
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-css.elcbin0 -> 16947 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-dabbrev-code.el104
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-dabbrev-code.elcbin0 -> 3583 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-dabbrev.el206
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-dabbrev.elcbin0 -> 6900 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-eclim.el186
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-eclim.elcbin0 -> 5478 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-elisp.el226
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-elisp.elcbin0 -> 6590 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-etags.el108
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-etags.elcbin0 -> 3110 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-files.el148
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-files.elcbin0 -> 4377 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-gtags.el117
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-gtags.elcbin0 -> 3667 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-ispell.el82
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-ispell.elcbin0 -> 1965 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-keywords.el300
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-keywords.elcbin0 -> 17818 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-nxml.el143
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-nxml.elcbin0 -> 4226 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-oddmuse.el57
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-oddmuse.elcbin0 -> 1425 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-pkg.el8
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-semantic.el168
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-semantic.elcbin0 -> 5239 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-template.el260
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-template.elcbin0 -> 8036 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-tempo.el71
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-tempo.elcbin0 -> 2235 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-tng.el174
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-tng.elcbin0 -> 4261 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-xcode.el123
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-xcode.elcbin0 -> 3743 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-yasnippet.el147
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-yasnippet.elcbin0 -> 3494 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company.el3182
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company.elcbin0 -> 103610 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/company-flow-20180225.1359/company-flow-autoloads.el22
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/company-flow-20180225.1359/company-flow-pkg.el2
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/company-flow-20180225.1359/company-flow.el209
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/company-flow-20180225.1359/company-flow.elcbin0 -> 6524 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/company-lsp-20180828.438/company-lsp-autoloads.el24
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/company-lsp-20180828.438/company-lsp-pkg.el2
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/company-lsp-20180828.438/company-lsp.el435
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/company-lsp-20180828.438/company-lsp.elcbin0 -> 16679 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/counsel-20180719.1303/counsel-autoloads.el430
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/counsel-20180719.1303/counsel-pkg.el2
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/counsel-20180719.1303/counsel.el4668
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/counsel-20180719.1303/counsel.elcbin0 -> 151861 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/counsel-projectile-20180718.842/counsel-projectile-autoloads.el122
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/counsel-projectile-20180718.842/counsel-projectile-pkg.el2
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/counsel-projectile-20180718.842/counsel-projectile.el1408
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/counsel-projectile-20180718.842/counsel-projectile.elcbin0 -> 51608 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cycle-themes-20150402.2009/cycle-themes-autoloads.el32
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cycle-themes-20150402.2009/cycle-themes-pkg.el2
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cycle-themes-20150402.2009/cycle-themes.el155
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/cycle-themes-20150402.2009/cycle-themes.elcbin0 -> 4479 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/dash-20180413.30/dash-autoloads.el15
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/dash-20180413.30/dash-pkg.el2
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/dash-20180413.30/dash.el2800
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/dash-20180413.30/dash.elcbin0 -> 93133 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/dash-functional-20180107.818/dash-functional-autoloads.el16
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/dash-functional-20180107.818/dash-functional-pkg.el2
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/dash-functional-20180107.818/dash-functional.el219
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/dash-functional-20180107.818/dash-functional.elcbin0 -> 9073 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/diminish-20170419.1036/diminish-autoloads.el57
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/diminish-20170419.1036/diminish-pkg.el2
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/diminish-20170419.1036/diminish.el294
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/diminish-20170419.1036/diminish.elcbin0 -> 4615 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/docker-20180710.743/docker-autoloads.el256
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/docker-20180710.743/docker-container.el478
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/docker-20180710.743/docker-container.elcbin0 -> 32273 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/docker-20180710.743/docker-image.el245
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/docker-20180710.743/docker-image.elcbin0 -> 15362 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/docker-20180710.743/docker-machine.el260
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/docker-20180710.743/docker-machine.elcbin0 -> 16437 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/docker-20180710.743/docker-network.el106
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/docker-20180710.743/docker-network.elcbin0 -> 7083 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/docker-20180710.743/docker-pkg.el14
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/docker-20180710.743/docker-process.el48
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/docker-20180710.743/docker-process.elcbin0 -> 1171 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/docker-20180710.743/docker-utils.el73
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/docker-20180710.743/docker-utils.elcbin0 -> 2423 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/docker-20180710.743/docker-volume.el121
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/docker-20180710.743/docker-volume.elcbin0 -> 7588 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/docker-20180710.743/docker.el51
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/docker-20180710.743/docker.elcbin0 -> 1480 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/docker-tramp-20170206.1925/docker-tramp-autoloads.el45
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/docker-tramp-20170206.1925/docker-tramp-compat.el87
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/docker-tramp-20170206.1925/docker-tramp-compat.elcbin0 -> 5144 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/docker-tramp-20170206.1925/docker-tramp-pkg.el9
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/docker-tramp-20170206.1925/docker-tramp.el156
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/docker-tramp-20170206.1925/docker-tramp.elcbin0 -> 3759 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/dockerfile-mode-20180628.959/dockerfile-mode-autoloads.el36
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/dockerfile-mode-20180628.959/dockerfile-mode-pkg.el2
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/dockerfile-mode-20180628.959/dockerfile-mode.el188
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/dockerfile-mode-20180628.959/dockerfile-mode.elcbin0 -> 8712 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-challenger-deep-theme.el164
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-challenger-deep-theme.elcbin0 -> 206727 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-city-lights-theme.el164
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-city-lights-theme.elcbin0 -> 209303 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-dracula-theme.el212
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-dracula-theme.elcbin0 -> 232185 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-molokai-theme.el171
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-molokai-theme.elcbin0 -> 199193 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-nord-light-theme.el189
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-nord-light-theme.elcbin0 -> 229176 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-nord-theme.el190
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-nord-theme.elcbin0 -> 228338 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-nova-theme.el160
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-nova-theme.elcbin0 -> 198093 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-one-light-theme.el199
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-one-light-theme.elcbin0 -> 217083 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-one-theme.el167
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-one-theme.elcbin0 -> 227980 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-opera-light-theme.el145
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-opera-light-theme.elcbin0 -> 228039 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-opera-theme.el145
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-opera-theme.elcbin0 -> 228154 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-peacock-theme.el185
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-peacock-theme.elcbin0 -> 228529 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-solarized-light-theme.el185
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-solarized-light-theme.elcbin0 -> 220272 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-spacegrey-theme.el182
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-spacegrey-theme.elcbin0 -> 227696 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-themes-autoloads.el101
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-themes-common.el1377
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-themes-common.elcbin0 -> 54997 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-themes-neotree.el359
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-themes-neotree.elcbin0 -> 12298 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-themes-org.el86
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-themes-org.elcbin0 -> 3381 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-themes-pkg.el10
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-themes-treemacs.el115
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-themes-treemacs.elcbin0 -> 4307 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-themes.el270
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-themes.elcbin0 -> 7010 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-tomorrow-day-theme.el121
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-tomorrow-day-theme.elcbin0 -> 196430 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-tomorrow-night-theme.el108
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-tomorrow-night-theme.elcbin0 -> 196580 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-vibrant-theme.el162
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-vibrant-theme.elcbin0 -> 229621 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/elisp-slime-nav-20160128.1109/elisp-slime-nav-autoloads.el49
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/elisp-slime-nav-20160128.1109/elisp-slime-nav-pkg.el2
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/elisp-slime-nav-20160128.1109/elisp-slime-nav.el140
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/elisp-slime-nav-20160128.1109/elisp-slime-nav.elcbin0 -> 4308 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/emojify-20180611.838/data/emoji-sets.json26
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/emojify-20180611.838/data/emoji.json31306
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/emojify-20180611.838/emojify-autoloads.el95
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/emojify-20180611.838/emojify-pkg.el10
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/emojify-20180611.838/emojify.el2122
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/emojify-20180611.838/emojify.elcbin0 -> 87632 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/engine-mode-20180401.946/engine-mode-autoloads.el71
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/engine-mode-20180401.946/engine-mode-pkg.el2
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/engine-mode-20180401.946/engine-mode.el178
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/engine-mode-20180401.946/engine-mode.elcbin0 -> 6745 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/epl-20180205.1249/epl-autoloads.el15
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/epl-20180205.1249/epl-pkg.el2
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/epl-20180205.1249/epl.el711
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/epl-20180205.1249/epl.elcbin0 -> 32585 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/dir18
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-autoloads.el27
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-command-window.el168
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-command-window.elcbin0 -> 7362 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-commands.el4496
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-commands.elcbin0 -> 260102 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-common.el3883
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-common.elcbin0 -> 116872 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-core.el1363
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-core.elcbin0 -> 43496 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-development.el50
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-development.elcbin0 -> 863 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-digraphs.el1729
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-digraphs.elcbin0 -> 30821 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-ex.el1163
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-ex.elcbin0 -> 31552 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-integration.el588
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-integration.elcbin0 -> 37003 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-jumps.el318
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-jumps.elcbin0 -> 14201 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-macros.el777
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-macros.elcbin0 -> 20654 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-maps.el560
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-maps.elcbin0 -> 22577 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-pkg.el8
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-repeat.el638
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-repeat.elcbin0 -> 17324 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-search.el1294
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-search.elcbin0 -> 40383 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-states.el903
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-states.elcbin0 -> 56954 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-types.el424
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-types.elcbin0 -> 17615 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-vars.el1879
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-vars.elcbin0 -> 60771 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil.el148
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil.elcbin0 -> 878 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil.info1215
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/fdl-1.3.info484
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/macros.info7
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/version.info8
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-ace-jump-mode.el148
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-ace-jump-mode.elcbin0 -> 9572 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-ag.el62
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-ag.elcbin0 -> 1190 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-alchemist.el113
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-alchemist.elcbin0 -> 2860 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-anaconda-mode.el63
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-anaconda-mode.elcbin0 -> 1270 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-arc-mode.el76
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-arc-mode.elcbin0 -> 1510 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-autoloads.el115
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-avy.el121
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-avy.elcbin0 -> 17115 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-bookmark.el78
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-bookmark.elcbin0 -> 1832 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-buff-menu.el121
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-buff-menu.elcbin0 -> 3914 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-calc.el173
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-calc.elcbin0 -> 4129 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-calendar.el104
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-calendar.elcbin0 -> 2369 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-cider.el213
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-cider.elcbin0 -> 7508 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-cmake-mode.el43
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-cmake-mode.elcbin0 -> 962 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-comint.el54
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-comint.elcbin0 -> 991 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-company.el82
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-company.elcbin0 -> 1902 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-compile.el60
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-compile.elcbin0 -> 1329 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-cus-theme.el64
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-cus-theme.elcbin0 -> 1221 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-custom.el67
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-custom.elcbin0 -> 1203 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-daemons.el67
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-daemons.elcbin0 -> 1279 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-debbugs.el75
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-debbugs.elcbin0 -> 1477 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-debug.el69
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-debug.elcbin0 -> 1336 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-diff-mode.el143
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-diff-mode.elcbin0 -> 3242 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-dired.el190
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-dired.elcbin0 -> 5614 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-doc-view.el83
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-doc-view.elcbin0 -> 1877 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-edebug.el124
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-edebug.elcbin0 -> 2757 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-ediff.el204
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-ediff.elcbin0 -> 6029 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-eldoc.el39
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-eldoc.elcbin0 -> 700 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-elfeed.el120
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-elfeed.elcbin0 -> 2246 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-elisp-mode.el78
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-elisp-mode.elcbin0 -> 2379 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-elisp-refs.el51
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-elisp-refs.elcbin0 -> 987 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-emms.el234
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-emms.elcbin0 -> 6128 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-epa.el70
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-epa.elcbin0 -> 1257 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-ert.el69
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-ert.elcbin0 -> 1697 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-eshell.el96
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-eshell.elcbin0 -> 2271 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-etags-select.el40
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-etags-select.elcbin0 -> 775 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-eval-sexp-fu.el60
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-eval-sexp-fu.elcbin0 -> 1596 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-eww.el152
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-eww.elcbin0 -> 2828 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-flycheck.el55
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-flycheck.elcbin0 -> 1258 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-free-keys.el52
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-free-keys.elcbin0 -> 1288 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-geiser.el103
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-geiser.elcbin0 -> 2363 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-ggtags.el99
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-ggtags.elcbin0 -> 2036 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-git-timemachine.el48
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-git-timemachine.elcbin0 -> 1189 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-go-mode.el46
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-go-mode.elcbin0 -> 909 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-grep.el44
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-grep.elcbin0 -> 834 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-guix.el209
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-guix.elcbin0 -> 7239 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-helm.el211
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-helm.elcbin0 -> 4403 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-help.el74
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-help.elcbin0 -> 1250 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-ibuffer.el196
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-ibuffer.elcbin0 -> 6354 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-image+.el53
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-image+.elcbin0 -> 1094 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-image.el91
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-image.elcbin0 -> 1750 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-imenu-list.el46
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-imenu-list.elcbin0 -> 971 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-indium.el133
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-indium.elcbin0 -> 3245 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-info.el110
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-info.elcbin0 -> 2222 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-integration.el313
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-integration.elcbin0 -> 9134 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-ivy.el110
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-ivy.elcbin0 -> 2186 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-js2-mode.el45
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-js2-mode.elcbin0 -> 975 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-kotlin-mode.el41
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-kotlin-mode.elcbin0 -> 806 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-lispy.el211
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-lispy.elcbin0 -> 6183 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-log-view.el55
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-log-view.elcbin0 -> 1207 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-lsp-ui-imenu.el46
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-lsp-ui-imenu.elcbin0 -> 1043 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-lua-mode.el49
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-lua-mode.elcbin0 -> 1098 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-macrostep.el51
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-macrostep.elcbin0 -> 1038 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-magit-todos.el52
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-magit-todos.elcbin0 -> 1208 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-magit.el47
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-magit.elcbin0 -> 795 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-man.el67
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-man.elcbin0 -> 1270 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-minibuffer.el75
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-minibuffer.elcbin0 -> 1868 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-mu4e-conversation.el74
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-mu4e-conversation.elcbin0 -> 2022 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-mu4e.el337
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-mu4e.elcbin0 -> 8254 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-neotree.el100
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-notmuch.el178
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-notmuch.elcbin0 -> 5164 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-nov.el66
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-nov.elcbin0 -> 1298 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-occur.el73
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-occur.elcbin0 -> 1388 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-outline.el97
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-outline.elcbin0 -> 2038 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-p4.el57
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-p4.elcbin0 -> 1234 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-package-menu.el55
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-package-menu.elcbin0 -> 1089 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-paren.el76
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-paren.elcbin0 -> 1591 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-pass.el59
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-pass.elcbin0 -> 1192 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-pdf.el281
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-pdf.elcbin0 -> 7244 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-pkg.el10
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-popup.el43
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-popup.elcbin0 -> 809 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-proced.el92
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-proced.elcbin0 -> 1728 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-prodigy.el79
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-prodigy.elcbin0 -> 1618 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-profiler.el70
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-profiler.elcbin0 -> 1463 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-python.el47
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-python.elcbin0 -> 1070 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-quickrun.el41
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-quickrun.elcbin0 -> 802 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-racer.el47
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-racer.elcbin0 -> 923 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-realgud.el102
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-realgud.elcbin0 -> 2311 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-reftex.el141
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-reftex.elcbin0 -> 4485 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-rjsx-mode.el46
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-rjsx-mode.elcbin0 -> 885 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-robe.el44
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-robe.elcbin0 -> 851 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-rtags.el140
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-rtags.elcbin0 -> 2776 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-ruby-mode.el44
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-ruby-mode.elcbin0 -> 954 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-settings.el45
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-settings.elcbin0 -> 1009 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-simple.el47
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-simple.elcbin0 -> 900 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-slime.el182
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-slime.elcbin0 -> 4789 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-term.el159
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-term.elcbin0 -> 3995 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-tide.el65
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-tide.elcbin0 -> 1302 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-transmission.el172
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-transmission.elcbin0 -> 3090 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-typescript-mode.el45
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-typescript-mode.elcbin0 -> 981 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-vc-annotate.el58
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-vc-annotate.elcbin0 -> 1432 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-vdiff.el66
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-vdiff.elcbin0 -> 1341 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-view.el53
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-view.elcbin0 -> 1025 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-vlf.el77
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-vlf.elcbin0 -> 1509 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-wdired.el46
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-wdired.elcbin0 -> 891 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-wgrep.el48
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-wgrep.elcbin0 -> 895 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-which-key.el51
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-which-key.elcbin0 -> 939 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-woman.el50
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-woman.elcbin0 -> 930 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-xref.el54
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-xref.elcbin0 -> 1036 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-ztree.el72
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-ztree.elcbin0 -> 1524 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection.el496
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection.elcbin0 -> 14225 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-commentary-20170413.751/evil-commentary-autoloads.el45
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-commentary-20170413.751/evil-commentary-integration.el37
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-commentary-20170413.751/evil-commentary-integration.elcbin0 -> 1903 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-commentary-20170413.751/evil-commentary-pkg.el8
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-commentary-20170413.751/evil-commentary.el121
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-commentary-20170413.751/evil-commentary.elcbin0 -> 8737 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-leader-20140606.543/evil-leader-autoloads.el42
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-leader-20140606.543/evil-leader-pkg.el2
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-leader-20140606.543/evil-leader.el213
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-leader-20140606.543/evil-leader.elcbin0 -> 7027 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-surround-20180102.601/evil-surround-autoloads.el70
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-surround-20180102.601/evil-surround-pkg.el2
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-surround-20180102.601/evil-surround.el436
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-surround-20180102.601/evil-surround.elcbin0 -> 20803 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-text-objects-haskell-20180316.1833/evil-text-objects-haskell-autoloads.el16
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-text-objects-haskell-20180316.1833/evil-text-objects-haskell-pkg.el2
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-text-objects-haskell-20180316.1833/evil-text-objects-haskell.el132
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-text-objects-javascript-20180330.1320/evil-text-objects-javascript-autoloads.el16
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-text-objects-javascript-20180330.1320/evil-text-objects-javascript-pkg.el2
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-text-objects-javascript-20180330.1320/evil-text-objects-javascript.el163
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/evil-text-objects-javascript-20180330.1320/evil-text-objects-javascript.elcbin0 -> 17147 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/exec-path-from-shell-20180323.1904/exec-path-from-shell-autoloads.el44
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/exec-path-from-shell-20180323.1904/exec-path-from-shell-pkg.el2
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/exec-path-from-shell-20180323.1904/exec-path-from-shell.el272
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/exec-path-from-shell-20180323.1904/exec-path-from-shell.elcbin0 -> 7969 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/f-20180106.122/f-autoloads.el15
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/f-20180106.122/f-pkg.el2
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/f-20180106.122/f.el624
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/f-20180106.122/f.elcbin0 -> 20673 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/flow-minor-mode-20180315.1124/flow-minor-mode-autoloads.el27
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/flow-minor-mode-20180315.1124/flow-minor-mode-pkg.el2
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/flow-minor-mode-20180315.1124/flow-minor-mode.el323
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/flow-minor-mode-20180315.1124/flow-minor-mode.elcbin0 -> 10929 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/flx-20151030.1112/flx-autoloads.el15
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/flx-20151030.1112/flx-pkg.el2
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/flx-20151030.1112/flx.el420
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/flx-20151030.1112/flx.elcbin0 -> 8646 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/flx-ido-20180117.719/flx-ido-autoloads.el29
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/flx-ido-20180117.719/flx-ido-pkg.el2
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/flx-ido-20180117.719/flx-ido.el292
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/flx-ido-20180117.719/flx-ido.elcbin0 -> 8497 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/flycheck-20180720.247/flycheck-autoloads.el240
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/flycheck-20180720.247/flycheck-buttercup.el157
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/flycheck-20180720.247/flycheck-ert.el483
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/flycheck-20180720.247/flycheck-ert.elcbin0 -> 22211 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/flycheck-20180720.247/flycheck-pkg.el12
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/flycheck-20180720.247/flycheck.el10446
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/flycheck-20180720.247/flycheck.elcbin0 -> 451005 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/flycheck-flow-20180216.1156/flycheck-flow-autoloads.el16
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/flycheck-flow-20180216.1156/flycheck-flow-pkg.el2
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/flycheck-flow-20180216.1156/flycheck-flow.el174
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/flycheck-flow-20180216.1156/flycheck-flow.elcbin0 -> 4729 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/general-20180628.1112/general-autoloads.el368
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/general-20180628.1112/general-pkg.el2
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/general-20180628.1112/general.el2469
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/ghub-20180715.1159/dir18
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/ghub-20180715.1159/ghub-autoloads.el37
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/ghub-20180715.1159/ghub-pkg.el9
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/ghub-20180715.1159/ghub.el849
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/ghub-20180715.1159/ghub.elcbin0 -> 43993 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/ghub-20180715.1159/ghub.info1002
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/git-commit-20180713.1444/git-commit-autoloads.el48
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/git-commit-20180713.1444/git-commit-pkg.el2
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/git-commit-20180713.1444/git-commit.el881
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/git-commit-20180713.1444/git-commit.elcbin0 -> 29318 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/git-timemachine-20180607.120/git-timemachine-autoloads.el32
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/git-timemachine-20180607.120/git-timemachine-pkg.el2
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/git-timemachine-20180607.120/git-timemachine.el395
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/git-timemachine-20180607.120/git-timemachine.elcbin0 -> 15180 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/gntp-20141024.1950/gntp-autoloads.el22
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/gntp-20141024.1950/gntp-pkg.el2
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/gntp-20141024.1950/gntp.el243
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/gntp-20141024.1950/gntp.elcbin0 -> 5962 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/gnupg/pubring.kbxbin0 -> 1177 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/gnupg/pubring.kbx~bin0 -> 32 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/gnupg/trustdb.gpgbin0 -> 1200 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/goto-chg-20180105.1033/goto-chg-autoloads.el50
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/goto-chg-20180105.1033/goto-chg-pkg.el2
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/goto-chg-20180105.1033/goto-chg.el360
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/goto-chg-20180105.1033/goto-chg.elcbin0 -> 7442 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/NEWS600
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/dir18
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/ghc-core.el123
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/ghc-core.elcbin0 -> 5566 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/ghci-script-mode.el66
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/ghci-script-mode.elcbin0 -> 4183 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-align-imports.el231
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-align-imports.elcbin0 -> 4134 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-c2hs.el207
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-c2hs.elcbin0 -> 5108 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-cabal.el1178
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-cabal.elcbin0 -> 40194 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-collapse.el114
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-collapse.elcbin0 -> 3880 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-commands.el961
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-commands.elcbin0 -> 29590 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-compat.el65
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-compat.elcbin0 -> 1288 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-compile.el154
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-compile.elcbin0 -> 7509 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-complete-module.el131
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-complete-module.elcbin0 -> 3158 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-completions.el393
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-completions.elcbin0 -> 9607 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-customize.el466
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-customize.elcbin0 -> 14979 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-debug.el757
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-debug.elcbin0 -> 24816 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-decl-scan.el687
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-decl-scan.elcbin0 -> 14861 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-doc.el1861
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-doc.elcbin0 -> 49845 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-font-lock.el711
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-font-lock.elcbin0 -> 19622 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-ghc-support.el1344
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-ghc-support.elcbin0 -> 27843 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-hoogle.el151
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-hoogle.elcbin0 -> 5130 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-indent.el1596
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-indent.elcbin0 -> 37509 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-indentation.el1255
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-indentation.elcbin0 -> 35309 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-interactive-mode.el1129
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-interactive-mode.elcbin0 -> 37944 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-lexeme.el513
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-lexeme.elcbin0 -> 14230 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-load.el632
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-load.elcbin0 -> 19280 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-menu.el162
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-menu.elcbin0 -> 6466 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-mode-autoloads.el1011
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-mode-pkg.el8
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-mode.el1195
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-mode.elcbin0 -> 39658 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-mode.info2425
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-modules.el117
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-modules.elcbin0 -> 3229 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-move-nested.el130
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-move-nested.elcbin0 -> 2890 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-navigate-imports.el130
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-navigate-imports.elcbin0 -> 2997 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-presentation-mode.el104
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-presentation-mode.elcbin0 -> 5072 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-process.el510
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-process.elcbin0 -> 21735 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-repl.el124
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-repl.elcbin0 -> 3645 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-sandbox.el41
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-sandbox.elcbin0 -> 1177 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-session.el227
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-session.elcbin0 -> 6278 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-sort-imports.el129
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-sort-imports.elcbin0 -> 3036 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-string.el219
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-string.elcbin0 -> 8508 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-unicode-input-method.el300
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-unicode-input-method.elcbin0 -> 10108 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-utils.el193
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-utils.elcbin0 -> 5488 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell.el528
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell.elcbin0 -> 16649 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/highlight-uses-mode.el106
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/highlight-uses-mode.elcbin0 -> 3823 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/inf-haskell.el262
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/inf-haskell.elcbin0 -> 10516 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/logo.svg16
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/w3m-haddock.el190
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/w3m-haddock.elcbin0 -> 4807 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/ht-20180129.1434/ht-autoloads.el15
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/ht-20180129.1434/ht-pkg.el2
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/ht-20180129.1434/ht.el296
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/ht-20180129.1434/ht.elcbin0 -> 10080 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/intero-20180703.18/intero-autoloads.el60
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/intero-20180703.18/intero-pkg.el2
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/intero-20180703.18/intero.el3648
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/intero-20180703.18/intero.elcbin0 -> 120175 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/ivy-20180719.1037/colir.el124
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/ivy-20180719.1037/colir.elcbin0 -> 3421 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/ivy-20180719.1037/dir18
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/ivy-20180719.1037/ivy-autoloads.el135
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/ivy-20180719.1037/ivy-help.org138
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/ivy-20180719.1037/ivy-overlay.el139
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/ivy-20180719.1037/ivy-overlay.elcbin0 -> 3304 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/ivy-20180719.1037/ivy-pkg.el8
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/ivy-20180719.1037/ivy.el4283
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/ivy-20180719.1037/ivy.elcbin0 -> 159743 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/ivy-20180719.1037/ivy.info1885
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/js2-mode-20180627.744/js2-imenu-extras.el349
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/js2-mode-20180627.744/js2-imenu-extras.elcbin0 -> 15212 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/js2-mode-20180627.744/js2-mode-autoloads.el68
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/js2-mode-20180627.744/js2-mode-pkg.el9
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/js2-mode-20180627.744/js2-mode.el12854
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/js2-mode-20180627.744/js2-mode.elcbin0 -> 1135721 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/js2-mode-20180627.744/js2-old-indent.el712
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/js2-mode-20180627.744/js2-old-indent.elcbin0 -> 15906 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/json-mode-20180718.109/json-mode-autoloads.el58
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/json-mode-20180718.109/json-mode-pkg.el2
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/json-mode-20180718.109/json-mode.el222
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/json-mode-20180718.109/json-mode.elcbin0 -> 8341 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/json-reformat-20160212.53/json-reformat-autoloads.el26
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/json-reformat-20160212.53/json-reformat-pkg.el2
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/json-reformat-20160212.53/json-reformat.el221
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/json-reformat-20160212.53/json-reformat.elcbin0 -> 5126 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/json-snatcher-20150511.2047/json-snatcher-autoloads.el22
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/json-snatcher-20150511.2047/json-snatcher-pkg.el2
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/json-snatcher-20150511.2047/json-snatcher.el351
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/json-snatcher-20150511.2047/json-snatcher.elcbin0 -> 8488 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/key-chord-20160227.438/key-chord-autoloads.el67
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/key-chord-20160227.438/key-chord-pkg.el2
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/key-chord-20160227.438/key-chord.el373
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/key-chord-20160227.438/key-chord.elcbin0 -> 6178 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/let-alist-1.0.5.signed1
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/let-alist-1.0.5/let-alist-autoloads.el50
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/let-alist-1.0.5/let-alist-pkg.el2
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/let-alist-1.0.5/let-alist.el182
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/let-alist-1.0.5/let-alist.elcbin0 -> 3057 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/log4e-20170401.604/log4e-autoloads.el29
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/log4e-20170401.604/log4e-pkg.el2
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/log4e-20170401.604/log4e.el592
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/log4e-20170401.604/log4e.elcbin0 -> 21174 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/lsp-haskell-20180826.1119/lsp-haskell-autoloads.el31
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/lsp-haskell-20180826.1119/lsp-haskell-pkg.el2
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/lsp-haskell-20180826.1119/lsp-haskell.el301
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/lsp-haskell-20180826.1119/lsp-haskell.elcbin0 -> 10487 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/lsp-javascript-flow-20180613.508/lsp-javascript-flow-autoloads.el29
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/lsp-javascript-flow-20180613.508/lsp-javascript-flow-pkg.el2
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/lsp-javascript-flow-20180613.508/lsp-javascript-flow.el71
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/lsp-javascript-flow-20180613.508/lsp-javascript-flow.elcbin0 -> 2330 bytes
-rwxr-xr-xconfigs/shared/emacs/.emacs.d/elpa/lsp-mode-20180827.344/lsp-common.el192
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/lsp-mode-20180827.344/lsp-common.elcbin0 -> 6934 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/lsp-mode-20180827.344/lsp-flycheck.el3
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/lsp-mode-20180827.344/lsp-flycheck.elcbin0 -> 624 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/lsp-mode-20180827.344/lsp-imenu.el75
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/lsp-mode-20180827.344/lsp-imenu.elcbin0 -> 2525 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/lsp-mode-20180827.344/lsp-io.el350
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/lsp-mode-20180827.344/lsp-io.elcbin0 -> 24343 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/lsp-mode-20180827.344/lsp-methods.el2204
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/lsp-mode-20180827.344/lsp-methods.elcbin0 -> 152101 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/lsp-mode-20180827.344/lsp-mode-autoloads.el108
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/lsp-mode-20180827.344/lsp-mode-pkg.el10
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/lsp-mode-20180827.344/lsp-mode.el401
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/lsp-mode-20180827.344/lsp-mode.elcbin0 -> 19903 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/lsp-mode-20180827.344/lsp-notifications.el117
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/lsp-mode-20180827.344/lsp-notifications.elcbin0 -> 13587 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/lsp-ui-20180619.251/lsp-ui-autoloads.el32
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/lsp-ui-20180619.251/lsp-ui-doc.el651
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/lsp-ui-20180619.251/lsp-ui-doc.elcbin0 -> 25330 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/lsp-ui-20180619.251/lsp-ui-flycheck.el235
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/lsp-ui-20180619.251/lsp-ui-flycheck.elcbin0 -> 10512 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/lsp-ui-20180619.251/lsp-ui-imenu.el241
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/lsp-ui-20180619.251/lsp-ui-imenu.elcbin0 -> 9177 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/lsp-ui-20180619.251/lsp-ui-peek.el731
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/lsp-ui-20180619.251/lsp-ui-peek.elcbin0 -> 27951 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/lsp-ui-20180619.251/lsp-ui-pkg.el17
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/lsp-ui-20180619.251/lsp-ui-sideline.el505
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/lsp-ui-20180619.251/lsp-ui-sideline.elcbin0 -> 19899 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/lsp-ui-20180619.251/lsp-ui.el165
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/lsp-ui-20180619.251/lsp-ui.elcbin0 -> 5927 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/AUTHORS.md303
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/LICENSE676
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/dir18
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/git-rebase.el592
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/git-rebase.elcbin0 -> 20536 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-apply.el641
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-apply.elcbin0 -> 28199 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-autoloads.el2469
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-autorevert.el260
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-autorevert.elcbin0 -> 12007 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-bisect.el210
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-bisect.elcbin0 -> 13602 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-blame.el926
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-blame.elcbin0 -> 34400 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-bookmark.el366
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-bookmark.elcbin0 -> 11216 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-branch.el1081
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-branch.elcbin0 -> 39645 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-collab.el171
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-collab.elcbin0 -> 4892 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-commit.el485
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-commit.elcbin0 -> 16312 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-core.el132
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-core.elcbin0 -> 3279 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-diff.el2747
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-diff.elcbin0 -> 122519 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-ediff.el509
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-ediff.elcbin0 -> 18389 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-extras.el700
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-extras.elcbin0 -> 24446 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-files.el562
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-files.elcbin0 -> 27236 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-git.el2107
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-git.elcbin0 -> 81602 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-imenu.el241
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-imenu.elcbin0 -> 6819 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-log.el1675
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-log.elcbin0 -> 87054 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-margin.el237
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-margin.elcbin0 -> 8417 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-merge.el278
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-merge.elcbin0 -> 16064 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-mode.el1360
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-mode.elcbin0 -> 51891 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-notes.el201
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-notes.elcbin0 -> 7770 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-obsolete.el33
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-obsolete.elcbin0 -> 487 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-pkg.el11
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-process.el1099
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-process.elcbin0 -> 43526 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-refs.el747
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-refs.elcbin0 -> 36065 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-remote.el1052
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-remote.elcbin0 -> 42597 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-repos.el304
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-repos.elcbin0 -> 13297 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-reset.el113
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-reset.elcbin0 -> 4453 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-section.el1327
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-section.elcbin0 -> 50235 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-sequence.el901
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-sequence.elcbin0 -> 41070 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-stash.el492
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-stash.elcbin0 -> 31924 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-status.el567
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-status.elcbin0 -> 44514 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-submodule.el498
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-submodule.elcbin0 -> 27783 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-subtree.el146
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-subtree.elcbin0 -> 5295 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-tag.el132
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-tag.elcbin0 -> 4389 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-utils.el971
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-utils.elcbin0 -> 33527 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-wip.el286
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-wip.elcbin0 -> 18239 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-worktree.el173
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-worktree.elcbin0 -> 8444 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit.el616
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit.elcbin0 -> 19489 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit.info182
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit.info-17844
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit.info-22600
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-popup-20180618.1602/dir18
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-popup-20180618.1602/magit-popup-autoloads.el16
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-popup-20180618.1602/magit-popup-pkg.el10
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-popup-20180618.1602/magit-popup.el1366
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-popup-20180618.1602/magit-popup.elcbin0 -> 57508 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/magit-popup-20180618.1602/magit-popup.info740
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/markdown-mode-20180707.555/markdown-mode-autoloads.el46
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/markdown-mode-20180707.555/markdown-mode-pkg.el2
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/markdown-mode-20180707.555/markdown-mode.el9612
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/markdown-mode-20180707.555/markdown-mode.elcbin0 -> 323987 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/memoize-20180614.1230/memoize-autoloads.el15
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/memoize-20180614.1230/memoize-pkg.el2
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/memoize-20180614.1230/memoize.el189
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/memoize-20180614.1230/memoize.elcbin0 -> 4646 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-build.el32
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-build.elcbin0 -> 1028 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-drv-mode.el48
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-drv-mode.elcbin0 -> 1076 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-edit.el37
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-edit.elcbin0 -> 1105 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-format.el35
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-format.elcbin0 -> 1355 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-instantiate.el104
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-instantiate.elcbin0 -> 3111 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-log.el36
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-log.elcbin0 -> 1045 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-mode-autoloads.el190
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-mode-pkg.el10
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-mode.el510
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-mode.elcbin0 -> 14842 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-prettify-mode.el202
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-prettify-mode.elcbin0 -> 10687 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-repl.el112
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-repl.elcbin0 -> 6480 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-search.el64
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-search.elcbin0 -> 1769 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-shebang.el47
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-shebang.elcbin0 -> 1078 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-shell.el250
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-shell.elcbin0 -> 7839 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-store.el25
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-store.elcbin0 -> 745 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix.el289
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix.elcbin0 -> 7353 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/oauth2-0.11.signed1
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/oauth2-0.11/oauth2-autoloads.el45
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/oauth2-0.11/oauth2-pkg.el2
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/oauth2-0.11/oauth2.el342
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/oauth2-0.11/oauth2.elcbin0 -> 16609 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/org-bullets-20171127.526/org-bullets-autoloads.el22
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/org-bullets-20171127.526/org-bullets-pkg.el2
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/org-bullets-20171127.526/org-bullets.el143
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/org-bullets-20171127.526/org-bullets.elcbin0 -> 4116 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/paredit-20171126.1805/paredit-autoloads.el33
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/paredit-20171126.1805/paredit-pkg.el2
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/paredit-20171126.1805/paredit.el2929
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/paredit-20171126.1805/paredit.elcbin0 -> 80550 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/pcre2el-20161120.1303/pcre2el-autoloads.el217
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/pcre2el-20161120.1303/pcre2el-pkg.el2
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/pcre2el-20161120.1303/pcre2el.el3157
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/pcre2el-20161120.1303/pcre2el.elcbin0 -> 141834 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/pkg-info-20150517.443/pkg-info-autoloads.el122
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/pkg-info-20150517.443/pkg-info-pkg.el2
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/pkg-info-20150517.443/pkg-info.el331
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/pkg-info-20150517.443/pkg-info.elcbin0 -> 9910 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/prettier-js-20180108.2326/prettier-js-autoloads.el22
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/prettier-js-20180108.2326/prettier-js-pkg.el2
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/prettier-js-20180108.2326/prettier-js.el214
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/prettier-js-20180108.2326/prettier-js.elcbin0 -> 5987 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/projectile-20180711.102/projectile-autoloads.el521
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/projectile-20180711.102/projectile-pkg.el2
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/projectile-20180711.102/projectile.el4000
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/projectile-20180711.102/projectile.elcbin0 -> 149140 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/quelpa-0.0.1/quelpa-autoloads.el68
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/quelpa-0.0.1/quelpa-pkg.el2
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/quelpa-0.0.1/quelpa.el1799
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/quelpa-0.0.1/quelpa.elcbin0 -> 67290 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/quelpa-20180711.1638/bootstrap.el32
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/quelpa-20180711.1638/bootstrap.elcbin0 -> 953 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/quelpa-20180711.1638/quelpa-autoloads.el73
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/quelpa-20180711.1638/quelpa-pkg.el12
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/quelpa-20180711.1638/quelpa.el1799
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/quelpa-20180711.1638/quelpa.elcbin0 -> 67290 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/quelpa-20180903.1313/bootstrap.el32
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/quelpa-20180903.1313/bootstrap.elcbin0 -> 953 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/quelpa-20180903.1313/quelpa-autoloads.el73
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/quelpa-20180903.1313/quelpa-pkg.el12
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/quelpa-20180903.1313/quelpa.el1832
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/quelpa-20180903.1313/quelpa.elcbin0 -> 68303 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/quelpa-20180907.1832/bootstrap.el32
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/quelpa-20180907.1832/bootstrap.elcbin0 -> 953 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/quelpa-20180907.1832/quelpa-autoloads.el73
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/quelpa-20180907.1832/quelpa-pkg.el12
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/quelpa-20180907.1832/quelpa.el1799
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/quelpa-20180907.1832/quelpa.elcbin0 -> 67290 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/queue-0.2.signed1
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/queue-0.2/queue-autoloads.el19
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/queue-0.2/queue-pkg.el2
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/queue-0.2/queue.el192
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/queue-0.2/queue.elcbin0 -> 8778 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/request-20170131.1747/request-autoloads.el15
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/request-20170131.1747/request-pkg.el2
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/request-20170131.1747/request.el1224
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/request-20170131.1747/request.elcbin0 -> 67314 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/rjsx-mode-20180624.1758/rjsx-mode-autoloads.el29
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/rjsx-mode-20180624.1758/rjsx-mode-pkg.el2
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/rjsx-mode-20180624.1758/rjsx-mode.el964
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/rjsx-mode-20180624.1758/rjsx-mode.elcbin0 -> 101261 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/s-20180406.108/s-autoloads.el15
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/s-20180406.108/s-pkg.el2
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/s-20180406.108/s.el747
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/s-20180406.108/s.elcbin0 -> 27351 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/seq-2.20.signed1
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/seq-2.20/ChangeLog195
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/seq-2.20/seq-24.el496
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/seq-2.20/seq-24.elcbin0 -> 17415 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/seq-2.20/seq-25.el530
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/seq-2.20/seq-25.elcbin0 -> 22019 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/seq-2.20/seq-autoloads.el16
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/seq-2.20/seq-pkg.el2
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/seq-2.20/seq-pkg.elcbin0 -> 543 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/seq-2.20/seq.el48
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/seq-2.20/seq.elcbin0 -> 548 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/seq-2.20/tests/seq-tests.el382
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/seq-2.20/tests/seq-tests.elcbin0 -> 147774 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/sesman-20180719.213/sesman-autoloads.el67
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/sesman-20180719.213/sesman-pkg.el2
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/sesman-20180719.213/sesman.el728
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/sesman-20180719.213/sesman.elcbin0 -> 24762 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-attachment.el127
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-attachment.elcbin0 -> 6558 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-autoloads.el57
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-bot-message.el93
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-bot-message.elcbin0 -> 3137 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-buffer.el439
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-buffer.elcbin0 -> 22886 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-channel.el275
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-channel.elcbin0 -> 13722 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-edit-file-comment-buffer.el89
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-edit-file-comment-buffer.elcbin0 -> 6873 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-emoji.el93
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-emoji.elcbin0 -> 2619 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-file-comment-compose-buffer.el74
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-file-comment-compose-buffer.elcbin0 -> 3154 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-file-comment.el210
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-file-comment.elcbin0 -> 13953 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-file-info-buffer.el235
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-file-info-buffer.elcbin0 -> 12051 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-file-list-buffer.el56
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-file-list-buffer.elcbin0 -> 5690 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-file-share-message.el118
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-file-share-message.elcbin0 -> 5335 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-file.el779
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-file.elcbin0 -> 39519 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-group.el293
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-group.elcbin0 -> 14425 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-im.el252
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-im.elcbin0 -> 11644 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message-buffer.el434
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message-buffer.elcbin0 -> 20632 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message-compose-buffer.el51
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message-compose-buffer.elcbin0 -> 5310 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message-edit-buffer.el96
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message-edit-buffer.elcbin0 -> 6923 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message-editor.el130
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message-editor.elcbin0 -> 5950 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message-formatter.el306
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message-formatter.elcbin0 -> 9894 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message-notification.el145
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message-notification.elcbin0 -> 5054 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message-reaction.el168
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message-reaction.elcbin0 -> 5637 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message-sender.el169
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message-sender.elcbin0 -> 5066 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message-share-buffer.el75
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message-share-buffer.elcbin0 -> 6298 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message.el445
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message.elcbin0 -> 23834 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-pinned-item.el49
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-pinned-item.elcbin0 -> 2142 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-pinned-items-buffer.el105
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-pinned-items-buffer.elcbin0 -> 7093 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-pkg.el11
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-reaction.el117
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-reaction.elcbin0 -> 4950 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-reminder.el272
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-reminder.elcbin0 -> 13318 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-reply.el49
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-reply.elcbin0 -> 1214 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-request-worker.el143
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-request-worker.elcbin0 -> 4976 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-request.el162
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-request.elcbin0 -> 7568 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-room-buffer.el107
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-room-buffer.elcbin0 -> 4560 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-room-message-compose-buffer.el69
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-room-message-compose-buffer.elcbin0 -> 3067 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-room.el501
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-room.elcbin0 -> 22074 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-search-result-buffer.el129
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-search-result-buffer.elcbin0 -> 8392 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-search.el418
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-search.elcbin0 -> 14756 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-slash-commands.el122
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-slash-commands.elcbin0 -> 3576 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-star.el264
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-star.elcbin0 -> 17372 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-stars-buffer.el128
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-stars-buffer.elcbin0 -> 8043 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-team.el308
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-team.elcbin0 -> 14231 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-thread-message-buffer.el145
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-thread-message-buffer.elcbin0 -> 9456 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-thread-message-compose-buffer.el79
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-thread-message-compose-buffer.elcbin0 -> 3533 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-thread.el332
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-thread.elcbin0 -> 15846 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-user-message.el35
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-user-message.elcbin0 -> 1726 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-user-profile-buffer.el88
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-user-profile-buffer.elcbin0 -> 6458 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-user.el385
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-user.elcbin0 -> 15381 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-util.el471
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-util.elcbin0 -> 15253 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-websocket.el1018
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-websocket.elcbin0 -> 37985 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack.el227
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack.elcbin0 -> 7614 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/smex-20151212.1409/smex-autoloads.el31
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/smex-20151212.1409/smex-pkg.el2
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/smex-20151212.1409/smex.el484
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/smex-20151212.1409/smex.elcbin0 -> 13166 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/spinner-1.7.3.signed1
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/spinner-1.7.3/spinner-autoloads.el68
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/spinner-1.7.3/spinner-pkg.el2
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/spinner-1.7.3/spinner.el406
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/spinner-1.7.3/spinner.elcbin0 -> 16351 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/swiper-20180713.946/swiper-autoloads.el32
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/swiper-20180713.946/swiper-pkg.el2
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/swiper-20180713.946/swiper.el1040
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/swiper-20180713.946/swiper.elcbin0 -> 29995 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/tablist-20170219.1935/tablist-autoloads.el36
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/tablist-20170219.1935/tablist-filter.el448
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/tablist-20170219.1935/tablist-filter.elcbin0 -> 12559 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/tablist-20170219.1935/tablist-pkg.el7
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/tablist-20170219.1935/tablist.el1941
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/tablist-20170219.1935/tablist.elcbin0 -> 62038 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/undo-tree-0.6.5.signed1
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/undo-tree-0.6.5/undo-tree-autoloads.el59
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/undo-tree-0.6.5/undo-tree-pkg.el2
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/undo-tree-0.6.5/undo-tree.el4418
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/undo-tree-0.6.5/undo-tree.elcbin0 -> 120698 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/dir18
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package-autoloads.el209
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package-bind-key.el172
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package-bind-key.elcbin0 -> 4536 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package-core.el1591
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package-core.elcbin0 -> 53990 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package-delight.el91
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package-delight.elcbin0 -> 1840 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package-diminish.el80
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package-diminish.elcbin0 -> 1747 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package-ensure.el214
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package-ensure.elcbin0 -> 5327 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package-jump.el79
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package-jump.elcbin0 -> 1775 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package-lint.el84
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package-lint.elcbin0 -> 1534 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package-pkg.el9
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package.el54
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package.elcbin0 -> 720 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package.info1048
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/visual-fill-column-20180511.211/visual-fill-column-autoloads.el57
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/visual-fill-column-20180511.211/visual-fill-column-pkg.el2
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/visual-fill-column-20180511.211/visual-fill-column.el205
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/visual-fill-column-20180511.211/visual-fill-column.elcbin0 -> 12072 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/websocket-20180422.1716/websocket-autoloads.el15
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/websocket-20180422.1716/websocket-pkg.el2
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/websocket-20180422.1716/websocket.el1070
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/websocket-20180422.1716/websocket.elcbin0 -> 60337 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/which-key-20180621.1238/which-key-autoloads.el172
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/which-key-20180621.1238/which-key-pkg.el2
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/which-key-20180621.1238/which-key.el2632
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/which-key-20180621.1238/which-key.elcbin0 -> 100707 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/with-editor-20180618.1602/dir18
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/with-editor-20180618.1602/with-editor-autoloads.el95
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/with-editor-20180618.1602/with-editor-pkg.el9
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/with-editor-20180618.1602/with-editor.el822
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/with-editor-20180618.1602/with-editor.elcbin0 -> 30134 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/with-editor-20180618.1602/with-editor.info331
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/writeroom-mode-20170623.327/dir19
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/writeroom-mode-20170623.327/writeroom-mode-autoloads.el49
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/writeroom-mode-20170623.327/writeroom-mode-pkg.el8
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/writeroom-mode-20170623.327/writeroom-mode.el468
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/writeroom-mode-20170623.327/writeroom-mode.elcbin0 -> 24822 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/writeroom-mode-20170623.327/writeroom-mode.info543
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/xterm-color-20180202.1518/xterm-color-autoloads.el43
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/xterm-color-20180202.1518/xterm-color-pkg.el2
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/xterm-color-20180202.1518/xterm-color.el699
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/xterm-color-20180202.1518/xterm-color.elcbin0 -> 12687 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/yaml-mode-20180408.2307/yaml-mode-autoloads.el28
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/yaml-mode-20180408.2307/yaml-mode-pkg.el2
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/yaml-mode-20180408.2307/yaml-mode.el472
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/yaml-mode-20180408.2307/yaml-mode.elcbin0 -> 14088 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/yasnippet-20180620.1750/yasnippet-autoloads.el56
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/yasnippet-20180620.1750/yasnippet-pkg.el2
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/yasnippet-20180620.1750/yasnippet.el5106
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/yasnippet-20180620.1750/yasnippet.elcbin0 -> 215457 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/zen-mode-20170723.139/zen-mode-autoloads.el22
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/zen-mode-20170723.139/zen-mode-pkg.el2
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/zen-mode-20170723.139/zen-mode.el203
-rw-r--r--configs/shared/emacs/.emacs.d/elpa/zen-mode-20170723.139/zen-mode.elcbin0 -> 6676 bytes
-rw-r--r--configs/shared/emacs/.emacs.d/init.el42
-rw-r--r--configs/shared/emacs/.emacs.d/network-security.data6
-rwxr-xr-xconfigs/shared/emacs/.emacs.d/open-from-iterm.sh37
-rw-r--r--configs/shared/emacs/.emacs.d/projectile-bookmarks.eld1
m---------configs/shared/emacs/.emacs.d/quelpa/build/evil-text-objects-haskell0
m---------configs/shared/emacs/.emacs.d/quelpa/build/evil-text-objects-javascript0
m---------configs/shared/emacs/.emacs.d/quelpa/build/quelpa0
m---------configs/shared/emacs/.emacs.d/quelpa/build/zen-mode0
-rw-r--r--configs/shared/emacs/.emacs.d/quelpa/cache1
m---------configs/shared/emacs/.emacs.d/quelpa/melpa0
-rw-r--r--configs/shared/emacs/.emacs.d/smex-items69
-rw-r--r--configs/shared/emacs/.emacs.d/snippets/emacs-lisp-mode/elisp-module-docs11
-rw-r--r--configs/shared/emacs/.emacs.d/snippets/emacs-lisp-mode/provide-footer6
-rw-r--r--configs/shared/emacs/.emacs.d/snippets/haskell-mode/derive-safe-copy5
-rw-r--r--configs/shared/emacs/.emacs.d/snippets/haskell-mode/import-qualified5
-rw-r--r--configs/shared/emacs/.emacs.d/snippets/haskell-mode/instance-defn6
-rw-r--r--configs/shared/emacs/.emacs.d/snippets/haskell-mode/language-extension5
-rw-r--r--configs/shared/emacs/.emacs.d/snippets/haskell-mode/separator5
-rw-r--r--configs/shared/emacs/.emacs.d/snippets/haskell-mode/undefined5
-rw-r--r--configs/shared/emacs/.emacs.d/snippets/org-mode/code-snippet7
-rw-r--r--configs/shared/emacs/.emacs.d/snippets/org-mode/href5
-rw-r--r--configs/shared/emacs/.emacs.d/snippets/rjsx-mode/action-extractor5
-rw-r--r--configs/shared/emacs/.emacs.d/snippets/rjsx-mode/console-log5
-rw-r--r--configs/shared/emacs/.emacs.d/snippets/rjsx-mode/const-defn5
-rw-r--r--configs/shared/emacs/.emacs.d/snippets/rjsx-mode/const-function7
-rw-r--r--configs/shared/emacs/.emacs.d/snippets/rjsx-mode/destructure-const5
-rw-r--r--configs/shared/emacs/.emacs.d/snippets/rjsx-mode/fat-arrow5
-rw-r--r--configs/shared/emacs/.emacs.d/snippets/rjsx-mode/fat-arrow-function7
-rw-r--r--configs/shared/emacs/.emacs.d/snippets/rjsx-mode/import-destructured5
-rw-r--r--configs/shared/emacs/.emacs.d/snippets/rjsx-mode/import-react5
-rw-r--r--configs/shared/emacs/.emacs.d/snippets/rjsx-mode/import-type5
-rw-r--r--configs/shared/emacs/.emacs.d/snippets/rjsx-mode/import-x-from-y5
-rw-r--r--configs/shared/emacs/.emacs.d/snippets/rjsx-mode/import-y5
-rw-r--r--configs/shared/emacs/.emacs.d/snippets/rjsx-mode/jest-describe-test10
-rw-r--r--configs/shared/emacs/.emacs.d/snippets/rjsx-mode/jest-test7
-rw-r--r--configs/shared/emacs/.emacs.d/snippets/rjsx-mode/react-class-component11
-rw-r--r--configs/shared/emacs/.emacs.d/snippets/rjsx-mode/redux-action5
-rw-r--r--configs/shared/emacs/.emacs.d/snippets/rjsx-mode/typed-redux-action5
-rw-r--r--configs/shared/emacs/.emacs.d/vendor/org-clubhouse.el365
-rw-r--r--configs/shared/emacs/.emacs.d/vendor/reason-indent.el304
-rw-r--r--configs/shared/emacs/.emacs.d/vendor/reason-interaction.el216
-rw-r--r--configs/shared/emacs/.emacs.d/vendor/reason-mode.el242
-rw-r--r--configs/shared/emacs/.emacs.d/vendor/refmt.el231
-rw-r--r--configs/shared/emacs/.emacs.d/vendor/slack-snippets.el228
-rw-r--r--configs/shared/emacs/.emacs.d/wpc/casing.el49
-rw-r--r--configs/shared/emacs/.emacs.d/wpc/fs-functions.el28
-rw-r--r--configs/shared/emacs/.emacs.d/wpc/functions.el222
-rw-r--r--configs/shared/emacs/.emacs.d/wpc/macros.el33
-rw-r--r--configs/shared/emacs/.emacs.d/wpc/packages/wpc-clojure.el61
-rw-r--r--configs/shared/emacs/.emacs.d/wpc/packages/wpc-company.el24
-rw-r--r--configs/shared/emacs/.emacs.d/wpc/packages/wpc-dired.el18
-rw-r--r--configs/shared/emacs/.emacs.d/wpc/packages/wpc-docker.el18
-rw-r--r--configs/shared/emacs/.emacs.d/wpc/packages/wpc-flycheck.el14
-rw-r--r--configs/shared/emacs/.emacs.d/wpc/packages/wpc-git.el14
-rw-r--r--configs/shared/emacs/.emacs.d/wpc/packages/wpc-graphql.el17
-rw-r--r--configs/shared/emacs/.emacs.d/wpc/packages/wpc-haskell.el56
-rw-r--r--configs/shared/emacs/.emacs.d/wpc/packages/wpc-javascript.el95
-rw-r--r--configs/shared/emacs/.emacs.d/wpc/packages/wpc-keybindings.el134
-rw-r--r--configs/shared/emacs/.emacs.d/wpc/packages/wpc-lisp.el45
-rw-r--r--configs/shared/emacs/.emacs.d/wpc/packages/wpc-misc.el168
-rw-r--r--configs/shared/emacs/.emacs.d/wpc/packages/wpc-nix.el12
-rw-r--r--configs/shared/emacs/.emacs.d/wpc/packages/wpc-org.el45
-rw-r--r--configs/shared/emacs/.emacs.d/wpc/packages/wpc-package.el32
-rw-r--r--configs/shared/emacs/.emacs.d/wpc/packages/wpc-slack.el65
-rw-r--r--configs/shared/emacs/.emacs.d/wpc/packages/wpc-terminal.el19
-rw-r--r--configs/shared/emacs/.emacs.d/wpc/packages/wpc-ui.el172
-rw-r--r--configs/shared/emacs/.emacs.d/wpc/string-functions.el51
-rw-r--r--configs/shared/emacs/.emacs.d/wpc/variables.el26
1332 files changed, 332785 insertions, 0 deletions
diff --git a/configs/shared/emacs/.emacs.d/auto-save-list/.saves-15593-wpc-mbp~ b/configs/shared/emacs/.emacs.d/auto-save-list/.saves-15593-wpc-mbp~
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/auto-save-list/.saves-15593-wpc-mbp~
diff --git a/configs/shared/emacs/.emacs.d/auto-save-list/.saves-18355-wpc-mbp~ b/configs/shared/emacs/.emacs.d/auto-save-list/.saves-18355-wpc-mbp~
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/auto-save-list/.saves-18355-wpc-mbp~
diff --git a/configs/shared/emacs/.emacs.d/auto-save-list/.saves-32097-wpc-mbp~ b/configs/shared/emacs/.emacs.d/auto-save-list/.saves-32097-wpc-mbp~
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/auto-save-list/.saves-32097-wpc-mbp~
diff --git a/configs/shared/emacs/.emacs.d/auto-save-list/.saves-8187-wpc-mbp~ b/configs/shared/emacs/.emacs.d/auto-save-list/.saves-8187-wpc-mbp~
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/auto-save-list/.saves-8187-wpc-mbp~
diff --git a/configs/shared/emacs/.emacs.d/bookmarks b/configs/shared/emacs/.emacs.d/bookmarks
new file mode 100644
index 0000000000..a222a18de7
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/bookmarks
@@ -0,0 +1,15 @@
+;;;; Emacs Bookmark Format Version 1 ;;;;
+;;; This format is meant to be slightly human-readable;
+;;; nevertheless, you probably don't want to edit it.
+;;; -*- End Of Bookmark File Format Version Stamp -*-
+(("org-capture-last-stored"
+ (filename . "~/org/notes.org")
+ (front-context-string . "** TODO testing ")
+ (rear-context-string)
+ (position . 9))
+("org-refile-last-stored"
+ (filename . "~/Dropbox/cryptocurrency/todo.org")
+ (front-context-string . "** TODO Maintain")
+ (rear-context-string . "h email & text)\n")
+ (position . 1465))
+)
\ No newline at end of file
diff --git a/configs/shared/emacs/.emacs.d/custom.el b/configs/shared/emacs/.emacs.d/custom.el
new file mode 100644
index 0000000000..88219f70cd
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/custom.el
@@ -0,0 +1,52 @@
+(custom-set-variables
+ ;; custom-set-variables was added by Custom.
+ ;; If you edit it by hand, you could mess it up, so be careful.
+ ;; Your init file should contain only one such instance.
+ ;; If there is more than one, they won't work right.
+ '(ansi-color-names-vector
+   ["#10151C" "#D95468" "#8BD49C" "#EBBF83" "#5EC4FF" "#E27E8D" "#70E1E8" "#9CAABB"])
+ '(custom-safe-themes
+   (quote
+    ("bd23e5e571f9b951eb79941ba3927fb493c26463654add2a53f4fb0de72ef08b" "013c62a1fcee7c8988c831027b1c38ae215f99722911b69e570f21fc19cb662e" "0b1ded82ebea8b76e3c17c628fe0d3c7aa46746c3efcf657f633d71989110585" "8ff5073d6c694a442c85505d6f885a752061b3738e2de7c2b9042ffd2c1579e5" "4f5fb2b25a9c71d584472abc5b6f850d616ac280a69e43df6e78ddf2b4aa68fa" "0a3a41085c19d8121ed0ad3eb658a475ccb948a70a83604641ee7d4c3575a4d5" "73e35ffa5ca98b57a9923954f296c3854ce6d8736b31fdbdda3d27502d4b4d69" "a7e7804313dbf827a441c86a8109ef5b64b03011383322cbdbf646eb02692f76" "77bddca0879cb3b0ecdf071d9635c818827c57d69164291cb27268ae324efa84" "3481e594ae6866d72c40ad77d86a1ffa338d01daa9eb0977e324f365cef4f47c" "6be42070d23e832a7493166f90e9bb08af348a818ec18389c1f21d33542771af" default)))
+ '(fci-rule-color "#56697A")
+ '(flycheck-javascript-flow-args nil)
+ '(jdee-db-active-breakpoint-face-colors (cons "#10151C" "#5EC4FF"))
+ '(jdee-db-requested-breakpoint-face-colors (cons "#10151C" "#8BD49C"))
+ '(jdee-db-spec-breakpoint-face-colors (cons "#10151C" "#384551"))
+ '(org-fontify-done-headline t t)
+ '(org-fontify-quote-and-verse-blocks t t)
+ '(org-fontify-whole-heading-line t t)
+ '(package-selected-packages
+   (quote
+    (writeroom-mode general rainbow-delimiters zen-mode flx-ido xterm-color evil-collection evil-text-objects-javascript evil-text-objects-haskell dired+ org-bullets slack emojify circe oauth2 engine-mode uniquify diminish elisp-slime-nav pcre2el magit-gh-pulls org-mode intero f cycle-themes ansi-term request dash-functional company-flow flycheck-flow flow-minor-mode elixir-mode oceanic-theme git-timemachine dockerfile-mode docker yaml-mode s key-chord yasnippet prettier-js rjsx-mode indium reason-mode flycheck markdown-mode smex magit all-the-icons-ivy which-key doom-themes cider hydra ace-window counsel-projectile counsel paredit projectile company evil exec-path-from-shell use-package)))
+ '(safe-local-variable-values
+   (quote
+    ((intero-targets "grid:lib" "grid:exe:grid-exe" "grid:test:doctests" "grid:test:grid-test"))))
+ '(vc-annotate-background "#10151C")
+ '(vc-annotate-color-map
+   (list
+    (cons 20 "#8BD49C")
+    (cons 40 "#abcd93")
+    (cons 60 "#cbc68b")
+    (cons 80 "#EBBF83")
+    (cons 100 "#e5ae6f")
+    (cons 120 "#df9e5b")
+    (cons 140 "#D98E48")
+    (cons 160 "#dc885f")
+    (cons 180 "#df8376")
+    (cons 200 "#E27E8D")
+    (cons 220 "#df7080")
+    (cons 240 "#dc6274")
+    (cons 260 "#D95468")
+    (cons 280 "#b05062")
+    (cons 300 "#884c5c")
+    (cons 320 "#604856")
+    (cons 340 "#56697A")
+    (cons 360 "#56697A")))
+ '(vc-annotate-very-old-color nil))
+(custom-set-faces
+ ;; custom-set-faces was added by Custom.
+ ;; If you edit it by hand, you could mess it up, so be careful.
+ ;; Your init file should contain only one such instance.
+ ;; If there is more than one, they won't work right.
+ )
diff --git a/configs/shared/emacs/.emacs.d/elpa/ace-window-20180607.1223/ace-window-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/ace-window-20180607.1223/ace-window-autoloads.el
new file mode 100644
index 0000000000..b7be5988ff
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/ace-window-20180607.1223/ace-window-autoloads.el
@@ -0,0 +1,68 @@
+;;; ace-window-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "ace-window" "ace-window.el" (23377 60991 457690
+;;;;;;  292000))
+;;; Generated autoloads from ace-window.el
+
+(autoload 'ace-select-window "ace-window" "\
+Ace select window.
+
+\(fn)" t nil)
+
+(autoload 'ace-delete-window "ace-window" "\
+Ace delete window.
+
+\(fn)" t nil)
+
+(autoload 'ace-swap-window "ace-window" "\
+Ace swap window.
+
+\(fn)" t nil)
+
+(autoload 'ace-delete-other-windows "ace-window" "\
+Ace delete other windows.
+
+\(fn)" t nil)
+
+(autoload 'ace-window "ace-window" "\
+Select a window.
+Perform an action based on ARG described below.
+
+By default, behaves like extended `other-window'.
+
+Prefixed with one \\[universal-argument], does a swap between the
+selected window and the current window, so that the selected
+buffer moves to current window (and current buffer moves to
+selected window).
+
+Prefixed with two \\[universal-argument]'s, deletes the selected
+window.
+
+\(fn ARG)" t nil)
+
+(defvar ace-window-display-mode nil "\
+Non-nil if Ace-Window-Display mode is enabled.
+See the `ace-window-display-mode' command
+for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `ace-window-display-mode'.")
+
+(custom-autoload 'ace-window-display-mode "ace-window" nil)
+
+(autoload 'ace-window-display-mode "ace-window" "\
+Minor mode for showing the ace window key in the mode line.
+
+\(fn &optional ARG)" t nil)
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; ace-window-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/ace-window-20180607.1223/ace-window-pkg.el b/configs/shared/emacs/.emacs.d/elpa/ace-window-20180607.1223/ace-window-pkg.el
new file mode 100644
index 0000000000..9e518a8522
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/ace-window-20180607.1223/ace-window-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "ace-window" "20180607.1223" "Quickly switch windows." '((avy "0.2.0")))
diff --git a/configs/shared/emacs/.emacs.d/elpa/ace-window-20180607.1223/ace-window.el b/configs/shared/emacs/.emacs.d/elpa/ace-window-20180607.1223/ace-window.el
new file mode 100644
index 0000000000..b6759c421b
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/ace-window-20180607.1223/ace-window.el
@@ -0,0 +1,802 @@
+;;; ace-window.el --- Quickly switch windows. -*- lexical-binding: t -*-
+
+;; Copyright (C) 2015  Free Software Foundation, Inc.
+
+;; Author: Oleh Krehel <ohwoeowho@gmail.com>
+;; Maintainer: Oleh Krehel <ohwoeowho@gmail.com>
+;; URL: https://github.com/abo-abo/ace-window
+;; Package-Version: 20180607.1223
+;; Version: 0.9.0
+;; Package-Requires: ((avy "0.2.0"))
+;; Keywords: window, location
+
+;; This file is part of GNU Emacs.
+
+;; This file 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, or (at your option)
+;; any later version.
+
+;; This program 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.
+
+;; For a full copy of the GNU General Public License
+;; see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;
+;; The main function, `ace-window' is meant to replace `other-window'
+;; by assigning each window a short, unique label.  When there are only
+;; two windows present, `other-window' is called (unless
+;; aw-dispatch-always is set non-nil).  If there are more, each
+;; window will have its first label character highlighted.  Once a
+;; unique label is typed, ace-window will switch to that window.
+;;
+;; To setup this package, just add to your .emacs:
+;;
+;;    (global-set-key (kbd "M-o") 'ace-window)
+;;
+;; replacing "M-o"  with an appropriate shortcut.
+;;
+;; By default, ace-window uses numbers for window labels so the window
+;; labeling is intuitively ordered.  But if you prefer to type keys on
+;; your home row for quicker access, use this setting:
+;;
+;;    (setq aw-keys '(?a ?s ?d ?f ?g ?h ?j ?k ?l))
+;;
+;; Whenever ace-window prompts for a window selection, it grays out
+;; all the window characters, highlighting window labels in red.  To
+;; disable this behavior, set this:
+;;
+;;    (setq aw-background nil)
+;;
+;; If you want to know the selection characters ahead of time, turn on
+;; `ace-window-display-mode'.
+;;
+;; When prefixed with one `universal-argument', instead of switching
+;; to the selected window, the selected window is swapped with the
+;; current one.
+;;
+;; When prefixed with two `universal-argument', the selected window is
+;; deleted instead.
+
+;;; Code:
+(require 'avy)
+(require 'ring)
+(require 'subr-x)
+
+;;* Customization
+(defgroup ace-window nil
+  "Quickly switch current window."
+  :group 'convenience
+  :prefix "aw-")
+
+(defcustom aw-keys '(?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9)
+  "Keys for selecting window."
+  :type '(repeat character))
+
+(defcustom aw-scope 'global
+  "The scope used by `ace-window'."
+  :type '(choice
+          (const :tag "visible frames" visible)
+          (const :tag "global" global)
+          (const :tag "frame" frame)))
+
+(defcustom aw-minibuffer-flag nil
+  "When non-nil, also display `ace-window-mode' string in the minibuffer when ace-window is active."
+  :type 'boolean)
+
+(defcustom aw-ignored-buffers '("*Calc Trail*" "*LV*")
+  "List of buffers and major-modes to ignore when choosing a window from the window list.
+Active only when `aw-ignore-on' is non-nil.  Windows displaying these
+buffers can still be chosen by typing their specific labels."
+  :type '(repeat string))
+
+(defcustom aw-ignore-on t
+  "When t, `ace-window' will ignore buffers and major-modes in `aw-ignored-buffers'.
+Use M-0 `ace-window' to toggle this value."
+  :type 'boolean)
+
+(defcustom aw-ignore-current nil
+  "When t, `ace-window' will ignore `selected-window'."
+  :type 'boolean)
+
+(defcustom aw-background t
+  "When t, `ace-window' will dim out all buffers temporarily when used."
+  :type 'boolean)
+
+(defcustom aw-leading-char-style 'char
+  "Style of the leading char overlay."
+  :type '(choice
+          (const :tag "single char" 'char)
+          (const :tag "full path" 'path)))
+
+(defcustom aw-dispatch-always nil
+  "When non-nil, `ace-window' will issue a `read-char' even for one window.
+This will make `ace-window' act different from `other-window' for
+  one or two windows."
+  :type 'boolean)
+
+(defcustom aw-dispatch-when-more-than 2
+  "If the number of windows is more than this, activate ace-window-ness."
+  :type 'integer)
+
+(defcustom aw-reverse-frame-list nil
+  "When non-nil `ace-window' will order frames for selection in
+the reverse of `frame-list'"
+  :type 'boolean)
+
+(defcustom aw-frame-offset '(13 . 23)
+  "Increase in pixel offset for new ace-window frames relative to the selected frame.
+Its value is an (x-offset . y-offset) pair in pixels."
+  :type '(cons integer integer))
+
+(defcustom aw-frame-size nil
+  "Frame size to make new ace-window frames.
+Its value is a (width . height) pair in pixels or nil for the default frame size.
+(0 . 0) is special and means make the frame size the same as the last selected frame size."
+  :type '(cons integer integer))
+
+(defcustom aw-char-position 'top-left
+  "Window positions of the character overlay.
+Consider changing this if the overlay tends to overlap with other things."
+  :type '(choice
+          (const :tag "top left corner only" 'top-left)
+          (const :tag "both left corners" 'left)))
+
+;; Must be defined before `aw-make-frame-char' since its :set function references this.
+(defvar aw-dispatch-alist
+  '((?x aw-delete-window "Delete Window")
+    (?m aw-swap-window "Swap Windows")
+    (?M aw-move-window "Move Window")
+    (?j aw-switch-buffer-in-window "Select Buffer")
+    (?n aw-flip-window)
+    (?u aw-switch-buffer-other-window "Switch Buffer Other Window")
+    (?c aw-split-window-fair "Split Fair Window")
+    (?v aw-split-window-vert "Split Vert Window")
+    (?b aw-split-window-horz "Split Horz Window")
+    (?o delete-other-windows "Delete Other Windows")
+    (?? aw-show-dispatch-help))
+  "List of actions for `aw-dispatch-default'.
+Each action is a list of either:
+  (char function description) where function takes a single window argument
+or
+  (char function) where function takes no argument and the description is omitted.")
+
+(defun aw-set-make-frame-char (option value)
+  ;; Signal an error if `aw-make-frame-char' is ever set to an invalid
+  ;; or conflicting value.
+  (when value
+    (cond ((not (characterp value))
+           (user-error "`aw-make-frame-char' must be a character, not `%s'" value))
+          ((memq value aw-keys)
+           (user-error "`aw-make-frame-char' is `%c'; this conflicts with the same character in `aw-keys'" value))
+          ((assq value aw-dispatch-alist)
+           (user-error "`aw-make-frame-char' is `%c'; this conflicts with the same character in `aw-dispatch-alist'" value))))
+  (set option value))
+
+(defcustom aw-make-frame-char ?z
+  "Non-existing ace window label character that triggers creation of a new single-window frame for display."
+  :set 'aw-set-make-frame-char
+  :type 'character)
+
+(defface aw-leading-char-face
+  '((((class color)) (:foreground "red"))
+    (((background dark)) (:foreground "gray100"))
+    (((background light)) (:foreground "gray0"))
+    (t (:foreground "gray100" :underline nil)))
+  "Face for each window's leading char.")
+
+(defface aw-background-face
+  '((t (:foreground "gray40")))
+  "Face for whole window background during selection.")
+
+(defface aw-mode-line-face
+  '((t (:inherit mode-line-buffer-id)))
+  "Face used for displaying the ace window key in the mode-line.")
+
+(defface aw-key-face
+  '((t :inherit font-lock-builtin-face))
+  "Face used by `aw-show-dispatch-help'.")
+
+;;* Implementation
+(defun aw-ignored-p (window)
+  "Return t if WINDOW should be ignored when choosing from the window list."
+  (or (and aw-ignore-on
+           ;; Ignore major-modes and buffer-names in `aw-ignored-buffers'.
+           (or (memq (buffer-local-value 'major-mode (window-buffer window))
+                     aw-ignored-buffers)
+               (member (buffer-name (window-buffer window)) aw-ignored-buffers)))
+      ;; Ignore selected window if `aw-ignore-current' is non-nil.
+      (and aw-ignore-current
+           (equal window (selected-window)))
+      ;; When `ignore-window-parameters' is nil, ignore windows whose
+      ;; `no-other-window’ or `no-delete-other-windows' parameter is non-nil.
+      (unless ignore-window-parameters
+        (cl-case this-command
+          (ace-select-window (window-parameter window 'no-other-window))
+          (ace-delete-window (window-parameter window 'no-delete-other-windows))
+          (ace-delete-other-windows (window-parameter
+                                     window 'no-delete-other-windows))))))
+
+(defun aw-window-list ()
+  "Return the list of interesting windows."
+  (sort
+   (cl-remove-if
+    (lambda (w)
+      (let ((f (window-frame w)))
+        (or (not (and (frame-live-p f)
+                      (frame-visible-p f)))
+            (string= "initial_terminal" (terminal-name f))
+            (aw-ignored-p w))))
+    (cl-case aw-scope
+      (visible
+       (cl-mapcan #'window-list (visible-frame-list)))
+      (global
+       (cl-mapcan #'window-list (frame-list)))
+      (frame
+       (window-list))
+      (t
+       (error "Invalid `aw-scope': %S" aw-scope))))
+   'aw-window<))
+
+(defvar aw-overlays-back nil
+  "Hold overlays for when `aw-background' is t.")
+
+(defvar ace-window-mode nil
+  "Minor mode during the selection process.")
+
+;; register minor mode
+(or (assq 'ace-window-mode minor-mode-alist)
+    (nconc minor-mode-alist
+           (list '(ace-window-mode ace-window-mode))))
+
+(defvar aw-empty-buffers-list nil
+  "Store the read-only empty buffers which had to be modified.
+Modify them back eventually.")
+
+(defun aw--done ()
+  "Clean up mode line and overlays."
+  ;; mode line
+  (aw-set-mode-line nil)
+  ;; background
+  (mapc #'delete-overlay aw-overlays-back)
+  (setq aw-overlays-back nil)
+  (avy--remove-leading-chars)
+  (dolist (b aw-empty-buffers-list)
+    (with-current-buffer b
+      (when (string= (buffer-string) " ")
+        (let ((inhibit-read-only t))
+          (delete-region (point-min) (point-max))))))
+  (setq aw-empty-buffers-list nil))
+
+(defun aw--overlay-str (wnd pos path)
+  "Return the replacement text for an overlay in WND at POS,
+accessible by typing PATH."
+  (let ((old-str (or
+                  (ignore-errors
+                    (with-selected-window wnd
+                      (buffer-substring pos (1+ pos))))
+                  "")))
+    (concat
+     (cl-case aw-leading-char-style
+       (char
+        (string (avy--key-to-char (car (last path)))))
+       (path
+        (mapconcat
+         (lambda (x) (string (avy--key-to-char x)))
+         (reverse path)
+         ""))
+       (t
+        (error "Bad `aw-leading-char-style': %S"
+               aw-leading-char-style)))
+     (cond ((string-equal old-str "\t")
+            (make-string (1- tab-width) ?\ ))
+           ((string-equal old-str "\n")
+            "\n")
+           (t
+            (make-string
+             (max 0 (1- (string-width old-str)))
+             ?\ ))))))
+
+(defun aw--lead-overlay (path leaf)
+  "Create an overlay using PATH at LEAF.
+LEAF is (PT . WND)."
+  (let ((wnd (cdr leaf)))
+    (with-selected-window wnd
+      (when (= 0 (buffer-size))
+        (push (current-buffer) aw-empty-buffers-list)
+        (let ((inhibit-read-only t))
+          (insert " ")))
+
+      (let* ((pt (car leaf))
+             (ol (make-overlay pt (1+ pt) (window-buffer wnd))))
+        (overlay-put ol 'display (aw--overlay-str wnd pt path))
+        (overlay-put ol 'face 'aw-leading-char-face)
+        (overlay-put ol 'window wnd)
+        (push ol avy--overlays-lead))
+
+      (when (eq aw-char-position 'left)
+        (let* ((pt
+                (save-excursion
+                  ;; Move to the start of the last visible line in the buffer.
+                  (move-to-window-line -1)
+                  (move-beginning-of-line nil)
+                  ;; If this line is empty, use the previous line so we
+                  ;; have space for the overlay.
+                  (when (equal (point) (point-max))
+                    (forward-line -1))
+                  (point)))
+               (ol (make-overlay pt (1+ pt) (window-buffer wnd))))
+          (overlay-put ol 'display (aw--overlay-str wnd pt path))
+          (overlay-put ol 'face 'aw-leading-char-face)
+          (overlay-put ol 'window wnd)
+          (push ol avy--overlays-lead))))))
+
+(defun aw--make-backgrounds (wnd-list)
+  "Create a dim background overlay for each window on WND-LIST."
+  (when aw-background
+    (setq aw-overlays-back
+          (mapcar (lambda (w)
+                    (let ((ol (make-overlay
+                               (window-start w)
+                               (window-end w)
+                               (window-buffer w))))
+                      (overlay-put ol 'face 'aw-background-face)
+                      ol))
+                  wnd-list))))
+
+(define-obsolete-variable-alias
+    'aw-flip-keys 'aw--flip-keys "0.1.0"
+    "Use `aw-dispatch-alist' instead.")
+
+(defvar aw-dispatch-function 'aw-dispatch-default
+  "Function to call when a character not in `aw-keys' is pressed.")
+
+(defvar aw-action nil
+  "Function to call at the end of `aw-select'.")
+
+(defun aw-set-mode-line (str)
+  "Set mode line indicator to STR."
+  (setq ace-window-mode str)
+  (when (and aw-minibuffer-flag ace-window-mode)
+    (message "%s" (string-trim-left str)))
+  (force-mode-line-update))
+
+(defun aw--dispatch-action (char)
+  "Return item from `aw-dispatch-alist' matching CHAR."
+  (assoc char aw-dispatch-alist))
+
+(defun aw-make-frame ()
+  "Make a new Emacs frame using the values of `aw-frame-size' and `aw-frame-offset'."
+  (make-frame
+   (delq nil
+         (list
+          ;; This first parameter is important because an
+          ;; aw-dispatch-alist command may not want to leave this
+          ;; frame with input focus.  If it is given focus, the
+          ;; command may not be able to return focus to a different
+          ;; frame since this is done asynchronously by the window
+          ;; manager.
+          '(no-focus-on-map . t)
+          (when aw-frame-size
+            (cons 'width
+                  (if (zerop (car aw-frame-size))
+                      (frame-width)
+                    (car aw-frame-size))))
+          (when aw-frame-size
+            (cons 'height
+                  (if (zerop (cdr aw-frame-size))
+                      (frame-height)
+                    (car aw-frame-size))))
+          (cons 'left (+ (car aw-frame-offset)
+                         (car (frame-position))))
+          (cons 'top (+ (cdr aw-frame-offset)
+                        (cdr (frame-position))))))))
+
+(defun aw-use-frame (window)
+  "Create a new frame using the contents of WINDOW.
+
+The new frame is set to the same size as the previous frame, offset by
+`aw-frame-offset' (x . y) pixels."
+  (aw-switch-to-window window)
+  (aw-make-frame))
+
+(defun aw-clean-up-avy-current-path ()
+  "Edit `avy-current-path' so only window label characters remain."
+  ;; Remove any possible ace-window command char that may
+  ;; precede the last specified window label, so
+  ;; functions can use `avy-current-path' as the chosen
+  ;; window label.
+  (when (and (> (length avy-current-path) 0)
+             (assq (aref avy-current-path 0) aw-dispatch-alist))
+    (setq avy-current-path (substring avy-current-path 1))))
+
+(defun aw-dispatch-default (char)
+  "Perform an action depending on CHAR."
+  (cond ((and (fboundp 'avy-mouse-event-window)
+              (avy-mouse-event-window char)))
+        ((= char (aref (kbd "C-g") 0))
+         (throw 'done 'exit))
+        ((= char aw-make-frame-char)
+         ;; Make a new frame and perform any action on its window.
+         (let ((start-win (selected-window))
+               (end-win (frame-selected-window (aw-make-frame))))
+           (if aw-action
+               ;; Action must be called from the start-win.  The action
+               ;; determines which window to leave selected.
+               (progn (select-frame-set-input-focus (window-frame start-win))
+                      (funcall aw-action end-win))
+             ;; Select end-win when no action
+             (aw-switch-to-window end-win)))
+         (throw 'done 'exit))
+        (t
+         (let ((action (aw--dispatch-action char)))
+           (if action
+               (cl-destructuring-bind (_key fn &optional description) action
+                 (if (and fn description)
+                     (prog1 (setq aw-action fn)
+                       (aw-set-mode-line (format " Ace - %s" description)))
+                   (funcall fn)
+                   (throw 'done 'exit)))
+             (aw-clean-up-avy-current-path)
+             ;; Prevent any char from triggering an avy dispatch command.
+             (let ((avy-dispatch-alist))
+               (avy-handler-default char)))))))
+
+(defun aw-select (mode-line &optional action)
+  "Return a selected other window.
+Amend MODE-LINE to the mode line for the duration of the selection."
+  (setq aw-action action)
+  (let ((start-window (selected-window))
+        (next-window-scope (cl-case aw-scope
+                             ('visible 'visible)
+                             ('global 'visible)
+                             ('frame 'frame)))
+        (wnd-list (aw-window-list))
+        window)
+    (setq window
+          (cond ((<= (length wnd-list) 1)
+                 (when aw-dispatch-always
+                   (setq aw-action
+                         (unwind-protect
+                              (catch 'done
+                                (funcall aw-dispatch-function (read-char)))
+                           (aw--done)))
+                   (when (eq aw-action 'exit)
+                     (setq aw-action nil)))
+                 (or (car wnd-list) start-window))
+                ((and (<= (length wnd-list) aw-dispatch-when-more-than)
+                      (not aw-dispatch-always)
+                      (not aw-ignore-current))
+                 (let ((wnd (next-window nil nil next-window-scope)))
+                   (while (and (or (not (memq wnd wnd-list))
+                                   (aw-ignored-p wnd))
+                               (not (equal wnd start-window)))
+                     (setq wnd (next-window wnd nil next-window-scope)))
+                   wnd))
+                (t
+                 (let ((candidate-list
+                        (mapcar (lambda (wnd)
+                                  (cons (aw-offset wnd) wnd))
+                                wnd-list)))
+                   (aw--make-backgrounds wnd-list)
+                   (aw-set-mode-line mode-line)
+                   ;; turn off helm transient map
+                   (remove-hook 'post-command-hook 'helm--maybe-update-keymap)
+                   (unwind-protect
+                        (let* ((avy-handler-function aw-dispatch-function)
+                               (avy-translate-char-function #'identity)
+                               (res (avy-read (avy-tree candidate-list aw-keys)
+                                              #'aw--lead-overlay
+                                              #'avy--remove-leading-chars)))
+                          (if (eq res 'exit)
+                              (setq aw-action nil)
+                            (or (cdr res)
+                                start-window)))
+                     (aw--done))))))
+    (if aw-action
+        (funcall aw-action window)
+      window)))
+
+;;* Interactive
+;;;###autoload
+(defun ace-select-window ()
+  "Ace select window."
+  (interactive)
+  (aw-select " Ace - Window"
+             #'aw-switch-to-window))
+
+;;;###autoload
+(defun ace-delete-window ()
+  "Ace delete window."
+  (interactive)
+  (aw-select " Ace - Delete Window"
+             #'aw-delete-window))
+
+;;;###autoload
+(defun ace-swap-window ()
+  "Ace swap window."
+  (interactive)
+  (aw-select " Ace - Swap Window"
+             #'aw-swap-window))
+
+;;;###autoload
+(defun ace-delete-other-windows ()
+  "Ace delete other windows."
+  (interactive)
+  (aw-select " Ace - Delete Other Windows"
+             #'delete-other-windows))
+
+(define-obsolete-function-alias
+    'ace-maximize-window 'ace-delete-other-windows "0.10.0")
+
+;;;###autoload
+(defun ace-window (arg)
+  "Select a window.
+Perform an action based on ARG described below.
+
+By default, behaves like extended `other-window'.
+
+Prefixed with one \\[universal-argument], does a swap between the
+selected window and the current window, so that the selected
+buffer moves to current window (and current buffer moves to
+selected window).
+
+Prefixed with two \\[universal-argument]'s, deletes the selected
+window."
+  (interactive "p")
+  (cl-case arg
+    (0
+     (setq aw-ignore-on
+           (not aw-ignore-on))
+     (ace-select-window))
+    (4 (ace-swap-window))
+    (16 (ace-delete-window))
+    (t (ace-select-window))))
+
+;;* Utility
+(unless (fboundp 'frame-position)
+  (defun frame-position (&optional frame)
+    (cons (frame-parameter frame 'left)
+          (frame-parameter frame 'top))))
+
+(defun aw-window< (wnd1 wnd2)
+  "Return true if WND1 is less than WND2.
+This is determined by their respective window coordinates.
+Windows are numbered top down, left to right."
+  (let ((f1 (window-frame wnd1))
+        (f2 (window-frame wnd2))
+        (e1 (window-edges wnd1))
+        (e2 (window-edges wnd2)))
+    (cond ((< (car (frame-position f1)) (car (frame-position f2)))
+           (not aw-reverse-frame-list))
+          ((> (car (frame-position f1)) (car (frame-position f2)))
+           aw-reverse-frame-list)
+          ((< (car e1) (car e2))
+           t)
+          ((> (car e1) (car e2))
+           nil)
+          ((< (cadr e1) (cadr e2))
+           t))))
+
+(defvar aw--window-ring (make-ring 10)
+  "Hold the window switching history.")
+
+(defun aw--push-window (window)
+  "Store WINDOW to `aw--window-ring'."
+  (when (or (zerop (ring-length aw--window-ring))
+            (not (equal
+                  (ring-ref aw--window-ring 0)
+                  window)))
+    (ring-insert aw--window-ring (selected-window))))
+
+(defun aw--pop-window ()
+  "Return the removed top of `aw--window-ring'."
+  (let (res)
+    (condition-case nil
+        (while (or (not (window-live-p
+                         (setq res (ring-remove aw--window-ring 0))))
+                   (equal res (selected-window))))
+      (error
+       (if (= (length (aw-window-list)) 2)
+           (progn
+             (other-window 1)
+             (setq res (selected-window)))
+         (error "No previous windows stored"))))
+    res))
+
+(defun aw-switch-to-window (window)
+  "Switch to the window WINDOW."
+  (let ((frame (window-frame window)))
+    (aw--push-window (selected-window))
+    (when (and (frame-live-p frame)
+               (not (eq frame (selected-frame))))
+      (select-frame-set-input-focus frame))
+    (if (window-live-p window)
+        (select-window window)
+      (error "Got a dead window %S" window))))
+
+(defun aw-flip-window ()
+  "Switch to the window you were previously in."
+  (interactive)
+  (aw-switch-to-window (aw--pop-window)))
+
+(defun aw-show-dispatch-help ()
+  "Display action shortucts in echo area."
+  (interactive)
+  (message "%s" (mapconcat
+                 (lambda (action)
+                   (cl-destructuring-bind (key fn &optional description) action
+                     (format "%s: %s"
+                             (propertize
+                              (char-to-string key)
+                              'face 'aw-key-face)
+                             (or description fn))))
+                 aw-dispatch-alist
+                 "\n"))
+  ;; Prevent this from replacing any help display
+  ;; in the minibuffer.
+  (let (aw-minibuffer-flag)
+    (mapc #'delete-overlay aw-overlays-back)
+    (call-interactively 'ace-window)))
+
+(defun aw-delete-window (window)
+  "Delete window WINDOW."
+  (let ((frame (window-frame window)))
+    (when (and (frame-live-p frame)
+               (not (eq frame (selected-frame))))
+      (select-frame-set-input-focus (window-frame window)))
+    (if (= 1 (length (window-list)))
+        (delete-frame frame)
+      (if (window-live-p window)
+          (delete-window window)
+        (error "Got a dead window %S" window)))))
+
+(defun aw-switch-buffer-in-window (window)
+  "Select buffer in WINDOW."
+  (aw-switch-to-window window)
+  (aw--switch-buffer))
+
+(declare-function ivy-switch-buffer "ext:ivy")
+
+(defun aw--switch-buffer ()
+  (cond ((bound-and-true-p ivy-mode)
+         (ivy-switch-buffer))
+        ((bound-and-true-p ido-mode)
+         (ido-switch-buffer))
+        (t
+         (call-interactively 'switch-to-buffer))))
+
+(defcustom aw-swap-invert nil
+  "When non-nil, the other of the two swapped windows gets the point."
+  :type 'boolean)
+
+(defun aw-swap-window (window)
+  "Swap buffers of current window and WINDOW."
+  (cl-labels ((swap-windows (window1 window2)
+                "Swap the buffers of WINDOW1 and WINDOW2."
+                (let ((buffer1 (window-buffer window1))
+                      (buffer2 (window-buffer window2)))
+                  (set-window-buffer window1 buffer2)
+                  (set-window-buffer window2 buffer1)
+                  (select-window window2))))
+    (let ((frame (window-frame window))
+          (this-window (selected-window)))
+      (when (and (frame-live-p frame)
+                 (not (eq frame (selected-frame))))
+        (select-frame-set-input-focus (window-frame window)))
+      (when (and (window-live-p window)
+                 (not (eq window this-window)))
+        (aw--push-window this-window)
+        (if aw-swap-invert
+            (swap-windows window this-window)
+          (swap-windows this-window window))))))
+
+(defun aw-move-window (window)
+  "Move the current buffer to WINDOW.
+Switch the current window to the previous buffer."
+  (let ((buffer (current-buffer)))
+    (switch-to-buffer (other-buffer))
+    (aw-switch-to-window window)
+    (switch-to-buffer buffer)))
+
+(defun aw-split-window-vert (window)
+  "Split WINDOW vertically."
+  (select-window window)
+  (split-window-vertically))
+
+(defun aw-split-window-horz (window)
+  "Split WINDOW horizontally."
+  (select-window window)
+  (split-window-horizontally))
+
+(defcustom aw-fair-aspect-ratio 2
+  "The aspect ratio to aim for when splitting windows.
+Sizes are based on the number of characters, not pixels.
+Increase to prefer wider windows, or decrease for taller windows."
+  :type 'number)
+
+(defun aw-split-window-fair (window)
+  "Split WINDOW vertically or horizontally, based on its current dimensions.
+Modify `aw-fair-aspect-ratio' to tweak behavior."
+  (let ((w (window-body-width window))
+        (h (window-body-height window)))
+    (if (< (* h aw-fair-aspect-ratio) w)
+        (aw-split-window-horz window)
+      (aw-split-window-vert window))))
+
+(defun aw-switch-buffer-other-window (window)
+  "Switch buffer in WINDOW without selecting WINDOW."
+  (aw-switch-to-window window)
+  (aw--switch-buffer)
+  (aw-flip-window))
+
+(defun aw-offset (window)
+  "Return point in WINDOW that's closest to top left corner.
+The point is writable, i.e. it's not part of space after newline."
+  (let ((h (window-hscroll window))
+        (beg (window-start window))
+        (end (window-end window))
+        (inhibit-field-text-motion t))
+    (with-current-buffer
+        (window-buffer window)
+      (save-excursion
+        (goto-char beg)
+        (while (and (< (point) end)
+                    (< (- (line-end-position)
+                          (line-beginning-position))
+                       h))
+          (forward-line))
+        (+ (point) h)))))
+
+;;* Mode line
+;;;###autoload
+(define-minor-mode ace-window-display-mode
+  "Minor mode for showing the ace window key in the mode line."
+  :global t
+  (if ace-window-display-mode
+      (progn
+        (aw-update)
+        (set-default
+         'mode-line-format
+         `((ace-window-display-mode
+            (:eval (window-parameter (selected-window) 'ace-window-path)))
+           ,@(assq-delete-all
+              'ace-window-display-mode
+              (default-value 'mode-line-format))))
+        (force-mode-line-update t)
+        (add-hook 'window-configuration-change-hook 'aw-update)
+        ;; Add at the end so does not precede select-frame call.
+        (add-hook 'after-make-frame-functions (lambda (_) (aw-update)) t))
+    (set-default
+     'mode-line-format
+     (assq-delete-all
+      'ace-window-display-mode
+      (default-value 'mode-line-format)))
+    (remove-hook 'window-configuration-change-hook 'aw-update)
+    (remove-hook 'after-make-frame-functions 'aw-update)))
+
+(defun aw-update ()
+  "Update ace-window-path window parameter for all windows.
+
+Ensure all windows are labeled so the user can select a specific
+one, even from the set of windows typically ignored when making a
+window list."
+  (let ((aw-ignore-on)
+        (aw-ignore-current)
+        (ignore-window-parameters t))
+    (avy-traverse
+     (avy-tree (aw-window-list) aw-keys)
+     (lambda (path leaf)
+       (set-window-parameter
+        leaf 'ace-window-path
+        (propertize
+         (apply #'string (reverse path))
+         'face 'aw-mode-line-face))))))
+
+(provide 'ace-window)
+
+;;; ace-window.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/ace-window-20180607.1223/ace-window.elc b/configs/shared/emacs/.emacs.d/elpa/ace-window-20180607.1223/ace-window.elc
new file mode 100644
index 0000000000..37b206070c
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/ace-window-20180607.1223/ace-window.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/add-node-modules-path-20180710.2342/add-node-modules-path-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/add-node-modules-path-20180710.2342/add-node-modules-path-autoloads.el
new file mode 100644
index 0000000000..3c43ba2bdb
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/add-node-modules-path-20180710.2342/add-node-modules-path-autoloads.el
@@ -0,0 +1,35 @@
+;;; add-node-modules-path-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "add-node-modules-path" "add-node-modules-path.el"
+;;;;;;  (23438 54284 226170 718000))
+;;; Generated autoloads from add-node-modules-path.el
+
+(defvar add-node-modules-path-debug nil "\
+Enable verbose output when non nil.")
+
+(custom-autoload 'add-node-modules-path-debug "add-node-modules-path" t)
+
+(defvar add-node-modules-max-depth 20 "\
+Max depth to look for node_modules.")
+
+(custom-autoload 'add-node-modules-max-depth "add-node-modules-path" t)
+
+(autoload 'add-node-modules-path "add-node-modules-path" "\
+Search the current buffer's parent directories for `node_modules/.bin`.
+Traverse the directory structure up, until reaching the user's home directory,
+ or hitting add-node-modules-max-depth.
+Any path found is added to the `exec-path'.
+
+\(fn)" t nil)
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; add-node-modules-path-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/add-node-modules-path-20180710.2342/add-node-modules-path-pkg.el b/configs/shared/emacs/.emacs.d/elpa/add-node-modules-path-20180710.2342/add-node-modules-path-pkg.el
new file mode 100644
index 0000000000..3c5d53fd57
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/add-node-modules-path-20180710.2342/add-node-modules-path-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "add-node-modules-path" "20180710.2342" "Add node_modules to your exec-path" 'nil :commit "f31e69ccb681f882aebb806ce6e9478e3ac39708" :keywords '("javascript" "node" "node_modules" "eslint") :authors '(("Neri Marschik" . "marschik_neri@cyberagent.co.jp")) :maintainer '("Neri Marschik" . "marschik_neri@cyberagent.co.jp") :url "https://github.com/codesuki/add-node-modules-path")
diff --git a/configs/shared/emacs/.emacs.d/elpa/add-node-modules-path-20180710.2342/add-node-modules-path.el b/configs/shared/emacs/.emacs.d/elpa/add-node-modules-path-20180710.2342/add-node-modules-path.el
new file mode 100644
index 0000000000..cd8adc0f8d
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/add-node-modules-path-20180710.2342/add-node-modules-path.el
@@ -0,0 +1,79 @@
+;;; add-node-modules-path.el --- Add node_modules to your exec-path
+
+;; Copyright (C) 2016 Neri Marschik
+;; This package uses the MIT License.
+;; See the LICENSE file.
+
+;; Author: Neri Marschik <marschik_neri@cyberagent.co.jp>
+;; Version: 1.0
+;; Package-Version: 20180710.2342
+;; Package-Requires: ()
+;; Keywords: javascript, node, node_modules, eslint
+;; URL: https://github.com/codesuki/add-node-modules-path
+
+;;; Commentary:
+;;
+;; This file provides `add-node-modules-path', which searches
+;; the current files parent directories for the `node_modules/.bin/' directory
+;; and adds it to the buffer local `exec-path'.
+;; This allows Emacs to find project based installs of e.g. eslint.
+;;
+;; Usage:
+;;     M-x add-node-modules-path
+;;
+;;     To automatically run it when opening a new buffer:
+;;     (Choose depending on your favorite mode.)
+;;
+;;     (eval-after-load 'js-mode
+;;       '(add-hook 'js-mode-hook #'add-node-modules-path))
+;;
+;;     (eval-after-load 'js2-mode
+;;       '(add-hook 'js2-mode-hook #'add-node-modules-path))
+
+;;; Code:
+
+;;;###autoload
+(defcustom add-node-modules-path-debug nil
+  "Enable verbose output when non nil."
+  :type 'boolean)
+
+;;;###autoload
+(defcustom add-node-modules-max-depth 20
+  "Max depth to look for node_modules."
+  :type 'integer)
+
+;;;###autoload
+(defun add-node-modules-path ()
+  "Search the current buffer's parent directories for `node_modules/.bin`.
+Traverse the directory structure up, until reaching the user's home directory,
+ or hitting add-node-modules-max-depth.
+Any path found is added to the `exec-path'."
+  (interactive)
+  (let* ((default-dir (expand-file-name default-directory))
+         (file (or (buffer-file-name) default-dir))
+         (home (expand-file-name "~"))
+         (iterations add-node-modules-max-depth)
+         (root (directory-file-name (or (and (buffer-file-name) (file-name-directory (buffer-file-name))) default-dir)))
+         (roots '()))
+    (while (and root (> iterations 0))
+      (setq iterations (1- iterations))
+      (let ((bindir (expand-file-name "node_modules/.bin/" root)))
+        (when (file-directory-p bindir)
+          (add-to-list 'roots bindir)))
+      (if (string= root home)
+          (setq root nil)
+        (setq root (directory-file-name (file-name-directory root)))))
+    (if roots
+        (progn
+          (make-local-variable 'exec-path)
+          (while roots
+            (add-to-list 'exec-path (car roots))
+            (when add-node-modules-path-debug
+              (message (concat "added " (car roots) " to exec-path")))
+            (setq roots (cdr roots))))
+      (when add-node-modules-path-debug
+        (message (concat "node_modules/.bin not found for " file))))))
+
+(provide 'add-node-modules-path)
+
+;;; add-node-modules-path.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/add-node-modules-path-20180710.2342/add-node-modules-path.elc b/configs/shared/emacs/.emacs.d/elpa/add-node-modules-path-20180710.2342/add-node-modules-path.elc
new file mode 100644
index 0000000000..a8db407d77
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/add-node-modules-path-20180710.2342/add-node-modules-path.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/alert-20180403.38/alert-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/alert-20180403.38/alert-autoloads.el
new file mode 100644
index 0000000000..ddd84066fc
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/alert-20180403.38/alert-autoloads.el
@@ -0,0 +1,94 @@
+;;; alert-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "alert" "alert.el" (23377 61297 758177 48000))
+;;; Generated autoloads from alert.el
+
+(autoload 'alert-add-rule "alert" "\
+Programmatically add an alert configuration rule.
+
+Normally, users should custoimze `alert-user-configuration'.
+This facility is for module writers and users that need to do
+things the Lisp way.
+
+Here is a rule the author currently uses with ERC, so that the
+fringe gets colored whenever people chat on BitlBee:
+
+\(alert-add-rule :status   \\='(buried visible idle)
+                :severity \\='(moderate high urgent)
+                :mode     \\='erc-mode
+                :predicate
+                #\\='(lambda (info)
+                    (string-match (concat \"\\\\`[^&].*@BitlBee\\\\\\='\")
+                                  (erc-format-target-and/or-network)))
+                :persistent
+                #\\='(lambda (info)
+                    ;; If the buffer is buried, or the user has been
+                    ;; idle for `alert-reveal-idle-time' seconds,
+                    ;; make this alert persistent.  Normally, alerts
+                    ;; become persistent after
+                    ;; `alert-persist-idle-time' seconds.
+                    (memq (plist-get info :status) \\='(buried idle)))
+                :style \\='fringe
+                :continue t)
+
+\(fn &key SEVERITY STATUS MODE CATEGORY TITLE MESSAGE PREDICATE ICON (style alert-default-style) PERSISTENT CONTINUE NEVER-PERSIST APPEND)" nil nil)
+
+(autoload 'alert "alert" "\
+Alert the user that something has happened.
+MESSAGE is what the user will see.  You may also use keyword
+arguments to specify additional details.  Here is a full example:
+
+\(alert \"This is a message\"
+       :severity \\='high          ;; The default severity is `normal'
+       :title \"Title\"           ;; An optional title
+       :category \\='example       ;; A symbol to identify the message
+       :mode \\='text-mode         ;; Normally determined automatically
+       :buffer (current-buffer) ;; This is the default
+       :data nil                ;; Unused by alert.el itself
+       :persistent nil          ;; Force the alert to be persistent;
+                                ;; it is best not to use this
+       :never-persist nil       ;; Force this alert to never persist
+       :id \\='my-id)              ;; Used to replace previous message of
+                                ;; the same id in styles that support it
+       :style \\='fringe)          ;; Force a given style to be used;
+                                ;; this is only for debugging!
+
+If no :title is given, the buffer-name of :buffer is used.  If
+:buffer is nil, it is the current buffer at the point of call.
+
+:data is an opaque value which modules can pass through to their
+own styles if they wish.
+
+Here are some more typical examples of usage:
+
+  ;; This is the most basic form usage
+  (alert \"This is an alert\")
+
+  ;; You can adjust the severity for more important messages
+  (alert \"This is an alert\" :severity \\='high)
+
+  ;; Or decrease it for purely informative ones
+  (alert \"This is an alert\" :severity \\='trivial)
+
+  ;; Alerts can have optional titles.  Otherwise, the title is the
+  ;; buffer-name of the (current-buffer) where the alert originated.
+  (alert \"This is an alert\" :title \"My Alert\")
+
+  ;; Further, alerts can have categories.  This allows users to
+  ;; selectively filter on them.
+  (alert \"This is an alert\" :title \"My Alert\"
+         :category \\='some-category-or-other)
+
+\(fn MESSAGE &key (severity (quote normal)) TITLE ICON CATEGORY BUFFER MODE DATA STYLE PERSISTENT NEVER-PERSIST ID)" nil nil)
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; alert-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/alert-20180403.38/alert-pkg.el b/configs/shared/emacs/.emacs.d/elpa/alert-20180403.38/alert-pkg.el
new file mode 100644
index 0000000000..5c9a799599
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/alert-20180403.38/alert-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "alert" "20180403.38" "Growl-style notification system for Emacs" '((gntp "0.1") (log4e "0.3.0")))
diff --git a/configs/shared/emacs/.emacs.d/elpa/alert-20180403.38/alert.el b/configs/shared/emacs/.emacs.d/elpa/alert-20180403.38/alert.el
new file mode 100644
index 0000000000..0741f5410c
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/alert-20180403.38/alert.el
@@ -0,0 +1,1161 @@
+;;; alert.el --- Growl-style notification system for Emacs
+
+;; Copyright (C) 2011-2013 John Wiegley
+
+;; Author: John Wiegley <jwiegley@gmail.com>
+;; Created: 24 Aug 2011
+;; Updated: 16 Mar 2015
+;; Version: 1.2
+;; Package-Version: 20180403.38
+;; Package-Requires: ((gntp "0.1") (log4e "0.3.0"))
+;; Keywords: notification emacs message
+;; X-URL: https://github.com/jwiegley/alert
+
+;; This program 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 2, or (at
+;; your option) any later version.
+
+;; This program 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; see the file COPYING.  If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+
+;; Alert is a Growl-workalike for Emacs which uses a common notification
+;; interface and multiple, selectable "styles", whose use is fully
+;; customizable by the user.
+;;
+;; * For module writers
+;;
+;; Just use `alert' instead of `message' as follows:
+;;
+;;   (require 'alert)
+;;
+;;   ;; This is the most basic form usage
+;;   (alert "This is an alert")
+;;
+;;   ;; You can adjust the severity for more important messages
+;;   (alert "This is an alert" :severity 'high)
+;;
+;;   ;; Or decrease it for purely informative ones
+;;   (alert "This is an alert" :severity 'trivial)
+;;
+;;   ;; Alerts can have optional titles.  Otherwise, the title is the
+;;   ;; buffer-name of the (current-buffer) where the alert originated.
+;;   (alert "This is an alert" :title "My Alert")
+;;
+;;   ;; Further, alerts can have categories.  This allows users to
+;;   ;; selectively filter on them.
+;;   (alert "This is an alert" :title "My Alert" :category 'debug)
+;;
+;; * For users
+;;
+;; For the user, there are several variables to control when and how alerts
+;; are presented.  By default, they appear in the minibuffer much the same
+;; as a normal Emacs message.  But there are many more possibilities:
+;;
+;;   `alert-fade-time'
+;;     Normally alerts disappear after this many seconds, if the style
+;;     supports it.  The default is 5 seconds.
+;;
+;;   `alert-default-style'
+;;     Pick the style to use if no other config rule matches.  The
+;;     default is `message', but `growl' works well too.
+;;
+;;   `alert-reveal-idle-time'
+;;     If a config rule choose to match on `idle', this is how many
+;;     seconds idle the user has to be.  Defaults to 5 so that users
+;;     don't miss any alerts, but 120 is also good.
+;;
+;;   `alert-persist-idle-time'
+;;     After this many idle seconds, alerts will become sticky, and not
+;;     fade away more.  The default is 15 minutes.
+;;
+;;   `alert-log-messages'
+;;     By default, all alerts are logged to *Alerts* (and to *Messages*,
+;;     if the `message' style is being used).  Set to nil to disable.
+;;
+;;   `alert-hide-all-notifications'
+;;     Want alerts off entirely?  They still get logged, however, unless
+;;     you've turned that off too.
+;;
+;;   `alert-user-configuration'
+;;     This variable lets you control exactly how and when a particular
+;;     alert, a class of alerts, or all alerts, get reported -- or if at
+;;     all.  Use this to make some alerts use Growl, while others are
+;;     completely silent.
+;;
+;; * Programmatically adding rules
+;;
+;; Users can also programmatically add configuration rules, in addition to
+;; customizing `alert-user-configuration'.  Here is one that the author
+;; currently uses with ERC, so that the fringe gets colored whenever people
+;; chat on BitlBee:
+;;
+;;  (alert-add-rule :status   '(buried visible idle)
+;;                  :severity '(moderate high urgent)
+;;                  :mode     'erc-mode
+;;                  :predicate
+;;                  #'(lambda (info)
+;;                      (string-match (concat "\\`[^&].*@BitlBee\\'")
+;;                                    (erc-format-target-and/or-network)))
+;;                  :persistent
+;;                  #'(lambda (info)
+;;                      ;; If the buffer is buried, or the user has been
+;;                      ;; idle for `alert-reveal-idle-time' seconds,
+;;                      ;; make this alert persistent.  Normally, alerts
+;;                      ;; become persistent after
+;;                      ;; `alert-persist-idle-time' seconds.
+;;                      (memq (plist-get info :status) '(buried idle)))
+;;                  :style 'fringe
+;;                  :continue t)
+;;
+;; * Builtin alert styles
+;;
+;; There are several builtin styles, and it is trivial to create new ones.
+;; The builtins are:
+;;
+;;   fringe        - Changes the current frame's fringe background color
+;;   mode-line     - Changes the current frame's mode-line background color
+;;   gntp          - Uses gntp, it requires gntp.el (see https://github.com/tekai/gntp.el)
+;;   growl         - Uses Growl on OS X, if growlnotify is on the PATH
+;;   ignore        - Ignores the alert entirely
+;;   libnotify     - Uses libnotify if notify-send is on the PATH
+;;   log           - Logs the alert text to *Alerts*, with a timestamp
+;;   message       - Uses the Emacs `message' facility
+;;   momentary     - Uses the Emacs `momentary-string-display' facility
+;;   notifications - Uses notifications library via D-Bus
+;;   notifier      - Uses terminal-notifier on OS X, if it is on the PATH
+;;   osx-notifier  - Native OSX notifier using AppleScript
+;;   toaster       - Use the toast notification system
+;;   x11 -         - Changes the urgency property of the window in the X Window System
+;;
+;; * Defining new styles
+;;
+;; To create a new style, you need to at least write a "notifier", which is
+;; a function that receives the details of the alert.  These details are
+;; given in a plist which uses various keyword to identify the parts of the
+;; alert.  Here is a prototypical style definition:
+;;
+;;  (alert-define-style 'style-name :title "My Style's title"
+;;                      :notifier
+;;                      (lambda (info)
+;;                        ;; The message text is :message
+;;                        (plist-get info :message)
+;;                        ;; The :title of the alert
+;;                        (plist-get info :title)
+;;                        ;; The :category of the alert
+;;                        (plist-get info :category)
+;;                        ;; The major-mode this alert relates to
+;;                        (plist-get info :mode)
+;;                        ;; The buffer the alert relates to
+;;                        (plist-get info :buffer)
+;;                        ;; Severity of the alert.  It is one of:
+;;                        ;;   `urgent'
+;;                        ;;   `high'
+;;                        ;;   `moderate'
+;;                        ;;   `normal'
+;;                        ;;   `low'
+;;                        ;;   `trivial'
+;;                        (plist-get info :severity)
+;;                        ;; Whether this alert should persist, or fade away
+;;                        (plist-get info :persistent)
+;;                        ;; Data which was passed to `alert'.  Can be
+;;                        ;; anything.
+;;                        (plist-get info :data))
+;;
+;;                      ;; Removers are optional.  Their job is to remove
+;;                      ;; the visual or auditory effect of the alert.
+;;                      :remover
+;;                      (lambda (info)
+;;                        ;; It is the same property list that was passed to
+;;                        ;; the notifier function.
+;;                        ))
+;;
+;; You can test a specific style with something like this:
+;;
+;; (let ((alert-user-configuration '((((:severity high)) momentary nil))))
+;;   (alert "Same buffer momentary alert" :title "My Alert" :severity 'high)
+;;   (alert "This is a momentary alert in another visible buffer" :title "My Alert"
+;;          :severity 'high :buffer (other-buffer (current-buffer) t)))
+
+;;; Code:
+
+(eval-when-compile
+  (require 'cl))
+(require 'gntp nil t)
+(eval-when-compile
+  ;; if not available, silence the byte compiler
+  (defvar gntp-server))
+(declare-function gntp-notify "gntp")
+(require 'notifications nil t)
+(require 'log4e nil t)
+
+;; shut up the byte compiler
+(declare-function alert-gntp-notify "alert")
+(declare-function alert-notifications-notify "alert")
+
+(defgroup alert nil
+  "Notification system for Emacs similar to Growl"
+  :group 'emacs)
+
+(defcustom alert-severity-faces
+  '((urgent   . alert-urgent-face)
+    (high     . alert-high-face)
+    (moderate . alert-moderate-face)
+    (normal   . alert-normal-face)
+    (low      . alert-low-face)
+    (trivial  . alert-trivial-face))
+  "Faces associated by default with alert severities."
+  :type '(alist :key-type symbol :value-type color)
+  :group 'alert)
+
+(defcustom alert-severity-colors
+  '((urgent   . "red")
+    (high     . "orange")
+    (moderate . "yellow")
+    (normal   . "green")
+    (low      . "blue")
+    (trivial  . "purple"))
+  "Colors associated by default with alert severities.
+This is used by styles external to Emacs that don't understand faces."
+  :type '(alist :key-type symbol :value-type color)
+  :group 'alert)
+
+(defcustom alert-log-severity-functions
+  '((urgent   . alert--log-fatal)
+    (high     . alert--log-error)
+    (moderate . alert--log-warn)
+    (normal   . alert--log-info)
+    (low      . alert--log-debug)
+    (trivial  . alert--log-trace))
+  "Log4e logging functions"
+  :type '(alist :key-type symbol :value-type color)
+  :group 'alert)
+
+(defcustom alert-log-level
+  'normal
+  "Minimum level of messages to log"
+  :type 'symbol
+  :group 'alert)
+
+(defcustom alert-reveal-idle-time 15
+  "If idle this many seconds, rules will match the `idle' property."
+  :type 'integer
+  :group 'alert)
+
+(defcustom alert-persist-idle-time 900
+  "If idle this many seconds, all alerts become persistent.
+This can be overriden with the Never Persist option (:never-persist)."
+  :type 'integer
+  :group 'alert)
+
+(defcustom alert-fade-time 5
+  "If not idle, alerts disappear after this many seconds.
+The amount of idle time is governed by `alert-persist-idle-time'."
+  :type 'integer
+  :group 'alert)
+
+(defcustom alert-hide-all-notifications nil
+  "If non-nil, no alerts are ever shown to the user."
+  :type 'boolean
+  :group 'alert)
+
+(defcustom alert-log-messages t
+  "If non-nil, all alerts are logged to the *Alerts* buffer."
+  :type 'boolean
+  :group 'alert)
+
+(defcustom alert-default-icon
+  (concat data-directory
+          "images/icons/hicolor/scalable/apps/emacs.svg")
+  "Filename of default icon to show for libnotify-alerts."
+  :type 'string
+  :group 'alert)
+
+(defvar alert-styles nil)
+
+(defun alert-styles-radio-type (widget-name)
+  (append
+   (list widget-name :tag "Style")
+   (mapcar #'(lambda (style)
+               (list 'const
+                     :tag (or (plist-get (cdr style) :title)
+                              (symbol-name (car style)))
+                     (car style)))
+           (setq alert-styles
+                 (sort alert-styles
+                       #'(lambda (l r)
+                           (string< (symbol-name (car l))
+                                    (symbol-name (car r)))))))))
+
+(defcustom alert-default-style 'message
+  "The style to use if no rules match in the current configuration.
+If a configured rule does match an alert, this style is not used;
+it is strictly a fallback."
+  :type (alert-styles-radio-type 'radio)
+  :group 'alert)
+
+(defun alert-configuration-type ()
+  (list 'repeat
+        (list
+         'list :tag "Select style if alert matches selector"
+         '(repeat
+           :tag "Selector"
+           (choice
+            (cons :tag "Severity"
+                  (const :format "" :severity)
+                  (set (const :tag "Urgent" urgent)
+                       (const :tag "High" high)
+                       (const :tag "Moderate" moderate)
+                       (const :tag "Normal" normal)
+                       (const :tag "Low" low)
+                       (const :tag "Trivial" trivial)))
+            (cons :tag "User Status"
+                  (const :format "" :status)
+                  (set (const :tag "Buffer not visible" buried)
+                       (const :tag "Buffer visible" visible)
+                       (const :tag "Buffer selected" selected)
+                       (const :tag "Buffer selected, user idle" idle)))
+            (cons :tag "Major Mode"
+                  (const :format "" :mode)
+                  regexp)
+            (cons :tag "Category"
+                  (const :format "" :category)
+                  regexp)
+            (cons :tag "Title"
+                  (const :format "" :title)
+                  regexp)
+            (cons :tag "Message"
+                  (const :format "" :message)
+                  regexp)
+            (cons :tag "Predicate"
+                  (const :format "" :predicate)
+                  function)
+            (cons :tag "Icon"
+                  (const :format "" :icon)
+                  regexp)))
+         (alert-styles-radio-type 'choice)
+         '(set :tag "Options"
+               (cons :tag "Make alert persistent"
+                     (const :format "" :persistent)
+                     (choice :value t (const :tag "Yes" t)
+                             (function :tag "Predicate")))
+               (cons :tag "Never persist"
+                     (const :format "" :never-persist)
+                     (choice :value t (const :tag "Yes" t)
+                             (function :tag "Predicate")))
+               (cons :tag "Continue to next rule"
+                     (const :format "" :continue)
+                     (choice :value t (const :tag "Yes" t)
+                             (function :tag "Predicate")))
+               ;;(list :tag "Change Severity"
+               ;;      (radio :tag "From"
+               ;;             (const :tag "Urgent" urgent)
+               ;;             (const :tag "High" high)
+               ;;             (const :tag "Moderate" moderate)
+               ;;             (const :tag "Normal" normal)
+               ;;             (const :tag "Low" low)
+               ;;             (const :tag "Trivial" trivial))
+               ;;      (radio :tag "To"
+               ;;             (const :tag "Urgent" urgent)
+               ;;             (const :tag "High" high)
+               ;;             (const :tag "Moderate" moderate)
+               ;;             (const :tag "Normal" normal)
+               ;;             (const :tag "Low" low)
+               ;;             (const :tag "Trivial" trivial)))
+               ))))
+
+(defcustom alert-user-configuration nil
+  "Rules that determine how and when alerts get displayed."
+  :type (alert-configuration-type)
+  :group 'alert)
+
+(defvar alert-internal-configuration nil
+  "Rules added by `alert-add-rule'.
+For user customization, see `alert-user-configuration'.")
+
+(defface alert-urgent-face
+  '((t (:foreground "Red" :bold t)))
+  "Urgent alert face."
+  :group 'alert)
+
+(defface alert-high-face
+  '((t (:foreground "Dark Orange" :bold t)))
+  "High alert face."
+  :group 'alert)
+
+(defface alert-moderate-face
+  '((t (:foreground "Gold" :bold t)))
+  "Moderate alert face."
+  :group 'alert)
+
+(defface alert-normal-face
+  '((t))
+  "Normal alert face."
+  :group 'alert)
+
+(defface alert-low-face
+  '((t (:foreground "Dark Blue")))
+  "Low alert face."
+  :group 'alert)
+
+(defface alert-trivial-face
+  '((t (:foreground "Dark Purple")))
+  "Trivial alert face."
+  :group 'alert)
+
+(defun alert-define-style (name &rest plist)
+  "Define a new style for notifying the user of alert messages.
+To create a new style, you need to at least write a \"notifier\",
+which is a function that receives the details of the alert.
+These details are given in a plist which uses various keyword to
+identify the parts of the alert.  Here is a prototypical style
+definition:
+
+\(alert-define-style 'style-name :title \"My Style's title\"
+                    :notifier
+                    (lambda (info)
+                      ;; The message text is :message
+                      (plist-get info :message)
+                      ;; The :title of the alert
+                      (plist-get info :title)
+                      ;; The :category of the alert
+                      (plist-get info :category)
+                      ;; The major-mode this alert relates to
+                      (plist-get info :mode)
+                      ;; The buffer the alert relates to
+                      (plist-get info :buffer)
+                      ;; Severity of the alert.  It is one of:
+                      ;;   `urgent'
+                      ;;   `high'
+                      ;;   `moderate'
+                      ;;   `normal'
+                      ;;   `low'
+                      ;;   `trivial'
+                      (plist-get info :severity)
+                      ;; Whether this alert should persist, or fade away
+                      (plist-get info :persistent)
+                      ;; Data which was passed to `alert'.  Can be
+                      ;; anything.
+                      (plist-get info :data))
+
+                    ;; Removers are optional.  Their job is to remove
+                    ;; the visual or auditory effect of the alert.
+                    :remover
+                    (lambda (info)
+                      ;; It is the same property list that was passed to
+                      ;; the notifier function.
+                      ))"
+  (add-to-list 'alert-styles (cons name plist))
+  (put 'alert-user-configuration 'custom-type (alert-configuration-type))
+  (put 'alert-define-style 'custom-type (alert-styles-radio-type 'radio)))
+
+(alert-define-style 'ignore :title "Ignore Alert"
+                    :notifier #'ignore
+                    :remover #'ignore)
+
+;;;###autoload
+(defun* alert-add-rule (&key severity status mode category title
+                             message predicate icon (style alert-default-style)
+                             persistent continue never-persist append)
+  "Programmatically add an alert configuration rule.
+
+Normally, users should custoimze `alert-user-configuration'.
+This facility is for module writers and users that need to do
+things the Lisp way.
+
+Here is a rule the author currently uses with ERC, so that the
+fringe gets colored whenever people chat on BitlBee:
+
+\(alert-add-rule :status   \\='(buried visible idle)
+                :severity \\='(moderate high urgent)
+                :mode     \\='erc-mode
+                :predicate
+                #\\='(lambda (info)
+                    (string-match (concat \"\\\\`[^&].*@BitlBee\\\\\\='\")
+                                  (erc-format-target-and/or-network)))
+                :persistent
+                #\\='(lambda (info)
+                    ;; If the buffer is buried, or the user has been
+                    ;; idle for `alert-reveal-idle-time' seconds,
+                    ;; make this alert persistent.  Normally, alerts
+                    ;; become persistent after
+                    ;; `alert-persist-idle-time' seconds.
+                    (memq (plist-get info :status) \\='(buried idle)))
+                :style \\='fringe
+                :continue t)"
+  (let ((rule (list (list t) style (list t))))
+    (if severity
+        (nconc (nth 0 rule)
+               (list (cons :severity
+                           (if (listp severity)
+                               severity
+                             (list severity))))))
+    (if status
+        (nconc (nth 0 rule)
+               (list (cons :status
+                           (if (listp status)
+                               status
+                             (list status))))))
+    (if mode
+        (nconc (nth 0 rule)
+               (list (cons :mode
+                           (if (stringp mode)
+                               mode
+                             (concat "\\`" (symbol-name mode)
+                                     "\\'"))))))
+    (if category
+        (nconc (nth 0 rule) (list (cons :category category))))
+    (if title
+        (nconc (nth 0 rule) (list (cons :title title))))
+    (if message
+        (nconc (nth 0 rule) (list (cons :message message))))
+    (if predicate
+        (nconc (nth 0 rule) (list (cons :predicate predicate))))
+    (if icon
+        (nconc (nth 0 rule) (list (cons :icon icon))))
+    (setcar rule (cdr (nth 0 rule)))
+
+    (if persistent
+        (nconc (nth 2 rule) (list (cons :persistent persistent))))
+    (if never-persist
+        (nconc (nth 2 rule) (list (cons :never-persist never-persist))))
+    (if continue
+        (nconc (nth 2 rule) (list (cons :continue continue))))
+    (setcdr (cdr rule) (list (cdr (nth 2 rule))))
+
+    (if (null alert-internal-configuration)
+        (setq alert-internal-configuration (list rule))
+      (if append
+          (nconc alert-internal-configuration (list rule))
+        (setq alert-internal-configuration
+              (cons rule alert-internal-configuration))))
+
+    rule))
+
+(alert-define-style 'ignore :title "Don't display alerts")
+
+(defun alert-log-notify (info)
+  (let* ((mes (plist-get info :message))
+         (sev (plist-get info :severity))
+         (len (length mes))
+         (func (cdr (assoc sev alert-log-severity-functions))))
+    (if (not (featurep 'log4e))
+        (alert-legacy-log-notify mes sev len)
+      ;; when we get here you better be using log4e or have your logging
+      ;; functions defined
+      (if (fboundp func)
+          (apply func (list mes))
+        (when (fboundp 'log4e:deflogger)
+          (log4e:deflogger "alert" "%t [%l] %m" "%H:%M:%S")
+          (when (functionp 'alert--log-set-level)
+            (alert--log-set-level alert-log-level)))))))
+
+(defun alert-legacy-log-notify (mes sev len)
+  (with-current-buffer
+      (get-buffer-create "*Alerts*")
+    (goto-char (point-max))
+    (insert (format-time-string "%H:%M %p - "))
+    (insert mes)
+    (set-text-properties (- (point) len) (point)
+                       (list 'face (cdr (assq sev
+                                              alert-severity-faces))))
+    (insert ?\n)))
+
+(defun alert-log-clear (info)
+  (if (functionp 'alert--log-clear-log)
+      (alert--log-clear-log)
+    (if (bufferp "*Alerts*")
+        (with-current-buffer
+            (get-buffer-create "*Alerts*")
+          (goto-char (point-max))
+          (insert (format-time-string "%H:%M %p - ")
+                  "Clear: " (plist-get info :message)
+                  ?\n)))))
+
+(alert-define-style 'log :title "Log to *Alerts* buffer"
+                    :notifier #'alert-log-notify
+                    ;;:remover #'alert-log-clear
+                    )
+
+(defun alert-message-notify (info)
+  ;; the message text might contain `%' and we don't want them to be
+  ;; interpreted as format specifiers:
+  (message "%s" (plist-get info :message))
+  ;;(if (memq (plist-get info :severity) '(high urgency))
+  ;;    (ding))
+  )
+
+(defun alert-message-remove (info)
+  (message ""))
+
+(alert-define-style 'message :title "Display message in minibuffer"
+                    :notifier #'alert-message-notify
+                    :remover #'alert-message-remove)
+
+(defun alert-momentary-notify (info)
+  (save-excursion
+    (with-current-buffer (or (plist-get info :buffer) (current-buffer))
+      (momentary-string-display
+       (format "%s: %s (%s/%s/%s)"
+               (or (plist-get info :title) "untitled")
+               (or (plist-get info :message) "no message")
+               (or (plist-get info :severity) "no priority")
+               (or (plist-get info :category) "no category")
+               (or (plist-get info :mode) "no mode"))
+       (progn
+         (beginning-of-line)
+         (point))))))
+
+(alert-define-style 'momentary :title "Display message momentarily in buffer"
+                    :notifier #'alert-momentary-notify
+                    ;; explicitly, we don't need a remover
+                    :remover #'ignore)
+
+(copy-face 'fringe 'alert-saved-fringe-face)
+
+(defun alert-fringe-notify (info)
+  (set-face-background 'fringe (cdr (assq (plist-get info :severity)
+                                          alert-severity-colors))))
+
+(defun alert-fringe-restore (info)
+  (copy-face 'alert-saved-fringe-face 'fringe))
+
+(alert-define-style 'fringe :title "Change the fringe color"
+                    :notifier #'alert-fringe-notify
+                    :remover #'alert-fringe-restore)
+
+
+(defun alert-mode-line-notify (info)
+  (copy-face 'mode-line 'alert-saved-mode-line-face)
+  (set-face-background 'mode-line (cdr (assq (plist-get info :severity)
+                                             alert-severity-colors)))
+  (set-face-foreground 'mode-line "white"))
+
+(defun alert-mode-line-restore (info)
+  (copy-face 'alert-saved-mode-line-face 'mode-line))
+
+(alert-define-style 'mode-line :title "Change the mode-line color"
+                    :notifier #'alert-mode-line-notify
+                    :remover #'alert-mode-line-restore)
+
+
+
+(defcustom alert-growl-command (executable-find "growlnotify")
+  "Path to the growlnotify command.
+This is found in the Growl Extras: http://growl.info/extras.php."
+  :type 'file
+  :group 'alert)
+
+(defcustom alert-growl-priorities
+  '((urgent   . 2)
+    (high     . 2)
+    (moderate . 1)
+    (normal   . 0)
+    (low      . -1)
+    (trivial  . -2))
+  "A mapping of alert severities onto Growl priority values."
+  :type '(alist :key-type symbol :value-type integer)
+  :group 'alert)
+
+(defsubst alert-encode-string (str)
+  (encode-coding-string str (keyboard-coding-system)))
+
+(defun alert-growl-notify (info)
+  (if alert-growl-command
+      (let ((args
+             (list "--appIcon"  "Emacs"
+                   "--name"     "Emacs"
+                   "--title"    (alert-encode-string (plist-get info :title))
+                   "--message"  (alert-encode-string (plist-get info :message))
+                   "--priority" (number-to-string
+                                 (cdr (assq (plist-get info :severity)
+                                            alert-growl-priorities))))))
+        (if (and (plist-get info :persistent)
+                 (not (plist-get info :never-persist)))
+            (nconc args (list "--sticky")))
+        (apply #'call-process alert-growl-command nil nil nil args))
+    (alert-message-notify info)))
+
+(alert-define-style 'growl :title "Notify using Growl"
+                    :notifier #'alert-growl-notify)
+
+
+(defcustom alert-libnotify-command (executable-find "notify-send")
+  "Path to the notify-send command.
+This is found in the libnotify-bin package in Debian based
+systems."
+  :type 'file
+  :group 'alert)
+
+(defcustom alert-libnotify-additional-args
+  nil
+  "Additional args to pass to notify-send.
+Must be a list of strings."
+  :type '(repeat string)
+  :group 'alert)
+
+(defcustom alert-libnotify-priorities
+  '((urgent   . critical)
+    (high     . critical)
+    (moderate . normal)
+    (normal   . normal)
+    (low      . low)
+    (trivial  . low))
+  "A mapping of alert severities onto libnotify priority values."
+  :type '(alist :key-type symbol :value-type symbol)
+  :group 'alert)
+
+(defun alert-libnotify-notify (info)
+  "Send INFO using notify-send.
+Handles :ICON, :CATEGORY, :SEVERITY, :PERSISTENT, :NEVER-PERSIST, :TITLE
+and :MESSAGE keywords from the INFO plist.  :CATEGORY can be
+passed as a single symbol, a string or a list of symbols or
+strings."
+  (if alert-libnotify-command
+      (let* ((args
+              (append
+               (list "--icon"     (or (plist-get info :icon)
+                                      alert-default-icon)
+                     "--app-name" "Emacs"
+                     "--urgency"  (let ((urgency (cdr (assq
+                                                       (plist-get info :severity)
+                                                       alert-libnotify-priorities))))
+                                    (if urgency
+                                        (symbol-name urgency)
+                                      "normal")))
+               alert-libnotify-additional-args))
+             (category (plist-get info :category)))
+        (nconc args
+               (list "--expire-time"
+                     (number-to-string
+                      (* 1000 ; notify-send takes msecs
+                         (if (and (plist-get info :persistent)
+                                  (not (plist-get info :never-persist)))
+                             0 ; 0 indicates persistence
+                           alert-fade-time)))))
+        (when category
+          (nconc args
+                 (list "--category"
+                       (cond ((symbolp category)
+                              (symbol-name category))
+                             ((stringp category) category)
+                             ((listp category)
+                              (mapconcat (if (symbolp (car category))
+                                             #'symbol-name
+                                           #'identity)
+                                         category ","))))))
+        (nconc args (list
+                     (alert-encode-string (plist-get info :title))
+                     (alert-encode-string (plist-get info :message))))
+        (apply #'call-process alert-libnotify-command nil
+               (list (get-buffer-create " *libnotify output*") t) nil args))
+    (alert-message-notify info)))
+
+(alert-define-style 'libnotify :title "Notify using libnotify"
+                    :notifier #'alert-libnotify-notify)
+
+
+(defcustom alert-gntp-icon
+  "http://cvs.savannah.gnu.org/viewvc/*checkout*/emacs/emacs/etc/images/icons/hicolor/48x48/apps/emacs.png"
+  "Icon file using gntp."
+  :type 'string
+  :group 'alert)
+
+(when (featurep 'gntp)
+(defun alert-gntp-notify (info)
+  (gntp-notify 'alert
+               (alert-encode-string (plist-get info :title))
+               (alert-encode-string (plist-get info :message))
+                                    gntp-server nil
+                                    (number-to-string
+                                 (cdr (assq (plist-get info :severity)
+                                            alert-growl-priorities)))
+                                    (if (eq (plist-get info :icon) nil)
+                                        alert-gntp-icon
+                                      (plist-get info :icon)))
+               (alert-message-notify info))
+
+(alert-define-style 'gntp :title "Notify using gntp"
+                    :notifier #'alert-gntp-notify))
+
+
+(defcustom alert-notifications-priorities
+  '((urgent   . critical)
+    (high     . critical)
+    (moderate . normal)
+    (normal   . normal)
+    (low      . low)
+    (trivial  . low))
+  "A mapping of alert severities onto Growl priority values."
+  :type '(alist :key-type symbol :value-type integer)
+  :group 'alert)
+
+(defvar alert-notifications-ids (make-hash-table :test #'equal)
+  "Internal store of notification ids returned by the `notifications' backend.
+Used for replacing notifications with the same id.  The key is
+the value of the :id keyword to `alert'.  An id is only stored
+here if there `alert' was called ith an :id keyword and handled
+by the `notifications' style.")
+
+(when (featurep 'notifications)
+(defun alert-notifications-notify (info)
+  "Show the alert defined by INFO with `notifications-notify'."
+  (let ((id (notifications-notify :title (plist-get info :title)
+                                  :body  (plist-get info :message)
+                                  :app-icon (plist-get info :icon)
+                                  :timeout (if (plist-get info :persistent) 0 -1)
+                                  :replaces-id (gethash (plist-get info :id) alert-notifications-ids)
+                                  :urgency (cdr (assq (plist-get info :severity)
+                                                      alert-notifications-priorities)))))
+    (when (plist-get info :id)
+      (puthash (plist-get info :id) id alert-notifications-ids)))
+  (alert-message-notify info))
+
+(defun alert-notifications-remove (info)
+  "Remove the `notifications-notify' message based on INFO :id."
+  (let ((id (and (plist-get info :id)
+                 (gethash (plist-get info :id) alert-notifications-ids))))
+    (when id
+      (notifications-close-notification id)
+      (remhash (plist-get info :id) alert-notifications-ids))))
+
+(alert-define-style 'notifications :title "Notify using notifications"
+                    :notifier #'alert-notifications-notify))
+
+
+(defcustom alert-notifier-command (executable-find "terminal-notifier")
+  "Path to the terminal-notifier command.
+From https://github.com/julienXX/terminal-notifier."
+  :type 'file
+  :group 'alert)
+
+(defcustom alert-notifier-default-icon
+  (concat data-directory
+          "images/icons/hicolor/128x128/apps/emacs.png")
+  "Filename of default icon to show for terminal-notifier alerts."
+  :type 'string
+  :group 'alert)
+
+(defun alert-notifier-notify (info)
+  (if alert-notifier-command
+      (let ((args
+             (list "-title"   (alert-encode-string (plist-get info :title))
+                   "-appIcon" (or (plist-get info :icon) alert-notifier-default-icon)
+                   "-message" (alert-encode-string (plist-get info :message)))))
+        (apply #'call-process alert-notifier-command nil nil nil args))
+    (alert-message-notify info)))
+
+(alert-define-style 'notifier :title "Notify using terminal-notifier"
+                    :notifier #'alert-notifier-notify)
+
+(defun alert-osx-notifier-notify (info)
+  (apply #'call-process "osascript" nil nil nil "-e" (list (format "display notification %S with title %S"
+                (alert-encode-string (plist-get info :message))
+                (alert-encode-string (plist-get info :title)))))
+  (alert-message-notify info))
+
+(alert-define-style 'osx-notifier :title "Notify using native OSX notification" :notifier #'alert-osx-notifier-notify)
+
+(defun alert-frame-notify (info)
+  (let ((buf (plist-get info :buffer)))
+    (if (eq (alert-buffer-status buf) 'buried)
+        (let ((current-frame (selected-frame)))
+          (with-selected-frame
+              (make-frame '((width                . 80)
+                            (height               . 20)
+                            (top                  . -1)
+                            (left                 . 0)
+                            (left-fringe          . 0)
+                            (right-fringe         . 0)
+                            (tool-bar-lines       . nil)
+                            (menu-bar-lines       . nil)
+                            (vertical-scroll-bars . nil)
+                            (unsplittable         . t)
+                            (has-modeline-p       . nil)
+                            (minibuffer           . nil)))
+            (switch-to-buffer buf)
+            ;;(set (make-local-variable 'mode-line-format) nil)
+            (nconc info (list :frame (selected-frame))))
+          (select-frame current-frame)))))
+
+(defun alert-frame-remove (info)
+  (unless (eq this-command 'handle-switch-frame)
+    (delete-frame (plist-get info :frame) t)))
+
+; This code was kindly borrowed from Arne Babenhauserheide:
+; http://www.draketo.de/proj/babcore/#sec-3-14-2
+(defun x-urgency-hint (frame arg &optional source)
+  "Set the x-urgency hint for the frame to arg:
+
+- If arg is nil, unset the urgency.
+- If arg is any other value, set the urgency.
+
+If you unset the urgency, you still have to visit the frame to make the urgency
+setting disappear (at least in KDE)."
+  (let* ((wm-hints (append (x-window-property
+                            "WM_HINTS" frame "WM_HINTS"
+                            source nil t) nil))
+         (flags (car wm-hints)))
+    (setcar wm-hints
+            (if arg
+                (logior flags #x00000100)
+              (logand flags #x1ffffeff)))
+    (x-change-window-property "WM_HINTS" wm-hints frame "WM_HINTS" 32 t)))
+
+(defun x-urgent (&optional arg)
+  "Mark the current emacs frame as requiring urgent attention.
+
+With a prefix argument which does not equal a boolean value of nil,
+remove the urgency flag (which might or might not change display, depending on
+the window manager)."
+  (interactive "P")
+  (let (frame (car (car (cdr (current-frame-configuration)))))
+  (x-urgency-hint frame (not arg))))
+
+(defun alert-x11-notify (info)
+  (x-urgent))
+
+(alert-define-style 'x11 :title "Set the X11 window property"
+                    :notifier #'alert-x11-notify)
+
+
+(defcustom alert-toaster-default-icon
+  (let ((exec-bin (executable-find "emacs.exe")))
+    (cond (exec-bin
+           (concat (file-name-directory exec-bin) "../share/icons/hicolor/128x128/apps/emacs.png"))
+          (t nil)))
+  "Icon file using toaster."
+  :type 'string
+  :group 'alert
+  )
+
+(defcustom alert-toaster-command (executable-find "toast")
+  "Path to the toast command.
+This is found at https://github.com/nels-o/toaster."
+  :type 'file
+  :group 'alert
+  )
+
+(defun alert-toaster-notify (info)
+  (if alert-toaster-command
+      (let ((args (list
+                    "-t" (alert-encode-string (plist-get info :title))
+                    "-m" (alert-encode-string (plist-get info :message))
+                    "-p" (expand-file-name (or (plist-get info :icon) alert-toaster-default-icon))
+                   )))
+        (apply #'call-process alert-toaster-command nil nil nil args))
+    (alert-message-notify info)))
+
+(alert-define-style 'toaster :title "Notify using Toaster"
+                    :notifier #'alert-toaster-notify)
+
+;; jww (2011-08-25): Not quite working yet
+;;(alert-define-style 'frame :title "Popup buffer in a frame"
+;;                    :notifier #'alert-frame-notify
+;;                    :remover #'alert-frame-remove)
+
+(defun alert-buffer-status (&optional buffer)
+  (with-current-buffer (or buffer (current-buffer))
+    (let ((wind (get-buffer-window)))
+      (if wind
+          (if (eq wind (selected-window))
+              (if (and (current-idle-time)
+                       (> (float-time (current-idle-time))
+                          alert-reveal-idle-time))
+                  'idle
+                'selected)
+            'visible)
+        'buried))))
+
+(defvar alert-active-alerts nil)
+
+(defun alert-remove-when-active (remover info)
+  (let ((idle-time (and (current-idle-time)
+                        (float-time (current-idle-time)))))
+    (cond
+     ((and idle-time (> idle-time alert-persist-idle-time)))
+     ((and idle-time (> idle-time alert-reveal-idle-time))
+      (run-with-timer alert-fade-time nil
+                      #'alert-remove-when-active remover info))
+     (t
+      (funcall remover info)))))
+
+(defun alert-remove-on-command ()
+  (let (to-delete)
+    (dolist (alert alert-active-alerts)
+      (when (eq (current-buffer) (nth 0 alert))
+        (push alert to-delete)
+        (if (nth 2 alert)
+            (funcall (nth 2 alert) (nth 1 alert)))))
+    (dolist (alert to-delete)
+      (setq alert-active-alerts (delq alert alert-active-alerts)))))
+
+(defun alert-send-notification
+    (alert-buffer info style-def &optional persist never-per)
+  (let ((notifier (plist-get style-def :notifier)))
+    (if notifier
+        (funcall notifier info)))
+  (let ((remover (plist-get style-def :remover)))
+    (add-to-list 'alert-active-alerts (list alert-buffer info remover))
+    (with-current-buffer alert-buffer
+      (add-hook 'post-command-hook #'alert-remove-on-command nil t))
+    (if (and remover (or (not persist) never-per))
+        (run-with-timer alert-fade-time nil
+                        #'alert-remove-when-active
+                        remover info))))
+
+;;;###autoload
+(defun* alert (message &key (severity 'normal) title icon category
+                       buffer mode data style persistent never-persist
+                       id)
+  "Alert the user that something has happened.
+MESSAGE is what the user will see.  You may also use keyword
+arguments to specify additional details.  Here is a full example:
+
+\(alert \"This is a message\"
+       :severity \\='high          ;; The default severity is `normal'
+       :title \"Title\"           ;; An optional title
+       :category \\='example       ;; A symbol to identify the message
+       :mode \\='text-mode         ;; Normally determined automatically
+       :buffer (current-buffer) ;; This is the default
+       :data nil                ;; Unused by alert.el itself
+       :persistent nil          ;; Force the alert to be persistent;
+                                ;; it is best not to use this
+       :never-persist nil       ;; Force this alert to never persist
+       :id \\='my-id)              ;; Used to replace previous message of
+                                ;; the same id in styles that support it
+       :style \\='fringe)          ;; Force a given style to be used;
+                                ;; this is only for debugging!
+
+If no :title is given, the buffer-name of :buffer is used.  If
+:buffer is nil, it is the current buffer at the point of call.
+
+:data is an opaque value which modules can pass through to their
+own styles if they wish.
+
+Here are some more typical examples of usage:
+
+  ;; This is the most basic form usage
+  (alert \"This is an alert\")
+
+  ;; You can adjust the severity for more important messages
+  (alert \"This is an alert\" :severity \\='high)
+
+  ;; Or decrease it for purely informative ones
+  (alert \"This is an alert\" :severity \\='trivial)
+
+  ;; Alerts can have optional titles.  Otherwise, the title is the
+  ;; buffer-name of the (current-buffer) where the alert originated.
+  (alert \"This is an alert\" :title \"My Alert\")
+
+  ;; Further, alerts can have categories.  This allows users to
+  ;; selectively filter on them.
+  (alert \"This is an alert\" :title \"My Alert\"
+         :category \\='some-category-or-other)"
+  (destructuring-bind
+      (alert-buffer current-major-mode current-buffer-status
+                    current-buffer-name)
+      (with-current-buffer (or buffer (current-buffer))
+        (list (current-buffer)
+              (or mode major-mode)
+              (alert-buffer-status)
+              (buffer-name)))
+
+    (let ((base-info (list :message message
+                           :title (or title current-buffer-name)
+                           :icon icon
+                           :severity severity
+                           :category category
+                           :buffer alert-buffer
+                           :mode current-major-mode
+                           :id id
+                           :data data))
+          matched)
+
+      (if alert-log-messages
+          (alert-log-notify base-info))
+
+      (unless alert-hide-all-notifications
+        (catch 'finish
+          (dolist (config (append alert-user-configuration
+                                  alert-internal-configuration))
+            (let* ((style-def (cdr (assq (or style (nth 1 config))
+                                         alert-styles)))
+                   (options (nth 2 config))
+                   (persist-p (or persistent
+                                  (cdr (assq :persistent options))))
+                   (persist (if (functionp persist-p)
+                                (funcall persist-p base-info)
+                              persist-p))
+                   (never-persist-p
+                    (or never-persist
+                        (cdr (assq :never-persist options))))
+                   (never-per (if (functionp never-persist-p)
+                                  (funcall never-persist-p base-info)
+                                never-persist-p))
+                   (continue (cdr (assq :continue options)))
+                   info)
+              (setq info (if (not (memq :persistent base-info))
+                             (append base-info (list :persistent persist))
+                           base-info)
+                    info (if (not (memq :never-persist info))
+                             (append info (list :never-persist never-per))
+                           info))
+              (when
+                  (or style           ; :style always "matches", for testing
+                      (not
+                       (memq
+                        nil
+                        (mapcar
+                         #'(lambda (condition)
+                             (case (car condition)
+                               (:severity
+                                (memq severity (cdr condition)))
+                               (:status
+                                (memq current-buffer-status (cdr condition)))
+                               (:mode
+                                (string-match
+                                 (cdr condition)
+                                 (symbol-name current-major-mode)))
+                               (:category
+                                (and category (string-match
+                                               (cdr condition)
+                                               (if (stringp category)
+                                                   category
+                                                 (symbol-name category)))))
+                               (:title
+                                (and title
+                                     (string-match (cdr condition) title)))
+                               (:message
+                                (string-match (cdr condition) message))
+                               (:predicate
+                                (funcall (cdr condition) info))
+                               (:icon
+                                (string-match (cdr condition) icon))))
+                         (nth 0 config)))))
+
+                (alert-send-notification alert-buffer info style-def
+                                         persist never-per)
+                (setq matched t)
+                (if (or style (not (if (functionp continue)
+                                       (funcall continue info)
+                                     continue)))
+                    (throw 'finish t)))))))
+
+      (if (and (not matched) alert-default-style)
+          (alert-send-notification alert-buffer base-info
+                                   (cdr (assq alert-default-style
+                                              alert-styles)))))))
+
+(provide 'alert)
+
+;;; alert.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/alert-20180403.38/alert.elc b/configs/shared/emacs/.emacs.d/elpa/alert-20180403.38/alert.elc
new file mode 100644
index 0000000000..e05c4fc364
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/alert-20180403.38/alert.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/all-the-icons-20180125.757/all-the-icons-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/all-the-icons-20180125.757/all-the-icons-autoloads.el
new file mode 100644
index 0000000000..6d68c721b2
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/all-the-icons-20180125.757/all-the-icons-autoloads.el
@@ -0,0 +1,59 @@
+;;; all-the-icons-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "all-the-icons" "all-the-icons.el" (23377 61284
+;;;;;;  887385 430000))
+;;; Generated autoloads from all-the-icons.el
+
+(autoload 'all-the-icons-icon-for-file "all-the-icons" "\
+Get the formatted icon for FILE.
+ARG-OVERRIDES should be a plist containining `:height',
+`:v-adjust' or `:face' properties like in the normal icon
+inserting functions.
+
+\(fn FILE &rest ARG-OVERRIDES)" nil nil)
+
+(autoload 'all-the-icons-icon-for-mode "all-the-icons" "\
+Get the formatted icon for MODE.
+ARG-OVERRIDES should be a plist containining `:height',
+`:v-adjust' or `:face' properties like in the normal icon
+inserting functions.
+
+\(fn MODE &rest ARG-OVERRIDES)" nil nil)
+
+(autoload 'all-the-icons--icon-info-for-buffer "all-the-icons" "\
+Get icon info for the current buffer.
+
+When F is provided, the info function is calculated with the format
+`all-the-icons-icon-%s-for-file' or `all-the-icons-icon-%s-for-mode'.
+
+\(fn &optional F)" nil nil)
+
+(autoload 'all-the-icons-install-fonts "all-the-icons" "\
+Helper function to download and install the latests fonts based on OS.
+When PFX is non-nil, ignore the prompt and just install
+
+\(fn &optional PFX)" t nil)
+
+(autoload 'all-the-icons-insert "all-the-icons" "\
+Interactive icon insertion function.
+When Prefix ARG is non-nil, insert the propertized icon.
+When FAMILY is non-nil, limit the candidates to the icon set matching it.
+
+\(fn &optional ARG FAMILY)" t nil)
+
+;;;***
+
+;;;### (autoloads nil nil ("all-the-icons-faces.el" "all-the-icons-pkg.el")
+;;;;;;  (23377 61284 888696 545000))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; all-the-icons-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/all-the-icons-20180125.757/all-the-icons-faces.el b/configs/shared/emacs/.emacs.d/elpa/all-the-icons-20180125.757/all-the-icons-faces.el
new file mode 100644
index 0000000000..6e88c84fe8
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/all-the-icons-20180125.757/all-the-icons-faces.el
@@ -0,0 +1,225 @@
+;;; all-the-icons-faces.el --- A module of faces for all-the-icons
+
+;; Copyright (C) 2016  Dominic Charlesworth <dgc336@gmail.com>
+
+;; Author: Dominic Charlesworth <dgc336@gmail.com>
+;; Version: 1.0.0
+;; Package-Requires: ((emacs "24.3"))
+;; URL: https://github.com/domtronn/all-the-icons.el
+;; Keywords: convenient, lisp
+
+;; This program 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.
+
+;; This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This file contains all of the faces used by the package for
+;; colouring icons
+
+;;; Code:
+
+(defgroup all-the-icons-faces nil
+  "Manage how All The Icons icons are coloured and themed."
+  :prefix "all-the-icons-"
+  :group 'tools
+  :group 'all-the-icons)
+
+
+;; red
+(defface all-the-icons-red
+  '((((background dark)) :foreground "#AC4142")
+    (((background light)) :foreground "#AC4142"))
+  "Face for red icons"
+  :group 'all-the-icons-faces)
+(defface all-the-icons-lred
+  '((((background dark)) :foreground "#EB595A")
+    (((background light)) :foreground "#EB595A"))
+  "Face for lred icons"
+  :group 'all-the-icons-faces)
+(defface all-the-icons-dred
+  '((((background dark)) :foreground "#843031")
+    (((background light)) :foreground "#843031"))
+  "Face for dred icons"
+  :group 'all-the-icons-faces)
+(defface all-the-icons-red-alt
+  '((((background dark)) :foreground "#ce5643")
+    (((background light)) :foreground "#843031"))
+  "Face for dred icons"
+  :group 'all-the-icons-faces)
+
+;; green
+(defface all-the-icons-green
+  '((((background dark)) :foreground "#90A959")
+    (((background light)) :foreground "#90A959"))
+  "Face for green icons"
+  :group 'all-the-icons-faces)
+(defface all-the-icons-lgreen
+  '((((background dark)) :foreground "#C6E87A")
+    (((background light)) :foreground "#3D6837"))
+  "Face for lgreen icons"
+  :group 'all-the-icons-faces)
+(defface all-the-icons-dgreen
+  '((((background dark)) :foreground "#6D8143")
+    (((background light)) :foreground "#6D8143"))
+  "Face for dgreen icons"
+  :group 'all-the-icons-faces)
+
+;; yellow
+(defface all-the-icons-yellow
+  '((((background dark)) :foreground "#FFD446")
+    (((background light)) :foreground "#FFCC0E"))
+  "Face for yellow icons"
+  :group 'all-the-icons-faces)
+(defface all-the-icons-lyellow
+  '((((background dark)) :foreground "#FFC16D")
+    (((background light)) :foreground "#FF9300"))
+  "Face for lyellow icons"
+  :group 'all-the-icons-faces)
+(defface all-the-icons-dyellow
+  '((((background dark)) :foreground "#B48D56")
+    (((background light)) :foreground "#B48D56"))
+  "Face for dyellow icons"
+  :group 'all-the-icons-faces)
+
+;; blue
+(defface all-the-icons-blue
+  '((((background dark)) :foreground "#6A9FB5")
+    (((background light)) :foreground "#6A9FB5"))
+  "Face for blue icons"
+  :group 'all-the-icons-faces)
+(defface all-the-icons-blue-alt
+  '((((background dark)) :foreground "#2188b6")
+    (((background light)) :foreground "#2188b6"))
+  "Face for blue icons"
+  :group 'all-the-icons-faces)
+(defface all-the-icons-lblue
+  '((((background dark)) :foreground "#8FD7F4")
+    (((background light)) :foreground "#677174"))
+  "Face for lblue icons"
+  :group 'all-the-icons-faces)
+(defface all-the-icons-dblue
+  '((((background dark)) :foreground "#446674")
+    (((background light)) :foreground "#446674"))
+  "Face for dblue icons"
+  :group 'all-the-icons-faces)
+
+;; maroon
+(defface all-the-icons-maroon
+  '((((background dark)) :foreground "#8F5536")
+    (((background light)) :foreground "#8F5536"))
+  "Face for maroon icons"
+  :group 'all-the-icons-faces)
+(defface all-the-icons-lmaroon
+  '((((background dark)) :foreground "#CE7A4E")
+    (((background light)) :foreground "#CE7A4E"))
+  "Face for lmaroon icons"
+  :group 'all-the-icons-faces)
+(defface all-the-icons-dmaroon
+  '((((background dark)) :foreground "#72584B")
+    (((background light)) :foreground "#72584B"))
+  "Face for dmaroon icons"
+  :group 'all-the-icons-faces)
+
+;; purple
+(defface all-the-icons-purple
+  '((((background dark)) :foreground "#AA759F")
+    (((background light)) :foreground "#68295B"))
+  "Face for purple icons"
+  :group 'all-the-icons-faces)
+(defface all-the-icons-lpurple
+  '((((background dark)) :foreground "#E69DD6")
+    (((background light)) :foreground "#E69DD6"))
+  "Face for lpurple icons"
+  :group 'all-the-icons-faces)
+(defface all-the-icons-dpurple
+  '((((background dark)) :foreground "#694863")
+    (((background light)) :foreground "#694863"))
+  "Face for dpurple icons"
+  :group 'all-the-icons-faces)
+
+;; orange
+(defface all-the-icons-orange
+  '((((background dark)) :foreground "#D4843E")
+    (((background light)) :foreground "#D4843E"))
+  "Face for orange icons"
+  :group 'all-the-icons-faces)
+(defface all-the-icons-lorange
+  '((((background dark)) :foreground "#FFA500")
+    (((background light)) :foreground "#FFA500"))
+  "Face for lorange icons"
+  :group 'all-the-icons-faces)
+(defface all-the-icons-dorange
+  '((((background dark)) :foreground "#915B2D")
+    (((background light)) :foreground "#915B2D"))
+  "Face for dorange icons"
+  :group 'all-the-icons-faces)
+
+;; cyan
+(defface all-the-icons-cyan
+  '((((background dark)) :foreground "#75B5AA")
+    (((background light)) :foreground "#75B5AA"))
+  "Face for cyan icons"
+  :group 'all-the-icons-faces)
+(defface all-the-icons-cyan-alt
+  '((((background dark)) :foreground "#61dafb")
+    (((background light)) :foreground "#0595bd"))
+  "Face for cyan icons"
+  :group 'all-the-icons-faces)
+(defface all-the-icons-lcyan
+  '((((background dark)) :foreground "#A5FDEC")
+    (((background light)) :foreground "#2C7D6E"))
+  "Face for lcyan icons"
+  :group 'all-the-icons-faces)
+(defface all-the-icons-dcyan
+  '((((background dark)) :foreground "#48746D")
+    (((background light)) :foreground "#48746D"))
+  "Face for dcyan icons"
+  :group 'all-the-icons-faces)
+
+;; pink
+(defface all-the-icons-pink
+  '((((background dark)) :foreground "#F2B4B8")
+    (((background light)) :foreground "#FC505B"))
+  "Face for pink icons"
+  :group 'all-the-icons-faces)
+(defface all-the-icons-lpink
+  '((((background dark)) :foreground "#FFBDC1")
+    (((background light)) :foreground "#FF505B"))
+  "Face for lpink icons"
+  :group 'all-the-icons-faces)
+(defface all-the-icons-dpink
+  '((((background dark)) :foreground "#B18286")
+    (((background light)) :foreground "#7E5D5F"))
+  "Face for dpink icons"
+  :group 'all-the-icons-faces)
+
+;; silver
+(defface all-the-icons-silver
+  '((((background dark)) :foreground "#716E68")
+    (((background light)) :foreground "#716E68"))
+  "Face for silver icons"
+  :group 'all-the-icons-faces)
+(defface all-the-icons-lsilver
+  '((((background dark)) :foreground "#B9B6AA")
+    (((background light)) :foreground "#7F7869"))
+  "Face for lsilver icons"
+  :group 'all-the-icons-faces)
+(defface all-the-icons-dsilver
+  '((((background dark)) :foreground "#838484")
+    (((background light)) :foreground "#838484"))
+  "Face for dsilver icons"
+  :group 'all-the-icons-faces)
+
+
+(provide 'all-the-icons-faces)
+;;; all-the-icons-faces.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/all-the-icons-20180125.757/all-the-icons-faces.elc b/configs/shared/emacs/.emacs.d/elpa/all-the-icons-20180125.757/all-the-icons-faces.elc
new file mode 100644
index 0000000000..a22b73618b
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/all-the-icons-20180125.757/all-the-icons-faces.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/all-the-icons-20180125.757/all-the-icons-pkg.el b/configs/shared/emacs/.emacs.d/elpa/all-the-icons-20180125.757/all-the-icons-pkg.el
new file mode 100644
index 0000000000..47e38023ba
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/all-the-icons-20180125.757/all-the-icons-pkg.el
@@ -0,0 +1,9 @@
+(define-package "all-the-icons" "20180125.757" "A library for inserting Developer icons"
+  '((emacs "24.3")
+    (memoize "1.0.1"))
+  :keywords
+  '("convenient" "lisp")
+  :url "https://github.com/domtronn/all-the-icons.el")
+;; Local Variables:
+;; no-byte-compile: t
+;; End:
diff --git a/configs/shared/emacs/.emacs.d/elpa/all-the-icons-20180125.757/all-the-icons.el b/configs/shared/emacs/.emacs.d/elpa/all-the-icons-20180125.757/all-the-icons.el
new file mode 100644
index 0000000000..049fed492a
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/all-the-icons-20180125.757/all-the-icons.el
@@ -0,0 +1,832 @@
+;;; all-the-icons.el --- A library for inserting Developer icons
+
+;; Copyright (C) 2016  Dominic Charlesworth <dgc336@gmail.com>
+
+;; Author: Dominic Charlesworth <dgc336@gmail.com>
+;; Version: 3.1.4
+;; Package-Requires: ((emacs "24.3") (memoize "1.0.1"))
+;; URL: https://github.com/domtronn/all-the-icons.el
+;; Keywords: convenient, lisp
+
+;; This program 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.
+
+;; This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This package is a utility for using and formatting various Icon
+;; fonts within Emacs.  Icon Fonts allow you to propertize and format
+;; icons the same way you would normal text.  This enables things such
+;; as better scaling of and anti aliasing of the icons.
+
+;; This package was inspired by
+
+;; - `mode-icons' for Emacs, found at https://github.com/ryuslash/mode-icons
+;; - `file-icons' for Atom, found at https://atom.io/packages/file-icons
+
+;; Currently, this package provides an interface to the following Icon Fonts
+
+;; - Atom File Icons,       found at https://atom.io/packages/file-icons
+;; - FontAwesome Icons,     found at http://fontawesome.io/
+;; - GitHub Octicons,       found at http://octicons.github.com
+;; - Material Design Icons, found at http://google.github.io/material-design-icons/
+;; - Weather Icons,         found at https://erikflowers.github.io/weather-icons/
+;; - AllTheIcons,           a custom Icon Font maintained as part of this package
+
+;; Requests for new icons will be accepted and added to the AllTheIcons Icon Font
+
+;;; Usage:
+
+;; The simplest usage for this package is to use the following functions;
+
+;;   `all-the-icons-icon-for-buffer'
+;;   `all-the-icons-icon-for-file'
+;;   `all-the-icons-icon-for-mode'
+
+;; Which can be used to get a formatted icon for the current buffer, a
+;; file name or a major mode respectively.  e.g.
+
+;;   (insert (all-the-icons-icon-for-file "foo.js"))
+
+;; Inserts a JavaScript icon formatted like this
+
+;;   #("some-icon" 0 1 (display (raise -0.24)
+;;              face (:family "dev-icons" :height 1.08 :foreground "#FFD446")))
+
+;; You can also insert icons directly using the individual icon family
+;; functions
+
+;;   `all-the-icons-alltheicon'     // Custom font with fewest icons
+;;   `all-the-icons-devicon'        // Developer Icons
+;;   `all-the-icons-faicon'         // Font Awesome Icons
+;;   `all-the-icons-fileicon'       // File Icons from the Atom File Icons package
+;;   `all-the-icons-octicon'        // GitHub Octicons
+;;   `all-the-icons-material'       // Material Design Icons
+;;   `all-the-icons-wicon'          // Weather Icons
+
+;; You can call these functions with the icon name you want to insert, e.g.
+
+;;   (all-the-icons-octicon "file-binary")  // GitHub Octicon for Binary File
+;;   (all-the-icons-faicon  "cogs")         // FontAwesome icon for cogs
+;;   (all-the-icons-wicon   "tornado")      // Weather Icon for tornado
+
+;; A list of all the icon names for the different font families can be
+;; found in the data directory, or by inspecting the alist variables.
+;; All the alist variables are prefixed with `all-the-icons-data/'
+
+;;; Code:
+(require 'memoize)
+(require 'cl-lib)
+
+(require 'data-alltheicons  "./data/data-alltheicons.el")
+(require 'data-faicons      "./data/data-faicons.el")
+(require 'data-fileicons    "./data/data-fileicons.el")
+(require 'data-octicons     "./data/data-octicons.el")
+(require 'data-weathericons "./data/data-weathericons.el")
+(require 'data-material     "./data/data-material.el")
+
+(require 'all-the-icons-faces)
+
+;;; Custom Variables
+(defgroup all-the-icons nil
+  "Manage how All The Icons formats icons."
+  :prefix "all-the-icons-"
+  :group 'appearance
+  :group 'convenience)
+
+(defcustom all-the-icons-color-icons t
+  "Whether or not to include a foreground colour when formatting the icon."
+  :group 'all-the-icons
+  :type 'boolean)
+
+(defcustom all-the-icons-scale-factor 1.2
+  "The base Scale Factor for the `height' face property of an icon."
+  :group 'all-the-icons
+  :type 'number)
+
+(defcustom all-the-icons-default-adjust -0.2
+  "The default adjustment to be made to the `raise' display property of an icon."
+  :group 'all-the-icons
+  :type 'number)
+
+(defvar all-the-icons-font-families '() "List of defined icon font families.")
+(defvar all-the-icons-font-names '() "List of defined font file names this package was built with.")
+
+(defvar all-the-icons-icon-alist
+  '(
+    ;; Meta
+    ("\\.tags"          all-the-icons-octicon "tag"                     :height 1.0 :v-adjust 0.0 :face all-the-icons-blue)
+    ("^TAGS$"           all-the-icons-octicon "tag"                     :height 1.0 :v-adjust 0.0 :face all-the-icons-blue)
+    ("\\.log"           all-the-icons-octicon "bug"                     :height 1.0 :v-adjust 0.0 :face all-the-icons-maroon)
+
+    ;;
+    ("\\.key$"          all-the-icons-octicon "key"                     :v-adjust 0.0 :face all-the-icons-lblue)
+    ("\\.pem$"          all-the-icons-octicon "key"                     :v-adjust 0.0 :face all-the-icons-orange)
+    ("\\.p12$"          all-the-icons-octicon "key"                     :v-adjust 0.0 :face all-the-icons-dorange)
+    ("\\.crt$"          all-the-icons-octicon "key"                     :v-adjust 0.0 :face all-the-icons-lblue)
+    ("\\.pub$"          all-the-icons-octicon "key"                     :v-adjust 0.0 :face all-the-icons-blue)
+    ("\\.gpg$"          all-the-icons-octicon "key"                     :v-adjust 0.0 :face all-the-icons-lblue)
+
+    ("^TODO$"           all-the-icons-octicon "checklist"               :v-adjust 0.0 :face all-the-icons-lyellow)
+    ("^LICENSE$"        all-the-icons-octicon "book"                    :height 1.0 :v-adjust 0.0 :face all-the-icons-blue)
+    ("^readme"          all-the-icons-octicon "book"                    :height 1.0 :v-adjust 0.0 :face all-the-icons-lcyan)
+
+    ("\\.fish"          all-the-icons-alltheicon "terminal"             :face all-the-icons-lpink)
+    ("\\.zsh"           all-the-icons-alltheicon "terminal"             :face all-the-icons-lcyan)
+    ("\\.sh"            all-the-icons-alltheicon "terminal"             :face all-the-icons-purple)
+
+    ;; Config
+    ("\\.node"          all-the-icons-alltheicon "nodejs"               :height 1.0  :face all-the-icons-green)
+    ("\\.babelrc$"      all-the-icons-fileicon "babel"                  :face all-the-icons-yellow)
+    ("\\.bashrc$"       all-the-icons-alltheicon "script"               :height 0.9  :face all-the-icons-dpink)
+    ("\\.bowerrc$"      all-the-icons-alltheicon "bower"                :height 1.0 :v-adjust 0.0 :face all-the-icons-silver)
+    ("^bower.json$"     all-the-icons-alltheicon "bower"                :height 1.0 :v-adjust 0.0 :face all-the-icons-lorange)
+    ("\\.ini$"          all-the-icons-octicon "settings"                :v-adjust 0.0 :face all-the-icons-yellow)
+    ("\\.eslintignore"  all-the-icons-fileicon "eslint"                 :height 0.9  :face all-the-icons-purple)
+    ("\\.eslint"        all-the-icons-fileicon "eslint"                 :height 0.9  :face all-the-icons-lpurple)
+    ("\\.git"           all-the-icons-alltheicon "git"                  :height 1.0  :face all-the-icons-lred)
+    ("nginx"            all-the-icons-fileicon "nginx"                  :height 0.9  :face all-the-icons-dgreen)
+    ("apache"           all-the-icons-alltheicon "apache"               :height 0.9  :face all-the-icons-dgreen)
+    ("^Makefile$"       all-the-icons-fileicon "gnu"                    :face all-the-icons-dorange)
+    ("\\.mk$"           all-the-icons-fileicon "gnu"                    :face all-the-icons-dorange)
+
+    ("\\.dockerignore$" all-the-icons-fileicon "dockerfile"             :height 1.2  :face all-the-icons-dblue)
+    ("^\\.?Dockerfile"  all-the-icons-fileicon "dockerfile"             :face all-the-icons-blue)
+    ("^Brewfile$"       all-the-icons-faicon "beer"                     :face all-the-icons-lsilver)
+    ("\\.npmignore"     all-the-icons-fileicon "npm"                    :face all-the-icons-dred)
+    ("^package.json$"   all-the-icons-fileicon "npm"                    :face all-the-icons-red)
+    ("^package.lock.json$" all-the-icons-fileicon "npm"                 :face all-the-icons-dred)
+    ("^yarn\.lock"      all-the-icons-fileicon "yarn"                   :face all-the-icons-blue-alt)
+
+    ("\.xml$"           all-the-icons-faicon "file-code-o"              :height 0.95 :face all-the-icons-lorange)
+
+    ;; ;; AWS
+    ("^stack.*.json$"   all-the-icons-alltheicon "aws"                  :face all-the-icons-orange)
+
+    
+    ("^serverless\\.yml$" all-the-icons-faicon "bolt"                   :v-adjust 0.0 :face all-the-icons-yellow)
+    ("\\.[jc]son$"      all-the-icons-octicon "settings"                :v-adjust 0.0 :face all-the-icons-yellow)
+    ("\\.ya?ml$"        all-the-icons-octicon "settings"                :v-adjust 0.0 :face all-the-icons-dyellow)
+
+    ("\\.pkg$"          all-the-icons-octicon "package"                 :v-adjust 0.0 :face all-the-icons-dsilver)
+    ("\\.rpm$"          all-the-icons-octicon "package"                 :v-adjust 0.0 :face all-the-icons-dsilver)
+
+    ("\\.elc$"          all-the-icons-octicon "file-binary"             :v-adjust 0.0 :face all-the-icons-dsilver)
+
+    ("\\.gz$"           all-the-icons-octicon "file-binary"             :v-adjust 0.0 :face all-the-icons-lmaroon)
+    ("\\.zip$"          all-the-icons-octicon "file-zip"                :v-adjust 0.0 :face all-the-icons-lmaroon)
+    ("\\.7z$"           all-the-icons-octicon "file-zip"                :v-adjust 0.0 :face all-the-icons-lmaroon)
+
+    ("\\.dat$"          all-the-icons-faicon "bar-chart"                :face all-the-icons-cyan :height 0.9)
+    ;; lock files
+    ("~$"               all-the-icons-octicon "lock"                    :v-adjust 0.0 :face all-the-icons-maroon)
+
+    ("\\.dmg$"          all-the-icons-octicon "tools"                   :v-adjust 0.0 :face all-the-icons-lsilver)
+    ("\\.dll$"          all-the-icons-faicon "cogs"                     :face all-the-icons-silver)
+    ("\\.DS_STORE$"     all-the-icons-faicon "cogs"                     :face all-the-icons-silver)
+
+    ;; Source Codes
+    ("\\.scpt$"         all-the-icons-fileicon "apple"                  :face all-the-icons-pink)
+    ("\\.aup$"          all-the-icons-fileicon "audacity"               :face all-the-icons-yellow)
+
+    ("\\.elm"           all-the-icons-fileicon "elm"                    :face all-the-icons-blue)
+
+    ("\\.erl$"          all-the-icons-alltheicon "erlang"               :face all-the-icons-red :v-adjust -0.1 :height 0.9)
+    ("\\.hrl$"          all-the-icons-alltheicon "erlang"               :face all-the-icons-dred :v-adjust -0.1 :height 0.9)
+
+    ("\\.eex$"          all-the-icons-alltheicon "elixir"               :face all-the-icons-lorange :v-adjust -0.1 :height 0.9)
+    ("\\.ex$"           all-the-icons-alltheicon "elixir"               :face all-the-icons-lpurple :v-adjust -0.1 :height 0.9)
+    ("\\.exs$"          all-the-icons-alltheicon "elixir"               :face all-the-icons-lred :v-adjust -0.1 :height 0.9)
+    ("^mix.lock$"       all-the-icons-alltheicon "elixir"               :face all-the-icons-lyellow :v-adjust -0.1 :height 0.9)
+
+    ("\\.java$"         all-the-icons-alltheicon "java"                 :height 1.0  :face all-the-icons-purple)
+
+    ("\\.go$"           all-the-icons-alltheicon "go"                   :height 1.0  :face all-the-icons-blue)
+
+    ("\\.mp3$"          all-the-icons-faicon "volume-up"                :face all-the-icons-dred)
+    ("\\.wav$"          all-the-icons-faicon "volume-up"                :face all-the-icons-dred)
+    ("\\.m4a$"          all-the-icons-faicon "volume-up"                :face all-the-icons-dred)
+
+    ("\\.jl$"           all-the-icons-fileicon "julia"                  :v-adjust 0.0 :face all-the-icons-purple)
+    ("\\.matlab$"       all-the-icons-fileicon "matlab"                 :face all-the-icons-orange)
+
+    ("\\.p[ml]$"        all-the-icons-alltheicon "perl"                 :face all-the-icons-lorange)
+    ("\\.pl6$"          all-the-icons-fileicon "perl6"                  :face all-the-icons-cyan)
+    ("\\.pod$"          all-the-icons-alltheicon "perldocs"             :height 1.2  :face all-the-icons-lgreen)
+
+    ("\\.php$"          all-the-icons-fileicon "php"                    :face all-the-icons-lsilver)
+    ("\\.pony$"         all-the-icons-fileicon "pony"                   :face all-the-icons-maroon)
+    ("\\.prol?o?g?$"    all-the-icons-alltheicon "prolog"               :height 1.1  :face all-the-icons-lmaroon)
+    ("\\.py$"           all-the-icons-alltheicon "python"               :height 1.0  :face all-the-icons-dblue)
+
+    ("\\.rkt$"          all-the-icons-fileicon "racket"                 :height 1.2 :face all-the-icons-red)
+    ("\\.gem$"          all-the-icons-alltheicon "ruby-alt"             :face all-the-icons-red)
+    ("_?test\\.rb$"        all-the-icons-fileicon "test-ruby"            :height 1.0 :v-adjust 0.0 :face all-the-icons-red)
+    ("_?test_helper\\.rb$" all-the-icons-fileicon "test-ruby"            :height 1.0 :v-adjust 0.0 :face all-the-icons-dred)
+    ("\\.rb$"           all-the-icons-octicon "ruby"                    :v-adjust 0.0 :face all-the-icons-lred)
+    ("\\.rs$"           all-the-icons-alltheicon "rust"                 :height 1.2  :face all-the-icons-maroon)
+    ("\\.rlib$"         all-the-icons-alltheicon "rust"                 :height 1.2  :face all-the-icons-dmaroon)
+    ("\\.r[ds]?x?$"     all-the-icons-fileicon "R"                      :face all-the-icons-lblue)
+
+    ("\\.scala$"        all-the-icons-alltheicon "scala"                :face all-the-icons-red)
+    ("\\.scm$"          all-the-icons-fileicon   "scheme"               :height 1.2 :face all-the-icons-red)
+    ("\\.swift$"        all-the-icons-alltheicon "swift"                :height 1.0 :v-adjust -0.1 :face all-the-icons-green)
+
+    ("-?spec\\.ts$"     all-the-icons-fileicon "test-typescript"        :height 1.0 :v-adjust 0.0 :face all-the-icons-blue)
+    ("-?test\\.ts$"     all-the-icons-fileicon "test-typescript"        :height 1.0 :v-adjust 0.0 :face all-the-icons-blue)
+    ("-?spec\\.js$"     all-the-icons-fileicon "test-js"                :height 1.0 :v-adjust 0.0 :face all-the-icons-lpurple)
+    ("-?test\\.js$"     all-the-icons-fileicon "test-js"                :height 1.0 :v-adjust 0.0 :face all-the-icons-lpurple)
+    ("-?spec\\.jsx$"    all-the-icons-fileicon "test-react"             :height 1.0 :v-adjust 0.0 :face all-the-icons-blue-alt)
+    ("-?test\\.jsx$"    all-the-icons-fileicon "test-react"             :height 1.0 :v-adjust 0.0 :face all-the-icons-blue-alt)
+
+    ("-?spec\\."        all-the-icons-fileicon "test-generic"           :height 1.0 :v-adjust 0.0 :face all-the-icons-dgreen)
+    ("-?test\\."        all-the-icons-fileicon "test-generic"           :height 1.0 :v-adjust 0.0 :face all-the-icons-dgreen)
+
+    ;; There seems to be a a bug with this font icon which does not
+    ;; let you propertise it without it reverting to being a lower
+    ;; case phi
+    ("\\.c$"            all-the-icons-alltheicon "c-line"               :face all-the-icons-blue)
+    ("\\.h$"            all-the-icons-alltheicon "c-line"               :face all-the-icons-purple)
+    ("\\.m$"            all-the-icons-fileicon "apple"                  :v-adjust 0.0 :height 1.0)
+    ("\\.mm$"           all-the-icons-fileicon "apple"                  :v-adjust 0.0 :height 1.0)
+
+    ("\\.c\\(c\\|pp\\|xx\\)$"   all-the-icons-alltheicon "cplusplus-line"       :v-adjust -0.2 :face all-the-icons-blue)
+    ("\\.h\\(h\\|pp\\|xx\\)$"   all-the-icons-alltheicon "cplusplus-line"       :v-adjust -0.2 :face all-the-icons-purple)
+
+    ("\\.csx?$"         all-the-icons-alltheicon "csharp-line"          :face all-the-icons-dblue)
+
+    ("\\.cljc?$"        all-the-icons-alltheicon "clojure-line"         :height 1.0 :face all-the-icons-blue :v-adjust 0.0)
+    ("\\.cljs$"         all-the-icons-fileicon "cljs"                   :height 1.0 :face all-the-icons-dblue :v-adjust 0.0)
+
+    ("\\.coffee$"       all-the-icons-alltheicon "coffeescript"         :height 1.0  :face all-the-icons-maroon)
+    ("\\.iced$"         all-the-icons-alltheicon "coffeescript"         :height 1.0  :face all-the-icons-lmaroon)
+
+    ;; Git
+    ("^MERGE_"          all-the-icons-octicon "git-merge"               :v-adjust 0.0 :face all-the-icons-red)
+    ("^COMMIT_EDITMSG"  all-the-icons-octicon "git-commit"              :v-adjust 0.0 :face all-the-icons-red)
+
+    ;; Lisps
+    ("\\.cl$"           all-the-icons-fileicon "clisp"                  :face all-the-icons-lorange)
+    ("\\.l\\(isp\\)?$"  all-the-icons-fileicon "lisp"                   :face all-the-icons-orange)
+    ("\\.el$"           all-the-icons-fileicon "elisp"                  :height 1.0 :v-adjust -0.2 :face all-the-icons-purple)
+
+    ;; Stylesheeting
+    ("\\.css$"          all-the-icons-alltheicon "css3"                 :face all-the-icons-yellow)
+    ("\\.scss$"         all-the-icons-alltheicon "sass"                 :face all-the-icons-pink)
+    ("\\.sass$"         all-the-icons-alltheicon "sass"                 :face all-the-icons-dpink)
+    ("\\.less$"         all-the-icons-alltheicon "less"                 :height 0.8  :face all-the-icons-dyellow)
+    ("\\.postcss$"      all-the-icons-fileicon "postcss"                :face all-the-icons-dred)
+    ("\\.sss$"          all-the-icons-fileicon "postcss"                :face all-the-icons-dred)
+    ("\\.styl$"         all-the-icons-alltheicon "stylus"               :face all-the-icons-lgreen)
+    ("stylelint"        all-the-icons-fileicon "stylelint"              :face all-the-icons-lyellow)
+    ("\\.csv$"          all-the-icons-octicon "graph"                   :v-adjust 0.0 :face all-the-icons-dblue)
+
+    ("\\.hs$"           all-the-icons-alltheicon "haskell"              :height 1.0  :face all-the-icons-red)
+
+    ;; Web modes
+    ("\\.inky-haml$"    all-the-icons-fileicon "haml"                   :face all-the-icons-lyellow)
+    ("\\.haml$"         all-the-icons-fileicon "haml"                   :face all-the-icons-lyellow)
+    ("\\.html?$"        all-the-icons-alltheicon "html5"                :face all-the-icons-orange)
+    ("\\.inky-erb?$"    all-the-icons-alltheicon "html5"                :face all-the-icons-lred)
+    ("\\.erb$"          all-the-icons-alltheicon "html5"                :face all-the-icons-lred)
+    ("\\.hbs$"          all-the-icons-fileicon "moustache"              :face all-the-icons-green)
+    ("\\.inky-slim$"    all-the-icons-octicon "dashboard"               :v-adjust 0.0 :face all-the-icons-yellow)
+    ("\\.slim$"         all-the-icons-octicon "dashboard"               :v-adjust 0.0 :face all-the-icons-yellow)
+    ("\\.jade$"         all-the-icons-fileicon "jade"                   :face all-the-icons-red)
+    ("\\.pug$"          all-the-icons-fileicon "pug-alt"                :face all-the-icons-red)
+
+    ;; JavaScript
+    ("^gulpfile"        all-the-icons-alltheicon "gulp"                 :height 1.0  :face all-the-icons-lred)
+    ("^gruntfile"       all-the-icons-alltheicon "grunt"                :height 1.0 :v-adjust -0.1 :face all-the-icons-lyellow)
+    ("^webpack"         all-the-icons-fileicon "webpack"                :face all-the-icons-lblue)
+
+    ("\\.d3\\.?js"      all-the-icons-alltheicon "d3"                   :height 0.8  :face all-the-icons-lgreen)
+
+    ("\\.re$"            all-the-icons-fileicon "reason"                :height 1.0  :face all-the-icons-red-alt)
+    ("\\.rei$"           all-the-icons-fileicon "reason"                :height 1.0  :face all-the-icons-dred)
+    ("\\.ml$"            all-the-icons-fileicon "ocaml"                 :height 1.0  :face all-the-icons-lpink)
+    ("\\.mli$"           all-the-icons-fileicon "ocaml"                 :height 1.0  :face all-the-icons-dpink)
+
+    ("\\.react"         all-the-icons-alltheicon "react"                :height 1.1  :face all-the-icons-lblue)
+    ("\\.d\\.ts$"       all-the-icons-fileicon "typescript"             :height 1.0 :v-adjust -0.1 :face all-the-icons-cyan-alt)
+    ("\\.ts$"           all-the-icons-fileicon "typescript"             :height 1.0 :v-adjust -0.1 :face all-the-icons-blue-alt)
+    ("\\.js$"           all-the-icons-alltheicon "javascript"           :height 1.0 :v-adjust 0.0 :face all-the-icons-yellow)
+    ("\\.es[0-9]$"      all-the-icons-alltheicon "javascript"           :height 1.0 :v-adjust 0.0 :face all-the-icons-yellow)
+    ("\\.jsx$"          all-the-icons-fileicon "jsx-2"                  :height 1.0 :v-adjust -0.1 :face all-the-icons-cyan-alt)
+    ("\\.njs$"          all-the-icons-alltheicon "nodejs"               :height 1.2  :face all-the-icons-lgreen)
+    ("\\.vue$"          all-the-icons-fileicon "vue"                    :face all-the-icons-lgreen)
+
+    ;; File Types
+    ("\\.ico$"          all-the-icons-octicon "file-media"              :v-adjust 0.0 :face all-the-icons-blue)
+    ("\\.png$"          all-the-icons-octicon "file-media"              :v-adjust 0.0 :face all-the-icons-orange)
+    ("\\.gif$"          all-the-icons-octicon "file-media"              :v-adjust 0.0 :face all-the-icons-green)
+    ("\\.jpe?g$"        all-the-icons-octicon "file-media"              :v-adjust 0.0 :face all-the-icons-dblue)
+    ("\\.svg$"          all-the-icons-alltheicon "svg"                  :height 0.9  :face all-the-icons-lgreen)
+
+    ;; Video
+    ("\\.mov"           all-the-icons-faicon "film"                     :face all-the-icons-blue)
+    ("\\.mp4"           all-the-icons-faicon "film"                     :face all-the-icons-blue)
+    ("\\.ogv"           all-the-icons-faicon "film"                     :face all-the-icons-dblue)
+
+    ;; Fonts
+    ("\\.ttf$"          all-the-icons-fileicon "font"                   :v-adjust 0.0 :face all-the-icons-dcyan)
+    ("\\.woff2?$"       all-the-icons-fileicon "font"                   :v-adjust 0.0 :face all-the-icons-cyan)
+
+    ;; Doc
+    ("\\.pdf"           all-the-icons-octicon "file-pdf"                :v-adjust 0.0 :face all-the-icons-dred)
+    ("\\.te?xt"         all-the-icons-octicon "file-text"               :v-adjust 0.0 :face all-the-icons-cyan)
+    ("\\.doc[xm]?$"     all-the-icons-fileicon "word"                   :face all-the-icons-blue)
+    ("\\.texi?$"        all-the-icons-fileicon "tex"                    :face all-the-icons-lred)
+    ("\\.md$"           all-the-icons-octicon "markdown"                :v-adjust 0.0 :face all-the-icons-lblue)
+    ("\\.bib$"          all-the-icons-fileicon "bib"                    :face all-the-icons-maroon)
+    ("\\.org$"          all-the-icons-fileicon "org"                    :face all-the-icons-lgreen)
+
+    ("\\.pp[st]$"       all-the-icons-fileicon "powerpoint"             :face all-the-icons-orange)
+    ("\\.pp[st]x$"      all-the-icons-fileicon "powerpoint"             :face all-the-icons-red)
+    ("\\.knt$"          all-the-icons-fileicon "powerpoint"             :face all-the-icons-cyan)
+
+    ("bookmark"         all-the-icons-octicon "bookmark"                :height 1.1 :v-adjust 0.0 :face all-the-icons-lpink)
+    ("\\.cache$"        all-the-icons-octicon "database"                :height 1.0 :v-adjust 0.0 :face all-the-icons-green)
+
+    ("^\\*scratch\\*$"  all-the-icons-faicon "sticky-note"              :face all-the-icons-lyellow)
+    ("^\\*scratch.*"    all-the-icons-faicon "sticky-note"              :face all-the-icons-yellow)
+    ("^\\*new-tab\\*$"  all-the-icons-material "star"                     :face all-the-icons-cyan)
+
+    ("^\\."             all-the-icons-octicon "gear"                    :v-adjust 0.0)
+    ("."                all-the-icons-faicon "file-o"                   :height 0.8 :v-adjust 0.0 :face all-the-icons-dsilver)))
+
+(defvar all-the-icons-dir-icon-alist
+  '(
+    ("trash"            all-the-icons-faicon "trash-o"          :height 1.2 :v-adjust -0.1)
+    ("dropbox"          all-the-icons-faicon "dropbox"          :height 1.0 :v-adjust -0.1)
+    ("google[ _-]drive" all-the-icons-alltheicon "google-drive" :height 1.3 :v-adjust -0.1)
+    ("^atom$"           all-the-icons-alltheicon "atom"         :height 1.2 :v-adjust -0.1)
+    ("documents"        all-the-icons-faicon "book"             :height 1.0 :v-adjust -0.1)
+    ("download"         all-the-icons-faicon "cloud-download"   :height 0.9 :v-adjust -0.2)
+    ("desktop"          all-the-icons-octicon "device-desktop"  :height 1.0 :v-adjust -0.1)
+    ("pictures"         all-the-icons-faicon "picture-o"        :height 0.9 :v-adjust -0.2)
+    ("photos"           all-the-icons-faicon "camera-retro"     :height 1.0 :v-adjust -0.1)
+    ("music"            all-the-icons-faicon "music"            :height 1.0 :v-adjust -0.1)
+    ("movies"           all-the-icons-faicon "film"             :height 0.9 :v-adjust -0.1)
+    ("code"             all-the-icons-octicon "code"            :height 1.1 :v-adjust -0.1)
+    ("workspace"        all-the-icons-octicon "code"            :height 1.1 :v-adjust -0.1)
+    ("test"             all-the-icons-fileicon "test-dir"       :height 0.9)
+    ("\\.git"           all-the-icons-alltheicon "git"          :height 1.0)
+    ("."                all-the-icons-octicon "file-directory"  :height 1.0 :v-adjust -0.1)
+    ))
+
+(defvar all-the-icons-weather-icon-alist
+  '(
+    ("tornado"               all-the-icons-wicon "tornado")
+    ("hurricane"             all-the-icons-wicon "hurricane")
+    ("thunderstorms"         all-the-icons-wicon "thunderstorm")
+    ("sunny"                 all-the-icons-wicon "day-sunny")
+    ("rain.*snow"            all-the-icons-wicon "rain-mix")
+    ("rain.*hail"            all-the-icons-wicon "rain-mix")
+    ("sleet"                 all-the-icons-wicon "sleet")
+    ("hail"                  all-the-icons-wicon "hail")
+    ("drizzle"               all-the-icons-wicon "sprinkle")
+    ("rain"                  all-the-icons-wicon "showers" :height 1.1 :v-adjust 0.0)
+    ("showers"               all-the-icons-wicon "showers")
+    ("blowing.*snow"         all-the-icons-wicon "snow-wind")
+    ("snow"                  all-the-icons-wicon "snow")
+    ("dust"                  all-the-icons-wicon "dust")
+    ("fog"                   all-the-icons-wicon "fog")
+    ("haze"                  all-the-icons-wicon "day-haze")
+    ("smoky"                 all-the-icons-wicon "smoke")
+    ("blustery"              all-the-icons-wicon "cloudy-windy")
+    ("windy"                 all-the-icons-wicon "cloudy-gusts")
+    ("cold"                  all-the-icons-wicon "snowflake-cold")
+    ("partly.*cloudy.*night" all-the-icons-wicon "night-alt-partly-cloudy")
+    ("partly.*cloudy"        all-the-icons-wicon "day-cloudy-high")
+    ("cloudy.*night"         all-the-icons-wicon "night-alt-cloudy")
+    ("cxloudy.*day"          all-the-icons-wicon "day-cloudy")
+    ("cloudy"                all-the-icons-wicon "cloudy")
+    ("clear.*night"          all-the-icons-wicon "night-clear")
+    ("fair.*night"           all-the-icons-wicon "stars")
+    ("fair.*day"             all-the-icons-wicon "horizon")
+    ("hot"                   all-the-icons-wicon "hot")
+    ("not.*available"        all-the-icons-wicon "na")
+    ))
+
+(defvar all-the-icons-mode-icon-alist
+  '(
+    (emacs-lisp-mode           all-the-icons-fileicon "elisp"              :height 1.0 :v-adjust -0.2 :face all-the-icons-purple)
+    (inferior-emacs-lisp-mode  all-the-icons-fileicon "elisp"              :height 1.0 :v-adjust -0.2 :face all-the-icons-lblue)
+    (dired-mode                all-the-icons-octicon "file-directory"      :v-adjust 0.0)
+    (lisp-interaction-mode     all-the-icons-fileicon "lisp"               :v-adjust -0.1 :face all-the-icons-orange)
+    (org-mode                  all-the-icons-fileicon "org"                :v-adjust 0.0 :face all-the-icons-lgreen)
+    (typescript-mode           all-the-icons-fileicon "typescript"         :v-adjust -0.1 :face all-the-icons-blue-alt)
+    (js-mode                   all-the-icons-alltheicon "javascript"       :v-adjust -0.1 :face all-the-icons-yellow)
+    (js-jsx-mode               all-the-icons-alltheicon "javascript"       :v-adjust -0.1 :face all-the-icons-yellow)
+    (js2-mode                  all-the-icons-alltheicon "javascript"       :v-adjust -0.1 :face all-the-icons-yellow)
+    (js3-mode                  all-the-icons-alltheicon "javascript"       :v-adjust -0.1 :face all-the-icons-yellow)
+    (rjsx-mode                 all-the-icons-fileicon "jsx-2"              :v-adjust -0.1 :face all-the-icons-cyan-alt)
+    (term-mode                 all-the-icons-octicon "terminal"            :v-adjust 0.2)
+    (eshell-mode               all-the-icons-octicon "terminal"            :v-adjust 0.0 :face all-the-icons-purple)
+    (magit-refs-mode           all-the-icons-octicon "git-branch"          :v-adjust 0.0 :face all-the-icons-red)
+    (magit-process-mode        all-the-icons-octicon "mark-github"         :v-adjust 0.0)
+    (magit-diff-mode           all-the-icons-octicon "git-compare"         :v-adjust 0.0 :face all-the-icons-lblue)
+    (ediff-mode                all-the-icons-octicon "git-compare"         :v-adjust 0.0 :Face all-the-icons-red)
+    (comint-mode               all-the-icons-faicon "terminal"             :v-adjust 0.0 :face all-the-icons-lblue)
+    (eww-mode                  all-the-icons-faicon "firefox"              :v-adjust -0.1 :face all-the-icons-red)
+    (org-agenda-mode           all-the-icons-octicon "checklist"           :v-adjust 0.0 :face all-the-icons-lgreen)
+    (cfw:calendar-mode         all-the-icons-octicon "calendar"            :v-adjust 0.0)
+    (ibuffer-mode              all-the-icons-faicon "files-o"              :v-adjust 0.0 :face all-the-icons-dsilver)
+    (messages-buffer-mode      all-the-icons-faicon "stack-overflow"       :v-adjust -0.1)
+    (help-mode                 all-the-icons-faicon "info"                 :v-adjust -0.1 :face all-the-icons-purple)
+    (benchmark-init/tree-mode  all-the-icons-octicon "dashboard"           :v-adjust 0.0)
+    (jenkins-mode              all-the-icons-fileicon "jenkins"            :face all-the-icons-blue)
+    (magit-popup-mode          all-the-icons-alltheicon "git"              :face all-the-icons-red)
+    (magit-status-mode         all-the-icons-alltheicon "git"              :face all-the-icons-lred)
+    (magit-log-mode            all-the-icons-alltheicon "git"              :face all-the-icons-green)
+    (Custom-mode               all-the-icons-octicon "settings")
+
+    ;; Special matcher for Web Mode based on the `web-mode-content-type' of the current buffer
+    (web-mode             all-the-icons--web-mode-icon)
+
+    (fundamental-mode                   all-the-icons-fileicon "elisp"            :height 1.0 :v-adjust -0.2 :face all-the-icons-dsilver)
+    (special-mode                       all-the-icons-fileicon "elisp"            :height 1.0 :v-adjust -0.2 :face all-the-icons-yellow)
+    (text-mode                          all-the-icons-octicon "file-text"         :v-adjust 0.0 :face all-the-icons-cyan)
+    (ruby-mode                          all-the-icons-alltheicon "ruby-alt"       :face all-the-icons-lred)
+    (inf-ruby-mode                      all-the-icons-alltheicon "ruby-alt"       :face all-the-icons-red)
+    (projectile-rails-compilation-mode  all-the-icons-alltheicon "ruby-alt"       :face all-the-icons-red)
+    (rspec-compilation-mode             all-the-icons-alltheicon "ruby-alt"       :face all-the-icons-red)
+    (rake-compilation-mode              all-the-icons-alltheicon "ruby-alt"       :face all-the-icons-red)
+    (shell-mode                         all-the-icons-alltheicon "terminal"       :face all-the-icons-purple)
+    (fish-mode                          all-the-icons-alltheicon "terminal"       :face all-the-icons-lpink)
+    (nginx-mode                         all-the-icons-fileicon "nginx"            :height 0.9  :face all-the-icons-dgreen)
+    (apache-mode                        all-the-icons-alltheicon "apache"         :height 0.9  :face all-the-icons-dgreen)
+    (makefile-mode                      all-the-icons-fileicon "gnu"              :face all-the-icons-dorange)
+    (dockerfile-mode                    all-the-icons-fileicon "dockerfile"       :face all-the-icons-blue)
+    (docker-compose-mode                all-the-icons-fileicon "dockerfile"       :face all-the-icons-lblue)
+    (xml-mode                           all-the-icons-faicon "file-code-o"        :height 0.95 :face all-the-icons-lorange)
+    (json-mode                          all-the-icons-octicon "settings"          :face all-the-icons-yellow)
+    (yaml-mode                          all-the-icons-octicon "settings"          :v-adjust 0.0 :face all-the-icons-dyellow)
+    (elisp-byte-code-mode               all-the-icons-octicon "file-binary"       :v-adjust 0.0 :face all-the-icons-dsilver)
+    (archive-mode                       all-the-icons-octicon "file-zip"          :v-adjust 0.0 :face all-the-icons-lmaroon)
+    (elm-mode                           all-the-icons-fileicon "elm"              :face all-the-icons-blue)
+    (erlang-mode                        all-the-icons-alltheicon "erlang"         :face all-the-icons-red :v-adjust -0.1 :height 0.9)
+    (elixir-mode                        all-the-icons-alltheicon "elixir"         :face all-the-icons-lorange :v-adjust -0.1 :height 0.9)
+    (java-mode                          all-the-icons-alltheicon "java"           :height 1.0  :face all-the-icons-purple)
+    (go-mode                            all-the-icons-alltheicon "go"             :height 1.0  :face all-the-icons-blue)
+    (matlab-mode                        all-the-icons-fileicon "matlab"           :face all-the-icons-orange)
+    (perl-mode                          all-the-icons-alltheicon "perl"           :face all-the-icons-lorange)
+    (cperl-mode                         all-the-icons-alltheicon "perl"           :face all-the-icons-lorange)
+    (php-mode                           all-the-icons-fileicon "php"              :face all-the-icons-lsilver)
+    (prolog-mode                        all-the-icons-alltheicon "prolog"         :height 1.1  :face all-the-icons-lmaroon)
+    (python-mode                        all-the-icons-alltheicon "python"         :height 1.0  :face all-the-icons-dblue)
+    (racket-mode                        all-the-icons-fileicon "racket"           :height 1.2 :face all-the-icons-red)
+    (rust-mode                          all-the-icons-alltheicon "rust"           :height 1.2  :face all-the-icons-maroon)
+    (scala-mode                         all-the-icons-alltheicon "scala"          :face all-the-icons-red)
+    (scheme-mode                        all-the-icons-fileicon   "scheme"         :height 1.2 :face all-the-icons-red)
+    (swift-mode                         all-the-icons-alltheicon "swift"          :height 1.0 :v-adjust -0.1 :face all-the-icons-green)
+    (c-mode                             all-the-icons-alltheicon "c-line"         :face all-the-icons-blue)
+    (c++-mode                           all-the-icons-alltheicon "cplusplus-line" :v-adjust -0.2 :face all-the-icons-blue)
+    (csharp-mode                        all-the-icons-alltheicon "csharp-line"    :face all-the-icons-dblue)
+    (clojure-mode                       all-the-icons-alltheicon "clojure-line"   :height 1.0  :face all-the-icons-blue)
+    (cider-repl-mode                    all-the-icons-alltheicon "clojure-line"   :height 1.0  :face all-the-icons-dblue)
+    (clojurescript-mode                 all-the-icons-fileicon "cljs"             :height 1.0  :face all-the-icons-dblue)
+    (coffee-mode                        all-the-icons-alltheicon "coffeescript"   :height 1.0  :face all-the-icons-maroon)
+    (lisp-mode                          all-the-icons-fileicon "lisp"             :face all-the-icons-orange)
+    (css-mode                           all-the-icons-alltheicon "css3"           :face all-the-icons-yellow)
+    (scss-mode                          all-the-icons-alltheicon "sass"           :face all-the-icons-pink)
+    (sass-mode                          all-the-icons-alltheicon "sass"           :face all-the-icons-dpink)
+    (less-css-mode                      all-the-icons-alltheicon "less"           :height 0.8  :face all-the-icons-dyellow)
+    (stylus-mode                        all-the-icons-alltheicon "stylus"         :face all-the-icons-lgreen)
+    (csv-mode                           all-the-icons-octicon "graph"             :v-adjust 0.0 :face all-the-icons-dblue)
+    (haskell-mode                       all-the-icons-alltheicon "haskell"        :height 1.0  :face all-the-icons-red)
+    (haml-mode                          all-the-icons-fileicon "haml"             :face all-the-icons-lyellow)
+    (html-mode                          all-the-icons-alltheicon "html5"          :face all-the-icons-orange)
+    (rhtml-mode                         all-the-icons-alltheicon "html5"          :face all-the-icons-lred)
+    (mustache-mode                      all-the-icons-fileicon "moustache"        :face all-the-icons-green)
+    (slim-mode                          all-the-icons-octicon "dashboard"         :v-adjust 0.0 :face all-the-icons-yellow)
+    (jade-mode                          all-the-icons-fileicon "jade"             :face all-the-icons-red)
+    (pug-mode                           all-the-icons-fileicon "pug"              :face all-the-icons-red)
+    (react-mode                         all-the-icons-alltheicon "react"          :height 1.1  :face all-the-icons-lblue)
+    (image-mode                         all-the-icons-octicon "file-media"        :v-adjust 0.0 :face all-the-icons-blue)
+    (texinfo-mode                       all-the-icons-fileicon "tex"              :face all-the-icons-lred)
+    (markdown-mode                      all-the-icons-octicon "markdown"          :v-adjust 0.0 :face all-the-icons-lblue)
+    (bibtex-mode                        all-the-icons-fileicon "bib"              :face all-the-icons-maroon)
+    (org-mode                           all-the-icons-fileicon "org"              :face all-the-icons-lgreen)
+    (compilation-mode                   all-the-icons-faicon "cogs"               :v-adjust 0.0 :height 1.0)
+    (objc-mode                          all-the-icons-faicon "apple"              :v-adjust 0.0 :height 1.0)
+    ))
+
+;; ====================
+;;   Functions Start
+;; ====================
+
+(defun all-the-icons-auto-mode-match? (&optional file)
+  "Whether or not FILE's `major-mode' match against its `auto-mode-alist'."
+  (let* ((file (or file (buffer-file-name) (buffer-name)))
+         (auto-mode (all-the-icons-match-to-alist file auto-mode-alist)))
+    (eq major-mode auto-mode)))
+
+(defun all-the-icons-match-to-alist (file alist)
+  "Match FILE against an entry in ALIST using `string-match'."
+  (cdr (cl-find-if (lambda (it) (string-match (car it) file)) alist)))
+
+(defun all-the-icons-dir-is-submodule (dir)
+  "Checker whether or not DIR is a git submodule."
+  (let* ((gitmodule-dir (locate-dominating-file dir ".gitmodules"))
+         (modules-file  (expand-file-name (format "%s.gitmodules" gitmodule-dir)))
+         (module-search (format "submodule \".*?%s\"" (file-name-base dir))))
+
+    (when (and gitmodule-dir (file-exists-p (format "%s/.git" dir)))
+      (with-temp-buffer
+        (insert-file-contents modules-file)
+        (search-forward-regexp module-search (point-max) t)))))
+
+;; Icon functions
+(defun all-the-icons-icon-for-dir (dir &optional chevron padding)
+  "Format an icon for DIR with CHEVRON similar to tree based directories.
+
+If PADDING is provided, it will prepend and separate the chevron
+and directory with PADDING.
+
+Produces different symbols by inspecting DIR to distinguish
+symlinks and git repositories which do not depend on the
+directory contents"
+  (let* ((matcher (all-the-icons-match-to-alist (file-name-base dir) all-the-icons-dir-icon-alist))
+         (path (expand-file-name dir))
+         (chevron (if chevron (all-the-icons-octicon (format "chevron-%s" chevron) :height 0.8 :v-adjust -0.1) ""))
+         (padding (or padding "\t"))
+         (icon (cond
+                ((file-symlink-p path)
+                 (all-the-icons-octicon "file-symlink-directory" :height 1.0))
+                ((all-the-icons-dir-is-submodule path)
+                 (all-the-icons-octicon "file-submodule" :height 1.0))
+                ((file-exists-p (format "%s/.git" path))
+                 (format "%s" (all-the-icons-octicon "repo" :height 1.1)))
+                (t (apply (car matcher) (cdr matcher))))))
+    (format "%s%s%s%s%s" padding chevron padding icon padding)))
+
+(defun all-the-icons-icon-for-buffer ()
+  "Get the formatted icon for the current buffer.
+
+This function prioritises the use of the buffers file extension to
+discern the icon when its `major-mode' matches its auto mode,
+otherwise it will use the buffers `major-mode' to decide its
+icon."
+  (all-the-icons--icon-info-for-buffer))
+
+(defun all-the-icons-icon-family-for-buffer ()
+  "Get the icon font family for the current buffer."
+  (all-the-icons--icon-info-for-buffer "family"))
+
+(defun all-the-icons--web-mode-icon (&rest arg-overrides) "Get icon for a `web-mode' buffer with ARG-OVERRIDES." (all-the-icons--web-mode nil arg-overrides))
+(defun all-the-icons--web-mode-icon-family () "Get icon family for a `web-mode' buffer." (all-the-icons--web-mode t))
+(defun all-the-icons--web-mode (&optional family arg-overrides)
+  "Return icon or FAMILY for `web-mode' based on `web-mode-content-type'.
+Providing ARG-OVERRIDES will modify the creation of the icon."
+  (let ((non-nil-args (cl-reduce (lambda (acc it) (if it (append acc (list it)) acc)) arg-overrides :initial-value '())))
+    (cond
+     ((equal web-mode-content-type "jsx")
+      (if family (all-the-icons-fileicon-family) (apply 'all-the-icons-fileicon (append '("jsx-2") non-nil-args))))
+     ((equal web-mode-content-type "javascript")
+      (if family (all-the-icons-alltheicon-family) (apply 'all-the-icons-alltheicon (append '("javascript") non-nil-args))))
+     ((equal web-mode-content-type "json")
+      (if family (all-the-icons-alltheicon-family) (apply 'all-the-icons-alltheicon (append '("less") non-nil-args))))
+     ((equal web-mode-content-type "xml")
+      (if family (all-the-icons-faicon-family) (apply 'all-the-icons-faicon (append '("file-code-o") non-nil-args))))
+     ((equal web-mode-content-type "css")
+      (if family (all-the-icons-alltheicon-family) (apply 'all-the-icons-alltheicon (append '("css3") non-nil-args))))
+     (t
+      (if family (all-the-icons-alltheicon-family) (apply 'all-the-icons-alltheicon (append '("html5") non-nil-args)))))))
+
+;; Icon Functions
+
+;;;###autoload
+(defun all-the-icons-icon-for-file (file &rest arg-overrides)
+  "Get the formatted icon for FILE.
+ARG-OVERRIDES should be a plist containining `:height',
+`:v-adjust' or `:face' properties like in the normal icon
+inserting functions."
+  (let* ((icon (all-the-icons-match-to-alist file all-the-icons-icon-alist))
+         (args (cdr icon)))
+    (when arg-overrides (setq args (append `(,(car args)) arg-overrides (cdr args))))
+    (apply (car icon) args)))
+
+;;;###autoload
+(defun all-the-icons-icon-for-mode (mode &rest arg-overrides)
+  "Get the formatted icon for MODE.
+ARG-OVERRIDES should be a plist containining `:height',
+`:v-adjust' or `:face' properties like in the normal icon
+inserting functions."
+  (let* ((icon (cdr (assoc mode all-the-icons-mode-icon-alist)))
+         (args (cdr icon)))
+    (when arg-overrides (setq args (append `(,(car args)) arg-overrides (cdr args))))
+    (if icon (apply (car icon) args) mode)))
+
+(memoize 'all-the-icons-icon-for-file)
+(memoize 'all-the-icons-icon-for-mode)
+
+;; Family Face Functions
+(defun all-the-icons-icon-family-for-file (file)
+  "Get the icons font family for FILE."
+  (let ((icon (all-the-icons-match-to-alist file all-the-icons-icon-alist)))
+    (funcall (intern (format "%s-family" (car icon))))))
+
+(defun all-the-icons-icon-family-for-mode (mode)
+  "Get the icons font family for MODE."
+  (let ((icon (cdr (assoc mode all-the-icons-mode-icon-alist))))
+    (if icon (funcall (intern (format "%s-family" (car icon)))) nil)))
+
+(defun all-the-icons-icon-family (icon)
+  "Get a propertized ICON family programatically."
+  (plist-get (get-text-property 0 'face icon) :family))
+
+(memoize 'all-the-icons-icon-family-for-file)
+(memoize 'all-the-icons-icon-family-for-mode)
+(memoize 'all-the-icons-icon-family)
+
+;;;###autoload
+(defun all-the-icons--icon-info-for-buffer (&optional f)
+  "Get icon info for the current buffer.
+
+When F is provided, the info function is calculated with the format
+`all-the-icons-icon-%s-for-file' or `all-the-icons-icon-%s-for-mode'."
+  (let* ((base-f (concat "all-the-icons-icon" (when f (format "-%s" f))))
+         (file-f (intern (concat base-f "-for-file")))
+         (mode-f (intern (concat base-f "-for-mode"))))
+    (if (and (buffer-file-name)
+             (all-the-icons-auto-mode-match?))
+        (funcall file-f (file-name-nondirectory (buffer-file-name)))
+      (funcall mode-f major-mode))))
+
+;; Weather icons
+(defun all-the-icons-icon-for-weather (weather)
+  "Get an icon for a WEATHER status."
+  (let ((icon (all-the-icons-match-to-alist weather all-the-icons-weather-icon-alist)))
+    (if icon (apply (car icon) (cdr icon)) weather)))
+
+;; Definitions
+
+(eval-and-compile
+  (defun all-the-icons--function-name (name)
+    "Get the symbol for an icon function name for icon set NAME."
+    (intern (concat "all-the-icons-" (downcase (symbol-name name)))))
+
+  (defun all-the-icons--family-name (name)
+    "Get the symbol for an icon family function for icon set NAME."
+    (intern (concat "all-the-icons-" (downcase (symbol-name name)) "-family")))
+
+  (defun all-the-icons--data-name (name)
+    "Get the symbol for an icon family function for icon set NAME."
+    (intern (concat "all-the-icons-" (downcase (symbol-name name)) "-data")))
+
+  (defun all-the-icons--insert-function-name (name)
+    "Get the symbol for an icon insert function for icon set NAME."
+    (intern (concat "all-the-icons-insert-" (downcase (symbol-name name))))))
+
+;; Icon insertion functions
+
+(defun all-the-icons--read-candidates ()
+  "Helper to build a list of candidates for all families."
+  (cl-reduce 'append (mapcar (lambda (it) (all-the-icons--read-candidates-for-family it t)) all-the-icons-font-families)))
+
+(defun all-the-icons--read-candidates-for-family (family &optional show-family)
+  "Helper to build read candidates for FAMILY.
+If SHOW-FAMILY is non-nil, displays the icons family in the candidate string."
+  (let ((data   (funcall (all-the-icons--data-name family)))
+        (icon-f (all-the-icons--function-name family)))
+    (mapcar
+     (lambda (it)
+       (let* ((icon-name (car it))
+              (icon-name-head (substring icon-name 0 1))
+              (icon-name-tail (substring icon-name 1))
+
+              (icon-display (propertize icon-name-head 'display (format "%s\t%s" (funcall icon-f icon-name) icon-name-head)))
+              (icon-family (if show-family (format "\t[%s]" family) ""))
+
+              (candidate-name (format "%s%s%s" icon-display icon-name-tail icon-family))
+              (candidate-icon (funcall (all-the-icons--function-name family) icon-name)))
+
+         (cons candidate-name candidate-icon)))
+     data)))
+
+;;;###autoload
+(defun all-the-icons-install-fonts (&optional pfx)
+  "Helper function to download and install the latests fonts based on OS.
+When PFX is non-nil, ignore the prompt and just install"
+  (interactive "P")
+  (when (or pfx (yes-or-no-p "This will download and install fonts, are you sure you want to do this?"))
+    (let* ((url-format "https://github.com/domtronn/all-the-icons.el/blob/master/fonts/%s?raw=true")
+           (font-dest (cl-case window-system
+                        (x  (concat (or (getenv "XDG_DATA_HOME")            ;; Default Linux install directories
+                                        (concat (getenv "HOME") "/.local/share"))
+                                    "/fonts/"))
+                        (mac (concat (getenv "HOME") "/Library/Fonts/" ))
+                        (ns (concat (getenv "HOME") "/Library/Fonts/" ))))  ;; Default MacOS install directory
+           (known-dest? (stringp font-dest))
+           (font-dest (or font-dest (read-directory-name "Font installation directory: " "~/"))))
+
+      (unless (file-directory-p font-dest) (mkdir font-dest t))
+
+      (mapc (lambda (font)
+              (url-copy-file (format url-format font) (expand-file-name font font-dest) t))
+            all-the-icons-font-names)
+      (when known-dest?
+        (message "Fonts downloaded, updating font cache... <fc-cache -f -v> ")
+        (shell-command-to-string (format "fc-cache -f -v")))
+      (message "%s Successfully %s `all-the-icons' fonts to `%s'!"
+               (all-the-icons-wicon "stars" :v-adjust 0.0)
+               (if known-dest? "installed" "downloaded")
+               font-dest))))
+
+;;;###autoload
+(defun all-the-icons-insert (&optional arg family)
+  "Interactive icon insertion function.
+When Prefix ARG is non-nil, insert the propertized icon.
+When FAMILY is non-nil, limit the candidates to the icon set matching it."
+  (interactive "P")
+  (let* ((standard-output (current-buffer))
+         (candidates (if family
+                         (all-the-icons--read-candidates-for-family family)
+                       (all-the-icons--read-candidates)))
+         (prompt     (if family
+                         (format "%s Icon: " (funcall (all-the-icons--family-name family)))
+                       "Icon : "))
+
+         (selection (completing-read prompt candidates nil t))
+         (result    (cdr (assoc selection candidates))))
+
+    (if arg (prin1 result) (insert result))))
+
+;; Debug Helpers
+
+(defun all-the-icons-insert-icons-for (family &optional height duration)
+  "Insert all of the available icons associated with FAMILY.
+If a HEIGHT is provided it will render the icons at this height.
+This is useful both to see the icons more clearly and to test
+different height rendering.  If DURATION is provided, it will
+pause for DURATION seconds between printing each character."
+  (let* ((data-f    (all-the-icons--data-name family))
+         (insert-f  (all-the-icons--function-name family))
+
+         (height (or height 2.0))
+         (data (funcall data-f)))
+    (mapc
+     (lambda (it)
+       (insert (format "%s - %s\n" (funcall insert-f (car it) :height height) (car it)))
+       (when duration (sit-for duration 0)))
+     data)))
+
+(defmacro define-icon (name alist family &optional font-name)
+  "Macro to generate functions for inserting icons for icon set NAME.
+
+NAME defines is the name of the iconset and will produce a
+function of the for `all-the-icons-NAME'.
+
+ALIST is the alist containing maps between icon names and the
+UniCode for the character.  All of these can be found in the data
+directory of this package.
+
+FAMILY is the font family to use for the icons.
+FONT-NAME is the name of the .ttf file providing the font, defaults to FAMILY."
+  `(progn
+     (add-to-list 'all-the-icons-font-families (quote ,name))
+     (add-to-list 'all-the-icons-font-names (quote ,(downcase (format "%s.ttf" (or font-name family)))))
+
+     (defun ,(all-the-icons--family-name name) () ,family)
+     (defun ,(all-the-icons--data-name name) () ,alist)
+     (defun ,(all-the-icons--function-name name) (icon-name &rest args)
+       (let ((icon (cdr (assoc icon-name ,alist)))
+             (other-face (when all-the-icons-color-icons (plist-get args :face)))
+             (height  (* all-the-icons-scale-factor (or (plist-get args :height) 1.0)))
+             (v-adjust (* all-the-icons-scale-factor (or (plist-get args :v-adjust) all-the-icons-default-adjust)))
+             (family ,family))
+         (unless icon
+           (error (format "Unable to find icon with name `%s' in icon set `%s'" icon-name (quote ,name))))
+         (propertize icon
+                     'face (if other-face
+                               `(:family ,family :height ,height :inherit ,other-face)
+                             `(:family ,family :height ,height))
+                     'display `(raise ,v-adjust)
+                     'rear-nonsticky t
+                     'font-lock-ignore t)))
+     (defun ,(all-the-icons--insert-function-name name) (&optional arg)
+       ,(format "Insert a %s icon at point." family)
+       (interactive "P")
+       (all-the-icons-insert arg (quote ,name)))))
+
+(define-icon alltheicon all-the-icons-data/alltheicons-alist    "all-the-icons")
+(define-icon fileicon   all-the-icons-data/file-icon-alist      "file-icons")
+(define-icon faicon     all-the-icons-data/fa-icon-alist        "FontAwesome")
+(define-icon octicon    all-the-icons-data/octicons-alist       "github-octicons" "octicons")
+(define-icon wicon      all-the-icons-data/weather-icons-alist  "Weather Icons"   "weathericons")
+(define-icon material   all-the-icons-data/material-icons-alist "Material Icons"  "material-design-icons")
+
+(provide 'all-the-icons)
+
+;;; all-the-icons.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/all-the-icons-20180125.757/all-the-icons.elc b/configs/shared/emacs/.emacs.d/elpa/all-the-icons-20180125.757/all-the-icons.elc
new file mode 100644
index 0000000000..d1a2660e11
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/all-the-icons-20180125.757/all-the-icons.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/all-the-icons-20180125.757/data/data-alltheicons.el b/configs/shared/emacs/.emacs.d/elpa/all-the-icons-20180125.757/data/data-alltheicons.el
new file mode 100644
index 0000000000..3322500f19
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/all-the-icons-20180125.757/data/data-alltheicons.el
@@ -0,0 +1,70 @@
+(defvar all-the-icons-data/alltheicons-alist
+  '(
+
+    ( "apache"             . "\xe909" )
+    ( "atom"               . "\xe917" )
+    ( "aws"                . "\xe90c" )
+    ( "bower"              . "\xe918" )
+    ( "c"                  . "\xe915" )
+    ( "c-line"             . "\xe90f" )
+    ( "clojure"            . "\xe919" )
+    ( "clojure-line"       . "\xe91a" )
+    ( "coffeescript"       . "\xe914" )
+    ( "cplusplus"          . "\xe913" )
+    ( "cplusplus-line"     . "\xe910" )
+    ( "csharp"             . "\xe911" )
+    ( "csharp-line"        . "\xe912" )
+    ( "css3"               . "\xe91b" )
+    ( "css3-alt"           . "\xe91c" )
+    ( "d3"                 . "\xe90e" )
+    ( "dlang"              . "\xe935" )
+    ( "elixir"             . "\xe936" )
+    ( "erlang"             . "\xe934" )
+    ( "git"                . "\xe907" )
+    ( "go"                 . "\xe91d" )
+    ( "google-drive"       . "\xe91e" )
+    ( "grunt"              . "\xe90d" )
+    ( "grunt-line"         . "\xe91f" )
+    ( "gulp"               . "\xe920" )
+    ( "haskell"            . "\xe921" )
+    ( "html5"              . "\xe932" )
+    ( "jasmine"            . "\xe904" )
+    ( "java"               . "\xe922" )
+    ( "javascript"         . "\xe906" )
+    ( "javascript-badge"   . "\xe923" )
+    ( "javascript-shield"  . "\xe924" )
+    ( "less"               . "\xe90b" )
+    ( "nginx"              . "\xe933" )
+    ( "nodejs"             . "\xe925" )
+    ( "perl"               . "\xe905" )
+    ( "perldocs"           . "\xe926" )
+    ( "postgresql"         . "\xe938" )
+    ( "prolog"             . "\xe927" )
+    ( "python"             . "\xe928" )
+    ( "react"              . "\xe929" )
+    ( "ruby"               . "\xe92a" )
+    ( "ruby-alt"           . "\xe92b" )
+    ( "rust"               . "\xe92c" )
+    ( "sass"               . "\xe92d" )
+    ( "scala"              . "\xe908" )
+    ( "script"             . "\xe90a" )
+    ( "spring"             . "\xe937" )
+    ( "stylus"             . "\xe92e" )
+    ( "svg"                . "\xe903" )
+    ( "swift"              . "\xe92f" )
+    ( "terminal"           . "\xe930" )
+    ( "terminal-alt"       . "\xe931" )
+    ( "battery-charging"   . "\xe939" )
+
+    ( "arrow-left"  . "\xe93a" )
+    ( "arrow-right" . "\xe93b" )
+    ( "cup-left"    . "\xe93c" )
+    ( "cup-right"   . "\xe93d" )
+    ( "slant-left"  . "\xe93e" )
+    ( "slant-right" . "\xe93f" )
+    ( "wave-left"   . "\xe940" )
+    ( "wave-right"  . "\xe941" )
+
+    ))
+
+(provide 'data-alltheicons)
diff --git a/configs/shared/emacs/.emacs.d/elpa/all-the-icons-20180125.757/data/data-alltheicons.elc b/configs/shared/emacs/.emacs.d/elpa/all-the-icons-20180125.757/data/data-alltheicons.elc
new file mode 100644
index 0000000000..dda280702b
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/all-the-icons-20180125.757/data/data-alltheicons.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/all-the-icons-20180125.757/data/data-faicons.el b/configs/shared/emacs/.emacs.d/elpa/all-the-icons-20180125.757/data/data-faicons.el
new file mode 100644
index 0000000000..6ab0480646
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/all-the-icons-20180125.757/data/data-faicons.el
@@ -0,0 +1,641 @@
+(defvar all-the-icons-data/fa-icon-alist
+  '(
+
+    ("500px" . "\xf26e")
+    ("adjust" . "\xf042")
+    ("adn" . "\xf170")
+    ("align-center" . "\xf037")
+    ("align-justify" . "\xf039")
+    ("align-left" . "\xf036")
+    ("align-right" . "\xf038")
+    ("amazon" . "\xf270")
+    ("ambulance" . "\xf0f9")
+    ("american-sign-language-interpreting" . "\xf2a3")
+    ("anchor" . "\xf13d")
+    ("android" . "\xf17b")
+    ("angellist" . "\xf209")
+    ("angle-double-down" . "\xf103")
+    ("angle-double-left" . "\xf100")
+    ("angle-double-right" . "\xf101")
+    ("angle-double-up" . "\xf102")
+    ("angle-down" . "\xf107")
+    ("angle-left" . "\xf104")
+    ("angle-right" . "\xf105")
+    ("angle-up" . "\xf106")
+    ("apple" . "\xf179")
+    ("archive" . "\xf187")
+    ("area-chart" . "\xf1fe")
+    ("arrow-circle-down" . "\xf0ab")
+    ("arrow-circle-left" . "\xf0a8")
+    ("arrow-circle-o-down" . "\xf01a")
+    ("arrow-circle-o-left" . "\xf190")
+    ("arrow-circle-o-right" . "\xf18e")
+    ("arrow-circle-o-up" . "\xf01b")
+    ("arrow-circle-right" . "\xf0a9")
+    ("arrow-circle-up" . "\xf0aa")
+    ("arrow-down" . "\xf063")
+    ("arrow-left" . "\xf060")
+    ("arrow-right" . "\xf061")
+    ("arrow-up" . "\xf062")
+    ("arrows" . "\xf047")
+    ("arrows-alt" . "\xf0b2")
+    ("arrows-h" . "\xf07e")
+    ("arrows-v" . "\xf07d")
+    ("assistive-listening-systems" . "\xf2a2")
+    ("asterisk" . "\xf069")
+    ("at" . "\xf1fa")
+    ("audio-description" . "\xf29e")
+    ("backward" . "\xf04a")
+    ("balance-scale" . "\xf24e")
+    ("ban" . "\xf05e")
+    ("bar-chart" . "\xf080")
+    ("barcode" . "\xf02a")
+    ("bars" . "\xf0c9")
+    ("battery-empty" . "\xf244")
+    ("battery-full" . "\xf240")
+    ("battery-half" . "\xf242")
+    ("battery-quarter" . "\xf243")
+    ("battery-three-quarters" . "\xf241")
+    ("bed" . "\xf236")
+    ("beer" . "\xf0fc")
+    ("behance" . "\xf1b4")
+    ("behance-square" . "\xf1b5")
+    ("bell" . "\xf0f3")
+    ("bell-o" . "\xf0a2")
+    ("bell-slash" . "\xf1f6")
+    ("bell-slash-o" . "\xf1f7")
+    ("bicycle" . "\xf206")
+    ("binoculars" . "\xf1e5")
+    ("birthday-cake" . "\xf1fd")
+    ("bitbucket" . "\xf171")
+    ("bitbucket-square" . "\xf172")
+    ("black-tie" . "\xf27e")
+    ("blind" . "\xf29d")
+    ("bluetooth" . "\xf293")
+    ("bluetooth-b" . "\xf294")
+    ("bold" . "\xf032")
+    ("bolt" . "\xf0e7")
+    ("bomb" . "\xf1e2")
+    ("book" . "\xf02d")
+    ("bookmark" . "\xf02e")
+    ("bookmark-o" . "\xf097")
+    ("braille" . "\xf2a1")
+    ("briefcase" . "\xf0b1")
+    ("btc" . "\xf15a")
+    ("bug" . "\xf188")
+    ("building" . "\xf1ad")
+    ("building-o" . "\xf0f7")
+    ("bullhorn" . "\xf0a1")
+    ("bullseye" . "\xf140")
+    ("bus" . "\xf207")
+    ("buysellads" . "\xf20d")
+    ("calculator" . "\xf1ec")
+    ("calendar" . "\xf073")
+    ("calendar-check-o" . "\xf274")
+    ("calendar-minus-o" . "\xf272")
+    ("calendar-o" . "\xf133")
+    ("calendar-plus-o" . "\xf271")
+    ("calendar-times-o" . "\xf273")
+    ("camera" . "\xf030")
+    ("camera-retro" . "\xf083")
+    ("car" . "\xf1b9")
+    ("caret-down" . "\xf0d7")
+    ("caret-left" . "\xf0d9")
+    ("caret-right" . "\xf0da")
+    ("caret-square-o-down" . "\xf150")
+    ("caret-square-o-left" . "\xf191")
+    ("caret-square-o-right" . "\xf152")
+    ("caret-square-o-up" . "\xf151")
+    ("caret-up" . "\xf0d8")
+    ("cart-arrow-down" . "\xf218")
+    ("cart-plus" . "\xf217")
+    ("cc" . "\xf20a")
+    ("cc-amex" . "\xf1f3")
+    ("cc-diners-club" . "\xf24c")
+    ("cc-discover" . "\xf1f2")
+    ("cc-jcb" . "\xf24b")
+    ("cc-mastercard" . "\xf1f1")
+    ("cc-paypal" . "\xf1f4")
+    ("cc-stripe" . "\xf1f5")
+    ("cc-visa" . "\xf1f0")
+    ("certificate" . "\xf0a3")
+    ("chain-broken" . "\xf127")
+    ("check" . "\xf00c")
+    ("check-circle" . "\xf058")
+    ("check-circle-o" . "\xf05d")
+    ("check-square" . "\xf14a")
+    ("check-square-o" . "\xf046")
+    ("chevron-circle-down" . "\xf13a")
+    ("chevron-circle-left" . "\xf137")
+    ("chevron-circle-right" . "\xf138")
+    ("chevron-circle-up" . "\xf139")
+    ("chevron-down" . "\xf078")
+    ("chevron-left" . "\xf053")
+    ("chevron-right" . "\xf054")
+    ("chevron-up" . "\xf077")
+    ("child" . "\xf1ae")
+    ("chrome" . "\xf268")
+    ("circle" . "\xf111")
+    ("circle-o" . "\xf10c")
+    ("circle-o-notch" . "\xf1ce")
+    ("circle-thin" . "\xf1db")
+    ("clipboard" . "\xf0ea")
+    ("clock-o" . "\xf017")
+    ("clone" . "\xf24d")
+    ("cloud" . "\xf0c2")
+    ("cloud-download" . "\xf0ed")
+    ("cloud-upload" . "\xf0ee")
+    ("code" . "\xf121")
+    ("code-fork" . "\xf126")
+    ("codepen" . "\xf1cb")
+    ("codiepie" . "\xf284")
+    ("coffee" . "\xf0f4")
+    ("cog" . "\xf013")
+    ("cogs" . "\xf085")
+    ("columns" . "\xf0db")
+    ("comment" . "\xf075")
+    ("comment-o" . "\xf0e5")
+    ("commenting" . "\xf27a")
+    ("commenting-o" . "\xf27b")
+    ("comments" . "\xf086")
+    ("comments-o" . "\xf0e6")
+    ("compass" . "\xf14e")
+    ("compress" . "\xf066")
+    ("connectdevelop" . "\xf20e")
+    ("contao" . "\xf26d")
+    ("copyright" . "\xf1f9")
+    ("creative-commons" . "\xf25e")
+    ("credit-card" . "\xf09d")
+    ("credit-card-alt" . "\xf283")
+    ("crop" . "\xf125")
+    ("crosshairs" . "\xf05b")
+    ("css3" . "\xf13c")
+    ("cube" . "\xf1b2")
+    ("cubes" . "\xf1b3")
+    ("cutlery" . "\xf0f5")
+    ("dashcube" . "\xf210")
+    ("database" . "\xf1c0")
+    ("deaf" . "\xf2a4")
+    ("delicious" . "\xf1a5")
+    ("desktop" . "\xf108")
+    ("deviantart" . "\xf1bd")
+    ("diamond" . "\xf219")
+    ("digg" . "\xf1a6")
+    ("dot-circle-o" . "\xf192")
+    ("download" . "\xf019")
+    ("dribbble" . "\xf17d")
+    ("dropbox" . "\xf16b")
+    ("drupal" . "\xf1a9")
+    ("edge" . "\xf282")
+    ("eject" . "\xf052")
+    ("ellipsis-h" . "\xf141")
+    ("ellipsis-v" . "\xf142")
+    ("empire" . "\xf1d1")
+    ("envelope" . "\xf0e0")
+    ("envelope-o" . "\xf003")
+    ("envelope-square" . "\xf199")
+    ("envira" . "\xf299")
+    ("eraser" . "\xf12d")
+    ("eur" . "\xf153")
+    ("exchange" . "\xf0ec")
+    ("exclamation" . "\xf12a")
+    ("exclamation-circle" . "\xf06a")
+    ("exclamation-triangle" . "\xf071")
+    ("expand" . "\xf065")
+    ("expeditedssl" . "\xf23e")
+    ("external-link" . "\xf08e")
+    ("external-link-square" . "\xf14c")
+    ("eye" . "\xf06e")
+    ("eye-slash" . "\xf070")
+    ("eyedropper" . "\xf1fb")
+    ("facebook" . "\xf09a")
+    ("facebook-official" . "\xf230")
+    ("facebook-square" . "\xf082")
+    ("fast-backward" . "\xf049")
+    ("fast-forward" . "\xf050")
+    ("fax" . "\xf1ac")
+    ("female" . "\xf182")
+    ("fighter-jet" . "\xf0fb")
+    ("file" . "\xf15b")
+    ("file-archive-o" . "\xf1c6")
+    ("file-audio-o" . "\xf1c7")
+    ("file-code-o" . "\xf1c9")
+    ("file-excel-o" . "\xf1c3")
+    ("file-image-o" . "\xf1c5")
+    ("file-o" . "\xf016")
+    ("file-pdf-o" . "\xf1c1")
+    ("file-powerpoint-o" . "\xf1c4")
+    ("file-text" . "\xf15c")
+    ("file-text-o" . "\xf0f6")
+    ("file-video-o" . "\xf1c8")
+    ("file-word-o" . "\xf1c2")
+    ("files-o" . "\xf0c5")
+    ("film" . "\xf008")
+    ("filter" . "\xf0b0")
+    ("fire" . "\xf06d")
+    ("fire-extinguisher" . "\xf134")
+    ("firefox" . "\xf269")
+    ("first-order" . "\xf2b0")
+    ("flag" . "\xf024")
+    ("flag-checkered" . "\xf11e")
+    ("flag-o" . "\xf11d")
+    ("flask" . "\xf0c3")
+    ("flickr" . "\xf16e")
+    ("floppy-o" . "\xf0c7")
+    ("folder" . "\xf07b")
+    ("folder-o" . "\xf114")
+    ("folder-open" . "\xf07c")
+    ("folder-open-o" . "\xf115")
+    ("font" . "\xf031")
+    ("font-awesome" . "\xf2b4")
+    ("fonticons" . "\xf280")
+    ("fort-awesome" . "\xf286")
+    ("forumbee" . "\xf211")
+    ("forward" . "\xf04e")
+    ("foursquare" . "\xf180")
+    ("frown-o" . "\xf119")
+    ("futbol-o" . "\xf1e3")
+    ("gamepad" . "\xf11b")
+    ("gavel" . "\xf0e3")
+    ("gbp" . "\xf154")
+    ("genderless" . "\xf22d")
+    ("get-pocket" . "\xf265")
+    ("gg" . "\xf260")
+    ("gg-circle" . "\xf261")
+    ("gift" . "\xf06b")
+    ("git" . "\xf1d3")
+    ("git-square" . "\xf1d2")
+    ("github" . "\xf09b")
+    ("github-alt" . "\xf113")
+    ("github-square" . "\xf092")
+    ("gitlab" . "\xf296")
+    ("glass" . "\xf000")
+    ("glide" . "\xf2a5")
+    ("glide-g" . "\xf2a6")
+    ("globe" . "\xf0ac")
+    ("google" . "\xf1a0")
+    ("google-plus" . "\xf0d5")
+    ("google-plus-official" . "\xf2b3")
+    ("google-plus-square" . "\xf0d4")
+    ("google-wallet" . "\xf1ee")
+    ("graduation-cap" . "\xf19d")
+    ("gratipay" . "\xf184")
+    ("h-square" . "\xf0fd")
+    ("hacker-news" . "\xf1d4")
+    ("hand-lizard-o" . "\xf258")
+    ("hand-o-down" . "\xf0a7")
+    ("hand-o-left" . "\xf0a5")
+    ("hand-o-right" . "\xf0a4")
+    ("hand-o-up" . "\xf0a6")
+    ("hand-paper-o" . "\xf256")
+    ("hand-peace-o" . "\xf25b")
+    ("hand-pointer-o" . "\xf25a")
+    ("hand-rock-o" . "\xf255")
+    ("hand-scissors-o" . "\xf257")
+    ("hand-spock-o" . "\xf259")
+    ("hashtag" . "\xf292")
+    ("hdd-o" . "\xf0a0")
+    ("header" . "\xf1dc")
+    ("headphones" . "\xf025")
+    ("heart" . "\xf004")
+    ("heart-o" . "\xf08a")
+    ("heartbeat" . "\xf21e")
+    ("history" . "\xf1da")
+    ("home" . "\xf015")
+    ("hospital-o" . "\xf0f8")
+    ("hourglass" . "\xf254")
+    ("hourglass-end" . "\xf253")
+    ("hourglass-half" . "\xf252")
+    ("hourglass-o" . "\xf250")
+    ("hourglass-start" . "\xf251")
+    ("houzz" . "\xf27c")
+    ("html5" . "\xf13b")
+    ("i-cursor" . "\xf246")
+    ("ils" . "\xf20b")
+    ("inbox" . "\xf01c")
+    ("indent" . "\xf03c")
+    ("industry" . "\xf275")
+    ("info" . "\xf129")
+    ("info-circle" . "\xf05a")
+    ("inr" . "\xf156")
+    ("instagram" . "\xf16d")
+    ("internet-explorer" . "\xf26b")
+    ("ioxhost" . "\xf208")
+    ("italic" . "\xf033")
+    ("joomla" . "\xf1aa")
+    ("jpy" . "\xf157")
+    ("jsfiddle" . "\xf1cc")
+    ("key" . "\xf084")
+    ("keyboard-o" . "\xf11c")
+    ("krw" . "\xf159")
+    ("language" . "\xf1ab")
+    ("laptop" . "\xf109")
+    ("lastfm" . "\xf202")
+    ("lastfm-square" . "\xf203")
+    ("leaf" . "\xf06c")
+    ("leanpub" . "\xf212")
+    ("lemon-o" . "\xf094")
+    ("level-down" . "\xf149")
+    ("level-up" . "\xf148")
+    ("life-ring" . "\xf1cd")
+    ("lightbulb-o" . "\xf0eb")
+    ("line-chart" . "\xf201")
+    ("link" . "\xf0c1")
+    ("linkedin" . "\xf0e1")
+    ("linkedin-square" . "\xf08c")
+    ("linux" . "\xf17c")
+    ("list" . "\xf03a")
+    ("list-alt" . "\xf022")
+    ("list-ol" . "\xf0cb")
+    ("list-ul" . "\xf0ca")
+    ("location-arrow" . "\xf124")
+    ("lock" . "\xf023")
+    ("long-arrow-down" . "\xf175")
+    ("long-arrow-left" . "\xf177")
+    ("long-arrow-right" . "\xf178")
+    ("long-arrow-up" . "\xf176")
+    ("low-vision" . "\xf2a8")
+    ("magic" . "\xf0d0")
+    ("magnet" . "\xf076")
+    ("male" . "\xf183")
+    ("map" . "\xf279")
+    ("map-marker" . "\xf041")
+    ("map-o" . "\xf278")
+    ("map-pin" . "\xf276")
+    ("map-signs" . "\xf277")
+    ("mars" . "\xf222")
+    ("mars-double" . "\xf227")
+    ("mars-stroke" . "\xf229")
+    ("mars-stroke-h" . "\xf22b")
+    ("mars-stroke-v" . "\xf22a")
+    ("maxcdn" . "\xf136")
+    ("meanpath" . "\xf20c")
+    ("medium" . "\xf23a")
+    ("medkit" . "\xf0fa")
+    ("meh-o" . "\xf11a")
+    ("mercury" . "\xf223")
+    ("microphone" . "\xf130")
+    ("microphone-slash" . "\xf131")
+    ("minus" . "\xf068")
+    ("minus-circle" . "\xf056")
+    ("minus-square" . "\xf146")
+    ("minus-square-o" . "\xf147")
+    ("mixcloud" . "\xf289")
+    ("mobile" . "\xf10b")
+    ("modx" . "\xf285")
+    ("money" . "\xf0d6")
+    ("moon-o" . "\xf186")
+    ("motorcycle" . "\xf21c")
+    ("mouse-pointer" . "\xf245")
+    ("music" . "\xf001")
+    ("neuter" . "\xf22c")
+    ("newspaper-o" . "\xf1ea")
+    ("object-group" . "\xf247")
+    ("object-ungroup" . "\xf248")
+    ("odnoklassniki" . "\xf263")
+    ("odnoklassniki-square" . "\xf264")
+    ("opencart" . "\xf23d")
+    ("openid" . "\xf19b")
+    ("opera" . "\xf26a")
+    ("optin-monster" . "\xf23c")
+    ("outdent" . "\xf03b")
+    ("pagelines" . "\xf18c")
+    ("paint-brush" . "\xf1fc")
+    ("paper-plane" . "\xf1d8")
+    ("paper-plane-o" . "\xf1d9")
+    ("paperclip" . "\xf0c6")
+    ("paragraph" . "\xf1dd")
+    ("pause" . "\xf04c")
+    ("pause-circle" . "\xf28b")
+    ("pause-circle-o" . "\xf28c")
+    ("paw" . "\xf1b0")
+    ("paypal" . "\xf1ed")
+    ("pencil" . "\xf040")
+    ("pencil-square" . "\xf14b")
+    ("pencil-square-o" . "\xf044")
+    ("percent" . "\xf295")
+    ("phone" . "\xf095")
+    ("phone-square" . "\xf098")
+    ("picture-o" . "\xf03e")
+    ("pie-chart" . "\xf200")
+    ("pied-piper" . "\xf2ae")
+    ("pied-piper-alt" . "\xf1a8")
+    ("pied-piper-pp" . "\xf1a7")
+    ("pinterest" . "\xf0d2")
+    ("pinterest-p" . "\xf231")
+    ("pinterest-square" . "\xf0d3")
+    ("plane" . "\xf072")
+    ("play" . "\xf04b")
+    ("play-circle" . "\xf144")
+    ("play-circle-o" . "\xf01d")
+    ("plug" . "\xf1e6")
+    ("plus" . "\xf067")
+    ("plus-circle" . "\xf055")
+    ("plus-square" . "\xf0fe")
+    ("plus-square-o" . "\xf196")
+    ("power-off" . "\xf011")
+    ("print" . "\xf02f")
+    ("product-hunt" . "\xf288")
+    ("puzzle-piece" . "\xf12e")
+    ("qq" . "\xf1d6")
+    ("qrcode" . "\xf029")
+    ("question" . "\xf128")
+    ("question-circle" . "\xf059")
+    ("question-circle-o" . "\xf29c")
+    ("quote-left" . "\xf10d")
+    ("quote-right" . "\xf10e")
+    ("random" . "\xf074")
+    ("rebel" . "\xf1d0")
+    ("recycle" . "\xf1b8")
+    ("reddit" . "\xf1a1")
+    ("reddit-alien" . "\xf281")
+    ("reddit-square" . "\xf1a2")
+    ("refresh" . "\xf021")
+    ("registered" . "\xf25d")
+    ("renren" . "\xf18b")
+    ("repeat" . "\xf01e")
+    ("reply" . "\xf112")
+    ("reply-all" . "\xf122")
+    ("retweet" . "\xf079")
+    ("road" . "\xf018")
+    ("rocket" . "\xf135")
+    ("rss" . "\xf09e")
+    ("rss-square" . "\xf143")
+    ("rub" . "\xf158")
+    ("safari" . "\xf267")
+    ("scissors" . "\xf0c4")
+    ("scribd" . "\xf28a")
+    ("search" . "\xf002")
+    ("search-minus" . "\xf010")
+    ("search-plus" . "\xf00e")
+    ("sellsy" . "\xf213")
+    ("server" . "\xf233")
+    ("share" . "\xf064")
+    ("share-alt" . "\xf1e0")
+    ("share-alt-square" . "\xf1e1")
+    ("share-square" . "\xf14d")
+    ("share-square-o" . "\xf045")
+    ("shield" . "\xf132")
+    ("ship" . "\xf21a")
+    ("shirtsinbulk" . "\xf214")
+    ("shopping-bag" . "\xf290")
+    ("shopping-basket" . "\xf291")
+    ("shopping-cart" . "\xf07a")
+    ("sign-in" . "\xf090")
+    ("sign-language" . "\xf2a7")
+    ("sign-out" . "\xf08b")
+    ("signal" . "\xf012")
+    ("simplybuilt" . "\xf215")
+    ("sitemap" . "\xf0e8")
+    ("skyatlas" . "\xf216")
+    ("skype" . "\xf17e")
+    ("slack" . "\xf198")
+    ("sliders" . "\xf1de")
+    ("slideshare" . "\xf1e7")
+    ("smile-o" . "\xf118")
+    ("snapchat" . "\xf2ab")
+    ("snapchat-ghost" . "\xf2ac")
+    ("snapchat-square" . "\xf2ad")
+    ("sort" . "\xf0dc")
+    ("sort-alpha-asc" . "\xf15d")
+    ("sort-alpha-desc" . "\xf15e")
+    ("sort-amount-asc" . "\xf160")
+    ("sort-amount-desc" . "\xf161")
+    ("sort-asc" . "\xf0de")
+    ("sort-desc" . "\xf0dd")
+    ("sort-numeric-asc" . "\xf162")
+    ("sort-numeric-desc" . "\xf163")
+    ("soundcloud" . "\xf1be")
+    ("space-shuttle" . "\xf197")
+    ("spinner" . "\xf110")
+    ("spoon" . "\xf1b1")
+    ("spotify" . "\xf1bc")
+    ("square" . "\xf0c8")
+    ("square-o" . "\xf096")
+    ("stack-exchange" . "\xf18d")
+    ("stack-overflow" . "\xf16c")
+    ("star" . "\xf005")
+    ("star-half" . "\xf089")
+    ("star-half-o" . "\xf123")
+    ("star-o" . "\xf006")
+    ("steam" . "\xf1b6")
+    ("steam-square" . "\xf1b7")
+    ("step-backward" . "\xf048")
+    ("step-forward" . "\xf051")
+    ("stethoscope" . "\xf0f1")
+    ("sticky-note" . "\xf249")
+    ("sticky-note-o" . "\xf24a")
+    ("stop" . "\xf04d")
+    ("stop-circle" . "\xf28d")
+    ("stop-circle-o" . "\xf28e")
+    ("street-view" . "\xf21d")
+    ("strikethrough" . "\xf0cc")
+    ("stumbleupon" . "\xf1a4")
+    ("stumbleupon-circle" . "\xf1a3")
+    ("subscript" . "\xf12c")
+    ("subway" . "\xf239")
+    ("suitcase" . "\xf0f2")
+    ("sun-o" . "\xf185")
+    ("superscript" . "\xf12b")
+    ("table" . "\xf0ce")
+    ("tablet" . "\xf10a")
+    ("tachometer" . "\xf0e4")
+    ("tag" . "\xf02b")
+    ("tags" . "\xf02c")
+    ("tasks" . "\xf0ae")
+    ("taxi" . "\xf1ba")
+    ("television" . "\xf26c")
+    ("tencent-weibo" . "\xf1d5")
+    ("terminal" . "\xf120")
+    ("text-height" . "\xf034")
+    ("text-width" . "\xf035")
+    ("th" . "\xf00a")
+    ("th-large" . "\xf009")
+    ("th-list" . "\xf00b")
+    ("themeisle" . "\xf2b2")
+    ("thumb-tack" . "\xf08d")
+    ("thumbs-down" . "\xf165")
+    ("thumbs-o-down" . "\xf088")
+    ("thumbs-o-up" . "\xf087")
+    ("thumbs-up" . "\xf164")
+    ("ticket" . "\xf145")
+    ("times" . "\xf00d")
+    ("times-circle" . "\xf057")
+    ("times-circle-o" . "\xf05c")
+    ("tint" . "\xf043")
+    ("toggle-off" . "\xf204")
+    ("toggle-on" . "\xf205")
+    ("trademark" . "\xf25c")
+    ("train" . "\xf238")
+    ("transgender" . "\xf224")
+    ("transgender-alt" . "\xf225")
+    ("trash" . "\xf1f8")
+    ("trash-o" . "\xf014")
+    ("tree" . "\xf1bb")
+    ("trello" . "\xf181")
+    ("tripadvisor" . "\xf262")
+    ("trophy" . "\xf091")
+    ("truck" . "\xf0d1")
+    ("try" . "\xf195")
+    ("tty" . "\xf1e4")
+    ("tumblr" . "\xf173")
+    ("tumblr-square" . "\xf174")
+    ("twitch" . "\xf1e8")
+    ("twitter" . "\xf099")
+    ("twitter-square" . "\xf081")
+    ("umbrella" . "\xf0e9")
+    ("underline" . "\xf0cd")
+    ("undo" . "\xf0e2")
+    ("universal-access" . "\xf29a")
+    ("university" . "\xf19c")
+    ("unlock" . "\xf09c")
+    ("unlock-alt" . "\xf13e")
+    ("upload" . "\xf093")
+    ("usb" . "\xf287")
+    ("usd" . "\xf155")
+    ("user" . "\xf007")
+    ("user-md" . "\xf0f0")
+    ("user-plus" . "\xf234")
+    ("user-secret" . "\xf21b")
+    ("user-times" . "\xf235")
+    ("users" . "\xf0c0")
+    ("venus" . "\xf221")
+    ("venus-double" . "\xf226")
+    ("venus-mars" . "\xf228")
+    ("viacoin" . "\xf237")
+    ("viadeo" . "\xf2a9")
+    ("viadeo-square" . "\xf2aa")
+    ("video-camera" . "\xf03d")
+    ("vimeo" . "\xf27d")
+    ("vimeo-square" . "\xf194")
+    ("vine" . "\xf1ca")
+    ("vk" . "\xf189")
+    ("volume-control-phone" . "\xf2a0")
+    ("volume-down" . "\xf027")
+    ("volume-off" . "\xf026")
+    ("volume-up" . "\xf028")
+    ("weibo" . "\xf18a")
+    ("weixin" . "\xf1d7")
+    ("whatsapp" . "\xf232")
+    ("wheelchair" . "\xf193")
+    ("wheelchair-alt" . "\xf29b")
+    ("wifi" . "\xf1eb")
+    ("wikipedia-w" . "\xf266")
+    ("windows" . "\xf17a")
+    ("wordpress" . "\xf19a")
+    ("wpbeginner" . "\xf297")
+    ("wpforms" . "\xf298")
+    ("wrench" . "\xf0ad")
+    ("xing" . "\xf168")
+    ("xing-square" . "\xf169")
+    ("y-combinator" . "\xf23b")
+    ("yahoo" . "\xf19e")
+    ("yelp" . "\xf1e9")
+    ("yoast" . "\xf2b1")
+    ("youtube" . "\xf167")
+    ("youtube-play" . "\xf16a")
+    ("youtube-square" . "\xf166")
+
+    ))
+
+(provide 'data-faicons)
diff --git a/configs/shared/emacs/.emacs.d/elpa/all-the-icons-20180125.757/data/data-faicons.elc b/configs/shared/emacs/.emacs.d/elpa/all-the-icons-20180125.757/data/data-faicons.elc
new file mode 100644
index 0000000000..a961975335
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/all-the-icons-20180125.757/data/data-faicons.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/all-the-icons-20180125.757/data/data-fileicons.el b/configs/shared/emacs/.emacs.d/elpa/all-the-icons-20180125.757/data/data-fileicons.el
new file mode 100644
index 0000000000..acc465fb68
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/all-the-icons-20180125.757/data/data-fileicons.el
@@ -0,0 +1,487 @@
+(defvar all-the-icons-data/file-icon-alist
+  '(
+		
+    ( "1c" . "\xa5ea" )
+    ( "1c-alt" . "\xea28" )
+    ( "MJML" . "\xea6f" )
+    ( "R" . "\xe905" )
+    ( "abap" . "\xe92b" )
+    ( "abif" . "\xea4e" )
+    ( "access" . "\xe9ea" )
+    ( "actionscript" . "\xe92e" )
+    ( "ada" . "\xe90b" )
+    ( "ae" . "\xe9f3" )
+    ( "ai" . "\xe6b4" )
+    ( "akka" . "\xea0e" )
+    ( "alex" . "\x29cb" )
+    ( "alloy" . "\xe935" )
+    ( "alpine-linux" . "\xe9ff" )
+    ( "ampl" . "\xe94e" )
+    ( "amx" . "\xe99b" )
+    ( "angelscript" . "\xea5b" )
+    ( "ansible" . "\x24b6" )
+    ( "ansible-alt" . "\x61" )
+    ( "ant" . "\xe93e" )
+    ( "antlr" . "\xe92c" )
+    ( "antwar" . "\x2591" )
+    ( "api-blueprint" . "\xe92d" )
+    ( "apl" . "\x234b" )
+    ( "apl-old" . "\xe909" )
+    ( "apple" . "\xe925" )
+    ( "appveyor" . "\xe923" )
+    ( "arc" . "\xe92f" )
+    ( "arch-linux" . "\x41" )
+    ( "arduino" . "\xe930" )
+    ( "arttext" . "\x24d0" )
+    ( "asciidoc" . "\xe918" )
+    ( "ats" . "\xe934" )
+    ( "audacity" . "\xe9f9" )
+    ( "augeas" . "\xe931" )
+    ( "aurelia" . "\xea48" )
+    ( "auto-hotkey" . "\xe932" )
+    ( "autoit" . "\xe933" )
+    ( "babel" . "\xe91f" )
+    ( "bazel" . "\xea5a" )
+    ( "bem" . "\xea59" )
+    ( "bib" . "\xe601" )
+    ( "bintray" . "\xea6e" )
+    ( "bithound" . "\xea2a" )
+    ( "blender" . "\xe9fa" )
+    ( "bluespec" . "\xe93c" )
+    ( "boo" . "\xe939" )
+    ( "brain" . "\xe93a" )
+    ( "brakeman" . "\xe9d6" )
+    ( "bro" . "\xe93b" )
+    ( "broccoli" . "\xe922" )
+    ( "brotli" . "\xea6c" )
+    ( "browserslist" . "\xea80" )
+    ( "brunch" . "\xea47" )
+    ( "buck" . "\xea46" )
+    ( "build-boot" . "\xf103" )
+    ( "bundler" . "\xea45" )
+    ( "byond" . "\xe962" )
+    ( "cabal" . "\xe9c2" )
+    ( "caddy" . "\xea58" )
+    ( "cake" . "\xe9e3" )
+    ( "cakefile" . "\xe924" )
+    ( "cakephp" . "\xea43" )
+    ( "cakephp-old" . "\xe9d3" )
+    ( "cc" . "\xe9d5" )
+    ( "ceylon" . "\xe94f" )
+    ( "chai" . "\x63" )
+    ( "chapel" . "\xe950" )
+    ( "chartjs" . "\xea0b" )
+    ( "chef" . "\xea42" )
+    ( "chuck" . "\xe943" )
+    ( "circle-ci" . "\xea12" )
+    ( "cirru" . "\xe951" )
+    ( "ckeditor" . "\xea0c" )
+    ( "clarion" . "\xe952" )
+    ( "clean" . "\xe95b" )
+    ( "click" . "\xe95c" )
+    ( "clips" . "\xe940" )
+    ( "clj" . "\xf105" )
+    ( "cljs" . "\xf104" )
+    ( "closure-template" . "\xea82" )
+    ( "cmake" . "\xe93f" )
+    ( "cobol" . "\xea44" )
+    ( "codecov" . "\x2602" )
+    ( "codekit" . "\xea41" )
+    ( "codemirror" . "\xea0d" )
+    ( "codeship" . "\xea6a" )
+    ( "cold-fusion" . "\xe929" )
+    ( "clisp" . "\xe972" )
+    ( "composer" . "\xe683" )
+    ( "config" . "\xf07c" )
+    ( "coq" . "\xe95f" )
+    ( "cordova" . "\xea11" )
+    ( "cp" . "\xe942" )
+    ( "cpan" . "\xea87" )
+    ( "creole" . "\xe95e" )
+    ( "crystal" . "\xe902" )
+    ( "cs-script" . "\xe9e2" )
+    ( "csound" . "\xe9f0" )
+    ( "cucumber" . "\xf02b" )
+    ( "cython" . "\xe963" )
+    ( "d3" . "\xea10" )
+    ( "darcs" . "\xe964" )
+    ( "dashboard" . "\xf07d" )
+    ( "dbase" . "\xe9f1" )
+    ( "default" . "\x1f5cc" )
+    ( "delphi" . "\xea40" )
+    ( "devicetree" . "\xea57" )
+    ( "diff" . "\xe960" )
+    ( "dockerfile" . "\xf106" )
+    ( "doclets" . "\xea3f" )
+    ( "doge" . "\xe946" )
+    ( "dom" . "\xea71" )
+    ( "donejs" . "\x1f3c1" )
+    ( "doxygen" . "\xe928" )
+    ( "dragula" . "\x1f44c" )
+    ( "drone" . "\xea3d" )
+    ( "dyalog" . "\xe90c" )
+    ( "dylib" . "\xea15" )
+    ( "e" . "\x45" )
+    ( "eagle" . "\xe965" )
+    ( "easybuild" . "\xea85" )
+    ( "ec" . "\xe9c9" )
+    ( "ecere" . "\xe966" )
+    ( "edge" . "\xea78" )
+    ( "editorconfig" . "\xea1b" )
+    ( "eiffel" . "\xe967" )
+    ( "ejs" . "\xea4b" )
+    ( "electron" . "\xea27" )
+    ( "elm" . "\xf102" )
+    ( "emacs" . "\xe926" )
+    ( "elisp" . "\xe926" )
+    ( "ember" . "\xe61b" )
+    ( "emberscript" . "\xe968" )
+    ( "eq" . "\xea0a" )
+    ( "esdoc" . "\xea5c" )
+    ( "eslint" . "\xea0f" )
+    ( "eslint-old" . "\xe90e" )
+    ( "excel" . "\xe9ee" )
+    ( "fabfile" . "\xe94b" )
+    ( "factor" . "\xe96a" )
+    ( "fancy" . "\xe96b" )
+    ( "fantom" . "\xe96f" )
+    ( "fbx" . "\xe9fc" )
+    ( "ffmpeg" . "\xea22" )
+    ( "finder" . "\xe9e9" )
+    ( "firebase" . "\xea7f" )
+    ( "flow" . "\xe921" )
+    ( "flux" . "\xe969" )
+    ( "font" . "\xe90f" )
+    ( "fontforge" . "\xfb00" )
+    ( "fortran" . "\xe90a" )
+    ( "franca" . "\xea56" )
+    ( "freemarker" . "\xe970" )
+    ( "frege" . "\xe96e" )
+    ( "fuel-ux" . "\xea09" )
+    ( "gams" . "\xe973" )
+    ( "gap" . "\xe971" )
+    ( "gdb" . "\xea08" )
+    ( "genshi" . "\xe976" )
+    ( "gentoo" . "\xe96d" )
+    ( "gf" . "\xe978" )
+    ( "gitlab" . "\xea3c" )
+    ( "glade" . "\xe938" )
+    ( "glyphs" . "\x47" )
+    ( "gn" . "\xea25" )
+    ( "gnu" . "\xe679" )
+    ( "go" . "\xe624" )
+    ( "godot" . "\xe974" )
+    ( "golo" . "\xe979" )
+    ( "gosu" . "\xe97a" )
+    ( "gradle" . "\xe903" )
+    ( "graphql" . "\xe97c" )
+    ( "graphviz" . "\xe97d" )
+    ( "groovy" . "\xe904" )
+    ( "grunt" . "\xe611" )
+    ( "gulp" . "\xe610" )
+    ( "hack" . "\xe9ce" )
+    ( "haml" . "\xf15b" )
+    ( "harbour" . "\xe97b" )
+    ( "hashicorp" . "\xe97e" )
+    ( "haxe" . "\xe907" )
+    ( "haxedevelop" . "\xea3b" )
+    ( "hg" . "\x263f" )
+    ( "hoplon" . "\xea4d" )
+    ( "hy" . "\xe97f" )
+    ( "icu" . "\xea23" )
+    ( "id" . "\xe9f4" )
+    ( "idl" . "\xe947" )
+    ( "idris" . "\xe983" )
+    ( "igorpro" . "\xe980" )
+    ( "image" . "\xf012" )
+    ( "inform7" . "\xe984" )
+    ( "inno" . "\xe985" )
+    ( "io" . "\xe981" )
+    ( "ioke" . "\xe982" )
+    ( "ionic-project" . "\xf14b" )
+    ( "isabelle" . "\xe945" )
+    ( "j" . "\xe937" )
+    ( "jade" . "\xe90d" )
+    ( "jake" . "\xe948" )
+    ( "jasmine" . "\xea3a" )
+    ( "jenkins" . "\xe667" )
+    ( "jest" . "\xea39" )
+    ( "jinja" . "\xe944" )
+    ( "jison" . "\xea55" )
+    ( "jolie" . "\xea75" )
+    ( "jsonld" . "\xe958" )
+    ( "jsx" . "\xf100" )
+    ( "jsx-2" . "\xf101" )
+    ( "jsx2-alt" . "\xe9e6" )
+    ( "julia" . "\x26ec" )
+    ( "junos" . "\xea81" )
+    ( "jupyter" . "\xe987" )
+    ( "karma" . "\xe9cd" )
+    ( "keynote" . "\xe9e5" )
+    ( "khronos" . "\xe9f8" )
+    ( "kicad" . "\xea4c" )
+    ( "kitchenci" . "\xea38" )
+    ( "kivy" . "\xe901" )
+    ( "knockout" . "\x4b" )
+    ( "kotlin" . "\xe989" )
+    ( "krl" . "\xe988" )
+    ( "labview" . "\xe98a" )
+    ( "lasso" . "\xe98c" )
+    ( "leaflet" . "\xea07" )
+    ( "lean" . "\x4c" )
+    ( "lerna" . "\xea37" )
+    ( "lfe" . "\xe94c" )
+    ( "libuv" . "\xea21" )
+    ( "lightwave" . "\xe9fb" )
+    ( "lime" . "\xea36" )
+    ( "lisp" . "\xe908" )
+    ( "livescript" . "\xe914" )
+    ( "llvm" . "\xe91d" )
+    ( "logtalk" . "\xe98d" )
+    ( "lookml" . "\xe98e" )
+    ( "lsl" . "\xe98b" )
+    ( "lua" . "\xe91b" )
+    ( "mako" . "\xe98f" )
+    ( "man-page" . "\xe936" )
+    ( "mapbox" . "\xe941" )
+    ( "markdownlint" . "\xf0c9" )
+    ( "marko" . "\xe920" )
+    ( "mathematica" . "\xe990" )
+    ( "mathjax" . "\xea06" )
+    ( "matlab" . "\xe991" )
+    ( "max" . "\xe993" )
+    ( "maxscript" . "\xe900" )
+    ( "maya" . "\xe9f6" )
+    ( "mediawiki" . "\xe954" )
+    ( "mercury" . "\xe994" )
+    ( "meson" . "\xea54" )
+    ( "metal" . "\x4d" )
+    ( "meteor" . "\xe6a5" )
+    ( "microsoft-infopath" . "\xea35" )
+    ( "minecraft" . "\xe9dc" )
+    ( "minizinc" . "\xea53" )
+    ( "mirah" . "\xe995" )
+    ( "miranda" . "\xea52" )
+    ( "mocha" . "\x26fe" )
+    ( "modula-2" . "\xe996" )
+    ( "moment" . "\x1f558" )
+    ( "moment-tz" . "\x1f30d" )
+    ( "monkey" . "\xe997" )
+    ( "moustache" . "\xe60f" )
+    ( "mruby" . "\xea18" )
+    ( "mupad" . "\xe9ca" )
+    ( "nano" . "\xea76" )
+    ( "nanoc" . "\xea51" )
+    ( "nant" . "\xe9e1" )
+    ( "nasm" . "\xea72" )
+    ( "neko" . "\xea05" )
+    ( "netlogo" . "\xe99c" )
+    ( "new-relic" . "\xe9d7" )
+    ( "nginx" . "\xf146b" )
+    ( "nib" . "\x2712" )
+    ( "nimrod" . "\xe998" )
+    ( "nit" . "\xe999" )
+    ( "nix" . "\xe99a" )
+    ( "nmap" . "\xe94d" )
+    ( "nodemon" . "\xea26" )
+    ( "normalize" . "\xea04" )
+    ( "npm" . "\xe91c" )
+    ( "npm-old" . "\xf17b" )
+    ( "nsis" . "\xea1e" )
+    ( "nsis-old" . "\xe992" )
+    ( "nuclide" . "\xea34" )
+    ( "nuget" . "\xe9d9" )
+    ( "numpy" . "\xe99d" )
+    ( "nunjucks" . "\xe953" )
+    ( "nvidia" . "\xe95d" )
+    ( "nxc" . "\xea6b" )
+    ( "obj" . "\xe9e8" )
+    ( "objective-j" . "\xe99e" )
+    ( "ocaml" . "\xe91a" )
+    ( "octave" . "\xea33" )
+    ( "onenote" . "\xe9eb" )
+    ( "ooc" . "\xe9cb" )
+    ( "opa" . "\x2601" )
+    ( "opencl" . "\xe99f" )
+    ( "opengl" . "\xea7a" )
+    ( "openoffice" . "\xe9e4" )
+    ( "openscad" . "\xe911" )
+    ( "org" . "\xe917" )
+    ( "owl" . "\xe957" )
+    ( "ox" . "\xe9a1" )
+    ( "oxygene" . "\xe9bf" )
+    ( "oz" . "\xe9be" )
+    ( "p4" . "\xea50" )
+    ( "pan" . "\xe9bd" )
+    ( "papyrus" . "\xe9bc" )
+    ( "parrot" . "\xe9bb" )
+    ( "pascal" . "\xe92a" )
+    ( "patch" . "\xe961" )
+    ( "pawn" . "\x265f" )
+    ( "pb" . "\xea14" )
+    ( "pegjs" . "\xea74" )
+    ( "perl6" . "\xe96c" )
+    ( "phalcon" . "\xe94a" )
+    ( "phoenix" . "\xea5f" )
+    ( "php" . "\xf147" )
+    ( "phpunit" . "\xea32" )
+    ( "pickle" . "\xe9c4" )
+    ( "pike" . "\xe9b9" )
+    ( "platformio" . "\xea2c" )
+    ( "pm2" . "\x2630" )
+    ( "pod" . "\xea84" )
+    ( "pogo" . "\xe9b8" )
+    ( "pointwise" . "\xe977" )
+    ( "polymer" . "\xea2b" )
+    ( "pony" . "\xe9b7" )
+    ( "postcss" . "\xe910" )
+    ( "postscript" . "\xe955" )
+    ( "povray" . "\x50" )
+    ( "powerpoint" . "\xe9ec" )
+    ( "powershell" . "\xe9da" )
+    ( "precision" . "\x2295" )
+    ( "premiere" . "\xe9f5" )
+    ( "processing" . "\xe9a0" )
+    ( "progress" . "\xe9c0" )
+    ( "propeller" . "\xe9b5" )
+    ( "proselint" . "\xea6d" )
+    ( "protractor" . "\xe9de" )
+    ( "ps" . "\xe6b8" )
+    ( "pug" . "\xea13" )
+    ( "pug-alt" . "\xe9d0" )
+    ( "puppet" . "\xf0c3" )
+    ( "purebasic" . "\x1b5" )
+    ( "purescript" . "\xe9b2" )
+    ( "racket" . "\xe9b1" )
+    ( "raml" . "\xe913" )
+    ( "rascal" . "\xea24" )
+    ( "rdoc" . "\xe9b0" )
+    ( "realbasic" . "\xe9af" )
+    ( "reason" . "\xea1d" )
+    ( "rebol" . "\xe9ae" )
+    ( "red" . "\xe9ad" )
+    ( "redux" . "\xea30" )
+    ( "regex" . "\x2a" )
+    ( "rexx" . "\xea16" )
+    ( "rhino" . "\xea4a" )
+    ( "ring" . "\x1f48d" )
+    ( "riot" . "\xe919" )
+    ( "robot" . "\xe9ac" )
+    ( "rollup" . "\xea20" )
+    ( "rollup-old" . "\xe9fd" )
+    ( "rot" . "\x1f764" )
+    ( "rspec" . "\xea31" )
+    ( "rst" . "\xe9cc" )
+    ( "sage" . "\xe9ab" )
+    ( "saltstack" . "\xe915" )
+    ( "sas" . "\xe95a" )
+    ( "sbt" . "\xe9d2" )
+    ( "sc" . "\xe9a2" )
+    ( "scheme" . "\x3bb" )
+    ( "scilab" . "\xe9a9" )
+    ( "scrutinizer" . "\xe9d4" )
+    ( "self" . "\xe9a8" )
+    ( "sequelize" . "\xea2f" )
+    ( "sf" . "\xe9db" )
+    ( "shen" . "\xe9a7" )
+    ( "shipit" . "\x26f5" )
+    ( "shippable" . "\xea2d" )
+    ( "shopify" . "\xe9cf" )
+    ( "shuriken" . "\x272b" )
+    ( "silverstripe" . "\xe800" )
+    ( "sinatra" . "\xea03" )
+    ( "sketch" . "\xe927" )
+    ( "sketchup-layout" . "\xea7c" )
+    ( "sketchup-make" . "\xea7e" )
+    ( "sketchup-stylebuilder" . "\xea7d" )
+    ( "slash" . "\xe9a6" )
+    ( "snyk" . "\xea1c" )
+    ( "solidity" . "\xea86" )
+    ( "sparql" . "\xe959" )
+    ( "spray" . "\xea02" )
+    ( "sqf" . "\xe9a5" )
+    ( "sqlite" . "\xe9dd" )
+    ( "squarespace" . "\xea5e" )
+    ( "stan" . "\xe9a4" )
+    ( "stata" . "\xe9a3" )
+    ( "storyist" . "\xe9ef" )
+    ( "strings" . "\xe9e0" )
+    ( "stylelint" . "\xe93d" )
+    ( "stylus" . "\x73" )
+    ( "stylus-full" . "\xe9f7" )
+    ( "stylus-orb" . "\x53" )
+    ( "sublime" . "\xe986" )
+    ( "sv" . "\xe9c3" )
+    ( "svn" . "\xea17" )
+    ( "swagger" . "\xea29" )
+    ( "tag" . "\xf015" )
+    ( "tcl" . "\xe956" )
+    ( "telegram" . "\x2708" )
+    ( "terminal" . "\xf0c8" )
+    ( "tern" . "\x1f54a" )
+    ( "terraform" . "\xe916" )
+    ( "test-coffeescript" . "\xea62" )
+    ( "test-dir" . "\xea60" )
+    ( "test-generic" . "\xea63" )
+    ( "test-js" . "\xea64" )
+    ( "test-perl" . "\xea65" )
+    ( "test-python" . "\xea66" )
+    ( "test-react" . "\xea67" )
+    ( "test-ruby" . "\xea68" )
+    ( "test-typescript" . "\xea69" )
+    ( "tex" . "\xe600" )
+    ( "textile" . "\x74" )
+    ( "textmate" . "\x2122" )
+    ( "thor" . "\xe9d8" )
+    ( "tinymce" . "\xea01" )
+    ( "tsx" . "\xe9d1" )
+    ( "tsx-alt" . "\xe9e7" )
+    ( "tt" . "\x54" )
+    ( "turing" . "\xe9b6" )
+    ( "twig" . "\x2e19" )
+    ( "twine" . "\xea5d" )
+    ( "txl" . "\xe9c1" )
+    ( "typedoc" . "\xe9fe" )
+    ( "typescript" . "\xe912" )
+    ( "typescript-alt" . "\x2a6" )
+    ( "typings" . "\xe9df" )
+    ( "uno" . "\xe9b3" )
+    ( "unreal" . "\x75" )
+    ( "urweb" . "\xe9ba" )
+    ( "v8" . "\xea1f" )
+    ( "vagrant" . "\x56" )
+    ( "vcl" . "\xe9b4" )
+    ( "verilog" . "\xe949" )
+    ( "vertex-shader" . "\xea79" )
+    ( "vhdl" . "\xe9aa" )
+    ( "video" . "\xf057" )
+    ( "virtualbox" . "\xea3e" )
+    ( "virtualbox-alt" . "\xea2e" )
+    ( "visio" . "\xea83" )
+    ( "vmware" . "\xea49" )
+    ( "vue" . "\xe906" )
+    ( "wasm" . "\xea70" )
+    ( "watchman" . "\xea4f" )
+    ( "webgl" . "\xea7b" )
+    ( "webpack" . "\xea61" )
+    ( "webpack-old" . "\xe91e" )
+    ( "wercker" . "\xea19" )
+    ( "word" . "\xe9ed" )
+    ( "x10" . "\x2169" )
+    ( "xamarin" . "\xea77" )
+    ( "xmos" . "\x58" )
+    ( "xpages" . "\xe9c5" )
+    ( "xtend" . "\xe9c6" )
+    ( "yarn" . "\xea1a" )
+    ( "yasm" . "\xea73" )
+    ( "yin-yang" . "\x262f" )
+    ( "yoyo" . "\xe975" )
+    ( "yui" . "\xea00" )
+    ( "zbrush" . "\xe9f2" )
+    ( "zephir" . "\xe9c7" )
+    ( "zimpl" . "\xe9c8" )
+    
+    )
+  )
+
+(provide 'data-fileicons)
diff --git a/configs/shared/emacs/.emacs.d/elpa/all-the-icons-20180125.757/data/data-fileicons.elc b/configs/shared/emacs/.emacs.d/elpa/all-the-icons-20180125.757/data/data-fileicons.elc
new file mode 100644
index 0000000000..358f49eeb7
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/all-the-icons-20180125.757/data/data-fileicons.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/all-the-icons-20180125.757/data/data-material.el b/configs/shared/emacs/.emacs.d/elpa/all-the-icons-20180125.757/data/data-material.el
new file mode 100644
index 0000000000..bafcfe7814
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/all-the-icons-20180125.757/data/data-material.el
@@ -0,0 +1,935 @@
+(defvar all-the-icons-data/material-icons-alist
+  '(("3d_rotation" . "\xe84d")
+    ("ac_unit" . "\xeb3b")
+    ("access_alarm" . "\xe190")
+    ("access_alarms" . "\xe191")
+    ("access_time" . "\xe192")
+    ("accessibility" . "\xe84e")
+    ("accessible" . "\xe914")
+    ("account_balance" . "\xe84f")
+    ("account_balance_wallet" . "\xe850")
+    ("account_box" . "\xe851")
+    ("account_circle" . "\xe853")
+    ("adb" . "\xe60e")
+    ("add" . "\xe145")
+    ("add_a_photo" . "\xe439")
+    ("add_alarm" . "\xe193")
+    ("add_alert" . "\xe003")
+    ("add_box" . "\xe146")
+    ("add_circle" . "\xe147")
+    ("add_circle_outline" . "\xe148")
+    ("add_location" . "\xe567")
+    ("add_shopping_cart" . "\xe854")
+    ("add_to_photos" . "\xe39d")
+    ("add_to_queue" . "\xe05c")
+    ("adjust" . "\xe39e")
+    ("airline_seat_flat" . "\xe630")
+    ("airline_seat_flat_angled" . "\xe631")
+    ("airline_seat_individual_suite" . "\xe632")
+    ("airline_seat_legroom_extra" . "\xe633")
+    ("airline_seat_legroom_normal" . "\xe634")
+    ("airline_seat_legroom_reduced" . "\xe635")
+    ("airline_seat_recline_extra" . "\xe636")
+    ("airline_seat_recline_normal" . "\xe637")
+    ("airplanemode_active" . "\xe195")
+    ("airplanemode_inactive" . "\xe194")
+    ("airplay" . "\xe055")
+    ("airport_shuttle" . "\xeb3c")
+    ("alarm" . "\xe855")
+    ("alarm_add" . "\xe856")
+    ("alarm_off" . "\xe857")
+    ("alarm_on" . "\xe858")
+    ("album" . "\xe019")
+    ("all_inclusive" . "\xeb3d")
+    ("all_out" . "\xe90b")
+    ("android" . "\xe859")
+    ("announcement" . "\xe85a")
+    ("apps" . "\xe5c3")
+    ("archive" . "\xe149")
+    ("arrow_back" . "\xe5c4")
+    ("arrow_downward" . "\xe5db")
+    ("arrow_drop_down" . "\xe5c5")
+    ("arrow_drop_down_circle" . "\xe5c6")
+    ("arrow_drop_up" . "\xe5c7")
+    ("arrow_forward" . "\xe5c8")
+    ("arrow_upward" . "\xe5d8")
+    ("art_track" . "\xe060")
+    ("aspect_ratio" . "\xe85b")
+    ("assessment" . "\xe85c")
+    ("assignment" . "\xe85d")
+    ("assignment_ind" . "\xe85e")
+    ("assignment_late" . "\xe85f")
+    ("assignment_return" . "\xe860")
+    ("assignment_returned" . "\xe861")
+    ("assignment_turned_in" . "\xe862")
+    ("assistant" . "\xe39f")
+    ("assistant_photo" . "\xe3a0")
+    ("attach_file" . "\xe226")
+    ("attach_money" . "\xe227")
+    ("attachment" . "\xe2bc")
+    ("audiotrack" . "\xe3a1")
+    ("autorenew" . "\xe863")
+    ("av_timer" . "\xe01b")
+    ("backspace" . "\xe14a")
+    ("backup" . "\xe864")
+    ("battery_alert" . "\xe19c")
+    ("battery_charging_full" . "\xe1a3")
+    ("battery_full" . "\xe1a4")
+    ("battery_std" . "\xe1a5")
+    ("battery_unknown" . "\xe1a6")
+    ("beach_access" . "\xeb3e")
+    ("beenhere" . "\xe52d")
+    ("block" . "\xe14b")
+    ("bluetooth" . "\xe1a7")
+    ("bluetooth_audio" . "\xe60f")
+    ("bluetooth_connected" . "\xe1a8")
+    ("bluetooth_disabled" . "\xe1a9")
+    ("bluetooth_searching" . "\xe1aa")
+    ("blur_circular" . "\xe3a2")
+    ("blur_linear" . "\xe3a3")
+    ("blur_off" . "\xe3a4")
+    ("blur_on" . "\xe3a5")
+    ("book" . "\xe865")
+    ("bookmark" . "\xe866")
+    ("bookmark_border" . "\xe867")
+    ("border_all" . "\xe228")
+    ("border_bottom" . "\xe229")
+    ("border_clear" . "\xe22a")
+    ("border_color" . "\xe22b")
+    ("border_horizontal" . "\xe22c")
+    ("border_inner" . "\xe22d")
+    ("border_left" . "\xe22e")
+    ("border_outer" . "\xe22f")
+    ("border_right" . "\xe230")
+    ("border_style" . "\xe231")
+    ("border_top" . "\xe232")
+    ("border_vertical" . "\xe233")
+    ("branding_watermark" . "\xe06b")
+    ("brightness_1" . "\xe3a6")
+    ("brightness_2" . "\xe3a7")
+    ("brightness_3" . "\xe3a8")
+    ("brightness_4" . "\xe3a9")
+    ("brightness_5" . "\xe3aa")
+    ("brightness_6" . "\xe3ab")
+    ("brightness_7" . "\xe3ac")
+    ("brightness_auto" . "\xe1ab")
+    ("brightness_high" . "\xe1ac")
+    ("brightness_low" . "\xe1ad")
+    ("brightness_medium" . "\xe1ae")
+    ("broken_image" . "\xe3ad")
+    ("brush" . "\xe3ae")
+    ("bubble_chart" . "\xe6dd")
+    ("bug_report" . "\xe868")
+    ("build" . "\xe869")
+    ("burst_mode" . "\xe43c")
+    ("business" . "\xe0af")
+    ("business_center" . "\xeb3f")
+    ("cached" . "\xe86a")
+    ("cake" . "\xe7e9")
+    ("call" . "\xe0b0")
+    ("call_end" . "\xe0b1")
+    ("call_made" . "\xe0b2")
+    ("call_merge" . "\xe0b3")
+    ("call_missed" . "\xe0b4")
+    ("call_missed_outgoing" . "\xe0e4")
+    ("call_received" . "\xe0b5")
+    ("call_split" . "\xe0b6")
+    ("call_to_action" . "\xe06c")
+    ("camera" . "\xe3af")
+    ("camera_alt" . "\xe3b0")
+    ("camera_enhance" . "\xe8fc")
+    ("camera_front" . "\xe3b1")
+    ("camera_rear" . "\xe3b2")
+    ("camera_roll" . "\xe3b3")
+    ("cancel" . "\xe5c9")
+    ("card_giftcard" . "\xe8f6")
+    ("card_membership" . "\xe8f7")
+    ("card_travel" . "\xe8f8")
+    ("casino" . "\xeb40")
+    ("cast" . "\xe307")
+    ("cast_connected" . "\xe308")
+    ("center_focus_strong" . "\xe3b4")
+    ("center_focus_weak" . "\xe3b5")
+    ("change_history" . "\xe86b")
+    ("chat" . "\xe0b7")
+    ("chat_bubble" . "\xe0ca")
+    ("chat_bubble_outline" . "\xe0cb")
+    ("check" . "\xe5ca")
+    ("check_box" . "\xe834")
+    ("check_box_outline_blank" . "\xe835")
+    ("check_circle" . "\xe86c")
+    ("chevron_left" . "\xe5cb")
+    ("chevron_right" . "\xe5cc")
+    ("child_care" . "\xeb41")
+    ("child_friendly" . "\xeb42")
+    ("chrome_reader_mode" . "\xe86d")
+    ("class" . "\xe86e")
+    ("clear" . "\xe14c")
+    ("clear_all" . "\xe0b8")
+    ("close" . "\xe5cd")
+    ("closed_caption" . "\xe01c")
+    ("cloud" . "\xe2bd")
+    ("cloud_circle" . "\xe2be")
+    ("cloud_done" . "\xe2bf")
+    ("cloud_download" . "\xe2c0")
+    ("cloud_off" . "\xe2c1")
+    ("cloud_queue" . "\xe2c2")
+    ("cloud_upload" . "\xe2c3")
+    ("code" . "\xe86f")
+    ("collections" . "\xe3b6")
+    ("collections_bookmark" . "\xe431")
+    ("color_lens" . "\xe3b7")
+    ("colorize" . "\xe3b8")
+    ("comment" . "\xe0b9")
+    ("compare" . "\xe3b9")
+    ("compare_arrows" . "\xe915")
+    ("computer" . "\xe30a")
+    ("confirmation_number" . "\xe638")
+    ("contact_mail" . "\xe0d0")
+    ("contact_phone" . "\xe0cf")
+    ("contacts" . "\xe0ba")
+    ("content_copy" . "\xe14d")
+    ("content_cut" . "\xe14e")
+    ("content_paste" . "\xe14f")
+    ("control_point" . "\xe3ba")
+    ("control_point_duplicate" . "\xe3bb")
+    ("copyright" . "\xe90c")
+    ("create" . "\xe150")
+    ("create_new_folder" . "\xe2cc")
+    ("credit_card" . "\xe870")
+    ("crop" . "\xe3be")
+    ("crop_16_9" . "\xe3bc")
+    ("crop_3_2" . "\xe3bd")
+    ("crop_5_4" . "\xe3bf")
+    ("crop_7_5" . "\xe3c0")
+    ("crop_din" . "\xe3c1")
+    ("crop_free" . "\xe3c2")
+    ("crop_landscape" . "\xe3c3")
+    ("crop_original" . "\xe3c4")
+    ("crop_portrait" . "\xe3c5")
+    ("crop_rotate" . "\xe437")
+    ("crop_square" . "\xe3c6")
+    ("dashboard" . "\xe871")
+    ("data_usage" . "\xe1af")
+    ("date_range" . "\xe916")
+    ("dehaze" . "\xe3c7")
+    ("delete" . "\xe872")
+    ("delete_forever" . "\xe92b")
+    ("delete_sweep" . "\xe16c")
+    ("description" . "\xe873")
+    ("desktop_mac" . "\xe30b")
+    ("desktop_windows" . "\xe30c")
+    ("details" . "\xe3c8")
+    ("developer_board" . "\xe30d")
+    ("developer_mode" . "\xe1b0")
+    ("device_hub" . "\xe335")
+    ("devices" . "\xe1b1")
+    ("devices_other" . "\xe337")
+    ("dialer_sip" . "\xe0bb")
+    ("dialpad" . "\xe0bc")
+    ("directions" . "\xe52e")
+    ("directions_bike" . "\xe52f")
+    ("directions_boat" . "\xe532")
+    ("directions_bus" . "\xe530")
+    ("directions_car" . "\xe531")
+    ("directions_railway" . "\xe534")
+    ("directions_run" . "\xe566")
+    ("directions_subway" . "\xe533")
+    ("directions_transit" . "\xe535")
+    ("directions_walk" . "\xe536")
+    ("disc_full" . "\xe610")
+    ("dns" . "\xe875")
+    ("do_not_disturb" . "\xe612")
+    ("do_not_disturb_alt" . "\xe611")
+    ("do_not_disturb_off" . "\xe643")
+    ("do_not_disturb_on" . "\xe644")
+    ("dock" . "\xe30e")
+    ("domain" . "\xe7ee")
+    ("done" . "\xe876")
+    ("done_all" . "\xe877")
+    ("donut_large" . "\xe917")
+    ("donut_small" . "\xe918")
+    ("drafts" . "\xe151")
+    ("drag_handle" . "\xe25d")
+    ("drive_eta" . "\xe613")
+    ("dvr" . "\xe1b2")
+    ("edit" . "\xe3c9")
+    ("edit_location" . "\xe568")
+    ("eject" . "\xe8fb")
+    ("email" . "\xe0be")
+    ("enhanced_encryption" . "\xe63f")
+    ("equalizer" . "\xe01d")
+    ("error" . "\xe000")
+    ("error_outline" . "\xe001")
+    ("euro_symbol" . "\xe926")
+    ("ev_station" . "\xe56d")
+    ("event" . "\xe878")
+    ("event_available" . "\xe614")
+    ("event_busy" . "\xe615")
+    ("event_note" . "\xe616")
+    ("event_seat" . "\xe903")
+    ("exit_to_app" . "\xe879")
+    ("expand_less" . "\xe5ce")
+    ("expand_more" . "\xe5cf")
+    ("explicit" . "\xe01e")
+    ("explore" . "\xe87a")
+    ("exposure" . "\xe3ca")
+    ("exposure_neg_1" . "\xe3cb")
+    ("exposure_neg_2" . "\xe3cc")
+    ("exposure_plus_1" . "\xe3cd")
+    ("exposure_plus_2" . "\xe3ce")
+    ("exposure_zero" . "\xe3cf")
+    ("extension" . "\xe87b")
+    ("face" . "\xe87c")
+    ("fast_forward" . "\xe01f")
+    ("fast_rewind" . "\xe020")
+    ("favorite" . "\xe87d")
+    ("favorite_border" . "\xe87e")
+    ("featured_play_list" . "\xe06d")
+    ("featured_video" . "\xe06e")
+    ("feedback" . "\xe87f")
+    ("fiber_dvr" . "\xe05d")
+    ("fiber_manual_record" . "\xe061")
+    ("fiber_new" . "\xe05e")
+    ("fiber_pin" . "\xe06a")
+    ("fiber_smart_record" . "\xe062")
+    ("file_download" . "\xe2c4")
+    ("file_upload" . "\xe2c6")
+    ("filter" . "\xe3d3")
+    ("filter_1" . "\xe3d0")
+    ("filter_2" . "\xe3d1")
+    ("filter_3" . "\xe3d2")
+    ("filter_4" . "\xe3d4")
+    ("filter_5" . "\xe3d5")
+    ("filter_6" . "\xe3d6")
+    ("filter_7" . "\xe3d7")
+    ("filter_8" . "\xe3d8")
+    ("filter_9" . "\xe3d9")
+    ("filter_9_plus" . "\xe3da")
+    ("filter_b_and_w" . "\xe3db")
+    ("filter_center_focus" . "\xe3dc")
+    ("filter_drama" . "\xe3dd")
+    ("filter_frames" . "\xe3de")
+    ("filter_hdr" . "\xe3df")
+    ("filter_list" . "\xe152")
+    ("filter_none" . "\xe3e0")
+    ("filter_tilt_shift" . "\xe3e2")
+    ("filter_vintage" . "\xe3e3")
+    ("find_in_page" . "\xe880")
+    ("find_replace" . "\xe881")
+    ("fingerprint" . "\xe90d")
+    ("first_page" . "\xe5dc")
+    ("fitness_center" . "\xeb43")
+    ("flag" . "\xe153")
+    ("flare" . "\xe3e4")
+    ("flash_auto" . "\xe3e5")
+    ("flash_off" . "\xe3e6")
+    ("flash_on" . "\xe3e7")
+    ("flight" . "\xe539")
+    ("flight_land" . "\xe904")
+    ("flight_takeoff" . "\xe905")
+    ("flip" . "\xe3e8")
+    ("flip_to_back" . "\xe882")
+    ("flip_to_front" . "\xe883")
+    ("folder" . "\xe2c7")
+    ("folder_open" . "\xe2c8")
+    ("folder_shared" . "\xe2c9")
+    ("folder_special" . "\xe617")
+    ("font_download" . "\xe167")
+    ("format_align_center" . "\xe234")
+    ("format_align_justify" . "\xe235")
+    ("format_align_left" . "\xe236")
+    ("format_align_right" . "\xe237")
+    ("format_bold" . "\xe238")
+    ("format_clear" . "\xe239")
+    ("format_color_fill" . "\xe23a")
+    ("format_color_reset" . "\xe23b")
+    ("format_color_text" . "\xe23c")
+    ("format_indent_decrease" . "\xe23d")
+    ("format_indent_increase" . "\xe23e")
+    ("format_italic" . "\xe23f")
+    ("format_line_spacing" . "\xe240")
+    ("format_list_bulleted" . "\xe241")
+    ("format_list_numbered" . "\xe242")
+    ("format_paint" . "\xe243")
+    ("format_quote" . "\xe244")
+    ("format_shapes" . "\xe25e")
+    ("format_size" . "\xe245")
+    ("format_strikethrough" . "\xe246")
+    ("format_textdirection_l_to_r" . "\xe247")
+    ("format_textdirection_r_to_l" . "\xe248")
+    ("format_underlined" . "\xe249")
+    ("forum" . "\xe0bf")
+    ("forward" . "\xe154")
+    ("forward_10" . "\xe056")
+    ("forward_30" . "\xe057")
+    ("forward_5" . "\xe058")
+    ("free_breakfast" . "\xeb44")
+    ("fullscreen" . "\xe5d0")
+    ("fullscreen_exit" . "\xe5d1")
+    ("functions" . "\xe24a")
+    ("g_translate" . "\xe927")
+    ("gamepad" . "\xe30f")
+    ("games" . "\xe021")
+    ("gavel" . "\xe90e")
+    ("gesture" . "\xe155")
+    ("get_app" . "\xe884")
+    ("gif" . "\xe908")
+    ("golf_course" . "\xeb45")
+    ("gps_fixed" . "\xe1b3")
+    ("gps_not_fixed" . "\xe1b4")
+    ("gps_off" . "\xe1b5")
+    ("grade" . "\xe885")
+    ("gradient" . "\xe3e9")
+    ("grain" . "\xe3ea")
+    ("graphic_eq" . "\xe1b8")
+    ("grid_off" . "\xe3eb")
+    ("grid_on" . "\xe3ec")
+    ("group" . "\xe7ef")
+    ("group_add" . "\xe7f0")
+    ("group_work" . "\xe886")
+    ("hd" . "\xe052")
+    ("hdr_off" . "\xe3ed")
+    ("hdr_on" . "\xe3ee")
+    ("hdr_strong" . "\xe3f1")
+    ("hdr_weak" . "\xe3f2")
+    ("headset" . "\xe310")
+    ("headset_mic" . "\xe311")
+    ("healing" . "\xe3f3")
+    ("hearing" . "\xe023")
+    ("help" . "\xe887")
+    ("help_outline" . "\xe8fd")
+    ("high_quality" . "\xe024")
+    ("highlight" . "\xe25f")
+    ("highlight_off" . "\xe888")
+    ("history" . "\xe889")
+    ("home" . "\xe88a")
+    ("hot_tub" . "\xeb46")
+    ("hotel" . "\xe53a")
+    ("hourglass_empty" . "\xe88b")
+    ("hourglass_full" . "\xe88c")
+    ("http" . "\xe902")
+    ("https" . "\xe88d")
+    ("image" . "\xe3f4")
+    ("image_aspect_ratio" . "\xe3f5")
+    ("import_contacts" . "\xe0e0")
+    ("import_export" . "\xe0c3")
+    ("important_devices" . "\xe912")
+    ("inbox" . "\xe156")
+    ("indeterminate_check_box" . "\xe909")
+    ("info" . "\xe88e")
+    ("info_outline" . "\xe88f")
+    ("input" . "\xe890")
+    ("insert_chart" . "\xe24b")
+    ("insert_comment" . "\xe24c")
+    ("insert_drive_file" . "\xe24d")
+    ("insert_emoticon" . "\xe24e")
+    ("insert_invitation" . "\xe24f")
+    ("insert_link" . "\xe250")
+    ("insert_photo" . "\xe251")
+    ("invert_colors" . "\xe891")
+    ("invert_colors_off" . "\xe0c4")
+    ("iso" . "\xe3f6")
+    ("keyboard" . "\xe312")
+    ("keyboard_arrow_down" . "\xe313")
+    ("keyboard_arrow_left" . "\xe314")
+    ("keyboard_arrow_right" . "\xe315")
+    ("keyboard_arrow_up" . "\xe316")
+    ("keyboard_backspace" . "\xe317")
+    ("keyboard_capslock" . "\xe318")
+    ("keyboard_hide" . "\xe31a")
+    ("keyboard_return" . "\xe31b")
+    ("keyboard_tab" . "\xe31c")
+    ("keyboard_voice" . "\xe31d")
+    ("kitchen" . "\xeb47")
+    ("label" . "\xe892")
+    ("label_outline" . "\xe893")
+    ("landscape" . "\xe3f7")
+    ("language" . "\xe894")
+    ("laptop" . "\xe31e")
+    ("laptop_chromebook" . "\xe31f")
+    ("laptop_mac" . "\xe320")
+    ("laptop_windows" . "\xe321")
+    ("last_page" . "\xe5dd")
+    ("launch" . "\xe895")
+    ("layers" . "\xe53b")
+    ("layers_clear" . "\xe53c")
+    ("leak_add" . "\xe3f8")
+    ("leak_remove" . "\xe3f9")
+    ("lens" . "\xe3fa")
+    ("library_add" . "\xe02e")
+    ("library_books" . "\xe02f")
+    ("library_music" . "\xe030")
+    ("lightbulb_outline" . "\xe90f")
+    ("line_style" . "\xe919")
+    ("line_weight" . "\xe91a")
+    ("linear_scale" . "\xe260")
+    ("link" . "\xe157")
+    ("linked_camera" . "\xe438")
+    ("list" . "\xe896")
+    ("live_help" . "\xe0c6")
+    ("live_tv" . "\xe639")
+    ("local_activity" . "\xe53f")
+    ("local_airport" . "\xe53d")
+    ("local_atm" . "\xe53e")
+    ("local_bar" . "\xe540")
+    ("local_cafe" . "\xe541")
+    ("local_car_wash" . "\xe542")
+    ("local_convenience_store" . "\xe543")
+    ("local_dining" . "\xe556")
+    ("local_drink" . "\xe544")
+    ("local_florist" . "\xe545")
+    ("local_gas_station" . "\xe546")
+    ("local_grocery_store" . "\xe547")
+    ("local_hospital" . "\xe548")
+    ("local_hotel" . "\xe549")
+    ("local_laundry_service" . "\xe54a")
+    ("local_library" . "\xe54b")
+    ("local_mall" . "\xe54c")
+    ("local_movies" . "\xe54d")
+    ("local_offer" . "\xe54e")
+    ("local_parking" . "\xe54f")
+    ("local_pharmacy" . "\xe550")
+    ("local_phone" . "\xe551")
+    ("local_pizza" . "\xe552")
+    ("local_play" . "\xe553")
+    ("local_post_office" . "\xe554")
+    ("local_printshop" . "\xe555")
+    ("local_see" . "\xe557")
+    ("local_shipping" . "\xe558")
+    ("local_taxi" . "\xe559")
+    ("location_city" . "\xe7f1")
+    ("location_disabled" . "\xe1b6")
+    ("location_off" . "\xe0c7")
+    ("location_on" . "\xe0c8")
+    ("location_searching" . "\xe1b7")
+    ("lock" . "\xe897")
+    ("lock_open" . "\xe898")
+    ("lock_outline" . "\xe899")
+    ("looks" . "\xe3fc")
+    ("looks_3" . "\xe3fb")
+    ("looks_4" . "\xe3fd")
+    ("looks_5" . "\xe3fe")
+    ("looks_6" . "\xe3ff")
+    ("looks_one" . "\xe400")
+    ("looks_two" . "\xe401")
+    ("loop" . "\xe028")
+    ("loupe" . "\xe402")
+    ("low_priority" . "\xe16d")
+    ("loyalty" . "\xe89a")
+    ("mail" . "\xe158")
+    ("mail_outline" . "\xe0e1")
+    ("map" . "\xe55b")
+    ("markunread" . "\xe159")
+    ("markunread_mailbox" . "\xe89b")
+    ("memory" . "\xe322")
+    ("menu" . "\xe5d2")
+    ("merge_type" . "\xe252")
+    ("message" . "\xe0c9")
+    ("mic" . "\xe029")
+    ("mic_none" . "\xe02a")
+    ("mic_off" . "\xe02b")
+    ("mms" . "\xe618")
+    ("mode_comment" . "\xe253")
+    ("mode_edit" . "\xe254")
+    ("monetization_on" . "\xe263")
+    ("money_off" . "\xe25c")
+    ("monochrome_photos" . "\xe403")
+    ("mood" . "\xe7f2")
+    ("mood_bad" . "\xe7f3")
+    ("more" . "\xe619")
+    ("more_horiz" . "\xe5d3")
+    ("more_vert" . "\xe5d4")
+    ("motorcycle" . "\xe91b")
+    ("mouse" . "\xe323")
+    ("move_to_inbox" . "\xe168")
+    ("movie" . "\xe02c")
+    ("movie_creation" . "\xe404")
+    ("movie_filter" . "\xe43a")
+    ("multiline_chart" . "\xe6df")
+    ("music_note" . "\xe405")
+    ("music_video" . "\xe063")
+    ("my_location" . "\xe55c")
+    ("nature" . "\xe406")
+    ("nature_people" . "\xe407")
+    ("navigate_before" . "\xe408")
+    ("navigate_next" . "\xe409")
+    ("navigation" . "\xe55d")
+    ("near_me" . "\xe569")
+    ("network_cell" . "\xe1b9")
+    ("network_check" . "\xe640")
+    ("network_locked" . "\xe61a")
+    ("network_wifi" . "\xe1ba")
+    ("new_releases" . "\xe031")
+    ("next_week" . "\xe16a")
+    ("nfc" . "\xe1bb")
+    ("no_encryption" . "\xe641")
+    ("no_sim" . "\xe0cc")
+    ("not_interested" . "\xe033")
+    ("note" . "\xe06f")
+    ("note_add" . "\xe89c")
+    ("notifications" . "\xe7f4")
+    ("notifications_active" . "\xe7f7")
+    ("notifications_none" . "\xe7f5")
+    ("notifications_off" . "\xe7f6")
+    ("notifications_paused" . "\xe7f8")
+    ("offline_pin" . "\xe90a")
+    ("ondemand_video" . "\xe63a")
+    ("opacity" . "\xe91c")
+    ("open_in_browser" . "\xe89d")
+    ("open_in_new" . "\xe89e")
+    ("open_with" . "\xe89f")
+    ("pages" . "\xe7f9")
+    ("pageview" . "\xe8a0")
+    ("palette" . "\xe40a")
+    ("pan_tool" . "\xe925")
+    ("panorama" . "\xe40b")
+    ("panorama_fish_eye" . "\xe40c")
+    ("panorama_horizontal" . "\xe40d")
+    ("panorama_vertical" . "\xe40e")
+    ("panorama_wide_angle" . "\xe40f")
+    ("party_mode" . "\xe7fa")
+    ("pause" . "\xe034")
+    ("pause_circle_filled" . "\xe035")
+    ("pause_circle_outline" . "\xe036")
+    ("payment" . "\xe8a1")
+    ("people" . "\xe7fb")
+    ("people_outline" . "\xe7fc")
+    ("perm_camera_mic" . "\xe8a2")
+    ("perm_contact_calendar" . "\xe8a3")
+    ("perm_data_setting" . "\xe8a4")
+    ("perm_device_information" . "\xe8a5")
+    ("perm_identity" . "\xe8a6")
+    ("perm_media" . "\xe8a7")
+    ("perm_phone_msg" . "\xe8a8")
+    ("perm_scan_wifi" . "\xe8a9")
+    ("person" . "\xe7fd")
+    ("person_add" . "\xe7fe")
+    ("person_outline" . "\xe7ff")
+    ("person_pin" . "\xe55a")
+    ("person_pin_circle" . "\xe56a")
+    ("personal_video" . "\xe63b")
+    ("pets" . "\xe91d")
+    ("phone" . "\xe0cd")
+    ("phone_android" . "\xe324")
+    ("phone_bluetooth_speaker" . "\xe61b")
+    ("phone_forwarded" . "\xe61c")
+    ("phone_in_talk" . "\xe61d")
+    ("phone_iphone" . "\xe325")
+    ("phone_locked" . "\xe61e")
+    ("phone_missed" . "\xe61f")
+    ("phone_paused" . "\xe620")
+    ("phonelink" . "\xe326")
+    ("phonelink_erase" . "\xe0db")
+    ("phonelink_lock" . "\xe0dc")
+    ("phonelink_off" . "\xe327")
+    ("phonelink_ring" . "\xe0dd")
+    ("phonelink_setup" . "\xe0de")
+    ("photo" . "\xe410")
+    ("photo_album" . "\xe411")
+    ("photo_camera" . "\xe412")
+    ("photo_filter" . "\xe43b")
+    ("photo_library" . "\xe413")
+    ("photo_size_select_actual" . "\xe432")
+    ("photo_size_select_large" . "\xe433")
+    ("photo_size_select_small" . "\xe434")
+    ("picture_as_pdf" . "\xe415")
+    ("picture_in_picture" . "\xe8aa")
+    ("picture_in_picture_alt" . "\xe911")
+    ("pie_chart" . "\xe6c4")
+    ("pie_chart_outlined" . "\xe6c5")
+    ("pin_drop" . "\xe55e")
+    ("place" . "\xe55f")
+    ("play_arrow" . "\xe037")
+    ("play_circle_filled" . "\xe038")
+    ("play_circle_outline" . "\xe039")
+    ("play_for_work" . "\xe906")
+    ("playlist_add" . "\xe03b")
+    ("playlist_add_check" . "\xe065")
+    ("playlist_play" . "\xe05f")
+    ("plus_one" . "\xe800")
+    ("poll" . "\xe801")
+    ("polymer" . "\xe8ab")
+    ("pool" . "\xeb48")
+    ("portable_wifi_off" . "\xe0ce")
+    ("portrait" . "\xe416")
+    ("power" . "\xe63c")
+    ("power_input" . "\xe336")
+    ("power_settings_new" . "\xe8ac")
+    ("pregnant_woman" . "\xe91e")
+    ("present_to_all" . "\xe0df")
+    ("print" . "\xe8ad")
+    ("priority_high" . "\xe645")
+    ("public" . "\xe80b")
+    ("publish" . "\xe255")
+    ("query_builder" . "\xe8ae")
+    ("question_answer" . "\xe8af")
+    ("queue" . "\xe03c")
+    ("queue_music" . "\xe03d")
+    ("queue_play_next" . "\xe066")
+    ("radio" . "\xe03e")
+    ("radio_button_checked" . "\xe837")
+    ("radio_button_unchecked" . "\xe836")
+    ("rate_review" . "\xe560")
+    ("receipt" . "\xe8b0")
+    ("recent_actors" . "\xe03f")
+    ("record_voice_over" . "\xe91f")
+    ("redeem" . "\xe8b1")
+    ("redo" . "\xe15a")
+    ("refresh" . "\xe5d5")
+    ("remove" . "\xe15b")
+    ("remove_circle" . "\xe15c")
+    ("remove_circle_outline" . "\xe15d")
+    ("remove_from_queue" . "\xe067")
+    ("remove_red_eye" . "\xe417")
+    ("remove_shopping_cart" . "\xe928")
+    ("reorder" . "\xe8fe")
+    ("repeat" . "\xe040")
+    ("repeat_one" . "\xe041")
+    ("replay" . "\xe042")
+    ("replay_10" . "\xe059")
+    ("replay_30" . "\xe05a")
+    ("replay_5" . "\xe05b")
+    ("reply" . "\xe15e")
+    ("reply_all" . "\xe15f")
+    ("report" . "\xe160")
+    ("report_problem" . "\xe8b2")
+    ("restaurant" . "\xe56c")
+    ("restaurant_menu" . "\xe561")
+    ("restore" . "\xe8b3")
+    ("restore_page" . "\xe929")
+    ("ring_volume" . "\xe0d1")
+    ("room" . "\xe8b4")
+    ("room_service" . "\xeb49")
+    ("rotate_90_degrees_ccw" . "\xe418")
+    ("rotate_left" . "\xe419")
+    ("rotate_right" . "\xe41a")
+    ("rounded_corner" . "\xe920")
+    ("router" . "\xe328")
+    ("rowing" . "\xe921")
+    ("rss_feed" . "\xe0e5")
+    ("rv_hookup" . "\xe642")
+    ("satellite" . "\xe562")
+    ("save" . "\xe161")
+    ("scanner" . "\xe329")
+    ("schedule" . "\xe8b5")
+    ("school" . "\xe80c")
+    ("screen_lock_landscape" . "\xe1be")
+    ("screen_lock_portrait" . "\xe1bf")
+    ("screen_lock_rotation" . "\xe1c0")
+    ("screen_rotation" . "\xe1c1")
+    ("screen_share" . "\xe0e2")
+    ("sd_card" . "\xe623")
+    ("sd_storage" . "\xe1c2")
+    ("search" . "\xe8b6")
+    ("security" . "\xe32a")
+    ("select_all" . "\xe162")
+    ("send" . "\xe163")
+    ("sentiment_dissatisfied" . "\xe811")
+    ("sentiment_neutral" . "\xe812")
+    ("sentiment_satisfied" . "\xe813")
+    ("sentiment_very_dissatisfied" . "\xe814")
+    ("sentiment_very_satisfied" . "\xe815")
+    ("settings" . "\xe8b8")
+    ("settings_applications" . "\xe8b9")
+    ("settings_backup_restore" . "\xe8ba")
+    ("settings_bluetooth" . "\xe8bb")
+    ("settings_brightness" . "\xe8bd")
+    ("settings_cell" . "\xe8bc")
+    ("settings_ethernet" . "\xe8be")
+    ("settings_input_antenna" . "\xe8bf")
+    ("settings_input_component" . "\xe8c0")
+    ("settings_input_composite" . "\xe8c1")
+    ("settings_input_hdmi" . "\xe8c2")
+    ("settings_input_svideo" . "\xe8c3")
+    ("settings_overscan" . "\xe8c4")
+    ("settings_phone" . "\xe8c5")
+    ("settings_power" . "\xe8c6")
+    ("settings_remote" . "\xe8c7")
+    ("settings_system_daydream" . "\xe1c3")
+    ("settings_voice" . "\xe8c8")
+    ("share" . "\xe80d")
+    ("shop" . "\xe8c9")
+    ("shop_two" . "\xe8ca")
+    ("shopping_basket" . "\xe8cb")
+    ("shopping_cart" . "\xe8cc")
+    ("short_text" . "\xe261")
+    ("show_chart" . "\xe6e1")
+    ("shuffle" . "\xe043")
+    ("signal_cellular_4_bar" . "\xe1c8")
+    ("signal_cellular_connected_no_internet_4_bar" . "\xe1cd")
+    ("signal_cellular_no_sim" . "\xe1ce")
+    ("signal_cellular_null" . "\xe1cf")
+    ("signal_cellular_off" . "\xe1d0")
+    ("signal_wifi_4_bar" . "\xe1d8")
+    ("signal_wifi_4_bar_lock" . "\xe1d9")
+    ("signal_wifi_off" . "\xe1da")
+    ("sim_card" . "\xe32b")
+    ("sim_card_alert" . "\xe624")
+    ("skip_next" . "\xe044")
+    ("skip_previous" . "\xe045")
+    ("slideshow" . "\xe41b")
+    ("slow_motion_video" . "\xe068")
+    ("smartphone" . "\xe32c")
+    ("smoke_free" . "\xeb4a")
+    ("smoking_rooms" . "\xeb4b")
+    ("sms" . "\xe625")
+    ("sms_failed" . "\xe626")
+    ("snooze" . "\xe046")
+    ("sort" . "\xe164")
+    ("sort_by_alpha" . "\xe053")
+    ("spa" . "\xeb4c")
+    ("space_bar" . "\xe256")
+    ("speaker" . "\xe32d")
+    ("speaker_group" . "\xe32e")
+    ("speaker_notes" . "\xe8cd")
+    ("speaker_notes_off" . "\xe92a")
+    ("speaker_phone" . "\xe0d2")
+    ("spellcheck" . "\xe8ce")
+    ("star" . "\xe838")
+    ("star_border" . "\xe83a")
+    ("star_half" . "\xe839")
+    ("stars" . "\xe8d0")
+    ("stay_current_landscape" . "\xe0d3")
+    ("stay_current_portrait" . "\xe0d4")
+    ("stay_primary_landscape" . "\xe0d5")
+    ("stay_primary_portrait" . "\xe0d6")
+    ("stop" . "\xe047")
+    ("stop_screen_share" . "\xe0e3")
+    ("storage" . "\xe1db")
+    ("store" . "\xe8d1")
+    ("store_mall_directory" . "\xe563")
+    ("straighten" . "\xe41c")
+    ("streetview" . "\xe56e")
+    ("strikethrough_s" . "\xe257")
+    ("style" . "\xe41d")
+    ("subdirectory_arrow_left" . "\xe5d9")
+    ("subdirectory_arrow_right" . "\xe5da")
+    ("subject" . "\xe8d2")
+    ("subscriptions" . "\xe064")
+    ("subtitles" . "\xe048")
+    ("subway" . "\xe56f")
+    ("supervisor_account" . "\xe8d3")
+    ("surround_sound" . "\xe049")
+    ("swap_calls" . "\xe0d7")
+    ("swap_horiz" . "\xe8d4")
+    ("swap_vert" . "\xe8d5")
+    ("swap_vertical_circle" . "\xe8d6")
+    ("switch_camera" . "\xe41e")
+    ("switch_video" . "\xe41f")
+    ("sync" . "\xe627")
+    ("sync_disabled" . "\xe628")
+    ("sync_problem" . "\xe629")
+    ("system_update" . "\xe62a")
+    ("system_update_alt" . "\xe8d7")
+    ("tab" . "\xe8d8")
+    ("tab_unselected" . "\xe8d9")
+    ("tablet" . "\xe32f")
+    ("tablet_android" . "\xe330")
+    ("tablet_mac" . "\xe331")
+    ("tag_faces" . "\xe420")
+    ("tap_and_play" . "\xe62b")
+    ("terrain" . "\xe564")
+    ("text_fields" . "\xe262")
+    ("text_format" . "\xe165")
+    ("textsms" . "\xe0d8")
+    ("texture" . "\xe421")
+    ("theaters" . "\xe8da")
+    ("thumb_down" . "\xe8db")
+    ("thumb_up" . "\xe8dc")
+    ("thumbs_up_down" . "\xe8dd")
+    ("time_to_leave" . "\xe62c")
+    ("timelapse" . "\xe422")
+    ("timeline" . "\xe922")
+    ("timer" . "\xe425")
+    ("timer_10" . "\xe423")
+    ("timer_3" . "\xe424")
+    ("timer_off" . "\xe426")
+    ("title" . "\xe264")
+    ("toc" . "\xe8de")
+    ("today" . "\xe8df")
+    ("toll" . "\xe8e0")
+    ("tonality" . "\xe427")
+    ("touch_app" . "\xe913")
+    ("toys" . "\xe332")
+    ("track_changes" . "\xe8e1")
+    ("traffic" . "\xe565")
+    ("train" . "\xe570")
+    ("tram" . "\xe571")
+    ("transfer_within_a_station" . "\xe572")
+    ("transform" . "\xe428")
+    ("translate" . "\xe8e2")
+    ("trending_down" . "\xe8e3")
+    ("trending_flat" . "\xe8e4")
+    ("trending_up" . "\xe8e5")
+    ("tune" . "\xe429")
+    ("turned_in" . "\xe8e6")
+    ("turned_in_not" . "\xe8e7")
+    ("tv" . "\xe333")
+    ("unarchive" . "\xe169")
+    ("undo" . "\xe166")
+    ("unfold_less" . "\xe5d6")
+    ("unfold_more" . "\xe5d7")
+    ("update" . "\xe923")
+    ("usb" . "\xe1e0")
+    ("verified_user" . "\xe8e8")
+    ("vertical_align_bottom" . "\xe258")
+    ("vertical_align_center" . "\xe259")
+    ("vertical_align_top" . "\xe25a")
+    ("vibration" . "\xe62d")
+    ("video_call" . "\xe070")
+    ("video_label" . "\xe071")
+    ("video_library" . "\xe04a")
+    ("videocam" . "\xe04b")
+    ("videocam_off" . "\xe04c")
+    ("videogame_asset" . "\xe338")
+    ("view_agenda" . "\xe8e9")
+    ("view_array" . "\xe8ea")
+    ("view_carousel" . "\xe8eb")
+    ("view_column" . "\xe8ec")
+    ("view_comfy" . "\xe42a")
+    ("view_compact" . "\xe42b")
+    ("view_day" . "\xe8ed")
+    ("view_headline" . "\xe8ee")
+    ("view_list" . "\xe8ef")
+    ("view_module" . "\xe8f0")
+    ("view_quilt" . "\xe8f1")
+    ("view_stream" . "\xe8f2")
+    ("view_week" . "\xe8f3")
+    ("vignette" . "\xe435")
+    ("visibility" . "\xe8f4")
+    ("visibility_off" . "\xe8f5")
+    ("voice_chat" . "\xe62e")
+    ("voicemail" . "\xe0d9")
+    ("volume_down" . "\xe04d")
+    ("volume_mute" . "\xe04e")
+    ("volume_off" . "\xe04f")
+    ("volume_up" . "\xe050")
+    ("vpn_key" . "\xe0da")
+    ("vpn_lock" . "\xe62f")
+    ("wallpaper" . "\xe1bc")
+    ("warning" . "\xe002")
+    ("watch" . "\xe334")
+    ("watch_later" . "\xe924")
+    ("wb_auto" . "\xe42c")
+    ("wb_cloudy" . "\xe42d")
+    ("wb_incandescent" . "\xe42e")
+    ("wb_iridescent" . "\xe436")
+    ("wb_sunny" . "\xe430")
+    ("wc" . "\xe63d")
+    ("web" . "\xe051")
+    ("web_asset" . "\xe069")
+    ("weekend" . "\xe16b")
+    ("whatshot" . "\xe80e")
+    ("widgets" . "\xe1bd")
+    ("wifi" . "\xe63e")
+    ("wifi_lock" . "\xe1e1")
+    ("wifi_tethering" . "\xe1e2")
+    ("work" . "\xe8f9")
+    ("wrap_text" . "\xe25b")
+    ("youtube_searched_for" . "\xe8fa")
+    ("zoom_in" . "\xe8ff")
+    ("zoom_out" . "\xe900")
+    ("zoom_out_map" . "\xe56b")))
+
+  (provide 'data-material)
diff --git a/configs/shared/emacs/.emacs.d/elpa/all-the-icons-20180125.757/data/data-material.elc b/configs/shared/emacs/.emacs.d/elpa/all-the-icons-20180125.757/data/data-material.elc
new file mode 100644
index 0000000000..349f534209
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/all-the-icons-20180125.757/data/data-material.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/all-the-icons-20180125.757/data/data-octicons.el b/configs/shared/emacs/.emacs.d/elpa/all-the-icons-20180125.757/data/data-octicons.el
new file mode 100644
index 0000000000..432251ed18
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/all-the-icons-20180125.757/data/data-octicons.el
@@ -0,0 +1,165 @@
+(defvar all-the-icons-data/octicons-alist
+  '(
+
+    ("alert" . "\xf02d")
+    ("arrow-down" . "\xf03f")
+    ("arrow-left" . "\xf040")
+    ("arrow-right" . "\xf03e")
+    ("arrow-small-down" . "\xf0a0")
+    ("arrow-small-left" . "\xf0a1")
+    ("arrow-small-right" . "\xf071")
+    ("arrow-small-up" . "\xf09f")
+    ("arrow-up" . "\xf03d")
+    ("book" . "\xf007")
+    ("bookmark" . "\xf07b")
+    ("briefcase" . "\xf0d3")
+    ("broadcast" . "\xf048")
+    ("browser" . "\xf0c5")
+    ("bug" . "\xf091")
+    ("calendar" . "\xf068")
+    ("check" . "\xf03a")
+    ("checklist" . "\xf076")
+    ("chevron-down" . "\xf0a3")
+    ("chevron-left" . "\xf0a4")
+    ("chevron-right" . "\xf078")
+    ("chevron-up" . "\xf0a2")
+    ("circle-slash" . "\xf084")
+    ("circuit-board" . "\xf0d6")
+    ("clippy" . "\xf035")
+    ("clock" . "\xf046")
+    ("cloud-download" . "\xf00b")
+    ("cloud-upload" . "\xf00c")
+    ("code" . "\xf05f")
+    ("comment" . "\xf02b")
+    ("comment-discussion" . "\xf04f")
+    ("credit-card" . "\xf045")
+    ("dash" . "\xf0ca")
+    ("dashboard" . "\xf07d")
+    ("database" . "\xf096")
+    ("device-camera" . "\xf056")
+    ("device-camera-video" . "\xf057")
+    ("device-desktop" . "\xf27c")
+    ("device-mobile" . "\xf038")
+    ("diff" . "\xf04d")
+    ("diff-added" . "\xf06b")
+    ("diff-ignored" . "\xf099")
+    ("diff-modified" . "\xf06d")
+    ("diff-removed" . "\xf06c")
+    ("diff-renamed" . "\xf06e")
+    ("ellipsis" . "\xf09a")
+    ("eye" . "\xf04e")
+    ("file-binary" . "\xf094")
+    ("file-code" . "\xf010")
+    ("file-directory" . "\xf016")
+    ("file-media" . "\xf012")
+    ("file-pdf" . "\xf014")
+    ("file-submodule" . "\xf017")
+    ("file-symlink-directory" . "\xf0b1")
+    ("file-symlink-file" . "\xf0b0")
+    ("file-text" . "\xf011")
+    ("file-zip" . "\xf013")
+    ("flame" . "\xf0d2")
+    ("fold" . "\xf0cc")
+    ("gear" . "\xf02f")
+    ("gift" . "\xf042")
+    ("gist" . "\xf00e")
+    ("gist-secret" . "\xf08c")
+    ("git-branch" . "\xf020")
+    ("git-commit" . "\xf01f")
+    ("git-compare" . "\xf0ac")
+    ("git-merge" . "\xf023")
+    ("git-pull-request" . "\xf009")
+    ("globe" . "\xf0b6")
+    ("graph" . "\xf043")
+    ("beaker" . "\xf0dd")
+    ("heart" . "\x2665")
+    ("history" . "\xf07e")
+    ("home" . "\xf08d")
+    ("horizontal-rule" . "\xf070")
+    ("hourglass" . "\xf09e")
+    ("hubot" . "\xf09d")
+    ("inbox" . "\xf0cf")
+    ("info" . "\xf059")
+    ("issue-closed" . "\xf028")
+    ("issue-opened" . "\xf026")
+    ("issue-reopened" . "\xf027")
+    ("jersey" . "\xf019")
+    ("key" . "\xf049")
+    ("keyboard" . "\xf00d")
+    ("law" . "\xf0d8")
+    ("light-bulb" . "\xf000")
+    ("link" . "\xf05c")
+    ("link-external" . "\xf07f")
+    ("list-ordered" . "\xf062")
+    ("list-unordered" . "\xf061")
+    ("location" . "\xf060")
+    ("lock" . "\xf06a")
+    ("logo-github" . "\xf092")
+    ("mail" . "\xf03b")
+    ("mail-read" . "\xf03c")
+    ("mail-reply" . "\xf051")
+    ("mark-github" . "\xf00a")
+    ("markdown" . "\xf0c9")
+    ("megaphone" . "\xf077")
+    ("mention" . "\xf0be")
+    ("milestone" . "\xf075")
+    ("mirror" . "\xf024")
+    ("mortar-board" . "\xf0d7")
+    ("mute" . "\xf080")
+    ("no-newline" . "\xf09c")
+    ("octoface" . "\xf008")
+    ("organization" . "\xf037")
+    ("package" . "\xf0c4")
+    ("paintcan" . "\xf0d1")
+    ("pencil" . "\xf058")
+    ("person" . "\xf018")
+    ("pin" . "\xf041")
+    ("plug" . "\xf0d4")
+    ("plus" . "\xf05d")
+    ("primitive-dot" . "\xf052")
+    ("primitive-square" . "\xf053")
+    ("pulse" . "\xf085")
+    ("puzzle" . "\xf0c0")
+    ("question" . "\xf02c")
+    ("quote" . "\xf063")
+    ("radio-tower" . "\xf030")
+    ("repo" . "\xf001")
+    ("repo-clone" . "\xf04c")
+    ("repo-force-push" . "\xf04a")
+    ("repo-forked" . "\xf002")
+    ("repo-pull" . "\xf006")
+    ("repo-push" . "\xf005")
+    ("rocket" . "\xf033")
+    ("rss" . "\xf034")
+    ("ruby" . "\xf047")
+    ("search" . "\xf02e")
+    ("server" . "\xf097")
+    ("settings" . "\xf07c")
+    ("sign-in" . "\xf036")
+    ("sign-out" . "\xf032")
+    ("squirrel" . "\xf0b2")
+    ("star" . "\xf02a")
+    ("steps" . "\xf0c7")
+    ("stop" . "\xf08f")
+    ("sync" . "\xf087")
+    ("tag" . "\xf015")
+    ("telescope" . "\xf088")
+    ("terminal" . "\xf0c8")
+    ("three-bars" . "\xf05e")
+    ("thumbsdown" . "\xf0db")
+    ("thumbsup" . "\xf0da")
+    ("tools" . "\xf031")
+    ("trashcan" . "\xf0d0")
+    ("triangle-down" . "\xf05b")
+    ("triangle-left" . "\xf044")
+    ("triangle-right" . "\xf05a")
+    ("triangle-up" . "\xf0aa")
+    ("unfold" . "\xf039")
+    ("unmute" . "\xf0ba")
+    ("versions" . "\xf064")
+    ("x" . "\xf081")
+    ("zap" . "\x26A1")
+
+    ))
+
+(provide 'data-octicons)
diff --git a/configs/shared/emacs/.emacs.d/elpa/all-the-icons-20180125.757/data/data-octicons.elc b/configs/shared/emacs/.emacs.d/elpa/all-the-icons-20180125.757/data/data-octicons.elc
new file mode 100644
index 0000000000..b1de2b1c4f
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/all-the-icons-20180125.757/data/data-octicons.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/all-the-icons-20180125.757/data/data-weathericons.el b/configs/shared/emacs/.emacs.d/elpa/all-the-icons-20180125.757/data/data-weathericons.el
new file mode 100644
index 0000000000..676581c3c8
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/all-the-icons-20180125.757/data/data-weathericons.el
@@ -0,0 +1,594 @@
+(defvar all-the-icons-data/weather-icons-alist
+  '(
+
+    ("alien"                           . "\xf075")
+    ("barometer"                       . "\xf079")
+    ("celsius"                         . "\xf03c")
+    ("cloud"                           . "\xf041")
+    ("cloud-down"                      . "\xf03d")
+    ("cloud-refresh"                   . "\xf03e")
+    ("cloud-up"                        . "\xf040")
+    ("cloudy"                          . "\xf013")
+    ("cloudy-gusts"                    . "\xf011")
+    ("cloudy-windy"                    . "\xf012")
+    ("day-cloudy"                      . "\xf002")
+    ("day-cloudy-gusts"                . "\xf000")
+    ("day-cloudy-high"                 . "\xf07d")
+    ("day-cloudy-windy"                . "\xf001")
+    ("day-fog"                         . "\xf003")
+    ("day-hail"                        . "\xf004")
+    ("day-haze"                        . "\xf0b6")
+    ("day-light-wind"                  . "\xf0c4")
+    ("day-lightning"                   . "\xf005")
+    ("day-rain"                        . "\xf008")
+    ("day-rain-mix"                    . "\xf006")
+    ("day-rain-wind"                   . "\xf007")
+    ("day-showers"                     . "\xf009")
+    ("day-sleet"                       . "\xf0b2")
+    ("day-sleet-storm"                 . "\xf068")
+    ("day-snow"                        . "\xf00a")
+    ("day-snow-thunderstorm"           . "\xf06b")
+    ("day-snow-wind"                   . "\xf065")
+    ("day-sprinkle"                    . "\xf00b")
+    ("day-storm-showers"               . "\xf00e")
+    ("day-sunny"                       . "\xf00d")
+    ("day-sunny-overcast"              . "\xf00c")
+    ("day-thunderstorm"                . "\xf010")
+    ("day-windy"                       . "\xf085")
+    ("degrees"                         . "\xf042")
+    ("direction-down"                  . "\xf044")
+    ("direction-down-left"             . "\xf043")
+    ("direction-down-right"            . "\xf088")
+    ("direction-left"                  . "\xf048")
+    ("direction-right"                 . "\xf04d")
+    ("direction-up"                    . "\xf058")
+    ("direction-up-left"               . "\xf087")
+    ("direction-up-right"              . "\xf057")
+    ("dust"                            . "\xf063")
+    ("earthquake"                      . "\xf0c6")
+    ("fahrenheit"                      . "\xf045")
+    ("fire"                            . "\xf0c7")
+    ("flood"                           . "\xf07c")
+    ("fog"                             . "\xf014")
+    ("forecast-io-clear-day"           . "\xf00d")
+    ("forecast-io-clear-night"         . "\xf02e")
+    ("forecast-io-cloudy"              . "\xf013")
+    ("forecast-io-fog"                 . "\xf014")
+    ("forecast-io-hail"                . "\xf015")
+    ("forecast-io-partly-cloudy-day"   . "\xf002")
+    ("forecast-io-partly-cloudy-night" . "\xf031")
+    ("forecast-io-rain"                . "\xf019")
+    ("forecast-io-sleet"               . "\xf0b5")
+    ("forecast-io-snow"                . "\xf01b")
+    ("forecast-io-thunderstorm"        . "\xf01e")
+    ("forecast-io-tornado"             . "\xf056")
+    ("forecast-io-wind"                . "\xf050")
+    ("gale-warning"                    . "\xf0cd")
+    ("hail"                            . "\xf015")
+    ("horizon"                         . "\xf047")
+    ("horizon-alt"                     . "\xf046")
+    ("hot"                             . "\xf072")
+    ("humidity"                        . "\xf07a")
+    ("hurricane"                       . "\xf073")
+    ("hurricane-warning"               . "\xf0cf")
+    ("lightning"                       . "\xf016")
+    ("lunar-eclipse"                   . "\xf070")
+    ("meteor"                          . "\xf071")
+    ("moon-0"                          . "\xf095")
+    ("moon-1"                          . "\xf096")
+    ("moon-10"                         . "\xf09f")
+    ("moon-11"                         . "\xf0a0")
+    ("moon-12"                         . "\xf0a1")
+    ("moon-13"                         . "\xf0a2")
+    ("moon-14"                         . "\xf0a3")
+    ("moon-15"                         . "\xf0a4")
+    ("moon-16"                         . "\xf0a5")
+    ("moon-17"                         . "\xf0a6")
+    ("moon-18"                         . "\xf0a7")
+    ("moon-19"                         . "\xf0a8")
+    ("moon-2"                          . "\xf097")
+    ("moon-20"                         . "\xf0a9")
+    ("moon-21"                         . "\xf0aa")
+    ("moon-22"                         . "\xf0ab")
+    ("moon-23"                         . "\xf0ac")
+    ("moon-24"                         . "\xf0ad")
+    ("moon-25"                         . "\xf0ae")
+    ("moon-26"                         . "\xf0af")
+    ("moon-27"                         . "\xf0b0")
+    ("moon-3"                          . "\xf098")
+    ("moon-4"                          . "\xf099")
+    ("moon-5"                          . "\xf09a")
+    ("moon-6"                          . "\xf09b")
+    ("moon-7"                          . "\xf09c")
+    ("moon-8"                          . "\xf09d")
+    ("moon-9"                          . "\xf09e")
+    ("moon-alt-first-quarter"          . "\xf0d6")
+    ("moon-alt-full"                   . "\xf0dd")
+    ("moon-alt-new"                    . "\xf0eb")
+    ("moon-alt-third-quarter"          . "\xf0e4")
+    ("moon-alt-waning-crescent-1"      . "\xf0e5")
+    ("moon-alt-waning-crescent-2"      . "\xf0e6")
+    ("moon-alt-waning-crescent-3"      . "\xf0e7")
+    ("moon-alt-waning-crescent-4"      . "\xf0e8")
+    ("moon-alt-waning-crescent-5"      . "\xf0e9")
+    ("moon-alt-waning-crescent-6"      . "\xf0ea")
+    ("moon-alt-waning-gibbous-1"       . "\xf0de")
+    ("moon-alt-waning-gibbous-2"       . "\xf0df")
+    ("moon-alt-waning-gibbous-3"       . "\xf0e0")
+    ("moon-alt-waning-gibbous-4"       . "\xf0e1")
+    ("moon-alt-waning-gibbous-5"       . "\xf0e2")
+    ("moon-alt-waning-gibbous-6"       . "\xf0e3")
+    ("moon-alt-waxing-crescent-1"      . "\xf0d0")
+    ("moon-alt-waxing-crescent-2"      . "\xf0d1")
+    ("moon-alt-waxing-crescent-3"      . "\xf0d2")
+    ("moon-alt-waxing-crescent-4"      . "\xf0d3")
+    ("moon-alt-waxing-crescent-5"      . "\xf0d4")
+    ("moon-alt-waxing-crescent-6"      . "\xf0d5")
+    ("moon-alt-waxing-gibbous-1"       . "\xf0d7")
+    ("moon-alt-waxing-gibbous-2"       . "\xf0d8")
+    ("moon-alt-waxing-gibbous-3"       . "\xf0d9")
+    ("moon-alt-waxing-gibbous-4"       . "\xf0da")
+    ("moon-alt-waxing-gibbous-5"       . "\xf0db")
+    ("moon-alt-waxing-gibbous-6"       . "\xf0dc")
+    ("moon-first-quarter"              . "\xf09c")
+    ("moon-full"                       . "\xf0a3")
+    ("moon-new"                        . "\xf095")
+    ("moon-third-quarter"              . "\xf0aa")
+    ("moon-waning-crescent-1"          . "\xf0ab")
+    ("moon-waning-crescent-2"          . "\xf0ac")
+    ("moon-waning-crescent-3"          . "\xf0ad")
+    ("moon-waning-crescent-4"          . "\xf0ae")
+    ("moon-waning-crescent-5"          . "\xf0af")
+    ("moon-waning-crescent-6"          . "\xf0b0")
+    ("moon-waning-gibbous-1"           . "\xf0a4")
+    ("moon-waning-gibbous-2"           . "\xf0a5")
+    ("moon-waning-gibbous-3"           . "\xf0a6")
+    ("moon-waning-gibbous-4"           . "\xf0a7")
+    ("moon-waning-gibbous-5"           . "\xf0a8")
+    ("moon-waning-gibbous-6"           . "\xf0a9")
+    ("moon-waxing-crescent-1"          . "\xf096")
+    ("moon-waxing-crescent-2"          . "\xf097")
+    ("moon-waxing-crescent-3"          . "\xf098")
+    ("moon-waxing-crescent-4"          . "\xf099")
+    ("moon-waxing-crescent-5"          . "\xf09a")
+    ("moon-waxing-crescent-6"          . "\xf09b")
+    ("moon-waxing-gibbous-1"           . "\xf09d")
+    ("moon-waxing-gibbous-2"           . "\xf09e")
+    ("moon-waxing-gibbous-3"           . "\xf09f")
+    ("moon-waxing-gibbous-4"           . "\xf0a0")
+    ("moon-waxing-gibbous-5"           . "\xf0a1")
+    ("moon-waxing-gibbous-6"           . "\xf0a2")
+    ("moonrise"                        . "\xf0c9")
+    ("moonset"                         . "\xf0ca")
+    ("na"                              . "\xf07b")
+    ("night-alt-cloudy"                . "\xf086")
+    ("night-alt-cloudy-gusts"          . "\xf022")
+    ("night-alt-cloudy-high"           . "\xf07e")
+    ("night-alt-cloudy-windy"          . "\xf023")
+    ("night-alt-hail"                  . "\xf024")
+    ("night-alt-lightning"             . "\xf025")
+    ("night-alt-partly-cloudy"         . "\xf081")
+    ("night-alt-rain"                  . "\xf028")
+    ("night-alt-rain-mix"              . "\xf026")
+    ("night-alt-rain-wind"             . "\xf027")
+    ("night-alt-showers"               . "\xf029")
+    ("night-alt-sleet"                 . "\xf0b4")
+    ("night-alt-sleet-storm"           . "\xf06a")
+    ("night-alt-snow"                  . "\xf02a")
+    ("night-alt-snow-thunderstorm"     . "\xf06d")
+    ("night-alt-snow-wind"             . "\xf067")
+    ("night-alt-sprinkle"              . "\xf02b")
+    ("night-alt-storm-showers"         . "\xf02c")
+    ("night-alt-thunderstorm"          . "\xf02d")
+    ("night-clear"                     . "\xf02e")
+    ("night-cloudy"                    . "\xf031")
+    ("night-cloudy-gusts"              . "\xf02f")
+    ("night-cloudy-high"               . "\xf080")
+    ("night-cloudy-windy"              . "\xf030")
+    ("night-fog"                       . "\xf04a")
+    ("night-hail"                      . "\xf032")
+    ("night-lightning"                 . "\xf033")
+    ("night-partly-cloudy"             . "\xf083")
+    ("night-rain"                      . "\xf036")
+    ("night-rain-mix"                  . "\xf034")
+    ("night-rain-wind"                 . "\xf035")
+    ("night-showers"                   . "\xf037")
+    ("night-sleet"                     . "\xf0b3")
+    ("night-sleet-storm"               . "\xf069")
+    ("night-snow"                      . "\xf038")
+    ("night-snow-thunderstorm"         . "\xf06c")
+    ("night-snow-wind"                 . "\xf066")
+    ("night-sprinkle"                  . "\xf039")
+    ("night-storm-showers"             . "\xf03a")
+    ("night-thunderstorm"              . "\xf03b")
+    ("owm-200"                         . "\xf01e")
+    ("owm-201"                         . "\xf01e")
+    ("owm-202"                         . "\xf01e")
+    ("owm-210"                         . "\xf016")
+    ("owm-211"                         . "\xf016")
+    ("owm-212"                         . "\xf016")
+    ("owm-221"                         . "\xf016")
+    ("owm-230"                         . "\xf01e")
+    ("owm-231"                         . "\xf01e")
+    ("owm-232"                         . "\xf01e")
+    ("owm-300"                         . "\xf01c")
+    ("owm-301"                         . "\xf01c")
+    ("owm-302"                         . "\xf019")
+    ("owm-310"                         . "\xf017")
+    ("owm-311"                         . "\xf019")
+    ("owm-312"                         . "\xf019")
+    ("owm-313"                         . "\xf01a")
+    ("owm-314"                         . "\xf019")
+    ("owm-321"                         . "\xf01c")
+    ("owm-500"                         . "\xf01c")
+    ("owm-501"                         . "\xf019")
+    ("owm-502"                         . "\xf019")
+    ("owm-503"                         . "\xf019")
+    ("owm-504"                         . "\xf019")
+    ("owm-511"                         . "\xf017")
+    ("owm-520"                         . "\xf01a")
+    ("owm-521"                         . "\xf01a")
+    ("owm-522"                         . "\xf01a")
+    ("owm-531"                         . "\xf01d")
+    ("owm-600"                         . "\xf01b")
+    ("owm-601"                         . "\xf01b")
+    ("owm-602"                         . "\xf0b5")
+    ("owm-611"                         . "\xf017")
+    ("owm-612"                         . "\xf017")
+    ("owm-615"                         . "\xf017")
+    ("owm-616"                         . "\xf017")
+    ("owm-620"                         . "\xf017")
+    ("owm-621"                         . "\xf01b")
+    ("owm-622"                         . "\xf01b")
+    ("owm-701"                         . "\xf01a")
+    ("owm-711"                         . "\xf062")
+    ("owm-721"                         . "\xf0b6")
+    ("owm-731"                         . "\xf063")
+    ("owm-741"                         . "\xf014")
+    ("owm-761"                         . "\xf063")
+    ("owm-762"                         . "\xf063")
+    ("owm-771"                         . "\xf011")
+    ("owm-781"                         . "\xf056")
+    ("owm-800"                         . "\xf00d")
+    ("owm-801"                         . "\xf011")
+    ("owm-802"                         . "\xf011")
+    ("owm-803"                         . "\xf012")
+    ("owm-804"                         . "\xf013")
+    ("owm-900"                         . "\xf056")
+    ("owm-901"                         . "\xf01d")
+    ("owm-902"                         . "\xf073")
+    ("owm-903"                         . "\xf076")
+    ("owm-904"                         . "\xf072")
+    ("owm-905"                         . "\xf021")
+    ("owm-906"                         . "\xf015")
+    ("owm-957"                         . "\xf050")
+    ("owm-day-200"                     . "\xf010")
+    ("owm-day-201"                     . "\xf010")
+    ("owm-day-202"                     . "\xf010")
+    ("owm-day-210"                     . "\xf005")
+    ("owm-day-211"                     . "\xf005")
+    ("owm-day-212"                     . "\xf005")
+    ("owm-day-221"                     . "\xf005")
+    ("owm-day-230"                     . "\xf010")
+    ("owm-day-231"                     . "\xf010")
+    ("owm-day-232"                     . "\xf010")
+    ("owm-day-300"                     . "\xf00b")
+    ("owm-day-301"                     . "\xf00b")
+    ("owm-day-302"                     . "\xf008")
+    ("owm-day-310"                     . "\xf008")
+    ("owm-day-311"                     . "\xf008")
+    ("owm-day-312"                     . "\xf008")
+    ("owm-day-313"                     . "\xf008")
+    ("owm-day-314"                     . "\xf008")
+    ("owm-day-321"                     . "\xf00b")
+    ("owm-day-500"                     . "\xf00b")
+    ("owm-day-501"                     . "\xf008")
+    ("owm-day-502"                     . "\xf008")
+    ("owm-day-503"                     . "\xf008")
+    ("owm-day-504"                     . "\xf008")
+    ("owm-day-511"                     . "\xf006")
+    ("owm-day-520"                     . "\xf009")
+    ("owm-day-521"                     . "\xf009")
+    ("owm-day-522"                     . "\xf009")
+    ("owm-day-531"                     . "\xf00e")
+    ("owm-day-600"                     . "\xf00a")
+    ("owm-day-601"                     . "\xf0b2")
+    ("owm-day-602"                     . "\xf00a")
+    ("owm-day-611"                     . "\xf006")
+    ("owm-day-612"                     . "\xf006")
+    ("owm-day-615"                     . "\xf006")
+    ("owm-day-616"                     . "\xf006")
+    ("owm-day-620"                     . "\xf006")
+    ("owm-day-621"                     . "\xf00a")
+    ("owm-day-622"                     . "\xf00a")
+    ("owm-day-701"                     . "\xf009")
+    ("owm-day-711"                     . "\xf062")
+    ("owm-day-721"                     . "\xf0b6")
+    ("owm-day-731"                     . "\xf063")
+    ("owm-day-741"                     . "\xf003")
+    ("owm-day-761"                     . "\xf063")
+    ("owm-day-762"                     . "\xf063")
+    ("owm-day-781"                     . "\xf056")
+    ("owm-day-800"                     . "\xf00d")
+    ("owm-day-801"                     . "\xf000")
+    ("owm-day-802"                     . "\xf000")
+    ("owm-day-803"                     . "\xf000")
+    ("owm-day-804"                     . "\xf00c")
+    ("owm-day-900"                     . "\xf056")
+    ("owm-day-902"                     . "\xf073")
+    ("owm-day-903"                     . "\xf076")
+    ("owm-day-904"                     . "\xf072")
+    ("owm-day-906"                     . "\xf004")
+    ("owm-day-957"                     . "\xf050")
+    ("owm-night-200"                   . "\xf02d")
+    ("owm-night-201"                   . "\xf02d")
+    ("owm-night-202"                   . "\xf02d")
+    ("owm-night-210"                   . "\xf025")
+    ("owm-night-211"                   . "\xf025")
+    ("owm-night-212"                   . "\xf025")
+    ("owm-night-221"                   . "\xf025")
+    ("owm-night-230"                   . "\xf02d")
+    ("owm-night-231"                   . "\xf02d")
+    ("owm-night-232"                   . "\xf02d")
+    ("owm-night-300"                   . "\xf02b")
+    ("owm-night-301"                   . "\xf02b")
+    ("owm-night-302"                   . "\xf028")
+    ("owm-night-310"                   . "\xf028")
+    ("owm-night-311"                   . "\xf028")
+    ("owm-night-312"                   . "\xf028")
+    ("owm-night-313"                   . "\xf028")
+    ("owm-night-314"                   . "\xf028")
+    ("owm-night-321"                   . "\xf02b")
+    ("owm-night-500"                   . "\xf02b")
+    ("owm-night-501"                   . "\xf028")
+    ("owm-night-502"                   . "\xf028")
+    ("owm-night-503"                   . "\xf028")
+    ("owm-night-504"                   . "\xf028")
+    ("owm-night-511"                   . "\xf026")
+    ("owm-night-520"                   . "\xf029")
+    ("owm-night-521"                   . "\xf029")
+    ("owm-night-522"                   . "\xf029")
+    ("owm-night-531"                   . "\xf02c")
+    ("owm-night-600"                   . "\xf02a")
+    ("owm-night-601"                   . "\xf0b4")
+    ("owm-night-602"                   . "\xf02a")
+    ("owm-night-611"                   . "\xf026")
+    ("owm-night-612"                   . "\xf026")
+    ("owm-night-615"                   . "\xf026")
+    ("owm-night-616"                   . "\xf026")
+    ("owm-night-620"                   . "\xf026")
+    ("owm-night-621"                   . "\xf02a")
+    ("owm-night-622"                   . "\xf02a")
+    ("owm-night-701"                   . "\xf029")
+    ("owm-night-711"                   . "\xf062")
+    ("owm-night-721"                   . "\xf0b6")
+    ("owm-night-731"                   . "\xf063")
+    ("owm-night-741"                   . "\xf04a")
+    ("owm-night-761"                   . "\xf063")
+    ("owm-night-762"                   . "\xf063")
+    ("owm-night-781"                   . "\xf056")
+    ("owm-night-800"                   . "\xf02e")
+    ("owm-night-801"                   . "\xf022")
+    ("owm-night-802"                   . "\xf022")
+    ("owm-night-803"                   . "\xf022")
+    ("owm-night-804"                   . "\xf086")
+    ("owm-night-900"                   . "\xf056")
+    ("owm-night-902"                   . "\xf073")
+    ("owm-night-903"                   . "\xf076")
+    ("owm-night-904"                   . "\xf072")
+    ("owm-night-906"                   . "\xf024")
+    ("owm-night-957"                   . "\xf050")
+    ("rain"                            . "\xf019")
+    ("rain-mix"                        . "\xf017")
+    ("rain-wind"                       . "\xf018")
+    ("raindrop"                        . "\xf078")
+    ("raindrops"                       . "\xf04e")
+    ("refresh"                         . "\xf04c")
+    ("refresh-alt"                     . "\xf04b")
+    ("sandstorm"                       . "\xf082")
+    ("showers"                         . "\xf01a")
+    ("sleet"                           . "\xf0b5")
+    ("small-craft-advisory"            . "\xf0cc")
+    ("smog"                            . "\xf074")
+    ("smoke"                           . "\xf062")
+    ("snow"                            . "\xf01b")
+    ("snow"                            . "\xf01b")
+    ("snow-wind"                       . "\xf064")
+    ("snowflake-cold"                  . "\xf076")
+    ("solar-eclipse"                   . "\xf06e")
+    ("sprinkle"                        . "\xf01c")
+    ("stars"                           . "\xf077")
+    ("storm-showers"                   . "\xf01d")
+    ("storm-showers"                   . "\xf01d")
+    ("storm-warning"                   . "\xf0ce")
+    ("strong-wind"                     . "\xf050")
+    ("sunrise"                         . "\xf051")
+    ("sunset"                          . "\xf052")
+    ("thermometer"                     . "\xf055")
+    ("thermometer-exterior"            . "\xf053")
+    ("thermometer-internal"            . "\xf054")
+    ("thunderstorm"                    . "\xf01e")
+    ("thunderstorm"                    . "\xf01e")
+    ("time-1"                          . "\xf08a")
+    ("time-10"                         . "\xf093")
+    ("time-11"                         . "\xf094")
+    ("time-12"                         . "\xf089")
+    ("time-2"                          . "\xf08b")
+    ("time-3"                          . "\xf08c")
+    ("time-4"                          . "\xf08d")
+    ("time-5"                          . "\xf08e")
+    ("time-6"                          . "\xf08f")
+    ("time-7"                          . "\xf090")
+    ("time-8"                          . "\xf091")
+    ("time-9"                          . "\xf092")
+    ("tornado"                         . "\xf056")
+    ("train"                           . "\xf0cb")
+    ("tsunami"                         . "\xf0c5")
+    ("umbrella"                        . "\xf084")
+    ("volcano"                         . "\xf0c8")
+    ("wind-beaufort-0"                 . "\xf0b7")
+    ("wind-beaufort-1"                 . "\xf0b8")
+    ("wind-beaufort-10"                . "\xf0c1")
+    ("wind-beaufort-11"                . "\xf0c2")
+    ("wind-beaufort-12"                . "\xf0c3")
+    ("wind-beaufort-2"                 . "\xf0b9")
+    ("wind-beaufort-3"                 . "\xf0ba")
+    ("wind-beaufort-4"                 . "\xf0bb")
+    ("wind-beaufort-5"                 . "\xf0bc")
+    ("wind-beaufort-6"                 . "\xf0bd")
+    ("wind-beaufort-7"                 . "\xf0be")
+    ("wind-beaufort-8"                 . "\xf0bf")
+    ("wind-beaufort-9"                 . "\xf0c0")
+    ("wind-direction"                  . "\xf0b1")
+    ("windy"                           . "\xf021")
+    ("wmo4680-00"                      . "\xf055")
+    ("wmo4680-01"                      . "\xf013")
+    ("wmo4680-02"                      . "\xf055")
+    ("wmo4680-03"                      . "\xf013")
+    ("wmo4680-04"                      . "\xf014")
+    ("wmo4680-05"                      . "\xf014")
+    ("wmo4680-10"                      . "\xf014")
+    ("wmo4680-11"                      . "\xf014")
+    ("wmo4680-12"                      . "\xf016")
+    ("wmo4680-18"                      . "\xf050")
+    ("wmo4680-20"                      . "\xf014")
+    ("wmo4680-21"                      . "\xf017")
+    ("wmo4680-22"                      . "\xf017")
+    ("wmo4680-23"                      . "\xf019")
+    ("wmo4680-24"                      . "\xf01b")
+    ("wmo4680-25"                      . "\xf015")
+    ("wmo4680-26"                      . "\xf01e")
+    ("wmo4680-27"                      . "\xf063")
+    ("wmo4680-28"                      . "\xf063")
+    ("wmo4680-29"                      . "\xf063")
+    ("wmo4680-30"                      . "\xf014")
+    ("wmo4680-31"                      . "\xf014")
+    ("wmo4680-32"                      . "\xf014")
+    ("wmo4680-33"                      . "\xf014")
+    ("wmo4680-34"                      . "\xf014")
+    ("wmo4680-35"                      . "\xf014")
+    ("wmo4680-40"                      . "\xf017")
+    ("wmo4680-41"                      . "\xf01c")
+    ("wmo4680-42"                      . "\xf019")
+    ("wmo4680-43"                      . "\xf01c")
+    ("wmo4680-44"                      . "\xf019")
+    ("wmo4680-45"                      . "\xf015")
+    ("wmo4680-46"                      . "\xf015")
+    ("wmo4680-47"                      . "\xf01b")
+    ("wmo4680-48"                      . "\xf01b")
+    ("wmo4680-50"                      . "\xf01c")
+    ("wmo4680-51"                      . "\xf01c")
+    ("wmo4680-52"                      . "\xf019")
+    ("wmo4680-53"                      . "\xf019")
+    ("wmo4680-54"                      . "\xf076")
+    ("wmo4680-55"                      . "\xf076")
+    ("wmo4680-56"                      . "\xf076")
+    ("wmo4680-57"                      . "\xf01c")
+    ("wmo4680-58"                      . "\xf019")
+    ("wmo4680-60"                      . "\xf01c")
+    ("wmo4680-61"                      . "\xf01c")
+    ("wmo4680-62"                      . "\xf019")
+    ("wmo4680-63"                      . "\xf019")
+    ("wmo4680-64"                      . "\xf015")
+    ("wmo4680-65"                      . "\xf015")
+    ("wmo4680-66"                      . "\xf015")
+    ("wmo4680-67"                      . "\xf017")
+    ("wmo4680-68"                      . "\xf017")
+    ("wmo4680-70"                      . "\xf01b")
+    ("wmo4680-71"                      . "\xf01b")
+    ("wmo4680-72"                      . "\xf01b")
+    ("wmo4680-73"                      . "\xf01b")
+    ("wmo4680-74"                      . "\xf076")
+    ("wmo4680-75"                      . "\xf076")
+    ("wmo4680-76"                      . "\xf076")
+    ("wmo4680-77"                      . "\xf01b")
+    ("wmo4680-78"                      . "\xf076")
+    ("wmo4680-80"                      . "\xf019")
+    ("wmo4680-81"                      . "\xf01c")
+    ("wmo4680-82"                      . "\xf019")
+    ("wmo4680-83"                      . "\xf019")
+    ("wmo4680-84"                      . "\xf01d")
+    ("wmo4680-85"                      . "\xf017")
+    ("wmo4680-86"                      . "\xf017")
+    ("wmo4680-87"                      . "\xf017")
+    ("wmo4680-89"                      . "\xf015")
+    ("wmo4680-90"                      . "\xf016")
+    ("wmo4680-91"                      . "\xf01d")
+    ("wmo4680-92"                      . "\xf01e")
+    ("wmo4680-93"                      . "\xf01e")
+    ("wmo4680-94"                      . "\xf016")
+    ("wmo4680-95"                      . "\xf01e")
+    ("wmo4680-96"                      . "\xf01e")
+    ("wmo4680-99"                      . "\xf056")
+    ("wu-chanceflurries"               . "\xf064")
+    ("wu-chancerain"                   . "\xf019")
+    ("wu-chancesleat"                  . "\xf0b5")
+    ("wu-chancesnow"                   . "\xf01b")
+    ("wu-chancetstorms"                . "\xf01e")
+    ("wu-clear"                        . "\xf00d")
+    ("wu-cloudy"                       . "\xf002")
+    ("wu-flurries"                     . "\xf064")
+    ("wu-hazy"                         . "\xf0b6")
+    ("wu-mostlycloudy"                 . "\xf002")
+    ("wu-mostlysunny"                  . "\xf00d")
+    ("wu-partlycloudy"                 . "\xf002")
+    ("wu-partlysunny"                  . "\xf00d")
+    ("wu-rain"                         . "\xf01a")
+    ("wu-sleat"                        . "\xf0b5")
+    ("wu-snow"                         . "\xf01b")
+    ("wu-sunny"                        . "\xf00d")
+    ("wu-tstorms"                      . "\xf01e")
+    ("wu-unknown"                      . "\xf00d")
+    ("yahoo-0"                         . "\xf056")
+    ("yahoo-1"                         . "\xf00e")
+    ("yahoo-10"                        . "\xf015")
+    ("yahoo-11"                        . "\xf01a")
+    ("yahoo-12"                        . "\xf01a")
+    ("yahoo-13"                        . "\xf01b")
+    ("yahoo-14"                        . "\xf00a")
+    ("yahoo-15"                        . "\xf064")
+    ("yahoo-16"                        . "\xf01b")
+    ("yahoo-17"                        . "\xf015")
+    ("yahoo-18"                        . "\xf017")
+    ("yahoo-19"                        . "\xf063")
+    ("yahoo-2"                         . "\xf073")
+    ("yahoo-20"                        . "\xf014")
+    ("yahoo-21"                        . "\xf021")
+    ("yahoo-22"                        . "\xf062")
+    ("yahoo-23"                        . "\xf050")
+    ("yahoo-24"                        . "\xf050")
+    ("yahoo-25"                        . "\xf076")
+    ("yahoo-26"                        . "\xf013")
+    ("yahoo-27"                        . "\xf031")
+    ("yahoo-28"                        . "\xf002")
+    ("yahoo-29"                        . "\xf031")
+    ("yahoo-3"                         . "\xf01e")
+    ("yahoo-30"                        . "\xf002")
+    ("yahoo-31"                        . "\xf02e")
+    ("yahoo-32"                        . "\xf00d")
+    ("yahoo-3200"                      . "\xf077")
+    ("yahoo-33"                        . "\xf083")
+    ("yahoo-34"                        . "\xf00c")
+    ("yahoo-35"                        . "\xf017")
+    ("yahoo-36"                        . "\xf072")
+    ("yahoo-37"                        . "\xf00e")
+    ("yahoo-38"                        . "\xf00e")
+    ("yahoo-39"                        . "\xf00e")
+    ("yahoo-4"                         . "\xf01e")
+    ("yahoo-40"                        . "\xf01a")
+    ("yahoo-41"                        . "\xf064")
+    ("yahoo-42"                        . "\xf01b")
+    ("yahoo-43"                        . "\xf064")
+    ("yahoo-44"                        . "\xf00c")
+    ("yahoo-45"                        . "\xf00e")
+    ("yahoo-46"                        . "\xf01b")
+    ("yahoo-47"                        . "\xf00e")
+    ("yahoo-5"                         . "\xf017")
+    ("yahoo-6"                         . "\xf017")
+    ("yahoo-7"                         . "\xf017")
+    ("yahoo-8"                         . "\xf015")
+    ("yahoo-9"                         . "\xf01a")
+
+    ))
+
+(provide 'data-weathericons)
diff --git a/configs/shared/emacs/.emacs.d/elpa/all-the-icons-20180125.757/data/data-weathericons.elc b/configs/shared/emacs/.emacs.d/elpa/all-the-icons-20180125.757/data/data-weathericons.elc
new file mode 100644
index 0000000000..5476a0bf20
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/all-the-icons-20180125.757/data/data-weathericons.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/all-the-icons-ivy-20180225.630/all-the-icons-ivy-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/all-the-icons-ivy-20180225.630/all-the-icons-ivy-autoloads.el
new file mode 100644
index 0000000000..1eed20cbf5
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/all-the-icons-ivy-20180225.630/all-the-icons-ivy-autoloads.el
@@ -0,0 +1,22 @@
+;;; all-the-icons-ivy-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "all-the-icons-ivy" "all-the-icons-ivy.el"
+;;;;;;  (23377 61297 57158 640000))
+;;; Generated autoloads from all-the-icons-ivy.el
+
+(autoload 'all-the-icons-ivy-setup "all-the-icons-ivy" "\
+Set ivy's display transformers to show relevant icons next to the candidates.
+
+\(fn)" nil nil)
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; all-the-icons-ivy-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/all-the-icons-ivy-20180225.630/all-the-icons-ivy-pkg.el b/configs/shared/emacs/.emacs.d/elpa/all-the-icons-ivy-20180225.630/all-the-icons-ivy-pkg.el
new file mode 100644
index 0000000000..ba8854af2f
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/all-the-icons-ivy-20180225.630/all-the-icons-ivy-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "all-the-icons-ivy" "20180225.630" "Shows icons while using ivy and counsel" '((emacs "24.4") (all-the-icons "2.4.0") (ivy "0.8.0")))
diff --git a/configs/shared/emacs/.emacs.d/elpa/all-the-icons-ivy-20180225.630/all-the-icons-ivy.el b/configs/shared/emacs/.emacs.d/elpa/all-the-icons-ivy-20180225.630/all-the-icons-ivy.el
new file mode 100644
index 0000000000..7bba6bd15c
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/all-the-icons-ivy-20180225.630/all-the-icons-ivy.el
@@ -0,0 +1,107 @@
+;;; all-the-icons-ivy.el --- Shows icons while using ivy and counsel  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2017 asok
+
+;; Author: asok
+;; Version: 0.2.0
+;; Package-Version: 20180225.630
+;; Keywords: faces
+;; Package-Requires: ((emacs "24.4") (all-the-icons "2.4.0") (ivy "0.8.0"))
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; To use this package, do
+;;
+;; (all-the-icons-ivy-setup)
+;;
+;; Or if you prefer to only set transformers
+;; for a subset of ivy commands:
+;;
+;; (require 'all-the-icons-ivy)
+;; (ivy-set-display-transformer 'ivy-switch-buffer 'all-the-icons-ivy-buffer-transformer)
+
+;;; Code:
+
+(require 'all-the-icons)
+(require 'ivy)
+
+(defgroup all-the-icons-ivy nil
+  "Shows icons while using ivy and counsel."
+  :group 'ivy)
+
+(defcustom all-the-icons-ivy-buffer-commands
+  '(ivy-switch-buffer ivy-switch-buffer-other-window counsel-projectile-switch-to-buffer)
+  "Commands to use with `all-the-icons-ivy-buffer-transformer'."
+  :type '(repeat function)
+  :group 'all-the-icons-ivy)
+
+
+(defcustom all-the-icons-ivy-file-commands
+  '(counsel-find-file counsel-projectile-find-file counsel-projectile-find-dir)
+  "Commands to use with `all-the-icons-ivy-file-transformer'."
+  :type '(repeat function)
+  :group 'all-the-icons-ivy)
+
+(defun all-the-icons-ivy--buffer-propertize (b s)
+  "If buffer B is modified apply `ivy-modified-buffer' face on string S."
+  (if (and (buffer-file-name b)
+           (buffer-modified-p b))
+      (propertize s 'face 'ivy-modified-buffer)
+    s))
+
+(defun all-the-icons-ivy--icon-for-mode (mode)
+  "Apply `all-the-icons-for-mode' on MODE but either return an icon or nil."
+  (let ((icon (all-the-icons-icon-for-mode mode)))
+    (unless (symbolp icon)
+      icon)))
+
+(defun all-the-icons-ivy--buffer-transformer (b s)
+  "Return a candidate string for buffer B named S preceded by an icon.
+Try to find the icon for the buffer's B `major-mode'.
+If that fails look for an icon for the mode that the `major-mode' is derived from."
+  (let ((mode (buffer-local-value 'major-mode b)))
+    (format "%s\t%s"
+            (propertize "\t" 'display (or
+                                       (all-the-icons-ivy--icon-for-mode mode)
+                                       (all-the-icons-ivy--icon-for-mode (get mode 'derived-mode-parent))))
+            (all-the-icons-ivy--buffer-propertize b s))))
+
+(defun all-the-icons-ivy-file-transformer (s)
+  "Return a candidate string for filename S preceded by an icon."
+  (format "%s\t%s"
+          (propertize "\t" 'display (all-the-icons-icon-for-file s))
+          s))
+
+(defun all-the-icons-ivy-buffer-transformer (s)
+  "Return a candidate string for buffer named S.
+Assume that sometimes the buffer named S might not exists.
+That can happen if `ivy-switch-buffer' does not find the buffer and it
+falls back to `ivy-recentf' and the same transformer is used."
+  (let ((b (get-buffer s)))
+    (if b
+        (all-the-icons-ivy--buffer-transformer b s)
+      (all-the-icons-ivy-file-transformer s))))
+
+;;;###autoload
+(defun all-the-icons-ivy-setup ()
+  "Set ivy's display transformers to show relevant icons next to the candidates."
+  (dolist (cmd all-the-icons-ivy-buffer-commands)
+    (ivy-set-display-transformer cmd 'all-the-icons-ivy-buffer-transformer))
+  (dolist (cmd all-the-icons-ivy-file-commands)
+    (ivy-set-display-transformer cmd 'all-the-icons-ivy-file-transformer)))
+
+(provide 'all-the-icons-ivy)
+
+;;; all-the-icons-ivy.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/all-the-icons-ivy-20180225.630/all-the-icons-ivy.elc b/configs/shared/emacs/.emacs.d/elpa/all-the-icons-ivy-20180225.630/all-the-icons-ivy.elc
new file mode 100644
index 0000000000..2f85d4374a
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/all-the-icons-ivy-20180225.630/all-the-icons-ivy.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/archives/gnu/archive-contents b/configs/shared/emacs/.emacs.d/elpa/archives/gnu/archive-contents
new file mode 100644
index 0000000000..5480175b17
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/archives/gnu/archive-contents
@@ -0,0 +1,1293 @@
+(1
+ (ace-window .
+	     [(0 9 0)
+	      ((avy
+		(0 2 0)))
+	      "Quickly switch windows." single
+	      ((:url . "https://github.com/abo-abo/ace-window")
+	       (:keywords "window" "location"))])
+ (ack .
+      [(1 5)
+       nil "interface to ack-like tools" tar
+       ((:keywords "tools" "processes" "convenience")
+	(:url . "https://github.com/leoliu/ack-el"))])
+ (ada-mode .
+	   [(5 3 1)
+	    ((wisi
+	      (1 1 6))
+	     (cl-lib
+	      (0 4))
+	     (emacs
+	      (24 3)))
+	    "major-mode for editing Ada sources" tar
+	    ((:keywords "languages" "ada")
+	     (:url . "http://www.nongnu.org/ada-mode/"))])
+ (ada-ref-man .
+	      [(2012 3)
+	       nil "Ada Reference Manual 2012" tar
+	       ((:keywords "languages" "ada")
+		(:url . "http://stephe-leake.org/ada/arm.html"))])
+ (adaptive-wrap .
+		[(0 5 2)
+		 nil "Smart line-wrapping with wrap-prefix" single
+		 ((:url . "http://elpa.gnu.org/packages/adaptive-wrap.html")
+		  (:keywords))])
+ (adjust-parens .
+		[(3 0)
+		 nil "Indent and dedent Lisp code, automatically adjust close parens" tar
+		 ((:url . "http://elpa.gnu.org/packages/adjust-parens.html"))])
+ (aggressive-indent .
+		    [(1 8 3)
+		     ((emacs
+		       (24 1))
+		      (cl-lib
+		       (0 5)))
+		     "Minor mode to aggressively keep your code always indented" single
+		     ((:url . "https://github.com/Malabarba/aggressive-indent-mode")
+		      (:keywords "indent" "lisp" "maint" "tools"))])
+ (ahungry-theme .
+		[(1 10 0)
+		 ((emacs
+		   (24)))
+		 "Ahungry color theme for Emacs.  Make sure to (load-theme 'ahungry)." tar
+		 ((:keywords "ahungry" "palette" "color" "theme" "emacs" "color-theme" "deftheme")
+		  (:url . "https://github.com/ahungry/color-theme-ahungry"))])
+ (all .
+      [(1 0)
+       nil "Edit all lines matching a given regexp" single
+       ((:url . "http://elpa.gnu.org/packages/all.html")
+	(:keywords "matching"))])
+ (ampc .
+       [(0 2)
+	nil "Asynchronous Music Player Controller" single
+	((:url . "http://elpa.gnu.org/packages/ampc.html")
+	 (:keywords "ampc" "mpc" "mpd"))])
+ (arbitools .
+	    [(0 95)
+	     ((cl-lib
+	       (0 5)))
+	     "Package for chess tournaments administration" single
+	     ((:url . "http://elpa.gnu.org/packages/arbitools.html")
+	      (:keywords))])
+ (ascii-art-to-unicode .
+		       [(1 12)
+			nil "a small artist adjunct" single
+			((:url . "http://www.gnuvola.org/software/aa2u/")
+			 (:keywords "ascii" "unicode" "box-drawing"))])
+ (async .
+	[(1 9 2)
+	 nil "Asynchronous processing in Emacs" tar
+	 ((:keywords "async")
+	  (:url . "http://elpa.gnu.org/packages/async.html"))])
+ (auctex .
+	 [(12 1 1)
+	  nil "Integrated environment for *TeX*" tar
+	  ((:url . "http://www.gnu.org/software/auctex/"))])
+ (aumix-mode .
+	     [(7)
+	      nil "run the aumix program in a buffer" single
+	      ((:url . "http://user42.tuxfamily.org/aumix-mode/index.html")
+	       (:keywords "multimedia" "mixer" "aumix"))])
+ (auto-correct .
+	       [(1 1 4)
+		nil "Remembers and automatically fixes past corrections" single
+		((:url . "http://elpa.gnu.org/packages/auto-correct.html")
+		 (:keywords "editing"))])
+ (auto-overlays .
+		[(0 10 9)
+		 nil "Automatic regexp-delimited overlays" tar
+		 ((:keywords "extensions")
+		  (:url . "http://www.dr-qubit.org/emacs.php"))])
+ (avy .
+      [(0 4 0)
+       ((emacs
+	 (24 1))
+	(cl-lib
+	 (0 5)))
+       "tree-based completion" tar
+       ((:keywords "point" "location")
+	(:url . "https://github.com/abo-abo/avy"))])
+ (bbdb .
+       [(3 2)
+	((emacs
+	  (24)))
+	"core of BBDB" tar
+	((:url . "http://elpa.gnu.org/packages/bbdb.html"))])
+ (beacon .
+	 [(1 3 3)
+	  ((seq
+	    (2 14)))
+	  "Highlight the cursor whenever the window scrolls" single
+	  ((:url . "https://github.com/Malabarba/beacon")
+	   (:keywords "convenience"))])
+ (brief .
+	[(5 84)
+	 nil "Brief Editor Emulator" single
+	 ((:url . "http://elpa.gnu.org/packages/brief.html")
+	  (:keywords "brief" "emulations" "crisp"))])
+ (bug-hunter .
+	     [(1 3 1)
+	      ((seq
+		(1 3))
+	       (cl-lib
+		(0 5)))
+	      "Hunt down errors by bisecting elisp files" single
+	      ((:url . "https://github.com/Malabarba/elisp-bug-hunter")
+	       (:keywords "lisp"))])
+ (caps-lock .
+	    [(1 0)
+	     nil "Caps-lock as a minor mode" single
+	     ((:url . "http://elpa.gnu.org/packages/caps-lock.html")
+	      (:keywords))])
+ (captain .
+	  [(1 0 3)
+	   nil "CAPiTalization is Automatic IN emacs" single
+	   ((:url . "http://elpa.gnu.org/packages/captain.html")
+	    (:keywords "editing"))])
+ (chess .
+	[(2 0 4)
+	 ((cl-lib
+	   (0 5)))
+	 "Play chess in GNU Emacs" tar
+	 ((:keywords "games")
+	  (:url . "http://elpa.gnu.org/packages/chess.html"))])
+ (cl-generic .
+	     [(0 3)
+	      nil "Forward cl-generic compatibility for Emacs<25" single
+	      ((:url . "http://elpa.gnu.org/packages/cl-generic.html")
+	       (:keywords))])
+ (cl-lib .
+	 [(0 6 1)
+	  nil "Properly prefixed CL functions and macros" single
+	  ((:url . "http://elpa.gnu.org/packages/cl-lib.html")
+	   (:keywords))])
+ (cl-print .
+	   [(1 0)
+	    ((emacs
+	      (25)))
+	    "CL-style generic printing" single
+	    ((:url . "http://elpa.gnu.org/packages/cl-print.html")
+	     (:keywords))])
+ (cobol-mode .
+	     [(1 0 0)
+	      ((cl-lib
+		(0 5)))
+	      "Mode for editing COBOL code" single
+	      ((:url . "http://elpa.gnu.org/packages/cobol-mode.html")
+	       (:keywords "languages"))])
+ (coffee-mode .
+	      [(0 4 1 1)
+	       nil "Major mode for CoffeeScript files" single
+	       ((:url . "http://github.com/defunkt/coffee-mode")
+		(:keywords "coffeescript" "major" "mode"))])
+ (compact-docstrings .
+		     [(0 1)
+		      nil "Shrink blank lines in docstrings and doc comments" single
+		      ((:url . "https://github.com/cpitclaudel/compact-docstrings")
+		       (:keywords "convenience" "faces" "lisp" "maint" "c"))])
+ (company .
+	  [(0 9 6)
+	   ((emacs
+	     (24 3)))
+	   "Modular text completion framework" tar
+	   ((:keywords "abbrev" "convenience" "matching")
+	    (:url . "http://company-mode.github.io/"))])
+ (company-ebdb .
+	       [(1)
+		((company
+		  (0 9 4))
+		 (ebdb
+		  (0 2)))
+		"company-mode completion backend for EBDB in message-mode" single
+		((:url . "http://elpa.gnu.org/packages/company-ebdb.html")
+		 (:keywords))])
+ (company-math .
+	       [(1 1)
+		((company
+		  (0 8 0))
+		 (math-symbol-lists
+		  (1 0)))
+		"Completion backends for unicode math symbols and latex tags" tar
+		((:keywords "unicode" "symbols" "completion")
+		 (:url . "https://github.com/vspinu/company-math"))])
+ (company-statistics .
+		     [(0 2 3)
+		      ((emacs
+			(24 3))
+		       (company
+			(0 8 5)))
+		      "Sort candidates using completion history" tar
+		      ((:keywords "abbrev" "convenience" "matching")
+		       (:url . "https://github.com/company-mode/company-statistics"))])
+ (context-coloring .
+		   [(8 1 0)
+		    ((emacs
+		      (24 3)))
+		    "Highlight by scope" tar
+		    ((:keywords "convenience" "faces" "tools")
+		     (:url . "https://github.com/jacksonrayhamilton/context-coloring"))])
+ (counsel-ebdb .
+	       [(1)
+		((ivy
+		  (0 8 0))
+		 (ebdb
+		  (0 2)))
+		"Counsel integration for EBDB" single
+		((:url . "http://elpa.gnu.org/packages/counsel-ebdb.html")
+		 (:keywords))])
+ (crisp .
+	[(1 3 4)
+	 nil "CRiSP/Brief Emacs emulator" single
+	 ((:url . "http://elpa.gnu.org/packages/crisp.html")
+	  (:keywords "emulations" "brief" "crisp"))])
+ (csv-mode .
+	   [(1 7)
+	    nil "Major mode for editing comma/char separated values" single
+	    ((:url . "http://elpa.gnu.org/packages/csv-mode.html")
+	     (:keywords "convenience"))])
+ (cycle-quotes .
+	       [(0 1)
+		nil "Cycle between quote styles" tar
+		((:keywords "convenience")
+		 (:url . "http://elpa.gnu.org/packages/cycle-quotes.html"))])
+ (darkroom .
+	   [(0 1)
+	    ((cl-lib
+	      (0 5)))
+	    "Remove visual distractions and focus on writing" single
+	    ((:url . "http://elpa.gnu.org/packages/darkroom.html")
+	     (:keywords "convenience" "emulations"))])
+ (dash .
+       [(2 12 0)
+	nil "A modern list library for Emacs" tar
+	((:keywords "lists")
+	 (:url . "http://elpa.gnu.org/packages/dash.html"))])
+ (dbus-codegen .
+	       [(0 1)
+		((cl-lib
+		  (0 5)))
+		"Lisp code generation for D-Bus." single
+		((:url . "http://elpa.gnu.org/packages/dbus-codegen.html")
+		 (:keywords "comm" "dbus" "convenience"))])
+ (debbugs .
+	  [(0 15)
+	   ((soap-client
+	     (3 1 1))
+	    (cl-lib
+	     (0 5)))
+	   "SOAP library to access debbugs servers" tar
+	   ((:keywords "comm" "hypermedia")
+	    (:url . "http://elpa.gnu.org/packages/debbugs.html"))])
+ (delight .
+	  [(1 5)
+	   nil "A dimmer switch for your lighter text." single
+	   ((:url . "https://savannah.nongnu.org/projects/delight")
+	    (:keywords "convenience"))])
+ (dict-tree .
+	    [(0 14)
+	     ((trie
+	       (0 3))
+	      (tNFA
+	       (0 1 1))
+	      (heap
+	       (0 3)))
+	     "Dictionary data structure" single
+	     ((:url . "http://www.dr-qubit.org/emacs.php")
+	      (:keywords "extensions" "matching" "data structures trie" "tree" "dictionary" "completion" "regexp"))])
+ (diff-hl .
+	  [(1 8 4)
+	   ((cl-lib
+	     (0 2)))
+	   "Highlight uncommitted changes using VC" tar
+	   ((:keywords "vc" "diff")
+	    (:url . "https://github.com/dgutov/diff-hl"))])
+ (diffview .
+	   [(1 0)
+	    nil "View diffs in side-by-side format" single
+	    ((:url . "https://github.com/mgalgs/diffview-mode")
+	     (:keywords "convenience" "diff"))])
+ (dired-du .
+	   [(0 5)
+	    ((emacs
+	      (24 4))
+	     (cl-lib
+	      (0 5)))
+	    "Dired with recursive directory sizes" tar
+	    ((:keywords "files" "unix" "convenience")
+	     (:url . "http://elpa.gnu.org/packages/dired-du.html"))])
+ (dismal .
+	 [(1 5)
+	  ((cl-lib
+	    (0)))
+	  "Dis Mode Ain't Lotus: Spreadsheet program Emacs" tar
+	  ((:url . "http://elpa.gnu.org/packages/dismal.html"))])
+ (djvu .
+       [(0 5)
+	nil "Edit and view Djvu files via djvused" single
+	((:url . "http://elpa.gnu.org/packages/djvu.html")
+	 (:keywords "files" "wp"))])
+ (docbook .
+	  [(0 1)
+	   nil "Info-like viewer for DocBook" single
+	   ((:url . "http://elpa.gnu.org/packages/docbook.html")
+	    (:keywords "docs" "help"))])
+ (dts-mode .
+	   [(0 1 0)
+	    nil "Major mode for Device Tree source files" single
+	    ((:url . "http://elpa.gnu.org/packages/dts-mode.html")
+	     (:keywords "languages"))])
+ (easy-kill .
+	    [(0 9 3)
+	     ((emacs
+	       (24))
+	      (cl-lib
+	       (0 5)))
+	     "kill & mark things easily" tar
+	     ((:keywords "killing" "convenience")
+	      (:url . "https://github.com/leoliu/easy-kill"))])
+ (ebdb .
+       [(0 6)
+	((emacs
+	  (25 1))
+	 (cl-lib
+	  (0 5))
+	 (seq
+	  (2 15)))
+	"Contact management package" tar
+	((:keywords "convenience" "mail")
+	 (:url . "https://github.com/girzel/ebdb"))])
+ (ebdb-gnorb .
+	     [(1 0 2)
+	      ((gnorb
+		(1 1 0))
+	       (ebdb
+		(0 2)))
+	      "Utilities for connecting EBDB to Gnorb" single
+	      ((:url . "http://elpa.gnu.org/packages/ebdb-gnorb.html")
+	       (:keywords))])
+ (ebdb-i18n-chn .
+		[(1 2)
+		 ((pyim
+		   (1 6 0))
+		  (ebdb
+		   (0 2)))
+		 "China-specific internationalization support for EBDB" single
+		 ((:url . "http://elpa.gnu.org/packages/ebdb-i18n-chn.html")
+		  (:keywords))])
+ (ediprolog .
+	    [(1 2)
+	     nil "Emacs Does Interactive Prolog" single
+	     ((:url . "http://elpa.gnu.org/packages/ediprolog.html")
+	      (:keywords "languages" "processes"))])
+ (eglot .
+	[(1 1)
+	 ((emacs
+	   (26 1))
+	  (jsonrpc
+	   (1 0 0)))
+	 "Client for Language Server Protocol (LSP) servers" tar
+	 ((:keywords "convenience" "languages")
+	  (:url . "https://github.com/joaotavora/eglot"))])
+ (el-search .
+	    [(1 7 7)
+	     ((emacs
+	       (25))
+	      (stream
+	       (2 2 4))
+	      (cl-print
+	       (1 0)))
+	     "Expression based interactive search for Emacs Lisp" tar
+	     ((:keywords "lisp")
+	      (:url . "http://elpa.gnu.org/packages/el-search.html"))])
+ (eldoc-eval .
+	     [(0 1)
+	      nil "Enable eldoc support when minibuffer is in use." single
+	      ((:url . "http://elpa.gnu.org/packages/eldoc-eval.html")
+	       (:keywords))])
+ (electric-spacing .
+		   [(5 0)
+		    nil "Insert operators with surrounding spaces smartly" single
+		    ((:url . "http://elpa.gnu.org/packages/electric-spacing.html")
+		     (:keywords))])
+ (enwc .
+       [(2 0)
+	((emacs
+	  (25 1)))
+	"The Emacs Network Client" tar
+	((:keywords "external" "network" "wicd" "manager" "nm")
+	 (:url . "http://elpa.gnu.org/packages/enwc.html"))])
+ (epoch-view .
+	     [(0 0 1)
+	      nil "Minor mode to visualize epoch timestamps" single
+	      ((:url . "http://elpa.gnu.org/packages/epoch-view.html")
+	       (:keywords "data" "timestamp" "epoch" "unix"))])
+ (ergoemacs-mode .
+		 [(5 16 10 12)
+		  ((emacs
+		    (24 1))
+		   (undo-tree
+		    (0 6 5))
+		   (cl-lib
+		    (0 5)))
+		  "Emacs mode based on common modern interface and ergonomics." tar
+		  ((:keywords "convenience")
+		   (:url . "https://github.com/ergoemacs/ergoemacs-mode"))])
+ (excorporate .
+	      [(0 7 6)
+	       ((emacs
+		 (24 1))
+		(fsm
+		 (0 2))
+		(soap-client
+		 (3 1 1))
+		(url-http-ntlm
+		 (2 0 3)))
+	       "Exchange integration" tar
+	       ((:keywords "calendar")
+		(:url . "http://elpa.gnu.org/packages/excorporate.html"))])
+ (exwm .
+       [(0 19)
+	((xelb
+	  (0 15)))
+	"Emacs X Window Manager" tar
+	((:keywords "unix")
+	 (:url . "https://github.com/ch11ng/exwm"))])
+ (f90-interface-browser .
+			[(1 1)
+			 nil "Parse and browse f90 interfaces" single
+			 ((:url . "http://github.com/wence-/f90-iface/")
+			  (:keywords))])
+ (filladapt .
+	    [(2 12 2)
+	     ((emacs
+	       (24 4)))
+	     "Adaptive fill" single
+	     ((:url . "http://elpa.gnu.org/packages/filladapt.html")
+	      (:keywords))])
+ (flylisp .
+	  [(0 2)
+	   ((emacs
+	     (24 1))
+	    (cl-lib
+	     (0 4)))
+	   "Color unbalanced parentheses and parentheses inconsistent with indentation" single
+	   ((:url . "http://elpa.gnu.org/packages/flylisp.html")
+	    (:keywords))])
+ (frame-tabs .
+	     [(1 1)
+	      nil "show buffer tabs in side window" single
+	      ((:url . "http://elpa.gnu.org/packages/frame-tabs.html")
+	       (:keywords "frames" "tabs"))])
+ (fsm .
+      [(0 2 1)
+       ((emacs
+	 (24 1))
+	(cl-lib
+	 (0 5)))
+       "state machine library" single
+       ((:url . "http://elpa.gnu.org/packages/fsm.html")
+	(:keywords "extensions"))])
+ (ggtags .
+	 [(0 8 13)
+	  ((emacs
+	    (24))
+	   (cl-lib
+	    (0 5)))
+	  "emacs frontend to GNU Global source code tagging system" single
+	  ((:url . "https://github.com/leoliu/ggtags")
+	   (:keywords "tools" "convenience"))])
+ (gited .
+	[(0 5 3)
+	 ((emacs
+	   (24 4))
+	  (cl-lib
+	   (0 5)))
+	 "Operate on Git branches like dired" tar
+	 ((:keywords "git" "vc" "convenience")
+	  (:url . "http://elpa.gnu.org/packages/gited.html"))])
+ (gle-mode .
+	   [(1 1)
+	    ((cl-lib
+	      (0 5)))
+	    "Major mode to edit Graphics Layout Engine files" single
+	    ((:url . "http://elpa.gnu.org/packages/gle-mode.html")
+	     (:keywords))])
+ (gnome-c-style .
+		[(0 1)
+		 nil "minor mode for editing GNOME-style C source code" tar
+		 ((:keywords "gnome" "c" "coding style")
+		  (:url . "http://elpa.gnu.org/packages/gnome-c-style.html"))])
+ (gnorb .
+	[(1 5 5)
+	 ((cl-lib
+	   (0 5)))
+	 "Glue code between Gnus, Org, and BBDB" tar
+	 ((:keywords "mail" "org" "gnus" "bbdb" "todo" "task")
+	  (:url . "http://elpa.gnu.org/packages/gnorb.html"))])
+ (gnugo .
+	[(3 1 0)
+	 ((ascii-art-to-unicode
+	   (1 5))
+	  (xpm
+	   (1 0 1))
+	  (cl-lib
+	   (0 5)))
+	 "play GNU Go in a buffer" tar
+	 ((:keywords "games" "processes")
+	  (:url . "http://www.gnuvola.org/software/gnugo/"))])
+ (heap .
+       [(0 5)
+	nil "Heap (a.k.a. priority queue) data structure" single
+	((:url . "http://www.dr-qubit.org/emacs.php")
+	 (:keywords "extensions" "data structures" "heap" "priority queue"))])
+ (helm-ebdb .
+	    [(1)
+	     ((helm
+	       (1 0))
+	      (ebdb
+	       (0 2)))
+	     "Helm integration for EBDB" single
+	     ((:url . "http://elpa.gnu.org/packages/helm-ebdb.html")
+	      (:keywords "mail" "convenience"))])
+ (highlight-escape-sequences .
+			     [(0 3)
+			      nil "Highlight escape sequences" single
+			      ((:url . "https://github.com/dgutov/highlight-escape-sequences")
+			       (:keywords "convenience"))])
+ (hook-helpers .
+	       [(1 1 1)
+		((emacs
+		  (25 1)))
+		"Anonymous, modifiable hook functions" tar
+		((:keywords "development" "hooks")
+		 (:url . "https://savannah.nongnu.org/projects/hook-helpers-el/"))])
+ (html5-schema .
+	       [(0 1)
+		nil "Add HTML5 schemas for use by nXML" tar
+		((:keywords "html" "xml")
+		 (:url . "https://github.com/validator/validator"))])
+ (hydra .
+	[(0 14 0)
+	 ((cl-lib
+	   (0 5)))
+	 "Make bindings that stick around." tar
+	 ((:keywords "bindings")
+	  (:url . "https://github.com/abo-abo/hydra"))])
+ (hyperbole .
+	    [(7 0 2)
+	     ((emacs
+	       (24 4)))
+	     "GNU Hyperbole: The Everyday Hypertextual Information Manager" tar
+	     ((:keywords "comm" "convenience" "files" "frames" "hypermedia" "languages" "mail" "matching" "mouse" "multimedia" "outlines" "tools" "wp")
+	      (:url . "http://www.gnu.org/software/hyperbole"))])
+ (ioccur .
+	 [(2 4)
+	  nil "Incremental occur" single
+	  ((:url . "http://elpa.gnu.org/packages/ioccur.html")
+	   (:keywords))])
+ (iterators .
+	    [(0 1 1)
+	     ((emacs
+	       (25)))
+	     "Functions for working with iterators" single
+	     ((:url . "http://elpa.gnu.org/packages/iterators.html")
+	      (:keywords "extensions" "elisp"))])
+ (ivy .
+      [(0 10 0)
+       ((emacs
+	 (24 1)))
+       "Incremental Vertical completYon" tar
+       ((:keywords "matching")
+	(:url . "https://github.com/abo-abo/swiper"))])
+ (javaimp .
+	  [(0 6)
+	   nil "Add and reorder Java import statements in Maven projects" tar
+	   ((:keywords "java" "maven" "programming")
+	    (:url . "http://elpa.gnu.org/packages/javaimp.html"))])
+ (jgraph-mode .
+	      [(1 1)
+	       ((cl-lib
+		 (0 5)))
+	       "Major mode for Jgraph files" single
+	       ((:url . "http://elpa.gnu.org/packages/jgraph-mode.html")
+		(:keywords "tex" "wp"))])
+ (js2-mode .
+	   [(20180301)
+	    ((emacs
+	      (24 1))
+	     (cl-lib
+	      (0 5)))
+	    "Improved JavaScript editing mode" tar
+	    ((:keywords "languages" "javascript")
+	     (:url . "https://github.com/mooz/js2-mode/"))])
+ (json-mode .
+	    [(0 1)
+	     ((emacs
+	       (25 1)))
+	     "Major mode for editing JSON files" single
+	     ((:url . "http://elpa.gnu.org/packages/json-mode.html")
+	      (:keywords "data"))])
+ (jsonrpc .
+	  [(1 0 6)
+	   ((emacs
+	     (25 2)))
+	   "JSON-RPC library" single
+	   ((:url . "http://elpa.gnu.org/packages/jsonrpc.html")
+	    (:keywords "processes" "languages" "extensions"))])
+ (jumpc .
+	[(3 0)
+	 nil "jump to previous insertion points" single
+	 ((:url . "http://elpa.gnu.org/packages/jumpc.html")
+	  (:keywords))])
+ (kmb .
+      [(0 1)
+       ((emacs
+	 (24 1)))
+       "Kill buffers matching a regexp w/o confirmation" single
+       ((:url . "http://elpa.gnu.org/packages/kmb.html")
+	(:keywords "lisp" "convenience"))])
+ (landmark .
+	   [(1 0)
+	    nil "Neural-network robot that learns landmarks" single
+	    ((:url . "http://elpa.gnu.org/packages/landmark.html")
+	     (:keywords "games" "neural network" "adaptive search" "chemotaxis"))])
+ (let-alist .
+   [(1 0 5)
+    ((emacs
+      (24 1)))
+    "Easily let-bind values of an assoc-list by their names" single
+    ((:url . "http://elpa.gnu.org/packages/let-alist.html")
+     (:keywords "extensions" "lisp"))])
+ (lex .
+      [(1 1)
+       nil "Lexical analyser construction" tar
+       ((:url . "http://elpa.gnu.org/packages/lex.html"))])
+ (lmc .
+      [(1 4)
+       ((emacs
+	 (24))
+	(cl-lib
+	 (0 5)))
+       "Little Man Computer in Elisp" single
+       ((:url . "http://elpa.gnu.org/packages/lmc.html")
+	(:keywords))])
+ (load-dir .
+	   [(0 0 5)
+	    ((cl-lib
+	      (0 5)))
+	    "Load all Emacs Lisp files in a given directory" single
+	    ((:url . "http://elpa.gnu.org/packages/load-dir.html")
+	     (:keywords "lisp" "files" "convenience"))])
+ (load-relative .
+		[(1 3)
+		 nil "relative file load (within a multi-file Emacs package)" single
+		 ((:url . "http://github.com/rocky/emacs-load-relative")
+		  (:keywords "internal"))])
+ (loc-changes .
+	      [(1 2)
+	       nil "keep track of positions even after buffer changes" single
+	       ((:url . "http://github.com/rocky/emacs-loc-changes")
+		(:keywords))])
+ (loccur .
+	 [(1 2 3)
+	  ((cl-lib
+	    (0)))
+	  "Perform an occur-like folding in current buffer" single
+	  ((:url . "https://github.com/fourier/loccur")
+	   (:keywords "matching"))])
+ (markchars .
+	    [(0 2 0)
+	     nil "Mark chars fitting certain characteristics" single
+	     ((:url . "http://elpa.gnu.org/packages/markchars.html")
+	      (:keywords))])
+ (math-symbol-lists .
+		    [(1 1)
+		     nil "Lists of Unicode math symbols and latex commands" tar
+		     ((:keywords "unicode" "symbols" "mathematics")
+		      (:url . "https://github.com/vspinu/math-symbol-lists"))])
+ (memory-usage .
+	       [(0 2)
+		nil "Analyze the memory usage of Emacs in various ways" single
+		((:url . "http://elpa.gnu.org/packages/memory-usage.html")
+		 (:keywords "maint"))])
+ (metar .
+	[(0 3)
+	 ((cl-lib
+	   (0 5)))
+	 "Retrieve and decode METAR weather information" single
+	 ((:url . "http://elpa.gnu.org/packages/metar.html")
+	  (:keywords "comm"))])
+ (midi-kbd .
+	   [(0 2)
+	    ((emacs
+	      (25)))
+	    "Create keyboard events from Midi input" single
+	    ((:url . "http://elpa.gnu.org/packages/midi-kbd.html")
+	     (:keywords "convenience" "hardware" "multimedia"))])
+ (mines .
+	[(1 6)
+	 ((emacs
+	   (24 4))
+	  (cl-lib
+	   (0 5)))
+	 "Minesweeper game" tar
+	 ((:keywords "games")
+	  (:url . "https://github.com/calancha/Minesweeper"))])
+ (minibuffer-line .
+		  [(0 1)
+		   nil "Display status info in the minibuffer window" single
+		   ((:url . "http://elpa.gnu.org/packages/minibuffer-line.html")
+		    (:keywords))])
+ (minimap .
+	  [(1 2)
+	   nil "Sidebar showing a \"mini-map\" of a buffer" single
+	   ((:url . "http://elpa.gnu.org/packages/minimap.html")
+	    (:keywords))])
+ (mmm-mode .
+	   [(0 5 7)
+	    ((cl-lib
+	      (0 2)))
+	    "Allow Multiple Major Modes in a buffer" tar
+	    ((:keywords "convenience" "faces" "languages" "tools")
+	     (:url . "https://github.com/purcell/mmm-mode"))])
+ (multishell .
+	     [(1 1 5)
+	      ((cl-lib
+		(0 5)))
+	      "Easily use multiple shell buffers, local and remote" tar
+	      ((:keywords "processes")
+	       (:url . "https://github.com/kenmanheimer/EmacsMultishell"))])
+ (muse .
+       [(3 20 2)
+	nil "Authoring and publishing tool for Emacs" tar
+	((:keywords "hypermedia")
+	 (:url . "http://mwolson.org/projects/EmacsMuse.html"))])
+ (myers .
+	[(0 1)
+	 ((emacs
+	   (25)))
+	 "Random-access singly-linked lists" single
+	 ((:url . "http://elpa.gnu.org/packages/myers.html")
+	  (:keywords "list" "containers"))])
+ (nameless .
+	   [(1 0 2)
+	    ((emacs
+	      (24 4)))
+	    "Hide package namespace in your emacs-lisp code" single
+	    ((:url . "https://github.com/Malabarba/nameless")
+	     (:keywords "convenience" "lisp"))])
+ (names .
+	[(20151201 0)
+	 ((emacs
+	   (24 1))
+	  (cl-lib
+	   (0 5)))
+	 "Namespaces for emacs-lisp. Avoid name clobbering without hiding symbols." tar
+	 ((:keywords "extensions" "lisp")
+	  (:url . "https://github.com/Malabarba/names"))])
+ (nhexl-mode .
+	     [(0 9)
+	      ((emacs
+		(24 4))
+	       (cl-lib
+		(0 5)))
+	      "Minor mode to edit files via hex-dump format" single
+	      ((:url . "http://elpa.gnu.org/packages/nhexl-mode.html")
+	       (:keywords "data"))])
+ (nlinum .
+	 [(1 8 1)
+	  nil "Show line numbers in the margin" single
+	  ((:url . "http://elpa.gnu.org/packages/nlinum.html")
+	   (:keywords "convenience"))])
+ (notes-mode .
+	     [(1 30)
+	      nil "Indexing system for on-line note-taking" tar
+	      ((:url . "http://elpa.gnu.org/packages/notes-mode.html"))])
+ (ntlm .
+       [(2 1 0)
+	nil "NTLM (NT LanManager) authentication support" single
+	((:url . "http://elpa.gnu.org/packages/ntlm.html")
+	 (:keywords "ntlm" "sasl" "comm"))])
+ (num3-mode .
+	    [(1 3)
+	     nil "highlight groups of digits in long numbers" single
+	     ((:url . "http://elpa.gnu.org/packages/num3-mode.html")
+	      (:keywords "faces" "minor-mode"))])
+ (oauth2 .
+	 [(0 11)
+	  nil "OAuth 2.0 Authorization Protocol" single
+	  ((:url . "http://elpa.gnu.org/packages/oauth2.html")
+	   (:keywords "comm"))])
+ (omn-mode .
+	   [(1 2)
+	    nil "Support for OWL Manchester Notation" single
+	    ((:url . "http://elpa.gnu.org/packages/omn-mode.html")
+	     (:keywords))])
+ (on-screen .
+	    [(1 3 2)
+	     ((cl-lib
+	       (0)))
+	     "guide your eyes while scrolling" single
+	     ((:url . "https://github.com/michael-heerdegen/on-screen.el")
+	      (:keywords "convenience"))])
+ (org .
+      [(9 1 14)
+       nil "Outline-based notes management and organizer" tar
+       ((:keywords "outlines" "hypermedia" "calendar" "wp")
+	(:url . "http://elpa.gnu.org/packages/org.html"))])
+ (org-edna .
+	   [(1 0 -2 6)
+	    ((emacs
+	      (25 1))
+	     (seq
+	      (2 19))
+	     (org
+	      (9 0 5)))
+	    "Extensible Dependencies 'N' Actions" tar
+	    ((:keywords "convenience" "text" "org")
+	     (:url . "https://savannah.nongnu.org/projects/org-edna-el/"))])
+ (orgalist .
+	   [(1 8)
+	    ((emacs
+	      (24 4)))
+	    "Manage Org-like lists in non-Org buffers" single
+	    ((:url . "http://elpa.gnu.org/packages/orgalist.html")
+	     (:keywords "convenience"))])
+ (osc .
+      [(0 1)
+       nil "Open Sound Control protocol library" single
+       ((:url . "http://elpa.gnu.org/packages/osc.html")
+	(:keywords "comm" "processes" "multimedia"))])
+ (other-frame-window .
+		     [(1 0 6)
+		      ((emacs
+			(24 4)))
+		      "Minor mode to enable global prefix keys for other frame/window buffer placement" single
+		      ((:url . "http://elpa.gnu.org/packages/other-frame-window.html")
+		       (:keywords "frame" "window"))])
+ (pabbrev .
+	  [(4 2 1)
+	   nil "Predictive abbreviation expansion" single
+	   ((:url . "http://elpa.gnu.org/packages/pabbrev.html")
+	    (:keywords))])
+ (paced .
+	[(1 1 3)
+	 ((emacs
+	   (25 1))
+	  (async
+	   (1 9 1)))
+	 "Predictive Abbreviation Completion and Expansion using Dictionaries" tar
+	 ((:keywords "convenience" "completion")
+	  (:url . "https://savannah.nongnu.org/projects/paced-el/"))])
+ (parsec .
+	 [(0 1 3)
+	  ((emacs
+	    (24))
+	   (cl-lib
+	    (0 5)))
+	  "Parser combinator library" tar
+	  ((:keywords "extensions")
+	   (:url . "https://github.com/cute-jumper/parsec.el"))])
+ (pinentry .
+	   [(0 1)
+	    nil "GnuPG Pinentry server implementation" single
+	    ((:url . "http://elpa.gnu.org/packages/pinentry.html")
+	     (:keywords "gnupg"))])
+ (poker .
+	[(0 2)
+	 nil "Texas hold 'em poker" single
+	 ((:url . "http://elpa.gnu.org/packages/poker.html")
+	  (:keywords "games"))])
+ (posframe .
+	   [(0 3 0)
+	    ((emacs
+	      (26)))
+	    "Pop a posframe (just a frame) at point" single
+	    ((:url . "https://github.com/tumashu/posframe")
+	     (:keywords "tooltip"))])
+ (psgml .
+	[(1 3 4)
+	 nil "SGML-editing mode with parsing support" tar
+	 ((:keywords "languages")
+	  (:url . "http://elpa.gnu.org/packages/psgml.html"))])
+ (python .
+	 [(0 26 1)
+	  ((emacs
+	    (24 1))
+	   (cl-lib
+	    (1 0)))
+	  "Python's flying circus support for Emacs" single
+	  ((:url . "https://github.com/fgallina/python.el")
+	   (:keywords "languages"))])
+ (quarter-plane .
+		[(0 1)
+		 nil "Minor mode for quarter-plane style editing" single
+		 ((:url . "http://elpa.gnu.org/packages/quarter-plane.html")
+		  (:keywords "convenience" "wp"))])
+ (queue .
+	[(0 2)
+	 nil "Queue data structure" single
+	 ((:url . "http://www.dr-qubit.org/emacs.php")
+	  (:keywords "extensions" "data structures" "queue"))])
+ (rainbow-mode .
+	       [(1 0 1)
+		nil "Colorize color names in buffers" single
+		((:url . "http://elpa.gnu.org/packages/rainbow-mode.html")
+		 (:keywords "faces"))])
+ (rbit .
+       [(0 1)
+	nil "Red-black persistent interval trees" single
+	((:url . "http://elpa.gnu.org/packages/rbit.html")
+	 (:keywords "data structures" "binary tree" "intervals"))])
+ (rcirc-color .
+	      [(0 4 1)
+	       ((emacs
+		 (24 4)))
+	       "color nicks" single
+	       ((:url . "http://elpa.gnu.org/packages/rcirc-color.html")
+		(:keywords "comm"))])
+ (rcirc-menu .
+	     [(1 1)
+	      nil "A menu of all your rcirc connections" single
+	      ((:url . "http://elpa.gnu.org/packages/rcirc-menu.html")
+	       (:keywords "comm"))])
+ (realgud .
+	  [(1 4 5)
+	   ((load-relative
+	     (1 2))
+	    (loc-changes
+	     (1 2))
+	    (test-simple
+	     (1 2 0))
+	    (cl-lib
+	     (0 5))
+	    (emacs
+	     (24)))
+	   "A modular front-end for interacting with external debuggers" tar
+	   ((:keywords "gdb" "python" "perl" "go" "bash" "nodejs" "zsh" "bashdb" "zshdb" "remake" "make" "trepan" "perldb" "pdb")
+	    (:url . "http://github.com/realgud/realgud/"))])
+ (register-list .
+		[(0 1)
+		 nil "Interactively list/edit registers" single
+		 ((:url . "http://elpa.gnu.org/packages/register-list.html")
+		  (:keywords "register"))])
+ (rich-minority .
+		[(1 0 1)
+		 ((cl-lib
+		   (0 5)))
+		 "Clean-up and Beautify the list of minor-modes." single
+		 ((:url . "https://github.com/Malabarba/rich-minority")
+		  (:keywords "mode-line" "faces"))])
+ (rnc-mode .
+	   [(0 2)
+	    nil "Emacs mode to edit Relax-NG Compact files" single
+	    ((:url . "http://elpa.gnu.org/packages/rnc-mode.html")
+	     (:keywords "xml" "relaxng"))])
+ (rudel .
+	[(0 3 1)
+	 ((emacs
+	   (24))
+	  (cl-lib
+	   (0 5))
+	  (cl-generic
+	   (0 3)))
+	 "A collaborative editing framework for Emacs" tar
+	 ((:keywords "rudel" "collaboration")
+	  (:url . "http://rudel.sourceforge.net/"))])
+ (scroll-restore .
+		 [(1 0)
+		  nil "restore original position after scrolling" single
+		  ((:url . "http://elpa.gnu.org/packages/scroll-restore.html")
+		   (:keywords "scrolling"))])
+ (sed-mode .
+	   [(1 0)
+	    nil "Major mode to edit sed scripts" single
+	    ((:url . "http://elpa.gnu.org/packages/sed-mode.html")
+	     (:keywords))])
+ (seq .
+      [(2 20)
+       nil "Sequence manipulation functions" tar
+       ((:keywords "sequences")
+	(:url . "http://elpa.gnu.org/packages/seq.html"))])
+ (shen-mode .
+	    [(0 1)
+	     nil "A major mode for editing shen source code" tar
+	     ((:keywords "languages" "shen")
+	      (:url . "http://elpa.gnu.org/packages/shen-mode.html"))])
+ (sisu-mode .
+	    [(7 1 8)
+	     nil "Major mode for SiSU markup text" single
+	     ((:url . "http://www.sisudoc.org/")
+	      (:keywords "text" "syntax" "processes" "tools"))])
+ (smart-yank .
+	     [(0 1 1)
+	      ((emacs
+		(24)))
+	      "A different approach of yank pointer handling" single
+	      ((:url . "http://elpa.gnu.org/packages/smart-yank.html")
+	       (:keywords "convenience"))])
+ (sml-mode .
+	   [(6 8)
+	    ((emacs
+	      (24))
+	     (cl-lib
+	      (0 5)))
+	    "Major mode for editing (Standard) ML" single
+	    ((:url . "http://elpa.gnu.org/packages/sml-mode.html")
+	     (:keywords "sml"))])
+ (soap-client .
+	      [(3 1 4)
+	       ((cl-lib
+		 (0 6 1)))
+	       "Access SOAP web services" tar
+	       ((:keywords "soap" "web-services" "comm" "hypermedia")
+		(:url . "http://elpa.gnu.org/packages/soap-client.html"))])
+ (sokoban .
+	  [(1 4 6)
+	   ((emacs
+	     (23 1)))
+	   "Implementation of Sokoban for Emacs." tar
+	   ((:keywords "games")
+	    (:url . "http://elpa.gnu.org/packages/sokoban.html"))])
+ (sotlisp .
+	  [(1 6 2)
+	   ((emacs
+	     (24 1)))
+	   "Write lisp at the speed of thought." single
+	   ((:url . "https://github.com/Malabarba/speed-of-thought-lisp")
+	    (:keywords "convenience" "lisp"))])
+ (spinner .
+	  [(1 7 3)
+	   nil "Add spinners and progress-bars to the mode-line for ongoing operations" single
+	   ((:url . "https://github.com/Malabarba/spinner.el")
+	    (:keywords "processes" "mode-line"))])
+ (sql-indent .
+	     [(1 2)
+	      ((cl-lib
+		(0 5)))
+	      "Support for indenting code in SQL files." tar
+	      ((:keywords "languages" "sql")
+	       (:url . "http://elpa.gnu.org/packages/sql-indent.html"))])
+ (stream .
+	 [(2 2 4)
+	  ((emacs
+	    (25)))
+	  "Implementation of streams" tar
+	  ((:keywords "stream" "laziness" "sequences")
+	   (:url . "http://elpa.gnu.org/packages/stream.html"))])
+ (svg .
+      [(0 1)
+       ((emacs
+	 (25)))
+       "svg image creation functions" single
+       ((:url . "http://elpa.gnu.org/packages/svg.html")
+	(:keywords "image"))])
+ (svg-clock .
+	    [(1 0)
+	     ((svg
+	       (0 1))
+	      (emacs
+	       (25 0)))
+	     "Analog clock using Scalable Vector Graphics" single
+	     ((:url . "http://elpa.gnu.org/packages/svg-clock.html")
+	      (:keywords "demo" "svg" "clock"))])
+ (tNFA .
+       [(0 1 1)
+	((queue
+	  (0 1)))
+	"Tagged non-deterministic finite-state automata" single
+	((:url . "http://www.dr-qubit.org/emacs.php")
+	 (:keywords "extensions" "matching" "data structures tnfa" "nfa" "dfa" "finite state automata" "automata" "regexp"))])
+ (temp-buffer-browse .
+		     [(1 5)
+		      ((emacs
+			(24)))
+		      "temp buffer browse mode" single
+		      ((:url . "http://elpa.gnu.org/packages/temp-buffer-browse.html")
+		       (:keywords "convenience"))])
+ (test-simple .
+	      [(1 3 0)
+	       ((cl-lib
+		 (0)))
+	       "Simple Unit Test Framework for Emacs Lisp" single
+	       ((:url . "http://github.com/rocky/emacs-test-simple")
+		(:keywords "unit-test"))])
+ (timerfunctions .
+		 [(1 4 2)
+		  ((cl-lib
+		    (0 5)))
+		  "Enhanced versions of some timer.el functions" single
+		  ((:url . "http://elpa.gnu.org/packages/timerfunctions.html")
+		   (:keywords))])
+ (tiny .
+       [(0 2 1)
+	nil "Quickly generate linear ranges in Emacs" tar
+	((:keywords "convenience")
+	 (:url . "https://github.com/abo-abo/tiny"))])
+ (tramp-theme .
+	      [(0 2)
+	       ((emacs
+		 (24 1)))
+	       "Custom theme for remote buffers" single
+	       ((:url . "http://elpa.gnu.org/packages/tramp-theme.html")
+		(:keywords "convenience" "faces"))])
+ (transcribe .
+	     [(1 5 2)
+	      nil "Package for audio transcriptions" single
+	      ((:url . "http://elpa.gnu.org/packages/transcribe.html")
+	       (:keywords))])
+ (trie .
+       [(0 4)
+	((tNFA
+	  (0 1 1))
+	 (heap
+	  (0 3)))
+	"Trie data structure" single
+	((:url . "http://www.dr-qubit.org/emacs.php")
+	 (:keywords "extensions" "matching" "data structures trie" "ternary search tree" "tree" "completion" "regexp"))])
+ (undo-tree .
+	    [(0 6 5)
+	     nil "Treat undo history as a tree" single
+	     ((:url . "http://www.dr-qubit.org/emacs.php")
+	      (:keywords "convenience" "files" "undo" "redo" "history" "tree"))])
+ (uni-confusables .
+		  [(0 1)
+		   nil "Unicode confusables table" tar
+		   ((:url . "http://elpa.gnu.org/packages/uni-confusables.html"))])
+ (url-http-ntlm .
+		[(2 0 4)
+		 ((cl-lib
+		   (0 5))
+		  (ntlm
+		   (2 1 0)))
+		 "NTLM authentication for the url library" single
+		 ((:url . "http://elpa.gnu.org/packages/url-http-ntlm.html")
+		  (:keywords "comm" "data" "processes" "hypermedia"))])
+ (validate .
+	   [(1 0 4)
+	    ((emacs
+	      (24 1))
+	     (cl-lib
+	      (0 5))
+	     (seq
+	      (2 16)))
+	    "Schema validation for Emacs-lisp" single
+	    ((:url . "http://elpa.gnu.org/packages/validate.html")
+	     (:keywords "lisp"))])
+ (vdiff .
+	[(0 2 3)
+	 ((emacs
+	   (24 4))
+	  (hydra
+	   (0 13 0)))
+	 "A diff tool similar to  vimdiff" single
+	 ((:url . "https://github.com/justbur/emacs-vdiff")
+	  (:keywords "diff"))])
+ (vigenere .
+	   [(1 0)
+	    ((emacs
+	      (25 1)))
+	    "Run a vigenere cipher on a block of text ;" single
+	    ((:url . "https://elpa.gnu.org/packages/vigenere.html")
+	     (:keywords "data" "vigenere" "cipher"))])
+ (vlf .
+      [(1 7 1)
+       nil "View Large Files" tar
+       ((:keywords "large files" "utilities")
+	(:url . "https://github.com/m00natic/vlfi"))])
+ (w3 .
+     [(4 0 49)
+      nil "Fully customizable, largely undocumented web browser for Emacs" tar
+      ((:keywords "faces" "help" "comm" "news" "mail" "processes" "mouse" "hypermedia")
+       (:url . "http://elpa.gnu.org/packages/w3.html"))])
+ (wcheck-mode .
+	      [(2016 1 30)
+	       nil "General interface for text checkers" single
+	       ((:url . "https://github.com/tlikonen/wcheck-mode")
+		(:keywords "text" "spell" "check" "languages" "ispell"))])
+ (wconf .
+	[(0 2 1)
+	 ((emacs
+	   (24 4)))
+	 "Minimal window layout manager" single
+	 ((:url . "https://github.com/ilohmar/wconf")
+	  (:keywords "windows" "frames" "layout"))])
+ (web-server .
+	     [(0 1 1)
+	      ((emacs
+		(24 3)))
+	      "Emacs Web Server" tar
+	      ((:keywords "http" "server" "network")
+	       (:url . "https://github.com/eschulte/emacs-web-server"))])
+ (websocket .
+	    [(1 8)
+	     ((cl-lib
+	       (0 5)))
+	     "Emacs WebSocket client and server" tar
+	     ((:keywords "communication" "websocket" "server")
+	      (:url . "http://elpa.gnu.org/packages/websocket.html"))])
+ (which-key .
+	    [(3 3 0)
+	     ((emacs
+	       (24 4)))
+	     "Display available keybindings in popup" tar
+	     ((:url . "https://github.com/justbur/emacs-which-key"))])
+ (windresize .
+	     [(0 1)
+	      nil "Resize windows interactively" single
+	      ((:url . "http://elpa.gnu.org/packages/windresize.html")
+	       (:keywords "window"))])
+ (wisi .
+       [(1 1 6)
+	((cl-lib
+	  (0 4))
+	 (emacs
+	  (24 3)))
+	"Utilities for implementing an indentation/navigation engine using a generalized LALR parser" tar
+	((:keywords "parser" "indentation" "navigation")
+	 (:url . "http://www.nongnu.org/ada-mode/wisi/wisi.html"))])
+ (wpuzzle .
+	  [(1 1)
+	   nil "find as many word in a given time" single
+	   ((:url . "http://elpa.gnu.org/packages/wpuzzle.html")
+	    (:keywords))])
+ (xclip .
+	[(1 4)
+	 nil "Copy&paste GUI clipboard from text terminal" single
+	 ((:url . "http://elpa.gnu.org/packages/xclip.html")
+	  (:keywords "convenience" "tools"))])
+ (xelb .
+       [(0 15)
+	((emacs
+	  (24 4))
+	 (cl-generic
+	  (0 2)))
+	"X protocol Emacs Lisp Binding" tar
+	((:keywords "unix")
+	 (:url . "https://github.com/ch11ng/xelb"))])
+ (xpm .
+      [(1 0 4)
+       nil "edit XPM images" tar
+       ((:keywords "multimedia" "xpm")
+	(:url . "http://www.gnuvola.org/software/xpm/"))])
+ (yasnippet .
+	    [(0 13 0)
+	     ((cl-lib
+	       (0 5)))
+	     "Yet another snippet extension for Emacs." tar
+	     ((:keywords "convenience" "emulation")
+	      (:url . "http://github.com/joaotavora/yasnippet"))])
+ (yasnippet-classic-snippets .
+			     [(1 0 2)
+			      ((yasnippet
+				(0 9 1)))
+			      "\"Classic\" yasnippet snippets" tar
+			      ((:keywords "snippets")
+			       (:url . "http://elpa.gnu.org/packages/yasnippet-classic-snippets.html"))])
+ (ztree .
+	[(1 0 5)
+	 ((cl-lib
+	   (0)))
+	 "Text mode directory tree" tar
+	 ((:keywords "files" "tools")
+	  (:url . "https://github.com/fourier/ztree"))]))
diff --git a/configs/shared/emacs/.emacs.d/elpa/archives/gnu/archive-contents.signed b/configs/shared/emacs/.emacs.d/elpa/archives/gnu/archive-contents.signed
new file mode 100644
index 0000000000..b422b21e07
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/archives/gnu/archive-contents.signed
@@ -0,0 +1 @@
+Good signature from 474F05837FBDEF9B GNU ELPA Signing Agent <elpasign@elpa.gnu.org> (trust undefined) created at 2018-07-20T05:10:02-0400 using DSA
\ No newline at end of file
diff --git a/configs/shared/emacs/.emacs.d/elpa/archives/melpa/archive-contents b/configs/shared/emacs/.emacs.d/elpa/archives/melpa/archive-contents
new file mode 100644
index 0000000000..4b6a6f590d
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/archives/melpa/archive-contents
@@ -0,0 +1,2 @@
+
+(1 (zzz-to-char . [(20180101 619) ((emacs (24 4)) (cl-lib (0 5)) (avy (0 3 0))) "Fancy version of `zap-to-char' command" single ((:commit . "db8d9e660ad18a15159779efe34d7a98ef0df535") (:keywords "convenience") (:authors ("Mark Karpov" . "markkarpov92@gmail.com")) (:maintainer "Mark Karpov" . "markkarpov92@gmail.com") (:url . "https://github.com/mrkkrp/zzz-to-char"))]) (zygospore . [(20140703 852) nil "reversible C-x 1 (delete-other-windows)" single ((:commit . "1af5ee663f5a7aa08d96a77cacff834dcdf55ea8") (:authors ("Louis Kottmann" . "louis.kottmann@gmail.com")) (:maintainer "Louis Kottmann" . "louis.kottmann@gmail.com") (:url . "https://github.com/louiskottmann/zygospore.el"))]) (zweilight-theme . [(20170113 605) nil "A dark color theme for Emacs." single ((:commit . "7f45ab9e23164d65538edb2beb9692ecdc24c31e") (:authors ("Philip Arvidsson" . "contact@philiparvidsson.com")) (:maintainer "Philip Arvidsson" . "contact@philiparvidsson.com") (:url . "http://github.com/philiparvidsson/zweilight-emacs"))]) (ztree . [(20180512 1850) ((cl-lib (0))) "Text mode directory tree" tar ((:commit . "c54425a094353ec40a8179f9eab3596f76c6cf94") (:keywords "files" "tools") (:authors ("Alexey Veretennikov" . "alexey.veretennikov@gmail.com")) (:maintainer "Alexey Veretennikov" . "alexey.veretennikov@gmail.com") (:url . "https://github.com/fourier/ztree"))]) (zpresent . [(20180605 438) ((emacs (25 1)) (org-parser (0 4)) (dash (2 12 0)) (request (0 3 0))) "Simple presentation mode based on org files." single ((:keywords "comm") (:url . "https://bitbucket.org/zck/zpresent.el"))]) (zoutline . [(20180314 1759) nil "Simple outline library." single ((:commit . "b3ee0f0e0b916838c2d2c249beba74ffdb8d5699") (:keywords "outline") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:url . "https://github.com/abo-abo/zoutline"))]) (zotxt . [(20180518 147) ((request-deferred (0 2 0))) "Tools to integrate emacs with Zotero via the zotxt plugin." tar ((:commit . "23a4a9f74a658222027d53a9a83cd4bcc583ca8b"))]) (zotelo . [(20160602 949) ((cl-lib (0 5))) "Manage Zotero collections from emacs" single ((:commit . "d9dc089b9adfcc70a63f2a84269a12eb7cb4c748") (:keywords "zotero" "emacs" "reftex" "bibtex" "mozrepl" "bibliography manager") (:authors ("Spinu Vitalie")) (:maintainer "Spinu Vitalie") (:url . "https://github.com/vitoshka/zotelo"))]) (zossima . [(20121124 35) ((inf-ruby (2 2 3))) "Ruby from Emacs" tar ((:commit . "991676635c374d2a12714dcf48c1ce2d6f97a375") (:keywords "ruby" "convenience") (:authors ("Phil Hagelberg")) (:maintainer "Phil Hagelberg") (:url . "https://github.com/technomancy/zossima"))]) (zop-to-char . [(20160212 1554) ((cl-lib (0 5))) "A replacement of zap-to-char." single ((:commit . "00152aa666354b27e56e20565f186b363afa0dce") (:authors ("Thierry Volpiatto" . "thierry.volpiatto@gmail.com")) (:maintainer "Thierry Volpiatto" . "thierry.volpiatto@gmail.com") (:url . "https://github.com/thierryvolpiatto/zop-to-char"))]) (zoom-window . [(20170302 827) ((emacs (24 3))) "Zoom window like tmux" single ((:commit . "cd6ecc103fc30b171bda7daf1f44a550854d0dbf") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-zoom-window"))]) (zoom . [(20180310 1221) ((emacs (24 4))) "Fixed and automatic balanced window layout" single ((:commit . "2cdb15c9e753222c8600120edecfb46c2fbfae5d") (:keywords "frames") (:authors ("Andrea Cardaci" . "cyrus.and@gmail.com")) (:maintainer "Andrea Cardaci" . "cyrus.and@gmail.com") (:url . "https://github.com/cyrus-and/zoom"))]) (zone-sl . [(20160201 1210) ((emacs (24 3))) "Zone out with steam locomotives." single ((:commit . "7ec22e3661c6348382f9fc39a9d0063dbd2352ff") (:keywords "games") (:authors ("KAWABATA, Taichi <kawabata.taichi_at_gmail.com>")) (:maintainer "KAWABATA, Taichi <kawabata.taichi_at_gmail.com>") (:url . "https://github.com/kawabata/zone-sl"))]) (zone-select . [(20160118 1419) ((emacs (24 3)) (dash (2 8))) "Select zone programs." single ((:commit . "bf30da12f1625fe6563448fccf3c506acad10af7") (:keywords "games") (:authors ("KAWABATA, Taichi <kawabata.taichi_at_gmail.com>")) (:maintainer "KAWABATA, Taichi <kawabata.taichi_at_gmail.com>") (:url . "https://github.com/kawabata/zone-select"))]) (zone-rainbow . [(20160120 1334) ((emacs (24 3))) "Zone out with rainbow." single ((:commit . "2ba4f1a87c69c4712124ebf12c1f3ea171e1af36") (:keywords "games") (:authors ("KAWABATA, Taichi <kawabata.taichi_at_gmail.com>")) (:maintainer "KAWABATA, Taichi <kawabata.taichi_at_gmail.com>") (:url . "https://github.com/kawabata/zone-rainbow"))]) (zone-nyan . [(20170818 1644) ((esxml (0 3 1))) "Zone out with nyan cat" single ((:commit . "4b1f8d95f130946718d52806489ffe2762aebfdc") (:keywords "zone") (:authors ("Vasilij Schneidermann" . "v.schneidermann@gmail.com")) (:maintainer "Vasilij Schneidermann" . "v.schneidermann@gmail.com") (:url . "https://github.com/wasamasa/zone-nyan"))]) (zombie-trellys-mode . [(20150304 1448) ((emacs (24)) (cl-lib (0 5)) (haskell-mode (1 5))) "A minor mode for interaction with Zombie Trellys" single ((:commit . "7f0c45fdda3a44c3b6d1762d116abb1421b8fba2") (:keywords "languages") (:authors ("David Raymond Christiansen" . "david@davidchristiansen.dk")) (:maintainer "David Raymond Christiansen" . "david@davidchristiansen.dk"))]) (zombie . [(20141222 1616) nil "major mode for editing ZOMBIE programs" single ((:commit . "ff8cd1b4cdbb4b0b9b8fd1ec8f6fb93eba249345") (:authors ("zk_phi")) (:maintainer "zk_phi") (:url . "http://hins11.yu-yake.com/"))]) (znc . [(20160627 2032) ((cl-lib (0 2))) "ZNC + ERC" single ((:commit . "ce468d185e4a949c45fdd7586313144bc69d4fe5") (:authors ("Yaroslav Shirokov")) (:maintainer "Yaroslav Shirokov") (:url . "https://github.com/sshirokov/ZNC.el"))]) (zlc . [(20151011 157) nil "Provides zsh like completion system to Emacs" single ((:commit . "4dd2ba267ecdeac845a7cbb3147294ee7daa25f4") (:keywords "matching" "convenience") (:authors ("mooz" . "stillpedant@gmail.com")) (:maintainer "mooz" . "stillpedant@gmail.com"))]) (zig-mode . [(20180818 1548) ((emacs (24))) "A major mode for the Zig programming language" single ((:commit . "f26f5d07a9e815bbf41a5410827c9544ade5f71b") (:keywords "zig" "languages") (:authors ("Andrea Orru <andreaorru1991@gmail.com>, Andrew Kelley" . "superjoe30@gmail.com")) (:maintainer "Andrea Orru <andreaorru1991@gmail.com>, Andrew Kelley" . "superjoe30@gmail.com") (:url . "https://github.com/zig-lang/zig-mode"))]) (zerodark-theme . [(20180824 958) ((all-the-icons (2 0 0)) (magit (2 8 0)) (flycheck (29))) "A dark, medium contrast theme for Emacs" single ((:commit . "2391e094bf4e44bf7ec37e17456aae7df1bcd8fb") (:keywords "themes") (:authors ("Nicolas Petton" . "nicolas@petton.fr")) (:maintainer "Nicolas Petton" . "nicolas@petton.fr") (:url . "https://github.com/NicolasPetton/zerodark-theme"))]) (zephir-mode . [(20170918 425) ((cl-lib (0 5)) (pkg-info (0 4)) (emacs (24 3))) "Major mode for editing Zephir code" single ((:commit . "c2c6b7451667e68e29c353616f54ef9195c3fffd") (:keywords "languages") (:authors ("Serghei Iakovlev" . "serghei@phalconphp.com")) (:maintainer "Serghei Iakovlev") (:url . "https://github.com/sergeyklay/zephir-mode"))]) (zeno-theme . [(20180901 222) ((emacs (24))) "A dark theme using different shades of blue" single ((:commit . "6d70168fcae333a9918c5315e6576f1e876874da") (:keywords "faces" "theme" "dark" "blue") (:authors ("Bharat Joshi" . "jbharat@outlook.com")) (:maintainer "Bharat Joshi" . "jbharat@outlook.com") (:url . "https://github.com/jbharat/zeno-theme"))]) (zenity-color-picker . [(20160302 1154) ((emacs (24 4))) "Insert and adjust colors using Zenity" single ((:commit . "4f4f46676a461ebc881487fb70c8c181e323db5e") (:keywords "colors") (:authors ("Samuel Laurén" . "samuel.lauren@iki.fi")) (:maintainer "Samuel Laurén" . "samuel.lauren@iki.fi") (:url . "https://bitbucket.org/Soft/zenity-color-picker.el"))]) (zencoding-mode . [(20140213 822) nil "Unfold CSS-selector-like expressions to markup" single ((:commit . "58e42af182c98cb9941d27cd042d227fbf4e146c") (:keywords "convenience") (:authors ("Chris Done" . "chrisdone@gmail.com")) (:maintainer "Chris Done" . "chrisdone@gmail.com") (:url . "https://github.com/rooney/zencoding"))]) (zenburn-theme . [(20180901 848) nil "A low contrast color theme for Emacs." single ((:commit . "f23a5ca9e2fd952ea4499746d0f5096f3842e989") (:authors ("Bozhidar Batsov" . "bozhidar@batsov.com")) (:maintainer "Bozhidar Batsov" . "bozhidar@batsov.com") (:url . "http://github.com/bbatsov/zenburn-emacs"))]) (zen-and-art-theme . [(20120622 1437) nil "zen and art color theme for GNU Emacs 24" single ((:commit . "a7226cbce0bca2501d69a620cb2aeabfc396c232") (:authors ("Nick Parker")) (:maintainer "Nick Parker"))]) (zel . [(20171014 832) ((emacs (25)) (frecency (0 1))) "Access frecent files easily" single ((:commit . "9dae2d212224d1deae1f62561fa8e4d689fd09f2") (:keywords "convenience" "files" "matching") (:authors ("Sebastian Christ" . "rudolfo.christ@gmail.com")) (:maintainer "Sebastian Christ" . "rudolfo.christ@gmail.com") (:url . "https://github.com/rudolfochrist/zel"))]) (zeal-at-point . [(20180131 2354) nil "Search the word at point with Zeal" single ((:commit . "0fc3263f44e95acd3e9d91057677621ce4d297ee") (:authors ("Jinzhu" . "wosmvp@gmail.com")) (:maintainer "Jinzhu" . "wosmvp@gmail.com") (:url . "https://github.com/jinzhu/zeal-at-point"))]) (z3-mode . [(20151120 2255) ((flycheck (0 23)) (emacs (24))) "A z3/SMTLIBv2 interactive development environment" single ((:commit . "163dc01d59e9880b4dc188d4e1ad84d6c0c852e1") (:keywords "z3" "yices" "mathsat" "smt" "beaver") (:authors ("Zephyr Pellerin" . "zephyr.pellerin@gmail.com")) (:maintainer "Zephyr Pellerin" . "zephyr.pellerin@gmail.com") (:url . "https://github.com/zv/z3-mode"))]) (youdao-dictionary . [(20180714 414) ((popup (0 5 0)) (pos-tip (0 4 6)) (chinese-word-at-point (0 2)) (names (0 5)) (emacs (24))) "Youdao Dictionary interface for Emacs" single ((:commit . "9496ea3ba8aa999db3dbde88d6aa37f3579d8dea") (:keywords "convenience" "chinese" "dictionary") (:authors ("Chunyang Xu" . "xuchunyang56@gmail.com")) (:maintainer "Chunyang Xu" . "xuchunyang56@gmail.com") (:url . "https://github.com/xuchunyang/youdao-dictionary.el"))]) (yoshi-theme . [(20170330 700) nil "Theme named after my cat" single ((:commit . "eab4fb67e8fec47c25c4c1393ac1211f043dbd44") (:keywords "faces") (:authors ("Tom Willemse" . "tom@ryuslash.org")) (:maintainer "Tom Willemse" . "tom@ryuslash.org") (:url . "http://projects.ryuslash.org/yoshi-theme/"))]) (yoficator . [(20180815 4) nil "Interactively yoficate Russian texts" tar ((:commit . "92d96a342a1ce29500891b71372c515c158ea0d9") (:authors ("Eugene Minkovskii" . "emin@mccme.ru") ("Alexander Krotov" . "ilabdsf@gmail.com")) (:maintainer "Eugene Minkovskii" . "emin@mccme.ru") (:url . "https://gitlab.com/link2xt/yoficator"))]) (yesql-ghosts . [(20150220 1237) ((s (1 9 0)) (dash (2 10 0)) (cider (0 8 0))) "Display ghostly yesql defqueries inline" single ((:commit . "8f1faf0137b85a5072d13e1240a463d9a35ce2bb") (:authors ("Magnar Sveen" . "magnars@gmail.com")) (:maintainer "Magnar Sveen" . "magnars@gmail.com"))]) (ydk-mode . [(20170113 921) nil "Language support for Yu-Gi-Oh! deck files" single ((:commit . "f3f125b29408e0b0a34fec27dcb7c02c5dbfd04e") (:keywords "faces" "games" "languages" "ydk" "yugioh" "yu-gi-oh") (:authors ("Jackson Ray Hamilton" . "jackson@jacksonrayhamilton.com")) (:maintainer "Jackson Ray Hamilton" . "jackson@jacksonrayhamilton.com") (:url . "https://github.com/jacksonrayhamilton/ydk-mode"))]) (ycmd . [(20180724 1256) ((emacs (24 4)) (dash (2 13 0)) (s (1 11 0)) (deferred (0 5 1)) (cl-lib (0 6 1)) (let-alist (1 0 5)) (request (0 3 0)) (request-deferred (0 3 0)) (pkg-info (0 6))) "emacs bindings to the ycmd completion server" tar ((:commit . "fe35b7f2e3d9370941b9e537c9bc578d814acce2") (:url . "https://github.com/abingham/emacs-ycmd"))]) (ycm . [(20150822 1836) nil "Emacs client for the YouCompleteMe auto-completion server." single ((:commit . "4da8a14abcd0f4fa3235042ade2e12b5068c0601") (:keywords "c" "abbrev") (:authors ("Ajay Gopinathan" . "ajay@gopinathan.net")) (:maintainer "Ajay Gopinathan" . "ajay@gopinathan.net"))]) (yaxception . [(20150105 1452) nil "Provide framework about exception like Java for Elisp" single ((:commit . "4e94cf3e0b9b5631b0e90eb4b7de597ee7185875") (:keywords "exception" "error" "signal") (:authors ("Hiroaki Otsu" . "ootsuhiroaki@gmail.com")) (:maintainer "Hiroaki Otsu" . "ootsuhiroaki@gmail.com") (:url . "https://github.com/aki2o/yaxception"))]) (yatex . [(20180821 149) nil "Yet Another tex-mode for emacs //野鳥//" tar nil]) (yatemplate . [(20180617 952) ((yasnippet (0 8 1)) (emacs (24 3))) "File templates with yasnippet" tar ((:commit . "4f4fca9f04f7088c98aa195cf33635a35a6055cb") (:keywords "files" "convenience") (:authors ("Wieland Hoffmann" . "themineo+yatemplate@gmail.com")) (:maintainer "Wieland Hoffmann" . "themineo+yatemplate@gmail.com") (:url . "https://github.com/mineo/yatemplate"))]) (yasnippet-snippets . [(20180825 1712) ((yasnippet (0 8 0))) "Collection of yasnippet snippets" tar ((:commit . "a778670f1e5d594e16c756c334ee13737bb87bfb") (:keywords "snippets") (:authors ("Andrea Crotti" . "andrea.crotti.0@gmail.com")) (:maintainer "Andrea Crotti" . "andrea.crotti.0@gmail.com"))]) (yasnippet . [(20180621 50) ((cl-lib (0 5))) "Yet another snippet extension for Emacs." single ((:commit . "1e713608682685d4a9b78519c84e3196e207c353") (:keywords "convenience" "emulation") (:maintainer "Noam Postavsky" . "npostavs@gmail.com") (:url . "http://github.com/joaotavora/yasnippet"))]) (yascroll . [(20170315 1906) ((cl-lib (0 3))) "Yet Another Scroll Bar Mode" single ((:commit . "fe4494e5f4faf2832e665c7de0fed99cdbb39478") (:keywords "convenience") (:authors ("Tomohiro Matsuyama" . "m2ym.pub@gmail.com")) (:maintainer "Tomohiro Matsuyama" . "m2ym.pub@gmail.com"))]) (yarn-mode . [(20170709 1937) ((emacs (24 3))) "Major mode for yarn.lock files." single ((:commit . "998b408d6be05fd1c3a9fd8db6ffaab3bf86d06b") (:keywords "convenience") (:authors ("Nicolás Salas V." . "nikosalas@gmail.com")) (:maintainer "Nicolás Salas V." . "nikosalas@gmail.com") (:url . "https://github.com/anachronic/yarn-mode"))]) (yari . [(20151128 739) nil "Yet Another RI interface for Emacs" single ((:commit . "a2cb9656ee5dfe1fc2ee3854f3079a1c8e85dbe9") (:keywords "tools") (:authors ("Aleksei Gusev" . "aleksei.gusev@gmail.com")) (:maintainer "Aleksei Gusev" . "aleksei.gusev@gmail.com"))]) (yard-mode . [(20170817 1237) nil "Minor mode for Ruby YARD comments" single ((:commit . "ba74a47463b0320ae152bd42a7dd7aeecd7b5748") (:authors ("Kyle Hargraves")) (:maintainer "Kyle Hargraves") (:url . "https://github.com/pd/yard-mode.el"))]) (yara-mode . [(20170720 651) ((emacs (24))) "Major mode for editing yara rule file" single ((:commit . "af5c05b34a29fc1bd73a6d21c82cc76320b33e5c") (:keywords "yara") (:authors (nil . "binjo.cn@gmail.com")) (:maintainer nil . "binjo.cn@gmail.com") (:url . "not distributed yet"))]) (yapfify . [(20180830 733) nil "(automatically) format python buffers using YAPF." single ((:commit . "b858225e1debe6734ee718e5c3c209152652a8b3") (:authors ("Joris Engbers" . "info@jorisengbers.nl")) (:maintainer "Joris Engbers" . "info@jorisengbers.nl") (:url . "https://github.com/JorisE/yapfify"))]) (yankpad . [(20180825 939) ((emacs (24))) "Paste snippets from an org-mode file" single ((:commit . "6a22116057e4110f4d4b446780fe996abfeed2af") (:keywords "abbrev" "convenience") (:authors ("Erik Sjöstrand")) (:maintainer "Erik Sjöstrand") (:url . "http://github.com/Kungsgeten/yankpad"))]) (yang-mode . [(20180306 1207) nil "major mode for editing YANG files" single ((:commit . "340aec635e359609b22f7e94df15af1af2b070f6") (:authors ("Martin Bjorklund" . "mbj4668@gmail.com")) (:maintainer "Martin Bjorklund" . "mbj4668@gmail.com"))]) (yandex-weather . [(20160311 2037) nil "Fetch Yandex Weather forecasts." tar ((:commit . "6f823fd9e04ff9efb2aa65f333079e9f7e6e5b28"))]) (yaml-tomato . [(20151123 753) ((s (1 9))) "copy or show the yaml path currently under cursor." single ((:commit . "f9df1c9bdfcec629b03031b2d2032f9dc533cb14") (:keywords "yaml") (:authors ("qrczeno")) (:maintainer "qrczeno"))]) (yaml-mode . [(20180409 607) ((emacs (24 1))) "Major mode for editing YAML files" single ((:commit . "40067a10ac1360f0b9533f0bbbb2eea128e2574d") (:keywords "data" "yaml") (:authors ("Yoshiki Kurihara" . "clouder@gmail.com") ("Marshall T. Vandegrift" . "llasram@gmail.com")) (:maintainer "Vasilij Schneidermann" . "v.schneidermann@gmail.com"))]) (yalinum . [(20130217 1043) nil "yet another display line numbers." single ((:commit . "d3e0cbe3f4f5ca311e3298e684901d6fea3ad973") (:keywords "convenience" "tools") (:authors ("tm8st" . "tm8st@hotmail.co.jp")) (:maintainer "tm8st" . "tm8st@hotmail.co.jp"))]) (yahtzee . [(20171022 1412) ((emacs (24 3))) "The yahtzee game" single ((:commit . "feeac7c64fc08c10ec0dae3203a6b3fc0bdfa5cd") (:keywords "games") (:authors ("Dimitar Dimitrov" . "mail.mitko@gmail.com")) (:maintainer "Dimitar Dimitrov" . "mail.mitko@gmail.com") (:url . "https://github.com/drdv/yahtzee"))]) (yahoo-weather . [(20170822 2244) ((emacs (24))) "Displays weather information in mode-line" single ((:commit . "a74e29bc81b13efe285b87fa4d0694d75f8e2bb5") (:keywords "weather" "mode-line") (:authors ("DarkSun" . "lujun9972@gmail.com")) (:maintainer "DarkSun" . "lujun9972@gmail.com") (:url . "https://github.com/lujun9972/yahoo-weather-mode"))]) (yagist . [(20160418 508) ((cl-lib (0 3))) "Yet Another Emacs integration for gist.github.com" single ((:commit . "dcdbd84f348414815d02f3da8a6ee0ac271632d4") (:keywords "tools") (:maintainer "Masahiro Hayashi" . "mhayashi1120@gmail.com") (:url . "https://github.com/mhayashi1120/yagist.el"))]) (yafolding . [(20170305 317) nil "Yet another folding extension for Emacs" single ((:commit . "57c015ddd7c3454571c80825bc5391d7a10fa1d7") (:keywords "folding") (:authors ("Zeno Zeng" . "zenoofzeng@gmail.com")) (:maintainer "Zeno Zeng" . "zenoofzeng@gmail.com"))]) (yabin . [(20140206 351) nil "Yet Another Bignum package (A thin wrapper of calc.el)." single ((:commit . "db8c404507560ef9147fcce2b94cd706fbfa03b5") (:keywords "data") (:authors ("Daisuke Kobayashi" . "d5884jp@gmail.com")) (:maintainer "Daisuke Kobayashi" . "d5884jp@gmail.com"))]) (xwidgete . [(20171118 2116) ((emacs (25))) "enhances usability of current xwidget browser" single ((:commit . "e4e8410fe32176df85b46234717824519443fb04") (:keywords "xwidgete" "tools") (:authors ("Tu, Do Hoang" . "tuhdo1710@gmail.com")) (:maintainer "Tu, Do Hoang") (:url . "https://github.com/tuhdo/xwidgete"))]) (xtest . [(20141214 1706) ((cl-lib (0 5))) "Simple Testing with Emacs & ERT" single ((:commit . "2c2bdf32667506dd9ddf6eb311832add616bdf1c") (:keywords "testing" "ert") (:authors ("Mustafa Shameem")) (:maintainer "Mustafa Shameem") (:url . "https://github.com/promethial/xtest"))]) (xterm-keybinder . [(20160523 56) ((emacs (24 3)) (cl-lib (0 5)) (let-alist (1 0 1))) "Let you extra keybinds in xterm/urxvt" tar ((:commit . "b29c4f700b0fa0c9f627f6725b36462b8fab06d6") (:keywords "convenient") (:authors ("Yuta Yamada <cokesboy\"at\"gmail.com>")) (:maintainer "Yuta Yamada <cokesboy\"at\"gmail.com>"))]) (xterm-color . [(20180202 2318) ((cl-lib (0 5))) "ANSI & XTERM 256 color support" single ((:commit . "42374a98f1039e105cad9f16ce585dffc96a3f1c") (:keywords "faces") (:authors (nil . "xristos@sdf.lonestar.org")) (:maintainer nil . "xristos@sdf.lonestar.org") (:url . "https://github.com/atomontage/xterm-color"))]) (xresources-theme . [(20160331 1402) nil "Use your .Xresources as your emacs theme" single ((:commit . "feb0552d31cb54210eabbc1abe32c8ea62841b6f") (:keywords "xresources" "theme") (:authors ("Marten Lienen" . "marten.lienen@gmail.com")) (:maintainer "Marten Lienen" . "marten.lienen@gmail.com"))]) (xref-js2 . [(20170530 826) ((emacs (25)) (js2-mode (20150909))) "Jump to references/definitions using ag & js2-mode's AST" single ((:commit . "d5f93605405989529c2f66b542def6c32429b927") (:keywords "javascript" "convenience" "tools") (:authors ("Nicolas Petton" . "nicolas@petton.fr")) (:maintainer "Nicolas Petton" . "nicolas@petton.fr") (:url . "https://github.com/NicolasPetton/xref-js2"))]) (xquery-tool . [(20170605 826) nil "A simple interface to saxonb's xquery." single ((:commit . "0d1e2960c48701b83be5255d56324f65a6ee182e") (:keywords "xml" "xquery" "emacs") (:authors ("Patrick McAllister" . "pma@rdorte.org")) (:maintainer "Patrick McAllister" . "pma@rdorte.org") (:url . "https://github.com/paddymcall/xquery-tool.el"))]) (xquery-mode . [(20170214 1119) ((cl-lib (0 5))) "A simple mode for editing xquery programs" single ((:commit . "1b655ccf83d02a7bd473d2cf02359ed60bdf7369") (:url . "https://github.com/xquery-mode/xquery-mode"))]) (xo . [(20160403 646) nil "XO linter integration with compilation mode" single ((:commit . "72fcd867cfa332fdb82f732925cf8977e690af78") (:keywords "processes") (:authors ("J.A" . "jer.github@gmail.com")) (:maintainer "J.A" . "jer.github@gmail.com"))]) (xmlunicode . [(20160319 1612) nil "Unicode support for XML" tar ((:commit . "f5d185da46414c0509ebd0aa0fab416becf94612") (:keywords "utf-8" "unicode" "xml" "characters") (:authors ("Norman Walsh" . "ndw@nwalsh.com")) (:maintainer "Norman Walsh" . "ndw@nwalsh.com"))]) (xmlgen . [(20170411 1317) nil "A DSL for generating XML." single ((:commit . "dba66681f0c5e621a9e70e8afb34903c9ffe93c4") (:authors ("Philip Jackson" . "phil@shellarchive.co.uk")) (:maintainer "Philip Jackson" . "phil@shellarchive.co.uk"))]) (xml-rpc . [(20160430 2158) nil "An elisp implementation of clientside XML-RPC" single ((:commit . "0ab093d60140d19e31d217c8abdc7dbdac944486") (:keywords "xml" "rpc" "network") (:authors ("Mark A. Hershberger" . "mah@everybody.org")) (:maintainer "Mark A. Hershberger" . "mah@everybody.org") (:url . "http://github.com/hexmode/xml-rpc-el"))]) (xml-quotes . [(20151230 2249) nil "read quotations from an XML document" tar ((:commit . "26db170e80b9295861227cdf970721b12539ed44") (:keywords "xml" "quotations") (:authors ("Norman Walsh" . "ndw@nwalsh.com")) (:maintainer "Norman Walsh" . "ndw@nwalsh.com") (:url . "https://github.com/ndw/xml-quotes"))]) (xml+ . [(20170727 2351) ((emacs (24 4)) (dash (2 12 0))) "Utilities for xml and html trees" single ((:commit . "232fa863c08fc159b21dd58c39ea45dce3334895") (:keywords "xml" "html") (:authors ("Ben Dean" . "bendean837@gmail.com")) (:maintainer "Ben Dean" . "bendean837@gmail.com") (:url . "https://github.com/bddean/xml-plus"))]) (xkcd . [(20160419 1130) ((json (1 3))) "View xkcd from Emacs" single ((:commit . "66e928706fd660cfdab204c98a347b49c4267bdf") (:keywords "xkcd" "webcomic") (:authors ("Vibhav Pant" . "vibhavp@gmail.com")) (:maintainer "Vibhav Pant" . "vibhavp@gmail.com") (:url . "https://github.com/vibhavp/emacs-xkcd"))]) (xcscope . [(20180426 712) nil "cscope interface for (X)Emacs" single ((:commit . "57bff67460c587acf60f513de622b4c7ab312081") (:keywords "languages" "c") (:authors ("Darryl Okahata" . "darrylo@sonic.net") ("Dima Kogan" . "dima@secretsauce.net")) (:maintainer "Dima Kogan" . "dima@secretsauce.net") (:url . "https://github.com/dkogan/xcscope.el"))]) (xcode-project . [(20180509 1918) ((emacs (25))) "A package for reading Xcode project files." tar ((:commit . "d6b711c535b963fab12d60784700d5fb9930191d") (:keywords "languages" "tools") (:authors ("John Buckley" . "john@olivetoast.com")) (:maintainer "John Buckley" . "john@olivetoast.com") (:url . "https://github.com/nhojb/xcode-project.git"))]) (xcode-mode . [(20160907 1208) ((emacs (24 4)) (s (1 10 0)) (dash (2 11 0)) (multiple-cursors (1 0 0))) "A minor mode for emacs to perform Xcode like actions." single ((:commit . "2ae4f512d6c601ea39d5ab785c2b5288eac24b59") (:keywords "conveniences") (:authors ("Nickolas Lanasa" . "nick@nytekproductions.com")) (:maintainer "Nickolas Lanasa" . "nick@nytekproductions.com"))]) (xbm-life . [(20160103 1017) nil "A XBM version of Conway's Game of Life" single ((:commit . "dd6a98ac9ea81b681e68f6318fed47158e5d469e") (:keywords "games") (:authors ("Vasilij Schneidermann" . "v.schneidermann@gmail.com")) (:maintainer "Vasilij Schneidermann" . "v.schneidermann@gmail.com") (:url . "https://github.com/wasamasa/xbm-life"))]) (xahk-mode . [(20170821 1107) ((emacs (24 1))) "Major mode for editing AutoHotkey scripts." single ((:commit . "02012b20603c00e3b2ef32159a690ed1e05d12c3") (:keywords "languages") (:authors ("Xah Lee ( http://xahlee.info/ )")) (:maintainer "Xah Lee ( http://xahlee.info/ )") (:url . "http://xahlee.info/mswin/emacs_autohotkey_mode.html"))]) (xah-replace-pairs . [(20180508 249) ((emacs (24 1))) "emacs lisp functions for multi-pair find/replace." single ((:commit . "4d845cfbce32d45befd7c454e3476c3ce40d2b43") (:keywords "lisp" "tools" "find replace") (:authors ("Xah Lee ( http://xahlee.info/ )")) (:maintainer "Xah Lee ( http://xahlee.info/ )") (:url . "http://ergoemacs.org/emacs/elisp_replace_string_region.html"))]) (xah-reformat-code . [(20170821 1111) nil "commands to reformat source code." single ((:commit . "7fec8b28e46b8cc2813fac5149e3bbb56c0aa6b1") (:keywords "convenience") (:authors ("Xah Lee ( http://xahlee.info/ )")) (:maintainer "Xah Lee ( http://xahlee.info/ )") (:url . "http://ergoemacs.org/emacs/emacs_reformat_lines.html"))]) (xah-math-input . [(20180710 528) ((emacs (24 1))) "a minor mode for inputting math and Unicode symbols." single ((:commit . "87e46fcaaada3e87dc828e75a52bec05c8c4c262") (:keywords "abbrev" "convenience" "unicode" "math" "latex") (:authors ("Xah Lee ( http://xahlee.info/ )")) (:maintainer "Xah Lee ( http://xahlee.info/ )") (:url . "http://ergoemacs.org/emacs/xmsi-math-symbols-input.html"))]) (xah-lookup . [(20180815 1250) ((emacs (24 1))) "look up word on internet." single ((:commit . "e3132ff21c3d0160e5bd5b7222c50dc9840727d4") (:keywords "help" "docs" "convenience") (:authors ("Xah Lee ( http://xahlee.info/ )")) (:maintainer "Xah Lee ( http://xahlee.info/ )") (:url . "http://ergoemacs.org/emacs/xah-lookup.html"))]) (xah-get-thing . [(20170821 1053) ((emacs (24 1))) "get thing or selection at point." single ((:commit . "e3ef069ea9fea3a092689d45c94c6211b51d0ea4") (:keywords "extensions" "lisp" "tools") (:authors ("Xah Lee ( http://xahlee.info/ )")) (:maintainer "Xah Lee ( http://xahlee.info/ )") (:url . "http://ergoemacs.org/emacs/elisp_get-selection-or-unit.html"))]) (xah-fly-keys . [(20180903 1538) ((emacs (24 1))) "ergonomic modal keybinding minor mode." single ((:commit . "f341cf39bb3d682ed38ed0d2fc991655acd4e518") (:keywords "convenience" "emulations" "vim" "ergoemacs") (:authors ("Xah Lee ( http://xahlee.info/ )")) (:maintainer "Xah Lee ( http://xahlee.info/ )") (:url . "http://ergoemacs.org/misc/ergoemacs_vi_mode.html"))]) (xah-find . [(20180830 2358) ((emacs (24 1))) "find replace in pure emacs lisp. Purpose similar to grep/sed." single ((:commit . "4019389a66abbb71d1a7c946c37efe184116bcc9") (:keywords "convenience" "extensions" "files" "tools" "unix") (:authors ("Xah Lee ( http://xahlee.info/ )")) (:maintainer "Xah Lee ( http://xahlee.info/ )") (:url . "http://ergoemacs.org/emacs/elisp-xah-find-text.html"))]) (xah-elisp-mode . [(20180902 1716) ((emacs (24 3))) "Major mode for editing emacs lisp." single ((:commit . "0a8c8832fa8ecb5b987df01722b6b3ec5fcf6cd5") (:keywords "lisp" "languages") (:authors ("Xah Lee ( http://xahlee.info/ )")) (:maintainer "Xah Lee ( http://xahlee.info/ )") (:url . "http://ergoemacs.org/emacs/xah-elisp-mode.html"))]) (xah-css-mode . [(20180629 807) ((emacs (24 3))) "Major mode for editing CSS code." single ((:commit . "9293a1a21cb7c2a6fb4ae9af0e581f30d2e45016") (:keywords "languages" "convenience" "css" "color") (:authors ("Xah Lee ( http://xahlee.info/ )")) (:maintainer "Xah Lee ( http://xahlee.info/ )") (:url . "http://ergoemacs.org/emacs/xah-css-mode.html"))]) (x86-lookup . [(20180528 1635) ((emacs (24 3)) (cl-lib (0 3))) "jump to x86 instruction documentation" single ((:commit . "609b2ba70dc5a246ac9b4b5f89eb5ef4331519bf") (:authors ("Christopher Wellons" . "wellons@nullprogram.com")) (:maintainer "Christopher Wellons" . "wellons@nullprogram.com") (:url . "https://github.com/skeeto/x86-lookup"))]) (x509-mode . [(20180702 736) ((emacs (24 1)) (cl-lib (0 5))) "View certificates, CRLs and keys using OpenSSL." tar ((:commit . "89bdeca8c7494eaaea115031b3235f0bfbd4d945") (:authors ("Fredrik Axelsson" . "f.axelsson@gmai.com") ("Package-Requires: ((emacs \"24.1\") (cl-lib \"0.5\"))")) (:maintainer "Fredrik Axelsson" . "f.axelsson@gmai.com"))]) (x-path-walker . [(20160922 1835) ((helm-core (1 9 2))) "Navigation feature for JSON/XML/HTML based on path (imenu like)" tar ((:commit . "3b01dbd7a039c6c84fdf8c8ee53ba72090ee950a") (:keywords "convenience") (:authors (nil . "<lompik@ArchOrion>")) (:maintainer nil . "<lompik@ArchOrion>"))]) (www-synonyms . [(20170128 2251) ((request (0 2 0)) (cl-lib (0 5))) "insert synonym for a word" single ((:commit . "7e37ea35064ff31c9945f0198a653647d408c936") (:keywords "lisp") (:authors ("Bernhard Specht" . "bernhard@specht.net")) (:maintainer "Bernhard Specht" . "bernhard@specht.net"))]) (wwtime . [(20151122 1610) nil "Insert a time of day with appropriate world-wide localization" single ((:commit . "d04d8fa814b5d3644efaeb28f25520ada69acbbd") (:keywords "time") (:authors ("Norman Walsh" . "ndw@nwalsh.com")) (:maintainer "Norman Walsh" . "ndw@nwalsh.com"))]) (wucuo . [(20180904 16) ((emacs (24 4))) "Spell check code containing camel case words" single ((:commit . "8efca1dce8c19a4ccf375357864a81b549be7f0d") (:keywords "convenience") (:authors ("Chen Bin <chenbin DOT sh AT gmail DOT com>")) (:maintainer "Chen Bin <chenbin DOT sh AT gmail DOT com>") (:url . "http://github.com/redguardtoo/wucuo"))]) (wttrin . [(20170614 1206) ((emacs (24 4)) (xterm-color (1 0))) "Emacs frontend for weather web service wttr.in" single ((:commit . "df5427ce2a5ad4dab652dbb1c4a1834d7ddc2abc") (:keywords "comm" "weather" "wttrin") (:authors ("Carl X. Su" . "bcbcarl@gmail.com") ("ono hiroko (kuanyui)" . "azazabc123@gmail.com")) (:maintainer "Carl X. Su" . "bcbcarl@gmail.com") (:url . "https://github.com/bcbcarl/emacs-wttrin"))]) (wsd-mode . [(20180807 1130) nil "Emacs major-mode for www.websequencediagrams.com" tar ((:commit . "0583df8efb742c90dc56df00f9714e13512cf6d9") (:keywords "wsd" "diagrams" "design" "process" "modelling" "uml") (:authors ("Jostein Kjønigsen" . "jostein@gmail.com")) (:maintainer "Jostein Kjønigsen" . "jostein@gmail.com") (:url . "https://github.com/josteink/wsd-mode"))]) (ws-butler . [(20170111 2334) nil "Unobtrusively remove trailing whitespace." single ((:commit . "52321b99be69aa1b661da7743c4421a30d8b6bcb") (:authors ("Le Wang")) (:maintainer "Le Wang") (:url . "https://github.com/lewang/ws-butler"))]) (writeroom-mode . [(20170623 1027) ((emacs (24 1)) (visual-fill-column (1 9))) "Minor mode for distraction-free writing" tar ((:commit . "07221a4fd979ff6d671247bc402d3dda5dbe14cc") (:keywords "text") (:authors ("Joost Kremers" . "joostkremers@fastmail.fm")) (:maintainer "Joost Kremers" . "joostkremers@fastmail.fm"))]) (writegood-mode . [(20180525 1343) nil "Polish up poor writing on the fly" single ((:commit . "b71757ec337e226909fb0422f0224e31acc71733") (:keywords "writing" "weasel-words" "grammar") (:authors ("Benjamin Beckwith")) (:maintainer "Benjamin Beckwith") (:url . "http://github.com/bnbeckwith/writegood-mode"))]) (wrap-region . [(20140117 720) ((dash (1 0 3))) "Wrap text with punctation or tag" single ((:commit . "fbae9b0f106187af19823f1a6260b5c68b7252e6") (:keywords "speed" "convenience") (:authors ("Johan Andersson" . "johan.rejeep@gmail.com")) (:maintainer "Johan Andersson" . "johan.rejeep@gmail.com") (:url . "http://github.com/rejeep/wrap-region"))]) (wotd . [(20170328 1948) ((emacs (24 4)) (org (8 2 10))) "Fetch word-of-the-day from multiple online sources" single ((:commit . "d2937a3d91e014f8028a1f33d21c18cc0b065a64") (:keywords "extensions") (:authors ("Junpeng Qiu" . "qjpchmail@gmail.com")) (:maintainer "Junpeng Qiu" . "qjpchmail@gmail.com"))]) (world-time-mode . [(20140627 807) nil "show whole days of world-time diffs" single ((:commit . "ce7a3b45c87eb24cfe61eee453175d64f741d7cc") (:keywords "tools" "calendar") (:authors ("Nic Ferrier" . "nferrier@ferrier.me.uk")) (:maintainer "Nic Ferrier" . "nferrier@ferrier.me.uk"))]) (workgroups2 . [(20141102 1922) ((cl-lib (0 4)) (dash (2 8 0)) (anaphora (1 0 0)) (f (0 17))) "New workspaces for Emacs" single ((:commit . "928d509157ec8a4a2e343b6115dff034c3243a7a") (:keywords "session" "management" "window-configuration" "persistence") (:authors ("Sergey Pashinin <sergey at pashinin dot com>")) (:maintainer "Sergey Pashinin <sergey at pashinin dot com>") (:url . "https://github.com/pashinin/workgroups2"))]) (workgroups . [(20110726 1641) nil "workgroups for windows (for Emacs)" single ((:commit . "9572b3492ee09054dc329f64ed846c962b395e39") (:keywords "session" "management" "window-configuration" "persistence") (:authors ("tlh" . "thunkout@gmail.com")) (:maintainer "tlh" . "thunkout@gmail.com"))]) (worf . [(20180620 1711) ((swiper (0 7 0)) (ace-link (0 1 0)) (hydra (0 13 0)) (zoutline (0 1 0))) "A warrior does not press so many keys! (in org-mode)" tar ((:commit . "b48e0c9bbd617ed8a8962174d804ce7a6da1c10a") (:keywords "lisp") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:url . "https://github.com/abo-abo/worf"))]) (wordsmith-mode . [(20171025 1430) nil "Syntax analysis and NLP text-processing in Emacs (OSX-only)" single ((:commit . "589a97412138145bea70e0450eeddeb7f138d538") (:authors ("istib" . "istib@thebati.net")) (:maintainer "istib" . "istib@thebati.net"))]) (wordnut . [(20180313 443) ((emacs (24 4))) "Major mode interface to WordNet" tar ((:commit . "feac531404041855312c1a046bde7ea18c674915"))]) (wordgen . [(20170803 1820) ((emacs (24)) (cl-lib (0 5))) "Random word generator" single ((:commit . "aacad928ae99a953e034a831dfd0ebdf7d52ac1d") (:authors ("Fanael Linithien" . "fanael4@gmail.com")) (:maintainer "Fanael Linithien" . "fanael4@gmail.com") (:url . "https://github.com/Fanael/wordgen.el"))]) (wonderland . [(20130913 119) ((dash (2 0 0)) (dash-functional (1 0 0)) (multi (2 0 0)) (emacs (24))) "declarative configuration for Emacsen" single ((:commit . "89d274ad694b0e748efdac23ccd60b7d8b73d7c6") (:keywords "configuration" "profile" "wonderland") (:authors ("Christina Whyte" . "kurisu.whyte@gmail.com")) (:maintainer "Christina Whyte" . "kurisu.whyte@gmail.com") (:url . "http://github.com/kurisuwhyte/emacs-wonderland"))]) (wolfram-mode . [(20180307 13) ((emacs (24 3))) "Mathematica editing and inferior mode." single ((:commit . "be680190cac6ccf579dbce107deaae495928d1b3") (:keywords "languages" "processes" "tools") (:authors ("Daichi Mochihashi <daichi at cslab.kecl.ntt.co.jp>")) (:maintainer "Daichi Mochihashi <daichi at cslab.kecl.ntt.co.jp>") (:url . "https://github.com/kawabata/wolfram-mode/"))]) (wolfram . [(20170123 756) nil "Wolfram Alpha Integration" single ((:commit . "6b5dceae3fd6cdb4d7562510deeafa02c93c010b") (:keywords "math") (:authors ("Hans Sjunnesson" . "hans.sjunnesson@gmail.com")) (:maintainer "Hans Sjunnesson" . "hans.sjunnesson@gmail.com"))]) (wn-mode . [(20151110 552) ((emacs (24))) "numeric window switching shortcuts" single ((:commit . "f05c3151523e529af5a0a3fa8c948b61fb369f6e") (:keywords "buffers" "windows" "switching-windows") (:authors ("Anonymous")) (:maintainer "Luís Oliveira" . "luismbo@gmail.com") (:url . "https://github.com/luismbo/wn-mode"))]) (with-simulated-input . [(20170821 617) ((emacs (24 4)) (seq (2 0)) (s (0))) "A macro to simulate user input non-interactively" single ((:commit . "af9a38ce28a741e6d8742750bef5d7b5afa13796") (:keywords "lisp" "tools" "extensions") (:authors ("Ryan C. Thompson")) (:maintainer "Ryan C. Thompson"))]) (with-namespace . [(20130407 1822) ((dash (1 1 0)) (loop (1 1))) "interoperable elisp namespaces" single ((:commit . "8ac52da3a09cf46087720e30cf730d00f140cde6") (:keywords "namespaces") (:authors ("Wilfred Hughes" . "me@wilfred.me.uk")) (:maintainer "Wilfred Hughes" . "me@wilfred.me.uk"))]) (with-editor . [(20180726 2044) ((emacs (24 4)) (async (1 9))) "Use the Emacsclient as $EDITOR" tar ((:commit . "3e6424764ee06fb50c580283baea3851c6f9ea66") (:keywords "tools") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:url . "https://github.com/magit/with-editor"))]) (wispjs-mode . [(20170720 1919) ((clojure-mode (0))) "Major mode for Wisp code." single ((:commit . "60f9f5fd9d1556e2d008939f67eb1b1d0f325fa8") (:authors ("Kris Jenkins" . "krisajenkins@gmail.com")) (:maintainer "Kris Jenkins" . "krisajenkins@gmail.com") (:url . "https://github.com/krisajenkins/wispjs-mode"))]) (wisp-mode . [(20180520 758) nil "Tools for wisp: the Whitespace-to-Lisp preprocessor" tar ((:keywords "languages" "lisp") (:authors ("Arne Babenhauserheide" . "arne_bab@web.de")) (:maintainer "Arne Babenhauserheide" . "arne_bab@web.de"))]) (winum . [(20171028 1402) ((cl-lib (0 5)) (dash (2 13 0))) "Navigate windows and frames using numbers." single ((:commit . "c56d1cdb8d1723eb4c0d7a7eb3ecd2697739146c") (:keywords "convenience" "frames" "windows" "multi-screen") (:authors ("Thomas de Beauchêne" . "thomas.de.beauchene@gmail.com")) (:maintainer "Thomas de Beauchêne" . "thomas.de.beauchene@gmail.com") (:url . "http://github.com/deb0ch/winum.el"))]) (winring . [(20180530 18) nil "Window configuration rings" single ((:commit . "f2d072bd446b73e93b127523f19ea82b99b9267f") (:keywords "frames" "tools") (:authors ("1997-2018 Barry A. Warsaw")) (:maintainer "1997-2018 Barry A. Warsaw") (:url . "https://gitlab.com/warsaw/winring"))]) (winpoint . [(20131023 1713) nil "Remember buffer positions per-window, not per buffer" single ((:commit . "e6050093c076308184566fa1d1012423d6934773") (:keywords "convenience") (:authors ("Jorgen Schaefer" . "forcer@forcix.cx")) (:maintainer "Jorgen Schaefer" . "forcer@forcix.cx") (:url . "https://github.com/jorgenschaefer/winpoint"))]) (winnow . [(20170903 1206) ((emacs (24))) "winnow ag/grep results by matching/excluding lines" single ((:commit . "18cb6b94338f3b7b4f2cd0331dad22f82dd9e0d3") (:keywords "matching") (:authors ("Charles L.G. Comstock" . "dgtized@gmail.com")) (:maintainer "Charles L.G. Comstock" . "dgtized@gmail.com") (:url . "https://github.com/dgtized/winnow.el"))]) (windwow . [(20170816 148) ((dash (2 11 0)) (cl-lib (0 6 1)) (emacs (24))) "simple workspace management" single ((:commit . "77bad26f651744b68d31b389389147014d250f23") (:keywords "frames") (:authors ("Viju Mathew" . "viju.jm@gmail.com")) (:maintainer "Viju Mathew" . "viju.jm@gmail.com") (:url . "github.com/vijumathew/windwow"))]) (windsize . [(20151121 1340) nil "Simple, intuitive window resizing" single ((:commit . "beb6376fdf52afa6f220c89032448460faf76e7f") (:keywords "window" "resizing" "convenience") (:authors ("Chris Perkins" . "chrisperkins99@gmail.com")) (:maintainer "Chris Perkins" . "chrisperkins99@gmail.com") (:url . "http://github.com/grammati/windsize"))]) (window-purpose . [(20180809 1156) ((emacs (24 4)) (let-alist (1 0 3)) (imenu-list (0 1))) "Purpose-based window management for Emacs" tar ((:commit . "a302340e183d20baa4445858d321f43449298829") (:keywords "frames") (:authors ("Bar Magal")) (:maintainer "Bar Magal") (:url . "https://github.com/bmag/emacs-purpose"))]) (window-numbering . [(20160809 1810) nil "Numbered window shortcuts" single ((:commit . "10809b3993a97c7b544240bf5d7ce9b1110a1b89") (:keywords "faces" "matching") (:authors ("Nikolaj Schumacher <bugs * nschum de>")) (:maintainer "Nikolaj Schumacher <bugs * nschum de>") (:url . "http://nschum.de/src/emacs/window-numbering-mode/"))]) (window-number . [(20170801 151) nil "Select windows by numbers." single ((:commit . "d41722de646ffeb3f70d26e4a86a5a1ba5c6be87") (:keywords "windows") (:authors ("Johann \"Myrkraverk\" Oskarsson" . "myrkraverk@users.sourceforge.net")) (:maintainer "Nik Nyby" . "niknyby@riseup.net") (:url . "https://github.com/nikolas/window-number"))]) (window-layout . [(20170215 33) nil "window layout manager" single ((:commit . "cd2e4f967b610c2bbef53182829e47250d027056") (:keywords "window" "layout") (:authors ("SAKURAI Masashi <m.sakurai atmark kiwanami.net>")) (:maintainer "SAKURAI Masashi <m.sakurai atmark kiwanami.net>"))]) (window-jump . [(20170809 2208) nil "Move left/right/up/down through your windows." single ((:commit . "6bdb51e9a346907d60a9625f6180bddd06be6674") (:keywords "frames" "convenience") (:authors ("Steven Thomas")) (:maintainer "Steven Thomas") (:url . "https://github.com/chumpage/chumpy-windows"))]) (window-end-visible . [(20140508 2041) nil "Find the last visible point in a window" single ((:commit . "525500fb2ebc08f3f9ea493972e5f2e1d79f89ef") (:keywords "extensions") (:authors ("Roland Walker" . "walker@pobox.com")) (:maintainer "Roland Walker" . "walker@pobox.com") (:url . "http://github.com/rolandwalker/window-end-visible"))]) (windata . [(20090830 1040) nil "convert window configuration to list" single ((:commit . "a723fc446ceaec23d5f29ecc8245d94c99d91625") (:keywords "convenience" "frames") (:authors (nil . "wenbinye@gmail.com")) (:maintainer nil . "wenbinye@gmail.com"))]) (win-switch . [(20161009 1627) nil "fast, dynamic bindings for window-switching/resizing" single ((:commit . "954eb5e4c5737f0c06368c42a7f1c3dd374d782f") (:keywords "window" "switch" "key bindings" "ergonomic" "efficient") (:authors ("Christopher Genovese" . "genovese@cmu.edu")) (:maintainer "Christopher R. Genovese" . "genovese@cmu.edu") (:url . "http://www.stat.cmu.edu/~genovese/emacs/win-switch/"))]) (wilt . [(20180220 854) ((emacs (24 3)) (dash (2 12 0)) (s (1 10 0))) "An extensions for calculating WILT in a buffer." single ((:commit . "04dbe37fa35d0b24c791421785d2c97a8cbfe2cc") (:authors ("Austin Bingham" . "austin@sixty-north.com")) (:maintainer "Austin Bingham" . "austin@sixty-north.com") (:url . "https://github.com/sixty-north/emacs-wilt"))]) (wiki-summary . [(20150408 2122) ((emacs (24))) "View Wikipedia summaries in Emacs easily." single ((:commit . "ed3755dd09f5f73ef78ec295fe842d08b316c8a0") (:keywords "wikipedia" "utility") (:authors ("Danny Gratzer")) (:maintainer "Danny Gratzer") (:url . "https://github.com/jozefg/wiki-summary.el"))]) (wiki-nav . [(20150223 1354) ((button-lock (1 0 2)) (nav-flash (1 0 0))) "Simple file navigation using [[WikiStrings]]" single ((:commit . "f9082feb329432fcf2ac49a95e64bed9fda24d58") (:keywords "mouse" "button" "hypermedia" "navigation") (:authors ("Roland Walker" . "walker@pobox.com")) (:maintainer "Roland Walker" . "walker@pobox.com") (:url . "http://github.com/rolandwalker/button-lock"))]) (widgetjs . [(20160719 1504) ((makey (0 3)) (js2-mode (20140114)) (js2-refactor (0 6 1)) (s (1 9 0))) "Widgetjs mode" single ((:commit . "70dcbe5e440d64d82d1912932695d00e2a275ec9") (:keywords "help") (:authors ("Nicolas Petton" . "petton.nicolas@gmail.com")) (:maintainer "Nicolas Petton" . "petton.nicolas@gmail.com"))]) (widget-mvc . [(20150102 406) nil "MVC framework for the emacs widgets" single ((:commit . "ff5a85880df7b87f9f480fe3c28438a0712b7b87") (:keywords "lisp" "widget") (:authors ("SAKURAI Masashi <m.sakurai at kiwanami.net>")) (:maintainer "SAKURAI Masashi <m.sakurai at kiwanami.net>"))]) (wide-column . [(20170925 1613) nil "Calls functions dependant on column position." single ((:commit . "ce9ef4675485a7bea381077866368ef875226b10") (:keywords "minor mode" "cursor colour" "column width") (:authors ("Phillip Lord" . "p.lord@russet.org.uk")) (:maintainer "Phillip Lord" . "p.lord@russet.org.uk"))]) (whole-line-or-region . [(20180325 419) nil "operate on current line if region undefined" single ((:commit . "944290d443a395ef0578531929186d6274ab03e9") (:keywords "convenience" "wp") (:authors ("Joe Casadonte" . "emacs@northbound-train.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com"))]) (whizzml-mode . [(20180711 1610) ((emacs (24 4))) "Programming mode for editing WhizzML files" tar ((:commit . "f457052dc5426d542ca69185a5a87905f08f1310") (:keywords "languages" "lisp") (:authors ("Jose Antonio Ortega Ruiz" . "jao@bigml.com")) (:maintainer "Jose Antonio Ortega Ruiz" . "jao@bigml.com"))]) (whitespace-cleanup-mode . [(20170506 223) nil "Intelligently call whitespace-cleanup on save" single ((:commit . "6d0a35159ee04ef9f3b1a80c548f545643ddb397") (:keywords "convenience") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:url . "https://github.com/purcell/whitespace-cleanup-mode"))]) (white-theme . [(20160917 1743) ((emacs (24))) "Minimalistic light color theme inspired by basic-theme" single ((:commit . "e9e6d5b9d43da6eb15e86f5fbc8b1ba83abe8c78") (:keywords "color" "theme" "minimal" "basic" "simple" "white") (:authors ("Anler Hernandez Peral" . "inbox@anler.me")) (:maintainer "Anler Hernandez Peral" . "inbox@anler.me") (:url . "http://github.com/anler/white-theme.el"))]) (white-sand-theme . [(20151117 1648) ((emacs (24))) "Emacs theme with a light background." single ((:commit . "97621edd69267dd143760d94393db2c2558c9ea4") (:authors ("Martin Haesler")) (:maintainer "Martin Haesler"))]) (whitaker . [(20150814 1122) ((dash (2 10 0))) "Comint interface for Whitaker's Words" single ((:commit . "eaf26ea647b729ca705b73ea70312d5ffdf89448") (:keywords "processes") (:authors ("Matus Goljer" . "matus.goljer@gmail.com")) (:maintainer "Matus Goljer" . "matus.goljer@gmail.com"))]) (which-key . [(20180621 1938) ((emacs (24 4))) "Display available keybindings in popup" single ((:commit . "c938bbf8d4b506d8a16bedf0059703236ce05a50") (:authors ("Justin Burkett" . "justin@burkett.cc")) (:maintainer "Justin Burkett" . "justin@burkett.cc") (:url . "https://github.com/justbur/emacs-which-key"))]) (what-the-commit . [(20150901 1316) nil "Random commit message generator" single ((:commit . "868c80a1b8614bcbd2225cd0290142c72f2a7956") (:keywords "git" "commit" "message") (:authors ("Dan Barbarito" . "dan@barbarito.me")) (:maintainer "Dan Barbarito" . "dan@barbarito.me") (:url . "http://barbarito.me/"))]) (wgrep-pt . [(20140510 2231) ((wgrep (2 1 5))) "Writable pt buffer and apply the changes to files" single ((:commit . "414be70bd313e482cd9f0b70fd2daad4ee23497c") (:keywords "grep" "edit" "extensions") (:authors ("Masahiro Hayashi <mhayashi1120@gmail.com>, Bailey Ling" . "bling@live.ca")) (:maintainer "Masahiro Hayashi <mhayashi1120@gmail.com>, Bailey Ling" . "bling@live.ca") (:url . "http://github.com/mhayashi1120/Emacs-wgrep/raw/master/wgrep-pt.el"))]) (wgrep-helm . [(20170510 2239) ((wgrep (2 1 1))) "Writable helm-grep-mode buffer and apply the changes to files" single ((:commit . "414be70bd313e482cd9f0b70fd2daad4ee23497c") (:keywords "grep" "edit" "extensions") (:authors ("Masahiro Hayashi" . "mhayashi1120@gmail.com")) (:maintainer "Masahiro Hayashi" . "mhayashi1120@gmail.com") (:url . "http://github.com/mhayashi1120/Emacs-wgrep/raw/master/wgrep-helm.el"))]) (wgrep-ag . [(20160923 1103) ((wgrep (2 1 5)) (cl-lib (0 5))) "Writable ag buffer and apply the changes to files" single ((:commit . "414be70bd313e482cd9f0b70fd2daad4ee23497c") (:keywords "grep" "edit" "extensions") (:authors ("Masahiro Hayashi" . "mhayashi1120@gmail.com")) (:maintainer "Masahiro Hayashi" . "mhayashi1120@gmail.com") (:url . "http://github.com/mhayashi1120/Emacs-wgrep/raw/master/wgrep-ag.el"))]) (wgrep-ack . [(20141012 1011) ((wgrep (2 1 1))) "Writable ack-and-a-half buffer and apply the changes to files" single ((:commit . "414be70bd313e482cd9f0b70fd2daad4ee23497c") (:keywords "grep" "edit" "extensions") (:authors ("Masahiro Hayashi" . "mhayashi1120@gmail.com")) (:maintainer "Masahiro Hayashi" . "mhayashi1120@gmail.com") (:url . "http://github.com/mhayashi1120/Emacs-wgrep/raw/master/wgrep-ack.el"))]) (wgrep . [(20180711 626) nil "Writable grep buffer and apply the changes to files" single ((:commit . "414be70bd313e482cd9f0b70fd2daad4ee23497c") (:keywords "grep" "edit" "extensions") (:authors ("Masahiro Hayashi" . "mhayashi1120@gmail.com")) (:maintainer "Masahiro Hayashi" . "mhayashi1120@gmail.com") (:url . "http://github.com/mhayashi1120/Emacs-wgrep/raw/master/wgrep.el"))]) (weibo . [(20150307 2242) ((cl-lib (0 5))) "Weibo client for Emacs" tar ((:commit . "a8abb50b7602fe15fe2bc6400ac29780e956b390") (:keywords "weibo") (:authors ("Austin" . "austiny.cn@gmail.com")) (:maintainer "Austin" . "austiny.cn@gmail.com") (:url . "https://github.com/austin-----/weibo.emacs"))]) (weechat-alert . [(20160416 1248) ((weechat (0 3 1)) (cl-lib (0 5)) (alert (1 2))) "Weechat notifier using alerts" single ((:commit . "a8fd557c8f335322f132c1c6c08b6741d6394e2e") (:keywords "irc" "chat" "network" "weechat") (:authors ("Andreas Klein" . "git@kungi.org")) (:maintainer "Andreas Klein" . "git@kungi.org") (:url . "https://github.com/kungi/weechat-alert"))]) (weechat . [(20180513 1010) ((s (1 3 1)) (cl-lib (0 2)) (emacs (24)) (tracking (1 2))) "Chat via WeeChat's relay protocol in Emacs" tar ((:commit . "8cbda2738149b070c09288df550781b6c604beb2"))]) (wedge-ws . [(20140714 2149) nil "Wedge whitespace between columns in text" single ((:commit . "4669115f02d9c6fee067cc5369bb38c0f9db88b2") (:keywords "formatting" "indentation") (:authors ("Anders Eurenius" . "aes@spotify.com")) (:maintainer "Anders Eurenius" . "aes@spotify.com"))]) (websocket . [(20180423 16) ((cl-lib (0 5))) "Emacs WebSocket client and server" single ((:commit . "0d96ba2ff5a25c6cd6c66f417cc9b5f38a4308ba") (:keywords "communication" "websocket" "server") (:authors ("Andrew Hyatt" . "ahyatt@gmail.com")) (:maintainer "Andrew Hyatt" . "ahyatt@gmail.com"))]) (webpaste . [(20180815 1855) ((emacs (24 4)) (request (0 2 0)) (cl-lib (0 5))) "Paste to pastebin-like services" single ((:commit . "e7fed98c30e960911426be054bad183fd1ab6a37") (:keywords "convenience" "comm" "paste") (:authors ("Elis \"etu\" Hirwing")) (:maintainer "Elis \"etu\" Hirwing") (:url . "https://github.com/etu/webpaste.el"))]) (weblogger . [(20110926 1618) ((xml-rpc (1 6 8))) "Weblog maintenance via XML-RPC APIs" single ((:commit . "b3dd4aead9d3a87e6d85e7fef4f4f3bd40d87b53") (:keywords "weblog" "blogger" "cms" "movable" "type" "openweblog" "blog") (:url . "http://launchpad.net/weblogger-el"))]) (webkit-color-picker . [(20180325 736) ((emacs (26 0)) (posframe (0 1 0))) "Insert and adjust colors using Webkit Widgets" tar ((:commit . "765cac80144cad4bc0bf59025ea0199f0486f737") (:keywords "tools") (:authors ("Ozan Sener" . "hi@ozan.email")) (:maintainer "Ozan Sener" . "hi@ozan.email") (:url . "https://github.com/osener/emacs-webkit-color-picker"))]) (web-server . [(20140906 6) ((emacs (24 3))) "Emacs Web Server" tar ((:commit . "469cd3bc117bfb8da0c03a2a2fb185e80c81d068") (:keywords "http" "server" "network") (:authors ("Eric Schulte" . "schulte.eric@gmail.com")) (:maintainer "Eric Schulte" . "schulte.eric@gmail.com") (:url . "https://github.com/eschulte/emacs-web-server"))]) (web-search . [(20170911 1946) ((emacs (24 3))) "Open a web search" tar ((:commit . "bdf590e7d6d62e874810aa4c5017c48e4e93f823") (:keywords "web" "search") (:authors ("Chunyang Xu" . "mail@xuchunyang.me")) (:maintainer "Chunyang Xu" . "mail@xuchunyang.me") (:url . "https://github.com/xuchunyang/web-search.el"))]) (web-narrow-mode . [(20170407 210) ((web-mode (14 0 27))) "quick narrow code block in web-mode" single ((:commit . "73bdcb7d0701abe65dab4fc295d944885e05ae33") (:keywords "web-mode" "react" "narrow" "web") (:authors ("Qquanwei" . "quanwei9958@126.com")) (:maintainer "Johan Andersson" . "quanwei9958@126.com") (:url . "https://github.com/Qquanwei/web-narrow-mode"))]) (web-mode-edit-element . [(20161114 1754) ((emacs (24 4)) (web-mode (14))) "Helper-functions for attribute- and element-handling" tar ((:commit . "8b8ac07aa8c920dafd94c96a51effb0d6c0ed1ce") (:keywords "languages" "convenience") (:authors ("Julian T. Knabenschuh" . "jtkdevelopments@gmail.com")) (:maintainer "Julian T. Knabenschuh" . "jtkdevelopments@gmail.com") (:url . "https://github.com/jtkDvlp/web-mode-edit-element"))]) (web-mode . [(20180813 1350) ((emacs (23 1))) "major mode for editing web templates" single ((:commit . "e31d1dd4ee436db8aaca3f35223af5a05fb47dec") (:keywords "languages") (:authors ("François-Xavier Bois <fxbois AT Google Mail Service>")) (:maintainer "François-Xavier Bois") (:url . "http://web-mode.org"))]) (web-completion-data . [(20160318 848) nil "Shared completion data for ac-html and company-web" tar ((:commit . "c272c94e8a71b779c29653a532f619acad433a4f") (:keywords "html" "auto-complete" "company") (:authors ("Olexandr Sydorchuk" . "olexandr.syd@gmail.com")) (:maintainer "Olexandr Sydorchuk" . "olexandr.syd@gmail.com") (:url . "https://github.com/osv/web-completion-data"))]) (web-beautify . [(20161115 2247) nil "Format HTML, CSS and JavaScript/JSON" single ((:commit . "e1b45321d8c11b404b12c8e55afe55eaa7c84ee9") (:authors ("Yasuyuki Oka" . "yasuyk@gmail.com")) (:maintainer "Yasuyuki Oka" . "yasuyk@gmail.com") (:url . "https://github.com/yasuyk/web-beautify"))]) (web . [(20141231 2001) ((dash (2 9 0)) (s (1 5 0))) "useful HTTP client" single ((:commit . "483188dac4bc6b409b985c9dae45f3324a425efd") (:keywords "lisp" "http" "hypermedia") (:authors ("Nic Ferrier" . "nferrier@ferrier.me.uk")) (:maintainer "Nic Ferrier" . "nferrier@ferrier.me.uk") (:url . "http://github.com/nicferrier/emacs-web"))]) (weather-metno . [(20150901 107) ((emacs (24)) (cl-lib (0 3))) "Weather data from met.no in Emacs" tar ((:commit . "bfc7137095e0ee71aad70ac46f2af677f3c051b6"))]) (wdl-mode . [(20180831 1946) nil "WDL (Workflow Definition Language) major mode" single ((:commit . "cef86e5afc136ae5ad9324cd6e6d6f860b889bcf") (:keywords "languages") (:authors ("Xiaowei Zhan" . "zhanxw@gmail.com")) (:maintainer "Xiaowei Zhan" . "zhanxw@gmail.com") (:url . "http://github.com/zhanxw/wdl-mode"))]) (wcheck-mode . [(20180126 1216) nil "General interface for text checkers" tar ((:commit . "6aa26626ccc6f7f670de092c7d40e44ab8b410f9"))]) (wc-mode . [(20170127 429) nil "Running word count with goals (minor mode)" single ((:commit . "f218f42709a651b34d6c1ddd98856f44648ef707") (:authors ("Benjamin Beckwith")) (:maintainer "Benjamin Beckwith") (:url . "https://github.com/bnbeckwith/wc-mode"))]) (wc-goal-mode . [(20140829 1359) nil "Running word count with goals (minor mode)" single ((:commit . "bf21ab9c5a449bcc20dd207a4915dcec218d2699") (:authors ("Benjamin Beckwith")) (:maintainer "Benjamin Beckwith") (:url . "https://github.com/bnbeckwith/wc-goal-mode"))]) (wavefront-obj-mode . [(20170808 1716) nil "Major mode for Wavefront obj files" single ((:commit . "34027915de6496460d8e68b5991dd24d47d54859") (:authors ("Sasha Kovar" . "sasha-emacs@arcocene.org")) (:maintainer "Sasha Kovar" . "sasha-emacs@arcocene.org") (:url . "http://github.com/abend/wavefront-obj-mode"))]) (watch-buffer . [(20120331 2044) nil "run a shell command when saving a buffer" single ((:commit . "761fd7252e6d7bf5148283c2a7ee935f087d9427") (:keywords "automation" "convenience") (:authors ("Michael Steger" . "mjsteger1@gmail.com")) (:maintainer "Michael Steger" . "mjsteger1@gmail.com") (:url . "https://github.com/mjsteger/watch-buffer"))]) (warm-night-theme . [(20161101 1428) ((emacs (24))) "Emacs 24 theme with a dark background." single ((:commit . "020f084d23409b5035150508ba6e57c2509edd64") (:authors ("martin haesler")) (:maintainer "martin haesler"))]) (wanderlust . [(20180826 1349) ((semi (1 14 7))) "Yet Another Message Interface on Emacsen" tar ((:commit . "ebde9a49a80bba4e21ef4a95e77c634779f00aaa"))]) (wandbox . [(20170603 1231) ((emacs (24)) (request (0 3 0)) (s (1 10 0))) "Wandbox client" tar ((:commit . "e002fe41f2cd9b4ce2b1dc80b83301176e9117f1") (:keywords "tools") (:authors ("KOBAYASHI Shigeru (kosh)" . "shigeru.kb@gmail.com")) (:maintainer "KOBAYASHI Shigeru (kosh)" . "shigeru.kb@gmail.com") (:url . "https://github.com/kosh04/emacs-wandbox"))]) (wand . [(20180815 1031) ((dash (20161121 55)) (s (20160928 636))) "Magic wand for Emacs - Select and execute" tar ((:commit . "5c0d4833a3afc57e4b2398250139729cc9131d16") (:keywords "extensions" "tools") (:authors ("Ha-Duong Nguyen <cmpitgATgmail>")) (:maintainer "Ha-Duong Nguyen <cmpitgATgmail>") (:url . "https://github.com/cmpitg/wand"))]) (walkclj . [(20180718 900) ((emacs (25)) (parseclj (0 1 0)) (treepy (0 1 0))) "Manipulate Clojure parse trees" single ((:commit . "2e54fa813b11d1a87c890cdf117f30165a193024") (:keywords "languages") (:authors ("Arne Brasseur")) (:maintainer "Arne Brasseur") (:url . "https://github.com/plexus/walkclj"))]) (wakib-keys . [(20180818 1829) ((emacs (24 4))) "Minor Mode for Modern Keybindings" single ((:commit . "a858979620bd22801e5ce214dd46d69b19ccd357") (:keywords "convenience" "keybindings" "keys") (:authors ("Abdulla Bubshait")) (:maintainer "Abdulla Bubshait") (:url . "https://github.com/darkstego/wakib-keys/"))]) (wakatime-mode . [(20170518 353) nil "Automatic time tracking extension for WakaTime" single ((:commit . "b1eae15f38a367017e519c10837c44650631b154") (:keywords "calendar" "comm") (:authors ("Gabor Torok" . "gabor@20y.hu")) (:maintainer "Alan Hamlett" . "alan@wakatime.com"))]) (waher-theme . [(20141115 1230) ((emacs (24 1))) "Emacs 24 theme based on waher for st2 by dduckster" single ((:commit . "60d31519fcfd8e797723d47961b255ae2f2e2c0a") (:authors ("Jasonm23" . "jasonm23@gmail.com")) (:maintainer "Jasonm23" . "jasonm23@gmail.com") (:url . "https://github.com/jasonm23/emacs-waher-theme"))]) (waf-mode . [(20170403 1940) nil "Waf integration for Emacs" single ((:commit . "20c75eabd1d54fbce8e0dbef785c9fb68577ee4f") (:authors ("Denys Valchuk" . "dvalchuk@gmail.com")) (:maintainer "Denys Valchuk" . "dvalchuk@gmail.com") (:url . "https://bitbucket.org/dvalchuk/waf-mode"))]) (wacspace . [(20180311 2350) ((dash (1 2 0)) (cl-lib (0 2))) "The WACky WorkSPACE manager for emACS" tar ((:commit . "54d19aab6fd2bc5945b7ffc58104e695064927e2"))]) (w3m . [(20180405 520) nil "an Emacs interface to w3m" tar ((:commit . "ea64ccb3d792b60f0815309f588bf46b1f0ca80e") (:keywords "w3m" "www" "hypermedia"))]) (w32-browser . [(20170101 1954) nil "Run Windows application associated with a file." single ((:commit . "e5c60eafd8f8d3546a0fa295ad5af2414d36b4e6") (:keywords "mouse" "dired" "w32" "explorer") (:authors ("Emacs Wiki, Drew Adams")) (:maintainer nil . "Drew Adams (concat \"drew.adams\" \"@\" \"oracle\" \".com\")") (:url . "http://www.emacswiki.org/w32-browser.el"))]) (vyper-mode . [(20180707 1935) ((emacs (24 3))) "Major mode for the Vyper programming language" single ((:commit . "323dfddfc38f0b11697e9ebaf04d1b53297e54e5") (:keywords "languages") (:authors ("Alex Stokes" . "r.alex.stokes@gmail.com")) (:maintainer "Alex Stokes" . "r.alex.stokes@gmail.com") (:url . "https://github.com/ralexstokes/vyper-mode"))]) (vue-mode . [(20180827 15) ((mmm-mode (0 5 5)) (vue-html-mode (0 2)) (ssass-mode (0 2)) (edit-indirect (0 1 4))) "Major mode for vue component based on mmm-mode" single ((:commit . "e5faa5767308dcd87139813957eabba62b7caf19") (:keywords "languages") (:authors ("codefalling" . "code.falling@gmail.com")) (:maintainer "codefalling" . "code.falling@gmail.com"))]) (vue-html-mode . [(20180428 2035) nil "Major mode for editing Vue.js templates" single ((:commit . "1514939804bad558584feeb6298b38d22eadf64e") (:keywords "languages" "vue" "template") (:authors ("Adam Niederer" . "adam.niederer@gmail.com")) (:maintainer "Adam Niederer" . "adam.niederer@gmail.com") (:url . "http://github.com/AdamNiederer/vue-html-mode"))]) (vscode-icon . [(20180901 938) ((emacs (25 1))) "Utility package to provide Vscode style icons" tar ((:commit . "f3659930aeaddb7a9c9f01db4677eda3a5c33ccc") (:keywords "files" "tools") (:authors ("James Nguyen" . "james@jojojames.com")) (:maintainer "James Nguyen" . "james@jojojames.com") (:url . "https://github.com/jojojames/vscode-icon-emacs"))]) (volume . [(20150718 2009) nil "tweak your sound card volume from Emacs" single ((:commit . "ecc1550b3c8b501d37e0f0116b54b535d15f90f6") (:authors ("Daniel Brockman" . "daniel@brockman.se")) (:maintainer "Daniel Brockman" . "daniel@brockman.se") (:url . "http://www.brockman.se/software/volume-el/"))]) (volatile-highlights . [(20160612 155) nil "Minor mode for visual feedback on some operations." single ((:commit . "9a20091f0ce7fc0a6b3e641a6a46d5f3ac4d8392") (:keywords "emulations" "convenience" "wp") (:authors ("K-talo Miyazaki <Keitaro dot Miyazaki at gmail dot com>")) (:maintainer "K-talo Miyazaki <Keitaro dot Miyazaki at gmail dot com>") (:url . "http://www.emacswiki.org/emacs/download/volatile-highlights.el"))]) (voca-builder . [(20161101 1645) ((popup (0 5 2))) "Helps you build up your vocabulary" single ((:commit . "51573beec8cd8308477b0faf453aad93e17f57c5") (:keywords "english" "vocabulary") (:authors ("Yi Tang" . "yi.tang.uk@me.com")) (:maintainer "Yi Tang" . "yi.tang.uk@me.com") (:url . "https://github.com/yitang/voca-builder"))]) (vmd-mode . [(20180223 1356) ((emacs (24 3))) "Fast Github-flavored Markdown preview using a vmd subprocess." single ((:commit . "24e38a20951dfad6e3e985c7cc6286c1e271da5f") (:keywords "markdown" "preview" "live" "vmd") (:authors ("Blake Miller" . "blak3mill3r@gmail.com")) (:maintainer "Blake Miller" . "blak3mill3r@gmail.com") (:url . "https://github.com/blak3mill3r/vmd-mode"))]) (vlf . [(20180201 2254) nil "View Large Files" tar ((:commit . "31b292dc85a374fb343789e217015683bfbdf5f1") (:keywords "large files" "utilities") (:maintainer "Andrey Kotlarski" . "m00naticus@gmail.com") (:url . "https://github.com/m00natic/vlfi"))]) (visual-regexp-steroids . [(20170222 253) ((visual-regexp (1 1))) "Extends visual-regexp to support other regexp engines" tar ((:commit . "a6420b25ec0fbba43bf57875827092e1196d8a9e") (:keywords "external" "foreign" "regexp" "replace" "python" "visual" "feedback") (:authors ("Marko Bencun" . "mbencun@gmail.com")) (:maintainer "Marko Bencun" . "mbencun@gmail.com") (:url . "https://github.com/benma/visual-regexp-steroids.el/"))]) (visual-regexp . [(20170301 116) ((cl-lib (0 2))) "A regexp/replace command for Emacs with interactive visual feedback" single ((:commit . "b3096c2d391ff4e28a2a4e8cd82efbf11071ea85") (:keywords "regexp" "replace" "visual" "feedback") (:authors ("Marko Bencun" . "mbencun@gmail.com")) (:maintainer "Marko Bencun" . "mbencun@gmail.com") (:url . "https://github.com/benma/visual-regexp.el/"))]) (visual-fill-column . [(20180727 2225) ((emacs (24 3))) "fill-column for visual-line-mode" single ((:commit . "ca65ed65d27bdce189bbb15f58399a682aa6f02b") (:authors ("Joost Kremers" . "joostkremers@fastmail.fm")) (:maintainer "Joost Kremers" . "joostkremers@fastmail.fm"))]) (visual-ascii-mode . [(20150129 1046) nil "Visualize ascii code (small integer) on buffer." single ((:commit . "99285a099a17472ddd9f1b4f74e9d092dd8c5947") (:keywords "presentation") (:authors ("Dewdrops" . "v_v_4474@126.com")) (:maintainer "Dewdrops" . "v_v_4474@126.com") (:url . "https://github.com/Dewdrops/visual-ascii-mode"))]) (visible-mark . [(20150624 450) nil "Make marks visible." single ((:commit . "a584db9bc88953b23a9648b3e14ade90767207f8") (:keywords "marking" "color" "faces") (:authors ("Ian Kelling" . "ian@iankelling.org")) (:maintainer "Ian Kelling" . "ian@iankelling.org") (:url . "https://gitlab.com/iankelling/visible-mark"))]) (virtualenvwrapper . [(20180212 144) ((dash (1 5 0)) (s (1 6 1))) "a featureful virtualenv tool for Emacs" single ((:commit . "bf13158dde071bdf4901709ed101aba6b8a25f7f") (:keywords "python" "virtualenv" "virtualenvwrapper") (:authors ("James J Porter" . "porterjamesj@gmail.com")) (:maintainer "James J Porter" . "porterjamesj@gmail.com") (:url . "http://github.com/porterjamesj/virtualenvwrapper.el"))]) (virtualenv . [(20140220 2301) nil "Virtualenv for Python" single ((:commit . "276c0f4d6493b402dc4d22ecdf17b2b072e911b3") (:keywords "python" "virtualenv") (:authors ("Aaron Culich" . "aculich@gmail.com")) (:maintainer "Aaron Culich" . "aculich@gmail.com"))]) (vimrc-mode . [(20170815 137) nil "Major mode for vimrc files" single ((:commit . "ba8140fba6e03a35b123acbd62fc8c6f0a03bf4a") (:keywords "languages" "vim") (:url . "https://github.com/mcandre/vimrc-mode"))]) (vimish-fold . [(20180101 612) ((emacs (24 4)) (cl-lib (0 5)) (f (0 18 0))) "Fold text like in Vim" single ((:commit . "c904cd3e8515e76fb836615305e174369211f6df") (:keywords "convenience") (:authors ("Mark Karpov" . "markkarpov92@gmail.com")) (:maintainer "Mark Karpov" . "markkarpov92@gmail.com") (:url . "https://github.com/mrkkrp/vimish-fold"))]) (vim-region . [(20140329 1624) ((expand-region (20140127))) "Select region as vim" single ((:commit . "7c4a99ce3678fee40c83ab88e8ad075d2a935fdf") (:authors ("ongaeshi" . "ongaeshi0621@gmail.com")) (:maintainer "ongaeshi" . "ongaeshi0621@gmail.com") (:url . "https://github.com/ongaeshi/emacs-vim-region"))]) (vim-empty-lines-mode . [(20150111 426) ((emacs (23))) "Vim-like empty line indicator at end of files." single ((:commit . "d4a5034ca8ea0c962ad6e92c86c0fa2a74d2964b") (:keywords "emulations") (:authors ("Jonne Mickelin" . "jonne@ljhms.com")) (:maintainer "Jonne Mickelin" . "jonne@ljhms.com") (:url . "https://github.com/jmickelin/vim-empty-lines-mode"))]) (viking-mode . [(20160705 2027) nil "kill first, ask later" single ((:commit . "c76aa265d13ad91d6890d242e142d05e31f0340b") (:keywords "kill" "delete") (:authors ("T.v.Dein" . "tlinden@cpan.org")) (:maintainer "T.v.Dein" . "tlinden@cpan.org") (:url . "https://github.com/tlinden/viking-mode"))]) (viewer . [(20170107 202) nil "View-mode extension" single ((:commit . "6c8db025bf4021428f7f2c3ef9d74fb13f5d267a") (:keywords "view" "extensions") (:authors ("rubikitch" . "rubikitch@ruby-lang.org")) (:maintainer "rubikitch" . "rubikitch@ruby-lang.org") (:url . "http://github.com/rubikitch/viewer/"))]) (vi-tilde-fringe . [(20141028 242) ((emacs (24))) "Displays tildes in the fringe on empty lines a la Vi." single ((:commit . "f1597a8d54535bb1d84b442577b2024e6f910308") (:keywords "emulation") (:authors ("Sylvain Benner" . "sylvain.benner@gmail.com")) (:maintainer "Sylvain Benner" . "sylvain.benner@gmail.com") (:url . "https://github.com/syl20bnr/vi-tilde-fringe"))]) (vhdl-tools . [(20180610 1658) ((ggtags (0 8 12)) (emacs (26 1)) (outshine (2 0)) (helm (2 9 6))) "Utilities for navigating vhdl sources." single ((:commit . "4e9df06c3519be22f1f713d18c80d325a5b0c3d2") (:keywords "languages" "convenience") (:authors ("Cayetano Santos")) (:maintainer "Cayetano Santos") (:url . "https://github.com/csantosb/vhdl-tools/wiki"))]) (vhdl-capf . [(20160221 1734) nil "Completion at point function (capf) for vhdl-mode." single ((:commit . "290abe217050f33532bc9ccb04f894123402f414") (:keywords "convenience" "usability" "vhdl" "completion") (:authors ("sh-ow" . "sh-ow@users.noreply.github.com")) (:maintainer "sh-ow" . "sh-ow@users.noreply.github.com") (:url . "https://github.com/sh-ow/vhdl-capf"))]) (vertigo . [(20180829 2230) ((dash (2 11 0))) "Jump across lines using the home row." single ((:commit . "6303d17270ea92290a6960890bca515274f1682b") (:keywords "vim" "vertigo") (:authors ("Fox Kiester" . "noct@posteo.net")) (:maintainer "Fox Kiester" . "noct@posteo.net") (:url . "https://github.com/noctuid/vertigo.el"))]) (vertica-snippets . [(20180208 954) ((yasnippet (0 6 1))) "Yasnippets for Vertica" tar ((:commit . "5959d86c77d4b8f67383f65f7f6ca3e0db2a9529") (:keywords "convenience" "snippets") (:authors ("Andreas Gerler" . "baron@bundesbrandschatzamt.de")) (:maintainer "Andreas Gerler" . "baron@bundesbrandschatzamt.de") (:url . "https://github.com/baron42bba/vertica-snippets"))]) (vertica . [(20131217 1511) ((sql (3 0))) "Vertica SQL mode extension" single ((:commit . "3c9647b425c5c13c30bf0cba483646af18196588") (:keywords "sql" "vertica") (:authors ("Roman Scherer" . "roman@burningswell.com")) (:maintainer "Roman Scherer" . "roman@burningswell.com"))]) (verify-url . [(20160426 1228) ((cl-lib (0 5))) "find out invalid urls in the buffer or region" single ((:commit . "d6f3623cda8cd526a2d198619b137059cb1ba1ab") (:keywords "convenience" "usability" "url") (:authors ("DarkSun" . "lujun9972@gmail.com")) (:maintainer "DarkSun" . "lujun9972@gmail.com") (:url . "https://github.com/lujun9972/verify-url"))]) (vector-utils . [(20140508 2041) nil "Vector-manipulation utility functions" single ((:commit . "c38ca1c6a23b2b51a6ac36c2c64e50e21cbe9d21") (:keywords "extensions") (:authors ("Roland Walker" . "walker@pobox.com")) (:maintainer "Roland Walker" . "walker@pobox.com") (:url . "http://github.com/rolandwalker/vector-utils"))]) (vdm-snippets . [(20180902 1835) ((emacs (24)) (yasnippet (0 13 0))) "YASnippets for VDM mode" tar ((:commit . "d5ee09de825c1ce53b1c68dfe318d879bf87e554") (:keywords "languages") (:authors ("Peter W. V. Tran-Jørgensen" . "peter.w.v.jorgensen@gmail.com")) (:maintainer "Peter W. V. Tran-Jørgensen" . "peter.w.v.jorgensen@gmail.com") (:url . "https://github.com/peterwvj/vdm-mode"))]) (vdm-mode . [(20180831 652) ((emacs (25))) "Major mode for the Vienna Development Method" tar ((:commit . "d5ee09de825c1ce53b1c68dfe318d879bf87e554") (:keywords "languages") (:authors ("Peter W. V. Tran-Jørgensen" . "peter.w.v.jorgensen@gmail.com")) (:maintainer "Peter W. V. Tran-Jørgensen" . "peter.w.v.jorgensen@gmail.com") (:url . "https://github.com/peterwvj/vdm-mode"))]) (vdirel . [(20170605 743) ((emacs (24 4)) (org-vcard (0 1 0)) (helm (1 7 0)) (seq (1 11))) "Manipulate vdir (i.e., vCard) repositories" single ((:commit . "72399f5e09f53aa25a068be8689cb711b8accf08") (:authors ("Damien Cassou" . "damien@cassou.me")) (:maintainer "Damien Cassou" . "damien@cassou.me"))]) (vdiff-magit . [(20180819 1802) ((emacs (24 4)) (vdiff (0 3)) (magit (2 10 0))) "magit integration for vdiff" single ((:commit . "2589b93a0a789b1d86e607cb84979c6a837eb008") (:keywords "diff") (:authors ("Justin Burkett" . "justin@burkett.cc")) (:maintainer "Justin Burkett" . "justin@burkett.cc") (:url . "https://github.com/justbur/emacs-vdiff-magit"))]) (vdiff . [(20180719 2027) ((emacs (24 4)) (hydra (0 13 0))) "A diff tool similar to  vimdiff" single ((:commit . "0e105218f167541421018bb61567f975f4ac16b8") (:keywords "diff") (:authors ("Justin Burkett" . "justin@burkett.cc")) (:maintainer "Justin Burkett" . "justin@burkett.cc") (:url . "https://github.com/justbur/emacs-vdiff"))]) (vcomp . [(20140906 2208) nil "compare version strings" single ((:commit . "092ef48a78e950c0576269d889be6caf9f6e61c5") (:keywords "versions") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:url . "https://github.com/tarsius/vcomp"))]) (vcl-mode . [(20170119 2051) nil "Syntax highlighting for Varnish Command Language" single ((:commit . "3d86c1352a7370d558d25f4c8f7be744e7d27332") (:authors ("Stig Sandbeck Mathisen" . "ssm@redpill-linpro.com")) (:maintainer "Stig Sandbeck Mathisen" . "ssm@redpill-linpro.com"))]) (vc-osc . [(20161119 1955) nil "non-resident support for osc version-control" single ((:commit . "8c09a0d5f69237285101554261b77d76b546a24b") (:authors ("Adam Spiers (see vc.el for full credits)")) (:maintainer "Adam Spiers" . "aspiers@suse.com"))]) (vc-msg . [(20180605 58) ((emacs (24 3)) (popup (0 5 0))) "Show commit information of current line" tar ((:commit . "ffd8db482cbd9fb63dace0e5ddcc7207a9c99f5e") (:keywords "git" "vc" "svn" "hg" "messenger") (:authors ("Chen Bin <chenbin DOT sh AT gmail DOT com>")) (:maintainer "Chen Bin <chenbin DOT sh AT gmail DOT com>") (:url . "http://github.com/redguardtoo/vc-msg"))]) (vc-fossil . [(20180215 1635) nil "VC backend for the fossil sofware configuraiton management system" tar ((:commit . "7c5af95181213db38f81f5f9586f3334301a3ea0") (:authors ("Venkat Iyer" . "venkat@comit.com")) (:maintainer "Venkat Iyer" . "venkat@comit.com"))]) (vc-darcs . [(20170905 320) ((emacs (24))) "a VC backend for darcs" single ((:commit . "390fb1ebdda1ffac45b9be02626dde3b6d95ac11") (:keywords "vc") (:authors ("Jorgen Schaefer" . "forcer@forcix.cx") ("Juliusz Chroboczek" . "jch@pps.univ-paris-diderot.fr")) (:maintainer "Libor Čapák" . "capak@inputwish.com"))]) (vc-check-status . [(20170107 1334) nil "Warn you when quitting emacs and leaving repo dirty." tar ((:commit . "37734beb16bfd8633ea328059bf9a47eed826d5c") (:keywords "vc" "convenience") (:authors ("Sylvain Rousseau <thisirs at gmail dot com>")) (:maintainer "Sylvain Rousseau <thisirs at gmail dot com>") (:url . "https://github.com/thisirs/vc-check-status"))]) (vc-auto-commit . [(20170107 1333) nil "Auto-committing feature for your repository" tar ((:commit . "446f664f4ec835532f4f18ba18b5fb731f6030aa") (:keywords "vc" "convenience") (:authors ("Sylvain Rousseau <thisirs at gmail dot com>")) (:maintainer "Sylvain Rousseau <thisirs at gmail dot com>") (:url . "http://github.com/thisirs/vc-auto-commit.git"))]) (vbasense . [(20140221 2353) ((auto-complete (1 4 0)) (log4e (0 2 0)) (yaxception (0 1))) "provide a environment like Visual Basic Editor." tar ((:commit . "8c61a492d7c15218ae1a96e2aebfe6f78bfff6db") (:keywords "vba" "completion") (:authors ("Hiroaki Otsu" . "ootsuhiroaki@gmail.com")) (:maintainer "Hiroaki Otsu" . "ootsuhiroaki@gmail.com") (:url . "https://github.com/aki2o/emacs-vbasense"))]) (vala-snippets . [(20150429 352) ((yasnippet (0 8 0))) "Yasnippets for Vala" tar ((:commit . "671439501060449bd100b9fffd524a86064fbfbb") (:authors ("Daniel Gopar")) (:maintainer "Daniel Gopar") (:url . "https://github.com/gopar/vala-snippets"))]) (vala-mode . [(20150324 2225) nil "Vala mode derived mode" single ((:commit . "fb2871a4492d75d03d72e60474919ab89adb267b") (:keywords "vala" "languages" "oop") (:authors ("2005 Dylan R. E. Moonfire") ("       2008 Étienne BERSAC")) (:maintainer "Étienne BERSAC" . "bersace03@laposte.net"))]) (vagrant-tramp . [(20160427 2332) ((dash (2 12 0))) "Vagrant method for TRAMP" tar ((:commit . "453ba605b28d2964bb4e10074f1e6891ebb4d2d6") (:keywords "vagrant") (:authors ("Doug MacEachern" . "dougm@vmware.com") ("Ryan Prior     " . "ryanprior@gmail.com")) (:maintainer "Doug MacEachern" . "dougm@vmware.com") (:url . "https://github.com/dougm/vagrant-tramp"))]) (vagrant . [(20170301 2206) nil "Manage a vagrant box from emacs" single ((:commit . "636ce2f9af32ea199170335a9cf1201b64873440") (:keywords "vagrant" "chef") (:authors ("Robert Crim" . "rob@servermilk.com")) (:maintainer "Robert Crim" . "rob@servermilk.com") (:url . "https://github.com/ottbot/vagrant.el"))]) (v2ex-mode . [(20160720 345) ((cl-lib (0 5)) (request (0 2)) (let-alist (1 0 3))) "Major mode for visit http://v2ex.com/ site." single ((:commit . "b7d19bb594b43ea3824a6f215dd1e5d1d4c0e8ad") (:keywords "v2ex" "v2ex.com") (:authors ("Aborn Jiang" . "aborn.jiang@gmail.com")) (:maintainer "Aborn Jiang" . "aborn.jiang@gmail.com") (:url . "https://github.com/aborn/v2ex-mode"))]) (uuidgen . [(20140918 2301) nil "Provides various UUID generating functions" single ((:commit . "7eb96415484c3854a3f383d1a3e10b87ae674e22") (:keywords "extensions" "lisp" "tools") (:authors ("Kan-Ru Chen" . "koster@debian.org")) (:maintainer "Kan-Ru Chen" . "koster@debian.org"))]) (uuid . [(20120910 851) nil "UUID's for EmacsLisp" single ((:commit . "1519bfeb0e31602b840bc8dd35d7c7e732c159fe") (:keywords "lisp") (:authors ("James Mastros")) (:maintainer "Nic Ferrier" . "nferrier@ferrier.me.uk"))]) (utop . [(20180706 2249) ((emacs (24))) "Universal toplevel for OCaml" single ((:commit . "53db99356e5136f8600dd910c651811d19bc65a2") (:keywords "ocaml" "languages") (:authors ("Jeremie Dimino" . "jeremie@dimino.org")) (:maintainer "Jeremie Dimino" . "jeremie@dimino.org") (:url . "https://github.com/diml/utop"))]) (usql . [(20180305 2323) ((emacs (25 1))) "U-SQL support for sql-mode" single ((:commit . "bfaf428b366a9a185eef84f0d645a98dc918fe3d") (:keywords "languages") (:authors ("Nicholas Barnwell" . "nb@ul.io")) (:maintainer "Nicholas Barnwell" . "nb@ul.io") (:url . "https://github.com/nickbarwell/usql.el"))]) (use-ttf . [(20180609 552) ((emacs (24 4)) (s (1 12 0))) "Use the same font cross OS." single ((:commit . "be1599e10ae5c095cd263a1d9be3e8270f770f55") (:authors ("Shen, Jen-Chieh" . "jcs090218@gmail.com")) (:maintainer "Shen, Jen-Chieh" . "jcs090218@gmail.com") (:url . "https://github.com/jcs090218/use-ttf"))]) (use-package-ensure-system-package . [(20180710 729) ((use-package (2 1)) (system-packages (1 0 4))) "auto install system packages" single ((:commit . "3fb8f39f5901a4c0ef7887283e56e60b541675ea") (:keywords "convenience" "tools" "extensions") (:authors ("Justin Talbott" . "justin@waymondo.com")) (:maintainer "Justin Talbott" . "justin@waymondo.com") (:url . "https://github.com/waymondo/use-package-ensure-system-package"))]) (use-package-el-get . [(20180131 505) ((use-package (1 0))) "el-get support for use package" single ((:commit . "cba87c4e9a3a66b7c10962e3aefdf11c83d737bc") (:keywords "dotemacs" "startup" "speed" "config" "package" "tools") (:authors ("Edward Knyshov" . "edvorg@gmail.com")) (:maintainer "Edward Knyshov" . "edvorg@gmail.com") (:url . "https://github.com/edvorg/use-package-el-get"))]) (use-package-chords . [(20180703 1958) ((use-package (2 1)) (bind-key (1 0)) (bind-chord (0 2)) (key-chord (0 6))) "key-chord keyword for use-package" single ((:commit . "3fb8f39f5901a4c0ef7887283e56e60b541675ea") (:keywords "convenience" "tools" "extensions") (:authors ("Justin Talbott" . "justin@waymondo.com")) (:maintainer "Justin Talbott" . "justin@waymondo.com") (:url . "https://github.com/waymondo/use-package-chords"))]) (use-package . [(20180715 1801) ((emacs (24 3)) (bind-key (2 4))) "A configuration macro for simplifying your .emacs" tar ((:commit . "3fb8f39f5901a4c0ef7887283e56e60b541675ea") (:keywords "dotemacs" "startup" "speed" "config" "package") (:authors ("John Wiegley" . "johnw@newartisans.com")) (:maintainer "John Wiegley" . "johnw@newartisans.com") (:url . "https://github.com/jwiegley/use-package"))]) (usage-memo . [(20170926 37) nil "integration of Emacs help system and memo" single ((:commit . "88e15a9942a3e0a6e36e9c3e51e3edb746067b1a") (:keywords "convenience" "languages" "lisp" "help" "tools" "docs") (:authors ("rubikitch" . "rubikitch@ruby-lang.org")) (:maintainer "rubikitch" . "rubikitch@ruby-lang.org") (:url . "http://www.emacswiki.org/cgi-bin/wiki/download/usage-memo.el"))]) (urlenc . [(20140116 1456) nil "URL encoding/decoding utility for Emacs." single ((:commit . "835a6dcb783bbe84714bae87a3464aa0b128bfac") (:keywords "url") (:authors ("Taiki SUGAWARA" . "buzz.taiki@gmail.com")) (:maintainer "Taiki SUGAWARA" . "buzz.taiki@gmail.com") (:url . "https://github.com/buzztaiki/urlenc-el"))]) (url-shortener . [(20170805 242) nil "shorten long url and expand tinyurl" single ((:commit . "06db8270213b9e352d6c335b0663059a1353d05e") (:authors ("Yu Yang" . "yy2012cn@NOSPAM.gmail.com")) (:maintainer "Yu Yang" . "yy2012cn@NOSPAM.gmail.com") (:url . "https://github.com/yuyang0/url-shortener"))]) (uptimes . [(20180416 1323) ((cl-lib (0 5)) (emacs (24))) "Track and display emacs session uptimes." single ((:commit . "5e81f8bb419836602819045e7d5a74b76ad3e69c") (:keywords "processes" "uptime") (:authors ("Dave Pearson" . "davep@davep.org")) (:maintainer "Dave Pearson" . "davep@davep.org") (:url . "https://github.com/davep/uptimes.el"))]) (upbo . [(20180422 822) ((dash (2 12 0)) (emacs (24 4))) "Karma Test Runner Integration" single ((:commit . "c37728e11dedd29d849ba9523465b0cdaccea9d5") (:keywords "javascript" "js" "test" "karma") (:authors ("Sungho Kim(shiren)")) (:maintainer "Sungho Kim(shiren)") (:url . "http://github.com/shiren"))]) (untitled-new-buffer . [(20161212 1508) ((emacs (24 4)) (magic-filetype (0 2 0))) "Open untitled new buffer like other text editors." single ((:commit . "4eabc6937b0e83062ffce9de0d42110224063a6c") (:keywords "files" "convenience") (:authors ("USAMI Kenta" . "tadsan@zonu.me")) (:maintainer "USAMI Kenta" . "tadsan@zonu.me") (:url . "https://github.com/zonuexe/untitled-new-buffer.el"))]) (unkillable-scratch . [(20160505 203) nil "Disallow buffers from being killed by regexp -- default is *scratch* buffer" single ((:commit . "676a5a97658830caece18fa65a23e3d113933151") (:keywords "scratch") (:authors ("Eric Crosson" . "esc@ericcrosson.com")) (:maintainer "Eric Crosson" . "esc@ericcrosson.com"))]) (universal-emotions-emoticons . [(20180729 1941) ((emacs (24 4))) "Emoticons For The Six Universal Expressions" single ((:commit . "9cedd09ee65cb9fa71f27b0ab46a8353bdc00902") (:keywords "convenience" "docs" "languages") (:authors ("Grant Rettke" . "gcr@wisdomandwonder.com")) (:maintainer nil . "<gcr@wisdomandwonder.com>") (:url . "https://github.com/grettke/universal-emotions-emoticons"))]) (unison-mode . [(20160513 1501) nil "Syntax highlighting for unison file synchronization program" single ((:commit . "0bd6a65c0d12f87fcf7bdff15fe54444959b93bf") (:keywords "symchronization" "unison") (:authors ("Karl Fogelmark" . "karlfogel@gmail.com")) (:maintainer "Karl Fogelmark" . "karlfogel@gmail.com") (:url . "https://github.com/impaktor/unison-mode"))]) (unison . [(20160704 740) ((emacs (24 1))) "sync with Unison" single ((:commit . "a78a04c0d1398d00f75a1bd4799622a65bcb0f28") (:keywords "sync") (:authors ("Kevin Brubeck Unhammer" . "unhammer@fsfe.org")) (:maintainer "Kevin Brubeck Unhammer" . "unhammer@fsfe.org") (:url . "http://github.com/unhammer/unison.el"))]) (unipoint . [(20140113 2224) nil "a simple way to insert unicode characters by TeX name" single ((:commit . "5da04aebac35a5c9e1d8704f2231808d42f4b36a") (:authors ("Andrew Gwozdziewycz" . "git@apgwoz.com")) (:maintainer "Andrew Gwozdziewycz" . "git@apgwoz.com") (:url . "https://github.com/apgwoz/unipoint"))]) (unify-opening . [(20171122 2012) ((emacs (24 4))) "Unify the mechanism to open files" single ((:commit . "502469ddba6d8d52159f53976265f7d956b6b17c") (:authors ("Damien Cassou" . "damien.cassou@gmail.com")) (:maintainer "Damien Cassou" . "damien.cassou@gmail.com") (:url . "https://github.com/DamienCassou/unify-opening"))]) (unidecode . [(20180312 1926) nil "Transliterate Unicode to ASCII" tar ((:commit . "5502ada9287b4012eabb879f12f5b0a9df52c5b7") (:authors ("sindikat <sindikat at mail36 dot net>")) (:maintainer "John Mastro" . "john.b.mastro@gmail.com"))]) (unicode-whitespace . [(20140508 2041) ((ucs-utils (0 7 6)) (list-utils (0 4 2)) (persistent-soft (0 8 8)) (pcache (0 2 3))) "teach whitespace-mode about fancy characters" single ((:commit . "a18c6b38d78b94f2eb1dcc4cb4fa91b6a17efabe") (:keywords "faces" "wp" "interface") (:authors ("Roland Walker" . "walker@pobox.com")) (:maintainer "Roland Walker" . "walker@pobox.com") (:url . "http://github.com/rolandwalker/unicode-whitespace"))]) (unicode-troll-stopper . [(20151024 131) nil "Minor mode for Highlighting Unicode homoglyphs" single ((:commit . "15e4b57b78bf643bb56e5000078030cbb5c66e2a") (:keywords "unicode") (:authors ("Cam Saül" . "cammsaul@gmail.com")) (:maintainer "Cam Saül" . "cammsaul@gmail.com") (:url . "https://github.com/camsaul/emacs-unicode-troll-stopper"))]) (unicode-progress-reporter . [(20140508 2041) ((emacs (24 1 0)) (ucs-utils (0 7 6)) (list-utils (0 4 2)) (persistent-soft (0 8 8)) (pcache (0 2 3))) "Progress-reporter with fancy characters" single ((:commit . "5e66724fd7d15743213b082474d798117b194494") (:keywords "interface") (:authors ("Roland Walker" . "walker@pobox.com")) (:maintainer "Roland Walker" . "walker@pobox.com") (:url . "http://github.com/rolandwalker/unicode-progress-reporter"))]) (unicode-input . [(20141219 720) nil "Support for unicode character input" single ((:keywords "unicode" "input") (:authors ("m00nlight" . "dot_wangyushi@yeah.net")) (:maintainer "m00nlight" . "dot_wangyushi@yeah.net"))]) (unicode-fonts . [(20150826 2232) ((font-utils (0 7 8)) (ucs-utils (0 8 2)) (list-utils (0 4 2)) (persistent-soft (0 8 10)) (pcache (0 3 1))) "Configure Unicode fonts" single ((:commit . "a36597d83e0248bd0e6b2c1d5fb95bff72add527") (:keywords "i18n" "faces" "frames" "wp" "interface") (:authors ("Roland Walker" . "walker@pobox.com")) (:maintainer "Roland Walker" . "walker@pobox.com") (:url . "http://github.com/rolandwalker/unicode-fonts"))]) (unicode-escape . [(20160614 1234) ((emacs (24)) (names (20151201 0)) (dash (2 12 1))) "Escape/Unescape unicode notations" single ((:commit . "fc69ec780d9e54c364a9252bd0cf1d2507f3fab7") (:keywords "i18n" "unicode") (:authors ("KOBAYASHI Shigeru (kosh)" . "shigeru.kb@gmail.com")) (:maintainer "KOBAYASHI Shigeru (kosh)" . "shigeru.kb@gmail.com") (:url . "https://github.com/kosh04/unicode-escape.el"))]) (unicode-enbox . [(20140508 2041) ((string-utils (0 3 2)) (ucs-utils (0 7 6)) (list-utils (0 4 2)) (persistent-soft (0 8 8)) (pcache (0 2 3))) "Surround a string with box-drawing characters" single ((:commit . "77074fac1994a4236f111d6a1d0cf79ea3fca151") (:keywords "extensions" "interface") (:authors ("Roland Walker" . "walker@pobox.com")) (:maintainer "Roland Walker" . "walker@pobox.com") (:url . "http://github.com/rolandwalker/unicode-enbox"))]) (unicode-emoticons . [(20150204 1108) nil "Shortcuts for common unicode emoticons" single ((:commit . "fb18631f342b0243cf77cf59ed2067c47aae5233") (:keywords "games" "entertainment" "comms") (:authors ("Gunther Hagleitner")) (:maintainer "Gunther Hagleitner") (:url . "https://github.com/hagleitn/unicode-emoticons"))]) (unfill . [(20170723 146) nil "Unfill paragraphs or regions, and toggle between filled & unfilled" single ((:commit . "df0c4dee19a3874b11c7c7f04e8a2fba629fda9b") (:keywords "utilities") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:url . "https://github.com/purcell/unfill"))]) (undohist . [(20150315 1242) ((cl-lib (1 0))) "Persistent undo history for GNU Emacs" single ((:commit . "d2239a5f736724ceb9e3b6bcaa86f4064805cda0") (:keywords "convenience") (:authors ("MATSUYAMA Tomohiro" . "m2ym.pub@gmail.com")) (:maintainer "MATSUYAMA Tomohiro" . "m2ym.pub@gmail.com"))]) (underwater-theme . [(20131118 2) nil "A gentle, deep blue color theme" single ((:commit . "4eb9ef014f580adc135d91d1cd68d37a310640b6") (:keywords "faces") (:authors ("Jon-Michael Deldin" . "dev@jmdeldin.com")) (:maintainer "Jon-Michael Deldin" . "dev@jmdeldin.com"))]) (underline-with-char . [(20170814 923) ((emacs (24))) "Underline with a char" single ((:commit . "6daeba77e17dc11558ca3ccb0495524f5104d581") (:keywords "convenience") (:maintainer nil . "marcowahlsoft@gmail.com"))]) (undercover . [(20180403 1452) ((emacs (24)) (dash (2 0 0)) (shut-up (0 3 2))) "Test coverage library for Emacs Lisp" single ((:commit . "3fc54ef92f0b4b7d26d962d6ed29a81d526a3a66") (:keywords "lisp" "tests" "coverage" "tools") (:authors ("Sviridov Alexander" . "sviridov.vmi@gmail.com")) (:maintainer "Sviridov Alexander" . "sviridov.vmi@gmail.com") (:url . "https://github.com/sviridov/undercover.el"))]) (uncrustify-mode . [(20130707 1359) nil "Minor mode to automatically uncrustify." single ((:commit . "73893d000361e95784911e5ec268ad0ab2a1473c") (:keywords "uncrustify") (:authors ("Tabito Ohtani" . "koko1000ban@gmail.com")) (:maintainer "Tabito Ohtani" . "koko1000ban@gmail.com"))]) (ukrainian-holidays . [(20130720 1349) nil "Ukrainian holidays for Emacs calendar." single ((:commit . "e52b0c92843e9f4d0415a7ba3b8559785497d23d") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:url . "https://github.com/abo-abo/ukrainian-holidays"))]) (ujelly-theme . [(20180214 1624) nil "Ujelly theme for GNU Emacs 24 (deftheme)" single ((:commit . "bf724ce7806a738d2043544061e5f9bbfc56e674") (:authors ("Mark Tran" . "mark.tran@gmail.com")) (:maintainer "Mark Tran" . "mark.tran@gmail.com") (:url . "http://github.com/marktran/color-theme-ujelly"))]) (uimage . [(20160901 1221) nil "An iimage like mode with the ability to display url images" single ((:commit . "9893d09160ef7e8c0ecdcd74fca99ffeb5f9d70d") (:keywords "lisp" "url" "image") (:authors ("DarkSun" . "lujun9972@gmail.com")) (:maintainer "DarkSun" . "lujun9972@gmail.com"))]) (ucs-utils . [(20150826 1414) ((persistent-soft (0 8 8)) (pcache (0 2 3)) (list-utils (0 4 2))) "Utilities for Unicode characters" tar ((:commit . "cbfd42f822bf5717934fa2d92060e6e24a813433") (:keywords "i18n" "extensions") (:authors ("Roland Walker" . "walker@pobox.com")) (:maintainer "Roland Walker" . "walker@pobox.com") (:url . "http://github.com/rolandwalker/ucs-utils"))]) (ubuntu-theme . [(20150805 1506) nil "A theme inspired by the default terminal colors in Ubuntu" single ((:commit . "88b0eefc75d4cbcde103057e1c5968d4c3052f69") (:authors ("Francesc Rocher" . "francesc.rocher@gmail.com")) (:maintainer "Francesc Rocher" . "francesc.rocher@gmail.com") (:url . "http://github.com/rocher/ubuntu-theme"))]) (typoscript-mode . [(20170126 912) ((emacs (24 4)) (use-package (0))) "mode for TypoScript files" single ((:commit . "44e7567e921573c4f33c537b827f71fb1f565c32") (:keywords "typo3" "typoscript") (:authors ("Johannes Goslar")) (:maintainer "Johannes Goslar") (:url . "https://github.com/ksjogo/typoscript-mode"))]) (typo . [(20171209 1023) nil "Minor mode for typographic editing" single ((:commit . "9dad93b6f367f02f52c8d9bf15d446d922cec294") (:keywords "convenience" "wp") (:authors ("Jorgen Schaefer" . "forcer@forcix.cx")) (:maintainer "Jorgen Schaefer" . "forcer@forcix.cx") (:url . "https://github.com/jorgenschaefer/typoel"))]) (typit . [(20180317 807) ((emacs (24 4)) (f (0 18)) (mmt (0 1 1))) "Typing game similar to tests on 10 fast fingers" tar ((:commit . "4fe50d616fc60e77eb9b5a824c0a1ca4010b0746") (:keywords "games") (:authors ("Mark Karpov" . "markkarpov92@gmail.com")) (:maintainer "Mark Karpov" . "markkarpov92@gmail.com") (:url . "https://github.com/mrkkrp/typit"))]) (typing-game . [(20160426 1220) nil "a simple typing game" single ((:commit . "616435a5270274f4c7b698697674dbb2039049a4") (:keywords "lisp" "game") (:authors ("DarkSun" . "lujun9972@gmail.com")) (:maintainer "DarkSun" . "lujun9972@gmail.com"))]) (typing . [(20180830 2203) nil "The Typing Of Emacs" single ((:commit . "a2ef25dde2d8eb91bd9c0c6164cb5208208647fa") (:keywords "games") (:authors ("Alex Schroeder" . "alex@gnu.org")) (:maintainer "Alex Schroeder" . "alex@gnu.org") (:url . "http://www.emacswiki.org/emacs/TypingOfEmacs"))]) (typescript-mode . [(20180802 1114) nil "Major mode for editing typescript" single ((:commit . "7c6fd0f4a8f32fdda3eecbd423a124302cfcfcf5") (:keywords "typescript" "languages") (:url . "http://github.com/ananthakumaran/typescript.el"))]) (typed-clojure-mode . [(20151003 1822) ((clojure-mode (2 1 1)) (cider (0 10 0 -4))) "Typed Clojure minor mode for Emacs" tar ((:commit . "3abd53d8cc1ad77ffe76e02849d0ab7731fd8364") (:authors ("John Walker <john.lou.walker@gmail.com>, Ambrose Bonnaire-Sergeant" . "abonnairesergeant@gmail.com")) (:maintainer "John Walker <john.lou.walker@gmail.com>, Ambrose Bonnaire-Sergeant" . "abonnairesergeant@gmail.com") (:url . "https://github.com/typedclojure/typed-clojure-mode"))]) (twittering-mode . [(20180818 1451) nil "Major mode for Twitter" single ((:commit . "ab26e683674a854a1e518995d60967ff417b2cff") (:keywords "twitter" "web") (:authors ("Tadashi MATSUO" . "tad@mymail.twin.ne.jp") ("Y. Hayamizu" . "y.hayamizu@gmail.com") ("Tsuyoshi CHO" . "Tsuyoshi.CHO+develop@Gmail.com") ("Alberto Garcia" . "agarcia@igalia.com") ("Xavier Maillard" . "xavier@maillard.im")) (:maintainer "Tadashi MATSUO" . "tad@mymail.twin.ne.jp") (:url . "http://twmode.sf.net/"))]) (twilight-theme . [(20120412 1303) nil "Twilight theme for GNU Emacs 24 (deftheme)" single ((:commit . "77c4741cb3dcf16e53d06d6c2ffdc660c40afb5b") (:authors ("Nick Parker" . "nickp@developernotes.com")) (:maintainer "Nick Parker" . "nickp@developernotes.com"))]) (twilight-bright-theme . [(20130605 843) nil "A Emacs 24 faces port of the TextMate theme" single ((:commit . "322157cb2f3bf7920ecd209dafc31bc1c7959f49") (:keywords "themes") (:authors ("Jim Myhrberg" . "contact@jimeh.me")) (:maintainer "Jim Myhrberg" . "contact@jimeh.me") (:url . "https://github.com/jimeh/twilight-bright-theme.el"))]) (twilight-anti-bright-theme . [(20160622 848) nil "A soothing Emacs 24 light-on-dark theme" single ((:commit . "523b95fcdbf4a6a6483af314ad05354a3d80f23f") (:keywords "themes") (:authors ("Jim Myhrberg" . "contact@jimeh.me")) (:maintainer "Jim Myhrberg" . "contact@jimeh.me") (:url . "https://github.com/jimeh/twilight-anti-bright-theme.el"))]) (twig-mode . [(20130220 1850) nil "A major mode for twig" single ((:commit . "2849f273a4855d3314a9c0cc84134f5b28ad5ea6") (:authors ("Bojan Matic aka moljac024")) (:maintainer "Bojan Matic aka moljac024"))]) (turnip . [(20150309 629) ((dash (2 6 0)) (s (1 9 0))) "Interacting with tmux from Emacs" single ((:commit . "2fd32562fc6fc1cda6d91aa939cfb29f9b16e9de") (:keywords "terminals" "tools") (:authors ("Johann Klähn" . "kljohann@gmail.com")) (:maintainer "Johann Klähn" . "kljohann@gmail.com"))]) (turkish . [(20170910 1511) nil "Convert to Turkish characters on-the-fly" single ((:commit . "9831a316c176bb21a1b91226323ea4133163e00c") (:keywords "turkish" "languages" "automatic" "conversion") (:authors ("Deniz Yüret")) (:maintainer "Emre Sevinç" . "emre.sevinc@gmail.com") (:url . "http://www.denizyuret.com/2006/11/emacs-turkish-mode.html"))]) (turing-machine . [(20180222 438) ((emacs (24 4))) "Single-tape Turing machine simulator" single ((:commit . "fa60b76a5bac1f54b7a1b3dc55aae7602c7e385b") (:keywords "turing" "machine" "simulation") (:authors ("Diego A. Mundo" . "diegoamundo@gmail.com")) (:maintainer "Diego A. Mundo" . "diegoamundo@gmail.com") (:url . "http://github.com/therockmandolinist/turing-machine"))]) (tup-mode . [(20140410 1614) nil "Major mode for editing files for Tup" single ((:commit . "bcc100c6485f1c81fdcd1215dfc6c41a81c215c8") (:authors ("Eric James Michael Ritz" . "lobbyjones@gmail.com")) (:maintainer "Eric James Michael Ritz" . "lobbyjones@gmail.com") (:url . "https://github.com/ejmr/tup-mode"))]) (tumblesocks . [(20140215 2047) ((htmlize (1 39)) (oauth (1 0 3)) (markdown-mode (1 8 1))) "An Emacs tumblr client." tar ((:commit . "85a6cdc2db3390593fd886c474959b675460b310"))]) (tumble . [(20160112 729) ((http-post-simple (0)) (cl-lib (0 5))) "an Tumblr mode for Emacs" single ((:commit . "e8fd7643cccf2b6ea4170f0c5f1f87d007e7fa00") (:keywords "tumblr") (:authors ("Federico Builes" . "federico.builes@gmail.com")) (:maintainer "Federico Builes" . "federico.builes@gmail.com"))]) (tuareg . [(20180512 2006) ((caml (3 12 0 1))) "OCaml mode for Emacs." tar ((:commit . "faa976ac930d3fba42ec59881046929c90ffa8f3") (:keywords "ocaml" "languages") (:authors ("Albert Cohen" . "Albert.Cohen@inria.fr") ("Sam Steingold" . "sds@gnu.org") ("Christophe Troestler" . "Christophe.Troestler@umons.ac.be") ("Till Varoquaux" . "till@pps.jussieu.fr") ("Sean McLaughlin" . "seanmcl@gmail.com") ("Stefan Monnier" . "monnier@iro.umontreal.ca")) (:maintainer "Albert Cohen" . "Albert.Cohen@inria.fr") (:url . "https://github.com/ocaml/tuareg"))]) (ttl-mode . [(20160505 832) nil "mode for Turtle (and Notation 3)" single nil]) (tt-mode . [(20130804 1110) nil "Emacs major mode for editing Template Toolkit files." single ((:commit . "85ed3832e7eef391f7879d9990d59c7a3493c15e") (:authors ("Dave Cross" . "dave@dave.org.uk")) (:maintainer "Dave Cross" . "dave@dave.org.uk"))]) (tss . [(20150913 1408) ((auto-complete (1 4 0)) (json-mode (1 1 0)) (log4e (0 2 0)) (yaxception (0 1))) "provide a interface for auto-complete.el/flymake.el on typescript-mode." tar ((:commit . "81ac6351a2ae258fd0ebf916dae9bd5a179fefd0") (:keywords "typescript" "completion") (:authors ("Hiroaki Otsu" . "ootsuhiroaki@gmail.com")) (:maintainer "Hiroaki Otsu" . "ootsuhiroaki@gmail.com") (:url . "https://github.com/aki2o/emacs-tss"))]) (ts-comint . [(20171106 647) nil "Run a Typescript interpreter in an inferior process window." single ((:commit . "8817dc7b3a6eb78c3cad42e5677c2113274a1963") (:keywords "typescript" "node" "inferior-mode" "convenience") (:authors ("Paul Huff" . "paul.huff@gmail.com")) (:maintainer "Paul Huff" . "paul.huff@gmail.com") (:url . "https://github.com/josteink/ts-comint"))]) (try . [(20170226 1605) ((emacs (24))) "Try out Emacs packages." single ((:commit . "271b0a362cadf44d0694628b9e213f54516ef913") (:keywords "packages") (:authors ("Lars Tveito" . "larstvei@ifi.uio.no")) (:maintainer "Lars Tveito" . "larstvei@ifi.uio.no") (:url . "http://github.com/larstvei/try"))]) (truthy . [(20140508 2041) ((list-utils (0 4 2))) "Test the content of a value" single ((:commit . "8ed8d07772aa8457554547eb17e264b5df2b4a69") (:keywords "extensions") (:authors ("Roland Walker" . "walker@pobox.com")) (:maintainer "Roland Walker" . "walker@pobox.com") (:url . "http://github.com/rolandwalker/truthy"))]) (trr . [(20170221 842) nil "a type-writing training program on GNU Emacs." tar ((:commit . "83660d8343ef3367837354dc684dfdde2f95826a") (:keywords "games" "faces") (:authors ("YAMAMOTO Hirotaka" . "ymmt@is.s.u-tokyo.ac.jp") ("KATO Kenji" . "kato@suri.co.jp") ("	*Original Author") ("INAMURA You" . "inamura@icot.or.jp") ("	*Original Author")) (:maintainer "YAMAMOTO Hirotaka" . "ymmt@is.s.u-tokyo.ac.jp"))]) (trinary . [(20180825 1050) ((emacs (24))) "Trinary logic." single ((:commit . "dc10294af106ff3b110c372841eef0a8ec4c29c7") (:keywords "languages") (:authors ("Matúš Goljer" . "matus.goljer@gmail.com")) (:maintainer "Matúš Goljer" . "matus.goljer@gmail.com") (:url . "https://github.com/Fuco1/trinary-logic"))]) (trident-mode . [(20130726 1907) ((emacs (24)) (slime (20130526)) (skewer-mode (1 5 0)) (dash (1 0 3))) "Live Parenscript interaction" single ((:commit . "ad3201f47e114de35df189c3d80f0fdea9507ea9") (:keywords "languages" "lisp" "processes" "tools") (:authors ("John Mastro" . "john.b.mastro@gmail.com")) (:maintainer "John Mastro" . "john.b.mastro@gmail.com") (:url . "https://github.com/johnmastro/trident-mode.el"))]) (treepy . [(20180724 656) ((emacs (25 1))) "Generic tree traversal tools" single ((:commit . "b40e6b09eb9be45da67b8c9e4990a5a0d7a2a09d") (:keywords "lisp" "maint" "tools") (:authors ("Daniel Barreto" . "daniel.barreto.n@gmail.com")) (:maintainer "Daniel Barreto" . "daniel.barreto.n@gmail.com") (:url . "https://github.com/volrath/treepy.el"))]) (treemacs-projectile . [(20180614 1721) ((projectile (0 14 0)) (treemacs (0))) "Projectile integration for treemacs" single ((:commit . "2ca96dcb9efba8fdb1ba16f73e5412f5df1e23d2") (:authors ("Alexander Miller" . "alexanderm@web.de")) (:maintainer "Alexander Miller" . "alexanderm@web.de") (:url . "https://github.com/Alexander-Miller/treemacs"))]) (treemacs-evil . [(20180803 1017) ((evil (1 2 12)) (treemacs (0))) "Evil mode integration for treemacs" single ((:commit . "2ca96dcb9efba8fdb1ba16f73e5412f5df1e23d2") (:authors ("Alexander Miller" . "alexanderm@web.de")) (:maintainer "Alexander Miller" . "alexanderm@web.de") (:url . "https://github.com/Alexander-Miller/treemacs"))]) (treemacs . [(20180830 1931) ((emacs (25 2)) (cl-lib (0 5)) (dash (2 11 0)) (s (1 10 0)) (f (0 11 0)) (ace-window (0 9 0)) (pfuture (1 2)) (hydra (0 13 2)) (ht (2 2))) "A tree style file explorer package" tar ((:commit . "2ca96dcb9efba8fdb1ba16f73e5412f5df1e23d2") (:authors ("Alexander Miller" . "alexanderm@web.de")) (:maintainer "Alexander Miller" . "alexanderm@web.de") (:url . "https://github.com/Alexander-Miller/treemacs"))]) (tree-mode . [(20151104 1331) nil "A mode to manage tree widgets" single ((:commit . "b06078826d5875d74b0e7b7ac47b0d0917610534") (:keywords "help" "convenience" "widget") (:authors (nil . "wenbinye@163.com")) (:maintainer nil . "wenbinye@163.com"))]) (travis . [(20150825 1138) ((s (1 9 0)) (dash (2 9 0)) (pkg-info (0 5 0)) (request (0 1 0))) "Emacs client for Travis" tar ((:commit . "754ef07c17fed17ab03664ad11e2b0b2ef5e78ed") (:keywords "travis") (:authors ("Nicolas Lamirault" . "nicolas.lamirault@gmail.com")) (:maintainer "Nicolas Lamirault" . "nicolas.lamirault@gmail.com") (:url . "https://github.com/nlamirault/emacs-travis"))]) (transpose-mark . [(20150405 716) nil "Transpose data using the Emacs mark" single ((:commit . "667327602004794de97214cf336ac61650ef75b7") (:keywords "transpose" "convenience") (:authors ("Kevin W. van Rooijen" . "kevin.van.rooijen@attichacker.com")) (:maintainer "Kevin W. van Rooijen" . "kevin.van.rooijen@attichacker.com"))]) (transpose-frame . [(20151126 1426) nil "Transpose windows arrangement in a frame" single ((:commit . "011f420c3496b69fc22d789f64cb8091834feba7") (:keywords "window") (:authors ("S. Irie")) (:maintainer "S. Irie"))]) (transmission . [(20180728 1717) ((emacs (24 4)) (let-alist (1 0 5))) "Interface to a Transmission session" single ((:commit . "bbe4077b89afe732d346eeed1ad0783537f33480") (:keywords "comm" "tools") (:authors ("Mark Oteiza" . "mvoteiza@udel.edu")) (:maintainer "Mark Oteiza" . "mvoteiza@udel.edu"))]) (transfer-sh . [(20180603 1431) ((async (1 0))) "Simple interface for sending buffer contents to transfer.sh" single ((:commit . "55da85f963d347255a2b46568954923679331798") (:keywords "cloud" "upload" "share") (:authors ("S. Roskamp" . "steffen.roskamp@gmail.com")) (:maintainer "S. Roskamp" . "steffen.roskamp@gmail.com"))]) (tramp-term . [(20180223 1527) nil "Automatic setup of directory tracking in ssh sessions." single ((:commit . "7c29f888de0385a676dbf9a4e17bac0111f5c10a") (:keywords "tramp" "ssh") (:authors ("Randy Morris" . "randy.morris@archlinux.us")) (:maintainer "Randy Morris" . "randy.morris@archlinux.us") (:url . "https://github.com/randymorris/tramp-term.el"))]) (tramp-hdfs . [(20170821 1320) ((emacs (24 4))) "Tramp extension to access hadoop/hdfs file system in Emacs" single ((:commit . "f8406f77bf83b66306ced693a5e4aaf606f46762") (:keywords "tramp" "emacs" "hdfs" "hadoop" "webhdfs" "rest") (:authors ("Raghav Kumar Gautam" . "raghav@apache.org")) (:maintainer "Raghav Kumar Gautam" . "raghav@apache.org"))]) (tracwiki-mode . [(20150119 1621) ((xml-rpc (1 6 8))) "Emacs Major mode for working with Trac" single ((:commit . "6a620444d59b438f42383b48cd4c19c03105dba6") (:keywords "trac" "wiki" "tickets") (:authors ("Matthew Erickson" . "peawee@peawee.net")) (:maintainer "Matthew Erickson" . "peawee@peawee.net"))]) (tracking . [(20171210 2102) nil "Buffer modification tracking" tar ((:commit . "fedfa7eb8516a53fa70b6a1f4fce4b5ab66ea91f") (:authors ("Jorgen Schaefer" . "forcer@forcix.cx")) (:maintainer "Jorgen Schaefer" . "forcer@forcix.cx") (:url . "https://github.com/jorgenschaefer/circe/wiki/Tracking"))]) (traad . [(20180730 48) ((dash (2 13 0)) (deferred (0 3 2)) (popup (0 5 0)) (request (0 2 0)) (request-deferred (0 2 0)) (virtualenvwrapper (20151123)) (f (0 20 0)) (bind-map (1 1 1))) "emacs interface to the traad refactoring server." single ((:commit . "98e23363b7e8a590a2f55976123a8c3da75c87a5") (:authors ("Austin Bingham" . "austin.bingham@gmail.com")) (:maintainer "Austin Bingham" . "austin.bingham@gmail.com") (:url . "https://github.com/abingham/traad"))]) (tql-mode . [(20170724 254) ((emacs (24))) "TQL mode" single ((:commit . "488add79eb3fc8ec02aedaa997fe1ed9e5c3e638") (:keywords "languages" "tql") (:authors ("Sean McLaughlin" . "seanmcl@gmail.com")) (:maintainer "Sean McLaughlin" . "seanmcl@gmail.com"))]) (toxi-theme . [(20160424 2126) ((emacs (24))) "A dark color theme by toxi" single ((:authors ("Karsten Schmidt" . "info@postspectacular.com")) (:maintainer "Karsten Schmidt" . "info@postspectacular.com") (:url . "http://bitbucket.org/postspectacular/toxi-theme/"))]) (tox . [(20160810 1555) nil "Launch current python test with tox" single ((:commit . "7655eb254038d5e34433e8a9d66b3ffc9c72e40c") (:keywords "convenience" "tox" "python" "tests") (:authors ("Chmouel Boudjnah" . "chmouel@chmouel.com")) (:maintainer "Chmouel Boudjnah" . "chmouel@chmouel.com") (:url . "https://github.com/chmouel/tox.el"))]) (totd . [(20150519 1440) ((s (1 9 0)) (cl-lib (0 5))) "Display a random daily emacs command." single ((:commit . "ca47b618ea8290776cdb5b0f1c2c335691f69660") (:keywords "help") (:authors ("Erik Hetzner" . "egh@e6h.org")) (:maintainer "Erik Hetzner" . "egh@e6h.org"))]) (total-lines . [(20171227 1239) ((emacs (24 3))) "Keep track of a buffer's total number of lines" single ((:commit . "473fa74a5416697ecd938866518bcad423f8fda6") (:keywords "convenience" "mode-line") (:authors ("Hinrik Örn Sigurðsson")) (:maintainer "Hinrik Örn Sigurðsson") (:url . "https://github.com/hinrik/total-lines"))]) (tornado-template-mode . [(20141128 1008) nil "A major mode for editing tornado templates" single ((:commit . "667c0663dbbd279b6c345446b9f2bc50eb52b747") (:authors ("Florian Mounier aka paradoxxxzero")) (:maintainer "Florian Mounier aka paradoxxxzero"))]) (tommyh-theme . [(20131004 2330) nil "A bright, bold-colored theme for emacs" single ((:commit . "46d1c69ee0a1ca7c67b569b891a2f28fed89e7d5") (:authors ("William Glass" . "william.glass@gmail.com")) (:maintainer "William Glass" . "william.glass@gmail.com"))]) (toml-mode . [(20161107 1800) ((emacs (24)) (cl-lib (0 5))) "Major mode for editing TOML files" single ((:commit . "f6c61817b00f9c4a3cab1bae9c309e0fc45cdd06") (:keywords "data" "toml") (:authors ("Felix Chern" . "idryman@gmail.com")) (:maintainer "Felix Chern" . "idryman@gmail.com") (:url . "https://github.com/dryman/toml-mode.el"))]) (toml . [(20130903 1255) nil "TOML (Tom's Obvious, Minimal Language) parser" single ((:commit . "9633a6872928e737a2335aae1065768b23d8c3b3") (:keywords "toml" "parser") (:authors ("Wataru MIYAGUNI" . "gonngo@gmail.com")) (:maintainer "Wataru MIYAGUNI" . "gonngo@gmail.com") (:url . "https://github.com/gongo/emacs-toml"))]) (tomatinho . [(20180621 1748) nil "Simple and beautiful pomodoro timer" tar ((:commit . "b53354b9b9f496c0388d6a573b06b7d6fc53d0bd") (:keywords "time" "productivity" "pomodoro technique") (:authors ("Konrad Scorciapino" . "scorciapino@gmail.com")) (:maintainer "Konrad Scorciapino" . "scorciapino@gmail.com"))]) (toggle-window . [(20141207 1548) nil "toggle current window size between half and full" single ((:commit . "e82c60e543933880402ede11e9423e48a17dde53") (:keywords "hide" "window") (:authors ("Kenny Liu")) (:maintainer "Kenny Liu") (:url . "https://github.com/deadghost/toggle-window"))]) (toggle-test . [(20140723 537) nil "Toggle between source and test files in various programming languages" single ((:commit . "e969321f274903d705995a7d0345a257576ec5ff") (:keywords "tdd" "test" "toggle" "productivity") (:authors ("Raghunandan Rao" . "r.raghunandan@gmail.com")) (:maintainer "Raghunandan Rao" . "r.raghunandan@gmail.com") (:url . "https://github.com/rags/toggle-test"))]) (toggle-quotes . [(20140710 926) nil "Toggle between single and double quoted string" single ((:commit . "33abc221d6887f0518337851318065cd86c34b03") (:keywords "convenience" "quotes") (:authors ("Jim Tian" . "tianjin.sc@gmail.com")) (:maintainer "Jim Tian" . "tianjin.sc@gmail.com") (:url . "https://github.com/toctan/toggle-quotes.el"))]) (toggle . [(20180316 3) ((cl-lib (0 5))) "quickly open corresponding file (eg test vs impl)." single ((:commit . "4ce20cc5b25a1f1b4669ea8ff2880ec764eaf7da") (:keywords "files" "extensions" "convenience") (:authors ("Ryan Davis" . "ryand-ruby@zenspider.com")) (:maintainer "Ryan Davis" . "ryand-ruby@zenspider.com"))]) (togetherly . [(20170426 616) ((cl-lib (0 3))) "allow multiple clients to edit a single buffer online" single ((:commit . "a6491bd5dd84f2aded0cd112ff06ae76ff78dfeb") (:authors ("zk_phi")) (:maintainer "zk_phi") (:url . "http://hins11.yu-yake.com/"))]) (todotxt-mode . [(20150424 1404) nil "Major mode for editing todo.txt files" single ((:commit . "dc6ae151edee88f329ba7abc5d39b7440002232f") (:keywords "wp" "files") (:authors ("Adolfo Villafiorita" . "adolfo.villafiorita@me.com")) (:maintainer "Adolfo Villafiorita" . "adolfo.villafiorita@me.com"))]) (todotxt . [(20180626 2230) nil "A major mode for editing todo.txt files" single ((:commit . "f13e404304c9d26c105de872f96b4601441b3875") (:keywords "todo.txt" "todotxt" "todotxt.el") (:authors ("Rick Dillon" . "rpdillon@killring.org")) (:maintainer "Rick Dillon" . "rpdillon@killring.org") (:url . "https://github.com/rpdillon/todotxt.el"))]) (toc-org . [(20180815 727) nil "add table of contents to org-mode files (formerly, org-toc)" single ((:commit . "ce9e49303c602c30c58ae98d3ce5202e8419a3bc") (:keywords "org-mode" "org-toc" "toc-org" "org" "toc" "table" "of" "contents") (:authors ("Sergei Nosov <sergei.nosov [at] gmail.com>")) (:maintainer "Sergei Nosov <sergei.nosov [at] gmail.com>") (:url . "https://github.com/snosov1/toc-org"))]) (tmmofl . [(20121025 1101) nil "Calls functions dependant on font lock highlighting at point" single ((:commit . "532aa6978e994e2b069ffe37aaf9a0011a07dadc") (:keywords "minor mode" "font lock" "toggling.") (:authors ("Phillip Lord" . "p.lord@hgmp.mrc.ac.uk")) (:maintainer "Phillip Lord" . "p.lord@hgmp.mrc.ac.uk"))]) (tldr . [(20180122 1112) ((emacs (24 3))) "tldr client for Emacs" single ((:commit . "398b197c8d2238628b07e1b32d0f373876279f4c") (:keywords "tools" "docs") (:authors ("Ono Hiroko" . "azazabc123@gmail.com")) (:maintainer "Ono Hiroko" . "azazabc123@gmail.com") (:url . "https://github.com/kuanyui/tldr.el"))]) (tj3-mode . [(20180519 1228) nil "major mode for editing TaskJuggler 3 files" single ((:commit . "1d98eb23f1606392f34ef1b80517cfc940fb9950") (:authors ("Christophe Rhodes" . "christophe@rhodes.io")) (:maintainer "Christophe Rhodes" . "christophe@rhodes.io") (:url . "https://github.com/csrhodes/tj3-mode"))]) (tinysegmenter . [(20141124 1013) ((cl-lib (0 5))) "Super compact Japanese tokenizer in Javascript ported to emacs lisp" single ((:commit . "872134704bd25c13a4c59552433da4c6881b5230") (:keywords "convenience") (:authors ("lugecy" . "lugecy@gmail.com")) (:maintainer "myuhe") (:url . "https://github.com/myuhe/tinysegmenter.el"))]) (tiny-menu . [(20161213 1235) ((emacs (24 4))) "Display tiny menus." single ((:commit . "05563b94537b6eb22aeddedef2a6e59e3f88d073") (:keywords "menu" "tools") (:authors ("Aaron Bieber" . "aaron@aaronbieber.com")) (:maintainer "Aaron Bieber" . "aaron@aaronbieber.com") (:url . "https://github.com/aaronbieber/tiny-menu.el"))]) (tiny . [(20170903 949) nil "Quickly generate linear ranges in Emacs" single ((:commit . "012b2e7a67b9f067bbfa0292479861ffbaa201fa") (:keywords "convenience") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:url . "https://github.com/abo-abo/tiny"))]) (tinkerer . [(20170906 1224) ((s (1 2 0))) "Elisp wrapper for Tinkerer Blogging Engine." single ((:commit . "e34135555f3748b578c7f8706dfd0c888fb87581") (:keywords "tinkerer" "blog" "wrapper") (:authors ("Yagnesh Raghava Yakkala" . "hi@yagnesh.org")) (:maintainer "Yagnesh Raghava Yakkala" . "hi@yagnesh.org") (:url . "https://github.com/yyr/tinkerer.el"))]) (timp . [(20160618 803) ((emacs (24 4)) (cl-lib (0 5)) (fifo-class (1 0)) (signal (1 0))) "Multithreading library" tar ((:commit . "66b21934b1eb8ee428c06dd64b3562ad44776a35") (:keywords "internal" "lisp" "processes" "tools") (:authors ("Mola-T" . "Mola@molamola.xyz")) (:maintainer "Mola-T" . "Mola@molamola.xyz") (:url . "https://github.com/mola-T/timp"))]) (timonier . [(20170411 800) ((emacs (24 4)) (s (1 11 0)) (f (0 19 0)) (dash (2 12 0)) (pkg-info (0 5 0)) (hydra (0 13 6)) (request (0 2 0)) (all-the-icons (2 0 0))) "Manage Kubernetes Applications" tar ((:commit . "0a150ea87bf695b43cf1740dfd7e553e0ae7601c") (:keywords "kubernetes" "docker") (:authors ("Nicolas Lamirault" . "nicolas.lamirault@gmail.com")) (:maintainer "Nicolas Lamirault" . "nicolas.lamirault@gmail.com") (:url . "https://github.com/nlamirault/timonier"))]) (timesheet . [(20180802 202) ((s (1)) (org (7)) (auctex (11))) "Timesheet management add-on for org-mode" tar ((:commit . "67ca6a9f6733052066b438301fb2dd81b8b3f6eb") (:keywords "org" "timesheet") (:authors ("Tom Marble")) (:maintainer "Tom Marble") (:url . "https://github.com/tmarble/timesheet.el"))]) (timer-revert . [(20150122 2032) nil "minor mode to revert buffer for a given time interval." tar ((:commit . "615c91dec8b440d2b9b7c725dd733d7432564e45"))]) (timecop . [(20160520 1052) ((cl-lib (0 5)) (datetime-format (0 0 1))) "Freeze Time for testing" single ((:commit . "e6427538b547cbe02e1bd6ed4b765c73620bdae8") (:keywords "datetime" "testing") (:authors ("USAMI Kenta" . "tadsan@zonu.me")) (:maintainer "USAMI Kenta" . "tadsan@zonu.me") (:url . "https://github.com/zonuexe/emacs-datetime"))]) (time-ext . [(20170126 1215) nil "more function for time/date" single ((:commit . "d128becf660fe3f30178eb1b05cd266741f4784a") (:keywords "lisp") (:authors ("rubikitch" . "rubikitch@ruby-lang.org")) (:maintainer "rubikitch" . "rubikitch@ruby-lang.org") (:url . "http://www.emacswiki.org/cgi-bin/wiki/download/time-ext.el"))]) (tile . [(20161225 357) ((emacs (25 1)) (s (1 9 0)) (dash (2 12 0)) (stream (2 2 3))) "Tile windows with layouts" single ((:commit . "22660f21f6e95de5aba55cd5d293d4841e9a4661") (:keywords "tile" "tiling" "window" "manager" "dynamic" "frames") (:authors ("Ivan Malison" . "IvanMalison@gmail.com")) (:maintainer "Ivan Malison" . "IvanMalison@gmail.com") (:url . "https://github.com/IvanMalison/tile"))]) (tide . [(20180810 403) ((dash (2 10 0)) (s (1 11 0)) (flycheck (27)) (typescript-mode (0 1)) (cl-lib (0 5))) "Typescript Interactive Development Environment" tar ((:commit . "d21568528c9bb1ba55627f548c7012f6bcc2fe58") (:keywords "typescript") (:authors ("Anantha kumaran" . "ananthakumaran@gmail.com")) (:maintainer "Anantha kumaran" . "ananthakumaran@gmail.com") (:url . "http://github.com/ananthakumaran/tide"))]) (tidal . [(20180410 1945) ((haskell-mode (16)) (emacs (24))) "Interact with TidalCycles for live coding patterns" single ((:commit . "ab12c0f6b1fa77bf1d739326bdd79d4f010f978d") (:keywords "tools") (:authors (nil . "alex@slab.org")) (:maintainer nil . "alex@slab.org") (:url . "https://github.com/tidalcycles/Tidal"))]) (tickscript-mode . [(20171219 203) ((emacs (24 1))) "A major mode for Tickscript files" single ((:commit . "f0579f38ff14954df5002ce30ae6d4a2c978d461") (:keywords "languages") (:authors ("Marc Sherry" . "msherry@gmail.com")) (:maintainer "Marc Sherry" . "msherry@gmail.com") (:url . "https://github.com/msherry/tickscript-mode"))]) (thumb-through . [(20120119 534) nil "Plain text reader of HTML documents" single ((:commit . "08d8fb720f93c6172653e035191a8fa9c3305e63") (:keywords "html"))]) (thrift . [(20140312 2048) nil "Major mode for Apache Thrift files" single ((:commit . "2566ecd5d9999f7ff70e6ac702243f0dfb24e7aa") (:keywords "files"))]) (threes . [(20160820 1242) ((emacs (24)) (seq (1 11))) "A clone of Threes (a tiny puzzle game)" single ((:commit . "6981acb30b856c77cba6aba63fefbf102cbdfbb2") (:keywords "games") (:authors ("Chunyang Xu" . "xuchunyang.me@gmail.com")) (:maintainer "Chunyang Xu" . "xuchunyang.me@gmail.com") (:url . "https://github.com/xuchunyang/threes.el"))]) (thread-dump . [(20170816 1850) nil "Java thread dump viewer" single ((:commit . "204c9600242756d4b514bb5ff6293e052bf4b49d") (:authors ("Dmitry Neverov")) (:maintainer "Dmitry Neverov") (:url . "http://github.com/nd/thread-dump.el"))]) (thinks . [(20170802 1128) ((cl-lib (0 5))) "Insert text in a think bubble." single ((:commit . "c02f236abc8c2025d9f01460b09b89ebdc96e28d") (:keywords "convenience" "quoting") (:authors ("Dave Pearson" . "davep@davep.org")) (:maintainer "Dave Pearson" . "davep@davep.org") (:url . "https://github.com/davep/thinks.el"))]) (thingopt . [(20160520 2318) nil "Thing at Point optional utilities" single ((:commit . "5679815852652479f3b3c9f3a98affc927384b2c") (:keywords "convenience") (:authors ("Tomohiro Matsuyama" . "m2ym.pub@gmail.com")) (:maintainer "Tomohiro Matsuyama" . "m2ym.pub@gmail.com"))]) (therapy . [(20151113 1953) ((emacs (24))) "Hooks for managing multiple Python major versions" single ((:commit . "775a92bb7b6b0fcc5b38c0b5198a9d0a1bef788a") (:authors ("Austin Bingham" . "austin.bingham@gmail.com")) (:maintainer "Austin Bingham" . "austin.bingham@gmail.com") (:url . "https://github.com/abingham/therapy"))]) (theme-looper . [(20170425 1306) ((cl-lib (0 5))) "Loop thru the available color-themes" single ((:commit . "875c2cfc84b3c143d3b14a7aba38905e35559157") (:keywords "convenience" "color-themes") (:authors ("Mohammed Ismail Ansari" . "team.terminal@gmail.com")) (:maintainer "Mohammed Ismail Ansari" . "team.terminal@gmail.com") (:url . "http://ismail.teamfluxion.com"))]) (theme-changer . [(20171221 1927) nil "Sunrise/Sunset Theme Changer for Emacs" single ((:commit . "61945695a30d678e6a5d47cbe7c8aff59a8c30ea") (:keywords "color-theme" "deftheme" "solar" "sunrise" "sunset") (:authors ("Joshua B. Griffith" . "josh.griffith@gmail.com")) (:maintainer "Joshua B. Griffith" . "josh.griffith@gmail.com") (:url . "https://github.com/hadronzoo/theme-changer"))]) (tfsmacs . [(20180904 1755) ((emacs (25)) (tablist (0 70))) "MS TFS source control interaction." single ((:commit . "32d40a7030775864cbb4d2377bf681dbd2c68e6f") (:keywords "tfs" "vc") (:authors ("Dino Chiesa <dpchiesa@outlook.com>, Sebastian Monia" . "smonia@outlook.com")) (:maintainer "Dino Chiesa <dpchiesa@outlook.com>, Sebastian Monia" . "smonia@outlook.com") (:url . "http://github.com/sebasmonia/tfsmacs/"))]) (tf2-conf-mode . [(20161209 1620) nil "TF2 Configuration files syntax highlighting" single ((:commit . "536950f64c071ffd8495fb2c7ac7c63a11e25f93") (:keywords "languages") (:authors ("Guillermo Robles" . "guillerobles1995@gmail.com")) (:maintainer "Guillermo Robles" . "guillerobles1995@gmail.com") (:url . "https://github.com/wynro/emacs-tf2-conf-mode"))]) (textx-mode . [(20170516 911) ((emacs (24 3))) "Major mode for editing TextX files" single ((:commit . "72f9f0c5855b382024f0da8f56833c22a70a5cb3") (:keywords "textx") (:authors ("Novak Boškov" . "gnovak.boskov@gmail.com")) (:maintainer "Novak Boškov" . "gnovak.boskov@gmail.com") (:url . "https://github.com/novakboskov/textx-mode"))]) (textmate-to-yas . [(20160409 1708) nil "Import Textmate macros into yasnippet syntax" tar ((:commit . "be3a768b7ac4c2e24b9d4aa6e9ac1d916cdc5a73") (:keywords "yasnippet" "textmate") (:authors ("Matthew L. Fidler")) (:maintainer "Matthew L. Fidler") (:url . "https://github.com/mlf176f2/textmate-to-yas.el/"))]) (textmate . [(20110816 2146) nil "TextMate minor mode for Emacs" single ((:commit . "350918b070148f0ace6d9d3cd4ebcaf15c1a8781") (:keywords "textmate" "osx" "mac") (:authors ("Chris Wanstrath" . "chris@ozmm.org")) (:maintainer "Chris Wanstrath" . "chris@ozmm.org"))]) (textile-mode . [(20170304 1716) nil "Textile markup editing major mode" single ((:commit . "c37aaab809503df008209390e31e19abf4e23630") (:authors ("Julien Barnier" . "julien@nozav.org")) (:maintainer "Julien Barnier" . "julien@nozav.org"))]) (texfrag . [(20180318 2347) ((emacs (25)) (auctex (11 90 2))) "preview LaTeX fragments in alien major modes" single ((:commit . "eb7ab304c1bcf3ea155e9a12daad8deefe940cf2") (:keywords "tex" "languages" "wp") (:authors ("Tobias Zawada" . "i@tn-home.de")) (:maintainer "Tobias Zawada" . "i@tn-home.de") (:url . "https://github.com/TobiasZawada/texfrag"))]) (tex-smart-umlauts . [(20160427 758) nil "Smart umlaut conversion for TeX." single ((:commit . "5261b931443558f4252489a1e6616034848aff02") (:keywords "tex" "wp") (:authors ("Frank Fischer <frank-fischer at shadow-soft.de>")) (:maintainer "Frank Fischer <frank-fischer at shadow-soft.de>") (:url . "http://hub.darcs.net/lyro/tex-smart-umlauts"))]) (test-simple . [(20170527 1532) ((cl-lib (0))) "Simple Unit Test Framework for Emacs Lisp" single ((:commit . "b3b69f52207d3a8111421ad7ab9ed82abbe85316") (:keywords "unit-test") (:authors ("Rocky Bernstein" . "rocky@gnu.org")) (:maintainer "Rocky Bernstein" . "rocky@gnu.org") (:url . "http://github.com/rocky/emacs-test-simple"))]) (test-kitchen . [(20171129 2035) nil "Run test-kitchen inside of emacs" single ((:commit . "0fc0ca4808425f03fbeb8125246043723e2a179a") (:keywords "chef" "ruby" "test-kitchen") (:authors ("JJ Asghar")) (:maintainer "JJ Asghar") (:url . "http://github.com/jjasghar/test-kitchen-el"))]) (test-case-mode . [(20130525 1434) ((fringe-helper (0 1 1))) "unit test front-end" single ((:commit . "6074df10ebc97ddfcc228c71c73db179e672dac3") (:keywords "tools") (:authors ("Nikolaj Schumacher <bugs * nschum de>")) (:maintainer "Nikolaj Schumacher <bugs * nschum de>") (:url . "http://nschum.de/src/emacs/test-case-mode/"))]) (test-c . [(20180423 1720) ((emacs (24 3))) "quickly test c code" single ((:commit . "761a576f62c7021ba941f178f153c51289df1553") (:authors ("Aurélien Aptel" . "aurelien.aptel@gmail.com")) (:maintainer "Aurélien Aptel" . "aurelien.aptel@gmail.com") (:url . "http://github.com/aaptel/test-c"))]) (terraform-mode . [(20170112 517) ((emacs (24 3)) (hcl-mode (0 3))) "Major mode for terraform configuration file" single ((:commit . "6973d1acaba2835dfdf174f5a5e27de6366002e1") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-terraform-mode"))]) (tern-django . [(20160221 1923) ((emacs (24)) (tern (0 0 1)) (f (0 17 1))) "Create tern projects for django applications." tar ((:commit . "46f2cd5e96bc804069f18455a828b8e4c5ec358a") (:authors ("Artem Malyshev" . "proofit404@gmail.com")) (:maintainer "Artem Malyshev" . "proofit404@gmail.com") (:url . "https://github.com/proofit404/tern-django"))]) (tern-context-coloring . [(20161218 747) ((emacs (24 3)) (context-coloring (8 1 0)) (tern (0 0 1))) "Use Tern for context coloring" single ((:commit . "3a8e979d6cc83aabcb3dda3f5f31a6422532efba") (:keywords "convenience" "faces" "tools") (:authors ("Jackson Ray Hamilton" . "jackson@jacksonrayhamilton.com")) (:maintainer "Jackson Ray Hamilton" . "jackson@jacksonrayhamilton.com") (:url . "https://github.com/jacksonrayhamilton/tern-context-coloring"))]) (tern-auto-complete . [(20170521 1935) ((tern (0 0 1)) (auto-complete (1 4)) (cl-lib (0 5)) (emacs (24))) "Tern Completion by auto-complete.el" single ((:commit . "4e3e61b3a1e2199e712b01c876a38455d841f57f") (:authors ("<m.sakurai at kiwanami.net>")) (:maintainer "<m.sakurai at kiwanami.net>"))]) (tern . [(20170925 2033) ((json (1 2)) (cl-lib (0 5)) (emacs (24))) "Tern-powered JavaScript integration" single ((:commit . "4e3e61b3a1e2199e712b01c876a38455d841f57f") (:authors ("Marijn Haverbeke")) (:maintainer "Marijn Haverbeke") (:url . "http://ternjs.net/"))]) (terminal-here . [(20180513 833) ((emacs (24)) (cl-lib (0 5))) "Run an external terminal in current directory" single ((:commit . "2b57dcfc7d78c6762eb74b37930067a75beb5ca4") (:keywords "tools" "frames") (:authors ("David Shepherd" . "davidshepherd7@gmail.com")) (:maintainer "David Shepherd" . "davidshepherd7@gmail.com") (:url . "https://github.com/davidshepherd7/terminal-here"))]) (terminal-focus-reporting . [(20180830 719) ((emacs (24 4))) "Minor mode for terminal focus reporting." single ((:commit . "8b84bf18f4c5f1b59a11692eb706f13c3598d9a5") (:keywords "convenience") (:authors ("Vitalii Elenhaupt")) (:maintainer "Vitalii Elenhaupt") (:url . "https://github.com/veelenga/terminal-focus-reporting.el"))]) (termbright-theme . [(20151031 235) ((emacs (24 1))) "a more usable theme for white-on-black terminals" single ((:commit . "bec6ab14336c0611e85f45486276004f16d20607") (:keywords "themes") (:authors ("Brian Mastenbrook" . "brian@mastenbrook.net")) (:maintainer "Brian Mastenbrook" . "brian@mastenbrook.net") (:url . "https://github.com/bmastenbrook/termbright-theme-el"))]) (term-run . [(20151228 905) nil "Run arbitrary command in terminal buffer" single ((:commit . "bffd7b0183ca26645d191732092546eab7fca95e") (:keywords "utility" "shell" "command" "term-mode") (:authors ("10sr <8slashes+el [at] gmail [dot] com>")) (:maintainer "10sr <8slashes+el [at] gmail [dot] com>") (:url . "https://github.com/10sr/term-run-el"))]) (term-projectile . [(20170421 805) ((emacs (24)) (term-manager (0 1 0)) (projectile (0 13 0))) "projectile terminal management" single ((:commit . "13a0f1637a1f075d70211ccb8162e63a18a474da") (:keywords "projectile" "tools" "terminals" "vc") (:authors ("Ivan Malison" . "IvanMalison@gmail.com")) (:maintainer "Ivan Malison" . "IvanMalison@gmail.com") (:url . "https://www.github.com/IvanMalison/term-manager"))]) (term-manager . [(20171020 841) ((dash (2 12 0)) (emacs (24 4))) "Contextual terminal management" tar ((:commit . "13a0f1637a1f075d70211ccb8162e63a18a474da") (:keywords "terminals" "tools") (:authors ("Ivan Malison" . "IvanMalison@gmail.com")) (:maintainer "Ivan Malison" . "IvanMalison@gmail.com") (:url . "https://www.github.com/IvanMalison/term-manager"))]) (term-cmd . [(20160517 1045) ((emacs (24 0)) (dash (2 12 0)) (f (0 18 2))) "Send commands from programs running in term.el." tar ((:commit . "6c9cbc659b70241d2ed1601eea34aeeca0646dac"))]) (term-alert . [(20161119 945) ((emacs (24 0)) (term-cmd (1 1)) (alert (1 1)) (f (0 18 2))) "Notifications when commands complete in term.el." tar ((:commit . "47af9e6fe483ef0d393098c145f499362a33292a"))]) (term+mux . [(20140211 749) ((term+ (0 1)) (tab-group (0 1))) "term+ terminal multiplexer and session management" single ((:commit . "81b60e80cf008472bfd7fad9233af2ef722c208a") (:keywords "terminal" "emulation") (:authors ("INA Lintaro <tarao.gnn at gmail.com>")) (:maintainer "INA Lintaro <tarao.gnn at gmail.com>") (:url . "http://github.com/tarao/term+-el"))]) (term+key-intercept . [(20140211 750) ((term+ (0 1)) (key-intercept (0 1))) "term+ intercept key mapping" single ((:commit . "fd0771fd66b8c7a909aaac972194485c79ba48c4") (:keywords "terminal" "emulation") (:authors ("INA Lintaro <tarao.gnn at gmail.com>")) (:maintainer "INA Lintaro <tarao.gnn at gmail.com>") (:url . "http://github.com/tarao/term+-el"))]) (term+ . [(20170509 17) ((emacs (24)) (cl-lib (0 5))) "term-mode enhancement" tar ((:commit . "c3c9239b339c127231860de43abfa08c44c0201a") (:keywords "terminal" "emulation") (:authors ("INA Lintaro <tarao.gnn at gmail.com>")) (:maintainer "INA Lintaro <tarao.gnn at gmail.com>") (:url . "https://github.com/tarao/term-plus-el"))]) (ten-hundred-mode . [(20161028 2236) ((cl-lib (0 5))) "use only the ten hundred most usual words" tar ((:commit . "bdcfda49b1819e82d61fe90947e50bb948cf7933"))]) (temporary-persistent . [(20161210 1133) ((emacs (24 3)) (names (20151201 0)) (dash (2 12 1)) (s (1 10 0))) "Keep temp notes buffers persistent -*- lexical-binding: t" single ((:commit . "ac66f3054fc701d53f11ada9d2d9ab18ea481dc0") (:keywords "temp" "buffers" "notes") (:authors ("Kostafey" . "kostafey@gmail.com")) (:maintainer "Kostafey" . "kostafey@gmail.com") (:url . "https://github.com/kostafey/temporary-persistent"))]) (template-overlays . [(20180706 1132) ((emacs (24 4)) (ov (1 0 6))) "Display template regions using overlays" single ((:commit . "d32db58c044b2aca3720879003f55b1d57208b07") (:keywords "faces" "convenience" "templates" "overlays") (:authors ("Mariano Montone" . "marianomontone@gmail.com")) (:maintainer "Mariano Montone" . "marianomontone@gmail.com") (:url . "http://www.github.com/mmontone/template-overlays"))]) (telephone-line . [(20180829 404) ((emacs (24 4)) (cl-lib (0 5)) (cl-generic (0 2)) (seq (1 8))) "Rewrite of Powerline" tar ((:commit . "401a9c6ad6f99ea41b270baaca0977af67c1f2fd") (:keywords "mode-line") (:authors ("Daniel Bordak" . "dbordak@fastmail.fm")) (:maintainer "Daniel Bordak" . "dbordak@fastmail.fm") (:url . "https://github.com/dbordak/telephone-line"))]) (telepathy . [(20131209 1258) nil "Access Telepathy from Emacs" single ((:commit . "211d785b02a29ddc254422fdcc3db45262582f8c") (:keywords "telepathy" "tools") (:authors ("Nicolas Petton" . "petton.nicolas@gmail.com")) (:maintainer "Nicolas Petton" . "petton.nicolas@gmail.com"))]) (tea-time . [(20120331 820) nil "Simple timer package, useful to make perfect tea." single ((:commit . "1f6cf0bdd27c5eb3508989c5095427781f858eca") (:keywords "timer" "tea-time") (:authors ("konsty" . "antipin.konstantin@googlemail.com")) (:maintainer "Gabriel Saldana" . "gsaldana@gmail.com"))]) (tdd-status-mode-line . [(20131123 1716) nil "TDD status on the mode-line" single ((:commit . "4c082e62f4915b573338a97efcc6854d132323dc") (:keywords "faces" "tdd") (:authors ("Gergely Nagy" . "algernon@madhouse-project.org")) (:maintainer "Gergely Nagy" . "algernon@madhouse-project.org") (:url . "https://github.com/algernon/tdd-status-mode-line"))]) (tco . [(20160811 12) ((dash (1 2 0)) (emacs (24))) "tail-call optimisation for Emacs lisp" single ((:commit . "97529ed7a0939c51ce0084c0aa8b12b313654735") (:authors ("Wilfred Hughes" . "me@wilfred.me.uk")) (:maintainer "Wilfred Hughes" . "me@wilfred.me.uk"))]) (tc . [(20180715 706) nil "a Japanese input method with T-Code on Emacs" tar ((:commit . "91bd7e29322f7477c9adb6a816c6207dcb48f6c1") (:authors ("Kaoru Maeda" . "maeda@src.ricoh.co.jp") ("Yasushi Saito" . "yasushi@cs.washington.edu") ("KITAJIMA Akira" . "kitajima@isc.osakac.ac.jp")) (:maintainer "KITAJIMA Akira"))]) (tbx2org . [(20140224 1559) ((dash (2 5 0)) (s (1 8 0)) (cl-lib (0 4))) "Tinderbox to org-mode conversion" single ((:commit . "08e9816ba6066f56936050b58d07ceb2187ae6f7") (:keywords "org-mode") (:authors ("istib")) (:maintainer "istib") (:url . "https://github.com/istib/tbx2org"))]) (tblui . [(20161007 1912) ((dash (2 12 1)) (magit-popup (2 6 0)) (tablist (0 70)) (cl-lib (0 5))) "Define tabulated list UI easily" single ((:commit . "bb29323bb3e27093d50cb42db3a9329a096b6e4d") (:authors ("Yuki Inoue <inouetakahiroki _at_ gmail.com>")) (:maintainer "Yuki Inoue <inouetakahiroki _at_ gmail.com>") (:url . "https://github.com/Yuki-Inoue/tblui.el"))]) (tawny-mode . [(20170422 2202) ((cider (0 12)) (emacs (25))) "Ontology Editing with Tawny-OWL" single ((:commit . "d768cce65891f11cd2f96aff54b76e5bb07cc649") (:authors ("Phillip Lord" . "phillip.lord@newcastle.ac.uk")) (:maintainer "Phillip Lord" . "phillip.lord@newcastle.ac.uk"))]) (taskpaper-mode . [(20180820 1411) nil "Major mode for working with TaskPaper files" tar ((:commit . "d9b63dcc8cd5906ad72d9e92343b4dc2377109a6") (:keywords "outlines" "notetaking" "task management" "productivity" "taskpaper") (:authors ("Dmitry Safronov" . "saf.dmitry@gmail.com")) (:maintainer "Dmitry Safronov" . "saf.dmitry@gmail.com") (:url . "https://github.com/saf-dmitry/taskpaper-mode"))]) (tao-theme . [(20171221 1801) nil "This package provides two parametrized uncoloured color themes for Emacs: tao-yin and tao-yang." tar ((:commit . "a97df8c51d77696787aaf55c67207f19c803fabe"))]) (tangotango-theme . [(20170924 1509) nil "Tango Palette color theme for Emacs 24." single ((:commit . "e2f2ea9c35f06dfc43a29c91c14cf0cdb19f2144") (:keywords "tango" "palette" "color" "theme" "emacs") (:authors ("Julien Barnier")) (:maintainer "Julien Barnier") (:url . "https://github.com/juba/color-theme-tangotango"))]) (tango-plus-theme . [(20170214 1708) nil "A color theme based on the tango palette" single ((:commit . "8ba8901397e3e9f1d53110487bfa0effc65015e7") (:authors ("Titus von der Malsburg" . "malsburg@posteo.de")) (:maintainer "Titus von der Malsburg" . "malsburg@posteo.de") (:url . "https://github.com/tmalsburg/tango-plus-theme"))]) (tango-2-theme . [(20120312 2025) nil "Tango 2 color theme for GNU Emacs 24" single ((:commit . "64e44c98e41ebbe3b827d54280e3b9615787daaa") (:authors ("Nick Parker")) (:maintainer "Nick Parker"))]) (take-off . [(20140531 917) ((emacs (24 3)) (web-server (0 1 0))) "Emacs remote web access" tar ((:commit . "aa9ea45566fc74febbb6ee9c409ecc4b59246215") (:authors ("Thomas Burette" . "burettethomas@gmail.com")) (:maintainer "Thomas Burette" . "burettethomas@gmail.com") (:url . "https://github.com/tburette/take-off"))]) (tagedit . [(20161121 855) ((s (1 3 1)) (dash (1 0 3))) "Some paredit-like features for html-mode" single ((:commit . "b3a70101a0dcf85498c92b7fcfa7fdbac869746c") (:keywords "convenience") (:authors ("Magnar Sveen" . "magnars@gmail.com")) (:maintainer "Magnar Sveen" . "magnars@gmail.com"))]) (tabula-rasa . [(20141216 547) ((emacs (24 4))) "Distraction free writing mode" single ((:commit . "e85fff9de18dc31bc6a7aca726e34a95cc5459f5") (:keywords "distraction free" "writing") (:authors ("Ido Magal" . "misc@satans.church")) (:maintainer "Ido Magal" . "misc@satans.church") (:url . "https://github.com/idomagal/Tabula-Rasa/blob/master/tabula-rasa.el"))]) (tablist . [(20170220 335) ((emacs (24 3))) "Extended tabulated-list-mode" tar ((:commit . "c834a84efb6efa32497efe1e73160fade741b836") (:keywords "extensions" "lisp") (:authors ("Andreas Politz" . "politza@fh-trier.de")) (:maintainer "Andreas Politz" . "politza@fh-trier.de"))]) (tabbar-ruler . [(20160802 307) ((tabbar (2 0 1)) (powerline (2 3)) (mode-icons (0 4 0)) (cl-lib (0 5))) "Pretty tabbar, autohide, use both tabbar/ruler" tar ((:commit . "535568189aa12a3eff7f977d2783e57b6a65ab6a") (:keywords "tabbar" "ruler mode" "menu" "tool bar.") (:authors ("Matthew Fidler, Ta Quang Trung, Nathaniel Cunningham")) (:maintainer "Matthew L. Fidler") (:url . "http://github.com/mlf176f2/tabbar-ruler.el"))]) (tabbar . [(20180726 1735) nil "Display a tab bar in the header line" tar ((:commit . "82bbda31cbe8ef367dd6501c3aa14b7f2c835910") (:keywords "convenience") (:authors ("David Ponce" . "david@dponce.com")) (:maintainer "David Ponce" . "david@dponce.com"))]) (tab-jump-out . [(20151006 130) ((dash (2 10)) (emacs (24 4))) "Use tab to jump out of delimiter pairs." single ((:commit . "1c3fec1826d2891177ea78e4e7cce1dc67e83e51") (:keywords "tab" "editing") (:authors ("Zhang Kai Yu" . "yeannylam@gmail.com")) (:maintainer "Zhang Kai Yu" . "yeannylam@gmail.com"))]) (tab-group . [(20140306 1450) nil "Grouped tabs and their tabbar" single ((:commit . "5a290ec2608e4100fb188fd60ecb77affcc3465b") (:keywords "convenience" "tabs") (:authors ("INA Lintaro <tarao.gnn at gmail.com>")) (:maintainer "INA Lintaro <tarao.gnn at gmail.com>") (:url . "http://github.com/tarao/tab-group-el"))]) (ta . [(20160619 1645) ((emacs (24 3)) (cl-lib (0 5))) "A tool to deal with Chinese homophonic characters" single ((:commit . "668ad41e71f374f8c32c8d0532f3d8485b355d35") (:keywords "tools") (:authors ("kuanyui" . "azazabc123@gmail.com")) (:maintainer "kuanyui" . "azazabc123@gmail.com") (:url . "http://github.com/kuanyui/ta.el"))]) (systemtap-mode . [(20151122 1940) nil "A mode for SystemTap" single ((:commit . "1a968c2b1f3a054bebf91ac49739d3a81ce050a9") (:keywords "tools" "languages") (:maintainer nil . "ruediger@c-plusplus.de") (:url . "https://github.com/ruediger/systemtap-mode"))]) (systemd . [(20180629 2106) ((emacs (24 4))) "Major mode for editing systemd units" tar ((:commit . "401d71c2dd24e424216ae5e4275c830f2a9c6b0c") (:keywords "tools" "unix") (:authors ("Mark Oteiza" . "mvoteiza@udel.edu")) (:maintainer "Mark Oteiza" . "mvoteiza@udel.edu"))]) (system-specific-settings . [(20140818 1457) nil "Apply settings only on certain systems" single ((:commit . "0050d85b2175095aa5ecf580a2fe43c069b0eef3") (:keywords "configuration") (:authors ("Ryan C. Thompson")) (:maintainer "Ryan C. Thompson") (:url . "https://github.com/DarwinAwardWinner/emacs-system-specific-settings"))]) (system-packages . [(20180821 17) ((emacs (24 3))) "functions to manage system packages" single ((:commit . "604d16b8746c290327200e568d37914ad24daf1a") (:authors ("J. Alexander Branham" . "branham@utexas.edu")) (:maintainer "J. Alexander Branham" . "branham@utexas.edu") (:url . "https://gitlab.com/jabranham/system-packages"))]) (syntax-subword . [(20160519 1905) nil "make operations on words more fine-grained" single ((:authors ("Jonathan Kotta" . "jpkotta@gmail.com")) (:maintainer "Jonathan Kotta" . "jpkotta@gmail.com"))]) (syntactic-sugar . [(20140508 2041) nil "Effect-free forms such as if/then/else" single ((:commit . "7ddc4502c831abe1c4ad4c7d1ca628a2c9e13968") (:keywords "extensions") (:authors ("Roland Walker" . "walker@pobox.com")) (:maintainer "Roland Walker" . "walker@pobox.com") (:url . "http://github.com/rolandwalker/syntactic-sugar"))]) (syntactic-close . [(20180827 929) ((emacs (24)) (cl-lib (0 5))) "Insert closing delimiter" single ((:commit . "5bcef5b1d07284839fc0eb2fd4b674f216c39a81") (:keywords "languages" "convenience") (:authors ("Emacs User Group Berlin" . "emacs-berlin@emacs-berlin.org")) (:maintainer "Emacs User Group Berlin" . "emacs-berlin@emacs-berlin.org") (:url . "https://github.com/emacs-berlin/syntactic-close"))]) (synquid . [(20160930 1550) ((flycheck (27)) (emacs (24 3))) "Major mode for editing Synquid files" single ((:commit . "28701ce1a15437202f53ab93a14bcba1de83fd2c") (:keywords "languages") (:authors ("Clément Pit-Claudel" . "clement.pitclaudel@live.com")) (:maintainer "Clément Pit-Claudel" . "clement.pitclaudel@live.com") (:url . "https://github.com/cpitclaudel/synquid-mode"))]) (synosaurus . [(20180125 1834) ((cl-lib (0 5))) "An extensible thesaurus supporting lookup and substitution." tar ((:commit . "8bf95b935976ec0a1964cf175ed57cc5f6f93bdb") (:url . "https://github.com/hpdeifel/synosaurus"))]) (synonymous . [(20180325 1817) ((emacs (24)) (cl-lib (0 5)) (request (0 2 0))) "A thesaurus at your fingertips" single ((:commit . "2cb9a674d84fddf3f1b00c9d6b13a853576acb87") (:keywords "utility") (:authors ("Katherine Whitlock" . "toroidalcode@gmail.com") ("Snippets adapted from FlySpell, authored by Manuel Serrano" . "Manuel.Serrano@inria.fr")) (:maintainer "Katherine Whitlock" . "toroidalcode@gmail.com") (:url . "http://github.com/toroidal-code/synonymous.el"))]) (syndicate . [(20160603 1523) ((evil (1 0))) "evil keybindings for org-mode" single ((:commit . "90cee202a06f5bab48268ebf9f62c43334b69f50") (:keywords "evil" "org" "bindings") (:authors ("Kawin Nikomborirak")) (:maintainer "Kawin Nikomborirak") (:url . "https://github.com/KNX32542/syndicate.git"))]) (sync-recentf . [(20160326 2001) nil "Synchronize the recent files list between Emacs instances" single ((:commit . "0052561d5c5b5c2684faedc3eead776aec06c3ed") (:keywords "recentf") (:authors ("François Févotte" . "fevotte@gmail.com")) (:maintainer "François Févotte" . "fevotte@gmail.com") (:url . "https://github.com/ffevotte/sync-recentf"))]) (symon-lingr . [(20150719 1342) ((symon (1 1 2)) (cl-lib (0 5))) "A notification-based Lingr client powered by symon.el" single ((:commit . "056d1a473e36992ff5881e5ce6fdc331cead975f") (:authors ("zk_phi")) (:maintainer "zk_phi") (:url . "http://hins11.yu-yake.com/"))]) (symon . [(20170224 833) nil "tiny graphical system monitor" single ((:commit . "8dd8b6df49b03cd7d31b85aedbe9dd08fb922335") (:authors ("zk_phi")) (:maintainer "zk_phi") (:url . "http://hins11.yu-yake.com/"))]) (symbolword-mode . [(20180401 1427) ((emacs (24)) (f (0 19 0))) "modify word split" single ((:commit . "3857c42696e20f49f274ff8bc45a6f3ee26884d4") (:authors ("ncaq" . "ncaq@ncaq.net")) (:maintainer "ncaq" . "ncaq@ncaq.net") (:url . "https://github.com/ncaq/symbolword-mode"))]) (symbol-overlay . [(20180815 340) ((emacs (24 3))) "Highlight symbols with keymap-enabled overlays" single ((:commit . "a37404a6a0e76ee2033d3ab31c2248d30c89c63a") (:keywords "faces" "matching") (:authors ("wolray" . "wolray@foxmail.com")) (:maintainer "wolray" . "wolray@foxmail.com") (:url . "https://github.com/wolray/symbol-overlay/"))]) (sx . [(20180606 736) ((emacs (24 1)) (cl-lib (0 5)) (json (1 3)) (markdown-mode (2 0)) (let-alist (1 0 3))) "StackExchange client. Ask and answer questions on Stack Overflow, Super User, and the likes" tar ((:commit . "46d9498e8f501697920c79437909cdddc93d5ec6") (:keywords "help" "hypermedia" "tools") (:authors ("Sean Allred" . "code@seanallred.com")) (:maintainer "Sean Allred" . "code@seanallred.com") (:url . "https://github.com/vermiculus/sx.el/"))]) (sws-mode . [(20150317 1945) nil "(S)ignificant (W)hite(S)pace mode" single ((:commit . "4dbde92542fc7ad61df38776980905a4721d642e") (:authors ("Brian M. Carlson and other contributors")) (:maintainer "Brian M. Carlson and other contributors") (:url . "https://github.com/brianc/jade-mode"))]) (swoop . [(20160120 1715) ((ht (2 0)) (pcre2el (1 5)) (async (1 1)) (emacs (24))) "Peculiar buffer navigation for Emacs" tar ((:commit . "a5e475db7a9f5db02ba3d08cd3c1c3594e2e01d7") (:keywords "swoop" "inner" "buffer" "search" "navigation") (:authors ("Shingo Fukuyama - http://fukuyama.co")) (:maintainer "Shingo Fukuyama - http://fukuyama.co") (:url . "https://github.com/ShingoFukuyama/emacs-swoop"))]) (switch-window . [(20180724 418) ((emacs (24))) "A *visual* way to switch window" tar ((:commit . "ceade03eba1b735aefcac70eefbab6b582750c48") (:keywords "convenience") (:authors ("Dimitri Fontaine" . "dim@tapoueh.org") ("Feng Shu" . "tumashu@163.com")) (:maintainer "Dimitri Fontaine" . "dim@tapoueh.org") (:url . "https://github.com/dimitri/switch-window"))]) (switch-buffer-functions . [(20171011 1704) nil "Hook run when current buffer changed" single ((:commit . "651696ef9dec7affbe51c81d9318288376c35899") (:keywords "hook" "utility") (:authors ("10sr <8slashes+el [at] gmail [dot] com>")) (:maintainer "10sr <8slashes+el [at] gmail [dot] com>") (:url . "https://github.com/10sr/switch-buffer-functions-el"))]) (swiper-helm . [(20180131 1744) ((emacs (24 1)) (swiper (0 1 0)) (helm (1 5 3))) "Helm version of Swiper." single ((:commit . "93fb6db87bc6a5967898b5fd3286954cc72a0008") (:keywords "matching") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:url . "https://github.com/abo-abo/swiper-helm"))]) (swiper . [(20180813 1625) ((emacs (24 1)) (ivy (0 9 0))) "Isearch with an overview. Oh, man!" single ((:commit . "02537c95baf183b6a42e142a85742d589c692aa2") (:keywords "matching") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:url . "https://github.com/abo-abo/swiper"))]) (swift3-mode . [(20160918 1250) ((emacs (24 4))) "Major-mode for Apple's Swift programming language." tar ((:commit . "4e51265c6905e17d8910e35b0b37cf51e20ecdfe") (:keywords "languages" "swift") (:url . "https://github.com/taku0/swift3-mode"))]) (swift-mode . [(20180721 735) ((emacs (24 4)) (seq (2 3))) "Major-mode for Apple's Swift programming language." tar ((:commit . "d2f2f1da6085c6fad2709b951d6891dd139a6080") (:keywords "languages" "swift") (:url . "https://github.com/swift-emacs/swift-mode"))]) (sweetgreen . [(20180605 335) ((dash (2 12 1)) (helm (1 5 6)) (request (0 2 0)) (cl-lib (0 5))) "Order Salads from sweetgreen.com" single ((:commit . "e933fe466b5ef0e976967e203f88bd7a012469d1") (:keywords "salad" "food" "sweetgreen" "request") (:authors ("Diego Berrocal" . "cestdiego@gmail.com")) (:maintainer "Diego Berrocal" . "cestdiego@gmail.com") (:url . "https://www.github.com/CestDiego/sweetgreen.el"))]) (swap-regions . [(20180116 1053) ((emacs (24 3))) "Swap text in two regions" single ((:commit . "6e7a1bc68f11afe00809c8e27c13bca08393a91c") (:keywords "convenience") (:authors ("Xu Chunyang" . "mail@xuchunyang.me")) (:maintainer "Xu Chunyang" . "mail@xuchunyang.me") (:url . "https://github.com/xuchunyang/swap-regions.el"))]) (swap-buffers . [(20150506 2139) nil "The quickest way to swap buffers between windows. Based on switch-window package." single ((:commit . "46ab31359b70d935add6c6e9533443116dc51103") (:keywords "window" "swap" "buffer" "exchange") (:authors ("Evgeniy Kazakov" . "evgeniy.kazakov@gmail.com")) (:maintainer "Evgeniy Kazakov" . "evgeniy.kazakov@gmail.com") (:url . "https://github.com/ekazakov/swap-buffers"))]) (swagger-to-org . [(20160611 56) ((emacs (24)) (cl-lib (0 5)) (json (1 4))) "Convert a swagger.json file into an org-mode file" single ((:commit . "181357c71ea24bede263f5706d8781ad65e16877") (:keywords "ahungry" "emacs" "swagger" "openapi" "orgmode" "org" "export") (:authors ("Matthew Carter" . "m@ahungry.com")) (:maintainer "Matthew Carter" . "m@ahungry.com") (:url . "https://github.com/ahungry/swagger-to-org"))]) (svnwrapper . [(20180414 1843) ((e2ansi (0 1 1))) "Highlighting and paging for shell command `svn'" tar ((:commit . "de5069f5784e5d9e87a0af0159ba5f28a3716583") (:keywords "faces") (:authors ("Anders Lindgren")) (:maintainer "Anders Lindgren") (:url . "https://github.com/Lindydancer/svnwrapper"))]) (svg-mode-line-themes . [(20150425 2006) ((xmlgen (0 4))) "SVG-based themes for mode-line" tar ((:commit . "80a0e01839cafbd66899202e7764c33231974259") (:authors ("sabof")) (:maintainer "sabof") (:url . "https://github.com/sabof/svg-mode-line-themes"))]) (suscolors-theme . [(20161109 2015) nil "Colorful theme, inspired by Gruvbox." single ((:commit . "b946e7924aa02fa7441c970026898f17fe97601f") (:url . "https://github.com/TheSuspiciousWombat/SusColors-emacs"))]) (supergenpass . [(20130329 548) nil "SuperGenPass for Emacs" single ((:commit . "549072ef7b5b82913cadd4758e8a0a9926f0a04a") (:keywords "supergenpass") (:authors ("Jaime Fournier" . "jaimef@linbsd.org")) (:maintainer "Jaime Fournier" . "jaimef@linbsd.org"))]) (super-save . [(20171008 703) ((emacs (24 4))) "Auto-save buffers, based on your activity." single ((:commit . "1c8fbd5e18277e4af0ada2678a854b1c9072db38") (:keywords "convenience") (:authors ("Bozhidar Batsov" . "bozhidar@batsov.com")) (:maintainer "Bozhidar Batsov" . "bozhidar@batsov.com") (:url . "https://github.com/bbatsov/super-save"))]) (suomalainen-kalenteri . [(20170801 826) nil "Finnish national and Christian holidays for calendar" tar ((:commit . "c702e33cb6e13cb28bd761844e95be112a3c04f3"))]) (sunshine . [(20180325 1248) ((cl-lib (0 5))) "Provide weather and forecast information." single ((:commit . "ecaccac91010f8d464646a0360b1676be71e6600") (:keywords "tools" "weather") (:authors ("Aaron Bieber" . "aaron@aaronbieber.com")) (:maintainer "Aaron Bieber" . "aaron@aaronbieber.com") (:url . "https://github.com/aaronbieber/sunshine.el"))]) (sunny-day-theme . [(20140413 2125) nil "Emacs24 theme with a light background." single ((:commit . "420e0a6eb33fcc9b75c2c9e88ab60a975d782a00") (:authors ("Martin Haesler")) (:maintainer "Martin Haesler") (:url . "http://github.com/mswift42/sunny-day-theme"))]) (sunburn-theme . [(20180602 1929) ((emacs (24))) "A low contrast color theme" single ((:commit . "ddb01b6f1f4f823398f7f8e08900c2b4a7811d3b") (:authors ("Martín Varela" . "martin@varela.fi")) (:maintainer "Martín Varela" . "martin@varela.fi") (:url . "http://github.com/mvarela/Sunburn-Theme"))]) (suggestion-box . [(20170830 807) ((emacs (25 1)) (popup (0 5 3))) "show tooltip on the cursor" single ((:commit . "50af0776c8caf3c79c4d37fd51cbf304ea34b68e") (:keywords "convenience") (:authors ("Yuta Yamada <cokesboy\"at\"gmail.com>")) (:maintainer "Yuta Yamada <cokesboy\"at\"gmail.com>"))]) (suggest . [(20180725 2312) ((emacs (24 4)) (loop (1 3)) (dash (2 13 0)) (s (1 11 0)) (f (0 18 2)) (spinner (1 7 3))) "suggest elisp functions that give the output requested" tar ((:commit . "ce7be778b0b32bf679e5929d013c310b061b5541") (:keywords "convenience") (:authors ("Wilfred Hughes" . "me@wilfred.me.uk")) (:maintainer "Wilfred Hughes" . "me@wilfred.me.uk") (:url . "https://github.com/Wilfred/suggest.el"))]) (sudoku . [(20161111 706) ((emacs (24 4))) "Simple sudoku game, can download puzzles" single ((:commit . "77c11b5041b58fc943cf1668b44b40bae039cb5b") (:keywords "games") (:authors ("Zajcev Evgeny" . "zevlg@yandex.ru")) (:maintainer "Zajcev Evgeny" . "zevlg@yandex.ru"))]) (sudo-ext . [(20170126 1214) nil "sudo support" single ((:commit . "9d4580f304121ce7b8104bd4bd3b64e4dfa3c9b3") (:keywords "unix") (:authors ("rubikitch" . "rubikitch@ruby-lang.org")) (:maintainer "rubikitch" . "rubikitch@ruby-lang.org") (:url . "http://www.emacswiki.org/cgi-bin/wiki/download/sudo-ext.el"))]) (sudo-edit . [(20180731 1908) ((emacs (24)) (cl-lib (0 5))) "Open files as another user" single ((:commit . "cc3d478937b1accd38742bfceba92af02ee9357d") (:keywords "convenience") (:authors ("Nathaniel Flath" . "flat0103@gmail.com")) (:maintainer "Nathaniel Flath" . "flat0103@gmail.com") (:url . "https://github.com/nflath/sudo-edit"))]) (sudden-death . [(20180217 23) nil "Totsuzen-no-Shi" single ((:commit . "791a63d3f4df192e71f4232a9a4c5588f4b43dfb") (:authors ("yewton")) (:maintainer "yewton") (:url . "https://github.com/yewton/sudden-death.el"))]) (sublimity . [(20170820 1527) ((cl-lib (0 3))) "smooth-scrolling, minimap and distraction-free mode" tar ((:commit . "62b0c526c599a0178a16a75f16513fc1f93a0d53") (:authors ("zk_phi")) (:maintainer "zk_phi") (:url . "https://github.com/zk-phi/sublimity"))]) (sublime-themes . [(20170606 1844) nil "A collection of themes based on Sublime Text" tar ((:commit . "60ee40af82eb55b79d5ed4026f1911326311603f") (:keywords "faces") (:authors ("Owain Lewis" . "owain@owainlewis.com")) (:maintainer "Owain Lewis" . "owain@owainlewis.com"))]) (subemacs . [(20170401 934) nil "Evaluating expressions in a fresh Emacs subprocess" single ((:commit . "18d53939fec8968c08dfc5aff7240ca07efb1aac") (:keywords "extensions" "lisp" "multiprocessing") (:authors ("Klaus-Dieter Bauer" . "bauer.klaus.dieter@gmail.com")) (:maintainer "Klaus-Dieter Bauer" . "bauer.klaus.dieter@gmail.com") (:url . "https://github.com/kbauer/subemacs"))]) (subatomic256-theme . [(20130621 210) nil "Fork of subatomic-theme for terminals." single ((:commit . "326177d6f99cd2b1d30df695e67ee3bc441cd96f") (:authors ("John Olsson" . "john@cryon.se")) (:maintainer "John Olsson" . "john@cryon.se") (:url . "https://github.com/cryon/subatomic256"))]) (subatomic-theme . [(20160126 1538) nil "Low contrast bluish color theme" single ((:commit . "6a4086af748b1ecb27f6ba2aa2614988db16d594") (:keywords "color-theme" "blue" "low contrast") (:authors ("John Olsson" . "john@cryon.se")) (:maintainer "John Olsson" . "john@cryon.se") (:url . "https://github.com/cryon/subatomic"))]) (stylus-mode . [(20150313 1512) ((sws-mode (0))) "Major mode for editing .jade files" single ((:commit . "4dbde92542fc7ad61df38776980905a4721d642e") (:authors ("Brian M. Carlson and other contributors")) (:maintainer "Brian M. Carlson and other contributors") (:url . "https://github.com/brianc/jade-mode"))]) (stylefmt . [(20161025 824) nil "Stylefmt interface" single ((:commit . "7a38f26bf8ff947215f34f0a064c7ca80575ccbc") (:keywords "style" "code" "formatter") (:authors ("κeen")) (:maintainer "κeen") (:url . "https://github.com/KeenS/stylefmt.el"))]) (stupid-indent-mode . [(20170525 1117) nil "Plain stupid indentation minor mode" single ((:commit . "3295e7de5e2cfddc3bf0e462e852bf58972f5d70") (:authors ("Mihai Bazon" . "mihai.bazon@gmail.com")) (:maintainer "Mihai Bazon" . "mihai.bazon@gmail.com"))]) (stumpwm-mode . [(20140131 216) nil "special lisp mode for evaluating code into running stumpwm" single ((:commit . "61a7cf27e49e0779a53c018b2342f5f1c5cc70b4") (:keywords "comm" "lisp" "tools") (:maintainer "Shawn Betts"))]) (stripe-buffer . [(20141208 1508) ((cl-lib (1 0))) "Use a different background for even and odd lines" single ((:commit . "c252080f55cb78c951b19ebab9687f6d00237baf") (:authors ("Andy Stewart" . "lazycat.manatee@gmail.com")) (:maintainer "sabof" . "esabof@gmail.com") (:url . "https://github.com/sabof/stripe-buffer"))]) (string-utils . [(20140508 2041) ((list-utils (0 4 2))) "String-manipulation utilities" single ((:commit . "c2232d691617973ecf12a970c6008a161c21da14") (:keywords "extensions") (:authors ("Roland Walker" . "walker@pobox.com")) (:maintainer "Roland Walker" . "walker@pobox.com") (:url . "http://github.com/rolandwalker/string-utils"))]) (string-inflection . [(20180827 1301) nil "underscore -> UPCASE -> CamelCase -> lowerCamelCase conversion of names" single ((:commit . "e9a50855a4c718592c28a5a892f164ecf46e39a8") (:keywords "elisp") (:authors ("akicho8" . "akicho8@gmail.com")) (:maintainer "akicho8" . "akicho8@gmail.com"))]) (string-edit . [(20160411 656) ((dash (1 2 0))) "Avoid escape nightmares by editing string in separate buffer" single ((:commit . "c44b65b4c5e9f52be9c14d88ca2f402a18d9e1dd") (:authors ("Magnar Sveen" . "magnars@gmail.com")) (:maintainer "Magnar Sveen" . "magnars@gmail.com"))]) (strie . [(20160211 2222) ((cl-lib (0 5))) "A simple trie data structure implementation" single ((:commit . "eb7efb0cccc127c414f6a64db11454869d9c10a8") (:authors ("James Atwood" . "jatwood@cs.umass.edu")) (:maintainer "James Atwood" . "jatwood@cs.umass.edu"))]) (strace-mode . [(20171116 2039) nil "strace output syntax highlighting" single ((:commit . "2901baa968d5180ab985ac40ca22cc20914d01f5") (:keywords "languages") (:authors ("Preston Moore" . "prestonkmoore@gmail.com")) (:maintainer "Preston Moore" . "prestonkmoore@gmail.com"))]) (stock-ticker . [(20150204 1052) ((s (1 9 0)) (request (0 2 0))) "Show stock prices in mode line" single ((:commit . "f2e564142c9de84232839a5b01979cf95b04d6a9") (:keywords "comms") (:authors ("Gunther Hagleitner")) (:maintainer "Gunther Hagleitner") (:url . "https://github.com/hagleitn/stock-ticker"))]) (stickyfunc-enhance . [(20150429 1814) ((emacs (24 3))) "An enhancement to stock `semantic-stickyfunc-mode'" single ((:commit . "13bdba51fcd83ccbc3267959d23afc94d458dcb0") (:keywords "c" "languages" "tools") (:authors ("Tu, Do Hoang" . "tuhdo1710@gmail.com")) (:maintainer "Tu, Do Hoang") (:url . "https://github.com/tuhdo/semantic-stickyfunc-enhance"))]) (sticky . [(20170926 36) nil "Sticky key for capital letters" single ((:commit . "fec4e1af38f17f5cd80eca361d8e8ef8772db366") (:keywords "convenience") (:authors ("rubikitch" . "rubikitch@ruby-lang.org")) (:maintainer "rubikitch" . "rubikitch@ruby-lang.org") (:url . "http://www.emacswiki.org/cgi-bin/wiki/download/sticky.el"))]) (stgit . [(20171130 1559) nil "major mode for StGit interaction" single ((:commit . "ffd7fb7a67b4c90b38f6caa7ce14448e11cbc86e") (:authors ("David Kågedal" . "davidk@lysator.liu.se")) (:maintainer "David Kågedal" . "davidk@lysator.liu.se") (:url . "http://www.procode.org/stgit"))]) (stem-english . [(20180109 358) ((emacs (24 3))) "- routines for stemming English word" single ((:commit . "c9fc4c6ed6bf82382e479dae80912f4ae17d31f4") (:keywords "text") (:authors ("Tsuchiya Masatoshi" . "tsuchiya@pine.kuee.kyoto-u.ac.jp")) (:maintainer "KAWABATA, Taichi <kawabata.taichi_at_gmail.com>") (:url . "http://github.com/kawabata/stem-english"))]) (stem . [(20131102 1109) nil "Routines for stemming" single ((:commit . "d74e6611d6ba5025e0276a2cc7c8a90f46bfa9ac") (:keywords "stemming") (:authors ("Tsuchiya Masatoshi" . "tsuchiya@pine.kuee.kyoto-u.ac.jp")) (:maintainer "Tsuchiya Masatoshi" . "tsuchiya@pine.kuee.kyoto-u.ac.jp") (:url . "https://github.com/yuutayamada/stem"))]) (steam . [(20171109 13) ((cl-lib (0 5))) "Organize and launch Steam games" single ((:commit . "d6ca2a828b0824da51978397e198bf91c51ce793") (:keywords "games") (:authors ("Erik Sjöstrand")) (:maintainer "Erik Sjöstrand") (:url . "http://github.com/Kungsgeten/steam.el"))]) (status . [(20151230 1408) nil "This package adds support for status icons to Emacs." tar ((:commit . "b62c74bf272566f82a68622f29fb9edafea0f241"))]) (state . [(20180627 1956) ((emacs (24))) "Quick navigation between workspaces" single ((:commit . "258fe1cba00bdc2c600f866bb0406c719661d0a6") (:keywords "convenience" "workspaces") (:authors ("Sylvain Rousseau <thisirs at gmail dot com>")) (:maintainer "Sylvain Rousseau <thisirs at gmail dot com>") (:url . "https://github.com/thisirs/state.git"))]) (stash . [(20151117 1427) nil "lightweight persistent caching" single ((:commit . "c2e494d20c752b80ebbdffbf66687b3cdfc425ad") (:keywords "extensions" "data" "internal" "lisp") (:authors ("Sean Allred" . "code@seanallred.com")) (:maintainer "Sean Allred" . "code@seanallred.com") (:url . "https://www.github.com/vermiculus/stash.el/"))]) (start-menu . [(20160426 1225) ((cl-lib (0 5)) (config-parser (0 1))) "start-menu for executing external program like in windows" single ((:commit . "f7d33fed7ad2dc61156f1c1cff9e1805366fbd69") (:keywords "convenience" "menu") (:authors ("DarkSun" . "lujun9972@gmail.com")) (:maintainer "DarkSun" . "lujun9972@gmail.com") (:url . "https://github.com/lujun9972/el-start-menu"))]) (standoff-mode . [(20171115 1731) nil "Create stand-off markup, also called external markup." tar ((:commit . "cf84b14066d63694d931395c6026fd0245d8a62b"))]) (stan-snippets . [(20161024 258) ((stan-mode (9 2 0)) (yasnippet (0 8 0))) "Yasnippets for Stan" tar ((:commit . "a8e88473ef996b455523dc3fbcf2d8520659652f") (:keywords "snippets") (:authors ("Jeffrey Arnold" . "jeffrey.arnold@gmail.com")) (:maintainer "Jeffrey Arnold" . "jeffrey.arnold@gmail.com") (:url . "http://github.com/stan-dev/stan-mode"))]) (stan-mode . [(20180110 2241) nil "Major mode for editing Stan files" tar ((:commit . "a8e88473ef996b455523dc3fbcf2d8520659652f") (:keywords "languanges") (:authors ("Jeffrey Arnold" . "jeffrey.arnold@gmail.com") ("Daniel Lee" . "bearlee@alum.mit.edu")) (:maintainer "Jeffrey Arnold" . "jeffrey.arnold@gmail.com") (:url . "http://github.com/stan-dev/stan-mode"))]) (stack-mode . [(20150923 1523) ((haskell-mode (13 14)) (cl-lib (0 5)) (flycheck (0 23))) "A minor mode enabling various features based on stack-ide." tar ((:commit . "f3481e239dde9817152ec00e32bfc3ebf5aaf2cb") (:keywords "haskell" "stack") (:url . "https://github.com/commercialhaskell/stack-ide"))]) (ssh-tunnels . [(20180703 2027) ((cl-lib (0 5)) (emacs (24))) "Manage SSH tunnels" single ((:commit . "a6b6ae9a5d17afa9ea39ca8c071e889deefcf8a3") (:keywords "tools" "convenience") (:authors ("death <github.com/death>")) (:maintainer "death <github.com/death>") (:url . "http://github.com/death/ssh-tunnels"))]) (ssh-deploy . [(20180819 546) ((emacs (24))) "Deployment via TRAMP, global or per directory." tar ((:commit . "67313e2c1c795317bf2bfb634705499757e4b889") (:keywords "tools" "convenience") (:authors ("Christian Johansson <github.com/cjohansson>")) (:maintainer "Christian Johansson <github.com/cjohansson>") (:url . "https://github.com/cjohansson/emacs-ssh-deploy"))]) (ssh-config-mode . [(20180609 951) nil "Mode for fontification of ~/.ssh/config" tar ((:commit . "5429a02b8f7431c40e4a50e5d1ac2cd2d08c6511") (:keywords "ssh" "config" "emacs") (:authors ("Harley Gorrell" . "harley@panix.com")) (:maintainer "Harley Gorrell" . "harley@panix.com") (:url . "https://github.com/jhgorrell/ssh-config-mode-el"))]) (ssh-agency . [(20180508 26) ((emacs (24 4)) (dash (2 10 0))) "manage ssh-agent from Emacs" single ((:commit . "d9dbedd773ad3a831e02e162c47936d6814a850a") (:authors ("Noam Postavsky" . "npostavs@user.sourceforge.net")) (:maintainer "Noam Postavsky" . "npostavs@user.sourceforge.net") (:url . "https://github.com/magit/ssh-agency"))]) (ssh . [(20120904 2042) nil "Support for remote logins using ssh." single ((:commit . "c17cf5b43df8ac4662a0580f85898e1f078df0d1") (:keywords "unix" "comm") (:authors ("Noah Friedman" . "friedman@splode.com")) (:maintainer "Ian Eure" . "ian.eure@gmail.com"))]) (ssass-mode . [(20180428 2039) ((emacs (24 3))) "Edit Sass without a Turing Machine" single ((:commit . "da82ebb2aa7e4999c23547270d2b0b2cd9311a47") (:keywords "languages" "sass") (:authors ("Adam Niederer" . "adam.niederer@gmail.com")) (:maintainer "Adam Niederer" . "adam.niederer@gmail.com") (:url . "http://github.com/AdamNiederer/ssass-mode"))]) (srv . [(20180715 1959) ((emacs (24 3))) "perform SRV DNS requests" single ((:commit . "714387d5a5cf34d8d8cd96bdb1f9cb8ded823ff7") (:keywords "comm") (:authors ("Magnus Henoch" . "magnus.henoch@gmail.com")) (:maintainer "Magnus Henoch" . "magnus.henoch@gmail.com") (:url . "https://github.com/legoscia/srv.el"))]) (srefactor . [(20180703 1810) ((emacs (24 4))) "A refactoring tool based on Semantic parser framework" tar ((:commit . "6f2c97d17fb70f4ca2112f5a2b99a8ec162004f5") (:keywords "c" "languages" "tools") (:authors ("Tu, Do Hoang" . "tuhdo1710@gmail.com")) (:maintainer "Tu, Do Hoang") (:url . "https://github.com/tuhdo/semantic-refactor"))]) (srcery-theme . [(20180803 846) ((emacs (24))) "Dark color theme." single ((:commit . "83c09d69b646d633d687766dbda5909bf080df55") (:keywords "faces") (:authors ("Daniel Berg")) (:maintainer "Daniel Berg") (:url . "https://github.com/srcery-colors/srcery-emacs"))]) (sr-speedbar . [(20161025 831) nil "Same frame speedbar" single ((:commit . "77a83fb50f763a465c021eca7343243f465b4a47") (:keywords "speedbar" "sr-speedbar.el") (:authors ("Sebastian Rose" . "sebastian_rose@gmx.de")) (:maintainer "Sebastian Rose" . "sebastian_rose@gmx.de") (:url . "http://www.emacswiki.org/emacs/download/sr-speedbar.el"))]) (sqlup-mode . [(20170610 1537) nil "Upcase SQL words for you" single ((:commit . "04970977b4abb4d44301651618bbf1cdb0b263dd") (:keywords "sql" "tools" "redis" "upcase") (:authors ("Aldric Giacomoni" . "trevoke@gmail.com")) (:maintainer "Aldric Giacomoni" . "trevoke@gmail.com") (:url . "https://github.com/trevoke/sqlup-mode.el"))]) (sqlite . [(20180708 1711) nil "use sqlite via elisp" single ((:commit . "dad42b8bbca4994be1871343dd18fd6528ee5797") (:authors ("Christian Giménez")) (:maintainer "Christian Giménez"))]) (sql-impala . [(20160427 2358) nil "comint support for Cloudera Impala" single ((:commit . "e7a2d79d60b0a6339d730fc39ca024c3d6c56de7") (:keywords "sql" "impala") (:authors ("Jason Terk" . "jason@goterkyourself.com")) (:maintainer "Jason Terk" . "jason@goterkyourself.com") (:url . "https://github.com/jterk/sql-impala"))]) (sql-clickhouse . [(20180302 1555) ((emacs (24))) "support ClickHouse as SQL interpreter" single ((:commit . "2edccd94145c55a040a3a87193793f06cf01f64f") (:authors ("Robert Schwarz" . "mail@rschwarz.net")) (:maintainer "Robert Schwarz" . "mail@rschwarz.net") (:url . "https://github.com/leethargo/sql-clickhouse"))]) (spu . [(20161214 324) ((emacs (24 4)) (signal (1 0)) (timp (1 2 0))) "Silently upgrade package in the background" tar ((:commit . "41eec86b595816e3852e8ad1a8e07e51a27fd065") (:keywords "convenience" "package") (:authors ("Mola-T" . "Mola@molamola.xyz")) (:maintainer "Mola-T" . "Mola@molamola.xyz") (:url . "https://github.com/mola-T/spu"))]) (sprunge . [(20160301 243) ((request (0 2 0)) (cl-lib (0 5))) "Upload pastes to sprunge.us" single ((:commit . "0fd386b8b29c4175022a04ad70ea5643185b6726") (:keywords "tools") (:authors ("Tom Jakubowski")) (:maintainer "Tom Jakubowski"))]) (sproto-mode . [(20151115 1805) nil "Major mode for editing sproto." single ((:commit . "0583a88273204dccd884b7edaa3590cefd31e7f7") (:keywords "sproto") (:authors ("m2q1n9")) (:maintainer "m2q1n9"))]) (sprintly-mode . [(20121006 534) ((furl (0 0 2))) "Major mode for dealing with sprint.ly" single ((:commit . "6695892bae5860b5268bf3ae62be990ee9b63c11") (:authors ("Justin Lilly" . "justin@justinlilly.com")) (:maintainer "Justin Lilly" . "justin@justinlilly.com") (:url . "https://github.com/sprintly/sprintly-mode"))]) (springboard . [(20170106 755) ((helm (1 6 9))) "Temporarily change default-directory for one command" single ((:commit . "263a8cd4582c81bfc29d7db37d5267e2488b148c") (:keywords "helm") (:authors ("John Wiegley" . "jwiegley@gmail.com")) (:maintainer "John Wiegley" . "jwiegley@gmail.com") (:url . "https://github.com/jwiegley/springboard"))]) (spray . [(20160304 2220) nil "a speed reading mode" single ((:commit . "00638bc916227f2f961013543d10e85a43a32e29") (:keywords "convenience") (:authors ("Ian Kelling" . "ian@iankelling.org")) (:maintainer "Ian Kelling" . "ian@iankelling.org") (:url . "https://github.com/ian-kelling/spray"))]) (spotlight . [(20150929 755) ((emacs (24 1)) (swiper (0 6 0)) (counsel (0 6 0))) "search files with Mac OS X spotlight" single ((:commit . "ab902900f22e7d1ea2dd8169441d2da7155aaa68") (:keywords "search" "external") (:authors ("Ben Maughan" . "benmaughan@gmail.com")) (:maintainer "Ben Maughan" . "benmaughan@gmail.com") (:url . "http://www.pragmaticemacs.com"))]) (spotify . [(20170303 629) ((cl-lib (0 5))) "Control the spotify application from emacs" single ((:commit . "2825b5cac8406969405096660aeab6e5fef765eb") (:keywords "convenience") (:authors ("R.W. van 't Veer")) (:maintainer "R.W. van 't Veer") (:url . "https://github.com/remvee/spotify-el"))]) (splitter . [(20170809 2208) nil "Manage window splits" single ((:commit . "6bdb51e9a346907d60a9625f6180bddd06be6674") (:keywords "frames" "convenience") (:authors ("Steven Thomas")) (:maintainer "Steven Thomas") (:url . "https://github.com/chumpage/chumpy-windows"))]) (splitjoin . [(20150505 1432) ((cl-lib (0 5))) "Transition between multiline and single-line code" single ((:commit . "e2945ee269e6e90f0243d6f2a33e067bb0a2873c") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-splitjoin"))]) (spiral . [(20180223 1140) ((emacs (25 1)) (a (0 1 0 -3 4)) (avy (0 4 0)) (clojure-mode (5 6 0)) (highlight (0)) (treepy (1 0 0))) "Clojure IDE based on UNREPL" tar ((:commit . "907b9792467139a942ba7b07ca0276b90770baf9") (:keywords "languages" "clojure") (:authors ("Daniel Barreto" . "daniel@barreto.tech")) (:maintainer "Daniel Barreto" . "daniel@barreto.tech") (:url . "https://github.com/Unrepl/spiral"))]) (spice-mode . [(20171028 643) ((emacs (24 3))) "Major mode for SPICE" single ((:commit . "702bf2d5c3561be44771ea77b476532d32068504") (:keywords "spice" "spice2g6" "spice3" "eldo" "hspice" "layla" "mondriaan" "fasthenry" "cdl" "spectre compatibility" "netlist editing") (:authors ("Geert A. M. Van der Plas" . "geert_vanderplas@email.com") ("Emmanuel Rouat" . "emmanuel.rouat@wanadoo.fr") ("Carlin J. Vieri, MIT AI Lab" . "cvieri@ai.mit.edu")) (:maintainer "Geert A. M. Van der Plas" . "geert_vanderplas@email.com") (:url . "http://spice-mode.4t.com/"))]) (sphinx-mode . [(20180620 915) ((f (0 20 0)) (dash (2 14 1))) "Minor mode providing sphinx support." tar ((:commit . "b5ac514e213459dcc57184086f10b5b6be3cecd8"))]) (sphinx-frontend . [(20161025 758) nil "Launch build process for rst documents via sphinx." single ((:commit . "0cbb03361c245382d3e679dded30c4fc1713c252") (:keywords "compile" "sphinx" "restructuredtext") (:authors ("Kostafey" . "kostafey@gmail.com")) (:maintainer "Kostafey" . "kostafey@gmail.com") (:url . "https://github.com/kostafey/sphinx-frontend"))]) (sphinx-doc . [(20160116 1117) ((s (1 9 0)) (cl-lib (0 5)) (dash (2 10 0))) "Sphinx friendly docstrings for Python functions" single ((:commit . "f39da2e6cae55d5d7c7ce887e69755b7529bcd67") (:keywords "sphinx" "python") (:authors ("Vineet Naik" . "naikvin@gmail.com")) (:maintainer "Vineet Naik" . "naikvin@gmail.com") (:url . "https://github.com/naiquevin/sphinx-doc.el"))]) (speeddating . [(20180319 723) ((emacs (25))) "Increase date and time at point" single ((:commit . "df69db0560f19636a66a74f3d88c793bbb18b21e") (:keywords "date" "time") (:authors ("Xu Chunyang" . "mail@xuchunyang.me")) (:maintainer "Xu Chunyang" . "mail@xuchunyang.me") (:url . "https://github.com/xuchunyang/emacs-speeddating"))]) (speed-type . [(20171230 1647) ((emacs (24 3)) (cl-lib (0 3))) "Practice touch and speed typing" single ((:commit . "7a67fcd7bf825eee890097bd4a1b3c4f531a1135") (:keywords "games") (:authors ("Gunther Hagleitner")) (:maintainer "Julien Pagès" . "j.parkouss@gmail.com") (:url . "https://github.com/parkouss/speed-type"))]) (speechd-el . [(20180105 2017) nil "Client to speech synthesizers and Braille displays." tar ((:commit . "0b25d3eb7ae219d2af9a7e9df2f3334652156bf5"))]) (speech-tagger . [(20170728 1829) ((cl-lib (0 5))) "tag parts of speech using coreNLP" tar ((:commit . "61955b40d4e8b09e66a3e8033e82893f81657c06") (:keywords "speech" "tag" "nlp" "language" "corenlp" "parsing" "natural") (:authors ("Danny McClanahan" . "danieldmcclanahan@gmail.com")) (:maintainer "Danny McClanahan" . "danieldmcclanahan@gmail.com") (:url . "https://github.com/cosmicexplorer/speech-tagger"))]) (sparql-mode . [(20180320 1802) ((cl-lib (0 5)) (emacs (24 3))) "Edit and interactively evaluate SPARQL queries." tar ((:commit . "a00bb622c54086ac1ee96c265bf7fbef12c68089") (:authors ("Craig Andera <candera at wangdera dot com>")) (:maintainer "Bjarte Johansen <Bjarte dot Johansen at gmail dot com>") (:url . "https://github.com/ljos/sparql-mode"))]) (sparkline . [(20150101 1319) ((cl-lib (0 3))) "Make sparkline images from a list of numbers" single ((:commit . "a2b5d817d272d6363b67ed8f8cc75499a19fa8d2") (:keywords "extensions") (:authors ("Willem Rein Oudshoorn" . "woudshoo@xs4all.nl")) (:maintainer "Willem Rein Oudshoorn" . "woudshoo@xs4all.nl"))]) (spark . [(20160415 201) ((emacs (24 3))) "sparkline generation" single ((:commit . "0bf148c3ede3b31d56fd75f347cdd0b0eae60025") (:keywords "lisp" "data") (:authors ("Alvin Francis Dumalus")) (:maintainer "Alvin Francis Dumalus") (:url . "https://github.com/alvinfrancis/spark"))]) (spaces . [(20170809 2208) nil "Create and switch between named window configurations." single ((:commit . "6bdb51e9a346907d60a9625f6180bddd06be6674") (:keywords "frames" "convenience") (:authors ("Steven Thomas")) (:maintainer "Steven Thomas") (:url . "https://github.com/chumpage/chumpy-windows"))]) (spacemacs-theme . [(20180817 1304) nil "Color theme with a dark and light versions" tar ((:commit . "ec1283ff8fa10a575e599b7b160e6082f1109409") (:keywords "color" "theme") (:url . "https://github.com/nashamri/spacemacs-theme"))]) (spaceline-all-the-icons . [(20170829 820) ((emacs (24 4)) (all-the-icons (2 6 0)) (spaceline (2 0 0)) (memoize (1 0 1))) "A Spaceline theme using All The Icons" tar ((:commit . "e2e195f64a541d72b6d0ba0451f1e3072234b820") (:keywords "convenience" "lisp" "tools") (:authors ("Dominic Charlesworth" . "dgc336@gmail.com")) (:maintainer "Dominic Charlesworth" . "dgc336@gmail.com") (:url . "https://github.com/domtronn/spaceline-all-the-icons.el"))]) (spaceline . [(20180628 746) ((emacs (24 4)) (cl-lib (0 5)) (powerline (2 3)) (dash (2 11 0)) (s (1 10 0))) "Modeline configuration library for powerline" tar ((:commit . "29ced71ed0097cd5eba15d6bfdbafd9d18f5bd82") (:keywords "mode-line" "powerline" "spacemacs") (:authors ("Eivind Fonn" . "evfonn@gmail.com")) (:maintainer "Eivind Fonn" . "evfonn@gmail.com") (:url . "https://github.com/TheBB/spaceline"))]) (spacegray-theme . [(20150719 1931) ((emacs (24 1))) "A Hyperminimal UI Theme" single ((:commit . "7f70ee36297e5ccf9bc90b1f81472024f5a7a749") (:keywords "themes") (:authors ("Bruce Williams" . "brwcodes@gmail.com")) (:maintainer "Bruce Williams" . "brwcodes@gmail.com") (:url . "http://github.com/bruce/emacs-spacegray-theme"))]) (sourcetrail . [(20170410 2137) ((emacs (24 4))) "Communication with Sourcetrail" single ((:commit . "b8d5557aa565ae979622312576db20515f65f977") (:keywords "external" "tool") (:authors ("Andreas Stallinger" . "astallinger@sourcetrail.com")) (:maintainer "Andreas Stallinger" . "astallinger@sourcetrail.com"))]) (sourcerer-theme . [(20161014 1625) nil "A version of sourcerer by xero" single ((:commit . "c7f8e665d53bb48fb72f95f706710d53d24bd407") (:keywords "themes") (:authors ("Bryan Gilbert" . "gilbertw1@gmail.com")) (:maintainer "Bryan Gilbert" . "gilbertw1@gmail.com") (:url . "http://github.com/gilbertw1/sourcerer-emacs"))]) (sourcemap . [(20161216 540) ((emacs (24 3))) "Sourcemap parser" single ((:commit . "64c89d296186f48d9135fb8aad501de19f64bceb") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-sourcemap"))]) (sourcekit . [(20180101 834) ((emacs (24 3)) (dash (2 12 1)) (dash-functional (1 2 0)) (request (0 2 0))) "Library to interact with sourcekittendaemon" single ((:commit . "abf9bc5a0102eb666d3aa6d6bf22f6efcc852781") (:keywords "tools" "processes") (:authors ("Nathan Kot" . "nk@nathankot.com")) (:maintainer "Nathan Kot" . "nk@nathankot.com") (:url . "https://github.com/nathankot/company-sourcekit"))]) (soundklaus . [(20160314 1231) ((dash (2 12 1)) (emacs (24)) (emms (4 0)) (s (1 11 0)) (pkg-info (0 4)) (cl-lib (0 5)) (request (0 2 0))) "Play music on SoundCloud with Emacs via EMMS" tar ((:commit . "09ec030843482594beae2664b8fe1e0ad1e66472") (:keywords "soundcloud" "music" "emms") (:authors ("r0man" . "roman@burningswell.com")) (:maintainer "r0man" . "roman@burningswell.com") (:url . "https://github.com/r0man/soundklaus.el"))]) (soundcloud . [(20150502 326) ((emms (20131016)) (json (1 2)) (deferred (0 3 1)) (string-utils (0 3 2)) (request (20140316 417)) (request-deferred (20130526 1015))) "a SoundCloud client for Emacs" single ((:commit . "f998d4276ea90258909c698f6a5a51fccb667c08") (:keywords "soundcloud" "music" "audio") (:authors ("Travis Thieman" . "travis.thieman@gmail.com")) (:maintainer "Travis Thieman" . "travis.thieman@gmail.com"))]) (sound-wav . [(20160725 1424) ((deferred (0 3 1)) (cl-lib (0 5))) "Play wav file" single ((:commit . "406868043761524118c27b1207be0f8bbda8798e") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-sound-wav"))]) (sotlisp . [(20180706 1749) ((emacs (24 1))) "Write lisp at the speed of thought." single ((:commit . "cc5730c0803a6e0f18e22d6027784b915d304318") (:keywords "convenience" "lisp") (:authors ("Artur Malabarba" . "emacs@endlessparentheses.com")) (:maintainer "Artur Malabarba" . "emacs@endlessparentheses.com") (:url . "https://github.com/Malabarba/speed-of-thought-lisp"))]) (sotclojure . [(20170922 8) ((emacs (24 1)) (clojure-mode (4 0 0)) (cider (0 8)) (sotlisp (1 3))) "Write clojure at the speed of thought." tar ((:commit . "a480c887b53cb007b7b099c5ffcab89b9e59d7bc") (:keywords "convenience" "clojure") (:authors ("Artur Malabarba" . "emacs@endlessparentheses.com")) (:maintainer "Artur Malabarba" . "emacs@endlessparentheses.com") (:url . "https://github.com/Malabarba/speed-of-thought-clojure"))]) (sos . [(20141215 403) ((org (7))) "StackOverflow Search" single ((:commit . "1573adca912b88b5010d99a25c83a5b2313bd39c") (:keywords "tools" "search" "questions") (:authors ("Rudolf Olah")) (:maintainer "Rudolf Olah") (:url . "https://github.com/omouse/emacs-sos"))]) (sort-words . [(20160929 1335) nil "Sort words in a selected region" single ((:commit . "7b6e108f80237363faf7ec28b2c58dec270b8601") (:keywords "tools") (:authors ("\"Aleksandar Simic\"" . "asimic@gmail.com")) (:maintainer "\"Aleksandar Simic\"" . "asimic@gmail.com") (:url . "http://github.org/dotemacs/sort-words.el"))]) (soothe-theme . [(20141027 1441) ((emacs (24 1))) "a dark colorful theme for Emacs24." single ((:commit . "0786fe70c6c1b4ddcfb932fdc6862b9611cfc09b") (:authors ("Jason Milkins" . "jasonm23@gmail.com")) (:maintainer "Jason Milkins" . "jasonm23@gmail.com") (:url . "https://github.com/jasonm23/emacs-soothe-theme"))]) (sonic-pi . [(20171205 1205) ((cl-lib (0 5)) (osc (0 1)) (dash (2 2 0)) (emacs (24)) (highlight (0))) "A Emacs client for SonicPi" tar ((:commit . "3cf101b3b299735ed91658c7791ea4f04164e076") (:keywords "sonicpi" "ruby") (:authors ("Joseph Wilk" . "joe@josephwilk.net")) (:maintainer "Joseph Wilk" . "joe@josephwilk.net") (:url . "http://www.github.com/repl-electric/sonic-pi.el"))]) (solidity-mode . [(20180721 2314) nil "Major mode for ethereum's solidity language" tar ((:commit . "d89dae03c9c6cb86f4e935081cb828c6c5c62830") (:keywords "languages") (:authors ("Lefteris Karapetsas " . "lefteris@refu.co")) (:maintainer "Lefteris Karapetsas " . "lefteris@refu.co"))]) (solarized-theme . [(20180808 539) ((emacs (24 1)) (cl-lib (0 5)) (dash (2 6 0))) "The Solarized color theme, ported to Emacs." tar ((:commit . "d662ab1ff554cd083e29b5626fe3f28544b0d253"))]) (solaire-mode . [(20180521 935) ((emacs (24 4)) (cl-lib (0 5))) "make certain buffers grossly incandescent" single ((:commit . "abf2ce4da77d0877efb4a035687390ce921eda4f") (:keywords "dim" "bright" "window" "buffer" "faces") (:authors ("Henrik Lissner <http://github/hlissner>")) (:maintainer "Henrik Lissner" . "henrik@lissner.net") (:url . "https://github.com/hlissner/emacs-solaire-mode"))]) (soft-stone-theme . [(20140614 835) ((emacs (24))) "Emacs 24 theme with a light background." single ((:commit . "fb475514cfb02cf30ce358a61c48e46614344d48") (:authors ("Martin Haesler")) (:maintainer "Martin Haesler") (:url . "http://github.com/mswift42/soft-stone-theme"))]) (soft-morning-theme . [(20150918 2041) nil "Emacs24 theme with a light background." single ((:commit . "c0f9c70c97ef2be2a093cf839c4bfe27740a111c") (:authors ("Martin Haesler")) (:maintainer "Martin Haesler") (:url . "http://github.com/mswift42/soft-morning-theme"))]) (soft-charcoal-theme . [(20140420 1643) nil "Dark charcoal theme with soft colors" single ((:commit . "5607ab977fae6638e78b1495e02da8955c9ba19f") (:authors ("Martin Haesler")) (:maintainer "Martin Haesler") (:url . "http://github.com/mswift42/soft-charcoal-theme"))]) (socyl . [(20170212 642) ((s (1 11 0)) (dash (2 12 0)) (pkg-info (0 5 0)) (cl-lib (0 5))) "Frontend for several search tools" tar ((:commit . "1ef2da42f66f3ab31a34131e51648f352416f0ba") (:keywords "ripgrep" "sift" "ack" "pt" "ag" "grep" "search") (:authors ("Nicolas Lamirault" . "nicolas.lamirault@gmail.com")) (:maintainer "Nicolas Lamirault" . "nicolas.lamirault@gmail.com") (:url . "https://github.com/nlamirault/socyl"))]) (snoopy . [(20171008 2004) ((emacs (24)) (cl-lib (0 6))) "minor mode for number row unshifted character insertion" single ((:commit . "ec4123bdebfe0bb7bf4feaac2dc02b59caffe386") (:keywords "lisp") (:authors ("António Nuno Monteiro" . "anmonteiro@gmail.com")) (:maintainer "António Nuno Monteiro" . "anmonteiro@gmail.com"))]) (snippet . [(20130210 2315) nil "Insert snippets of text into a buffer" single ((:commit . "11d00dd803874b93836f2010b08bd2c97b0f3c63") (:authors ("Pete Kazmier")) (:maintainer "Pete Kazmier"))]) (snazzy-theme . [(20170823 1832) ((emacs (24)) (base16-theme (2 1))) "An elegant syntax theme with bright colors" single ((:commit . "57a1763b49b4a776084c16bc70c219246fa5b412") (:keywords "faces" "theme" "color" "snazzy") (:url . "https://github.com/weijiangan/emacs-snazzy/"))]) (snapshot-timemachine-rsnapshot . [(20170324 1213) ((snapshot-timemachine (20160222 132)) (seq (2 19))) "rsnapshot backend for snapshot-timemachine" single ((:commit . "72b0b700d80f1a0442e62bbbb6a0c8c59182f97f") (:authors ("Nicolas Petton" . "nicolas@petton.fr")) (:maintainer "Nicolas Petton" . "nicolas@petton.fr"))]) (snapshot-timemachine . [(20161221 929) ((emacs (24 4))) "Step through (Btrfs, ZFS, ...) snapshots of files" single ((:commit . "99efcebab309b11ed512a8dc62555d3834df5efb") (:authors ("Thomas Winant" . "dewinant@gmail.com")) (:maintainer "Thomas Winant" . "dewinant@gmail.com") (:url . "https://github.com/mrBliss/snapshot-timemachine"))]) (snakemake-mode . [(20180901 450) ((emacs (24 5)) (cl-lib (0 5)) (magit-popup (2 4 0))) "Major mode for editing Snakemake files" tar ((:commit . "89caed9a05a9a18a21c312163b971795253678ac") (:keywords "tools") (:authors ("Kyle Meyer" . "kyle@kyleam.com")) (:maintainer "Kyle Meyer" . "kyle@kyleam.com") (:url . "https://github.com/kyleam/snakemake-mode"))]) (smyx-theme . [(20141127 828) nil "smyx Color Theme" single ((:commit . "6263f6b401bbabaed388c8efcfc0be2e58c51401") (:keywords "color" "theme" "smyx") (:authors ("Uriel G Maldonado" . "uriel781@gmail.com")) (:maintainer "Uriel G Maldonado" . "uriel781@gmail.com"))]) (smtpmail-multi . [(20160218 2349) nil "Use different smtp servers for sending mail" single ((:commit . "81eabfe56f620ee044ff9dd52fa8b6148d0a9f30") (:keywords "comm") (:authors ("Joe Bloggs" . "vapniks@yahoo.com")) (:maintainer "Joe Bloggs" . "vapniks@yahoo.com") (:url . "https://github.com/vapniks/smtpmail-multi"))]) (smotitah . [(20150218 1030) nil "Modular emacs configuration framework" tar ((:commit . "f9ab562128a5460549d016913533778e8c94bcf3"))]) (smooth-scrolling . [(20161002 1949) nil "Make emacs scroll smoothly" single ((:commit . "2462c13640aa4c75ab3ddad443fedc29acf68f84") (:keywords "convenience") (:authors ("Adam Spiers" . "emacs-ss@adamspiers.org") ("Jeremy Bondeson" . "jbondeson@gmail.com") ("Ryan C. Thompson" . "rct+github@thompsonclan.org")) (:maintainer "Adam Spiers" . "emacs-ss@adamspiers.org") (:url . "http://github.com/aspiers/smooth-scrolling/"))]) (smooth-scroll . [(20130322 414) nil "Minor mode for smooth scrolling and in-place scrolling." single ((:commit . "02320f28abb5cae28b3a18f6b9ce93129bdbfc45") (:keywords "convenience" "emulations" "frames") (:authors ("K-talo Miyazaki <Keitaro dot Miyazaki at gmail dot com>")) (:maintainer "K-talo Miyazaki <Keitaro dot Miyazaki at gmail dot com>") (:url . "http://www.emacswiki.org/emacs/download/smooth-scroll.el"))]) (smmry . [(20161024 901) nil "SMMRY client" single ((:commit . "986a1b0aec8ab1ef17dbfb7886f47e5558cf738a") (:keywords "api" "smmry") (:authors ("james sangho nah" . "microamp@protonmail.com")) (:maintainer "james sangho nah" . "microamp@protonmail.com") (:url . "https://github.com/microamp/smmry.el"))]) (sml-modeline . [(20170614 2111) nil "Show position in a scrollbar like way in mode-line" single ((:commit . "d2f9f70174c4cf68c67eb3bb8088235735e34d9a") (:authors ("Lennart Borgman (lennart O borgman A gmail O com)")) (:maintainer "Lennart Borgman (lennart O borgman A gmail O com)") (:url . "http://bazaar.launchpad.net/~nxhtml/nxhtml/main/annotate/head%3A/util/sml-modeline.el"))]) (smiles-mode . [(20160717 1120) nil "Major mode for SMILES." single ((:commit . "fbb381758adcb000a0c304be1b797f985f00e2de") (:keywords "smiles") (:authors (nil . "John Kitchin [jkitchin@andrew.cmu.edu]")) (:maintainer nil . "John Kitchin [jkitchin@andrew.cmu.edu]"))]) (smex . [(20151212 2209) ((emacs (24))) "M-x interface with Ido-style fuzzy matching." single ((:commit . "55aaebe3d793c2c990b39a302eb26c184281c42c") (:keywords "convenience" "usability") (:authors ("Cornelius Mika" . "cornelius.mika@gmail.com")) (:maintainer "Cornelius Mika" . "cornelius.mika@gmail.com") (:url . "http://github.com/nonsequitur/smex/"))]) (smeargle . [(20161212 2358) ((emacs (24 3))) "Highlighting region by last updated time" single ((:commit . "0665b1ff5109731898bc4a0ca6d939933b804777") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-smeargle"))]) (smblog . [(20170419 1021) ((emacs (24 3))) "samba log viewer" single ((:commit . "5245e7aeac20915121946f59bba30899305d950b") (:authors ("Aurélien Aptel" . "aaptel@suse.com")) (:maintainer "Aurélien Aptel" . "aaptel@suse.com") (:url . "http://github.com/aaptel/smblog-mode"))]) (smbc . [(20171229 1808) nil "View SMBC from Emacs" single ((:commit . "10538e3d575ba6ef3c94d555af2744b42dfd36c7") (:keywords "smbc" "webcomic") (:authors ("Saksham Sharma" . "saksham0808@gmail.com")) (:maintainer "Saksham Sharma" . "saksham0808@gmail.com") (:url . "https://github.com/sakshamsharma/emacs-smbc"))]) (smarty-mode . [(20100703 1158) nil "major mode for editing smarty templates" single ((:commit . "3dfdfe1571f5e9ef55a29c51e5a80046d4cb7568") (:keywords "smarty" "php" "languages" "templates") (:maintainer "Benj Carson") (:url . "none yet"))]) (smartscan . [(20170211 2033) nil "Jumps between other symbols found at point" single ((:commit . "234e077145710a174c20742de792b97ed2f965f6") (:keywords "extensions") (:authors ("Mickey Petersen" . "mickey@masteringemacs.org")) (:maintainer "Mickey Petersen" . "mickey@masteringemacs.org"))]) (smartrep . [(20150509 230) nil "Support sequential operation which omitted prefix keys." single ((:commit . "f0ff5a6d7b8603603598ae3045c98b011e58d86e") (:keywords "convenience") (:authors ("myuhe <yuhei.maeda_at_gmail.com>")) (:maintainer "myuhe") (:url . "https://github.com/myuhe/smartrep.el"))]) (smartparens . [(20180826 1053) ((dash (2 13 0)) (cl-lib (0 3))) "Automatic insertion, wrapping and paredit-like navigation with user defined pairs." tar ((:commit . "10e2a7f1690b5466fd373fd5f808cf9b733eabcd"))]) (smart-window . [(20160717 130) ((cl-lib (0 5))) "vim-like window controlling plugin" single ((:commit . "5996461b7cbc5ab4509ac48537916eb29a8e4c16") (:keywords "window") (:authors ("Felix Chern" . "idryman@gmail.com")) (:maintainer "Felix Chern" . "idryman@gmail.com") (:url . "https://github.com/dryman/smart-window.el"))]) (smart-tabs-mode . [(20160629 1452) nil "Intelligently indent with tabs, align with spaces!" single ((:commit . "9cc2594b82b03e7d68645a4878f9359f8b8c34c5") (:keywords "languages") (:authors ("John Croisant" . "jacius@gmail.com") ("Alan Pearce" . "alan@alanpearce.co.uk") ("Daniel Dehennin" . "daniel.dehennin@baby-gnu.org") ("Matt Renaud" . "mrenaud92@gmail.com")) (:maintainer "Joel C. Salomon" . "joelcsalomon@gmail.com") (:url . "http://www.emacswiki.org/emacs/SmartTabs"))]) (smart-tab . [(20170902 2107) nil "Intelligent tab completion and indentation." single ((:commit . "76a8ec13384975d39aa1b25e5384a02558dba574") (:keywords "extensions") (:authors ("John SJ Anderson" . "genehack@genehack.org") ("Sebastien Rocca Serra" . "sroccaserra@gmail.com") ("Daniel Hackney" . "dan@haxney.org")) (:maintainer "John SJ Anderson" . "genehack@genehack.org") (:url . "http://github.com/genehack/smart-tab/tree/master"))]) (smart-shift . [(20150203 725) nil "Smart shift text left/right." single ((:commit . "a26ab2b240137e62ec4bce1698ed9c5f7b6d13ae") (:keywords "convenience" "tools") (:authors ("Bin Huang" . "huangbin88@foxmail.com")) (:maintainer "Bin Huang" . "huangbin88@foxmail.com") (:url . "https://github.com/hbin/smart-shift"))]) (smart-semicolon . [(20171008 133) ((emacs (25))) "Insert semicolon smartly" single ((:commit . "bcea2aa37befa40abf8b24a2d2314904e6df43b3") (:authors ("Iku Iwasa" . "iku.iwasa@gmail.com")) (:maintainer "Iku Iwasa" . "iku.iwasa@gmail.com") (:url . "https://github.com/iquiw/smart-semicolon"))]) (smart-region . [(20150903 1403) ((emacs (24 4)) (expand-region (0 10 0)) (multiple-cursors (1 3 0)) (cl-lib (0 5))) "Smartly select region, rectangle, multi cursors" single ((:commit . "5a8017fd8e8dc3483865951c4942cab3f96f69f6") (:keywords "marking" "region") (:authors ("Yuuki Arisawa" . "yuuki.ari@gmail.com")) (:maintainer "Yuuki Arisawa" . "yuuki.ari@gmail.com") (:url . "https://github.com/uk-ar/smart-region"))]) (smart-newline . [(20131208 340) nil "Provide smart newline for one keybind." single ((:commit . "0553a9e4be7188352de1a28f2eddfd28e7436f94") (:authors ("Satoshi Namai")) (:maintainer "Satoshi Namai"))]) (smart-mode-line-powerline-theme . [(20160706 38) ((emacs (24 3)) (powerline (2 2)) (smart-mode-line (2 5))) "smart-mode-line theme that mimics the powerline appearance." tar ((:commit . "9a81b51cd37fc5b6d47abfbb2b32f98f36a0fcfc") (:keywords "mode-line" "faces" "themes") (:authors ("Artur Malabarba" . "bruce.connor.am@gmail.com")) (:maintainer "Artur Malabarba" . "bruce.connor.am@gmail.com") (:url . "http://github.com/Bruce-Connor/smart-mode-line"))]) (smart-mode-line . [(20180801 341) ((emacs (24 3)) (rich-minority (0 1 1))) "A color coded smart mode-line." tar ((:commit . "9a81b51cd37fc5b6d47abfbb2b32f98f36a0fcfc") (:keywords "mode-line" "faces" "themes") (:authors ("Artur Malabarba" . "emacs@endlessparentheses.com")) (:maintainer "Artur Malabarba" . "emacs@endlessparentheses.com") (:url . "http://github.com/Malabarba/smart-mode-line"))]) (smart-mark . [(20150912 210) nil "Restore point after C-g when mark" single ((:commit . "04b522a23e3aae8381c6a976fc978532fcb2e7d0") (:keywords "mark" "restore") (:authors ("Kai Yu" . "yeannylam@gmail.com")) (:maintainer "Kai Yu" . "yeannylam@gmail.com"))]) (smart-jump . [(20180822 139) ((emacs (25 1)) (dumb-jump (0 5 1))) "Smart go to definition." tar ((:commit . "7424267c88afcd113ef445272dde292ae5ff0fed") (:keywords "tools") (:authors ("James Nguyen" . "james@jojojames.com")) (:maintainer "James Nguyen" . "james@jojojames.com") (:url . "https://github.com/jojojames/smart-jump"))]) (smart-indent-rigidly . [(20141206 15) nil "Smart rigid indenting" single ((:commit . "323d1fe4d0b81e598249aad01bc44adb180ece0e") (:keywords "indenting" "coffee-mode" "haml-mode" "sass-mode") (:authors ("atom smith")) (:maintainer "atom smith") (:url . "https://github.com/re5et/smart-indent-rigidly"))]) (smart-hungry-delete . [(20170412 1343) ((emacs (24 3))) "smart hungry deletion of whitespace" single ((:commit . "7c1d56a92481594e14d40b5fdf6c48657a0108a0") (:keywords "convenience") (:authors ("Hauke Rehfeld" . "emacs@haukerehfeld.de")) (:maintainer "Hauke Rehfeld" . "emacs@haukerehfeld.de") (:url . "https://github.com/hrehfeld/emacs-smart-hungry-delete"))]) (smart-forward . [(20140430 713) ((expand-region (0 8 0))) "Semantic navigation" single ((:commit . "7b6dbfdbd4b646376a567c70e1a161545431b72b") (:keywords "navigation") (:authors ("Magnar Sveen" . "magnars@gmail.com")) (:maintainer "Magnar Sveen" . "magnars@gmail.com"))]) (smart-dash . [(20110131 316) nil "Smart-Dash minor mode" single ((:authors ("Dennis Lambe Jr." . "malsyned@malsyned.net")) (:maintainer "Dennis Lambe Jr." . "malsyned@malsyned.net"))]) (smart-cursor-color . [(20141124 1719) nil "Change cursor color dynamically" single ((:commit . "1d190f49ca77734b55ac58f1b6276e42ada967b0") (:keywords "cursor" "color" "face") (:authors ("7696122")) (:maintainer "7696122") (:url . "https://github.com/7696122/smart-cursor-color/"))]) (smart-compile . [(20180316 330) nil "an interface to `compile'" single ((:commit . "16ebc3c570f1949b8198fcc8663d6d26df32717a") (:keywords "tools" "unix") (:authors ("Seiji Zenitani" . "zenitani@mac.com")) (:maintainer "Seiji Zenitani" . "zenitani@mac.com"))]) (smart-comment . [(20160322 1839) nil "smarter commenting" single ((:commit . "17ddbd83205818763e6d68aa7a1aa9aaf414cbd4") (:keywords "lisp") (:authors ("Simon Friis Vindum" . "simon@vindum.io")) (:maintainer "Simon Friis Vindum" . "simon@vindum.io"))]) (smart-backspace . [(20171014 526) nil "intellj like backspace" single ((:commit . "a10ec44ff325ec8c4c98b1a6e44e89e60a9aa4ac") (:authors ("Takeshi Tsukamoto" . "t.t.itm.0403@gmail.com")) (:maintainer "Takeshi Tsukamoto" . "t.t.itm.0403@gmail.com") (:url . "https://github.com/itome/smart-backspace"))]) (sly-repl-ansi-color . [(20171020 1516) ((sly (0)) (cl-lib (0 5))) "Add ANSI colors support to the sly mrepl." single ((:commit . "b9cd52d1cf927bf7e08582d46ab0bcf1d4fb5048") (:keywords "sly") (:authors ("Javier \"PuercoPop\" Olaechea" . "pirata@gmail.com") ("Max Mikhanosha")) (:maintainer "Javier \"PuercoPop\" Olaechea" . "pirata@gmail.com") (:url . "https://github.com/PuercoPop/sly-repl-ansi-color"))]) (sly-quicklisp . [(20170112 935) ((sly (1 0 0 -2 2))) "Quicklisp support for SLY" tar ((:commit . "8a9e3c0c07c6861ec33b338cc46ac12e7ce6a477") (:keywords "languages" "lisp" "sly") (:authors ("João Távora" . "joaotavora@gmail.com")) (:maintainer "João Távora" . "joaotavora@gmail.com") (:url . "https://github.com/capitaomorte/sly-quicklisp"))]) (sly-named-readtables . [(20150817 1516) ((sly (1 0 0 -2 2))) "Support named readtables in Common Lisp files" tar ((:commit . "df4ed79064cf85275804e201899b677bef4ab3f5") (:keywords "languages" "lisp" "sly") (:authors ("João Távora" . "joaotavora@gmail.com")) (:maintainer "João Távora" . "joaotavora@gmail.com") (:url . "https://github.com/capitaomorte/sly-named-readtables"))]) (sly-macrostep . [(20160119 1234) ((sly (1 0 0 -2 2)) (macrostep (0 9))) "fancy macro-expansion via macrostep.el" tar ((:commit . "eb16778d104413a3e2a8d5537437c4ad76c2954b") (:keywords "languages" "lisp" "sly") (:url . "https://github.com/capitaomorte/sly-macrostep"))]) (sly-hello-world . [(20160119 1436) ((sly (1 0 0 -2 2))) "A template SLY contrib" tar ((:commit . "1bfcca692b6ec0670ed309ffe29eb9384397c183") (:keywords "languages" "lisp" "sly") (:authors ("João Távora" . "joaotavora@gmail.com")) (:maintainer "João Távora" . "joaotavora@gmail.com") (:url . "https://github.com/capitaomorte/sly-hello-world"))]) (sly . [(20180903 2249) ((emacs (24 3))) "Sylvester the Cat's Common Lisp IDE" tar ((:commit . "c3d6f127005c4c416744d8950d616285ff746bf0") (:keywords "languages" "lisp" "sly") (:url . "https://github.com/joaotavora/sly"))]) (slstats . [(20170823 849) ((cl-lib (0 5)) (emacs (24))) "Acquire and display stats about Second Life" single ((:commit . "e9696066abf3f2b7b818a57c062530dfd9377033") (:keywords "games") (:authors ("Dave Pearson" . "davep@davep.org")) (:maintainer "Dave Pearson" . "davep@davep.org") (:url . "https://github.com/davep/slstats.el"))]) (slow-keys . [(20180831 459) ((emacs (24 1))) "Slow keys mode to avoid RSI" single ((:commit . "b93ad77f9fc1d14e080d7d64864fc9cb222248b6") (:keywords "convenience") (:authors ("Manuel Uberti" . "manuel.uberti@inventati.org")) (:maintainer "Manuel Uberti" . "manuel.uberti@inventati.org") (:url . "https://github.com/manuel-uberti/slow-keys"))]) (slovak-holidays . [(20150418 855) nil "Adds a list of slovak holidays to Emacs calendar" single ((:commit . "effb16dfcd14797bf7448f5113085479db339c02") (:keywords "calendar") (:authors ("Matúš Goljer" . "matus.goljer@gmail.com")) (:maintainer "Matúš Goljer" . "matus.goljer@gmail.com"))]) (slirm . [(20160201 1425) ((emacs (24 4))) "Systematic Literature Review Mode for Emacs." single ((:commit . "9adfbe1fc67580e7d0d90f7e927a25d63a797464") (:authors ("Florian Biermann" . "fbie@itu.dk")) (:maintainer "Florian Biermann" . "fbie@itu.dk") (:url . "http://github.com/fbie/slirm"))]) (slime-volleyball . [(20140718 441) nil "An SVG Slime Volleyball Game" tar ((:commit . "159b5c0f40b109e3854e94b89ec5383854c46ae3") (:keywords "games") (:authors ("Thomas Fitzsimmons" . "fitzsim@fitzsim.org")) (:maintainer "Thomas Fitzsimmons" . "fitzsim@fitzsim.org"))]) (slime-theme . [(20170808 1322) ((emacs (24 0))) "an Emacs 24 theme based on Slime (tmTheme)" single ((:commit . "8e5880ac69e0b6a079103001cc3a90bdb688998f") (:authors ("Jason Milkins")) (:maintainer "Jason Milkins") (:url . "https://github.com/emacsfodder/tmtheme-to-deftheme"))]) (slime-docker . [(20171004 1851) ((emacs (24)) (slime (2 16)) (docker-tramp (0 1)) (cl-lib (0 5))) "Integration of SLIME with Docker containers." tar ((:commit . "13fa8be2fca516f3ff5fb70fa79dd8404bf86439") (:keywords "docker" "lisp" "slime") (:url . "https://github.com/daewok/slime-docker"))]) (slime-company . [(20180119 1843) ((emacs (24 4)) (slime (2 13)) (company (0 9 0))) "slime completion backend for company mode" single ((:commit . "4c2e2805540dea700130607fa235018a87e4a070") (:keywords "convenience" "lisp" "abbrev") (:authors ("Ole Arndt" . "anwyn@sugarshark.com")) (:maintainer "Ole Arndt" . "anwyn@sugarshark.com"))]) (slime . [(20180903 2109) ((cl-lib (0 5)) (macrostep (0 9))) "Superior Lisp Interaction Mode for Emacs" tar ((:commit . "114bc26170523f3215b319baa35569ba6b3e6917") (:keywords "languages" "lisp" "slime") (:url . "https://github.com/slime/slime"))]) (slim-mode . [(20170728 1348) nil "Major mode for editing Slim files" single ((:commit . "3636d18ab1c8b316eea71c4732eb44743e2ded87") (:keywords "markup" "language") (:authors ("Nathan Weizenbaum")) (:maintainer "Nathan Weizenbaum") (:url . "http://github.com/slim-template/emacs-slim"))]) (slideview . [(20150324 2240) ((cl-lib (0 3))) "File slideshow" single ((:commit . "b6d170bda139aedf81b47dc55cbd1a3af512fb4c") (:keywords "files") (:authors ("Masahiro Hayashi" . "mhayashi1120@gmail.com")) (:maintainer "Masahiro Hayashi" . "mhayashi1120@gmail.com") (:url . "https://github.com/mhayashi1120/Emacs-slideview"))]) (slack . [(20180902 755) ((websocket (1 8)) (request (0 2 0)) (oauth2 (0 10)) (circe (2 2)) (alert (1 2)) (emojify (0 2))) "Slack client for Emacs" tar ((:commit . "44ce2e90cb78a4d43674ddfa79254556ce75ec9f") (:url . "https://github.com/yuya373/emacs-slack"))]) (sl . [(20161217 1404) ((cl-lib (0 5))) "An Emacs clone of sl(1)" tar ((:commit . "0882117728be91276b815e18c2a66106bf9d69d3") (:authors ("Chunyang Xu" . "mail@xuchunyang.me")) (:maintainer "Chunyang Xu" . "mail@xuchunyang.me") (:url . "https://github.com/xuchunyang/sl.el"))]) (skype . [(20160711 824) nil "skype UI for emacs users.." tar ((:commit . "8e3b33e620ed355522aa36434ff41e3ced080629") (:keywords "skype" "chat") (:authors ("SAKURAI Masashi" . "m.sakurai@kiwanami.net")) (:maintainer "SAKURAI Masashi" . "m.sakurai@kiwanami.net"))]) (skewer-reload-stylesheets . [(20160725 1220) ((skewer-mode (1 5 3))) "live-edit CSS, SCSS, Less, and friends." tar ((:commit . "b9cc5635230ac3c0603a6da690c6e632d0a7490a") (:authors ("Nate Eagleson" . "nate@nateeag.com")) (:maintainer "Nate Eagleson" . "nate@nateeag.com"))]) (skewer-mode . [(20180706 1807) ((simple-httpd (1 4 0)) (js2-mode (20090723)) (emacs (24))) "live browser JavaScript, CSS, and HTML interaction" tar ((:commit . "a381049acc4fa2087615b4b3b26c0865841386bd"))]) (skewer-less . [(20160828 2021) ((skewer-mode (1 5 3))) "Skewer support for live LESS stylesheet updates" single ((:commit . "927d6848a1ea9428d4cc995f76bd42f7b8da6bc8") (:keywords "languages" "tools") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com"))]) (skeletor . [(20170617 46) ((s (1 7 0)) (f (0 14 0)) (dash (2 2 0)) (cl-lib (0 3)) (let-alist (1 0 3)) (emacs (24 1))) "Provides project skeletons for Emacs" tar ((:commit . "01c330ec115fc29bba5d9bdf6c15beb4a44e2281") (:authors ("Chris Barrett" . "chris.d.barrett@me.com")) (:maintainer "Chris Barrett" . "chris.d.barrett@me.com"))]) (simplezen . [(20130421 1000) ((s (1 4 0)) (dash (1 1 0))) "A simple subset of zencoding-mode for Emacs." single ((:commit . "119fdf2c6890a0c56045ae72cf4fce0071a81481") (:authors ("Magnar Sveen" . "magnars@gmail.com")) (:maintainer "Magnar Sveen" . "magnars@gmail.com"))]) (simplenote2 . [(20171202 206) ((request-deferred (0 2 0))) "Interact with app.simplenote.com" tar ((:commit . "0fd6dbd0566af29964078e4b74baf69c2f52381a") (:keywords "simplenote") (:authors ("alpha22jp" . "alpha22jp@gmail.com")) (:maintainer "alpha22jp" . "alpha22jp@gmail.com"))]) (simplenote . [(20141118 1440) nil "Interact with simple-note.appspot.com" single ((:commit . "e836fcdb5a6497a9ffd6bceddd19b4bc52189078") (:keywords "simplenote") (:authors ("Konstantinos Efstathiou" . "konstantinos@efstathiou.gr")) (:maintainer "Konstantinos Efstathiou" . "konstantinos@efstathiou.gr"))]) (simpleclip . [(20180811 1608) nil "Simplified access to the system clipboard" single ((:commit . "7fff9a1e574466878b5f91e9b56b16e490045aaa") (:keywords "convenience") (:authors ("Roland Walker" . "walker@pobox.com")) (:maintainer "Roland Walker" . "walker@pobox.com") (:url . "http://github.com/rolandwalker/simpleclip"))]) (simple-screen . [(20161009 920) nil "Simple screen configuration manager" single ((:commit . "596e3a451d9af24730ab31a8fe15c91a4264d09d") (:keywords "tools") (:authors ("Tadashi Watanabe" . "wac@umiushi.org")) (:maintainer "Tadashi Watanabe" . "wac@umiushi.org") (:url . "https://github.com/wachikun/simple-screen"))]) (simple-rtm . [(20160222 1534) ((rtm (0 1)) (dash (2 0 0))) "Interactive Emacs mode for Remember The Milk" single ((:commit . "8c7cd96cf66ef112be5c363e3378e304f8f83999") (:keywords "remember" "the" "milk" "productivity" "todo") (:authors ("Moritz Bunkus" . "morit@bunkus.org")) (:maintainer "Moritz Bunkus" . "morit@bunkus.org"))]) (simple-paren . [(20180427 918) ((emacs (24)) (cl-lib (0 5))) "Insert paired delimiter, wrap" single ((:commit . "8d735905306c587851eff1445898499c01c530ca") (:keywords "convenience") (:authors ("Andreas Röhler, Steve Purcell")) (:maintainer "Andreas Röhler, Steve Purcell") (:url . "https://github.com/andreas-roehler/simple-paren"))]) (simple-mpc . [(20180716 129) ((s (1 10 0))) "provides a simple interface to mpc" tar ((:commit . "bee8520e81292b4c7353e45b193f9a13b482f5b2") (:keywords "multimedia" "mpd" "mpc") (:authors ("Joren Van Onder" . "joren.vanonder@gmail.com")) (:maintainer "Joren Van Onder" . "joren.vanonder@gmail.com") (:url . "https://github.com/jorenvo/simple-mpc"))]) (simple-httpd . [(20180528 1603) ((cl-lib (0 3))) "pure elisp HTTP server" single ((:commit . "49721d5b791bee0fc25b1fdd69696371d546093a") (:authors ("Christopher Wellons" . "wellons@nullprogram.com")) (:maintainer "Christopher Wellons" . "wellons@nullprogram.com") (:url . "https://github.com/skeeto/emacs-http-server"))]) (simple-call-tree . [(20180224 2056) ((emacs (24 3)) (anaphora (1 0 0))) "analyze source code based on font-lock text-properties" single ((:commit . "20059eb5549408def76aeb03d0d20839903dedef") (:keywords "programming") (:authors ("Joe Bloggs" . "vapniks@yahoo.com")) (:maintainer "Joe Bloggs" . "vapniks@yahoo.com") (:url . "http://www.emacswiki.org/emacs/download/simple-call-tree.el"))]) (simple-bookmarks . [(20160804 1401) ((cl-lib (0 5))) "Bookmark / functioncall manager" tar ((:commit . "6c58337f2b7dbe9e58b5e097b1567f046a01d071") (:keywords "bookmark" "functioncall") (:authors ("Julian T. Knabenschuh" . "jtkdevelopments@gmail.com")) (:maintainer "Julian T. Knabenschuh" . "jtkdevelopments@gmail.com") (:url . "https://github.com/jtkDvlp/simple-bookmarks"))]) (simp . [(20180607 254) nil "Simple project definition, chiefly for file finding, and grepping" tar ((:commit . "d4d4b8547055347828bedccbeffdb4fd2d5a5d34") (:keywords "project" "grep" "find") (:authors ("atom smith")) (:maintainer "atom smith") (:url . "https://github.com/re5et/simp"))]) (silkworm-theme . [(20180301 1437) ((emacs (24))) "Light theme with pleasant, low contrast colors." single ((:commit . "4a297f952401cfe894dcb24174f6eda05e00fada") (:authors ("Martin Haesler")) (:maintainer "Martin Haesler"))]) (signature . [(20140730 1949) nil "Signature Survey" tar ((:commit . "c47df2e1189a84505f9224aa78e87b6c65d13d37") (:authors ("Peter Stiernström" . "peter@stiernstrom.se")) (:maintainer "Peter Stiernström" . "peter@stiernstrom.se"))]) (signal . [(20160816 1438) ((emacs (24)) (cl-lib (0 5))) "Advanced hook" single ((:commit . "aa58327e2297df921d72a0370468b48663efd438") (:keywords "internal" "lisp" "processes" "tools") (:authors ("Mola-T" . "Mola@molamola.xyz")) (:maintainer "Mola-T" . "Mola@molamola.xyz") (:url . "https://github.com/mola-T/signal"))]) (sift . [(20160107 1015) nil "Front-end for sift, a fast and powerful grep alternative" single ((:commit . "4ce8878a0fc396ded7521ce38852d93e1d863065") (:keywords "sift" "ack" "pt" "ag" "grep" "search") (:authors ("Nicolas Lamirault" . "nicolas.lamirault@gmail.com")) (:maintainer "Nicolas Lamirault" . "nicolas.lamirault@gmail.com") (:url . "https://github.com/nlamirault/sift.el"))]) (side-notes . [(20180524 628) ((emacs (24 5))) "Easy access to a directory notes file" single ((:commit . "981ac308b9b5d58e2af20485377e693d2a6e15aa") (:keywords "convenience") (:authors ("Paul W. Rankin" . "hello@paulwrankin.com")) (:maintainer "Paul W. Rankin" . "hello@paulwrankin.com") (:url . "https://github.com/rnkn/side-notes"))]) (sicp . [(20180823 1222) nil "Structure and Interpretation of Computer Programs in info format" tar ((:commit . "33acfa10a058aa65b6b22084a5b86a82410d794e") (:authors ("Hal Abelson") ("Jerry Sussman") ("Julie Sussman")) (:maintainer "Hal Abelson") (:url . "https://mitpress.mit.edu/sicp"))]) (sibilant-mode . [(20151119 2145) nil "Support for the Sibilant programming language" single ((:commit . "bc1b5d8cd597918bafc9b2880ee49024740e54ab") (:keywords "languages") (:authors ("Jacob Rothstein" . "hi@jbr.me")) (:maintainer "Jacob Rothstein" . "hi@jbr.me") (:url . "http://sibilantjs.info"))]) (shx . [(20180528 2108) ((emacs (24 4))) "\"Extras\" for the (comint-mode) shell" single ((:commit . "207e6cd292a26fb1162072e2e20df9aa5efd61ef") (:keywords "processes" "tools") (:url . "https://github.com/riscy/shx-for-emacs"))]) (shut-up . [(20180628 1830) ((cl-lib (0 3)) (emacs (24))) "Shut up would you!" single ((:commit . "081d6b01e3ba0e60326558e545c4019219e046ce") (:authors ("Johan Andersson" . "johan.rejeep@gmail.com")) (:maintainer "Johan Andersson" . "johan.rejeep@gmail.com") (:url . "http://github.com/rejeep/shut-up.el"))]) (shrink-whitespace . [(20150916 1915) nil "Whitespace removal DWIM key" single ((:commit . "8d4263d974fbe66417c0bb9edc155ecc2f48e4b7") (:keywords "editing") (:authors ("Jean-Christophe Petkovich" . "jcpetkovich@gmail.com")) (:maintainer "Jean-Christophe Petkovich" . "jcpetkovich@gmail.com") (:url . "https://github.com/jcpetkovich/shrink-whitespace.el"))]) (shrink-path . [(20170813 247) ((emacs (24)) (s (1 6 1)) (dash (1 8 0)) (f (0 10 0))) "fish-style path" single ((:commit . "9d06c453d1537df46a4b703a29213cc7f7857aa0") (:authors ("Benjamin Andresen")) (:maintainer "Benjamin Andresen") (:url . "https://gitlab.com/bennya/shrink-path.el"))]) (shr-tag-pre-highlight . [(20171113 914) ((emacs (25 1)) (language-detection (0 1 0))) "Syntax highlighting code block in HTML" single ((:commit . "6182f43a36b0f82ba6edcf6e423b5f69a46a814e") (:keywords "html") (:authors ("Chunyang Xu" . "mail@xuchunyang.me")) (:maintainer "Chunyang Xu" . "mail@xuchunyang.me") (:url . "https://github.com/xuchunyang/shr-tag-pre-highlight.el"))]) (shpec-mode . [(20150530 922) nil "Minor mode for shpec specification" single ((:commit . "146adc8281d0f115df39a3a3f982ac59ab61b754") (:keywords "languages" "tools") (:authors ("AdrieanKhisbe" . "adriean.khisbe@live.fr")) (:maintainer "AdrieanKhisbe" . "adriean.khisbe@live.fr") (:url . "http://github.com/shpec/shpec-mode"))]) (showtip . [(20090830 1040) nil "Show tip at cursor" single ((:commit . "930da302809a4257e8d69425455b29e1cc91949b") (:keywords "help") (:authors ("Ye Wenbin" . "wenbinye@gmail.com")) (:maintainer "Ye Wenbin" . "wenbinye@gmail.com"))]) (show-marks . [(20130805 1449) ((fm (1 0))) "Navigate and visualize the mark-ring" single ((:commit . "97609566582e65eed0d0a854efa5c312f209115d") (:keywords "convenience") (:authors ("Greg Rowe" . "emacs@therowes.net")) (:maintainer "Joe Bloggs" . "vapniks@yahoo.com") (:url . "https://github.com/vapniks/mark"))]) (show-css . [(20160210 1408) ((doom (1 3)) (s (1 10 0))) "Show the css of the html attribute the cursor is on" tar ((:commit . "771daeddd4df7a7c10f66419a837145649bab63b") (:keywords "hypermedia") (:authors ("Sheldon McGrandle" . "developer@rednemesis.com")) (:maintainer "Sheldon McGrandle" . "developer@rednemesis.com") (:url . "https://github.com/smmcg/showcss-mode"))]) (shoulda . [(20140616 1833) ((cl-lib (0 5))) "Shoulda test support for ruby" single ((:commit . "fbe8eb8efc6cfcca1713283a290882cfcdc8725e") (:keywords "ruby" "tests" "shoulda") (:authors ("Marcwebbie" . "marcwebbie@gmail.com")) (:maintainer "Marcwebbie" . "marcwebbie@gmail.com"))]) (shm . [(20180327 57) nil "Structured Haskell Mode" tar ((:commit . "7f9df73f45d107017c18ce4835bbc190dfe6782e") (:keywords "development" "haskell" "structured") (:authors ("Chris Done" . "chrisdone@gmail.com")) (:maintainer "Chris Done" . "chrisdone@gmail.com"))]) (shimbun . [(20180326 348) nil "interfacing with web newspapers" tar ((:commit . "ea64ccb3d792b60f0815309f588bf46b1f0ca80e") (:keywords "news") (:authors ("TSUCHIYA Masatoshi" . "tsuchiya@namazu.org") ("Akihiro Arisawa   " . "ari@mbf.sphere.ne.jp") ("Yuuichi Teranishi " . "teranisi@gohome.org") ("Katsumi Yamaoka   " . "yamaoka@jpl.org")) (:maintainer "TSUCHIYA Masatoshi" . "tsuchiya@namazu.org"))]) (shift-text . [(20130831 1655) ((cl-lib (1 0)) (es-lib (0 3))) "Move the region in 4 directions, in a way similar to Eclipse's" single ((:commit . "1be9cbf994000022172ceb746fe1d597f57ea8ba") (:authors ("sabof")) (:maintainer "sabof") (:url . "https://github.com/sabof/shift-text"))]) (shift-number . [(20170301 1459) nil "Increase/decrease the number at point" single ((:commit . "cd099a5582fc996b800ac7607f6c38a004ce9740") (:keywords "convenience") (:authors ("Alex Kost" . "alezost@gmail.com")) (:maintainer "Alex Kost" . "alezost@gmail.com") (:url . "https://github.com/alezost/shift-number.el"))]) (shen-elisp . [(20170427 2202) ((emacs (24 4))) "Shen implementation in Elisp" tar ((:commit . "ffe17dee05f75539cf5e4c59395e4c7400ececaa") (:keywords "shen" "elisp") (:url . "http://github.com/deech/shen-elisp"))]) (shelltest-mode . [(20180501 141) nil "Major mode for shelltestrunner" single ((:commit . "5fea8c9394380e822971a171905b6b5ab9be812d") (:keywords "languages") (:authors ("Dustin Fechner" . "dfe@rtrn.io")) (:maintainer "Dustin Fechner" . "dfe@rtrn.io") (:url . "https://github.com/rtrn/shelltest-mode"))]) (shelldoc . [(20151115 325) ((cl-lib (0 3)) (s (1 9 0))) "shell command editing support with man page." single ((:commit . "5df2264eb60e45066f3633df4f34834751667346") (:keywords "applications") (:authors ("Masahiro Hayashi" . "mhayashi1120@gmail.com")) (:maintainer "Masahiro Hayashi" . "mhayashi1120@gmail.com") (:url . "http://github.com/mhayashi1120/Emacs-shelldoc"))]) (shell-toggle . [(20150226 1411) nil "Toggle to and from the shell buffer" single ((:commit . "0d01bd9a780fdb7fe6609c552523f4498649a3b9") (:keywords "processes") (:authors ("Mikael Sjödin" . "mic@docs.uu.se") ("Matthieu Moy") ("Akinori MUSHA" . "knu@iDaemons.org")) (:maintainer "Mikael Sjödin" . "mic@docs.uu.se") (:url . "https://github.com/knu/shell-toggle.el"))]) (shell-switcher . [(20161029 552) ((emacs (24))) "Provide fast switching between shell buffers." tar ((:commit . "28a7f753dd7addd2933510526f52620cb5a22048"))]) (shell-split-string . [(20151224 1008) nil "Split strings using shell-like syntax" single ((:commit . "19f6f999c33cc66a4c91bacdcc3697c25d97bf5a") (:keywords "utility" "library" "shell" "string") (:authors ("10sr <8.slashes+el [at] gmail [dot] com>")) (:maintainer "10sr <8.slashes+el [at] gmail [dot] com>") (:url . "https://github.com/10sr/shell-split-string-el"))]) (shell-pop . [(20170304 1416) ((emacs (24)) (cl-lib (0 5))) "helps you to use shell easily on Emacs. Only one key action to work." single ((:commit . "4a3a9d093ad1add792bba764c601aa28de302b34") (:keywords "shell" "terminal" "tools") (:authors ("Kazuo YAGI" . "kazuo.yagi@gmail.com")) (:maintainer "Kazuo YAGI" . "kazuo.yagi@gmail.com") (:url . "http://github.com/kyagi/shell-pop-el"))]) (shell-history . [(20100505 839) nil "integration with shell history" single ((:commit . "ee371a81f2d2bf5a308344078329ca1e9b5ed38c") (:keywords "processes" "convenience") (:authors ("rubikitch" . "rubikitch@ruby-lang.org")) (:maintainer "rubikitch" . "rubikitch@ruby-lang.org") (:url . "http://www.emacswiki.org/cgi-bin/wiki/download/shell-history.el"))]) (shell-here . [(20150728 1704) nil "Open a shell relative to the working directory" single ((:commit . "251309141e18978d2b8014345acc6f5afcd4d509") (:keywords "unix" "tools" "processes") (:authors ("Ian Eure" . "ian.eure@gmail.com")) (:maintainer "Ian Eure" . "ian.eure@gmail.com"))]) (shell-current-directory . [(20140101 2354) nil "create new shell based on buffer directory" single ((:commit . "bf843771bf9a4aa05e054ade799eb8862f3be89a") (:keywords "shell" "comint") (:authors ("Daniel Polani")) (:maintainer "Daniel Polani"))]) (shell-command . [(20090830 1040) nil "enables tab-completion for `shell-command'" single ((:commit . "7e22125f746ce9ffbe9b0282d62f4b4bbbe672bd") (:keywords "shell") (:authors ("TSUCHIYA Masatoshi" . "tsuchiya@namazu.org")) (:maintainer "TSUCHIYA Masatoshi" . "tsuchiya@namazu.org"))]) (shampoo . [(20131230 1019) nil "A remote Smalltalk development mode" tar ((:commit . "bc193c39636c30182159c5c91c37a9a4cb50fedf"))]) (shakespeare-mode . [(20180704 2138) nil "A major mode for editing Shakespearean templates." single ((:commit . "c442eeea9d585e1b1fbb8813e33d47feec348a57") (:keywords "shakespeare" "hamlet" "lucius" "julius" "mode") (:authors ("Cody Reichert")) (:maintainer "Cody Reichert") (:url . "http://github.com/CodyReichert/shakespeare-mode"))]) (shader-mode . [(20180518 1157) ((emacs (24))) "Major mode for shader" single ((:commit . "d7dc8d0d6fe8914e8b6d5cf2081ad61e6952359c") (:authors ("midnightSuyama" . "midnightSuyama@gmail.com")) (:maintainer "midnightSuyama" . "midnightSuyama@gmail.com") (:url . "https://github.com/midnightSuyama/shader-mode"))]) (shadchen . [(20141102 1839) nil "pattern matching for elisp" single ((:commit . "35f2b9c304eec990c16efbd557198289dc7cbb1f") (:authors ("Vincent Toups")) (:maintainer "Vincent Toups"))]) (shackle . [(20171209 2201) ((cl-lib (0 5))) "Enforce rules for popups" single ((:commit . "4189c1c773aab533969b587f7801ffbcd1d7d613") (:keywords "convenience") (:authors ("Vasilij Schneidermann" . "v.schneidermann@gmail.com")) (:maintainer "Vasilij Schneidermann" . "v.schneidermann@gmail.com") (:url . "https://github.com/wasamasa/shackle"))]) (sexy-monochrome-theme . [(20180526 808) nil "A sexy dark Emacs >= 24 theme for your sexy code" single ((:commit . "036bc238e48dd21aae1c34e6971d376582d8281b") (:keywords "themes") (:authors ("Volodymyr Yevtushenko" . "voloyev@vivaldi.net")) (:maintainer "Volodymyr Yevtushenko" . "voloyev@vivaldi.net") (:url . "https://github.com/voloyev/sexy-monochrome-theme"))]) (sexp-move . [(20150915 1730) nil "Improved S-Expression Movement" single ((:commit . "117f7a91ab7c25e438413753e916570122011ce7") (:keywords "sexp") (:authors ("Philip Woods" . "elzairthesorcerer@gmail.com")) (:maintainer "Philip Woods" . "elzairthesorcerer@gmail.com") (:url . "https://gitlab.com/elzair/sexp-move"))]) (seti-theme . [(20161208 1636) nil "A dark colored theme, inspired by Seti Atom Theme" single ((:commit . "cbfef2fc15d19ce4c8326e65fafdd61737077132") (:keywords "themes") (:authors ("Vlad Piersec" . "vlad.piersec@gmail.com")) (:maintainer "Vlad Piersec" . "vlad.piersec@gmail.com") (:url . "https://github.com/caisah/seti-theme"))]) (session . [(20120511 0) nil "use variables, registers and buffer places across sessions" single ((:commit . "19ea0806873daac3539a4b956e15655e99e3dd6c") (:keywords "session" "session management" "desktop" "data" "tools") (:authors ("Christoph Wedler" . "wedler@users.sourceforge.net")) (:maintainer "Christoph Wedler" . "wedler@users.sourceforge.net") (:url . "http://emacs-session.sourceforge.net/"))]) (sesman . [(20180903 1826) ((emacs (25))) "Generic Session Manager" tar ((:commit . "5a9727ee82a74035fa6aee1e4b94829bd4260f0c") (:keywords "process") (:authors ("Vitalie Spinu")) (:maintainer "Vitalie Spinu") (:url . "https://github.com/vspinu/sesman"))]) (services . [(20170802 1130) ((cl-lib (0 5))) "Services database access functions." single ((:commit . "04c7986041a33dfa0b0ae57c7d6fbd600548c596") (:keywords "convenience" "net" "services") (:authors ("Dave Pearson" . "davep@davep.org")) (:maintainer "Dave Pearson" . "davep@davep.org") (:url . "https://github.com/davep/services.el"))]) (serverspec . [(20150623 1155) ((dash (2 6 0)) (s (1 9 0)) (f (0 16 2)) (helm (1 6 1))) "Serverspec minor mode" tar ((:commit . "b6dfe82af9869438de5e5d860ced196641f372c0") (:authors ("k1LoW (Kenichirou Oyama), <k1lowxb [at] gmail [dot] com> <k1low [at] 101000lab [dot] org>")) (:maintainer "k1LoW (Kenichirou Oyama), <k1lowxb [at] gmail [dot] com> <k1low [at] 101000lab [dot] org>") (:url . "http://101000lab.org"))]) (servant . [(20140216 1219) ((s (1 8 0)) (dash (2 2 0)) (f (0 11 0)) (ansi (0 3 0)) (commander (0 5 0)) (epl (0 2)) (shut-up (0 2 1)) (web-server (0 0 1))) "ELPA server written in Emacs Lisp" tar ((:commit . "4d2aa8250b54b28e6e7ee4cd5ebd98a33db2c134") (:keywords "elpa" "server") (:authors ("Johan Andersson" . "johan.rejeep@gmail.com") ("Sebastian Wiesner" . "lunaryorn@gmail.com")) (:maintainer "Johan Andersson" . "johan.rejeep@gmail.com") (:url . "http://github.com/rejeep/servant.el"))]) (sequential-command . [(20170926 40) nil "Many commands into one command" tar ((:commit . "a48cbcbe273b33edd3ae56e68f44b4100fa3a48a") (:keywords "convenience" "lisp") (:authors ("rubikitch" . "rubikitch@ruby-lang.org")) (:maintainer "rubikitch" . "rubikitch@ruby-lang.org") (:url . "http://www.emacswiki.org/cgi-bin/wiki/download/sequential-command.el"))]) (sequences . [(20170818 1252) ((emacs (24))) "Ports of some Clojure sequence functions." single ((:commit . "564ebbd93b0beea4e75acfbf824350e90b5d5738") (:keywords "convenience") (:authors ("Tim Visher" . "tim.visher@gmail.com")) (:maintainer "Tim Visher" . "tim.visher@gmail.com"))]) (seoul256-theme . [(20180505 757) ((emacs (24 3))) "Low-contrast color scheme based on Seoul Colors." single ((:commit . "d28a9de73a5ffb1a1c9492db75a5c1efe5e9815f") (:keywords "theme") (:authors ("Anand Iyer" . "anand.ucb@gmail.com")) (:maintainer "Anand Iyer" . "anand.ucb@gmail.com") (:url . "http://github.com/anandpiyer/seoul256-emacs"))]) (sentence-navigation . [(20180408 1619) ((ample-regexps (0 1)) (cl-lib (0 5)) (emacs (24 4))) "Commands to navigate one-spaced sentences." single ((:commit . "7c5d2edeaed01196aec25031782e89adeaa089f0") (:keywords "sentence" "evil") (:authors ("Fox Kiester" . "noct@openmailbox.org")) (:maintainer "Fox Kiester" . "noct@openmailbox.org") (:url . "https://github.com/noctuid/emacs-sentence-navigation"))]) (sensitive . [(20170818 1251) ((emacs (24)) (sequences (0 1 0))) "A dead simple way to load sensitive information" single ((:commit . "69dd6125a41d8b55f4b6ba61daa4d1aa1f716fa8") (:keywords "convenience") (:authors ("Tim Visher" . "tim.visher@gmail.com")) (:maintainer "Tim Visher" . "tim.visher@gmail.com"))]) (sendto . [(20160425 1250) ((emacs (24 4))) "send the region content to a function" single ((:commit . "076b81d7a53f75b0a59b0ef3448f35570567054c") (:keywords "convenience" "region") (:authors ("DarkSun" . "lujun9972@gmail.com")) (:maintainer "DarkSun" . "lujun9972@gmail.com") (:url . "https://github.com/lujun9972/sendto.el"))]) (semi . [(20180825 901) ((flim (1 14 9))) "A library to provide MIME features." tar ((:commit . "d445dbdf39bab9aaf00582506357f25f1b78d76d"))]) (selectric-mode . [(20170216 1111) nil "IBM Selectric mode for Emacs" tar ((:commit . "aed70015b29074b52a5d0c49b88b7a501d276dda") (:keywords "multimedia" "convenience" "typewriter" "selectric") (:authors ("Ricardo Bánffy" . "rbanffy@gmail.com")) (:maintainer "Ricardo Banffy" . "rbanffy@gmail.com") (:url . "https://github.com/rbanffy/selectric-mode"))]) (selected . [(20170222 834) nil "Keymap for when region is active" single ((:commit . "03edaeac90bc6000d263f03be3d889b4685e1bf7") (:keywords "convenience") (:authors ("Erik Sjöstrand")) (:maintainer "Erik Sjöstrand") (:url . "http://github.com/Kungsgeten/selected.el"))]) (select-themes . [(20160221 106) nil "Color theme selection with completing-read" single ((:commit . "236f54287519a3ea6dd7b3992d053e4f4ff5d0fe") (:authors ("Jason Milkins" . "jasonm23@gmail.com")) (:maintainer "Jason Milkins" . "jasonm23@gmail.com") (:url . "https://github.com/jasonm23/emacs-select-themes"))]) (sekka . [(20170803 1247) ((cl-lib (0 3)) (concurrent (0 3 1)) (popup (0 5 2))) "A client for Sekka IME server" single ((:commit . "61840b57d9ae32bf8e297b175942590a1319c7e7") (:keywords "ime" "skk" "japanese") (:authors ("Kiyoka Nishiyama" . "kiyoka@sumibi.org")) (:maintainer "Kiyoka Nishiyama" . "kiyoka@sumibi.org") (:url . "https://github.com/kiyoka/sekka"))]) (seethru . [(20150218 1829) ((shadchen (1 4))) "Easily change Emacs' transparency" single ((:commit . "d87e231f99313bea75b1e69e48c0f32968c82060") (:keywords "lisp" "tools" "alpha" "transparency") (:authors ("Benaiah Mischenko" . "benaiah@mischenko.com")) (:maintainer "Benaiah Mischenko" . "benaiah@mischenko.com") (:url . "http://github.com/benaiah/seethru"))]) (seeing-is-believing . [(20170214 1320) nil "minor mode for running the seeing-is-believing ruby gem" single ((:commit . "fbbe246c0fda87bb26227bb826eebadb418a220f") (:authors ("John Cinnamond")) (:maintainer "John Cinnamond"))]) (see-mode . [(20180511 41) ((emacs (24 4)) (language-detection (0 1 0))) "Edit string  in a separate buffer" single ((:commit . "b6e72ea90105b03816c334be9e43bb41dcc79abf") (:keywords "convenience") (:authors ("Marcelo Muñoz" . "ma.munoz.araya@gmail.com")) (:maintainer "Marcelo Muñoz" . "ma.munoz.araya@gmail.com") (:url . "https://github.com/marcelino-m/see-mode"))]) (secretaria . [(20180104 1520) ((emacs (24 4)) (alert (1 2)) (s (1 12)) (f (0 19 0))) "A personal assistant based on org-mode" tar ((:commit . "e9d59d264ba30f8055a1ee1576fe9296d5b41055") (:keywords "org" "convenience") (:authors ("Jorge Araya Navarro" . "jorge@esavara.cr")) (:maintainer "Jorge Araya Navarro" . "jorge@esavara.cr") (:url . "https://bitbucket.org/shackra/secretaria.el"))]) (seclusion-mode . [(20121118 2353) nil "Edit in seclusion. A Dark Room mode." single ((:commit . "9634e76c52bfb7200ff0f9f01404f743429e9ef0") (:authors (nil . "Daniel Leslie dan@ironoxide.ca")) (:maintainer nil . "Daniel Leslie dan@ironoxide.ca") (:url . "http://github.com/dleslie/seclusion-mode"))]) (searchq . [(20150829 1211) ((emacs (24 3))) "Framework of queued search tasks using GREP, ACK, AG and more." tar ((:commit . "dd510d55ad66a82c6ef022cfe7c4a73ad5365f82") (:authors ("boyw165")) (:maintainer "boyw165"))]) (search-web . [(20150312 1103) nil "Post web search queries using `browse-url'." single ((:commit . "c4ae86ac1acfc572b81f3d78764bd9a54034c331") (:authors ("Tomoya Otake" . "tomoya.ton@gmail.com")) (:maintainer "Tomoya Otake" . "tomoya.ton@gmail.com"))]) (sdlang-mode . [(20161201 711) ((emacs (24 3))) "Major mode for Simple Declarative Language files." single ((:commit . "d42a6eedefeb44919fbacf58d302b6df18f05bbc") (:keywords "languages") (:authors ("Vladimir Panteleev")) (:maintainer "Vladimir Panteleev") (:url . "https://github.com/CyberShadow/sdlang-mode"))]) (sdcv . [(20180211 1633) ((emacs (24 3)) (popup (0 5 3)) (showtip (0 1)) (pos-tip (0 4 6)) (cl-lib (0 3))) "Interface for sdcv (StartDict console version)." single ((:commit . "7cb1f8ec0fa4bb25669534d62bff58df38a992a8") (:keywords "startdict" "sdcv") (:authors ("Andy Stewart" . "lazycat.manatee@gmail.com")) (:maintainer "Andy Stewart" . "lazycat.manatee@gmail.com") (:url . "http://www.emacswiki.org/emacs/download/sdcv.el"))]) (scss-mode . [(20180123 1708) nil "Major mode for editing SCSS files" single ((:commit . "cf58dbec5394280503eb5502938f3b5445d1b53d") (:keywords "scss" "css" "mode") (:authors ("Anton Johansson" . "anton.johansson@gmail.com")) (:maintainer "Anton Johansson" . "anton.johansson@gmail.com") (:url . "https://github.com/antonj/scss-mode"))]) (scrooge . [(20180630 1022) ((emacs (24)) (cl-lib (0 5)) (dash (2 13 0)) (thrift (0 9 3))) "Major mode for Twitter Scrooge files" single ((:commit . "0a8c58e9e6708abe4ef7e415bc1e0472318bb1b0") (:keywords "scrooge" "thrift") (:authors ("Daniel McClanahan" . "danieldmcclanahan@gmail.com")) (:maintainer "Daniel McClanahan" . "danieldmcclanahan@gmail.com"))]) (scribble-mode . [(20160124 2328) ((emacs (24))) "Major mode for editing Scribble documents" single ((:commit . "34e9e5edb921813b6483e0fefa848efb6ee4b314") (:keywords "convenience") (:authors ("Mario Rodas" . "marsam@users.noreply.github.com")) (:maintainer "Mario Rodas" . "marsam@users.noreply.github.com") (:url . "https://github.com/emacs-pe/scribble-mode"))]) (scratches . [(20151006 416) ((dash (2 11 0)) (f (0 17 0))) "Multiple scratches in any language" single ((:commit . "9441afe6396ca38f08029123fab5d87429cbf315") (:keywords "scratch") (:authors ("Zhang Kai Yu" . "yeannylam@gmail.com")) (:maintainer "Zhang Kai Yu" . "yeannylam@gmail.com"))]) (scratch-pop . [(20170510 1458) ((popwin (0 7 0 -3))) "Generate, popup (& optionally backup) scratch buffer(s)." single ((:commit . "7f4172c792b10bd38898dd8963cf0ade91921869") (:authors ("zk_phi")) (:maintainer "zk_phi") (:url . "http://hins11.yu-yake.com/"))]) (scratch-palette . [(20150225 842) ((popwin (0 7 0 -3))) "make scratch buffer for each files" single ((:commit . "f6803b448079f4a81cc699cec7442ef543cd5818") (:authors ("zk_phi")) (:maintainer "zk_phi") (:url . "http://hins11.yu-yake.com/"))]) (scratch-message . [(20170107 1336) nil "Changing message in your scratch buffer" single ((:commit . "3ecc7f5e3b8a597ebd1492fd426d3720a7f34302") (:keywords "util" "scratch") (:authors ("Sylvain Rousseau <thisirs at gmail dot com>")) (:maintainer "Sylvain Rousseau <thisirs at gmail dot com>") (:url . "https://github.com/thisirs/scratch-message.git"))]) (scratch-log . [(20141115 743) nil "Utility for *scratch* buffer." single ((:commit . "1168f7f16d36ca0f4ddf2bb98881f8db62cc5dc0") (:authors ("kmori" . "morihenotegami@gmail.com")) (:maintainer "kmori" . "morihenotegami@gmail.com"))]) (scratch-ext . [(20140104 516) nil "Extensions for *scratch*" single ((:commit . "388c53cddd0466b451264894667ed64a6947ad67") (:authors ("Kouhei Yanagita" . "yanagi@shakenbu.org")) (:maintainer "Kouhei Yanagita" . "yanagi@shakenbu.org") (:url . "https://github.com/kyanagi/scratch-ext-el"))]) (scratch . [(20170614 2101) nil "Mode-specific scratch buffers" single ((:commit . "2cdf2b841ce7a0987093f65b0cc431947549f897") (:keywords "convenience" "tools" "files") (:authors ("Ian Eure" . "ian.eure@gmail.com")) (:maintainer "Ian Eure" . "ian.eure@gmail.com"))]) (scpaste . [(20180822 1551) ((htmlize (1 39))) "Paste to the web via scp." single ((:commit . "af23b09ece83a9382c3c3c1a2f09e78b8641f0a5") (:keywords "convenience" "hypermedia") (:authors ("Phil Hagelberg")) (:maintainer "Phil Hagelberg") (:url . "https://github.com/technomancy/scpaste"))]) (scp . [(20171204 251) ((emacs (25 1)) (cl-lib (0 5))) "Use the SCP command to transfer files with the remote server" single ((:commit . "447305db246d9c9240678dd9c734ed920300463a") (:keywords "convenience" "scp") (:authors ("zg" . "13853850881@163.com")) (:maintainer "zg" . "13853850881@163.com") (:url . "https://github.com/tszg/emacs-scp"))]) (sclang-snippets . [(20130513 751) ((yasnippet (0 8 0))) "Snippets for the SuperCollider Emacs mode" tar ((:commit . "c840a416b96f83bdd70491e3d1fbe2f1ae8b3f58") (:keywords "snippets") (:authors ("ptrv" . "mail@petervasil.net")) (:maintainer "ptrv" . "mail@petervasil.net"))]) (sclang-extensions . [(20160509 338) ((auto-complete (1 4 0)) (s (1 3 1)) (dash (1 2 0)) (emacs (24 1))) "Extensions for the SuperCollider Emacs mode." tar ((:commit . "e9cc79732f16fdb582129303110c163dcc0d6da0") (:keywords "sclang" "supercollider" "languages" "tools") (:authors ("Chris Barrett" . "chris.d.barrett@me.com")) (:maintainer "Chris Barrett" . "chris.d.barrett@me.com"))]) (scion . [(20130315 1255) nil "Haskell Minor Mode for Interacting with the Scion Library" single ((:commit . "99b4589175665687181a932cd836850205625f71") (:url . "https://code.google.com/p/scion-lib/"))]) (schrute . [(20170521 1840) ((emacs (24 3))) "Help you remember there is a better way to do something." single ((:commit . "59faa6c4232ae183cea93237301acad8c0763997") (:keywords "convenience") (:authors ("Jorge Araya Navarro" . "elcorreo@deshackra.com")) (:maintainer "Jorge Araya Navarro" . "elcorreo@deshackra.com") (:url . "https://bitbucket.org/shackra/dwight-k.-schrute"))]) (scheme-here . [(20141028 718) nil "cmuscheme extension for multiple inferior processes" single ((:commit . "430ba017cc530865218de23a8f7985095a58343f") (:keywords "scheme") (:authors ("Dimitris Vyzovitis" . "vyzo@media.mit.edu")) (:maintainer "Wei Zhao" . "kaihaosw@gmail.com") (:url . "https://github.com/kaihaosw/scheme-here"))]) (scheme-complete . [(20170824 1413) nil "Smart auto completion for Scheme in Emacs" single ((:commit . "4c77038048cbcf34b5907f0439c93058a71a2d2b") (:authors ("Alex Shinn")) (:maintainer "Alex Shinn"))]) (scf-mode . [(20151122 248) nil "shorten file-names in compilation type buffers" single ((:commit . "dbfcdcd89034f208d65e181af58e0d73ad09f8b2") (:keywords "compilation") (:authors ("Le Wang")) (:maintainer "Le Wang") (:url . "https://github.com/lewang/scf-mode"))]) (scala-mode . [(20170802 1132) nil "Major mode for editing Scala" tar ((:commit . "56cba2903cf6e12c715dbb5c99b34c97b2679379") (:keywords "languages") (:url . "https://github.com/ensime/emacs-scala-mode"))]) (scad-preview . [(20160206 1336) ((scad-mode (91 0))) "Preview SCAD models in real-time within Emacs" single ((:commit . "fee011589671cc8f1296cb6aa81553e5bb699819") (:authors ("zk_phi")) (:maintainer "zk_phi") (:url . "http://hins11.yu-yake.com/"))]) (scad-mode . [(20180109 209) nil "A major mode for editing OpenSCAD code" single ((:commit . "e73b59b1054b38d8e1ebc089e5b000c047d37b43") (:keywords "languages") (:authors ("Len Trigg, Łukasz Stelmach")) (:maintainer "Len Trigg" . "lenbok@gmail.com") (:url . "https://raw.github.com/openscad/openscad/master/contrib/scad-mode.el"))]) (sbt-mode . [(20180511 1622) ((emacs (24 4))) "Interactive support for sbt projects" tar ((:commit . "e658af140547cbef495c33535c7f694a501d318c") (:keywords "languages") (:url . "https://github.com/ensime/emacs-sbt-mode"))]) (sayid . [(20180901 903) ((cider (0 14 0))) "sayid nREPL middleware client" single ((:commit . "a6d319ff55dc2f06d873d43f3924339d1dffd4c5") (:authors ("Bill Piel" . "bill@billpiel.com")) (:maintainer "Bill Piel" . "bill@billpiel.com") (:url . "https://github.com/clojure-emacs/sayid"))]) (say-what-im-doing . [(20160706 1931) nil "dictate what you're doing with text to speech" single ((:commit . "5b2ce6783b02805bcac1107a149bfba3852cd9d5") (:keywords "text to speech" "dumb" "funny") (:authors ("Benaiah Mischenko")) (:maintainer "Benaiah Mischenko") (:url . "http://github.com/benaiah/say-what-im-doing"))]) (savekill . [(20140418 229) nil "Save kill ring to disk" single ((:commit . "67fc94e3d8fe8ce3ca16f90518f6a46479b63e34") (:keywords "tools") (:authors ("rubikitch" . "rubikitch@ruby-lang.org")) (:maintainer "rubikitch" . "rubikitch@ruby-lang.org") (:url . "http://www.emacswiki.org/cgi-bin/wiki/download/savekill.el"))]) (save-visited-files . [(20170301 650) nil "save opened files across sessions" single ((:commit . "33e8d223f622001f5792c52d8b36661e46b5834c") (:authors ("Nathaniel Flath" . "nflath@gmail.com")) (:maintainer "Nathaniel Flath" . "nflath@gmail.com") (:url . "http://github.com/nflath/save-visited-files"))]) (save-load-path . [(20140206 1214) nil "save load-path and reuse it to test" single ((:commit . "6cb763a37e2b8af505bff2bcd11fd49c9ea04d66") (:keywords "lisp") (:authors ("rubikitch" . "rubikitch@ruby-lang.org")) (:maintainer "rubikitch" . "rubikitch@ruby-lang.org") (:url . "http://www.emacswiki.org/cgi-bin/wiki/download/save-load-path.el"))]) (sauron . [(20171105 1047) nil "Track (erc/org/dbus/...) events and react to them." tar ((:commit . "50f09bfc6f5bf79e72a1223e345ee720b507e56a"))]) (sass-mode . [(20161007 626) ((haml-mode (3 0 15)) (cl-lib (0 5))) "Major mode for editing Sass files" single ((:commit . "37105f46f6ea3592039f2ea7d0463ae7f042616e") (:keywords "markup" "language" "css") (:authors ("Natalie Weizenbaum")) (:maintainer "Natalie Weizenbaum") (:url . "http://github.com/nex3/haml/tree/master"))]) (sane-term . [(20160620 1347) ((emacs (24 1))) "Multi Term is crazy. This is not." single ((:commit . "ef6fd08078f49f2bb3be60855d2d002bb6a5e0d2") (:authors ("Adam Patterson" . "adam@adamrt.com")) (:maintainer "Adam Patterson" . "adam@adamrt.com") (:url . "http://github.com/adamrt/sane-term"))]) (salt-mode . [(20180119 154) ((emacs (24 4)) (yaml-mode (0 0 12)) (mmm-mode (0 5 4)) (mmm-jinja2 (0 1))) "Major mode for Salt States" single ((:commit . "e46c28ef77663391519646c79641c9d177f70d35") (:keywords "languages") (:authors ("Ben Hayden" . "hayden767@gmail.com")) (:maintainer "Glynn Forrest" . "me@glynnforrest.com") (:url . "https://github.com/glynnforrest/salt-mode"))]) (salesforce-utils . [(20160814 154) ((cl-lib (0 5))) "simple utilities for Salesforce" single ((:commit . "73328baf0fb94ac0d0de645a8f6d42e5ae27f773") (:authors ("Sean McAfee")) (:maintainer "Sean McAfee") (:url . "https://github.com/grimnebulin/emacs-salesforce"))]) (sailfish-scratchbox . [(20171202 1332) nil "Sailfish OS scratchbox inside the emacs." single ((:commit . "bb5ed0f0b0cd72f2eb1af065b7587ec81866b089") (:keywords "sb2" "mb2" "building" "scratchbox" "sailfish") (:authors ("V. V. Polevoy" . "fx@thefx.co")) (:maintainer "V. V. Polevoy" . "fx@thefx.co") (:url . "https://github.com/vityafx/sailfish-scratchbox.el"))]) (sage-shell-mode . [(20180215 835) ((cl-lib (0 6 1)) (emacs (24 4)) (let-alist (1 0 5)) (deferred (0 5 1))) "A front-end for Sage Math" tar ((:commit . "9f07ff835e8d19afe571dbe414afb690c7b1cb5c") (:keywords "sage" "math") (:authors ("Sho Takemori" . "stakemorii@gmail.com")) (:maintainer "Sho Takemori" . "stakemorii@gmail.com") (:url . "https://github.com/sagemath/sage-shell-mode"))]) (sackspace . [(20130719 956) nil "A better backspace" single ((:commit . "fd0480eaaf6d3d11fd30ac5feb2da2f4f7572708") (:keywords "delete" "convenience") (:authors ("Michael Markert" . "markert.michael@googlemail.com")) (:maintainer "Michael Markert" . "markert.michael@googlemail.com") (:url . "http://github.com/cofi/sackspace.el"))]) (s3ed . [(20180204 1349) ((emacs (24 4)) (seq (0)) (dash (0))) "Tramp-like access to s3" tar ((:commit . "13503cb057bed29cb00a14dffe4472b5cb7748ad") (:keywords "s3" "tools") (:authors ("Matt Usifer" . "mattusifer@gmail.com")) (:maintainer "Matt Usifer" . "mattusifer@gmail.com") (:url . "https://github.com/mattusifer/s3ed"))]) (s12cpuv2-mode . [(20171013 2051) ((emacs (24 3))) "Major-mode for S12CPUV2 assembly" single ((:commit . "b17d4cf848dec1e20e66458e5c7ff77a2c051a8c") (:keywords "s12cpuv2" "assembly" "languages") (:authors ("Adam Niederer" . "adam.niederer@gmail.com")) (:maintainer "Adam Niederer" . "adam.niederer@gmail.com") (:url . "https://github.com/AdamNiederer/s12cpuv2-mode"))]) (s-buffer . [(20130605 2124) ((s (1 6 0)) (noflet (0 0 3))) "s operations for buffers" single ((:commit . "f95d234282377f00a2c3a9846681080cb95bb1df") (:keywords "lisp") (:authors ("Nic Ferrier" . "nferrier@ferrier.me.uk")) (:maintainer "Nic Ferrier" . "nferrier@ferrier.me.uk") (:url . "http://github.com/nicferrier/emacs-s-buffer"))]) (s . [(20180406 808) nil "The long lost Emacs string manipulation library." single ((:commit . "03410e6a7a2b11e47e1fea3b7d9899c7df26435e") (:keywords "strings") (:authors ("Magnar Sveen" . "magnars@gmail.com")) (:maintainer "Magnar Sveen" . "magnars@gmail.com"))]) (ryo-modal . [(20180331 818) ((emacs (24 4))) "Roll your own modal mode" single ((:commit . "42f874467dfdce59b511f883496ce2624b133dd7") (:keywords "convenience" "modal" "keys") (:authors ("Erik Sjöstrand" . "sjostrand.erik@gmail.com")) (:maintainer "Erik Sjöstrand" . "sjostrand.erik@gmail.com") (:url . "http://github.com/Kungsgeten/ryo-modal"))]) (rvm . [(20150402 1442) nil "Emacs integration for rvm" single ((:commit . "134497bc460990c71ab8fa75431156e62c17da2d") (:keywords "ruby" "rvm") (:authors ("Yves Senn" . "yves.senn@gmx.ch")) (:maintainer "Yves Senn" . "yves.senn@gmx.ch") (:url . "http://www.emacswiki.org/emacs/RvmEl"))]) (rustic . [(20180901 1933) ((emacs (26 1)) (xterm-color (1 6)) (dash (2 13 0)) (s (1 10 0)) (f (0 18 2)) (projectile (0 14 0)) (markdown-mode (2 3)) (spinner (1 7 3)) (magit (2 2 2))) "Rust development environment" tar ((:commit . "e0619d69a879d5548806667a5a864299cb0b9ff3") (:keywords "languages") (:authors ("Mozilla")) (:maintainer "Mozilla"))]) (rust-playground . [(20180807 1158) ((emacs (24 3))) "Local Rust playground for short code snippets." single ((:commit . "092c8b11d62dea23953a004744833092bac85fe1") (:keywords "tools" "rust") (:authors ("Alexander I.Grafov" . "grafov@gmail.com")) (:maintainer "Alexander I.Grafov" . "grafov@gmail.com") (:url . "https://github.com/grafov/rust-playground"))]) (rust-mode . [(20180626 2212) ((emacs (24 0))) "A major emacs mode for editing Rust source code" single ((:commit . "106aeab800fb3404baf231845d3e3549ec235afa") (:keywords "languages") (:authors ("Mozilla")) (:maintainer "Mozilla") (:url . "https://github.com/rust-lang/rust-mode"))]) (russian-holidays . [(20170109 2140) nil "Russian holidays for the calendar" single ((:commit . "b285a30f29d85c48e3ea4eb93972d34a090c167b") (:authors ("Alexander I.Grafov" . "siberian@laika.name")) (:maintainer "Alexander I.Grafov" . "siberian@laika.name") (:url . "https://github.com/grafov/russian-holidays"))]) (runtests . [(20150807 831) nil "Run unit tests from Emacs" single ((:commit . "ed90249f24cc48290018df48b9b9b7172440be3e") (:keywords "test") (:authors ("Sune Simonsen" . "sune@we-knowhow.dk")) (:maintainer "Sune Simonsen" . "sune@we-knowhow.dk") (:url . "https://github.com/sunesimonsen/emacs-runtests"))]) (runner . [(20160524 743) nil "Improved \"open with\" suggestions for dired" single ((:commit . "a211d57ddc600410d07a8b534920ba905b093d87") (:keywords "shell command" "dired" "file extension" "open with") (:authors ("Thamer Mahmoud" . "thamer.mahmoud@gmail.com")) (:maintainer "Thamer Mahmoud" . "thamer.mahmoud@gmail.com") (:url . "https://github.com/thamer/runner"))]) (run-stuff . [(20180209 748) ((emacs (24 4))) "context based command execution" single ((:commit . "ed42a7bc9a197ccf1ca87f9937bf98f0a9ed3f92") (:keywords "files" "lisp" "files" "convenience" "hypermedia") (:authors ("Campbell Barton" . "ideasman42@gmail.com")) (:maintainer "Campbell Barton" . "ideasman42@gmail.com") (:url . "https://github.com/ideasman42/emacs-run-stuff"))]) (rum-mode . [(20180127 22) ((emacs (24))) "Major mode for Rum programming language" single ((:commit . "893b1a26244ef6ea82833a9afbc13cb82c0cfb53") (:keywords "rum" "languages" "lisp") (:url . "https://github.com/rumlang/rum-mode"))]) (rufo . [(20170718 1416) ((emacs (24 3))) "use rufo to automatically format ruby files" single ((:commit . "85a6d80fb05fef396a8029b8f944c92a53faf8fe") (:authors ("Daniel Ma" . "danielhgma@gmail.com")) (:maintainer "Daniel Ma" . "danielhgma@gmail.com") (:url . "https://github.com/danielma/rufo.el"))]) (ruby-tools . [(20151209 1615) nil "Collection of handy functions for ruby-mode." tar ((:commit . "6b97066b58a4f82eb2ecea6434a0a7e981aa4c18"))]) (ruby-test-mode . [(20171016 1631) ((ruby-mode (1 0)) (pcre2el (1 8))) "Minor mode for Behaviour and Test Driven" single ((:commit . "87f6d770f8d2326c8d36099aeee5d577f3e2af69") (:keywords "ruby" "unit" "test" "rspec") (:authors ("Roman Scherer" . "roman.scherer@gmx.de") ("Caspar Florian Ebeling" . "florian.ebeling@gmail.com")) (:maintainer "Roman Scherer" . "roman.scherer@burningswell.com"))]) (ruby-refactor . [(20160214 1650) ((ruby-mode (1 2))) "A minor mode which presents various Ruby refactoring helpers." single ((:commit . "e6b7125878a08518bffec6942df0c606f748e9ee") (:keywords "refactor" "ruby") (:url . "https://github.com/ajvargo/ruby-refactor"))]) (ruby-interpolation . [(20131112 1652) nil "Ruby string interpolation helpers" single ((:commit . "1978e337601222cedf00e117bf4b5cac15d1f203") (:authors ("Arthur Leonard Andersen" . "leoc.git@gmail.com")) (:maintainer "Arthur Leonard Andersen" . "leoc.git@gmail.com") (:url . "http://github.com/leoc/ruby-interpolation.el"))]) (ruby-hash-syntax . [(20180324 209) nil "Toggle ruby hash syntax between classic and 1.9 styles" single ((:commit . "89fc364a837d7a78ecce34380f09c073a83e30e0") (:keywords "languages") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:url . "https://github.com/purcell/ruby-hash-syntax"))]) (ruby-factory . [(20160102 721) ((inflections (1 1))) "Minor mode for Ruby test object generation libraries" tar ((:commit . "2bb7ccc2fccb5257376a989aa395bc7b9eb1d55d") (:keywords "ruby" "rails" "convenience") (:authors ("Skye Shaw" . "skye.shaw@gmail.com")) (:maintainer "Skye Shaw" . "skye.shaw@gmail.com") (:url . "http://github.com/sshaw/ruby-factory-mode"))]) (ruby-extra-highlight . [(20171106 1933) nil "Highlight Ruby parameters." single ((:commit . "83942d18eae361998d24c1c523b308eea821f048") (:keywords "languages" "faces") (:authors ("Anders Lindgren")) (:maintainer "Anders Lindgren") (:url . "https://github.com/Lindydancer/ruby-extra-highlight"))]) (ruby-end . [(20141215 1223) nil "Automatic insertion of end blocks for Ruby" single ((:commit . "a136f75abb6d5577ce40d61dfeb778c2e9bb09c0") (:keywords "speed" "convenience" "ruby") (:authors ("Johan Andersson" . "johan.rejeep@gmail.com")) (:maintainer "Johan Andersson" . "johan.rejeep@gmail.com") (:url . "http://github.com/rejeep/ruby-end"))]) (ruby-electric . [(20170810 1130) nil "Minor mode for electrically editing ruby code" single ((:commit . "3553448a780a1ea5c3b0e9becd820d4762876593") (:keywords "languages" "ruby") (:maintainer "Akinori MUSHA" . "knu@iDaemons.org") (:url . "https://github.com/knu/ruby-electric.el"))]) (ruby-compilation . [(20150709 640) ((inf-ruby (2 2 1))) "run a ruby process in a compilation buffer" single ((:commit . "134438af8fbdfa9c8077267c768d273a9792b484") (:keywords "test" "convenience") (:authors ("Eric Schulte")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:url . "https://github.com/eschulte/rinari"))]) (ruby-additional . [(20180317 237) ((emacs (24 3)) (ruby-mode (1 2))) "ruby-mode extensions yet to be merged into Emacs" tar ((:commit . "55f2303591948c4b863ec2370387c8c70367270e") (:keywords "ruby" "languages") (:url . "https://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/misc/"))]) (rubocopfmt . [(20180519 1448) ((cl-lib (0 5))) "Minor-mode to format Ruby code with RuboCop on save" single ((:commit . "34c69c9c923d0da223f7569a6ecc842095adcf85") (:keywords "convenience" "wp" "edit" "ruby" "rubocop") (:authors ("Jim Myhrberg")) (:maintainer "Jim Myhrberg") (:url . "https://github.com/jimeh/rubocopfmt.el"))]) (rubocop . [(20170312 611) ((emacs (24))) "An Emacs interface for RuboCop" single ((:commit . "0ab1329a8634762bec5bdf5f415c05b32f990248") (:keywords "project" "convenience") (:authors ("Bozhidar Batsov")) (:maintainer "Bozhidar Batsov") (:url . "https://github.com/bbatsov/rubocop-emacs"))]) (rubik . [(20180222 2014) ((cl-lib (1 0)) (emacs (25 3))) "Rubik's Cube" single ((:commit . "c8dab1726463dbc9042a0b00186e4a8df02eb868") (:keywords "games") (:authors ("Ivan 'Kurvivor' Truskov" . "trus19@gmail.com")) (:maintainer "Ivan 'Kurvivor' Truskov" . "trus19@gmail.com") (:url . "https://github.com/Kurvivor19/rubik-mode"))]) (rtm . [(20180329 1508) ((cl-lib (1 0))) "An elisp implementation of the Remember The Milk API" single ((:commit . "3e3d09387cb84801343ecca8fb02e82f213e7bbe") (:keywords "remember" "the" "milk" "productivity" "todo") (:authors ("Friedrich Delgado Friedrichs" . "frie...@nomaden.org")) (:maintainer "Friedrich Delgado Friedrichs" . "frie...@nomaden.org") (:url . "https://github.com/pmiddend/emacs-rtm"))]) (rtags . [(20180829 449) nil "A front-end for rtags" single ((:commit . "fc63be8f48bed6703b37ccb1057d75d7ce5200ca") (:authors ("Jan Erik Hanssen" . "jhanssen@gmail.com") ("Anders Bakken" . "agbakken@gmail.com")) (:maintainer "Jan Erik Hanssen" . "jhanssen@gmail.com") (:url . "http://rtags.net"))]) (rspec-mode . [(20180614 1148) ((ruby-mode (1 0)) (cl-lib (0 4))) "Enhance ruby-mode for RSpec" tar ((:commit . "dda1ece81bd2802c4097e5c963fac33a444659cb") (:keywords "rspec" "ruby") (:authors ("Peter Williams, et al.")) (:maintainer "Peter Williams, et al.") (:url . "http://github.com/pezra/rspec-mode"))]) (rsense . [(20100511 405) nil "RSense client for Emacs" single ((:commit . "8b5ee58318747ca1dde84ee41d48c4f50175cf35") (:keywords "convenience") (:authors ("Tomohiro Matsuyama" . "tomo@cx4a.org")) (:maintainer "Tomohiro Matsuyama" . "tomo@cx4a.org"))]) (rpn-calc . [(20170523 142) ((popup (0 4))) "quick RPN calculator for hackers" single ((:commit . "66fcb64dbfddfc23823356b6213215bd7ab5efc6") (:authors ("zk_phi")) (:maintainer "zk_phi") (:url . "https://github.com/zk-phi/rpn-calc"))]) (rpm-spec-mode . [(20160710 1136) nil "RPM spec file editing commands for Emacs/XEmacs" single ((:commit . "c1c38050c48ea330c7cea632b8785d66daeefb2b") (:keywords "unix" "languages") (:authors ("Stig Bjørlykke," . "stig@bjorlykke.org")) (:maintainer "Stig Bjørlykke," . "stig@bjorlykke.org"))]) (roy-mode . [(20121208 1158) nil "Roy major mode" single ((:commit . "0416f561edbc6b4a29fced8be84d2527a9613d65") (:keywords "extensions") (:authors ("Georgii Leontiev")) (:maintainer "Georgii Leontiev") (:url . "https://github.com/folone/roy-mode"))]) (rotate . [(20160909 836) nil "Rotate the layout of emacs" single ((:commit . "091b5ac4fc310773253efb317e3dbe8e46959ba6") (:keywords "window" "layout") (:authors ("daichi.hirata <hirata.daichi at gmail.com>")) (:maintainer "daichi.hirata <hirata.daichi at gmail.com>") (:url . "https://github.com/daichirata/emacs-rotate"))]) (rope-read-mode . [(20171003 1419) nil "Rearrange lines to read text smoothly" single ((:commit . "77b183a6f5450138388509f54a6a2ce442766e50") (:keywords "reading" "convenience" "chill") (:authors ("Marco Wahl" . "marcowahlsoft@gmail.com")) (:maintainer "Marco Wahl" . "marcowahlsoft@gmail.com") (:url . "https://github.com/marcowahl/rope-read-mode"))]) (roguel-ike . [(20160120 302) ((popup (0 5 0))) "A coffee-break roguelike" tar ((:commit . "706dcb0687e8016d7d776f9d9e5ace9fdbbca43c"))]) (robots-txt-mode . [(20170908 1342) nil "Major mode for editing robots.txt" single ((:commit . "4a77674ab2963b829d3b751741c4ce1169e87f6b") (:keywords "languages" "comm" "web") (:authors ("USAMI Kenta" . "tadsan@zonu.me")) (:maintainer "USAMI Kenta" . "tadsan@zonu.me") (:url . "https://github.com/emacs-php/robots-txt-mode"))]) (robe . [(20171116 2049) ((inf-ruby (2 5 1)) (emacs (24 4))) "Code navigation, documentation lookup and completion for Ruby" tar ((:commit . "7829f4fdda41eee0add8868646ab86e6b17de4b4") (:keywords "ruby" "convenience" "rails") (:authors ("Dmitry Gutov")) (:maintainer "Dmitry Gutov") (:url . "https://github.com/dgutov/robe"))]) (rjsx-mode . [(20180823 1645) ((emacs (24 4)) (js2-mode (20170504))) "Real support for JSX" single ((:commit . "c463a162a2557668f624c32dd5c3b58512e80b1a") (:keywords "languages") (:authors ("Felipe Ochoa" . "felipe@fov.space")) (:maintainer "Felipe Ochoa" . "felipe@fov.space") (:url . "https://github.com/felipeochoa/rjsx-mode/"))]) (riscv-mode . [(20170804 1521) ((emacs (24 4))) "Major-mode for RISC V assembly" single ((:commit . "99febf97d1fa9441e8dada94fe30c2aa439c9749") (:keywords "riscv" "assembly") (:authors ("Adam Niederer <https://github.com/AdamNiederer>")) (:maintainer "Adam Niederer") (:url . "https://github.com/AdamNiederer/riscv-mode"))]) (ripgrep . [(20180323 1620) nil "Front-end for ripgrep, a command line search tool" single ((:commit . "a1f8f030bf5daea92dd13b953720a6c13dd3557c") (:keywords "ripgrep" "ack" "pt" "ag" "sift" "grep" "search") (:authors ("Nicolas Lamirault" . "nicolas.lamirault@gmail.com")) (:maintainer "Nicolas Lamirault" . "nicolas.lamirault@gmail.com") (:url . "https://github.com/nlamirault/ripgrep.el"))]) (rings . [(20160531 2027) nil "Buffer rings. Like tabs, but better." single ((:commit . "3590b222eb80652cbd27866f066bd3571d86edfc") (:keywords "utilities" "productivity") (:authors ("Konrad Scorciapino")) (:maintainer "Konrad Scorciapino") (:url . "http://github.com/konr/rings"))]) (rinari . [(20150709 640) ((ruby-mode (1 0)) (inf-ruby (2 2 5)) (ruby-compilation (0 16)) (jump (2 0))) "Rinari Is Not A Rails IDE" single ((:commit . "134438af8fbdfa9c8077267c768d273a9792b484") (:keywords "ruby" "rails" "project" "convenience" "web") (:authors ("Phil Hagelberg, Eric Schulte, Steve Purcell")) (:maintainer "Phil Hagelberg, Eric Schulte, Steve Purcell") (:url . "https://github.com/eschulte/rinari"))]) (rimero-theme . [(20180901 1348) ((emacs (24))) "Theme with a dark background suitable for UI and terminal usage." single ((:commit . "a2e706c2b34f749019979a133f08a2d94a1104b3") (:keywords "faces" "theme" "dark" "light colors") (:authors ("Yves Zoundi" . "yveszoundi@users.sf.net")) (:maintainer "Yves Zoundi" . "yveszoundi@users.sf.net") (:url . "https://github.com/yveszoundi/emacs-rimero-theme"))]) (rigid-tabs . [(20170903 1559) ((emacs (24 3))) "Fix TAB alignment in diff buffers" single ((:commit . "eba84ceaba2e57e76ad2dfbb7a7154238a25d956") (:keywords "diff" "whitespace" "version control" "magit") (:authors ("Yuri D'Elia" . "wavexx@thregr.org")) (:maintainer "Yuri D'Elia" . "wavexx@thregr.org") (:url . "https://github.com/wavexx/rigid-tabs.el"))]) (rich-minority . [(20170813 1322) ((cl-lib (0 5))) "Clean-up and Beautify the list of minor-modes." single ((:commit . "a50d9b2fd059f6a0e5b22063a5375851a087f61a") (:keywords "mode-line" "faces") (:authors ("Artur Malabarba" . "emacs@endlessparentheses.com")) (:maintainer "Artur Malabarba" . "emacs@endlessparentheses.com") (:url . "https://github.com/Malabarba/rich-minority"))]) (rib-mode . [(20170726 1448) ((emacs (24))) "RenderMan® Interface Bytestream (RIB) Major Mode" single ((:commit . "97470158784c3c212e22e2c20b8471ee65ba59af") (:authors ("Remik Ziemlinski and Daniel Blezek" . "daniel.blezek@gmail.com")) (:maintainer "Remik Ziemlinski and Daniel Blezek" . "daniel.blezek@gmail.com") (:url . "https://github.com/blezek/rib-mode"))]) (rhtml-mode . [(20130422 1311) nil "major mode for editing RHTML files" tar ((:commit . "a6d71b38a3db867ccf82999c99805db1a3a33c33"))]) (rg . [(20180901 1205) ((cl-lib (0 5)) (emacs (24 3)) (s (1 10 0))) "A search tool based on ripgrep." tar ((:commit . "28b2f7d0025a803250806c7d274c6df43b4ccc4b") (:keywords "matching" "tools") (:authors ("David Landell" . "david.landell@sunnyhill.email") ("Roland McGrath" . "roland@gnu.org")) (:maintainer "David Landell" . "david.landell@sunnyhill.email") (:url . "https://github.com/dajva/rg.el"))]) (reykjavik-theme . [(20180823 1544) ((emacs (24))) "Theme with a dark background." single ((:commit . "2cd0043ae6d046f812a95bb26398ea23141beccc") (:authors ("martin haesler")) (:maintainer "martin haesler"))]) (review-mode . [(20180312 1235) nil "major mode for ReVIEW" single ((:commit . "bf38b0ce8be2eef1cf810ac6f3664d2190bb9ef7") (:authors ("Kenshi Muto" . "kmuto@debian.org")) (:maintainer "Kenshi Muto" . "kmuto@debian.org") (:url . "https://github.com/kmuto/review-el"))]) (reverse-theme . [(20141205 145) nil "Reverse theme for Emacs" single ((:commit . "8319d0d5342890a3530ffa4daafdb7c35feda1ca") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-reverse-theme"))]) (reverse-im . [(20180213 1325) ((emacs (24 4))) "Reverse mapping for keyboard layouts other than english." single ((:commit . "16931909115a922b1cf3846b1f60509b6590001f") (:keywords "input" "method") (:url . "https://github.com/a13/reverse-im.el"))]) (reveal-in-osx-finder . [(20150802 1657) nil "Reveal file associated with buffer in OS X Finder" single ((:commit . "5710e5936e47139a610ec9a06899f72e77ddc7bc") (:keywords "os x" "finder") (:authors ("Kazuki YOSHIDA")) (:maintainer "Kazuki YOSHIDA") (:url . "https://github.com/kaz-yos/reveal-in-osx-finder"))]) (restclient-test . [(20180106 2046) ((emacs (24 4)) (restclient (0))) "Run tests with restclient.el" single ((:commit . "4518561bc9661fedacb6fb352e9677207f45c418") (:authors ("Simen Heggestøyl" . "simenheg@gmail.com")) (:maintainer "Simen Heggestøyl" . "simenheg@gmail.com") (:url . "https://github.com/simenheg/restclient-test.el"))]) (restclient-helm . [(20170314 1554) ((restclient (0)) (helm (1 9 4))) "helm interface for restclient.el" single ((:commit . "859d944796ce298b5779d9d256bd8d271d57e221") (:keywords "http" "helm") (:authors ("Pavel Kurnosov" . "pashky@gmail.com")) (:maintainer "Pavel Kurnosov" . "pashky@gmail.com"))]) (restclient . [(20180316 1551) nil "An interactive HTTP client for Emacs" single ((:commit . "859d944796ce298b5779d9d256bd8d271d57e221") (:keywords "http") (:authors ("Pavel Kurnosov" . "pashky@gmail.com")) (:maintainer "Pavel Kurnosov" . "pashky@gmail.com"))]) (restart-emacs . [(20180601 1031) nil "Restart emacs from within emacs" single ((:commit . "9aa90d3df9e08bc420e1c9845ee3ff568e911bd9") (:keywords "convenience") (:authors ("Iqbal Ansari" . "iqbalansari02@yahoo.com")) (:maintainer "Iqbal Ansari" . "iqbalansari02@yahoo.com") (:url . "https://github.com/iqbalansari/restart-emacs"))]) (resize-window . [(20170705 512) ((emacs (24)) (cl-lib (0 5))) "easily resize windows" single ((:commit . "dcbbd30f4f4435070a66a22c5a169b752ca9f904") (:keywords "window" "resize") (:authors ("Dan Sutton " . "danielsutton01@gmail.com")) (:maintainer "Dan Sutton " . "danielsutton01@gmail.com") (:url . "https://github.com/dpsutton/resize-mode"))]) (requirejs-mode . [(20130215 2104) nil "Improved AMD module management" single ((:commit . "bbb0c09f8eb2d6a33c17319be8137f68bb16bc92") (:keywords "javascript" "amd" "requirejs") (:authors ("Marc-Olivier Ricard" . "marco.ricard@gmail.com")) (:maintainer "Marc-Olivier Ricard" . "marco.ricard@gmail.com"))]) (requirejs . [(20151204 719) ((js2-mode (20150713)) (popup (0 5 3)) (s (1 9 0)) (cl-lib (0 5)) (yasnippet (20151011 1823))) "Requirejs import manipulation and source traversal." tar ((:commit . "4ea2a5fcbc76e4cbb6a7461e6f05f019b75865b1") (:keywords "javascript" "requirejs") (:authors ("Joe Heyming" . "joeheyming@gmail.com")) (:maintainer "Joe Heyming" . "joeheyming@gmail.com") (:url . "https://github.com/joeheyming/requirejs-emacs"))]) (request-deferred . [(20160419 2305) ((deferred (0 3 1)) (request (0 2 0))) "Wrap request.el by deferred" single ((:commit . "a3d080e57eb8be606fbf39d1baff94e1b16e1fb8") (:authors ("Takafumi Arakaki <aka.tkf at gmail.com>")) (:maintainer "Takafumi Arakaki <aka.tkf at gmail.com>"))]) (request . [(20170201 147) ((emacs (24 4))) "Compatible layer for URL request in Emacs" single ((:commit . "a3d080e57eb8be606fbf39d1baff94e1b16e1fb8") (:authors ("Takafumi Arakaki <aka.tkf at gmail.com>")) (:maintainer "Takafumi Arakaki <aka.tkf at gmail.com>"))]) (req-package . [(20180122 500) ((use-package (1 0)) (dash (2 7 0)) (log4e (0 2 0)) (ht (0))) "A use-package wrapper for package runtime dependencies management" tar ((:commit . "0c0ac7451149dac6bfda2adfe959d1df1c273de6") (:keywords "dotemacs" "startup" "speed" "config" "package") (:authors ("Edward Knyshov" . "edvorg@gmail.com")) (:maintainer "Edward Knyshov" . "edvorg@gmail.com") (:url . "https://github.com/edvorg/req-package"))]) (repo . [(20170213 939) ((emacs (24 3))) "Running repo from Emacs" single ((:commit . "d7b87cd515bad8a67d3a892a46a23f5fe81e08de") (:keywords "convenience") (:authors ("Damien Merenne")) (:maintainer "Damien Merenne") (:url . "https://github.com/canatella/repo-el"))]) (replace-with-inflections . [(20180831 635) ((cl-lib (0 5)) (string-inflection (1 0 10)) (inflections (1 1))) "Inflection aware `query-replace'" single ((:commit . "d9201e047856492f282da65459b28aba25998dbb") (:keywords "matching") (:authors ("Akinori MUSHA" . "knu@iDaemons.org")) (:maintainer "Akinori MUSHA" . "knu@iDaemons.org") (:url . "https://github.com/knu/replace-with-inflections.el"))]) (replace-symbol . [(20160518 12) nil "Rename symbols in expressions or buffers" single ((:commit . "baf949e528aee1881f455f9c84e67718bedcb3f6") (:authors ("Brian Mastenbrook" . "brian@mastenbrook.net")) (:maintainer "Brian Mastenbrook" . "brian@mastenbrook.net") (:url . "https://github.com/bmastenbrook/replace-symbol-el"))]) (replace-pairs . [(20160207 1251) ((emacs (24 4))) "Query-replace pairs of things" single ((:commit . "1e49071e2ef46a458a28f77681e313a63db5663c") (:authors ("David Shepherd" . "davidshepherd7@gmail.com")) (:maintainer "David Shepherd" . "davidshepherd7@gmail.com") (:url . "https://github.com/davidshepherd7/replace-pairs"))]) (replace-from-region . [(20170227 2316) nil "Replace commands whose query is from region" single ((:commit . "dc9318b9b2822da7b00ecc34d1dc965c8f96c9bb") (:keywords "replace" "search" "region") (:authors ("rubikitch" . "rubikitch@ruby-lang.org")) (:maintainer "rubikitch" . "rubikitch@ruby-lang.org") (:url . "http://www.emacswiki.org/emacs/download/replace-from-region.el"))]) (repl-toggle . [(20180501 1028) ((fullframe (0 0 5))) "Switch to/from repl buffer for current major-mode" single ((:commit . "484739e20bdc0e879cef647a1f5f89e8ab92c9b6") (:keywords "repl" "buffers" "toggle") (:authors ("Tom Regner" . "tom@goochesa.de")) (:maintainer "Tom Regner" . "tom@goochesa.de"))]) (repeater . [(20180418 1212) ((emacs (24 4))) "Repeat recent repeated commands" single ((:commit . "854b874542b186b2408cbc58ad0591fe8eb70b6c") (:keywords "convenience") (:authors ("Xu Chunyang" . "mail@xuchunyang.me")) (:maintainer "Xu Chunyang" . "mail@xuchunyang.me") (:url . "https://github.com/xuchunyang/repeater"))]) (repeatable-motion . [(20170620 1848) ((emacs (24))) "Make repeatable versions of motions" tar ((:commit . "f29effdc4121c2dc7e3fec9b3a62debce29cda9d") (:keywords "motion" "repeatable") (:authors ("William Hatch" . "willghatch@gmail.com")) (:maintainer "William Hatch" . "willghatch@gmail.com") (:url . "https://github.com/willghatch/emacs-repeatable-motion"))]) (remember-last-theme . [(20170619 2133) ((emacs (24 4))) "Remember the last used theme between sessions." single ((:commit . "0973f1aa6b96355fa376fffe8b45733b6e963c51") (:keywords "convenience" "faces") (:authors ("Anler Hernández Peral" . "inbox+emacs@anler.me")) (:maintainer "Anler Hernández Peral" . "inbox+emacs@anler.me") (:url . "https://github.com/anler/remember-last-theme"))]) (remark-mode . [(20171218 756) ((emacs (25 1)) (markdown-mode (2 0))) "Major mode for the remark slideshow tool" tar ((:commit . "e8a95f25d865d6165a7fdb1cadf5e6f0bb5ee73b") (:keywords "remark" "slideshow" "markdown" "hot reload") (:authors ("@torgeir")) (:maintainer "@torgeir"))]) (relax . [(20131029 2134) ((json (1 2))) "For browsing and interacting with CouchDB" single ((:commit . "6e33892623ab87833082262321dc8e1977209626") (:keywords "database" "http") (:authors ("Phil Hagelberg")) (:maintainer "Phil Hagelberg") (:url . "http://github.com/technomancy/relax.el"))]) (relative-buffers . [(20160221 1923) ((cl-lib (0 5)) (dash (2 6 0)) (s (1 9 0)) (f (0 16 2))) "Emacs buffers naming convention" single ((:commit . "2547475084244d266b507e563c9b4034705cfeca") (:authors ("Artem Malyshev" . "proofit404@gmail.com")) (:maintainer "Artem Malyshev" . "proofit404@gmail.com") (:url . "https://github.com/proofit404/relative-buffers"))]) (related . [(20161003 610) ((cl-lib (0 5))) "Switch back and forth between similarly named buffers." single ((:commit . "0065a2e16eeaa9bface49f7f0815b9cf9719f441") (:keywords "file" "buffer" "switch" "selection" "matching" "convenience") (:authors ("Julien Montmartin")) (:maintainer "Julien Montmartin") (:url . "https://bitbucket.org/lyude/related/raw/master/related.el"))]) (register-channel . [(20150514 359) nil "Jump around fast using registers" single ((:commit . "f62f9a62ebd2537d4a8c8f2e358562c67d2aefc1") (:keywords "convenience") (:authors ("Yang Zhao" . "YangZhao11@users.noreply.github.com")) (:maintainer "Yang Zhao" . "YangZhao11@users.noreply.github.com"))]) (region-state . [(20151128 1038) nil "Show the number of chars/lines or rows/columns in the region" single ((:commit . "07ffb7d9ada2fcd204f3447f078c265d25f36f60") (:keywords "convenience") (:authors ("Chunyang Xu" . "xuchunyang56@gmail.com")) (:maintainer "Chunyang Xu" . "xuchunyang56@gmail.com") (:url . "https://github.com/xuchunyang/region-state.el"))]) (region-convert . [(20161119 259) nil "Convert string in region by Lisp function" single ((:commit . "2f8195fb81b8d27aeb42bdc4055ebce37c09717b") (:keywords "region" "convenience") (:authors ("USAMI Kenta" . "tadsan@zonu.me")) (:maintainer "USAMI Kenta" . "tadsan@zonu.me") (:url . "https://github.com/zonuexe/right-click-context"))]) (region-bindings-mode . [(20140407 2214) nil "Enable custom bindings when mark is active." single ((:commit . "3fa5dbdbd7c000bebff6d9d14a4be326ec24b6fc") (:keywords "convenience") (:authors ("Fabián E. Gallina" . "fabian@anue.biz")) (:maintainer "Fabián E. Gallina" . "fabian@anue.biz") (:url . "https://github.com/fgallina/region-bindings-mode"))]) (regex-tool . [(20170104 1918) nil "A regular expression evaluation tool for programmers" single ((:commit . "0b4a0111143c88ef94bec56624cb2e00c1a054e6") (:keywords "regex" "languages" "programming" "development") (:authors ("John Wiegley" . "johnw@newartisans.com")) (:maintainer "John Wiegley" . "johnw@newartisans.com") (:url . "http://www.newartisans.com/"))]) (regex-dsl . [(20100124 1028) nil "lisp syntax for regexps" single ((:commit . "ac89ab8b7691a165ef3007cb84417125cfc0632e") (:authors ("Aliaksey Kandratsenka" . "alk@tut.by")) (:maintainer "Aliaksey Kandratsenka" . "alk@tut.by"))]) (refine . [(20180315 2228) ((emacs (24 3)) (s (1 11 0)) (dash (2 12 0)) (list-utils (0 4 4)) (loop (1 2))) "interactive value editing" single ((:commit . "0a99439a0b4ed6f79b9a240ea1270140a9e328bc") (:keywords "convenience") (:authors ("Wilfred Hughes" . "me@wilfred.me.uk")) (:maintainer "Wilfred Hughes" . "me@wilfred.me.uk"))]) (redtick . [(20180424 2136) ((emacs (24 4))) "Smallest pomodoro timer (1 char)" tar ((:commit . "94b4cd43ac20c64dcac96edac2c1a3b9fcc59bb9") (:keywords "calendar") (:authors ("F. Febles")) (:maintainer "F. Febles") (:url . "http://github.com/ferfebles/redtick"))]) (redshank . [(20180730 407) ((paredit (21))) "Common Lisp Editing Extensions" tar ((:commit . "d059c5841044aa163664f8bf87c1d981bf0a04fe") (:keywords "languages" "lisp") (:authors ("Michael Weber" . "michaelw@foldr.org")) (:maintainer "Michael Weber" . "michaelw@foldr.org"))]) (redprl . [(20180418 1434) ((emacs (24 3))) "Major mode for editing RedPRL proofs and interacting with RedPRL" single ((:commit . "bd73932409ddc3479c8ded5ac32ae0d93d31874a") (:keywords "languages") (:authors ("Jonathan Sterling" . "jon@jonmsterling.com")) (:maintainer "Jonathan Sterling" . "jon@jonmsterling.com"))]) (redpen-paragraph . [(20160625 1050) ((emacs (24)) (cl-lib (0 5)) (json (1 4))) "RedPen interface." single ((:commit . "770ffb34b04bfa0ea8484fa1506e96c530168e13") (:keywords "document" "proofreading" "help") (:authors ("karronoli")) (:maintainer "karronoli") (:url . "https://github.com/karronoli/redpen-paragraph.el"))]) (redis . [(20150531 1948) ((emacs (24)) (cl-lib (0 5))) "Redis integration" single ((:commit . "2c33f3397bc14e7a8192867b55920492d4eead8c") (:keywords "convenience") (:authors ("Mario Rodas" . "marsam@users.noreply.github.com")) (:maintainer "Mario Rodas" . "marsam@users.noreply.github.com") (:url . "https://github.com/emacs-pe/redis.el"))]) (recursive-narrow . [(20140902 1727) nil "narrow-to-region that operates recursively" single ((:commit . "bc0cab88234ca92640d4b8da0d83e132c1897922") (:authors ("Nathaniel Flath" . "flat0103@gmail.com")) (:maintainer "Nathaniel Flath" . "flat0103@gmail.com") (:url . "http://github.com/nflath/recursive-narrow"))]) (rectangle-utils . [(20160915 408) ((emacs (24)) (cl-lib (0 5))) "Some useful rectangle functions." single ((:commit . "6fe38fdd48ef5305a908b94a043a966ac3f2053a") (:authors ("Thierry Volpiatto" . "thierry.volpiatto@gmail.com")) (:maintainer "Thierry Volpiatto" . "thierry.volpiatto@gmail.com") (:url . "https://github.com/thierryvolpiatto/rectangle-utils"))]) (rect+ . [(20150621 44) nil "Extensions to rect.el" single ((:commit . "299b742faa0bc4448e0d5fe9cb98ab1eb93b8dcc") (:keywords "extensions" "data" "tools") (:authors ("Masahiro Hayashi" . "mhayashi1120@gmail.com")) (:maintainer "Masahiro Hayashi" . "mhayashi1120@gmail.com") (:url . "https://github.com/mhayashi1120/Emacs-rectplus"))]) (recover-buffers . [(20171009 437) nil "revisit all buffers from an auto-save file" tar ((:commit . "81a5cb53099955ebc2a411a44cba5a394ee3f2d1") (:authors ("era eriksson <http://www.iki.fi/era>")) (:maintainer "era eriksson <http://www.iki.fi/era>"))]) (recompile-on-save . [(20151126 1446) ((dash (1 1 0)) (cl-lib (0 5))) "Trigger recompilation on file save." single ((:commit . "92e11446869d878803d4f3dec5d2101380c12bb2") (:keywords "convenience" "files" "processes" "tools") (:authors ("Marian Schubert" . "marian.schubert@gmail.com")) (:maintainer "Marian Schubert" . "marian.schubert@gmail.com") (:url . "https://github.com/maio/recompile-on-save.el"))]) (recentf-remove-sudo-tramp-prefix . [(20180205 556) ((emacs (24 4))) "Normalise recentf history" single ((:commit . "6d23ebc3f52b0a66236c171c45cc77a4d3aba541") (:authors ("ncaq" . "ncaq@ncaq.net")) (:maintainer "ncaq" . "ncaq@ncaq.net") (:url . "https://github.com/ncaq/recentf-remove-sudo-tramp-prefix"))]) (recentf-ext . [(20170926 35) nil "Recentf extensions" single ((:commit . "450de5f8544ed6414e88d4924d7daa5caa55b7fe") (:keywords "convenience" "files") (:authors ("rubikitch" . "rubikitch@ruby-lang.org")) (:maintainer "rubikitch" . "rubikitch@ruby-lang.org") (:url . "http://www.emacswiki.org/cgi-bin/wiki/download/recentf-ext.el"))]) (rebox2 . [(20121113 1300) nil "Handling of comment boxes in various styles." single ((:commit . "00634eca420cc48657b81e40e599ff8548083985") (:authors ("François Pinard") ("Le Wang")) (:maintainer "Le Wang (lewang.emacs!!!gmayo.com remove exclamations, correct host, hint: google mail)") (:url . "https://github.com/lewang/rebox2"))]) (rebecca-theme . [(20180324 821) ((emacs (24))) "Rebecca Purple Theme" single ((:commit . "9ac0c71c2858b76dc5499f62c7c7fb7f9e8f16bc") (:keywords "theme" "dark") (:authors ("vic" . "vborja@apache.org")) (:maintainer "vic" . "vborja@apache.org") (:url . "https://github.com/vic/rebecca-theme"))]) (reazon . [(20180831 2125) ((emacs (26))) "miniKanren for Emacs" tar ((:commit . "7cb8abddb80931ee7ce5ed8bfffd803e348160bf") (:keywords "languages" "extensions" "lisp") (:authors ("Nick Drozd" . "nicholasdrozd@gmail.com")) (:maintainer "Nick Drozd" . "nicholasdrozd@gmail.com") (:url . "https://github.com/nickdrozd/reazon"))]) (reason-mode . [(20180727 1858) ((emacs (24 3))) "A major mode for editing ReasonML" tar ((:commit . "0ab99a03b2e47523e86d1e94ccc085e176b987df") (:keywords "languages" "ocaml") (:authors ("Mozilla")) (:maintainer "Mozilla") (:url . "https://github.com/reasonml-editor/reason-mode"))]) (realgud-rdb2 . [(20160303 843) ((realgud (1 3))) "realgud front-end for interacting with Ruby debugger2" tar ((:commit . "b394bee61e75b7c6a5fa565594aa79b74887f5df") (:authors ("Rocky Bernstein")) (:maintainer "Rocky Bernstein") (:url . "http://github.com/rocky/realgud-ruby-debugger2"))]) (realgud-pry . [(20160805 1445) ((realgud (1 4 3)) (cl-lib (0 5)) (emacs (24))) "realgud front-end to the Ruby pry debugger" tar ((:commit . "9b3834048fcbc16827c55af38f8cfef0cf6533da") (:authors ("Rocky Bernstein")) (:maintainer "Rocky Bernstein") (:url . "http://github.com/rocky/realgud-pry"))]) (realgud-old-debuggers . [(20170316 731) ((realgud (1 4 3)) (cl-lib (0 5)) (emacs (24))) "realgud front-end to older lesser-used debuggers" tar ((:commit . "1e1d573a6ba731afbe68c1309a316457ca3fbb94") (:authors ("Rocky Bernstein")) (:maintainer "Rocky Bernstein") (:url . "http://github.com/rocky/realgud-old-debuggers"))]) (realgud-byebug . [(20180309 323) ((realgud (1 4 3)) (cl-lib (0 5)) (emacs (24))) "realgud front-end to the Ruby byebug debugger" tar ((:commit . "de603d58aa9ef72a2619247a0234fccf6bc2cc9a") (:authors ("Rocky Bernstein")) (:maintainer "Rocky Bernstein") (:url . "http://github.com/rocky/realgud-byebug"))]) (realgud . [(20180711 253) ((load-relative (1 2)) (loc-changes (1 2)) (test-simple (1 2 0)) (cl-lib (0 5)) (emacs (24))) "A modular front-end for interacting with external debuggers" tar ((:commit . "da2a74b50a770a2c1166656a05ba9d132a2a5c73") (:keywords "gdb" "python" "perl" "go" "bash" "nodejs" "zsh" "bashdb" "zshdb" "remake" "make" "trepan" "perldb" "pdb") (:authors ("Rocky Bernstein" . "rocky@gnu.org")) (:maintainer "Rocky Bernstein" . "rocky@gnu.org") (:url . "http://github.com/realgud/realgud/"))]) (real-auto-save . [(20180803 447) nil "Automatically save your all your buffers/files at regular intervals." single ((:commit . "b4f83f1e7e921e4cb762c7f525c209ff385742d8") (:authors ("Chaoji Li <lichaoji AT gmail DOT com>") ("Anand Reddy Pandikunta <anand21nanda AT gmail DOT com>")) (:maintainer "Chaoji Li <lichaoji AT gmail DOT com>"))]) (readline-complete . [(20150708 1437) nil "offers completions in shell mode" single ((:commit . "30c020c37b2741160cc37e656e13c85d826a0ebf") (:authors ("Christopher Monsanto" . "chris@monsan.to")) (:maintainer "Christopher Monsanto" . "chris@monsan.to"))]) (readability . [(20140716 27) ((oauth (1 4)) (ov (1 0)) (emacs (24 3))) "Read articles from Readability in Emacs" single ((:commit . "6c220ab8e0ca63946574ed892add5c8fd14002ce") (:keywords "readability" "oauth") (:authors ("Shingo Fukuyama - http://fukuyama.co")) (:maintainer "Shingo Fukuyama - http://fukuyama.co") (:url . "https://github.com/ShingoFukuyama/emacs-readability"))]) (read-aloud . [(20160923 500) ((emacs (24 4))) "A simple interface to TTS engines" single ((:commit . "c662366226abfb07204ab442b4f853ed85438d8a") (:keywords "multimedia") (:authors ("Alexander Gromnitsky" . "alexander.gromnitsky@gmail.com")) (:maintainer "Alexander Gromnitsky" . "alexander.gromnitsky@gmail.com") (:url . "https://github.com/gromnitsky/read-aloud.el"))]) (react-snippets . [(20170803 2250) ((yasnippet (0 7 0))) "Yasnippets for React" tar ((:commit . "bfc4b68b81374a6a080240592641091a7e8a6d61"))]) (rdxmk . [(20170630 134) nil "A small set of tools for redox developments" tar ((:commit . "e78749fb29738365ffa4d863ffabeb969ebb0bcf") (:keywords "redox" "convenience" "tools") (:authors ("Jacob Salzberg" . "jsalzbergedu@yahoo.com")) (:maintainer "Jacob Salzberg" . "jsalzbergedu@yahoo.com") (:url . "https://github.com/jsalzbergedu/rdxmk"))]) (rdp . [(20120929 154) nil "Recursive Descent Parser library" single ((:commit . "b620192afada04aec33b38cc130fef0765f41ca9") (:authors ("Christopher Wellons" . "mosquitopsu@gmail.com")) (:maintainer "Christopher Wellons" . "mosquitopsu@gmail.com") (:url . "https://github.com/skeeto/rdp"))]) (rdf-prefix . [(20180127 1806) nil "Prefix lookup for RDF" single ((:commit . "164136d05505275d42d1ca3a390f55fcc89694b8") (:keywords "convenience" "abbrev") (:authors ("Simen Heggestøyl" . "simenheg@gmail.com")) (:maintainer "Simen Heggestøyl" . "simenheg@gmail.com") (:url . "https://github.com/simenheg/rdf-prefix"))]) (rcirc-styles . [(20160207 250) ((cl-lib (0 5))) "support mIRC-style color and attribute codes" single ((:commit . "f313bf6a7470bed314b27c7a40558cb787d7bc67"))]) (rcirc-notify . [(20150219 2204) nil "libnotify popups" single ((:commit . "841a7b5a6cdb0c11a812df924d2c6a7d364fd455") (:keywords "lisp" "rcirc" "irc" "notify" "growl") (:authors ("Will Farrington, Alex Schroeder <alex@gnu.org>, Nic Ferrier" . "nferrier@ferrier.me.uk")) (:maintainer "Nic Ferrier" . "nferrier@ferrier.me.uk"))]) (rcirc-groups . [(20170731 2101) nil "an emacs buffer in rcirc-groups major mode" single ((:commit . "b68ece9d219b909244d4e3c0d8bf6a746d6fead7") (:keywords "comm" "convenience") (:authors ("Dimitri Fontaine" . "dim@tapoueh.org")) (:maintainer "Dimitri Fontaine" . "dim@tapoueh.org") (:url . "http://tapoueh.org/emacs/rcirc-groups.html"))]) (rcirc-alertify . [(20140407 119) ((alert (20140406 1353))) "Cross platform notifications for rcirc" single ((:commit . "ea5cafc55893f375eccbe013d12dbaa94bf6e259") (:keywords "comm" "convenience") (:authors ("Fabián Ezequiel Gallina" . "fgallina@gnu.org")) (:maintainer "Fabián Ezequiel Gallina" . "fgallina@gnu.org"))]) (rcirc-alert . [(20141127 1047) nil "Configurable alert messages on top of RCIRC" tar ((:commit . "0adf8ff9c47023fec578f678424be62b0f49057f") (:keywords "lisp" "rcirc" "irc" "alert" "awesome") (:maintainer "Cayetano Santos"))]) (rc-mode . [(20160913 1918) nil "Major mode for the Plan9 rc shell" single ((:commit . "fe2e0570bf9c19a292e16b18fd4b0a256df5d93f") (:keywords "rc" "plan9" "shell") (:authors ("Jordan Brown")) (:maintainer "Jordan Brown") (:url . "https://github.com/mrhmouse/rc-mode.el"))]) (rbt . [(20170202 2302) ((popup (0 5 3)) (magit (20160128 1201))) "Integrate reviewboard with emacs." single ((:commit . "32bfba9062a014e375451cf4203c29535b5efc1e") (:keywords "reviewboard" "rbt") (:authors ("Joe Heyming" . "joeheyming@gmail.com")) (:maintainer "Joe Heyming" . "joeheyming@gmail.com"))]) (rbenv . [(20141120 749) nil "Emacs integration for rbenv" single ((:commit . "2ea1a5bdc1266caef1dd77700f2c8f42429b03f1") (:keywords "ruby" "rbenv") (:authors ("Yves Senn" . "yves.senn@gmail.com")) (:maintainer "Yves Senn" . "yves.senn@gmail.com") (:url . "https://github.com/senny/rbenv.el"))]) (rats . [(20170818 1013) ((s (1 10 0)) (go-mode (1 3 1)) (cl-lib (0 5))) "Rapid testing suite for Go" single ((:commit . "a6d55aebcc54f669c6c6ffedf84364c4097903cc") (:keywords "go") (:authors ("Antoine Kalmbach" . "ane@iki.fi")) (:maintainer "Antoine Kalmbach" . "ane@iki.fi"))]) (rase . [(20120928 2045) nil "Run At Sun Event daemon" single ((:commit . "59b5f7e8102570b65040e8d55781c7ea28de7338") (:keywords "solar" "sunrise" "sunset" "midday" "midnight") (:authors ("Andrey Kotlarski" . "m00naticus@gmail.com")) (:maintainer "Andrey Kotlarski" . "m00naticus@gmail.com") (:url . "https://github.com/m00natic/rase/"))]) (ranger . [(20170817 1557) ((emacs (24 4))) "Make dired more like ranger" single ((:commit . "6bbff5df2e55f56047fca5058d9ca93ba4963aef") (:keywords "files" "convenience" "dired") (:authors ("Rich Alesi <https://github.com/ralesi>")) (:maintainer "Rich Alesi <https://github.com/ralesi>") (:url . "https://github.com/ralesi/ranger"))]) (random-splash-image . [(20151003 130) nil "Randomly sets splash image to *GNU Emacs* buffer on startup." single ((:commit . "53a39ebfd8ac6be066a652a508a717870f94218a") (:keywords "games") (:authors ("kakakaya <kakakaya AT gmail.com>")) (:maintainer "kakakaya <kakakaya AT gmail.com>") (:url . "https://github.com/kakakaya/random-splash-image"))]) (rand-theme . [(20151219 2335) ((cl-lib (0 5))) "Random Emacs theme at start-up!" single ((:commit . "65a00e5c5150f857aa96803b68f50bc8da0215b7") (:authors ("Daniel Gopar")) (:maintainer "Daniel Gopar") (:url . "https://github.com/gopar/rand-theme"))]) (rally-mode . [(20161114 354) ((popwin (1 0 0))) "a mode to interact with the Rally Software web site." single ((:commit . "0f5e09a6abe2de7613f174b4f54863df93343134") (:keywords "rally" "ca" "agile") (:authors ("Sean LeBlanc" . "seanleblanc@gmail.com")) (:maintainer "Sean LeBlanc" . "seanleblanc@gmail.com") (:url . "https://pragcraft.wordpress.com/"))]) (rake . [(20180212 1008) ((f (0 13 0)) (dash (1 5 0)) (cl-lib (0 5))) "Run rake commands" single ((:commit . "9c204334b03b4e899fadae6e59c20cf105404128") (:keywords "rake" "ruby") (:authors ("Adam Sokolnicki" . "adam.sokolnicki@gmail.com")) (:maintainer "Adam Sokolnicki" . "adam.sokolnicki@gmail.com") (:url . "https://github.com/asok/rake.el"))]) (rainbow-identifiers . [(20141102 1526) ((emacs (24))) "Highlight identifiers according to their names" single ((:commit . "19fbfded1baa98d12335f26f6d7b20e5ae44ce2e") (:authors ("Fanael Linithien" . "fanael4@gmail.com")) (:maintainer "Fanael Linithien" . "fanael4@gmail.com") (:url . "https://github.com/Fanael/rainbow-identifiers"))]) (rainbow-delimiters . [(20170929 1132) nil "Highlight brackets according to their depth" single ((:commit . "19b93892afa0494ba749c2ca9c154e04447ad778") (:keywords "faces" "convenience" "lisp" "tools") (:authors ("Jeremy Rayman" . "opensource@jeremyrayman.com") ("Fanael Linithien" . "fanael4@gmail.com")) (:maintainer "Fanael Linithien" . "fanael4@gmail.com") (:url . "https://github.com/Fanael/rainbow-delimiters"))]) (rainbow-blocks . [(20171025 1438) nil "Block syntax highlighting for lisp code" single ((:commit . "dd435d7bb34ff6f162a5f315df308b90b7e9f842") (:authors ("istib")) (:maintainer "istib") (:url . "https://github.com/istib/rainbow-blocks"))]) (railscasts-theme . [(20150219 1525) nil "Railscasts color theme for GNU Emacs." single ((:commit . "1340c3f6c2717761cab95617cf8dcbd962b1095b") (:keywords "railscasts" "color" "theme") (:authors ("Oleg Shaldybin")) (:maintainer "Oleg Shaldybin") (:url . "https://github.com/mikenichols/railscasts-theme"))]) (railscasts-reloaded-theme . [(20180201 646) nil "Railscasts Reloaded color theme" single ((:commit . "6312f01470dcc73537dbdaaccabd59c4d18d23a9") (:authors ("George Thomas" . "iamgeorgethomas@gmail.com")) (:maintainer "George Thomas" . "iamgeorgethomas@gmail.com") (:url . "https://github.com/thegeorgeous/railscasts-reloaded-theme"))]) (rails-log-mode . [(20140408 425) nil "Major mode for viewing Rails log files" single ((:commit . "ff440003ad7d47cb0ac3300f2a632f4cfd36a446") (:keywords "rails" "log") (:authors ("Anantha kumaran" . "ananthakumaran@gmail.com")) (:maintainer "Anantha kumaran" . "ananthakumaran@gmail.com"))]) (racket-mode . [(20180830 1618) ((emacs (24 3)) (faceup (0 0 2)) (s (1 9 0))) "Major mode for Racket language." tar ((:commit . "2b1c7d476dc71b1707fd5222f963ab6509e50805") (:authors ("Greg Hendershott")) (:maintainer "Greg Hendershott") (:url . "https://github.com/greghendershott/racket-mode"))]) (racer . [(20180709 625) ((emacs (24 3)) (rust-mode (0 2 0)) (dash (2 13 0)) (s (1 10 0)) (f (0 18 2)) (pos-tip (0 4 6))) "code completion, goto-definition and docs browsing for Rust via racer" single ((:commit . "dd7f179efbab6597eb7eb1d66883f168b3dc5573") (:keywords "abbrev" "convenience" "matching" "rust" "tools") (:authors ("Phil Dawes")) (:maintainer "Phil Dawes") (:url . "https://github.com/racer-rust/emacs-racer"))]) (r-autoyas . [(20140101 1510) ((ess (0)) (yasnippet (0 8 0))) "Provides automatically created yasnippets for R function argument lists." tar ((:commit . "b4020ee7f5f895e0065b8b26da8a49c51432d530") (:keywords "r" "yasnippet") (:authors ("Sven Hartenstein & Matthew Fidler")) (:maintainer "Matthew Fidler") (:url . "https://github.com/mlf176f2/r-autoyas.el"))]) (quiz . [(20170818 1115) ((cl-lib (0 5)) (emacs (25))) "Multiple choice quiz game" single ((:commit . "c43151212ead2330e7ec8e5ac6914c617a12e4f8") (:keywords "games" "trivia" "quiz") (:authors ("Dave Pearson" . "davep@davep.org")) (:maintainer "Dave Pearson" . "davep@davep.org") (:url . "https://github.com/davep/quiz.el"))]) (quiet . [(20160508 1256) nil "disconnect from the online world for a while" single ((:commit . "6f20309f99e26fcae2601d1544b342f044e54baf") (:keywords "quiet" "distraction" "network" "detachment" "offline") (:authors ("nik gaffney" . "nik@fo.am")) (:maintainer "nik gaffney" . "nik@fo.am") (:url . "https://github.com/zzkt/quiet"))]) (quickrun . [(20170223 115) ((emacs (24 3))) "Run commands quickly" single ((:commit . "55bbe5d54b80206ea5a60bf2f58eb6368b2c8201") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-quickrun"))]) (quickref . [(20170817 1232) ((dash (1 0 3)) (s (1 0 0))) "Display relevant notes-to-self in the echo area" single ((:commit . "f368c8b8219bb90498c5ab84e26f00eedaa234cf") (:authors ("Kyle Hargraves")) (:maintainer "Kyle Hargraves") (:url . "https://github.com/pd/quickref.el"))]) (quick-shell-keybind . [(20171023 613) ((emacs (24))) "Interactively bind a key to shell commands" single ((:commit . "5f4541a5a5554d108bf16b5fd1713e962161ca1b") (:keywords "maint" "convenience" "processes") (:authors ("eyeinsky" . "eyeinsky9@gmail.com")) (:maintainer "eyeinsky" . "eyeinsky9@gmail.com") (:url . "https://github.com/eyeinsky/quick-shell-keybind"))]) (quick-preview . [(20150829 439) nil "quick preview using GNOME sushi, gloobus or quick look" single ((:commit . "29c884c6ab385ef67d9aa656ebb7c94cabeb5c35") (:keywords "files" "hypermedia") (:authors ("myuhe <yuhei.maeda_at_gmail.com>")) (:maintainer "myuhe") (:url . "https://github.com/myuhe/quick-preview.el"))]) (quick-peek . [(20180525 1411) ((emacs (24 3))) "Inline quick-peek windows" single ((:commit . "3cc57cc12f4b5f27a18cc5fb0c32c3a943c16158") (:keywords "tools" "help" "doc" "convenience") (:authors ("Clément Pit-Claudel" . "clement.pitclaudel@live.com")) (:maintainer "Clément Pit-Claudel" . "clement.pitclaudel@live.com"))]) (quick-buffer-switch . [(20151007 2208) nil "Quick switch to file or dir buffers." single ((:commit . "d5fdd67b4c9f04b7a7122da2215e4ae076a03b1b") (:keywords "emacs" "configuration") (:authors ("Sebastien Gross <seb•ɑƬ•chezwam•ɖɵʈ•org>")) (:maintainer "Sebastien Gross <seb•ɑƬ•chezwam•ɖɵʈ•org>"))]) (quelpa-use-package . [(20180812 1029) ((emacs (24 3)) (quelpa (0)) (use-package (2))) "quelpa handler for use-package" single ((:commit . "90fc1eadf3f7ff3a3bef07d229a807aba2f7beef") (:keywords "package" "management" "elpa" "use-package") (:authors ("steckerhalter")) (:maintainer "steckerhalter") (:url . "https://framagit.org/steckerhalter/quelpa-use-package"))]) (quelpa . [(20180903 1713) ((emacs (24 3))) "Emacs Lisp packages built directly from source" tar ((:commit . "d5b566fbcccfbe3595617c60a68b8d5f11558dab") (:keywords "package" "management" "build" "source" "elpa") (:authors ("steckerhalter")) (:maintainer "steckerhalter") (:url . "https://framagit.org/steckerhalter/quelpa"))]) (quasi-monochrome-theme . [(20180516 1513) nil "Quasi Monochrome theme" tar ((:commit . "e803bc0c2e38f350feb8297a092812e5204781c7") (:keywords "color" "theme" "monochrome"))]) (qt-pro-mode . [(20170604 1841) ((emacs (24))) "Qt Pro/Pri major mode" single ((:commit . "91e113e277c98ae71850802949e37490d537c735") (:keywords "extensions") (:authors ("Todd Neal" . "tolchz@gmail.com")) (:maintainer "Todd Neal" . "tolchz@gmail.com"))]) (qml-mode . [(20161016 31) nil "Major mode for editing QT Declarative (QML) code." single ((:commit . "6c5f33ba88ae010bf201a80ee8095e20a724558c") (:keywords "qml" "qt" "qt declarative") (:authors ("Yen-Chin Lee" . "coldnew.tw@gmail.com")) (:maintainer "Yen-Chin Lee" . "coldnew.tw@gmail.com") (:url . "https://github.com/coldnew/qml-mode"))]) (ql . [(20180418 2020) ((emacs (24))) "Control Quod Libet" single ((:commit . "d976414ba6aa576ad524b5ee5bfa620efd072258") (:keywords "multimedia") (:authors ("Ian Eure" . "ian.eure@gmail.com")) (:maintainer "Ian Eure" . "ian.eure@gmail.com") (:url . "https://github.com/ieure/ql-el"))]) (qiita . [(20140118 844) ((helm (1 5 9)) (markdown-mode (2 0))) "Qiita API Library for emacs" single ((:commit . "93c697b97d540fd1601a13a3d9889fb939b19878") (:keywords "qiita") (:authors ("Wataru MIYAGUNI (gonngo _at_ gmail.com)")) (:maintainer "Wataru MIYAGUNI (gonngo _at_ gmail.com)") (:url . "https://github.com/gongo/qiita-el"))]) (pyvenv . [(20180831 847) nil "Python virtual environment interface" single ((:commit . "921ae2356b6a111ac0b7e44fd04cba8e95cbe936") (:keywords "python" "virtualenv" "tools") (:authors ("Jorgen Schaefer" . "contact@jorgenschaefer.de")) (:maintainer "Jorgen Schaefer" . "contact@jorgenschaefer.de") (:url . "http://github.com/jorgenschaefer/pyvenv"))]) (pythonic . [(20180808 420) ((emacs (25)) (s (1 9)) (f (0 17 2))) "Utility functions for writing pythonic emacs package." single ((:commit . "4eb5ad0d80308495c8a369c4268825d3ae2d3807") (:authors ("Artem Malyshev" . "proofit404@gmail.com")) (:maintainer "Artem Malyshev" . "proofit404@gmail.com") (:url . "https://github.com/proofit404/pythonic"))]) (python-x . [(20180802 1742) ((python (0 24)) (folding (0)) (cl-lib (0 5))) "python.el extras for interactive evaluation" tar ((:commit . "74d8c7eb824846de94705b1e74ee03ef109868d1") (:keywords "python" "eval" "folding") (:url . "https://github.com/wavexx/python-x.el") (:author . "Yuri D'Elia <wavexx@thregr.org>"))]) (python-test . [(20171113 537) ((emacs (25 1))) "Python testing integration" single ((:commit . "f00b9de14647b15b6f36ceee77d7e9e08dd074a4") (:keywords "convenience" "tools" "processes") (:authors ("Mario Rodas" . "marsam@users.noreply.github.com")) (:maintainer "Mario Rodas" . "marsam@users.noreply.github.com") (:url . "https://github.com/emacs-pe/python-test.el"))]) (python-switch-quotes . [(20161228 809) ((emacs (24 3))) "cycle between ' and \" quotes in python strings" single ((:commit . "93f1e9b40e061a6cea480139e8b1362b6404abd0") (:keywords "python" "tools" "convenience") (:authors ("Vladimir Lagunov" . "lagunov.vladimir@gmail.com")) (:maintainer "Vladimir Lagunov" . "lagunov.vladimir@gmail.com") (:url . "https://github.com/werehuman/python-switch-quotes"))]) (python-pytest . [(20180725 1146) ((emacs (24 4)) (dash (2 12 0)) (dash-functional (2 12 0)) (magit-popup (2 12 0)) (projectile (0 14 0)) (s (1 12 0))) "helpers to run pytest" single ((:commit . "09ad688df207ee9b02c990d3897a9e2841931d97") (:keywords "pytest" "test" "python" "languages" "processes" "tools") (:authors ("wouter bolsterlee" . "wouter@bolsterl.ee")) (:maintainer "wouter bolsterlee" . "wouter@bolsterl.ee") (:url . "https://github.com/wbolster/emacs-python-pytest"))]) (python-mode . [(20180814 721) nil "Python major mode" tar ((:commit . "857cfce02d0078539f5389531b1fcfcdd3ef936d"))]) (python-info . [(20151228 1852) nil "Python info manual for Emacs" tar ((:commit . "306f15441b54b25757cdfd3b327b84024ea21ed7"))]) (python-environment . [(20150310 853) ((deferred (0 3 1))) "virtualenv API for Emacs Lisp" tar ((:commit . "401006584e32864a10c69d29f14414828909362e") (:keywords "applications" "tools") (:authors ("Takafumi Arakaki <aka.tkf at gmail.com>")) (:maintainer "Takafumi Arakaki <aka.tkf at gmail.com>"))]) (python-docstring . [(20170508 856) nil "Smart Python docstring formatting" tar ((:commit . "d35d2e0fbe468743c19a870fec7b28a7e725790d"))]) (python-django . [(20150822 404) nil "A Jazzy package for managing Django projects" single ((:commit . "fc54ad74f0309670359b939f64d0f1fff68aeac4") (:keywords "languages") (:authors ("Fabián E. Gallina" . "fabian@anue.biz")) (:maintainer "FSF") (:url . "https://github.com/fgallina/python-django.el"))]) (python-cell . [(20131029 2316) nil "Support for MATLAB-like cells in python mode" single ((:commit . "ccacd91a19be784860d687eb1e8ce88fddaacaf6") (:keywords "python" "matlab" "cell") (:authors ("Thomas Hisch" . "t.hisch@gmail.com")) (:maintainer "Thomas Hisch" . "t.hisch@gmail.com"))]) (pytest . [(20170614 1445) ((s (1 9 0))) "Easy Python test running in Emacs" single ((:commit . "013fccd684fc8f2092d6e1ec4203ec574e12051d") (:keywords "pytest" "python" "testing") (:url . "https://github.com/ionrock/pytest-el"))]) (pyramid . [(20180718 2120) ((emacs (25 2)) (pythonic (0 1 1)) (tablist (0 70))) "Minor mode for working with pyramid projects" tar ((:commit . "63b7ce47d3f79c8fdd06ea0cbdb519ae3e481aea") (:keywords "python" "pyramid" "pylons" "convenience" "tools" "processes") (:authors ("Daniel Kraus" . "daniel@kraus.my")) (:maintainer "Daniel Kraus" . "daniel@kraus.my") (:url . "https://github.com/dakra/pyramid.el"))]) (pynt . [(20180710 726) ((emacs (24 4)) (ein (0 13 1)) (epc (0 1 1)) (deferred (0 5 1))) "Generate and scroll EIN buffers from python code" single ((:commit . "4af6a0668057986ad8d297d9152d897baf77e303") (:keywords "convenience") (:authors ("Edward Banner" . "edward.banner@gmail.com")) (:maintainer "Edward Banner" . "edward.banner@gmail.com") (:url . "https://github.com/ebanner/pynt"))]) (pylint . [(20170402 1255) nil "minor mode for running `pylint'" single ((:commit . "ba62048e04fbe0e691cfccaf173c4ccbccca2992") (:keywords "languages" "python") (:authors ("Ian Eure" . "ian.eure@gmail.com")) (:maintainer "Jonathan Kotta" . "jpkotta@gmail.com"))]) (pyimpsort . [(20160130 453) ((emacs (24 3))) "Sort python imports." tar ((:commit . "d5c61d70896b642646dfd3c809c06174ae086c1a") (:keywords "convenience") (:authors ("Mario Rodas" . "marsam@users.noreply.github.com")) (:maintainer "Mario Rodas" . "marsam@users.noreply.github.com") (:url . "https://github.com/emacs-pe/pyimpsort.el"))]) (pyimport . [(20180308 1752) ((dash (2 8 0)) (s (1 9 0)) (shut-up (0 3 2))) "Manage Python imports!" single ((:commit . "a6f63cf7ed93f0c0f7c207e6595813966f8852b9") (:authors ("Wilfred Hughes" . "me@wilfred.me.uk")) (:maintainer "Wilfred Hughes" . "me@wilfred.me.uk"))]) (pyim-wbdict . [(20170724 2227) ((pyim (1 0))) "Some wubi dicts for pyim" tar ((:commit . "114489ed97e825ae11a8d09da6e873820cf23106") (:keywords "convenience" "chinese" "pinyin" "input-method" "complete") (:authors ("Feng Shu" . "tumashu@163.com")) (:maintainer "Feng Shu" . "tumashu@163.com") (:url . "https://github.com/tumashu/pyim-wbdict"))]) (pyim-cangjie5dict . [(20170730 246) ((pyim (1 0))) "Some cangjie5 dicts for pyim" tar ((:commit . "c8618590780b818db1a67a29bc47c5d25903517a") (:keywords "convenience" "chinese" "pinyin" "input-method" "complete") (:authors ("Yuanchen Xie" . "yuanchen.gm@gmail.com")) (:maintainer "Yuanchen Xie" . "yuanchen.gm@gmail.com") (:url . "https://github.com/erstern/pyim-cangjie5dict"))]) (pyim-basedict . [(20170727 259) nil "The default pinyin dict of pyim" tar ((:commit . "3196cb210e056702c5a4ea1dac1d8e1e27740fab") (:keywords "convenience" "chinese" "pinyin" "input-method" "complete") (:authors ("Feng Shu" . "tumashu@163.com")) (:maintainer "Feng Shu" . "tumashu@163.com") (:url . "https://github.com/tumashu/pyim-basedict"))]) (pyim . [(20180830 1135) ((emacs (24 4)) (popup (0 1)) (async (1 6)) (pyim-basedict (0 1))) "A Chinese input method support quanpin, shuangpin, wubi and cangjie." tar ((:commit . "602843b5d4a6176273d12128a523abf10d8318a5") (:keywords "convenience" "chinese" "pinyin" "input-method") (:authors ("Ye Wenbin <wenbinye@163.com>, Feng Shu" . "tumashu@163.com")) (:maintainer "Ye Wenbin <wenbinye@163.com>, Feng Shu" . "tumashu@163.com") (:url . "https://github.com/tumashu/pyim"))]) (pygen . [(20161121 506) ((elpy (1 12 0)) (python-mode (6 2 2)) (dash (2 13 0))) "Python code generation using Elpy and Python-mode." single ((:commit . "9019ff44ba49d7295b1476530feab91fdadb084b") (:keywords "python" "code generation") (:authors ("Jack Crawley <http://www.github.com/jackcrawley>")) (:maintainer "Jack Crawley <http://www.github.com/jackcrawley>") (:url . "https://github.com/JackCrawley/pygen/"))]) (pyfmt . [(20150521 2056) nil "Emacs interface to pyfmt" single ((:commit . "cb92be2cf0804cc53142dc5edb36f8e0ef5cec32") (:keywords "tools") (:authors ("Alexandre Héaumé" . "aheaume@gmail.com")) (:maintainer "Alexandre Héaumé" . "aheaume@gmail.com") (:url . "https://github.com/aheaume/pyfmt.el"))]) (pyenv-mode-auto . [(20180620 1252) ((pyenv-mode (0 1 0)) (s (1 11 0)) (f (0 17 0))) "Automatically activates pyenv version if .python-version file exists." single ((:commit . "b6eef88ad89865a7e0ec8bae8c6ce8239cb649c6") (:keywords "python" "pyenv") (:authors ("Sviatoslav Bulbakha" . "mail@ssbb.me")) (:maintainer "Sviatoslav Bulbakha" . "mail@ssbb.me") (:url . "https://github.com/ssbb/pyenv-mode-auto"))]) (pyenv-mode . [(20170801 2348) ((pythonic (0 1 0))) "Integrate pyenv with python-mode" single ((:commit . "eabb1c66f9e0c0500fef4d089508aad246d81dc0") (:authors ("Artem Malyshev" . "proofit404@gmail.com")) (:maintainer "Artem Malyshev" . "proofit404@gmail.com") (:url . "https://github.com/proofit404/pyenv-mode"))]) (pydoc-info . [(20110301 834) nil "Better Python support for info-lookup-symbol." tar nil]) (pydoc . [(20180509 2219) nil "functional, syntax highlighted pydoc navigation" single ((:commit . "253a95571fa80548e2174c89fa965e689030f09c") (:keywords "pydoc" "python") (:authors ("John Kitchin" . "jkitchin@andrew.cmu.edu")) (:maintainer "Brian J. Lopes" . "statmobile@gmail.com") (:url . "https://github.com/statmobile/pydoc"))]) (pycoverage . [(20160325 112) ((emacs (24 3))) "Support for coverage stats on Python 2.X and 3" tar ((:commit . "4f5451f4d6e1e2ddd5878fc7d18f5fc4fc92a83d") (:keywords "project" "convenience") (:authors ("matt harrison")) (:maintainer "matt harrison") (:url . "https://github.com/mattharrison/pycoverage.el"))]) (pycarddavel . [(20150831 1216) ((helm (1 7 0)) (emacs (24 0))) "Integrate pycarddav" single ((:commit . "a6d81ee4eb8309cd82f6082aeca68c5a015702a3") (:keywords "helm" "pyccarddav" "carddav" "message" "mu4e" "contacts") (:authors ("Damien Cassou" . "damien@cassou.me")) (:maintainer "Damien Cassou" . "damien@cassou.me"))]) (py-yapf . [(20160925 1122) nil "Use yapf to beautify a Python buffer" single ((:commit . "a878304202ad827a1f3de3dce1badd9ca8731146") (:authors ("Friedrich Paetzke" . "f.paetzke@gmail.com")) (:maintainer "Friedrich Paetzke" . "f.paetzke@gmail.com") (:url . "https://github.com/paetzke/py-yapf.el"))]) (py-test . [(20151117 622) ((dash (2 9 0)) (f (0 17)) (emacs (24 4))) "A test runner for Python code." single ((:commit . "3b2a0bdaacb54df6f2bee8317423e5c0d159d5cf") (:keywords "python" "testing" "py.test") (:authors ("Bogdan Paul Popa" . "popa.bogdanp@gmail.com")) (:maintainer "Bogdan Paul Popa" . "popa.bogdanp@gmail.com") (:url . "https://github.com/Bogdanp/py-test.el"))]) (py-smart-operator . [(20170531 1209) ((s (1 9 0))) "smart-operator for python-mode" single ((:commit . "0c8a66faca4b35158d0b5885472cb75286039167") (:keywords "python" "convenience" "smart-operator") (:authors ("Rustem Muslimov" . "r.muslimov@gmail.com")) (:maintainer "Rustem Muslimov" . "r.muslimov@gmail.com"))]) (py-isort . [(20160925 1018) nil "Use isort to sort the imports in a Python buffer" single ((:commit . "e67306f459c47c53a65604e4eea88a3914596560") (:authors ("Friedrich Paetzke" . "paetzke@fastmail.fm")) (:maintainer "Friedrich Paetzke" . "paetzke@fastmail.fm") (:url . "http://paetzke.me/project/py-isort.el"))]) (py-import-check . [(20130802 1111) nil "Finds the unused python imports using importchecker" single ((:commit . "9787f87745a4234cd9bed711860b707902bc8ae4") (:keywords "python" "import" "check") (:authors ("Sibi" . "sibi@psibi.in")) (:maintainer "Sibi" . "sibi@psibi.in") (:url . "https://github.com/psibi/emacs-py-import-check"))]) (py-gnitset . [(20170821 1732) nil "Run your Python tests any way you'd like" single ((:commit . "1e993cc29cbc31e06fe1e335dec198e21972fa55") (:authors ("Brandon W Maister" . "quodlibetor@gmail.com")) (:maintainer "Brandon W Maister" . "quodlibetor@gmail.com") (:url . "https://www.github.com/quodlibetor/py-gnitset"))]) (py-autopep8 . [(20160925 1052) nil "Use autopep8 to beautify a Python buffer" single ((:commit . "68e12d8788c91c7ec53a68acf1d23adb2ffa4788") (:authors ("Friedrich Paetzke" . "f.paetzke@gmail.com")) (:maintainer "Friedrich Paetzke" . "f.paetzke@gmail.com") (:url . "http://paetzke.me/project/py-autopep8.el"))]) (px . [(20170317 2330) nil "preview inline latex in any mode" single ((:commit . "0c52f7933eab3ca1642ab0df151db9950430c9e2") (:authors ("Aurélien Aptel" . "aurelien.aptel@gmail.com")) (:maintainer "Aurélien Aptel" . "aurelien.aptel@gmail.com") (:url . "http://github.com/aaptel/preview-latex"))]) (pushover . [(20170818 2103) ((cl-lib (0 5))) "Pushover API Access" single ((:commit . "bbe3ac8df3c532a72da4552615af960b8a577588") (:keywords "notifications") (:authors ("Samuel W. Flint" . "swflint@flintfam.org")) (:maintainer "Samuel W. Flint" . "swflint@flintfam.org") (:url . "http://github.com/swflint/pushover.el"))]) (pushbullet . [(20140809 1232) ((grapnel (0 5 2)) (json (1 2))) "Emacs client for the PushBullet Android app" single ((:commit . "73c59a0f1dc04875b3e5a2c8afbc26c32128e445") (:keywords "convenience") (:authors ("Abhishek L" . "abhishek.lekshmanan@gmail.com")) (:maintainer "Abhishek L" . "abhishek.lekshmanan@gmail.com") (:url . "http://www.github.com/theanalyst/revolver"))]) (purty-mode . [(20131004 2259) nil "Safely pretty-print greek letters, mathematical symbols, or anything else." single ((:commit . "8eef77317a3bab07ade212353a50fbd3f20f365a") (:authors ("James Atwood" . "jatwood@cs.umass.edu")) (:maintainer "James Atwood" . "jatwood@cs.umass.edu"))]) (purple-haze-theme . [(20141015 229) ((emacs (24 0))) "an overtly purple color theme for Emacs24." single ((:commit . "3e245cbef7cd09e6b3ee124963e372a04e9a6485") (:authors ("Jason Milkins" . "jasonm23@gmail.com")) (:maintainer "Jason Milkins" . "jasonm23@gmail.com") (:url . "https://github.com/jasonm23/emacs-purple-haze-theme"))]) (purescript-mode . [(20180120 1509) nil "A PureScript editing mode" tar ((:commit . "b76c7f37f1a3527e8ace66bbd584851e1f803cc8"))]) (puppet-mode . [(20180813 1947) ((emacs (24 1)) (pkg-info (0 4))) "Major mode for Puppet manifests" single ((:commit . "7dee1b5a5debac6e56f9107492a413b6c0edb94d") (:keywords "languages") (:authors ("Bozhidar Batsov" . "bozhidar@batsov.com") ("Sebastian Wiesner" . "swiesner@lunaryorn.com") ("Russ Allbery" . "rra@stanford.edu")) (:maintainer "Bozhidar Batsov" . "bozhidar@batsov.com") (:url . "https://github.com/voxpupuli/puppet-mode"))]) (punpun-theme . [(20161103 847) nil "A bleak theme" tar ((:commit . "cce8b10b2df6f9187a9eaa0c3f21ff0dda175968"))]) (pungi . [(20150222 1246) ((jedi (0 2 0 -3 2)) (pyvenv (1 5))) "Integrates jedi with virtualenv and buildout python environments" single ((:commit . "a2d4d439ea371be0b064a12248288903b8a521a0") (:keywords "convenience") (:authors ("Matthew Russell" . "matthew.russell@horizon5.org")) (:maintainer "Matthew Russell" . "matthew.russell@horizon5.org"))]) (punctuality-logger . [(20141120 2031) nil "Punctuality logger for Emacs" single ((:commit . "e09e5dd37bc92289fa2f7dc44aed51a7b5e04bb0") (:keywords "reminder" "calendar") (:authors ("Philip Woods" . "elzairthesorcerer@gmail.com")) (:maintainer "Philip Woods" . "elzairthesorcerer@gmail.com") (:url . "https://gitlab.com/elzair/punctuality-logger"))]) (pulseaudio-control . [(20180627 1150) nil "Use `pactl' to manage PulseAudio volumes." single ((:commit . "1da372ec79f5d2fb901d1f9f0679fee8848fd011") (:keywords "multimedia" "hardware" "sound" "pulseaudio") (:authors ("Alexis" . "flexibeast@gmail.com") ("Ellington Santos" . "ellingtonsantos@gmail.com") ("Sergey Trofimov" . "sarg@sarg.org.ru")) (:maintainer "Alexis" . "flexibeast@gmail.com") (:url . "https://github.com/flexibeast/pulseaudio-control"))]) (pug-mode . [(20180513 2126) ((emacs (24 4)) (cl-lib (0 5))) "Major mode for jade/pug template files" single ((:commit . "685fd3414d89736bf232f5d1a6bed9e0353b98fe") (:keywords "markup" "language" "jade" "pug") (:authors ("Nathan Weizenbaum")) (:maintainer "Henrik Lissner" . "henrik@lissner.net") (:url . "https://github.com/hlissner/emacs-pug-mode"))]) (pt . [(20161226 1959) nil "A front-end for pt, The Platinum Searcher." single ((:commit . "6d99b2aaded3ece3db19a20f4b8f1d4abe382622") (:keywords "pt" "ack" "ag" "grep" "search") (:authors ("Bailey Ling")) (:maintainer "Bailey Ling") (:url . "https://github.com/bling/pt.el"))]) (psysh . [(20171023 529) ((emacs (24 3)) (s (1 9 0)) (f (0 17))) "PsySH, PHP interactive shell (REPL)" single ((:commit . "926af4ae0c068ed699fc939f4b3e642aaa6f7c9e") (:keywords "processes" "php") (:authors ("USAMI Kenta" . "tadsan@zonu.me")) (:maintainer "USAMI Kenta" . "tadsan@zonu.me") (:url . "https://github.com/zonuexe/psysh.el"))]) (psession . [(20180424 459) ((emacs (24)) (cl-lib (0 5)) (async (1 9 3))) "Persistent save of elisp objects." single ((:commit . "b70e255c19e465351bed2091579a69ca991f4aff") (:authors ("Thierry Volpiatto" . "thierry.volpiatto@gmail.com")) (:maintainer "Thierry Volpiatto" . "thierry.volpiatto@gmail.com") (:url . "https://github.com/thierryvolpiatto/psession"))]) (psci . [(20180418 1233) ((purescript-mode (13 10)) (dash (2 9 0)) (s (1 9 0)) (f (0 17 1))) "Major mode for purescript repl psci" tar ((:commit . "3f5ef1141a97c4b5507204d48e8aeccd553e4591") (:keywords "purescript" "psci" "repl" "major" "mode") (:authors ("Antoine R. Dumont <eniotna.t AT gmail.com>")) (:maintainer "Antoine R. Dumont <eniotna.t AT gmail.com>") (:url . "https://github.com/ardumont/emacs-psci"))]) (psc-ide . [(20180605 1002) ((dash (2 13 0)) (dash-functional (1 2 0)) (company (0 8 7)) (cl-lib (0 5)) (s (1 10 0)) (emacs (24 4)) (flycheck (0 24)) (let-alist (1 0 4)) (seq (1 11))) "Minor mode for PureScript's psc-ide tool." tar ((:commit . "f71120b0c0d3192f79488ab000b9a689e5145ce4") (:keywords "languages") (:authors ("Erik Post" . "erik@shinsetsu.nl") ("Dmitry Bushenko" . "d.bushenko@gmail.com") ("Christoph Hegemann") ("Brian Sermons")) (:maintainer "Erik Post" . "erik@shinsetsu.nl") (:url . "https://github.com/epost/psc-ide-emacs"))]) (proxy-mode . [(20180521 330) ((emacs (25))) "A minor mode to toggle proxy." single ((:commit . "1cf689c2408945081215550589936a7eaab14987") (:keywords "comm" "proxy") (:url . "https://github.com/stardiviner/proxy-mode"))]) (protocols . [(20170802 1132) ((cl-lib (0 5))) "Protocol database access functions." single ((:commit . "d0f7c4acb05465f1a0d4be54363bbd2802647e77") (:keywords "convenience" "net" "protocols") (:authors ("Dave Pearson" . "davep@davep.org")) (:maintainer "Dave Pearson" . "davep@davep.org") (:url . "https://github.com/davep/protocols.el"))]) (protobuf-mode . [(20170526 1650) nil "major mode for editing protocol buffers." single ((:commit . "fd90f4536045bc881b8b895731fe72d89450b6b4") (:keywords "google" "protobuf" "languages") (:authors ("Alexandre Vassalotti" . "alexandre@peadrop.com")) (:maintainer "Alexandre Vassalotti" . "alexandre@peadrop.com"))]) (prosjekt . [(20151127 1416) ((dash (2 8 0))) "a software project tool for emacs" tar ((:commit . "a864a8be5842223043702395f311e3350c28e9db") (:authors ("Austin Bingham" . "austin.bingham@gmail.com")) (:maintainer "Austin Bingham" . "austin.bingham@gmail.com") (:url . "https://github.com/abingham/prosjekt"))]) (proportional . [(20171025 2337) ((emacs (25 1))) "use a proportional font everywhere" single ((:commit . "f671ffe8fd803e2fc462e2e1844aeeab1a13918e") (:keywords "faces") (:authors ("Johannes Goslar")) (:maintainer "Johannes Goslar") (:url . "https://github.com/ksjogo/proportional"))]) (propfont-mixed . [(20150113 2211) ((emacs (24)) (cl-lib (0 5))) "Use proportional fonts with space-based indentation." single ((:commit . "0b461ef4754a469610dba71874a34b6da42176bf") (:keywords "faces") (:authors ("Kirill Ignatiev <github.com/ikirill>")) (:maintainer "Kirill Ignatiev <github.com/ikirill>") (:url . "https://github.com/ikirill/propfont-mixed"))]) (prop-menu . [(20150728 1118) ((emacs (24 3)) (cl-lib (0 5))) "Create and display a context menu based on text and overlay properties" single ((:commit . "50b102c1c0935fd3e0c465feed7f27d66b21cdf3") (:keywords "convenience") (:authors ("David Christiansen" . "david@davidchristiansen.dk")) (:maintainer "David Christiansen" . "david@davidchristiansen.dk") (:url . "https://github.com/david-christiansen/prop-menu-el"))]) (proof-general . [(20180901 1708) ((emacs (24 3))) "A generic front-end for proof assistants (interactive theorem provers)" tar ((:commit . "65d69a7a6a4a5aa5518fd55671d58b0b4a350fe2"))]) (prompts . [(20160916 1041) ((dash (2 13 0))) "utilities for working with text prompts." single ((:commit . "1cd5e732ff2a86b47836eb7252e5b59cd4b6ab26") (:keywords "input" "minibuffer") (:authors ("Ben Moon" . "guiltydolphin@gmail.com")) (:maintainer "Ben Moon" . "guiltydolphin@gmail.com") (:url . "https://github.com/guiltydolphin/prompts.el"))]) (prompt-text . [(20160106 1409) nil "Various information in minibuffer prompt" single ((:commit . "bb9265ebfada42d0e3c67c809665e1e5d980691e") (:keywords "utility" "minibuffer") (:authors ("10sr <8slashes+el [at] gmail [dot] com>")) (:maintainer "10sr <8slashes+el [at] gmail [dot] com>") (:url . "https://github.com/10sr/prompt-text-el"))]) (promise . [(20180409 952) ((emacs (25)) (async (1 9))) "Promises/A+" tar ((:commit . "f623fa7466983fd1ba7034371f599434c03da723") (:keywords "async" "promise" "convenience") (:authors ("chuntaro" . "chuntaro@sakura-games.jp")) (:maintainer "chuntaro" . "chuntaro@sakura-games.jp") (:url . "https://github.com/chuntaro/emacs-promise"))]) (projmake-mode . [(20161031 1715) ((dash (20150611 922)) (indicators (20130217 1405))) "Project oriented automatic builder and error highlighter, flymake for projects" tar ((:commit . "a897701f7e8f8cc11459ed44eb0e454db2a460c1"))]) (projekt . [(20150324 848) ((emacs (24))) "some kind of staging for CVS" single ((:commit . "a65e554e5d8b0def08c5d06f3fe34fec40bebd83") (:authors ("Engelke Eschner" . "tekai@gmx.li")) (:maintainer "Engelke Eschner" . "tekai@gmx.li"))]) (projector . [(20180724 1822) ((alert (1 1)) (projectile (0 11 0)) (cl-lib (0 5))) "Lightweight library for managing project-aware shell and command buffers" single ((:commit . "d4aad9449960457932c19123c7ea2d60a67d1cca") (:authors ("Justin Talbott" . "justin@waymondo.com")) (:maintainer "Justin Talbott" . "justin@waymondo.com") (:url . "https://github.com/waymondo/projector"))]) (projectile-variable . [(20170208 1718) ((emacs (24)) (cl-lib (0 5))) "Store project local variables." single ((:commit . "8d348ac70bdd6dc320c13a12941b32b38140e264") (:keywords "project" "convenience") (:authors ("USAMI Kenta" . "tadsan@zonu.me")) (:maintainer "USAMI Kenta" . "tadsan@zonu.me") (:url . "https://github.com/zonuexe/projectile-variable"))]) (projectile-trailblazer . [(20170928 1624) ((emacs (24 4)) (projectile (0 12 0)) (inflections (1 1)) (inf-ruby (2 2 6)) (f (0 13 0)) (rake (0 3 2))) "Minor mode for Rails projects using trailblazer" single ((:commit . "a37a4f7b7f727d98e4c74c0256e059e84263553d") (:keywords "rails" "projectile" "trailblazer" "languages") (:authors ("Michael Dahl" . "michael.dahl84@gmail.com")) (:maintainer "Michael Dahl" . "michael.dahl84@gmail.com") (:url . "https://github.com/micdahl/projectile-trailblazer"))]) (projectile-speedbar . [(20170517 243) ((projectile (0 11 0)) (sr-speedbar (0))) "projectile integration for speedbar" single ((:commit . "dcab13db72c2084edbebe808e35f1126fe0b3bcd") (:keywords "project" "convenience" "speedbar" "projectile") (:authors ("Anshul Verma" . "anshul.verma86@gmail.com")) (:maintainer "Anshul Verma" . "anshul.verma86@gmail.com") (:url . "https://github.com/anshulverma/projectile-speedbar"))]) (projectile-sift . [(20160107 1015) ((sift (0 2 0)) (projectile (0 13 0))) "Run a sift with Projectile" single ((:commit . "4ce8878a0fc396ded7521ce38852d93e1d863065") (:keywords "sift" "projectile") (:authors ("Nicolas Lamirault" . "nicolas.lamirault@gmail.com")) (:maintainer "Nicolas Lamirault" . "nicolas.lamirault@gmail.com") (:url . "https://github.com/nlamirault/sift.el"))]) (projectile-ripgrep . [(20180301 1451) ((ripgrep (0 3 0)) (projectile (0 14 0))) "Run ripgrep with Projectile" single ((:commit . "a1f8f030bf5daea92dd13b953720a6c13dd3557c") (:keywords "ripgrep" "projectile") (:authors ("Nicolas Lamirault" . "nicolas.lamirault@gmail.com")) (:maintainer "Nicolas Lamirault" . "nicolas.lamirault@gmail.com") (:url . "https://github.com/nlamirault/ripgrep.el"))]) (projectile-rails . [(20180718 755) ((emacs (24 3)) (projectile (0 12 0)) (inflections (1 1)) (inf-ruby (2 2 6)) (f (0 13 0)) (rake (0 3 2))) "Minor mode for Rails projects based on projectile-mode" single ((:commit . "38fa072fe2d63890a439cc29a19671da39e975bd") (:keywords "rails" "projectile") (:authors ("Adam Sokolnicki" . "adam.sokolnicki@gmail.com")) (:maintainer "Adam Sokolnicki" . "adam.sokolnicki@gmail.com") (:url . "https://github.com/asok/projectile-rails"))]) (projectile-hanami . [(20160505 1311) ((emacs (24 3)) (projectile (0 12 0)) (rake (0 3 2)) (inf-ruby (2 2 6))) "Minor mode for Hanami projects based on projectile" single ((:commit . "c4b8e7d4dfec789ef8493a7c5d4ce0cf7937e579") (:keywords "hanami" "ruby" "projectile") (:authors ("Arjan van der Gaag")) (:maintainer "Arjan van der Gaag") (:url . "https://github.com/avdgaag/projectile-hanami"))]) (projectile-git-autofetch . [(20180418 2336) ((projectile (0 14 0)) (alert (1 2))) "automatically fetch git repositories" single ((:commit . "55855886bccb5a22fbeb2b1c86ef2e9ff4de9067") (:keywords "tools" "vc") (:authors ("Andreas Müller" . "code@0x7.ch")) (:maintainer "Andreas Müller" . "code@0x7.ch") (:url . "https://github.com/andrmuel/projectile-git-autofetch"))]) (projectile-direnv . [(20160306 138) ((emacs (24)) (s (1 11 0)) (dash (2 12 0)) (projectile (0 13 0))) "Set environment variables from .envrc" single ((:commit . "d5d29e5228f840b7a25358a2fd50353ef2dc9b16") (:keywords "convenience") (:authors ("Christian Romney" . "crommney@pointslope.com")) (:maintainer "Christian Romney" . "crommney@pointslope.com") (:url . "https://github.com/christianromney/projectile-direnv"))]) (projectile-codesearch . [(20180508 1522) ((codesearch (20171122 431)) (projectile (20150405 126))) "Integration of codesearch into projectile" single ((:commit . "b6452c87d8405f37a65ce9320e59422733580bbe") (:keywords "tools" "development" "search") (:authors ("Austin Bingham" . "austin.bingham@gmail.com")) (:maintainer "Austin Bingham" . "austin.bingham@gmail.com") (:url . "https://github.com/abingham/emacs-codesearch"))]) (projectile . [(20180824 2239) ((emacs (25 1)) (pkg-info (0 4))) "Manage and navigate projects in Emacs easily" single ((:commit . "62ef2aea33600b0b992905a37eff6febf30268d6") (:keywords "project" "convenience") (:authors ("Bozhidar Batsov" . "bozhidar@batsov.com")) (:maintainer "Bozhidar Batsov" . "bozhidar@batsov.com") (:url . "https://github.com/bbatsov/projectile"))]) (project-shells . [(20171107 851) ((emacs (24 3)) (seq (2 19))) "Manage the shell buffers of each project" single ((:commit . "d9401de750e444697c2eb9de1ff79f2a2eba4af8") (:keywords "processes" "terminals") (:authors ("\"Huang, Ying\"" . "huang.ying.caritas@gmail.com")) (:maintainer "\"Huang, Ying\"" . "huang.ying.caritas@gmail.com") (:url . "https://github.com/hying-caritas/project-shells"))]) (project-root . [(20110206 2030) nil "Define a project root and take actions based upon it." single ((:authors ("Philip Jackson" . "phil@shellarchive.co.uk")) (:maintainer "Philip Jackson" . "phil@shellarchive.co.uk"))]) (project-persist-drawer . [(20151108 1222) ((project-persist (0 3))) "Use a project drawer with project-persist." tar ((:commit . "35bbe132a4fab6a0fec15ce6c0fd2fe6a4aa9626"))]) (project-persist . [(20150519 2024) nil "A minor mode to allow loading and saving of project settings." tar ((:commit . "8da45c80b23b1d7499eac11a258fd7382312a304"))]) (project-explorer . [(20150504 14) ((cl-lib (0 3)) (es-lib (0 3)) (es-windows (0 1)) (emacs (24))) "A project explorer sidebar" single ((:commit . "589a09008706f5f4ef91393dc4306eede0d15ca9") (:authors ("sabof")) (:maintainer "sabof") (:url . "https://github.com/sabof/project-explorer"))]) (project-abbrev . [(20180706 254) ((emacs (24 4))) "Customize abbreviation expansion in the project." single ((:commit . "ca4bddd72a73d43332c5b262e6a104a341882af5") (:authors ("Shen, Jen-Chieh" . "jcs090218@gmail.com")) (:maintainer "Shen, Jen-Chieh" . "jcs090218@gmail.com") (:url . "https://github.com/jcs090218/project-abbrev"))]) (programmer-dvorak . [(20150427 137) nil "Input method for Programmer Dvorak." single ((:commit . "3288a8f058eca4cab390a564babbbcb17cfa0350") (:keywords "dvorak" "programmer-dvorak" "input-method") (:authors ("Chenyun Yang" . "yangchenyun@gmail.com")) (:maintainer "Chenyun Yang" . "yangchenyun@gmail.com") (:url . "https://github.com/yangchenyun/programmer-dvorak"))]) (prognth . [(20130920 1759) nil "Extend prog1 to arbitrary index" single ((:commit . "2f1ca4d34b1fd581163e1df122c85418137e8e62") (:keywords "lisp") (:authors ("Matus Goljer" . "matus.goljer@gmail.com")) (:maintainer "Matus Goljer" . "matus.goljer@gmail.com"))]) (prog-fill . [(20180607 132) ((emacs (25 1)) (cl-lib (0 6 1))) "Smartly format lines to use vertical space." single ((:commit . "3fbf7da6dd826e95c9077d659566ee29814a31d8") (:keywords "ahungry" "convenience" "c" "formatting" "editing") (:authors ("Matthew Carter" . "m@ahungry.com")) (:maintainer "Matthew Carter" . "m@ahungry.com") (:url . "https://github.com/ahungry/prog-fill"))]) (professional-theme . [(20150315 1100) nil "Emacs port of Vim's professional theme" single ((:commit . "0927d1474049a193f9f366bde5eb1887b9ba20ed") (:keywords "theme" "light" "professional") (:authors ("Juanjo Alvarez" . "juanjo@juanjoalvarez.net")) (:maintainer "Juanjo Alvarez" . "juanjo@juanjoalvarez.net") (:url . "https://github.com/juanjux/emacs-professional-theme"))]) (prodigy . [(20180511 938) ((s (1 8 0)) (dash (2 4 0)) (f (0 14 0)) (emacs (24))) "Manage external services from within Emacs" single ((:commit . "701dccaa56de9e6a330c05bde33bce4f3b3d6a97") (:authors ("Johan Andersson" . "johan.rejeep@gmail.com")) (:maintainer "Johan Andersson" . "johan.rejeep@gmail.com") (:url . "http://github.com/rejeep/prodigy.el"))]) (processing-snippets . [(20140426 1428) ((yasnippet (0 8 0))) "Snippets for processing-mode" tar ((:commit . "448aba82970c98322629eaf2746e73be6c30c98e"))]) (processing-mode . [(20171022 2302) nil "Major mode for Processing 2.0" single ((:commit . "448aba82970c98322629eaf2746e73be6c30c98e") (:keywords "languages" "snippets") (:authors ("Peter Vasil" . "mail@petervasil.net")) (:maintainer "Peter Vasil" . "mail@petervasil.net") (:url . "https://github.com/ptrv/processing2-emacs"))]) (proc-net . [(20130322 12) nil "network process tools" single ((:commit . "10861112a1f3994c8e6374d6c5bb5d734cfeaf73") (:keywords "processes") (:authors ("Nic Ferrier" . "nferrier@ferrier.me.uk")) (:maintainer "Nic Ferrier" . "nferrier@ferrier.me.uk") (:url . "http://github.com/nicferrier/emacs-procnet"))]) (private-diary . [(20151216 1657) ((emacs (24 0))) "maintain a private diary in Emacs" single ((:commit . "0c86fb6150ad8ed14f94def3504f5a68f4147283") (:keywords "diary" "encryption") (:authors ("James P. Ascher" . "jpa4q@virginia.edu")) (:maintainer "James P. Ascher" . "jpa4q@virginia.edu") (:url . "https://github.com/cacology/private-diary"))]) (private . [(20150122 157) ((aes (0 6))) "take care of your private configuration files." single ((:commit . "9266d01c095895cc3ee9de95bc20511e88353755") (:keywords "private" "configuration" "backup" "recover") (:authors ("Cheung Mou Wai" . "yeannylam@gmail.com")) (:maintainer "Cheung Mou Wai" . "yeannylam@gmail.com") (:url . "https://github.com/cheunghy/private"))]) (pretty-symbols . [(20140814 959) nil "Draw tokens as Unicode glyphs." single ((:commit . "582cbe51ecfe1cc0a5b185bc06113c8a661e3956") (:keywords "faces") (:authors ("David Röthlisberger" . "david@rothlis.net")) (:maintainer "David Röthlisberger" . "david@rothlis.net") (:url . "http://github.com/drothlis/pretty-symbols"))]) (pretty-sha-path . [(20141105 1826) nil "Prettify Guix/Nix store paths" single ((:commit . "a2b43dd9de423a38d67cda2e3bd9412f7d363257") (:keywords "faces" "convenience") (:authors ("Alex Kost" . "alezost@gmail.com")) (:maintainer "Alex Kost" . "alezost@gmail.com") (:url . "https://gitorious.org/alezost-emacs/pretty-sha-path"))]) (pretty-mode . [(20160614 1846) nil "Redisplay parts of the buffer as pretty Unicode symbols." single ((:commit . "59466813f6a46bed926ddcbae1a70b0eae7f73a0") (:keywords "pretty" "unicode" "symbols") (:authors ("Arthur Danskin" . "arthurdanskin@gmail.com")) (:maintainer "Dmitri Akatov" . "akatov@gmail.com") (:url . "https://github.com/akatov/pretty-mode"))]) (prettify-greek . [(20160603 908) nil "Greek letters for prettify-symbols" single ((:commit . "698d07a6ffe85f6fb53f3bfec4f49380c25cfd90") (:keywords "faces") (:url . "https://gitlab.com/fommil/emacs-prettify-greek"))]) (prettier-js . [(20180109 726) nil "Minor mode to format JS code on file save" single ((:commit . "fac9dd29720f8417bd8cd5dd8ab5138c6dd7d701") (:keywords "convenience" "wp" "edit" "js") (:authors ("James Long and contributors")) (:maintainer "James Long and contributors") (:url . "https://github.com/prettier/prettier-emacs"))]) (presentation . [(20180427 224) ((emacs (24 4)) (cl-lib (0 5))) "Display large character for presentation" single ((:commit . "f53f67aeab97e8eea6d1f12df5f7ce3b1b03b879") (:keywords "environment" "faces" "frames") (:authors ("USAMI Kenta" . "tadsan@zonu.me")) (:maintainer "USAMI Kenta" . "tadsan@zonu.me") (:url . "https://github.com/zonuexe/emacs-presentation-mode"))]) (preseed-generic-mode . [(20180210 500) nil "Debian preseed file major mode" single ((:commit . "3aa8806c4a659064baa01751400c53fbaf847f66") (:authors ("Tong Sun" . "suntong@users.sourceforge.net")) (:maintainer "Tong Sun" . "suntong@users.sourceforge.net") (:url . "https://github.com/suntong/preseed-generic-mode"))]) (prescient . [(20180824 138) ((emacs (25 1))) "Better sorting and filtering." single ((:commit . "1e0db9451e75f0db29668bebe98dfa747c6b4bcf") (:keywords "extensions") (:authors ("Radon Rosborough" . "radon.neon@gmail.com")) (:maintainer "Radon Rosborough" . "radon.neon@gmail.com") (:url . "https://github.com/raxod502/prescient.el"))]) (preproc-font-lock . [(20151107 2018) nil "Highlight C-style preprocessor directives." single ((:commit . "565fda9f5fdeb0598986174a07e9fb09f7604397") (:keywords "c" "languages" "faces") (:authors ("Anders Lindgren")) (:maintainer "Anders Lindgren") (:url . "https://github.com/Lindydancer/preproc-font-lock"))]) (prassee-theme . [(20180709 1004) ((emacs (24))) "A high contrast color theme for Emacs." single ((:commit . "81126f69cdbaab836c00ae7a49aaf89d4229fde1") (:keywords "dark" "high-contrast" "faces") (:authors ("Prassee " . "prassee.sathian@gmail.com")) (:maintainer "Prassee " . "prassee.sathian@gmail.com") (:url . "https://github.com/prassee/prassee-emacs-theme"))]) (ppd-sr-speedbar . [(20151108 1224) ((sr-speedbar (20140914 2339)) (project-persist-drawer (0 0 4))) "Sr Speedbar adaptor for project-persist-drawer." tar ((:commit . "d88d7f63f695824c435dd996405454d1e46d2aa3"))]) (powerthesaurus . [(20180719 908) ((emacs (24)) (request (0 3 0)) (s (1 12 0))) "Powerthesaurus integration" single ((:commit . "ab39b050e801934872f3dcaa60b50b0d30ecf367") (:keywords "convenience" "writing") (:url . "http://github.com/SavchenkoValeriy/emacs-powerthesaurus"))]) (powershell . [(20180617 628) ((emacs (24))) "Mode for editing Powershell scripts" single ((:commit . "4e215e4cd683c727315301d1b61bef4f9773abec") (:keywords "powershell" "languages") (:authors ("Frédéric Perrin <frederic (dot) perrin (arobas) resel (dot) fr>")) (:maintainer "Frédéric Perrin <frederic (dot) perrin (arobas) resel (dot) fr>") (:url . "http://github.com/jschaf/powershell.el"))]) (powerline-evil . [(20151112 1510) ((evil (1 0 8)) (powerline (2 3))) "Utilities for better Evil support for Powerline" tar ((:commit . "98b3a102b6dba6632aa0755a7257300c9b164309") (:keywords "evil" "mode-line" "powerline") (:authors ("Chris Johnson" . "raugturi@gmail.com")) (:maintainer "Chris Johnson" . "raugturi@gmail.com") (:url . "http://github.com/raugturi/powerline-evil/"))]) (powerline . [(20180322 248) ((cl-lib (0 2))) "Rewrite of Powerline" tar ((:commit . "af5ef31a33c3589a9be0b2a55a2741582e605efd") (:keywords "mode-line") (:authors ("Donald Ephraim Curtis" . "dcurtis@milkbox.net")) (:maintainer "Donald Ephraim Curtis" . "dcurtis@milkbox.net") (:url . "http://github.com/milkypostman/powerline/"))]) (pow . [(20140420 806) ((emacs (24)) (cl-lib (0 5))) "pow (http://pow.cx/) manager for emacs" tar ((:commit . "ea83986b8ca8e27cb996290d6463b111ec0966ce") (:keywords "develop" "web" "pow") (:authors ("yukihiro hara" . "yukihr@gmail.com")) (:maintainer "yukihiro hara" . "yukihr@gmail.com") (:url . "http://github.com/yukihr/emacs-pow"))]) (pov-mode . [(20161115 743) nil "Major mode for editing POV-Ray scene files." tar ((:commit . "9fc1db3aab7c27155674dd1a87ec62606035d074"))]) (postcss-sorting . [(20180211 956) ((emacs (24))) "postcss-sorting interface" single ((:commit . "deb0c935d2904c11a965758a9aee5a0e905f21fc") (:authors ("Peiwen Lu" . "hi@peiwen.lu")) (:maintainer "Peiwen Lu" . "hi@peiwen.lu") (:url . "https://github.com/P233/postcss-sorting.el"))]) (posframe . [(20180902 205) ((emacs (26))) "Pop a posframe (just a frame) at point" single ((:commit . "08ef38d27dad266fb3f666890df4994db2346427") (:keywords "tooltip") (:authors ("Feng Shu" . "tumashu@163.com")) (:maintainer "Feng Shu" . "tumashu@163.com") (:url . "https://github.com/tumashu/posframe"))]) (pos-tip . [(20150318 1513) nil "Show tooltip at point" single ((:commit . "051e08fec5cf30b7574bdf439f79fef7d42d689d") (:keywords "tooltip") (:authors ("S. Irie")) (:maintainer "S. Irie"))]) (portage-navi . [(20141208 1355) ((concurrent (0 3 1)) (ctable (0 1 2))) "portage viewer" single ((:commit . "8016c3e99fe6cef101d479a3d69185796b22ca2f") (:keywords "tools" "gentoo") (:authors ("<m.sakurai at kiwanami.net>")) (:maintainer "<m.sakurai at kiwanami.net>") (:url . "https://github.com/kiwanami/emacs-portage-navi"))]) (popwin . [(20150315 1300) nil "Popup Window Manager." single ((:commit . "95dea14c60019d6cccf9a3b33e0dec4e1f22c304") (:keywords "convenience") (:authors ("Tomohiro Matsuyama" . "m2ym.pub@gmail.com")) (:maintainer "Tomohiro Matsuyama" . "m2ym.pub@gmail.com"))]) (popup-switcher . [(20171205 851) ((cl-lib (0 3)) (popup (0 5 3))) "switch to other buffers and files via popup." single ((:commit . "f5788a31918e37bb5c04139048c667bcec9f1b62") (:keywords "popup" "switch" "buffers" "functions") (:authors ("Kostafey" . "kostafey@gmail.com")) (:maintainer "Kostafey" . "kostafey@gmail.com") (:url . "https://github.com/kostafey/popup-switcher"))]) (popup-kill-ring . [(20131020 1854) ((popup (0 4)) (pos-tip (0 4))) "interactively insert item from kill-ring" single ((:commit . "5773dfadc104a906c088a3ec62e8cdd3e01e57fa") (:keywords "popup" "kill-ring" "pos-tip") (:authors ("khiker" . "khiker.mail+elisp@gmail.com")) (:maintainer "khiker" . "khiker.mail+elisp@gmail.com") (:url . "https://github.com/waymondo/popup-kill-ring"))]) (popup-imenu . [(20170326 1040) ((dash (2 12 1)) (popup (0 5 3)) (flx-ido (0 6 1))) "imenu index popup" single ((:commit . "c5e2e69adbd3a630e4cb750965a1aee8c10c1f09") (:keywords "popup" "imenu") (:authors ("Igor Shymko" . "igor.shimko@gmail.com")) (:maintainer "Igor Shymko" . "igor.shimko@gmail.com") (:url . "https://github.com/ancane/popup-imenu"))]) (popup-edit-menu . [(20170404 1425) ((emacs (24))) "a popup context edit menu package" single ((:commit . "925600a6e29183841199e866cf55e566a6a1b002") (:keywords "lisp" "pop-up" "context" "edit" "menu") (:authors ("Debugfan Chin" . "debugfanchin@gmail.com")) (:maintainer "Debugfan Chin" . "debugfanchin@gmail.com"))]) (popup-complete . [(20141109 308) ((popup (0 5 0))) "completion with popup" single ((:commit . "caa655a6d8472e9a4bfa1311126d90d7d1b07fca") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-popup-complete"))]) (popup . [(20160709 1429) ((cl-lib (0 5))) "Visual Popup User Interface" single ((:commit . "80829dd46381754639fb764da11c67235fe63282") (:keywords "lisp") (:authors ("Tomohiro Matsuyama" . "m2ym.pub@gmail.com")) (:maintainer "Tomohiro Matsuyama" . "m2ym.pub@gmail.com"))]) (poporg . [(20170403 751) nil "Pop a comment or string to an empty buffer for text editing" single ((:commit . "2c58d68c81ecca4140bf179f19ed153ec804b65a") (:keywords "outlines" "tools") (:authors ("François Pinard" . "pinard@iro.umontreal.ca") ("Joseph Rabinoff" . "rabinoff@post.harvard.edu")) (:maintainer "Joseph Rabinoff" . "rabinoff@post.harvard.edu") (:url . "https://github.com/QBobWatson/poporg"))]) (pophint . [(20170918 248) ((log4e (0 2 0)) (yaxception (0 3))) "Provide navigation using pop-up tips, like Firefox's Vimperator Hint Mode" tar ((:commit . "909025c5a871ca4b9ec7aed7f1a27c819a94dba1") (:keywords "popup") (:authors ("Hiroaki Otsu" . "ootsuhiroaki@gmail.com")) (:maintainer "Hiroaki Otsu" . "ootsuhiroaki@gmail.com") (:url . "https://github.com/aki2o/emacs-pophint"))]) (ponylang-mode . [(20180804 1521) ((dash (2 10 0))) "Major mode for Pony code" single ((:commit . "be6f9dce623415656320f32e350e28da75c53437") (:keywords "languages" "programming") (:url . "https://github.com/seantallen/ponylang-mode"))]) (pony-snippets . [(20160205 411) ((yasnippet (0 8 0))) "Yasnippets for Pony" tar ((:commit . "a6615ab0693f17fc47ec45753202010238157810") (:keywords "snippets" "pony") (:url . "https://github.com/seantallen/pony-snippets"))]) (pony-mode . [(20170807 1522) nil "Minor mode for working with Django Projects" tar ((:commit . "760684d30b6c234d1b88c9a4673a808f36f7f341"))]) (pomodoro . [(20150716 1746) nil "A timer for the Pomodoro Technique" single ((:commit . "4a299b8f5e6623010224dcb3e524ff288c6a082c") (:authors ("David Kerschner" . "dkerschner@gmail.com")) (:maintainer "David Kerschner" . "dkerschner@gmail.com"))]) (pomidor . [(20180614 828) ((emacs (24 3)) (alert (1 2))) "Simple and cool pomodoro timer" tar ((:commit . "8859aecdb48b76a36c5e251793da0f108b2dfeb4") (:keywords "tools" "time" "applications" "pomodoro technique") (:authors ("TatriX" . "tatrics@gmail.com")) (:maintainer "TatriX" . "tatrics@gmail.com") (:url . "https://github.com/TatriX/pomidor"))]) (polymode . [(20180902 2235) ((emacs (25))) "Extensible framework for multiple major modes" tar ((:commit . "b7a27bf0127cc17348883052117c1745aadf20c2") (:keywords "languages" "multi-modes" "processes") (:authors ("Vitalie Spinu")) (:maintainer "Vitalie Spinu") (:url . "https://github.com/vitoshka/polymode"))]) (poly-slim . [(20180902 2237) ((emacs (25)) (polymode (0 1)) (slim-mode (1 1))) "Polymodes for slim" single ((:commit . "cbf6ad711d4e166afc288eef95025d239b8d70ad") (:keywords "emacs") (:authors ("Siavash Sajjadi and Vitalie Spinu")) (:maintainer "Vitalie Spinu") (:url . "https://github.com/polymode/poly-slim"))]) (poly-ruby . [(20170802 1348) ((emacs (24 3)) (polymode (1 0))) "Provides poly-ruby-mode" single ((:commit . "e6f50a92d29a5ff567d70cafa6621c4f89056d11") (:keywords "languages") (:authors ("Akinori MUSHA" . "knu@iDaemons.org")) (:maintainer "Akinori MUSHA" . "knu@iDaemons.org") (:url . "https://github.com/knu/poly-ruby.el"))]) (poly-org . [(20180902 2236) ((emacs (25)) (polymode (0 1))) "Polymode for org-mode" single ((:commit . "7e958ddc40a4d713dec8ce6664b3ae44df2c536c") (:keywords "languages" "multi-modes") (:authors ("Vitalie Spinu")) (:maintainer "Vitalie Spinu") (:url . "https://github.com/polymode/poly-org"))]) (poly-noweb . [(20180903 1238) ((emacs (25)) (polymode (0 1))) "Polymode for noweb" single ((:commit . "d6fa88468c8b097729ca579140c4537d11e96cfe") (:keywords "languages" "multi-modes") (:authors ("Vitalie Spinu")) (:maintainer "Vitalie Spinu") (:url . "https://github.com/polymode/poly-noweb"))]) (poly-markdown . [(20180903 1517) ((emacs (25)) (polymode (0 1)) (markdown-mode (2 3))) "Polymode for markdown-mode" single ((:commit . "93577cb1c5b58ac755a260f1e984ea9cdab651d0") (:keywords "emacs") (:authors ("Vitalie Spinu")) (:maintainer "Vitalie Spinu") (:url . "https://github.com/polymode/poly-markdown"))]) (poly-erb . [(20180902 2232) ((emacs (25)) (polymode (0 1))) "Polymode for erb" single ((:commit . "61744fa265c81ad300377b005ac481c077a3e20d") (:keywords "emacs") (:authors ("Siavash Sajjadi and Vitalie Spinu")) (:maintainer "Vitalie Spinu") (:url . "https://github.com/polymode/poly-erb"))]) (poly-R . [(20180904 1528) ((emacs (25)) (polymode (0 1))) "Various polymodes for R language" single ((:commit . "b4a3d88755199f1070629e852e81fe36dc00bad1") (:keywords "languages" "multi-modes") (:authors ("Vitalie Spinu")) (:maintainer "Vitalie Spinu") (:url . "https://github.com/polymode/poly-R"))]) (pollen-mode . [(20180404 1312) ((emacs (24 3)) (cl-lib (0 5))) "major mode for editing pollen files" single ((:commit . "df4eab5b490cb478a092e6bab6b07f9e2f9c6fad") (:keywords "languages" "pollen" "pollenpub") (:authors ("Junsong Li <ljs.darkfish AT GMAIL>")) (:maintainer "Junsong Li") (:url . "https://github.com/lijunsong/pollen-mode"))]) (pointback . [(20100210 1552) nil "Restore window points when returning to buffers" single ((:commit . "e3a02c1784d81b5a1d2477338d049af581ed19f8") (:keywords "convenience") (:authors ("Markus Triska" . "markus.triska@gmx.at")) (:maintainer "Markus Triska" . "markus.triska@gmx.at"))]) (point-stack . [(20170808 1658) nil "Back and forward navigation through buffer locations" single ((:commit . "76e17311e3a810314c7d31ac46dc55450ff30fa2") (:authors ("Matt Harrison" . "matthewharrison@gmail.com") ("Dmitry Gutov" . "dgutov@yandex.ru")) (:maintainer "Matt Harrison" . "matthewharrison@gmail.com"))]) (point-pos . [(20170421 1632) nil "Save and restore point positions" single ((:commit . "442bccb40791832cbc2d6f5c8f53be745aea2b73") (:keywords "tools" "convenience") (:authors ("Alex Kost" . "alezost@gmail.com")) (:maintainer "Alex Kost" . "alezost@gmail.com") (:url . "https://github.com/alezost/point-pos.el"))]) (poet-theme . [(20180812 1815) nil "A prose friendly theme." single ((:commit . "2c3c133bd01415abaa55cd46578c5f91f9eada0b") (:authors ("Kunal Bhalla" . "bhalla.kunal@gmail.com")) (:maintainer "Kunal Bhalla" . "bhalla.kunal@gmail.com") (:url . "https://github.com/kunalb/poet/"))]) (podcaster . [(20161020 1535) ((cl-lib (0 5))) "Podcast client" single ((:commit . "9854517025deb5d556168a68955fb7b662239f5c") (:authors ("DarkSun" . "lujun9972@gmail.com")) (:maintainer "DarkSun" . "lujun9972@gmail.com") (:url . "https://github.com/lujun9972/podcaster"))]) (pocket-reader . [(20180819 2007) ((emacs (25 1)) (dash (2 13 0)) (kv (0 0 19)) (pocket-lib (0 1)) (s (1 10)) (ov (1 0 6)) (rainbow-identifiers (0 2 2)) (org-web-tools (0 1)) (ht (2 2))) "Client for Pocket reading list" single ((:commit . "0eb2e678b3fdc8899e420e6ecca03a2ada4b6283") (:keywords "pocket") (:authors ("Adam Porter" . "adam@alphapapa.net")) (:maintainer "Adam Porter" . "adam@alphapapa.net") (:url . "https://github.com/alphapapa/pocket-reader.el"))]) (pocket-mode . [(20171201 1315) ((emacs (24 4)) (pocket-api (0 1))) "Manage your pocket" single ((:commit . "229de7d35b7e5605797591c46aa8200d7efc363c") (:keywords "convenience" "pocket") (:authors ("DarkSun" . "lujun9972@gmail.com")) (:maintainer "DarkSun" . "lujun9972@gmail.com"))]) (pocket-lib . [(20180712 23) ((emacs (25 1)) (request (0 2)) (dash (2 13 0)) (kv (0 0 19)) (s (1 12 0))) "Library for accessing getpocket.com API" single ((:commit . "8dd89153472d2e49bf9a3b3507b93c2acf0b44ac") (:keywords "pocket") (:authors (nil . "Adam Porter <adam@alphapapa.net")) (:maintainer nil . "Adam Porter <adam@alphapapa.net") (:url . "https://github.com/alphapapa/pocket-lib.el"))]) (pocket-api . [(20180403 109) ((emacs (24 4)) (request (0 2))) "another pocket api" single ((:commit . "3eb9430b9db90bc02e736e433eb86389f7655189") (:keywords "convenience" "pocket") (:authors ("DarkSun" . "lujun9972@gmail.com")) (:maintainer "DarkSun" . "lujun9972@gmail.com") (:url . "https://github.com/lujun9972/pocket-api.el"))]) (po-mode . [(20180505 1115) nil "major mode for GNU gettext PO files" single ((:commit . "b26729c67cffb2403d8a20b44606f5a08cb901b5") (:keywords "i18n" "gettext"))]) (pmdm . [(20151109 1836) nil "poor man's desktop-mode alternative." single ((:authors ("Iñigo Serna" . "inigoserna@gmail.com")) (:maintainer "Iñigo Serna" . "inigoserna@gmail.com") (:url . "https://bitbucket.com/inigoserna/pmdm.el"))]) (plur . [(20160504 924) ((emacs (24 4))) "Easily search and replace multiple variants of a word" single ((:commit . "5bdd3b9a2f0624414bd596e798644713cd1545f0") (:authors ("Chunyang Xu" . "xuchunyang.me@gmail.com")) (:maintainer "Chunyang Xu" . "xuchunyang.me@gmail.com") (:url . "https://github.com/xuchunyang/plur"))]) (plsense-direx . [(20140520 2008) ((direx (0 1 -3)) (plsense (0 3 2)) (log4e (0 2 0)) (yaxception (0 3 2))) "Perl Package Explorer" single ((:commit . "8a2f465264c74e04524cc789cdad0190ace43f6c") (:keywords "perl" "convenience") (:authors ("Hiroaki Otsu" . "ootsuhiroaki@gmail.com")) (:maintainer "Hiroaki Otsu" . "ootsuhiroaki@gmail.com") (:url . "https://github.com/aki2o/plsense-direx"))]) (plsense . [(20151104 1445) ((auto-complete (1 4 0)) (log4e (0 2 0)) (yaxception (0 2 0))) "provide interface for PlSense that is a development tool for Perl." single ((:commit . "d50f9dccc98f42bdb42f1d1c8142246e03879218") (:keywords "perl" "completion") (:authors ("Hiroaki Otsu" . "ootsuhiroaki@gmail.com")) (:maintainer "Hiroaki Otsu" . "ootsuhiroaki@gmail.com") (:url . "https://github.com/aki2o/emacs-plsense"))]) (plim-mode . [(20140813 13) nil "Major mode for editing Plim files" single ((:commit . "92e39190286f172567ceb02c80e1df3b81abfa2d") (:keywords "markup" "language") (:authors ("Dong Weiming")) (:maintainer "Dong Weiming") (:url . "http://github.com/dongweiming/plim-mode"))]) (plenv . [(20130707 616) nil "A plenv wrapper for Emacs" single ((:commit . "ee937d0f3a1a7ba2d035f45be896d3ed8fefaee2") (:keywords "emacs" "perl") (:authors ("Kenta Sato" . "karupa@cpan.org")) (:maintainer "Kenta Sato" . "karupa@cpan.org"))]) (playground . [(20180624 326) ((emacs (24 4))) "Manage sandboxes for alternative configurations" single ((:commit . "9212790026bea9ab5fb4ecf0da1163be8ab00776") (:keywords "maint") (:authors ("Akira Komamura" . "akira.komamura@gmail.com")) (:maintainer "Akira Komamura" . "akira.komamura@gmail.com") (:url . "https://github.com/akirak/emacs-playground"))]) (playerctl . [(20180301 1354) nil "Control your music player (e.g. Spotify) with playerctl" single ((:commit . "3eee541423c2e5eb9f23a26fa9aa88c9c5a19ad1") (:keywords "multimedia" "playerctl" "music") (:authors ("Thomas Luquet" . "thomas@luquet.net")) (:maintainer "Thomas Luquet" . "thomas@luquet.net") (:url . "https://github.com/thomasluquet/playerctl.el"))]) (play-routes-mode . [(20170426 733) nil "Play Framework Routes File Support" single ((:commit . "22d7b87e0eaf0330f2b2283872f8dc08a3258771") (:keywords "play" "scala") (:authors ("M.Riehl <max@flatmap.ninja>, P.Haun" . "bomgar85@googlemail.com")) (:maintainer "M.Riehl <max@flatmap.ninja>, P.Haun" . "bomgar85@googlemail.com") (:url . "https://github.com/brocode/play-routes-mode/"))]) (play-crystal . [(20180114 1024) ((emacs (24 4)) (dash (2 12 0)) (request (0 2 0))) "https://play.crystal-lang.org integration." single ((:commit . "0b4810a9025213bd11dbcbfd38b3ca928829e0a5") (:keywords "convenience") (:authors ("Vitalii Elenhaupt")) (:maintainer "Vitalii Elenhaupt") (:url . "https://github.com/veelenga/play-crystal.el"))]) (platformio-mode . [(20161210 1339) ((projectile (0 13 0))) "PlatformIO integration" single ((:commit . "1466aed132a77f48fcb31938d64abb1a1e58ec42") (:authors ("Zach Massia" . "zmassia@gmail.com")) (:maintainer "Zach Massia" . "zmassia@gmail.com") (:url . "https://github.com/zachmassia/platformio-mode"))]) (plaster . [(20180127 2050) ((emacs (24 3))) "Pasting to a plaster host with buffers." single ((:commit . "2e61d16af81b96ff3191afd7a880f032d245182b") (:keywords "convenience" "paste service") (:authors ("Nicolas Hafner" . "shinmera@tymoon.eu")) (:maintainer "Nicolas Hafner" . "shinmera@tymoon.eu") (:url . "http://github.com/shirakumo/plaster/"))]) (plantuml-mode . [(20180816 1012) ((emacs (25 0))) "Major mode for PlantUML" single ((:commit . "b358a53bb0ab195f0193169d0d6869a3ef2c543e") (:keywords "uml" "plantuml" "ascii") (:authors ("Zhang Weize (zwz)")) (:maintainer "Carlo Sciolla (skuro)"))]) (planet-theme . [(20161031 217) ((emacs (24))) "A dark theme inspired by Gmail's 'Planets' theme of yore" single ((:commit . "b0a310ff36565fe22224c407cf59569986698a32") (:keywords "themes") (:authors ("Charlie McMackin" . "charlie.mac@gmail.com")) (:maintainer "Charlie McMackin" . "charlie.mac@gmail.com") (:url . "https://github.com/cmack/emacs-planet-theme"))]) (plan9-theme . [(20180804 1441) nil "A color theme for Emacs based on Plan9" single ((:commit . "4c1050b8ed42e0f99ef64c77ec370a786bd0003c") (:authors ("John Louis Del Rosario" . "john2x@gmail.com")) (:maintainer "John Louis Del Rosario" . "john2x@gmail.com") (:url . "https://github.com/john2x/plan9-theme.el"))]) (plain-theme . [(20171124 410) ((emacs (24))) "Plain theme without syntax highlighting" single ((:commit . "a3d5389a44326314da21f147bad2ede60e2cf986"))]) (pkgbuild-mode . [(20180723 1231) ((emacs (25 1))) "Interface to the ArchLinux package manager" single ((:commit . "358911236a070c5ec4e79887d8f45e67e141c547") (:keywords "languages") (:authors ("Juergen Hoetzel" . "juergen@hoetzel.info")) (:maintainer "Juergen Hoetzel" . "juergen@hoetzel.info") (:url . "https://github.com/juergenhoetzel/pkgbuild-mode"))]) (pkg-info . [(20150517 1143) ((epl (0 8))) "Information about packages" single ((:commit . "76ba7415480687d05a4353b27fea2ae02b8d9d61") (:keywords "convenience") (:authors ("Sebastian Wiesner" . "swiesner@lunaryorn.com")) (:maintainer "Sebastian Wiesner" . "swiesner@lunaryorn.com") (:url . "https://github.com/lunaryorn/pkg-info.el"))]) (pixiv-novel-mode . [(20160220 1421) nil "Major mode for pixiv novel" single ((:commit . "0d1ca524d92b91f20a7105402a773bc21779b434") (:keywords "novel" "pixiv") (:authors ("USAMI Kenta" . "tadsan@zonu.me")) (:maintainer "USAMI Kenta" . "tadsan@zonu.me"))]) (pixie-mode . [(20180626 541) ((clojure-mode (3 0 1)) (inf-clojure (1 0 0))) "Major mode for Pixie-lang" single ((:commit . "a40c2632cfbe948852a5cdcfd44e6a65db11834d") (:authors ("John Walker" . "john.lou.walker@gmail.com")) (:maintainer "John Walker" . "john.lou.walker@gmail.com") (:url . "https://github.com/johnwalker/pixie-mode"))]) (pivotal-tracker . [(20170720 1516) nil "Interact with Pivotal Tracker through its API" single ((:commit . "0311d117037c74512149a4a78b269c2e46d7dfba") (:authors ("John Andrews")) (:maintainer "John Andrews") (:url . "http://github.com/jxa/pivotal-tracker"))]) (pippel . [(20180710 856) ((emacs (25 1)) (s (1 11 0)) (dash (2 12 0))) "Frontend to python package manager pip" tar ((:commit . "21a5200e8e5ccaa1911abb4ebf090b76ca839756") (:authors ("Fritz Stelzer" . "brotzeitmacher@gmail.com")) (:maintainer "Fritz Stelzer" . "brotzeitmacher@gmail.com") (:url . "https://github.com/brotzeitmacher/pippel"))]) (pipenv . [(20180719 547) ((emacs (25 1)) (f (0 19 0)) (s (1 12 0))) "A Pipenv porcelain." single ((:commit . "5582bf60577de74e6301871c6b77ac86b6ce1970") (:authors ("Paul Walsh" . "paulywalsh@gmail.com")) (:maintainer "Paul Walsh" . "paulywalsh@gmail.com") (:url . "https://github.com/pwalsh/pipenv.el"))]) (pip-requirements . [(20180602 1734) ((dash (2 8 0))) "A major mode for editing pip requirements files." single ((:commit . "4eff2953317272e145649effb1956081a31645ee") (:authors ("Wilfred Hughes" . "me@wilfred.me.uk")) (:maintainer "Wilfred Hughes" . "me@wilfred.me.uk"))]) (pinyinlib . [(20170827 2142) nil "Convert first letter of Pinyin to Simplified/Traditional Chinese characters" single ((:commit . "45f05d3dbb4fe957f7ab332ca6f94675848b6aa3") (:keywords "extensions") (:authors ("Junpeng Qiu" . "qjpchmail@gmail.com")) (:maintainer "Junpeng Qiu" . "qjpchmail@gmail.com"))]) (pinyin-search . [(20160515 358) ((pinyinlib (0 1 0))) "Search Chinese by Pinyin" single ((:commit . "2e877a76851009d41bde66eb33182a03a7f04262") (:keywords "chinese" "search") (:authors ("Chunyang Xu" . "xuchunyang56@gmail.com")) (:maintainer "Chunyang Xu" . "xuchunyang56@gmail.com") (:url . "https://github.com/xuchunyang/pinyin-search.el"))]) (pinyin . [(20180620 1241) ((cl-lib (0 5)) (emacs (24))) "Convert Hanzi to Pinyin (汉字转拼音)" tar ((:commit . "a325e790e9dd7c5028c4c8d110b08e9d78227382") (:keywords "extensions") (:authors ("Xu Chunyang" . "mail@xuchunyang.me")) (:maintainer "Xu Chunyang" . "mail@xuchunyang.me") (:url . "https://github.com/xuchunyang/pinyin.el"))]) (pinot . [(20140211 2026) nil "Emacs interface to pinot-search" tar ((:commit . "67fda555a155b22bb2ce44ba618b4bd6fc5f144a") (:authors ("Takafumi Arakaki <aka.tkf at gmail.com>")) (:maintainer "Takafumi Arakaki <aka.tkf at gmail.com>"))]) (pinboard-popular . [(20180511 1726) ((loop (1 4))) "Displays links from the pinboard.in popular page." single ((:commit . "c0bc76cd35f8ecf34723c64a702b82eec2751318") (:keywords "pinboard") (:url . "https://github.com/asimpson/pinboard-popular"))]) (pinboard-api . [(20140324 1148) nil "Rudimentary http://pinboard.in integration" single ((:commit . "b7b5214d0c35178f8dca08cf22d6ef3c21f0fce4") (:keywords "pinboard" "www") (:authors ("Danie Roux" . "danie@danieroux.com")) (:maintainer "Danie Roux" . "danie@danieroux.com") (:url . "https://github.com/danieroux/pinboard-api-el"))]) (pillar . [(20141112 1811) ((makey (0 3))) "Major mode for editing Pillar files" tar ((:commit . "13a7f676544cc66005ccd8e6fc1c25e4ccd6f909") (:keywords "markup" "major-mode") (:authors ("Damien Cassou" . "damien.cassou@gmail.com")) (:maintainer "Damien Cassou" . "damien.cassou@gmail.com") (:url . "http://github.com/DamienCassou/pillar-mode"))]) (pig-snippets . [(20130913 624) ((yasnippet (0 8 0))) "Snippets for pig-mode" tar ((:commit . "4c6c6e1b1bb719d8adc6c47cc24665f6fe558959"))]) (pig-mode . [(20180520 1400) nil "Major mode for Pig files" single ((:commit . "4c6c6e1b1bb719d8adc6c47cc24665f6fe558959") (:maintainer "David A. Shamma"))]) (picpocket . [(20180610 1059) ((emacs (24 4))) "Image viewer" single ((:commit . "ce4b6ed088384f2414af82e8e4eae5b92c2874bf") (:keywords "multimedia") (:authors ("Johan Claesson" . "johanclaesson@bredband.net")) (:maintainer "Johan Claesson" . "johanclaesson@bredband.net") (:url . "https://github.com/johanclaesson/picpocket"))]) (picolisp-mode . [(20150516 855) nil "Major mode for PicoLisp programming." single ((:commit . "1a537b14090813f46cbba54636d40365e1a8067e") (:keywords "picolisp" "lisp" "programming") (:authors ("Alexis" . "flexibeast@gmail.com")) (:maintainer "Alexis" . "flexibeast@gmail.com") (:url . "https://github.com/flexibeast/picolisp-mode"))]) (pickle . [(20180628 237) ((emacs (25 1)) (cl-lib (0 6 1))) "Major mode for editing cucumber gherkin files." single ((:commit . "568570b7d376026fbcb7c3df1ad8f605bd14c820") (:keywords "languages" "cucumber" "gherkin") (:authors ("Matthew Carter" . "m@ahungry.com")) (:maintainer "Matthew Carter" . "m@ahungry.com") (:url . "https://github.com/ahungry/pickle-mode"))]) (pianobar . [(20180417 104) nil "thin wrapper for Pianobar, a Pandora Radio client" single ((:commit . "3154c4cb7401017fd441fcd6a7a0b669a4406882") (:authors ("Aaron Griffith" . "aargri@gmail.com")) (:maintainer "Aaron Griffith" . "aargri@gmail.com") (:url . "http://github.com/agrif/pianobar.el"))]) (phpunit . [(20180829 1438) ((s (1 12 0)) (f (0 19 0)) (pkg-info (0 6)) (cl-lib (0 5)) (emacs (24 3))) "Launch PHP unit tests using phpunit" tar ((:commit . "fe6bc91c3bd8b329c6d26ad883a025f06b5121ee") (:keywords "tools" "php" "tests" "phpunit") (:authors ("Nicolas Lamirault" . "nicolas.lamirault@gmail.com") ("Eric Hansen" . "hansen.c.eric@gmail.com")) (:maintainer "Nicolas Lamirault" . "nicolas.lamirault@gmail.com") (:url . "https://github.com/nlamirault/phpunit.el"))]) (phpstan . [(20180721 1935) ((emacs (24 3))) "Interface to PHPStan." single ((:commit . "beac0e0e7160454d4f42162b3502a36ccf488120") (:keywords "tools" "php") (:authors ("USAMI Kenta" . "tadsan@zonu.me")) (:maintainer "USAMI Kenta" . "tadsan@zonu.me") (:url . "https://github.com/emacs-php/phpstan.el"))]) (phpcbf . [(20180519 838) ((s (1 9 0))) "Format PHP code in Emacs using PHP_CodeSniffer's phpcbf" single ((:commit . "a31020fc4c5add7339e009faea66894dc02a77f1") (:keywords "tools" "php") (:authors ("nishimaki10")) (:maintainer "nishimaki10") (:url . "https://github.com/nishimaki10/emacs-phpcbf"))]) (phpactor . [(20180823 1138) ((emacs (24 3)) (cl-lib (0 5)) (f (0 17))) "Interface to Phpactor" tar ((:commit . "3a37596c4f663419520f864d682250116252abcd") (:keywords "tools" "php") (:authors ("USAMI Kenta" . "tadsan@zonu.me")) (:maintainer "USAMI Kenta" . "tadsan@zonu.me") (:url . "https://github.com/emacs-php/phpactor.el"))]) (php-scratch . [(20161103 2217) ((emacs (24 3)) (s (1 11 0)) (php-mode (1 17 0))) "A scratch buffer to interactively evaluate php code" single ((:commit . "3aa66d1d53b84b779374edff7a7e6b5f2cd7575d") (:authors ("Tijs Mallaerts" . "tijs.mallaerts@gmail.com")) (:maintainer "Tijs Mallaerts" . "tijs.mallaerts@gmail.com"))]) (php-runtime . [(20180110 1734) ((emacs (25)) (cl-lib (0 5))) "Language binding bridge to PHP" single ((:commit . "fa4312863245511462b75cb31df2f8558288f4df") (:keywords "processes" "php") (:authors ("USAMI Kenta" . "tadsan@zonu.me")) (:maintainer "USAMI Kenta" . "tadsan@zonu.me") (:url . "https://github.com/emacs-php/php-runtime.el"))]) (php-refactor-mode . [(20171124 635) nil "Minor mode to quickly and safely perform common refactorings" single ((:commit . "7a794b0618df2882b1bd586fdd698dba0bc5130d") (:keywords "php" "refactor") (:authors ("Matthew M. Keeler" . "keelerm84@gmail.com")) (:maintainer "Matthew M. Keeler" . "keelerm84@gmail.com") (:url . "https://github.com/keelerm84/php-refactor-mode.el"))]) (php-mode . [(20180829 520) ((emacs (24 3)) (cl-lib (0 5))) "Major mode for editing PHP code" tar ((:commit . "1f04813f46219e626b385d0d96abefad914bfae0") (:keywords "languages" "php") (:authors ("Eric James Michael Ritz")) (:maintainer "USAMI Kenta" . "tadsan@zonu.me") (:url . "https://github.com/emacs-php/php-mode"))]) (php-eldoc . [(20140202 1941) nil "eldoc backend for php" tar ((:commit . "df05064146b884d9081e10657e32dc480f070cfe") (:authors ("sabof")) (:maintainer "sabof") (:url . "https://github.com/sabof/php-eldoc"))]) (php-cs-fixer . [(20170506 1833) ((cl-lib (0 5))) "php-cs-fixer wrapper." single ((:commit . "ca2c075a22ad156c336d2aa093fb6394c9f6c112") (:keywords "languages" "php") (:authors ("Philippe Ivaldi for OVYA")) (:maintainer "Philippe Ivaldi for OVYA") (:url . "https://github.com/OVYA/php-cs-fixer"))]) (php-boris-minor-mode . [(20140209 1835) ((php-boris (0 0 1)) (highlight (0))) "a minor mode to evaluate PHP code in the Boris repl" single ((:commit . "c70e176dd6545f2d42ca3427e87b469635616d8a") (:keywords "php" "repl" "eval") (:authors ("steckerhalter")) (:maintainer "steckerhalter") (:url . "https://github.com/steckerhalter/php-boris-minor-mode"))]) (php-boris . [(20130527 821) nil "Run boris php REPL" single ((:commit . "f2faebf610c917f7091f7ec0cd97645629c4f819") (:keywords "php" "commint" "repl" "boris") (:authors ("Tom Regner")) (:maintainer "Tom Regner" . "tom@goochesa.de"))]) (php-auto-yasnippets . [(20170331 114) ((php-mode (1 11)) (yasnippet (0 8 0))) "Creates snippets for PHP functions" tar ((:commit . "03e1f0899c081813901ac15c2f7a675a37cca9f5") (:authors ("Eric James Michael Ritz")) (:maintainer "Eric James Michael Ritz") (:url . "https://github.com/ejmr/php-auto-yasnippets"))]) (phoenix-dark-pink-theme . [(20170729 1403) nil "Originally a port of the Sublime Text 2 theme" single ((:commit . "4defbb76b00c1a29f060813898578152d6be623d") (:authors ("J Irving" . "j@lollyshouse.ca")) (:maintainer "J Irving" . "j@lollyshouse.ca") (:url . "http://github.com/j0ni/phoenix-dark-pink"))]) (phoenix-dark-mono-theme . [(20170729 1406) nil "Monochromatic version of the Phoenix theme" single ((:commit . "a54f515d162148bcb38676980bc2316adb3d7b8b") (:authors ("J Irving" . "j@lollyshouse.ca")) (:maintainer "J Irving" . "j@lollyshouse.ca") (:url . "http://github.com/j0ni/phoenix-dark-mono"))]) (phi-search-migemo . [(20170618 921) ((phi-search (2 2 0)) (migemo (1 9 1))) "migemo extension for phi-search" single ((:commit . "308909ebfc8003d16673f97ca9eb26a667b72969") (:authors ("zk_phi")) (:maintainer "zk_phi") (:url . "http://hins11.yu-yake.com/"))]) (phi-search-mc . [(20160324 1503) ((phi-search (2 0 0)) (multiple-cursors (1 2 1))) "multiple-cursors extension for phi-search" single ((:commit . "7aa671910f766437089aec26c3aa7814222d1356") (:keywords "search" "cursors") (:authors ("Akinori MUSHA" . "knu@iDaemons.org")) (:maintainer "Akinori MUSHA" . "knu@iDaemons.org") (:url . "https://github.com/knu/phi-search-mc.el"))]) (phi-search-dired . [(20150405 714) ((phi-search (2 2 0))) "interactive filtering for dired powered by phi-search" single ((:commit . "162a5e4507c72512affae22744bb606a906d4193") (:authors ("zk_phi")) (:maintainer "zk_phi") (:url . "http://hins11.yu-yake.com/"))]) (phi-search . [(20180322 129) nil "another incremental search & replace, compatible with \"multiple-cursors\"" tar ((:commit . "9a089b8271cb1cff9640848850298c9ec855286c") (:authors ("zk_phi")) (:maintainer "zk_phi") (:url . "http://hins11.yu-yake.com/"))]) (phi-rectangle . [(20151208 654) nil "another rectangle-mark command (rewrite of rect-mark)" single ((:commit . "0c12716afc71d803d1f39417469521dc465762d9") (:authors ("zk_phi")) (:maintainer "zk_phi") (:url . "http://hins11.yu-yake.com/"))]) (phi-grep . [(20170606 807) ((cl-lib (0 1))) "Interactively-editable recursive grep implementation in elisp" single ((:commit . "ab9bd8d25e751a9cbfa108b49839293230b6e8b5") (:authors ("zk_phi")) (:maintainer "zk_phi") (:url . "http://github.com/zk-phi/phi-grep"))]) (phi-autopair . [(20170217 353) ((paredit (20))) "another simple-minded autopair implementation" single ((:commit . "3c7556779c3a53b045f5df33ae2a0c67469cbf60") (:authors ("zk_phi")) (:maintainer "zk_phi") (:url . "http://hins11.yu-yake.com/"))]) (phan . [(20180528 339) ((emacs (24)) (composer (0 0 8)) (f (0 17))) "Utility functions for Phan (PHP static analizer)" single ((:commit . "6b077b3421a0b2c0b98a6906b8ab0d14d9d7bf50") (:keywords "tools" "php") (:authors ("USAMI Kenta" . "tadsan@pixiv.com")) (:maintainer "USAMI Kenta" . "tadsan@pixiv.com") (:url . "https://github.com/emacs-php/phan.el"))]) (phabricator . [(20160510 1425) ((emacs (24 4)) (dash (1 0)) (projectile (0 13 0)) (s (1 10 0)) (f (0 17 2))) "Phabricator/Arcanist helpers for Emacs." single ((:commit . "d09d6f059aea92d3b11c68664a5e80c901182ab8") (:keywords "phabricator" "arcanist" "diffusion") (:authors ("Andrew Tulloch")) (:maintainer "Andrew Tulloch") (:url . "https://github.com/ajtulloch/phabricator.el"))]) (ph . [(20161029 1522) ((emacs (24 3))) "A global minor mode for managing multiple projects." tar ((:commit . "ed80dad9211583ed0db633448b3624c99b7fac23"))]) (pgdevenv . [(20150105 2236) nil "Manage your PostgreSQL development envs" tar ((:commit . "7f1d5bc734750aca98cf67a9491cdbd5615fd132") (:keywords "emacs" "postgresql" "development" "environment" "shell" "debug" "gdb") (:authors ("Dimitri Fontaine" . "dim@tapoueh.org")) (:maintainer "Dimitri Fontaine" . "dim@tapoueh.org"))]) (pg . [(20130731 2142) nil "Emacs Lisp interface to the PostgreSQL RDBMS" single ((:commit . "4f6516ec3946d95dcef49abb6703cc89ecb5183d") (:keywords "data" "comm" "database" "postgresql") (:authors ("Eric Marsden" . "emarsden@laas.fr")) (:maintainer "Helmut Eller" . "heller@common-lisp.net"))]) (pfuture . [(20180715 1224) ((emacs (25 2))) "a simple wrapper around asynchronous processes" single ((:commit . "e39d0d2953a5db7d9f567596865239012e506ac4") (:authors ("Alexander Miller" . "alexanderm@web.de")) (:maintainer "Alexander Miller" . "alexanderm@web.de") (:url . "https://github.com/Alexander-Miller/pfuture"))]) (perspeen . [(20171203 1021) ((emacs (25 0)) (powerline (2 4))) "An package for multi-workspace" tar ((:commit . "edb70c530bda50ff3d1756e32a703d5fef5e5480") (:keywords "lisp") (:authors ("Peng Li" . "seudut@gmail.com")) (:maintainer "Peng Li" . "seudut@gmail.com") (:url . "https://github.com/seudut/perspeen"))]) (perspective . [(20180717 2103) ((cl-lib (0 5))) "switch between named \"perspectives\" of the editor" single ((:commit . "874aa4173b1bea7349df2375396cee146ba8d7c7") (:keywords "workspace" "convenience" "frames") (:authors ("Natalie Weizenbaum" . "nex342@gmail.com")) (:maintainer "Natalie Weizenbaum" . "nex342@gmail.com") (:url . "http://github.com/nex3/perspective-el"))]) (persp-projectile . [(20180616 1944) ((perspective (1 9)) (projectile (0 11 0)) (cl-lib (0 3))) "Perspective integration with Projectile" single ((:commit . "3a79cb26e290b478e83aa7795146fb1759092d14") (:keywords "project" "convenience") (:authors ("Daniel Wu")) (:maintainer "Daniel Wu"))]) (persp-mode-projectile-bridge . [(20170315 1120) ((persp-mode (2 9)) (projectile (0 13 0)) (cl-lib (0 5))) "persp-mode + projectile integration." single ((:commit . "f6453cd7b8b4352c06e771706f2c5b7e2cdff1ce") (:keywords "persp-mode" "projectile") (:authors ("Constantin Kulikov (Bad_ptr)" . "zxnotdead@gmail.com")) (:maintainer "Constantin Kulikov (Bad_ptr)" . "zxnotdead@gmail.com") (:url . "https://github.com/Bad-ptr/persp-mode-projectile-bridge.el"))]) (persp-mode . [(20180604 1718) nil "windows/buffers sets shared among frames + save/load." single ((:commit . "cc1d16aeb17f45d7141fcdc45f8bbffa03b3127f") (:keywords "perspectives" "session" "workspace" "persistence" "windows" "buffers" "convenience") (:authors ("Constantin Kulikov (Bad_ptr)" . "zxnotdead@gmail.com")) (:maintainer "Constantin Kulikov (Bad_ptr)" . "zxnotdead@gmail.com") (:url . "https://github.com/Bad-ptr/persp-mode.el"))]) (persp-fr . [(20180801 727) ((emacs (25 0)) (persp-mode (2 9 6)) (dash (2 13 0))) "In persp-mode, show perspective list in the GUI window title" single ((:commit . "3f536440b120499464106fd25f182d7580192870") (:keywords "perspectives" "workspace" "windows" "convenience") (:authors ("Francesc Rocher" . "francesc.rocher@gmail.com")) (:maintainer "Francesc Rocher" . "francesc.rocher@gmail.com") (:url . "http://github.com/rocher/persp-fr"))]) (persistent-soft . [(20150223 1853) ((pcache (0 3 1)) (list-utils (0 4 2))) "Persistent storage, returning nil on failure" single ((:commit . "a1e0ddf2a12a6f18cab565dee250f070384cbe02") (:keywords "data" "extensions") (:authors ("Roland Walker" . "walker@pobox.com")) (:maintainer "Roland Walker" . "walker@pobox.com") (:url . "http://github.com/rolandwalker/persistent-soft"))]) (persistent-scratch . [(20180426 111) ((emacs (24))) "Preserve the scratch buffer across Emacs sessions" single ((:commit . "0bfd717d28ce9e262741b06341c61306602c7711") (:authors ("Fanael Linithien" . "fanael4@gmail.com")) (:maintainer "Fanael Linithien" . "fanael4@gmail.com") (:url . "https://github.com/Fanael/persistent-scratch"))]) (persistent-overlays . [(20161128 700) nil "Minor mode to store selected overlays to be loaded later" tar ((:commit . "f563c8b966edc78c9d806661c4eb80e4781c4eab") (:keywords "overlays" "persistent") (:authors ("Michael Neilly" . "mneilly@yahoo.com")) (:maintainer "Michael Neilly" . "mneilly@yahoo.com") (:url . "https://github.com/mneilly/Emacs-Persistent-Overlays"))]) (perlbrew . [(20161109 709) nil "A perlbrew wrapper for Emacs" single ((:commit . "3a3406c3307c92aa30f9400d430925c434a3b6f0") (:keywords "emacs" "perl") (:authors ("Kentaro Kuribayashi" . "kentarok@gmail.com")) (:maintainer "Kentaro Kuribayashi" . "kentarok@gmail.com"))]) (perl6-mode . [(20180619 1159) ((emacs (24 4)) (pkg-info (0 1))) "Major mode for editing Perl 6 code" tar ((:commit . "88de065795d6863b23b6042576b9e90f8cbf8798") (:keywords "languages") (:authors ("Hinrik Örn Sigurðsson" . "hinrik.sig@gmail.com")) (:maintainer "Hinrik Örn Sigurðsson" . "hinrik.sig@gmail.com") (:url . "https://github.com/hinrik/perl6-mode"))]) (per-buffer-theme . [(20160318 2201) ((cl-lib (0 5))) "Change theme according to buffer name or major mode." single ((:keywords "themes") (:authors ("Iñigo Serna" . "inigoserna@gmail.com")) (:maintainer "Iñigo Serna" . "inigoserna@gmail.com") (:url . "https://bitbucket.com/inigoserna/per-buffer-theme.el"))]) (pelican-mode . [(20180604 2207) ((emacs (25))) "Minor mode for editing Pelican sites" single ((:commit . "209ad24318e1f28675da430aa10ef3467694b9ac") (:keywords "convenience" "editing") (:authors ("Joe Wreschnig" . "joe.wreschnig@gmail.com")) (:maintainer "Joe Wreschnig" . "joe.wreschnig@gmail.com") (:url . "https://git.korewanetadesu.com/pelican-mode.git"))]) (peg . [(20150708 641) nil "Parsing Expression Grammars in Emacs Lisp" single ((:commit . "081efeca91d790c7fbc90871ac22c40935f4833b"))]) (peep-dired . [(20160321 2237) nil "Peep at files in another window from dired buffers" single ((:commit . "c88a9a3050197840edfe145f11e0bb9488de32f4") (:keywords "files" "convenience") (:authors ("Adam Sokolnicki" . "adam.sokolnicki@gmail.com")) (:maintainer "Adam Sokolnicki" . "adam.sokolnicki@gmail.com"))]) (peek-mode . [(20130620 1946) ((elnode (0 9 8 1))) "Serve buffers live over HTTP with elnode backend" tar ((:commit . "55a7dd011375330c7d57322257a5167516702c71") (:authors ("Erik Iverson" . "erik@sigmafield.org")) (:maintainer "Erik Iverson" . "erik@sigmafield.org") (:url . "https://github.com/erikriverson/peek-mode"))]) (peacock-theme . [(20170808 1320) ((emacs (24 0))) "an Emacs 24 theme based on Peacock (tmTheme)" single ((:commit . "9e46fbfb562b6e26c6e3d6d618b044b3694da4c8") (:authors ("Jason Milkins")) (:maintainer "Jason Milkins") (:url . "https://github.com/emacsfodder/tmtheme-to-deftheme"))]) (pdf-tools . [(20180428 1527) ((emacs (24 3)) (tablist (0 70)) (let-alist (1 0 4))) "Support library for PDF documents." tar ((:commit . "8aa7aecf19090692d910036f256f67c1b8968a75") (:keywords "files" "multimedia") (:authors ("Andreas Politz" . "politza@fh-trier.de")) (:maintainer "Andreas Politz" . "politza@fh-trier.de"))]) (pdb-mode . [(20150128 1751) nil "Major mode for editing Protein Data Bank files" single ((:commit . "855fb18ebb73b5df30c8d7677c2bcd0f361b138a") (:keywords "data" "pdb") (:authors (nil . "charles.bond@uwa.edu.au")) (:maintainer nil . "aix.bing@gmail.com") (:url . "http://bondxray.org/software/pdb-mode/"))]) (pcsv . [(20150220 1131) nil "Parser of csv" single ((:commit . "798e0933f8d0818beb17aebf3b1056bbf74e03d0") (:keywords "data") (:authors ("Masahiro Hayashi" . "mhayashi1120@gmail.com")) (:maintainer "Masahiro Hayashi" . "mhayashi1120@gmail.com") (:url . "https://github.com/mhayashi1120/Emacs-pcsv/raw/master/pcsv.el"))]) (pcre2el . [(20161120 2103) ((emacs (24)) (cl-lib (0 3))) "regexp syntax converter" single ((:commit . "0b5b2a2c173aab3fd14aac6cf5e90ad3bf58fa7d") (:authors ("joddie <jonxfield at gmail.com>")) (:maintainer "joddie <jonxfield at gmail.com>") (:url . "https://github.com/joddie/pcre2el"))]) (pcomplete-extension . [(20180707 455) ((emacs (24)) (cl-lib (0 5))) "additional completion for pcomplete" single ((:commit . "bb941272b54f49f780819f7ce4fd2c802de9a0da") (:authors ("Thierry Volpiatto" . "thierry.volpiatto@gmail.com")) (:maintainer "Thierry Volpiatto" . "thierry.volpiatto@gmail.com") (:url . "https://github.com/thierryvolpiatto/pcomplete-extension"))]) (pcmpl-pip . [(20171201 833) ((s (1 12 0)) (f (0 19 0)) (seq (2 15))) "pcomplete for pip" single ((:commit . "8b001b579fc015f80ee0e4f3211058b830bf7c47") (:keywords "pcomplete" "pip" "python" "tools") (:authors ("Wei Zhao" . "kaihaosw@gmail.com")) (:maintainer "Wei Zhao" . "kaihaosw@gmail.com"))]) (pcmpl-homebrew . [(20170111 9) nil "pcomplete for homebrew" single ((:commit . "d001520fec4715c9a4c73f02fd948bac371cc50a") (:keywords "pcomplete" "homebrew" "tools" "cask" "services") (:authors ("hiddenlotus" . "kaihaosw@gmail.com")) (:maintainer "hiddenlotus" . "kaihaosw@gmail.com"))]) (pcmpl-git . [(20170121 59) nil "pcomplete for git" tar ((:commit . "9472ac70baeda025ef7becd1cf141d72aec93f32") (:keywords "tools") (:authors ("Leo Liu" . "sdl.web@gmail.com")) (:maintainer "Leo Liu" . "sdl.web@gmail.com"))]) (pcmpl-args . [(20120912 524) nil "Enhanced shell command completion" single ((:commit . "2ba03b3125ada8037585e545b88bd85b79da5c37") (:keywords "abbrev" "completion" "convenience" "processes" "terminals" "unix") (:authors ("Jonathan Waltman" . "jonathan.waltman@gmail.com")) (:maintainer "Jonathan Waltman" . "jonathan.waltman@gmail.com") (:url . "https://github.com/JonWaltman/pcmpl-args.el"))]) (pcap-mode . [(20161025 1448) ((emacs (24 3))) "Major mode for working with PCAP files" single ((:commit . "52780669af0ade136f84d73f21b4dbb7ab655416") (:keywords "pcap" "packets" "tcpdump" "wireshark" "tshark") (:authors ("Aaron Conole" . "aconole@bytheb.org")) (:maintainer "Aaron Conole" . "aconole@bytheb.org"))]) (pcache . [(20170105 2214) ((eieio (1 3))) "persistent caching for Emacs." single ((:commit . "1f8086077d770e524492e6fa59b07856e85a6fea") (:authors ("Yann Hodique" . "yann.hodique@gmail.com")) (:maintainer "Yann Hodique" . "yann.hodique@gmail.com"))]) (pc-bufsw . [(20180107 1840) nil "PC style quick buffer switcher" single ((:commit . "b99ba484e18ebf2b88654704146746490bb7625f") (:keywords "buffer") (:authors ("Igor Bukanov" . "igor@mir2.org")) (:maintainer "Igor Bukanov" . "igor@mir2.org") (:url . "https://github.com/ibukanov/pc-bufsw"))]) (pbcopy . [(20150225 459) nil "Emacs Interface to pbcopy" single ((:commit . "338f7245746b5de1bb96c5cc2b32bfd9b5d83272") (:keywords "mac" "osx" "pbcopy") (:authors ("Daniel Nelson")) (:maintainer "Daniel Nelson") (:url . "https://github.com/jkp/pbcopy.el"))]) (paxedit . [(20160730 1727) ((cl-lib (0 5)) (paredit (23))) "Structured, Context Driven LISP Editing and Refactoring" single ((:commit . "09f3d5aeb108937a801e77ef413e29eaa4ecc4be") (:keywords "lisp" "refactoring" "context") (:authors ("Mustafa Shameem")) (:maintainer "Mustafa Shameem") (:url . "https://github.com/promethial/paxedit"))]) (pathify . [(20160423 846) nil "Symlink your scripts into a PATH directory" single ((:commit . "401b184c743694a60b3bc4273fc43de05cd5ac4b") (:keywords "convenience") (:authors ("Alex Kost" . "alezost@gmail.com")) (:maintainer "Alex Kost" . "alezost@gmail.com") (:url . "https://gitlab.com/alezost-emacs/pathify"))]) (path-headerline-mode . [(20140423 1332) nil "Displaying file path on headerline." single ((:commit . "b5b2725c6a8b1cb592fc242b7dbbd54b4dff2e69") (:keywords "headerline") (:authors ("7696122")) (:maintainer "7696122") (:url . "https://github.com/7696122/path-headerline-mode"))]) (pastery . [(20171114 349) ((emacs (24 4)) (request (0 2 0))) "paste snippets to pastery.net." tar ((:commit . "4493be98b743b4d062cb4e00760125e394a55022") (:keywords "tools") (:authors ("Bruno Dias" . "dias.h.bruno@gmail.com")) (:maintainer "Bruno Dias" . "dias.h.bruno@gmail.com") (:url . "https://github.com/diasbruno/pastery.el"))]) (pastelmac-theme . [(20151031 236) ((emacs (24 1))) "a soothing theme with a pastel color palette" single ((:commit . "bead21741e3f46f6506e8aef4469d4240a819389") (:keywords "themes") (:authors ("Brian Mastenbrook" . "brian@mastenbrook.net")) (:maintainer "Brian Mastenbrook" . "brian@mastenbrook.net") (:url . "https://github.com/bmastenbrook/pastelmac-theme-el"))]) (pastehub . [(20140615 620) nil "A client for the PasteHub cloud service" single ((:commit . "37b045c67659c078f1517d0fbd5282dab58dca23") (:authors ("Kiyoka Nishiyama")) (:maintainer "Kiyoka Nishiyama") (:url . "https://github.com/kiyoka/pastehub"))]) (pastebin . [(20101125 2002) nil "A simple interface to the www.pastebin.com webservice" single ((:commit . "8e9a829298ce0f747ab80758aa26caeb2af6cb30"))]) (paste-of-code . [(20170709 2355) ((emacs (24 3)) (request (0 2 0))) "paste code on https://paste.ofcode.org" single ((:commit . "92d258e8ec98598d847ecab82903f9224c7c2050") (:keywords "lisp") (:authors ("Bernhard Specht" . "bernhard@specht.net")) (:maintainer "Bernhard Specht" . "bernhard@specht.net"))]) (password-vault . [(20160126 1820) ((cl-lib (0 2)) (emacs (24))) "A Password manager for Emacs." single ((:commit . "dc56e6c2f5da66f1ab63736cecf08fb2c6c2b30f") (:keywords "password" "productivity") (:authors ("Javier \"PuercoPop\" Olaechea" . "pirata@gmail.com")) (:maintainer "Javier \"PuercoPop\" Olaechea" . "pirata@gmail.com") (:url . "http://github.com/PuercoPop/password-vault"))]) (password-store-otp . [(20180815 610) ((emacs (25)) (s (1 9 0)) (password-store (0 1))) "Password store (pass) OTP extension support" single ((:commit . "1819cd88463cd98a5be9a63273b09202dc2bba63") (:keywords "tools" "pass") (:authors ("Daniel Barreto")) (:maintainer "Daniel Barreto") (:url . "https://github.com/volrath/password-store-otp.el"))]) (password-store . [(20170829 2333) ((emacs (24)) (f (0 11 0)) (s (1 9 0)) (with-editor (2 5 11))) "Password store (pass) support" single ((:commit . "d68d9c50db4cdba32266c52e6546f1d5181948db") (:keywords "tools" "pass" "password" "password-store") (:authors ("Svend Sorensen" . "svend@svends.net")) (:maintainer "Svend Sorensen" . "svend@svends.net") (:url . "https://www.passwordstore.org/"))]) (password-mode . [(20170412 629) nil "Hide password text using overlays" single ((:commit . "ed764a4ec1011526457c71b7c37fa9a659a866ab") (:keywords "docs" "password" "passphrase") (:authors ("Jürgen Hötzel" . "juergen@archlinux.org")) (:maintainer "Jürgen Hötzel" . "juergen@archlinux.org"))]) (password-generator . [(20150222 2040) nil "Password generator for humans. Good, Bad, Phonetic passwords included." single ((:commit . "c8193d5e963bda0a2f8e51fd4a94dcf37c76f282") (:authors ("Zargener" . "zargener@gmail.com")) (:maintainer "Zargener" . "zargener@gmail.com") (:url . "http://github.com/zargener/emacs-password-genarator"))]) (passthword . [(20141201 923) ((cl-lib (0 5))) "Simple password manager" single ((:commit . "30bace842eaaa6b48cb2251fb84868ebca0467d6") (:authors ("Peter Stiernström" . "peter@stiernstrom.se")) (:maintainer "Peter Stiernström" . "peter@stiernstrom.se"))]) (passmm . [(20180622 2326) ((emacs (24 4)) (password-store (0))) "A minor mode for pass (Password Store)." single ((:commit . "898709c63130d6c0422af544ebac64eae04d24ac") (:authors ("Peter Jones" . "pjones@devalot.com")) (:maintainer "Peter Jones" . "pjones@devalot.com") (:url . "https://github.com/pjones/passmm"))]) (pass . [(20180201 1251) ((emacs (24 3)) (password-store (0 1)) (password-store-otp (0 1 5)) (f (0 17))) "Major mode for password-store.el" single ((:commit . "da08fed8dbe1bac980088d47b01f90154dbb8d8b") (:keywords "password-store" "password" "keychain") (:authors ("Nicolas Petton" . "petton.nicolas@gmail.com") ("Damien Cassou" . "damien@cassou.me")) (:maintainer "Nicolas Petton" . "petton.nicolas@gmail.com"))]) (pasp-mode . [(20180404 1700) ((emacs (24 3))) "- A major mode for editing Answer Set Programs." single ((:commit . "59385eb0e8ebcfc8c11dd811fb145d4b0fa3cc92") (:keywords "asp" "pasp" "answer set programs" "potassco answer set programs" "major mode" "languages") (:authors ("Henrik Jürges" . "juerges.henrik@gmail.com")) (:maintainer "Henrik Jürges" . "juerges.henrik@gmail.com") (:url . "https://github.com/santifa/pasp-mode"))]) (parseclj . [(20180602 2006) ((emacs (25)) (a (0 1 0 -3 4))) "Clojure/EDN parser" tar ((:commit . "dc0d165b0a8633f5b11ed9175a6e421c52f4d314") (:keywords "lisp") (:authors ("Arne Brasseur" . "arne@arnebrasseur.net")) (:maintainer "Arne Brasseur" . "arne@arnebrasseur.net"))]) (parsec . [(20180730 16) ((emacs (24)) (cl-lib (0 5))) "Parser combinator library" single ((:commit . "2cbbbc2254aa7bcaa4fb5e07c8c1bf2f381dba26") (:keywords "extensions") (:authors ("Junpeng Qiu" . "qjpchmail@gmail.com")) (:maintainer "Junpeng Qiu" . "qjpchmail@gmail.com") (:url . "https://github.com/cute-jumper/parsec.el"))]) (parsebib . [(20180116 1427) ((emacs (24 3))) "A library for parsing bib files" single ((:commit . "683c970a6fb51591bc88ee80e295fedee876e044") (:keywords "text" "bibtex") (:authors ("Joost Kremers" . "joostkremers@fastmail.fm")) (:maintainer "Joost Kremers" . "joostkremers@fastmail.fm"))]) (parse-csv . [(20160512 1723) nil "Parse strings with CSV fields into s-expressions" single ((:commit . "96bef1ffbc89ea12d13311c9fa239c5c3e864890") (:keywords "csv") (:authors ("Edward Marco Baringer (Common Lisp)") ("Matt Curtis" . "matt.r.curtis@gmail.com")) (:maintainer "Matt Curtis" . "matt.r.curtis@gmail.com") (:url . "https://github.com/mrc/el-csv"))]) (parinfer . [(20180904 844) ((dash (2 13 0)) (cl-lib (0 5))) "Simpler Lisp editing" tar ((:commit . "a7c041454e05ec2b88333a73e72debaa671ed596") (:keywords "parinfer") (:authors ("Shi Tianshu")) (:maintainer "Shi Tianshu") (:url . "https://github.com/DogLooksGood/parinfer-mode"))]) (parent-mode . [(20150824 2300) nil "get major mode's parent modes" single ((:commit . "db692cf08deff2f0e973e6e86e26662b44813d1b") (:authors ("Fanael Linithien" . "fanael4@gmail.com")) (:maintainer "Fanael Linithien" . "fanael4@gmail.com") (:url . "https://github.com/Fanael/parent-mode"))]) (paren-face . [(20180318 2025) nil "a face for parentheses in lisp modes" single ((:commit . "a45d111153a76c481fa0b36d6172ac90e073dfc4") (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:url . "https://github.com/tarsius/paren-face"))]) (paren-completer . [(20160501 1052) ((emacs (24 3))) "Automatically, language agnostically, fill in delimiters." single ((:commit . "74183a8e13fa1266271bdcbcb4bfb29a4f915f0a") (:keywords "convenience") (:authors ("Matthew Bregg")) (:maintainer "Matthew Bregg") (:url . "https://github.com/MatthewBregg/paren-completer"))]) (paredit-menu . [(20160128 1733) ((paredit (25))) "Adds a menu to paredit.el as memory aid" single ((:commit . "cc0ae85bd819f9ebfa4f2a419ab3b2d70e39c9c8") (:keywords "paredit") (:authors ("Phillip Lord" . "phillip.lord@newcastle.ac.uk")) (:maintainer "Phillip Lord" . "phillip.lord@newcastle.ac.uk"))]) (paredit-everywhere . [(20180506 849) ((paredit (22))) "Enable some paredit features in non-lisp buffers" single ((:commit . "653d7a58fb370d5f7df367464d8d05e23a70b29d") (:keywords "languages" "convenience") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com"))]) (paredit . [(20171127 205) nil "minor mode for editing parentheses" single ((:commit . "acbe10fdd85d2e91831adf70b6a828bc7e900da0") (:keywords "lisp") (:authors ("Taylor R. Campbell" . "campbell+paredit@mumble.net")) (:maintainer "Taylor R. Campbell" . "campbell+paredit@mumble.net"))]) (paradox . [(20180216 1134) ((emacs (24 4)) (seq (1 7)) (let-alist (1 0 3)) (spinner (1 7 3)) (hydra (0 13 2))) "A modern Packages Menu. Colored, with package ratings, and customizable." tar ((:commit . "e5dd26f67ba8fa8ab1631a00ddea4117805b3fd0") (:keywords "package" "packages") (:authors ("Artur Malabarba" . "emacs@endlessparentheses.com")) (:maintainer "Artur Malabarba" . "emacs@endlessparentheses.com") (:url . "https://github.com/Malabarba/paradox"))]) (paperless . [(20180224 1245) ((emacs (24 4)) (f (0 11 0)) (s (1 10 0)) (cl-lib (0 6 1))) "A major mode for sorting and filing PDF documents." tar ((:commit . "b3b6c05da393f6b1292a3d5937bc4499baabd0b6") (:keywords "pdf" "convenience") (:authors ("Anthony Green" . "green@moxielogic.com")) (:maintainer "Anthony Green" . "green@moxielogic.com") (:url . "http://github.com/atgreen/paperless"))]) (paper-theme . [(20180429 2215) ((emacs (24))) "A minimal Emacs colour theme." single ((:commit . "05f2655321f020fd4c069d1939f0902eaa837eb4") (:keywords "theme" "paper") (:authors ("Göktuğ Kayaalp")) (:maintainer "Göktuğ Kayaalp") (:url . "https://cadadr.github.io/elisp/index.html#paper"))]) (pangu-spacing . [(20170317 857) nil "Minor-mode to add space between Chinese and English characters." single ((:commit . "a4463dbb74abdeddb6c1c132a1f8fcf67ed87498") (:authors ("coldnew" . "coldnew.tw@gmail.com")) (:maintainer "coldnew" . "coldnew.tw@gmail.com") (:url . "http://github.com/coldnew/pangu-spacing"))]) (pandoc-mode . [(20180727 2201) ((hydra (0 10 0)) (dash (2 10 0))) "Minor mode for interacting with Pandoc" tar ((:commit . "a3f25fec81022a76bc6aab236548d352b2a420cf") (:keywords "text" "pandoc") (:authors ("Joost Kremers" . "joostkremers@fastmail.fm")) (:maintainer "Joost Kremers" . "joostkremers@fastmail.fm"))]) (pandoc . [(20161128 1157) ((emacs (24 4))) "Pandoc interface" single ((:commit . "198d262d09e30448f1672338b0b5a81cf75e1eaa") (:keywords "hypermedia" "documentation" "markup" "converter") (:authors ("USAMI Kenta" . "tadsan@zonu.me")) (:maintainer "USAMI Kenta" . "tadsan@zonu.me") (:url . "https://github.com/zonuexe/pandoc.el"))]) (panda-theme . [(20180807 1143) ((emacs (24))) "Panda Theme" single ((:commit . "53b4cbb6bfdd531a8366bf1d01eede420e1f93c9") (:authors ("jamiecollinson" . "jamiecollinson@gmail.com")) (:maintainer "jamiecollinson" . "jamiecollinson@gmail.com") (:url . "https://github.com/jamiecollinson/emacs-panda-theme"))]) (pamparam . [(20180415 748) ((emacs (24 3)) (lispy (0 26 0)) (worf (0 1 0)) (hydra (0 13 4))) "Simple and fast flashcards." single ((:commit . "8fa25d06fb2ae6d992e738a10d8b2150e109d9bf") (:keywords "outlines" "hypermedia" "flashcards" "memory") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:url . "https://github.com/abo-abo/pamparam"))]) (pallet . [(20150512 702) ((dash (2 10 0)) (s (1 9 0)) (f (0 17 1)) (cask (0 7))) "A package management tool for Emacs, using Cask." tar ((:commit . "b8d0df1883224a371ac0a3bc9b9c1c4dc61e6ac0"))]) (palimpsest . [(20170119 2032) nil "Various deletion strategies when editing" single ((:commit . "e6d5944393c260ceb724462c84046cc62c9ae916") (:authors ("Daniel Szmulewicz" . "daniel.szmulewicz@gmail.com")) (:maintainer "Daniel Szmulewicz" . "daniel.szmulewicz@gmail.com"))]) (pager-default-keybindings . [(20130719 2057) ((pager (1 0))) "Add the default keybindings suggested for pager.el" single ((:commit . "dbbd49c2ac5906d1dabf9e9c832bfebc1ab405b3") (:authors ("Nathaniel Flath" . "nflath@gmail.com")) (:maintainer "Nathaniel Flath" . "nflath@gmail.com") (:url . "http://github.com/nflath/pager-default-keybindings"))]) (pager . [(20151202 120) nil "windows-scroll commands" single ((:commit . "5c791ed23f1136e04040d6f4bc9b4ca5b6dc919f") (:authors (nil . "Mikael Sjödin  --  mic@docs.uu.se")) (:maintainer nil . "Mikael Sjödin  --  mic@docs.uu.se"))]) (page-break-lines . [(20171210 831) ((emacs (24 4))) "Display ^L page breaks as tidy horizontal lines" single ((:commit . "fd3b7e38ad8747cd009ead7ef1bb150849ccc693") (:keywords "convenience" "faces") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:url . "https://github.com/purcell/page-break-lines"))]) (paganini-theme . [(20180815 1921) ((emacs (24 0))) "A colorful, dark and warm theme." single ((:commit . "255c5a2a8abee9c5935465ec42b9c3604c178c3c") (:authors ("Onur Temizkan")) (:maintainer "Onur Temizkan") (:url . "https://github.com/onurtemizkan/paganini"))]) (pact-mode . [(20180904 1553) ((emacs (24 3))) "Mode for Pact, a LISPlike smart contract language." single ((:commit . "ab967ff05dbe473e7994891b0cb5b71b85f7b8c3") (:keywords "pact" "lisp" "languages" "blockchain" "smartcontracts" "tools" "mode") (:authors ("Stuart Popejoy")) (:maintainer "Stuart Popejoy" . "stuart@kadena.io") (:url . "https://github.com/kadena-io/pact-mode"))]) (pacmacs . [(20160131 832) ((emacs (24 4)) (dash (2 11 0)) (dash-functional (1 2 0)) (cl-lib (0 5)) (f (0 18 0))) "Pacman for Emacs" tar ((:commit . "d813e9c62c2540fe619234824fc60e128c786442") (:authors ("Codingteam" . "codingteam@conference.jabber.ru")) (:maintainer "Alexey Kutepov" . "reximkut@gmail.com") (:url . "http://github.com/codingteam/pacmacs.el"))]) (packed . [(20180318 1729) ((emacs (24 3))) "package manager agnostic Emacs Lisp package utilities" single ((:commit . "c41c3dfda86ae33832ffc146923e2a4675cbacfa") (:keywords "compile" "convenience" "lisp" "package" "library") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:url . "https://github.com/emacscollective/packed"))]) (package-utils . [(20180514 1415) ((restart-emacs (0 1 1))) "Extensions for package.el" single ((:commit . "5621b95c56b55499f0463fd8b29501da25d861bd") (:keywords "package" "convenience") (:authors ("Philippe Vaucher" . "philippe.vaucher@gmail.com")) (:maintainer "Philippe Vaucher" . "philippe.vaucher@gmail.com") (:url . "https://github.com/Silex/package-utils"))]) (package-safe-delete . [(20150116 1607) ((emacs (24)) (epl (0 7 -4))) "Safely delete package.el packages" single ((:commit . "138171e4fc03c0ef05a8260cbb5cd2e114c1c194") (:authors ("Fanael Linithien" . "fanael4@gmail.com")) (:maintainer "Fanael Linithien" . "fanael4@gmail.com") (:url . "https://github.com/Fanael/package-safe-delete"))]) (package-lint . [(20180609 419) ((cl-lib (0 5)) (emacs (24))) "A linting library for elisp package authors" tar ((:commit . "318a608ff94229dfd2e953e4fd6f37bab27adfaa") (:keywords "lisp") (:authors ("Steve Purcell" . "steve@sanityinc.com") ("Fanael Linithien" . "fanael4@gmail.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:url . "https://github.com/purcell/package-lint"))]) (package-filter . [(20161122 719) nil "package archive whitelist and blacklist" single ((:commit . "bc73b41aea1d65ca44ef1593ca13126df9bbb39e") (:authors ("Donald Ephraim Curtis" . "dcurtis@milkbox.net")) (:maintainer "Donald Ephraim Curtis" . "dcurtis@milkbox.net") (:url . "https://github.com/milkypostman/package-filter"))]) (package-build . [(20180807 222) ((cl-lib (0 5))) "Tools for assembling a package archive" tar ((:commit . "dfcb7f0cdd949a55ad023fb76ce2ea66e149d762") (:keywords "tools") (:authors ("Donald Ephraim Curtis" . "dcurtis@milkbox.net")) (:maintainer "Donald Ephraim Curtis" . "dcurtis@milkbox.net"))]) (package+ . [(20170816 256) nil "Extensions for the package library." single ((:commit . "9213f6134eabc2cff5826779ced437714324c066") (:keywords "extensions" "tools") (:authors ("Ryan Davis" . "ryand-ruby@zenspider.com")) (:maintainer "Ryan Davis" . "ryand-ruby@zenspider.com") (:url . "TBA"))]) (pabbrev . [(20160320 2101) nil "Predictive abbreviation expansion" single ((:commit . "56400d5d256b42ffe45c229ea9827f026b650cf5") (:authors ("Phillip Lord" . "phillip.lord@newcastle.ac.uk")) (:maintainer "Phillip Lord" . "phillip.lord@newcastle.ac.uk"))]) (p4 . [(20150721 1937) nil "Simple Perforce-Emacs Integration" single ((:commit . "eff047caa75dbe4965defca9d1212454cdb755d5") (:authors ("Gareth Rees" . "gdr@garethrees.org")) (:maintainer "Gareth Rees" . "gdr@garethrees.org") (:url . "https://github.com/gareth-rees/p4.el"))]) (ox-twiki . [(20170803 2039) ((org (8)) (cl-lib (0 5))) "org Twiki and Foswiki export" single ((:commit . "99d0c25d56dbf75ce894a84e776ba4459208dbc2") (:keywords "org") (:authors ("Derek Feichtinger" . "derek.feichtinger@psi.ch")) (:maintainer "Derek Feichtinger" . "derek.feichtinger@psi.ch") (:url . "https://github.com/dfeich/org8-wikiexporters"))]) (ox-twbs . [(20161103 2016) nil "Bootstrap compatible HTML Back-End for Org" single ((:commit . "2414e6b1de7deb6dd2ae79a7be633fdccb9c2f28") (:keywords "org" "html" "publish" "twitter" "bootstrap") (:authors ("Carsten Dominik <carsten at orgmode dot org>") ("Jambunathan K <kjambunathan at gmail dot com>") ("Brandon van Beekum <marsmining at gmail dot com>")) (:maintainer "Carsten Dominik <carsten at orgmode dot org>") (:url . "https://github.com/marsmining/ox-twbs"))]) (ox-tufte . [(20160926 1607) ((org (8 2)) (emacs (24))) "Tufte HTML org-mode export backend" single ((:commit . "49d7ea78fde063b407ce6fa57739f90c83500682") (:keywords "org" "tufte" "html") (:authors ("M. Lee Hinman")) (:maintainer "M. Lee Hinman") (:url . "https://github.com/dakrone/ox-tufte"))]) (ox-trac . [(20171026 1823) ((org (9 0))) "Org Export Backend to Trac WikiFormat" single ((:commit . "03cc31efb1aa06991918f1071e250a9d58f96cfb") (:keywords "org-mode" "trac") (:authors ("Brian J. Carlson <hacker (at) abutilize (dot) com>")) (:maintainer "Brian J. Carlson <hacker (at) abutilize (dot) com>") (:url . "https://github.com/JalapenoGremlin/ox-trac"))]) (ox-tiddly . [(20180626 2052) ((org (8)) (cl-lib (0 5))) "org TiddlyWiki exporter" single ((:commit . "99d0c25d56dbf75ce894a84e776ba4459208dbc2") (:keywords "org") (:authors ("Derek Feichtinger" . "derek.feichtinger@psi.ch")) (:maintainer "Derek Feichtinger" . "derek.feichtinger@psi.ch") (:url . "https://github.com/dfeich/org8-wikiexporters"))]) (ox-textile . [(20180502 947) ((org (8 1))) "Textile Back-End for Org Export Engine" single ((:commit . "b179abaa6616604c6efe32cb509e62ad46e7374e") (:keywords "org" "textile") (:authors ("Yasushi SHOJI" . "yasushi.shoji@gmail.com")) (:maintainer "Yasushi SHOJI" . "yasushi.shoji@gmail.com") (:url . "https://github.com/yashi/org-textile"))]) (ox-rst . [(20180315 13) ((emacs (24 4)) (org (8 2 4))) "Export reStructuredText using org-mode." single ((:commit . "a74b60883b0d844c80efb364dac1560b85f2548f") (:keywords "org" "rst" "rest" "restructuredtext") (:authors ("Masanao Igarashi" . "syoux2@gmail.com")) (:maintainer "Masanao Igarashi" . "syoux2@gmail.com") (:url . "https://github.com/masayuko/ox-rst"))]) (ox-reveal . [(20161027 926) ((org (20150330))) "reveal.js Presentation Back-End for Org Export Engine" single ((:commit . "001567cc12d50ba07612edd1718b86a12e8c2547") (:keywords "outlines" "hypermedia" "slideshow" "presentation") (:authors ("Yujie Wen <yjwen.ty at gmail dot com>")) (:maintainer "Yujie Wen <yjwen.ty at gmail dot com>"))]) (ox-qmd . [(20170402 1657) ((org (8 0))) "Qiita Markdown Back-End for Org Export Engine" single ((:commit . "3a24c7a0b3ec80e494b977e14a3dfb94c9f1d8ec") (:keywords "org" "wp" "markdown" "qiita") (:authors ("0x60DF" . "0x60DF@gmail.com")) (:maintainer "0x60DF" . "0x60DF@gmail.com") (:url . "https://github.com/0x60df/ox-qmd"))]) (ox-pukiwiki . [(20150124 1716) ((org (8 1))) "Pukiwiki Back-End for Org Export Engine" single ((:commit . "bdbde2c294f5d3de11f08a3fe19f01175d2e011a") (:keywords "org" "pukiwiki") (:authors ("Yasushi SHOJI" . "yasushi.shoji@gmail.com")) (:maintainer "Yasushi SHOJI" . "yasushi.shoji@gmail.com") (:url . "https://github.com/yashi/org-pukiwiki"))]) (ox-pandoc . [(20180510 1338) ((org (8 2)) (emacs (24)) (dash (2 8)) (ht (2 0)) (cl-lib (0 5))) "org exporter for pandoc." single ((:commit . "aa37dc7e94213d4ebedb85c384c1ba35007da18e") (:keywords "tools") (:authors ("KAWABATA, Taichi" . "kawabata.taichi@gmail.com")) (:maintainer "KAWABATA, Taichi" . "kawabata.taichi@gmail.com") (:url . "https://github.com/kawabata/ox-pandoc"))]) (ox-nikola . [(20151114 1116) ((emacs (24 4)) (org (8 2 4)) (ox-rst (0 2))) "Export Nikola articles using org-mode." single ((:commit . "5bcbc1a38f6619f62294194f13ca0cd4ca14dd48") (:keywords "org" "nikola") (:authors ("IGARASHI Masanao" . "syoux2@gmail.com")) (:maintainer "IGARASHI Masanao" . "syoux2@gmail.com") (:url . "https://github.com/masayuko/ox-nikola"))]) (ox-minutes . [(20180202 1734) ((emacs (24 4))) "Plain text backend for Org for Meeting Minutes" single ((:commit . "27c29f3fdb9181322ae56f8bace8d95e621230e5") (:keywords "org" "exporter" "notes") (:authors ("Kaushal Modi" . "kaushal.modi@gmail.com")) (:maintainer "Kaushal Modi" . "kaushal.modi@gmail.com") (:url . "https://github.com/kaushalmodi/ox-minutes"))]) (ox-mediawiki . [(20180105 2154) ((cl-lib (0 5)) (s (1 9 0))) "Mediawiki Back-End for Org Export Engine" single ((:commit . "a9327150293e370e500ba55bddfe5fc435c6bf9b") (:keywords "org" "wp" "mediawiki") (:authors ("Tom Alexander" . "tomalexander@paphus.com")) (:maintainer "Tom Alexander" . "tomalexander@paphus.com") (:url . "https://github.com/tomalexander/orgmode-mediawiki"))]) (ox-jira . [(20171001 916) ((org (8 3))) "JIRA Backend for Org Export Engine" single ((:commit . "db2ec528f46c9e611624ba28611c440a99bff255") (:keywords "outlines" "hypermedia" "wp") (:authors ("Stig Brautaset" . "stig@brautaset.org")) (:maintainer "Stig Brautaset" . "stig@brautaset.org") (:url . "https://github.com/stig/ox-jira.el"))]) (ox-jekyll-md . [(20180831 1732) nil "Export Jekyll on Markdown articles using org-mode." single ((:commit . "ff7b81733354c2b427293e531bb51647fa84fc88") (:keywords "org" "jekyll") (:authors ("Elsa Gonsiorowski" . "gonsie@me.com")) (:maintainer "Elsa Gonsiorowski" . "gonsie@me.com"))]) (ox-jekyll . [(20180813 1755) nil "Export Jekyll articles using org-mode." single ((:commit . "102c53b1333abbf15b7c5c3ee1dc27124d1c0d68") (:keywords "org" "jekyll") (:authors ("Elsa Gonsiorowski" . "gonsie@me.com")) (:maintainer "Elsa Gonsiorowski" . "gonsie@me.com"))]) (ox-ioslide . [(20161015 1338) ((emacs (24 1)) (org (8 0)) (cl-lib (0 5)) (f (0 17 2)) (makey (0 3))) "Export org-mode to Google I/O HTML5 slide." tar ((:commit . "6555680be5364c8ddd2bf446865cb1a82adb6b9e") (:keywords "html" "presentation") (:authors ("coldnew" . "coldnew.tw@gmail.com")) (:maintainer "coldnew" . "coldnew.tw@gmail.com") (:url . "http://github.com/coldnew/org-ioslide"))]) (ox-impress-js . [(20150412 1716) ((org (8))) "impress.js Back-End for Org Export Engine" tar ((:commit . "91c6d2af6af308ade352a03355c4fb551b238c6b") (:keywords "outlines" "hypermedia" "calendar" "wp") (:authors ("Takumi Kinjo <takumi dot kinjo at gmail dot org>")) (:maintainer "Takumi Kinjo <takumi dot kinjo at gmail dot org>") (:url . "https://github.com/kinjo/org-impress-js.el"))]) (ox-hugo . [(20180824 1500) ((emacs (24 4)) (org (9 0))) "Hugo Markdown Back-End for Org Export Engine" tar ((:commit . "2179e502c0127ce090a981053a501aa86b15e54a") (:keywords "org" "markdown" "docs") (:url . "https://ox-hugo.scripter.co"))]) (ox-html5slide . [(20131228 606) ((org (8 0))) "Export org-mode to HTML5 slide." single ((:commit . "4703dfbd9d79161509def673d2c1e118d722a58f") (:keywords "html" "presentation") (:authors ("coldnew" . "coldnew.tw@gmail.com")) (:maintainer "coldnew" . "coldnew.tw@gmail.com") (:url . "http://github.com/coldnew/org-html5slide"))]) (ox-gfm . [(20170628 2102) nil "Github Flavored Markdown Back-End for Org Export Engine" single ((:commit . "99f93011b069e02b37c9660b8fcb45dab086a07f") (:keywords "org" "wp" "markdown" "github") (:authors ("Lars Tveito")) (:maintainer "Lars Tveito"))]) (ox-epub . [(20171203 113) ((emacs (24 3)) (org (9))) "Export org mode projects to EPUB" single ((:commit . "3d958203e169cbfb2204c43cb4c5543befec0b9d") (:keywords "hypermedia") (:authors ("Mark Meyer" . "mark@ofosos.org")) (:maintainer "Mark Meyer" . "mark@ofosos.org") (:url . "http://github.com/ofosos/org-epub"))]) (ox-clip . [(20180306 340) ((org (8 2)) (htmlize (0))) "Cross-platform formatted copying for org-mode" single ((:commit . "594c90953a91948505bb394350adf110e041f19a") (:keywords "org-mode") (:authors ("John Kitchin" . "jkitchin@andrew.cmu.edu")) (:maintainer "John Kitchin" . "jkitchin@andrew.cmu.edu") (:url . "https://github.com/jkitchin/ox-clip/ox-clip.el"))]) (ox-bibtex-chinese . [(20170723 309) ((emacs (24 4))) "Let ox-bibtex work well for Chinese users" tar ((:commit . "2ad2364399229144110db7ef6365ad0461d6a38c"))]) (ox-asciidoc . [(20171111 1154) ((org (8 1))) "AsciiDoc Back-End for Org Export Engine" single ((:commit . "e75d9565dd07dc59d11fa92d392ab47cecb3c902") (:keywords "org" "asciidoc") (:authors ("Yasushi SHOJI" . "yasushi.shoji@gmail.com")) (:maintainer "Yasushi SHOJI" . "yasushi.shoji@gmail.com") (:url . "https://github.com/yashi/org-asciidoc"))]) (owdriver . [(20170401 1312) ((smartrep (0 0 3)) (log4e (0 2 0)) (yaxception (0 2 0))) "Quickly perform various actions on other windows" single ((:commit . "d934f182bafe29aa16c173440eff3fef08b0ec10") (:keywords "convenience") (:authors ("Hiroaki Otsu" . "ootsuhiroaki@gmail.com")) (:maintainer "Hiroaki Otsu" . "ootsuhiroaki@gmail.com") (:url . "https://github.com/aki2o/owdriver"))]) (overseer . [(20180226 619) ((emacs (24)) (dash (2 10 0)) (pkg-info (0 4)) (f (0 18 1))) "Ert-runner Integration Into Emacs" single ((:commit . "02d49f582e80e36b4334c9187801c5ecfb027789") (:authors ("Samuel Tonini" . "tonini.samuel@gmail.com")) (:maintainer "Samuel Tonini" . "tonini.samuel@gmail.com") (:url . "http://www.github.com/tonini/overseer.el"))]) (overcast-theme . [(20180315 1943) ((emacs (24))) "A dark but vibrant color theme for Emacs" single ((:commit . "009257956522dedf07d9e136ee41ac0b1b0b3518") (:keywords "theme") (:authors ("Mohammed Ismail Ansari" . "team.terminal@gmail.com")) (:maintainer "Mohammed Ismail Ansari" . "team.terminal@gmail.com") (:url . "http://ismail.teamfluxion.com"))]) (ov . [(20150312 528) ((emacs (24 3))) "Overlay library for Emacs Lisp" single ((:commit . "fae7215b3dedba2a9ced145284332e4609bfdc38") (:keywords "overlay") (:authors ("Shingo Fukuyama - http://fukuyama.co")) (:maintainer "Shingo Fukuyama - http://fukuyama.co") (:url . "https://github.com/ShingoFukuyama/ov.el"))]) (outshine . [(20180625 1959) ((outorg (2 0)) (cl-lib (0 5))) "outline with outshine outshines outline" tar ((:commit . "8712df02b97a148e11de2761f3e707623db6f9c2") (:maintainer "Adam Porter" . "adam@alphapapa.net") (:url . "http://github.com/alphapapa/outshine"))]) (outrespace . [(20180711 1432) ((emacs (24 4))) "c++ namespace utility functions" single ((:commit . "7dafed7e1cabf4a0bb55e5c6465e83796e3fdabe") (:keywords "tools" "c++" "namespace") (:authors ("Dan Harms" . "danielrharms@gmail.com")) (:maintainer "Dan Harms" . "danielrharms@gmail.com") (:url . "https://github.com/articuluxe/outrespace.git"))]) (outorg . [(20170414 1915) ((emacs (24 4))) "Org-style comment editing" single ((:commit . "78b0695121fb974bc4e971eb4ef7f8afd6d89d64") (:maintainer "Adam Porter") (:url . "https://github.com/alphapapa/outorg"))]) (outlook . [(20180428 1430) ((emacs (24 4))) "send emails in MS Outlook style" tar ((:commit . "359683aff91b38bd1398a6ed4058a06f09a02d65") (:keywords "mail") (:authors ("Andrew Savonichev")) (:maintainer "Andrew Savonichev") (:url . "https://github.com/asavonic/outlook.el"))]) (outlined-elisp-mode . [(20131108 1127) nil "outline-minor-mode settings for emacs lisp" single ((:commit . "c16cb02b540448919ad148f2be6a41523ee5489c") (:authors ("zk_phi")) (:maintainer "zk_phi") (:url . "http://hins11.yu-yake.com/"))]) (outline-toc . [(20170730 1130) nil "Sidebar showing a \"table of contents\"." single ((:commit . "31f04bea19cfcfb01a94d1fd2b72391cb02b7463") (:keywords "convenience" "outlines") (:authors ("Austin Bingham" . "austin.bingham@gmail.com")) (:maintainer "Austin Bingham" . "austin.bingham@gmail.com") (:url . "https://github.com/abingham/outline-toc.el"))]) (outline-magic . [(20180619 1819) nil "outline mode extensions for Emacs" single ((:commit . "2a5f07417b696cf7541d435c43bafcc64817636b") (:keywords "outlines") (:authors ("Carsten Dominik" . "dominik@science.uva.nl")) (:maintainer "Thorsten Jolitz <tjolitz AT gmail DOT com>"))]) (other-emacs-eval . [(20180408 1348) ((emacs (25 1)) (async (1 9 2))) "Evaluate the Emacs Lisp expression in other Emacs" single ((:commit . "8ace5acafef65daabf0c6619eff60733d7f5d792") (:keywords "tools") (:authors ("Xu Chunyang" . "mail@xuchunyang.me")) (:maintainer "Xu Chunyang" . "mail@xuchunyang.me") (:url . "https://github.com/xuchunyang/other-emacs-eval"))]) (otama . [(20160404 1032) nil "Org-table Manipulator" single ((:commit . "c114fd8006762f891bc120a7c0ea213872e7ab31") (:keywords "database" "org-mode") (:authors ("Yoshinari Nomura" . "nom@quickhack.net")) (:maintainer "Yoshinari Nomura" . "nom@quickhack.net"))]) (osx-trash . [(20160520 1300) ((emacs (24 1))) "System trash for OS X" tar ((:commit . "0f1dc052d0a750b8c75f14530a4897f5d4324b4e") (:keywords "files" "convenience" "tools" "unix") (:authors ("Sebastian Wiesner" . "swiesner@lunaryorn.com")) (:maintainer "Sebastian Wiesner" . "swiesner@lunaryorn.com") (:url . "https://github.com/lunaryorn/osx-trash.el"))]) (osx-pseudo-daemon . [(20170722 607) nil "Daemon mode that plays nice with OSX." single ((:commit . "d235680a72677f11925b912428ad1a57b664e3e8") (:keywords "convenience" "osx") (:authors ("Ryan C. Thompson")) (:maintainer "Ryan C. Thompson") (:url . "https://github.com/DarwinAwardWinner/osx-pseudo-daemon"))]) (osx-org-clock-menubar . [(20150205 2111) nil "simple menubar integration for org-clock" tar ((:commit . "9964d2a97cc2fb6570dc4116da44f73bd8eb7cb3") (:keywords "org" "osx") (:authors ("Jordon Biondo" . "jordonbiondo@gmail.com")) (:maintainer "Jordon Biondo" . "jordonbiondo@gmail.com") (:url . "https://github.com/jordonbiondo/osx-org-clock-menubar"))]) (osx-location . [(20150613 917) nil "Watch and respond to changes in geographical location on OS X" tar ((:commit . "8bb3a94cc9f04b922d2d730fe08596cc6ee12bf2"))]) (osx-lib . [(20160920 0) ((emacs (24 4))) "Basic function for Apple/OSX." single ((:commit . "fdbbb41e07ba64d6a09b54bd142a7c7b83bfd09f") (:keywords "apple" "applescript" "osx" "finder" "emacs" "elisp" "vpn" "speech") (:authors ("Raghav Kumar Gautam" . "raghav@apache.org")) (:maintainer "Raghav Kumar Gautam" . "raghav@apache.org"))]) (osx-dictionary . [(20171026 734) ((cl-lib (0 5))) "Interface for OSX Dictionary.app" tar ((:commit . "b16630ecf69f87ac873486d8b9c8c03e6c9ea7fa") (:keywords "mac" "dictionary") (:authors ("Chunyang Xu" . "mail@xuchunyang.me")) (:maintainer "Chunyang Xu" . "mail@xuchunyang.me") (:url . "https://github.com/xuchunyang/osx-dictionary.el"))]) (osx-clipboard . [(20141012 717) nil "Use the OS X clipboard from terminal Emacs" single ((:commit . "e46dd31327a3f92f77b013b4c9b1e5fdd0e5c73d") (:authors ("Jon Oddie <jonxfield at gmail.com>")) (:maintainer "Jon Oddie <jonxfield at gmail.com>") (:url . "https://github.com/joddie/osx-clipboard-mode"))]) (osx-browse . [(20140508 2041) ((string-utils (0 3 2)) (browse-url-dwim (0 6 6))) "Web browsing helpers for OS X" single ((:commit . "44ded7cc3a7ee426c1c3257fae534c121f7e752e") (:keywords "hypermedia" "external") (:authors ("Roland Walker" . "walker@pobox.com")) (:maintainer "Roland Walker" . "walker@pobox.com") (:url . "http://github.com/rolandwalker/osx-browse"))]) (origami . [(20180101 1553) ((s (1 9 0)) (dash (2 5 0)) (emacs (24)) (cl-lib (0 5))) "Flexible text folding" tar ((:commit . "1f38085c8f9af7842765ed63f7d6dfe4dab59366") (:keywords "folding") (:authors ("Greg Sexton" . "gregsexton@gmail.com")) (:maintainer "Greg Sexton" . "gregsexton@gmail.com") (:url . "https://github.com/gregsexton/origami.el"))]) (orgtbl-show-header . [(20141023 837) nil "Show the header of the current column in the minibuffer" single ((:commit . "112d54a44682f065318ed0c9c89a8f5b8907342a") (:authors ("Damien Cassou" . "damien.cassou@gmail.com")) (:maintainer "Damien Cassou" . "damien.cassou@gmail.com"))]) (orgtbl-join . [(20150121 2246) ((cl-lib (0 5))) "join columns from another table" tar ((:commit . "ccf5e0d96e053dc289da39a048715fcf36835ff2") (:keywords "org" "table" "join" "filtering") (:authors ("Thierry Banel tbanelwebmin at free dot fr")) (:maintainer "Thierry Banel tbanelwebmin at free dot fr"))]) (orgtbl-ascii-plot . [(20151215 2151) nil "ascii-art bar plots in org-mode tables" single ((:commit . "cd91f6ae26a7402e192a1f4fd6248f5797edf19e") (:keywords "org" "table" "ascii" "plot") (:authors ("Thierry Banel  tbanelwebmin at free dot fr") ("Michael Brand")) (:maintainer "Thierry Banel  tbanelwebmin at free dot fr"))]) (orgtbl-aggregate . [(20180731 2154) nil "Create an aggregated Org table from another one" tar ((:commit . "7e87e0fb0784be9370462614ec0ffc9d9ae6ef1c") (:keywords "org" "table" "aggregation" "filtering"))]) (orgnav . [(20170608 1713) ((helm (2 7 0)) (s (1 11 0)) (dash (1 11 0)) (emacs (24))) "Org tree navigation using helm" tar ((:commit . "9e2cac9c1a67af5f0080e60022e821bf7b70312d") (:keywords "convenience" "outlines") (:authors ("Facet Framer" . "facet@facetframer.com")) (:maintainer "Facet Framer" . "facet@facetframer.com") (:url . "http://github.com/facetframer/orgnav"))]) (orglue . [(20171220 1226) ((org (8 1)) (epic (0 2))) "more functionality to org-mode." tar ((:commit . "ae2a45c19b52e45db7891093a3ff17ba2e51c507") (:keywords "org") (:authors ("Yoshinari Nomura" . "nom@quickhack.net")) (:maintainer "Yoshinari Nomura" . "nom@quickhack.net"))]) (orglink . [(20180318 2023) ((emacs (24 3)) (dash (2 12 1)) (org (8 3))) "use Org Mode links in other modes" single ((:commit . "e9e90e16ddaceaf99c9b251a215d6338b9762b4d") (:keywords "hypertext") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:url . "https://github.com/tarsius/orglink"))]) (orgit . [(20180318 2001) ((emacs (24 4)) (dash (2 13 0)) (magit (2 10 0)) (org (8 3 3))) "support for Org links to Magit buffers" single ((:commit . "d909f92d3b1b42184143fd5e6d4c6a2762477ab7") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:url . "https://github.com/magit/orgit"))]) (orgbox . [(20180827 218) ((org (8 0)) (cl-lib (0 5))) "Mailbox-like task scheduling Org." single ((:commit . "609e5e37348815ec3ba53ab6d643e38b0cc4fe17") (:keywords "org") (:authors ("Yasuhito Takamiya" . "yasuhito@gmail.com")) (:maintainer "Yasuhito Takamiya" . "yasuhito@gmail.com") (:url . "https://github.com/yasuhito/orgbox"))]) (organize-imports-java . [(20180623 1909) ((emacs (26)) (f (0 20 0)) (s (1 12 0)) (cl-lib (0 6))) "Mimic Eclipse's Organize Imports functionality." single ((:commit . "cd21c23f903384ffe0eca5e6511bdf893457ab19") (:authors ("Shen, Jen-Chieh" . "jcs090218@gmail.com")) (:maintainer "Shen, Jen-Chieh" . "jcs090218@gmail.com") (:url . "https://github.com/jcs090218/organize-imports-java"))]) (organic-green-theme . [(20180522 1620) nil "Low-contrast green color theme." single ((:commit . "200ac4a636eeb6faf1793d1937e62a343debc437"))]) (org2web . [(20171005 2317) ((cl-lib (1 0)) (ht (1 5)) (mustache (0 22)) (htmlize (1 47)) (org (8 0)) (dash (2 0 0)) (el2org (0 10)) (simple-httpd (0 1))) "A static site generator based on org mode." tar ((:commit . "5243b399927a4c474bb3b8d1c8a00799df1f27d7"))]) (org2jekyll . [(20170225 915) ((dash-functional (2 11 0)) (s (1 9 0)) (deferred (0 3 1)) (kv (0 0 19))) "Minor mode to publish org-mode post to jekyll without specific yaml" tar ((:commit . "52a19a5d372116262b9d613f4ec8490a3b49e329") (:keywords "org-mode" "jekyll" "blog" "publish") (:authors ("Antoine R. Dumont <eniotna.t AT gmail.com>")) (:maintainer "Antoine R. Dumont <eniotna.t AT gmail.com>") (:url . "https://github.com/ardumont/org2jekyll"))]) (org2issue . [(20160427 118) ((org (8 0)) (emacs (24 4)) (ox-gfm (0 1)) (gh (0 1)) (s (20160405 920))) "export org to github issue" single ((:commit . "0f7f13463e389f2d8d7d830a928042d0cf1c71eb") (:keywords "convenience" "github" "org") (:authors ("DarkSun" . "lujun9972@gmail.com")) (:maintainer "DarkSun" . "lujun9972@gmail.com") (:url . "https://github.com/lujun9972/org2issue"))]) (org2elcomment . [(20170324 945) ((org (8 3 4))) "Convert Org file to Elisp comments" single ((:commit . "c88a75d9587c484ead18f7adf08592b09c1cceb0") (:keywords "extensions") (:authors ("Junpeng Qiu" . "qjpchmail@gmail.com")) (:maintainer "Junpeng Qiu" . "qjpchmail@gmail.com"))]) (org2ctex . [(20171017 643) ((emacs (24 4))) "Export org to ctex (a latex macro for Chinese)" single ((:commit . "1b74aa9cf45de224ffd6aa9b93f0debddc2b48bc") (:authors ("Feng Shu" . "tumashu@163.com")) (:maintainer "Feng Shu" . "tumashu@163.com") (:url . "https://github.com/tumashu/org2ctex"))]) (org2blog . [(20171219 311) ((org (8 3)) (xml-rpc (1 6 12)) (metaweblog (1 0 1)) (htmlize (1 51))) "Blog from Org mode to wordpress" tar ((:commit . "aa7a5730f4a58a53c41370dcde7bec43d5c1a2cd"))]) (org-wunderlist . [(20150818 213) ((request-deferred (0 2 0)) (alert (1 1)) (emacs (24)) (cl-lib (0 5)) (org (8 2 4)) (s (1 9 0))) "Org sync with Wunderlist" single ((:commit . "f7f1ca73661356b9fa072efd73431592ff1182e1") (:keywords "convenience") (:authors ("myuhe <yuhei.maeda_at_gmail.com>")) (:maintainer "myuhe") (:url . "https://github.com/myuhe/org-wunderlist.el"))]) (org-wild-notifier . [(20180222 425) ((alert (1 2)) (dash (2 13 0)) (emacs (24 4))) "Customizable org-agenda notifications" single ((:commit . "d0df145d9bbb72b2c315b7d8007cb6a59fea2095") (:keywords "notification" "alert" "org" "org-agenda" "agenda") (:authors ("Artem Khramov" . "futu.fata@gmail.com")) (:maintainer "Artem Khramov" . "futu.fata@gmail.com") (:url . "https://github.com/akhramov/org-wild-notifier.el"))]) (org-web-tools . [(20180903 734) ((emacs (25 1)) (org (9 0)) (dash (2 12)) (esxml (0 3 4)) (s (1 10 0))) "Display and capture web content with Org-mode" single ((:commit . "7ad832950cb17890a4da751ae6d6817a7428f342") (:keywords "hypermedia" "outlines" "org" "web") (:authors ("Adam Porter" . "adam@alphapapa.net")) (:maintainer "Adam Porter" . "adam@alphapapa.net") (:url . "http://github.com/alphapapa/org-web-tools"))]) (org-wc . [(20180610 253) nil "Count words in org mode trees." single ((:commit . "0716c1e8276f6953e139e357e97566e792c8be19") (:authors ("Simon Guest")) (:maintainer "Simon Guest"))]) (org-vcard . [(20170929 1110) nil "org-mode support for vCard export and import." tar ((:commit . "dbe266b79df4fb31f1766010322bf4e383ce1c03") (:keywords "outlines" "org" "vcard") (:authors ("Alexis" . "flexibeast@gmail.com")) (:maintainer "Alexis" . "flexibeast@gmail.com") (:url . "https://github.com/flexibeast/org-vcard"))]) (org-variable-pitch . [(20180429 2215) ((emacs (25))) "Minor mode for variable pitch text in org mode." single ((:commit . "05f2655321f020fd4c069d1939f0902eaa837eb4") (:keywords "faces") (:authors ("Göktuğ Kayaalp" . "self@gkayaalp.com")) (:maintainer "Göktuğ Kayaalp" . "self@gkayaalp.com") (:url . "https://cadadr.github.io/elisp/index.html#ovp"))]) (org-trello . [(20180331 631) ((request-deferred (0 2 0)) (deferred (0 4 0)) (s (1 11 0)) (dash-functional (2 12 1)) (dash (2 12 1))) "Minor mode to synchronize org-mode buffer and trello board" tar ((:commit . "e2e8a3d45057645e4caae7d46a79d2d9be2894bd"))]) (org-tree-slide . [(20180424 2336) nil "A presentation tool for org-mode" single ((:commit . "42468d8a0960658f6f3e44f8a4044dc552b00252") (:keywords "org-mode" "presentation" "narrowing") (:authors ("Takaaki ISHIKAWA <takaxp at ieee dot org>")) (:maintainer "Takaaki ISHIKAWA <takaxp at ieee dot org>"))]) (org-transform-tree-table . [(20150110 1433) ((dash (2 10 0)) (s (1 3 0))) "Transform org-mode tree with properties to a table, and the other way around" single ((:commit . "0a9bf07f01bc5fc3b349aff64e83999a8de83b52") (:keywords "org-mode" "table" "org-table" "tree" "csv" "convert") (:authors (nil . "Johan Lindstrom <buzzwordninja not_this_bit@googlemail.com>")) (:maintainer nil . "Johan Lindstrom <buzzwordninja not_this_bit@googlemail.com>") (:url . "https://github.com/jplindstrom/emacs-org-transform-tree-table"))]) (org-tracktable . [(20161118 1329) ((emacs (24)) (cl-lib (0 5))) "Track your writing progress in an org-table" single ((:commit . "8e0e60a582a034bd66d5efb72d513140b7d4d90a") (:keywords "org" "writing") (:authors ("tty-tourist" . "andreasrasholm@protonmail.com")) (:maintainer "tty-tourist" . "andreasrasholm@protonmail.com") (:url . "https://github.com/tty-tourist/org-tracktable"))]) (org-toodledo . [(20150301 1113) ((request-deferred (0 2 0)) (emacs (24)) (cl-lib (0 5))) "Toodledo integration for Emacs Org mode" tar ((:commit . "2c91a92bd07ae4a546771b018a6faa0e06399968") (:keywords "outlines" "data") (:authors ("Christopher J. White" . "emacs@grierwhite.com")) (:maintainer "Christopher J. White" . "emacs@grierwhite.com"))]) (org-timeline . [(20180812 1119) ((dash (2 13 0)) (emacs (24 3))) "Add graphical view of agenda to agenda buffer." single ((:commit . "701f13246ad1ce286be69cc16c1126536b71e7ca") (:keywords "calendar") (:authors ("Matúš Goljer" . "matus.goljer@gmail.com")) (:maintainer "Matúš Goljer" . "matus.goljer@gmail.com") (:url . "https://github.com/Fuco1/org-timeline/"))]) (org-time-budgets . [(20151111 801) ((alert (0 5 10)) (cl-lib (0 5))) "Define time budgets and display clocked time." single ((:commit . "baa1ce6333157fed3b3799a80e6cf8c73c9e2c18") (:authors ("Arthur Leonard Andersen" . "leoc.git@gmail.com")) (:maintainer "Arthur Leonard Andersen" . "leoc.git@gmail.com"))]) (org-themis . [(20160122 404) ((cl-lib (0 4))) "Experimental project management mode for org-mode" single ((:commit . "78aadbbe22b1993be5c4accd0d3f91a4e85c9a3c") (:keywords "org-mode" "elisp" "project") (:maintainer "Zachary Elliott" . "contact@zell.io") (:url . "http://github.com/zellio/org-themis"))]) (org-tfl . [(20170923 1218) ((org (0 16 2)) (cl-lib (0 5)) (emacs (24 1))) "Transport for London meets Orgmode" tar ((:commit . "f0d7d39106a1de5457f5160cddd98ab892b61066") (:keywords "org" "tfl") (:authors ("storax (David Zuber), <zuber [dot] david [at] gmx [dot] de>")) (:maintainer "storax (David Zuber), <zuber [dot] david [at] gmx [dot] de>") (:url . "https://github.com/storax/org-tfl"))]) (org-table-sticky-header . [(20170409 114) ((org (8 2 10)) (emacs (24 4))) "Sticky header for org-mode tables" single ((:commit . "93dc69efc00ac9fd3cc2ece5100f51df33ec7d8b") (:keywords "extensions") (:authors ("Junpeng Qiu" . "qjpchmail@gmail.com")) (:maintainer "Junpeng Qiu" . "qjpchmail@gmail.com"))]) (org-table-comment . [(20120209 1851) nil "Org table comment modes." single ((:commit . "33b9966c33ecbc3e27cca67c2f2cdea04364d74e") (:keywords "org-mode" "orgtbl") (:authors ("Matthew L. Fidler <matthew dot fidler at gmail . com>")) (:maintainer "Matthew L. Fidler") (:url . "http://github.com/mlf176f2/org-table-comment.el"))]) (org-sync-snippets . [(20170824 1828) ((org (8 3 5)) (emacs (24 3)) (f (0 17 3))) "Export snippets to org-mode and vice versa" single ((:commit . "0f264a032d371d7dbb4a7cbaf0ea2f91b5a629ca") (:keywords "snippet" "org-mode" "yasnippet" "tools") (:authors ("Adrien Brochard")) (:maintainer "Adrien Brochard") (:url . "https://github.com/abrochard/org-sync-snippets"))]) (org-sync . [(20180221 1927) ((cl-lib (0 5)) (org (8 2)) (emacs (24))) "Synchronize Org documents with External Issue Trackers" tar ((:commit . "095335063b306871970f981898a220f62ad0ae4e") (:keywords "org" "synchronization" "issue tracking" "github" "redmine") (:authors ("Aurelien Aptel <aurelien dot aptel at gmail dot com>")) (:maintainer "Andrei Beliankou" . "arbox@yandex.ru") (:url . "https://github.com/arbox/org-sync"))]) (org-super-agenda . [(20180904 1451) ((emacs (25 1)) (s (1 10 0)) (dash (2 13)) (org (9 0)) (ht (2 2))) "Supercharge your agenda" tar ((:commit . "01b55ad4d2b35a3f07425cafb8bca5d7d30fb7af") (:keywords "hypermedia" "outlines" "org" "agenda") (:authors ("Adam Porter" . "adam@alphapapa.net")) (:maintainer "Adam Porter" . "adam@alphapapa.net") (:url . "http://github.com/alphapapa/org-super-agenda"))]) (org-sticky-header . [(20170423 435) ((emacs (24 4)) (org (8 3 5))) "Show off-screen Org heading at top of window" single ((:commit . "aae8dbc7f3b33c4dd35dc38d83791d7c23757060") (:keywords "hypermedia" "outlines" "org") (:authors ("Adam Porter" . "adam@alphapapa.net")) (:maintainer "Adam Porter" . "adam@alphapapa.net") (:url . "http://github.com/alphapapa/org-sticky-header"))]) (org-static-blog . [(20180528 648) ((emacs (24 3))) "a simple org-mode based static blog generator" single ((:commit . "f69d2fd6671fb250fbd87df5efa898a7bf5b9bda") (:authors ("Bastian Bechtold")) (:maintainer "Bastian Bechtold") (:url . "https://github.com/bastibe/org-static-blog"))]) (org-starter . [(20180830 1712) ((emacs (25 1)) (dash (2 12))) "A basic configuration framework for org mode" single ((:commit . "0f3cb297976547a99d71ff944dc0f2a4e2f292ee") (:authors ("Akira Komamura" . "akira.komamura@gmail.com")) (:maintainer "Akira Komamura" . "akira.komamura@gmail.com") (:url . "https://github.com/akirak/org-starter"))]) (org-send-ebook . [(20180801 523) ((emacs (25)) (cl-lib (0 5)) (seq (2 20))) "Send org link file to ebook reader." single ((:commit . "39ee6440ec6f29f67cb24e3c62e179342d3a7b11") (:keywords "org" "link" "ebook" "kindle" "epub" "mobi") (:url . "https://github.com/stardiviner/org-send-ebook"))]) (org-seek . [(20161217 502) ((emacs (24 3)) (ag (0 48))) "Searching Org-mode files with search tools." single ((:commit . "1f51e6634e3b9a6a29d335d0d14370a6ffef2265") (:keywords "org" "search" "ag" "pt") (:authors ("stardiviner" . "numbchild@gmail.com")) (:maintainer "stardiviner" . "numbchild@gmail.com") (:url . "https://github.com/stardiviner/org-seek.el"))]) (org-rtm . [(20160214 1236) ((rtm (0 1))) "Simple import/export from rememberthemilk to org-mode" single ((:commit . "adc42ad1fbe92ab447ccc9553780f4456f2508d2") (:keywords "outlines" "data") (:authors ("Philipp Middendorf" . "pmidden@secure.mailbox.org")) (:maintainer "Philipp Middendorf" . "pmidden@secure.mailbox.org") (:url . "https://github.com/pmiddend/org-rtm"))]) (org-rich-yank . [(20180430 1344) ((emacs (24 4))) "paste with org-mode markup and link to source" single ((:commit . "b29bd06f295424fc15b3b8c1b3f78f501d67db47") (:keywords "convenience" "hypermedia" "org") (:authors ("Kevin Brubeck Unhammer" . "unhammer@fsfe.org")) (:maintainer "Kevin Brubeck Unhammer" . "unhammer@fsfe.org"))]) (org-review . [(20160907 537) nil "schedule reviews for Org entries" single ((:commit . "058e75b7f28d2ad2390290fe17a63d98ef5ab763") (:keywords "org" "review") (:authors ("Alan Schmitt" . "alan.schmitt@polytechnique.org")) (:maintainer "Alan Schmitt" . "alan.schmitt@polytechnique.org") (:url . "https://github.com/brabalan/org-review"))]) (org-repo-todo . [(20171228 119) nil "Simple repository todo management with org-mode" single ((:commit . "f73ebd91399c5760ad52c6ad9033de1066042003") (:keywords "convenience") (:authors ("justin talbott" . "justin@waymondo.com")) (:maintainer "justin talbott" . "justin@waymondo.com") (:url . "https://github.com/waymondo/org-repo-todo"))]) (org-ref . [(20180820 1428) ((dash (2 11 0)) (htmlize (1 51)) (helm (1 5 5)) (helm-bibtex (2 0 0)) (ivy (0 8 0)) (hydra (0 13 2)) (key-chord (0)) (s (1 10 0)) (f (0 18 0)) (emacs (24 4)) (pdf-tools (0 7))) "citations, cross-references and bibliographies in org-mode" tar ((:commit . "38cccc9a688e40883885a7ef643f10640e3a747a") (:keywords "org-mode" "cite" "ref" "label") (:authors ("John Kitchin" . "jkitchin@andrew.cmu.edu")) (:maintainer "John Kitchin" . "jkitchin@andrew.cmu.edu") (:url . "https://github.com/jkitchin/org-ref"))]) (org-redmine . [(20160711 1114) nil "Redmine tools using Emacs OrgMode" single ((:commit . "e77d013bc3784947c46a5c53f03cd7d3c68552fc") (:keywords "redmine" "org") (:authors ("Wataru MIYAGUNI" . "gonngo@gmail.com")) (:maintainer "Wataru MIYAGUNI" . "gonngo@gmail.com") (:url . "https://github.com/gongo/org-redmine"))]) (org-recent-headings . [(20170908 429) ((emacs (25 1)) (org (9 0 5)) (dash (2 13 0)) (frecency (0 1))) "Jump to recently used Org headings" single ((:commit . "a09c2670c400c7a4fbbf0ac05d2d9226aa10e8f4") (:keywords "hypermedia" "outlines" "org") (:authors ("Adam Porter" . "adam@alphapapa.net")) (:maintainer "Adam Porter" . "adam@alphapapa.net") (:url . "http://github.com/alphapapa/org-recent-headings"))]) (org-readme . [(20151204 1217) ((http-post-simple (1 0)) (yaoddmuse (0 1 1)) (header2 (21 0)) (lib-requires (21 0)) (cl-lib (0 5))) "Integrates Readme.org and Commentary/Change-logs." tar ((:commit . "4cb9f768d282a2835b4510b6504ff9ede487007d") (:keywords "header2" "readme.org" "emacswiki" "git") (:authors ("Matthew L. Fidler")) (:maintainer "Matthew L. Fidler") (:url . "https://github.com/mlf176f2/org-readme"))]) (org-randomnote . [(20171210 1357) ((f (0 19 0)) (dash (2 12 0))) "Find a random note in your Org-Mode files" single ((:commit . "c89eb4cf625ea7e7624b6a2d3d5676ce25ab03d7") (:authors ("Michael Fogleman" . "michaelwfogleman@gmail.com")) (:maintainer "Michael Fogleman" . "michaelwfogleman@gmail.com") (:url . "http://github.com/mwfogleman/org-randomnote"))]) (org-random-todo . [(20180312 804) ((emacs (24 3)) (alert (1 2))) "show a random TODO (with alert) every so often" single ((:commit . "8357350a66bbc4e0e5cb590acc104d39870cf736") (:keywords "org" "todo" "notification" "calendar") (:authors ("Kevin Brubeck Unhammer" . "unhammer@fsfe.org")) (:maintainer "Kevin Brubeck Unhammer" . "unhammer@fsfe.org"))]) (org-radiobutton . [(20180612 1028) ((dash (2 13 0)) (emacs (24))) "Radiobutton for org-mode lists." single ((:commit . "4182aafbe5ae1bdfb0b07efa435bdba8bbd7199d") (:keywords "outlines") (:authors ("Matúš Goljer" . "matus.goljer@gmail.com")) (:maintainer "Matúš Goljer" . "matus.goljer@gmail.com") (:url . "https://github.com/Fuco1/org-radiobutton"))]) (org-protocol-jekyll . [(20170328 1639) ((cl-lib (0 5))) "Jekyll's handler for org-protocol" single ((:commit . "dec064a42d6dfe81dfde7ba59ece5ca103ac6334") (:authors ("Vladimir S. Ivanov" . "ivvl82@gmail.com")) (:maintainer "Vladimir S. Ivanov" . "ivvl82@gmail.com"))]) (org-projectile-helm . [(20180601 1822) ((org-projectile (1 0 0)) (helm (2 3 1)) (emacs (25))) "helm functions for org-projectile" single ((:commit . "c798b1dff1d94304fa3621a905cbb572c7cb1d33") (:keywords "org" "projectile" "todo" "helm" "outlines") (:authors ("Ivan Malison" . "IvanMalison@gmail.com")) (:maintainer "Ivan Malison" . "IvanMalison@gmail.com") (:url . "https://github.com/IvanMalison/org-projectile"))]) (org-projectile . [(20180601 242) ((projectile (0 11 0)) (dash (2 10 0)) (emacs (24)) (s (1 9 0)) (org-category-capture (0 0 0))) "Repository todo management for org-mode" single ((:commit . "c798b1dff1d94304fa3621a905cbb572c7cb1d33") (:keywords "org-mode" "projectile" "todo" "tools" "outlines") (:authors ("Ivan Malison" . "IvanMalison@gmail.com")) (:maintainer "Ivan Malison" . "IvanMalison@gmail.com") (:url . "https://github.com/IvanMalison/org-projectile"))]) (org-preview-html . [(20180625 619) ((org (8 0)) (emacs (24 4))) "automatically use eww to preview the current org file on save" single ((:commit . "8ba7ecd7ac624f33b3e2395f477bbff4f1ec4efe") (:keywords "convenience" "eww" "org") (:authors ("DarkSun" . "lujun9972@gmail.com")) (:maintainer "DarkSun" . "lujun9972@gmail.com") (:url . "https://github.com/lujun9972/org-preview-html"))]) (org-present . [(20180303 2330) ((org (7))) "Minimalist presentation minor-mode for Emacs org-mode." single ((:commit . "d13acd70eff6a1608bc991920232146a0de76b21") (:authors ("Ric Lister")) (:maintainer "Ric Lister") (:url . "https://github.com/rlister/org-present"))]) (org-pomodoro . [(20171108 2114) ((alert (0 5 10)) (cl-lib (0 5))) "Pomodoro implementation for org-mode." tar ((:commit . "3deed1c26dcbda4d5231b9085ddf68e302b0f9dc") (:authors ("Arthur Leonard Andersen" . "leoc.git@gmail.com")) (:maintainer "Arthur Leonard Andersen" . "leoc.git@gmail.com") (:url . "https://github.com/lolownia/org-pomodoro"))]) (org-pdfview . [(20180225 1006) ((org (8 2 10)) (pdf-tools (0 80))) "Support for links to documents in pdfview mode" single ((:commit . "09ef4bf8ff8319c1ac78046c7e6b89f6a0beb82c") (:keywords "org" "pdf-view" "pdf-tools") (:authors ("Markus Hauck" . "markus1189@gmail.com")) (:maintainer "Markus Hauck" . "markus1189@gmail.com"))]) (org-password-manager . [(20180227 1810) ((org (8 2 10)) (s (1 9 0)) (dash (2 13 0))) "Password manager for Org Mode." single ((:commit . "4b30a36e71182553a02e4dd415369290d98ec03a") (:keywords "password") (:authors ("Leandro Facchinetti" . "me@leafac.com")) (:maintainer "Leandro Facchinetti" . "me@leafac.com") (:url . "https://git.leafac.com/org-password-manager"))]) (org-parser . [(20171003 436) ((emacs (25 1)) (dash (2 12 0)) (ht (2 1))) "parse org files into structured datatypes." single ((:keywords "files" "outlines" "tools") (:url . "https://bitbucket.org/zck/org-parser.el"))]) (org-page . [(20170807 224) ((ht (1 5)) (simple-httpd (1 4 6)) (mustache (0 22)) (htmlize (1 47)) (org (8 0)) (dash (2 0 0)) (cl-lib (0 5)) (git (0 1 1))) "a static site generator based on org mode" tar ((:commit . "50430ababf73a2d090881a952e9770badaf7478b"))]) (org-outlook . [(20160705 1338) nil "Outlook org" tar ((:commit . "ec32d8d9d8ffd17e6de4de0b52fc3f5ad9b4cc0d") (:keywords "org-outlook") (:authors ("Matthew L. Fidler")) (:maintainer "Matthew L. Fidler") (:url . "https://github.com/mlf176f2/org-outlook.el"))]) (org-outline-numbering . [(20180705 1501) ((emacs (24)) (org (8 3)) (cl-lib (0 6)) (ov (1 0 6))) "Show outline numbering as overlays in org-mode" single ((:commit . "b95b6a7ed9289637cb512232470633b330ca9713") (:keywords "wp" "convenience") (:authors ("Anders Johansson")) (:maintainer "Anders Johansson") (:url . "https://gitlab.com/andersjohansson/org-outline-numbering"))]) (org-onenote . [(20171008 500) ((oauth2 (0 11)) (request (0 2 0)) (org (8 2 10))) "export org-mode document to onenote." single ((:commit . "5ce5cf4edb143180e0b185ac26826d39ae5bc929") (:keywords "tools" "docs" "org-mode" "onenote") (:authors ("Frei Zhang" . "ifree0@gmail.com")) (:maintainer "Frei Zhang" . "ifree0@gmail.com") (:url . "https://github.com/ifree/org-onenote"))]) (org-octopress . [(20170821 415) ((org (9 0)) (orglue (0 1)) (ctable (0 1 1))) "Compose octopress articles using org-mode." tar ((:commit . "38598ef98d04076a8eb78d549907ddfde8d3a652") (:keywords "org" "jekyll" "octopress" "blog") (:authors ("Yoshinari Nomura" . "nom@quickhack.net")) (:maintainer "Yoshinari Nomura" . "nom@quickhack.net"))]) (org-noter . [(20180903 1520) ((emacs (24 4)) (cl-lib (0 6)) (org (9 0))) "A synchronized, Org-mode, document annotator" single ((:commit . "97111e8760ff1fd1a2b0c5338f6e7087b56b46d8") (:keywords "lisp" "pdf" "interleave" "annotate" "external" "sync" "notes" "documents" "org-mode") (:authors (nil . "Gonçalo Santos (aka. weirdNox@GitHub)")) (:maintainer nil . "Gonçalo Santos (aka. weirdNox@GitHub)") (:url . "https://github.com/weirdNox/org-noter"))]) (org-notebook . [(20170322 452) ((emacs (24)) (org (8)) (cl-lib (0 5))) "Ease the use of org-mode as a notebook" single ((:commit . "86042d866bf441e2c9bb51f995e5994141b78517") (:keywords "convenience" "tools") (:authors ("Paul Elder" . "paul.elder@amanokami.net")) (:maintainer "Paul Elder" . "paul.elder@amanokami.net"))]) (org-multiple-keymap . [(20150329 106) ((org (8 2 4)) (emacs (24)) (cl-lib (0 5))) "Set keymap to elements, such as timestamp and priority." single ((:commit . "8ebc532df7f0dd6e6c3aa7c380a51d4166c668e8") (:keywords "convenience" "org-mode") (:authors ("myuhe <yuhei.maeda_at_gmail.com>")) (:maintainer "myuhe") (:url . "https://github.com/myuhe/org-multiple-keymap.el"))]) (org-mru-clock . [(20180419 1306) ((emacs (24 3))) "clock in/out of tasks with completion and persistent history" single ((:commit . "72e6cd0a6458ae0392f587026233f553278ab481") (:keywords "convenience" "calendar") (:authors ("Kevin Brubeck Unhammer" . "unhammer@fsfe.org")) (:maintainer "Kevin Brubeck Unhammer" . "unhammer@fsfe.org"))]) (org-mobile-sync . [(20180606 524) ((emacs (24 3 50)) (org (8 0))) "automatically sync org-mobile on changes" single ((:commit . "06764b943a528827df1e2acc6bc7806cc2c1351f") (:keywords "org-mode" "org" "mobile" "sync" "todo") (:authors ("steckerhalter")) (:maintainer "steckerhalter") (:url . "https://framagit.org/steckerhalter/org-mobile-sync"))]) (org-mind-map . [(20180826 2340) ((emacs (24)) (dash (1 8 0)) (org (8 2 10))) "Creates a directed graph from org-mode files" single ((:commit . "41df4b2e30455494f1848b4e06cc9208aa9e902b") (:keywords "orgmode" "extensions" "graphviz" "dot") (:authors ("Ted Wiles" . "theodore.wiles@gmail.com")) (:maintainer "Ted Wiles" . "theodore.wiles@gmail.com") (:url . "https://github.com/theodorewiles/org-mind-map"))]) (org-mime . [(20180608 650) ((emacs (24 4)) (cl-lib (0 5))) "org html export for text/html MIME emails" single ((:commit . "895a7c31bb6aa0913b902ece414d0ad29dc8cf1f") (:keywords "mime" "mail" "email" "html") (:authors ("Eric Schulte")) (:maintainer "Chen Bin (redguardtoo)") (:url . "http://github.com/org-mime/org-mime"))]) (org-make-toc . [(20180731 1419) ((emacs (25 1)) (dash (2 12)) (s (1 10 0)) (org (9 0))) "Automatic tables of contents for Org files" single ((:commit . "710dcf99bd73763dcdfa5418a699955a9aeb60d8") (:keywords "org" "convenience") (:authors ("Adam Porter" . "adam@alphapapa.net")) (:maintainer "Adam Porter" . "adam@alphapapa.net") (:url . "http://github.com/alphapapa/org-make-toc"))]) (org-listcruncher . [(20180815 603) ((cl-lib (0 5)) (seq (2 3)) (emacs (24 4))) "Parse Org mode list contents into table" single ((:commit . "50bd8c22cde3b9b091889861e44a5043b53556f7") (:keywords "convenience") (:authors ("Derek Feichtinger" . "dfeich@gmail.com")) (:maintainer "Derek Feichtinger" . "dfeich@gmail.com") (:url . "https://github.com/dfeich/org-listcruncher"))]) (org-linkany . [(20160207 411) ((log4e (0 2 0)) (yaxception (0 1))) "Insert link using anything.el/helm.el on org-mode" single ((:commit . "8cfe2f1a46e6654a79f56505349d1396263cecb3") (:keywords "org" "completion") (:authors ("Hiroaki Otsu" . "ootsuhiroaki@gmail.com")) (:maintainer "Hiroaki Otsu" . "ootsuhiroaki@gmail.com") (:url . "https://github.com/aki2o/org-linkany"))]) (org-link-travis . [(20140405 2327) ((org (7))) "Insert/Export the link of Travis CI on org-mode" single ((:commit . "596615ad8373d9090bd4138da683524f0ad0bda5") (:keywords "org") (:authors ("Hiroaki Otsu" . "ootsuhiroaki@gmail.com")) (:maintainer "Hiroaki Otsu" . "ootsuhiroaki@gmail.com") (:url . "https://github.com/aki2o/org-link-travis"))]) (org-link-minor-mode . [(20170805 1852) ((org (8))) "Enable org-mode links in non-org modes" single ((:commit . "7b92df60f3fee7f609d649d80ef243b45771ebea") (:authors ("Sean O'Halpin <sean dot ohalpin at gmail dot com>")) (:maintainer "Sean O'Halpin <sean dot ohalpin at gmail dot com>") (:url . "https://github.com/seanohalpin/org-link-minor-mode"))]) (org-kanban . [(20180820 55) ((dash (2 13 0)) (emacs (24 4)) (org (9 1))) "kanban dynamic block for org-mode." single ((:commit . "0871636ae5a448f1678e9bcaab1b8a25be2fc5dd") (:keywords "org-mode" "org" "kanban" "tools") (:authors ("Christian Köstlin" . "christian.koestlin@gmail.com")) (:maintainer "Christian Köstlin" . "christian.koestlin@gmail.com") (:url . "http://github.com/gizmomogwai/org-kanban"))]) (org-journal . [(20180903 1007) ((emacs (25 1))) "a simple org-mode based journaling mode" single ((:commit . "db9c4c352bd56bebcac940adc70bfb89063ef3b9") (:authors ("Bastian Bechtold")) (:maintainer "Bastian Bechtold") (:url . "http://github.com/bastibe/org-journal"))]) (org-jira . [(20180828 2047) ((emacs (24 5)) (cl-lib (0 5)) (request (0 2 0)) (s (0 0 0)) (dash (2 14 1))) "Syncing between Jira and Org-mode." tar ((:commit . "aaf78e21b92a79d169b753019c30835e142c610a") (:keywords "ahungry" "jira" "org" "bug" "tracker") (:maintainer "Matthew Carter" . "m@ahungry.com") (:url . "https://github.com/ahungry/org-jira"))]) (org-iv . [(20171001 1022) ((impatient-mode (1 0 0)) (org (8 0)) (cl-lib (0 5))) "a tool used to view html (in browser) generated by org-file once the org-file changes" tar ((:commit . "7f2bb1b32647655fd9d6684f6f09dcc66b61b0cd"))]) (org-index . [(20180830 1550) ((emacs (24 4))) "A personal adaptive index for org" single ((:commit . "953f5a78f570be4745fb267523174e5f3fddc8a1") (:authors ("Marc Ihm" . "org-index@2484.de")) (:maintainer "Marc Ihm" . "org-index@2484.de") (:url . "https://github.com/marcIhm/org-index"))]) (org-if . [(20150920 1513) nil "Interactive Fiction Authoring System for Org-Mode." tar ((:commit . "fab602cc1bbee7a4e99c0083e129219d3f9ed2e8"))]) (org-grep . [(20151202 1229) ((cl-lib (0 5))) "Kind of M-x rgrep adapted for Org mode." single ((:commit . "5bdd04c0f53b8a3d656f36ea17bba3df7f0cb684") (:authors ("François Pinard" . "pinard@iro.umontreal.ca")) (:maintainer "François Pinard" . "pinard@iro.umontreal.ca") (:url . "https://github.com/pinard/org-grep"))]) (org-gnome . [(20150614 1457) ((alert (1 2)) (telepathy (0 1)) (gnome-calendar (0 1))) "Orgmode integration with the GNOME desktop" single ((:commit . "122e14cf6f8104150a65246a9a7c10e1d7939862") (:keywords "org" "gnome") (:authors ("Nicolas Petton" . "petton.nicolas@gmail.com")) (:maintainer "Nicolas Petton" . "petton.nicolas@gmail.com"))]) (org-gcal . [(20180827 808) ((request-deferred (0 2 0)) (alert (1 1)) (emacs (24)) (cl-lib (0 5)) (org (8 2 4))) "Org sync with Google Calendar" single ((:commit . "8636d25c81f8cb02d6522427753e76b853bda491") (:keywords "convenience") (:authors ("myuhe <yuhei.maeda_at_gmail.com>")) (:maintainer "Raimon Grau" . "raimonster@gmail.com") (:url . "https://github.com/kidd/org-gcal.el"))]) (org-fancy-priorities . [(20180328 2331) nil "Display org priorities as custom strings" single ((:commit . "819bb993b71e7253cefef7047306ab4e0f9d0a86") (:keywords "convenience" "faces" "outlines") (:authors ("Harry Bournis" . "harrybournis@gmail.com")) (:maintainer "Harry Bournis" . "harrybournis@gmail.com") (:url . "https://github.com/harrybournis/org-fancy-priorities"))]) (org-evil . [(20180620 1517) ((dash (2 13 0)) (evil (0)) (monitor (0)) (org (0))) "Evil extensions for Org." tar ((:commit . "3b4620edc606412ef75c0b5aa637af22486eb126") (:keywords "convenience" "evil" "org") (:authors ("Ben Moon" . "software@guiltydolphin.com")) (:maintainer "Ben Moon" . "software@guiltydolphin.com") (:url . "https://github.com/guiltydolphin/org-evil"))]) (org-emms . [(20180820 2127) ((emacs (24))) "Play multimedia files from org-mode" single ((:commit . "69752f482dbc265aafedbf1d19e7fd8f4265ca0b") (:keywords "multimedia") (:authors ("Jonathan Gregory <jgrg at autistici dot org>")) (:maintainer "Jonathan Gregory <jgrg at autistici dot org>") (:url . "https://github.com/jagrg/org-emms"))]) (org-elisp-help . [(20161122 55) ((cl-lib (0 5)) (org (9 0))) "org links to emacs-lisp documentation" single ((:commit . "3e33ab1a2933dd7f2782ef91d667a37f12d633ab") (:keywords "org" "remember" "lisp") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:url . "https://github.com/tarsius/org-elisp-help"))]) (org-ehtml . [(20150506 2358) ((web-server (20140109 2200)) (emacs (24 3))) "Export Org-mode files as editable web pages" tar ((:commit . "9df85de1a0fe1e7b2d6c000777c1a0c0217f92d0"))]) (org-edit-latex . [(20170908 1522) ((emacs (24 4)) (auctex (11 90))) "Edit embedded LaTeX in a dedicated buffer" single ((:commit . "1f228310ef2f3f2959a527f6d99e42ce977384c8") (:keywords "org" "latex") (:authors ("James Wong" . "jianwang.academic@gmail.com")) (:maintainer "James Wong" . "jianwang.academic@gmail.com") (:url . "https://github.com/et2010/org-edit-latex"))]) (org-easy-img-insert . [(20160915 2008) ((emacs (24 4))) "An easier way to add images from the web in org mode" single ((:commit . "9f8aaa7f68ff1f0d8d7b1e9b618abb15002f971e") (:keywords "convenience" "hypermedia" "files") (:authors ("Tashrif Sanil" . "tashrifsanil@kloke-source.com")) (:maintainer "Tashrif Sanil" . "tashrifsanil@kloke-source.com") (:url . "https://github.com/tashrifsanil/org-easy-img-insert"))]) (org-dropbox . [(20150114 509) ((dash (2 2)) (names (20150000)) (emacs (24))) "move Dropbox notes from phone into org-mode datetree" single ((:commit . "75dab6d6f0438a7a8a18ccf3a5d55f50bf531f6e") (:keywords "dropbox" "android" "notes" "org-mode") (:authors ("Heikki Lehvaslaiho" . "heikki.lehvaslaiho@gmail.com")) (:maintainer "Heikki Lehvaslaiho" . "heikki.lehvaslaiho@gmail.com") (:url . "https://github.com/heikkil/org-dropbox"))]) (org-drill-table . [(20180115 1009) ((s (1 7 0)) (dash (2 2 0)) (cl-lib (0 3)) (org (8 2)) (emacs (24 1))) "Generate drill cards from org tables" single ((:commit . "2729aaa42c1e2720d9bf7bcc125e92dcf48b7f7d") (:authors ("Chris Barrett" . "chris.d.barrett@me.com")) (:maintainer "Chris Barrett" . "chris.d.barrett@me.com"))]) (org-dp . [(20180311 923) ((cl-lib (0 5))) "Declarative Local Programming with Org Elements" tar ((:commit . "e720f1c155a795a5b65a04790ad195c413449716") (:authors ("Thorsten Jolitz <tjolitz AT gmail DOT com>")) (:maintainer "Thorsten Jolitz <tjolitz AT gmail DOT com>") (:url . "https://github.com/tj64/org-dp"))]) (org-download . [(20180831 1331) ((async (1 2))) "Image drag-and-drop for Emacs org-mode" single ((:commit . "cf87c16810a08c8eaed790e99c2bea5b3c9bb1ae") (:keywords "images" "screenshots" "download") (:authors ("Oleh Krehel")) (:maintainer "Oleh Krehel") (:url . "https://github.com/abo-abo/org-download"))]) (org-dotemacs . [(20180802 28) ((org (7 9 3)) (cl-lib (0 5))) "Store your emacs config as an org file, and choose which bits to load." single ((:commit . "49072168158b6cd45796e92e940c9ac71e181722") (:keywords "local") (:authors ("Joe Bloggs" . "vapniks@yahoo.com")) (:maintainer "Joe Bloggs" . "vapniks@yahoo.com") (:url . "https://github.com/vapniks/org-dotemacs"))]) (org-doing . [(20161017 1620) nil "Keep track of what you're doing" tar ((:commit . "07ddbfc238cba31e4990c9b52e9a2757b39111da") (:keywords "tools" "org") (:authors ("Rudolf Olah")) (:maintainer "Rudolf Olah") (:url . "https://github.com/omouse/org-doing"))]) (org-dashboard . [(20171223 1924) ((cl-lib (0 5))) "Visually summarize progress in org files" single ((:commit . "02c0699771d199075a286e4502340ca6e7c9e831") (:keywords "outlines" "calendar") (:authors ("Massimiliano Mirra" . "hyperstruct@gmail.com")) (:maintainer "Massimiliano Mirra" . "hyperstruct@gmail.com") (:url . "http://github.com/bard/org-dashboard"))]) (org-cua-dwim . [(20120203 534) nil "Org-mode and Cua mode compatibility layer" single ((:commit . "a55d6c7009fc0b22f1110c07de629acc955c85e4") (:keywords "org-mode" "cua-mode") (:authors ("Matthew L. Fidler")) (:maintainer "Matthew L. Fidler"))]) (org-context . [(20170107 1337) nil "Contextual capture and agenda commands for Org-mode" single ((:commit . "a3b4a4ce6d15e3c2d45eb5dcb78bea81913f3e21") (:keywords "org" "capture" "agenda" "convenience") (:authors ("Sylvain Rousseau <thisirs at gmail dot com>")) (:maintainer "Sylvain Rousseau <thisirs at gmail dot com>") (:url . "https://github.com/thisirs/org-context"))]) (org-commentary . [(20160802 637) ((dash (2 0)) (emacs (24 4)) (org (8 0))) "generate or update conventional library headers using Org mode files" tar ((:commit . "821ccb994811359c42f4e3d459e0e88849d42b75") (:keywords "convenience" "docs" "tools") (:authors ("Sergei Maximov" . "s.b.maximov@gmail.com")) (:maintainer "Sergei Maximov" . "s.b.maximov@gmail.com") (:url . "https://github.com/smaximov/org-commentary"))]) (org-clock-today . [(20161014 920) ((emacs (25))) "Show the total clocked time of the current day in the mode line" single ((:commit . "02b8fd541a01040405a9a1400c46dcb68b7c2a3a") (:authors ("Tijs Mallaerts" . "tijs.mallaerts@gmail.com")) (:maintainer "Tijs Mallaerts" . "tijs.mallaerts@gmail.com"))]) (org-clock-csv . [(20180314 257) ((org (8 3)) (s (1 0))) "Export `org-mode' clock entries to CSV format." single ((:commit . "4a6e9e4895799afa0b994f4a908c1e3c2043451f") (:keywords "calendar" "data" "org") (:authors ("Aaron Jacobs" . "atheriel@gmail.com")) (:maintainer "Aaron Jacobs" . "atheriel@gmail.com") (:url . "https://github.com/atheriel/org-clock-csv"))]) (org-clock-convenience . [(20160830 1856) ((cl-lib (0 5)) (org (8)) (emacs (24 3))) "convenience functions for org time tracking" single ((:commit . "2d3fab0991ef7fa8d94c46a63a66abd289c79d9e") (:keywords "org") (:authors ("Derek Feichtinger <dfeich.gmail.com>")) (:maintainer "Derek Feichtinger <dfeich.gmail.com>") (:url . "https://github.com/dfeich/org-clock-convenience"))]) (org-cliplink . [(20180810 2034) ((emacs (24 4))) "insert org-mode links from the clipboard" tar ((:commit . "d99f6f9618ad8ed6185714786ed0e89fc439749d") (:authors ("Alexey Kutepov" . "reximkut@gmail.com")) (:maintainer "Alexey Kutepov" . "reximkut@gmail.com") (:url . "http://github.com/rexim/org-cliplink"))]) (org-chef . [(20180707 135) ((org (0)) (emacs (24))) "Cookbook and recipe management with org-mode." tar ((:commit . "6b004af05d05c981b9cf9d24a525242e36129b46") (:keywords "convenience" "abbrev" "outlines" "org" "food" "recipes" "cooking") (:authors ("Calvin Beck" . "hobbes@ualberta.ca")) (:maintainer "Calvin Beck" . "hobbes@ualberta.ca") (:url . "https://github.com/Chobbes/org-chef"))]) (org-category-capture . [(20180601 242) ((org (9 0 0)) (emacs (24))) "Contextualy capture of org-mode TODOs." single ((:commit . "c798b1dff1d94304fa3621a905cbb572c7cb1d33") (:keywords "org-mode" "todo" "tools" "outlines") (:authors ("Ivan Malison" . "IvanMalison@gmail.com")) (:maintainer "Ivan Malison" . "IvanMalison@gmail.com") (:url . "https://github.com/IvanMalison/org-projectile"))]) (org-capture-pop-frame . [(20160518 1008) ((emacs (24 4))) "Run org-capture in a new pop frame" single ((:commit . "b16fd712de62cf0d1f9befd03be6ab5983cb3301") (:authors ("Feng Shu" . "tumashu@163.com")) (:maintainer "Feng Shu" . "tumashu@163.com") (:url . "https://github.com/tumashu/org-capture-pop-frame.git"))]) (org-caldav . [(20180403 2036) ((org (7))) "Sync org files with external calendar through CalDAV" single ((:commit . "8d3492c27a09f437d2d94f2736c56d7652e87aa0") (:keywords "calendar" "caldav") (:authors ("David Engster" . "deng@randomsample.de")) (:maintainer "David Engster" . "deng@randomsample.de"))]) (org-bullets . [(20180208 2343) nil "Show bullets in org-mode as UTF-8 characters" single ((:commit . "b56f2e3812626f2c4ac1686073d102c71f4a8513") (:authors ("sabof")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:url . "https://github.com/emacsorphanage/org-bullets"))]) (org-brain . [(20180712 2110) ((emacs (25)) (org (9))) "Org-mode concept mapping" single ((:commit . "d8dc1c4914c6200eaf44e36bf51a3cf02ef88fb9") (:keywords "outlines" "hypermedia") (:authors ("Erik Sjöstrand" . "sjostrand.erik@gmail.com")) (:maintainer "Erik Sjöstrand" . "sjostrand.erik@gmail.com") (:url . "http://github.com/Kungsgeten/org-brain"))]) (org-bookmark-heading . [(20180904 1709) ((emacs (24 4)) (f (0 17 2))) "Emacs bookmark support for org-mode" single ((:commit . "eba5ef7a3c992c4a9da86f64d12fca0c1158208a") (:keywords "hypermedia" "outlines") (:authors ("Adam Porter" . "adam@alphapapa.net")) (:maintainer "Adam Porter" . "adam@alphapapa.net") (:url . "http://github.com/alphapapa/org-bookmark-heading"))]) (org-board . [(20180530 1820) nil "bookmarking and web archival system for Org mode." single ((:commit . "38de9ff14099bb79b55ddf73b68b8e30ebd7b280") (:keywords "org" "bookmarks" "archives") (:authors ("Charles A. Roelli " . "charles@aurox.ch")) (:maintainer "Charles A. Roelli " . "charles@aurox.ch") (:url . "https://github.com/scallywag/org-board"))]) (org-beautify-theme . [(20170908 2218) nil "A sub-theme to make org-mode more beautiful." single ((:commit . "df6a1114fda313e1689363e196c8284fbe2a2738") (:keywords "org" "theme") (:authors ("Jonathan Arkell" . "jonnay@jonnay.net")) (:maintainer "Jonathan Arkell" . "jonnay@jonnay.net"))]) (org-babel-eval-in-repl . [(20170511 1214) ((eval-in-repl (0 9 2)) (matlab-mode (3 3 6)) (ess (16 10)) (emacs (24))) "Eval org-mode babel code blocks in various REPLs." tar ((:commit . "bfa72c582ac1531ad42aba23e2b1267ab68e31f6") (:keywords "literate programming" "reproducible research" "async execution") (:authors ("Takeshi Teshima" . "diadochos.developer@gmail.com")) (:maintainer "Takeshi Teshima" . "diadochos.developer@gmail.com") (:url . "https://github.com/diadochos/org-babel-eval-in-repl"))]) (org-autolist . [(20170924 1901) nil "Improved list management in org-mode" single ((:commit . "c82d1e83e982b5f0c106b8800e5b0cfd5f73fdc1") (:keywords "lists" "checklists" "org-mode") (:authors ("Calvin Young")) (:maintainer "Calvin Young") (:url . "https://github.com/calvinwyoung/org-autolist"))]) (org-attach-screenshot . [(20180420 525) nil "screenshots integrated with org attachment dirs" single ((:commit . "6b1edbd2384191122a30788ac72f2233c2df0294") (:keywords "org") (:authors ("Derek Feichtinger" . "derek.feichtinger@psi.ch")) (:maintainer "Derek Feichtinger" . "derek.feichtinger@psi.ch") (:url . "https://github.com/dfeich/org-screenshot"))]) (org-alert . [(20180524 133) ((s (1 10 0)) (dash (2 11 0)) (alert (1 2))) "Notify org deadlines via notify-send" single ((:commit . "f87bff4acbd839acb4d2245b56b2c3d21f950911") (:keywords "org" "org-mode" "notify" "notifications" "calendar") (:authors ("Stephen Pegoraro" . "spegoraro@tutive.com")) (:maintainer "Stephen Pegoraro" . "spegoraro@tutive.com") (:url . "https://github.com/groksteve/org-alert"))]) (org-agenda-property . [(20140626 2116) ((emacs (24 2))) "Display org properties in the agenda buffer." single ((:commit . "3b469f3e93de0036547f3631cd0366d53f7584c8") (:keywords "calendar") (:authors ("Artur Malabarba" . "bruce.connor.am@gmail.com")) (:maintainer "Artur Malabarba" . "bruce.connor.am@gmail.com") (:url . "http://github.com/Bruce-Connor/org-agenda-property"))]) (org-ac . [(20170401 1307) ((auto-complete-pcmp (0 0 1)) (log4e (0 2 0)) (yaxception (0 1))) "Some auto-complete sources for org-mode" single ((:commit . "41e3ef8e4039619d0370c23c66730b3b2e9e32ed") (:keywords "org" "completion") (:authors ("Hiroaki Otsu" . "ootsuhiroaki@gmail.com")) (:maintainer "Hiroaki Otsu" . "ootsuhiroaki@gmail.com") (:url . "https://github.com/aki2o/org-ac"))]) (orca . [(20171030 1916) ((emacs (24 3))) "Org Capture" single ((:commit . "5e1744afb793dda744ddc6fe342144b5e90bea08") (:keywords "org" "convenience") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:url . "https://github.com/abo-abo/orca"))]) (operate-on-number . [(20150707 623) nil "Operate on number at point with arithmetic functions" single ((:commit . "ceb3be565a29326c1098244fac0c50606723a56e") (:keywords "editing") (:authors ("Akinori MUSHA" . "knu@iDaemons.org")) (:maintainer "Akinori MUSHA" . "knu@iDaemons.org") (:url . "https://github.com/knu/operate-on-number.el"))]) (openwith . [(20120531 2136) nil "Open files with external programs" single ((:keywords "files" "processes") (:authors ("Markus Triska" . "markus.triska@gmx.at")) (:maintainer "Markus Triska" . "markus.triska@gmx.at") (:url . "https://bitbucket.org/jpkotta/openwith"))]) (openstack-cgit-browse-file . [(20130819 927) nil "Browse the current file in OpenStack cgit" single ((:commit . "244219288b9aef41155044697bb114b7af83ab8f") (:keywords "convenience" "vc" "git" "cgit" "gerrit" "openstack") (:authors ("Chmouel Boudjnah" . "chmouel@chmouel.com")) (:maintainer "Chmouel Boudjnah" . "chmouel@chmouel.com") (:url . "https://github.com/chmouel/openstack-cgit-browse-file"))]) (opensource . [(20160926 1616) ((s (1 11 0)) (dash (2 12 1)) (pkg-info (0 6 0)) (request (0 2 0))) "Client for Opensource API" tar ((:commit . "13499b7ae602c735e40c1c494bda6252a2f1c98f") (:keywords "opensource") (:authors ("Nicolas Lamirault" . "nicolas.lamirault@gmail.com")) (:maintainer "Nicolas Lamirault" . "nicolas.lamirault@gmail.com") (:url . "https://github.com/OpenSourceOrg/el-opensourceorg"))]) (opener . [(20161207 1810) ((request (0 2 0)) (emacs (24)) (cl-lib (0 5))) "opening urls as buffers" tar ((:commit . "c384f67278046fdcd220275fdd212ab85672cbeb") (:keywords "url" "http" "files") (:authors ("Tim Reddehase" . "tr@rightsrestricted.com")) (:maintainer "Tim Reddehase" . "tr@rightsrestricted.com") (:url . "https://github.com/0robustus1/opener.el"))]) (opencl-mode . [(20170816 1249) nil "Syntax coloring for opencl kernels" single ((:commit . "6e69434d0fa6e11a542acad370611bba18d3bc5c") (:keywords "c" "opencl") (:authors ("Salmane Bah" . "salmane.bah@u-bordeaux.fr")) (:maintainer "Salmane Bah" . "salmane.bah@u-bordeaux.fr") (:url . "https://github.com/salmanebah/opencl-mode"))]) (opencc . [(20170722 816) ((emacs (24 4))) "中文简繁转换 <-> 中文簡繁轉換 (Convert Chinese with OpenCC)" single ((:commit . "8c539f72669ba9a99d8b5198db5ea930897ad1b9") (:keywords "chinese") (:authors ("徐春阳" . "mail@xuchunyang.me")) (:maintainer "徐春阳" . "mail@xuchunyang.me") (:url . "https://github.com/xuchunyang/emacs-opencc"))]) (open-junk-file . [(20161210 1114) nil "Open a junk (memo) file to try-and-error" single ((:commit . "558bec7372b0fed4c4cb6074ab906535fae615bd") (:keywords "convenience" "tools") (:authors ("rubikitch" . "rubikitch@ruby-lang.org")) (:maintainer "rubikitch" . "rubikitch@ruby-lang.org") (:url . "http://www.emacswiki.org/cgi-bin/wiki/download/open-junk-file.el"))]) (open-in-msvs . [(20170123 2228) nil "Open current file:line:column in Microsoft Visual Studio" tar ((:commit . "e0d071c83188ad5db8f3297d6ce784b4ed554a04") (:keywords "convenience" "usability" "integration" "visual studio" "msvs" "ide") (:authors ("Evgeny Panasyuk")) (:maintainer "Evgeny Panasyuk") (:url . "https://github.com/evgeny-panasyuk/open-in-msvs"))]) (opam . [(20150719 1220) ((emacs (24 1))) "OPAM tools" single ((:commit . "4d589de5765728f56af7078fae328b6792de8600") (:keywords "convenience") (:authors ("Sebastian Wiesner" . "swiesner@lunaryorn.com")) (:maintainer "Sebastian Wiesner" . "swiesner@lunaryorn.com") (:url . "https://github.com/lunaryorn/opam.el"))]) (one-time-pad-encrypt . [(20160329 1513) nil "One time pad encryption within file" single ((:commit . "87cc1f124024ce3d277299ca0ac703f182937d9f") (:keywords "convenience") (:authors ("Garvin Guan" . "garvin.guan@gmail.com")) (:maintainer "Garvin Guan" . "garvin.guan@gmail.com") (:url . "https://github.com/garvinguan/emacs-one-time-pad/"))]) (one-themes . [(20180507 1708) ((emacs (24))) "One Colorscheme" tar ((:commit . "7677a1801494cf70460e5493908248f1b7c06df1") (:authors ("Balaji Sivaraman" . "balaji@balajisivaraman.com")) (:maintainer "Balaji Sivaraman" . "balaji@balajisivaraman.com") (:url . "http://github.com/balajisivaraman/emacs-one-themes"))]) (on-screen . [(20160302 950) ((cl-lib (0))) "guide your eyes while scrolling" single ((:commit . "206468aa4de299ad26c2db12b757f5ad7290912f") (:keywords "convenience") (:authors ("Michael Heerdegen" . "michael_heerdegen@web.de")) (:maintainer "Michael Heerdegen" . "michael_heerdegen@web.de") (:url . "https://github.com/michael-heerdegen/on-screen.el"))]) (on-parens . [(20180202 2241) ((dash (2 10 0)) (emacs (24)) (evil (1 1 6)) (smartparens (1 6 3))) "smartparens wrapper to fit with evil-mode/vim normal-state" single ((:commit . "7a41bc02bcffd265f8a69ed4b4e0df3c3009aaa4") (:keywords "evil" "smartparens") (:authors ("William G Hatch")) (:maintainer "William G Hatch"))]) (omtose-phellack-theme . [(20161111 2120) nil "A dark theme, with cold bluish touch." tar ((:commit . "66f99633e199e65bd28641626435e8e59246529a"))]) (omnisharp . [(20180805 1624) ((emacs (24 4)) (flycheck (30)) (dash (2 12 0)) (auto-complete (1 4)) (popup (0 5 1)) (csharp-mode (0 8 7)) (cl-lib (0 5)) (s (1 10 0)) (shut-up (0 3 2)) (f (0 19 0))) "Omnicompletion (intellisense) and more for C#" tar ((:commit . "88f574a5fe6ba19c37c49ddb7772a5935c3eac46") (:keywords "languages" "csharp" "c#" "ide" "auto-complete" "intellisense") (:authors ("Mika Vilpas and others")) (:maintainer "Mika Vilpas and others") (:url . "https://github.com/Omnisharp/omnisharp-emacs"))]) (omnibox . [(20180423 49) ((emacs (26 1)) (dash (2 13)) (frame-local (0 0 1))) "Selection package" single ((:commit . "8ee75c71c20c438ebc43ba24ef6f543633d118f3") (:keywords "completion" "selection" "convenience" "frames") (:authors ("Sebastien Chapuis" . "sebastien@chapu.is")) (:maintainer "Sebastien Chapuis" . "sebastien@chapu.is") (:url . "https://github.com/sebastiencs/omnibox"))]) (omni-tags . [(20170426 2109) ((pcre2el (1 7)) (cl-lib (0 5))) "Highlight and Actions for 'Tags'" tar ((:commit . "8f0f6c302fab900b7681e5c039f90850cbbabd33") (:keywords "convenience") (:authors ("Adrien Becchis" . "adriean.khisbe@live.fr")) (:maintainer "Adrien Becchis" . "adriean.khisbe@live.fr") (:url . "http://github.com/AdrieanKhisbe/omni-tags.el"))]) (omni-scratch . [(20171009 2151) nil "Easy and mode-specific draft buffers" single ((:commit . "9eee3161e5cb6df58618548a2173f4da7d194814") (:keywords "convenience" "languages" "tools") (:authors ("Adrien Becchis" . "adriean.khisbe@live.fr")) (:maintainer "Adrien Becchis" . "adriean.khisbe@live.fr") (:url . "https://github.com/AdrieanKhisbe/omni-scratch.el"))]) (omni-quotes . [(20170425 1832) ((dash (2 8)) (omni-log (0 3 3)) (f (0 19 0)) (s (1 11 0)) (ht (2 1))) "Random quotes displayer" tar ((:commit . "454116c1dd6581baaeefd6b9310b1b6b7a5c36d0") (:keywords "convenience") (:authors ("Adrien Becchis" . "adriean.khisbe@live.fr")) (:maintainer "Adrien Becchis" . "adriean.khisbe@live.fr") (:url . "https://github.com/AdrieanKhisbe/omni-quotes.el"))]) (omni-log . [(20170930 1235) ((emacs (24)) (ht (2 0)) (s (1 6 1)) (dash (2 13 0))) "Logging utilities" tar ((:commit . "11e959473c1bd9415d0cda785940c36ba6ad44ab") (:keywords "convenience" "languages" "tools") (:authors ("Adrien Becchis" . "adriean.khisbe@live.fr")) (:maintainer "Adrien Becchis" . "adriean.khisbe@live.fr") (:url . "https://github.com/AdrieanKhisbe/omni-log.el"))]) (omni-kill . [(20171016 2140) nil "Kill all the things" single ((:commit . "904549c8fd6ac3cf22b5d7111ca8944e179cffea") (:keywords "convenience" "editing" "tools") (:authors ("Adrien Becchis" . "adriean.khisbe@live.fr")) (:maintainer "Adrien Becchis" . "adriean.khisbe@live.fr"))]) (om-mode . [(20140915 2110) nil "Insert Om component template with life cycle." single ((:commit . "cdc0c2912321f8438b0f3449ba8aca50ec150bba") (:keywords "clojurescript") (:authors ("Daniel Szmulewicz" . "daniel.szmulewicz@gmail.com")) (:maintainer "Daniel Szmulewicz" . "daniel.szmulewicz@gmail.com"))]) (olivetti . [(20180531 737) ((emacs (24 4))) "Minor mode for a nice writing environment" single ((:commit . "02272654f1d920ea2da5a4b553acd5e5cc096ab1") (:keywords "wp" "text") (:authors ("Paul Rankin" . "hello@paulwrankin.com")) (:maintainer "Paul Rankin" . "hello@paulwrankin.com") (:url . "https://github.com/rnkn/olivetti"))]) (oldlace-theme . [(20150705 1300) ((emacs (24))) "Emacs 24 theme with an 'oldlace' background." single ((:commit . "5c6f437203b0783b36a7aff4a578de4a0c8c4ee6") (:authors ("martin haesler")) (:maintainer "martin haesler"))]) (old-norse-input . [(20170816 1842) ((emacs (24))) "An input method for Old Norse" single ((:commit . "c2e21ee72c3768e9152aff6baf12a19cde1d0c53") (:keywords "languages") (:authors ("David Christiansen" . "david@davidchristiansen.dk")) (:maintainer "David Christiansen" . "david@davidchristiansen.dk") (:url . "https://github.com/david-christiansen/emacs-old-norse-input"))]) (offlineimap . [(20150916 1158) nil "Run OfflineIMAP from Emacs" single ((:commit . "cc3e067e6237a1eb7b21c575a41683b1febb47f1") (:authors ("Julien Danjou" . "julien@danjou.info")) (:maintainer "Julien Danjou" . "julien@danjou.info") (:url . "http://julien.danjou.info/offlineimap-el.html"))]) (octopress . [(20170813 1315) nil "A lightweight wrapper for Jekyll and Octopress." tar ((:commit . "b4c25df9e3ccf49ac27c0a152daa4e27d1247d56") (:keywords "octopress" "blog") (:authors ("Aaron Bieber" . "aaron@aaronbieber.com")) (:maintainer "Aaron Bieber" . "aaron@aaronbieber.com") (:url . "https://github.com/aaronbieber/octopress.el"))]) (octo-mode . [(20161008 1229) ((emacs (24))) "Major mode for Octo assembly language" single ((:commit . "bd4db7e5e3275b24c74e6a23c11d04f54e9feca5") (:keywords "languages") (:authors ("John Olsson" . "john@cryon.se")) (:maintainer "John Olsson" . "john@cryon.se") (:url . "https://github.com/cryon/octo-mode"))]) (octicons . [(20151101 340) ((cl-lib (0 5))) "octicons utility" tar ((:commit . "a61e561966ffd8faa3b48ce5b3a4eec10c59708b") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-octicons"))]) (ocp-indent . [(20180417 1549) nil "automatic indentation with ocp-indent" single ((:commit . "4830ebf5d1c1b8f47bc152ff13d2c6aa1aad705b") (:keywords "ocaml" "languages") (:url . "http://www.typerex.org/ocp-indent.html"))]) (ocodo-svg-modelines . [(20150516 1419) ((svg-mode-line-themes (0))) "A collection of beautiful SVG modelines" tar ((:commit . "c7b0789a177219f117c4de5659ecfa8622958c40"))]) (oceanic-theme . [(20161015 819) nil "Oceanic theme." single ((:commit . "a92ee9b470843c923e6cdcafdd65106ff994d04d") (:keywords "oceanic" "color" "theme") (:authors ("Tengfei Guo")) (:maintainer "Tengfei Guo") (:url . "https://github.com/terry3/oceanic-theme"))]) (occur-x . [(20130610 1343) nil "Extra functionality for occur" single ((:commit . "352f5fab207d8a1d3dd048073ff127a83e97c82b") (:keywords "occur" "search" "convenience") (:authors ("Juan-Leon Lahoz" . "juanleon1@gmail.com")) (:maintainer "Juan-Leon Lahoz" . "juanleon1@gmail.com"))]) (occur-context-resize . [(20170904 2309) nil "dynamically resize context around matches in occur-mode" single ((:commit . "cdee5a631ceed9337579d4090e0acf8140747f80") (:keywords "matching") (:authors ("Charles L.G. Comstock" . "dgtized@gmail.com")) (:maintainer "Charles L.G. Comstock" . "dgtized@gmail.com") (:url . "https://github.com/dgtized/occur-context-resize.el"))]) (occidental-theme . [(20130312 1958) nil "Custom theme for faces based on Adwaita" single ((:commit . "fd2db7256d4f78c43d99c3cddb1c39106d479816") (:authors ("William Stevenson" . "yhvh2000@gmail.com") ("Erik Timan" . "dev@timan.info")) (:maintainer "William Stevenson" . "yhvh2000@gmail.com") (:url . "http://github.com/olcai/occidental-theme"))]) (obsidian-theme . [(20170719 948) nil "port of the eclipse obsidian theme" single ((:commit . "f45efb2ebe9942466c1db6abbe2d0e6847b785ea") (:authors ("martin haesler")) (:maintainer "martin haesler") (:url . "http://github.com/mswift42/obsidian-theme"))]) (objc-font-lock . [(20141021 1822) nil "Highlight Objective-C method calls." single ((:commit . "34b457d577f97ca94b8792d025f9a909c7610612") (:keywords "languages" "faces") (:authors ("Anders Lindgren")) (:maintainer "Anders Lindgren") (:url . "https://github.com/Lindydancer/objc-font-lock"))]) (obfusurl . [(20170809 1524) ((cl-lib (0 5))) "Obfuscate URLs so they aren't spoilers" single ((:commit . "7a5a41905000ce2ec1fd72509a5567e5fd9f47e5") (:keywords "convenience" "web" "text") (:authors ("Dave Pearson" . "davep@davep.org")) (:maintainer "Dave Pearson" . "davep@davep.org") (:url . "https://github.com/davep/obfusurl.el"))]) (oberon . [(20120715 909) nil "Major mode for editing Oberon/Oberon-2 program texts" single ((:commit . "fb57d18ce13835a8a69b6bafecdd9193ca9a59a3") (:keywords "oberon" "oberon-2" "languages" "oop") (:authors ("Karl Landström" . "karl@karllandstrom.se")) (:maintainer "Karl Landström" . "karl@karllandstrom.se"))]) (ob-uart . [(20170521 858) nil "org-babel support for UART communication" single ((:commit . "90daeac90a9e75c20cdcf71234c67b812110c50e") (:keywords "tools" "comm" "org-mode" "uart" "literate programming" "reproducible development") (:authors ("Andreas Müller")) (:maintainer "Andreas Müller") (:url . "https://www.0x7.ch"))]) (ob-typescript . [(20150804 1230) ((emacs (24)) (org (8 0))) "org-babel functions for typescript evaluation" single ((:commit . "9dcbd226cbfb75e790dd9de91d9401dde85a889a") (:keywords "literate programming" "reproducible research" "typescript") (:authors ("KURASHIKI Satoru")) (:maintainer "KURASHIKI Satoru") (:url . "https://github.com/lurdan/ob-typescript"))]) (ob-translate . [(20170720 1919) ((google-translate (0 11)) (org (8))) "Translation of text blocks in org-mode." single ((:commit . "9d9054a51bafd5a29a8135964069b4fa3a80b169") (:keywords "org" "babel" "translate" "translation") (:authors ("Kris Jenkins" . "krisajenkins@gmail.com")) (:maintainer "Kris Jenkins" . "krisajenkins@gmail.com") (:url . "https://github.com/krisajenkins/ob-translate"))]) (ob-tmux . [(20180831 1017) ((emacs (25 1)) (seq (2 3)) (s (1 9 0))) "Babel Support for Interactive Terminal" single ((:commit . "73bed0ebad27f0ad57ea67582494543eb2fab73d") (:keywords "literate programming" "interactive shell" "tmux") (:authors ("Allard Hendriksen")) (:maintainer "Allard Hendriksen") (:url . "https://github.com/ahendriksen/ob-tmux"))]) (ob-swift . [(20170921 1325) ((org (8))) "org-babel functions for swift evaluation" single ((:commit . "ed478ddbbe41ce5373efde06b4dd0c3663c9055f") (:keywords "org" "babel" "swift") (:authors ("Feng Zhou" . "zf.pascal@gmail.com")) (:maintainer "Feng Zhou" . "zf.pascal@gmail.com") (:url . "http://github.com/zweifisch/ob-swift"))]) (ob-sql-mode . [(20180426 1911) ((emacs (24 4))) "SQL code blocks evaluated by sql-mode" single ((:commit . "8f38e4a882f79a53a96dc6f2a0a17b7878a461ad") (:keywords "languages" "org" "org-babel" "sql") (:authors (nil . "Nik Clayton nik@google.com")) (:maintainer nil . "Nik Clayton nik@google.com") (:url . "http://github.com/nikclayton/ob-sql-mode"))]) (ob-sml . [(20130829 1843) ((sml-mode (6 4))) "org-babel functions for template evaluation" single ((:commit . "958165c92b6cff6cada5c85c8ae5887806b8451b") (:keywords "literate programming" "reproducible research") (:authors ("David Nolen")) (:maintainer "David Nolen") (:url . "http://orgmode.org"))]) (ob-sagemath . [(20170131 233) ((sage-shell-mode (0 0 8)) (s (1 8 0)) (emacs (24))) "org-babel functions for SageMath evaluation" tar ((:commit . "68d3e516c712bc7aa5042f305f3eb5bbb6d656c2") (:keywords "sagemath" "org-babel") (:authors ("Sho Takemori" . "stakemorii@gmail.com")) (:maintainer "Sho Takemori" . "stakemorii@gmail.com") (:url . "https://github.com/stakemori/ob-sagemath"))]) (ob-rust . [(20180606 2346) nil "Org-babel functions for Rust" tar ((:commit . "a0e3c62ac3d4d44ae73746b5a45c04322c908bd3") (:keywords "rust" "languages" "org" "babel") (:authors ("Mican Zhang")) (:maintainer "Mican Zhang") (:url . "https://github.com/micanzhang/ob-rust"))]) (ob-restclient . [(20180904 709) ((restclient (0))) "org-babel functions for restclient-mode" single ((:commit . "00b2c5a6637ab6e504708612357ffb29b5416e4b") (:keywords "literate programming" "reproducible research") (:authors ("Alf Lervåg")) (:maintainer "Alf Lervåg") (:url . "http://orgmode.org"))]) (ob-prolog . [(20180720 1044) nil "org-babel functions for prolog evaluation." single ((:commit . "85ada8fc1f523167f137746c82d823a194160141") (:keywords "literate programming" "reproducible research") (:authors ("Bjarte Johansen")) (:maintainer "Bjarte Johansen") (:url . "https://github.com/ljos/ob-prolog"))]) (ob-nim . [(20170809 1830) ((cl-lib (0 5))) "Babel Functions for nim" single ((:commit . "bf1642cb93f0a898804dc13fd9408d2964403bd2") (:keywords "literate programming" "reproducible research") (:authors ("Lompik")) (:maintainer "Lompik"))]) (ob-mongo . [(20170720 1919) ((org (8))) "Execute mongodb queries within org-mode blocks." single ((:commit . "371bf19c7c10eab2f86424f8db8ab685997eb5aa") (:keywords "org" "babel" "mongo" "mongodb") (:authors ("Kris Jenkins" . "krisajenkins@gmail.com")) (:maintainer "Kris Jenkins" . "krisajenkins@gmail.com") (:url . "https://github.com/krisajenkins/ob-mongo"))]) (ob-ml-marklogic . [(20170622 1833) nil "org-babel functions for MarkLogic evaluation" tar ((:commit . "f678af0f440b3030e311ed6fbc444200be04da91") (:keywords "marklogic" "xquery" "javascript" "sparql") (:authors ("Norman Walsh" . "ndw@nwalsh.com")) (:maintainer "Norman Walsh" . "ndw@nwalsh.com") (:url . "http://github.com/ndw/ob-ml-marklogic"))]) (ob-mermaid . [(20180522 1659) nil "org-babel support for mermaid evaluation" single ((:commit . "31ed3e2d3d84c0a08a0a1a3985e87a92caea6f00") (:keywords "lisp") (:authors ("Alexei Nunez" . "alexeirnunez@gmail.com")) (:maintainer "Alexei Nunez" . "alexeirnunez@gmail.com") (:url . "https://github.com/arnm/ob-mermaid"))]) (ob-lfe . [(20170725 1420) ((org (8))) "org-babel functions for lfe evaluation" single ((:commit . "f7780f58e650b4d29dfd834c662b1d354b620a8e") (:keywords "org" "babel" "lfe" "lisp" "erlang") (:authors ("ZHOU Feng" . "zf.pascal@gmail.com")) (:maintainer "ZHOU Feng" . "zf.pascal@gmail.com") (:url . "http://github.com/zweifisch/ob-lfe"))]) (ob-kotlin . [(20180823 1321) ((org (8))) "org-babel functions for kotlin evaluation" single ((:commit . "96e420cbd2e9ea8a77043e5dcaebdfc6da17492a") (:keywords "org" "babel" "kotlin") (:authors ("ZHOU Feng" . "zf.pascal@gmail.com")) (:maintainer "ZHOU Feng" . "zf.pascal@gmail.com") (:url . "http://github.com/zweifisch/ob-kotlin"))]) (ob-ipython . [(20180224 953) ((s (1 9 0)) (dash (2 10 0)) (dash-functional (1 2 0)) (f (0 17 2)) (emacs (24))) "org-babel functions for IPython evaluation" tar ((:commit . "7147455230841744fb5b95dcbe03320313a77124") (:keywords "literate programming" "reproducible research") (:authors ("Greg Sexton" . "gregsexton@gmail.com")) (:maintainer "Greg Sexton" . "gregsexton@gmail.com") (:url . "http://www.gregsexton.org"))]) (ob-hy . [(20180702 540) ((emacs (24 4))) "org-babel functions for Hy-lang evaluation" tar ((:commit . "a42ecaf440adc03e279afe43ee5ef6093ddd542a") (:keywords "hy" "literate programming" "reproducible research") (:authors ("Brantou" . "brantou89@gmail.com")) (:maintainer "Brantou" . "brantou89@gmail.com") (:url . "https://github.com/brantou/ob-hy"))]) (ob-http . [(20180707 1448) ((s (1 9 0)) (cl-lib (0 5))) "http request in org-mode babel" tar ((:commit . "b1428ea2a63bcb510e7382a1bf5fe82b19c104a7") (:authors ("ZHOU Feng" . "zf.pascal@gmail.com")) (:maintainer "ZHOU Feng" . "zf.pascal@gmail.com") (:url . "http://github.com/zweifisch/ob-http"))]) (ob-go . [(20170731 1757) nil "org-babel functions for go evaluation" tar ((:commit . "28a0250cd969974936e44dfdccb0265632d25f84") (:keywords "golang" "go" "literate programming" "reproducible research") (:authors ("K. Adam Christensen")) (:maintainer "K. Adam Christensen") (:url . "http://orgmode.org"))]) (ob-fsharp . [(20170618 1429) ((emacs (25)) (fsharp-mode (1 9 8))) "Org-Babel F#" single ((:commit . "0b2fdd9bb4f38af8b5cf4914627af52f5b43d9f7") (:keywords "literate programming" "reproducible research") (:authors ("Jürgen Hötzel" . "juergen@archlinux.org")) (:maintainer "Jürgen Hötzel" . "juergen@archlinux.org") (:url . "https://github.com/juergenhoetzel/ob-fsharp"))]) (ob-elvish . [(20180427 1900) nil "org-babel functions for Elvish shell" single ((:commit . "369181ceae1190bf971c71aebf9fc6133bd98c39") (:keywords "literate programming" "elvish" "shell" "languages" "processes" "tools") (:authors ("Diego Zamboni" . "diego@zzamboni.org")) (:maintainer "Diego Zamboni" . "diego@zzamboni.org") (:url . "https://github.com/zzamboni/ob-elvish"))]) (ob-elixir . [(20170725 1419) ((org (8))) "org-babel functions for elixir evaluation" single ((:commit . "8990a8178b2f7bd93504a9ab136622aab6e82e32") (:keywords "org" "babel" "elixir") (:authors ("ZHOU Feng" . "zf.pascal@gmail.com")) (:maintainer "ZHOU Feng" . "zf.pascal@gmail.com") (:url . "http://github.com/zweifisch/ob-elixir"))]) (ob-diagrams . [(20160407 1237) nil "org-babel functions for diagrams evaluation" single ((:commit . "ed6649616325ca5b2d2109f74aded8bcb8aa5186") (:keywords "literate programming" "reproducible research") (:authors ("Daniel Bergey")) (:maintainer "Daniel Bergey") (:url . "http://orgmode.org"))]) (ob-dart . [(20170106 1624) nil "org-babel functions for Dart evaluation" single ((:commit . "04d63b922a5469506560ca0c00678e57131e0269") (:keywords "literate programming" "reproducible research" "emacs" "org" "babel" "dart") (:authors ("Milan Zimmermann")) (:maintainer "Milan Zimmermann") (:url . "http://github.org/mzimmerm/ob-dart"))]) (ob-dao . [(20170816 1558) ((org (8))) "Org Babel Functions for Dao" single ((:commit . "fa92f62a63c684d689f57e790e5dd614c5bba270") (:keywords "literate programming" "reproducible research" "org" "babel" "dao") (:authors ("Chunyang Xu" . "mail@xuchunyang.me")) (:maintainer "Chunyang Xu" . "mail@xuchunyang.me") (:url . "https://github.com/xuchunyang/ob-dao"))]) (ob-cypher . [(20170725 1420) ((s (1 9 0)) (cypher-mode (0 0 6)) (dash (2 10 0)) (dash-functional (1 2 0))) "query neo4j using cypher in org-mode blocks" single ((:commit . "114bdf6db20ee0ade060bb5df379ddee48ff4f26") (:keywords "org" "babel" "cypher" "neo4j") (:authors ("ZHOU Feng" . "zf.pascal@gmail.com")) (:maintainer "ZHOU Feng" . "zf.pascal@gmail.com") (:url . "http://github.com/zweifisch/ob-cypher"))]) (ob-crystal . [(20180126 718) ((emacs (24 3))) "org-babel functions for Crystal evaluation" tar ((:commit . "d84c1adee4b269cdba06a97caedb8071561a09af") (:keywords "crystal" "literate programming" "reproducible research") (:authors ("Brantou" . "brantou89@gmail.com")) (:maintainer "Brantou" . "brantou89@gmail.com") (:url . "https://github.com/brantou/ob-crystal"))]) (ob-coffeescript . [(20180126 719) ((emacs (24 4))) "org-babel functions for coffee-script evaluation, and fully implementation!" single ((:commit . "5a5bb04aea9c2a6eab5b05f90f5c7cb6de7b4261") (:keywords "coffee-script" "literate programming" "reproducible research") (:authors ("Brantou" . "brantou89@gmail.com")) (:maintainer "Brantou" . "brantou89@gmail.com") (:url . "https://github.com/brantou/ob-coffeescript"))]) (ob-coffee . [(20170725 1424) ((org (8))) "org-babel functions for coffee-script evaluation" tar ((:commit . "7f0b330273e8af7777de87a75fe52a89798e4548") (:keywords "org" "babel" "coffee-script") (:authors ("ZHOU Feng" . "zf.pascal@gmail.com")) (:maintainer "ZHOU Feng" . "zf.pascal@gmail.com") (:url . "http://github.com/zweifisch/ob-coffee"))]) (ob-clojurescript . [(20180406 1828) ((emacs (24 4)) (org (9 0))) "org-babel functions for ClojureScript evaluation" single ((:commit . "17ee1558aa94c7b0246fd03f684884122806cfe7") (:keywords "literate programming" "reproducible research") (:authors ("Larry Staton Jr.")) (:maintainer "Larry Staton Jr.") (:url . "https://gitlab.com/statonjr/ob-clojurescript"))]) (ob-cfengine3 . [(20180102 1812) nil "Org Babel functions for CFEngine 3" single ((:commit . "93ebcfceec3734f4bd187ae123686187d66fd401") (:keywords "tools" "convenience") (:authors ("Nick Anderson" . "nick@cmdln.org")) (:maintainer "Nick Anderson" . "nick@cmdln.org") (:url . "https://github.com/nickanderson/ob-cfengine3"))]) (ob-browser . [(20170720 1918) ((org (8))) "Render HTML in org-mode blocks." tar ((:commit . "a347d9df1c87b7eb660be8723982c7ad2563631a") (:keywords "org" "babel" "browser" "phantomjs") (:authors ("Kris Jenkins" . "krisajenkins@gmail.com")) (:maintainer "Kris Jenkins" . "krisajenkins@gmail.com") (:url . "https://github.com/krisajenkins/ob-browser"))]) (ob-blockdiag . [(20170728 101) nil "org-babel functions for blockdiag evaluation" single ((:commit . "634fcf64a4ae735afe7001d865b03f5d71e23046") (:keywords "tools" "convenience") (:authors ("Dmitry Moskowski")) (:maintainer "Dmitry Moskowski") (:url . "https://github.com/corpix/ob-blockdiag.el"))]) (ob-axiom . [(20171103 2248) ((emacs (24 2)) (axiom-environment (20171021))) "An org-babel backend for the axiom-environment system" single ((:commit . "5d6b2cd12f639c11b032185c4c5fe4f5bba15b08") (:keywords "axiom" "openaxiom" "fricas") (:authors ("Paul Onions")) (:maintainer "Paul Onions"))]) (ob-async . [(20180816 1553) ((async (1 9)) (org (9 0 1)) (emacs (24 4)) (dash (2 14 1))) "Asynchronous org-babel src block execution" single ((:commit . "2470490e6efb3f8efde1702f7986f6e31cc1ab6c") (:keywords "tools") (:authors ("Andrew Stahlman" . "andrewstahlman@gmail.com")) (:maintainer "Andrew Stahlman" . "andrewstahlman@gmail.com") (:url . "https://github.com/astahlman/ob-async"))]) (ob-applescript . [(20160914 2027) nil "org-babel functions for template evaluation" single ((:commit . "bc708af6cf45707d4e8d8f00ea59a7e413bfaca7") (:keywords "literate programming" "reproducible research" "mac") (:authors ("Stig Brautaset")) (:maintainer "Stig Brautaset") (:url . "http://github.com/stig/ob-applescript.el"))]) (oauth . [(20130128 151) nil "Oauth library." tar ((:commit . "ee4744ad76a1560281b0c4944575a3bd598c6458") (:keywords "comm") (:authors ("Peter Sanford <peter AT petersdanceparty.com>")) (:maintainer "Peter Sanford <peter AT petersdanceparty.com>"))]) (o-blog . [(20151202 2339) nil "Standalone orgmode blog exporter" tar ((:commit . "e466c59478feddc8126c43c1b98550474af484c0") (:keywords "emacs") (:authors ("Sébastien Gross <seb•ɑƬ•chezwam•ɖɵʈ•org>")) (:maintainer "Sébastien Gross <seb•ɑƬ•chezwam•ɖɵʈ•org>"))]) (nyx-theme . [(20170910 1307) ((emacs (24))) "Dark theme" single ((:commit . "afe2b8c3b5421b4c292d182dcf77079b278e93d8") (:keywords "themes" "dark-theme") (:authors ("Guido Schmidt")) (:maintainer "Guido Schmidt" . "guido.schmidt.2912@gmail.com") (:url . "https://github.com/GuidoSchmidt/emacs-nyx-theme"))]) (nyan-mode . [(20170423 740) nil "Nyan Cat shows position in current buffer in mode-line." tar ((:commit . "a85ac925367ddc542827182a2d9f0133b421c41b") (:keywords "nyan" "cat" "lulz" "scrolling" "pop tart cat" "build something amazing") (:authors ("Jacek \"TeMPOraL\" Zlydach" . "temporal.pl@gmail.com")) (:maintainer "Jacek \"TeMPOraL\" Zlydach" . "temporal.pl@gmail.com") (:url . "https://github.com/TeMPOraL/nyan-mode/"))]) (nvm . [(20171217 1636) ((s (1 8 0)) (dash (2 4 0)) (f (0 14 0)) (dash-functional (2 4 0))) "Manage Node versions within Emacs" single ((:commit . "bc0a33257ec16e9f575bb6914b5949199897ada9") (:keywords "node" "nvm") (:authors ("Johan Andersson" . "johan.rejeep@gmail.com")) (:maintainer "Johan Andersson" . "johan.rejeep@gmail.com") (:url . "http://github.com/rejeep/nvm.el"))]) (nv-delete-back . [(20170224 1249) ((emacs (24))) "backward delete like modern text editors" single ((:commit . "44d506105989873dc1725e0cfc675925b35c9c98") (:keywords "lisp") (:authors ("Nicolas Vaughan <n.vaughan [at] oxon.org>")) (:maintainer "Nicolas Vaughan <n.vaughan [at] oxon.org>"))]) (nummm-mode . [(20131117 1014) nil "Display the number of minor modes instead of their names" single ((:commit . "81951e12032274543c5f7a585b29bd93961e94e4") (:authors ("Andreu Gil" . "agpchil@gmail.com")) (:maintainer "Andreu Gil" . "agpchil@gmail.com") (:url . "http://github.com/agpchil/nummm-mode"))]) (numbers . [(20170802 1134) ((emacs (24))) "Display information and trivia about numbers" single ((:commit . "dd02508b788a13b7d4dbcc4923fa23134b783ab3") (:keywords "games" "trivia" "maths" "numbers") (:authors ("Dave Pearson" . "davep@davep.org")) (:maintainer "Dave Pearson" . "davep@davep.org") (:url . "https://github.com/davep/numbers.el"))]) (number-lock . [(20160830 200) nil "Enter symbols on your number keys without pressing shift" single ((:commit . "74417b1238953bf485961a0dd7d20f5c36ae25ea") (:keywords "convenience") (:authors ("Liu233w" . "wwwlsmcom@outlook.com")) (:maintainer "Liu233w" . "wwwlsmcom@outlook.com") (:url . "https://github.com/Liu233w/number-lock.el"))]) (number . [(20170901 1312) nil "Working with numbers at point." single ((:commit . "bbc278d34dbcca83e70e3be855ec98b23debfb99"))]) (nubox . [(20170619 910) nil "Nubox color theme (dark, light and tty versions)" tar ((:commit . "1ccb8035ae42727ba6bdd5c1106fbceddeeed370") (:keywords "faces") (:authors ("Martijn Terpstra" . "bigmartijn@gmail.com")) (:maintainer "Martijn Terpstra" . "bigmartijn@gmail.com"))]) (nu-mode . [(20180903 2045) ((undo-tree (0 6 5)) (ace-window (0)) (avy (0)) (which-key (0)) (transpose-frame (0))) "Modern Emacs Prompts Based Keybinding." tar ((:commit . "08b3e49e59091753551510e978340b530452d69d"))]) (nsis-mode . [(20180719 308) nil "NSIS-mode" tar ((:commit . "a49f5dbc8a5e60d3bbb803582efb5468bbbe7507") (:keywords "nsis") (:authors ("Matthew L. Fidler")) (:maintainer "Matthew L. Fidler") (:url . "http://github.com/mlf176f2/nsis-mode"))]) (nrepl-sync . [(20140807 1554) ((cider (0 6))) "connect to nrepl port and eval .sync.clj." single ((:commit . "bab53a2361526d63a24cda176d07a1247bf5b399") (:authors ("Phillip Lord" . "phillip.lord@newcastle.ac.uk")) (:maintainer "Phillip Lord" . "phillip.lord@newcastle.ac.uk") (:url . "https://github.com/phillord/lein-sync"))]) (nrepl-eval-sexp-fu . [(20140311 1041) ((highlight (0 0 0)) (smartparens (0 0 0)) (thingatpt (0 0 0))) "Tiny functionality enhancements for evaluating sexps." single ((:commit . "3a24b7d4bca13e87c987a4ddd212da914ff59191") (:keywords "lisp" "highlight" "convenience") (:authors ("Takeshi Banse" . "takebi@laafc.net")) (:maintainer "Takeshi Banse" . "takebi@laafc.net"))]) (npm-mode . [(20180720 1701) ((emacs (24 1))) "minor mode for working with npm projects" single ((:commit . "4f4b9fc2c07290ae87f65179df95be5221e76bf2") (:keywords "convenience" "project" "javascript" "node" "npm") (:authors ("Allen Gooch" . "allen.gooch@gmail.com")) (:maintainer "Allen Gooch" . "allen.gooch@gmail.com") (:url . "https://github.com/mojochao/npm-mode"))]) (noxml-fold . [(20170823 1357) nil "Fold away XML things." single ((:commit . "46c7f6a008672213238a9f8d7a416ce80916aa62") (:keywords "xml" "folding") (:authors ("Patrick McAllister" . "pma@rdorte.org")) (:maintainer "Patrick McAllister" . "pma@rdorte.org") (:url . "https://github.com/paddymcall/noxml-fold"))]) (nova-theme . [(20180530 1501) ((emacs (24 3))) "A dark, pastel color theme" single ((:commit . "2f41855ac250d822d2e8cec4610c8645718bd7e3") (:keywords "theme" "dark" "nova" "pastel" "faces") (:authors ("Muir Manders" . "muir+emacs@mnd.rs")) (:maintainer "Muir Manders" . "muir+emacs@mnd.rs") (:url . "https://github.com/muirmanders/emacs-nova-theme"))]) (nov . [(20180617 2144) ((dash (2 12 0)) (esxml (0 3 3)) (emacs (24 4))) "Featureful EPUB reader mode" single ((:commit . "3be6e8cd1a6311b0782ca2aa3d9961bec6183632") (:keywords "hypermedia" "multimedia" "epub") (:authors ("Vasilij Schneidermann" . "mail@vasilij.de")) (:maintainer "Vasilij Schneidermann" . "mail@vasilij.de") (:url . "https://github.com/wasamasa/nov.el"))]) (notmuch-labeler . [(20131230 1719) ((notmuch (0))) "Improve notmuch way of displaying labels" tar ((:commit . "d65d1129555d368243df4770ecc1e7ccb88efc58") (:keywords "emacs" "package" "elisp" "notmuch" "emails") (:authors ("Damien Cassou" . "damien.cassou@gmail.com")) (:maintainer "Damien Cassou" . "damien.cassou@gmail.com") (:url . "https://github.com/DamienCassou/notmuch-labeler"))]) (notmuch . [(20180829 927) nil "run notmuch within emacs" tar ((:commit . "dfda1745bf6efa993de8c842511e1a52c0694fd2") (:url . "https://notmuchmail.org/"))]) (nose . [(20140520 1648) nil "Easy Python test running in Emacs" single ((:keywords "nose" "python" "testing"))]) (northcode-theme . [(20180423 1649) ((emacs (24))) "A dark theme focused on blue and orange colors." single ((:commit . "4d3750461ba25ec45321318b5f1af4e8fdf16147") (:authors ("Andreas Larsen" . "andreas@northcode.no")) (:maintainer "Andreas Larsen" . "andreas@northcode.no") (:url . "https://github.com/Northcode/northcode-theme.el"))]) (nordless-theme . [(20180613 750) nil "A mostly colorless theme" single ((:commit . "e4da9d2465a123ea28e33a507cc7ab69692cde86") (:keywords "theme" "dark") (:authors ("Thomas Letan" . "contact@thomasletan.fr")) (:maintainer "Thomas Letan" . "contact@thomasletan.fr") (:url . "https://github.com/lethom/nordless-theme.el"))]) (nord-theme . [(20180102 1801) ((emacs (24))) "An arctic, north-bluish clean and elegant theme" single ((:commit . "b5c1dc762fe3acaa88a0ce9640085d45d0109c43") (:authors ("Arctic Ice Studio" . "development@arcticicestudio.com")) (:maintainer "Arctic Ice Studio" . "development@arcticicestudio.com") (:url . "https://github.com/arcticicestudio/nord-emacs"))]) (nofrils-acme-theme . [(20180620 1248) ((emacs (24))) "Port of \"No Frils Acme\" Vim theme." tar ((:commit . "98ad7bfaff1d85b33dc162645670285b067c6f92") (:authors ("Eric Sessoms" . "esessoms@protonmail.com")) (:maintainer "Eric Sessoms" . "esessoms@protonmail.com") (:url . "https://gitlab.com/esessoms/nofrils-theme"))]) (noflet . [(20141102 1454) nil "locally override functions" single ((:commit . "7ae84dc3257637af7334101456dafe1759c6b68a") (:keywords "lisp") (:authors ("Nic Ferrier" . "nferrier@ferrier.me.uk")) (:maintainer "Nic Ferrier" . "nferrier@ferrier.me.uk") (:url . "https://github.com/nicferrier/emacs-noflet"))]) (nodenv . [(20180830 1217) ((emacs (24 4))) "Integration with nodenv" single ((:commit . "7ea70f1ee6c7bee422b9d090a49af6041ed81668") (:keywords "node" "environment" "tools") (:authors ("Gong Qijian" . "gongqijian@gmail.com")) (:maintainer "Gong Qijian" . "gongqijian@gmail.com") (:url . "https://github.com/twlz0ne/nodenv.el"))]) (nodemcu-mode . [(20180501 2225) ((emacs (25))) "Minor mode for NodeMCU" single ((:commit . "8effd9f3df40b6b92a2f05e4d54750b624afc4a7") (:keywords "tools") (:authors ("Andreas Müller" . "code@0x7.ch")) (:maintainer "Andreas Müller" . "code@0x7.ch") (:url . "https://github.com/andrmuel/nodemcu-mode"))]) (nodejs-repl . [(20170722 1143) nil "Run Node.js REPL" single ((:commit . "4a4104dbf2cd314e90f35d200f28bd93c34708d0") (:authors ("Takeshi Arabiki")) (:maintainer "Takeshi Arabiki"))]) (node-resolver . [(20140930 1723) ((cl-lib (0 5))) "hook to install node modules in background" single ((:commit . "ef9d0486907a746a80b02ffc6208a09c168a9f7c") (:keywords "convenience" "nodejs" "javascript" "npm") (:authors ("Dave Justice")) (:maintainer "Dave Justice") (:url . "https://github.com/meandavejustice/node-resolver.el"))]) (noctilux-theme . [(20161113 1442) ((emacs (24))) "Dark theme inspired by LightTable" single ((:commit . "a3265a1be7f4d73f44acce6d968ca6f7add1f2ca") (:authors ("Simon Manning" . "simon@ecksdee.org")) (:maintainer "Simon Manning" . "simon@ecksdee.org") (:url . "https://github.com/sjrmanning/noctilux-theme"))]) (nocomments-mode . [(20170213 2037) nil "Minor mode that makes comments invisible." single ((:commit . "5a41a20cc44dfe4a9ea584354ed6dbc15dd92f46") (:authors ("Anders Lindgren")) (:maintainer "Anders Lindgren") (:url . "https://github.com/Lindydancer/nocomments-mode"))]) (noccur . [(20150514 2120) nil "Run multi-occur on project/dired files" single ((:commit . "6cc02ce07178a61ae38a849f80472c01969272bc") (:keywords "convenience") (:authors ("Nicolas Petton" . "petton.nicolas@gmail.com")) (:maintainer "Nicolas Petton" . "petton.nicolas@gmail.com"))]) (noaa . [(20180419 1833) ((request (0 2 0)) (cl-lib (0 5)) (emacs (24))) "Get NOAA weather data" single ((:commit . "e99f7702512de49f93138dce6e0a7cfe2bc5eed3") (:authors ("David Thompson")) (:maintainer "David Thompson") (:url . "https://github.com/thomp/noaa"))]) (no-littering . [(20180825 1351) ((cl-lib (0 5))) "help keeping ~/.emacs.d clean" single ((:commit . "3f6d290bb43d75ba749d56fffc21c15f1d4157d2") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:url . "https://github.com/emacscollective/no-littering"))]) (no-emoji . [(20180515 1837) ((emacs (24))) "Show :emoji-name: instead of emoji characters" single ((:commit . "ebceeab50dbfe4d60235180a57633745dbc18c77") (:keywords "extensions") (:authors ("Peter" . "craven@gmx.net")) (:maintainer "Peter" . "craven@gmx.net") (:url . "https://github.com/ecraven/no-emoji"))]) (nnir-est . [(20180710 2103) nil "Gnus nnir interface for HyperEstraier" single ((:commit . "6d0d5c8e33f4e4ccbc22350324c0990d2676fb5a") (:keywords "mail") (:authors ("KAWABATA, Taichi <kawabata.taichi_at_gmail.com>")) (:maintainer "KAWABATA, Taichi <kawabata.taichi_at_gmail.com>") (:url . "https://github.com/kawabata/nnir-est"))]) (nm . [(20151110 1910) ((notmuch (0 21)) (peg (0 6)) (company (0)) (emacs (24 3))) "NEVERMORE: an email interface for Notmuch" tar ((:commit . "5a3f29174b3a4b2b2e7a700a862f3b16a942687e") (:authors ("Trevor Jim")) (:maintainer "Trevor Jim") (:url . "https://github.com/tjim/nevermore"))]) (nlinum-relative . [(20160526 708) ((emacs (24 4)) (nlinum (1 5))) "Relative line number with nlinum" single ((:commit . "5b9950c97ba79a6f0683e38b13da23f39e01031c") (:keywords "convenience") (:authors ("codefalling" . "code.falling@gmail.com")) (:maintainer "codefalling" . "code.falling@gmail.com"))]) (nlinum-hl . [(20170614 48) ((emacs (24 4)) (nlinum (1 7)) (cl-lib (0 5))) "heal nlinum's line numbers" single ((:commit . "d5ca1490e0cde0605e34a6a17de8cc236c9810da") (:keywords "nlinum" "highlight" "current" "line" "faces") (:authors ("Henrik Lissner <http://github/hlissner>")) (:maintainer "Henrik Lissner" . "henrik@lissner.net") (:url . "https://github.com/hlissner/emacs-nlinum-hl"))]) (nixos-options . [(20160209 1841) ((emacs (24))) "Interface for browsing and completing NixOS options." single ((:commit . "7007363e773a419203a69798fb0e0731b2eb0f73") (:keywords "unix") (:authors ("Diego Berrocal" . "cestdiego@gmail.com") ("Travis B. Hartwell" . "nafai@travishartwell.net")) (:maintainer "Diego Berrocal" . "cestdiego@gmail.com") (:url . "http://www.github.com/travisbhartwell/nix-emacs/"))]) (nix-update . [(20180425 48) ((emacs (25))) "Update \"fetch\" blocks in .nix expressions" single ((:commit . "d92b2c190dbaeb16751be724fe381f8a796c424c") (:keywords "nix") (:authors ("John Wiegley" . "johnw@newartisans.com")) (:maintainer "John Wiegley" . "johnw@newartisans.com") (:url . "https://github.com/jwiegley/nix-update-el"))]) (nix-sandbox . [(20171004 1706) ((dash (2 12 1)) (s (1 10 0))) "Utility functions to work with nix-shell sandboxes" single ((:commit . "7007363e773a419203a69798fb0e0731b2eb0f73") (:authors ("Sven Keidel" . "svenkeidel@gmail.com")) (:maintainer "Sven Keidel" . "svenkeidel@gmail.com") (:url . "https://github.com/travisbhartwell/nix-emacs"))]) (nix-mode . [(20180822 214) ((emacs (24 3))) "Major mode for editing .nix files" tar ((:commit . "38061187ca16fa9973622777e6087730b72ebfc1") (:keywords "nix" "languages" "tools" "unix") (:maintainer "Matthew Bauer" . "mjbauer95@gmail.com") (:url . "https://github.com/NixOS/nix-mode"))]) (nix-buffer . [(20180212 1518) ((f (0 17 3)) (emacs (24 4))) "Set up buffer environments with nix" single ((:commit . "db57cda36e7477bdc7ef5a136357b971b1d4d099") (:authors ("Shea Levy")) (:maintainer "Shea Levy") (:url . "https://github.com/shlevy/nix-buffer/tree/master/"))]) (ninja-mode . [(20141204 559) ((emacs (24))) "Major mode for editing .ninja files" single ((:commit . "ca041d88f4d610332aa48c801342edfafb622ccb"))]) (nimbus-theme . [(20180607 236) nil "An awesome dark theme" single ((:commit . "d4adcf0e821648aef066f9b97808a3c691615749") (:keywords "faces") (:authors ("Marcin Swieczkowski" . "scatman@bu.edu")) (:maintainer "Marcin Swieczkowski" . "scatman@bu.edu") (:url . "https://github.com/m-cat/nimbus-theme"))]) (nim-mode . [(20180516 2009) ((emacs (24 4)) (epc (0 1 1)) (let-alist (1 0 1)) (commenter (0 5 1)) (flycheck-nimsuggest (0 8 1))) "A major mode for the Nim programming language" tar ((:commit . "35f4b2cb2d4c142f6f7f0e3ffb06c87b81bb8c26") (:keywords "nim" "languages") (:authors ("Simon Hafner")) (:maintainer "Simon Hafner" . "hafnersimon@gmail.com"))]) (nikola . [(20170703 2021) ((async (1 5)) (emacs (24 3))) "Simple wrapper for nikola" single ((:commit . "964715ac30943c9d6976999cad208dc60d09def0") (:keywords ":" "nikola") (:authors (": drymer <drymer [ AT ] autistici.org>")) (:maintainer ": drymer <drymer [ AT ] autistici.org>") (:url . ": https://git.daemons.it/drymer/nikola.el"))]) (night-owl-theme . [(20180630 2131) ((emacs (24))) "A color theme for the night owls out there" single ((:commit . "6c73732986015c6a36919f16096d5e4f81b516ad") (:authors ("Aaron Jensen" . "aaronjensen@gmail.com")) (:maintainer "Aaron Jensen" . "aaronjensen@gmail.com") (:url . "http://github.com/aaronjensen/night-owl-theme"))]) (niconama . [(20170910 1501) ((emacs (24)) (request (20170131 1747)) (cl-lib (0 5))) "Tools for Niconico Live Broadcast" single ((:commit . "96e7553e50e6bf7b58aac50f52c9b0b8edb41c56") (:keywords "comm") (:url . "https://github.com/NOBUTOKA/niconama.el"))]) (niceify-info . [(20160416 1244) nil "improve usability of Info pages" single ((:commit . "38df5062bc3b99d1074cab3e788b5ed66732111c"))]) (nginx-mode . [(20170612 437) nil "major mode for editing nginx config files" single ((:commit . "a2bab83c2eb233d57d76b236e7c141c2ccc97005") (:keywords "languages" "nginx") (:authors ("Andrew J Cosgriff" . "andrew@cosgriff.name")) (:maintainer "Andrew J Cosgriff" . "andrew@cosgriff.name"))]) (ng2-mode . [(20180521 31) ((typescript-mode (0 1))) "Major modes for editing Angular 2" tar ((:commit . "177248bca3787fabab70f3026ccf390395171f0d") (:keywords "typescript" "angular" "angular2" "template") (:authors ("Adam Niederer" . "adam.niederer@gmail.com")) (:maintainer "Adam Niederer" . "adam.niederer@gmail.com") (:url . "http://github.com/AdamNiederer/ng2-mode"))]) (nexus . [(20140114 1305) nil "REST Client for Nexus Maven Repository servers" tar ((:commit . "c46f499951b90839aa8683779fe43d8f01672a60") (:keywords "comm") (:authors ("Juergen Hoetzel" . "juergen@archlinux.org")) (:maintainer "Juergen Hoetzel" . "juergen@archlinux.org"))]) (newlisp-mode . [(20160226 1545) nil "newLISP editing mode for Emacs" single ((:commit . "ac23be40c81a360988ab803d365f1510733f6db4") (:keywords "language" "lisp" "newlisp") (:authors ("KOBAYASHI Shigeru <shigeru.kb[at]gmail.com>")) (:maintainer "KOBAYASHI Shigeru <shigeru.kb[at]gmail.com>") (:url . "https://github.com/kosh04/newlisp-mode"))]) (never-comment . [(20140104 2207) nil "Never blocks are comment" single ((:commit . "74ded8f1e7f23240f5f6032d0451fb0a51733bc4") (:authors ("Scott Frazer")) (:maintainer "Toon Claes") (:url . "http://stackoverflow.com/a/4554658/89376"))]) (network-watch . [(20171123 1146) ((emacs (24 3))) "Support for intermittent network connectivity" single ((:commit . "958dd0d419e4f9402648a86b754091ba346e01b8") (:keywords "unix" "tools" "hardware" "lisp") (:authors ("Juan Amiguet Vercher" . "jamiguet@gmail.com")) (:maintainer "Juan Amiguet Vercher" . "jamiguet@gmail.com") (:url . "https://github.com/jamiguet/network-watch"))]) (netrunner . [(20160910 2332) ((popup (0 5 3)) (company (0 9 0)) (helm (1 9 5))) "Create Android: Netrunner decklists using Company, Helm and org-mode" single ((:commit . "c64672992175c8c1073c0f56c2e471839db71a0f") (:keywords "games") (:authors ("Erik Sjöstrand")) (:maintainer "Erik Sjöstrand") (:url . "http://github.com/Kungsgeten/netrunner"))]) (netherlands-holidays . [(20150202 1617) nil "Netherlands holidays for Emacs calendar." single ((:commit . "26236178cdd650df9958bf5a086e184096559f00") (:keywords "calendar") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:url . "https://github.com/abo-abo/netherlands-holidays"))]) (netease-music . [(20180430 122) ((names (0 5)) (emacs (25))) "listen netease music" single ((:commit . "a48dbe96429540d41abcc0b88d5d33532fca734d") (:keywords "multimedia" "chinese" "music") (:authors ("hiro方圆" . "wfy11235813@gmail.com")) (:maintainer "hiro方圆" . "wfy11235813@gmail.com") (:url . "https://github.com/nicehiro/netease-music"))]) (nerdtab . [(20180811 339) ((emacs (24 5))) "Keyboard-oriented tabs" single ((:commit . "601d531fa3748db733fbdff157a0f1cdf8a66416") (:keywords "convenience") (:authors ("Yuan Fu" . "casouri@gmail.com")) (:maintainer "Yuan Fu" . "casouri@gmail.com") (:url . "https://github.com/casouri/nerdtab"))]) (neotree . [(20180616 1603) ((cl-lib (0 5))) "A tree plugin like NerdTree for Vim" tar ((:commit . "4f8d80fd51c712df7b11ae8491be3527db46f612") (:authors ("jaypei" . "jaypei97159@gmail.com")) (:maintainer "jaypei" . "jaypei97159@gmail.com") (:url . "https://github.com/jaypei/emacs-neotree"))]) (neon-mode . [(20180406 1156) nil "Simple major mode for editing neon files" single ((:commit . "99d15e46beaf1e7d71e39a00cce810df1f33229d") (:keywords "conf") (:authors ("Matúš Goljer" . "matus.goljer@gmail.com")) (:maintainer "Matúš Goljer" . "matus.goljer@gmail.com"))]) (nemerle . [(20161029 2023) nil "major mode for editing nemerle programs" single ((:commit . "59b28607968a9bee060b42eac55c69c37d1c0e69") (:keywords "nemerle" "mode" "languages") (:authors ("Jacek Sliwerski (rzyjontko)" . "rzyj@o2.pl")) (:maintainer "Jacek Sliwerski (rzyjontko)" . "rzyj@o2.pl"))]) (neato-graph-bar . [(20171231 153) ((emacs (24 3))) "Neat-o graph bars CPU/memory etc." single ((:commit . "c59f15ed9a40aecc174aa22c4bbfa7978e182705") (:authors ("Robert Cochran" . "robert-git@cochranmail.com")) (:maintainer "Robert Cochran" . "robert-git@cochranmail.com") (:url . "https://gitlab.com/RobertCochran/neato-graph-bar"))]) (nclip . [(20130617 2015) nil "Network (HTTP) Clipboard" tar ((:commit . "af88e38b1f04be02bf2e57affc662dbd0f828e67") (:keywords "nclip" "clipboard" "network") (:authors ("Marian Schubert" . "marian.schubert@gmail.com")) (:maintainer "Marian Schubert" . "marian.schubert@gmail.com") (:url . "http://www.github.com/maio/nclip.el"))]) (ncl-mode . [(20180129 703) ((emacs (24))) "Major Mode for editing NCL scripts and other goodies" tar ((:commit . "602292712a9e6b7e7c25155978999e77d06b7338"))]) (navorski . [(20141203 1824) ((s (1 9 0)) (dash (1 5 0)) (multi-term (0 8 14))) "Helping you live in the terminal, like Viktor did." single ((:commit . "698c1c62da70164aebe9a7a5d034778fbc30ea5b") (:keywords "terminal") (:authors ("Roman Gonzalez <romanandreg@gmail.com>, Tavis Rudd" . "tavis@birdseye-sw.com")) (:maintainer "Roman Gonzalez" . "romanandreg@gmail.com"))]) (navi2ch . [(20150330 216) nil "Navigator for 2ch for Emacsen" tar ((:commit . "f39d93c32acd5b9c3a7fb1a9fe14c5e1c4b5288e") (:keywords "network" "2ch") (:authors ("Taiki SUGAWARA" . "taiki@users.sourceforge.net")) (:maintainer "Taiki SUGAWARA" . "taiki@users.sourceforge.net"))]) (navi-mode . [(20180516 248) ((outshine (2 0)) (outorg (2 0))) "major-mode for easy buffer-navigation" single ((:commit . "7c3fd1a9b520300abfdb1b7c3de21403e81a95bf") (:maintainer "Adam Porter") (:url . "https://github.com/alphapapa/navi"))]) (nav-flash . [(20140508 2041) nil "Briefly highlight the current line" single ((:commit . "53f5bc59e3f32c1192d15637d3979732dacb2c35") (:keywords "extensions" "navigation" "interface") (:authors ("Roland Walker" . "walker@pobox.com")) (:maintainer "Roland Walker" . "walker@pobox.com") (:url . "http://github.com/rolandwalker/nav-flash"))]) (nav . [(20120507 707) nil "Emacs mode for filesystem navigation" tar ((:commit . "c5eb234c063f435dbdcd1f8bdc46cfc68c973ebe") (:authors ("Issac Trotts" . "issactrotts@google.com")) (:maintainer "Issac Trotts" . "issactrotts@google.com"))]) (nasm-mode . [(20180711 1909) ((emacs (24 3))) "NASM x86 assembly major mode" single ((:commit . "1d4871ef184fc5da792bccbae1ea189f876706fc") (:authors ("Christopher Wellons" . "wellons@nullprogram.com")) (:maintainer "Christopher Wellons" . "wellons@nullprogram.com") (:url . "https://github.com/skeeto/nasm-mode"))]) (nash-mode . [(20160830 1212) nil "Nash major mode" single ((:commit . "2cd96535eb7d669a94306183e95ee37333872c1a") (:keywords "nash" "languages") (:authors ("Tiago Natel de Moura")) (:maintainer "Tiago Natel de Moura") (:url . "https://github.com/tiago4orion/nash-mode.el"))]) (narrowed-page-navigation . [(20150109 519) ((emacs (24)) (cl-lib (0 5))) "A minor mode for showing one page at a time" single ((:commit . "b215adbac4873f56fbab65772062f0f5be8058a1") (:keywords "outlines") (:authors ("David Raymond Christiansen" . "david@davidchristiansen.dk")) (:maintainer "David Raymond Christiansen" . "david@davidchristiansen.dk"))]) (narrow-reindent . [(20150722 1906) ((emacs (24 4))) "Defines a minor mode to left-align narrowed regions." single ((:commit . "87466aac4dbeb79597124dd077bf5c704872fd3d") (:authors ("J David Smith" . "emallson@atlanis.net")) (:maintainer "J David Smith" . "emallson@atlanis.net") (:url . "https://github.com/emallson/narrow-reindent.el"))]) (naquadah-theme . [(20180212 1240) nil "A theme based on Tango color set" single ((:commit . "999056526db5095ce600c83672fc80cb744bd93e"))]) (nanowrimo . [(20151105 228) nil "Track progress for nanowrimo" single ((:authors ("Ivan Andrus <darthandrus at gmail.com>")) (:maintainer "Ivan Andrus <darthandrus at gmail.com>") (:url . "https://bitbucket.org/gvol/nanowrimo-mode"))]) (nand2tetris-assembler . [(20171201 1813) ((nand2tetris (1 1 0))) "Assembler For the Nand2tetris Course" single ((:commit . "33acee34d24b1c6a87db833b7d23449cf858f64f") (:keywords "nand2tetris-assembler" "hdl") (:authors ("Diego Berrocal" . "cestdiego@gmail.com")) (:maintainer "Diego Berrocal" . "cestdiego@gmail.com") (:url . "http://www.github.com/CestDiego/nand2tetris-assembler.el/"))]) (nand2tetris . [(20171201 1813) ((emacs (24))) "Major mode for HDL files in the nand2tetris course" tar ((:commit . "33acee34d24b1c6a87db833b7d23449cf858f64f") (:keywords "nand2tetris" "hdl") (:authors ("Diego Berrocal" . "cestdiego@gmail.com")) (:maintainer "Diego Berrocal" . "cestdiego@gmail.com") (:url . "http://www.github.com/CestDiego/nand2tetris.el/"))]) (namespaces . [(20130326 2250) nil "An implementation of namespaces for Elisp, with an emphasis on immutabilty." single ((:commit . "3d02525d9b9a5ae6e7be3adefd880121436e6270") (:authors ("Chris Barrett")) (:maintainer "Chris Barrett") (:url . "https://github.com/chrisbarrett/elisp-namespaces"))]) (names . [(20180321 1155) ((emacs (24 1)) (cl-lib (0 5))) "Namespaces for emacs-lisp. Avoid name clobbering without hiding symbols." tar ((:commit . "d8baba5360e5253938a25d3e005455b6d2d86971") (:keywords "extensions" "lisp") (:authors ("Artur Malabarba" . "emacs@endlessparentheses.com")) (:maintainer "Artur Malabarba" . "emacs@endlessparentheses.com") (:url . "https://github.com/Malabarba/names"))]) (nameless . [(20180215 2221) ((emacs (24 4))) "Hide package namespace in your emacs-lisp code" single ((:commit . "3cd4ade5433c8e2041dfff9d9624d9e676d9c5ee") (:keywords "convenience" "lisp") (:authors ("Artur Malabarba" . "emacs@endlessparentheses.com")) (:maintainer "Artur Malabarba" . "emacs@endlessparentheses.com") (:url . "https://github.com/Malabarba/nameless"))]) (nameframe-projectile . [(20160928 403) ((nameframe (0 4 1 -2)) (projectile (0 13 0))) "Nameframe integration with Projectile" single ((:commit . "aafb8c5c5fbe0510e2f5d5b6b6b5dd0b73abe5d8") (:authors ("John Del Rosario" . "john2x@gmail.com")) (:maintainer "John Del Rosario" . "john2x@gmail.com") (:url . "https://github.com/john2x/nameframe"))]) (nameframe-perspective . [(20170406 119) ((nameframe (0 4 1 -2)) (perspective (1 12))) "Nameframe integration with perspective.el" single ((:commit . "aafb8c5c5fbe0510e2f5d5b6b6b5dd0b73abe5d8") (:authors ("John Del Rosario" . "john2x@gmail.com")) (:maintainer "John Del Rosario" . "john2x@gmail.com") (:url . "https://github.com/john2x/nameframe"))]) (nameframe . [(20171107 56) nil "Manage frames by name." single ((:commit . "aafb8c5c5fbe0510e2f5d5b6b6b5dd0b73abe5d8") (:authors ("John Del Rosario" . "john2x@gmail.com")) (:maintainer "John Del Rosario" . "john2x@gmail.com") (:url . "https://github.com/john2x/nameframe"))]) (name-this-color . [(20151014 2030) ((emacs (24)) (cl-lib (0 5)) (dash (2 11 0))) "Match RGB codes to names easily and precisely" single ((:commit . "e37cd1291d5d68d4c8d6386eab9cb9d94fd3bcfa") (:keywords "lisp" "color" "hex" "rgb" "shade" "name") (:url . "https://github.com/knl/name-this-color.el"))]) (n4js . [(20150714 231) ((emacs (24)) (cypher-mode (0))) "Neo4j Shell" single ((:commit . "3991ed8975151d5e8d568e952362df810f7ffab7") (:keywords "neo4j" "shell" "comint") (:authors ("TruongTx" . "me@truongtx.me")) (:maintainer "TruongTx" . "me@truongtx.me") (:url . "https://github.com/tmtxt/n4js.el"))]) (myterminal-controls . [(20170426 236) ((emacs (24)) (cl-lib (0 5))) "Quick toggle controls at a key-stroke" single ((:commit . "aae4f50f9f22d374eaaac2ce95e522f13dcc8fc0") (:keywords "convenience" "shortcuts") (:authors ("Mohammed Ismail Ansari" . "team.terminal@gmail.com")) (:maintainer "Mohammed Ismail Ansari" . "team.terminal@gmail.com") (:url . "http://ismail.teamfluxion.com"))]) (mysql2sqlite . [(20170725 2216) nil "Convert mysql databases into sqlite databases." single ((:commit . "8e6e74451c942e2e92f90dc13222b95a7dbb285e"))]) (mysql-to-org . [(20180123 1514) ((emacs (24 3)) (s (1 11 0))) "Minor mode to output the results of mysql queries to org tables" single ((:commit . "2526205ad484ad3fa38d41e7d537ace38c27645c") (:authors ("Tijs Mallaerts" . "tijs.mallaerts@gmail.com")) (:maintainer "Tijs Mallaerts" . "tijs.mallaerts@gmail.com"))]) (mynt-mode . [(20150512 2049) ((virtualenvwrapper (20131514))) "Minor mode to work with the mynt static site generator" single ((:commit . "23d4489167bfa899634548cb41ed32fdeb3600c9") (:keywords "convenience") (:authors ("Christian Brassat")) (:maintainer "Christian Brassat") (:url . "https://github.com/crshd/mynt-mode"))]) (mykie . [(20150808 2205) ((emacs (24 3)) (cl-lib (0 5))) "Command multiplexer: Register multiple functions to a keybind" tar ((:commit . "7676f0e883af1d1054e404e97691f3c13aba196f") (:keywords "emacs" "configuration" "keybind") (:authors ("Yuta Yamada <cokesboy\"at\"gmail.com>")) (:maintainer "Yuta Yamada <cokesboy\"at\"gmail.com>") (:url . "https://github.com/yuutayamada/mykie-el"))]) (myanmar-input-methods . [(20160106 1537) nil "Emacs Input Method for Myanmar" single ((:commit . "9d4e0d6358c61bde7a2274e430ef71683faea32e") (:keywords "myanmar" "unicode" "keyboard") (:authors ("Ye Lin Kyaw" . "yelinkyaw@gmail.com")) (:maintainer "Ye Lin Kyaw" . "yelinkyaw@gmail.com") (:url . "http://github.com/yelinkyaw/emacs-myanmar-input-methods"))]) (mxf-view . [(20180501 740) ((emacs (25))) "Simple MXF viewer" single ((:commit . "6ca3cc93d995fac5fc4d72275e1e984e9857ffcb") (:keywords "data" "multimedia") (:authors ("Tomotaka SUWA" . "tomotaka.suwa@gmail.com")) (:maintainer "Tomotaka SUWA" . "tomotaka.suwa@gmail.com") (:url . "https://github.com/t-suwa/mxf-view"))]) (mwim . [(20180227 1652) nil "Switch between the beginning/end of line or code" single ((:commit . "462207227b98a6a4356d51419f5ad5ba9356e5cf") (:keywords "convenience") (:authors ("Alex Kost" . "alezost@gmail.com")) (:maintainer "Alex Kost" . "alezost@gmail.com") (:url . "https://github.com/alezost/mwim.el"))]) (mw-thesaurus . [(20180629 525) ((emacs (25))) "Merriam-Webster Thesaurus" single ((:commit . "b3f8c3aae2b68a4e6cc054c6c99d3b3135e781d1") (:keywords "wp" "matching") (:authors ("Ag Ibragimov")) (:maintainer "Ag Ibragimov") (:url . "https://github.com/agzam/mw-thesaurus.el"))]) (mvn . [(20160211 1543) nil "helpers for compiling with maven" single ((:commit . "8a65b4eb88c9801aa3bff1921b600c72dfb8791a") (:keywords "compilation" "maven" "java") (:authors ("Andrew Gwozdziewycz" . "git@apgwoz.com")) (:maintainer "Andrew Gwozdziewycz" . "git@apgwoz.com") (:url . "https://github.com/apgwoz/mvn-el"))]) (mutant . [(20160124 1353) ((emacs (24 4)) (dash (2 1 0))) "An interface for the Mutant testing tool" single ((:commit . "de9cdefe48c880128a8f62c6699d7416e9c8ced1") (:keywords "mutant" "testing") (:authors ("Pedro Lambert")) (:maintainer "Pedro Lambert") (:url . "http://github.com/p-lambert/mutant.el"))]) (mustard-theme . [(20170808 1319) ((emacs (24 0))) "an Emacs 24 theme based on Mustard (tmTheme)" single ((:commit . "3b15d992c79590d7ea2503004e2a863b57e274b5") (:authors ("Jason Milkins")) (:maintainer "Jason Milkins") (:url . "https://github.com/emacsfodder/tmtheme-to-deftheme"))]) (mustang-theme . [(20170719 946) nil "port of vim's mustang theme" single ((:commit . "dda6d04803f1c9b196b620ef564e7768fee15de2") (:authors ("martin haesler")) (:maintainer "martin haesler") (:url . "http://github.com/mswift42/mustang-theme"))]) (mustache-mode . [(20141024 1432) nil "A major mode for editing Mustache files." single ((:commit . "bf9897eb287ca47ced65d7d4e07ea61ea0aec39f") (:authors ("Tony Gentilcore") ("Chris Wanstrath") ("Daniel Hackney")) (:maintainer "Tony Gentilcore"))]) (mustache . [(20170923 1233) ((ht (0 9)) (s (1 3 0)) (dash (1 2 0))) "a mustache templating library in emacs lisp" tar ((:commit . "5e39654b933a18131146a0f3b3e3dc55c5058124"))]) (multitran . [(20180320 1656) ((emacs (24)) (cl-lib (0 5))) "Interface to multitran" single ((:commit . "d826eff6ada28799a9ff6c8a4c2884b2ef1e36fb") (:keywords "dictionary" "hypermedia") (:authors ("Zajcev Evgeny" . "zevlg@yandex.ru")) (:maintainer "Zajcev Evgeny" . "zevlg@yandex.ru"))]) (multiple-cursors . [(20180615 1218) ((cl-lib (0 5))) "Multiple cursors for Emacs." tar ((:commit . "9c49874fa444a4e7255ec05f62c01daed31c7b09"))]) (multifiles . [(20130615 2133) nil "View and edit parts of multiple files in one buffer" single ((:commit . "dddfe64b8e1c1cd1f9ccc1f03405477fc0d53897") (:keywords "multiple" "files") (:authors ("Magnar Sveen" . "magnars@gmail.com")) (:maintainer "Magnar Sveen" . "magnars@gmail.com"))]) (multicolumn . [(20150202 2251) nil "Creating and managing multiple side-by-side windows." single ((:commit . "c7a3afecd470859b2e60aa7c554d6e4d436df7fa") (:authors ("Anders Lindgren")) (:maintainer "Anders Lindgren") (:url . "https://github.com/Lindydancer/multicolumn"))]) (multi-web-mode . [(20130824 354) nil "multiple major mode support for web editing" tar ((:commit . "ad1c8d1c870334052d244c7ae3636cb7b9357b7c") (:keywords "convenience" "languages" "wp") (:authors ("Fabián E. Gallina" . "fabian@anue.biz")) (:maintainer "Fabián E. Gallina" . "fabian@anue.biz") (:url . "https://github.com/fgallina/multi-web-mode"))]) (multi-term . [(20160619 933) nil "Managing multiple terminal buffers in Emacs." single ((:commit . "f954e4e18b0a035151d34852387e724d87a3316f") (:keywords "term" "terminal" "multiple buffer") (:authors ("Andy Stewart" . "lazycat.manatee@gmail.com")) (:maintainer "Andy Stewart" . "lazycat.manatee@gmail.com") (:url . "http://www.emacswiki.org/emacs/download/multi-term.el"))]) (multi-run . [(20180122 1509) ((emacs (24)) (window-layout (1 4))) "Manage multiple terminals and run commands on them" single ((:commit . "51586c9afd4a55356b0b42436d97fcbcefba5aaf") (:keywords "tools" "terminals") (:authors ("Sagar Jha")) (:maintainer "Sagar Jha") (:url . "https://www.github.com/sagarjha/multi-run"))]) (multi-project . [(20171217 2011) ((emacs (25))) "Find files, compile, search, and switch between" single ((:keywords "convenience" "project" "management") (:authors ("Shawn Ellis" . "shawn.ellis17@gmail.com")) (:maintainer "Shawn Ellis" . "shawn.ellis17@gmail.com") (:url . "https://bitbucket.org/ellisvelo/multi-project/overview"))]) (multi-line . [(20170822 226) ((emacs (24 3)) (s (1 9 0)) (cl-lib (0 5)) (dash (2 12 0)) (shut-up (0 3 2))) "multi-line statements" tar ((:commit . "d5ae863ced0adeb7032ada398005f27a6c669d79") (:keywords "multi" "line" "length" "whitespace" "programming" "tools" "convenience" "files") (:authors ("Ivan Malison" . "IvanMalison@gmail.com")) (:maintainer "Ivan Malison" . "IvanMalison@gmail.com") (:url . "https://github.com/IvanMalison/multi-line"))]) (multi-compile . [(20160306 2223) ((emacs (24)) (dash (2 12 1))) "Multi target interface to compile." single ((:commit . "bd0331854774e7a269ce8a7dd49580cd397c0ec2") (:keywords "tools" "compile" "build") (:authors ("Kvashnin Vladimir" . "reangd@gmail.com")) (:maintainer "Kvashnin Vladimir" . "reangd@gmail.com") (:url . "https://github.com/ReanGD/emacs-multi-compile"))]) (multi . [(20131013 1544) ((emacs (24))) "Clojure-style multi-methods for emacs lisp" single ((:commit . "0987ab71692717ed457cb3984de184db9185806d") (:keywords "multimethod" "generic" "predicate" "dispatch") (:authors ("Christina Whyte" . "kurisu.whyte@gmail.com")) (:maintainer "Christina Whyte" . "kurisu.whyte@gmail.com") (:url . "http://github.com/kurisuwhyte/emacs-multi"))]) (muban . [(20180415 1219) ((emacs (25))) "Lightweight template expansion tool" single ((:commit . "7078e439ee0433a8fbd1cb174464496f9a9d00fa") (:keywords "abbrev" "tools") (:authors ("Jiahao Li" . "jiahaowork@gmail.com")) (:maintainer "Jiahao Li" . "jiahaowork@gmail.com") (:url . "https://github.com/jiahaowork/muban.el"))]) (mu4e-query-fragments . [(20170923 1322) ((emacs (24 4))) "mu4e query fragments extension" single ((:commit . "34ddad4e6785f575333efcc66153d892daa1c884") (:keywords "mu4e" "mail" "convenience") (:authors ("Yuri D'Elia" . "wavexx@thregr.org")) (:maintainer "Yuri D'Elia" . "wavexx@thregr.org") (:url . "https://github.com/wavexx/mu4e-query-fragments.el"))]) (mu4e-maildirs-extension . [(20180606 812) ((dash (0 0 0))) "Show mu4e maildirs summary in mu4e-main-view" single ((:commit . "3ef4c48516be66e73d24fe764aadbcfc126b7964") (:authors ("Andreu Gil Pàmies" . "agpchil@gmail.com")) (:maintainer "Andreu Gil Pàmies" . "agpchil@gmail.com") (:url . "http://github.com/agpchil/mu4e-maildirs-extension"))]) (mu4e-jump-to-list . [(20180425 1832) ((emacs (24 4)) (cl-lib (0 5))) "mu4e jump-to-list extension" single ((:commit . "e336ffe84b55edaaf4e48040d4d9156a9f4c881e") (:keywords "mu4e" "mail" "convenience") (:authors ("Yuri D'Elia" . "wavexx@thregr.org")) (:maintainer "Yuri D'Elia" . "wavexx@thregr.org") (:url . "https://github.com/wavexx/mu4e-jump-to-list.el"))]) (mu4e-conversation . [(20180827 845) ((emacs (25 1))) "Show a complete thread in a single buffer" single ((:commit . "32236a1a296a5f8e31673040fb2f0c008afd7d5f") (:keywords "mail" "convenience" "mu4e") (:authors ("Pierre Neidhardt" . "mail@ambrevar.xyz")) (:maintainer "Pierre Neidhardt" . "mail@ambrevar.xyz") (:url . "https://gitlab.com/Ambrevar/mu4e-conversation"))]) (mu4e-alert . [(20180305 646) ((alert (1 2)) (s (1 10 0)) (ht (2 0)) (emacs (24 3))) "Desktop notification for mu4e" single ((:commit . "96a293b28646f4620e257f24748becc4a06843cd") (:keywords "mail" "convenience") (:authors ("Iqbal Ansari" . "iqbalansari02@yahoo.com")) (:maintainer "Iqbal Ansari" . "iqbalansari02@yahoo.com") (:url . "https://github.com/iqbalansari/mu4e-alert"))]) (mu-cite . [(20160130 1100) ((flim (1 14 9))) "A library to provide MIME features." tar ((:commit . "aea3c2d01eb3284d5e0124059d368e8c6b6ffddc"))]) (mtg-deck-mode . [(20180613 2010) ((emacs (25 1))) "Major mode to edit MTG decks" tar ((:commit . "8265b8ed17fcd4406760c19aa6ee9c76068b1ab0") (:keywords "data" "mtg" "magic") (:authors ("Mattias Bengtsson" . "mattias.jc.bengtsson@gmail.com")) (:maintainer "Mattias Bengtsson" . "mattias.jc.bengtsson@gmail.com") (:url . "https://github.com/mattiasb/mtg-deck-mode"))]) (msvc . [(20171225 1538) ((emacs (24)) (cl-lib (0 5)) (cedet (1 0)) (ac-clang (2 0 0))) "Microsoft Visual C/C++ mode" tar ((:commit . "dfc529aa6da8b46b0a0c7db9a0e5e9bc33ab1fb3") (:keywords "languages" "completion" "syntax check" "mode" "intellisense") (:authors ("yaruopooner [https://github.com/yaruopooner]")) (:maintainer "yaruopooner [https://github.com/yaruopooner]") (:url . "https://github.com/yaruopooner/msvc"))]) (mqtt-mode . [(20180605 1731) ((emacs (25)) (dash (2 12 0))) "client for interaction with MQTT servers" single ((:commit . "36d1d4296d79e17b8f35e8e14f2708980eb502db") (:keywords "tools") (:authors ("Andreas Müller" . "code@0x7.ch")) (:maintainer "Andreas Müller" . "code@0x7.ch") (:url . "https://github.com/andrmuel/mqtt-mode"))]) (mqr . [(20180527 1204) ((emacs (24 4))) "Multi-dimensional query and replace" single ((:commit . "4ade19d4620b8b61340290bf63fa56d5e493859f") (:keywords "convenience" "extensions" "lisp") (:authors ("Tino Calancha" . "tino.calancha@gmail.com")) (:maintainer "Tino Calancha" . "tino.calancha@gmail.com") (:url . "https://github.com/calancha/multi-replace"))]) (mpv . [(20180602 1014) ((cl-lib (0 5)) (emacs (24)) (json (1 3)) (org (8 0))) "control mpv for easy note-taking" single ((:commit . "9dedf3b7c1bfd778284df7f394207ce0447ea7aa") (:keywords "tools" "multimedia") (:authors ("Johann Klähn" . "kljohann@gmail.com")) (:maintainer "Johann Klähn" . "kljohann@gmail.com") (:url . "https://github.com/kljohann/mpv.el"))]) (mpmc-queue . [(20180303 2029) ((emacs (26 0)) (queue (0 2 0))) "a multiple-producer-multiple-consumer queue" single ((:commit . "df07d6bef7468edb1d73ef73b8331b94d0e5d0ca") (:keywords "lisp" "async") (:authors ("Sho Mizoe" . "sho.mizoe@gmail.com")) (:maintainer "Sho Mizoe" . "sho.mizoe@gmail.com") (:url . "https://github.com/smizoe/mpmc-queue"))]) (mpdel . [(20180606 1212) ((emacs (25 1)) (libmpdel (0 7 0))) "Play and control your MPD music" tar ((:commit . "a1e05828e3bc03679530b4cfff1306706171cb78") (:keywords "multimedia") (:authors ("Damien Cassou" . "damien@cassou.me")) (:maintainer "Damien Cassou" . "damien@cassou.me") (:url . "https://gitlab.petton.fr/mpdel/mpdel"))]) (mpages . [(20150710 1404) nil "An Emacs buffer for quickly writing your Morning Pages" single ((:commit . "39a72a0931ab1cdbfdf0ab9f412dc12d43a3829f") (:authors ("Sean Levin")) (:maintainer "Sean Levin") (:url . "https://github.com/slevin/mpages"))]) (mozc-temp . [(20160228 840) ((emacs (24)) (dash (2 10 0)) (mozc (0))) "Use mozc temporarily" single ((:commit . "9d6b645eff901ea79dbc43a55d5a97ead3f4bad7") (:authors ("Hiroki YAMAKAWA" . "s06139@gmail.com")) (:maintainer "Hiroki YAMAKAWA" . "s06139@gmail.com") (:url . "https://github.com/HKey/mozc-temp"))]) (mozc-popup . [(20150224 34) ((popup (0 5 2)) (mozc (0))) "Mozc with popup" single ((:commit . "f0684b875a7427ec08f8df13939a486e5d5cf420") (:keywords "i18n" "extentions") (:authors ("Daisuke Kobayashi" . "d5884jp@gmail.com")) (:maintainer "Daisuke Kobayashi" . "d5884jp@gmail.com"))]) (mozc-im . [(20160412 22) ((mozc (0))) "Mozc with input-method-function interface." single ((:commit . "df614a1076c28a11551fb3e822868bae47e855a5") (:keywords "i18n" "extentions") (:authors ("Daisuke Kobayashi" . "d5884jp@gmail.com")) (:maintainer "Daisuke Kobayashi" . "d5884jp@gmail.com"))]) (mozc . [(20180101 800) nil "minor mode to input Japanese with Mozc" single ((:commit . "afb03ddfe72dde4cf2409863a3bfea160f7a66d8") (:keywords "mule" "multilingual" "input method"))]) (moz-controller . [(20151209 206) ((moz (0))) "Control Firefox from Emacs" single ((:commit . "46f665c03574fa922de767fc29795e0db4a7c5c6") (:authors ("任文山 (Ren Wenshan) <renws1990 at gmail.com>")) (:maintainer "任文山 (Ren Wenshan) <renws1990 at gmail.com>") (:url . "https://github.com/RenWenshan/emacs-moz-controller"))]) (moz . [(20150805 1706) nil "Lets current buffer interact with inferior mozilla." single ((:commit . "ab3e79914445039ceb62f7f2dc342358fec3492e") (:authors ("Massimiliano Mirra, <bard [at] hyperstruct [dot] net>")) (:maintainer "Massimiliano Mirra, <bard [at] hyperstruct [dot] net>") (:url . "http://github.com/bard/mozrepl/raw/master/chrome/content/moz.el"))]) (mowedline . [(20161122 235) nil "elisp utilities for using mowedline" single ((:commit . "6121b7d4aacd18f7b24da226e61dbae054e50a7c") (:authors ("John Foerch" . "jjfoerch@earthlink.net")) (:maintainer "John Foerch" . "jjfoerch@earthlink.net"))]) (move-text . [(20170909 330) nil "Move current line or region with M-up or M-down." single ((:commit . "7cbc941a9150468609010a93c429117da2523903") (:keywords "edit") (:authors ("Jason Milkins" . "jasonm23@gmail.com")) (:maintainer "Jason Milkins" . "jasonm23@gmail.com") (:url . "https://github.com/emacsfodder/move-text"))]) (move-dup . [(20180531 1237) nil "Eclipse-like moving and duplicating lines or rectangles." single ((:commit . "24e5b6d7222cbe2437c602f1af37d5807569961a") (:keywords "convenience" "text" "edit") (:authors ("Jimmy Yuen Ho Wong" . "wyuenho@gmail.com")) (:maintainer "Jimmy Yuen Ho Wong" . "wyuenho@gmail.com") (:url . "https://github.com/wyuenho/move-dup"))]) (mouse-slider-mode . [(20161021 1914) ((emacs (24 3)) (cl-lib (0 3))) "scale numbers dragged under the mouse" single ((:commit . "b3c19cd231edecce76787c5a9bbe5e4046d91f88") (:authors ("Christopher Wellons" . "mosquitopsu@gmail.com")) (:maintainer "Christopher Wellons" . "mosquitopsu@gmail.com") (:url . "https://github.com/skeeto/mouse-slider-mode"))]) (motion-mode . [(20140920 156) ((flymake-easy (0 7)) (flymake-cursor (1 0 2))) "major mode for RubyMotion enviroment" tar ((:commit . "4c94180e3ecea611a61240a0c0cd48f1032c4a55") (:authors ("Satoshi Namai")) (:maintainer "Satoshi Namai") (:url . "https://github.com/ainame/motion-mode"))]) (mote-mode . [(20160123 29) ((ruby-mode (1 1))) "Mote minor mode" single ((:commit . "666c6641addbd3b337a7aa01fd2742ded2f41b83") (:authors ("Leandro López (inkel)" . "inkel.ar@gmail.com")) (:maintainer "Leandro López (inkel)" . "inkel.ar@gmail.com") (:url . "http://inkel.github.com/mote-mode/"))]) (mosey . [(20180614 1649) ((emacs (24 4))) "Mosey around your buffers" single ((:commit . "2e3ac9d334fa2937ed5267193dfd25d8e1f14dc2") (:keywords "convenience") (:authors ("Adam Porter" . "adam@alphapapa.net")) (:maintainer "Adam Porter" . "adam@alphapapa.net") (:url . "http://github.com/alphapapa/mosey.el"))]) (morlock . [(20180318 2023) nil "more font-lock keywords for elisp" single ((:commit . "b883d48024ddfffebe2d0dd69f5ed54c617f8834") (:keywords "convenience") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:url . "https://github.com/tarsius/morlock"))]) (morganey-mode . [(20170118 934) ((emacs (24 4))) "Major mode for editing Morganey files" single ((:commit . "5cf3870432a2aeb69d373abe63b3be1f325f6d21") (:authors ("Alexey Kutepov" . "reximkut@gmail.com")) (:maintainer "Alexey Kutepov" . "reximkut@gmail.com") (:url . "https://github.com/morganey-lang/morganey-mode"))]) (moonscript . [(20170831 2226) ((cl-lib (0 5)) (emacs (24))) "Major mode for editing MoonScript code" tar ((:commit . "56f90471e2ced2b0a177aed4d8c2f854797e9cc7") (:authors ("@GriffinSchneider, @k2052, @EmacsFodder")) (:maintainer "@GriffinSchneider, @k2052, @EmacsFodder"))]) (moom . [(20180618 1945) ((emacs (25 1))) "Commands to control frame position and size" tar ((:commit . "54b50eac555c9195ad39060e31fd4aac5662b5fd") (:keywords "frames" "faces" "convenience") (:authors ("Takaaki ISHIKAWA <takaxp at ieee dot org>")) (:maintainer "Takaaki ISHIKAWA <takaxp at ieee dot org>") (:url . "https://github.com/takaxp/Moom"))]) (moody . [(20180403 1249) ((emacs (25 3))) "Tabs and ribbons for the mode line" single ((:commit . "05cf642d4295e24629022447df8e422180df20e4") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:url . "https://github.com/tarsius/moody"))]) (monroe . [(20180703 1746) nil "Yet another client for nREPL" single ((:commit . "7eeac4f5127f7d74cd975542a8b901742b682922") (:keywords "languages" "clojure" "nrepl" "lisp") (:authors ("Sanel Zukan" . "sanelz@gmail.com")) (:maintainer "Sanel Zukan" . "sanelz@gmail.com") (:url . "http://www.github.com/sanel/monroe"))]) (monotropic-theme . [(20180218 1157) ((emacs (24))) "Monotropic Theme" single ((:commit . "b46e94a712e01cebe69a6f7d950e91d7c7dd1b66") (:authors ("caffo")) (:maintainer "caffo") (:url . "https://github.com/caffo/monotropic-theme"))]) (monokai-theme . [(20180730 1329) nil "A fruity color theme for Emacs." single ((:commit . "f4ef092129f4a35edaee0a9b2219c17e86309730") (:authors ("Kelvin Smith" . "oneKelvinSmith@gmail.com")) (:maintainer "Kelvin Smith" . "oneKelvinSmith@gmail.com") (:url . "http://github.com/oneKelvinSmith/monokai-emacs"))]) (monokai-alt-theme . [(20170630 2048) ((emacs (24))) "Theme with a dark background. Based on sublime monokai theme." single ((:commit . "f342b6afc31f929be0626eca2d696ee9fab78011") (:authors ("Dmytro Koval")) (:maintainer "Dmytro Koval") (:url . "https://github.com/dawidof/emacs-monokai-theme"))]) (monochrome-theme . [(20140326 1050) nil "A dark Emacs 24 theme for your focused hacking sessions" tar ((:commit . "bfca67fe7365310bc47ae9ca96c417caada54896") (:authors ("Xavier Noria" . "fxn@hashref.com")) (:maintainer "Xavier Noria" . "fxn@hashref.com"))]) (monky . [(20180806 739) nil "Control Hg from Emacs." tar ((:commit . "c40038710db855a5b71fa8ba0032b397a6730d2d"))]) (monitor . [(20161018 1144) ((dash (2 13 0))) "Utilities for monitoring expressions." tar ((:commit . "63f4643a0ee81616dbb692b8b03bae21df2283e2") (:keywords "lisp" "monitor" "utility") (:authors ("Ben Moon" . "software@guiltydolphin.com")) (:maintainer "Ben Moon" . "software@guiltydolphin.com") (:url . "https://github.com/guiltydolphin/monitor"))]) (mongo . [(20150315 1219) nil "MongoDB driver for Emacs Lisp" tar ((:commit . "595529ddd70ecb9fab8b11daad2c3929941099d6") (:keywords "convenience") (:authors ("Tomohiro Matsuyama" . "m2ym.pub@gmail.com")) (:maintainer "Tomohiro Matsuyama" . "m2ym.pub@gmail.com"))]) (molokai-theme . [(20151016 1545) nil "molokai theme with Emacs theme engine" single ((:commit . "04a44f21184b6a26caae4f2c92db9019d883309c") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/alloy-d/color-theme-molokai"))]) (molecule . [(20180527 743) ((emacs (25 1))) "Simple wrapper for molecule" single ((:commit . "2ef72b81d9aa24ea782b71a061a3abdad6cae162") (:keywords ":" "languages" "terminals") (:authors (": drymer <drymer [ AT ] autistici.org>")) (:maintainer ": drymer <drymer [ AT ] autistici.org>") (:url . "https://git.daemons.it/drymer/molecule.el"))]) (moe-theme . [(20180617 200) nil "A colorful eye-candy theme. Moe, moe, kyun!" tar ((:commit . "ee6d7a1c84ac7a11fcc82dfc3b174eee1c8461fa") (:url . "https://github.com/kuanyui/moe-theme.el"))]) (modtime-skip-mode . [(20140128 2201) nil "Minor mode for disabling modtime and supersession checks on files." single ((:commit . "c0e49523aa26b2263a8693691ac775988015f592") (:authors ("Jordon Biondo" . "biondoj@mail.gvsu.edu")) (:maintainer "Jordon Biondo" . "biondoj@mail.gvsu.edu") (:url . "http://www.github.com/jordonbiondo/modtime-skip-mode"))]) (modern-cpp-font-lock . [(20180110 2031) nil "Font-locking for \"Modern C++\"" single ((:commit . "9b10e1831bac34685be89e32e83ed969c4bac683") (:keywords "languages" "c++" "cpp" "font-lock") (:authors ("Ludwig PACIFICI" . "ludwig@lud.cc")) (:maintainer "Ludwig PACIFICI" . "ludwig@lud.cc") (:url . "https://github.com/ludwigpacifici/modern-cpp-font-lock"))]) (mode-line-debug . [(20180318 2225) nil "show status of `debug-on-error' in the mode-line" single ((:commit . "a0fcc394b07d2414bd6f722da10f1c7567333f6b") (:keywords "convenience" "lisp") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:url . "https://github.com/tarsius/mode-line-debug"))]) (mode-line-bell . [(20180101 339) nil "Flash the mode line instead of ringing the bell" single ((:commit . "dcfad0929a606af0e836d93e78be989a8ac16f87") (:keywords "convenience") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com"))]) (mode-icons . [(20180806 2253) ((emacs (24)) (cl-lib (0 5))) "Show icons for modes" tar ((:commit . "2a443db39115b781e2daae939eeac2db0df9933f") (:keywords "multimedia") (:authors ("Tom Willemse" . "tom@ryuslash.org")) (:maintainer "Tom Willemse" . "tom@ryuslash.org") (:url . "http://ryuslash.org/projects/mode-icons.html"))]) (modalka . [(20180101 613) ((emacs (24 4))) "Easily introduce native modal editing of your own design" single ((:commit . "9d990341aa13ea27ba4e47ad02b1a9619af22792") (:keywords "modal" "editing") (:authors ("Mark Karpov" . "markkarpov92@gmail.com")) (:maintainer "Mark Karpov" . "markkarpov92@gmail.com") (:url . "https://github.com/mrkkrp/modalka"))]) (mocker . [(20150917 154) ((eieio (1 3)) (el-x (0 2 4))) "mocking framework for emacs" single ((:commit . "6a1d7c9189bd721debd1a60707526e43a733f537") (:keywords "lisp" "testing") (:authors ("Yann Hodique" . "yann.hodique@gmail.com")) (:maintainer "Yann Hodique" . "yann.hodique@gmail.com"))]) (mocha-snippets . [(20170104 527) ((yasnippet (0 8 0))) "Yasnippets for the Mocha JS Testing Framework" tar ((:commit . "e054137bd78f0d236e983874da1f345d30a71816") (:keywords "test" "javascript") (:authors ("Charles Lowell" . "cowboyd@frontside.io")) (:maintainer "Charles Lowell" . "cowboyd@frontside.io"))]) (mocha . [(20180321 2322) ((js2-mode (20150909)) (f (0 18))) "Run Mocha or Jasmine tests" single ((:commit . "33e1b521a8a8d0225df353b51f1e8a4588ee32d0") (:keywords "javascript" "mocha" "jasmine") (:authors ("Al Scott")) (:maintainer "Al Scott") (:url . "http://github.com/scottaj/mocha.el"))]) (mobdebug-mode . [(20140110 346) ((lua-mode (20130419)) (emacs (24))) "Major mode for MobDebug" single ((:commit . "e1d483bc4e341c762bc5c0a8c52306a8d01ea0da") (:authors ("Shihpin Tseng" . "deftsp@gmail.com")) (:maintainer "Shihpin Tseng" . "deftsp@gmail.com") (:url . "https://github.com/deftsp/mobdebug-mode"))]) (mo-vi-ment-mode . [(20131029 633) nil "Provide vi-like cursor movement that's easy on the fingers" single ((:commit . "f45b014261f8fab19254920bd1d92f3a83263411") (:keywords "convenience") (:authors ("Ajay MT" . "ajay.tatachar@gmail.com")) (:maintainer "Ajay MT" . "ajay.tatachar@gmail.com"))]) (mo-git-blame . [(20160129 1759) nil "An interactive, iterative 'git blame' mode for Emacs" single ((:commit . "254a675eb794cdbbdef9fa2b4b7bb510b70089c0") (:keywords "tools") (:authors ("Moritz Bunkus" . "moritz@bunkus.org")) (:maintainer "Moritz Bunkus" . "moritz@bunkus.org"))]) (mmt . [(20180101 619) ((emacs (24 1)) (cl-lib (0 3))) "Missing macro tools for Emacs Lisp" single ((:commit . "e860009ce531ee05d2902309db5f804326596b45") (:keywords "macro" "emacs-lisp") (:authors ("Mark Karpov" . "markkarpov92@gmail.com")) (:maintainer "Mark Karpov" . "markkarpov92@gmail.com") (:url . "https://github.com/mrkkrp/mmt"))]) (mmm-mako . [(20121020 651) ((mmm-mode (0 4 8))) "MMM submode class for Mako Templates" single ((:authors ("Philip Jenvey" . "pjenvey@underboss.org")) (:maintainer "Philip Jenvey" . "pjenvey@underboss.org") (:url . "https://bitbucket.org/pjenvey/mmm-mako"))]) (mmm-jinja2 . [(20170313 1420) ((mmm-mode (0 5 4))) "MMM submode class for Jinja2 Templates" single ((:commit . "c8cb763174fa2fb61b9a0e5e0ff8cb0210f8492f") (:authors ("Ben Hayden" . "hayden767@gmail.com")) (:maintainer "Ben Hayden" . "hayden767@gmail.com") (:url . "https://github.com/glynnforrest/mmm-jinja2"))]) (mkdown . [(20140517 1418) ((markdown-mode (2 0))) "Pretty Markdown previews based on mkdown.com" tar ((:commit . "8e23de82719af6c5b53b52b3308a02b3a1fb872e") (:keywords "markdown") (:authors ("Andrew Tulloch")) (:maintainer "Andrew Tulloch") (:url . "https://github.com/ajtulloch/mkdown.el"))]) (mixed-pitch . [(20180410 1617) ((emacs (24 3))) "Use a variable pitch, keeping fixed pitch where it's sensible" single ((:commit . "fe613e514bddc9ac7dfd8e51cee44a0fcfaf3f42") (:authors ("J. Alexander Branham" . "branham@utexas.edu")) (:maintainer "J. Alexander Branham" . "branham@utexas.edu") (:url . "https://github.com/jabranham/mixed-pitch"))]) (mips-mode . [(20180502 1457) nil "Major-mode for MIPS assembly" single ((:commit . "75152fc78baa762af4f83602f6cb3c8b9bcebca3") (:keywords "languages" "mips" "assembly") (:authors ("Henrik Lissner <http://github/hlissner>")) (:maintainer "Henrik Lissner" . "henrik@lissner.net") (:url . "https://github.com/hlissner/emacs-mips-mode"))]) (mip-mode . [(20151127 617) nil "virtual projects for emacs." single ((:commit . "7c88c383b4c7ed0a4c1dc397735f365c1fcb461c") (:keywords "workspaces" "workspace" "project" "projects" "mip-mode") (:authors ("Eeli Reilin" . "gaudecker@fea.st")) (:maintainer "Eeli Reilin" . "gaudecker@fea.st"))]) (minor-mode-hack . [(20170926 34) nil "Change priority of minor-mode keymaps" single ((:commit . "9688994e23ccb2de568225ef125b41c46e5667c3") (:keywords "lisp") (:authors ("rubikitch" . "rubikitch@ruby-lang.org")) (:maintainer "rubikitch" . "rubikitch@ruby-lang.org") (:url . "http://www.emacswiki.org/cgi-bin/wiki/download/minor-mode-hack.el"))]) (minizinc-mode . [(20180201 1450) ((emacs (24 1))) "Major mode for MiniZinc code" single ((:commit . "2512521ba7f8e263a06db88df663fc6b3cca7e16") (:keywords "languages" "minizinc") (:url . "http://github.com/m00nlight/minizinc-mode"))]) (minitest . [(20160628 1820) ((dash (1 0 0))) "An Emacs mode for ruby minitest files" tar ((:commit . "1aadb7865c1dc69c201cecee275751ecec33a182") (:authors ("Arthur Neves")) (:maintainer "Arthur Neves") (:url . "https://github.com/arthurnn/minitest-emacs"))]) (minions . [(20180709 1712) ((emacs (25 3)) (dash (2 13 0))) "A minor-mode menu for the mode line" single ((:commit . "2f5e73e15d0021e7ba26cf09f1cd2734b018fb69") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:url . "https://github.com/tarsius/minions"))]) (minimal-theme . [(20160608 1022) nil "A light/dark minimalistic Emacs 24 theme." tar ((:commit . "430e0d3fc2044c16aa9f10961841febbd60df285") (:keywords "color" "theme" "minimal") (:authors ("Anler Hp <anler86 [at] gmail.com>")) (:maintainer "Anler Hp <anler86 [at] gmail.com>") (:url . "http://github.com/ikame/minimal-theme"))]) (minimal-session-saver . [(20140508 2041) nil "Very lean session saver" single ((:commit . "cf654ac549850746dc21091746e4bcc1aef7668e") (:keywords "tools" "frames" "project") (:authors ("Roland Walker" . "walker@pobox.com")) (:maintainer "Roland Walker" . "walker@pobox.com") (:url . "http://github.com/rolandwalker/minimal-session-saver"))]) (miniedit . [(20100419 1745) nil "Enhanced editing for minibuffer fields." single ((:commit . "e12bf659c3eb92dd8a4cb77642dc0865c54667a3"))]) (minibuffer-cua . [(20130906 1134) nil "Make CUA mode's S-up/S-down work in minibuffer" single ((:commit . "adc4979a64f8b36e05960e9afa0746dfa9e2e4c7") (:keywords "completion" "editing") (:authors ("Akinori MUSHA" . "knu@iDaemons.org")) (:maintainer "Akinori MUSHA" . "knu@iDaemons.org") (:url . "https://github.com/knu/minibuffer-cua.el"))]) (minibuffer-complete-cycle . [(20130813 1645) nil "Cycle through the *Completions* buffer" single ((:commit . "3df80135887d0169e02294a948711f6dfeca4a6f") (:keywords "completion") (:authors ("Akinori MUSHA" . "knu@iDaemons.org") ("Kevin Rodgers" . "ihs_4664@yahoo.com")) (:maintainer "Akinori MUSHA" . "knu@iDaemons.org") (:url . "https://github.com/knu/minibuffer-complete-cycle"))]) (minibuf-isearch . [(20151226 1943) nil "incremental search on minibuffer history" single ((:commit . "2846c6ac369ee623dad4cd3c8a7a6d9078965516") (:keywords "minibuffer" "history" "incremental search") (:authors ("Keiichiro Nagano" . "knagano@sodan.org") ("Hideyuki SHIRAI " . "shirai@meadowy.org")) (:maintainer "Keiichiro Nagano" . "knagano@sodan.org"))]) (mini-header-line . [(20170621 1221) ((emacs (24 4))) "a minimal header-line" single ((:commit . "73b6724e0a26c4528d93768191c8aa59e6bce2e5") (:keywords "header-line" "mode-line") (:authors ("Johannes Goslar")) (:maintainer "Johannes Goslar") (:url . "https://github.com/ksjogo/mini-header-line"))]) (mingus . [(20180713 636) ((libmpdee (2 1))) "MPD Interface" tar ((:commit . "686d383f48b196c916c5fcb6ddc3bcff8a0c4b14") (:keywords "multimedia" "elisp" "music" "mpd") (:authors ("Niels Giesen <pft on #emacs>")) (:maintainer "Niels Giesen <pft on #emacs>") (:url . "https://github.com/pft/mingus"))]) (minesweeper . [(20150414 522) nil "play minesweeper in Emacs" single ((:keywords "game" "fun" "minesweeper" "inane" "diversion") (:authors ("Zachary Kanfer" . "zkanfer@gmail.com")) (:maintainer "Zachary Kanfer" . "zkanfer@gmail.com") (:url . "https://bitbucket.org/zck/minesweeper.el"))]) (milkode . [(20140927 529) nil "Command line search and direct jump with Milkode" single ((:commit . "ba97e2aeefa1d9d0b3835bf08edd0de248b0c513") (:keywords "milkode" "search" "grep" "jump" "keyword") (:authors ("ongaeshi")) (:maintainer "ongaeshi"))]) (migemo . [(20160924 1441) ((cl-lib (0 5))) "Japanese incremental search through dynamic pattern expansion" single ((:commit . "e4744efae1b2fdea2bbd2ceaff0f6ea0bb739f5a") (:authors ("Satoru Takabayashi" . "satoru-t@is.aist-nara.ac.jp")) (:maintainer "Satoru Takabayashi" . "satoru-t@is.aist-nara.ac.jp") (:url . "https://github.com/emacs-jp/migemo"))]) (midje-mode . [(20170809 403) ((cider (0 1 4)) (clojure-mode (1 0))) "Minor mode for running Midje tests in emacs" tar ((:commit . "10ad5b6084cd03d5cd268b486a7c3c246d85535f"))]) (micgoline . [(20160415 326) ((emacs (24 3)) (powerline (2 3))) "powerline mode, color schemes from microsoft and google's logo." single ((:commit . "837504263bb1711203b0f7efecd6b7b5f272fae0") (:keywords "mode-line" "powerline" "theme") (:authors ("yzprofile" . "yzprofiles@gmail.com")) (:maintainer "yzprofile" . "yzprofiles@gmail.com") (:url . "https://github.com/yzprofile/micgoline"))]) (mic-paren . [(20170731 1907) nil "advanced highlighting of matching parentheses" single ((:commit . "d0410c7d805c9aaf51a1bcefaaef092bed5824c4") (:keywords "languages" "faces" "parenthesis" "matching") (:authors ("Mikael Sjödin" . "mic@docs.uu.se") ("Klaus Berndl " . "berndl@sdm.de") ("Jonathan Kotta" . "jpkotta@gmail.com")) (:maintainer "ttn"))]) (mhc . [(20180724 458) ((calfw (20150703))) "Message Harmonized Calendaring system." tar ((:commit . "2cd1e97fa2e32e7dfde5ee7878fb9a915fb6a3b8") (:keywords "calendar") (:authors ("Yoshinari Nomura" . "nom@quickhack.net")) (:maintainer "Yoshinari Nomura" . "nom@quickhack.net") (:url . "http://www.quickhack.net/mhc"))]) (mgmtconfig-mode . [(20180222 2057) ((emacs (24 3))) "mgmt configuration management language" single ((:commit . "f342e06ef0d0fc173dcb5320e9a376f14d561868") (:keywords "languages") (:authors ("Peter Oliver" . "mgmtconfig@mavit.org.uk")) (:maintainer "Mgmt contributors <https://github.com/purpleidea/mgmt>") (:url . "https://github.com/purpleidea/mgmt/misc/emacs"))]) (mexican-holidays . [(20160109 2142) nil "Mexico holidays for Emacs calendar." single ((:commit . "43ced1f9e40a04be6927d1a1be64060f9be4f5c5") (:keywords "calendar") (:authors ("Saúl Gutiérrez" . "me@sggc.me")) (:maintainer "Saúl Gutiérrez" . "me@sggc.me") (:url . "https://github.com/shopClerk/mexican-holidays"))]) (mew . [(20180710 117) nil "Messaging in the Emacs World" tar ((:commit . "d4eac40c09ef349e09f0169bc2725d050dc8c7ad") (:authors ("Kazu Yamamoto" . "Kazu@Mew.org")) (:maintainer "Kazu Yamamoto" . "Kazu@Mew.org"))]) (metaweblog . [(20171217 240) ((xml-rpc (1 6 8))) "An emacs library to access metaweblog based weblogs" tar ((:commit . "aa14380eb7e7b879a0c16c96866b20a987cd3f2a"))]) (metascript-mode . [(20150709 57) ((emacs (24 3))) "Major mode for the Metascript programming language" single ((:commit . "edb361c7b0e5de231e5334a17b90652fb1df78f9") (:keywords "languages" "metascript" "mjs") (:url . "http://github.com/metascript/metascript-mode"))]) (metalheart-theme . [(20160710 641) ((emacs (24))) "Low-contrast theme with a dark blue-green background." single ((:commit . "ec98ea2c11dc1213dae8cbe1fe0cee73ca138bb2") (:authors ("Martin Haesler")) (:maintainer "Martin Haesler"))]) (meta-presenter . [(20170426 234) nil "A simple multi-file presentation tool for Emacs" single ((:commit . "4e7aae56e5abf6deaadbda84fd5ec4e3e19c22be") (:keywords "productivity" "presentation") (:authors ("Mohammed Ismail Ansari" . "team.terminal@gmail.com")) (:maintainer "Mohammed Ismail Ansari" . "team.terminal@gmail.com") (:url . "http://ismail.teamfluxion.com"))]) (messages-are-flowing . [(20170219 120) nil "visible indication when composing \"flowed\" emails" single ((:commit . "ef879726957c850c3a5afd7f1118604991e37e32") (:keywords "mail") (:authors ("Magnus Henoch" . "magnus.henoch@gmail.com")) (:maintainer "Magnus Henoch" . "magnus.henoch@gmail.com"))]) (meson-mode . [(20170901 1835) ((emacs (24 3))) "Major mode for the Meson build system files" single ((:commit . "212d9f38a08074f1cb6e914e12b60bc52dcb8bee") (:keywords "languages" "tools") (:authors ("Michal Sojka" . "sojkam1@fel.cvut.cz")) (:maintainer "Michal Sojka" . "sojkam1@fel.cvut.cz") (:url . "https://github.com/wentasah/meson-mode"))]) (merlin-eldoc . [(20180830 1016) ((emacs (24 4)) (merlin (3 0))) "eldoc for OCaml and Reason" single ((:commit . "85dec436648f43c050048524fae7a3ad7ad4c019") (:keywords "merlin" "ocaml" "languages" "eldoc") (:authors ("Louis Roché" . "louis@louisroche.net")) (:maintainer "Louis Roché" . "louis@louisroche.net") (:url . "https://github.com/khady/merlin-eldoc"))]) (merlin . [(20180214 1042) nil "Mode for Merlin, an assistant for OCaml." tar ((:commit . "068960d0ae622e3db7a0261ffdfa8673884292a7") (:keywords "ocaml" "languages") (:authors ("Frédéric Bour <frederic.bour(_)lakaban.net>")) (:maintainer "Frédéric Bour <frederic.bour(_)lakaban.net>") (:url . "https://github.com/ocaml/merlin"))]) (mentor . [(20170105 1021) ((xml-rpc (1 6 9)) (seq (1 11)) (cl-lib (0 5))) "Frontend for the rTorrent bittorrent client" tar ((:commit . "9a160d718b02a95b1bb24072cca87b4348e1e261") (:keywords "comm" "processes" "bittorrent") (:authors ("Stefan Kangas" . "stefankangas@gmail.com")) (:maintainer "Stefan Kangas" . "stefankangas@gmail.com"))]) (memolist . [(20150804 1721) ((markdown-mode (22 0)) (ag (0 45))) "memolist.el is Emacs port of memolist.vim." single ((:commit . "60c296e202a71e9dcf1c3936d47b5c4b95c5839f") (:keywords "markdown" "memo") (:authors ("mikanfactory <k952i4j14x17_at_gmail.com>")) (:maintainer "mikanfactory") (:url . "http://github.com/mikanfactory/emacs-memolist"))]) (memoize . [(20180614 1930) nil "Memoization functions" single ((:commit . "9a561268ffb550b257a08710489a95cd087998b6") (:authors ("Christopher Wellons" . "mosquitopsu@gmail.com")) (:maintainer "Christopher Wellons" . "mosquitopsu@gmail.com") (:url . "https://github.com/skeeto/emacs-memoize"))]) (melpa-upstream-visit . [(20130720 1033) ((s (1 6 0))) "A set of kludges to visit a melpa-hosted package's homepage" single ((:commit . "7310c74fdead3c0f86ad6eff76cf989e63f70f66") (:keywords "convenience") (:authors ("Alessandro Piras" . "laynor@gmail.com")) (:maintainer "Alessandro Piras" . "laynor@gmail.com"))]) (mellow-theme . [(20170808 1317) ((emacs (24 0))) "an Emacs 24 theme based on Mellow (tmTheme)" single ((:commit . "2bdf18f05f5212b6f269d9a94afe2cf201766891") (:authors ("Jason Milkins")) (:maintainer "Jason Milkins") (:url . "https://github.com/emacsfodder/tmtheme-to-deftheme"))]) (melancholy-theme . [(20170220 2048) nil "A dark theme for dark minds" single ((:commit . "a9e13ca7051731b3a2c2aece9f3e3033b9a5e41d") (:authors ("Sod Oscarfono" . "sod@oscarfono.com")) (:maintainer "Sod Oscarfono" . "sod@oscarfono.com") (:url . "http://github.com/techquila/melancholy-theme"))]) (meghanada . [(20180718 110) ((emacs (24 3)) (yasnippet (0 6 1)) (company (0 9 0)) (flycheck (0 23))) "A better java development mode" tar ((:commit . "fbc75b71d99446f65527f9ad75140a0798301230") (:keywords "languages" "java") (:authors ("Yutaka Matsubara" . "yutaka.matsubara@gmail.com")) (:maintainer "Yutaka Matsubara" . "yutaka.matsubara@gmail.com") (:url . "https://github.com/mopemope/meghanada-emacs"))]) (mediawiki . [(20170813 555) nil "mediawiki frontend" single ((:commit . "8473e12d1839f5287a4227586bf117dad820f867") (:keywords "mediawiki" "wikipedia" "network" "wiki") (:authors ("Mark A. Hershberger" . "mah@everybody.org")) (:maintainer "Mark A. Hershberger" . "mah@everybody.org") (:url . "https://github.com/hexmode/mediawiki-el"))]) (md4rd . [(20180626 536) ((emacs (25 1)) (hierarchy (0 7 0)) (request (0 3 0)) (cl-lib (0 6 1)) (dash (2 12 0)) (s (1 12 0)) (tree-mode (1 0 0))) "Mode for reddit (browse it)." single ((:commit . "75fbf295d896230c4b441dc773d266fa6cd7a509") (:keywords "ahungry" "reddit" "browse" "news") (:authors ("Matthew Carter" . "m@ahungry.com")) (:maintainer "Matthew Carter" . "m@ahungry.com") (:url . "https://github.com/ahungry/md4rd"))]) (md-readme . [(20160811 1646) nil "Markdown-formatted READMEs for your ELisp" tar ((:commit . "bf818dd847c8b06b3b5100c5d3cf24cf96662528") (:keywords "lisp" "help" "readme" "markdown" "header" "documentation" "github") (:authors ("Thomas Kappler" . "tkappler@gmail.com")) (:maintainer "Thomas Kappler" . "tkappler@gmail.com") (:url . "http://github.com/thomas11/md-readme/tree/master"))]) (mc-extras . [(20180520 439) ((multiple-cursors (1 2 1))) "Extra functions for multiple-cursors mode." tar ((:commit . "fac7e42d03078b4ca0fa72f191995c727143a0d1") (:keywords "editing" "cursors") (:authors ("Akinori MUSHA" . "knu@iDaemons.org")) (:maintainer "Akinori MUSHA" . "knu@iDaemons.org") (:url . "https://github.com/knu/mc-extras.el"))]) (mbsync . [(20180530 733) nil "run mbsync to fetch mails" single ((:commit . "bca442138f24f20479b89bd5d77b012ab06f4232") (:authors ("Dimitri Fontaine" . "dim@tapoueh.org")) (:maintainer "Dimitri Fontaine" . "dim@tapoueh.org") (:url . "https://github.com/dimitri/mbsync-el"))]) (mbo70s-theme . [(20170808 1315) ((emacs (24 0))) "70s style palette, with similarities to mbo theme" single ((:commit . "bed3db8965708ed4e9482b224a9b084765c052f2") (:authors ("Jason Milkins")) (:maintainer "Jason Milkins") (:url . "https://github.com/emacsfodder/tmtheme-to-deftheme"))]) (mbe . [(20151126 1134) ((emacs (24)) (cl-lib (0 5))) "Macros by Example" single ((:commit . "bb10aa8f26bb7e9b1d5746934c94edb00402940c") (:keywords "tools" "macros") (:authors ("Ian Price" . "ianprice90@googlemail.com")) (:maintainer "Ian Price" . "ianprice90@googlemail.com") (:url . "https://github.com/ijp/mbe.el"))]) (mb-url . [(20180901 2222) ((cl-lib (0))) "Multiple Backends for Emacs URL package." tar ((:commit . "ebe7db4cac31259017556285c2ee0b357b62d2a2") (:url . "https://github.com/dochang/mb-url") (:keywords "url"))]) (maxframe . [(20170120 1705) nil "maximize the emacs frame based on display size" single ((:commit . "13bda6dd9f1d96aa4b9dd9957a26cefd399a7772") (:keywords "display" "frame" "window" "maximize") (:authors ("Ryan McGeary")) (:maintainer "Ryan McGeary"))]) (maven-test-mode . [(20141220 557) ((s (1 9)) (emacs (24))) "Utilities for navigating test files and running maven test tasks." single ((:commit . "a19151861df2ad8ae4880a2e7c86ddf848cb569a") (:keywords "java" "maven" "test") (:authors ("Renan Ranelli")) (:maintainer "Renan Ranelli") (:url . "http://github.com/rranelli/maven-test-mode"))]) (maude-mode . [(20160222 1607) nil "Emacs mode for the programming language Maude" single ((:commit . "c9543bb8a172fa77af592388e7f520a4a6d38987") (:keywords "maude") (:authors ("Ellef Gjelstad <ellefg+maude*ifi.uio.no>")) (:maintainer "Rudi Schlatte" . "rudi@constantly.at"))]) (matlab-mode . [(20180125 1810) nil "Major mode for MATLAB(R) dot-m files" tar ((:commit . "50266ff812607e55bddacd71a46d1b96e36fb0bd") (:url . "http://sourceforge.net/projects/matlab-emacs/") (:keywords "matlab" "programming" "language" "(X)emacs"))]) (math-symbols . [(20170818 1459) ((helm (1 0))) "Math Symbol Input methods and conversion tools" tar ((:commit . "3f8b466f002e1b28ddbe9a6f236c9a1352adb17d") (:keywords "i18n" "languages" "tex") (:authors ("KAWABATA, Taichi <kawabata.taichi_at_gmail.com>")) (:maintainer "KAWABATA, Taichi <kawabata.taichi_at_gmail.com>") (:url . "https://github.com/kawabata/math-symbols"))]) (math-symbol-lists . [(20170221 1353) nil "Lists of Unicode math symbols and latex commands" tar ((:commit . "1af8fdcab7941a62287c2d04b8876e1538f39c60") (:keywords "unicode" "symbols" "mathematics") (:authors ("Vitalie Spinu")) (:maintainer "Vitalie Spinu") (:url . "https://github.com/vspinu/math-symbol-lists"))]) (material-theme . [(20171123 1840) ((emacs (24 1))) "A Theme based on the colors of the Google Material Design" tar ((:commit . "b66838d220ad380a16da1d8878936974b26f815d") (:keywords "themes") (:authors ("Christoph Paulik" . "cpaulik@gmail.com")) (:maintainer "Christoph Paulik" . "cpaulik@gmail.com") (:url . "http://github.com/cpaulik/emacs-material-theme"))]) (mastodon . [(20180811 220) ((emacs (24 4))) "Client for Mastodon" tar ((:commit . "585a2dd79f6f929378237c3a678cf43efdf37407") (:authors ("Johnson Denen" . "johnson.denen@gmail.com")) (:maintainer "Johnson Denen" . "johnson.denen@gmail.com") (:url . "https://github.com/jdenen/mastodon.el"))]) (maruo-macro-mode . [(20160616 1349) ((emacs (24 3))) "Major mode for editing Hidemaru/Maruo macro script" single ((:commit . "8fc9a38ad051eafa8eb94038711acc52c5d1d8d5") (:keywords "programming" "editor" "macro") (:authors ("USAMI Kenta" . "tadsan@zonu.me")) (:maintainer "USAMI Kenta" . "tadsan@zonu.me"))]) (marshal . [(20180124 1239) ((eieio (1 4)) (json (1 3)) (ht (2 1))) "eieio extension for automatic (un)marshalling" single ((:commit . "f038689cbd5b3680b80b44edd0c7a63ca3038e26") (:keywords "eieio") (:authors ("Yann Hodique" . "hodiquey@vmware.com")) (:maintainer "Yann Hodique" . "hodiquey@vmware.com") (:url . "https://github.com/sigma/marshal.el"))]) (marmalade-client . [(20141231 2007) ((web (0 5 2)) (kv (0 0 19)) (gh (0 8 0))) "client for marmalade API from emacs" tar ((:commit . "f315dea57e4fbebd9ee0668c0bafd4c45c7b754a") (:keywords "lisp") (:authors ("Nic Ferrier" . "nferrier@ferrier.me.uk")) (:maintainer "Nic Ferrier" . "nferrier@ferrier.me.uk") (:url . "https://github.com/nicferrier/emacs-marmalade-upload"))]) (markup-faces . [(20141110 817) nil "collection of faces for markup language modes" single ((:commit . "98a807ed82473eb41c6a201ed7ef816d6bcd67b0") (:keywords "wp" "faces") (:authors ("Florian Kaufmann" . "sensorflo@gmail.com")) (:maintainer "Florian Kaufmann" . "sensorflo@gmail.com") (:url . "https://github.com/sensorflo/markup-faces"))]) (markup . [(20170420 1129) ((cl-lib (0 5))) "Simple markup generation helpers." single ((:commit . "876da2d3f23473475bb0fd0a1480ae11d2671291") (:keywords "convenience" "markup" "html") (:authors ("Arthur Leonard Andersen" . "leoc.git@gmail.com")) (:maintainer "Arthur Leonard Andersen" . "leoc.git@gmail.com") (:url . "http://github.com/leoc/markup.el"))]) (markdownfmt . [(20160609 1241) ((emacs (24))) "Format markdown using markdownfmt" single ((:commit . "187a74eb4fd9e8520ce08da42d1d292b9af7f2b7") (:keywords "markdown") (:authors ("Nicolas Lamirault" . "nicolas.lamirault@gmail.com")) (:maintainer "Nicolas Lamirault" . "nicolas.lamirault@gmail.com") (:url . "https://github.com/nlamirault/emacs-markdownfmt"))]) (markdown-toc . [(20170711 1949) ((s (1 9 0)) (dash (2 11 0)) (markdown-mode (2 1))) "A simple TOC generator for markdown file" tar ((:commit . "7038f4f6d5c2bc7e4aea89699a607ac2b7dd16a8"))]) (markdown-preview-mode . [(20171122 723) ((emacs (24 3)) (websocket (1 6)) (markdown-mode (2 0)) (cl-lib (0 5)) (web-server (0 1 1)) (uuidgen (0 3))) "markdown realtime preview minor mode." tar ((:commit . "4ec15183fc9fadb9368902c9b77a2d0e1196d1c6") (:keywords "markdown" "gfm" "convenience") (:authors ("Igor Shymko" . "igor.shimko@gmail.com")) (:maintainer "Igor Shymko" . "igor.shimko@gmail.com") (:url . "https://github.com/ancane/markdown-preview-mode"))]) (markdown-preview-eww . [(20160111 1502) ((emacs (24 4))) "Realtime preview by eww" single ((:commit . "5853f836425c877c8a956501f0adda137ef1d3b7") (:authors ("niku" . "niku@niku.name")) (:maintainer "niku" . "niku@niku.name") (:url . "https://github.com/niku/markdown-preview-eww"))]) (markdown-mode . [(20180904 1601) ((emacs (24 4)) (cl-lib (0 5))) "Major mode for Markdown-formatted text" single ((:commit . "30ae22215da05c4e02fcc3bfee0317cfec9c8fe5") (:keywords "markdown" "github flavored markdown" "itex") (:authors ("Jason R. Blevins" . "jblevins@xbeta.org")) (:maintainer "Jason R. Blevins" . "jblevins@xbeta.org") (:url . "https://jblevins.org/projects/markdown-mode/"))]) (markdown-mode+ . [(20170320 2104) ((markdown-mode (20111229))) "extra functions for markdown-mode" tar ((:commit . "411d079f4430a33c34ec0bbcb1535fe1145a2509") (:keywords "markdown" "latex" "osx" "rtf") (:authors ("Donald Ephraim Curtis")) (:maintainer "Donald Ephraim Curtis") (:url . "http://github.com/milkypostman/markdown-mode-plus"))]) (mark-tools . [(20130614 1025) nil "Some simple tools to access the mark-ring in Emacs" single ((:commit . "a11b61effa90bd0abc876d12573674d36fc17f0c") (:authors ("Alex Bennée" . "alex@bennee.com")) (:maintainer "Alex Bennée" . "alex@bennee.com") (:url . "https://github.com/stsquad/emacs-mark-tools"))]) (mark-multiple . [(20121118 1554) nil "Sorta lets you mark several regions at once." tar ((:commit . "f6a53c7c5283d640ae718f4548b0fda78877a375"))]) (marcopolo . [(20160421 1004) ((s (1 9 0)) (dash (2 9 0)) (pkg-info (0 5 0)) (request (0 1 0))) "Emacs client to the Docker HUB/Registry API" tar ((:commit . "9193aabdf12223087b5ed58f1507d5d8a24a4381") (:keywords "docker") (:authors ("Nicolas Lamirault" . "nicolas.lamirault@gmail.com")) (:maintainer "Nicolas Lamirault" . "nicolas.lamirault@gmail.com") (:url . "https://github.com/nlamirault/marcopolo"))]) (map-regexp . [(20130522 2103) ((cl-lib (0 2))) "map over matches of a regular expression" single ((:commit . "b8e06284ec1c593d7d2bda5f35597a63de46333f") (:keywords "convenience") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:url . "https://github.com/tarsius/map-regexp"))]) (map-progress . [(20140310 2132) nil "mapping macros that report progress" single ((:commit . "3167eb218510953fb97e7d50948a625eaa3f0005") (:keywords "convenience") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:url . "https://github.com/tarsius/map-progress/"))]) (mandoku-tls . [(20171118 240) ((emacs (24 4)) (mandoku (20170301)) (github-clone (0 2)) (hydra (0 13 6)) (helm (1 7 0)) (org (9 0)) (helm-charinfo (20170601))) "A tool to access the TLS database" single ((:commit . "ffeebf5bd451ac1806ddfe1744fbbd036a56f902") (:keywords "convenience") (:authors ("Christian Wittern" . "cwittern@gmail.com")) (:maintainer "Christian Wittern" . "cwittern@gmail.com") (:url . "https://github.com/mandoku/mandoku-tls"))]) (mandoku . [(20180403 1106) ((org (8 0)) (magit (20151028)) (github-clone (20150705)) (git (20140128))) "A tool to access repositories of premodern Chinese texts" tar ((:commit . "f230c871de8aab1be7b7a9718cd930548a90baa8"))]) (mandm-theme . [(20170925 1021) nil "An M&M color theme." single ((:commit . "078d6d6f11bd48193c5de590cfb0e3d0d687ffc9") (:authors ("Christian Hopps" . "chopps@gmail.com")) (:maintainer "Christian Hopps" . "chopps@gmail.com") (:url . "https://github.com/choppsv1/emacs-mandm-theme.git"))]) (manage-minor-mode . [(20140310 1600) ((emacs (24 3))) "Manage your minor-modes easily" single ((:commit . "1bed33b0752380b548b822fe72e6858c5fe70c8e") (:keywords "minor-mode" "manage" "emacs") (:authors ("Shingo Fukuyama - http://fukuyama.co")) (:maintainer "Shingo Fukuyama - http://fukuyama.co") (:url . "https://github.com/ShingoFukuyama/manage-minor-mode"))]) (man-commands . [(20151221 2221) ((cl-lib (0 5))) "Add interactive commands for every manpages installed in your computer." single ((:commit . "f4ba0c3790855d7544dff92d470d212f24de1d9d") (:authors ("Nathaniel Flath" . "nflath@gmail.com")) (:maintainer "Nathaniel Flath" . "nflath@gmail.com") (:url . "http://github.com/nflath/man-commands"))]) (malyon . [(20161208 2125) ((cl-lib (0 5))) "mode to execute Z-code files version 3, 5, 8" single ((:commit . "0d9882650720b4a791556f5e2d917388965d6fc0") (:keywords "games" "emulations") (:authors ("Peter Ilberg <peter.ilberg@gmail.com>, Christopher Madsen <cjm@cjmweb.net>, Erik Selberg" . "erik@selberg.org")) (:maintainer "Christopher Madsen <cjm@cjmweb.net>, Erik Selberg" . "erik@selberg.org") (:url . "https://github.com/speedenator/malyon"))]) (mallard-snippets . [(20131023 1851) ((yasnippet (0 8 0)) (mallard-mode (0 1 1))) "Yasnippets for Mallard" tar ((:commit . "70c5293f10722f2ace73bdf74d9a18f95b040edc") (:keywords "snippets" "mallard") (:authors ("Jaromir Hradilek" . "jhradilek@gmail.com")) (:maintainer "Jaromir Hradilek" . "jhradilek@gmail.com") (:url . "https://github.com/jhradilek/emacs-mallard-snippets"))]) (mallard-mode . [(20131204 425) nil "Major mode for editing Mallard files" tar ((:commit . "c48170c1ace4959abcc5fb1df0d4cb149cff44c1") (:keywords "xml" "mallard") (:authors ("Jaromir Hradilek" . "jhradilek@gmail.com")) (:maintainer "Jaromir Hradilek" . "jhradilek@gmail.com") (:url . "https://github.com/jhradilek/emacs-mallard-mode"))]) (malinka . [(20171202 1021) ((s (1 9 0)) (dash (2 4 0)) (f (0 11 0)) (cl-lib (0 3)) (rtags (0 0)) (projectile (0 11 0))) "A C/C++ project configuration package for Emacs" single ((:commit . "d4aa517c7a9022eae16c758c7efdb3a0403542d7") (:keywords "c" "c++" "project-management") (:authors ("Lefteris Karapetsas" . "lefteris@refu.co")) (:maintainer "Lefteris Karapetsas" . "lefteris@refu.co") (:url . "https://github.com/LefterisJP/malinka"))]) (makey . [(20131231 1430) ((cl-lib (0 2))) "interactive commandline mode" single ((:commit . "a61781e69d3b451551e269446e1c5f624ab81137") (:authors ("Mickey Petersen" . "mickey@masteringemacs.org")) (:maintainer "Mickey Petersen" . "mickey@masteringemacs.org"))]) (makefile-executor . [(20180720 832) ((emacs (24 3)) (dash (2 11 0)) (f (0 11 0)) (s (1 10 0))) "Commands for conveniently running makefile targets" single ((:commit . "9a7d78f814a4b372d8f8179819cb1b37b83b1973") (:keywords "processes") (:authors ("Lowe Thiderman" . "lowe.thiderman@gmail.com")) (:maintainer "Lowe Thiderman" . "lowe.thiderman@gmail.com") (:url . "https://github.com/thiderman/makefile-executor.el"))]) (make-it-so . [(20180128 2107) ((swiper (0 8 0)) (emacs (24))) "Transform files with Makefile recipes." tar ((:commit . "bc3b01d6b9ed6ff66ebbd524234f9d6df60dd4be") (:keywords "make" "dired") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:url . "https://github.com/abo-abo/make-it-so"))]) (make-color . [(20140625 1150) nil "Alternative to picking color - update fg/bg color by pressing r/g/b/... keys" single ((:commit . "5ca1383ca9228bca82120b238bdc119f302b75c0") (:keywords "color") (:authors ("Alex Kost" . "alezost@gmail.com")) (:maintainer "Alex Kost" . "alezost@gmail.com") (:url . "https://github.com/alezost/make-color.el"))]) (major-mode-icons . [(20170301 714) ((emacs (24 3)) (powerline (2 4)) (all-the-icons (2 3 0))) "display icon for major-mode on mode-line." tar ((:commit . "e6117a236b2ad52e948576550b183053321dfc91") (:keywords "frames" "multimedia") (:url . "http://github.com/stardiviner/major-mode-icons"))]) (majapahit-theme . [(20160817 1848) nil "Color theme with a dark and light versions" tar ((:commit . "77c96df7619666b2102d90d452eeadf04adc89a6") (:keywords "color" "theme") (:url . "https://gitlab.com/franksn/majapahit-theme"))]) (magnatune . [(20151030 1935) ((dash (2 9 0)) (s (1 9 0))) "browse magnatune's music catalog" tar ((:commit . "605b01505ba30589c77ebb4c96834b5072ccbdd4"))]) (magma-mode . [(20180413 1427) ((cl-lib (0 3)) (dash (2 6 0)) (f (0 17 1))) "Magma mode for Emacs" tar ((:commit . "d8e41b3c0bc7d37be78fdbcabf6c13c9e182dfaa") (:url . "https://github.com/ThibautVerron/magma-mode"))]) (magithub . [(20180809 2353) ((emacs (25)) (magit (2 12)) (s (1 12 0)) (ghub+ (0 3)) (git-commit (2 12)) (markdown-mode (2 3))) "Magit interfaces for GitHub" tar ((:commit . "c5204a85133dd0655caf94dbeded0373d61d00d5") (:keywords "git" "tools" "vc") (:authors ("Sean Allred" . "code@seanallred.com")) (:maintainer "Sean Allred" . "code@seanallred.com") (:url . "https://github.com/vermiculus/magithub"))]) (magit-topgit . [(20160313 1954) ((emacs (24 4)) (magit (2 1 0))) "TopGit extension for Magit" single ((:commit . "11489ea798bc88d0ea5244bbf725285eedfefbef") (:keywords "vc" "tools") (:authors ("Yann Hodique" . "yann.hodique@gmail.com")) (:maintainer "Robin Green" . "greenrd@greenrd.org"))]) (magit-todos . [(20180904 1137) ((emacs (25 2)) (async (1 9 2)) (dash (2 13 0)) (f (0 17 2)) (hl-todo (1 9 0)) (magit (2 13 0)) (pcre2el (1 8)) (s (1 12 0))) "Show source file TODOs in Magit" single ((:commit . "2e0f68f093c0523f4cdabb19c07a4b23b3d805c0") (:keywords "magit" "vc") (:authors ("Adam Porter" . "adam@alphapapa.net")) (:maintainer "Adam Porter" . "adam@alphapapa.net") (:url . "http://github.com/alphapapa/magit-todos"))]) (magit-tbdiff . [(20180823 137) ((emacs (24 4)) (magit (2 10 0))) "Magit extension for git-tbdiff" single ((:commit . "0655eeb76e97c2608f30e3a265c1c88eded0166a") (:keywords "vc" "tools") (:authors ("Kyle Meyer" . "kyle@kyleam.com")) (:maintainer "Kyle Meyer" . "kyle@kyleam.com") (:url . "https://github.com/magit/magit-tbdiff"))]) (magit-svn . [(20170213 1233) ((emacs (24 4)) (magit (2 1 0))) "Git-Svn extension for Magit" single ((:commit . "c833903732a14478f5c4cfc561bae7c50671b36c") (:keywords "vc" "tools") (:authors ("Phil Jackson" . "phil@shellarchive.co.uk")) (:maintainer "Phil Jackson" . "phil@shellarchive.co.uk"))]) (magit-stgit . [(20180522 1242) ((emacs (24 4)) (magit (2 1 0))) "StGit extension for Magit" single ((:commit . "186e60489f5449d87d94aca24b9d65e2f26a3bc5") (:keywords "vc" "tools") (:authors ("Lluís Vilanova" . "vilanova@ac.upc.edu")) (:maintainer "Lluís Vilanova" . "vilanova@ac.upc.edu"))]) (magit-popup . [(20180726 2037) ((emacs (24 4)) (async (1 9 2)) (dash (2 13 0))) "Define prefix-infix-suffix command combos" tar ((:commit . "6e07f745a18af514c2885eeabe9b2b2a5216e53c") (:keywords "bindings") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:url . "https://github.com/magit/magit-popup"))]) (magit-p4 . [(20170414 1246) ((magit (2 1)) (magit-popup (2 1)) (p4 (12 0)) (cl-lib (0 5))) "git-p4 plug-in for Magit" single ((:commit . "01e8bb24830861c50109878812550b4265cba82b") (:keywords "vc" "tools") (:authors ("Damian T. Dobroczy\\\\'nski" . "qoocku@gmail.com")) (:maintainer "Aleksey Fedotov" . "lexa@cfotr.com") (:url . "https://github.com/qoocku/magit-p4"))]) (magit-org-todos . [(20180709 1950) ((magit (2 0 0)) (emacs (24))) "Add local todo items to the magit status buffer" single ((:commit . "9ffa3efb098434d837cab4bacd1601fdfc6fe999") (:keywords "org-mode" "magit" "tools") (:authors ("Daniel Ma")) (:maintainer "Daniel Ma") (:url . "http://github.com/danielma/magit-org-todos"))]) (magit-lfs . [(20170312 2224) ((emacs (24 4)) (magit (2 10 3)) (dash (2 13 0))) "Magit plugin for Git LFS" single ((:commit . "799282fce73b668d2cf6e4fa87f889fec8e25333") (:keywords "magit" "git" "lfs" "tools" "vc") (:authors ("Junyoung Clare Jang" . "jjc9310@gmail.com")) (:maintainer "Junyoung Clare Jang" . "jjc9310@gmail.com") (:url . "https://github.com/ailrun/magit-lfs"))]) (magit-imerge . [(20180609 1558) ((emacs (24 4)) (magit (2 10 0))) "Magit extension for git-imerge" single ((:commit . "1cb30746f4541295a60ba7584be3d4f8654c6c9b") (:keywords "vc" "tools") (:authors ("Kyle Meyer" . "kyle@kyleam.com")) (:maintainer "Kyle Meyer" . "kyle@kyleam.com") (:url . "https://github.com/magit/magit-imerge"))]) (magit-gitflow . [(20170929 824) ((magit (2 1 0)) (magit-popup (2 2 0))) "gitflow extension for magit" single ((:commit . "cc41b561ec6eea947fe9a176349fb4f771ed865b") (:keywords "vc" "tools") (:authors ("Jan Tatarik" . "Jan.Tatarik@gmail.com")) (:maintainer "Jan Tatarik" . "Jan.Tatarik@gmail.com") (:url . "https://github.com/jtatarik/magit-gitflow"))]) (magit-gh-pulls . [(20180716 1636) ((emacs (24 4)) (gh (0 9 1)) (magit (2 12 0)) (pcache (0 2 3)) (s (1 6 1))) "GitHub pull requests extension for Magit" single ((:commit . "6949e973f3e951cb0bfe75d889e0fcccc33ba733") (:keywords "git" "tools") (:authors ("Yann Hodique" . "yann.hodique@gmail.com")) (:maintainer "Yann Hodique" . "yann.hodique@gmail.com") (:url . "https://github.com/sigma/magit-gh-pulls"))]) (magit-gerrit . [(20160226 930) ((magit (2 3 1))) "Magit plugin for Gerrit Code Review" single ((:commit . "ece6f369694aca17f3ac166ed2801b432acfe20d") (:authors ("Brian Fransioli" . "assem@terranpro.org")) (:maintainer "Brian Fransioli" . "assem@terranpro.org") (:url . "https://github.com/terranpro/magit-gerrit"))]) (magit-find-file . [(20150702 830) ((magit (2 1 0)) (dash (2 8 0))) "completing-read over all files in Git" single ((:commit . "c3ea91bab37d10a814a829728ec972811f728d60") (:keywords "git") (:authors ("Bradley Wright" . "brad@intranation.com")) (:maintainer "Bradley Wright" . "brad@intranation.com") (:url . "https://github.com/bradleywright/magit-find-file.el"))]) (magit-filenotify . [(20151116 2340) ((magit (1 3 0)) (emacs (24 4))) "Refresh status buffer when git tree changes" single ((:commit . "c0865b3c41af20b6cd89de23d3b0beb54c8401a4") (:keywords "tools") (:authors ("Rüdiger Sonderfeld" . "ruediger@c-plusplus.de")) (:maintainer "Rüdiger Sonderfeld" . "ruediger@c-plusplus.de"))]) (magit-annex . [(20180716 112) ((cl-lib (0 3)) (magit (2 12 0))) "Control git-annex from Magit" single ((:commit . "e36674fa052431342942ce42c3e396318a5bb5b0") (:keywords "vc" "tools") (:authors ("Kyle Meyer" . "kyle@kyleam.com") ("Rémi Vanicat" . "vanicat@debian.org")) (:maintainer "Kyle Meyer" . "kyle@kyleam.com") (:url . "https://github.com/magit/magit-annex"))]) (magit . [(20180903 2339) ((emacs (25 1)) (async (20180527)) (dash (20180413)) (ghub (20180417)) (git-commit (20180602)) (magit-popup (20180509)) (with-editor (20180414))) "A Git porcelain inside Emacs." tar ((:commit . "0e818e9dfd053eed6da8a40bbf6a65f2fa4b2ed8"))]) (magik-mode . [(20180903 2111) nil "mode for editing Magik + some utils." tar ((:commit . "b944eaa20d4f8b732768dc5cb67ee246a1a4f9e1") (:keywords "languages") (:url . "http://github.com/roadrunner1776/magik"))]) (magic-latex-buffer . [(20170531 5) ((cl-lib (0 5)) (emacs (24 3))) "Magically enhance LaTeX-mode font-locking for semi-WYSIWYG editing" single ((:commit . "c03277d5619d9adcd871f3e6480a1a27985810cb") (:authors ("zk_phi")) (:maintainer "zk_phi") (:url . "http://hins11.yu-yake.com/"))]) (magic-filetype . [(20180219 1552) ((emacs (24)) (s (1 9 0))) "Enhance filetype major mode" single ((:commit . "019494add5ff02dd36cb3f500142fc51125522cc") (:keywords "emulations" "vim" "ft" "file" "magic-mode") (:authors ("USAMI Kenta" . "tadsan@zonu.me")) (:maintainer "USAMI Kenta" . "tadsan@zonu.me") (:url . "https://github.com/zonuexe/magic-filetype.el"))]) (mag-menu . [(20150505 1850) ((splitter (0 1 0))) "Intuitive keyboard-centric menu system" single ((:commit . "9b9277021cd09fb1dba64b1d2a00705d20914bd6") (:keywords "convenience") (:authors ("Steven Thomas")) (:maintainer "Steven Thomas") (:url . "https://github.com/chumpage/mag-menu"))]) (madhat2r-theme . [(20170203 30) ((emacs (24))) "dark color theme that is easy on the eyes" single ((:commit . "6b387f09de055cfcc15d74981cd4f32f8f9a7323") (:keywords "color" "theme") (:authors ("Micah Duke")) (:maintainer "Micah Duke") (:url . "https://github.com/madhat2r/madhat2r-theme"))]) (macrostep . [(20161120 2106) ((cl-lib (0 5))) "interactive macro expander" tar ((:commit . "424e3734a1ee526a1bd7b5c3cd1d3ef19d184267") (:keywords "lisp" "languages" "macro" "debugging") (:authors ("joddie" . "j.j.oddie@gmail.com")) (:maintainer "joddie" . "j.j.oddie@gmail.com") (:url . "https://github.com/joddie/macrostep"))]) (macro-math . [(20130328 1604) nil "in-buffer mathematical operations" single ((:commit . "216e59371e9ee39c34117ba79b9acd78bb415750") (:keywords "convenience") (:authors ("Nikolaj Schumacher <bugs * nschum de>")) (:maintainer "Nikolaj Schumacher <bugs * nschum de>") (:url . "http://nschum.de/src/emacs/macro-math/"))]) (maces-game . [(20170903 1551) ((dash (2 12 0)) (cl-lib (0 5)) (emacs (24))) "another anagram game." tar ((:commit . "c0fb795f5642467ea528d2f04d904547e8a77ecd") (:keywords "games" "word games" "anagram") (:authors ("Pawel Bokota" . "pawelb.lnx@gmail.com")) (:maintainer "Pawel Bokota" . "pawelb.lnx@gmail.com") (:url . "https://github.com/pawelbx/anagram-game"))]) (mac-pseudo-daemon . [(20170728 1940) ((cl-lib (0 1))) "Daemon mode that plays nice with Mac OS." single ((:commit . "d235680a72677f11925b912428ad1a57b664e3e8") (:keywords "convenience" "osx" "mac") (:authors ("Ryan C. Thompson")) (:maintainer "Ryan C. Thompson") (:url . "https://github.com/DarwinAwardWinner/osx-pseudo-daemon"))]) (m-buffer . [(20170407 2141) ((seq (2 14))) "List-Oriented, Functional Buffer Manipulation" tar ((:commit . "8681342aaffa187e5c54945ab91b812965a96d19") (:authors ("Phillip Lord" . "phillip.lord@russet.org.uk")) (:maintainer "Phillip Lord" . "phillip.lord@russet.rg.uk"))]) (lyrics . [(20180812 1841) ((emacs (25 1)) (seq (2 15))) "Show lyrics" single ((:commit . "d0b920be634a5be81ad49418cfaada0f0a57d6cd") (:keywords "convenience") (:authors ("Mario Rodas" . "marsam@users.noreply.github.com")) (:maintainer "Mario Rodas" . "marsam@users.noreply.github.com") (:url . "https://github.com/emacs-pe/lyrics.el"))]) (lxc-tramp . [(20180523 2024) ((emacs (24)) (cl-lib (0 6))) "TRAMP integration for LXC containers" single ((:commit . "1aab85fef50df2067902bff13e1bac5e6366908b") (:keywords "lxc" "convenience") (:authors ("montag451")) (:maintainer "montag451") (:url . "https://github.com/montag451/lxc-tramp"))]) (lxc . [(20140410 2022) nil "lxc integration with Emacs" single ((:commit . "88bed56c954d1edd9ff5ce0ced2c02dcf9f71835") (:keywords "processes") (:authors ("Nic Ferrier" . "nferrier@ferrier.me.uk")) (:maintainer "Nic Ferrier" . "nferrier@ferrier.me.uk") (:url . "https://github.com/nicferrier/emacs-lxc"))]) (lv . [(20160912 1456) nil "Other echo area" single ((:commit . "44b42598eed5077d8945ef44c38d80b59510b865") (:authors ("Oleh Krehel")) (:maintainer "Oleh Krehel"))]) (lusty-explorer . [(20180628 1346) nil "Dynamic filesystem explorer and buffer switcher" single ((:commit . "fc4b2f0f8a07db107234490fdfbf72f8b76a6643") (:keywords "convenience" "files" "matching"))]) (lush-theme . [(20180816 2200) ((emacs (24))) "A dark theme with lush colors" single ((:commit . "7cfc993709d712f75c51b505078608c9e1c11466") (:keywords "theme" "dark" "strong colors") (:authors ("Andre Richter" . "andre.o.richter@gmail.com")) (:maintainer "Andre Richter" . "andre.o.richter@gmail.com") (:url . "https://github.com/andre-richter/emacs-lush-theme"))]) (luarocks . [(20170430 2305) ((emacs (24)) (cl-lib (0 5))) "luarocks tools" single ((:commit . "cee27ba0716edf338077387969883226dd2b7484") (:keywords "convenience") (:authors ("Mario Rodas" . "marsam@users.noreply.github.com")) (:maintainer "Mario Rodas" . "marsam@users.noreply.github.com") (:url . "https://github.com/emacs-pe/luarocks.el"))]) (lua-mode . [(20180323 1021) nil "a major-mode for editing Lua scripts" tar ((:commit . "99312b8d6c500ba3067da6d81efcfbbea05a1cbd") (:keywords "languages" "processes" "tools") (:authors ("2011-2013 immerrr" . "immerrr+lua@gmail.com") ("2010-2011 Reuben Thomas" . "rrt@sc3d.org") ("2006 Juergen Hoetzel" . "juergen@hoetzel.info") ("2004 various (support for Lua 5 and byte compilation)") ("2001 Christian Vogler" . "cvogler@gradient.cis.upenn.edu") ("1997 Bret Mogilefsky" . "mogul-lua@gelatinous.com") ("tcl-mode by Gregor Schmid" . "schmid@fb3-s7.math.tu-berlin.de") ("with tons of assistance from") ("Paul Du Bois" . "pld-lua@gelatinous.com") ("Aaron Smith" . "aaron-lua@gelatinous.com")) (:maintainer "2011-2013 immerrr" . "immerrr+lua@gmail.com") (:url . "http://immerrr.github.com/lua-mode"))]) (lsp-vue . [(20180628 715) ((emacs (25 1)) (lsp-mode (3 0))) "Vue support for lsp-mode" single ((:commit . "3c3f364f70d300101a37a239a6bf8c382176f238") (:authors ("Nikita Sivakov" . "cryptomaniac.512@gmail.com")) (:maintainer "Nikita Sivakov" . "cryptomaniac.512@gmail.com") (:url . "https://github.com/emacs-lsp/lsp-vue"))]) (lsp-ui . [(20180831 459) ((emacs (25 1)) (dash (2 13)) (dash-functional (1 2 0)) (flycheck (31)) (lsp-mode (4 0)) (markdown-mode (2 3))) "UI modules for lsp-mode" tar ((:commit . "d1b1713389c8b80a6d7b1c2f11d80755408fa29c") (:keywords "lsp") (:authors ("Tobias Pisani" . "topisani@hamsterpoison.com")) (:maintainer "Tobias Pisani" . "topisani@hamsterpoison.com") (:url . "https://github.com/emacs-lsp/lsp-ui"))]) (lsp-typescript . [(20180614 2011) ((lsp-mode (3 0)) (typescript-mode (0 1)) (emacs (25 1))) "Javascript/Typescript support for lsp-mode" single ((:commit . "7e7c5f66b02321f402712841064347cb872c41e4") (:keywords "languages" "tools") (:authors ("George Pittarelli" . "g@gjp.cc")) (:maintainer "George Pittarelli" . "g@gjp.cc") (:url . "https://github.com/emacs-lsp/lsp-javascript"))]) (lsp-rust . [(20180305 1308) ((emacs (25)) (lsp-mode (3 0)) (rust-mode (0 3 0)) (dash (1 0)) (markdown-mode (2 3))) "Rust support for lsp-mode" single ((:commit . "ecc889cc8735b280e0e6e84d2f4526b0048148b3") (:keywords "rust") (:authors ("Vibhav Pant" . "vibhavp@gmail.com")) (:maintainer "Vibhav Pant" . "vibhavp@gmail.com") (:url . "https://github.com/emacs-lsp/lsp-rust"))]) (lsp-ruby . [(20180611 2119) ((lsp-mode (3 0)) (emacs (25 1))) "Ruby support for lsp-mode" single ((:commit . "2bf50315374251a265fe4787c73839c96d8ed5aa") (:keywords "languages" "tools") (:authors ("George Pittarelli" . "g@gjp.cc")) (:maintainer "George Pittarelli" . "g@gjp.cc") (:url . "https://github.com/emacs-lsp/lsp-ruby"))]) (lsp-python . [(20180816 1314) ((lsp-mode (3 0))) "Python support for lsp-mode" single ((:commit . "b97688aa82b41828d3ffb5345c809d1fee88839d") (:keywords "python") (:authors ("Vibhav Pant" . "vibhavp@gmail.com")) (:maintainer "Vibhav Pant" . "vibhavp@gmail.com") (:url . "https://github.com/emacs-lsp/lsp-python"))]) (lsp-php . [(20180331 1644) ((emacs (25 1)) (lsp-mode (3 4))) "PHP support for lsp-mode" single ((:commit . "f96e23570120eca765132504df852a78d8b4d042") (:authors ("Declspeck" . "declspeck@declblog.com") ("zg" . "13853850881@163.com")) (:maintainer "Declspeck" . "declspeck@declblog.com") (:url . "https://github.com/emacs-lsp/lsp-php"))]) (lsp-p4 . [(20180728 1915) ((lsp-mode (3 0))) "P4 support for lsp-mode" single ((:commit . "17172f41220a42b23c5b396340d1af02ee612125") (:keywords "lsp" "p4") (:authors ("Dmitri Makarov")) (:maintainer "Dmitri Makarov") (:url . "https://github.com/dmakarov/p4ls"))]) (lsp-ocaml . [(20180610 1854) ((emacs (25 1)) (lsp-mode (3 0))) "OCaml support for lsp-mode" single ((:commit . "5a8c776b6d75b502703243b3d628fccd813481b0") (:keywords "languages" "ocaml" "reason" "lsp") (:authors ("Antonio N. Monteiro" . "anmonteiro@gmail.com")) (:maintainer "Antonio N. Monteiro" . "anmonteiro@gmail.com") (:url . "https://github.com/emacs-lsp/lsp-ocaml"))]) (lsp-mode . [(20180830 523) ((emacs (25 1))) "Minor mode for interacting with Language Servers" tar ((:commit . "6eadc0c2a0762b35440a2f6eb6ba27a528334b22") (:authors ("Vibhav Pant" . "vibhavp@gmail.com")) (:maintainer "Vibhav Pant" . "vibhavp@gmail.com") (:url . "https://github.com/emacs-lsp/lsp-mode"))]) (lsp-javascript-typescript . [(20180614 2011) ((lsp-mode (3 0)) (typescript-mode (0 1)) (emacs (25 1))) "Javascript/Typescript support for lsp-mode" single ((:commit . "7e7c5f66b02321f402712841064347cb872c41e4") (:keywords "languages" "tools") (:authors ("George Pittarelli" . "g@gjp.cc")) (:maintainer "George Pittarelli" . "g@gjp.cc") (:url . "https://github.com/emacs-lsp/lsp-javascript"))]) (lsp-javascript-flow . [(20180613 508) ((lsp-mode (3 0)) (emacs (25 1))) "Javascript/Flow support for lsp-mode" single ((:commit . "7e7c5f66b02321f402712841064347cb872c41e4") (:keywords "languages" "tools") (:authors ("Ozan Sener" . "hi@ozan.email")) (:maintainer "Ozan Sener" . "hi@ozan.email") (:url . "https://github.com/emacs-lsp/lsp-javascript"))]) (lsp-javacomp . [(20180219 734) ((emacs (25 1)) (lsp-mode (3 0)) (s (1 2 0))) "Provide Java IDE features powered by JavaComp." single ((:commit . "ed2ed9e3fb2305de889be49068a39448af4cb522") (:keywords "java") (:url . "https://github.com/tigersoldier/lsp-javacomp"))]) (lsp-java . [(20180818 1833) ((emacs (25 1)) (lsp-mode (3 0)) (markdown-mode (2 3))) "Java support for lsp-mode" single ((:commit . "7eb0beb26888a6ba1045e3e3c4c27906d1af64dc") (:keywords "java") (:url . "https://github.com/emacs-lsp/lsp-java"))]) (lsp-intellij . [(20180831 2051) ((emacs (25 1)) (lsp-mode (4 1))) "intellij lsp client" single ((:commit . "cf30f0ac63bd0140e758840b8ab070e8313697b2") (:keywords "languages" "processes" "tools") (:authors ("Ruin0x11" . "ipickering2@gmail.com")) (:maintainer "Ruin0x11" . "ipickering2@gmail.com") (:url . "https://github.com/Ruin0x11/lsp-intellij"))]) (lsp-html . [(20180629 725) ((lsp-mode (4 2))) "HTML support for lsp-mode" single ((:commit . "53b3c30511cab7e5f1e4ad15094b407b27cdc7f5") (:keywords "languages" "html" "lsp") (:authors ("Vibhav Pant" . "vibhavp@gmail.com")) (:maintainer "Vibhav Pant" . "vibhavp@gmail.com") (:url . "https://github.com/emacs-lsp/lsp-html"))]) (lsp-haskell . [(20180828 838) ((lsp-mode (3 0)) (haskell-mode (1 0))) "Haskell support for lsp-mode" single ((:commit . "ec38000fc1768a0e03a88ef51a12c3710ce52484") (:keywords "haskell") (:url . "https://github.com/emacs-lsp/lsp-haskell"))]) (lsp-hack . [(20180818 200) ((lsp-mode (4 2))) "lsp-mode client for hacklang" single ((:commit . "a7fe82cc598264be3a0a378426a1da2c41ffc140") (:authors ("John Allen" . "oss@porcnick.com")) (:maintainer "John Allen" . "oss@porcnick.com") (:url . "https://github.com/jra3/lsp-hack"))]) (lsp-go . [(20180818 704) ((lsp-mode (3 0))) "Go support for lsp-mode" single ((:commit . "55601ec667df887fc1f9645e8bb8f29c774a175d") (:keywords "go" "golang") (:authors ("Vibhav Pant" . "vibhavp@gmail.com")) (:maintainer "Vibhav Pant" . "vibhavp@gmail.com") (:url . "https://github.com/emacs-lsp/lsp-go"))]) (lsp-css . [(20180627 1951) ((lsp-mode (3 0)) (emacs (25 1))) "CSS/LESS/SASS support for lsp-mode" single ((:commit . "1395b48209c5744e19f688ebb5fe8201e5a006df") (:keywords "languages" "tools") (:authors ("George Pittarelli" . "g@gjp.cc")) (:maintainer "George Pittarelli" . "g@gjp.cc") (:url . "https://github.com/emacs-lsp/lsp-css"))]) (lsp-clangd . [(20180828 1657) ((lsp-mode (3 0)) (emacs (24 3))) "clangd support for lsp-mode" single ((:commit . "37ca521483e3ce5b63b97672916368dbf4566a67") (:keywords "lsp" "clang" "clangd" "c" "c++" "objective-c" "objective-c++") (:authors ("Thomas Brown" . "tabsoftwareconsulting@gmail.com")) (:maintainer "Thomas Brown" . "tabsoftwareconsulting@gmail.com") (:url . "https://github.com/emacs-lsp/lsp-clangd"))]) (love-minor-mode . [(20170727 536) ((lua-mode (20130419))) "Minor mode for working on LÖVE projects" single ((:commit . "3ca8f3405338f2d6f4fbcdd5e89342a46378543a") (:authors ("Eric James Michael Ritz")) (:maintainer "Eric James Michael Ritz") (:url . "https://github.com/ejmr/love-minor-mode"))]) (lorem-ipsum . [(20140911 2108) nil "Insert dummy pseudo Latin text." single ((:commit . "4b39f6fed455d67f635b3837cf5668bf74d0f6cd") (:keywords "tools" "language" "convenience") (:authors ("Jean-Philippe Theberge" . "jphil21@sourceforge.net")) (:maintainer "Joe Schafer" . "joe@jschaf.com"))]) (loop . [(20160813 1407) nil "friendly imperative loop structures" single ((:commit . "e22807f83a0890dc8a904c51ee0742c34efccc6c") (:keywords "loop" "while" "for each" "break" "continue") (:authors ("Wilfred Hughes" . "me@wilfred.me.uk")) (:maintainer "Wilfred Hughes" . "me@wilfred.me.uk"))]) (look-mode . [(20151211 1826) nil "quick file viewer for image and text file browsing" single ((:commit . "d65f75e8ea24eff2ac31c53b4835b45127eedd56") (:authors ("Peter H. Mao <peter.mao@gmail.com>" . "peterm@srl.caltech.edu")) (:maintainer "Peter H. Mao <peter.mao@gmail.com>" . "peterm@srl.caltech.edu"))]) (look-dired . [(20160729 2323) ((look-mode (1 0))) "Extensions to look-mode for dired buffers" single ((:commit . "9bfa4e5e6f3810705b6426c88493ea0bf6b15640") (:keywords "convenience") (:authors ("Joe Bloggs" . "vapniks@yahoo.com")) (:maintainer "Joe Bloggs" . "vapniks@yahoo.com") (:url . "https://github.com/vapniks/look-dired"))]) (lolcode-mode . [(20111002 847) nil "Major mode for editing LOLCODE" single ((:commit . "1914f1ba87587ecf5f175eeb2144c28e9f039317") (:keywords "lolcode" "major" "mode") (:authors ("Bodil Stokke" . "lolcode@bodil.tv")) (:maintainer "Bodil Stokke" . "lolcode@bodil.tv") (:url . "http://github.com/bodil/lolcode-mode"))]) (logview . [(20180522 1754) ((emacs (24 4)) (datetime (0 3))) "Major mode for viewing log files" single ((:commit . "902c881f5e1ca802761b856b3945bd418847dd79") (:keywords "files" "tools") (:authors ("Paul Pogonyshev" . "pogonyshev@gmail.com")) (:maintainer "Paul Pogonyshev" . "pogonyshev@gmail.com") (:url . "https://github.com/doublep/logview"))]) (logstash-conf . [(20170524 1929) nil "basic mode for editing logstash configuration" single ((:commit . "4e127f9aec190786613445aa88efa307ff7c6748") (:authors ("Wilfred Hughes" . "me@wilfred.me.uk")) (:maintainer "Wilfred Hughes" . "me@wilfred.me.uk"))]) (logpad . [(20180607 1915) nil "Simulate Windows Notepad for logging." single ((:keywords "files" "outlines" "notepad") (:authors ("Jens K. Loewe" . "git@tuxproject.de")) (:maintainer "Jens K. Loewe" . "git@tuxproject.de") (:url . "https://bitbucket.org/tux_/logpad.el"))]) (lognav-mode . [(20180708 1022) ((emacs (24 3))) "Navigate Log Error Messages" single ((:keywords "log" "error" "lognav-mode" "convenience") (:authors ("Shawn Ellis" . "shawn.ellis17@gmail.com")) (:maintainer "Shawn Ellis" . "shawn.ellis17@gmail.com") (:url . "https://bitbucket.org/ellisvelo/lognav-mode"))]) (logito . [(20120225 2055) ((eieio (1 3))) "logging library for Emacs" single ((:commit . "824acb89d2cc18cb47281a4fbddd81ad244a2052") (:keywords "lisp" "tool") (:authors ("Yann Hodique" . "yann.hodique@gmail.com")) (:maintainer "Yann Hodique" . "yann.hodique@gmail.com"))]) (logalimacs . [(20131021 1829) ((popwin (0 6 2)) (popup (0 5 0)) (stem (20130120))) "Front-end to logaling-command for Ruby gems" single ((:commit . "8286e39502250fc6c3c6656a7f46a8eee8e9a713") (:keywords "translation" "logaling-command") (:authors ("Yuta Yamada <cokesboy\"at\"gmail.com>")) (:maintainer "Yuta Yamada <cokesboy\"at\"gmail.com>") (:url . "https://github.com/logaling/logalimacs"))]) (log4j-mode . [(20160108 1918) nil "major mode for viewing log files" single ((:commit . "26171b1e723502055e085393b0ecdcb6db406010") (:keywords "tools") (:authors ("Johan Dykstrom" . "jody4711-sf@yahoo.se")) (:maintainer "Johan Dykstrom" . "jody4711-sf@yahoo.se") (:url . "http://log4j-mode.sourceforge.net"))]) (log4e . [(20170401 1304) nil "provide logging framework for elisp" single ((:commit . "c69424e407be0d9d0e54b427d8b18b1ac5a607e2") (:keywords "log") (:authors ("Hiroaki Otsu" . "ootsuhiroaki@gmail.com")) (:maintainer "Hiroaki Otsu" . "ootsuhiroaki@gmail.com") (:url . "https://github.com/aki2o/log4e"))]) (lodgeit . [(20150312 1349) nil "Paste to a lodgeit powered pastebin" single ((:commit . "ec9b8e5cbb17bcf8ac4bdddd1d361cb60e59384c") (:keywords "pastebin" "lodgeit") (:authors ("Eric Larson" . "eric@ionrock.org")) (:maintainer "Eric Larson" . "eric@ionrock.org") (:url . "https://github.com/ionrock/lodgeit-el"))]) (lockfile-mode . [(20170625 507) nil "Major mode for .lock files" single ((:commit . "fcfef88460cb3cd67c4d83a1801d0326d282feac") (:authors ("Preetpal S. Sohal")) (:maintainer "Preetpal S. Sohal") (:url . "https://github.com/preetpalS/emacs-lockfile-mode"))]) (loccur . [(20161227 1051) ((emacs (24 3))) "Perform an occur-like folding in current buffer" single ((:commit . "650d91dda0d313c8f445a0803c07809d857dee0f") (:keywords "matching") (:authors ("Alexey Veretennikov" . "alexey.veretennikov@gmail.com")) (:maintainer "Alexey Veretennikov" . "alexey.veretennikov@gmail.com") (:url . "https://github.com/fourier/loccur"))]) (loc-changes . [(20160801 1708) nil "keep track of positions even after buffer changes" single ((:commit . "4d1dcdf7631c23b1259ad4f72bf9686cf95fb46c") (:authors ("Rocky Bernstein" . "rocky@gnu.org")) (:maintainer "Rocky Bernstein" . "rocky@gnu.org") (:url . "http://github.com/rocky/emacs-loc-changes"))]) (load-theme-buffer-local . [(20120702 2036) nil "Install emacs24 color themes by buffer." single ((:commit . "e606dec66f16a06140b9aad625a4fd52bca4f936") (:keywords "faces") (:authors ("Victor Borja" . "vic.borja@gmail.com")) (:maintainer "Victor Borja" . "vic.borja@gmail.com") (:url . "http://github.com/vic/color-theme-buffer-local"))]) (load-relative . [(20170526 1010) nil "relative file load (within a multi-file Emacs package)" tar ((:commit . "738896e3da491b35399178ed2c6bc92cc728d119") (:keywords "internal") (:authors ("Rocky Bernstein" . "rocky@gnu.org")) (:maintainer "Rocky Bernstein" . "rocky@gnu.org") (:url . "http://github.com/rocky/emacs-load-relative"))]) (load-env-vars . [(20180511 2210) ((emacs (24))) "Load environment variables from files" single ((:commit . "3808520efaf9492033f6e11a9bffd68eabf02a0f") (:keywords "lisp") (:authors ("Jorge Dias" . "jorge@mrdias.com")) (:maintainer "Jorge Dias" . "jorge@mrdias.com") (:url . "https://github.com/diasjorge/emacs-load-env-vars"))]) (lms . [(20170804 1622) ((emacs (25 1))) "Squeezebox / Logitech Media Server frontend" single ((:keywords "multimedia") (:authors ("Iñigo Serna" . "inigoserna@gmail.com")) (:maintainer "Iñigo Serna" . "inigoserna@gmail.com") (:url . "https://bitbucket.com/inigoserna/lms.el"))]) (livid-mode . [(20131116 1344) ((skewer-mode (1 5 3)) (s (1 8 0))) "Live browser eval of JavaScript every time a buffer changes" single ((:commit . "dfe5212fa64738bc4138bfebf349fbc8bc237c26") (:authors ("Murphy McMahon")) (:maintainer "Murphy McMahon") (:url . "https://github.com/pandeiro/livid-mode"))]) (livescript-mode . [(20140613 421) nil "Major mode for editing LiveScript files" single ((:commit . "90a918d9686e256e6d4d439cc20f24dad8d3b804") (:keywords "languages" "livescript") (:authors ("Hisamatsu Yasuyuki" . "yas@null.net")) (:maintainer "Hisamatsu Yasuyuki" . "yas@null.net") (:url . "https://github.com/yhisamatsu/livescript-mode"))]) (livereload . [(20170629 650) ((emacs (25)) (websocket (1 8))) "Livereload server" tar ((:commit . "1e501d7e46dbd476c2c7cc9d20b5ac9d41fb1955") (:keywords "convenience") (:authors ("João Távora" . "joaotavora@gmail.com")) (:maintainer "João Távora" . "joaotavora@gmail.com"))]) (lively . [(20171005 754) nil "interactively updating text" single ((:commit . "348675828c6a81bfa1ac311ca465aad813542c1b") (:authors ("Luke Gorrie" . "luke@bup.co.nz")) (:maintainer "Steve Purcell" . "steve@sanityinc.com"))]) (live-py-mode . [(20180811 1820) ((emacs (24 3))) "Live Coding in Python" tar ((:commit . "5d8cd84cd844c191ceab3be693d117f5ec703217") (:keywords "live" "coding") (:authors ("Don Kirkby http://donkirkby.github.io")) (:maintainer "Don Kirkby http://donkirkby.github.io") (:url . "http://donkirkby.github.io/live-py-plugin/"))]) (live-code-talks . [(20150115 2223) ((emacs (24)) (cl-lib (0 5)) (narrowed-page-navigation (0 1))) "Support for slides with live code in them" single ((:commit . "fece58108939a53104f88d348298c9e122f25b75") (:keywords "docs" "multimedia") (:authors ("David Raymond Christiansen" . "david@davidchristiansen.dk")) (:maintainer "David Raymond Christiansen" . "david@davidchristiansen.dk"))]) (literate-starter-kit . [(20150730 1854) ((emacs (24 3))) "A literate starter kit to configure Emacs using Org-mode files." tar ((:commit . "6dce1d01781966c14558aa553cfc85008c06e115"))]) (literate-coffee-mode . [(20170211 1515) ((coffee-mode (0 5 0))) "major-mode for Literate CoffeeScript" single ((:commit . "55ce0305495f4a38c8063c4bd63deb1e1252373d") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-literate-coffee-mode"))]) (literal-string . [(20170301 1530) ((markdown-mode (2 0)) (emacs (25))) "edit string literals in a dedicated buffer" single ((:commit . "2ca4fc08b8e19e6183b1f1db747bb0a4aa4f98eb") (:keywords "lisp" "tools" "docs") (:authors ("Joost Diepenmaat" . "joost@zeekat.nl")) (:maintainer "Joost Diepenmaat" . "joost@zeekat.nl") (:url . "https://github.com/joodie/literal-string-mode/"))]) (litecoin-ticker . [(20160612 11) ((json (1 2))) "litecoin price in modeline" single ((:commit . "3d8047c736e4ee0b8638953f8cc63eaefad34106") (:authors ("Zhe Lei")) (:maintainer "Zhe Lei"))]) (litable . [(20160922 1559) ((dash (2 6 0))) "dynamic evaluation replacement with emacs" single ((:commit . "90a2dca14a6da9b24fe332a65cff899ab4a90810") (:keywords "lisp") (:authors ("Matus Goljer" . "matus.goljer@gmail.com")) (:maintainer "Matus Goljer" . "matus.goljer@gmail.com"))]) (lit-mode . [(20141123 1736) nil "Major mode for lit" single ((:commit . "c61c403afc8333a5649c5421ab1a6341dc1c7d92") (:keywords "languages" "tools") (:authors ("Hector A Escobedo" . "ninjahector.escobedo@gmail.com")) (:maintainer "Hector A Escobedo" . "ninjahector.escobedo@gmail.com"))]) (list-utils . [(20160414 1402) nil "List-manipulation utility functions" single ((:commit . "acf18aca1131a90f8d673974673e3c5d8fdc6a86") (:keywords "extensions") (:authors ("Roland Walker" . "walker@pobox.com")) (:maintainer "Roland Walker" . "walker@pobox.com") (:url . "http://github.com/rolandwalker/list-utils"))]) (list-unicode-display . [(20150219 901) ((cl-lib (0 5))) "Search for and list unicode characters by name" single ((:commit . "222c21c68ccc930b2843ea919c960de9be3b55c2") (:keywords "convenience") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com"))]) (list-packages-ext . [(20151115 1716) ((s (1 6 0)) (ht (1 5 0)) (persistent-soft (0 8 6))) "Extras for list-packages" single ((:commit . "b4dd644e4369c9aa66f5bb8895ea49ebbfd0a27a") (:keywords "convenience" "tools") (:authors ("Alessandro Piras" . "laynor@gmail.com")) (:maintainer "Alessandro Piras" . "laynor@gmail.com"))]) (list-environment . [(20151227 256) nil "A tabulated process environment editor" single ((:commit . "b7ca30b05905047be2e55199a6475f8d98ce318b") (:keywords "processes" "unix") (:authors ("Charles L.G. Comstock" . "dgtized@gmail.com")) (:maintainer "Charles L.G. Comstock" . "dgtized@gmail.com"))]) (lispyville . [(20180704 1158) ((lispy (0)) (evil (1 2 12)) (cl-lib (0 5)) (emacs (24 4))) "A minor mode for integrating evil with lispy." single ((:commit . "8c5fdec474cad95a09a69c9b9f7d593d2cd67fee") (:keywords "vim" "evil" "lispy" "lisp" "parentheses") (:authors ("Fox Kiester" . "noct@openmailbox.org")) (:maintainer "Fox Kiester" . "noct@openmailbox.org") (:url . "https://github.com/noctuid/lispyville"))]) (lispyscript-mode . [(20170720 1917) nil "Major mode for LispyScript code." single ((:commit . "def632e3335b0c481fbcf5a17f18b0a8c58dd12f") (:keywords "lisp" "languages") (:authors ("Kris Jenkins" . "krisajenkins@gmail.com")) (:maintainer "Kris Jenkins" . "krisajenkins@gmail.com") (:url . "https://github.com/krisajenkins/lispyscript-mode"))]) (lispy . [(20180831 1327) ((emacs (24 1)) (ace-window (0 9 0)) (iedit (0 9 9)) (swiper (0 7 0)) (hydra (0 13 4)) (zoutline (0 1 0))) "vi-like Paredit" tar ((:commit . "053037137e8587380e6d0f8c1b4f6a83c48d2528"))]) (lispxmp . [(20170926 23) nil "Automagic emacs lisp code annotation" single ((:commit . "7ad077b4ee91ce8a42f84eeddb9fc7ea4eac7814") (:keywords "lisp" "convenience") (:authors ("rubikitch" . "rubikitch@ruby-lang.org")) (:maintainer "rubikitch" . "rubikitch@ruby-lang.org") (:url . "http://www.emacswiki.org/cgi-bin/wiki/download/lispxmp.el"))]) (lisp-extra-font-lock . [(20160930 1927) nil "Highlight bound variables and quoted exprs." single ((:commit . "092f5a6e75ddfc8051b252f10e182723a17980e4") (:keywords "languages" "faces") (:authors ("Anders Lindgren")) (:maintainer "Anders Lindgren") (:url . "https://github.com/Lindydancer/lisp-extra-font-lock"))]) (liso-theme . [(20160410 2029) nil "Eclectic Dark Theme for GNU Emacs" single ((:commit . "844688245eb860d23043455e165ee24503454c81") (:keywords "theme" "themes") (:authors ("Vlad Piersec" . "vlad.piersec@gmail.com")) (:maintainer "Vlad Piersec" . "vlad.piersec@gmail.com") (:url . "https://github.com/caisah/liso-theme"))]) (liquid-types . [(20151202 735) ((flycheck (0 13)) (dash (1 2)) (emacs (24 1)) (popup (0 5 2)) (pos-tip (0 5 0)) (flycheck-liquidhs (0 0 1)) (button-lock (1 0 2))) "show inferred liquid-types" single ((:commit . "cc4bacbbf204ef9cf0756f78dfebee2c6ae14d7b") (:authors ("Ranjit Jhala" . "jhala@cs.ucsd.edu")) (:maintainer "Ranjit Jhala" . "jhala@cs.ucsd.edu"))]) (linum-relative . [(20180124 1047) nil "display relative line number in emacs." single ((:commit . "c74a6981b688a5e1e6b8e0809363963ff558ce4d") (:keywords "converience") (:authors ("coldnew" . "coldnew.tw@gmail.com")) (:maintainer "coldnew" . "coldnew.tw@gmail.com") (:url . "http://github.com/coldnew/linum-relative"))]) (linum-off . [(20160217 2137) nil "Provides an interface for turning line-numbering off" single ((:commit . "116e66ac259b183e0763b85616888316ab196822") (:keywords "line" "numbering") (:authors ("Matthew L. Fidler, Florian Adamsky (see wiki)")) (:maintainer "Matthew L. Fidler") (:url . "http://www.emacswiki.org/emacs/auto-indent-mode.el "))]) (linphone . [(20130524 1109) nil "Emacs interface to Linphone" tar ((:commit . "99af3db941b7f4e5272bb48bff96c1ce4ceac302") (:keywords "comm") (:authors ("Yoni Rabkin" . "yonirabkin@member.fsf.org")) (:maintainer "Yoni Rabkin" . "yonirabkin@member.fsf.org") (:url . "https://github.com/zabbal/emacs-linphone"))]) (link-hint . [(20180519 2130) ((avy (0 4 0)) (emacs (24 1)) (cl-lib (0 5))) "Use avy to open, copy, etc. visible links." single ((:commit . "23df5fa36ab182452be6b772475eab67b846dd92") (:keywords "convenience" "url" "avy" "link" "links" "hyperlink") (:authors ("Fox Kiester" . "noct@openmailbox.org")) (:maintainer "Fox Kiester" . "noct@openmailbox.org") (:url . "https://github.com/noctuid/link-hint.el"))]) (link . [(20140718 329) nil "Hypertext links in text buffers" single ((:commit . "a23b8f4a422d0de69a006ed010eff5795319db98") (:keywords "interface" "hypermedia") (:authors ("Torsten Hilbrich" . "torsten.hilbrich@gmx.net")) (:maintainer "Torsten Hilbrich" . "torsten.hilbrich@gmx.net"))]) (linguistic . [(20180831 2154) nil "A package for basic linguistic analysis." tar ((:commit . "18e28a7e54efb140c17e16836bc5dac766c9522e") (:keywords "linguistics" "text analysis" "matching") (:authors ("Andrew Favia <drewlinguistics01 at gmail dot com>")) (:maintainer "Andrew Favia <drewlinguistics01 at gmail dot com>") (:url . "https://github.com/andcarnivorous/linguistic"))]) (lingr . [(20100807 1731) nil "Lingr Client for GNU Emacs" single ((:commit . "4215a8704492d3c860097cbe2649936c22c196df") (:keywords "chat" "client" "internet") (:authors ("lugecy" . "lugecy@gmail.com")) (:maintainer "lugecy" . "lugecy@gmail.com") (:url . "http://github.com/lugecy/lingr-el"))]) (lines-at-once . [(20180422 247) ((emacs (25))) "Insert and edit multiple lines at once" single ((:commit . "a018ba90549384d52ec58c2685fd14a0f65252be") (:keywords "abbrev" "tools") (:authors ("Jiahao Li" . "jiahaowork@gmail.com")) (:maintainer "Jiahao Li" . "jiahaowork@gmail.com") (:url . "https://github.com/jiahaowork/lines-at-once.el"))]) (line-up-words . [(20180219 1024) nil "Align words in an intelligent way" single ((:commit . "6927b4525ae8fe6ebb5428e21def56eeea20611f") (:url . "https://github.com/janestreet/line-up-words"))]) (line-reminder . [(20180603 552) ((emacs (24 4)) (cl-lib (0 6))) "Remind current line status by current buffer." single ((:commit . "e5b08b2c6ed4f8695019dcb41d280101d92771fd") (:authors ("Shen, Jen-Chieh" . "jcs090218@gmail.com")) (:maintainer "Shen, Jen-Chieh" . "jcs090218@gmail.com") (:url . "https://github.com/jcs090218/line-reminder"))]) (light-soap-theme . [(20150607 1445) ((emacs (24))) "Emacs 24 theme with a light background." single ((:commit . "76a787bd40c6b567ae68ced7f5d9f9f10725e00d"))]) (lice . [(20170220 943) nil "License And Header Template" tar ((:commit . "4339929927c62bd636f89bb39ea999d18d269250") (:keywords "template" "license" "tools") (:authors ("Taiki Sugawara" . "buzz.taiki@gmail.com")) (:maintainer "Taiki Sugawara" . "buzz.taiki@gmail.com") (:url . "https://github.com/buzztaiki/lice-el"))]) (libmpdel . [(20180606 1153) ((emacs (25 1))) "Communication with an MPD server" single ((:commit . "3d3bcd9de8a3836ec7d7ec5b5db121bcefe65149") (:keywords "multimedia") (:authors ("Damien Cassou" . "damien@cassou.me")) (:maintainer "Damien Cassou" . "damien@cassou.me") (:url . "https://gitlab.petton.fr/mpdel/libmpdel"))]) (libmpdee . [(20160117 2301) nil "Client end library for mpd, a music playing daemon" single ((:commit . "a6ca3b7d6687f3ba60996b9b5044ad1d3b228290") (:keywords "music" "mpd") (:authors ("Ramkumar R. Aiyengar" . "andyetitmoves@gmail.com")) (:maintainer "Ramkumar R. Aiyengar" . "andyetitmoves@gmail.com"))]) (libgit . [(20180625 659) ((emacs (25 1))) "Thin bindings to libgit2." tar ((:commit . "1efd2eca8cc3fad08a239d9046892c699448d64b") (:keywords "git" "vc") (:authors ("Eivind Fonn" . "evfonn@gmail.com")) (:maintainer "Eivind Fonn" . "evfonn@gmail.com") (:url . "https://github.com/TheBB/libegit2"))]) (libelcouch . [(20180604 753) ((emacs (25 1)) (request (0 3 0))) "Communication with CouchDB" single ((:commit . "1396144ebbb9790d4c744db0d4aacc0211b8e8e6") (:keywords "tools") (:authors ("Damien Cassou" . "damien@cassou.me")) (:maintainer "Damien Cassou" . "damien@cassou.me") (:url . "https://gitlab.petton.fr/elcouch/libelcouch/"))]) (lfe-mode . [(20170121 1254) nil "Lisp Flavoured Erlang mode" tar ((:commit . "ea62f924b7abbe2a0ff65e27be47acb7f452bc38"))]) (lexbind-mode . [(20141027 1429) nil "Puts the value of lexical-binding in the mode line" single ((:commit . "fa0a6848c1cfd3fbf45db43dc2deef16377d887d") (:keywords "convenience" "lisp") (:authors ("Andrew Kirkpatrick" . "ubermonk@gmail.com")) (:maintainer "Andrew Kirkpatrick" . "ubermonk@gmail.com") (:url . "https://github.com/spacebat/lexbind-mode"))]) (levenshtein . [(20090830 1040) nil "Edit distance between two strings." single ((:commit . "070925197ebf6b704e6e00c4f2d2ec783f3df38c") (:keywords "lisp") (:authors ("Aaron S. Hawley <ashawley at uvm dot edu>,") ("Art Taylor")) (:maintainer "Aaron S. Hawley <ashawley at uvm dot edu>,"))]) (leuven-theme . [(20170919 952) nil "Awesome Emacs color theme on white background" tar ((:commit . "9d31a9d4ed763d6309e9d44985cd8b4a5a2fb500") (:keywords "color" "theme") (:authors ("Fabrice Niessen <(concat \"fniessen\" at-sign \"pirilampo.org\")>")) (:maintainer "Fabrice Niessen <(concat \"fniessen\" at-sign \"pirilampo.org\")>") (:url . "https://github.com/fniessen/emacs-leuven-theme"))]) (letterbox-mode . [(20170702 125) ((emacs (24 3))) "hide sensitive text on a buffer" single ((:commit . "88c67a51d67216d569a28e8423200883fde096dd") (:keywords "password" "convenience") (:authors ("Fernando Leboran" . "f.leboran@gmail.com")) (:maintainer "Fernando Leboran" . "f.leboran@gmail.com") (:url . "http://github.com/pacha64/letterbox-mode"))]) (letcheck . [(20160202 1948) nil "Check the erroneous assignments in let forms" single ((:commit . "edf188ca2f85349e971b83f164c6484264e79426") (:keywords "convenience") (:authors ("Matus Goljer" . "matus.goljer@gmail.com")) (:maintainer "Matus Goljer" . "matus.goljer@gmail.com") (:url . "https://github.com/Fuco1/letcheck"))]) (less-css-mode . [(20161001 453) nil "Major mode for editing LESS CSS files (lesscss.org)" single ((:commit . "2c3f69640c3c98457255f601db98f520dee2e7b6") (:keywords "less" "css" "mode") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:url . "https://github.com/purcell/less-css-mode"))]) (lentic-server . [(20160717 2052) ((lentic (0 8)) (web-server (0 1 1))) "Web Server for Emacs Literate Source" single ((:commit . "8e809fafbb27a98f815b544d9d9ee15843eb6a36") (:authors ("Phillip Lord" . "phillip.lord@newcastle.ac.uk")) (:maintainer "Phillip Lord" . "phillip.lord@newcastle.ac.uk"))]) (lentic . [(20161202 2152) ((emacs (24 4)) (m-buffer (0 13)) (dash (2 5 0)) (f (0 17 2)) (s (1 9 0))) "One buffer as a view of another" tar ((:commit . "678db9327209a1e6200c9272f4080595dc68f8a5") (:authors ("Phillip Lord" . "phillip.lord@russet.org.uk")) (:maintainer "Phillip Lord" . "phillip.lord@russet.org.uk"))]) (lenlen-theme . [(20170329 245) ((color-theme-solarized (20150110))) "a solarized-based kawaii light theme" single ((:commit . "b8a6412c81633b10fb98ba0930f55b25071c084a") (:authors ("zk_phi")) (:maintainer "zk_phi") (:url . "http://hins11.yu-yake.com/"))]) (lemon-mode . [(20130216 1304) nil "A major mode for editing lemon grammar files" single ((:commit . "155bfced6c9afc8072a0133d3d1baa54c6d67430") (:keywords "lemon") (:authors ("mooz" . "stillpedant@gmail.com")) (:maintainer "mooz" . "stillpedant@gmail.com"))]) (legalese . [(20150820 1724) nil "Add legalese to your program files" single ((:commit . "ec23e69d18329456beed9546a1d6c72f96db91cf") (:keywords "convenience") (:authors ("Jorgen Schaefer" . "forcer@forcix.cx")) (:maintainer "Jorgen Schaefer" . "forcer@forcix.cx") (:url . "https://github.com/jorgenschaefer/legalese"))]) (leerzeichen . [(20170422 1313) nil "Minor mode to display whitespace characters." single ((:commit . "5acf9855ecb2b2cd5da4402bb48df149e7525cc5") (:keywords "whitespace" "characters") (:authors ("Felix Geller" . "fgeller@gmail.com")) (:maintainer "Felix Geller" . "fgeller@gmail.com") (:url . "http://github.com/fgeller/leerzeichen.el"))]) (ledger-mode . [(20180826 243) ((emacs (24 3))) "Helper code for use with the \"ledger\" command-line tool" tar ((:commit . "b0e31e8788dac15c7eed855e5c92ad3d2b45c114"))]) (leanote . [(20161223 139) ((emacs (24 4)) (cl-lib (0 5)) (request (0 2)) (let-alist (1 0 3)) (pcache (0 4 0)) (s (1 10 0)) (async (1 9))) "A minor mode writing markdown leanote" single ((:commit . "d499e7b59bb1f1a2fabc0e4c26fb101ed62ebc7b") (:keywords "leanote" "note" "markdown") (:authors ("Aborn Jiang" . "aborn.jiang@gmail.com")) (:maintainer "Aborn Jiang" . "aborn.jiang@gmail.com") (:url . "https://github.com/aborn/leanote-emacs"))]) (lean-mode . [(20180712 757) ((emacs (24 3)) (dash (2 12 0)) (dash-functional (1 2 0)) (s (1 10 0)) (f (0 19 0)) (flycheck (30))) "A major mode for the Lean language" tar ((:commit . "529b8fa535cfa090a6b62566794161556ffade80") (:keywords "languages") (:authors ("Leonardo de Moura" . "leonardo@microsoft.com") ("Soonho Kong      " . "soonhok@cs.cmu.edu") ("Gabriel Ebner    " . "gebner@gebner.org") ("Sebastian Ullrich" . "sebasti@nullri.ch")) (:maintainer "Sebastian Ullrich" . "sebasti@nullri.ch") (:url . "https://github.com/leanprover/lean-mode"))]) (lcr . [(20180902 1919) ((dash (2 12 0)) (emacs (25 1))) "lightweight coroutines" single ((:commit . "c14f40692292d59156c7632dbdd2867c086aa75f") (:keywords "tools") (:authors ("Jean-Philippe Bernardy" . "jeanphilippe.bernardy@gmail.com")) (:maintainer "Jean-Philippe Bernardy" . "jeanphilippe.bernardy@gmail.com") (:url . "https://github.com/jyp/lcr"))]) (lcb-mode . [(20160816 540) ((emacs (24))) "LiveCode Builder major mode" single ((:commit . "be0768e9aa6f9b8e76f2230f4f7f4d152a766b9a") (:keywords "languages") (:authors ("Peter TB Brett" . "peter@peter-b.co.uk")) (:maintainer "Peter TB Brett" . "peter@peter-b.co.uk") (:url . "https://github.com/peter-b/lcb-mode"))]) (lavender-theme . [(20170808 1313) ((emacs (24 0))) "an Emacs 24 theme based on Lavender (tmTheme)" single ((:commit . "ef5e959b95d7fb8152137bc186c4c24e986c1e3c") (:authors ("Jason Milkins")) (:maintainer "Jason Milkins") (:url . "https://github.com/emacsfodder/tmtheme-to-deftheme"))]) (launchctl . [(20150518 1309) ((emacs (24 1))) "Interface to launchctl on Mac OS X." single ((:commit . "73f8f52a5aa9a0be9bdcf68c29ad0fa2b4a115a4") (:keywords "tools" "convenience") (:authors ("Peking Duck <github.com/pekingduck>")) (:maintainer "Peking Duck <github.com/pekingduck>") (:url . "http://github.com/pekingduck/launchctl-el"))]) (launch-mode . [(20170106 512) ((emacs (24 4))) "Major mode for launch-formatted text" tar ((:commit . "25ebd4ba77afcbe729901eb74923dbe9ae81c313") (:authors ("iory" . "ab.ioryz@gmail.com")) (:maintainer "iory" . "ab.ioryz@gmail.com") (:url . "https://github.com/iory/launch-mode"))]) (launch . [(20130619 2204) nil "launch files with OS-standard associated applications." single ((:commit . "e7c3b573fc05fe4d3d322389079909311542e799") (:keywords "convenience" "processes") (:authors ("Simon Law" . "sfllaw@sfllaw.ca")) (:maintainer "Simon Law" . "sfllaw@sfllaw.ca") (:url . "https://github.com/sfllaw/emacs-launch"))]) (latexdiff . [(20180521 2232) ((emacs (24 4))) "Latexdiff integration in Emacs" single ((:commit . "024ee7a4fd235695dacd9f53594fef3d79bee88b") (:keywords "tex" "vc" "tools" "git" "helm") (:authors ("Launay Gaby" . "gaby.launay@tutanota.com")) (:maintainer "Launay Gaby" . "gaby.launay@tutanota.com") (:url . "http://github.com/galaunay/latexdiff.el"))]) (latex-unicode-math-mode . [(20170123 1816) nil "Input method for Unicode math symbols" tar ((:commit . "eb4a5c9f9b00a58d2ca80f90782a851f4c8497b8") (:authors ("Christoph Dittmann" . "github@christoph-d.de")) (:maintainer "Christoph Dittmann" . "github@christoph-d.de") (:url . "https://github.com/Christoph-D/latex-unicode-math-mode"))]) (latex-preview-pane . [(20180222 1751) nil "Makes LaTeX editing less painful by providing a updatable preview pane" tar ((:commit . "e7dbe0df3ca938128ab394cdf04f3e40eb5b139e"))]) (latex-pretty-symbols . [(20151112 1044) nil "Display many latex symbols as their unicode counterparts" single ((:keywords "convenience" "display") (:authors ("Erik Parmann" . "eparmann@gmail.com") ("Pål Drange")) (:maintainer "Erik Parmann" . "eparmann@gmail.com") (:url . "https://bitbucket.org/mortiferus/latex-pretty-symbols.el"))]) (latex-math-preview . [(20170522 2155) nil "preview LaTeX mathematical expressions." single ((:commit . "775887a89447dd19541b121161cc02e9799d0d3a") (:keywords "latex" "tex") (:authors ("Takayuki YAMAGUCHI" . "d@ytak.info")) (:maintainer "Takayuki YAMAGUCHI" . "d@ytak.info") (:url . "https://gitlab.com/latex-math-preview/latex-math-preview"))]) (latex-extra . [(20170817 147) ((auctex (11 86 1)) (cl-lib (0 5))) "Adds several useful functionalities to LaTeX-mode." single ((:commit . "82d99b8b0c2db20e5270749582e03bcc2443ffb5") (:keywords "tex") (:authors ("Artur Malabarba" . "artur@endlessparentheses.com")) (:maintainer "Artur Malabarba" . "artur@endlessparentheses.com") (:url . "http://github.com/Malabarba/latex-extra"))]) (lastpass . [(20171208 1016) ((emacs (24 4)) (seq (1 9)) (cl-lib (0 5))) "LastPass command wrapper" single ((:commit . "a4529ce70b8187ed9ac4972997df152af58ef2eb") (:keywords "extensions" "processes" "lpass" "lastpass") (:authors ("Petter Storvik")) (:maintainer "Petter Storvik") (:url . "https://github.com/storvik/emacs-lastpass"))]) (language-detection . [(20161123 1813) ((emacs (24)) (cl-lib (0 5))) "Automatic language detection from code snippets" single ((:commit . "54a6ecf55304fba7d215ef38a4ec96daff2f35a4") (:authors ("Andreas Jansson" . "andreas@jansson.me.uk")) (:maintainer "Andreas Jansson" . "andreas@jansson.me.uk") (:url . "https://github.com/andreasjansson/language-detection.el"))]) (langtool . [(20180409 1016) ((cl-lib (0 3))) "Grammar check utility using LanguageTool" single ((:commit . "d93286722cff3fecf8641a4a6c3b0691f30362fe") (:keywords "docs") (:authors ("Masahiro Hayashi" . "mhayashi1120@gmail.com")) (:maintainer "Masahiro Hayashi" . "mhayashi1120@gmail.com") (:url . "https://github.com/mhayashi1120/Emacs-langtool"))]) (langdoc . [(20150218 645) ((cl-lib (0 2))) "Help to define help document mode for various languages" single ((:commit . "2c7223bacb116992d700ecb19a60df5c09c63424") (:keywords "convenience" "eldoc") (:authors ("Tomoya Tanjo" . "ttanjo@gmail.com")) (:maintainer "Tomoya Tanjo" . "ttanjo@gmail.com") (:url . "https://github.com/tom-tan/langdoc/"))]) (lang-refactor-perl . [(20131122 2127) nil "Simple refactorings, primarily for Perl" single ((:commit . "691bd69639de6b7af357e3b7143563ececd9c497") (:keywords "languages" "refactoring" "perl") (:authors (nil . "Johan Lindstrom <buzzwordninja not_this_bit@googlemail.com>")) (:maintainer nil . "Johan Lindstrom <buzzwordninja not_this_bit@googlemail.com>") (:url . "https://github.com/jplindstrom/emacs-lang-refactor-perl"))]) (lammps-mode . [(20180801 1319) ((emacs (24 4))) "basic syntax highlighting for LAMMPS files" single ((:commit . "a5b68d7a59975770b56ee8f6e66fa4f703a72ffe") (:keywords "languages" "faces") (:authors ("Aidan Thompson <athomps at sandia.gov>")) (:maintainer "Rohit Goswami <r95g10 at gmail.com>") (:url . "https://github.com/lammps/lammps/tree/master/tools/emacs"))]) (labburn-theme . [(20170502 907) nil "A lab color space zenburn theme." single ((:commit . "e95334acd8a73fbe8e156f70e047014a87e92e66") (:keywords "theme" "zenburn") (:authors ("Johannes Goslar")) (:maintainer "Johannes Goslar") (:url . "https://github.com/ksjogo/labburn-theme"))]) (kwin . [(20150308 1812) nil "communicatewith the KWin window manager" single ((:commit . "d4f8f3593598b71ee596e0a87b2c1d6a912a9566") (:authors ("Simon Hafner")) (:maintainer "Simon Hafner") (:url . "http://github.com/reactormonk/kwin-minor-mode"))]) (kv . [(20140108 1534) nil "key/value data structure functions" single ((:commit . "721148475bce38a70e0b678ba8aa923652e8900e") (:keywords "lisp") (:authors ("Nic Ferrier" . "nferrier@ferrier.me.uk")) (:maintainer "Nic Ferrier" . "nferrier@ferrier.me.uk"))]) (kurecolor . [(20180401 1221) ((emacs (24 1)) (s (1 0))) "color editing goodies for Emacs" single ((:commit . "a27153f6a01f38226920772dc4917b73166da5e6") (:authors ("Jason Milkins" . "jasonm23@gmail.com")) (:maintainer "Jason Milkins" . "jasonm23@gmail.com"))]) (kubernetes-tramp . [(20171026 1622) ((emacs (24)) (cl-lib (0 5))) "TRAMP integration for kubernetes containers" single ((:commit . "9fa84df71f6e88bc23a756cdf2df393a35aec945") (:keywords "kubernetes" "convenience") (:authors ("Giovanni Ruggiero" . "giovanni.ruggiero+github@gmail.com")) (:maintainer "Giovanni Ruggiero" . "giovanni.ruggiero+github@gmail.com") (:url . "https://github.com/gruggiero/kubernetes-tramp"))]) (kubernetes-evil . [(20171123 219) ((kubernetes (0 12 0)) (evil (1 2 12))) "Kubernetes keybindings for evil-mode." single ((:commit . "2b5ce22b12bd8a569cb0a8019a395173e3a13523") (:authors ("Chris Barrett" . "chris+emacs@walrus.cool")) (:maintainer "Chris Barrett" . "chris+emacs@walrus.cool"))]) (kubernetes . [(20180706 1220) ((emacs (25 1)) (dash (2 12 0)) (magit (2 8 0))) "Magit-like porcelain for Kubernetes." tar ((:commit . "2b5ce22b12bd8a569cb0a8019a395173e3a13523") (:authors ("Chris Barrett" . "chris+emacs@walrus.cool")) (:maintainer "Chris Barrett" . "chris+emacs@walrus.cool"))]) (ksp-cfg-mode . [(20180609 547) ((cl-lib (0 5))) "major mode for editing KSP CFG files" single ((:commit . "fda64705f605fb8fccee53a5040fe4865ca17d44") (:keywords "data") (:authors ("Emily Backes" . "lucca@accela.net")) (:maintainer "Emily Backes" . "lucca@accela.net") (:url . "http://github.com/lashtear/ksp-cfg-mode"))]) (kroman . [(20150827 2340) nil "Korean hangul romanization" single ((:commit . "90402b6ae40383e75d8ba97d66eee93eebf40f70") (:keywords "korean" "roman") (:authors ("Zhang Kai Yu" . "yeannylam@gmail.com")) (:maintainer "Zhang Kai Yu" . "yeannylam@gmail.com"))]) (kpm-list . [(20170924 1352) nil "An emacs buffer list that tries to intelligently group together buffers." single ((:commit . "e0f5112e5ce8ec1b603f4428fa51681c68bb28f5") (:authors ("Kevin Mahoney")) (:maintainer "Kevin Mahoney") (:url . "https://github.com/KMahoney/kpm-list/"))]) (kotlin-mode . [(20180219 1653) ((emacs (24 3))) "Major mode for kotlin" single ((:commit . "a2c2628d55c4e8b018ffe9f55ca38d89302a1bbc") (:keywords "languages") (:authors ("Shodai Yokoyama" . "quantumcars@gmail.com")) (:maintainer "Shodai Yokoyama" . "quantumcars@gmail.com"))]) (kosmos-theme . [(20170502 1850) ((emacs (24))) "Black and lightgray theme with not so much syntax highlighting." single ((:commit . "616456d2376a75dc31190ad65137d179fbad4336") (:authors ("Maxim Kim" . "habamax@gmail.com")) (:maintainer "Maxim Kim" . "habamax@gmail.com") (:url . "https://github.com/habamax/kosmos-theme"))]) (korean-holidays . [(20170301 445) nil "Korean holidays for calendar." single ((:commit . "6e94c2e071069aee9ed12ebbfd9b0ad863b8c78e") (:keywords "calendar") (:authors ("SeungKi Kim" . "tttuuu888@gmail.com")) (:maintainer "SeungKi Kim" . "tttuuu888@gmail.com") (:url . "https://github.com/tttuuu888/korean-holidays"))]) (kooten-theme . [(20161023 905) ((emacs (24 1))) "Dark color theme" single ((:commit . "d10197b4dd7af02cd14aeab2573c273a294798c3") (:keywords "themes") (:authors ("Pascal van Kooten" . "kootenpv@gmail.com")) (:maintainer "Pascal van Kooten" . "kootenpv@gmail.com") (:url . "http://github.com/kootenpv/emacs-kooten-theme"))]) (kolon-mode . [(20140122 1134) nil "Syntax highlighting for Text::Xslate's Kolon syntax" single ((:commit . "5af0955e280ae991862189ebecd3937c5fc8fb9f") (:keywords "xslate" "perl") (:authors ("Sam Tran")) (:maintainer "Sam Tran") (:url . "https://github.com/samvtran/kolon-mode"))]) (kodi-remote . [(20180820 715) ((request (0 2 0)) (let-alist (1 0 4)) (json (1 4)) (elnode (20140203 1506))) "Remote Control for Kodi" single ((:commit . "e2df2b6032255a6dc4292e95992e72f579262aaf") (:keywords "kodi" "tools" "convinience") (:authors ("Stefan Huchler" . "stefan.huchler@mail.de")) (:maintainer "Stefan Huchler" . "stefan.huchler@mail.de") (:url . "http://github.com/spiderbit/kodi-remote.el"))]) (know-your-http-well . [(20160208 2304) nil "Look up the meaning of HTTP headers, methods, relations, status codes" tar ((:commit . "3cc5ab6d2764ab7aacb1b6e026abaccbeb6c37f2"))]) (klere-theme . [(20180415 1823) ((emacs (24))) "A dark theme with lambent color highlights and incremental grays" single ((:commit . "c064f9e5c44173c239fce239a62c8d5e61827672") (:authors ("Wamm K. D." . "jaft.r@outlook.com")) (:maintainer "Wamm K. D." . "jaft.r@outlook.com") (:url . "https://github.com/WammKD/emacs-klere-theme"))]) (kixtart-mode . [(20150611 1604) ((emacs (24))) "major mode for Kixtart scripting files" single ((:commit . "1c2356797e7b766bbaaa2b341176a8b10499cd79") (:keywords "languages") (:authors ("Ryrun <https://github.com/ryrun>")) (:maintainer "Ryrun <https://github.com/ryrun>") (:url . "https://github.com/ryrun/kixtart-mode"))]) (kiwix . [(20170927 820) ((emacs (24 4)) (cl-lib (0 5))) "Kiwix interface and support." single ((:commit . "86dbead6c0017beefd92a0b64a0bb5f5d12c5b16") (:keywords "kiwix" "wikipedia") (:authors ("stardiviner" . "numbchild@gmail.com")) (:maintainer "stardiviner" . "numbchild@gmail.com") (:url . "https://github.com/stardiviner/kiwix.el"))]) (kivy-mode . [(20180702 2029) nil "Emacs major mode for editing Kivy files" single ((:commit . "038acbf6ac324c8ebca6107185d0a736c21b2fca") (:authors ("Dean Serenevy" . "dean@serenevy.net")) (:maintainer "Dean Serenevy" . "dean@serenevy.net"))]) (kite-mini . [(20160508 1106) ((dash (2 11 0)) (websocket (1 5))) "Remotely evaluate JavaScript in the WebKit debugger" tar ((:commit . "a68619dbc109c7989f3448426d8c1ee9e797c11f") (:keywords "webkit") (:authors ("Tung Dao" . "me@tungdao.com")) (:maintainer "Tung Dao" . "me@tungdao.com") (:url . "https://github.com/tungd/kite-mini.el"))]) (kite . [(20130201 1938) ((json (1 2)) (websocket (0 93 1))) "WebKit inspector front-end" tar ((:commit . "7ed74d1147a6ddd152d3da65dc30df3517d53144") (:keywords "tools") (:authors ("Julian Scheid" . "julians37@gmail.com")) (:maintainer "Julian Scheid" . "julians37@gmail.com"))]) (killer . [(20120808 1122) nil "kill and delete text" single ((:commit . "7bbb223f875402a7b2abee4baa5a54f10bd97212") (:keywords "convenience") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:url . "http://github.com/tarsius/killer"))]) (kill-ring-search . [(20140422 1555) nil "incremental search for the kill ring" single ((:commit . "23535b4a01a1cb1574604e36c49614e84e85c883") (:keywords "convenience" "matching") (:authors ("Nikolaj Schumacher <bugs * nschum de>")) (:maintainer "Nikolaj Schumacher <bugs * nschum de>") (:url . "http://nschum.de/src/emacs/kill-ring-search/"))]) (kill-or-bury-alive . [(20180101 618) ((emacs (24 4)) (cl-lib (0 5))) "Precise control over buffer killing in Emacs" single ((:commit . "0ba8f44efe60058ef66b10a059fd30489b42546f") (:keywords "buffer" "killing" "convenience") (:authors ("Mark Karpov" . "markkarpov92@gmail.com")) (:maintainer "Mark Karpov" . "markkarpov92@gmail.com") (:url . "https://github.com/mrkkrp/kill-or-bury-alive"))]) (kibit-helper . [(20150508 1533) ((s (0 8)) (emacs (24))) "Conveniently use the Kibit Leiningen plugin from Emacs" single ((:commit . "16bdfff785ee05d8e74a5780f6808506d990cef7") (:keywords "languages" "clojure" "kibit") (:authors ("Jonas Enlund") ("James Elliott" . "james@brunchboy.com")) (:maintainer "Jonas Enlund") (:url . "http://www.github.com/brunchboy/kibit-helper"))]) (keyword-search . [(20180424 1102) nil "browser keyword search from Emacs" tar ((:commit . "f8475ecaddb8804a9be6bee47678207c86ac8dee") (:keywords "web" "search" "keyword") (:maintainer "Jens Petersen") (:url . "https://github.com/juhp/keyword-search"))]) (keyswap . [(20160813 957) ((emacs (24 3))) "swap bindings between key pairs" single ((:commit . "cd682a7c4a8d64d6bae6a005db5045232e5e7b95") (:keywords "convenience") (:authors ("Matthew Malcomson" . "hardenedapple@gmail.com")) (:maintainer "Matthew Malcomson" . "hardenedapple@gmail.com") (:url . "http://github.com/hardenedapple/keyswap.el"))]) (keyset . [(20150220 530) ((dash (2 8 0)) (cl-lib (0 5))) "A small library for structuring key bindings." single ((:commit . "41bbfc4dbed5de6ecf3ec1dba634c7c26241ca84") (:authors ("Hiroki YAMAKAWA" . "s06139@gmail.com")) (:maintainer "Hiroki YAMAKAWA" . "s06139@gmail.com") (:url . "https://github.com/HKey/keyset"))]) (keypress-multi-event . [(20180817 853) ((emacs (24 3))) "Perform different actions for the same keypress." single ((:commit . "6a53e3f9435e34e7b4858bc9ec0c180d1e93d15f") (:keywords "abbrev" "convenience" "wp" "keyboard") (:authors ("Boruch Baum" . "boruch_baum@gmx.com")) (:maintainer "Boruch Baum" . "boruch_baum@gmx.com") (:url . "https://www.github.com/Boruch_Baum/emacs-keypress-multi-event"))]) (keymap-utils . [(20180318 2237) ((cl-lib (0 3))) "keymap utilities" single ((:commit . "1ad766dbc111ec78b1a292da97b9bd4856cd2ff7") (:keywords "convenience" "extensions") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:url . "https://github.com/tarsius/keymap-utils"))]) (keyfreq . [(20160516 1416) ((cl-lib (0 5))) "track command frequencies" single ((:commit . "9c665c8c219d18866403897936427bb408e3d6b9") (:authors ("Ryan Yeske, Michal Nazarewicz (mina86/AT/mina86.com)")) (:maintainer "David Capello, Xah lee"))]) (keydef . [(20090428 1931) nil "a simpler way to define keys, with kbd syntax" single ((:commit . "dff2be9f58d12d8c6a490ad0c1b2b10b55528dc0") (:keywords "convenience" "lisp" "customization" "keyboard" "keys") (:authors ("Michael John Downes" . "mjd@ams.org")) (:maintainer "Michael John Downes" . "mjd@ams.org"))]) (keychain-environment . [(20180318 2223) nil "load keychain environment variables" single ((:commit . "d3643196de6dc79ea77f9f4805028350fd76100b") (:keywords "gnupg" "pgp" "ssh") (:authors ("Paul Tipper <bluefoo at googlemail dot com>")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:url . "https://github.com/tarsius/keychain-environment"))]) (keycast . [(20180318 2021) ((emacs (25 3))) "Show current command and its key in the mode line" single ((:commit . "46370b8a72922902921d3ed2fa194564568053dc") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:url . "https://github.com/tarsius/keycast"))]) (key-seq . [(20150907 756) ((key-chord (0 6))) "map pairs of sequentially pressed keys to commands" single ((:commit . "e29b083a6427d061638749194fc249ef69ad2cc0") (:keywords "convenience" "keyboard" "keybindings") (:authors ("Vyacheslav Levit" . "dev@vlevit.org")) (:maintainer "Vyacheslav Levit" . "dev@vlevit.org") (:url . "http://github.com/vlevit/key-seq.el"))]) (key-leap . [(20160831 1447) ((emacs (24 3))) "Leap between lines by typing keywords" single ((:commit . "b3f6ef15c8a13870475d5af159fa24b30f97dea0") (:keywords "point" "convenience") (:authors ("Martin Rykfors" . "martinrykfors@gmail.com")) (:maintainer "Martin Rykfors" . "martinrykfors@gmail.com") (:url . "https://github.com/MartinRykfors/key-leap"))]) (key-intercept . [(20140211 749) nil "Intercept prefix keys" single ((:commit . "d9a60edb4ce893f2d3d94f242164fdcc62d43cf2") (:keywords "keyboard") (:authors ("INA Lintaro <tarao.gnn at gmail.com>")) (:maintainer "INA Lintaro <tarao.gnn at gmail.com>") (:url . "http://github.com/tarao/key-intercept-el"))]) (key-combo . [(20150324 1439) nil "map key sequence to commands" single ((:commit . "2fb5c65bc82d5bd2964e2b163822429ab45d90a1") (:keywords "keyboard" "input") (:authors ("Yuuki Arisawa" . "yuuki.ari@gmail.com")) (:maintainer "Vitalie Spinu" . "spinuvit@gmail.com") (:url . "https://github.com/uk-ar/key-combo"))]) (key-chord . [(20160227 1238) nil "map pairs of simultaneously pressed keys to commands" single ((:commit . "72443e9ff3c4f1c3ccaced3130236801efde3d83") (:keywords "keyboard" "chord" "input") (:authors ("David Andersson <l.david.andersson(at)sverige.nu>")) (:maintainer "David Andersson <l.david.andersson(at)sverige.nu>"))]) (kerl . [(20150424 2005) nil "Emacs integration for kerl" single ((:commit . "1732ee26213f021bf040919c45ad276aafcaae14") (:keywords "tools") (:authors ("Correl Roush" . "correl@gmail.com")) (:maintainer "Correl Roush" . "correl@gmail.com") (:url . "http://github.com/correl/kerl.el/"))]) (kdeconnect . [(20180126 2340) nil "An interface for KDE Connect" single ((:commit . "ca0cbf9a628ba7b519b43fa85e0d988ca26bf853") (:keywords "kdeconnect" "android") (:authors ("Carl Lieberman" . "dev@carl.ac")) (:maintainer "Carl Lieberman" . "dev@carl.ac"))]) (karma . [(20160220 1245) ((pkg-info (0 4)) (emacs (24))) "Karma Test Runner Emacs Integration" single ((:commit . "31d3e7708246183d7ed0686be92bf23140af348c") (:keywords "language" "javascript" "js" "karma" "testing") (:authors ("Samuel Tonini")) (:maintainer "Samuel Tonini") (:url . "http://github.com/tonini/karma.el"))]) (kapacitor . [(20180827 516) ((emacs (25 1)) (magit (2 13 0)) (magit-popup (2 12 4))) "Main file for kapacitor-mode" single ((:commit . "be7dc1459266ea8e0bc85e05736426e53d1b0fca") (:keywords "kapacitor" "emacs" "magit" "tools") (:authors ("Manoj Kumar Manikchand" . "manojm.321@gmail.com")) (:maintainer "Manoj Kumar Manikchand" . "manojm.321@gmail.com") (:url . "http://github.com/Manoj321/kapacitor-el"))]) (kaomoji . [(20171227 440) ((emacs (24 3)) (helm-core (1 9 1))) "Input kaomoji superb easily" tar ((:commit . "90a1490743b2a30762f5454c9d9309018eff83dd") (:keywords "tools" "fun") (:authors ("Ono Hiroko" . "azazabc123@gmail.com")) (:maintainer "Ono Hiroko" . "azazabc123@gmail.com") (:url . "https://github.com/kuanyui/kaomoji.el"))]) (kaolin-themes . [(20180902 1353) ((emacs (25 1)) (autothemer (0 2 2)) (cl-lib (0 6))) "A set of eye pleasing themes" tar ((:commit . "c2b22c3f16bd68674690a65d02ceb70f1c69e40a") (:keywords "dark" "light" "teal" "blue" "violet" "purple" "brown" "theme" "faces") (:authors ("Ogden Webb" . "ogdenwebb@gmail.com")) (:maintainer "Ogden Webb" . "ogdenwebb@gmail.com") (:url . "https://github.com/ogdenwebb/emacs-kaolin-themes"))]) (kanji-mode . [(20160826 1139) nil "View stroke order for kanji characters at cursor" tar ((:commit . "eda4f8666486689d36317db7dbda54fb73d3e3d2") (:authors ("Wojciech Gac" . "wojciech.s.gac@gmail.com")) (:maintainer "Wojciech Gac" . "wojciech.s.gac@gmail.com") (:url . "http://github.com/wsgac/kanji-mode "))]) (kanban . [(20170418 810) nil "Parse org-todo headlines to use org-tables as Kanban tables" single ((:keywords "outlines" "convenience") (:authors ("Arne Babenhauserheide" . "arne_bab@web.de")) (:maintainer "Arne Babenhauserheide" . "arne_bab@web.de"))]) (kaleidoscope-evil-state-flash . [(20170728 1020) ((evil (1 2 12)) (kaleidoscope (0 1 0)) (s (1 11 0))) "Flash keyboard LEDs when changing Evil state" single ((:commit . "52b5be3277f65cb5ca657973e9bd7f914b996356") (:authors ("Gergely Nagy")) (:maintainer "Gergely Nagy") (:url . "https://github.com/algernon/kaleidoscope.el"))]) (kaleidoscope . [(20170808 817) ((s (1 11 0))) "Controlling Kaleidoscope-powered devices." single ((:commit . "52b5be3277f65cb5ca657973e9bd7f914b996356") (:authors ("Gergely Nagy")) (:maintainer "Gergely Nagy") (:url . "https://github.com/algernon/kaleidoscope.el"))]) (kakapo-mode . [(20171004 451) ((cl-lib (0 5))) "TABS (hard or soft) for indentation (leading whitespace), and SPACES for alignment." single ((:commit . "292e07203c676361a1d918deb5acf2123cd70eaf") (:keywords "indentation") (:url . "https://github.com/listx/kakapo-mode"))]) (kaesar-mode . [(20160128 1008) ((kaesar (0 1 4)) (cl-lib (0 3))) "Encrypt/Decrypt buffer by AES with password." single ((:commit . "d087075cb1a46c2c85cd075220e09b2eaef9b86e") (:keywords "data" "convenience") (:authors ("Masahiro Hayashi" . "mhayashi1120@gmail.com")) (:maintainer "Masahiro Hayashi" . "mhayashi1120@gmail.com") (:url . "https://github.com/mhayashi1120/Emacs-kaesar"))]) (kaesar-file . [(20160128 1008) ((kaesar (0 1 1))) "Encrypt/Decrypt file by AES with password." single ((:commit . "d087075cb1a46c2c85cd075220e09b2eaef9b86e") (:keywords "data" "files") (:authors ("Masahiro Hayashi" . "mhayashi1120@gmail.com")) (:maintainer "Masahiro Hayashi" . "mhayashi1120@gmail.com") (:url . "https://github.com/mhayashi1120/Emacs-kaesar"))]) (kaesar . [(20160128 1008) ((cl-lib (0 3))) "Another AES algorithm encrypt/decrypt string with password." single ((:commit . "d087075cb1a46c2c85cd075220e09b2eaef9b86e") (:keywords "data") (:authors ("Masahiro Hayashi" . "mhayashi1120@gmail.com")) (:maintainer "Masahiro Hayashi" . "mhayashi1120@gmail.com") (:url . "https://github.com/mhayashi1120/Emacs-kaesar"))]) (jvm-mode . [(20150422 708) ((dash (2 6 0)) (emacs (24))) "Monitor and manage your JVMs" single ((:commit . "3355dbaf5b0185aadfbad24160399abb32c5bea0") (:keywords "convenience") (:authors ("Martin Trojer" . "martin.trojer@gmail.com")) (:maintainer "Martin Trojer" . "martin.trojer@gmail.com") (:url . "https://github.com/martintrojer/jvm-mode.el"))]) (jumplist . [(20151120 345) ((cl-lib (0 5))) "Jump like vim jumplist or ex jumplist" single ((:commit . "c482d137d95bc5e1bcd790cdbde25b7f729b2502") (:keywords "jumplist" "vim") (:authors ("ganmacs <ganmacs_at_gmail.com>")) (:maintainer "ganmacs <ganmacs_at_gmail.com>") (:url . "https://github.com/ganmacs/jumplist"))]) (jump-tree . [(20171014 1551) nil "Treat position history as a tree" tar ((:commit . "282267dc6305889e31d46b405b7ad4dfe5923b66") (:keywords "convenience" "position" "jump" "tree") (:authors ("Wen Yang" . "yangwen0228@foxmail.com")) (:maintainer "Wen Yang" . "yangwen0228@foxmail.com") (:url . "https://github.com/yangwen0228/jump-tree"))]) (jump-to-line . [(20130122 1653) nil "Jump to line number at point." single ((:commit . "01ef8c3529d85e6c59cc20840acbc4a8e8325bc8") (:keywords "jump" "line" "back" "file" "ruby" "csharp" "python" "perl") (:authors ("ongaeshi")) (:maintainer "ongaeshi"))]) (jump-char . [(20180601 1348) nil "navigation by char" single ((:commit . "1e31a3c687f2b3c71bbfab881c6d75915534bb9e") (:authors ("Le Wang")) (:maintainer "Le Wang") (:url . "https://github.com/lewang/jump-char"))]) (jump . [(20161127 128) ((findr (0 7)) (inflections (2 4)) (cl-lib (0 5))) "build functions which contextually jump between files" single ((:commit . "e4f1372cf22e811faca52fc86bdd5d817498a4d8") (:keywords "project" "convenience" "navigation") (:authors ("Eric Schulte")) (:maintainer "Eric Schulte") (:url . "http://github.com/eschulte/jump.el"))]) (jumblr . [(20170727 2043) ((s (1 8 0)) (dash (2 2 0))) "an anagram game for emacs" tar ((:commit . "34533dfb9db8538c005f4eaffafeff7ed193729f") (:keywords "anagram" "word game" "games") (:url . "https://github.com/mkmcc/jumblr"))]) (julia-shell . [(20161125 1910) ((julia-mode (0 3))) "Major mode for an inferior Julia shell" tar ((:commit . "583a0b2ca20461ab4356929fd0f2212c22341b69") (:authors ("Dennis Ogbe" . "dogbe@purdue.edu")) (:maintainer "Dennis Ogbe" . "dogbe@purdue.edu"))]) (julia-repl . [(20180903 857) ((emacs (25)) (s (1 10))) "A minor mode for a Julia REPL" single ((:commit . "1f6b6bc5832669804318c0c2940573baf91bebb0") (:keywords "languages") (:authors ("Tamas Papp" . "tkpapp@gmail.com")) (:maintainer "Tamas Papp" . "tkpapp@gmail.com"))]) (julia-mode . [(20180816 2117) nil "Major mode for editing Julia source code" single ((:commit . "ec01995f60486480cf2240bbd3b9a2ff3fa9e0f0") (:keywords "languages") (:url . "https://github.com/JuliaLang/julia"))]) (jtags . [(20160211 2029) nil "enhanced tags functionality for Java development" tar ((:commit . "b50daa48510f71e74ce0ec2eb85030896a79cf96") (:keywords "languages" "tools") (:authors ("Alexander Baltatzis" . "alexander@baltatzis.com") ("Johan Dykstrom" . "jody4711-sf@yahoo.se")) (:maintainer "Johan Dykstrom" . "jody4711-sf@yahoo.se") (:url . "http://jtags.sourceforge.net"))]) (jsx-mode . [(20130908 1724) nil "major mode for JSX" single ((:commit . "47213429c09259126cddb5742482cfc444c70d50") (:authors ("Takeshi Arabiki (abicky)")) (:maintainer "Takeshi Arabiki (abicky)") (:url . "https://github.com/jsx/jsx-mode.el"))]) (jst . [(20150604 1138) ((s (1 9)) (f (0 17)) (dash (2 10)) (pcache (0 3)) (emacs (24 4))) "JS test mode" single ((:commit . "2a3fd16c992f7790dc67134ef06a814c3d20579c") (:keywords "js" "javascript" "jasmine" "coffee" "coffeescript") (:authors ("Cheung Hoi Yu" . "yeannylam@gmail.com")) (:maintainer "Cheung Hoi Yu" . "yeannylam@gmail.com") (:url . "https://github.com/cheunghy/jst-mode"))]) (jss . [(20130508 1423) ((emacs (24 1)) (websocket (0)) (js2-mode (0))) "An emacs interface to webkit and mozilla debuggers" tar ((:commit . "41749257aecf13c7bd6ed489b5ab3304d06e40bc") (:keywords "languages") (:authors ("Marco Baringer" . "mb@bese.it")) (:maintainer "Marco Baringer" . "mb@bese.it"))]) (jsonnet-mode . [(20180822 1619) ((emacs (24))) "Major mode for editing jsonnet files" single ((:commit . "0d68681d501fd57ebde5ed4fe100033a5d3aafa8") (:keywords "languages") (:authors ("Nick Lanham")) (:maintainer "Nick Lanham") (:url . "https://github.com/mgyucht/jsonnet-mode"))]) (json-snatcher . [(20150512 347) ((emacs (24))) "Grabs the path to JSON values in a JSON file" single ((:commit . "c4cecc0a5051bd364373aa499c47a1bb7a5ac51c") (:authors ("Sterling Graham" . "sterlingrgraham@gmail.com")) (:maintainer "Sterling Graham" . "sterlingrgraham@gmail.com") (:url . "http://github.com/sterlingg/json-snatcher"))]) (json-rpc . [(20180104 1528) ((emacs (24 1)) (cl-lib (0 5))) "JSON-RPC library" single ((:commit . "0992ae71964055230aa5d4d934a1b93b5dfd7eb4") (:authors ("Christopher Wellons" . "wellons@nullprogram.com")) (:maintainer "Christopher Wellons" . "wellons@nullprogram.com") (:url . "https://github.com/skeeto/elisp-json-rpc"))]) (json-reformat . [(20160212 853) nil "Reformatting tool for JSON" single ((:commit . "8eb6668ed447988aea06467ba8f42e1f2178246f") (:keywords "json") (:authors ("Wataru MIYAGUNI" . "gonngo@gmail.com")) (:maintainer "Wataru MIYAGUNI" . "gonngo@gmail.com") (:url . "https://github.com/gongo/json-reformat"))]) (json-navigator . [(20171220 819) ((emacs (24 3)) (hierarchy (0 6 0))) "View and navigate JSON structures" single ((:commit . "7a1fec93500c46ccba4086d10115d8188607d0d0") (:authors ("Damien Cassou" . "damien@cassou.me")) (:maintainer "Damien Cassou" . "damien@cassou.me") (:url . "https://github.com/DamienCassou/json-navigator"))]) (json-mode . [(20180718 809) ((json-reformat (0 0 5)) (json-snatcher (1 0 0))) "Major mode for editing JSON files." single ((:commit . "ffc92b1eefc54963703b43be140f4c8c8ad348f7") (:authors ("Josh Johnston")) (:maintainer "Josh Johnston") (:url . "https://github.com/joshwnj/json-mode"))]) (jsfmt . [(20150727 2225) nil "Interface to jsfmt command for javascript files" single ((:commit . "68109120f553fbc651fafb6fc35ed83c3e79f8a6") (:authors ("Brett Langdon" . "brett@blangdon.com")) (:maintainer "Brett Langdon" . "brett@blangdon.com") (:url . "https://github.com/brettlangdon/jsfmt.el"))]) (jscs . [(20151015 1749) ((emacs (24 1)) (cl-lib (0 5))) "Consistent JavaScript editing using JSCS" single ((:commit . "9d39d0f2355e69a020bf76242504f3a33e013ccf") (:keywords "languages" "convenience") (:authors ("papaeye" . "papaeye@gmail.com")) (:maintainer "papaeye" . "papaeye@gmail.com") (:url . "https://github.com/papaeye/emacs-jscs"))]) (js3-mode . [(20160515 1550) nil "An improved JavaScript editing mode" tar ((:commit . "229aeb374f1b1f3ee5c59b8ba3eebb6385c232cb") (:keywords "javascript" "languages") (:authors ("Thom Blake" . "webmaster@thomblake.com")) (:maintainer "Thom Blake" . "webmaster@thomblake.com"))]) (js2-refactor . [(20180502 1042) ((js2-mode (20101228)) (s (1 9 0)) (multiple-cursors (1 0 0)) (dash (1 0 0)) (s (1 0 0)) (yasnippet (0 9 0 1))) "A JavaScript refactoring library for emacs." tar ((:commit . "186e1abf8c818623e1eef8bb07509d2ea11367b8"))]) (js2-mode . [(20180724 801) ((emacs (24 1)) (cl-lib (0 5))) "Improved JavaScript editing mode" tar ((:commit . "2ed3cc070c7819556c9c89826b0f5c4629b104ef") (:keywords "languages" "javascript") (:authors ("Steve Yegge" . "steve.yegge@gmail.com") ("mooz" . "stillpedant@gmail.com") ("Dmitry Gutov" . "dgutov@yandex.ru")) (:maintainer "Steve Yegge" . "steve.yegge@gmail.com") (:url . "https://github.com/mooz/js2-mode/"))]) (js2-highlight-vars . [(20170418 1829) ((emacs (24 4)) (js2-mode (20150908))) "highlight occurrences of the variable under cursor" single ((:commit . "e3bb177e50f76b272e8073a94d4f46be6512a163") (:authors ("Mihai Bazon" . "mihai.bazon@gmail.com")) (:maintainer "Mihai Bazon" . "mihai.bazon@gmail.com") (:url . "http://mihai.bazon.net/projects/editing-javascript-with-emacs-js2-mode/js2-highlight-vars-mode"))]) (js2-closure . [(20170816 1918) ((js2-mode (20150909))) "Google Closure dependency manager" single ((:commit . "f59db386d7d0693935d0bf52babcd2c203c06d04") (:keywords "javascript" "closure") (:authors ("Justine Tunney" . "jart@google.com")) (:maintainer "Justine Tunney" . "jart@google.com") (:url . "http://github.com/jart/js2-closure"))]) (js-import . [(20180817 1056) ((emacs (24 4)) (f (0 19 0)) (projectile (0 14 0)) (dash (2 13 0))) "Import Javascript files from your current project or dependencies" single ((:commit . "c98e74a0b43d6ccb8764cf572cdde95ca27f5633") (:keywords "tools") (:authors ("Jakob Lind" . "karl.jakob.lind@gmail.com")) (:maintainer "Jakob Lind" . "karl.jakob.lind@gmail.com") (:url . "https://github.com/jakoblind/js-import"))]) (js-format . [(20170119 102) ((emacs (24 1)) (js2-mode (20101228))) "Format or transform code style using NodeJS server with different javascript formatter" tar ((:commit . "544bda9be72b74ec2d442543ba60cff727d96669") (:keywords "js" "javascript" "format" "standard" "jsbeautify" "esformatter" "airbnb") (:authors ("James Yang" . "jamesyang999@gmail.com")) (:maintainer "James Yang" . "jamesyang999@gmail.com") (:url . "http://github.com/futurist/js-format.el"))]) (js-doc . [(20160715 434) nil "Insert JsDoc style comment easily" single ((:commit . "f0606e89d5aa89146f96edb38cf69af0068a9d1e") (:keywords "document" "comment") (:authors ("mooz" . "stillpedant@gmail.com")) (:maintainer "mooz" . "stillpedant@gmail.com") (:url . "https://github.com/mooz/js-doc"))]) (js-comint . [(20171130 456) ((emacs (24 3))) "JavaScript interpreter in window." single ((:commit . "83e932e4a83d1a69098ee87e0ab911d299368e60") (:keywords "javascript" "node" "inferior-mode" "convenience") (:authors ("Paul Huff" . "paul.huff@gmail.com")) (:maintainer "Chen Bin <chenbin.sh AT gmail DOT com>") (:url . "https://github.com/redguardtoo/js-comint"))]) (js-codemod . [(20171104 1154) ((emacs (24 4))) "Run js-codemod on current line or selected region" tar ((:commit . "014e56c846487d1eeaf8a91dd503b9d96eb1510a") (:keywords "js" "codemod" "region") (:authors (nil . "Torgeir Thoresen <@torgeir>")) (:maintainer nil . "Torgeir Thoresen <@torgeir>"))]) (js-auto-format-mode . [(20180807 1352) ((emacs (24))) "Minor mode for auto-formatting JavaScript code" single ((:commit . "29d245b4d126a5fc5153a4d8f17396be4165b4a6") (:keywords "languages") (:authors ("Masafumi Koba" . "ybiquitous@gmail.com")) (:maintainer "Masafumi Koba" . "ybiquitous@gmail.com") (:url . "https://github.com/ybiquitous/js-auto-format-mode"))]) (js-auto-beautify . [(20161031 509) ((web-beautify (0 3 1)) (web-mode (14 0 27))) "auto format you js/jsx file" single ((:commit . "180d15af7b5dfaab4ee1954cca2fdc797932f9de") (:authors (nil . "quanwei9958@126.com")) (:maintainer nil . "quanwei9958@126.com"))]) (jquery-doc . [(20150812 758) nil "jQuery api documentation interface for emacs" tar ((:commit . "24032284919b942ec27707d929bdd8bf48420062") (:keywords "docs" "jquery") (:authors ("Anantha kumaran" . "ananthakumaran@gmail.com")) (:maintainer "Anantha kumaran" . "ananthakumaran@gmail.com"))]) (jq-mode . [(20180407 1748) ((emacs (25 1))) "Edit jq scripts." tar ((:commit . "72ea5e35e0a66c7275cf4fe4af25a619761653d7") (:authors ("Bjarte Johansen <Bjarte dot Johansen at gmail dot com>")) (:maintainer "Bjarte Johansen <Bjarte dot Johansen at gmail dot com>") (:url . "https://github.com/ljos/jq-mode"))]) (jpop . [(20170410 1250) ((emacs (24)) (dash (2 11 0)) (cl-lib (0 5))) "Lightweight project caching and navigation framework" tar ((:commit . "7628b03260be96576b34459d45959ee77d8b2110") (:keywords "project" "convenience") (:authors ("Dom Charlesworth" . "dgc336@gmail.com")) (:maintainer "Dom Charlesworth" . "dgc336@gmail.com") (:url . "https://github.com/domtronn/jpop.el"))]) (jonprl-mode . [(20160819 59) ((emacs (24 3)) (cl-lib (0 5)) (yasnippet (0 8 0))) "A major mode for editing JonPRL files" tar ((:commit . "6059bb64891fae45827174e044d6a87ac07172d8") (:keywords "languages") (:authors ("David Raymond Christiansen" . "david@davidchristiansen.dk")) (:maintainer "David Raymond Christiansen" . "david@davidchristiansen.dk"))]) (jknav . [(20121006 2025) nil "Automatically enable j/k keys for line-based navigation" single ((:commit . "861245715c728503dad6573278fdd75c271dbf8b") (:keywords "keyboard" "navigation") (:authors ("Aaron Culich" . "aculich@gmail.com")) (:maintainer "Aaron Culich" . "aculich@gmail.com"))]) (jist . [(20161229 1721) ((emacs (24 4)) (dash (2 12 0)) (seq (1 11)) (let-alist (1 0 4)) (magit (2 1 0)) (request (0 2 0))) "Gist integration" single ((:commit . "da0692452e312a99bb27d8708504b521798aca48") (:keywords "convenience") (:authors ("Mario Rodas" . "marsam@users.noreply.github.com")) (:maintainer "Mario Rodas" . "marsam@users.noreply.github.com") (:url . "https://github.com/emacs-pe/jist.el"))]) (jira-markup-mode . [(20150601 2109) nil "Emacs Major mode for JIRA-markup-formatted text files" single ((:commit . "4fc534c47df26a2f402bf835ebe2ed89474a4062") (:keywords "jira" "markup") (:authors ("Matthias Nuessler" . "m.nuessler@web.de>")) (:maintainer "Matthias Nuessler" . "m.nuessler@web.de>") (:url . "https://github.com/mnuessler/jira-markup-mode"))]) (jinja2-mode . [(20141128 1007) nil "A major mode for jinja2" single ((:commit . "cfaa7bbe7bb290cc500440124ce89686f3e26f86") (:authors ("Florian Mounier aka paradoxxxzero")) (:maintainer "Florian Mounier aka paradoxxxzero"))]) (jg-quicknav . [(20170809 130) ((s (1 9 0)) (cl-lib (0 5))) "Quickly navigate the file system to find a file." single ((:commit . "c8d53e774d63e68a944092c08a026b57da741038") (:keywords "navigation") (:authors ("Jeff Gran" . "jeff@jeffgran.com")) (:maintainer "Jeff Gran" . "jeff@jeffgran.com") (:url . "https://github.com/jeffgran/jg-quicknav"))]) (jetbrains . [(20180301 502) ((emacs (24 3)) (cl-lib (0 5)) (f (0 17))) "JetBrains IDE bridge" single ((:commit . "56f71a17d455581c10d48f6dbb31d9e2126227bf") (:keywords "tools" "php") (:authors ("USAMI Kenta" . "tadsan@zonu.me")) (:maintainer "USAMI Kenta" . "tadsan@zonu.me") (:url . "https://github.com/emacs-php/jetbrains.el"))]) (jenkins-watch . [(20121004 2326) nil "Watch continuous integration build status" single ((:commit . "37b84dfbd98240a57ff798e1ff8bc7dba2913577") (:authors ("Andrew Taylor" . "ataylor@redtoad.ca")) (:maintainer "Andrew Taylor" . "ataylor@redtoad.ca") (:url . "https://github.com/ataylor284/jenkins-watch"))]) (jenkins . [(20170721 936) ((dash (2 12)) (emacs (24 3)) (json (1 4))) "Minimalistic Jenkins client for Emacs" single ((:commit . "1ec967973db685c9d84133ec6a5e06489ce06b62") (:keywords "jenkins" "convenience") (:authors ("Rustem Muslimov" . "r.muslimov@gmail.com")) (:maintainer "Rustem Muslimov" . "r.muslimov@gmail.com"))]) (jemdoc-mode . [(20170704 2027) ((emacs (24 3))) "Major mode for editing jemdoc files" single ((:commit . "529b4d4681e1198b9892f340fdd6c3f1592a047a") (:keywords "convenience" "usability") (:authors ("Dimitar Dimitrov" . "mail.mitko@gmail.com")) (:maintainer "Dimitar Dimitrov" . "mail.mitko@gmail.com") (:url . "https://github.com/drdv/jemdoc-mode"))]) (jekyll-modes . [(20141117 1314) ((polymode (0 2))) "Major modes (markdown and HTML) for authoring Jekyll content" single ((:commit . "7cb10b50fd2883e3f7b10fdfd98f19f2f0b2381c") (:keywords "docs") (:authors ("Fredrik Appelberg" . "fredrik@milgrim.local")) (:maintainer "Fredrik Appelberg" . "fredrik@milgrim.local") (:url . "https://github.com/fred-o/jekyll-modes"))]) (jedi-direx . [(20140310 936) ((jedi (0 1 2)) (direx (0 1 -3))) "Tree style source code viewer for Python buffer" single ((:commit . "7a2e677400717ed12b959cb5988e7b3fb1c12117") (:authors ("Takafumi Arakaki <aka.tkf at gmail.com>")) (:maintainer "Takafumi Arakaki <aka.tkf at gmail.com>"))]) (jedi-core . [(20170121 1410) ((emacs (24)) (epc (0 1 0)) (python-environment (0 0 2)) (cl-lib (0 5))) "Common code of jedi.el and company-jedi.el" tar ((:commit . "b0764f425766786dfb1bff910ed1d1670f11eb9c") (:authors ("Takafumi Arakaki <aka.tkf at gmail.com>")) (:maintainer "Takafumi Arakaki <aka.tkf at gmail.com>"))]) (jedi . [(20160426 456) ((emacs (24)) (jedi-core (0 2 2)) (auto-complete (1 4))) "a Python auto-completion for Emacs" single ((:commit . "b0764f425766786dfb1bff910ed1d1670f11eb9c") (:authors ("Takafumi Arakaki <aka.tkf at gmail.com>")) (:maintainer "Takafumi Arakaki <aka.tkf at gmail.com>"))]) (jdee . [(20180831 1500) ((emacs (24 3)) (flycheck (30)) (memoize (1 0 1)) (dash (2 13 0)) (s (1 12 0))) "Java Development Environment for Emacs" tar ((:commit . "8451b811b11d8cb428bafab31752e93180a3c724") (:keywords "java" "tools") (:authors ("Paul Kinnucan" . "pkinnucan@attbi.com")) (:maintainer "Paul Landes") (:url . "http://github.com/jdee-emacs/jdee"))]) (jdecomp . [(20170224 2200) ((emacs (24 5))) "Interface to Java decompilers" single ((:commit . "692866abc83deedce62be8d6040cf24dda7fb7a8") (:keywords "decompile" "java" "languages" "tools") (:authors ("Tianxiang Xiong" . "tianxiang.xiong@gmail.com")) (:maintainer "Tianxiang Xiong" . "tianxiang.xiong@gmail.com") (:url . "https://github.com/xiongtx/jdecomp"))]) (jbeans-theme . [(20180309 1625) ((emacs (24))) "Jbeans theme for GNU Emacs 24 (deftheme)" single ((:commit . "3caa95998d8492a2ca6c17971de499ca15609871") (:authors ("Adam Olsen" . "arolsen@gmail.com")) (:maintainer "Adam Olsen" . "arolsen@gmail.com") (:url . "https://github.com/synic/jbeans-emacs"))]) (jazz-theme . [(20170411 1411) nil "A warm color theme for Emacs 24+." single ((:commit . "b1cb78a97cc4050f19d88a89e455c3e52d98240e") (:authors ("Roman Parykin" . "donderom@ymail.com")) (:maintainer "Roman Parykin" . "donderom@ymail.com") (:url . "https://github.com/donderom/jazz-theme"))]) (jaword . [(20170426 627) ((tinysegmenter (0 1))) "Minor-mode for handling Japanese words better" single ((:commit . "ac062b0e5ab4bd3270497e80aa0f3ac033a0493f") (:authors ("zk_phi")) (:maintainer "zk_phi") (:url . "http://hins11.yu-yake.com/"))]) (javap-mode . [(20120223 2208) nil "Javap major mode" single ((:commit . "864c1130e204b2072e1d19cd027b6fce8ebe6629") (:url . "http://github.com/hiredman/javap-mode"))]) (javadoc-lookup . [(20160214 31) ((cl-lib (0 3))) "Javadoc Emacs integration with Maven" tar ((:commit . "507a2dd443d60b537b8f779c1847e2cd0ccd1382") (:authors ("Christopher Wellons" . "wellons@nullprogram.com")) (:maintainer "Christopher Wellons" . "wellons@nullprogram.com") (:url . "https://github.com/skeeto/javadoc-lookup"))]) (java-snippets . [(20160627 252) ((yasnippet (0 8 0))) "Yasnippets for Java" tar ((:commit . "6d0e2768823be27dbe07448f4cb244cd657a7136") (:authors ("Takayoshi Kimura")) (:maintainer "Takayoshi Kimura") (:url . "https://github.com/nekop/yasnippet-java-mode"))]) (java-imports . [(20170913 1410) ((emacs (24 4)) (s (1 10 0)) (pcache (0 3 2))) "Code for dealing with Java imports" single ((:commit . "e96ff44ed48b362ab6227b8b802b84d84f78bcaa") (:keywords "java") (:authors ("Lee Hinman" . "lee@writequit.org")) (:maintainer "Lee Hinman" . "lee@writequit.org") (:url . "http://www.github.com/dakrone/emacs-java-imports"))]) (jastadd-ast-mode . [(20161219 926) ((emacs (24))) "Major mode for editing JastAdd AST files" single ((:commit . "a29fdb470cbf0a398164950a3b0d2217de48e0c0") (:keywords "languages") (:authors ("Rudi Schlatte" . "rudi@constantly.at")) (:maintainer "Rudi Schlatte" . "rudi@constantly.at") (:url . "https://github.com/rudi/jastadd-ast-mode"))]) (jasminejs-mode . [(20150527 5) nil "A minor mode for manipulating jasmine test files" tar ((:commit . "9f8044bf81ab5b4841a30b0bd099916e1b7ff54a") (:keywords "javascript" "jasmine") (:authors ("Eric Stolten" . "stoltene2@gmail.com")) (:maintainer "Eric Stolten" . "stoltene2@gmail.com") (:url . "https://github.com/stoltene2/jasminejs-mode"))]) (jar-manifest-mode . [(20160501 26) nil "Major mode to edit JAR manifest files" single ((:commit . "270dae14c481300f75ed96dad3a5ae42ca928a1d") (:keywords "convenience" "languages") (:authors ("Omair Majid" . "omair.majid@gmail.com")) (:maintainer "Omair Majid" . "omair.majid@gmail.com") (:url . "http://github.com/omajid/jar-manifest-mode"))]) (jape-mode . [(20140903 1506) nil "An Emacs editing mode mode for GATE's JAPE files" single ((:commit . "85b9182850707b5d107391f6caee5bd401507a7d") (:keywords "languages" "jape" "gate") (:url . "http://github.com/tanzoniteblack/jape-mode"))]) (japanlaw . [(20160129 820) ((cl-lib (0 5))) "Japan law from law.e-gov.go.jp" single ((:commit . "c160e195cda0e02a709a2d39c62bc2a1ed39a09a") (:keywords "docs" "help") (:authors ("Kazushi NODA (http://www.ne.jp/asahi/alpha/kazu/)")) (:maintainer "Masahiro Hayashi" . "mhayashi1120@gmail.com"))]) (japanese-holidays . [(20160928 618) ((cl-lib (0 3))) "calendar functions for the Japanese calendar" single ((:commit . "0bccfac342d6ebda1c1a35c3babca0c800ff0c9b") (:keywords "calendar") (:authors ("Takashi Hattori" . "hattori@sfc.keio.ac.jp") ("Hiroya Murata" . "lapis-lazuli@pop06.odn.ne.jp")) (:maintainer "Takashi Hattori" . "hattori@sfc.keio.ac.jp") (:url . "https://github.com/emacs-jp/japanese-holidays"))]) (jammer . [(20160310 859) nil "Punish yourself for using Emacs inefficiently" single ((:commit . "48aa795df6df7ae6484518bcd0398293ca49d7c6") (:keywords "games") (:authors ("Vasilij Schneidermann" . "v.schneidermann@gmail.com")) (:maintainer "Vasilij Schneidermann" . "v.schneidermann@gmail.com") (:url . "https://github.com/wasamasa/jammer"))]) (jade-mode . [(20160525 1441) nil "Major mode for editing .jade files" single ((:commit . "4dbde92542fc7ad61df38776980905a4721d642e") (:authors ("Brian M. Carlson and other contributors")) (:maintainer "Brian M. Carlson and other contributors") (:url . "https://github.com/brianc/jade-mode"))]) (jack-connect . [(20141207 1207) nil "Manage jack connections within Emacs" single ((:commit . "b00658dfe3d5d67431c18ffa693d5a3705067ba0") (:authors ("Stefano Barbi" . "stefanobarbi@gmail.com")) (:maintainer "Stefano Barbi" . "stefanobarbi@gmail.com"))]) (jabber-otr . [(20150918 1144) ((emacs (24)) (jabber (0 8 92))) "Off-The-Record messaging for jabber.el" tar ((:commit . "2692b1530234e0ba9a0d6c1eaa1cbe8679f193c0") (:keywords "comm") (:authors ("Magnus Henoch" . "magnus.henoch@gmail.com")) (:maintainer "Magnus Henoch" . "magnus.henoch@gmail.com") (:url . "https://github.com/legoscia/emacs-jabber-otr/"))]) (jabber . [(20170423 1213) ((fsm (0 2))) "A Jabber client for Emacs." tar ((:commit . "3de7fb40ab9c82ada2a4b5f364a2417345953050"))]) (j-mode . [(20171224 1856) nil "Major mode for editing J programs" tar ((:commit . "e8725ac8af95498faabb2ca3ab3bd809a8f148e6") (:keywords "j" "languages") (:url . "http://github.com/zellio/j-mode"))]) (iy-go-to-char . [(20141029 1546) nil "Go to next CHAR which is similar to \"f\" and \"t\" in vim" single ((:commit . "04ab4f5f3a241cbbc9b8c178a22b412a62f632f9") (:keywords "navigation" "search") (:authors ("Ian Yang <doit dot ian (at) gmail dot com>")) (:maintainer "Ian Yang <doit dot ian (at) gmail dot com>") (:url . "https://github.com/doitian/iy-go-to-char"))]) (ix . [(20131027 1629) ((grapnel (0 5 3))) "Emacs client for http://ix.io pastebin" single ((:commit . "aea4c54a5cc5a6f26637353c16a3a0e70fc76963") (:authors ("Abhishek L" . "abhishekl.2006@gmail.com")) (:maintainer "Abhishek L" . "abhishekl.2006@gmail.com") (:url . "http://www.github.com/theanalyst/ix.el"))]) (ivy-youtube . [(20171112 1532) ((request (0 2 0)) (ivy (0 8 0)) (cl-lib (0 5))) "Query YouTube and play videos in your browser" single ((:commit . "8168dc1f26521830dfd99466d35ab93159afd004") (:keywords "youtube" "multimedia" "mpv" "vlc") (:authors ("Brunno dos Santos")) (:maintainer "Brunno dos Santos") (:url . "https://github.com/squiter/ivy-youtube"))]) (ivy-ycmd . [(20180726 1402) ((ycmd (1 3)) (emacs (24)) (ivy (0 10 0))) "Ivy interface to ycmd" single ((:commit . "02efcdafd3d18ba39b6aade259ba5f80e397b29a") (:keywords "tools") (:authors ("Austin Bingham" . "austin.bingham@gmail.com")) (:maintainer "Austin Bingham" . "austin.bingham@gmail.com") (:url . "https://github.com/abingham/emacs-ivy-ycmd"))]) (ivy-yasnippet . [(20180831 1615) ((emacs (24)) (ivy (0 10 0)) (yasnippet (0 12 2)) (dash (2 14 1)) (cl-lib (0))) "Preview yasnippets with ivy" single ((:commit . "1d4ac765f5376263fa25b595b9cd7dcfb999cc52") (:keywords "convenience") (:authors ("Michał Kondraciuk" . "k.michal@zoho.com")) (:maintainer "Michał Kondraciuk" . "k.michal@zoho.com") (:url . "https://github.com/mkcms/ivy-yasnippet"))]) (ivy-xref . [(20180821 1211) ((emacs (25 1)) (ivy (0 10 0))) "Ivy interface for xref results" single ((:commit . "61864f82e554121be0a26ba0a1d8f48b669dd5f0") (:authors ("Alex Murray" . "murray.alex@gmail.com")) (:maintainer "Alex Murray" . "murray.alex@gmail.com") (:url . "https://github.com/alexmurray/ivy-xref"))]) (ivy-xcdoc . [(20160917 1055) ((ivy (0 8 0)) (emacs (24 4))) "Search Xcode documents with ivy interface." single ((:commit . "5ea22af36c4c2737fb0bec53432c233482d8b314") (:keywords "ivy" "xcode" "xcdoc") (:authors ("C.T.Chen" . "chenct@7adybird.com")) (:maintainer "C.T.Chen" . "chenct@7adybird.com") (:url . "https://github.com/hex2010/emacs-ivy-xcdoc"))]) (ivy-todo . [(20171208 1609) ((ivy (0 8 0)) (emacs (24 3))) "Manage org-mode TODOs with ivy" single ((:commit . "964e347cea1a6097854d7113f5b07f6c5ef81df0") (:keywords "convenience") (:authors ("Erik Sjöstrand" . "sjostrand.erik@gmail.com")) (:maintainer "Erik Sjöstrand" . "sjostrand.erik@gmail.com") (:url . "http://github.com/Kungsgeten/ivy-todo"))]) (ivy-rtags . [(20170523 454) ((ivy (0 7 0)) (rtags (2 10))) "RTags completion back-end for ivy" single ((:commit . "fc63be8f48bed6703b37ccb1057d75d7ce5200ca") (:authors ("Jan Erik Hanssen" . "jhanssen@gmail.com") ("Anders Bakken" . "agbakken@gmail.com")) (:maintainer "Jan Erik Hanssen" . "jhanssen@gmail.com") (:url . "http://rtags.net"))]) (ivy-rich . [(20180827 656) ((emacs (24 4)) (ivy (0 8 0))) "More friendly display transformer for ivy." single ((:commit . "8d7c36d85d153654415c1117b95c58c19f4b3d22") (:keywords "ivy") (:authors ("Yevgnen Koh" . "wherejoystarts@gmail.com")) (:maintainer "Yevgnen Koh" . "wherejoystarts@gmail.com"))]) (ivy-purpose . [(20160724 1003) ((emacs (24)) (ivy (0 8)) (window-purpose (1 5))) "Ivy Interface for Purpose" single ((:commit . "0495f2f3aed64d7e0028125e76a9a68f8fc4107e") (:authors ("Bar Magal (2016)")) (:maintainer "Bar Magal (2016)") (:url . "https://github.com/bmag/ivy-purpose"))]) (ivy-prescient . [(20180824 138) ((emacs (25 1)) (prescient (2 2)) (ivy (0 10 0))) "prescient.el + Ivy" single ((:commit . "1e0db9451e75f0db29668bebe98dfa747c6b4bcf") (:keywords "extensions") (:authors ("Radon Rosborough" . "radon.neon@gmail.com")) (:maintainer "Radon Rosborough" . "radon.neon@gmail.com") (:url . "https://github.com/raxod502/prescient.el"))]) (ivy-posframe . [(20180818 424) ((emacs (26 0)) (posframe (0 1 0)) (ivy (0 10 0))) "Using posframe to show Ivy" single ((:commit . "b92aaa1c4695e2c6012cdbc1469b89e8c0dac4c2") (:keywords "abbrev" "convenience" "matching" "ivy") (:authors ("Feng Shu")) (:maintainer "Feng Shu" . "tumashu@163.com") (:url . "https://github.com/tumashu/ivy-posframe"))]) (ivy-phpunit . [(20180219 915) ((ivy (0 10 0)) (phpunit (0 7 0)) (emacs (25))) "Ivy integration for phpunit.el" single ((:commit . "ffedb0138d36564e8e36a28fd9bc71ea8944681f") (:keywords "convenience" "tools" "ivy" "phpunit" "php") (:authors ("12pt")) (:maintainer "12pt") (:url . "https://github.com/12pt/ivy-phpunit"))]) (ivy-pass . [(20170812 1955) ((emacs (24)) (ivy (0 8 0)) (password-store (1 6 5))) "ivy interface for pass" single ((:commit . "5b523de1151f2109fdd6a8114d0af12eef83d3c5") (:keywords "pass" "password" "convenience" "data") (:authors ("ecraven")) (:maintainer "ecraven") (:url . "https://github.com/ecraven/ivy-pass/"))]) (ivy-pages . [(20160728 1920) ((emacs (24 1)) (ivy (0 8 0))) "Complete current buffer's pages with Ivy" single ((:commit . "47b03a1f9384502cf22369ff31a2898c863d3aff") (:keywords "convenience" "matching") (:authors ("Igor Epstein" . "igorepst@gmail.com")) (:maintainer "Igor Epstein" . "igorepst@gmail.com") (:url . "https://github.com/igorepst/ivy-pages"))]) (ivy-mpdel . [(20180502 1848) ((emacs (25 1)) (ivy (0 10 0)) (libmpdel (0 5 0)) (mpdel (0 4 0))) "Ivy interface to navigate MPD" single ((:commit . "3f7d91cb10416b26a8e465d8c22e0faad4a722a8") (:keywords "multimedia") (:authors ("Damien Cassou" . "damien@cassou.me")) (:maintainer "Damien Cassou" . "damien@cassou.me") (:url . "https://gitlab.petton.fr/mpdel/ivy-mpdel"))]) (ivy-lobsters . [(20171202 2041) ((ivy (0 8 0)) (cl-lib (0 5))) "Browse lobste.rs stories with ivy." single ((:commit . "4364df4b3685fd1b50865ac9360fb948c0288dd1") (:authors ("Julien Blanchard <https://github.com/julienXX>")) (:maintainer "Julien Blanchard <https://github.com/julienXX>") (:url . "https://github.com/julienXX/ivy-lobsters"))]) (ivy-hydra . [(20180614 2200) ((emacs (24 1)) (ivy (0 9 0)) (hydra (0 13 4))) "Additional key bindings for Ivy" single ((:commit . "02537c95baf183b6a42e142a85742d589c692aa2") (:keywords "convenience") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:url . "https://github.com/abo-abo/swiper"))]) (ivy-historian . [(20170716 420) ((emacs (24 4)) (historian (20170111)) (ivy (0 8 0)) (flx (0 6 1))) "Persistently store selected minibuffer candidates" single ((:commit . "6be869f585b854eb849303c452ab4f91dab04fa9") (:keywords "convenience" "ivy") (:authors ("PythonNut" . "pythonnut@pythonnut.com")) (:maintainer "PythonNut" . "pythonnut@pythonnut.com") (:url . "https://github.com/PythonNut/historian.el"))]) (ivy-gitlab . [(20180312 1647) ((s (1 9 0)) (dash (2 9 0)) (ivy (0 8 0)) (gitlab (0 8))) "Ivy interface to Gitlab" single ((:commit . "68318aca3206d50701039c9aae39734ca29a49f9") (:keywords "gitlab" "ivy") (:authors ("Nicolas Lamirault" . "nicolas.lamirault@gmail.com")) (:maintainer "Nicolas Lamirault" . "nicolas.lamirault@gmail.com") (:url . "https://github.com/nlamirault/emacs-gitlab"))]) (ivy-feedwrangler . [(20180618 1522) nil "No description available." single ((:commit . "051eac49cae32b16fab2e06ff0115cd8fb5dc499"))]) (ivy-erlang-complete . [(20180716 444) ((async (1 9)) (counsel (0 8 0)) (ivy (0 8 0)) (erlang (19 2)) (emacs (24 4))) "Erlang context sensitive completion at point using ivy. It also support xref and eldoc." tar ((:commit . "6dad91e4951ed6fd8886bfee587144da18b57049"))]) (ivy-dired-history . [(20170626 556) ((ivy (0 9 0)) (counsel (0 9 0)) (cl-lib (0 5))) "use ivy to open recent directories" single ((:commit . "c9c67ea1ee5e68443f0e6006ba162d6c8d868b69") (:authors ("纪秀峰" . "jixiuf@gmail.com")) (:maintainer "纪秀峰" . "jixiuf@gmail.com") (:url . "https://github.com/jixiuf/ivy-dired-history"))]) (ivy-bibtex . [(20180826 1548) ((swiper (0 7 0)) (parsebib (1 0)) (s (1 9 0)) (dash (2 6 0)) (f (0 16 2)) (cl-lib (0 5)) (biblio (0 2))) "A bibliography manager based on Ivy" tar ((:commit . "b1a4f7d7c0dd3a258ee9f5cdc22b9a7847a2c4c6") (:authors ("Justin Burkett" . "justin@burkett.cc")) (:maintainer "Titus von der Malsburg" . "malsburg@posteo.de"))]) (ivy . [(20180822 1824) ((emacs (24 1))) "Incremental Vertical completYon" tar ((:commit . "02537c95baf183b6a42e142a85742d589c692aa2") (:keywords "matching") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:url . "https://github.com/abo-abo/swiper"))]) (ivs-edit . [(20170818 1441) ((emacs (24 3)) (dash (2 6 0)) (cl-lib (1 0))) "IVS (Ideographic Variation Sequence) editing tool" tar ((:commit . "5db39c234aa7393b591168a4fd0a9a4cbbca347d") (:keywords "text") (:authors ("KAWABATA, Taichi <kawabata.taichi_at_gmail.com>")) (:maintainer "KAWABATA, Taichi <kawabata.taichi_at_gmail.com>") (:url . "http://github.com/kawabata/ivs-edit"))]) (ivariants . [(20170823 224) ((emacs (24 3)) (ivs-edit (1 0))) "Ideographic variants editor and browser" tar ((:commit . "ca0b74d32b5d2d77a45cc6ad6edc00be0ee85284") (:keywords "i18n" "languages") (:authors ("KAWABATA, Taichi <kawabata.taichi_at_gmail.com>")) (:maintainer "KAWABATA, Taichi <kawabata.taichi_at_gmail.com>") (:url . "http://github.com/kawabata/ivariants"))]) (iterator . [(20170207 838) ((emacs (24)) (cl-lib (0 5))) "A library to create and use elisp iterators objects." single ((:commit . "9da54f9aed945b46866782cdf962c9e530419297") (:authors ("Thierry Volpiatto <thierry dot volpiatto at gmail dot com>")) (:maintainer "Thierry Volpiatto <thierry dot volpiatto at gmail dot com>") (:url . "https://github.com/thierryvolpiatto/iterator"))]) (iter2 . [(20180510 1333) ((emacs (25 1))) "Reimplementation of Elisp generators" single ((:commit . "f8fb8dc7230cdcd37c5d0e4e5a432125c13816d2") (:keywords "elisp" "extensions") (:authors ("Paul Pogonyshev" . "pogonyshev@gmail.com")) (:maintainer "Paul Pogonyshev" . "pogonyshev@gmail.com") (:url . "https://github.com/doublep/iter2"))]) (itasca . [(20170601 1622) ((emacs (24 3))) "Major modes for Itasca software data files." tar ((:commit . "3d15dd1b70d6db69b0f4758a3e28b8b506cc84ca") (:keywords "itasca" "flac" "3dec" "udec" "flac3d" "pfc" "pfc2d" "pfc3d" "fish") (:authors ("Jason Furtney" . "jkfurtney@gmail.com")) (:maintainer "Jason Furtney" . "jkfurtney@gmail.com") (:url . "http://github.com/jkfurtney/itasca-emacs/"))]) (itail . [(20171112 804) nil "An interactive tail mode" single ((:commit . "6e43c20da03be3b9c6ece93b7dc3495975ec1888") (:keywords "tail") (:authors ("atom smith")) (:maintainer "atom smith") (:url . "https://github.com/re5et/itail"))]) (iss-mode . [(20141001 1913) nil "Mode for InnoSetup install scripts" single ((:commit . "3b517aff31529bab33f8d7b562bd17aff0107fd1") (:authors ("Stefan Reichoer," . "stefan@xsteve.at")) (:maintainer "Stefan Reichoer," . "stefan@xsteve.at"))]) (isortify . [(20180612 1322) ((emacs (25)) (pythonic (0 1 0))) "(automatically) format python buffers using isort." single ((:commit . "442f12fa91695a43a4b542f7b82d6ac9b004729b") (:authors ("Artem Malyshev" . "proofit404@gmail.com")) (:maintainer "Artem Malyshev" . "proofit404@gmail.com") (:url . "https://github.com/proofit404/isortify"))]) (isolate . [(20180902 1937) ((emacs (25))) "Surrounding tool with flexible customizations." single ((:commit . "ec44bcb44d0332111d76d697deb6699c4ab2a91d") (:keywords "convenience") (:authors ("Yuan Fu" . "casouri@gmail.com")) (:maintainer "Yuan Fu" . "casouri@gmail.com") (:url . "https://github.com/casouri/isolate"))]) (isgd . [(20150414 936) nil "Shorten URLs using the isgd.com shortener service" single ((:commit . "764306dadd5a9213799081a48aba22f7c75cca9a") (:authors ("Chmouel Boudjnah" . "chmouel@chmouel.com")) (:maintainer "Chmouel Boudjnah" . "chmouel@chmouel.com") (:url . "https://github.com/chmouel/isgd.el"))]) (isend-mode . [(20171118 1545) nil "Interactively send parts of an Emacs buffer to an interpreter" single ((:commit . "88d4576e70e5874115c305ab2767d181dfda5985") (:authors ("François Févotte" . "fevotte@gmail.com")) (:maintainer "François Févotte" . "fevotte@gmail.com") (:url . "https://github.com/ffevotte/isend-mode.el"))]) (isearch-symbol-at-point . [(20130728 2221) nil "Use isearch to search for the symbol at point" single ((:commit . "51a1029bec1ec414885f9edb7e5947603dffdab2") (:keywords "isearch") (:authors ("atom smith")) (:maintainer "atom smith") (:url . "https://github.com/re5et/isearch-symbol-at-point"))]) (isearch-dabbrev . [(20141224 622) ((cl-lib (0 5))) "Use dabbrev in isearch" single ((:commit . "1efe7abba4923015cbc2462395deaec5446a9cc8") (:keywords "dabbrev" "isearch") (:authors ("Dewdrops" . "v_v_4474@126.com")) (:maintainer "Dewdrops" . "v_v_4474@126.com") (:url . "https://github.com/Dewdrops/isearch-dabbrev"))]) (irony-eldoc . [(20170502 1908) ((emacs (24)) (cl-lib (0 5)) (irony (0 1))) "irony-mode support for eldoc-mode" single ((:commit . "0df5831eaae264a25422b061eb2792aadde8b3f2") (:keywords "c" "c++" "objc" "convenience" "tools") (:authors ("Kirill Ignatiev <github.com/ikirill>")) (:maintainer "Kirill Ignatiev <github.com/ikirill>") (:url . "https://github.com/ikirill/irony-eldoc"))]) (irony . [(20180703 1740) ((cl-lib (0 5)) (json (1 2))) "C/C++ minor mode powered by libclang" tar ((:commit . "91353a291509f0615fabaedcd92663cd6d94d345") (:keywords "c" "convenience" "tools") (:authors ("Guillaume Papin" . "guillaume.papin@epitech.eu")) (:maintainer "Guillaume Papin" . "guillaume.papin@epitech.eu") (:url . "https://github.com/Sarcasm/irony-mode"))]) (iregister . [(20150515 2107) nil "Interactive register commands for Emacs." tar ((:commit . "6a48c66187289de5f300492be11c83e98410c018") (:keywords "convenience") (:authors ("Andrey Tykhonov" . "atykhonov@gmail.com")) (:maintainer "Andrey Tykhonov" . "atykhonov@gmail.com") (:url . "https://github.com/atykhonov/iregister.el"))]) (ir-black-theme . [(20130303 755) nil "Port of ir-black theme" single ((:commit . "36e930d107604b5763c80294a6f92aaa02e6c272") (:keywords "faces") (:authors ("Jon-Michael Deldin" . "dev@jmdeldin.com")) (:maintainer "Jon-Michael Deldin" . "dev@jmdeldin.com"))]) (iqa . [(20170722 1534) ((emacs (24 3))) "Init file(and directory) Quick Access." single ((:commit . "08e3f70d0a3ed95a0c5675ae88e7966474ecc45a") (:url . "https://github.com/a13/iqa.el"))]) (ipython-shell-send . [(20171212 1118) ((emacs (24))) "Send code (including magics) to ipython shell" single ((:commit . "36523a387c15ee1652a5b0e291d4d4838da5e912") (:keywords "tools" "processes") (:authors ("Jack Kamm" . "jackkamm@gmail.com")) (:maintainer "Jack Kamm" . "jackkamm@gmail.com") (:url . "https://github.com/jackkamm/ipython-shell-send-el"))]) (ipretty . [(20180606 522) nil "Interactive Emacs Lisp pretty-printing" single ((:commit . "042f5cc4e6f81d59115e8335c582bb5c571c2585") (:keywords "pretty-print" "elisp" "buffer") (:authors ("steckerhalter")) (:maintainer "steckerhalter") (:url . "https://framagit.org/steckerhalter/ipretty"))]) (iplayer . [(20161120 2120) nil "Browse and download BBC TV/radio shows" single ((:commit . "b788fffa4b36bbd558047ffa6be51b1f0f462f23") (:keywords "multimedia" "bbc") (:authors ("Christophe Rhodes" . "csr21@cantab.net")) (:maintainer "Christophe Rhodes" . "csr21@cantab.net") (:url . "https://github.com/csrhodes/iplayer-el"))]) (ipcalc . [(20170926 805) ((cl-lib (0 5))) "IP subnet calculator" single ((:commit . "2720f7e3e662e04e195f8338b81a499cf321296a") (:keywords "networking" "tools") (:authors ("\"Aleksandar Simic\"" . "asimic@gmail.com")) (:maintainer "\"Aleksandar Simic\"" . "asimic@gmail.com") (:url . "http://github.com/dotemacs/ipcalc.el"))]) (iodine-theme . [(20151031 1639) ((emacs (24))) "A light emacs color theme" single ((:commit . "02fb780e1d8d8a6b9c709bfac399abe1665c6999") (:keywords "themes") (:authors ("Srđan Panić" . "srdja.panic@gmail.com")) (:maintainer "Srđan Panić" . "srdja.panic@gmail.com") (:url . "https://github.com/srdja/iodine-theme"))]) (ioccur . [(20130822 548) nil "Incremental occur" single ((:commit . "4c0ef992a6fcd2aed62e3866d56650463108ab5a") (:authors ("Thierry Volpiatto <thierry dot volpiatto at gmail dot com>")) (:maintainer "Thierry Volpiatto <thierry dot volpiatto at gmail dot com>") (:url . "https://github.com/thierryvolpiatto/ioccur"))]) (io-mode-inf . [(20140128 1934) nil "Interaction with an Io interpreter." single ((:commit . "6dd2bac3fd87484bb7d97e135b06c29d70b444b6") (:keywords "io" "languages") (:url . "https://github.com/slackorama/io-emacs"))]) (io-mode . [(20161004 756) nil "Major mode to edit Io language files in Emacs" single ((:commit . "fd65ae769093defcf554d6d637eba6e6dfc29f56") (:keywords "languages" "io") (:authors ("Sergei Lebedev" . "superbobry@gmail.com")) (:maintainer "Sergei Lebedev" . "superbobry@gmail.com") (:url . "https://github.com/superbobry/io-mode"))]) (inverse-acme-theme . [(20170823 254) ((autothemer (0 2)) (cl-lib (0 5))) "A theme that looks like an inverse of Acme's color scheme." single ((:commit . "74d6f3e2f6534371509dd2d77006435156c276d6") (:authors ("Dylan Johnson")) (:maintainer "Dylan Johnson") (:url . "http://github.com/djohnson/inverse-acme-theme"))]) (interval-tree . [(20130325 1407) ((dash (1 1 0))) "Interval tree data structure for 1D range queries" single ((:commit . "301302f480617091cf3ab6989caac385d52543dc") (:keywords "extensions" "data structure") (:authors ("Matus Goljer" . "matus.goljer@gmail.com")) (:maintainer "Matus Goljer" . "matus.goljer@gmail.com") (:url . "https://github.com/Fuco1/interval-tree"))]) (interval-list . [(20150327 1718) ((dash (2 4 0)) (cl-lib (0 5)) (emacs (24 4))) "Interval list data structure for 1D selections" single ((:commit . "38af7ecf0a493ad8f487074938a2a115f3531177") (:keywords "extensions" "data structure") (:authors ("Matus Goljer" . "matus.goljer@gmail.com")) (:maintainer "Matus Goljer" . "matus.goljer@gmail.com") (:url . "https://github.com/Fuco1/interval-list"))]) (intero . [(20180806 2145) ((flycheck (0 25)) (company (0 8)) (emacs (24 4)) (haskell-mode (13 0))) "Complete development mode for Haskell" single ((:commit . "0eec1536a0b051d1628895205c273d498385c7a7") (:keywords "haskell" "tools") (:authors ("Chris Done" . "chrisdone@fpcomplete.com")) (:maintainer "Chris Done" . "chrisdone@fpcomplete.com") (:url . "https://github.com/commercialhaskell/intero"))]) (interleave . [(20171004 624) nil "Interleaving text books since 2015" single ((:commit . "87549df30cbc681baf86b238bd14c7cf7ec11fc4") (:authors ("Sebastian Christ" . "rudolfo.christ@gmail.com")) (:maintainer "Sebastian Christ" . "rudolfo.christ@gmail.com") (:url . "https://github.com/rudolfochrist/interleave"))]) (interaction-log . [(20160305 1301) ((cl-lib (0))) "exhaustive log of interactions with Emacs" single ((:commit . "a49a06746d4df6bcfceec3c48dece065d635f9f9") (:keywords "convenience") (:authors ("Michael Heerdegen" . "michael_heerdegen@web.de")) (:maintainer "Michael Heerdegen" . "michael_heerdegen@web.de") (:url . "https://github.com/michael-heerdegen/interaction-log.el"))]) (intellij-theme . [(20171017 1415) nil "Inspired by IntelliJ's default theme" single ((:commit . "1bbfff8e6742d18e9b77ed796f44da3b7bd10606") (:keywords "faces") (:authors ("Vladimir Polushin" . "vovapolu@gmail.com")) (:maintainer "Vladimir Polushin" . "vovapolu@gmail.com"))]) (intel-hex-mode . [(20180423 31) nil "Mode for Intel Hex files." single ((:commit . "e83c94e1c31a8435a88b3ae395f2bc842ef83217") (:keywords "tools" "hex") (:maintainer "Michael Schuldt" . "mbschuldt@gmail.com") (:url . "https://github.com/mschuldt/intel-hex-mode"))]) (instapaper . [(20130104 1421) nil "add URLs to instapaper from emacs" single ((:authors ("Jason F. McBrayer" . "jmcbray@carcosa.net")) (:maintainer "Jason F. McBrayer" . "jmcbray@carcosa.net") (:url . "htts://bitbucket.org/jfm/emacs-instapaper"))]) (insfactor . [(20141117 2) nil "Client for a Clojure project with insfactor in it" single ((:commit . "7ef5446cebb08a17d4106d2e6f3c053e49e1e829") (:keywords "clojure") (:authors ("John D. Hume" . "duelin.markers@gmail.com")) (:maintainer "John D. Hume" . "duelin.markers@gmail.com") (:url . "http://github.com/duelinmarkers/insfactor.el"))]) (insert-shebang . [(20180403 1214) nil "Insert shebang line automatically." single ((:commit . "7bfea92ba1dae9d13d442e2f84f9fb6c05a0a9bd") (:keywords "shebang" "tool" "convenience") (:authors ("Sachin Patil" . "iclcoolster@gmail.com")) (:maintainer "Sachin Patil" . "iclcoolster@gmail.com") (:url . "http://github.com/psachin/insert-shebang"))]) (inlineR . [(20120520 1432) nil "insert Tag for inline image of R graphics" single ((:commit . "29357186beca825e3d0451b700ec09b9ed65e37b") (:keywords "convenience" "iimage.el" "cacoo.el") (:authors ("myuhe <yuhei.maeda_at_gmail.com>")) (:maintainer "myuhe") (:url . "https://github.com/myuhe/inlineR.el"))]) (inline-docs . [(20170523 450) ((emacs (24 3))) "Show inline contextual docs." single ((:commit . "b57f1681be6147f999cdc12abff414a0442e8897") (:keywords "inline" "docs" "overlay") (:authors ("stardiviner" . "numbchild@gmail.com")) (:maintainer "stardiviner" . "numbchild@gmail.com") (:url . "https://github.com/stardiviner/inline-docs.el"))]) (inline-crypt . [(20170824 900) nil "Simple inline encryption via openssl" tar ((:commit . "281385b383f850fd2e895926b1cef804dd052633"))]) (inkpot-theme . [(20171217 944) nil "port of vim's inkpot theme" single ((:commit . "e423aed885bf9b1de10c87891faec45b978113fa") (:keywords "color" "theme") (:authors ("Sarah Iovan" . "sarah@hwaetageek.com") ("Campbell Barton" . "ideasman42@gmail.com")) (:maintainer "Sarah Iovan" . "sarah@hwaetageek.com") (:url . "https://github.com/ideasman42/emacs-inkpot-theme"))]) (ink-mode . [(20160814 1116) ((emacs (24 3))) "Major mode for writing interactive fiction in Ink" single ((:commit . "e35f26abbaf8ea23c5aa0a0c7ef15334cdfb7b48") (:keywords "languages") (:authors ("Erik Sjöstrand")) (:maintainer "Erik Sjöstrand") (:url . "http://github.com/Kungsgeten/ink-mode"))]) (initsplit . [(20160919 1818) nil "code to split customizations into different files" single ((:commit . "c941d436eb2b10b01c76a582c5a2b23fb30751aa") (:keywords "lisp") (:authors ("John Wiegley <johnw@gnu.org>, Dave Abrahams" . "dave@boostpro.com")) (:maintainer "John Wiegley <johnw@gnu.org>, Dave Abrahams" . "dave@boostpro.com") (:url . "http://www.gci-net.com/users/j/johnw/emacs.html"))]) (init-open-recentf . [(20161206 1445) ((emacs (24 4))) "Open recentf immediately after Emacs is started" single ((:commit . "7d8fb124806291f7f6ef2ec3a664ea25899b6d68") (:keywords "files" "recentf" "after-init-hook") (:authors ("USAMI Kenta" . "tadsan@zonu.me")) (:maintainer "USAMI Kenta" . "tadsan@zonu.me") (:url . "https://github.com/zonuexe/init-open-recentf.el"))]) (init-loader . [(20160528 1315) nil "Loader for configuration files" single ((:commit . "5d3cea1004c11ff96b33020e337b03b925c67c42") (:authors ("IMAKADO" . "ken.imakado@gmail.com")) (:maintainer "IMAKADO" . "ken.imakado@gmail.com") (:url . "https://github.com/emacs-jp/init-loader/"))]) (ini-mode . [(20170424 909) nil "Major mode for Windows-style ini files." single ((:commit . "2194cfa2fd13196a37350ec20b3f00dcf6162b7c") (:keywords "languages" "faces") (:authors ("Anders Lindgren")) (:maintainer "Anders Lindgren") (:url . "https://github.com/Lindydancer/ini-mode"))]) (inherit-local . [(20170409 1649) ((emacs (24 3))) "Inherited buffer-local variables" single ((:commit . "b1f4ff9c41f9d64e4adaf5adcc280b82f084cdc7") (:authors ("Shea Levy")) (:maintainer "Shea Levy") (:url . "https://github.com/shlevy/inherit-local/tree-master/"))]) (info-colors . [(20180205 1150) ((emacs (24)) (cl-lib (0 5))) "Extra colors for Info-mode" single ((:commit . "a8ebb7b8efa314c08ea8110d8b1876afb562bb45") (:keywords "faces") (:authors ("Tuấn-Anh Nguyễn" . "ubolonton@gmail.com")) (:maintainer "Tuấn-Anh Nguyễn" . "ubolonton@gmail.com") (:url . "https://github.com/ubolonton/info-colors"))]) (info-buffer . [(20170112 1422) nil "Display info topics in separate buffers" single ((:commit . "d35dad6e766c6e2ddb8dc6acb4ce5b6e10fbcaa7") (:keywords "docs" "info") (:authors ("Lluís Vilanova" . "vilanova@ac.upc.edu")) (:maintainer "Lluís Vilanova" . "vilanova@ac.upc.edu") (:url . "http://www.github.com/llvilanova/info-buffer"))]) (info-beamer . [(20180604 2122) ((emacs (24 4))) "Utilities for working with info-beamer" single ((:commit . "af443795af20481af91ac54a489b20f6a9d90b0a") (:keywords "tools" "processes" "comm") (:authors ("Daniel Kraus" . "daniel@kraus.my")) (:maintainer "Daniel Kraus" . "daniel@kraus.my") (:url . "https://github.com/dakra/info-beamer.el"))]) (inflections . [(20170913 916) ((cl-lib (0 5)) (emacs (24))) "convert english words between singular and plural" single ((:commit . "e4f1372cf22e811faca52fc86bdd5d817498a4d8") (:keywords "languages" "tools" "wp") (:authors ("Dmitry Galinsky, Howard Yeh")) (:maintainer "Dmitry Galinsky, Howard Yeh") (:url . "https://github.com/eschulte/jump.el"))]) (inferior-spim . [(20160826 1346) nil "inferior mode for spim." single ((:commit . "fb9aa091f6058bf320793f1a608c1ed7322c1f47") (:keywords "spim" "inferior" "mips") (:authors ("hiddenlotus" . "kaihaosw@gmail.com")) (:maintainer "hiddenlotus" . "kaihaosw@gmail.com"))]) (inf-ruby . [(20180521 1348) nil "Run a Ruby process in a buffer" single ((:commit . "49d59a7897f594e3be74ecbddae83719f9a6c0f0") (:keywords "languages" "ruby") (:authors ("Yukihiro Matsumoto") ("Nobuyoshi Nakada") ("Cornelius Mika" . "cornelius.mika@gmail.com") ("Dmitry Gutov" . "dgutov@yandex.ru") ("Kyle Hargraves" . "pd@krh.me")) (:maintainer "Yukihiro Matsumoto") (:url . "http://github.com/nonsequitur/inf-ruby"))]) (inf-mongo . [(20180408 1338) nil "Run a MongoDB shell process in a buffer" single ((:commit . "2e498d1c88bd1904eeec18ed06b1a0cf8bdc2a92") (:keywords "databases" "mongodb") (:authors ("Tobias Svensson")) (:maintainer "Tobias Svensson") (:url . "http://github.com/endofunky/inf-mongo"))]) (inf-crystal . [(20180119 211) ((emacs (24 3)) (crystal-mode (0 1 0))) "Run a Inferior-Crystal process in a buffer" single ((:commit . "02007b2a2a3bea44902d7c83c4acba1e39d278e3") (:keywords "languages" "crystal") (:authors ("Brantou" . "brantou89@gmail.com")) (:maintainer "Brantou" . "brantou89@gmail.com") (:url . "https://github.com/brantou/inf-crystal.el"))]) (inf-clojure . [(20180402 2103) ((emacs (24 4)) (clojure-mode (5 6))) "Run an external Clojure process in an Emacs buffer" single ((:commit . "59868ff0433f7631c362ce25879bd4271d350ebc") (:keywords "processes" "clojure") (:url . "http://github.com/clojure-emacs/inf-clojure"))]) (indy . [(20150610 1706) nil "A minor mode and EDSL to manage your mode's indentation rules." single ((:commit . "4604867d8111f0e186a5351e68e054a77cb14abf") (:keywords "convenience" "matching" "tools") (:authors ("Kevin W. van Rooijen" . "kevin.van.rooijen@attichacker.com")) (:maintainer "Kevin W. van Rooijen" . "kevin.van.rooijen@attichacker.com"))]) (indium . [(20180821 853) ((emacs (25)) (seq (2 16)) (js2-mode (20140114)) (js2-refactor (0 9 0)) (company (0 9 0))) "JavaScript Awesome Development Environment" tar ((:commit . "eee4db88ab190cfbf4ccfb8b0c2691eee9033944") (:keywords "tools" "javascript") (:authors ("Nicolas Petton" . "nicolas@petton.fr")) (:maintainer "Nicolas Petton" . "nicolas@petton.fr") (:url . "https://github.com/NicolasPetton/indium"))]) (indicators . [(20161211 1126) ((dash (2 13 0)) (cl-lib (0 5 0))) "Display the buffer relative location of line in the fringe." single ((:commit . "f62a1201f21453e3aca93f48483e65ae8251432e") (:keywords "fringe" "frames") (:authors ("Matus Goljer" . "matus.goljer@gmail.com")) (:maintainer "Matus Goljer" . "matus.goljer@gmail.com") (:url . "https://github.com/Fuco1/indicators.el"))]) (indent-tools . [(20180124 1208) ((s (0)) (hydra (0)) (yafolding (0))) "Indent, navigate (and more) by blocks of indentation: yaml, python etc." tar ((:commit . "b650b2ca82ccd9ccb4f3142afa0da4737ddd364f") (:keywords "indentation" "movements" "navigation" "kill" "fold" "yaml" "python") (:authors ("vindarel" . "ehvince@mailz.org")) (:maintainer "vindarel" . "ehvince@mailz.org") (:url . "https://gitlab.com/emacs-stuff/indent-tools/"))]) (indent-info . [(20180423 1912) nil "show indentation information in status bar" single ((:commit . "d218b4cb3726476caee91db6f6c920856ab992bc") (:keywords "convenience" "tools") (:authors ("Terje Larsen" . "terlar@gmail.com")) (:maintainer "Terje Larsen" . "terlar@gmail.com") (:url . "https://github.com/terlar/indent-info.el"))]) (indent-guide . [(20170221 1127) nil "show vertical lines to guide indentation" single ((:commit . "d64f43011c72068e008621e620009ec592b35913") (:authors ("zk_phi")) (:maintainer "zk_phi") (:url . "http://hins11.yu-yake.com/"))]) (importmagic . [(20180520 303) ((f (0 11 0)) (epc (0 1 0)) (emacs (24 3))) "Fix Python imports using importmagic." tar ((:commit . "e32ee9f6a5eef937b76eba82fdae8bae85d18088") (:keywords "languages" "convenience") (:authors ("Nicolás Salas V." . "nikosalas@gmail.com")) (:maintainer "Nicolás Salas V." . "nikosalas@gmail.com") (:url . "https://github.com/anachronic/importmagic.el"))]) (import-popwin . [(20170218 1407) ((emacs (24 3)) (popwin (0 6))) "popwin buffer near by import statements with popwin" single ((:commit . "bb05a9e226f8c63fe7b18a3e92010357049ab5ba") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-import-popwin"))]) (import-js . [(20180709 1833) ((grizzl (0 1 0)) (emacs (24))) "Import Javascript dependencies" single ((:commit . "fb1f167e33c388b09a2afd32fbda90a67bfb2e40") (:keywords "javascript") (:authors ("Kevin Kehl" . "kevin.kehl@gmail.com")) (:maintainer "Kevin Kehl" . "kevin.kehl@gmail.com") (:url . "http://github.com/Galooshi/emacs-import-js/"))]) (impatient-mode . [(20180828 1425) ((cl-lib (0 3)) (simple-httpd (1 4 0)) (htmlize (1 40))) "Serve buffers live over HTTP" tar ((:commit . "6632c20dc317d196ffec823125d280c37697d541") (:authors ("Brian Taylor" . "el.wubo@gmail.com")) (:maintainer "Brian Taylor" . "el.wubo@gmail.com") (:url . "https://github.com/netguy204/imp.el"))]) (immutant-server . [(20140311 2208) nil "Run your Immutant server in Emacs" single ((:commit . "2a21e65588acb6a976f2998e30b21fdabdba4dbb") (:authors ("David Leatherman" . "leathekd@gmail.com")) (:maintainer "David Leatherman" . "leathekd@gmail.com") (:url . "http://www.github.com/leathekd/immutant-server.el"))]) (immortal-scratch . [(20160517 2118) nil "respawn the scratch buffer when it's killed" single ((:authors ("Jonathan Kotta" . "jpkotta@gmail.com")) (:maintainer "Jonathan Kotta" . "jpkotta@gmail.com"))]) (imgbb . [(20180609 1649) ((emacs (24)) (request (0 3 0))) "Simple image upload client for imgbb.com" single ((:commit . "a524a46263835aa474f908827ebab4e8fa586001") (:keywords "extensions") (:authors ("Peter" . "craven@gmx.net")) (:maintainer "Peter" . "craven@gmx.net") (:url . "https://github.com/ecraven/imgbb.el"))]) (imenus . [(20180505 1717) ((cl-lib (0 5))) "Imenu for multiple buffers and without subgroups" single ((:commit . "149cfa579ee231014d3341a0e05add69759757a5") (:keywords "tools" "convenience") (:authors ("Alex Kost" . "alezost@gmail.com")) (:maintainer "Alex Kost" . "alezost@gmail.com") (:url . "https://github.com/alezost/imenus.el"))]) (imenu-list . [(20180601 1402) ((cl-lib (0 5))) "Show imenu entries in a separate buffer" single ((:commit . "04f0632f7b8c81be8747617768c57b66e5d60994") (:authors ("Bar Magal (2015)")) (:maintainer "Bar Magal (2015)") (:url . "https://github.com/bmag/imenu-list"))]) (imenu-anywhere . [(20170805 1855) ((cl-lib (0 5))) "ido/ivy/helm imenu across same mode/project/etc buffers" single ((:commit . "fc7f0fd2f19e5ebee70156a99bf87393123893e3") (:keywords "ido" "imenu" "tags") (:authors ("Vitalie Spinu  <spinuvit.list[ aaattt ]gmail[ dot ]com>")) (:maintainer "Vitalie Spinu  <spinuvit.list[ aaattt ]gmail[ dot ]com>") (:url . "https://github.com/vitoshka/imenu-anywhere"))]) (imapfilter . [(20180318 2027) nil "run the imapfilter executable" single ((:commit . "79bbbe918319bc1e8f42a0bef53dc7c77fe868ea") (:keywords "mail") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:url . "https://github.com/tarsius/imapfilter"))]) (imake . [(20180318 2259) ((emacs (24 3))) "Simple, opinionated make target runner" single ((:commit . "7df5fb9684a0288313ef5f64594078d477105959") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:url . "https://github.com/tarsius/imake"))]) (imakado . [(20141024 923) nil "imakado's usefull macros and functions" single ((:commit . "00a1e7eea2cb9e9066343a23927d6c747707902f") (:keywords "convenience") (:authors ("imakado <ken.imakado_at_gmail.com>")) (:maintainer "imakado") (:url . "https://github.com/imakado/emacs-imakado"))]) (image-dired+ . [(20150430 544) ((cl-lib (0 3))) "Image-dired extensions" single ((:commit . "b68094625d963056ad64e0e44af0e2266b2eadc7") (:keywords "extensions" "multimedia") (:authors ("Masahiro Hayashi" . "mhayashi1120@gmail.com")) (:maintainer "Masahiro Hayashi" . "mhayashi1120@gmail.com") (:url . "https://github.com/mhayashi1120/Emacs-image-diredx"))]) (image-archive . [(20150621 132) ((emacs (24)) (cl-lib (0 5))) "Image thumbnails in archive file with non-blocking" single ((:commit . "8d29535bd832329ffeeac780aae7aa8919af1175") (:keywords "multimedia") (:authors ("Masahiro Hayashi" . "mhayashi1120@gmail.com")) (:maintainer "Masahiro Hayashi" . "mhayashi1120@gmail.com") (:url . "https://github.com/mhayashi1120/Emacs-image-archive"))]) (image+ . [(20150707 1616) ((cl-lib (0 3))) "Image manipulate extensions for Emacs" single ((:commit . "6834d0c09bb4df9ecc0d7a559bd7827fed48fffc") (:keywords "multimedia" "extensions") (:authors ("Masahiro Hayashi" . "mhayashi1120@gmail.com")) (:maintainer "Masahiro Hayashi" . "mhayashi1120@gmail.com") (:url . "https://github.com/mhayashi1120/Emacs-imagex"))]) (igv . [(20141210 1227) nil "Control Integrative Genomic Viewer within Emacs" single ((:commit . "47ac6ceede252f451348a2c696398c0cb5279555") (:authors ("Stefano Barbi" . "stefanobarbi@gmail.com")) (:maintainer "Stefano Barbi" . "stefanobarbi@gmail.com"))]) (ignoramus . [(20160414 1409) nil "Ignore backups, build files, et al." single ((:commit . "b37dc7c07edd9d152436f9019c14df158b599be3") (:keywords "convenience" "tools") (:authors ("Roland Walker" . "walker@pobox.com")) (:maintainer "Roland Walker" . "walker@pobox.com") (:url . "http://github.com/rolandwalker/ignoramus"))]) (iflipb . [(20171113 2044) nil "interactively flip between recently visited buffers" single ((:commit . "a5ad1fbd1173cff5228dab265515c92c0778f86a") (:authors ("Joel Rosdahl" . "joel@rosdahl.net")) (:maintainer "Joel Rosdahl" . "joel@rosdahl.net") (:url . "https://github.com/jrosdahl/iflipb"))]) (ietf-docs . [(20150928 957) nil "Fetch, Cache and Load IETF documents" single ((:commit . "ede30d6d26044069e1731fd20c0ab2324552c0b4") (:keywords "ietf" "rfc") (:authors ("Christian E. Hopps" . "chopps@gmail.com")) (:maintainer "Christian E. Hopps" . "chopps@gmail.com") (:url . "https://github.com/choppsv1/ietf-docs"))]) (iedit . [(20180830 531) nil "Edit multiple regions in the same way simultaneously." tar ((:commit . "825f1f30f7410827cc60cca7a30d149c2431833a") (:keywords "occurrence" "region" "simultaneous" "refactoring") (:authors ("Victor Ren" . "victorhge@gmail.com")) (:maintainer "Victor Ren" . "victorhge@gmail.com") (:url . "http://www.emacswiki.org/emacs/Iedit"))]) (ids-edit . [(20170818 1502) ((emacs (24 3))) "IDS (Ideographic Description Sequence) editing tool" tar ((:commit . "8562a6cbfb3f2d44bc6f62ab15081a80f8fee502") (:keywords "i18n" "wp") (:authors ("KAWABATA, Taichi <kawabata.taichi_at_gmail.com>")) (:maintainer "KAWABATA, Taichi <kawabata.taichi_at_gmail.com>") (:url . "http://github.com/kawabata/ids-edit"))]) (idris-mode . [(20180417 545) ((emacs (24)) (prop-menu (0 1)) (cl-lib (0 5))) "Major mode for editing Idris code" tar ((:commit . "2cd2ace9327248e141c35127b8ef9114a1301a1d") (:keywords "languages") (:url . "https://github.com/idris-hackers/idris-mode"))]) (idomenu . [(20141123 2120) nil "imenu tag selection a la ido" single ((:commit . "4b0152d606360c70204fb4c27f68de79ca885386") (:authors ("Georg Brandl" . "georg@python.org")) (:maintainer "Georg Brandl" . "georg@python.org"))]) (ido-yes-or-no . [(20161108 2351) ((ido-completing-read+ (0))) "Use Ido to answer yes-or-no questions" single ((:commit . "c55383b1fce5879e87e7ca6809fc60534508e182") (:keywords "convenience" "completion" "ido") (:authors ("Ryan C. Thompson")) (:maintainer "Ryan C. Thompson") (:url . "https://github.com/DarwinAwardWinner/ido-yes-or-no"))]) (ido-vertical-mode . [(20180618 2101) nil "Makes ido-mode display vertically." single ((:commit . "16c4c1a112796ee0bcf401ea39d3e2643a89feaf") (:keywords "convenience") (:authors ("Steven Degutis")) (:maintainer "Christopher Reichert" . "creichert07@gmail.com") (:url . "https://github.com/creichert/ido-vertical-mode.el"))]) (ido-springboard . [(20170106 755) nil "Temporarily change default-directory for one command" single ((:commit . "263a8cd4582c81bfc29d7db37d5267e2488b148c") (:keywords "ido") (:authors ("John Wiegley" . "jwiegley@gmail.com")) (:maintainer "John Wiegley" . "jwiegley@gmail.com") (:url . "https://github.com/jwiegley/springboard"))]) (ido-sort-mtime . [(20171121 859) nil "Sort Ido's file list by modification time" single ((:commit . "f638ff0c922af862f5211779f2311a27fde428eb") (:keywords "convenience" "files") (:authors ("Paweł Kraśnicki")) (:maintainer "Paweł Kraśnicki"))]) (ido-skk . [(20151111 950) ((emacs (24 4)) (ddskk (20150912 1820))) "ido interface for skk henkan" single ((:commit . "89a2e62799bff2841ff634517c86084c4ce69246") (:keywords "languages") (:authors ("tsukimizake <shomasd_at_gmail.com>")) (:maintainer "tsukimizake <shomasd_at_gmail.com>") (:url . "https://github.com/tsukimizake/ido-skk"))]) (ido-select-window . [(20131220 2047) ((emacs (24 1))) "Select a window using ido and buffer names" single ((:commit . "a64707d8d154664d50d12e26417d586e4c3dd78b") (:authors ("Peter Jones" . "pjones@devalot.com")) (:maintainer "Peter Jones" . "pjones@devalot.com") (:url . "https://github.com/pjones/ido-select-window"))]) (ido-occur . [(20160820 1440) ((dash (2 13 0))) "Yet another `occur' with `ido'." single ((:commit . "522af5d55b3d4cd6885f3b4100913566c202cec4") (:keywords "inner" "buffer" "search") (:authors ("Danil" . "danil@kutkevich.org")) (:maintainer "Danil" . "danil@kutkevich.org") (:url . "https://github.com/danil/ido-occur"))]) (ido-occasional . [(20150214 1248) ((emacs (24 1))) "Use ido where you choose." single ((:commit . "d405f1795e1e0c63be411ee2825184738d29c33a") (:keywords "completion") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:url . "https://github.com/abo-abo/ido-occasional"))]) (ido-migemo . [(20150921 2244) ((migemo (1 9 1))) "Migemo plug-in for Ido" single ((:commit . "e71114a92dd69cb46abf3fb71a09ce27506fcf77") (:keywords "files") (:authors ("myuhe <yuhei.maeda_at_gmail.com>")) (:maintainer "myuhe") (:url . "https://github.com/myuhe/ido-migemo.el"))]) (ido-load-library . [(20140611 1600) ((persistent-soft (0 8 8)) (pcache (0 2 3))) "Load-library alternative using ido-completing-read" single ((:commit . "e03b55957c93aa1a7dd190e173e16ec59dbb2ba7") (:keywords "maint" "completion") (:authors ("Roland Walker" . "walker@pobox.com")) (:maintainer "Roland Walker" . "walker@pobox.com") (:url . "http://github.com/rolandwalker/ido-load-library"))]) (ido-hacks . [(20150331 1909) nil "Put more IDO in your IDO" single ((:commit . "b7e7514a0e011e4d767d1f5755c5eae9d85f83dc") (:keywords "convenience") (:authors ("Andreas Politz")) (:maintainer "Scott Jaderholm" . "jaderholm@gmail.com"))]) (ido-grid-mode . [(20160122 1139) ((emacs (24 4))) "Display ido-prospects in the minibuffer in a grid." single ((:commit . "7cfca3988a6dc3ad18e28abe114218095ff2366f") (:keywords "convenience") (:authors ("Tom Hinton")) (:maintainer "Tom Hinton" . "t@larkery.com") (:url . "https://github.com/larkery/ido-grid-mode.el"))]) (ido-gnus . [(20140216 1646) ((gnus (5 13))) "Access gnus groups or servers using ido" single ((:commit . "f5fe3f6aa8086f675ba216abace9e3d5f2e3a089") (:keywords "comm") (:authors ("Joe Bloggs" . "vapniks@yahoo.com")) (:maintainer "Joe Bloggs" . "vapniks@yahoo.com") (:url . "https://github.com/vapniks/ido-gnus"))]) (ido-flex-with-migemo . [(20180323 1156) ((flx-ido (0 6 1)) (migemo (1 9 1)) (emacs (24 4))) "use ido with flex and migemo" single ((:commit . "9684ffc47d838e82d611d0955b390d8387cf5741") (:keywords "matching") (:authors ("ROCKTAKEY " . "rocktakey@gmail.com")) (:maintainer "ROCKTAKEY " . "rocktakey@gmail.com") (:url . "https://github.com/ROCKTAKEY/ido-flex-with-migemo"))]) (ido-exit-target . [(20170717 1851) ((emacs (24 4))) "Commands and keys for selecting other window and frame targets within ido" single ((:commit . "e56fc6928649c87ccf39d56d84ab53ebaced1f73") (:keywords "convenience" "tools" "extensions") (:authors ("justin talbott" . "justin@waymondo.com")) (:maintainer "justin talbott" . "justin@waymondo.com") (:url . "https://github.com/waymondo/ido-exit-target"))]) (ido-describe-bindings . [(20161023 1102) ((dash (2 13 0))) "Yet another `describe-bindings' with `ido'." single ((:commit . "a142ff1c33df23ed9665497d0dcae2943b3c706a") (:keywords "help") (:authors ("Danil <danil@kutkevich.org>, Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Danil <danil@kutkevich.org>, Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/danil/ido-describe-bindings"))]) (ido-completing-read+ . [(20180628 244) ((emacs (24 4)) (cl-lib (0 5)) (s (0 1)) (memoize (1 1))) "A completing-read-function using ido" single ((:commit . "51d9d4e667aaf2833e94614e5eeffdbbcab4ee98") (:keywords "ido" "completion" "convenience") (:authors ("Ryan Thompson")) (:maintainer "Ryan Thompson") (:url . "https://github.com/DarwinAwardWinner/ido-completing-read-plus"))]) (ido-complete-space-or-hyphen . [(20130228 1008) nil "Complete SPACE or HYPHEN when type SPACE in ido" single ((:commit . "3fe1fe1e1a743f8deb8f4025977647afecd58f14") (:keywords "ido" "completion") (:authors ("Ian Yang <me (at) iany.me>")) (:maintainer "Ian Yang <me (at) iany.me>") (:url . "https://github.com/doitian/ido-complete-space-or-hyphen"))]) (ido-clever-match . [(20151011 1726) ((emacs (24 4)) (cl-lib (0 5))) "Alternative matcher for ido." single ((:commit . "f173473e99c8b0756f12e4cc8f67e68fa59eadd3") (:keywords "ido" "flex") (:authors ("Bogdan Paul Popa" . "popa.bogdanp@gmail.com")) (:maintainer "Bogdan Paul Popa" . "popa.bogdanp@gmail.com") (:url . "https://github.com/Bogdanp/ido-clever-match"))]) (ido-at-point . [(20151021 757) ((emacs (24))) "ido-style completion-at-point" single ((:commit . "e5907bbe8a3d148d07698b76bd994dc3076e16ee") (:keywords "convenience" "abbrev") (:authors ("katspaugh")) (:maintainer "katspaugh") (:url . "https://github.com/katspaugh/ido-at-point"))]) (idle-require . [(20090715 2203) nil "load elisp libraries while Emacs is idle" single ((:commit . "33592bb098223b4432d7a35a1d65ab83f47c1ec1") (:keywords "internal") (:authors ("Nikolaj Schumacher <bugs * nschum de>")) (:maintainer "Nikolaj Schumacher <bugs * nschum de>") (:url . "http://nschum.de/src/emacs/idle-require/"))]) (idle-highlight-mode . [(20120920 1648) nil "highlight the word the point is on" single ((:commit . "c466f2a9e291f9da1167dc879577b2e1a7880482") (:keywords "convenience") (:authors ("Phil Hagelberg, Cornelius Mika")) (:maintainer "Phil Hagelberg, Cornelius Mika") (:url . "http://www.emacswiki.org/cgi-bin/wiki/IdleHighlight"))]) (idle-highlight-in-visible-buffers-mode . [(20180811 631) nil "highlight the word the point is on" single ((:commit . "09bb527ff9b8e5ad3da15aa461d595f187b91172") (:keywords "convenience") (:authors ("Ignacy Moryc")) (:maintainer "Ignacy Moryc") (:url . "https://github.com/ignacy/idle-highlight-in-visible-buffers"))]) (identica-mode . [(20130204 2253) nil "Major mode API client for status.net open microblogging" tar ((:commit . "cf9183ee11ac922e85c7c908f04e2d00b03111b3") (:keywords "identica" "web") (:authors ("Gabriel Saldana" . "gsaldana@gmail.com")) (:maintainer "Gabriel Saldana" . "gsaldana@gmail.com") (:url . "http://blog.gabrielsaldana.org/identica-mode-for-emacs/"))]) (idea-darkula-theme . [(20160416 2303) ((emacs (24 1))) "Color theme based on IntelliJ IDEA Darkula color theme" single ((:commit . "52602d9b91883e1f297d000951aeed48bf60176e") (:keywords "themes") (:authors ("Alexey Veretennikov <alexey dot veretennikov at gmail dot com>")) (:maintainer "Alexey Veretennikov <alexey dot veretennikov at gmail dot com>") (:url . "http://github.com/fourier/idea-darkula-theme"))]) (id-manager . [(20170320 1246) nil "id-password management" single ((:commit . "14ebc35db298aac4dedc8aa188bc46bacab81f3b") (:keywords "password" "convenience") (:authors ("SAKURAI Masashi <m.sakurai atmark kiwanami.net>")) (:maintainer "SAKURAI Masashi <m.sakurai atmark kiwanami.net>"))]) (ibuffer-vc . [(20171107 741) ((cl-lib (0 2))) "Group ibuffer's list by VC project, or show VC status" single ((:commit . "83d60aefd21e2aa20c7217d224f38a40bb75e63b") (:keywords "themes") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:url . "http://github.com/purcell/ibuffer-vc"))]) (ibuffer-tramp . [(20151118 1739) nil "Group ibuffer's list by TRAMP connection" single ((:commit . "bcad0bda3a67f55d1be936bf8fa9ef735fe1e3f3") (:keywords "convenience") (:authors ("Svend Sorensen" . "svend@ciffer.net")) (:maintainer "Svend Sorensen" . "svend@ciffer.net") (:url . "http://github.com/svend/ibuffer-tramp"))]) (ibuffer-sidebar . [(20180219 131) ((emacs (25 1))) "Sidebar for `ibuffer'" single ((:commit . "7ddf1b5a158b33e9a7d3fe5dad7ea626a464d2bc") (:keywords "ibuffer" "files" "tools") (:authors ("James Nguyen" . "james@jojojames.com")) (:maintainer "James Nguyen" . "james@jojojames.com") (:url . "https://github.com/jojojames/ibuffer-sidebar"))]) (ibuffer-rcirc . [(20150215 2118) ((cl-lib (0 2))) "Ibuffer integration for rcirc" single ((:commit . "8a4409b1c679d65c819dee4085faf929840e79f8") (:keywords "buffer" "convenience" "comm") (:authors ("Fabián Ezequiel Gallina" . "fgallina@gnu.org")) (:maintainer "Fabián Ezequiel Gallina" . "fgallina@gnu.org") (:url . "https://github.com/fgallina/ibuffer-rcirc"))]) (ibuffer-projectile . [(20180325 325) ((projectile (0 11 0))) "Group ibuffer's list by projectile root" single ((:commit . "1e89bfa7cae0629d29f24af3d81774b88b3cede0") (:keywords "themes") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:url . "http://github.com/purcell/ibuffer-projectile"))]) (ibuffer-git . [(20110508 731) nil "show git status in ibuffer column" single ((:commit . "d326319c05ddb8280885b31f9094040c1b365876") (:keywords "convenience") (:authors ("Jonathan Rockway" . "jon@jrock.us")) (:maintainer "Jonathan Rockway" . "jon@jrock.us"))]) (iasm-mode . [(20171023 1422) nil "interactive assembly major mode." single ((:commit . "abbec7f308f9ce97beeb57e459fff35f559b4c18") (:keywords ":" "tools") (:authors ("Rémi Attab" . "remi.attab@gmail.com")) (:maintainer "Rémi Attab" . "remi.attab@gmail.com") (:url . "https://github.com/RAttab/iasm-mode"))]) (ialign . [(20180705 1153) ((emacs (24 4))) "visual align-regexp" single ((:commit . "e92664e673647826161a19e9cfc327fa8c69ba6e") (:keywords "tools" "editing" "align" "interactive") (:authors ("Michał Kondraciuk" . "k.michal@zoho.com")) (:maintainer "Michał Kondraciuk" . "k.michal@zoho.com") (:url . "https://github.com/mkcms/interactive-align"))]) (i3wm . [(20170822 1438) nil "i3wm integration library" single ((:commit . "71391dc61063fee77ad174f3b2ca25c60b41009e") (:keywords "convenience" "extensions") (:authors ("Samuel W. Flint" . "swflint@flintfam.org")) (:maintainer "Samuel W. Flint" . "swflint@flintfam.org") (:url . "https://git.flintfam.org/swf-projects/emacs-i3"))]) (i2b2-mode . [(20140710 104) nil "Highlights corresponding PHI data in the text portion of an i2b2 XML Document." single ((:commit . "db10efcfc8bed369a516bbf7526ede41f98cb95a") (:keywords "xml" "phi" "i2b2" "deidi2b2") (:authors ("Dan LaManna" . "dan.lamanna@gmail.com")) (:maintainer "Dan LaManna" . "dan.lamanna@gmail.com"))]) (hydra . [(20180703 1502) ((cl-lib (0 5))) "Make bindings that stick around." tar ((:commit . "44b42598eed5077d8945ef44c38d80b59510b865") (:keywords "bindings") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:url . "https://github.com/abo-abo/hydra"))]) (hyde . [(20160508 308) nil "Major mode to help create and manage Jekyll blogs" tar ((:commit . "a8cd6ed00ecd8d7de0ded2f4867015b412b15b76"))]) (hydandata-light-theme . [(20160816 418) nil "A light color theme that is easy on your eyes" single ((:commit . "0fbc91678ef65e1f65d7ec6792ff0b2f104d16a9") (:keywords "color-theme" "theme") (:authors ("David Chkhikvadze" . "david.chk@outlook.com")) (:maintainer "David Chkhikvadze" . "david.chk@outlook.com"))]) (hyai . [(20170301 1447) ((cl-lib (0 5)) (emacs (24))) "Haskell Yet Another Indentation" single ((:commit . "e1cd115c19225bbe0e1183d9a8c289eadaeb37b6") (:authors ("Iku Iwasa" . "iku.iwasa@gmail.com")) (:maintainer "Iku Iwasa" . "iku.iwasa@gmail.com") (:url . "https://github.com/iquiw/hyai"))]) (hy-mode . [(20180702 1940) ((dash (2 13 0)) (dash-functional (1 2 0)) (s (1 11 0)) (emacs (24))) "Major mode for Hylang" single ((:commit . "71a12a9208c4b87859bcbb6978e7915dd518e8dd") (:keywords "languages" "lisp" "python") (:url . "http://github.com/hylang/hy-mode"))]) (hungry-delete . [(20170412 102) nil "hungry delete minor mode" single ((:commit . "0434458d3f6b2b585f332271feaa054bf4ec96d7") (:authors ("Nathaniel Flath" . "flat0103@gmail.com")) (:maintainer "Nathaniel Flath" . "flat0103@gmail.com") (:url . "http://github.com/nflath/hungry-delete"))]) (hungarian-holidays . [(20161020 1138) nil "Adds a list of Hungarian public holidays to Emacs calendar" single ((:commit . "653108769279499d84a79267c90e640d98823872") (:keywords "calendar") (:authors ("Gergely Polonkai" . "gergely@polonkai.eu")) (:maintainer "Gergely Polonkai" . "gergely@polonkai.eu"))]) (hugsql-ghosts . [(20180425 1129) ((s (1 9 0)) (dash (2 10 0)) (cider (0 14 0))) "Display hugsql defqueries in clojure code as an overlay." single ((:commit . "f3ebc60c66204ad39058cb84eb4bd5facce091df") (:authors ("Roland Kaercher" . "roland.kaercher@gmail.com")) (:maintainer "Roland Kaercher" . "roland.kaercher@gmail.com") (:url . "https://github.com/rkaercher/hugsql-ghosts"))]) (httprepl . [(20141101 1734) ((s (1 9 0)) (dash (2 5 0)) (emacs (24))) "An HTTP REPL" single ((:commit . "cfa3693267a8ed1c96a86a126823f37dbfe077d8") (:keywords "http" "repl") (:authors ("Greg Sexton" . "gregsexton@gmail.com")) (:maintainer "Greg Sexton" . "gregsexton@gmail.com") (:url . "https://github.com/gregsexton/httprepl.el"))]) (httpcode . [(20121002 345) nil "explains the meaning of an HTTP status code" single ((:commit . "a45e735082b09477cd704a99294d336cdbeb12ba") (:authors ("Ruslan Spivak" . "ruslan.spivak@gmail.com")) (:maintainer "Ruslan Spivak" . "ruslan.spivak@gmail.com") (:url . "http://github.com/rspivak/httpcode.el"))]) (http-twiddle . [(20160801 1911) nil "send & twiddle & resend HTTP requests" single ((:commit . "4d0c73b7dcbde8b483d4f3a75c49c74d2fe3ca45") (:keywords "http" "rest" "soap") (:authors ("Luke Gorrie" . "luke@synap.se")) (:maintainer "Hasan Veldstra" . "h@vidiowiki.com") (:url . "https://github.com/hassy/http-twiddle/blob/master/http-twiddle.el"))]) (http-post-simple . [(20170715 940) nil "HTTP POST requests using the url library" single ((:commit . "f53697fca278c741051aeb668b00466b5e0fd3fe") (:keywords "comm" "data" "processes" "hypermedia") (:authors ("Tom Schutzer-Weissmann")) (:maintainer "Tom Schutzer-Weissmann"))]) (http . [(20170906 1811) ((emacs (24 4)) (request (0 2 0)) (edit-indirect (0 1 4))) "Yet another HTTP client" single ((:commit . "193a7bf843dd6b6805c7b18dab31f50c8325d710") (:keywords "convenience") (:authors ("Mario Rodas" . "marsam@users.noreply.github.com")) (:maintainer "Mario Rodas" . "marsam@users.noreply.github.com") (:url . "https://github.com/emacs-pe/http.el"))]) (htmlize . [(20180412 1944) nil "Convert buffer text and decorations to HTML." single ((:commit . "315a8f23cfd3e87642ff9e30ae3300c7a84244d5") (:keywords "hypermedia" "extensions") (:authors ("Hrvoje Niksic" . "hniksic@gmail.com")) (:maintainer "Hrvoje Niksic" . "hniksic@gmail.com"))]) (html2org . [(20170418 501) ((emacs (24 4))) "Convert html to org format text" single ((:commit . "6904aed40259ad8afccff079ebd8a07bff319ebc") (:keywords "convenience" "html" "org") (:authors ("DarkSun" . "lujun9972@gmail.com")) (:maintainer "DarkSun" . "lujun9972@gmail.com") (:url . "http://github.com/lujun9972/html2org.el"))]) (html-to-markdown . [(20151105 840) ((cl-lib (0 5))) "HTML to Markdown converter written in Emacs-lisp." single ((:commit . "60c5498c801be186478cf7c05be05b4430c4a144") (:keywords "tools" "wp" "languages") (:authors ("Artur Malabarba" . "bruce.connor.am@gmail.com")) (:maintainer "Artur Malabarba" . "bruce.connor.am@gmail.com") (:url . "http://github.com/Bruce-Connor/html-to-markdown"))]) (html-to-hiccup . [(20161028 1401) ((emacs (25 1)) (dash (2 13 0)) (s (1 10 0))) "Convert HTML to Hiccup syntax" single ((:commit . "99217a5058626d253ed8ada51a7642071fe54ba5") (:keywords "html" "hiccup" "clojure") (:authors ("Arne Brasseur" . "arne@arnebrasseur.net")) (:maintainer "Arne Brasseur" . "arne@arnebrasseur.net") (:url . "https://github.com/plexus/html-to-hiccup"))]) (html-script-src . [(20120403 1815) nil "Insert <script src=\"..\"> for popular JavaScript libraries" single ((:commit . "66460f8ab1b24656e6f3ce5bd50cff6a81be8422") (:keywords "tools" "convenience") (:authors ("Johan Andersson" . "johan.rejeep@gmail.com")) (:maintainer "Johan Andersson" . "johan.rejeep@gmail.com") (:url . "http://github.com/rejeep/html-script-src"))]) (html-check-frag . [(20160131 535) ((emacs (24 3))) "Check html-fragments" single ((:commit . "feb89765eafd69dfcf07afeebded8985dc456e7c") (:keywords "html") (:authors ("Tobias.Zawada" . "i@tn-home.de")) (:maintainer "Tobias.Zawada" . "i@tn-home.de"))]) (ht . [(20180129 2234) ((dash (2 12 0))) "The missing hash table library for Emacs" single ((:commit . "5a665d00dc8fda77bad2a43277d8809c23e46ab8") (:keywords "hash table" "hash map" "hash") (:authors ("Wilfred Hughes" . "me@wilfred.me.uk")) (:maintainer "Wilfred Hughes" . "me@wilfred.me.uk"))]) (howm . [(20180225 1005) ((cl-lib (0 5))) "Wiki-like note-taking tool" tar ((:commit . "b932fa603f074049637907d35594f73c3fba45d0") (:authors ("HIRAOKA Kazuyuki" . "khi@users.osdn.me")) (:maintainer "HIRAOKA Kazuyuki" . "khi@users.osdn.me") (:url . "https://howm.osdn.jp"))]) (howdoi . [(20150204 43) nil "Instant coding answers via Emacs." tar ((:commit . "5fbf7069ee160c597a328e5ce5fb32920e1ca88f"))]) (how-many-lines-in-project . [(20140807 442) nil "Calculate how many lines are there in your project." single ((:commit . "8a37ef885d004fe2ce231bfe05ed4867c6192d9b") (:keywords "project" "convenience") (:authors ("Wei Zhao" . "kaihaosw@gmail.com")) (:maintainer "Wei Zhao" . "kaihaosw@gmail.com"))]) (hound . [(20170627 1959) ((request (0 2 0)) (cl-lib (0 5))) "Display hound search results in a compilation window" single ((:commit . "0c5a250ef82870dca737a429b6e9b9db93874ed3") (:authors ("Ryan Young")) (:maintainer "Ryan Young"))]) (horoscope . [(20180409 641) ((emacs (24))) "generate horoscopes." single ((:commit . "f4c683e991adce0a8f9023f15050f306f9b9a9ed") (:keywords "extensions" "games") (:authors ("Bob Manson" . "manson@cygnus.com")) (:maintainer "Noah Friedman" . "friedman@prep.ai.mit.edu") (:url . "https://github.com/mschuldt/horoscope.el"))]) (hookify . [(20141216 2209) ((s (1 9 0)) (dash (1 5 0))) "Interactive commands to create temporary hooks" single ((:commit . "21baae7393b07257de5796402fde0ca72fb00d77") (:keywords "hook" "convenience") (:authors ("Philippe Vaucher" . "philippe.vaucher@gmail.com")) (:maintainer "Philippe Vaucher" . "philippe.vaucher@gmail.com") (:url . "https://github.com/Silex/hookify"))]) (honcho . [(20180707 24) ((emacs (25 1)) (sudo-edit (0 1))) "Run and manage long-running services" single ((:commit . "f6a89a27e255b3ecb1f0b13058933558b1f0c6fb") (:keywords "convenience") (:authors ("Mario Rodas" . "marsam@users.noreply.github.com")) (:maintainer "Mario Rodas" . "marsam@users.noreply.github.com") (:url . "https://github.com/emacs-pe/honcho.el"))]) (homebrew-mode . [(20160615 1320) ((emacs (24 4)) (inf-ruby (2 4 0)) (dash (1 2 0))) "minor mode for editing Homebrew formulae" single ((:commit . "d422307aee2f897d1a92e3b959c3214bc54cbe38") (:keywords "homebrew" "brew" "ruby") (:authors ("Alex Dunn" . "dunn.alex@gmail.com")) (:maintainer "Alex Dunn" . "dunn.alex@gmail.com") (:url . "https://github.com/dunn/homebrew-mode"))]) (home-end . [(20180817 855) ((emacs (24 3)) (keypress-multi-event (1 0))) "Smart multi-purpose home / end keys" single ((:commit . "91491564e9dd3fb111ca0012a9760f723343453d") (:keywords "abbrev" "convenience" "wp" "keyboard") (:authors ("Boruch Baum" . "boruch_baum@gmx.com")) (:maintainer "Boruch Baum" . "boruch_baum@gmx.com") (:url . "https://www.github.com/Boruch_Baum/emacs-home-end"))]) (holiday-pascha-etc . [(20160822 58) nil "Eastern Christian analog to holiday-easter-etc" single ((:commit . "eb198656f63cb8679fb0e3a8248782df071a0f3c") (:authors ("Mark A. Hershberger" . "mah@everybody.org")) (:maintainer "Mark A. Hershberger" . "mah@everybody.org") (:url . "http://github.com/hexmode/holiday-pascha-etc"))]) (hoa-pp-mode . [(20151027 736) ((emacs (24 1)) (names (20150723 0))) "Major mode for Hoa PP grammars" single ((:commit . "925b79930a3f4377b0fb2a36b3c6d5566d4b9a8e") (:keywords "php" "hoa") (:authors ("Steven Rémot")) (:maintainer "Steven Rémot") (:url . "https://github.com/hoaproject/Contributions-Emacs-Pp"))]) (hoa-mode . [(20151203 1650) nil "Major mode for the Hanoi Omega Automata format" single ((:commit . "3c608e15b655d2375c5f81323ac561c7848dc029") (:keywords "major-mode" "automata" "convenience") (:authors ("Alexandre Duret-Lutz" . "adl@lrde.epita.fr")) (:maintainer "Alexandre Duret-Lutz" . "adl@lrde.epita.fr") (:url . "https://gitlab.lrde.epita.fr/spot/emacs-modes"))]) (hmac . [(20180429 2010) ((cl-lib (0 5)) (emacs (25))) "hash-based message authentication code" single ((:commit . "30132cd3fee7d3d91a9f04709d49ca0dcb96d565") (:authors ("Sean McAfee")) (:maintainer "Sean McAfee") (:url . "https://github.com/grimnebulin/emacs-hmac"))]) (hlinum . [(20180422 412) ((cl-lib (0 2))) "Extension for linum.el to highlight current line number" single ((:commit . "f17360fe93de6df99a05b4b64b0a1ca4ee45abb6") (:keywords "convenience" "extensions") (:authors ("Tomoya Tanjo" . "ttanjo@gmail.com")) (:maintainer "Tomoya Tanjo" . "ttanjo@gmail.com") (:url . "https://github.com/tom-tan/hlinum-mode/"))]) (hlint-refactor . [(20170818 448) nil "Apply HLint suggestions" single ((:commit . "92c69aa01c65968e86c15db087bb1ea785e4736c") (:keywords "haskell" "refactor") (:url . "https://github.com/mpickering/hlint-refactor-mode"))]) (hledger-mode . [(20180821 1433) ((emacs (24 4)) (popup (0 5 3)) (async (1 9)) (htmlize (1 47))) "A mode for writing journal entries for hledger." tar ((:commit . "af51c0a7a0952c244e5c6bb818ab4ce3b9806609") (:keywords "data") (:authors ("Narendra Joshi" . "narendraj9@gmail.com")) (:maintainer "Narendra Joshi" . "narendraj9@gmail.com") (:url . "https://github.com/narendraj9/hledger-mode.git"))]) (hl-todo . [(20180710 455) nil "highlight TODO and similar keywords" single ((:commit . "3401f322d954e635372995bf5cc77dae171a78ba") (:keywords "convenience") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:url . "https://github.com/tarsius/hl-todo"))]) (hl-sentence . [(20171018 1519) nil "highlight a sentence based on customizable face" single ((:commit . "86ae38d3103bd20da5485cbdd59dfbd396c45ee4") (:keywords "highlighting") (:authors ("Donald Ephraim Curtis" . "dcurtis@milkbox.net")) (:maintainer "Donald Ephraim Curtis" . "dcurtis@milkbox.net") (:url . "http://github.com/milkypostman/hl-sentence"))]) (hl-indent . [(20170429 2104) ((emacs (24)) (cl-lib (0 5))) "Highlight irregular indentation." single ((:commit . "bdb2e0177a7c8b29af26998e688b856adc6ded93") (:keywords "convenience" "faces") (:authors ("Kirill Ignatiev <github.com/ikirill>")) (:maintainer "Kirill Ignatiev <github.com/ikirill>") (:url . "https://github.com/ikirill/hl-indent"))]) (hl-anything . [(20160422 1708) ((emacs (24 3))) "Highlight symbols, selections, enclosing parens and more." tar ((:commit . "8696bc55a8cba408f0fc83a907a9ec529d79e558") (:authors ("boyw165")) (:maintainer "boyw165"))]) (hiwin . [(20150825 827) nil "Visible active window mode." single ((:commit . "6ee8ed051405653bd9b7332d7e9fbb591d954051") (:keywords "faces" "editing" "emulating") (:authors ("k.sugita")) (:maintainer "k.sugita"))]) (hive . [(20131217 1512) ((sql (3 0))) "Hive SQL mode extension" single ((:commit . "11b5172e081ad8079fc78758bef6f306f82ae32b") (:keywords "sql" "hive") (:authors ("Roman Scherer" . "roman@burningswell.com")) (:maintainer "Roman Scherer" . "roman@burningswell.com"))]) (historyf . [(20151124 159) nil "file history library like browser" single ((:commit . "196c058ceb092fdd56b0e4ce85b7e714d6f72224") (:authors ("k1LoW (Kenichirou Oyama), <k1lowxb [at] gmail [dot] com> <k1low [at] 101000lab [dot] org>")) (:maintainer "k1LoW (Kenichirou Oyama), <k1lowxb [at] gmail [dot] com> <k1low [at] 101000lab [dot] org>") (:url . "https://github.com/k1LoW/emacs-historyf"))]) (history . [(20160821 1602) ((emacs (24 3))) "History utility for source code navigation" tar ((:commit . "5317663fb45bbd5e96d258cb0807dcc266ce67ff") (:authors ("boyw165")) (:maintainer "boyw165") (:url . "https://github.com/boyw165/history"))]) (historian . [(20180619 1923) ((emacs (24 4))) "Persistently store selected minibuffer candidates" single ((:commit . "6be869f585b854eb849303c452ab4f91dab04fa9") (:keywords "convenience") (:authors ("PythonNut" . "pythonnut@pythonnut.com")) (:maintainer "PythonNut" . "pythonnut@pythonnut.com") (:url . "https://github.com/PythonNut/historian.el"))]) (hippie-namespace . [(20140508 2041) nil "Special treatment for namespace prefixes in hippie-expand" single ((:commit . "d0d0f15c67ab8bef5e9d1e29a89ecd3613a60b49") (:keywords "convenience" "lisp" "tools" "completion") (:authors ("Roland Walker" . "walker@pobox.com")) (:maintainer "Roland Walker" . "walker@pobox.com") (:url . "http://github.com/rolandwalker/hippie-namespace"))]) (hippie-expand-slime . [(20170723 146) nil "Hook slime's completion into hippie-expand" single ((:commit . "39bbae94896a62854d31754debdfae71d35fec62") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:url . "https://github.com/purcell/hippie-expand-slime"))]) (hippie-exp-ext . [(20160502 2326) nil "Extension of hippie-expand" single ((:commit . "4eda13f90da51ab217d024701f4c30f91ffcb90e") (:keywords "abbrev" "convenience" "completions" "hippie-expand") (:authors ("rubikitch" . "rubikitch@ruby-lang.org")) (:maintainer "rubikitch" . "rubikitch@ruby-lang.org") (:url . "http://www.emacswiki.org/emacs/download/hippie-exp-ext.el"))]) (hindent . [(20180518 902) ((cl-lib (0 5))) "Indent haskell code using the \"hindent\" program" single ((:commit . "dbe766053e1d0aad87599454831bb79331ce1325") (:authors ("Chris Done" . "chrisdone@gmail.com")) (:maintainer "Chris Done" . "chrisdone@gmail.com") (:url . "https://github.com/chrisdone/hindent"))]) (himp . [(20170814 1915) ((emacs (24 3)) (vimish-fold (0 1 0))) "Automatically hide imports/documentation" single ((:commit . "140234b7f7cde03cf858c5011a2ab63e3bc802ec") (:keywords "convenience" "tools") (:authors ("Michał Kondraciuk" . "k.michal@zoho.com")) (:maintainer "Michał Kondraciuk" . "k.michal@zoho.com") (:url . "http://github.com/mkcms/himp/"))]) (highlight2clipboard . [(20151020 1840) ((htmlize (1 47))) "Copy text to clipboard with highlighting." tar ((:commit . "6ce58a060d9c5843ccb8c79ec2bba7858c68ac15") (:keywords "tools") (:authors ("Anders Lindgren")) (:maintainer "Anders Lindgren"))]) (highlight-unique-symbol . [(20130612 542) ((deferred (0 3 2))) "highlight symbols which not appear in the repository" single ((:commit . "4141bf86a94e30d94d9af9c29d40b16886226e1c") (:authors ("hitode909" . "hitode909@gmail.com")) (:maintainer "hitode909" . "hitode909@gmail.com") (:url . "https://github.com/hitode909/emacs-highlight-unique-symbol"))]) (highlight-thing . [(20170919 1404) nil "Minimalistic minor mode to highlight current thing under point." single ((:commit . "4eadd178175772fb04ae50e1199d797a6375ad4d") (:keywords "highlight" "thing" "symbol") (:authors ("Felix Geller" . "fgeller@gmail.com")) (:maintainer "Felix Geller" . "fgeller@gmail.com") (:url . "https://github.com/fgeller/highlight-thing.el"))]) (highlight-symbol . [(20160102 2009) nil "automatic and manual symbol highlighting" single ((:commit . "7a789c779648c55b16e43278e51be5898c121b3a") (:keywords "faces" "matching") (:authors ("Nikolaj Schumacher <bugs * nschum de>")) (:maintainer "Nikolaj Schumacher <bugs * nschum de>") (:url . "http://nschum.de/src/emacs/highlight-symbol/"))]) (highlight-stages . [(20161212 1457) nil "highlight staged (quasi-quoted) expressions" single ((:commit . "29cbc5b78261916da042ddb107420083da49b271") (:authors ("zk_phi")) (:maintainer "zk_phi") (:url . "http://hins11.yu-yake.com/"))]) (highlight-refontification . [(20170211 2024) nil "Visualize font-lock refontification." single ((:commit . "32632897d88c4611fadb08517ca00ef5cbc989b6") (:keywords "faces" "tools") (:authors ("Anders Lindgren")) (:maintainer "Anders Lindgren") (:url . "https://github.com/Lindydancer/highlight-refontification"))]) (highlight-quoted . [(20140916 1822) ((emacs (24))) "Highlight Lisp quotes and quoted symbols" single ((:commit . "24103478158cd19fbcfb4339a3f1fa1f054f1469") (:authors ("Fanael Linithien" . "fanael4@gmail.com")) (:maintainer "Fanael Linithien" . "fanael4@gmail.com") (:url . "https://github.com/Fanael/highlight-quoted"))]) (highlight-parentheses . [(20180704 1102) nil "highlight surrounding parentheses" single ((:commit . "f0bd58c8dadd2db703b7bfd09e911b5fda05b3df") (:keywords "faces" "matching") (:authors ("Nikolaj Schumacher <bugs * nschum de>")) (:maintainer "Tassilo Horn" . "tsdh@gnu.org") (:url . "https://github.com/tsdh/highlight-parentheses.el"))]) (highlight-operators . [(20170213 2220) nil "a face for operators in programming modes" single ((:authors ("Jonathan Kotta" . "jpkotta@gmail.com")) (:maintainer "Jonathan Kotta" . "jpkotta@gmail.com"))]) (highlight-numbers . [(20170905 1042) ((emacs (24)) (parent-mode (2 0))) "Highlight numbers in source code" single ((:commit . "f952ecb7448c125d4ef82ee6ad136b25e640d74a") (:authors ("Fanael Linithien" . "fanael4@gmail.com")) (:maintainer "Fanael Linithien" . "fanael4@gmail.com") (:url . "https://github.com/Fanael/highlight-numbers"))]) (highlight-leading-spaces . [(20151216 1222) ((emacs (24 4))) "Highlight leading spaces" single ((:commit . "840db19d863dd97993fd9f893f5be501627b6354") (:authors ("Thomas Winant" . "dewinant@gmail.com")) (:maintainer "Thomas Winant" . "dewinant@gmail.com") (:url . "https://github.com/mrBliss/highlight-leading-spaces"))]) (highlight-indentation . [(20171218 937) nil "Minor modes for highlighting indentation" single ((:commit . "35e2c1d4f8f368685893128f77f90454cb9c2708") (:authors ("Anton Johansson" . "anton.johansson@gmail.com")) (:maintainer "Anton Johansson" . "anton.johansson@gmail.com") (:url . "https://github.com/antonj/Highlight-Indentation-for-Emacs"))]) (highlight-indent-guides . [(20180529 1739) ((emacs (24))) "Minor mode to highlight indentation" single ((:commit . "895181ec53a07dfef2b7183d8477454ca2606d0e") (:authors ("DarthFennec" . "darthfennec@derpymail.org")) (:maintainer "DarthFennec" . "darthfennec@derpymail.org") (:url . "https://github.com/DarthFennec/highlight-indent-guides"))]) (highlight-function-calls . [(20170908 500) ((emacs (24 4))) "Highlight function/macro calls" single ((:commit . "f7a1eaf95fc64cc0db4d0567f9ff79ec4ae04787") (:keywords "faces" "highlighting") (:authors ("Adam Porter" . "adam@alphapapa.net")) (:maintainer "Adam Porter" . "adam@alphapapa.net") (:url . "http://github.com/alphapapa/highlight-function-calls"))]) (highlight-escape-sequences . [(20171117 1237) nil "Highlight escape sequences" single ((:commit . "08d846a7aa748209d65fecead2b6a766c3e5cb41") (:keywords "convenience") (:authors ("Dmitry Gutov" . "dgutov@yandex.ru") ("Pavel Matcula" . "dev.plvlml@gmail.com")) (:maintainer "Dmitry Gutov" . "dgutov@yandex.ru") (:url . "https://github.com/dgutov/highlight-escape-sequences"))]) (highlight-doxygen . [(20180829 1818) nil "Highlight Doxygen comments" single ((:commit . "53f2250018725fa19548e1771ee79fcc23641694") (:keywords "faces") (:authors ("Anders Lindgren")) (:maintainer "Anders Lindgren") (:url . "https://github.com/Lindydancer/highlight-doxygen"))]) (highlight-defined . [(20141225 1530) ((emacs (24))) "Syntax highlighting of known Elisp symbols" single ((:commit . "243478cc204ab42d29805ed610961cbb260c1dfd") (:authors ("Fanael Linithien" . "fanael4@gmail.com")) (:maintainer "Fanael Linithien" . "fanael4@gmail.com") (:url . "https://github.com/Fanael/highlight-defined"))]) (highlight-context-line . [(20170319 2142) nil "Improve orientation when scrolling" single ((:commit . "716e10a0c7b703b5f1d9c6ca1481524a4d06b7b8") (:keywords "faces" "services" "user") (:authors ("Stefan Kamphausen <www.skamphausen.de>")) (:maintainer "Stefan Kamphausen <www.skamphausen.de>") (:url . "https://github.com/ska2342/highlight-context-line/"))]) (highlight-blocks . [(20151201 1615) ((emacs (24))) "Highlight the blocks point is in" single ((:commit . "9c4240a5d16008db430d1a81c76dad474d3deb0c") (:authors ("Fanael Linithien" . "fanael4@gmail.com")) (:maintainer "Fanael Linithien" . "fanael4@gmail.com") (:url . "https://github.com/Fanael/highlight-blocks"))]) (highlight . [(20180605 635) nil "Highlighting commands." single ((:commit . "6f92253690dde26d9bfd21546fdf68ef2fdd486b") (:keywords "faces" "help" "local") (:authors ("Drew Adams")) (:maintainer nil . "Drew Adams (concat \"drew.adams\" \"@\" \"oracle\" \".com\")") (:url . "https://www.emacswiki.org/emacs/download/highlight.el"))]) (hierarchy . [(20171221 1151) ((emacs (25 1))) "Library to create and display hierarchy structures" single ((:commit . "06f21d3fc16c44c1fa45dc9c91d10100b4db9355") (:authors ("Damien Cassou" . "damien@cassou.me")) (:maintainer "Damien Cassou" . "damien@cassou.me") (:url . "https://github.com/DamienCassou/hierarchy"))]) (hideshow-org . [(20120223 2250) nil "Provides org-mode like hide and show for hideshow.el" single ((:commit . "16419e52e6cdd2f46f755144c0ab11ce00d1a626") (:keywords "c" "c++" "java" "lisp" "tools" "editing" "comments" "blocks" "hiding" "outlines" "org-mode") (:authors ("Shane Celis <shane (at) gnufoo (dot) org>")) (:maintainer "Shane Celis <shane (at) gnufoo (dot) org>"))]) (hide-mode-line . [(20180302 1910) ((emacs (24 4))) "minor mode that hides/masks your modeline" single ((:commit . "86b9057391edad75467261c2e579603567e608f9") (:keywords "frames" "mode-line") (:authors ("Henrik Lissner <http://github/hlissner>")) (:maintainer "Henrik Lissner" . "henrik@lissner.net") (:url . "https://github.com/hlissner/emacs-hide-mode-line"))]) (hide-lines . [(20151127 1840) nil "Commands for hiding lines based on a regexp" single ((:commit . "331122bf19361130351cfe55968c2a7820329eb3") (:keywords "convenience") (:authors ("Mark Hulme-Jones <ture at plig cucumber dot net>")) (:maintainer "Joe Bloggs" . "vapniks@yahoo.com") (:url . "https://github.com/vapniks/hide-lines"))]) (hi2 . [(20141005 1931) nil "indentation module for Haskell Mode" single ((:commit . "c9d199727b5cdcb9e36a972b38131ce4611fd6c8") (:keywords "indentation" "haskell") (:authors ("Gergely Risko" . "gergely@risko.hu")) (:maintainer "Gergely Risko" . "gergely@risko.hu") (:url . "https://github.com/errge/hi2"))]) (hgrc-mode . [(20150409 2043) nil "major mode for editing hgrc files" single ((:commit . "314e8320b82cc1ce74b1bd372f296252e7a23090") (:keywords "convenience" "vc" "hg") (:authors ("Omair Majid" . "omair.majid@gmail.com")) (:maintainer "Omair Majid" . "omair.majid@gmail.com") (:url . "http://github.com/omajid/hgrc-mode"))]) (hgignore-mode . [(20160501 7) nil "a major mode for editing hgignore files" single ((:commit . "7aa9f3b8a9c610dbd80b952061b40194e1d9c5bd") (:keywords "convenience" "vc" "hg") (:authors ("Omair Majid" . "omair.majid@gmail.com")) (:maintainer "Omair Majid" . "omair.majid@gmail.com") (:url . "http://github.com/omajid/hgignore-mode"))]) (hfst-mode . [(20160708 1202) nil "major mode for editing HFST files" single ((:commit . "ac1bb9dd92545d3e7fdc05c83996c227cc15c6b8") (:keywords "languages") (:authors ("Kevin Brubeck Unhammer" . "unhammer@fsfe.org")) (:maintainer "Kevin Brubeck Unhammer" . "unhammer@fsfe.org") (:url . "http://wiki.apertium.org/wiki/Emacs"))]) (hexo . [(20180815 219) ((emacs (24 3))) "Major mode & tools for Hexo" single ((:commit . "6bca18f911f6b2cd5c055ed73ddec98c385f9f86") (:keywords "tools" "hexo") (:authors ("Ono Hiroko (kuanyui)" . "azazabc123@gmail.com")) (:maintainer "Ono Hiroko (kuanyui)" . "azazabc123@gmail.com") (:url . "https://github.com/kuanyui/hexo.el"))]) (heroku-theme . [(20150523 219) nil "Heroku color theme" single ((:commit . "8083643fe92ec3a1c3eb82f1b8dc2236c9c9691d") (:authors ("Jonathan Chu" . "me@jonathanchu.is")) (:maintainer "Jonathan Chu" . "me@jonathanchu.is") (:url . "https://github.com/jonathanchu/color-theme-heroku"))]) (heroku . [(20120629 1813) nil "Interface to Heroku apps." single ((:commit . "92af1c073b593c4def99c8777c869992aa4d0b3a") (:keywords "convenience" "api" "database") (:authors ("Phil Hagelberg" . "technomancy@gmail.com")) (:maintainer "Phil Hagelberg" . "technomancy@gmail.com") (:url . "https://github.com/technomancy/heroku.el"))]) (hemisu-theme . [(20130508 1844) nil "Hemisu for Emacs." tar ((:commit . "5c206561aa2c844ecdf3e3b672c3235e559ddd7f") (:authors ("Andrzej Sliwa")) (:maintainer "Andrzej Sliwa") (:url . "http://github/anrzejsliwa/django-theme"))]) (hemera-theme . [(20170910 1303) ((emacs (24))) "Light theme" single ((:commit . "354ae3b788c11ac08e6e2fe7c86adc621e2b16fd") (:keywords "themes" "light-theme") (:authors ("Guido Schmidt")) (:maintainer "Guido Schmidt" . "guido.schmidt.2912@gmail.com") (:url . "https://github.com/GuidoSchmidt/emacs-hemera-theme"))]) (helpful . [(20180816 2217) ((emacs (25 1)) (dash (2 12 0)) (dash-functional (1 2 0)) (s (1 11 0)) (f (0 20 0)) (elisp-refs (1 2)) (shut-up (0 3))) "a better *help* buffer" single ((:commit . "6274c100b50c977ed7310d0f99eba26951b51f13") (:keywords "help" "lisp") (:authors ("Wilfred Hughes" . "me@wilfred.me.uk")) (:maintainer "Wilfred Hughes" . "me@wilfred.me.uk") (:url . "https://github.com/Wilfred/helpful"))]) (helm-zhihu-daily . [(20160625 1145) ((helm (1 0)) (cl-lib (0 5)) (emacs (24 4))) "Helm interface for 知乎日报 (http://daily.zhihu.com)" single ((:commit . "be27dcc6be1eb97663b65581a9a5c0fc81cfaba7") (:authors ("Chunyang Xu" . "xuchunyang56@gmail.com")) (:maintainer "Chunyang Xu" . "xuchunyang56@gmail.com") (:url . "https://github.com/xuchunyang/helm-zhihu-daily"))]) (helm-z . [(20171204 325) ((helm (1 0))) "Show z directory list with helm.el support." single ((:commit . "37212220bebea8b9c238cb1bbacd8332b7f26c03") (:authors ("yynozk" . "yynozk@gmail.com")) (:maintainer "yynozk" . "yynozk@gmail.com") (:url . "https://github.com/yynozk/helm-z"))]) (helm-youtube . [(20161114 248) ((request (0 2 0)) (helm (2 3 1)) (cl-lib (0 5))) "Query YouTube and play videos in your browser" single ((:commit . "202c27fc3b54927611e9d9c764465e1b42ef7e41") (:keywords "youtube" "multimedia") (:authors ("Maximilian Roquemore" . "maximus12793@gmail.com")) (:maintainer "Maximilian Roquemore" . "maximus12793@gmail.com") (:url . "https://github.com/maximus12793/helm-youtube"))]) (helm-xref . [(20180528 1516) ((emacs (25 1)) (helm (1 9 4))) "Helm interface for xref results" single ((:commit . "6f7e8eeec5cc4db64a76ba242c0f2f61e7ee1e46") (:authors ("Fritz Stelzer" . "brotzeitmacher@gmail.com")) (:maintainer "Fritz Stelzer" . "brotzeitmacher@gmail.com") (:url . "https://github.com/brotzeitmacher/helm-xref"))]) (helm-xcdoc . [(20160116 1018) ((helm (1 5)) (emacs (24 4))) "Search Xcode Document by docsetutil and eww with helm interface" single ((:commit . "a85612149a6d8e18ab309b3db2d222ce39c42049") (:authors ("Ryo Fujimoto" . "fujimisakri@gmail.com")) (:maintainer "Ryo Fujimoto" . "fujimisakri@gmail.com") (:url . "https://github.com/fujimisakari/emacs-helm-xcdoc"))]) (helm-wordnet . [(20160128 1507) ((emacs (24)) (helm (1 7 0)) (cl-lib (0 5))) "Helm interface to local wordnet dictionary" single ((:commit . "a36dbc6fcb570b812870bc1e190f203e0a0042fc") (:keywords "dictionary" "wordnet" "emacs" "elisp" "helm") (:authors ("Raghav Kumar Gautam" . "rgautam@apache.com")) (:maintainer "Raghav Kumar Gautam" . "rgautam@apache.com") (:url . "https://github.com/raghavgautam/helm-wordnet"))]) (helm-w3m . [(20171102 916) ((helm (1 5)) (w3m (0 0)) (cl-lib (0 5)) (emacs (24 1))) "W3m bookmark - helm interface." single ((:commit . "8345b7e60702911f54eb6571e429c0d31878957d"))]) (helm-w32-launcher . [(20141223 2014) ((emacs (24)) (helm (1 6 5)) (cl-lib (0 5))) "Start Menu entry launcher using Helm" tar ((:commit . "3e59ad62b89dd21d334af0203d445a83eb25dc5b") (:authors ("Fanael Linithien" . "fanael4@gmail.com")) (:maintainer "Fanael Linithien" . "fanael4@gmail.com") (:url . "https://github.com/Fanael/helm-w32-launcher"))]) (helm-unicode . [(20180608 1407) ((helm (1 9 8)) (emacs (24 4))) "Helm command for unicode characters." single ((:commit . "fbeb0c5e741a6f462520884b744d43a9acbe1d34"))]) (helm-tramp . [(20180829 709) ((emacs (24 3)) (helm (2 0))) "Tramp helm interface for ssh, docker, vagrant" single ((:commit . "3f6380fd7c220b642c01cb420ea95770c0e42bdb") (:authors ("Masashı Mıyaura")) (:maintainer "Masashı Mıyaura") (:url . "https://github.com/masasam/emacs-helm-tramp"))]) (helm-themes . [(20160918 545) ((helm-core (2 0)) (emacs (24 4))) "Color theme selection with helm interface" single ((:commit . "1160af42590b0d845a55e65e1e782d9e4027fd6e") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-helm-themes"))]) (helm-tail . [(20180624 903) ((emacs (25 1)) (helm (2 7 0))) "Read recent output from various sources" single ((:commit . "cdbbd9bfb121534a4c089df84325cf776ba2c578") (:keywords "maint" "tools") (:authors ("Akira Komamura" . "akira.komamura@gmail.com")) (:maintainer "Akira Komamura" . "akira.komamura@gmail.com") (:url . "https://github.com/akirak/helm-tail"))]) (helm-systemd . [(20180131 434) ((emacs (24 4)) (helm (1 9 2)) (with-editor (2 5 0))) "helm's systemd interface" single ((:commit . "96f5cd3ee3412539c2f8d145201f47c4f8e53b4f") (:keywords "convenience") (:authors (nil . "<lompik@oriontabArch>")) (:maintainer nil . "<lompik@oriontabArch>"))]) (helm-system-packages . [(20180827 1255) ((emacs (24 4)) (helm (2 8 6)) (seq (1 8))) "Helm UI wrapper for system package managers." tar ((:commit . "80a2165f8e204bb42c29acc058d27e8c61e6cfed") (:keywords "helm" "packages") (:authors ("Pierre Neidhardt" . "mail@ambrevar.xyz")) (:maintainer "Pierre Neidhardt" . "mail@ambrevar.xyz") (:url . "https://github.com/emacs-helm/helm-system-packages"))]) (helm-swoop . [(20180215 1154) ((helm (1 0)) (emacs (24 3))) "Efficiently hopping squeezed lines powered by helm interface" single ((:commit . "c66336b8245ddc51c4206f19c119f1081920985c") (:keywords "helm" "swoop" "inner" "buffer" "search") (:authors ("Shingo Fukuyama - http://fukuyama.co")) (:maintainer "Shingo Fukuyama - http://fukuyama.co") (:url . "https://github.com/ShingoFukuyama/helm-swoop"))]) (helm-sql-connect . [(20170319 1251) ((helm (0 0 0))) "Choose a database to connect to via Helm." single ((:commit . "5aead55b6f8636140945714d8c332b287ab9ef10") (:keywords "tools" "convenience" "comm") (:authors ("Eric Hansen" . "hansen.c.eric@gmail.com")) (:maintainer "Eric Hansen" . "hansen.c.eric@gmail.com") (:url . "https://github.com/eric-hansen/helm-sql-connect"))]) (helm-spotify-plus . [(20180107 1138) ((emacs (24 4)) (helm (2 0 0)) (multi (2 0 1))) "Control Spotify search and select music with Helm." single ((:commit . "895f241f1259891d5c89cd42023f119f9fa121d6") (:authors ("Wanderson Ferreira <https://github.com/wandersoncferreira> and Luis Moneda <https://github.com/lgmoneda>")) (:maintainer "Wanderson Ferreira <https://github.com/wandersoncferreira> and Luis Moneda <https://github.com/lgmoneda>"))]) (helm-spotify . [(20160905 2147) ((helm (0 0 0)) (multi (2 0 0))) "Control Spotify with Helm." single ((:commit . "f7a62d1ff88e3127de9be7cd3e818b0a92268ab3") (:keywords "helm" "spotify") (:authors ("Kris Jenkins" . "krisajenkins@gmail.com")) (:maintainer "Kris Jenkins" . "krisajenkins@gmail.com") (:url . "https://github.com/krisajenkins/helm-spotify"))]) (helm-spaces . [(20161001 1409) ((helm-core (2 2)) (spaces (0 1 0))) "helm sources for spaces" single ((:commit . "877e2b5178926308d6a7c2a37477bb12c33a96d4") (:keywords "helm" "frames" "convenience") (:authors ("Yasuyuki Oka" . "yasuyk@gmail.com")) (:maintainer "Yasuyuki Oka" . "yasuyk@gmail.com") (:url . "https://github.com/yasuyk/helm-spaces"))]) (helm-smex . [(20171004 2008) ((emacs (24)) (smex (3 0)) (helm (1 7 7))) "Helm interface for smex" single ((:commit . "2269375dfa452b88b5170d1a5d5849ebb2c1e413") (:keywords "convenience") (:authors ("Peter Vasil" . "mail@petervasil.net")) (:maintainer "Peter Vasil" . "mail@petervasil.net"))]) (helm-sheet . [(20130630 1239) ((helm (1 0))) "helm sources for sheet" single ((:commit . "d360b68d0ddb09aa1854e7b2f3cb39caeee26463") (:keywords "helm" "sheet") (:authors ("Yasuyuki Oka" . "yasuyk@gmail.com")) (:maintainer "Yasuyuki Oka" . "yasuyk@gmail.com") (:url . "https://github.com/yasuyk/helm-sheet"))]) (helm-selected . [(20171223 210) ((emacs (24 4)) (helm (2 8 6)) (selected (1 1))) "helm extension for selected.el" single ((:commit . "6743ede584571319e4c29204197e9ff6b7ee97cf") (:keywords "extensions" "convenience") (:authors ("Takaaki ISHIKAWA <takaxp at ieee dot org>")) (:maintainer "Takaaki ISHIKAWA <takaxp at ieee dot org>") (:url . "https://github.com/takaxp/helm-selected"))]) (helm-sage . [(20160514 745) ((cl-lib (0 5)) (helm (1 5 6)) (sage-shell-mode (0 1 0))) "A helm extension for sage-shell-mode." single ((:commit . "f14e9281d8f2162df7d8f9c2ad9ad1248a24803b") (:keywords "sage" "math" "helm") (:authors ("Sho Takemori" . "stakemorii@gmail.com")) (:maintainer "Sho Takemori" . "stakemorii@gmail.com") (:url . "https://github.com/stakemori/helm-sage"))]) (helm-safari . [(20160404 324) ((helm (1 9 1)) (emacs (24))) "Browse your Safari bookmarks and history" single ((:commit . "664c7f4488829228eed7e90cd53002e14bec555b") (:keywords "tools") (:authors ("Chunyang Xu" . "xuchunyang56@gmail.com")) (:maintainer "Chunyang Xu" . "xuchunyang56@gmail.com") (:url . "https://github.com/xuchunyang/helm-safari"))]) (helm-rubygems-org . [(20140826 1156) ((emacs (24)) (helm (1 6 3)) (cl-lib (0 5))) "Use helm to search rubygems.org" single ((:commit . "6aaed984f698cbdf9f9aceb0221404563e28764d") (:keywords "ruby" "rubygems" "gemfile" "helm") (:authors ("Chad Albers" . "calbers@neomantic.com")) (:maintainer "Chad Albers" . "calbers@neomantic.com") (:url . "https://github.com/neomantic/helm-rubygems-org"))]) (helm-rubygems-local . [(20130712 111) ((helm (1 5 3))) "Installed local rubygems find-file for helm" single ((:commit . "289cb33d41c703af9791d6da46b55f070013c2e3") (:authors ("hadashiA" . "dev@hadashikick.jp")) (:maintainer "hadashiA" . "dev@hadashikick.jp") (:url . "https://github.com/f-kubotar/helm-rubygems-local"))]) (helm-rtags . [(20170813 411) ((helm (2 0)) (rtags (2 10))) "A front-end for rtags" single ((:commit . "fc63be8f48bed6703b37ccb1057d75d7ce5200ca") (:authors ("Jan Erik Hanssen" . "jhanssen@gmail.com") ("Anders Bakken" . "agbakken@gmail.com")) (:maintainer "Jan Erik Hanssen" . "jhanssen@gmail.com") (:url . "http://rtags.net"))]) (helm-ros . [(20160812 1752) ((helm (1 9 9)) (xterm-color (1 0)) (cl-lib (0 5))) "Interfaces ROS with helm" single ((:commit . "92b0b215f6a017f0f57f1af15466cc0b2a5a0135") (:keywords "helm" "ros") (:authors ("David Landry" . "davidlandry93@gmail.com")) (:maintainer "David Landry" . "davidlandry93@gmail.com") (:url . "https://www.github.com/davidlandry93/helm-ros"))]) (helm-robe . [(20151209 355) ((helm (1 7 7))) "completing read function for robe" single ((:commit . "6e69543b4ee76c5f8f3f2510c76e6d9aed17a370") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-helm-robe"))]) (helm-rhythmbox . [(20160524 1158) ((helm (1 5 0)) (cl-lib (0 5))) "control Rhythmbox's play queue via Helm" single ((:commit . "c92e1ded34ddd4e62e7e9a558259c232e05193fa") (:authors ("Thomas Winant" . "dewinant@gmail.com")) (:maintainer "Thomas Winant" . "dewinant@gmail.com") (:url . "https://github.com/mrBliss/helm-rhythmbox"))]) (helm-rg . [(20180629 920) ((emacs (25)) (cl-lib (0 5)) (dash (2 13 0)) (helm (2 8 8))) "a helm interface to ripgrep" single ((:commit . "d356a2abb6359d709487ed49414e151627287577") (:keywords "find" "file" "files" "helm" "fast" "rg" "ripgrep" "grep" "search" "match") (:authors ("Danny McClanahan")) (:maintainer "Danny McClanahan") (:url . "https://github.com/cosmicexplorer/helm-rg"))]) (helm-recoll . [(20160731 921) ((helm (1 9 9))) "helm interface for the recoll desktop search tool." single ((:commit . "cc4c4fa9c8f4f99383647baa8512b60523dc8b36") (:keywords "convenience") (:authors ("Thierry Volpiatto <thierry.volpiatto at gmail.com>")) (:maintainer "Thierry Volpiatto <thierry.volpiatto at gmail.com>") (:url . "https://github.com/emacs-helm/helm-recoll"))]) (helm-rdefs . [(20161130 536) ((emacs (24)) (helm (1 6 4))) "rdefs with helm interface" single ((:commit . "cd3a6b3af3015ee58ef30cb7c81c79ebe5fc867b") (:keywords "matching" "tools") (:authors ("Hiroshi Saito" . "monodie@gmail.com")) (:maintainer "Hiroshi Saito" . "monodie@gmail.com") (:url . "https://github.com/saidie/helm-rdefs"))]) (helm-rb . [(20131123 1639) ((helm (1 0)) (helm-ag-r (20131123))) "Search Ruby's method by ag and display helm" tar ((:commit . "4949d646420a9849af234dacdd8eb34a77c662fd") (:keywords "searching" "ruby") (:authors ("Yuta Yamada <cokesboy\"at\"gmail.com>")) (:maintainer "Yuta Yamada <cokesboy\"at\"gmail.com>") (:url . "https://github.com/yuutayamada/helm-rb"))]) (helm-rails . [(20130424 1519) ((helm (1 5 1)) (inflections (1 1))) "Helm extension for Rails projects." single ((:commit . "506d9948d45dfbc575c9c4c0d102c1ad2f511e82") (:keywords "helm" "rails" "git") (:authors ("Adam Sokolnicki" . "adam.sokolnicki@gmail.com")) (:maintainer "Adam Sokolnicki" . "adam.sokolnicki@gmail.com") (:url . "https://github.com/asok/helm-rails"))]) (helm-rage . [(20180118 1532) ((helm (1 9 8)) (emacs (24 4)) (dash (2 13 0)) (s (1 11 0))) "Helm command for rage characters." tar ((:commit . "5d0aefb53d859186181d4bdcfeff7d315339c7b8") (:keywords "helm" "rage" "meme") (:url . "https://github.com/bomgar/helm-rage"))]) (helm-qiita . [(20180301 1435) ((helm (2 8 2))) "Qiita with helm interface" single ((:commit . "3ccb85640bf54491ed3c3c8110d454ae181650dc") (:authors ("Takashi Masuda" . "masutaka.net@gmail.com")) (:maintainer "Takashi Masuda" . "masutaka.net@gmail.com") (:url . "https://github.com/masutaka/emacs-helm-qiita"))]) (helm-pydoc . [(20160918 542) ((helm-core (2 0)) (emacs (24 4))) "pydoc with helm interface" tar ((:commit . "85480a29b56dacde425655bc8f5a597c785afdf5") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-helm-pydoc"))]) (helm-purpose . [(20170114 1636) ((emacs (24)) (helm (1 9 2)) (window-purpose (1 4))) "Helm Interface for Purpose" single ((:commit . "9ff4c21c1e9ebc7afb851b738f815df7343bb287") (:authors ("Bar Magal (2016)")) (:maintainer "Bar Magal (2016)") (:url . "https://github.com/bmag/helm-purpose"))]) (helm-pt . [(20160214 2342) ((helm (1 5 6))) "Helm interface to the platinum searcher" tar ((:commit . "8acc52911dad1ed0c3975f134a468762afe0b76b") (:keywords "helm" "platinum searcher"))]) (helm-prosjekt . [(20140129 717) ((prosjekt (0 3)) (helm (1 5 9))) "Helm integration for prosjekt." single ((:commit . "a864a8be5842223043702395f311e3350c28e9db") (:authors ("Sohail Somani" . "sohail@taggedtype.net")) (:maintainer "Sohail Somani" . "sohail@taggedtype.net") (:url . "https://github.com/abingham/prosjekt"))]) (helm-projectile . [(20180815 1514) ((helm (1 9 9)) (projectile (0 14 0)) (cl-lib (0 3))) "Helm integration for Projectile" single ((:commit . "8a2dbc973548fac89356c11d70f7f474ea1367a5") (:keywords "project" "convenience") (:authors ("Bozhidar Batsov")) (:maintainer "Bozhidar Batsov") (:url . "https://github.com/bbatsov/helm-projectile"))]) (helm-project-persist . [(20151210 1543) ((helm (1 5 2)) (project-persist (0 1 4))) "Helm integration for project-persist package" single ((:commit . "357950fbac18090985a750e40d5d8b10ee9dcd53") (:keywords "project-persist" "project" "helm") (:authors ("Sliim" . "sliim@mailoo.org")) (:maintainer "Sliim" . "sliim@mailoo.org"))]) (helm-proc . [(20161006 305) ((helm (1 6 0))) "Helm interface for managing system processes" tar ((:commit . "576d31c2d74ba3897d56e2acd2b0993f52c2547c"))]) (helm-posframe . [(20180610 1748) ((emacs (26 0)) (posframe (0 1 0)) (helm (0 1))) "Using posframe to show helm window" single ((:commit . "d28f96ea92ee9393658901bb552723db10f40dc3") (:keywords "abbrev" "convenience" "matching" "helm") (:authors ("Feng Shu")) (:maintainer "Feng Shu" . "tumashu@163.com") (:url . "https://github.com/tumashu/helm-posframe"))]) (helm-phpunit . [(20160513 853) ((helm (1 9 5)) (phpunit (0 7 0))) "Helm integration for phpunit.el" single ((:commit . "739f26204ad2ba76c25f45e8eab1e5216f7c3518") (:keywords "phpunit" "helm" "php") (:authors ("Eric Hansen" . "hansen.c.eric@gmail.com")) (:maintainer "Eric Hansen" . "hansen.c.eric@gmail.com") (:url . "https://github.com/eric-hansen/phpunit-helm"))]) (helm-perspeen . [(20170228 1345) ((perspeen (0 1 0)) (helm (2 5 0))) "Helm interface for perspeen." single ((:commit . "7fe2922d85608bfa9e18269fc44181428b8849ff") (:keywords "projects" "lisp") (:authors ("Yoshinobu Fujimoto")) (:maintainer "Yoshinobu Fujimoto") (:url . "https://github.com/jimo1001/helm-perspeen"))]) (helm-perldoc . [(20160918 556) ((helm-core (2 0)) (deferred (0 3 1)) (emacs (24 4))) "perldoc with helm interface" tar ((:commit . "1979f9f67814c11ec9498502237c89a5e1153100") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-helm-perldoc"))]) (helm-pass . [(20180607 2348) ((emacs (25)) (helm (0)) (password-store (0)) (auth-source-pass (4 0 0))) "helm interface of pass, the standard Unix password manager" single ((:commit . "fdff8f8f2e2b8a61caed7b6c171624700dbe1346") (:authors ("J. Alexander Branham" . "branham@utexas.edu")) (:maintainer "J. Alexander Branham" . "branham@utexas.edu") (:url . "https://github.com/jabranham/helm-pass"))]) (helm-pages . [(20161121 226) ((helm (1 6 5)) (emacs (24)) (cl-lib (0 5))) "Pages in current buffer as Helm datasource" single ((:commit . "51dcb9374d1df9feaae85e60cfb39b970554ecba") (:keywords "convenience" "helm" "outlines") (:authors ("David Christiansen" . "david@davidchristiansen.dk")) (:maintainer "David Christiansen" . "david@davidchristiansen.dk"))]) (helm-orgcard . [(20151001 1524) ((helm-core (1 7 7))) "browse the orgcard by helm" single ((:commit . "9655ac340d1ccc5f3d1c0f7c49be8dd3556d4d0d") (:keywords "convenience" "helm" "org") (:authors ("Yuhei Maeda <yuhei.maeda_at_gmail.com>")) (:maintainer "Yuhei Maeda") (:url . "https://github.com/emacs-jp/helm-orgcard"))]) (helm-org-rifle . [(20180712 2245) ((emacs (24 4)) (dash (2 12)) (f (0 18 1)) (helm (1 9 4)) (s (1 10 0))) "Rifle through your Org files" single ((:commit . "b712ced914da3ae733ee7c355261071d4eed4876") (:keywords "hypermedia" "outlines") (:authors ("Adam Porter" . "adam@alphapapa.net")) (:maintainer "Adam Porter" . "adam@alphapapa.net") (:url . "http://github.com/alphapapa/helm-org-rifle"))]) (helm-open-github . [(20170220 159) ((emacs (24 4)) (helm-core (1 7 7)) (gh (0 8 2))) "Utilities of Opening Github Page" single ((:commit . "2f03d97552a1233db7694116d5f80ecde7612756") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-helm-open-github"))]) (helm-notmuch . [(20180730 1722) ((helm (1 9 3)) (notmuch (0 21))) "Search emails with Notmuch and Helm" single ((:commit . "9988eb0f787c82c779f2417b5613b9142a5b1c9b") (:keywords "mail") (:authors ("Chunyang Xu" . "mail@xuchunyang.me")) (:maintainer "Chunyang Xu" . "mail@xuchunyang.me") (:url . "https://github.com/xuchunyang/helm-notmuch"))]) (helm-nixos-options . [(20151013 2309) ((nixos-options (0 0 1)) (helm (1 5 6))) "Helm Interface for nixos-options" single ((:commit . "7007363e773a419203a69798fb0e0731b2eb0f73") (:keywords "unix") (:authors ("Diego Berrocal" . "cestdiego@gmail.com") ("Travis B. Hartwell" . "nafai@travishartwell.net")) (:maintainer "Diego Berrocal" . "cestdiego@gmail.com") (:url . "http://www.github.com/travisbhartwell/nix-emacs/"))]) (helm-navi . [(20170402 1452) ((emacs (24 4)) (helm (1 9 4)) (navi-mode (2 0)) (s (1 10 0))) "Helm for navi-mode" single ((:commit . "2256591174ff79f889450fdc10822316819d6476") (:keywords "navigation" "outlines") (:authors ("Adam Porter" . "adam@alphapapa.net")) (:maintainer "Adam Porter" . "adam@alphapapa.net") (:url . "http://github.com/emacs-helm/helm-navi"))]) (helm-mu . [(20180513 921) ((helm (1 5 5))) "Helm sources for searching emails and contacts" single ((:commit . "77e6fea24e01481418738421dbcfe28ef1bd63cf") (:authors ("Titus von der Malsburg" . "malsburg@posteo.de")) (:maintainer "Titus von der Malsburg" . "malsburg@posteo.de") (:url . "https://github.com/emacs-helm/helm-mu"))]) (helm-mt . [(20160918 452) ((emacs (24)) (helm (0 0)) (multi-term (0 0)) (cl-lib (0 5))) "helm multi-term management" single ((:commit . "d2bff4100118483bc398c56d0ff095294209265b") (:keywords "helm" "multi-term") (:authors ("Didier Deshommes" . "dfdeshom@gmail.com")) (:maintainer "Didier Deshommes" . "dfdeshom@gmail.com") (:url . "https://github.com/dfdeshom/helm-mt"))]) (helm-mode-manager . [(20151124 938) ((helm (1 5 3))) "Select and toggle major and minor modes with helm" single ((:commit . "5d9c3ca4f8205d07ff4e03c4c3e88f596751c1fc") (:authors ("istib")) (:maintainer "istib") (:url . "https://github.com/istib/helm-mode-manager"))]) (helm-migemo . [(20151010 356) ((emacs (24 4)) (helm-core (1 7 8)) (migemo (1 9)) (cl-lib (0 5))) "Migemo plug-in for helm" single ((:commit . "66c6a19d07c6a385daefd2090d0709d26b608b4e") (:keywords "matching" "convenience" "tools" "i18n") (:authors ("rubikitch" . "rubikitch@ruby-lang.org")) (:maintainer "Yuhei Maeda <yuhei.maeda_at_gmail.com>") (:url . "https://github.com/emacs-jp/helm-migemo"))]) (helm-make . [(20180602 1353) ((helm (1 5 3)) (projectile (0 11 0))) "Select a Makefile target with helm" single ((:commit . "e72cdacecb46421dfbde9febdc352a5f06425176") (:keywords "makefile") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:url . "https://github.com/abo-abo/helm-make"))]) (helm-ls-svn . [(20150717 739) ((emacs (24 1)) (helm (1 7 0)) (cl-lib (0 5))) "helm extension to list svn files" single ((:commit . "4d4dc1a272f27fba5fdd7cc47e5d309b53c63ae3") (:keywords "helm" "svn") (:authors ("Chunyang Xu" . "chunyang@macports.org")) (:maintainer "Chunyang Xu" . "chunyang@macports.org") (:url . "https://svn.macports.org/repository/macports/users/chunyang/helm-ls-svn.el/helm-ls-svn.el"))]) (helm-ls-hg . [(20150909 543) ((helm (1 7 8))) "List hg files in hg project." single ((:commit . "61b91a22fcfb62d0fc56e361ec01ce96973c7165"))]) (helm-ls-git . [(20180711 923) ((helm (1 7 8))) "list git files." single ((:commit . "e38cee59c42fbf16b6de239a537d27af58473394"))]) (helm-lobsters . [(20150213 1546) ((helm (1 0)) (cl-lib (0 5))) "helm front-end for lobste.rs" single ((:commit . "53c5b42baf72776dcba891fc3d7cd7d47721e9b0") (:authors ("Julien BLANCHARD" . "julien@sideburns.eu")) (:maintainer "Julien BLANCHARD" . "julien@sideburns.eu") (:url . "https://github.com/julienXX/helm-lobste.rs"))]) (helm-lines . [(20180601 2033) ((emacs (24 4)) (helm (1 9 8))) "A helm interface for completing by lines" single ((:commit . "3bfe15a60c6405682085ab289de3eb364624c4e9") (:keywords "files" "helm" "ag" "pt" "vc" "git" "lines" "complete" "tools" "languages") (:authors ("@torgeir")) (:maintainer "@torgeir") (:url . "https://github.com/torgeir/helm-lines.el/"))]) (helm-lib-babel . [(20180510 1324) ((cl-lib (0 5)) (helm (1 9 2)) (emacs (24 4))) "helm insertion of babel function references" single ((:commit . "41bc0cdea8a604c6c8dc83ed5066644d33688fad") (:keywords "convenience") (:authors ("Derek Feichtinger" . "dfeich@gmail.com")) (:maintainer "Derek Feichtinger" . "dfeich@gmail.com") (:url . "https://github.com/dfeich/helm-lib-babel.el"))]) (helm-lean . [(20171102 1454) ((emacs (24 3)) (dash (2 12 0)) (helm (2 8 0)) (lean-mode (3 3 0))) "Helm interfaces for lean-mode" single ((:commit . "529b8fa535cfa090a6b62566794161556ffade80") (:keywords "languages") (:authors ("Leonardo de Moura" . "leonardo@microsoft.com") ("Soonho Kong      " . "soonhok@cs.cmu.edu") ("Gabriel Ebner    " . "gebner@gebner.org") ("Sebastian Ullrich" . "sebasti@nullri.ch")) (:maintainer "Sebastian Ullrich" . "sebasti@nullri.ch") (:url . "https://github.com/leanprover/lean-mode"))]) (helm-lastpass . [(20180722 806) ((emacs (25 1)) (helm (2 0)) (csv (2 1))) "Helm interface of LastPass" single ((:commit . "82e1ffb6ae77d9d9e29c398eb013cd20ce963f77") (:authors ("Xu Chunyang" . "mail@xuchunyang.me")) (:maintainer "Xu Chunyang" . "mail@xuchunyang.me") (:url . "https://github.com/xuchunyang/helm-lastpass"))]) (helm-kythe . [(20170709 726) ((emacs (25)) (dash (2 12 0)) (helm (2 0))) "Google Kythe helm interface" single ((:commit . "eabbef4948f8ec7c7b2fac498e9145dfdb10ca82") (:authors ("Fangrui Song" . "i@maskray.me")) (:maintainer "Fangrui Song" . "i@maskray.me") (:url . "https://github.com/MaskRay/emacs-helm-kythe"))]) (helm-jstack . [(20150603 422) ((emacs (24)) (helm (1 7 0)) (cl-lib (0 5))) "Helm interface to Jps & Jstack for Java/JVM processes" single ((:commit . "2064f7215dcf4ccbd6a7b8784223251507746da4") (:keywords "java" "jps" "jstack" "jvm" "emacs" "elisp" "helm") (:authors ("Raghav Kumar Gautam" . "rgautam@apache.com")) (:maintainer "Raghav Kumar Gautam" . "rgautam@apache.com"))]) (helm-js-codemod . [(20171106 1044) ((emacs (24 4)) (helm-core (1 9 8)) (js-codemod (1 0 0))) "A helm interface for running js-codemods" single ((:commit . "18503d94e64418e8ea5c5854f197ae9f3009cdbf") (:keywords "helm" "js" "codemod" "region") (:authors (nil . "Torgeir Thoresen <@torgeir>")) (:maintainer nil . "Torgeir Thoresen <@torgeir>"))]) (helm-jira . [(20180802 815) ((emacs (25)) (cl-lib (0 5)) (helm (1 9 9))) "Helm bindings for JIRA/Bitbucket/stash" single ((:commit . "75d6ed5bd7a041fa8c1adb21cbbbe57b5a7c7cc7") (:keywords "tools" "helm" "jira" "bitbucket" "stash") (:authors ("Roman Decker <roman dot decker at gmail dot com>")) (:maintainer "Roman Decker <roman dot decker at gmail dot com>") (:url . "https://github.com/DeX3/helm-jira"))]) (helm-j-cheatsheet . [(20170217 829) ((helm (1 5 3))) "Quick J reference for Emacs" single ((:commit . "6c47e7162b9ba2de4b41221d01180146973d860b") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:url . "https://github.com/abo-abo/helm-j-cheatsheet"))]) (helm-itunes . [(20151013 648) ((helm (1 6 1))) "Play local iTunes and Spotify tracks" single ((:commit . "966de755a5aadbe02311a6cef77bd4790e84c263") (:authors ("Adam Schwartz" . "adam@adamschwartz.io")) (:maintainer "Adam Schwartz" . "adam@adamschwartz.io") (:url . "https://github.com/daschwa/helm-itunes"))]) (helm-ispell . [(20151231 853) ((helm-core (1 7 7))) "ispell-complete-word with helm interface" single ((:commit . "cb735695ab3a0e66c123c2f3f3e8911fb1c2d5fc") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-helm-ispell"))]) (helm-img-tiqav . [(20151224 2322) ((helm-img (0 0 1))) "An helm-source for joking." single ((:commit . "33a7e9508bc8f37d53320b56c92b53d321a57bb0") (:keywords "convenience") (:authors ("Sho Matsumoto <l3msh0_at_gmail.com>")) (:maintainer "l3msh0") (:url . "https://github.com/l3msh0/helm-img"))]) (helm-img . [(20151224 2321) ((helm (1 7 7)) (cl-lib (0 5))) "Utilities for making image sources for helm." tar ((:commit . "aa3f8a5dce8d0413bf07584f07153a39015c2bfc") (:keywords "convenience") (:authors ("Sho Matsumoto <l3msh0_at_gmail.com>")) (:maintainer "l3msh0") (:url . "https://github.com/l3msh0/helm-img"))]) (helm-idris . [(20141202 1757) ((helm (0 0 0)) (idris-mode (0 9 14))) "A Helm datasource for Idris documentation, queried from the compiler" single ((:commit . "a2f45d6817974f318b55ad9b7fd19d5df132d47e") (:keywords "languages" "helm") (:authors ("David Raymond Christiansen" . "david@davidchristiansen.dk")) (:maintainer "David Raymond Christiansen" . "david@davidchristiansen.dk"))]) (helm-hunks . [(20171217 1933) ((emacs (24 4)) (helm (1 9 8))) "A helm interface for git hunks - browsing, staging, unstaging and killing" single ((:commit . "6392bf716f618eac23ce81140aceb0dfacb9c6d0") (:keywords "helm" "git" "hunks" "vc") (:authors ("@torgeir")) (:maintainer "@torgeir"))]) (helm-hoogle . [(20161027 534) ((helm (1 6 2)) (emacs (24 4))) "Use helm to navigate query results from Hoogle" single ((:commit . "73969a9d46d2121a849a01a9f7ed3636d01f7bbc") (:keywords "haskell" "programming" "hoogle") (:authors ("John Wiegley" . "jwiegley@gmail.com")) (:maintainer "John Wiegley" . "jwiegley@gmail.com") (:url . "https://github.com/jwiegley/haskell-config"))]) (helm-helm-commands . [(20130902 1748) ((helm (1 5 4))) "List all helm commands with helm" single ((:commit . "3a05aa19c976501343ad9ae630a36810921a85f6") (:keywords "convenience") (:authors ("Joe Bloggs" . "vapniks@yahoo.com")) (:maintainer "Joe Bloggs" . "vapniks@yahoo.com") (:url . "https://github.com/vapniks/helm-helm-commands"))]) (helm-hayoo . [(20151014 651) ((helm (1 6 0)) (json (1 2)) (haskell-mode (13 7))) "Source and configured helm for searching hayoo" single ((:commit . "dd4c0c8c87521026edf1b808c4de01fa19b7c693") (:keywords "helm") (:authors ("Markus Hauck" . "markus1189@gmail.com")) (:maintainer "Markus Hauck" . "markus1189@gmail.com"))]) (helm-hatena-bookmark . [(20180804 546) ((helm (2 8 2))) "Hatena::Bookmark with helm interface" single ((:commit . "274e18182fe20c11e96009387a8e38e8cd2a1d7e") (:authors ("Takashi Masuda" . "masutaka.net@gmail.com")) (:maintainer "Takashi Masuda" . "masutaka.net@gmail.com") (:url . "https://github.com/masutaka/emacs-helm-hatena-bookmark"))]) (helm-gtags . [(20170116 529) ((emacs (24 4)) (helm (2 0))) "GNU GLOBAL helm interface" single ((:commit . "108e93d0d099ebb7b98847388f368311cf177033") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-helm-gtags"))]) (helm-growthforecast . [(20140120 344) ((helm (1 5 9))) "helm extensions for growthforecast." single ((:commit . "0f94ac090d6c354058ad89a86e5c18385c136d9b") (:authors ("Daichi Hirata" . "daichi.hirat@gmail.com")) (:maintainer "Daichi Hirata" . "daichi.hirat@gmail.com") (:url . "https://github.com/daic-h/helm-growthforecast"))]) (helm-grepint . [(20161001 1413) ((helm (1 0)) (emacs (24))) "Generic helm interface to grep" single ((:commit . "a62ca27515ff6a366b89b420500eb16d380cc653") (:keywords "grep" "grepping" "searching" "helm") (:authors ("Kalle Kankare" . "kalle.kankare@iki.fi")) (:maintainer "Kalle Kankare" . "kalle.kankare@iki.fi") (:url . "https://github.com/kopoli/helm-grepint"))]) (helm-google . [(20180606 520) ((helm (0))) "Emacs Helm Interface for quick Google searches" single ((:commit . "48e91a73d5f48c39d7a219022a24440cff548e1a") (:keywords "helm" "google" "search" "browse" "searx") (:authors ("steckerhalter")) (:maintainer "steckerhalter") (:url . "https://framagit.org/steckerhalter/helm-google"))]) (helm-go-package . [(20161103 153) ((emacs (24 4)) (helm-core (2 2 1)) (go-mode (1 4 0)) (deferred (0 4 0))) "helm sources for Go programming language's package" single ((:commit . "e42c563936c205ceedb930a687c11b4bb56447bc") (:authors ("Yasuyuki Oka" . "yasuyk@gmail.com")) (:maintainer "Yasuyuki Oka" . "yasuyk@gmail.com") (:url . "https://github.com/yasuyk/helm-go-package"))]) (helm-gitlab . [(20180312 1647) ((s (1 9 0)) (dash (2 9 0)) (helm (1 0)) (gitlab (0 8 0))) "Helm interface to Gitlab" single ((:commit . "68318aca3206d50701039c9aae39734ca29a49f9") (:keywords "gitlab" "helm") (:authors ("Nicolas Lamirault" . "nicolas.lamirault@gmail.com")) (:maintainer "Nicolas Lamirault" . "nicolas.lamirault@gmail.com") (:url . "https://github.com/nlamirault/emacs-gitlab"))]) (helm-gitignore . [(20170211 8) ((gitignore-mode (1 1 0)) (helm (1 7 0)) (request (0 1 0)) (cl-lib (0 5))) "Generate .gitignore files with gitignore.io." single ((:commit . "2a2e7da7855a6db0ab3bb6a6a087863d7abd4391") (:keywords "helm" "gitignore" "gitignore.io") (:authors ("Juan Placencia")) (:maintainer "Juan Placencia") (:url . "https://github.com/jupl/helm-gitignore"))]) (helm-github-stars . [(20180718 111) ((helm (1 6 8)) (emacs (24 4))) "Helm integration for your starred repositories on github" single ((:commit . "809cf88e2984b121348b1046e1d3890f1fd580b4") (:keywords "helm" "github" "stars") (:authors ("Sliim" . "sliim@mailoo.org") ("xuchunyang" . "xuchunyang56@gmail.com")) (:maintainer "Sliim" . "sliim@mailoo.org") (:url . "https://github.com/Sliim/helm-github-stars"))]) (helm-git-grep . [(20170614 1411) ((helm-core (2 2 0))) "helm for git grep, an incremental git-grep(1)" single ((:commit . "744cea07dba6e6a5effbdba83f1b786c78fd86d3") (:authors ("mechairoi")) (:maintainer "Yasuyuki Oka" . "yasuyk@gmail.com") (:url . "https://github.com/yasuyk/helm-git-grep"))]) (helm-git-files . [(20141212 1317) ((helm (1 5 9))) "helm for git files" single ((:commit . "43193960774069369ac6964bbf7c026900206fa8") (:keywords "helm" "git") (:authors ("INA Lintaro <tarao.gnn at gmail.com>") ("TAKAGI Kentaro <kentaro0910_at_gmail.com>")) (:maintainer "INA Lintaro <tarao.gnn at gmail.com>"))]) (helm-git . [(20120630 2103) nil "Helm extension for Git." single ((:commit . "cb96a52b5aecadd3c27aba7749d14e43ab128d55") (:keywords "helm" "git") (:authors ("Marian Schubert" . "marian.schubert@gmail.com")) (:maintainer "Marian Schubert" . "marian.schubert@gmail.com") (:url . "https://github.com/maio/helm-git"))]) (helm-ghs . [(20170715 541) ((emacs (24)) (helm (2 2 0))) "ghs with helm interface" single ((:commit . "17a70bf16255d90d67c8350e88200ec8bfd47563") (:authors ("iory" . "ab.ioryz@gmail.com")) (:maintainer "iory" . "ab.ioryz@gmail.com") (:url . "https://github.com/iory/emacs-helm-ghs"))]) (helm-ghq . [(20161015 817) ((helm (2 2 0))) "ghq with helm interface" single ((:commit . "49481685adbb25b3f766aabfdb7472becc673a94") (:authors ("Takashi Masuda" . "masutaka.net@gmail.com")) (:maintainer "Takashi Masuda" . "masutaka.net@gmail.com") (:url . "https://github.com/masutaka/emacs-helm-ghq"))]) (helm-ghc . [(20141105 1459) ((emacs (24)) (cl-lib (0 5)) (helm (1 6 4)) (ghc (5 2 1 0))) "A Helm datasource for ghc-mod errors" single ((:commit . "e5ee7b8d3b745d162553aecfbd41381c4de85f35") (:keywords "languages" "helm") (:authors ("David Raymond Christiansen" . "david@davidchristiansen.dk")) (:maintainer "David Raymond Christiansen" . "david@davidchristiansen.dk"))]) (helm-fuzzy-find . [(20171106 400) ((emacs (24 1)) (helm (1 7 0))) "Find file using Fuzzy Search" single ((:commit . "de2abbf7ca13609587325bacd4a1ed4376b5c927") (:keywords "helm" "fuzzy" "find" "file") (:authors ("Chunyang Xu" . "xuchunyang56@gmail.com")) (:maintainer "Chunyang Xu" . "xuchunyang56@gmail.com") (:url . "https://github.com/xuchunyang/helm-fuzzy-find"))]) (helm-fuzzier . [(20160605 2145) ((emacs (24 3)) (helm (1 7 0))) "Better fuzzy matching for Helm" single ((:commit . "8798dcf3583b863df5b9dea7fe3b0179ba1c35bc") (:keywords "convenience" "helm" "fuzzy") (:authors ("Ephram Perdition")) (:maintainer "Ephram Perdition") (:url . "http://github.com/EphramPerdition/helm-fuzzier"))]) (helm-frame . [(20170515 1950) ((emacs (24 4))) "open helm buffers in a dedicated frame" single ((:commit . "389e6461a423d649b7062ba99a2234bef7770059") (:keywords "lisp" "helm" "popup" "frame") (:authors ("chee" . "chee@snake.dog")) (:maintainer "chee" . "chee@snake.dog"))]) (helm-flyspell . [(20170210 1901) ((helm (1 6 5))) "Helm extension for correcting words with flyspell" single ((:commit . "8d4d947c687cb650cb149aa2271ad5201ea92594") (:keywords "convenience") (:authors ("Andrzej Pronobis")) (:maintainer "Andrzej Pronobis") (:url . "https://github.com/pronobis/helm-flyspell"))]) (helm-flymake . [(20160610 2) ((helm (1 0))) "helm interface for flymake" single ((:commit . "72cf18a1a1f843db9bb5d58301739ea9ccb1655b") (:authors ("Akira Tamamori" . "tamamori5917@gmail.com")) (:maintainer "Akira Tamamori" . "tamamori5917@gmail.com") (:url . "https://github.com/tam17aki"))]) (helm-flycheck . [(20160710 829) ((dash (2 12 1)) (flycheck (28)) (helm-core (1 9 8))) "Show flycheck errors with helm" single ((:commit . "3cf7d3bb194acacc6395f88360588013d92675d6") (:keywords "helm" "flycheck") (:authors ("Yasuyuki Oka" . "yasuyk@gmail.com")) (:maintainer "Yasuyuki Oka" . "yasuyk@gmail.com") (:url . "https://github.com/yasuyk/helm-flycheck"))]) (helm-flx . [(20180103 516) ((emacs (24 4)) (helm (1 7 9)) (flx (0 5))) "Sort helm candidates by flx score" single ((:commit . "6640fac5cb16bee73c95b8ed1248a4e5e113690e") (:keywords "convenience" "helm" "fuzzy" "flx") (:authors ("PythonNut" . "pythonnut@pythonnut.com")) (:maintainer "PythonNut" . "pythonnut@pythonnut.com") (:url . "https://github.com/PythonNut/helm-flx"))]) (helm-firefox . [(20161202 1317) ((helm (1 5)) (cl-lib (0 5)) (emacs (24 1))) "Firefox bookmarks" single ((:commit . "0ad34b7b5abc485a86cae6920c14de861cbeb085") (:url . "https://github.com/emacs-helm/helm-firefox"))]) (helm-filesets . [(20140929 1835) ((helm (1 6 3)) (filesets+ (0))) "A helm source for emacs filesets" single ((:commit . "b352910af4c3099267a8aa0169c7f743b35bb1fa") (:keywords "filesets") (:authors ("Graham Clark" . "grclark@gmail.com")) (:maintainer "Graham Clark" . "grclark@gmail.com") (:url . "https://github.com/gcla/helm-filesets"))]) (helm-exwm . [(20180827 837) ((emacs (25 2)) (helm (2 8 5)) (exwm (0 15))) "Helm for EXWM buffers" single ((:commit . "e21c6ffabadd2fe8d6c7805b6027cc59a6f914e9") (:keywords "helm" "exwm") (:authors ("Pierre Neidhardt" . "mail@ambrevar.xyz")) (:maintainer "Pierre Neidhardt" . "mail@ambrevar.xyz") (:url . "https://github.com/emacs-helm/helm-exwm"))]) (helm-ext . [(20180526 350) ((emacs (24 4)) (helm (2 5 3))) "A few extensions to Helm" tar ((:commit . "90b788aced21ec467a234b6b77b5a6ebae6de75f") (:keywords "extensions") (:authors ("Junpeng Qiu" . "qjpchmail@gmail.com")) (:maintainer "Junpeng Qiu" . "qjpchmail@gmail.com"))]) (helm-eww . [(20180827 836) ((emacs (24 4)) (helm (2 8 6)) (seq (1 8))) "Helm UI wrapper for EWW." single ((:commit . "2bb7b644f953c45b5dd03298b556312440618026") (:keywords "helm" "packages") (:authors ("Pierre Neidhardt" . "mail@ambrevar.xyz")) (:maintainer "Pierre Neidhardt" . "mail@ambrevar.xyz") (:url . "https://github.com/emacs-helm/helm-eww"))]) (helm-etags-plus . [(20170113 1414) ((helm (1 7 8))) "Another Etags helm.el interface" single ((:commit . "704f0991ee4a2298b01c33aafc224eef322e15e3") (:keywords "helm" "etags") (:authors ("纪秀峰(Joseph)" . "jixiuf@gmail.com")) (:maintainer "纪秀峰(Joseph)" . "jixiuf@gmail.com") (:url . "https://github.com/jixiuf/helm-etags-plus"))]) (helm-emms . [(20180406 528) ((helm (1 5)) (emms (0 0)) (cl-lib (0 5)) (emacs (24 1))) "Emms for Helm." single ((:commit . "d3f9bdef8ff0d093eaf6e26af50ea905ab53fdec") (:url . "https://github.com/emacs-helm/helm-emms"))]) (helm-emmet . [(20160713 1231) ((helm (1 0)) (emmet-mode (1 0 2))) "helm sources for emmet-mode's snippets" single ((:commit . "f0364e736b10cf44232053a78de04133a88185ae") (:keywords "convenience" "helm" "emmet") (:authors ("Yasuyuki Oka" . "yasuyk@gmail.com")) (:maintainer "Yasuyuki Oka" . "yasuyk@gmail.com") (:url . "https://github.com/yasuyk/helm-emmet"))]) (helm-elscreen . [(20170709 914) ((helm (2 8 0)) (elscreen (0)) (cl-lib (0 5)) (emacs (24 1))) "Elscreen with helm interface" single ((:commit . "b8212866939dc4a1e1dc23ad572407b688e130e3") (:keywords "files" "convenience") (:authors ("Thierry Volpiatto" . "thierry.volpiatto@gmail.com")) (:maintainer "Thierry Volpiatto" . "thierry.volpiatto@gmail.com") (:url . "https://github.com/emacs-helm/helm-elscreen"))]) (helm-dirset . [(20151209 12) ((f (0 16 2)) (helm (1 6 1)) (s (1 9 0)) (cl-lib (0 5))) "helm sources for multi directories" single ((:commit . "eb30810cd26e1ee73d84a863e6b2667700e9aead") (:keywords "files" "directories") (:authors ("k1LoW (Kenichirou Oyama), <k1lowxb [at] gmail [dot] com> <k1low [at] 101000lab [dot] org>")) (:maintainer "k1LoW (Kenichirou Oyama), <k1lowxb [at] gmail [dot] com> <k1low [at] 101000lab [dot] org>") (:url . "http://101000lab.org"))]) (helm-dired-recent-dirs . [(20131228 1414) ((helm (1 0))) "Show recent dirs with helm.el support." single ((:commit . "3bcd125b44f5a707588ae3868777d91192351523") (:keywords "helm" "dired" "zsh") (:authors ("Akisute" . "akisute3@gmail.com")) (:maintainer "Akisute" . "akisute3@gmail.com"))]) (helm-dired-history . [(20170524 1046) ((helm (1 9 8)) (cl-lib (0 5))) "Show dired history with helm.el support." single ((:commit . "281523f9fc46cf00fafd670ba5cd16552a607212") (:keywords "helm" "dired history") (:authors ("Joseph(纪秀峰)" . "jixiuf@gmail.com")) (:maintainer "Joseph(纪秀峰)" . "jixiuf@gmail.com") (:url . "https://github.com/jixiuf/helm-dired-history"))]) (helm-directory . [(20170706 402) ((emacs (24 4)) (helm (2 0))) "selecting directory before select the file" single ((:commit . "51bd7cd6e40a84a7efda894283ec76a0107830ad") (:authors ("Masashı Mıyaura")) (:maintainer "Masashı Mıyaura") (:url . "https://github.com/masasam/emacs-helm-directory"))]) (helm-dictionary . [(20160817 2033) ((helm (1 5 5))) "Helm source for looking up dictionaries" single ((:commit . "805ce850d4cbe811227d9c9b16cc51f652198f3f") (:authors ("Titus von der Malsburg" . "malsburg@posteo.de") ("Michael Heerdegen" . "michael_heerdegen@web.de")) (:maintainer "Titus von der Malsburg" . "malsburg@posteo.de") (:url . "https://github.com/emacs-helm/helm-dictionary"))]) (helm-describe-modes . [(20160212 518) ((helm (1 9)) (cl-lib (0 5)) (emacs (24 1))) "Helm interface to major and minor modes." single ((:commit . "11fb36af119b784539d31c6160002de1957408aa") (:keywords "docs" "convenience") (:authors ("Tianxiang Xiong" . "tianxiang.xiong@gmail.com")) (:maintainer "Tianxiang Xiong" . "tianxiang.xiong@gmail.com") (:url . "https://github.com/emacs-helm/helm-describe-modes"))]) (helm-descbinds . [(20180429 1456) ((helm (1 5))) "A convenient `describe-bindings' with `helm'" single ((:commit . "033be73f21778633813264ce1634a6e1ad873d8e") (:keywords "helm" "help") (:authors ("Taiki SUGAWARA" . "buzz.taiki@gmail.com")) (:maintainer "Taiki SUGAWARA" . "buzz.taiki@gmail.com") (:url . "https://github.com/emacs-helm/helm-descbinds"))]) (helm-dash . [(20180503 918) ((helm (1 9 2)) (cl-lib (0 5))) "Offline documentation browser for +150 APIs using Dash docsets." single ((:commit . "0ac2db529577fa63f2ed32310062873c585b91de") (:keywords "docs") (:authors ("Raimon Grau" . "raimonster@gmail.com") ("Toni Reina " . "areina0@gmail.com")) (:maintainer "Raimon Grau" . "raimonster@gmail.com") (:url . "http://github.com/areina/helm-dash"))]) (helm-ctest . [(20180821 1005) ((s (1 9 0)) (dash (2 11 0)) (helm-core (1 7 4))) "Run ctest from within emacs" single ((:commit . "0c73689692a290f56080e95325c15362e90d529b") (:keywords "helm" "ctest") (:authors ("Dan LaManna" . "me@danlamanna.com")) (:maintainer "Dan LaManna" . "me@danlamanna.com"))]) (helm-css-scss . [(20140627 25) ((helm (1 0)) (emacs (24))) "CSS/SCSS/LESS Selectors with helm interface" single ((:commit . "ab8348aa98e0daa2f1b771e35bdb06bfacbe5016") (:keywords "scss" "css" "less" "selector" "helm") (:authors ("Shingo Fukuyama - http://fukuyama.co")) (:maintainer "Shingo Fukuyama - http://fukuyama.co") (:url . "https://github.com/ShingoFukuyama/helm-css-scss"))]) (helm-cscope . [(20170326 722) ((xcscope (1 0)) (helm (1 6 7)) (cl-lib (0 5)) (emacs (24 1))) "Helm interface for xcscope.el." single ((:commit . "3cc7259ab4989f9f7ca039e703cdac14b907530a") (:keywords "cscope" "helm") (:authors ("alpha22jp" . "alpha22jp@gmail.com")) (:maintainer "alpha22jp" . "alpha22jp@gmail.com") (:url . "https://github.com/alpha22jp/helm-cscope.el"))]) (helm-core . [(20180826 515) ((emacs (24 4)) (async (1 9 3))) "Development files for Helm" tar ((:commit . "3f3bfa4f4b4ed163bd1b36690fd63ff40ce14669") (:url . "https://emacs-helm.github.io/helm/"))]) (helm-company . [(20180828 1612) ((helm (1 5 9)) (company (0 6 13))) "Helm interface for company-mode" single ((:commit . "d3fc093a0e833b4dee6561c00d6df3d62aa50f3f") (:authors ("Yasuyuki Oka" . "yasuyk@gmail.com")) (:maintainer "Daniel Ralston" . "Sodel-the-Vociferous@users.noreply.github.com") (:url . "https://github.com/Sodel-the-Vociferous/helm-company"))]) (helm-commandlinefu . [(20150611 545) ((emacs (24 1)) (helm (1 7 0)) (json (1 3)) (let-alist (1 0 3))) "Search and browse commandlinefu.com from helm" single ((:commit . "9ee7e018c5db23ae9c8d1c8fa969876f15b7280d") (:keywords "commandlinefu.com") (:authors ("Chunyang Xu" . "xuchunyang56@gmail.com")) (:maintainer "Chunyang Xu" . "xuchunyang56@gmail.com") (:url . "https://github.com/xuchunyang/helm-commandlinefu"))]) (helm-codesearch . [(20180204 433) ((s (1 10 0)) (dash (2 12 0)) (helm (1 7 7)) (cl-lib (0 5))) "helm interface for codesearch" single ((:commit . "87a68168b7c1490769305db0df60035e47799a75") (:keywords "tools") (:authors ("Youngjoo Lee" . "youngker@gmail.com")) (:maintainer "Youngjoo Lee" . "youngker@gmail.com"))]) (helm-cmd-t . [(20170125 1459) nil "cmd-t style completion" tar ((:commit . "7fa3d4a9f7271512e54c5de999079b27c9eec6bf") (:keywords "helm" "project-management" "completion" "convenience" "cmd-t" "textmate") (:authors ("Le Wang")) (:maintainer "Le Wang") (:url . "https://github.com/lewang/helm-cmd-t"))]) (helm-clojuredocs . [(20160405 723) ((edn (1 1 2)) (helm (1 5 7))) "search for help in clojuredocs.org" single ((:commit . "5a7f0f2cb401be0b09e73262a1c18265ab9a3cea") (:keywords "helm" "clojure") (:authors ("Michal Buczko" . "michal.buczko@gmail.com")) (:maintainer "Michal Buczko" . "michal.buczko@gmail.com") (:url . "https://github.com/mbuczko/helm-clojuredocs"))]) (helm-circe . [(20160207 652) ((emacs (24)) (helm (0 0)) (circe (0 0)) (cl-lib (0 5))) "helm circe buffer management." single ((:commit . "9091651d9fdd8d49d8ff6f9dcf3a2ae416c9f15a") (:keywords "helm" "circe") (:authors ("Les Harris" . "les@lesharris.com")) (:maintainer "Les Harris" . "les@lesharris.com") (:url . "https://github.com/lesharris/helm-circe"))]) (helm-cider-history . [(20150719 2120) ((helm (1 4 0)) (cider (0 9 0))) "Helm interface for cider history" single ((:commit . "c391fcb2e162a02001605a0b9449783575a831fd") (:keywords "convenience") (:authors ("Andreas Klein" . "git@kungi.org")) (:maintainer "Andreas Klein" . "git@kungi.org") (:url . "https://github.com/Kungi/helm-cider-history"))]) (helm-cider . [(20180307 458) ((emacs (24 4)) (cider (0 16)) (helm-core (2 8))) "Helm interface to CIDER" tar ((:commit . "9363cc537f06233345aa3af5cd46aa5681ad607b") (:keywords "cider" "clojure" "helm" "languages") (:authors ("Tianxiang Xiong" . "tianxiang.xiong@gmail.com")) (:maintainer "Tianxiang Xiong" . "tianxiang.xiong@gmail.com") (:url . "https://github.com/clojure-emacs/helm-cider"))]) (helm-chronos . [(20150528 2036) ((chronos (1 2)) (helm (1 7 1))) "helm interface for chronos timers" tar ((:commit . "a14fc3d65dd96ce6616234b3f7b8b08b4c1817ef") (:keywords "calendar") (:authors ("David Knight" . "dxknight@opmbx.org")) (:maintainer "David Knight" . "dxknight@opmbx.org") (:url . "http://github.com/dxknight/helm-chronos"))]) (helm-chrome . [(20160719 520) ((helm (1 5)) (cl-lib (0 3)) (emacs (24))) "Helm interface for Chrome bookmarks" single ((:commit . "fd630ace4b4b4f33355a973743bbfe0c90ce4830") (:keywords "tools") (:authors ("KAWABATA, Taichi <kawabata.taichi_at_gmail.com>")) (:maintainer "KAWABATA, Taichi <kawabata.taichi_at_gmail.com>") (:url . "https://github.com/kawabata/helm-chrome"))]) (helm-charinfo . [(20170810 1231) ((emacs (24)) (helm (1 7 0)) (cl-lib (0 5))) "A helm source for character information" single ((:commit . "91798a49dc115342a7e01e48b264e9a0bf5ea414") (:keywords "convenience") (:authors ("Christian Wittern" . "cwittern@gmail.com")) (:maintainer "Christian Wittern" . "cwittern@gmail.com") (:url . "https://github.com/cwittern/helm-charinfo"))]) (helm-c-yasnippet . [(20170128 1542) ((helm (1 7 7)) (yasnippet (0 8 0)) (cl-lib (0 3))) "helm source for yasnippet.el" single ((:commit . "65ca732b510bfc31636708aebcfe4d2d845b59b0") (:keywords "convenience" "emulation") (:authors ("Kenji.I (Kenji Imakado)" . "ken.imakaado@gmail.com")) (:maintainer "Kenji.I (Kenji Imakado)" . "ken.imakaado@gmail.com"))]) (helm-c-moccur . [(20151230 924) ((helm (20120811)) (color-moccur (2 71))) "helm source for color-moccur.el" single ((:commit . "b0a906f85fa352db091f88b91a9c510de607dfe9") (:keywords "convenience" "emulation") (:authors ("Kenji.I (Kenji Imakado)" . "ken.imakaado@gmail.com")) (:maintainer "Kenji.I (Kenji Imakado)" . "ken.imakaado@gmail.com"))]) (helm-bundle-show . [(20151221 1230) ((helm (1 8 0))) "bundle show with helm interface" single ((:commit . "850fecb36f609f1dfd5d20ca0170c9a6b7f90ab9") (:authors ("Takashi Masuda" . "masutaka.net@gmail.com")) (:maintainer "Takashi Masuda" . "masutaka.net@gmail.com") (:url . "https://github.com/masutaka/emacs-helm-bundle-show"))]) (helm-books . [(20170325 631) ((helm (1 7 7))) "Helm interface for searching books" single ((:commit . "625aadec1541a5ca36951e4ce1301f4b6fe2bf3f") (:authors ("grugrut" . "grugruglut+github@gmail.com")) (:maintainer "grugrut" . "grugruglut+github@gmail.com") (:url . "https://github.com/grugrut/helm-books"))]) (helm-bm . [(20160321 1331) ((bm (1 0)) (cl-lib (0 5)) (helm (1 9 3)) (s (1 11 0))) "helm sources for bm.el" single ((:commit . "d66341f5646c23178d4d8bffb6cfebe3fb73f1d7") (:keywords "helm" "bookmark") (:authors ("Yasuyuki Oka" . "yasuyk@gmail.com")) (:maintainer "Yasuyuki Oka" . "yasuyk@gmail.com") (:url . "https://github.com/yasuyk/helm-bm"))]) (helm-bind-key . [(20141109 515) ((bind-key (1 0)) (helm (1 6 4))) "helm-source for for bind-key." single ((:commit . "9da6ad8b7530e72fb4ac67be8c6a482898dddc25") (:keywords "convenience" "emulation") (:authors ("Yuhei Maeda <yuhei.maeda_at_gmail.com>")) (:maintainer "myuhe"))]) (helm-bibtexkey . [(20140214 1504) ((helm (1 5 8))) "Bibtexkey source for helm" tar ((:commit . "aa1637ea5c8c5f1817e480fc2a3750cafab3d99f") (:keywords "bib" "tex") (:authors ("TAKAGI Kentaro <kentaro0910_at_gmail.com>")) (:maintainer "TAKAGI Kentaro <kentaro0910_at_gmail.com>") (:url . "https://github.com/kenbeese/helm-bibtexkey"))]) (helm-bibtex . [(20180826 1548) ((helm (1 5 5)) (parsebib (1 0)) (s (1 9 0)) (dash (2 6 0)) (f (0 16 2)) (cl-lib (0 5)) (biblio (0 2))) "A bibliography manager based on Helm" tar ((:commit . "b1a4f7d7c0dd3a258ee9f5cdc22b9a7847a2c4c6") (:authors ("Titus von der Malsburg" . "malsburg@posteo.de")) (:maintainer "Titus von der Malsburg" . "malsburg@posteo.de"))]) (helm-bbdb . [(20180505 1508) ((helm (1 5)) (bbdb (3 1 2))) "Helm interface for bbdb" single ((:commit . "db286b0ee0ea18142f7d005e465832bb755bb0cb") (:url . "https://github.com/emacs-helm/helm-bbdb"))]) (helm-backup . [(20171205 757) ((helm (1 5 5)) (s (1 8 0)) (cl-lib (0))) "Backup each file change using git" single ((:commit . "a2c0fa16113e628500d6822c6605280b94e24038") (:keywords "backup" "convenience" "files" "tools" "vc") (:authors ("Anthony HAMON" . "hamon.anth@gmail.com")) (:maintainer "Anthony HAMON" . "hamon.anth@gmail.com") (:url . "http://github.com/antham/helm-backup"))]) (helm-aws . [(20180514 1032) ((helm (1 5 3)) (cl-lib (0 5)) (s (1 9 0))) "Manage AWS EC2 server instances directly from Emacs" single ((:commit . "b36c744b3f00f458635a91d1f5158fccbb5baef6") (:authors ("istib")) (:maintainer "istib") (:url . "https://github.com/istib/helm-aws"))]) (helm-ag-r . [(20131123 1531) ((helm (1 0))) "Search something by ag and display by helm" single ((:commit . "67de4ebafe9b088db950eefa5ef590a6d78b4ac8") (:keywords "searching") (:authors ("Yuta Yamada <cokesboy\"at\"gmail.com>")) (:maintainer "Yuta Yamada <cokesboy\"at\"gmail.com>") (:url . "https://github.com/yuutayamada/helm-ag-r"))]) (helm-ag . [(20170209 1545) ((emacs (24 4)) (helm (2 0))) "the silver searcher with helm interface" single ((:commit . "2fc02c4ead29bf0db06fd70740cc7c364cb650ac") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-helm-ag"))]) (helm-addressbook . [(20170903 728) ((helm (2 8 2)) (addressbook-bookmark (1 0)) (cl-lib (0 5)) (emacs (24 4))) "Helm for addressbook bookmarks." single ((:commit . "62497f72d46afd3a9f9f94b27d062a82fb232de4") (:url . "https://github.com/emacs-helm/helm-addressbook"))]) (helm-ad . [(20151209 1015) ((dash (2 8 0)) (helm (1 6 2))) "helm source for Active Directory" single ((:commit . "8ac044705d8620ee354a9cfa8cc1b865e83c0d55") (:keywords "comm") (:authors ("Takahiro Noda" . "takahiro.noda+github@gmail.com")) (:maintainer "Takahiro Noda" . "takahiro.noda+github@gmail.com"))]) (helm-ack . [(20141030 1226) ((helm (1 0)) (cl-lib (0 5))) "Ack command with helm interface" single ((:commit . "889bc225318d14c6e3be80e73b1d9d6fb30e48c3") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-helm-ack"))]) (helm-R . [(20120820 14) ((helm (20120517)) (ess (20120509))) "helm-sources and some utilities for GNU R." single ((:commit . "b0eb9d5f6a483a9dbe6eb6cf1f2024d4f5938bc2") (:keywords "convenience") (:authors ("myuhe <yuhei.maeda_at_gmail.com>")) (:maintainer "myuhe") (:url . "https://github.com/myuhe/helm-R.el"))]) (helm . [(20180831 1450) ((emacs (24 4)) (async (1 9 3)) (popup (0 5 3)) (helm-core (3 0))) "Helm is an Emacs incremental and narrowing framework" tar ((:commit . "3f3bfa4f4b4ed163bd1b36690fd63ff40ce14669") (:url . "https://emacs-helm.github.io/helm/"))]) (heaven-and-hell . [(20180421 921) ((emacs (24 4))) "easy toggle light/dark themes" single ((:commit . "0e4191065a1c18b50734a437f3cafb629b89edc0") (:keywords "faces") (:authors ("Valentin Ignatev" . "valentignatev@gmail.com")) (:maintainer "Valentin Ignatev" . "valentignatev@gmail.com") (:url . "https://github.com/valignatev/heaven-and-hell"))]) (headlong . [(20150417 1526) nil "reckless completion" single ((:commit . "f6830f87f236eee88263cb6976125f72422abe72") (:keywords "completion") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:url . "https://github.com/abo-abo/headlong"))]) (hcl-mode . [(20170107 827) ((emacs (24 3))) "Major mode for Hashicorp" single ((:commit . "0f2c5ec7e7bcf77c8548e8cac8721ea935ca1b5e") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-hcl-mode"))]) (hc-zenburn-theme . [(20150928 1633) nil "An higher contrast version of the Zenburn theme." single ((:commit . "fd0024a5191cdce204d91c8f1db99ba31640f6e9") (:authors ("Nantas Nardelli" . "nantas.nardelli@gmail.com")) (:maintainer "Nantas Nardelli" . "nantas.nardelli@gmail.com") (:url . "https:github.com/edran/hc-zenburn-emacs"))]) (hayoo . [(20140831 1221) ((emacs (24)) (json (1 3))) "Query hayoo and show results in a tabulated buffer." single ((:commit . "3ca2fb0c4d5f337d0410c21b2702dd147014e984") (:keywords "hayoo" "haskell") (:authors ("Marko Bencun" . "mbencun@gmail.com")) (:maintainer "Marko Bencun" . "mbencun@gmail.com") (:url . "https://github.com/benma/hayoo.el/"))]) (haxor-mode . [(20160618 1129) ((emacs (24 0))) "Major mode for editing Haxor Assembly Files" single ((:commit . "6fa25a8e6b6a59481bc0354c2fe1e0ed53cbdc91") (:keywords "haxor") (:authors ("Krzysztof Magosa" . "krzysztof@magosa.pl")) (:maintainer "Krzysztof Magosa" . "krzysztof@magosa.pl") (:url . "https://github.com/krzysztof-magosa/haxor-mode"))]) (haxe-mode . [(20131004 842) nil "An Emacs major mode for Haxe" single ((:authors ("Jens Peter Secher")) (:maintainer "Jens Peter Secher") (:url . "http://people.debian.org/~jps/misc/haxe-mode.el"))]) (haxe-imports . [(20170330 2304) ((emacs (24 4)) (s (1 10 0)) (pcache (0 3 1))) "Code for dealing with Haxe imports" single ((:commit . "f104a641f3dfe698359d9aca1f28d9383cf43e04") (:keywords "haxe") (:authors ("Juan Karlo Licudine" . "karlo@accidentalrebel.com")) (:maintainer "Juan Karlo Licudine" . "karlo@accidentalrebel.com") (:url . "http://www.github.com/accidentalrebel/emacs-haxe-imports"))]) (haste . [(20141030 2034) ((json (1 2))) "Emacs client for hastebin (http://hastebin.com/about.md)" single ((:commit . "22d05aacc3296ab50a7361222ab139fb4d447c25") (:authors ("Ric Lister")) (:maintainer "Ric Lister") (:url . "http://github.com/rlister/emacs-haste-client"))]) (hasky-stack . [(20180331 908) ((emacs (24 4)) (f (0 18 0)) (magit-popup (2 10))) "Interface to the Stack Haskell development tool" single ((:commit . "3e17ce07dd6b0207474e4ff14ad7b8c467382947") (:keywords "tools" "haskell") (:authors ("Mark Karpov" . "markkarpov92@gmail.com")) (:maintainer "Mark Karpov" . "markkarpov92@gmail.com") (:url . "https://github.com/hasky-mode/hasky-stack"))]) (hasky-extensions . [(20180108 512) ((emacs (24 4)) (avy-menu (0 2))) "Toggle Haskell language extensions" single ((:commit . "6909022bccb7e5c26d1c4e5fa20cbc6b65c62d69") (:keywords "programming") (:authors ("Mark Karpov" . "markkarpov92@gmail.com")) (:maintainer "Mark Karpov" . "markkarpov92@gmail.com") (:url . "https://github.com/hasky-mode/hasky-extensions"))]) (haskell-tab-indent . [(20170701 958) nil "tab-based indentation for haskell-mode" single ((:commit . "b4cb851aef96c42ec7b3cc37b6fdd867fe5a0853") (:keywords "indentation" "haskell") (:authors ("Sean Whitton" . "spwhitton@spwhitton.name")) (:maintainer "Sean Whitton" . "spwhitton@spwhitton.name") (:url . "https://spwhitton.name/tech/code/haskell-tab-indent/"))]) (haskell-snippets . [(20160919 22) ((cl-lib (0 5)) (yasnippet (0 8 0))) "Yasnippets for Haskell" tar ((:commit . "07b0f460b946fd1be26c29652cb0468b47782f3a") (:keywords "snippets" "haskell") (:authors ("Luke Hoersten" . "luke@hoersten.org")) (:maintainer "Luke Hoersten" . "luke@hoersten.org") (:url . "https://github.com/haskell/haskell-snippets"))]) (haskell-mode . [(20180601 843) ((emacs (24 3))) "A Haskell editing mode" tar ((:commit . "dd0ea640fa449d021399a17db65e4d50d3f0f2a9") (:keywords "haskell" "cabal" "ghc" "repl") (:url . "https://github.com/haskell/haskell-mode"))]) (haskell-emacs-text . [(20150713 1416) ((haskell-emacs (2 4 0))) "Haskell functions from Data.Text" tar ((:commit . "a2c6a079175904689eed7c6c200754bfa85d1ed9") (:keywords "haskell" "emacs" "ffi") (:authors ("Florian Knupfer")) (:maintainer "Florian Knupfer") (:url . "https://github.com/knupfer/haskell-emacs/modules/text"))]) (haskell-emacs-base . [(20150714 1559) ((haskell-emacs (2 4 0))) "Haskell functions from Prelude" tar ((:commit . "a2c6a079175904689eed7c6c200754bfa85d1ed9") (:keywords "haskell" "emacs" "ffi") (:authors ("Florian Knupfer")) (:maintainer "Florian Knupfer") (:url . "https://github.com/knupfer/haskell-emacs/modules/base"))]) (haskell-emacs . [(20160904 2026) nil "Write emacs extensions in haskell" tar ((:commit . "a2c6a079175904689eed7c6c200754bfa85d1ed9") (:keywords "haskell" "emacs" "ffi") (:authors ("Florian Knupfer")) (:maintainer "Florian Knupfer") (:url . "https://github.com/knupfer/haskell-emacs"))]) (harvest . [(20170822 1746) ((swiper (0 7 0)) (hydra (0 13 0)) (s (1 11 0))) "Harvest integration" single ((:commit . "7acbc0564b250521b67131ee2a0a92720239454f") (:keywords "harvest") (:authors ("Kosta Harlan" . "kosta@kostaharlan.net")) (:maintainer "Kosta Harlan" . "kosta@kostaharlan.net") (:url . "https://github.com/kostajh/harvest.el"))]) (hardhat . [(20160414 1413) ((ignoramus (0 7 0))) "Protect against clobbering user-writable files" single ((:commit . "9038a49ab55cd4c502cf7f07ed0d1b9b6bc3626e") (:keywords "convenience") (:authors ("Roland Walker" . "walker@pobox.com")) (:maintainer "Roland Walker" . "walker@pobox.com") (:url . "http://github.com/rolandwalker/hardhat"))]) (hardcore-mode . [(20151114 701) nil "Disable arrow keys + optionally backspace and return" single ((:commit . "b1dda19692b4a7a58a689e81784a9b35be39e70d") (:authors ("Magnar Sveen" . "magnars@gmail.com")) (:maintainer "Magnar Sveen" . "magnars@gmail.com"))]) (handoff . [(20150917 600) nil "Get your hand off that mouse, damn it!" single ((:commit . "75dc7a7e352f38679f65d0ca80ad158798e168bd") (:authors ("Johan Andersson" . "johan.rejeep@gmail.com")) (:maintainer "Johan Andersson" . "johan.rejeep@gmail.com") (:url . "http://github.com/rejeep/handoff.el"))]) (handlebars-sgml-mode . [(20130623 2333) nil "Add Handlebars contextual indenting support to sgml-mode" single ((:commit . "c76df93a9a8c1b1b3efdcc4add32bf93304192a4") (:authors ("Geoff Jacobsen" . "geoffjacobsen@gmail.com")) (:maintainer "Geoff Jacobsen" . "geoffjacobsen@gmail.com") (:url . "http://github.com/jacott/handlebars-sgml-mode"))]) (handlebars-mode . [(20150211 1749) nil "A major mode for editing Handlebars files." single ((:commit . "81f6b73fea8f397807781a1b51568397af21a6ef") (:authors ("Tony Gentilcore") ("Chris Wanstrath") ("Daniel Hackney") ("Daniel Evans")) (:maintainer "Tony Gentilcore"))]) (hamlet-mode . [(20131208 724) ((cl-lib (0 3)) (dash (2 3 0)) (s (1 7 0))) "Hamlet editing mode" single ((:commit . "7362b955e556a3d007fa06945a27e5b99349527d") (:keywords "wp" "languages" "comm") (:authors (nil . "Kata <lightquake@amateurtopologist.com")) (:maintainer nil . "Kata <lightquake@amateurtopologist.com") (:url . "https://github.com/lightquake/hamlet-mode"))]) (haml-mode . [(20170924 453) ((emacs (24)) (cl-lib (0 5))) "Major mode for editing Haml files" single ((:commit . "1cbb2de8f0fc25f35448c5cad04642f28078f3bb") (:keywords "markup" "languages" "html") (:authors ("Natalie Weizenbaum")) (:maintainer "Natalie Weizenbaum") (:url . "https://github.com/nex3/haml-mode"))]) (hamburger-menu . [(20160825 2031) ((emacs (24 5))) "Mode line hamburger menu" single ((:commit . "3568159c693c30bed7f61580e4f3b6241253ad4e") (:keywords "hamburger" "menu") (:authors ("Iain Nicol")) (:maintainer "Iain Nicol") (:url . "https://gitlab.com/iain/hamburger-menu-mode"))]) (hamburg-theme . [(20160123 740) ((emacs (24))) "Color Theme with a dark blue background." single ((:commit . "aacefdf1501d97a5afc0e63c8ead4b2463323028") (:authors ("Martin Haesler")) (:maintainer "Martin Haesler"))]) (ham-mode . [(20150811 1306) ((html-to-markdown (1 2)) (markdown-mode (2 0))) "Html As Markdown. Transparently edit an html file using markdown" single ((:commit . "3a141986a21c2aa6eefb428983352abb8b7907d2") (:keywords "convenience" "emulation" "wp") (:authors ("Artur Malabarba" . "bruce.connor.am@gmail.com")) (:maintainer "Artur Malabarba" . "bruce.connor.am@gmail.com") (:url . "http://github.com/Bruce-Connor/ham-mode"))]) (hal-mode . [(20160704 1746) nil "Major mode for editing HAL files" single ((:commit . "cd2f66f219ee520198d4586fb6b169cef7ad3f21") (:keywords "language") (:authors ("Alexander Rössler")) (:maintainer "Alexander Rössler") (:url . "https://github.com/strahlex/hal-mode/"))]) (hackernews . [(20180903 612) ((json (1 2))) "Access the Hacker News aggregator from Emacs" tar ((:commit . "d8c450bbc76d6bb65ec5cdb6c3b888a23f3769e9"))]) (hacker-typer . [(20170206 1520) ((emacs (24))) "Pretend to write code like a pro" tar ((:commit . "d5a23714a4ccc5071580622f278597d5973f40bd") (:keywords "hacker" "typer" "multimedia" "games") (:authors ("Diego A. Mundo" . "diegoamundo@gmail.com")) (:maintainer "Diego A. Mundo" . "diegoamundo@gmail.com") (:url . "http://github.com/therockmandolinist/emacs-hacker-typer"))]) (hack-time-mode . [(20170527 1610) ((emacs (24 4))) "Forge time" single ((:commit . "73d6fcf8b39283526e5d4e3919193611e25a0898") (:keywords "time" "convenience") (:authors ("Marco Wahl" . "marcowahlsoft@gmail.com")) (:maintainer "Marco Wahl" . "marcowahlsoft@gmail.com") (:url . "https://gitlab.com/marcowahl/hack-time-mode"))]) (hack-mode . [(20180830 2107) ((emacs (25 1))) "Major mode for the Hack programming language" tar ((:commit . "36c005d5617a944f19853649344a915a48f6b9a0") (:authors ("John Allen" . "jallen@fb.com")) (:maintainer "John Allen" . "jallen@fb.com") (:url . "https://github.com/hhvm/hack-mode"))]) (habitica . [(20171023 222) ((org (8 3 5)) (emacs (24 3))) "Interface for habitica.com" single ((:commit . "e51ff7436fe1da10404e2c0872b15d6a7a926717") (:keywords "habitica" "todo") (:authors ("Adrien Brochard")) (:maintainer "Adrien Brochard") (:url . "https://github.com/abrochard/emacs-habitica"))]) (habamax-theme . [(20180820 919) ((emacs (24))) "Boring white background color that gets the job done." single ((:commit . "23a87d831f35ec0a187a2bd9aa8ffbe06e671f8e") (:authors ("Maxim Kim" . "habamax@gmail.com")) (:maintainer "Maxim Kim" . "habamax@gmail.com") (:url . "https://github.com/habamax/habamax-theme"))]) (gxref . [(20170411 1753) ((emacs (25))) "xref backend using GNU Global." single ((:commit . "380b02c3c3c2586c828456716eef6a6392bb043b") (:keywords "xref" "global" "tools") (:authors ("Dedi Hirschfeld")) (:maintainer "Dedi Hirschfeld") (:url . "https://github.com/dedi/gxref"))]) (gvpr-mode . [(20131208 1718) nil "A major mode offering basic syntax coloring for gvpr scripts." single ((:commit . "3d6cc6f4416faf2a1913821d12ba6eb624362af0") (:keywords "graphviz" "gv" "dot" "gvpr" "graph") (:authors ("Rod Waldhoff" . "r.waldhoff@gmail.com")) (:maintainer "Rod Waldhoff" . "r.waldhoff@gmail.com") (:url . "https://raw.github.com/rodw/gvpr-lib/master/extra/gvpr-mode.el"))]) (guru-mode . [(20170730 731) nil "Become an Emacs guru" single ((:commit . "c180e05ebc1484764aad245c85b69de779826e4e") (:keywords "convenience") (:authors ("Bozhidar Batsov")) (:maintainer "Bozhidar Batsov") (:url . "https://github.com/bbatsov/guru-mode"))]) (gulp-task-runner . [(20170718 2041) nil "Gulp task runner" single ((:commit . "877990e956b1d71e2d9c7c3e5a129ad199b9debb") (:keywords "convenience" "javascript") (:authors ("Nicolas Petton" . "nicolas@petton.fr")) (:maintainer "Nicolas Petton" . "nicolas@petton.fr"))]) (guix . [(20180812 1949) ((emacs (24 3)) (dash (2 11 0)) (geiser (0 8)) (bui (1 1 0)) (magit-popup (2 1 0)) (edit-indirect (0 1 4))) "Interface for GNU Guix" tar ((:commit . "1ed98be606d41356725f7a9fd1d7f981427aa53a") (:keywords "tools") (:authors ("Alex Kost" . "alezost@gmail.com")) (:maintainer "Alex Kost" . "alezost@gmail.com") (:url . "https://emacs-guix.gitlab.io/website/"))]) (guide-key-tip . [(20161011 823) ((guide-key (1 2 3)) (pos-tip (0 4 5))) "Show guide-key.el hints using pos-tip.el" single ((:commit . "02c5d4b0b65f3e91be5a47f0ff1ae5e86e00c64e") (:keywords "help" "convenience" "tooltip") (:authors ("Hiroaki Otsu" . "ootsuhiroaki@gmail.com")) (:maintainer "Hiroaki Otsu" . "ootsuhiroaki@gmail.com") (:url . "https://github.com/aki2o/guide-key-tip"))]) (guide-key . [(20150108 635) ((dash (2 10 0)) (popwin (0 3 0)) (s (1 9 0))) "Guide the following key bindings automatically and dynamically" single ((:commit . "9236d287a7272e307fb941237390a96037c8c0a2") (:keywords "help" "convenience") (:authors ("Tsunenobu Kai" . "kai2nenobu@gmail.com")) (:maintainer "Tsunenobu Kai" . "kai2nenobu@gmail.com") (:url . "https://github.com/kai2nenobu/guide-key"))]) (guess-language . [(20170620 1008) ((cl-lib (0 5)) (emacs (24))) "Robust automatic language detection" tar ((:commit . "1f1602f74d7159e7fb8c90f92ec5a3d1df5429da") (:authors ("Titus von der Malsburg" . "malsburg@posteo.de")) (:maintainer "Titus von der Malsburg" . "malsburg@posteo.de") (:url . "https://github.com/tmalsburg/guess-language.el"))]) (gtk-pomodoro-indicator . [(20171230 1640) nil "A pomodoro indicator for the GTK tray" tar ((:commit . "eb59b229de0dde307b20654075a9bbac69899a66") (:keywords "convenience" "pomodoro") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:url . "https://github.com/abo-abo/gtk-pomodoro-indicator"))]) (gscholar-bibtex . [(20170913 2157) nil "Retrieve BibTeX from Google Scholar and other online sources(ACM, IEEE, DBLP)" single ((:commit . "ba4ce159e385d695d8560e8b06b3cbe48424861c") (:keywords "extensions") (:authors ("Junpeng Qiu" . "qjpchmail@gmail.com")) (:maintainer "Junpeng Qiu" . "qjpchmail@gmail.com"))]) (gs-mode . [(20151202 1006) nil "Major mode for editing GrADS script files" single ((:commit . "1a13051db21b999c7682a015b33a03096ff9d891") (:keywords "grads" "script" "major-mode") (:authors ("Joe Wielgosz" . "joew@cola.iges.org")) (:maintainer "Joe Wielgosz" . "joew@cola.iges.org"))]) (gruvbox-theme . [(20180624 309) ((autothemer (0 2))) "A retro-groove colour theme for Emacs" tar ((:commit . "796999e5db2a0e43ad64c062c1bec3c966d095bc") (:authors ("Jason Milkins" . "jasonm23@gmail.com")) (:maintainer "Jason Milkins" . "jasonm23@gmail.com") (:url . "http://github.com/greduan/emacs-theme-gruvbox"))]) (grunt . [(20160316 1528) ((dash (2 9 0)) (ansi-color (3 4 2)) (emacs (24 3))) "Some glue to stick Emacs and Gruntfiles together" single ((:commit . "4c269e2738658643ec2ed9ef61a2a3d71b08d304") (:keywords "convenience" "grunt") (:authors ("Daniel Gempesaw" . "dgempesaw@sharecare.com")) (:maintainer "Daniel Gempesaw" . "dgempesaw@sharecare.com") (:url . "https://github.com/gempesaw/grunt.el"))]) (gruber-darker-theme . [(20180529 712) nil "Gruber Darker color theme for Emacs 24." single ((:commit . "c7687ec0511941db1371dcd70b31061d74aa5668") (:authors ("Alexey Kutepov" . "reximkut@gmail.com")) (:maintainer "Alexey Kutepov" . "reximkut@gmail.com") (:url . "http://github.com/rexim/gruber-darker-theme"))]) (groovy-mode . [(20180810 607) ((s (1 12 0)) (emacs (24 3)) (dash (2 13 0))) "Major mode for Groovy source files" tar ((:commit . "c32f82dd3a11be5871a71e8ffac55022bbbc5cfb") (:keywords "languages") (:authors ("Russel Winder" . "russel@winder.org.uk") ("Jim Morris" . "morris@wolfman.com") ("Wilfred Hughes" . "me@wilfred.me.uk")) (:maintainer "Russel Winder" . "russel@winder.org.uk"))]) (groovy-imports . [(20161003 851) ((emacs (24 4)) (s (1 10 0)) (pcache (0 3 2))) "Code for dealing with Groovy imports" single ((:commit . "e56d7dda617555ec6205644d32ffddf2e1fa43d9") (:keywords "groovy") (:authors ("Miro Bezjak")) (:maintainer "Miro Bezjak") (:url . "http://www.github.com/mbezjak/emacs-groovy-imports"))]) (grizzl . [(20160818 737) ((cl-lib (0 5)) (emacs (24 3))) "Fast fuzzy search index for Emacs." single ((:commit . "1e917253ce2b846f0272b8356fad3dbff9cd513a") (:keywords "convenience" "usability") (:authors ("Chris Corbyn" . "chris@w3style.co.uk")) (:maintainer "Bozhidar Batsov" . "bozhidar@batsov.com") (:url . "https://github.com/grizzl/grizzl"))]) (grin . [(20110806 658) nil "run grin and grind (python replacements for grep and find) putting hits in a grep buffer" single ((:keywords "python" "grin" "grind" "grep" "find") (:authors ("Darius Powell" . "dariusp686@gmail.com")) (:maintainer "Darius Powell" . "dariusp686@gmail.com") (:url . "http://bitbucket.org/dariusp686/emacs-grin"))]) (greymatters-theme . [(20150621 1123) ((emacs (24))) "Emacs 24 theme with a light background." single ((:commit . "a7220a8c6cf18ccae2b76946b6f01188a7c9d5d1") (:authors ("Martin Haesler")) (:maintainer "Martin Haesler"))]) (grep-context . [(20180415 1135) ((emacs (24 4)) (dash (2 12 0)) (cl-lib (0 5 0))) "Increase context in compilation and grep buffers" single ((:commit . "4c63d0f2654dee1e249c2054d118d674a757bd45") (:keywords "convenience" "search" "grep" "compile") (:authors ("Michał Kondraciuk" . "k.michal@zoho.com")) (:maintainer "Michał Kondraciuk" . "k.michal@zoho.com") (:url . "https://github.com/mkcms/grep-context"))]) (grep-a-lot . [(20131006 1347) nil "manages multiple search results buffers for grep.el" single ((:commit . "9f9f645b9e308a0d887b66864ff97d0fca1ba4ad") (:keywords "tools" "convenience" "search") (:authors ("Avi Rozen" . "avi.rozen@gmail.com")) (:maintainer "Avi Rozen" . "avi.rozen@gmail.com") (:url . "https://github.com/ZungBang/emacs-grep-a-lot"))]) (gregorio-mode . [(20170705 1451) nil "Gregorio Mode for .gabc files" single ((:commit . "736fd3d05fb67f707cca1a7ce24e3ee7ca5e9567") (:keywords "gregorio" "chant") (:authors ("Fr. John Jenkins" . "jenkins@sspx.ng")) (:maintainer "Fr. John Jenkins" . "jenkins@sspx.ng") (:url . "https://jsrjenkins.github.io/gregorio-mode/"))]) (green-screen-theme . [(20180816 1502) nil "A nice color theme for those who miss green CRTs" single ((:commit . "774e8f6c033786406267f71ec07319d906a30b75") (:keywords "faces" "theme") (:authors ("Ricardo Banffy" . "rbanffy@gmail.com")) (:maintainer "Ricardo Banffy" . "rbanffy@gmail.com") (:url . "https://github.com/rbanffy/green-screen-emacs"))]) (green-phosphor-theme . [(20150515 1447) nil "A light color theme with muted, autumnal colors." single ((:commit . "fa42f598626adfdc5450e5c380fa2d5df6110f28") (:keywords "color" "theme") (:authors ("Adam Alpern" . "adam.alpern@gmail.com")) (:maintainer "Adam Alpern" . "adam.alpern@gmail.com") (:url . "http://github.com/aalpern/emacs-color-theme-green-phosphor"))]) (green-is-the-new-black-theme . [(20180323 203) nil "A cool and minimalist green blackened theme engine" single ((:commit . "8a03687a2b8b55c5dc7f099086019278d505d8d8") (:keywords "faces" "themes") (:authors ("Fred Campos" . "fred.tecnologia@gmail.com")) (:maintainer "Fred Campos" . "fred.tecnologia@gmail.com") (:url . "https://github.com/fredcamps/green-is-the-new-black-emacs"))]) (grayscale-theme . [(20171005 802) nil "A simple grayscale theme" single ((:commit . "53ad50e10e68f2f076ebfc96e10ecef7a932d38d") (:keywords "lisp") (:authors ("Kaleb Elwert" . "belak@coded.io")) (:maintainer "Kaleb Elwert" . "belak@coded.io") (:url . "https://github.com/belak/emacs-grayscale-theme"))]) (grass-mode . [(20170503 1500) ((cl-lib (0 2)) (dash (2 8 0))) "Provides Emacs modes for interacting with the GRASS GIS program" single ((:keywords "grass" "gis") (:authors ("Tyler Smith" . "tyler@plantarum.ca")) (:maintainer "Tyler Smith" . "tyler@plantarum.ca"))]) (grapnel . [(20131001 1534) nil "HTTP request lib with flexible callback dispatch" single ((:commit . "fbd0f9a51139973d35e4014855964fa435e8ecaf") (:authors ("David Leatherman" . "leathekd@gmail.com")) (:maintainer "David Leatherman" . "leathekd@gmail.com") (:url . "http://www.github.com/leathekd/grapnel"))]) (graphviz-dot-mode . [(20171103 827) nil "Mode for the dot-language used by graphviz (att)." single ((:commit . "c456a2b65c734089e6c44e87209a5a432a741b1a") (:keywords "mode" "dot" "dot-language" "dotlanguage" "graphviz" "graphs" "att") (:maintainer "Pieter Pareit" . "pieter.pareit@gmail.com") (:url . "http://ppareit.github.com/graphviz-dot-mode/"))]) (graphql-mode . [(20180303 2358) ((emacs (24 3))) "Major mode for editing GraphQL schemas" single ((:commit . "36b1a4ed9fe78ccd1f386111644e69a5424a1a7b") (:keywords "languages") (:authors ("David Vazquez Pua" . "davazp@gmail.com")) (:maintainer "David Vazquez Pua" . "davazp@gmail.com"))]) (graphene-meta-theme . [(20161204 1607) nil "Integrated theming for common packages" single ((:commit . "62cc73fee31f1bd9474027b83a249feee050271e") (:keywords "defaults") (:authors ("Robert Dallas Gray" . "mail@robertdallasgray.com")) (:maintainer "Robert Dallas Gray" . "mail@robertdallasgray.com") (:url . "https://github.com/rdallasgray/graphene"))]) (graphene . [(20180529 1112) ((dash (2 10 0)) (exec-path-from-shell (1 9)) (ppd-sr-speedbar (0 0 6)) (sr-speedbar (20140505)) (ido-completing-read+ (4 3)) (smex (3 0)) (web-mode (11 2)) (smartparens (1 8 0)) (graphene-meta-theme (0 0 2)) (flycheck (0 23)) (company (0 8 12))) "Friendly Emacs defaults" tar ((:commit . "cc8477fcfb7771ea4e5bbaf3c01f9e679234c1c1"))]) (grandshell-theme . [(20180606 517) nil "Dark color theme for Emacs > 24 with intensive colors." tar ((:commit . "0ed8e4273607dd4fcaa742b4097259233b09eda6"))]) (grails-projectile-mode . [(20160327 1324) ((projectile (0 10 0)) (emacs (24)) (cl-lib (0 5))) "Grails mode with Projectile for projects management." tar ((:commit . "8efca50ce92b556fe9d467b157d7aec635bcc017") (:keywords "grails" "projectile") (:authors ("Yves Zoundi" . "rimerosolutions@gmail.com")) (:maintainer "Yves Zoundi") (:url . "https://github.com/yveszoundi/grails-projectile-mode"))]) (grails-mode . [(20160504 911) nil "minor-mode that adds some Grails project management to a grails project" single ((:commit . "c32f82dd3a11be5871a71e8ffac55022bbbc5cfb") (:keywords "languages") (:authors ("Jim Morris" . "morris@wolfman.com")) (:maintainer "Russel Winder" . "russel@winder.org.uk") (:url . "http://blog.wolfman.com"))]) (grails . [(20160417 636) ((emacs (24))) "Minor mode for Grails projects" single ((:commit . "fa638abe5c37f3f8af4fcd32f212453185ce50b1") (:url . "https://github.com/lifeisfoo/emacs-grails"))]) (gradle-mode . [(20150313 1905) ((s (1 8 0))) "Gradle integration with Emacs' compile" single ((:commit . "e4d665d5784ecda7ddfba015f07c69be3cfc45f2") (:keywords "gradle") (:authors ("Daniel Mijares" . "daniel.j.mijares@gmail.com")) (:maintainer "Daniel Mijares" . "daniel.j.mijares@gmail.com") (:url . "http://github.com/jacobono/emacs-gradle-mode"))]) (grab-x-link . [(20180205 1146) ((emacs (24)) (cl-lib (0 5))) "Grab links from X11 apps and insert into Emacs" single ((:commit . "d19f0c0da0ddc55005a4c1cdc2b8c5de8bea1e8c") (:keywords "hyperlink") (:authors ("Xu Chunyang" . "mail@xuchunyang.me")) (:maintainer "Xu Chunyang" . "mail@xuchunyang.me") (:url . "https://github.com/xuchunyang/grab-x-link"))]) (grab-mac-link . [(20180328 1445) ((emacs (24))) "Grab link from Mac Apps and insert it into Emacs" single ((:commit . "35edb57d136c2a9726fd14e6a59cce4fc0248771") (:keywords "mac" "hyperlink") (:authors ("Xu Chunyang" . "mail@xuchunyang.me")) (:maintainer "Xu Chunyang" . "mail@xuchunyang.me") (:url . "https://github.com/xuchunyang/grab-mac-link.el"))]) (gpastel . [(20180420 650) ((emacs (24 3))) "Integrates GPaste with the kill-ring" single ((:commit . "ae11a0ae58577321605c338809fc5ae29b38fc72") (:keywords "tools") (:authors ("Damien Cassou" . "damien@cassou.me")) (:maintainer "Damien Cassou" . "damien@cassou.me") (:url . "https://gitlab.petton.fr/DamienCassou/desktop-environment"))]) (govet . [(20170808 1724) nil "linter/problem finder for the Go source code" single ((:commit . "1c05817cf8b96589076c7ac4e52ee58a860a0cbf") (:url . "https://godoc.org/golang.org/x/tools/cmd/vet"))]) (govc . [(20180524 2023) ((emacs (24 3)) (dash (1 5 0)) (s (1 9 0)) (magit-popup (2 0 50)) (json-mode (1 6 0))) "Interface to govc for managing VMware ESXi and vCenter" single ((:commit . "bf3de044f4a9f0eee36171874ed82a892a2fbe92") (:keywords "convenience") (:authors ("The govc developers")) (:maintainer "The govc developers") (:url . "https://github.com/vmware/govmomi/tree/master/govc/emacs"))]) (goto-last-change . [(20150109 1823) nil "Move point through buffer-undo-list positions" single ((:commit . "58b0928bc255b47aad318cd183a5dce8f62199cc") (:keywords "convenience") (:authors ("Kevin Rodgers" . "ihs_4664@yahoo.com")) (:maintainer "Kevin Rodgers" . "ihs_4664@yahoo.com") (:url . "https://github.com/camdez/goto-last-change.el"))]) (goto-gem . [(20140729 1845) ((s (1 9 0))) "Open dired in gem directory" single ((:commit . "e3206f11f48bb7e798514a4ca2c2f60649613e5e") (:keywords "gemfile" "convenience") (:authors ("Peter Stiernström" . "peter@stiernstrom.se")) (:maintainer "Peter Stiernström" . "peter@stiernstrom.se"))]) (goto-chg . [(20180105 1833) nil "goto last change" single ((:commit . "e5b38e4e1378f6ea48fa9e8439f49c2998654aa4") (:keywords "convenience" "matching") (:authors ("David Andersson <l.david.andersson(at)sverige.nu>")) (:maintainer "Vasilij Schneidermann" . "v.schneidermann@github.com") (:url . "https://github.com/emacs-evil/goto-chg"))]) (gotham-theme . [(20171013 1916) nil "A very dark Emacs color theme." single ((:commit . "5e97554d1f9639698faedb0660e63694be33bd84") (:authors ("Vasilij Schneidermann" . "v.schneidermann@gmail.com")) (:maintainer "Vasilij Schneidermann" . "v.schneidermann@gmail.com") (:url . "https://github.com/wasamasa/gotham-theme"))]) (gotest . [(20180617 1333) ((emacs (24 3)) (s (1 11 0)) (f (0 19 0)) (go-mode (1 5 0))) "Launch GO unit tests" single ((:commit . "4b21b86c07a1597e5e3ca795603787906695ee1b") (:keywords "languages" "go" "tests") (:authors ("Nicolas Lamirault" . "nicolas.lamirault@gmail.com")) (:maintainer "Nicolas Lamirault" . "nicolas.lamirault@gmail.com") (:url . "https://github.com/nlamirault/gotest.el"))]) (gorepl-mode . [(20170905 945) ((emacs (24)) (s (1 11 0)) (f (0 19 0)) (hydra (0 13 0))) "Go REPL Interactive Development in top of Gore" single ((:commit . "bbd27f6a0a77f484e2a3f082d70dc69da63ae52a") (:keywords "languages" "go" "golang" "gorepl") (:authors ("Manuel Alonso" . "manuteali@gmail.com")) (:maintainer "Manuel Alonso" . "manuteali@gmail.com") (:url . "http://www.github.com/manute/gorepl-mode"))]) (gore-mode . [(20151123 1927) ((go-mode (1 0 0))) "Simple mode for gore, a command-line evaluator for golang." single ((:commit . "94d7f3e99104e06167967c98fdc201049c433c2d") (:keywords "go" "repl") (:authors ("Sergey Pashaev" . "sergey.pashaev@gmail.com")) (:maintainer "Sergey Pashaev" . "sergey.pashaev@gmail.com"))]) (goose-theme . [(20160828 1245) ((emacs (24 1))) "A gray color theme" single ((:commit . "acd017b50ab25a75fd1331eb3de66467e2042e9c") (:authors ("Stephen Whipple" . "shw@wicdmedia.org")) (:maintainer "Stephen Whipple" . "shw@wicdmedia.org") (:url . "https://github.com/thwg/goose-theme"))]) (google-translate . [(20170713 819) nil "Emacs interface to Google Translate." tar ((:commit . "d8b84a8359fcc697114d1298840e9a45b111c974"))]) (google-this . [(20170810 1215) ((emacs (24 1))) "A set of functions and bindings to google under point." single ((:commit . "8a2e3ca5da6a8c89bfe99a21486c6c7db125dc84") (:keywords "convenience" "hypermedia") (:authors ("Artur Malabarba" . "bruce.connor.am@gmail.com")) (:maintainer "Artur Malabarba" . "bruce.connor.am@gmail.com") (:url . "http://github.com/Malabarba/emacs-google-this"))]) (google-maps . [(20171002 1434) ((emacs (24 3))) "Access Google Maps from Emacs" tar ((:commit . "c0e5dccfdc9f7f77ff8f29177547be47833d7156") (:keywords "comm") (:authors ("Julien Danjou" . "julien@danjou.info")) (:maintainer "Julien Danjou" . "julien@danjou.info") (:url . "https://julien.danjou.info/projects/emacs-packages#google-maps"))]) (google-contacts . [(20171027 1733) ((oauth2 (0 10)) (cl-lib (0 5))) "Support for Google Contacts in Emacs" tar ((:commit . "a40389bae006ae094aeb1a39fae9891ca687c0fa") (:keywords "comm") (:authors ("Julien Danjou" . "julien@danjou.info")) (:maintainer "Julien Danjou" . "julien@danjou.info") (:url . "http://julien.danjou.info/projects/emacs-packages#google-contacts"))]) (google-c-style . [(20180130 1736) nil "Google's C/C++ style for c-mode" single ((:commit . "d3881b4fa910526f0e60e56d0110a9c6492949d8") (:keywords "c" "tools"))]) (google . [(20140416 1748) nil "Emacs interface to the Google API" single ((:commit . "3b3189a8b201c8d36fed6e61496274e530dd40bd") (:keywords "comm" "processes" "tools") (:authors ("Edward O'Connor" . "ted@oconnor.cx")) (:maintainer "Edward O'Connor" . "ted@oconnor.cx"))]) (gom-mode . [(20131008 253) nil "Major mode for Gomfile" single ((:commit . "972e33df1d38ff323bc97de87477305826013701") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-gom-mode"))]) (golint . [(20180221 2015) nil "lint for the Go source code" single ((:commit . "06c8688daad7faa9da5a0c2f163a3d14aac986ca") (:url . "https://github.com/golang/lint"))]) (goldendict . [(20180121 920) ((emacs (24 4)) (cl-lib (0 5))) "query word smartly with goldendict.el" single ((:commit . "1aac19daaec811deb9afe45eea4929309c09ac8b") (:keywords "dict" "goldendict") (:url . "https://github.com/stardiviner/goldendict.el"))]) (golden-ratio-scroll-screen . [(20170224 229) nil "Scroll half screen down or up, and highlight current line" single ((:commit . "44e947194d3e5cbe0fd2f3c4886a4e6e1a0c0791") (:keywords "scroll" "screen" "highlight") (:authors ("纪秀峰 <jixiuf at gmail dot com>")) (:maintainer "纪秀峰 <jixiuf at gmail dot com>") (:url . "https://github.com/jixiuf/golden-ratio-scroll-screen"))]) (golden-ratio . [(20150819 1120) nil "Automatic resizing of Emacs windows to the golden ratio" single ((:commit . "72b028808b41d23fa3f7e8c0d23d2c475e7b46ae") (:keywords "window" "resizing") (:authors ("Roman Gonzalez" . "romanandreg@gmail.com")) (:maintainer "Roman Gonzalez" . "romanandreg@gmail.com"))]) (gold-mode . [(20140607 206) ((sws-mode (0))) "Major mode for editing .gold files" single ((:commit . "6d3aa59602b1b835495271c8c9741ac344c2eab1") (:keywords "golang" "template" "gold") (:authors ("Yuta Yamada <cokesboy\"at\"gmail.com>")) (:maintainer "Yuta Yamada <cokesboy\"at\"gmail.com>") (:url . "https://github.com/yuutayamada/gold-mode-el"))]) (godoctor . [(20180710 2152) nil "Frontend for godoctor" single ((:commit . "4b45ff3d0572f0e84056e4c3ba91fcc178199859") (:keywords "go" "golang" "refactoring") (:authors ("Sangho Na" . "microamp@protonmail.com")) (:maintainer "Sangho Na" . "microamp@protonmail.com") (:url . "https://github.com/microamp/godoctor.el"))]) (god-mode . [(20180117 1134) nil "God-like command entering minor mode" tar ((:commit . "344167ed9b4c212273dd056e7481cf1373b461d0") (:authors ("Chris Done" . "chrisdone@gmail.com")) (:maintainer "Chris Done" . "chrisdone@gmail.com") (:url . "https://github.com/chrisdone/god-mode"))]) (gobgen . [(20161020 1523) ((emacs (24 4))) "Generate GObject descendants using a detailed form" single ((:commit . "ed2c2b0d217deae293096f3cf14aa492791ddd4f") (:keywords "gobject" "glib" "gtk" "helper" "utilities") (:authors ("Gergely Polonkai" . "gergely@polonkai.eu")) (:maintainer "Gergely Polonkai" . "gergely@polonkai.eu"))]) (go-tag . [(20180227 411) ((emacs (24 0)) (go-mode (1 5 0))) "Edit Golang struct field tag" single ((:commit . "59b243f2fa079d9de9d56f6e2d94397e9560310a") (:keywords "tools") (:authors ("Brantou" . "brantou89@gmail.com")) (:maintainer "Brantou" . "brantou89@gmail.com") (:url . "https://github.com/brantou/emacs-go-tag"))]) (go-stacktracer . [(20150430 2142) nil "parse Go stack traces" single ((:commit . "a2ac6d801b389f80ca4e2fcc1ab44513a9e55976") (:keywords "tools") (:authors ("Samer Masterson" . "samer@samertm.com")) (:maintainer "Samer Masterson" . "samer@samertm.com") (:url . "https://github.com/samertm/go-stacktracer.el"))]) (go-snippets . [(20180113 611) ((yasnippet (0 8 0))) "Yasnippets for go" tar ((:commit . "d437df148879566ffe7f2e503a3cf2602aa9fb28"))]) (go-scratch . [(20150810 440) ((go-mode (1 3 1)) (emacs (24))) "*scratch* buffer for Go" single ((:commit . "3f68cbcce04f59eb8e83af109164731ec0454be0") (:keywords "languages" "go") (:authors ("Emanuel Evans" . "mail@emanuel.industries")) (:maintainer "Emanuel Evans" . "mail@emanuel.industries"))]) (go-rename . [(20180627 648) ((go-mode (1 3 1))) "Integration of the 'gorename' tool into Emacs." single ((:commit . "7f87c32464d2eb22ac7a413cac741a89fbfdc740") (:keywords "tools"))]) (go-projectile . [(20180808 1822) ((projectile (0 10 0)) (go-mode (0)) (go-eldoc (0 16)) (go-rename (0)) (go-guru (0))) "Go add-ons for Projectile" single ((:commit . "11989b104a4bef406bf0e7b31ef6608aa6057cf7") (:keywords "project" "convenience") (:authors ("Doug MacEachern" . "dougm@vmware.com")) (:maintainer "Doug MacEachern" . "dougm@vmware.com") (:url . "https://github.com/dougm/go-projectile"))]) (go-playground-cli . [(20160503 914) ((emacs (24)) (request (0 2 0)) (deferred (0 3 2)) (names (20151201 404)) (s (1 10 0)) (f (0 17 2)) (let-alist (1 0 4)) (cl-lib (0 5))) "Go Playground client tool" single ((:commit . "60beebd98e3930641d41cee0189c579626f223bc") (:authors ("KOBAYASHI Shigeru (kosh)" . "shigeru.kb@gmail.com")) (:maintainer "KOBAYASHI Shigeru (kosh)" . "shigeru.kb@gmail.com") (:url . "https://github.com/kosh04/go-playground-cli"))]) (go-playground . [(20170226 843) ((emacs (24)) (go-mode (1 4 0)) (gotest (0 13 0))) "Local Golang playground for short snippets." single ((:commit . "559d53bbc507394aaca3683325d17286637bf4f0") (:keywords "tools" "golang") (:authors ("Alexander I.Grafov (axel)" . "grafov@gmail.com")) (:maintainer "Alexander I.Grafov (axel)" . "grafov@gmail.com") (:url . "https://github.com/grafov/go-playground"))]) (go-mode . [(20180327 1530) nil "Major mode for the Go programming language" single ((:commit . "7f87c32464d2eb22ac7a413cac741a89fbfdc740") (:keywords "languages" "go") (:authors ("The go-mode Authors")) (:maintainer "The go-mode Authors") (:url . "https://github.com/dominikh/go-mode.el"))]) (go-imports . [(20180710 528) nil "Insert go import statement given package name" tar ((:commit . "d9950309c868aa46c45f8671413e53f97dc7fe0b") (:keywords "tools" "go" "import") (:authors ("Yaz Saito")) (:maintainer "Yaz Saito") (:url . "https://github.com/yasushi-saito/go-imports"))]) (go-impl . [(20170125 1552) ((emacs (24 3)) (go-mode (1 3 0))) "impl integration for go-mode" single ((:commit . "69f0d0ef05771487e15abec500cd06befd171abf") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-go-impl"))]) (go-guru . [(20180628 1010) ((go-mode (1 3 1)) (cl-lib (0 5))) "Integration of the Go 'guru' analysis tool into Emacs." single ((:commit . "7f87c32464d2eb22ac7a413cac741a89fbfdc740") (:keywords "tools"))]) (go-gopath . [(20160705 1034) ((cl-lib (0 5))) "Will guess GOPATH using gb and projectile." single ((:commit . "5172fc53f21edbf9347d5ee7d1d745da1ec88a15") (:authors ("Andrew Kirilenko" . "andrew.kirilenko.main@gmail.com")) (:maintainer "Andrew Kirilenko" . "andrew.kirilenko.main@gmail.com") (:url . "http://github.com/iced/go-gopath/"))]) (go-gen-test . [(20171023 358) ((emacs (24 3)) (s (1 12))) "Generate tests for go code with gotests" single ((:commit . "44c202ac97e728e93a35cee028a0ea8dd6e4292c") (:keywords "languages") (:authors ("Sergey Kostyaev" . "feo.me@ya.ru")) (:maintainer "Sergey Kostyaev" . "feo.me@ya.ru") (:url . "https://github.com/s-kostyaev/go-gen-test"))]) (go-fill-struct . [(20171225 331) ((emacs (24))) "Fill struct for golang." single ((:commit . "a613d0b378473eef39e8fd5724abe790aea84321") (:keywords "tools") (:authors ("Sergey Kostyaev" . "feo.me@ya.ru")) (:maintainer "Sergey Kostyaev" . "feo.me@ya.ru") (:url . "https://github.com/s-kostyaev/go-fill-struct"))]) (go-errcheck . [(20160723 43) nil "errcheck integration for go-mode" single ((:commit . "9db21eccecedc2490793f176246094167164af31") (:authors ("Dominik Honnef" . "dominikh@fork-bomb.org")) (:maintainer "Dominik Honnef" . "dominikh@fork-bomb.org"))]) (go-eldoc . [(20170305 1427) ((emacs (24 3)) (go-mode (1 0 0))) "eldoc for go-mode" single ((:commit . "cbbd2ea1e94a36004432a9ac61414cb5a95a39bd") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-go-eldoc"))]) (go-dlv . [(20160517 2046) ((go-mode (1 3 1))) "Go Delve - Debug Go programs interactively with the GUD." single ((:commit . "45a9e8a047c9995eb7c802268d96b3e527569f41") (:keywords "go" "debug" "debugger" "delve" "interactive" "gud") (:authors ("Marko Bencun" . "mbencun@gmail.com")) (:maintainer "Marko Bencun" . "mbencun@gmail.com") (:url . "https://github.com/benma/go-dlv.el/"))]) (go-direx . [(20150316 143) ((direx (1 0 0)) (cl-lib (0 5))) "Tree style source code viewer for Go language" single ((:commit . "8f2206469328ee932c7f1892f5e1fb02dec98432") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-go-direx"))]) (go-complete . [(20151015 928) ((go-mode (0)) (cl-lib (0 5))) "Native code completion for Go" single ((:commit . "e39efc356f6e19f17db3f3d2c81f28d38b31a55e") (:keywords "go" "golang" "completion") (:authors ("Vibhav Pant" . "vibhavp@gmail.com")) (:maintainer "Vibhav Pant" . "vibhavp@gmail.com") (:url . "https://github.com/vibhavp/go-complete"))]) (go-autocomplete . [(20170626 1023) ((auto-complete (1 4 0))) "auto-complete-mode backend for go-mode" single ((:commit . "7b1d4e18cdc58a74dc1bd4c2d45b3f1b2ca227c3") (:keywords "languages") (:authors ("Mikhail" . "tensai@cirno.in")) (:maintainer "Mikhail" . "tensai@cirno.in"))]) (go-add-tags . [(20161123 1227) ((emacs (24 3)) (s (1 11 0))) "Add field tags for struct fields" single ((:commit . "54879945e46a0884c5f93d7fd6c866a9cdf401ac") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-go-add-tags"))]) (go . [(20161111 249) ((emacs (24))) "Play GO, translate and transfer between GO back ends" tar ((:commit . "ff45fb44d9cb6579d8511d8b6156ed0b34d5ac97") (:keywords "game" "go" "sgf") (:authors ("Eric Schulte" . "schulte.eric@gmail.com")) (:maintainer "Eric Schulte" . "schulte.eric@gmail.com") (:url . "http://eschulte.github.io/el-go/"))]) (gnus-x-gm-raw . [(20140610 731) ((log4e (0 2 0)) (yaxception (0 1))) "Search mail of Gmail using X-GM-RAW as web interface" single ((:commit . "978bdfcecc8844465b71641c2e909fcdc66b22be") (:keywords "gnus") (:authors ("Hiroaki Otsu" . "ootsuhiroaki@gmail.com")) (:maintainer "Hiroaki Otsu" . "ootsuhiroaki@gmail.com") (:url . "https://github.com/aki2o/gnus-x-gm-raw"))]) (gnus-summary-ext . [(20180113 1316) nil "Extra limit and process mark commands for the gnus summary buffer" single ((:commit . "025fd853fe9280ae696a89ec2c2cac9befd010aa") (:keywords "comm") (:authors ("Joe Bloggs" . "vapniks@yahoo.com")) (:maintainer "Joe Bloggs" . "vapniks@yahoo.com") (:url . "https://github.com/vapniks/gnus-summary-ext"))]) (gnus-select-account . [(20170722 511) nil "Select an account before writing a mail in gnus" single ((:commit . "ddc8c135eeaf90f5b6692a033af2badae36e68ce") (:keywords "convenience") (:authors ("Feng Shu " . "tumashu@163.com")) (:maintainer "Feng Shu " . "tumashu@163.com") (:url . "https://github.com/tumashu/gnus-select-account"))]) (gnus-desktop-notify . [(20180623 1538) ((gnus (1 0))) "Gnus Desktop Notification global minor mode" single ((:commit . "44ebe0241a19f4052cd427dff408206542aa3c8f") (:authors ("Yuri D'Elia <wavexx AT thregr.org>")) (:maintainer "Yuri D'Elia <wavexx AT thregr.org>") (:url . "http://www.thregr.org/~wavexx/software/gnus-desktop-notify.el/"))]) (gnus-alias . [(20150316 42) nil "an alternative to gnus-posting-styles" single ((:commit . "9447d3ccb4c0e75d0468899cccff7aa249657bac") (:keywords "personality" "identity" "news" "mail" "gnus") (:authors ("Joe Casadonte" . "emacs@northbound-train.com")) (:maintainer "Mark A. Hershberger" . "mah@everybody.org"))]) (gnuplot-mode . [(20171013 1616) nil "Major mode for editing gnuplot scripts" single ((:commit . "601f6392986f0cba332c87678d31ae0d0a496ce7") (:keywords "gnuplot" "plotting") (:url . "https://github.com/mkmcc/gnuplot-mode"))]) (gnuplot . [(20141231 2137) nil "drive gnuplot from within emacs" tar ((:commit . "21f9046e3f5caad41b750b5c9cee02fa4fd20fb9") (:keywords "gnuplot" "plotting") (:authors ("Bruce Ravel" . "bruceravel1@gmail.com")) (:maintainer "Bruce Ravel" . "bruceravel1@gmail.com"))]) (gnu-apl-mode . [(20180130 700) ((emacs (24))) "Integrate GNU APL with Emacs" tar ((:commit . "fa569827c916ed46e410e9f28e4b4d28f8567654") (:keywords "languages" "apl") (:url . "https://github.com/lokedhs/gnu-apl-mode"))]) (gntp . [(20141025 250) nil "Growl Notification Protocol for Emacs" single ((:commit . "767571135e2c0985944017dc59b0be79af222ef5") (:authors ("Engelke Eschner" . "tekai@gmx.li")) (:maintainer "Engelke Eschner" . "tekai@gmx.li"))]) (gnomenm . [(20150316 1918) ((s (1 9 0)) (dash (2 3 0)) (kv (0 0 19))) "Emacs interface to Gnome nmcli command" single ((:commit . "9065cda44ffc9e06239b8189a0154d31314c3b4d") (:keywords "processes" "hardware") (:authors ("Nic Ferrier" . "nferrier@ferrier.me.uk")) (:maintainer "Nic Ferrier" . "nferrier@ferrier.me.uk") (:url . "http://github.com/nicferrier/emacs-nm"))]) (gnome-calendar . [(20161110 1256) nil "Integration with the GNOME Shell calendar" single ((:commit . "489f9f15f7bb35696b1cc19db75b554ae8328df2") (:keywords "gnome" "calendar") (:authors ("Nicolas Petton" . "nicolas@petton.fr")) (:maintainer "Nicolas Petton" . "nicolas@petton.fr"))]) (gmpl-mode . [(20171031 2054) ((emacs (24))) "Major mode for editing GMPL(MathProg) files" single ((:commit . "c5d362169819ee8b8e8954145daee7e260c54921") (:keywords "extensions") (:authors ("Junpeng Qiu" . "qjpchmail@gmail.com")) (:maintainer "Junpeng Qiu" . "qjpchmail@gmail.com"))]) (gmail2bbdb . [(20170423 1144) nil "import email and name into bbdb from vcard." single ((:commit . "a84fa385cfaec7fc5f1518c368e52722da139f99") (:keywords "vcard" "bbdb" "email" "contact" "gmail") (:authors ("Chen Bin" . "chenbin.sh@gmail.com")) (:maintainer "Chen Bin" . "chenbin.sh@gmail.com") (:url . "http://github.com/redguardtoo/gmail2bbdb"))]) (gmail-message-mode . [(20160627 1847) ((ham-mode (1 0))) "A major-mode for editing gmail messages using markdown syntax." single ((:commit . "ec36672a9dc93c09ebe2f77597b498d11883d008") (:keywords "mail" "convenience" "emulation") (:authors ("Artur Malabarba" . "bruce.connor.am@gmail.com")) (:maintainer "Artur Malabarba" . "bruce.connor.am@gmail.com") (:url . "http://github.com/Bruce-Connor/gmail-message-mode"))]) (glsl-mode . [(20170927 1436) nil "major mode for Open GLSL shader files" single ((:commit . "384968506cf25c5c2df61b32fdfdbd041e3bf651") (:keywords "languages") (:url . "http://artis.inrialpes.fr/~Xavier.Decoret/resources/glsl-mode/"))]) (glab . [(20180821 1551) nil "minuscule client library for the Gitlab API" single ((:commit . "d75ba1bd8843f53ae3e37b206187b3b97d9f3540") (:keywords "tools") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:url . "https://github.com/magit/ghub"))]) (gl-conf-mode . [(20170714 1310) ((emacs (24 3))) "Mode for editing gitolite config files" single ((:commit . "9136a9b737e0a5b6471a91571d104c487c43f35b") (:keywords "git" "gitolite" "languages") (:authors ("Luis Lloret")) (:maintainer "Luis Lloret") (:url . "https://github.com/llloret/gitolite-emacs"))]) (gitter . [(20180122 856) ((emacs (24 4)) (let-alist (1 0 4))) "An Emacs Gitter client" single ((:commit . "11cb9b4b45f67bdc24f055a9bfac21d2bd19ea1a") (:keywords "gitter" "chat" "client" "internet") (:authors ("Chunyang Xu" . "mail@xuchunyang.me")) (:maintainer "Chunyang Xu" . "mail@xuchunyang.me") (:url . "https://github.com/xuchunyang/gitter.el"))]) (gitpatch . [(20170722 410) ((emacs (24 3))) "Git-format patch toolkit" single ((:commit . "577d5adf65c8133caa325c10e89e1e2fc323c907") (:keywords "convenience") (:authors ("Feng Shu" . "tumashu@163.com")) (:maintainer "Feng Shu" . "tumashu@163.com") (:url . "https://github.com/tumashu/gitpatch"))]) (gitolite-clone . [(20160609 2355) ((dash (2 10 0)) (s (1 9 0)) (pcache (0 3 1)) (emacs (24))) "Clone gitolite repositories from a completing list" single ((:commit . "d8a4c2875c984e51137c980b5773f42703602721") (:keywords "gitolite" "clone" "git") (:authors ("Ivan Malison" . "IvanMalison@gmail.com")) (:maintainer "Ivan Malison" . "IvanMalison@gmail.com") (:url . "https://github.com/IvanMalison/gitolite-clone"))]) (gitlab-ci-mode-flycheck . [(20180604 2204) ((emacs (25)) (flycheck (31)) (gitlab-ci-mode (1))) "Flycheck support for ‘gitlab-ci-mode’" single ((:commit . "30ea0eab74b24818f187242b079845785035e967") (:keywords "tools" "vc" "convenience") (:authors ("Joe Wreschnig")) (:maintainer "Joe Wreschnig") (:url . "https://gitlab.com/joewreschnig/gitlab-ci-mode-flycheck/"))]) (gitlab-ci-mode . [(20180604 2203) ((emacs (25)) (yaml-mode (0 0 12))) "mode for editing GitLab CI files" single ((:commit . "b9fd692d27351e959c4d272a2149def63ef1c00c") (:keywords "tools" "vc") (:authors ("Joe Wreschnig")) (:maintainer "Joe Wreschnig") (:url . "https://gitlab.com/joewreschnig/gitlab-ci-mode/"))]) (gitlab . [(20180312 1647) ((s (1 9 0)) (dash (2 9 0)) (pkg-info (0 5 0)) (request (0 1 0))) "Emacs client for Gitlab" tar ((:commit . "68318aca3206d50701039c9aae39734ca29a49f9") (:keywords "gitlab") (:authors ("Nicolas Lamirault" . "nicolas.lamirault@gmail.com")) (:maintainer "Nicolas Lamirault" . "nicolas.lamirault@gmail.com") (:url . "https://github.com/nlamirault/emacs-gitlab"))]) (gitignore-templates . [(20180327 1326) ((emacs (24 3))) "Access GitHub .gitignore templates" single ((:commit . "b0705b8de4cbdd631c64c4e0024d62ba4ad68052") (:keywords "tools") (:authors ("Xu Chunyang" . "mail@xuchunyang.me")) (:maintainer "Xu Chunyang" . "mail@xuchunyang.me") (:url . "https://github.com/xuchunyang/gitignore-templates.el"))]) (gitignore-mode . [(20180318 1956) nil "Major mode for editing .gitignore files" single ((:commit . "55468314a5f6b77d2c96be62c7005ac94545e217") (:keywords "convenience" "vc" "git") (:authors ("Sebastian Wiesner" . "lunaryorn@gmail.com")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:url . "https://github.com/magit/git-modes"))]) (github-theme . [(20170630 2201) nil "The GitHub color theme for Emacs." single ((:commit . "29f00a51d949a248a5f6355a97131e216747c797") (:authors ("Philip Arvidsson" . "philip@philiparvidsson.com")) (:maintainer "Philip Arvidsson" . "philip@philiparvidsson.com") (:url . "https://github.com/philiparvidsson/GitHub-Theme-for-Emacs"))]) (github-stars . [(20180328 1133) ((emacs (25 1)) (ghub (2 0 0))) "Browse your Github Stars" single ((:commit . "15cbf15cdd3fbd2139b5c128a173bb8f6a4ef496") (:keywords "tools") (:authors ("Xu Chunyang" . "mail@xuchunyang.me")) (:maintainer "Xu Chunyang" . "mail@xuchunyang.me") (:url . "https://github.com/xuchunyang/github-stars.el"))]) (github-search . [(20170824 323) ((magit (0 8 1)) (gh (1 0 0))) "Clone repositories by searching github" single ((:commit . "c5fa1d9f8f9bcf201fa31478a6f5e02ed5ac086b") (:keywords "github" "search" "clone" "api" "gh" "magit" "vc" "tools") (:authors ("Ivan Malison" . "IvanMalison@gmail.com")) (:maintainer "Ivan Malison" . "IvanMalison@gmail.com") (:url . "https://github.com/IvanMalison/github-search"))]) (github-pullrequest . [(20170116 616) ((emacs (24 4)) (request (0 2 0)) (dash (2 11 0)) (magit (2 10 0))) "Create and fetch Github Pull requests with ease" single ((:commit . "6ae5c38b0fc15b638b5ba4490112d9822ce5e267") (:keywords "tools") (:authors ("Jakob Lind" . "karl.jakob.lind@gmail.com")) (:maintainer "Jakob Lind" . "karl.jakob.lind@gmail.com") (:url . "https://github.com/jakoblind/github-pullrequest"))]) (github-notifier . [(20180421 316) ((emacs (24))) "Displays your GitHub notifications unread count in mode-line" single ((:commit . "274f3812926ea371346f639fcee98066f6e8c96f") (:keywords "github" "mode-line") (:authors ("Chunyang Xu" . "mail@xuchunyang.me")) (:maintainer "Chunyang Xu" . "mail@xuchunyang.me") (:url . "https://github.com/xuchunyang/github-notifier.el"))]) (github-modern-theme . [(20171109 1251) nil "The GitHub color theme for Emacs." single ((:commit . "a7e7b8e5e9c122138e79e837caf9b7299e748d44") (:authors ("Philip Arvidsson" . "philip@philiparvidsson.com")) (:maintainer "Philip Arvidsson" . "philip@philiparvidsson.com") (:url . "https://github.com/philiparvidsson/GitHub-Theme-for-Emacs"))]) (github-issues . [(20160616 1841) ((emacs (24))) "Functions and modes for managing GitHub projects' issues" single ((:commit . "816f7712b0eb05bffec0add3507302862d2629c4") (:keywords "github" "issues") (:authors ("Leandro M. López (inkel)" . "inkel.ar@gmail.com")) (:maintainer "Leandro M. López (inkel)" . "inkel.ar@gmail.com") (:url . "http://inkel.github.com/github-issues.el/"))]) (github-elpa . [(20180831 811) ((package-build (1 0)) (commander (0 7 0)) (git (0 1 1))) "Build and publish ELPA repositories with GitHub Pages" tar ((:commit . "cbde5bc239687e07347cecf46ba5aa31948ebe1d") (:authors (nil . "10sr<8slashes+el@gmail.com>")) (:maintainer nil . "10sr<8slashes+el@gmail.com>") (:url . "https://github.com/10sr/github-elpa"))]) (github-clone . [(20160623 310) ((gh (0 7 2)) (magit (2 1 0)) (emacs (24 4))) "Fork and clone github repos" single ((:commit . "467b40ca60a6c26257466ebc43c74414df7f19cc") (:keywords "vc" "tools") (:authors ("Charles L.G. Comstock" . "dgtized@gmail.com")) (:maintainer "Charles L.G. Comstock" . "dgtized@gmail.com") (:url . "https://github.com/dgtized/github-clone.el"))]) (github-browse-file . [(20160205 1427) ((cl-lib (0 5))) "View the file you're editing on GitHub" single ((:commit . "9742a5183af853788c6ecb83fb7ee0b00d1675ac") (:keywords "convenience" "vc" "git" "github") (:authors ("Ozan Sener" . "ozan@ozansener.com")) (:maintainer "Ozan Sener" . "ozan@ozansener.com") (:url . "https://github.com/osener/github-browse-file"))]) (gitconfig-mode . [(20180318 1956) nil "Major mode for editing .gitconfig files" single ((:commit . "55468314a5f6b77d2c96be62c7005ac94545e217") (:keywords "convenience" "vc" "git") (:authors ("Sebastian Wiesner" . "lunaryorn@gmail.com")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:url . "https://github.com/magit/git-modes"))]) (gitconfig . [(20130718 935) nil "Emacs lisp interface to work with git-config variables" single ((:commit . "7612a37ca14009cac8fb8d6b6f54adad739a5741") (:keywords "git" "gitconfig" "git-config") (:authors ("Samuel Tonini")) (:maintainer "Samuel Tonini"))]) (gitattributes-mode . [(20180318 1956) nil "Major mode for editing .gitattributes files" single ((:commit . "55468314a5f6b77d2c96be62c7005ac94545e217") (:keywords "convenience" "vc" "git") (:authors ("Rüdiger Sonderfeld" . "ruediger@c-plusplus.net")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:url . "https://github.com/magit/git-modes"))]) (git-wip-timemachine . [(20150408 1006) ((s (1 9 0))) "Walk through git-wip revisions of a file" single ((:commit . "ed4c7931a5f5233bf3e358b1e81647d063526460") (:keywords "git") (:authors ("Tim Krones" . "t.krones@gmx.net")) (:maintainer "Tim Krones" . "t.krones@gmx.net") (:url . "https://github.com/itsjeyd/git-wip-timemachine"))]) (git-timemachine . [(20180607 820) ((emacs (24 3))) "Walk through git revisions of a file" single ((:commit . "90a980578249c102da3e904fccdc9a2a5a0e7bcc") (:keywords "git") (:authors ("Peter Stiernström" . "peter@stiernstrom.se")) (:maintainer "Peter Stiernström" . "peter@stiernstrom.se") (:url . "https://github.com/pidu/git-timemachine"))]) (git-ps1-mode . [(20180413 947) nil "Global minor-mode to print __git_ps1" single ((:commit . "6a06bf57cbe614ab26032b153d3dcf4fb4bfa7ee") (:keywords "utility" "mode-line" "git") (:authors ("10sr <8slashes+el [at] gmail [dot] com>")) (:maintainer "10sr <8slashes+el [at] gmail [dot] com>") (:url . "https://github.com/10sr/git-ps1-mode-el"))]) (git-msg-prefix . [(20180118 1446) ((emacs (24)) (s (1 10 0)) (dash (2 9 0))) "Insert commit message prefix (issue number)" single ((:commit . "848f2c7475f5e4937b09f55e85ea89a3be5f8588") (:keywords "vc" "tools") (:authors ("Raimon Grau" . "raimonster@gmail.com")) (:maintainer "Raimon Grau" . "raimonster@gmail.com") (:url . "http://github.com/kidd/git-msg-prefix.el"))]) (git-messenger . [(20170102 440) ((emacs (24 3)) (popup (0 5 0))) "Pop up last commit information of current line" single ((:commit . "83815915eb8c1cb47443ff34bca3fecf7d2edf3a") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-git-messenger"))]) (git-link . [(20180708 1643) ((emacs (24 3))) "Get the GitHub/Bitbucket/GitLab URL for a buffer location" single ((:commit . "efd14ab5f17f5942d25e165210447f3983f3250e") (:keywords "git" "vc" "github" "bitbucket" "gitlab" "convenience") (:authors ("Skye Shaw" . "skye.shaw@gmail.com")) (:maintainer "Skye Shaw" . "skye.shaw@gmail.com") (:url . "http://github.com/sshaw/git-link"))]) (git-lens . [(20180328 1417) ((emacs (24 4))) "Show new, deleted or modified files in branch" single ((:commit . "ea49e2e005af977a08331f8caa8f64d102b3b932") (:keywords "vc" "convenience") (:authors ("Peter Stiernström" . "peter@stiernstrom.se")) (:maintainer "Peter Stiernström" . "peter@stiernstrom.se") (:url . "https://github.com/pidu/git-lens"))]) (git-io . [(20180317 1752) ((emacs (24 4))) "git.io integration" single ((:commit . "48753acba73b48b997bb678fb5e2a938ae63b5d6") (:keywords "convenience" "files") (:authors ("Tejas Bubane" . "tejasbubane@gmail.com")) (:maintainer "Tejas Bubane" . "tejasbubane@gmail.com") (:url . "https://github.com/tejasbubane/emacs-git-io"))]) (git-gutter-fringe . [(20170113 533) ((git-gutter (0 88)) (fringe-helper (0 1 1)) (cl-lib (0 5)) (emacs (24))) "Fringe version of git-gutter.el" single ((:commit . "16226caab44174301f1659f7bf8cc67a76153445") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-git-gutter-fringe"))]) (git-gutter-fringe+ . [(20140729 1103) ((git-gutter+ (0 1)) (fringe-helper (1 0 1))) "Fringe version of git-gutter+.el" single ((:commit . "7a2f49d2455a3a872e90e5f7dd4e6b27f1d96cfc") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/nonsequitur/git-gutter-fringe-plus"))]) (git-gutter . [(20161105 1356) ((emacs (24 3))) "Port of Sublime Text plugin GitGutter" single ((:commit . "00c05264af046b5ce248e5b0bc42f117d9c27a09") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-git-gutter"))]) (git-gutter+ . [(20151204 1723) ((git-commit (0)) (dash (0))) "Manage Git hunks straight from the buffer" single ((:commit . "b7726997806d9a2da9fe84ff00ecf21d62b6f975") (:keywords "git" "vc") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/nonsequitur/git-gutter-plus"))]) (git-dwim . [(20170126 1214) nil "Context-aware git commands such as branch handling" single ((:commit . "485c732130686c2f28a026e385366006435394b9") (:keywords "git" "tools" "convenience") (:authors ("rubikitch" . "rubikitch@ruby-lang.org")) (:maintainer "rubikitch" . "rubikitch@ruby-lang.org") (:url . "http://www.emacswiki.org/cgi-bin/wiki/download/git-dwim.el"))]) (git-commit-insert-issue . [(20171102 1841) ((projectile (0)) (s (0)) (github-issues (0)) (gitlab (0)) (bitbucket (0))) "Get issues list when typing \"Fixes #\"" single ((:commit . "f986923b04b587206ce7ee8e0c456768600e8be7") (:keywords "git" "github" "gitlab" "bitbucket" "commit" "issues") (:authors ("Vindarel")) (:maintainer "Vindarel") (:url . "https://gitlab.com/emacs-stuff/git-commit-insert-issue/"))]) (git-commit . [(20180802 2018) ((emacs (25 1)) (dash (20180413)) (with-editor (20180414))) "Edit Git commit messages" single ((:commit . "0e818e9dfd053eed6da8a40bbf6a65f2fa4b2ed8") (:keywords "git" "tools" "vc") (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:url . "https://github.com/magit/magit"))]) (git-command . [(20160111 1303) ((term-run (0 1 4)) (with-editor (2 3 1))) "Yet another Git interface" single ((:commit . "dce465ca1cd80e16df0f8dce8e427a76e9edc3b7") (:keywords "utility" "git") (:authors ("10sr <8slashes+el [at] gmail [dot] com>")) (:maintainer "10sr <8slashes+el [at] gmail [dot] com>") (:url . "https://github.com/10sr/git-command-el"))]) (git-blamed . [(20161028 1926) nil "Minor mode for incremental blame for Git" single ((:commit . "cef196abf398e2dd11f775d1e6cd8690567408aa") (:keywords "git" "version control" "release management"))]) (git-auto-commit-mode . [(20161229 1617) nil "Emacs Minor mode to automatically commit and push" single ((:commit . "2c8197e5d7813734d6a49f9b9c0b227b7ae022a8") (:keywords "vc") (:authors ("Tom Willemse" . "tom@ryuslash.org")) (:maintainer "Tom Willemse" . "tom@ryuslash.org") (:url . "http://projects.ryuslash.org/git-auto-commit-mode/"))]) (git-attr . [(20180204 815) ((emacs (24 3))) "Git attributes of buffer file" tar ((:commit . "c03078637a00ea301cbcc7ae301ae928b10af889") (:keywords "vc") (:authors ("Arne Jørgensen" . "arne@arnested.dk")) (:maintainer "Arne Jørgensen" . "arne@arnested.dk") (:url . "https://github.com/arnested/emacs-git-attr"))]) (git-annex . [(20180427 1556) nil "Mode for easy editing of git-annex'd files" single ((:commit . "ebdb44aef1883f1b2b8058e05d30fb9315b03707") (:keywords "files" "data" "git" "annex") (:authors ("John Wiegley" . "jwiegley@gmail.com")) (:maintainer "John Wiegley" . "jwiegley@gmail.com") (:url . "https://github.com/jwiegley/git-annex-el"))]) (git . [(20140128 1041) ((s (1 7 0)) (dash (2 2 0)) (f (0 10 0))) "An Elisp API for programmatically using Git" single ((:commit . "a3396a7027a7d986598c6a2d6d5599bac918f3da") (:keywords "git") (:authors ("Johan Andersson" . "johan.rejeep@gmail.com")) (:maintainer "Johan Andersson" . "johan.rejeep@gmail.com") (:url . "http://github.com/rejeep/git.el"))]) (gist . [(20171128 406) ((emacs (24 1)) (gh (0 10 0))) "Emacs integration for gist.github.com" single ((:commit . "314fe6ab80fae35b95f0734eceb82f72813b6f41") (:keywords "tools") (:authors ("Yann Hodique" . "yann.hodique@gmail.com")) (:maintainer "Yann Hodique" . "yann.hodique@gmail.com") (:url . "https://github.com/defunkt/gist.el"))]) (gildas-mode . [(20150919 2201) ((polymode (0)) (emacs (24 3))) "Major mode for Gildas" single ((:commit . "23e8a2e6066ff74af592de6d5d0d858442e2bf8a") (:keywords "languages" "gildas") (:authors ("Sébastien Maret" . "sebastien.maret@icloud.com")) (:maintainer "Sébastien Maret" . "sebastien.maret@icloud.com") (:url . "https://github.com/smaret/gildas-mode"))]) (gift-mode . [(20180530 1235) nil "major mode for editing GIFT format quizzes" single ((:commit . "b0441ae6e02f343be3b611a2d4b40495ecd932f0") (:authors ("Christophe Rhodes" . "christophe@rhodes.io")) (:maintainer "Christophe Rhodes" . "christophe@rhodes.io") (:url . "https://github.com/csrhodes/gift-mode"))]) (gif-screencast . [(20180827 835) ((emacs (25 1))) "One-frame-per-action GIF recording" single ((:commit . "62e69ea464e87f1f7791d95a4fbbe9b70a84668a") (:keywords "multimedia" "screencast") (:authors ("Pierre Neidhardt" . "mail@ambrevar.xyz")) (:maintainer "Pierre Neidhardt" . "mail@ambrevar.xyz") (:url . "https://gitlab.com/ambrevar/emacs-gif-screencast"))]) (ghub . [(20180821 1430) ((emacs (24 4)) (let-alist (1 0 5))) "minuscule client library for the Github API" tar ((:commit . "48e91c0e1b5dea431b5edad018d2a2bdfa49eca2") (:keywords "tools") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:url . "https://github.com/magit/ghub"))]) (ghub+ . [(20180602 2245) ((emacs (25)) (ghub (2 0)) (apiwrap (0 5))) "a thick GitHub API client built on ghub" single ((:commit . "52acf79f59e5807bd1825affd79808db709e283a") (:keywords "extensions" "multimedia" "tools") (:authors ("Sean Allred" . "code@seanallred.com")) (:maintainer "Sean Allred" . "code@seanallred.com") (:url . "https://github.com/vermiculus/ghub-plus"))]) (ghq . [(20160803 1557) nil "Ghq interface for emacs" single ((:commit . "aae4b8cb22fd6c24d2c9e3962c7e8e9dac6d9825") (:keywords "ghq") (:authors ("Roman Coedo" . "romancoedo@gmail.com")) (:maintainer "Roman Coedo" . "romancoedo@gmail.com"))]) (ghost-blog . [(20171023 742) ((markdown-mode (1 0))) "A package to manage Ghost blog" single ((:commit . "71b358643cc9a2db1bf752281ff94aba9b59e4cc") (:keywords "ghost" "blog") (:authors ("Javier Aguirre" . "hello@javaguirre.net")) (:maintainer "Javier Aguirre" . "hello@javaguirre.net") (:url . "https://github.com/javaguirre/ghost-blog"))]) (gherkin-mode . [(20171224 1353) nil "An emacs major mode for editing gherkin files." single ((:commit . "0313492e7da152f0aa73ddf96c0287ded8f51253") (:keywords "languages") (:authors ("Craig Andera")) (:maintainer "Craig Andera"))]) (ghci-completion . [(20151125 1257) ((emacs (24 1)) (cl-lib (0 5))) "Completion for GHCi commands in inferior-haskell buffers" single ((:commit . "c47e23d585d2a3c7b13aac163693fdc4f2bb90e5") (:keywords "convenience") (:authors ("Oleksandr Manzyuk" . "manzyuk@gmail.com")) (:maintainer "Oleksandr Manzyuk" . "manzyuk@gmail.com"))]) (ghc-imported-from . [(20141124 1932) ((emacs (24 1))) "Haskell documentation lookup with ghc-imported-from" single ((:commit . "fcff08628a19f5d26151564659218cc677779b79") (:keywords "languages") (:authors ("David Raymond Christiansen" . "david@davidchristiansen.dk")) (:maintainer "David Raymond Christiansen" . "david@davidchristiansen.dk"))]) (ghc . [(20180121 1218) ((haskell-mode (13 0))) "Sub mode for Haskell mode" tar ((:commit . "3bca649482d002418b0a77e66889a9aadc35826e"))]) (gh-md . [(20151207 1740) ((emacs (24))) "Render markdown using the Github api" single ((:commit . "693cb0dcadff70e813e1a9d303d227aff7898557") (:keywords "convenience") (:authors ("Mario Rodas" . "marsam@users.noreply.github.com")) (:maintainer "Mario Rodas" . "marsam@users.noreply.github.com") (:url . "https://github.com/emacs-pe/gh-md.el"))]) (gh . [(20180308 2138) ((emacs (24 3)) (pcache (0 4 1)) (logito (0 1)) (marshal (0 6 3))) "A GitHub library for Emacs" tar ((:commit . "f029fc11f345ef04ab62ee91c38657e29c462fea"))]) (ggtags . [(20180725 1713) ((emacs (25))) "emacs frontend to GNU Global source code tagging system" single ((:commit . "c737181c16a673d36e81b4c8ec4f389d630ec49d") (:keywords "tools" "convenience") (:authors ("Leo Liu" . "sdl.web@gmail.com")) (:maintainer "Leo Liu" . "sdl.web@gmail.com") (:url . "https://github.com/leoliu/ggtags"))]) (ggo-mode . [(20130524 1143) nil "Gengetopt major mode" single ((:commit . "e326899d9ed8217c7a4ea6cfdc4dd7aea61d6c1b") (:keywords "extensions" "convenience" "local") (:authors ("Matthew K. Junker" . "junker@alum.mit.edu")) (:maintainer "Matthew K. Junker" . "junker@alum.mit.edu"))]) (gf . [(20180822 2025) ((s (1 0)) (ht (2 0))) "Major mode for editing GF code" single ((:commit . "e8e55584b0a473922c58cbb4860306a84c3336e5") (:keywords "languages") (:authors ("Johan Bockgård" . "bojohan+mail@dd.chalmers.se")) (:maintainer "bruno cuconato" . "bcclaro+emacs@gmail.com") (:url . "https://github.com/GrammaticalFramework/gf-emacs-mode"))]) (gerrit-download . [(20150714 1408) ((emacs (24 0)) (magit (2 1 0))) "Show gerrit reviews in a diff buffer." single ((:commit . "d568acc7c5935188c9bc19ba72719a6092d9f6fd") (:keywords "tools" "gerrit" "git") (:authors ("Chmouel Boudjnah" . "chmouel@chmouel.com")) (:maintainer "Chmouel Boudjnah" . "chmouel@chmouel.com") (:url . "https://github.com/chmouel/gerrit-download.el"))]) (german-holidays . [(20161011 713) nil "German holidays for Emacs calendar" single ((:commit . "d7d540c229c1a8be68ee09fbda08fe3ea31b7d29") (:authors ("Sebastian Christ" . "rudolfo.christ@gmail.com")) (:maintainer "Sebastian Christ" . "rudolfo.christ@gmail.com") (:url . "https://github.com/rudolfochrist/german-holidays"))]) (genrnc . [(20140612 1237) ((deferred (0 3 1)) (concurrent (0 3)) (log4e (0 2 0)) (yaxception (0 1))) "generate RELAX NG Compact Schema from RELAX NG Schema, XML Schema and DTD." tar ((:commit . "da75b1966a73ad215ec2ced4522c25f4d0bf1f9a") (:keywords "xml") (:authors ("Hiroaki Otsu" . "ootsuhiroaki@gmail.com")) (:maintainer "Hiroaki Otsu" . "ootsuhiroaki@gmail.com") (:url . "https://github.com/aki2o/emacs-genrnc"))]) (general . [(20180901 1552) ((emacs (24 4)) (cl-lib (0 5))) "Convenience wrappers for keybindings." single ((:commit . "f1feeb8241bc724ced9952f328d6694329178cf1") (:keywords "vim" "evil" "leader" "keybindings" "keys") (:authors ("Fox Kiester" . "noct@openmailbox.org")) (:maintainer "Fox Kiester" . "noct@openmailbox.org") (:url . "https://github.com/noctuid/general.el"))]) (geiser . [(20180626 1140) nil "GNU Emacs and Scheme talk to each other" tar ((:commit . "1bdd966a4fbe0c8bd5bcb04dad5213e47a1534e6") (:url . "http://www.nongnu.org/geiser/"))]) (geeknote . [(20160717 1249) ((emacs (24))) "Use Evernote in Emacs through geeknote" single ((:commit . "8ed607c76864afcc9c338972ab093caf4501cbf8") (:keywords "evernote" "geeknote" "note" "emacs-evernote" "evernote-mode") (:authors ("Evan Dale Aromin")) (:maintainer "Evan Dale Aromin") (:url . "http://github.com/avendael/emacs-geeknote"))]) (geben-helm-projectile . [(20160611 59) ((emacs (24)) (geben (0 26)) (helm-projectile (0 13 0))) "Integrate helm-projectile with geben" single ((:commit . "31ce0faca5dcc71924884f03fd5a7a25d00ccd9b") (:keywords "ahungry" "emacs" "geben" "helm" "projectile" "debug") (:authors ("Matthew Carter" . "m@ahungry.com")) (:maintainer "Matthew Carter" . "m@ahungry.com") (:url . "https://github.com/ahungry/geben-helm-projectile"))]) (geben . [(20170801 1251) ((emacs (24 3)) (cl-lib (0 5))) "DBGp protocol frontend, a script debugger" tar ((:commit . "ec3f5e9376cf1ea5615990bd8c212543d57f033b") (:keywords "c" "comm" "tools") (:authors ("Matthew Carter" . "m@ahungry.com")) (:maintainer "Matthew Carter" . "m@ahungry.com") (:url . "https://github.com/ahungry/geben"))]) (gdscript-mode . [(20180118 456) ((emacs (24 3))) "Major mode for editing Godot GDScript files" single ((:commit . "31af5283eaec207bc864022a28e2824132471eaf") (:keywords "languages") (:authors ("Adam Bark" . "adam@adambark.com")) (:maintainer "Adam Bark" . "adam@adambark.com") (:url . "https://github.com/AdamBark/gdscript-mode"))]) (gather . [(20141230 1338) nil "Gather string in buffer." single ((:commit . "50809fbc22d70a1c724c2dd99ac5a1f818ffeb6b") (:keywords "matching" "convenience" "tools") (:authors ("Masahiro Hayashi" . "mhayashi1120@gmail.com")) (:maintainer "Masahiro Hayashi" . "mhayashi1120@gmail.com") (:url . "https://github.com/mhayashi1120/Emacs-gather/raw/master/gather.el"))]) (gap-mode . [(20180809 445) nil "Major mode for editing files in the GAP programing language." tar ((:keywords "gap") (:authors ("Michael Smith" . "smith@pell.anu.edu.au") ("Gary Zablackis") ("Goetz Pfeiffer") ("Ivan Andrus" . "darthandrus@gmail.com")) (:maintainer "Ivan Andrus" . "darthandrus@gmail.com") (:url . "https://bitbucket.org/gvol/gap-mode"))]) (gandalf-theme . [(20130809 947) nil "Gandalf color theme" single ((:commit . "4e472fc851431458537d458d09c1f5895e338536") (:keywords "color" "theme") (:authors ("Peter Vasil" . "mail@petervasil.net")) (:maintainer "Peter Vasil" . "mail@petervasil.net"))]) (gams-mode . [(20180416 906) ((emacs (24 3))) "Major mode for General Algebraic Modeling System (GAMS)." single ((:commit . "3022e9f8411628e6a210fb5843d858b15a7513f5") (:keywords "languages" "tools" "gams") (:authors ("Shiro Takeda")) (:maintainer "Shiro Takeda") (:url . "http://shirotakeda.org/en/gams/gams-mode/"))]) (gams-ac . [(20180423 926) ((emacs (24)) (auto-complete (1 0)) (gams-mode (4 0))) "auto-complete source file for GAMS mode" single ((:commit . "66d04ff36033f54205c19bc1d893e926d4dbf02e") (:keywords "languages" "tools" "gams-mode" "auto-complete") (:authors ("Shiro Takeda")) (:maintainer "Shiro Takeda") (:url . "https://github.com/ShiroTakeda/gams-ac"))]) (fzf . [(20180619 145) ((emacs (24 4))) "A front-end for fzf." single ((:commit . "521d18933cb586337c4e34281bdc71ac07202c98") (:keywords "fzf" "fuzzy" "search") (:authors ("Bailey Ling")) (:maintainer "Bailey Ling") (:url . "https://github.com/bling/fzf.el"))]) (fyure . [(20130216 1314) nil "An interface to fix Japanese hyoki-yure" tar ((:commit . "b6977f1eb148e8b63259f7233b55bb050e44d9b8") (:keywords "languages") (:authors ("Masafumi Oyamada" . "stillpedant@gmail.com")) (:maintainer "Masafumi Oyamada" . "stillpedant@gmail.com"))]) (fxrd-mode . [(20170728 1801) ((s (1 2))) "Major mode for editing fixed field width files" tar ((:commit . "18a603474abb5a786a8d9f20c283d5f7beed3540") (:keywords "convenience") (:authors ("Marc Sherry" . "msherry@gmail.com")) (:maintainer "Marc Sherry" . "msherry@gmail.com") (:url . "https://github.com/msherry/fxrd-mode"))]) (fwb-cmds . [(20180318 2219) nil "misc frame, window and buffer commands" single ((:commit . "90258a5c7dbbaa2ac227e0fb4ff6c7d5aec3628f") (:keywords "convenience") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:url . "https://github.com/tarsius/fwb-cmds"))]) (fvwm-mode . [(20160411 1138) nil "A major mode for editing Fvwm configuration files" single ((:commit . "6832a1c1f68bf6249c3fd6672ea8e27dc7a5c79e") (:keywords "files") (:authors ("Bert Geens" . "bert@lair.be")) (:maintainer "Bert Geens" . "bert@lair.be") (:url . "https://github.com/theBlackDragon/fvwm-mode"))]) (fuzzy . [(20150730 337) nil "Fuzzy Matching" single ((:commit . "534d723ad2e06322ff8d9bd0ba4863d243f698e7") (:keywords "convenience") (:authors ("Tomohiro Matsuyama" . "m2ym.pub@gmail.com")) (:maintainer "Tomohiro Matsuyama" . "m2ym.pub@gmail.com"))]) (futhark-mode . [(20180812 950) ((cl-lib (0 5))) "major mode for editing Futhark source files" single ((:commit . "f19f4824dccba692616e5a61a1db8798fdfd00c7") (:keywords "languages") (:url . "https://github.com/diku-dk/futhark"))]) (furl . [(20150509 316) nil "Friendly URL retrieval" single ((:commit . "014438271e0ef27333dfcd599cb247f12a20d870") (:authors ("Natalie Weizenbaum" . "nweiz@google.com")) (:maintainer "Natalie Weizenbaum" . "nweiz@google.com"))]) (fuo . [(20180314 1648) ((emacs (24 4))) "feeluown client." single ((:commit . "5318bef9d935b53031e6312652554920def69af2") (:keywords "feeluown" "multimedia" "unix") (:authors ("cosven" . "yinshaowen241@gmail.com")) (:maintainer "cosven" . "yinshaowen241@gmail.com") (:url . "http://github.com/cosven/emacs-fuo"))]) (function-args . [(20171031 1704) ((ivy (0 9 1))) "C++ completion for GNU Emacs" tar ((:commit . "609b25305670fff08d5e357298e7128e4f4e3497") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:url . "https://github.com/abo-abo/function-args"))]) (fullframe . [(20170816 1003) ((cl-lib (0 5))) "Generalized automatic execution in a single frame" single ((:commit . "d6a5217f7f2a5a5edcb75140f3fa69b3a50f1cdd") (:keywords "fullscreen") (:authors ("Tom Regner" . "tom@goochesa.de")) (:maintainer "Tom Regner" . "tom@goochesa.de"))]) (full-ack . [(20140223 1732) nil "a front-end for ack" single ((:commit . "761d846e105b150f8e6d13d7a8983f0248313a45") (:keywords "tools" "matching") (:authors ("Nikolaj Schumacher <bugs * nschum de>")) (:maintainer "Nikolaj Schumacher <bugs * nschum de>") (:url . "http://nschum.de/src/emacs/full-ack/"))]) (fuff . [(20170202 1503) ((seq (2 3))) "Find files with findutils, recursively" single ((:commit . "278e849913df87bd8756c59382282d87474802c3") (:keywords "files" "project" "convenience") (:authors ("Joel Moberg")) (:maintainer "Joel Moberg") (:url . "https://github.com/joelmo/fuff"))]) (fuel . [(20180224 2211) ((cl-lib (0 2)) (emacs (24 2))) "Major mode for the Factor programming language." tar ((:commit . "a51fd04d0b88bdbe16fc6adbc5fe2e0b9a68fa66"))]) (fstar-mode . [(20180814 1944) ((emacs (24 3)) (dash (2 11)) (company (0 8 12)) (quick-peek (1 0)) (yasnippet (0 11 0)) (flycheck (30 0)) (company-quickhelp (2 2 0))) "Support for F* programming" tar ((:commit . "20633d42734ff54d662d8da618dc5aa5e20c743f") (:keywords "convenience" "languages") (:authors ("Clément Pit-Claudel" . "clement.pitclaudel@live.com")) (:maintainer "Clément Pit-Claudel" . "clement.pitclaudel@live.com") (:url . "https://github.com/FStarLang/fstar-mode.el"))]) (fsharp-mode . [(20180518 1820) ((company (0 8 0)) (company-quickhelp (1 2 0)) (popup (0 5 3)) (pos-tip (0 4 5)) (s (1 3 1)) (dash (1 1 0)) (flycheck (0 25))) "F# mode for Emacs" tar ((:commit . "68d2121a7317d90fe3794c9295d117f4aebd1438"))]) (fsbot-data-browser . [(20160921 1533) nil "browse the fsbot database using tabulated-list-mode" single ((:commit . "6bca4f7de63e31839d2542f6c678b79931dec344") (:keywords "fsbot" "irc" "tabulated-list-mode") (:authors ("Benaiah Mischenko")) (:maintainer "Benaiah Mischenko") (:url . "http://github.com/benaiah/fsbot-data-browser"))]) (fringe-helper . [(20140620 2109) nil "helper functions for fringe bitmaps" single ((:commit . "ef4a9c023bae18ec1ddd7265f1f2d6d2e775efdd") (:keywords "lisp") (:authors ("Nikolaj Schumacher <bugs * nschum de>")) (:maintainer "Nikolaj Schumacher <bugs * nschum de>") (:url . "http://nschum.de/src/emacs/fringe-helper/"))]) (fringe-current-line . [(20140111 411) nil "show current line on the fringe." single ((:commit . "0ef000bac76abae30601222e6f06c7d133ab4942") (:authors ("Kouhei Yanagita" . "yanagi@shakenbu.org")) (:maintainer "Kouhei Yanagita" . "yanagi@shakenbu.org") (:url . "http://github.com/kyanagi/fringe-current-line/raw/master/fringe-current-line.el"))]) (free-keys . [(20160726 2050) ((cl-lib (0 3))) "Show free keybindings for modkeys or prefixes" single ((:commit . "edfd69dc369b2647447b7c28c7c1163b1ddf45b4") (:keywords "convenience") (:authors ("Matus Goljer" . "matus.goljer@gmail.com")) (:maintainer "Matus Goljer" . "matus.goljer@gmail.com") (:url . "https://github.com/Fuco1/free-keys"))]) (frecency . [(20170909 631) ((emacs (25 1)) (a (0 1)) (dash (2 13 0))) "Library for sorting items by frequency and recency of access" single ((:commit . "31ef9ff4af1a4fed3dcc24ea74037feea8795c87") (:keywords "libraries" "recency" "recent" "frequency" "frequent") (:authors ("Adam Porter" . "adam@alphapapa.net")) (:maintainer "Adam Porter" . "adam@alphapapa.net") (:url . "http://github.com/alphapapa/frecency.el"))]) (framesize . [(20131017 2132) ((key-chord (0 5 20080915))) "change the size of frames in Emacs" single ((:commit . "f2dbf5d2513b2bc45f2085370a55c1754b6025da") (:keywords "frames") (:authors ("Nic Ferrier" . "nferrier@ferrier.me.uk")) (:maintainer "Nic Ferrier" . "nferrier@ferrier.me.uk") (:url . "http://github.com/nicferrier/emacs-framesize"))]) (frameshot . [(20180723 2128) ((emacs (25 3))) "Take screenshots of a frame" single ((:commit . "917efdd678e397aa01efa657e3488d34445eca90") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:url . "https://github.com/tarsius/frameshot"))]) (frames-only-mode . [(20180114 1848) ((emacs (24 4)) (dash (2 13 0)) (s (1 11 0))) "Use frames instead of Emacs windows" single ((:commit . "0f42139a41e97bb0a2ebc320d41cec071c034ca0") (:keywords "frames" "windows") (:authors ("David Shepherd" . "davidshepherd7@gmail.com")) (:maintainer "David Shepherd" . "davidshepherd7@gmail.com") (:url . "https://github.com/davidshepherd7/frames-only-mode"))]) (frame-tag . [(20170111 6) ((cl-lib (0 5))) "Minor mode that assigns a unique number to each frame for easy switching" single ((:commit . "73d6163568c7d32952175e663318b872f995a4e5") (:keywords "frame" "movement") (:authors ("Wong Liang Zan" . "zan@liangzan.net")) (:maintainer "Wong Liang Zan" . "zan@liangzan.net") (:url . "http://github.com/liangzan/frame-tag.el"))]) (frame-purpose . [(20180624 57) ((emacs (25 1)) (dash (2 12)) (dash-functional (1 2 0))) "Purpose-specific frames" single ((:commit . "ef571eb64acb4fef5c5ab22bc1e87a0e6614efa4") (:keywords "buffers" "convenience" "frames") (:authors ("Adam Porter" . "adam@alphapapa.net")) (:maintainer "Adam Porter" . "adam@alphapapa.net") (:url . "http://github.com/alphapapa/frame-purpose.el"))]) (frame-mode . [(20170419 2127) ((s (1 9 0)) (emacs (24 4))) "Use frames instead of windows" single ((:commit . "fcdbafbda45758cd60ab3acb492fbbd692987a58") (:keywords "frames") (:authors ("Ivan Malison" . "IvanMalison@gmail.com")) (:maintainer "Ivan Malison" . "IvanMalison@gmail.com") (:url . "https://github.com/IvanMalison/frame-mode"))]) (frame-local . [(20180330 940) ((emacs (25 1))) "Variables local to a frame" single ((:commit . "7ee1106c3bcd4022f48421f8cb1ef4f995da816e") (:keywords "frames" "tools" "local" "lisp") (:authors ("Sebastien Chapuis" . "sebastien@chapu.is")) (:maintainer "Sebastien Chapuis" . "sebastien@chapu.is") (:url . "https://github.com/sebastiencs/frame-local"))]) (fraktur-mode . [(20160815 227) ((cl-lib (0 5))) "Easily insert Unicode mathematical Fraktur characters" single ((:commit . "514baf5546aed12a0d9fa0fe66e87cdcc7843b08") (:keywords "unicode" "fraktur" "math" "mathematical") (:authors ("Grant Rettke" . "gcr@wisdomandwonder.com")) (:maintainer nil . "<gcr@wisdomandwonder.com>") (:url . "https://github.com/grettke/fraktur-mode"))]) (fountain-mode . [(20180808 621) ((emacs (24 5))) "Major mode for screenwriting in Fountain markup" single ((:commit . "26919a26e3107432d3ade56a19e0e5490dc2cbd9") (:keywords "wp" "text") (:authors ("Paul Rankin" . "hello@paulwrankin.com")) (:maintainer "Paul Rankin" . "hello@paulwrankin.com") (:url . "https://github.com/rnkn/fountain-mode"))]) (fortune-cookie . [(20170407 2217) nil "Print a fortune in your scratch buffer." single ((:commit . "bad99a2cd090f6646c7ee1125b95dd98744939c6") (:keywords "fortune" "cowsay" "scratch" "startup") (:authors ("Andrew Schwartzmeyer" . "andrew@schwartzmeyer.com")) (:maintainer "Andrew Schwartzmeyer" . "andrew@schwartzmeyer.com") (:url . "https://github.com/andschwa/fortune-cookie"))]) (fortpy . [(20150715 2032) ((epc (0 1 0)) (auto-complete (1 4)) (python-environment (0 0 2)) (pos-tip (0 4 5))) "a Fortran auto-completion for Emacs" tar ((:commit . "c614517e9396ef7a78be3b8786fbf303879cf43b") (:authors ("Conrad Rosenbrock <rosenbrockc at gmail.com>")) (:maintainer "Conrad Rosenbrock <rosenbrockc at gmail.com>"))]) (forth-mode . [(20170527 1930) nil "Programming language mode for Forth" tar ((:commit . "522256d98d1a909983bcfd3ae20c65226d5929b6") (:keywords "languages" "forth") (:authors ("Lars Brinkhoff" . "lars@nocrew.org")) (:maintainer "Lars Brinkhoff" . "lars@nocrew.org") (:url . "http://github.com/larsbrinkhoff/forth-mode"))]) (format-sql . [(20150422 1333) nil "Use format-sql to make your SQL readable in directly Emacs." single ((:commit . "97f475c245cd6c81a72a265678e2087cee66ac7b") (:authors ("Friedrich Paetzke" . "paetzke@fastmail.fm")) (:maintainer "Friedrich Paetzke" . "paetzke@fastmail.fm") (:url . "https://github.com/paetzke/format-sql.el"))]) (format-all . [(20180902 1158) ((emacs (24)) (cl-lib (0 5))) "Auto-format C, C++, JS, Python, Ruby and 25 other languages" single ((:commit . "d4a832c2fb6d0db76dff14342d001e69296f9316") (:keywords "languages" "util") (:authors ("Lassi Kortela" . "lassi@lassi.io")) (:maintainer "Lassi Kortela" . "lassi@lassi.io") (:url . "https://github.com/lassik/emacs-format-all-the-code"))]) (form-feed . [(20160102 2253) nil "Display ^L glyphs as horizontal lines" single ((:commit . "799ca3e72b20a59a755a094b8cead57f654f3170") (:keywords "faces") (:authors ("Vasilij Schneidermann" . "v.schneidermann@gmail.com")) (:maintainer "Vasilij Schneidermann" . "v.schneidermann@gmail.com") (:url . "https://github.com/wasamasa/form-feed"))]) (forest-blue-theme . [(20160627 842) ((emacs (24))) "Emacs theme with a dark background." single ((:commit . "58096ce1a25615d2bae806c3775bae3e2775019d") (:authors ("olkinn")) (:maintainer "olkinn"))]) (foreman-mode . [(20170725 1422) ((s (1 9 0)) (dash (2 10 0)) (dash-functional (1 2 0)) (f (0 17 2)) (emacs (24))) "View and manage Procfile-based applications" single ((:commit . "22b3bb13134b617870ed1e888af739f4818be929") (:keywords "foreman") (:authors ("ZHOU Feng" . "zf.pascal@gmail.com")) (:maintainer "ZHOU Feng" . "zf.pascal@gmail.com") (:url . "http://github.com/zweifisch/foreman-mode"))]) (foreign-regexp . [(20180224 1121) nil "search and replace by foreign regexp." tar ((:commit . "2ec5c44f27c2396ee487aa0ed77ae47d143fa5aa") (:keywords "convenience" "emulations" "matching" "tools" "unix" "wp") (:authors ("K-talo Miyazaki <Keitaro dot Miyazaki at gmail dot com>")) (:maintainer "K-talo Miyazaki <Keitaro dot Miyazaki at gmail dot com>"))]) (forecast . [(20180429 2215) ((emacs (24 4))) "Weather forecasts" single ((:commit . "05f2655321f020fd4c069d1939f0902eaa837eb4") (:keywords "weather" "forecast") (:authors ("Göktuğ Kayaalp" . "self@gkayaalp.com")) (:maintainer "Göktuğ Kayaalp" . "self@gkayaalp.com") (:url . "https://cadadr.github.io/elisp/index.html#forecast-el"))]) (fontify-face . [(20180420 1624) ((emacs (24))) "Fontify symbols representing faces with that face." single ((:commit . "fc3325c98427523d86f0b411e0515cec51ac3d8a") (:keywords "faces") (:authors ("Matúš Goljer" . "matus.goljer@gmail.com")) (:maintainer "Matúš Goljer" . "matus.goljer@gmail.com") (:url . "https://github.com/Fuco1/fontify-face"))]) (fontawesome . [(20170305 1356) ((emacs (24 4))) "fontawesome utility" tar ((:commit . "a743f80bfd53767ca9ee32da34c5ca032172a480") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-fontawesome"))]) (font-utils . [(20150806 1751) ((persistent-soft (0 8 8)) (pcache (0 2 3))) "Utility functions for working with fonts" single ((:commit . "9192d3f8ee6a4e75f34c3fed10378674cc2b11d3") (:keywords "extensions") (:authors ("Roland Walker" . "walker@pobox.com")) (:maintainer "Roland Walker" . "walker@pobox.com") (:url . "http://github.com/rolandwalker/font-utils"))]) (font-lock-studio . [(20170127 2051) ((emacs (24 3))) "interactive debugger for Font Lock keywords." single ((:commit . "12c35967b31233e06946c70627aa3152dacfe261") (:keywords "faces" "tools") (:authors ("Anders Lindgren")) (:maintainer "Anders Lindgren") (:url . "https://github.com/Lindydancer/font-lock-studio"))]) (font-lock-profiler . [(20170208 2008) ((emacs (24 3))) "Coverage and timing tool for font-lock keywords." single ((:commit . "6e096458416888a4f63cca0d6bc5965a052753c8") (:keywords "faces" "tools") (:authors ("Anders Lindgren")) (:maintainer "Anders Lindgren") (:url . "https://github.com/Lindydancer/font-lock-profiler"))]) (folding . [(20170925 1538) nil "A folding-editor-like minor mode." single ((:commit . "3bf134fd1ecfa8767ab7020c25281ea5ce9968a2") (:keywords "tools") (:maintainer "Jari Aalto <jari aalto A T cante dt net>"))]) (fold-this . [(20180828 1336) nil "Just fold this region please" single ((:commit . "59ec711ee5f4decf197b8168e333b691b852c827") (:keywords "convenience") (:authors ("Magnar Sveen" . "magnars@gmail.com")) (:maintainer "Magnar Sveen" . "magnars@gmail.com"))]) (fold-dwim-org . [(20131203 1351) ((fold-dwim (1 2))) "Fold DWIM bound to org key-strokes." single ((:commit . "c09bb2b46d65afbd1d0febc6fded7495be7a3037") (:keywords "folding" "emacs" "org-mode") (:authors ("Matthew L. Fidler & Shane Celis")) (:maintainer "Matthew L. Fidler") (:url . "https://github.com/mlf176f2/fold-dwim-org"))]) (fold-dwim . [(20140208 1637) nil "Unified user interface for Emacs folding modes" single ((:commit . "c46f4bb2ce91b4e307136320e72c28dd50b6cd8b") (:authors ("Peter Heslin" . "p.j.heslin@dur.ac.uk")) (:maintainer "Peter Heslin" . "p.j.heslin@dur.ac.uk") (:url . "http://www.dur.ac.uk/p.j.heslin/Software/Emacs"))]) (foggy-night-theme . [(20160209 1508) ((emacs (24))) "Dark low contrast theme with soft and muted colors." single ((:commit . "60a12abdac29c2d913e1cf24485d0cc083e26093") (:authors ("Martin Haesler")) (:maintainer "Martin Haesler"))]) (focus-autosave-mode . [(20160519 2116) ((emacs (24 4))) "Automatically save files in focus-out-hook." single ((:commit . "e89ed22aa4dfc76e1b844b202aedd468ad58814a") (:keywords "convenience" "files" "frames" "mouse") (:authors ("Wojciech Siewierski" . "wojciech.siewierski@onet.pl")) (:maintainer "Wojciech Siewierski" . "wojciech.siewierski@onet.pl"))]) (focus . [(20171204 503) ((emacs (24)) (cl-lib (0 5))) "Dim the font color of text in surrounding sections" single ((:commit . "045ee6175e9340f873db03445c74ff9eefa35a27") (:authors ("Lars Tveito" . "larstvei@ifi.uio.no")) (:maintainer "Lars Tveito" . "larstvei@ifi.uio.no") (:url . "http://github.com/larstvei/Focus"))]) (fn . [(20170210 204) ((emacs (24)) (cl-lib (0 5)) (dash (2 12 1)) (dash-functional (1 2 0))) "Concise anonymous functions for Emacs Lisp" single ((:commit . "f685fd0c08ec3b1d1b9974b37e62edd78a000cb8") (:keywords "functional") (:authors ("Troy Pracy")) (:maintainer "Troy Pracy"))]) (fm-bookmarks . [(20170104 1716) ((emacs (24 3)) (cl-lib (0 5))) "Use file manager bookmarks (eg Dolphin, Nautilus, PCManFM) in Dired" single ((:commit . "11dacfd16a926bfecba96a94c6b13e162c7717f7") (:keywords "files" "convenience") (:authors ("Ono Hiroko" . "azazabc123@gmail.com")) (:maintainer "Ono Hiroko" . "azazabc123@gmail.com") (:url . "http://github.com/kuanyui/fm-bookmarks.el"))]) (flyspell-popup . [(20170529 815) ((popup (0 5 0))) "Correcting words with Flyspell in popup menus" single ((:commit . "29311849bfd253b9b689bf331860b4c4d3bd4dde") (:keywords "convenience") (:authors ("Chunyang Xu" . "mail@xuchunyang.me")) (:maintainer "Chunyang Xu" . "mail@xuchunyang.me") (:url . "https://github.com/xuchunyang/flyspell-popup"))]) (flyspell-lazy . [(20180224 2106) nil "Improve flyspell responsiveness using idle timers" single ((:commit . "3ebf68cc9eb10c972a2de8d7861cbabbbce69570") (:keywords "spelling") (:authors ("Roland Walker" . "walker@pobox.com")) (:maintainer "Roland Walker" . "walker@pobox.com") (:url . "http://github.com/rolandwalker/flyspell-lazy"))]) (flyspell-correct-popup . [(20180427 1835) ((flyspell-correct (0 4 0)) (popup (0 5 3))) "correcting words with flyspell via popup interface" single ((:commit . "0486912f57ac2ec70c472b776c63360462cb32d7") (:authors ("Boris Buliga" . "boris@d12frosted.io")) (:maintainer "Boris Buliga" . "boris@d12frosted.io") (:url . "https://github.com/d12frosted/flyspell-correct"))]) (flyspell-correct-ivy . [(20180427 1835) ((flyspell-correct (0 4 0)) (ivy (0 8 0))) "correcting words with flyspell via ivy interface" single ((:commit . "0486912f57ac2ec70c472b776c63360462cb32d7") (:authors ("Boris Buliga" . "boris@d12frosted.io")) (:maintainer "Boris Buliga" . "boris@d12frosted.io") (:url . "https://github.com/d12frosted/flyspell-correct"))]) (flyspell-correct-helm . [(20180427 1835) ((flyspell-correct (0 4 0)) (helm (1 9 0))) "correcting words with flyspell via helm interface" single ((:commit . "0486912f57ac2ec70c472b776c63360462cb32d7") (:authors ("Boris Buliga" . "boris@d12frosted.io")) (:maintainer "Boris Buliga" . "boris@d12frosted.io") (:url . "https://github.com/d12frosted/flyspell-correct"))]) (flyspell-correct . [(20180427 1835) nil "correcting words with flyspell via custom interface" tar ((:commit . "0486912f57ac2ec70c472b776c63360462cb32d7") (:authors ("Boris Buliga" . "boris@d12frosted.io")) (:maintainer "Boris Buliga" . "boris@d12frosted.io") (:url . "https://github.com/d12frosted/flyspell-correct"))]) (flyparens . [(20140723 1846) nil "Check for unbalanced parens on the fly" tar ((:commit . "af9b8cfd647d0e5f97684d613dc2eea7cfc19398") (:keywords "faces" "convenience" "lisp" "matching" "parentheses" "parens") (:authors ("Jisang Yoo")) (:maintainer "Jisang Yoo"))]) (flymd . [(20160617 1214) ((cl-lib (0 5))) "On the fly markdown preview" tar ((:commit . "84d5a68bcfed4a295952c33ffcd11e880978d9d7") (:keywords "markdown" "convenience") (:authors ("Mola-T" . "Mola@molamola.xyz")) (:maintainer "Mola-T" . "Mola@molamola.xyz") (:url . "https://github.com/mola-T/flymd"))]) (flymake-yaml . [(20130423 1548) ((flymake-easy (0 1))) "A flymake handler for YAML" single ((:commit . "24cb5b744a1796e554e6dbfc6eeb237d06a00b10") (:keywords "yaml") (:authors ("Yasuyuki Oka" . "yasuyk@gmail.com")) (:maintainer "Yasuyuki Oka" . "yasuyk@gmail.com") (:url . "https://github.com/yasuyk/flymake-yaml"))]) (flymake-vala . [(20150326 531) ((flymake-easy (0 1))) "A flymake handler for vala-mode files" single ((:commit . "c3674f461fc84fb0300cd3a562fb903a59782745") (:keywords "convenience" "vala") (:authors ("Daniel Lawrence" . "dannyla@linux.com")) (:maintainer "Daniel Lawrence" . "dannyla@linux.com") (:url . "https://github.com/daniellawrence/flymake-vala"))]) (flymake-solidity . [(20170805 644) ((flymake-easy (0 10))) "A flymake handler for solidity using solc" single ((:commit . "48bfe9525f764d8a68cc0270905dbf45bfd00bb8") (:authors ("Pascal van Kooten" . "kootenpv@gmail.com")) (:maintainer "Pascal van Kooten" . "kootenpv@gmail.com") (:url . "https://github.com/kootenvp/flymake-solidity"))]) (flymake-shellcheck . [(20180830 1145) ((emacs (26))) "A bash/sh Flymake backend" single ((:commit . "4325f0e952b9f3c0172887f45068c3ae1de097d9") (:authors ("Federico Tedin" . "federicotedin@gmail.com")) (:maintainer "Federico Tedin" . "federicotedin@gmail.com") (:url . "https://github.com/federicotdn/flymake-shellcheck"))]) (flymake-shell . [(20170723 146) ((flymake-easy (0 1))) "A flymake syntax-checker for shell scripts" single ((:commit . "a16cf453056b9849cc7c912bb127fb0b08fc6dab") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:url . "https://github.com/purcell/flymake-shell"))]) (flymake-sass . [(20170723 146) ((flymake-easy (0 1))) "Flymake handler for sass and scss files" single ((:commit . "2de28148e92deb93bff3d55fe14e7c67ac476056") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:url . "https://github.com/purcell/flymake-sass"))]) (flymake-rust . [(20170729 2139) ((flymake-easy (0 1))) "A flymake handler for rust-mode files" single ((:commit . "2f42d1f2dad73ec9de460eda6176e3ab25c446f0") (:authors ("Joao Oliveira" . "joaoxsouls@gmail.com")) (:maintainer "Joao Oliveira" . "joaoxsouls@gmail.com") (:url . "https://github.com/joaoxsouls/flymake-rust"))]) (flymake-ruby . [(20170723 146) ((flymake-easy (0 1))) "A flymake handler for ruby-mode files" single ((:commit . "6c320c6fb686c5223bf975cc35178ad6b195e073") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:url . "https://github.com/purcell/flymake-ruby"))]) (flymake-python-pyflakes . [(20170723 146) ((flymake-easy (0 8))) "A flymake handler for python-mode files using pyflakes (or flake8)" single ((:commit . "1d65c26bf65a5dcbd29fcd967e2feb90e1e7a33d") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:url . "https://github.com/purcell/flymake-python-pyflakes"))]) (flymake-puppet . [(20170801 554) ((flymake-easy (0 9))) "Flymake handler using puppet-lint" single ((:commit . "8a772395f4ccc59d883712ab53a92a17c1d9a429") (:authors ("Ben Prew")) (:maintainer "Ben Prew") (:url . "https://github.com/benprew/flymake-puppet"))]) (flymake-phpcs . [(20140713 631) ((flymake-easy (0 9))) "making flymake work with PHP CodeSniffer" single ((:commit . "a4d383474e055e554aaf1cd617055d5d7181aa50") (:keywords "flymake" "phpcs" "php") (:authors ("Akiha Senda")) (:maintainer "Akiha Senda") (:url . "https://github.com/senda-akiha/flymake-phpcs/"))]) (flymake-php . [(20170723 146) ((flymake-easy (0 1))) "A flymake handler for php-mode files" single ((:commit . "c045d01e002ba5e09b05f40e25bf5068d02126bc") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:url . "https://github.com/purcell/flymake-php"))]) (flymake-perlcritic . [(20120328 814) ((flymake (0 3))) "Flymake handler for Perl to invoke Perl::Critic" tar ((:commit . "edfaa86500ddfa8a6a6f51f5581a81a821277df6") (:authors ("Sam Graham <libflymake-perlcritic-emacs BLAHBLAH illusori.co.uk>")) (:maintainer "Sam Graham <libflymake-perlcritic-emacs BLAHBLAH illusori.co.uk>") (:url . "https://github.com/illusori/emacs-flymake-perlcritic"))]) (flymake-lua . [(20170129 154) nil "Flymake for Lua" single ((:commit . "84589f20066921a5b79cf3a1f914a223a2552d2a") (:keywords "lua") (:authors (nil . "Sébastien Roccaserra (format \"<%s%s@%s.%s>\" \"s\" \"roccaserra\" \"yahoo\" \"com\")")) (:maintainer nil . "Sébastien Roccaserra (format \"<%s%s@%s.%s>\" \"s\" \"roccaserra\" \"yahoo\" \"com\")"))]) (flymake-less . [(20151111 738) ((less-css-mode (0 15)) (flymake-easy (0 1))) "Flymake handler for LESS stylesheets (lesscss.org)" single ((:commit . "32d3c28a9a5c52b82d1741ff9d715013b6498421") (:keywords "languages") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com"))]) (flymake-ktlint . [(20180831 346) ((emacs (26 1))) "Flymake extension for Ktlint." single ((:commit . "33730a4818b74cb27196f06a9b23045d0af4c16d") (:keywords "languages" "ktlint") (:maintainer "James Nguyen" . "james@jojojames.com") (:url . "https://github.com/jojojames/flymake-ktlint"))]) (flymake-json . [(20180511 911) ((flymake-easy (0 1))) "A flymake handler for json using jsonlint" single ((:commit . "ae58795f948402e987cda4c15f10354f8ec2d0fd") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:url . "https://github.com/purcell/flymake-json"))]) (flymake-jslint . [(20170723 146) ((flymake-easy (0 1))) "A flymake handler for javascript using jslint" single ((:commit . "8edb82be605542b0ef62d38d818adcdde335eecb") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:url . "https://github.com/purcell/flymake-jslint"))]) (flymake-jshint . [(20140319 2200) ((flymake-easy (0 8))) "making flymake work with JSHint" single ((:commit . "79dd554c227883c487db38ac111306c8d5382c95") (:keywords "flymake" "jshint" "javascript") (:authors ("Wilfred Hughes" . "me@wilfred.me.uk")) (:maintainer "Wilfred Hughes" . "me@wilfred.me.uk"))]) (flymake-hlint . [(20170723 146) ((flymake-easy (0 1))) "A flymake handler for haskell-mode files using hlint" single ((:commit . "f910736b26784efc9a2fa29503f45c1f1dd0aa38") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:url . "https://github.com/purcell/flymake-hlint"))]) (flymake-haskell-multi . [(20170723 146) ((flymake-easy (0 1))) "Syntax-check haskell-mode using both ghc and hlint" tar ((:commit . "b564a94312259885b1380272eb867bf52a164020"))]) (flymake-haml . [(20170723 146) ((flymake-easy (0 1))) "A flymake handler for haml files" single ((:commit . "22a81e8484734552d461e7ae7305664dc244447e") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:url . "https://github.com/purcell/flymake-haml"))]) (flymake-google-cpplint . [(20140205 1325) ((flymake-easy (0 9))) "Help to comply with the Google C++ Style Guide" single ((:commit . "905d32e84a27f18a78bec455ca930ab1ff9ae31e") (:keywords "flymake" "c" "c++") (:authors ("Akiha Senda" . "senda.akiha@gmail.com")) (:maintainer "Akiha Senda" . "senda.akiha@gmail.com") (:url . "https://github.com/senda-akiha/flymake-google-cpplint/"))]) (flymake-go . [(20150714 733) nil "A flymake handler for go-mode files" single ((:commit . "ae83761aa908c1a50ff34af04f00dcc46bca2ce9") (:keywords "go" "flymake") (:authors ("Michael Fellinger" . "michael@iron.io") ("Robert Zaremba" . "robert.marek.zaremba@wp.eu")) (:maintainer "Michael Fellinger" . "michael@iron.io") (:url . "https://github.com/robert-zaremba/flymake-go"))]) (flymake-gjshint . [(20130327 1232) nil "A flymake handler for javascript using both jshint and gjslint" single ((:commit . "dc957c14cb060819585de8aedb330e24efa4b784") (:keywords "flymake" "javascript" "jshint" "gjslint") (:authors ("Yasuyuki Oka" . "yasuyk@gmail.com")) (:maintainer "Yasuyuki Oka" . "yasuyk@gmail.com"))]) (flymake-elixir . [(20130810 1417) nil "A flymake handler for elixir-mode .ex files." single ((:commit . "3810566cffe35d04cc3f01e27fe397d68d52f802") (:authors ("Sylvain Benner" . "syl20bnr@gmail.com")) (:maintainer "Sylvain Benner" . "syl20bnr@gmail.com"))]) (flymake-easy . [(20140818 755) nil "Helpers for easily building flymake checkers" single ((:commit . "de41ea49503f71f997e5c359a2ad08df696c0147") (:keywords "convenience" "internal") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:url . "https://github.com/purcell/flymake-easy"))]) (flymake-cursor . [(20120322 1757) ((flymake (0 3))) "Show flymake messages in the minibuffer after delay" single ((:commit . "ecc539082c3fc9e91bba33d72c26989217411593") (:keywords "languages" "mode" "flymake") (:authors ("Unknown Original Author") ("Dino Chiesa" . "dpchiesa@hotmail.com") ("Sam Graham <libflymake-emacs BLAHBLAH illusori.co.uk>")) (:maintainer "Sam Graham <libflymake-emacs BLAHBLAH illusori.co.uk>") (:url . "https://github.com/illusori/emacs-flymake-cursor"))]) (flymake-css . [(20170723 146) ((flymake-easy (0 1))) "Flymake support for css using csslint" single ((:commit . "de090163ba289910ceeb61b13368ce42d0f2dfd8") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:url . "https://github.com/purcell/flymake-css"))]) (flymake-cppcheck . [(20140415 1257) ((flymake-easy (0 9))) "Flymake work with Cppcheck for C/C++" single ((:commit . "9554f504d425a04fa6a875f7e3179bc7cf07dd03") (:keywords "flymake" "cppcheck" "c" "c++") (:authors ("Akiha Senda" . "senda.akiha@gmail.com")) (:maintainer "Akiha Senda" . "senda.akiha@gmail.com") (:url . "https://github.com/senda-akiha/flymake-cppcheck/"))]) (flymake-coffee . [(20170723 146) ((flymake-easy (0 1))) "A flymake handler for coffee script" single ((:commit . "dee295acf30820ed15fe0de17137d50bc27fc80c") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:url . "https://github.com/purcell/flymake-coffee"))]) (flycheck-ycmd . [(20180207 1643) ((emacs (24)) (dash (2 13 0)) (flycheck (0 22)) (ycmd (1 2)) (let-alist (1 0 5))) "flycheck integration for ycmd" single ((:commit . "fe35b7f2e3d9370941b9e537c9bc578d814acce2") (:authors ("Austin Bingham" . "austin.bingham@gmail.com")) (:maintainer "Austin Bingham" . "austin.bingham@gmail.com") (:url . "https://github.com/abingham/emacs-ycmd"))]) (flycheck-yang . [(20180312 1831) ((yang-mode (0 9 4)) (flycheck (0 18))) "YANG flycheck checker" single ((:commit . "47881fc42ef0163c47064b72b5d6dbef4f83d778") (:authors (nil . "Andrew Fort (@andaru)")) (:maintainer nil . "Andrew Fort (@andaru)"))]) (flycheck-yamllint . [(20170325 1735) ((flycheck (30))) "Flycheck integration for YAMLLint" single ((:commit . "c2b273d84f15bd03464d6722391e595d7c179a5c") (:keywords "convenience" "languages" "tools") (:authors ("Krzysztof Magosa" . "krzysztof@magosa.pl")) (:maintainer "Krzysztof Magosa" . "krzysztof@magosa.pl") (:url . "https://github.com/krzysztof-magosa/flycheck-yamllint"))]) (flycheck-xcode . [(20180122 651) ((emacs (25 1)) (flycheck (0 25))) "Flycheck extension for Apple's Xcode." single ((:commit . "6147ab777e2c08e4f5ffdbd85d3013ca700fa835") (:keywords "languages" "xcode") (:maintainer "James Nguyen" . "james@jojojames.com") (:url . "https://github.com/jojojames/flycheck-xcode"))]) (flycheck-vdm . [(20180831 652) ((emacs (24)) (flycheck (32 -4)) (vdm-mode (0 0 3))) "Syntax checking for vdm-mode" single ((:commit . "d5ee09de825c1ce53b1c68dfe318d879bf87e554") (:keywords "languages") (:authors ("Peter W. V. Tran-Jørgensen" . "peter.w.v.jorgensen@gmail.com")) (:maintainer "Peter W. V. Tran-Jørgensen" . "peter.w.v.jorgensen@gmail.com") (:url . "https://github.com/peterwvj/vdm-mode"))]) (flycheck-vale . [(20180309 643) ((emacs (24 4)) (flycheck (0 22)) (let-alist (1 0 4))) "flycheck integration for vale" single ((:commit . "7777e0d4cf961b6ee6ae4ef917636121d18b3ee8") (:authors ("Austin Bingham" . "austin.bingham@gmail.com")) (:maintainer "Austin Bingham" . "austin.bingham@gmail.com") (:url . "https://github.com/abingham/flycheck-vale"))]) (flycheck-title . [(20170216 2346) ((flycheck (30)) (emacs (24))) "show flycheck errors in the frame title" single ((:commit . "6faea67be8661faf8152217869d16e993cc2bc49") (:authors ("Wilfred Hughes" . "me@wilfred.me.uk")) (:maintainer "Wilfred Hughes" . "me@wilfred.me.uk"))]) (flycheck-tip . [(20171020 1048) ((flycheck (29)) (emacs (24 1)) (popup (0 5 0))) "Show flycheck/flymake errors by tooltip" tar ((:commit . "9b0072d92e6b4a52834bf5a34120a0f5e1c8c2fd") (:keywords "flycheck") (:authors ("Yuta Yamada <cokesboy\"at\"gmail.com>")) (:maintainer "Yuta Yamada <cokesboy\"at\"gmail.com>") (:url . "https://github.com/yuutayamada/flycheck-tip"))]) (flycheck-tcl . [(20180327 1259) ((emacs (24 4)) (flycheck (0 22))) "A flycheck checker for Tcl using tclchecker" single ((:commit . "7ca23f4673e178b9f5dcc8a82b86cf05b15d7236") (:authors ("Niels Widger" . "niels.widger@gmail.com")) (:maintainer "Niels Widger" . "niels.widger@gmail.com") (:url . "https://github.com/nwidger/flycheck-tcl"))]) (flycheck-swiftlint . [(20180830 340) ((emacs (25 1)) (flycheck (0 25))) "Flycheck extension for Swiftlint." single ((:commit . "65101873c4c9f8e7eac9471188b161eeddda1555") (:keywords "languages" "swiftlint" "swift" "emacs") (:maintainer "James Nguyen" . "james@jojojames.com") (:url . "https://github.com/jojojames/flycheck-swiftlint"))]) (flycheck-swift3 . [(20180411 1352) ((emacs (24 4)) (flycheck (26))) "Flycheck: Swift support for Apple swift-mode" single ((:commit . "06a6f98d7e498860b345bbd03e96bfe59608f508") (:keywords "convenience" "languages" "tools") (:authors ("Goichi Hirakawa" . "gooichi@gyazsquare.com")) (:maintainer "Goichi Hirakawa" . "gooichi@gyazsquare.com") (:url . "https://github.com/GyazSquare/flycheck-swift3"))]) (flycheck-swift . [(20170129 549) ((emacs (24 4)) (flycheck (0 25))) "Flycheck extension for Apple's Swift." single ((:commit . "4c5ad401252400a78da395fd56a71e67ff8c2761") (:keywords "languages" "swift"))]) (flycheck-status-emoji . [(20180330 2325) ((cl-lib (0 1)) (emacs (24)) (flycheck (0 20)) (let-alist (1 0))) "Show flycheck status using cute, compact emoji" single ((:commit . "4bd113ab42dec9544b66e0a27ed9008ce8148433") (:keywords "convenience" "languages" "tools") (:authors ("Ben Liblit" . "liblit@acm.org")) (:maintainer "Ben Liblit" . "liblit@acm.org") (:url . "https://github.com/liblit/flycheck-status-emoji"))]) (flycheck-stack . [(20160520 944) ((flycheck (26)) (haskell-mode (13))) "Flychecker using stack ghci" single ((:commit . "f04235e00998000ee2c305f5a3ee72bb5dbbc926"))]) (flycheck-rust . [(20180904 1117) ((emacs (24 1)) (flycheck (28)) (dash (2 13 0)) (seq (2 3)) (let-alist (1 0 4))) "Flycheck: Rust additions and Cargo support" single ((:commit . "f1220ccd9acbdb2556765f49f2f3dcb00dca2970") (:keywords "tools" "convenience") (:authors ("Sebastian Wiesner" . "swiesner@lunaryorn.com")) (:maintainer "Sebastian Wiesner" . "swiesner@lunaryorn.com") (:url . "https://github.com/flycheck/flycheck-rust"))]) (flycheck-rtags . [(20180619 824) ((emacs (24)) (flycheck (0 23)) (rtags (2 10))) "RTags Flycheck integration." single ((:commit . "fc63be8f48bed6703b37ccb1057d75d7ce5200ca") (:authors ("Christian Schwarzgruber" . "c.schwarzgruber.cs@gmail.com")) (:maintainer "Christian Schwarzgruber" . "c.schwarzgruber.cs@gmail.com") (:url . "http://rtags.net"))]) (flycheck-rebar3 . [(20180806 2103) ((flycheck (27))) "Rebar3 flycheck integration for Erlang projects" single ((:commit . "3cca1268c54643204b5bae52e3f0bf5bc921018c") (:keywords "erlang" "flycheck" "rebar3") (:authors ("Joe DeVivo")) (:maintainer "Joe DeVivo") (:url . "https://github/joedevivo/flycheck-rebar3"))]) (flycheck-pyflakes . [(20170330 2311) ((flycheck (0 18))) "Support pyflakes in flycheck" single ((:commit . "61b045939e3743b2162b7e4e73249c66fc2b8f65") (:authors ("Wilfred Hughes" . "me@wilfred.me.uk")) (:maintainer "Wilfred Hughes" . "me@wilfred.me.uk"))]) (flycheck-pycheckers . [(20180820 2044) ((flycheck (0 18))) "multiple syntax checker for Python, using Flycheck" tar ((:commit . "427e54a783174004202b6397b1e060c4b0a6989f") (:keywords "convenience" "tools" "languages") (:url . "https://github.com/msherry/flycheck-pycheckers"))]) (flycheck-purescript . [(20161121 1707) ((emacs (24 3)) (flycheck (0 22)) (dash (2 12 0)) (let-alist (1 0 4)) (seq (1 11))) "Flycheck: PureScript support" single ((:commit . "30f0435d5e2715053c8c6170b2bce2ae462ac819") (:keywords "convenience" "tools" "languages") (:authors ("Mario Rodas" . "marsam@users.noreply.github.com")) (:maintainer "Mario Rodas" . "marsam@users.noreply.github.com") (:url . "https://github.com/emacs-pe/flycheck-purescript"))]) (flycheck-prospector . [(20180524 450) ((flycheck (0 22))) "Support prospector in flycheck" single ((:commit . "92f2680573290ba4a69a2d6e140f44680efce6a8") (:authors ("Carlos Coelho" . "carlospecter@gmail.com")) (:maintainer "Carlos Coelho" . "carlospecter@gmail.com") (:url . "https://github.com/chocoelho/flycheck-prospector"))]) (flycheck-posframe . [(20180322 607) ((flycheck (0 24)) (emacs (26)) (posframe (0 3 0))) "Show flycheck error messages using posframe.el" single ((:commit . "61bdfd4b04e1651163fdcaa7dc631ad073b3e513") (:authors ("Alex Murray" . "murray.alex@gmail.com")) (:maintainer "Alex Murray" . "murray.alex@gmail.com") (:url . "https://github.com/alexmurray/flycheck-posframe"))]) (flycheck-pos-tip . [(20180610 1615) ((emacs (24 1)) (flycheck (0 22)) (pos-tip (0 4 6))) "Display Flycheck errors in GUI tooltips" single ((:commit . "909113977d37739387c7f099d74a724cfe6efcec") (:keywords "tools" "convenience") (:authors ("Akiha Senda" . "senda.akiha@gmail.com") ("Sebastian Wiesner" . "swiesner@lunaryorn.com")) (:maintainer "Sebastian Wiesner" . "swiesner@lunaryorn.com") (:url . "https://github.com/flycheck/flycheck-pos-tip"))]) (flycheck-popup-tip . [(20170812 2351) ((flycheck (0 22)) (popup (0 5)) (emacs (24))) "Display Flycheck error messages using popup.el" single ((:commit . "ef86aad907f27ca076859d8d9416f4f7727619c6") (:keywords "convenience" "tools" "flycheck" "tooltip") (:authors ("Saša Jovanić" . "sasa@simplify.ba")) (:maintainer "Saša Jovanić" . "sasa@simplify.ba") (:url . "https://github.com/flycheck/flycheck-popup-tip/"))]) (flycheck-pony . [(20160501 2117) ((flycheck (0 25 1))) "Pony support in Flycheck" single ((:commit . "ef27475a14090396a01924d131bfee9e163cf6e9") (:keywords "tools" "convenience") (:url . "https://github.com/seantallen/flycheck-pony"))]) (flycheck-plantuml . [(20171018 111) ((flycheck (0 24)) (emacs (24 4)) (plantuml-mode (1 2 2))) "Integrate plantuml with flycheck" single ((:commit . "183be89e1dbba0b38237dd198dff600e0790309d") (:authors ("Alex Murray" . "murray.alex@gmail.com")) (:maintainer "Alex Murray" . "murray.alex@gmail.com") (:url . "https://github.com/alexmurray/flycheck-plantuml"))]) (flycheck-pkg-config . [(20180430 2243) ((dash (2 8 0)) (s (1 9 0)) (flycheck (29))) "configure flycheck using pkg-config" single ((:commit . "e72e4c1b8153611ed82695673af84096f4d52795") (:keywords "flycheck") (:authors ("Wilfred Hughes" . "me@wilfred.me.uk")) (:maintainer "Wilfred Hughes" . "me@wilfred.me.uk"))]) (flycheck-phpstan . [(20180801 1741) ((emacs (24 3)) (flycheck (26)) (phpstan (0 2 1))) "Flycheck integration for PHPStan" single ((:commit . "beac0e0e7160454d4f42162b3502a36ccf488120") (:keywords "convenience" "php") (:authors ("USAMI Kenta" . "tadsan@zonu.me")) (:maintainer "USAMI Kenta" . "tadsan@zonu.me") (:url . "https://github.com/emacs-php/phpstan.el"))]) (flycheck-perl6 . [(20180509 2201) ((emacs (24 3)) (flycheck (0 22))) "Perl 6 support in Flycheck" single ((:commit . "b804702305d7a6e26f762ff98cfdeec2e9dd4cb7") (:keywords "tools" "convenience") (:authors ("Hinrik Örn Sigurðsson" . "hinrik.sig@gmail.com")) (:maintainer "Hinrik Örn Sigurðsson" . "hinrik.sig@gmail.com") (:url . "https://github.com/hinrik/flycheck-perl6"))]) (flycheck-package . [(20161111 2251) ((flycheck (0 22)) (package-lint (0 2))) "A Flycheck checker for elisp package authors" single ((:commit . "6d99248b45eea1e5236062f38e524230efdb1a84") (:keywords "lisp") (:authors ("Steve Purcell" . "steve@sanityinc.com") ("Fanael Linithien" . "fanael4@gmail.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com"))]) (flycheck-ocaml . [(20170730 2153) ((emacs (24 1)) (flycheck (0 22)) (merlin (3 0 1)) (let-alist (1 0 3))) "Flycheck: OCaml support" single ((:commit . "8707a7bf545a8639a6a5c600a98d9a2ea1487dc9") (:keywords "convenience" "tools" "languages") (:authors ("Sebastian Wiesner" . "swiesner@lunaryorn.com")) (:maintainer "Sebastian Wiesner" . "swiesner@lunaryorn.com") (:url . "https://github.com/flycheck/flycheck-ocaml"))]) (flycheck-objc-clang . [(20180410 1122) ((emacs (24 4)) (flycheck (26))) "Flycheck: Objective-C support using Clang" single ((:commit . "f4a76ac199b67ff383ab5e70434c9b98b48c92d5") (:keywords "convenience" "languages" "tools") (:authors ("Goichi Hirakawa" . "gooichi@gyazsquare.com")) (:maintainer "Goichi Hirakawa" . "gooichi@gyazsquare.com") (:url . "https://github.com/GyazSquare/flycheck-objc-clang"))]) (flycheck-nimsuggest . [(20171027 2208) ((flycheck (0 23)) (emacs (24 3))) "flycheck backend for Nim using nimsuggest" single ((:commit . "dc9a5de1cb3ee05db5794d824610959a1f603bc9") (:authors ("Yuta Yamada <cokesboy\"at\"gmail.com>")) (:maintainer "Yuta Yamada <cokesboy\"at\"gmail.com>") (:url . "https://github.com/yuutayamada/flycheck-nimsuggest"))]) (flycheck-nim . [(20160715 428) ((dash (2 4 0)) (flycheck (0 20))) "Defines a flycheck syntax checker for nim" single ((:commit . "6d27349b66e44578851e6148299709d64d2bde41") (:authors ("Adam Schwalm" . "adamschwalm@gmail.com")) (:maintainer "Adam Schwalm" . "adamschwalm@gmail.com") (:url . "https://github.com/ALSchwalm/flycheck-nim"))]) (flycheck-mypy . [(20180518 704) ((flycheck (0 18))) "Support mypy in flycheck" single ((:commit . "043e8bba13a6d5e760cde8374c8f77d90946a1f5") (:authors ("Lorenzo Bolla" . "lbolla@gmail.com")) (:maintainer "Lorenzo Bolla" . "lbolla@gmail.com"))]) (flycheck-mmark . [(20180203 1732) ((emacs (24 4)) (flycheck (0 29))) "Flycheck checker for the MMark markdown processor" single ((:commit . "7fdcc48ff6ffa5e7db126a76f4948ab08b9eb8d4") (:keywords "convenience" "text") (:authors ("Mark Karpov" . "markkarpov92@gmail.com")) (:maintainer "Mark Karpov" . "markkarpov92@gmail.com") (:url . "https://github.com/mmark-md/flycheck-mmark"))]) (flycheck-mix . [(20170118 1430) ((flycheck (27)) (elixir-mode (1 8 0))) "Elixir mix flycheck integration" single ((:commit . "76684d4b5987925b98b254aab656f8bf8198ab88") (:keywords "elixir" "flycheck" "mix") (:authors ("Tomasz Kowal" . "tomekowal@gmail.com")) (:maintainer "Tomasz Kowal" . "tomekowal@gmail.com") (:url . "https://github.com/tomekowal/flycheck-mix"))]) (flycheck-mercury . [(20151123 734) ((flycheck (0 22)) (s (1 9 0)) (dash (2 4 0))) "Mercury support in Flycheck" single ((:commit . "fa9e433a0a912f0fae9e4dec9ea616ef99fcf861") (:keywords "convenience" "languages" "tools") (:authors ("Matthias Güdemann" . "matthias.gudemann@gmail.com")) (:maintainer "Matthias Güdemann" . "matthias.gudemann@gmail.com") (:url . "https://github.com/flycheck/flycheck-mercury"))]) (flycheck-liquidhs . [(20170412 2326) ((flycheck (0 15))) "A flycheck checker for Haskell using liquid (i.e. liquidhaskell)" single ((:commit . "c27252ac24d77f4b6eec76a4ba9cd61761a3fba9") (:keywords "convenience" "languages" "tools") (:authors ("Ranjit Jhala" . "jhala@cs.ucsd.edu")) (:maintainer "Ranjit Jhala" . "jhala@cs.ucsd.edu") (:url . "https://github.com/ucsd-progsys/liquidhaskell/flycheck-liquid.el"))]) (flycheck-lilypond . [(20171203 1332) ((emacs (24 3)) (flycheck (0 22))) "LilyPond support in Flycheck" single ((:commit . "cc1b7677a932c42e5dab1661ad7b923d4aae744c") (:keywords "tools" "convenience") (:authors ("Hinrik Örn Sigurðsson" . "hinrik.sig@gmail.com")) (:maintainer "Hinrik Örn Sigurðsson" . "hinrik.sig@gmail.com") (:url . "https://github.com/hinrik/flycheck-lilypond"))]) (flycheck-ledger . [(20180819 321) ((flycheck (0 15))) "Flycheck integration for ledger files" single ((:commit . "8d7f52a4c7f80ca396ef0fc6c7d8e9f005778dfc") (:keywords "convenience" "languages" "tools") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com"))]) (flycheck-kotlin . [(20170122 1137) ((flycheck (0 18))) "Support kotlin in flycheck" single ((:commit . "cbb9fbf70dbe8efcc3971b3606ee95c97469b1fe") (:authors ("Elric Milon" . "whirm_REMOVETHIS__@gmx.com")) (:maintainer "Elric Milon" . "whirm_REMOVETHIS__@gmx.com"))]) (flycheck-julia . [(20170729 2141) ((emacs (24)) (flycheck (0 22))) "Julia support for Flycheck" single ((:commit . "213b60a5a9a1cb7887260e1d159b5bb27167cbb6") (:keywords "convenience" "tools" "languages") (:authors ("Guido Kraemer" . "guido.kraemer@gmx.de")) (:maintainer "Guido Kraemer" . "guido.kraemer@gmx.de") (:url . "https://github.com/gdkrmr/flycheck-julia"))]) (flycheck-joker . [(20180713 402) ((flycheck (0 18))) "Add Clojure syntax checker (via Joker) to flycheck" single ((:commit . "0d8d5683a273093ca12841bf93d10dae97ccbc5d") (:authors ("Roman Bataev" . "roman.bataev@gmail.com")) (:maintainer "Roman Bataev" . "roman.bataev@gmail.com"))]) (flycheck-jest . [(20180411 328) ((emacs (25 1)) (flycheck (0 25))) "Flycheck extension for Jest." single ((:commit . "08f27c5ed97c83c445f99fab58f0b6c826f14449") (:keywords "languages" "jest") (:maintainer "James Nguyen" . "james@jojojames.com") (:url . "https://github.com/jojojames/flycheck-jest"))]) (flycheck-irony . [(20180604 2152) ((emacs (24 1)) (flycheck (0 22)) (irony (0 2 0))) "Flycheck: C/C++ support via Irony" single ((:commit . "42dbecd4a865cabeb301193bb4d660e26ae3befe") (:keywords "convenience" "tools" "c") (:authors ("Guillaume Papin" . "guillaume.papin@epitech.eu")) (:maintainer "Guillaume Papin" . "guillaume.papin@epitech.eu") (:url . "https://github.com/Sarcasm/flycheck-irony/"))]) (flycheck-inline . [(20180821 849) ((emacs (25 1)) (flycheck (31))) "Display Flycheck errors inline" single ((:commit . "6381d676462dab74f337e6fed9ada121fec25caf") (:keywords "tools" "convenience") (:authors ("fmdkdd")) (:maintainer "fmdkdd") (:url . "https://github.com/flycheck/flycheck-inline"))]) (flycheck-hdevtools . [(20160926 702) ((flycheck (0 21 -4 1)) (dash (2 0))) "A flycheck checker for Haskell using hdevtools" single ((:commit . "eab1fc184854341a56154623a131cab6ff0ce18c") (:keywords "convenience" "languages" "tools") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:url . "https://github.com/flycheck/flycheck-hdevtools"))]) (flycheck-haskell . [(20180611 2142) ((emacs (24 3)) (flycheck (0 25)) (haskell-mode (13 7)) (dash (2 4 0)) (seq (1 11)) (let-alist (1 0 1))) "Flycheck: Automatic Haskell configuration" tar ((:commit . "32877c2912d435c30c0202680611d127862a372c") (:keywords "tools" "convenience") (:authors ("Sebastian Wiesner" . "swiesner@lunaryorn.com")) (:maintainer "Sebastian Wiesner" . "swiesner@lunaryorn.com") (:url . "https://github.com/flycheck/flycheck-haskell"))]) (flycheck-grammalecte . [(20180723 904) ((emacs (24)) (flycheck (26))) "Integrate Grammalecte with Flycheck" tar ((:commit . "c47a6dc2c441827954cdb623ec19bf7e736d43ef") (:keywords "i18n" "text") (:authors ("Guilhem Doulcier" . "guilhem.doulcier@espci.fr") ("Étienne Deparis" . "etienne@depar.is")) (:maintainer "Guilhem Doulcier" . "guilhem.doulcier@espci.fr") (:url . "https://git.deparis.io/flycheck-grammalecte/"))]) (flycheck-gradle . [(20180403 733) ((emacs (25 1)) (flycheck (0 25))) "Flycheck extension for Gradle." single ((:commit . "a14b45183e50993e8b28a4c57ad5db82b789faef") (:keywords "languages" "gradle") (:maintainer "James Nguyen" . "james@jojojames.com") (:url . "https://github.com/jojojames/flycheck-gradle"))]) (flycheck-gometalinter . [(20180424 941) ((emacs (24)) (flycheck (0 22))) "flycheck checker for gometalinter" single ((:commit . "422f6e4b77b27fd7370f0c88437ac5072c9d3413") (:keywords "convenience" "tools" "go") (:authors ("Diep Pham" . "me@favadi.com")) (:maintainer "Diep Pham" . "me@favadi.com") (:url . "https://github.com/favadi/flycheck-gometalinter"))]) (flycheck-golangci-lint . [(20180711 817) ((emacs (24)) (flycheck (0 22))) "Flycheck checker for golangci-lint" single ((:commit . "b4b51aa6fe5335c0f46f2f83c7dc32e4141ff9f1") (:keywords "convenience" "tools" "go") (:authors ("Wei Jian Gan" . "weijiangan@outlook.com")) (:maintainer "Wei Jian Gan" . "weijiangan@outlook.com") (:url . "https://github.com/weijiangan/flycheck-golangci-lint"))]) (flycheck-ghcmod . [(20150114 632) ((flycheck (0 21 -4 1)) (dash (2 0))) "A flycheck checker for Haskell using ghcmod" single ((:commit . "6bb7b7d879f05bbae54e99eb04806c877adf3ccc") (:keywords "convenience" "languages" "tools") (:authors ("Shen Chao" . "scturtle@gmail.com")) (:maintainer "Shen Chao" . "scturtle@gmail.com") (:url . "https://github.com/scturtle/flycheck-ghcmod"))]) (flycheck-flow . [(20180801 1242) ((flycheck (0 18)) (json (1 4))) "Support Flow in flycheck" single ((:commit . "5d42270c798918c05c5e983e774063930bd87838") (:authors ("Lorenzo Bolla" . "lbolla@gmail.com")) (:maintainer "Lorenzo Bolla" . "lbolla@gmail.com"))]) (flycheck-flawfinder . [(20170116 327) ((flycheck (0 24)) (emacs (24 4))) "Integrate flawfinder with flycheck" single ((:commit . "7d964d38023b088adf3ffc2fddeead81f4491a45") (:authors ("Alex Murray" . "murray.alex@gmail.com")) (:maintainer "Alex Murray" . "murray.alex@gmail.com") (:url . "https://github.com/alexmurray/flycheck-flawfinder"))]) (flycheck-elsa . [(20180823 1426) ((emacs (25)) (seq (2 0)) (cask (0 8 4))) "Flycheck for Elsa." single ((:commit . "54a132205d7653a9c0b38fdc03736a0c49c193f6") (:keywords "convenience") (:authors ("Matúš Goljer" . "matus.goljer@gmail.com")) (:maintainer "Matúš Goljer" . "matus.goljer@gmail.com") (:url . "https://github.com/emacs-elsa/flycheck-elsa"))]) (flycheck-elm . [(20160717 957) ((flycheck (0 29 -4)) (emacs (24 4))) "Flycheck support for the elm language" single ((:commit . "b401873ebd2176190a0a6fb4d61c2cca97d3b9fb") (:authors ("Brian Sermons")) (:maintainer "Brian Sermons") (:url . "https://github.com/bsermons/flycheck-elm"))]) (flycheck-elixir . [(20180810 642) ((flycheck (0 25))) "Support Elixir in flycheck" single ((:commit . "11998d7e3e63a33453e934d25b3673f7c558e579") (:authors ("Lorenzo Bolla" . "lbolla@gmail.com")) (:maintainer "Lorenzo Bolla" . "lbolla@gmail.com"))]) (flycheck-dtrace . [(20180903 1630) ((emacs (25 1)) (flycheck (0 22))) "Flycheck: DTrace support" single ((:commit . "951fab3a15c11d92b9fac1ea4791a80dfe034a00") (:keywords "languages" "convenience" "tools") (:authors ("Jürgen Hötzel" . "juergen@hoetzel.info")) (:maintainer "Jürgen Hötzel" . "juergen@hoetzel.info"))]) (flycheck-dogma . [(20170125 721) ((flycheck (29))) "flycheck checker for elixir dogma" single ((:commit . "eea1844a81e87e2488b05e703a93272d0fc3bc74") (:authors ("Aaron Jensen" . "aaronjensen@gmail.com")) (:maintainer "Aaron Jensen" . "aaronjensen@gmail.com") (:url . "https://github.com/aaronjensen/flycheck-dogma"))]) (flycheck-dmd-dub . [(20180625 1635) ((flycheck (0 24)) (f (0 18 2))) "Sets flycheck-dmd-include-paths from dub package information" single ((:commit . "148ea4ba3e4c46c8edc616f947f796e98bcad0de") (:keywords "languages") (:authors ("Atila Neves" . "atila.neves@gmail.com")) (:maintainer "Atila Neves" . "atila.neves@gmail.com") (:url . "http://github.com/atilaneves/flycheck-dmd-dub"))]) (flycheck-dialyzer . [(20160326 1430) ((flycheck (0 18))) "Support dialyzer in flycheck" single ((:commit . "a5df0db95ac69f397b5f85d325a6d88cf8974f64") (:authors ("Lorenzo Bolla" . "lbolla@gmail.com")) (:maintainer "Lorenzo Bolla" . "lbolla@gmail.com"))]) (flycheck-dialyxir . [(20170515 1525) ((flycheck (29))) "flycheck checker for elixir dialyxir" single ((:commit . "adfb73374cb2bee75724822972f405f2ec371199") (:authors ("Aaron Jensen" . "aaronjensen@gmail.com")) (:maintainer "Aaron Jensen" . "aaronjensen@gmail.com") (:url . "https://github.com/aaronjensen/flycheck-dialyxir"))]) (flycheck-demjsonlint . [(20161115 718) ((flycheck (30))) "Flychecker for json-mode using jsonlint from demjson" tar ((:commit . "a3dfe1df8ecdea76c076c0849901427567356228") (:keywords "convenience" "tools") (:authors ("Zenkie Zhu" . "451218651@qq.com")) (:maintainer "Zenkie Zhu" . "451218651@qq.com") (:url . "https://github.com/z4139jq/flycheck-demjsonlint"))]) (flycheck-dedukti . [(20171103 1212) ((flycheck (0 19)) (dedukti-mode (0 1))) "Flycheck integration of Dedukti" single ((:commit . "3dbff5646355f39d57a3ec514f560a6b0082a1cd") (:keywords "convenience" "languages" "tools" "flycheck" "dedukti") (:authors ("Raphaël Cauderlier")) (:maintainer "Raphaël Cauderlier") (:url . "https://github.com/rafoo/flycheck-dedukti"))]) (flycheck-d-unittest . [(20160522 417) ((flycheck (0 21 -4 1)) (dash (1 4 0))) "Add D unittest support to flycheck" single ((:commit . "3e614f23cb4a5566fd7988dbcaaf254af81c7718") (:keywords "flycheck" "d") (:authors ("Tomoya Tanjo" . "ttanjo@gmail.com")) (:maintainer "Tomoya Tanjo" . "ttanjo@gmail.com") (:url . "https://github.com/tom-tan/flycheck-d-unittest/"))]) (flycheck-cython . [(20170724 958) ((flycheck (0 25))) "Support Cython in flycheck" single ((:commit . "ecc4454d35ab5317ab66a04406f36f0c1dbc0b76") (:authors ("Lorenzo Bolla" . "lbolla@gmail.com")) (:maintainer "Lorenzo Bolla" . "lbolla@gmail.com"))]) (flycheck-cstyle . [(20160905 2341) ((flycheck (0 24)) (emacs (24 4))) "Integrate cstyle with flycheck" single ((:commit . "207285140a353d08cf1fc450cacab158bc98ba82") (:authors ("Alex Murray" . "murray.alex@gmail.com")) (:maintainer "Alex Murray" . "murray.alex@gmail.com") (:url . "https://github.com/alexmurray/flycheck-cstyle"))]) (flycheck-css-colorguard . [(20161031 1122) ((flycheck (0 22)) (emacs (24))) "Detect similar colors in CSS" single ((:commit . "ae94fa0396acd99f9ec36d9572459df793f37fe8") (:keywords "flycheck" "css" "colorguard") (:authors ("Saša Jovanić" . "info@simplify.ba")) (:maintainer "Saša Jovanić" . "info@simplify.ba") (:url . "https://github.com/Simplify/flycheck-css-colorguard/"))]) (flycheck-crystal . [(20180627 242) ((flycheck (30))) "Add support for Crystal to Flycheck" single ((:commit . "8649736fea8960a5e54c3ec934484f231a518ea5") (:keywords "tools" "crystal") (:url . "https://github.com/crystal-lang-tools/emacs-crystal-mode"))]) (flycheck-credo . [(20170526 1545) ((flycheck (29))) "flycheck checker for elixir credo" single ((:commit . "e88f11ead53805c361ec7706e44c3dfee1daa19f") (:authors ("Aaron Jensen" . "aaronjensen@gmail.com")) (:maintainer "Aaron Jensen" . "aaronjensen@gmail.com") (:url . "https://github.com/aaronjensen/flycheck-credo"))]) (flycheck-coverity . [(20170704 59) ((flycheck (0 24)) (dash (2 12 0)) (emacs (24 4))) "Integrate Coverity with flycheck" single ((:commit . "cb211e3dd50413a5042eb20175be518214591c9d") (:authors ("Alex Murray" . "murray.alex@gmail.com")) (:maintainer "Alex Murray" . "murray.alex@gmail.com") (:url . "https://github.com/alexmurray/flycheck-coverity"))]) (flycheck-color-mode-line . [(20171122 707) ((flycheck (0 15)) (dash (1 2)) (emacs (24 1))) "Change mode line color with Flycheck status" single ((:commit . "cc474804d4e8088a627485faaf4217a5781aec7d") (:keywords "convenience" "language" "tools") (:authors ("Sylvain Benner" . "sylvain.benner@gmail.com")) (:maintainer "Sylvain Benner" . "sylvain.benner@gmail.com"))]) (flycheck-clojure . [(20180721 1412) ((cider (0 8 1)) (flycheck (0 22 -4 1)) (let-alist (1 0 1)) (emacs (24))) "Flycheck: Clojure support" single ((:commit . "d81d875f83f7db26cd7bf43d0f9bab272fb54a3c") (:authors ("Peter Fraenkel" . "pnf@podsnap.com") ("Sebastian Wiesner" . "swiesner@lunaryorn.com")) (:maintainer "Peter Fraenkel" . "pnf@podsnap.com") (:url . "https://github.com/clojure-emacs/squiggly-clojure"))]) (flycheck-clangcheck . [(20150712 710) ((cl-lib (0 5)) (seq (1 7)) (flycheck (0 17))) "A Flycheck checker difinition for ClangCheck." single ((:commit . "24a9424c484420073a24443a829fd5779752362b") (:authors ("kumar8600" . "kumar8600@gmail.com")) (:maintainer "kumar8600" . "kumar8600@gmail.com") (:url . "https://github.com/kumar8600/flycheck-clangcheck"))]) (flycheck-clang-tidy . [(20171024 808) ((flycheck (0 30))) "Flycheck syntax checker using clang-tidy" single ((:commit . "b8ebd49693f67e08e420ba847cc88f6721ef9e3e") (:keywords "convenience" "languages" "tools") (:authors (nil . "Sebastian Nagel<sebastian.nagel@ncoding.at>")) (:maintainer nil . "Sebastian Nagel<sebastian.nagel@ncoding.at>") (:url . "https://github.com/ch1bo/flycheck-clang-tidy"))]) (flycheck-clang-analyzer . [(20180904 304) ((flycheck (0 24)) (emacs (24 4))) "Integrate Clang Analyzer with flycheck" single ((:commit . "6568e082057c028c721ceda69bddd745fee5c5d5") (:authors ("Alex Murray" . "murray.alex@gmail.com")) (:maintainer "Alex Murray" . "murray.alex@gmail.com") (:url . "https://github.com/alexmurray/flycheck-clang-analyzer"))]) (flycheck-checkpatch . [(20170217 1025) ((emacs (25)) (flycheck (30))) "Flycheck support for checkpatch.pl tool" single ((:commit . "6461fc7b0d493eb9863814055f8bce5fa35739de") (:authors ("Alexander Yarygin" . "yarygin.alexander@gmail.com")) (:maintainer "Alexander Yarygin" . "yarygin.alexander@gmail.com") (:url . "https://github.com/zpp0/flycheck-checkpatch"))]) (flycheck-checkbashisms . [(20160224 1706) ((emacs (24)) (flycheck (0 25))) "checkbashisms checker for flycheck" single ((:commit . "0794ad763d7cd81286283f6400bc89a81e8e07d4") (:keywords "convenience" "tools" "sh" "unix") (:authors ("Cuong Le" . "cuong.manhle.vn@gmail.com")) (:maintainer "Cuong Le" . "cuong.manhle.vn@gmail.com") (:url . "https://github.com/Gnouc/flycheck-checkbashisms"))]) (flycheck-cask . [(20160928 926) ((emacs (24 1)) (flycheck (0 14)) (dash (2 4 0))) "Cask support in Flycheck" single ((:commit . "c3a51147eddeb7347de81f6a498fc96538bac499") (:keywords "tools" "convenience") (:authors ("Sebastian Wiesner" . "swiesner@lunaryorn.com")) (:maintainer "Sebastian Wiesner" . "swiesner@lunaryorn.com") (:url . "https://github.com/flycheck/flycheck-cask"))]) (flycheck-bashate . [(20160630 440) ((flycheck (0 24)) (emacs (24 4))) "Integrate bashate with flycheck" single ((:commit . "77fa03dbc578c34fe71ca44926bac2aff8f2b021") (:authors ("Alex Murray" . "murray.alex@gmail.com")) (:maintainer "Alex Murray" . "murray.alex@gmail.com") (:url . "https://github.com/alexmurray/flycheck-bashate"))]) (flycheck-ats2 . [(20170225 1636) ((emacs (24 1)) (flycheck (0 22))) "Flycheck: ATS2 support" single ((:commit . "9f77add8408462af35bdddf87e37a661880255e3") (:keywords "convenience" "tools" "languages") (:authors ("Mark Laws" . "mdl@60hz.org")) (:maintainer "Mark Laws" . "mdl@60hz.org") (:url . "http://github.com/drvink/flycheck-ats2"))]) (flycheck-apertium . [(20160406 1318) ((flycheck (0 25))) "Apertium checkers in flycheck" tar ((:commit . "71cf49d5aaee962b995583384bfa045a1d4c3db7") (:keywords "convenience" "tools" "xml") (:authors ("Kevin Brubeck Unhammer" . "unhammer+apertium@mm.st")) (:maintainer "Kevin Brubeck Unhammer" . "unhammer+apertium@mm.st") (:url . "http://wiki.apertium.org/wiki/Emacs"))]) (flycheck . [(20180823 826) ((dash (2 12 1)) (pkg-info (0 4)) (let-alist (1 0 4)) (seq (1 11)) (emacs (24 3))) "On-the-fly syntax checking" tar ((:commit . "ef2dcc1229e13c170b612dd0fc7fccb129e5ada1") (:keywords "convenience" "languages" "tools") (:authors ("Sebastian Wiesner" . "swiesner@lunaryorn.com")) (:maintainer "Clément Pit-Claudel" . "clement.pitclaudel@live.com") (:url . "http://www.flycheck.org"))]) (flx-isearch . [(20180103 514) ((emacs (24)) (flx (20140821)) (cl-lib (0 5))) "Fuzzy incremental searching for emacs" single ((:commit . "f132fd6367e369885ab3a865fbfe20eee989bc0b") (:keywords "convenience" "search" "flx") (:authors ("PythonNut" . "pythonnut@pythonnut.com")) (:maintainer "PythonNut" . "pythonnut@pythonnut.com") (:url . "https://github.com/pythonnut/flx-isearch"))]) (flx-ido . [(20180117 1519) ((flx (0 1)) (cl-lib (0 3))) "flx integration for ido" single ((:commit . "46040d0b096a0340d91235561f27a959a61d0fef") (:authors ("Le Wang")) (:maintainer "Le Wang") (:url . "https://github.com/lewang/flx"))]) (flx . [(20151030 1812) ((cl-lib (0 3))) "fuzzy matching with good sorting" single ((:commit . "46040d0b096a0340d91235561f27a959a61d0fef") (:authors ("Le Wang")) (:maintainer "Le Wang") (:url . "https://github.com/lewang/flx"))]) (fluxus-mode . [(20170210 1941) ((osc (0 1)) (emacs (24 4))) "Major mode for interfacing with Fluxus" single ((:commit . "3661d4dfdaf249138e7f215f15f291c9391ede8d") (:keywords "languages") (:authors ("modula t." . "defaultxr@gmail.com")) (:maintainer "modula t." . "defaultxr@gmail.com") (:url . "https://github.com/defaultxr/fluxus-mode"))]) (flower . [(20180821 1602) ((emacs (24 4)) (clomacs (0 0 3))) "Emacs task tracker client." tar ((:commit . "a0e6912e6e709e5cf083d48cebffdb60b809c59a") (:keywords "hypermedia" "outlines" "tools" "vc") (:authors ("Sergey Sobko" . "SSobko@ptsecurity.com")) (:maintainer "Sergey Sobko" . "SSobko@ptsecurity.com") (:url . "https://github.com/PositiveTechnologies/flower"))]) (flow-minor-mode . [(20180315 1824) ((emacs (25 1))) "Flow type mode based on web-mode." single ((:commit . "d1b32a7dd0d33c6a00a106da5f4b2323602cbd3e") (:url . "https://github.com/an-sh/flow-minor-mode"))]) (floobits . [(20180801 524) ((json (1 2)) (highlight (0))) "Floobits plugin for real-time collaborative editing" tar ((:commit . "489b294a7f30ecd2af2edc0823dead8102f27af6") (:keywords "comm" "tools") (:authors ("Matt Kaniaris") ("Geoff Greer")) (:maintainer "Matt Kaniaris") (:url . "http://github.com/Floobits/floobits-emacs"))]) (fliptext . [(20171124 2056) nil "Input method for flipping characters upside down" single ((:commit . "fd821f645ffebae6ae3894afa7ba7fc06f91afc6") (:keywords "games" "i18n") (:authors ("André Riemann" . "andre.riemann@web.de")) (:maintainer "André Riemann" . "andre.riemann@web.de"))]) (flimenu . [(20170418 147) ((dash (2 10 0)) (emacs (24 4))) "Flatten imenu automatically" single ((:commit . "9351201d89b05cbdaec312a6ebd7fd10c38d6112") (:keywords "imenu" "browse" "structure" "hook" "mode" "matching" "tools" "convenience" "files") (:authors ("Ivan Malison" . "IvanMalison@gmail.com")) (:maintainer "Ivan Malison" . "IvanMalison@gmail.com") (:url . "https://github.com/IvanMalison/flimenu"))]) (flim . [(20180328 2324) ((apel (10 8))) "A library to provide basic features about message representation or encoding." tar ((:commit . "faaa2b1f2bb8fcf835ddfb8981654e4d3b2bdbc6"))]) (flex-isearch . [(20170308 2010) nil "Flex matching (like ido) in isearch." single ((:keywords "convenience" "search") (:authors ("Jonathan Kotta" . "jpkotta@gmail.com")) (:maintainer "Jonathan Kotta" . "jpkotta@gmail.com") (:url . "https://bitbucket.org/jpkotta/flex-isearch"))]) (flex-compile . [(20180812 1856) ((emacs (25)) (buffer-manage (0 7)) (dash (2 13 0))) "Run, evaluate and compile for a many languages and modes." tar ((:commit . "4ca1a706aa1bc684a143d3430f009147df9c8e82") (:keywords "compilation" "integration") (:authors ("Paul Landes")) (:maintainer "Paul Landes") (:url . "https://github.com/plandes/flex-compile"))]) (flex-autopair . [(20120809 1218) nil "Automatically insert pair braces and quotes, insertion conditions & actions are highly customizable." single ((:commit . "4bb757f2556a4a51828e2fed8fb81e31e83052cb") (:keywords "keyboard" "input") (:authors ("Yuuki Arisawa" . "yuuki.ari@gmail.com")) (:maintainer "Yuuki Arisawa" . "yuuki.ari@gmail.com") (:url . "https://github.com/uk-ar/flex-autopair.el"))]) (flatui-theme . [(20160619 127) nil "A color theme for Emacs based on flatuicolors.com" single ((:commit . "9c15db5526c15c8dba55023f5698372b19c2a780") (:authors ("John Louis Del Rosario" . "john2x@gmail.com")) (:maintainer "John Louis Del Rosario" . "john2x@gmail.com") (:url . "https://github.com/john2x/flatui-theme.el"))]) (flatui-dark-theme . [(20170513 1422) ((emacs (24))) "Dark color theme with colors from https://flatuicolors.com/" single ((:commit . "5b959a9f743f891e4660b1b432086417947872ea") (:keywords "color" "theme" "dark" "flatui" "faces") (:authors ("Andrew Phillips" . "theasp@gmail.com")) (:maintainer "Andrew Phillips" . "theasp@gmail.com") (:url . "https://github.com/theasp/flatui-dark-theme"))]) (flatland-theme . [(20171113 1521) nil "A simple theme for Emacs based on the Flatland theme for Sublime Text" single ((:commit . "a98a6f19ad4dff0fa3fad1ea487b7d0ef634a19a") (:authors ("Greg Chapple" . "info@gregchapple.com")) (:maintainer "Greg Chapple" . "info@gregchapple.com") (:url . "http://github.com/gregchapple/flatland-emacs"))]) (flatland-black-theme . [(20170808 1312) ((emacs (24 0))) "an Emacs 24 theme based on Flatland Black (tmTheme)" single ((:commit . "348c5d5fe615e6ea13cadc17f046e506e789ce07") (:authors ("Jason Milkins")) (:maintainer "Jason Milkins") (:url . "https://github.com/emacsfodder/flatland-black-theme"))]) (flash-region . [(20130923 1817) nil "Flash a region" single ((:commit . "261b3597b23cdd40e5c14262a5687bcc6c1d0901") (:keywords "utility") (:authors ("Matus Goljer" . "matus.goljer@gmail.com")) (:maintainer "Matus Goljer" . "matus.goljer@gmail.com"))]) (flappymacs . [(20171023 1004) nil "flappybird clone for emacs" single ((:commit . "27f3e21acb22f786606481e3f4e5dc1edbaaaed4") (:keywords "games") (:authors ("Takayuki Sato")) (:maintainer "Takayuki Sato") (:url . "https://github.com/taksatou/flappymacs"))]) (flame . [(20180303 2016) ((emacs (24))) "automatic generation of flamage, as if we needed more." single ((:commit . "a749b2a77b87e505572d0f1f5d59fac76348bb73") (:keywords "games") (:authors ("Ian G. Batten" . "batten@uk.ac.bham.multics") ("Noah Friedman" . "friedman@splode.com")) (:maintainer "Noah Friedman" . "friedman@splode.com") (:url . "https://github.com/mschuldt/flame"))]) (fixmee . [(20150223 1355) ((button-lock (1 0 2)) (nav-flash (1 0 0)) (back-button (0 6 0)) (smartrep (0 0 3)) (string-utils (0 3 2)) (tabulated-list (0))) "Quickly navigate to FIXME notices in code" single ((:commit . "1b8b3460f1e3c3c1784b2a63fb9f4fb3bb4dc084") (:keywords "navigation" "convenience") (:authors ("Roland Walker" . "walker@pobox.com")) (:maintainer "Roland Walker" . "walker@pobox.com") (:url . "http://github.com/rolandwalker/fixmee"))]) (fix-word . [(20180101 615) ((emacs (24 1)) (cl-lib (0 5))) "Convenient word transformation" single ((:commit . "8e66b6a7b599c6c5098490e83ef4e69acf307603") (:keywords "word" "convenience") (:authors ("Mark Karpov" . "markkarpov92@gmail.com")) (:maintainer "Mark Karpov" . "markkarpov92@gmail.com") (:url . "https://github.com/mrkkrp/fix-word"))]) (fix-muscle-memory . [(20160823 439) nil "Simple hacks to fix muscle memory problems" single ((:commit . "a123e04f8a1d2982cbf930efb909cad9522ac884") (:keywords "spelling" "typing") (:authors ("Jonathan Arkell" . "jonnay@jonnay.net")) (:maintainer "Jonathan Arkell" . "jonnay@jonnay.net"))]) (fix-input . [(20180101 620) ((emacs (24 4))) "Make input methods play nicely with alternative keyboard layout on OS level" single ((:commit . "37bc0734a2e71d66245ee3960879577e5ef906bb") (:keywords "input" "method") (:authors ("Mark Karpov" . "markkarpov92@gmail.com")) (:maintainer "Mark Karpov" . "markkarpov92@gmail.com") (:url . "https://github.com/mrkkrp/fix-input"))]) (fish-mode . [(20180827 303) ((emacs (24))) "Major mode for fish shell scripts" single ((:commit . "35fc7c1e243a7410823088a571ecf378e9f3efa6") (:keywords "fish" "shell") (:authors ("Tony Wang" . "wwwjfy@gmail.com")) (:maintainer "Tony Wang" . "wwwjfy@gmail.com"))]) (fish-completion . [(20180827 829) nil "Add fish completion to pcomplete (shell and Eshell)" single ((:commit . "a73526d67c4c5f7f2e425cec79d56c7517c7f1e9") (:authors ("Pierre Neidhardt" . "mail@ambrevar.xyz")) (:maintainer "Pierre Neidhardt" . "mail@ambrevar.xyz") (:url . "https://gitlab.com/Ambrevar/emacs-fish-completion"))]) (firrtl-mode . [(20180221 2355) ((emacs (24 3))) "mode for working with FIRRTL files" single ((:commit . "1ac00d526018945389bcb2292dbdd8395381774a") (:keywords "languages" "firrtl") (:authors ("Schuyler Eldridge" . "schuyler.eldridge@ibm.com")) (:maintainer "Schuyler Eldridge" . "schuyler.eldridge@ibm.com") (:url . "https://github.com/ibm/firrtl-mode"))]) (firestarter . [(20161219 1323) nil "Execute (shell) commands on save" single ((:commit . "4d6b106f325ac1802eabce3c8a7cd0a4c7a32864") (:keywords "convenience") (:authors ("Vasilij Schneidermann" . "v.schneidermann@gmail.com")) (:maintainer "Vasilij Schneidermann" . "v.schneidermann@gmail.com") (:url . "https://github.com/wasamasa/firestarter"))]) (fireplace . [(20160811 1219) nil "A cozy fireplace for emacs" single ((:commit . "23a444f749bcb2b804593e3b2cb9c73cc59231fb") (:keywords "games") (:authors ("Johan Sivertsen" . "johanvts@gmail.com")) (:maintainer "Johan Sivertsen" . "johanvts@gmail.com") (:url . "https://github.com/johanvts/emacs-fireplace"))]) (firefox-controller . [(20160320 1847) ((moz (0)) (popwin (1 0 0)) (cl-lib (0 5))) "An improved Firefox controller" single ((:commit . "a8af8cbf70afaf6b89a26d6ac69af8e92afc181f") (:keywords "extensions") (:authors ("Junpeng Qiu" . "qjpchmail@gmail.com")) (:maintainer "Junpeng Qiu" . "qjpchmail@gmail.com") (:url . "https://github.com/cute-jumper/emacs-firefox-controller"))]) (firecode-theme . [(20170808 1311) ((emacs (24 0))) "an Emacs 24 theme based on FireCode (tmTheme)" single ((:commit . "8b7b03ecdd41e70dab145b98906017e1392eaef4") (:authors ("Jason Milkins")) (:maintainer "Jason Milkins") (:url . "https://github.com/emacsfodder/tmtheme-to-deftheme"))]) (fiplr . [(20140724 645) ((grizzl (0 1 0)) (cl-lib (0 1))) "Fuzzy Search for Files in Projects" tar ((:commit . "3f50159fd42125440d5b0eb9d6398560461f030b"))]) (fingers . [(20160817 829) nil "Modal editing with universal text manipulation helpers." tar ((:commit . "fed0f742afb1d72eaef29d8da394467550a030fa") (:keywords "fingers" "modal" "editing" "workman") (:authors ("Felix Geller" . "fgeller@gmail.com")) (:maintainer "Felix Geller" . "fgeller@gmail.com") (:url . "http://github.com/fgeller/fingers.el"))]) (findr . [(20130127 2032) nil "Breadth-first file-finding facility for (X)Emacs" single ((:commit . "1ddbc0464bb05dcda392b62666ad17239a2152d3") (:keywords "files") (:authors ("David Bakhash" . "cadet@bu.edu")) (:maintainer "David Bakhash" . "cadet@bu.edu"))]) (find-things-fast . [(20150519 2226) nil "Find things fast, leveraging the power of git" single ((:commit . "efc7c189019ed65430e2f9e910e8e0a5ca9d2d03") (:keywords "project" "convenience") (:authors ("Elvio Toccalino and Elliot Glaysher and Phil Hagelberg and Doug Alcorn")) (:maintainer "Elvio Toccalino and Elliot Glaysher and Phil Hagelberg and Doug Alcorn"))]) (find-temp-file . [(20170107 1339) nil "Open quickly a temporary file" single ((:commit . "513005d19d72d71f34481ee00158dd57bd93206f") (:keywords "convenience") (:authors ("Sylvain Rousseau <thisirs at gmail dot com>")) (:maintainer "Sylvain Rousseau <thisirs at gmail dot com>") (:url . "https://github.com/thisirs/find-temp-file.git"))]) (find-file-in-repository . [(20151113 1319) nil "Quickly find files in a git, mercurial or other repository" single ((:commit . "8a8c84a6dbe7a2bba4564c3b58c92d157abfa3f8") (:keywords "files" "convenience" "repository" "project" "source control") (:authors ("Samuel Hoffstaetter" . "samuel@hoffstaetter.com")) (:maintainer "Samuel Hoffstaetter" . "samuel@hoffstaetter.com") (:url . "https://github.com/hoffstaetter/find-file-in-repository"))]) (find-file-in-project . [(20180706 132) ((ivy (0 10 0)) (emacs (24 3))) "Find file/directory and review Diff/Patch/Commit efficiently everywhere" single ((:commit . "1c54325cb60bde7496dad4e19f4c2a857999df58") (:keywords "project" "convenience") (:authors ("Phil Hagelberg, Doug Alcorn, and Will Farrington")) (:maintainer "Chen Bin" . "chenbin.sh@gmail.com") (:url . "https://github.com/technomancy/find-file-in-project"))]) (find-by-pinyin-dired . [(20180210 218) ((pinyinlib (0 1 0))) "Find file by first PinYin character of Chinese Hanzi" single ((:commit . "3b4781148dddc84a701ad76c0934ed991ecd59d5") (:keywords "hanzi" "chinese" "dired" "find" "file" "pinyin") (:authors ("Chen Bin" . "chenbin.sh@gmail.com")) (:maintainer "Chen Bin" . "chenbin.sh@gmail.com") (:url . "http://github.com/redguardtoo/find-by-pinyin-dired"))]) (finalize . [(20170418 1945) ((emacs (24 1)) (cl-generic (0 3)) (cl-lib (0 3)) (eieio (1 4))) "finalizers for Emacs Lisp" tar ((:commit . "846731531e7d1d80451787992e07bfe7dedbe9ff"))]) (fillcode . [(20171029 1625) nil "Fill (wrap) function calls and expressions in source code" single ((:commit . "d0a9e20f5fcc24a786d09ea19bfb9237681ba823") (:authors ("Ryan Barrett" . "fillcode@ryanb.org")) (:maintainer "Ryan Barrett" . "fillcode@ryanb.org") (:url . "https://snarfed.org/fillcode"))]) (fill-function-arguments . [(20180427 1702) ((emacs (24 4))) "Convert function arguments to/from single line" single ((:commit . "fcfb2a671adaf04110586aee0c499b1f0056a8e6") (:keywords "convenience") (:authors ("David Shepherd" . "davidshepherd7@gmail.com")) (:maintainer "David Shepherd" . "davidshepherd7@gmail.com") (:url . "https://github.com/davidshepherd7/fill-function-arguments"))]) (fill-column-indicator . [(20171209 1924) nil "Graphically indicate the fill column" single ((:commit . "d2536b1c48f78679e15a2b50cd5d8c0ffde4b155") (:keywords "convenience") (:authors ("Alp Aker" . "alp.tekin.aker@gmail.com")) (:maintainer "Alp Aker" . "alp.tekin.aker@gmail.com"))]) (filelock . [(20180524 2215) ((emacs (24)) (cl-lib (0)) (f (0))) "Functions for manipulating file locks" single ((:commit . "17a5ca6e0dee14d2e7d92c84be91143bca9d9663") (:keywords "extensions" "files" "tools") (:authors ("Ryan C. Thompson")) (:maintainer "Ryan C. Thompson") (:url . "https://github.com/DarwinAwardWinner/emacs-filelock"))]) (figlet . [(20160218 2237) nil "Annoy people with big, ascii art text" single ((:authors ("Philip Jackson" . "phil@shellarchive.co.uk")) (:maintainer "Philip Jackson" . "phil@shellarchive.co.uk"))]) (fifo-class . [(20160425 558) nil "First in first out abstract class" single ((:commit . "8fe4cf690727f4ac7b67f29c55f845df023c3f21") (:keywords "lisp") (:authors ("Mola-T" . "Mola@molamola.xyz")) (:maintainer "Mola-T" . "Mola@molamola.xyz") (:url . "https://github.com/mola-T/fifo-class"))]) (fic-mode . [(20180603 2035) nil "Show FIXME/TODO/BUG(...) in special face only in comments and strings" single ((:commit . "a05fc36ed54ba0c6dc22ac216a6a72cf191ca13d") (:url . "https://github.com/lewang/fic-mode"))]) (fetch . [(20131201 730) nil "Fetch and unpack resources" single ((:commit . "3f2793afcbbc32f320e572453166f9354ecc6d06") (:authors ("Christian 'crshd' Brassat" . "christian.brassat@gmail.com")) (:maintainer "Christian 'crshd' Brassat" . "christian.brassat@gmail.com") (:url . "https://github.com/crshd/fetch.el"))]) (fennel-mode . [(20180801 350) nil "a major-mode for editing Fennel code" single ((:commit . "b1f07dff0b16a0bc912528e3c1a70231488a1399") (:keywords "languages" "tools") (:authors ("Phil Hagelberg")) (:maintainer "Phil Hagelberg") (:url . "https://gitlab.com/technomancy/fennel-mode"))]) (feebleline . [(20180802 1227) nil "Replace modeline with a slimmer proxy" single ((:commit . "dfcfd849dd206a138d7901700df73e91e59969e9") (:authors ("Benjamin Lindqvist" . "benjamin.lindqvist@gmail.com")) (:maintainer "Benjamin Lindqvist" . "benjamin.lindqvist@gmail.com") (:url . "https://github.com/tautologyclub/feebleline"))]) (feature-mode . [(20170907 1448) nil "Major mode for editing Gherkin (i.e. Cucumber) user stories" tar ((:commit . "722b352c4f0b800a9356dd369c79612782b3b847"))]) (fd-dired . [(20180731 1049) ((emacs (25))) "find-dired alternative using fd" single ((:commit . "fd4c3f490b0b6727592b85f1635e57638dec8f91") (:keywords "tools" "fd" "find" "dired") (:authors ("Rashawn Zhang" . "namy.19@gmail.com")) (:maintainer "Rashawn Zhang" . "namy.19@gmail.com") (:url . "https://github.com/yqrashawn/fd-dired"))]) (fcopy . [(20150304 1403) nil "Funny Copy, set past point HERE then search copy text" single ((:commit . "e355f6ec889d8ecbdb096019c2dc660b1cec4941") (:keywords "convenience") (:authors ("Masayuki Ataka" . "masayuki.ataka@gmail.com")) (:maintainer "Masayuki Ataka" . "masayuki.ataka@gmail.com") (:url . "https://github.com/ataka/fcopy"))]) (fcitx . [(20170914 200) nil "Make fcitx better in Emacs" single ((:commit . "095332fbeb994c908c533fe2ad068c0728211c3d") (:keywords "extensions") (:authors ("Junpeng Qiu" . "qjpchmail@gmail.com")) (:maintainer "Junpeng Qiu" . "qjpchmail@gmail.com") (:url . "https://github.com/cute-jumper/fcitx.el"))]) (faustine . [(20171122 1202) ((emacs (24 3)) (faust-mode (0 3))) "Edit, visualize, build and run Faust code" single ((:commit . "07a38963111518f86123802f9d477be0d4689a3f") (:keywords "languages" "faust") (:authors ("Yassin Philip" . "xaccrocheur@gmail.com")) (:maintainer "Yassin Philip" . "xaccrocheur@gmail.com") (:url . "https://bitbucket.org/yphil/faustine"))]) (faust-mode . [(20180205 926) nil "Faust syntax colorizer for Emacs." single ((:commit . "7c31b22bdbfd2f8c16ec117d2975d56dd61ac15c") (:keywords "languages" "faust") (:authors ("rukano" . "rukano@gmail.com")) (:maintainer "Yassin Philip" . "xaccrocheur@gmail.com") (:url . "https://github.com/rukano/emacs-faust-mode"))]) (fastnav . [(20120211 1457) nil "Fast navigation and editing routines." single ((:commit . "1019ba2b61d1a070204099b23da347278a61bc89") (:keywords "nav" "fast" "fastnav" "navigation") (:authors ("Zsolt Terek" . "zsolt@google.com")) (:maintainer "Zsolt Terek" . "zsolt@google.com"))]) (fastdef . [(20160713 1329) ((ivy (0 7 0)) (w3m (0 0))) "Insert terminology from Google top search results" single ((:commit . "0696f41dc150d35ce31fe8d2ea74f4173818bb55") (:keywords "terminology" "org-mode" "markdown") (:authors ("Chen Bin <chenin DOT sh AT gmail DOT com>")) (:maintainer "Chen Bin <chenin DOT sh AT gmail DOT com>") (:url . "http://github.com/redguardtoo/fastdef"))]) (fasd . [(20180606 505) nil "Emacs integration for the command-line productivity booster `fasd'" single ((:commit . "020c6a4b5fd1498a84ae142d2e32c7ff678fb029") (:keywords "cli" "bash" "zsh" "autojump") (:authors ("steckerhalter")) (:maintainer "steckerhalter") (:url . "https://framagit.org/steckerhalter/emacs-fasd"))]) (farmhouse-theme . [(20160713 2244) nil "Farmhouse Theme, Emacs edition" tar ((:commit . "7ddc1ff13b4a3d5466bd0d33ecb86100352e83a7") (:keywords "color" "theme") (:url . "https://github.com/mattly/emacs-farmhouse-theme"))]) (fancy-narrow . [(20171031 16) nil "narrow-to-region with more eye candy." single ((:commit . "9f4a587f6a5a387271fb665e13f59d41fd42504c") (:keywords "faces" "convenience") (:authors ("Artur Malabarba" . "bruce.connor.am@gmail.com")) (:maintainer "Artur Malabarba" . "bruce.connor.am@gmail.com") (:url . "http://github.com/Bruce-Connor/fancy-narrow"))]) (fancy-battery . [(20150101 1204) ((emacs (24 1))) "Fancy battery display" single ((:commit . "9b88ae77a01aa3edc529840338bcb2db7f445822") (:keywords "convenience" "tools" "hardware") (:authors ("Sebastian Wiesner" . "swiesner@lunaryorn.com")) (:maintainer "Sebastian Wiesner" . "swiesner@lunaryorn.com") (:url . "https://github.com/lunaryorn/fancy-battery.el"))]) (fakir . [(20140729 1652) ((noflet (0 0 8)) (dash (1 3 2)) (kv (0 0 19))) "fakeing bits of Emacs" single ((:commit . "1fca406ad7de80fece6319ff75d4230b648534b0") (:keywords "lisp" "tools") (:authors ("Nic Ferrier" . "nferrier@ferrier.me.uk")) (:maintainer "Nic Ferrier" . "nferrier@ferrier.me.uk") (:url . "http://github.com/nicferrier/emacs-fakir"))]) (fakespace . [(20120818 6) nil "fake namespaces with defpackage" single ((:commit . "d1bd1f4b14b2690d7a67f9a52622ec51ed84813a") (:authors ("Christopher Wellons" . "mosquitopsu@gmail.com")) (:maintainer "Christopher Wellons" . "mosquitopsu@gmail.com") (:url . "https://github.com/skeeto/elisp-fakespace"))]) (faff-theme . [(20180702 1723) nil "Light Emacs color theme on ivory3 background" single ((:commit . "596c8cfbf1a7fbc3b93643359f8d0f4c612d69be") (:keywords "color" "theme") (:authors ("James Ferguson <(concat \"wjcferguson\" at-sign \"gmail.com\")>")) (:maintainer "James Ferguson <(concat \"wjcferguson\" at-sign \"gmail.com\")>") (:url . "https://github.com/WJCFerguson/emacs-faff-theme"))]) (factlog . [(20130210 140) ((deferred (0 3 1))) "File activity logger" single ((:commit . "6503d77ea882c995b051d22e72db336fb28770fc") (:authors ("Takafumi Arakaki <aka.tkf at gmail.com>")) (:maintainer "Takafumi Arakaki <aka.tkf at gmail.com>") (:url . "https://github.com/tkf/factlog"))]) (faceup . [(20170925 1946) nil "Markup language for faces and font-lock regression testing" single ((:commit . "6c92dad56a133e14e7b27831e1bcf9b3a71ff154") (:keywords "faces" "languages") (:authors ("Anders Lindgren")) (:maintainer "Anders Lindgren") (:url . "https://github.com/Lindydancer/faceup"))]) (face-explorer . [(20170710 1901) nil "Library and tools for faces and text properties" single ((:commit . "13bd4553bc4b09215a04d0267be1cb4ed834775c") (:keywords "faces") (:authors ("Anders Lindgren")) (:maintainer "Anders Lindgren") (:url . "https://github.com/Lindydancer/face-explorer"))]) (fabric . [(20171116 656) nil "Launch Fabric using Emacs" tar ((:commit . "df79be341d0b34ed23850f9894136092fa5fea8c") (:keywords "python" "fabric") (:authors ("Nicolas Lamirault" . "nicolas.lamirault@chmouel.com")) (:maintainer "Nicolas Lamirault" . "nicolas.lamirault@chmouel.com") (:url . "https://github.com/nlamirault/fabric.el"))]) (f3 . [(20180130 1158) ((emacs (24 3)) (helm (2 8 8)) (cl-lib (0 5))) "a helm interface to find" tar ((:commit . "000009ce4adf7a57eae80512f29c4ec2a1391ce5") (:keywords "find" "file" "files" "helm" "fast" "finder") (:authors ("Danny McClanahan")) (:maintainer "Danny McClanahan") (:url . "https://github.com/cosmicexplorer/f3"))]) (f . [(20180106 922) ((s (1 7 0)) (dash (2 2 0))) "Modern API for working with files and directories" single ((:commit . "de6d4d40ddc844eee643e92d47b9d6a63fbebb48") (:keywords "files" "directories") (:authors ("Johan Andersson" . "johan.rejeep@gmail.com")) (:maintainer "Johan Andersson" . "johan.rejeep@gmail.com") (:url . "http://github.com/rejeep/f.el"))]) (eziam-theme . [(20180414 1029) nil "A mostly monochrome theme, inspired by Tao and Leuven, with dark and light versions." tar ((:commit . "96595833110cd64c391e0ccd5230782a8f0a4e08"))]) (ez-query-replace . [(20170814 1321) ((dash (1 2 0)) (s (1 11 0))) "a smarter context-sensitive query-replace that can be reapplied" single ((:commit . "f5dbd2d3e5e62e6b7e7cc1a98fc4d0cd411e5afa") (:authors ("Wilfred Hughes" . "me@wilfred.me.uk")) (:maintainer "Wilfred Hughes" . "me@wilfred.me.uk"))]) (eyuml . [(20141028 2227) ((request (0 2 0)) (s (1 8 0))) "Write textual uml diagram from emacs using yuml.me" single ((:commit . "eb29c37316e44a14741f16e894fbcfcb7537dc80") (:keywords "uml") (:authors ("Anthony HAMON" . "hamon.anth@gmail.com")) (:maintainer "Anthony HAMON" . "hamon.anth@gmail.com") (:url . "http://github.com/antham/eyuml"))]) (eyebrowse . [(20180514 1919) ((dash (2 7 0)) (emacs (24 3 1))) "Easy window config switching" single ((:commit . "dfeea9e9cd6dcd78ddc9fccdf9a21f7317f754bc") (:keywords "convenience") (:authors ("Vasilij Schneidermann" . "v.schneidermann@gmail.com")) (:maintainer "Vasilij Schneidermann" . "v.schneidermann@gmail.com") (:url . "https://github.com/wasamasa/eyebrowse"))]) (exwm-x . [(20180227 1057) ((cl-lib (0 5)) (exwm (0 17)) (switch-window (0 10)) (swiper (0 9 0)) (bind-key (1 0)) (counsel (0 9 0)) (ivy (0 9 0))) "A derivative wm based on EXWM (emacs x window manager)" tar ((:commit . "4f7946db67d6599baba6b3961e8f543a68707742") (:keywords "window-manager" "exwm") (:authors ("Feng Shu" . "tumashu@163.com")) (:maintainer "Feng Shu" . "tumashu@163.com") (:url . "https://github.com/tumashu/exwm-x"))]) (exwm-surf . [(20171204 1140) ((emacs (24 4)) (exwm (0 16))) "Interface for Surf (surf.suckless.org) under exwm" single ((:commit . "6c17e2c1597fe4b7b454a1dac23b9127ac951e94") (:keywords "extensions") (:authors ("Peter" . "craven@gmx.net")) (:maintainer "Peter" . "craven@gmx.net") (:url . "https://github.com/ecraven/exwm-surf"))]) (exwm-edit . [(20180812 2158) ((emacs (24 4))) "Edit mode for EXWM" single ((:commit . "617cba2eb9f5df6f98b0c8245e78b64467c27cbe") (:keywords "convenience") (:authors ("Ag Ibragimov")) (:maintainer "Ag Ibragimov") (:url . "https://github.com/agzam/exwm-edit"))]) (extmap . [(20180205 1847) ((emacs (24 1))) "Externally-stored constant mapping for Elisp" single ((:commit . "3860b69fb19c962425d4e271ee0a24547b67d323") (:keywords "lisp") (:authors ("Paul Pogonyshev" . "pogonyshev@gmail.com")) (:maintainer "Paul Pogonyshev" . "pogonyshev@gmail.com") (:url . "https://github.com/doublep/extmap"))]) (extend-dnd . [(20151122 1850) nil "R drag and Drop" tar ((:commit . "80c966c93b82c9bb5c6225a432557c39144fc602") (:keywords "extend" "drag and drop") (:authors ("Matthew L. Fidler")) (:maintainer "Matthew L. Fidler") (:url . "https://github.com/mlf176f2/extend-dnd"))]) (extempore-mode . [(20180105 621) ((emacs (24 4))) "Emacs major mode for Extempore source files" single ((:commit . "ae5f40d4b0883a4519e460cd7720e5fcc3a68fa5") (:keywords "extempore") (:authors ("Ben Swift" . "ben@benswift.me")) (:maintainer "Ben Swift" . "ben@benswift.me") (:url . "http://github.com/extemporelang/extempore-emacs-mode"))]) (exsqlaim-mode . [(20170607 1003) ((s (1 10 0))) "Use variables inside sql queries" single ((:commit . "a2e0a62ec8b87193d8eaa695774bfd689324b06c") (:authors ("Ahmad Nazir Raja" . "ahmadnazir@gmail.com")) (:maintainer "Ahmad Nazir Raja" . "ahmadnazir@gmail.com") (:url . "https://github.com/ahmadnazir/exsqlaim-mode"))]) (express . [(20140508 2041) ((string-utils (0 3 2))) "Alternatives to `message'" single ((:commit . "93dae7377eace4a5413ba99aecb6f26f90798725") (:keywords "extensions" "message" "interface") (:authors ("Roland Walker" . "walker@pobox.com")) (:maintainer "Roland Walker" . "walker@pobox.com") (:url . "http://github.com/rolandwalker/express"))]) (expand-region . [(20180817 1134) nil "Increase selected region by semantic units." tar ((:commit . "ed3292473035dc8f3d2f321e82974ef87327808f"))]) (expand-line . [(20151006 207) nil "Expand selection by line" single ((:commit . "75a5d0241f35dd0748ab8ecb4ff16891535be372") (:authors ("Kai Yu" . "yeannylam@gmail.com")) (:maintainer "Kai Yu" . "yeannylam@gmail.com"))]) (exotica-theme . [(20180212 2329) ((emacs (24))) "A dark theme with vibrant colors" single ((:commit . "ff3ef4f6fa38c93b99becad977c7810c990a4d2f") (:keywords "faces" "theme" "dark" "vibrant colors") (:authors ("Bharat Joshi" . "jbharat@outlook.com")) (:maintainer "Bharat Joshi" . "jbharat@outlook.com") (:url . "https://github.com/jbharat/exotica-theme"))]) (exiftool . [(20170822 2132) ((emacs (25))) "Elisp wrapper around ExifTool" single ((:commit . "3a07dbcb975577734d4abf6d68e1ab83a01951bb") (:keywords "data") (:authors ("Arun I" . "arunisaac@systemreboot.net")) (:maintainer "Arun I" . "arunisaac@systemreboot.net") (:url . "https://git.systemreboot.net/exiftool.el"))]) (exec-path-from-shell . [(20180324 204) nil "Get environment variables such as $PATH from the shell" single ((:commit . "d8aa7765a138a0cee1a18ac380019fb3b33d07e6") (:keywords "unix" "environment") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:url . "https://github.com/purcell/exec-path-from-shell"))]) (exato . [(20180305 1042) ((evil (1 2 13)) (emacs (24))) "EXATO: Evil XML/HTML Attributes Text Object" single ((:commit . "88266fa7fcfbef704032f671b94f756f2f98bd4f") (:authors ("Filipe Silva" . "filipe.silva@gmail.com")) (:maintainer "Filipe Silva" . "filipe.silva@gmail.com") (:url . "https://github.com/ninrod/exato"))]) (eww-lnum . [(20150102 1512) nil "Conkeror-like functionality for eww" single ((:commit . "4b0ecec769919ecb05ca4fb15ec51911ba589929") (:keywords "eww" "browse" "conkeror") (:authors ("Andrey Kotlarski" . "m00naticus@gmail.com")) (:maintainer "Andrey Kotlarski" . "m00naticus@gmail.com") (:url . "https://github.com/m00natic/eww-lnum"))]) (ewmctrl . [(20170922 217) nil "Use `wmctrl' to manage desktop windows via EWMH/NetWM." single ((:commit . "3d0217c4d6cdb5c308b6cb4293574f470d4faacf") (:keywords "desktop" "windows" "ewmh" "netwm") (:authors ("Alexis" . "flexibeast@gmail.com") ("Adam Plaice" . "plaice.adam@gmail.com")) (:maintainer "Alexis" . "flexibeast@gmail.com") (:url . "https://github.com/flexibeast/ewmctrl"))]) (evm . [(20141007 1156) ((dash (2 3 0)) (f (0 13 0))) "Emacs Version Manager" single ((:commit . "d0623b2355436a5fd9f7238b419782080c79196b") (:authors ("Johan Andersson" . "johan.rejeep@gmail.com")) (:maintainer "Johan Andersson" . "johan.rejeep@gmail.com") (:url . "http://github.com/rejeep/evm"))]) (evil-visualstar . [(20160223 48) ((evil (0))) "Starts a * or # search from the visual selection" single ((:commit . "06c053d8f7381f91c53311b1234872ca96ced752") (:keywords "evil" "vim" "visualstar") (:authors ("Bailey Ling")) (:maintainer "Bailey Ling") (:url . "https://github.com/bling/evil-visualstar"))]) (evil-visual-replace . [(20171016 613) ((evil (1 0 0))) "search/replace commands for evil visual state, inc. blocks" single ((:commit . "163fc827a1ffc106475da470c37fb26f4cc9b008") (:keywords "evil" "search" "replace" "regexp" "block" "rectangular" "region" "visual") (:authors ("Troy Pracy")) (:maintainer "Troy Pracy") (:url . "https://github.com/troyp/evil-visual-replace"))]) (evil-visual-mark-mode . [(20150202 1800) ((evil (1 0 9)) (dash (2 10))) "Display evil marks on buffer" single ((:commit . "094ee37599492885ff3144918fcdd9b74dadaaa0") (:keywords "evil") (:authors ("Roman Gonzalez" . "romanandreg@gmail.com")) (:maintainer "Roman Gonzalez" . "romanandreg@gmail.com"))]) (evil-vimish-fold . [(20171030 1151) ((emacs (24 4)) (evil (1 0 0)) (vimish-fold (0 2 0))) "Integrate vimish-fold with evil" single ((:commit . "c617fecb91303f8c63f85a6101a503fdc88aae84") (:authors ("Alex Murray" . "murray.alex@gmail.com")) (:maintainer "Alex Murray" . "murray.alex@gmail.com") (:url . "https://github.com/alexmurray/evil-vimish-fold"))]) (evil-tutor-ja . [(20160917 132) ((evil (1 0 9)) (evil-tutor (0 1))) "Japanese Vimtutor adapted to Evil and wrapped in a major-mode" tar ((:commit . "99af7d82e02ce3bcdfaff47c5c80b57327a7ea8d") (:keywords "convenience" "editing" "evil" "japanese") (:authors ("Kenji Miyazaki" . "kenjizmyzk@gmail.com")) (:maintainer "Kenji Miyazaki" . "kenjizmyzk@gmail.com") (:url . "https://github.com/kenjimyzk/evil-tutor-ja"))]) (evil-tutor . [(20150103 650) ((evil (1 0 9))) "Vimtutor adapted to Evil and wrapped in a major-mode" tar ((:commit . "4e124cd3911dc0d1b6817ad2c9e59b4753638f28") (:keywords "convenience" "editing" "evil") (:authors ("Sylvain Benner" . "sylvain.benner@gmail.com")) (:maintainer "Sylvain Benner" . "sylvain.benner@gmail.com") (:url . "https://github.com/syl20bnr/evil-tutor"))]) (evil-textobj-column . [(20170905 1905) ((names (0 5)) (emacs (24)) (evil (0))) "Provides column text objects." single ((:commit . "835d7036d0bc9a6e44fc9b7c54ccf2a7c01428cd") (:keywords "evil" "column" "text-object") (:authors ("Fox Kiester" . "noct@openmailbox.org")) (:maintainer "Fox Kiester" . "noct@openmailbox.org") (:url . "https://github.com/noctuid/evil-textobj-column"))]) (evil-textobj-anyblock . [(20170905 1907) ((cl-lib (0 5)) (evil (1 1 0))) "Textobject for the closest user-defined blocks." single ((:commit . "ff00980f0634f95bf2ad9956b615a155ea8743be") (:keywords "evil") (:authors ("Fox Kiester" . "noct@openmailbox.org")) (:maintainer "Fox Kiester" . "noct@openmailbox.org") (:url . "https://github.com/noctuid/evil-textobj-anyblock"))]) (evil-text-object-python . [(20160815 841) ((emacs (24)) (evil (1 2 12))) "Python specific evil text objects" single ((:commit . "3b3fb01e7ad7eeeeae1143695547fe75148cc44f") (:keywords "evil" "python" "text-object") (:authors ("Wouter Bolsterlee" . "wouter@bolsterl.ee")) (:maintainer "Wouter Bolsterlee" . "wouter@bolsterl.ee") (:url . "https://github.com/wbolster/evil-text-object-python"))]) (evil-test-helpers . [(20180109 1840) ((evil (1 2 13))) "unit test helpers for Evil" single ((:commit . "3d9f76f3add56f670042af9421b36dfb8574ad00") (:authors ("Vegard Øye <vegard_oye at hotmail.com>")) (:maintainer "Vegard Øye <vegard_oye at hotmail.com>"))]) (evil-terminal-cursor-changer . [(20170401 842) ((evil (1 0 8))) "Change cursor shape and color by evil state in terminal" single ((:commit . "b49ca4393d2f3cc6014174950059b36a5cb22949") (:keywords "evil" "terminal" "cursor") (:authors ("7696122")) (:maintainer "7696122") (:url . "https://github.com/7696122/evil-terminal-cursor-changer"))]) (evil-tabs . [(20160217 1520) ((evil (0 0 0)) (elscreen (0 0 0))) "Integrating Vim-style tabs for Evil mode users." single ((:commit . "53d3314a810017b6056ab6796aef671f5ea1c063") (:keywords "evil" "tab" "tabs" "vim") (:authors ("Kris Jenkins" . "krisajenkins@gmail.com")) (:maintainer "Kris Jenkins" . "krisajenkins@gmail.com") (:url . "https://github.com/krisajenkins/evil-tabs"))]) (evil-swap-keys . [(20170726 1820) ((emacs (24))) "intelligently swap keys on text input with evil" single ((:commit . "56bc201e265a6bd482a7c41a7c81d2238341ef3a") (:keywords "evil" "key" "swap" "numbers" "symbols") (:authors ("Wouter Bolsterlee" . "wouter@bolsterl.ee")) (:maintainer "Wouter Bolsterlee" . "wouter@bolsterl.ee") (:url . "https://github.com/wbolster/evil-swap-keys"))]) (evil-surround . [(20180102 1401) ((evil (1 2 12))) "emulate surround.vim from Vim" single ((:commit . "2af81ab3ac64e4b0515a157a672d8cb89f0172b9") (:keywords "emulation" "vi" "evil") (:authors ("Tim Harper <timcharper at gmail dot com>") ("Vegard Øye <vegard_oye at hotmail dot com>")) (:maintainer "Tim Harper <timcharper at gmail dot com>"))]) (evil-string-inflection . [(20180313 1755) ((emacs (24)) (evil (1 2 13)) (string-inflection (1 0 6))) "snake_case -> CamelCase -> etc. for text objects" single ((:commit . "008b74a9b2994abfb4ff5b679b8a5a26fd45e98a") (:authors ("Filipe Silva" . "filipe.silva@gmail.com")) (:maintainer "Filipe Silva" . "filipe.silva@gmail.com") (:url . "https://github.com/ninrod/evil-string-inflection"))]) (evil-space . [(20151208 1228) ((evil (1 0 0))) "Repeat motion in Evil. Correct the behaviour of what SPC should do." single ((:commit . "a9c07284d308425deee134c9d88a2d538dd229e6") (:keywords "space" "repeat" "motion") (:authors ("Quang Linh LE" . "linktohack@gmail.com")) (:maintainer "Quang Linh LE" . "linktohack@gmail.com") (:url . "http://github.com/linktohack/evil-space"))]) (evil-snipe . [(20180731 1731) ((emacs (24 4)) (evil (1 2 12)) (cl-lib (0 5))) "emulate vim-sneak & vim-seek" single ((:commit . "8dd076cc56eb9b04494e4e303b86a959b048350b") (:keywords "emulation" "vim" "evil" "sneak" "seek") (:authors ("Henrik Lissner <http://github/hlissner>")) (:maintainer "Henrik Lissner" . "henrik@lissner.net") (:url . "https://github.com/hlissner/evil-snipe"))]) (evil-smartparens . [(20171210 1513) ((evil (1 0)) (emacs (24 4)) (smartparens (1 10 1))) "Evil support for smartparens" single ((:commit . "026d4a3cfce415a4dfae1457f871b385386e61d3") (:keywords "evil" "smartparens") (:authors ("Lars Andersen" . "expez@expez.com")) (:maintainer "Lars Andersen" . "expez@expez.com") (:url . "https://www.github.com/expez/evil-smartparens"))]) (evil-search-highlight-persist . [(20170523 334) ((highlight (0))) "Persistent highlights after search" single ((:commit . "979d2dec58d3b9c5ca5fdf4bb802a0209913794e") (:authors ("Juanjo Alvarez" . "juanjo@juanjoalvarez.net")) (:maintainer "Juanjo Alvarez" . "juanjo@juanjoalvarez.net"))]) (evil-rsi . [(20160221 2104) ((evil (1 0 0))) "Use emacs motion keys in evil, inspired by vim-rsi" single ((:commit . "65ae60866be494e4622fe383e23975e04d2a42a3") (:keywords "evil" "rsi" "evil-rsi") (:authors ("Quang Linh LE" . "linktohack@gmail.com")) (:maintainer "Quang Linh LE" . "linktohack@gmail.com") (:url . "http://github.com/linktohack/evil-rsi"))]) (evil-replace-with-register . [(20170713 925) ((evil (1 0 8))) "Port of vim plugin ReplaceWithRegister" single ((:commit . "91cc7bf21a94703c441cc9212214075b226b7f67") (:keywords "evil" "plugin") (:authors ("Dewdrops" . "v_v_4474@126.com")) (:maintainer "Dewdrops" . "v_v_4474@126.com") (:url . "https://github.com/Dewdrops/evil-ReplaceWithRegister"))]) (evil-replace-with-char . [(20180324 2206) ((evil (1 2 13)) (emacs (24))) "replace chars of a text object with a char" single ((:commit . "ed4a12d5bff11163eb03ad2826c52fd30f51a8d3") (:authors ("Filipe Silva" . "filipe.silva@gmail.com")) (:maintainer "Filipe Silva" . "filipe.silva@gmail.com") (:url . "https://github.com/ninrod/evil-replace-with-char"))]) (evil-rails . [(20160621 2258) ((evil (1 0)) (projectile-rails (1 0))) "Rails support for Evil Mode" single ((:commit . "c8669783d8a40719b2604c58a4c06c248cab272f") (:keywords "ruby" "rails" "vim" "project" "convenience" "web" "evil" "projectile") (:authors ("Antono Vasiljev" . "antono.vasiljev@gmail.com")) (:maintainer "Antono Vasiljev" . "antono.vasiljev@gmail.com") (:url . "https://github.com/antono/evil-rails"))]) (evil-quickscope . [(20160202 1924) ((evil (0))) "Highlight unique characters in words for f,F,t,T navigation" single ((:commit . "37a20e4c56c6058abf186ad4013c155e695e876f") (:keywords "faces" "emulation" "vim" "evil") (:authors ("Michael Chen" . "blorbx@gmail.com")) (:maintainer "Michael Chen" . "blorbx@gmail.com") (:url . "http://github.com/blorbx/evil-quickscope"))]) (evil-python-movement . [(20180724 1420) ((emacs (25 1)) (cl-lib (0 5)) (dash (2 13 0)) (evil (1 0)) (s (1 12 0))) "Port Neovim's python movement to Evil" single ((:commit . "9936b3b7f8d96415d517c1f3604637889484a637") (:authors ("Felipe Lema <felipelema en mortemale punto org>")) (:maintainer "Felipe Lema <felipelema en mortemale punto org>") (:url . "https://bitbucket.org/FelipeLema/evil-python-movement.el/"))]) (evil-paredit . [(20150413 2048) ((evil (1 0 9)) (paredit (25 -2))) "Paredit support for evil keybindings" single ((:commit . "e058fbdcf9dbf7ad6cc77f0172d7517ef233d55f") (:keywords "paredit" "evil") (:authors ("Roman Gonzalez" . "romanandreg@gmail.com")) (:maintainer "Roman Gonzalez" . "romanandreg@gmail.com") (:url . "https://github.com/roman/evil-paredit"))]) (evil-org . [(20180323 2306) ((emacs (24 4)) (evil (1 0))) "evil keybindings for org-mode" tar ((:commit . "b6d652a9163d3430a9e0933a554bdbee5244bbf6") (:keywords "evil" "vim-emulation" "org-mode" "key-bindings" "presets") (:maintainer "Somelauw") (:url . "https://github.com/Somelauw/evil-org-mode.git"))]) (evil-opener . [(20161207 1810) ((evil (1 2 12)) (opener (0 2 2))) "opening urls as buffers in evil" tar ((:commit . "c384f67278046fdcd220275fdd212ab85672cbeb") (:keywords "url" "http" "files") (:authors ("Tim Reddehase" . "tr@rightsrestricted.com")) (:maintainer "Tim Reddehase" . "tr@rightsrestricted.com") (:url . "https://github.com/0robustus1/opener.el"))]) (evil-numbers . [(20140606 1251) nil "increment/decrement numbers like in vim" single ((:commit . "6ea1c8c3a9b37bed63d48f1128e9a4910e68187e") (:keywords "numbers" "increment" "decrement" "octal" "hex" "binary") (:authors ("Michael Markert" . "markert.michael@googlemail.com")) (:maintainer "Michael Markert" . "markert.michael@googlemail.com") (:url . "http://github.com/cofi/evil-numbers"))]) (evil-nerd-commenter . [(20180722 2325) ((emacs (24 4))) "Comment/uncomment lines efficiently. Like Nerd Commenter in Vim" tar ((:commit . "275c95c89cc09c7096bd6fd0deabd49f29634f5d") (:keywords "commenter" "vim" "line" "evil") (:authors ("Chen Bin" . "chenbin.sh@gmail.com")) (:maintainer "Chen Bin" . "chenbin.sh@gmail.com") (:url . "http://github.com/redguardtoo/evil-nerd-commenter"))]) (evil-multiedit . [(20180210 219) ((emacs (24 4)) (evil (1 2 12)) (iedit (0 97)) (cl-lib (0 5))) "multiple cursors for evil-mode" single ((:commit . "ea3d9177b74ab0bc65e55df9cc0a0b42e4ef815d") (:keywords "multiple cursors" "editing" "iedit") (:authors ("Henrik Lissner <http://github/hlissner>")) (:maintainer "Henrik Lissner" . "henrik@lissner.net") (:url . "https://github.com/hlissner/evil-multiedit"))]) (evil-mu4e . [(20180613 1039) ((emacs (24 4)) (evil (1 2 10))) "evil-based key bindings for mu4e" single ((:commit . "5b22c1e30246318f233264506272d770f63897ca") (:authors ("Joris Engbers" . "info@jorisengbers.nl")) (:maintainer "Joris Engbers" . "info@jorisengbers.nl") (:url . "https://github.com/JorisE/evil-mu4e"))]) (evil-mc-extras . [(20170202 1649) ((emacs (24 3)) (evil (1 2 12)) (cl-lib (0 5)) (evil-mc (0 0 2)) (evil-numbers (0 4))) "Extra functionality for evil-mc" tar ((:commit . "8c1af3232dd1e15b2ea38360b8cd1e857e11c416") (:keywords "evil" "editing" "multiple-cursors" "vim" "evil-multiple-cursors" "evil-mc" "evil-mc-extras") (:authors ("Gabriel Adomnicai" . "gabesoft@gmail.com")) (:maintainer "Gabriel Adomnicai" . "gabesoft@gmail.com") (:url . "https://github.com/gabesoft/evil-mc-extras"))]) (evil-mc . [(20180604 333) ((emacs (24 3)) (evil (1 2 12)) (cl-lib (0 5))) "Multiple cursors for evil-mode" tar ((:commit . "05686bc98ce4682cc47530f2045dcff2a6897ea0") (:keywords "evil" "editing" "multiple-cursors" "vim" "evil-multiple-cursors" "evil-mc" "evil-mc") (:authors ("Gabriel Adomnicai" . "gabesoft@gmail.com")) (:maintainer "Gabriel Adomnicai" . "gabesoft@gmail.com") (:url . "https://github.com/gabesoft/evil-mc"))]) (evil-matchit . [(20180822 712) ((evil (1 0 7))) "Vim matchit ported to Evil" tar ((:commit . "47894a6cc02c037dd782d0c0023a3193b6b49e89") (:keywords "matchit" "vim" "evil") (:authors ("Chen Bin" . "chenbin.sh@gmail.com")) (:maintainer "Chen Bin" . "chenbin.sh@gmail.com") (:url . "http://github.com/redguardtoo/evil-matchit"))]) (evil-mark-replace . [(20150424 718) ((evil (1 0 8))) "replace the thing in marked area" single ((:commit . "56cf191724a3e82239ca47a17b071c20aedb0617") (:keywords "mark" "replace" "evil") (:authors ("Chen Bin" . "chenbin.sh@gmail.com")) (:maintainer "Chen Bin" . "chenbin.sh@gmail.com") (:url . "http://github.com/redguardtoo/evil-mark-replace"))]) (evil-magit . [(20180702 1553) ((evil (1 2 3)) (magit (2 6 0))) "evil-based key bindings for magit" single ((:commit . "9e2275b14807168451e10b93d69e420e435f21ef") (:authors ("Justin Burkett" . "justin@burkett.cc")) (:maintainer "Justin Burkett" . "justin@burkett.cc") (:url . "https://github.com/justbur/evil-magit"))]) (evil-lispy . [(20170304 1059) ((lispy (0 26 0)) (evil (1 2 12)) (hydra (0 13 5))) "precision Lisp editing with Evil and Lispy" tar ((:commit . "040a7ee130c2403a1d6dac591b94b202bb48e186") (:keywords "lisp") (:authors ("Brandon Carrell <brandoncarrell@gmail.com>, Mika Vilpas" . "mika.vilpas@gmail.com")) (:maintainer "Brandon Carrell <brandoncarrell@gmail.com>, Mika Vilpas" . "mika.vilpas@gmail.com") (:url . "https://github.com/sp3ctum/evil-lispy"))]) (evil-lisp-state . [(20160404 248) ((evil (1 0 9)) (bind-map (0)) (smartparens (1 6 1))) "An evil state to edit Lisp code" single ((:commit . "3c65fecd9917a41eaf6460f22187e2323821f3ce") (:keywords "convenience" "editing" "evil" "smartparens" "lisp" "mnemonic") (:authors ("Sylvain Benner" . "sylvain.benner@gmail.com")) (:maintainer "Sylvain Benner" . "sylvain.benner@gmail.com") (:url . "https://github.com/syl20bnr/evil-lisp-state"))]) (evil-lion . [(20170811 614) ((emacs (24 3)) (evil (1 0 0))) "Evil align operator, port of vim-lion" single ((:commit . "aaa3874ad54c31b4322ac5bbc63e331498b11d61") (:keywords "emulations" "evil" "vim") (:authors ("edkolev" . "evgenysw@gmail.com")) (:maintainer "edkolev" . "evgenysw@gmail.com") (:url . "http://github.com/edkolev/evil-lion"))]) (evil-ledger . [(20180802 1612) ((emacs (24 4)) (evil (1 2 12)) (ledger-mode (0))) "Make `ledger-mode' more `evil'." single ((:commit . "7a9f9f5d39c42fffdba8004f8982642351f2b233") (:keywords "convenience" "evil" "languages" "ledger" "vim-emulation") (:authors ("Aaron Jacobs" . "atheriel@gmail.com")) (:maintainer "Aaron Jacobs" . "atheriel@gmail.com") (:url . "https://github.com/atheriel/evil-ledger"))]) (evil-leader . [(20140606 1243) ((evil (0))) "let there be <leader>" single ((:commit . "39f7014bcf8b36463e0c7512c638bda4bac6c2cf") (:keywords "evil" "vim-emulation" "leader") (:authors ("Michael Markert" . "markert.michael@googlemail.com")) (:maintainer "Michael Markert" . "markert.michael@googlemail.com") (:url . "http://github.com/cofi/evil-leader"))]) (evil-indent-textobject . [(20130831 2219) ((evil (0))) "evil textobjects based on indentation" single ((:commit . "70a1154a531b7cfdbb9a31d6922482791e20a3a7") (:keywords "convenience" "evil") (:authors ("Michael Markert" . "markert.michael@gmail.com")) (:maintainer "Michael Markert" . "markert.michael@gmail.com") (:url . "http://github.com/cofi/evil-indent-textobject"))]) (evil-indent-plus . [(20151109 1906) ((evil (0)) (cl-lib (0 5))) "Evil textobjects based on indentation" single ((:commit . "0c7501e6efed661242c3a20e0a6c79a6455c2c40") (:keywords "convenience" "evil") (:authors ("Eivind Fonn" . "evfonn@gmail.com")) (:maintainer "Eivind Fonn" . "evfonn@gmail.com") (:url . "http://github.com/TheBB/evil-indent-plus"))]) (evil-iedit-state . [(20180607 558) ((evil (1 0 9)) (iedit (0 97))) "Evil states to interface iedit mode." single ((:commit . "f75cff4ecbd5beaa9ca64a6c157c4105f078daec") (:keywords "convenience" "editing" "evil" "iedit" "mnemonic") (:authors ("Sylvain Benner" . "sylvain.benner@gmail.com")) (:maintainer "Sylvain Benner" . "sylvain.benner@gmail.com") (:url . "https://github.com/syl20bnr/evil-iedit-state"))]) (evil-goggles . [(20180725 952) ((emacs (24 4)) (evil (1 0 0))) "Add a visual hint to evil operations" single ((:commit . "d7876e6566ac82b7c3251a59651e7db6ab756589") (:keywords "emulations" "evil" "vim" "visual") (:authors ("edkolev" . "evgenysw@gmail.com")) (:maintainer "edkolev" . "evgenysw@gmail.com") (:url . "http://github.com/edkolev/evil-goggles"))]) (evil-god-state . [(20141117 255) ((evil (1 0 8)) (god-mode (2 12 0))) "use god-mode keybindings in evil-mode" single ((:commit . "3d44197dc0a1fb40e7b7ff8717f8a8c339ce1d40") (:keywords "evil" "leader" "god-mode") (:authors ("Eric Seidel")) (:maintainer "Eric Seidel") (:url . "https://github.com/gridaphobe/evil-god-state"))]) (evil-fringe-mark . [(20180728 647) ((emacs (24 3)) (evil (1 0 0)) (fringe-helper (0 1 1)) (goto-chg (1 6))) "Display evil-mode marks in the fringe" tar ((:commit . "37521e190dc0414a2bfddd6b219527b1a8dd3f58") (:authors ("Andrew Smith" . "andy.bill.smith@gmail.com")) (:maintainer "Andrew Smith" . "andy.bill.smith@gmail.com") (:url . "https://github.com/Andrew-William-Smith/evil-fringe-mark"))]) (evil-find-char-pinyin . [(20160514 2041) ((evil (1 2 12)) (pinyinlib (0 1 0))) "Evil's f/F/t/T/evil-snipe commands with Pinyin support" single ((:commit . "04e277946d658f1a73c68dcbbadea9c21097a31c") (:keywords "extensions") (:authors ("Junpeng Qiu" . "qjpchmail@gmail.com")) (:maintainer "Junpeng Qiu" . "qjpchmail@gmail.com"))]) (evil-extra-operator . [(20161213 403) ((evil (1 0 7))) "Evil operator for evaluating codes, taking notes, searching via google, etc." single ((:commit . "e16a9b36f9901254da9af8a73871061616410fc3") (:keywords "evil" "plugin") (:authors ("Dewdrops" . "v_v_4474@126.com")) (:maintainer "Dewdrops" . "v_v_4474@126.com") (:url . "http://github.com/Dewdrops/evil-extra-operator"))]) (evil-expat . [(20180719 816) ((emacs (24 3)) (evil (1 0 0))) "Evil ex commands" single ((:commit . "3ff831784c5f301330ecced5ebd43cce42980d2b") (:keywords "emulations" "evil" "vim") (:authors ("edkolev" . "evgenysw@gmail.com")) (:maintainer "edkolev" . "evgenysw@gmail.com") (:url . "http://github.com/edkolev/evil-expat"))]) (evil-exchange . [(20170511 259) ((evil (1 2 8)) (cl-lib (0 3))) "Exchange text more easily within Evil" single ((:commit . "47691537815150715e64e6f6ec79be7746c96120") (:keywords "evil" "plugin") (:authors ("Dewdrops" . "v_v_4474@126.com")) (:maintainer "Dewdrops" . "v_v_4474@126.com") (:url . "http://github.com/Dewdrops/evil-exchange"))]) (evil-escape . [(20180624 319) ((emacs (24)) (evil (1 0 9)) (cl-lib (0 5))) "Escape from anything with a customizable key sequence" single ((:commit . "73b30bfd912f40657b1306ee5849d215f0f9ffbd") (:keywords "convenience" "editing" "evil") (:authors ("Sylvain Benner" . "sylvain.benner@gmail.com")) (:maintainer "Sylvain Benner" . "sylvain.benner@gmail.com") (:url . "https://github.com/syl20bnr/evil-escape"))]) (evil-embrace . [(20160519 1829) ((emacs (24 4)) (embrace (0 1 0)) (evil-surround (0))) "Evil integration of embrace.el" single ((:commit . "4379adea032b25e359d01a36301b4a5afdd0d1b7") (:keywords "extensions") (:authors ("Junpeng Qiu" . "qjpchmail@gmail.com")) (:maintainer "Junpeng Qiu" . "qjpchmail@gmail.com"))]) (evil-ediff . [(20170724 1923) ((evil (1 2 3))) "Make ediff a little evil" single ((:commit . "50d26cb0654fca8f8fd7227410e5cbf0b8f681cf") (:authors ("Justin Burkett" . "justin@burkett.cc")) (:maintainer "Justin Burkett" . "justin@burkett.cc") (:url . "https://github.com/justbur/evil-ediff"))]) (evil-easymotion . [(20180114 654) ((emacs (24)) (avy (0 3 0)) (cl-lib (0 5))) "A port of vim's easymotion to emacs" single ((:commit . "79c13ed3bce018ac09d358e642e5bd7025e93603") (:keywords "convenience" "evil") (:authors ("PythonNut" . "pythonnut@pythonnut.com")) (:maintainer "PythonNut" . "pythonnut@pythonnut.com") (:url . "https://github.com/pythonnut/evil-easymotion"))]) (evil-dvorak . [(20160416 1841) ((evil (1 0 8))) "evil keybindings for that work with dvorak mode" tar ((:commit . "824f7c56980d72a0ff04c662223540cd66f13754") (:keywords "evil" "vim-emulation" "dvorak" "keyboard") (:url . "https://github.com/jbranso/evil-dvorak.git"))]) (evil-commentary . [(20170413 1451) ((evil (1 0 0))) "Comment stuff out. A port of vim-commentary." tar ((:commit . "395f91014b69844b81660c155f42eb9b1b3d199d") (:keywords "evil" "comment" "commentary" "evil-commentary") (:authors ("Quang Linh LE" . "linktohack@gmail.com")) (:maintainer "Quang Linh LE" . "linktohack@gmail.com") (:url . "http://github.com/linktohack/evil-commentary"))]) (evil-collection . [(20180830 500) ((emacs (25 1)) (cl-lib (0 5)) (evil (1 2 13))) "A set of keybindings for Evil mode" tar ((:commit . "04a3e5c85977b05ca9d36535cfbd224917eac0bb") (:keywords "evil" "tools") (:authors ("James Nguyen" . "james@jojojames.com")) (:maintainer "James Nguyen" . "james@jojojames.com") (:url . "https://github.com/emacs-evil/evil-collection"))]) (evil-colemak-minimal . [(20171006 1317) ((emacs (24)) (evil (1 2 12))) "Minimal Colemak key bindings for evil-mode" single ((:commit . "6d98b6da60f414524a0d718f76024c26dce742b3") (:keywords "colemak" "evil") (:authors ("Bryan Allred" . "bryan@revolvingcow.com")) (:maintainer "Bryan Allred" . "bryan@revolvingcow.com") (:url . "https://github.com/bmallred/evil-colemak-minimal"))]) (evil-colemak-basics . [(20170425 1209) ((emacs (24)) (evil (1 2 12)) (evil-snipe (2 0 3))) "Basic Colemak key bindings for evil-mode" single ((:commit . "7844079b47f47bb1dc24c885b0ac2e67524fa960") (:keywords "colemak" "evil") (:authors ("Wouter Bolsterlee" . "wouter@bolsterl.ee")) (:maintainer "Wouter Bolsterlee" . "wouter@bolsterl.ee") (:url . "https://github.com/wbolster/evil-colemak-basics"))]) (evil-cleverparens . [(20170718 413) ((evil (1 0)) (paredit (1)) (smartparens (1 6 1)) (emacs (24 4)) (dash (2 12 0))) "Evil friendly minor-mode for editing lisp." tar ((:commit . "8c45879d49bfa6d4e414b6c1df700a4a51cbb869") (:keywords "cleverparens" "parentheses" "evil" "paredit" "smartparens") (:authors ("Olli Piepponen" . "opieppo@gmail.com")) (:maintainer "Olli Piepponen" . "opieppo@gmail.com") (:url . "https://github.com/luxbock/evil-cleverparens"))]) (evil-avy . [(20150908 748) ((emacs (24 1)) (cl-lib (0 5)) (avy (0 3 0)) (evil (1 2 3))) "set-based completion" single ((:commit . "2dd955cc3ecaa7ddeb67b295298abdc6d16dd3a5") (:keywords "point" "location" "evil" "vim") (:authors ("Yufan Lou" . "loganlyf@gmail.com")) (:maintainer "Yufan Lou" . "loganlyf@gmail.com") (:url . "https://github.com/louy2/evil-avy"))]) (evil-args . [(20140329 2129) ((evil (1 0 8))) "Motions and text objects for delimited arguments in Evil." single ((:commit . "b4c68bfb458210bbe0b7f35951400920b06f2285") (:keywords "evil" "vim-emulation") (:authors ("Connor Smith" . "wconnorsmith@gmail.com")) (:maintainer "Connor Smith" . "wconnorsmith@gmail.com") (:url . "http://github.com/wcsmith/evil-args"))]) (evil-anzu . [(20170124 718) ((evil (1 0 0)) (anzu (0 46))) "anzu for evil-mode" single ((:commit . "9bca6ca14d865e7e005bc02a28a09b4ae74facc9") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com") ("Fredrik Bergroth" . "fbergroth@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-evil-anzu"))]) (evil . [(20180723 1243) ((emacs (24 1)) (undo-tree (0 6 3)) (goto-chg (1 6)) (cl-lib (0 5))) "Extensible Vi layer for Emacs." tar ((:commit . "3d9f76f3add56f670042af9421b36dfb8574ad00"))]) (eve-mode . [(20170822 2231) ((emacs (25)) (polymode (1 0)) (markdown-mode (2 0))) "Major mode for editing Eve documents." single ((:commit . "a4661114d9c18725691b76321d72167ca5a9070a") (:keywords "languages" "wp" "tools") (:authors ("Joshua Cole" . "joshuafcole@gmail.com")) (:maintainer "Joshua Cole" . "joshuafcole@gmail.com") (:url . "https://github.com/witheve/emacs-eve-mode"))]) (evalator-clojure . [(20160208 2148) ((cider (0 10 0)) (evalator (1 0 0))) "Clojure evaluation context for evalator via CIDER." tar ((:commit . "caa4e0a137bdfada86593128a654e16aa617ad50") (:keywords "languages" "clojure" "cider" "helm") (:authors ("Sean Irby")) (:maintainer "Sean Irby" . "sean.t.irby@gmail.com") (:url . "http://www.github.com/seanirby/evalator-clojure"))]) (evalator . [(20160213 128) ((helm-core (1 9 1))) "Package for interactive transformation of data with helm" tar ((:commit . "f30da4da48c0b3f3cfa1fc1c7cfdb53ffe79df36") (:keywords "languages" "elisp" "helm") (:authors ("Sean Irby")) (:maintainer "Sean Irby" . "sean.t.irby@gmail.com") (:url . "http://www.github.com/seanirby/evalator"))]) (eval-sexp-fu . [(20180510 203) ((cl-lib (0)) (highlight (0))) "Tiny functionality enhancements for evaluating sexps." single ((:commit . "1cfd0f3e167d63080692fad97ffe0091b024ad73") (:keywords "lisp" "highlight" "convenience") (:authors ("Takeshi Banse" . "takebi@laafc.net")) (:maintainer "Takeshi Banse" . "takebi@laafc.net"))]) (eval-in-repl . [(20171122 1343) ((dash (0 0 0)) (paredit (0 0 0)) (ace-window (0 0 0))) "Consistent ESS-like eval interface for various REPLs" tar ((:commit . "fea05a5b81d74ac53cb2a83aa83a73d9526bcc42") (:url . "https://github.com/kaz-yos/eval-in-repl/"))]) (eval-expr . [(20120619 647) nil "enhanced eval-expression command" single ((:commit . "a0e69e83de41df8dbccefc1962ab4f02206a3328") (:keywords "lisp" "extensions") (:authors ("Noah Friedman" . "friedman@splode.com")) (:maintainer nil . "friedman@splode.com"))]) (euslisp-mode . [(20170830 1929) ((emacs (24 3)) (s (1 9)) (exec-path-from-shell (0)) (helm-ag (0 58))) "Major mode for Euslisp-formatted text" single ((:commit . "db62a2d148482317794727982576494596365a55") (:keywords "euslisp" "euslisp" "github") (:authors ("iory" . "ab.ioryz@gmail.com")) (:maintainer "iory" . "ab.ioryz@gmail.com") (:url . "https://github.com/iory/euslisp-mode"))]) (ethan-wspace . [(20170507 2030) nil "whitespace customizations for emacs" single ((:commit . "e055ee6730c0b03525d32e67511ef6c51e4c29e4") (:keywords "whitespace" "tab" "newline" "trailing" "clean") (:authors ("Ethan Glasser-Camp" . "ethan@betacantrips.com")) (:maintainer "Ethan Glasser-Camp" . "ethan@betacantrips.com"))]) (eterm-256color . [(20180520 1223) ((emacs (24 4)) (xterm-color (1 7)) (f (0 19 0))) "Customizable 256 colors for term." tar ((:commit . "ef99d3a12ddce4aa06069c19e66e826f4cfc91e4") (:keywords "faces") (:authors ("Diego A. Mundo" . "diegoamundo@gmail.com")) (:maintainer "Diego A. Mundo" . "diegoamundo@gmail.com") (:url . "http://github.com/dieggsy/eterm-256color"))]) (etable . [(20161028 2009) ((dash (2 9 0)) (interval-list (0 1)) (emacs (24 4))) "Implementation of javax.swing.JTable for Emacs." tar ((:commit . "d502141f0c69bf95256ba5cb9cd15350c7e942d2"))]) (esxml . [(20171129 807) nil "Library for working with xml via esxml and sxml" tar ((:commit . "5548ceba17deae0c3c6d0092672edc4de3c75ce3"))]) (esup . [(20180727 342) ((cl-lib (0 5)) (emacs (24))) "the Emacs StartUp Profiler (ESUP)" tar ((:commit . "5acb60e8d7a8fef854178f325682765820522b10") (:keywords "convenience" "processes") (:authors ("Joe Schafer" . "joe@jschaf.com")) (:maintainer "Joe Schafer" . "joe@jschaf.com") (:url . "http://github.com/jschaf/esup"))]) (ess-view . [(20180525 2203) ((ess (15)) (s (1 8 0)) (f (0 16 0))) "View R dataframes in a spreadsheet software" single ((:commit . "dab08b405dbda5aff71022c5cf021ea18b2bde0f") (:keywords "extensions" "ess") (:authors ("Bocci Gionata" . "boccigionata@gmail.com")) (:maintainer "Bocci Gionata" . "boccigionata@gmail.com") (:url . "https://github.com/GioBo/ess-view"))]) (ess-smart-underscore . [(20170223 115) ((ess (0))) "Ess Smart Underscore" tar ((:commit . "02e8a03553f34fe7184afff97f20e560d6f8d617") (:keywords "ess" "underscore") (:authors ("Matthew L. Fidler")) (:maintainer "Matthew Fidler") (:url . "http://github.com/mlf176f2/ess-smart-underscore.el"))]) (ess-smart-equals . [(20150202 601) ((emacs (24)) (ess (5 0))) "better smart-assignment with =-key in R and S" single ((:commit . "e0f5f18f01ed252fde50d051adf1fa6254a254c9") (:keywords "r" "s" "ess" "convenience") (:authors ("Christopher R. Genovese" . "genovese@cmu.edu")) (:maintainer "Christopher R. Genovese" . "genovese@cmu.edu") (:url . "https://github.com/genovese/ess-smart-equals"))]) (ess-R-data-view . [(20130509 1158) ((ctable (20130313 1743)) (popup (20130324 1305)) (ess (20130225 1754))) "Data viewer for GNU R" single ((:commit . "d6e98d3ae1e2a2ea39a56eebcdb73e99d29562e9") (:keywords "convenience") (:authors ("myuhe <yuhei.maeda_at_gmail.com>")) (:maintainer "myuhe") (:url . "https://github.com/myuhe/ess-R-data-view.el"))]) (ess . [(20180904 829) nil "Emacs Speaks Statistics" tar ((:commit . "fffb56a5efc5d389a7eb38de7c437fc98d83d635") (:authors ("David Smith" . "dsmith@stats.adelaide.edu.au")) (:maintainer "ESS-core" . "ESS-core@r-project.org"))]) (esqlite-helm . [(20151116 850) ((esqlite (0 2 0)) (helm (20131207 845))) "Define helm source for sqlite database" single ((:commit . "bc4047e09b8f6c34802db86095cd465935670dce") (:keywords "data") (:authors ("Masahiro Hayashi" . "mhayashi1120@gmail.com")) (:maintainer "Masahiro Hayashi" . "mhayashi1120@gmail.com") (:url . "https://github.com/mhayashi1120/Emacs-esqlite"))]) (esqlite . [(20151206 1206) ((pcsv (1 3 3))) "Manipulate sqlite file from Emacs" single ((:commit . "bc4047e09b8f6c34802db86095cd465935670dce") (:keywords "data") (:authors ("Masahiro Hayashi" . "mhayashi1120@gmail.com")) (:maintainer "Masahiro Hayashi" . "mhayashi1120@gmail.com") (:url . "https://github.com/mhayashi1120/Emacs-esqlite"))]) (espuds . [(20160905 1300) ((s (1 7 0)) (dash (2 2 0)) (f (0 12 1))) "Ecukes step definitions" single ((:commit . "78fc53feaf77a98d63894cd410faee2a18107b00") (:keywords "test") (:authors ("Johan Andersson" . "johan.rejeep@gmail.com")) (:maintainer "Johan Andersson" . "johan.rejeep@gmail.com") (:url . "http://github.com/ecukes/espuds"))]) (espresso-theme . [(20170716 1513) nil "Espresso Tutti Colori port for Emacs" single ((:commit . "e79c5c14732b7e34aab75dbcc968839536536c59") (:authors ("Martin Kühl <purl.org/net/mkhl>")) (:maintainer "Martin Kühl <purl.org/net/mkhl>") (:url . "https://github.com/dgutov/espresso-theme"))]) (eslintd-fix . [(20180429 1455) ((dash (2 12 0)) (emacs (24 3))) "use eslint_d to automatically fix js files" single ((:commit . "90e451af4daa190d6c0e29fb714b0501a7cce89a") (:authors ("Aaron Jensen" . "aaronjensen@gmail.com")) (:maintainer "Aaron Jensen" . "aaronjensen@gmail.com") (:url . "https://github.com/aaronjensen/eslintd-fix"))]) (eslint-fix . [(20180514 700) nil "Fix JavaScript files using ESLint" single ((:commit . "f81f3b47a47460611fbdbdae1d23275ec78f2f8d") (:keywords "tools" "javascript" "eslint" "lint" "formatting" "style") (:authors ("Neri Marschik" . "marschik_neri@cyberagent.co.jp")) (:maintainer "Neri Marschik" . "marschik_neri@cyberagent.co.jp") (:url . "https://github.com/codesuki/eslint-fix"))]) (eshell-z . [(20170117 438) ((cl-lib (0 5))) "cd to frequent directory in eshell" single ((:commit . "c9334cbc1552234df3437f35d98e32f4d18446b8") (:keywords "convenience") (:authors ("Chunyang Xu" . "mail@xuchunyang.me")) (:maintainer "Chunyang Xu" . "mail@xuchunyang.me") (:url . "https://github.com/xuchunyang/eshell-z"))]) (eshell-up . [(20170425 1737) ((emacs (24))) "Quickly go to a specific parent directory in eshell" single ((:commit . "9c100bae5c3020e8d9307e4332d3b64e7dc28519") (:keywords "eshell") (:authors ("Peter W. V. Tran-Jørgensen" . "peter.w.v.jorgensen@gmail.com")) (:maintainer "Peter W. V. Tran-Jørgensen" . "peter.w.v.jorgensen@gmail.com") (:url . "https://github.com/peterwvj/eshell-up"))]) (eshell-prompt-extras . [(20180110 634) nil "Display extra information for your eshell prompt." single ((:commit . "1d8825dcc005b488c6366d0b3015fc6686194eea") (:keywords "eshell" "prompt") (:authors ("Wei Zhao" . "kaihaosw@gmail.com")) (:maintainer "Chunyang Xu" . "mail@xuchunyang.me") (:url . "https://github.com/hiddenlotus/eshell-prompt-extras"))]) (eshell-git-prompt . [(20170909 1452) ((emacs (24 1)) (cl-lib (0 5)) (dash (2 11 0))) "Some Eshell prompt for Git users" single ((:commit . "b6bb2d7bd4e393b4170b29891cfefb72ae020aab") (:keywords "eshell" "git") (:authors ("Chunyang Xu" . "mail@xuchunyang.me")) (:maintainer "Chunyang Xu" . "mail@xuchunyang.me") (:url . "https://github.com/xuchunyang/eshell-git-prompt"))]) (eshell-fringe-status . [(20170117 2316) nil "Show last status in fringe" single ((:commit . "adc6997c68e39c0d52a2af1b2fd5cf2057783797") (:authors ("Tom Willemse" . "tom@ryuslash.org")) (:maintainer "Tom Willemse" . "tom@ryuslash.org") (:url . "http://projects.ryuslash.org/eshell-fringe-status/"))]) (eshell-fixed-prompt . [(20170804 1335) ((emacs (25)) (s (1 11 0))) "Restrict eshell to a single fixed prompt" single ((:commit . "4351b214de6d4e8e45279930448e2f93b491848e") (:authors ("Tijs Mallaerts" . "tijs.mallaerts@gmail.com")) (:maintainer "Tijs Mallaerts" . "tijs.mallaerts@gmail.com"))]) (eshell-did-you-mean . [(20150915 1952) ((emacs (24 1)) (cl-lib (0 5))) "command not found (\"did you mean…\" feature) in Eshell" single ((:commit . "7cb6ef8e2274d0a50a9e114d412307a6543533d5") (:keywords "eshell") (:authors ("Chunyang Xu" . "xuchunyang56@gmail.com")) (:maintainer "Chunyang Xu" . "xuchunyang56@gmail.com") (:url . "https://github.com/xuchunyang/eshell-did-you-mean"))]) (eshell-bookmark . [(20170922 1514) ((emacs (24 3))) "Integrate bookmarks with eshell." single ((:commit . "deda4b848b2fb979dbe73ead2cb866610e3596ed") (:keywords "convenience" "files") (:authors ("Matúš Goljer" . "matus.goljer@gmail.com")) (:maintainer "Matúš Goljer" . "matus.goljer@gmail.com") (:url . "https://github.com/Fuco1/eshell-bookmark"))]) (eshell-autojump . [(20150927 724) nil "autojump command for Eshell" single ((:commit . "c6a8b81a16576df9875e721fbbfe6690d04e7e43") (:authors ("Alex Schroeder")) (:maintainer "Yen-Chin, Lee" . "coldnew.tw@gmail.com") (:url . "http://github.com/coldnew/eshell-autojump"))]) (esh-help . [(20170830 411) ((dash (1 4 0))) "Add some help functions and support for Eshell" single ((:commit . "8a8a9d4d9852f8bd96da3b94e95ff57097ac8ec6") (:keywords "eshell" "extensions") (:authors ("Tomoya Tanjo" . "ttanjo@gmail.com")) (:maintainer "Tomoya Tanjo" . "ttanjo@gmail.com") (:url . "https://github.com/tom-tan/esh-help/"))]) (esh-buf-stack . [(20140107 1018) nil "Add a buffer stack feature to Eshell" single ((:commit . "ce0ea5aadca3150eaa9d2e6ec20296add4e99176") (:keywords "eshell" "extensions") (:authors ("Tomoya Tanjo" . "ttanjo@gmail.com")) (:maintainer "Tomoya Tanjo" . "ttanjo@gmail.com"))]) (esh-autosuggest . [(20171224 255) ((emacs (24 4)) (company (0 9 4))) "History autosuggestions for eshell" single ((:commit . "2fd996c1a29b21e60854a3c90d7d4fc3d5b0aded") (:keywords "completion" "company" "matching" "convenience" "abbrev") (:authors ("Diego A. Mundo" . "diegoamundo@gmail.com")) (:maintainer "Diego A. Mundo" . "diegoamundo@gmail.com") (:url . "http://github.com/dieggsy/esh-autosuggest"))]) (esa . [(20180403 1525) ((cl-lib (0 5))) "Interface to esa.io" single ((:commit . "417e0ac55abe9b17e0b7165d0df26bc018aff42e") (:keywords "tools" "esa") (:authors ("Nab Inno" . "nab@blahfe.com")) (:maintainer "Nab Inno" . "nab@blahfe.com") (:url . "https://github.com/nabinno/esa.el"))]) (es-windows . [(20140211 904) ((cl-lib (0 3)) (emacs (24))) "Window-management utilities" single ((:commit . "239e30408cb1adb4bc8bd63e2df34711fa910b4f") (:authors ("sabof")) (:maintainer "sabof") (:url . "https://github.com/sabof/es-windows"))]) (es-mode . [(20180212 2225) ((dash (2 11 0)) (cl-lib (0 5)) (spark (1 0)) (s (1 11 0)) (request (0 3 0))) "A major mode for editing and executing Elasticsearch queries" tar ((:commit . "c5ad728ce3fc2c513108e0ada2cd0c08ab94f870") (:keywords "elasticsearch") (:authors ("Lee Hinman" . "lee@writequit.org")) (:maintainer "Lee Hinman" . "lee@writequit.org") (:url . "http://www.github.com/dakrone/es-mode"))]) (es-lib . [(20141111 1830) ((cl-lib (0 3))) "A collection of emacs utilities" tar ((:commit . "753b27363e39c10edc9e4e452bdbbbe4d190df4a") (:authors ("sabof")) (:maintainer "sabof") (:url . "https://github.com/sabof/es-lib"))]) (ert-runner . [(20180831 1145) ((s (1 6 1)) (dash (1 8 0)) (f (0 10 0)) (commander (0 2 0)) (ansi (0 1 0)) (shut-up (0 1 0))) "Opinionated Ert testing workflow" tar ((:commit . "90b8fdd5970ef76a4649be60003b37f82cdc1a65") (:keywords "test") (:authors ("Johan Andersson" . "johan.rejeep@gmail.com")) (:maintainer "Johan Andersson" . "johan.rejeep@gmail.com") (:url . "http://github.com/rejeep/ert-runner.el"))]) (ert-modeline . [(20140115 1015) ((s (1 3 1)) (dash (1 2 0)) (emacs (24 1)) (projectile (0 9 1))) "displays ert test results in the modeline." single ((:commit . "e7be2b81191afb437b70368a819770f8f750e4af") (:keywords "tools" "tests" "convenience") (:authors ("Chris Barrett" . "chris.d.barrett@me.com")) (:maintainer "Chris Barrett" . "chris.d.barrett@me.com"))]) (ert-junit . [(20180809 2111) ((ert (0)) (emacs (23 4))) "JUnit XML reports from ert results" single ((:commit . "69177610824f20d4c4e16af4b9850fd96bea6491") (:keywords "tools" "test" "unittest" "ert") (:authors ("Ola Nilsson" . "ola.nilsson@gmail.com")) (:maintainer "Ola Nilsson" . "ola.nilsson@gmail.com") (:url . "http://bitbucket.org/olanilsson/ert-junit"))]) (ert-expectations . [(20121009 734) nil "The simplest unit test framework in the world" single ((:commit . "aed70e002c4305b66aed7f6d0d48e9addd2dc1e6") (:keywords "test" "unittest" "ert" "expectations") (:authors ("rubikitch" . "rubikitch@ruby-lang.org")) (:maintainer "rubikitch" . "rubikitch@ruby-lang.org") (:url . "http://www.emacswiki.org/emacs/download/ert-expectations.el"))]) (ert-async . [(20151011 1359) nil "Async support for ERT" single ((:commit . "f64a7ed5b0d2900c9a3d8cc33294bf8a79bc8526") (:keywords "test") (:authors ("Johan Andersson" . "johan.rejeep@gmail.com")) (:maintainer "Johan Andersson" . "johan.rejeep@gmail.com") (:url . "http://github.com/rejeep/ert-async.el"))]) (eros . [(20180415 618) ((emacs (24 4))) "Evaluation Result OverlayS for Emacs Lisp" single ((:commit . "dd8910279226259e100dab798b073a52f9b4233a") (:keywords "convenience" "lisp") (:authors ("Tianxiang Xiong" . "tianxiang.xiong@gmail.com")) (:maintainer "Tianxiang Xiong" . "tianxiang.xiong@gmail.com") (:url . "https://github.com/xiongtx/eros"))]) (erlstack-mode . [(20180817 926) ((emacs (25 1)) (dash (2 12 0))) "Minor mode for analysing Erlang stacktraces" single ((:commit . "d480d937f02f8cc66350bc583ee54942a786ac49") (:keywords "tools" "erlang") (:authors ("k32")) (:maintainer "k32") (:url . "https://github.com/k32/erlstack-mode"))]) (erlang . [(20180816 1134) ((emacs (24 1))) "Erlang major mode" tar ((:commit . "1808df550501c5f834edf5d55d0bdcd2b4328d68"))]) (ergoemacs-status . [(20160318 538) ((powerline (2 3)) (mode-icons (0 1 0))) "Adaptive Status Bar / Mode Line" single ((:commit . "d952cc2361adf6eb4d6af60950ad4ab699c81320") (:authors ("Matthew Fidler")) (:maintainer "Matthew Fidler"))]) (ergoemacs-mode . [(20180709 1345) ((emacs (24 1)) (undo-tree (0 6 5)) (cl-lib (0 5))) "Emacs mode based on common modern interface and ergonomics." tar ((:commit . "a5d46653fd3a521276630c81bf75d3e8d224e5cb") (:keywords "convenience") (:authors ("Xah Lee" . "xah@xahlee.org") ("David Capello" . "davidcapello@gmail.com") ("Matthew L. Fidler" . "matthew.fidler@gmail.com")) (:maintainer "Matthew L. Fidler" . "matthew.fidler@gmail.com") (:url . "https://github.com/ergoemacs/ergoemacs-mode"))]) (erefactor . [(20160121 959) ((cl-lib (0 3))) "Emacs-Lisp refactoring utilities" single ((:commit . "bf68085e5635eb94fd85709f8e1355c1f5534745") (:keywords "extensions" "tools" "maint") (:authors ("Masahiro Hayashi" . "mhayashi1120@gmail.com")) (:maintainer "Masahiro Hayashi" . "mhayashi1120@gmail.com") (:url . "https://github.com/mhayashi1120/Emacs-erefactor"))]) (eredis . [(20180221 2113) nil "eredis, a Redis client in emacs lisp" single ((:commit . "8a96034805fe0664132ce2e12deb9936503af2d4") (:authors ("Justin Heyes-Jones")) (:maintainer "Justin Heyes-Jones") (:url . "http://code.google.com/p/eredis/"))]) (ereader . [(20170810 501) ((emacs (24 4)) (dash (2 12 1)) (s (1 10 0)) (xml+ (0 0 0))) "Major mode for reading ebooks with org-mode integration" tar ((:commit . "f3bbd3f13195f8fba3e3c880aab0e4c60430dcf3") (:keywords "epub" "ebook") (:authors ("Ben Dean" . "bendean837@gmail.com")) (:maintainer "Ben Dean" . "bendean837@gmail.com") (:url . "https://github.com/bddean/emacs-ereader"))]) (ercn . [(20150523 1503) nil "Flexible ERC notifications" single ((:commit . "79a4df5609046ae2e2e3375998287be6dda80615") (:authors ("David Leatherman" . "leathekd@gmail.com")) (:maintainer "David Leatherman" . "leathekd@gmail.com") (:url . "http://www.github.com/leathekd/ercn"))]) (erc-yt . [(20150426 1249) ((dash (2 10 0))) "An erc module to display youtube links nicely" single ((:commit . "43e7d49325b17a3217a6ffb4a9daf75c5ff4e6f8") (:keywords "multimedia") (:authors ("William Stevenson" . "yhvh2000@gmail.com")) (:maintainer "William Stevenson" . "yhvh2000@gmail.com"))]) (erc-youtube . [(20150603 2136) nil "Show info about a YouTube URL in an ERC buffer." single ((:commit . "97054ba8475b442e2aa81e5a291f668b7f28697f") (:keywords "multimedia") (:authors ("Raimon Grau Cuscó" . "raimonster@gmail.com")) (:maintainer "Raimon Grau Cuscó" . "raimonster@gmail.com"))]) (erc-view-log . [(20140227 2039) nil "Major mode for viewing ERC logs" single ((:commit . "c5a25f0cbca84ed2e4f72068c02b66bd0ea3b266") (:keywords "erc" "viewer" "logs" "colors") (:authors ("Antoine Levitt") ("Thomas Riccardi" . "riccardi.thomas@gmail.com")) (:maintainer "Antoine Levitt") (:url . "http://github.com/Niluge-KiWi/erc-view-log/raw/master/erc-view-log.el"))]) (erc-twitch . [(20170427 606) ((json (1 3)) (erc (5 0))) "Support for Twitch emotes for ERC." single ((:commit . "53c6af0cb72e56d897d30a40e7e5066668d6b5ec") (:keywords "twitch" "erc" "emotes") (:authors ("Vibhav Pant" . "vibhavp@gmail.com")) (:maintainer "Vibhav Pant" . "vibhavp@gmail.com") (:url . "https://github.com/vibhavp/erc-twitch"))]) (erc-tweet . [(20150920 1258) nil "shows text of a tweet when an url is posted in erc buffers" single ((:commit . "91fed61e139fa788d66a7358f0d50acc896414b8") (:keywords "extensions") (:authors ("Raimon Grau" . "raimonster@gmail.com")) (:maintainer "Raimon Grau" . "raimonster@gmail.com"))]) (erc-track-score . [(20130328 1215) nil "Add score support to tracked channel buffers" single ((:commit . "5b27531ea6b1a4c4b703b270dfa9128cb5bfdaa3") (:authors ("Julien Danjou" . "julien@danjou.info")) (:maintainer "Julien Danjou" . "julien@danjou.info") (:url . "http://julien.danjou.info/erc-track-score.html"))]) (erc-terminal-notifier . [(20140115 1024) nil "OSX notifications via the terminal-notifier gem for Emacs ERC." single ((:commit . "a3dacb935845e4a20031212bbd82b2170f68d2a8") (:keywords "erc" "terminal-notifier" "nick") (:authors ("Julien Blanchard" . "julien@sideburns.eu")) (:maintainer "Julien Blanchard" . "julien@sideburns.eu") (:url . "http://github.com/julienXX/"))]) (erc-status-sidebar . [(20171223 2124) ((emacs (24 5)) (seq (2 3))) "a hexchat-like activity overview for ERC channels" single ((:commit . "ea4189a1dbfe60117359c36e681ad7c389e2968c") (:authors ("Andrew Barbarello")) (:maintainer "Andrew Barbarello") (:url . "https://github.com/drewbarbs/erc-status-sidebar"))]) (erc-social-graph . [(20150508 1204) nil "A social network graph module for ERC." single ((:commit . "e6ef3416a1c5064054bf054d9f0c1c7bf54a9cd0") (:keywords "erc" "graph") (:authors ("Vibhav Pant" . "vibhavp@gmail.com")) (:maintainer "Vibhav Pant" . "vibhavp@gmail.com") (:url . "https://github.com/vibhavp/erc-social-graph"))]) (erc-scrolltoplace . [(20180608 606) ((emacs (24 0)) (switch-buffer-functions (0 0 1))) "An Erc module to scrolltobottom better with keep-place" single ((:commit . "feb0fbf1fd4bdf220ae2d31ea7c066d8e62089f9") (:keywords "erc" "module" "comm" "scrolltobottom" "keep-place") (:authors ("Jay Kamat" . "jaygkamat@gmail.com")) (:maintainer "Jay Kamat" . "jaygkamat@gmail.com") (:url . "http://gitlab.com/jgkamat/erc-scrolltoplace"))]) (erc-image . [(20180522 1424) nil "Show received image urls in the ERC buffer" single ((:commit . "82fb3871f02e24b1e880770b9a3d187aab43d0f0") (:keywords "multimedia") (:authors ("Jon de Andrés Frías" . "jondeandres@gmail.com") ("Raimon Grau Cuscó" . "raimonster@gmail.com")) (:maintainer "Jon de Andrés Frías" . "jondeandres@gmail.com"))]) (erc-hl-nicks . [(20180415 1946) nil "ERC nick highlighter that ignores uniquifying chars when colorizing" single ((:commit . "756c4438a8245ccd3e389bf6c9850ee8453783ec") (:authors ("David Leatherman" . "leathekd@gmail.com")) (:maintainer "David Leatherman" . "leathekd@gmail.com") (:url . "http://www.github.com/leathekd/erc-hl-nicks"))]) (erc-hipchatify . [(20170314 1637) ((emacs (24 4)) (s (1 10 0)) (alert (1 2)) (request (0 2 0))) "Provide emoticons and html rendering for HipChat" single ((:keywords "erc" "bitlbee" "hipchat" "multimedia") (:authors ("Sean Farley" . "sean@farley.io")) (:maintainer "Sean Farley" . "sean@farley.io") (:url . "https://bitbucket.org/seanfarley/erc-hipchatify"))]) (erc-crypt . [(20161228 1539) ((cl-lib (0 5))) "Symmetric Encryption for ERC" single ((:commit . "731f9264a5bf08a8fc0b5ce69e72058c86f873a5") (:keywords "comm") (:authors (nil . "xristos@sdf.lonestar.org")) (:maintainer nil . "xristos@sdf.lonestar.org") (:url . "https://github.com/atomontage/erc-crypt"))]) (erc-colorize . [(20170107 1339) nil "Per user colorization of whole message" single ((:commit . "d026a016dcb9d63d9ac66d30627a92a8f1681bbd") (:keywords "erc" "convenience") (:authors ("Sylvain Rousseau <thisirs at gmail dot com>")) (:maintainer "Sylvain Rousseau <thisirs at gmail dot com>") (:url . "https://github.com/thisirs/erc-colorize.git"))]) (eproject . [(20180312 1642) ((helm (1 6 4))) "assign files to projects, programatically" tar ((:commit . "068218d2cf2138cb2e8fc29b57e773a0097a7e8b") (:keywords "programming" "projects") (:authors ("Jonathan Rockway" . "jon@jrock.us")) (:maintainer "Jonathan Rockway" . "jon@jrock.us"))]) (eprime-mode . [(20140513 1816) nil "An E-prime checking mode for Emacs" single ((:commit . "17a481af26496be91c07139a9bfc05cfe722506f") (:keywords "e-prime" "english" "grammar") (:authors ("Andrew Hynes" . "andrewhynes@openmailbox.org")) (:maintainer "Andrew Hynes" . "andrewhynes@openmailbox.org") (:url . "https://github.com/AndrewHynes/eprime-mode"))]) (epresent . [(20160411 201) ((org (8)) (cl-lib (0 5))) "Simple presentation mode for Emacs Org-mode" single ((:commit . "6c8abedcf46ff08091fa2bba52eb905c6290057d") (:keywords "gui") (:url . "https://github.com/dakrone/epresent"))]) (epm . [(20161027 734) ((emacs (24 3)) (epl (0 8))) "Emacs Package Manager" tar ((:commit . "ab3d194fc4d11520d6b9bce4746d7242f3f1606a") (:authors ("Chunyang Xu" . "xuchunyang.me@gmail.com")) (:maintainer "Chunyang Xu" . "xuchunyang.me@gmail.com") (:url . "https://github.com/xuchunyang/epm"))]) (epl . [(20180205 2049) ((cl-lib (0 3))) "Emacs Package Library" single ((:commit . "78ab7a85c08222cd15582a298a364774e3282ce6") (:keywords "convenience") (:authors ("Sebastian Wiesner" . "swiesner@lunaryorn.com")) (:maintainer "Johan Andersson" . "johan.rejeep@gmail.com") (:url . "http://github.com/cask/epl"))]) (epkg . [(20180627 2053) ((closql (0 4 0)) (dash (2 13 0)) (emacs (25 1))) "browse the Emacsmirror package database" tar ((:commit . "740b06cb11871f65b16cda602c5d8fc23138e99f") (:keywords "tools") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:url . "https://github.com/emacscollective/epkg"))]) (epic . [(20170210 23) ((htmlize (1 47))) "Evernote Picker for Cocoa Emacs" single ((:commit . "a41826c330eb0ea061d58a08cc861b0c4ac8ec4e") (:keywords "evernote" "applescript") (:authors ("Yoshinari Nomura" . "nom@quickhack.net")) (:maintainer "Yoshinari Nomura" . "nom@quickhack.net") (:url . "https://github.com/yoshinari-nomura/epic"))]) (epc . [(20140610 534) ((concurrent (0 3 1)) (ctable (0 1 2))) "A RPC stack for the Emacs Lisp" tar ((:commit . "e1bfa5ca163273859336e3cc89b4b6460f7f8cda") (:keywords "lisp" "rpc") (:authors ("SAKURAI Masashi <m.sakurai at kiwanami.net>")) (:maintainer "SAKURAI Masashi <m.sakurai at kiwanami.net>") (:url . "https://github.com/kiwanami/emacs-epc"))]) (eopengrok . [(20160904 659) ((s (1 9 0)) (dash (2 10 0)) (magit (2 1 0)) (cl-lib (0 5))) "opengrok interface for emacs" single ((:commit . "78f734328aaf19c52720415c037708ece1944c4c") (:keywords "tools") (:authors ("Youngjoo Lee" . "youngker@gmail.com")) (:maintainer "Youngjoo Lee" . "youngker@gmail.com"))]) (envdir . [(20160221 1923) ((emacs (24)) (dash (2 10 0)) (f (0 17 2))) "Modify environment according to files in a specified directory" single ((:commit . "f29346c55ccf11d8c75628edc6d430ed63c36917") (:authors ("Artem Malyshev" . "proofit404@gmail.com")) (:maintainer "Artem Malyshev" . "proofit404@gmail.com") (:url . "https://github.com/proofit404/envdir-mode"))]) (ensime . [(20180615 1330) ((scala-mode (0 23)) (sbt-mode (0 2)) (yasnippet (0 10 0)) (company (0 9 0)) (dash (2 12 1)) (s (1 11 0)) (popup (0 5 3))) "ENhanced Scala Interaction Mode for Emacs" tar ((:commit . "34eb11dac3ec9d1c554c2e55bf056ece6983add7") (:keywords "languages") (:url . "https://github.com/ensime/ensime-emacs"))]) (enotify . [(20130407 1348) nil "A networked notification system for emacs" tar ((:commit . "7fd2f48ef4ff32c8f013c634ea2dd6b1d1409f80"))]) (eno . [(20160110 1034) ((dash (2 12 1)) (edit-at-point (1 0))) "Goto/copy/cut any word/symbol/line in view, similar to ace-jump/easymotion" single ((:commit . "40075bb1ed9e62f42c5799f3d3721734742ed417") (:authors (nil . "<e.enoson@gmail.com>")) (:maintainer nil . "<e.enoson@gmail.com>") (:url . "http://github.com/enoson/eno.el"))]) (enlive . [(20170725 1417) nil "query html document with css selectors" single ((:commit . "604a8ca272b6889f114e2b5a13adb5b1dc4bae86") (:keywords "css" "selector" "query") (:authors ("ZHOU Feng" . "zf.pascal@gmail.com")) (:maintainer "ZHOU Feng" . "zf.pascal@gmail.com") (:url . "http://github.com/zweifisch/enlive"))]) (enh-ruby-mode . [(20180730 2309) ((emacs (24))) "Major mode for editing Ruby files" tar ((:commit . "09e1ed06c1cf323e3b4d45cd86353087e6a12fde") (:keywords "languages" "elisp" "ruby") (:authors ("Geoff Jacobsen")) (:maintainer "Geoff Jacobsen") (:url . "http://github.com/zenspider/Enhanced-Ruby-Mode"))]) (engine-mode . [(20180401 1646) ((cl-lib (0 5))) "Define and query search engines from within Emacs." single ((:commit . "fd5a235b2c93b95143d676e6b654e388d7cdd956") (:authors ("Harry R. Schwartz" . "hello@harryrschwartz.com")) (:maintainer "Harry R. Schwartz" . "hello@harryrschwartz.com") (:url . "https://github.com/hrs/engine-mode"))]) (encourage-mode . [(20151128 905) ((emacs (24 4))) "Encourages you in your work. :D" single ((:commit . "99edacf2d94d168d3da0609860dc7253db7c9815") (:keywords "fun") (:authors ("Patrick Mosby" . "patrick@schreiblogade.de")) (:maintainer "Patrick Mosby" . "patrick@schreiblogade.de") (:url . "https://github.com/halbtuerke/encourage-mode.el"))]) (enclose . [(20121008 1614) nil "Enclose cursor within punctuation pairs." tar ((:commit . "2747653e84af39017f503064bc66ed1812a77259"))]) (emr . [(20180815 2320) ((s (1 3 1)) (dash (1 2 0)) (cl-lib (0 2)) (popup (0 5 0)) (emacs (24 1)) (list-utils (0 3 0)) (paredit (24 0 0)) (projectile (0 9 1)) (clang-format (0)) (iedit (0 97))) "Emacs refactoring system." tar ((:commit . "d7bb2bb54c50ed79030278e2243c20c22359388a") (:keywords "tools" "convenience" "refactoring") (:authors ("Chris Barrett" . "chris.d.barrett@me.com")) (:maintainer "Chris Barrett" . "chris.d.barrett@me.com"))]) (empos . [(20151011 1916) nil "Locate bibtex citations from within emacs" single ((:commit . "7b99ad30e56937adb7e6349777e5a2045597d564") (:keywords "citations" "reference" "bibtex" "reftex") (:authors ("Dimitris Alikaniotis <da352 [at] cam.ac.uk>")) (:maintainer "Dimitris Alikaniotis <da352 [at] cam.ac.uk>") (:url . "http://github.com/dimalik/empos/"))]) (emojify-logos . [(20180814 917) ((emojify (0 4))) "Add logos to emojify" tar ((:commit . "a3e78bcbdf863092d4c9b026ac08bf7d1c7c0e8b") (:authors ("mxgoldstein" . "m_goldstein@gmx.net")) (:maintainer "mxgoldstein" . "m_goldstein@gmx.net") (:url . "https://github.com/mxgoldstein/emojify-logos"))]) (emojify . [(20180611 1538) ((seq (1 11)) (ht (2 0)) (emacs (24 3))) "Display emojis in Emacs" tar ((:commit . "38ae28d95b58e9fb86a3495a2dda3e5de254c4fc") (:keywords "multimedia" "convenience") (:authors ("Iqbal Ansari" . "iqbalansari02@yahoo.com")) (:maintainer "Iqbal Ansari" . "iqbalansari02@yahoo.com") (:url . "https://github.com/iqbalansari/emacs-emojify"))]) (emoji-recall . [(20160723 2208) ((emacs (24))) "How many emoji can you recall from memory?" tar ((:commit . "d9122f8fb1467309260109a1985cd14f18fdf631") (:keywords "game") (:authors ("DarkSun" . "lujun9972@gmail.com")) (:maintainer "DarkSun" . "lujun9972@gmail.com") (:url . "https://github.com/lujun9972/emoji-recall.el"))]) (emoji-fontset . [(20160726 1924) nil "Set font face for Emoji." single ((:commit . "10be897fa5165fd40fd35a89e38c759e008fa775") (:keywords "emoji" "font" "config") (:authors ("USAMI Kenta" . "tadsan@zonu.me")) (:maintainer "USAMI Kenta" . "tadsan@zonu.me"))]) (emoji-display . [(20140117 1013) nil "emoji displaying module" single ((:commit . "bb4217f6400151a9cfa6d4524b8427f01feb5193") (:keywords "emoji") (:authors ("Kazuhiro Ito" . "kzhr@d1.dion.ne.jp")) (:maintainer "Kazuhiro Ito" . "kzhr@d1.dion.ne.jp") (:url . "https://github.com/ikazuhiro/emoji-display"))]) (emoji-cheat-sheet-plus . [(20150617 1331) ((emacs (24)) (helm (1 6 4))) "emoji-cheat-sheet for emacs" tar ((:commit . "96a003127d646a2683d81ca906a17eace0a6413e") (:keywords "emacs" "emoji") (:authors ("Sylvain Benner (based on the work of Shingo Fukuyama)")) (:maintainer "Sylvain Benner (based on the work of Shingo Fukuyama)") (:url . "https://github.com/syl20bnr/emacs-emoji-cheat-sheet-plus"))]) (emms-state . [(20160504 805) ((emms (0))) "Display track description and playing time in the mode line" single ((:commit . "77930300222333b71eafd495cc1fee3a3585eb23") (:keywords "emms") (:authors ("Alex Kost" . "alezost@gmail.com")) (:maintainer "Alex Kost" . "alezost@gmail.com") (:url . "https://github.com/alezost/emms-state.el"))]) (emms-soundcloud . [(20131221 1145) ((emms (20131016)) (json (1 2))) "EMMS source for Soundcloud audio sharing platform" single ((:commit . "87e5cbf9609d1f26c24dc834fdeb78b33d453c2b") (:keywords "emms" "soundcloud") (:authors ("Ozan Sener" . "ozan@ozansener.com")) (:maintainer "Ozan Sener" . "ozan@ozansener.com") (:url . "http://github.com/osener/emms-soundcloud"))]) (emms-player-simple-mpv . [(20180316 1549) ((emacs (24)) (cl-lib (0 5)) (emms (4 0))) "An extension of emms-player-simple.el for mpv JSON IPC" tar ((:commit . "101d120ccdee1c2c213fd2f0423c858b21649c00") (:keywords "emms" "mpv") (:authors ("momomo5717")) (:maintainer "momomo5717") (:url . "https://github.com/momomo5717/emms-player-simple-mpv"))]) (emms-player-mpv-jp-radios . [(20180325 1117) ((emacs (24)) (cl-lib (0 5)) (emms (4 0)) (emms-player-simple-mpv (0 1 7))) "EMMS players and stream lists of Japan radio stations" tar ((:commit . "f6b37f5878c741124d5fca43c5b80af873541edd") (:keywords "emms" "mpv" "radio") (:url . "https://github.com/momomo5717/emms-player-mpv-jp-radios"))]) (emms-player-mpv . [(20180503 2127) ((emms (0))) "mpv support for EMMS" single ((:commit . "9c9ffc6f00a737a6db6377681a88e5292ebcf86b") (:keywords "multimedia" "emms" "mpv") (:url . "https://github.com/dochang/emms-player-mpv/"))]) (emms-mode-line-cycle . [(20160221 1120) ((emacs (24)) (emms (4 0))) "Display the emms mode line as a ticker" single ((:commit . "2c2f395e484a1d345050ddd61ff5fab71a92a6bc") (:keywords "emms" "mode-line") (:authors ("momomo5717")) (:maintainer "momomo5717") (:url . "https://github.com/momomo5717/emms-mode-line-cycle"))]) (emms-mark-ext . [(20130529 327) ((emms (3 0))) "Extra functions for emms-mark-mode and emms-tag-edit-mode" single ((:commit . "ec68129e3e9e469e5bf160c6a1b7030e322f3541") (:keywords "convenience" "multimedia") (:authors ("Joe Bloggs" . "vapniks@yahoo.com")) (:maintainer "Joe Bloggs" . "vapniks@yahoo.com") (:url . "https://github.com/vapniks/emms-mark-ext"))]) (emms-info-mediainfo . [(20131223 1300) ((emms (0))) "Info-method for EMMS using medianfo" single ((:commit . "bce16eae9eacd38719fea62a9755225a888da59d") (:keywords "multimedia" "processes") (:authors ("Fabián Ezequiel Gallina" . "fgallina@gnu.org")) (:maintainer "Fabián Ezequiel Gallina" . "fgallina@gnu.org"))]) (emms-bilibili . [(20180103 418) ((emacs (25)) (cl-lib (0 5))) "Play Bilibili in EMMS." single ((:commit . "294bca3dfc42fe3a55fb326ab39bc0fcfc8c5090") (:keywords "emms" "bilibili") (:url . "https://github.com/stardiviner/emms-bilibili"))]) (emms . [(20180827 831) ((cl-lib (0 5))) "The Emacs Multimedia System" tar ((:commit . "a43047f6a298632b875971aeb16bd529f0dfed33") (:keywords "emms" "mp3" "mpeg" "multimedia") (:authors ("Jorgen Schäfer" . "forcer@forcix.cx")) (:maintainer "Jorgen Schäfer" . "forcer@forcix.cx") (:url . "http://www.gnu.org/software/emms/"))]) (emmet-mode . [(20180613 341) nil "Unofficial Emmet's support for emacs" single ((:commit . "1acb821e0142136344ccf40c1e5fb664d7db2e70") (:keywords "convenience") (:authors ("Shin Aoyama" . "smihica@gmail.com")) (:maintainer "Shin Aoyama" . "smihica@gmail.com") (:url . "https://github.com/smihica/emmet-mode"))]) (emlib . [(20161126 1523) ((dash (2 13 0)) (cl-lib (0 5))) "A Machine Learning library for Emacs" tar ((:commit . "dea2af00f551ea580c641d86dd69219f7d4f3685") (:keywords "data" "ai" "neural networks" "ml") (:authors ("Narendra Joshi" . "narendraj9@gmail.com")) (:maintainer "Narendra Joshi" . "narendraj9@gmail.com") (:url . "https://github.com/narendraj9/emlib.git"))]) (embrace . [(20171031 1833) ((cl-lib (0 5)) (expand-region (0 10 0))) "Add/Change/Delete pairs based on `expand-region'" single ((:commit . "dd5da196e5bcc5e6d87e1937eca0c21da4334ef2") (:keywords "extensions") (:authors ("Junpeng Qiu" . "qjpchmail@gmail.com")) (:maintainer "Junpeng Qiu" . "qjpchmail@gmail.com"))]) (ember-yasnippets . [(20160526 1658) ((yasnippet (0 8 0))) "Snippets for Ember.js development" tar ((:commit . "3b5bd01569646237bf1b540d097e12f9118b67f4") (:keywords "tools" "abbrev" "languages") (:authors ("Ron White" . "ronco@costite.com")) (:maintainer "Ron White" . "ronco@costite.com"))]) (ember-mode . [(20180823 1006) ((cl-lib (0 5))) "Ember navigation mode for emacs" single ((:commit . "0f984f9ea709dfc3b13acae3a29956147ad4e2c2") (:keywords "ember" "ember.js" "emberjs") (:authors ("Aad Versteden" . "madnificent@gmail.com")) (:maintainer "Aad Versteden" . "madnificent@gmail.com"))]) (emaps . [(20180712 1916) nil "utilities for working with keymaps." single ((:commit . "823b8f72e6459c9f1a5dd62451ee4005ef71d955") (:keywords "convenience" "keyboard" "keymap" "utility") (:authors ("Ben Moon" . "software@guiltydolphin.com")) (:maintainer "Ben Moon" . "software@guiltydolphin.com") (:url . "https://github.com/GuiltyDolphin/emaps"))]) (emamux-ruby-test . [(20130812 1639) ((emamux (0 1)) (projectile (0 9 1))) "Ruby test with emamux" single ((:commit . "23b73c650573b340351a919da3da416acfc2ac84") (:url . "https://github.com/syohex/emamux-ruby-test"))]) (emamux . [(20170227 337) ((emacs (24 3))) "Interact with tmux" single ((:commit . "39f57786b2cdd3844888df42d71c7bd251f07158") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-emamux"))]) (emacsshot . [(20161018 1443) nil "Snapshot a frame or window from within Emacs" tar ((:commit . "11ace77ab718292d05b82d93178380aff591468b") (:keywords "convenience") (:authors ("Marco Wahl" . "marcowahlsoft@gmail.com")) (:maintainer "Marco Wahl") (:url . "https://github.com/marcowahl/emacsshot"))]) (emacsql-sqlite . [(20180128 2052) ((emacs (25 1)) (emacsql (2 0 0))) "EmacSQL back-end for SQLite" tar ((:commit . "6f1e375a2ebb558138b73d2a63f2077da1028f92") (:authors ("Christopher Wellons" . "wellons@nullprogram.com")) (:maintainer "Christopher Wellons" . "wellons@nullprogram.com") (:url . "https://github.com/skeeto/emacsql"))]) (emacsql-psql . [(20171219 227) ((emacs (25 1)) (emacsql (2 0 0))) "EmacSQL back-end for PostgreSQL via psql" tar ((:commit . "6f1e375a2ebb558138b73d2a63f2077da1028f92") (:authors ("Christopher Wellons" . "wellons@nullprogram.com")) (:maintainer "Christopher Wellons" . "wellons@nullprogram.com") (:url . "https://github.com/skeeto/emacsql"))]) (emacsql-mysql . [(20171219 227) ((emacs (25 1)) (emacsql (2 0 0))) "EmacSQL back-end for MySQL" single ((:commit . "6f1e375a2ebb558138b73d2a63f2077da1028f92") (:authors ("Christopher Wellons" . "wellons@nullprogram.com")) (:maintainer "Christopher Wellons" . "wellons@nullprogram.com") (:url . "https://github.com/skeeto/emacsql"))]) (emacsql . [(20180712 1752) ((emacs (25 1))) "high-level SQL database front-end" tar ((:commit . "6f1e375a2ebb558138b73d2a63f2077da1028f92") (:authors ("Christopher Wellons" . "wellons@nullprogram.com")) (:maintainer "Christopher Wellons" . "wellons@nullprogram.com") (:url . "https://github.com/skeeto/emacsql"))]) (emacsist-view . [(20160426 1223) nil "Mode for viewing emacsist.com" single ((:commit . "f67761259ed779a9bc95c9a4e0474522990c5c6b") (:keywords "convenience" "usability") (:authors ("DarkSun" . "lujun9972@gmail.com")) (:maintainer "DarkSun" . "lujun9972@gmail.com") (:url . "https://github.com/lujun9972/emacsist-view"))]) (emacsc . [(20161028 1706) nil "helper for emacsc(1)" tar ((:commit . "421e0c567358769e32f670ae8e949d99abae0c28") (:keywords "tools") (:authors ("Akinori MUSHA" . "knu@iDaemons.org")) (:maintainer "Akinori MUSHA" . "knu@iDaemons.org") (:url . "https://github.com/knu/emacsc"))]) (emacsagist . [(20140331 1830) ((cl-lib (0 5))) "Search Packagist.org packages without leaving Emacs" single ((:commit . "aba342ba59c254a88017f25e9fb7a8cd6f2fda83") (:keywords "tools") (:authors ("Brian Zwahr" . "echosa@icloud.com")) (:maintainer "Brian Zwahr" . "echosa@icloud.com") (:url . "http://github.com/echosa/emacsagist"))]) (emacs-setup . [(20120727 1426) nil "Package for maintaining your emacs configuration. Clean up your .emacs!" tar ((:commit . "c783ec13e3b39093fffb6f6d64dccdce8ce4d375"))]) (elx . [(20180830 1414) ((emacs (26))) "extract information from Emacs Lisp libraries" single ((:commit . "3b4d5ac1ba46a515f29e4803eaa23d879cf017ce") (:keywords "docs" "libraries" "packages") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:url . "https://github.com/emacscollective/elx"))]) (elwm . [(20150817 1007) ((dash (1 1 0))) "Minimalistic window manager for emacs" single ((:commit . "c33b183f006ad476c3a44dab316f580f8b369930") (:keywords "docs") (:authors ("Matus Goljer" . "matus.goljer@gmail.com")) (:maintainer "Matus Goljer" . "matus.goljer@gmail.com") (:url . "https://github.com/Fuco1/elwm"))]) (elvish-mode . [(20180809 1612) ((emacs (24 3))) "Defines a major mode for Elvish" single ((:commit . "c3a7e31564256b9755b1ab9fb40d32ad78cd1ad2") (:authors ("Adam Schwalm" . "adamschwalm@gmail.com")) (:maintainer "Adam Schwalm" . "adamschwalm@gmail.com") (:url . "https://github.com/ALSchwalm/elvish-mode"))]) (elscreen-separate-buffer-list . [(20161107 358) ((emacs (24 4)) (elscreen (1 4 6))) "Separate buffer list manager for elscreen" single ((:commit . "7652d827aa1b8c1b04303c5b4b0bda5e8f85565e") (:keywords "elscreen") (:authors ("wamei" . "wamei.cho@gmail.com")) (:maintainer "wamei" . "wamei.cho@gmail.com"))]) (elscreen-multi-term . [(20151022 233) ((emacs (24 4)) (elscreen (1 4 6)) (multi-term (1 3))) "Multi term for elscreen" single ((:commit . "7b6048a0dd80f69460a62bbc6f1af8856141a5ea") (:keywords "elscreen" "multi term") (:authors ("wamei" . "wamei.cho@gmail.com")) (:maintainer "wamei" . "wamei.cho@gmail.com"))]) (elscreen-mew . [(20160504 1835) ((elscreen (20120413 807))) "ElScreen Add-On for Mew" single ((:commit . "c90a23441d836da14a1cb12788432308ba58e2b6") (:authors ("Takashi Masuda" . "masutaka.net@gmail.com")) (:maintainer "Takashi Masuda" . "masutaka.net@gmail.com") (:url . "https://github.com/masutaka/elscreen-mew"))]) (elscreen-fr . [(20160920 953) ((elscreen (0)) (seq (1 11))) "Use frame title as screen tab" single ((:commit . "b9c11f80d277086d5d5bf88623e15fc7adbbbe3c") (:authors ("Francesc Rocher" . "francesc.rocher@gmail.com")) (:maintainer "Francesc Rocher" . "francesc.rocher@gmail.com") (:url . "http://github.com/rocher/elscreen-fr"))]) (elscreen-buffer-group . [(20170809 125) ((emacs (24 4)) (elscreen (0)) (cl-lib (0 5))) "elscreen buffer group" single ((:commit . "a3cd4d7eae3cca87bede4b39a46d3c0641f8cd06") (:keywords "buffer") (:authors ("Jeff Gran" . "jeff@jeffgran.com") ("Author: Ryan C. Thompson")) (:maintainer "Jeff Gran" . "jeff@jeffgran.com") (:url . "https://github.com/jeffgran/elscreen-buffer-group"))]) (elscreen . [(20180321 202) ((emacs (24))) "Emacs window session manager" tar ((:commit . "02164afab2c5fbff6e4aa7c59e0daedc6c504772") (:keywords "window" "convenience") (:authors ("Naoto Morishima" . "naoto@morishima.net")) (:maintainer "Akinori MUSHA" . "knu@iDaemons.org") (:url . "https://github.com/knu/elscreen"))]) (elquery . [(20180514 212) ((emacs (25 1)) (s (1 11 0)) (dash (2 13 0))) "The HTML library for elisp." single ((:commit . "a0d135e3230fc56fc88d790bbc3d87f53de5741e") (:keywords "html" "hypermedia" "tools" "webscale") (:authors ("Adam Niederer")) (:maintainer "Adam Niederer") (:url . "https://github.com/AdamNiederer/elquery"))]) (elpygen . [(20171225 1736) ((emacs (25)) (yasnippet (0 8 0))) "Generate a Python function/method using a symbol under point" single ((:commit . "21929c997a05968f9eefe52b85a76ceaab3b0d81") (:keywords "python" "languages" "tools") (:authors ("Vladimir Kazanov" . "vkazanov@inbox.ru")) (:maintainer "Vladimir Kazanov" . "vkazanov@inbox.ru") (:url . "https://github.com/vkazanov/elpygen"))]) (elpy . [(20180831 846) ((company (0 9 2)) (emacs (24 4)) (find-file-in-project (3 3)) (highlight-indentation (0 5 0)) (pyvenv (1 3)) (yasnippet (0 8 0)) (s (1 11 0))) "Emacs Python Development Environment" tar ((:commit . "875b46add2569abe18129bae7a5992cc674e7e3f"))]) (elpa-mirror . [(20180301 36) ((emacs (24 4))) "Create local package repository so package upgrade never breaks" single ((:commit . "6ca78e3fb69ef582da1a01f1d193e07ae8223142") (:keywords "cloud" "mirror" "elpa") (:authors ("Chen Bin" . "chenbin.sh@gmail.com")) (:maintainer "Chen Bin" . "chenbin.sh@gmail.com") (:url . "http://github.com/redguardtoo/elpa-mirror"))]) (elpa-clone . [(20170502 1214) ((emacs (24 4)) (cl-lib (0))) "Clone ELPA archive" single ((:commit . "92f4c9d3570ad002575a90d0cc4a522c203a1110") (:keywords "comm" "elpa" "clone" "mirror") (:authors ("ZHANG Weiyi" . "dochang@gmail.com")) (:maintainer "ZHANG Weiyi" . "dochang@gmail.com") (:url . "https://github.com/dochang/elpa-clone"))]) (elpa-audit . [(20141023 1331) nil "Handy functions for inspecting and comparing package archives" single ((:commit . "727da50e626977351aff2675b6540a36818bbbe6") (:keywords "maint") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:url . "https://github.com/purcell/elpa-audit"))]) (eloud . [(20160731 1557) ((emacs (24 4))) "A lightweight, interactive screen reader" single ((:commit . "82c97918585bd2a749251ae87d7732ca9d856c16") (:keywords "extensions") (:authors ("Patrick Smyth" . "patricksmyth01@gmail.com")) (:maintainer "Patrick Smyth" . "patricksmyth01@gmail.com") (:url . "https://github.com/smythp/eloud"))]) (elogcat . [(20151121 41) ((s (1 9 0)) (dash (2 10 0))) "logcat interface" single ((:commit . "4f311b7a07565b0d060334bc68edb36f2bff703f") (:keywords "tools") (:authors ("Youngjoo Lee" . "youngker@gmail.com")) (:maintainer "Youngjoo Lee" . "youngker@gmail.com"))]) (elog . [(20160724 2255) ((eieio (1 3))) "logging library extended from logito" single ((:commit . "a67237d9813c7591614d95e2ef31cc5e5ed3f31b") (:keywords "lisp" "tool" "log") (:authors ("DarkSun" . "lujun9972@gmail.com")) (:maintainer "DarkSun" . "lujun9972@gmail.com"))]) (elnode . [(20140203 2306) ((web (0 1 4)) (dash (1 1 0)) (noflet (0 0 7)) (s (1 5 0)) (creole (0 8 14)) (fakir (0 1 6)) (db (0 0 5)) (kv (0 0 17))) "The Emacs webserver." tar ((:commit . "3f2bf225853e40a2a10386ee5ae0bd6ba5d44ce9"))]) (elmine . [(20170511 720) ((s (1 10 0))) "Redmine API access via elisp." single ((:commit . "432d2f2f7cb5b533f25b993d1001abcadcebe8ed") (:keywords "tools") (:authors ("Arthur Andersen" . "leoc.git@gmail.com")) (:maintainer "Arthur Andersen" . "leoc.git@gmail.com") (:url . "http://github.com/leoc/elmine"))]) (elmacro . [(20180628 1411) ((s (1 11 0)) (dash (2 13 0))) "Convert keyboard macros to emacs lisp" single ((:commit . "89b9b0feabafd01fee48111d67131c4c9b5fed9a") (:keywords "macro" "elisp" "convenience") (:authors ("Philippe Vaucher" . "philippe.vaucher@gmail.com")) (:maintainer "Philippe Vaucher" . "philippe.vaucher@gmail.com") (:url . "https://github.com/Silex/elmacro"))]) (elm-yasnippets . [(20160401 524) ((yasnippet (0 8 0))) "Yasnippets for Elm" tar ((:commit . "45a11a0cef0c36633fb3477d3dc4167e82779ba4") (:keywords "snippets") (:authors ("Austin Bingham" . "austin.bingham@gmail.com")) (:maintainer "Austin Bingham" . "austin.bingham@gmail.com"))]) (elm-test-runner . [(20180830 1312) ((emacs (24 4))) "Enhanced support for running elm-test" single ((:commit . "730ad5f247d09cbf1ceefdae72a898b1759ca0c9") (:authors ("Juan Edi")) (:maintainer "Juan Edi") (:url . "https://github.com/juanedi/elm-test-runner"))]) (elm-mode . [(20180828 2227) ((f (0 17)) (let-alist (1 0 4)) (seq (2 2)) (s (1 7 0)) (emacs (24 4)) (dash (2 13 0))) "Major mode for Elm" tar ((:commit . "5167d3fd8a32d384d999655dbed6870352b65673") (:authors ("Joseph Collard")) (:maintainer "Joseph Collard") (:url . "https://github.com/jcollard/elm-mode"))]) (elixir-yasnippets . [(20150417 1239) ((yasnippet (0 8 0))) "Yasnippets for Elixir" tar ((:commit . "980ca7626c14ef0573bec0035ec7942796062783"))]) (elixir-mode . [(20180711 1245) ((emacs (24)) (pkg-info (0 4))) "Major mode for editing Elixir files" tar ((:commit . "90323cd7669eb472ee1f97b9d070056ebe225d15") (:keywords "languages" "elixir") (:url . "https://github.com/elixir-lang/emacs-elixir"))]) (elisp-slime-nav . [(20160128 1909) ((cl-lib (0 2))) "Make M-. and M-, work in elisp like they do in slime" single ((:commit . "34938422929800839e2f935aca890cd4a229ca99") (:keywords "navigation" "slime" "elisp" "emacs-lisp") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:url . "https://github.com/purcell/elisp-slime-nav"))]) (elisp-sandbox . [(20131116 1842) nil "Evaluate EmacsLisp expressions in a sandbox" single ((:commit . "d894d68934ef09c42f72ac4e1173a0bedc23f139") (:keywords "lisp") (:authors ("Joel McCracken <mccracken.joel@gmail.com>, D. Goel" . "deego@gnufans.org")) (:maintainer "Joel McCracken <mccracken.joel@gmail.com>, D. Goel" . "deego@gnufans.org") (:url . "https://github.com/joelmccracken/elisp-sandbox"))]) (elisp-refs . [(20180715 2302) ((dash (2 12 0)) (loop (1 2)) (s (1 11 0))) "find callers of elisp functions or macros" single ((:commit . "7faa17293b8fc9e4b5c98a0dbe53bf3c2705a3f2") (:keywords "lisp") (:authors ("Wilfred Hughes" . "me@wilfred.me.uk")) (:maintainer "Wilfred Hughes" . "me@wilfred.me.uk"))]) (elisp-lint . [(20180224 2042) ((emacs (24))) "basic linting for Emacs Lisp" single ((:commit . "04b0d36ec0e4dc1bb54c2bf4c2d16b2af8cf6a39") (:keywords "lisp" "maint" "tools") (:authors ("Nikolaj Schumacher <bugs * nschum de>,")) (:maintainer "Nikolaj Schumacher <bugs * nschum de>,") (:url . "http://github.com/gonewest818/elisp-lint/"))]) (elisp-format . [(20160508 952) nil "Format elisp code" single ((:commit . "03cc293eb2f78ec58fc1d84279af06816a04b979") (:authors (nil . "Andy Stewart lazycat.manatee@gmail.com")) (:maintainer "Yuki Inoue inouetakahiroki _at_ gmail.com") (:url . "https://github.com/Yuki-Inoue/elisp-format"))]) (elisp-docstring-mode . [(20170304 1615) nil "Major mode for editing elisp docstrings." single ((:commit . "f512e509dd690f65133e55563ebbfd2dede5034f") (:keywords "languages") (:authors ("Matúš Goljer" . "matus.goljer@gmail.com")) (:maintainer "Matúš Goljer" . "matus.goljer@gmail.com"))]) (elisp-depend . [(20161230 1550) nil "Parse depend libraries of elisp file." single ((:commit . "e4b201ac7dcee4489d58800c299fd04aaa61d07a"))]) (elisp-def . [(20180806 723) ((dash (2 12 0)) (f (0 19 0)) (s (1 11 0)) (emacs (24 3))) "macro-aware go-to-definition for elisp" single ((:commit . "368b04da68783601b52e3169312183381871cf9e") (:keywords "lisp") (:authors ("Wilfred Hughes" . "me@wilfred.me.uk")) (:maintainer "Wilfred Hughes" . "me@wilfred.me.uk"))]) (elhome . [(20161025 2042) ((initsplit (20120630))) "A framework for a \"home\" Emacs configuration" tar ((:commit . "e789e806469af3e9705f72298683c21f6c3a516d") (:keywords "lisp") (:authors ("Dave Abrahams" . "dave@boostpro.com")) (:maintainer "Demyan Rogozhin" . "demyan.rogozhin@gmail.com") (:url . "http://github.com/demyanrogozhin/elhome"))]) (elgrep . [(20180302 1327) ((emacs (25 1))) "Searching files for regular expressions" single ((:commit . "5e982024250e75fe02aee358a542ae3ed2a472d5") (:keywords "tools" "matching" "files" "unix") (:authors ("Tobias Zawada" . "naehring@smtp.1und1.de")) (:maintainer "Tobias Zawada" . "naehring@smtp.1und1.de") (:url . "https://github.com/TobiasZawada/elgrep"))]) (elfeed-web . [(20180829 1716) ((simple-httpd (1 4 3)) (elfeed (1 4 0)) (emacs (24 1))) "web interface to Elfeed" tar ((:commit . "3d1c6ecbe585f9fe6ca5a97a3fc352d68f303f9e"))]) (elfeed-protocol . [(20180728 907) ((emacs (24 4)) (elfeed (2 1 1)) (cl-lib (0 5))) "Provide owncloud/ttrss protocols for elfeed" tar ((:commit . "67b4e6e6341a4738cdd56b07778daadae33eabdd") (:keywords "news") (:authors ("Xu Fasheng" . "fasheng.xu@gmail.com")) (:maintainer "Xu Fasheng" . "fasheng.xu@gmail.com") (:url . "https://github.com/fasheng/elfeed-protocol"))]) (elfeed-org . [(20180129 1307) ((elfeed (1 1 1)) (org (8 2 7)) (dash (2 10 0)) (s (1 9 0)) (cl-lib (0 5))) "Configure elfeed with one or more org-mode files" single ((:commit . "b9d09a554127244d4807a3d2d90e062df63b2fd5") (:keywords "news") (:authors ("Remy Honig" . "remyhonig@gmail.com")) (:maintainer "Remy Honig" . "remyhonig@gmail.com") (:url . "https://github.com/remyhonig/elfeed-org"))]) (elfeed-goodies . [(20171127 651) ((popwin (1 0 0)) (powerline (2 2)) (elfeed (2 0 0)) (cl-lib (0 5)) (noflet (0 0 10)) (ace-jump-mode (2 0))) "Elfeed goodies" tar ((:commit . "fc0c3e72f9fcd7bbf5237f6f2323bc666e8240b4") (:authors ("Gergely Nagy")) (:maintainer "Gergely Nagy") (:url . "https://github.com/algernon/elfeed-goodies"))]) (elfeed . [(20180829 1716) ((emacs (24 3))) "an Emacs Atom/RSS feed reader" tar ((:commit . "3d1c6ecbe585f9fe6ca5a97a3fc352d68f303f9e"))]) (elf-mode . [(20161009 748) ((emacs (24 3))) "Show symbols in binaries" single ((:commit . "cd280d683cd3341d8bb31af6db7e3b74a133e6ab") (:keywords "matching") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:url . "https://github.com/abo-abo/elf-mode"))]) (elein . [(20120120 1116) nil "running leiningen commands from emacs" single ((:commit . "d4c0c0491dbb7c90e953d7a16172107c37103605") (:keywords "tools" "processes") (:authors ("R.W. van 't Veer")) (:maintainer "R.W. van 't Veer") (:url . "https://github.com/remvee/elein"))]) (electric-spacing . [(20161209 1957) nil "Insert operators with surrounding spaces smartly" single ((:commit . "9d0f8a213133f2619a4e9dfbba3b00d4348c07b0") (:authors ("William Xu" . "william.xwl@gmail.com")) (:maintainer "William Xu" . "william.xwl@gmail.com"))]) (electric-operator . [(20180831 1746) ((dash (2 10 0)) (emacs (24 4))) "Automatically add spaces around operators" tar ((:commit . "343b28966f1d39c47d31643631708454d7843c02") (:keywords "electric") (:authors ("David Shepherd" . "davidshepherd7@gmail.com")) (:maintainer "David Shepherd" . "davidshepherd7@gmail.com") (:url . "https://github.com/davidshepherd7/electric-operator"))]) (electric-case . [(20150417 1112) nil "insert camelCase, snake_case words without \"Shift\"ing" single ((:commit . "bac64e772107e3dc721a9819f63b9ebdc28a81f7") (:authors ("zk_phi")) (:maintainer "zk_phi") (:url . "http://hins11.yu-yake.com/"))]) (eldoc-overlay . [(20171219 940) ((emacs (24 3)) (inline-docs (1 0 1)) (quick-peek (1 0))) "Display eldoc with contextual documentation overlay." single ((:commit . "a391396f4cdf30a2f27a4c426b58b44ab3d0f0d0") (:keywords "documentation" "eldoc" "overlay") (:authors ("stardiviner" . "numbchild@gmail.com")) (:maintainer "stardiviner" . "numbchild@gmail.com") (:url . "https://github.com/stardiviner/eldoc-overlay"))]) (eldoc-eval . [(20180607 1157) nil "Enable eldoc support when minibuffer is in use." single ((:commit . "f59a1ae7ecfa97ef659c7adb93e0673419acc485") (:authors ("Thierry Volpiatto" . "thierry.volpiatto@gmail.com")) (:maintainer "Thierry Volpiatto" . "thierry.volpiatto@gmail.com"))]) (elcouch . [(20180529 757) ((emacs (25 1)) (json-mode (1 0 0)) (libelcouch (0 7 0))) "View and manipulate CouchDB databases" single ((:commit . "608fe254a7ee69c43c69b905ef708189dc3e3192") (:keywords "data" "tools") (:authors ("Damien Cassou" . "damien@cassou.me")) (:maintainer "Damien Cassou" . "damien@cassou.me") (:url . "https://gitlab.petton.fr/DamienCassou/elcouch"))]) (elcord . [(20180411 1907) ((emacs (25))) "Allows you to integrate Rich Presence from Discord" tar ((:commit . "0cef4ca13b00d79507292d5591be8ffb7df5a9ca") (:keywords "games") (:authors ("heatingdevice") ("Wilfredo Velázquez-Rodríguez" . "zulu.inuoe@gmail.com")) (:maintainer "heatingdevice") (:url . "https://github.com/Mstrodl/elcord"))]) (elcontext . [(20180526 1304) ((ht (2 3)) (hydra (0 14 0)) (emacs (24 3)) (f (0 20 0)) (osx-location (0 4)) (uuidgen (0 3))) "Create context specific actions" tar ((:commit . "f434ffc655e6349a4dd52285ff68a9194bcfc949") (:keywords "calendar" "convenience") (:authors ("Thomas Sojka")) (:maintainer "Thomas Sojka") (:url . "https://github.com/rollacaster/elcontext"))]) (elbank . [(20180316 1343) ((emacs (25)) (seq (2 16))) "Personal finances reporting application" tar ((:commit . "fa9bc7dec0a8fd489e90b9f178719344cc8d315a") (:keywords "tools" "personal-finances") (:authors ("Nicolas Petton" . "nicolas@petton.fr")) (:maintainer "Nicolas Petton" . "nicolas@petton.fr"))]) (el2org . [(20180311 1555) ((emacs (25 1))) "Convert elisp file to org file" single ((:commit . "81f1c97db8911f5bdf92c729630ab509de4ec73f") (:keywords "convenience") (:authors ("Feng Shu  <tumashu AT 163.com>")) (:maintainer "Feng Shu  <tumashu AT 163.com>") (:url . "https://github.com/tumashu/el2org"))]) (el2markdown . [(20170630 1858) nil "Convert commentary section of elisp files to markdown." single ((:commit . "368d99313683cd943c99feaffca356be60bdb636") (:authors ("Anders Lindgren")) (:maintainer "Anders Lindgren") (:url . "https://github.com/Lindydancer/el2markdown"))]) (el-x . [(20140111 2201) nil "main entry point for el-x package" tar ((:commit . "e7c333d4fc31a90f4dca951efe21129164b42605") (:keywords "lisp") (:authors ("Yann Hodique" . "yann.hodique@gmail.com")) (:maintainer "Yann Hodique" . "yann.hodique@gmail.com"))]) (el-spy . [(20131226 2008) nil "Mocking framework for Emacs lisp. It also support spy, proxy." single ((:commit . "b1dead9d1877660856ada22d906ac4e54695aec7") (:keywords "test") (:authors ("Yuuki Arisawa" . "yuuki.ari@gmail.com")) (:maintainer "Yuuki Arisawa" . "yuuki.ari@gmail.com") (:url . "https://github.com/uk-ar/el-spy"))]) (el-sprunge . [(20140107 139) ((web-server (20140105 2246)) (htmlize (20130207 1202)) (emacs (24 3))) "Command line paste server with Emacs highlighting" tar ((:commit . "37855ec60aeb4d565c49a4d711edc7341e9a22cb"))]) (el-spice . [(20180128 1721) nil "Extra spice for emacs lisp programming" tar ((:commit . "4e0852ebf5d8e9cbb3eaaa6ae9c53d126b53f58c") (:keywords "languages" "extensions") (:authors ("Vedang Manerikar" . "vedang.manerikar@gmail.com")) (:maintainer "Vedang Manerikar" . "vedang.manerikar@gmail.com") (:url . "https://github.com/vedang/el-spice"))]) (el-spec . [(20121018 704) nil "ruby's rspec like syntax test frame work" single ((:commit . "1dbc465401d4aea5560318c4f13ff30920a0718d") (:keywords "test") (:authors ("Yuuki Arisawa" . "yuuki.ari@gmail.com")) (:maintainer "Yuuki Arisawa" . "yuuki.ari@gmail.com") (:url . "https://github.com/uk-ar/el-spec"))]) (el-pocket . [(20170922 1249) ((web (0 5 2)) (emacs (24))) "Read and write to Pocket (getpocket.com)" single ((:commit . "a80abfb67efe68ada1d7d0a73aecee57e763baaa") (:keywords "emacs" "pocket" "bookmarks") (:authors ("Tod Davies" . "davies.t.o@gmail.com")) (:maintainer "Tod Davies" . "davies.t.o@gmail.com") (:url . "http://github.com/pterygota/el-pocket"))]) (el-patch . [(20180814 1937) ((emacs (25))) "Future-proof your Elisp." single ((:commit . "3f7534e0df31727f52e3caf82dd344fa70a3ec43") (:keywords "extensions") (:authors ("Radon Rosborough" . "radon.neon@gmail.com")) (:maintainer "Radon Rosborough" . "radon.neon@gmail.com") (:url . "https://github.com/raxod502/el-patch"))]) (el-mock . [(20170824 1954) nil "Tiny Mock and Stub framework in Emacs Lisp" single ((:commit . "5df1d3a956544f1d3ad0bcd81daf47fff33ab8cc") (:keywords "lisp" "testing" "unittest") (:authors ("rubikitch" . "rubikitch@ruby-lang.org")) (:maintainer "Johan Andersson" . "johan.rejeep@gmail.com") (:url . "http://github.com/rejeep/el-mock.el"))]) (el-init-viewer . [(20150303 828) ((emacs (24)) (cl-lib (0 5)) (ctable (0 1 2)) (dash (2 10 0)) (anaphora (1 0 0)) (el-init (0 1 4))) "Record viewer for el-init" single ((:commit . "dbcb4418fe342dfd7da805f2d7caf1def68db7f9") (:authors ("Hiroki YAMAKAWA" . "s06139@gmail.com")) (:maintainer "Hiroki YAMAKAWA" . "s06139@gmail.com") (:url . "https://github.com/HKey/el-init-viewer"))]) (el-init . [(20150728 920) ((emacs (24)) (cl-lib (0 5)) (anaphora (1 0 0))) "A loader inspired by init-loader" single ((:commit . "6b45551b8ed473c8a0c897b743b0378a3501556c") (:authors ("Hiroki YAMAKAWA" . "s06139@gmail.com")) (:maintainer "Hiroki YAMAKAWA" . "s06139@gmail.com") (:url . "https://github.com/HKey/el-init"))]) (el-get . [(20180611 121) nil "Manage the external elisp bits and pieces you depend upon" tar ((:commit . "87bb3f9481077f67d6520800b9ce5b8bf88fde5c") (:keywords "emacs" "package" "elisp" "install" "elpa" "git" "git-svn" "bzr" "cvs" "svn" "darcs" "hg" "apt-get" "fink" "pacman" "http" "http-tar" "emacswiki") (:authors ("Dimitri Fontaine" . "dim@tapoueh.org")) (:maintainer "Dimitri Fontaine" . "dim@tapoueh.org") (:url . "http://www.emacswiki.org/emacs/el-get"))]) (el-fly-indent-mode . [(20180422 243) ((emacs (25))) "Indent Emacs Lisp on the fly" single ((:commit . "4917f486a7be7482dedfea0a7ac3d01cab4ce21c") (:keywords "lisp" "languages") (:authors ("Jiahao Li" . "jiahaowork@gmail.com")) (:maintainer "Jiahao Li" . "jiahaowork@gmail.com") (:url . "https://github.com/jiahaowork/el-fly-indent-mode.el"))]) (el-autoyas . [(20120918 1317) nil "Automatically create Emacs-Lisp Yasnippets" tar ((:commit . "bde0251ecb504f585dfa27c205c8e312655310cc") (:keywords "emacs" "lisp" "mode" "yasnippet") (:authors ("Matthew L. Fidler")) (:maintainer "Matthew L. Fidler") (:url . "https://github.com/mlf176f2/el-autoyas.el"))]) (ejc-sql . [(20180827 1408) ((emacs (24 4)) (clomacs (0 0 3)) (dash (2 12 1)) (auto-complete (1 5 1)) (spinner (1 7 1)) (direx (1 0 0))) "Emacs SQL client uses Clojure JDBC." tar ((:commit . "af9a081911f63e91b3692b2947152ef788a14613") (:keywords "sql" "jdbc") (:authors ("Kostafey" . "kostafey@gmail.com")) (:maintainer "Kostafey" . "kostafey@gmail.com") (:url . "https://github.com/kostafey/ejc-sql"))]) (eink-theme . [(20170717 1507) nil "E Ink color theme" single ((:commit . "4c990bb3428f725735fa1f733ef4c5ad61f632b0") (:authors ("Marian Schubert" . "marian.schubert@gmail.com")) (:maintainer "Marian Schubert" . "marian.schubert@gmail.com") (:url . "http://github.com/maio/eink-emacs"))]) (ein-mumamo . [(20150302 28) ((ein (0 4))) "Multiple major mode support for Emacs IPython Notebook" single ((:commit . "028fefec499598add1a87b92ed991891f38f0c7b") (:authors ("Takafumi Arakaki <aka.tkf at gmail.com>") (": John Miller <millejoh at mac.com>")) (:maintainer "Takafumi Arakaki <aka.tkf at gmail.com>"))]) (ein . [(20180904 1447) ((websocket (1 7)) (auto-complete (1 4 0)) (request (0 3)) (deferred (0 5)) (request-deferred (0 2 0)) (cl-generic (0 3)) (dash (2 13 0)) (s (1 11 0)) (skewer-mode (1 6 2))) "Emacs IPython Notebook" tar ((:commit . "6cf17bfc9270569ba5b1d2052a7cc3b2df973c0c"))]) (eimp . [(20120826 2039) nil "Emacs Image Manipulation Package" single ((:commit . "2e7536fe6d8f7faf1bad7a8ae37faba0162c3b4f") (:keywords "files" "frames") (:authors ("Matthew P. Hodges" . "MPHodges@member.fsf.org")) (:maintainer "Nic Ferrier" . "nferrier@ferrier.me.uk"))]) (eide . [(20180626 1959) nil "IDE interface" tar ((:commit . "6bd4c3b67a532527b3514c72bf2d7371172b8a93"))]) (ego . [(20180301 104) ((emacs (24 5)) (ht (1 5)) (mustache (0 22)) (htmlize (1 47)) (org (8 0)) (dash (2 0 0)) (simple-httpd (1 4 5))) "a static site generator based on org mode, forked from org-page." tar ((:commit . "719809679c1a60887735db41abae53b61f08ef59"))]) (eglot . [(20180827 1317) ((emacs (26 1)) (jsonrpc (1 0 6))) "Client for Language Server Protocol (LSP) servers" single ((:commit . "f9beb19a687692069638e6a3336d16b779096eb4") (:keywords "convenience" "languages") (:authors ("João Távora" . "joaotavora@gmail.com")) (:maintainer "João Távora" . "joaotavora@gmail.com") (:url . "https://github.com/joaotavora/eglot"))]) (egison-mode . [(20160603 803) nil "Egison editing mode" single ((:commit . "8a2a376abc488f0c31605b2aa2fcc4700a065446") (:authors ("Satoshi Egi" . "egisatoshi@gmail.com")) (:maintainer "Satoshi Egi" . "egisatoshi@gmail.com") (:url . "https://github.com/egisatoshi/egison3/blob/master/elisp/egison-mode.el"))]) (egg . [(20180713 918) nil "Emacs Got Git - Emacs interface to Git" tar ((:commit . "5bf9879eec067e25a60f2363137c9e69f7b5cc68") (:keywords "git" "version control" "release management") (:authors ("Bogolisk" . "bogolisk@gmail.com")) (:maintainer "Bogolisk" . "bogolisk@gmail.com"))]) (eg . [(20170830 815) ((cl-lib (0 5)) (emacs (24 3))) "Norton Guide reader" single ((:commit . "1c7f1613d2aaae728ef540305f6ba030616f86bd") (:keywords "docs") (:authors ("Dave Pearson" . "davep@davep.org")) (:maintainer "Dave Pearson" . "davep@davep.org") (:url . "https://github.com/davep/eg.el"))]) (efire . [(20151009 2031) ((circe (1 2))) "Use campfire from Emacs" single ((:commit . "91a644662afb352475efad0b377713656f131e5c") (:keywords "convenience" "tools") (:authors ("João Távora" . "joaotavora@gmail.com")) (:maintainer "João Távora" . "joaotavora@gmail.com") (:url . "https://github.com/capitaomorte/efire"))]) (edts . [(20171030 709) ((auto-complete (1 3 1)) (auto-highlight-symbol (1 53)) (dash (2 13)) (erlang (2 4 1)) (f (0 19 0)) (popup (0 4)) (s (1 11 0))) "Erlang Development Tool Suite" tar ((:commit . "6ef4bdf571235ee1b078db321402270cabff7fda"))]) (edn . [(20160215 1219) ((cl-lib (0 3)) (emacs (24 1)) (peg (0 6))) "Support for reading and writing the edn data format from elisp" single ((:commit . "be9e32d1b49e35247b263b0243df7cfdc8d413ab") (:keywords "edn" "clojure") (:authors ("Lars Andersen" . "expez@expez.com")) (:maintainer "Lars Andersen" . "expez@expez.com") (:url . "https://www.github.com/expez/edn.el"))]) (editorconfig-domain-specific . [(20180505 924) ((cl-lib (0 5)) (editorconfig (0 6 0))) "Apply brace style and other \"domain-specific\" EditorConfig properties" single ((:commit . "e9824160fb2e466afa755240ee3ab7cc5657fb04") (:keywords "editorconfig" "util") (:authors ("Lassi Kortela" . "lassi@lassi.io")) (:maintainer "Lassi Kortela" . "lassi@lassi.io") (:url . "https://github.com/lassik/editorconfig-emacs-domain-specific"))]) (editorconfig-custom-majormode . [(20180816 244) ((editorconfig (0 6 0))) "Decide major-mode and mmm-mode from EditorConfig" single ((:commit . "13ad1c83f847bedd4b3a19f9df7fd925853b19de") (:keywords "editorconfig" "util") (:authors ("10sr <8slashes+el [at] gmail [dot] com>")) (:maintainer "10sr <8slashes+el [at] gmail [dot] com>") (:url . "https://github.com/10sr/editorconfig-custom-majormode-el"))]) (editorconfig-charset-extras . [(20180223 457) ((editorconfig (0 6 0))) "Extra EditorConfig Charset Support" single ((:commit . "ddf60923c6f4841cb593b2ea04c9c710a01d262f") (:keywords "tools") (:authors ("10sr" . "8.slashes@gmail.com")) (:maintainer "10sr" . "8.slashes@gmail.com") (:url . "https://github.com/10sr/editorconfig-charset-extras-el"))]) (editorconfig . [(20180904 212) ((cl-lib (0 5))) "EditorConfig Emacs Plugin" tar ((:commit . "24d65714fe6a934266b5c19aa82ab3215bdb710a") (:authors ("EditorConfig Team" . "editorconfig@googlegroups.com")) (:maintainer "EditorConfig Team" . "editorconfig@googlegroups.com") (:url . "https://github.com/editorconfig/editorconfig-emacs#readme"))]) (edit-server-htmlize . [(20130329 2248) ((edit-server (1 9))) "(de)HTMLization hooks for edit-server.el" single ((:commit . "e7f8dadfabe869c77ca241cd6fbd4c52bd908392") (:authors ("Roland McGrath" . "roland@hack.frob.com")) (:maintainer "Roland McGrath" . "roland@hack.frob.com") (:url . "https://github.com/frobtech/edit-server-htmlize"))]) (edit-server . [(20180120 1552) nil "server that responds to edit requests from Chrome" single ((:commit . "ac80a6e3340ad0340bc0655969320b0b100a2c0e") (:authors ("Alex Bennée" . "alex@bennee.com")) (:maintainer "Alex Bennée" . "alex@bennee.com") (:url . "https://github.com/stsquad/emacs_chrome"))]) (edit-list . [(20100930 1443) nil "edit a single list" single ((:commit . "f460d3f9e208a4e606fe6ded307f1b011916ca71") (:authors ("Michael Olson" . "mwolson@gnu.org")) (:maintainer "Michael Olson" . "mwolson@gnu.org") (:url . "http://mwolson.org/static/dist/elisp/edit-list.el"))]) (edit-indirect-region-latex . [(20161129 645) ((emacs (24 3)) (ht (2 2)) (edit-indirect (0 1 4))) "Edit LaTeX regions in separate buffers, e.g. for English grammar checks" single ((:commit . "05043f2c0c9838947d3ca4b51b695deb7c47612e") (:authors ("Hirotaka Niitsuma" . "hirotaka.niitsuma@gmail.com")) (:maintainer "Hirotaka Niitsuma" . "hirotaka.niitsuma@gmail.com") (:url . "https://github.com/niitsuma/edit-indirect-region-latex"))]) (edit-indirect . [(20180422 1807) ((emacs (24 3))) "Edit regions in separate buffers" single ((:commit . "de645d8144e8a08f039a9c88185121ec81d957ef") (:authors ("Fanael Linithien" . "fanael4@gmail.com")) (:maintainer "Fanael Linithien" . "fanael4@gmail.com") (:url . "https://github.com/Fanael/edit-indirect"))]) (edit-color-stamp . [(20130529 1733) ((es-lib (0 2)) (cl-lib (1 0))) "Edit a hex color stamp, using a QT or the internal color picker" tar ((:commit . "32dc1ca5bcf3dcf83fad5e39b55dc5b77becb3d3") (:authors ("sabof")) (:maintainer "sabof") (:url . "https://github.com/sabof/edit-color-stamp"))]) (edit-at-point . [(20150716 1324) nil "edit(copy,cut..) current things(word,symbol..) under cursor" single ((:commit . "3b800c11685102e1eab62ec71c5fc1589ebb81a7") (:authors (nil . "<e.enoson@gmail.com>")) (:maintainer nil . "<e.enoson@gmail.com>") (:url . "http://github.com/enoson/edit-at-point.el"))]) (edebug-x . [(20130616 625) nil "Extensions for Edebug" single ((:commit . "a2c2c42553d3bcbd5ac11898554865acbed1bc46") (:keywords "extensions") (:authors ("Scott Barnett" . "scott.n.barnett@gmail.com")) (:maintainer "Scott Barnett" . "scott.n.barnett@gmail.com") (:url . "https://github.com/ScottyB/edebug-x"))]) (ede-php-autoload-drupal . [(20170316 2158) ((ede-php-autoload (1 0 0)) (f (0 19 0)) (s (1 7 0))) "Drupal support for ede-php-autoload" single ((:commit . "54a04241d94fabc4f4d16ae4dc8ba4f0c6e3b435") (:keywords "programming" "php" "drupal") (:authors ("Thomas Fini Hansen" . "xen@xen.dk")) (:maintainer "Thomas Fini Hansen" . "xen@xen.dk"))]) (ede-php-autoload-composer-installers . [(20170221 2026) ((ede-php-autoload (1 0 0)) (f (0 19 0)) (s (1 7 0))) "Composer installers support for ede-php-autoload" single ((:commit . "7840439802c7d11ee086bbf465657f3da12f9f66") (:keywords "programming" "php") (:authors ("Thomas Fini Hansen" . "xen@xen.dk")) (:maintainer "Thomas Fini Hansen" . "xen@xen.dk") (:url . "https://github.com/xendk/ede-php-autoload-composer-installers"))]) (ede-php-autoload . [(20180901 1255) nil "Simple EDE PHP Project" tar ((:commit . "8a4eeeaa93b8d87b65a107c4ebcbeb14528d9449") (:keywords "php" "project" "ede") (:authors ("Steven Rémot" . "steven.remot@gmail.com") ("original code for C++ by Eric M. Ludlam" . "eric@siege-engine.com")) (:maintainer "Steven Rémot" . "steven.remot@gmail.com") (:url . "https://github.com/emacs-php/ede-php-autoload"))]) (ede-compdb . [(20150920 2033) ((ede (1 2)) (semantic (2 2)) (cl-lib (0 4))) "Support for compilation database projects in EDE" single ((:commit . "d6d8466cd62876fc90adeff5875a1a584fd846cd") (:keywords "development" "ninja" "build" "cedet" "ede") (:authors ("Alastair Rankine" . "alastair@girtby.net")) (:maintainer "Alastair Rankine" . "alastair@girtby.net"))]) (edbi-sqlite . [(20160221 1923) ((emacs (24)) (edbi (0 1 3))) "Open sqlite files with edbi" single ((:commit . "52cb9ca1af7691b592f2cfd2f007847e7a4ccd5f") (:authors ("Artem Malyshev" . "proofit404@gmail.com")) (:maintainer "Artem Malyshev" . "proofit404@gmail.com") (:url . "https://github.com/proofit404/edbi-sqlite"))]) (edbi-minor-mode . [(20160706 1447) ((edbi (0 1 3))) "Use edbi with regular SQL files." single ((:commit . "566a2141a6eb9d9d5d7e1bd7c251d1c5e8f0d2ec") (:authors ("Artem Malyshev" . "proofit404@gmail.com")) (:maintainer "Artem Malyshev" . "proofit404@gmail.com") (:url . "https://github.com/proofit404/edbi-minor-mode"))]) (edbi-django . [(20180627 1000) ((emacs (25)) (pythonic (0 1 0)) (edbi (0 1 3))) "Run edbi with django settings" single ((:commit . "5fe3fe82c8691af91dfc24ad3dc591ca228ec875") (:authors ("Artem Malyshev" . "proofit404@gmail.com")) (:maintainer "Artem Malyshev" . "proofit404@gmail.com") (:url . "https://github.com/proofit404/edbi-django"))]) (edbi-database-url . [(20160221 1923) ((emacs (24)) (edbi (0 1 3))) "Run edbi with database url" single ((:commit . "d56c580268cd93651998c4c6b1c5558e6b6ca90f") (:authors ("Artem Malyshev" . "proofit404@gmail.com")) (:maintainer "Artem Malyshev" . "proofit404@gmail.com") (:url . "https://github.com/proofit404/edbi-database-url"))]) (edbi . [(20160225 141) ((concurrent (0 3 1)) (ctable (0 1 2)) (epc (0 1 1))) "Emacs Database Interface" tar ((:commit . "6f50aaf4bde75255221f2292c7a4ad3fa9d918c0"))]) (ecukes . [(20171216 1208) ((commander (0 6 1)) (espuds (0 2 2)) (ansi (0 3 0)) (dash (2 2 0)) (s (1 8 0)) (f (0 11 0))) "Cucumber for Emacs." tar ((:commit . "3a77ba9f1064c2bca47b401974c009e65727c46e"))]) (eclipse-theme . [(20160430 1022) nil "Theme based on Eclipse circa 2010" single ((:commit . "dc54d9312d97210823b922038076e2b1b132eff2") (:keywords "themes") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:url . "https://github.com/abo-abo/eclipse-theme"))]) (eclim . [(20171114 154) ((dash (2 11 0)) (json (1 2)) (popup (0 5 2)) (s (1 9 0)) (cl-lib (0 5)) (yasnippet (0 10 0))) "An interface to the Eclipse IDE." tar ((:commit . "6396ad1cd25c0a197109343ec1cce5d5080acdff"))]) (ecb . [(20170728 1921) nil "a code browser for Emacs" tar ((:commit . "1330a44cf3c171781083b0b926ab7622f64e6e81") (:keywords "browser" "code" "programming" "tools") (:authors ("Jesper Nordenberg" . "mayhem@home.se") ("Klaus Berndl" . "klaus.berndl@sdm.de") ("Kevin A. Burton" . "burton@openprivacy.org")) (:maintainer "Klaus Berndl" . "klaus.berndl@sdm.de"))]) (ebib . [(20180817 1024) ((dash (2 5 0)) (seq (2 15)) (parsebib (2 3)) (emacs (24 4))) "a BibTeX database manager" tar ((:commit . "1b675d32ebeb8b52cd20934b6e4a4914361329fa") (:keywords "text" "bibtex") (:authors ("Joost Kremers" . "joostkremers@fastmail.fm")) (:maintainer "Joost Kremers" . "joostkremers@fastmail.fm"))]) (ebf . [(20160211 1758) ((dash (2 11 0)) (dash-functional (1 2 0)) (cl-lib (0 5))) "brainfuck language transpiler to Emacs Lisp" tar ((:commit . "4cd9c26354d8be6571354b2954d21fba882e78a2") (:authors ("Alexey Kutepov" . "reximkut@gmail.com")) (:maintainer "Alexey Kutepov" . "reximkut@gmail.com") (:url . "http://github.com/rexim/ebf"))]) (ebal . [(20180101 616) ((emacs (24 4)) (f (0 18 0))) "Emacs interface to Cabal and Stack" single ((:commit . "1740118125ae7aa6ba82d36e1fe0e69065a6fcaa") (:keywords "convenience" "cabal" "haskell") (:authors ("Mark Karpov" . "markkarpov92@gmail.com")) (:maintainer "Mark Karpov" . "markkarpov92@gmail.com") (:url . "https://github.com/mrkkrp/ebal"))]) (easy-repeat . [(20150516 848) ((emacs (24 4))) "Repeat easily" single ((:commit . "060f0e6801c82c40c06961dc0528a00e18947a8c") (:keywords "repeat" "convenience") (:authors ("Chunyang Xu" . "xuchunyang56@gmail.com")) (:maintainer "Chunyang Xu" . "xuchunyang56@gmail.com") (:url . "https://github.com/xuchunyang/easy-repeat.el"))]) (easy-kill-extras . [(20161028 1204) ((easy-kill (0 9 4))) "Extra functions for easy-kill." tar ((:commit . "e60a74d7121eff7c263098aea2901cc05a5f6acd") (:keywords "killing" "convenience") (:authors ("Akinori MUSHA" . "knu@iDaemons.org")) (:maintainer "Akinori MUSHA" . "knu@iDaemons.org") (:url . "https://github.com/knu/easy-kill-extras.el"))]) (easy-kill . [(20151031 529) ((emacs (24)) (cl-lib (0 5))) "kill & mark things easily" single ((:commit . "e2b667f651a3531164d24ea4cbcd8c34fba0e17f") (:keywords "killing" "convenience") (:authors ("Leo Liu" . "sdl.web@gmail.com")) (:maintainer "Leo Liu" . "sdl.web@gmail.com") (:url . "https://github.com/leoliu/easy-kill"))]) (easy-jekyll . [(20180822 145) ((emacs (24 4))) "Major mode managing jekyll blogs" single ((:commit . "b098997af471bb462fa63d83a987f0a24ad17733") (:authors ("Masashı Mıyaura")) (:maintainer "Masashı Mıyaura") (:url . "https://github.com/masasam/emacs-easy-jekyll"))]) (easy-hugo . [(20180823 126) ((emacs (24 4)) (popup (0 5 3))) "Write blogs made with hugo by markdown or org-mode" single ((:commit . "c90fd5ae0504ab8e797493cde68df886ff1d0645") (:authors ("Masashı Mıyaura")) (:maintainer "Masashı Mıyaura") (:url . "https://github.com/masasam/emacs-easy-hugo"))]) (easy-escape . [(20161209 1544) nil "Improve readability of escape characters in regular expressions" single ((:commit . "63fa5fcf9a53b7d3c1e872081e65afad5a722ba8") (:keywords "convenience" "lisp" "tools") (:authors ("Clément Pit--Claudel" . "clement.pitclaudel@live.com")) (:maintainer "Clément Pit--Claudel" . "clement.pitclaudel@live.com") (:url . "https://github.com/cpitclaudel/easy-escape"))]) (easy-after-load . [(20170817 1231) nil "eval-after-load for all files in a directory" single ((:commit . "29e20145da49ac9ea40463c552130777408040de") (:authors ("Kyle Hargraves")) (:maintainer "Kyle Hargraves") (:url . "https://github.com/pd/easy-after-load"))]) (eacl . [(20180607 1358) ((emacs (24 3)) (ivy (0 9 1))) "Auto-complete line(s) by grepping project" single ((:commit . "ccf1401b1acff67fe445c95e8be7b09e8c3ae5d8") (:keywords "abbrev" "convenience" "matching") (:authors ("Chen Bin <chenbin DOT sh AT gmail DOT com>")) (:maintainer "Chen Bin <chenbin DOT sh AT gmail DOT com>") (:url . "http://github.com/redguardtoo/eacl"))]) (e2wm-term . [(20141009 1308) ((e2wm (1 2)) (log4e (0 2 0)) (yaxception (0 3 2))) "Perspective of e2wm.el for work in terminal" single ((:commit . "65b5ac88043d5c4048920a048f3599904ca55981") (:keywords "tools" "window manager") (:authors ("Hiroaki Otsu" . "ootsuhiroaki@gmail.com")) (:maintainer "Hiroaki Otsu" . "ootsuhiroaki@gmail.com") (:url . "https://github.com/aki2o/e2wm-term"))]) (e2wm-sww . [(20140524 858) ((e2wm (1 2))) "Plugin of e2wm.el to switch plugin quickly" single ((:commit . "1063f9854bd34db5ac771cd1036cecc89834729d") (:keywords "tools" "window manager") (:authors ("Hiroaki Otsu" . "ootsuhiroaki@gmail.com")) (:maintainer "Hiroaki Otsu" . "ootsuhiroaki@gmail.com") (:url . "https://github.com/aki2o/e2wm-sww"))]) (e2wm-svg-clock . [(20150106 1306) ((e2wm (20130225 1602)) (svg-clock (0 4))) "e2wm plugin for svg-clock" single ((:commit . "d425925e3afffcbe2ff74edc80b714e4319d4c94") (:keywords "convenience" "e2wm") (:authors ("Yuhei Maeda <yuhei.maeda_at_gmail.com>")) (:maintainer "Yuhei Maeda") (:url . "https://github.com/myuhe/e2wm-svg-clock.el"))]) (e2wm-pkgex4pl . [(20140525 1047) ((e2wm (1 2)) (plsense-direx (0 2 0))) "Plugin of e2wm.el for package explorer of Perl" single ((:commit . "7ea994450727190c4f3cb46cb429ba41b692ecc0") (:keywords "tools" "window manager" "perl") (:authors ("Hiroaki Otsu" . "ootsuhiroaki@gmail.com")) (:maintainer "Hiroaki Otsu" . "ootsuhiroaki@gmail.com") (:url . "https://github.com/aki2o/e2wm-pkgex4pl"))]) (e2wm-direx . [(20170509 1301) ((e2wm (1 2)) (direx (0 1 -3))) "Plugin of e2wm.el for direx.el" single ((:commit . "b47f19d15436cc28233a812a1150689f61d11046") (:keywords "tools" "window manager" "convenience") (:authors ("Hiroaki Otsu" . "ootsuhiroaki@gmail.com")) (:maintainer "Hiroaki Otsu" . "ootsuhiroaki@gmail.com") (:url . "https://github.com/aki2o/e2wm-direx"))]) (e2wm-bookmark . [(20151123 521) ((e2wm (1 2))) "Bookmark plugin for e2wm.el" single ((:commit . "bad816b6d8049984d69bcd277b7d325fb84d55eb") (:keywords "convenience") (:authors ("Yuhei Maeda <yuhei.maeda_at_gmail.com>")) (:maintainer "Yuhei Maeda <yuhei.maeda_at_gmail.com>"))]) (e2wm-R . [(20151230 926) ((e2wm (1 3)) (inlineR (1 0)) (ess (15 3))) "some e2wm plugin and perspective for GNU R" single ((:commit . "4350601ee1a96bf89777b3f09f1b79b88e2e6e4d") (:keywords "convenience" "e2wm") (:authors ("myuhe <yuhei.maeda_at_gmail.com>")) (:maintainer "myuhe") (:url . "https://github.com/myuhe/e2wm-R.el"))]) (e2wm . [(20170215 36) ((window-layout (1 4))) "simple window manager for emacs" tar ((:commit . "4353d3394c77a49f8f0291c239858c8c5e877549") (:keywords "tools" "window manager") (:authors ("SAKURAI Masashi <m.sakurai atmark kiwanami.net>")) (:maintainer "SAKURAI Masashi <m.sakurai atmark kiwanami.net>"))]) (e2ansi . [(20180403 1915) ((face-explorer (0 0 3))) "Syntax highlighting support for `less', powered by Emacs." tar ((:commit . "f886e687d50ff58063a92d40623f2400fa913af0") (:keywords "faces" "languages") (:authors ("Anders Lindgren")) (:maintainer "Anders Lindgren") (:url . "https://github.com/Lindydancer/e2ansi"))]) (dynamic-spaces . [(20171027 1851) nil "When editing, don't move text separated by spaces" single ((:commit . "97ae8480c257ba573ca3d06dbf602f9b23c41d38") (:keywords "convenience") (:authors ("Anders Lindgren")) (:maintainer "Anders Lindgren") (:url . "https://github.com/Lindydancer/dynamic-spaces"))]) (dynamic-ruler . [(20160602 808) nil "Displays a dynamic ruler at point." single ((:commit . "c9c0de6fe5721f06b50e01d9b4684b519c71b367") (:keywords "ruler" "tools" "convenience") (:authors ("Francesc Rocher" . "francesc.rocher@gmail.com")) (:maintainer "Francesc Rocher" . "francesc.rocher@gmail.com") (:url . "http://rocher.github.io/dynamic-ruler"))]) (dynamic-fonts . [(20140731 1226) ((font-utils (0 7 0)) (persistent-soft (0 8 8)) (pcache (0 2 3))) "Set faces based on available fonts" single ((:commit . "ab0c65accbdb59acaed5b263327e22ec019b3e82") (:keywords "faces" "frames") (:authors ("Roland Walker" . "walker@pobox.com")) (:maintainer "Roland Walker" . "walker@pobox.com") (:url . "http://github.com/rolandwalker/dynamic-fonts"))]) (dylan-mode . [(20160405 2214) nil "Major mode for editing Dylan programs." tar ((:commit . "7e8ba16bf125f0066d3e1caeefaba94a6d32ac72") (:authors ("Robert Stockton" . "rgs@cs.cmu.edu")) (:maintainer "Chris Page" . "cpage@opendylan.org"))]) (dyalog-mode . [(20180605 2113) ((cl-lib (0 2)) (emacs (24))) "Major mode for editing Dyalog APL source code" tar ((:keywords "languages") (:authors ("Joakim Hårsman" . "joakim.harsman@gmail.com")) (:maintainer "Joakim Hårsman" . "joakim.harsman@gmail.com") (:url . "https://bitbucket.org/harsman/dyalog-mode/"))]) (dut-mode . [(20170729 2111) ((emacs (24))) "Major mode for the Dut programming language" single ((:commit . "9235c7acaa6690942e9de8b7acd1e4be0c859dc1") (:keywords "languages" "gut") (:authors ("The dut-mode Authors")) (:maintainer "The dut-mode Authors") (:url . "https://github.com/dut-lang/dut-mode"))]) (duplicate-thing . [(20120515 1648) nil "Duplicate current line & selection" single ((:commit . "f6ed0232fd0653621afe450d53775a32a9d0e328") (:keywords "command" "duplicate" "line" "selection") (:authors ("ongaeshi")) (:maintainer "ongaeshi"))]) (dummyparens . [(20141009 1024) nil "parenthesis auto-pairing and wrapping" single ((:commit . "9798ef1d0eaa24e4fe66f8aa6022a8c62714cc89") (:keywords "dummyparens" "auto-pair" "wrapping") (:authors ("Sergei Nosov <sergei.nosov [at] gmail.com>")) (:maintainer "Sergei Nosov <sergei.nosov [at] gmail.com>") (:url . "https://github.com/snosov1/dummyparens"))]) (dumb-jump . [(20180818 2342) ((emacs (24 3)) (f (0 20 0)) (s (1 11 0)) (dash (2 9 0)) (popup (0 5 3))) "jump to definition for multiple languages without configuration." single ((:commit . "9e436eaa7302cea01cd14e9ed9dcccb3617e01cd") (:keywords "programming") (:authors ("jack angers")) (:maintainer "jack angers"))]) (dumb-diff . [(20171211 2122) ((emacs (24 3))) "fast arbitrary diffs" single ((:commit . "1a2331d283049b71a07c1b06b1e0627a950d55f4") (:keywords "programming" "diff") (:authors ("jack angers")) (:maintainer "jack angers"))]) (ducpel . [(20140702 1154) ((cl-lib (0 5))) "Logic game with sokoban elements" tar ((:commit . "b53b935ab95c02b82ccf38f63c89e39e99477a55") (:keywords "games") (:authors ("Alex Kost" . "alezost@gmail.com")) (:maintainer "Alex Kost" . "alezost@gmail.com") (:url . "https://github.com/alezost/ducpel"))]) (dts-mode . [(20161103 1223) nil "Major mode for Devicetree source code" single ((:commit . "9ee0854446dcc6c53d2b8d2941051768dba50344") (:keywords "languages") (:authors ("Ben Gamari" . "ben@smart-cactus.org")) (:maintainer "Ben Gamari" . "ben@smart-cactus.org"))]) (dtrt-indent . [(20180628 2138) nil "Adapt to foreign indentation offsets" tar ((:commit . "084dac7ab36a89d2a7d6cb8f443b1eccbfd189e2") (:keywords "convenience" "files" "languages" "c") (:authors ("Julian Scheid" . "julians37@googlemail.com")) (:maintainer "Julian Scheid" . "julians37@googlemail.com"))]) (dtrace-script-mode . [(20150214 623) nil "DTrace code editing commands for Emacs" single ((:commit . "801af1ef16075d31a19830ebb8404bbf3a322f10"))]) (dsvn . [(20130120 2057) nil "Subversion interface" single ((:commit . "17bce692e9bd5a43373d5cb1d66da50e1acb903b") (:keywords "docs") (:authors ("David Kågedal" . "davidk@lysator.liu.se") ("   Mattias Engdegård" . "mattiase@acm.org")) (:maintainer "Mattias Engdegård" . "mattiase@acm.org"))]) (drupal-spell . [(20130520 1655) nil "Aspell extra dictionary for Drupal" tar ((:commit . "cddf1dbc71fb4c5c4c50317db6830467fa97cff0") (:keywords "wp") (:authors ("Arne Jørgensen" . "arne@arnested.dk")) (:maintainer "Arne Jørgensen" . "arne@arnested.dk") (:url . "https://github.com/arnested/drupal-spell"))]) (drupal-mode . [(20171120 2309) ((php-mode (1 5 0))) "Advanced minor mode for Drupal development" tar ((:commit . "47fda0a38a5b197f4606137d9c3b7d44aaeaa886") (:keywords "programming" "php" "drupal") (:authors ("Arne Jørgensen" . "arne@arnested.dk")) (:maintainer "Arne Jørgensen" . "arne@arnested.dk") (:url . "https://github.com/arnested/drupal-mode"))]) (dropbox . [(20170503 22) ((json (1 2)) (oauth (1 0 3))) "Emacs backend for dropbox" single ((:commit . "d85bbf6caa4203d6088ea29f5c057c1e9bcacd85") (:keywords "dropbox") (:authors ("Pavel Panchekha" . "me@pavpanchekha.com")) (:maintainer "Pavel Panchekha" . "me@pavpanchekha.com"))]) (drone . [(20161106 918) nil "Launch your drone test suite if drone.yml is present" single ((:commit . "1d4ee037ad3208847a4235426edf0c4a3e7b1899") (:keywords "drone" "tests" "ci") (:authors ("Oliver Marks" . "oly@digitaloctave.com")) (:maintainer "Oliver Marks" . "oly@digitaloctave.com") (:url . "https://github.com/olymk2/emacs-drone"))]) (drill-instructor-AZIK-force . [(20151123 514) ((popup (0 5))) "Support AZIK input" tar ((:commit . "008cea202dc31d7d6fb1e7d8e6334d516403b7a5"))]) (drawille . [(20160418 1838) ((cl-lib (0 5))) "Drawille implementation in elisp" tar ((:commit . "d914845725719d8293e2f0dea3c9c7e0a1e0e62a") (:keywords "graphics") (:authors ("Josuah Demangeon" . "josuah.demangeon@gmail.com")) (:maintainer "Josuah Demangeon" . "josuah.demangeon@gmail.com") (:url . "https://github.com/sshbio/elisp-drawille"))]) (drag-stuff . [(20161108 749) nil "Drag stuff (lines, words, region, etc...) around" tar ((:commit . "6d06d846cd37c052d79acd0f372c13006aa7e7c8"))]) (draft-mode . [(20140609 1456) nil "Rough drafting for Emacs." single ((:commit . "4779fb32daf53746459da2def7e08004492d4f18") (:keywords "draft" "drafting") (:authors ("Eeli Reilin" . "gaudecker@fea.st")) (:maintainer "Eeli Reilin" . "gaudecker@fea.st") (:url . "https://github.com/gaudecker/draft-mode"))]) (dracula-theme . [(20180710 1324) ((emacs (24))) "Dracula Theme" single ((:commit . "a1c9888b7876ace60a536d27fb290e788bffc9cb") (:authors ("film42")) (:maintainer "film42") (:url . "https://github.com/dracula/emacs"))]) (dr-racket-like-unicode . [(20161021 1211) ((emacs (24 1))) "DrRacket-style unicode input" single ((:commit . "4953f1c8a68472e157a0dcd0a7e35a4ec2577133") (:keywords "i18n" "tools") (:authors ("David Christiansen" . "david@davidchristiansen.dk")) (:maintainer "David Christiansen" . "david@davidchristiansen.dk"))]) (dpaste_de . [(20131015 1225) ((web (0 3 7))) "Emacs mode to paste to dpaste.de" single ((:commit . "f0c39e8864299f735642f7d9fa490689398ce39d") (:keywords "pastebin") (:authors ("Thejaswi Puthraya" . "thejaswi.puthraya@gmail.com")) (:maintainer "Thejaswi Puthraya" . "thejaswi.puthraya@gmail.com"))]) (dpaste . [(20160303 2112) nil "Emacs integration for dpaste.com" single ((:commit . "5ebabb466a6ae70882549855b6b2194fc32189f8") (:keywords "paste" "pastie" "pastebin" "dpaste" "python") (:authors ("Greg Newman" . "greg@gregnewman.org") ("Guilherme Gondim" . "semente@taurinus.org")) (:maintainer "Greg Newman" . "greg@gregnewman.org"))]) (downplay-mode . [(20151125 2009) nil "focus attention on a region of the buffer" single ((:commit . "4a2c3addc73c8ca3816345c3c11c08af265baedb") (:authors ("Toby Crawley" . "toby@tcrawley.org")) (:maintainer "Toby Crawley" . "toby@tcrawley.org") (:url . "https://github.com/tobias/downplay-mode/"))]) (download-region . [(20180124 133) ((cl-lib (0 3))) "Simple in-buffer download manager" single ((:commit . "bbba3ecd80818d5d940d41fe89a6e2ec5dd2c53c") (:authors ("zk_phi")) (:maintainer "zk_phi") (:url . "http://hins11.yu-yake.com/"))]) (dotnet . [(20170827 1538) nil "Interact with dotnet CLI tool" single ((:commit . "e22fd23bf2bfab980d4802b10c4d872b800f90d4") (:keywords ".net" "tools") (:authors ("Julien BLANCHARD" . "julien@sideburns.eu")) (:maintainer "Julien BLANCHARD" . "julien@sideburns.eu") (:url . "https://github.com/julienXX/dotnet.el"))]) (dotenv-mode . [(20180207 1914) ((emacs (24 3))) "Major mode for .env files" single ((:commit . "f4c52bcd5313379b9f2460db7f7a33119dfa96ea") (:authors ("Preetpal S. Sohal")) (:maintainer "Preetpal S. Sohal") (:url . "https://github.com/preetpalS/emacs-dotenv-mode"))]) (dot-mode . [(20180312 2300) ((emacs (24 3))) "minor mode to repeat typing or commands" single ((:commit . "6ca22b73bcdae2363ee9641b822a60685df16a3e") (:keywords "convenience") (:authors ("Robert Wyrick" . "rob@wyrick.org")) (:maintainer "Robert Wyrick" . "rob@wyrick.org") (:url . "https://github.com/wyrickre/dot-mode"))]) (doom-themes . [(20180829 2148) ((emacs (24 4)) (all-the-icons (1 0 0)) (cl-lib (0 5))) "an opinionated pack of modern color-themes" tar ((:commit . "3769bf2ba3b18f22897588aee8dfae63144a5afa") (:keywords "dark" "light" "blue" "atom" "one" "theme" "neotree" "icons" "faces" "nova") (:authors ("Henrik Lissner <http://github/hlissner>")) (:maintainer "Henrik Lissner" . "henrik@lissner.net") (:url . "https://github.com/hlissner/emacs-doom-theme"))]) (doom-modeline . [(20180830 1951) ((emacs (25 1)) (all-the-icons (1 0 0)) (projectile (0 10 0)) (shrink-path (0 2 0)) (eldoc-eval (0 1)) (dash (2 11 0))) "A minimal modeline from DOOM." single ((:commit . "ac0372958bc3acb46862fcb79302a069ef19d4fa") (:keywords "faces" "mode-line") (:authors ("Vincent Zhang" . "seagle0128@gmail.com")) (:maintainer "Vincent Zhang" . "seagle0128@gmail.com") (:url . "https://github.com/seagle0128/doom-modeline"))]) (doom . [(20180301 2308) ((cl-lib (0 5))) "DOM implementation and manipulation library" single ((:commit . "e59040aefc92dd9b3134eb623624307fb9e4327b") (:keywords "xml" "dom") (:authors ("Alex Schroeder" . "alex@gnu.org") ("Henrik.Motakef" . "elisp@henrik-motakef.de") ("Katherine Whitlock" . "toroidal-code@gmail.com") ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Alex Schroeder") (:url . "http://www.github.com/kensanata/doom.el/"))]) (doneburn-theme . [(20180502 1704) nil "A light theme based on Bozhidar Batsov's Zenburn" single ((:commit . "dffe0d177765bc978607455864625bcf3413597a") (:keywords "faces" "themes") (:authors ("Manuel Uberti" . "manuel.uberti@inventati.org")) (:maintainer "Manuel Uberti" . "manuel.uberti@inventati.org") (:url . "http://github.com/manuel-uberti/doneburn-emacs"))]) (dollaro . [(20151123 1302) ((s (1 6 0))) "simple text templates" single ((:commit . "500127f0172ac7a1eec627e026b59136580a74ac") (:keywords "tools" "convenience") (:authors ("Alessandro Piras" . "laynor@gmail.com")) (:maintainer "Alessandro Piras" . "laynor@gmail.com"))]) (dokuwiki-mode . [(20170223 1301) nil "Major mode for DokuWiki document" single ((:commit . "e4e116f6fcc373e3f5937c1a7daa5c2c9c6d3fa1") (:keywords "hypermedia" "text" "dokuwiki") (:authors ("Tsunenobu Kai" . "kai2nenobu@gmail.com")) (:maintainer "Tsunenobu Kai" . "kai2nenobu@gmail.com") (:url . "https://github.com/kai2nenobu/emacs-dokuwiki-mode"))]) (dokuwiki . [(20180102 59) ((emacs (24 3)) (xml-rpc (1 6 8))) "Edit Remote DokuWiki Pages Using XML-RPC" single ((:commit . "594c4d4904dcc2796bbbd2c0845d9e7c09ccf6f7") (:keywords "convenience") (:authors ("Juan Karlo Licudine" . "accidentalrebel@gmail.com")) (:maintainer "Juan Karlo Licudine" . "accidentalrebel@gmail.com") (:url . "http://www.github.com/accidentalrebel/emacs-dokuwiki"))]) (dockerfile-mode . [(20180628 1659) ((emacs (24)) (s (1 12))) "Major mode for editing Docker's Dockerfiles" single ((:commit . "64733f64ea9be1e5e534e590846869b75c62ed1f") (:url . "https://github.com/spotify/dockerfile-mode"))]) (docker-tramp . [(20170207 325) ((emacs (24)) (cl-lib (0 5))) "TRAMP integration for docker containers" tar ((:commit . "8e2b671eff7a81af43b76d9dfcf94ddaa8333a23") (:keywords "docker" "convenience") (:authors ("Mario Rodas" . "marsam@users.noreply.github.com")) (:maintainer "Mario Rodas" . "marsam@users.noreply.github.com") (:url . "https://github.com/emacs-pe/docker-tramp.el"))]) (docker-compose-mode . [(20180324 1752) ((emacs (24 3)) (dash (2 12 0)) (yaml-mode (0 0 12))) "Major mode for editing docker-compose files" single ((:commit . "c9f131d2c90d652435d407fd36c40feebfed1dad") (:keywords "convenience") (:authors ("Ricardo Martins")) (:maintainer "Ricardo Martins") (:url . "https://github.com/meqif/docker-compose-mode"))]) (docker-api . [(20160525 720) ((dash (2 12 1)) (request (0 2 0)) (s (1 11 0))) "Emacs interface to the Docker API" tar ((:commit . "206144346b7fa4165223349cfeb64a75d47ddd1b") (:authors ("Philippe Vaucher" . "philippe.vaucher@gmail.com")) (:maintainer "Philippe Vaucher" . "philippe.vaucher@gmail.com") (:url . "https://github.com/Silex/docker-api.el"))]) (docker . [(20180820 1130) ((emacs (24 5)) (dash (2 14 1)) (docker-tramp (0 1)) (magit-popup (2 12 3)) (s (1 12 0)) (tablist (0 70)) (json-mode (1 7 0))) "Emacs interface to Docker" tar ((:commit . "a88d585e283cb614170e450dd82895612c8d315d") (:keywords "filename" "convenience") (:authors ("Philippe Vaucher" . "philippe.vaucher@gmail.com")) (:maintainer "Philippe Vaucher" . "philippe.vaucher@gmail.com") (:url . "https://github.com/Silex/docker.el"))]) (docean . [(20180605 1744) ((emacs (24)) (cl-lib (0 5)) (request (0 2 0))) "Interact with DigitalOcean from Emacs." single ((:commit . "bbe2298fd21f7876fc2d5c52a69b931ff59df979") (:keywords "convenience") (:authors ("Mario Rodas" . "marsam@users.noreply.github.com")) (:maintainer "Mario Rodas" . "marsam@users.noreply.github.com") (:url . "https://github.com/emacs-pe/docean.el"))]) (docbook-snippets . [(20150714 1625) ((yasnippet (0 8 0))) "Yasnippets for DocBook" tar ((:commit . "b06297fdec039a541aaa6312cb328a11062cfab4") (:keywords "snippets" "docbook") (:authors ("Jaromir Hradilek" . "jhradilek@gmail.com")) (:maintainer "Jaromir Hradilek" . "jhradilek@gmail.com") (:url . "https://github.com/jhradilek/emacs-docbook-snippets"))]) (dna-mode . [(20170804 814) nil "a major mode for editing dna sequences" tar ((:commit . "471d374de22c33eaddd8e41dd8ae29753fab2f6a") (:keywords "dna" "emacs" "editing") (:authors ("Harley Gorrell" . "harley@panix.com")) (:maintainer "Harley Gorrell" . "harley@panix.com") (:url . "http://www.mahalito.net/~harley/elisp/dna-mode.el"))]) (dmenu . [(20180118 1245) ((cl-lib (0 5))) "simulate the dmenu command line program" single ((:commit . "6e492cd4ee4fb39ecda92776707fc270f54d25e7") (:keywords "convenience" "usability") (:authors ("DarkSun" . "lujun9972@gmail.com")) (:maintainer "DarkSun" . "lujun9972@gmail.com"))]) (dkmisc . [(20131110 1115) ((emacs (24 1))) "Miscellaneous functions required by dk* packages." tar ((:commit . "fe3d49c6f8322b6f89466361acd97585bdfe0608"))]) (dklrt . [(20131110 1341) ((dkmisc (0 50)) (ledger-mode (20130908 1357)) (emacs (24 1))) "Ledger Recurring Transactions." tar ((:commit . "5d6c99f8018335256ab934b4c1049708ae2d48ba"))]) (dkl . [(20161005 7) nil "Display keyboard layout." tar ((:commit . "6b4584f86037bda3383960c678d51f340229fb91") (:keywords "input" "keyboard" "layout") (:authors ("Alexis" . "flexibeast@gmail.com")) (:maintainer "Alexis" . "flexibeast@gmail.com") (:url . "https://github.com/flexibeast/dkl"))]) (dkdo . [(20131110 1119) ((dkmisc (0 50)) (emacs (24 1))) "Do List major mode based on org-mode." tar ((:commit . "fd6bb105e8331fafb6385c5238c988c4c5bbe2da"))]) (djangonaut . [(20180727 1544) ((emacs (25 2)) (magit-popup (2 6 0)) (pythonic (0 1 0)) (f (0 20 0)) (s (1 12 0))) "Minor mode to interact with Django projects" single ((:commit . "487dbd19a312cf5b45183df82d5d57f5c5a403a2") (:authors ("Artem Malyshev" . "proofit404@gmail.com")) (:maintainer "Artem Malyshev" . "proofit404@gmail.com") (:url . "https://github.com/proofit404/djangonaut"))]) (django-theme . [(20131022 902) nil "Custom face theme for Emacs" single ((:commit . "86c8142b3eb1addd94a43aa6f1d98dab06401af0") (:authors ("Andrzej Sliwa")) (:maintainer "Andrzej Sliwa") (:url . "http://github/anrzejsliwa/django-theme"))]) (django-snippets . [(20131229 1611) ((yasnippet (0 8 0))) "Yasnippets for django" tar ((:commit . "a71b8dd984e7f724b8321246e5c353a4ae5c986e") (:authors ("Yasuyuki Oka" . "yasuyk@gmail.com")) (:maintainer "Yasuyuki Oka" . "yasuyk@gmail.com") (:url . "https://github.com/myfreeweb/django-mode"))]) (django-mode . [(20170522 714) ((projectile (0)) (s (0)) (helm-make (0))) "Major mode for Django web framework." tar ((:commit . "a71b8dd984e7f724b8321246e5c353a4ae5c986e") (:keywords "languages") (:authors ("Greg V" . "floatboth@me.com")) (:maintainer "Greg V" . "floatboth@me.com"))]) (django-manage . [(20160819 212) ((hydra (0 13 2))) "Django minor mode for commanding manage.py" single ((:commit . "876fb2cb627d465adfdc905841279784bcdd7ee8") (:keywords "languages") (:authors ("Daniel Gopar" . "gopardaniel@yahoo.com")) (:maintainer "Daniel Gopar" . "gopardaniel@yahoo.com"))]) (dizzee . [(20171201 916) nil "A more pleasant way to manage your project's subprocesses in Emacs." tar ((:commit . "e3cf1c2ea5d0fc00747524b6f3c5b905d0a8c8e1"))]) (dix-evil . [(20170105 1423) ((dix (0 3 0)) (evil (1 0 7))) "optional evil-integration with dix.el" single ((:commit . "bcc7fd7aef5d25171978c386c620e09d0ba8d2f8") (:keywords "languages") (:authors ("Kevin Brubeck Unhammer" . "unhammer@fsfe.org")) (:maintainer "Kevin Brubeck Unhammer" . "unhammer@fsfe.org") (:url . "http://wiki.apertium.org/wiki/Emacs"))]) (dix . [(20170224 1415) ((cl-lib (0 5))) "minor mode for editing Apertium XML dictionary files" tar ((:commit . "bcc7fd7aef5d25171978c386c620e09d0ba8d2f8") (:keywords "languages") (:authors ("Kevin Brubeck Unhammer" . "unhammer@fsfe.org")) (:maintainer "Kevin Brubeck Unhammer" . "unhammer@fsfe.org") (:url . "http://wiki.apertium.org/wiki/Emacs"))]) (ditz-mode . [(20150729 940) nil "Emacs interface to Ditz issue tracking system" single ((:keywords "tools") (:authors ("Glenn Hutchings" . "zondo42@gmail.com")) (:maintainer "Glenn Hutchings" . "zondo42@gmail.com"))]) (distinguished-theme . [(20151216 2015) nil "A dark and elegant theme for emacs." single ((:commit . "9b1d25ac59465a5016d187ea84b7614c95a29b3b") (:authors ("Kim Silkebækken" . "kim.silkebaekken@gmail.com")) (:maintainer "Kim Silkebækken" . "kim.silkebaekken@gmail.com") (:url . "https://github.com/Lokaltog/distinguished-theme"))]) (distel-completion-lib . [(20180827 1344) nil "Completion library for Erlang/Distel" single ((:commit . "acc4c0a5521904203d797fe96b08e5fae4233c7e") (:keywords "erlang" "distel" "completion") (:authors ("Sebastian Weddmark Olsson")) (:maintainer "Sebastian Weddmark Olsson") (:url . "github.com/sebastiw/distel-completion"))]) (display-theme . [(20140115 1556) ((emacs (24))) "display current theme(s) at mode-line" single ((:commit . "b180b3be7a74ae4799a14e7e4bc2fe10e3ff7a15") (:keywords "tools") (:authors ("KAWABATA, Taichi <kawabata.taichi_at_gmail.com>")) (:maintainer "KAWABATA, Taichi <kawabata.taichi_at_gmail.com>") (:url . "https://github.com/kawabata/emacs-display-theme/"))]) (dispass . [(20140202 1531) ((dash (1 0 0))) "Emacs wrapper for DisPass" single ((:commit . "b6e8f89040ebaaf0e7609b04bc27a8979f0ae861") (:keywords "processes") (:authors ("Tom Willemsen" . "tom@ryuslash.org")) (:maintainer "Tom Willemsen" . "tom@ryuslash.org") (:url . "http://projects.ryuslash.org/dispass.el/"))]) (disk . [(20171116 731) nil "simplified find-file, revert-file, save-buffer interface" single ((:commit . "283e54e3be7d08f959076240b2ab324e25632137") (:keywords "convenience") (:authors ("Alex Schroeder" . "alex@gnu.org") ("Peter Barabas" . "peter.barabas+disk@gmail.com")) (:maintainer "Alex Schroeder" . "alex@gnu.org") (:url . "http://www.emacswiki.org/emacs/DiskKey"))]) (discover-my-major . [(20180606 511) ((makey (0 2))) "Discover key bindings and their meaning for the current Emacs major mode" single ((:commit . "c592e5e67454f0d1b68669ac0c270073164b16b3") (:keywords "discover" "help" "major-mode" "keys") (:authors ("steckerhalter")) (:maintainer "steckerhalter") (:url . "https://framagit.org/steckerhalter/discover-my-major"))]) (discover-js2-refactor . [(20140129 1552) ((js2-refactor (20131221 501)) (discover (20140103 1339))) "Adds discover context menu for js2-refactor" single ((:commit . "3812abf61f39f3e73a9f3daefa6fed4f21a429ba") (:keywords "js2-refactor" "discover") (:authors ("Nicolas Petton" . "petton.nicolas@gmail.com")) (:maintainer "Nicolas Petton" . "petton.nicolas@gmail.com"))]) (discover-clj-refactor . [(20150328 1459) ((clj-refactor (0 14 0)) (discover (0 3))) "Adds discover context menu for clj-refactor" single ((:commit . "3fbd5c1162739e606d7cf5d4f5d7426547d99647") (:keywords "clj-refactor" "discover" "convenience") (:authors ("Marian Schubert" . "marian.schubert@gmail.com")) (:maintainer "Marian Schubert" . "marian.schubert@gmail.com"))]) (discover . [(20140103 2139) ((makey (0 3))) "discover more of Emacs" single ((:commit . "7b0044bbb3b3bd5d811fdfb0f5ac6ec8de1239df") (:authors ("Mickey Petersen" . "mickey@fyeah.org")) (:maintainer "Mickey Petersen" . "mickey@fyeah.org"))]) (discourse . [(20160911 819) ((cl-lib (0 5)) (request (0 2)) (s (1 11 0))) "discourse api" single ((:commit . "a86c7e608851e186fe12e892a573994f08c8e65e") (:keywords "lisp" "discourse") (:authors ("DarkSun" . "lujun9972@gmail.com")) (:maintainer "DarkSun" . "lujun9972@gmail.com") (:url . "https://github.com/lujun9972/discourse-api"))]) (disaster . [(20171016 2152) nil "Disassemble C/C++ code under cursor in Emacs" single ((:commit . "10a785facc60d89d78e0d5177985ab1af1741bb4") (:keywords "tools") (:authors ("Justine Tunney" . "jtunney@gmail.com")) (:maintainer "Justine Tunney" . "jtunney@gmail.com") (:url . "https://github.com/jart/disaster"))]) (disable-mouse . [(20171227 115) nil "Disable mouse commands globally" single ((:commit . "541363bd6353b8b05375552bab884a6315ea545c") (:keywords "mouse") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:url . "https://github.com/purcell/disable-mouse"))]) (dirtree-prosjekt . [(20140129 904) ((prosjekt (0 3)) (dirtree (0 1))) "dirtree integration for prosjekt." single ((:commit . "a864a8be5842223043702395f311e3350c28e9db") (:authors ("Austin Bingham" . "austin.bingham@gmail.com")) (:maintainer "Austin Bingham" . "austin.bingham@gmail.com") (:url . "https://github.com/abingham/prosjekt"))]) (dirtree . [(20140129 832) ((tree-mode (1 1 1 1)) (windata (0))) "Directory tree views" single ((:commit . "ba55f1e716e386fdd37cb8e7f48616e405dc7251") (:authors ("Ye Wenbin" . "wenbinye@gmail.com")) (:maintainer "Ye Wenbin" . "wenbinye@gmail.com"))]) (direx-grep . [(20140515 1506) ((direx (0 1 -3))) "Grep node of direx.el using incremental search like anything.el/helm.el" single ((:commit . "1109a512a80b2673a70b18b8568514049017faad") (:keywords "convenience") (:authors ("Hiroaki Otsu" . "ootsuhiroaki@gmail.com")) (:maintainer "Hiroaki Otsu" . "ootsuhiroaki@gmail.com") (:url . "https://github.com/aki2o/direx-grep"))]) (direx . [(20170422 1327) nil "Simple Directory Explorer" tar ((:commit . "a79bfdb5980cf6ed7bfb3b41ddc471a7b6c0ede4") (:keywords "convenience") (:authors ("Tomohiro Matsuyama" . "m2ym.pub@gmail.com")) (:maintainer "Tomohiro Matsuyama" . "m2ym.pub@gmail.com"))]) (direnv . [(20180513 823) ((emacs (24 4)) (dash (2 12 0)) (with-editor (2 5 10))) "direnv support" single ((:commit . "6cf079fe8171bdf4bebefe02e8353d7f13847ebd") (:keywords "direnv" "environment" "processes" "unix" "tools") (:authors ("Wouter Bolsterlee" . "wouter@bolsterl.ee")) (:maintainer "Wouter Bolsterlee" . "wouter@bolsterl.ee") (:url . "https://github.com/wbolster/emacs-direnv"))]) (diredful . [(20160529 2017) nil "colorful file names in dired buffers" single ((:commit . "c08e163d9d6c62f7b07e94d54c96c2e364e67e0e") (:keywords "dired" "colors" "extension" "widget") (:authors ("Thamer Mahmoud" . "thamer.mahmoud@gmail.com")) (:maintainer "Thamer Mahmoud" . "thamer.mahmoud@gmail.com") (:url . "https://github.com/thamer/diredful"))]) (diredfl . [(20180211 214) ((emacs (24))) "Extra font lock rules for a more colourful dired" single ((:commit . "9b2a89951cee8bdf5c0cb67f9c3ad6ac73abf9cb") (:keywords "faces") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:url . "https://github.com/purcell/diredfl"))]) (dired-toggle-sudo . [(20151109 1006) nil "Browse directory with sudo privileges." single ((:commit . "02449dbda4e168f99fe5352c9628df5d39e11483") (:keywords "emacs" "dired") (:authors ("Sebastien Gross <seb•ɑƬ•chezwam•ɖɵʈ•org>")) (:maintainer "Sebastien Gross <seb•ɑƬ•chezwam•ɖɵʈ•org>"))]) (dired-toggle . [(20140907 2049) nil "provide a simple way to toggle dired buffer for current directory" single ((:commit . "84efb9ec9c327e4da53cdb7cda5b51dcd0ede0e5") (:keywords "dired" "toggle") (:authors ("Xu FaSheng" . "fasheng.xu@gmail.com")) (:maintainer "Xu FaSheng") (:url . "https://github.com/fasheng/dired-toggle"))]) (dired-subtree . [(20170910 2221) ((dash (2 5 0)) (dired-hacks-utils (0 0 1))) "Insert subdirectories in a tree-like fashion" single ((:commit . "b6f3b7addefa046f22a15e72a25e4368e8a33d5e") (:keywords "files") (:authors ("Matúš Goljer" . "matus.goljer@gmail.com")) (:maintainer "Matúš Goljer" . "matus.goljer@gmail.com"))]) (dired-single . [(20180824 312) nil "Reuse the current dired buffer to visit a directory" single ((:commit . "b0ccca83df0542c5525c047ae283c0eadf500f5c") (:keywords "dired" "reuse" "buffer") (:authors ("Joe Casadonte" . "emacs@northbound-train.com")) (:maintainer "crocket" . "crockabiscuit@gmail.com"))]) (dired-sidebar . [(20180902 1600) ((emacs (25 1)) (dired-subtree (0 0 1))) "Tree browser leveraging dired" single ((:commit . "4e0c89cf99d3176809275f53571d8ca89f3f40b9") (:keywords "dired" "files" "tools") (:authors ("James Nguyen" . "james@jojojames.com")) (:maintainer "James Nguyen" . "james@jojojames.com") (:url . "https://github.com/jojojames/dired-sidebar"))]) (dired-rsync . [(20180802 1525) ((s (1 12 0)) (dash (2 0 0)) (emacs (24))) "Allow rsync from dired buffers" single ((:commit . "f2d55c7e63b9500c7a71a85db06a6ef3abc80254") (:authors ("Alex Bennée" . "alex@bennee.com")) (:maintainer "Alex Bennée" . "alex@bennee.com") (:url . "https://github.com/stsquad/dired-rsync"))]) (dired-recent . [(20180527 1959) ((emacs (24))) "Dired visited paths history" single ((:commit . "22104c87593f24ec513dfdf97fc4c8c91defec33") (:keywords "files") (:authors ("Wojciech Siewierski <wojciech dot siewierski at onet dot pl>")) (:maintainer "Wojciech Siewierski <wojciech dot siewierski at onet dot pl>") (:url . "https://github.com/vifon/dired-recent"))]) (dired-ranger . [(20180401 2206) ((dash (2 7 0)) (dired-hacks-utils (0 0 1))) "Implementation of useful ranger features for dired" single ((:commit . "b6f3b7addefa046f22a15e72a25e4368e8a33d5e") (:keywords "files") (:authors ("Matúš Goljer" . "matus.goljer@gmail.com")) (:maintainer "Matúš Goljer" . "matus.goljer@gmail.com"))]) (dired-rainbow . [(20171202 2248) ((dash (2 5 0)) (dired-hacks-utils (0 0 1))) "Extended file highlighting according to its type" single ((:commit . "b6f3b7addefa046f22a15e72a25e4368e8a33d5e") (:keywords "files") (:authors ("Matus Goljer" . "matus.goljer@gmail.com")) (:maintainer "Matus Goljer" . "matus.goljer@gmail.com"))]) (dired-quick-sort . [(20161208 2112) ((hydra (0 13 0))) "Persistent quick sorting of dired buffers in various ways." single ((:commit . "1845f978d313f750a5b70b832457ed803c4ffbdb") (:keywords "convenience" "files") (:authors ("Hong Xu" . "hong@topbug.net")) (:maintainer "Hong Xu" . "hong@topbug.net") (:url . "https://gitlab.com/xuhdev/dired-quick-sort#dired-quick-sort"))]) (dired-open . [(20160205 2013) ((dash (2 5 0)) (dired-hacks-utils (0 0 1))) "Open files from dired using using custom actions" single ((:commit . "b6f3b7addefa046f22a15e72a25e4368e8a33d5e") (:keywords "files") (:authors ("Matúš Goljer" . "matus.goljer@gmail.com")) (:maintainer "Matúš Goljer" . "matus.goljer@gmail.com"))]) (dired-narrow . [(20170309 1129) ((dash (2 7 0)) (dired-hacks-utils (0 0 1))) "Live-narrowing of search results for dired" single ((:commit . "b6f3b7addefa046f22a15e72a25e4368e8a33d5e") (:keywords "files") (:authors ("Matúš Goljer" . "matus.goljer@gmail.com")) (:maintainer "Matúš Goljer" . "matus.goljer@gmail.com"))]) (dired-launch . [(20180607 1841) nil "Use dired as a launcher" single ((:commit . "ad45940f76ef2f6c3bb55e998829b311de191dae") (:keywords "dired" "launch") (:authors ("David Thompson")) (:maintainer "David Thompson") (:url . "https://github.com/thomp/dired-launch"))]) (dired-k . [(20170313 1503) ((emacs (24 3))) "highlight dired buffer by file size, modified time, git status" tar ((:commit . "c50e8f73358060a448bff66db2d330b52bbeffc1") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-dired-k"))]) (dired-imenu . [(20140109 1610) nil "imenu binding for dired mode" single ((:commit . "610e21fe0988c85931d34894d3eee2442c79ab0a") (:keywords "dired" "imenu") (:authors ("Damien Cassou" . "damien.cassou@gmail.com")) (:maintainer "Damien Cassou" . "damien.cassou@gmail.com") (:url . "https://github.com/DamienCassou/dired-imenu"))]) (dired-icon . [(20170223 526) ((emacs (24 3))) "A minor mode to display a list of associated icons in dired buffers." tar ((:commit . "f60e10757a5011235b519231ad35974ff25963ed") (:keywords "dired" "files") (:authors ("Hong Xu" . "hong@topbug.net")) (:maintainer "Hong Xu" . "hong@topbug.net") (:url . "https://gitlab.com/xuhdev/dired-icon"))]) (dired-hide-dotfiles . [(20170314 2039) ((emacs (25 1))) "Hide dotfiles in dired" single ((:commit . "b715f643ec805b3b8aca334595e6589320f04a49") (:keywords "files") (:authors ("Mattias Bengtsson" . "mattias.jc.bengtsson@gmail.com")) (:maintainer "Mattias Bengtsson" . "mattias.jc.bengtsson@gmail.com") (:url . "https://github.com/mattiasb/dired-hide-dotfiles"))]) (dired-hacks-utils . [(20160527 2136) ((dash (2 5 0))) "Utilities and helpers for dired-hacks collection" single ((:commit . "b6f3b7addefa046f22a15e72a25e4368e8a33d5e") (:keywords "files") (:authors ("Matúš Goljer" . "matus.goljer@gmail.com")) (:maintainer "Matúš Goljer" . "matus.goljer@gmail.com"))]) (dired-filter . [(20180830 2302) ((dash (2 10 0)) (dired-hacks-utils (0 0 1)) (f (0 17 0)) (cl-lib (0 3))) "Ibuffer-like filtering for dired" single ((:commit . "b6f3b7addefa046f22a15e72a25e4368e8a33d5e") (:keywords "files") (:authors ("Matúš Goljer" . "matus.goljer@gmail.com")) (:maintainer "Matúš Goljer" . "matus.goljer@gmail.com"))]) (dired-filetype-face . [(20160822 1355) nil "Set different faces for different filetypes in dired" single ((:commit . "72b3c88e8b82b3f8681d940757f7b2992bd80793") (:keywords "dired" "filetype" "face") (:authors ("纪秀峰 <jixiuf at gmail dot com>")) (:maintainer "纪秀峰 <jixiuf at gmail dot com>") (:url . "https://github.com/jixiuf/dired-filetype-face"))]) (dired-fdclone . [(20180403 608) nil "dired functions and settings to mimic FDclone" single ((:commit . "903d7a736d240ef7352989a4e5d0ff9129c2ee3c") (:keywords "unix" "directories" "dired") (:authors ("Akinori MUSHA" . "knu@iDaemons.org")) (:maintainer "Akinori MUSHA" . "knu@iDaemons.org") (:url . "https://github.com/knu/dired-fdclone.el"))]) (dired-explorer . [(20180607 221) ((cl-lib (0 5))) "minor-mode provides Explorer like select file at dired." single ((:commit . "3ade0a31b5340271d05e9bf443f2504960f6c6dd") (:keywords "dired" "explorer") (:maintainer "jidaikobo-shibata"))]) (dired-efap . [(20140122 1656) nil "Edit Filename At Point in a dired buffer" single ((:commit . "624757b2e54d9a13e2183118d6c113e37684b90c") (:keywords "dired" "environment" "files" "renaming") (:authors ("Juan-Leon Lahoz" . "juanleon1@gmail.com")) (:maintainer "Juan-Leon Lahoz" . "juanleon1@gmail.com") (:url . "https://github.com/juan-leon/dired-efap"))]) (dired-dups . [(20130527 2125) nil "Find duplicate files and display them in a dired buffer" single ((:commit . "694ad128c822c59348ced16c4a0c1356d43da47a") (:keywords "unix") (:authors ("Joe Bloggs" . "vapniks@yahoo.com")) (:maintainer "Joe Bloggs" . "vapniks@yahoo.com") (:url . "https://github.com/vapniks/dired-dups"))]) (dired-collapse . [(20180724 1644) ((dash (2 10 0)) (f (0 19 0)) (dired-hacks-utils (0 0 1))) "Collapse unique nested paths in dired listing" single ((:commit . "b6f3b7addefa046f22a15e72a25e4368e8a33d5e") (:keywords "files") (:authors ("Matúš Goljer" . "matus.goljer@gmail.com")) (:maintainer "Matúš Goljer" . "matus.goljer@gmail.com"))]) (dired-avfs . [(20161012 1104) ((dash (2 5 0)) (dired-hacks-utils (0 0 1))) "AVFS support for dired" single ((:commit . "b6f3b7addefa046f22a15e72a25e4368e8a33d5e") (:keywords "files") (:authors ("Matus Goljer" . "matus.goljer@gmail.com")) (:maintainer "Matus Goljer" . "matus.goljer@gmail.com"))]) (dired-atool . [(20180303 740) ((emacs (24))) "Pack/unpack files with atool on dired." single ((:commit . "b92e0106827d34fa686e189c7e9a537a3a947a8b") (:keywords "files") (:authors ("Hiroki YAMAKAWA" . "s06139@gmail.com")) (:maintainer "Hiroki YAMAKAWA" . "s06139@gmail.com") (:url . "https://github.com/HKey/dired-atool"))]) (dircmp . [(20141204 1756) nil "Compare and sync directories." tar ((:commit . "558ee0b601c2de9d247612085aafe2926f56a09f") (:keywords "unix" "tools") (:authors ("Matt McClure -- http://matthewlmcclure.com")) (:maintainer "Matt McClure -- http://matthewlmcclure.com") (:url . "https://github.com/matthewlmcclure/dircmp-mode"))]) (dionysos . [(20160810 1056) ((libmpdee (2 1 0)) (alert (1 2)) (s (1 11 0)) (dash (2 12 1)) (pkg-info (0 5 0)) (cl-lib (0 5))) "Dionysos, a music player for Emacs" tar ((:commit . "0aac21caadabc5a7f09e18a9dcb02f3dec26588b") (:keywords "music") (:authors ("Nicolas Lamirault" . "nicolas.lamirault@gmail.com")) (:maintainer "Nicolas Lamirault" . "nicolas.lamirault@gmail.com") (:url . "https://github.com/nlamirault/dionysos"))]) (dimmer . [(20180218 411) ((emacs (25))) "visually highlight the selected buffer" single ((:commit . "d033fdda154e688e45cca35902dbff9915351b98") (:keywords "faces" "editing") (:authors ("Neil Okamoto")) (:maintainer "Neil Okamoto") (:url . "https://github.com/gonewest818/dimmer.el"))]) (diminish . [(20170419 1736) nil "Diminished modes are minor modes with no modeline display" single ((:commit . "565a983a39d2e2cffab5df13b34f3b6116723208") (:keywords "extensions" "diminish" "minor" "codeprose") (:authors ("Will Mengarini" . "seldon@eskimo.com")) (:maintainer "Martin Yrjölä" . "martin.yrjola@gmail.com") (:url . "https://github.com/myrjola/diminish.el"))]) (dim-autoload . [(20180318 2027) nil "dim or hide autoload cookie lines" single ((:commit . "788320fe089fafbdf1cb09d2ab4d29d64a804e21") (:keywords "convenience") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:url . "https://github.com/tarsius/dim-autoload"))]) (dim . [(20160818 949) ((emacs (24 4))) "Change mode-line names of major/minor modes" single ((:commit . "79b81724b951fedffdd3113f473c18990af837a9") (:keywords "convenience") (:authors ("Alex Kost" . "alezost@gmail.com")) (:maintainer "Alex Kost" . "alezost@gmail.com") (:url . "https://github.com/alezost/dim.el"))]) (digitalocean-helm . [(20180610 746) ((emacs (24 3)) (helm (2 5)) (digitalocean (0 1))) "Create and manipulate digitalocean droplets" single ((:commit . "b125c9882eded7d73ec109d152b26625f333440b") (:keywords "processes" "tools") (:authors ("Oliver Marks" . "oly@digitaloctave.com")) (:maintainer "Oliver Marks" . "oly@digitaloctave.com") (:url . "https://gitlab.com/olymk2/digitalocean-api"))]) (digitalocean . [(20180603 925) ((request (2 5)) (emacs (24 4))) "Create and manipulate digitalocean droplets" single ((:commit . "1cac663c4bcb7f8325783954df6c0caf3dc20f6e") (:keywords "processes" "tools") (:authors ("Oliver Marks" . "oly@digitaloctave.com")) (:maintainer "Oliver Marks" . "oly@digitaloctave.com") (:url . "https://github.com/olymk2/emacs-digitalocean"))]) (digit-groups . [(20160817 226) ((dash (2 11 0))) "Highlight place-value positions in numbers" single ((:authors ("Michael D. Adams <http://michaeldadams.org>")) (:maintainer "Michael D. Adams <http://michaeldadams.org>") (:url . "http://bitbucket.com/adamsmd/digit-groups"))]) (digistar-mode . [(20160218 1955) nil "major mode for Digistar scripts" single ((:commit . "15288b1e1a04b79b5ab7097fdd26d48b2ff41076") (:keywords "languages") (:authors ("John Foerch" . "jjfoerch@earthlink.net")) (:maintainer "John Foerch" . "jjfoerch@earthlink.net"))]) (diffview . [(20150929 511) nil "View diffs in side-by-side format" single ((:commit . "031b70913e755c5e55222680f80185032a7d1728") (:keywords "convenience" "diff") (:authors ("Mitchel Humpherys" . "mitch.special@gmail.com")) (:maintainer "Mitchel Humpherys" . "mitch.special@gmail.com") (:url . "https://github.com/mgalgs/diffview-mode"))]) (diffscuss-mode . [(20141014 2357) nil "Major mode for diffscuss files." single ((:commit . "e0aacd8b3d9f886f27222c1397f0655e849e0af7") (:keywords "tools") (:authors ("Edmund Jorgensen" . "edmund@hut8labs.com")) (:maintainer "Edmund Jorgensen" . "edmund@hut8labs.com"))]) (difflib . [(20171227 1518) ((emacs (24 4)) (cl-generic (0 3)) (ht (2 2)) (s (1 12 0))) "Helpers for computing deltas between sequences." single ((:commit . "b08850251812d71e62fd6956081299590acdf37b") (:keywords "matching" "tools" "string") (:authors ("Diego A. Mundo" . "diegoamundo@gmail.com")) (:maintainer "Diego A. Mundo" . "diegoamundo@gmail.com") (:url . "http://github.com/dieggsy/difflib.el"))]) (diff-hl . [(20180201 1155) ((cl-lib (0 2)) (emacs (24 3))) "Highlight uncommitted changes using VC" tar ((:commit . "154c64affe7bdd16da814d198277d29bd1b6bb2a") (:keywords "vc" "diff") (:authors ("Dmitry Gutov" . "dgutov@yandex.ru")) (:maintainer "Dmitry Gutov" . "dgutov@yandex.ru") (:url . "https://github.com/dgutov/diff-hl"))]) (dictionary . [(20140718 329) ((connection (1 10)) (link (1 10))) "Client for rfc2229 dictionary servers" single ((:commit . "a23b8f4a422d0de69a006ed010eff5795319db98") (:keywords "interface" "dictionary") (:authors ("Torsten Hilbrich" . "torsten.hilbrich@gmx.net")) (:maintainer "Torsten Hilbrich" . "torsten.hilbrich@gmx.net"))]) (dictcc . [(20171213 2134) ((emacs (24 4)) (cl-lib (0 5)) (ivy (0 10 0))) "Look up translations on dict.cc" single ((:commit . "7b988413f7719820cd846827525142a23f401e50") (:keywords "convenience") (:authors ("Marten Lienen" . "marten.lienen@gmail.com")) (:maintainer "Marten Lienen" . "marten.lienen@gmail.com"))]) (dic-lookup-w3m . [(20170803 1054) ((w3m (20120723 324)) (stem (20120826))) "look up dictionaries on the Internet" tar ((:commit . "79aca5eb9c78e67cb85a386060d48113caad5ec3") (:keywords "emacs-w3m" "w3m" "dictionary") (:authors ("mcprvmec")) (:maintainer "mcprvmec"))]) (diary-manager . [(20180626 1758) ((emacs (25))) "Simple personal diary." single ((:commit . "ab7fd57de75354a9208470b45ab7bb17a26b95f4") (:keywords "extensions") (:authors ("Radon Rosborough" . "radon.neon@gmail.com")) (:maintainer "Radon Rosborough" . "radon.neon@gmail.com") (:url . "https://github.com/raxod502/diary-manager"))]) (dhall-mode . [(20180715 913) ((emacs (24 4))) "a major mode for dhall configuration language" single ((:commit . "5aa24b844ee0371024b7b65d1682984d3c1d82bf") (:keywords "languages") (:authors ("Sibi Prabakaran" . "sibi@psibi.in")) (:maintainer "Sibi Prabakaran" . "sibi@psibi.in") (:url . "https://github.com/psibi/dhall-mode"))]) (dfmt . [(20170728 1023) nil "Emacs Interface to D indenting/formatting tool dfmt." single ((:commit . "21b9094e907b7ac53f5ecb4ff4539613a9d12434") (:keywords "tools" "convenience" "languages" "dlang") (:authors ("Per Nordlöw")) (:maintainer "Kirill Babikhin <qsimpleq>") (:url . "https://github.com/qsimpleq/elisp-dfmt"))]) (devdocs . [(20170731 850) nil "Launch DevDocs search" single ((:commit . "a2d51e824f0cc48a9dd611cc740bc8b86143e611") (:authors ("Chunyang Xu" . "xuchunyang.me@gmail.com")) (:maintainer "Chunyang Xu" . "xuchunyang.me@gmail.com") (:url . "https://github.com/xuchunyang/DevDocs.el"))]) (desktop-registry . [(20140119 2143) nil "Keep a central registry of desktop files" single ((:commit . "244c2e7f9f0a1050aa8a47ad0b38f4e4584682dd") (:keywords "convenience") (:authors ("Tom Willemse" . "tom@ryuslash.org")) (:maintainer "Tom Willemse" . "tom@ryuslash.org") (:url . "http://projects.ryuslash.org/desktop-registry/"))]) (desktop-environment . [(20180423 853) ((emacs (25 1))) "Helps you control your GNU/Linux computer" single ((:commit . "62fbceded526b8e35c90803bcf80e33ebfe8473a") (:authors ("Damien Cassou" . "damien@cassou.me")) (:maintainer "Damien Cassou" . "damien@cassou.me") (:url . "https://gitlab.petton.fr/DamienCassou/desktop-environment"))]) (desktop+ . [(20170107 2132) ((emacs (24 4)) (dash (2 11 0)) (f (0 17 2))) "Handle special buffers when saving & restoring sessions" single ((:commit . "88055cee526a000056201898499cebbd35e3ea76") (:authors ("François Févotte" . "fevotte@gmail.com")) (:maintainer "François Févotte" . "fevotte@gmail.com") (:url . "https://github.com/ffevotte/desktop-plus"))]) (describe-number . [(20151101 55) ((yabin (1 1))) "Describe arbitrarily large number at point." single ((:commit . "40618345a37831804b29589849a785ef5aa5ac24") (:keywords "describe" "value" "help") (:authors ("Morten Slot Kristensen <msk AT nullpointer DOT dk>")) (:maintainer "Morten Slot Kristensen <msk AT nullpointer DOT dk>") (:url . "https://github.com/netromdk/describe-number"))]) (demo-it . [(20180404 332) nil "Create demonstrations" tar ((:commit . "4f74e6f1bb6519587303e20fe59470853b1a0352") (:keywords "demonstration" "presentation" "test") (:authors ("Howard Abrams" . "howard.abrams@gmail.com")) (:maintainer "Howard Abrams" . "howard.abrams@gmail.com"))]) (demangle-mode . [(20180516 245) ((cl-lib (0 1)) (emacs (24))) "Automatically demangle C++ symbols" single ((:commit . "a34b062c8a08d35fe2b9ee66e92f6f9626aae9a3") (:keywords "c" "tools") (:authors ("Ben Liblit" . "liblit@acm.org")) (:maintainer "Ben Liblit" . "liblit@acm.org") (:url . "https://github.com/liblit/demangle-mode"))]) (delim-kill . [(20100517 620) nil "Kill text between delimiters." single ((:commit . "1dbe47344f2d2cbc8c54beedf0cf0bf10fd203c1") (:keywords "convenience" "languages") (:authors ("Thomas Kappler" . "tkappler@gmail.com")) (:maintainer "Thomas Kappler" . "tkappler@gmail.com") (:url . "http://github.com/thomas11/delim-kill/tree/master"))]) (deft . [(20180902 1302) nil "quickly browse, filter, and edit plain text notes" single ((:commit . "9d31a92ed8407ee92cfd7102538dc9ec6c41559c") (:keywords "plain text" "notes" "simplenote" "notational velocity") (:authors ("Jason R. Blevins" . "jrblevin@xbeta.org")) (:maintainer "Jason R. Blevins" . "jrblevin@xbeta.org") (:url . "https://jblevins.org/projects/deft/"))]) (defrepeater . [(20180830 410) ((emacs (25 2)) (s (1 12 0))) "Easily make commands repeatable" single ((:commit . "62b00ede57d2e115b9ef9f21268c021ae1186873") (:keywords "convenience") (:authors ("Adam Porter" . "adam@alphapapa.net")) (:maintainer "Adam Porter" . "adam@alphapapa.net") (:url . "http://github.com/alphapapa/defrepeater.el"))]) (defproject . [(20151201 2219) ((emacs (24))) "Manager dir-locals and project specific variables" single ((:commit . "674d48a5e34cb4bba76faa38ee901322ec649086") (:keywords "convenience") (:authors (nil . "<kotfic@gmail.com>")) (:maintainer nil . "<kotfic@gmail.com>") (:url . "https://github.com/kotfic/defproject"))]) (define-word . [(20180706 2029) ((emacs (24 3))) "display the definition of word at point." single ((:commit . "637cd29837d4bd5567e17a11a479fd2edfb0e2c1") (:keywords "dictionary" "convenience") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:url . "https://github.com/abo-abo/define-word"))]) (deferred . [(20170901 1330) ((emacs (24 4))) "Simple asynchronous functions for emacs lisp" single ((:commit . "2239671d94b38d92e9b28d4e12fd79814cfb9c16") (:keywords "deferred" "async") (:authors ("SAKURAI Masashi <m.sakurai at kiwanami.net>")) (:maintainer "SAKURAI Masashi <m.sakurai at kiwanami.net>") (:url . "https://github.com/kiwanami/emacs-deferred"))]) (default-text-scale . [(20180521 649) nil "Easily adjust the font size in all frames" single ((:commit . "512d701df5e2079cad33329184fd7683c3b0b0af") (:keywords "frames" "faces") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:url . "https://github.com/purcell/default-text-scale"))]) (dedukti-mode . [(20171103 1212) nil "Major mode for Dedukti files" single ((:commit . "d7c3505a1046187de3c3aeb144455078d514594e") (:keywords "languages" "dedukti") (:authors ("Raphaël Cauderlier")) (:maintainer "Raphaël Cauderlier") (:url . "https://github.com/rafoo/dedukti-mode"))]) (dedicated . [(20090428 1931) nil "A very simple minor mode for dedicated buffers" single ((:commit . "8275fb672f9cc4ba6682ebda0ef91db827e32992") (:keywords "dedicated" "buffer") (:authors ("Eric Crampton" . "eric@atdesk.com")) (:maintainer "Eric Crampton" . "eric@atdesk.com"))]) (decl . [(20171212 1458) ((dash (2 5 0)) (emacs (24 3)) (cl-lib (0 3))) "Library for organizing code declaratively" single ((:commit . "ff7f8a4f1225cbdf141c86172104e67a4cf58c86") (:authors ("Preetpal S. Sohal")) (:maintainer "Preetpal S. Sohal") (:url . "https://github.com/preetpalS/decl.el"))]) (decide . [(20180316 1801) nil "rolling dice and other random things" single ((:commit . "257f0e39ac60ca375942950b44eeaee04cb9d961") (:authors ("Pelle Nilsson" . "perni@lysator.liu.se")) (:maintainer "Pelle Nilsson" . "perni@lysator.liu.se"))]) (debug-print . [(20140126 19) ((emacs (24))) "A nice printf debugging environment by the way Gauche do" single ((:commit . "d817fd9ea2d3f8d2c1ace4d8af155684f3a99dc5") (:keywords "extensions" "lisp" "tools" "maint") (:authors ("Ken Okada" . "keno.ss57@gmail.com")) (:maintainer "Ken Okada" . "keno.ss57@gmail.com") (:url . "https://github.com/kenoss/debug-print"))]) (debpaste . [(20160113 2347) ((xml-rpc (1 6 7))) "Interface for getting/posting/deleting pastes from paste.debian.net" single ((:commit . "6f2a400665062468ebd03a2ce1de2a73d9084958") (:keywords "paste") (:authors ("Alex Kost" . "alezost@gmail.com")) (:maintainer "Alex Kost" . "alezost@gmail.com") (:url . "http://github.com/alezost/debpaste.el"))]) (deadgrep . [(20180829 2124) ((emacs (25 1)) (dash (2 12 0)) (s (1 11 0)) (spinner (1 7 3)) (projectile (0 14 0))) "fast, friendly searching with ripgrep" single ((:commit . "260049e0df580131784989172727cc8b4eb89c2f") (:keywords "tools") (:authors ("Wilfred Hughes" . "me@wilfred.me.uk")) (:maintainer "Wilfred Hughes" . "me@wilfred.me.uk") (:url . "https://github.com/Wilfred/deadgrep"))]) (ddskk . [(20180707 532) ((ccc (1 43)) (cdb (20141201 754))) "Simple Kana to Kanji conversion program." tar ((:commit . "b05c610e27b86e71fb4e8d67292ef6a696dd5992"))]) (db-pg . [(20130131 1902) ((pg (0 12)) (db (0 0 6))) "A PostgreSQL adapter for emacs-db" single ((:commit . "7d5ab86b74b05fe003b3b434d4835f37f3f3eded") (:keywords "data" "comm" "database" "postgresql") (:authors ("Nic Ferrier" . "nic@ferrier.me.uk")) (:maintainer "Nic Ferrier" . "nic@ferrier.me.uk"))]) (db . [(20140421 2111) ((kv (0 0 11))) "A database for EmacsLisp" single ((:commit . "b3a423fb8e72f9013009cbe033d654df2ce31438") (:keywords "data" "lisp") (:authors ("Nic Ferrier" . "nferrier@ferrier.me.uk")) (:maintainer "Nic Ferrier" . "nferrier@ferrier.me.uk"))]) (dayone . [(20160105 1240) ((uuid (0 0 3)) (mustache (0 22)) (ht (1 5))) "Utility script for Day One" tar ((:commit . "ab628274f0806451f23bce16f62a6a11cbf91a2b") (:keywords "day one" "tools" "convenience") (:authors ("mori-dev" . "mori.dev.asdf@gmail.com")) (:maintainer "mori-dev" . "mori.dev.asdf@gmail.com") (:url . "https://github.com/mori-dev/emacs-dayone"))]) (datomic-snippets . [(20180817 1045) ((s (1 4 0)) (dash (1 2 0)) (yasnippet (0 6 1))) "Yasnippets for Datomic" tar ((:commit . "4a14228840d5252e13d2bf6209670f26345bbb84"))]) (datetime-format . [(20160612 1715) nil "Datetime functions" single ((:commit . "e6427538b547cbe02e1bd6ed4b765c73620bdae8") (:keywords "datetime" "calendar") (:authors ("USAMI Kenta" . "tadsan@zonu.me")) (:maintainer "USAMI Kenta" . "tadsan@zonu.me") (:url . "https://github.com/zonuexe/emacs-datetime"))]) (datetime . [(20180325 1704) ((emacs (24 1)) (extmap (1 0))) "Parsing, formatting and matching timestamps" tar ((:commit . "d8674ac11f9ebb702e5bbac10a4a6e5542958ef5") (:keywords "lisp" "i18n") (:authors ("Paul Pogonyshev" . "pogonyshev@gmail.com")) (:maintainer "Paul Pogonyshev" . "pogonyshev@gmail.com") (:url . "https://github.com/doublep/datetime"))]) (date-field . [(20141129 105) ((dash (2 9 0)) (log4e (0 2 0)) (yaxception (0 3 2))) "Date widget" single ((:commit . "11c9170d1f7b343233f7716d4c0a62be024c1654") (:keywords "widgets") (:authors ("Hiroaki Otsu" . "ootsuhiroaki@gmail.com")) (:maintainer "Hiroaki Otsu" . "ootsuhiroaki@gmail.com") (:url . "https://github.com/aki2o/emacs-date-field"))]) (date-at-point . [(20150308 1243) nil "Add `date' to `thing-at-point' function" single ((:commit . "38df823d05df08ec0748a4185113fae5f99090e9") (:keywords "convenience") (:authors ("Alex Kost" . "alezost@gmail.com")) (:maintainer "Alex Kost" . "alezost@gmail.com") (:url . "https://github.com/alezost/date-at-point.el"))]) (dashboard . [(20180902 1848) ((emacs (24 4)) (page-break-lines (0 11))) "A startup screen extracted from Spacemacs" tar ((:commit . "caef4564d50cc00b748d98f6180f26d4036cc8c6") (:keywords "startup" "screen" "tools") (:authors ("Rakan Al-Hneiti")) (:maintainer "Rakan Al-Hneiti") (:url . "https://github.com/rakanalh/emacs-dashboard"))]) (dash-functional . [(20180107 1618) ((dash (2 0 0)) (emacs (24))) "Collection of useful combinators for Emacs Lisp" single ((:commit . "85e8f62b7a8ae0b4da307ddf16e4f1c3559d0d3f") (:keywords "lisp" "functions" "combinators"))]) (dash-at-point . [(20180710 1356) nil "Search the word at point with Dash" single ((:commit . "4d795a23a8428c421d5107f1b005c9d8e0d1816c") (:authors ("Shinji Tanaka" . "shinji.tanaka@gmail.com")) (:maintainer "Shinji Tanaka" . "shinji.tanaka@gmail.com") (:url . "https://github.com/stanaka/dash-at-point"))]) (dash . [(20180903 1042) nil "A modern list library for Emacs" single ((:commit . "85e8f62b7a8ae0b4da307ddf16e4f1c3559d0d3f") (:keywords "lists") (:authors ("Magnar Sveen" . "magnars@gmail.com")) (:maintainer "Magnar Sveen" . "magnars@gmail.com"))]) (dart-mode . [(20180801 349) ((emacs (24 5)) (cl-lib (0 5)) (dash (2 10 0)) (flycheck (0 23)) (s (1 10))) "Major mode for editing Dart files" single ((:commit . "c11d02ab6a912abb675b0b7e331aca883ffbae30") (:keywords "language") (:authors ("Natalie Weizenbaum")) (:maintainer "Natalie Weizenbaum") (:url . "https://github.com/nex3/dart-mode"))]) (darktooth-theme . [(20180726 302) ((autothemer (0 2))) "From the darkness... it watches" single ((:commit . "1dfd91c46f1e66d7c25bd6974b4ae4399b7574d6") (:url . "http://github.com/emacsfodder/emacs-theme-darktooth"))]) (darkokai-theme . [(20180514 157) nil "A darker variant on Monokai." single ((:commit . "bd5efef1edd42664bb731abd398d5d71a5d2d145") (:url . "http://github.com/sjrmanning/darkokai"))]) (darkmine-theme . [(20160406 624) nil "Yet another emacs dark color theme." single ((:commit . "7f7e82ca03bcad52911fa41fb3e204e32d6ee63e") (:authors ("Pierre Lecocq" . "pierre.lecocq@gmail.com")) (:maintainer "Pierre Lecocq" . "pierre.lecocq@gmail.com") (:url . "https://github.com/pierre-lecocq/darkmine-theme"))]) (darkburn-theme . [(20170423 1652) nil "A not-so-low contrast color theme for Emacs." single ((:commit . "0af794ff7fac19778ac8a7efb92455c6f6c2158f") (:authors ("Jonas Gorauskas" . "jgorauskas@gmail.com")) (:maintainer "Jonas Gorauskas" . "jgorauskas@gmail.com") (:url . "http://github.com/gorauskas/darkburn-theme"))]) (dark-souls . [(20140314 1128) nil "Prepare to die" single ((:commit . "94122b1215423e58dcf18584a2bd022029d54d4b") (:keywords "games") (:authors ("Tom Jakubowski" . "tom@crystae.net")) (:maintainer "Tom Jakubowski" . "tom@crystae.net") (:url . "http://github.com/tomjakubowski/dark-souls.el"))]) (dark-mint-theme . [(20160302 642) nil "dark & minty fresh theme" single ((:commit . "95c30a26de31549cd341184ba9ab2be8fdc67eba"))]) (dark-krystal-theme . [(20170808 1300) ((emacs (24 0))) "an Emacs 24 theme based on Dark Krystal (tmTheme)" single ((:commit . "79084b99665dc9ffb0ec62cc092349a5ecebebbc") (:authors ("Jason Milkins")) (:maintainer "Jason Milkins") (:url . "https://github.com/emacsfodder/tmtheme-to-deftheme"))]) (darcula-theme . [(20171227 1845) nil "Inspired by IntelliJ's Darcula theme" single ((:commit . "d9b82b58ded9014985be6658f4ab17e26ed9e93e") (:keywords "faces") (:authors ("Sam Halliday" . "Sam.Halliday@gmail.com")) (:maintainer "Sam Halliday" . "Sam.Halliday@gmail.com") (:url . "https://gitlab.com/fommil/emacs-darcula-theme"))]) (darcsum . [(20140316 410) nil "a pcl-cvs like interface for managing darcs patches" tar ((:commit . "00c252b51cb24c25fb74f529960ebd631514a4c1") (:keywords "completion" "convenience" "tools" "vc") (:authors ("John Wiegley" . "johnw@gnu.org")) (:maintainer "John Wiegley" . "johnw@gnu.org"))]) (dap-mode . [(20180902 1925) ((emacs (25 1)) (dash (2 14 1)) (lsp-mode (4 0)) (dash-functional (1 2 0)) (tree-mode (1 1 1 1)) (bui (1 1 0)) (f (0 20 0)) (s (1 12 0))) "Debug Adapter Protocol mode" tar ((:commit . "235eb9f8a740303e723b145963de0e1757a7a061") (:keywords "languages" "debug") (:authors ("Ivan Yonchovski" . "yyoncho@gmail.com")) (:maintainer "Ivan Yonchovski" . "yyoncho@gmail.com") (:url . "https://github.com/yyoncho/dap-mode"))]) (dante . [(20180901 1939) ((dash (2 12 0)) (emacs (25 1)) (f (0 19 0)) (flycheck (0 30)) (haskell-mode (13 14)) (s (1 11 0)) (lcr (1 0))) "Development mode for Haskell" single ((:commit . "1419ae9cb2a97f953a6e6289923e51d827868788") (:keywords "haskell" "tools") (:authors ("Jean-Philippe Bernardy" . "jeanphilippe.bernardy@gmail.com")) (:maintainer "Jean-Philippe Bernardy" . "jeanphilippe.bernardy@gmail.com") (:url . "https://github.com/jyp/dante"))]) (danneskjold-theme . [(20180708 1424) nil "Beautiful high-contrast Emacs theme." tar ((:commit . "abc8c7fbe7ab071b8260e3355051304bb36adbd7"))]) (dakrone-theme . [(20170801 1933) nil "dakrone's custom dark theme" single ((:commit . "232ad1be5f3572dcbdf528f1655109aa355a6937") (:keywords "color" "themes") (:authors ("Lee Hinman <lee _AT_ writequit.org>")) (:maintainer "Lee Hinman <lee _AT_ writequit.org>") (:url . "https://github.com/dakrone/dakrone-theme"))]) (dakrone-light-theme . [(20170808 2140) nil "dakrone's custom light theme" single ((:commit . "06f198dc8b4ca7421990b30a23d89c8e0b8c5de4") (:keywords "color" "themes" "faces") (:authors ("Lee Hinman <lee _AT_ writequit.org>")) (:maintainer "Lee Hinman <lee _AT_ writequit.org>") (:url . "https://github.com/dakrone/dakrone-light-theme"))]) (daemons . [(20180610 1510) ((emacs (25 1))) "UI for managing init system daemons (services)" tar ((:commit . "dcf42cb3178d7245d6d49de346d5e2b44e5b7498") (:keywords "unix" "convenience") (:authors ("Chris Bowdon")) (:maintainer "Chris Bowdon") (:url . "https://github.com/cbowdon/daemons.el"))]) (dad-joke . [(20170928 658) ((emacs (24))) "Get/display dad jokes" single ((:commit . "bee47e7b746b403228fa7d7361cb095de19ac9ba") (:keywords "games") (:authors ("Dave Pearson" . "davep@davep.org")) (:maintainer "Dave Pearson" . "davep@davep.org") (:url . "https://github.com/davep/dad-joke.el"))]) (dactyl-mode . [(20140906 1725) nil "Major mode for editing Pentadactyl config files" single ((:commit . "cc55fe6b987271d9647492b8df4c812d884f661f") (:keywords "languages" "vim") (:url . "https://github.com/luxbock/dactyl-mode"))]) (d-mode . [(20180502 1410) ((emacs (24 3))) "D Programming Language major mode for (X)Emacs" single ((:commit . "026fceb78e13d67778d72d90ba83f337d0144707") (:keywords "d" "programming" "language" "emacs" "cc-mode") (:authors ("William Baxter")) (:maintainer "Russel Winder" . "russel@winder.org.uk"))]) (czech-holidays . [(20160113 1752) nil "Adds a list of Czech public holidays to Emacs calendar" single ((:commit . "d136fa09a152b3cd80db6d55c7b4ddfe07b90fbf") (:keywords "calendar") (:authors ("David Chkhikvadze" . "david.chk@outlook.com")) (:maintainer "David Chkhikvadze" . "david.chk@outlook.com"))]) (cython-mode . [(20180213 1654) nil "Major mode for editing Cython files" single ((:commit . "b1960185a2a9815009b9ab040a5bd0b4b103bf49"))]) (cypher-mode . [(20151110 1142) nil "major mode for editing cypher scripts" single ((:commit . "ce8543d7877c736c574a17b49874c9dcdc7a06d6") (:keywords "cypher" "graph") (:authors ("François-Xavier Bois <fxbois AT Google Mail Service>")) (:maintainer "François-Xavier Bois") (:url . "http://github.com/fxbois/cypher-mode"))]) (cyphejor . [(20180101 618) ((emacs (24 4))) "Shorten major mode names using user-defined rules" single ((:commit . "df449180d28691c9bdbef7bcb25aee75b2af50ca") (:keywords "mode-line" "major-mode") (:authors ("Mark Karpov" . "markkarpov92@gmail.com")) (:maintainer "Mark Karpov" . "markkarpov92@gmail.com") (:url . "https://github.com/mrkkrp/cyphejor"))]) (cycle-themes . [(20150403 309) ((cl-lib (0 5))) "A global minor mode to make switching themes easier" single ((:commit . "6e125d11fdbc6b78fc9f219eb2609a5e29815898") (:keywords "themes" "utility" "global minor mode") (:url . "http://github.com/toroidal-code/cycle-themes.el"))]) (cycle-resize . [(20160521 1557) nil "Cycle resize the current window horizontally or vertically" single ((:commit . "7d255d6fe85f12c967a0f7fcfcf18633be194c88") (:authors ("Pierre Lecocq")) (:maintainer "Pierre Lecocq") (:url . "https://github.com/pierre-lecocq/cycle-resize"))]) (cycbuf . [(20131203 2037) nil "Cycle buffers, inspired by swbuff.el, swbuff-x.el, and bs.el" single ((:commit . "1079b41c3eb27d65b66d4399959bb6253f84858e") (:keywords "files" "convenience" "buffer switching") (:authors ("Martin Pohlack martinp (at) gmx.de")) (:maintainer "Martin Pohlack martinp (at) gmx.de") (:url . "https://github.com/martinp26/cycbuf"))]) (cyberpunk-theme . [(20180609 509) nil "Cyberpunk Color Theme" single ((:commit . "f8967e46b8bdb3eaf7b72474f2d70997dc1152e9") (:keywords "color" "theme" "cyberpunk") (:authors ("Nicholas M. Van Horn" . "nvanhorn@protonmail.com")) (:maintainer "Nicholas M. Van Horn" . "nvanhorn@protonmail.com"))]) (cwl-mode . [(20171205 945) ((yaml-mode (0 0 13)) (emacs (24 4))) "A major mode for editing CWL" single ((:commit . "bdeb9c0734126f940db80bfb8b1dc735dab671c7") (:keywords "languages" "cwl" "common workflow language") (:authors ("Tomoya Tanjo" . "ttanjo@gmail.com")) (:maintainer "Tomoya Tanjo" . "ttanjo@gmail.com") (:url . "https://github.com/tom-tan/cwl-mode"))]) (cursor-test . [(20131207 1732) ((emacs (24))) "testing library for cursor position in emacs." single ((:commit . "e09956e048b88fd2ee8dd90b5678baed8b04d31b") (:authors ("ainame")) (:maintainer "ainame") (:url . "https://github.com/ainame/cursor-test.el"))]) (cuda-mode . [(20151214 321) nil "NVIDIA CUDA Major Mode" single ((:commit . "9ae9eacfdba3559b5456342d0d03296290df8ff5") (:keywords "c" "languages") (:authors ("Jack Morrison" . "jackmorrison1@gmail.com")) (:maintainer "Jack Morrison" . "jackmorrison1@gmail.com"))]) (cucumber-goto-step . [(20131210 519) ((pcre2el (1 5))) "Jump to cucumber step definition" single ((:commit . "f2713ffb26ebe1b757d1f2ea80e900b55e5895aa") (:authors ("Glen Stampoultzis" . "gstamp@gmail.com")) (:maintainer "Glen Stampoultzis" . "gstamp@gmail.com") (:url . "http://orthogonal.me"))]) (cubicle-mode . [(20171009 1957) nil "Major mode for the Cubicle model checker" single ((:commit . "c2fba597da83b9ddc1195f1c8710d5330db24735") (:authors ("Alain Mebsout")) (:maintainer "Alain Mebsout"))]) (cubicaltt . [(20171108 1402) ((emacs (24 1)) (cl-lib (0 5))) "Mode for cubical type theory" single ((:commit . "452d973fae544861090fbdea51f4f5da653fb394") (:keywords "languages") (:url . "https://github.com/mortberg/cubicaltt"))]) (ctxmenu . [(20140303 2142) ((popup (20140205 103)) (log4e (0 2 0)) (yaxception (0 1))) "Provide a context menu like right-click." tar ((:commit . "5c2376859562b98c07c985d2b483658e4c0e888e") (:keywords "popup") (:authors ("Hiroaki Otsu" . "ootsuhiroaki@gmail.com")) (:maintainer "Hiroaki Otsu" . "ootsuhiroaki@gmail.com") (:url . "https://github.com/aki2o/emacs-ctxmenu"))]) (ctl-mode . [(20151202 1006) nil "Major mode for editing GrADS script files" single ((:commit . "1a13051db21b999c7682a015b33a03096ff9d891") (:keywords "grads" "script" "major-mode") (:authors ("Joe Wielgosz" . "joew@cola.iges.org")) (:maintainer "Joe Wielgosz" . "joew@cola.iges.org"))]) (ctags-update . [(20170728 758) nil "(auto) update TAGS in parent directory using exuberant-ctags" single ((:commit . "783bf91eba1cd27cbb739067a24e15e5e04564e6") (:keywords "exuberant-ctags" "etags") (:authors (nil . "Joseph(纪秀峰)  jixiuf@gmail.com")) (:maintainer nil . "Joseph(纪秀峰)  jixiuf@gmail.com") (:url . "https://github.com/jixiuf/ctags-update"))]) (ctable . [(20171006 11) nil "Table component for Emacs Lisp" single ((:commit . "b8830d1ca95abb100a81bc32011bd17d5ecba000") (:keywords "table") (:authors ("SAKURAI Masashi <m.sakurai at kiwanami.net>")) (:maintainer "SAKURAI Masashi <m.sakurai at kiwanami.net>") (:url . "https://github.com/kiwanami/emacs-ctable"))]) (csv . [(20161113 1510) nil "Functions for reading and parsing CSV files." single ((:commit . "aa1dfa1263565d5fac3879c21d8ddf5f8915e411") (:keywords "extensions" "data" "csv") (:authors ("Ulf Jasper" . "ulf.jasper@web.de")) (:maintainer "Ulf Jasper" . "ulf.jasper@web.de"))]) (cssh . [(20150810 1709) nil "clusterssh implementation for emacs" single ((:commit . "2fe2754235225a59b63f08b130cfd4352e2e1c3f") (:keywords "clusterssh" "ssh" "cssh") (:authors ("Dimitri Fontaine" . "dim@tapoueh.org")) (:maintainer "Dimitri Fontaine" . "dim@tapoueh.org") (:url . "http://tapoueh.org/emacs/cssh.html"))]) (css-eldoc . [(20150125 323) nil "an eldoc-mode plugin for CSS source code" tar ((:commit . "c558ac4c470742c98a37290e6b409db28183df30") (:authors ("Zeno Zeng" . "zenoes@qq.com")) (:maintainer "Zeno Zeng" . "zenoes@qq.com"))]) (css-comb . [(20160416 559) nil "Sort CSS properties in a particular order using CSS Comb" single ((:commit . "6fa45e5af8a8bd3af6c1154cde3540e32c4206ee") (:authors ("Charanjit Singh" . "ckhabra@gmail.com")) (:maintainer "Charanjit Singh" . "ckhabra@gmail.com") (:url . "https://github.com/channikhabra/css-comb.el"))]) (css-autoprefixer . [(20180311 1600) ((emacs (24))) "Adds autoprefix to CSS" single ((:commit . "386a5defc8543a3b87820f1761c075c7d1d93b38") (:keywords "convenience" "usability" "css") (:authors (nil . "Kyung Mo Kweon<kkweon@gmail.com> and contributors")) (:maintainer nil . "Kyung Mo Kweon<kkweon@gmail.com> and contributors") (:url . "https://github.com/kkweon/emacs-css-autoprefixer"))]) (csound-mode . [(20180505 1925) ((emacs (25)) (shut-up (0 3 2)) (multi (2 0 1))) "A major mode for interacting and coding Csound" tar ((:commit . "5137de36e49b41ec428f35d9bfa08b5cc82e066c") (:authors ("Hlöðver Sigurðsson" . "hlolli@gmail.com")) (:maintainer "Hlöðver Sigurðsson" . "hlolli@gmail.com") (:url . "https://github.com/hlolli/csound-mode"))]) (csharp-mode . [(20180831 1024) nil "C# mode derived mode" single ((:commit . "20efdc8b9fa21fe4c297cc290c4fe68ef21d896e") (:keywords "c#" "languages" "oop" "mode") (:authors ("Dylan R. E. Moonfire (original)")) (:maintainer "Jostein Kjønigsen" . "jostein@gmail.com") (:url . "https://github.com/josteink/csharp-mode"))]) (csgo-conf-mode . [(20161209 1619) nil "CS:GO Configuration files syntax highlighting" single ((:commit . "57e7224f87a3ccc76b5564cc95fa0ff43bb6807c") (:keywords "languages") (:authors ("Guillermo Robles" . "guillerobles1995@gmail.com")) (:maintainer "Guillermo Robles" . "guillerobles1995@gmail.com") (:url . "https://github.com/wynro/emacs-csgo-conf-mode"))]) (crystal-playground . [(20180830 501) ((emacs (25)) (crystal-mode (0 1 2))) "Local crystal playground for short code snippets." single ((:commit . "532dc7e4239eb4bdd241bc4347d34760344c1ebb") (:keywords "tools" "crystal") (:authors ("Jason Howell")) (:maintainer "Jason Howell") (:url . "https://github.com/jasonrobot/crystal-playground"))]) (crystal-mode . [(20180827 329) ((emacs (24 4))) "Major mode for editing Crystal files" single ((:commit . "8649736fea8960a5e54c3ec934484f231a518ea5") (:keywords "languages" "crystal") (:url . "https://github.com/crystal-lang-tools/emacs-crystal-mode"))]) (cryptsy-public-api . [(20141008 1228) ((json (1 2))) "Library for working with the Cryptsy public API" single ((:commit . "795c204452f880c0087663e7c35faf26ea34af4d") (:keywords "cryptsy" "bitcoin" "litecoin" "dogecoin") (:authors ("Phil Newton" . "phil@sodaware.net")) (:maintainer "Phil Newton" . "phil@sodaware.net"))]) (cryptol-mode . [(20180321 1808) nil "Cryptol major mode for Emacs" single ((:commit . "91f8ad617e5db2fad57a7be1da211f22f3b51550") (:keywords "cryptol" "cryptography") (:authors (nil . "Austin Seipp <aseipp [@at] pobox [dot] com>")) (:maintainer nil . "Austin Seipp <aseipp [@at] pobox [dot] com>") (:url . "http://github.com/thoughtpolice/cryptol-mode"))]) (crux . [(20180612 655) ((seq (1 11))) "A Collection of Ridiculously Useful eXtensions" single ((:commit . "c79985f69b7cd96edb505199bd751f71ce6d4e58") (:keywords "convenience") (:authors ("Bozhidar Batsov" . "bozhidar@batsov.com")) (:maintainer "Bozhidar Batsov" . "bozhidar@batsov.com") (:url . "https://github.com/bbatsov/crux"))]) (crm-custom . [(20160117 6) ((cl-lib (0 5))) "Alternate `completing-read-multiple' that uses `completing-read'" single ((:commit . "f1aaccf64306a5f99d9bf7ba815d7ea41c15518d") (:keywords "completion" "minibuffer" "multiple elements") (:authors ("Ryan C. Thompson" . "rct@thompsonclan.org")) (:maintainer "Ryan C. Thompson" . "rct@thompsonclan.org") (:url . "https://github.com/DarwinAwardWinner/crm-custom"))]) (cricbuzz . [(20180804 2254) ((enlive (0 0 1)) (f (0 19 0)) (dash (2 13 0)) (s (1 11 0))) "Cricket scores from cricbuzz in emacs" single ((:commit . "0b95d45991bbcd2fa58d96ce921f6a57ba42c153") (:keywords "cricket" "score") (:authors ("Abhinav Tushar" . "abhinav.tushar.vs@gmail.com")) (:maintainer "Abhinav Tushar" . "abhinav.tushar.vs@gmail.com") (:url . "https://github.com/lepisma/cricbuzz.el"))]) (creole-mode . [(20130722 50) nil "a markup mode for creole" single ((:commit . "b5e79b2ec5f19fb5aacf689b5febc3e0b61515c4") (:keywords "hypermedia" "wp") (:authors ("Nic Ferrier" . "nferrier@ferrier.me.uk")) (:maintainer "Nic Ferrier" . "nferrier@ferrier.me.uk") (:url . "https://github.com/nicferrier/creole-mode"))]) (creole . [(20140924 1500) ((noflet (0 0 3)) (kv (0 0 17))) "A parser for the Creole Wiki language" single ((:commit . "7d5cffe93857f6c75ca09ac79c0e47b8d4410e53") (:keywords "lisp" "creole" "wiki") (:authors ("Nic Ferrier" . "nferrier@ferrier.me.uk")) (:maintainer "Nic Ferrier" . "nferrier@ferrier.me.uk"))]) (creds . [(20140510 1706) ((s (1 9 0)) (dash (2 5 0))) "A parser credentials file library (not limited to credentials entries)" tar ((:commit . "b059397a7d59481f05fbb1bb9c8d3c2c69226482"))]) (creamsody-theme . [(20170222 1058) ((autothemer (0 2))) "Straight from the soda fountain." single ((:commit . "32fa3f4e461da92700523b1b20e7b28974c19a26") (:url . "http://github.com/emacsfodder/emacs-theme-creamsody"))]) (crappy-jsp-mode . [(20140311 931) nil "A pretty crappy major-mode for jsp." single ((:commit . "6c45ab92b452411cc0fab9bcee2f456276b4fc40") (:keywords "jsp" "major" "mode"))]) (cquery . [(20180811 2131) ((emacs (25 1)) (lsp-mode (3 4)) (dash (0 13))) "cquery client for lsp-mode" tar ((:commit . "a803e92e77e1ffc74c13a753c1eb4f6f47127a97") (:keywords "languages" "lsp" "c++") (:authors ("Tobias Pisani")) (:maintainer "Tobias Pisani") (:url . "https://github.com/jacobdufault/cquery"))]) (cql-mode . [(20160721 339) ((emacs (24))) "Major mode for editting CQLs" single ((:commit . "2529ade55c125a89d8215f096a74733a90611c5d") (:keywords "cql" "cassandra") (:authors ("Yuki Inoue <inouetakahiroki at gmail.com>")) (:maintainer "Yuki Inoue <inouetakahiroki at gmail.com>") (:url . "https://github.com/Yuki-Inoue/cql-mode"))]) (cpputils-cmake . [(20170819 959) nil "Easy realtime C++ syntax check and IntelliSense with CMake." single ((:commit . "4fa37dd075c716f98b67b96f3b6e022730df1c1b") (:keywords "cmake" "intellisense" "flymake" "flycheck") (:authors ("Chen Bin" . "chenbin.sh@gmail.com")) (:maintainer "Chen Bin" . "chenbin.sh@gmail.com") (:url . "http://github.com/redguardtoo/cpputils-cmake"))]) (cpanfile-mode . [(20161001 710) ((emacs (24 4))) "Major mode for cpanfiles" single ((:commit . "eda675703525198df1f76ddf250bffa40217ec5d") (:keywords "perl") (:authors ("Zak B. Elep" . "zakame@zakame.net")) (:maintainer "Zak B. Elep" . "zakame@zakame.net") (:url . "https://github.com/zakame/cpanfile-mode"))]) (cp5022x . [(20120323 2335) nil "cp50220, cp50221, cp50222 coding system" single ((:commit . "ea7327dd75e54539576916f592ae1be98179ae35") (:keywords "languages" "cp50220" "cp50221" "cp50222" "cp51932" "cp932") (:authors ("ARISAWA Akihiro" . "ari@mbf.ocn.ne.jp")) (:maintainer "ARISAWA Akihiro" . "ari@mbf.ocn.ne.jp"))]) (coverlay . [(20180518 2255) ((emacs (24 1)) (cl-lib (0 5))) "Test coverage overlays" single ((:commit . "8205a845d58755dd7640b2e2b5991bf842998935") (:keywords "coverage" "overlay") (:authors ("Takuto Wada <takuto.wada at gmail com>")) (:maintainer "Takuto Wada <takuto.wada at gmail com>") (:url . "https://github.com/twada/coverlay.el"))]) (coverage . [(20180227 457) ((ov (1 0)) (cl-lib (0 5))) "Code coverage line highlighting" single ((:commit . "c73d984168955ca0f47f44b0464aa45282df42b6") (:keywords "coverage" "metrics" "simplecov" "ruby" "rspec") (:authors ("Kieran Trezona-le Comte" . "trezona.lecomte@gmail.com")) (:maintainer "Kieran Trezona-le Comte" . "trezona.lecomte@gmail.com") (:url . "https://github.com/trezona-lecomte/coverage"))]) (cov . [(20180415 2031) ((emacs (24 4)) (f (0 18 2)) (s (1 11 0)) (elquery (0))) "Show coverage stats in the fringe." single ((:commit . "7c72a949b9628296af97cc7e4df0af6c3824d66e") (:keywords "coverage" "gcov" "c") (:authors ("Adam Niederer")) (:maintainer "Adam Niederer") (:url . "https://github.com/AdamNiederer/cov"))]) (counsel-world-clock . [(20171202 737) ((ivy (0 9 0)) (s (1 12 0))) "Display world clock using Ivy." single ((:commit . "04153fbb21e51b1cfd042bdfc6ed1e8355a1edd7") (:authors ("Kuang Chen <http://github.com/kchenphy>")) (:maintainer "Kuang Chen <http://github.com/kchenphy>") (:url . "https://github.com/kchenphy/counsel-world-clock"))]) (counsel-tramp . [(20180821 941) ((emacs (24 3)) (counsel (0 10))) "Tramp ivy interface for ssh, docker, vagrant" single ((:commit . "35fd630a272a4243071a75e3bf03fa8ec6b122ef") (:authors ("Masashı Mıyaura")) (:maintainer "Masashı Mıyaura") (:url . "https://github.com/masasam/emacs-counsel-tramp"))]) (counsel-spotify . [(20180320 322) ((emacs (25)) (ivy (0 9 0))) "Control Spotify search and select music with Ivy." single ((:commit . "9033e207dccdfea7fe590d2e102d50fcd2bd22e3") (:authors ("Lautaro García <https://github.com/Lautaro-Garcia>")) (:maintainer "Lautaro García <https://github.com/Lautaro-Garcia>"))]) (counsel-pydoc . [(20171018 2042) ((emacs (24 3)) (ivy (0 9 1))) "run pydoc with counsel" single ((:commit . "1d8ff8ca3b9d69453cde423b1887fbb490a95c9e") (:keywords "completion" "matching") (:authors (nil . "Hao Deng(denghao8888@gmail.com)")) (:maintainer nil . "Hao Deng(denghao8888@gmail.com)") (:url . "https://github.com/co-dh/pydoc_utils"))]) (counsel-projectile . [(20180903 1234) ((counsel (0 10 0)) (projectile (1 0 0))) "Ivy integration for Projectile" single ((:commit . "175b4a787406ebd53e62186f1d3b46b1aed4324f") (:keywords "project" "convenience") (:authors ("Eric Danan")) (:maintainer "Eric Danan") (:url . "https://github.com/ericdanan/counsel-projectile"))]) (counsel-osx-app . [(20160821 809) ((ivy (0 8 0)) (emacs (24 3))) "launch osx applications via ivy interface" single ((:commit . "b1c54cbc033c4939966910d85ce035503079e108") (:authors ("Boris Buliga" . "d12frosted@gmail.com")) (:maintainer "Boris Buliga" . "d12frosted@gmail.com") (:url . "https://github.com/d12frosted/counsel-osx-app"))]) (counsel-org-clock . [(20180623 1317) ((emacs (24 3)) (ivy (0 10 0)) (dash (2 0))) "Counsel commands for org-clock" single ((:commit . "960c919ed730f95b740cc6b3b9c17e0e1765d7d8") (:authors ("Akira Komamura" . "akira.komamura@gmail.com")) (:maintainer "Akira Komamura" . "akira.komamura@gmail.com") (:url . "https://github.com/akirak/counsel-org-clock"))]) (counsel-org-capture-string . [(20180816 724) ((emacs (25 1)) (ivy (0 10))) "Counsel for org-capture-string" single ((:commit . "0fd5d72397a9268a89dd26de2a6c355f127453ac") (:keywords "outlines") (:authors ("Akira Komamura" . "akira.komamura@gmail.com")) (:maintainer "Akira Komamura" . "akira.komamura@gmail.com") (:url . "https://github.com/akirak/counsel-org-capture-string"))]) (counsel-notmuch . [(20180714 40) ((emacs (24)) (ivy (0 10 0)) (notmuch (0 21)) (s (1 12 0))) "Search emails in Notmuch asynchronously with Ivy" single ((:commit . "f4c864eca400abe0bb7420bcee80f2f8259ca0ff") (:keywords "mail") (:authors ("Alexander Fu Xi" . "fuxialexander@gmail.com")) (:maintainer "Alexander Fu Xi" . "fuxialexander@gmail.com") (:url . "https://github.com/fuxialexander/counsel-notmuch"))]) (counsel-gtags . [(20170326 1259) ((emacs (24 3)) (counsel (0 8 0))) "ivy for GNU global" single ((:commit . "220ebb48419ee6891ecbf9ea8fe130b494b17ee2") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-counsel-gtags"))]) (counsel-etags . [(20180807 555) ((emacs (24 4)) (counsel (0 9 1))) "Fast and complete Ctags/Etags solution using ivy" single ((:commit . "36577b7c1c23a688742e6d55eab8fe50f879d082") (:keywords "tools" "convenience") (:authors ("Chen Bin" . "chenbin.sh@gmail.com")) (:maintainer "Chen Bin" . "chenbin.sh@gmail.com") (:url . "http://github.com/redguardtoo/counsel-etags"))]) (counsel-dash . [(20160729 1529) ((emacs (24 4)) (dash (2 12 1)) (dash-functional (1 2 0)) (helm-dash (1 3 0)) (counsel (0 8 0))) "Browse dash docsets using Ivy" single ((:commit . "07fa74a94ff4da5b6c8c4810f5e143e701b480d2") (:keywords "dash" "ivy" "counsel") (:authors ("Nathan Kot" . "nk@nathankot.com")) (:maintainer "Nathan Kot" . "nk@nathankot.com") (:url . "https://github.com/nathankot/counsel-dash"))]) (counsel-css . [(20180302 1036) ((emacs (24 4)) (counsel (0 7 0)) (cl-lib (0 5))) "stylesheet-selector-aware swiper" single ((:commit . "0536af00236cdce1ed08b40dd46c917e8b4b8869") (:keywords "convenience" "tools" "counsel" "swiper" "selector" "css" "less" "scss") (:authors ("Henrik Lissner <http://github/hlissner>")) (:maintainer "Henrik Lissner" . "henrik@lissner.net") (:url . "https://github.com/hlissner/emacs-counsel-css"))]) (counsel-codesearch . [(20180713 1004) ((codesearch (1)) (counsel (0 10 0)) (emacs (24)) (ivy (0 10 0))) "Counsel interface for codesearch.el" single ((:commit . "cb9f3df541e84b4b13905c3ad3658cad2f34b0cf") (:keywords "tools") (:authors ("Austin Bingham" . "austin.bingham@gmail.com")) (:maintainer "Austin Bingham" . "austin.bingham@gmail.com") (:url . "https://github.com/abingham/emacs-counsel-codesearch"))]) (counsel-bbdb . [(20171130 137) ((ivy (0 8 0)) (emacs (24 3))) "Quick search&input email from BBDB based on ivy" single ((:commit . "c86f4b9ef99c9db0b2c4196a300d61300dc2d0c1") (:keywords "mail" "abbrev" "convenience" "matching") (:authors ("Chen Bin <chenbin.sh AT gmail>")) (:maintainer "Chen Bin <chenbin.sh AT gmail>") (:url . "https://github.com/redguard/counsel-bbdb"))]) (counsel . [(20180820 1500) ((emacs (24 3)) (swiper (0 9 0))) "Various completion functions using Ivy" single ((:commit . "02537c95baf183b6a42e142a85742d589c692aa2") (:keywords "convenience" "matching" "tools") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:url . "https://github.com/abo-abo/swiper"))]) (cosmo . [(20170922 744) ((emacs (24 4))) "Cosmological Calculator" single ((:commit . "dd83b09a49a2843606b28279b674b2207040b36b") (:keywords "tools") (:authors ("Francesco Montanari" . "fmnt@fmnt.info")) (:maintainer "Francesco Montanari" . "fmnt@fmnt.info") (:url . "https://gitlab.com/montanari/cosmo-el"))]) (corral . [(20160502 701) nil "Quickly surround text with delimiters" single ((:commit . "e7ab6aa118e46b93d4933d1364bc273f57cd6911") (:authors ("Kevin Liu" . "mail@nivekuil.com")) (:maintainer "Kevin Liu" . "mail@nivekuil.com") (:url . "http://github.com/nivekuil/corral"))]) (coq-commenter . [(20170822 2309) ((dash (2 13 0)) (s (1 11 0)) (cl-lib (0 5))) "Coq commenting minor mode for proof" single ((:commit . "7fe9a2cc0ebdb0b1e54a24eb7971d757fb588ac3") (:keywords "comment" "coq" "proof") (:authors ("Junyoung Clare Jang" . "jjc9310@gmail.com")) (:maintainer "Junyoung Clare Jang" . "jjc9310@gmail.com") (:url . "http://github.com/ailrun/coq-commenter"))]) (copyit-pandoc . [(20160624 2028) ((emacs (24)) (copyit (0 0 1)) (pandoc (0 0 1))) "Copy it, yank anything!" single ((:commit . "f50d033b129d467fb517a351adf3f16cabd82a62") (:keywords "convinience" "yank" "clipboard") (:authors ("USAMI Kenta" . "tadsan@zonu.me")) (:maintainer "USAMI Kenta" . "tadsan@zonu.me") (:url . "https://github.com/zonuexe/emacs-copyit"))]) (copyit . [(20161126 1229) ((emacs (24)) (cl-lib (0 5)) (s (1 9 0))) "Copy it, yank anything!" single ((:commit . "f50d033b129d467fb517a351adf3f16cabd82a62") (:keywords "convenience" "yank" "clipboard") (:authors ("USAMI Kenta" . "tadsan@zonu.me")) (:maintainer "USAMI Kenta" . "tadsan@zonu.me") (:url . "https://github.com/zonuexe/emacs-copyit"))]) (copy-file-on-save . [(20180604 1419) ((emacs (24 3)) (cl-lib (0 5)) (f (0 17)) (s (1 7 0))) "Copy file on save, automatic deployment it." single ((:commit . "5af6d5fcc35ddf9050eada96fd5f334bf0661b62") (:keywords "files" "comm" "deploy") (:authors ("USAMI Kenta" . "tadsan@zonu.me")) (:maintainer "USAMI Kenta" . "tadsan@zonu.me") (:url . "https://github.com/emacs-php/emacs-auto-deployment"))]) (copy-as-format . [(20171216 16) ((cl-lib (0 5))) "Copy buffer locations as GitHub/Slack/JIRA/HipChat/... formatted code" single ((:commit . "971957166fe64d914ec4be209b4f80efeeabbb19") (:keywords "github" "slack" "jira" "hipchat" "gitlab" "bitbucket" "org-mode" "pod" "rst" "asciidoc" "tools" "convenience") (:authors ("Skye Shaw" . "skye.shaw@gmail.com")) (:maintainer "Skye Shaw" . "skye.shaw@gmail.com") (:url . "https://github.com/sshaw/copy-as-format"))]) (control-mode . [(20160624 1710) nil "A \"control\" mode, similar to vim's \"normal\" mode" single ((:commit . "72d6179b60adc438aada74083b2bf4264b575de3") (:keywords "convenience" "emulations") (:authors ("Stephen Marsh" . "stephen.david.marsh@gmail.com")) (:maintainer "Stephen Marsh" . "stephen.david.marsh@gmail.com") (:url . "https://github.com/stephendavidmarsh/control-mode"))]) (contrast-color . [(20160903 1807) ((emacs (24 3)) (cl-lib (0 5))) "Pick best contrast color for you" single ((:commit . "c5fb77a211ebbef3185ada37bea7420534c33f94") (:keywords "color" "convenience") (:authors ("Yuta Yamada <cokesboy[at]gmail.com>")) (:maintainer "Yuta Yamada <cokesboy[at]gmail.com>") (:url . "https://github.com/yuutayamada/contrast-color-el"))]) (contextual-menubar . [(20180205 709) nil "display the menubar only on a graphical display" single ((:commit . "f76f55232ac07df76ef9a334a0c527dfab97c40b") (:authors ("Aaron Jensen" . "aaronjensen@gmail.com")) (:maintainer "Aaron Jensen" . "aaronjensen@gmail.com") (:url . "https://github.com/aaronjensen/contextual-menubar"))]) (contextual . [(20180726 800) ((emacs (24)) (dash (2 12 1)) (cl-lib (0 5))) "Contextual profile management system" single ((:commit . "e3c0de4a2e06757a0e8407c3c6e75930026191e3") (:keywords "convenience" "tools") (:authors ("Alexander Kahl" . "ak@sodosopa.io")) (:maintainer "Alexander Kahl" . "ak@sodosopa.io") (:url . "https://github.com/lshift-de/contextual"))]) (connection . [(20140718 329) nil "TCP-based client connection" single ((:commit . "a23b8f4a422d0de69a006ed010eff5795319db98") (:keywords "network") (:authors ("Torsten Hilbrich" . "torsten.hilbrich@gmx.net")) (:maintainer "Torsten Hilbrich" . "torsten.hilbrich@gmx.net"))]) (conllu-mode . [(20180730 1718) ((emacs (25)) (parsec (0 1)) (cl-lib (0 5))) "editing mode for CoNLL-U files" tar ((:commit . "a752e9f7a04237e70e58beba23871f8fee4fd4e3") (:keywords "extensions") (:authors ("bruno cuconato" . "bcclaro+emacs@gmail.com")) (:maintainer "bruno cuconato" . "bcclaro+emacs@gmail.com") (:url . "https://github.com/odanoburu/conllu-mode"))]) (conkeror-minor-mode . [(20150114 1604) nil "Mode for editing conkeror javascript files." single ((:commit . "476e81c27b056e21c192391fe674a2bf875466b0") (:keywords "programming" "tools") (:authors ("Artur Malabarba" . "bruce.connor.am@gmail.com>")) (:maintainer "Artur Malabarba" . "bruce.connor.am@gmail.com>") (:url . "http://github.com/Bruce-Connor/conkeror-minor-mode"))]) (confluence . [(20151021 128) ((xml-rpc (1 6 4))) "Emacs mode for interacting with confluence wikis" tar ((:commit . "4518d270a07760644c4204985c83d234ece4738b") (:keywords "confluence" "wiki" "xmlrpc") (:authors ("James Ahlborn")) (:maintainer "James Ahlborn") (:url . "http://code.google.com/p/confluence-el/"))]) (config-parser . [(20160426 1219) ((emacs (24 4))) "a library for parsing config file" single ((:commit . "85d559e7889d8f5b98b8794b79426ae25ec3caa5") (:keywords "convenience" "config") (:authors ("DarkSun" . "lujun9972@gmail.com")) (:maintainer "DarkSun" . "lujun9972@gmail.com") (:url . "https://github.com/lujun9972/el-config-parser"))]) (config-general-mode . [(20171024 1840) nil "Config::General config file mode" single ((:commit . "b4a8e6ba0bb027a77e4a0f701409f3e57bb2e4c0") (:keywords "files") (:authors ("T.v.Dein" . "tlinden@cpan.org")) (:maintainer "T.v.Dein" . "tlinden@cpan.org") (:url . "https://github.com/tlinden/config-general-mode"))]) (conda . [(20171122 1516) ((emacs (24 4)) (pythonic (0 1 0)) (dash (2 13 0)) (s (1 11 0)) (f (0 18 2))) "Work with your conda environments" single ((:commit . "0bba56d80bb959a20838a024b174d1cf1e2cfd07") (:keywords "python" "environment" "conda") (:authors ("Rami Chowdhury" . "rami.chowdhury@gmail.com")) (:maintainer "Rami Chowdhury" . "rami.chowdhury@gmail.com") (:url . "http://github.com/necaris/conda.el"))]) (concurrent . [(20161229 330) ((emacs (24 3)) (deferred (0 5 0))) "Concurrent utility functions for emacs lisp" single ((:commit . "2239671d94b38d92e9b28d4e12fd79814cfb9c16") (:keywords "deferred" "async" "concurrent") (:authors ("SAKURAI Masashi <m.sakurai at kiwanami.net>")) (:maintainer "SAKURAI Masashi <m.sakurai at kiwanami.net>") (:url . "https://github.com/kiwanami/emacs-deferred/blob/master/README-concurrent.markdown"))]) (composer . [(20180820 121) ((emacs (24)) (s (1 9 0)) (f (0 17)) (request (0 2 0)) (seq (1 9)) (php-runtime (0 1 0))) "Interface to PHP Composer" single ((:commit . "d759562626520a61cdfc358ee8081795874d2450") (:keywords "tools" "php" "dependency" "manager") (:authors ("USAMI Kenta" . "tadsan@zonu.me")) (:maintainer "USAMI Kenta" . "tadsan@zonu.me") (:url . "https://github.com/zonuexe/composer.el"))]) (composable . [(20170724 647) ((emacs (24 4))) "composable editing" tar ((:commit . "ac981974f89607393cc61314aaa19672d45b0650") (:keywords "lisp") (:authors ("Simon Friis Vindum" . "simon@vindum.io")) (:maintainer "Simon Friis Vindum" . "simon@vindum.io"))]) (company-ycmd . [(20180520 1053) ((ycmd (1 3)) (company (0 9 3)) (deferred (0 5 1)) (s (1 11 0)) (dash (2 13 0)) (let-alist (1 0 5)) (f (0 19 0))) "company-mode backend for ycmd" single ((:commit . "fe35b7f2e3d9370941b9e537c9bc578d814acce2") (:url . "https://github.com/abingham/emacs-ycmd"))]) (company-ycm . [(20140904 1817) ((ycm (0 1))) "company-ycm" single ((:commit . "4da8a14abcd0f4fa3235042ade2e12b5068c0601") (:keywords "abbrev") (:authors ("Ajay Gopinathan" . "ajay@gopinathan.net")) (:maintainer "Ajay Gopinathan" . "ajay@gopinathan.net"))]) (company-web . [(20180402 1155) ((company (0 8 0)) (dash (2 8 0)) (cl-lib (0 5 0)) (web-completion-data (0 1 0))) "Company version of ac-html, complete for web,html,emmet,jade,slim modes" tar ((:commit . "f0cc9187c9c34f72ad71f5649a69c74f996bae9a") (:keywords "html" "company") (:authors ("Olexandr Sydorchuk" . "olexandr.syd@gmail.com")) (:maintainer "Olexandr Sydorchuk" . "olexandr.syd@gmail.com") (:url . "https://github.com/osv/company-web"))]) (company-try-hard . [(20150902 2206) ((emacs (24 3)) (company (0 8 0)) (dash (2 0))) "get all completions from company backends" single ((:commit . "70b94cfc40c576af404e743133979048e1bd2610") (:keywords "matching") (:authors ("Wilfred Hughes" . "me@wilfred.me.uk")) (:maintainer "Wilfred Hughes" . "me@wilfred.me.uk"))]) (company-terraform . [(20180703 1233) ((emacs (24 4)) (company (0 8 12)) (terraform-mode (0 6))) "A company backend for terraform" tar ((:commit . "9c1146bfe23d4c461f4a59577faf4e46fcca7fe9") (:keywords "abbrev" "convenience" "terraform" "company") (:authors ("Rafał Cieślak" . "rafalcieslak256@gmail.com")) (:maintainer "Rafał Cieślak" . "rafalcieslak256@gmail.com") (:url . "https://github.com/rafalcieslak/emacs-company-terraform"))]) (company-tern . [(20161004 1847) ((company (0 8 0)) (tern (0 0 1)) (dash (2 8 0)) (dash-functional (2 8 0)) (s (1 9 0)) (cl-lib (0 5 0))) "Tern backend for company-mode" single ((:commit . "10ac058b065ae73c1f30e9fb7d969dd1a79387be") (:authors ("Artem Malyshev" . "proofit404@gmail.com")) (:maintainer "Artem Malyshev" . "proofit404@gmail.com") (:url . "https://github.com/proofit404/company-tern"))]) (company-suggest . [(20180527 1631) ((company (0 9 0)) (emacs (25 1))) "Company-mode back-end for search engine suggests" single ((:commit . "e1fa663b48639c76d91d1f5ac3b23215aa3dabc3") (:keywords "completion" "convenience") (:authors ("Jürgen Hötzel" . "juergen@archlinux.org")) (:maintainer "Jürgen Hötzel" . "juergen@archlinux.org") (:url . "https://github.com/juergenhoetzel/company-suggest"))]) (company-statistics . [(20170210 1933) ((emacs (24 3)) (company (0 8 5))) "Sort candidates using completion history" single ((:commit . "e62157d43b2c874d2edbd547c3bdfb05d0a7ae5c") (:keywords "abbrev" "convenience" "matching") (:authors ("Ingo Lohmar" . "i.lohmar@gmail.com")) (:maintainer "Ingo Lohmar" . "i.lohmar@gmail.com") (:url . "https://github.com/company-mode/company-statistics"))]) (company-sourcekit . [(20170126 1153) ((emacs (24 3)) (company (0 8 12)) (dash (2 12 1)) (dash-functional (1 2 0)) (sourcekit (0 2 0))) "company-mode completion backend for SourceKit" single ((:commit . "abf9bc5a0102eb666d3aa6d6bf22f6efcc852781") (:keywords "abbrev") (:authors ("Nathan Kot" . "nk@nathankot.com")) (:maintainer "Nathan Kot" . "nk@nathankot.com") (:url . "https://github.com/nathankot/company-sourcekit"))]) (company-solidity . [(20180407 2044) ((company (0 9 0)) (cl-lib (0 5 0)) (solidity-mode (0 1 8))) "Company-mode back-end for solidity-mode" single ((:commit . "32bfe4c8fe282c30ebf4f5cf1f9285f151c8e6d4") (:keywords "solidity" "completion" "company") (:authors ("Samuel Smolkin" . "sam@future-precedent.org")) (:maintainer "Samuel Smolkin" . "sam@future-precedent.org") (:url . "https://github.com/ethereum/emacs-solidity"))]) (company-shell . [(20170518 541) ((emacs (24 4)) (company (0 8 12)) (dash (2 12 0)) (cl-lib (0 5))) "Company mode backend for shell functions" single ((:commit . "6ae625f80d90e0779c79de38e8f83a336c1d00fa") (:keywords "company" "shell" "auto-completion") (:authors ("Alexander Miller" . "alexanderm@web.de")) (:maintainer "Alexander Miller" . "alexanderm@web.de") (:url . "https://github.com/Alexander-Miller/company-shell"))]) (company-rtags . [(20180730 338) ((emacs (24 3)) (company (0 8 1)) (rtags (2 10))) "RTags back-end for company" single ((:commit . "fc63be8f48bed6703b37ccb1057d75d7ce5200ca") (:authors ("Jan Erik Hanssen" . "jhanssen@gmail.com") ("Anders Bakken" . "agbakken@gmail.com")) (:maintainer "Jan Erik Hanssen" . "jhanssen@gmail.com") (:url . "http://rtags.net"))]) (company-restclient . [(20151202 1201) ((cl-lib (0 5)) (company (0 8 0)) (emacs (24)) (know-your-http-well (0 2 0)) (restclient (0 0 0))) "company-mode completion back-end for restclient-mode" single ((:commit . "19d819b14b7cd186a840369060963a08377d052e") (:authors ("Iku Iwasa" . "iku.iwasa@gmail.com")) (:maintainer "Iku Iwasa" . "iku.iwasa@gmail.com") (:url . "https://github.com/iquiw/company-restclient"))]) (company-reftex . [(20180713 841) ((emacs (25 1)) (s (1 12)) (company (0 8))) "Company backend based on RefTeX." single ((:commit . "d96ce340851499452c8d4d64bee80a3d7f9e9275") (:keywords "bib" "tex" "company" "latex" "reftex" "references" "labels" "citations") (:authors ("Eivind Fonn" . "evfonn@gmail.com")) (:maintainer "Eivind Fonn" . "evfonn@gmail.com") (:url . "https://github.com/TheBB/company-reftex"))]) (company-racer . [(20171205 310) ((emacs (24 4)) (cl-lib (0 5)) (company (0 8 0)) (deferred (0 3 1))) "Company integration for racer" single ((:commit . "a00381c9d416f375f783fcb6ae8d40669ce1f567") (:keywords "convenience") (:authors ("Mario Rodas" . "marsam@users.noreply.github.com")) (:maintainer "Mario Rodas" . "marsam@users.noreply.github.com") (:url . "https://github.com/emacs-pe/company-racer"))]) (company-quickhelp . [(20180525 1003) ((emacs (24 3)) (company (0 8 9)) (pos-tip (0 4 6))) "Popup documentation for completion candidates" single ((:commit . "479676cade80a9f03802ca3d956591820ed5c537") (:keywords "company" "popup" "documentation" "quickhelp") (:authors ("Lars Andersen" . "expez@expez.com")) (:maintainer "Lars Andersen" . "expez@expez.com") (:url . "https://www.github.com/expez/company-quickhelp"))]) (company-qml . [(20170428 1708) ((qml-mode (0 1)) (company (0 8 12))) "Company backend for QML files" tar ((:commit . "4af4f32a7ad86d86bb9293fb0b675aec513b5736") (:keywords "extensions") (:authors ("Junpeng Qiu" . "qjpchmail@gmail.com")) (:maintainer "Junpeng Qiu" . "qjpchmail@gmail.com"))]) (company-prescient . [(20180824 138) ((emacs (25 1)) (prescient (2 2)) (company (0 9 6))) "prescient.el + Company" single ((:commit . "1e0db9451e75f0db29668bebe98dfa747c6b4bcf") (:keywords "extensions") (:authors ("Radon Rosborough" . "radon.neon@gmail.com")) (:maintainer "Radon Rosborough" . "radon.neon@gmail.com") (:url . "https://github.com/raxod502/prescient.el"))]) (company-posframe . [(20180610 1710) ((emacs (26 0)) (company (0 9 0)) (posframe (0 1 0))) "Use a posframe as company candidate menu" single ((:commit . "47861f501891d3c67958353c25f4dce13b386c3d") (:keywords "abbrev" "convenience" "matching") (:authors ("Clément Pit-Claudel, Feng Shu")) (:maintainer "Feng Shu" . "tumashu@163.com") (:url . "https://github.com/tumashu/company-posframe"))]) (company-pollen . [(20160812 1510) ((company (0 9 0)) (pollen-mode (1 0))) "company-mode completion backend for pollen" single ((:commit . "df4eab5b490cb478a092e6bab6b07f9e2f9c6fad") (:keywords "languages" "pollen" "pollenpub" "company") (:authors ("Junsong Li <ljs.darkfish AT GMAIL>")) (:maintainer "Junsong Li") (:url . "https://github.com/lijunsong/pollen-mode"))]) (company-plsense . [(20180118 58) ((company (0 9 3)) (cl-lib (0 5 0)) (dash (2 12 0)) (s (1 12)) (emacs (24))) "Company backend for Perl" single ((:commit . "b48e3181e08ec597269621d621aa06636f02d883") (:authors ("Troy Hinckley" . "troy.hinckley@gmail.com")) (:maintainer "Troy Hinckley" . "troy.hinckley@gmail.com") (:url . "https://github.com/CeleritasCelery/company-plsense"))]) (company-php . [(20180510 2200) ((cl-lib (0 5)) (ac-php-core (1)) (company (0 9))) "company completion source for php" single ((:commit . "dcac8321b85b2ef6d43244e2b0932cb3ec7cfefb") (:keywords "completion" "convenience" "intellisense") (:authors (nil . "xcwenn@qq.com [https://github.com/xcwen]")) (:maintainer nil . "xcwenn@qq.com [https://github.com/xcwen]") (:url . "https://github.com/xcwen/ac-php"))]) (company-nixos-options . [(20160215 857) ((company (0 8 0)) (nixos-options (0 0 1)) (cl-lib (0 5 0))) "Company Backend for nixos-options" single ((:commit . "7007363e773a419203a69798fb0e0731b2eb0f73") (:keywords "unix") (:authors ("Diego Berrocal" . "cestdiego@gmail.com") ("Travis B. Hartwell" . "nafai@travishartwell.net")) (:maintainer "Diego Berrocal" . "cestdiego@gmail.com") (:url . "http://www.github.com/travisbhartwell/nix-emacs/"))]) (company-ngram . [(20170129 1913) ((cl-lib (0 5)) (company (0 8 0))) "N-gram based completion" tar ((:commit . "09a68b802e64799e95f205b438d469bbd78cd2e6") (:authors ("kshramt")) (:maintainer "kshramt") (:url . "https://github.com/kshramt/company-ngram"))]) (company-nginx . [(20180604 2) ((emacs (24))) "company-mode keywords support for nginx-mode" single ((:commit . "3074a5d322562f36867ef67bffeb25f1c0d8aca9") (:keywords "company" "nginx") (:url . "https://github.com/stardiviner/company-nginx"))]) (company-nand2tetris . [(20171201 1813) ((nand2tetris (1 1 0)) (company (0 5)) (cl-lib (0 5 0))) "Company backend for nand2tetris major mode" single ((:commit . "33acee34d24b1c6a87db833b7d23449cf858f64f") (:keywords "nand2tetris" "hdl" "company") (:authors ("Diego Berrocal" . "cestdiego@gmail.com")) (:maintainer "Diego Berrocal" . "cestdiego@gmail.com") (:url . "http://www.github.com/CestDiego/nand2tetris.el/"))]) (company-math . [(20171016 1514) ((company (0 8 0)) (math-symbol-lists (1 2))) "Completion backends for unicode math symbols and latex tags" single ((:commit . "3481f03ebb6a613ff85b71ca8edd2d5842c49012") (:keywords "unicode" "symbols" "completion") (:authors ("Vitalie Spinu")) (:maintainer "Vitalie Spinu") (:url . "https://github.com/vspinu/company-math"))]) (company-lua . [(20171108 2306) ((company (0 8 12)) (s (1 10 0)) (f (0 17 0)) (lua-mode (20151025))) "Company backend for Lua" tar ((:commit . "29f6819de4d691e5fd0b62893a9f4fbc1c6fcb52") (:authors ("Peter Vasil" . "mail@petervasil.net")) (:maintainer "Peter Vasil" . "mail@petervasil.net"))]) (company-lsp . [(20180828 438) ((emacs (25 1)) (lsp-mode (3 4)) (company (0 9 0)) (s (1 2 0)) (dash (2 11 0))) "Company completion backend for lsp-mode." single ((:commit . "82c3f1a0446060da57dffa638be873382e8efc74") (:url . "https://github.com/tigersoldier/company-lsp"))]) (company-lean . [(20171102 1454) ((emacs (24 3)) (dash (2 12 0)) (dash-functional (1 2 0)) (s (1 10 0)) (f (0 19 0)) (company (0 9 3)) (lean-mode (3 3 0))) "A company backend for lean-mode" single ((:commit . "529b8fa535cfa090a6b62566794161556ffade80") (:keywords "languages") (:authors ("Leonardo de Moura" . "leonardo@microsoft.com") ("Soonho Kong      " . "soonhok@cs.cmu.edu") ("Gabriel Ebner    " . "gebner@gebner.org") ("Sebastian Ullrich" . "sebasti@nullri.ch")) (:maintainer "Sebastian Ullrich" . "sebasti@nullri.ch") (:url . "https://github.com/leanprover/lean-mode"))]) (company-jedi . [(20151217 321) ((emacs (24)) (cl-lib (0 5)) (company (0 8 11)) (jedi-core (0 2 7))) "company-mode completion back-end for Python JEDI" single ((:commit . "2f54e791e10f5dc0ff164bfe97f1878359fab6f6") (:authors ("Boy" . "boyw165@gmail.com")) (:maintainer "Boy" . "boyw165@gmail.com"))]) (company-irony-c-headers . [(20151018 909) ((cl-lib (0 5)) (company (0 9 0)) (irony (0 2 0))) "Company mode backend for C/C++ header files with Irony" single ((:commit . "72c386aeb079fb261d9ec02e39211272f76bbd97") (:keywords "c" "company") (:authors ("Yutian Li" . "hotpxless@gmail.com")) (:maintainer "Yutian Li" . "hotpxless@gmail.com") (:url . "https://github.com/hotpxl/company-irony-c-headers"))]) (company-irony . [(20170905 2046) ((emacs (24 1)) (company (0 8 0)) (irony (1 1 0)) (cl-lib (0 5))) "company-mode completion back-end for irony-mode" single ((:commit . "52aca45bcd0f2cb0648fcafa2bbb4f8ad4b2fee7") (:keywords "convenience") (:authors ("Guillaume Papin" . "guillaume.papin@epitech.eu")) (:maintainer "Guillaume Papin" . "guillaume.papin@epitech.eu") (:url . "https://github.com/Sarcasm/company-irony/"))]) (company-inf-ruby . [(20140805 2054) ((company (0 6 10)) (inf-ruby (2 2 7)) (emacs (24 1))) "company-mode completion back-end for inf-ruby" single ((:commit . "fe3e4863bc971fbb81edad447efad5795ead1b17") (:authors ("Dmitry Gutov" . "dgutov@yandex.ru")) (:maintainer "Dmitry Gutov" . "dgutov@yandex.ru") (:url . "https://github.com/company-mode/company-inf-ruby"))]) (company-go . [(20170825 1643) ((company (0 8 0)) (go-mode (1 0 0))) "company-mode backend for Go (using gocode)" single ((:commit . "7b1d4e18cdc58a74dc1bd4c2d45b3f1b2ca227c3") (:keywords "languages") (:authors ("nsf" . "no.smile.face@gmail.com")) (:maintainer "nsf" . "no.smile.face@gmail.com"))]) (company-glsl . [(20171015 1749) ((company (0 9 4)) (glsl-mode (2 0)) (emacs (24 4))) "Support glsl in company-mode" single ((:commit . "a262c12c3bcd0807718c4edcaf2b054e30ef0e26") (:authors ("Guido Schmidt" . "git@guidoschmidt.cc")) (:maintainer "Guido Schmidt" . "git@guidoschmidt.cc") (:url . "https://github.com/guidoschmidt/company-glsl"))]) (company-ghci . [(20160311 200) ((company (0 8 11)) (haskell-mode (13))) "company backend which uses the current ghci process." single ((:commit . "c2d74a41166e76de2e78c87f582ba3a1179b2aa6") (:authors ("Hector Orellana" . "hofm92@gmail.com")) (:maintainer "Hector Orellana" . "hofm92@gmail.com"))]) (company-ghc . [(20170918 833) ((cl-lib (0 5)) (company (0 8 0)) (ghc (5 4 0 0)) (emacs (24))) "company-mode ghc-mod backend" single ((:commit . "8b264b5c3c0e42c0d0c4e9315559896c9b0edfdc") (:keywords "haskell" "completion") (:authors ("Iku Iwasa" . "iku.iwasa@gmail.com")) (:maintainer "Iku Iwasa" . "iku.iwasa@gmail.com") (:url . "https://github.com/iquiw/company-ghc"))]) (company-flx . [(20180103 518) ((emacs (24)) (company (0 8 12)) (flx (0 5))) "flx based fuzzy matching for company" single ((:commit . "16ca0d2f84e8e768bf2db8c5cfe421230a00bded") (:keywords "convenience" "company" "fuzzy" "flx") (:authors ("PythonNut" . "pythonnut@pythonnut.com")) (:maintainer "PythonNut" . "pythonnut@pythonnut.com") (:url . "https://github.com/PythonNut/company-flx"))]) (company-flow . [(20180225 2159) ((company (0 8 0)) (dash (2 13 0))) "Flow backend for company-mode" single ((:commit . "76ef585c70d2a3206c2eadf24ba61e59124c3a16") (:authors ("Aaron Jensen" . "aaronjensen@gmail.com")) (:maintainer "Aaron Jensen" . "aaronjensen@gmail.com") (:url . "https://github.com/aaronjensen/company-flow"))]) (company-erlang . [(20170123 538) ((emacs (24 4)) (ivy-erlang-complete (0 1)) (company (0 9 2))) "company backend based on ivy-erlang-complete" single ((:commit . "bc0524a16f17b66c7397690e4ca0e004f09ea6c5") (:keywords "tools") (:authors ("Sergey Kostyaev" . "feo.me@ya.ru")) (:maintainer "Sergey Kostyaev" . "feo.me@ya.ru"))]) (company-emoji . [(20161231 337) ((cl-lib (0 5)) (company (0 8 0))) "company-mode backend for emoji" tar ((:commit . "8dc88ffe0773ef44321f245d39430c14a1bc2b82") (:keywords "emoji" "company") (:authors ("Alex Dunn" . "dunn.alex@gmail.com")) (:maintainer "Alex Dunn" . "dunn.alex@gmail.com") (:url . "https://github.com/dunn/company-emoji.git"))]) (company-emacs-eclim . [(20170104 1543) ((eclim (0 3)) (company (0 7)) (cl-lib (0 5))) "company-mode backend for eclim" single ((:commit . "6396ad1cd25c0a197109343ec1cce5d5080acdff"))]) (company-edbi . [(20160221 1923) ((company (0 8 5)) (edbi (0 1 3)) (cl-lib (0 5 0)) (s (1 9 0))) "Edbi backend for company-mode" single ((:commit . "ffaeff75d0457285d16d11db772881542a6026ad") (:authors ("Artem Malyshev" . "proofit404@gmail.com")) (:maintainer "Artem Malyshev" . "proofit404@gmail.com") (:url . "https://github.com/proofit404/company-edbi"))]) (company-distel . [(20180827 1344) ((distel-completion-lib (1 0 0))) "Erlang/distel completion backend for company-mode" single ((:commit . "acc4c0a5521904203d797fe96b08e5fae4233c7e") (:keywords "erlang" "distel" "company") (:authors ("Sebastian Weddmark Olsson")) (:maintainer "Sebastian Weddmark Olsson") (:url . "github.com/sebastiw/distel-completion"))]) (company-dict . [(20180216 956) ((emacs (24 4)) (company (0 8 12)) (parent-mode (2 3))) "A backend that emulates ac-source-dictionary" single ((:commit . "7ab6331d8095e9b93c726da754102fd708c0002e") (:keywords "company" "dictionary" "ac-source-dictionary") (:authors ("Henrik Lissner <http://github/hlissner>")) (:maintainer "Henrik Lissner" . "henrik@lissner.net") (:url . "https://github.com/hlissner/emacs-company-dict"))]) (company-dcd . [(20170516 910) ((company (0 9)) (flycheck-dmd-dub (0 7)) (yasnippet (0 8)) (popwin (0 7)) (cl-lib (0 5)) (ivy (20160804 326))) "Company backend for Dlang using DCD." single ((:commit . "4832188a9e42287539a69c372fe1643166a6a7aa") (:keywords "languages") (:authors ("tsukimizake <shomasd_at_gmail.com>")) (:maintainer "tsukimizake <shomasd_at_gmail.com>") (:url . "http://github.com/tsukimizake/company-dcd"))]) (company-coq . [(20180307 1310) ((company-math (1 1)) (company (0 8 12)) (yasnippet (0 11 0)) (dash (2 12 1)) (cl-lib (0 5))) "A collection of extensions for Proof General's Coq mode" tar ((:commit . "0271b2cbea7f056d143ed248a6f32a319d33534a"))]) (company-childframe . [(20180705 546) ((emacs (26 0)) (company-posframe (0 1 0))) "Please use company-posframe instead." single ((:commit . "562eaa1e3a0c39dd36f10cda37a3724384fde1df") (:keywords "abbrev" "convenience" "matching") (:authors ("Clément Pit-Claudel, Feng Shu")) (:maintainer "Feng Shu" . "tumashu@163.com") (:url . "https://github.com/company-mode/company-mode"))]) (company-cabal . [(20170917 1317) ((cl-lib (0 5)) (company (0 8 0)) (emacs (24))) "company-mode cabal backend" tar ((:commit . "62112a7259e24bd6c08885629a185afe512b7d3d") (:authors ("Iku Iwasa" . "iku.iwasa@gmail.com")) (:maintainer "Iku Iwasa" . "iku.iwasa@gmail.com") (:url . "https://github.com/iquiw/company-cabal"))]) (company-c-headers . [(20180814 1730) ((emacs (24 1)) (company (0 8))) "Company mode backend for C/C++ header files" single ((:commit . "41331192b3961c8e3a51540678e1d11eaa346f03") (:keywords "development" "company") (:authors ("Alastair Rankine" . "alastair@girtby.net")) (:maintainer "Alastair Rankine" . "alastair@girtby.net"))]) (company-box . [(20180607 1545) ((emacs (26 0 91)) (dash (2 13)) (dash-functional (1 2 0)) (company (0 9 6))) "Company front-end with icons" tar ((:commit . "6e047e6fd7226a1b8292a74985db82bbccc679c7") (:keywords "company" "completion" "front-end" "convenience") (:authors ("Sebastien Chapuis" . "sebastien@chapu.is")) (:maintainer "Sebastien Chapuis" . "sebastien@chapu.is") (:url . "https://github.com/sebastiencs/company-box"))]) (company-bibtex . [(20171105 644) ((company (0 9 0)) (cl-lib (0 5)) (parsebib (1 0))) "Company completion for bibtex keys" single ((:commit . "da67faf3a6faba8e7f1b222dedfc5521b02c7655") (:keywords "company-mode" "bibtex") (:authors ("GB Gardner" . "gbgar@users.noreply.github.com")) (:maintainer "GB Gardner" . "gbgar@users.noreply.github.com") (:url . "https://github.com/gbgar/company-bibtex"))]) (company-axiom . [(20171024 2010) ((emacs (24)) (company (0 9)) (axiom-environment (20171021))) "A company-mode backend for the axiom-environment system" single ((:commit . "5d6b2cd12f639c11b032185c4c5fe4f5bba15b08") (:keywords "axiom" "openaxiom" "fricas" "axiom-environment") (:authors ("Paul Onions" . "paul.onions@acm.org")) (:maintainer "Paul Onions" . "paul.onions@acm.org"))]) (company-auctex . [(20180725 1912) ((yasnippet (0 8 0)) (company (0 8 0)) (auctex (11 87))) "Company-mode auto-completion for AUCTeX" single ((:commit . "48c42c58ce2f0e693301b0cb2d085055410c1b25") (:authors ("Christopher Monsanto <chris@monsan.to>, Alexey Romanov" . "alexey.v.romanov@gmail.com")) (:maintainer "Christopher Monsanto <chris@monsan.to>, Alexey Romanov" . "alexey.v.romanov@gmail.com") (:url . "https://github.com/alexeyr/company-auctex/"))]) (company-arduino . [(20160306 1739) ((emacs (24 1)) (company (0 8 0)) (irony (0 1 0)) (cl-lib (0 5)) (company-irony (0 1 0)) (company-c-headers (20140930)) (arduino-mode (1 0))) "company-mode for Arduino" single ((:commit . "d7e369702b8eee63e6dfdeba645ce28b6dc66fb1") (:keywords "convenience" "development" "company") (:authors ("Yuta Yamada" . "sleepboy.zzz@gmail.com")) (:maintainer "Yuta Yamada" . "sleepboy.zzz@gmail.com") (:url . "https://github.com/yuutayamada/company-arduino"))]) (company-ansible . [(20180701 1813) ((emacs (24 4)) (company (0 8 12))) "A company back-end for ansible" tar ((:commit . "c6dc714e3a15f89671ae5e8fe668858b20ef63e8") (:keywords "ansible") (:authors ("Krzysztof Magosa" . "krzysztof@magosa.pl")) (:maintainer "Krzysztof Magosa" . "krzysztof@magosa.pl") (:url . "https://github.com/krzysztof-magosa/company-ansible"))]) (company-anaconda . [(20180611 621) ((company (0 8 0)) (anaconda-mode (0 1 1)) (cl-lib (0 5 0)) (dash (2 6 0)) (s (1 9))) "Anaconda backend for company-mode" single ((:commit . "ef6cbe26af1ee526a38139ed21cec8569c1b989d") (:authors ("Artem Malyshev" . "proofit404@gmail.com")) (:maintainer "Artem Malyshev" . "proofit404@gmail.com") (:url . "https://github.com/proofit404/anaconda-mode"))]) (company . [(20180802 1207) ((emacs (24 3))) "Modular text completion framework" tar ((:commit . "1c768504eb0ed7c416be4f7844311b6c68f789fb") (:keywords "abbrev" "convenience" "matching") (:authors ("Nikolaj Schumacher")) (:maintainer "Dmitry Gutov" . "dgutov@yandex.ru") (:url . "http://company-mode.github.io/"))]) (common-lisp-snippets . [(20180226 1523) ((yasnippet (0 8 0))) "Yasnippets for Common Lisp" tar ((:commit . "1ddf808311ba4d9e8444a1cb50bd5ee75e4111f6") (:keywords "snippets") (:authors ("Mark Karpov" . "markkarpov92@gmail.com")) (:maintainer "Mark Karpov" . "markkarpov92@gmail.com") (:url . "https://github.com/mrkkrp/common-lisp-snippets"))]) (commify . [(20161106 2334) ((s (1 9 0))) "Toggle grouping commas in numbers" single ((:commit . "78732c2fa6c1a10288b7436d7c561ec9ebdd41be") (:keywords "convenience" "editing" "numbers" "grouping" "commas") (:authors ("Daniel E. Doherty" . "ded-commify@ddoherty.net")) (:maintainer "Daniel E. Doherty" . "ded-commify@ddoherty.net") (:url . "https://github.com/ddoherty03/commify"))]) (commenter . [(20160219 1627) ((emacs (24 4)) (let-alist (1 0 4))) "multiline-comment support package" single ((:commit . "6d1885419434ba779270c6fda0e30d390bb074bd") (:keywords "comment") (:authors ("Yuta Yamada <cokesboy\"at\"gmail.com>")) (:maintainer "Yuta Yamada <cokesboy\"at\"gmail.com>") (:url . "https://github.com/yuutayamada/commenter"))]) (commentary-theme . [(20180816 2115) ((emacs (24))) "A minimal theme with contrasting comments" single ((:commit . "1e2a64719b9d52992c6cdb91911ab313bcd69a77") (:url . "https://github.com/pzel/commentary-theme"))]) (comment-tags . [(20170910 1735) ((emacs (24 5))) "Highlight & navigate comment tags like 'TODO'." single ((:commit . "7d914097f0a03484af71e621db533737fc692f58") (:keywords "convenience" "comments" "tags") (:authors ("Vincent Dumas" . "vincekd@gmail.com")) (:maintainer "Vincent Dumas" . "vincekd@gmail.com") (:url . "https://github.com/vincekd/comment-tags"))]) (comment-dwim-2 . [(20170809 2054) nil "An all-in-one comment command to rule them all" single ((:commit . "8da8aba4cab4a0a1eef3aea2de219227526876e4") (:keywords "convenience") (:authors ("Rémy Ferré" . "dev@remyferre.net")) (:maintainer "Rémy Ferré" . "dev@remyferre.net") (:url . "https://github.com/remyferre/comment-dwim-2"))]) (commander . [(20140120 1852) ((s (1 6 0)) (dash (2 0 0)) (cl-lib (0 3)) (f (0 6 1))) "Emacs command line parser" single ((:commit . "c93985dc318fe89e5a29abc21d19fb41e2fd14d2") (:keywords "cli" "argv") (:authors ("Johan Andersson" . "johan.rejeep@gmail.com")) (:maintainer "Johan Andersson" . "johan.rejeep@gmail.com") (:url . "http://github.com/rejeep/commander.el"))]) (command-queue . [(20160328 1725) ((emacs (24 3))) "shell command queue" single ((:commit . "f327c6f852592229a755ec6de0c62c6aeafd6659") (:authors ("Yuki INOUE <inouetakahiroki at gmail.com>")) (:maintainer "Yuki INOUE <inouetakahiroki at gmail.com>") (:url . "https://github.com/Yuki-Inoue/command-queue"))]) (command-log-mode . [(20160413 447) nil "log keyboard commands to buffer" single ((:commit . "af600e6b4129c8115f464af576505ea8e789db27") (:keywords "help") (:authors ("Michael Weber" . "michaelw@foldr.org")) (:maintainer "Michael Weber" . "michaelw@foldr.org") (:url . "https://github.com/lewang/command-log-mode"))]) (comint-intercept . [(20170317 1228) ((emacs (24 3))) "Intercept input in comint-mode" single ((:commit . "a329abf01fa8e0c6b02b46b29bcb421a21120dc5") (:keywords "processes" "terminals") (:authors ("\"Huang, Ying\"" . "huang.ying.caritas@gmail.com")) (:maintainer "\"Huang, Ying\"" . "huang.ying.caritas@gmail.com") (:url . "https://github.com/hying-caritas/comint-intercept"))]) (comb . [(20180831 721) ((emacs (25 1))) "Interactive grep tool for manual static analysis" tar ((:commit . "69d59284e19428794b5c0aaa9be0e7d2770cc846") (:keywords "matching") (:authors ("Andrea Cardaci" . "cyrus.and@gmail.com")) (:maintainer "Andrea Cardaci" . "cyrus.and@gmail.com") (:url . "https://github.com/cyrus-and/comb"))]) (com-css-sort . [(20180608 108) ((emacs (24 4)) (s (1 12 0))) "Common way of sorting the CSS attributes." single ((:commit . "1564c035039a053936d186b4db7a71b34db99200") (:authors ("Shen, Jen-Chieh" . "jcs090218@gmail.com")) (:maintainer "Shen, Jen-Chieh" . "jcs090218@gmail.com") (:url . "https://github.com/jcs090218/com-css-sort"))]) (column-enforce-mode . [(20171030 1900) nil "Highlight text that extends beyond a  column" single ((:commit . "2341a2b6a33d4b8b74c35062ec9cfe1bffd61944") (:authors ("Jordon Biondo")) (:maintainer "Jordon Biondo") (:url . "www.github.com/jordonbiondo/column-enforce-mode"))]) (colormaps . [(20171008 2224) ((emacs (25))) "Hex colormaps" single ((:commit . "19fbb64a6288d505b9cf45c9b5a3eed0bfb135e2") (:keywords "tools") (:authors ("Abhinav Tushar" . "lepisma@fastmail.com")) (:maintainer "Abhinav Tushar" . "lepisma@fastmail.com") (:url . "https://github.com/lepisma/colormaps.el"))]) (color-theme-x . [(20180227 46) ((cl-lib (0 5))) "convert color themes to X11 resource settings" single ((:commit . "6c2264aa6c5d9a72caeae67ebaa4472090e70350") (:keywords "convenience" "faces" "frames") (:authors ("Matthew Kennedy" . "mkennedy@killr.ath.cx")) (:maintainer "Andrew Johnson" . "andrew@andrewjamesjohnson.com") (:url . "https://github.com/ajsquared/color-theme-x"))]) (color-theme-solarized . [(20171024 1525) ((color-theme (6 5 5))) "Solarized themes for Emacs" tar ((:commit . "f3ca8902ea056fb8e46cb09f09c96294e31cd4ee"))]) (color-theme-sanityinc-tomorrow . [(20180804 1045) nil "A version of Chris Kempson's \"tomorrow\" themes" tar ((:commit . "f45776485147b92fee9e09eaf99f91c2d4970098") (:keywords "faces" "themes") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:url . "http://github.com/purcell/color-theme-sanityinc-tomorrow"))]) (color-theme-sanityinc-solarized . [(20160430 203) nil "A version of Ethan Schoonover's Solarized themes" tar ((:commit . "6dd1d67a8e88a7bd586572cabe519b99a90fc3ee") (:keywords "themes") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:url . "http://github.com/purcell/color-theme-sanityinc-solarized"))]) (color-theme-modern . [(20161219 1144) ((emacs (24))) "Reimplement colortheme with Emacs 24 theme framework." tar ((:commit . "42a79266f1d7b473e9328e67a455e505e6c3eff5") (:url . "https://github.com/emacs-jp/replace-colorthemes/"))]) (color-theme-buffer-local . [(20170126 601) ((color-theme (0))) "Install color-themes by buffer." single ((:commit . "e606dec66f16a06140b9aad625a4fd52bca4f936") (:keywords "faces") (:authors ("Victor Borja" . "vic.borja@gmail.com")) (:maintainer "Victor Borja" . "vic.borja@gmail.com") (:url . "http://github.com/vic/color-theme-buffer-local"))]) (color-theme-approximate . [(20140228 436) nil "Makes Emacs theme works on terminal transparently" single ((:commit . "f54301ca39bc5d2ffb000f233f8114184a3e7d71") (:authors ("Tung Dao" . "me@tungdao.com")) (:maintainer "Tung Dao" . "me@tungdao.com"))]) (color-theme . [(20080305 834) nil "install color themes" tar ((:commit . "eeb07560b30aaf7934dfd21f5c2518a479905cd9") (:keywords "faces") (:authors ("Jonadab the Unsightly One" . "jonadab@bright.net")) (:maintainer "Xavier Maillard" . "zedek@gnu.org") (:url . "http://www.emacswiki.org/cgi-bin/wiki.pl?ColorTheme"))]) (color-moccur . [(20141223 35) nil "multi-buffer occur (grep) mode" single ((:commit . "4f1c59ffd1ccc2ab1a171cd6b721e8cb9e002fb7") (:keywords "convenience") (:url . "http://www.bookshelf.jp/elc/color-moccur.el"))]) (color-identifiers-mode . [(20180504 1626) ((dash (2 5 0)) (emacs (24))) "Color identifiers based on their names" single ((:commit . "60ae3ab0fdffe0efae7e08950d7b2a96f4ea49e2") (:keywords "faces" "languages") (:authors ("Ankur Dave" . "ankurdave@gmail.com")) (:maintainer "Ankur Dave" . "ankurdave@gmail.com") (:url . "https://github.com/ankurdave/color-identifiers-mode"))]) (colonoscopy-theme . [(20170808 1309) ((emacs (24 0))) "an Emacs 24 theme based on Colonoscopy (tmTheme)" single ((:commit . "64bbb322b13dae91ce9f1e3581f836f94f800ead") (:authors ("Jason Milkins")) (:maintainer "Jason Milkins") (:url . "https://github.com/emacsfodder/tmtheme-to-deftheme"))]) (colemak-evil . [(20171015 2307) ((evil (20170323 1140))) "Colemak-friendly keybindings for Evil." single ((:commit . "192c779281ae1fbf2405dcdb55b3c5b2a1d0b3d1") (:authors ("Patrick Brinich-Langlois" . "pbrinichlanglois@gmail.com")) (:maintainer "Patrick Brinich-Langlois" . "pbrinichlanglois@gmail.com") (:url . "https://github.com/patbl/colemak-evil"))]) (coin-ticker . [(20170611 727) ((request (0 3 0)) (emacs (25))) "Show a cryptocurrency price ticker" single ((:commit . "9efab90fe4e6f29464af14e0d8fd1e20c0147b80") (:keywords "news") (:authors ("Evan Klitzke" . "evan@eklitzke.org")) (:maintainer "Evan Klitzke" . "evan@eklitzke.org") (:url . "https://github.com/eklitzke/coin-ticker-mode"))]) (coffee-mode . [(20170324 940) ((emacs (24 3))) "Major mode for CoffeeScript code" single ((:commit . "86ab8aae8662e8eff54d3013010b9c693b16eac5") (:keywords "coffeescript" "major" "mode") (:authors ("Chris Wanstrath" . "chris@ozmm.org")) (:maintainer "Chris Wanstrath" . "chris@ozmm.org") (:url . "http://github.com/defunkt/coffee-mode"))]) (coffee-fof . [(20131012 1230) ((coffee-mode (0 4 1))) "A coffee-mode configuration for `ff-find-other-file'." single ((:commit . "211529594bc074721c6cbc4edb73a63cc05f89ac") (:keywords "coffee-mode") (:authors ("Yasuyki Oka" . "yasuyk@gmail.com")) (:maintainer "Yasuyki Oka" . "yasuyk@gmail.com") (:url . "http://github.com/yasuyk/coffee-fof"))]) (codic . [(20150926 1127) ((emacs (24)) (cl-lib (0 5))) "Search Codic (codic.jp) naming dictionaries" tar ((:commit . "52bbb6997ef4ab9fb7fea43bbfff7f04671aa557") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-codic"))]) (codesearch . [(20180508 1522) ((elog (0 1))) "Core support for managing codesearch tools" tar ((:commit . "b6452c87d8405f37a65ce9320e59422733580bbe") (:keywords "tools" "development" "search") (:authors ("Austin Bingham" . "austin.bingham@gmail.com") ("Youngjoo Lee" . "youngker@gmail.com")) (:maintainer "Austin Bingham" . "austin.bingham@gmail.com") (:url . "https://github.com/abingham/emacs-codesearch"))]) (codebug . [(20140929 2137) nil "Interact with codebug" single ((:commit . "ac0e4331ba94ccb5203fa492570e1ca6b90c3d52") (:authors ("Shane Dowling")) (:maintainer "Shane Dowling") (:url . "http://www.shanedowling.com/"))]) (code-stats . [(20180810 1242) ((emacs (25)) (request (0 3 0))) "Code::Stats plugin" single ((:commit . "8ffa1a24206565fe52abec1f1f0458fa3adb253f") (:authors ("Xu Chunyang" . "mail@xuchunyang.me")) (:maintainer "Xu Chunyang" . "mail@xuchunyang.me") (:url . "https://github.com/xuchunyang/code-stats-emacs"))]) (code-library . [(20160426 1218) ((gist (1 3 1))) "use org-mode to collect code snippets" single ((:commit . "32d59c5c845d6dbdda18f9bd1c03a58d55417fc5") (:keywords "lisp" "code") (:authors ("DarkSun" . "lujun9972@gmail.com")) (:maintainer "DarkSun" . "lujun9972@gmail.com"))]) (code-archive . [(20180706 213) ((emacs (24 3))) "git supported code archive and reference for org-mode" single ((:commit . "bc51428d2761dedc20bca1014cc2760b3af87e0e") (:authors ("Michael Schuldt" . "mbschuldt@gmail.com")) (:maintainer "Michael Schuldt" . "mbschuldt@gmail.com") (:url . "https://github.com/mschuldt/code-archive"))]) (cobra-mode . [(20140116 2116) nil "Major mode for .NET-based Cobra language" single ((:commit . "acd6e53f6286af5176471d01f25257e5ddb6dd01") (:keywords "languages") (:authors ("Taylor \"Nekroze\" Lawson")) (:maintainer "Taylor \"Nekroze\" Lawson") (:url . "http://github.com/Nekroze/cobra-mode"))]) (cobalt . [(20180304 1155) ((emacs (24))) "Easily use the Cobalt.rs static site generator" single ((:commit . "634ace275697e188746ca22a30ff94380ec756be") (:keywords "convenience") (:authors ("Juan Karlo Licudine" . "accidentalrebel@gmail.com")) (:maintainer "Juan Karlo Licudine" . "accidentalrebel@gmail.com") (:url . "https://github.com/cobalt-org/cobalt.el"))]) (cnfonts . [(20180830 2128) ((emacs (24))) "A simple Chinese fonts config tool" tar ((:commit . "6d07b14e5c04033966056dd231047f110ce925c0") (:keywords "convenience" "chinese" "font") (:authors ("Feng Shu" . "tumashu@163.com")) (:maintainer "Feng Shu" . "tumashu@163.com") (:url . "https://github.com/tumashu/cnfonts"))]) (cmm-mode . [(20150225 746) nil "Major mode for C-- source code" single ((:commit . "c3ad514dff3eb30434f6b20d953276d4c00de1ee"))]) (cmd-to-echo . [(20161203 2133) ((emacs (24 4)) (s (1 11 0)) (shell-split-string (20151224 208))) "Show the output of long-running commands in the echo area" single ((:commit . "e0e874fc0e1ad6d291e39ed76023445297ad438a") (:authors ("Tijs Mallaerts" . "tijs.mallaerts@gmail.com")) (:maintainer "Tijs Mallaerts" . "tijs.mallaerts@gmail.com"))]) (cmake-project . [(20171121 1115) nil "Integrates CMake build process with Emacs" single ((:commit . "d3f408f226eff3f77f7e00dd519f4efc78fd292d") (:keywords "c" "cmake" "languages" "tools") (:authors ("Alexander Lamaison" . "alexander.lamaison@gmail")) (:maintainer "Alexander Lamaison" . "alexander.lamaison@gmail") (:url . "http://github.com/alamaison/emacs-cmake-project"))]) (cmake-mode . [(20180709 1426) nil "major-mode for editing CMake sources" single ((:commit . "612975c6652c83c29fcfcf56a7b5a0cfe0218c93"))]) (cmake-ide . [(20180713 1513) ((emacs (24 4)) (cl-lib (0 5)) (seq (1 11)) (levenshtein (0)) (s (1 11 0))) "Calls CMake to find out include paths and other compiler flags" single ((:commit . "249865f53389fa6e74342e73c35eb6d9f332f815") (:keywords "languages") (:authors ("Atila Neves" . "atila.neves@gmail.com")) (:maintainer "Atila Neves" . "atila.neves@gmail.com") (:url . "http://github.com/atilaneves/cmake-ide"))]) (cmake-font-lock . [(20170117 2025) ((cmake-mode (0 0))) "Advanced, type aware, highlight support for CMake" single ((:commit . "8be491b4b13338078e524e2fe6213c93e18a101e") (:keywords "faces" "languages") (:authors ("Anders Lindgren")) (:maintainer "Anders Lindgren") (:url . "https://github.com/Lindydancer/cmake-font-lock"))]) (cm-mode . [(20170203 2107) ((cl-lib (0 5))) "Minor mode for CriticMarkup" single ((:commit . "276d49c859822265070ae5dfbb403fd7d8d06436") (:keywords "text" "markdown") (:authors ("Joost Kremers" . "joostkremers@fastmail.fm")) (:maintainer "Joost Kremers" . "joostkremers@fastmail.fm"))]) (clues-theme . [(20161213 1127) ((emacs (24 0))) "an Emacs 24 theme which may well be fully awesome..." single ((:commit . "abd61f2b7f3e98de58ca26e6d1230e70c6406cc7") (:authors ("Jason Milkins" . "jasonm23@gmail.com")) (:maintainer "Jason Milkins" . "jasonm23@gmail.com") (:url . "https://github.com/emacsfodder/emacs-clues-theme"))]) (cloud-to-butt-erc . [(20130627 2308) nil "Replace 'the cloud' with 'my butt'" single ((:commit . "6710c03d1bc91736435cbfe845924940cae34e5c") (:authors ("David Leatherman" . "leathekd@gmail.com")) (:maintainer "David Leatherman" . "leathekd@gmail.com") (:url . "http://www.github.com/leathekd/cloud-to-butt-erc"))]) (closure-lint-mode . [(20101118 2124) nil "minor mode for the Closure Linter" single ((:commit . "bc3d2fd5c35580bf1b8af43b12484c95a343b4b5") (:keywords "tools" "closure" "javascript" "lint" "flymake") (:authors ("Roman Scherer" . "roman@burningswell.com")) (:maintainer "Roman Scherer" . "roman@burningswell.com") (:url . "https://github.com/r0man/closure-lint-mode"))]) (closql . [(20180808 441) ((emacs (25 1)) (emacsql-sqlite (2 0 3))) "store EIEIO objects using EmacSQL" single ((:commit . "edb441335b98c71516046cfe8d2c8c1c2cfd8c5a") (:keywords "extensions") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:url . "https://github.com/emacscollective/closql"))]) (clomacs . [(20180901 1941) ((emacs (24 3)) (cider (0 17 0)) (s (1 12 0)) (simple-httpd (1 4 6))) "Simplifies Emacs Lisp interaction with Clojure." single ((:commit . "7b63b802318e3bcae1591f868b2493246cc98310") (:keywords "clojure" "interaction") (:authors ("Kostafey" . "kostafey@gmail.com")) (:maintainer "Kostafey" . "kostafey@gmail.com") (:url . "https://github.com/clojure-emacs/clomacs"))]) (clojure-snippets . [(20180314 1308) ((yasnippet (0 10 0))) "Yasnippets for clojure" tar ((:commit . "6068dca90467a0f4ebc2cd39338a173d6f5ddc04"))]) (clojure-quick-repls . [(20150814 736) ((cider (0 8 1)) (dash (2 9 0))) "Quickly create Clojure and ClojureScript repls for a project." single ((:commit . "730311dd3ac4e0aceb0204f818b422017873467f") (:keywords "languages" "clojure" "cider" "clojurescript") (:url . "https://github.com/symfrog/clojure-quick-repls"))]) (clojure-mode-extra-font-locking . [(20180114 1711) ((clojure-mode (3 0))) "Extra font-locking for Clojure mode" single ((:commit . "aecb12973d2b090f8675e8926d77a68269be55a2") (:keywords "languages" "lisp") (:authors ("Bozhidar Batsov" . "bozhidar@batsov.com")) (:maintainer "Bozhidar Batsov" . "bozhidar@batsov.com") (:url . "http://github.com/clojure-emacs/clojure-mode"))]) (clojure-mode . [(20180827 1827) ((emacs (25 1))) "Major mode for Clojure code" single ((:commit . "aecb12973d2b090f8675e8926d77a68269be55a2") (:keywords "languages" "clojure" "clojurescript" "lisp") (:url . "http://github.com/clojure-emacs/clojure-mode"))]) (clojure-cheatsheet . [(20180201 804) ((helm (1 7 7)) (cider (0 9 0))) "The Clojure Cheatsheet for Emacs" single ((:commit . "85c382317a56bbdfac03ae95999c28fc0cde65d7") (:keywords "clojure" "cider" "cheatsheet" "helm") (:authors ("Kris Jenkins" . "krisajenkins@gmail.com")) (:maintainer "Kris Jenkins" . "krisajenkins@gmail.com") (:url . "https://github.com/clojure-emacs/clojure-cheatsheet"))]) (clojars . [(20180825 1951) ((request-deferred (0 2 0))) "clojars.org search interface" single ((:commit . "696c5b056e45067512a7d6dcce2515f3c639f61b") (:keywords "docs" "help" "tools") (:authors ("Joshua Miller" . "josh@joshmiller.io")) (:maintainer "Joshua Miller" . "josh@joshmiller.io") (:url . "https://github.com/joshuamiller/clojars.el"))]) (clocker . [(20160125 2305) ((projectile (0 11 0)) (dash (2 10))) "Note taker and clock-in enforcer" single ((:commit . "4a4831ed4e42e18976edd16b844cb16cb78f3c17") (:keywords "org") (:authors ("Roman Gonzalez" . "romanandreg@gmail.com")) (:maintainer "Roman Gonzalez" . "romanandreg@gmail.com"))]) (cloc . [(20170728 1824) ((cl-lib (0 5))) "count lines of code over emacs buffers" single ((:commit . "f30f0472e465cc8d433d2473e9d3b8dfe2c94491") (:keywords "cloc" "count" "source" "code" "lines") (:authors ("Danny McClanahan" . "danieldmcclanahan@gmail.com")) (:maintainer "Danny McClanahan" . "danieldmcclanahan@gmail.com") (:url . "https://github.com/cosmicexplorer/cloc-emacs"))]) (clmemo . [(20160326 1623) nil "Change Log MEMO" tar ((:commit . "846a81b984d71edf8278a4d9f9b886e44d5b8365") (:keywords "convenience") (:authors ("Masayuki Ataka" . "masayuki.ataka@gmail.com")) (:maintainer "Masayuki Ataka" . "masayuki.ataka@gmail.com") (:url . "https://github.com/ataka/clmemo"))]) (cljsbuild-mode . [(20160402 1700) nil "A minor mode for the ClojureScript 'lein cljsbuild' command" single ((:commit . "fa2315660cb3ce944b5e16c679dcf5afd6a97f4c") (:keywords "clojure" "clojurescript" "leiningen" "compilation") (:url . "http://github.com/kototama/cljsbuild-mode"))]) (cljr-helm . [(20160913 828) ((clj-refactor (0 13 0)) (helm-core (1 7 7)) (cl-lib (0 5))) "Wraps clojure refactor commands with helm" single ((:commit . "f2fc7b698a56e4a44d5dfbc6a55d77a93c0fa9a4") (:keywords "helm" "clojure" "refactor") (:authors ("Phil Jackson" . "phil@shellarchive.co.uk")) (:maintainer "Phil Jackson" . "phil@shellarchive.co.uk") (:url . "https://github.com/philjackson/cljr-helm"))]) (clj-refactor . [(20180826 2149) ((emacs (25 1)) (seq (2 19)) (yasnippet (0 6 1)) (paredit (24)) (multiple-cursors (1 2 2)) (clojure-mode (5 6 1)) (cider (0 17 0)) (edn (1 1 2)) (inflections (2 3)) (hydra (0 13 2))) "A collection of commands for refactoring Clojure code" tar ((:commit . "ec158357c4f7a375bc47f89de71ea28028a3bfa0") (:keywords "convenience" "clojure" "cider") (:authors ("Magnar Sveen" . "magnars@gmail.com") ("Lars Andersen" . "expez@expez.com") ("Benedek Fazekas" . "benedek.fazekas@gmail.com")) (:maintainer "Magnar Sveen" . "magnars@gmail.com"))]) (clips-mode . [(20170909 823) nil "Major mode for editing CLIPS code and REPL" tar ((:commit . "dd38e2822640a38f7d8bfec4f69d8dd24be27074"))]) (clippy . [(20161028 1954) ((pos-tip (1 0))) "Show tooltip with function documentation at point" single ((:commit . "ad4b5dba4cede6d4b21533186303d3d3e9a2510f") (:keywords "docs") (:authors ("Matus Goljer" . "matus.goljer@gmail.com")) (:maintainer "Matus Goljer" . "matus.goljer@gmail.com") (:url . "https://github.com/Fuco1/clippy.el"))]) (clipmon . [(20180129 1054) nil "Clipboard monitor - watch system clipboard, add changes to kill ring/autoinsert" tar ((:commit . "95dc56c7ed84a654ec90f4740eb6df1050de8cf1") (:keywords "convenience") (:authors ("Brian Burns" . "bburns.km@gmail.com")) (:maintainer "Brian Burns" . "bburns.km@gmail.com") (:url . "https://github.com/bburns/clipmon"))]) (cliphist . [(20171113 538) ((emacs (24 3)) (ivy (0 9 0))) "Read data from clipboard managers at Linux and Mac" tar ((:commit . "e454254f8bd9dbaea28e95c786d7297a2d4e920a") (:keywords "clipboard" "manager" "history") (:authors ("Chen Bin <chenin DOT sh AT gmail DOT com>")) (:maintainer "Chen Bin <chenin DOT sh AT gmail DOT com>") (:url . "http://github.com/redguardtoo/cliphist"))]) (click-mode . [(20180611 44) ((emacs (24))) "Major mode for the Click Modular Router Project" single ((:commit . "b94ea8cce89cf0e753b2ab915202d49ffc470fb6") (:keywords "click" "router") (:authors ("Brian Malehorn" . "bmalehorn@gmail.com")) (:maintainer "Brian Malehorn" . "bmalehorn@gmail.com") (:url . "https://github.com/bmalehorn/click-mode"))]) (clevercss . [(20131229 155) nil "A major mode for editing CleverCSS files" single ((:commit . "b8a3c0dd674367c62b1a1ffec84d88fe0c0219bc") (:keywords "languages" "css") (:authors ("Joe Schafer" . "joesmoe10@gmail.com")) (:maintainer "Joe Schafer" . "joesmoe10@gmail.com"))]) (clear-text . [(20160406 2043) nil "Make you use clear text" tar ((:commit . "b50669b6077d6948f72cb3c649281d206e0c2f2b") (:keywords "convenience") (:authors ("Chunyang Xu" . "xuchunyang56@gmail.com")) (:maintainer "Chunyang Xu" . "xuchunyang56@gmail.com") (:url . "https://github.com/xuchunyang/clear-text.el"))]) (clean-buffers . [(20160529 2259) ((cl-lib (0 5))) "clean useless buffers" single ((:commit . "1be6c54e3095761b6b64bf749faae3dfce94e72a") (:keywords "convenience" "usability" "buffers") (:authors ("DarkSun" . "lujun9972@gmail.com")) (:maintainer "DarkSun" . "lujun9972@gmail.com"))]) (clean-aindent-mode . [(20171017 2043) nil "Simple indent and unindent, trims indent white-space" single ((:commit . "a97bcae8f43a9ff64e95473e4ef0d8bafe829211") (:keywords "indentation" "whitespace" "backspace") (:authors ("peter marinov" . "efravia@gmail.com")) (:maintainer "peter marinov" . "efravia@gmail.com") (:url . "https://github.com/pmarinov/clean-aindent-mode"))]) (clang-format . [(20180406 1514) ((cl-lib (0 3))) "Format code using clang-format" single ((:commit . "3620b76c6657a53d0c5033e6a05e6104541ebc7d") (:keywords "tools" "c"))]) (cl-lib-highlight . [(20140127 2112) ((cl-lib (0 3))) "full cl-lib font-lock highlighting" single ((:commit . "fd1b308e6e989791d1df14438efa6b77d20f7c7e") (:authors ("Christopher Wellons" . "wellons@nullprogram.com")) (:maintainer "Christopher Wellons" . "wellons@nullprogram.com") (:url . "https://github.com/skeeto/cl-lib-highlight"))]) (cl-format . [(20160413 45) nil "CL format routine." tar ((:commit . "4380cb8009c47cc6d9098b383082b93b1aefa460"))]) (citeproc . [(20180429 757) ((emacs (25)) (dash (2 13 0)) (s (1 12 0)) (f (0 18 0)) (queue (0 2)) (string-inflection (1 0)) (org (9))) "A CSL 1.0.1 Citation Processor" tar ((:commit . "44f147d228d2d652cdd404d31e987e14519c3eef") (:keywords "bib") (:authors ("András Simonyi" . "andras.simonyi@gmail.com")) (:maintainer "András Simonyi" . "andras.simonyi@gmail.com") (:url . "https://github.com/andras-simonyi/citeproc-el"))]) (circe-notifications . [(20180102 2318) ((emacs (24 4)) (circe (2 3)) (alert (1 2))) "Add desktop notifications to Circe." single ((:commit . "291149ac12877bbd062da993479d3533a26862b0") (:authors ("Ruben Maher" . "r@rkm.id.au")) (:maintainer "Ruben Maher" . "r@rkm.id.au") (:url . "https://github.com/eqyiel/circe-notifications"))]) (circe . [(20180525 1231) ((cl-lib (0 5))) "Client for IRC in Emacs" tar ((:commit . "fedfa7eb8516a53fa70b6a1f4fce4b5ab66ea91f") (:url . "https://github.com/jorgenschaefer/circe"))]) (circadian . [(20180708 1343) ((emacs (24 4))) "Theme-switching based on daytime" single ((:commit . "9894361dcd6ffb6d4629b4cbbabda2153699eb8e") (:keywords "themes") (:authors ("Guido Schmidt")) (:maintainer "Guido Schmidt" . "git@guidoschmidt.cc") (:url . "https://github.com/GuidoSchmidt/circadian"))]) (cinspect . [(20150716 233) ((emacs (24)) (cl-lib (0 5)) (deferred (0 3 1)) (python-environment (0 0 2))) "Use cinspect to look at the CPython source of builtins and other C objects!" single ((:commit . "4e199a90f89b335cccda1518aa0963e0a1d4fbab") (:keywords "python") (:authors ("Ben Yelsey" . "ben.yelsey@gmail.com")) (:maintainer "Ben Yelsey" . "ben.yelsey@gmail.com") (:url . "https://github.com/inlinestyle/cinspect-mode"))]) (cil-mode . [(20160622 1430) nil "Common Intermediate Language mode" single ((:commit . "a78a88ca9a66a82f069329a96e34b67478ae2d9b") (:keywords "languages") (:authors ("Friedrich von Never" . "friedrich@fornever.me")) (:maintainer "Friedrich von Never" . "friedrich@fornever.me") (:url . "https://github.com/ForNeVeR/cil-mode"))]) (ciel . [(20170330 1226) ((emacs (24))) "A command that is clone of \"ci\" in vim." single ((:commit . "8c73f78d60ef52d3c395a9629963a63439b8a83e") (:keywords "convinience") (:authors ("Takuma Matsushita" . "cs14095@gmail.com")) (:maintainer "Takuma Matsushita" . "cs14095@gmail.com") (:url . "https://github.com/cs14095/ciel.el"))]) (cider-spy . [(20160313 1440) ((emacs (24 4)) (cider (0 10 0)) (dash (2 5 0)) (cl-lib (0 5)) (noflet (0 0 15))) "Spy on CIDER to get info" single ((:commit . "0224608d240e9900e588b6df049c2a87c24fc936") (:keywords "languages" "clojure" "cider" "nrepl") (:authors ("Jon Pither" . "jon.pither@gmail.com")) (:maintainer "Jon Pither" . "jon.pither@gmail.com") (:url . "http://www.github.com/jonpither/cider-spy"))]) (cider-hydra . [(20161019 554) ((cider (0 14 0)) (hydra (0 13 0))) "Hydras for CIDER." single ((:commit . "6bb341143fe16f12be2262b2bcd003a246962676") (:keywords "convenience" "tools") (:authors ("Tianxiang Xiong" . "tianxiang.xiong@gmail.com")) (:maintainer "Tianxiang Xiong" . "tianxiang.xiong@gmail.com") (:url . "https://github.com/clojure-emacs/cider-hydra"))]) (cider-eval-sexp-fu . [(20160907 800) ((emacs (24)) (highlight (0)) (eval-sexp-fu (0 4 0))) "Briefly highlights an evaluated sexp." single ((:commit . "5687e7b33e17f2be40b036dac82da4a5bc6705fb") (:keywords "languages" "clojure" "cider") (:authors ("Sylvain Benner" . "sylvain.benner@gmail.com")) (:maintainer "Sylvain Benner" . "sylvain.benner@gmail.com"))]) (cider-decompile . [(20151122 537) ((cider (0 3 0)) (javap-mode (9))) "decompilation extension for cider" single ((:commit . "5d87035f3c3c14025e8f01c0c53d0ce2c8f56651") (:keywords "languages" "clojure" "cider") (:authors ("Dmitry Bushenko")) (:maintainer "Dmitry Bushenko") (:url . "http://www.github.com/clojure-emacs/cider-decompile"))]) (cider . [(20180903 2111) ((emacs (25)) (clojure-mode (5 9)) (pkg-info (0 4)) (queue (0 2)) (spinner (1 7)) (seq (2 16)) (sesman (0 3))) "Clojure Interactive Development Environment that Rocks" tar ((:commit . "7f1c5e2ea9b5271c9c7fd43b44b6f4a1a1262183") (:keywords "languages" "clojure" "cider") (:authors ("Tim King" . "kingtim@gmail.com") ("Phil Hagelberg" . "technomancy@gmail.com") ("Bozhidar Batsov" . "bozhidar@batsov.com") ("Artur Malabarba" . "bruce.connor.am@gmail.com") ("Hugo Duncan" . "hugo@hugoduncan.org") ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Bozhidar Batsov" . "bozhidar@batsov.com") (:url . "http://www.github.com/clojure-emacs/cider"))]) (chyla-theme . [(20180302 1658) nil "chyla.org - green color theme." single ((:commit . "ae5e7ecace2ab474151eb0ac5ef07fba2dc32f8a") (:authors ("Adam Chyła" . "adam@chyla.org")) (:maintainer "Adam Chyła" . "adam@chyla.org") (:url . "https://github.com/chyla/ChylaThemeForEmacs"))]) (chruby . [(20180114 1652) ((cl-lib (0 5))) "Emacs integration for chruby" single ((:commit . "42bc6d521f832eca8e2ba210f30d03ad5529788f") (:keywords "languages") (:authors ("Arne Brasseur" . "arne@arnebrasseur.net")) (:maintainer "Arne Brasseur" . "arne@arnebrasseur.net") (:url . "https://github.com/plexus/chruby.el"))]) (chronos . [(20150602 1529) nil "multiple simultaneous countdown / countup timers" tar ((:commit . "b360d9dae57aa553cf2a14ffa0756a51ad71de09") (:keywords "calendar") (:authors ("David Knight" . "dxknight@opmbx.org")) (:maintainer "David Knight" . "dxknight@opmbx.org") (:url . "http://github.com/dxknight/chronos"))]) (choice-program . [(20171004 1631) ((emacs (25)) (cl-lib (1 0))) "parameter based program" tar ((:commit . "27607ec1fe241c58fbc1f861454a8e2ec1fd7b15") (:keywords "exec" "execution" "parameter" "option") (:authors ("Paul Landes")) (:maintainer "Paul Landes") (:url . "https://github.com/plandes/choice-program"))]) (chinese-yasdcv . [(20171015 144) ((cl-lib (0 5)) (pyim (1 6 0))) "Yet another StarDict frontend" tar ((:commit . "5ab830daf1273d5a5cddcb94b56a9737f12d996f") (:keywords "convenience" "chinese" "dictionary") (:authors ("Feng Shu" . "tumashu@gmail.com")) (:maintainer "Feng Shu" . "tumashu@gmail.com") (:url . "https://github.com/tumashu/chinese-yasdcv"))]) (chinese-word-at-point . [(20170811 941) ((cl-lib (0 5))) "Add `chinese-word' thing to `thing-at-point'" single ((:commit . "8223d7439e005555b86995a005b225ae042f0538") (:keywords "convenience" "chinese") (:authors ("Chunyang Xu" . "xuchunyang56@gmail.com")) (:maintainer "Chunyang Xu" . "xuchunyang56@gmail.com") (:url . "https://github.com/xuchunyang/chinese-word-at-point.el"))]) (chinese-wbim . [(20150624 350) nil "Enable Wubi Input Method in Emacs." tar ((:commit . "57ff61ff3895d77335709d24b40cefc4d10b0095"))]) (chinese-number . [(20161008 509) nil "Convert numbers between Arabic and Chinese formats" single ((:commit . "7311c2a0c5eea5f016a90d733dfe75144c302fb2") (:authors (nil . "zhcosin<zhcosin@163.com>")) (:maintainer nil . "zhcosin<zhcosin@163.com>") (:url . "https://github.com/zhcosin/chinese-number"))]) (chinese-conv . [(20170807 2128) ((cl-lib (0 5))) "Conversion between Chinese Characters with opencc or cconv" single ((:commit . "b56815bbb163d642e97fa73093b5a7e87cc32574") (:authors ("gucong" . "gucong43216@gmail.com")) (:maintainer "gucong" . "gucong43216@gmail.com") (:url . "https://github.com/gucong/emacs-chinese-conv"))]) (chicken-scheme . [(20141116 1939) nil "Scheme-mode extensions for Chicken Scheme" single ((:commit . "19b0b08b5592063e852cae094b394c7d1f923639") (:authors ("Daniel Leslie" . "dan@ironoxide.ca")) (:maintainer "Daniel Leslie" . "dan@ironoxide.ca") (:url . "http://github.com/dleslie/chicken-scheme"))]) (cherry-blossom-theme . [(20150622 342) ((emacs (24 0))) "a soothing color theme for Emacs24." single ((:commit . "eea7653e00f35973857ee23b27bc2fae5e753e50") (:authors ("Ben Yelsey" . "byelsey1@gmail.com")) (:maintainer "Ben Yelsey" . "byelsey1@gmail.com") (:url . "https://github.com/inlinestyle/emacs-cherry-blossom-theme"))]) (chef-mode . [(20180628 1453) nil "minor mode for editing an opscode chef repository" single ((:commit . "048d691cb63981ae235763d4a6ced4af5c729924") (:keywords "chef" "knife") (:authors ("Maciej Pasternacki" . "maciej@pasternacki.net")) (:maintainer "Maciej Pasternacki" . "maciej@pasternacki.net"))]) (cheerilee . [(20160313 1835) ((xelb (0 1))) "Toolkit library" tar ((:commit . "41bd81b5b0bb657241ceda5be6af5e07254d7376") (:keywords "tools"))]) (chee . [(20171123 2233) ((dash (2 12 1)) (s (1 10 0)) (f (0 18 2))) "Interface to chee using dired and image-dired" tar ((:commit . "669ff9ee429f24c3c2d03b83d9cb9aec5f86bb8b") (:url . "https://github.com/eikek/chee/tree/release/0.3.0/emacs"))]) (checkbox . [(20141117 58) ((emacs (24)) (cl-lib (0 5))) "Quick manipulation of textual checkboxes" single ((:commit . "335afa4404adf72973195a580458927004664d98") (:keywords "convenience") (:authors ("Cameron Desautels" . "camdez@gmail.com")) (:maintainer "Cameron Desautels" . "camdez@gmail.com") (:url . "http://github.com/camdez/checkbox.el"))]) (cheatsheet . [(20170126 2150) ((emacs (24)) (cl-lib (0 5))) "create your own cheatsheet" single ((:commit . "e4f8e0110167ea16a17a74517d1f10cb7ff805b8") (:keywords "convenience" "usability") (:authors ("Shirin Nikita" . "shirin.nikita@gmail.com")) (:maintainer "Shirin Nikita" . "shirin.nikita@gmail.com") (:url . "http://github.com/darksmile/cheatsheet/"))]) (cheat-sh . [(20170802 1118) ((emacs (24))) "Interact with cheat.sh" single ((:commit . "e90445124f3f145a047779e42d070a3c5e150f70") (:keywords "docs" "help") (:authors ("Dave Pearson" . "davep@davep.org")) (:maintainer "Dave Pearson" . "davep@davep.org") (:url . "https://github.com/davep/cheat-sh.el"))]) (chatwork . [(20170511 442) nil "ChatWork client for Emacs" single ((:commit . "fea231d479f06bf40dbfcf45de143eecc9ed744c") (:keywords "web") (:authors ("Masayuki Ataka" . "masayuki.ataka@gmail.com")) (:maintainer "Masayuki Ataka" . "masayuki.ataka@gmail.com") (:url . "https://github.com/ataka/chatwork"))]) (charmap . [(20160309 946) nil "Unicode table for Emacs" single ((:commit . "bd4b3e466d7a9433cf35167e3a68ec74fe631bb2") (:keywords "unicode" "character" "ucs") (:authors ("Anan Mikami" . "lateau@gmail.com")) (:maintainer "Anan Mikami" . "lateau@gmail.com") (:url . "https://github.com/lateau/charmap"))]) (char-menu . [(20180101 618) ((emacs (24 3)) (avy-menu (0 1))) "Create your own menu for fast insertion of arbitrary symbols" single ((:commit . "82f0422179737bcb9f93481aebaf1071d54fc859") (:keywords "convenience" "editing") (:authors ("Mark Karpov" . "markkarpov92@gmail.com")) (:maintainer "Mark Karpov" . "markkarpov92@gmail.com") (:url . "https://github.com/mrkkrp/char-menu"))]) (chapel-mode . [(20160504 808) nil "a CC Mode for Chapel derived from derived-mode-ex.el" single ((:commit . "6e095edd7639f5f0a81e14d6412410b49466697e") (:keywords "chapel" "languages" "oop") (:authors ("Steven T Balensiefer")) (:maintainer "Russel Winder" . "russel@winder.org.uk"))]) (change-inner . [(20150707 1544) ((expand-region (0 7))) "Change contents based on semantic units" single ((:commit . "52c543a4b9808c0d15b565fcdf646c9779de33e8") (:keywords "convenience" "extensions") (:authors ("Magnar Sveen" . "magnars@gmail.com")) (:maintainer "Magnar Sveen" . "magnars@gmail.com"))]) (challenger-deep-theme . [(20180816 2258) ((emacs (24))) "challenger-deep Theme" single ((:commit . "443ca72dca966b3d27dbec9eab54a09cbd76eac0") (:authors ("MaxSt")) (:maintainer "MaxSt") (:url . "https://github.com/challenger-deep-theme/emacs"))]) (cg . [(20171123 1101) nil "major mode for editing Constraint Grammar files" single ((:commit . "e19f3bf60b9c8dbcff053b008fa3ace17fc073fe") (:keywords "languages") (:authors ("Kevin Brubeck Unhammer" . "unhammer@fsfe.org")) (:maintainer "Kevin Brubeck Unhammer" . "unhammer@fsfe.org") (:url . "https://visl.sdu.dk/constraint_grammar.html"))]) (cftag-mode . [(20170812 540) ((emacs (25))) "Emacs mode for editing tag-based CFML files" single ((:commit . "86e77dcbb583191a3e755bdc29534f33d82bfc56") (:authors ("Andrew Myers" . "am2605@gmail.com")) (:maintainer "Andrew Myers" . "am2605@gmail.com") (:url . "https://github.com/am2605/cftag-mode"))]) (cframe . [(20170917 2209) ((emacs (25)) (buffer-manage (0 6)) (dash (2 13 0))) "customize a frame and fast switch size and positions" single ((:commit . "bb99672502046e87c8f029ce98c637f762a4fc54") (:keywords "frame" "customize") (:authors ("Paul Landes")) (:maintainer "Paul Landes") (:url . "https://github.com/plandes/cframe"))]) (cfml-mode . [(20170904 249) ((emacs (25)) (mmm-mode (0 5 4)) (cftag-mode (1 0 0))) "Emacs mode for editing CFML files" single ((:commit . "86e77dcbb583191a3e755bdc29534f33d82bfc56") (:authors ("Andrew Myers" . "am2605@gmail.com")) (:maintainer "Andrew Myers" . "am2605@gmail.com") (:url . "https://github.com/am2605/cfml-mode"))]) (cff . [(20160118 2018) ((cl-lib (0 5)) (emacs (24))) "Search of the C/C++ file header by the source and vice versa" single ((:commit . "b6ab2a28e64ef06f281ec74cfe3114e450644dfa") (:keywords "find-file") (:authors ("Alexey Veretennikov" . "alexey.veretennikov@gmail.com")) (:maintainer "Alexey Veretennikov" . "alexey.veretennikov@gmail.com") (:url . "https://github.com/fourier/cff"))]) (cfengine-code-style . [(20171115 2108) nil "C code style for CFEngine project." single ((:commit . "11b10fb5d80a67763977c8f2dac4dc850156aa4c") (:authors ("Mikhail Gusarov" . "mikhail.gusarov@cfengine.com")) (:maintainer "Mikhail Gusarov" . "mikhail.gusarov@cfengine.com") (:url . "https://github.com/cfengine/core"))]) (ceylon-mode . [(20180606 1324) ((emacs (25))) "Major mode for editing Ceylon source code" single ((:commit . "948515672bc596dc118e8e3ede3ede5ec6a3c95a") (:keywords "languages" "ceylon") (:authors ("Lucas Werkmeister" . "mail@lucaswerkmeister.de")) (:maintainer "Lucas Werkmeister" . "mail@lucaswerkmeister.de") (:url . "https://github.com/lucaswerkmeister/ceylon-mode"))]) (cerbere . [(20140418 1415) ((s (1 9 0)) (f (0 16 0)) (pkg-info (0 5))) "Unit testing in Emacs for several programming languages" tar ((:commit . "dd2105c372b469954e665a5aa0c3766b4922ce6a") (:keywords "python" "go" "php" "tests" "tdd") (:authors ("Nicolas Lamirault" . "nicolas.lamirault@gmail.com")) (:maintainer "Nicolas Lamirault" . "nicolas.lamirault@gmail.com") (:url . "https://github.com/nlamirault/cerbere"))]) (centimacro . [(20140306 1427) nil "Assign multiple macros as global key bindings" single ((:commit . "1b97a9b558ed9c49d5da1bfbf29b2506575c2742") (:keywords "macros") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:url . "https://github.com/abo-abo/centimacro"))]) (centered-window . [(20171127 949) ((emacs (24 4))) "Center the text when there's only one window" single ((:commit . "24f7c5be9def20879f46659082d497e67b55d7af") (:keywords "faces" "windows") (:authors ("Anler Hernández Peral" . "inbox+emacs@anler.me")) (:maintainer "Anler Hernández Peral" . "inbox+emacs@anler.me") (:url . "https://github.com/anler/centered-window-mode"))]) (centered-cursor-mode . [(20180112 1555) nil "cursor stays vertically centered" single ((:commit . "00fb47d227f9e211ec1c58161a501a1550c3a60d") (:keywords "convenience") (:authors ("André Riemann" . "andre.riemann@web.de")) (:maintainer "André Riemann" . "andre.riemann@web.de") (:url . "https://github.com/andre-r/centered-cursor-mode.el"))]) (celestial-mode-line . [(20180518 822) ((emacs (24))) "Show lunar phase and sunrise/-set time in modeline" single ((:commit . "3f5794aca99b977f1592cf1ab4516ae7922196a1") (:keywords "extensions") (:authors ("Peter" . "craven@gmx.net")) (:maintainer "Peter" . "craven@gmx.net") (:url . "https://github.com/ecraven/celestial-mode-line"))]) (celery . [(20170225 924) ((emacs (24)) (dash-functional (2 11 0)) (s (1 9 0)) (deferred (0 3 2))) "a minor mode to draw stats from celery and more?" single ((:commit . "51197d74f5eaa8ae09144af7663a2f4277f07d16") (:keywords "celery" "convenience") (:authors ("ardumont" . "eniotna.t@gmail.com")) (:maintainer "ardumont" . "eniotna.t@gmail.com") (:url . "https://github.com/ardumont/emacs-celery"))]) (cedit . [(20141231 1614) nil "paredit-like commands for c-like languages" single ((:commit . "0878d851b6307c162bfbddd2bb02789e5e27bc2c") (:authors ("zk_phi")) (:maintainer "zk_phi") (:url . "http://hins11.yu-yake.com/"))]) (cdnjs . [(20161031 1522) ((dash (2 13 0)) (deferred (0 4)) (f (0 17 2)) (pkg-info (0 5))) "A front end for http://cdnjs.com" single ((:commit . "ce19880d3ec3d81e6c665d0b1dfea99cc7a3f908") (:keywords "tools") (:authors ("Yasuyuki Oka" . "yasuyk@gmail.com")) (:maintainer "Yasuyuki Oka" . "yasuyk@gmail.com") (:url . "https://github.com/yasuyk/cdnjs.el"))]) (cdlatex . [(20140707 1126) nil "Fast input methods for LaTeX environments and math" single ((:commit . "ff534912b93fc2c7a6b191b1c8d6d699a46bbb01") (:keywords "tex") (:authors ("Carsten Dominik" . "carsten.dominik@gmail.com")) (:maintainer "Carsten Dominik" . "carsten.dominik@gmail.com"))]) (cdb . [(20151205 1343) nil "constant database (cdb) reader for Emacs Lisp" single ((:commit . "b05c610e27b86e71fb4e8d67292ef6a696dd5992") (:keywords "cdb") (:authors ("Yusuke Shinyama <yusuke at cs . nyu . edu>")) (:maintainer "SKK Development Team" . "skk@ring.gr.jp"))]) (cd-compile . [(20141108 1957) nil "run compile in a specific directory" single ((:commit . "10284ccae86afda4a37b09ba90acd1e2efedec9f") (:authors ("Jamie Nicol" . "jamie@thenicols.net")) (:maintainer "Jamie Nicol" . "jamie@thenicols.net"))]) (ccls . [(20180903 2309) ((emacs (25 1)) (lsp-mode (3 4)) (dash (0 13))) "ccls client for lsp-mode" tar ((:commit . "2b2d5a27ec739b59458e03aa30bb0eb612e727b6") (:keywords "languages" "lsp" "c++") (:authors ("Tobias Pisani, Fangrui Song")) (:maintainer "Tobias Pisani, Fangrui Song") (:url . "https://github.com/MaskRay/emacs-ccls"))]) (ccc . [(20151205 1343) nil "buffer local cursor color control library" single ((:commit . "b05c610e27b86e71fb4e8d67292ef6a696dd5992") (:keywords "cursor") (:authors ("Masatake YAMATO" . "masata-y@is.aist-nara.ac.jp")) (:maintainer "SKK Development Team" . "skk@ring.gr.jp") (:url . "https://github.com/skk-dev/ddskk/blob/master/READMEs/README.ccc.org"))]) (cbm . [(20171116 1240) ((cl-lib (0 5))) "Switch to similar buffers." single ((:commit . "5b41c936ba9f6d170309a85ffebc9939c1050b31") (:keywords "buffers") (:authors ("Lukas Fürmetz" . "fuermetz@mailbox.org")) (:maintainer "Lukas Fürmetz" . "fuermetz@mailbox.org") (:url . "http://github.com/akermu/cbm.el"))]) (catmacs . [(20170826 1157) ((emacs (24))) "Simple CAT interface for Yaesu Transceivers." single ((:commit . "65d3e0563abe6ff9577202cf2278074d4130fbdd") (:keywords "comm" "hardware") (:authors ("Frank Singleton" . "b17flyboy@gmail.com")) (:maintainer "Frank Singleton" . "b17flyboy@gmail.com") (:url . "https://bitbucket.org/pymaximus/catmacs"))]) (caskxy . [(20140513 1539) ((log4e (0 2 0)) (yaxception (0 1))) "Control Cask in Emacs" single ((:commit . "dc18dcab7ed526070ab76de071c9c5272e6ac40e") (:keywords "convenience") (:authors ("Hiroaki Otsu" . "ootsuhiroaki@gmail.com")) (:maintainer "Hiroaki Otsu" . "ootsuhiroaki@gmail.com") (:url . "https://github.com/aki2o/caskxy"))]) (cask-package-toolset . [(20170921 2256) ((emacs (24)) (cl-lib (0 3)) (s (1 6 1)) (dash (1 8 0)) (f (0 10 0)) (commander (0 2 0)) (ansi (0 1 0)) (shut-up (0 1 0))) "Toolsettize your package" tar ((:commit . "2c74cd827e88c7f8360581a841e45f0b794510e7") (:keywords "convenience" "tools") (:authors ("Adrien Becchis" . "adriean.khisbe@live.fr")) (:maintainer "Adrien Becchis" . "adriean.khisbe@live.fr") (:url . "http://github.com/AdrieanKhisbe/cask-package-toolset.el"))]) (cask-mode . [(20160410 1449) ((emacs (24 3))) "major mode for editing Cask files" single ((:commit . "7c6719d3bb4fe552958634bd5a11abc56681f3a7") (:authors ("Wilfred Hughes" . "me@wilfred.me.uk")) (:maintainer "Wilfred Hughes" . "me@wilfred.me.uk"))]) (cask . [(20180831 1308) ((s (1 8 0)) (dash (2 2 0)) (f (0 16 0)) (epl (0 5)) (shut-up (0 1 0)) (cl-lib (0 3)) (package-build (1 2))) "Cask: Project management for Emacs package development" tar ((:commit . "c3a78630300377be179a6f83fc0d8d68ec07af06") (:keywords "speed" "convenience") (:authors ("Johan Andersson" . "johan.rejeep@gmail.com")) (:maintainer "Johan Andersson" . "johan.rejeep@gmail.com") (:url . "http://github.com/cask/cask"))]) (caseformat . [(20160115 1615) ((emacs (24)) (cl-lib (0 5)) (dash (2 12 1)) (s (1 10 0))) "Format based letter case converter" single ((:commit . "92a31f6a7cae0b4e2af106cd6f2b0abe6c2d8921") (:keywords "convenience") (:authors ("Hiroki YAMAKAWA" . "s06139@gmail.com")) (:maintainer "Hiroki YAMAKAWA" . "s06139@gmail.com") (:url . "https://github.com/HKey/caseformat"))]) (caroline-theme . [(20160318 520) ((emacs (24))) "A trip down to New Orleans..." single ((:commit . "222fd483db304509f9e422dc82883d808e023ceb") (:authors ("Jack Killilea" . "jaaacckz1@gmail.com")) (:maintainer "Jack Killilea" . "jaaacckz1@gmail.com") (:url . "https://github.com/xjackk/carolines-theme"))]) (cargo . [(20180812 1218) ((emacs (24 3)) (rust-mode (0 2 0)) (markdown-mode (2 4))) "Emacs Minor Mode for Cargo, Rust's Package Manager." tar ((:commit . "c995b42e2c0fc609d265286ce465d508d81b8a4d") (:keywords "tools") (:authors ("Kevin W. van Rooijen" . "kevin.van.rooijen@attichacker.com")) (:maintainer "Kevin W. van Rooijen" . "kevin.van.rooijen@attichacker.com"))]) (carbon-now-sh . [(20180331 1735) ((emacs (24 4)) (dash (2 12 0))) "https://carbon.now.sh integration." single ((:commit . "71dee6bc4f2a2cb02b9b7b5e643c4c92b880e6a4") (:keywords "convenience") (:authors ("Vitalii Elenhaupt")) (:maintainer "Vitalii Elenhaupt") (:url . "https://github.com/veelenga/carbon-now-sh.el"))]) (capture . [(20130828 1644) nil "screencasting with \"avconv\" or \"ffmpeg\"" tar ((:commit . "1bb26060311da76767f70096218313fc93b0c806") (:authors ("Sergey Pashinin <sergey at pashinin dot com>")) (:maintainer "Sergey Pashinin <sergey at pashinin dot com>"))]) (caml . [(20180808 741) nil "OCaml code editing commands for Emacs" tar ((:commit . "284c8f8bb858009ebba5ab34b3a8ec493bb8f7bf") (:keywords "ocaml") (:authors ("Jacques Garrigue" . "garrigue@kurims.kyoto-u.ac.jp") ("Ian T Zimmerman" . "itz@rahul.net")) (:maintainer "Damien Doligez" . "damien.doligez@inria.fr") (:url . "https://github.com/ocaml/ocaml/"))]) (camcorder . [(20160405 434) ((emacs (24)) (names (20150000)) (cl-lib (0 5))) "Record screencasts in gif or other formats." single ((:commit . "b13d939990e6709492efefc0945798adc1c0fcb9") (:keywords "multimedia" "screencast") (:authors ("Artur Malabarba" . "bruce.connor.am@gmail.com")) (:maintainer "Artur Malabarba" . "bruce.connor.am@gmail.com") (:url . "http://github.com/Bruce-Connor/camcorder.el"))]) (calmer-forest-theme . [(20130926 510) nil "Darkish theme with green/orange tint" single ((:commit . "87ba7bae389084d13fe3bc34e0c923017eda6ba0") (:authors ("Artur Hefczyc, created 2003-04-18") ("David Caldwell" . "david@porkrind.org")) (:maintainer "Artur Hefczyc, created 2003-04-18") (:url . "https://github.com/caldwell/calmer-forest-theme"))]) (call-graph . [(20180509 1335) ((emacs (25 1)) (cl-lib (0 6 1)) (hierarchy (0 7 0)) (tree-mode (1 0 0)) (ivy (0 10 0))) "Library to generate call graph for c/c++ functions" single ((:commit . "7e51c1eea59b13e6c1c099680492ebcd58893399") (:keywords "programming" "convenience") (:authors ("Huming Chen" . "chenhuming@gmail.com")) (:maintainer "Huming Chen" . "chenhuming@gmail.com") (:url . "https://github.com/beacoder/call-graph"))]) (calfw-org . [(20160303 258) nil "calendar view for org-agenda" single ((:commit . "03abce97620a4a7f7ec5f911e669da9031ab9088") (:keywords "calendar" "org") (:authors ("SAKURAI Masashi <m.sakurai at kiwanami.net>")) (:maintainer "SAKURAI Masashi <m.sakurai at kiwanami.net>"))]) (calfw-ical . [(20150703 819) nil "calendar view for ical format" single ((:commit . "03abce97620a4a7f7ec5f911e669da9031ab9088") (:keywords "calendar") (:authors ("SAKURAI Masashi <m.sakurai at kiwanami.net>")) (:maintainer "SAKURAI Masashi <m.sakurai at kiwanami.net>"))]) (calfw-howm . [(20170704 4) nil "calendar view for howm" single ((:commit . "03abce97620a4a7f7ec5f911e669da9031ab9088") (:keywords "calendar") (:authors ("SAKURAI Masashi <m.sakurai at kiwanami.net>")) (:maintainer "SAKURAI Masashi <m.sakurai at kiwanami.net>"))]) (calfw-gcal . [(20120111 1000) nil "edit Google calendar for calfw.el." tar ((:commit . "14aab20687d6cc9e6c5ddb9e11984c4e14c3d870") (:keywords "convenience" "calendar" "calfw.el") (:authors ("myuhe <yuhei.maeda_at_gmail.com>")) (:maintainer "myuhe") (:url . "https://github.com/myuhe/calfw-gcal.el"))]) (calfw-cal . [(20170320 1206) nil "calendar view for emacs diary" single ((:commit . "03abce97620a4a7f7ec5f911e669da9031ab9088") (:keywords "calendar") (:authors ("SAKURAI Masashi <m.sakurai at kiwanami.net>")) (:maintainer "SAKURAI Masashi <m.sakurai at kiwanami.net>"))]) (calfw . [(20180118 45) nil "Calendar view framework on Emacs" single ((:commit . "03abce97620a4a7f7ec5f911e669da9031ab9088") (:keywords "calendar") (:authors ("SAKURAI Masashi <m.sakurai at kiwanami.net>")) (:maintainer "SAKURAI Masashi <m.sakurai at kiwanami.net>") (:url . "https://github.com/kiwanami/emacs-calfw"))]) (calendar-norway . [(20160827 2016) nil "Norwegian calendar" single ((:commit . "8501b2ee515e995f345365391b03f44c812cabdf") (:keywords "calendar" "norwegian" "localization") (:authors ("Kevin Brubeck Unhammer" . "unhammer@fsfe.org")) (:maintainer "Kevin Brubeck Unhammer" . "unhammer@fsfe.org"))]) (cal-china-x . [(20180211 1901) ((cl-lib (0 5))) "Chinese localization, lunar/horoscope/zodiac info and more..." tar ((:commit . "e9b309065829af3a9a0c526509bd64d9228fdced") (:authors ("William Xu" . "william.xwl@gmail.com")) (:maintainer "William Xu" . "william.xwl@gmail.com") (:url . "https://github.com/xwl/cal-china-x"))]) (cakecrumbs . [(20180223 245) ((emacs (24 4))) "Show parents on header for HTML/Jade/Sass/Stylus" single ((:commit . "76cfbfacfaa9d2128fc9218338a0ba2bb47349ab") (:keywords "languages" "html" "jade" "pug" "sass" "scss" "stylus") (:authors ("ono hiroko <kuanyui.github.io>")) (:maintainer "ono hiroko <kuanyui.github.io>") (:url . "https://github.com/kuanyui/cakecrumbs.el"))]) (cake-inflector . [(20140415 858) ((s (1 9 0))) "Lazy porting CakePHP infrector.php to el" single ((:commit . "a1d338ec4840b1b1bc14f7f9298c07e2c1d2d8fc") (:authors ("k1LoW (Kenichirou Oyama), <k1lowxb [at] gmail [dot] com> <k1low [at] 101000lab [dot] org>")) (:maintainer "k1LoW (Kenichirou Oyama), <k1lowxb [at] gmail [dot] com> <k1low [at] 101000lab [dot] org>") (:url . "https://github.com/k1LoW/emacs-cake-inflector"))]) (cacoo . [(20120319 2359) ((concurrent (0 3 1))) "Minor mode for Cacoo : http://cacoo.com" tar ((:commit . "c9fa04fbe97639b24698709530361c2bb5f3273c"))]) (cache . [(20111019 2300) nil "implementation of a hash table whose key-value pairs expire" single ((:commit . "7499586b6c8224df9f5c5bc4dec96b008258d580") (:authors ("Nathaniel Flath")) (:maintainer "Nathaniel Flath"))]) (cabledolphin . [(20160204 938) ((emacs (24 4)) (seq (1 0))) "capture Emacs network traffic" single ((:commit . "fffc192cafa61558e924323d6da8166fe5f2a6f9") (:keywords "comm") (:authors ("Magnus Henoch" . "magnus.henoch@gmail.com")) (:maintainer "Magnus Henoch" . "magnus.henoch@gmail.com"))]) (c0-mode . [(20151110 1852) nil "Major mode for editing C0 files" tar ((:commit . "c214093c36864d6208fcb9e6a72413ed17ed5d60") (:keywords "c0" "languages") (:authors ("Jakob Max Uecker")) (:maintainer "Jakob Max Uecker") (:url . "http://c0.typesafety.net/"))]) (c-eldoc . [(20170917 2202) nil "helpful description of the arguments to C functions" single ((:commit . "79d09769362228058246f5e6fa183d121f7fb322") (:authors ("Nathaniel Flath" . "flat0103@gmail.com")) (:maintainer "Nathaniel Flath" . "flat0103@gmail.com") (:url . "http://github.com/nflath/c-eldoc"))]) (c-c-combo . [(20151224 255) nil "Make stuff happen when you reach a target wpm" tar ((:commit . "a261a833499a7fdc29610863b3aafc74818770ba") (:authors ("Diego Berrocal" . "cestdiego@gmail.com")) (:maintainer "Diego Berrocal" . "cestdiego@gmail.com") (:url . "https://www.github.com/CestDiego/c-c-combo.el"))]) (button-lock . [(20150223 1354) nil "Clickable text defined by regular expression" single ((:commit . "f9082feb329432fcf2ac49a95e64bed9fda24d58") (:keywords "mouse" "button" "hypermedia" "extensions") (:authors ("Roland Walker" . "walker@pobox.com")) (:maintainer "Roland Walker" . "walker@pobox.com") (:url . "http://github.com/rolandwalker/button-lock"))]) (buttercup . [(20180903 742) nil "Behavior-Driven Emacs Lisp Testing" tar ((:commit . "0d742b00debd59f07320638c505777f6a908f5ad"))]) (butler . [(20150812 8) ((deferred (0 3 2)) (json (1 2)) (emacs (24))) "Emacs client for Jenkins" tar ((:commit . "8ceb35737107572455cca9a61ff46b3ff78f1016"))]) (busybee-theme . [(20170719 928) nil "port of vim's mustang theme" single ((:commit . "66b2315b030582d0ebee605cf455d386d8c30fcd") (:authors ("martin haesler")) (:maintainer "martin haesler") (:url . "http://github.com/mswift42/busybee-theme"))]) (buster-snippets . [(20151125 1010) ((yasnippet (0 8 0))) "Yasnippets for the Buster javascript testing framework" tar ((:commit . "bb8769dae132659858e74d52f3f4e8790399423a") (:keywords "snippets") (:authors ("Magnar Sveen" . "magnars@gmail.com")) (:maintainer "Magnar Sveen" . "magnars@gmail.com"))]) (buster-mode . [(20140928 1213) nil "Minor mode to speed up development when writing tests with Buster.js" single ((:commit . "de6958ef8369400922618b8d1e99abfa91b97ac5") (:keywords "buster" "testing" "javascript"))]) (bury-successful-compilation . [(20150329 28) nil "Bury the *compilation* buffer after successful compilation" single ((:commit . "52da2c07419beceab9b4d426d76adb3dcf2548d1") (:keywords "compilation") (:authors ("Eric Crosson" . "esc@ericcrosson.com")) (:maintainer "Eric Crosson" . "esc@ericcrosson.com"))]) (bundler . [(20160815 915) ((inf-ruby (2 1)) (cl-lib (0 5))) "Interact with Bundler from Emacs" single ((:commit . "f981f67c33b42243e57a78c358dffff70022b56b") (:keywords "bundler" "ruby") (:authors ("Tobias Svensson" . "tob@tobiassvensson.co.uk")) (:maintainer "Tobias Svensson" . "tob@tobiassvensson.co.uk") (:url . "http://github.com/endofunky/bundler.el"))]) (build-status . [(20171111 1947) ((cl-lib (0 5))) "Mode line build status indicator" single ((:commit . "ef44185d9dd748ea578d68398f3f729a8adb45b5") (:keywords "mode-line" "ci" "circleci" "travis-ci") (:authors ("Skye Shaw" . "skye.shaw@gmail.com")) (:maintainer "Skye Shaw" . "skye.shaw@gmail.com") (:url . "http://github.com/sshaw/build-status"))]) (build-helper . [(20161009 1755) ((projectile (0 9 0))) "Utilities to help build code" single ((:commit . "7a6fe71125a26ed1c492dab77cc688a7fe1d68ac") (:keywords "convenience") (:authors ("Afonso Bordado" . "afonsobordado@az8.co")) (:maintainer "Afonso Bordado" . "afonsobordado@az8.co") (:url . "http://github.com/afonso360/build-helper"))]) (build-farm . [(20180828 840) ((emacs (24 4)) (bui (1 1 0)) (magit-popup (2 1 0))) "Interface for Nix and Guix build farms (Hydra and Cuirass)" tar ((:commit . "82dbf78aa5897616be9dc62fdef089dc758a5d86") (:keywords "tools") (:authors ("Alex Kost" . "alezost@gmail.com")) (:maintainer "Alex Kost" . "alezost@gmail.com") (:url . "https://gitlab.com/alezost-emacs/build-farm"))]) (bui . [(20180812 2113) ((emacs (24 3)) (dash (2 11 0))) "Buffer interface library" tar ((:commit . "bd3c5ee32d28d80c6eb54b0340626103c32e3093") (:keywords "tools") (:authors ("Alex Kost" . "alezost@gmail.com")) (:maintainer "Alex Kost" . "alezost@gmail.com") (:url . "https://github.com/alezost/bui.el"))]) (bug-reference-github . [(20180128 1314) nil "Set `bug-reference-url-format' in Github repos" tar ((:commit . "f570a0532bfb44f095b42cf68ab1f69799101137") (:keywords "programming" "tools") (:authors ("Arne Jørgensen" . "arne@arnested.dk")) (:maintainer "Arne Jørgensen" . "arne@arnested.dk") (:url . "https://github.com/arnested/bug-reference-github"))]) (bufshow . [(20130726 1838) ((emacs (24 1))) "A simple presentation tool for Emacs." single ((:commit . "d60a554e7239e6f7520d9c3436d5ecdbc9cf6957") (:authors ("Peter Jones" . "pjones@pmade.com")) (:maintainer "Peter Jones" . "pjones@pmade.com") (:url . "https://github.com/pjones/bufshow"))]) (buffer-watcher . [(20170913 839) ((f (0 16 2)) (cl-lib (0 5))) "Easily run shell scripts per filetype/directory when a buffer is saved" single ((:commit . "b32c67c8a5d724257d759f4c903d0dedc32246ef") (:authors ("Nicolas Petton" . "nicolas@petton.fr")) (:maintainer "Nicolas Petton" . "nicolas@petton.fr"))]) (buffer-utils . [(20140512 1400) nil "Buffer-manipulation utility functions" single ((:commit . "685b13457e3a2085b7584e41365d2aa0779a1b6f") (:keywords "extensions") (:authors ("Roland Walker" . "walker@pobox.com")) (:maintainer "Roland Walker" . "walker@pobox.com") (:url . "http://github.com/rolandwalker/buffer-utils"))]) (buffer-sets . [(20170718 340) ((cl-lib (0 5))) "Sets of Buffers for Buffer Management" single ((:commit . "4a4ccb0d6916c3e9fba737bb7b48e8aac921954e") (:keywords "buffer-management") (:authors ("Samuel W. Flint" . "swflint@flintfam.org")) (:maintainer "Samuel W. Flint" . "swflint@flintfam.org") (:url . "http://github.com/swflint/buffer-sets"))]) (buffer-move . [(20160615 1803) nil "easily swap buffers" single ((:commit . "cb517ecf8409b5fdcda472d7190c6021f0c49751") (:keywords "lisp" "convenience") (:url . "https://github.com/lukhas/buffer-move"))]) (buffer-manage . [(20180528 1613) ((emacs (25)) (choice-program (0 3)) (dash (2 13 0))) "manage buffers" tar ((:commit . "8bbe342a4dafcfdaf305baea98bd4208036ab89a") (:keywords "interactive" "buffer" "management") (:authors ("Paul Landes")) (:maintainer "Paul Landes") (:url . "https://github.com/plandes/buffer-manage"))]) (buffer-flip . [(20180307 2251) nil "Cycle through buffers like Alt-Tab in Windows" single ((:commit . "e093360e05164c78255866c1ac8f966aa38ba514") (:keywords "convenience") (:authors ("Russell Black" . "killdash9@github")) (:maintainer "Russell Black" . "killdash9@github") (:url . "https://github.com/killdash9/buffer-flip.el"))]) (buffer-buttons . [(20150106 1439) nil "Define, save, and load code-safe buttons in files for emacs" single ((:commit . "2feb8494fa7863b98256bc85da670d74a3a8a975") (:authors ("Ryan Pavlik" . "rpavlik@gmail.com")) (:maintainer "Ryan Pavlik" . "rpavlik@gmail.com") (:url . "https://github.com/rpav/buffer-buttons"))]) (buckwalter . [(20180107 1643) nil "Write arabic using Buckwalter transliteration" single ((:commit . "2aa5451c3682c268adebc6b1191a796466732f53") (:keywords "arabic" "transliteration" "i18n") (:authors ("Joe HAKIM RAHME" . "joehakimrahme@gmail.com")) (:maintainer "Joe HAKIM RAHME" . "joehakimrahme@gmail.com") (:url . "https://github.com/joehakimrahme/buckwalter-arabic"))]) (bubbleberry-theme . [(20141017 944) ((emacs (24 1))) "A theme based on LightTable for Emacs24" single ((:commit . "22e9adf4586414024e4592972022ec297321b320") (:authors ("Jason Milkins" . "jasonm23@gmail.com") ("Gaurav Giri github.com/grvgr")) (:maintainer "Jason Milkins" . "jasonm23@gmail.com") (:url . "https://github.com/jasonm23/emacs-bubbleberry-theme"))]) (bts-github . [(20170401 1249) ((bts (0 0 1)) (gh (0 8 2))) "A plugin of bts.el for GitHub" single ((:commit . "ef2cf9202dc2128e5efdb613bfde9276a8cd95ad") (:keywords "convenience" "git" "github") (:authors ("Hiroaki Otsu" . "ootsuhiroaki@gmail.com")) (:maintainer "Hiroaki Otsu" . "ootsuhiroaki@gmail.com") (:url . "https://github.com/aki2o/emacs-bts-github"))]) (bts . [(20151109 1333) ((widget-mvc (0 0 2)) (log4e (0 3 0)) (yaxception (0 3 3)) (dash (2 9 0)) (s (1 9 0)) (pos-tip (0 4 5))) "A unified UI for various bug tracking systems" single ((:commit . "df42d58a36447697f93b56e69f5e700b2baef1f9") (:keywords "convenience") (:authors ("Hiroaki Otsu" . "ootsuhiroaki@gmail.com")) (:maintainer "Hiroaki Otsu" . "ootsuhiroaki@gmail.com") (:url . "https://github.com/aki2o/emacs-bts"))]) (btc-ticker . [(20151113 1459) ((json (1 2)) (request (0 2 0))) "Shows latest bitcoin price" single ((:commit . "845235b545f070d0812cd1654cbaa4997565824f") (:keywords "news") (:authors ("Jorge Niedbalski R." . "jnr@metaklass.org")) (:maintainer "Jorge Niedbalski R." . "jnr@metaklass.org"))]) (bshell . [(20170903 1837) ((emacs (25)) (buffer-manage (0 5))) "manage and track multiple inferior shells" single ((:commit . "884a8b906617d305e9d5d2c3750618d2f86f9aed") (:keywords "interactive" "shell" "management") (:authors ("Paul Landes")) (:maintainer "Paul Landes") (:url . "https://github.com/plandes/bshell"))]) (brutalist-theme . [(20180831 636) nil "Brutalist theme" single ((:commit . "f61b15874ba2b9ccbc9fdf4a8538a33addb23c2f") (:authors ("Gergely Nagy")) (:maintainer "Gergely Nagy") (:url . "https://git.madhouse-project.org/algernon/brutalist-theme.el"))]) (browse-url-dwim . [(20140731 1922) ((string-utils (0 3 2))) "Context-sensitive external browse URL or Internet search" single ((:commit . "3d611dbb167c286109ac53995ad68286d87aafb9") (:keywords "hypermedia") (:authors ("Roland Walker" . "walker@pobox.com")) (:maintainer "Roland Walker" . "walker@pobox.com") (:url . "http://github.com/rolandwalker/browse-url-dwim"))]) (browse-kill-ring . [(20171219 1908) nil "interactively insert items from kill-ring" single ((:commit . "8debc43e41d7e51532698331c6f283905890b904") (:keywords "convenience") (:authors ("Colin Walters" . "walters@verbum.org")) (:maintainer "browse-kill-ring" . "browse-kill-ring@tonotdo.com") (:url . "https://github.com/browse-kill-ring/browse-kill-ring"))]) (browse-at-remote . [(20180622 631) ((f (0 17 2)) (s (1 9 0)) (cl-lib (0 5))) "Open github/gitlab/bitbucket/stash page from Emacs" single ((:commit . "99af94ada33badd3e1eceb704e07f62c1eef513a") (:keywords "github" "gitlab" "bitbucket" "convenience") (:authors ("Rustem Muslimov" . "r.muslimov@gmail.com")) (:maintainer "Rustem Muslimov" . "r.muslimov@gmail.com"))]) (broadcast . [(20151205 212) ((emacs (24 4))) "Links buffers together for simultaneous editing." single ((:commit . "f6f9cd2e0e3f8c31d6b8e7446c27eb0e50b25f16") (:keywords "convenience" "frames" "link" "cursors") (:authors ("Russell Black" . "killdash9@github")) (:maintainer "Russell Black" . "killdash9@github") (:url . "https://github.com/killdash9/broadcast.el"))]) (brainfuck-mode . [(20150113 842) ((langdoc (20130601 1450))) "Brainfuck mode for Emacs" single ((:commit . "36e69552bb3b97a4f888d362c59845651bd0d492") (:keywords "brainfuck" "langdoc") (:authors ("Tomoya Tanjo" . "ttanjo@gmail.com")) (:maintainer "Tomoya Tanjo" . "ttanjo@gmail.com") (:url . "https://github.com/tom-tan/brainfuck-mode/"))]) (bracketed-paste . [(20160407 2348) ((emacs (24 3))) "bracketed paste mode support within emacs -nw" single ((:commit . "843ce3bbb63d560face889e13a57a2f7543957d5") (:keywords "terminals") (:authors ("Takeshi Banse" . "takebi@laafc.net")) (:maintainer "Takeshi Banse" . "takebi@laafc.net"))]) (bpr . [(20180220 1844) ((emacs (24))) "Background Process Runner" tar ((:commit . "af84a83dea09d86e77d87ac30604f2c5b4bf4117") (:keywords "background" "async" "process" "management") (:authors ("Ilya Babanov" . "ilya-babanov@ya.ru")) (:maintainer "Ilya Babanov" . "ilya-babanov@ya.ru") (:url . "https://github.com/ilya-babanov/emacs-bpr"))]) (bpe . [(20141228 2205) ((emacs (24 1))) "Blog from Org mode to Blogger" single ((:commit . "7b5b25f83506e6c9f4075d3803fa32404943a189") (:keywords "blogger" "blog") (:authors ("Yuta Yamada <cokesboy\"at\"gmail.com>")) (:maintainer "Yuta Yamada <cokesboy\"at\"gmail.com>") (:url . "https://github.com/yuutayamada/bpe"))]) (boxquote . [(20170802 1117) ((cl-lib (0 5))) "Quote text with a semi-box." single ((:commit . "7e47e0e2853bc1215739b2e28f260e9eed93b2c5") (:keywords "quoting") (:authors ("Dave Pearson" . "davep@davep.org")) (:maintainer "Dave Pearson" . "davep@davep.org") (:url . "https://github.com/davep/boxquote.el"))]) (boron-theme . [(20170808 1308) ((emacs (24 0))) "an Emacs 24 theme based on Boron (tmTheme)" single ((:commit . "87ae1a765e07429fec25d2f29b004f84b52d2e0a") (:authors ("Jason Milkins")) (:maintainer "Jason Milkins") (:url . "https://github.com/emacsfodder/tmtheme-to-deftheme"))]) (borland-blue-theme . [(20160117 1321) ((emacs (24 1))) "Blue/yellow theme based on old DOS Borland/Turbo C IDE" single ((:commit . "db74eefebbc89d3c62575f8f50b319e87b4a3470") (:keywords "themes") (:authors ("Alexey Veretennikov <alexey dot veretennikov at gmail dot com>")) (:maintainer "Alexey Veretennikov <alexey dot veretennikov at gmail dot com>") (:url . "http://github.com/fourier/borland-blue-theme"))]) (borg . [(20180826 2312) ((emacs (26)) (dash (2 13)) (epkg (3 0)) (magit (2 11))) "assimilate Emacs packages as Git submodules" tar ((:commit . "a495a46ca5c7deece51096a0b8a9e6f819c5382c") (:keywords "tools") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:url . "https://github.com/emacscollective/borg"))]) (boon . [(20180829 751) ((emacs (25 1)) (expand-region (0 10 0)) (dash (2 12 0)) (multiple-cursors (1 3 0))) "Ergonomic Command Mode for Emacs." tar ((:commit . "e95a0623053040945e1eee315762be40327e30bd"))]) (bool-flip . [(20161215 1539) ((emacs (24 3))) "flip the boolean under the point" single ((:commit . "f58a9a7b9ab875bcfbd57c8262697ae404eb4485") (:keywords "boolean" "convenience" "usability") (:authors ("Michael Brandt" . "michaelbrandt5@gmail.com")) (:maintainer "Michael Brandt" . "michaelbrandt5@gmail.com") (:url . "http://github.com/michaeljb/bool-flip/"))]) (boogie-friends . [(20171025 255) ((cl-lib (0 5)) (dash (2 10 0)) (flycheck (0 23)) (yasnippet (0 9 0 1)) (company (0 8 12))) "A collection of programming modes for Boogie, Dafny, and Z3 (SMTLIB v2)." tar ((:commit . "ff9903783013f3598b6f44c99d47b25c5cdbed00"))]) (bonjourmadame . [(20170919 1134) nil "Say \"Hello ma'am!\"" single ((:commit . "d3df185fce78aefa689fded8e56a654f0fde4ac0"))]) (bongo . [(20171119 242) ((cl-lib (0 5)) (emacs (24 1))) "play music with Emacs" tar ((:commit . "3d246be1e8d14865f5253567ab8fee5d4e9c470c"))]) (bolt-mode . [(20180310 810) ((emacs (24 3))) "Editing support for Bolt language" single ((:commit . "85a5a752bfbebb4aed884326c25db64c000e9934") (:keywords "languages") (:authors ("Mikhail Pontus" . "mpontus@gmail.com")) (:maintainer "Mikhail Pontus" . "mpontus@gmail.com") (:url . "https://github.com/mpontus/bolt-mode"))]) (bog . [(20180815 2213) ((cl-lib (0 5))) "Extensions for research notes in Org mode" single ((:commit . "b5df3647f55359f8546dcfa991a351673a069a49") (:keywords "bib" "outlines") (:authors ("Kyle Meyer" . "kyle@kyleam.com")) (:maintainer "Kyle Meyer" . "kyle@kyleam.com") (:url . "https://github.com/kyleam/bog"))]) (bnfc . [(20160605 1927) ((emacs (24 3))) "Define context-free grammars for the BNFC tool" single ((:commit . "1b58df1dd0cb9b81900632fb2843a03b94f56fdb") (:keywords "languages" "tools") (:authors ("Jacob Mitchell" . "jmitchell@member.fsf.org")) (:maintainer "Jacob Mitchell" . "jmitchell@member.fsf.org") (:url . "https://github.com/jmitchell/bnfc-mode"))]) (bmx-mode . [(20180324 1557) ((emacs (25 1)) (cl-lib (0 5)) (company (0 9 4)) (dash (2 13 0)) (s (1 12 0))) "Batch Mode eXtras" single ((:commit . "7450c29f5c1f5f67b02bca1c89f06cdf01855f41") (:keywords "c" "convenience" "tools") (:authors ("Jostein Kjønigsen" . "jostein@gmail.com")) (:maintainer "Jostein Kjønigsen" . "jostein@gmail.com") (:url . "http://github.com/josteink/bmx-mode"))]) (bm . [(20180703 1043) nil "Visible bookmarks in buffer." tar ((:commit . "210cbdaad96a1019bdf5b060fc7892f778e8729c") (:keywords "bookmark" "highlight" "faces" "persistent") (:authors ("Jo Odland <jo.odland(at)gmail.com>")) (:maintainer "Jo Odland <jo.odland(at)gmail.com>") (:url . "https://github.com/joodland/bm"))]) (blog-minimal . [(20170311 1355) ((ht (1 5)) (simple-httpd (1 4 6)) (mustache (0 22)) (s (1 11 0)) (org (9 0 3))) "a very simple static site generator based on org mode" tar ((:commit . "d679d74039ecc114b037800c8a94303265b9542a") (:keywords "blog" "org") (:authors ("Thank Fly" . "thiefuniverses@gmail.com")) (:maintainer "Thank Fly" . "thiefuniverses@gmail.com") (:url . "https://github.com/thiefuniverse/blog-minimal"))]) (blog-admin . [(20170923 1409) ((ctable (0 1 1)) (s (1 10 0)) (f (0 17 3)) (names (20151201 0)) (cl-lib (0 5))) "Blog admin for emacs with hexo/org-page supported" tar ((:commit . "b5f2e1dad7d68ec903619f7280bb0bcb7e398a1e") (:keywords "tools" "blog" "org" "hexo" "org-page") (:authors (nil . "code.falling@gmail.com")) (:maintainer nil . "code.falling@gmail.com"))]) (blockdiag-mode . [(20160427 524) ((emacs (24 3))) "Major mode for editing blockdiag files" single ((:commit . "f3b21ba433d60327cebd103ae4492200750e24a9") (:authors ("xcezx" . "main.xcezx@gmail.com")) (:maintainer "xcezx" . "main.xcezx@gmail.com") (:url . "https://github.com/xcezx/xdiag-mode"))]) (bln-mode . [(20180730 1223) nil "binary line navigation minor mode for cursor movement in long lines" single ((:commit . "b5e86b1bc8b7ac25bf8ec07056824861c4c3f050") (:keywords "motion" "location" "cursor" "convenience") (:authors ("Maarten Grachten")) (:maintainer "Maarten Grachten") (:url . "https://github.com/mgrachten/bln-mode"))]) (bliss-theme . [(20170808 1307) ((emacs (24 0))) "an Emacs 24 theme based on Bliss (tmTheme)" single ((:commit . "c3cf6d8a666ab26909b7da158f9e94df71a5fbbf") (:authors ("Jason Milkins")) (:maintainer "Jason Milkins") (:url . "https://github.com/emacsfodder/tmtheme-to-deftheme"))]) (blimp . [(20180903 2240) ((emacs (25)) (eimp (1 4 0))) "Bustling Image Manipulation Package" single ((:commit . "b048b037129b68674b99310bcc08fb96d44fdbb4") (:keywords "multimedia" "unix") (:authors ("Sebastian Wålinder" . "s.walinder@gmail.com")) (:maintainer "Sebastian Wålinder" . "s.walinder@gmail.com") (:url . "https://github.com/walseb/blimp"))]) (blgrep . [(20150401 1416) ((clmemo (20140321 715))) "Block grep" tar ((:commit . "605beda210610a5829750a987f5fcebea97af546") (:keywords "tools" "convenience") (:authors ("Masayuki Ataka" . "masayuki.ataka@gmail.com")) (:maintainer "Masayuki Ataka" . "masayuki.ataka@gmail.com"))]) (blacken . [(20180901 528) ((emacs (25 2))) "Reformat python buffers using the \"black\" formatter" single ((:commit . "48061012139d4524619dd90ce5b33775e394dabe") (:authors ("Artem Malyshev" . "proofit404@gmail.com")) (:maintainer "Artem Malyshev" . "proofit404@gmail.com") (:url . "https://github.com/proofit404/blacken"))]) (blackboard-theme . [(20161216 656) ((emacs (24))) "TextMate Blackboard Theme" single ((:commit . "d8b984f2541bb86eb4363a2b4c94631e49843d4a") (:authors ("Dong Zheng")) (:maintainer "Dong Zheng") (:url . "https://github.com/don9z/blackboard-theme"))]) (blackboard-bold-mode . [(20160813 206) ((cl-lib (0 5))) "Easily insert Unicode mathematical double-struck characters" single ((:commit . "5299cb064ba71baa3e331b8560bf8dd38cbbc4ed") (:keywords "unicode" "double struck" "blackboard bold" "math" "mathematical") (:authors ("Grant Rettke" . "gcr@wisdomandwonder.com")) (:maintainer nil . "<gcr@wisdomandwonder.com>") (:url . "https://github.com/grettke/blackboard-bold-mode"))]) (bitlbee . [(20151203 0) nil "Help get Bitlbee (http://www.bitlbee.org) up and running." single ((:commit . "3a92a4119e0c007df2c7dcf1b1c3a5f23ee40e05"))]) (bitbucket . [(20170405 446) ((emacs (24)) (request (0 1 0)) (s (1 9 0))) "Bitbucket API wrapper" tar ((:commit . "5e663da1bd38a14c1ecf4d66a79d4321ac833bcf") (:keywords "bitbucket") (:authors ("2017 Tjaart van der Walt" . "tjaart@tjaart.co.za")) (:maintainer "2017 Tjaart van der Walt" . "tjaart@tjaart.co.za") (:url . "http://github.com/tjaartvdwalt/bitbucket.el/"))]) (bitbake . [(20180326 758) ((emacs (24 1)) (dash (2 6 0)) (mmm-mode (0 5 4)) (s (1 10 0))) "Running bitbake from emacs" single ((:commit . "e5088c4b3dfb4feb96850fbc281b4207d23c7713") (:keywords "convenience") (:authors ("Damien Merenne")) (:maintainer "Damien Merenne") (:url . "https://github.com/canatella/bitbake-el"))]) (bison-mode . [(20160617 552) nil "Major mode for editing bison, yacc and lex files." single ((:commit . "314af3b7af7eb897fd3932616cb8600a85228cea") (:keywords "bison-mode" "yacc-mode") (:authors ("Eric Beuscher" . "beuscher@eecs.tulane.edu")) (:maintainer "Eric Beuscher" . "beuscher@eecs.tulane.edu"))]) (birds-of-paradise-plus-theme . [(20130419 2129) nil "A brown/orange light-on-dark theme for Emacs 24 (deftheme)." single ((:commit . "bb9f9d4ef7f7872a388ec4eee1253069adcadb6f") (:keywords "themes") (:authors ("Jim Myhrberg" . "contact@jimeh.me")) (:maintainer "Jim Myhrberg" . "contact@jimeh.me") (:url . "https://github.com/jimeh/birds-of-paradise-plus-theme.el"))]) (bing-dict . [(20170605 131) nil "Minimalists' English-Chinese Bing dictionary" single ((:commit . "d4b261739e53e8ed8fa5db3d3946de82c0ab8e34") (:keywords "extensions") (:authors ("Junpeng Qiu" . "qjpchmail@gmail.com")) (:maintainer "Junpeng Qiu" . "qjpchmail@gmail.com") (:url . "https://github.com/cute-jumper/bing-dict.el"))]) (bind-map . [(20161207 1511) ((emacs (24 3))) "Bind personal keymaps in multiple locations" single ((:commit . "bf4181e3a41463684adfffc6c5c305b30480e30f") (:authors ("Justin Burkett" . "justin@burkett.cc")) (:maintainer "Justin Burkett" . "justin@burkett.cc") (:url . "https://github.com/justbur/emacs-bind-map"))]) (bind-key . [(20180513 430) nil "A simple way to manage personal keybindings" single ((:commit . "3fb8f39f5901a4c0ef7887283e56e60b541675ea") (:keywords "keys" "keybinding" "config" "dotemacs") (:authors ("John Wiegley" . "johnw@newartisans.com")) (:maintainer "John Wiegley" . "johnw@newartisans.com") (:url . "https://github.com/jwiegley/use-package"))]) (bind-chord . [(20171204 2010) ((bind-key (1 0)) (key-chord (0 6))) "key-chord binding helper for use-package-chords" single ((:commit . "3fb8f39f5901a4c0ef7887283e56e60b541675ea") (:keywords "convenience" "tools" "extensions") (:authors ("Justin Talbott" . "justin@waymondo.com")) (:maintainer "Justin Talbott" . "justin@waymondo.com") (:url . "https://github.com/waymondo/use-package-chords"))]) (binclock . [(20170802 1116) ((cl-lib (0 5))) "Display the current time using a binary clock." single ((:commit . "87042230d7f3fe3e9a77fae0dbab7d8f7e7794ad") (:keywords "games" "time" "display") (:authors ("Dave Pearson" . "davep@davep.org")) (:maintainer "Dave Pearson" . "davep@davep.org") (:url . "https://github.com/davep/binclock.el"))]) (bifocal . [(20171004 1824) ((emacs (24 4))) "Split-screen scrolling for comint-mode buffers" single ((:commit . "a8b222b069a6bd64531b4780905989797bad8abe") (:keywords "frames" "processes" "tools") (:url . "https://github.com/riscy/bifocal-mode"))]) (bicycle . [(20180624 712) ((emacs (25 1))) "cycle outline and code visibility" single ((:commit . "ab48f01ec8a3ebcb2f6cf36ea7f3cb8aef3da263") (:keywords "outlines") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:url . "https://github.com/tarsius/bicycle"))]) (bibtex-utils . [(20170817 1919) nil "Provides utilities for extending BibTeX mode" single ((:commit . "ed5ccce46c2088a28a2f0c49caa679d2f20567f0") (:keywords "bibtex") (:authors ("Tyler Smith" . "tyler@plantarum.ca")) (:maintainer "Tyler Smith" . "tyler@plantarum.ca") (:url . "https://github.com/plantarum/bibtex-utils"))]) (bibslurp . [(20151202 2346) ((s (1 6 0)) (dash (1 5 0))) "retrieve BibTeX entries from NASA ADS" single ((:commit . "aeba96368f2a06959e4fe945375ce2a54d34b189") (:keywords "bibliography" "nasa ads") (:url . "https://github.com/mkmcc/bibslurp"))]) (bibretrieve . [(20180901 928) ((auctex (11 87)) (emacs (24 3))) "Retrieve BibTeX entries from the internet" tar ((:commit . "600fa1fcc4c5d79c628457f2316f3429c96be006") (:keywords "bibtex" "bibliography" "mathscinet" "arxiv" "zbmath") (:authors ("Antonio Sartori")) (:maintainer "Pavel Zorin-Kranich" . "pzorin@uni-bonn.de") (:url . "https://github.com/pzorin/bibretrieve"))]) (bibliothek . [(20180429 2215) ((emacs (24 4)) (pdf-tools (0 70)) (a (0 1 0 -3 4))) "Managing a digital library of PDFs" single ((:commit . "05f2655321f020fd4c069d1939f0902eaa837eb4") (:keywords "tools") (:authors ("Göktuğ Kayaalp" . "self@gkayaalp.com")) (:maintainer "Göktuğ Kayaalp" . "self@gkayaalp.com") (:url . "https://cadadr.github.io/elisp/index.html#bibliothek-el"))]) (biblio-core . [(20160901 1815) ((emacs (24 3)) (let-alist (1 0 4)) (seq (1 11)) (dash (2 12 1))) "A framework for looking up and displaying bibliographic entries" single ((:commit . "a5a68fcf677f286f205f32dc7486f6c9f66aa6af") (:keywords "bib" "tex" "convenience" "hypermedia") (:authors ("Clément Pit-Claudel" . "clement.pitclaudel@live.com")) (:maintainer "Clément Pit-Claudel" . "clement.pitclaudel@live.com") (:url . "http://github.com/cpitclaudel/biblio.el"))]) (biblio . [(20161014 2304) ((emacs (24 3)) (biblio-core (0 2))) "Browse and import bibliographic references from CrossRef, arXiv, DBLP, HAL, Dissemin, and doi.org" tar ((:commit . "a5a68fcf677f286f205f32dc7486f6c9f66aa6af"))]) (bfbuilder . [(20150924 1650) ((cl-lib (0 3))) "A brainfuck development environment with interactive debugger" single ((:commit . "49560bdef131fa5672dab660e0c62376dbdcd906") (:authors ("zk_phi")) (:maintainer "zk_phi") (:url . "http://hins11.yu-yake.com/"))]) (bf-mode . [(20130403 1442) nil "Browse file persistently on dired" single ((:commit . "7cc4d09aed64d9db6be95646f5f5067de68f8895") (:keywords "convenience") (:authors ("isojin")) (:maintainer "myuhe <yuhei.maeda_at_gmail.com>") (:url . "https://github.com/emacs-jp/bf-mode"))]) (better-shell . [(20180625 1316) ((emacs (24 4))) "Better shell management" single ((:commit . "cfcd9d57f87ad68cd72bf4935fd1aaa1d9f059a9") (:keywords "convenience") (:authors ("Russell Black" . "killdash9@github")) (:maintainer "Russell Black" . "killdash9@github") (:url . "https://github.com/killdash9/better-shell"))]) (better-defaults . [(20170614 404) nil "Fixing weird quirks and poor defaults" single ((:commit . "ab830cf1a0987f43e419565404a4fa8c0a2f5560") (:keywords "convenience") (:authors ("Phil Hagelberg")) (:maintainer "Phil Hagelberg") (:url . "https://github.com/technomancy/better-defaults"))]) (bert . [(20131117 1014) nil "BERT serialization library for Emacs" single ((:commit . "a3eec6980a725aa4abd2019e4c00246450260490") (:keywords "comm" "data") (:authors ("Oleksandr Manzyuk" . "manzyuk@gmail.com")) (:maintainer "Oleksandr Manzyuk" . "manzyuk@gmail.com"))]) (benchstat . [(20171014 312) nil "proper benchmarking made simple" single ((:commit . "a5b67cf7972ca2bbc9f5bc6a0f521ab02b76d4f0") (:keywords "lisp") (:authors ("Iskander Sharipov" . "quasilyte@gmail.com")) (:maintainer "Iskander Sharipov" . "quasilyte@gmail.com") (:url . "https://github.com/Quasilyte/benchstat.el"))]) (benchmark-init . [(20150905 938) nil "Benchmarks Emacs require and load calls" tar ((:commit . "7a0f263282bbc86b01b662636306f22813082647") (:keywords "benchmark") (:authors ("Steve Purcell")) (:maintainer "David Holm" . "dholmster@gmail.com"))]) (belarus-holidays . [(20180615 1311) nil "Belarus holidays whith transfers" single ((:commit . "410a7dcf46fdcbee762a0c0aa0c7af03230b9656") (:authors ("Yauhen Makei" . "yauhen.makei@gmail.com")) (:maintainer "Yauhen Makei" . "yauhen.makei@gmail.com") (:url . "http://bitbucket.org/EugeneMakei/belarus-holidays.el"))]) (beginend . [(20180827 926) ((emacs (25 3))) "Redefine M-< and M-> for some modes" single ((:commit . "e4ff077de4a2c80e1f42adfc86837537899447a5") (:url . "https://github.com/DamienCassou/beginend"))]) (beeminder . [(20180413 1929) ((org (7))) "Emacs interface for Beeminder" tar ((:commit . "3fcee7a7003a37171ddb59171c7f4b5dd4b34349") (:keywords "beeminder") (:authors ("Phil Newton" . "phil@sodaware.net")) (:maintainer "Phil Newton" . "phil@sodaware.net") (:url . "http://www.philnewton.net/code/beeminder-el/"))]) (beacon . [(20180706 1725) ((seq (2 14))) "Highlight the cursor whenever the window scrolls" single ((:commit . "8dfe64496be3cb79d5b83891f95b70b1b699470b") (:keywords "convenience") (:authors ("Artur Malabarba" . "emacs@endlessparentheses.com")) (:maintainer "Artur Malabarba" . "emacs@endlessparentheses.com") (:url . "https://github.com/Malabarba/beacon"))]) (bdo . [(20140126 901) nil "Do things to a browser page from Emacs. BETA!" tar ((:commit . "c96cb6aa9e97fa3491185c50dee0f77a13241010") (:keywords "development") (:authors ("Chris Done" . "chrisdone@gmail.com")) (:maintainer "Chris Done" . "chrisdone@gmail.com"))]) (bbyac . [(20180206 1441) ((browse-kill-ring (1 3)) (cl-lib (0 5))) "Type a little Bit, and Bang! You Are Completed." tar ((:commit . "9f0de9cad13801891ffb590dc09f51ff9a7cb225") (:keywords "abbrev") (:authors ("Bao Haojun" . "baohaojun@gmail.com")) (:maintainer "Bao Haojun" . "baohaojun@gmail.com") (:url . "https://github.com/baohaojun/bbyac"))]) (bbdb2erc . [(20170221 1354) ((bbdb (3 0))) "make bbdb show if pal is online with ERC, click i to chat" single ((:commit . "15db2bd29df0f6ee32c499fdeffb960b6a7f97a0") (:keywords "irc" "contacts" "chat" "client" "internet") (:authors ("Kevin Brubeck Unhammer" . "unhammer@fsfe.org")) (:maintainer "Kevin Brubeck Unhammer" . "unhammer@fsfe.org"))]) (bbdb-vcard . [(20150713 2050) ((bbdb (3 0))) "vCard import/export for BBDB" tar ((:commit . "c3aafd4160854a38fd92afcdade32b9a13abe82c") (:keywords "data" "calendar" "mail" "news") (:authors ("Bert Burgemeister" . "trebbu@googlemail.com") ("Toke Høiland-Jørgensen") ("Kevin Brubeck Unhammer") ("Steve Purcell") ("Vincent Geddes" . "vincent.geddes@gmail.com")) (:maintainer "Bert Burgemeister" . "trebbu@googlemail.com") (:url . "http://github.com/vgeddes/bbdb-vcard"))]) (bbdb-ext . [(20151220 2013) ((bbdb (2 36))) "Extra commands for BBDB" single ((:commit . "fee97b1b3faa83edaea00fbc5ad3cbca5e791a55") (:keywords "extensions") (:authors ("Joe Bloggs" . "vapniks@yahoo.com")) (:maintainer "Joe Bloggs" . "vapniks@yahoo.com") (:url . "https://github.com/vapniks/bbdb-ext"))]) (bbdb-csv-import . [(20180122 49) ((pcsv (1 3 3)) (dash (2 5 0)) (bbdb (20140412 1949))) "import csv to bbdb version 3+" single ((:commit . "dbc2e0fe9e8ae65e494011044d905ae79b3cee3e") (:keywords "csv" "util" "bbdb") (:authors ("Ian Kelling" . "ian@iankelling.org")) (:maintainer "Ian Kelling" . "ian@iankelling.org") (:url . "https://gitlab.com/iankelling/bbdb-csv-import"))]) (bbdb . [(20180503 338) nil "The Insidious Big Brother Database for GNU Emacs" tar ((:commit . "2da950300bb22fa713cede74b71041df315ecc2e"))]) (bbdb- . [(20140221 2354) ((bbdb (20140123 1541)) (log4e (0 2 0)) (yaxception (0 1))) "provide interface for more easily search/choice than BBDB." single ((:commit . "2839e84c894de2513af41053e80a277a1b483d22") (:keywords "bbdb" "news" "mail") (:authors ("Hiroaki Otsu" . "ootsuhiroaki@gmail.com")) (:maintainer "Hiroaki Otsu" . "ootsuhiroaki@gmail.com") (:url . "https://github.com/aki2o/bbdb-"))]) (bbcode-mode . [(20180505 927) ((cl-lib (0 5))) "Major mode for phpBB posts (BBCode markup)" single ((:commit . "ee30d43f9029e0919a06be0dde0ed16f201647c1") (:keywords "bbcode" "languages") (:authors ("Eric James Michael Ritz" . "lobbyjones@gmail.com")) (:maintainer "Lassi Kortela" . "lassi@lassi.io") (:url . "https://github.com/lassik/bbcode-mode"))]) (bazel-mode . [(20180223 653) ((emacs (24 3))) "A major mode for editing Bazel files" single ((:commit . "b7aa14516feaed40ee4910eafa81db719de0fe56") (:keywords "languages" "bazel") (:authors ("Neri Marschik")) (:maintainer "Neri Marschik") (:url . "https://github.com/codesuki/bazel-mode"))]) (bats-mode . [(20160514 615) nil "Emacs mode for editing and running Bats tests" single ((:commit . "d519f7c89f5ae17dfc33400596df4564b478315f") (:keywords "bats" "tests") (:authors ("Doug MacEachern")) (:maintainer "Doug MacEachern") (:url . "https://github.com/dougm/bats-mode"))]) (basic-theme . [(20160817 827) ((emacs (24))) "Minimalistic light color theme" single ((:commit . "e2a855bd39f4b78296228d4b790f9123156f7d7e") (:keywords "theme" "basic" "minimal" "colors") (:authors ("Felix Geller" . "fgeller@gmail.com")) (:maintainer "Felix Geller" . "fgeller@gmail.com") (:url . "http://github.com/fgeller/basic-theme.el"))]) (basic-mode . [(20180612 1852) ((seq (2 20)) (emacs (24 3))) "major mode for editing BASIC code" single ((:commit . "024505ae0a37756e3259773383852ed208120bde") (:keywords "basic" "languages") (:authors ("Johan Dykstrom")) (:maintainer "Johan Dykstrom") (:url . "https://github.com/dykstrom/basic-mode"))]) (basic-c-compile . [(20170302 1112) ((cl-lib (0 5)) (f (0 19 0))) "Quickly create a Makefile, compile and run C." single ((:commit . "0129786aeee50d7bb0020d9fc2b7508875d403e8") (:keywords "c" "makefile" "compilation" "convenience") (:authors ("Nick Spain" . "nicholas.spain96@gmail.com")) (:maintainer "Nick Spain" . "nicholas.spain96@gmail.com") (:url . "https://github.com/nick96/basic-c-compile"))]) (bash-completion . [(20180519 1620) nil "BASH completion for the shell buffer" single ((:commit . "fbdc78b8770833752ac4bda28e2c3ea764bf8e76") (:authors ("Stephane Zermatten" . "szermatt@gmx.net")) (:maintainer "Stephane Zermatten" . "szermatt@gmx.net"))]) (base16-theme . [(20180524 2011) nil "Collection of themes built on combinations of 16 base colors" tar ((:commit . "c9acfddcc0a3a3753223d4e8742de6af284154cc") (:url . "https://github.com/belak/base16-emacs"))]) (bart-mode . [(20180201 229) ((emacs (24 3))) "Real time BART departures info." single ((:commit . "6feeb8f9badbc2ce4b60499bf7bf4acdae4cfed7") (:keywords "convenience" "transit") (:authors ("Michael Schuldt" . "mbschuldt@gmail.com")) (:maintainer "Michael Schuldt" . "mbschuldt@gmail.com") (:url . "https://github.com/mschuldt/bart-mode"))]) (bar-cursor . [(20180227 45) nil "package used to switch block cursor to a bar" single ((:commit . "20cb59bedc3532a712fe7feeff3660ebd72a8107") (:keywords "files") (:authors ("Joe Casadonte" . "emacs@northbound-train.com")) (:maintainer "Andrew Johnson" . "andrew@andrewjamesjohnson.com") (:url . "https://github.com/ajsquared/bar-cursor"))]) (bap-mode . [(20180802 1310) nil "Major-mode for BAP's IR" single ((:commit . "b74e583fa1e82046d79df21be225f9409698d293") (:keywords "languages") (:authors ("Thomas Barabosch <http://github/tbarabosch>")) (:maintainer "Thomas Barabosch" . "thomas.barabosch@fkie.fraunhofer.de") (:url . "https://github.com/fkie-cad/bap-mode"))]) (banner-comment . [(20180510 1320) ((emacs (24 4))) "For producing banner comments." single ((:commit . "fedbb071d043106a30e378ee58b96e349e8068ed") (:keywords "convenience") (:authors ("James Ferguson" . "james@faff.org")) (:maintainer "James Ferguson" . "james@faff.org") (:url . "https://github.com/WJCFerguson/banner-comment"))]) (badwolf-theme . [(20161004 715) ((emacs (24))) "Bad Wolf color theme" single ((:commit . "ea01a3d9358e968f75e3ed15dec6a2a96ce3d9a1") (:keywords "themes") (:authors ("bkruczyk" . "bartlomiej.kruczyk@gmail.com")) (:maintainer "bkruczyk" . "bartlomiej.kruczyk@gmail.com") (:url . "https://github.com/bkruczyk/badwolf-emacs"))]) (badger-theme . [(20140717 232) nil "A dark theme for Emacs 24." single ((:commit . "493d672d5a5478976da7d5ca752008cc7837c57f") (:authors ("Cody Canning" . "cocanning11@gmail.com")) (:maintainer "Cody Canning" . "cocanning11@gmail.com") (:url . "https://github.com/ccann/badger-theme"))]) (backward-forward . [(20161229 550) ((emacs (24 5))) "navigation backwards and forwards across marks" single ((:commit . "58489957a62a0da25dfb5df902624d2548d800b4") (:keywords "navigation" "convenience" "backward" "forward") (:authors ("Currell Berry" . "currellberry@gmail.com")) (:maintainer "Currell Berry" . "currellberry@gmail.com") (:url . "https://gitlab.com/vancan1ty/emacs-backward-forward/tree/master"))]) (backup-walker . [(20130720 1516) nil "quickly traverse all backups of a file" single ((:commit . "934a4128c122972ac32bb9952addf279a60a94da") (:keywords "backup") (:authors ("Le Wang")) (:maintainer "Le Wang") (:url . "https://github.com/lewang/backup-walker"))]) (backup-each-save . [(20180227 557) nil "backup each savepoint of a file" single ((:commit . "3c414b9d6b278911c95c5b8b71819e6af6f8a02a") (:authors ("Benjamin Rutt" . "brutt@bloomington.in.us")) (:maintainer "Conor Nash" . "conor@nashcobusinessservicesllc.com"))]) (backlight . [(20180629 2159) ((emacs (24 3))) "backlight brightness adjustment on GNU/Linux" single ((:commit . "096e632bf100d318754d6c961c90ebb0ef29dce5") (:keywords "hardware") (:authors ("Michael Schuldt" . "mbschuldt@gmail.com")) (:maintainer "Michael Schuldt" . "mbschuldt@gmail.com") (:url . "https://github.com/mschuldt/backlight.el"))]) (back-button . [(20150804 2004) ((nav-flash (1 0 0)) (smartrep (0 0 3)) (ucs-utils (0 7 2)) (list-utils (0 4 2)) (persistent-soft (0 8 8)) (pcache (0 2 3))) "Visual navigation through mark rings" single ((:commit . "98d92984a740acd1547bd7ed05cca0affdb21c3e") (:keywords "convenience" "navigation" "interface") (:authors ("Roland Walker" . "walker@pobox.com")) (:maintainer "Roland Walker" . "walker@pobox.com") (:url . "http://github.com/rolandwalker/back-button"))]) (babel-repl . [(20160504 2201) ((emacs (24))) "Run babel REPL" single ((:commit . "e619c16e349a1ee7bd0ee0d7f3650d33bff73fc3") (:keywords "babel" "javascript" "es6") (:authors ("Hung Phan")) (:maintainer "Hung Phan") (:url . "https://github.com/hung-phan/babel-repl/"))]) (babel . [(20161123 740) nil "interface to web translation services such as Babelfish" single ((:commit . "d4212e25fcbd22b8e38be13936f937a2963d34a9") (:keywords "translation" "web") (:authors ("Juergen Hoetzel" . "juergen@hoetzel.info") ("Eric Marsden" . "emarsden@laas.fr")) (:maintainer "Juergen Hoetzel" . "juergen@hoetzel.info") (:url . "http://github.com/juergenhoetzel/babel"))]) (axiom-environment . [(20180823 955) ((emacs (24 2))) "An environment for using Axiom/OpenAxiom/FriCAS" tar ((:commit . "5d6b2cd12f639c11b032185c4c5fe4f5bba15b08") (:keywords "axiom" "openaxiom" "fricas") (:authors ("Paul Onions" . "paul.onions@acm.org")) (:maintainer "Paul Onions" . "paul.onions@acm.org"))]) (aws-snippets . [(20180410 1545) ((yasnippet (0 8 0))) "Yasnippets for AWS" tar ((:commit . "a2ebae582a8c8a5f5f16dbc42ecd2ded9d70fca8") (:keywords "snippets"))]) (aws-ec2 . [(20161007 1914) ((emacs (24 4)) (dash (2 12 1)) (tblui (0 1 0))) "Manage AWS EC2 instances" single ((:commit . "5601d4f268fc34b86a02ca90cde7d3771619a368") (:authors ("Yuki Inoue <inouetakahiroki _at_ gmail.com>")) (:maintainer "Yuki Inoue <inouetakahiroki _at_ gmail.com>") (:url . "https://github.com/Yuki-Inoue/aws.el"))]) (avy-zap . [(20160921 2144) ((avy (0 2 0))) "Zap to char using `avy'" single ((:commit . "6081738668ab726099ce1c711c580d9745dfaede") (:keywords "extensions") (:authors ("Junpeng Qiu" . "qjpchmail@gmail.com")) (:maintainer "Junpeng Qiu" . "qjpchmail@gmail.com") (:url . "https://github.com/cute-jumper/avy-zap"))]) (avy-migemo . [(20180716 1455) ((emacs (24 4)) (avy (0 4 0)) (migemo (1 9))) "avy with migemo" tar ((:commit . "922a6dd82c0bfa316b0fbb56a9d4dd4ffa5707e7") (:keywords "avy" "migemo") (:authors ("momomo5717")) (:maintainer "momomo5717") (:url . "https://github.com/momomo5717/avy-migemo"))]) (avy-menu . [(20180101 620) ((emacs (24 3)) (avy (0 3 0))) "Library providing avy-powered popup menu" single ((:commit . "b133564cc438870d9b5505c8104611c8998fd0d5") (:keywords "popup" "menu") (:authors ("Mark Karpov" . "markkarpov92@gmail.com")) (:maintainer "Mark Karpov" . "markkarpov92@gmail.com") (:url . "https://github.com/mrkkrp/avy-menu"))]) (avy-flycheck . [(20160720 1500) ((emacs (24 1)) (flycheck (0 14)) (seq (1 11)) (avy (0 4 0))) "Jump to and fix syntax errors using `flycheck' with `avy' interface" single ((:commit . "5522f3bbbed1801d9278ed696ec0cbba38352985") (:keywords "tools" "convenience" "avy" "flycheck") (:authors ("Xu Ma" . "magicdirac@gmail.com")) (:maintainer "Xu Ma" . "magicdirac@gmail.com") (:url . "https://github.com/magicdirac/avy-flycheck"))]) (avy . [(20180814 2121) ((emacs (24 1)) (cl-lib (0 5))) "Jump to arbitrary positions in visible text and select text quickly." single ((:commit . "a29558d22ce9af163b7959da663a22fcedc9c163") (:keywords "point" "location") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:url . "https://github.com/abo-abo/avy"))]) (avk-emacs-themes . [(20180822 1539) nil "Collection of avk themes" tar ((:commit . "80a8e4f88ccd4a9ff29dc50afb2da6aa290611d8") (:url . "https://github.com/avkoval/avk-emacs-themes"))]) (avandu . [(20170101 1903) nil "Gateway to Tiny Tiny RSS" tar ((:commit . "f44588d8e747fa880411cb4542cc39962252b90a") (:keywords "net") (:authors ("Tom Willemse" . "tom@ryuslash.org")) (:maintainer "Tom Willemse" . "tom@ryuslash.org"))]) (autumn-light-theme . [(20150515 1447) nil "A light color theme with muted, autumnal colors." single ((:commit . "1e3b2a43a3001e4a97a5ff073ba3f0d2ea3888f9") (:keywords "color" "theme") (:authors ("Adam Alpern" . "adam.alpern@gmail.com")) (:maintainer "Adam Alpern" . "adam.alpern@gmail.com") (:url . "http://github.com/aalpern/emacs-color-theme-autumn-light"))]) (autothemer . [(20170112 2124) ((dash (2 10 0)) (emacs (24)) (cl-lib (0 5))) "Conveniently define themes." single ((:commit . "8c467f57571c154129d660dfccebd151c998f2d9") (:authors ("Sebastian Sturm")) (:maintainer "Sebastian Sturm") (:url . "https://github.com/sebastiansturm/autothemer"))]) (autotetris-mode . [(20141114 1646) ((cl-lib (0 5))) "automatically play tetris" single ((:commit . "0c3a746dcc304a67d2a6e7ad4ef93f512486343a") (:authors ("Christopher Wellons" . "wellons@nullprogram.com")) (:maintainer "Christopher Wellons" . "wellons@nullprogram.com") (:url . "https://github.com/skeeto/autotetris-mode"))]) (autotest . [(20180323 2242) nil "ZenTest's autotest integration with emacs." single ((:commit . "4ce20cc5b25a1f1b4669ea8ff2880ec764eaf7da") (:keywords "testing" "ruby" "convenience") (:authors ("Ryan Davis" . "ryand-ruby@zenspider.com")) (:maintainer "Ryan Davis" . "ryand-ruby@zenspider.com") (:url . "https://github.com/zenspider/elisp/blob/master/autotest.el"))]) (autopair . [(20160304 1237) ((cl-lib (0 3))) "Automagically pair braces and quotes like TextMate" single ((:commit . "2b6d72bccb0ebba6e7e711528872b898b0c65b0a") (:keywords "convenience" "emulations") (:authors ("Joao Tavora <joaotavora [at] gmail.com>")) (:maintainer "Joao Tavora <joaotavora [at] gmail.com>") (:url . "https://github.com/capitaomorte/autopair"))]) (automargin . [(20131112 814) nil "add margins to windows not-splitted, and center them" single ((:commit . "4901d969ad69f5244e6300baab4ba04efed800c3") (:authors ("zk_phi")) (:maintainer "zk_phi") (:url . "http://hins11.yu-yake.com/"))]) (autodisass-llvm-bitcode . [(20150411 125) nil "Automatically disassemble LLVM bitcode" tar ((:commit . "d2579e3a1427af2dc947c343e49eb3434078bf04"))]) (autodisass-java-bytecode . [(20151005 1612) nil "Automatically disassemble Java bytecode" tar ((:commit . "3d61dbe266133c950b39e880f78d142751c7dc4c"))]) (autobookmarks . [(20180531 1906) ((dash (2 10 0)) (cl-lib (0 5))) "Save recently visited files and buffers" single ((:commit . "e971aa49d97da9f7ed760b37e0b674e45f1c5673") (:keywords "files") (:authors ("Matúš Goljer" . "matus.goljer@gmail.com")) (:maintainer "Matúš Goljer" . "matus.goljer@gmail.com"))]) (auto-yasnippet . [(20180503 1908) ((yasnippet (0 8 0))) "Quickly create disposable yasnippets" single ((:commit . "623734aa418b18ff52cb65a0adb9e359aed31615") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:url . "https://github.com/abo-abo/auto-yasnippet"))]) (auto-virtualenvwrapper . [(20180408 1010) ((cl-lib (0 6)) (s (1 10 0)) (virtualenvwrapper (0))) "Lightweight auto activate python virtualenvs" single ((:commit . "e2628408d4e67e1b1714cf7682cff9405e735c81") (:keywords "python" "virtualenv" "tools") (:authors ("Marcwebbie" . "marcwebbie@gmail.com") ("Robert Zaremba" . "robert-zaremba@scale-it.pl")) (:maintainer "Marcwebbie" . "marcwebbie@gmail.com"))]) (auto-virtualenv . [(20170125 1917) ((cl-lib (0 5)) (pyvenv (1 9)) (s (1 10 0))) "Auto activate python virtualenvs" single ((:commit . "3826db66b417788e2b2eb138717255b1f52a55c3") (:keywords "python" "virtualenv" "tools") (:authors ("Marcwebbie" . "marcwebbie@gmail.com")) (:maintainer "Marcwebbie" . "marcwebbie@gmail.com") (:url . "http://github.com/marcwebbie/auto-virtualenv"))]) (auto-sudoedit . [(20180429 643) ((emacs (24)) (f (0 19 0))) "auto sudo edit by tramp" single ((:commit . "5a770615fe2989b3b7cb1435d0e65fa672d775d7") (:authors ("ncaq" . "ncaq@ncaq.net")) (:maintainer "ncaq" . "ncaq@ncaq.net") (:url . "https://github.com/ncaq/auto-sudoedit"))]) (auto-shell-command . [(20180817 1502) ((deferred (20130312)) (popwin (20130329))) "Run the shell command asynchronously that you specified when you save the file." single ((:commit . "a8f9213e3c773b5687b81881240e6e648f2f56ba") (:keywords "shell" "save" "async" "deferred" "auto") (:authors ("ongaeshi")) (:maintainer "ongaeshi"))]) (auto-save-buffers-enhanced . [(20161109 710) nil "Automatically save buffers in a decent way" single ((:commit . "461e8c816c1b7c650be5f209078b381fe55da8c6") (:authors ("Kentaro Kuribayashi" . "kentarok@gmail.com")) (:maintainer "Kentaro Kuribayashi" . "kentarok@gmail.com"))]) (auto-read-only . [(20170306 443) ((cl-lib (0 5))) "Automatically make the buffer to read-only" single ((:commit . "79654f8fc024f383ae7af05487c1345738236500") (:keywords "files" "convenience") (:authors ("USAMI Kenta" . "tadsan@zonu.me")) (:maintainer "USAMI Kenta" . "tadsan@zonu.me") (:url . "https://github.com/zonuexe/auto-read-only.el"))]) (auto-pause . [(20160426 1216) ((emacs (24 4))) "Run processes which will be paused when Emacs is idle" single ((:commit . "a4d778de774ca3895542cb559a953e0d98657338") (:keywords "convenience" "menu") (:authors ("DarkSun" . "lujun9972@gmail.com")) (:maintainer "DarkSun" . "lujun9972@gmail.com") (:url . "https://github.com/lujun9972/auto-pause"))]) (auto-package-update . [(20180712 2045) ((emacs (24 4)) (dash (2 1 0))) "Automatically update Emacs packages." single ((:commit . "55870d313fbe9db40b1a2b59dbc420ba66a9297e") (:keywords "package" "update") (:authors ("Renan Ranelli")) (:maintainer "Renan Ranelli") (:url . "http://github.com/rranelli/auto-package-update.el"))]) (auto-org-md . [(20180213 2343) ((emacs (24 4))) "export a markdown file automatically when you save an org-file" single ((:commit . "9318338bdb7fe8bd698d88f3af89b2d6413efdd2") (:keywords "org" "markdown") (:authors ("jamcha" . "jamcha.aa@gmail.com")) (:maintainer "jamcha" . "jamcha.aa@gmail.com") (:url . "https://github.com/jamcha-aa/auto-org-md"))]) (auto-minor-mode . [(20180527 1123) ((emacs (24 4))) "Enable minor modes by file name and contents" single ((:commit . "c62f4e04c7b73835c399f0348bea0ade2720bcbb") (:keywords "convenience") (:authors ("Joe Wreschnig" . "joe.wreschnig@gmail.com")) (:maintainer "Joe Wreschnig" . "joe.wreschnig@gmail.com") (:url . "https://github.com/joewreschnig/auto-minor-mode"))]) (auto-indent-mode . [(20171222 506) nil "Auto indent Minor mode" tar ((:commit . "28069360a7f89ad0286fd6a53db550752ec58488") (:keywords "auto" "indentation") (:authors ("Matthew L. Fidler, Le Wang & Others")) (:maintainer "Matthew L. Fidler") (:url . "https://github.com/mlf176f2/auto-indent-mode.el/"))]) (auto-highlight-symbol . [(20130313 943) nil "Automatic highlighting current symbol minor mode" single ((:commit . "26573de912d760e04321b350897aea70958cee8b") (:keywords "highlight" "face" "match" "convenience") (:authors ("Mitsuo Saito" . "arch320@NOSPAM.gmail.com")) (:maintainer "Mitsuo Saito" . "arch320@NOSPAM.gmail.com") (:url . "http://github.com/gennad/auto-highlight-symbol/raw/master/auto-highlight-symbol.el"))]) (auto-dim-other-buffers . [(20180612 2341) nil "Makes non-current buffers less prominent" single ((:commit . "ec74b4803adeadf06296c84595fb6ccf4e1b4a3f") (:authors ("Steven Degutis") ("Michal Nazarewicz" . "mina86@mina86.com")) (:maintainer "Michal Nazarewicz" . "mina86@mina86.com") (:url . "https://github.com/mina86/auto-dim-other-buffers.el"))]) (auto-dictionary . [(20150410 1610) nil "automatic dictionary switcher for flyspell" single ((:commit . "b364e08009fe0062cf0927d8a0582fad5a12b8e7") (:keywords "wp") (:authors ("Nikolaj Schumacher <bugs * nschum de>")) (:maintainer "Nikolaj Schumacher <bugs * nschum de>") (:url . "http://nschum.de/src/emacs/auto-dictionary/"))]) (auto-complete-sage . [(20160514 751) ((auto-complete (1 5 1)) (sage-shell-mode (0 1 0))) "An auto-complete source for sage-shell-mode." single ((:commit . "51b8e3905196d266e1f8aa47881189833151b398") (:keywords "sage" "math" "auto-complete") (:authors ("Sho Takemori" . "stakemorii@gmail.com")) (:maintainer "Sho Takemori" . "stakemorii@gmail.com") (:url . "https://github.com/stakemori/auto-complete-sage"))]) (auto-complete-rst . [(20140225 944) ((auto-complete (1 4))) "Auto-complete extension for ReST and Sphinx" tar ((:commit . "4803ce41a96224e6fa54e6741a5b5f40ebed7351") (:authors ("ARAKAKI, Takafumi")) (:maintainer "ARAKAKI, Takafumi") (:url . "https://github.com/tkf/auto-complete-rst"))]) (auto-complete-pcmp . [(20140227 651) ((auto-complete (1 4 0)) (log4e (0 2 0)) (yaxception (0 1))) "Provide auto-complete sources using pcomplete results" single ((:commit . "2595d3dab1ef3549271ca922f212928e9d830eec") (:keywords "completion") (:authors ("Hiroaki Otsu" . "ootsuhiroaki@gmail.com")) (:maintainer "Hiroaki Otsu" . "ootsuhiroaki@gmail.com") (:url . "https://github.com/aki2o/auto-complete-pcmp"))]) (auto-complete-nxml . [(20140221 458) ((auto-complete (1 4))) "do completion by auto-complete.el on nXML-mode" single ((:commit . "ac7b09a23e45f9bd02affb31847263de4180163a") (:keywords "completion" "html" "xml") (:authors ("Hiroaki Otsu" . "ootsuhiroaki@gmail.com")) (:maintainer "Hiroaki Otsu" . "ootsuhiroaki@gmail.com") (:url . "https://github.com/aki2o/auto-complete-nxml"))]) (auto-complete-exuberant-ctags . [(20140320 724) ((auto-complete (1 4 0))) "Exuberant ctags auto-complete.el source" single ((:commit . "ff6121ff8b71beb5aa606d28fd389c484ed49765") (:keywords "anto-complete" "exuberant ctags") (:authors ("Kenichirou Oyama" . "k1lowxb@gmail.com")) (:maintainer "Kenichirou Oyama" . "k1lowxb@gmail.com") (:url . "http://code.101000lab.org"))]) (auto-complete-distel . [(20180827 1344) ((auto-complete (1 4)) (distel-completion-lib (1 0 0))) "Erlang/distel completion backend for auto-complete-mode" single ((:commit . "acc4c0a5521904203d797fe96b08e5fae4233c7e") (:keywords "erlang" "distel" "auto-complete") (:authors ("Sebastian Weddmark Olsson")) (:maintainer "Sebastian Weddmark Olsson") (:url . "github.com/sebastiw/distel-completion"))]) (auto-complete-clang-async . [(20130526 1514) nil "Auto Completion source for clang for GNU Emacs" single ((:commit . "5d9c5cabbb6b31e0ac3637631c0c8b25184aa8b4") (:keywords "completion" "convenience"))]) (auto-complete-clang . [(20140409 752) ((auto-complete (1 3 1))) "Auto Completion source for clang for GNU Emacs" single ((:commit . "a195db1d0593b4fb97efe50885e12aa6764d998c") (:keywords "completion" "convenience") (:authors ("Brian Jiang" . "brianjcj@gmail.com")) (:maintainer "Brian Jiang" . "brianjcj@gmail.com") (:url . "https://github.com/brianjcj/auto-complete-clang"))]) (auto-complete-chunk . [(20140225 946) ((auto-complete (1 4))) "Auto-completion for dot.separated.words." single ((:commit . "a9aa77ffb84a1037984a7ce4dda25074272f13fe") (:authors ("ARAKAKI, Takafumi")) (:maintainer "ARAKAKI, Takafumi") (:url . "https://github.com/tkf/auto-complete-chunk"))]) (auto-complete-c-headers . [(20150912 323) ((auto-complete (1 4))) "An auto-complete source for C/C++ header files" single ((:commit . "52fef720c6f274ad8de52bef39a343421006c511") (:keywords "c") (:authors ("Masafumi Oyamada" . "stillpedant@gmail.com")) (:maintainer "Masafumi Oyamada" . "stillpedant@gmail.com"))]) (auto-complete-auctex . [(20140223 1758) ((yasnippet (0 6 1)) (auto-complete (1 4))) "auto-completion for auctex" single ((:commit . "855633f668bcc4b9408396742a7cb84e0c4a2f77") (:authors ("Christopher Monsanto" . "chris@monsan.to")) (:maintainer "Christopher Monsanto" . "chris@monsan.to"))]) (auto-complete . [(20170125 245) ((popup (0 5 0)) (cl-lib (0 5))) "Auto Completion for GNU Emacs" tar ((:commit . "2e83566ddfa758c69afe50b8a1c62a66f47471e3"))]) (auto-compile . [(20180321 1507) ((emacs (24 3)) (packed (2 0 0))) "automatically compile Emacs Lisp libraries" single ((:commit . "6ce4255ab9a0b010ef8414c5bd9a6d6d9eea012f") (:keywords "compile" "convenience" "lisp") (:authors ("Jonas Bernoulli" . "jonas@bernoul.li")) (:maintainer "Jonas Bernoulli" . "jonas@bernoul.li") (:url . "https://github.com/emacscollective/auto-compile"))]) (auto-auto-indent . [(20131106 1903) ((es-lib (0 1)) (cl-lib (1 0))) "Indents code as you type" single ((:commit . "0139378577f936d34b20276af6f022fb457af490") (:authors ("sabof")) (:maintainer "sabof") (:url . "https://github.com/sabof/auto-auto-indent"))]) (auto-async-byte-compile . [(20160916 454) nil "Automatically byte-compile when saved" single ((:commit . "8681e74ddb8481789c5dbb3cafabb327db4c4484") (:keywords "lisp" "convenience") (:authors ("rubikitch" . "rubikitch@ruby-lang.org")) (:maintainer "rubikitch" . "rubikitch@ruby-lang.org") (:url . "http://www.emacswiki.org/cgi-bin/wiki/download/auto-async-byte-compile.el"))]) (auth-source-pass . [(20180529 1357) ((emacs (25))) "Integrate auth-source with password-store" single ((:commit . "3de8bbb51054f495f0363a3121f287b15e0d9049") (:authors ("Damien Cassou" . "damien@cassou.me") ("Nicolas Petton" . "nicolas@petton.fr")) (:maintainer "Damien Cassou" . "damien@cassou.me") (:url . "https://github.com/DamienCassou/auth-password-store"))]) (aurora-config-mode . [(20180216 2302) nil "Major mode for Apache Aurora configuration files" single ((:commit . "8273ec7937a21b469b9dbb6c11714255b890f410") (:keywords "languages" "configuration") (:authors ("Berk D. Demir" . "bdd@mindcast.org")) (:maintainer "Berk D. Demir" . "bdd@mindcast.org") (:url . "https://github.com/bdd/aurora-config.el"))]) (aurel . [(20170114 937) ((emacs (24 3)) (bui (1 1 0)) (dash (2 11 0))) "Search, get info, vote for and download AUR packages" single ((:commit . "fc7ad208f43f8525f84a18941c9b55f956df8961") (:keywords "tools") (:authors ("Alex Kost" . "alezost@gmail.com")) (:maintainer "Alex Kost" . "alezost@gmail.com") (:url . "https://github.com/alezost/aurel"))]) (audio-notes-mode . [(20170611 2159) nil "Play audio notes synced from somewhere else." single ((:commit . "fa38350829c7e97257efc746a010471d33748a68") (:keywords "hypermedia" "convenience") (:authors ("Artur Malabarba" . "bruce.connor.am@gmail.com")) (:maintainer "Artur Malabarba" . "bruce.connor.am@gmail.com") (:url . "http://github.com/Bruce-Connor/audio-notes-mode"))]) (auctex-lua . [(20151121 1610) ((auctex (11 86)) (lua-mode (20130419))) "Lua editing support for AUCTeX" single ((:commit . "799cd8ac10c96991bb63d9aa60528ae5d8c786b5") (:keywords "latex" "lua") (:authors ("Sean Allred" . "seallred@smcm.edu")) (:maintainer "Sean Allred" . "seallred@smcm.edu") (:url . "http://github.com/vermiculus/auctex-lua"))]) (auctex-latexmk . [(20170618 1636) ((auctex (11 87))) "Add LatexMk support to AUCTeX" single ((:commit . "4d353522650d7685acbf1d38f7dbc504f734bd84") (:keywords "tex") (:authors ("Tomoya Tanjo" . "ttanjo@gmail.com")) (:maintainer "Tomoya Tanjo" . "ttanjo@gmail.com") (:url . "https://github.com/tom-tan/auctex-latexmk/"))]) (attrap . [(20180901 907) ((dash (2 12 0)) (emacs (25 1)) (f (0 19 0)) (flycheck (0 30)) (s (1 11 0))) "ATtempt To Repair At Point" single ((:commit . "a971acb251e343d4c6b0253f69dcce0c2cee0fac") (:keywords "programming" "tools") (:authors ("Jean-Philippe Bernardy" . "jeanphilippe.bernardy@gmail.com")) (:maintainer "Jean-Philippe Bernardy" . "jeanphilippe.bernardy@gmail.com") (:url . "https://github.com/jyp/attrap"))]) (atomic-chrome . [(20180617 724) ((emacs (24 3)) (let-alist (1 0 4)) (websocket (1 4))) "Edit Chrome text area with Emacs using Atomic Chrome" single ((:commit . "a505f638866f9e7b913784be0dc84f338e9ad449") (:keywords "chrome" "edit" "textarea") (:authors ("alpha22jp" . "alpha22jp@gmail.com")) (:maintainer "alpha22jp" . "alpha22jp@gmail.com") (:url . "https://github.com/alpha22jp/atomic-chrome"))]) (atom-one-dark-theme . [(20180607 2338) nil "Atom One Dark color theme" single ((:commit . "1f1185bf667a38d3d0d180ce85fd4c131818aae2") (:authors ("Jonathan Chu" . "me@jonathanchu.is")) (:maintainer "Jonathan Chu" . "me@jonathanchu.is") (:url . "https://github.com/jonathanchu/atom-one-dark-theme"))]) (atom-dark-theme . [(20170710 2312) nil "An Emacs port of the Atom Dark theme from Atom.io." single ((:commit . "7fb37fd953e417acbcf7dd3f36e3167bed9bc887") (:keywords "themes" "atom" "dark") (:authors (nil . "Jeremy Whitlock <jwhitlock@apache.org")) (:maintainer nil . "Jeremy Whitlock <jwhitlock@apache.org") (:url . "https://github.com/whitlockjc/atom-dark-theme-emacs"))]) (async-await . [(20170208 1150) ((emacs (25)) (promise (1 0))) "Async/Await" single ((:commit . "56ab90e4019ed1f81fd4ad9e8701b5cec7ffa795") (:keywords "async" "await" "convenience") (:authors ("chuntaro" . "chuntaro@sakura-games.jp")) (:maintainer "chuntaro" . "chuntaro@sakura-games.jp") (:url . "https://github.com/chuntaro/emacs-async-await"))]) (async . [(20180527 1730) nil "Asynchronous processing in Emacs" tar ((:commit . "d17c11e6082aa51f421bb037b828bdb15f405618") (:keywords "async") (:url . "https://github.com/jwiegley/emacs-async"))]) (assess . [(20170504 1357) ((emacs (24 1)) (m-buffer (0 15))) "Test support functions" tar ((:commit . "e5b0415126c6bd24bd220759ff04220d963a0195") (:authors ("Phillip Lord" . "phillip.lord@russet.org.uk")) (:maintainer "Phillip Lord" . "phillip.lord@russet.org.uk"))]) (asn1-mode . [(20170729 226) ((emacs (24 3)) (s (1 10 0))) "ASN.1/GDMO mode for GNU Emacs" single ((:commit . "d5d4a8259daf708411699bcea85d322f18beb972") (:keywords "languages" "processes" "tools") (:authors ("Taichi Kawabata <kawabata.taichi_at_gmail.com>")) (:maintainer "Taichi Kawabata <kawabata.taichi_at_gmail.com>") (:url . "https://github.com/kawabata/asn1-mode/"))]) (asilea . [(20150105 1525) ((emacs (24)) (cl-lib (0 5))) "Find best compiler options using simulated annealing" single ((:commit . "2aab1cc63b64ef08d12e84fd7ba5c94065f6039f") (:authors ("Fanael Linithien" . "fanael4@gmail.com")) (:maintainer "Fanael Linithien" . "fanael4@gmail.com") (:url . "https://github.com/Fanael/asilea"))]) (arview . [(20160419 2109) nil "extract and view archives in the temporary directory" single ((:commit . "5437b4221b64b238c273a651d4792c577dba6d45") (:keywords "files") (:authors ("Andrey Fainer" . "fandrey@gmx.com")) (:maintainer "Andrey Fainer" . "fandrey@gmx.com") (:url . "https://github.com/afainer/arview"))]) (artbollocks-mode . [(20170524 422) nil "Improve your writing (especially about art)" single ((:commit . "33a41ca4f8206f57e5498a526d3b0ea18d08bb93") (:authors ("Rob Myers <rob@robmyers.org>, Sacha Chua" . "sacha@sachachua.com")) (:maintainer "Rob Myers <rob@robmyers.org>, Sacha Chua" . "sacha@sachachua.com") (:url . "https://github.com/sachac/artbollocks-mode"))]) (arjen-grey-theme . [(20170522 2047) nil "A soothing dark grey theme" single ((:commit . "4cd0be72b65d42390e2105cfdaa408a1ead8d8d1") (:keywords "faces") (:authors ("Arjen Wiersma" . "arjen@wiersma.org")) (:maintainer "Arjen Wiersma" . "arjen@wiersma.org") (:url . "https://github.com/credmp/arjen-grey"))]) (ariadne . [(20131117 1711) ((bert (0 1))) "Ariadne plugin for Emacs" single ((:commit . "6fe401c7f996bcbc2f685e7971324c6f5e5eaf15") (:keywords "comm" "convenience" "processes") (:authors ("Oleksandr Manzyuk" . "manzyuk@gmail.com")) (:maintainer "Oleksandr Manzyuk" . "manzyuk@gmail.com"))]) (aria2 . [(20141107 2317) ((emacs (24 4))) "Control aria2c commandline tool from Emacs" single ((:commit . "7a944c5100812269369225af7aa9580fedab175f") (:keywords "download" "bittorrent" "aria2") (:authors ("Łukasz Gruner" . "lukasz@gruner.lu")) (:maintainer "Łukasz Gruner" . "lukasz@gruner.lu") (:url . "https://bitbucket.org/ukaszg/aria2-mode"))]) (arduino-mode . [(20180509 36) ((emacs (25)) (cl-lib (0 5)) (spinner (1 7 3))) "Major mode for editing Arduino code." tar ((:commit . "e39cb1c02acb6676aea35f93fbd0d86badce6a38") (:keywords "languages" "arduino") (:maintainer "stardiviner" . "numbchild@gmail.com") (:url . "https://github.com/stardiviner/arduino-mode"))]) (archive-rpm . [(20180706 1232) ((emacs (24 4))) "RPM and CPIO support for archive-mode" tar ((:commit . "59f83caebbd2f92fd634f6968e6d17b50ffa3dc7"))]) (archive-region . [(20140201 2342) nil "Move region to archive file instead of killing" single ((:commit . "0d357d4c42a6a248c457f358f81b20fd20fede2f") (:keywords "languages") (:authors ("rubikitch" . "rubikitch@ruby-lang.org")) (:maintainer "rubikitch" . "rubikitch@ruby-lang.org") (:url . "http://www.emacswiki.org/cgi-bin/wiki/download/archive-region.el"))]) (arch-packer . [(20170730 1321) ((emacs (25 1)) (s (1 11 0)) (async (1 9 2)) (dash (2 12 0))) "Arch Linux package management frontend" single ((:commit . "940e96f7d357c6570b675a0f942181c787f1bfd7") (:authors ("Fritz Stelzer" . "brotzeitmacher@gmail.com")) (:maintainer "Fritz Stelzer" . "brotzeitmacher@gmail.com") (:url . "https://github.com/brotzeitmacher/arch-packer"))]) (apt-sources-list . [(20180527 1241) ((emacs (24 4))) "Mode for editing APT source.list files" single ((:commit . "44112833b3fa7f4d7e43708e5996782e22bb2fa3") (:authors ("Dr. Rafael Sepúlveda" . "drs@gnulinux.org.mx")) (:maintainer "Joe Wreschnig" . "joe.wreschnig@gmail.com") (:url . "https://git.korewanetadesu.com/apt-sources-list.git"))]) (apropospriate-theme . [(20180718 1801) nil "A colorful, low-contrast, light & dark theme set for Emacs with a fun name." tar ((:commit . "97a26598a4d64f8339f7b12818d67425057235be") (:keywords "color" "theme") (:url . "https://github.com/waymondo/apropospriate-theme"))]) (aproject . [(20150605 906) nil "Basic project framework for Emacs" tar ((:commit . "3c7d23c341862dfd77fd0a64775df12ddb44ab54") (:keywords "environment" "project") (:authors ("Vietor Liu" . "vietor.liu@gmail.com")) (:maintainer "Vietor Liu" . "vietor.liu@gmail.com") (:url . "https://github.com/vietor/aproject"))]) (applescript-mode . [(20090321 632) nil "major mode for editing AppleScript source" single ((:commit . "8f888cd80af1e0902b5609143facd3051bc94892") (:keywords "languages" "tools") (:authors ("sakito" . "sakito@users.sourceforge.jp")) (:maintainer "sakito" . "sakito@users.sourceforge.jp"))]) (apples-mode . [(20110121 418) nil "Major mode for editing and executing AppleScript code" tar ((:commit . "83a9ab0d6ba82496e2f7df386909b1a55701fccb") (:keywords "applescript" "languages") (:authors ("tequilasunset" . "tequilasunset.mac@gmail.com")) (:maintainer "tequilasunset" . "tequilasunset.mac@gmail.com"))]) (apiwrap . [(20180602 2231) ((emacs (25))) "api-wrapping macros" single ((:commit . "e4c9c57d6620a788ec8a715ff1bb50542edea3a6") (:keywords "tools" "maint" "convenience") (:authors ("Sean Allred" . "code@seanallred.com")) (:maintainer "Sean Allred" . "code@seanallred.com") (:url . "https://github.com/vermiculus/apiwrap.el"))]) (apib-mode . [(20170520 1358) ((markdown-mode (2 1))) "Major mode for API Blueprint files" single ((:commit . "6cc7c6f21b8e415b1718bb6a07ab2182e9e9dde6") (:keywords "tools" "api-blueprint") (:authors ("Vilibald Wanča" . "vilibald@wvi.cz")) (:maintainer "Vilibald Wanča" . "vilibald@wvi.cz") (:url . "http://github.com/w-vi/apib-mode"))]) (apel . [(20170122 2258) nil "APEL (A Portable Emacs Library) provides support for portable Emacs Lisp programs" tar ((:commit . "339eb28ffae3165255a79de9b1fd362f43cd37c3"))]) (apache-mode . [(20180724 351) nil "major mode for editing Apache configuration files" single ((:commit . "d2ac57942f852a727db4fc73004e1e8f046cb657") (:keywords "languages" "faces") (:authors ("Karl Chen" . "quarl@nospam.quarl.org")) (:maintainer "USAMI Kenta" . "tadsan@zonu.me") (:url . "https://github.com/emacs-php/apache-mode"))]) (aozora-view . [(20140310 1317) nil "Aozora Bunko text Emacs viewer." tar ((:commit . "b0390616d19e45f15f9a2f5d5688274831e721fd") (:keywords "text") (:authors ("KAWABATA, Taichi <kawabata.taichi_at_gmail.com>")) (:maintainer "KAWABATA, Taichi <kawabata.taichi_at_gmail.com>") (:url . "https://github.com/kawabata/aozora-view"))]) (anzu . [(20161017 1607) ((emacs (24 3))) "Show number of matches in mode-line while searching" single ((:commit . "e6c56ca8b23ac433f7be58b6f3f50801dd4164e4") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-anzu"))]) (anyins . [(20131229 1041) nil "Insert content at multiple places from shell command or kill-ring" single ((:commit . "83844c17ac9b5b6c7655ee556b75689e4c8ea663") (:keywords "insert" "rectangular") (:authors ("Anthony HAMON" . "hamon.anth@gmail.com")) (:maintainer "Anthony HAMON" . "hamon.anth@gmail.com") (:url . "http://github.com/antham/anyins"))]) (anybar . [(20160816 1421) nil "Control AnyBar from Emacs" single ((:commit . "7a0743e0d31bcb36ab1bb2e351f3e7139c422ac5") (:keywords "anybar") (:authors ("Christopher Shea" . "cmshea@gmail.com")) (:maintainer "Christopher Shea" . "cmshea@gmail.com"))]) (anx-api . [(20140208 1514) nil "Interact with the AppNexus API from Emacs." single ((:commit . "b2411ebc966ac32c3ffc61bc22bf183834df0fa0") (:keywords "convenience" "json" "rest" "api" "appnexus") (:authors ("Rich Loveland")) (:maintainer "Rich Loveland"))]) (anti-zenburn-theme . [(20180712 1838) nil "Low-contrast Zenburn-inverted theme" single ((:commit . "dbafbaa86be67c1d409873f57a5c0bbe1e7ca158") (:authors ("Andrey Kotlarski" . "m00naticus@gmail.com")) (:maintainer "Andrey Kotlarski" . "m00naticus@gmail.com") (:url . "https://github.com/m00natic/anti-zenburn-theme"))]) (ant . [(20160211 1543) nil "helpers for compiling with ant" single ((:commit . "510b5a3f57ee4b2855422d88d359a28922c1ab70") (:keywords "compilation" "ant" "java"))]) (ansible-vault . [(20170111 2118) ((emacs (24 3))) "Minor mode for editing ansible vault files" single ((:commit . "71d1df3b1c2d1569b6c3091a9d54baf2ebc7019d") (:keywords "ansible" "ansible-vault" "tools") (:maintainer "Zachary Elliott" . "contact@zell.io") (:url . "http://github.com/zellio/ansible-vault-mode"))]) (ansible-doc . [(20160924 824) ((emacs (24 3))) "Ansible documentation Minor Mode" single ((:commit . "86083a7bb2ed0468ca64e52076b06441a2f8e9e0") (:keywords "tools" "help") (:authors ("Sebastian Wiesner" . "swiesner@lunaryorn")) (:maintainer "Sebastian Wiesner" . "swiesner@lunaryorn") (:url . "https://github.com/lunaryorn/ansible-doc.el"))]) (ansible . [(20180813 114) ((s (1 9 0)) (f (0 16 2))) "Ansible minor mode" tar ((:commit . "8a097176d6772b6667254dbbe19c5fb64527bf5d") (:authors ("k1LoW (Kenichirou Oyama), <k1lowxb [at] gmail [dot] com> <k1low [at] 101000lab [dot] org>")) (:maintainer "k1LoW (Kenichirou Oyama), <k1lowxb [at] gmail [dot] com> <k1low [at] 101000lab [dot] org>") (:url . "http://101000lab.org"))]) (ansi . [(20150703 826) ((s (1 6 1)) (dash (1 5 0))) "Turn string into ansi strings" single ((:commit . "12b4c5d91b3da1902838f421e5af6d40e2cd57dd") (:keywords "color" "ansi") (:authors ("Johan Andersson" . "johan.rejeep@gmail.com")) (:maintainer "Johan Andersson" . "johan.rejeep@gmail.com") (:url . "http://github.com/rejeep/ansi"))]) (annoying-arrows-mode . [(20161024 646) ((cl-lib (0 5))) "Ring the bell if using arrows too much" single ((:commit . "3c42e9807d7696da2da2a21b63beebf9cdb3f5dc") (:authors ("Magnar Sveen" . "magnars@gmail.com")) (:maintainer "Magnar Sveen" . "magnars@gmail.com"))]) (annotate-depth . [(20160520 2040) nil "Annotate buffer if indentation depth is beyond threshold." single ((:commit . "fcb24fa36287250e40d195590c4ca4a8a696277b") (:keywords "convenience") (:authors ("Morten Slot Kristensen <msk AT nullpointer DOT dk>")) (:maintainer "Morten Slot Kristensen <msk AT nullpointer DOT dk>") (:url . "https://github.com/netromdk/annotate-depth"))]) (annotate . [(20171111 736) nil "annotate files without changing them" single ((:commit . "dedbd9e5d5286f1ca8ad73e489d408a20f06156c") (:authors ("Bastian Bechtold")) (:maintainer "Bastian Bechtold") (:url . "https://github.com/bastibe/annotate.el"))]) (anki-editor . [(20180812 152) ((emacs (25)) (request (0 3 0)) (dash (2 12 0))) "Minor mode for making Anki cards with Org" tar ((:commit . "b533c9899ca6213eface863c7bfcfa5b5ad71f1b") (:authors ("Lei Tan")) (:maintainer "Lei Tan") (:url . "https://github.com/louietan/anki-editor"))]) (angular-snippets . [(20140514 523) ((s (1 4 0)) (dash (1 2 0))) "Yasnippets for AngularJS" tar ((:commit . "af5ae0a4a8603b040446c28afcf6ca01a8b4bd7b"))]) (angular-mode . [(20151201 2127) nil "Major mode for Angular.js" tar ((:commit . "8720cde86af0f1859ccc8580571e8d0ad1c52cff") (:keywords "languages" "javascript") (:authors ("Rudolf Olah" . "omouse@gmail.com")) (:maintainer "Rudolf Olah" . "omouse@gmail.com") (:url . "https://github.com/omouse/angularjs-mode"))]) (angry-police-captain . [(20120829 1252) nil "Show quote from http://theangrypolicecaptain.com in the minibuffer" single ((:commit . "d11931c5cb63368dcc4a48797962428cca6d3e9d") (:keywords "games" "web" "fun") (:authors ("Rolando Pereira" . "rolando_pereira@sapo.pt")) (:maintainer "Rolando Pereira" . "rolando_pereira@sapo.pt"))]) (android-mode . [(20170323 815) nil "Minor mode for Android application development" single ((:commit . "f274da87429617b0b9c5889d46b36de64d982da4") (:keywords "tools" "processes") (:authors ("R.W. van 't Veer")) (:maintainer "R.W. van 't Veer") (:url . "https://github.com/remvee/android-mode"))]) (anaphora . [(20180618 2200) nil "anaphoric macros providing implicit temp variables" single ((:commit . "3b2da3f759b244975852e79721c4a2dbad3905cf") (:keywords "extensions") (:authors ("Roland Walker" . "walker@pobox.com")) (:maintainer "Roland Walker" . "walker@pobox.com") (:url . "http://github.com/rolandwalker/anaphora"))]) (anaconda-mode . [(20180808 625) ((emacs (25)) (pythonic (0 1 0)) (dash (2 6 0)) (s (1 9)) (f (0 16 2))) "Code navigation, documentation lookup and completion for Python" single ((:commit . "706ad11477b48a2b891235869d32e4aa5536774f") (:authors ("Artem Malyshev" . "proofit404@gmail.com")) (:maintainer "Artem Malyshev" . "proofit404@gmail.com") (:url . "https://github.com/proofit404/anaconda-mode"))]) (amx . [(20180627 2255) ((emacs (24 4)) (s (0))) "Alternative M-x with extra features." single ((:commit . "260e7c013690d412ec8d965c282572505596636d") (:keywords "convenience" "usability") (:authors ("Ryan C. Thompson" . "rct@thompsonclan.org") ("Cornelius Mika" . "cornelius.mika@gmail.com")) (:maintainer "Ryan C. Thompson" . "rct@thompsonclan.org") (:url . "http://github.com/DarwinAwardWinner/amx/"))]) (ample-zen-theme . [(20150119 2154) nil "AmpleZen Theme for Emacs 24" single ((:commit . "b277bb7abd4b6624e8d59f02474b79af50a007bd") (:keywords "theme" "dark" "emacs 24") (:authors ("Michael Wall")) (:maintainer "Michael Wall") (:url . "https://github.com/mjwall/ample-zen"))]) (ample-theme . [(20180207 1745) nil "Calm Dark Theme for Emacs" tar ((:commit . "366698400c555211c2082962a5d74f3dd79a78c8") (:keywords "theme" "dark") (:authors ("Jordon Biondo" . "jordonbiondo@gmail.com")) (:maintainer "Jordon Biondo" . "jordonbiondo@gmail.com") (:url . "https://github.com/jordonbiondo/ample-theme"))]) (ample-regexps . [(20151023 1000) nil "ample regular expressions for Emacs" tar ((:commit . "cbe91e148cac1ee8e223874dc956ed4cf607f046") (:keywords "regexps" "extensions" "tools") (:authors ("immerrr" . "immerrr@gmail.com")) (:maintainer "immerrr" . "immerrr@gmail.com"))]) (amd-mode . [(20180111 1402) ((emacs (25)) (projectile (20161008 47)) (s (1 9 0)) (f (0 16 2)) (seq (2 16)) (makey (0 3)) (js2-mode (20140114)) (js2-refactor (0 6 1))) "Minor mode for handling JavaScript AMD module requirements." single ((:commit . "01fd19e0d635ccaf8e812364d8720733f2e84126") (:keywords "javascript" "amd" "projectile") (:authors ("Nicolas Petton" . "petton.nicolas@gmail.com")) (:maintainer "Nicolas Petton" . "petton.nicolas@gmail.com"))]) (all-the-icons-ivy . [(20180826 2016) ((emacs (24 4)) (all-the-icons (2 4 0)) (ivy (0 8 0))) "Shows icons while using ivy and counsel" single ((:commit . "7baba16410e78ca3c7a564c3731baa75b2e8d93a") (:keywords "faces") (:authors ("asok")) (:maintainer "asok"))]) (all-the-icons-gnus . [(20180511 654) ((emacs (24 4)) (dash (2 12 0)) (all-the-icons (3 1 0))) "Shows icons for in Gnus" single ((:commit . "27f78996da0725943bcfb2d18038e6f7bddfa9c7") (:keywords "mail" "tools") (:authors ("Nicolas Lamirault" . "nicolas.lamirault@gmail.com")) (:maintainer "Nicolas Lamirault" . "nicolas.lamirault@gmail.com"))]) (all-the-icons-dired . [(20170418 2131) ((emacs (24 4)) (all-the-icons (2 2 0))) "Shows icons for each file in dired mode" single ((:commit . "980b7747d6c4a7992a1ec56afad908956db0a519") (:keywords "files" "icons" "dired") (:authors ("jtbm37")) (:maintainer "jtbm37"))]) (all-the-icons . [(20180125 1557) ((emacs (24 3)) (memoize (1 0 1))) "A library for inserting Developer icons" tar ((:commit . "52d1f2d36468146c93aaf11399f581401a233306") (:keywords "convenient" "lisp") (:authors ("Dominic Charlesworth" . "dgc336@gmail.com")) (:maintainer "Dominic Charlesworth" . "dgc336@gmail.com") (:url . "https://github.com/domtronn/all-the-icons.el"))]) (all-ext . [(20170115 205) ((all (1 0))) "M-x all with helm-swoop/anything/multiple-cursors/line-number" single ((:commit . "9f4ef84a147cf4e0af6ef45826d6cb3558db6b88") (:keywords "all" "search" "replace" "anything" "helm" "helm-swoop" "occur") (:authors ("rubikitch" . "rubikitch@ruby-lang.org")) (:maintainer "rubikitch" . "rubikitch@ruby-lang.org") (:url . "https://github.com/rubikitch/all-ext"))]) (align-cljlet . [(20160112 2101) ((clojure-mode (1 11 5))) "Space align various Clojure forms" single ((:commit . "602d72a7ad52788a0265e3c6da519464a98166b8") (:url . "https://github.com/gstamp/align-cljlet"))]) (alert . [(20180827 422) ((gntp (0 1)) (log4e (0 3 0))) "Growl-style notification system for Emacs" single ((:commit . "fe494d1e80e308f7db7273bf02281757fdf86e6f") (:keywords "notification" "emacs" "message") (:authors ("John Wiegley" . "jwiegley@gmail.com")) (:maintainer "John Wiegley" . "jwiegley@gmail.com") (:url . "https://github.com/jwiegley/alert"))]) (alect-themes . [(20180504 1720) ((emacs (24 0))) "Configurable light, dark and black themes for Emacs 24 or later" tar ((:commit . "4d90833a7381123a979f73fa97a013071ca7ff00") (:keywords "color" "theme") (:authors ("Alex Kost" . "alezost@gmail.com")) (:maintainer "Alex Kost" . "alezost@gmail.com") (:url . "https://github.com/alezost/alect-themes"))]) (alda-mode . [(20180608 605) ((emacs (24 0))) "An Alda major mode" single ((:commit . "c49dad79591de6662bf5f4eb79acac1d5dd2610e") (:keywords "alda" "highlight") (:authors ("Jay Kamat" . "jaygkamat@gmail.com")) (:maintainer "Jay Kamat" . "jaygkamat@gmail.com") (:url . "http://gitlab.com/jgkamat/alda-mode"))]) (alchemist . [(20180312 1304) ((elixir-mode (2 2 5)) (dash (2 11 0)) (emacs (24 4)) (company (0 8 0)) (pkg-info (0 4)) (s (1 11 0))) "Elixir tooling integration into Emacs" tar ((:commit . "6f99367511ae209f8fe2c990779764bbb4ccb6ed") (:keywords "languages" "elixir" "elixirc" "mix" "hex" "alchemist") (:authors ("Samuel Tonini" . "tonini.samuel@gmail.com")) (:maintainer "Samuel Tonini" . "tonini.samuel@gmail.com") (:url . "http://www.github.com/tonini/alchemist.el"))]) (alan-mode . [(20180902 1431) ((flycheck (32)) (emacs (25 1)) (s (1 12))) "Major mode for editing M-industries Alan files" single ((:commit . "998bf0a8a494783c65fd9fa2c1fd6f081002dc59") (:keywords "alan" "languages") (:authors ("Paul van Dam" . "pvandam@m-industries.com")) (:maintainer "Paul van Dam" . "pvandam@m-industries.com") (:url . "https://github.com/M-industries/AlanForEmacs"))]) (airplay . [(20130212 1226) ((request (20130110 2144)) (simple-httpd (1 4 1)) (deferred (0 3 1))) "Airplay bindings to Emacs" tar ((:commit . "bd690aafcae3a887946e1bba8327597932d964ad") (:keywords "appletv" "airplay") (:authors ("Wataru MIYAGUNI" . "gonngo@gmail.com")) (:maintainer "Wataru MIYAGUNI" . "gonngo@gmail.com") (:url . "https://github.com/gongo/airplay-el"))]) (airline-themes . [(20180411 406) ((powerline (2 3))) "vim-airline themes for emacs powerline" tar ((:commit . "8b528fbae0e557461315bed82883275d58df41f2") (:keywords "evil" "mode-line" "powerline" "airline" "themes") (:authors ("Anthony DiGirolamo" . "anthony.digirolamo@gmail.com")) (:maintainer "Anthony DiGirolamo" . "anthony.digirolamo@gmail.com") (:url . "http://github.com/AnthonyDiGirolamo/airline-themes"))]) (ahungry-theme . [(20180131 328) ((emacs (24))) "Ahungry color theme for Emacs.  Make sure to (load-theme 'ahungry)." single ((:commit . "a038d91ec593d1f1b19ca66a0576d59bbc24c523") (:keywords "ahungry" "palette" "color" "theme" "emacs" "color-theme" "deftheme") (:authors ("Matthew Carter" . "m@ahungry.com")) (:maintainer "Matthew Carter" . "m@ahungry.com") (:url . "https://github.com/ahungry/color-theme-ahungry"))]) (ahk-mode . [(20160320 2221) ((emacs (24 3))) "Major mode for editing AHK (AutoHotkey and AutoHotkey_L)" single ((:commit . "9cfc4840507f6cc8016fdede84ad90df53285359") (:keywords "ahk" "autohotkey" "hotkey" "keyboard shortcut" "automation") (:authors ("Rich Alesi")) (:maintainer "Rich Alesi") (:url . "https://github.com/ralesi/ahk-mode"))]) (ahg . [(20180809 653) nil "Alberto's Emacs interface for Mercurial (Hg)" single ((:authors ("Alberto Griggio" . "agriggio@users.sourceforge.net")) (:maintainer "Alberto Griggio" . "agriggio@users.sourceforge.net") (:url . "https://bitbucket.org/agriggio/ahg"))]) (aggressive-indent . [(20180627 21) ((emacs (24 1)) (cl-lib (0 5))) "Minor mode to aggressively keep your code always indented" single ((:commit . "8e70039c7190639c43794cb75eae118c2faaa0d1") (:keywords "indent" "lisp" "maint" "tools") (:authors ("Artur Malabarba" . "emacs@endlessparentheses.com")) (:maintainer "Artur Malabarba" . "emacs@endlessparentheses.com") (:url . "https://github.com/Malabarba/aggressive-indent-mode"))]) (aggressive-fill-paragraph . [(20170902 1405) ((dash (2 10 0))) "A mode to automatically keep paragraphs filled" single ((:commit . "bcbc63d1c93cd8dc5bf2fc6eb4988fa76375c631") (:keywords "fill-paragraph" "automatic" "comments") (:authors ("David Shepherd" . "davidshepherd7@gmail.com")) (:maintainer "David Shepherd" . "davidshepherd7@gmail.com") (:url . "https://github.com/davidshepherd7/aggressive-fill-paragraph-mode"))]) (ag . [(20180225 1040) ((dash (2 8 0)) (s (1 9 0)) (cl-lib (0 5))) "A front-end for ag ('the silver searcher'), the C ack replacement." single ((:commit . "77b4f50c5372bf219da496567b2b867261f0d354") (:authors ("Wilfred Hughes" . "me@wilfred.me.uk")) (:maintainer "Wilfred Hughes" . "me@wilfred.me.uk"))]) (afternoon-theme . [(20140104 1859) ((emacs (24 1))) "Dark color theme with a deep blue background" single ((:commit . "89b1d778a1f8b385775c122f2bd1c62f0fbf931a") (:keywords "themes") (:authors ("Ozan Sener" . "ozan@ozansener.com")) (:maintainer "Ozan Sener" . "ozan@ozansener.com") (:url . "http://github.com/osener/emacs-afternoon-theme"))]) (aes . [(20171029 623) nil "Implementation of AES" single ((:commit . "b7d5da89c3443292e4f0b1c9d254d459933cf5af") (:keywords "data" "tools") (:authors ("Markus Sauermann" . "emacs-aes@sauermann-consulting.de")) (:maintainer "Markus Sauermann" . "emacs-aes@sauermann-consulting.de") (:url . "https://github.com/Sauermann/emacs-aes"))]) (adoc-mode . [(20160314 2130) ((markup-faces (1 0 0))) "a major-mode for editing AsciiDoc files in Emacs" single ((:commit . "745884359a1b8826ede2c4cfd2f0b5478953ac40") (:keywords "wp" "asciidoc") (:authors ("Florian Kaufmann" . "sensorflo@gmail.com")) (:maintainer "Florian Kaufmann" . "sensorflo@gmail.com") (:url . "https://github.com/sensorflo/adoc-mode/wiki"))]) (addressbook-bookmark . [(20171108 634) ((emacs (24))) "An address book based on Standard Emacs bookmarks." single ((:commit . "981355dcfb7477c00d41560a5a66fce73f02c0f5") (:authors ("Thierry Volpiatto" . "thierry.volpiatto@gmail.com")) (:maintainer "Thierry Volpiatto" . "thierry.volpiatto@gmail.com") (:url . "https://github.com/thierryvolpiatto/addressbook-bookmark"))]) (add-node-modules-path . [(20180710 2342) nil "Add node_modules to your exec-path" single ((:commit . "f31e69ccb681f882aebb806ce6e9478e3ac39708") (:keywords "javascript" "node" "node_modules" "eslint") (:authors ("Neri Marschik" . "marschik_neri@cyberagent.co.jp")) (:maintainer "Neri Marschik" . "marschik_neri@cyberagent.co.jp") (:url . "https://github.com/codesuki/add-node-modules-path"))]) (add-hooks . [(20171217 123) nil "Functions for setting multiple hooks" single ((:commit . "1845137703461fc44bd77cf24014ba58f19c369d") (:keywords "lisp") (:authors ("Nick McCurdy" . "nick@nickmccurdy.com")) (:maintainer "Nick McCurdy" . "nick@nickmccurdy.com") (:url . "https://github.com/nickmccurdy/add-hooks"))]) (adafruit-wisdom . [(20180225 52) ((emacs (25))) "Get/display adafruit.com quotes" single ((:commit . "aafc01726f1b3160321d40160298a0e1b054b382") (:keywords "games") (:authors ("Neil Okamoto" . "neil.okamoto+melpa@gmail.com")) (:maintainer "Neil Okamoto" . "neil.okamoto+melpa@gmail.com") (:url . "https://github.com/gonewest818/adafruit-wisdom.el"))]) (actionscript-mode . [(20180527 1701) nil "A simple mode for editing Actionscript 3 files" single ((:commit . "65abd58e198458a8e46748c5962c41d80d60c4ea") (:keywords "language" "modes") (:authors ("Austin Haas")) (:maintainer "Austin Haas"))]) (ack-menu . [(20150504 2022) ((mag-menu (0 1 0))) "A menu-based front-end for ack" single ((:commit . "f77be93a4697926ecf3195a355eb69580f695f4d") (:keywords "tools" "matching" "convenience") (:authors ("Steven Thomas") ("Nikolaj Schumacher")) (:maintainer "Steven Thomas") (:url . "https://github.com/chumpage/ack-menu"))]) (achievements . [(20150530 1826) ((keyfreq (0 0 3))) "Achievements for emacs usage." tar nil]) (ace-window . [(20180814 1516) ((avy (0 2 0))) "Quickly switch windows." single ((:commit . "d93e16b52ee7c1b6c9df599060e7077b4e46cbf8") (:keywords "window" "location") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:url . "https://github.com/abo-abo/ace-window"))]) (ace-popup-menu . [(20180101 615) ((emacs (24 3)) (avy-menu (0 1))) "Replace GUI popup menu with something more efficient" single ((:commit . "7b436a0d9e896463d00afbeb7e49a59cc6670e9c") (:keywords "convenience" "popup" "menu") (:authors ("Mark Karpov" . "markkarpov92@gmail.com")) (:maintainer "Mark Karpov" . "markkarpov92@gmail.com") (:url . "https://github.com/mrkkrp/ace-popup-menu"))]) (ace-pinyin . [(20170501 626) ((avy (0 2 0)) (pinyinlib (0 1 0))) "Jump to Chinese characters using avy or ace-jump-mode" single ((:commit . "a9df88c1e6a32a4f4895acbb8c45383693c494c1") (:keywords "extensions") (:authors ("Junpeng Qiu" . "qjpchmail@gmail.com")) (:maintainer "Junpeng Qiu" . "qjpchmail@gmail.com") (:url . "https://github.com/cute-jumper/ace-pinyin"))]) (ace-mc . [(20160409 37) ((ace-jump-mode (1 0)) (multiple-cursors (1 0)) (dash (2 10 0))) "Add multiple cursors quickly using ace jump" single ((:commit . "b106bf6a6c78c3e026fbe9a99a34d6239adce4fd") (:keywords "motion" "location" "cursor") (:authors ("Josh Moller-Mara" . "jmm@cns.nyu.edu")) (:maintainer "Josh Moller-Mara" . "jmm@cns.nyu.edu") (:url . "https://github.com/mm--/ace-mc"))]) (ace-link . [(20180308 900) ((avy (0 4 0))) "Quickly follow links" single ((:commit . "fae5d508ff519ba1fab21c51f46c0906fd82229f") (:keywords "convenience" "links" "avy") (:authors ("Oleh Krehel" . "ohwoeowho@gmail.com")) (:maintainer "Oleh Krehel" . "ohwoeowho@gmail.com") (:url . "https://github.com/abo-abo/ace-link"))]) (ace-jump-zap . [(20170717 1849) ((ace-jump-mode (1 0)) (dash (2 10 0))) "Character zapping, `ace-jump-mode` style" single ((:commit . "52b5d4c6c73bd0fc833a0dcb4e803a5287d8cae8") (:keywords "convenience" "tools" "extensions") (:authors ("justin talbott" . "justin@waymondo.com")) (:maintainer "justin talbott" . "justin@waymondo.com") (:url . "https://github.com/waymondo/ace-jump-zap"))]) (ace-jump-mode . [(20140616 815) nil "a quick cursor location minor mode for emacs" single ((:commit . "8351e2df4fbbeb2a4003f2fb39f46d33803f3dac") (:keywords "motion" "location" "cursor") (:authors ("winterTTr" . "winterTTr@gmail.com")) (:maintainer "winterTTr" . "winterTTr@gmail.com") (:url . "https://github.com/winterTTr/ace-jump-mode/"))]) (ace-jump-helm-line . [(20160918 1836) ((avy (0 4 0)) (helm (1 6 3))) "Ace-jump to a candidate in helm window" single ((:commit . "1483055255df3f8ae349f7520f05b1e43ea3ed37") (:keywords "extensions") (:authors ("Junpeng Qiu" . "qjpchmail@gmail.com")) (:maintainer "Junpeng Qiu" . "qjpchmail@gmail.com") (:url . "https://github.com/cute-jumper/ace-jump-helm-line"))]) (ace-jump-buffer . [(20171031 1550) ((avy (0 4 0)) (dash (2 4 0))) "fast buffer switching extension to `avy'" single ((:commit . "ae5be0415c823f7bb66833aa4af2180d4cf99cef") (:authors ("Justin Talbott" . "justin@waymondo.com")) (:maintainer "Justin Talbott" . "justin@waymondo.com") (:url . "https://github.com/waymondo/ace-jump-buffer"))]) (ace-isearch . [(20170506 712) ((emacs (24))) "A seamless bridge between isearch, ace-jump-mode, avy, helm-swoop and swiper" single ((:commit . "0502f95e333c8059a678745e5a112542965661d1") (:authors ("Akira Tamamori")) (:maintainer "Akira Tamamori") (:url . "https://github.com/tam17aki/ace-isearch"))]) (ace-flyspell . [(20170309 509) ((avy (0 4 0))) "Jump to and correct spelling errors using `ace-jump-mode' and flyspell" single ((:commit . "538d4f8508d305262ba0228dfe7c819fb65b53c9") (:keywords "extensions") (:authors ("Junpeng Qiu" . "qjpchmail@gmail.com")) (:maintainer "Junpeng Qiu" . "qjpchmail@gmail.com") (:url . "https://github.com/cute-jumper/ace-flyspell"))]) (academic-phrases . [(20180723 1021) ((dash (2 12 0)) (s (1 12 0)) (ht (2 0)) (emacs (24))) "Bypass that mental block when writing your papers." single ((:commit . "25d9cf67feac6359cb213f061735e2679c84187f") (:keywords "academic" "convenience" "papers" "writing" "wp") (:authors ("Nasser Alshammari" . "designernasser@gmail.com")) (:maintainer "Nasser Alshammari" . "designernasser@gmail.com") (:url . "https://github.com/nashamri/academic-phrases"))]) (ac-sly . [(20170728 1027) ((sly (1 0 0 -3)) (auto-complete (1 4)) (cl-lib (0 5))) "An auto-complete source using sly completions" single ((:commit . "bf69c687c4ecf1994349d20c182e9b567399912e") (:authors ("Damian T. Dobroczy\\'nski" . "qoocku@gmail.com")) (:maintainer "Damian T. Dobroczy\\'nski" . "qoocku@gmail.com") (:url . "https://github.com/qoocku/ac-sly"))]) (ac-slime . [(20171027 2100) ((auto-complete (1 4)) (slime (2 9)) (cl-lib (0 5))) "An auto-complete source using slime completions" single ((:commit . "6c80cb602ddad46486288f94ad7546396c6e4b1a") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com") (:url . "https://github.com/purcell/ac-slime"))]) (ac-skk . [(20141230 119) ((auto-complete (1 3 1)) (ddskk (16 0 50)) (tinysegmenter (0)) (cl-lib (0 5))) "auto-complete-mode source for DDSKK a.k.a Japanese input method" single ((:commit . "d25a265930430d080329789fb253d786c01dfa24") (:keywords "convenience" "auto-complete") (:authors ("lugecy <https://twitter.com/lugecy>")) (:maintainer "myuhe") (:url . "https://github.com/myuhe/ac-skk.el"))]) (ac-rtags . [(20170523 454) ((auto-complete (1 4 0)) (rtags (2 10))) "auto-complete back-end for RTags" single ((:commit . "fc63be8f48bed6703b37ccb1057d75d7ce5200ca") (:authors ("Jan Erik Hanssen" . "jhanssen@gmail.com") ("Anders Bakken" . "agbakken@gmail.com")) (:maintainer "Jan Erik Hanssen" . "jhanssen@gmail.com") (:url . "http://rtags.net"))]) (ac-racer . [(20170114 809) ((emacs (24 3)) (auto-complete (1 5 0)) (racer (0 0 2))) "auto-complete source of racer" single ((:commit . "4408c2d652dec0432e20c05e001db8222d778c6b") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-ac-racer"))]) (ac-php-core . [(20180824 806) ((emacs (24)) (dash (1)) (php-mode (1)) (xcscope (1)) (s (1)) (f (0 17 0)) (popup (0 5 0))) "gen tags for php" tar ((:commit . "dcac8321b85b2ef6d43244e2b0932cb3ec7cfefb") (:keywords "completion" "convenience" "intellisense") (:authors (nil . "xcwenn@qq.com [https://github.com/xcwen]")) (:maintainer nil . "xcwenn@qq.com [https://github.com/xcwen]") (:url . "https://github.com/xcwen/ac-php"))]) (ac-php . [(20171201 934) ((ac-php-core (1)) (auto-complete (1 4 0)) (yasnippet (0 8 0))) "auto-completion source for php" single ((:commit . "dcac8321b85b2ef6d43244e2b0932cb3ec7cfefb") (:keywords "completion" "convenience" "intellisense") (:authors (nil . "xcwenn@qq.com [https://github.com/xcwen]")) (:maintainer nil . "xcwenn@qq.com [https://github.com/xcwen]") (:url . "https://github.com/xcwen/ac-php"))]) (ac-octave . [(20180406 334) ((auto-complete (1 4 0))) "An auto-complete source for Octave" single ((:commit . "fe0f931f2024f43de3c4fff4b1ace672413adeae") (:keywords "octave" "auto-complete" "completion") (:authors ("coldnew" . "coldnew.tw@gmail.com")) (:maintainer "coldnew" . "coldnew.tw@gmail.com") (:url . "https://github.com/coldnew/ac-octave"))]) (ac-mozc . [(20150227 1619) ((cl-lib (0 5)) (auto-complete (1 4)) (mozc (0))) "auto-complete sources for Japanese input using Mozc" single ((:commit . "4c6c8be4701010d9362184437c0f783e0335c631") (:authors ("igjit" . "igjit1@gmail.com")) (:maintainer "igjit" . "igjit1@gmail.com") (:url . "https://github.com/igjit/ac-mozc"))]) (ac-math . [(20141116 2127) ((auto-complete (1 4)) (math-symbol-lists (1 0))) "Auto-complete sources for input of mathematical symbols and latex tags" single ((:commit . "c012a8f620a48cb18db7d78995035d65eae28f11") (:keywords "latex" "auto-complete" "unicode" "symbols") (:authors ("Vitalie Spinu")) (:maintainer "Vitalie Spinu") (:url . "https://github.com/vitoshka/ac-math"))]) (ac-js2 . [(20140906 1142) ((js2-mode (20090723)) (skewer-mode (1 4))) "Auto-complete source for Js2-mode, with navigation" tar ((:commit . "721c482e1d4a08f4a29a74437257d573e8f69969") (:authors ("Scott Barnett" . "scott.n.barnett@gmail.com")) (:maintainer "Scott Barnett" . "scott.n.barnett@gmail.com") (:url . "https://github.com/ScottyB/ac-js2"))]) (ac-ispell . [(20151101 226) ((auto-complete (1 4)) (cl-lib (0 5))) "ispell completion source for auto-complete" single ((:commit . "22bace7387e9012002a6a444922f75f9913077b0") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-ac-ispell"))]) (ac-inf-ruby . [(20131115 1150) ((inf-ruby (2 3 2)) (auto-complete (1 4))) "Enable auto-complete in inf-ruby sessions" single ((:commit . "ee53fc9c61950da9a96df3ff5ef186f9a9faf151") (:keywords "languages" "tools") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com"))]) (ac-html-csswatcher . [(20151208 2113) ((web-completion-data (0 1))) "css/less class/id completion with `ac-html' or `company-web'" single ((:commit . "b0f3e7e1a3fe49e88b6eb6432377232fc715f221") (:keywords "html" "css" "less" "auto-complete") (:authors ("Olexandr Sydorchuck " . "olexandr.syd@gmail.com")) (:maintainer "Olexandr Sydorchuck " . "olexandr.syd@gmail.com") (:url . "https://github.com/osv/ac-html-csswatcher"))]) (ac-html-angular . [(20151225 719) ((web-completion-data (0 1))) "auto complete angular15 data for `ac-html' and `company-web'" tar ((:commit . "6bafe09afe03112ca4183d58461c1a6f6c2b3c67") (:keywords "html" "auto-complete" "angular") (:authors ("Olexandr Sydorchuk" . "olexandr.syd@gmail.com")) (:maintainer "Olexandr Sydorchuk" . "olexandr.syd@gmail.com") (:url . "https://github.com/osv/ac-html-bootstrap"))]) (ac-html . [(20151005 731) ((auto-complete (1 4)) (s (1 9)) (f (0 17)) (dash (2 10))) "auto complete source for html tags and attributes" tar ((:commit . "668154cba123c321d1b07c2dc8b26d14092253b8") (:keywords "html" "auto-complete" "slim" "haml" "jade") (:authors ("Zhang Kai Yu" . "yeannylam@gmail.com")) (:maintainer "Zhang Kai Yu" . "yeannylam@gmail.com") (:url . "https://github.com/cheunghy/ac-html"))]) (ac-helm . [(20160319 233) ((helm (1 6 3)) (auto-complete (1 4 0)) (popup (0 5 0)) (cl-lib (0 5))) "Helm interface for auto-complete" single ((:commit . "baf2b1e04bcffa835084389c0fab415f26efbf32") (:keywords "completion" "convenience" "helm") (:authors ("rubikitch" . "rubikitch@ruby-lang.org") ("Yasuyuki Oka" . "yasuyk@gmail.com")) (:maintainer "Yasuyuki Oka" . "yasuyk@gmail.com"))]) (ac-haskell-process . [(20150423 1402) ((auto-complete (1 4)) (haskell-mode (13))) "Haskell auto-complete source which uses the current haskell process" single ((:commit . "0362d4323511107ec70e7165cb612f3ab01b712f") (:keywords "languages") (:authors ("Steve Purcell" . "steve@sanityinc.com")) (:maintainer "Steve Purcell" . "steve@sanityinc.com"))]) (ac-geiser . [(20130929 647) ((geiser (0 5)) (auto-complete (1 4))) "Auto-complete backend for geiser" tar ((:commit . "502d18a8a0bd4b5fdd495a99299ba2a632c5cd9a"))]) (ac-etags . [(20161001 1507) ((auto-complete (1 4))) "etags/ctags completion source for auto-complete" single ((:commit . "7983e631c226fe0fa53af3b2d56bf4eca3d785ce") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-ac-etags"))]) (ac-emoji . [(20150823 711) ((auto-complete (1 5 0)) (cl-lib (0 5))) "auto-complete source of Emoji" tar ((:commit . "40a639764eb654f1b4bb705c817b66032a26ff2b") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-ac-emoji"))]) (ac-emmet . [(20131015 1558) ((emmet-mode (1 0 2)) (auto-complete (1 4))) "auto-complete sources for emmet-mode's snippets" single ((:commit . "88f24876ee3b759978d4614a758280b5d512d543") (:keywords "completion" "convenience" "emmet") (:authors ("Yasuyuki Oka" . "yasuyk@gmail.com")) (:maintainer "Yasuyuki Oka" . "yasuyk@gmail.com") (:url . "https://github.com/yasuyk/ac-emmet"))]) (ac-emacs-eclim . [(20170924 2039) ((eclim (0 3)) (auto-complete (1 5))) "auto-complete source for eclim" single ((:commit . "6396ad1cd25c0a197109343ec1cce5d5080acdff"))]) (ac-dcd . [(20170323 1301) ((auto-complete (1 3 1)) (flycheck-dmd-dub (0 7))) "Auto Completion source for dcd for GNU Emacs" single ((:commit . "1614aa624252e3445b0392c8a9b7197084f3e422") (:keywords "languages") (:authors (nil . "<atila.neves@gmail.com>")) (:maintainer nil . "<atila.neves@gmail.com>") (:url . "http://github.com/atilaneves/ac-dcd"))]) (ac-clang . [(20180710 546) ((emacs (24)) (cl-lib (0 5)) (auto-complete (1 4 0)) (pos-tip (0 4 6)) (yasnippet (0 8 0))) "Auto Completion source by libclang for GNU Emacs" tar ((:commit . "3294b968eb1a8317049190940193f9da47c085ef") (:keywords "completion" "convenience" "intellisense") (:authors ("yaruopooner [https://github.com/yaruopooner]")) (:maintainer "yaruopooner [https://github.com/yaruopooner]") (:url . "https://github.com/yaruopooner/ac-clang"))]) (ac-cider . [(20161006 719) ((cider (0 8 0)) (auto-complete (1 4)) (cl-lib (0 3))) "Clojure auto-complete sources using CIDER" single ((:commit . "fa13e067dd9c8c76151c7d140a2803da1d109b84") (:keywords "languages" "clojure" "nrepl" "cider" "compliment") (:authors ("Alex Yakushev" . "alex@bytopia.org") ("Steve Purcell" . "steve@sanityinc.com") ("Sam Aaron" . "samaaron@gmail.com")) (:maintainer "Alex Yakushev" . "alex@bytopia.org") (:url . "https://github.com/clojure-emacs/ac-cider"))]) (ac-capf . [(20151101 217) ((auto-complete (1 4)) (cl-lib (0 5))) "auto-complete source with completion-at-point" single ((:commit . "17571dba0a8f98111f2ab758e9bea285b263781b") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-ac-capf"))]) (ac-c-headers . [(20151021 834) ((auto-complete (1 3 1))) "auto-complete source for C headers" single ((:commit . "de13a1d35b311e6601556d8ef163de102057deea") (:authors ("zk_phi")) (:maintainer "zk_phi") (:url . "http://hins11.yu-yake.com/"))]) (ac-alchemist . [(20150908 656) ((auto-complete (1 5 0)) (alchemist (1 5 0)) (cl-lib (0 5))) "auto-complete source for alchemist" single ((:commit . "b1891c3d41aed83f61d78a609ea97be5cc2758d9") (:authors ("Syohei YOSHIDA" . "syohex@gmail.com")) (:maintainer "Syohei YOSHIDA" . "syohex@gmail.com") (:url . "https://github.com/syohex/emacs-ac-alchemist"))]) (abyss-theme . [(20170808 1345) ((emacs (24))) "A dark theme with contrasting colours." single ((:commit . "18791c6e8d9cc2b4815c9f08627a2e94fc0eeb14") (:keywords "theme" "dark" "contrasting colours") (:authors ("Matt Russell" . "matt@mgrbyte.co.uk")) (:maintainer "Matt Russell" . "matt@mgrbyte.co.uk") (:url . "https://github.com/mgrbyte/emacs-abyss-theme"))]) (abl-mode . [(20170604 2009) nil "Python TDD minor mode" single ((:commit . "9aff997fe7b4caded60150a832e3704ac55e69e5") (:authors ("Ulas Tuerkmen <ulas.tuerkmen at gmail dot com>")) (:maintainer "Ulas Tuerkmen <ulas.tuerkmen at gmail dot com>") (:url . "http://github.com/afroisalreadyinu/abl-mode"))]) (abgaben . [(20171119 646) ((pdf-tools (0 80)) (f (0 19 0)) (s (1 11 0))) "review and correct assignments received by mail" single ((:commit . "20d14830f07d66e2a04bcad1498a4a6fbf4b4451") (:keywords "mail" "outlines" "convenience") (:authors ("Arne Köhn" . "arne@chark.eu")) (:maintainer "Arne Köhn" . "arne@chark.eu") (:url . "http://arne.chark.eu/"))]) (abc-mode . [(20171020 1019) nil "Major mode for editing abc music files" single ((:commit . "238deedeb6c90df168045552eb463cfae9e1f88f") (:keywords "local" "docs") (:authors ("Matthew K. Junker" . "junker@alum.mit.edu")) (:maintainer "Matthew K. Junker" . "junker@alum.mit.edu"))]) (aa-edit-mode . [(20170119 320) ((emacs (24 3)) (navi2ch (2 0 0))) "Major mode for editing AA(S_JIS Art) and .mlt file" single ((:commit . "1dd801225b7ad3c23ad09698f5e77f0df7012a65") (:keywords "wp" "text" "shiftjis" "mlt" "yaruo") (:authors ("USAMI Kenta" . "tadsan@zonu.me")) (:maintainer "USAMI Kenta" . "tadsan@zonu.me"))]) (a . [(20180806 851) ((emacs (25))) "Associative data structure functions" single ((:commit . "79cef60deeefb6a22d42491f6eeb4d2820ff329a") (:keywords "lisp") (:authors ("Arne Brasseur" . "arne@arnebrasseur.net")) (:maintainer "Arne Brasseur" . "arne@arnebrasseur.net") (:url . "https://github.com/plexus/a.el"))]) (@ . [(20180726 1931) ((emacs (24 3))) "multiple-inheritance prototype-based objects DSL" tar ((:commit . "3671318a811fb51c03a792342af7b42004922809") (:authors ("Christopher Wellons" . "wellons@nullprogram.com")) (:maintainer "Christopher Wellons" . "wellons@nullprogram.com") (:url . "https://github.com/skeeto/at-el"))]) (4clojure . [(20131014 2207) ((json (1 2)) (request (0 2 0))) "Open and evaluate 4clojure.com questions" single ((:commit . "3cdfd356c24cd3518397d29ae833f56a4d20b4ca") (:keywords "languages" "data") (:authors ("Joshua Hoff")) (:maintainer "Joshua Hoff"))]) (2048-game . [(20151026 1933) nil "play 2048 in Emacs" single ((:authors ("Zachary Kanfer" . "zkanfer@gmail.com")) (:maintainer "Zachary Kanfer" . "zkanfer@gmail.com") (:url . "https://bitbucket.org/zck/2048.el"))]) (0xc . [(20170126 353) ((emacs (24 4)) (s (1 11 0))) "Base conversion made easy" single ((:commit . "12c2c6118c062a49594965c69e6a17bb46339eb2") (:keywords "base" "conversion") (:authors ("Adam Niederer" . "adam.niederer@gmail.com")) (:maintainer "Adam Niederer" . "adam.niederer@gmail.com") (:url . "http://github.com/AdamNiederer/0xc"))]) (0blayout . [(20161008 607) nil "Layout grouping with ease" single ((:commit . "873732ddb99a3ec18845a37467ee06bce4e61d87") (:keywords "convenience" "window-management") (:authors ("Elis \"etu\" Axelsson")) (:maintainer "Elis \"etu\" Axelsson") (:url . "https://github.com/etu/0blayout"))]))
diff --git a/configs/shared/emacs/.emacs.d/elpa/async-20180527.1030/async-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/async-20180527.1030/async-autoloads.el
new file mode 100644
index 0000000000..f44e50b3b5
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/async-20180527.1030/async-autoloads.el
@@ -0,0 +1,158 @@
+;;; async-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "async" "async.el" (23377 61605 799563 818000))
+;;; Generated autoloads from async.el
+
+(autoload 'async-start-process "async" "\
+Start the executable PROGRAM asynchronously.  See `async-start'.
+PROGRAM is passed PROGRAM-ARGS, calling FINISH-FUNC with the
+process object when done.  If FINISH-FUNC is nil, the future
+object will return the process object when the program is
+finished.  Set DEFAULT-DIRECTORY to change PROGRAM's current
+working directory.
+
+\(fn NAME PROGRAM FINISH-FUNC &rest PROGRAM-ARGS)" nil nil)
+
+(autoload 'async-start "async" "\
+Execute START-FUNC (often a lambda) in a subordinate Emacs process.
+When done, the return value is passed to FINISH-FUNC.  Example:
+
+    (async-start
+       ;; What to do in the child process
+       (lambda ()
+         (message \"This is a test\")
+         (sleep-for 3)
+         222)
+
+       ;; What to do when it finishes
+       (lambda (result)
+         (message \"Async process done, result should be 222: %s\"
+                  result)))
+
+If FINISH-FUNC is nil or missing, a future is returned that can
+be inspected using `async-get', blocking until the value is
+ready.  Example:
+
+    (let ((proc (async-start
+                   ;; What to do in the child process
+                   (lambda ()
+                     (message \"This is a test\")
+                     (sleep-for 3)
+                     222))))
+
+        (message \"I'm going to do some work here\") ;; ....
+
+        (message \"Waiting on async process, result should be 222: %s\"
+                 (async-get proc)))
+
+If you don't want to use a callback, and you don't care about any
+return value from the child process, pass the `ignore' symbol as
+the second argument (if you don't, and never call `async-get', it
+will leave *emacs* process buffers hanging around):
+
+    (async-start
+     (lambda ()
+       (delete-file \"a remote file on a slow link\" nil))
+     'ignore)
+
+Note: Even when FINISH-FUNC is present, a future is still
+returned except that it yields no value (since the value is
+passed to FINISH-FUNC).  Call `async-get' on such a future always
+returns nil.  It can still be useful, however, as an argument to
+`async-ready' or `async-wait'.
+
+\(fn START-FUNC &optional FINISH-FUNC)" nil nil)
+
+;;;***
+
+;;;### (autoloads nil "async-bytecomp" "async-bytecomp.el" (23377
+;;;;;;  61605 797595 754000))
+;;; Generated autoloads from async-bytecomp.el
+
+(autoload 'async-byte-recompile-directory "async-bytecomp" "\
+Compile all *.el files in DIRECTORY asynchronously.
+All *.elc files are systematically deleted before proceeding.
+
+\(fn DIRECTORY &optional QUIET)" nil nil)
+
+(defvar async-bytecomp-package-mode nil "\
+Non-nil if Async-Bytecomp-Package mode is enabled.
+See the `async-bytecomp-package-mode' command
+for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `async-bytecomp-package-mode'.")
+
+(custom-autoload 'async-bytecomp-package-mode "async-bytecomp" nil)
+
+(autoload 'async-bytecomp-package-mode "async-bytecomp" "\
+Byte compile asynchronously packages installed with package.el.
+Async compilation of packages can be controlled by
+`async-bytecomp-allowed-packages'.
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'async-byte-compile-file "async-bytecomp" "\
+Byte compile Lisp code FILE asynchronously.
+
+Same as `byte-compile-file' but asynchronous.
+
+\(fn FILE)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "dired-async" "dired-async.el" (23377 61605
+;;;;;;  793062 430000))
+;;; Generated autoloads from dired-async.el
+
+(defvar dired-async-mode nil "\
+Non-nil if Dired-Async mode is enabled.
+See the `dired-async-mode' command
+for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `dired-async-mode'.")
+
+(custom-autoload 'dired-async-mode "dired-async" nil)
+
+(autoload 'dired-async-mode "dired-async" "\
+Do dired actions asynchronously.
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'dired-async-do-copy "dired-async" "\
+Run ‘dired-do-copy’ asynchronously.
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'dired-async-do-symlink "dired-async" "\
+Run ‘dired-do-symlink’ asynchronously.
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'dired-async-do-hardlink "dired-async" "\
+Run ‘dired-do-hardlink’ asynchronously.
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'dired-async-do-rename "dired-async" "\
+Run ‘dired-do-rename’ asynchronously.
+
+\(fn &optional ARG)" t nil)
+
+;;;***
+
+;;;### (autoloads nil nil ("async-pkg.el" "smtpmail-async.el") (23377
+;;;;;;  61605 801409 281000))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; async-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/async-20180527.1030/async-bytecomp.el b/configs/shared/emacs/.emacs.d/elpa/async-20180527.1030/async-bytecomp.el
new file mode 100644
index 0000000000..7bb2d46a20
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/async-20180527.1030/async-bytecomp.el
@@ -0,0 +1,219 @@
+;;; async-bytecomp.el --- Compile elisp files asynchronously -*- lexical-binding: t -*-
+
+;; Copyright (C) 2014-2016 Free Software Foundation, Inc.
+
+;; Authors: John Wiegley <jwiegley@gmail.com>
+;;          Thierry Volpiatto <thierry.volpiatto@gmail.com>
+
+;; Keywords: dired async byte-compile
+;; X-URL: https://github.com/jwiegley/dired-async
+
+;; This program 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 2, or (at
+;; your option) any later version.
+
+;; This program 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; see the file COPYING.  If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+;;
+;;  This package provide the `async-byte-recompile-directory' function
+;;  which allows, as the name says to recompile a directory outside of
+;;  your running emacs.
+;;  The benefit is your files will be compiled in a clean environment without
+;;  the old *.el files loaded.
+;;  Among other things, this fix a bug in package.el which recompile
+;;  the new files in the current environment with the old files loaded, creating
+;;  errors in most packages after upgrades.
+;;
+;;  NB: This package is advicing the function `package--compile'.
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'async)
+
+(defcustom async-bytecomp-allowed-packages
+  '(async helm helm-core helm-ls-git helm-ls-hg magit)
+  "Packages in this list will be compiled asynchronously by `package--compile'.
+All the dependencies of these packages will be compiled async too,
+so no need to add dependencies to this list.
+The value of this variable can also be a list with a single element,
+the symbol `all', in this case packages are always compiled asynchronously."
+  :group 'async
+  :type '(repeat (choice symbol)))
+
+(defvar async-byte-compile-log-file
+  (concat user-emacs-directory "async-bytecomp.log"))
+
+;;;###autoload
+(defun async-byte-recompile-directory (directory &optional quiet)
+  "Compile all *.el files in DIRECTORY asynchronously.
+All *.elc files are systematically deleted before proceeding."
+  (cl-loop with dir = (directory-files directory t "\\.elc\\'")
+           unless dir return nil
+           for f in dir
+           when (file-exists-p f) do (delete-file f))
+  ;; Ensure async is reloaded when async.elc is deleted.
+  ;; This happen when recompiling its own directory.
+  (load "async")
+  (let ((call-back
+         (lambda (&optional _ignore)
+           (if (file-exists-p async-byte-compile-log-file)
+               (let ((buf (get-buffer-create byte-compile-log-buffer))
+                     (n 0))
+                 (with-current-buffer buf
+                   (goto-char (point-max))
+                   (let ((inhibit-read-only t))
+                     (insert-file-contents async-byte-compile-log-file)
+                     (compilation-mode))
+                   (display-buffer buf)
+                   (delete-file async-byte-compile-log-file)
+                   (unless quiet
+                     (save-excursion
+                       (goto-char (point-min))
+                       (while (re-search-forward "^.*:Error:" nil t)
+                         (cl-incf n)))
+                     (if (> n 0)
+                         (message "Failed to compile %d files in directory `%s'" n directory)
+                         (message "Directory `%s' compiled asynchronously with warnings" directory)))))
+               (unless quiet
+                 (message "Directory `%s' compiled asynchronously with success" directory))))))
+    (async-start
+     `(lambda ()
+        (require 'bytecomp)
+        ,(async-inject-variables "\\`\\(load-path\\)\\|byte\\'")
+        (let ((default-directory (file-name-as-directory ,directory))
+              error-data)
+          (add-to-list 'load-path default-directory)
+          (byte-recompile-directory ,directory 0 t)
+          (when (get-buffer byte-compile-log-buffer)
+            (setq error-data (with-current-buffer byte-compile-log-buffer
+                               (buffer-substring-no-properties (point-min) (point-max))))
+            (unless (string= error-data "")
+              (with-temp-file ,async-byte-compile-log-file
+                (erase-buffer)
+                (insert error-data))))))
+     call-back)
+    (unless quiet (message "Started compiling asynchronously directory %s" directory))))
+
+(defvar package-archive-contents)
+(defvar package-alist)
+(declare-function package-desc-reqs "package.el" (cl-x))
+
+(defun async-bytecomp--get-package-deps (pkg &optional only)
+  ;; Same as `package--get-deps' but parse instead `package-archive-contents'
+  ;; because PKG is not already installed and not present in `package-alist'.
+  ;; However fallback to `package-alist' in case PKG no more present
+  ;; in `package-archive-contents' due to modification to `package-archives'.
+  ;; See issue #58.
+  (let* ((pkg-desc (cadr (or (assq pkg package-archive-contents)
+                             (assq pkg package-alist))))
+         (direct-deps (cl-loop for p in (package-desc-reqs pkg-desc)
+                               for name = (car p)
+                               when (or (assq name package-archive-contents)
+                                        (assq name package-alist))
+                               collect name))
+         (indirect-deps (unless (eq only 'direct)
+                          (delete-dups
+                           (cl-loop for p in direct-deps append
+                                    (async-bytecomp--get-package-deps p))))))
+    (cl-case only
+      (direct   direct-deps)
+      (separate (list direct-deps indirect-deps))
+      (indirect indirect-deps)
+      (t        (delete-dups (append direct-deps indirect-deps))))))
+
+(defun async-bytecomp-get-allowed-pkgs ()
+  (when (and async-bytecomp-allowed-packages
+             (listp async-bytecomp-allowed-packages))
+    (if package-archive-contents
+        (cl-loop for p in async-bytecomp-allowed-packages
+                 when (assq p package-archive-contents)
+                 append (async-bytecomp--get-package-deps p) into reqs
+                 finally return
+                 (delete-dups
+                  (append async-bytecomp-allowed-packages reqs)))
+        async-bytecomp-allowed-packages)))
+
+(defadvice package--compile (around byte-compile-async)
+  (let ((cur-package (package-desc-name pkg-desc))
+        (pkg-dir (package-desc-dir pkg-desc)))
+    (if (or (equal async-bytecomp-allowed-packages '(all))
+            (memq cur-package (async-bytecomp-get-allowed-pkgs)))
+        (progn
+          (when (eq cur-package 'async)
+            (fmakunbound 'async-byte-recompile-directory))
+          ;; Add to `load-path' the latest version of async and
+          ;; reload it when reinstalling async.
+          (when (string= cur-package "async")
+            (cl-pushnew pkg-dir load-path)
+            (load "async-bytecomp"))
+          ;; `async-byte-recompile-directory' will add directory
+          ;; as needed to `load-path'.
+          (async-byte-recompile-directory (package-desc-dir pkg-desc) t))
+        ad-do-it)))
+
+;;;###autoload
+(define-minor-mode async-bytecomp-package-mode
+    "Byte compile asynchronously packages installed with package.el.
+Async compilation of packages can be controlled by
+`async-bytecomp-allowed-packages'."
+  :group 'async
+  :global t
+  (if async-bytecomp-package-mode
+      (ad-activate 'package--compile)
+      (ad-deactivate 'package--compile)))
+
+;;;###autoload
+(defun async-byte-compile-file (file)
+  "Byte compile Lisp code FILE asynchronously.
+
+Same as `byte-compile-file' but asynchronous."
+  (interactive "fFile: ")
+  (let ((call-back
+         (lambda (&optional _ignore)
+           (let ((bn (file-name-nondirectory file)))
+             (if (file-exists-p async-byte-compile-log-file)
+                 (let ((buf (get-buffer-create byte-compile-log-buffer))
+                       start)
+                   (with-current-buffer buf
+                     (goto-char (setq start (point-max)))
+                     (let ((inhibit-read-only t))
+                       (insert-file-contents async-byte-compile-log-file)
+                       (compilation-mode))
+                     (display-buffer buf)
+                     (delete-file async-byte-compile-log-file)
+                     (save-excursion
+                       (goto-char start)
+                       (if (re-search-forward "^.*:Error:" nil t)
+                           (message "Failed to compile `%s'" bn)
+                         (message "`%s' compiled asynchronously with warnings" bn)))))
+               (message "`%s' compiled asynchronously with success" bn))))))
+    (async-start
+     `(lambda ()
+        (require 'bytecomp)
+        ,(async-inject-variables "\\`load-path\\'")
+        (let ((default-directory ,(file-name-directory file)))
+          (add-to-list 'load-path default-directory)
+          (byte-compile-file ,file)
+          (when (get-buffer byte-compile-log-buffer)
+            (setq error-data (with-current-buffer byte-compile-log-buffer
+                               (buffer-substring-no-properties (point-min) (point-max))))
+            (unless (string= error-data "")
+              (with-temp-file ,async-byte-compile-log-file
+                (erase-buffer)
+                (insert error-data))))))
+     call-back)))
+
+(provide 'async-bytecomp)
+
+;;; async-bytecomp.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/async-20180527.1030/async-bytecomp.elc b/configs/shared/emacs/.emacs.d/elpa/async-20180527.1030/async-bytecomp.elc
new file mode 100644
index 0000000000..dd2cdf2318
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/async-20180527.1030/async-bytecomp.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/async-20180527.1030/async-pkg.el b/configs/shared/emacs/.emacs.d/elpa/async-20180527.1030/async-pkg.el
new file mode 100644
index 0000000000..1f999997fb
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/async-20180527.1030/async-pkg.el
@@ -0,0 +1,6 @@
+(define-package "async" "20180527.1030" "Asynchronous processing in Emacs" 'nil :keywords
+  '("async")
+  :url "https://github.com/jwiegley/emacs-async")
+;; Local Variables:
+;; no-byte-compile: t
+;; End:
diff --git a/configs/shared/emacs/.emacs.d/elpa/async-20180527.1030/async.el b/configs/shared/emacs/.emacs.d/elpa/async-20180527.1030/async.el
new file mode 100644
index 0000000000..771e641053
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/async-20180527.1030/async.el
@@ -0,0 +1,392 @@
+;;; async.el --- Asynchronous processing in Emacs -*- lexical-binding: t -*-
+
+;; Copyright (C) 2012-2016 Free Software Foundation, Inc.
+
+;; Author: John Wiegley <jwiegley@gmail.com>
+;; Created: 18 Jun 2012
+;; Version: 1.9.3
+
+;; Keywords: async
+;; X-URL: https://github.com/jwiegley/emacs-async
+
+;; This program 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 2, or (at
+;; your option) any later version.
+
+;; This program 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; see the file COPYING.  If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+
+;; Adds the ability to call asynchronous functions and process with ease.  See
+;; the documentation for `async-start' and `async-start-process'.
+
+;;; Code:
+
+(eval-when-compile (require 'cl-lib))
+
+(defgroup async nil
+  "Simple asynchronous processing in Emacs"
+  :group 'emacs)
+
+(defcustom async-variables-noprops-function #'async-variables-noprops
+  "Default function to remove text properties in variables."
+  :group 'async
+  :type 'function)
+
+(defvar async-debug nil)
+(defvar async-send-over-pipe t)
+(defvar async-in-child-emacs nil)
+(defvar async-callback nil)
+(defvar async-callback-for-process nil)
+(defvar async-callback-value nil)
+(defvar async-callback-value-set nil)
+(defvar async-current-process nil)
+(defvar async--procvar nil)
+
+(defun async-variables-noprops (sequence)
+  "Remove text properties in SEQUENCE.
+
+Argument SEQUENCE may be a list or a string, if anything else it
+is returned unmodified.
+
+Note that this is a naive function that doesn't remove text properties
+in SEQUENCE recursively, only at the first level which suffice in most
+cases."
+  (cond ((stringp sequence)
+         (substring-no-properties sequence))
+        ((listp sequence)
+         (cl-loop for elm in sequence
+                  if (stringp elm)
+                  collect (substring-no-properties elm)
+                  else collect elm))
+        (t sequence)))
+
+(defun async-inject-variables
+  (include-regexp &optional predicate exclude-regexp noprops)
+  "Return a `setq' form that replicates part of the calling environment.
+
+It sets the value for every variable matching INCLUDE-REGEXP and
+also PREDICATE.  It will not perform injection for any variable
+matching EXCLUDE-REGEXP (if present) or representing a syntax-table
+i.e. ending by \"-syntax-table\".
+When NOPROPS is non nil it tries to strip out text properties of each
+variable's value with `async-variables-noprops-function'.
+
+It is intended to be used as follows:
+
+    (async-start
+       `(lambda ()
+          (require 'smtpmail)
+          (with-temp-buffer
+            (insert ,(buffer-substring-no-properties (point-min) (point-max)))
+            ;; Pass in the variable environment for smtpmail
+            ,(async-inject-variables \"\\`\\(smtpmail\\|\\(user-\\)?mail\\)-\")
+            (smtpmail-send-it)))
+       'ignore)"
+  `(setq
+    ,@(let (bindings)
+        (mapatoms
+         (lambda (sym)
+           (let* ((sname (and (boundp sym) (symbol-name sym)))
+                  (value (and sname (symbol-value sym))))
+             (when (and sname
+                        (or (null include-regexp)
+                            (string-match include-regexp sname))
+                        (or (null exclude-regexp)
+                            (not (string-match exclude-regexp sname)))
+                        (not (string-match "-syntax-table\\'" sname)))
+               (unless (or (stringp value)
+                           (memq value '(nil t))
+                           (numberp value)
+                           (vectorp value))
+                 (setq value `(quote ,value)))
+               (when noprops
+                 (setq value (funcall async-variables-noprops-function
+                                      value)))
+               (when (or (null predicate)
+                         (funcall predicate sym))
+                 (setq bindings (cons value bindings)
+                       bindings (cons sym bindings)))))))
+        bindings)))
+
+(defalias 'async-inject-environment 'async-inject-variables)
+
+(defun async-handle-result (func result buf)
+  (if (null func)
+      (progn
+        (set (make-local-variable 'async-callback-value) result)
+        (set (make-local-variable 'async-callback-value-set) t))
+    (unwind-protect
+        (if (and (listp result)
+                 (eq 'async-signal (nth 0 result)))
+            (signal (car (nth 1 result))
+                    (cdr (nth 1 result)))
+          (funcall func result))
+      (unless async-debug
+        (kill-buffer buf)))))
+
+(defun async-when-done (proc &optional _change)
+  "Process sentinel used to retrieve the value from the child process."
+  (when (eq 'exit (process-status proc))
+    (with-current-buffer (process-buffer proc)
+      (let ((async-current-process proc))
+        (if (= 0 (process-exit-status proc))
+            (if async-callback-for-process
+                (if async-callback
+                    (prog1
+                        (funcall async-callback proc)
+                      (unless async-debug
+                        (kill-buffer (current-buffer))))
+                  (set (make-local-variable 'async-callback-value) proc)
+                  (set (make-local-variable 'async-callback-value-set) t))
+              (goto-char (point-max))
+              (backward-sexp)
+              (async-handle-result async-callback (read (current-buffer))
+                                   (current-buffer)))
+          (set (make-local-variable 'async-callback-value)
+               (list 'error
+                     (format "Async process '%s' failed with exit code %d"
+                             (process-name proc) (process-exit-status proc))))
+          (set (make-local-variable 'async-callback-value-set) t))))))
+
+(defun async--receive-sexp (&optional stream)
+  (let ((sexp (decode-coding-string (base64-decode-string
+                                     (read stream)) 'utf-8-auto))
+	;; Parent expects UTF-8 encoded text.
+	(coding-system-for-write 'utf-8-auto))
+    (if async-debug
+        (message "Received sexp {{{%s}}}" (pp-to-string sexp)))
+    (setq sexp (read sexp))
+    (if async-debug
+        (message "Read sexp {{{%s}}}" (pp-to-string sexp)))
+    (eval sexp)))
+
+(defun async--insert-sexp (sexp)
+  (let (print-level
+	print-length
+	(print-escape-nonascii t)
+	(print-circle t))
+    (prin1 sexp (current-buffer))
+    ;; Just in case the string we're sending might contain EOF
+    (encode-coding-region (point-min) (point-max) 'utf-8-auto)
+    (base64-encode-region (point-min) (point-max) t)
+    (goto-char (point-min)) (insert ?\")
+    (goto-char (point-max)) (insert ?\" ?\n)))
+
+(defun async--transmit-sexp (process sexp)
+  (with-temp-buffer
+    (if async-debug
+        (message "Transmitting sexp {{{%s}}}" (pp-to-string sexp)))
+    (async--insert-sexp sexp)
+    (process-send-region process (point-min) (point-max))))
+
+(defun async-batch-invoke ()
+  "Called from the child Emacs process' command-line."
+  ;; Make sure 'message' and 'prin1' encode stuff in UTF-8, as parent
+  ;; process expects.
+  (let ((coding-system-for-write 'utf-8-auto))
+    (setq async-in-child-emacs t
+	  debug-on-error async-debug)
+    (if debug-on-error
+	(prin1 (funcall
+		(async--receive-sexp (unless async-send-over-pipe
+				       command-line-args-left))))
+      (condition-case err
+	  (prin1 (funcall
+		  (async--receive-sexp (unless async-send-over-pipe
+					 command-line-args-left))))
+	(error
+	 (prin1 (list 'async-signal err)))))))
+
+(defun async-ready (future)
+  "Query a FUTURE to see if it is ready.
+
+I.e., if no blocking
+would result from a call to `async-get' on that FUTURE."
+  (and (memq (process-status future) '(exit signal))
+       (let ((buf (process-buffer future)))
+         (if (buffer-live-p buf)
+             (with-current-buffer buf
+               async-callback-value-set)
+             t))))
+
+(defun async-wait (future)
+  "Wait for FUTURE to become ready."
+  (while (not (async-ready future))
+    (sleep-for 0.05)))
+
+(defun async-get (future)
+  "Get the value from process FUTURE when it is ready.
+FUTURE is returned by `async-start' or `async-start-process' when
+its FINISH-FUNC is nil."
+  (and future (async-wait future))
+  (let ((buf (process-buffer future)))
+    (when (buffer-live-p buf)
+      (with-current-buffer buf
+        (async-handle-result
+         #'identity async-callback-value (current-buffer))))))
+
+(defun async-message-p (value)
+  "Return true of VALUE is an async.el message packet."
+  (and (listp value)
+       (plist-get value :async-message)))
+
+(defun async-send (&rest args)
+  "Send the given messages to the asychronous Emacs PROCESS."
+  (let ((args (append args '(:async-message t))))
+    (if async-in-child-emacs
+        (if async-callback
+            (funcall async-callback args))
+      (async--transmit-sexp (car args) (list 'quote (cdr args))))))
+
+(defun async-receive ()
+  "Send the given messages to the asychronous Emacs PROCESS."
+  (async--receive-sexp))
+
+;;;###autoload
+(defun async-start-process (name program finish-func &rest program-args)
+  "Start the executable PROGRAM asynchronously.  See `async-start'.
+PROGRAM is passed PROGRAM-ARGS, calling FINISH-FUNC with the
+process object when done.  If FINISH-FUNC is nil, the future
+object will return the process object when the program is
+finished.  Set DEFAULT-DIRECTORY to change PROGRAM's current
+working directory."
+  (let* ((buf (generate-new-buffer (concat "*" name "*")))
+         (proc (let ((process-connection-type nil))
+                 (apply #'start-process name buf program program-args))))
+    (with-current-buffer buf
+      (set (make-local-variable 'async-callback) finish-func)
+      (set-process-sentinel proc #'async-when-done)
+      (unless (string= name "emacs")
+        (set (make-local-variable 'async-callback-for-process) t))
+      proc)))
+
+(defvar async-quiet-switch "-Q"
+  "The Emacs parameter to use to call emacs without config.
+Can be one of \"-Q\" or \"-q\".
+Default is \"-Q\" but it is sometimes useful to use \"-q\" to have a
+enhanced config or some more variables loaded.")
+
+;;;###autoload
+(defun async-start (start-func &optional finish-func)
+  "Execute START-FUNC (often a lambda) in a subordinate Emacs process.
+When done, the return value is passed to FINISH-FUNC.  Example:
+
+    (async-start
+       ;; What to do in the child process
+       (lambda ()
+         (message \"This is a test\")
+         (sleep-for 3)
+         222)
+
+       ;; What to do when it finishes
+       (lambda (result)
+         (message \"Async process done, result should be 222: %s\"
+                  result)))
+
+If FINISH-FUNC is nil or missing, a future is returned that can
+be inspected using `async-get', blocking until the value is
+ready.  Example:
+
+    (let ((proc (async-start
+                   ;; What to do in the child process
+                   (lambda ()
+                     (message \"This is a test\")
+                     (sleep-for 3)
+                     222))))
+
+        (message \"I'm going to do some work here\") ;; ....
+
+        (message \"Waiting on async process, result should be 222: %s\"
+                 (async-get proc)))
+
+If you don't want to use a callback, and you don't care about any
+return value from the child process, pass the `ignore' symbol as
+the second argument (if you don't, and never call `async-get', it
+will leave *emacs* process buffers hanging around):
+
+    (async-start
+     (lambda ()
+       (delete-file \"a remote file on a slow link\" nil))
+     'ignore)
+
+Note: Even when FINISH-FUNC is present, a future is still
+returned except that it yields no value (since the value is
+passed to FINISH-FUNC).  Call `async-get' on such a future always
+returns nil.  It can still be useful, however, as an argument to
+`async-ready' or `async-wait'."
+  (let ((sexp start-func)
+	;; Subordinate Emacs will send text encoded in UTF-8.
+	(coding-system-for-read 'utf-8-auto))
+    (setq async--procvar
+          (async-start-process
+           "emacs" (file-truename
+                    (expand-file-name invocation-name
+                                      invocation-directory))
+           finish-func
+           async-quiet-switch "-l"
+           ;; Using `locate-library' ensure we use the right file
+           ;; when the .elc have been deleted.
+           (locate-library "async")
+           "-batch" "-f" "async-batch-invoke"
+           (if async-send-over-pipe
+               "<none>"
+               (with-temp-buffer
+                 (async--insert-sexp (list 'quote sexp))
+                 (buffer-string)))))
+    (if async-send-over-pipe
+        (async--transmit-sexp async--procvar (list 'quote sexp)))
+    async--procvar))
+
+(defmacro async-sandbox(func)
+  "Evaluate FUNC in a separate Emacs process, synchronously."
+  `(async-get (async-start ,func)))
+
+(defun async--fold-left (fn forms bindings)
+  (let ((res forms))
+    (dolist (binding bindings)
+      (setq res (funcall fn res
+                         (if (listp binding)
+                             binding
+                             (list binding)))))
+    res))
+
+(defmacro async-let (bindings &rest forms)
+  "Implements `let', but each binding is established asynchronously.
+For example:
+
+  (async-let ((x (foo))
+              (y (bar)))
+     (message \"%s %s\" x y))
+
+    expands to ==>
+
+  (async-start (foo)
+   (lambda (x)
+     (async-start (bar)
+      (lambda (y)
+        (message \"%s %s\" x y)))))"
+  (declare (indent 1))
+  (async--fold-left
+   (lambda (acc binding)
+     (let ((fun (pcase (cadr binding)
+                  ((and (pred functionp) f) f)
+                  (f `(lambda () ,f)))))
+       `(async-start ,fun
+                     (lambda (,(car binding))
+                       ,acc))))
+   `(progn ,@forms)
+   (reverse bindings)))
+
+(provide 'async)
+
+;;; async.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/async-20180527.1030/async.elc b/configs/shared/emacs/.emacs.d/elpa/async-20180527.1030/async.elc
new file mode 100644
index 0000000000..da36a94b10
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/async-20180527.1030/async.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/async-20180527.1030/dired-async.el b/configs/shared/emacs/.emacs.d/elpa/async-20180527.1030/dired-async.el
new file mode 100644
index 0000000000..bc406b3903
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/async-20180527.1030/dired-async.el
@@ -0,0 +1,405 @@
+;;; dired-async.el --- Asynchronous dired actions -*- lexical-binding: t -*-
+
+;; Copyright (C) 2012-2016 Free Software Foundation, Inc.
+
+;; Authors: John Wiegley <jwiegley@gmail.com>
+;;          Thierry Volpiatto <thierry.volpiatto@gmail.com>
+
+;; Keywords: dired async network
+;; X-URL: https://github.com/jwiegley/dired-async
+
+;; This program 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 2, or (at
+;; your option) any later version.
+
+;; This program 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; see the file COPYING.  If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+
+;; This file provide a redefinition of `dired-create-file' function,
+;; performs copies, moves and all what is handled by `dired-create-file'
+;; in the background using a slave Emacs process,
+;; by means of the async.el module.
+;; To use it, put this in your .emacs:
+
+;;     (dired-async-mode 1)
+
+;; This will enable async copy/rename etc...
+;; in dired and helm.
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'dired-aux)
+(require 'async)
+
+(eval-when-compile
+  (defvar async-callback))
+
+(defgroup dired-async nil
+  "Copy rename files asynchronously from dired."
+  :group 'dired)
+
+(defcustom dired-async-env-variables-regexp
+  "\\`\\(tramp-\\(default\\|connection\\|remote\\)\\|ange-ftp\\)-.*"
+  "Variables matching this regexp will be loaded on Child Emacs."
+  :type  'regexp
+  :group 'dired-async)
+
+(defcustom dired-async-message-function 'dired-async-mode-line-message
+  "Function to use to notify result when operation finish.
+Should take same args as `message'."
+  :group 'dired-async
+  :type  'function)
+
+(defcustom dired-async-log-file "/tmp/dired-async.log"
+  "File use to communicate errors from Child Emacs to host Emacs."
+  :group 'dired-async
+  :type 'string)
+
+(defcustom dired-async-mode-lighter '(:eval
+                                      (when (eq major-mode 'dired-mode)
+                                        " Async"))
+  "Mode line lighter used for `dired-async-mode'."
+  :group 'dired-async
+  :risky t
+  :type 'sexp)
+
+(defface dired-async-message
+    '((t (:foreground "yellow")))
+  "Face used for mode-line message."
+  :group 'dired-async)
+
+(defface dired-async-failures
+    '((t (:foreground "red")))
+  "Face used for mode-line message."
+  :group 'dired-async)
+
+(defface dired-async-mode-message
+    '((t (:foreground "Gold")))
+  "Face used for `dired-async--modeline-mode' lighter."
+  :group 'dired-async)
+
+(define-minor-mode dired-async--modeline-mode
+    "Notify mode-line that an async process run."
+  :group 'dired-async
+  :global t
+  :lighter (:eval (propertize (format " [%s Async job(s) running]"
+                                      (length (dired-async-processes)))
+                              'face 'dired-async-mode-message))
+  (unless dired-async--modeline-mode
+    (let ((visible-bell t)) (ding))))
+
+(defun dired-async-mode-line-message (text face &rest args)
+  "Notify end of operation in `mode-line'."
+  (message nil)
+  (let ((mode-line-format (concat
+                           " " (propertize
+                                (if args
+                                    (apply #'format text args)
+                                    text)
+                                'face face))))
+    (force-mode-line-update)
+    (sit-for 3)
+    (force-mode-line-update)))
+
+(defun dired-async-processes ()
+  (cl-loop for p in (process-list)
+           when (cl-loop for c in (process-command p) thereis
+                         (string= "async-batch-invoke" c))
+           collect p))
+
+(defun dired-async-kill-process ()
+  (interactive)
+  (let* ((processes (dired-async-processes))
+         (proc (car (last processes))))
+    (and proc (delete-process proc))
+    (unless (> (length processes) 1)
+      (dired-async--modeline-mode -1))))
+
+(defun dired-async-after-file-create (total operation failures skipped)
+  "Callback function used for operation handled by `dired-create-file'."
+  (unless (dired-async-processes)
+    ;; Turn off mode-line notification
+    ;; only when last process end.
+    (dired-async--modeline-mode -1))
+  (when operation
+    (if (file-exists-p dired-async-log-file)
+        (progn
+          (pop-to-buffer (get-buffer-create dired-log-buffer))
+          (goto-char (point-max))
+          (setq inhibit-read-only t)
+          (insert "Error: ")
+          (insert-file-contents dired-async-log-file)
+          (special-mode)
+          (shrink-window-if-larger-than-buffer)
+          (delete-file dired-async-log-file))
+        (run-with-timer
+         0.1 nil
+         (lambda ()
+           ;; First send error messages.
+           (cond (failures
+                  (funcall dired-async-message-function
+                           "%s failed for %d of %d file%s -- See *Dired log* buffer"
+                           'dired-async-failures
+                           (car operation) (length failures)
+                           total (dired-plural-s total)))
+                 (skipped
+                  (funcall dired-async-message-function
+                           "%s: %d of %d file%s skipped -- See *Dired log* buffer"
+                           'dired-async-failures
+                           (car operation) (length skipped) total
+                           (dired-plural-s total))))
+           (when dired-buffers
+             (cl-loop for (_f . b) in dired-buffers
+                      when (buffer-live-p b)
+                      do (with-current-buffer b (revert-buffer nil t))))
+           ;; Finally send the success message.
+           (funcall dired-async-message-function
+                    "Asynchronous %s of %s on %s file%s done"
+                    'dired-async-message
+                    (car operation) (cadr operation)
+                    total (dired-plural-s total)))))))
+
+(defun dired-async-maybe-kill-ftp ()
+  "Return a form to kill ftp process in child emacs."
+  (quote
+   (progn
+     (require 'cl-lib)
+     (let ((buf (cl-loop for b in (buffer-list)
+                         thereis (and (string-match
+                                       "\\`\\*ftp.*"
+                                       (buffer-name b)) b))))
+       (when buf (kill-buffer buf))))))
+
+(defvar overwrite-query)
+(defun dired-async-create-files (file-creator operation fn-list name-constructor
+                                 &optional _marker-char)
+  "Same as `dired-create-files' but asynchronous.
+
+See `dired-create-files' for the behavior of arguments."
+  (setq overwrite-query nil)
+  (let ((total (length fn-list))
+        failures async-fn-list skipped callback
+        async-quiet-switch)
+    (let (to)
+      (dolist (from fn-list)
+        (setq to (funcall name-constructor from))
+        (if (and (equal to from)
+                 (null (eq file-creator 'backup-file)))
+            (progn
+              (setq to nil)
+              (dired-log "Cannot %s to same file: %s\n"
+                         (downcase operation) from)))
+        (if (not to)
+            (setq skipped (cons (dired-make-relative from) skipped))
+            (let* ((overwrite (and (null (eq file-creator 'backup-file))
+                                   (file-exists-p to)))
+                   (dired-overwrite-confirmed ; for dired-handle-overwrite
+                    (and overwrite
+                         (let ((help-form `(format "\
+Type SPC or `y' to overwrite file `%s',
+DEL or `n' to skip to next,
+ESC or `q' to not overwrite any of the remaining files,
+`!' to overwrite all remaining files with no more questions." ,to)))
+                           (dired-query 'overwrite-query "Overwrite `%s'?" to)))))
+              ;; Handle the `dired-copy-file' file-creator specially
+              ;; When copying a directory to another directory or
+              ;; possibly to itself or one of its subdirectories.
+              ;; e.g "~/foo/" => "~/test/"
+              ;; or "~/foo/" =>"~/foo/"
+              ;; or "~/foo/ => ~/foo/bar/")
+              ;; In this case the 'name-constructor' have set the destination
+              ;; TO to "~/test/foo" because the old emacs23 behavior
+              ;; of `copy-directory' was to not create the subdirectory
+              ;; and instead copy the contents.
+              ;; With the new behavior of `copy-directory'
+              ;; (similar to the `cp' shell command) we don't
+              ;; need such a construction of the target directory,
+              ;; so modify the destination TO to "~/test/" instead of "~/test/foo/".
+              (let ((destname (file-name-directory to)))
+                (when (and (file-directory-p from)
+                           (file-directory-p to)
+                           (eq file-creator 'dired-copy-file))
+                  (setq to destname))
+                ;; If DESTNAME is a subdirectory of FROM, not a symlink,
+                ;; and the method in use is copying, signal an error.
+                (and (eq t (car (file-attributes destname)))
+                     (eq file-creator 'dired-copy-file)
+                     (file-in-directory-p destname from)
+                     (error "Cannot copy `%s' into its subdirectory `%s'"
+                            from to)))
+              (if overwrite
+                  (or (and dired-overwrite-confirmed
+                           (push (cons from to) async-fn-list))
+                      (progn
+                        (push (dired-make-relative from) failures)
+                        (dired-log "%s `%s' to `%s' failed\n"
+                                   operation from to)))
+                  (push (cons from to) async-fn-list)))))
+      ;; Fix tramp issue #80 with emacs-26, use "-q" only when needed.
+      (setq async-quiet-switch
+            (if (and (boundp 'tramp-cache-read-persistent-data)
+                     async-fn-list
+                     (cl-loop for (_from . to) in async-fn-list
+                              thereis (file-remote-p to)))
+                "-q" "-Q"))
+      ;; When failures have been printed to dired log add the date at bob.
+      (when (or failures skipped) (dired-log t))
+      ;; When async-fn-list is empty that's mean only one file
+      ;; had to be copied and user finally answer NO.
+      ;; In this case async process will never start and callback
+      ;; will have no chance to run, so notify failures here.
+      (unless async-fn-list
+        (cond (failures
+               (funcall dired-async-message-function
+                        "%s failed for %d of %d file%s -- See *Dired log* buffer"
+                        'dired-async-failures
+                        operation (length failures)
+                        total (dired-plural-s total)))
+              (skipped
+               (funcall dired-async-message-function
+                        "%s: %d of %d file%s skipped -- See *Dired log* buffer"
+                        'dired-async-failures
+                        operation (length skipped) total
+                        (dired-plural-s total)))))
+      ;; Setup callback.
+      (setq callback
+            (lambda (&optional _ignore)
+               (dired-async-after-file-create
+                total (list operation (length async-fn-list)) failures skipped)
+               (when (string= (downcase operation) "rename")
+                 (cl-loop for (file . to) in async-fn-list
+                          for bf = (get-file-buffer file)
+                          for destp = (file-exists-p to)
+                          do (and bf destp
+                                  (with-current-buffer bf
+                                    (set-visited-file-name to t t))))))))
+    ;; Start async process.
+    (when async-fn-list
+      (async-start `(lambda ()
+                      (require 'cl-lib) (require 'dired-aux) (require 'dired-x)
+                      ,(async-inject-variables dired-async-env-variables-regexp)
+                          (let ((dired-recursive-copies (quote always))
+                                (dired-copy-preserve-time
+                                 ,dired-copy-preserve-time))
+                            (setq overwrite-backup-query nil)
+                            ;; Inline `backup-file' as long as it is not
+                            ;; available in emacs.
+                            (defalias 'backup-file
+                                ;; Same feature as "cp -f --backup=numbered from to"
+                                ;; Symlinks are copied as file from source unlike
+                                ;; `dired-copy-file' which is same as cp -d.
+                                ;; Directories are omitted.
+                                (lambda (from to ok)
+                                  (cond ((file-directory-p from) (ignore))
+                                        (t (let ((count 0))
+                                             (while (let ((attrs (file-attributes to)))
+                                                      (and attrs (null (nth 0 attrs))))
+                                               (cl-incf count)
+                                               (setq to (concat (file-name-sans-versions to)
+                                                                (format ".~%s~" count)))))
+                                           (condition-case err
+                                               (copy-file from to ok dired-copy-preserve-time)
+                                             (file-date-error
+                                              (dired-log "Can't set date on %s:\n%s\n" from err)))))))
+                            ;; Now run the FILE-CREATOR function on files.
+                            (cl-loop with fn = (quote ,file-creator)
+                                     for (from . dest) in (quote ,async-fn-list)
+                                     do (condition-case err
+                                            (funcall fn from dest t)
+                                          (file-error
+                                           (dired-log "%s: %s\n" (car err) (cdr err)))
+                                          nil))
+                        (when (get-buffer dired-log-buffer)
+                          (dired-log t)
+                          (with-current-buffer dired-log-buffer
+                           (write-region (point-min) (point-max)
+                                         ,dired-async-log-file))))
+                      ,(dired-async-maybe-kill-ftp))
+                   callback)
+      ;; Run mode-line notifications while process running.
+      (dired-async--modeline-mode 1)
+      (message "%s proceeding asynchronously..." operation))))
+
+(defvar wdired-use-interactive-rename)
+(defun dired-async-wdired-do-renames (old-fn &rest args)
+  ;; Perhaps a better fix would be to ask for renaming BEFORE starting
+  ;; OLD-FN when `wdired-use-interactive-rename' is non-nil.  For now
+  ;; just bind it to nil to ensure no questions will be asked between
+  ;; each rename.
+  (let (wdired-use-interactive-rename)
+    (apply old-fn args)))
+
+(defadvice wdired-do-renames (around wdired-async)
+  (let (wdired-use-interactive-rename)
+    ad-do-it))
+
+(defadvice dired-create-files (around dired-async)
+  (dired-async-create-files file-creator operation fn-list
+                            name-constructor marker-char))
+
+;;;###autoload
+(define-minor-mode dired-async-mode
+  "Do dired actions asynchronously."
+  :group 'dired-async
+  :lighter dired-async-mode-lighter
+  :global t
+  (if dired-async-mode
+      (if (fboundp 'advice-add)
+          (progn (advice-add 'dired-create-files :override #'dired-async-create-files)
+                 (advice-add 'wdired-do-renames :around #'dired-async-wdired-do-renames))
+        (ad-activate 'dired-create-files)
+        (ad-activate 'wdired-do-renames))
+      (if (fboundp 'advice-remove)
+          (progn (advice-remove 'dired-create-files #'dired-async-create-files)
+                 (advice-remove 'wdired-do-renames #'dired-async-wdired-do-renames))
+          (ad-deactivate 'dired-create-files)
+          (ad-deactivate 'wdired-do-renames))))
+
+(defmacro dired-async--with-async-create-files (&rest body)
+  "Evaluate BODY with ‘dired-create-files’ set to ‘dired-async-create-files’."
+  (declare (indent 0))
+  `(cl-letf (((symbol-function 'dired-create-files) #'dired-async-create-files))
+     ,@body))
+
+;;;###autoload
+(defun dired-async-do-copy (&optional arg)
+  "Run ‘dired-do-copy’ asynchronously."
+  (interactive "P")
+  (dired-async--with-async-create-files
+    (dired-do-copy arg)))
+
+;;;###autoload
+(defun dired-async-do-symlink (&optional arg)
+  "Run ‘dired-do-symlink’ asynchronously."
+  (interactive "P")
+  (dired-async--with-async-create-files
+    (dired-do-symlink arg)))
+
+;;;###autoload
+(defun dired-async-do-hardlink (&optional arg)
+  "Run ‘dired-do-hardlink’ asynchronously."
+  (interactive "P")
+  (dired-async--with-async-create-files
+    (dired-do-hardlink arg)))
+
+;;;###autoload
+(defun dired-async-do-rename (&optional arg)
+  "Run ‘dired-do-rename’ asynchronously."
+  (interactive "P")
+  (dired-async--with-async-create-files
+    (dired-do-rename arg)))
+
+(provide 'dired-async)
+
+;;; dired-async.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/async-20180527.1030/dired-async.elc b/configs/shared/emacs/.emacs.d/elpa/async-20180527.1030/dired-async.elc
new file mode 100644
index 0000000000..5f17b056c5
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/async-20180527.1030/dired-async.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/async-20180527.1030/smtpmail-async.el b/configs/shared/emacs/.emacs.d/elpa/async-20180527.1030/smtpmail-async.el
new file mode 100644
index 0000000000..ac269231ca
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/async-20180527.1030/smtpmail-async.el
@@ -0,0 +1,73 @@
+;;; smtpmail-async.el --- Send e-mail with smtpmail.el asynchronously -*- lexical-binding: t -*-
+
+;; Copyright (C) 2012-2016 Free Software Foundation, Inc.
+
+;; Author: John Wiegley <jwiegley@gmail.com>
+;; Created: 18 Jun 2012
+
+;; Keywords: email async
+;; X-URL: https://github.com/jwiegley/emacs-async
+
+;; This program 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 2, or (at
+;; your option) any later version.
+
+;; This program 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; see the file COPYING.  If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+
+;; Send e-mail with smtpmail.el asynchronously.  To use:
+;;
+;;   (require 'smtpmail-async)
+;;
+;;   (setq send-mail-function 'async-smtpmail-send-it
+;;         message-send-mail-function 'async-smtpmail-send-it)
+;;
+;; This assumes you already have smtpmail.el working.
+
+;;; Code:
+
+(defgroup smtpmail-async nil
+  "Send e-mail with smtpmail.el asynchronously"
+  :group 'smptmail)
+
+(require 'async)
+(require 'smtpmail)
+(require 'message)
+
+(defvar async-smtpmail-before-send-hook nil
+  "Hook running in the child emacs in `async-smtpmail-send-it'.
+It is called just before calling `smtpmail-send-it'.")
+
+(defun async-smtpmail-send-it ()
+  (let ((to          (message-field-value "To"))
+        (buf-content (buffer-substring-no-properties
+                      (point-min) (point-max))))
+    (message "Delivering message to %s..." to)
+    (async-start
+     `(lambda ()
+        (require 'smtpmail)
+        (with-temp-buffer
+          (insert ,buf-content)
+          (set-buffer-multibyte nil)
+          ;; Pass in the variable environment for smtpmail
+          ,(async-inject-variables
+            "\\`\\(smtpmail\\|async-smtpmail\\|\\(user-\\)?mail\\)-\\|auth-sources\\|epg\\|nsm"
+            nil "\\`\\(mail-header-format-function\\|smtpmail-address-buffer\\|mail-mode-abbrev-table\\)")
+          (run-hooks 'async-smtpmail-before-send-hook)
+          (smtpmail-send-it)))
+     (lambda (&optional _ignore)
+       (message "Delivering message to %s...done" to)))))
+
+(provide 'smtpmail-async)
+
+;;; smtpmail-async.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/async-20180527.1030/smtpmail-async.elc b/configs/shared/emacs/.emacs.d/elpa/async-20180527.1030/smtpmail-async.elc
new file mode 100644
index 0000000000..8c364cf1f8
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/async-20180527.1030/smtpmail-async.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/avy-20180615.801/avy-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/avy-20180615.801/avy-autoloads.el
new file mode 100644
index 0000000000..1e0ad22fed
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/avy-20180615.801/avy-autoloads.el
@@ -0,0 +1,253 @@
+;;; avy-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "avy" "avy.el" (23377 60991 205495 602000))
+;;; Generated autoloads from avy.el
+
+(autoload 'avy-goto-char "avy" "\
+Jump to the currently visible CHAR.
+The window scope is determined by `avy-all-windows' (ARG negates it).
+
+\(fn CHAR &optional ARG)" t nil)
+
+(autoload 'avy-goto-char-in-line "avy" "\
+Jump to the currently visible CHAR in the current line.
+
+\(fn CHAR)" t nil)
+
+(autoload 'avy-goto-char-2 "avy" "\
+Jump to the currently visible CHAR1 followed by CHAR2.
+The window scope is determined by `avy-all-windows'.
+When ARG is non-nil, do the opposite of `avy-all-windows'.
+BEG and END narrow the scope where candidates are searched.
+
+\(fn CHAR1 CHAR2 &optional ARG BEG END)" t nil)
+
+(autoload 'avy-goto-char-2-above "avy" "\
+Jump to the currently visible CHAR1 followed by CHAR2.
+This is a scoped version of `avy-goto-char-2', where the scope is
+the visible part of the current buffer up to point.
+The window scope is determined by `avy-all-windows'.
+When ARG is non-nil, do the opposite of `avy-all-windows'.
+
+\(fn CHAR1 CHAR2 &optional ARG)" t nil)
+
+(autoload 'avy-goto-char-2-below "avy" "\
+Jump to the currently visible CHAR1 followed by CHAR2.
+This is a scoped version of `avy-goto-char-2', where the scope is
+the visible part of the current buffer following point.
+The window scope is determined by `avy-all-windows'.
+When ARG is non-nil, do the opposite of `avy-all-windows'.
+
+\(fn CHAR1 CHAR2 &optional ARG)" t nil)
+
+(autoload 'avy-isearch "avy" "\
+Jump to one of the current isearch candidates.
+
+\(fn)" t nil)
+
+(autoload 'avy-goto-word-0 "avy" "\
+Jump to a word start.
+The window scope is determined by `avy-all-windows'.
+When ARG is non-nil, do the opposite of `avy-all-windows'.
+BEG and END narrow the scope where candidates are searched.
+
+\(fn ARG &optional BEG END)" t nil)
+
+(autoload 'avy-goto-word-1 "avy" "\
+Jump to the currently visible CHAR at a word start.
+The window scope is determined by `avy-all-windows'.
+When ARG is non-nil, do the opposite of `avy-all-windows'.
+BEG and END narrow the scope where candidates are searched.
+When SYMBOL is non-nil, jump to symbol start instead of word start.
+
+\(fn CHAR &optional ARG BEG END SYMBOL)" t nil)
+
+(autoload 'avy-goto-word-1-above "avy" "\
+Jump to the currently visible CHAR at a word start.
+This is a scoped version of `avy-goto-word-1', where the scope is
+the visible part of the current buffer up to point.
+The window scope is determined by `avy-all-windows'.
+When ARG is non-nil, do the opposite of `avy-all-windows'.
+
+\(fn CHAR &optional ARG)" t nil)
+
+(autoload 'avy-goto-word-1-below "avy" "\
+Jump to the currently visible CHAR at a word start.
+This is a scoped version of `avy-goto-word-1', where the scope is
+the visible part of the current buffer following point.
+The window scope is determined by `avy-all-windows'.
+When ARG is non-nil, do the opposite of `avy-all-windows'.
+
+\(fn CHAR &optional ARG)" t nil)
+
+(autoload 'avy-goto-symbol-1 "avy" "\
+Jump to the currently visible CHAR at a symbol start.
+The window scope is determined by `avy-all-windows'.
+When ARG is non-nil, do the opposite of `avy-all-windows'.
+
+\(fn CHAR &optional ARG)" t nil)
+
+(autoload 'avy-goto-symbol-1-above "avy" "\
+Jump to the currently visible CHAR at a symbol start.
+This is a scoped version of `avy-goto-symbol-1', where the scope is
+the visible part of the current buffer up to point.
+The window scope is determined by `avy-all-windows'.
+When ARG is non-nil, do the opposite of `avy-all-windows'.
+
+\(fn CHAR &optional ARG)" t nil)
+
+(autoload 'avy-goto-symbol-1-below "avy" "\
+Jump to the currently visible CHAR at a symbol start.
+This is a scoped version of `avy-goto-symbol-1', where the scope is
+the visible part of the current buffer following point.
+The window scope is determined by `avy-all-windows'.
+When ARG is non-nil, do the opposite of `avy-all-windows'.
+
+\(fn CHAR &optional ARG)" t nil)
+
+(autoload 'avy-goto-subword-0 "avy" "\
+Jump to a word or subword start.
+The window scope is determined by `avy-all-windows' (ARG negates it).
+
+When PREDICATE is non-nil it's a function of zero parameters that
+should return true.
+
+BEG and END narrow the scope where candidates are searched.
+
+\(fn &optional ARG PREDICATE BEG END)" t nil)
+
+(autoload 'avy-goto-subword-1 "avy" "\
+Jump to the currently visible CHAR at a subword start.
+The window scope is determined by `avy-all-windows' (ARG negates it).
+The case of CHAR is ignored.
+
+\(fn CHAR &optional ARG)" t nil)
+
+(autoload 'avy-goto-word-or-subword-1 "avy" "\
+Forward to `avy-goto-subword-1' or `avy-goto-word-1'.
+Which one depends on variable `subword-mode'.
+
+\(fn)" t nil)
+
+(autoload 'avy-goto-line "avy" "\
+Jump to a line start in current buffer.
+
+When ARG is 1, jump to lines currently visible, with the option
+to cancel to `goto-line' by entering a number.
+
+When ARG is 4, negate the window scope determined by
+`avy-all-windows'.
+
+Otherwise, forward to `goto-line' with ARG.
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'avy-goto-line-above "avy" "\
+Goto visible line above the cursor.
+OFFSET changes the distance between the closest key to the cursor and
+the cursor
+When BOTTOM-UP is non-nil, display avy candidates from top to bottom
+
+\(fn &optional OFFSET BOTTOM-UP)" t nil)
+
+(autoload 'avy-goto-line-below "avy" "\
+Goto visible line below the cursor.
+OFFSET changes the distance between the closest key to the cursor and
+the cursor
+When BOTTOM-UP is non-nil, display avy candidates from top to bottom
+
+\(fn &optional OFFSET BOTTOM-UP)" t nil)
+
+(autoload 'avy-copy-line "avy" "\
+Copy a selected line above the current line.
+ARG lines can be used.
+
+\(fn ARG)" t nil)
+
+(autoload 'avy-move-line "avy" "\
+Move a selected line above the current line.
+ARG lines can be used.
+
+\(fn ARG)" t nil)
+
+(autoload 'avy-copy-region "avy" "\
+Select two lines and copy the text between them to point.
+
+The window scope is determined by `avy-all-windows' or
+`avy-all-windows-alt' when ARG is non-nil.
+
+\(fn ARG)" t nil)
+
+(autoload 'avy-move-region "avy" "\
+Select two lines and move the text between them above the current line.
+
+\(fn)" t nil)
+
+(autoload 'avy-kill-region "avy" "\
+Select two lines and kill the region between them.
+
+The window scope is determined by `avy-all-windows' or
+`avy-all-windows-alt' when ARG is non-nil.
+
+\(fn ARG)" t nil)
+
+(autoload 'avy-kill-ring-save-region "avy" "\
+Select two lines and save the region between them to the kill ring.
+The window scope is determined by `avy-all-windows'.
+When ARG is non-nil, do the opposite of `avy-all-windows'.
+
+\(fn ARG)" t nil)
+
+(autoload 'avy-kill-whole-line "avy" "\
+Select line and kill the whole selected line.
+
+With a numerical prefix ARG, kill ARG line(s) starting from the
+selected line.  If ARG is negative, kill backward.
+
+If ARG is zero, kill the selected line but exclude the trailing
+newline.
+
+\\[universal-argument] 3 \\[avy-kil-whole-line] kill three lines
+starting from the selected line.  \\[universal-argument] -3
+
+\\[avy-kill-whole-line] kill three lines backward including the
+selected line.
+
+\(fn ARG)" t nil)
+
+(autoload 'avy-kill-ring-save-whole-line "avy" "\
+Select line and save the whole selected line as if killed, but don’t kill it.
+
+This command is similar to `avy-kill-whole-line', except that it
+saves the line(s) as if killed, but does not kill it(them).
+
+With a numerical prefix ARG, kill ARG line(s) starting from the
+selected line.  If ARG is negative, kill backward.
+
+If ARG is zero, kill the selected line but exclude the trailing
+newline.
+
+\(fn ARG)" t nil)
+
+(autoload 'avy-setup-default "avy" "\
+Setup the default shortcuts.
+
+\(fn)" nil nil)
+
+(autoload 'avy-goto-char-timer "avy" "\
+Read one or many consecutive chars and jump to the first one.
+The window scope is determined by `avy-all-windows' (ARG negates it).
+
+\(fn &optional ARG)" t nil)
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; avy-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/avy-20180615.801/avy-pkg.el b/configs/shared/emacs/.emacs.d/elpa/avy-20180615.801/avy-pkg.el
new file mode 100644
index 0000000000..9f80788dd2
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/avy-20180615.801/avy-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "avy" "20180615.801" "Jump to arbitrary positions in visible text and select text quickly." '((emacs "24.1") (cl-lib "0.5")))
diff --git a/configs/shared/emacs/.emacs.d/elpa/avy-20180615.801/avy.el b/configs/shared/emacs/.emacs.d/elpa/avy-20180615.801/avy.el
new file mode 100644
index 0000000000..4fc2f3a9d6
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/avy-20180615.801/avy.el
@@ -0,0 +1,2001 @@
+;;; avy.el --- Jump to arbitrary positions in visible text and select text quickly. -*- lexical-binding: t -*-
+
+;; Copyright (C) 2015  Free Software Foundation, Inc.
+
+;; Author: Oleh Krehel <ohwoeowho@gmail.com>
+;; URL: https://github.com/abo-abo/avy
+;; Package-Version: 20180615.801
+;; Version: 0.4.0
+;; Package-Requires: ((emacs "24.1") (cl-lib "0.5"))
+;; Keywords: point, location
+
+;; This file is part of GNU Emacs.
+
+;; This file 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, or (at your option)
+;; any later version.
+
+;; This program 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.
+
+;; For a full copy of the GNU General Public License
+;; see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;
+;; With Avy, you can move point to any position in Emacs – even in a
+;; different window – using very few keystrokes. For this, you look at
+;; the position where you want point to be, invoke Avy, and then enter
+;; the sequence of characters displayed at that position.
+;;
+;; If the position you want to jump to can be determined after only
+;; issuing a single keystroke, point is moved to the desired position
+;; immediately after that keystroke. In case this isn't possible, the
+;; sequence of keystrokes you need to enter is comprised of more than
+;; one character. Avy uses a decision tree where each candidate position
+;; is a leaf and each edge is described by a character which is distinct
+;; per level of the tree. By entering those characters, you navigate the
+;; tree, quickly arriving at the desired candidate position, such that
+;; Avy can move point to it.
+;;
+;; Note that this only makes sense for positions you are able to see
+;; when invoking Avy. These kinds of positions are supported:
+;;
+;; * character positions
+;; * word or subword start positions
+;; * line beginning positions
+;; * link positions
+;; * window positions
+;;
+;; If you're familiar with the popular `ace-jump-mode' package, this
+;; package does all that and more, without the implementation
+;; headache.
+
+;;; Code:
+(require 'cl-lib)
+(require 'ring)
+
+;;* Customization
+(defgroup avy nil
+  "Jump to things tree-style."
+  :group 'convenience
+  :prefix "avy-")
+
+(defcustom avy-keys '(?a ?s ?d ?f ?g ?h ?j ?k ?l)
+  "Default keys for jumping.
+Any key is either a character representing a self-inserting
+key (letters, digits, punctuation, etc.) or a symbol denoting a
+non-printing key like an arrow key (left, right, up, down).  For
+non-printing keys, a corresponding entry in
+`avy-key-to-char-alist' must exist in order to visualize the key
+in the avy overlays.
+
+If `avy-style' is set to words, make sure there are at least three
+keys different than the following: a, e, i, o, u, y"
+  :type '(repeat :tag "Keys" (choice
+                              (character :tag "char")
+                              (symbol :tag "non-printing key"))))
+
+(defcustom avy-keys-alist nil
+  "Alist of avy-jump commands to `avy-keys' overriding the default `avy-keys'."
+  :type '(alist
+          :key-type (choice :tag "Command"
+                     (const avy-goto-char)
+                     (const avy-goto-char-2)
+                     (const avy-isearch)
+                     (const avy-goto-line)
+                     (const avy-goto-subword-0)
+                     (const avy-goto-subword-1)
+                     (const avy-goto-word-0)
+                     (const avy-goto-word-1)
+                     (const avy-copy-line)
+                     (const avy-copy-region)
+                     (const avy-move-line)
+                     (const avy-move-region)
+                     (const avy-kill-whole-line)
+                     (const avy-kill-region)
+                     (const avy-kill-ring-save-whole-line)
+                     (const avy-kill-ring-save-region)
+                     (function :tag "Other command"))
+          :value-type (repeat :tag "Keys" character)))
+
+(defcustom avy-words
+  '("am" "by" "if" "is" "it" "my" "ox" "up"
+    "ace" "act" "add" "age" "ago" "aim" "air" "ale" "all" "and" "ant" "any"
+    "ape" "apt" "arc" "are" "arm" "art" "ash" "ate" "awe" "axe" "bad" "bag"
+    "ban" "bar" "bat" "bay" "bed" "bee" "beg" "bet" "bid" "big" "bit" "bob"
+    "bot" "bow" "box" "boy" "but" "cab" "can" "cap" "car" "cat" "cog" "cop"
+    "cow" "cry" "cup" "cut" "day" "dew" "did" "die" "dig" "dim" "dip" "dog"
+    "dot" "dry" "dub" "dug" "dye" "ear" "eat" "eel" "egg" "ego" "elf" "eve"
+    "eye" "fan" "far" "fat" "fax" "fee" "few" "fin" "fit" "fix" "flu" "fly"
+    "foe" "fog" "for" "fox" "fry" "fun" "fur" "gag" "gap" "gas" "gel" "gem"
+    "get" "gig" "gin" "gnu" "god" "got" "gum" "gun" "gut" "guy" "gym" "had"
+    "hag" "ham" "has" "hat" "her" "hid" "him" "hip" "his" "hit" "hop" "hot"
+    "how" "hub" "hue" "hug" "hut" "ice" "icy" "imp" "ink" "inn" "ion" "ire"
+    "ivy" "jab" "jam" "jar" "jaw" "jet" "job" "jog" "joy" "key" "kid" "kit"
+    "lag" "lap" "lay" "let" "lid" "lie" "lip" "lit" "lob" "log" "lot" "low"
+    "mad" "man" "map" "mat" "may" "men" "met" "mix" "mob" "mop" "mud" "mug"
+    "nag" "nap" "new" "nil" "nod" "nor" "not" "now" "nun" "oak" "odd" "off"
+    "oil" "old" "one" "orb" "ore" "ork" "our" "out" "owl" "own" "pad" "pan"
+    "par" "pat" "paw" "pay" "pea" "pen" "pet" "pig" "pin" "pit" "pod" "pot"
+    "pry" "pub" "pun" "put" "rag" "ram" "ran" "rat" "raw" "ray" "red" "rib"
+    "rim" "rip" "rob" "rod" "rot" "row" "rub" "rug" "rum" "run" "sad" "sat"
+    "saw" "say" "sea" "see" "sew" "she" "shy" "sin" "sip" "sit" "six" "ski"
+    "sky" "sly" "sob" "son" "soy" "spy" "sum" "sun" "tab" "tad" "tag" "tan"
+    "tap" "tar" "tax" "tea" "the" "tie" "tin" "tip" "toe" "ton" "too" "top"
+    "toy" "try" "tub" "two" "urn" "use" "van" "war" "was" "wax" "way" "web"
+    "wed" "wet" "who" "why" "wig" "win" "wit" "woe" "won" "wry" "you" "zap"
+    "zip" "zoo")
+  "Words to use in case `avy-style' is set to `words'.
+Every word should contain at least one vowel i.e. one of the following
+characters: a, e, i, o, u, y
+They do not have to be sorted but no word should be a prefix of another one."
+  :type '(repeat string))
+
+(defcustom avy-style 'at-full
+  "The default method of displaying the overlays.
+Use `avy-styles-alist' to customize this per-command."
+  :type '(choice
+          (const :tag "Pre" pre)
+          (const :tag "At" at)
+          (const :tag "At Full" at-full)
+          (const :tag "Post" post)
+          (const :tag "De Bruijn" de-bruijn)
+          (const :tag "Words" words)))
+
+(defcustom avy-styles-alist nil
+  "Alist of avy-jump commands to the style for each command.
+If the commands isn't on the list, `avy-style' is used."
+  :type '(alist
+          :key-type (choice :tag "Command"
+                     (const avy-goto-char)
+                     (const avy-goto-char-2)
+                     (const avy-isearch)
+                     (const avy-goto-line)
+                     (const avy-goto-subword-0)
+                     (const avy-goto-subword-1)
+                     (const avy-goto-word-0)
+                     (const avy-goto-word-1)
+                     (const avy-copy-line)
+                     (const avy-copy-region)
+                     (const avy-move-line)
+                     (const avy-move-region)
+                     (const avy-kill-whole-line)
+                     (const avy-kill-region)
+                     (const avy-kill-ring-save-whole-line)
+                     (const avy-kill-ring-save-region)
+                     (function :tag "Other command"))
+          :value-type (choice
+                       (const :tag "Pre" pre)
+                       (const :tag "At" at)
+                       (const :tag "At Full" at-full)
+                       (const :tag "Post" post)
+                       (const :tag "De Bruijn" de-bruijn)
+                       (const :tag "Words" words))))
+
+(defcustom avy-dispatch-alist
+  '((?x . avy-action-kill-move)
+    (?X . avy-action-kill-stay)
+    (?t . avy-action-teleport)
+    (?m . avy-action-mark)
+    (?n . avy-action-copy)
+    (?y . avy-action-yank)
+    (?i . avy-action-ispell)
+    (?z . avy-action-zap-to-char))
+  "List of actions for `avy-handler-default'.
+
+Each item is (KEY . ACTION).  When KEY not on `avy-keys' is
+pressed during the dispatch, ACTION is set to replace the default
+`avy-action-goto' once a candidate is finally selected."
+  :type
+  '(alist
+    :key-type (choice (character :tag "Char"))
+    :value-type (choice
+                 (const :tag "Mark" avy-action-mark)
+                 (const :tag "Copy" avy-action-copy)
+                 (const :tag "Kill and move point" avy-action-kill-move)
+                 (const :tag "Kill" avy-action-kill-stay))))
+
+(defcustom avy-background nil
+  "When non-nil, a gray background will be added during the selection."
+  :type 'boolean)
+
+(defcustom avy-all-windows t
+  "Determine the list of windows to consider in search of candidates."
+  :type
+  '(choice
+    (const :tag "All Frames" all-frames)
+    (const :tag "This Frame" t)
+    (const :tag "This Window" nil)))
+
+(defcustom avy-case-fold-search t
+  "Non-nil if searches should ignore case."
+  :type 'boolean)
+
+(defcustom avy-word-punc-regexp "[!-/:-@[-`{-~]"
+  "Regexp of punctuation chars that count as word starts for `avy-goto-word-1.
+When nil, punctuation chars will not be matched.
+
+\"[!-/:-@[-`{-~]\" will match all printable punctuation chars."
+  :type 'regexp)
+
+(defcustom avy-goto-word-0-regexp "\\b\\sw"
+  "Regexp that determines positions for `avy-goto-word-0'."
+  :type '(choice
+          (const :tag "Default" "\\b\\sw")
+          (const :tag "Symbol" "\\_<\\(\\sw\\|\\s_\\)")
+          (const :tag "Not whitespace" "[^ \r\n\t]+")
+          (regexp :tag "Regex")))
+
+(defcustom avy-ignored-modes '(image-mode doc-view-mode pdf-view-mode)
+  "List of modes to ignore when searching for candidates.
+Typically, these modes don't use the text representation."
+  :type 'list)
+
+(defvar avy-ring (make-ring 20)
+  "Hold the window and point history.")
+
+(defvar avy-translate-char-function #'identity
+  "Function to translate user input key into another key.
+For example, to make SPC do the same as ?a, use
+\(lambda (c) (if (= c 32) ?a c)).")
+
+(defface avy-lead-face-0
+  '((t (:foreground "white" :background "#4f57f9")))
+  "Face used for first non-terminating leading chars.")
+
+(defface avy-lead-face-1
+  '((t (:foreground "white" :background "gray")))
+  "Face used for matched leading chars.")
+
+(defface avy-lead-face-2
+  '((t (:foreground "white" :background "#f86bf3")))
+  "Face used for leading chars.")
+
+(defface avy-lead-face
+  '((t (:foreground "white" :background "#e52b50")))
+  "Face used for the leading chars.")
+
+(defface avy-background-face
+  '((t (:foreground "gray40")))
+  "Face for whole window background during selection.")
+
+(defface avy-goto-char-timer-face
+  '((t (:inherit highlight)))
+  "Face for matches during reading chars using `avy-goto-char-timer'.")
+
+(defconst avy-lead-faces '(avy-lead-face
+                           avy-lead-face-0
+                           avy-lead-face-2
+                           avy-lead-face
+                           avy-lead-face-0
+                           avy-lead-face-2)
+  "Face sequence for `avy--overlay-at-full'.")
+
+(defvar avy-key-to-char-alist '((left . ?◀)
+                                (right . ?▶)
+                                (up . ?▲)
+                                (down . ?▼)
+                                (prior . ?△)
+                                (next . ?▽))
+  "An alist from non-character keys to printable chars used in avy overlays.
+This alist must contain all keys used in `avy-keys' which are not
+self-inserting keys and thus aren't read as characters.")
+
+;;* Internals
+;;** Tree
+(defmacro avy-multipop (lst n)
+  "Remove LST's first N elements and return them."
+  `(if (<= (length ,lst) ,n)
+       (prog1 ,lst
+         (setq ,lst nil))
+     (prog1 ,lst
+       (setcdr
+        (nthcdr (1- ,n) (prog1 ,lst (setq ,lst (nthcdr ,n ,lst))))
+        nil))))
+
+(defun avy--de-bruijn (keys n)
+  "De Bruijn sequence for alphabet KEYS and subsequences of length N."
+  (let* ((k (length keys))
+         (a (make-list (* n k) 0))
+         sequence)
+    (cl-labels ((db (T p)
+                  (if (> T n)
+                      (if (eq (% n p) 0)
+                          (setq sequence
+                                (append sequence
+                                        (cl-subseq a 1 (1+ p)))))
+                    (setf (nth T a) (nth (- T p) a))
+                    (db (1+ T) p)
+                    (cl-loop for j from (1+ (nth (- T p) a)) to (1- k) do
+                         (setf (nth T a) j)
+                         (db (1+ T) T)))))
+      (db 1 1)
+      (mapcar (lambda (n)
+                (nth n keys))
+              sequence))))
+
+(defun avy--path-alist-1 (lst seq-len keys)
+  "Build a De Bruin sequence from LST.
+SEQ-LEN is how many elements of KEYS it takes to identify a match."
+  (let ((db-seq (avy--de-bruijn keys seq-len))
+        prev-pos prev-seq prev-win path-alist)
+    ;; The De Bruijn seq is cyclic, so append the seq-len - 1 first chars to
+    ;; the end.
+    (setq db-seq (nconc db-seq (cl-subseq db-seq 0 (1- seq-len))))
+    (cl-labels ((subseq-and-pop ()
+                  (when (nth (1- seq-len) db-seq)
+                    (prog1 (cl-subseq db-seq 0 seq-len)
+                      (pop db-seq)))))
+      (while lst
+        (let* ((cur (car lst))
+               (pos (cond
+                      ;; ace-window has matches of the form (pos . wnd)
+                      ((integerp (car cur)) (car cur))
+                      ;; avy-jump have form ((start . end) . wnd)
+                      ((consp (car cur)) (caar cur))
+                      (t (error "Unexpected match representation: %s" cur))))
+               (win (cdr cur))
+               (path (if prev-pos
+                         (let ((diff (if (eq win prev-win)
+                                         (- pos prev-pos)
+                                       0)))
+                           (when (and (> diff 0) (< diff seq-len))
+                             (while (and (nth (1- seq-len) db-seq)
+                                         (not
+                                          (eq 0
+                                              (cl-search
+                                               (cl-subseq prev-seq diff)
+                                               (cl-subseq db-seq 0 seq-len)))))
+                               (pop db-seq)))
+                           (subseq-and-pop))
+                       (subseq-and-pop))))
+          (if (not path)
+              (setq lst nil
+                    path-alist nil)
+            (push (cons path (car lst)) path-alist)
+            (setq prev-pos pos
+                  prev-seq path
+                  prev-win win
+                  lst (cdr lst))))))
+    (nreverse path-alist)))
+
+(defun avy-tree (lst keys)
+  "Coerce LST into a balanced tree.
+The degree of the tree is the length of KEYS.
+KEYS are placed appropriately on internal nodes."
+  (let ((len (length keys)))
+    (cl-labels
+        ((rd (ls)
+           (let ((ln (length ls)))
+             (if (< ln len)
+                 (cl-pairlis keys
+                             (mapcar (lambda (x) (cons 'leaf x)) ls))
+               (let ((ks (copy-sequence keys))
+                     res)
+                 (dolist (s (avy-subdiv ln len))
+                   (push (cons (pop ks)
+                               (if (eq s 1)
+                                   (cons 'leaf (pop ls))
+                                 (rd (avy-multipop ls s))))
+                         res))
+                 (nreverse res))))))
+      (rd lst))))
+
+(defun avy-subdiv (n b)
+  "Distribute N in B terms in a balanced way."
+  (let* ((p (1- (floor (+ (log n b) 1e-6))))
+         (x1 (expt b p))
+         (x2 (* b x1))
+         (delta (- n x2))
+         (n2 (/ delta (- x2 x1)))
+         (n1 (- b n2 1)))
+    (append
+     (make-list n1 x1)
+     (list
+      (- n (* n1 x1) (* n2 x2)))
+     (make-list n2 x2))))
+
+(defun avy-traverse (tree walker &optional recur-key)
+  "Traverse TREE generated by `avy-tree'.
+WALKER is a function that takes KEYS and LEAF.
+
+RECUR-KEY is used in recursion.
+
+LEAF is a member of LST argument of `avy-tree'.
+
+KEYS is the path from the root of `avy-tree' to LEAF."
+  (dolist (br tree)
+    (let ((key (cons (car br) recur-key)))
+      (if (eq (cadr br) 'leaf)
+          (funcall walker key (cddr br))
+        (avy-traverse (cdr br) walker key)))))
+
+(defvar avy-action nil
+  "Function to call at the end of select.")
+
+(defun avy-handler-default (char)
+  "The default handler for a bad CHAR."
+  (let (dispatch)
+    (cond ((setq dispatch (assoc char avy-dispatch-alist))
+           (setq avy-action (cdr dispatch))
+           (throw 'done 'restart))
+          ((memq char '(27 ?\C-g))
+           ;; exit silently
+           (throw 'done 'exit))
+          ((mouse-event-p char)
+           (signal 'user-error (list "Mouse event not handled" char)))
+          (t
+           (signal 'user-error (list "No such candidate"
+                                     (if (characterp char) (string char) char)))
+           (throw 'done nil)))))
+
+(defvar avy-handler-function 'avy-handler-default
+  "A function to call for a bad `read-key' in `avy-read'.")
+
+(defvar avy-current-path ""
+  "Store the current incomplete path during `avy-read'.")
+
+(defun avy-mouse-event-window (char)
+  "If CHAR is a mouse event, return the window of the event if any or the selected window.
+Return nil if not a mouse event."
+  (when (mouse-event-p char)
+    (cond ((windowp (posn-window (event-start char)))
+           (posn-window (event-start char)))
+          ((framep (posn-window (event-start char)))
+           (frame-selected-window (posn-window (event-start char))))
+          (t (selected-window)))))
+
+(defun avy-read (tree display-fn cleanup-fn)
+  "Select a leaf from TREE using consecutive `read-char'.
+
+DISPLAY-FN should take CHAR and LEAF and signify that LEAFs
+associated with CHAR will be selected if CHAR is pressed.  This is
+commonly done by adding a CHAR overlay at LEAF position.
+
+CLEANUP-FN should take no arguments and remove the effects of
+multiple DISPLAY-FN invocations."
+  (catch 'done
+    (setq avy-current-path "")
+    (while tree
+      (let ((avy--leafs nil))
+        (avy-traverse tree
+                      (lambda (path leaf)
+                        (push (cons path leaf) avy--leafs)))
+        (dolist (x avy--leafs)
+          (funcall display-fn (car x) (cdr x))))
+      (let ((char (funcall avy-translate-char-function (read-key)))
+            window
+            branch)
+        (funcall cleanup-fn)
+        (if (setq window (avy-mouse-event-window char))
+            (throw 'done (cons char window))
+          ;; Ensure avy-current-path stores the full path prior to
+          ;; exit so other packages can utilize its value.
+          (setq avy-current-path
+                (concat avy-current-path (string (avy--key-to-char char))))
+          (if (setq branch (assoc char tree))
+              (if (eq (car (setq tree (cdr branch))) 'leaf)
+                  (throw 'done (cdr tree)))
+            (funcall avy-handler-function char)))))))
+
+(defun avy-read-de-bruijn (lst keys)
+  "Select from LST dispatching on KEYS."
+  ;; In theory, the De Bruijn sequence B(k,n) has k^n subsequences of length n
+  ;; (the path length) usable as paths, thus that's the lower bound.  Due to
+  ;; partially overlapping matches, not all subsequences may be usable, so it's
+  ;; possible that the path-len must be incremented, e.g., if we're matching
+  ;; for x and a buffer contains xaxbxcx only every second subsequence is
+  ;; usable for the four matches.
+  (catch 'done
+    (let* ((path-len (ceiling (log (length lst) (length keys))))
+           (alist (avy--path-alist-1 lst path-len keys)))
+      (while (not alist)
+        (cl-incf path-len)
+        (setq alist (avy--path-alist-1 lst path-len keys)))
+      (let* ((len (length (caar alist)))
+             (i 0))
+        (setq avy-current-path "")
+        (while (< i len)
+          (dolist (x (reverse alist))
+            (avy--overlay-at-full (reverse (car x)) (cdr x)))
+          (let ((char (funcall avy-translate-char-function (read-key))))
+            (avy--remove-leading-chars)
+            (setq alist
+                  (delq nil
+                        (mapcar (lambda (x)
+                                  (when (eq (caar x) char)
+                                    (cons (cdr (car x)) (cdr x))))
+                                alist)))
+            (setq avy-current-path
+                  (concat avy-current-path (string (avy--key-to-char char))))
+            (cl-incf i)
+            (unless alist
+              (funcall avy-handler-function char))))
+        (cdar alist)))))
+
+(defun avy-read-words (lst words)
+  "Select from LST using WORDS."
+  (catch 'done
+    (let ((num-words (length words))
+          (num-entries (length lst))
+          alist)
+      ;; If there are not enough words to cover all the candidates,
+      ;; we use a De Bruijn sequence to generate the remaining ones.
+      (when (< num-words num-entries)
+        (let ((keys avy-keys)
+              (bad-keys '(?a ?e ?i ?o ?u ?y))
+              (path-len 1)
+              (num-remaining (- num-entries num-words))
+              tmp-alist)
+          ;; Delete all keys which could lead to duplicates.
+          ;; We want at least three keys left to work with.
+          (dolist (x bad-keys)
+            (when (memq x keys)
+              (setq keys (delq ?a keys))))
+          (when (< (length keys) 3)
+            (signal 'user-error
+                    '("Please add more keys to the variable `avy-keys'.")))
+          ;; Generate the sequence and add the keys to the existing words.
+          (while (not tmp-alist)
+            (cl-incf path-len)
+            (setq tmp-alist (avy--path-alist-1 lst path-len keys)))
+          (while (>= (cl-decf num-remaining) 0)
+            (push (mapconcat 'string (caar tmp-alist) nil) (cdr (last words)))
+            (setq tmp-alist (cdr tmp-alist)))))
+      (dolist (x lst)
+        (push (cons (string-to-list (pop words)) x) alist))
+      (setq avy-current-path "")
+      (while (or (> (length alist) 1)
+                 (caar alist))
+        (dolist (x (reverse alist))
+          (avy--overlay-at-full (reverse (car x)) (cdr x)))
+        (let ((char (funcall avy-translate-char-function (read-key))))
+          (avy--remove-leading-chars)
+          (setq alist
+                (delq nil
+                      (mapcar (lambda (x)
+                                (when (eq (caar x) char)
+                                  (cons (cdr (car x)) (cdr x))))
+                              alist)))
+          (setq avy-current-path
+                (concat avy-current-path (string (avy--key-to-char char))))
+          (unless alist
+            (funcall avy-handler-function char))))
+      (cdar alist))))
+
+;;** Rest
+(defun avy-window-list ()
+  "Return a list of windows depending on `avy-all-windows'."
+  (cond ((eq avy-all-windows 'all-frames)
+         (cl-mapcan #'window-list (frame-list)))
+
+        ((eq avy-all-windows t)
+         (window-list))
+
+        ((null avy-all-windows)
+         (list (selected-window)))
+
+        (t
+         (error "Unrecognized option: %S" avy-all-windows))))
+
+(defcustom avy-all-windows-alt nil
+  "The alternative `avy-all-windows' for use with \\[universal-argument]."
+  :type '(choice
+          (const :tag "Current window" nil)
+          (const :tag "All windows on the current frame" t)
+          (const :tag "All windows on all frames" all-frames)))
+
+(defmacro avy-dowindows (flip &rest body)
+  "Depending on FLIP and `avy-all-windows' run BODY in each or selected window."
+  (declare (indent 1)
+           (debug (form body)))
+  `(let ((avy-all-windows (if ,flip
+                              avy-all-windows-alt
+                            avy-all-windows)))
+     (dolist (wnd (avy-window-list))
+       (with-selected-window wnd
+         (unless (memq major-mode avy-ignored-modes)
+           ,@body)))))
+
+(defun avy-resume ()
+  "Stub to hold last avy command.
+Commands using `avy-with' macro can be resumed."
+  (interactive))
+
+(defvar avy-command nil
+  "Store the current command symbol.
+E.g. 'avy-goto-line or 'avy-goto-char.")
+
+(defmacro avy-with (command &rest body)
+  "Set `avy-keys' according to COMMAND and execute BODY.
+Set `avy-style' according to COMMMAND as well."
+  (declare (indent 1)
+           (debug (form body)))
+  `(let ((avy-keys (or (cdr (assq ',command avy-keys-alist))
+                       avy-keys))
+         (avy-style (or (cdr (assq ',command avy-styles-alist))
+                        avy-style))
+         (avy-command ',command))
+     (setq avy-action nil)
+     (setf (symbol-function 'avy-resume)
+           (lambda ()
+             (interactive)
+             ,@body))
+     ,@body))
+
+(defun avy-action-goto (pt)
+  "Goto PT."
+  (let ((frame (window-frame (selected-window))))
+    (unless (equal frame (selected-frame))
+      (select-frame-set-input-focus frame)
+      (raise-frame frame))
+    (goto-char pt)))
+
+(defun avy-forward-item ()
+  (if (eq avy-command 'avy-goto-line)
+      (end-of-line)
+    (forward-sexp))
+  (point))
+
+(defun avy-action-mark (pt)
+  "Mark sexp at PT."
+  (goto-char pt)
+  (set-mark (point))
+  (avy-forward-item))
+
+(defun avy-action-copy (pt)
+  "Copy sexp starting on PT."
+  (save-excursion
+    (let (str)
+      (goto-char pt)
+      (avy-forward-item)
+      (setq str (buffer-substring pt (point)))
+      (kill-new str)
+      (message "Copied: %s" str)))
+  (let ((dat (ring-ref avy-ring 0)))
+    (select-frame-set-input-focus
+     (window-frame (cdr dat)))
+    (select-window (cdr dat))
+    (goto-char (car dat))))
+
+(defun avy-action-yank (pt)
+  "Yank sexp starting at PT at the current point."
+  (avy-action-copy pt)
+  (yank)
+  t)
+
+(defun avy-action-kill-move (pt)
+  "Kill sexp at PT and move there."
+  (goto-char pt)
+  (avy-forward-item)
+  (kill-region pt (point))
+  (message "Killed: %s" (current-kill 0))
+  (point))
+
+(defun avy-action-kill-stay (pt)
+  "Kill sexp at PT."
+  (save-excursion
+    (goto-char pt)
+    (avy-forward-item)
+    (kill-region pt (point))
+    (just-one-space))
+  (message "Killed: %s" (current-kill 0))
+  (select-window
+   (cdr
+    (ring-ref avy-ring 0)))
+  t)
+
+(defun avy-action-zap-to-char (pt)
+  "Kill from point up to PT."
+  (if (> pt (point))
+      (kill-region (point) pt)
+    (kill-region pt (point))))
+
+(defun avy-action-teleport (pt)
+  "Kill sexp starting on PT and yank into the current location."
+  (avy-action-kill-stay pt)
+  (select-window
+   (cdr
+    (ring-ref avy-ring 0)))
+  (save-excursion
+    (yank))
+  t)
+
+(declare-function flyspell-correct-word-before-point "flyspell")
+
+(defun avy-action-ispell (pt)
+  "Auto correct word at PT."
+  (save-excursion
+    (goto-char pt)
+    (cond
+      ((eq avy-command 'avy-goto-line)
+       (ispell-region
+        (line-beginning-position)
+        (line-end-position)))
+      ((bound-and-true-p flyspell-mode)
+       (flyspell-correct-word-before-point))
+      ((looking-at-p "\\b")
+       (ispell-word))
+      (t
+       (progn
+         (backward-word)
+         (when (looking-at-p "\\b")
+           (ispell-word)))))))
+
+(defun avy--process-1 (candidates overlay-fn)
+  (let ((len (length candidates)))
+    (cond ((= len 0)
+           nil)
+          ((= len 1)
+           (car candidates))
+          (t
+           (unwind-protect
+                (progn
+                  (avy--make-backgrounds
+                   (avy-window-list))
+                  (cond ((eq avy-style 'de-bruijn)
+                         (avy-read-de-bruijn
+                          candidates avy-keys))
+                        ((eq avy-style 'words)
+                         (avy-read-words
+                          candidates avy-words))
+                        (t
+                         (avy-read (avy-tree candidates avy-keys)
+                                   overlay-fn
+                                   #'avy--remove-leading-chars))))
+             (avy--done))))))
+
+(defun avy--process (candidates overlay-fn)
+  "Select one of CANDIDATES using `avy-read'.
+Use OVERLAY-FN to visualize the decision overlay."
+  (unless (and (consp (car candidates))
+               (windowp (cdar candidates)))
+    (setq candidates
+          (mapcar (lambda (x) (cons x (selected-window)))
+                  candidates)))
+  (let ((original-cands (copy-sequence candidates))
+        (res (avy--process-1 candidates overlay-fn)))
+    (cond
+      ((null res)
+       (message "zero candidates")
+       t)
+      ((eq res 'restart)
+       (avy--process original-cands overlay-fn))
+      ;; ignore exit from `avy-handler-function'
+      ((eq res 'exit))
+      (t
+       (avy-push-mark)
+       (when (and (consp res)
+                  (windowp (cdr res)))
+         (let* ((window (cdr res))
+                (frame (window-frame window)))
+           (unless (equal frame (selected-frame))
+             (select-frame-set-input-focus frame))
+           (select-window window))
+         (setq res (car res)))
+
+       (funcall (or avy-action 'avy-action-goto)
+                (if (consp res)
+                    (car res)
+                  res))))))
+
+(defvar avy--overlays-back nil
+  "Hold overlays for when `avy-background' is t.")
+
+(defun avy--make-backgrounds (wnd-list)
+  "Create a dim background overlay for each window on WND-LIST."
+  (when avy-background
+    (setq avy--overlays-back
+          (mapcar (lambda (w)
+                    (let ((ol (make-overlay
+                               (window-start w)
+                               (window-end w)
+                               (window-buffer w))))
+                      (overlay-put ol 'face 'avy-background-face)
+                      (overlay-put ol 'window w)
+                      ol))
+                  wnd-list))))
+
+(defun avy--done ()
+  "Clean up overlays."
+  (mapc #'delete-overlay avy--overlays-back)
+  (setq avy--overlays-back nil)
+  (avy--remove-leading-chars))
+
+(defun avy--next-visible-point ()
+  "Return the next closest point without 'invisible property."
+  (let ((s (point)))
+    (while (and (not (= (point-max) (setq s (next-char-property-change s))))
+                (get-char-property s 'invisible)))
+    s))
+
+(defun avy--next-invisible-point ()
+  "Return the next closest point with 'invisible property."
+  (let ((s (point)))
+    (while (and (not (= (point-max) (setq s (next-char-property-change s))))
+                (not (get-char-property s 'invisible))))
+    s))
+
+(defun avy--find-visible-regions (rbeg rend)
+  "Return a list of all visible regions between RBEG and REND."
+  (setq rbeg (max rbeg (point-min)))
+  (setq rend (min rend (point-max)))
+  (when (< rbeg rend)
+    (let (visibles beg)
+      (save-excursion
+        (save-restriction
+          (narrow-to-region rbeg rend)
+          (setq beg (goto-char (point-min)))
+          (while (not (= (point) (point-max)))
+            (goto-char (avy--next-invisible-point))
+            (push (cons beg (point)) visibles)
+            (setq beg (goto-char (avy--next-visible-point))))
+          (nreverse visibles))))))
+
+(defun avy--regex-candidates (regex &optional beg end pred group)
+  "Return all elements that match REGEX.
+Each element of the list is ((BEG . END) . WND)
+When PRED is non-nil, it's a filter for matching point positions.
+When GROUP is non-nil, (BEG . END) should delimit that regex group."
+  (setq group (or group 0))
+  (let ((case-fold-search (or avy-case-fold-search
+                              (string= regex (downcase regex))))
+        candidates)
+    (avy-dowindows current-prefix-arg
+      (dolist (pair (avy--find-visible-regions
+                     (or beg (window-start))
+                     (or end (window-end (selected-window) t))))
+        (save-excursion
+          (goto-char (car pair))
+          (while (re-search-forward regex (cdr pair) t)
+            (unless (get-char-property (1- (point)) 'invisible)
+              (when (or (null pred)
+                        (funcall pred))
+                (push (cons (cons (match-beginning group)
+                                  (match-end group))
+                            wnd) candidates)))))))
+    (nreverse candidates)))
+
+(defvar avy--overlay-offset 0
+  "The offset to apply in `avy--overlay'.")
+
+(defvar avy--overlays-lead nil
+  "Hold overlays for leading chars.")
+
+(defun avy--remove-leading-chars ()
+  "Remove leading char overlays."
+  (mapc #'delete-overlay avy--overlays-lead)
+  (setq avy--overlays-lead nil))
+
+(defun avy--old-str (pt wnd)
+  "Return a one-char string at PT in WND."
+  (let ((old-str (with-selected-window wnd
+                   (buffer-substring pt (1+ pt)))))
+    (if avy-background
+        (propertize old-str 'face 'avy-background-face)
+      old-str)))
+
+(defun avy--overlay (str beg end wnd &optional compose-fn)
+  "Create an overlay with STR from BEG to END in WND.
+COMPOSE-FN is a lambda that concatenates the old string at BEG with STR."
+  (let ((eob (with-selected-window wnd (point-max))))
+    (when (<= beg eob)
+      (let* ((beg (+ beg avy--overlay-offset))
+             (ol (make-overlay beg (or end (1+ beg)) (window-buffer wnd)))
+             (old-str (if (eq beg eob) "" (avy--old-str beg wnd)))
+             (os-line-prefix (get-text-property 0 'line-prefix old-str))
+             (os-wrap-prefix (get-text-property 0 'wrap-prefix old-str))
+             other-ol)
+        (when os-line-prefix
+          (add-text-properties 0 1 `(line-prefix ,os-line-prefix) str))
+        (when os-wrap-prefix
+          (add-text-properties 0 1 `(wrap-prefix ,os-wrap-prefix) str))
+        (when (setq other-ol (cl-find-if
+                              (lambda (o) (overlay-get o 'goto-address))
+                              (overlays-at beg)))
+          (add-text-properties
+           0 (length old-str)
+           `(face ,(overlay-get other-ol 'face)) old-str))
+        (overlay-put ol 'window wnd)
+        (overlay-put ol 'category 'avy)
+        (overlay-put ol (if (eq beg eob)
+                            'after-string
+                          'display)
+                     (funcall
+                      (or compose-fn #'concat)
+                      str old-str))
+        (push ol avy--overlays-lead)))))
+
+(defcustom avy-highlight-first nil
+  "When non-nil highlight the first decision char with `avy-lead-face-0'.
+Do this even when the char is terminating."
+  :type 'boolean)
+
+(defun avy--key-to-char (c)
+  "If C is no character, translate it using `avy-key-to-char-alist'."
+  (cond ((characterp c) c)
+        ((cdr (assoc c avy-key-to-char-alist)))
+        ((mouse-event-p c) c)
+        (t
+         (error "Unknown key %s" c))))
+
+(defun avy-candidate-beg (leaf)
+  "Return the start position for LEAF."
+  (cond ((numberp leaf)
+         leaf)
+        ((consp (car leaf))
+         (caar leaf))
+        (t
+         (car leaf))))
+
+(defun avy-candidate-end (leaf)
+  "Return the end position for LEAF."
+  (cond ((numberp leaf)
+         leaf)
+        ((consp (car leaf))
+         (cdar leaf))
+        (t
+         (car leaf))))
+
+(defun avy-candidate-wnd (leaf)
+  "Return the window for LEAF."
+  (if (consp leaf)
+      (cdr leaf)
+    (selected-window)))
+
+(defun avy--overlay-pre (path leaf)
+  "Create an overlay with PATH at LEAF.
+PATH is a list of keys from tree root to LEAF.
+LEAF is normally ((BEG . END) . WND)."
+  (let* ((path (mapcar #'avy--key-to-char path))
+         (str (propertize (apply #'string (reverse path))
+                          'face 'avy-lead-face)))
+    (when (or avy-highlight-first (> (length str) 1))
+      (set-text-properties 0 1 '(face avy-lead-face-0) str))
+    (setq str (concat
+               (propertize avy-current-path
+                           'face 'avy-lead-face-1)
+               str))
+    (avy--overlay
+     str
+     (avy-candidate-beg leaf) nil
+     (avy-candidate-wnd leaf))))
+
+(defun avy--overlay-at (path leaf)
+  "Create an overlay with PATH at LEAF.
+PATH is a list of keys from tree root to LEAF.
+LEAF is normally ((BEG . END) . WND)."
+  (let* ((path (mapcar #'avy--key-to-char path))
+         (str (propertize
+               (string (car (last path)))
+               'face 'avy-lead-face)))
+    (avy--overlay
+     str
+     (avy-candidate-beg leaf) nil
+     (avy-candidate-wnd leaf)
+     (lambda (str old-str)
+       (cond ((string= old-str "\n")
+              (concat str "\n"))
+             ;; add padding for wide-width character
+             ((eq (string-width old-str) 2)
+              (concat str " "))
+             (t
+              str))))))
+
+(defun avy--overlay-at-full (path leaf)
+  "Create an overlay with PATH at LEAF.
+PATH is a list of keys from tree root to LEAF.
+LEAF is normally ((BEG . END) . WND)."
+  (let* ((path (mapcar #'avy--key-to-char path))
+         (str (propertize
+               (apply #'string (reverse path))
+               'face 'avy-lead-face))
+         (len (length path))
+         (beg (avy-candidate-beg leaf))
+         (wnd (cdr leaf))
+         end)
+    (dotimes (i len)
+      (set-text-properties (- len i 1) (- len i)
+                           `(face ,(nth i avy-lead-faces))
+                           str))
+    (when (eq avy-style 'de-bruijn)
+      (setq str (concat
+                 (propertize avy-current-path
+                             'face 'avy-lead-face-1)
+                 str))
+      (setq len (length str)))
+    (with-selected-window wnd
+      (save-excursion
+        (goto-char beg)
+        (let* ((lep (if (bound-and-true-p visual-line-mode)
+                        (save-excursion
+                          (end-of-visual-line)
+                          (point))
+                      (line-end-position)))
+               ;; `end-of-visual-line' is bugged sometimes
+               (lep (if (< lep beg)
+                        (line-end-position)
+                      lep))
+               (len-and-str (avy--update-offset-and-str len str lep)))
+          (setq len (car len-and-str))
+          (setq str (cdr len-and-str))
+          (setq end (if (= beg lep)
+                        (1+ beg)
+                      (min (+ beg
+                              (if (eq (char-after) ?\t)
+                                  1
+                                len))
+                           lep)))
+          (when (and (bound-and-true-p visual-line-mode)
+                     (> len (- end beg))
+                     (not (eq lep beg)))
+            (setq len (- end beg))
+            (let ((old-str (apply #'string (reverse path))))
+              (setq str
+                    (substring
+                     (propertize
+                      old-str
+                      'face
+                      (if (= (length old-str) 1)
+                          'avy-lead-face
+                        'avy-lead-face-0))
+                     0 len)))))))
+    (avy--overlay
+     str beg end wnd
+     (lambda (str old-str)
+       (cond ((string= old-str "\n")
+              (concat str "\n"))
+             ((string= old-str "\t")
+              (concat str (make-string (max (- tab-width len) 0) ?\ )))
+             (t
+              ;; add padding for wide-width character
+              (if (eq (string-width old-str) 2)
+                  (concat str " ")
+                str)))))))
+
+(defun avy--overlay-post (path leaf)
+  "Create an overlay with PATH at LEAF.
+PATH is a list of keys from tree root to LEAF.
+LEAF is normally ((BEG . END) . WND)."
+  (let* ((path (mapcar #'avy--key-to-char path))
+         (str (propertize (apply #'string (reverse path))
+                          'face 'avy-lead-face)))
+    (when (or avy-highlight-first (> (length str) 1))
+      (set-text-properties 0 1 '(face avy-lead-face-0) str))
+    (setq str (concat
+               (propertize avy-current-path
+                           'face 'avy-lead-face-1)
+               str))
+    (avy--overlay
+     str
+     (avy-candidate-end leaf) nil
+     (avy-candidate-wnd leaf))))
+
+(defun avy--update-offset-and-str (offset str lep)
+  "Recalculate the length of the new overlay at point.
+
+OFFSET is the previous overlay length.
+STR is the overlay string that we wish to add.
+LEP is the line end position.
+
+We want to add an overlay between point and END=point+OFFSET.
+When other overlays already exist between point and END, set
+OFFSET to be the difference between the start of the first
+overlay and point.  This is equivalent to truncating our new
+overlay, so that it doesn't intersect with overlays that already
+exist."
+  (let* ((wnd (selected-window))
+         (beg (point))
+         (oov (delq nil
+                    (mapcar
+                     (lambda (o)
+                       (and (eq (overlay-get o 'category) 'avy)
+                            (eq (overlay-get o 'window) wnd)
+                            (overlay-start o)))
+                     (overlays-in beg (min (+ beg offset) lep))))))
+    (when oov
+      (setq offset (- (apply #'min oov) beg))
+      (setq str (substring str 0 offset)))
+    (let ((other-ov (cl-find-if
+                     (lambda (o)
+                       (and (eq (overlay-get o 'category) 'avy)
+                            (eq (overlay-start o) beg)
+                            (not (eq (overlay-get o 'window) wnd))))
+                     (overlays-in (point) (min (+ (point) offset) lep)))))
+      (when (and other-ov
+                 (> (overlay-end other-ov)
+                    (+ beg offset)))
+        (setq str (concat str (buffer-substring
+                               (+ beg offset)
+                               (overlay-end other-ov))))
+        (setq offset (- (overlay-end other-ov)
+                        beg))))
+    (cons offset str)))
+
+(defun avy--style-fn (style)
+  "Transform STYLE symbol to a style function."
+  (cl-case style
+    (pre #'avy--overlay-pre)
+    (at #'avy--overlay-at)
+    (at-full 'avy--overlay-at-full)
+    (post #'avy--overlay-post)
+    (de-bruijn #'avy--overlay-at-full)
+    (words #'avy--overlay-at-full)
+    (t (error "Unexpected style %S" style))))
+
+(defun avy--generic-jump (regex window-flip style &optional beg end)
+  "Jump to REGEX.
+The window scope is determined by `avy-all-windows'.
+When WINDOW-FLIP is non-nil, do the opposite of `avy-all-windows'.
+STYLE determines the leading char overlay style.
+BEG and END narrow the scope where candidates are searched."
+  (let ((avy-all-windows
+         (if window-flip
+             (not avy-all-windows)
+           avy-all-windows)))
+    (avy--process
+     (avy--regex-candidates regex beg end)
+     (avy--style-fn style))))
+
+;;* Commands
+;;;###autoload
+(defun avy-goto-char (char &optional arg)
+  "Jump to the currently visible CHAR.
+The window scope is determined by `avy-all-windows' (ARG negates it)."
+  (interactive (list (read-char "char: " t)
+                     current-prefix-arg))
+  (avy-with avy-goto-char
+    (avy--generic-jump
+     (if (= 13 char)
+         "\n"
+       (regexp-quote (string char)))
+     arg
+     avy-style)))
+
+;;;###autoload
+(defun avy-goto-char-in-line (char)
+  "Jump to the currently visible CHAR in the current line."
+  (interactive (list (read-char "char: " t)))
+  (avy-with avy-goto-char
+    (avy--generic-jump
+     (regexp-quote (string char))
+     avy-all-windows
+     avy-style
+     (line-beginning-position)
+     (line-end-position))))
+
+;;;###autoload
+(defun avy-goto-char-2 (char1 char2 &optional arg beg end)
+  "Jump to the currently visible CHAR1 followed by CHAR2.
+The window scope is determined by `avy-all-windows'.
+When ARG is non-nil, do the opposite of `avy-all-windows'.
+BEG and END narrow the scope where candidates are searched."
+  (interactive (list (read-char "char 1: " t)
+                     (read-char "char 2: " t)
+                     current-prefix-arg
+                     nil nil))
+  (when (eq char1 ?
)
+    (setq char1 ?\n))
+  (when (eq char2 ?
)
+    (setq char2 ?\n))
+  (avy-with avy-goto-char-2
+    (avy--generic-jump
+     (regexp-quote (string char1 char2))
+     arg
+     avy-style
+     beg end)))
+
+;;;###autoload
+(defun avy-goto-char-2-above (char1 char2 &optional arg)
+  "Jump to the currently visible CHAR1 followed by CHAR2.
+This is a scoped version of `avy-goto-char-2', where the scope is
+the visible part of the current buffer up to point.
+The window scope is determined by `avy-all-windows'.
+When ARG is non-nil, do the opposite of `avy-all-windows'."
+  (interactive (list (read-char "char 1: " t)
+                     (read-char "char 2: " t)
+                     current-prefix-arg))
+  (avy-with avy-goto-char-2-above
+    (avy-goto-char-2
+     char1 char2 arg
+     (window-start) (point))))
+
+;;;###autoload
+(defun avy-goto-char-2-below (char1 char2 &optional arg)
+  "Jump to the currently visible CHAR1 followed by CHAR2.
+This is a scoped version of `avy-goto-char-2', where the scope is
+the visible part of the current buffer following point.
+The window scope is determined by `avy-all-windows'.
+When ARG is non-nil, do the opposite of `avy-all-windows'."
+  (interactive (list (read-char "char 1: " t)
+                     (read-char "char 2: " t)
+                     current-prefix-arg))
+  (avy-with avy-goto-char-2-below
+    (avy-goto-char-2
+     char1 char2 arg
+     (point) (window-end (selected-window) t))))
+
+;;;###autoload
+(defun avy-isearch ()
+  "Jump to one of the current isearch candidates."
+  (interactive)
+  (avy-with avy-isearch
+    (let ((avy-background nil))
+      (avy--process
+       (avy--regex-candidates (if isearch-regexp
+                                  isearch-string
+                                (regexp-quote isearch-string)))
+       (avy--style-fn avy-style))
+      (isearch-done))))
+
+;;;###autoload
+(defun avy-goto-word-0 (arg &optional beg end)
+  "Jump to a word start.
+The window scope is determined by `avy-all-windows'.
+When ARG is non-nil, do the opposite of `avy-all-windows'.
+BEG and END narrow the scope where candidates are searched."
+  (interactive "P")
+  (avy-with avy-goto-word-0
+    (avy--generic-jump avy-goto-word-0-regexp arg avy-style beg end)))
+
+(defun avy-goto-word-0-above (arg)
+  "Jump to a word start between window start and point.
+The window scope is determined by `avy-all-windows'.
+When ARG is non-nil, do the opposite of `avy-all-windows'."
+  (interactive "P")
+  (avy-with avy-goto-word-0
+    (avy-goto-word-0 arg (window-start) (point))))
+
+(defun avy-goto-word-0-below (arg)
+  "Jump to a word start between point and window end.
+The window scope is determined by `avy-all-windows'.
+When ARG is non-nil, do the opposite of `avy-all-windows'."
+  (interactive "P")
+  (avy-with avy-goto-word-0
+    (avy-goto-word-0 arg (point) (window-end (selected-window) t))))
+
+;;;###autoload
+(defun avy-goto-word-1 (char &optional arg beg end symbol)
+  "Jump to the currently visible CHAR at a word start.
+The window scope is determined by `avy-all-windows'.
+When ARG is non-nil, do the opposite of `avy-all-windows'.
+BEG and END narrow the scope where candidates are searched.
+When SYMBOL is non-nil, jump to symbol start instead of word start."
+  (interactive (list (read-char "char: " t)
+                     current-prefix-arg))
+  (avy-with avy-goto-word-1
+    (let* ((str (string char))
+           (regex (cond ((string= str ".")
+                         "\\.")
+                        ((and avy-word-punc-regexp
+                              (string-match avy-word-punc-regexp str))
+                         (regexp-quote str))
+                        ((<= char 26)
+                         str)
+                        (t
+                         (concat
+                          (if symbol "\\_<" "\\b")
+                          str)))))
+      (avy--generic-jump regex arg avy-style beg end))))
+
+;;;###autoload
+(defun avy-goto-word-1-above (char &optional arg)
+  "Jump to the currently visible CHAR at a word start.
+This is a scoped version of `avy-goto-word-1', where the scope is
+the visible part of the current buffer up to point.
+The window scope is determined by `avy-all-windows'.
+When ARG is non-nil, do the opposite of `avy-all-windows'."
+  (interactive (list (read-char "char: " t)
+                     current-prefix-arg))
+  (avy-with avy-goto-word-1
+    (avy-goto-word-1 char arg (window-start) (point))))
+
+;;;###autoload
+(defun avy-goto-word-1-below (char &optional arg)
+  "Jump to the currently visible CHAR at a word start.
+This is a scoped version of `avy-goto-word-1', where the scope is
+the visible part of the current buffer following point.
+The window scope is determined by `avy-all-windows'.
+When ARG is non-nil, do the opposite of `avy-all-windows'."
+  (interactive (list (read-char "char: " t)
+                     current-prefix-arg))
+  (avy-with avy-goto-word-1
+    (avy-goto-word-1 char arg (point) (window-end (selected-window) t))))
+
+;;;###autoload
+(defun avy-goto-symbol-1 (char &optional arg)
+  "Jump to the currently visible CHAR at a symbol start.
+The window scope is determined by `avy-all-windows'.
+When ARG is non-nil, do the opposite of `avy-all-windows'."
+  (interactive (list (read-char "char: " t)
+                     current-prefix-arg))
+  (avy-with avy-goto-symbol-1
+    (avy-goto-word-1 char arg nil nil t)))
+
+;;;###autoload
+(defun avy-goto-symbol-1-above (char &optional arg)
+  "Jump to the currently visible CHAR at a symbol start.
+This is a scoped version of `avy-goto-symbol-1', where the scope is
+the visible part of the current buffer up to point.
+The window scope is determined by `avy-all-windows'.
+When ARG is non-nil, do the opposite of `avy-all-windows'."
+  (interactive (list (read-char "char: " t)
+                     current-prefix-arg))
+  (avy-with avy-goto-symbol-1-above
+    (avy-goto-word-1 char arg (window-start) (point) t)))
+
+;;;###autoload
+(defun avy-goto-symbol-1-below (char &optional arg)
+  "Jump to the currently visible CHAR at a symbol start.
+This is a scoped version of `avy-goto-symbol-1', where the scope is
+the visible part of the current buffer following point.
+The window scope is determined by `avy-all-windows'.
+When ARG is non-nil, do the opposite of `avy-all-windows'."
+  (interactive (list (read-char "char: " t)
+                     current-prefix-arg))
+  (avy-with avy-goto-symbol-1-below
+    (avy-goto-word-1 char arg (point) (window-end (selected-window) t) t)))
+
+(declare-function subword-backward "subword")
+(defvar subword-backward-regexp)
+
+(defcustom avy-subword-extra-word-chars '(?{ ?= ?} ?* ?: ?> ?<)
+  "A list of characters that should temporarily match \"\\w\".
+This variable is used by `avy-goto-subword-0' and `avy-goto-subword-1'."
+  :type '(repeat character))
+
+;;;###autoload
+(defun avy-goto-subword-0 (&optional arg predicate beg end)
+  "Jump to a word or subword start.
+The window scope is determined by `avy-all-windows' (ARG negates it).
+
+When PREDICATE is non-nil it's a function of zero parameters that
+should return true.
+
+BEG and END narrow the scope where candidates are searched."
+  (interactive "P")
+  (require 'subword)
+  (avy-with avy-goto-subword-0
+    (let ((case-fold-search nil)
+          (subword-backward-regexp
+           "\\(\\(\\W\\|[[:lower:][:digit:]]\\)\\([!-/:@`~[:upper:]]+\\W*\\)\\|\\W\\w+\\)")
+          candidates)
+      (avy-dowindows arg
+        (let ((syn-tbl (copy-syntax-table)))
+          (dolist (char avy-subword-extra-word-chars)
+            (modify-syntax-entry char "w" syn-tbl))
+          (with-syntax-table syn-tbl
+            (let ((ws (or beg (window-start)))
+                  window-cands)
+              (save-excursion
+                (goto-char (or end (window-end (selected-window) t)))
+                (subword-backward)
+                (while (> (point) ws)
+                  (when (or (null predicate)
+                            (and predicate (funcall predicate)))
+                    (unless (get-char-property (point) 'invisible)
+                      (push (cons (point) (selected-window)) window-cands)))
+                  (subword-backward))
+                (and (= (point) ws)
+                     (or (null predicate)
+                         (and predicate (funcall predicate)))
+                     (not (get-char-property (point) 'invisible))
+                     (push (cons (point) (selected-window)) window-cands)))
+              (setq candidates (nconc candidates window-cands))))))
+      (avy--process candidates (avy--style-fn avy-style)))))
+
+;;;###autoload
+(defun avy-goto-subword-1 (char &optional arg)
+  "Jump to the currently visible CHAR at a subword start.
+The window scope is determined by `avy-all-windows' (ARG negates it).
+The case of CHAR is ignored."
+  (interactive (list (read-char "char: " t)
+                     current-prefix-arg))
+  (avy-with avy-goto-subword-1
+    (let ((char (downcase char)))
+      (avy-goto-subword-0
+       arg (lambda ()
+             (and (char-after)
+                  (eq (downcase (char-after)) char)))))))
+
+;;;###autoload
+(defun avy-goto-word-or-subword-1 ()
+  "Forward to `avy-goto-subword-1' or `avy-goto-word-1'.
+Which one depends on variable `subword-mode'."
+  (interactive)
+  (if (bound-and-true-p subword-mode)
+      (call-interactively #'avy-goto-subword-1)
+    (call-interactively #'avy-goto-word-1)))
+
+(defvar visual-line-mode)
+
+(defun avy--line-cands (&optional arg beg end bottom-up)
+  "Get candidates for selecting a line.
+The window scope is determined by `avy-all-windows'.
+When ARG is non-nil, do the opposite of `avy-all-windows'.
+BEG and END narrow the scope where candidates are searched.
+When BOTTOM-UP is non-nil, display avy candidates from top to bottom"
+  (let (candidates)
+    (avy-dowindows arg
+      (let ((ws (or beg (window-start))))
+        (save-excursion
+          (save-restriction
+            (narrow-to-region ws (or end (window-end (selected-window) t)))
+            (goto-char (point-min))
+            (while (< (point) (point-max))
+              (unless (get-char-property
+                       (max (1- (point)) ws) 'invisible)
+                (push (cons
+                       (if (eq avy-style 'post)
+                           (line-end-position)
+                         (point))
+                       (selected-window)) candidates))
+              (if visual-line-mode
+                  (progn
+                    (setq temporary-goal-column 0)
+                    (line-move-visual 1 t))
+                (forward-line 1)))))))
+    (if bottom-up
+        candidates
+      (nreverse candidates))))
+
+(defun avy--linum-strings ()
+  "Get strings for `avy-linum-mode'."
+  (let* ((lines (mapcar #'car (avy--line-cands)))
+         (line-tree (avy-tree lines avy-keys))
+         (line-list nil))
+    (avy-traverse
+     line-tree
+     (lambda (path _leaf)
+       (let ((str (propertize (apply #'string (reverse path))
+                              'face 'avy-lead-face)))
+         (when (> (length str) 1)
+           (set-text-properties 0 1 '(face avy-lead-face-0) str))
+         (push str line-list))))
+    (nreverse line-list)))
+
+(defvar linum-available)
+(defvar linum-overlays)
+(defvar linum-format)
+(declare-function linum--face-width "linum")
+
+(define-minor-mode avy-linum-mode
+  "Minor mode that uses avy hints for `linum-mode'."
+  :group 'avy
+  (if avy-linum-mode
+      (progn
+        (require 'linum)
+        (advice-add 'linum-update-window :around 'avy--linum-update-window)
+        (linum-mode 1))
+    (advice-remove 'linum-update-window 'avy--linum-update-window)
+    (linum-mode -1)))
+
+(defun avy--linum-update-window (_ win)
+  "Update line numbers for the portion visible in window WIN."
+  (goto-char (window-start win))
+  (let ((line (line-number-at-pos))
+        (limit (window-end win t))
+        (fmt (cond ((stringp linum-format) linum-format)
+                   ((eq linum-format 'dynamic)
+                    (let ((w (length (number-to-string
+                                      (count-lines (point-min) (point-max))))))
+                      (concat "%" (number-to-string w) "d")))))
+        (width 0)
+        (avy-strs (when avy-linum-mode
+                    (avy--linum-strings))))
+    (run-hooks 'linum-before-numbering-hook)
+    ;; Create an overlay (or reuse an existing one) for each
+    ;; line visible in this window, if necessary.
+    (while (and (not (eobp)) (< (point) limit))
+      (let* ((str
+              (cond (avy-linum-mode
+                     (pop avy-strs))
+                    (fmt
+                     (propertize (format fmt line) 'face 'linum))
+                    (t
+                     (funcall linum-format line))))
+             (visited (catch 'visited
+                        (dolist (o (overlays-in (point) (point)))
+                          (when (equal-including-properties
+                                 (overlay-get o 'linum-str) str)
+                            (unless (memq o linum-overlays)
+                              (push o linum-overlays))
+                            (setq linum-available (delq o linum-available))
+                            (throw 'visited t))))))
+        (setq width (max width (length str)))
+        (unless visited
+          (let ((ov (if (null linum-available)
+                        (make-overlay (point) (point))
+                      (move-overlay (pop linum-available) (point) (point)))))
+            (push ov linum-overlays)
+            (overlay-put ov 'before-string
+                         (propertize " " 'display `((margin left-margin) ,str)))
+            (overlay-put ov 'linum-str str))))
+      ;; Text may contain those nasty intangible properties, but that
+      ;; shouldn't prevent us from counting those lines.
+      (let ((inhibit-point-motion-hooks t))
+        (forward-line))
+      (setq line (1+ line)))
+    (when (display-graphic-p)
+      (setq width (ceiling
+                   (/ (* width 1.0 (linum--face-width 'linum))
+                      (frame-char-width)))))
+    (set-window-margins win width (cdr (window-margins win)))))
+
+(defun avy--line (&optional arg beg end bottom-up)
+  "Select a line.
+The window scope is determined by `avy-all-windows'.
+When ARG is non-nil, do the opposite of `avy-all-windows'.
+BEG and END narrow the scope where candidates are searched.
+When BOTTOM-UP is non-nil, display avy candidates from top to bottom"
+  (let ((avy-action #'identity))
+    (avy--process
+     (avy--line-cands arg beg end bottom-up)
+     (if avy-linum-mode
+         (progn (message "Goto line:")
+                'ignore)
+       (avy--style-fn avy-style)))))
+
+;;;###autoload
+(defun avy-goto-line (&optional arg)
+  "Jump to a line start in current buffer.
+
+When ARG is 1, jump to lines currently visible, with the option
+to cancel to `goto-line' by entering a number.
+
+When ARG is 4, negate the window scope determined by
+`avy-all-windows'.
+
+Otherwise, forward to `goto-line' with ARG."
+  (interactive "p")
+  (setq arg (or arg 1))
+  (if (not (memq arg '(1 4)))
+      (progn
+        (goto-char (point-min))
+        (forward-line (1- arg)))
+    (avy-with avy-goto-line
+      (let* ((avy-handler-old avy-handler-function)
+             (avy-handler-function
+              (lambda (char)
+                (if (or (< char ?0)
+                        (> char ?9))
+                    (funcall avy-handler-old char)
+                  (let ((line (read-from-minibuffer
+                               "Goto line: " (string char))))
+                    (when line
+                      (avy-push-mark)
+                      (save-restriction
+                        (widen)
+                        (goto-char (point-min))
+                        (forward-line (1- (string-to-number line))))
+                      (throw 'done 'exit))))))
+             (r (avy--line (eq arg 4))))
+        (unless (eq r t)
+          (avy-action-goto r))))))
+
+;;;###autoload
+(defun avy-goto-line-above (&optional offset bottom-up)
+  "Goto visible line above the cursor.
+OFFSET changes the distance between the closest key to the cursor and
+the cursor
+When BOTTOM-UP is non-nil, display avy candidates from top to bottom"
+  (interactive)
+  (if offset
+    (setq offset (+ 2 (- offset))))
+  (let* ((avy-all-windows nil)
+         (r (avy--line nil (window-start)
+                       (line-beginning-position (or offset 1))
+		       bottom-up)))
+    (unless (eq r t)
+      (avy-action-goto r))))
+
+;;;###autoload
+(defun avy-goto-line-below (&optional offset bottom-up)
+  "Goto visible line below the cursor.
+OFFSET changes the distance between the closest key to the cursor and
+the cursor
+When BOTTOM-UP is non-nil, display avy candidates from top to bottom"
+  (interactive)
+  (if offset
+    (setq offset (+ offset 1)))
+  (let* ((avy-all-windows nil)
+         (r (avy--line
+             nil (line-beginning-position (or offset 2))
+             (window-end (selected-window) t)
+	     bottom-up)))
+    (unless (eq r t)
+      (avy-action-goto r))))
+
+(defcustom avy-line-insert-style 'above
+  "How to insert the newly copied/cut line."
+  :type '(choice
+          (const :tag "Above" above)
+          (const :tag "Below" below)))
+
+;;;###autoload
+(defun avy-copy-line (arg)
+  "Copy a selected line above the current line.
+ARG lines can be used."
+  (interactive "p")
+  (let ((initial-window (selected-window)))
+    (avy-with avy-copy-line
+      (let* ((start (avy--line))
+             (str (buffer-substring-no-properties
+                   start
+                   (save-excursion
+                     (goto-char start)
+                     (move-end-of-line arg)
+                     (point)))))
+        (select-window initial-window)
+        (cond ((eq avy-line-insert-style 'above)
+               (beginning-of-line)
+               (save-excursion
+                 (insert str "\n")))
+              ((eq avy-line-insert-style 'below)
+               (end-of-line)
+               (insert "\n" str)
+               (beginning-of-line))
+              (t
+               (user-error "Unexpected `avy-line-insert-style'")))))))
+
+;;;###autoload
+(defun avy-move-line (arg)
+  "Move a selected line above the current line.
+ARG lines can be used."
+  (interactive "p")
+  (let ((initial-window (selected-window)))
+    (avy-with avy-move-line
+      (let ((start (avy--line)))
+        (save-excursion
+          (goto-char start)
+          (kill-whole-line arg))
+        (select-window initial-window)
+        (cond ((eq avy-line-insert-style 'above)
+               (beginning-of-line)
+               (save-excursion
+                 (insert
+                  (current-kill 0))))
+              ((eq avy-line-insert-style 'below)
+               (end-of-line)
+               (newline)
+               (save-excursion
+                 (insert (substring (current-kill 0) 0 -1))))
+              (t
+               (user-error "Unexpected `avy-line-insert-style'")))))))
+
+;;;###autoload
+(defun avy-copy-region (arg)
+  "Select two lines and copy the text between them to point.
+
+The window scope is determined by `avy-all-windows' or
+`avy-all-windows-alt' when ARG is non-nil."
+  (interactive "P")
+  (let ((initial-window (selected-window)))
+    (avy-with avy-copy-region
+      (let* ((beg (save-selected-window
+                    (avy--line arg)))
+             (end (avy--line arg))
+             (str (buffer-substring-no-properties
+                   beg
+                   (save-excursion
+                     (goto-char end)
+                     (line-end-position)))))
+        (select-window initial-window)
+        (cond ((eq avy-line-insert-style 'above)
+               (beginning-of-line)
+               (save-excursion
+                 (insert str "\n")))
+              ((eq avy-line-insert-style 'below)
+               (end-of-line)
+               (newline)
+               (save-excursion
+                 (insert str)))
+              (t
+               (user-error "Unexpected `avy-line-insert-style'")))))))
+
+;;;###autoload
+(defun avy-move-region ()
+  "Select two lines and move the text between them above the current line."
+  (interactive)
+  (avy-with avy-move-region
+    (let* ((initial-window (selected-window))
+           (beg (avy--line))
+           (end (avy--line))
+           text)
+      (when (> beg end)
+        (cl-rotatef beg end))
+      (setq end (save-excursion
+                  (goto-char end)
+                  (1+ (line-end-position))))
+      (setq text (buffer-substring beg end))
+      (move-beginning-of-line nil)
+      (delete-region beg end)
+      (select-window initial-window)
+      (insert text))))
+
+;;;###autoload
+(defun avy-kill-region (arg)
+  "Select two lines and kill the region between them.
+
+The window scope is determined by `avy-all-windows' or
+`avy-all-windows-alt' when ARG is non-nil."
+  (interactive "P")
+  (let ((initial-window (selected-window)))
+    (avy-with avy-kill-region
+      (let* ((beg (save-selected-window
+                    (list (avy--line arg) (selected-window))))
+             (end (list (avy--line arg) (selected-window))))
+        (cond
+          ((not (numberp (car beg)))
+           (user-error "Fail to select the beginning of region"))
+          ((not (numberp (car end)))
+           (user-error "Fail to select the end of region"))
+          ;; Restrict operation to same window. It's better if it can be
+          ;; different windows but same buffer; however, then the cloned
+          ;; buffers with different narrowed regions might cause problem.
+          ((not (equal (cdr beg) (cdr end)))
+           (user-error "Selected points are not in the same window"))
+          ((< (car beg) (car end))
+           (save-excursion
+             (kill-region
+              (car beg)
+              (progn (goto-char (car end)) (forward-visible-line 1) (point)))))
+          (t
+           (save-excursion
+             (kill-region
+              (progn (goto-char (car beg)) (forward-visible-line 1) (point))
+              (car end)))))))
+    (select-window initial-window)))
+
+;;;###autoload
+(defun avy-kill-ring-save-region (arg)
+  "Select two lines and save the region between them to the kill ring.
+The window scope is determined by `avy-all-windows'.
+When ARG is non-nil, do the opposite of `avy-all-windows'."
+  (interactive "P")
+  (let ((initial-window (selected-window)))
+    (avy-with avy-kill-ring-save-region
+      (let* ((beg (save-selected-window
+                    (list (avy--line arg) (selected-window))))
+             (end (list (avy--line arg) (selected-window))))
+        (cond
+          ((not (numberp (car beg)))
+           (user-error "Fail to select the beginning of region"))
+          ((not (numberp (car end)))
+           (user-error "Fail to select the end of region"))
+          ((not (equal (cdr beg) (cdr end)))
+           (user-error "Selected points are not in the same window"))
+          ((< (car beg) (car end))
+           (save-excursion
+             (kill-ring-save
+              (car beg)
+              (progn (goto-char (car end)) (forward-visible-line 1) (point)))))
+          (t
+           (save-excursion
+             (kill-ring-save
+              (progn (goto-char (car beg)) (forward-visible-line 1) (point))
+              (car end)))))))
+    (select-window initial-window)))
+
+;;;###autoload
+(defun avy-kill-whole-line (arg)
+  "Select line and kill the whole selected line.
+
+With a numerical prefix ARG, kill ARG line(s) starting from the
+selected line.  If ARG is negative, kill backward.
+
+If ARG is zero, kill the selected line but exclude the trailing
+newline.
+
+\\[universal-argument] 3 \\[avy-kil-whole-line] kill three lines
+starting from the selected line.  \\[universal-argument] -3
+
+\\[avy-kill-whole-line] kill three lines backward including the
+selected line."
+  (interactive "P")
+  (let ((initial-window (selected-window)))
+    (avy-with avy-kill-whole-line
+      (let* ((start (avy--line)))
+        (if (not (numberp start))
+            (user-error "Fail to select the line to kill")
+          (save-excursion (goto-char start)
+                          (kill-whole-line arg)))))
+    (select-window initial-window)))
+
+;;;###autoload
+(defun avy-kill-ring-save-whole-line (arg)
+  "Select line and save the whole selected line as if killed, but don’t kill it.
+
+This command is similar to `avy-kill-whole-line', except that it
+saves the line(s) as if killed, but does not kill it(them).
+
+With a numerical prefix ARG, kill ARG line(s) starting from the
+selected line.  If ARG is negative, kill backward.
+
+If ARG is zero, kill the selected line but exclude the trailing
+newline."
+  (interactive "P")
+  (let ((initial-window (selected-window)))
+    (avy-with avy-kill-ring-save-whole-line
+      (let* ((start (avy--line)))
+        (if (not (numberp start))
+            (user-error "Fail to select the line to kill")
+          (save-excursion
+            (let ((kill-read-only-ok t)
+                  (buffer-read-only t))
+              (goto-char start)
+              (kill-whole-line arg))))))
+    (select-window initial-window)))
+
+;;;###autoload
+(defun avy-setup-default ()
+  "Setup the default shortcuts."
+  (eval-after-load "isearch"
+    '(define-key isearch-mode-map (kbd "C-'") 'avy-isearch)))
+
+(defcustom avy-timeout-seconds 0.5
+  "How many seconds to wait for the second char."
+  :type 'float)
+
+(defcustom avy-enter-times-out t
+  "Whether enter exits avy-goto-char-timer early. If nil it matches newline"
+  :type 'boolean)
+
+(defun avy--read-candidates (&optional re-builder)
+  "Read as many chars as possible and return their occurrences.
+At least one char must be read, and then repeatedly one next char
+may be read if it is entered before `avy-timeout-seconds'.  `C-h'
+or `DEL' deletes the last char entered, and `RET' exits with the
+currently read string immediately instead of waiting for another
+char for `avy-timeout-seconds'.
+The format of the result is the same as that of `avy--regex-candidates'.
+This function obeys `avy-all-windows' setting.
+RE-BUILDER is a function that takes a string and returns a regex.
+When nil, `regexp-quote' is used.
+If a group is captured, the first group is highlighted.
+Otherwise, the whole regex is highlighted."
+  (let ((str "")
+        (re-builder (or re-builder #'regexp-quote))
+        char break overlays regex)
+    (unwind-protect
+         (progn
+           (while (and (not break)
+                       (setq char
+                             (read-char (format "char%s: "
+                                                (if (string= str "")
+                                                    str
+                                                  (format " (%s)" str)))
+                                        t
+                                        (and (not (string= str ""))
+                                             avy-timeout-seconds))))
+             ;; Unhighlight
+             (dolist (ov overlays)
+               (delete-overlay ov))
+             (setq overlays nil)
+             (cond
+               ;; Handle RET
+               ((= char 13)
+                (if avy-enter-times-out
+                    (setq break t)
+                  (setq str (concat str (list ?\n)))))
+               ;; Handle C-h, DEL
+               ((memq char '(8 127))
+                (let ((l (length str)))
+                  (when (>= l 1)
+                    (setq str (substring str 0 (1- l))))))
+               (t
+                (setq str (concat str (list char)))))
+             ;; Highlight
+             (when (>= (length str) 1)
+               (let ((case-fold-search
+                      (or avy-case-fold-search (string= str (downcase str))))
+                     found)
+                 (avy-dowindows current-prefix-arg
+                   (dolist (pair (avy--find-visible-regions
+                                  (window-start)
+                                  (window-end (selected-window) t)))
+                     (save-excursion
+                       (goto-char (car pair))
+                       (setq regex (funcall re-builder str))
+                       (while (re-search-forward regex (cdr pair) t)
+                         (unless (get-char-property (1- (point)) 'invisible)
+                           (let* ((idx (if (= (length (match-data)) 4) 1 0))
+                                  (ov (make-overlay
+                                       (match-beginning idx) (match-end idx))))
+                             (setq found t)
+                             (push ov overlays)
+                             (overlay-put
+                              ov 'window (selected-window))
+                             (overlay-put
+                              ov 'face 'avy-goto-char-timer-face)))))))
+                 ;; No matches at all, so there's surely a typo in the input.
+                 (unless found (beep)))))
+           (nreverse (mapcar (lambda (ov)
+                               (cons (cons (overlay-start ov)
+                                           (overlay-end ov))
+                                     (overlay-get ov 'window)))
+                             overlays)))
+      (dolist (ov overlays)
+        (delete-overlay ov)))))
+
+;;;###autoload
+(defun avy-goto-char-timer (&optional arg)
+  "Read one or many consecutive chars and jump to the first one.
+The window scope is determined by `avy-all-windows' (ARG negates it)."
+  (interactive "P")
+  (let ((avy-all-windows (if arg
+                             (not avy-all-windows)
+                           avy-all-windows)))
+    (avy-with avy-goto-char-timer
+      (avy--process
+       (avy--read-candidates)
+       (avy--style-fn avy-style)))))
+
+(defun avy-push-mark ()
+  "Store the current point and window."
+  (ring-insert avy-ring
+               (cons (point) (selected-window)))
+  (unless (region-active-p)
+    (push-mark)))
+
+(defun avy-pop-mark ()
+  "Jump back to the last location of `avy-push-mark'."
+  (interactive)
+  (let (res)
+    (condition-case nil
+        (progn
+          (while (not (window-live-p
+                       (cdr (setq res (ring-remove avy-ring 0))))))
+          (let* ((window (cdr res))
+                 (frame (window-frame window)))
+            (when (and (frame-live-p frame)
+                       (not (eq frame (selected-frame))))
+              (select-frame-set-input-focus frame))
+            (select-window window)
+            (goto-char (car res))))
+      (error
+       (set-mark-command 4)))))
+
+;; ** Org-mode
+(defvar org-reverse-note-order)
+(declare-function org-refile "org")
+(declare-function org-back-to-heading "org")
+
+(defun avy-org-refile-as-child ()
+  "Refile current heading as first child of heading selected with `avy.'"
+  ;; Inspired by `org-teleport': http://kitchingroup.cheme.cmu.edu/blog/2016/03/18/Org-teleport-headlines/
+  (interactive)
+  (let ((rfloc (save-excursion
+                 (let* ((org-reverse-note-order t)
+                        (pos (avy-with avy-goto-line
+                               (avy--generic-jump (rx bol (1+ "*") (1+ space))
+                                                  nil avy-style)
+                               (point)))
+                        (filename (buffer-file-name (or (buffer-base-buffer (current-buffer))
+                                                        (current-buffer)))))
+                   (list nil filename nil pos)))))
+    ;; org-refile must be called outside of the excursion
+    (org-refile nil nil rfloc)))
+
+(defun avy-org-goto-heading-timer (&optional arg)
+  "Read one or many characters and jump to matching Org headings.
+The window scope is determined by `avy-all-windows' (ARG negates it)."
+  (interactive "P")
+  (let ((avy-all-windows (if arg
+                             (not avy-all-windows)
+                           avy-all-windows)))
+    (avy-with avy-goto-char-timer
+      (avy--process
+       (avy--read-candidates
+        (lambda (input)
+          (format "^\\*+ .*\\(%s\\)" input)))
+       (avy--style-fn avy-style))
+      (org-back-to-heading))))
+
+(provide 'avy)
+
+;;; avy.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/avy-20180615.801/avy.elc b/configs/shared/emacs/.emacs.d/elpa/avy-20180615.801/avy.elc
new file mode 100644
index 0000000000..4972d2a2e7
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/avy-20180615.801/avy.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/bind-key-20180512.2130/bind-key-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/bind-key-20180512.2130/bind-key-autoloads.el
new file mode 100644
index 0000000000..7dfbdb7996
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/bind-key-20180512.2130/bind-key-autoloads.el
@@ -0,0 +1,79 @@
+;;; bind-key-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "bind-key" "bind-key.el" (23377 60538 663260
+;;;;;;  569000))
+;;; Generated autoloads from bind-key.el
+
+(autoload 'bind-key "bind-key" "\
+Bind KEY-NAME to COMMAND in KEYMAP (`global-map' if not passed).
+
+KEY-NAME may be a vector, in which case it is passed straight to
+`define-key'. Or it may be a string to be interpreted as
+spelled-out keystrokes, e.g., \"C-c C-z\". See documentation of
+`edmacro-mode' for details.
+
+COMMAND must be an interactive function or lambda form.
+
+KEYMAP, if present, should be a keymap and not a quoted symbol.
+For example:
+
+  (bind-key \"M-h\" #'some-interactive-function my-mode-map)
+
+If PREDICATE is non-nil, it is a form evaluated to determine when
+a key should be bound. It must return non-nil in such cases.
+Emacs can evaluate this form at any time that it does redisplay
+or operates on menu data structures, so you should write it so it
+can safely be called at any time.
+
+\(fn KEY-NAME COMMAND &optional KEYMAP PREDICATE)" nil t)
+
+(autoload 'unbind-key "bind-key" "\
+Unbind the given KEY-NAME, within the KEYMAP (if specified).
+See `bind-key' for more details.
+
+\(fn KEY-NAME &optional KEYMAP)" nil t)
+
+(autoload 'bind-key* "bind-key" "\
+Similar to `bind-key', but overrides any mode-specific bindings.
+
+\(fn KEY-NAME COMMAND &optional PREDICATE)" nil t)
+
+(autoload 'bind-keys "bind-key" "\
+Bind multiple keys at once.
+
+Accepts keyword arguments:
+:map MAP               - a keymap into which the keybindings should be
+                         added
+:prefix KEY            - prefix key for these bindings
+:prefix-map MAP        - name of the prefix map that should be created
+                         for these bindings
+:prefix-docstring STR  - docstring for the prefix-map variable
+:menu-name NAME        - optional menu string for prefix map
+:filter FORM           - optional form to determine when bindings apply
+
+The rest of the arguments are conses of keybinding string and a
+function symbol (unquoted).
+
+\(fn &rest ARGS)" nil t)
+
+(autoload 'bind-keys* "bind-key" "\
+
+
+\(fn &rest ARGS)" nil t)
+
+(autoload 'describe-personal-keybindings "bind-key" "\
+Display all the personal keybindings defined by `bind-key'.
+
+\(fn)" t nil)
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; bind-key-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/bind-key-20180512.2130/bind-key-pkg.el b/configs/shared/emacs/.emacs.d/elpa/bind-key-20180512.2130/bind-key-pkg.el
new file mode 100644
index 0000000000..ec18d3c642
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/bind-key-20180512.2130/bind-key-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "bind-key" "20180512.2130" "A simple way to manage personal keybindings" 'nil)
diff --git a/configs/shared/emacs/.emacs.d/elpa/bind-key-20180512.2130/bind-key.el b/configs/shared/emacs/.emacs.d/elpa/bind-key-20180512.2130/bind-key.el
new file mode 100644
index 0000000000..4c6cb64500
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/bind-key-20180512.2130/bind-key.el
@@ -0,0 +1,455 @@
+;;; bind-key.el --- A simple way to manage personal keybindings
+
+;; Copyright (c) 2012-2017 John Wiegley
+
+;; Author: John Wiegley <johnw@newartisans.com>
+;; Maintainer: John Wiegley <johnw@newartisans.com>
+;; Created: 16 Jun 2012
+;; Modified: 29 Nov 2017
+;; Version: 2.4
+;; Package-Version: 20180512.2130
+;; Keywords: keys keybinding config dotemacs
+;; URL: https://github.com/jwiegley/use-package
+
+;; This program 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, or (at
+;; your option) any later version.
+
+;; This program 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; see the file copying.  if not, write to the
+;; free software foundation, inc., 59 temple place - suite 330,
+;; boston, ma 02111-1307, usa.
+
+;;; Commentary:
+
+;; If you have lots of keybindings set in your .emacs file, it can be hard to
+;; know which ones you haven't set yet, and which may now be overriding some
+;; new default in a new emacs version.  This module aims to solve that
+;; problem.
+;;
+;; Bind keys as follows in your .emacs:
+;;
+;;   (require 'bind-key)
+;;
+;;   (bind-key "C-c x" 'my-ctrl-c-x-command)
+;;
+;; If the keybinding argument is a vector, it is passed straight to
+;; `define-key', so remapping a key with `[remap COMMAND]' works as
+;; expected:
+;;
+;;   (bind-key [remap original-ctrl-c-x-command] 'my-ctrl-c-x-command)
+;;
+;; If you want the keybinding to override all minor modes that may also bind
+;; the same key, use the `bind-key*' form:
+;;
+;;   (bind-key* "<C-return>" 'other-window)
+;;
+;; If you want to rebind a key only in a particular keymap, use:
+;;
+;;   (bind-key "C-c x" 'my-ctrl-c-x-command some-other-mode-map)
+;;
+;; To unbind a key within a keymap (for example, to stop your favorite major
+;; mode from changing a binding that you don't want to override everywhere),
+;; use `unbind-key':
+;;
+;;   (unbind-key "C-c x" some-other-mode-map)
+;;
+;; To bind multiple keys at once, or set up a prefix map, a `bind-keys' macro
+;; is provided.  It accepts keyword arguments, please see its documentation
+;; for a detailed description.
+;;
+;; To add keys into a specific map, use :map argument
+;;
+;;    (bind-keys :map dired-mode-map
+;;               ("o" . dired-omit-mode)
+;;               ("a" . some-custom-dired-function))
+;;
+;; To set up a prefix map, use `:prefix-map' and `:prefix' arguments (both are
+;; required)
+;;
+;;    (bind-keys :prefix-map my-customize-prefix-map
+;;               :prefix "C-c c"
+;;               ("f" . customize-face)
+;;               ("v" . customize-variable))
+;;
+;; You can combine all the keywords together.  Additionally,
+;; `:prefix-docstring' can be specified to set documentation of created
+;; `:prefix-map' variable.
+;;
+;; To bind multiple keys in a `bind-key*' way (to be sure that your bindings
+;; will not be overridden by other modes), you may use `bind-keys*' macro:
+;;
+;;    (bind-keys*
+;;     ("C-o" . other-window)
+;;     ("C-M-n" . forward-page)
+;;     ("C-M-p" . backward-page))
+;;
+;; After Emacs loads, you can see a summary of all your personal keybindings
+;; currently in effect with this command:
+;;
+;;   M-x describe-personal-keybindings
+;;
+;; This display will tell you if you've overriden a default keybinding, and
+;; what the default was.  Also, it will tell you if the key was rebound after
+;; your binding it with `bind-key', and what it was rebound it to.
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'easy-mmode)
+
+(defgroup bind-key nil
+  "A simple way to manage personal keybindings"
+  :group 'emacs)
+
+(defcustom bind-key-column-widths '(18 . 40)
+  "Width of columns in `describe-personal-keybindings'."
+  :type '(cons integer integer)
+  :group 'bind-key)
+
+(defcustom bind-key-segregation-regexp
+  "\\`\\(\\(C-[chx] \\|M-[gso] \\)\\([CM]-\\)?\\|.+-\\)"
+  "Regular expression used to divide key sets in the output from
+\\[describe-personal-keybindings]."
+  :type 'regexp
+  :group 'bind-key)
+
+(defcustom bind-key-describe-special-forms nil
+  "If non-nil, extract docstrings from lambdas, closures and keymaps if possible."
+  :type 'boolean
+  :group 'bind-key)
+
+;; Create override-global-mode to force key remappings
+
+(defvar override-global-map (make-keymap)
+  "override-global-mode keymap")
+
+(define-minor-mode override-global-mode
+  "A minor mode so that keymap settings override other modes."
+  t "")
+
+;; the keymaps in `emulation-mode-map-alists' take precedence over
+;; `minor-mode-map-alist'
+(add-to-list 'emulation-mode-map-alists
+             `((override-global-mode . ,override-global-map)))
+
+(defvar personal-keybindings nil
+  "List of bindings performed by `bind-key'.
+
+Elements have the form ((KEY . [MAP]) CMD ORIGINAL-CMD)")
+
+;;;###autoload
+(defmacro bind-key (key-name command &optional keymap predicate)
+  "Bind KEY-NAME to COMMAND in KEYMAP (`global-map' if not passed).
+
+KEY-NAME may be a vector, in which case it is passed straight to
+`define-key'. Or it may be a string to be interpreted as
+spelled-out keystrokes, e.g., \"C-c C-z\". See documentation of
+`edmacro-mode' for details.
+
+COMMAND must be an interactive function or lambda form.
+
+KEYMAP, if present, should be a keymap and not a quoted symbol.
+For example:
+
+  (bind-key \"M-h\" #'some-interactive-function my-mode-map)
+
+If PREDICATE is non-nil, it is a form evaluated to determine when
+a key should be bound. It must return non-nil in such cases.
+Emacs can evaluate this form at any time that it does redisplay
+or operates on menu data structures, so you should write it so it
+can safely be called at any time."
+  (let ((namevar (make-symbol "name"))
+        (keyvar (make-symbol "key"))
+        (kdescvar (make-symbol "kdesc"))
+        (bindingvar (make-symbol "binding")))
+    `(let* ((,namevar ,key-name)
+            (,keyvar (if (vectorp ,namevar) ,namevar
+                       (read-kbd-macro ,namevar)))
+            (,kdescvar (cons (if (stringp ,namevar) ,namevar
+                               (key-description ,namevar))
+                             (quote ,keymap)))
+            (,bindingvar (lookup-key (or ,keymap global-map) ,keyvar)))
+       (let ((entry (assoc ,kdescvar personal-keybindings))
+             (details (list ,command
+                            (unless (numberp ,bindingvar)
+                              ,bindingvar))))
+         (if entry
+             (setcdr entry details)
+           (add-to-list 'personal-keybindings (cons ,kdescvar details))))
+       ,(if predicate
+            `(define-key (or ,keymap global-map) ,keyvar
+               '(menu-item "" nil :filter (lambda (&optional _)
+                                            (when ,predicate
+                                              ,command))))
+          `(define-key (or ,keymap global-map) ,keyvar ,command)))))
+
+;;;###autoload
+(defmacro unbind-key (key-name &optional keymap)
+  "Unbind the given KEY-NAME, within the KEYMAP (if specified).
+See `bind-key' for more details."
+  `(progn
+     (bind-key ,key-name nil ,keymap)
+     (setq personal-keybindings
+           (cl-delete-if #'(lambda (k)
+                             ,(if keymap
+                                  `(and (consp (car k))
+                                        (string= (caar k) ,key-name)
+                                        (eq (cdar k) ',keymap))
+                                `(and (stringp (car k))
+                                      (string= (car k) ,key-name))))
+                         personal-keybindings))))
+
+;;;###autoload
+(defmacro bind-key* (key-name command &optional predicate)
+  "Similar to `bind-key', but overrides any mode-specific bindings."
+  `(bind-key ,key-name ,command override-global-map ,predicate))
+
+(defun bind-keys-form (args keymap)
+  "Bind multiple keys at once.
+
+Accepts keyword arguments:
+:map MAP               - a keymap into which the keybindings should be
+                         added
+:prefix KEY            - prefix key for these bindings
+:prefix-map MAP        - name of the prefix map that should be created
+                         for these bindings
+:prefix-docstring STR  - docstring for the prefix-map variable
+:menu-name NAME        - optional menu string for prefix map
+:filter FORM           - optional form to determine when bindings apply
+
+The rest of the arguments are conses of keybinding string and a
+function symbol (unquoted)."
+  (let (map
+        doc
+        prefix-map
+        prefix
+        filter
+        menu-name
+        pkg)
+
+    ;; Process any initial keyword arguments
+    (let ((cont t))
+      (while (and cont args)
+        (if (cond ((and (eq :map (car args))
+                        (not prefix-map))
+                   (setq map (cadr args)))
+                  ((eq :prefix-docstring (car args))
+                   (setq doc (cadr args)))
+                  ((and (eq :prefix-map (car args))
+                        (not (memq map '(global-map
+                                         override-global-map))))
+                   (setq prefix-map (cadr args)))
+                  ((eq :prefix (car args))
+                   (setq prefix (cadr args)))
+                  ((eq :filter (car args))
+                   (setq filter (cadr args)) t)
+                  ((eq :menu-name (car args))
+                   (setq menu-name (cadr args)))
+                  ((eq :package (car args))
+                   (setq pkg (cadr args))))
+            (setq args (cddr args))
+          (setq cont nil))))
+
+    (when (or (and prefix-map (not prefix))
+              (and prefix (not prefix-map)))
+      (error "Both :prefix-map and :prefix must be supplied"))
+
+    (when (and menu-name (not prefix))
+      (error "If :menu-name is supplied, :prefix must be too"))
+
+    (unless map (setq map keymap))
+
+    ;; Process key binding arguments
+    (let (first next)
+      (while args
+        (if (keywordp (car args))
+            (progn
+              (setq next args)
+              (setq args nil))
+          (if first
+              (nconc first (list (car args)))
+            (setq first (list (car args))))
+          (setq args (cdr args))))
+
+      (cl-flet
+          ((wrap (map bindings)
+                 (if (and map pkg (not (memq map '(global-map
+                                                   override-global-map))))
+                     `((if (boundp ',map)
+                           ,(macroexp-progn bindings)
+                         (eval-after-load
+                             ,(if (symbolp pkg) `',pkg pkg)
+                           ',(macroexp-progn bindings))))
+                   bindings)))
+
+        (append
+         (when prefix-map
+           `((defvar ,prefix-map)
+             ,@(when doc `((put ',prefix-map 'variable-documentation ,doc)))
+             ,@(if menu-name
+                   `((define-prefix-command ',prefix-map nil ,menu-name))
+                 `((define-prefix-command ',prefix-map)))
+             ,@(if (and map (not (eq map 'global-map)))
+                   (wrap map `((bind-key ,prefix ',prefix-map ,map ,filter)))
+                 `((bind-key ,prefix ',prefix-map nil ,filter)))))
+         (wrap map
+               (cl-mapcan
+                (lambda (form)
+                  (let ((fun (and (cdr form) (list 'function (cdr form)))))
+                    (if prefix-map
+                        `((bind-key ,(car form) ,fun ,prefix-map ,filter))
+                      (if (and map (not (eq map 'global-map)))
+                          `((bind-key ,(car form) ,fun ,map ,filter))
+                        `((bind-key ,(car form) ,fun nil ,filter))))))
+                first))
+         (when next
+           (bind-keys-form (if pkg
+                               (cons :package (cons pkg next))
+                             next) map)))))))
+
+;;;###autoload
+(defmacro bind-keys (&rest args)
+  "Bind multiple keys at once.
+
+Accepts keyword arguments:
+:map MAP               - a keymap into which the keybindings should be
+                         added
+:prefix KEY            - prefix key for these bindings
+:prefix-map MAP        - name of the prefix map that should be created
+                         for these bindings
+:prefix-docstring STR  - docstring for the prefix-map variable
+:menu-name NAME        - optional menu string for prefix map
+:filter FORM           - optional form to determine when bindings apply
+
+The rest of the arguments are conses of keybinding string and a
+function symbol (unquoted)."
+  (macroexp-progn (bind-keys-form args nil)))
+
+;;;###autoload
+(defmacro bind-keys* (&rest args)
+  (macroexp-progn (bind-keys-form args 'override-global-map)))
+
+(defun get-binding-description (elem)
+  (cond
+   ((listp elem)
+    (cond
+     ((memq (car elem) '(lambda function))
+      (if (and bind-key-describe-special-forms
+               (stringp (nth 2 elem)))
+          (nth 2 elem)
+        "#<lambda>"))
+     ((eq 'closure (car elem))
+      (if (and bind-key-describe-special-forms
+               (stringp (nth 3 elem)))
+          (nth 3 elem)
+        "#<closure>"))
+     ((eq 'keymap (car elem))
+      "#<keymap>")
+     (t
+      elem)))
+   ;; must be a symbol, non-symbol keymap case covered above
+   ((and bind-key-describe-special-forms (keymapp elem))
+    (let ((doc (get elem 'variable-documentation)))
+      (if (stringp doc) doc elem)))
+   ((symbolp elem)
+    elem)
+   (t
+    "#<byte-compiled lambda>")))
+
+(defun compare-keybindings (l r)
+  (let* ((regex bind-key-segregation-regexp)
+         (lgroup (and (string-match regex (caar l))
+                      (match-string 0 (caar l))))
+         (rgroup (and (string-match regex (caar r))
+                      (match-string 0 (caar r))))
+         (lkeymap (cdar l))
+         (rkeymap (cdar r)))
+    (cond
+     ((and (null lkeymap) rkeymap)
+      (cons t t))
+     ((and lkeymap (null rkeymap))
+      (cons nil t))
+     ((and lkeymap rkeymap
+           (not (string= (symbol-name lkeymap) (symbol-name rkeymap))))
+      (cons (string< (symbol-name lkeymap) (symbol-name rkeymap)) t))
+     ((and (null lgroup) rgroup)
+      (cons t t))
+     ((and lgroup (null rgroup))
+      (cons nil t))
+     ((and lgroup rgroup)
+      (if (string= lgroup rgroup)
+          (cons (string< (caar l) (caar r)) nil)
+        (cons (string< lgroup rgroup) t)))
+     (t
+      (cons (string< (caar l) (caar r)) nil)))))
+
+;;;###autoload
+(defun describe-personal-keybindings ()
+  "Display all the personal keybindings defined by `bind-key'."
+  (interactive)
+  (with-output-to-temp-buffer "*Personal Keybindings*"
+    (princ (format (concat "Key name%s Command%s Comments\n%s %s "
+                           "---------------------\n")
+                   (make-string (- (car bind-key-column-widths) 9) ? )
+                   (make-string (- (cdr bind-key-column-widths) 8) ? )
+                   (make-string (1- (car bind-key-column-widths)) ?-)
+                   (make-string (1- (cdr bind-key-column-widths)) ?-)))
+    (let (last-binding)
+      (dolist (binding
+               (setq personal-keybindings
+                     (sort personal-keybindings
+                           (lambda (l r)
+                             (car (compare-keybindings l r))))))
+
+        (if (not (eq (cdar last-binding) (cdar binding)))
+            (princ (format "\n\n%s: %s\n%s\n\n"
+                           (cdar binding) (caar binding)
+                           (make-string (+ 21 (car bind-key-column-widths)
+                                           (cdr bind-key-column-widths)) ?-)))
+          (if (and last-binding
+                   (cdr (compare-keybindings last-binding binding)))
+              (princ "\n")))
+
+        (let* ((key-name (caar binding))
+               (at-present (lookup-key (or (symbol-value (cdar binding))
+                                           (current-global-map))
+                                       (read-kbd-macro key-name)))
+               (command (nth 1 binding))
+               (was-command (nth 2 binding))
+               (command-desc (get-binding-description command))
+               (was-command-desc (and was-command
+                                      (get-binding-description was-command)))
+               (at-present-desc (get-binding-description at-present))
+               )
+          (let ((line
+                 (format
+                  (format "%%-%ds%%-%ds%%s\n" (car bind-key-column-widths)
+                          (cdr bind-key-column-widths))
+                  key-name (format "`%s\'" command-desc)
+                  (if (string= command-desc at-present-desc)
+                      (if (or (null was-command)
+                              (string= command-desc was-command-desc))
+                          ""
+                        (format "was `%s\'" was-command-desc))
+                    (format "[now: `%s\']" at-present)))))
+            (princ (if (string-match "[ \t]+\n" line)
+                       (replace-match "\n" t t line)
+                     line))))
+
+        (setq last-binding binding)))))
+
+(provide 'bind-key)
+
+;; Local Variables:
+;; outline-regexp: ";;;\\(;* [^\s\t\n]\\|###autoload\\)\\|("
+;; indent-tabs-mode: nil
+;; End:
+
+;;; bind-key.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/bind-key-20180512.2130/bind-key.elc b/configs/shared/emacs/.emacs.d/elpa/bind-key-20180512.2130/bind-key.elc
new file mode 100644
index 0000000000..24910ba7b7
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/bind-key-20180512.2130/bind-key.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-apropos.el b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-apropos.el
new file mode 100644
index 0000000000..97be9aa62a
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-apropos.el
@@ -0,0 +1,208 @@
+;;; cider-apropos.el --- Apropos functionality for Clojure -*- lexical-binding: t -*-
+
+;; Copyright © 2014-2018 Jeff Valk, Bozhidar Batsov and CIDER contributors
+;;
+;; Author: Jeff Valk <jv@jeffvalk.com>
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;; This file is not part of GNU Emacs.
+
+;;; Commentary:
+
+;; Apropos functionality for Clojure.
+
+;;; Code:
+
+(require 'cider-doc)
+(require 'cider-util)
+(require 'subr-x)
+(require 'cider-compat)
+
+(require 'cider-client)
+(require 'cider-popup)
+(require 'nrepl-dict)
+
+(require 'clojure-mode)
+(require 'apropos)
+(require 'button)
+
+(defconst cider-apropos-buffer "*cider-apropos*")
+
+(defcustom cider-apropos-actions '(("display-doc" . cider-doc-lookup)
+                                   ("find-def" . cider--find-var)
+                                   ("lookup-on-grimoire" . cider-grimoire-lookup))
+  "Controls the actions to be applied on the symbol found by an apropos search.
+The first action key in the list will be selected as default.  If the list
+contains only one action key, the associated action function will be
+applied automatically.  An action function can be any function that receives
+the symbol found by the apropos search as argument."
+  :type '(alist :key-type string :value-type function)
+  :group 'cider
+  :package-version '(cider . "0.13.0"))
+
+(define-button-type 'apropos-special-form
+  'apropos-label "Special form"
+  'apropos-short-label "s"
+  'face 'font-lock-keyword-face
+  'help-echo "mouse-2, RET: Display more help on this special form"
+  'follow-link t
+  'action (lambda (button)
+            (describe-function (button-get button 'apropos-symbol))))
+
+(defun cider-apropos-doc (button)
+  "Display documentation for the symbol represented at BUTTON."
+  (cider-doc-lookup (button-get button 'apropos-symbol)))
+
+(defun cider-apropos-summary (query ns docs-p include-private-p case-sensitive-p)
+  "Return a short description for the performed apropos search.
+
+QUERY can be a regular expression list of space-separated words
+\(e.g take while) which will be converted to a regular expression
+\(like take.+while) automatically behind the scenes.  The search may be
+limited to the namespace NS, and may optionally search doc strings
+\(based on DOCS-P), include private vars (based on INCLUDE-PRIVATE-P),
+and be case-sensitive (based on CASE-SENSITIVE-P)."
+  (concat (if case-sensitive-p "Case-sensitive " "")
+          (if docs-p "Documentation " "")
+          (format "Apropos for %S" query)
+          (if ns (format " in namespace %S" ns) "")
+          (if include-private-p
+              " (public and private symbols)"
+            " (public symbols only)")))
+
+(defun cider-apropos-highlight (doc query)
+  "Return the DOC string propertized to highlight QUERY matches."
+  (let ((pos 0))
+    (while (string-match query doc pos)
+      (setq pos (match-end 0))
+      (put-text-property (match-beginning 0)
+                         (match-end 0)
+                         'font-lock-face apropos-match-face doc)))
+  doc)
+
+(defun cider-apropos-result (result query docs-p)
+  "Emit a RESULT matching QUERY into current buffer, formatted for DOCS-P."
+  (nrepl-dbind-response result (name type doc)
+    (let* ((label (capitalize (if (string= type "variable") "var" type)))
+           (help (concat "Display doc for this " (downcase label))))
+      (cider-propertize-region (list 'apropos-symbol name
+                                     'action 'cider-apropos-doc
+                                     'help-echo help)
+        (insert-text-button name 'type 'apropos-symbol)
+        (insert "\n  ")
+        (insert-text-button label 'type (intern (concat "apropos-" type)))
+        (insert ": ")
+        (let ((beg (point)))
+          (if docs-p
+              (insert (cider-apropos-highlight doc query) "\n")
+            (insert doc)
+            (fill-region beg (point))))
+        (insert "\n")))))
+
+(declare-function cider-mode "cider-mode")
+
+(defun cider-show-apropos (summary results query docs-p)
+  "Show SUMMARY and RESULTS for QUERY in a pop-up buffer, formatted for DOCS-P."
+  (with-current-buffer (cider-popup-buffer cider-apropos-buffer 'select 'apropos-mode 'ancillary)
+    (let ((inhibit-read-only t))
+      (if (boundp 'header-line-format)
+          (setq-local header-line-format summary)
+        (insert summary "\n\n"))
+      (dolist (result results)
+        (cider-apropos-result result query docs-p))
+      (goto-char (point-min)))))
+
+;;;###autoload
+(defun cider-apropos (query &optional ns docs-p privates-p case-sensitive-p)
+  "Show all symbols whose names match QUERY, a regular expression.
+QUERY can also be a list of space-separated words (e.g. take while) which
+will be converted to a regular expression (like take.+while) automatically
+behind the scenes.  The search may be limited to the namespace NS, and may
+optionally search doc strings (based on DOCS-P), include private vars
+\(based on PRIVATES-P), and be case-sensitive (based on CASE-SENSITIVE-P)."
+  (interactive
+   (cons (read-string "Search for Clojure symbol (a regular expression): ")
+         (when current-prefix-arg
+           (list (let ((ns (completing-read "Namespace (default is all): " (cider-sync-request:ns-list))))
+                   (if (string= ns "") nil ns))
+                 (y-or-n-p "Search doc strings? ")
+                 (y-or-n-p "Include private symbols? ")
+                 (y-or-n-p "Case-sensitive? ")))))
+  (cider-ensure-connected)
+  (cider-ensure-op-supported "apropos")
+  (if-let* ((summary (cider-apropos-summary
+                      query ns docs-p privates-p case-sensitive-p))
+            (results (cider-sync-request:apropos query ns docs-p privates-p case-sensitive-p)))
+      (cider-show-apropos summary results query docs-p)
+    (message "No apropos matches for %S" query)))
+
+;;;###autoload
+(defun cider-apropos-documentation ()
+  "Shortcut for (cider-apropos <query> nil t)."
+  (interactive)
+  (cider-ensure-connected)
+  (cider-ensure-op-supported "apropos")
+  (cider-apropos (read-string "Search for Clojure documentation (a regular expression): ") nil t))
+
+(defun cider-apropos-act-on-symbol (symbol)
+  "Apply selected action on SYMBOL."
+  (let* ((first-action-key (car (car cider-apropos-actions)))
+         (action-key (if (= 1 (length cider-apropos-actions))
+                         first-action-key
+                       (completing-read (format "Choose action to apply to `%s` (default %s): "
+                                                symbol first-action-key)
+                                        cider-apropos-actions nil nil nil nil first-action-key)))
+         (action-fn (cdr (assoc action-key cider-apropos-actions))))
+    (if action-fn
+        (funcall action-fn symbol)
+      (user-error "Unknown action `%s`" action-key))))
+
+;;;###autoload
+(defun cider-apropos-select (query &optional ns docs-p privates-p case-sensitive-p)
+  "Similar to `cider-apropos', but presents the results in a completing read.
+Show all symbols whose names match QUERY, a regular expression.
+QUERY can also be a list of space-separated words (e.g. take while) which
+will be converted to a regular expression (like take.+while) automatically
+behind the scenes.  The search may be limited to the namespace NS, and may
+optionally search doc strings (based on DOCS-P), include private vars
+\(based on PRIVATES-P), and be case-sensitive (based on CASE-SENSITIVE-P)."
+  (interactive
+   (cons (read-string "Search for Clojure symbol (a regular expression): ")
+         (when current-prefix-arg
+           (list (let ((ns (completing-read "Namespace (default is all): " (cider-sync-request:ns-list))))
+                   (if (string= ns "") nil ns))
+                 (y-or-n-p "Search doc strings? ")
+                 (y-or-n-p "Include private symbols? ")
+                 (y-or-n-p "Case-sensitive? ")))))
+  (cider-ensure-connected)
+  (cider-ensure-op-supported "apropos")
+  (if-let* ((summary (cider-apropos-summary
+                      query ns docs-p privates-p case-sensitive-p))
+            (results (mapcar (lambda (r) (nrepl-dict-get r "name"))
+                             (cider-sync-request:apropos query ns docs-p privates-p case-sensitive-p))))
+      (cider-apropos-act-on-symbol (completing-read (concat summary ": ") results))
+    (message "No apropos matches for %S" query)))
+
+;;;###autoload
+(defun cider-apropos-documentation-select ()
+  "Shortcut for (cider-apropos-select <query> nil t)."
+  (interactive)
+  (cider-ensure-connected)
+  (cider-ensure-op-supported "apropos")
+  (cider-apropos-select (read-string "Search for Clojure documentation (a regular expression): ") nil t))
+
+(provide 'cider-apropos)
+
+;;; cider-apropos.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-apropos.elc b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-apropos.elc
new file mode 100644
index 0000000000..1b2d8c643e
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-apropos.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-autoloads.el
new file mode 100644
index 0000000000..28df5fd632
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-autoloads.el
@@ -0,0 +1,607 @@
+;;; cider-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "cider" "cider.el" (23377 61664 804060 975000))
+;;; Generated autoloads from cider.el
+
+(autoload 'cider-version "cider" "\
+Display CIDER's version.
+
+\(fn)" t nil)
+
+(autoload 'cider-jack-in-clj "cider" "\
+Start an nREPL server for the current project and connect to it.
+PARAMS is a plist optionally containing :project-dir and :jack-in-cmd.
+With the prefix argument, prompt for all these parameters.
+
+\(fn PARAMS)" t nil)
+
+(autoload 'cider-jack-in-cljs "cider" "\
+Start an nREPL server for the current project and connect to it.
+PARAMS is a plist optionally containing :project-dir, :jack-in-cmd and
+:cljs-repl-type (e.g. Node, Figwheel, etc).  With the prefix argument,
+prompt for all these parameters.
+
+\(fn PARAMS)" t nil)
+
+(autoload 'cider-jack-in-clj&cljs "cider" "\
+Start an nREPL server and connect with clj and cljs REPLs.
+PARAMS is a plist optionally containing :project-dir, :jack-in-cmd and
+:cljs-repl-type (e.g. Node, Figwheel, etc).  With the prefix argument,
+prompt for all these parameters.  When SOFT-CLJS-START is non-nil, start
+cljs REPL only when the ClojureScript dependencies are met.
+
+\(fn &optional PARAMS SOFT-CLJS-START)" t nil)
+
+(autoload 'cider-connect-sibling-clj "cider" "\
+Create a Clojure REPL with the same server as OTHER-REPL.
+PARAMS is for consistency with other connection commands and is currently
+ignored.  OTHER-REPL defaults to `cider-current-repl' and in programs can
+also be a server buffer, in which case a new session with a REPL for that
+server is created.
+
+\(fn PARAMS &optional OTHER-REPL)" t nil)
+
+(autoload 'cider-connect-sibling-cljs "cider" "\
+Create a ClojureScript REPL with the same server as OTHER-REPL.
+PARAMS is a plist optionally containing :cljs-repl-type (e.g. Node,
+Figwheel, etc).  All other parameters are inferred from the OTHER-REPL.
+OTHER-REPL defaults to `cider-current-repl' but in programs can also be a
+server buffer, in which case a new session for that server is created.
+
+\(fn PARAMS &optional OTHER-REPL)" t nil)
+
+(autoload 'cider-connect-clj "cider" "\
+Initialize a CLJ connection to an nREPL server.
+PARAMS is a plist optionally containing :host, :port and :project-dir.  On
+prefix argument, prompt for all the parameters.
+
+\(fn &optional PARAMS)" t nil)
+
+(autoload 'cider-connect-cljs "cider" "\
+Initialize a CLJS connection to an nREPL server.
+PARAMS is a plist optionally containing :host, :port, :project-dir and
+:cljs-repl-type (e.g. Node, Figwheel, etc).  On prefix, prompt for all the
+parameters regardless of their supplied or default values.
+
+\(fn &optional PARAMS)" t nil)
+
+(autoload 'cider-connect-clj&cljs "cider" "\
+Initialize a CLJ and CLJS connection to an nREPL server..
+PARAMS is a plist optionally containing :host, :port, :project-dir and
+:cljs-repl-type (e.g. Node, Figwheel, etc).  When SOFT-CLJS-START is
+non-nil, don't start if ClojureScript requirements are not met.
+
+\(fn PARAMS &optional SOFT-CLJS-START)" t nil)
+
+(autoload 'cider "cider" "\
+Start a connection of any type interactively.
+
+\(fn)" t nil)
+
+(defalias 'cider-jack-in #'cider-jack-in-clj)
+
+(defalias 'cider-jack-in-clojure #'cider-jack-in-clj)
+
+(defalias 'cider-jack-in-clojurescript #'cider-jack-in-cljs)
+
+(defalias 'cider-connect #'cider-connect-clj)
+
+(defalias 'cider-connect-clojure #'cider-connect-clj)
+
+(defalias 'cider-connect-clojurescript #'cider-connect-cljs)
+
+(defalias 'cider-connect-sibling-clojure #'cider-connect-sibling-clj)
+
+(defalias 'cider-connect-sibling-clojurescript #'cider-connect-sibling-cljs)
+
+(eval-after-load 'clojure-mode '(progn (define-key clojure-mode-map (kbd "C-c M-x") #'cider) (define-key clojure-mode-map (kbd "C-c M-j") #'cider-jack-in-clj) (define-key clojure-mode-map (kbd "C-c M-J") #'cider-jack-in-cljs) (define-key clojure-mode-map (kbd "C-c M-c") #'cider-connect-clj) (define-key clojure-mode-map (kbd "C-c M-C") #'cider-connect-cljs) (define-key clojure-mode-map (kbd "C-c C-x") 'cider-start-map) (define-key clojure-mode-map (kbd "C-c C-s") 'sesman-map) (require 'sesman) (sesman-install-menu clojure-mode-map) (add-hook 'clojure-mode-hook (lambda nil (setq-local sesman-system 'CIDER)))))
+
+;;;***
+
+;;;### (autoloads nil "cider-apropos" "cider-apropos.el" (23377 61664
+;;;;;;  770864 524000))
+;;; Generated autoloads from cider-apropos.el
+
+(autoload 'cider-apropos "cider-apropos" "\
+Show all symbols whose names match QUERY, a regular expression.
+QUERY can also be a list of space-separated words (e.g. take while) which
+will be converted to a regular expression (like take.+while) automatically
+behind the scenes.  The search may be limited to the namespace NS, and may
+optionally search doc strings (based on DOCS-P), include private vars
+\(based on PRIVATES-P), and be case-sensitive (based on CASE-SENSITIVE-P).
+
+\(fn QUERY &optional NS DOCS-P PRIVATES-P CASE-SENSITIVE-P)" t nil)
+
+(autoload 'cider-apropos-documentation "cider-apropos" "\
+Shortcut for (cider-apropos <query> nil t).
+
+\(fn)" t nil)
+
+(autoload 'cider-apropos-select "cider-apropos" "\
+Similar to `cider-apropos', but presents the results in a completing read.
+Show all symbols whose names match QUERY, a regular expression.
+QUERY can also be a list of space-separated words (e.g. take while) which
+will be converted to a regular expression (like take.+while) automatically
+behind the scenes.  The search may be limited to the namespace NS, and may
+optionally search doc strings (based on DOCS-P), include private vars
+\(based on PRIVATES-P), and be case-sensitive (based on CASE-SENSITIVE-P).
+
+\(fn QUERY &optional NS DOCS-P PRIVATES-P CASE-SENSITIVE-P)" t nil)
+
+(autoload 'cider-apropos-documentation-select "cider-apropos" "\
+Shortcut for (cider-apropos-select <query> nil t).
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "cider-browse-ns" "cider-browse-ns.el" (23377
+;;;;;;  61664 768380 279000))
+;;; Generated autoloads from cider-browse-ns.el
+
+(autoload 'cider-browse-ns "cider-browse-ns" "\
+List all NAMESPACE's vars in BUFFER.
+
+\(fn NAMESPACE)" t nil)
+
+(autoload 'cider-browse-ns-all "cider-browse-ns" "\
+List all loaded namespaces in BUFFER.
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "cider-browse-spec" "cider-browse-spec.el"
+;;;;;;  (23377 61664 797512 30000))
+;;; Generated autoloads from cider-browse-spec.el
+
+(autoload 'cider-browse-spec "cider-browse-spec" "\
+Browse SPEC definition.
+
+\(fn SPEC)" t nil)
+
+(autoload 'cider-browse-spec-all "cider-browse-spec" "\
+Open list of specs in a popup buffer.
+
+With a prefix argument ARG, prompts for a regexp to filter specs.
+No filter applied if the regexp is the empty string.
+
+\(fn &optional ARG)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "cider-cheatsheet" "cider-cheatsheet.el" (23377
+;;;;;;  61664 799996 355000))
+;;; Generated autoloads from cider-cheatsheet.el
+
+(autoload 'cider-cheatsheet "cider-cheatsheet" "\
+Navigate `cider-cheatsheet-hierarchy' with `completing-read'.
+
+When you make it to a Clojure var its doc buffer gets displayed.
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "cider-classpath" "cider-classpath.el" (23377
+;;;;;;  61664 806586 783000))
+;;; Generated autoloads from cider-classpath.el
+
+(autoload 'cider-classpath "cider-classpath" "\
+List all classpath entries.
+
+\(fn)" t nil)
+
+(autoload 'cider-open-classpath-entry "cider-classpath" "\
+Open a classpath entry.
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "cider-debug" "cider-debug.el" (23377 61664
+;;;;;;  769634 161000))
+;;; Generated autoloads from cider-debug.el
+
+(autoload 'cider-debug-defun-at-point "cider-debug" "\
+Instrument the \"top-level\" expression at point.
+If it is a defn, dispatch the instrumented definition.  Otherwise,
+immediately evaluate the instrumented expression.
+
+While debugged code is being evaluated, the user is taken through the
+source code and displayed the value of various expressions.  At each step,
+a number of keys will be prompted to the user.
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "cider-find" "cider-find.el" (23377 61664 796304
+;;;;;;  526000))
+;;; Generated autoloads from cider-find.el
+
+(autoload 'cider-find-var "cider-find" "\
+Find definition for VAR at LINE.
+Prompt according to prefix ARG and `cider-prompt-for-symbol'.
+A single or double prefix argument inverts the meaning of
+`cider-prompt-for-symbol'.  A prefix of `-` or a double prefix argument causes
+the results to be displayed in a different window.  The default value is
+thing at point.
+
+\(fn &optional ARG VAR LINE)" t nil)
+
+(autoload 'cider-find-dwim "cider-find" "\
+Find and display the SYMBOL-FILE at point.
+SYMBOL-FILE could be a var or a resource.  If thing at point is empty then
+show dired on project.  If var is not found, try to jump to resource of the
+same name.  When called interactively, a prompt is given according to the
+variable `cider-prompt-for-symbol'.  A single or double prefix argument
+inverts the meaning.  A prefix of `-' or a double prefix argument causes
+the results to be displayed in a different window.  A default value of thing
+at point is given when prompted.
+
+\(fn SYMBOL-FILE)" t nil)
+
+(autoload 'cider-find-resource "cider-find" "\
+Find the resource at PATH.
+Prompt for input as indicated by the variable `cider-prompt-for-symbol'.
+A single or double prefix argument inverts the meaning of
+`cider-prompt-for-symbol'.  A prefix argument of `-` or a double prefix
+argument causes the results to be displayed in other window.  The default
+value is thing at point.
+
+\(fn PATH)" t nil)
+
+(autoload 'cider-find-ns "cider-find" "\
+Find the file containing NS.
+A prefix ARG of `-` or a double prefix argument causes
+the results to be displayed in a different window.
+
+\(fn &optional ARG NS)" t nil)
+
+(autoload 'cider-find-keyword "cider-find" "\
+Find the namespace of the keyword at point and its first occurrence there.
+
+For instance - if the keyword at point is \":cider.demo/keyword\", this command
+would find the namespace \"cider.demo\" and afterwards find the first mention
+of \"::keyword\" there.
+
+Prompt according to prefix ARG and `cider-prompt-for-symbol'.
+A single or double prefix argument inverts the meaning of
+`cider-prompt-for-symbol'.  A prefix of `-` or a double prefix argument causes
+the results to be displayed in a different window.  The default value is
+thing at point.
+
+\(fn &optional ARG)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "cider-format" "cider-format.el" (23377 61664
+;;;;;;  755199 681000))
+;;; Generated autoloads from cider-format.el
+
+(autoload 'cider-format-region "cider-format" "\
+Format the Clojure code in the current region.
+START and END represent the region's boundaries.
+
+\(fn START END)" t nil)
+
+(autoload 'cider-format-defun "cider-format" "\
+Format the code in the current defun.
+
+\(fn)" t nil)
+
+(autoload 'cider-format-buffer "cider-format" "\
+Format the Clojure code in the current buffer.
+
+\(fn)" t nil)
+
+(autoload 'cider-format-edn-buffer "cider-format" "\
+Format the EDN data in the current buffer.
+
+\(fn)" t nil)
+
+(autoload 'cider-format-edn-region "cider-format" "\
+Format the EDN data in the current region.
+START and END represent the region's boundaries.
+
+\(fn START END)" t nil)
+
+(autoload 'cider-format-edn-last-sexp "cider-format" "\
+Format the EDN data of the last sexp.
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "cider-grimoire" "cider-grimoire.el" (23377
+;;;;;;  61664 785871 442000))
+;;; Generated autoloads from cider-grimoire.el
+
+(autoload 'cider-grimoire-web "cider-grimoire" "\
+Open grimoire documentation in the default web browser.
+
+Prompts for the symbol to use, or uses the symbol at point, depending on
+the value of `cider-prompt-for-symbol'.  With prefix arg ARG, does the
+opposite of what that option dictates.
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'cider-grimoire "cider-grimoire" "\
+Open grimoire documentation in a popup buffer.
+
+Prompts for the symbol to use, or uses the symbol at point, depending on
+the value of `cider-prompt-for-symbol'.  With prefix arg ARG, does the
+opposite of what that option dictates.
+
+\(fn &optional ARG)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "cider-inspector" "cider-inspector.el" (23377
+;;;;;;  61664 783382 910000))
+;;; Generated autoloads from cider-inspector.el
+
+(autoload 'cider-inspect-last-sexp "cider-inspector" "\
+Inspect the result of the the expression preceding point.
+
+\(fn)" t nil)
+
+(autoload 'cider-inspect-defun-at-point "cider-inspector" "\
+Inspect the result of the \"top-level\" expression at point.
+
+\(fn)" t nil)
+
+(autoload 'cider-inspect-last-result "cider-inspector" "\
+Inspect the most recent eval result.
+
+\(fn)" t nil)
+
+(autoload 'cider-inspect "cider-inspector" "\
+Inspect the result of the preceding sexp.
+
+With a prefix argument ARG it inspects the result of the \"top-level\" form.
+With a second prefix argument it prompts for an expression to eval and inspect.
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'cider-inspect-expr "cider-inspector" "\
+Evaluate EXPR in NS and inspect its value.
+Interactively, EXPR is read from the minibuffer, and NS the
+current buffer's namespace.
+
+\(fn EXPR NS)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "cider-macroexpansion" "cider-macroexpansion.el"
+;;;;;;  (23377 61664 801273 463000))
+;;; Generated autoloads from cider-macroexpansion.el
+
+(autoload 'cider-macroexpand-1 "cider-macroexpansion" "\
+Invoke \\=`macroexpand-1\\=` on the expression preceding point.
+If invoked with a PREFIX argument, use \\=`macroexpand\\=` instead of
+\\=`macroexpand-1\\=`.
+
+\(fn &optional PREFIX)" t nil)
+
+(autoload 'cider-macroexpand-all "cider-macroexpansion" "\
+Invoke \\=`macroexpand-all\\=` on the expression preceding point.
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "cider-mode" "cider-mode.el" (23377 61664 773443
+;;;;;;  195000))
+;;; Generated autoloads from cider-mode.el
+
+(defvar cider-mode-line '(:eval (format " cider[%s]" (cider--modeline-info))) "\
+Mode line lighter for cider mode.
+
+The value of this variable is a mode line template as in
+`mode-line-format'.  See Info Node `(elisp)Mode Line Format' for details
+about mode line templates.
+
+Customize this variable to change how cider mode displays its status in the
+mode line.  The default value displays the current connection.  Set this
+variable to nil to disable the mode line entirely.")
+
+(custom-autoload 'cider-mode-line "cider-mode" t)
+
+(eval-after-load 'clojure-mode '(easy-menu-define cider-clojure-mode-menu-open clojure-mode-map "Menu for Clojure mode.\n  This is displayed in `clojure-mode' buffers, if `cider-mode' is not active." `("CIDER" :visible (not cider-mode) ["Start a Clojure REPL" cider-jack-in :help "Starts an nREPL server (with Leiningen, Boot, or Gradle) and connects a REPL to it."] ["Connect to a Clojure REPL" cider-connect :help "Connects to a REPL that's already running."] ["Connect to a ClojureScript REPL" cider-connect-clojurescript :help "Connects to a ClojureScript REPL that's already running."] ["Start a Clojure REPL, and a ClojureScript REPL" cider-jack-in-cljs :help "Starts an nREPL server, connects a Clojure REPL to it, and then a ClojureScript REPL."] "--" ["View manual online" cider-view-manual])))
+
+(autoload 'cider-mode "cider-mode" "\
+Minor mode for REPL interaction from a Clojure buffer.
+
+\\{cider-mode-map}
+
+\(fn &optional ARG)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "cider-ns" "cider-ns.el" (23377 61664 775924
+;;;;;;  562000))
+;;; Generated autoloads from cider-ns.el
+
+(autoload 'cider-ns-refresh "cider-ns" "\
+Reload modified and unloaded namespaces on the classpath.
+
+With a single prefix argument, or if MODE is `refresh-all', reload all
+namespaces on the classpath unconditionally.
+
+With a double prefix argument, or if MODE is `clear', clear the state of
+the namespace tracker before reloading.  This is useful for recovering from
+some classes of error (for example, those caused by circular dependencies)
+that a normal reload would not otherwise recover from.  The trade-off of
+clearing is that stale code from any deleted files may not be completely
+unloaded.
+
+With a negative prefix argument, or if MODE is `inhibit-fns', prevent any
+refresh functions (defined in `cider-ns-refresh-before-fn' and
+`cider-ns-refresh-after-fn') from being invoked.
+
+\(fn &optional MODE)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "cider-profile" "cider-profile.el" (23377 61664
+;;;;;;  764574 111000))
+;;; Generated autoloads from cider-profile.el
+
+(autoload 'cider-profile-samples "cider-profile" "\
+Displays current max-sample-count.
+If optional QUERY is specified, set max-sample-count and display new value.
+
+\(fn &optional QUERY)" t nil)
+
+(autoload 'cider-profile-var-profiled-p "cider-profile" "\
+Displays the profiling status of var under point.
+Prompts for var if none under point or QUERY is present.
+
+\(fn QUERY)" t nil)
+
+(autoload 'cider-profile-ns-toggle "cider-profile" "\
+Toggle profiling for the ns associated with optional QUERY.
+
+If optional argument QUERY is non-nil, prompt for ns.  Otherwise use
+current ns.
+
+\(fn &optional QUERY)" t nil)
+
+(autoload 'cider-profile-toggle "cider-profile" "\
+Toggle profiling for the given QUERY.
+Defaults to the symbol at point.
+With prefix arg or no symbol at point, prompts for a var.
+
+\(fn QUERY)" t nil)
+
+(autoload 'cider-profile-summary "cider-profile" "\
+Display a summary of currently collected profile data.
+
+\(fn)" t nil)
+
+(autoload 'cider-profile-var-summary "cider-profile" "\
+Display profile data for var under point QUERY.
+Defaults to the symbol at point.  With prefix arg or no symbol at point,
+prompts for a var.
+
+\(fn QUERY)" t nil)
+
+(autoload 'cider-profile-clear "cider-profile" "\
+Clear any collected profile data.
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "cider-repl-history" "cider-repl-history.el"
+;;;;;;  (23377 61664 794990 521000))
+;;; Generated autoloads from cider-repl-history.el
+
+(autoload 'cider-repl-history "cider-repl-history" "\
+Display items in the CIDER command history in another buffer.
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "cider-scratch" "cider-scratch.el" (23377 61664
+;;;;;;  778379 441000))
+;;; Generated autoloads from cider-scratch.el
+
+(autoload 'cider-scratch "cider-scratch" "\
+Go to the scratch buffer named `cider-scratch-buffer-name'.
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "cider-selector" "cider-selector.el" (23377
+;;;;;;  61664 805380 173000))
+;;; Generated autoloads from cider-selector.el
+
+(autoload 'cider-selector "cider-selector" "\
+Select a new buffer by type, indicated by a single character.
+The user is prompted for a single character indicating the method by
+which to choose a new buffer.  The `?' character describes then
+available methods.  OTHER-WINDOW provides an optional target.
+See `def-cider-selector-method' for defining new methods.
+
+\(fn &optional OTHER-WINDOW)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "cider-test" "cider-test.el" (23377 61664 798770
+;;;;;;  508000))
+;;; Generated autoloads from cider-test.el
+
+(defvar cider-auto-test-mode nil "\
+Non-nil if Cider-Auto-Test mode is enabled.
+See the `cider-auto-test-mode' command
+for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `cider-auto-test-mode'.")
+
+(custom-autoload 'cider-auto-test-mode "cider-test" nil)
+
+(autoload 'cider-auto-test-mode "cider-test" "\
+Toggle automatic testing of Clojure files.
+
+When enabled this reruns tests every time a Clojure file is loaded.
+Only runs tests corresponding to the loaded file's namespace and does
+nothing if no tests are defined or if the file failed to load.
+
+\(fn &optional ARG)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "cider-tracing" "cider-tracing.el" (23377 61664
+;;;;;;  774719 690000))
+;;; Generated autoloads from cider-tracing.el
+
+(autoload 'cider-toggle-trace-var "cider-tracing" "\
+Toggle var tracing.
+Prompts for the symbol to use, or uses the symbol at point, depending on
+the value of `cider-prompt-for-symbol'.  With prefix arg ARG, does the
+opposite of what that option dictates.
+
+\(fn ARG)" t nil)
+
+(autoload 'cider-toggle-trace-ns "cider-tracing" "\
+Toggle ns tracing.
+Defaults to the current ns.  With prefix arg QUERY, prompts for a ns.
+
+\(fn QUERY)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "cider-util" "cider-util.el" (23377 61664 802813
+;;;;;;  332000))
+;;; Generated autoloads from cider-util.el
+
+(autoload 'cider-view-manual "cider-util" "\
+View the manual in your default browser.
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads nil nil ("cider-client.el" "cider-common.el" "cider-compat.el"
+;;;;;;  "cider-completion.el" "cider-connection.el" "cider-doc.el"
+;;;;;;  "cider-eldoc.el" "cider-eval.el" "cider-overlays.el" "cider-pkg.el"
+;;;;;;  "cider-popup.el" "cider-repl.el" "cider-resolve.el" "cider-stacktrace.el"
+;;;;;;  "nrepl-client.el" "nrepl-dict.el") (23377 61664 793689 575000))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; cider-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-browse-ns.el b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-browse-ns.el
new file mode 100644
index 0000000000..6f7353532b
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-browse-ns.el
@@ -0,0 +1,232 @@
+;;; cider-browse-ns.el --- CIDER namespace browser
+
+;; Copyright © 2014-2018 John Andrews, Bozhidar Batsov and CIDER contributors
+
+;; Author: John Andrews <john.m.andrews@gmail.com>
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;; This file is not part of GNU Emacs.
+
+;;; Commentary:
+
+;; M-x cider-browse-ns
+;;
+;; Display a list of all vars in a namespace.
+;; Pressing <enter> will take you to the cider-doc buffer for that var.
+;; Pressing ^ will take you to a list of all namespaces (akin to `dired-mode').
+
+;; M-x cider-browse-ns-all
+;;
+;; Explore Clojure namespaces by browsing a list of all namespaces.
+;; Pressing <enter> expands into a list of that namespace's vars as if by
+;; executing the command (cider-browse-ns "my.ns").
+
+;;; Code:
+
+(require 'cider-client)
+(require 'cider-popup)
+(require 'cider-compat)
+(require 'cider-util)
+(require 'nrepl-dict)
+
+(require 'subr-x)
+(require 'easymenu)
+(require 'thingatpt)
+
+(defconst cider-browse-ns-buffer "*cider-ns-browser*")
+
+(defvar-local cider-browse-ns-current-ns nil)
+
+;; Mode Definition
+
+(defvar cider-browse-ns-mode-map
+  (let ((map (make-sparse-keymap)))
+    (set-keymap-parent map cider-popup-buffer-mode-map)
+    (define-key map "d" #'cider-browse-ns-doc-at-point)
+    (define-key map "s" #'cider-browse-ns-find-at-point)
+    (define-key map (kbd "RET") #'cider-browse-ns-operate-at-point)
+    (define-key map "^" #'cider-browse-ns-all)
+    (define-key map "n" #'next-line)
+    (define-key map "p" #'previous-line)
+    (easy-menu-define cider-browse-ns-mode-menu map
+      "Menu for CIDER's namespace browser"
+      '("Namespace Browser"
+        ["Show doc" cider-browse-ns-doc-at-point]
+        ["Go to definition" cider-browse-ns-find-at-point]
+        "--"
+        ["Browse all namespaces" cider-browse-ns-all]))
+    map))
+
+(defvar cider-browse-ns-mouse-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map [mouse-1] #'cider-browse-ns-handle-mouse)
+    map))
+
+(define-derived-mode cider-browse-ns-mode special-mode "browse-ns"
+  "Major mode for browsing Clojure namespaces.
+
+\\{cider-browse-ns-mode-map}"
+  (setq-local electric-indent-chars nil)
+  (setq-local sesman-system 'CIDER)
+  (when cider-special-mode-truncate-lines
+    (setq-local truncate-lines t))
+  (setq-local cider-browse-ns-current-ns nil))
+
+(defun cider-browse-ns--text-face (var-meta)
+  "Return font-lock-face for a var.
+VAR-META contains the metadata information used to decide a face.
+Presence of \"arglists-str\" and \"macro\" indicates a macro form.
+Only \"arglists-str\" indicates a function. Otherwise, its a variable.
+If the NAMESPACE is not loaded in the REPL, assume TEXT is a fn."
+  (cond
+   ((not var-meta) 'font-lock-function-name-face)
+   ((and (nrepl-dict-contains var-meta "arglists")
+         (string= (nrepl-dict-get var-meta "macro") "true"))
+    'font-lock-keyword-face)
+   ((nrepl-dict-contains var-meta "arglists") 'font-lock-function-name-face)
+   (t 'font-lock-variable-name-face)))
+
+(defun cider-browse-ns--properties (var var-meta)
+  "Decorate VAR with a clickable keymap and a face.
+VAR-META is used to decide a font-lock face."
+  (let ((face (cider-browse-ns--text-face var-meta)))
+    (propertize var
+                'font-lock-face face
+                'mouse-face 'highlight
+                'keymap cider-browse-ns-mouse-map)))
+
+(defun cider-browse-ns--list (buffer title items &optional ns noerase)
+  "Reset contents of BUFFER.
+Display TITLE at the top and ITEMS are indented underneath.
+If NS is non-nil, it is added to each item as the
+`cider-browse-ns-current-ns' text property.  If NOERASE is non-nil, the
+contents of the buffer are not reset before inserting TITLE and ITEMS."
+  (with-current-buffer buffer
+    (cider-browse-ns-mode)
+    (let ((inhibit-read-only t))
+      (unless noerase (erase-buffer))
+      (goto-char (point-max))
+      (insert (cider-propertize title 'ns) "\n")
+      (dolist (item items)
+        (insert (propertize (concat "  " item "\n")
+                            'cider-browse-ns-current-ns ns)))
+      (goto-char (point-min)))))
+
+(defun cider-browse-ns--first-doc-line (doc)
+  "Return the first line of the given DOC string.
+If the first line of the DOC string contains multiple sentences, only
+the first sentence is returned.  If the DOC string is nil, a Not documented
+string is returned."
+  (if doc
+      (let* ((split-newline (split-string doc "\n"))
+             (first-line (car split-newline)))
+        (cond
+         ((string-match "\\. " first-line) (substring first-line 0 (match-end 0)))
+         ((= 1 (length split-newline)) first-line)
+         (t (concat first-line "..."))))
+    "Not documented."))
+
+(defun cider-browse-ns--items (namespace)
+  "Return the items to show in the namespace browser of the given NAMESPACE.
+Each item consists of a ns-var and the first line of its docstring."
+  (let* ((ns-vars-with-meta (cider-sync-request:ns-vars-with-meta namespace))
+         (propertized-ns-vars (nrepl-dict-map #'cider-browse-ns--properties ns-vars-with-meta)))
+    (mapcar (lambda (ns-var)
+              (let* ((doc (nrepl-dict-get-in ns-vars-with-meta (list ns-var "doc")))
+                     ;; to avoid (read nil)
+                     ;; it prompts the user for a Lisp expression
+                     (doc (when doc (read doc)))
+                     (first-doc-line (cider-browse-ns--first-doc-line doc)))
+                (concat ns-var " " (propertize first-doc-line 'font-lock-face 'font-lock-doc-face))))
+            propertized-ns-vars)))
+
+;; Interactive Functions
+
+;;;###autoload
+(defun cider-browse-ns (namespace)
+  "List all NAMESPACE's vars in BUFFER."
+  (interactive (list (completing-read "Browse namespace: " (cider-sync-request:ns-list))))
+  (with-current-buffer (cider-popup-buffer cider-browse-ns-buffer 'select nil 'ancillary)
+    (cider-browse-ns--list (current-buffer)
+                           namespace
+                           (cider-browse-ns--items namespace))
+    (setq-local cider-browse-ns-current-ns namespace)))
+
+;;;###autoload
+(defun cider-browse-ns-all ()
+  "List all loaded namespaces in BUFFER."
+  (interactive)
+  (with-current-buffer (cider-popup-buffer cider-browse-ns-buffer 'select nil 'ancillary)
+    (let ((names (cider-sync-request:ns-list)))
+      (cider-browse-ns--list (current-buffer)
+                             "All loaded namespaces"
+                             (mapcar (lambda (name)
+                                       (cider-browse-ns--properties name nil))
+                                     names))
+      (setq-local cider-browse-ns-current-ns nil))))
+
+(defun cider-browse-ns--thing-at-point ()
+  "Get the thing at point.
+Return a list of the type ('ns or 'var) and the value."
+  (let ((line (car (split-string (string-trim (thing-at-point 'line)) " "))))
+    (if (string-match "\\." line)
+        `(ns ,line)
+      `(var ,(format "%s/%s"
+                     (or (get-text-property (point) 'cider-browse-ns-current-ns)
+                         cider-browse-ns-current-ns)
+                     line)))))
+
+(defun cider-browse-ns-doc-at-point ()
+  "Show the documentation for the thing at current point."
+  (interactive)
+  (let* ((thing (cider-browse-ns--thing-at-point))
+         (value (cadr thing)))
+    ;; value is either some ns or a var
+    (cider-doc-lookup value)))
+
+(defun cider-browse-ns-operate-at-point ()
+  "Expand browser according to thing at current point.
+If the thing at point is a ns it will be browsed,
+and if the thing at point is some var - its documentation will
+be displayed."
+  (interactive)
+  (let* ((thing (cider-browse-ns--thing-at-point))
+         (type (car thing))
+         (value (cadr thing)))
+    (if (eq type 'ns)
+        (cider-browse-ns value)
+      (cider-doc-lookup value))))
+
+(declare-function cider-find-ns "cider-find")
+(declare-function cider-find-var "cider-find")
+
+(defun cider-browse-ns-find-at-point ()
+  "Find the definition of the thing at point."
+  (interactive)
+  (let* ((thing (cider-browse-ns--thing-at-point))
+         (type (car thing))
+         (value (cadr thing)))
+    (if (eq type 'ns)
+        (cider-find-ns nil value)
+      (cider-find-var current-prefix-arg value))))
+
+(defun cider-browse-ns-handle-mouse (event)
+  "Handle mouse click EVENT."
+  (interactive "e")
+  (cider-browse-ns-operate-at-point))
+
+(provide 'cider-browse-ns)
+
+;;; cider-browse-ns.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-browse-ns.elc b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-browse-ns.elc
new file mode 100644
index 0000000000..e452c7e4a2
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-browse-ns.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-browse-spec.el b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-browse-spec.el
new file mode 100644
index 0000000000..d58352b168
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-browse-spec.el
@@ -0,0 +1,357 @@
+;;; cider-browse-spec.el --- CIDER spec browser
+
+;; Copyright © 2017 Juan Monetta, Bozhidar Batsov and CIDER contributors
+
+;; Author: Juan Monetta <jpmonettas@gmail.com>
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;; This file is not part of GNU Emacs.
+
+;;; Commentary:
+
+;; M-x cider-browse-spec
+;;
+;; Display a spec description you can browse.
+;; Pressing <enter> over a sub spec will take you to the description of that sub spec.
+;; Pressing ^ takes you to the list of all specs.
+
+;; M-x cider-browse-spec-all
+;;
+;; Explore clojure.spec registry by browsing a list of all specs.
+;; Pressing <enter> over a spec display the spec description you can browse.
+
+;;; Code:
+
+(require 'cider-client)
+(require 'cider-compat)
+(require 'cider-util)
+(require 'cl-lib)
+(require 'nrepl-dict)
+(require 'seq)
+(require 'subr-x)
+(require 'help-mode)
+
+;; The buffer names used by the spec browser
+(defconst cider-browse-spec-buffer "*cider-spec-browser*")
+(defconst cider-browse-spec-example-buffer "*cider-spec-example*")
+
+;; Mode Definition
+
+(defvar cider-browse-spec-mode-map
+  (let ((map (make-sparse-keymap)))
+    (set-keymap-parent map (make-composed-keymap button-buffer-map
+                                                 cider-popup-buffer-mode-map))
+    (define-key map (kbd "RET") #'cider-browse-spec--browse-at)
+    (define-key map "n" #'forward-button)
+    (define-key map "p" #'backward-button)
+    map)
+  "Keymap for `cider-browse-spec-mode'.")
+
+(define-derived-mode cider-browse-spec-mode special-mode "Specs"
+  "Major mode for browsing Clojure specs.
+
+\\{cider-browse-spec-mode-map}"
+  (setq-local electric-indent-chars nil)
+  (setq-local sesman-system 'CIDER)
+  (when cider-special-mode-truncate-lines
+    (setq-local truncate-lines t)))
+
+(defvar cider-browse-spec--current-spec nil)
+
+(defvar cider-browse-spec-view-mode-map
+  (let ((map (make-sparse-keymap)))
+    (set-keymap-parent map help-mode-map)
+    (define-key map (kbd "RET") #'cider-browse-spec--browse-at)
+    (define-key map "^" #'cider-browse-spec-all)
+    (define-key map "e" #'cider-browse-spec--print-curr-spec-example)
+    (define-key map "n" #'forward-button)
+    (define-key map "p" #'backward-button)
+    map)
+  "Keymap for `cider-browse-spec-view-mode'.")
+
+(define-derived-mode cider-browse-spec-view-mode help-mode "Spec"
+  "Major mode for displaying CIDER spec.
+
+\\{cider-browse-spec-view-mode-map}"
+  (setq-local cider-browse-spec--current-spec nil)
+  (setq-local electric-indent-chars nil)
+  (setq-local sesman-system 'CIDER)
+  (when cider-special-mode-truncate-lines
+    (setq-local truncate-lines t)))
+
+(defvar cider-browse-spec-example-mode-map
+  (let ((map (make-sparse-keymap)))
+    (set-keymap-parent map cider-popup-buffer-mode-map)
+    (define-key map "^" #'cider-browse-spec-all)
+    (define-key map "e" #'cider-browse-spec--print-curr-spec-example)
+    (define-key map "g" #'revert-buffer)
+    map)
+  "Keymap for `cider-browse-spec-example-mode'.")
+
+(define-derived-mode cider-browse-spec-example-mode special-mode "Example"
+  "Major mode for Clojure spec examples.
+
+\\{cider-browse-spec-example-mode-map}"
+  (setq-local electric-indent-chars nil)
+  (setq-local revert-buffer-function #'cider-browse-spec--example-revert-buffer-function)
+  (setq-local sesman-system 'CIDER)
+  (when cider-special-mode-truncate-lines
+    (setq-local truncate-lines t)))
+
+;; Non interactive functions
+
+(define-button-type 'cider-browse-spec--spec
+  'action #'cider-browse-spec--browse-at
+  'face nil
+  'follow-link t
+  'help-echo "View spec")
+
+(defun cider-browse-spec--draw-list-buffer (buffer title specs)
+  "Reset contents of BUFFER.
+Display TITLE at the top and SPECS are indented underneath."
+  (with-current-buffer buffer
+    (cider-browse-spec-mode)
+    (let ((inhibit-read-only t))
+      (erase-buffer)
+      (goto-char (point-max))
+      (insert (cider-propertize title 'emph) "\n")
+      (dolist (spec-name specs)
+        (insert (propertize "  " 'spec-name spec-name))
+        (thread-first (cider-font-lock-as-clojure spec-name)
+          (insert-text-button 'type 'cider-browse-spec--spec)
+          (button-put 'spec-name spec-name))
+        (insert (propertize "\n" 'spec-name spec-name)))
+      (goto-char (point-min)))))
+
+(defun cider--qualified-keyword-p (str)
+  "Return non nil if STR is a namespaced keyword."
+  (string-match-p "^:.+/.+$" str))
+
+(defun cider--spec-fn-p (value fn-name)
+  "Return non nil if VALUE is clojure.spec.[alpha]/FN-NAME."
+  (string-match-p (concat "^\\(clojure.spec\\|clojure.spec.alpha\\)/" fn-name "$") value))
+
+(defun cider-browse-spec--pprint (form)
+  "Given a spec FORM builds a multi line string with a pretty render of that FORM."
+  (cond ((stringp form)
+         (if (cider--qualified-keyword-p form)
+             (with-temp-buffer
+               (thread-first form
+                 (insert-text-button 'type 'cider-browse-spec--spec)
+                 (button-put 'spec-name form))
+               (buffer-string))
+           ;; to make it easier to read replace all clojure.spec ns with s/
+           ;; and remove all clojure.core ns
+           (thread-last form
+             (replace-regexp-in-string "^\\(clojure.spec\\|clojure.spec.alpha\\)/" "s/")
+             (replace-regexp-in-string "^\\(clojure.core\\)/" ""))))
+
+        ((and (listp form) (stringp (cl-first form)))
+         (let ((form-tag (cl-first form)))
+           (cond
+            ;; prettier fns #()
+            ((string-equal form-tag "clojure.core/fn")
+             (if (equal (cl-second form) '("%"))
+                 (format "#%s" (cl-reduce #'concat (mapcar #'cider-browse-spec--pprint (cl-rest (cl-rest form)))))
+               (format "(fn [%%] %s)" (cl-reduce #'concat (mapcar #'cider-browse-spec--pprint (cl-rest (cl-rest form)))))))
+            ;; prettier (s/and )
+            ((cider--spec-fn-p form-tag "and")
+             (format "(s/and\n%s)" (string-join (thread-last (cl-rest form)
+                                                  (mapcar #'cider-browse-spec--pprint)
+                                                  (mapcar (lambda (x) (format "%s" x))))
+                                                "\n")))
+            ;; prettier (s/or )
+            ((cider--spec-fn-p form-tag "or")
+             (let ((name-spec-pair (seq-partition (cl-rest form) 2)))
+               (format "(s/or\n%s)" (string-join
+                                     (thread-last name-spec-pair
+                                       (mapcar (lambda (s) (format "%s %s" (cl-first s) (cider-browse-spec--pprint (cl-second s))))))
+                                     "\n"))))
+            ;; prettier (s/merge )
+            ((cider--spec-fn-p form-tag "merge")
+             (format "(s/merge\n%s)" (string-join (thread-last (cl-rest form)
+                                                    (mapcar #'cider-browse-spec--pprint)
+                                                    (mapcar (lambda (x) (format "%s" x))))
+                                                  "\n")))
+            ;; prettier (s/keys )
+            ((cider--spec-fn-p form-tag "keys")
+             (let ((keys-args (seq-partition (cl-rest form) 2)))
+               (format "(s/keys%s)" (thread-last
+                                        keys-args
+                                      (mapcar (lambda (s)
+                                                (let ((key-type (cl-first s))
+                                                      (specs-vec (cl-second s)))
+                                                  (concat "\n" key-type
+                                                          " ["
+                                                          (string-join (thread-last specs-vec
+                                                                         (mapcar #'cider-browse-spec--pprint)
+                                                                         (mapcar (lambda (x) (format "%s" x))))
+                                                                       "\n")
+                                                          "]"))))
+                                      (cl-reduce #'concat)))))
+            ;; prettier (s/multi-spec)
+            ((cider--spec-fn-p form-tag "multi-spec")
+             (let ((multi-method (cl-second form))
+                   (retag (cl-third form))
+                   (sub-specs (cl-rest (cl-rest (cl-rest form)))))
+               (format "(s/multi-spec %s %s\n%s)"
+                       multi-method
+                       retag
+                       (string-join
+                        (thread-last sub-specs
+                          (mapcar (lambda (s)
+                                    (concat "\n\n" (cl-first s) " " (cider-browse-spec--pprint (cl-second s))))))
+                        "\n"))))
+            ;; prettier (s/cat )
+            ((cider--spec-fn-p form-tag "cat")
+             (let ((name-spec-pairs (seq-partition (cl-rest form) 2)))
+               (format "(s/cat %s)"
+                       (thread-last name-spec-pairs
+                         (mapcar (lambda (s)
+                                   (concat "\n" (cl-first s) " " (cider-browse-spec--pprint (cl-second s)))))
+                         (cl-reduce #'concat)))))
+            ;; prettier (s/alt )
+            ((cider--spec-fn-p form-tag "alt")
+             (let ((name-spec-pairs (seq-partition (cl-rest form) 2)))
+               (format "(s/alt %s)"
+                       (thread-last name-spec-pairs
+                         (mapcar (lambda (s)
+                                   (concat "\n" (cl-first s) " " (cider-browse-spec--pprint (cl-second s)))))
+                         (cl-reduce #'concat)))))
+            ;; prettier (s/fspec )
+            ((cider--spec-fn-p form-tag "fspec")
+             (thread-last (seq-partition (cl-rest form) 2)
+               (cl-remove-if (lambda (s) (and (stringp (cl-second s))
+                                              (string-empty-p (cl-second s)))))
+               (mapcar (lambda (s)
+                         (format "\n%-11s: %s" (pcase (cl-first s)
+                                                 (":args" "arguments")
+                                                 (":ret" "returns")
+                                                 (":fn" "invariants"))
+                                 (cider-browse-spec--pprint (cl-second s)))))
+               (cl-reduce #'concat)
+               (format "%s")))
+            ;; every other with no special management
+            (t (format "(%s %s)"
+                       (cider-browse-spec--pprint form-tag)
+                       (string-join (mapcar #'cider-browse-spec--pprint (cl-rest form)) " "))))))
+        (t (format "%s" form))))
+
+(defun cider-browse-spec--pprint-indented (spec-form)
+  "Indent (pretty-print) and font-lock SPEC-FORM.
+Return the result as a string."
+  (with-temp-buffer
+    (clojure-mode)
+    (insert (cider-browse-spec--pprint spec-form))
+    (indent-region (point-min) (point-max))
+    (cider--font-lock-ensure)
+    (buffer-string)))
+
+(defun cider-browse-spec--draw-spec-buffer (buffer spec spec-form)
+  "Reset contents of BUFFER and draws everything needed to browse the SPEC-FORM.
+Display SPEC as a title and uses `cider-browse-spec--pprint' to display
+a more user friendly representation of SPEC-FORM."
+  (with-current-buffer buffer
+    (let ((inhibit-read-only t))
+      (cider--help-setup-xref (list #'cider-browse-spec spec) nil buffer)
+      (goto-char (point-max))
+      (insert (cider-font-lock-as-clojure spec) "\n\n")
+      (insert (cider-browse-spec--pprint-indented spec-form))
+      (cider--make-back-forward-xrefs)
+      (current-buffer))))
+
+(defun cider-browse-spec--browse (spec)
+  "Browse SPEC."
+  (cider-ensure-connected)
+  (cider-ensure-op-supported "spec-form")
+  (with-current-buffer (cider-popup-buffer cider-browse-spec-buffer 'select #'cider-browse-spec-view-mode 'ancillary)
+    (setq-local cider-browse-spec--current-spec spec)
+    (cider-browse-spec--draw-spec-buffer (current-buffer)
+                                         spec
+                                         (cider-sync-request:spec-form spec))
+    (goto-char (point-min))
+    (current-buffer)))
+
+(defun cider-browse-spec--browse-at (&optional pos)
+  "View the definition of a spec.
+
+Optional argument POS is the position of a spec, defaulting to point.  POS
+may also be a button, so this function can be used a the button's `action'
+property."
+  (interactive)
+  (let ((pos (or pos (point))))
+    (when-let* ((spec (button-get pos 'spec-name)))
+      (cider-browse-spec--browse spec))))
+
+;; Interactive Functions
+
+(defun cider-browse-spec--print-curr-spec-example ()
+  "Generate and print an example of the current spec."
+  (interactive)
+  (cider-ensure-connected)
+  (cider-ensure-op-supported "spec-example")
+  (if-let* ((spec cider-browse-spec--current-spec))
+      (if-let* ((example (cider-sync-request:spec-example spec)))
+          (with-current-buffer (cider-popup-buffer cider-browse-spec-example-buffer 'select #'cider-browse-spec-example-mode 'ancillary)
+            (setq-local cider-browse-spec--current-spec spec)
+            (let ((inhibit-read-only t))
+              (insert "Example of " (cider-font-lock-as-clojure spec))
+              (insert "\n\n")
+              (insert (cider-font-lock-as-clojure example))
+              (goto-char (point-min))))
+        (error (format "No example for spec %s" spec)))
+    (error "No current spec")))
+
+(defun cider-browse-spec--example-revert-buffer-function (&rest _)
+  "`revert-buffer' function for `cider-browse-spec-example-mode'.
+
+Generates a new example for the current spec."
+  (cider-browse-spec--print-curr-spec-example))
+
+;;;###autoload
+(defun cider-browse-spec (spec)
+  "Browse SPEC definition."
+  (interactive (list (completing-read "Browse spec: "
+                                      (cider-sync-request:spec-list)
+                                      nil nil
+                                      (cider-symbol-at-point))))
+  (cider-browse-spec--browse spec))
+
+(defun cider-browse-spec-regex (regex)
+  "Open the list of specs that matches REGEX in a popup buffer.
+Displays all specs when REGEX is nil."
+  (cider-ensure-connected)
+  (cider-ensure-op-supported "spec-list")
+  (let ((filter-regex (or regex "")))
+    (with-current-buffer (cider-popup-buffer cider-browse-spec-buffer 'select nil 'ancillary)
+      (let ((specs (cider-sync-request:spec-list filter-regex)))
+        (cider-browse-spec--draw-list-buffer (current-buffer)
+                                             (if (string-empty-p filter-regex)
+                                                 "All specs in registry"
+                                               (format "All specs matching regex `%s' in registry" filter-regex))
+                                             specs)))))
+
+;;;###autoload
+(defun cider-browse-spec-all (&optional arg)
+  "Open list of specs in a popup buffer.
+
+With a prefix argument ARG, prompts for a regexp to filter specs.
+No filter applied if the regexp is the empty string."
+  (interactive "P")
+  (cider-browse-spec-regex (if arg (read-string "Filter regex: ") "")))
+
+(provide 'cider-browse-spec)
+
+;;; cider-browse-spec.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-browse-spec.elc b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-browse-spec.elc
new file mode 100644
index 0000000000..a7b18881b3
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-browse-spec.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-cheatsheet.el b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-cheatsheet.el
new file mode 100644
index 0000000000..d870c5a5a8
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-cheatsheet.el
@@ -0,0 +1,577 @@
+;;; cider-cheatsheet.el --- Quick reference for Clojure        -*- lexical-binding: t -*-
+
+;; Copyright © 2018 Kris Jenkins, Bozhidar Batsov and CIDER contributors
+;;
+;; Author: Kris Jenkins <krisajenkins@gmail.com>
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;; This file is not part of GNU Emacs.
+
+;;; Commentary:
+
+;; A quick reference system for Clojure.  Fast, searchable & available offline.
+
+;; Mostly taken from Kris Jenkins' `clojure-cheatsheet'
+;; See: https://github.com/clojure-emacs/clojure-cheatsheet
+
+;;; Code:
+
+(require 'cider-doc)
+(require 'seq)
+
+(defconst cider-cheatsheet-hierarchy
+  '(("Primitives"
+     ("Numbers"
+      ("Arithmetic"
+       (clojure.core + - * / quot rem mod dec inc max min))
+      ("Compare"
+       (clojure.core = == not= < > <= >= compare))
+      ("Bitwise"
+       (clojure.core bit-and bit-and-not bit-clear bit-flip bit-not bit-or bit-set bit-shift-left bit-shift-right bit-test bit-xor unsigned-bit-shift-right))
+      ("Cast"
+       (clojure.core byte short long int float double bigdec bigint biginteger num rationalize))
+      ("Test"
+       (clojure.core nil? some? identical? zero? pos? neg? even? odd?))
+      ("Random"
+       (clojure.core rand rand-int))
+      ("BigDecimal"
+       (clojure.core with-precision))
+      ("Ratios"
+       (clojure.core numerator denominator ratio?))
+      ("Arbitrary Precision Arithmetic"
+       (clojure.core +\' -\' *\' inc\' dec\'))
+      ("Unchecked"
+       (clojure.core *unchecked-math*
+                     unchecked-add
+                     unchecked-add-int
+                     unchecked-byte
+                     unchecked-char
+                     unchecked-dec
+                     unchecked-dec-int
+                     unchecked-divide-int
+                     unchecked-double
+                     unchecked-float
+                     unchecked-inc
+                     unchecked-inc-int
+                     unchecked-int
+                     unchecked-long
+                     unchecked-multiply
+                     unchecked-multiply-int
+                     unchecked-negate
+                     unchecked-negate-int
+                     unchecked-remainder-int
+                     unchecked-short
+                     unchecked-subtract
+                     unchecked-subtract-int)))
+
+     ("Strings"
+      ("Create"
+       (clojure.core str format))
+      ("Use"
+       (clojure.core count get subs compare)
+       (clojure.string join escape split split-lines replace replace-first reverse re-quote-replacement index-of last-index-of starts-with? ends-with? includes?))
+      ("Regex"
+       (clojure.core re-find re-seq re-matches re-pattern re-matcher re-groups)
+       (clojure.string replace replace-first re-quote-replacement))
+      ("Letters"
+       (clojure.string capitalize lower-case upper-case))
+      ("Trim"
+       (clojure.string trim trim-newline triml trimr))
+      ("Test"
+       (clojure.core char char? string?)
+       (clojure.string blank?)))
+
+     ("Other"
+      ("Characters"
+       (clojure.core char char-name-string char-escape-string))
+      ("Keywords"
+       (clojure.core keyword keyword? find-keyword))
+      ("Symbols"
+       (clojure.core symbol symbol? gensym))
+      ("Data Readers"
+       (clojure.core *data-readers* default-data-readers *default-data-reader-fn*))))
+
+    ("Collections"
+     ("Generic Ops"
+      (clojure.core count bounded-count empty not-empty into conj))
+     ("Tree Walking"
+      (clojure.walk walk prewalk prewalk-demo prewalk-replace postwalk postwalk-demo postwalk-replace keywordize-keys stringify-keys))
+     ("Content tests"
+      (clojure.core distinct? empty? every? not-every? some not-any?))
+     ("Capabilities"
+      (clojure.core sequential? associative? sorted? counted? reversible?))
+     ("Type tests"
+      (clojure.core type class coll? list? vector? set? map? seq?
+                    number? integer? float? decimal? class? rational? ratio?
+                    chunked-seq? reduced? special-symbol? record?))
+     ("Lists"
+      ("Create"
+       (clojure.core list list*))
+      ("Examine"
+       (clojure.core first nth peek))
+      ("Change"
+       (clojure.core cons conj rest pop)))
+
+     ("Vectors"
+      ("Create"
+       (clojure.core vec vector vector-of))
+      ("Examine"
+       (clojure.core get peek))
+
+      ("Change"
+       (clojure.core assoc pop subvec replace conj rseq))
+      ("Ops"
+       (clojure.core mapv filterv reduce-kv)))
+
+     ("Sets"
+      ("Create"
+       (clojure.core set hash-set sorted-set sorted-set-by))
+      ("Examine"
+       (clojure.core get contains?))
+      ("Change"
+       (clojure.core conj disj))
+      ("Relational Algebra"
+       (clojure.set join select project union difference intersection))
+      ("Get map"
+       (clojure.set index rename-keys rename map-invert))
+      ("Test"
+       (clojure.set subset? superset?))
+      ("Sorted Sets"
+       (clojure.core rseq subseq rsubseq)))
+
+     ("Maps"
+      ("Create"
+       (clojure.core hash-map array-map zipmap sorted-map sorted-map-by bean frequencies group-by))
+      ("Examine"
+       (clojure.core get get-in contains? find keys vals map-entry?))
+      ("Change"
+       (clojure.core assoc assoc-in dissoc merge merge-with select-keys update update-in))
+      ("Entry"
+       (clojure.core key val))
+      ("Sorted Maps"
+       (clojure.core rseq subseq rsubseq)))
+
+     ("Hashes"
+      (clojure.core hash hash-ordered-coll hash-unordered-coll mix-collection-hash))
+
+     ("Volatiles"
+      (clojure.core volatile! volatile? vreset! vswap!)))
+
+    ("Functions"
+     ("Create"
+      (clojure.core fn defn defn- definline identity constantly comp complement partial juxt memfn memoize fnil every-pred some-fn trampoline))
+     ("Call"
+      (clojure.core -> ->> some-> some->> as-> cond-> cond->>))
+     ("Test"
+      (clojure.core fn? ifn?)))
+
+    ("Transducers"
+     ("Create"
+      (clojure.core cat dedupe distinct drop drop-while filter halt-when interpose keep keep-indexed map map-indexed mapcat partition-all partition-by random-sample remove replace take take-nth take-while))
+     ("Call"
+      (clojure.core ->Eduction eduction into sequence transduce completing run!))
+     ("Early Termination"
+      (clojure.core deref reduced reduced? ensure-reduced unreduced)))
+
+    ("Spec"
+     ("Operations"
+      (clojure.spec.alpha valid? conform unform explain explain-data explain-str explain-out form describe assert check-asserts check-asserts?))
+     ("Generator Ops"
+      (clojure.spec.alpha gen exercise exercise-fn))
+     ("Defn & Registry"
+      (clojure.spec.alpha def fdef registry get-spec spec? spec with-gen))
+     ("Logical"
+      (clojure.spec.alpha and or))
+     ("Collection"
+      (clojure.spec.alpha coll-of map-of every every-kv keys merge))
+     ("Regex "
+      (clojure.spec.alpha cat alt * + \? & keys*))
+     ("Range"
+      (clojure.spec.alpha int-in inst-in double-in int-in-range? inst-in-range?))
+     ("Custom Explain"
+      (clojure.spec.alpha explain-printer *explain-out*))
+     ("Other"
+      (clojure.spec.alpha nilable multi-spec fspec conformer))
+
+     ("Predicates with test.check generators"
+      ("Numbers"
+       (clojure.core number? rational? integer? ratio? decimal? float? zero? double? int? nat-int? neg-int? pos-int?))
+      ("Symbols & Keywords"
+       (clojure.core keyword? symbol? ident? qualified-ident? qualified-keyword? qualified-symbol? simple-ident? simple-keyword? simple-symbol?))
+      ("Scalars"
+       (clojure.core string? true? false? nil? some? boolean? bytes? inst? uri? uuid?))
+      ("Collections"
+       (clojure.core list? map? set? vector? associative? coll? sequential? seq? empty? indexed? seqable?))
+      ("Other"
+       (clojure.core any?))))
+
+    ("Other"
+     ("XML"
+      (clojure.core xml-seq)
+      (clojure.xml parse))
+     ("REPL"
+      (clojure.core *1 *2 *3 *e *print-dup* *print-length* *print-level* *print-meta* *print-readably*))
+     ("EDN"
+      (clojure.edn read read-string))
+     ("Compiling Code & Class Generation"
+      (clojure.core *compile-files* *compile-path* *file* *warn-on-reflection* compile gen-class gen-interface loaded-libs test))
+     ("Misc"
+      (clojure.core eval force name *clojure-version* clojure-version *command-line-args*))
+     ("Pretty Printing"
+      (clojure.pprint pprint print-table pp *print-right-margin*))
+     ("Browser / Shell"
+      (clojure.java.browse browse-url)
+      (clojure.java.shell sh with-sh-dir with-sh-env)))
+
+    ("Vars & Global Environment"
+     ("Def Variants"
+      (:special def)
+      (clojure.core defn defn- definline defmacro defmethod defmulti defonce defrecord))
+     ("Interned Vars"
+      (:special var)
+      (clojure.core declare intern binding find-var))
+     ("Var Objects"
+      (clojure.core with-local-vars var-get var-set alter-var-root var?))
+     ("Var Validators"
+      (clojure.core set-validator! get-validator)))
+
+    ("Reader Conditionals"
+     (clojure.core reader-conditional reader-conditional? tagged-literal tagged-literal?))
+
+    ("Abstractions"
+     ("Protocols"
+      (clojure.core defprotocol extend extend-type extend-protocol reify extends? satisfies? extenders))
+     ("Records & Types"
+      (clojure.core defrecord deftype))
+     ("Multimethods"
+      ("Define"
+       (clojure.core defmulti defmethod))
+      ("Dispatch"
+       (clojure.core get-method methods))
+      ("Remove"
+       (clojure.core remove-method remove-all-methods))
+      ("Prefer"
+       (clojure.core prefer-method prefers))
+      ("Relation"
+       (clojure.core derive isa? parents ancestors descendants make-hierarchy))))
+
+    ("Macros"
+     ("Create"
+      (clojure.core defmacro definline))
+     ("Debug"
+      (clojure.core macroexpand-1 macroexpand)
+      (clojure.walk macroexpand-all))
+     ("Branch"
+      (clojure.core and or when when-not when-let when-first if-not if-let cond condp case))
+     ("Loop"
+      (clojure.core for doseq dotimes while))
+     ("Arrange"
+      (clojure.core .. doto ->))
+     ("Scope"
+      (clojure.core binding locking time)
+      (clojure.core with-in-str with-local-vars with-open with-out-str with-precision with-redefs with-redefs-fn))
+     ("Lazy"
+      (clojure.core lazy-cat lazy-seq delay delay?))
+     ("Doc"
+      (clojure.core assert comment)
+      (clojure.repl doc dir dir-fn source-fn)))
+
+    ("Java Interop"
+     ("General"
+      (:special new set!)
+      (clojure.core .. doto bean comparator enumeration-seq import iterator-seq memfn definterface supers bases))
+     ("Cast"
+      (clojure.core boolean byte short char int long float double bigdec bigint num cast biginteger))
+     ("Exceptions"
+      (:special throw try catch finally)
+      (clojure.core ex-info ex-data Throwable->map StackTraceElement->vec)
+      (clojure.repl pst))
+     ("Arrays"
+      ("Create"
+       (clojure.core boolean-array byte-array double-array char-array float-array int-array long-array make-array object-array short-array to-array))
+      ("Manipulate"
+       (clojure.core aclone aget aset alength amap areduce aset-int aset-long aset-short aset-boolean aset-byte aset-char aset-double aset-float))
+      ("Cast"
+       (clojure.core booleans bytes chars doubles floats ints longs shorts)))
+     ("Proxy"
+      ("Create"
+       (clojure.core proxy get-proxy-class construct-proxy init-proxy))
+      ("Misc"
+       (clojure.core proxy-mappings proxy-super update-proxy))))
+
+    ("Namespaces"
+     ("Current"
+      (clojure.core *ns*))
+     ("Create Switch"
+      (clojure.core ns in-ns create-ns))
+     ("Add"
+      (clojure.core alias import intern refer refer-clojure))
+     ("Find"
+      (clojure.core all-ns find-ns))
+     ("Examine"
+      (clojure.core ns-aliases ns-imports ns-interns ns-map ns-name ns-publics ns-refers))
+     ("From symbol"
+      (clojure.core resolve namespace ns-resolve the-ns))
+     ("Remove"
+      (clojure.core ns-unalias ns-unmap remove-ns)))
+    ("Loading"
+     ("Load libs"
+      (clojure.core require use import refer))
+     ("List Loaded"
+      (clojure.core loaded-libs))
+     ("Load Misc"
+      (clojure.core load load-file load-reader load-string)))
+
+    ("Concurrency"
+     ("Atoms"
+      (clojure.core atom swap! swap-vals! reset! reset-vals! compare-and-set!))
+     ("Futures"
+      (clojure.core future future-call future-cancel future-cancelled? future-done? future?))
+     ("Threads"
+      (clojure.core bound-fn bound-fn* get-thread-bindings pop-thread-bindings push-thread-bindings))
+
+     ("Misc"
+      (clojure.core locking pcalls pvalues pmap seque promise deliver))
+
+     ("Refs & Transactions"
+      ("Create"
+       (clojure.core ref))
+      ("Examine"
+       (clojure.core deref))
+      ("Transaction"
+       (clojure.core sync dosync io!))
+      ("In Transaction"
+       (clojure.core ensure ref-set alter commute))
+      ("Validators"
+       (clojure.core get-validator set-validator!))
+      ("History"
+       (clojure.core ref-history-count ref-max-history ref-min-history)))
+
+     ("Agents & Asynchronous Actions"
+      ("Create"
+       (clojure.core agent))
+      ("Examine"
+       (clojure.core agent-error))
+      ("Change State"
+       (clojure.core send send-off restart-agent send-via set-agent-send-executor! set-agent-send-off-executor!))
+      ("Block Waiting"
+       (clojure.core await await-for))
+      ("Ref Validators"
+       (clojure.core get-validator set-validator!))
+      ("Watchers"
+       (clojure.core add-watch remove-watch))
+      ("Thread Handling"
+       (clojure.core shutdown-agents))
+      ("Error"
+       (clojure.core error-handler set-error-handler! error-mode set-error-mode!))
+      ("Misc"
+       (clojure.core *agent* release-pending-sends))))
+
+    ("Sequences"
+     ("Creating a Lazy Seq"
+      ("From Collection"
+       (clojure.core seq sequence keys vals rseq subseq rsubseq))
+      ("From Producer Fn"
+       (clojure.core lazy-seq repeatedly iterate))
+      ("From Constant"
+       (clojure.core repeat range))
+      ("From Other"
+       (clojure.core file-seq line-seq resultset-seq re-seq tree-seq xml-seq iterator-seq enumeration-seq))
+      ("From Seq"
+       (clojure.core keep keep-indexed)))
+
+     ("Seq in, Seq out"
+      ("Get shorter"
+       (clojure.core distinct dedupe filter remove for))
+      ("Get longer"
+       (clojure.core cons conj concat lazy-cat mapcat cycle interleave interpose)))
+     ("Tail-items"
+      (clojure.core rest nthrest fnext nnext drop drop-while take-last for))
+     ("Head-items"
+      (clojure.core take take-nth take-while butlast drop-last for))
+     ("Change"
+      (clojure.core conj concat distinct flatten group-by partition partition-all partition-by split-at split-with filter remove replace shuffle random-sample))
+     ("Rearrange"
+      (clojure.core reverse sort sort-by compare))
+     ("Process items"
+      (clojure.core map pmap map-indexed mapcat for replace seque))
+
+     ("Using a Seq"
+      ("Extract item"
+       (clojure.core first second last rest next ffirst nfirst fnext nnext nth nthnext rand-nth when-first max-key min-key))
+      ("Construct coll"
+       (clojure.core zipmap into reduce reductions set vec into-array to-array-2d))
+      ("Pass to fn"
+       (clojure.core apply))
+      ("Search"
+       (clojure.core some filter))
+      ("Force evaluation"
+       (clojure.core doseq dorun doall))
+      ("Check for forced"
+       (clojure.core realized?))))
+
+    ("Zippers"
+     ("Create"
+      (clojure.zip zipper seq-zip vector-zip xml-zip))
+     ("Get loc"
+      (clojure.zip up down left right leftmost rightmost))
+     ("Get seq"
+      (clojure.zip lefts rights path children))
+     ("Change"
+      (clojure.zip make-node replace edit insert-child insert-left insert-right append-child remove))
+     ("Move"
+      (clojure.zip next prev))
+     ("XML"
+      (clojure.data.zip.xml attr attr= seq-test tag= text text= xml-> xml1->))
+     ("Misc"
+      (clojure.zip root node branch? end?)))
+
+    ("Documentation"
+     ("REPL"
+      (clojure.repl doc find-doc apropos source pst)
+      (clojure.java.javadoc javadoc)))
+
+    ("Transients"
+     ("Create"
+      (clojure.core transient persistent!))
+     ("Change"
+      (clojure.core conj! pop! assoc! dissoc! disj!)))
+    ("Misc"
+     ("Compare"
+      (clojure.core = == identical? not= not compare)
+      (clojure.data diff))
+     ("Test"
+      (clojure.core true? false? nil? instance?)))
+
+    ("IO"
+     ("To/from ..."
+      (clojure.core spit slurp))
+     ("To *out*"
+      (clojure.core pr prn print printf println newline)
+      (clojure.pprint print-table))
+     ("To writer"
+      (clojure.pprint pprint cl-format))
+     ("To string"
+      (clojure.core format with-out-str pr-str prn-str print-str println-str))
+     ("From *in*"
+      (clojure.core read-line read))
+     ("From reader"
+      (clojure.core line-seq read))
+     ("From string"
+      (clojure.core read-string with-in-str))
+     ("Open"
+      (clojure.core with-open)
+      (clojure.java.io reader writer input-stream output-stream))
+     ("Interop"
+      (clojure.java.io make-writer make-reader make-output-stream make-input-stream))
+     ("Misc"
+      (clojure.core flush file-seq *in* *out* *err*)
+      (clojure.java.io file copy delete-file resource as-file as-url as-relative-path make-parents)))
+
+    ("Metadata"
+     (clojure.core meta with-meta alter-meta! reset-meta! vary-meta))
+
+    ("Special Forms"
+     (:special def if do quote var recur throw try monitor-enter monitor-exit)
+     (clojure.core fn loop)
+     ("Binding / Destructuring"
+      (clojure.core let fn letfn defn defmacro loop for doseq if-let if-some when-let when-some)))
+
+    ("Async"
+     ("Main"
+      (clojure.core.async go go-loop <! <!! >! >!! chan put! take take! close! timeout offer! poll! promise-chan))
+     ("Choice"
+      (clojure.core.async alt! alt!! alts! alts!! do-alts))
+     ("Buffering"
+      (clojure.core.async buffer dropping-buffer sliding-buffer unblocking-buffer?))
+     ("Pipelines"
+      (clojure.core.async pipeline pipeline-async pipeline-blocking))
+     ("Threading"
+      (clojure.core.async thread thread-call))
+     ("Mixing"
+      (clojure.core.async admix solo-mode mix unmix unmix-all toggle merge pipe unique))
+     ("Multiples"
+      (clojure.core.async mult tap untap untap-all))
+     ("Publish/Subscribe"
+      (clojure.core.async pub sub unsub unsub-all))
+     ("Higher Order"
+      (clojure.core.async filter< filter> map map< map> mapcat< mapcat> partition partition-by reduce remove< remove> split))
+     ("Pre-Populate"
+      (clojure.core.async into onto-chan to-chan)))
+    ("Unit Tests"
+     ("Defining"
+      (clojure.test deftest deftest- testing is are))
+     ("Running"
+      (clojure.test run-tests run-all-tests test-vars))
+     ("Fixtures"
+      (clojure.test use-fixtures join-fixtures compose-fixtures))))
+  "A data structure for Clojure cheatsheet information.
+
+It's a tree, where the head of each list determines the context of the rest
+of the list.  The head may be:
+
+  - A string, in which case it's a (sub)heading for the rest of the items.
+
+  - A symbol, in which case it's the Clojure namespace of the symbols that
+    follow it.
+
+  - The keyword :special, in which case it's a Clojure special form
+
+  - Any other keyword, in which case it's a typed item that will be passed
+    through.
+
+Note that some Clojure symbols appear in more than once.  This is entirely
+intentional.  For instance, `map` belongs in the sections on collections
+and transducers.")
+
+(defun cider-cheatsheet--expand-vars (list)
+  "Expand the symbols in LIST to fully-qualified var names.
+
+This list is supposed to have the following format:
+
+  (my-ns var1 var2 var3)"
+  (let ((ns (car list))
+        (vars (cdr list)))
+    (if (eq ns :special)
+        (mapcar #'symbol-name vars)
+      (mapcar (lambda (var) (format "%s/%s" ns var)) vars))))
+
+(defun cider-cheatsheet--select-var (var-list)
+  "Expand the symbols in VAR-LIST to fully-qualified var names.
+
+The list can hold one or more lists inside - one per each namespace."
+  (let ((namespaced-vars (seq-mapcat #'cider-cheatsheet--expand-vars
+                                     (seq-remove (lambda (list)
+                                                   (eq (car list) :url))
+                                                 var-list))))
+    (cider-doc-lookup (completing-read "Select var: " namespaced-vars))))
+
+;;;###autoload
+(defun cider-cheatsheet ()
+  "Navigate `cider-cheatsheet-hierarchy' with `completing-read'.
+
+When you make it to a Clojure var its doc buffer gets displayed."
+  (interactive)
+  (let ((cheatsheet-data cider-cheatsheet-hierarchy))
+    (while (stringp (caar cheatsheet-data))
+      (let* ((sections (mapcar #'car cheatsheet-data))
+             (sel-section (completing-read "Select cheatsheet section: " sections))
+             (section-data (seq-find (lambda (elem) (equal (car elem) sel-section)) cheatsheet-data)))
+        (setq cheatsheet-data (cdr section-data))))
+    (cider-cheatsheet--select-var cheatsheet-data)))
+
+(provide 'cider-cheatsheet)
+
+;;; cider-cheatsheet.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-cheatsheet.elc b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-cheatsheet.elc
new file mode 100644
index 0000000000..238c9f5cec
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-cheatsheet.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-classpath.el b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-classpath.el
new file mode 100644
index 0000000000..101413705c
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-classpath.el
@@ -0,0 +1,112 @@
+;;; cider-classpath.el --- Basic Java classpath browser
+
+;; Copyright © 2014-2018 Bozhidar Batsov and CIDER contributors
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;; This file is not part of GNU Emacs.
+
+;;; Commentary:
+
+;; Basic Java classpath browser for CIDER.
+
+;;; Code:
+
+(require 'cider-client)
+(require 'cider-popup)
+(require 'subr-x)
+(require 'cider-compat)
+
+(defvar cider-classpath-buffer "*cider-classpath*")
+
+(defvar cider-classpath-mode-map
+  (let ((map (make-sparse-keymap)))
+    (set-keymap-parent map cider-popup-buffer-mode-map)
+    (define-key map (kbd "RET") #'cider-classpath-operate-on-point)
+    (define-key map "n" #'next-line)
+    (define-key map "p" #'previous-line)
+    map))
+
+(defvar cider-classpath-mouse-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map [mouse-1] #'cider-classpath-handle-mouse)
+    map))
+
+(define-derived-mode cider-classpath-mode special-mode "classpath"
+  "Major mode for browsing the entries in Java's classpath.
+
+\\{cider-classpath-mode-map}"
+  (setq-local electric-indent-chars nil)
+  (setq-local sesman-system 'CIDER)
+  (when cider-special-mode-truncate-lines
+    (setq-local truncate-lines t)))
+
+(defun cider-classpath-list (buffer items)
+  "Populate BUFFER with ITEMS."
+  (with-current-buffer buffer
+    (cider-classpath-mode)
+    (let ((inhibit-read-only t))
+      (erase-buffer)
+      (dolist (item items)
+        (insert item "\n"))
+      (goto-char (point-min)))))
+
+(defun cider-classpath-properties (text)
+  "Decorate TEXT with a clickable keymap and function face."
+  (let ((face (cond
+               ((not (file-exists-p text)) 'font-lock-warning-face)
+               ((file-directory-p text) 'dired-directory)
+               (t 'default))))
+    (propertize text
+                'font-lock-face face
+                'mouse-face 'highlight
+                'keymap cider-classpath-mouse-map)))
+
+(defun cider-classpath-operate-on-point ()
+  "Expand browser according to thing at current point."
+  (interactive)
+  (let* ((bol (line-beginning-position))
+         (eol (line-end-position))
+         (line (buffer-substring-no-properties bol eol)))
+    (find-file-other-window line)))
+
+(defun cider-classpath-handle-mouse (event)
+  "Handle mouse click EVENT."
+  (interactive "e")
+  (cider-classpath-operate-on-point))
+
+;;;###autoload
+(defun cider-classpath ()
+  "List all classpath entries."
+  (interactive)
+  (cider-ensure-connected)
+  (cider-ensure-op-supported "classpath")
+  (with-current-buffer (cider-popup-buffer cider-classpath-buffer 'select nil 'ancillary)
+    (cider-classpath-list (current-buffer)
+                          (mapcar (lambda (name)
+                                    (cider-classpath-properties name))
+                                  (cider-sync-request:classpath)))))
+
+;;;###autoload
+(defun cider-open-classpath-entry ()
+  "Open a classpath entry."
+  (interactive)
+  (cider-ensure-connected)
+  (cider-ensure-op-supported "classpath")
+  (when-let* ((entry (completing-read "Classpath entries: " (cider-sync-request:classpath))))
+    (find-file-other-window entry)))
+
+(provide 'cider-classpath)
+
+;;; cider-classpath.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-classpath.elc b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-classpath.elc
new file mode 100644
index 0000000000..a8ce2b63f6
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-classpath.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-client.el b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-client.el
new file mode 100644
index 0000000000..038fba2fcf
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-client.el
@@ -0,0 +1,577 @@
+;;; cider-client.el --- A layer of abstraction above low-level nREPL client code. -*- lexical-binding: t -*-
+
+;; Copyright © 2013-2018 Bozhidar Batsov
+;;
+;; Author: Bozhidar Batsov <bozhidar@batsov.com>
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;; This file is not part of GNU Emacs.
+
+;;; Commentary:
+
+;; A layer of abstraction above the low-level nREPL client code.
+
+;;; Code:
+
+(require 'spinner)
+(require 'nrepl-client)
+(require 'cider-connection)
+(require 'cider-common)
+(require 'cider-util)
+(require 'clojure-mode)
+
+(require 'subr-x)
+(require 'cider-compat)
+(require 'seq)
+
+
+;;; Eval spinner
+(defcustom cider-eval-spinner-type 'progress-bar
+  "Appearance of the evaluation spinner.
+
+Value is a symbol.  The possible values are the symbols in the
+`spinner-types' variable."
+  :type 'symbol
+  :group 'cider
+  :package-version '(cider . "0.10.0"))
+
+(defcustom cider-show-eval-spinner t
+  "When true, show the evaluation spinner in the mode line."
+  :type 'boolean
+  :group 'cider
+  :package-version '(cider . "0.10.0"))
+
+(defcustom cider-eval-spinner-delay 1
+  "Amount of time, in seconds, after which the evaluation spinner will be shown."
+  :type 'integer
+  :group 'cider
+  :package-version '(cider . "0.10.0"))
+
+(defun cider-spinner-start (buffer)
+  "Start the evaluation spinner in BUFFER.
+Do nothing if `cider-show-eval-spinner' is nil."
+  (when cider-show-eval-spinner
+    (with-current-buffer buffer
+      (spinner-start cider-eval-spinner-type nil
+                     cider-eval-spinner-delay))))
+
+(defun cider-eval-spinner-handler (eval-buffer original-callback)
+  "Return a response handler to stop the spinner and call ORIGINAL-CALLBACK.
+EVAL-BUFFER is the buffer where the spinner was started."
+  (lambda (response)
+    ;; buffer still exists and
+    ;; we've got status "done" from nrepl
+    ;; stop the spinner
+    (when (and (buffer-live-p eval-buffer)
+               (let ((status (nrepl-dict-get response "status")))
+                 (or (member "done" status)
+                     (member "eval-error" status)
+                     (member "error" status))))
+      (with-current-buffer eval-buffer
+        (when spinner-current (spinner-stop))))
+    (funcall original-callback response)))
+
+
+;;; Evaluation helpers
+(defun cider-ns-form-p (form)
+  "Check if FORM is an ns form."
+  (string-match-p "^[[:space:]]*\(ns\\([[:space:]]*$\\|[[:space:]]+\\)" form))
+
+(defun cider-ns-from-form (ns-form)
+  "Get ns substring from NS-FORM."
+  (when (string-match "^[ \t\n]*\(ns[ \t\n]+\\([^][ \t\n(){}]+\\)" ns-form)
+    (match-string-no-properties 1 ns-form)))
+
+(defvar-local cider-buffer-ns nil
+  "Current Clojure namespace of some buffer.
+Useful for special buffers (e.g. REPL, doc buffers) that have to keep track
+of a namespace.  This should never be set in Clojure buffers, as there the
+namespace should be extracted from the buffer's ns form.")
+
+(defun cider-current-ns (&optional no-default)
+  "Return the current ns.
+The ns is extracted from the ns form for Clojure buffers and from
+`cider-buffer-ns' for all other buffers.  If it's missing, use the current
+REPL's ns, otherwise fall back to \"user\".  When NO-DEFAULT is non-nil, it
+will return nil instead of \"user\"."
+  (or cider-buffer-ns
+      (clojure-find-ns)
+      (when-let* ((repl (cider-current-repl)))
+        (buffer-local-value 'cider-buffer-ns repl))
+      (if no-default nil "user")))
+
+(defun cider-expected-ns (&optional path)
+  "Return the namespace string matching PATH, or nil if not found.
+PATH is expected to be an absolute file path.  If PATH is nil, use the path
+to the file backing the current buffer.  The command falls back to
+`clojure-expected-ns' in the absence of an active nREPL connection."
+  (if (cider-connected-p)
+      (let* ((path (or path (file-truename (buffer-file-name))))
+             (relpath (thread-last (cider-sync-request:classpath)
+                        (seq-map
+                         (lambda (cp)
+                           (when (string-prefix-p cp path)
+                             (substring path (length cp)))))
+                        (seq-filter #'identity)
+                        (seq-sort (lambda (a b)
+                                    (< (length a) (length b))))
+                        (car))))
+        (if relpath
+            (thread-last (substring relpath 1) ; remove leading /
+              (file-name-sans-extension)
+              (replace-regexp-in-string "/" ".")
+              (replace-regexp-in-string "_" "-"))
+          (clojure-expected-ns path)))
+    (clojure-expected-ns path)))
+
+(defun cider-nrepl-op-supported-p (op &optional connection)
+  "Check whether the CONNECTION supports the nREPL middleware OP."
+  (nrepl-op-supported-p op (or connection (cider-current-repl))))
+
+(defvar cider-version)
+(defun cider-ensure-op-supported (op)
+  "Check for support of middleware op OP.
+Signal an error if it is not supported."
+  (unless (cider-nrepl-op-supported-p op)
+    (user-error "`%s' requires the nREPL op \"%s\".  Please, install (or update) cider-nrepl %s and restart CIDER" this-command op (upcase cider-version))))
+
+(defun cider-nrepl-send-request (request callback &optional connection)
+  "Send REQUEST and register response handler CALLBACK.
+REQUEST is a pair list of the form (\"op\" \"operation\" \"par1-name\"
+                                    \"par1\" ... ).
+If CONNECTION is provided dispatch to that connection instead of
+the current connection.  Return the id of the sent message."
+  (nrepl-send-request request callback (or connection (cider-current-repl))))
+
+(defun cider-nrepl-send-sync-request (request &optional connection abort-on-input)
+  "Send REQUEST to the nREPL server synchronously using CONNECTION.
+Hold till final \"done\" message has arrived and join all response messages
+of the same \"op\" that came along and return the accumulated response.
+If ABORT-ON-INPUT is non-nil, the function will return nil
+at the first sign of user input, so as not to hang the
+interface."
+  (nrepl-send-sync-request request
+                           (or connection (cider-current-repl))
+                           abort-on-input))
+
+(defun cider-nrepl-send-unhandled-request (request &optional connection)
+  "Send REQUEST to the nREPL CONNECTION and ignore any responses.
+Immediately mark the REQUEST as done.  Return the id of the sent message."
+  (let* ((conn (or connection (cider-current-repl)))
+         (id (nrepl-send-request request #'ignore conn)))
+    (with-current-buffer conn
+      (nrepl--mark-id-completed id))
+    id))
+
+(defun cider-nrepl-request:eval (input callback &optional ns line column additional-params connection)
+  "Send the request INPUT and register the CALLBACK as the response handler.
+If NS is non-nil, include it in the request.  LINE and COLUMN, if non-nil,
+define the position of INPUT in its buffer.  ADDITIONAL-PARAMS is a plist
+to be appended to the request message.  CONNECTION is the connection
+buffer, defaults to (cider-current-repl)."
+  (let ((connection (or connection (cider-current-repl))))
+    (nrepl-request:eval input
+                        (if cider-show-eval-spinner
+                            (cider-eval-spinner-handler connection callback)
+                          callback)
+                        connection
+                        ns line column additional-params)
+    (cider-spinner-start connection)))
+
+(defun cider-nrepl-sync-request:eval (input &optional connection ns)
+  "Send the INPUT to the nREPL CONNECTION synchronously.
+If NS is non-nil, include it in the eval request."
+  (nrepl-sync-request:eval input (or connection (cider-current-repl)) ns))
+
+(defcustom cider-pprint-fn 'pprint
+  "Sets the function to use when pretty-printing evaluation results.
+
+The value must be one of the following symbols:
+
+`pprint' - to use \\=`clojure.pprint/pprint\\=`
+
+`fipp' - to use the Fast Idiomatic Pretty Printer, approximately 5-10x
+faster than \\=`clojure.core/pprint\\=` (this is the default)
+
+`puget' - to use Puget, which provides canonical serialization of data on
+top of fipp, but at a slight performance cost
+
+Alternatively, can be the namespace-qualified name of a Clojure function of
+one argument.  If the function cannot be resolved, an exception will be
+thrown.
+
+The function is assumed to respect the contract of \\=`clojure.pprint/pprint\\=`
+with respect to the bound values of \\=`*print-length*\\=`, \\=`*print-level*\\=`,
+\\=`*print-meta*\\=`, and \\=`clojure.pprint/*print-right-margin*\\=`."
+  :type '(choice (const pprint)
+                 (const fipp)
+                 (const puget)
+                 string)
+  :group 'cider
+  :package-version '(cider . "0.11.0"))
+
+(defun cider--pprint-fn ()
+  "Return the value to send in the pprint-fn slot of messages."
+  (pcase cider-pprint-fn
+    (`pprint "clojure.pprint/pprint")
+    (`fipp "cider.nrepl.middleware.pprint/fipp-pprint")
+    (`puget "cider.nrepl.middleware.pprint/puget-pprint")
+    (_ cider-pprint-fn)))
+
+(defun cider--nrepl-pprint-request-plist (right-margin &optional pprint-fn)
+  "Plist to be appended to an eval request to make it use pprint.
+PPRINT-FN is the name of the Clojure function to use.
+RIGHT-MARGIN specifies the maximum column-width of the pretty-printed
+result, and is included in the request if non-nil."
+  (nconc `("pprint" "true"
+           "pprint-fn" ,(or pprint-fn (cider--pprint-fn)))
+         (and right-margin `("print-right-margin" ,right-margin))))
+
+(defun cider--nrepl-content-type-plist ()
+  "Plist to be appended to an eval request to make it use content-types."
+  '("content-type" "true"))
+
+(defun cider-tooling-eval (input callback &optional ns connection)
+  "Send the request INPUT to CONNECTION and register the CALLBACK.
+NS specifies the namespace in which to evaluate the request.  Requests
+evaluated in the tooling nREPL session don't affect the thread-local
+bindings of the primary eval nREPL session (e.g. this is not going to
+clobber *1/2/3)."
+  ;; namespace forms are always evaluated in the "user" namespace
+  (nrepl-request:eval input
+                      callback
+                      (or connection (cider-current-repl))
+                      ns nil nil nil 'tooling))
+
+(defun cider-sync-tooling-eval (input &optional ns connection)
+  "Send the request INPUT to CONNECTION and evaluate in synchronously.
+NS specifies the namespace in which to evaluate the request.  Requests
+evaluated in the tooling nREPL session don't affect the thread-local
+bindings of the primary eval nREPL session (e.g. this is not going to
+clobber *1/2/3)."
+  ;; namespace forms are always evaluated in the "user" namespace
+  (nrepl-sync-request:eval input
+                           (or connection (cider-current-repl))
+                           ns
+                           'tooling))
+
+;; TODO: Add some unit tests and pretty those two functions up.
+;; FIXME: Currently that's broken for group-id with multiple segments (e.g. org.clojure/clojure)
+(defun cider-classpath-libs ()
+  "Return a list of all libs on the classpath."
+  (let ((libs (seq-filter (lambda (cp-entry)
+                            (string-suffix-p ".jar" cp-entry))
+                          (cider-sync-request:classpath)))
+        (dir-sep (if (string-equal system-type "windows-nt") "\\\\" "/")))
+    (thread-last libs
+      (seq-map (lambda (s) (split-string s dir-sep)))
+      (seq-map #'reverse)
+      (seq-map (lambda (l) (reverse (seq-take l 4)))))))
+
+(defun cider-library-present-p (lib)
+  "Check whether LIB is present on the classpath.
+The library is a string of the format \"group-id/artifact-id\"."
+  (let* ((lib (split-string lib "/"))
+         (group-id (car lib))
+         (artifact-id (cadr lib)))
+    (seq-find (lambda (lib)
+                (let ((g (car lib))
+                      (a (cadr lib)))
+                  (and (equal group-id g) (equal artifact-id a))))
+              (cider-classpath-libs))))
+
+
+;;; Interrupt evaluation
+
+(defun cider-interrupt-handler (buffer)
+  "Create an interrupt response handler for BUFFER."
+  (nrepl-make-response-handler buffer nil nil nil nil))
+
+(defun cider-interrupt ()
+  "Interrupt any pending evaluations."
+  (interactive)
+  ;; FIXME: does this work correctly in cljc files?
+  (with-current-buffer (cider-current-repl)
+    (let ((pending-request-ids (cider-util--hash-keys nrepl-pending-requests)))
+      (dolist (request-id pending-request-ids)
+        (nrepl-request:interrupt
+         request-id
+         (cider-interrupt-handler (current-buffer))
+         (cider-current-repl))))))
+
+(defun cider-nrepl-eval-session ()
+  "Return the eval nREPL session id of the current connection."
+  (with-current-buffer (cider-current-repl)
+    nrepl-session))
+
+(defun cider-nrepl-tooling-session ()
+  "Return the tooling nREPL session id of the current connection."
+  (with-current-buffer (cider-current-repl)
+    nrepl-tooling-session))
+
+(defun cider--var-choice (var-info)
+  "Prompt to choose from among multiple VAR-INFO candidates, if required.
+This is needed only when the symbol queried is an unqualified host platform
+method, and multiple classes have a so-named member.  If VAR-INFO does not
+contain a `candidates' key, it is returned as is."
+  (let ((candidates (nrepl-dict-get var-info "candidates")))
+    (if candidates
+        (let* ((classes (nrepl-dict-keys candidates))
+               (choice (completing-read "Member in class: " classes nil t))
+               (info (nrepl-dict-get candidates choice)))
+          info)
+      var-info)))
+
+(defun cider-var-info (var &optional all)
+  "Return VAR's info as an alist with list cdrs.
+When multiple matching vars are returned you'll be prompted to select one,
+unless ALL is truthy."
+  (when (and var (not (string= var "")))
+    (let ((var-info (cider-sync-request:info var)))
+      (if all var-info (cider--var-choice var-info)))))
+
+(defun cider-member-info (class member)
+  "Return the CLASS MEMBER's info as an alist with list cdrs."
+  (when (and class member)
+    (cider-sync-request:info nil class member)))
+
+
+;;; Requests
+
+(declare-function cider-load-file-handler "cider-eval")
+(defun cider-request:load-file (file-contents file-path file-name &optional connection callback)
+  "Perform the nREPL \"load-file\" op.
+FILE-CONTENTS, FILE-PATH and FILE-NAME are details of the file to be
+loaded.  If CONNECTION is nil, use `cider-current-repl'.  If CALLBACK
+is nil, use `cider-load-file-handler'."
+  (cider-nrepl-send-request `("op" "load-file"
+                              "file" ,file-contents
+                              "file-path" ,file-path
+                              "file-name" ,file-name)
+                            (or callback
+                                (cider-load-file-handler (current-buffer)))
+                            connection))
+
+
+;;; Sync Requests
+
+(defcustom cider-filtered-namespaces-regexps
+  '("^cider.nrepl" "^refactor-nrepl" "^clojure.tools.nrepl")
+  "List of regexps used to filter out some vars/symbols/namespaces.
+When nil, nothing is filtered out.  Otherwise, all namespaces matching any
+regexp from this list are dropped out of the \"ns-list\" op.  Also,
+\"apropos\" won't include vars from such namespaces.  This list is passed
+on to the nREPL middleware without any pre-processing.  So the regexps have
+to be in Clojure format (with twice the number of backslashes) and not
+Emacs Lisp."
+  :type '(repeat string)
+  :safe #'listp
+  :group 'cider
+  :package-version '(cider . "0.13.0"))
+
+(defun cider-sync-request:apropos (query &optional search-ns docs-p privates-p case-sensitive-p)
+  "Send \"apropos\" request for regexp QUERY.
+
+Optional arguments include SEARCH-NS, DOCS-P, PRIVATES-P, CASE-SENSITIVE-P."
+  (let* ((query (replace-regexp-in-string "[ \t]+" ".+" query))
+         (response (cider-nrepl-send-sync-request
+                    `("op" "apropos"
+                      "ns" ,(cider-current-ns)
+                      "query" ,query
+                      ,@(when search-ns `("search-ns" ,search-ns))
+                      ,@(when docs-p '("docs?" "t"))
+                      ,@(when privates-p '("privates?" "t"))
+                      ,@(when case-sensitive-p '("case-sensitive?" "t"))
+                      "filter-regexps" ,cider-filtered-namespaces-regexps))))
+    (if (member "apropos-regexp-error" (nrepl-dict-get response "status"))
+        (user-error "Invalid regexp: %s" (nrepl-dict-get response "error-msg"))
+      (nrepl-dict-get response "apropos-matches"))))
+
+(defun cider-sync-request:classpath ()
+  "Return a list of classpath entries."
+  (cider-ensure-op-supported "classpath")
+  (thread-first '("op" "classpath")
+    (cider-nrepl-send-sync-request)
+    (nrepl-dict-get "classpath")))
+
+(defun cider-sync-request:complete (str context)
+  "Return a list of completions for STR using nREPL's \"complete\" op.
+CONTEXT represents a completion context for compliment."
+  (when-let* ((dict (thread-first `("op" "complete"
+                                    "ns" ,(cider-current-ns)
+                                    "symbol" ,str
+                                    "context" ,context)
+                      (cider-nrepl-send-sync-request nil 'abort-on-input))))
+    (nrepl-dict-get dict "completions")))
+
+(defun cider-sync-request:complete-flush-caches ()
+  "Send \"complete-flush-caches\" op to flush Compliment's caches."
+  (cider-nrepl-send-sync-request (list "op" "complete-flush-caches"
+                                       "session" (cider-nrepl-eval-session))
+                                 'abort-on-input))
+
+(defun cider-sync-request:info (symbol &optional class member)
+  "Send \"info\" op with parameters SYMBOL or CLASS and MEMBER."
+  (let ((var-info (thread-first `("op" "info"
+                                  "ns" ,(cider-current-ns)
+                                  ,@(when symbol `("symbol" ,symbol))
+                                  ,@(when class `("class" ,class))
+                                  ,@(when member `("member" ,member)))
+                    (cider-nrepl-send-sync-request))))
+    (if (member "no-info" (nrepl-dict-get var-info "status"))
+        nil
+      var-info)))
+
+(defun cider-sync-request:eldoc (symbol &optional class member)
+  "Send \"eldoc\" op with parameters SYMBOL or CLASS and MEMBER."
+  (when-let* ((eldoc (thread-first `("op" "eldoc"
+                                     "ns" ,(cider-current-ns)
+                                     ,@(when symbol `("symbol" ,symbol))
+                                     ,@(when class `("class" ,class))
+                                     ,@(when member `("member" ,member)))
+                       (cider-nrepl-send-sync-request nil 'abort-on-input))))
+    (if (member "no-eldoc" (nrepl-dict-get eldoc "status"))
+        nil
+      eldoc)))
+
+(defun cider-sync-request:eldoc-datomic-query (symbol)
+  "Send \"eldoc-datomic-query\" op with parameter SYMBOL."
+  (when-let* ((eldoc (thread-first `("op" "eldoc-datomic-query"
+                                     "ns" ,(cider-current-ns)
+                                     ,@(when symbol `("symbol" ,symbol)))
+                       (cider-nrepl-send-sync-request nil 'abort-on-input))))
+    (if (member "no-eldoc" (nrepl-dict-get eldoc "status"))
+        nil
+      eldoc)))
+
+(defun cider-sync-request:spec-list (&optional filter-regex)
+  "Get a list of the available specs in the registry.
+Optional argument FILTER-REGEX filters specs.  By default, all specs are
+returned."
+  (setq filter-regex (or filter-regex ""))
+  (thread-first `("op" "spec-list"
+                  "filter-regex" ,filter-regex)
+    (cider-nrepl-send-sync-request)
+    (nrepl-dict-get "spec-list")))
+
+(defun cider-sync-request:spec-form (spec)
+  "Get SPEC's form from registry."
+  (thread-first `("op" "spec-form"
+                  "spec-name" ,spec)
+    (cider-nrepl-send-sync-request)
+    (nrepl-dict-get "spec-form")))
+
+(defun cider-sync-request:spec-example (spec)
+  "Get an example for SPEC."
+  (thread-first `("op" "spec-example"
+                  "spec-name" ,spec)
+    (cider-nrepl-send-sync-request)
+    (nrepl-dict-get "spec-example")))
+
+(defun cider-sync-request:ns-list ()
+  "Get a list of the available namespaces."
+  (thread-first `("op" "ns-list"
+                  "filter-regexps" ,cider-filtered-namespaces-regexps)
+    (cider-nrepl-send-sync-request)
+    (nrepl-dict-get "ns-list")))
+
+(defun cider-sync-request:ns-vars (ns)
+  "Get a list of the vars in NS."
+  (thread-first `("op" "ns-vars"
+                  "ns" ,ns)
+    (cider-nrepl-send-sync-request)
+    (nrepl-dict-get "ns-vars")))
+
+(defun cider-sync-request:ns-path (ns)
+  "Get the path to the file containing NS."
+  (thread-first `("op" "ns-path"
+                  "ns" ,ns)
+    (cider-nrepl-send-sync-request)
+    (nrepl-dict-get "path")))
+
+(defun cider-sync-request:ns-vars-with-meta (ns)
+  "Get a map of the vars in NS to its metadata information."
+  (thread-first `("op" "ns-vars-with-meta"
+                  "ns" ,ns)
+    (cider-nrepl-send-sync-request)
+    (nrepl-dict-get "ns-vars-with-meta")))
+
+(defun cider-sync-request:ns-load-all ()
+  "Load all project namespaces."
+  (thread-first '("op" "ns-load-all")
+    (cider-nrepl-send-sync-request)
+    (nrepl-dict-get "loaded-ns")))
+
+(defun cider-sync-request:resource (name)
+  "Perform nREPL \"resource\" op with resource name NAME."
+  (thread-first `("op" "resource"
+                  "name" ,name)
+    (cider-nrepl-send-sync-request)
+    (nrepl-dict-get "resource-path")))
+
+(defun cider-sync-request:resources-list ()
+  "Return a list of all resources on the classpath.
+The result entries are relative to the classpath."
+  (when-let* ((resources (thread-first '("op" "resources-list")
+                           (cider-nrepl-send-sync-request)
+                           (nrepl-dict-get "resources-list"))))
+    (seq-map (lambda (resource) (nrepl-dict-get resource "relpath")) resources)))
+
+(defun cider-sync-request:format-code (code)
+  "Perform nREPL \"format-code\" op with CODE."
+  (thread-first `("op" "format-code"
+                  "code" ,code)
+    (cider-nrepl-send-sync-request)
+    (nrepl-dict-get "formatted-code")))
+
+(defun cider-sync-request:format-edn (edn right-margin)
+  "Perform \"format-edn\" op with EDN and RIGHT-MARGIN."
+  (let* ((response (thread-first `("op" "format-edn"
+                                   "edn" ,edn)
+                     (append (cider--nrepl-pprint-request-plist right-margin))
+                     (cider-nrepl-send-sync-request)))
+         (err (nrepl-dict-get response "err")))
+    (when err
+      ;; err will be a stacktrace with a first line that looks like:
+      ;; "clojure.lang.ExceptionInfo: Unmatched delimiter ]"
+      (error (car (split-string err "\n"))))
+    (nrepl-dict-get response "formatted-edn")))
+
+;;; Dealing with input
+;; TODO: Replace this with some nil handler.
+(defun cider-stdin-handler (&optional _buffer)
+  "Make a stdin response handler for _BUFFER."
+  (nrepl-make-response-handler (current-buffer)
+                               (lambda (_buffer _value))
+                               (lambda (_buffer _out))
+                               (lambda (_buffer _err))
+                               nil))
+
+(defun cider-need-input (buffer)
+  "Handle an need-input request from BUFFER."
+  (with-current-buffer buffer
+    (let ((map (make-sparse-keymap)))
+      (set-keymap-parent map minibuffer-local-map)
+      (define-key map (kbd "C-c C-c") 'abort-recursive-edit)
+      (let ((stdin (condition-case nil
+                       (concat (read-from-minibuffer "Stdin: " nil map) "\n")
+                     (quit nil))))
+        (nrepl-request:stdin stdin
+                             (cider-stdin-handler buffer)
+                             (cider-current-repl))))))
+
+(provide 'cider-client)
+
+;;; cider-client.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-client.elc b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-client.elc
new file mode 100644
index 0000000000..141e23bb20
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-client.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-common.el b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-common.el
new file mode 100644
index 0000000000..3bae267a22
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-common.el
@@ -0,0 +1,375 @@
+;;; cider-common.el --- Common use functions         -*- lexical-binding: t; -*-
+
+;; Copyright © 2015-2018  Artur Malabarba
+
+;; Author: Artur Malabarba <bruce.connor.am@gmail.com>
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Common functions that are useful in both Clojure buffers and REPL
+;; buffers.
+
+;;; Code:
+
+(require 'subr-x)
+(require 'cider-compat)
+(require 'nrepl-dict)
+(require 'cider-util)
+(require 'etags) ; for find-tags-marker-ring
+(require 'tramp)
+
+(defcustom cider-prompt-for-symbol t
+  "Controls when to prompt for symbol when a command requires one.
+
+When non-nil, always prompt, and use the symbol at point as the default
+value at the prompt.
+
+When nil, attempt to use the symbol at point for the command, and only
+prompt if that throws an error."
+  :type '(choice (const :tag "always" t)
+                 (const :tag "dwim" nil))
+  :group 'cider
+  :package-version '(cider . "0.9.0"))
+
+(defcustom cider-special-mode-truncate-lines t
+  "If non-nil, contents of CIDER's special buffers will be line-truncated.
+Should be set before loading CIDER."
+  :type 'boolean
+  :group 'cider
+  :package-version '(cider . "0.15.0"))
+
+(defun cider--should-prompt-for-symbol (&optional invert)
+  "Return the value of the variable `cider-prompt-for-symbol'.
+Optionally invert the value, if INVERT is truthy."
+  (if invert (not cider-prompt-for-symbol) cider-prompt-for-symbol))
+
+(defun cider-prompt-for-symbol-function (&optional invert)
+  "Prompt for symbol if funcall `cider--should-prompt-for-symbol' is truthy.
+Otherwise attempt to use the symbol at point for the command, and only
+prompt if that throws an error.
+
+INVERT is used to invert the semantics of the function `cider--should-prompt-for-symbol'."
+  (if (cider--should-prompt-for-symbol invert)
+      #'cider-read-symbol-name
+    #'cider-try-symbol-at-point))
+
+(defun cider--kw-to-symbol (kw)
+  "Convert the keyword KW to a symbol."
+  (when kw
+    (replace-regexp-in-string "\\`:+" "" kw)))
+
+;;; Minibuffer
+(defvar cider-minibuffer-history '()
+  "History list of expressions read from the minibuffer.")
+
+(defvar cider-minibuffer-map
+  (let ((map (make-sparse-keymap)))
+    (set-keymap-parent map minibuffer-local-map)
+    (define-key map (kbd "TAB") #'complete-symbol)
+    (define-key map (kbd "M-TAB") #'complete-symbol)
+    map)
+  "Minibuffer keymap used for reading Clojure expressions.")
+
+(declare-function cider-complete-at-point "cider-completion")
+(declare-function cider-eldoc "cider-eldoc")
+(defun cider-read-from-minibuffer (prompt &optional value)
+  "Read a string from the minibuffer, prompting with PROMPT.
+If VALUE is non-nil, it is inserted into the minibuffer as initial-input.
+PROMPT need not end with \": \". If it doesn't, VALUE is displayed on the
+prompt as a default value (used if the user doesn't type anything) and is
+not used as initial input (input is left empty)."
+  (minibuffer-with-setup-hook
+      (lambda ()
+        (set-syntax-table clojure-mode-syntax-table)
+        (add-hook 'completion-at-point-functions
+                  #'cider-complete-at-point nil t)
+        (setq-local eldoc-documentation-function #'cider-eldoc)
+        (run-hooks 'eval-expression-minibuffer-setup-hook))
+    (let* ((has-colon (string-match ": \\'" prompt))
+           (input (read-from-minibuffer (cond
+                                         (has-colon prompt)
+                                         (value (format "%s (default %s): " prompt value))
+                                         (t (format "%s: " prompt)))
+                                        (when has-colon value) ; initial-input
+                                        cider-minibuffer-map nil
+                                        'cider-minibuffer-history
+                                        (unless has-colon value)))) ; default-value
+      (if (and (equal input "") value (not has-colon))
+          value
+        input))))
+
+(defun cider-read-symbol-name (prompt callback)
+  "Read a symbol name using PROMPT with a default of the one at point.
+Use CALLBACK as the completing read var callback."
+  (funcall callback (cider-read-from-minibuffer
+                     prompt
+                     ;; if the thing at point is a keyword we treat it as symbol
+                     (cider--kw-to-symbol (cider-symbol-at-point 'look-back)))))
+
+(defun cider-try-symbol-at-point (prompt callback)
+  "Call CALLBACK with symbol at point.
+On failure, read a symbol name using PROMPT and call CALLBACK with that."
+  (condition-case nil (funcall callback (cider--kw-to-symbol (cider-symbol-at-point 'look-back)))
+    ('error (funcall callback (cider-read-from-minibuffer prompt)))))
+
+(declare-function cider-mode "cider-mode")
+
+(defun cider-jump-to (buffer &optional pos other-window)
+  "Push current point onto marker ring, and jump to BUFFER and POS.
+POS can be either a number, a cons, or a symbol.
+If a number, it is the character position (the point).
+If a cons, it specifies the position as (LINE . COLUMN).  COLUMN can be nil.
+If a symbol, `cider-jump-to' searches for something that looks like the
+symbol's definition in the file.
+If OTHER-WINDOW is non-nil don't reuse current window."
+  (with-no-warnings
+    (ring-insert find-tag-marker-ring (point-marker)))
+  (if other-window
+      (pop-to-buffer buffer)
+    ;; like switch-to-buffer, but reuse existing window if BUFFER is visible
+    (pop-to-buffer buffer '((display-buffer-reuse-window display-buffer-same-window))))
+  (with-current-buffer buffer
+    (widen)
+    (goto-char (point-min))
+    (cider-mode +1)
+    (cond
+     ;; Line-column specification.
+     ((consp pos)
+      (forward-line (1- (or (car pos) 1)))
+      (if (cdr pos)
+          (move-to-column (cdr pos))
+        (back-to-indentation)))
+     ;; Point specification.
+     ((numberp pos)
+      (goto-char pos))
+     ;; Symbol or string.
+     (pos
+      ;; Try to find (def full-name ...).
+      (if (or (save-excursion
+                (search-forward-regexp (format "(def.*\\s-\\(%s\\)" (regexp-quote pos))
+                                       nil 'noerror))
+              (let ((name (replace-regexp-in-string ".*/" "" pos)))
+                ;; Try to find (def name ...).
+                (or (save-excursion
+                      (search-forward-regexp (format "(def.*\\s-\\(%s\\)" (regexp-quote name))
+                                             nil 'noerror))
+                    ;; Last resort, just find the first occurrence of `name'.
+                    (save-excursion
+                      (search-forward name nil 'noerror)))))
+          (goto-char (match-beginning 0))
+        (message "Can't find %s in %s" pos (buffer-file-name))))
+     (t nil))))
+
+(defun cider--find-buffer-for-file (file)
+  "Return a buffer visiting FILE.
+If FILE is a temp buffer name, return that buffer."
+  (if (string-prefix-p "*" file)
+      file
+    (and file
+         (not (cider--tooling-file-p file))
+         (cider-find-file file))))
+
+(defun cider--jump-to-loc-from-info (info &optional other-window)
+  "Jump to location give by INFO.
+INFO object is returned by `cider-var-info' or `cider-member-info'.
+OTHER-WINDOW is passed to `cider-jump-to'."
+  (let* ((line (nrepl-dict-get info "line"))
+         (file (nrepl-dict-get info "file"))
+         (name (nrepl-dict-get info "name"))
+         ;; the filename might actually be a REPL buffer name
+         (buffer (cider--find-buffer-for-file file)))
+    (if buffer
+        (cider-jump-to buffer (if line (cons line nil) name) other-window)
+      (error "No source location"))))
+
+(declare-function url-filename "url-parse" (cl-x) t)
+
+(defun cider--url-to-file (url)
+  "Return the filename from the resource URL.
+Uses `url-generic-parse-url' to parse the url.  The filename is extracted and
+then url decoded.  If the decoded filename has a Windows device letter followed
+by a colon immediately after the leading '/' then the leading '/' is dropped to
+create a valid path."
+  (let ((filename (url-unhex-string (url-filename (url-generic-parse-url url)))))
+    (if (string-match "^/\\([a-zA-Z]:/.*\\)" filename)
+        (match-string 1 filename)
+      filename)))
+
+(defun cider-make-tramp-prefix (method user host)
+  "Constructs a Tramp file prefix from METHOD, USER, HOST.
+It originated from Tramp's `tramp-make-tramp-file-name'.  The original be
+forced to make full file name with `with-parsed-tramp-file-name', not providing
+prefix only option."
+  (concat tramp-prefix-format
+          (unless (zerop (length method))
+            (concat method tramp-postfix-method-format))
+          (unless (zerop (length user))
+            (concat user tramp-postfix-user-format))
+          (when host
+            (if (string-match tramp-ipv6-regexp host)
+                (concat tramp-prefix-ipv6-format host tramp-postfix-ipv6-format)
+              host))
+          tramp-postfix-host-format))
+
+(defun cider-tramp-prefix (&optional buffer)
+  "Use the filename for BUFFER to determine a tramp prefix.
+Defaults to the current buffer.  Return the tramp prefix, or nil
+if BUFFER is local."
+  (let* ((buffer (or buffer (current-buffer)))
+         (name (or (buffer-file-name buffer)
+                   (with-current-buffer buffer
+                     default-directory))))
+    (when (tramp-tramp-file-p name)
+      (with-parsed-tramp-file-name name v
+        (with-no-warnings
+          (cider-make-tramp-prefix v-method v-user v-host))))))
+
+(defun cider--client-tramp-filename (name &optional buffer)
+  "Return the tramp filename for path NAME relative to BUFFER.
+If BUFFER has a tramp prefix, it will be added as a prefix to NAME.
+If the resulting path is an existing tramp file, it returns the path,
+otherwise, nil."
+  (let* ((buffer (or buffer (current-buffer)))
+         (name (replace-regexp-in-string "^file:" "" name))
+         (name (concat (cider-tramp-prefix buffer) name)))
+    (if (tramp-handle-file-exists-p name)
+        name)))
+
+(defun cider--server-filename (name)
+  "Return the nREPL server-relative filename for NAME."
+  (if (tramp-tramp-file-p name)
+      (with-parsed-tramp-file-name name nil
+        localname)
+    name))
+
+(defvar cider-from-nrepl-filename-function
+  (with-no-warnings
+    (if (eq system-type 'cygwin)
+        #'cygwin-convert-file-name-from-windows
+      #'identity))
+  "Function to translate nREPL namestrings to Emacs filenames.")
+
+(defcustom cider-prefer-local-resources nil
+  "Prefer local resources to remote (tramp) ones when both are available."
+  :type 'boolean
+  :group 'cider)
+
+(defun cider--file-path (path)
+  "Return PATH's local or tramp path using `cider-prefer-local-resources'.
+If no local or remote file exists, return nil."
+  (let* ((local-path (funcall cider-from-nrepl-filename-function path))
+         (tramp-path (and local-path (cider--client-tramp-filename local-path))))
+    (cond ((equal local-path "") "")
+          ((and cider-prefer-local-resources (file-exists-p local-path))
+           local-path)
+          ((and tramp-path (file-exists-p tramp-path))
+           tramp-path)
+          ((and local-path (file-exists-p local-path))
+           local-path))))
+
+(declare-function archive-extract "arc-mode")
+(declare-function archive-zip-extract "arc-mode")
+
+(defun cider-find-file (url)
+  "Return a buffer visiting the file URL if it exists, or nil otherwise.
+If URL has a scheme prefix, it must represent a fully-qualified file path
+or an entry within a zip/jar archive.  If URL doesn't contain a scheme
+prefix and is an absolute path, it is treated as such.  Finally, if URL is
+relative, it is expanded within each of the open Clojure buffers till an
+existing file ending with URL has been found."
+  (require 'arc-mode)
+  (cond ((string-match "^file:\\(.+\\)" url)
+         (when-let* ((file (cider--url-to-file (match-string 1 url)))
+                     (path (cider--file-path file)))
+           (find-file-noselect path)))
+        ((string-match "^\\(jar\\|zip\\):\\(file:.+\\)!/\\(.+\\)" url)
+         (when-let* ((entry (match-string 3 url))
+                     (file  (cider--url-to-file (match-string 2 url)))
+                     (path  (cider--file-path file))
+                     ;; It is used for targeting useless intermediate buffer.
+                     ;; That buffer is made by (find-file path) below.
+                     ;; It has the name which is the last part of the path.
+                     (trash (replace-regexp-in-string "^/.+/" "" path))
+                     (name  (format "%s:%s" path entry)))
+           (or (find-buffer-visiting name)
+               (if (tramp-tramp-file-p path)
+                   (progn
+                     ;; Use emacs built in archiving.
+                     ;; This makes a list of files in archived Zip or Jar.
+                     ;; That list buffer is useless after jumping to the
+                     ;; buffer which has the real definition.
+                     ;; It'll be removed by (kill-buffer trash) below.
+                     (find-file path)
+                     (goto-char (point-min))
+                     ;; Make sure the file path is followed by a newline to
+                     ;; prevent eg. clj matching cljs.
+                     (search-forward (concat entry "\n"))
+                     ;; moves up to matching line
+                     (forward-line -1)
+                     (archive-extract)
+                     ;; Remove useless buffer made by (find-file path) above.
+                     (kill-buffer trash)
+                     (current-buffer))
+                 ;; Use external zip program to just extract the single file
+                 (with-current-buffer (generate-new-buffer
+                                       (file-name-nondirectory entry))
+                   (archive-zip-extract path entry)
+                   (set-visited-file-name name)
+                   (setq-local default-directory (file-name-directory path))
+                   (setq-local buffer-read-only t)
+                   (set-buffer-modified-p nil)
+                   (set-auto-mode)
+                   (current-buffer))))))
+        (t (if-let* ((path (cider--file-path url)))
+               (find-file-noselect path)
+             (unless (file-name-absolute-p url)
+               (let ((cider-buffers (cider-util--clojure-buffers))
+                     (url (file-name-nondirectory url)))
+                 (or (cl-loop for bf in cider-buffers
+                              for path = (with-current-buffer bf
+                                           (expand-file-name url))
+                              if (and path (file-exists-p path))
+                              return (find-file-noselect path))
+                     (cl-loop for bf in cider-buffers
+                              if (string= (buffer-name bf) url)
+                              return bf))))))))
+
+(defun cider--open-other-window-p (arg)
+  "Test prefix value ARG to see if it indicates displaying results in other window."
+  (let ((narg (prefix-numeric-value arg)))
+    (pcase narg
+      (-1 t) ; -
+      (16 t) ; empty empty
+      (_ nil))))
+
+(defun cider-abbreviate-ns (namespace)
+  "Return a string that abbreviates NAMESPACE."
+  (when namespace
+    (let* ((names (reverse (split-string namespace "\\.")))
+           (lastname (car names)))
+      (concat (mapconcat (lambda (s) (concat (substring s 0 1) "."))
+                         (reverse (cdr names))
+                         "")
+              lastname))))
+
+(defun cider-last-ns-segment (namespace)
+  "Return the last segment of NAMESPACE."
+  (when namespace
+    (car (reverse (split-string namespace "\\.")))))
+
+
+(provide 'cider-common)
+;;; cider-common.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-common.elc b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-common.elc
new file mode 100644
index 0000000000..0ecf32e770
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-common.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-compat.el b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-compat.el
new file mode 100644
index 0000000000..e6b64b287c
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-compat.el
@@ -0,0 +1,54 @@
+;;; cider-compat.el --- Functions from newer Emacs versions for compatibility -*- lexical-binding: t -*-
+
+;; Copyright © 2012-2013 Tim King, Phil Hagelberg, Bozhidar Batsov
+;; Copyright © 2013-2018 Bozhidar Batsov, Artur Malabarba and CIDER contributors
+;;
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;; This file is not part of GNU Emacs.
+
+;;; Commentary:
+
+;; Everything here was copied from subr-x for compatibility with
+;; Emacs 25.1.
+
+;;; Code:
+
+(eval-and-compile
+
+  (unless (fboundp 'if-let*)
+    (defmacro if-let* (bindings then &rest else)
+      "Process BINDINGS and if all values are non-nil eval THEN, else ELSE.
+Argument BINDINGS is a list of tuples whose car is a symbol to be
+bound and (optionally) used in THEN, and its cadr is a sexp to be
+evalled to set symbol's value."
+      (declare (indent 2)
+               (debug ([&or (&rest (symbolp form)) (symbolp form)] form body)))
+      `(let* ,(internal--build-bindings bindings)
+         (if ,(car (internal--listify (car (last bindings))))
+             ,then
+           ,@else))))
+
+  (unless (fboundp 'when-let*)
+    (defmacro when-let* (bindings &rest body)
+      "Process BINDINGS and if all values are non-nil eval BODY.
+Argument BINDINGS is a list of tuples whose car is a symbol to be
+bound and (optionally) used in BODY, and its cadr is a sexp to be
+evalled to set symbol's value."
+      (declare (indent 1) (debug if-let*))
+      `(if-let* ,bindings ,(macroexp-progn body)))))
+
+(provide 'cider-compat)
+;;; cider-compat.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-compat.elc b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-compat.elc
new file mode 100644
index 0000000000..be6816c977
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-compat.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-completion.el b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-completion.el
new file mode 100644
index 0000000000..c52769eec9
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-completion.el
@@ -0,0 +1,253 @@
+;;; cider-completion.el --- Smart REPL-powered code completion -*- lexical-binding: t -*-
+
+;; Copyright © 2013-2018 Bozhidar Batsov, Artur Malabarba and CIDER contributors
+;;
+;; Author: Bozhidar Batsov <bozhidar@batsov.com>
+;;         Artur Malabarba <bruce.connor.am@gmail.com>
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;; This file is not part of GNU Emacs.
+
+;;; Commentary:
+
+;; Smart REPL-powered code completion and integration with company-mode.
+
+;;; Code:
+
+(require 'subr-x)
+(require 'thingatpt)
+
+(require 'cider-client)
+(require 'cider-common)
+(require 'cider-eldoc)
+(require 'nrepl-dict)
+
+(defcustom cider-completion-use-context t
+  "When true, uses context at point to improve completion suggestions."
+  :type 'boolean
+  :group 'cider
+  :package-version '(cider . "0.7.0"))
+
+(defcustom cider-annotate-completion-candidates t
+  "When true, annotate completion candidates with some extra information."
+  :type 'boolean
+  :group 'cider
+  :package-version '(cider . "0.8.0"))
+
+(defcustom cider-annotate-completion-function
+  #'cider-default-annotate-completion-function
+  "Controls how the annotations for completion candidates are formatted.
+Must be a function that takes two arguments: the abbreviation of the
+candidate type according to `cider-completion-annotations-alist' and the
+candidate's namespace."
+  :type 'function
+  :group 'cider
+  :package-version '(cider . "0.9.0"))
+
+(defcustom cider-completion-annotations-alist
+  '(("class" "c")
+    ("field" "fi")
+    ("function" "f")
+    ("import" "i")
+    ("keyword" "k")
+    ("local" "l")
+    ("macro" "m")
+    ("method" "me")
+    ("namespace" "n")
+    ("protocol" "p")
+    ("protocol-function" "pf")
+    ("record" "r")
+    ("special-form" "s")
+    ("static-field" "sf")
+    ("static-method" "sm")
+    ("type" "t")
+    ("var" "v"))
+  "Controls the abbreviations used when annotating completion candidates.
+
+Must be a list of elements with the form (TYPE . ABBREVIATION), where TYPE
+is a possible value of the candidate's type returned from the completion
+backend, and ABBREVIATION is a short form of that type."
+  :type '(alist :key-type string :value-type string)
+  :group 'cider
+  :package-version '(cider . "0.9.0"))
+
+(defcustom cider-completion-annotations-include-ns 'unqualified
+  "Controls passing of namespaces to `cider-annotate-completion-function'.
+
+When set to 'always, the candidate's namespace will always be passed if it
+is available.  When set to 'unqualified, the namespace will only be passed
+if the candidate is not namespace-qualified."
+  :type '(choice (const always)
+                 (const unqualified)
+                 (const :tag "never" nil))
+  :group 'cider
+  :package-version '(cider . "0.9.0"))
+
+(defvar cider-completion-last-context nil)
+
+(defun cider-completion-symbol-start-pos ()
+  "Find the starting position of the symbol at point, unless inside a string."
+  (let ((sap (symbol-at-point)))
+    (when (and sap (not (nth 3 (syntax-ppss))))
+      (car (bounds-of-thing-at-point 'symbol)))))
+
+(defun cider-completion-get-context-at-point ()
+  "Extract the context at point.
+If point is not inside the list, returns nil; otherwise return \"top-level\"
+form, with symbol at point replaced by __prefix__."
+  (when (save-excursion
+          (condition-case _
+              (progn
+                (up-list)
+                (check-parens)
+                t)
+            (scan-error nil)
+            (user-error nil)))
+    (save-excursion
+      (let* ((pref-end (point))
+             (pref-start (cider-completion-symbol-start-pos))
+             (context (cider-defun-at-point))
+             (_ (beginning-of-defun))
+             (expr-start (point)))
+        (concat (when pref-start (substring context 0 (- pref-start expr-start)))
+                "__prefix__"
+                (substring context (- pref-end expr-start)))))))
+
+(defun cider-completion-get-context ()
+  "Extract context depending on `cider-completion-use-context' and major mode."
+  (let ((context (if (and cider-completion-use-context
+                          ;; Important because `beginning-of-defun' and
+                          ;; `ending-of-defun' work incorrectly in the REPL
+                          ;; buffer, so context extraction fails there.
+                          (derived-mode-p 'clojure-mode))
+                     (or (cider-completion-get-context-at-point)
+                         "nil")
+                   "nil")))
+    (if (string= cider-completion-last-context context)
+        ":same"
+      (setq cider-completion-last-context context)
+      context)))
+
+(defun cider-completion--parse-candidate-map (candidate-map)
+  "Get \"candidate\" from CANDIDATE-MAP.
+Put type and ns properties on the candidate"
+  (let ((candidate (nrepl-dict-get candidate-map "candidate"))
+        (type (nrepl-dict-get candidate-map "type"))
+        (ns (nrepl-dict-get candidate-map "ns")))
+    (put-text-property 0 1 'type type candidate)
+    (put-text-property 0 1 'ns ns candidate)
+    candidate))
+
+(defun cider-complete (str)
+  "Complete STR with context at point."
+  (let* ((context (cider-completion-get-context))
+         (candidates (cider-sync-request:complete str context)))
+    (mapcar #'cider-completion--parse-candidate-map candidates)))
+
+(defun cider-completion--get-candidate-type (symbol)
+  "Get candidate type for SYMBOL."
+  (let ((type (get-text-property 0 'type symbol)))
+    (or (cadr (assoc type cider-completion-annotations-alist))
+        type)))
+
+(defun cider-completion--get-candidate-ns (symbol)
+  "Get candidate ns for SYMBOL."
+  (when (or (eq 'always cider-completion-annotations-include-ns)
+            (and (eq 'unqualified cider-completion-annotations-include-ns)
+                 (not (cider-namespace-qualified-p symbol))))
+    (get-text-property 0 'ns symbol)))
+
+(defun cider-default-annotate-completion-function (type ns)
+  "Get completion function based on TYPE and NS."
+  (concat (when ns (format " (%s)" ns))
+          (when type (format " <%s>" type))))
+
+(defun cider-annotate-symbol (symbol)
+  "Return a string suitable for annotating SYMBOL.
+If SYMBOL has a text property `type` whose value is recognised, its
+abbreviation according to `cider-completion-annotations-alist' will be
+used.  If `type` is present but not recognised, its value will be used
+unaltered.  If SYMBOL has a text property `ns`, then its value will be used
+according to `cider-completion-annotations-include-ns'.  The formatting is
+performed by `cider-annotate-completion-function'."
+  (when cider-annotate-completion-candidates
+    (let* ((type (cider-completion--get-candidate-type symbol))
+           (ns (cider-completion--get-candidate-ns symbol)))
+      (funcall cider-annotate-completion-function type ns))))
+
+(defun cider-complete-at-point ()
+  "Complete the symbol at point."
+  (when-let* ((bounds (bounds-of-thing-at-point 'symbol)))
+    (when (and (cider-connected-p)
+               (not (or (cider-in-string-p) (cider-in-comment-p))))
+      (list (car bounds) (cdr bounds)
+            (completion-table-dynamic #'cider-complete)
+            :annotation-function #'cider-annotate-symbol
+            :company-doc-buffer #'cider-create-doc-buffer
+            :company-location #'cider-company-location
+            :company-docsig #'cider-company-docsig))))
+
+(defun cider-completion-flush-caches ()
+  "Force Compliment to refill its caches.
+This command should be used if Compliment fails to pick up new classnames
+and methods from dependencies that were loaded dynamically after the REPL
+has started."
+  (interactive)
+  (cider-sync-request:complete-flush-caches))
+
+(defun cider-company-location (var)
+  "Open VAR's definition in a buffer.
+Returns the cons of the buffer itself and the location of VAR's definition
+in the buffer."
+  (when-let* ((info (cider-var-info var))
+              (file (nrepl-dict-get info "file"))
+              (line (nrepl-dict-get info "line"))
+              (buffer (cider-find-file file)))
+    (with-current-buffer buffer
+      (save-excursion
+        (goto-char (point-min))
+        (forward-line (1- line))
+        (cons buffer (point))))))
+
+(defun cider-company-docsig (thing)
+  "Return signature for THING."
+  (let* ((eldoc-info (cider-eldoc-info thing))
+         (ns (lax-plist-get eldoc-info "ns"))
+         (symbol (lax-plist-get eldoc-info "symbol"))
+         (arglists (lax-plist-get eldoc-info "arglists")))
+    (when eldoc-info
+      (format "%s: %s"
+              (cider-eldoc-format-thing ns symbol thing
+                                        (cider-eldoc-thing-type eldoc-info))
+              (cider-eldoc-format-arglist arglists 0)))))
+
+;; Fuzzy completion for company-mode
+
+(defun cider-company-unfiltered-candidates (string &rest _)
+  "Return CIDER completion candidates for STRING as is, unfiltered."
+  (cider-complete string))
+
+(add-to-list 'completion-styles-alist
+             '(cider
+               cider-company-unfiltered-candidates
+               cider-company-unfiltered-candidates
+               "CIDER backend-driven completion style."))
+
+(defun cider-company-enable-fuzzy-completion ()
+  "Enable backend-driven fuzzy completion in the current buffer."
+  (setq-local completion-styles '(cider)))
+
+(provide 'cider-completion)
+;;; cider-completion.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-completion.elc b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-completion.elc
new file mode 100644
index 0000000000..688ce414a0
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-completion.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-connection.el b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-connection.el
new file mode 100644
index 0000000000..c50610d42b
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-connection.el
@@ -0,0 +1,646 @@
+;;; cider-connection.el --- Connection and session life-cycle management for CIDER -*- lexical-binding: t -*-
+;;
+;; Copyright © 2018 Artur Malabarba, Bozhidar Batsov, Vitalie Spinu and CIDER contributors
+;;
+;; Author: Artur Malabarba <bruce.connor.am@gmail.com>
+;;         Bozhidar Batsov <bozhidar@batsov.com>
+;;         Vitalie Spinu <spinuvit@gmail.com>
+;;
+;; Keywords: languages, clojure, cider
+;;
+;; This program 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.
+;;
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+;;
+;; This file is not part of GNU Emacs.
+;;
+;;
+;;; Commentary:
+;;
+;;
+;;; Code:
+
+(require 'nrepl-client)
+(require 'cl-lib)
+(require 'sesman)
+
+(defcustom cider-connection-message-fn #'cider-random-words-of-inspiration
+  "The function to use to generate the message displayed on connect.
+When set to nil no additional message will be displayed.  A good
+alternative to the default is `cider-random-tip'."
+  :type 'function
+  :group 'cider
+  :package-version '(cider . "0.11.0"))
+
+(defcustom cider-redirect-server-output-to-repl  t
+  "Controls whether nREPL server output would be redirected to the REPL.
+When non-nil the output would end up in both the nrepl-server buffer (when
+available) and the matching REPL buffer."
+  :type 'boolean
+  :group 'cider
+  :safe #'booleanp
+  :package-version '(cider . "0.17.0"))
+
+(defcustom cider-auto-mode t
+  "When non-nil, automatically enable cider mode for all Clojure buffers."
+  :type 'boolean
+  :group 'cider
+  :safe #'booleanp
+  :package-version '(cider . "0.9.0"))
+
+(defconst cider-required-nrepl-version "0.2.12"
+  "The minimum nREPL version that's known to work properly with CIDER.")
+
+
+;;; Connect
+
+(defun cider-nrepl-connect (params)
+  "Start nrepl client and create the REPL.
+PARAMS is a plist containing :host, :port, :server and other parameters for
+`cider-repl-create'."
+  (process-buffer
+   (nrepl-start-client-process
+    (plist-get params :host)
+    (plist-get params :port)
+    (plist-get params :server)
+    (lambda (_)
+      (cider-repl-create params)))))
+
+(defun cider-connected-p ()
+  "Return t if CIDER is currently connected, nil otherwise."
+  (process-live-p (get-buffer-process (cider-current-repl))))
+
+(defun cider-ensure-connected ()
+  "Ensure there is a linked CIDER session."
+  (sesman-ensure-session 'CIDER))
+
+(defun cider--gather-connect-params (params proc-buffer)
+  "Gather all relevant connection parameters into PARAMS plist.
+PROC-BUFFER is either server or client buffer."
+  (with-current-buffer proc-buffer
+    (unless nrepl-endpoint
+      (error "This is not a REPL or SERVER buffer; is there an active REPL?"))
+    (let ((server-buf (if (nrepl-server-p proc-buffer)
+                          proc-buffer
+                        nrepl-server-buffer)))
+      (cl-loop for l on nrepl-endpoint by #'cddr
+               do (setq params (plist-put params (car l) (cadr l))))
+      (setq params (thread-first params
+                     (plist-put :project-dir nrepl-project-dir)))
+      (when (buffer-live-p server-buf)
+        (setq params (thread-first params
+                       (plist-put :server (get-buffer-process server-buf))
+                       (plist-put :server-command nrepl-server-command))))
+      ;; repl-specific parameters (do not pollute server params!)
+      (when (nrepl-server-p proc-buffer)
+        (setq params (thread-first params
+                       (plist-put :repl-type cider-repl-type)
+                       (plist-put :repl-init-function cider-repl-init-function))))
+      params)))
+
+(defun cider--close-buffer (buffer)
+  "Close the BUFFER and kill its associated process (if any)."
+  (when (buffer-live-p buffer)
+    (when-let* ((proc (get-buffer-process buffer)))
+      (when (process-live-p proc)
+        (delete-process proc)))
+    (kill-buffer buffer)))
+
+(declare-function cider-repl-emit-interactive-stderr "cider-repl")
+(defun cider--close-connection (repl &optional no-kill)
+  "Close connection associated with REPL.
+When NO-KILL is non-nil stop the connection but don't kill the REPL
+buffer."
+  (when (buffer-live-p repl)
+    (with-current-buffer repl
+      (when spinner-current (spinner-stop))
+      (when nrepl-tunnel-buffer
+        (cider--close-buffer nrepl-tunnel-buffer))
+      (when no-kill
+        ;; inform sentinel not to kill the server, if any
+        (thread-first (get-buffer-process repl)
+          (process-plist)
+          (plist-put :no-server-kill t))))
+    (let ((proc (get-buffer-process repl)))
+      (when (and (process-live-p proc)
+                 (or (not nrepl-server-buffer)
+                     ;; Sync request will hang if the server is dead.
+                     (process-live-p (get-buffer-process nrepl-server-buffer))))
+        (nrepl-sync-request:close repl)
+        (delete-process proc)))
+    (when-let* ((messages-buffer (and nrepl-log-messages
+                                      (nrepl-messages-buffer repl))))
+      (kill-buffer messages-buffer))
+    (if no-kill
+        (with-current-buffer repl
+          (goto-char (point-max))
+          (cider-repl-emit-interactive-stderr
+           (format "*** Closed on %s ***\n" (current-time-string))))
+      (kill-buffer repl)))
+  (when repl
+    (sesman-remove-object 'CIDER nil repl (not no-kill) t)))
+
+(defun cider-emit-manual-warning (section-id format &rest args)
+  "Emit a warning to the REPL and link to the online manual.
+SECTION-ID is the section to link to.  The link is added on the last line.
+FORMAT is a format string to compile with ARGS and display on the REPL."
+  (let ((message (apply #'format format args)))
+    (cider-repl-emit-interactive-stderr
+     (concat "WARNING: " message "\n         "
+             (cider--manual-button "More information" section-id)
+             "."))))
+
+(defvar cider-version)
+(defun cider--check-required-nrepl-version ()
+  "Check whether we're using a compatible nREPL version."
+  (if-let* ((nrepl-version (cider--nrepl-version)))
+      (when (version< nrepl-version cider-required-nrepl-version)
+        (cider-emit-manual-warning "troubleshooting/#warning-saying-you-have-to-use-nrepl-0212"
+                                   "CIDER requires nREPL %s (or newer) to work properly"
+                                   cider-required-nrepl-version))
+    (cider-emit-manual-warning "troubleshooting/#warning-saying-you-have-to-use-nrepl-0212"
+                               "Can't determine nREPL's version.\nPlease, update nREPL to %s."
+                               cider-required-nrepl-version)))
+
+(defvar cider-minimum-clojure-version)
+(defun cider--check-clojure-version-supported ()
+  "Ensure that we are meeting the minimum supported version of Clojure."
+  (if-let* ((clojure-version (cider--clojure-version)))
+      (when (version< clojure-version cider-minimum-clojure-version)
+        (cider-emit-manual-warning "installation/#prerequisites"
+                                   "Clojure version (%s) is not supported (minimum %s). CIDER will not work."
+                                   clojure-version cider-minimum-clojure-version))
+    (cider-emit-manual-warning "installation/#prerequisites"
+                               "Can't determine Clojure's version. CIDER requires Clojure %s (or newer)."
+                               cider-minimum-clojure-version)))
+
+(defun cider--check-middleware-compatibility ()
+  "CIDER frontend/backend compatibility check.
+Retrieve the underlying connection's CIDER-nREPL version and checks if the
+middleware used is compatible with CIDER.  If not, will display a warning
+message in the REPL area."
+  (let* ((version-dict        (nrepl-aux-info "cider-version" (cider-current-repl)))
+         (middleware-version  (nrepl-dict-get version-dict "version-string" "not installed")))
+    (unless (equal cider-version middleware-version)
+      (cider-emit-manual-warning "troubleshooting/#cider-complains-of-the-cider-nrepl-version"
+                                 "CIDER's version (%s) does not match cider-nrepl's version (%s). Things will break!"
+                                 cider-version middleware-version))))
+
+(declare-function cider-interactive-eval-handler "cider-eval")
+;; TODO: Use some null handler here
+(defun cider--subscribe-repl-to-server-out ()
+  "Subscribe to the nREPL server's *out*."
+  (cider-nrepl-send-request '("op" "out-subscribe")
+                            (cider-interactive-eval-handler (current-buffer))))
+
+(declare-function cider-mode "cider-mode")
+(defun cider-enable-on-existing-clojure-buffers ()
+  "Enable CIDER's minor mode on existing Clojure buffers.
+See command `cider-mode'."
+  (interactive)
+  (add-hook 'clojure-mode-hook #'cider-mode)
+  (dolist (buffer (cider-util--clojure-buffers))
+    (with-current-buffer buffer
+      (cider-mode +1))))
+
+(defun cider-disable-on-existing-clojure-buffers ()
+  "Disable command `cider-mode' on existing Clojure buffers."
+  (interactive)
+  (dolist (buffer (cider-util--clojure-buffers))
+    (with-current-buffer buffer
+      (cider-mode -1))))
+
+(defun cider-possibly-disable-on-existing-clojure-buffers ()
+  "If not connected, disable command `cider-mode' on existing Clojure buffers."
+  (unless (cider-connected-p)
+    (cider-disable-on-existing-clojure-buffers)))
+
+(declare-function cider--debug-init-connection "cider-debug")
+(declare-function cider-repl-init "cider-repl")
+(defun cider--connected-handler ()
+  "Handle CIDER initialization after nREPL connection has been established.
+This function is appended to `nrepl-connected-hook' in the client process
+buffer."
+  ;; `nrepl-connected-hook' is run in the connection buffer
+  ;; `cider-enlighten-mode' changes eval to include the debugger, so we inhibit
+  ;; it here as the debugger isn't necessarily initialized yet
+  (let ((cider-enlighten-mode nil))
+    ;; after initialization, set mode-line and buffer name.
+    (cider-set-repl-type cider-repl-type)
+    (cider-repl-init (current-buffer))
+    (cider--check-required-nrepl-version)
+    (cider--check-clojure-version-supported)
+    (cider--check-middleware-compatibility)
+    (when cider-redirect-server-output-to-repl
+      (cider--subscribe-repl-to-server-out))
+    (when cider-auto-mode
+      (cider-enable-on-existing-clojure-buffers))
+    ;; Middleware on cider-nrepl's side is deferred until first usage, but
+    ;; loading middleware concurrently can lead to occasional "require" issues
+    ;; (likely a Clojure bug). Thus, we load the heavy debug middleware towards
+    ;; the end, allowing for the faster "server-out" middleware to load
+    ;; first.
+    (cider--debug-init-connection)
+    (when cider-repl-init-function
+      (funcall cider-repl-init-function))
+    (run-hooks 'cider-connected-hook)))
+
+(defun cider--disconnected-handler ()
+  "Cleanup after nREPL connection has been lost or closed.
+This function is appended to `nrepl-disconnected-hook' in the client
+process buffer."
+  ;; `nrepl-connected-hook' is run in the connection buffer
+  (cider-possibly-disable-on-existing-clojure-buffers)
+  (run-hooks 'cider-disconnected-hook))
+
+
+;;; Connection Info
+
+(defun cider--java-version ()
+  "Retrieve the underlying connection's Java version."
+  (with-current-buffer (cider-current-repl)
+    (when nrepl-versions
+      (thread-first nrepl-versions
+        (nrepl-dict-get "java")
+        (nrepl-dict-get "version-string")))))
+
+(defun cider--clojure-version ()
+  "Retrieve the underlying connection's Clojure version."
+  (with-current-buffer (cider-current-repl)
+    (when nrepl-versions
+      (thread-first nrepl-versions
+        (nrepl-dict-get "clojure")
+        (nrepl-dict-get "version-string")))))
+
+(defun cider--nrepl-version ()
+  "Retrieve the underlying connection's nREPL version."
+  (with-current-buffer (cider-current-repl)
+    (when nrepl-versions
+      (thread-first nrepl-versions
+        (nrepl-dict-get "nrepl")
+        (nrepl-dict-get "version-string")))))
+
+(defun cider--connection-info (connection-buffer &optional genericp)
+  "Return info about CONNECTION-BUFFER.
+Info contains project name, current REPL namespace, host:port endpoint and
+Clojure version.  When GENERICP is non-nil, don't provide specific info
+about this buffer (like variable `cider-repl-type')."
+  (with-current-buffer connection-buffer
+    (format "%s%s@%s:%s (Java %s, Clojure %s, nREPL %s)"
+            (if genericp "" (upcase (concat cider-repl-type " ")))
+            (or (cider--project-name nrepl-project-dir) "<no project>")
+            (plist-get nrepl-endpoint :host)
+            (plist-get nrepl-endpoint :port)
+            (cider--java-version)
+            (cider--clojure-version)
+            (cider--nrepl-version))))
+
+
+;;; Cider's Connection Management UI
+
+(defun cider-quit ()
+  "Quit the currently active CIDER connection."
+  (interactive)
+  (cider-ensure-connected)
+  (let ((connection (cider-current-repl)))
+    (cider--close-connection connection))
+  ;; if there are no more connections we can kill all ancillary buffers
+  (unless (cider-connected-p)
+    (cider-close-ancillary-buffers)))
+
+(defun cider-restart ()
+  "Restart the currently active CIDER connection.
+Don't restart the server or other connections within the same session.  Use
+`sesman-restart' to restart the entire session."
+  (interactive)
+  (let* ((repl (or (cider-current-repl)
+                   (user-error "No linked REPL")))
+         (params (thread-first (cider--gather-connect-params nil repl)
+                   (plist-put :session-name (sesman-session-name-for-object 'CIDER repl))
+                   (plist-put :repl-buffer repl))))
+    (cider--close-connection repl 'no-kill)
+    (cider-nrepl-connect params)))
+
+(defun cider-close-ancillary-buffers ()
+  "Close buffers that are shared across connections."
+  (interactive)
+  (dolist (buf-name cider-ancillary-buffers)
+    (when (get-buffer buf-name)
+      (kill-buffer buf-name))))
+
+(defun cider-describe-current-connection ()
+  "Display information about the current connection."
+  (interactive)
+  (message "%s" (cider--connection-info (cider-current-repl nil 'ensure))))
+(define-obsolete-function-alias 'cider-display-connection-info 'cider-describe-current-connection "0.18.0")
+
+(defconst cider-nrepl-session-buffer "*cider-nrepl-session*")
+
+(defun cider-describe-nrepl-session ()
+  "Describe an nREPL session."
+  (interactive)
+  (cider-ensure-connected)
+  (let* ((repl (cider-current-repl nil 'ensure))
+         (selected-session (completing-read "Describe nREPL session: " (nrepl-sessions repl))))
+    (when (and selected-session (not (equal selected-session "")))
+      (let* ((session-info (nrepl-sync-request:describe repl))
+             (ops (nrepl-dict-keys (nrepl-dict-get session-info "ops")))
+             (session-id (nrepl-dict-get session-info "session"))
+             (session-type (cond
+                            ((equal session-id (cider-nrepl-eval-session)) "Active eval")
+                            ((equal session-id (cider-nrepl-tooling-session)) "Active tooling")
+                            (t "Unknown"))))
+        (with-current-buffer (cider-popup-buffer cider-nrepl-session-buffer 'select nil 'ancillary)
+          (read-only-mode -1)
+          (insert (format "Session: %s\n" session-id)
+                  (format "Type: %s session\n" session-type)
+                  (format "Supported ops:\n"))
+          (mapc (lambda (op) (insert (format "  * %s\n" op))) ops)))
+      (display-buffer cider-nrepl-session-buffer))))
+
+
+;;; Sesman's Session-Wise Management UI
+
+(cl-defmethod sesman-more-relevant-p ((_system (eql CIDER)) session1 session2)
+  (sesman-more-recent-p (cdr session1) (cdr session2)))
+
+(cl-defmethod sesman-session-info ((_system (eql CIDER)) session)
+  (interactive "P")
+  (let ((repl (cadr session)))
+    (format "\t%s: %s\n\tREPLS: %s"
+            (if (buffer-local-value 'nrepl-server-buffer repl) "SERVER" "CONNECTION")
+            (cider--connection-info repl t)
+            (mapconcat #'buffer-name (cdr session) ", "))))
+
+(declare-function cider "cider")
+(cl-defmethod sesman-start-session ((_system (eql CIDER)))
+  "Start a connection of any type interactively.
+Fallback on `cider' command."
+  (call-interactively #'cider))
+
+(cl-defmethod sesman-quit-session ((_system (eql CIDER)) session)
+  (mapc #'cider--close-connection (cdr session))
+  ;; if there are no more connections we can kill all ancillary buffers
+  (unless (cider-connected-p)
+    (cider-close-ancillary-buffers)))
+
+(cl-defmethod sesman-restart-session ((_system (eql CIDER)) session)
+  (let* ((repls (cdr session))
+         (s-buf (seq-some (lambda (r)
+                            (buffer-local-value 'nrepl-server-buffer r))
+                          repls))
+         (s-params (cider--gather-connect-params nil s-buf))
+         (ses-name (car session)))
+    ;; 1) kill all connections, but keep the buffers
+    (mapc (lambda (conn)
+            (cider--close-connection conn 'no-kill))
+          repls)
+    ;; 2) kill the server
+    (message "Waiting for CIDER server to quit...")
+    (nrepl-kill-server-buffer s-buf)
+    ;; 3) start server
+    (nrepl-start-server-process
+     (plist-get s-params :project-dir)
+     (plist-get s-params :server-command)
+     (lambda (server-buf)
+       ;; 4) restart the repls reusing the buffer
+       (dolist (r repls)
+         (cider-nrepl-connect
+          (thread-first ()
+            (cider--gather-connect-params r)
+            ;; server params (:port, :project-dir etc) have precedence
+            (cider--gather-connect-params server-buf)
+            (plist-put :session-name ses-name)
+            (plist-put :repl-buffer r))))
+       (message "Restarted CIDER %s session" ses-name)))))
+
+(defun cider-new-session-name (params)
+  "Create new session name given plist of connection PARAMS."
+  (let* ((dir (or (plist-get params :project-dir)
+                  (clojure-project-dir (cider-current-dir))
+                  default-directory))
+         (host (plist-get params :host))
+         ;; showing host:port on remotes only
+         (host-port (if (not (or (null host)
+                                 (equal host "localhost")
+                                 (equal host "127.0.0.1")))
+                        (format ":%s:%s" host (plist-get params :port))
+                      ""))
+         (root-name (file-name-nondirectory (directory-file-name dir)))
+         (name (format "%s%s" root-name host-port))
+         (other-names (mapcar #'car (sesman-sessions 'CIDER)))
+         (i 2))
+    (while (member name other-names)
+      (setq name (concat root-name "#" (number-to-string i))
+            i (+ i 1)))
+    name))
+
+
+;;; REPL Buffer Init
+
+(defvar-local cider-repl-type nil
+  "The type of this REPL buffer, usually either \"clj\" or \"cljs\".")
+
+(defun cider-repl-type (repl-buffer)
+  "Get REPL-BUFFER's type."
+  (buffer-local-value 'cider-repl-type repl-buffer))
+
+(defun cider-repl-type-for-buffer (&optional buffer)
+  "Return the matching connection type (clj or cljs) for BUFFER.
+BUFFER defaults to the `current-buffer'.  In cljc buffers return
+\"multi\". This function infers connection type based on the major mode.
+For the REPL type use the function `cider-repl-type'."
+  (with-current-buffer (or buffer (current-buffer))
+    (cond
+     ((derived-mode-p 'clojurescript-mode) "cljs")
+     ((derived-mode-p 'clojurec-mode) "multi")
+     ((derived-mode-p 'clojure-mode) "clj")
+     (cider-repl-type))))
+
+(defun cider-set-repl-type (&optional type)
+  "Set REPL TYPE to \"clj\" or \"cljs\".
+Assume that the current buffer is a REPL."
+  (interactive)
+  (let ((type (or type (completing-read
+                        (format "Set REPL type (currently `%s') to: "
+                                cider-repl-type)
+                        '("clj" "cljs")))))
+    (when (or (not (equal cider-repl-type type))
+              (null mode-name))
+      (setq cider-repl-type type)
+      (setq mode-name (format "REPL[%s]" type))
+      (rename-buffer (nrepl-repl-buffer-name))
+      (when (and nrepl-log-messages nrepl-messages-buffer)
+        (let ((mbuf-name (nrepl-messages-buffer-name (current-buffer))))
+          (with-current-buffer nrepl-messages-buffer
+            (rename-buffer mbuf-name)))))))
+
+(declare-function cider-default-err-handler "cider-eval")
+(declare-function cider-repl-mode "cider-repl")
+(declare-function cider-repl--state-handler "cider-repl")
+(declare-function cider-repl-reset-markers "cider-repl")
+(defvar-local cider-repl-init-function nil)
+(defun cider-repl-create (params)
+  "Create new repl buffer.
+PARAMS is a plist which contains :repl-type, :host, :port, :project-dir,
+:repl-init-function and :session-name.  When non-nil, :repl-init-function
+must be a function with no arguments which is called after repl creation
+function with the repl buffer set as current."
+  ;; Connection might not have been set as yet. Please don't send requests in
+  ;; this function, but use cider--connected-handler instead.
+  (let ((buffer (or (plist-get params :repl-buffer)
+                    (get-buffer-create (generate-new-buffer-name "*cider-uninitialized-repl*")))))
+    (with-current-buffer buffer
+      (let ((ses-name (or (plist-get params :session-name)
+                          (cider-new-session-name params))))
+        (sesman-add-object 'CIDER ses-name buffer t))
+      (unless (derived-mode-p 'cider-repl-mode)
+        (cider-repl-mode))
+      (setq nrepl-err-handler #'cider-default-err-handler
+            ;; used as a new-repl marker in cider-set-repl-type
+            mode-name nil
+            ;; REPLs start with clj and then "upgrade" to a different type
+            cider-repl-type "clj"
+            ;; ran at the end of cider--connected-handler
+            cider-repl-init-function (plist-get params :repl-init-function))
+      (cider-repl-reset-markers)
+      (add-hook 'nrepl-response-handler-functions #'cider-repl--state-handler nil 'local)
+      (add-hook 'nrepl-connected-hook 'cider--connected-handler nil 'local)
+      (add-hook 'nrepl-disconnected-hook 'cider--disconnected-handler nil 'local)
+      (current-buffer))))
+
+
+;;; Current/other REPLs
+
+(defun cider-current-repl (&optional type ensure)
+  "Get the most recent REPL of TYPE from the current session.
+TYPE is either \"clj\", \"cljs\" or \"multi\".  When nil, infer the type
+from the current buffer.  If ENSURE is non-nil, throw an error if either
+there is no linked session or there is no REPL of TYPE within the current
+session."
+  (if (and (derived-mode-p 'cider-repl-mode)
+           (or (null type)
+               (string= cider-repl-type type)))
+      ;; shortcut when in REPL buffer
+      (current-buffer)
+    (let* ((type (or type (cider-repl-type-for-buffer)))
+           (repls (cider-repls type ensure))
+           (repl (if (<= (length repls) 1)
+                     (car repls)
+                   ;; pick the most recent one
+                   (seq-find (lambda (b)
+                               (member b repls))
+                             (buffer-list)))))
+      (if (and ensure (null repl))
+          (user-error "No %s REPL in current session (%s)"
+                      type (car (sesman-current-session 'CIDER)))
+        repl))))
+
+(defun cider-repls (&optional type ensure)
+  "Return cider REPLs of TYPE from the current session.
+If TYPE is nil or \"multi\", return all repls.  If ENSURE is non-nil, throw
+an error if no linked session exists."
+  (let ((repls (cdr (if ensure
+                        (sesman-ensure-session 'CIDER)
+                      (sesman-current-session 'CIDER)))))
+    (if (or (null type) (equal type "multi"))
+        repls
+      (seq-filter (lambda (b)
+                    (string= type (cider-repl-type b)))
+                  repls))))
+
+(defun cider-map-repls (which function)
+  "Call FUNCTION once for each appropriate REPL as indicated by WHICH.
+The function is called with one argument, the REPL buffer.  The appropriate
+connections are found by inspecting the current buffer.  WHICH is one of
+the following keywords:
+ :auto - Act on the connections whose type matches the current buffer.  In
+     `cljc' files, mapping happens over both types of REPLs.
+ :clj (:cljs) - Map over clj (cljs)) REPLs only.
+ :clj-strict (:cljs-strict) - Map over clj (cljs) REPLs but signal a
+      `user-error' in `clojurescript-mode' (`clojure-mode').  Use this for
+      commands only supported in Clojure (ClojureScript).
+Error is signaled if no REPL buffer of specified type exists."
+  (declare (indent 1))
+  (let ((cur-type (cider-repl-type-for-buffer)))
+    (cl-case which
+      (:clj-strict (when (equal cur-type "cljs")
+                     (user-error "Clojure-only operation requested in a ClojureScript buffer")))
+      (:cljs-strict (when (equal cur-type "clj")
+                      (user-error "ClojureScript-only operation requested in a Clojure buffer"))))
+    (let* ((type (cl-case which
+                   ((:clj :clj-strict) "clj")
+                   ((:cljs :cljs-strict) "cljs")
+                   (:auto cur-type)))
+           (repls (cider-repls type 'ensure)))
+      (mapcar function repls))))
+
+;; REPLs double as connections in CIDER, so it's useful to be able to refer to
+;; them as connections in certain contexts.
+(defalias 'cider-current-connection #'cider-current-repl)
+(defalias 'cider-connections #'cider-repls)
+(defalias 'cider-map-connections #'cider-map-repls)
+(defalias 'cider-connection-type-for-buffer #'cider-repl-type-for-buffer)
+
+
+;; Deprecation after #2324
+
+(define-obsolete-function-alias 'cider-current-repl-buffer 'cider-current-repl "0.18")
+(define-obsolete-function-alias 'cider-repl-buffers 'cider-repls "0.18")
+(define-obsolete-function-alias 'cider-current-session 'cider-nrepl-eval-session "0.18")
+(define-obsolete-function-alias 'cider-current-tooling-session 'cider-nrepl-tooling-session "0.18")
+(define-obsolete-function-alias 'cider-display-connection-info 'cider-describe-current-connection "0.18")
+(define-obsolete-function-alias 'nrepl-connection-buffer-name 'nrepl-repl-buffer-name "0.18")
+(define-obsolete-function-alias 'cider-repl-set-type 'cider-set-repl-type "0.18")
+
+(make-obsolete 'cider-assoc-buffer-with-connection 'sesman-link-with-buffer "0.18")
+(make-obsolete 'cider-assoc-project-with-connection 'sesman-link-with-project "0.18")
+(make-obsolete 'cider-change-buffers-designation nil "0.18")
+(make-obsolete 'cider-clear-buffer-local-connection nil "0.18")
+(make-obsolete 'cider-close-nrepl-session 'cider-quit "0.18")
+(make-obsolete 'cider-create-sibling-cljs-repl 'cider-connect-sibling-cljs "0.18")
+(make-obsolete 'cider-current-messages-buffer nil "0.18")
+(make-obsolete 'cider-default-connection "see sesman." "0.18")
+(make-obsolete 'cider-extract-designation-from-current-repl-buffer nil "0.18")
+(make-obsolete 'cider-find-connection-buffer-for-project-directory 'sesman-linked-sessions "0.18")
+(make-obsolete 'cider-find-reusable-repl-buffer nil "0.18")
+(make-obsolete 'cider-make-connection-default "see sesman." "0.18")
+(make-obsolete 'cider-other-connection nil "0.18")
+(make-obsolete 'cider-project-connections 'sesman-linked-sessions "0.18")
+(make-obsolete 'cider-project-connections-types nil "0.18")
+(make-obsolete 'cider-prompt-for-project-on-connect nil "0.18")
+(make-obsolete 'cider-read-connection `sesman-ask-for-session "0.18")
+(make-obsolete 'cider-replicate-connection nil "0.18")
+(make-obsolete 'cider-request-dispatch "see sesman." "0.18")
+(make-obsolete 'cider-rotate-default-connection "see sesman." "0.18")
+(make-obsolete 'cider-toggle-buffer-connection nil "0.18")
+(make-obsolete 'cider-toggle-request-dispatch nil "0.18")
+(make-obsolete 'nrepl-connection-buffer-name-template 'nrepl-repl-buffer-name-template "0.18")
+(make-obsolete 'nrepl-create-client-buffer-function nil "0.18")
+(make-obsolete 'nrepl-post-client-callback nil "0.18")
+(make-obsolete 'nrepl-prompt-to-kill-server-buffer-on-quit nil "0.18")
+(make-obsolete 'nrepl-use-this-as-repl-buffer nil "0.18")
+
+;; connection manager
+(make-obsolete 'cider-client-name-repl-type "see sesman." "0.18")
+(make-obsolete 'cider-connection-browser "see sesman." "0.18")
+(make-obsolete 'cider-connections-buffer-mode "see sesman." "0.18")
+(make-obsolete 'cider-connections-buffer-mode-map "see sesman." "0.18")
+(make-obsolete 'cider-connections-close-connection "see sesman." "0.18")
+(make-obsolete 'cider-connections-goto-connection "see sesman." "0.18")
+(make-obsolete 'cider-connections-make-default "see sesman." "0.18")
+(make-obsolete 'cider-display-connected-message "see sesman." "0.18")
+(make-obsolete 'cider-project-name "see sesman." "0.18")
+
+(provide 'cider-connection)
+
+;;; cider-connection.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-connection.elc b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-connection.elc
new file mode 100644
index 0000000000..d4a84774c4
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-connection.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-debug.el b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-debug.el
new file mode 100644
index 0000000000..9d17e7d772
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-debug.el
@@ -0,0 +1,755 @@
+;;; cider-debug.el --- CIDER interaction with the cider.debug nREPL middleware  -*- lexical-binding: t; -*-
+
+;; Copyright © 2015-2018 Bozhidar Batsov, Artur Malabarba and CIDER contributors
+
+;; Author: Artur Malabarba <bruce.connor.am@gmail.com>
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Instrument code with `cider-debug-defun-at-point', and when the code is
+;; executed cider-debug will kick in.  See this function's doc for more
+;; information.
+
+;;; Code:
+
+(require 'nrepl-dict)
+(require 'nrepl-client) ; `nrepl--mark-id-completed'
+(require 'cider-eval)
+(require 'cider-client)
+(require 'cider-util)
+(require 'cider-inspector)
+(require 'cider-browse-ns)
+(require 'cider-common)
+(require 'subr-x)
+(require 'cider-compat)
+(require 'seq)
+(require 'spinner)
+
+
+;;; Customization
+(defgroup cider-debug nil
+  "Presentation and behaviour of the cider debugger."
+  :prefix "cider-debug-"
+  :group 'cider
+  :package-version '(cider . "0.10.0"))
+
+(defface cider-debug-code-overlay-face
+  '((((class color) (background light)) :background "grey80")
+    (((class color) (background dark))  :background "grey30"))
+  "Face used to mark code being debugged."
+  :group 'cider-debug
+  :package-version '(cider . "0.9.1"))
+
+(defface cider-debug-prompt-face
+  '((t :underline t :inherit font-lock-builtin-face))
+  "Face used to highlight keys in the debug prompt."
+  :group 'cider-debug
+  :package-version '(cider . "0.10.0"))
+
+(defface cider-enlightened-face
+  '((((class color) (background light)) :inherit cider-result-overlay-face
+     :box (:color "darkorange" :line-width -1))
+    (((class color) (background dark))  :inherit cider-result-overlay-face
+     ;; "#dd0" is a dimmer yellow.
+     :box (:color "#990" :line-width -1)))
+  "Face used to mark enlightened sexps and their return values."
+  :group 'cider-debug
+  :package-version '(cider . "0.11.0"))
+
+(defface cider-enlightened-local-face
+  '((((class color) (background light)) :weight bold :foreground "darkorange")
+    (((class color) (background dark))  :weight bold :foreground "yellow"))
+  "Face used to mark enlightened locals (not their values)."
+  :group 'cider-debug
+  :package-version '(cider . "0.11.0"))
+
+(defcustom cider-debug-prompt 'overlay
+  "If and where to show the keys while debugging.
+If `minibuffer', show it in the minibuffer along with the return value.
+If `overlay', show it in an overlay above the current function.
+If t, do both.
+If nil, don't list available keys at all."
+  :type '(choice (const :tag "Show in minibuffer" minibuffer)
+                 (const :tag "Show above function" overlay)
+                 (const :tag "Show in both places" t)
+                 (const :tag "Don't list keys" nil))
+  :group 'cider-debug
+  :package-version '(cider . "0.10.0"))
+
+(defcustom cider-debug-use-overlays t
+  "Whether to higlight debugging information with overlays.
+Takes the same possible values as `cider-use-overlays', but only applies to
+values displayed during debugging sessions.
+To control the overlay that lists possible keys above the current function,
+configure `cider-debug-prompt' instead."
+  :type '(choice (const :tag "End of line" t)
+                 (const :tag "Bottom of screen" nil)
+                 (const :tag "Both" both))
+  :group 'cider-debug
+  :package-version '(cider . "0.9.1"))
+
+(defcustom cider-debug-print-level 10
+  "The print level for values displayed by the debugger.
+This variable must be set before starting the repl connection."
+  :type '(choice (const :tag "No limit" nil)
+                 (integer :tag "Max depth" 10))
+  :group 'cider-debug
+  :package-version '(cider . "0.10.0"))
+
+(defcustom cider-debug-print-length 10
+  "The print length for values displayed by the debugger.
+This variable must be set before starting the repl connection."
+  :type '(choice (const :tag "No limit" nil)
+                 (integer :tag "Max depth" 10))
+  :group 'cider-debug
+  :package-version '(cider . "0.10.0"))
+
+
+;;; Implementation
+(defun cider-browse-instrumented-defs ()
+  "List all instrumented definitions."
+  (interactive)
+  (if-let* ((all (thread-first (cider-nrepl-send-sync-request '("op" "debug-instrumented-defs"))
+                   (nrepl-dict-get "list"))))
+      (with-current-buffer (cider-popup-buffer cider-browse-ns-buffer t)
+        (let ((inhibit-read-only t))
+          (erase-buffer)
+          (dolist (list all)
+            (let* ((ns (car list))
+                   (ns-vars-with-meta (cider-sync-request:ns-vars-with-meta ns))
+                   ;; seq of metadata maps of the instrumented vars
+                   (instrumented-meta (mapcar (apply-partially #'nrepl-dict-get ns-vars-with-meta)
+                                              (cdr list))))
+              (cider-browse-ns--list (current-buffer) ns
+                                     (seq-mapn #'cider-browse-ns--properties
+                                               (cdr list)
+                                               instrumented-meta)
+
+                                     ns 'noerase)
+              (goto-char (point-max))
+              (insert "\n"))))
+        (goto-char (point-min)))
+    (message "No currently instrumented definitions")))
+
+(defun cider--debug-response-handler (response)
+  "Handles RESPONSE from the cider.debug middleware."
+  (nrepl-dbind-response response (status id causes)
+    (when (member "enlighten" status)
+      (cider--handle-enlighten response))
+    (when (or (member "eval-error" status)
+              (member "stack" status))
+      ;; TODO: Make the error buffer a bit friendlier when we're just printing
+      ;; the stack.
+      (cider--render-stacktrace-causes causes))
+    (when (member "need-debug-input" status)
+      (cider--handle-debug response))
+    (when (member "done" status)
+      (nrepl--mark-id-completed id))))
+
+(defun cider--debug-init-connection ()
+  "Initialize a connection with the cider.debug middleware."
+  (cider-nrepl-send-request
+   (nconc '("op" "init-debugger")
+          (when cider-debug-print-level
+            `("print-level" ,cider-debug-print-level))
+          (when cider-debug-print-length
+            `("print-length" ,cider-debug-print-length)))
+   #'cider--debug-response-handler))
+
+
+;;; Debugging overlays
+(defconst cider--fringe-arrow-string
+  #("." 0 1 (display (left-fringe right-triangle)))
+  "Used as an overlay's before-string prop to place a fringe arrow.")
+
+(defun cider--debug-display-result-overlay (value)
+  "Place an overlay at point displaying VALUE."
+  (when cider-debug-use-overlays
+    ;; This is cosmetic, let's ensure it doesn't break the session no matter what.
+    (ignore-errors
+      ;; Result
+      (cider--make-result-overlay (cider-font-lock-as-clojure value)
+        :where (point-marker)
+        :type 'debug-result
+        'before-string cider--fringe-arrow-string)
+      ;; Code
+      (cider--make-overlay (save-excursion (clojure-backward-logical-sexp 1) (point))
+                           (point) 'debug-code
+                           'face 'cider-debug-code-overlay-face
+                           ;; Higher priority than `show-paren'.
+                           'priority 2000))))
+
+
+;;; Minor mode
+(defvar-local cider--debug-mode-commands-dict nil
+  "An nrepl-dict from keys to debug commands.
+Autogenerated by `cider--turn-on-debug-mode'.")
+
+(defvar-local cider--debug-mode-response nil
+  "Response that triggered current debug session.
+Set by `cider--turn-on-debug-mode'.")
+
+(defcustom cider-debug-display-locals nil
+  "If non-nil, local variables are displayed while debugging.
+Can be toggled at any time with `\\[cider-debug-toggle-locals]'."
+  :type 'boolean
+  :group 'cider-debug
+  :package-version '(cider . "0.10.0"))
+
+(defun cider--debug-format-locals-list (locals)
+  "Return a string description of list LOCALS.
+Each element of LOCALS should be a list of at least two elements."
+  (if locals
+      (let ((left-col-width
+             ;; To right-indent the variable names.
+             (apply #'max (mapcar (lambda (l) (string-width (car l))) locals))))
+        ;; A format string to build a format string. :-P
+        (mapconcat (lambda (l) (format (format " %%%ds: %%s\n" left-col-width)
+                                       (propertize (car l) 'face 'font-lock-variable-name-face)
+                                       (cider-font-lock-as-clojure (cadr l))))
+                   locals ""))
+    ""))
+
+(defun cider--debug-prompt (command-dict)
+  "Return prompt to display for COMMAND-DICT."
+  ;; Force `default' face, otherwise the overlay "inherits" the face of the text
+  ;; after it.
+  (format (propertize "%s\n" 'face 'default)
+          (string-join
+           (nrepl-dict-map (lambda (char cmd)
+                             (when-let* ((pos (cl-search char cmd)))
+                               (put-text-property pos (1+ pos) 'face 'cider-debug-prompt-face cmd))
+                             cmd)
+                           command-dict)
+           " ")))
+
+(defvar-local cider--debug-prompt-overlay nil)
+
+(defun cider--debug-mode-redisplay ()
+  "Display the input prompt to the user."
+  (nrepl-dbind-response cider--debug-mode-response (debug-value input-type locals)
+    (when (or (eq cider-debug-prompt t)
+              (eq cider-debug-prompt 'overlay))
+      (if (overlayp cider--debug-prompt-overlay)
+          (overlay-put cider--debug-prompt-overlay
+                       'before-string (cider--debug-prompt input-type))
+        (setq cider--debug-prompt-overlay
+              (cider--make-overlay
+               (max (car (cider-defun-at-point 'bounds))
+                    (window-start))
+               nil 'debug-prompt
+               'before-string (cider--debug-prompt input-type)))))
+    (let* ((value (concat " " cider-eval-result-prefix
+                          (cider-font-lock-as-clojure
+                           (or debug-value "#unknown#"))))
+           (to-display
+            (concat (when cider-debug-display-locals
+                      (cider--debug-format-locals-list locals))
+                    (when (or (eq cider-debug-prompt t)
+                              (eq cider-debug-prompt 'minibuffer))
+                      (cider--debug-prompt input-type))
+                    (when (or (not cider-debug-use-overlays)
+                              (eq cider-debug-use-overlays 'both))
+                      value))))
+      (if (> (string-width to-display) 0)
+          (message "%s" to-display)
+        ;; If there's nothing to display in the minibuffer. Just send the value
+        ;; to the Messages buffer.
+        (message "%s" value)
+        (message nil)))))
+
+(defun cider-debug-toggle-locals ()
+  "Toggle display of local variables."
+  (interactive)
+  (setq cider-debug-display-locals (not cider-debug-display-locals))
+  (cider--debug-mode-redisplay))
+
+(defun cider--debug-lexical-eval (key form &optional callback _point)
+  "Eval FORM in the lexical context of debug session given by KEY.
+Do nothing if CALLBACK is provided.
+Designed to be used as `cider-interactive-eval-override' and called instead
+of `cider-interactive-eval' in debug sessions."
+  ;; The debugger uses its own callback, so if the caller is passing a callback
+  ;; we return nil and let `cider-interactive-eval' do its thing.
+  (unless callback
+    (cider-debug-mode-send-reply (format "{:response :eval, :code %s}" form)
+                                 key)
+    t))
+
+(defvar cider--debug-mode-tool-bar-map
+  (let ((tool-bar-map (make-sparse-keymap)))
+    (tool-bar-add-item "right-arrow" #'cider-debug-mode-send-reply :next :label "Next step")
+    (tool-bar-add-item "next-node" #'cider-debug-mode-send-reply :continue :label "Continue non-stop")
+    (tool-bar-add-item "jump-to" #'cider-debug-mode-send-reply :out :label "Out of sexp")
+    (tool-bar-add-item "exit" #'cider-debug-mode-send-reply :quit :label "Quit")
+    tool-bar-map))
+
+(defvar cider--debug-mode-map)
+
+(define-minor-mode cider--debug-mode
+  "Mode active during debug sessions.
+In order to work properly, this mode must be activated by
+`cider--turn-on-debug-mode'."
+  nil " DEBUG" '()
+  (if cider--debug-mode
+      (if cider--debug-mode-response
+          (nrepl-dbind-response cider--debug-mode-response (input-type)
+            ;; A debug session is an ongoing eval, but it's annoying to have the
+            ;; spinner spinning while you debug.
+            (when spinner-current (spinner-stop))
+            (setq-local tool-bar-map cider--debug-mode-tool-bar-map)
+            (add-hook 'kill-buffer-hook #'cider--debug-quit nil 'local)
+            (add-hook 'before-revert-hook #'cider--debug-quit nil 'local)
+            (unless (consp input-type)
+              (error "Activated debug-mode on a message not asking for commands: %s" cider--debug-mode-response))
+            ;; Integrate with eval commands.
+            (setq cider-interactive-eval-override
+                  (apply-partially #'cider--debug-lexical-eval
+                                   (nrepl-dict-get cider--debug-mode-response "key")))
+            ;; Set the keymap.
+            (nrepl-dict-map (lambda (char _cmd)
+                              (unless (string= char "h") ; `here' needs a special command.
+                                (define-key cider--debug-mode-map char #'cider-debug-mode-send-reply))
+                              (when (string= char "o")
+                                (define-key cider--debug-mode-map (upcase char) #'cider-debug-mode-send-reply)))
+                            input-type)
+            (setq cider--debug-mode-commands-dict input-type)
+            ;; Show the prompt.
+            (cider--debug-mode-redisplay)
+            ;; If a sync request is ongoing, the user can't act normally to
+            ;; provide input, so we enter `recursive-edit'.
+            (when nrepl-ongoing-sync-request
+              (recursive-edit)))
+        (cider--debug-mode -1)
+        (if (called-interactively-p 'any)
+            (user-error (substitute-command-keys "Don't call this mode manually, use `\\[universal-argument] \\[cider-eval-defun-at-point]' instead"))
+          (error "Attempt to activate `cider--debug-mode' without setting `cider--debug-mode-response' first")))
+    (setq cider-interactive-eval-override nil)
+    (setq cider--debug-mode-commands-dict nil)
+    (setq cider--debug-mode-response nil)
+    ;; We wait a moment before clearing overlays and the read-onlyness, so that
+    ;; cider-nrepl has a chance to send the next message, and so that the user
+    ;; doesn't accidentally hit `n' between two messages (thus editing the code).
+    (when-let* ((proc (unless nrepl-ongoing-sync-request
+                        (get-buffer-process (cider-current-repl)))))
+      (accept-process-output proc 1))
+    (unless cider--debug-mode
+      (setq buffer-read-only nil)
+      (cider--debug-remove-overlays (current-buffer)))
+    (when nrepl-ongoing-sync-request
+      (ignore-errors (exit-recursive-edit)))))
+
+;;; Bind the `:here` command to both h and H, because it behaves differently if
+;;; invoked with an uppercase letter.
+(define-key cider--debug-mode-map "h" #'cider-debug-move-here)
+(define-key cider--debug-mode-map "H" #'cider-debug-move-here)
+
+(defun cider--debug-remove-overlays (&optional buffer)
+  "Remove CIDER debug overlays from BUFFER if variable `cider--debug-mode' is nil."
+  (when (or (not buffer) (buffer-live-p buffer))
+    (with-current-buffer (or buffer (current-buffer))
+      (unless cider--debug-mode
+        (kill-local-variable 'tool-bar-map)
+        (remove-overlays nil nil 'category 'debug-result)
+        (remove-overlays nil nil 'category 'debug-code)
+        (setq cider--debug-prompt-overlay nil)
+        (remove-overlays nil nil 'category 'debug-prompt)))))
+
+(defun cider--debug-set-prompt (value)
+  "Set `cider-debug-prompt' to VALUE, then redisplay."
+  (setq cider-debug-prompt value)
+  (cider--debug-mode-redisplay))
+
+(easy-menu-define cider-debug-mode-menu cider--debug-mode-map
+  "Menu for CIDER debug mode"
+  `("CIDER Debugger"
+    ["Next step" (cider-debug-mode-send-reply ":next") :keys "n"]
+    ["Continue non-stop" (cider-debug-mode-send-reply ":continue") :keys "c"]
+    ["Move out of sexp" (cider-debug-mode-send-reply ":out") :keys "o"]
+    ["Quit" (cider-debug-mode-send-reply ":quit") :keys "q"]
+    "--"
+    ["Evaluate in current scope" (cider-debug-mode-send-reply ":eval") :keys "e"]
+    ["Inject value" (cider-debug-mode-send-reply ":inject") :keys "i"]
+    ["Inspect value" (cider-debug-mode-send-reply ":inspect")]
+    ["Inspect local variables" (cider-debug-mode-send-reply ":locals") :keys "l"]
+    "--"
+    ("Configure keys prompt"
+     ["Don't show keys"     (cider--debug-set-prompt nil)         :style toggle :selected (eq cider-debug-prompt nil)]
+     ["Show in minibuffer"  (cider--debug-set-prompt 'minibuffer) :style toggle :selected (eq cider-debug-prompt 'minibuffer)]
+     ["Show above function" (cider--debug-set-prompt 'overlay)    :style toggle :selected (eq cider-debug-prompt 'overlay)]
+     ["Show in both places" (cider--debug-set-prompt t)           :style toggle :selected (eq cider-debug-prompt t)]
+     "--"
+     ["List locals" cider-debug-toggle-locals :style toggle :selected cider-debug-display-locals])
+    ["Customize" (customize-group 'cider-debug)]))
+
+(defun cider--uppercase-command-p ()
+  "Return non-nil if the last command was uppercase letter."
+  (ignore-errors
+    (let ((case-fold-search nil))
+      (string-match "[[:upper:]]" (string last-command-event)))))
+
+(defun cider-debug-mode-send-reply (command &optional key force)
+  "Reply to the message that started current bufer's debugging session.
+COMMAND is sent as the input option.  KEY can be provided to reply to a
+specific message.  If FORCE is non-nil, send a \"force?\" argument in the
+message."
+  (interactive (list
+                (if (symbolp last-command-event)
+                    (symbol-name last-command-event)
+                  (ignore-errors
+                    (concat ":" (nrepl-dict-get cider--debug-mode-commands-dict
+                                                (downcase (string last-command-event))))))
+                nil
+                (cider--uppercase-command-p)))
+  (when (and (string-prefix-p ":" command) force)
+    (setq command (format "{:response %s :force? true}" command)))
+  (cider-nrepl-send-unhandled-request
+   `("op" "debug-input"
+     "input" ,(or command ":quit")
+     "key" ,(or key (nrepl-dict-get cider--debug-mode-response "key"))))
+  (ignore-errors (cider--debug-mode -1)))
+
+(defun cider--debug-quit ()
+  "Send a :quit reply to the debugger.  Used in hooks."
+  (when cider--debug-mode
+    (cider-debug-mode-send-reply ":quit")
+    (message "Quitting debug session")))
+
+
+;;; Movement logic
+(defconst cider--debug-buffer-format "*cider-debug %s*")
+
+(defun cider--debug-trim-code (code)
+  "Remove whitespace and reader macros from the start of the CODE.
+Return trimmed CODE."
+  (replace-regexp-in-string "\\`#[a-z]+[\n\r[:blank:]]*" "" code))
+
+(declare-function cider-set-buffer-ns "cider-mode")
+(defun cider--initialize-debug-buffer (code ns id &optional reason)
+  "Create a new debugging buffer with CODE and namespace NS.
+ID is the id of the message that instrumented CODE.
+REASON is a keyword describing why this buffer was necessary."
+  (let ((buffer-name (format cider--debug-buffer-format id)))
+    (if-let* ((buffer (get-buffer buffer-name)))
+        (cider-popup-buffer-display buffer 'select)
+      (with-current-buffer (cider-popup-buffer buffer-name 'select
+                                               #'clojure-mode 'ancillary)
+        (cider-set-buffer-ns ns)
+        (setq buffer-undo-list nil)
+        (let ((inhibit-read-only t)
+              (buffer-undo-list t))
+          (erase-buffer)
+          (insert (format "%s" (cider--debug-trim-code code)))
+          (when code
+            (insert "\n\n\n;; We had to create this temporary buffer because we couldn't find the original definition. That probably happened because "
+                    reason
+                    ".")
+            (fill-paragraph))
+          (cider--font-lock-ensure)
+          (set-buffer-modified-p nil))))
+    (switch-to-buffer buffer-name)
+    (goto-char (point-min))))
+
+(defun cider--debug-goto-keyval (key)
+  "Find KEY in current sexp or return nil."
+  (when-let* ((limit (ignore-errors (save-excursion (up-list) (point)))))
+    (search-forward-regexp (concat "\\_<" (regexp-quote key) "\\_>")
+                           limit 'noerror)))
+
+(defun cider--debug-move-point (coordinates)
+  "Place point on after the sexp specified by COORDINATES.
+COORDINATES is a list of integers that specify how to navigate into the
+sexp that is after point when this function is called.
+
+As an example, a COORDINATES list of '(1 0 2) means:
+  - enter next sexp then `forward-sexp' once,
+  - enter next sexp,
+  - enter next sexp then `forward-sexp' twice.
+
+In the following snippet, this takes us to the (* x 2) sexp (point is left
+at the end of the given sexp).
+
+    (letfn [(twice [x]
+              (* x 2))]
+      (twice 15))
+
+In addition to numbers, a coordinate can be a string.  This string names the
+key of a map, and it means \"go to the value associated with this key\"."
+  (condition-case-unless-debug nil
+      ;; Navigate through sexps inside the sexp.
+      (let ((in-syntax-quote nil))
+        (while coordinates
+          (while (clojure--looking-at-non-logical-sexp)
+            (forward-sexp))
+          ;; An `@x` is read as (deref x), so we pop coordinates once to account
+          ;; for the extra depth, and move past the @ char.
+          (if (eq ?@ (char-after))
+              (progn (forward-char 1)
+                     (pop coordinates))
+            (down-list)
+            ;; Are we entering a syntax-quote?
+            (when (looking-back "`\\(#{\\|[{[(]\\)" (line-beginning-position))
+              ;; If we are, this affects all nested structures until the next `~',
+              ;; so we set this variable for all following steps in the loop.
+              (setq in-syntax-quote t))
+            (when in-syntax-quote
+              ;; A `(. .) is read as (seq (concat (list .) (list .))). This pops
+              ;; the `seq', since the real coordinates are inside the `concat'.
+              (pop coordinates)
+              ;; Non-list seqs like `[] and `{} are read with
+              ;; an extra (apply vector ...), so pop it too.
+              (unless (eq ?\( (char-before))
+                (pop coordinates)))
+            ;; #(...) is read as (fn* ([] ...)), so we patch that here.
+            (when (looking-back "#(" (line-beginning-position))
+              (pop coordinates))
+            (if coordinates
+                (let ((next (pop coordinates)))
+                  (when in-syntax-quote
+                    ;; We're inside the `concat' form, but we need to discard the
+                    ;; actual `concat' symbol from the coordinate.
+                    (setq next (1- next)))
+                  ;; String coordinates are map keys.
+                  (if (stringp next)
+                      (cider--debug-goto-keyval next)
+                    (clojure-forward-logical-sexp next)
+                    (when in-syntax-quote
+                      (clojure-forward-logical-sexp 1)
+                      (forward-sexp -1)
+                      ;; Here a syntax-quote is ending.
+                      (let ((match (when (looking-at "~@?")
+                                     (match-string 0))))
+                        (when match
+                          (setq in-syntax-quote nil))
+                        ;; A `~@' is read as the object itself, so we don't pop
+                        ;; anything.
+                        (unless (equal "~@" match)
+                          ;; Anything else (including a `~') is read as a `list'
+                          ;; form inside the `concat', so we need to pop the list
+                          ;; from the coordinates.
+                          (pop coordinates))))))
+              ;; If that extra pop was the last coordinate, this represents the
+              ;; entire #(...), so we should move back out.
+              (backward-up-list))))
+        ;; Place point at the end of instrumented sexp.
+        (clojure-forward-logical-sexp 1))
+    ;; Avoid throwing actual errors, since this happens on every breakpoint.
+    (error (message "Can't find instrumented sexp, did you edit the source?"))))
+
+(defun cider--debug-position-for-code (code)
+  "Return non-nil if point is roughly before CODE.
+This might move point one line above."
+  (or (looking-at-p (regexp-quote code))
+      (let ((trimmed (regexp-quote (cider--debug-trim-code code))))
+        (or (looking-at-p trimmed)
+            ;; If this is a fake #dbg injected by `C-u
+            ;; C-M-x', then the sexp we want is actually on
+            ;; the line above.
+            (progn (forward-line -1)
+                   (looking-at-p trimmed))))))
+
+(defun cider--debug-find-source-position (response &optional create-if-needed)
+  "Return a marker of the position after the sexp specified in RESPONSE.
+This marker might be in a different buffer!  If the sexp can't be
+found (file that contains the code is no longer visited or has been
+edited), return nil.  However, if CREATE-IF-NEEDED is non-nil, a new buffer
+is created in this situation and the return value is never nil.
+
+Follow the \"line\" and \"column\" entries in RESPONSE, and check whether
+the code at point matches the \"code\" entry in RESPONSE.  If it doesn't,
+assume that the code in this file has been edited, and create a temp buffer
+holding the original code.
+Either way, navigate inside the code by following the \"coor\" entry which
+is a coordinate measure in sexps."
+  (nrepl-dbind-response response (code file line column ns original-id coor)
+    (when (or code (and file line column))
+      ;; This is for restoring current-buffer.
+      (save-excursion
+        (let ((out))
+          ;; We prefer in-source debugging.
+          (when-let* ((buf (and file line column
+                                (ignore-errors
+                                  (cider--find-buffer-for-file file)))))
+            ;; The logic here makes it hard to use `with-current-buffer'.
+            (with-current-buffer buf
+              ;; This is for restoring point inside buf.
+              (save-excursion
+                ;; Get to the proper line & column in the file
+                (forward-line (- line (line-number-at-pos)))
+                (move-to-column column)
+                ;; Check if it worked
+                (when (cider--debug-position-for-code code)
+                  ;; Find the desired sexp.
+                  (cider--debug-move-point coor)
+                  (setq out (point-marker))))))
+          ;; But we can create a temp buffer if that fails.
+          (or out
+              (when create-if-needed
+                (cider--initialize-debug-buffer
+                 code ns original-id
+                 (if (and line column)
+                     "you edited the code"
+                   "your tools.nrepl version is older than 0.2.11"))
+                (save-excursion
+                  (cider--debug-move-point coor)
+                  (point-marker)))))))))
+
+(defun cider--handle-debug (response)
+  "Handle debugging notification.
+RESPONSE is a message received from the nrepl describing the input
+needed.  It is expected to contain at least \"key\", \"input-type\", and
+\"prompt\", and possibly other entries depending on the input-type."
+  (nrepl-dbind-response response (debug-value key input-type prompt inspect)
+    (condition-case-unless-debug e
+        (progn
+          (pcase input-type
+            ("expression" (cider-debug-mode-send-reply
+                           (condition-case nil
+                               (cider-read-from-minibuffer
+                                (or prompt "Expression: "))
+                             (quit "nil"))
+                           key))
+            ((pred sequencep)
+             (let* ((marker (cider--debug-find-source-position response 'create-if-needed)))
+               (pop-to-buffer (marker-buffer marker))
+               (goto-char marker))
+             ;; The overlay code relies on window boundaries, but point could have been
+             ;; moved outside the window by some other code. Redisplay here to ensure the
+             ;; visible window includes point.
+             (redisplay)
+             ;; Remove overlays AFTER redisplaying! Otherwise there's a visible
+             ;; flicker even if we immediately recreate the overlays.
+             (cider--debug-remove-overlays)
+             (when cider-debug-use-overlays
+               (cider--debug-display-result-overlay debug-value))
+             (setq cider--debug-mode-response response)
+             (cider--debug-mode 1)))
+          (when inspect
+            (cider-inspector--render-value inspect)))
+      ;; If something goes wrong, we send a "quit" or the session hangs.
+      (error (cider-debug-mode-send-reply ":quit" key)
+             (message "Error encountered while handling the debug message: %S" e)))))
+
+(defun cider--handle-enlighten (response)
+  "Handle an enlighten notification.
+RESPONSE is a message received from the nrepl describing the value and
+coordinates of a sexp.  Create an overlay after the specified sexp
+displaying its value."
+  (when-let* ((marker (cider--debug-find-source-position response)))
+    (with-current-buffer (marker-buffer marker)
+      (save-excursion
+        (goto-char marker)
+        (clojure-backward-logical-sexp 1)
+        (nrepl-dbind-response response (debug-value erase-previous)
+          (when erase-previous
+            (remove-overlays (point) marker 'category 'enlighten))
+          (when debug-value
+            (if (memq (char-before marker) '(?\) ?\] ?}))
+                ;; Enlightening a sexp looks like a regular return value, except
+                ;; for a different border.
+                (cider--make-result-overlay (cider-font-lock-as-clojure debug-value)
+                  :where (cons marker marker)
+                  :type 'enlighten
+                  :prepend-face 'cider-enlightened-face)
+              ;; Enlightening a symbol uses a more abbreviated format. The
+              ;; result face is the same as a regular result, but we also color
+              ;; the symbol with `cider-enlightened-local-face'.
+              (cider--make-result-overlay (cider-font-lock-as-clojure debug-value)
+                :format "%s"
+                :where (cons (point) marker)
+                :type 'enlighten
+                'face 'cider-enlightened-local-face))))))))
+
+
+;;; Move here command
+;; This is the inverse of `cider--debug-move-point'.  However, that algorithm is
+;; complicated, and trying to code its inverse would probably be insane.
+;; Instead, we find the coordinate by trial and error.
+(defun cider--debug-find-coordinates-for-point (target &optional list-so-far)
+  "Return the coordinates list for reaching TARGET.
+Assumes that the next thing after point is a logical Clojure sexp and that
+TARGET is inside it.  The returned list is suitable for use in
+`cider--debug-move-point'.  LIST-SO-FAR is for internal use."
+  (when (looking-at (rx (or "(" "[" "#{" "{")))
+    (let ((starting-point (point)))
+      (unwind-protect
+          (let ((x 0))
+            ;; Keep incrementing the last coordinate until we've moved
+            ;; past TARGET.
+            (while (condition-case nil
+                       (progn (goto-char starting-point)
+                              (cider--debug-move-point (append list-so-far (list x)))
+                              (< (point) target))
+                     ;; Not a valid coordinate. Move back a step and stop here.
+                     (scan-error (setq x (1- x))
+                                 nil))
+              (setq x (1+ x)))
+            (setq list-so-far (append list-so-far (list x)))
+            ;; We have moved past TARGET, now determine whether we should
+            ;; stop, or if target is deeper inside the previous sexp.
+            (if (or (= target (point))
+                    (progn (forward-sexp -1)
+                           (<= target (point))))
+                list-so-far
+              (goto-char starting-point)
+              (cider--debug-find-coordinates-for-point target list-so-far)))
+        ;; `unwind-protect' clause.
+        (goto-char starting-point)))))
+
+(defun cider-debug-move-here (&optional force)
+  "Skip any breakpoints up to point.
+The boolean value of FORCE will be sent in the reply."
+  (interactive (list (cider--uppercase-command-p)))
+  (unless cider--debug-mode
+    (user-error "`cider-debug-move-here' only makes sense during a debug session"))
+  (let ((here (point)))
+    (nrepl-dbind-response cider--debug-mode-response (line column)
+      (if (and line column (buffer-file-name))
+          (progn ;; Get to the proper line & column in the file
+            (forward-line (1- (- line (line-number-at-pos))))
+            (move-to-column column))
+        (beginning-of-defun))
+      ;; Is HERE inside the sexp being debugged?
+      (when (or (< here (point))
+                (save-excursion
+                  (forward-sexp 1)
+                  (> here (point))))
+        (user-error "Point is outside the sexp being debugged"))
+      ;; Move forward untill start of sexp.
+      (comment-normalize-vars)
+      (comment-forward (point-max))
+      ;; Find the coordinate and send it.
+      (cider-debug-mode-send-reply
+       (format "{:response :here, :coord %s :force? %s}"
+               (cider--debug-find-coordinates-for-point here)
+               (if force "true" "false"))))))
+
+
+;;; User commands
+;;;###autoload
+(defun cider-debug-defun-at-point ()
+  "Instrument the \"top-level\" expression at point.
+If it is a defn, dispatch the instrumented definition.  Otherwise,
+immediately evaluate the instrumented expression.
+
+While debugged code is being evaluated, the user is taken through the
+source code and displayed the value of various expressions.  At each step,
+a number of keys will be prompted to the user."
+  (interactive)
+  (cider-eval-defun-at-point 'debug-it))
+
+(provide 'cider-debug)
+;;; cider-debug.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-debug.elc b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-debug.elc
new file mode 100644
index 0000000000..a657a2a8d1
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-debug.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-doc.el b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-doc.el
new file mode 100644
index 0000000000..5cca050563
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-doc.el
@@ -0,0 +1,533 @@
+;;; cider-doc.el --- CIDER documentation functionality -*- lexical-binding: t -*-
+
+;; Copyright © 2014-2018 Bozhidar Batsov, Jeff Valk and CIDER contributors
+
+;; Author: Jeff Valk <jv@jeffvalk.com>
+
+;; This program 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.
+
+;; This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+
+;; This file is not part of GNU Emacs.
+
+;;; Commentary:
+
+;; Mode for formatting and presenting documentation
+
+;;; Code:
+
+(require 'cider-common)
+(require 'subr-x)
+(require 'cider-compat)
+(require 'cider-util)
+(require 'cider-popup)
+(require 'cider-client)
+(require 'cider-grimoire)
+(require 'nrepl-dict)
+(require 'org-table)
+(require 'button)
+(require 'easymenu)
+(require 'cider-browse-spec)
+
+
+;;; Variables
+
+(defgroup cider-doc nil
+  "Documentation for CIDER."
+  :prefix "cider-doc-"
+  :group 'cider)
+
+(defcustom cider-doc-auto-select-buffer t
+  "Controls whether to auto-select the doc popup buffer."
+  :type 'boolean
+  :group 'cider-doc
+  :package-version  '(cider . "0.15.0"))
+
+(declare-function cider-apropos "cider-apropos")
+(declare-function cider-apropos-select "cider-apropos")
+(declare-function cider-apropos-documentation "cider-apropos")
+(declare-function cider-apropos-documentation-select "cider-apropos")
+
+(defvar cider-doc-map
+  (let (cider-doc-map)
+    (define-prefix-command 'cider-doc-map)
+    (define-key cider-doc-map (kbd "a") #'cider-apropos)
+    (define-key cider-doc-map (kbd "C-a") #'cider-apropos)
+    (define-key cider-doc-map (kbd "s") #'cider-apropos-select)
+    (define-key cider-doc-map (kbd "C-s") #'cider-apropos-select)
+    (define-key cider-doc-map (kbd "f") #'cider-apropos-documentation)
+    (define-key cider-doc-map (kbd "C-f") #'cider-apropos-documentation)
+    (define-key cider-doc-map (kbd "e") #'cider-apropos-documentation-select)
+    (define-key cider-doc-map (kbd "C-e") #'cider-apropos-documentation-select)
+    (define-key cider-doc-map (kbd "d") #'cider-doc)
+    (define-key cider-doc-map (kbd "C-d") #'cider-doc)
+    (define-key cider-doc-map (kbd "r") #'cider-grimoire)
+    (define-key cider-doc-map (kbd "C-r") #'cider-grimoire)
+    (define-key cider-doc-map (kbd "w") #'cider-grimoire-web)
+    (define-key cider-doc-map (kbd "C-w") #'cider-grimoire-web)
+    (define-key cider-doc-map (kbd "j") #'cider-javadoc)
+    (define-key cider-doc-map (kbd "C-j") #'cider-javadoc)
+    cider-doc-map)
+  "CIDER documentation keymap.")
+
+(defconst cider-doc-menu
+  '("Documentation"
+    ["CiderDoc" cider-doc]
+    ["JavaDoc in browser" cider-javadoc]
+    ["Grimoire" cider-grimoire]
+    ["Grimoire in browser" cider-grimoire-web]
+    ["Search symbols" cider-apropos]
+    ["Search symbols & select" cider-apropos-select]
+    ["Search documentation" cider-apropos-documentation]
+    ["Search documentation & select" cider-apropos-documentation-select]
+    "--"
+    ["Configure Doc buffer" (customize-group 'cider-docview-mode)])
+  "CIDER documentation submenu.")
+
+
+;;; cider-docview-mode
+
+(defgroup cider-docview-mode nil
+  "Formatting/fontifying documentation viewer."
+  :prefix "cider-docview-"
+  :group 'cider)
+
+(defcustom cider-docview-fill-column fill-column
+  "Fill column for docstrings in doc buffer."
+  :type 'list
+  :group 'cider-docview-mode
+  :package-version '(cider . "0.7.0"))
+
+
+;; Faces
+
+(defface cider-docview-emphasis-face
+  '((t (:inherit default :underline t)))
+  "Face for emphasized text"
+  :group 'cider-docview-mode
+  :package-version '(cider . "0.7.0"))
+
+(defface cider-docview-strong-face
+  '((t (:inherit default :underline t :weight bold)))
+  "Face for strongly emphasized text"
+  :group 'cider-docview-mode
+  :package-version '(cider . "0.7.0"))
+
+(defface cider-docview-literal-face
+  '((t (:inherit font-lock-string-face)))
+  "Face for literal text"
+  :group 'cider-docview-mode
+  :package-version '(cider . "0.7.0"))
+
+(defface cider-docview-table-border-face
+  '((t (:inherit shadow)))
+  "Face for table borders"
+  :group 'cider-docview-mode
+  :package-version '(cider . "0.7.0"))
+
+
+;; Colors & Theme Support
+
+(defvar cider-docview-code-background-color
+  (cider-scale-background-color)
+  "Background color for code blocks.")
+
+(defadvice enable-theme (after cider-docview-adapt-to-theme activate)
+  "When theme is changed, update `cider-docview-code-background-color'."
+  (setq cider-docview-code-background-color (cider-scale-background-color)))
+
+
+(defadvice disable-theme (after cider-docview-adapt-to-theme activate)
+  "When theme is disabled, update `cider-docview-code-background-color'."
+  (setq cider-docview-code-background-color (cider-scale-background-color)))
+
+
+;; Mode & key bindings
+
+(defvar cider-docview-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map "q" #'cider-popup-buffer-quit-function)
+    (define-key map "g" #'cider-docview-grimoire)
+    (define-key map "G" #'cider-docview-grimoire-web)
+    (define-key map "j" #'cider-docview-javadoc)
+    (define-key map "s" #'cider-docview-source)
+    (define-key map (kbd "<backtab>") #'backward-button)
+    (define-key map (kbd "TAB") #'forward-button)
+    (easy-menu-define cider-docview-mode-menu map
+      "Menu for CIDER's doc mode"
+      `("CiderDoc"
+        ["Look up in Grimoire" cider-docview-grimoire]
+        ["Look up in Grimoire (browser)" cider-docview-grimoire-web]
+        ["JavaDoc in browser" cider-docview-javadoc]
+        ["Jump to source" cider-docview-source]
+        "--"
+        ["Quit" cider-popup-buffer-quit-function]
+        ))
+    map))
+
+(defvar cider-docview-symbol)
+(defvar cider-docview-javadoc-url)
+(defvar cider-docview-file)
+(defvar cider-docview-line)
+
+(define-derived-mode cider-docview-mode help-mode "Doc"
+  "Major mode for displaying CIDER documentation
+
+\\{cider-docview-mode-map}"
+  (setq buffer-read-only t)
+  (setq-local sesman-system 'CIDER)
+  (when cider-special-mode-truncate-lines
+    (setq-local truncate-lines t))
+  (setq-local electric-indent-chars nil)
+  (setq-local cider-docview-symbol nil)
+  (setq-local cider-docview-javadoc-url nil)
+  (setq-local cider-docview-file nil)
+  (setq-local cider-docview-line nil))
+
+
+;;; Interactive functions
+
+(defun cider-docview-javadoc ()
+  "Open the Javadoc for the current class, if available."
+  (interactive)
+  (if cider-docview-javadoc-url
+      (browse-url cider-docview-javadoc-url)
+    (error "No Javadoc available for %s" cider-docview-symbol)))
+
+(defun cider-javadoc-handler (symbol-name)
+  "Invoke the nREPL \"info\" op on SYMBOL-NAME if available."
+  (when symbol-name
+    (let* ((info (cider-var-info symbol-name))
+           (url (nrepl-dict-get info "javadoc")))
+      (if url
+          (browse-url url)
+        (user-error "No Javadoc available for %s" symbol-name)))))
+
+(defun cider-javadoc (arg)
+  "Open Javadoc documentation in a popup buffer.
+
+Prompts for the symbol to use, or uses the symbol at point, depending on
+the value of `cider-prompt-for-symbol'.  With prefix arg ARG, does the
+opposite of what that option dictates."
+  (interactive "P")
+  (cider-ensure-connected)
+  (cider-ensure-op-supported "info")
+  (funcall (cider-prompt-for-symbol-function arg)
+           "Javadoc for"
+           #'cider-javadoc-handler))
+
+(defun cider-docview-source ()
+  "Open the source for the current symbol, if available."
+  (interactive)
+  (if cider-docview-file
+      (if-let* ((buffer (and (not (cider--tooling-file-p cider-docview-file))
+                             (cider-find-file cider-docview-file))))
+          (cider-jump-to buffer (if cider-docview-line
+                                    (cons cider-docview-line nil)
+                                  cider-docview-symbol)
+                         nil)
+        (user-error
+         (substitute-command-keys
+          "Can't find the source because it wasn't defined with `cider-eval-buffer'")))
+    (error "No source location for %s" cider-docview-symbol)))
+
+(defvar cider-buffer-ns)
+
+(declare-function cider-grimoire-lookup "cider-grimoire")
+
+(defun cider-docview-grimoire ()
+  "Return the grimoire documentation for `cider-docview-symbol'."
+  (interactive)
+  (if cider-buffer-ns
+      (cider-grimoire-lookup cider-docview-symbol)
+    (error "%s cannot be looked up on Grimoire" cider-docview-symbol)))
+
+(declare-function cider-grimoire-web-lookup "cider-grimoire")
+
+(defun cider-docview-grimoire-web ()
+  "Open the grimoire documentation for `cider-docview-symbol' in a web browser."
+  (interactive)
+  (if cider-buffer-ns
+      (cider-grimoire-web-lookup cider-docview-symbol)
+    (error "%s cannot be looked up on Grimoire" cider-docview-symbol)))
+
+(defconst cider-doc-buffer "*cider-doc*")
+
+(defun cider-create-doc-buffer (symbol)
+  "Populates *cider-doc* with the documentation for SYMBOL."
+  (when-let* ((info (cider-var-info symbol)))
+    (cider-docview-render (cider-make-popup-buffer cider-doc-buffer nil 'ancillary) symbol info)))
+
+(defun cider-doc-lookup (symbol)
+  "Look up documentation for SYMBOL."
+  (if-let* ((buffer (cider-create-doc-buffer symbol)))
+      (cider-popup-buffer-display buffer cider-doc-auto-select-buffer)
+    (user-error "Symbol %s not resolved" symbol)))
+
+(defun cider-doc (&optional arg)
+  "Open Clojure documentation in a popup buffer.
+
+Prompts for the symbol to use, or uses the symbol at point, depending on
+the value of `cider-prompt-for-symbol'.  With prefix arg ARG, does the
+opposite of what that option dictates."
+  (interactive "P")
+  (cider-ensure-connected)
+  (funcall (cider-prompt-for-symbol-function arg)
+           "Doc for"
+           #'cider-doc-lookup))
+
+
+;;; Font Lock and Formatting
+
+(defun cider-docview-fontify-code-blocks (buffer mode)
+  "Font lock BUFFER code blocks using MODE and remove markdown characters.
+This processes the triple backtick GFM markdown extension.  An overlay is used
+to shade the background.  Blocks are marked to be ignored by other fonification
+and line wrap."
+  (with-current-buffer buffer
+    (save-excursion
+      (while (search-forward-regexp "```\n" nil t)
+        (replace-match "")
+        (let ((beg (point))
+              (bg `(:background ,cider-docview-code-background-color)))
+          (when (search-forward-regexp "```\n" nil t)
+            (replace-match "")
+            (cider-font-lock-region-as mode beg (point))
+            (overlay-put (make-overlay beg (point)) 'font-lock-face bg)
+            (put-text-property beg (point) 'block 'code)))))))
+
+(defun cider-docview-fontify-literals (buffer)
+  "Font lock BUFFER literal text and remove backtick markdown characters.
+Preformatted code text blocks are ignored."
+  (with-current-buffer buffer
+    (save-excursion
+      (while (search-forward "`" nil t)
+        (if (eq (get-text-property (point) 'block) 'code)
+            (forward-char)
+          (progn
+            (replace-match "")
+            (let ((beg (point)))
+              (when (search-forward "`" (line-end-position) t)
+                (replace-match "")
+                (put-text-property beg (point) 'font-lock-face 'cider-docview-literal-face)))))))))
+
+(defun cider-docview-fontify-emphasis (buffer)
+  "Font lock BUFFER emphasized text and remove markdown characters.
+One '*' represents emphasis, multiple '**'s represent strong emphasis.
+Preformatted code text blocks are ignored."
+  (with-current-buffer buffer
+    (save-excursion
+      (while (search-forward-regexp "\\(*+\\)\\(\\w\\)" nil t)
+        (if (eq (get-text-property (point) 'block) 'code)
+            (forward-char)
+          (progn
+            (replace-match "\\2")
+            (let ((beg (1- (point)))
+                  (face (if (> (length (match-string 1)) 1)
+                            'cider-docview-strong-face
+                          'cider-docview-emphasis-face)))
+              (when (search-forward-regexp "\\(\\w\\)\\*+" (line-end-position) t)
+                (replace-match "\\1")
+                (put-text-property beg (point) 'font-lock-face face)))))))))
+
+(defun cider-docview-format-tables (buffer)
+  "Align BUFFER tables and dim borders.
+This processes the GFM table markdown extension using `org-table'.
+Tables are marked to be ignored by line wrap."
+  (with-current-buffer buffer
+    (save-excursion
+      (let ((border 'cider-docview-table-border-face))
+        (org-table-map-tables
+         (lambda ()
+           (org-table-align)
+           (goto-char (org-table-begin))
+           (while (search-forward-regexp "[+|-]" (org-table-end) t)
+             (put-text-property (match-beginning 0) (match-end 0) 'font-lock-face border))
+           (put-text-property (org-table-begin) (org-table-end) 'block 'table)))))))
+
+(defun cider-docview-wrap-text (buffer)
+  "For text in BUFFER not propertized as 'block', apply line wrap."
+  (with-current-buffer buffer
+    (save-excursion
+      (while (not (eobp))
+        (unless (get-text-property (point) 'block)
+          (fill-region (point) (line-end-position)))
+        (forward-line)))))
+
+
+;;; Rendering
+
+(defun cider-docview-render-java-doc (buffer text)
+  "Emit into BUFFER formatted doc TEXT for a Java class or member."
+  (with-current-buffer buffer
+    (let ((beg (point)))
+      (insert text)
+      (save-excursion
+        (goto-char beg)
+        (cider-docview-fontify-code-blocks buffer 'java-mode) ; left alone hereafter
+        (cider-docview-fontify-literals buffer)
+        (cider-docview-fontify-emphasis buffer)
+        (cider-docview-format-tables buffer) ; may contain literals, emphasis
+        (cider-docview-wrap-text buffer))))) ; ignores code, table blocks
+
+(defun cider--abbreviate-file-protocol (file-with-protocol)
+  "Abbreviate the file-path in `file:/path/to/file' of FILE-WITH-PROTOCOL."
+  (if (string-match "\\`file:\\(.*\\)" file-with-protocol)
+      (let ((file (match-string 1 file-with-protocol))
+            (proj-dir (clojure-project-dir)))
+        (if (and proj-dir
+                 (file-in-directory-p file proj-dir))
+            (file-relative-name file proj-dir)
+          file))
+    file-with-protocol))
+
+(defun cider-docview-render-info (buffer info)
+  "Emit into BUFFER formatted INFO for the Clojure or Java symbol."
+  (let* ((ns      (nrepl-dict-get info "ns"))
+         (name    (nrepl-dict-get info "name"))
+         (added   (nrepl-dict-get info "added"))
+         (depr    (nrepl-dict-get info "deprecated"))
+         (macro   (nrepl-dict-get info "macro"))
+         (special (nrepl-dict-get info "special-form"))
+         (forms   (when-let* ((str (nrepl-dict-get info "forms-str")))
+                    (split-string str "\n")))
+         (args    (when-let* ((str (nrepl-dict-get info "arglists-str")))
+                    (split-string str "\n")))
+         (doc     (or (nrepl-dict-get info "doc")
+                      "Not documented."))
+         (url     (nrepl-dict-get info "url"))
+         (class   (nrepl-dict-get info "class"))
+         (member  (nrepl-dict-get info "member"))
+         (javadoc (nrepl-dict-get info "javadoc"))
+         (super   (nrepl-dict-get info "super"))
+         (ifaces  (nrepl-dict-get info "interfaces"))
+         (spec    (nrepl-dict-get info "spec"))
+         (clj-name  (if ns (concat ns "/" name) name))
+         (java-name (if member (concat class "/" member) class))
+         (see-also (nrepl-dict-get info "see-also")))
+    (cider--help-setup-xref (list #'cider-doc-lookup (format "%s/%s" ns name)) nil buffer)
+    (with-current-buffer buffer
+      (cl-flet ((emit (text &optional face)
+                      (insert (if face
+                                  (propertize text 'font-lock-face face)
+                                text)
+                              "\n")))
+        (emit (if class java-name clj-name) 'font-lock-function-name-face)
+        (when super
+          (emit (concat "   Extends: " (cider-font-lock-as 'java-mode super))))
+        (when ifaces
+          (emit (concat "Implements: " (cider-font-lock-as 'java-mode (car ifaces))))
+          (dolist (iface (cdr ifaces))
+            (emit (concat "            "(cider-font-lock-as 'java-mode iface)))))
+        (when (or super ifaces)
+          (insert "\n"))
+        (when-let* ((forms (or forms args)))
+          (dolist (form forms)
+            (insert " ")
+            (emit (cider-font-lock-as-clojure form))))
+        (when special
+          (emit "Special Form" 'font-lock-keyword-face))
+        (when macro
+          (emit "Macro" 'font-lock-variable-name-face))
+        (when added
+          (emit (concat "Added in " added) 'font-lock-comment-face))
+        (when depr
+          (emit (concat "Deprecated in " depr) 'font-lock-keyword-face))
+        (if class
+            (cider-docview-render-java-doc (current-buffer) doc)
+          (emit (concat "  " doc)))
+        (when url
+          (insert "\n  Please see ")
+          (insert-text-button url
+                              'url url
+                              'follow-link t
+                              'action (lambda (x)
+                                        (browse-url (button-get x 'url))))
+          (insert "\n"))
+        (when javadoc
+          (insert "\n\nFor additional documentation, see the ")
+          (insert-text-button "Javadoc"
+                              'url javadoc
+                              'follow-link t
+                              'action (lambda (x)
+                                        (browse-url (button-get x 'url))))
+          (insert ".\n"))
+        (insert "\n")
+        (when spec
+          (emit "Spec:" 'font-lock-function-name-face)
+          (insert (cider-browse-spec--pprint-indented spec))
+          (insert "\n\n")
+          (insert-text-button "Browse spec"
+                              'follow-link t
+                              'action (lambda (_)
+                                        (cider-browse-spec (format "%s/%s" ns name))))
+          (insert "\n\n"))
+        (if cider-docview-file
+            (progn
+              (insert (propertize (if class java-name clj-name)
+                                  'font-lock-face 'font-lock-function-name-face)
+                      " is defined in ")
+              (insert-text-button (cider--abbreviate-file-protocol cider-docview-file)
+                                  'follow-link t
+                                  'action (lambda (_x)
+                                            (cider-docview-source)))
+              (insert "."))
+          (insert "Definition location unavailable."))
+        (when see-also
+          (insert "\n\n Also see: ")
+          (mapc (lambda (ns-sym)
+                  (let* ((ns-sym-split (split-string ns-sym "/"))
+                         (see-also-ns (car ns-sym-split))
+                         (see-also-sym (cadr ns-sym-split))
+                         ;; if the var belongs to the same namespace,
+                         ;; we omit the namespace to save some screen space
+                         (symbol (if (equal ns see-also-ns) see-also-sym ns-sym)))
+                    (insert-text-button symbol
+                                        'type 'help-xref
+                                        'help-function (apply-partially #'cider-doc-lookup symbol)))
+                  (insert " "))
+                see-also))
+        (cider--doc-make-xrefs)
+        (let ((beg (point-min))
+              (end (point-max)))
+          (nrepl-dict-map (lambda (k v)
+                            (put-text-property beg end k v))
+                          info)))
+      (current-buffer))))
+
+(declare-function cider-set-buffer-ns "cider-mode")
+(defun cider-docview-render (buffer symbol info)
+  "Emit into BUFFER formatted documentation for SYMBOL's INFO."
+  (with-current-buffer buffer
+    (let ((javadoc (nrepl-dict-get info "javadoc"))
+          (file (nrepl-dict-get info "file"))
+          (line (nrepl-dict-get info "line"))
+          (ns (nrepl-dict-get info "ns"))
+          (inhibit-read-only t))
+      (cider-docview-mode)
+
+      (cider-set-buffer-ns ns)
+      (setq-local cider-docview-symbol symbol)
+      (setq-local cider-docview-javadoc-url javadoc)
+      (setq-local cider-docview-file file)
+      (setq-local cider-docview-line line)
+
+      (remove-overlays)
+      (cider-docview-render-info buffer info)
+
+      (goto-char (point-min))
+      (current-buffer))))
+
+
+(provide 'cider-doc)
+
+;;; cider-doc.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-doc.elc b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-doc.elc
new file mode 100644
index 0000000000..5c7fc0320e
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-doc.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-eldoc.el b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-eldoc.el
new file mode 100644
index 0000000000..b055824df3
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-eldoc.el
@@ -0,0 +1,481 @@
+;;; cider-eldoc.el --- eldoc support for Clojure -*- lexical-binding: t -*-
+
+;; Copyright © 2012-2013 Tim King, Phil Hagelberg, Bozhidar Batsov
+;; Copyright © 2013-2018 Bozhidar Batsov, Artur Malabarba and CIDER contributors
+;;
+;; Author: Tim King <kingtim@gmail.com>
+;;         Phil Hagelberg <technomancy@gmail.com>
+;;         Bozhidar Batsov <bozhidar@batsov.com>
+;;         Artur Malabarba <bruce.connor.am@gmail.com>
+;;         Hugo Duncan <hugo@hugoduncan.org>
+;;         Steve Purcell <steve@sanityinc.com>
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;; This file is not part of GNU Emacs.
+
+;;; Commentary:
+
+;; eldoc support for Clojure.
+
+;;; Code:
+
+(require 'cider-client)
+(require 'cider-common) ; for cider-symbol-at-point
+(require 'subr-x)
+(require 'cider-compat)
+(require 'cider-util)
+(require 'nrepl-dict)
+
+(require 'seq)
+
+(require 'eldoc)
+
+(defvar cider-extra-eldoc-commands '("yas-expand")
+  "Extra commands to be added to eldoc's safe commands list.")
+
+(defcustom cider-eldoc-max-num-sexps-to-skip 30
+  "The maximum number of sexps to skip while searching the beginning of current sexp."
+  :type 'integer
+  :group 'cider
+  :package-version '(cider . "0.10.1"))
+
+(defvar-local cider-eldoc-last-symbol nil
+  "The eldoc information for the last symbol we checked.")
+
+(defcustom cider-eldoc-ns-function #'identity
+  "A function that returns a ns string to be used by eldoc.
+Takes one argument, a namespace name.
+For convenience, some functions are already provided for this purpose:
+`cider-abbreviate-ns', and `cider-last-ns-segment'."
+  :type '(choice (const :tag "Full namespace" identity)
+                 (const :tag "Abbreviated namespace" cider-abbreviate-ns)
+                 (const :tag "Last name in namespace" cider-last-ns-segment)
+                 (function :tag "Custom function"))
+  :group 'cider
+  :package-version '(cider . "0.13.0"))
+
+(defcustom cider-eldoc-max-class-names-to-display 3
+  "The maximum number of classes to display in an eldoc string.
+An eldoc string for Java interop forms can have a number of classes prefixed to
+it, when the form belongs to more than 1 class.  When, not nil we only display
+the names of first `cider-eldoc-max-class-names-to-display' classes and add
+a \"& x more\" suffix. Otherwise, all the classes are displayed."
+  :type 'integer
+  :safe #'integerp
+  :group 'cider
+  :package-version '(cider . "0.13.0"))
+
+(defcustom cider-eldoc-display-for-symbol-at-point t
+  "When non-nil, display eldoc for symbol at point if available.
+So in (map inc ...) when the cursor is over inc its eldoc would be
+displayed.  When nil, always display eldoc for first symbol of the sexp."
+  :type 'boolean
+  :safe #'booleanp
+  :group 'cider
+  :package-version '(cider . "0.13.0"))
+
+(defcustom cider-eldoc-display-context-dependent-info nil
+  "When non-nil, display context dependent info in the eldoc where possible.
+CIDER will try to add expected function arguments based on the current context,
+for example for the datomic.api/q function where it will show the expected
+inputs of the query at point."
+  :type 'boolean
+  :group 'cider
+  :package-version '(cider . "0.15.0"))
+
+(defun cider--eldoc-format-class-names (class-names)
+  "Return a formatted CLASS-NAMES prefix string.
+CLASS-NAMES is a list of classes to which a Java interop form belongs.
+Only keep the first `cider-eldoc-max-class-names-to-display' names, and
+add a \"& x more\" suffix.  Return nil if the CLASS-NAMES list is empty or
+mapping `cider-eldoc-ns-function' on it returns an empty list."
+  (when-let* ((eldoc-class-names (seq-remove #'null (mapcar (apply-partially cider-eldoc-ns-function) class-names)))
+              (eldoc-class-names-length (length eldoc-class-names)))
+    (cond
+     ;; truncate class-names list and then format it
+     ((and cider-eldoc-max-class-names-to-display
+           (> eldoc-class-names-length cider-eldoc-max-class-names-to-display))
+      (format "(%s & %s more)"
+              (thread-first eldoc-class-names
+                (seq-take cider-eldoc-max-class-names-to-display)
+                (string-join " ")
+                (cider-propertize 'ns))
+              (- eldoc-class-names-length cider-eldoc-max-class-names-to-display)))
+
+     ;; format the whole list but add surrounding parentheses
+     ((> eldoc-class-names-length 1)
+      (format "(%s)"
+              (thread-first eldoc-class-names
+                (string-join " ")
+                (cider-propertize 'ns))))
+
+     ;; don't add the parentheses
+     (t (format "%s" (car eldoc-class-names))))))
+
+(defun cider-eldoc-format-thing (ns symbol thing type)
+  "Format the eldoc subject defined by NS, SYMBOL, THING and TYPE.
+THING represents the thing at point which triggered eldoc.  Normally NS and
+SYMBOL are used (they are derived from THING), but when empty we fallback to
+THING (e.g. for Java methods).  Format it as a function, if FUNCTION-P
+is non-nil.  Else format it as a variable."
+  (if-let* ((method-name (if (and symbol (not (string= symbol "")))
+                             symbol
+                           thing))
+            (propertized-method-name (cider-propertize method-name type))
+            (ns-or-class (if (and ns (stringp ns))
+                             (funcall cider-eldoc-ns-function ns)
+                           (cider--eldoc-format-class-names ns))))
+      (format "%s/%s"
+              ;; we set font-lock properties of classes in `cider--eldoc-format-class-names'
+              ;; to avoid font locking the parentheses and "& x more"
+              ;; so we only propertize ns-or-class if not already done
+              (if (get-text-property 1 'face ns-or-class)
+                  ;; it is already propertized
+                  ns-or-class
+                (cider-propertize ns-or-class 'ns))
+              propertized-method-name)
+    ;; in case ns-or-class is nil
+    propertized-method-name))
+
+(defun cider-eldoc-format-sym-doc (var ns docstring)
+  "Return the formatted eldoc string for VAR and DOCSTRING.
+
+Consider the value of `eldoc-echo-area-use-multiline-p' while formatting.
+If the entire line cannot fit in the echo area, the var name may be
+truncated or eliminated entirely from the output to make room for the
+description.
+
+Try to truncate the var with various strategies, so that the var and
+the docstring can be displayed in the minibuffer without resizing the window.
+We start with `cider-abbreviate-ns' and `cider-last-ns-segment'.
+Next, if the var is in current namespace, we remove NS from the eldoc string.
+Otherwise, only the docstring is returned."
+  (let* ((ea-multi eldoc-echo-area-use-multiline-p)
+         ;; Subtract 1 from window width since emacs will not write
+         ;; any chars to the last column, or in later versions, will
+         ;; cause a wraparound and resize of the echo area.
+         (ea-width (1- (window-width (minibuffer-window))))
+         (strip (- (+ (length var) (length docstring)) ea-width))
+         (newline (string-match-p "\n" docstring))
+         ;; Truncated var can be ea-var long
+         ;; Subtract 2 to account for the : and / added when including
+         ;; the namespace prefixed form in eldoc string
+         (ea-var (- (- ea-width (length docstring)) 2)))
+    (cond
+     ((or (eq ea-multi t)
+          (and (<= strip 0) (null newline))
+          (and ea-multi (or (> (length docstring) ea-width) newline)))
+      (format "%s: %s" var docstring))
+
+     ;; Now we have to truncate either the docstring or the var
+     (newline (cider-eldoc-format-sym-doc var ns (substring docstring 0 newline)))
+
+     ;; Only return the truncated docstring
+     ((> (length docstring) ea-width)
+      (substring docstring 0 ea-width))
+
+     ;; Try to truncate the var with cider-abbreviate-ns
+     ((<= (length (cider-abbreviate-ns var)) ea-var)
+      (format "%s: %s" (cider-abbreviate-ns var) docstring))
+
+     ;; Try to truncate var with cider-last-ns-segment
+     ((<= (length (cider-last-ns-segment var)) ea-var)
+      (format "%s: %s" (cider-last-ns-segment var) docstring))
+
+     ;; If the var is in current namespace, we try to truncate the var by
+     ;; skipping the namespace from the returned eldoc string
+     ((and (string-equal ns (cider-current-ns))
+           (<= (- (length var) (length ns)) ea-var))
+      (format "%s: %s"
+              (replace-regexp-in-string (format "%s/" ns) "" var)
+              docstring))
+
+     ;; We couldn't fit the var and docstring in the available space,
+     ;; so we just display the docstring
+     (t docstring))))
+
+(defun cider-eldoc-format-variable (thing eldoc-info)
+  "Return the formatted eldoc string for a variable.
+
+THING is the variable name.  ELDOC-INFO is a p-list containing the eldoc
+information."
+  (let* ((ns (lax-plist-get eldoc-info "ns"))
+         (symbol (lax-plist-get eldoc-info "symbol"))
+         (docstring (lax-plist-get eldoc-info "docstring"))
+         (formatted-var (cider-eldoc-format-thing ns symbol thing 'var)))
+    (when docstring
+      (cider-eldoc-format-sym-doc formatted-var ns docstring))))
+
+(defun cider-eldoc-format-function (thing pos eldoc-info)
+  "Return the formatted eldoc string for a function.
+THING is the function name.  POS is the argument-index of the functions
+arglists.  ELDOC-INFO is a p-list containing the eldoc information."
+  (let ((ns (lax-plist-get eldoc-info "ns"))
+        (symbol (lax-plist-get eldoc-info "symbol"))
+        (arglists (lax-plist-get eldoc-info "arglists")))
+    (format "%s: %s"
+            (cider-eldoc-format-thing ns symbol thing 'fn)
+            (cider-eldoc-format-arglist arglists pos))))
+
+(defun cider-highlight-args (arglist pos)
+  "Format the the function ARGLIST for eldoc.
+POS is the index of the currently highlighted argument."
+  (let* ((rest-pos (cider--find-rest-args-position arglist))
+         (i 0))
+    (mapconcat
+     (lambda (arg)
+       (let ((argstr (format "%s" arg)))
+         (if (string= arg "&")
+             argstr
+           (prog1
+               (if (or (= (1+ i) pos)
+                       (and rest-pos
+                            (> (1+ i) rest-pos)
+                            (> pos rest-pos)))
+                   (propertize argstr 'face
+                               'eldoc-highlight-function-argument)
+                 argstr)
+             (setq i (1+ i)))))) arglist " ")))
+
+(defun cider--find-rest-args-position (arglist)
+  "Find the position of & in the ARGLIST vector."
+  (seq-position arglist "&"))
+
+(defun cider-highlight-arglist (arglist pos)
+  "Format the ARGLIST for eldoc.
+POS is the index of the argument to highlight."
+  (concat "[" (cider-highlight-args arglist pos) "]"))
+
+(defun cider-eldoc-format-arglist (arglist pos)
+  "Format all the ARGLIST for eldoc.
+POS is the index of current argument."
+  (concat "("
+          (mapconcat (lambda (args) (cider-highlight-arglist args pos))
+                     arglist
+                     " ")
+          ")"))
+
+(defun cider-eldoc-beginning-of-sexp ()
+  "Move to the beginning of current sexp.
+
+Return the number of nested sexp the point was over or after.  Return nil
+if the maximum number of sexps to skip is exceeded."
+  (let ((parse-sexp-ignore-comments t)
+        (num-skipped-sexps 0))
+    (condition-case _
+        (progn
+          ;; First account for the case the point is directly over a
+          ;; beginning of a nested sexp.
+          (condition-case _
+              (let ((p (point)))
+                (forward-sexp -1)
+                (forward-sexp 1)
+                (when (< (point) p)
+                  (setq num-skipped-sexps 1)))
+            (error))
+          (while
+              (let ((p (point)))
+                (forward-sexp -1)
+                (when (< (point) p)
+                  (setq num-skipped-sexps
+                        (unless (and cider-eldoc-max-num-sexps-to-skip
+                                     (>= num-skipped-sexps
+                                         cider-eldoc-max-num-sexps-to-skip))
+                          ;; Without the above guard,
+                          ;; `cider-eldoc-beginning-of-sexp' could traverse the
+                          ;; whole buffer when the point is not within a
+                          ;; list. This behavior is problematic especially with
+                          ;; a buffer containing a large number of
+                          ;; non-expressions like a REPL buffer.
+                          (1+ num-skipped-sexps)))))))
+      (error))
+    num-skipped-sexps))
+
+(defun cider-eldoc-thing-type (eldoc-info)
+  "Return the type of the ELDOC-INFO being displayed by eldoc.
+It can be a function or var now."
+  (pcase (lax-plist-get eldoc-info "type")
+    ("function" 'fn)
+    ("variable" 'var)))
+
+(defun cider-eldoc-info-at-point ()
+  "Return eldoc info at point.
+First go to the beginning of the sexp and check if the eldoc is to be
+considered (i.e sexp is a method call) and not a map or vector literal.
+Then go back to the point and return its eldoc."
+  (save-excursion
+    (unless (cider-in-comment-p)
+      (let* ((current-point (point)))
+        (cider-eldoc-beginning-of-sexp)
+        (unless (member (or (char-before (point)) 0) '(?\" ?\{ ?\[))
+          (goto-char current-point)
+          (when-let* ((eldoc-info (cider-eldoc-info
+                                   (cider--eldoc-remove-dot (cider-symbol-at-point)))))
+            `("eldoc-info" ,eldoc-info
+              "thing" ,(cider-symbol-at-point)
+              "pos" 0)))))))
+
+(defun cider-eldoc-info-at-sexp-beginning ()
+  "Return eldoc info for first symbol in the sexp."
+  (save-excursion
+    (when-let* ((beginning-of-sexp (cider-eldoc-beginning-of-sexp))
+                ;; If we are at the beginning of function name, this will be -1
+                (argument-index (max 0 (1- beginning-of-sexp))))
+      (unless (or (memq (or (char-before (point)) 0)
+                        '(?\" ?\{ ?\[))
+                  (cider-in-comment-p))
+        (when-let* ((eldoc-info (cider-eldoc-info
+                                 (cider--eldoc-remove-dot (cider-symbol-at-point)))))
+          `("eldoc-info" ,eldoc-info
+            "thing" ,(cider-symbol-at-point)
+            "pos" ,argument-index))))))
+
+(defun cider-eldoc-info-in-current-sexp ()
+  "Return eldoc information from the sexp.
+If `cider-eldoc-display-for-symbol-at-poin' is non-nil and
+the symbol at point has a valid eldoc available, return that.
+Otherwise return the eldoc of the first symbol of the sexp."
+  (or (when cider-eldoc-display-for-symbol-at-point
+        (cider-eldoc-info-at-point))
+      (cider-eldoc-info-at-sexp-beginning)))
+
+(defun cider-eldoc--convert-ns-keywords (thing)
+  "Convert THING values that match ns macro keywords to function names."
+  (pcase thing
+    (":import" "clojure.core/import")
+    (":refer-clojure" "clojure.core/refer-clojure")
+    (":use" "clojure.core/use")
+    (":refer" "clojure.core/refer")
+    (_ thing)))
+
+(defun cider-eldoc-info (thing)
+  "Return the info for THING.
+This includes the arglist and ns and symbol name (if available)."
+  (let ((thing (cider-eldoc--convert-ns-keywords thing)))
+    (when (and (cider-nrepl-op-supported-p "eldoc")
+               thing
+               ;; ignore empty strings
+               (not (string= thing ""))
+               ;; ignore strings
+               (not (string-prefix-p "\"" thing))
+               ;; ignore regular expressions
+               (not (string-prefix-p "#" thing))
+               ;; ignore chars
+               (not (string-prefix-p "\\" thing))
+               ;; ignore numbers
+               (not (string-match-p "^[0-9]" thing)))
+      ;; check if we can used the cached eldoc info
+      (cond
+       ;; handle keywords for map access
+       ((string-prefix-p ":" thing) (list "symbol" thing
+                                          "type" "function"
+                                          "arglists" '(("map") ("map" "not-found"))))
+       ;; handle Classname. by displaying the eldoc for new
+       ((string-match-p "^[A-Z].+\\.$" thing) (list "symbol" thing
+                                                    "type" "function"
+                                                    "arglists" '(("args*"))))
+       ;; generic case
+       (t (if (equal thing (car cider-eldoc-last-symbol))
+              (cadr cider-eldoc-last-symbol)
+            (when-let* ((eldoc-info (cider-sync-request:eldoc thing)))
+              (let* ((arglists (nrepl-dict-get eldoc-info "eldoc"))
+                     (docstring (nrepl-dict-get eldoc-info "docstring"))
+                     (type (nrepl-dict-get eldoc-info "type"))
+                     (ns (nrepl-dict-get eldoc-info "ns"))
+                     (class (nrepl-dict-get eldoc-info "class"))
+                     (name (nrepl-dict-get eldoc-info "name"))
+                     (member (nrepl-dict-get eldoc-info "member"))
+                     (ns-or-class (if (and ns (not (string= ns "")))
+                                      ns
+                                    class))
+                     (name-or-member (if (and name (not (string= name "")))
+                                         name
+                                       (format ".%s" member)))
+                     (eldoc-plist (list "ns" ns-or-class
+                                        "symbol" name-or-member
+                                        "arglists" arglists
+                                        "docstring" docstring
+                                        "type" type)))
+                ;; add context dependent args if requested by defcustom
+                ;; do not cache this eldoc info to avoid showing info
+                                        ;: of the previous context
+                (if cider-eldoc-display-context-dependent-info
+                    (cond
+                     ;; add inputs of datomic query
+                     ((and (equal ns-or-class "datomic.api")
+                           (equal name-or-member "q"))
+                      (let ((arglists (lax-plist-get eldoc-plist "arglists")))
+                        (lax-plist-put eldoc-plist "arglists"
+                                       (cider--eldoc-add-datomic-query-inputs-to-arglists arglists))))
+                     ;; if none of the clauses is successful, do cache the eldoc
+                     (t (setq cider-eldoc-last-symbol (list thing eldoc-plist))))
+                  ;; middleware eldoc lookups are expensive, so we
+                  ;; cache the last lookup.  This eliminates the need
+                  ;; for extra middleware requests within the same sexp.
+                  (setq cider-eldoc-last-symbol (list thing eldoc-plist)))
+                eldoc-plist))))))))
+
+(defun cider--eldoc-remove-dot (sym)
+  "Remove the preceding \".\" from a namespace qualified SYM and return sym.
+Only useful for interop forms.  Clojure forms would be returned unchanged."
+  (when sym (replace-regexp-in-string "/\\." "/" sym)))
+
+(defun cider--eldoc-edn-file-p (file-name)
+  "Check whether FILE-NAME is representing an EDN file."
+  (and file-name (equal (file-name-extension file-name) "edn")))
+
+(defun cider--eldoc-add-datomic-query-inputs-to-arglists (arglists)
+  "Add the expected inputs of the datomic query to the ARGLISTS."
+  (if (cider-second-sexp-in-list)
+      (let* ((query (cider-second-sexp-in-list))
+             (query-inputs (nrepl-dict-get
+                            (cider-sync-request:eldoc-datomic-query query)
+                            "inputs")))
+        (if query-inputs
+            (thread-first
+                (thread-last arglists
+                  (car)
+                  (remove "&")
+                  (remove "inputs"))
+              (append (car query-inputs))
+              (list))
+          arglists))
+    arglists))
+
+(defun cider-eldoc ()
+  "Backend function for eldoc to show argument list in the echo area."
+  (when (and (cider-connected-p)
+             ;; don't clobber an error message in the minibuffer
+             (not (member last-command '(next-error previous-error)))
+             ;; don't try to provide eldoc in EDN buffers
+             (not (cider--eldoc-edn-file-p buffer-file-name)))
+    (let* ((sexp-eldoc-info (cider-eldoc-info-in-current-sexp))
+           (eldoc-info (lax-plist-get sexp-eldoc-info "eldoc-info"))
+           (pos (lax-plist-get sexp-eldoc-info "pos"))
+           (thing (lax-plist-get sexp-eldoc-info "thing")))
+      (when eldoc-info
+        (if (equal (cider-eldoc-thing-type eldoc-info) 'fn)
+            (cider-eldoc-format-function thing pos eldoc-info)
+          (cider-eldoc-format-variable thing eldoc-info))))))
+
+(defun cider-eldoc-setup ()
+  "Setup eldoc in the current buffer.
+eldoc mode has to be enabled for this to have any effect."
+  (setq-local eldoc-documentation-function #'cider-eldoc)
+  (apply #'eldoc-add-command cider-extra-eldoc-commands))
+
+(provide 'cider-eldoc)
+
+;;; cider-eldoc.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-eldoc.elc b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-eldoc.elc
new file mode 100644
index 0000000000..db499612c2
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-eldoc.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-eval.el b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-eval.el
new file mode 100644
index 0000000000..8191da5245
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-eval.el
@@ -0,0 +1,1098 @@
+;;; cider-eval.el --- Interactive evaluation (compilation) functionality -*- lexical-binding: t -*-
+
+;; Copyright © 2012-2013 Tim King, Phil Hagelberg, Bozhidar Batsov
+;; Copyright © 2013-2018 Bozhidar Batsov, Artur Malabarba and CIDER contributors
+;;
+;; Author: Tim King <kingtim@gmail.com>
+;;         Phil Hagelberg <technomancy@gmail.com>
+;;         Bozhidar Batsov <bozhidar@batsov.com>
+;;         Artur Malabarba <bruce.connor.am@gmail.com>
+;;         Hugo Duncan <hugo@hugoduncan.org>
+;;         Steve Purcell <steve@sanityinc.com>
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;; This file is not part of GNU Emacs.
+
+;;; Commentary:
+
+;; This file contains CIDER's interactive evaluation (compilation) functionality.
+;; Although Clojure doesn't really have the concept of evaluation (only
+;; compilation), we're using everywhere in the code the term evaluation for
+;; brevity (and to be in line with the naming employed by other similar modes).
+;;
+;; This files also contains all the logic related to displaying errors and
+;; evaluation warnings.
+;;
+;; Pretty much all of the commands here are meant to be used mostly from
+;; `cider-mode', but some of them might make sense in other contexts as well.
+
+;;; Code:
+
+(require 'cider-client)
+(require 'cider-repl)
+(require 'cider-popup)
+(require 'cider-common)
+(require 'cider-util)
+(require 'cider-stacktrace)
+(require 'cider-overlays)
+(require 'cider-compat)
+
+(require 'clojure-mode)
+(require 'ansi-color)
+(require 'cl-lib)
+(require 'subr-x)
+(require 'compile)
+
+(defconst cider-read-eval-buffer "*cider-read-eval*")
+(defconst cider-result-buffer "*cider-result*")
+
+(defcustom cider-show-error-buffer t
+  "Control the popup behavior of cider stacktraces.
+The following values are possible t or 'always, 'except-in-repl,
+'only-in-repl.  Any other value, including nil, will cause the stacktrace
+not to be automatically shown.
+
+Irespective of the value of this variable, the `cider-error-buffer' is
+always generated in the background.  Use `cider-selector' to
+navigate to this buffer."
+  :type '(choice (const :tag "always" t)
+                 (const except-in-repl)
+                 (const only-in-repl)
+                 (const :tag "never" nil))
+  :group 'cider)
+
+(defcustom cider-auto-jump-to-error t
+  "Control the cursor jump behaviour in compilation error buffer.
+When non-nil automatically jump to error location during interactive
+compilation.  When set to 'errors-only, don't jump to warnings.
+When set to nil, don't jump at all."
+  :type '(choice (const :tag "always" t)
+                 (const errors-only)
+                 (const :tag "never" nil))
+  :group 'cider
+  :package-version '(cider . "0.7.0"))
+
+(defcustom cider-auto-select-error-buffer t
+  "Controls whether to auto-select the error popup buffer."
+  :type 'boolean
+  :group 'cider)
+
+(defcustom cider-auto-track-ns-form-changes t
+  "Controls whether to auto-evaluate a source buffer's ns form when changed.
+When non-nil CIDER will check for ns form changes before each eval command.
+When nil the users are expected to take care of the re-evaluating updated
+ns forms manually themselves."
+  :type 'boolean
+  :group 'cider
+  :package-version '(cider . "0.15.0"))
+
+(defcustom cider-save-file-on-load 'prompt
+  "Controls whether to prompt to save the file when loading a buffer.
+If nil, files are not saved.
+If 'prompt, the user is prompted to save the file if it's been modified.
+If t, save the file without confirmation."
+  :type '(choice (const prompt :tag "Prompt to save the file if it's been modified")
+                 (const nil :tag "Don't save the file")
+                 (const t :tag "Save the file without confirmation"))
+  :group 'cider
+  :package-version '(cider . "0.6.0"))
+
+
+(defconst cider-output-buffer "*cider-out*")
+
+(defcustom cider-interactive-eval-output-destination 'repl-buffer
+  "The destination for stdout and stderr produced from interactive evaluation."
+  :type '(choice (const output-buffer)
+                 (const repl-buffer))
+  :group 'cider
+  :package-version '(cider . "0.7.0"))
+
+(defface cider-error-highlight-face
+  '((((supports :underline (:style wave)))
+     (:underline (:style wave :color "red") :inherit unspecified))
+    (t (:inherit font-lock-warning-face :underline t)))
+  "Face used to highlight compilation errors in Clojure buffers."
+  :group 'cider)
+
+(defface cider-warning-highlight-face
+  '((((supports :underline (:style wave)))
+     (:underline (:style wave :color "yellow") :inherit unspecified))
+    (t (:inherit font-lock-warning-face :underline (:color "yellow"))))
+  "Face used to highlight compilation warnings in Clojure buffers."
+  :group 'cider)
+
+(defcustom cider-comment-prefix ";; => "
+  "The prefix to insert before the first line of commented output."
+  :type 'string
+  :group 'cider
+  :package-version '(cider . "0.16.0"))
+
+(defcustom cider-comment-continued-prefix ";;    "
+  "The prefix to use on the second and subsequent lines of commented output."
+  :type 'string
+  :group 'cider
+  :package-version '(cider . "0.16.0"))
+
+(defcustom cider-comment-postfix ""
+  "The postfix to be appended after the final line of commented output."
+  :type 'string
+  :group 'cider
+  :package-version '(cider . "0.16.0"))
+
+
+;;; Utilities
+
+(defun cider--clear-compilation-highlights ()
+  "Remove compilation highlights."
+  (remove-overlays (point-min) (point-max) 'cider-note-p t))
+
+(defun cider-clear-compilation-highlights (&optional arg)
+  "Remove compilation highlights.
+When invoked with a prefix ARG the command doesn't prompt for confirmation."
+  (interactive "P")
+  (when (or arg (y-or-n-p "Are you sure you want to clear the compilation highlights? "))
+    (cider--clear-compilation-highlights)))
+
+(defun cider--quit-error-window ()
+  "Buries the `cider-error-buffer' and quits its containing window."
+  (when-let* ((error-win (get-buffer-window cider-error-buffer)))
+    (quit-window nil error-win)))
+
+
+;;; Dealing with compilation (evaluation) errors and warnings
+(defun cider-find-property (property &optional backward)
+  "Find the next text region which has the specified PROPERTY.
+If BACKWARD is t, then search backward.
+Returns the position at which PROPERTY was found, or nil if not found."
+  (let ((p (if backward
+               (previous-single-char-property-change (point) property)
+             (next-single-char-property-change (point) property))))
+    (when (and (not (= p (point-min))) (not (= p (point-max))))
+      p)))
+
+(defun cider-jump-to-compilation-error (&optional _arg _reset)
+  "Jump to the line causing the current compilation error.
+_ARG and _RESET are ignored, as there is only ever one compilation error.
+They exist for compatibility with `next-error'."
+  (interactive)
+  (cl-labels ((goto-next-note-boundary
+               ()
+               (let ((p (or (cider-find-property 'cider-note-p)
+                            (cider-find-property 'cider-note-p t))))
+                 (when p
+                   (goto-char p)
+                   (message "%s" (get-char-property p 'cider-note))))))
+    ;; if we're already on a compilation error, first jump to the end of
+    ;; it, so that we find the next error.
+    (when (get-char-property (point) 'cider-note-p)
+      (goto-next-note-boundary))
+    (goto-next-note-boundary)))
+
+(defun cider--show-error-buffer-p ()
+  "Return non-nil if the error buffer must be shown on error.
+Takes into account both the value of `cider-show-error-buffer' and the
+currently selected buffer."
+  (let* ((selected-buffer (window-buffer (selected-window)))
+         (replp (with-current-buffer selected-buffer (derived-mode-p 'cider-repl-mode))))
+    (memq cider-show-error-buffer
+          (if replp
+              '(t always only-in-repl)
+            '(t always except-in-repl)))))
+
+(defun cider-new-error-buffer (&optional mode error-types)
+  "Return an empty error buffer using MODE.
+
+When deciding whether to display the buffer, takes into account not only
+the value of `cider-show-error-buffer' and the currently selected buffer
+but also the ERROR-TYPES of the error, which is checked against the
+`cider-stacktrace-suppressed-errors' set.
+
+When deciding whether to select the buffer, takes into account the value of
+`cider-auto-select-error-buffer'."
+  (if (and (cider--show-error-buffer-p)
+           (not (cider-stacktrace-some-suppressed-errors-p error-types)))
+      (cider-popup-buffer cider-error-buffer cider-auto-select-error-buffer mode 'ancillary)
+    (cider-make-popup-buffer cider-error-buffer mode 'ancillary)))
+
+(defun cider-emit-into-color-buffer (buffer value)
+  "Emit into color BUFFER the provided VALUE."
+  (with-current-buffer buffer
+    (let ((inhibit-read-only t)
+          (buffer-undo-list t))
+      (goto-char (point-max))
+      (insert (format "%s" value))
+      (ansi-color-apply-on-region (point-min) (point-max)))
+    (goto-char (point-min))))
+
+(defun cider--handle-err-eval-response (response)
+  "Render eval RESPONSE into a new error buffer.
+
+Uses the value of the `out' slot in RESPONSE."
+  (nrepl-dbind-response response (out)
+    (when out
+      (let ((error-buffer (cider-new-error-buffer)))
+        (cider-emit-into-color-buffer error-buffer out)
+        (with-current-buffer error-buffer
+          (compilation-minor-mode +1))))))
+
+(defun cider-default-err-eval-handler ()
+  "Display the last exception without middleware support."
+  (cider--handle-err-eval-response
+   (cider-nrepl-sync-request:eval
+    "(clojure.stacktrace/print-cause-trace *e)")))
+
+(defun cider--render-stacktrace-causes (causes &optional error-types)
+  "If CAUSES is non-nil, render its contents into a new error buffer.
+Optional argument ERROR-TYPES contains a list which should determine the
+op/situation that originated this error."
+  (when causes
+    (let ((error-buffer (cider-new-error-buffer #'cider-stacktrace-mode error-types)))
+      (cider-stacktrace-render error-buffer (reverse causes) error-types))))
+
+(defun cider--handle-stacktrace-response (response causes)
+  "Handle stacktrace op RESPONSE, aggregating the result into CAUSES.
+If RESPONSE contains a cause, cons it onto CAUSES and return that.  If
+RESPONSE is the final message (i.e. it contains a status), render CAUSES
+into a new error buffer."
+  (nrepl-dbind-response response (class status)
+    (cond (class (cons response causes))
+          (status (cider--render-stacktrace-causes causes)))))
+
+(defun cider-default-err-op-handler ()
+  "Display the last exception, with middleware support."
+  ;; Causes are returned as a series of messages, which we aggregate in `causes'
+  (let (causes)
+    (cider-nrepl-send-request
+     (nconc '("op" "stacktrace")
+            (when (cider--pprint-fn)
+              `("pprint-fn" ,(cider--pprint-fn)))
+            (when cider-stacktrace-print-length
+              `("print-length" ,cider-stacktrace-print-length))
+            (when cider-stacktrace-print-level
+              `("print-level" ,cider-stacktrace-print-level)))
+     (lambda (response)
+       ;; While the return value of `cider--handle-stacktrace-response' is not
+       ;; meaningful for the last message, we do not need the value of `causes'
+       ;; after it has been handled, so it's fine to set it unconditionally here
+       (setq causes (cider--handle-stacktrace-response response causes))))))
+
+(defun cider-default-err-handler ()
+  "This function determines how the error buffer is shown.
+It delegates the actual error content to the eval or op handler."
+  (if (cider-nrepl-op-supported-p "stacktrace")
+      (cider-default-err-op-handler)
+    (cider-default-err-eval-handler)))
+
+(defvar cider-compilation-regexp
+  '("\\(?:.*\\(warning, \\)\\|.*?\\(, compiling\\):(\\)\\(.*?\\):\\([[:digit:]]+\\)\\(?::\\([[:digit:]]+\\)\\)?\\(\\(?: - \\(.*\\)\\)\\|)\\)" 3 4 5 (1))
+  "Specifications for matching errors and warnings in Clojure stacktraces.
+See `compilation-error-regexp-alist' for help on their format.")
+
+(add-to-list 'compilation-error-regexp-alist-alist
+             (cons 'cider cider-compilation-regexp))
+(add-to-list 'compilation-error-regexp-alist 'cider)
+
+(defun cider-extract-error-info (regexp message)
+  "Extract error information with REGEXP against MESSAGE."
+  (let ((file (nth 1 regexp))
+        (line (nth 2 regexp))
+        (col (nth 3 regexp))
+        (type (nth 4 regexp))
+        (pat (car regexp)))
+    (when (string-match pat message)
+      ;; special processing for type (1.2) style
+      (setq type (if (consp type)
+                     (or (and (car type) (match-end (car type)) 1)
+                         (and (cdr type) (match-end (cdr type)) 0)
+                         2)))
+      (list
+       (when file
+         (let ((val (match-string-no-properties file message)))
+           (unless (string= val "NO_SOURCE_PATH") val)))
+       (when line (string-to-number (match-string-no-properties line message)))
+       (when col
+         (let ((val (match-string-no-properties col message)))
+           (when val (string-to-number val))))
+       (aref [cider-warning-highlight-face
+              cider-warning-highlight-face
+              cider-error-highlight-face]
+             (or type 2))
+       message))))
+
+(defun cider--goto-expression-start ()
+  "Go to the beginning a list, vector, map or set outside of a string.
+We do so by starting and the current position and proceeding backwards
+until we find a delimiters that's not inside a string."
+  (if (and (looking-back "[])}]" (line-beginning-position))
+           (null (nth 3 (syntax-ppss))))
+      (backward-sexp)
+    (while (or (not (looking-at-p "[({[]"))
+               (nth 3 (syntax-ppss)))
+      (backward-char))))
+
+(defun cider--find-last-error-location (message)
+  "Return the location (begin end buffer) from the Clojure error MESSAGE.
+If location could not be found, return nil."
+  (save-excursion
+    (let ((info (cider-extract-error-info cider-compilation-regexp message)))
+      (when info
+        (let ((file (nth 0 info))
+              (line (nth 1 info))
+              (col (nth 2 info)))
+          (unless (or (not (stringp file))
+                      (cider--tooling-file-p file))
+            (when-let* ((buffer (cider-find-file file)))
+              (with-current-buffer buffer
+                (save-excursion
+                  (save-restriction
+                    (widen)
+                    (goto-char (point-min))
+                    (forward-line (1- line))
+                    (move-to-column (or col 0))
+                    (let ((begin (progn (if col (cider--goto-expression-start) (back-to-indentation))
+                                        (point)))
+                          (end (progn (if col (forward-list) (move-end-of-line nil))
+                                      (point))))
+                      (list begin end buffer))))))))))))
+
+(defun cider-handle-compilation-errors (message eval-buffer)
+  "Highlight and jump to compilation error extracted from MESSAGE.
+EVAL-BUFFER is the buffer that was current during user's interactive
+evaluation command.  Honor `cider-auto-jump-to-error'."
+  (when-let* ((loc (cider--find-last-error-location message))
+              (overlay (make-overlay (nth 0 loc) (nth 1 loc) (nth 2 loc)))
+              (info (cider-extract-error-info cider-compilation-regexp message)))
+    (let* ((face (nth 3 info))
+           (note (nth 4 info))
+           (auto-jump (if (eq cider-auto-jump-to-error 'errors-only)
+                          (not (eq face 'cider-warning-highlight-face))
+                        cider-auto-jump-to-error)))
+      (overlay-put overlay 'cider-note-p t)
+      (overlay-put overlay 'font-lock-face face)
+      (overlay-put overlay 'cider-note note)
+      (overlay-put overlay 'help-echo note)
+      (overlay-put overlay 'modification-hooks
+                   (list (lambda (o &rest _args) (delete-overlay o))))
+      (when auto-jump
+        (with-current-buffer eval-buffer
+          (push-mark)
+          ;; At this stage selected window commonly is *cider-error* and we need to
+          ;; re-select the original user window. If eval-buffer is not
+          ;; visible it was probably covered as a result of a small screen or user
+          ;; configuration (https://github.com/clojure-emacs/cider/issues/847). In
+          ;; that case we don't jump at all in order to avoid covering *cider-error*
+          ;; buffer.
+          (when-let* ((win (get-buffer-window eval-buffer)))
+            (with-selected-window win
+              (cider-jump-to (nth 2 loc) (car loc)))))))))
+
+
+;;; Interactive evaluation handlers
+(defun cider-insert-eval-handler (&optional buffer)
+  "Make an nREPL evaluation handler for the BUFFER.
+The handler simply inserts the result value in BUFFER."
+  (let ((eval-buffer (current-buffer)))
+    (nrepl-make-response-handler (or buffer eval-buffer)
+                                 (lambda (_buffer value)
+                                   (with-current-buffer buffer
+                                     (insert value)))
+                                 (lambda (_buffer out)
+                                   (cider-repl-emit-interactive-stdout out))
+                                 (lambda (_buffer err)
+                                   (cider-handle-compilation-errors err eval-buffer))
+                                 '())))
+
+(defun cider--emit-interactive-eval-output (output repl-emit-function)
+  "Emit output resulting from interactive code evaluation.
+The OUTPUT can be sent to either a dedicated output buffer or the current
+REPL buffer.  This is controlled by `cider-interactive-eval-output-destination'.
+REPL-EMIT-FUNCTION emits the OUTPUT."
+  (pcase cider-interactive-eval-output-destination
+    (`output-buffer (let ((output-buffer (or (get-buffer cider-output-buffer)
+                                             (cider-popup-buffer cider-output-buffer t))))
+                      (cider-emit-into-popup-buffer output-buffer output)
+                      (pop-to-buffer output-buffer)))
+    (`repl-buffer (funcall repl-emit-function output))
+    (_ (error "Unsupported value %s for `cider-interactive-eval-output-destination'"
+              cider-interactive-eval-output-destination))))
+
+(defun cider-emit-interactive-eval-output (output)
+  "Emit OUTPUT resulting from interactive code evaluation.
+The output can be send to either a dedicated output buffer or the current
+REPL buffer.  This is controlled via
+`cider-interactive-eval-output-destination'."
+  (cider--emit-interactive-eval-output output 'cider-repl-emit-interactive-stdout))
+
+(defun cider-emit-interactive-eval-err-output (output)
+  "Emit err OUTPUT resulting from interactive code evaluation.
+The output can be send to either a dedicated output buffer or the current
+REPL buffer.  This is controlled via
+`cider-interactive-eval-output-destination'."
+  (cider--emit-interactive-eval-output output 'cider-repl-emit-interactive-stderr))
+
+(defun cider--make-fringe-overlays-for-region (beg end)
+  "Place eval indicators on all sexps between BEG and END."
+  (with-current-buffer (if (markerp end)
+                           (marker-buffer end)
+                         (current-buffer))
+    (save-excursion
+      (goto-char beg)
+      (remove-overlays beg end 'category 'cider-fringe-indicator)
+      (condition-case nil
+          (while (progn (clojure-forward-logical-sexp)
+                        (and (<= (point) end)
+                             (not (eobp))))
+            (cider--make-fringe-overlay (point)))
+        (scan-error nil)))))
+
+(defun cider-interactive-eval-handler (&optional buffer place)
+  "Make an interactive eval handler for BUFFER.
+PLACE is used to display the evaluation result.
+If non-nil, it can be the position where the evaluated sexp ends,
+or it can be a list with (START END) of the evaluated region."
+  (let* ((eval-buffer (current-buffer))
+         (beg (car-safe place))
+         (end (or (car-safe (cdr-safe place)) place))
+         (beg (when beg (copy-marker beg)))
+         (end (when end (copy-marker end)))
+         (fringed nil))
+    (nrepl-make-response-handler (or buffer eval-buffer)
+                                 (lambda (_buffer value)
+                                   (if beg
+                                       (unless fringed
+                                         (cider--make-fringe-overlays-for-region beg end)
+                                         (setq fringed t))
+                                     (cider--make-fringe-overlay end))
+                                   (cider--display-interactive-eval-result value end))
+                                 (lambda (_buffer out)
+                                   (cider-emit-interactive-eval-output out))
+                                 (lambda (_buffer err)
+                                   (cider-emit-interactive-eval-err-output err)
+                                   (cider-handle-compilation-errors err eval-buffer))
+                                 '())))
+
+(defun cider-load-file-handler (&optional buffer)
+  "Make a load file handler for BUFFER."
+  (let ((eval-buffer (current-buffer)))
+    (nrepl-make-response-handler (or buffer eval-buffer)
+                                 (lambda (buffer value)
+                                   (cider--display-interactive-eval-result value)
+                                   (when (buffer-live-p buffer)
+                                     (with-current-buffer buffer
+                                       (cider--make-fringe-overlays-for-region (point-min) (point-max))
+                                       (run-hooks 'cider-file-loaded-hook))))
+                                 (lambda (_buffer value)
+                                   (cider-emit-interactive-eval-output value))
+                                 (lambda (_buffer err)
+                                   (cider-emit-interactive-eval-err-output err)
+                                   (cider-handle-compilation-errors err eval-buffer))
+                                 '()
+                                 (lambda ()
+                                   (funcall nrepl-err-handler)))))
+
+(defun cider-eval-print-handler (&optional buffer)
+  "Make a handler for evaluating and printing result in BUFFER."
+  (nrepl-make-response-handler (or buffer (current-buffer))
+                               (lambda (buffer value)
+                                 (with-current-buffer buffer
+                                   (insert
+                                    (if (derived-mode-p 'cider-clojure-interaction-mode)
+                                        (format "\n%s\n" value)
+                                      value))))
+                               (lambda (_buffer out)
+                                 (cider-emit-interactive-eval-output out))
+                               (lambda (_buffer err)
+                                 (cider-emit-interactive-eval-err-output err))
+                               '()))
+
+(defun cider-eval-print-with-comment-handler (buffer location comment-prefix)
+  "Make a handler for evaluating and printing commented results in BUFFER.
+LOCATION is the location at which to insert.  COMMENT-PREFIX is the comment
+prefix to use."
+  (nrepl-make-response-handler buffer
+                               (lambda (buffer value)
+                                 (with-current-buffer buffer
+                                   (save-excursion
+                                     (goto-char location)
+                                     (insert (concat comment-prefix
+                                                     value "\n")))))
+                               (lambda (_buffer out)
+                                 (cider-emit-interactive-eval-output out))
+                               (lambda (_buffer err)
+                                 (cider-emit-interactive-eval-err-output err))
+                               '()))
+
+(defun cider-eval-pprint-with-multiline-comment-handler (buffer location comment-prefix continued-prefix comment-postfix)
+  "Make a handler for evaluating and inserting results in BUFFER.
+The inserted text is pretty-printed and region will be commented.
+LOCATION is the location at which to insert.
+COMMENT-PREFIX is the comment prefix for the first line of output.
+CONTINUED-PREFIX is the comment prefix to use for the remaining lines.
+COMMENT-POSTFIX is the text to output after the last line."
+  (cl-flet ((multiline-comment-handler (buffer value)
+              (with-current-buffer buffer
+                (save-excursion
+                  (goto-char location)
+                  (let ((lines (split-string value "[\n]+" t)))
+                    ;; only the first line gets the normal comment-prefix
+                    (insert (concat comment-prefix (pop lines)))
+                    (dolist (elem lines)
+                      (insert (concat "\n" continued-prefix elem)))
+                    (unless (string= comment-postfix "")
+                      (insert comment-postfix)))))))
+    (nrepl-make-response-handler buffer
+                                 '()
+                                 #'multiline-comment-handler
+                                 #'multiline-comment-handler
+                                 '())))
+
+(defun cider-popup-eval-out-handler (&optional buffer)
+  "Make a handler for evaluating and printing stdout/stderr in popup BUFFER.
+This is used by pretty-printing commands and intentionally discards their results."
+  (cl-flet ((popup-output-handler (buffer str)
+                                  (cider-emit-into-popup-buffer buffer
+                                                                (ansi-color-apply str)
+                                                                nil
+                                                                t)))
+    (nrepl-make-response-handler (or buffer (current-buffer))
+                                 '()
+                                 ;; stdout handler
+                                 #'popup-output-handler
+                                 ;; stderr handler
+                                 #'popup-output-handler
+                                 '())))
+
+
+;;; Interactive valuation commands
+
+(defvar cider-to-nrepl-filename-function
+  (with-no-warnings
+    (if (eq system-type 'cygwin)
+        #'cygwin-convert-file-name-to-windows
+      #'identity))
+  "Function to translate Emacs filenames to nREPL namestrings.")
+
+(defun cider--prep-interactive-eval (form connection)
+  "Prepare the environment for an interactive eval of FORM in CONNECTION.
+Ensure the current ns declaration has been evaluated (so that the ns
+containing FORM exists).  Cache ns-form in the current buffer unless FORM is
+ns declaration itself.  Clear any compilation highlights and kill the error
+window."
+  (cider--clear-compilation-highlights)
+  (cider--quit-error-window)
+  (let ((cur-ns-form (cider-ns-form)))
+    (when (and cur-ns-form
+               (not (cider-ns-form-p form))
+               (cider-repl--ns-form-changed-p cur-ns-form connection))
+      (when cider-auto-track-ns-form-changes
+        ;; The first interactive eval on a file can load a lot of libs. This can
+        ;; easily lead to more than 10 sec.
+        (let ((nrepl-sync-request-timeout 30))
+          ;; TODO: check for evaluation errors
+          (cider-nrepl-sync-request:eval cur-ns-form connection)))
+      ;; cache at the end, in case of errors
+      (cider-repl--cache-ns-form cur-ns-form connection))))
+
+(defvar-local cider-interactive-eval-override nil
+  "Function to call instead of `cider-interactive-eval'.")
+
+(defun cider-interactive-eval (form &optional callback bounds additional-params)
+  "Evaluate FORM and dispatch the response to CALLBACK.
+If the code to be evaluated comes from a buffer, it is preferred to use a
+nil FORM, and specify the code via the BOUNDS argument instead.
+
+This function is the main entry point in CIDER's interactive evaluation
+API.  Most other interactive eval functions should rely on this function.
+If CALLBACK is nil use `cider-interactive-eval-handler'.
+BOUNDS, if non-nil, is a list of two numbers marking the start and end
+positions of FORM in its buffer.
+ADDITIONAL-PARAMS is a plist to be appended to the request message.
+
+If `cider-interactive-eval-override' is a function, call it with the same
+arguments and only proceed with evaluation if it returns nil."
+  (let ((form  (or form (apply #'buffer-substring-no-properties bounds)))
+        (start (car-safe bounds))
+        (end   (car-safe (cdr-safe bounds))))
+    (when (and start end)
+      (remove-overlays start end 'cider-temporary t))
+    (unless (and cider-interactive-eval-override
+                 (functionp cider-interactive-eval-override)
+                 (funcall cider-interactive-eval-override form callback bounds))
+      (cider-map-repls :auto
+        (lambda (connection)
+          (cider--prep-interactive-eval form connection)
+          (cider-nrepl-request:eval
+           form
+           (or callback (cider-interactive-eval-handler nil bounds))
+           ;; always eval ns forms in the user namespace
+           ;; otherwise trying to eval ns form for the first time will produce an error
+           (if (cider-ns-form-p form) "user" (cider-current-ns))
+           (when start (line-number-at-pos start))
+           (when start (cider-column-number-at-pos start))
+           additional-params
+           connection))))))
+
+(defun cider-eval-region (start end)
+  "Evaluate the region between START and END."
+  (interactive "r")
+  (cider-interactive-eval nil nil (list start end)))
+
+(defun cider-eval-last-sexp (&optional output-to-current-buffer)
+  "Evaluate the expression preceding point.
+If invoked with OUTPUT-TO-CURRENT-BUFFER, print the result in the current
+buffer."
+  (interactive "P")
+  (cider-interactive-eval nil
+                          (when output-to-current-buffer (cider-eval-print-handler))
+                          (cider-last-sexp 'bounds)))
+
+(defun cider-eval-last-sexp-and-replace ()
+  "Evaluate the expression preceding point and replace it with its result."
+  (interactive)
+  (let ((last-sexp (cider-last-sexp)))
+    ;; we have to be sure the evaluation won't result in an error
+    (cider-nrepl-sync-request:eval last-sexp)
+    ;; seems like the sexp is valid, so we can safely kill it
+    (backward-kill-sexp)
+    (cider-interactive-eval last-sexp (cider-eval-print-handler))))
+
+(defun cider-eval-sexp-at-point (&optional output-to-current-buffer)
+  "Evaluate the expression around point.
+If invoked with OUTPUT-TO-CURRENT-BUFFER, output the result to current buffer."
+  (interactive "P")
+  (save-excursion
+    (goto-char (cadr (cider-sexp-at-point 'bounds)))
+    (cider-eval-last-sexp output-to-current-buffer)))
+
+(defvar-local cider-previous-eval-context nil
+  "The previous evaluation context if any.
+That's set by commands like `cider-eval-last-sexp-in-context'.")
+
+(defun cider--eval-in-context (code)
+  "Evaluate CODE in user-provided evaluation context."
+  (let* ((code (string-trim-right code))
+         (eval-context (read-string
+                        (format "Evaluation context (let-style) for `%s': " code)
+                        cider-previous-eval-context))
+         (code (concat "(let [" eval-context "]\n  " code ")")))
+    (cider-interactive-eval code)
+    (setq-local cider-previous-eval-context eval-context)))
+
+(defun cider-eval-last-sexp-in-context ()
+  "Evaluate the preceding sexp in user-supplied context.
+The context is just a let binding vector (without the brackets).
+The context is remembered between command invocations."
+  (interactive)
+  (cider--eval-in-context (cider-last-sexp)))
+
+(defun cider-eval-sexp-at-point-in-context ()
+  "Evaluate the preceding sexp in user-supplied context.
+
+The context is just a let binding vector (without the brackets).
+The context is remembered between command invocations."
+  (interactive)
+  (cider--eval-in-context (cider-sexp-at-point)))
+
+(defun cider-eval-defun-to-comment (&optional insert-before)
+  "Evaluate the \"top-level\" form and insert result as comment.
+
+The formatting of the comment is defined in `cider-comment-prefix'
+which, by default, is \";; => \" and can be customized.
+
+With the prefix arg INSERT-BEFORE, insert before the form, otherwise afterwards."
+  (interactive "P")
+  (let* ((bounds (cider-defun-at-point 'bounds))
+         (insertion-point (nth (if insert-before 0 1) bounds)))
+    (cider-interactive-eval nil
+                            (cider-eval-print-with-comment-handler
+                             (current-buffer)
+                             insertion-point
+                             cider-comment-prefix)
+                            bounds)))
+
+(defun cider-pprint-form-to-comment (form-fn insert-before)
+  "Evaluate the form selected by FORM-FN and insert result as comment.
+FORM-FN can be either `cider-last-sexp' or `cider-defun-at-point'.
+
+The formatting of the comment is controlled via three options:
+    `cider-comment-prefix'           \";; => \"
+    `cider-comment-continued-prefix' \";;    \"
+    `cider-comment-postfix'          \"\"
+
+so that with customization you can optionally wrap the output
+in the reader macro \"#_( .. )\", or \"(comment ... )\", or any
+other desired formatting.
+
+If INSERT-BEFORE is non-nil, insert before the form, otherwise afterwards."
+  (let* ((bounds (funcall form-fn 'bounds))
+         (insertion-point (nth (if insert-before 0 1) bounds))
+         ;; when insert-before, we need a newline after the output to
+         ;; avoid commenting the first line of the form
+         (comment-postfix (concat cider-comment-postfix
+                                  (if insert-before "\n" ""))))
+    (cider-interactive-eval nil
+                            (cider-eval-pprint-with-multiline-comment-handler
+                             (current-buffer)
+                             insertion-point
+                             cider-comment-prefix
+                             cider-comment-continued-prefix
+                             comment-postfix)
+                            bounds
+                            (cider--nrepl-pprint-request-plist (cider--pretty-print-width)))))
+
+(defun cider-pprint-eval-last-sexp-to-comment (&optional insert-before)
+  "Evaluate the last sexp and insert result as comment.
+
+The formatting of the comment is controlled via three options:
+    `cider-comment-prefix'           \";; => \"
+    `cider-comment-continued-prefix' \";;    \"
+    `cider-comment-postfix'          \"\"
+
+so that with customization you can optionally wrap the output
+in the reader macro \"#_( .. )\", or \"(comment ... )\", or any
+other desired formatting.
+
+If INSERT-BEFORE is non-nil, insert before the form, otherwise afterwards."
+  (interactive "P")
+  (cider-pprint-form-to-comment 'cider-last-sexp insert-before))
+
+(defun cider-pprint-eval-defun-to-comment (&optional insert-before)
+  "Evaluate the \"top-level\" form and insert result as comment.
+
+The formatting of the comment is controlled via three options:
+    `cider-comment-prefix'           \";; => \"
+    `cider-comment-continued-prefix' \";;    \"
+    `cider-comment-postfix'          \"\"
+
+so that with customization you can optionally wrap the output
+in the reader macro \"#_( .. )\", or \"(comment ... )\", or any
+other desired formatting.
+
+If INSERT-BEFORE is non-nil, insert before the form, otherwise afterwards."
+  (interactive "P")
+  (cider-pprint-form-to-comment 'cider-defun-at-point insert-before))
+
+(declare-function cider-switch-to-repl-buffer "cider-mode")
+
+(defun cider-eval-last-sexp-to-repl (&optional prefix)
+  "Evaluate the expression preceding point and insert its result in the REPL.
+If invoked with a PREFIX argument, switch to the REPL buffer."
+  (interactive "P")
+  (cider-interactive-eval nil
+                          (cider-insert-eval-handler (cider-current-repl))
+                          (cider-last-sexp 'bounds))
+  (when prefix
+    (cider-switch-to-repl-buffer)))
+
+(defun cider-pprint-eval-last-sexp-to-repl (&optional prefix)
+  "Evaluate expr before point and insert its pretty-printed result in the REPL.
+If invoked with a PREFIX argument, switch to the REPL buffer."
+  (interactive "P")
+  (cider-interactive-eval nil
+                          (cider-insert-eval-handler (cider-current-repl))
+                          (cider-last-sexp 'bounds)
+                          (cider--nrepl-pprint-request-plist (cider--pretty-print-width)))
+  (when prefix
+    (cider-switch-to-repl-buffer)))
+
+(defun cider-eval-print-last-sexp ()
+  "Evaluate the expression preceding point.
+Print its value into the current buffer."
+  (interactive)
+  (cider-interactive-eval nil
+                          (cider-eval-print-handler)
+                          (cider-last-sexp 'bounds)))
+
+(defun cider--pprint-eval-form (form)
+  "Pretty print FORM in popup buffer."
+  (let* ((result-buffer (cider-popup-buffer cider-result-buffer nil 'clojure-mode 'ancillary))
+         (handler (cider-popup-eval-out-handler result-buffer)))
+    (cider-interactive-eval (when (stringp form) form)
+                            handler
+                            (when (consp form) form)
+                            (cider--nrepl-pprint-request-plist (cider--pretty-print-width)))))
+
+(defun cider-pprint-eval-last-sexp (&optional output-to-current-buffer)
+  "Evaluate the sexp preceding point and pprint its value.
+If invoked with OUTPUT-TO-CURRENT-BUFFER, insert as comment in the current
+buffer, else display in a popup buffer."
+  (interactive "P")
+  (if output-to-current-buffer
+      (cider-pprint-eval-last-sexp-to-comment)
+    (cider--pprint-eval-form (cider-last-sexp 'bounds))))
+
+(defun cider--prompt-and-insert-inline-dbg ()
+  "Insert a #dbg button at the current sexp."
+  (save-excursion
+    (let ((beg))
+      (skip-chars-forward "\r\n[:blank:]")
+      (unless (looking-at-p "(")
+        (ignore-errors (backward-up-list)))
+      (setq beg (point))
+      (let* ((cond (cider-read-from-minibuffer "Condition for debugging (leave empty for \"always\"): "))
+             (button (propertize (concat "#dbg"
+                                         (unless (equal cond "")
+                                           (format " ^{:break/when %s}" cond)))
+                                 'font-lock-face 'cider-fragile-button-face)))
+        (when (> (current-column) 30)
+          (insert "\n")
+          (indent-according-to-mode))
+        (insert button)
+        (when (> (current-column) 40)
+          (insert "\n")
+          (indent-according-to-mode)))
+      (make-button beg (point)
+                   'help-echo "Breakpoint. Reevaluate this form to remove it."
+                   :type 'cider-fragile))))
+
+(defun cider-eval-defun-at-point (&optional debug-it)
+  "Evaluate the current toplevel form, and print result in the minibuffer.
+With DEBUG-IT prefix argument, also debug the entire form as with the
+command `cider-debug-defun-at-point'."
+  (interactive "P")
+  (let ((inline-debug (eq 16 (car-safe debug-it))))
+    (when debug-it
+      (when (derived-mode-p 'clojurescript-mode)
+        (when (y-or-n-p (concat "The debugger doesn't support ClojureScript yet, and we need help with that."
+                                "  \nWould you like to read the Feature Request?"))
+          (browse-url "https://github.com/clojure-emacs/cider/issues/1416"))
+        (user-error "The debugger does not support ClojureScript"))
+      (when inline-debug
+        (cider--prompt-and-insert-inline-dbg)))
+    (cider-interactive-eval (when (and debug-it (not inline-debug))
+                              (concat "#dbg\n" (cider-defun-at-point)))
+                            nil (cider-defun-at-point 'bounds))))
+
+(defun cider--calculate-opening-delimiters ()
+  "Walks up the list of expressions to collect all sexp opening delimiters.
+The result is a list of the delimiters.
+
+That function is used in `cider-eval-defun-up-to-point' so it can make an
+incomplete expression complete."
+  (interactive)
+  (let ((result nil))
+    (save-excursion
+      (condition-case nil
+          (while t
+            (backward-up-list)
+            (push (char-after) result))
+        (error result)))))
+
+(defun cider--matching-delimiter (delimiter)
+  "Get the matching (opening/closing) delimiter for DELIMITER."
+  (pcase delimiter
+    (?\( ?\))
+    (?\[ ?\])
+    (?\{ ?\})
+    (?\) ?\()
+    (?\] ?\[)
+    (?\} ?\{)))
+
+(defun cider--calculate-closing-delimiters ()
+  "Compute the list of closing delimiters to make the defun before point valid."
+  (mapcar #'cider--matching-delimiter (cider--calculate-opening-delimiters)))
+
+(defun cider-eval-defun-up-to-point (&optional output-to-current-buffer)
+  "Evaluate the current toplevel form up to point.
+If invoked with OUTPUT-TO-CURRENT-BUFFER, print the result in the current
+buffer.  It constructs an expression to eval in the following manner:
+
+- It find the code between the point and the start of the toplevel expression;
+- It balances this bit of code by closing all open expressions;
+- It evaluates the resulting code using `cider-interactive-eval'."
+  (interactive "P")
+  (let* ((beg-of-defun (save-excursion (beginning-of-defun) (point)))
+         (code (buffer-substring-no-properties beg-of-defun (point)))
+         (code (concat code (cider--calculate-closing-delimiters))))
+    (cider-interactive-eval
+     code
+     (when output-to-current-buffer (cider-eval-print-handler)))))
+
+(defun cider-eval-sexp-up-to-point (&optional  output-to-current-buffer)
+  "Evaluate the current sexp form up to point.
+If invoked with OUTPUT-TO-CURRENT-BUFFER, print the result in the current
+buffer.  It constructs an expression to eval in the following manner:
+
+- It finds the code between the point and the start of the sexp expression;
+- It balances this bit of code by closing the expression;
+- It evaluates the resulting code using `cider-interactive-eval'."
+  (interactive "P")
+  (let* ((beg-of-sexp (save-excursion (up-list) (backward-list) (point)))
+         (beg-delimiter (save-excursion (up-list) (backward-list) (char-after)))
+         (beg-set?  (save-excursion (up-list) (backward-list) (char-before)))
+         (code (buffer-substring-no-properties beg-of-sexp (point)))
+         (code (if (= beg-set? ?#) (concat (list beg-set?) code) code))
+         (code (concat code (list (cider--matching-delimiter beg-delimiter)))))
+    (cider-interactive-eval code
+                            (when output-to-current-buffer (cider-eval-print-handler)))))
+
+(defun cider-pprint-eval-defun-at-point (&optional output-to-current-buffer)
+  "Evaluate the \"top-level\" form at point and pprint its value.
+If invoked with OUTPUT-TO-CURRENT-BUFFER, insert as comment in the current
+buffer, else display in a popup buffer."
+  (interactive "P")
+  (if output-to-current-buffer
+      (cider-pprint-eval-defun-to-comment)
+    (cider--pprint-eval-form (cider-defun-at-point 'bounds))))
+
+(defun cider-eval-ns-form ()
+  "Evaluate the current buffer's namespace form."
+  (interactive)
+  (when (clojure-find-ns)
+    (save-excursion
+      (goto-char (match-beginning 0))
+      (cider-eval-defun-at-point))))
+
+(defun cider-read-and-eval (&optional value)
+  "Read a sexp from the minibuffer and output its result to the echo area.
+If VALUE is non-nil, it is inserted into the minibuffer as initial input."
+  (interactive)
+  (let* ((form (cider-read-from-minibuffer "Clojure Eval: " value))
+         (override cider-interactive-eval-override)
+         (ns-form (if (cider-ns-form-p form) "" (format "(ns %s)" (cider-current-ns)))))
+    (with-current-buffer (get-buffer-create cider-read-eval-buffer)
+      (erase-buffer)
+      (clojure-mode)
+      (unless (string= "" ns-form)
+        (insert ns-form "\n\n"))
+      (insert form)
+      (let ((cider-interactive-eval-override override))
+        (cider-interactive-eval form)))))
+
+(defun cider-read-and-eval-defun-at-point ()
+  "Insert the toplevel form at point in the minibuffer and output its result.
+The point is placed next to the function name in the minibuffer to allow
+passing arguments."
+  (interactive)
+  (let* ((fn-name (cadr (split-string (cider-defun-at-point))))
+         (form (format "(%s)" fn-name)))
+    (cider-read-and-eval (cons form (length form)))))
+
+;; Eval keymap
+
+(defvar cider-eval-commands-map
+  (let ((map (define-prefix-command 'cider-eval-commands-map)))
+    ;; single key bindings defined last for display in menu
+    (define-key map (kbd "w") #'cider-eval-last-sexp-and-replace)
+    (define-key map (kbd "r") #'cider-eval-region)
+    (define-key map (kbd "n") #'cider-eval-ns-form)
+    (define-key map (kbd "d") #'cider-eval-defun-at-point)
+    (define-key map (kbd "f") #'cider-eval-last-sexp)
+    (define-key map (kbd "v") #'cider-eval-sexp-at-point)
+    (define-key map (kbd "o") #'cider-eval-sexp-up-to-point)
+    (define-key map (kbd ".") #'cider-read-and-eval-defun-at-point)
+    (define-key map (kbd "z") #'cider-eval-defun-up-to-point)
+    (define-key map (kbd "c") #'cider-eval-last-sexp-in-context)
+    (define-key map (kbd "b") #'cider-eval-sexp-at-point-in-context)
+
+    ;; duplicates with C- for convenience
+    (define-key map (kbd "C-w") #'cider-eval-last-sexp-and-replace)
+    (define-key map (kbd "C-r") #'cider-eval-region)
+    (define-key map (kbd "C-n") #'cider-eval-ns-form)
+    (define-key map (kbd "C-d") #'cider-eval-defun-at-point)
+    (define-key map (kbd "C-f") #'cider-eval-last-sexp)
+    (define-key map (kbd "C-v") #'cider-eval-sexp-at-point)
+    (define-key map (kbd "C-o") #'cider-eval-sexp-up-to-point)
+    (define-key map (kbd "C-.") #'cider-read-and-eval-defun-at-point)
+    (define-key map (kbd "C-z") #'cider-eval-defun-up-to-point)
+    (define-key map (kbd "C-c") #'cider-eval-last-sexp-in-context)
+    (define-key map (kbd "C-b") #'cider-eval-sexp-at-point-in-context)))
+
+(defun cider--file-string (file)
+  "Read the contents of a FILE and return as a string."
+  (with-current-buffer (find-file-noselect file)
+    (substring-no-properties (buffer-string))))
+
+(defun cider-load-buffer (&optional buffer)
+  "Load (eval) BUFFER's file in nREPL.
+If no buffer is provided the command acts on the current buffer.  If the
+buffer is for a cljc file, and both a Clojure and ClojureScript REPL exists
+for the project, it is evaluated in both REPLs."
+  (interactive)
+  (setq buffer (or buffer (current-buffer)))
+  ;; When cider-load-buffer or cider-load-file are called in programs the
+  ;; current context might not match the buffer's context. We use the caller
+  ;; context instead of the buffer's context because that's the common use
+  ;; case. For the other use case just let-bind the default-directory.
+  (let ((orig-default-directory default-directory))
+    (with-current-buffer buffer
+      (check-parens)
+      (let ((default-directory orig-default-directory))
+        (unless buffer-file-name
+          (user-error "Buffer `%s' is not associated with a file" (current-buffer)))
+        (when (and cider-save-file-on-load
+                   (buffer-modified-p)
+                   (or (eq cider-save-file-on-load t)
+                       (y-or-n-p (format "Save file %s? " buffer-file-name))))
+          (save-buffer))
+        (remove-overlays nil nil 'cider-temporary t)
+        (cider--clear-compilation-highlights)
+        (cider--quit-error-window)
+        (let ((filename (buffer-file-name buffer))
+              (ns-form  (cider-ns-form)))
+          (cider-map-repls :auto
+            (lambda (repl)
+              (when ns-form
+                (cider-repl--cache-ns-form ns-form repl))
+              (cider-request:load-file (cider--file-string filename)
+                                       (funcall cider-to-nrepl-filename-function
+                                                (cider--server-filename filename))
+                                       (file-name-nondirectory filename)
+                                       repl)))
+          (message "Loading %s..." filename))))))
+
+(defun cider-load-file (filename)
+  "Load (eval) the Clojure file FILENAME in nREPL.
+If the file is a cljc file, and both a Clojure and ClojureScript REPL
+exists for the project, it is evaluated in both REPLs.  The heavy lifting
+is done by `cider-load-buffer'."
+  (interactive (list
+                (read-file-name "Load file: " nil nil nil
+                                (when (buffer-file-name)
+                                  (file-name-nondirectory
+                                   (buffer-file-name))))))
+  (if-let* ((buffer (find-buffer-visiting filename)))
+      (cider-load-buffer buffer)
+    (cider-load-buffer (find-file-noselect filename))))
+
+(defun cider-load-all-files (directory)
+  "Load all files in DIRECTORY (recursively).
+Useful when the running nREPL on remote host."
+  (interactive "DLoad files beneath directory: ")
+  (mapcar #'cider-load-file
+          (directory-files-recursively directory ".clj$")))
+
+(defalias 'cider-eval-file 'cider-load-file
+  "A convenience alias as some people are confused by the load-* names.")
+
+(defalias 'cider-eval-all-files 'cider-load-all-files
+  "A convenience alias as some people are confused by the load-* names.")
+
+(defalias 'cider-eval-buffer 'cider-load-buffer
+  "A convenience alias as some people are confused by the load-* names.")
+
+(defun cider-load-all-project-ns ()
+  "Load all namespaces in the current project."
+  (interactive)
+  (cider-ensure-connected)
+  (cider-ensure-op-supported "ns-load-all")
+  (when (y-or-n-p "Are you sure you want to load all namespaces in the project? ")
+    (message "Loading all project namespaces...")
+    (let ((loaded-ns-count (length (cider-sync-request:ns-load-all))))
+      (message "Loaded %d namespaces" loaded-ns-count))))
+
+(provide 'cider-eval)
+
+;;; cider-eval.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-eval.elc b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-eval.elc
new file mode 100644
index 0000000000..b6a95194f9
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-eval.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-find.el b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-find.el
new file mode 100644
index 0000000000..7b598c5a76
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-find.el
@@ -0,0 +1,220 @@
+;;; cider-find.el --- Functionality for finding things -*- lexical-binding: t -*-
+
+;; Copyright © 2013-2018 Bozhidar Batsov, Artur Malabarba and CIDER contributors
+;;
+;; Author: Bozhidar Batsov <bozhidar@batsov.com>
+;;         Artur Malabarba <bruce.connor.am@gmail.com>
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;; This file is not part of GNU Emacs.
+
+;;; Commentary:
+
+;; A bunch of commands for finding resources and definitions.
+
+;;; Code:
+
+(require 'cider-client)
+(require 'cider-common)
+
+(require 'thingatpt)
+
+(defun cider--find-var-other-window (var &optional line)
+  "Find the definition of VAR, optionally at a specific LINE.
+
+Display the results in a different window."
+  (if-let* ((info (cider-var-info var)))
+      (progn
+        (if line (setq info (nrepl-dict-put info "line" line)))
+        (cider--jump-to-loc-from-info info t))
+    (user-error "Symbol `%s' not resolved" var)))
+
+(defun cider--find-var (var &optional line)
+  "Find the definition of VAR, optionally at a specific LINE."
+  (if-let* ((info (cider-var-info var)))
+      (progn
+        (if line (setq info (nrepl-dict-put info "line" line)))
+        (cider--jump-to-loc-from-info info))
+    (user-error "Symbol `%s' not resolved" var)))
+
+;;;###autoload
+(defun cider-find-var (&optional arg var line)
+  "Find definition for VAR at LINE.
+Prompt according to prefix ARG and `cider-prompt-for-symbol'.
+A single or double prefix argument inverts the meaning of
+`cider-prompt-for-symbol'.  A prefix of `-` or a double prefix argument causes
+the results to be displayed in a different window.  The default value is
+thing at point."
+  (interactive "P")
+  (cider-ensure-op-supported "info")
+  (if var
+      (cider--find-var var line)
+    (funcall (cider-prompt-for-symbol-function arg)
+             "Symbol"
+             (if (cider--open-other-window-p arg)
+                 #'cider--find-var-other-window
+               #'cider--find-var))))
+
+(defun cider--find-dwim (symbol-file callback &optional other-window)
+  "Find the SYMBOL-FILE at point.
+CALLBACK upon failure to invoke prompt if not prompted previously.
+Show results in a different window if OTHER-WINDOW is true."
+  (if-let* ((info (cider-var-info symbol-file)))
+      (cider--jump-to-loc-from-info info other-window)
+    (progn
+      (cider-ensure-op-supported "resource")
+      (if-let* ((resource (cider-sync-request:resource symbol-file))
+                (buffer (cider-find-file resource)))
+          (cider-jump-to buffer 0 other-window)
+        (if (cider--prompt-for-symbol-p current-prefix-arg)
+            (error "Resource or var %s not resolved" symbol-file)
+          (let ((current-prefix-arg (if current-prefix-arg nil '(4))))
+            (call-interactively callback)))))))
+
+(defun cider--find-dwim-interactive (prompt)
+  "Get interactive arguments for jump-to functions using PROMPT as needed."
+  (if (cider--prompt-for-symbol-p current-prefix-arg)
+      (list
+       (cider-read-from-minibuffer prompt (thing-at-point 'filename)))
+    (list (or (thing-at-point 'filename) ""))))  ; No prompt.
+
+(defun cider-find-dwim-other-window (symbol-file)
+  "Jump to SYMBOL-FILE at point, place results in other window."
+  (interactive (cider--find-dwim-interactive "Jump to: "))
+  (cider--find-dwim symbol-file 'cider-find-dwim-other-window t))
+
+;;;###autoload
+(defun cider-find-dwim (symbol-file)
+  "Find and display the SYMBOL-FILE at point.
+SYMBOL-FILE could be a var or a resource.  If thing at point is empty then
+show dired on project.  If var is not found, try to jump to resource of the
+same name.  When called interactively, a prompt is given according to the
+variable `cider-prompt-for-symbol'.  A single or double prefix argument
+inverts the meaning.  A prefix of `-' or a double prefix argument causes
+the results to be displayed in a different window.  A default value of thing
+at point is given when prompted."
+  (interactive (cider--find-dwim-interactive "Jump to: "))
+  (cider--find-dwim symbol-file `cider-find-dwim
+                    (cider--open-other-window-p current-prefix-arg)))
+
+;;;###autoload
+(defun cider-find-resource (path)
+  "Find the resource at PATH.
+Prompt for input as indicated by the variable `cider-prompt-for-symbol'.
+A single or double prefix argument inverts the meaning of
+`cider-prompt-for-symbol'.  A prefix argument of `-` or a double prefix
+argument causes the results to be displayed in other window.  The default
+value is thing at point."
+  (interactive
+   (list
+    (if (cider--prompt-for-symbol-p current-prefix-arg)
+        (completing-read "Resource: "
+                         (cider-sync-request:resources-list)
+                         nil nil
+                         (thing-at-point 'filename))
+      (or (thing-at-point 'filename) ""))))
+  (cider-ensure-op-supported "resource")
+  (when (= (length path) 0)
+    (error "Cannot find resource for empty path"))
+  (if-let* ((resource (cider-sync-request:resource path))
+            (buffer (cider-find-file resource)))
+      (cider-jump-to buffer nil (cider--open-other-window-p current-prefix-arg))
+    (if (cider--prompt-for-symbol-p current-prefix-arg)
+        (error "Cannot find resource %s" path)
+      (let ((current-prefix-arg (cider--invert-prefix-arg current-prefix-arg)))
+        (call-interactively 'cider-find-resource)))))
+
+(defun cider--invert-prefix-arg (arg)
+  "Invert the effect of prefix value ARG on `cider-prompt-for-symbol'.
+This function preserves the `other-window' meaning of ARG."
+  (let ((narg (prefix-numeric-value arg)))
+    (pcase narg
+      (16 -1)   ; empty empty -> -
+      (-1 16)   ; - -> empty empty
+      (4 nil)   ; empty -> no-prefix
+      (_ 4)))) ; no-prefix -> empty
+
+(defun cider--prefix-invert-prompt-p (arg)
+  "Test prefix value ARG for its effect on `cider-prompt-for-symbol`."
+  (let ((narg (prefix-numeric-value arg)))
+    (pcase narg
+      (16 t) ; empty empty
+      (4 t)  ; empty
+      (_ nil))))
+
+(defun cider--prompt-for-symbol-p (&optional prefix)
+  "Check if cider should prompt for symbol.
+Tests againsts PREFIX and the value of `cider-prompt-for-symbol'.
+Invert meaning of `cider-prompt-for-symbol' if PREFIX indicates it should be."
+  (if (cider--prefix-invert-prompt-p prefix)
+      (not cider-prompt-for-symbol) cider-prompt-for-symbol))
+
+(defun cider--find-ns (ns &optional other-window)
+  "Find the file containing NS's definition.
+Optionally open it in a different window if OTHER-WINDOW is truthy."
+  (if-let* ((path (cider-sync-request:ns-path ns)))
+      (cider-jump-to (cider-find-file path) nil other-window)
+    (user-error "Can't find namespace `%s'" ns)))
+
+;;;###autoload
+(defun cider-find-ns (&optional arg ns)
+  "Find the file containing NS.
+A prefix ARG of `-` or a double prefix argument causes
+the results to be displayed in a different window."
+  (interactive "P")
+  (cider-ensure-connected)
+  (cider-ensure-op-supported "ns-path")
+  (if ns
+      (cider--find-ns ns)
+    (let* ((namespaces (cider-sync-request:ns-list))
+           (ns (completing-read "Find namespace: " namespaces)))
+      (cider--find-ns ns (cider--open-other-window-p arg)))))
+
+;;;###autoload
+(defun cider-find-keyword (&optional arg)
+  "Find the namespace of the keyword at point and its first occurrence there.
+
+For instance - if the keyword at point is \":cider.demo/keyword\", this command
+would find the namespace \"cider.demo\" and afterwards find the first mention
+of \"::keyword\" there.
+
+Prompt according to prefix ARG and `cider-prompt-for-symbol'.
+A single or double prefix argument inverts the meaning of
+`cider-prompt-for-symbol'.  A prefix of `-` or a double prefix argument causes
+the results to be displayed in a different window.  The default value is
+thing at point."
+  (interactive "P")
+  (cider-ensure-connected)
+  (let* ((kw (let ((kw-at-point (cider-symbol-at-point 'look-back)))
+               (if (or cider-prompt-for-symbol arg)
+                   (read-string
+                    (format "Keyword (default %s): " kw-at-point)
+                    nil nil kw-at-point)
+                 kw-at-point)))
+         (ns-qualifier (and
+                        (string-match "^:+\\(.+\\)/.+$" kw)
+                        (match-string 1 kw)))
+         (kw-ns (if ns-qualifier
+                    (cider-resolve-alias (cider-current-ns) ns-qualifier)
+                  (cider-current-ns)))
+         (kw-to-find (concat "::" (replace-regexp-in-string "^:+\\(.+/\\)?" "" kw))))
+
+    (when (and ns-qualifier (string= kw-ns (cider-current-ns)))
+      (error "Could not resolve alias `%s' in `%s'" ns-qualifier (cider-current-ns)))
+    (cider--find-ns kw-ns arg)
+    (search-forward-regexp kw-to-find nil 'noerror)))
+
+(provide 'cider-find)
+;;; cider-find.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-find.elc b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-find.elc
new file mode 100644
index 0000000000..0ddc9351f9
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-find.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-format.el b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-format.el
new file mode 100644
index 0000000000..0aa9e8f0c4
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-format.el
@@ -0,0 +1,150 @@
+;;; cider-format.el --- Code and EDN formatting functionality -*- lexical-binding: t -*-
+
+;; Copyright © 2013-2018 Bozhidar Batsov, Artur Malabarba and CIDER contributors
+;;
+;; Author: Bozhidar Batsov <bozhidar@batsov.com>
+;;         Artur Malabarba <bruce.connor.am@gmail.com>
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;; This file is not part of GNU Emacs.
+
+;;; Commentary:
+
+;; Middleware-powered code and EDN formatting functionality.
+
+;;; Code:
+
+(require 'subr-x)
+
+(require 'cider-client)
+(require 'cider-util)
+
+
+;; Format
+
+(defun cider--format-reindent (formatted start)
+  "Reindent FORMATTED to align with buffer position START."
+  (let* ((start-column (save-excursion (goto-char start) (current-column)))
+         (indent-line (concat "\n" (make-string start-column ? ))))
+    (replace-regexp-in-string "\n" indent-line formatted)))
+
+
+;;; Format region
+
+(defun cider--format-region (start end formatter)
+  "Format the contents of the given region.
+
+START and END represent the region's boundaries.
+
+FORMATTER is a function of one argument which is used to convert
+the string contents of the region into a formatted string.
+
+Uses the following heuristic to try to maintain point position:
+
+- Take a snippet of text starting at current position, up to 64 chars.
+- Search for the snippet, with lax whitespace, in the formatted text.
+  - If snippet is less than 64 chars (point was near end of buffer), search
+    from end instead of beginning.
+- Place point at match beginning, or `point-min' if no match."
+  (let* ((original (buffer-substring-no-properties start end))
+         (formatted (funcall formatter original))
+         (indented (cider--format-reindent formatted start)))
+    (unless (equal original indented)
+      (let* ((pos (point))
+             (pos-max (1+ (buffer-size)))
+             (l 64)
+             (endp (> (+ pos l) pos-max))
+             (snippet (thread-last (buffer-substring-no-properties
+                                    pos (min (+ pos l) pos-max))
+                        (replace-regexp-in-string "[[:space:]\t\n\r]+" "[[:space:]\t\n\r]*"))))
+        (delete-region start end)
+        (insert indented)
+        (goto-char (if endp (point-max) (point-min)))
+        (funcall (if endp #'re-search-backward #'re-search-forward) snippet nil t)
+        (goto-char (or (match-beginning 0) start))
+        (when (looking-at-p "\n") (forward-char))))))
+
+;;;###autoload
+(defun cider-format-region (start end)
+  "Format the Clojure code in the current region.
+START and END represent the region's boundaries."
+  (interactive "r")
+  (cider-ensure-connected)
+  (cider--format-region start end #'cider-sync-request:format-code))
+
+
+;;; Format defun
+
+;;;###autoload
+(defun cider-format-defun ()
+  "Format the code in the current defun."
+  (interactive)
+  (cider-ensure-connected)
+  (save-excursion
+    (mark-defun)
+    (cider-format-region (region-beginning) (region-end))))
+
+
+;;; Format buffer
+
+(defun cider--format-buffer (formatter)
+  "Format the contents of the current buffer.
+
+Uses FORMATTER, a function of one argument, to convert the string contents
+of the buffer into a formatted string."
+  (cider--format-region 1 (1+ (buffer-size)) formatter))
+
+;;;###autoload
+(defun cider-format-buffer ()
+  "Format the Clojure code in the current buffer."
+  (interactive)
+  (check-parens)
+  (cider-ensure-connected)
+  (cider--format-buffer #'cider-sync-request:format-code))
+
+
+;;; Format EDN
+
+(declare-function cider--pretty-print-width "cider-repl")
+
+;;;###autoload
+(defun cider-format-edn-buffer ()
+  "Format the EDN data in the current buffer."
+  (interactive)
+  (check-parens)
+  (cider-ensure-connected)
+  (cider--format-buffer (lambda (edn)
+                          (cider-sync-request:format-edn edn (cider--pretty-print-width)))))
+
+;;;###autoload
+(defun cider-format-edn-region (start end)
+  "Format the EDN data in the current region.
+START and END represent the region's boundaries."
+  (interactive "r")
+  (cider-ensure-connected)
+  (let* ((start-column (save-excursion (goto-char start) (current-column)))
+         (right-margin (- (cider--pretty-print-width) start-column)))
+    (cider--format-region start end
+                          (lambda (edn)
+                            (cider-sync-request:format-edn edn right-margin)))))
+
+;;;###autoload
+(defun cider-format-edn-last-sexp ()
+  "Format the EDN data of the last sexp."
+  (interactive)
+  (apply 'cider-format-edn-region (cider-sexp-at-point 'bounds)))
+
+(provide 'cider-format)
+;;; cider-format.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-format.elc b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-format.elc
new file mode 100644
index 0000000000..4a995a4eac
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-format.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-grimoire.el b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-grimoire.el
new file mode 100644
index 0000000000..c07614ba59
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-grimoire.el
@@ -0,0 +1,130 @@
+;;; cider-grimoire.el --- Grimoire integration -*- lexical-binding: t -*-
+
+;; Copyright © 2014-2018 Bozhidar Batsov and CIDER contributors
+;;
+;; Author: Bozhidar Batsov <bozhidar@batsov.com>
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;; This file is not part of GNU Emacs.
+
+;;; Commentary:
+
+;; A few commands for Grimoire documentation lookup.
+
+;;; Code:
+
+(require 'cider-client)
+(require 'cider-common)
+(require 'subr-x)
+(require 'cider-compat)
+(require 'cider-popup)
+
+(require 'nrepl-dict)
+
+(require 'url-vars)
+
+(declare-function markdown-mode "markdown-mode.el")
+(declare-function markdown-toggle-fontify-code-blocks-natively "markdown-mode.el")
+
+(defconst cider-grimoire-url "http://conj.io/")
+
+(defconst cider-grimoire-buffer "*cider-grimoire*")
+
+(defun cider-grimoire-replace-special (name)
+  "Convert the dashes in NAME to a grimoire friendly format."
+  (thread-last name
+    (replace-regexp-in-string "\\?" "_QMARK_")
+    (replace-regexp-in-string "\\." "_DOT_")
+    (replace-regexp-in-string "\\/" "_SLASH_")
+    (replace-regexp-in-string "\\(\\`_\\)\\|\\(_\\'\\)" "")))
+
+(defun cider-grimoire-url (name ns)
+  "Generate a grimoire search v0 url from NAME, NS."
+  (let ((base-url cider-grimoire-url))
+    (when (and name ns)
+      (concat base-url  "search/v0/" ns "/" (cider-grimoire-replace-special name) "/"))))
+
+(defun cider-grimoire-web-lookup (symbol)
+  "Open the grimoire documentation for SYMBOL in a web browser."
+  (if-let* ((var-info (cider-var-info symbol)))
+      (let ((name (nrepl-dict-get var-info "name"))
+            (ns (nrepl-dict-get var-info "ns")))
+        (browse-url (cider-grimoire-url name ns)))
+    (error "Symbol %s not resolved" symbol)))
+
+;;;###autoload
+(defun cider-grimoire-web (&optional arg)
+  "Open grimoire documentation in the default web browser.
+
+Prompts for the symbol to use, or uses the symbol at point, depending on
+the value of `cider-prompt-for-symbol'.  With prefix arg ARG, does the
+opposite of what that option dictates."
+  (interactive "P")
+  (funcall (cider-prompt-for-symbol-function arg)
+           "Grimoire doc for"
+           #'cider-grimoire-web-lookup))
+
+(defun cider-create-grimoire-buffer (content)
+  "Create a new grimoire buffer with CONTENT."
+  (with-current-buffer (cider-popup-buffer cider-grimoire-buffer t)
+    (read-only-mode -1)
+    (insert content)
+    (when (require 'markdown-mode nil 'noerror)
+      (markdown-mode)
+      (cider-popup-buffer-mode 1)
+      (when (fboundp 'markdown-toggle-fontify-code-blocks-natively)
+        (markdown-toggle-fontify-code-blocks-natively 1)))
+    (view-mode 1)
+    (goto-char (point-min))
+    (current-buffer)))
+
+(defun cider-grimoire-lookup (symbol)
+  "Look up the grimoire documentation for SYMBOL.
+
+If SYMBOL is a special form, the clojure.core ns is used, as is
+Grimoire's convention."
+  (if-let* ((var-info (cider-var-info symbol)))
+      (let ((name (nrepl-dict-get var-info "name"))
+            (ns (nrepl-dict-get var-info "ns" "clojure.core"))
+            (url-request-method "GET")
+            (url-request-extra-headers `(("Content-Type" . "text/plain"))))
+        (url-retrieve (cider-grimoire-url name ns)
+                      (lambda (_status)
+                        ;; we need to strip the http header
+                        (goto-char (point-min))
+                        (re-search-forward "^$")
+                        (delete-region (point-min) (point))
+                        (delete-blank-lines)
+                        ;; and create a new buffer with whatever is left
+                        (pop-to-buffer (cider-create-grimoire-buffer (buffer-string))))))
+    (error "Symbol %s not resolved" symbol)))
+
+;;;###autoload
+(defun cider-grimoire (&optional arg)
+  "Open grimoire documentation in a popup buffer.
+
+Prompts for the symbol to use, or uses the symbol at point, depending on
+the value of `cider-prompt-for-symbol'.  With prefix arg ARG, does the
+opposite of what that option dictates."
+  (interactive "P")
+  (when (derived-mode-p 'clojurescript-mode)
+    (user-error "`cider-grimoire' doesn't support ClojureScript"))
+  (funcall (cider-prompt-for-symbol-function arg)
+           "Grimoire doc for"
+           #'cider-grimoire-lookup))
+
+(provide 'cider-grimoire)
+
+;;; cider-grimoire.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-grimoire.elc b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-grimoire.elc
new file mode 100644
index 0000000000..43d26d33f0
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-grimoire.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-inspector.el b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-inspector.el
new file mode 100644
index 0000000000..61d5007db0
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-inspector.el
@@ -0,0 +1,397 @@
+;;; cider-inspector.el --- Object inspector -*- lexical-binding: t -*-
+
+;; Copyright © 2013-2018 Vital Reactor, LLC
+;; Copyright © 2014-2018 Bozhidar Batsov and CIDER contributors
+
+;; Author: Ian Eslick <ian@vitalreactor.com>
+;;         Bozhidar Batsov <bozhidar@batsov.com>
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;; This file is not part of GNU Emacs.
+
+;;; Commentary:
+
+;; Clojure object inspector inspired by SLIME.
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'seq)
+(require 'cider-eval)
+
+;; ===================================
+;; Inspector Key Map and Derived Mode
+;; ===================================
+
+(defconst cider-inspector-buffer "*cider-inspect*")
+
+;;; Customization
+(defgroup cider-inspector nil
+  "Presentation and behaviour of the cider value inspector."
+  :prefix "cider-inspector-"
+  :group 'cider
+  :package-version '(cider . "0.10.0"))
+
+(defcustom cider-inspector-page-size 32
+  "Default page size in paginated inspector view.
+The page size can be also changed interactively within the inspector."
+  :type '(integer :tag "Page size" 32)
+  :group 'cider-inspector
+  :package-version '(cider . "0.10.0"))
+
+(defcustom cider-inspector-fill-frame nil
+  "Controls whether the cider inspector window fills its frame."
+  :type 'boolean
+  :group 'cider-inspector
+  :package-version '(cider . "0.15.0"))
+
+(defvar cider-inspector-mode-map
+  (let ((map (make-sparse-keymap)))
+    (set-keymap-parent map cider-popup-buffer-mode-map)
+    (define-key map (kbd "RET") #'cider-inspector-operate-on-point)
+    (define-key map [mouse-1] #'cider-inspector-operate-on-click)
+    (define-key map "l" #'cider-inspector-pop)
+    (define-key map "g" #'cider-inspector-refresh)
+    ;; Page-up/down
+    (define-key map [next] #'cider-inspector-next-page)
+    (define-key map [prior] #'cider-inspector-prev-page)
+    (define-key map " " #'cider-inspector-next-page)
+    (define-key map (kbd "M-SPC") #'cider-inspector-prev-page)
+    (define-key map (kbd "S-SPC") #'cider-inspector-prev-page)
+    (define-key map "s" #'cider-inspector-set-page-size)
+    (define-key map [tab] #'cider-inspector-next-inspectable-object)
+    (define-key map "\C-i" #'cider-inspector-next-inspectable-object)
+    (define-key map [(shift tab)] #'cider-inspector-previous-inspectable-object)
+    ;; Emacs translates S-TAB to BACKTAB on X.
+    (define-key map [backtab] #'cider-inspector-previous-inspectable-object)
+    map))
+
+(define-derived-mode cider-inspector-mode special-mode "Inspector"
+  "Major mode for inspecting Clojure data structures.
+
+\\{cider-inspector-mode-map}"
+  (set-syntax-table clojure-mode-syntax-table)
+  (setq-local electric-indent-chars nil)
+  (setq-local sesman-system 'CIDER)
+  (when cider-special-mode-truncate-lines
+    (setq-local truncate-lines t)))
+
+;;;###autoload
+(defun cider-inspect-last-sexp ()
+  "Inspect the result of the the expression preceding point."
+  (interactive)
+  (cider-inspect-expr (cider-last-sexp) (cider-current-ns)))
+
+;;;###autoload
+(defun cider-inspect-defun-at-point ()
+  "Inspect the result of the \"top-level\" expression at point."
+  (interactive)
+  (cider-inspect-expr (cider-defun-at-point) (cider-current-ns)))
+
+;;;###autoload
+(defun cider-inspect-last-result ()
+  "Inspect the most recent eval result."
+  (interactive)
+  (cider-inspect-expr "*1" (cider-current-ns)))
+
+;;;###autoload
+(defun cider-inspect (&optional arg)
+  "Inspect the result of the preceding sexp.
+
+With a prefix argument ARG it inspects the result of the \"top-level\" form.
+With a second prefix argument it prompts for an expression to eval and inspect."
+  (interactive "p")
+  (pcase arg
+    (1 (cider-inspect-last-sexp))
+    (4 (cider-inspect-defun-at-point))
+    (16 (call-interactively #'cider-inspect-expr))))
+
+(defvar cider-inspector-location-stack nil
+  "A stack used to save point locations in inspector buffers.
+These locations are used to emulate `save-excursion' between
+`cider-inspector-push' and `cider-inspector-pop' operations.")
+
+(defvar cider-inspector-page-location-stack nil
+  "A stack used to save point locations in inspector buffers.
+These locations are used to emulate `save-excursion' between
+`cider-inspector-next-page' and `cider-inspector-prev-page' operations.")
+
+(defvar cider-inspector-last-command nil
+  "Contains the value of the most recently used `cider-inspector-*' command.
+This is used as an alternative to the built-in `last-command'.  Whenever we
+invoke any command through \\[execute-extended-command] and its variants,
+the value of `last-command' is not set to the command it invokes.")
+
+;; Operations
+;;;###autoload
+(defun cider-inspect-expr (expr ns)
+  "Evaluate EXPR in NS and inspect its value.
+Interactively, EXPR is read from the minibuffer, and NS the
+current buffer's namespace."
+  (interactive (list (cider-read-from-minibuffer "Inspect expression: " (cider-sexp-at-point))
+                     (cider-current-ns)))
+  (when-let* ((value (cider-sync-request:inspect-expr expr ns (or cider-inspector-page-size 32))))
+    (cider-inspector--render-value value)))
+
+(defun cider-inspector-pop ()
+  "Pop the last value off the inspector stack and render it.
+See `cider-sync-request:inspect-pop' and `cider-inspector--render-value'."
+  (interactive)
+  (setq cider-inspector-last-command 'cider-inspector-pop)
+  (when-let* ((value (cider-sync-request:inspect-pop)))
+    (cider-inspector--render-value value)))
+
+(defun cider-inspector-push (idx)
+  "Inspect the value at IDX in the inspector stack and render it.
+See `cider-sync-request:insepect-push' and `cider-inspector--render-value'"
+  (push (point) cider-inspector-location-stack)
+  (when-let* ((value (cider-sync-request:inspect-push idx)))
+    (cider-inspector--render-value value)))
+
+(defun cider-inspector-refresh ()
+  "Re-render the currently inspected value.
+See `cider-sync-request:insepect-refresh' and `cider-inspector--render-value'"
+  (interactive)
+  (when-let* ((value (cider-sync-request:inspect-refresh)))
+    (cider-inspector--render-value value)))
+
+(defun cider-inspector-next-page ()
+  "Jump to the next page when inspecting a paginated sequence/map.
+
+Does nothing if already on the last page."
+  (interactive)
+  (push (point) cider-inspector-page-location-stack)
+  (when-let* ((value (cider-sync-request:inspect-next-page)))
+    (cider-inspector--render-value value)))
+
+(defun cider-inspector-prev-page ()
+  "Jump to the previous page when expecting a paginated sequence/map.
+
+Does nothing if already on the first page."
+  (interactive)
+  (setq cider-inspector-last-command 'cider-inspector-prev-page)
+  (when-let* ((value (cider-sync-request:inspect-prev-page)))
+    (cider-inspector--render-value value)))
+
+(defun cider-inspector-set-page-size (page-size)
+  "Set the page size in pagination mode to the specified PAGE-SIZE.
+
+Current page will be reset to zero."
+  (interactive "nPage size: ")
+  (when-let* ((value (cider-sync-request:inspect-set-page-size page-size)))
+    (cider-inspector--render-value value)))
+
+;; nREPL interactions
+(defun cider-sync-request:inspect-pop ()
+  "Move one level up in the inspector stack."
+  (thread-first '("op" "inspect-pop")
+    (cider-nrepl-send-sync-request)
+    (nrepl-dict-get "value")))
+
+(defun cider-sync-request:inspect-push (idx)
+  "Inspect the inside value specified by IDX."
+  (thread-first `("op" "inspect-push"
+                  "idx" ,idx)
+    (cider-nrepl-send-sync-request)
+    (nrepl-dict-get "value")))
+
+(defun cider-sync-request:inspect-refresh ()
+  "Re-render the currently inspected value."
+  (thread-first '("op" "inspect-refresh")
+    (cider-nrepl-send-sync-request)
+    (nrepl-dict-get "value")))
+
+(defun cider-sync-request:inspect-next-page ()
+  "Jump to the next page in paginated collection view."
+  (thread-first '("op" "inspect-next-page")
+    (cider-nrepl-send-sync-request)
+    (nrepl-dict-get "value")))
+
+(defun cider-sync-request:inspect-prev-page ()
+  "Jump to the previous page in paginated collection view."
+  (thread-first '("op" "inspect-prev-page")
+    (cider-nrepl-send-sync-request)
+    (nrepl-dict-get "value")))
+
+(defun cider-sync-request:inspect-set-page-size (page-size)
+  "Set the page size in paginated view to PAGE-SIZE."
+  (thread-first `("op" "inspect-set-page-size"
+                  "page-size" ,page-size)
+    (cider-nrepl-send-sync-request)
+    (nrepl-dict-get "value")))
+
+(defun cider-sync-request:inspect-expr (expr ns page-size)
+  "Evaluate EXPR in context of NS and inspect its result.
+Set the page size in paginated view to PAGE-SIZE."
+  (thread-first (append (nrepl--eval-request expr ns)
+                        `("inspect" "true"
+                          "page-size" ,page-size))
+    (cider-nrepl-send-sync-request)
+    (nrepl-dict-get "value")))
+
+;; Render Inspector from Structured Values
+(defun cider-inspector--render-value (value)
+  "Render VALUE."
+  (cider-make-popup-buffer cider-inspector-buffer 'cider-inspector-mode 'ancillary)
+  (cider-inspector-render cider-inspector-buffer value)
+  (cider-popup-buffer-display cider-inspector-buffer t)
+  (when cider-inspector-fill-frame (delete-other-windows))
+  (with-current-buffer cider-inspector-buffer
+    (when (eq cider-inspector-last-command 'cider-inspector-pop)
+      (setq cider-inspector-last-command nil)
+      ;; Prevents error message being displayed when we try to pop
+      ;; from the top-level of a data struture
+      (when cider-inspector-location-stack
+        (goto-char (pop cider-inspector-location-stack))))
+
+    (when (eq cider-inspector-last-command 'cider-inspector-prev-page)
+      (setq cider-inspector-last-command nil)
+      ;; Prevents error message being displayed when we try to
+      ;; go to a prev-page from the first page
+      (when cider-inspector-page-location-stack
+        (goto-char (pop cider-inspector-page-location-stack))))))
+
+(defun cider-inspector-render (buffer str)
+  "Render STR in BUFFER."
+  (with-current-buffer buffer
+    (cider-inspector-mode)
+    (let ((inhibit-read-only t))
+      (condition-case nil
+          (cider-inspector-render* (car (read-from-string str)))
+        (error (insert "\nInspector error for: " str))))
+    (goto-char (point-min))))
+
+(defun cider-inspector-render* (elements)
+  "Render ELEMENTS."
+  (dolist (el elements)
+    (cider-inspector-render-el* el)))
+
+(defun cider-inspector-render-el* (el)
+  "Render EL."
+  (cond ((symbolp el) (insert (symbol-name el)))
+        ((stringp el) (insert (propertize el 'font-lock-face 'font-lock-keyword-face)))
+        ((and (consp el) (eq (car el) :newline))
+         (insert "\n"))
+        ((and (consp el) (eq (car el) :value))
+         (cider-inspector-render-value (cadr el) (cl-caddr el)))
+        (t (message "Unrecognized inspector object: %s" el))))
+
+(defun cider-inspector-render-value (value idx)
+  "Render VALUE at IDX."
+  (cider-propertize-region
+      (list 'cider-value-idx idx
+            'mouse-face 'highlight)
+    (cider-inspector-render-el* (cider-font-lock-as-clojure value))))
+
+
+;; ===================================================
+;; Inspector Navigation (lifted from SLIME inspector)
+;; ===================================================
+
+(defun cider-find-inspectable-object (direction limit)
+  "Find the next/previous inspectable object.
+DIRECTION can be either 'next or 'prev.
+LIMIT is the maximum or minimum position in the current buffer.
+
+Return a list of two values: If an object could be found, the
+starting position of the found object and T is returned;
+otherwise LIMIT and NIL is returned."
+  (let ((finder (cl-ecase direction
+                  (next 'next-single-property-change)
+                  (prev 'previous-single-property-change))))
+    (let ((prop nil) (curpos (point)))
+      (while (and (not prop) (not (= curpos limit)))
+        (let ((newpos (funcall finder curpos 'cider-value-idx nil limit)))
+          (setq prop (get-text-property newpos 'cider-value-idx))
+          (setq curpos newpos)))
+      (list curpos (and prop t)))))
+
+(defun cider-inspector-next-inspectable-object (arg)
+  "Move point to the next inspectable object.
+With optional ARG, move across that many objects.
+If ARG is negative, move backwards."
+  (interactive "p")
+  (let ((maxpos (point-max)) (minpos (point-min))
+        (previously-wrapped-p nil))
+    ;; Forward.
+    (while (> arg 0)
+      (seq-let (pos foundp) (cider-find-inspectable-object 'next maxpos)
+        (if foundp
+            (progn (goto-char pos) (setq arg (1- arg))
+                   (setq previously-wrapped-p nil))
+          (if (not previously-wrapped-p) ; cycle detection
+              (progn (goto-char minpos) (setq previously-wrapped-p t))
+            (error "No inspectable objects")))))
+    ;; Backward.
+    (while (< arg 0)
+      (seq-let (pos foundp) (cider-find-inspectable-object 'prev minpos)
+        ;; CIDER-OPEN-INSPECTOR inserts the title of an inspector page
+        ;; as a presentation at the beginning of the buffer; skip
+        ;; that.  (Notice how this problem can not arise in ``Forward.'')
+        (if (and foundp (/= pos minpos))
+            (progn (goto-char pos) (setq arg (1+ arg))
+                   (setq previously-wrapped-p nil))
+          (if (not previously-wrapped-p) ; cycle detection
+              (progn (goto-char maxpos) (setq previously-wrapped-p t))
+            (error "No inspectable objects")))))))
+
+(defun cider-inspector-previous-inspectable-object (arg)
+  "Move point to the previous inspectable object.
+With optional ARG, move across that many objects.
+If ARG is negative, move forwards."
+  (interactive "p")
+  (cider-inspector-next-inspectable-object (- arg)))
+
+(defun cider-inspector-property-at-point ()
+  "Return property at point."
+  (let* ((properties '(cider-value-idx cider-range-button
+                                       cider-action-number))
+         (find-property
+          (lambda (point)
+            (cl-loop for property in properties
+                     for value = (get-text-property point property)
+                     when value
+                     return (list property value)))))
+    (or (funcall find-property (point))
+        (funcall find-property (1- (point))))))
+
+(defun cider-inspector-operate-on-point ()
+  "Invoke the command for the text at point.
+1. If point is on a value then recursively call the inspector on
+that value.
+2. If point is on an action then call that action.
+3. If point is on a range-button fetch and insert the range."
+  (interactive)
+  (seq-let (property value) (cider-inspector-property-at-point)
+    (cl-case property
+      (cider-value-idx
+       (cider-inspector-push value))
+      ;; TODO: range and action handlers
+      (t (error "No object at point")))))
+
+(defun cider-inspector-operate-on-click (event)
+  "Move to EVENT's position and operate the part."
+  (interactive "@e")
+  (let ((point (posn-point (event-end event))))
+    (cond ((and point
+                (or (get-text-property point 'cider-value-idx)))
+           (goto-char point)
+           (cider-inspector-operate-on-point))
+          (t
+           (error "No clickable part here")))))
+
+(provide 'cider-inspector)
+
+;;; cider-inspector.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-inspector.elc b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-inspector.elc
new file mode 100644
index 0000000000..5bebf64b1d
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-inspector.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-macroexpansion.el b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-macroexpansion.el
new file mode 100644
index 0000000000..8123932a34
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-macroexpansion.el
@@ -0,0 +1,206 @@
+;;; cider-macroexpansion.el --- Macro expansion support -*- lexical-binding: t -*-
+
+;; Copyright © 2012-2013 Tim King, Phil Hagelberg, Bozhidar Batsov
+;; Copyright © 2013-2018 Bozhidar Batsov, Artur Malabarba and CIDER contributors
+;;
+;; Author: Tim King <kingtim@gmail.com>
+;;         Phil Hagelberg <technomancy@gmail.com>
+;;         Bozhidar Batsov <bozhidar@batsov.com>
+;;         Artur Malabarba <bruce.connor.am@gmail.com>
+;;         Hugo Duncan <hugo@hugoduncan.org>
+;;         Steve Purcell <steve@sanityinc.com>
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;; This file is not part of GNU Emacs.
+
+;;; Commentary:
+
+;; Macro expansion support.
+
+;;; Code:
+
+(require 'cider-mode)
+(require 'subr-x)
+(require 'cider-compat)
+
+(defconst cider-macroexpansion-buffer "*cider-macroexpansion*")
+
+(defcustom cider-macroexpansion-display-namespaces 'tidy
+  "Determines if namespaces are displayed in the macroexpansion buffer.
+Possible values are:
+
+  'qualified ;=> Vars are fully-qualified in the expansion
+  'none      ;=> Vars are displayed without namespace qualification
+  'tidy      ;=> Vars that are :refer-ed or defined in the current namespace are
+                 displayed with their simple name, non-refered vars from other
+                 namespaces are refered using the alias for that namespace (if
+                 defined), other vars are displayed fully qualified."
+  :type '(choice (const :tag "Suppress namespaces" none)
+                 (const :tag "Show fully-qualified namespaces" qualified)
+                 (const :tag "Show namespace aliases" tidy))
+  :group 'cider
+  :package-version '(cider . "0.7.0"))
+
+(defcustom cider-macroexpansion-print-metadata nil
+  "Determines if metadata is included in macroexpansion results."
+  :type 'boolean
+  :group 'cider
+  :package-version '(cider . "0.9.0"))
+
+(defun cider-sync-request:macroexpand (expander expr &optional display-namespaces)
+  "Macroexpand, using EXPANDER, the given EXPR.
+The default for DISPLAY-NAMESPACES is taken from
+`cider-macroexpansion-display-namespaces'."
+  (cider-ensure-op-supported "macroexpand")
+  (thread-first `("op" "macroexpand"
+                  "expander" ,expander
+                  "code" ,expr
+                  "ns" ,(cider-current-ns)
+                  "display-namespaces" ,(or display-namespaces
+                                            (symbol-name cider-macroexpansion-display-namespaces)))
+    (nconc (when cider-macroexpansion-print-metadata
+             '("print-meta" "true")))
+    (cider-nrepl-send-sync-request)
+    (nrepl-dict-get "expansion")))
+
+(defun cider-macroexpand-undo (&optional arg)
+  "Undo the last macroexpansion, using `undo-only'.
+ARG is passed along to `undo-only'."
+  (interactive)
+  (let ((inhibit-read-only t))
+    (undo-only arg)))
+
+(defvar cider-last-macroexpand-expression nil
+  "Specify the last macroexpansion preformed.
+This variable specifies both what was expanded and the expander.")
+
+(defun cider-macroexpand-expr (expander expr)
+  "Macroexpand, use EXPANDER, the given EXPR."
+  (when-let* ((expansion (cider-sync-request:macroexpand expander expr)))
+    (setq cider-last-macroexpand-expression expr)
+    (cider-initialize-macroexpansion-buffer expansion (cider-current-ns))))
+
+(defun cider-macroexpand-expr-inplace (expander)
+  "Substitute the form preceding point with its macroexpansion using EXPANDER."
+  (interactive)
+  (let* ((expansion (cider-sync-request:macroexpand expander (cider-last-sexp)))
+         (bounds (cons (save-excursion (clojure-backward-logical-sexp 1) (point)) (point))))
+    (cider-redraw-macroexpansion-buffer
+     expansion (current-buffer) (car bounds) (cdr bounds))))
+
+(defun cider-macroexpand-again ()
+  "Repeat the last macroexpansion."
+  (interactive)
+  (cider-initialize-macroexpansion-buffer cider-last-macroexpand-expression (cider-current-ns)))
+
+;;;###autoload
+(defun cider-macroexpand-1 (&optional prefix)
+  "Invoke \\=`macroexpand-1\\=` on the expression preceding point.
+If invoked with a PREFIX argument, use \\=`macroexpand\\=` instead of
+\\=`macroexpand-1\\=`."
+  (interactive "P")
+  (let ((expander (if prefix "macroexpand" "macroexpand-1")))
+    (cider-macroexpand-expr expander (cider-last-sexp))))
+
+(defun cider-macroexpand-1-inplace (&optional prefix)
+  "Perform inplace \\=`macroexpand-1\\=` on the expression preceding point.
+If invoked with a PREFIX argument, use \\=`macroexpand\\=` instead of
+\\=`macroexpand-1\\=`."
+  (interactive "P")
+  (let ((expander (if prefix "macroexpand" "macroexpand-1")))
+    (cider-macroexpand-expr-inplace expander)))
+
+;;;###autoload
+(defun cider-macroexpand-all ()
+  "Invoke \\=`macroexpand-all\\=` on the expression preceding point."
+  (interactive)
+  (cider-macroexpand-expr "macroexpand-all" (cider-last-sexp)))
+
+(defun cider-macroexpand-all-inplace ()
+  "Perform inplace \\=`macroexpand-all\\=` on the expression preceding point."
+  (interactive)
+  (cider-macroexpand-expr-inplace "macroexpand-all"))
+
+(defun cider-initialize-macroexpansion-buffer (expansion ns)
+  "Create a new Macroexpansion buffer with EXPANSION and namespace NS."
+  (pop-to-buffer (cider-create-macroexpansion-buffer))
+  (setq cider-buffer-ns ns)
+  (setq buffer-undo-list nil)
+  (let ((inhibit-read-only t)
+        (buffer-undo-list t))
+    (erase-buffer)
+    (insert (format "%s" expansion))
+    (goto-char (point-max))
+    (cider--font-lock-ensure)))
+
+(defun cider-redraw-macroexpansion-buffer (expansion buffer start end)
+  "Redraw the macroexpansion with new EXPANSION.
+Text in BUFFER from START to END is replaced with new expansion,
+and point is placed after the expanded form."
+  (with-current-buffer buffer
+    (let ((buffer-read-only nil))
+      (goto-char start)
+      (delete-region start end)
+      (insert (format "%s" expansion))
+      (goto-char start)
+      (indent-sexp)
+      (forward-sexp))))
+
+(declare-function cider-mode "cider-mode")
+
+(defun cider-create-macroexpansion-buffer ()
+  "Create a new macroexpansion buffer."
+  (with-current-buffer (cider-popup-buffer cider-macroexpansion-buffer 'select 'clojure-mode 'ancillary)
+    (cider-mode -1)
+    (cider-macroexpansion-mode 1)
+    (current-buffer)))
+
+(declare-function cider-find-var "cider-find")
+
+(defvar cider-macroexpansion-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "g") #'cider-macroexpand-again)
+    (define-key map (kbd "q") #'cider-popup-buffer-quit-function)
+    (define-key map (kbd "d") #'cider-doc)
+    (define-key map (kbd "j") #'cider-javadoc)
+    (define-key map (kbd ".") #'cider-find-var)
+    (define-key map (kbd "m") #'cider-macroexpand-1-inplace)
+    (define-key map (kbd "a") #'cider-macroexpand-all-inplace)
+    (define-key map (kbd "u") #'cider-macroexpand-undo)
+    (define-key map [remap undo] #'cider-macroexpand-undo)
+    (easy-menu-define cider-macroexpansion-mode-menu map
+      "Menu for CIDER's doc mode"
+      '("Macroexpansion"
+        ["Restart expansion" cider-macroexpand-again]
+        ["Macroexpand-1" cider-macroexpand-1-inplace]
+        ["Macroexpand-all" cider-macroexpand-all-inplace]
+        ["Macroexpand-undo" cider-macroexpand-undo]
+        ["Go to source" cider-find-var]
+        ["Go to doc" cider-doc]
+        ["Go to Javadoc" cider-docview-javadoc]
+        ["Quit" cider-popup-buffer-quit-function]))
+    map))
+
+(define-minor-mode cider-macroexpansion-mode
+  "Minor mode for CIDER macroexpansion.
+
+\\{cider-macroexpansion-mode-map}"
+  nil
+  " Macroexpand"
+  cider-macroexpansion-mode-map)
+
+(provide 'cider-macroexpansion)
+
+;;; cider-macroexpansion.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-macroexpansion.elc b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-macroexpansion.elc
new file mode 100644
index 0000000000..ab51790181
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-macroexpansion.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-mode.el b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-mode.el
new file mode 100644
index 0000000000..039531037e
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-mode.el
@@ -0,0 +1,1026 @@
+;;; cider-mode.el --- Minor mode for REPL interactions -*- lexical-binding: t -*-
+
+;; Copyright © 2012-2013 Tim King, Phil Hagelberg, Bozhidar Batsov
+;; Copyright © 2013-2018 Bozhidar Batsov, Artur Malabarba and CIDER contributors
+;;
+;; Author: Tim King <kingtim@gmail.com>
+;;         Phil Hagelberg <technomancy@gmail.com>
+;;         Bozhidar Batsov <bozhidar@batsov.com>
+;;         Artur Malabarba <bruce.connor.am@gmail.com>
+;;         Hugo Duncan <hugo@hugoduncan.org>
+;;         Steve Purcell <steve@sanityinc.com>
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;; This file is not part of GNU Emacs.
+
+;;; Commentary:
+
+;; Minor mode for REPL interactions.
+
+;;; Code:
+
+(require 'clojure-mode)
+(require 'cider-eval)
+(require 'cider-test) ; required only for the menu
+(require 'cider-eldoc)
+(require 'cider-resolve)
+(require 'cider-doc) ; required only for the menu
+(require 'cider-profile) ; required only for the menu
+(require 'cider-completion)
+(require 'subr-x)
+(require 'cider-compat)
+
+(defcustom cider-mode-line-show-connection t
+  "If the mode-line lighter should detail the connection."
+  :group 'cider
+  :type 'boolean
+  :package-version '(cider "0.10.0"))
+
+(defun cider--modeline-info ()
+  "Return info for the cider mode modeline.
+Info contains the connection type, project name and host:port endpoint."
+  (if-let* ((current-connection (ignore-errors (cider-current-repl))))
+      (with-current-buffer current-connection
+        (concat
+         cider-repl-type
+         (when cider-mode-line-show-connection
+           (format ":%s@%s:%s"
+                   (or (cider--project-name nrepl-project-dir) "<no project>")
+                   (pcase (car nrepl-endpoint)
+                     ("localhost" "")
+                     (x x))
+                   (cadr nrepl-endpoint)))))
+    "not connected"))
+
+;;;###autoload
+(defcustom cider-mode-line
+  '(:eval (format " cider[%s]" (cider--modeline-info)))
+  "Mode line lighter for cider mode.
+
+The value of this variable is a mode line template as in
+`mode-line-format'.  See Info Node `(elisp)Mode Line Format' for details
+about mode line templates.
+
+Customize this variable to change how cider mode displays its status in the
+mode line.  The default value displays the current connection.  Set this
+variable to nil to disable the mode line entirely."
+  :group 'cider
+  :type 'sexp
+  :risky t
+  :package-version '(cider "0.7.0"))
+
+
+;;; Switching between REPL & source buffers
+
+(defun cider--switch-to-repl-buffer (repl-buffer &optional set-namespace)
+  "Select the REPL-BUFFER, when possible in an existing window.
+When SET-NAMESPACE is t, sets the namespace in the REPL buffer to
+that of the namespace in the Clojure source buffer."
+  (let ((buffer (current-buffer)))
+    ;; first we switch to the REPL buffer
+    (if cider-repl-display-in-current-window
+        (pop-to-buffer-same-window repl-buffer)
+      (pop-to-buffer repl-buffer))
+    ;; then if necessary we update its namespace
+    (when set-namespace
+      (cider-repl-set-ns (with-current-buffer buffer (cider-current-ns))))
+    (goto-char (point-max))))
+
+(defun cider-switch-to-repl-buffer (&optional set-namespace)
+  "Switch to current REPL buffer, when possible in an existing window.
+The type of the REPL is inferred from the mode of current buffer.  With a
+prefix arg SET-NAMESPACE sets the namespace in the REPL buffer to that of
+the namespace in the Clojure source buffer"
+  (interactive "P")
+  (cider--switch-to-repl-buffer
+   (cider-current-repl nil 'ensure)
+   set-namespace))
+
+(declare-function cider-load-buffer "cider-eval")
+
+(defun cider-load-buffer-and-switch-to-repl-buffer (&optional set-namespace)
+  "Load the current buffer into the matching REPL buffer and switch to it.
+When SET-NAMESPACE is true, we'll also set the REPL's ns to match that of the
+Clojure buffer."
+  (interactive "P")
+  (cider-load-buffer)
+  (cider-switch-to-repl-buffer set-namespace))
+
+(defun cider-switch-to-last-clojure-buffer ()
+  "Switch to the last Clojure buffer.
+The default keybinding for this command is
+the same as `cider-switch-to-repl-buffer',
+so that it is very convenient to jump between a
+Clojure buffer and the REPL buffer."
+  (interactive)
+  (if (derived-mode-p 'cider-repl-mode)
+      (let* ((a-buf)
+             (the-buf (let ((repl-type (cider-repl-type-for-buffer)))
+                        (seq-find (lambda (b)
+                                    (unless (with-current-buffer b (derived-mode-p 'cider-repl-mode))
+                                      (when-let* ((type (cider-repl-type-for-buffer b)))
+                                        (unless a-buf
+                                          (setq a-buf b))
+                                        (or (equal type "multi")
+                                            (equal type repl-type)))))
+                                  (buffer-list)))))
+        (if-let* ((buf (or the-buf a-buf)))
+            (if cider-repl-display-in-current-window
+                (pop-to-buffer-same-window buf)
+              (pop-to-buffer buf))
+          (user-error "No Clojure buffer found")))
+    (user-error "Not in a CIDER REPL buffer")))
+
+(defun cider-find-and-clear-repl-output (&optional clear-repl)
+  "Find the current REPL buffer and clear it.
+With a prefix argument CLEAR-REPL the command clears the entire REPL
+buffer.  Returns to the buffer in which the command was invoked.  See also
+the related commands `cider-repl-clear-buffer' and
+`cider-repl-clear-output'."
+  (interactive "P")
+  (let ((origin-buffer (current-buffer)))
+    (switch-to-buffer (cider-current-repl))
+    (if clear-repl
+        (cider-repl-clear-buffer)
+      (cider-repl-clear-output))
+    (switch-to-buffer origin-buffer)))
+
+(defun cider-undef ()
+  "Undefine a symbol from the current ns."
+  (interactive)
+  (cider-ensure-op-supported "undef")
+  (cider-read-symbol-name
+   "Undefine symbol: "
+   (lambda (sym)
+     (cider-nrepl-send-request
+      `("op" "undef"
+        "ns" ,(cider-current-ns)
+        "symbol" ,sym)
+      (cider-interactive-eval-handler (current-buffer))))))
+
+;;; cider-run
+(defvar cider--namespace-history nil
+  "History of user input for namespace prompts.")
+
+(defun cider--var-namespace (var)
+  "Return the namespace of VAR.
+VAR is a fully qualified Clojure variable name as a string."
+  (replace-regexp-in-string "\\(?:#'\\)?\\(.*\\)/.*" "\\1" var))
+
+(defun cider-run (&optional function)
+  "Run -main or FUNCTION, prompting for its namespace if necessary.
+With a prefix argument, prompt for function to run instead of -main."
+  (interactive (list (when current-prefix-arg (read-string "Function name: "))))
+  (cider-ensure-connected)
+  (let ((name (or function "-main")))
+    (when-let* ((response (cider-nrepl-send-sync-request
+                           `("op" "ns-list-vars-by-name"
+                             "name" ,name))))
+      (if-let* ((vars (split-string (substring (nrepl-dict-get response "var-list") 1 -1))))
+          (cider-interactive-eval
+           (if (= (length vars) 1)
+               (concat "(" (car vars) ")")
+             (let* ((completions (mapcar #'cider--var-namespace vars))
+                    (def (or (car cider--namespace-history)
+                             (car completions))))
+               (format "(#'%s/%s)"
+                       (completing-read (format "Namespace (%s): " def)
+                                        completions nil t nil
+                                        'cider--namespace-history def)
+                       name))))
+        (user-error "No %s var defined in any namespace" (cider-propertize name 'fn))))))
+
+;;; Insert (and eval) in REPL functionality
+(defvar cider-insert-commands-map
+  (let ((map (define-prefix-command 'cider-insert-commands-map)))
+    ;; single key bindings defined last for display in menu
+    (define-key map (kbd "e") #'cider-insert-last-sexp-in-repl)
+    (define-key map (kbd "d") #'cider-insert-defun-in-repl)
+    (define-key map (kbd "r") #'cider-insert-region-in-repl)
+    (define-key map (kbd "n") #'cider-insert-ns-form-in-repl)
+
+    ;; duplicates with C- for convenience
+    (define-key map (kbd "C-e") #'cider-insert-last-sexp-in-repl)
+    (define-key map (kbd "C-d") #'cider-insert-defun-in-repl)
+    (define-key map (kbd "C-r") #'cider-insert-region-in-repl)
+    (define-key map (kbd "C-n") #'cider-insert-ns-form-in-repl)))
+
+(defcustom cider-switch-to-repl-after-insert-p t
+  "Whether to switch to the repl after inserting a form into the repl."
+  :type 'boolean
+  :group 'cider
+  :package-version '(cider . "0.18.0"))
+
+(defcustom cider-invert-insert-eval-p nil
+  "Whether to invert the behavior of evaling.
+Default behavior when inserting is to NOT eval the form and only eval with
+a prefix.  This allows to invert this so that default behavior is to insert
+and eval and the prefix is required to prevent evaluation."
+  :type 'boolean
+  :group 'cider
+  :package-version '(cider . "0.18.0"))
+
+(defun cider-insert-in-repl (form eval)
+  "Insert FORM in the REPL buffer and switch to it.
+If EVAL is non-nil the form will also be evaluated."
+  (while (string-match "\\`[ \t\n\r]+\\|[ \t\n\r]+\\'" form)
+    (setq form (replace-match "" t t form)))
+  (with-current-buffer (cider-current-repl)
+    (goto-char (point-max))
+    (let ((beg (point)))
+      (insert form)
+      (indent-region beg (point)))
+    (when (if cider-invert-insert-eval-p
+              (not eval)
+            eval)
+      (cider-repl-return)))
+  (when cider-switch-to-repl-after-insert-p
+    (cider-switch-to-repl-buffer)))
+
+(defun cider-insert-last-sexp-in-repl (&optional arg)
+  "Insert the expression preceding point in the REPL buffer.
+If invoked with a prefix ARG eval the expression after inserting it."
+  (interactive "P")
+  (cider-insert-in-repl (cider-last-sexp) arg))
+
+(defun cider-insert-defun-in-repl (&optional arg)
+  "Insert the top level form at point in the REPL buffer.
+If invoked with a prefix ARG eval the expression after inserting it."
+  (interactive "P")
+  (cider-insert-in-repl (cider-defun-at-point) arg))
+
+(defun cider-insert-region-in-repl (start end &optional arg)
+  "Insert the curent region in the REPL buffer.
+START and END represent the region's boundaries.
+If invoked with a prefix ARG eval the expression after inserting it."
+  (interactive "rP")
+  (cider-insert-in-repl
+   (buffer-substring-no-properties start end) arg))
+
+(defun cider-insert-ns-form-in-repl (&optional arg)
+  "Insert the current buffer's ns form in the REPL buffer.
+If invoked with a prefix ARG eval the expression after inserting it."
+  (interactive "P")
+  (cider-insert-in-repl (cider-ns-form) arg))
+
+
+
+;;; The menu-bar
+(defconst cider-mode-menu
+  `("CIDER"
+    ["Start or connect to any REPL" cider
+     :help "A simple wrapper around all commands for starting/connecting to a REPL."]
+    ("Clojure"
+     ["Start a Clojure REPL" cider-jack-in
+      :help "Starts an nREPL server and connects a Clojure REPL to it."]
+     ["Connect to a Clojure REPL" cider-connect
+      :help "Connects to a REPL that's already running."])
+    ("ClojureScript"
+     ["Start a ClojureScript REPL" cider-jack-in-cljs
+      :help "Starts an nREPL server and connects a ClojureScript REPL to it."]
+     ["Connect to a ClojureScript REPL" cider-connect-clojurescript
+      :help "Connects to a ClojureScript REPL that's already running."]
+     ["Create a ClojureScript REPL from a Clojure REPL" cider-jack-in-sibling-clojurescript])
+    "--"
+    ["Quit" cider-quit :active (cider-connected-p)]
+    ["Restart" cider-restart :active (cider-connected-p)]
+    "--"
+    ["Connection info" cider-describe-current-connection
+     :active (cider-connected-p)]
+    ["Select any CIDER buffer" cider-selector]
+    "--"
+    ["Configure CIDER" (customize-group 'cider)]
+    "--"
+    ["A sip of CIDER" cider-drink-a-sip]
+    ["View manual online" cider-view-manual]
+    ["View refcard online" cider-view-refcard]
+    ["Report a bug" cider-report-bug]
+    ["Version info" cider-version]
+    "--"
+    ["Close ancillary buffers" cider-close-ancillary-buffers
+     :active (seq-remove #'null cider-ancillary-buffers)]
+    ("nREPL" :active (cider-connected-p)
+     ["Describe nrepl session" cider-describe-nrepl-session]
+     ["Toggle message logging" nrepl-toggle-message-logging])
+    "Menu for CIDER mode."))
+
+(defconst cider-mode-eval-menu
+  '("CIDER Eval" :visible (cider-connected-p)
+    ["Eval top-level sexp" cider-eval-defun-at-point]
+    ["Eval top-level sexp to point" cider-eval-defun-up-to-point]
+    ["Eval top-level sexp to comment" cider-eval-defun-to-comment]
+    ["Eval top-level sexp and pretty-print to comment" cider-pprint-eval-defun-to-comment]
+    "--"
+    ["Eval current sexp" cider-eval-sexp-at-point]
+    ["Eval current sexp to point" cider-eval-sexp-up-to-point]
+    ["Eval current sexp in context" cider-eval-sexp-at-point-in-context]
+    "--"
+    ["Eval last sexp" cider-eval-last-sexp]
+    ["Eval last sexp in context" cider-eval-last-sexp-in-context]
+    ["Eval last sexp and insert" cider-eval-print-last-sexp
+     :keys "\\[universal-argument] \\[cider-eval-last-sexp]"]
+    ["Eval last sexp in popup buffer" cider-pprint-eval-last-sexp]
+    ["Eval last sexp and replace" cider-eval-last-sexp-and-replace]
+    ["Eval last sexp to REPL" cider-eval-last-sexp-to-repl]
+    ["Eval last sexp and pretty-print to REPL" cider-pprint-eval-last-sexp-to-repl]
+    ["Eval last sexp and pretty-print to comment" cider-pprint-eval-last-sexp-to-comment]
+    "--"
+    ["Eval selected region" cider-eval-region]
+    ["Eval ns form" cider-eval-ns-form]
+    "--"
+    ["Interrupt evaluation" cider-interrupt]
+    "--"
+    ["Insert last sexp in REPL" cider-insert-last-sexp-in-repl]
+    ["Insert top-level sexp in REPL" cider-insert-defun-in-repl]
+    ["Insert region in REPL" cider-insert-region-in-repl]
+    ["Insert ns form in REPL" cider-insert-ns-form-in-repl]
+    "--"
+    ["Load this buffer" cider-load-buffer]
+    ["Load another file" cider-load-file]
+    ["Recursively load all files in directory" cider-load-all-files]
+    ["Load all project files" cider-load-all-project-ns]
+    ["Refresh loaded code" cider-ns-refresh]
+    ["Run project (-main function)" cider-run])
+  "Menu for CIDER mode eval commands.")
+
+(defconst cider-mode-interactions-menu
+  `("CIDER Interactions" :visible (cider-connected-p)
+    ["Complete symbol" complete-symbol]
+    "--"
+    ("REPL"
+     ["Set REPL to this ns" cider-repl-set-ns]
+     ["Switch to REPL" cider-switch-to-repl-buffer]
+     ["REPL Pretty Print" cider-repl-toggle-pretty-printing
+      :style toggle :selected cider-repl-use-pretty-printing]
+     ["Clear latest output" cider-find-and-clear-repl-output]
+     ["Clear all output" (cider-find-and-clear-repl-output t)
+      :keys "\\[universal-argument] \\[cider-find-and-clear-repl-output]"]
+     "--"
+     ["Configure the REPL" (customize-group 'cider-repl)])
+    ,cider-doc-menu
+    ("Find (jump to)"
+     ["Find definition" cider-find-var]
+     ["Find namespace" cider-find-ns]
+     ["Find resource" cider-find-resource]
+     ["Find keyword" cider-find-keyword]
+     ["Go back" cider-pop-back])
+    ("Browse"
+     ["Browse namespace" cider-browse-ns]
+     ["Browse all namespaces" cider-browse-ns-all]
+     ["Browse spec" cider-browse-spec]
+     ["Browse all specs" cider-browse-spec-all]
+     ["Browse REPL input history" cider-repl-history]
+     ["Browse classpath" cider-classpath]
+     ["Browse classpath entry" cider-open-classpath-entry])
+    ("Format"
+     ["Format EDN last sexp" cider-format-edn-last-sexp]
+     ["Format EDN region" cider-format-edn-region]
+     ["Format EDN buffer" cider-format-edn-buffer])
+    ("Macroexpand"
+     ["Macroexpand-1" cider-macroexpand-1]
+     ["Macroexpand-all" cider-macroexpand-all])
+    ,cider-test-menu
+    ("Debug"
+     ["Inspect" cider-inspect]
+     ["Toggle var tracing" cider-toggle-trace-var]
+     ["Toggle ns tracing" cider-toggle-trace-ns]
+     "--"
+     ["Debug top-level form" cider-debug-defun-at-point
+      :keys "\\[universal-argument] \\[cider-eval-defun-at-point]"]
+     ["List instrumented defs" cider-browse-instrumented-defs]
+     "--"
+     ["Configure the Debugger" (customize-group 'cider-debug)])
+    ,cider-profile-menu
+    ("Misc"
+     ["Clojure Cheatsheet" cider-cheatsheet]
+     ["Flush completion cache" cider-completion-flush-caches]))
+  "Menu for CIDER interactions.")
+
+
+(declare-function cider-ns-refresh "cider-ns")
+(declare-function cider-browse-ns "cider-browse-ns")
+(declare-function cider-eval-ns-form "cider-eval")
+(declare-function cider-repl-set-ns "cider-repl")
+(declare-function cider-find-ns "cider-find")
+
+(defvar cider-ns-map
+  (let ((map (define-prefix-command 'cider-ns-map)))
+    (define-key map (kbd "b") #'cider-browse-ns)
+    (define-key map (kbd "M-b") #'cider-browse-ns)
+    (define-key map (kbd "e") #'cider-eval-ns-form)
+    (define-key map (kbd "M-e") #'cider-eval-ns-form)
+    (define-key map (kbd "f") #'cider-find-ns)
+    (define-key map (kbd "M-f") #'cider-find-ns)
+    (define-key map (kbd "n") #'cider-repl-set-ns)
+    (define-key map (kbd "M-n") #'cider-repl-set-ns)
+    (define-key map (kbd "r") #'cider-ns-refresh)
+    (define-key map (kbd "M-r") #'cider-ns-refresh)
+    map)
+  "CIDER NS keymap.")
+
+;; Those declares are needed, because we autoload all those commands when first
+;; used. That optimizes CIDER's initial load time.
+(declare-function cider-macroexpand-1 "cider-macroexpansion")
+(declare-function cider-macroexpand-all "cider-macroexpansion")
+(declare-function cider-selector "cider-selector")
+(declare-function cider-toggle-trace-ns "cider-tracing")
+(declare-function cider-toggle-trace-var "cider-tracing")
+(declare-function cider-find-resource "cider-find")
+(declare-function cider-find-keyword "cider-find")
+(declare-function cider-find-var "cider-find")
+
+(defconst cider-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "C-c C-d") 'cider-doc-map)
+    (define-key map (kbd "M-.") #'cider-find-var)
+    (define-key map (kbd "C-c C-.") #'cider-find-ns)
+    (define-key map (kbd "C-c C-:") #'cider-find-keyword)
+    (define-key map (kbd "M-,") #'cider-pop-back)
+    (define-key map (kbd "C-c M-.") #'cider-find-resource)
+    (define-key map (kbd "M-TAB") #'complete-symbol)
+    (define-key map (kbd "C-M-x")   #'cider-eval-defun-at-point)
+    (define-key map (kbd "C-c C-c") #'cider-eval-defun-at-point)
+    (define-key map (kbd "C-x C-e") #'cider-eval-last-sexp)
+    (define-key map (kbd "C-c C-e") #'cider-eval-last-sexp)
+    (define-key map (kbd "C-c C-v") 'cider-eval-commands-map)
+    (define-key map (kbd "C-c C-j") 'cider-insert-commands-map)
+    (define-key map (kbd "C-c M-;") #'cider-eval-defun-to-comment)
+    (define-key map (kbd "C-c M-e") #'cider-eval-last-sexp-to-repl)
+    (define-key map (kbd "C-c M-p") #'cider-insert-last-sexp-in-repl)
+    (define-key map (kbd "C-c C-p") #'cider-pprint-eval-last-sexp)
+    (define-key map (kbd "C-c C-f") #'cider-pprint-eval-defun-at-point)
+    (define-key map (kbd "C-c M-:") #'cider-read-and-eval)
+    (define-key map (kbd "C-c C-u") #'cider-undef)
+    (define-key map (kbd "C-c C-m") #'cider-macroexpand-1)
+    (define-key map (kbd "C-c M-m") #'cider-macroexpand-all)
+    (define-key map (kbd "C-c M-n") 'cider-ns-map)
+    (define-key map (kbd "C-c M-i") #'cider-inspect)
+    (define-key map (kbd "C-c M-t v") #'cider-toggle-trace-var)
+    (define-key map (kbd "C-c M-t n") #'cider-toggle-trace-ns)
+    (define-key map (kbd "C-c C-z") #'cider-switch-to-repl-buffer)
+    (define-key map (kbd "C-c M-z") #'cider-load-buffer-and-switch-to-repl-buffer)
+    (define-key map (kbd "C-c C-o") #'cider-find-and-clear-repl-output)
+    (define-key map (kbd "C-c C-k") #'cider-load-buffer)
+    (define-key map (kbd "C-c C-l") #'cider-load-file)
+    (define-key map (kbd "C-c C-M-l") #'cider-load-all-files)
+    (define-key map (kbd "C-c C-b") #'cider-interrupt)
+    (define-key map (kbd "C-c ,")   'cider-test-commands-map)
+    (define-key map (kbd "C-c C-t") 'cider-test-commands-map)
+    (define-key map (kbd "C-c M-s") #'cider-selector)
+    (define-key map (kbd "C-c M-d") #'cider-describe-current-connection)
+    (define-key map (kbd "C-c C-=") 'cider-profile-map)
+    (define-key map (kbd "C-c C-q") #'cider-quit)
+    (define-key map (kbd "C-c M-r") #'cider-restart)
+    (dolist (variable '(cider-mode-interactions-menu
+                        cider-mode-eval-menu
+                        cider-mode-menu))
+      (easy-menu-do-define (intern (format "%s-open" variable))
+                           map
+                           (get variable 'variable-documentation)
+                           (cider--menu-add-help-strings (symbol-value variable))))
+    map))
+
+;; This menu works as an easy entry-point into CIDER.  Even if cider.el isn't
+;; loaded yet, this will be shown in Clojure buffers next to the "Clojure"
+;; menu.
+;;;###autoload
+(eval-after-load 'clojure-mode
+  '(easy-menu-define cider-clojure-mode-menu-open clojure-mode-map
+     "Menu for Clojure mode.
+  This is displayed in `clojure-mode' buffers, if `cider-mode' is not active."
+     `("CIDER" :visible (not cider-mode)
+       ["Start a Clojure REPL" cider-jack-in
+        :help "Starts an nREPL server (with Leiningen, Boot, or Gradle) and connects a REPL to it."]
+       ["Connect to a Clojure REPL" cider-connect
+        :help "Connects to a REPL that's already running."]
+       ["Connect to a ClojureScript REPL" cider-connect-clojurescript
+        :help "Connects to a ClojureScript REPL that's already running."]
+       ["Start a Clojure REPL, and a ClojureScript REPL" cider-jack-in-cljs
+        :help "Starts an nREPL server, connects a Clojure REPL to it, and then a ClojureScript REPL."]
+       "--"
+       ["View manual online" cider-view-manual])))
+
+;;; Dynamic indentation
+(defcustom cider-dynamic-indentation t
+  "Whether CIDER should aid Clojure(Script) indentation.
+If non-nil, CIDER uses runtime information (such as the \":style/indent\"
+metadata) to improve standard `clojure-mode' indentation.
+If nil, CIDER won't interfere with `clojure-mode's indentation.
+
+Toggling this variable only takes effect after a file is closed and
+re-visited."
+  :type 'boolean
+  :package-version '(cider . "0.11.0")
+  :group 'cider)
+
+(defun cider--get-symbol-indent (symbol-name)
+  "Return the indent metadata for SYMBOL-NAME in the current namespace."
+  (let* ((ns (cider-current-ns)))
+    (if-let* ((meta (cider-resolve-var ns symbol-name))
+              (indent (or (nrepl-dict-get meta "style/indent")
+                          (nrepl-dict-get meta "indent"))))
+        (let ((format (format ":indent metadata on ‘%s’ is unreadable! \nERROR: %%s"
+                              symbol-name)))
+          (with-demoted-errors format
+            (cider--deep-vector-to-list (read indent))))
+      ;; There's no indent metadata, but there might be a clojure-mode
+      ;; indent-spec with fully-qualified namespace.
+      (when (string-match cider-resolve--prefix-regexp symbol-name)
+        (when-let* ((sym (intern-soft (replace-match (save-match-data
+                                                       (cider-resolve-alias ns (match-string 1 symbol-name)))
+                                                     t t symbol-name 1))))
+          (get sym 'clojure-indent-function))))))
+
+
+;;; Dynamic font locking
+(defcustom cider-font-lock-dynamically '(macro core deprecated)
+  "Specifies how much dynamic font-locking CIDER should use.
+Dynamic font-locking this refers to applying syntax highlighting to vars
+defined in the currently active nREPL connection.  This is done in addition
+to `clojure-mode's usual (static) font-lock, so even if you set this
+variable to nil you'll still see basic syntax highlighting.
+
+The value is a list of symbols, each one indicates a different type of var
+that should be font-locked:
+   `macro' (default): Any defined macro gets the `font-lock-builtin-face'.
+   `function': Any defined function gets the `font-lock-function-face'.
+   `var': Any non-local var gets the `font-lock-variable-face'.
+   `deprecated' (default): Any deprecated var gets the `cider-deprecated-face'
+   face.
+   `core' (default): Any symbol from clojure.core (face depends on type).
+
+The value can also be t, which means to font-lock as much as possible."
+  :type '(choice (set :tag "Fine-tune font-locking"
+                      (const :tag "Any defined macro" macro)
+                      (const :tag "Any defined function" function)
+                      (const :tag "Any defined var" var)
+                      (const :tag "Any defined deprecated" deprecated)
+                      (const :tag "Any symbol from clojure.core" core))
+                 (const :tag "Font-lock as much as possible" t))
+  :group 'cider
+  :package-version '(cider . "0.10.0"))
+
+(defcustom cider-font-lock-reader-conditionals t
+  "Apply font-locking to unused reader conditional expressions depending on the buffer CIDER connection type."
+  :type 'boolean
+  :group 'cider
+  :package-version '(cider . "0.15.0"))
+
+(defface cider-deprecated-face
+  '((((background light)) :background "light goldenrod")
+    (((background dark)) :background "#432"))
+  "Face used on deprecated vars."
+  :group 'cider)
+
+(defface cider-instrumented-face
+  '((((type graphic)) :box (:color "#c00" :line-width -1))
+    (t :underline t :background "#800"))
+  "Face used to mark code being debugged."
+  :group 'cider-debug
+  :group 'cider
+  :package-version '(cider . "0.10.0"))
+
+(defface cider-traced-face
+  '((((type graphic)) :box (:color "cyan" :line-width -1))
+    (t :underline t :background "#066"))
+  "Face used to mark code being traced."
+  :group 'cider
+  :package-version '(cider . "0.11.0"))
+
+(defface cider-reader-conditional-face
+  '((t (:inherit font-lock-comment-face)))
+  "Face used to mark unused reader conditional expressions."
+  :group 'cider
+  :package-version '(cider . "0.15.0"))
+
+(defconst cider-reader-conditionals-regexp "\\(?:#\\?@?[[:space:]\n]*(\\)"
+  "Regexp for matching reader conditionals with a non-capturing group.
+Starts from the reader macro characters to the opening parentheses.")
+
+(defvar cider--reader-conditionals-match-data (list nil nil)
+  "Reusable list for `match-data` in reader conditionals font lock matchers.")
+
+(defun cider--search-reader-conditionals (limit)
+  "Matcher for finding reader conditionals.
+Search is done with the given LIMIT."
+  (when (and cider-font-lock-reader-conditionals
+             (cider-connected-p))
+    (when (search-forward-regexp cider-reader-conditionals-regexp limit t)
+      (let ((start (match-beginning 0))
+            (state (syntax-ppss)))
+        (if (or (nth 3 state) (nth 4 state)) ; inside string or comment?
+            (cider--search-reader-conditionals limit)
+          (when (<= (point) limit)
+            (ignore-errors
+              (let ((md (match-data nil cider--reader-conditionals-match-data)))
+                (setf (nth 0 md) start)
+                (setf (nth 1 md) (point))
+                (set-match-data md)
+                t))))))))
+
+(defun cider--anchored-search-suppressed-forms-internal (repl-types limit)
+  "Helper function for `cider--anchored-search-suppressed-forms`.
+REPL-TYPES is a list of strings repl-type strings.  LIMIT is the same as
+the LIMIT in `cider--anchored-search-suppressed-forms`"
+  (when (= (length repl-types) 1)
+    (let ((type (car repl-types))
+          (expr (read (current-buffer)))
+          (start (save-excursion (backward-sexp) (point))))
+      (when (<= (point) limit)
+        (forward-sexp)
+        (if (not (string-equal (symbol-name expr) (concat ":" type)))
+            (ignore-errors
+              (cl-assert (<= (point) limit))
+              (let ((md (match-data nil cider--reader-conditionals-match-data)))
+                (setf (nth 0 md) start)
+                (setf (nth 1 md) (point))
+                (set-match-data md)
+                t))
+          (cider--anchored-search-suppressed-forms-internal repl-types limit))))))
+
+(defun cider--anchored-search-suppressed-forms (limit)
+  "Matcher for finding unused reader conditional expressions.
+An unused reader conditional expression is an expression for a platform
+that does not match the CIDER connection for the buffer.  Search is done
+with the given LIMIT."
+  (let ((repl-types (seq-uniq (seq-map #'cider-repl-type (cider-repls))))
+        (result 'retry))
+    (while (and (eq result 'retry) (<= (point) limit))
+      (condition-case condition
+          (setq result
+                (cider--anchored-search-suppressed-forms-internal
+                 repl-types limit))
+        (invalid-read-syntax
+         (setq result 'retry))
+        (wrong-type-argument
+         (setq result 'retry))
+        (scan-error
+         (setq result 'retry))
+        (end-of-file
+         (setq result nil))
+        (error
+         (setq result nil)
+         (message
+          "Error during fontification while searching for forms: %S"
+          condition))))
+    (if (eq result 'retry) (setq result nil))
+    result))
+
+(defconst cider--reader-conditionals-font-lock-keywords
+  '((cider--search-reader-conditionals
+     (cider--anchored-search-suppressed-forms
+      (save-excursion
+        (let* ((state (syntax-ppss))
+               (list-pt (nth 1 state)))
+          (when list-pt
+            (goto-char list-pt)
+            (forward-list)
+            (backward-char)
+            (point))))
+      nil
+      (0 'cider-reader-conditional-face t))))
+  "Font Lock keywords for unused reader conditionals in CIDER mode.")
+
+(defun cider--unless-local-match (value)
+  "Return VALUE, unless `match-string' is a local var."
+  (unless (or (get-text-property (point) 'cider-block-dynamic-font-lock)
+              (member (match-string 0)
+                      (get-text-property (point) 'cider-locals)))
+    value))
+
+(defun cider--compile-font-lock-keywords (symbols-plist core-plist)
+  "Return a list of font-lock rules for the symbols in SYMBOLS-PLIST and CORE-PLIST."
+  (let ((cider-font-lock-dynamically (if (eq cider-font-lock-dynamically t)
+                                         '(function var macro core deprecated)
+                                       cider-font-lock-dynamically))
+        deprecated enlightened
+        macros functions vars instrumented traced)
+    (cl-labels ((handle-plist
+                 (plist)
+                 (let ((do-function (memq 'function cider-font-lock-dynamically))
+                       (do-var (memq 'var cider-font-lock-dynamically))
+                       (do-macro (memq 'macro cider-font-lock-dynamically))
+                       (do-deprecated (memq 'deprecated cider-font-lock-dynamically)))
+                   (while plist
+                     (let ((sym (pop plist))
+                           (meta (pop plist)))
+                       (pcase (nrepl-dict-get meta "cider/instrumented")
+                         (`nil nil)
+                         (`"\"breakpoint-if-interesting\""
+                          (push sym instrumented))
+                         (`"\"light-form\""
+                          (push sym enlightened)))
+                       ;; The ::traced keywords can be inlined by MrAnderson, so
+                       ;; we catch that case too.
+                       ;; FIXME: This matches values too, not just keys.
+                       (when (seq-find (lambda (k) (and (stringp k)
+                                                        (string-match (rx "clojure.tools.trace/traced" eos) k)))
+                                       meta)
+                         (push sym traced))
+                       (when (and do-deprecated (nrepl-dict-get meta "deprecated"))
+                         (push sym deprecated))
+                       (cond ((and do-macro (nrepl-dict-get meta "macro"))
+                              (push sym macros))
+                             ((and do-function (or (nrepl-dict-get meta "fn")
+                                                   (nrepl-dict-get meta "arglists")))
+                              (push sym functions))
+                             (do-var (push sym vars))))))))
+      (when (memq 'core cider-font-lock-dynamically)
+        (let ((cider-font-lock-dynamically '(function var macro core deprecated)))
+          (handle-plist core-plist)))
+      (handle-plist symbols-plist))
+    `(
+      ,@(when macros
+          `((,(concat (rx (or "(" "#'")) ; Can't take the value of macros.
+                      "\\(" (regexp-opt macros 'symbols) "\\)")
+             1 (cider--unless-local-match font-lock-keyword-face))))
+      ,@(when functions
+          `((,(regexp-opt functions 'symbols) 0
+             (cider--unless-local-match font-lock-function-name-face))))
+      ,@(when vars
+          `((,(regexp-opt vars 'symbols) 0
+             (cider--unless-local-match font-lock-variable-name-face))))
+      ,@(when deprecated
+          `((,(regexp-opt deprecated 'symbols) 0
+             (cider--unless-local-match 'cider-deprecated-face) append)))
+      ,@(when enlightened
+          `((,(regexp-opt enlightened 'symbols) 0
+             (cider--unless-local-match 'cider-enlightened-face) append)))
+      ,@(when instrumented
+          `((,(regexp-opt instrumented 'symbols) 0
+             (cider--unless-local-match 'cider-instrumented-face) append)))
+      ,@(when traced
+          `((,(regexp-opt traced 'symbols) 0
+             (cider--unless-local-match 'cider-traced-face) append))))))
+
+(defconst cider--static-font-lock-keywords
+  (eval-when-compile
+    `((,(regexp-opt '("#break" "#dbg" "#light") 'symbols) 0 font-lock-warning-face)))
+  "Default expressions to highlight in CIDER mode.")
+
+(defvar-local cider--dynamic-font-lock-keywords nil)
+
+(defun cider-refresh-dynamic-font-lock (&optional ns)
+  "Ensure that the current buffer has up-to-date font-lock rules.
+NS defaults to `cider-current-ns', and it can also be a dict describing the
+namespace itself."
+  (interactive)
+  (when (and cider-font-lock-dynamically
+             font-lock-mode)
+    (font-lock-remove-keywords nil cider--dynamic-font-lock-keywords)
+    (when-let* ((ns (or ns (cider-current-ns)))
+                (symbols (cider-resolve-ns-symbols ns)))
+      (setq-local cider--dynamic-font-lock-keywords
+                  (cider--compile-font-lock-keywords
+                   symbols (cider-resolve-ns-symbols (cider-resolve-core-ns))))
+      (font-lock-add-keywords nil cider--dynamic-font-lock-keywords 'end))
+    (cider--font-lock-flush)))
+
+
+;;; Detecting local variables
+(defun cider--read-locals-from-next-sexp ()
+  "Return a list of all locals inside the next logical sexp."
+  (save-excursion
+    (ignore-errors
+      (clojure-forward-logical-sexp 1)
+      (let ((out nil)
+            (end (point)))
+        (forward-sexp -1)
+        ;; FIXME: This returns locals found inside the :or clause of a
+        ;; destructuring map.
+        (while (search-forward-regexp "\\_<[^:&]\\(\\sw\\|\\s_\\)*\\_>" end 'noerror)
+          (push (match-string-no-properties 0) out))
+        out))))
+
+(defun cider--read-locals-from-bindings-vector ()
+  "Return a list of all locals inside the next bindings vector."
+  (save-excursion
+    (ignore-errors
+      (cider-start-of-next-sexp)
+      (when (eq (char-after) ?\[)
+        (forward-char 1)
+        (let ((out nil))
+          (setq out (append (cider--read-locals-from-next-sexp) out))
+          (while (ignore-errors (clojure-forward-logical-sexp 3)
+                                (unless (eobp)
+                                  (forward-sexp -1)
+                                  t))
+            (setq out (append (cider--read-locals-from-next-sexp) out)))
+          out)))))
+
+(defun cider--read-locals-from-arglist ()
+  "Return a list of all locals in current form's arglist(s)."
+  (let ((out nil))
+    (save-excursion
+      (ignore-errors
+        (cider-start-of-next-sexp)
+        ;; Named fn
+        (when (looking-at-p "\\s_\\|\\sw")
+          (cider-start-of-next-sexp 1))
+        ;; Docstring
+        (when (eq (char-after) ?\")
+          (cider-start-of-next-sexp 1))
+        ;; Attribute map
+        (when (eq (char-after) ?{)
+          (cider-start-of-next-sexp 1))
+        ;; The arglist
+        (pcase (char-after)
+          (?\[ (setq out (cider--read-locals-from-next-sexp)))
+          ;; FIXME: This returns false positives. It takes all arglists of a
+          ;; function and returns all args it finds. The logic should be changed
+          ;; so that each arglist applies to its own scope.
+          (?\( (ignore-errors
+                 (while (eq (char-after) ?\()
+                   (save-excursion
+                     (forward-char 1)
+                     (setq out (append (cider--read-locals-from-next-sexp) out)))
+                   (cider-start-of-next-sexp 1)))))))
+    out))
+
+(defun cider--parse-and-apply-locals (end &optional outer-locals)
+  "Figure out local variables between point and END.
+A list of these variables is set as the `cider-locals' text property over
+the code where they are in scope.
+Optional argument OUTER-LOCALS is used to specify local variables defined
+before point."
+  (while (search-forward-regexp "(\\(ns\\_>\\|def\\|fn\\|for\\b\\|loop\\b\\|with-\\|do[a-z]+\\|\\([a-z]+-\\)?let\\b\\)"
+                                end 'noerror)
+    (goto-char (match-beginning 0))
+    (let ((sym (match-string 1))
+          (sexp-end (save-excursion
+                      (or (ignore-errors (forward-sexp 1)
+                                         (point))
+                          end))))
+      ;; #1324: Don't do dynamic font-lock in `ns' forms, they are special
+      ;; macros where nothing is evaluated, so we'd get a lot of false
+      ;; positives.
+      (if (equal sym "ns")
+          (add-text-properties (point) sexp-end '(cider-block-dynamic-font-lock t))
+        (forward-char 1)
+        (forward-sexp 1)
+        (let ((locals (append outer-locals
+                              (pcase sym
+                                ((or "fn" "def" "") (cider--read-locals-from-arglist))
+                                (_ (cider--read-locals-from-bindings-vector))))))
+          (add-text-properties (point) sexp-end (list 'cider-locals locals))
+          (clojure-forward-logical-sexp 1)
+          (cider--parse-and-apply-locals sexp-end locals)))
+      (goto-char sexp-end))))
+
+(defun cider--update-locals-for-region (beg end)
+  "Update the `cider-locals' text property for region from BEG to END."
+  (save-excursion
+    (goto-char beg)
+    ;; If the inside of a `ns' form changed, reparse it from the start.
+    (when (and (not (bobp))
+               (get-text-property (1- (point)) 'cider-block-dynamic-font-lock))
+      (ignore-errors (beginning-of-defun)))
+    (save-excursion
+      ;; Move up until we reach a sexp that encloses the entire region (or
+      ;; a top-level sexp), and set that as the new BEG.
+      (goto-char end)
+      (while (and (or (> (point) beg)
+                      (not (eq (char-after) ?\()))
+                  (condition-case nil
+                      (progn (backward-up-list) t)
+                    (scan-error nil))))
+      (setq beg (min beg (point)))
+      ;; If there are locals above the current sexp, reapply them to the
+      ;; current sexp.
+      (let ((locals-above (when (> beg (point-min))
+                            (get-text-property (1- beg) 'cider-locals))))
+        (condition-case nil
+            (clojure-forward-logical-sexp 1)
+          (error (goto-char end)))
+        (add-text-properties beg (point) `(cider-locals ,locals-above))
+        ;; Extend the region being font-locked to include whole sexps.
+        (setq end (max end (point)))
+        (goto-char beg)
+        (ignore-errors
+          (cider--parse-and-apply-locals end locals-above))))))
+
+(defun cider--docview-as-string (sym info)
+  "Return a string of what would be displayed by `cider-docview-render'.
+SYM and INFO is passed to `cider-docview-render'"
+  (with-temp-buffer
+    (cider-docview-render (current-buffer) sym info)
+    (goto-char (point-max))
+    (forward-line -1)
+    (replace-regexp-in-string
+     "[`']" "\\\\=\\&"
+     (buffer-substring-no-properties (point-min) (1- (point))))))
+
+(defcustom cider-use-tooltips t
+  "If non-nil, CIDER displays mouse-over tooltips."
+  :group 'cider
+  :type 'boolean
+  :package-version '(cider "0.12.0"))
+
+(defvar cider--debug-mode-response)
+(defvar cider--debug-mode)
+
+(defun cider--help-echo (_ obj pos)
+  "Return the help-echo string for OBJ at POS.
+See \(info \"(elisp) Special Properties\")"
+  (while-no-input
+    (when (and (bufferp obj)
+               (cider-connected-p)
+               cider-use-tooltips (not help-at-pt-display-when-idle))
+      (with-current-buffer obj
+        (ignore-errors
+          (save-excursion
+            (goto-char pos)
+            (when-let* ((sym (cider-symbol-at-point)))
+              (if (member sym (get-text-property (point) 'cider-locals))
+                  (concat (format "`%s' is a local" sym)
+                          (when cider--debug-mode
+                            (let* ((locals (nrepl-dict-get cider--debug-mode-response "locals"))
+                                   (local-val (cadr (assoc sym locals))))
+                              (format " with value:\n%s" local-val))))
+                (let* ((info (cider-sync-request:info sym))
+                       (candidates (nrepl-dict-get info "candidates")))
+                  (if candidates
+                      (concat "There were ambiguities resolving this symbol:\n\n"
+                              (mapconcat (lambda (x) (cider--docview-as-string sym x))
+                                         candidates
+                                         (concat "\n\n" (make-string 60 ?-) "\n\n")))
+                    (cider--docview-as-string sym info)))))))))))
+
+(defun cider--wrap-fontify-locals (func)
+  "Return a function that will call FUNC after parsing local variables.
+The local variables are stored in a list under the `cider-locals' text
+property."
+  (lambda (beg end &rest rest)
+    (with-silent-modifications
+      (remove-text-properties beg end '(cider-locals nil cider-block-dynamic-font-lock nil))
+      (add-text-properties beg end '(help-echo cider--help-echo))
+      (when cider-font-lock-dynamically
+        (cider--update-locals-for-region beg end)))
+    (apply func beg end rest)))
+
+
+;;; Minor-mode definition
+(defvar x-gtk-use-system-tooltips)
+
+;;;###autoload
+(define-minor-mode cider-mode
+  "Minor mode for REPL interaction from a Clojure buffer.
+
+\\{cider-mode-map}"
+  nil
+  cider-mode-line
+  cider-mode-map
+  (if cider-mode
+      (progn
+        (setq-local sesman-system 'CIDER)
+        (cider-eldoc-setup)
+        (make-local-variable 'completion-at-point-functions)
+        (add-to-list 'completion-at-point-functions
+                     #'cider-complete-at-point)
+        (font-lock-add-keywords nil cider--static-font-lock-keywords)
+        (cider-refresh-dynamic-font-lock)
+        (font-lock-add-keywords nil cider--reader-conditionals-font-lock-keywords)
+        ;; `font-lock-mode' might get enabled after `cider-mode'.
+        (add-hook 'font-lock-mode-hook #'cider-refresh-dynamic-font-lock nil 'local)
+        (setq-local font-lock-fontify-region-function
+                    (cider--wrap-fontify-locals font-lock-fontify-region-function))
+        ;; GTK tooltips look bad, and we have no control over the face.
+        (setq-local x-gtk-use-system-tooltips nil)
+        ;; `tooltip' has variable-width by default, which looks terrible.
+        (set-face-attribute 'tooltip nil :inherit 'unspecified)
+        (when cider-dynamic-indentation
+          (setq-local clojure-get-indent-function #'cider--get-symbol-indent))
+        (setq-local clojure-expected-ns-function #'cider-expected-ns)
+        (setq next-error-function #'cider-jump-to-compilation-error))
+    (mapc #'kill-local-variable '(completion-at-point-functions
+                                  next-error-function
+                                  x-gtk-use-system-tooltips
+                                  font-lock-fontify-region-function
+                                  clojure-get-indent-function))
+    (remove-hook 'font-lock-mode-hook #'cider-refresh-dynamic-font-lock 'local)
+    (font-lock-add-keywords nil cider--reader-conditionals-font-lock-keywords)
+    (font-lock-remove-keywords nil cider--dynamic-font-lock-keywords)
+    (font-lock-remove-keywords nil cider--static-font-lock-keywords)
+    (cider--font-lock-flush)))
+
+(defun cider-set-buffer-ns (ns)
+  "Set this buffer's namespace to NS and refresh font-locking."
+  (setq-local cider-buffer-ns ns)
+  (when (or cider-mode (derived-mode-p 'cider-repl-mode))
+    (cider-refresh-dynamic-font-lock ns)))
+
+(provide 'cider-mode)
+
+;;; cider-mode.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-mode.elc b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-mode.elc
new file mode 100644
index 0000000000..8b76826af8
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-mode.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-ns.el b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-ns.el
new file mode 100644
index 0000000000..ec34e7d59a
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-ns.el
@@ -0,0 +1,207 @@
+;;; cider-ns.el --- Namespace manipulation functionality -*- lexical-binding: t -*-
+
+;; Copyright © 2013-2018 Bozhidar Batsov, Artur Malabarba and CIDER contributors
+;;
+;; Author: Bozhidar Batsov <bozhidar@batsov.com>
+;;         Artur Malabarba <bruce.connor.am@gmail.com>
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;; This file is not part of GNU Emacs.
+
+;;; Commentary:
+
+;; Smart code refresh functionality based on ideas
+;; fromhttp://thinkrelevance.com/blog/2013/06/04/clojure-workflow-reloaded
+
+;;; Code:
+
+(require 'subr-x)
+
+(require 'cider-client)
+(require 'cider-popup)
+(require 'cider-stacktrace)
+
+(defcustom cider-ns-save-files-on-refresh 'prompt
+  "Controls whether to prompt to save Clojure files on `cider-ns-refresh'.
+If nil, files are not saved.
+If 'prompt, the user is prompted to save files if they have been modified.
+If t, save the files without confirmation."
+  :type '(choice (const prompt :tag "Prompt to save files if they have been modified")
+                 (const nil :tag "Don't save the files")
+                 (const t :tag "Save the files without confirmation"))
+  :group 'cider
+  :package-version '(cider . "0.15.0"))
+
+(define-obsolete-variable-alias 'cider-save-files-on-cider-ns-refresh 'cider-ns-save-files-on-refresh "0.18")
+
+(defconst cider-ns-refresh-log-buffer "*cider-ns-refresh-log*")
+
+(defcustom cider-ns-refresh-show-log-buffer nil
+  "Controls when to display the refresh log buffer.
+If non-nil, the log buffer will be displayed every time `cider-ns-refresh' is
+called.  If nil, the log buffer will still be written to, but will never be
+displayed automatically.  Instead, the most relevant information will be
+displayed in the echo area."
+  :type '(choice (const :tag "always" t)
+                 (const :tag "never" nil))
+  :group 'cider
+  :package-version '(cider . "0.10.0"))
+
+(define-obsolete-variable-alias 'cider-refresh-show-log-buffer 'cider-ns-refresh-show-log-buffer "0.18")
+
+(defcustom cider-ns-refresh-before-fn nil
+  "Clojure function for `cider-ns-refresh' to call before reloading.
+If nil, nothing will be invoked before reloading.  Must be a
+namespace-qualified function of zero arity.  Any thrown exception will
+prevent reloading from occurring."
+  :type 'string
+  :group 'cider
+  :package-version '(cider . "0.10.0"))
+
+(define-obsolete-variable-alias 'cider-refresh-before-fn 'cider-ns-refresh-before-fn "0.18")
+
+(defcustom cider-ns-refresh-after-fn nil
+  "Clojure function for `cider-ns-refresh' to call after reloading.
+If nil, nothing will be invoked after reloading.  Must be a
+namespace-qualified function of zero arity."
+  :type 'string
+  :group 'cider
+  :package-version '(cider . "0.10.0"))
+
+(define-obsolete-variable-alias 'cider-refresh-after-fn 'cider-ns-refresh-after-fn "0.18")
+
+(defun cider-ns-refresh--handle-response (response log-buffer)
+  "Refresh LOG-BUFFER with RESPONSE."
+  (nrepl-dbind-response response (out err reloading status error error-ns after before)
+    (cl-flet* ((log (message &optional face)
+                    (cider-emit-into-popup-buffer log-buffer message face t))
+
+               (log-echo (message &optional face)
+                         (log message face)
+                         (unless cider-ns-refresh-show-log-buffer
+                           (let ((message-truncate-lines t))
+                             (message "cider-ns-refresh: %s" message)))))
+      (cond
+       (out
+        (log out))
+
+       (err
+        (log err 'font-lock-warning-face))
+
+       ((member "invoking-before" status)
+        (log-echo (format "Calling %s\n" before) 'font-lock-string-face))
+
+       ((member "invoked-before" status)
+        (log-echo (format "Successfully called %s\n" before) 'font-lock-string-face))
+
+       ((member "invoked-not-resolved" status)
+        (log-echo "Could not resolve refresh function\n" 'font-lock-string-face))
+
+       (reloading
+        (log-echo (format "Reloading %s\n" reloading) 'font-lock-string-face))
+
+       ((member "reloading" (nrepl-dict-keys response))
+        (log-echo "Nothing to reload\n" 'font-lock-string-face))
+
+       ((member "ok" status)
+        (log-echo "Reloading successful\n" 'font-lock-string-face))
+
+       (error-ns
+        (log-echo (format "Error reloading %s\n" error-ns) 'font-lock-warning-face))
+
+       ((member "invoking-after" status)
+        (log-echo (format "Calling %s\n" after) 'font-lock-string-face))
+
+       ((member "invoked-after" status)
+        (log-echo (format "Successfully called %s\n" after) 'font-lock-string-face))))
+
+    (with-selected-window (or (get-buffer-window cider-ns-refresh-log-buffer)
+                              (selected-window))
+      (with-current-buffer cider-ns-refresh-log-buffer
+        (goto-char (point-max))))
+
+    (when (member "error" status)
+      (cider--render-stacktrace-causes error))))
+
+(defun cider-ns-refresh--save-project-buffers ()
+  "Ensure modified project buffers are saved before certain operations.
+Its behavior is controlled by `cider-save-files-on-cider-ns-refresh'."
+  (when-let* ((project-root (clojure-project-dir)))
+    (when cider-save-files-on-cider-ns-refresh
+      (save-some-buffers
+       (eq cider-save-files-on-cider-ns-refresh t)
+       (lambda ()
+         (and
+          (derived-mode-p 'clojure-mode)
+          (string-prefix-p project-root
+                           (file-truename default-directory)
+                           (eq system-type 'windows-nt))))))))
+
+;;;###autoload
+(defun cider-ns-refresh (&optional mode)
+  "Reload modified and unloaded namespaces on the classpath.
+
+With a single prefix argument, or if MODE is `refresh-all', reload all
+namespaces on the classpath unconditionally.
+
+With a double prefix argument, or if MODE is `clear', clear the state of
+the namespace tracker before reloading.  This is useful for recovering from
+some classes of error (for example, those caused by circular dependencies)
+that a normal reload would not otherwise recover from.  The trade-off of
+clearing is that stale code from any deleted files may not be completely
+unloaded.
+
+With a negative prefix argument, or if MODE is `inhibit-fns', prevent any
+refresh functions (defined in `cider-ns-refresh-before-fn' and
+`cider-ns-refresh-after-fn') from being invoked."
+  (interactive "p")
+  (cider-ensure-connected)
+  (cider-ensure-op-supported "refresh")
+  (cider-ns-refresh--save-project-buffers)
+  (let ((clear? (member mode '(clear 16)))
+        (refresh-all? (member mode '(refresh-all 4)))
+        (inhibit-refresh-fns (member mode '(inhibit-fns -1))))
+    (cider-map-repls :clj
+      (lambda (conn)
+        ;; Inside the lambda, so the buffer is not created if we error out.
+        (let ((log-buffer (or (get-buffer cider-ns-refresh-log-buffer)
+                              (cider-make-popup-buffer cider-ns-refresh-log-buffer))))
+          (when cider-ns-refresh-show-log-buffer
+            (cider-popup-buffer-display log-buffer))
+          (when inhibit-refresh-fns
+            (cider-emit-into-popup-buffer log-buffer
+                                          "inhibiting refresh functions\n"
+                                          nil
+                                          t))
+          (when clear?
+            (cider-nrepl-send-sync-request '("op" "refresh-clear") conn))
+          (cider-nrepl-send-request
+           (nconc `("op" ,(if refresh-all? "refresh-all" "refresh")
+                    "print-length" ,cider-stacktrace-print-length
+                    "print-level" ,cider-stacktrace-print-level)
+                  (when (cider--pprint-fn)
+                    `("pprint-fn" ,(cider--pprint-fn)))
+                  (when (and (not inhibit-refresh-fns) cider-ns-refresh-before-fn)
+                    `("before" ,cider-ns-refresh-before-fn))
+                  (when (and (not inhibit-refresh-fns) cider-ns-refresh-after-fn)
+                    `("after" ,cider-ns-refresh-after-fn)))
+           (lambda (response)
+             (cider-ns-refresh--handle-response response log-buffer))
+           conn))))))
+
+(define-obsolete-function-alias 'cider-refresh 'cider-ns-refresh "0.18")
+
+(provide 'cider-ns)
+;;; cider-ns.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-ns.elc b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-ns.elc
new file mode 100644
index 0000000000..5de191a9f5
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-ns.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-overlays.el b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-overlays.el
new file mode 100644
index 0000000000..1a92b35f48
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-overlays.el
@@ -0,0 +1,311 @@
+;;; cider-overlays.el --- Managing CIDER overlays  -*- lexical-binding: t; -*-
+
+;; Copyright © 2015-2018 Bozhidar Batsov, Artur Malabarba and CIDER contributors
+
+;; Author: Artur Malabarba <bruce.connor.am@gmail.com>
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Use `cider--make-overlay' to place a generic overlay at point.  Or use
+;; `cider--make-result-overlay' to place an interactive eval result overlay at
+;; the end of a specified line.
+
+;;; Code:
+
+(require 'cider-common)
+(require 'subr-x)
+(require 'cider-compat)
+(require 'cl-lib)
+
+
+;;; Customization
+(defface cider-result-overlay-face
+  '((((class color) (background light))
+     :background "grey90" :box (:line-width -1 :color "yellow"))
+    (((class color) (background dark))
+     :background "grey10" :box (:line-width -1 :color "black")))
+  "Face used to display evaluation results at the end of line.
+If `cider-overlays-use-font-lock' is non-nil, this face is
+applied with lower priority than the syntax highlighting."
+  :group 'cider
+  :package-version '(cider "0.9.1"))
+
+(defcustom cider-result-use-clojure-font-lock t
+  "If non-nil, interactive eval results are font-locked as Clojure code."
+  :group 'cider
+  :type 'boolean
+  :package-version '(cider . "0.10.0"))
+
+(defcustom cider-overlays-use-font-lock t
+  "If non-nil, results overlays are font-locked as Clojure code.
+If nil, apply `cider-result-overlay-face' to the entire overlay instead of
+font-locking it."
+  :group 'cider
+  :type 'boolean
+  :package-version '(cider . "0.10.0"))
+
+(defcustom cider-use-overlays 'both
+  "Whether to display evaluation results with overlays.
+If t, use overlays.  If nil, display on the echo area.  If both, display on
+both places.
+
+Only applies to evaluation commands.  To configure the debugger overlays,
+see `cider-debug-use-overlays'."
+  :type '(choice (const :tag "End of line" t)
+                 (const :tag "Bottom of screen" nil)
+                 (const :tag "Both" both))
+  :group 'cider
+  :package-version '(cider . "0.10.0"))
+
+(defcustom cider-eval-result-prefix "=> "
+  "The prefix displayed in the minibuffer before a result value."
+  :type 'string
+  :group 'cider
+  :package-version '(cider . "0.5.0"))
+
+(defcustom cider-eval-result-duration 'command
+  "Duration, in seconds, of CIDER's eval-result overlays.
+If nil, overlays last indefinitely.
+If the symbol `command', they're erased after the next command.
+Also see `cider-use-overlays'."
+  :type '(choice (integer :tag "Duration in seconds")
+                 (const :tag "Until next command" command)
+                 (const :tag "Last indefinitely" nil))
+  :group 'cider
+  :package-version '(cider . "0.10.0"))
+
+
+;;; Overlay logic
+(defun cider--delete-overlay (ov &rest _)
+  "Safely delete overlay OV.
+Never throws errors, and can be used in an overlay's modification-hooks."
+  (ignore-errors (delete-overlay ov)))
+
+(defun cider--make-overlay (l r type &rest props)
+  "Place an overlay between L and R and return it.
+TYPE is a symbol put on the overlay's category property.  It is used to
+easily remove all overlays from a region with:
+    (remove-overlays start end 'category TYPE)
+PROPS is a plist of properties and values to add to the overlay."
+  (let ((o (make-overlay l (or r l) (current-buffer))))
+    (overlay-put o 'category type)
+    (overlay-put o 'cider-temporary t)
+    (while props (overlay-put o (pop props) (pop props)))
+    (push #'cider--delete-overlay (overlay-get o 'modification-hooks))
+    o))
+
+(defun cider--remove-result-overlay ()
+  "Remove result overlay from current buffer.
+This function also removes itself from `post-command-hook'."
+  (remove-hook 'post-command-hook #'cider--remove-result-overlay 'local)
+  (remove-overlays nil nil 'category 'result))
+
+(defun cider--remove-result-overlay-after-command ()
+  "Add `cider--remove-result-overlay' locally to `post-command-hook'.
+This function also removes itself from `post-command-hook'."
+  (remove-hook 'post-command-hook #'cider--remove-result-overlay-after-command 'local)
+  (add-hook 'post-command-hook #'cider--remove-result-overlay nil 'local))
+
+(defface cider-fringe-good-face
+  '((((class color) (background light)) :foreground "lightgreen")
+    (((class color) (background dark)) :foreground "darkgreen"))
+  "Face used on the fringe indicator for successful evaluation."
+  :group 'cider)
+
+(defconst cider--fringe-overlay-good
+  (propertize " " 'display '(left-fringe empty-line cider-fringe-good-face))
+  "The before-string property that adds a green indicator on the fringe.")
+
+(defcustom cider-use-fringe-indicators t
+  "Whether to display evaluation indicators on the left fringe."
+  :safe #'booleanp
+  :group 'cider
+  :type 'boolean
+  :package-version '(cider . "0.13.0"))
+
+(defun cider--make-fringe-overlay (&optional end)
+  "Place an eval indicator at the fringe before a sexp.
+END is the position where the sexp ends, and defaults to point."
+  (when cider-use-fringe-indicators
+    (with-current-buffer (if (markerp end)
+                             (marker-buffer end)
+                           (current-buffer))
+      (save-excursion
+        (if end
+            (goto-char end)
+          (setq end (point)))
+        (clojure-forward-logical-sexp -1)
+        ;; Create the green-circle overlay.
+        (cider--make-overlay (point) end 'cider-fringe-indicator
+                             'before-string cider--fringe-overlay-good)))))
+
+(cl-defun cider--make-result-overlay (value &rest props &key where duration (type 'result)
+                                            (format (concat " " cider-eval-result-prefix "%s "))
+                                            (prepend-face 'cider-result-overlay-face)
+                                            &allow-other-keys)
+  "Place an overlay displaying VALUE at the end of line.
+VALUE is used as the overlay's after-string property, meaning it is
+displayed at the end of the overlay.  The overlay itself is placed from
+beginning to end of current line.
+Return nil if the overlay was not placed or if it might not be visible, and
+return the overlay otherwise.
+
+Return the overlay if it was placed successfully, and nil if it failed.
+
+This function takes some optional keyword arguments:
+
+  If WHERE is a number or a marker, apply the overlay over
+  the entire line at that place (defaulting to `point').  If
+  it is a cons cell, the car and cdr determine the start and
+  end of the overlay.
+  DURATION takes the same possible values as the
+  `cider-eval-result-duration' variable.
+  TYPE is passed to `cider--make-overlay' (defaults to `result').
+  FORMAT is a string passed to `format'.  It should have
+  exactly one %s construct (for VALUE).
+
+All arguments beyond these (PROPS) are properties to be used on the
+overlay."
+  (declare (indent 1))
+  (while (keywordp (car props))
+    (setq props (cdr (cdr props))))
+  ;; If the marker points to a dead buffer, don't do anything.
+  (let ((buffer (cond
+                 ((markerp where) (marker-buffer where))
+                 ((markerp (car-safe where)) (marker-buffer (car where)))
+                 (t (current-buffer)))))
+    (with-current-buffer buffer
+      (save-excursion
+        (when (number-or-marker-p where)
+          (goto-char where))
+        ;; Make sure the overlay is actually at the end of the sexp.
+        (skip-chars-backward "\r\n[:blank:]")
+        (let* ((beg (if (consp where)
+                        (car where)
+                      (save-excursion
+                        (clojure-backward-logical-sexp 1)
+                        (point))))
+               (end (if (consp where)
+                        (cdr where)
+                      (line-end-position)))
+               (display-string (format format value))
+               (o nil))
+          (remove-overlays beg end 'category type)
+          (funcall (if cider-overlays-use-font-lock
+                       #'font-lock-prepend-text-property
+                     #'put-text-property)
+                   0 (length display-string)
+                   'face prepend-face
+                   display-string)
+          ;; If the display spans multiple lines or is very long, display it at
+          ;; the beginning of the next line.
+          (when (or (string-match "\n." display-string)
+                    (> (string-width display-string)
+                       (- (window-width) (current-column))))
+            (setq display-string (concat " \n" display-string)))
+          ;; Put the cursor property only once we're done manipulating the
+          ;; string, since we want it to be at the first char.
+          (put-text-property 0 1 'cursor 0 display-string)
+          (when (> (string-width display-string) (* 3 (window-width)))
+            (setq display-string
+                  (concat (substring display-string 0 (* 3 (window-width)))
+                          (substitute-command-keys
+                           "...\nResult truncated. Type `\\[cider-inspect-last-result]' to inspect it."))))
+          ;; Create the result overlay.
+          (setq o (apply #'cider--make-overlay
+                         beg end type
+                         'after-string display-string
+                         props))
+          (pcase duration
+            ((pred numberp) (run-at-time duration nil #'cider--delete-overlay o))
+            (`command
+             ;; If inside a command-loop, tell `cider--remove-result-overlay'
+             ;; to only remove after the *next* command.
+             (if this-command
+                 (add-hook 'post-command-hook
+                           #'cider--remove-result-overlay-after-command
+                           nil 'local)
+               (cider--remove-result-overlay-after-command))))
+          (when-let* ((win (get-buffer-window buffer)))
+            ;; Left edge is visible.
+            (when (and (<= (window-start win) (point) (window-end win))
+                       ;; Right edge is visible. This is a little conservative
+                       ;; if the overlay contains line breaks.
+                       (or (< (+ (current-column) (string-width value))
+                              (window-width win))
+                           (not truncate-lines)))
+              o)))))))
+
+
+;;; Displaying eval result
+(defun cider--display-interactive-eval-result (value &optional point)
+  "Display the result VALUE of an interactive eval operation.
+VALUE is syntax-highlighted and displayed in the echo area.
+If POINT and `cider-use-overlays' are non-nil, it is also displayed in an
+overlay at the end of the line containing POINT.
+Note that, while POINT can be a number, it's preferable to be a marker, as
+that will better handle some corner cases where the original buffer is not
+focused."
+  (let* ((font-value (if cider-result-use-clojure-font-lock
+                         (cider-font-lock-as-clojure value)
+                       value))
+         (used-overlay (when (and point cider-use-overlays)
+                         (cider--make-result-overlay font-value
+                           :where point
+                           :duration cider-eval-result-duration))))
+    (message
+     "%s"
+     (propertize (format "%s%s" cider-eval-result-prefix font-value)
+                 ;; The following hides the message from the echo-area, but
+                 ;; displays it in the Messages buffer. We only hide the message
+                 ;; if the user wants to AND if the overlay succeeded.
+                 'invisible (and used-overlay
+                                 (not (eq cider-use-overlays 'both)))))))
+
+
+;;; Fragile buttons
+(defface cider-fragile-button-face
+  '((((type graphic))
+     :box (:line-width 3 :style released-button)
+     :inherit font-lock-warning-face)
+    (t :inverse-video t))
+  "Face for buttons that vanish when clicked."
+  :package-version '(cider . "0.12.0")
+  :group 'cider)
+
+(define-button-type 'cider-fragile
+  'action 'cider--overlay-destroy
+  'follow-link t
+  'face nil
+  'modification-hooks '(cider--overlay-destroy)
+  'help-echo "RET: delete this.")
+
+(defun cider--overlay-destroy (ov &rest r)
+  "Delete overlay OV and its underlying text.
+If any other arguments are given (collected in R), only actually do anything
+if the first one is non-nil.  This is so it works in `modification-hooks'."
+  (unless (and r (not (car r)))
+    (let ((inhibit-modification-hooks t)
+          (beg (copy-marker (overlay-start ov)))
+          (end (copy-marker (overlay-end ov))))
+      (delete-overlay ov)
+      (delete-region beg end)
+      (goto-char beg)
+      (when (= (char-after) (char-before) ?\n)
+        (delete-char 1)))))
+
+(provide 'cider-overlays)
+;;; cider-overlays.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-overlays.elc b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-overlays.elc
new file mode 100644
index 0000000000..1dbedb324c
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-overlays.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-pkg.el b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-pkg.el
new file mode 100644
index 0000000000..7d8078d17d
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-pkg.el
@@ -0,0 +1,14 @@
+(define-package "cider" "20180719.542" "Clojure Interactive Development Environment that Rocks"
+  '((emacs "25")
+    (clojure-mode "5.7.0")
+    (pkg-info "0.4")
+    (queue "0.1.1")
+    (spinner "1.7")
+    (seq "2.16")
+    (sesman "0.1.1"))
+  :keywords
+  '("languages" "clojure" "cider")
+  :url "http://www.github.com/clojure-emacs/cider")
+;; Local Variables:
+;; no-byte-compile: t
+;; End:
diff --git a/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-popup.el b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-popup.el
new file mode 100644
index 0000000000..274a0666b4
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-popup.el
@@ -0,0 +1,137 @@
+;;; cider-popup.el --- Creating and quitting popup buffers  -*- lexical-binding: t; -*-
+
+;; Copyright © 2015-2018  Bozhidar Batsov, Artur Malabarba and CIDER contributors
+
+;; Author: Artur Malabarba <bruce.connor.am@gmail.com>
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Common functionality for dealing with popup buffers.
+
+;;; Code:
+
+(require 'subr-x)
+(require 'cider-compat)
+
+(define-minor-mode cider-popup-buffer-mode
+  "Mode for CIDER popup buffers"
+  nil
+  (" cider-tmp")
+  '(("q" .  cider-popup-buffer-quit-function)))
+
+(defvar-local cider-popup-buffer-quit-function #'cider-popup-buffer-quit
+  "The function that is used to quit a temporary popup buffer.")
+
+(defun cider-popup-buffer-quit-function (&optional kill-buffer-p)
+  "Wrapper to invoke the function `cider-popup-buffer-quit-function'.
+KILL-BUFFER-P is passed along."
+  (interactive)
+  (funcall cider-popup-buffer-quit-function kill-buffer-p))
+
+(defun cider-popup-buffer (name &optional select mode ancillary)
+  "Create new popup buffer called NAME.
+If SELECT is non-nil, select the newly created window.
+If major MODE is non-nil, enable it for the popup buffer.
+If ANCILLARY is non-nil, the buffer is added to `cider-ancillary-buffers'
+and automatically removed when killed."
+  (thread-first (cider-make-popup-buffer name mode ancillary)
+    (cider-popup-buffer-display select)))
+
+(defun cider-popup-buffer-display (buffer &optional select)
+  "Display BUFFER.
+If SELECT is non-nil, select the BUFFER."
+  (let ((window (get-buffer-window buffer 'visible)))
+    (when window
+      (with-current-buffer buffer
+        (set-window-point window (point))))
+    ;; If the buffer we are popping up is already displayed in the selected
+    ;; window, the below `inhibit-same-window' logic will cause it to be
+    ;; displayed twice - so we early out in this case. Note that we must check
+    ;; `selected-window', as async request handlers are executed in the context
+    ;; of the current connection buffer (i.e. `current-buffer' is dynamically
+    ;; bound to that).
+    (unless (eq window (selected-window))
+      ;; Non nil `inhibit-same-window' ensures that current window is not covered
+      ;; Non nil `inhibit-switch-frame' ensures that the other frame is not selected
+      ;; if that's where the buffer is being shown.
+      (funcall (if select #'pop-to-buffer #'display-buffer)
+               buffer `(nil . ((inhibit-same-window . ,pop-up-windows)
+                               (reusable-frames . visible))))))
+  buffer)
+
+(defun cider-popup-buffer-quit (&optional kill)
+  "Quit the current (temp) window.
+Bury its buffer using `quit-restore-window'.
+If prefix argument KILL is non-nil, kill the buffer instead of burying it."
+  (interactive)
+  (quit-restore-window (selected-window) (if kill 'kill 'append)))
+
+(defvar-local cider-popup-output-marker nil)
+
+(defvar cider-ancillary-buffers nil
+  "A list ancillary buffers created by the various CIDER commands.
+We track them mostly to be able to clean them up on quit.")
+
+(defun cider-make-popup-buffer (name &optional mode ancillary)
+  "Create a temporary buffer called NAME using major MODE (if specified).
+If ANCILLARY is non-nil, the buffer is added to `cider-ancillary-buffers'
+and automatically removed when killed."
+  (with-current-buffer (get-buffer-create name)
+    (kill-all-local-variables)
+    (setq buffer-read-only nil)
+    (erase-buffer)
+    (when mode
+      (funcall mode))
+    (cider-popup-buffer-mode 1)
+    (setq cider-popup-output-marker (point-marker))
+    (setq buffer-read-only t)
+    (when ancillary
+      (add-to-list 'cider-ancillary-buffers name)
+      (add-hook 'kill-buffer-hook
+                (lambda ()
+                  (setq cider-ancillary-buffers
+                        (remove name cider-ancillary-buffers)))
+                nil 'local))
+    (current-buffer)))
+
+(defun cider-emit-into-popup-buffer (buffer value &optional face inhibit-indent)
+  "Emit into BUFFER the provided VALUE optionally using FACE.
+Indent emitted value (usually a sexp) unless INHIBIT-INDENT is specified
+and non-nil."
+  ;; Long string output renders Emacs unresponsive and users might intentionally
+  ;; kill the frozen popup buffer. Therefore, we don't re-create the buffer and
+  ;; silently ignore the output.
+  (when (buffer-live-p buffer)
+    (with-current-buffer buffer
+      (let ((inhibit-read-only t)
+            (buffer-undo-list t)
+            (moving (= (point) cider-popup-output-marker)))
+        (save-excursion
+          (goto-char cider-popup-output-marker)
+          (let ((value-str (format "%s" value)))
+            (when face
+              (if (fboundp 'add-face-text-property)
+                  (add-face-text-property 0 (length value-str) face nil value-str)
+                (add-text-properties 0 (length value-str) (list 'face face) value-str)))
+            (insert value-str))
+          (unless inhibit-indent
+            (indent-sexp))
+          (set-marker cider-popup-output-marker (point)))
+        (when moving (goto-char cider-popup-output-marker))))))
+
+(provide 'cider-popup)
+
+;;; cider-popup.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-popup.elc b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-popup.elc
new file mode 100644
index 0000000000..a65f7b3e76
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-popup.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-profile.el b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-profile.el
new file mode 100644
index 0000000000..7957791058
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-profile.el
@@ -0,0 +1,208 @@
+;;; cider-profile.el --- CIDER support for profiling  -*- lexical-binding: t; -*-
+
+;; Copyright © 2014-2018 Edwin Watkeys and CIDER contributors
+
+;; Author: Edwin Watkeys <edw@poseur.com>
+;;         Juan E. Maya <jmayaalv@gmail.com>
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Provides coarse-grained interactive profiling support.
+;; Based on earlier work by Edwin Watkeys (https://github.com/thunknyc/nrepl-profile).
+
+;;; Code:
+
+(require 'cider-client)
+(require 'cider-popup)
+(require 'cider-eval)
+
+(defconst cider-profile-buffer "*cider-profile*")
+
+(defvar cider-profile-map
+  (let ((map (define-prefix-command 'cider-profile-map)))
+    (define-key map (kbd "t") #'cider-profile-toggle)
+    (define-key map (kbd "c") #'cider-profile-clear)
+    (define-key map (kbd "S") #'cider-profile-summary)
+    (define-key map (kbd "s") #'cider-profile-var-summary)
+    (define-key map (kbd "n") #'cider-profile-ns-toggle)
+    (define-key map (kbd "v") #'cider-profile-var-profiled-p)
+    (define-key map (kbd "+") #'cider-profile-samples)
+    map)
+  "CIDER profiler keymap.")
+
+(defconst cider-profile-menu
+  '("Profile"
+    ["Toggle var profiling" cider-profile-toggle]
+    ["Toggle namespace profiling" cider-profile-ns-toggle]
+    "--"
+    ["Display var profiling status" cider-profile-var-profiled-p]
+    ["Display max sample count" cider-profile-samples]
+    ["Display summary" cider-profile-summary]
+    ["Clear data" cider-profile-clear])
+  "CIDER profiling submenu.")
+
+(defun cider-profile--make-response-handler (handler &optional buffer)
+  "Make a response handler using value handler HANDLER for connection BUFFER.
+
+Optional argument BUFFER defaults to current buffer."
+  (nrepl-make-response-handler
+   (or buffer (current-buffer)) handler nil nil nil))
+
+;;;###autoload
+(defun cider-profile-samples (&optional query)
+  "Displays current max-sample-count.
+If optional QUERY is specified, set max-sample-count and display new value."
+  (interactive "P")
+  (cider-ensure-op-supported "set-max-samples")
+  (cider-ensure-op-supported "get-max-samples")
+  (if (not (null query))
+      (cider-nrepl-send-request
+       (let ((max-samples (if (numberp query) query '())))
+         (message "query: %s" max-samples)
+         `("op" "set-max-samples" "max-samples" ,max-samples))
+       (cider-profile--make-response-handler
+        (lambda (_buffer value)
+          (let ((value (if (zerop (length value)) "unlimited" value)))
+            (message "max-sample-count is now %s" value)))))
+    (cider-nrepl-send-request
+     '("op" "get-max-samples")
+     (cider-profile--make-response-handler
+      (lambda (_buffer value)
+        (let ((value (if (zerop (length value)) "unlimited" value)))
+          (message "max-sample-count is now %s" value))))))
+  query)
+
+;;;###autoload
+(defun cider-profile-var-profiled-p (query)
+  "Displays the profiling status of var under point.
+Prompts for var if none under point or QUERY is present."
+  (interactive "P")
+  (cider-ensure-op-supported "is-var-profiled")
+  (cider-read-symbol-name
+   "Report profiling status for var: "
+   (lambda (sym)
+     (let ((ns (cider-current-ns)))
+       (cider-nrepl-send-request
+        `("op" "is-var-profiled"
+          "ns" ,ns
+          "sym" ,sym)
+        (cider-profile--make-response-handler
+         (lambda (_buffer value)
+           (pcase value
+             ("profiled" (message "Profiling is currently enabled for %s/%s" ns sym))
+             ("unprofiled" (message "Profiling  is currently disabled for %s/%s" ns sym))
+             ("unbound" (message "%s/%s is unbound" ns sym)))))))))
+  query)
+
+;;;###autoload
+(defun cider-profile-ns-toggle (&optional query)
+  "Toggle profiling for the ns associated with optional QUERY.
+
+If optional argument QUERY is non-nil, prompt for ns.  Otherwise use
+current ns."
+  (interactive "P")
+  (cider-ensure-op-supported "toggle-profile-ns")
+  (let ((ns (if query
+                (completing-read "Toggle profiling for ns: "
+                                 (cider-sync-request:ns-list))
+              (cider-current-ns))))
+    (cider-nrepl-send-request
+     `("op" "toggle-profile-ns"
+       "ns" ,ns)
+     (cider-profile--make-response-handler
+      (lambda (_buffer value)
+        (pcase value
+          ("profiled" (message "Profiling enabled for %s" ns))
+          ("unprofiled" (message "Profiling disabled for %s" ns)))))))
+  query)
+
+;;;###autoload
+(defun cider-profile-toggle (query)
+  "Toggle profiling for the given QUERY.
+Defaults to the symbol at point.
+With prefix arg or no symbol at point, prompts for a var."
+  (interactive "P")
+  (cider-ensure-op-supported "toggle-profile")
+  (cider-read-symbol-name
+   "Toggle profiling for var: "
+   (lambda (sym)
+     (let ((ns (cider-current-ns)))
+       (cider-nrepl-send-request
+        `("op" "toggle-profile"
+          "ns" ,ns
+          "sym" ,sym)
+        (cider-profile--make-response-handler
+         (lambda (_buffer value)
+           (pcase value
+             ("profiled" (message "Profiling enabled for %s/%s" ns sym))
+             ("unprofiled" (message "Profiling disabled for %s/%s" ns sym))
+             ("unbound" (message "%s/%s is unbound" ns sym)))))))))
+  query)
+
+(defun cider-profile-display-stats (stats-response)
+  "Displays the STATS-RESPONSE on `cider-profile-buffer`."
+  (let ((table (nrepl-dict-get stats-response "err")))
+    (if cider-profile-buffer
+        (let ((buffer (cider-make-popup-buffer cider-profile-buffer)))
+          (with-current-buffer buffer
+            (let ((inhibit-read-only t)) (insert table)))
+          (display-buffer buffer)
+          (let ((window (get-buffer-window buffer)))
+            (set-window-point window 0)
+            (select-window window)
+            (fit-window-to-buffer window)))
+      (cider-emit-interactive-eval-err-output table))))
+
+;;;###autoload
+(defun cider-profile-summary ()
+  "Display a summary of currently collected profile data."
+  (interactive)
+  (cider-ensure-op-supported "profile-summary")
+  (cider-profile-display-stats
+   (cider-nrepl-send-sync-request '("op" "profile-summary"))))
+
+;;;###autoload
+(defun cider-profile-var-summary (query)
+  "Display profile data for var under point QUERY.
+Defaults to the symbol at point.  With prefix arg or no symbol at point,
+prompts for a var."
+  (interactive "P")
+  (cider-ensure-op-supported "profile-var-summary")
+  (cider-read-symbol-name
+   "Profile-summary for var: "
+   (lambda (sym)
+     (cider-profile-display-stats
+      (cider-nrepl-send-sync-request
+       `("op" "profile-var-summary"
+         "ns" ,(cider-current-ns)
+         "sym" ,sym)))))
+  query)
+
+;;;###autoload
+(defun cider-profile-clear ()
+  "Clear any collected profile data."
+  (interactive)
+  (cider-ensure-op-supported "clear-profile")
+  (cider-nrepl-send-request
+   '("op" "clear-profile")
+   (cider-profile--make-response-handler
+    (lambda (_buffer value)
+      (when (equal value "cleared")
+        (message "Cleared profile data"))))))
+
+(provide 'cider-profile)
+
+;;; cider-profile.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-profile.elc b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-profile.elc
new file mode 100644
index 0000000000..ffa751b9d5
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-profile.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-repl-history.el b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-repl-history.el
new file mode 100644
index 0000000000..f6cd4c86cd
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-repl-history.el
@@ -0,0 +1,726 @@
+;;; cider-repl-history.el --- REPL input history browser
+
+;; Copyright (c) 2017 John Valente and browse-kill-ring authors
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;; This file is not part of GNU Emacs.
+
+;; Based heavily on browse-kill-ring
+;; https://github.com/browse-kill-ring/browse-kill-ring
+
+;;; Commentary:
+
+;; REPL input history browser for CIDER.
+
+;; Allows you to browse the full input history for your REPL buffer, and
+;; insert previous commands at the prompt.
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'cider-compat)
+(require 'cider-popup)
+(require 'clojure-mode)
+(require 'derived)
+(require 'pulse)
+
+(defconst cider-repl-history-buffer "*cider-repl-history*")
+
+(defgroup cider-repl-history nil
+  "A package for browsing and inserting the items in the CIDER command history."
+  :prefix "cider-repl-history-"
+  :group 'cider)
+
+(defvar cider-repl-history-display-styles
+  '((separated . cider-repl-history-insert-as-separated)
+    (one-line . cider-repl-history-insert-as-one-line)))
+
+(defcustom cider-repl-history-display-style 'separated
+  "How to display the CIDER command history items.
+
+If `one-line', then replace newlines with \"\\n\" for display.
+
+If `separated', then display `cider-repl-history-separator' between
+entries."
+  :type '(choice (const :tag "One line" one-line)
+                 (const :tag "Separated" separated))
+  :group 'cider-repl-history
+  :package-version '(cider . "0.15.0"))
+
+(defcustom cider-repl-history-quit-action 'quit-window
+  "What action to take when `cider-repl-history-quit' is called.
+
+If `bury-buffer', then simply bury the *cider-repl-history* buffer, but keep
+the window.
+
+If `bury-and-delete-window', then bury the buffer, and (if there is
+more than one window) delete the window.
+
+If `delete-and-restore', then restore the window configuration to what it was
+before `cider-repl-history' was called, and kill the *cider-repl-history*
+buffer.
+
+If `quit-window', then restore the window configuration to what
+it was before `cider-repl-history' was called, and bury *cider-repl-history*.
+This is the default.
+
+If `kill-and-delete-window', then kill the *cider-repl-history* buffer, and
+delete the window on close.
+
+Otherwise, it should be a function to call."
+  ;; Note, if you use one of the non-"delete" options, after you "quit",
+  ;; the *cider-repl-history* buffer is still available.  If you are using
+  ;; `cider-repl-history-show-preview', and you switch to *cider-repl-history* (i.e.,
+  ;; with C-x b), it will not give the preview unless and until you "update"
+  ;; the *cider-repl-history* buffer.
+  ;;
+  ;; This really should not be an issue, because there's no reason to "switch"
+  ;; back to the buffer.  If you want to get it back, you can just do C-c M-p
+  ;; from the REPL buffer.
+
+  ;; If you get in this situation and find it annoying, you can either disable
+  ;; the preview, or set `cider-repl-history-quit-action' to 'delete-and-restore.
+  ;; Then you will simply not have the *cider-repl-history* buffer after you quit,
+  ;; and it won't be an issue.
+
+  :type '(choice (const :tag "Bury buffer"
+                        :value bury-buffer)
+                 (const :tag "Bury buffer and delete window"
+                        :value bury-and-delete-window)
+                 (const :tag "Delete window"
+                        :value delete-and-restore)
+                 (const :tag "Save and restore"
+                        :value quit-window)
+                 (const :tag "Kill buffer and delete window"
+                        :value kill-and-delete-window)
+                 function)
+  :group 'cider-repl-history
+  :package-version '(cider . "0.15.0"))
+
+(defcustom cider-repl-history-resize-window nil
+  "Whether to resize the `cider-repl-history' window to fit its contents.
+Value is either t, meaning yes, or a cons pair of integers,
+ (MAXIMUM . MINIMUM) for the size of the window.  MAXIMUM defaults to
+the window size chosen by `pop-to-buffer'; MINIMUM defaults to
+`window-min-height'."
+  :type '(choice (const :tag "No" nil)
+                 (const :tag "Yes" t)
+                 (cons (integer :tag "Maximum") (integer :tag "Minimum")))
+  :group 'cider-repl-history
+  :package-version '(cider . "0.15.0"))
+
+(defcustom cider-repl-history-separator ";;;;;;;;;;"
+  "The string separating entries in the `separated' style.
+See `cider-repl-history-display-style'."
+  ;; The (default) separator is a Clojure comment, to preserve fontification
+  ;; in the buffer.
+  :type 'string
+  :group 'cider-repl-history
+  :package-version '(cider . "0.15.0"))
+
+(defcustom cider-repl-history-recenter nil
+  "If non-nil, then always keep the current entry at the top of the window."
+  :type 'boolean
+  :group 'cider-repl-history
+  :package-version '(cider . "0.15.0"))
+
+(defcustom cider-repl-history-highlight-current-entry nil
+  "If non-nil, highlight the currently selected command history entry."
+  :type 'boolean
+  :group 'cider-repl-history
+  :package-version '(cider . "0.15.0"))
+
+(defcustom cider-repl-history-highlight-inserted-item nil
+  "If non-nil, then temporarily highlight the inserted command history entry.
+The value selected controls how the inserted item is highlighted,
+possible values are `solid' (highlight the inserted text for a
+fixed period of time), or `pulse' (fade out the highlighting gradually).
+Setting this variable to the value t will select the default
+highlighting style, which currently `pulse'.
+
+The variable `cider-repl-history-inserted-item-face' contains the
+face used for highlighting."
+  :type '(choice (const nil) (const t) (const solid) (const pulse))
+  :group 'cider-repl-history
+  :package-version '(cider . "0.15.0"))
+
+(defcustom cider-repl-history-separator-face 'bold
+  "The face in which to highlight the `cider-repl-history-separator'."
+  :type 'face
+  :group 'cider-repl-history
+  :package-version '(cider . "0.15.0"))
+
+(defcustom cider-repl-history-current-entry-face 'highlight
+  "The face in which to highlight the command history current entry."
+  :type 'face
+  :group 'cider-repl-history
+  :package-version '(cider . "0.15.0"))
+
+(defcustom cider-repl-history-inserted-item-face 'highlight
+  "The face in which to highlight the inserted item."
+  :type 'face
+  :group 'cider-repl-history
+  :package-version '(cider . "0.15.0"))
+
+(defcustom cider-repl-history-maximum-display-length nil
+  "Whether or not to limit the length of displayed items.
+
+If this variable is an integer, the display of the command history will be
+limited to that many characters.
+Setting this variable to nil means no limit."
+  :type '(choice (const :tag "None" nil)
+                 integer)
+  :group 'cider-repl-history
+  :package-version '(cider . "0.15.0"))
+
+(defcustom cider-repl-history-display-duplicates t
+  "If non-nil, then display duplicate items in the command history."
+  :type 'boolean
+  :group 'cider-repl-history
+  :package-version '(cider . "0.15.0"))
+
+(defcustom cider-repl-history-display-duplicate-highest t
+  "When `cider-repl-history-display-duplicates' is nil, then display highest (most recent) duplicate items in the command history."
+  :type 'boolean
+  :group 'cider-repl-history
+  :package-version '(cider . "0.15.0"))
+
+(defcustom cider-repl-history-text-properties nil
+  "If non-nil, maintain text properties of the command history items."
+  :type 'boolean
+  :group 'cider-repl-history
+  :package-version '(cider . "0.15.0"))
+
+(defcustom cider-repl-history-hook nil
+  "A list of functions to call after `cider-repl-history'."
+  :type 'hook
+  :group 'cider-repl-history
+  :package-version '(cider . "0.15.0"))
+
+(defcustom cider-repl-history-show-preview nil
+  "If non-nil, show a preview of the inserted text in the REPL buffer.
+
+The REPL buffer would show a preview of what the buffer would look like
+if the item under point were inserted."
+
+  :type 'boolean
+  :group 'cider-repl-history
+  :package-version '(cider . "0.15.0"))
+
+(defvar cider-repl-history-repl-window nil
+  "The window in which chosen command history data will be inserted.
+It is probably not a good idea to set this variable directly; simply
+call `cider-repl-history' again.")
+
+(defvar cider-repl-history-repl-buffer nil
+  "The buffer in which chosen command history data will be inserted.
+It is probably not a good idea to set this variable directly; simply
+call `cider-repl-history' again.")
+
+(defvar cider-repl-history-preview-overlay nil
+  "The overlay used to preview what would happen if the user inserted the given text.")
+
+(defvar cider-repl-history-previous-overlay nil
+  "Previous overlay within *cider-repl-history* buffer.")
+
+
+(defun cider-repl-history-get-history ()
+  "Function to retrieve history from the REPL buffer."
+  (if cider-repl-history-repl-buffer
+      (buffer-local-value
+       'cider-repl-input-history
+       cider-repl-history-repl-buffer)
+    (error "Variable `cider-repl-history-repl-buffer' not bound to a buffer")))
+
+(defun cider-repl-history-resize-window ()
+  "If variable `cider-repl-history-resize-window' is non-nil, resize the *cider-repl-history* window."
+  (when cider-repl-history-resize-window
+    (apply #'fit-window-to-buffer (selected-window)
+           (if (consp cider-repl-history-resize-window)
+               (list (car cider-repl-history-resize-window)
+                     (or (cdr cider-repl-history-resize-window)
+                         window-min-height))
+             (list nil window-min-height)))))
+
+(defun cider-repl-history-read-regexp (msg use-default-p)
+  "Get a regular expression from the user, prompting with MSG; previous entry is default if USE-DEFAULT-P."
+  (let* ((default (car regexp-history))
+         (prompt (if (and default use-default-p)
+                     (format "%s for regexp (default `%s'): "
+                             msg
+                             default)
+                   (format "%s (regexp): " msg)))
+         (input
+          (read-from-minibuffer prompt nil nil nil 'regexp-history
+                                (if use-default-p nil default))))
+    (if (equal input "")
+        (if use-default-p default nil)
+      input)))
+
+(defun cider-repl-history-clear-preview ()
+  "Clear the preview, if one is present."
+  (interactive)
+  (when cider-repl-history-preview-overlay
+    (cl-assert (overlayp cider-repl-history-preview-overlay))
+    (delete-overlay cider-repl-history-preview-overlay)))
+
+(defun cider-repl-history-cleanup-on-exit ()
+  "Function called when the user is finished with `cider-repl-history'.
+This function performs any cleanup that is required when the user
+has finished interacting with the *cider-repl-history* buffer.  For now
+the only cleanup performed is to remove the preview overlay, if
+it's turned on."
+  (cider-repl-history-clear-preview))
+
+(defun cider-repl-history-quit ()
+  "Take the action specified by `cider-repl-history-quit-action'."
+  (interactive)
+  (cider-repl-history-cleanup-on-exit)
+  (pcase cider-repl-history-quit-action
+    (`delete-and-restore
+     (quit-restore-window (selected-window) 'kill))
+    (`quit-window
+     (quit-window))
+    (`kill-and-delete-window
+     (kill-buffer (current-buffer))
+     (unless (= (count-windows) 1)
+       (delete-window)))
+    (`bury-and-delete-window
+     (bury-buffer)
+     (unless (= (count-windows) 1)
+       (delete-window)))
+    (_
+     (funcall cider-repl-history-quit-action))))
+
+(defun cider-repl-history-preview-overlay-setup (orig-buf)
+  "Setup the preview overlay in ORIG-BUF."
+  (when cider-repl-history-show-preview
+    (with-current-buffer orig-buf
+      (let* ((will-replace (region-active-p))
+             (start (if will-replace
+                        (min (point) (mark))
+                      (point)))
+             (end (if will-replace
+                      (max (point) (mark))
+                    (point))))
+        (cider-repl-history-clear-preview)
+        (setq cider-repl-history-preview-overlay
+              (make-overlay start end orig-buf))
+        (overlay-put cider-repl-history-preview-overlay
+                     'invisible t)))))
+
+(defun cider-repl-history-highlight-inserted (start end)
+  "Insert the text between START and END."
+  (pcase cider-repl-history-highlight-inserted-item
+    ((or `pulse `t)
+     (let ((pulse-delay .05) (pulse-iterations 10))
+       (with-no-warnings
+         (pulse-momentary-highlight-region
+          start end cider-repl-history-inserted-item-face))))
+    (`solid
+     (let ((o (make-overlay start end)))
+       (overlay-put o 'face cider-repl-history-inserted-item-face)
+       (sit-for 0.5)
+       (delete-overlay o)))))
+
+(defun cider-repl-history-insert-and-highlight (str)
+  "Helper function to insert STR at point, highlighting it if appropriate."
+  (let ((before-insert (point)))
+    (let (deactivate-mark)
+      (insert-for-yank str))
+    (cider-repl-history-highlight-inserted
+     before-insert
+     (point))))
+
+(defun cider-repl-history-target-overlay-at (position &optional no-error)
+  "Return overlay at POSITION that has property `cider-repl-history-target'.
+If no such overlay, raise an error unless NO-ERROR is true, in which
+case retun nil."
+  (let ((ovs  (overlays-at (point))))
+    (catch 'cider-repl-history-target-overlay-at
+      (dolist (ov ovs)
+        (when (overlay-get ov 'cider-repl-history-target)
+          (throw 'cider-repl-history-target-overlay-at ov)))
+      (unless no-error
+        (error "No CIDER history item here")))))
+
+(defun cider-repl-history-current-string (pt &optional no-error)
+  "Find the string to insert into the REPL by looking for the overlay at PT; might error unless NO-ERROR set."
+  (let ((o (cider-repl-history-target-overlay-at pt t)))
+    (if o
+        (overlay-get o 'cider-repl-history-target)
+      (unless no-error
+        (error "No CIDER history item in this buffer")))))
+
+(defun cider-repl-history-do-insert (buf pt)
+  "Helper function to insert text from BUF at PT into the REPL buffer and kill *cider-repl-history*."
+  ;; Note: as mentioned at the top, this file is based on browse-kill-ring,
+  ;; which has numerous insertion options.  The functionality of
+  ;; browse-kill-ring allows users to insert at point, and move point to the end
+  ;; of the inserted text; or insert at the beginning or end of the buffer,
+  ;; while leaving point alone.  And each of these had the option of leaving the
+  ;; history buffer in place, or getting rid of it.  That was appropriate for a
+  ;; generic paste tool, but for inserting a previous command into an
+  ;; interpreter, I felt the only useful option would be inserting it at the end
+  ;; and quitting the history buffer, so that is all that's provided.
+  (let ((str (cider-repl-history-current-string pt)))
+    (cider-repl-history-quit)
+    (with-selected-window cider-repl-history-repl-window
+      (with-current-buffer cider-repl-history-repl-buffer
+        (let ((max (point-max)))
+          (if (= max (point))
+              (cider-repl-history-insert-and-highlight str)
+            (save-excursion
+              (goto-char max)
+              (cider-repl-history-insert-and-highlight str))))))))
+
+(defun cider-repl-history-insert-and-quit ()
+  "Insert the item into the REPL buffer, and close *cider-repl-history*.
+
+The text is always inserted at the very bottom of the REPL buffer.  If your
+cursor is already at the bottom, it is advanced to the end of the inserted
+text.  If your cursor is somewhere else, the cursor is not moved, but the
+text is still inserted at the end."
+  (interactive)
+  (cider-repl-history-do-insert (current-buffer) (point)))
+
+(defun cider-repl-history-mouse-insert (e)
+  "Insert the item at E into the REPL buffer, and close *cider-repl-history*.
+
+The text is always inserted at the very bottom of the REPL buffer.  If your
+cursor is already at the bottom, it is advanced to the end of the inserted
+text.  If your cursor is somewhere else, the cursor is not moved, but the
+text is still inserted at the end."
+  (interactive "e")
+  (let* ((data (save-excursion
+                 (mouse-set-point e)
+                 (cons (current-buffer) (point))))
+         (buf (car data))
+         (pt (cdr data)))
+    (cider-repl-history-do-insert buf pt)))
+
+(defun cider-repl-history-clear-highlighed-entry ()
+  "Clear the highlighted entry, when one exists."
+  (when cider-repl-history-previous-overlay
+    (cl-assert (overlayp cider-repl-history-previous-overlay)
+               nil "not an overlay")
+    (overlay-put cider-repl-history-previous-overlay 'face nil)))
+
+(defun cider-repl-history-update-highlighed-entry ()
+  "Update highlighted entry, when feature is turned on."
+  (when cider-repl-history-highlight-current-entry
+    (if-let* ((current-overlay (cider-repl-history-target-overlay-at (point) t)))
+        (unless (equal cider-repl-history-previous-overlay current-overlay)
+          ;; We've changed overlay.  Clear current highlighting,
+          ;; and highlight the new overlay.
+          (cl-assert (overlay-get current-overlay 'cider-repl-history-target) t)
+          (cider-repl-history-clear-highlighed-entry)
+          (setq cider-repl-history-previous-overlay current-overlay)
+          (overlay-put current-overlay 'face
+                       cider-repl-history-current-entry-face))
+      ;; No overlay at point.  Just clear all current highlighting.
+      (cider-repl-history-clear-highlighed-entry))))
+
+(defun cider-repl-history-forward (&optional arg)
+  "Move forward by ARG command history entries."
+  (interactive "p")
+  (beginning-of-line)
+  (while (not (zerop arg))
+    (let ((o (cider-repl-history-target-overlay-at (point) t)))
+      (cond
+       ((>= arg 0)
+        (setq arg (1- arg))
+        ;; We're on a cider-repl-history overlay, skip to the end of it.
+        (when o
+          (goto-char (overlay-end o))
+          (setq o nil))
+        (while (not (or o (eobp)))
+          (goto-char (next-overlay-change (point)))
+          (setq o (cider-repl-history-target-overlay-at (point) t))))
+       (t
+        (setq arg (1+ arg))
+        (when o
+          (goto-char (overlay-start o))
+          (setq o nil))
+        (while (not (or o (bobp)))
+          (goto-char (previous-overlay-change (point)))
+          (setq o (cider-repl-history-target-overlay-at (point) t)))))))
+  (when cider-repl-history-recenter
+    (recenter 1)))
+
+(defun cider-repl-history-previous (&optional arg)
+  "Move backward by ARG command history entries."
+  (interactive "p")
+  (cider-repl-history-forward (- arg)))
+
+(defun cider-repl-history-search-forward (regexp &optional backwards)
+  "Move to the next command history entry matching REGEXP from point.
+If optional arg BACKWARDS is non-nil, move to the previous matching
+entry."
+  (interactive
+   (list (cider-repl-history-read-regexp "Search forward" t)
+         current-prefix-arg))
+  (let ((orig (point)))
+    (cider-repl-history-forward (if backwards -1 1))
+    (let ((over (cider-repl-history-target-overlay-at (point) t)))
+      (while (and over
+                  (not (if backwards (bobp) (eobp)))
+                  (not (string-match regexp
+                                     (overlay-get over
+                                                  'cider-repl-history-target))))
+        (cider-repl-history-forward (if backwards -1 1))
+        (setq over (cider-repl-history-target-overlay-at (point) t)))
+      (unless (and over
+                   (string-match regexp
+                                 (overlay-get over
+                                              'cider-repl-history-target)))
+        (goto-char orig)
+        (message "No more command history entries matching %s" regexp)))))
+
+(defun cider-repl-history-search-backward (regexp)
+  "Move to the previous command history entry matching REGEXP from point."
+  (interactive
+   (list (cider-repl-history-read-regexp "Search backward" t)))
+  (cider-repl-history-search-forward regexp t))
+
+(defun cider-repl-history-elide (str)
+  "If STR is too long, abbreviate it with an ellipsis; otherwise, return it unchanged."
+  (if (and cider-repl-history-maximum-display-length
+           (> (length str)
+              cider-repl-history-maximum-display-length))
+      (concat (substring str 0 (- cider-repl-history-maximum-display-length 3))
+              (propertize "..." 'cider-repl-history-extra t))
+    str))
+
+(defmacro cider-repl-history-add-overlays-for (item &rest body)
+  "Add overlays for ITEM, and execute BODY."
+  (let ((beg (cl-gensym "cider-repl-history-add-overlays-"))
+        (end (cl-gensym "cider-repl-history-add-overlays-")))
+    `(let ((,beg (point))
+           (,end
+            (progn
+              ,@body
+              (point))))
+       (let ((o (make-overlay ,beg ,end)))
+         (overlay-put o 'cider-repl-history-target ,item)
+         (overlay-put o 'mouse-face 'highlight)))))
+
+(defun cider-repl-history-insert-as-separated (items)
+  "Insert ITEMS into the current buffer, with separators between items."
+  (while items
+    (let* ((origitem (car items))
+           (item (cider-repl-history-elide origitem))
+           (len (length item)))
+      (cider-repl-history-add-overlays-for origitem (insert item))
+      ;; When the command history has items with read-only text property at
+      ;; **the end of** string, cider-repl-history-setup fails with error
+      ;; `Text is read-only'.  So inhibit-read-only here.
+      ;; See http://bugs.debian.org/225082
+      (let ((inhibit-read-only t))
+        (insert "\n")
+        (when (cdr items)
+          (insert (propertize cider-repl-history-separator
+                              'cider-repl-history-extra t
+                              'cider-repl-history-separator t))
+          (insert "\n"))))
+    (setq items (cdr items))))
+
+(defun cider-repl-history-insert-as-one-line (items)
+  "Insert ITEMS into the current buffer, formatting each item as a single line.
+
+An explicit newline character will replace newlines so that the text retains its
+spacing when it's actually inserted into the REPL buffer."
+  (dolist (item items)
+    (cider-repl-history-add-overlays-for
+     item
+     (let* ((item (cider-repl-history-elide item))
+            (len (length item))
+            (start 0)
+            (newl (propertize "\\n" 'cider-repl-history-extra t)))
+       (while (and (< start len)
+                   (string-match "\n" item start))
+         (insert (substring item start (match-beginning 0))
+                 newl)
+         (setq start (match-end 0)))
+       (insert (substring item start len))))
+    (insert "\n")))
+
+(defun cider-repl-history-preview-update-text (preview-text)
+  "Update `cider-repl-history-preview-overlay' to show `PREVIEW-TEXT`."
+  ;; If preview-text is nil, replacement should be nil too.
+  (cl-assert (overlayp cider-repl-history-preview-overlay))
+  (let ((replacement (when preview-text
+                       (propertize preview-text 'face 'highlight))))
+    (overlay-put cider-repl-history-preview-overlay
+                 'before-string replacement)))
+
+(defun cider-repl-history-preview-update-by-position (&optional pt)
+  "Update `cider-repl-history-preview-overlay' to match item at PT.
+
+This function is called whenever the selection in the *cider-repl-history*
+buffer is adjusted, the `cider-repl-history-preview-overlay'
+is udpated to preview the text of the selection at PT (or the
+current point if not specified)."
+  (let ((new-text (cider-repl-history-current-string
+                   (or pt (point)) t)))
+    (cider-repl-history-preview-update-text new-text)))
+
+(defun cider-repl-history-undo-other-window ()
+  "Undo the most recent change in the other window's buffer.
+You most likely want to use this command for undoing an insertion of
+text from the *cider-repl-history* buffer."
+  (interactive)
+  (with-current-buffer cider-repl-history-repl-buffer
+    (undo)))
+
+(defun cider-repl-history-setup (repl-win repl-buf history-buf &optional regexp)
+  "Setup: REPL-WIN and REPL-BUF are where to insert commands, HISTORY-BUF is the history, and optional arg REGEXP is a filter."
+  (cider-repl-history-preview-overlay-setup repl-buf)
+  (with-current-buffer history-buf
+    (unwind-protect
+        (progn
+          (cider-repl-history-mode)
+          (setq buffer-read-only nil)
+          (when (eq 'one-line cider-repl-history-display-style)
+            (setq truncate-lines t))
+          (let ((inhibit-read-only t))
+            (erase-buffer))
+          (setq cider-repl-history-repl-buffer repl-buf)
+          (setq cider-repl-history-repl-window repl-win)
+          (let* ((cider-repl-history-maximum-display-length
+                  (if (and cider-repl-history-maximum-display-length
+                           (<= cider-repl-history-maximum-display-length 3))
+                      4
+                    cider-repl-history-maximum-display-length))
+                 (cider-command-history (cider-repl-history-get-history))
+                 (items (mapcar
+                         (if cider-repl-history-text-properties
+                             #'copy-sequence
+                           #'substring-no-properties)
+                         cider-command-history)))
+            (unless cider-repl-history-display-duplicates
+              ;; display highest or lowest duplicate.
+              ;; if `cider-repl-history-display-duplicate-highest' is t,
+              ;; display highest (most recent) duplicate.
+              (cl-delete-duplicates
+               items
+               :test #'equal
+               :from-end cider-repl-history-display-duplicate-highest))
+            (when (stringp regexp)
+              (setq items (delq nil
+                                (mapcar
+                                 #'(lambda (item)
+                                     (when (string-match regexp item)
+                                       item))
+                                 items))))
+            (funcall (or (cdr (assq cider-repl-history-display-style
+                                    cider-repl-history-display-styles))
+                         (error "Invalid `cider-repl-history-display-style': %s"
+                                cider-repl-history-display-style))
+                     items)
+            (when cider-repl-history-show-preview
+              (cider-repl-history-preview-update-by-position (point-min))
+              ;; Local post-command-hook, only happens in *cider-repl-history*
+              (add-hook 'post-command-hook
+                        'cider-repl-history-preview-update-by-position
+                        nil t)
+              (add-hook 'kill-buffer-hook
+                        'cider-repl-history-cleanup-on-exit
+                        nil t))
+            (when cider-repl-history-highlight-current-entry
+              (add-hook 'post-command-hook
+                        'cider-repl-history-update-highlighed-entry
+                        nil t))
+            (message
+             (let ((entry (if (= 1 (length cider-command-history))
+                              "entry"
+                            "entries")))
+               (concat
+                (if (and (not regexp)
+                         cider-repl-history-display-duplicates)
+                    (format "%s %s in the command history."
+                            (length cider-command-history) entry)
+                  (format "%s (of %s) %s in the command history shown."
+                          (length items) (length cider-command-history) entry))
+                (substitute-command-keys
+                 (concat "  Type \\[cider-repl-history-quit] to quit.  "
+                         "\\[describe-mode] for help.")))))
+            (set-buffer-modified-p nil)
+            (goto-char (point-min))
+            (cider-repl-history-forward 0)
+            (setq mode-name (if regexp
+                                (concat "History [" regexp "]")
+                              "History"))
+            (run-hooks 'cider-repl-history-hook)))
+      (setq buffer-read-only t))))
+
+(defun cider-repl-history-update ()
+  "Update the history buffer to reflect the latest state of the command history."
+  (interactive)
+  (cl-assert (eq major-mode 'cider-repl-history-mode))
+  (cider-repl-history-setup cider-repl-history-repl-window
+                            cider-repl-history-repl-buffer
+                            (current-buffer))
+  (cider-repl-history-resize-window))
+
+(defun cider-repl-history-occur (regexp)
+  "Display all command history entries matching REGEXP."
+  (interactive
+   (list (cider-repl-history-read-regexp
+          "Display command history entries matching" nil)))
+  (cl-assert (eq major-mode 'cider-repl-history-mode))
+  (cider-repl-history-setup cider-repl-history-repl-window
+                            cider-repl-history-repl-buffer
+                            (current-buffer)
+                            regexp)
+  (cider-repl-history-resize-window))
+
+(put 'cider-repl-history-mode 'mode-class 'special)
+(define-derived-mode cider-repl-history-mode clojure-mode "History"
+  "Major mode for browsing the entries in the command input history.
+
+\\{cider-repl-history-mode-map}"
+  (setq-local sesman-system 'CIDER)
+  (define-key cider-repl-history-mode-map (kbd "n") 'cider-repl-history-forward)
+  (define-key cider-repl-history-mode-map (kbd "p") 'cider-repl-history-previous)
+  (define-key cider-repl-history-mode-map (kbd "SPC") 'cider-repl-history-insert-and-quit)
+  (define-key cider-repl-history-mode-map (kbd "RET") 'cider-repl-history-insert-and-quit)
+  (define-key cider-repl-history-mode-map [(mouse-2)] 'cider-repl-history-mouse-insert)
+  (define-key cider-repl-history-mode-map (kbd "l") 'cider-repl-history-occur)
+  (define-key cider-repl-history-mode-map (kbd "s") 'cider-repl-history-search-forward)
+  (define-key cider-repl-history-mode-map (kbd "r") 'cider-repl-history-search-backward)
+  (define-key cider-repl-history-mode-map (kbd "g") 'cider-repl-history-update)
+  (define-key cider-repl-history-mode-map (kbd "q") 'cider-repl-history-quit)
+  (define-key cider-repl-history-mode-map (kbd "U") 'cider-repl-history-undo-other-window)
+  (define-key cider-repl-history-mode-map (kbd "?") 'describe-mode)
+  (define-key cider-repl-history-mode-map (kbd "h") 'describe-mode))
+
+;;;###autoload
+(defun cider-repl-history ()
+  "Display items in the CIDER command history in another buffer."
+  (interactive)
+  (when (eq major-mode 'cider-repl-history-mode)
+    (user-error "Already viewing the CIDER command history"))
+
+  (let* ((repl-win (selected-window))
+         (repl-buf (window-buffer repl-win))
+         (buf (get-buffer-create cider-repl-history-buffer)))
+    (cider-repl-history-setup repl-win repl-buf buf)
+    (pop-to-buffer buf)
+    (cider-repl-history-resize-window)))
+
+(provide 'cider-repl-history)
+
+;;; cider-repl-history.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-repl-history.elc b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-repl-history.elc
new file mode 100644
index 0000000000..9d3245245f
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-repl-history.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-repl.el b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-repl.el
new file mode 100644
index 0000000000..0a3a4c5e19
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-repl.el
@@ -0,0 +1,1747 @@
+;;; cider-repl.el --- CIDER REPL mode interactions -*- lexical-binding: t -*-
+
+;; Copyright © 2012-2013 Tim King, Phil Hagelberg, Bozhidar Batsov
+;; Copyright © 2013-2018 Bozhidar Batsov, Artur Malabarba and CIDER contributors
+;;
+;; Author: Tim King <kingtim@gmail.com>
+;;         Phil Hagelberg <technomancy@gmail.com>
+;;         Bozhidar Batsov <bozhidar@batsov.com>
+;;         Artur Malabarba <bruce.connor.am@gmail.com>
+;;         Hugo Duncan <hugo@hugoduncan.org>
+;;         Steve Purcell <steve@sanityinc.com>
+;;         Reid McKenzie <me@arrdem.com>
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;; This file is not part of GNU Emacs.
+
+;;; Commentary:
+
+;; This functionality concerns `cider-repl-mode' and REPL interaction.  For
+;; REPL/connection life-cycle management see cider-connection.el.
+
+;;; Code:
+
+(require 'cider-client)
+(require 'cider-doc)
+(require 'cider-test)
+(require 'cider-eldoc) ; for cider-eldoc-setup
+(require 'cider-common)
+(require 'subr-x)
+(require 'cider-compat)
+(require 'cider-util)
+(require 'cider-resolve)
+
+(require 'clojure-mode)
+(require 'easymenu)
+(require 'cl-lib)
+(require 'sesman)
+
+(eval-when-compile
+  (defvar paredit-version)
+  (defvar paredit-space-for-delimiter-predicates))
+
+
+(defgroup cider-repl nil
+  "Interaction with the REPL."
+  :prefix "cider-repl-"
+  :group 'cider)
+
+(defface cider-repl-prompt-face
+  '((t (:inherit font-lock-keyword-face)))
+  "Face for the prompt in the REPL buffer."
+  :group 'cider-repl)
+
+(defface cider-repl-stdout-face
+  '((t (:inherit font-lock-string-face)))
+  "Face for STDOUT output in the REPL buffer."
+  :group 'cider-repl)
+
+(defface cider-repl-stderr-face
+  '((t (:inherit font-lock-warning-face)))
+  "Face for STDERR output in the REPL buffer."
+  :group 'cider-repl
+  :package-version '(cider . "0.6.0"))
+
+(defface cider-repl-input-face
+  '((t (:bold t)))
+  "Face for previous input in the REPL buffer."
+  :group 'cider-repl)
+
+(defface cider-repl-result-face
+  '((t ()))
+  "Face for the result of an evaluation in the REPL buffer."
+  :group 'cider-repl)
+
+(defcustom cider-repl-pop-to-buffer-on-connect t
+  "Controls whether to pop to the REPL buffer on connect.
+
+When set to nil the buffer will only be created, and not displayed.  When
+set to `display-only' the buffer will be displayed, but it will not become
+focused.  Otherwise the buffer is displayed and focused."
+  :type '(choice (const :tag "Create the buffer, but don't display it" nil)
+                 (const :tag "Create and display the buffer, but don't focus it"
+                        display-only)
+                 (const :tag "Create, display, and focus the buffer" t))
+  :group 'cider-repl)
+
+(defcustom cider-repl-display-in-current-window nil
+  "Controls whether the REPL buffer is displayed in the current window."
+  :type 'boolean
+  :group 'cider-repl)
+
+(defcustom cider-repl-scroll-on-output t
+  "Controls whether the REPL buffer auto-scrolls on new output.
+
+When set to t (the default), if the REPL buffer contains more lines than the
+size of the window, the buffer is automatically re-centered upon completion
+of evaluating an expression, so that the bottom line of output is on the
+bottom line of the window.
+
+If this is set to nil, no re-centering takes place."
+  :type 'boolean
+  :group 'cider-repl
+  :package-version '(cider . "0.11.0"))
+
+(defcustom cider-repl-use-pretty-printing nil
+  "Control whether results in the REPL are pretty-printed or not.
+The `cider-toggle-pretty-printing' command can be used to interactively
+change the setting's value."
+  :type 'boolean
+  :group 'cider-repl)
+
+(defcustom cider-repl-pretty-print-width nil
+  "Control the width of pretty printing on the REPL.
+This sets the wrap point for pretty printing on the repl.  If nil, it
+defaults to the variable `fill-column'."
+  :type '(restricted-sexp  :match-alternatives
+                           (integerp 'nil))
+  :group 'cider-repl
+  :package-version '(cider . "0.15.0"))
+
+(defcustom cider-repl-use-content-types t
+  "Control whether REPL results are presented using content-type information.
+The `cider-repl-toggle-content-types' command can be used to interactively
+change the setting's value."
+  :type 'boolean
+  :group 'cider-repl
+  :package-version '(cider . "0.17.0"))
+
+(defcustom cider-repl-auto-detect-type t
+  "Control whether to auto-detect the REPL type using track-state information.
+If you disable this you'll have to manually change the REPL type between
+Clojure and ClojureScript when invoking REPL type changing forms.
+Use `cider-set-repl-type' to manually change the REPL type."
+  :type 'boolean
+  :group 'cider-repl
+  :safe #'booleanp
+  :package-version '(cider . "0.18.0"))
+
+(defcustom cider-repl-use-clojure-font-lock t
+  "Non-nil means to use Clojure mode font-locking for input and result.
+Nil means that `cider-repl-input-face' and `cider-repl-result-face'
+will be used."
+  :type 'boolean
+  :group 'cider-repl
+  :package-version '(cider . "0.10.0"))
+
+(defcustom cider-repl-result-prefix ""
+  "The prefix displayed in the REPL before a result value.
+By default there's no prefix, but you can specify something
+like \"=>\" if want results to stand out more."
+  :type 'string
+  :group 'cider
+  :package-version '(cider . "0.5.0"))
+
+(defcustom cider-repl-tab-command 'cider-repl-indent-and-complete-symbol
+  "Select the command to be invoked by the TAB key.
+The default option is `cider-repl-indent-and-complete-symbol'.  If
+you'd like to use the default Emacs behavior use
+`indent-for-tab-command'."
+  :type 'symbol
+  :group 'cider-repl)
+
+(defcustom cider-repl-print-length 100
+  "Initial value for *print-length* set during REPL start."
+  :type 'integer
+  :group 'cider
+  :package-version '(cider . "0.17.0"))
+
+(defcustom cider-repl-print-level nil
+  "Initial value for *print-level* set during REPL start."
+  :type 'integer
+  :group 'cider
+  :package-version '(cider . "0.17.0"))
+
+(defcustom cider-repl-display-help-banner t
+  "When non-nil a bit of help text will be displayed on REPL start."
+  :type 'boolean
+  :group 'cider-repl
+  :package-version '(cider . "0.11.0"))
+
+
+;;;; REPL buffer local variables
+(defvar-local cider-repl-input-start-mark nil)
+
+(defvar-local cider-repl-prompt-start-mark nil)
+
+(defvar-local cider-repl-old-input-counter 0
+  "Counter used to generate unique `cider-old-input' properties.
+This property value must be unique to avoid having adjacent inputs be
+joined together.")
+
+(defvar-local cider-repl-input-history '()
+  "History list of strings read from the REPL buffer.")
+
+(defvar-local cider-repl-input-history-items-added 0
+  "Variable counting the items added in the current session.")
+
+(defvar-local cider-repl-output-start nil
+  "Marker for the start of output.
+Currently its only purpose is to facilitate `cider-repl-clear-buffer'.")
+
+(defvar-local cider-repl-output-end nil
+  "Marker for the end of output.
+Currently its only purpose is to facilitate `cider-repl-clear-buffer'.")
+
+(defun cider-repl-tab ()
+  "Invoked on TAB keystrokes in `cider-repl-mode' buffers."
+  (interactive)
+  (funcall cider-repl-tab-command))
+
+(defun cider-repl-reset-markers ()
+  "Reset all REPL markers."
+  (dolist (markname '(cider-repl-output-start
+                      cider-repl-output-end
+                      cider-repl-prompt-start-mark
+                      cider-repl-input-start-mark))
+    (set markname (make-marker))
+    (set-marker (symbol-value markname) (point))))
+
+
+;;; REPL init
+
+(defvar-local cider-repl-ns-cache nil
+  "A dict holding information about all currently loaded namespaces.
+This cache is stored in the connection buffer.")
+
+(defvar cider-mode)
+(declare-function cider-refresh-dynamic-font-lock "cider-mode")
+
+(defun cider-repl--state-handler (response)
+  "Handle server state contained in RESPONSE."
+  (with-demoted-errors "Error in `cider-repl--state-handler': %s"
+    (when (member "state" (nrepl-dict-get response "status"))
+      (nrepl-dbind-response response (repl-type changed-namespaces)
+        (when (and repl-type cider-repl-auto-detect-type)
+          (cider-set-repl-type repl-type))
+        (unless (nrepl-dict-empty-p changed-namespaces)
+          (setq cider-repl-ns-cache (nrepl-dict-merge cider-repl-ns-cache changed-namespaces))
+          (dolist (b (buffer-list))
+            (with-current-buffer b
+              ;; Metadata changed, so signatures may have changed too.
+              (setq cider-eldoc-last-symbol nil)
+              (when (or cider-mode (derived-mode-p 'cider-repl-mode))
+                (when-let* ((ns-dict (or (nrepl-dict-get changed-namespaces (cider-current-ns))
+                                         (let ((ns-dict (cider-resolve--get-in (cider-current-ns))))
+                                           (when (seq-find (lambda (ns) (nrepl-dict-get changed-namespaces ns))
+                                                           (nrepl-dict-get ns-dict "aliases"))
+                                             ns-dict)))))
+                  (cider-refresh-dynamic-font-lock ns-dict))))))))))
+
+(declare-function cider-set-buffer-ns "cider-mode")
+(defun cider-repl-set-initial-ns (buffer)
+  "Require standard REPL util functions and set the ns of the REPL's BUFFER.
+Namespace is \"user\" by default, but can be overridden in apps like
+lein (:init-ns).  Both of these operations need to be done as a sync
+request at the beginning of the session.  Bundling them together for
+efficiency."
+  ;; we don't want to get a timeout during init
+  (let ((nrepl-sync-request-timeout nil))
+    (with-current-buffer buffer
+      (let* ((response (nrepl-send-sync-request
+                        (lax-plist-put (nrepl--eval-request "(str *ns*)")
+                                       "inhibit-cider-middleware" "true")
+                        (cider-current-repl)))
+             (initial-ns (or (read (nrepl-dict-get response "value"))
+                             "user")))
+        (cider-set-buffer-ns initial-ns)))))
+
+(defun cider-repl-require-repl-utils ()
+  "Require standard REPL util functions into the current REPL."
+  (interactive)
+  (nrepl-send-sync-request
+   (lax-plist-put
+    (nrepl--eval-request
+     "(when (clojure.core/resolve 'clojure.main/repl-requires)
+       (clojure.core/map clojure.core/require clojure.main/repl-requires))")
+    "inhibit-cider-middleware" "true")
+   (cider-current-repl)))
+
+(defun cider-repl--build-config-expression ()
+  "Build the initial config expression."
+  (when (or cider-repl-print-length cider-repl-print-level)
+    (concat
+     "(do"
+     (when cider-repl-print-length (format " (set! *print-length* %d)" cider-repl-print-length))
+     (when cider-repl-print-level (format " (set! *print-level* %d)" cider-repl-print-level))
+     ")")))
+
+(defun cider-repl-set-config ()
+  "Set an inititial REPL configuration."
+  (interactive)
+  (when-let* ((config-expression (cider-repl--build-config-expression)))
+    (nrepl-send-sync-request
+     (lax-plist-put
+      (nrepl--eval-request config-expression)
+      "inhibit-cider-middleware" "true")
+     (cider-current-repl))))
+
+(defun cider-repl-init (buffer &optional no-banner)
+  "Initialize the REPL in BUFFER.
+BUFFER must be a REPL buffer with `cider-repl-mode' and a running
+client process connection.  Unless NO-BANNER is non-nil, insert a banner."
+  (when cider-repl-display-in-current-window
+    (add-to-list 'same-window-buffer-names (buffer-name buffer)))
+  (pcase cider-repl-pop-to-buffer-on-connect
+    (`display-only (display-buffer buffer))
+    ((pred identity) (pop-to-buffer buffer)))
+  (cider-repl-set-initial-ns buffer)
+  (cider-repl-require-repl-utils)
+  (cider-repl-set-config)
+  (unless no-banner
+    (cider-repl--insert-banner-and-prompt buffer))
+  buffer)
+
+(defun cider-repl--insert-banner-and-prompt (buffer)
+  "Insert REPL banner and REPL prompt in BUFFER."
+  (with-current-buffer buffer
+    (when (zerop (buffer-size))
+      (insert (propertize (cider-repl--banner) 'font-lock-face 'font-lock-comment-face))
+      (when cider-repl-display-help-banner
+        (insert (propertize (cider-repl--help-banner) 'font-lock-face 'font-lock-comment-face))))
+    (goto-char (point-max))
+    (cider-repl--mark-output-start)
+    (cider-repl--mark-input-start)
+    (cider-repl--insert-prompt cider-buffer-ns)))
+
+(defun cider-repl--banner ()
+  "Generate the welcome REPL buffer banner."
+  (format ";; Connected to nREPL server - nrepl://%s:%s
+;; CIDER %s, nREPL %s
+;; Clojure %s, Java %s
+;;     Docs: (doc function-name)
+;;           (find-doc part-of-name)
+;;   Source: (source function-name)
+;;  Javadoc: (javadoc java-object-or-class)
+;;     Exit: <C-c C-q>
+;;  Results: Stored in vars *1, *2, *3, an exception in *e;"
+          (plist-get nrepl-endpoint :host)
+          (plist-get nrepl-endpoint :port)
+          (cider--version)
+          (cider--nrepl-version)
+          (cider--clojure-version)
+          (cider--java-version)))
+
+(defun cider-repl--help-banner ()
+  "Generate the help banner."
+  (substitute-command-keys
+   "\n;; ======================================================================
+;; If you're new to CIDER it is highly recommended to go through its
+;; manual first. Type <M-x cider-view-manual> to view it.
+;; In case you're seeing any warnings you should consult the manual's
+;; \"Troubleshooting\" section.
+;;
+;; Here are few tips to get you started:
+;;
+;; * Press <\\[describe-mode]> to see a list of the keybindings available (this
+;;   will work in every Emacs buffer)
+;; * Press <\\[cider-repl-handle-shortcut]> to quickly invoke some REPL command
+;; * Press <\\[cider-switch-to-last-clojure-buffer]> to switch between the REPL and a Clojure file
+;; * Press <\\[cider-find-var]> to jump to the source of something (e.g. a var, a
+;;   Java method)
+;; * Press <\\[cider-doc]> to view the documentation for something (e.g.
+;;   a var, a Java method)
+;; * Enable `eldoc-mode' to display function & method signatures in the minibuffer.
+;; * Print CIDER's refcard and keep it close to your keyboard.
+;;
+;; CIDER is super customizable - try <M-x customize-group cider> to
+;; get a feel for this. If you're thirsty for knowledge you should try
+;; <M-x cider-drink-a-sip>.
+;;
+;; If you think you've encountered a bug (or have some suggestions for
+;; improvements) use <M-x cider-report-bug> to report it.
+;;
+;; Above all else - don't panic! In case of an emergency - procure
+;; some (hard) cider and enjoy it responsibly!
+;;
+;; You can remove this message with the <M-x cider-repl-clear-help-banner> command.
+;; You can disable it from appearing on start by setting
+;; `cider-repl-display-help-banner' to nil.
+;; ======================================================================
+"))
+
+
+;;; REPL interaction
+
+(defun cider-repl--in-input-area-p ()
+  "Return t if in input area."
+  (<= cider-repl-input-start-mark (point)))
+
+(defun cider-repl--current-input (&optional until-point-p)
+  "Return the current input as string.
+The input is the region from after the last prompt to the end of
+buffer.  If UNTIL-POINT-P is non-nil, the input is until the current
+point."
+  (buffer-substring-no-properties cider-repl-input-start-mark
+                                  (if until-point-p
+                                      (point)
+                                    (point-max))))
+
+(defun cider-repl-previous-prompt ()
+  "Move backward to the previous prompt."
+  (interactive)
+  (cider-repl--find-prompt t))
+
+(defun cider-repl-next-prompt ()
+  "Move forward to the next prompt."
+  (interactive)
+  (cider-repl--find-prompt))
+
+(defun cider-repl--find-prompt (&optional backward)
+  "Find the next prompt.
+If BACKWARD is non-nil look backward."
+  (let ((origin (point))
+        (cider-repl-prompt-property 'field))
+    (while (progn
+             (cider-search-property-change cider-repl-prompt-property backward)
+             (not (or (cider-end-of-proprange-p cider-repl-prompt-property) (bobp) (eobp)))))
+    (unless (cider-end-of-proprange-p cider-repl-prompt-property)
+      (goto-char origin))))
+
+(defun cider-search-property-change (prop &optional backward)
+  "Search forward for a property change to PROP.
+If BACKWARD is non-nil search backward."
+  (cond (backward
+         (goto-char (previous-single-char-property-change (point) prop)))
+        (t
+         (goto-char (next-single-char-property-change (point) prop)))))
+
+(defun cider-end-of-proprange-p (property)
+  "Return t if at the the end of a property range for PROPERTY."
+  (and (get-char-property (max (point-min) (1- (point))) property)
+       (not (get-char-property (point) property))))
+
+(defun cider-repl--mark-input-start ()
+  "Mark the input start."
+  (set-marker cider-repl-input-start-mark (point) (current-buffer)))
+
+(defun cider-repl--mark-output-start ()
+  "Mark the output start."
+  (set-marker cider-repl-output-start (point))
+  (set-marker cider-repl-output-end (point)))
+
+(defun cider-repl-mode-beginning-of-defun (&optional arg)
+  "Move to the beginning of defun.
+If given a negative value of ARG, move to the end of defun."
+  (if (and arg (< arg 0))
+      (cider-repl-mode-end-of-defun (- arg))
+    (dotimes (_ (or arg 1))
+      (cider-repl-previous-prompt))))
+
+(defun cider-repl-mode-end-of-defun (&optional arg)
+  "Move to the end of defun.
+If given a negative value of ARG, move to the beginning of defun."
+  (if (and arg (< arg 0))
+      (cider-repl-mode-beginning-of-defun (- arg))
+    (dotimes (_ (or arg 1))
+      (cider-repl-next-prompt))))
+
+(defun cider-repl-beginning-of-defun ()
+  "Move to beginning of defun."
+  (interactive)
+  ;; We call `beginning-of-defun' if we're at the start of a prompt
+  ;; already, to trigger `cider-repl-mode-beginning-of-defun' by means
+  ;; of the locally bound `beginning-of-defun-function', in order to
+  ;; jump to the start of the previous prompt.
+  (if (and (not (cider-repl--at-prompt-start-p))
+           (cider-repl--in-input-area-p))
+      (goto-char cider-repl-input-start-mark)
+    (beginning-of-defun)))
+
+(defun cider-repl-end-of-defun ()
+  "Move to end of defun."
+  (interactive)
+  ;; C.f. `cider-repl-beginning-of-defun'
+  (if (and (not (= (point) (point-max)))
+           (cider-repl--in-input-area-p))
+      (goto-char (point-max))
+    (end-of-defun)))
+
+(defun cider-repl-bol-mark ()
+  "Set the mark and go to the beginning of line or the prompt."
+  (interactive)
+  (unless mark-active
+    (set-mark (point)))
+  (move-beginning-of-line 1))
+
+(defun cider-repl--at-prompt-start-p ()
+  "Return t if point is at the start of prompt.
+This will not work on non-current prompts."
+  (= (point) cider-repl-input-start-mark))
+
+(defun cider-repl--show-maximum-output ()
+  "Put the end of the buffer at the bottom of the window."
+  (when (and cider-repl-scroll-on-output (eobp))
+    (let ((win (get-buffer-window (current-buffer) t)))
+      (when win
+        (with-selected-window win
+          (set-window-point win (point-max))
+          (recenter -1))))))
+
+(defmacro cider-save-marker (marker &rest body)
+  "Save MARKER and execute BODY."
+  (declare (debug t))
+  (let ((pos (make-symbol "pos")))
+    `(let ((,pos (marker-position ,marker)))
+       (prog1 (progn . ,body)
+         (set-marker ,marker ,pos)))))
+
+(put 'cider-save-marker 'lisp-indent-function 1)
+
+(defun cider-repl-prompt-default (namespace)
+  "Return a prompt string that mentions NAMESPACE."
+  (format "%s> " namespace))
+
+(defun cider-repl-prompt-abbreviated (namespace)
+  "Return a prompt string that abbreviates NAMESPACE."
+  (format "%s> " (cider-abbreviate-ns namespace)))
+
+(defun cider-repl-prompt-lastname (namespace)
+  "Return a prompt string with the last name in NAMESPACE."
+  (format "%s> " (cider-last-ns-segment namespace)))
+
+(defcustom cider-repl-prompt-function #'cider-repl-prompt-default
+  "A function that returns a prompt string.
+Takes one argument, a namespace name.
+For convenience, three functions are already provided for this purpose:
+`cider-repl-prompt-lastname', `cider-repl-prompt-abbreviated', and
+`cider-repl-prompt-default'"
+  :type '(choice (const :tag "Full namespace" cider-repl-prompt-default)
+                 (const :tag "Abbreviated namespace" cider-repl-prompt-abbreviated)
+                 (const :tag "Last name in namespace" cider-repl-prompt-lastname)
+                 (function :tag "Custom function"))
+  :group 'cider-repl
+  :package-version '(cider . "0.9.0"))
+
+(defun cider-repl--insert-prompt (namespace)
+  "Insert the prompt (before markers!), taking into account NAMESPACE.
+Set point after the prompt.
+Return the position of the prompt beginning."
+  (goto-char cider-repl-input-start-mark)
+  (cider-save-marker cider-repl-output-start
+    (cider-save-marker cider-repl-output-end
+      (unless (bolp) (insert-before-markers "\n"))
+      (let ((prompt-start (point))
+            (prompt (funcall cider-repl-prompt-function namespace)))
+        (cider-propertize-region
+            '(font-lock-face cider-repl-prompt-face read-only t intangible t
+                             field cider-repl-prompt
+                             rear-nonsticky (field read-only font-lock-face intangible))
+          (insert-before-markers prompt))
+        (set-marker cider-repl-prompt-start-mark prompt-start)
+        prompt-start))))
+
+(defun cider-repl--flush-ansi-color-context ()
+  "Flush ansi color context after printing.
+When there is a possible unfinished ansi control sequence,
+ `ansi-color-context` maintains this list."
+  (when (and ansi-color-context (stringp (cadr ansi-color-context)))
+    (insert-before-markers (cadr ansi-color-context))
+    (setq ansi-color-context nil)))
+
+(defvar-local cider-repl--ns-forms-plist nil
+  "Plist holding ns->ns-form mappings within each connection.")
+
+(defun cider-repl--ns-form-changed-p (ns-form connection)
+  "Return non-nil if NS-FORM for CONNECTION changed since last eval."
+  (when-let* ((ns (cider-ns-from-form ns-form)))
+    (not (string= ns-form
+                  (lax-plist-get
+                   (buffer-local-value 'cider-repl--ns-forms-plist connection)
+                   ns)))))
+
+(defvar cider-repl--root-ns-highlight-template "\\_<\\(%s\\)[^$/: \t\n()]+"
+  "Regexp used to highlight root ns in REPL buffers.")
+
+(defvar-local cider-repl--root-ns-regexp nil
+  "Cache of root ns regexp in REPLs.")
+
+(defvar-local cider-repl--ns-roots nil
+  "List holding all past root namespaces seen during interactive eval.")
+
+(defun cider-repl--cache-ns-form (ns-form connection)
+  "Given NS-FORM cache root ns in CONNECTION."
+  (with-current-buffer connection
+    (when-let* ((ns (cider-ns-from-form ns-form)))
+      ;; cache ns-form
+      (setq cider-repl--ns-forms-plist
+            (lax-plist-put cider-repl--ns-forms-plist ns ns-form))
+      ;; cache ns roots regexp
+      (when (string-match "\\([^.]+\\)" ns)
+        (let ((root (match-string-no-properties 1 ns)))
+          (unless (member root cider-repl--ns-roots)
+            (push root cider-repl--ns-roots)
+            (let ((roots (mapconcat
+                          ;; Replace _ or - with regexp pattern to accommodate "raw" namespaces
+                          (lambda (r) (replace-regexp-in-string "[_-]+" "[_-]+" r))
+                          cider-repl--ns-roots "\\|")))
+              (setq cider-repl--root-ns-regexp
+                    (format cider-repl--root-ns-highlight-template roots)))))))))
+
+(defvar cider-repl-spec-keywords-regexp
+  (concat
+   (regexp-opt '("In:" " val:"
+                 " at:" "fails at:"
+                 " spec:" "fails spec:"
+                 " predicate:" "fails predicate:"))
+   "\\|^"
+   (regexp-opt '(":clojure.spec.alpha/spec"
+                 ":clojure.spec.alpha/value")
+               "\\("))
+  "Regexp matching clojure.spec `explain` keywords.")
+
+(defun cider-repl-highlight-spec-keywords (string)
+  "Highlight clojure.spec `explain` keywords in STRING.
+Foreground of `clojure-keyword-face' is used for highlight."
+  (cider-add-face cider-repl-spec-keywords-regexp
+                  'clojure-keyword-face t nil string)
+  string)
+
+(defun cider-repl-highlight-current-project (string)
+  "Fontify project's root namespace to make stacktraces more readable.
+Foreground of `cider-stacktrace-ns-face' is used to propertize matched
+namespaces.  STRING is REPL's output."
+  (cider-add-face cider-repl--root-ns-regexp 'cider-stacktrace-ns-face
+                  t nil string)
+  string)
+
+(defun cider-repl-add-locref-help-echo (string)
+  "Set help-echo property of STRING to `cider-locref-help-echo'."
+  (put-text-property 0 (length string) 'help-echo 'cider-locref-help-echo string)
+  string)
+
+(defvar cider-repl-preoutput-hook '(ansi-color-apply
+                                    cider-repl-highlight-current-project
+                                    cider-repl-highlight-spec-keywords
+                                    cider-repl-add-locref-help-echo)
+  "Hook run on output string before it is inserted into the REPL buffer.
+Each functions takes a string and must return a modified string.  Also see
+`cider-run-chained-hook'.")
+
+(defun cider-repl--emit-output-at-pos (buffer string output-face position &optional bol)
+  "Using BUFFER, insert STRING (applying to it OUTPUT-FACE) at POSITION.
+If BOL is non-nil insert at the beginning of line.  Run
+`cider-repl-preoutput-hook' on STRING."
+  (with-current-buffer buffer
+    (save-excursion
+      (cider-save-marker cider-repl-output-start
+        (cider-save-marker cider-repl-output-end
+          (goto-char position)
+          ;; TODO: Review the need for bol
+          (when (and bol (not (bolp))) (insert-before-markers "\n"))
+          (setq string (propertize string
+                                   'font-lock-face output-face
+                                   'rear-nonsticky '(font-lock-face)))
+          (setq string (cider-run-chained-hook 'cider-repl-preoutput-hook string))
+          (insert-before-markers string)
+          (cider-repl--flush-ansi-color-context)
+          (when (and (= (point) cider-repl-prompt-start-mark)
+                     (not (bolp)))
+            (insert-before-markers "\n")
+            (set-marker cider-repl-output-end (1- (point)))))))
+    (cider-repl--show-maximum-output)))
+
+(defun cider-repl--emit-interactive-output (string face)
+  "Emit STRING as interactive output using FACE."
+  (with-current-buffer (cider-current-repl)
+    (let ((pos (cider-repl--end-of-line-before-input-start))
+          (string (replace-regexp-in-string "\n\\'" "" string)))
+      (cider-repl--emit-output-at-pos (current-buffer) string face pos t))))
+
+(defun cider-repl-emit-interactive-stdout (string)
+  "Emit STRING as interactive output."
+  (cider-repl--emit-interactive-output string 'cider-repl-stdout-face))
+
+(defun cider-repl-emit-interactive-stderr (string)
+  "Emit STRING as interactive err output."
+  (cider-repl--emit-interactive-output string 'cider-repl-stderr-face))
+
+(defun cider-repl--emit-output (buffer string face &optional bol)
+  "Using BUFFER, emit STRING font-locked with FACE.
+If BOL is non-nil, emit at the beginning of the line."
+  (with-current-buffer buffer
+    (cider-repl--emit-output-at-pos buffer string face cider-repl-input-start-mark bol)))
+
+(defun cider-repl-emit-stdout (buffer string)
+  "Using BUFFER, emit STRING as standard output."
+  (cider-repl--emit-output buffer string 'cider-repl-stdout-face))
+
+(defun cider-repl-emit-stderr (buffer string)
+  "Using BUFFER, emit STRING as error output."
+  (cider-repl--emit-output buffer string 'cider-repl-stderr-face))
+
+(defun cider-repl-emit-prompt (buffer)
+  "Emit the REPL prompt into BUFFER."
+  (with-current-buffer buffer
+    (save-excursion
+      (cider-save-marker cider-repl-output-start
+        (cider-save-marker cider-repl-output-end
+          (cider-repl--insert-prompt cider-buffer-ns))))
+    (cider-repl--show-maximum-output)))
+
+(defun cider-repl-emit-result (buffer string show-prefix &optional bol)
+  "Emit into BUFFER the result STRING and mark it as an evaluation result.
+If SHOW-PREFIX is non-nil insert `cider-repl-result-prefix' at the beginning
+of the line.  If BOL is non-nil insert at the beginning of the line."
+  (with-current-buffer buffer
+    (save-excursion
+      (cider-save-marker cider-repl-output-start
+        (cider-save-marker cider-repl-output-end
+          (goto-char cider-repl-input-start-mark)
+          (when (and bol (not (bolp)))
+            (insert-before-markers "\n"))
+          (when show-prefix
+            (insert-before-markers (propertize cider-repl-result-prefix 'font-lock-face 'font-lock-comment-face)))
+          (if cider-repl-use-clojure-font-lock
+              (insert-before-markers (cider-font-lock-as-clojure string))
+            (cider-propertize-region
+                '(font-lock-face cider-repl-result-face rear-nonsticky (font-lock-face))
+              (insert-before-markers string))))))
+    (cider-repl--show-maximum-output)))
+
+(defun cider-repl-newline-and-indent ()
+  "Insert a newline, then indent the next line.
+Restrict the buffer from the prompt for indentation, to avoid being
+confused by strange characters (like unmatched quotes) appearing
+earlier in the buffer."
+  (interactive)
+  (save-restriction
+    (narrow-to-region cider-repl-prompt-start-mark (point-max))
+    (insert "\n")
+    (lisp-indent-line)))
+
+(defun cider-repl-indent-and-complete-symbol ()
+  "Indent the current line and perform symbol completion.
+First indent the line.  If indenting doesn't move point, complete
+the symbol."
+  (interactive)
+  (let ((pos (point)))
+    (lisp-indent-line)
+    (when (= pos (point))
+      (if (save-excursion (re-search-backward "[^() \n\t\r]+\\=" nil t))
+          (completion-at-point)))))
+
+(defun cider-repl-kill-input ()
+  "Kill all text from the prompt to point."
+  (interactive)
+  (cond ((< (marker-position cider-repl-input-start-mark) (point))
+         (kill-region cider-repl-input-start-mark (point)))
+        ((= (point) (marker-position cider-repl-input-start-mark))
+         (cider-repl-delete-current-input))))
+
+(defun cider-repl--input-complete-p (start end)
+  "Return t if the region from START to END is a complete sexp."
+  (save-excursion
+    (goto-char start)
+    (cond ((looking-at-p "\\s *[@'`#]?[(\"]")
+           (ignore-errors
+             (save-restriction
+               (narrow-to-region start end)
+               ;; Keep stepping over blanks and sexps until the end of
+               ;; buffer is reached or an error occurs. Tolerate extra
+               ;; close parens.
+               (cl-loop do (skip-chars-forward " \t\r\n)")
+                        until (eobp)
+                        do (forward-sexp))
+               t)))
+          (t t))))
+
+(defun cider-repl--display-image (buffer image &optional show-prefix bol string)
+  "Insert IMAGE into BUFFER at the current point.
+
+For compatibility with the rest of CIDER's REPL machinery, supports
+SHOW-PREFIX and BOL."
+  (with-current-buffer buffer
+    (save-excursion
+      (cider-save-marker cider-repl-output-start
+        (cider-save-marker cider-repl-output-end
+          (goto-char cider-repl-input-start-mark)
+          (when (and bol (not (bolp)))
+            (insert-before-markers "\n"))
+          (when show-prefix
+            (insert-before-markers
+             (propertize cider-repl-result-prefix 'font-lock-face 'font-lock-comment-face)))
+          (insert-image image string)
+          (set-marker cider-repl-input-start-mark (point) buffer)
+          (set-marker cider-repl-prompt-start-mark (point) buffer))))
+    (cider-repl--show-maximum-output))
+  t)
+
+(defcustom cider-repl-image-margin 10
+  "Specifies the margin to be applied to images displayed in the REPL.
+Either a single number of pixels - interpreted as a symmetric margin, or
+pair of numbers `(x . y)' encoding an arbitrary margin."
+  :type '(choice integer (vector integer integer))
+  :group 'cider-repl
+  :package-version '(cider . "0.17.0"))
+
+(defun cider-repl--image (data type datap)
+  "A helper for creating images with CIDER's image options.
+DATA is either the path to an image or its base64 coded data.  TYPE is a
+symbol indicating the image type.  DATAP indicates whether the image is the
+raw image data or a filename.  Returns an image instance with a margin per
+`cider-repl-image-margin'."
+  (create-image data type datap
+                :margin cider-repl-image-margin))
+
+(defun cider-repl-handle-jpeg (_type buffer image &optional show-prefix bol)
+  "A handler for inserting a jpeg IMAGE into a repl BUFFER.
+Part of the default `cider-repl-content-type-handler-alist'."
+  (cider-repl--display-image buffer
+                             (cider-repl--image image 'jpeg t)
+                             show-prefix bol " "))
+
+(defun cider-repl-handle-png (_type buffer image &optional show-prefix bol)
+  "A handler for inserting a png IMAGE into a repl BUFFER.
+Part of the default `cider-repl-content-type-handler-alist'."
+  (cider-repl--display-image buffer
+                             (cider-repl--image image 'png t)
+                             show-prefix bol " "))
+
+(defun cider-repl-handle-external-body (type buffer _ &optional _show-prefix _bol)
+  "Handler for slurping external content into BUFFER.
+Handles an external-body TYPE by issuing a slurp request to fetch the content."
+  (if-let* ((args        (cadr type))
+            (access-type (nrepl-dict-get args "access-type")))
+      (nrepl-send-request
+       (list "op" "slurp" "url" (nrepl-dict-get args access-type))
+       (cider-repl-handler buffer)
+       (cider-current-repl)))
+  nil)
+
+(defvar cider-repl-content-type-handler-alist
+  `(("message/external-body" . ,#'cider-repl-handle-external-body)
+    ("image/jpeg" . ,#'cider-repl-handle-jpeg)
+    ("image/png" . ,#'cider-repl-handle-png))
+  "Association list from content-types to handlers.
+Handlers must be functions of two required and two optional arguments - the
+REPL buffer to insert into, the value of the given content type as a raw
+string, the REPL's show prefix as any and an `end-of-line' flag.
+
+The return value of the handler should be a flag, indicating whether or not
+the REPL is ready for a prompt to be displayed.  Most handlers should return
+t, as the content-type response is (currently) an alternative to the
+value response.  However for handlers which themselves issue subsequent
+nREPL ops, it may be convenient to prevent inserting a prompt.")
+
+(defun cider-repl-handler (buffer)
+  "Make an nREPL evaluation handler for the REPL BUFFER."
+  (let (after-first-result-chunk
+        (show-prompt t))
+    (nrepl-make-response-handler
+     buffer
+     (lambda (buffer value)
+       (cider-repl-emit-result buffer value (not after-first-result-chunk) t)
+       (setq after-first-result-chunk t))
+     (lambda (buffer out)
+       (cider-repl-emit-stdout buffer out))
+     (lambda (buffer err)
+       (cider-repl-emit-stderr buffer err))
+     (lambda (buffer)
+       (when show-prompt
+         (cider-repl-emit-prompt buffer)
+         (let ((win (get-buffer-window (current-buffer) t)))
+           (when win
+             (with-selected-window win
+               (set-window-point win cider-repl-input-start-mark))
+             (cider-repl--show-maximum-output)))))
+     nrepl-err-handler
+     (lambda (buffer pprint-out)
+       (cider-repl-emit-result buffer pprint-out (not after-first-result-chunk))
+       (setq after-first-result-chunk t))
+     (lambda (buffer value content-type)
+       (if-let* ((content-attrs (cadr content-type))
+                 (content-type* (car content-type))
+                 (handler (cdr (assoc content-type*
+                                      cider-repl-content-type-handler-alist))))
+           (setq after-first-result-chunk t
+                 show-prompt (funcall handler content-type buffer value
+                                      (not after-first-result-chunk) t))
+         (progn (cider-repl-emit-result buffer value (not after-first-result-chunk) t)
+                (setq after-first-result-chunk t)))))))
+
+(defun cider--repl-request-plist (right-margin &optional pprint-fn)
+  "Plist to be appended to generic eval requests, as for the REPL.
+PPRINT-FN and RIGHT-MARGIN are as in `cider--nrepl-pprint-request-plist'."
+  (nconc (when cider-repl-use-pretty-printing
+           (cider--nrepl-pprint-request-plist right-margin pprint-fn))
+         (when cider-repl-use-content-types
+           (cider--nrepl-content-type-plist))))
+
+(defun cider-repl--send-input (&optional newline)
+  "Go to the end of the input and send the current input.
+If NEWLINE is true then add a newline at the end of the input."
+  (unless (cider-repl--in-input-area-p)
+    (error "No input at point"))
+  (let ((input (cider-repl--current-input)))
+    (if (string-blank-p input)
+        ;; don't evaluate a blank string, but erase it and emit
+        ;; a fresh prompt to acknowledge to the user.
+        (progn
+          (cider-repl--replace-input "")
+          (cider-repl-emit-prompt (current-buffer)))
+      ;; otherwise evaluate the input
+      (goto-char (point-max))
+      (let ((end (point)))              ; end of input, without the newline
+        (cider-repl--add-to-input-history input)
+        (when newline
+          (insert "\n")
+          (cider-repl--show-maximum-output))
+        (let ((inhibit-modification-hooks t))
+          (add-text-properties cider-repl-input-start-mark
+                               (point)
+                               `(cider-old-input
+                                 ,(cl-incf cider-repl-old-input-counter))))
+        (unless cider-repl-use-clojure-font-lock
+          (let ((overlay (make-overlay cider-repl-input-start-mark end)))
+            ;; These properties are on an overlay so that they won't be taken
+            ;; by kill/yank.
+            (overlay-put overlay 'read-only t)
+            (overlay-put overlay 'font-lock-face 'cider-repl-input-face))))
+      (let ((input-start (save-excursion (cider-repl-beginning-of-defun) (point))))
+        (goto-char (point-max))
+        (cider-repl--mark-input-start)
+        (cider-repl--mark-output-start)
+        (cider-nrepl-request:eval
+         input
+         (cider-repl-handler (current-buffer))
+         (cider-current-ns)
+         (line-number-at-pos input-start)
+         (cider-column-number-at-pos input-start)
+         (cider--repl-request-plist (cider--pretty-print-width)))))))
+
+(defun cider-repl-return (&optional end-of-input)
+  "Evaluate the current input string, or insert a newline.
+Send the current input ony if a whole expression has been entered,
+i.e. the parenthesis are matched.
+When END-OF-INPUT is non-nil, send the input even if the parentheses
+are not balanced."
+  (interactive "P")
+  (cond
+   (end-of-input
+    (cider-repl--send-input))
+   ((and (get-text-property (point) 'cider-old-input)
+         (< (point) cider-repl-input-start-mark))
+    (cider-repl--grab-old-input end-of-input)
+    (cider-repl--recenter-if-needed))
+   ((cider-repl--input-complete-p cider-repl-input-start-mark (point-max))
+    (cider-repl--send-input t))
+   (t
+    (cider-repl-newline-and-indent)
+    (message "[input not complete]"))))
+
+(defun cider-repl--recenter-if-needed ()
+  "Make sure that the point is visible."
+  (unless (pos-visible-in-window-p (point-max))
+    (save-excursion
+      (goto-char (point-max))
+      (recenter -1))))
+
+(defun cider-repl--grab-old-input (replace)
+  "Resend the old REPL input at point.
+If REPLACE is non-nil the current input is replaced with the old
+input; otherwise the new input is appended.  The old input has the
+text property `cider-old-input'."
+  (cl-multiple-value-bind (beg end) (cider-property-bounds 'cider-old-input)
+    (let ((old-input (buffer-substring beg end)) ;;preserve
+          ;;properties, they will be removed later
+          (offset (- (point) beg)))
+      ;; Append the old input or replace the current input
+      (cond (replace (goto-char cider-repl-input-start-mark))
+            (t (goto-char (point-max))
+               (unless (eq (char-before) ?\ )
+                 (insert " "))))
+      (delete-region (point) (point-max))
+      (save-excursion
+        (insert old-input)
+        (when (equal (char-before) ?\n)
+          (delete-char -1)))
+      (forward-char offset))))
+
+(defun cider-repl-closing-return ()
+  "Evaluate the current input string after closing all open parenthesized or bracketed expressions."
+  (interactive)
+  (goto-char (point-max))
+  (save-restriction
+    (narrow-to-region cider-repl-input-start-mark (point))
+    (let ((matching-delimiter nil))
+      (while (ignore-errors (save-excursion
+                              (backward-up-list 1)
+                              (setq matching-delimiter (cdr (syntax-after (point))))) t)
+        (insert-char matching-delimiter))))
+  (cider-repl-return))
+
+(defun cider-repl-toggle-pretty-printing ()
+  "Toggle pretty-printing in the REPL."
+  (interactive)
+  (setq cider-repl-use-pretty-printing (not cider-repl-use-pretty-printing))
+  (message "Pretty printing in REPL %s."
+           (if cider-repl-use-pretty-printing "enabled" "disabled")))
+
+(defun cider--pretty-print-width ()
+  "Return the width to use for pretty-printing."
+  (or cider-repl-pretty-print-width
+      fill-column
+      80))
+
+(defun cider-repl-toggle-content-types ()
+  "Toggle content-type rendering in the REPL."
+  (interactive)
+  (setq cider-repl-use-content-types (not cider-repl-use-content-types))
+  (message "Content-type support in REPL %s."
+           (if cider-repl-use-content-types "enabled" "disabled")))
+
+(defun cider-repl-switch-to-other ()
+  "Switch between the Clojure and ClojureScript REPLs for the current project."
+  (interactive)
+  ;; FIXME: implement cycling as session can hold more than two REPLs
+  (let* ((this-repl (cider-current-repl nil 'ensure))
+         (other-repl (car (seq-remove (lambda (r) (eq r this-repl)) (cider-repls nil t)))))
+    (if other-repl
+        (switch-to-buffer other-repl)
+      (user-error "No other REPL in current session (%s)"
+                  (car (sesman-current-session 'CIDER))))))
+
+(defvar cider-repl-clear-buffer-hook)
+
+(defun cider-repl--clear-region (start end)
+  "Delete the output and its overlays between START and END."
+  (mapc #'delete-overlay (overlays-in start end))
+  (delete-region start end))
+
+(defun cider-repl-clear-buffer ()
+  "Clear the currently visited REPL buffer completely.
+See also the related commands `cider-repl-clear-output' and
+`cider-find-and-clear-repl-output'."
+  (interactive)
+  (let ((inhibit-read-only t))
+    (cider-repl--clear-region (point-min) cider-repl-prompt-start-mark)
+    (cider-repl--clear-region cider-repl-output-start cider-repl-output-end)
+    (when (< (point) cider-repl-input-start-mark)
+      (goto-char cider-repl-input-start-mark))
+    (recenter t))
+  (run-hooks 'cider-repl-clear-buffer-hook))
+
+(defun cider-repl--end-of-line-before-input-start ()
+  "Return the position of the end of the line preceding the beginning of input."
+  (1- (previous-single-property-change cider-repl-input-start-mark 'field nil
+                                       (1+ (point-min)))))
+
+(defun cider-repl-clear-output (&optional clear-repl)
+  "Delete the output inserted since the last input.
+With a prefix argument CLEAR-REPL it will clear the entire REPL buffer instead."
+  (interactive "P")
+  (if clear-repl
+      (cider-repl-clear-buffer)
+    (let ((start (save-excursion
+                   (cider-repl-previous-prompt)
+                   (ignore-errors (forward-sexp))
+                   (forward-line)
+                   (point)))
+          (end (cider-repl--end-of-line-before-input-start)))
+      (when (< start end)
+        (let ((inhibit-read-only t))
+          (cider-repl--clear-region start end)
+          (save-excursion
+            (goto-char start)
+            (insert
+             (propertize ";; output cleared" 'font-lock-face 'font-lock-comment-face))))))))
+
+(defun cider-repl-clear-banners ()
+  "Delete the REPL banners."
+  (interactive)
+  ;; TODO: Improve the boundaries detecting logic
+  ;; probably it should be based on text properties
+  ;; the current implemetation will clear warnings as well
+  (let ((start (point-min))
+        (end (save-excursion
+               (goto-char (point-min))
+               (cider-repl-next-prompt)
+               (forward-line -1)
+               (end-of-line)
+               (point))))
+    (when (< start end)
+      (let ((inhibit-read-only t))
+        (cider-repl--clear-region start (1+ end))))))
+
+(defun cider-repl-clear-help-banner ()
+  "Delete the help REPL banner."
+  (interactive)
+  ;; TODO: Improve the boundaries detecting logic
+  ;; probably it should be based on text properties
+  (let ((start (save-excursion
+                 (goto-char (point-min))
+                 (search-forward ";; =")
+                 (beginning-of-line)
+                 (point)))
+        (end (save-excursion
+               (goto-char (point-min))
+               (cider-repl-next-prompt)
+               (search-backward ";; =")
+               (end-of-line)
+               (point))))
+    (when (< start end)
+      (let ((inhibit-read-only t))
+        (cider-repl--clear-region start (1+ end))))))
+
+(defun cider-repl-switch-ns-handler (buffer)
+  "Make an nREPL evaluation handler for the REPL BUFFER's ns switching."
+  (nrepl-make-response-handler buffer
+                               (lambda (_buffer _value))
+                               (lambda (buffer out)
+                                 (cider-repl-emit-stdout buffer out))
+                               (lambda (buffer err)
+                                 (cider-repl-emit-stderr buffer err))
+                               (lambda (buffer)
+                                 (cider-repl-emit-prompt buffer))))
+
+(defun cider-repl-set-ns (ns)
+  "Switch the namespace of the REPL buffer to NS.
+If called from a cljc buffer act on both the Clojure and ClojureScript REPL
+if there are more than one REPL present.  If invoked in a REPL buffer the
+command will prompt for the name of the namespace to switch to."
+  (interactive (list (if (or (derived-mode-p 'cider-repl-mode)
+                             (null (cider-ns-form)))
+                         (completing-read "Switch to namespace: "
+                                          (cider-sync-request:ns-list))
+                       (cider-current-ns))))
+  (when (or (not ns) (equal ns ""))
+    (user-error "No namespace selected"))
+  (cider-map-repls :auto
+    (lambda (connection)
+      (cider-nrepl-request:eval (format "(in-ns '%s)" ns)
+                                (cider-repl-switch-ns-handler connection)))))
+
+
+;;; Location References
+
+(defcustom cider-locref-regexp-alist
+  '((stdout-stacktrace "[ \t]\\(at \\([^$(]+\\).*(\\([^:()]+\\):\\([0-9]+\\))\\)" 1 2 3 4)
+    (aviso-stacktrace  "^[ \t]*\\(\\([^$/ \t]+\\).*? +\\([^:]+\\): +\\([0-9]+\\)\\)" 1 2 3 4)
+    (print-stacktrace  "\\[\\([^][$ \t]+\\).* +\\([^ \t]+\\) +\\([0-9]+\\)\\]" 0 1 2 3)
+    (timbre-log        "\\(TRACE\\|INFO\\|DEBUG\\|WARN\\|ERROR\\) +\\(\\[\\([^:]+\\):\\([0-9]+\\)\\]\\)" 2 3 nil 4)
+    (cljs-message      "at line \\([0-9]+\\) +\\(.*\\)$" 0 nil 2 1)
+    (reflection        "Reflection warning, +\\(\\([^\n:]+\\):\\([0-9]+\\):[0-9]+\\)" 1 nil 2 3))
+  "Alist holding regular expressions for inline location references.
+Each element in the alist has the form (NAME REGEXP HIGHLIGHT VAR FILE
+LINE), where NAME is the identifier of the regexp, REGEXP - regexp matching
+a location, HIGHLIGHT - sub-expression matching region to highlight on
+mouse-over, VAR - sub-expression giving Clojure VAR to look up.  FILE is
+currently only used when VAR is nil and must be full resource path in that
+case."
+  :type '(alist :key-type sexp)
+  :group 'cider-repl
+  :package-version '(cider. "0.16.0"))
+
+(defun cider--locref-at-point-1 (reg-list &optional pos)
+  "Workhorse for getting locref at POS.
+REG-LIST is an entry in `cider-locref-regexp-alist'."
+  (save-excursion
+    (let ((pos (or pos (point))))
+      (goto-char pos)
+      (beginning-of-line)
+      (when (re-search-forward (nth 1 reg-list) (point-at-eol) t)
+        (let ((ix-highlight (or (nth 2 reg-list) 0))
+              (ix-var (nth 3 reg-list))
+              (ix-file (nth 4 reg-list))
+              (ix-line (nth 5 reg-list)))
+          (list
+           :type (car reg-list)
+           :highlight (cons (match-beginning ix-highlight) (match-end ix-highlight))
+           :var  (and ix-var
+                      (replace-regexp-in-string "_" "-"
+                                                (match-string-no-properties ix-var)
+                                                nil t))
+           :file (and ix-file (match-string-no-properties ix-file))
+           :line (and ix-line (string-to-number (match-string-no-properties ix-line)))))))))
+
+(defun cider-locref-at-point (&optional pos)
+  "Return a plist of components of the location reference at POS.
+Limit search to current line only and return nil if no location has been
+found.  Returned keys are :type, :highlight, :var, :file, :line, where
+:highlight is a cons of positions, :var and :file are strings or nil, :line
+is a number.  See `cider-locref-regexp-alist' for how to specify regexes
+for locref look up."
+  (seq-some (lambda (rl) (cider--locref-at-point-1 rl pos))
+            cider-locref-regexp-alist))
+
+(defun cider-jump-to-locref-at-point (&optional pos)
+  "Identify location reference at POS and navigate to it.
+This function is used from help-echo property inside REPL buffers and uses
+regexes from `cider-locref-regexp-alist' to infer locations at point."
+  (interactive)
+  (if-let* ((loc (cider-locref-at-point pos)))
+      (let* ((var (plist-get loc :var))
+             (line (plist-get loc :line))
+             (file (or
+                    ;; retrieve from info middleware
+                    (when var
+                      (or (cider-sync-request:ns-path var)
+                          (nrepl-dict-get (cider-sync-request:info var) "file")))
+                    ;; when not found, return the file detected by regexp
+                    (when-let* ((file (plist-get loc :file)))
+                      (if (file-name-absolute-p file)
+                          file
+                        ;; when not absolute, expand within the current project
+                        (when-let* ((proj (clojure-project-dir)))
+                          (expand-file-name file proj)))))))
+        (if file
+            (cider--jump-to-loc-from-info (nrepl-dict "file" file "line" line) t)
+          (error "No source location for %s" var)))
+    (user-error "No location reference at point")))
+
+(defvar cider-locref-hoover-overlay
+  (let ((o (make-overlay 1 1)))
+    (overlay-put o 'category 'cider-error-hoover)
+    ;; (overlay-put o 'face 'highlight)
+    (overlay-put o 'pointer 'hand)
+    (overlay-put o 'mouse-face 'highlight)
+    (overlay-put o 'follow-link 'mouse)
+    (overlay-put o 'keymap
+                 (let ((map (make-sparse-keymap)))
+                   (define-key map [return]  'cider-jump-to-locref-at-point)
+                   (define-key map [mouse-2] 'cider-jump-to-locref-at-point)
+                   map))
+    o)
+  "Overlay used during hoovering on location references in REPL buffers.
+One for all REPLs.")
+
+(defun cider-locref-help-echo (_win buffer pos)
+  "Function for help-echo property in REPL buffers.
+WIN, BUFFER and POS are the window, buffer and point under mouse position."
+  (with-current-buffer buffer
+    (if-let* ((hl (plist-get (cider-locref-at-point pos) :highlight)))
+        (move-overlay cider-locref-hoover-overlay (car hl) (cdr hl))
+      (delete-overlay cider-locref-hoover-overlay))
+    nil))
+
+
+;;; History
+
+(defcustom cider-repl-wrap-history nil
+  "T to wrap history around when the end is reached."
+  :type 'boolean
+  :group 'cider-repl)
+
+;; These two vars contain the state of the last history search.  We
+;; only use them if `last-command' was `cider-repl--history-replace',
+;; otherwise we reinitialize them.
+
+(defvar cider-repl-input-history-position -1
+  "Newer items have smaller indices.")
+
+(defvar cider-repl-history-pattern nil
+  "The regexp most recently used for finding input history.")
+
+(defun cider-repl--add-to-input-history (string)
+  "Add STRING to the input history.
+Empty strings and duplicates are ignored."
+  (unless (or (equal string "")
+              (equal string (car cider-repl-input-history)))
+    (push string cider-repl-input-history)
+    (cl-incf cider-repl-input-history-items-added)))
+
+(defun cider-repl-delete-current-input ()
+  "Delete all text after the prompt."
+  (goto-char (point-max))
+  (delete-region cider-repl-input-start-mark (point-max)))
+
+(defun cider-repl--replace-input (string)
+  "Replace the current REPL input with STRING."
+  (cider-repl-delete-current-input)
+  (insert-and-inherit string))
+
+(defun cider-repl--position-in-history (start-pos direction regexp)
+  "Return the position of the history item starting at START-POS.
+Search in DIRECTION for REGEXP.
+Return -1 resp the length of the history if no item matches."
+  ;; Loop through the history list looking for a matching line
+  (let* ((step (cl-ecase direction
+                 (forward -1)
+                 (backward 1)))
+         (history cider-repl-input-history)
+         (len (length history)))
+    (cl-loop for pos = (+ start-pos step) then (+ pos step)
+             if (< pos 0) return -1
+             if (<= len pos) return len
+             if (string-match-p regexp (nth pos history)) return pos)))
+
+(defun cider-repl--history-replace (direction &optional regexp)
+  "Replace the current input with the next line in DIRECTION.
+DIRECTION is 'forward' or 'backward' (in the history list).
+If REGEXP is non-nil, only lines matching REGEXP are considered."
+  (setq cider-repl-history-pattern regexp)
+  (let* ((min-pos -1)
+         (max-pos (length cider-repl-input-history))
+         (pos0 (cond ((cider-history-search-in-progress-p)
+                      cider-repl-input-history-position)
+                     (t min-pos)))
+         (pos (cider-repl--position-in-history pos0 direction (or regexp "")))
+         (msg nil))
+    (cond ((and (< min-pos pos) (< pos max-pos))
+           (cider-repl--replace-input (nth pos cider-repl-input-history))
+           (setq msg (format "History item: %d" pos)))
+          ((not cider-repl-wrap-history)
+           (setq msg (cond ((= pos min-pos) "End of history")
+                           ((= pos max-pos) "Beginning of history"))))
+          (cider-repl-wrap-history
+           (setq pos (if (= pos min-pos) max-pos min-pos))
+           (setq msg "Wrapped history")))
+    (when (or (<= pos min-pos) (<= max-pos pos))
+      (when regexp
+        (setq msg (concat msg "; no matching item"))))
+    (message "%s%s" msg (cond ((not regexp) "")
+                              (t (format "; current regexp: %s" regexp))))
+    (setq cider-repl-input-history-position pos)
+    (setq this-command 'cider-repl--history-replace)))
+
+(defun cider-history-search-in-progress-p ()
+  "Return t if a current history search is in progress."
+  (eq last-command 'cider-repl--history-replace))
+
+(defun cider-terminate-history-search ()
+  "Terminate the current history search."
+  (setq last-command this-command))
+
+(defun cider-repl-previous-input ()
+  "Cycle backwards through input history.
+If the `last-command' was a history navigation command use the
+same search pattern for this command.
+Otherwise use the current input as search pattern."
+  (interactive)
+  (cider-repl--history-replace 'backward (cider-repl-history-pattern t)))
+
+(defun cider-repl-next-input ()
+  "Cycle forwards through input history.
+See `cider-previous-input'."
+  (interactive)
+  (cider-repl--history-replace 'forward (cider-repl-history-pattern t)))
+
+(defun cider-repl-forward-input ()
+  "Cycle forwards through input history."
+  (interactive)
+  (cider-repl--history-replace 'forward (cider-repl-history-pattern)))
+
+(defun cider-repl-backward-input ()
+  "Cycle backwards through input history."
+  (interactive)
+  (cider-repl--history-replace 'backward (cider-repl-history-pattern)))
+
+(defun cider-repl-previous-matching-input (regexp)
+  "Find the previous input matching REGEXP."
+  (interactive "sPrevious element matching (regexp): ")
+  (cider-terminate-history-search)
+  (cider-repl--history-replace 'backward regexp))
+
+(defun cider-repl-next-matching-input (regexp)
+  "Find then next input matching REGEXP."
+  (interactive "sNext element matching (regexp): ")
+  (cider-terminate-history-search)
+  (cider-repl--history-replace 'forward regexp))
+
+(defun cider-repl-history-pattern (&optional use-current-input)
+  "Return the regexp for the navigation commands.
+If USE-CURRENT-INPUT is non-nil, use the current input."
+  (cond ((cider-history-search-in-progress-p)
+         cider-repl-history-pattern)
+        (use-current-input
+         (cl-assert (<= cider-repl-input-start-mark (point)))
+         (let ((str (cider-repl--current-input t)))
+           (cond ((string-match-p "^[ \n]*$" str) nil)
+                 (t (concat "^" (regexp-quote str))))))
+        (t nil)))
+
+;;; persistent history
+(defcustom cider-repl-history-size 500
+  "The maximum number of items to keep in the REPL history."
+  :type 'integer
+  :safe #'integerp
+  :group 'cider-repl)
+
+(defcustom cider-repl-history-file nil
+  "File to save the persistent REPL history to."
+  :type 'string
+  :safe #'stringp
+  :group 'cider-repl)
+
+(defun cider-repl--history-read-filename ()
+  "Ask the user which file to use, defaulting `cider-repl-history-file'."
+  (read-file-name "Use CIDER REPL history file: "
+                  cider-repl-history-file))
+
+(defun cider-repl--history-read (filename)
+  "Read history from FILENAME and return it.
+It does not yet set the input history."
+  (if (file-readable-p filename)
+      (with-temp-buffer
+        (insert-file-contents filename)
+        (when (> (buffer-size (current-buffer)) 0)
+          (read (current-buffer))))
+    '()))
+
+(defun cider-repl-history-load (&optional filename)
+  "Load history from FILENAME into current session.
+FILENAME defaults to the value of `cider-repl-history-file' but user
+defined filenames can be used to read special history files.
+
+The value of `cider-repl-input-history' is set by this function."
+  (interactive (list (cider-repl--history-read-filename)))
+  (let ((f (or filename cider-repl-history-file)))
+    ;; TODO: probably need to set cider-repl-input-history-position as well.
+    ;; in a fresh connection the newest item in the list is currently
+    ;; not available.  After sending one input, everything seems to work.
+    (setq cider-repl-input-history (cider-repl--history-read f))))
+
+(defun cider-repl--history-write (filename)
+  "Write history to FILENAME.
+Currently coding system for writing the contents is hardwired to
+utf-8-unix."
+  (let* ((mhist (cider-repl--histories-merge cider-repl-input-history
+                                             cider-repl-input-history-items-added
+                                             (cider-repl--history-read filename)))
+         ;; newest items are at the beginning of the list, thus 0
+         (hist (cl-subseq mhist 0 (min (length mhist) cider-repl-history-size))))
+    (unless (file-writable-p filename)
+      (error (format "History file not writable: %s" filename)))
+    (let ((print-length nil) (print-level nil))
+      (with-temp-file filename
+        ;; TODO: really set cs for output
+        ;; TODO: does cs need to be customizable?
+        (insert ";; -*- coding: utf-8-unix -*-\n")
+        (insert ";; Automatically written history of CIDER REPL session\n")
+        (insert ";; Edit at your own risk\n\n")
+        (prin1 (mapcar #'substring-no-properties hist) (current-buffer))))))
+
+(defun cider-repl-history-save (&optional filename)
+  "Save the current REPL input history to FILENAME.
+FILENAME defaults to the value of `cider-repl-history-file'."
+  (interactive (list (cider-repl--history-read-filename)))
+  (let* ((file (or filename cider-repl-history-file)))
+    (cider-repl--history-write file)))
+
+(defun cider-repl-history-just-save ()
+  "Just save the history to `cider-repl-history-file'.
+This function is meant to be used in hooks to avoid lambda
+constructs."
+  (cider-repl-history-save cider-repl-history-file))
+
+;; SLIME has different semantics and will not save any duplicates.
+;; we keep track of how many items were added to the history in the
+;; current session in `cider-repl--add-to-input-history' and merge only the
+;; new items with the current history found in the file, which may
+;; have been changed in the meantime by another session.
+(defun cider-repl--histories-merge (session-hist n-added-items file-hist)
+  "Merge histories from SESSION-HIST adding N-ADDED-ITEMS into FILE-HIST."
+  (append (cl-subseq session-hist 0 n-added-items)
+          file-hist))
+
+
+;;; REPL shortcuts
+(defcustom cider-repl-shortcut-dispatch-char ?\,
+  "Character used to distinguish REPL commands from Lisp forms."
+  :type '(character)
+  :group 'cider-repl)
+
+(defvar cider-repl-shortcuts (make-hash-table :test 'equal))
+
+(defun cider-repl-add-shortcut (name handler)
+  "Add a REPL shortcut command, defined by NAME and HANDLER."
+  (puthash name handler cider-repl-shortcuts))
+
+(declare-function cider-toggle-trace-ns "cider-tracing")
+(declare-function cider-undef "cider-mode")
+(declare-function cider-browse-ns "cider-browse-ns")
+(declare-function cider-classpath "cider-classpath")
+(declare-function cider-repl-history "cider-repl-history")
+(declare-function cider-run "cider-mode")
+(declare-function cider-ns-refresh "cider-ns")
+(declare-function cider-version "cider")
+(declare-function cider-test-run-loaded-tests "cider-test")
+(declare-function cider-test-run-project-tests "cider-test")
+(cider-repl-add-shortcut "clear-output" #'cider-repl-clear-output)
+(cider-repl-add-shortcut "clear" #'cider-repl-clear-buffer)
+(cider-repl-add-shortcut "clear-banners" #'cider-repl-clear-banners)
+(cider-repl-add-shortcut "clear-help-banner" #'cider-repl-clear-help-banner)
+(cider-repl-add-shortcut "ns" #'cider-repl-set-ns)
+(cider-repl-add-shortcut "toggle-pretty" #'cider-repl-toggle-pretty-printing)
+(cider-repl-add-shortcut "browse-ns" (lambda () (interactive) (cider-browse-ns (cider-current-ns))))
+(cider-repl-add-shortcut "classpath" #'cider-classpath)
+(cider-repl-add-shortcut "history" #'cider-repl-history)
+(cider-repl-add-shortcut "trace-ns" #'cider-toggle-trace-ns)
+(cider-repl-add-shortcut "undef" #'cider-undef)
+(cider-repl-add-shortcut "refresh" #'cider-ns-refresh)
+(cider-repl-add-shortcut "help" #'cider-repl-shortcuts-help)
+(cider-repl-add-shortcut "test-ns" #'cider-test-run-ns-tests)
+(cider-repl-add-shortcut "test-all" #'cider-test-run-loaded-tests)
+(cider-repl-add-shortcut "test-project" #'cider-test-run-project-tests)
+(cider-repl-add-shortcut "test-ns-with-filters" #'cider-test-run-ns-tests-with-filters)
+(cider-repl-add-shortcut "test-all-with-filters" (lambda () (interactive) (cider-test-run-loaded-tests 'prompt-for-filters)))
+(cider-repl-add-shortcut "test-project-with-filters" (lambda () (interactive) (cider-test-run-project-tests 'prompt-for-filters)))
+(cider-repl-add-shortcut "test-report" #'cider-test-show-report)
+(cider-repl-add-shortcut "run" #'cider-run)
+(cider-repl-add-shortcut "conn-info" #'cider-describe-current-connection)
+(cider-repl-add-shortcut "hasta la vista" #'cider-quit)
+(cider-repl-add-shortcut "adios" #'cider-quit)
+(cider-repl-add-shortcut "sayonara" #'cider-quit)
+(cider-repl-add-shortcut "quit" #'cider-quit)
+(cider-repl-add-shortcut "restart" #'cider-restart)
+(cider-repl-add-shortcut "version" #'cider-version)
+(cider-repl-add-shortcut "require-repl-utils" #'cider-repl-require-repl-utils)
+
+(defconst cider-repl-shortcuts-help-buffer "*CIDER REPL Shortcuts Help*")
+
+(defun cider-repl-shortcuts-help ()
+  "Display a help buffer."
+  (interactive)
+  (ignore-errors (kill-buffer cider-repl-shortcuts-help-buffer))
+  (with-current-buffer (get-buffer-create cider-repl-shortcuts-help-buffer)
+    (insert "CIDER REPL shortcuts:\n\n")
+    (maphash (lambda (k v) (insert (format "%s:\n\t%s\n" k v))) cider-repl-shortcuts)
+    (goto-char (point-min))
+    (help-mode)
+    (display-buffer (current-buffer) t))
+  (cider-repl-handle-shortcut)
+  (current-buffer))
+
+(defun cider-repl--available-shortcuts ()
+  "Return the available REPL shortcuts."
+  (cider-util--hash-keys cider-repl-shortcuts))
+
+(defun cider-repl-handle-shortcut ()
+  "Execute a REPL shortcut."
+  (interactive)
+  (if (> (point) cider-repl-input-start-mark)
+      (insert (string cider-repl-shortcut-dispatch-char))
+    (let ((command (completing-read "Command: "
+                                    (cider-repl--available-shortcuts))))
+      (if (not (equal command ""))
+          (let ((command-func (gethash command cider-repl-shortcuts)))
+            (if command-func
+                (call-interactively command-func)
+              (error "Unknown command %S.  Available commands: %s"
+                     command-func
+                     (mapconcat 'identity (cider-repl--available-shortcuts) ", "))))
+        (error "No command selected")))))
+
+
+;;;;; CIDER REPL mode
+(defvar cider-repl-mode-hook nil
+  "Hook executed when entering `cider-repl-mode'.")
+
+(defvar cider-repl-mode-syntax-table
+  (copy-syntax-table clojure-mode-syntax-table))
+
+(declare-function cider-eval-last-sexp "cider-eval")
+(declare-function cider-toggle-trace-ns "cider-tracing")
+(declare-function cider-toggle-trace-var "cider-tracing")
+(declare-function cider-find-resource "cider-find")
+(declare-function cider-find-ns "cider-find")
+(declare-function cider-find-keyword "cider-find")
+(declare-function cider-find-var "cider-find")
+(declare-function cider-switch-to-last-clojure-buffer "cider-mode")
+(declare-function cider-macroexpand-1 "cider-macroexpansion")
+(declare-function cider-macroexpand-all "cider-macroexpansion")
+(declare-function cider-selector "cider-selector")
+(declare-function cider-jack-in-clj "cider")
+(declare-function cider-jack-in-cljs "cider")
+(declare-function cider-connect-clj "cider")
+(declare-function cider-connect-cljs "cider")
+
+(defvar cider-repl-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "C-c C-d") 'cider-doc-map)
+    (define-key map (kbd "C-c ,")   'cider-test-commands-map)
+    (define-key map (kbd "C-c C-t") 'cider-test-commands-map)
+    (define-key map (kbd "M-.") #'cider-find-var)
+    (define-key map (kbd "C-c C-.") #'cider-find-ns)
+    (define-key map (kbd "C-c C-:") #'cider-find-keyword)
+    (define-key map (kbd "M-,") #'cider-pop-back)
+    (define-key map (kbd "C-c M-.") #'cider-find-resource)
+    (define-key map (kbd "RET") #'cider-repl-return)
+    (define-key map (kbd "TAB") #'cider-repl-tab)
+    (define-key map (kbd "C-<return>") #'cider-repl-closing-return)
+    (define-key map (kbd "C-j") #'cider-repl-newline-and-indent)
+    (define-key map (kbd "C-c C-o") #'cider-repl-clear-output)
+    (define-key map (kbd "C-c M-n") #'cider-repl-set-ns)
+    (define-key map (kbd "C-c C-u") #'cider-repl-kill-input)
+    (define-key map (kbd "C-S-a") #'cider-repl-bol-mark)
+    (define-key map [S-home] #'cider-repl-bol-mark)
+    (define-key map (kbd "C-<up>") #'cider-repl-backward-input)
+    (define-key map (kbd "C-<down>") #'cider-repl-forward-input)
+    (define-key map (kbd "M-p") #'cider-repl-previous-input)
+    (define-key map (kbd "M-n") #'cider-repl-next-input)
+    (define-key map (kbd "M-r") #'cider-repl-previous-matching-input)
+    (define-key map (kbd "M-s") #'cider-repl-next-matching-input)
+    (define-key map (kbd "C-c C-n") #'cider-repl-next-prompt)
+    (define-key map (kbd "C-c C-p") #'cider-repl-previous-prompt)
+    (define-key map (kbd "C-c C-b") #'cider-interrupt)
+    (define-key map (kbd "C-c C-c") #'cider-interrupt)
+    (define-key map (kbd "C-c C-m") #'cider-macroexpand-1)
+    (define-key map (kbd "C-c M-m") #'cider-macroexpand-all)
+    (define-key map (kbd "C-c C-s") #'sesman-map)
+    (define-key map (kbd "C-c C-z") #'cider-switch-to-last-clojure-buffer)
+    (define-key map (kbd "C-c M-o") #'cider-repl-switch-to-other)
+    (define-key map (kbd "C-c M-s") #'cider-selector)
+    (define-key map (kbd "C-c M-d") #'cider-describe-current-connection)
+    (define-key map (kbd "C-c C-q") #'cider-quit)
+    (define-key map (kbd "C-c M-r") #'cider-restart)
+    (define-key map (kbd "C-c M-i") #'cider-inspect)
+    (define-key map (kbd "C-c M-p") #'cider-repl-history)
+    (define-key map (kbd "C-c M-t v") #'cider-toggle-trace-var)
+    (define-key map (kbd "C-c M-t n") #'cider-toggle-trace-ns)
+    (define-key map (kbd "C-c C-x") 'cider-start-map)
+    (define-key map (kbd "C-x C-e") #'cider-eval-last-sexp)
+    (define-key map (kbd "C-c C-r") 'clojure-refactor-map)
+    (define-key map (kbd "C-c C-v") 'cider-eval-commands-map)
+    (define-key map (kbd "C-c M-j") #'cider-jack-in-clj)
+    (define-key map (kbd "C-c M-J") #'cider-jack-in-cljs)
+    (define-key map (kbd "C-c M-c") #'cider-connect-clj)
+    (define-key map (kbd "C-c M-C") #'cider-connect-cljs)
+
+    (define-key map (string cider-repl-shortcut-dispatch-char) #'cider-repl-handle-shortcut)
+    (easy-menu-define cider-repl-mode-menu map
+      "Menu for CIDER's REPL mode"
+      `("REPL"
+        ["Complete symbol" complete-symbol]
+        "--"
+        ,cider-doc-menu
+        "--"
+        ("Find"
+         ["Find definition" cider-find-var]
+         ["Find namespace" cider-find-ns]
+         ["Find resource" cider-find-resource]
+         ["Find keyword" cider-find-keyword]
+         ["Go back" cider-pop-back])
+        "--"
+        ["Switch to Clojure buffer" cider-switch-to-last-clojure-buffer]
+        ["Switch to other REPL" cider-repl-switch-to-other]
+        "--"
+        ("Macroexpand"
+         ["Macroexpand-1" cider-macroexpand-1]
+         ["Macroexpand-all" cider-macroexpand-all])
+        "--"
+        ,cider-test-menu
+        "--"
+        ["Run project (-main function)" cider-run]
+        ["Inspect" cider-inspect]
+        ["Toggle var tracing" cider-toggle-trace-var]
+        ["Toggle ns tracing" cider-toggle-trace-ns]
+        ["Refresh loaded code" cider-ns-refresh]
+        "--"
+        ["Set REPL ns" cider-repl-set-ns]
+        ["Toggle pretty printing" cider-repl-toggle-pretty-printing]
+        ["Require REPL utils" cider-repl-require-repl-utils]
+        "--"
+        ["Browse classpath" cider-classpath]
+        ["Browse classpath entry" cider-open-classpath-entry]
+        ["Browse namespace" cider-browse-ns]
+        ["Browse all namespaces" cider-browse-ns-all]
+        ["Browse spec" cider-browse-spec]
+        ["Browse all specs" cider-browse-spec-all]
+        "--"
+        ["Next prompt" cider-repl-next-prompt]
+        ["Previous prompt" cider-repl-previous-prompt]
+        ["Clear output" cider-repl-clear-output]
+        ["Clear buffer" cider-repl-clear-buffer]
+        ["Clear banners" cider-repl-clear-banners]
+        ["Clear help banner" cider-repl-clear-help-banner]
+        ["Kill input" cider-repl-kill-input]
+        "--"
+        ["Interrupt evaluation" cider-interrupt]
+        "--"
+        ["Connection info" cider-describe-current-connection]
+        "--"
+        ["Close ancillary buffers" cider-close-ancillary-buffers]
+        ["Quit" cider-quit]
+        ["Restart" cider-restart]
+        "--"
+        ["Clojure Cheatsheet" cider-cheatsheet]
+        "--"
+        ["A sip of CIDER" cider-drink-a-sip]
+        ["View manual online" cider-view-manual]
+        ["View refcard online" cider-view-refcard]
+        ["Report a bug" cider-report-bug]
+        ["Version info" cider-version]))
+    map))
+
+(sesman-install-menu cider-repl-mode-map)
+
+(defun cider-repl-wrap-fontify-function (func)
+  "Return a function that will call FUNC narrowed to input region."
+  (lambda (beg end &rest rest)
+    (when (and cider-repl-input-start-mark
+               (> end cider-repl-input-start-mark))
+      (save-restriction
+        (narrow-to-region cider-repl-input-start-mark (point-max))
+        (let ((font-lock-dont-widen t))
+          (apply func (max beg cider-repl-input-start-mark) end rest))))))
+
+(declare-function cider-complete-at-point "cider-completion")
+(defvar cider--static-font-lock-keywords)
+
+(define-derived-mode cider-repl-mode fundamental-mode "REPL"
+  "Major mode for Clojure REPL interactions.
+
+\\{cider-repl-mode-map}"
+  (clojure-mode-variables)
+  (clojure-font-lock-setup)
+  (font-lock-add-keywords nil cider--static-font-lock-keywords)
+  (setq-local sesman-system 'CIDER)
+  (setq-local font-lock-fontify-region-function
+              (cider-repl-wrap-fontify-function font-lock-fontify-region-function))
+  (setq-local font-lock-unfontify-region-function
+              (cider-repl-wrap-fontify-function font-lock-unfontify-region-function))
+  (make-local-variable 'completion-at-point-functions)
+  (add-to-list 'completion-at-point-functions
+               #'cider-complete-at-point)
+  (set-syntax-table cider-repl-mode-syntax-table)
+  (cider-eldoc-setup)
+  ;; At the REPL, we define beginning-of-defun and end-of-defun to be
+  ;; the start of the previous prompt or next prompt respectively.
+  ;; Notice the interplay with `cider-repl-beginning-of-defun'.
+  (setq-local beginning-of-defun-function #'cider-repl-mode-beginning-of-defun)
+  (setq-local end-of-defun-function #'cider-repl-mode-end-of-defun)
+  (setq-local prettify-symbols-alist clojure--prettify-symbols-alist)
+  ;; apply dir-local variables to REPL buffers
+  (hack-dir-local-variables-non-file-buffer)
+  (when cider-repl-history-file
+    (cider-repl-history-load cider-repl-history-file)
+    (add-hook 'kill-buffer-hook #'cider-repl-history-just-save t t)
+    (add-hook 'kill-emacs-hook #'cider-repl-history-just-save))
+  (add-hook 'paredit-mode-hook (lambda () (clojure-paredit-setup cider-repl-mode-map))))
+
+(provide 'cider-repl)
+
+;;; cider-repl.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-repl.elc b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-repl.elc
new file mode 100644
index 0000000000..70318bef15
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-repl.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-resolve.el b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-resolve.el
new file mode 100644
index 0000000000..eb3ba4f74f
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-resolve.el
@@ -0,0 +1,130 @@
+;;; cider-resolve.el --- Resolve clojure symbols according to current nREPL connection
+
+;; Copyright © 2015-2018 Bozhidar Batsov, Artur Malabarba and CIDER contributors
+
+;; Author: Artur Malabarba <bruce.connor.am@gmail.com>
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; The ns cache is a dict of namespaces stored in the connection buffer.  This
+;; file offers functions to easily get information about variables from this
+;; cache, given the variable's name and the file's namespace.  This
+;; functionality is similar to that offered by the `cider-var-info' function
+;; (and others).  The difference is that all functions in this file operate
+;; without contacting the server (they still rely on an active connection
+;; buffer, but no messages are actually exchanged).
+
+;; For this reason, the functions here are well suited for very
+;; performance-sentitive operations, such as font-locking or
+;; indentation.  Meanwhile, operations like code-jumping are better off
+;; communicating with the middleware, just in the off chance that the cache is
+;; outdated.
+
+;; Below is a typical entry on this cache dict.  Note that clojure.core symbols
+;; are excluded from the refers to save space.
+
+;; "cider.nrepl.middleware.track-state"
+;; (dict "aliases"
+;;       (dict "cljs" "cider.nrepl.middleware.util.cljs"
+;;             "misc" "cider.nrepl.middleware.util.misc"
+;;             "set" "clojure.set")
+;;       "interns" (dict a
+;;                       "assoc-state"    (dict "arglists"
+;;                                              (("response"
+;;                                                (dict "as" "msg" "keys"
+;;                                                      ("session")))))
+;;                       "filter-core"    (dict "arglists"
+;;                                              (("refers")))
+;;                       "make-transport" (dict "arglists"
+;;                                              (((dict "as" "msg" "keys"
+;;                                                      ("transport")))))
+;;                       "ns-as-map"      (dict "arglists"
+;;                                              (("ns")))
+;;                       "ns-cache"       (dict)
+;;                       "relevant-meta"  (dict "arglists"
+;;                                              (("var")))
+;;                       "update-vals"    (dict "arglists"
+;;                                              (("m" "f")))
+;;                       "wrap-tracker"   (dict "arglists"
+;;                                              (("handler"))))
+;;       "refers" (dict "set-descriptor!" "#'clojure.tools.nrepl.middleware/set-descriptor!"))
+
+;;; Code:
+
+(require 'cider-client)
+(require 'nrepl-dict)
+(require 'cider-util)
+
+(defvar cider-repl-ns-cache)
+
+(defun cider-resolve--get-in (&rest keys)
+  "Return (nrepl-dict-get-in cider-repl-ns-cache KEYS)."
+  (when-let* ((conn (cider-current-repl)))
+    (with-current-buffer conn
+      (nrepl-dict-get-in cider-repl-ns-cache keys))))
+
+(defun cider-resolve-alias (ns alias)
+  "Return the namespace that ALIAS refers to in namespace NS.
+If it doesn't point anywhere, returns ALIAS."
+  (or (cider-resolve--get-in ns "aliases" alias)
+      alias))
+
+(defconst cider-resolve--prefix-regexp "\\`\\(?:#'\\)?\\([^/]+\\)/")
+
+(defun cider-resolve-var (ns var)
+  "Return a dict of the metadata of a clojure var VAR in namespace NS.
+VAR is a string.
+Return nil only if VAR cannot be resolved."
+  (let* ((var-ns (when (string-match cider-resolve--prefix-regexp var)
+                   (cider-resolve-alias ns (match-string 1 var))))
+         (name (replace-regexp-in-string cider-resolve--prefix-regexp "" var)))
+    (or
+     (cider-resolve--get-in (or var-ns ns) "interns" name)
+     (unless var-ns
+       ;; If the var had no prefix, it might be referred.
+       (if-let* ((referal (cider-resolve--get-in ns "refers" name)))
+           (cider-resolve-var ns referal)
+         ;; Or it might be from core.
+         (unless (equal ns "clojure.core")
+           (cider-resolve-var "clojure.core" name)))))))
+
+(defun cider-resolve-core-ns ()
+  "Return a dict of the core namespace for current connection.
+This will be clojure.core or cljs.core depending on the return value of the
+function `cider-repl-type'."
+  (when-let* ((repl (cider-current-repl)))
+    (with-current-buffer repl
+      (cider-resolve--get-in (if (equal cider-repl-type "cljs")
+                                 "cljs.core"
+                               "clojure.core")))))
+
+(defun cider-resolve-ns-symbols (ns)
+  "Return a plist of all valid symbols in NS.
+Each entry's value is the metadata of the var that the symbol refers to.
+NS can be the namespace name, or a dict of the namespace itself."
+  (when-let* ((dict (if (stringp ns)
+                        (cider-resolve--get-in ns)
+                      ns)))
+    (nrepl-dbind-response dict (interns refers aliases)
+      (append (cdr interns)
+              (nrepl-dict-flat-map (lambda (alias namespace)
+                                     (nrepl-dict-flat-map (lambda (sym meta)
+                                                            (list (concat alias "/" sym) meta))
+                                                          (cider-resolve--get-in namespace "interns")))
+                                   aliases)))))
+
+(provide 'cider-resolve)
+;;; cider-resolve.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-resolve.elc b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-resolve.elc
new file mode 100644
index 0000000000..c1bd31c59b
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-resolve.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-scratch.el b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-scratch.el
new file mode 100644
index 0000000000..f1c3e93d1c
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-scratch.el
@@ -0,0 +1,98 @@
+;;; cider-scratch.el --- *scratch* buffer for Clojure -*- lexical-binding: t -*-
+
+;; Copyright © 2014-2018 Bozhidar Batsov and CIDER contributors
+;;
+;; Author: Tim King <kingtim@gmail.com>
+;;         Phil Hagelberg <technomancy@gmail.com>
+;;         Bozhidar Batsov <bozhidar@batsov.com>
+;;         Artur Malabarba <bruce.connor.am@gmail.com>
+;;         Hugo Duncan <hugo@hugoduncan.org>
+;;         Steve Purcell <steve@sanityinc.com>
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;; This file is not part of GNU Emacs.
+
+;;; Commentary:
+
+;; Imitate Emacs's *scratch* buffer.
+
+;;; Code:
+
+(require 'cider-eval)
+(require 'clojure-mode)
+(require 'easymenu)
+
+(defcustom cider-scratch-initial-message
+  ";; This buffer is for Clojure experiments and evaluation.\n
+;; Press C-j to evaluate the last expression.\n\n"
+  "The initial message displayed in new scratch buffers."
+  :type 'string
+  :group 'cider
+  :package-version '(cider . "0.18.0"))
+
+(defvar cider-clojure-interaction-mode-map
+  (let ((map (make-sparse-keymap)))
+    (set-keymap-parent map clojure-mode-map)
+    (define-key map (kbd "C-j") #'cider-eval-print-last-sexp)
+    (define-key map [remap paredit-newline] #'cider-eval-print-last-sexp)
+    (easy-menu-define cider-clojure-interaction-mode-menu map
+      "Menu for Clojure Interaction mode"
+      '("Clojure Interaction"
+        (["Eval and print last sexp" #'cider-eval-print-last-sexp]
+         "--"
+         ["Reset" #'cider-scratch-reset])))
+    map))
+
+(defconst cider-scratch-buffer-name "*cider-scratch*")
+
+;;;###autoload
+(defun cider-scratch ()
+  "Go to the scratch buffer named `cider-scratch-buffer-name'."
+  (interactive)
+  (pop-to-buffer (cider-scratch-find-or-create-buffer)))
+
+(defun cider-scratch-find-or-create-buffer ()
+  "Find or create the scratch buffer."
+  (or (get-buffer cider-scratch-buffer-name)
+      (cider-scratch--create-buffer)))
+
+(define-derived-mode cider-clojure-interaction-mode clojure-mode "Clojure Interaction"
+  "Major mode for typing and evaluating Clojure forms.
+Like clojure-mode except that \\[cider-eval-print-last-sexp] evals the Lisp expression
+before point, and prints its value into the buffer, advancing point.
+
+\\{cider-clojure-interaction-mode-map}"
+  (setq-local sesman-system 'CIDER))
+
+(defun cider-scratch--insert-welcome-message ()
+  "Insert the welcome message for the scratch buffer."
+  (insert cider-scratch-initial-message))
+
+(defun cider-scratch--create-buffer ()
+  "Create a new scratch buffer."
+  (with-current-buffer (get-buffer-create cider-scratch-buffer-name)
+    (cider-clojure-interaction-mode)
+    (cider-scratch--insert-welcome-message)
+    (current-buffer)))
+
+(defun cider-scratch-reset ()
+  "Reset the current scratch buffer."
+  (interactive)
+  (erase-buffer)
+  (cider-scratch--insert-welcome-message))
+
+(provide 'cider-scratch)
+
+;;; cider-scratch.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-scratch.elc b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-scratch.elc
new file mode 100644
index 0000000000..f6f0788fa7
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-scratch.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-selector.el b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-selector.el
new file mode 100644
index 0000000000..3163e6fafe
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-selector.el
@@ -0,0 +1,165 @@
+;;; cider-selector.el --- Buffer selection command inspired by SLIME's selector -*- lexical-binding: t -*-
+
+;; Copyright © 2012-2013 Tim King, Phil Hagelberg, Bozhidar Batsov
+;; Copyright © 2013-2018 Bozhidar Batsov, Artur Malabarba and CIDER contributors
+;;
+;; Author: Tim King <kingtim@gmail.com>
+;;         Phil Hagelberg <technomancy@gmail.com>
+;;         Bozhidar Batsov <bozhidar@batsov.com>
+;;         Artur Malabarba <bruce.connor.am@gmail.com>
+;;         Hugo Duncan <hugo@hugoduncan.org>
+;;         Steve Purcell <steve@sanityinc.com>
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;; This file is not part of GNU Emacs.
+
+;;; Commentary:
+
+;; Buffer selection command inspired by SLIME's selector.
+
+;;; Code:
+
+(require 'cider-client)
+(require 'cider-eval)
+(require 'cider-scratch)
+
+(defconst cider-selector-help-buffer "*CIDER Selector Help*"
+  "The name of the selector's help buffer.")
+
+(defvar cider-selector-methods nil
+  "List of buffer-selection methods for the `cider-selector' command.
+Each element is a list (KEY DESCRIPTION FUNCTION).
+DESCRIPTION is a one-line description of what the key selects.")
+
+(defvar cider-selector-other-window nil
+  "If non-nil use `switch-to-buffer-other-window'.
+Not meant to be set by users.  It's used internally
+by `cider-selector'.")
+
+(defun cider-selector--recently-visited-buffer (mode)
+  "Return the most recently visited buffer, deriving its `major-mode' from MODE.
+Only considers buffers that are not already visible."
+  (cl-loop for buffer in (buffer-list)
+           when (and (with-current-buffer buffer
+                       (derived-mode-p mode))
+                     ;; names starting with space are considered hidden by Emacs
+                     (not (string-match-p "^ " (buffer-name buffer)))
+                     (null (get-buffer-window buffer 'visible)))
+           return buffer
+           finally (error "Can't find unshown buffer in %S" mode)))
+
+;;;###autoload
+(defun cider-selector (&optional other-window)
+  "Select a new buffer by type, indicated by a single character.
+The user is prompted for a single character indicating the method by
+which to choose a new buffer.  The `?' character describes then
+available methods.  OTHER-WINDOW provides an optional target.
+See `def-cider-selector-method' for defining new methods."
+  (interactive)
+  (message "Select [%s]: "
+           (apply #'string (mapcar #'car cider-selector-methods)))
+  (let* ((cider-selector-other-window other-window)
+         (ch (save-window-excursion
+               (select-window (minibuffer-window))
+               (read-char)))
+         (method (cl-find ch cider-selector-methods :key #'car)))
+    (cond (method
+           (funcall (cl-caddr method)))
+          (t
+           (message "No method for character: ?\\%c" ch)
+           (ding)
+           (sleep-for 1)
+           (discard-input)
+           (cider-selector)))))
+
+(defmacro def-cider-selector-method (key description &rest body)
+  "Define a new `cider-select' buffer selection method.
+KEY is the key the user will enter to choose this method.
+
+DESCRIPTION is a one-line sentence describing how the method
+selects a buffer.
+
+BODY is a series of forms which are evaluated when the selector
+is chosen.  The returned buffer is selected with
+`switch-to-buffer'."
+  (let ((method `(lambda ()
+                   (let ((buffer (progn ,@body)))
+                     (cond ((not (get-buffer buffer))
+                            (message "No such buffer: %S" buffer)
+                            (ding))
+                           ((get-buffer-window buffer)
+                            (select-window (get-buffer-window buffer)))
+                           (cider-selector-other-window
+                            (switch-to-buffer-other-window buffer))
+                           (t
+                            (switch-to-buffer buffer)))))))
+    `(setq cider-selector-methods
+           (cl-sort (cons (list ,key ,description ,method)
+                          (cl-remove ,key cider-selector-methods :key #'car))
+                    #'< :key #'car))))
+
+(def-cider-selector-method ?? "Selector help buffer."
+  (ignore-errors (kill-buffer cider-selector-help-buffer))
+  (with-current-buffer (get-buffer-create cider-selector-help-buffer)
+    (insert "CIDER Selector Methods:\n\n")
+    (cl-loop for (key line nil) in cider-selector-methods
+             do (insert (format "%c:\t%s\n" key line)))
+    (goto-char (point-min))
+    (help-mode)
+    (display-buffer (current-buffer) t))
+  (cider-selector)
+  (current-buffer))
+
+(cl-pushnew (list ?4 "Select in other window" (lambda () (cider-selector t)))
+            cider-selector-methods :key #'car)
+
+(def-cider-selector-method ?c
+  "Most recently visited clojure-mode buffer."
+  (cider-selector--recently-visited-buffer 'clojure-mode))
+
+(def-cider-selector-method ?e
+  "Most recently visited emacs-lisp-mode buffer."
+  (cider-selector--recently-visited-buffer 'emacs-lisp-mode))
+
+(def-cider-selector-method ?q "Abort."
+  (top-level))
+
+(def-cider-selector-method ?r
+  "Current REPL buffer."
+  (cider-current-repl))
+
+(def-cider-selector-method ?m
+  "Current connection's *nrepl-messages* buffer."
+  (nrepl-messages-buffer (cider-current-repl)))
+
+(def-cider-selector-method ?x
+  "*cider-error* buffer."
+  cider-error-buffer)
+
+(def-cider-selector-method ?p
+  "CIDER profiler buffer."
+  cider-profile-buffer)
+
+(def-cider-selector-method ?d
+  "*cider-doc* buffer."
+  cider-doc-buffer)
+
+(def-cider-selector-method ?s
+  "*cider-scratch* buffer."
+  (cider-scratch-find-or-create-buffer))
+
+(provide 'cider-selector)
+
+;;; cider-selector.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-selector.elc b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-selector.elc
new file mode 100644
index 0000000000..8947ee9870
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-selector.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-stacktrace.el b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-stacktrace.el
new file mode 100644
index 0000000000..5daed06cc8
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-stacktrace.el
@@ -0,0 +1,899 @@
+;;; cider-stacktrace.el --- Stacktrace navigator -*- lexical-binding: t -*-
+
+;; Copyright © 2014-2018 Jeff Valk, Bozhidar Batsov and CIDER contributors
+
+;; Author: Jeff Valk <jv@jeffvalk.com>
+
+;; This program 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.
+
+;; This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+
+;; This file is not part of GNU Emacs.
+
+;;; Commentary:
+
+;; Stacktrace filtering and stack frame source navigation
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'cider-popup)
+(require 'button)
+(require 'easymenu)
+(require 'cider-common)
+(require 'subr-x)
+(require 'cider-compat)
+(require 'cider-client)
+(require 'cider-util)
+
+(require 'seq)
+
+;; Variables
+
+(defgroup cider-stacktrace nil
+  "Stacktrace filtering and navigation."
+  :prefix "cider-stacktrace-"
+  :group 'cider)
+
+(defcustom cider-stacktrace-fill-column t
+  "Fill column for error messages in stacktrace display.
+If nil, messages will not be wrapped.  If truthy but non-numeric,
+`fill-column' will be used."
+  :type 'list
+  :group 'cider-stacktrace
+  :package-version '(cider . "0.7.0"))
+
+(defcustom cider-stacktrace-default-filters '(tooling dup)
+  "Frame types to omit from initial stacktrace display."
+  :type 'list
+  :group 'cider-stacktrace
+  :package-version '(cider . "0.6.0"))
+
+(defcustom cider-stacktrace-print-length 50
+  "Set the maximum length of sequences in displayed cause data.
+
+This sets the value of Clojure's `*print-length*` when pretty printing the
+`ex-data` map for exception causes in the stacktrace that are instances of
+`IExceptionInfo`.
+
+Be advised that setting this to `nil` will cause the attempted printing of
+infinite data structures."
+  :type '(choice integer (const nil))
+  :group 'cider-stacktrace
+  :package-version '(cider . "0.9.0"))
+
+(defcustom cider-stacktrace-print-level 50
+  "Set the maximum level of nesting in displayed cause data.
+
+This sets the value of Clojure's `*print-level*` when pretty printing the
+`ex-data` map for exception causes in the stacktrace that are instances of
+`IExceptionInfo`.
+
+Be advised that setting this to `nil` will cause the attempted printing of
+cyclical data structures."
+  :type '(choice integer (const nil))
+  :group 'cider-stacktrace
+  :package-version '(cider . "0.8.0"))
+
+(defvar cider-stacktrace-detail-max 2
+  "The maximum detail level for causes.")
+
+(defvar-local cider-stacktrace-hidden-frame-count 0)
+(defvar-local cider-stacktrace-filters nil)
+(defvar-local cider-stacktrace-cause-visibility nil)
+(defvar-local cider-stacktrace-positive-filters nil)
+
+(defconst cider-error-buffer "*cider-error*")
+
+(make-obsolete 'cider-visit-error-buffer 'cider-selector "0.18")
+
+(defcustom cider-stacktrace-suppressed-errors '()
+  "Errors that won't make the stacktrace buffer 'pop-over' your active window.
+The error types are represented as strings."
+  :type 'list
+  :group 'cider-stacktrace
+  :package-version '(cider . "0.12.0"))
+
+;; Faces
+
+(defface cider-stacktrace-error-class-face
+  '((t (:inherit font-lock-warning-face)))
+  "Face for exception class names"
+  :group 'cider-stacktrace
+  :package-version '(cider . "0.6.0"))
+
+(defface cider-stacktrace-error-message-face
+  '((t (:inherit font-lock-doc-face)))
+  "Face for exception messages"
+  :group 'cider-stacktrace
+  :package-version '(cider . "0.7.0"))
+
+(defface cider-stacktrace-filter-active-face
+  '((t (:inherit button :underline t :weight normal)))
+  "Face for filter buttons representing frames currently visible"
+  :group 'cider-stacktrace
+  :package-version '(cider . "0.6.0"))
+
+(defface cider-stacktrace-filter-inactive-face
+  '((t (:inherit button :underline nil :weight normal)))
+  "Face for filter buttons representing frames currently filtered out"
+  :group 'cider-stacktrace
+  :package-version '(cider . "0.6.0"))
+
+(defface cider-stacktrace-face
+  '((t (:inherit default)))
+  "Face for stack frame text"
+  :group 'cider-stacktrace
+  :package-version '(cider . "0.6.0"))
+
+(defface cider-stacktrace-ns-face
+  '((t (:inherit font-lock-comment-face)))
+  "Face for stack frame namespace name"
+  :group 'cider-stacktrace
+  :package-version '(cider . "0.6.0"))
+
+(defface cider-stacktrace-fn-face
+  '((t (:inherit default :weight bold)))
+  "Face for stack frame function name"
+  :group 'cider-stacktrace
+  :package-version '(cider . "0.6.0"))
+
+(defface cider-stacktrace-promoted-button-face
+  '((((type graphic))
+     :box (:line-width 3 :style released-button)
+     :inherit error)
+    (t :inverse-video t))
+  "A button with this face represents a promoted (non-suppressed) error type."
+  :group 'cider-stacktrace
+  :package-version '(cider . "0.12.0"))
+
+(defface cider-stacktrace-suppressed-button-face
+  '((((type graphic))
+     :box (:line-width 3 :style pressed-button)
+     :inherit widget-inactive)
+    (t :inverse-video t))
+  "A button with this face represents a suppressed error type."
+  :group 'cider-stacktrace
+  :package-version '(cider . "0.12.0"))
+
+;; Colors & Theme Support
+
+(defvar cider-stacktrace-frames-background-color
+  (cider-scale-background-color)
+  "Background color for stacktrace frames.")
+
+(defadvice enable-theme (after cider-stacktrace-adapt-to-theme activate)
+  "When theme is changed, update `cider-stacktrace-frames-background-color'."
+  (setq cider-stacktrace-frames-background-color (cider-scale-background-color)))
+
+
+(defadvice disable-theme (after cider-stacktrace-adapt-to-theme activate)
+  "When theme is disabled, update `cider-stacktrace-frames-background-color'."
+  (setq cider-stacktrace-frames-background-color (cider-scale-background-color)))
+
+
+;; Mode & key bindings
+
+(defvar cider-stacktrace-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "M-p") #'cider-stacktrace-previous-cause)
+    (define-key map (kbd "M-n") #'cider-stacktrace-next-cause)
+    (define-key map (kbd "M-.") #'cider-stacktrace-jump)
+    (define-key map "q" #'cider-popup-buffer-quit-function)
+    (define-key map "j" #'cider-stacktrace-toggle-java)
+    (define-key map "c" #'cider-stacktrace-toggle-clj)
+    (define-key map "r" #'cider-stacktrace-toggle-repl)
+    (define-key map "t" #'cider-stacktrace-toggle-tooling)
+    (define-key map "d" #'cider-stacktrace-toggle-duplicates)
+    (define-key map "p" #'cider-stacktrace-show-only-project)
+    (define-key map "a" #'cider-stacktrace-toggle-all)
+    (define-key map "1" #'cider-stacktrace-cycle-cause-1)
+    (define-key map "2" #'cider-stacktrace-cycle-cause-2)
+    (define-key map "3" #'cider-stacktrace-cycle-cause-3)
+    (define-key map "4" #'cider-stacktrace-cycle-cause-4)
+    (define-key map "5" #'cider-stacktrace-cycle-cause-5)
+    (define-key map "0" #'cider-stacktrace-cycle-all-causes)
+    (define-key map (kbd "TAB") #'cider-stacktrace-cycle-current-cause)
+    (define-key map [backtab] #'cider-stacktrace-cycle-all-causes)
+    (easy-menu-define cider-stacktrace-mode-menu map
+      "Menu for CIDER's stacktrace mode"
+      '("Stacktrace"
+        ["Previous cause" cider-stacktrace-previous-cause]
+        ["Next cause" cider-stacktrace-next-cause]
+        "--"
+        ["Jump to frame source" cider-stacktrace-jump]
+        "--"
+        ["Cycle current cause detail" cider-stacktrace-cycle-current-cause]
+        ["Cycle cause #1 detail" cider-stacktrace-cycle-cause-1]
+        ["Cycle cause #2 detail" cider-stacktrace-cycle-cause-2]
+        ["Cycle cause #3 detail" cider-stacktrace-cycle-cause-3]
+        ["Cycle cause #4 detail" cider-stacktrace-cycle-cause-4]
+        ["Cycle cause #5 detail" cider-stacktrace-cycle-cause-5]
+        ["Cycle all cause detail" cider-stacktrace-cycle-all-causes]
+        "--"
+        ["Show/hide Java frames" cider-stacktrace-toggle-java]
+        ["Show/hide Clojure frames" cider-stacktrace-toggle-clj]
+        ["Show/hide REPL frames" cider-stacktrace-toggle-repl]
+        ["Show/hide tooling frames" cider-stacktrace-toggle-tooling]
+        ["Show/hide duplicate frames" cider-stacktrace-toggle-duplicates]
+        ["Toggle only project frames" cider-stacktrace-show-only-project]
+        ["Show/hide all frames" cider-stacktrace-toggle-all]))
+    map))
+
+(define-derived-mode cider-stacktrace-mode special-mode "Stacktrace"
+  "Major mode for filtering and navigating CIDER stacktraces.
+
+\\{cider-stacktrace-mode-map}"
+  (when cider-special-mode-truncate-lines
+    (setq-local truncate-lines t))
+  (setq-local sesman-system 'CIDER)
+  (setq-local electric-indent-chars nil)
+  (setq-local cider-stacktrace-hidden-frame-count 0)
+  (setq-local cider-stacktrace-filters cider-stacktrace-default-filters)
+  (setq-local cider-stacktrace-cause-visibility (make-vector 10 0)))
+
+
+;; Stacktrace filtering
+
+(defvar cider-stacktrace--all-negative-filters
+  '(clj tooling dup java repl)
+  "Filters that remove stackframes.")
+
+(defvar cider-stacktrace--all-positive-filters
+  '(project all)
+  "Filters that ensure stackframes are shown.")
+
+(defun cider-stacktrace--face-for-filter (filter neg-filters pos-filters)
+  "Return whether we should mark the FILTER is active or not.
+
+NEG-FILTERS and POS-FILTERS are lists of filters to check FILTER's type.
+
+NEG-FILTERS dictate which frames should be hidden while POS-FILTERS can
+override this and ensure that those frames are shown."
+  (cond ((member filter cider-stacktrace--all-negative-filters)
+         (if (member filter neg-filters)
+             'cider-stacktrace-filter-active-face
+           'cider-stacktrace-filter-inactive-face))
+        ((member filter cider-stacktrace--all-positive-filters)
+         (if (member filter pos-filters)
+             'cider-stacktrace-filter-active-face
+           'cider-stacktrace-filter-inactive-face))))
+
+(defun cider-stacktrace-indicate-filters (filters pos-filters)
+  "Update enabled state of filter buttons.
+
+Find buttons with a 'filter property; if filter is a member of FILTERS, or
+if filter is nil ('show all') and the argument list is non-nil, fontify the
+button as disabled.  Upon finding text with a 'hidden-count property, stop
+searching and update the hidden count text.  POS-FILTERS is the list of
+positive filters to always include."
+  (with-current-buffer cider-error-buffer
+    (save-excursion
+      (goto-char (point-min))
+      (let ((inhibit-read-only t))
+        ;; Toggle buttons
+        (while (not (or (get-text-property (point) 'hidden-count) (eobp)))
+          (let ((button (button-at (point))))
+            (when button
+              (let* ((filter (button-get button 'filter))
+                     (face (cider-stacktrace--face-for-filter filter
+                                                              filters
+                                                              pos-filters)))
+                (button-put button 'face face)))
+            (goto-char (or (next-property-change (point))
+                           (point-max)))))
+        ;; Update hidden count
+        (when (and (get-text-property (point) 'hidden-count)
+                   (re-search-forward "[0-9]+" (line-end-position) t))
+          (replace-match
+           (number-to-string cider-stacktrace-hidden-frame-count)))))))
+
+(defun cider-stacktrace-frame-p ()
+  "Indicate if the text at point is a stack frame."
+  (get-text-property (point) 'cider-stacktrace-frame))
+
+(defun cider-stacktrace-collapsed-p ()
+  "Indicate if the stackframe was collapsed."
+  (get-text-property (point) 'collapsed))
+
+(defun cider-stacktrace--should-hide-p (neg-filters pos-filters flags)
+  "Decide whether a stackframe should be hidden or not.
+NEG-FILTERS dictate which frames should be hidden while POS-FILTERS can
+override this and ensure that those frames are shown.
+Argument FLAGS are the flags set on the stackframe, ie: clj dup, etc."
+  (let ((neg (seq-intersection neg-filters flags))
+        (pos (seq-intersection pos-filters flags))
+        (all (memq 'all pos-filters)))
+    (cond (all nil) ;; if all filter is on then we should not hide
+          ((and pos neg) nil) ;; if hidden and "resurrected" we should not hide
+          (pos nil)
+          (neg t)
+          (t nil))))
+
+(defun cider-stacktrace--apply-filters (neg-filters pos-filters)
+  "Set visibility on stack frames.
+Should be called by `cider-stacktrace-apply-filters' which has the logic of
+how to interpret the combinations of the positive and negative filters.
+For instance, the presence of the positive filter `project' requires all of
+the other negative filters to be applied so that only project frames are
+shown.  NEG-FILTERS are the tags that should be hidden.  POS-FILTERS are
+the tags that must be shown."
+  (with-current-buffer cider-error-buffer
+    (save-excursion
+      (goto-char (point-min))
+      (let ((inhibit-read-only t)
+            (hidden 0))
+        (while (not (eobp))
+          (when (and (cider-stacktrace-frame-p)
+                     (not (cider-stacktrace-collapsed-p)))
+            (let* ((flags (get-text-property (point) 'flags))
+                   (hide (cider-stacktrace--should-hide-p neg-filters
+                                                          pos-filters
+                                                          flags)))
+              (when hide (cl-incf hidden))
+              (put-text-property (point) (line-beginning-position 2)
+                                 'invisible hide)))
+          (forward-line 1))
+        (setq cider-stacktrace-hidden-frame-count hidden)))
+    (cider-stacktrace-indicate-filters neg-filters pos-filters)))
+
+(defun cider-stacktrace-apply-filters (filters)
+  "Takes a single list of filters and applies them.
+Update `cider-stacktrace-hidden-frame-count' and indicate
+filters applied.  Currently collapsed stacktraces are ignored, and do not
+contribute to the hidden count.  FILTERS is the list of filters to be
+applied, positive and negative all together.  This function defines how
+those choices interact and separates them into positive and negative
+filters for the resulting machinery."
+  (let ((neg-filters (seq-intersection filters cider-stacktrace--all-negative-filters))
+        (pos-filters (seq-intersection filters cider-stacktrace--all-positive-filters)))
+    ;; project and all are mutually exclusive. when both are present we check to
+    ;; see the most recent one (as cons onto the list would put it) and use that
+    ;; interaction.
+    (cond
+     ((memq 'all (memq 'project pos-filters)) ;; project is most recent
+      (cider-stacktrace--apply-filters cider-stacktrace--all-negative-filters '(project)))
+     ((memq 'project (memq 'all pos-filters)) ;; all is most recent
+      (cider-stacktrace--apply-filters nil '(all)))
+     ((memq 'all pos-filters) (cider-stacktrace--apply-filters nil '(all)))
+     ((memq 'project pos-filters) (cider-stacktrace--apply-filters cider-stacktrace--all-negative-filters
+                                                                   pos-filters))
+     (t (cider-stacktrace--apply-filters neg-filters pos-filters)))))
+
+(defun cider-stacktrace-apply-cause-visibility ()
+  "Apply `cider-stacktrace-cause-visibility' to causes and reapply filters."
+  (with-current-buffer cider-error-buffer
+    (save-excursion
+      (goto-char (point-min))
+      (cl-flet ((next-detail (end)
+                             (when-let* ((pos (next-single-property-change (point) 'detail)))
+                               (when (< pos end)
+                                 (goto-char pos)))))
+        (let ((inhibit-read-only t))
+          ;; For each cause...
+          (while (cider-stacktrace-next-cause)
+            (let* ((num   (get-text-property (point) 'cause))
+                   (level (elt cider-stacktrace-cause-visibility num))
+                   (cause-end (cadr (cider-property-bounds 'cause))))
+              ;; For each detail level within the cause, set visibility.
+              (while (next-detail cause-end)
+                (let* ((detail (get-text-property (point) 'detail))
+                       (detail-end (cadr (cider-property-bounds 'detail)))
+                       (hide (if (> detail level) t nil)))
+                  (add-text-properties (point) detail-end
+                                       (list 'invisible hide
+                                             'collapsed hide))))))))
+      (cider-stacktrace-apply-filters cider-stacktrace-filters))))
+
+;;; Internal/Middleware error suppression
+
+(defun cider-stacktrace-some-suppressed-errors-p (error-types)
+  "Return intersection of ERROR-TYPES and CIDER-STACKTRACE-SUPPRESSED-ERRORS.
+I.e, Return non-nil if the seq ERROR-TYPES shares any elements with
+`cider-stacktrace-suppressed-errors'.  This means that even a
+'well-behaved' (ie, promoted) error type will be 'guilty by association' if
+grouped with a suppressed error type."
+  (seq-intersection error-types cider-stacktrace-suppressed-errors))
+
+(defun cider-stacktrace-suppress-error (error-type)
+  "Destructively add element ERROR-TYPE to the `cider-stacktrace-suppressed-errors' set."
+  (setq cider-stacktrace-suppressed-errors
+        (cl-adjoin error-type cider-stacktrace-suppressed-errors :test 'equal)))
+
+(defun cider-stacktrace-promote-error (error-type)
+  "Destructively remove element ERROR-TYPE from the `cider-stacktrace-suppressed-errors' set."
+  (setq cider-stacktrace-suppressed-errors
+        (remove error-type cider-stacktrace-suppressed-errors)))
+
+(defun cider-stacktrace-suppressed-error-p (error-type)
+  "Return non-nil if element ERROR-TYPE is a member of the `cider-stacktrace-suppressed-errors' set."
+  (member error-type cider-stacktrace-suppressed-errors))
+
+;; Interactive functions
+
+(defun cider-stacktrace-previous-cause ()
+  "Move point to the previous exception cause, if one exists."
+  (interactive)
+  (with-current-buffer cider-error-buffer
+    (when-let* ((pos (previous-single-property-change (point) 'cause)))
+      (goto-char pos))))
+
+(defun cider-stacktrace-next-cause ()
+  "Move point to the next exception cause, if one exists."
+  (interactive)
+  (with-current-buffer cider-error-buffer
+    (when-let* ((pos (next-single-property-change (point) 'cause)))
+      (goto-char pos))))
+
+(defun cider-stacktrace-cycle-cause (num &optional level)
+  "Update element NUM of `cider-stacktrace-cause-visibility'.
+If LEVEL is specified, it is useed, otherwise its current value is incremented.
+When it reaches 3, it wraps to 0."
+  (let ((level (or level (1+ (elt cider-stacktrace-cause-visibility num)))))
+    (aset cider-stacktrace-cause-visibility num (mod level 3))
+    (cider-stacktrace-apply-cause-visibility)))
+
+(defun cider-stacktrace-cycle-all-causes ()
+  "Cycle the visibility of all exception causes."
+  (interactive)
+  (with-current-buffer cider-error-buffer
+    (save-excursion
+      ;; Find nearest cause.
+      (unless (get-text-property (point) 'cause)
+        (cider-stacktrace-next-cause)
+        (unless (get-text-property (point) 'cause)
+          (cider-stacktrace-previous-cause)))
+      ;; Cycle its level, and apply that to all causes.
+      (let* ((num (get-text-property (point) 'cause))
+             (level (1+ (elt cider-stacktrace-cause-visibility num))))
+        (setq-local cider-stacktrace-cause-visibility
+                    (make-vector 10 (mod level 3)))
+        (cider-stacktrace-apply-cause-visibility)))))
+
+(defun cider-stacktrace-cycle-current-cause ()
+  "Cycle the visibility of current exception at point, if any."
+  (interactive)
+  (with-current-buffer cider-error-buffer
+    (when-let* ((num (get-text-property (point) 'cause)))
+      (cider-stacktrace-cycle-cause num))))
+
+(defun cider-stacktrace-cycle-cause-1 ()
+  "Cycle the visibility of exception cause #1."
+  (interactive)
+  (cider-stacktrace-cycle-cause 1))
+
+(defun cider-stacktrace-cycle-cause-2 ()
+  "Cycle the visibility of exception cause #2."
+  (interactive)
+  (cider-stacktrace-cycle-cause 2))
+
+(defun cider-stacktrace-cycle-cause-3 ()
+  "Cycle the visibility of exception cause #3."
+  (interactive)
+  (cider-stacktrace-cycle-cause 3))
+
+(defun cider-stacktrace-cycle-cause-4 ()
+  "Cycle the visibility of exception cause #4."
+  (interactive)
+  (cider-stacktrace-cycle-cause 4))
+
+(defun cider-stacktrace-cycle-cause-5 ()
+  "Cycle the visibility of exception cause #5."
+  (interactive)
+  (cider-stacktrace-cycle-cause 5))
+
+(defun cider-stacktrace-toggle (flag)
+  "Update `cider-stacktrace-filters' to add or remove FLAG, and apply filters."
+  (cider-stacktrace-apply-filters
+   (setq cider-stacktrace-filters
+         (if (memq flag cider-stacktrace-filters)
+             (remq flag cider-stacktrace-filters)
+           (cons flag cider-stacktrace-filters)))))
+
+(defun cider-stacktrace-toggle-all ()
+  "Toggle `all' in filter list."
+  (interactive)
+  (cider-stacktrace-toggle 'all))
+
+(defun cider-stacktrace-show-only-project ()
+  "Display only the stackframes from the project."
+  (interactive)
+  (cider-stacktrace-toggle 'project))
+
+(defun cider-stacktrace-toggle-java ()
+  "Toggle display of Java stack frames."
+  (interactive)
+  (cider-stacktrace-toggle 'java))
+
+(defun cider-stacktrace-toggle-clj ()
+  "Toggle display of Clojure stack frames."
+  (interactive)
+  (cider-stacktrace-toggle 'clj))
+
+(defun cider-stacktrace-toggle-repl ()
+  "Toggle display of REPL stack frames."
+  (interactive)
+  (cider-stacktrace-toggle 'repl))
+
+(defun cider-stacktrace-toggle-tooling ()
+  "Toggle display of Tooling stack frames (compiler, nREPL middleware, etc)."
+  (interactive)
+  (cider-stacktrace-toggle 'tooling))
+
+(defun cider-stacktrace-toggle-duplicates ()
+  "Toggle display of stack frames that are duplicates of their descendents."
+  (interactive)
+  (cider-stacktrace-toggle 'dup))
+
+;; Text button functions
+
+(defun cider-stacktrace-filter (button)
+  "Apply filter(s) indicated by the BUTTON."
+  (with-temp-message "Filters may also be toggled with the keyboard."
+    (let ((flag (button-get button 'filter)))
+      (cond ((member flag cider-stacktrace--all-negative-filters)
+             (cider-stacktrace-toggle flag))
+            ((member flag cider-stacktrace--all-positive-filters)
+             (cider-stacktrace-show-only-project))
+            (t (cider-stacktrace-toggle-all))))
+    (sit-for 5)))
+
+(defun cider-stacktrace-toggle-suppression (button)
+  "Toggle stacktrace pop-over/pop-under behavior for the `error-type' in BUTTON.
+Achieved by destructively manipulating the `cider-stacktrace-suppressed-errors' set."
+  (with-current-buffer cider-error-buffer
+    (let ((inhibit-read-only t)
+          (suppressed (button-get button 'suppressed))
+          (error-type (button-get button 'error-type)))
+      (if suppressed
+          (progn
+            (cider-stacktrace-promote-error error-type)
+            (button-put button 'face 'cider-stacktrace-promoted-button-face)
+            (button-put button 'help-echo "Click to suppress these stacktraces."))
+        (cider-stacktrace-suppress-error error-type)
+        (button-put button 'face 'cider-stacktrace-suppressed-button-face)
+        (button-put button 'help-echo "Click to promote these stacktraces."))
+      (button-put button 'suppressed (not suppressed)))))
+
+(defun cider-stacktrace-navigate (button)
+  "Navigate to the stack frame source represented by the BUTTON."
+  (let* ((var (button-get button 'var))
+         (class (button-get button 'class))
+         (method (button-get button 'method))
+         (info (or (and var (cider-var-info var))
+                   (and class method (cider-member-info class method))
+                   (nrepl-dict)))
+         ;; Stacktrace returns more accurate line numbers, but if the function's
+         ;; line was unreliable, then so is the stacktrace by the same amount.
+         ;; Set `line-shift' to the number of lines from the beginning of defn.
+         (line-shift (- (or (button-get button 'line) 0)
+                        (or (nrepl-dict-get info "line") 1)))
+         (file (or
+                (and (null var) (cider-resolve-java-class class))
+                (nrepl-dict-get info "file")
+                (button-get button 'file)))
+         ;; give priority to `info` files as `info` returns full paths.
+         (info (nrepl-dict-put info "file" file)))
+    (cider--jump-to-loc-from-info info t)
+    (forward-line line-shift)
+    (back-to-indentation)))
+
+(declare-function cider-find-var "cider-find")
+
+(defun cider-stacktrace-jump (&optional arg)
+  "Find definition for stack frame at point, if available.
+The prefix ARG and `cider-prompt-for-symbol' decide whether to
+prompt and whether to use a new window.  Similar to `cider-find-var'."
+  (interactive "P")
+  (let ((button (button-at (point))))
+    (if (and button (button-get button 'line))
+        (cider-stacktrace-navigate button)
+      (cider-find-var arg))))
+
+
+;; Rendering
+
+(defun cider-stacktrace-emit-indented (text &optional indent fill fontify)
+  "Insert TEXT, and optionally FILL and FONTIFY as clojure the entire block.
+INDENT is a string to insert before each line.  When INDENT is nil, first
+line is not indented and INDENT defaults to a white-spaced string with
+length given by `current-column'."
+  (let ((text (if fontify
+                  (cider-font-lock-as-clojure text)
+                text))
+        (do-first indent)
+        (indent (or indent (make-string (current-column) ? )))
+        (beg (point)))
+    (insert text)
+    (goto-char beg)
+    (when do-first
+      (insert indent))
+    (forward-line)
+    (while (not (eobp))
+      (insert indent)
+      (forward-line))
+    (when (and fill cider-stacktrace-fill-column)
+      (when (and (numberp cider-stacktrace-fill-column))
+        (setq-local fill-column cider-stacktrace-fill-column))
+      (setq-local fill-prefix indent)
+      (fill-region beg (point)))))
+
+(defun cider-stacktrace-render-filters (buffer special-filters filters)
+  "Emit into BUFFER toggle buttons for each of the FILTERS.
+SPECIAL-FILTERS are filters that show stack certain stack frames, hiding
+others."
+  (with-current-buffer buffer
+    (insert "  Show: ")
+    (dolist (filter special-filters)
+      (insert-text-button (car filter)
+                          'filter (cadr filter)
+                          'follow-link t
+                          'action 'cider-stacktrace-filter
+                          'help-echo (format "Toggle %s stack frames"
+                                             (car filter)))
+      (insert " "))
+    (insert "\n")
+    (insert "  Hide: ")
+    (dolist (filter filters)
+      (insert-text-button (car filter)
+                          'filter (cadr filter)
+                          'follow-link t
+                          'action 'cider-stacktrace-filter
+                          'help-echo (format "Toggle %s stack frames"
+                                             (car filter)))
+      (insert " "))
+
+    (let ((hidden "(0 frames hidden)"))
+      (put-text-property 0 (length hidden) 'hidden-count t hidden)
+      (insert " " hidden "\n"))))
+
+(defun cider-stacktrace-render-suppression-toggle (buffer error-types)
+  "Emit into BUFFER toggle buttons for each of the ERROR-TYPES leading this stacktrace buffer."
+  (with-current-buffer buffer
+    (when error-types
+      (insert "  This is an unexpected CIDER middleware error.\n  Please submit a bug report via `")
+      (insert-text-button "M-x cider-report-bug"
+                          'follow-link t
+                          'action (lambda (_button) (cider-report-bug))
+                          'help-echo "Report bug to the CIDER team.")
+      (insert "`.\n\n")
+      (insert "\
+  If these stacktraces are occuring frequently, consider using the
+  button(s) below to suppress these types of errors for the duration of
+  your current CIDER session. The stacktrace buffer will still be
+  generated, but it will \"pop under\" your current buffer instead of
+  \"popping over\". The button toggles this behavior.\n\n ")
+      (dolist (error-type error-types)
+        (let ((suppressed (cider-stacktrace-suppressed-error-p error-type)))
+          (insert-text-button (format "%s %s" (if suppressed "Promote" "Suppress") error-type)
+                              'follow-link t
+                              'error-type error-type
+                              'action 'cider-stacktrace-toggle-suppression
+                              'suppressed suppressed
+                              'face (if suppressed
+                                        'cider-stacktrace-suppressed-button-face
+                                      'cider-stacktrace-promoted-button-face)
+                              'help-echo (format "Click to %s these stacktraces."
+                                                 (if suppressed "promote" "suppress"))))
+        (insert " ")))))
+
+(defun cider-stacktrace-render-frame (buffer frame)
+  "Emit into BUFFER function call site info for the stack FRAME.
+This associates text properties to enable filtering and source navigation."
+  (with-current-buffer buffer
+    (nrepl-dbind-response frame (file line flags class method name var ns fn)
+      (let ((flags (mapcar 'intern flags))) ; strings -> symbols
+        (insert-text-button (format "%26s:%5d  %s/%s"
+                                    (if (member 'repl flags) "REPL" file) line
+                                    (if (member 'clj flags) ns class)
+                                    (if (member 'clj flags) fn method))
+                            'var var 'class class 'method method
+                            'name name 'file file 'line line
+                            'flags flags 'follow-link t
+                            'action 'cider-stacktrace-navigate
+                            'help-echo "View source at this location"
+                            'font-lock-face 'cider-stacktrace-face
+                            'type 'cider-plain-button)
+        (save-excursion
+          (let ((p4 (point))
+                (p1 (search-backward " "))
+                (p2 (search-forward "/"))
+                (p3 (search-forward-regexp "[^/$]+")))
+            (put-text-property p1 p4 'font-lock-face 'cider-stacktrace-ns-face)
+            (put-text-property p2 p3 'font-lock-face 'cider-stacktrace-fn-face)
+            (put-text-property (line-beginning-position) (line-end-position)
+                               'cider-stacktrace-frame t)))
+        (insert "\n")))))
+
+(defun cider-stacktrace-render-compile-error (buffer cause)
+  "Emit into BUFFER the compile error CAUSE, and enable jumping to it."
+  (with-current-buffer buffer
+    (nrepl-dbind-response cause (file path line column)
+      (let ((indent "   ")
+            (message-face 'cider-stacktrace-error-message-face))
+        (insert indent)
+        (insert (propertize "Error compiling " 'font-lock-face  message-face))
+        (insert-text-button path 'compile-error t
+                            'file file 'line line 'column column 'follow-link t
+                            'action (lambda (_button)
+                                      (cider-jump-to (cider-find-file file)
+                                                     (cons line column))))
+        (insert (propertize (format " at (%d:%d)" line column)
+                            'font-lock-face message-face))))))
+
+(defun cider-stacktrace--toggle-visibility (id)
+  "Toggle visibility of the region with ID invisibility prop.
+ID can also be a button, in which case button's property :id is used
+instead.  This function can be used directly in button actions."
+  (let ((id (if (or (numberp id) (symbolp id))
+                ;; There is no proper way to identify buttons. Assuming that
+                ;; id's can be either numbers or symbols.
+                id
+              (button-get id :id))))
+    (if (and (consp buffer-invisibility-spec)
+             (assoc id buffer-invisibility-spec))
+        (remove-from-invisibility-spec (cons id t))
+      (add-to-invisibility-spec (cons id t)))))
+
+(defun cider-stacktrace--insert-named-group (indent name &rest vals)
+  "Insert named group with the ability to toggle visibility.
+NAME is a string naming the group.  VALS are strings to be inserted after
+the NAME.  The whole group is prefixed by string INDENT."
+  (let* ((str (and vals (replace-regexp-in-string "\n+\\'" "" (apply #'concat vals))))
+         (id (and str
+                  (string-match "\n" str)
+                  (cl-gensym name))))
+    (insert indent)
+    (if id
+        (let* ((beg-link (string-match "[^ :]" name))
+               (end-link (string-match "[ :]" name (1+ beg-link))))
+          (insert (substring name 0 beg-link))
+          (insert-text-button (substring name beg-link end-link)
+                              :id id
+                              'face '((:weight bold) (:underline t))
+                              'follow-link t
+                              'help-echo "Toggle visibility"
+                              'action #'cider-stacktrace--toggle-visibility)
+          (insert (substring name end-link)))
+      (insert (propertize name 'face '((:weight bold)))))
+    (let ((pos (point)))
+      (when str
+        (cider-stacktrace-emit-indented (concat str "\n") nil nil t)
+        (when id
+          (remove-from-invisibility-spec (cons id t))
+          (let ((hide-beg (save-excursion (goto-char pos) (point-at-eol)))
+                (hide-end (1- (point-at-bol))))
+            (overlay-put (make-overlay hide-beg hide-end) 'invisible id)))))))
+
+(defun cider-stacktrace--emit-spec-problems (spec-data indent)
+  "Emit SPEC-DATA indented with INDENT."
+  (nrepl-dbind-response spec-data (spec value problems)
+    (insert "\n")
+    (cider-stacktrace--insert-named-group indent "    Spec: " spec)
+    (cider-stacktrace--insert-named-group indent "   Value: " value)
+    (insert "\n")
+    (cider-stacktrace--insert-named-group indent "Problems: \n")
+    (let ((indent2 (concat indent "    ")))
+      (dolist (prob problems)
+        (nrepl-dbind-response prob (in val predicate reason spec at extra)
+          (insert "\n")
+          (when (not (string= val value))
+            (cider-stacktrace--insert-named-group indent2 "   val: " val))
+          (when in
+            (cider-stacktrace--insert-named-group indent2 "    in: " in))
+          (cider-stacktrace--insert-named-group indent2   "failed: " predicate)
+          (when spec
+            (cider-stacktrace--insert-named-group indent2 "  spec: " spec))
+          (when at
+            (cider-stacktrace--insert-named-group indent2 "    at: " at))
+          (when reason
+            (cider-stacktrace--insert-named-group indent2 "reason: " reason))
+          (when extra
+            (cider-stacktrace--insert-named-group indent2 "extras: \n")
+            (cider-stacktrace-emit-indented extra (concat indent2 "  ") nil t)))))))
+
+(defun cider-stacktrace-render-cause (buffer cause num note)
+  "Emit into BUFFER the CAUSE NUM, exception class, message, data, and NOTE."
+  (with-current-buffer buffer
+    (nrepl-dbind-response cause (class message data spec stacktrace)
+      (let ((indent "   ")
+            (class-face 'cider-stacktrace-error-class-face)
+            (message-face 'cider-stacktrace-error-message-face))
+        (cider-propertize-region `(cause ,num)
+          ;; Detail level 0: exception class
+          (cider-propertize-region '(detail 0)
+            (insert (format "%d. " num)
+                    (propertize note 'font-lock-face 'font-lock-comment-face) " "
+                    (propertize class 'font-lock-face class-face)
+                    "\n"))
+          ;; Detail level 1: message + ex-data
+          (cider-propertize-region '(detail 1)
+            (if (equal class "clojure.lang.Compiler$CompilerException")
+                (cider-stacktrace-render-compile-error buffer cause)
+              (cider-stacktrace-emit-indented
+               (propertize (or message "(No message)")
+                           'font-lock-face  message-face)
+               indent t))
+            (insert "\n")
+            (when spec
+              (cider-stacktrace--emit-spec-problems spec (concat indent "  ")))
+            (when data
+              (cider-stacktrace-emit-indented data indent nil t)))
+          ;; Detail level 2: stacktrace
+          (cider-propertize-region '(detail 2)
+            (insert "\n")
+            (let ((beg (point))
+                  (bg `(:background ,cider-stacktrace-frames-background-color)))
+              (dolist (frame stacktrace)
+                (cider-stacktrace-render-frame buffer frame))
+              (overlay-put (make-overlay beg (point)) 'font-lock-face bg)))
+          ;; Add line break between causes, even when collapsed.
+          (cider-propertize-region '(detail 0)
+            (insert "\n")))))))
+
+(defun cider-stacktrace-initialize (causes)
+  "Set and apply CAUSES initial visibility, filters, and cursor position."
+  (nrepl-dbind-response (car causes) (class)
+    (let ((compile-error-p (equal class "clojure.lang.Compiler$CompilerException")))
+      ;; Partially display outermost cause if it's a compiler exception (the
+      ;; description reports reader location of the error).
+      (when compile-error-p
+        (cider-stacktrace-cycle-cause (length causes) 1))
+      ;; Fully display innermost cause. This also applies visibility/filters.
+      (cider-stacktrace-cycle-cause 1 cider-stacktrace-detail-max)
+      ;; Move point (DWIM) to the compile error location if present, or to the
+      ;; first stacktrace frame in displayed cause otherwise. If the error
+      ;; buffer is visible in a window, ensure that window is selected while moving
+      ;; point, so as to move both the buffer's and the window's point.
+      (with-selected-window (or (get-buffer-window cider-error-buffer)
+                                (selected-window))
+        (with-current-buffer cider-error-buffer
+          (goto-char (point-min))
+          (if compile-error-p
+              (goto-char (next-single-property-change (point) 'compile-error))
+            (progn
+              (while (cider-stacktrace-next-cause))
+              (goto-char (next-single-property-change (point) 'flags)))))))))
+
+(defun cider-stacktrace-render (buffer causes &optional error-types)
+  "Emit into BUFFER useful stacktrace information for the CAUSES.
+Takes an optional ERROR-TYPES list which will render a 'suppression' toggle
+that alters the pop-over/pop-under behavorior of the stacktrace buffers
+created by these types of errors.  The suppressed errors set can be customized
+through the `cider-stacktrace-suppressed-errors' variable."
+  (with-current-buffer buffer
+    (let ((inhibit-read-only t))
+      (erase-buffer)
+      (insert "\n")
+      ;; Stacktrace filters
+      (cider-stacktrace-render-filters
+       buffer
+       `(("Project-Only" project) ("All" all))
+       `(("Clojure" clj) ("Java" java) ("REPL" repl)
+         ("Tooling" tooling) ("Duplicates" dup)))
+      (insert "\n")
+      ;; Option to suppress internal/middleware errors
+      (when error-types
+        (cider-stacktrace-render-suppression-toggle buffer error-types)
+        (insert "\n\n"))
+      ;; Stacktrace exceptions & frames
+      (let ((num (length causes)))
+        (dolist (cause causes)
+          (let ((note (if (= num (length causes)) "Unhandled" "Caused by")))
+            (cider-stacktrace-render-cause buffer cause num note)
+            (setq num (1- num))))))
+    (cider-stacktrace-initialize causes)
+    (font-lock-refresh-defaults)))
+
+(provide 'cider-stacktrace)
+
+;;; cider-stacktrace.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-stacktrace.elc b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-stacktrace.elc
new file mode 100644
index 0000000000..b1eb7d9d0b
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-stacktrace.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-test.el b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-test.el
new file mode 100644
index 0000000000..bce6b4c066
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-test.el
@@ -0,0 +1,825 @@
+;;; cider-test.el --- Test result viewer -*- lexical-binding: t -*-
+
+;; Copyright © 2014-2018 Jeff Valk, Bozhidar Batsov and CIDER contributors
+
+;; Author: Jeff Valk <jv@jeffvalk.com>
+
+;; This program 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.
+
+;; This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+
+;; This file is not part of GNU Emacs.
+
+;;; Commentary:
+
+;; This provides execution, reporting, and navigation support for Clojure tests,
+;; specifically using the `clojure.test' machinery.  This functionality replaces
+;; the venerable `clojure-test-mode' (deprecated in June 2014), and relies on
+;; nREPL middleware for report running and session support.
+
+;;; Code:
+
+(require 'cider-common)
+(require 'cider-client)
+(require 'cider-popup)
+(require 'cider-stacktrace)
+(require 'subr-x)
+(require 'cider-compat)
+(require 'cider-overlays)
+
+(require 'button)
+(require 'cl-lib)
+(require 'easymenu)
+(require 'seq)
+
+;;; Variables
+
+(defgroup cider-test nil
+  "Presentation and navigation for test results."
+  :prefix "cider-test-"
+  :group 'cider)
+
+(defcustom cider-test-show-report-on-success nil
+  "Whether to show the `*cider-test-report*` buffer on passing tests."
+  :type 'boolean
+  :group 'cider-test
+  :package-version '(cider . "0.8.0"))
+
+(defcustom cider-auto-select-test-report-buffer t
+  "Determines if the test-report buffer should be auto-selected."
+  :type 'boolean
+  :group 'cider-test
+  :package-version '(cider . "0.9.0"))
+
+(defcustom cider-test-defining-forms '("deftest" "defspec")
+  "Forms that define individual tests.
+CIDER considers the \"top-level\" form around point to define a test if
+the form starts with one of these forms.
+Add to this list to have CIDER recognize additional test defining macros."
+  :type '(repeat string)
+  :group 'cider-test
+  :package-version '(cider . "0.15.0"))
+
+(defvar cider-test-last-summary nil
+  "The summary of the last run test.")
+
+(defvar cider-test-last-results nil
+  "The results of the last run test.")
+
+(defconst cider-test-report-buffer "*cider-test-report*"
+  "Buffer name in which to display test reports.")
+
+;;; Faces
+
+(defface cider-test-failure-face
+  '((((class color) (background light))
+     :background "orange red")
+    (((class color) (background dark))
+     :background "firebrick"))
+  "Face for failed tests."
+  :group 'cider-test
+  :package-version '(cider . "0.7.0"))
+
+(defface cider-test-error-face
+  '((((class color) (background light))
+     :background "orange1")
+    (((class color) (background dark))
+     :background "orange4"))
+  "Face for erring tests."
+  :group 'cider-test
+  :package-version '(cider . "0.7.0"))
+
+(defface cider-test-success-face
+  '((((class color) (background light))
+     :foreground "black"
+     :background "green")
+    (((class color) (background dark))
+     :foreground "black"
+     :background "green"))
+  "Face for passing tests."
+  :group 'cider-test
+  :package-version '(cider . "0.7.0"))
+
+
+;; Colors & Theme Support
+
+(defvar cider-test-items-background-color
+  (cider-scale-background-color)
+  "Background color for test assertion items.")
+
+(defadvice enable-theme (after cider-test-adapt-to-theme activate)
+  "When theme is changed, update `cider-test-items-background-color'."
+  (setq cider-test-items-background-color (cider-scale-background-color)))
+
+
+(defadvice disable-theme (after cider-test-adapt-to-theme activate)
+  "When theme is disabled, update `cider-test-items-background-color'."
+  (setq cider-test-items-background-color (cider-scale-background-color)))
+
+
+;;; Report mode & key bindings
+;;
+;; The primary mode of interacting with test results is the report buffer, which
+;; allows navigation among tests, jumping to test definitions, expected/actual
+;; diff-ing, and cause/stacktrace inspection for test errors.
+
+(defvar cider-test-commands-map
+  (let ((map (define-prefix-command 'cider-test-commands-map)))
+    ;; Duplicates of keys below with C- for convenience
+    (define-key map (kbd "C-r") #'cider-test-rerun-failed-tests)
+    (define-key map (kbd "C-t") #'cider-test-run-test)
+    (define-key map (kbd "C-g") #'cider-test-rerun-test)
+    (define-key map (kbd "C-n") #'cider-test-run-ns-tests)
+    (define-key map (kbd "C-s") #'cider-test-run-ns-tests-with-filters)
+    (define-key map (kbd "C-l") #'cider-test-run-loaded-tests)
+    (define-key map (kbd "C-p") #'cider-test-run-project-tests)
+    (define-key map (kbd "C-b") #'cider-test-show-report)
+    ;; Single-key bindings defined last for display in menu
+    (define-key map (kbd "r")   #'cider-test-rerun-failed-tests)
+    (define-key map (kbd "t")   #'cider-test-run-test)
+    (define-key map (kbd "g")   #'cider-test-rerun-test)
+    (define-key map (kbd "n")   #'cider-test-run-ns-tests)
+    (define-key map (kbd "s")   #'cider-test-run-ns-tests-with-filters)
+    (define-key map (kbd "l")   #'cider-test-run-loaded-tests)
+    (define-key map (kbd "p")   #'cider-test-run-project-tests)
+    (define-key map (kbd "b")   #'cider-test-show-report)
+    map))
+
+(defconst cider-test-menu
+  '("Test"
+    ["Run test" cider-test-run-test]
+    ["Run namespace tests" cider-test-run-ns-tests]
+    ["Run namespace tests with filters" cider-test-run-ns-tests-with-filters]
+    ["Run all loaded tests" cider-test-run-loaded-tests]
+    ["Run all loaded tests with filters" (apply-partially cider-test-run-loaded-tests 'prompt-for-filters)]
+    ["Run all project tests" cider-test-run-project-tests]
+    ["Run all project tests with filters" (apply-partially cider-test-run-project-tests 'prompt-for-filters)]
+    ["Run tests after load-file" cider-auto-test-mode
+     :style toggle :selected cider-auto-test-mode]
+    "--"
+    ["Interrupt running tests" cider-interrupt]
+    ["Rerun failed/erring tests" cider-test-rerun-failed-tests]
+    ["Show test report" cider-test-show-report]
+    "--"
+    ["Configure testing" (customize-group 'cider-test)])
+  "CIDER test submenu.")
+
+(defvar cider-test-report-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "C-c ,")   'cider-test-commands-map)
+    (define-key map (kbd "C-c C-t") 'cider-test-commands-map)
+    (define-key map (kbd "M-p") #'cider-test-previous-result)
+    (define-key map (kbd "M-n") #'cider-test-next-result)
+    (define-key map (kbd "M-.") #'cider-test-jump)
+    (define-key map (kbd "<backtab>") #'cider-test-previous-result)
+    (define-key map (kbd "TAB") #'cider-test-next-result)
+    (define-key map (kbd "RET") #'cider-test-jump)
+    (define-key map (kbd "t") #'cider-test-jump)
+    (define-key map (kbd "d") #'cider-test-ediff)
+    (define-key map (kbd "e") #'cider-test-stacktrace)
+    ;; `f' for "run failed".
+    (define-key map "f" #'cider-test-rerun-failed-tests)
+    (define-key map "n" #'cider-test-run-ns-tests)
+    (define-key map "s" #'cider-test-run-ns-tests-with-filters)
+    (define-key map "l" #'cider-test-run-loaded-tests)
+    (define-key map "p" #'cider-test-run-project-tests)
+    ;; `g' generally reloads the buffer.  The closest thing we have to that is
+    ;; "run the test at point".  But it's not as nice as rerunning all tests in
+    ;; this buffer.
+    (define-key map "g" #'cider-test-run-test)
+    (define-key map "q" #'cider-popup-buffer-quit-function)
+    (easy-menu-define cider-test-report-mode-menu map
+      "Menu for CIDER's test result mode"
+      '("Test-Report"
+        ["Previous result" cider-test-previous-result]
+        ["Next result" cider-test-next-result]
+        "--"
+        ["Rerun current test" cider-test-run-test]
+        ["Rerun failed/erring tests" cider-test-rerun-failed-tests]
+        ["Run all ns tests" cider-test-run-ns-tests]
+        ["Run all ns tests with filters" cider-test-run-ns-tests-with-filters]
+        ["Run all loaded tests" cider-test-run-loaded-tests]
+        ["Run all loaded tests with filters" (apply-partially cider-test-run-loaded-tests 'prompt-for-filters)]
+        ["Run all project tests" cider-test-run-project-tests]
+        ["Run all project tests with filters" (apply-partially cider-test-run-project-tests 'prompt-for-filters)]
+        "--"
+        ["Jump to test definition" cider-test-jump]
+        ["Display test error" cider-test-stacktrace]
+        ["Display expected/actual diff" cider-test-ediff]))
+    map))
+
+(define-derived-mode cider-test-report-mode fundamental-mode "Test Report"
+  "Major mode for presenting Clojure test results.
+
+\\{cider-test-report-mode-map}"
+  (setq buffer-read-only t)
+  (when cider-special-mode-truncate-lines
+    (setq-local truncate-lines t))
+  (setq-local sesman-system 'CIDER)
+  (setq-local electric-indent-chars nil))
+
+;; Report navigation
+
+(defun cider-test-show-report ()
+  "Show the test report buffer, if one exists."
+  (interactive)
+  (if-let* ((report-buffer (get-buffer cider-test-report-buffer)))
+      (switch-to-buffer report-buffer)
+    (message "No test report buffer")))
+
+(defun cider-test-previous-result ()
+  "Move point to the previous test result, if one exists."
+  (interactive)
+  (with-current-buffer (get-buffer cider-test-report-buffer)
+    (when-let* ((pos (previous-single-property-change (point) 'type)))
+      (if (get-text-property pos 'type)
+          (goto-char pos)
+        (when-let* ((pos (previous-single-property-change pos 'type)))
+          (goto-char pos))))))
+
+(defun cider-test-next-result ()
+  "Move point to the next test result, if one exists."
+  (interactive)
+  (with-current-buffer (get-buffer cider-test-report-buffer)
+    (when-let* ((pos (next-single-property-change (point) 'type)))
+      (if (get-text-property pos 'type)
+          (goto-char pos)
+        (when-let* ((pos (next-single-property-change pos 'type)))
+          (goto-char pos))))))
+
+(declare-function cider-find-var "cider-find")
+
+(defun cider-test-jump (&optional arg)
+  "Find definition for test at point, if available.
+The prefix ARG and `cider-prompt-for-symbol' decide whether to
+prompt and whether to use a new window.  Similar to `cider-find-var'."
+  (interactive "P")
+  (let ((ns   (get-text-property (point) 'ns))
+        (var  (get-text-property (point) 'var))
+        (line (get-text-property (point) 'line)))
+    (if (and ns var)
+        (cider-find-var arg (concat ns "/" var) line)
+      (cider-find-var arg))))
+
+;;; Error stacktraces
+
+(defvar cider-auto-select-error-buffer)
+
+(defun cider-test-stacktrace-for (ns var index)
+  "Display stacktrace for the erring NS VAR test with the assertion INDEX."
+  (let (causes)
+    (cider-nrepl-send-request
+     (nconc `("op" "test-stacktrace"
+              "ns" ,ns
+              "var" ,var
+              "index" ,index)
+            (when (cider--pprint-fn)
+              `("pprint-fn" ,(cider--pprint-fn)))
+            (when cider-stacktrace-print-length
+              `("print-length" ,cider-stacktrace-print-length))
+            (when cider-stacktrace-print-level
+              `("print-level" ,cider-stacktrace-print-level)))
+     (lambda (response)
+       (nrepl-dbind-response response (class status)
+         (cond (class  (setq causes (cons response causes)))
+               (status (when causes
+                         (cider-stacktrace-render
+                          (cider-popup-buffer cider-error-buffer
+                                              cider-auto-select-error-buffer
+                                              #'cider-stacktrace-mode
+                                              'ancillary)
+                          (reverse causes))))))))))
+
+(defun cider-test-stacktrace ()
+  "Display stacktrace for the erring test at point."
+  (interactive)
+  (let ((ns    (get-text-property (point) 'ns))
+        (var   (get-text-property (point) 'var))
+        (index (get-text-property (point) 'index))
+        (err   (get-text-property (point) 'error)))
+    (if (and err ns var index)
+        (cider-test-stacktrace-for ns var index)
+      (message "No test error at point"))))
+
+
+;;; Expected vs actual diffing
+
+(defvar cider-test-ediff-buffers nil
+  "The expected/actual buffers used to display diff.")
+
+(defun cider-test--extract-from-actual (actual n)
+  "Extract form N from ACTUAL, ignoring outermost not.
+
+ACTUAL is a string like \"(not (= 3 4))\", of the sort returned by
+clojure.test.
+
+N = 1 => 3, N = 2 => 4, etc."
+  (with-temp-buffer
+    (insert actual)
+    (clojure-mode)
+    (goto-char (point-min))
+    (re-search-forward "(" nil t 2)
+    (clojure-forward-logical-sexp n)
+    (forward-whitespace 1)
+    (let ((beg (point)))
+      (clojure-forward-logical-sexp)
+      (buffer-substring beg (point)))))
+
+(defun cider-test-ediff ()
+  "Show diff of the expected vs actual value for the test at point.
+With the actual value, the outermost '(not ...)' s-expression is removed."
+  (interactive)
+  (let* ((expected-buffer (generate-new-buffer " *expected*"))
+         (actual-buffer   (generate-new-buffer " *actual*"))
+         (diffs (get-text-property (point) 'diffs))
+         (actual* (get-text-property (point) 'actual))
+         (expected (cond (diffs (get-text-property (point) 'expected))
+                         (actual* (cider-test--extract-from-actual actual* 1))))
+         (actual (cond (diffs (caar diffs))
+                       (actual* (cider-test--extract-from-actual actual* 2)))))
+    (if (not (and expected actual))
+        (message "No test failure at point")
+      (with-current-buffer expected-buffer
+        (insert expected)
+        (clojure-mode))
+      (with-current-buffer actual-buffer
+        (insert actual)
+        (clojure-mode))
+      (apply #'ediff-buffers
+             (setq cider-test-ediff-buffers
+                   (list (buffer-name expected-buffer)
+                         (buffer-name actual-buffer)))))))
+
+(defun cider-test-ediff-cleanup ()
+  "Cleanup expected/actual buffers used for diff."
+  (interactive)
+  (mapc (lambda (b) (when (get-buffer b) (kill-buffer b)))
+        cider-test-ediff-buffers))
+
+(add-hook 'ediff-cleanup-hook #'cider-test-ediff-cleanup)
+
+
+;;; Report rendering
+
+(defun cider-test-type-face (type)
+  "Return the font lock face for the test result TYPE."
+  (pcase type
+    ("pass"  'cider-test-success-face)
+    ("fail"  'cider-test-failure-face)
+    ("error" 'cider-test-error-face)
+    (_       'default)))
+
+(defun cider-test-type-simple-face (type)
+  "Return a face for the test result TYPE using the highlight color as foreground."
+  (let ((face (cider-test-type-face type)))
+    `(:foreground ,(face-attribute face :background))))
+
+(defun cider-test-render-summary (buffer summary)
+  "Emit into BUFFER the report SUMMARY statistics."
+  (with-current-buffer buffer
+    (nrepl-dbind-response summary (ns var test pass fail error)
+      (insert (format "Tested %d namespaces\n" ns))
+      (insert (format "Ran %d assertions, in %d test functions\n" test var))
+      (unless (zerop fail)
+        (cider-insert (format "%d failures" fail) 'cider-test-failure-face t))
+      (unless (zerop error)
+        (cider-insert (format "%d errors" error) 'cider-test-error-face t))
+      (when (zerop (+ fail error))
+        (cider-insert (format "%d passed" pass) 'cider-test-success-face t))
+      (insert "\n\n"))))
+
+(defun cider-test-render-assertion (buffer test)
+  "Emit into BUFFER report detail for the TEST assertion."
+  (with-current-buffer buffer
+    (nrepl-dbind-response test (var context type message expected actual diffs error gen-input)
+      (cl-flet ((insert-label (s)
+                  (cider-insert (format "%8s: " s) 'font-lock-comment-face))
+                (insert-align-label (s)
+                  (insert (format "%12s" s)))
+                (insert-rect (s)
+                  (insert-rectangle (thread-first s
+                                      cider-font-lock-as-clojure
+                                      (split-string "\n")))
+                  (beginning-of-line)))
+        (cider-propertize-region (cider-intern-keys (cdr test))
+          (let ((beg (point))
+                (type-face (cider-test-type-simple-face type))
+                (bg `(:background ,cider-test-items-background-color)))
+            (cider-insert (capitalize type) type-face nil " in ")
+            (cider-insert var 'font-lock-function-name-face t)
+            (when context  (cider-insert context 'font-lock-doc-face t))
+            (when message  (cider-insert message 'font-lock-doc-string-face t))
+            (when expected
+              (insert-label "expected")
+              (insert-rect expected)
+              (insert "\n"))
+            (if diffs
+                (dolist (d diffs)
+                  (cl-destructuring-bind (actual (removed added)) d
+                    (insert-label "actual")
+                    (insert-rect actual)
+                    (insert-label "diff")
+                    (insert "- ")
+                    (insert-rect removed)
+                    (insert-align-label "+ ")
+                    (insert-rect added)
+                    (insert "\n")))
+              (when actual
+                (insert-label "actual")
+                (insert-rect actual)))
+            (when error
+              (insert-label "error")
+              (insert-text-button error
+                                  'follow-link t
+                                  'action '(lambda (_button) (cider-test-stacktrace))
+                                  'help-echo "View causes and stacktrace")
+              (insert "\n"))
+            (when gen-input
+              (insert-label "input")
+              (insert (cider-font-lock-as-clojure gen-input)))
+            (overlay-put (make-overlay beg (point)) 'font-lock-face bg))
+          (insert "\n"))))))
+
+(defun cider-test-non-passing (tests)
+  "For a list of TESTS, each an `nrepl-dict`, return only those that did not pass."
+  (seq-filter (lambda (test)
+                (unless (equal (nrepl-dict-get test "type") "pass")
+                  test))
+              tests))
+
+(defun cider-test-render-report (buffer summary results)
+  "Emit into BUFFER the report for the SUMMARY, and test RESULTS."
+  (with-current-buffer buffer
+    (let ((inhibit-read-only t))
+      (cider-test-report-mode)
+      (cider-insert "Test Summary" 'bold t)
+      (dolist (ns (nrepl-dict-keys results))
+        (insert (cider-propertize ns 'ns) "\n"))
+      (cider-insert "\n")
+      (cider-test-render-summary buffer summary)
+      (nrepl-dbind-response summary (fail error)
+        (unless (zerop (+ fail error))
+          (cider-insert "Results" 'bold t "\n")
+          ;; Results are a nested dict, keyed first by ns, then var. Within each
+          ;; var is a sequence of test assertion results.
+          (nrepl-dict-map
+           (lambda (ns vars)
+             (nrepl-dict-map
+              (lambda (_var tests)
+                (let* ((problems (cider-test-non-passing tests))
+                       (count (length problems)))
+                  (when (< 0 count)
+                    (insert (format "%s\n%d non-passing tests:\n\n"
+                                    (cider-propertize ns 'ns) count))
+                    (dolist (test problems)
+                      (cider-test-render-assertion buffer test)))))
+              vars))
+           results)))
+      (goto-char (point-min))
+      (current-buffer))))
+
+
+;;; Message echo
+
+(defun cider-test-echo-running (ns &optional test)
+  "Echo a running message for the test NS, which may be a keyword.
+The optional arg TEST denotes an individual test name."
+  (if test
+      (message "Running test %s in %s..."
+               (cider-propertize test 'bold)
+               (cider-propertize ns 'ns))
+    (message "Running tests in %s..."
+             (concat (cider-propertize
+                      (cond ((stringp ns) ns)
+                            ((eq :non-passing ns) "failing")
+                            ((eq :loaded ns)  "all loaded")
+                            ((eq :project ns) "all project"))
+                      'ns)
+                     (unless (stringp ns) " namespaces")))))
+
+(defun cider-test-echo-summary (summary results)
+  "Echo SUMMARY statistics for a test run returning RESULTS."
+  (nrepl-dbind-response summary (ns test var fail error)
+    (if (nrepl-dict-empty-p results)
+        (message (concat (propertize "No assertions (or no tests) were run." 'face 'cider-test-error-face)
+                         "Did you forget to use `is' in your tests?"))
+      (message (propertize
+                "%sRan %d assertions, in %d test functions. %d failures, %d errors."
+                'face (cond ((not (zerop error)) 'cider-test-error-face)
+                            ((not (zerop fail))  'cider-test-failure-face)
+                            (t                   'cider-test-success-face)))
+               (concat (if (= 1 ns)     ; ns count from summary
+                           (cider-propertize (car (nrepl-dict-keys results)) 'ns)
+                         (propertize (format "%d namespaces" ns) 'face 'default))
+                       (propertize ": " 'face 'default))
+               test var fail error))))
+
+;;; Test definition highlighting
+;;
+;; On receipt of test results, failing/erring test definitions are highlighted.
+;; Highlights are cleared on the next report run, and may be cleared manually
+;; by the user.
+
+;; NOTE If keybindings specific to test sources are desired, it would be
+;; straightforward to turn this into a `cider-test-mode' minor mode, which we
+;; enable on test sources, much like the legacy `clojure-test-mode'. At present,
+;; though, there doesn't seem to be much value in this, since the report buffer
+;; provides the primary means of interacting with test results.
+
+(defun cider-test-highlight-problem (buffer test)
+  "Highlight the BUFFER test definition for the non-passing TEST."
+  (with-current-buffer buffer
+    ;; we don't need the file name here, as we always operate on the current
+    ;; buffer and the line data is correct even for vars that were
+    ;; defined interactively
+    (nrepl-dbind-response test (type line message expected actual)
+      (when line
+        (save-excursion
+          (goto-char (point-min))
+          (forward-line (1- line))
+          (search-forward "(" nil t)
+          (let ((beg (point)))
+            (forward-sexp)
+            (cider--make-overlay beg (point) 'cider-test
+                                 'font-lock-face (cider-test-type-face type)
+                                 'type type
+                                 'help-echo message
+                                 'message message
+                                 'expected expected
+                                 'actual actual)))))))
+
+(defun cider-find-var-file (ns var)
+  "Return the buffer visiting the file in which the NS VAR is defined.
+Or nil if not found."
+  (cider-ensure-op-supported "info")
+  (when-let* ((info (cider-var-info (concat ns "/" var)))
+              (file (nrepl-dict-get info "file")))
+    (cider-find-file file)))
+
+(defun cider-test-highlight-problems (results)
+  "Highlight all non-passing tests in the test RESULTS."
+  (nrepl-dict-map
+   (lambda (ns vars)
+     (nrepl-dict-map
+      (lambda (var tests)
+        (when-let* ((buffer (cider-find-var-file ns var)))
+          (dolist (test tests)
+            (nrepl-dbind-response test (type)
+              (unless (equal "pass" type)
+                (cider-test-highlight-problem buffer test))))))
+      vars))
+   results))
+
+(defun cider-test-clear-highlights ()
+  "Clear highlighting of non-passing tests from the last test run."
+  (interactive)
+  (when cider-test-last-results
+    (nrepl-dict-map
+     (lambda (ns vars)
+       (dolist (var (nrepl-dict-keys vars))
+         (when-let* ((buffer (cider-find-var-file ns var)))
+           (with-current-buffer buffer
+             (remove-overlays nil nil 'category 'cider-test)))))
+     cider-test-last-results)))
+
+
+;;; Test namespaces
+;;
+;; Test namespace inference exists to enable DWIM test running functions: the
+;; same "run-tests" function should be able to be used in a source file, and in
+;; its corresponding test namespace. To provide this, we need to map the
+;; relationship between those namespaces.
+
+(defcustom cider-test-infer-test-ns 'cider-test-default-test-ns-fn
+  "Function to infer the test namespace for NS.
+The default implementation uses the simple Leiningen convention of appending
+'-test' to the namespace name."
+  :type 'symbol
+  :group 'cider-test
+  :package-version '(cider . "0.7.0"))
+
+(defun cider-test-default-test-ns-fn (ns)
+  "For a NS, return the test namespace, which may be the argument itself.
+This uses the Leiningen convention of appending '-test' to the namespace name."
+  (when ns
+    (let ((suffix "-test"))
+      (if (string-suffix-p suffix ns)
+          ns
+        (concat ns suffix)))))
+
+
+;;; Test execution
+
+(declare-function cider-emit-interactive-eval-output "cider-eval")
+(declare-function cider-emit-interactive-eval-err-output "cider-eval")
+
+(defun cider-test--prompt-for-selectors (message)
+  "Prompt for test selectors with MESSAGE.
+The selectors can be either keywords or strings."
+  (mapcar
+   (lambda (string) (replace-regexp-in-string "^:+" "" string))
+   (split-string
+    (cider-read-from-minibuffer message))))
+
+(defun cider-test-execute (ns &optional tests silent prompt-for-filters)
+  "Run tests for NS, which may be a keyword, optionally specifying TESTS.
+This tests a single NS, or multiple namespaces when using keywords `:project',
+`:loaded' or `:non-passing'.  Optional TESTS are only honored when a single
+namespace is specified.  Upon test completion, results are echoed and a test
+report is optionally displayed.  When test failures/errors occur, their sources
+are highlighted.
+If SILENT is non-nil, suppress all messages other then test results.
+If PROMPT-FOR-FILTERS is non-nil, prompt the user for a test selector filters.
+The include/exclude selectors will be used to filter the tests before
+ running them."
+  (cider-test-clear-highlights)
+  (let ((include-selectors
+         (when prompt-for-filters
+           (cider-test--prompt-for-selectors "Test selectors to include (space separated): ")))
+        (exclude-selectors
+         (when prompt-for-filters
+           (cider-test--prompt-for-selectors "Test selectors to exclude (space separated): "))))
+    (cider-map-repls :clj-strict
+      (lambda (conn)
+        (unless silent
+          (if (and tests (= (length tests) 1))
+              ;; we generate a different message when running individual tests
+              (cider-test-echo-running ns (car tests))
+            (cider-test-echo-running ns)))
+        (let ((request `("op" ,(cond ((stringp ns)         "test")
+                                     ((eq :project ns)     "test-all")
+                                     ((eq :loaded ns)      "test-all")
+                                     ((eq :non-passing ns) "retest")))))
+          ;; we add optional parts of the request only when relevant
+          (when (and (listp include-selectors) include-selectors)
+            (setq request (append request `("include" ,include-selectors))))
+          (when (and (listp exclude-selectors) exclude-selectors)
+            (setq request (append request `("exclude" ,exclude-selectors))))
+          (when (stringp ns)
+            (setq request (append request `("ns" ,ns))))
+          (when (stringp ns)
+            (setq request (append request `("tests" ,tests))))
+          (when (or (stringp ns) (eq :project ns))
+            (setq request (append request `("load?" ,"true"))))
+          (cider-nrepl-send-request
+           request
+           (lambda (response)
+             (nrepl-dbind-response response (summary results status out err)
+               (cond ((member "namespace-not-found" status)
+                      (unless silent
+                        (message "No test namespace: %s" (cider-propertize ns 'ns))))
+                     (out (cider-emit-interactive-eval-output out))
+                     (err (cider-emit-interactive-eval-err-output err))
+                     (results
+                      (nrepl-dbind-response summary (error fail)
+                        (setq cider-test-last-summary summary)
+                        (setq cider-test-last-results results)
+                        (cider-test-highlight-problems results)
+                        (cider-test-echo-summary summary results)
+                        (if (or (not (zerop (+ error fail)))
+                                cider-test-show-report-on-success)
+                            (cider-test-render-report
+                             (cider-popup-buffer
+                              cider-test-report-buffer
+                              cider-auto-select-test-report-buffer)
+                             summary
+                             results)
+                          (when (get-buffer cider-test-report-buffer)
+                            (with-current-buffer cider-test-report-buffer
+                              (let ((inhibit-read-only t))
+                                (erase-buffer)))
+                            (cider-test-render-report
+                             cider-test-report-buffer
+                             summary results))))))))
+           conn))))))
+
+(defun cider-test-rerun-failed-tests ()
+  "Rerun failed and erring tests from the last test run."
+  (interactive)
+  (if cider-test-last-summary
+      (nrepl-dbind-response cider-test-last-summary (fail error)
+        (if (not (zerop (+ error fail)))
+            (cider-test-execute :non-passing)
+          (message "No prior failures to retest")))
+    (message "No prior results to retest")))
+
+(defun cider-test-run-loaded-tests (prompt-for-filters)
+  "Run all tests defined in currently loaded namespaces.
+
+If PROMPT-FOR-FILTERS is non-nil, prompt the user for a test selectors to filter the tests with."
+  (interactive "P")
+  (cider-test-execute :loaded nil nil prompt-for-filters))
+
+(defun cider-test-run-project-tests (prompt-for-filters)
+  "Run all tests defined in all project namespaces, loading these as needed.
+
+If PROMPT-FOR-FILTERS is non-nil, prompt the user for a test selectors to filter the tests with."
+  (interactive "P")
+  (cider-test-execute :project nil nil prompt-for-filters))
+
+(defun cider-test-run-ns-tests-with-filters (suppress-inference)
+  "Run tests filtered by selectors for the current Clojure namespace context.
+
+With a prefix arg SUPPRESS-INFERENCE it will try to run the tests in the
+current ns."
+  (interactive "P")
+  (cider-test-run-ns-tests suppress-inference nil 't))
+
+(defun cider-test-run-ns-tests (suppress-inference &optional silent prompt-for-filters)
+  "Run all tests for the current Clojure namespace context.
+
+If SILENT is non-nil, suppress all messages other then test results.
+With a prefix arg SUPPRESS-INFERENCE it will try to run the tests in the
+current ns.  If PROMPT-FOR-FILTERS is non-nil, prompt the user for
+test selectors to filter the tests with."
+  (interactive "P")
+  (if-let* ((ns (if suppress-inference
+                    (cider-current-ns t)
+                  (funcall cider-test-infer-test-ns (cider-current-ns t)))))
+      (cider-test-execute ns nil silent prompt-for-filters)
+    (if (eq major-mode 'cider-test-report-mode)
+        (when (y-or-n-p (concat "Test report does not define a namespace. "
+                                "Rerun failed/erring tests?"))
+          (cider-test-rerun-failed-tests))
+      (unless silent
+        (message "No namespace to test in current context")))))
+
+(defvar cider-test-last-test-ns nil
+  "The ns of the last test ran with `cider-test-run-test'.")
+(defvar cider-test-last-test-var nil
+  "The var of the last test ran with `cider-test-run-test'.")
+
+(defun cider-test-update-last-test (ns var)
+  "Update the last test by setting NS and VAR.
+
+See `cider-test-rerun-test'."
+  (setq cider-test-last-test-ns ns
+        cider-test-last-test-var var))
+
+(defun cider-test-run-test ()
+  "Run the test at point.
+The test ns/var exist as text properties on report items and on highlighted
+failed/erred test definitions.  When not found, a test definition at point
+is searched."
+  (interactive)
+  (let ((ns  (get-text-property (point) 'ns))
+        (var (get-text-property (point) 'var)))
+    (if (and ns var)
+        ;; we're in a `cider-test-report-mode' buffer
+        ;; or on a highlighted failed/erred test definition
+        (progn
+          (cider-test-update-last-test ns var)
+          (cider-test-execute ns (list var)))
+      ;; we're in a `clojure-mode' buffer
+      (let* ((ns  (clojure-find-ns))
+             (def (clojure-find-def)) ; it's a list of the form (deftest something)
+             (deftype (car def))
+             (var (cadr def)))
+        (if (and ns (member deftype cider-test-defining-forms))
+            (progn
+              (cider-test-update-last-test ns (list var))
+              (cider-test-execute ns (list var)))
+          (message "No test at point"))))))
+
+(defun cider-test-rerun-test ()
+  "Re-run the test that was previously ran."
+  (interactive)
+  (if (and cider-test-last-test-ns cider-test-last-test-var)
+      (cider-test-execute cider-test-last-test-ns cider-test-last-test-var)
+    (user-error "No test to re-run")))
+
+;;; Auto-test mode
+(defun cider--test-silently ()
+  "Like `cider-test-run-tests', but with less feedback.
+Only notify the user if there actually were any tests to run and only after
+the results are received."
+  (when (cider-connected-p)
+    (let ((cider-auto-select-test-report-buffer nil)
+          (cider-test-show-report-on-success nil))
+      (cider-test-run-ns-tests nil 'soft))))
+
+;;;###autoload
+(define-minor-mode cider-auto-test-mode
+  "Toggle automatic testing of Clojure files.
+
+When enabled this reruns tests every time a Clojure file is loaded.
+Only runs tests corresponding to the loaded file's namespace and does
+nothing if no tests are defined or if the file failed to load."
+  nil (cider-mode " Test") nil
+  :global t
+  (if cider-auto-test-mode
+      (add-hook 'cider-file-loaded-hook #'cider--test-silently)
+    (remove-hook 'cider-file-loaded-hook #'cider--test-silently)))
+
+(provide 'cider-test)
+
+;;; cider-test.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-test.elc b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-test.elc
new file mode 100644
index 0000000000..3d1d7b0c2a
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-test.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-tracing.el b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-tracing.el
new file mode 100644
index 0000000000..c00e7b7f98
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-tracing.el
@@ -0,0 +1,90 @@
+;;; cider-tracing.el --- Executing tracing functionality -*- lexical-binding: t -*-
+
+;; Copyright © 2013-2018 Bozhidar Batsov, Artur Malabarba and CIDER contributors
+;;
+;; Author: Bozhidar Batsov <bozhidar@batsov.com>
+;;         Artur Malabarba <bruce.connor.am@gmail.com>
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;; This file is not part of GNU Emacs.
+
+;;; Commentary:
+
+;; A couple of commands for tracing the execution of functions.
+
+;;; Code:
+
+(require 'cider-client)
+(require 'cider-common) ; for `cider-prompt-for-symbol-function'
+(require 'cider-util) ; for `cider-propertize'
+(require 'cider-connection) ; for `cider-map-repls'
+(require 'nrepl-dict)
+
+(defun cider-sync-request:toggle-trace-var (symbol)
+  "Toggle var tracing for SYMBOL."
+  (thread-first `("op" "toggle-trace-var"
+                  "ns" ,(cider-current-ns)
+                  "sym" ,symbol)
+    (cider-nrepl-send-sync-request)))
+
+(defun cider--toggle-trace-var (sym)
+  "Toggle var tracing for SYM."
+  (let* ((trace-response (cider-sync-request:toggle-trace-var sym))
+         (var-name (nrepl-dict-get trace-response "var-name"))
+         (var-status (nrepl-dict-get trace-response "var-status")))
+    (pcase var-status
+      ("not-found" (error "Var %s not found" (cider-propertize sym 'fn)))
+      ("not-traceable" (error "Var %s can't be traced because it's not bound to a function" (cider-propertize var-name 'fn)))
+      (_ (message "Var %s %s" (cider-propertize var-name 'fn) var-status)))))
+
+;;;###autoload
+(defun cider-toggle-trace-var (arg)
+  "Toggle var tracing.
+Prompts for the symbol to use, or uses the symbol at point, depending on
+the value of `cider-prompt-for-symbol'.  With prefix arg ARG, does the
+opposite of what that option dictates."
+  (interactive "P")
+  (cider-ensure-op-supported "toggle-trace-var")
+  (funcall (cider-prompt-for-symbol-function arg)
+           "Toggle trace for var"
+           #'cider--toggle-trace-var))
+
+(defun cider-sync-request:toggle-trace-ns (ns)
+  "Toggle namespace tracing for NS."
+  (thread-first `("op" "toggle-trace-ns"
+                  "ns" ,ns)
+    (cider-nrepl-send-sync-request)))
+
+;;;###autoload
+(defun cider-toggle-trace-ns (query)
+  "Toggle ns tracing.
+Defaults to the current ns.  With prefix arg QUERY, prompts for a ns."
+  (interactive "P")
+  (cider-map-repls :clj-strict
+    (lambda (conn)
+      (with-current-buffer conn
+        (cider-ensure-op-supported "toggle-trace-ns")
+        (let ((ns (if query
+                      (completing-read "Toggle trace for ns: "
+                                       (cider-sync-request:ns-list))
+                    (cider-current-ns))))
+          (let* ((trace-response (cider-sync-request:toggle-trace-ns ns))
+                 (ns-status (nrepl-dict-get trace-response "ns-status")))
+            (pcase ns-status
+              ("not-found" (error "Namespace %s not found" (cider-propertize ns 'ns)))
+              (_ (message "Namespace %s %s" (cider-propertize ns 'ns) ns-status)))))))))
+
+(provide 'cider-tracing)
+;;; cider-tracing.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-tracing.elc b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-tracing.elc
new file mode 100644
index 0000000000..0a351a3732
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-tracing.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-util.el b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-util.el
new file mode 100644
index 0000000000..5263713d5a
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-util.el
@@ -0,0 +1,849 @@
+;; cider-util.el --- Common utility functions that don't belong anywhere else -*- lexical-binding: t -*-
+
+;; Copyright © 2012-2013 Tim King, Phil Hagelberg, Bozhidar Batsov
+;; Copyright © 2013-2018 Bozhidar Batsov, Artur Malabarba and CIDER contributors
+;;
+;; Author: Tim King <kingtim@gmail.com>
+;;         Phil Hagelberg <technomancy@gmail.com>
+;;         Bozhidar Batsov <bozhidar@batsov.com>
+;;         Artur Malabarba <bruce.connor.am@gmail.com>
+;;         Hugo Duncan <hugo@hugoduncan.org>
+;;         Steve Purcell <steve@sanityinc.com>
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;; This file is not part of GNU Emacs.
+
+;;; Commentary:
+
+;; Common utility functions that don't belong anywhere else.
+
+;;; Code:
+
+;; Built-ins
+(require 'ansi-color)
+(require 'color)
+(require 'seq)
+(require 'subr-x)
+(require 'thingatpt)
+
+;; clojure-mode and CIDER
+(require 'cider-compat)
+(require 'clojure-mode)
+(require 'nrepl-dict)
+
+(defalias 'cider-pop-back 'pop-tag-mark)
+
+(defcustom cider-font-lock-max-length 10000
+  "The max length of strings to fontify in `cider-font-lock-as'.
+
+Setting this to nil removes the fontification restriction."
+  :group 'cider
+  :type 'boolean
+  :package-version '(cider . "0.10.0"))
+
+(defun cider-util--hash-keys (hashtable)
+  "Return a list of keys in HASHTABLE."
+  (let ((keys '()))
+    (maphash (lambda (k _v) (setq keys (cons k keys))) hashtable)
+    keys))
+
+(defun cider-util--clojure-buffers ()
+  "Return a list of all existing `clojure-mode' buffers."
+  (seq-filter
+   (lambda (buffer) (with-current-buffer buffer (derived-mode-p 'clojure-mode)))
+   (buffer-list)))
+
+(defun cider-current-dir ()
+  "Return the directory of the current buffer."
+  (if buffer-file-name
+      (file-name-directory buffer-file-name)
+    default-directory))
+
+(defun cider-in-string-p ()
+  "Return non-nil if point is in a string."
+  (let ((beg (save-excursion (beginning-of-defun) (point))))
+    (nth 3 (parse-partial-sexp beg (point)))))
+
+(defun cider-in-comment-p ()
+  "Return non-nil if point is in a comment."
+  (let ((beg (save-excursion (beginning-of-defun) (point))))
+    (nth 4 (parse-partial-sexp beg (point)))))
+
+(defun cider--tooling-file-p (file-name)
+  "Return t if FILE-NAME is not a 'real' source file.
+Currently, only check if the relative file name starts with 'form-init'
+which nREPL uses for temporary evaluation file names."
+  (let ((fname (file-name-nondirectory file-name)))
+    (string-match-p "^form-init" fname)))
+
+(defun cider--cljc-buffer-p (&optional buffer)
+  "Return non-nil if the current buffer is visiting a cljc file.
+
+If BUFFER is provided act on that buffer instead."
+  (with-current-buffer (or buffer (current-buffer))
+    (or (derived-mode-p 'clojurec-mode))))
+
+
+;;; Thing at point
+
+(defun cider--text-or-limits (bounds start end)
+  "Returns the substring or the bounds of text.
+If BOUNDS is non-nil, returns the list (START END) of character
+positions.  Else returns the substring from START to END."
+  (funcall (if bounds #'list #'buffer-substring-no-properties)
+           start end))
+
+(defun cider-top-level-comment-p ()
+  "Return non-nil if point is in a comment form."
+  (save-excursion
+    (end-of-defun)
+    (clojure-backward-logical-sexp 1)
+    (forward-char 1)
+    (clojure-forward-logical-sexp 1)
+    (clojure-backward-logical-sexp 1)
+    (looking-at-p "comment")))
+
+(defcustom cider-eval-toplevel-inside-comment-form nil
+  "Eval top level forms inside comment forms instead of the comment form itself.
+Experimental.  Function `cider-defun-at-point' is used extensively so if we
+change this heuristic it needs to be bullet-proof and desired.  While
+testing, give an easy way to turn this new behavior off."
+  :group 'cider
+  :type 'boolean
+  :package-version '(cider . "0.18.0"))
+
+(defun cider-sexp-starts-until-position (position)
+  "Returns the starting points for forms before POSITION.
+Positions are in descending order to aide in finding the first starting
+position before the current position."
+  (save-excursion
+    (let (sexp-positions)
+      (condition-case nil
+          (while (< (point) position)
+            (clojure-forward-logical-sexp 1)
+            (clojure-backward-logical-sexp 1)
+            (push (point) sexp-positions)
+            (clojure-forward-logical-sexp 1))
+        (scan-error nil))
+      sexp-positions)))
+
+(defun cider-defun-inside-comment-form (&optional bounds)
+  "Return the toplevel form inside a comment containing point.
+Assumes point is inside a (comment ....) form and will return the text of
+that form or if BOUNDS, will return a list of the starting and ending
+position."
+  (save-excursion
+    (save-match-data
+      (let ((original-position (point))
+            cider-comment-start cider-comment-end)
+        (end-of-defun)
+        (setq cider-comment-end (point))
+        (clojure-backward-logical-sexp 1) ;; beginning of comment form
+        (setq cider-comment-start (point))
+        (forward-char 1)                  ;; skip paren so we start at comment
+        (clojure-forward-logical-sexp)    ;; skip past the comment form itself
+        (if-let* ((sexp-start (seq-find (lambda (beg-pos) (< beg-pos original-position))
+                                        (cider-sexp-starts-until-position cider-comment-end))))
+            (progn
+              (goto-char sexp-start)
+              (clojure-forward-logical-sexp 1)
+              (cider--text-or-limits bounds sexp-start (point)))
+          (cider--text-or-limits bounds cider-comment-start cider-comment-end))))))
+
+(defun cider-defun-at-point (&optional bounds)
+  "Return the text of the top level sexp at point.
+If BOUNDS is non-nil, return a list of its starting and ending position
+instead."
+  (if (and cider-eval-toplevel-inside-comment-form
+           (cider-top-level-comment-p))
+      (cider-defun-inside-comment-form bounds)
+    (save-excursion
+      (save-match-data
+        (end-of-defun)
+        (let ((end (point)))
+          (clojure-backward-logical-sexp 1)
+          (cider--text-or-limits bounds (point) end))))))
+
+(defun cider-ns-form ()
+  "Retrieve the ns form."
+  (when (clojure-find-ns)
+    (save-excursion
+      (goto-char (match-beginning 0))
+      (cider-defun-at-point))))
+
+(defun cider-symbol-at-point (&optional look-back)
+  "Return the name of the symbol at point, otherwise nil.
+Ignores the REPL prompt.  If LOOK-BACK is non-nil, move backwards trying to
+find a symbol if there isn't one at point."
+  (or (when-let* ((str (thing-at-point 'symbol)))
+        (unless (text-property-any 0 (length str) 'field 'cider-repl-prompt str)
+          (substring-no-properties str)))
+      (when look-back
+        (save-excursion
+          (ignore-errors
+            (while (not (looking-at "\\sw\\|\\s_\\|\\`"))
+              (forward-sexp -1)))
+          (cider-symbol-at-point)))))
+
+
+;;; sexp navigation
+(defun cider-sexp-at-point (&optional bounds)
+  "Return the sexp at point as a string, otherwise nil.
+If BOUNDS is non-nil, return a list of its starting and ending position
+instead."
+  (when-let* ((b (or (and (equal (char-after) ?\()
+                          (member (char-before) '(?\' ?\, ?\@))
+                          ;; hide stuff before ( to avoid quirks with '( etc.
+                          (save-restriction
+                            (narrow-to-region (point) (point-max))
+                            (bounds-of-thing-at-point 'sexp)))
+                     (bounds-of-thing-at-point 'sexp))))
+    (funcall (if bounds #'list #'buffer-substring-no-properties)
+             (car b) (cdr b))))
+
+(defun cider-last-sexp (&optional bounds)
+  "Return the sexp preceding the point.
+If BOUNDS is non-nil, return a list of its starting and ending position
+instead."
+  (apply (if bounds #'list #'buffer-substring-no-properties)
+         (save-excursion
+           (clojure-backward-logical-sexp 1)
+           (list (point)
+                 (progn (clojure-forward-logical-sexp 1)
+                        (skip-chars-forward "[:blank:]")
+                        (when (looking-at-p "\n") (forward-char 1))
+                        (point))))))
+
+(defun cider-start-of-next-sexp (&optional skip)
+  "Move to the start of the next sexp.
+Skip any non-logical sexps like ^metadata or #reader macros.
+If SKIP is an integer, also skip that many logical sexps first.
+Can only error if SKIP is non-nil."
+  (while (clojure--looking-at-non-logical-sexp)
+    (forward-sexp 1))
+  (when (and skip (> skip 0))
+    (dotimes (_ skip)
+      (forward-sexp 1)
+      (cider-start-of-next-sexp))))
+
+(defun cider-second-sexp-in-list ()
+  "Return the second sexp in the list at point."
+  (condition-case nil
+      (save-excursion
+        (backward-up-list)
+        (forward-char)
+        (forward-sexp 2)
+        (cider-sexp-at-point))
+    (error nil)))
+
+;;; Text properties
+
+(defun cider-maybe-intern (name)
+  "If NAME is a symbol, return it; otherwise, intern it."
+  (if (symbolp name) name (intern name)))
+
+(defun cider-intern-keys (plist)
+  "Copy PLIST, with any non-symbol keys replaced with symbols."
+  (when plist
+    (cons (cider-maybe-intern (pop plist))
+          (cons (pop plist) (cider-intern-keys plist)))))
+
+(defmacro cider-propertize-region (props &rest body)
+  "Execute BODY and add PROPS to all the inserted text.
+More precisely, PROPS are added to the region between the point's
+positions before and after executing BODY."
+  (declare (indent 1)
+           (debug (sexp body)))
+  (let ((start (make-symbol "start")))
+    `(let ((,start (point)))
+       (prog1 (progn ,@body)
+         (add-text-properties ,start (point) ,props)))))
+
+(put 'cider-propertize-region 'lisp-indent-function 1)
+
+(defun cider-property-bounds (prop)
+  "Return the the positions of the previous and next change to PROP.
+PROP is the name of a text property."
+  (let ((end (next-single-char-property-change (point) prop)))
+    (list (previous-single-char-property-change end prop) end)))
+
+(defun cider-insert (text &optional face break more-text)
+  "Insert TEXT with FACE, optionally followed by a line BREAK and MORE-TEXT."
+  (insert (if face (propertize text 'font-lock-face face) text))
+  (when more-text (insert more-text))
+  (when break (insert "\n")))
+
+
+;;; Hooks
+
+(defun cider-run-chained-hook (hook arg)
+  "Like `run-hook-with-args' but pass intermediate return values through.
+HOOK is a name of a hook (a symbol).  You can use `add-hook' or
+`remove-hook' to add functions to this variable.  ARG is passed to first
+function.  Its return value is passed to the second function and so forth
+till all functions are called or one of them returns nil.  Return the value
+return by the last called function."
+  (let ((functions (copy-sequence (symbol-value hook))))
+    (while (and functions arg)
+      (if (eq (car functions) t)
+          ;; global value of the hook
+          (let ((functions (default-value hook)))
+            (while (and functions arg)
+              (setq arg (funcall (car functions) arg))
+              (setq functions (cdr functions))))
+        (setq arg (funcall (car functions) arg)))
+      (setq functions (cdr functions)))
+    arg))
+
+
+;;; Font lock
+
+(defalias 'cider--font-lock-ensure
+  (if (fboundp 'font-lock-ensure)
+      #'font-lock-ensure
+    (with-no-warnings
+      (lambda (&optional _beg _end)
+        (when font-lock-mode
+          (font-lock-fontify-buffer))))))
+
+(defalias 'cider--font-lock-flush
+  (if (fboundp 'font-lock-flush)
+      #'font-lock-flush
+    (with-no-warnings
+      (lambda (&optional _beg _end)
+        (when font-lock-mode
+          (font-lock-fontify-buffer))))))
+
+(defvar cider--mode-buffers nil
+  "A list of buffers for different major modes.")
+
+(defun cider--make-buffer-for-mode (mode)
+  "Return a temp buffer using `major-mode' MODE.
+This buffer is not designed to display anything to the user.  For that, use
+`cider-make-popup-buffer' instead."
+  (setq cider--mode-buffers (seq-filter (lambda (x) (buffer-live-p (cdr x)))
+                                        cider--mode-buffers))
+  (or (cdr (assq mode cider--mode-buffers))
+      (let ((b (generate-new-buffer (format " *cider-temp %s*" mode))))
+        (push (cons mode b) cider--mode-buffers)
+        (with-current-buffer b
+          ;; suppress major mode hooks as we care only about their font-locking
+          ;; otherwise modes like whitespace-mode and paredit might interfere
+          (setq-local delay-mode-hooks t)
+          (setq delayed-mode-hooks nil)
+          (funcall mode))
+        b)))
+
+(defun cider-ansi-color-string-p (string)
+  "Return non-nil if STRING is an ANSI string."
+  (string-match "^\\[" string))
+
+(defun cider-font-lock-as (mode string)
+  "Use MODE to font-lock the STRING."
+  (let ((string (if (cider-ansi-color-string-p string)
+                    (substring-no-properties (ansi-color-apply string))
+                  string)))
+    (if (or (null cider-font-lock-max-length)
+            (< (length string) cider-font-lock-max-length))
+        (with-current-buffer (cider--make-buffer-for-mode mode)
+          (erase-buffer)
+          (insert string)
+          (font-lock-fontify-region (point-min) (point-max))
+          (buffer-string))
+      string)))
+
+(defun cider-font-lock-region-as (mode beg end &optional buffer)
+  "Use MODE to font-lock text between BEG and END.
+
+Unless you specify a BUFFER it will default to the current one."
+  (with-current-buffer (or buffer (current-buffer))
+    (let ((text (buffer-substring beg end)))
+      (delete-region beg end)
+      (goto-char beg)
+      (insert (cider-font-lock-as mode text)))))
+
+(defun cider-font-lock-as-clojure (string)
+  "Font-lock STRING as Clojure code."
+  (cider-font-lock-as 'clojure-mode string))
+
+;; Button allowing use of `font-lock-face', ignoring any inherited `face'
+(define-button-type 'cider-plain-button
+  'face nil)
+
+(defun cider-add-face (regexp face &optional foreground-only sub-expr object)
+  "Propertize all occurrences of REGEXP with FACE.
+If FOREGROUND-ONLY is non-nil, change only the foreground of matched
+regions.  SUB-EXPR is a sub-expression of REGEXP to be
+propertized (defaults to 0).  OBJECT is an object to be
+propertized (defaults to current buffer)."
+  (setq sub-expr (or sub-expr 0))
+  (when (and regexp face)
+    (let ((beg 0)
+          (end 0))
+      (with-current-buffer (or (and (bufferp object) object)
+                               (current-buffer))
+        (while (if (stringp object)
+                   (string-match regexp object end)
+                 (re-search-forward regexp nil t))
+          (setq beg (match-beginning sub-expr)
+                end (match-end sub-expr))
+          (if foreground-only
+              (let ((face-spec (list (cons 'foreground-color
+                                           (face-attribute face :foreground nil t)))))
+                (font-lock-prepend-text-property beg end 'face face-spec object))
+            (put-text-property beg end 'face face object)))))))
+
+
+;;; Colors
+
+(defun cider-scale-background-color ()
+  "Scale the current background color to get a slighted muted version."
+  (let ((color (frame-parameter nil 'background-color))
+        (darkp (eq (frame-parameter nil 'background-mode) 'dark)))
+    (unless (equal "unspecified-bg" color)
+      (color-lighten-name color (if darkp 5 -5)))))
+
+(autoload 'pkg-info-version-info "pkg-info.el")
+
+(defvar cider-version)
+(defvar cider-codename)
+
+(defun cider--version ()
+  "Retrieve CIDER's version.
+A codename is added to stable versions."
+  (let ((version (condition-case nil
+                     (pkg-info-version-info 'cider)
+                   (error cider-version))))
+    (if (string-match-p "-snapshot" cider-version)
+        version
+      (format "%s (%s)" version cider-codename))))
+
+
+;;; Strings
+
+(defun cider-join-into-alist (candidates &optional separator)
+  "Make an alist from CANDIDATES.
+The keys are the elements joined with SEPARATOR and values are the original
+elements.  Useful for `completing-read' when candidates are complex
+objects."
+  (mapcar (lambda (el)
+            (if (listp el)
+                (cons (string-join el (or separator ":")) el)
+              (cons el el)))
+          candidates))
+
+(defun cider-add-to-alist (symbol car cadr)
+  "Add '(CAR CADR) to the alist stored in SYMBOL.
+If CAR already corresponds to an entry in the alist, destructively replace
+the entry's second element with CADR.
+
+This can be used, for instance, to update the version of an injected
+plugin or dependency with:
+  (cider-add-to-alist 'cider-jack-in-lein-plugins
+                  \"plugin/artifact-name\" \"THE-NEW-VERSION\")"
+  (let ((alist (symbol-value symbol)))
+    (if-let* ((cons (assoc car alist)))
+        (setcdr cons (list cadr))
+      (set symbol (cons (list car cadr) alist)))))
+
+(defun cider-namespace-qualified-p (sym)
+  "Return t if SYM is namespace-qualified."
+  (string-match-p "[^/]+/" sym))
+
+(defvar cider-version)
+
+(defconst cider-manual-url "http://docs.cider.mx/en/%s/"
+  "The URL to CIDER's manual.")
+
+(defun cider--manual-version ()
+  "Convert the version to a ReadTheDocs-friendly version."
+  (if (string-match-p "-snapshot" cider-version)
+      "latest"
+    "stable"))
+
+(defun cider-manual-url ()
+  "The CIDER manual's url."
+  (format cider-manual-url (cider--manual-version)))
+
+;;;###autoload
+(defun cider-view-manual ()
+  "View the manual in your default browser."
+  (interactive)
+  (browse-url (cider-manual-url)))
+
+(defun cider--manual-button (label section-id)
+  "Return a button string that links to the online manual.
+LABEL is the displayed string, and SECTION-ID is where it points
+to."
+  (with-temp-buffer
+    (insert-text-button
+     label
+     'follow-link t
+     'action (lambda (&rest _) (interactive)
+               (browse-url (concat (cider-manual-url)
+                                   section-id))))
+    (buffer-string)))
+
+(defconst cider-refcard-url "https://github.com/clojure-emacs/cider/raw/%s/doc/cider-refcard.pdf"
+  "The URL to CIDER's refcard.")
+
+(defun cider--github-version ()
+  "Convert the version to a GitHub-friendly version."
+  (if (string-match-p "-snapshot" cider-version)
+      "master"
+    (concat "v" cider-version)))
+
+(defun cider-refcard-url ()
+  "The CIDER manual's url."
+  (format cider-refcard-url (cider--github-version)))
+
+(defun cider-view-refcard ()
+  "View the refcard in your default browser."
+  (interactive)
+  (browse-url (cider-refcard-url)))
+
+(defconst cider-report-bug-url "https://github.com/clojure-emacs/cider/issues/new"
+  "The URL to report a CIDER issue.")
+
+(defun cider-report-bug ()
+  "Report a bug in your default browser."
+  (interactive)
+  (browse-url cider-report-bug-url))
+
+(defun cider--project-name (dir)
+  "Extracts a project name from DIR, possibly nil.
+The project name is the final component of DIR if not nil."
+  (when dir
+    (file-name-nondirectory (directory-file-name dir))))
+
+;;; Vectors
+(defun cider--deep-vector-to-list (x)
+  "Convert vectors in X to lists.
+If X is a sequence, return a list of `cider--deep-vector-to-list' applied to
+each of its elements.
+Any other value is just returned."
+  (if (sequencep x)
+      (mapcar #'cider--deep-vector-to-list x)
+    x))
+
+
+;;; Help mode
+
+;; Same as https://github.com/emacs-mirror/emacs/blob/86d083438dba60dc00e9e96414bf7e832720c05a/lisp/help-mode.el#L355
+;; the original function uses some buffer local variables, but the buffer used
+;; is not configurable. It defaults to (help-buffer)
+
+(defun cider--help-setup-xref (item interactive-p buffer)
+  "Invoked from commands using the \"*Help*\" buffer to install some xref info.
+
+ITEM is a (FUNCTION . ARGS) pair appropriate for recreating the help
+buffer after following a reference.  INTERACTIVE-P is non-nil if the
+calling command was invoked interactively.  In this case the stack of
+items for help buffer \"back\" buttons is cleared.  Use BUFFER for the
+buffer local variables.
+
+This should be called very early, before the output buffer is cleared,
+because we want to record the \"previous\" position of point so we can
+restore it properly when going back."
+  (with-current-buffer buffer
+    (when help-xref-stack-item
+      (push (cons (point) help-xref-stack-item) help-xref-stack)
+      (setq help-xref-forward-stack nil))
+    (when interactive-p
+      (let ((tail (nthcdr 10 help-xref-stack)))
+        ;; Truncate the stack.
+        (if tail (setcdr tail nil))))
+    (setq help-xref-stack-item item)))
+
+(defcustom cider-doc-xref-regexp "`\\(.*?\\)`"
+  "The regexp used to search Clojure vars in doc buffers."
+  :type 'regexp
+  :safe #'stringp
+  :group 'cider
+  :package-version '(cider . "0.13.0"))
+
+(defun cider--find-symbol-xref ()
+  "Parse and return the first clojure symbol in current buffer.
+Use `cider-doc-xref-regexp' for the search.  Set match data and return a
+string of the Clojure symbol.  Return nil if there are no more matches in
+the buffer."
+  (when (re-search-forward cider-doc-xref-regexp nil t)
+    (match-string 1)))
+
+(declare-function cider-doc-lookup "cider-doc")
+(declare-function cider--eldoc-remove-dot "cider-eldoc")
+
+;; Taken from: https://github.com/emacs-mirror/emacs/blob/65c8c7cb96c14f9c6accd03cc8851b5a3459049e/lisp/help-mode.el#L551-L565
+(defun cider--make-back-forward-xrefs (&optional buffer)
+  "Insert special references `back' and `forward', as in `help-make-xrefs'.
+
+Optional argument BUFFER is the buffer in which to insert references.
+Default is current buffer."
+  (with-current-buffer (or buffer (current-buffer))
+    (insert "\n")
+    (when (or help-xref-stack help-xref-forward-stack)
+      (insert "\n"))
+    ;; Make a back-reference in this buffer if appropriate.
+    (when help-xref-stack
+      (help-insert-xref-button help-back-label 'help-back
+                               (current-buffer)))
+    ;; Make a forward-reference in this buffer if appropriate.
+    (when help-xref-forward-stack
+      (when help-xref-stack
+        (insert "\t"))
+      (help-insert-xref-button help-forward-label 'help-forward
+                               (current-buffer)))
+    (when (or help-xref-stack help-xref-forward-stack)
+      (insert "\n"))))
+
+;; Similar to https://github.com/emacs-mirror/emacs/blob/65c8c7cb96c14f9c6accd03cc8851b5a3459049e/lisp/help-mode.el#L404
+(defun cider--doc-make-xrefs ()
+  "Parse and hyperlink documentation cross-references in current buffer.
+Find cross-reference information in a buffer and activate such cross
+references for selection with `help-xref'.  Cross-references are parsed
+using `cider--find-symbol-xref'.
+
+Special references `back' and `forward' are made to go back and forth
+through a stack of help buffers.  Variables `help-back-label' and
+`help-forward-label' specify the text for that."
+  (interactive "b")
+
+  ;; parse the docstring and create xrefs for symbols
+  (save-excursion
+    (goto-char (point-min))
+    (let ((symbol))
+      (while (setq symbol (cider--find-symbol-xref))
+        (replace-match "")
+        (insert-text-button symbol
+                            'type 'help-xref
+                            'help-function (apply-partially #'cider-doc-lookup
+                                                            (cider--eldoc-remove-dot symbol))))))
+  (cider--make-back-forward-xrefs))
+
+
+;;; Words of inspiration
+(defun cider-user-first-name ()
+  "Find the current user's first name."
+  (let ((name (if (string= (user-full-name) "")
+                  (user-login-name)
+                (user-full-name))))
+    (string-match "^[^ ]*" name)
+    (capitalize (match-string 0 name))))
+
+(defvar cider-words-of-inspiration
+  `("The best way to predict the future is to invent it. -Alan Kay"
+    "A point of view is worth 80 IQ points. -Alan Kay"
+    "Lisp isn't a language, it's a building material. -Alan Kay"
+    "Simple things should be simple, complex things should be possible. -Alan Kay"
+    "Everything should be as simple as possible, but not simpler. -Albert Einstein"
+    "Measuring programming progress by lines of code is like measuring aircraft building progress by weight. -Bill Gates"
+    "Controlling complexity is the essence of computer programming. -Brian Kernighan"
+    "The unavoidable price of reliability is simplicity. -C.A.R. Hoare"
+    "You're bound to be unhappy if you optimize everything. -Donald Knuth"
+    "Simplicity is prerequisite for reliability. -Edsger W. Dijkstra"
+    "Elegance is not a dispensable luxury but a quality that decides between success and failure. -Edsger W. Dijkstra"
+    "Deleted code is debugged code. -Jeff Sickel"
+    "The key to performance is elegance, not battalions of special cases. -Jon Bentley and Doug McIlroy"
+    "First, solve the problem. Then, write the code. -John Johnson"
+    "Simplicity is the ultimate sophistication. -Leonardo da Vinci"
+    "Programming is not about typing... it's about thinking. -Rich Hickey"
+    "Design is about pulling things apart. -Rich Hickey"
+    "Programmers know the benefits of everything and the tradeoffs of nothing. -Rich Hickey"
+    "Code never lies, comments sometimes do. -Ron Jeffries"
+    "The true delight is in the finding out rather than in the knowing. -Isaac Asimov"
+    "If paredit is not for you, then you need to become the sort of person that paredit is for. -Phil Hagelberg"
+    "Express Yourself. -Madonna"
+    "Put on your red shoes and dance the blues. -David Bowie"
+    "Do. Or do not. There is no try. -Yoda"
+    "The enjoyment of one's tools is an essential ingredient of successful work. -Donald E. Knuth"
+    "Not all those who wander are lost. -J.R.R. Tolkien"
+    "The best way to learn is to do. -P.R. Halmos"
+    "If you wish to make an apple pie from scratch, you must first invent the universe. -Carl Sagan"
+    "Learn the rules like a pro, so you can break them like an artist. -Pablo Picasso"
+    "The only way of discovering the limits of the possible is to venture a little way past them into the impossible. -Arthur C. Clarke"
+    "Don't wish it were easier. Wish you were better. -Jim Rohn"
+    "One chord is fine. Two chords is pushing it. Three chords and you're into jazz. -Lou Reed"
+    "We are all apprentices in a craft where no one ever becomes a master. -Ernest Hemingway"
+    "A designer knows he has achieved perfection not when there is nothing left to add, but when there is nothing left to take away. -Antoine de Saint-Exupery"
+    "Clojure isn't a language, it's a building material."
+    "Think big!"
+    "Think bold!"
+    "Think fun!"
+    "Code big!"
+    "Code bold!"
+    "Code fun!"
+    "Take this REPL, fellow hacker, and may it serve you well."
+    "Let the hacking commence!"
+    "Hacks and glory await!"
+    "Hack and be merry!"
+    "Your hacking starts... NOW!"
+    "May the Source be with you!"
+    "May the Source shine upon thy REPL!"
+    "Code long and prosper!"
+    "Happy hacking!"
+    "nREPL server is up, CIDER REPL is online!"
+    "CIDER REPL operational!"
+    "Your imagination is the only limit to what you can do with this REPL!"
+    "This REPL is yours to command!"
+    "Fame is but a hack away!"
+    "The REPL is not enough, but it is such a perfect place to start..."
+    "Keep on codin' in the free world!"
+    "What we do in the REPL echoes in eternity!"
+    "Evaluating is believing."
+    "To infinity... and beyond."
+    "Showtime!"
+    "Unfortunately, no one can be told what CIDER is. You have to figure this out yourself."
+    "Procure a bottle of cider to achieve optimum programming results."
+    "In parentheses we trust!"
+    "Write you some Clojure for Great Good!"
+    "Oh, what a day... what a lovely day!"
+    "What a day! What cannot be accomplished on such a splendid day!"
+    "Home is where your REPL is."
+    "The worst day programming is better than the best day working."
+    "The only thing worse than a rebel without a cause is a REPL without a clause."
+    "In the absence of parentheses, chaos prevails."
+    "One REPL to rule them all, One REPL to find them, One REPL to bring them all, and in parentheses bind them!"
+    ,(format "%s, I've a feeling we're not in Kansas anymore."
+             (cider-user-first-name))
+    ,(format "%s, this could be the start of a beautiful program."
+             (cider-user-first-name)))
+  "Scientifically-proven optimal words of hackerish encouragement.")
+
+(defun cider-random-words-of-inspiration ()
+  "Select a random entry from `cider-words-of-inspiration'."
+  (eval (nth (random (length cider-words-of-inspiration))
+             cider-words-of-inspiration)))
+
+(defvar cider-tips
+  '("Press <\\[cider-connect]> to connect to a running nREPL server."
+    "Press <\\[cider-quit]> to quit the current connection."
+    "Press <\\[cider-view-manual]> to view CIDER's manual."
+    "Press <\\[cider-view-refcard]> to view CIDER's refcard."
+    "Press <\\[describe-mode]> to see a list of the keybindings available (this will work in every Emacs buffer)."
+    "Press <\\[cider-repl-handle-shortcut]> to quickly invoke some REPL command."
+    "Press <\\[cider-switch-to-last-clojure-buffer]> to switch between the REPL and a Clojure source buffer."
+    "Press <\\[cider-doc]> to view the documentation for something (e.g. a var, a Java method)."
+    "Press <\\[cider-find-resource]> to find a resource on the classpath."
+    "Press <\\[cider-find-var]> to jump to the source of something (e.g. a var, a Java method)."
+    "Press <\\[cider-selector]> to quickly select a CIDER buffer."
+    "Press <\\[cider-test-run-ns-tests]> to run the tests for the current namespace."
+    "Press <\\[cider-test-run-loaded-tests]> to run all loaded tests."
+    "Press <\\[cider-test-run-project-tests]> to run all tests for the current project."
+    "Press <\\[cider-apropos]> to look for a symbol by some search string."
+    "Press <\\[cider-apropos-documentation]> to look for a symbol that has some string in its docstring."
+    "Press <\\[cider-eval-defun-at-point]> to eval the top-level form at point."
+    "Press <\\[cider-eval-defun-up-to-point]> to eval the top-level form up to the point."
+    "Press <\\[cider-eval-sexp-up-to-point]> to eval the current form up to the point."
+    "Press <\\[cider-eval-sexp-at-point]> to eval the current form around the point."
+    "Press <\\[cider-eval-sexp-at-point-in-context]> to eval the current form around the point in a user-provided context."
+    "Press <\\[cider-eval-buffer]> to eval the entire source buffer."
+    "Press <\\[cider-scratch]> to create a Clojure scratchpad. Pretty handy for prototyping."
+    "Press <\\[cider-read-and-eval]> to evaluate some Clojure expression directly in the minibuffer."
+    "Press <\\[cider-drink-a-sip]> to get more CIDER tips."
+    "Press <\\[cider-browse-ns-all]> to start CIDER's namespace browser."
+    "Press <\\[cider-classpath]> to start CIDER's classpath browser."
+    "Press <\\[cider-repl-history]> to start CIDER's REPL input history browser."
+    "Press <\\[cider-macroexpand-1]> to expand the preceding macro."
+    "Press <\\[cider-inspect]> to inspect the preceding expression's result."
+    "Press <C-u \\[cider-inspect]> to inspect the defun at point's result."
+    "Press <C-u C-u \\[cider-inspect]> to read Clojure code from the minibuffer and inspect its result."
+    "Press <\\[cider-ns-refresh]> to reload modified and unloaded namespaces."
+    "You can define Clojure functions to be called before and after `cider-ns-refresh' (see `cider-ns-refresh-before-fn' and `cider-ns-refresh-after-fn'."
+    "Press <\\[cider-describe-current-connection]> to view information about the connection."
+    "Press <\\[cider-undef]> to undefine a symbol in the current namespace."
+    "Press <\\[cider-interrupt]> to interrupt an ongoing evaluation."
+    "Use <M-x customize-group RET cider RET> to see every possible setting you can customize."
+    "Use <M-x customize-group RET cider-repl RET> to see every possible REPL setting you can customize."
+    "Enable `eldoc-mode' to display function & method signatures in the minibuffer."
+    "Enable `cider-enlighten-mode' to display the locals of a function when it's executed."
+    "Use <\\[cider-close-ancillary-buffers]> to close all ancillary buffers created by CIDER (e.g. *cider-doc*)."
+    "Exploring CIDER's menu-bar entries is a great way to discover features."
+    "Keep in mind that some commands don't have a keybinding by default. Explore CIDER!"
+    "Tweak `cider-repl-prompt-function' to customize your REPL prompt."
+    "Tweak `cider-eldoc-ns-function' to customize the way namespaces are displayed by eldoc.")
+  "Some handy CIDER tips."
+  )
+
+(defun cider-random-tip ()
+  "Select a random tip from `cider-tips'."
+  (substitute-command-keys (nth (random (length cider-tips)) cider-tips)))
+
+(defun cider-drink-a-sip ()
+  "Show a random tip."
+  (interactive)
+  (message (cider-random-tip)))
+
+(defun cider-column-number-at-pos (pos)
+  "Analog to `line-number-at-pos'.
+Return buffer column number at position POS."
+  (save-excursion
+    (goto-char pos)
+    ;; we have to adjust the column number by 1 to account for the fact
+    ;; that Emacs starts counting columns from 0 and Clojure from 1
+    (1+ (current-column))))
+
+(defun cider-propertize (text kind)
+  "Propertize TEXT as KIND.
+KIND can be the symbols `ns', `var', `emph', `fn', or a face name."
+  (propertize text 'face (pcase kind
+                           (`fn 'font-lock-function-name-face)
+                           (`var 'font-lock-variable-name-face)
+                           (`ns 'font-lock-type-face)
+                           (`emph 'font-lock-keyword-face)
+                           (face face))))
+
+(defun cider--menu-add-help-strings (menu-list)
+  "Add a :help entries to items in MENU-LIST."
+  (mapcar (lambda (x)
+            (cond
+             ((listp x) (cider--menu-add-help-strings x))
+             ((and (vectorp x)
+                   (not (plist-get (append x nil) :help))
+                   (functionp (elt x 1)))
+              (vconcat x `[:help ,(documentation (elt x 1))]))
+             (t x)))
+          menu-list))
+
+(defcustom cider-jdk-src-paths '("/usr/lib/jvm/openjdk-8/src.zip")
+  "Used by `cider-stacktrace-navigate'.
+Zip/jar files work, but it's better to extract them and put the directory
+paths here.  Clojure sources here:
+https://repo1.maven.org/maven2/org/clojure/clojure/1.8.0/."
+  :group 'cider
+  :package-version '(cider . "0.17.0")
+  :type '(list string))
+
+(defun cider-resolve-java-class (class)
+  "Return a path to a Java source file that corresponds to CLASS.
+
+This will be a zip/jar path for archived sources and a normal
+file path otherwise."
+  (when class
+    (let ((file-name (concat (replace-regexp-in-string "\\." "/" class) ".java")))
+      (cl-find-if
+       'file-exists-p
+       (mapcar
+        (lambda (d)
+          (cond ((file-directory-p d)
+                 (expand-file-name file-name d))
+                ((and (file-exists-p d)
+                      (member (file-name-extension d) '("jar" "zip")))
+                 (format "zip:file:%s!/%s" d file-name))
+                (t (error "Unexpected archive: %s" d))))
+        cider-jdk-src-paths)))))
+
+(provide 'cider-util)
+
+;;; cider-util.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-util.elc b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-util.elc
new file mode 100644
index 0000000000..3e7e1beb8c
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-util.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider.el b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider.el
new file mode 100644
index 0000000000..73127a5785
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider.el
@@ -0,0 +1,1309 @@
+;;; cider.el --- Clojure Interactive Development Environment that Rocks -*- lexical-binding: t -*-
+
+;; Copyright © 2012-2013 Tim King, Phil Hagelberg, Bozhidar Batsov
+;; Copyright © 2013-2018 Bozhidar Batsov, Artur Malabarba and CIDER contributors
+;;
+;; Author: Tim King <kingtim@gmail.com>
+;;         Phil Hagelberg <technomancy@gmail.com>
+;;         Bozhidar Batsov <bozhidar@batsov.com>
+;;         Artur Malabarba <bruce.connor.am@gmail.com>
+;;         Hugo Duncan <hugo@hugoduncan.org>
+;;         Steve Purcell <steve@sanityinc.com>
+;; Maintainer: Bozhidar Batsov <bozhidar@batsov.com>
+;; URL: http://www.github.com/clojure-emacs/cider
+;; Version: 0.18.0-snapshot
+;; Package-Requires: ((emacs "25") (clojure-mode "5.7.0") (pkg-info "0.4") (queue "0.1.1") (spinner "1.7") (seq "2.16") (sesman "0.1.1"))
+;; Keywords: languages, clojure, cider
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;; This file is not part of GNU Emacs.
+
+;;; Commentary:
+
+;; Provides a Clojure interactive development environment for Emacs, built on
+;; top of nREPL.
+
+;;; Installation:
+
+;; Available as a package in melpa.org and stable.melpa.org
+
+;; (add-to-list 'package-archives
+;;              '("melpa" . "https://melpa.org/packages/"))
+;;
+;; or
+;;
+;; (add-to-list 'package-archives
+;;              '("melpa-stable" . "https://stable.melpa.org/packages/") t)
+;;
+;; M-x package-install cider
+
+;;; Usage:
+
+;; M-x cider-jack-in-clj
+;; M-x cider-jack-in-cljs
+;;
+;; M-x cider-connect-sibling-clj
+;; M-x cider-connect-sibling-cljs
+;;
+;; M-x cider-connect-clj
+;; M-x cider-connect-cljs
+
+;;; Code:
+
+(defgroup cider nil
+  "Clojure Interactive Development Environment that Rocks."
+  :prefix "cider-"
+  :group 'applications
+  :link '(url-link :tag "GitHub" "https://github.com/clojure-emacs/cider")
+  :link '(url-link :tag "Online Manual" "http://docs.cider.mx")
+  :link '(emacs-commentary-link :tag "Commentary" "cider"))
+
+(require 'cider-client)
+(require 'cider-eldoc)
+(require 'cider-repl)
+(require 'cider-repl-history)
+(require 'cider-connection)
+(require 'cider-mode)
+(require 'cider-common)
+(require 'cider-compat)
+(require 'cider-debug)
+
+(require 'tramp-sh)
+(require 'subr-x)
+(require 'seq)
+(require 'sesman)
+
+(defconst cider-version "0.18.0-snapshot"
+  "Fallback version used when it cannot be extracted automatically.
+Normally it won't be used, unless `pkg-info' fails to extract the
+version from the CIDER package or library.")
+
+(defconst cider-codename "Saigon"
+  "Codename used to denote stable releases.")
+
+(defcustom cider-lein-command
+  "lein"
+  "The command used to execute Leiningen."
+  :type 'string
+  :group 'cider)
+
+(defcustom cider-lein-global-options
+  nil
+  "Command global options used to execute Leiningen (e.g.: -o for offline)."
+  :type 'string
+  :group 'cider
+  :safe #'stringp)
+
+(defcustom cider-lein-parameters
+  "repl :headless :host ::"
+  "Params passed to Leiningen to start an nREPL server via `cider-jack-in'."
+  :type 'string
+  :group 'cider
+  :safe #'stringp)
+
+(defcustom cider-boot-command
+  "boot"
+  "The command used to execute Boot."
+  :type 'string
+  :group 'cider
+  :package-version '(cider . "0.9.0"))
+
+(defcustom cider-boot-global-options
+  nil
+  "Command global options used to execute Boot (e.g.: -c for checkouts)."
+  :type 'string
+  :group 'cider
+  :safe #'stringp
+  :package-version '(cider . "0.14.0"))
+
+(defcustom cider-boot-parameters
+  "repl -s -H :: wait"
+  "Params passed to boot to start an nREPL server via `cider-jack-in'."
+  :type 'string
+  :group 'cider
+  :safe #'stringp
+  :package-version '(cider . "0.9.0"))
+
+(defcustom cider-clojure-cli-command
+  "clojure"
+  "The command used to execute clojure with tools.deps (requires Clojure 1.9+).
+Don't use clj here, as it doesn't work when spawned from Emacs due to
+it using rlwrap."
+  :type 'string
+  :group 'cider
+  :safe #'stringp
+  :package-version '(cider . "0.17.0"))
+
+(defcustom cider-clojure-cli-global-options
+  nil
+  "Command line options used to execute clojure with tools.deps."
+  :type 'string
+  :group 'cider
+  :safe #'stringp
+  :package-version '(cider . "0.17.0"))
+
+(defcustom cider-clojure-cli-parameters
+  "-e '(require (quote cider-nrepl.main)) (cider-nrepl.main/init %s)'"
+  "Params passed to clojure to start an nREPL server via `cider-jack-in'.
+This is evaluated using `format', with the first argument being the Clojure
+vector of middleware variables as a string."
+  :type 'string
+  :group 'cider
+  :safe #'stringp
+  :package-version '(cider . "0.17.0"))
+
+(defcustom cider-shadow-cljs-command
+  "npx shadow-cljs"
+  "The command used to execute shadow-cljs.
+
+By default we favor the project-specific shadow-cljs over the system-wide."
+  :type 'string
+  :group 'cider
+  :safe #'stringp
+  :package-version '(cider . "0.17.0"))
+
+(defcustom cider-shadow-cljs-global-options
+  ""
+  "Command line options used to execute shadow-cljs (e.g.: -v for verbose mode)."
+  :type 'string
+  :group 'cider
+  :safe #'stringp
+  :package-version '(cider . "0.17.0"))
+
+(defcustom cider-shadow-cljs-parameters
+  "server"
+  "Params passed to shadow-cljs to start an nREPL server via `cider-jack-in'."
+  :type 'string
+  :group 'cider
+  :safe #'stringp
+  :package-version '(cider . "0.17.0"))
+
+(defcustom cider-gradle-command
+  "gradle"
+  "The command used to execute Gradle."
+  :type 'string
+  :group 'cider
+  :safe #'stringp
+  :package-version '(cider . "0.10.0"))
+
+(defcustom cider-gradle-global-options
+  "--no-daemon"
+  "Command line options used to execute Gradle (e.g.: -m for dry run)."
+  :type 'string
+  :group 'cider
+  :safe #'stringp
+  :package-version '(cider . "0.14.0"))
+
+(defcustom cider-gradle-parameters
+  "clojureRepl"
+  "Params passed to gradle to start an nREPL server via `cider-jack-in'."
+  :type 'string
+  :group 'cider
+  :safe #'stringp
+  :package-version '(cider . "0.10.0"))
+
+(defcustom cider-default-repl-command "clojure-cli"
+  "The default command and parameters to use when connecting to nREPL.
+This value will only be consulted when no identifying file types, i.e.
+project.clj for leiningen or build.boot for boot, could be found.
+
+As tools.deps is bundled with Clojure itself, it's the default REPL command."
+  :type 'string
+  :group 'cider
+  :safe #'stringp
+  :package-version '(cider . "0.9.0"))
+
+(defcustom cider-preferred-build-tool
+  nil
+  "Allow choosing a build system when there are many.
+When there are artifacts from multiple build systems (\"lein\", \"boot\",
+\"gradle\") the user is prompted to select one of them.  When non-nil, this
+variable will suppress this behavior and will select whatever build system
+is indicated by the variable if present.  Note, this is only when CIDER
+cannot decide which of many build systems to use and will never override a
+command when there is no ambiguity."
+  :type '(choice (const "lein")
+                 (const "boot")
+                 (const "clojure-cli")
+                 (const "shadow-cljs")
+                 (const "gradle")
+                 (const :tag "Always ask" nil))
+  :group 'cider
+  :safe #'stringp
+  :package-version '(cider . "0.13.0"))
+
+(defcustom cider-allow-jack-in-without-project 'warn
+  "Controls what happens when doing `cider-jack-in' outside a project.
+When set to 'warn you'd prompted to confirm the command.
+When set to t `cider-jack-in' will quietly continue.
+When set to nil `cider-jack-in' will fail."
+  :type '(choice (const :tag "always" t)
+                 (const 'warn)
+                 (const :tag "never" nil))
+  :group 'cider
+  :safe #'stringp
+  :package-version '(cider . "0.15.0"))
+
+(defcustom cider-known-endpoints nil
+  "A list of connection endpoints where each endpoint is a list.
+For example: \\='((\"label\" \"host\" \"port\")).
+The label is optional so that \\='(\"host\" \"port\") will suffice.
+This variable is used by `cider-connect'."
+  :type '(repeat (list (string :tag "label")
+                       (string :tag "host")
+                       (string :tag "port")))
+  :group 'cider)
+
+(defcustom cider-connected-hook nil
+  "List of functions to call when connected to Clojure nREPL server."
+  :type 'hook
+  :group 'cider
+  :package-version '(cider . "0.9.0"))
+
+(defcustom cider-disconnected-hook nil
+  "List of functions to call when disconnected from the Clojure nREPL server."
+  :type 'hook
+  :group 'cider
+  :package-version '(cider . "0.9.0"))
+
+(defcustom cider-inject-dependencies-at-jack-in t
+  "When nil, do not inject repl dependencies (most likely nREPL middlewares) at `cider-jack-in' time."
+  :type 'boolean
+  :safe #'booleanp
+  :version '(cider . "0.11.0"))
+
+(defcustom cider-offer-to-open-cljs-app-in-browser t
+  "When nil, do not offer to open ClojureScript apps in a browser on connect."
+  :type 'boolean
+  :safe #'booleanp
+  :version '(cider . "0.15.0"))
+
+(defvar cider-ps-running-nrepls-command "ps u | grep leiningen"
+  "Process snapshot command used in `cider-locate-running-nrepl-ports'.")
+
+(defvar cider-ps-running-nrepl-path-regexp-list
+  '("\\(?:leiningen.original.pwd=\\)\\(.+?\\) -D"
+    "\\(?:-classpath +:?\\(.+?\\)/self-installs\\)")
+  "Regexp list to get project paths.
+Extract project paths from output of `cider-ps-running-nrepls-command'.
+Sub-match 1 must be the project path.")
+
+(defvar cider-host-history nil
+  "Completion history for connection hosts.")
+
+;;;###autoload
+(defun cider-version ()
+  "Display CIDER's version."
+  (interactive)
+  (message "CIDER %s" (cider--version)))
+
+(defun cider-jack-in-command (project-type)
+  "Determine the command `cider-jack-in' needs to invoke for the PROJECT-TYPE."
+  (pcase project-type
+    ("lein" cider-lein-command)
+    ("boot" cider-boot-command)
+    ("clojure-cli" cider-clojure-cli-command)
+    ("shadow-cljs" cider-shadow-cljs-command)
+    ("gradle" cider-gradle-command)
+    (_ (user-error "Unsupported project type `%s'" project-type))))
+
+(defun cider-jack-in-resolve-command (project-type)
+  "Determine the resolved file path to `cider-jack-in-command'.
+Throws an error if PROJECT-TYPE is unknown.  Known types are
+\"lein\", \"boot\", and \"gradle\"."
+  (pcase project-type
+    ("lein" (cider--resolve-command cider-lein-command))
+    ("boot" (cider--resolve-command cider-boot-command))
+    ("clojure-cli" (cider--resolve-command cider-clojure-cli-command))
+    ;; here we have to account for the possibility that the command is either
+    ;; "npx shadow-cljs" or just "shadow-cljs"
+    ("shadow-cljs" (let ((parts (split-string cider-shadow-cljs-command)))
+                     (when-let* ((command (cider--resolve-command (car parts))))
+                       (mapconcat #'identity (cons command (cdr parts)) " "))))
+    ("gradle" (cider--resolve-command cider-gradle-command))
+    (_ (user-error "Unsupported project type `%s'" project-type))))
+
+(defun cider-jack-in-global-options (project-type)
+  "Determine the command line options for `cider-jack-in' for the PROJECT-TYPE."
+  (pcase project-type
+    ("lein" cider-lein-global-options)
+    ("boot" cider-boot-global-options)
+    ("clojure-cli" cider-clojure-cli-global-options)
+    ("shadow-cljs" cider-shadow-cljs-global-options)
+    ("gradle" cider-gradle-global-options)
+    (_ (user-error "Unsupported project type `%s'" project-type))))
+
+(defun cider-jack-in-params (project-type)
+  "Determine the commands params for `cider-jack-in' for the PROJECT-TYPE."
+  (pcase project-type
+    ("lein" cider-lein-parameters)
+    ("boot" cider-boot-parameters)
+    ("clojure-cli" (format cider-clojure-cli-parameters
+                           (concat
+                            "["
+                            (mapconcat
+                             (apply-partially #'format "\"%s\"")
+                             (cider-jack-in-normalized-nrepl-middlewares)
+                             ", ")
+                            "]")))
+    ("shadow-cljs" cider-shadow-cljs-parameters)
+    ("gradle" cider-gradle-parameters)
+    (_ (user-error "Unsupported project type `%s'" project-type))))
+
+
+;;; Jack-in dependencies injection
+(defvar cider-jack-in-dependencies nil
+  "List of dependencies where elements are lists of artifact name and version.")
+(put 'cider-jack-in-dependencies 'risky-local-variable t)
+(cider-add-to-alist 'cider-jack-in-dependencies
+                    "org.clojure/tools.nrepl" "0.2.13")
+
+(defvar cider-jack-in-cljs-dependencies nil
+  "List of dependencies where elements are lists of artifact name and version.
+Added to `cider-jack-in-dependencies' when doing `cider-jack-in-cljs'.")
+(put 'cider-jack-in-cljs-dependencies 'risky-local-variable t)
+(cider-add-to-alist 'cider-jack-in-cljs-dependencies "cider/piggieback" "0.3.5")
+
+(defvar cider-jack-in-dependencies-exclusions nil
+  "List of exclusions for jack in dependencies.
+Elements of the list are artifact name and list of exclusions to apply for the artifact.")
+(put 'cider-jack-in-dependencies-exclusions 'risky-local-variable t)
+(cider-add-to-alist 'cider-jack-in-dependencies-exclusions
+                    "org.clojure/tools.nrepl" '("org.clojure/clojure"))
+
+(defconst cider-clojure-artifact-id "org.clojure/clojure"
+  "Artifact identifier for Clojure.")
+
+(defconst cider-minimum-clojure-version "1.8.0"
+  "Minimum supported version of Clojure.")
+
+(defconst cider-latest-clojure-version "1.10.0"
+  "Latest supported version of Clojure.")
+
+(defcustom cider-jack-in-auto-inject-clojure nil
+  "Version of clojure to auto-inject into REPL.
+If nil, do not inject Clojure into the REPL.  If `latest', inject
+`cider-latest-clojure-version', which should approximate to the most recent
+version of Clojure.  If `minimal', inject `cider-minimum-clojure-version',
+which will be the lowest version CIDER supports.  If a string, use this as
+the version number.  If it is a list, the first element should be a string,
+specifying the artifact ID, and the second element the version number."
+  :type '(choice (const :tag "None" nil)
+                 (const :tag "Latest" 'latest)
+                 (const :tag "Minimal" 'minimal)
+                 (string :tag "Specific Version")
+                 (list :tag "Artifact ID and Version"
+                       (string :tag "Artifact ID")
+                       (string :tag "Version"))))
+
+(defvar cider-jack-in-lein-plugins nil
+  "List of Leiningen plugins to be injected at jack-in.
+Each element is a list of artifact name and version, followed optionally by
+keyword arguments.  The only keyword argument currently accepted is
+`:predicate', which should be given a function that takes the list (name,
+version, and keyword arguments) and returns non-nil to indicate that the
+plugin should actually be injected.  (This is useful primarily for packages
+that extend CIDER, not for users.  For example, a refactoring package might
+want to inject some middleware only when within a project context.)")
+(put 'cider-jack-in-lein-plugins 'risky-local-variable t)
+(cider-add-to-alist 'cider-jack-in-lein-plugins
+                    "cider/cider-nrepl" (upcase cider-version))
+
+(defvar cider-jack-in-cljs-lein-plugins nil
+  "List of Leiningen plugins to be injected at jack-in.
+Added to `cider-jack-in-lein-plugins' (which see) when doing
+`cider-jack-in-cljs'.")
+(put 'cider-jack-in-cljs-lein-plugins 'risky-local-variable t)
+
+(defun cider-jack-in-normalized-lein-plugins ()
+  "Return a normalized list of Leiningen plugins to be injected.
+See `cider-jack-in-lein-plugins' for the format, except that the list
+returned by this function does not include keyword arguments."
+  (thread-last cider-jack-in-lein-plugins
+    (seq-filter
+     (lambda (spec)
+       (if-let* ((pred (plist-get (seq-drop spec 2) :predicate)))
+           (funcall pred spec)
+         t)))
+    (mapcar
+     (lambda (spec)
+       (seq-take spec 2)))))
+
+(defvar cider-jack-in-nrepl-middlewares nil
+  "List of Clojure variable names.
+Each of these Clojure variables should hold a vector of nREPL middlewares.
+Instead of a string, an element can be a list containing a string followed
+by optional keyword arguments.  The only keyword argument currently
+accepted is `:predicate', which should be given a function that takes the
+list (string and keyword arguments) and returns non-nil to indicate that
+the middlewares should actually be injected.")
+(put 'cider-jack-in-nrepl-middlewares 'risky-local-variable t)
+(add-to-list 'cider-jack-in-nrepl-middlewares "cider.nrepl/cider-middleware")
+
+(defvar cider-jack-in-cljs-nrepl-middlewares nil
+  "List of Clojure variable names.
+Added to `cider-jack-in-nrepl-middlewares' (which see) when doing
+`cider-jack-in-cljs'.")
+(put 'cider-jack-in-cljs-nrepl-middlewares 'risky-local-variable t)
+(add-to-list 'cider-jack-in-cljs-nrepl-middlewares "cider.piggieback/wrap-cljs-repl")
+
+(defun cider-jack-in-normalized-nrepl-middlewares ()
+  "Return a normalized list of middleware variable names.
+See `cider-jack-in-nrepl-middlewares' for the format, except that the list
+returned by this function only contains strings."
+  (thread-last cider-jack-in-nrepl-middlewares
+    (seq-filter
+     (lambda (spec)
+       (or (not (listp spec))
+           (if-let* ((pred (plist-get (cdr spec) :predicate)))
+               (funcall pred spec)
+             t))))
+    (mapcar
+     (lambda (spec)
+       (if (listp spec)
+           (car spec)
+         spec)))))
+
+(defun cider--list-as-boot-artifact (list)
+  "Return a boot artifact string described by the elements of LIST.
+LIST should have the form (ARTIFACT-NAME ARTIFACT-VERSION).  The returned
+string is quoted for passing as argument to an inferior shell."
+  (concat "-d " (shell-quote-argument (format "%s:%s" (car list) (cadr list)))))
+
+(defun cider-boot-dependencies (dependencies)
+  "Return a list of boot artifact strings created from DEPENDENCIES."
+  (concat (mapconcat #'cider--list-as-boot-artifact dependencies " ")
+          (unless (seq-empty-p dependencies) " ")))
+
+(defun cider-boot-middleware-task (params middlewares)
+  "Create a command to add MIDDLEWARES with corresponding PARAMS."
+  (concat "cider.tasks/add-middleware "
+          (mapconcat (lambda (middleware)
+                       (format "-m %s" (shell-quote-argument middleware)))
+                     middlewares
+                     " ")
+          " " params))
+
+(defun cider-boot-jack-in-dependencies (global-opts params dependencies plugins middlewares)
+  "Create boot jack-in dependencies.
+Does so by concatenating GLOBAL-OPTS, DEPENDENCIES,
+PLUGINS and MIDDLEWARES.  PARAMS and MIDDLEWARES are passed on to
+`cider-boot-middleware-task` before concatenating and DEPENDENCIES and PLUGINS
+ are passed on to `cider-boot-dependencies`."
+  (concat global-opts
+          (unless (seq-empty-p global-opts) " ")
+          "-i \"(require 'cider.tasks)\" " ;; Note the space at the end here
+          (cider-boot-dependencies (append dependencies plugins))
+          (cider-boot-middleware-task params middlewares)))
+
+(defun cider--lein-artifact-exclusions (exclusions)
+  "Return an exclusions vector described by the elements of EXCLUSIONS."
+  (if exclusions
+      (format " :exclusions [%s]" (mapconcat #'identity exclusions " "))
+    ""))
+
+(defun cider--list-as-lein-artifact (list &optional exclusions)
+  "Return an artifact string described by the elements of LIST.
+LIST should have the form (ARTIFACT-NAME ARTIFACT-VERSION).  Optionally a list
+of EXCLUSIONS can be provided as well.  The returned
+string is quoted for passing as argument to an inferior shell."
+  (shell-quote-argument (format "[%s %S%s]" (car list) (cadr list) (cider--lein-artifact-exclusions exclusions))))
+
+(defun cider-lein-jack-in-dependencies (global-opts params dependencies dependencies-exclusions lein-plugins)
+  "Create lein jack-in dependencies.
+Does so by concatenating GLOBAL-OPTS, DEPENDENCIES, with DEPENDENCIES-EXCLUSIONS
+removed, LEIN-PLUGINS, and finally PARAMS."
+  (concat
+   global-opts
+   (unless (seq-empty-p global-opts) " ")
+   (mapconcat #'identity
+              (append (seq-map (lambda (dep)
+                                 (let ((exclusions (cadr (assoc (car dep) dependencies-exclusions))))
+                                   (concat "update-in :dependencies conj "
+                                           (cider--list-as-lein-artifact dep exclusions))))
+                               dependencies)
+                      (seq-map (lambda (plugin)
+                                 (concat "update-in :plugins conj "
+                                         (cider--list-as-lein-artifact plugin)))
+                               lein-plugins))
+              " -- ")
+   " -- "
+   params))
+
+(defun cider-clojure-cli-jack-in-dependencies (global-opts params dependencies)
+  "Create Clojure tools.deps jack-in dependencies.
+Does so by concatenating GLOBAL-OPTS, DEPENDENCIES finally PARAMS."
+  (let ((dependencies (append dependencies cider-jack-in-lein-plugins)))
+    (concat
+     global-opts
+     (unless (seq-empty-p global-opts) " ")
+     "-Sdeps '{:deps {"
+     (mapconcat #'identity
+                (seq-map (lambda (dep) (format "%s {:mvn/version \"%s\"}" (car dep) (cadr dep))) dependencies)
+                " ")
+     "}}' "
+     params)))
+
+(defun cider-shadow-cljs-jack-in-dependencies (global-opts params dependencies)
+  "Create shadow-cljs jack-in deps.
+Does so by concatenating GLOBAL-OPTS, DEPENDENCIES finally PARAMS."
+  (let ((dependencies (append dependencies cider-jack-in-lein-plugins)))
+    (concat
+     global-opts
+     (unless (seq-empty-p global-opts) " ")
+     (mapconcat #'identity
+                (seq-map (lambda (dep) (format "-d %s:%s" (car dep) (cadr dep))) dependencies)
+                " ")
+     " "
+     params)))
+
+(defun cider-add-clojure-dependencies-maybe (dependencies)
+  "Return DEPENDENCIES with an added Clojure dependency if requested.
+See also `cider-jack-in-auto-inject-clojure'."
+  (if cider-jack-in-auto-inject-clojure
+      (if (consp cider-jack-in-auto-inject-clojure)
+          (cons cider-jack-in-auto-inject-clojure dependencies)
+        (cons (list cider-clojure-artifact-id
+                    (cond
+                     ((stringp cider-jack-in-auto-inject-clojure)
+                      cider-jack-in-auto-inject-clojure)
+                     ((eq cider-jack-in-auto-inject-clojure 'minimal)
+                      cider-minimum-clojure-version)
+                     ((eq cider-jack-in-auto-inject-clojure 'latest)
+                      cider-latest-clojure-version)))
+              dependencies))
+    dependencies))
+
+(defun cider-inject-jack-in-dependencies (global-opts params project-type)
+  "Return GLOBAL-OPTS and PARAMS with injected REPL dependencies.
+These are set in `cider-jack-in-dependencies', `cider-jack-in-lein-plugins' and
+`cider-jack-in-nrepl-middlewares' are injected from the CLI according to
+the used PROJECT-TYPE.  Eliminates the need for hacking profiles.clj or the
+boot script for supporting cider with its nREPL middleware and
+dependencies."
+  (pcase project-type
+    ("lein" (cider-lein-jack-in-dependencies
+             global-opts
+             params
+             (cider-add-clojure-dependencies-maybe
+              cider-jack-in-dependencies)
+             cider-jack-in-dependencies-exclusions
+             (cider-jack-in-normalized-lein-plugins)))
+    ("boot" (cider-boot-jack-in-dependencies
+             global-opts
+             params
+             (cider-add-clojure-dependencies-maybe
+              cider-jack-in-dependencies)
+             (cider-jack-in-normalized-lein-plugins)
+             (cider-jack-in-normalized-nrepl-middlewares)))
+    ("clojure-cli" (cider-clojure-cli-jack-in-dependencies
+                    global-opts
+                    params
+                    (cider-add-clojure-dependencies-maybe
+                     cider-jack-in-dependencies)))
+    ("shadow-cljs" (cider-shadow-cljs-jack-in-dependencies
+                    global-opts
+                    params
+                    (cider-add-clojure-dependencies-maybe
+                     cider-jack-in-dependencies)))
+    ("gradle" (concat
+               global-opts
+               (unless (seq-empty-p global-opts) " ")
+               params))
+    (_ (error "Unsupported project type `%s'" project-type))))
+
+
+;;; ClojureScript REPL creation
+
+(defcustom cider-check-cljs-repl-requirements t
+  "When non-nil will run the requirement checks for the different cljs repls.
+Generally you should not disable this unless you run into some faulty check."
+  :type 'boolean
+  :safe #'booleanp
+  :version '(cider . "0.17.0"))
+
+(defun cider-verify-clojurescript-is-present ()
+  "Check whether ClojureScript is present."
+  (unless (cider-library-present-p "clojure/clojurescript")
+    (user-error "ClojureScript is not available.  See http://docs.cider.mx/en/latest/clojurescript for details")))
+
+(defun cider-verify-piggieback-is-present ()
+  "Check whether the piggieback middleware is present."
+  (unless (cider-library-present-p "cider/piggieback")
+    (user-error "Piggieback is not available.  See http://docs.cider.mx/en/latest/clojurescript for details")))
+
+(defun cider-check-nashorn-requirements ()
+  "Check whether we can start a Nashorn ClojureScript REPL."
+  (cider-verify-piggieback-is-present)
+  (when (string-prefix-p "1.7" (cider--java-version))
+    (user-error "Nashorn is supported only on Java 8 or newer")))
+
+(defun cider-check-node-requirements ()
+  "Check whether we can start a Node ClojureScript REPL."
+  (cider-verify-piggieback-is-present)
+  (unless (executable-find "node")
+    (user-error "Node.js is not present on the exec-path.  Make sure you've installed it and your exec-path is properly set")))
+
+(defun cider-check-figwheel-requirements ()
+  "Check whether we can start a Figwheel ClojureScript REPL."
+  (cider-verify-piggieback-is-present)
+  (unless (cider-library-present-p "figwheel-sidecar/figwheel-sidecar")
+    (user-error "Figwheel-sidecar is not available.  Please check http://docs.cider.mx/en/latest/clojurescript")))
+
+(defun cider-check-figwheel-main-requirements ()
+  "Check whether we can start a Figwheel ClojureScript REPL."
+  (cider-verify-piggieback-is-present)
+  (unless (cider-library-present-p "bhauman/figwheel-main")
+    (user-error "Figwheel-main is not available.  Please check http://docs.cider.mx/en/latest/clojurescript")))
+
+(defun cider-check-weasel-requirements ()
+  "Check whether we can start a Weasel ClojureScript REPL."
+  (cider-verify-piggieback-is-present)
+  (unless (cider-library-present-p "weasel/weasel")
+    (user-error "Weasel in not available.  Please check http://docs.cider.mx/en/latest/clojurescript/#browser-connected-clojurescript-repl")))
+
+(defun cider-check-boot-requirements ()
+  "Check whether we can start a Boot ClojureScript REPL."
+  (cider-verify-piggieback-is-present)
+  (unless (cider-library-present-p "adzerk/boot-cljs-repl")
+    (user-error "The Boot ClojureScript REPL is not available.  Please check https://github.com/adzerk-oss/boot-cljs-repl/blob/master/README.md")))
+
+(defun cider-check-shadow-cljs-requirements ()
+  "Check whether we can start a shadow-cljs REPL."
+  (unless (cider-library-present-p "thheller/shadow-cljs")
+    (user-error "The shadow-cljs ClojureScript REPL is not available")))
+
+(defun cider-shadow-cljs-init-form ()
+  "Generate the init form for a shadow-cljs REPL.
+We have to prompt the user to select a build, that's why
+this is a command, not just a string."
+  (let ((form "(do (require '[shadow.cljs.devtools.api :as shadow]) (shadow/watch :%s) (shadow/nrepl-select :%s))")
+        (build (string-remove-prefix ":" (read-from-minibuffer "Select shadow-cljs build: "))))
+    (format form build build)))
+
+(defcustom cider-figwheel-main-default-options nil
+  "Defines the `figwheel.main/start' options.
+
+Note that figwheel-main/start can also accept a map of options, refer to
+Figwheel for details."
+  :type 'string
+  :safe (lambda (s) (or (null s) (stringp s)))
+  :package-version '(cider . "0.18.0"))
+
+(defun cider-figwheel-main-init-form ()
+  "Produce the figwheel-main ClojureScript init form."
+  (let ((form "(do (require 'figwheel.main) (figwheel.main/start %s))")
+        (options (or cider-figwheel-main-default-options
+                     (read-from-minibuffer "Select figwheel-main build: "))))
+    (format form options)))
+
+(defun cider-custom-cljs-repl-init-form ()
+  "Prompt for a form that would start a ClojureScript REPL.
+The supplied string will be wrapped in a do form if needed."
+  (let ((form (read-from-minibuffer "Please, provide a form to start a ClojureScript REPL: ")))
+    ;; TODO: We should probably make this more robust (e.g. by using a regexp or
+    ;; parsing the form).
+    (if (string-prefix-p "(do" form)
+        form
+      (format "(do %s)" form))))
+
+(defvar cider-cljs-repl-types
+  '((nashorn "(do (require 'cljs.repl.nashorn) (cider.piggieback/cljs-repl (cljs.repl.nashorn/repl-env)))"
+             cider-check-nashorn-requirements)
+    (figwheel "(do (require 'figwheel-sidecar.repl-api) (figwheel-sidecar.repl-api/start-figwheel!) (figwheel-sidecar.repl-api/cljs-repl))"
+              cider-check-figwheel-requirements)
+    (figwheel-main cider-figwheel-main-init-form cider-check-figwheel-main-requirements)
+    (node "(do (require 'cljs.repl.node) (cider.piggieback/cljs-repl (cljs.repl.node/repl-env)))"
+          cider-check-node-requirements)
+    (weasel "(do (require 'weasel.repl.websocket) (cider.piggieback/cljs-repl (weasel.repl.websocket/repl-env :ip \"127.0.0.1\" :port 9001)))"
+            cider-check-weasel-requirements)
+    (boot "(do (require 'adzerk.boot-cljs-repl) (adzerk.boot-cljs-repl/start-repl))"
+          cider-check-boot-requirements)
+    (shadow cider-shadow-cljs-init-form cider-check-shadow-cljs-requirements)
+    (custom cider-custom-cljs-repl-init-form nil))
+  "A list of supported ClojureScript REPLs.
+
+For each one we have its name, the form we need to evaluate in a Clojure
+REPL to start the ClojureScript REPL and functions to very their requirements.
+
+The form should be either a string or a function producing a string.")
+
+(defun cider-register-cljs-repl-type (type init-form &optional requirements-fn)
+  "Register a new ClojureScript REPL type.
+
+Types are defined by the following:
+
+- TYPE - symbol identifier that will be used to refer to the REPL type
+- INIT-FORM - string or function (symbol) producing string
+- REQUIREMENTS-FN - function to check whether the REPL can be started.
+This param is optional.
+
+All this function does is modifying `cider-cljs-repl-types'.
+It's intended to be used in your Emacs config."
+  (unless (symbolp type)
+    (user-error "The REPL type must be a symbol"))
+  (unless (or (stringp init-form) (symbolp init-form))
+    (user-error "The init form must be a string or a symbol referring to a function"))
+  (unless (or (null requirements-fn) (symbolp requirements-fn))
+    (user-error "The requirements-fn must be a symbol referring to a function"))
+  (add-to-list 'cider-cljs-repl-types (list type init-form requirements-fn)))
+
+(defcustom cider-default-cljs-repl nil
+  "The default ClojureScript REPL to start.
+This affects commands like `cider-jack-in-cljs'.  Generally it's
+intended to be set via .dir-locals.el for individual projects, as its
+relatively unlikely you'd like to use the same type of REPL in each project
+you're working on."
+  :type '(choice (const :tag "Nashorn"  nashorn)
+                 (const :tag "Figwheel" figwheel)
+                 (const :tag "Node"     node)
+                 (const :tag "Weasel"   weasel)
+                 (const :tag "Boot"     boot)
+                 (const :tag "Shadow"   shadow)
+                 (const :tag "Custom"   custom))
+  :group 'cider
+  :safe #'symbolp
+  :package-version '(cider . "0.17.0"))
+
+(make-obsolete-variable 'cider-cljs-lein-repl 'cider-default-cljs-repl "0.17")
+(make-obsolete-variable 'cider-cljs-boot-repl 'cider-default-cljs-repl "0.17")
+(make-obsolete-variable 'cider-cljs-gradle-repl 'cider-default-cljs-repl "0.17")
+
+(defun cider-select-cljs-repl ()
+  "Select the ClojureScript REPL to use with `cider-jack-in-cljs'."
+  (let ((repl-types (mapcar #'car cider-cljs-repl-types)))
+    (intern (completing-read "Select ClojureScript REPL type: " repl-types))))
+
+(defun cider-cljs-repl-form (repl-type)
+  "Get the cljs REPL form for REPL-TYPE."
+  (if-let* ((repl-form (cadr (seq-find
+                              (lambda (entry)
+                                (eq (car entry) repl-type))
+                              cider-cljs-repl-types))))
+      ;; repl-form can be either a string or a function producing a string
+      (if (symbolp repl-form)
+          (funcall repl-form)
+        repl-form)
+    (user-error "No ClojureScript REPL type %s found.  Please make sure that `cider-cljs-repl-types' has an entry for it" repl-type)))
+
+(defun cider-verify-cljs-repl-requirements (&optional repl-type)
+  "Verify that the requirements for REPL-TYPE are met.
+Return REPL-TYPE if requirements are met."
+  (let ((repl-type (or repl-type
+                       cider-default-cljs-repl
+                       (cider-select-cljs-repl))))
+    (when-let* ((fun (nth 2 (seq-find
+                             (lambda (entry)
+                               (eq (car entry) repl-type))
+                             cider-cljs-repl-types))))
+      (funcall fun))
+    repl-type))
+
+(defun cider--check-cljs (&optional cljs-type no-error)
+  "Verify that all cljs requirements are met for CLJS-TYPE connection.
+Return REPL-TYPE of requirement are met, and throw an ‘user-error’ otherwise.
+When NO-ERROR is non-nil, don't throw an error, issue a message and return
+nil."
+  (if no-error
+      (condition-case ex
+          (progn
+            (cider-verify-clojurescript-is-present)
+            (cider-verify-cljs-repl-requirements cljs-type))
+        (error
+         (message "Invalid CLJS dependency: %S" ex)
+         nil))
+    (cider-verify-clojurescript-is-present)
+    (cider-verify-cljs-repl-requirements cljs-type)))
+
+(defun cider--offer-to-open-app-in-browser (server-buffer)
+  "Look for a server address in SERVER-BUFFER and offer to open it."
+  (when (buffer-live-p server-buffer)
+    (with-current-buffer server-buffer
+      (save-excursion
+        (goto-char (point-min))
+        (when-let* ((url (and (search-forward-regexp "http://localhost:[0-9]+" nil 'noerror)
+                              (match-string 0))))
+          (when (y-or-n-p (format "Visit ‘%s’ in a browser? " url))
+            (browse-url url)))))))
+
+
+;;; User Level Connectors
+
+(defvar cider-start-map
+  (let ((map (define-prefix-command 'cider-start-map)))
+    (define-key map (kbd "j j") #'cider-jack-in-clj)
+    (define-key map (kbd "j s") #'cider-jack-in-cljs)
+    (define-key map (kbd "j m") #'cider-jack-in-clj&cljs)
+    (define-key map (kbd "C-j j") #'cider-jack-in-clj)
+    (define-key map (kbd "C-j s") #'cider-jack-in-cljs)
+    (define-key map (kbd "C-j m") #'cider-jack-in-clj&cljs)
+    (define-key map (kbd "C-j C-j") #'cider-jack-in-clj)
+    (define-key map (kbd "C-j C-s") #'cider-jack-in-cljs)
+    (define-key map (kbd "C-j C-m") #'cider-jack-in-clj&cljs)
+    (define-key map (kbd "c j") #'cider-connect-clj)
+    (define-key map (kbd "c s") #'cider-connect-cljs)
+    (define-key map (kbd "c m") #'cider-connect-clj&cljs)
+    (define-key map (kbd "C-c j") #'cider-connect-clj)
+    (define-key map (kbd "C-c s") #'cider-connect-cljs)
+    (define-key map (kbd "C-c m") #'cider-connect-clj&cljs)
+    (define-key map (kbd "C-c C-j") #'cider-connect-clj)
+    (define-key map (kbd "C-c C-s") #'cider-connect-cljs)
+    (define-key map (kbd "C-c C-m") #'cider-connect-clj&cljs)
+    (define-key map (kbd "s j") #'cider-connect-sibling-clj)
+    (define-key map (kbd "s s") #'cider-connect-sibling-cljs)
+    (define-key map (kbd "C-s j") #'cider-connect-sibling-clj)
+    (define-key map (kbd "C-s s") #'cider-connect-sibling-cljs)
+    (define-key map (kbd "C-s C-j") #'cider-connect-sibling-clj)
+    (define-key map (kbd "C-s C-s") #'cider-connect-sibling-cljs)
+    map)
+  "CIDER jack-in and connect keymap.")
+
+;;;###autoload
+(defun cider-jack-in-clj (params)
+  "Start an nREPL server for the current project and connect to it.
+PARAMS is a plist optionally containing :project-dir and :jack-in-cmd.
+With the prefix argument, prompt for all these parameters."
+  (interactive "P")
+  (let ((params (thread-first params
+                  (cider--update-project-dir)
+                  (cider--update-jack-in-cmd))))
+    (nrepl-start-server-process
+     (plist-get params :project-dir)
+     (plist-get params :jack-in-cmd)
+     (lambda (server-buffer)
+       (cider-connect-sibling-clj params server-buffer)))))
+
+;;;###autoload
+(defun cider-jack-in-cljs (params)
+  "Start an nREPL server for the current project and connect to it.
+PARAMS is a plist optionally containing :project-dir, :jack-in-cmd and
+:cljs-repl-type (e.g. Node, Figwheel, etc).  With the prefix argument,
+prompt for all these parameters."
+  (interactive "P")
+  (let ((cider-jack-in-dependencies (append cider-jack-in-dependencies cider-jack-in-cljs-dependencies))
+        (cider-jack-in-lein-plugins (append cider-jack-in-lein-plugins cider-jack-in-cljs-lein-plugins))
+        (cider-jack-in-nrepl-middlewares (append cider-jack-in-nrepl-middlewares cider-jack-in-cljs-nrepl-middlewares))
+        (params (thread-first params
+                  (cider--update-project-dir)
+                  (cider--update-jack-in-cmd))))
+    (nrepl-start-server-process
+     (plist-get params :project-dir)
+     (plist-get params :jack-in-cmd)
+     (lambda (server-buffer)
+       (cider-connect-sibling-cljs params server-buffer)))))
+
+;;;###autoload
+(defun cider-jack-in-clj&cljs (&optional params soft-cljs-start)
+  "Start an nREPL server and connect with clj and cljs REPLs.
+PARAMS is a plist optionally containing :project-dir, :jack-in-cmd and
+:cljs-repl-type (e.g. Node, Figwheel, etc).  With the prefix argument,
+prompt for all these parameters.  When SOFT-CLJS-START is non-nil, start
+cljs REPL only when the ClojureScript dependencies are met."
+  (interactive "P")
+  (let ((cider-jack-in-dependencies (append cider-jack-in-dependencies cider-jack-in-cljs-dependencies))
+        (cider-jack-in-lein-plugins (append cider-jack-in-lein-plugins cider-jack-in-cljs-lein-plugins))
+        (cider-jack-in-nrepl-middlewares (append cider-jack-in-nrepl-middlewares cider-jack-in-cljs-nrepl-middlewares))
+        (params (thread-first params
+                  (cider--update-project-dir)
+                  (cider--update-jack-in-cmd)
+                  (cider--update-cljs-type)
+                  (plist-put :do-prompt nil))))
+    (nrepl-start-server-process
+     (plist-get params :project-dir)
+     (plist-get params :jack-in-cmd)
+     (lambda (server-buffer)
+       (let ((clj-repl (cider-connect-sibling-clj params server-buffer)))
+         (if soft-cljs-start
+             (when (cider--check-cljs (plist-get params :cljs-repl-type) 'no-error)
+               (cider-connect-sibling-cljs params clj-repl))
+           (cider-connect-sibling-cljs params clj-repl)))))))
+
+;;;###autoload
+(defun cider-connect-sibling-clj (params &optional other-repl)
+  "Create a Clojure REPL with the same server as OTHER-REPL.
+PARAMS is for consistency with other connection commands and is currently
+ignored.  OTHER-REPL defaults to `cider-current-repl' and in programs can
+also be a server buffer, in which case a new session with a REPL for that
+server is created."
+  (interactive "P")
+  (cider-nrepl-connect
+   (let* ((other-repl (or other-repl (cider-current-repl nil 'ensure)))
+          (ses-name (unless (nrepl-server-p other-repl)
+                      (sesman-session-name-for-object 'CIDER other-repl))))
+     (thread-first params
+       (cider--update-do-prompt)
+       (cider--gather-connect-params other-repl)
+       (plist-put :repl-init-function nil)
+       (plist-put :repl-type "clj")
+       (plist-put :session-name ses-name)))))
+
+;;;###autoload
+(defun cider-connect-sibling-cljs (params &optional other-repl)
+  "Create a ClojureScript REPL with the same server as OTHER-REPL.
+PARAMS is a plist optionally containing :cljs-repl-type (e.g. Node,
+Figwheel, etc).  All other parameters are inferred from the OTHER-REPL.
+OTHER-REPL defaults to `cider-current-repl' but in programs can also be a
+server buffer, in which case a new session for that server is created."
+  (interactive "P")
+  (let* ((other-repl (or other-repl (cider-current-repl nil 'ensure)))
+         (ses-name (unless (nrepl-server-p other-repl)
+                     (sesman-session-name-for-object 'CIDER other-repl))))
+    (cider-nrepl-connect
+     (thread-first params
+       (cider--update-do-prompt)
+       (cider--gather-connect-params other-repl)
+       (cider--update-cljs-type)
+       (cider--update-cljs-init-function)
+       (plist-put :session-name ses-name)
+       (plist-put :repl-type "cljs")))))
+
+;;;###autoload
+(defun cider-connect-clj (&optional params)
+  "Initialize a CLJ connection to an nREPL server.
+PARAMS is a plist optionally containing :host, :port and :project-dir.  On
+prefix argument, prompt for all the parameters."
+  (interactive "P")
+  (cider-nrepl-connect
+   (thread-first params
+     (cider--update-project-dir)
+     (cider--update-host-port)
+     (plist-put :repl-init-function nil)
+     (plist-put :session-name nil)
+     (plist-put :repl-type "clj"))))
+
+;;;###autoload
+(defun cider-connect-cljs (&optional params)
+  "Initialize a CLJS connection to an nREPL server.
+PARAMS is a plist optionally containing :host, :port, :project-dir and
+:cljs-repl-type (e.g. Node, Figwheel, etc).  On prefix, prompt for all the
+parameters regardless of their supplied or default values."
+  (interactive "P")
+  (cider-nrepl-connect
+   (thread-first params
+     (cider--update-project-dir)
+     (cider--update-host-port)
+     (cider--update-cljs-type)
+     (cider--update-cljs-init-function)
+     (plist-put :session-name nil)
+     (plist-put :repl-type "cljs"))))
+
+;;;###autoload
+(defun cider-connect-clj&cljs (params &optional soft-cljs-start)
+  "Initialize a CLJ and CLJS connection to an nREPL server..
+PARAMS is a plist optionally containing :host, :port, :project-dir and
+:cljs-repl-type (e.g. Node, Figwheel, etc).  When SOFT-CLJS-START is
+non-nil, don't start if ClojureScript requirements are not met."
+  (interactive "P")
+  (let* ((params (thread-first params
+                   (cider--update-project-dir)
+                   (cider--update-host-port)
+                   (cider--update-cljs-type)))
+         (clj-repl (cider-connect-clj params)))
+    (if soft-cljs-start
+        (when (cider--check-cljs (plist-get params :cljs-repl-type) 'no-error)
+          (cider-connect-sibling-cljs params clj-repl))
+      (cider-connect-sibling-cljs params clj-repl))))
+
+(defvar cider-connection-init-commands
+  '(cider-jack-in-clj
+    cider-jack-in-cljs
+    cider-jack-in-clj&cljs
+    cider-connect-clj
+    cider-connect-cljs
+    cider-connect-clj&cljs
+    cider-connect-sibling-clj
+    cider-connect-sibling-cljs)
+  "A list of all user-level connection init commands in CIDER.")
+
+;;;###autoload
+(defun cider ()
+  "Start a connection of any type interactively."
+  (interactive)
+  (when-let* ((command (intern (completing-read "Select command: " cider-connection-init-commands))))
+    (call-interactively command)))
+
+
+;;; PARAMS updating
+
+(defun cider--update-do-prompt (params)
+  "Update :do-prompt in PARAMS."
+  (if (equal params '(4))
+      (list :do-prompt t)
+    params))
+
+(defun cider--update-project-dir (params)
+  "Update :project-dir in PARAMS."
+  (let ((params (cider--update-do-prompt params)))
+    (plist-put params :project-dir
+               (if (plist-get params :do-prompt)
+                   (read-directory-name "Project: "
+                                        (clojure-project-dir (cider-current-dir)))
+                 (or (plist-get params :project-dir)
+                     (clojure-project-dir (cider-current-dir)))))))
+
+(defun cider--update-cljs-type (params)
+  "Update :cljs-repl-type in PARAMS."
+  (let ((params (cider--update-do-prompt params)))
+    (plist-put params :cljs-repl-type
+               (if (plist-get params :do-prompt)
+                   (cider-select-cljs-repl)
+                 (or (plist-get params :cljs-repl-type)
+                     cider-default-cljs-repl
+                     (cider-select-cljs-repl))))))
+
+(defun cider--update-jack-in-cmd (params)
+  "Update :jack-in-cmd key in PARAMS."
+  (let* ((params (cider--update-do-prompt params))
+         (project-dir (plist-get params :project-dir))
+         (project-type (cider-project-type project-dir))
+         (command (cider-jack-in-command project-type))
+         (command-resolved (cider-jack-in-resolve-command project-type))
+         (command-global-opts (cider-jack-in-global-options project-type))
+         (command-params (cider-jack-in-params project-type)))
+    (if command-resolved
+        (let* ((command-params (if (plist-get params :do-prompt)
+                                   (read-string (format "nREPL server command: %s " command-params)
+                                                command-params)
+                                 command-params))
+               (cmd-params (if cider-inject-dependencies-at-jack-in
+                               (cider-inject-jack-in-dependencies command-global-opts command-params project-type)
+                             command-params)))
+          (if (or project-dir cider-allow-jack-in-without-project)
+              (when (or project-dir
+                        (eq cider-allow-jack-in-without-project t)
+                        (and (null project-dir)
+                             (eq cider-allow-jack-in-without-project 'warn)
+                             (y-or-n-p "Are you sure you want to run `cider-jack-in' without a Clojure project? ")))
+                (let* ((cmd (format "%s %s" command-resolved cmd-params)))
+                  (plist-put params :jack-in-cmd cmd)))
+            (user-error "`cider-jack-in' is not allowed without a Clojure project")))
+      (user-error "The %s executable isn't on your `exec-path'" command))))
+
+(defun cider--update-host-port (params)
+  "Update :host and :port in PARAMS."
+  (let* ((params (cider--update-do-prompt params))
+         (host (plist-get params :host))
+         (port (plist-get params :port))
+         (endpoint (if (plist-get params :do-prompt)
+                       (cider-select-endpoint)
+                     (if (and host port)
+                         (cons host port)
+                       (cider-select-endpoint)))))
+    (thread-first params
+      (plist-put :host (car endpoint))
+      (plist-put :port (cdr endpoint)))))
+
+(defun cider--update-cljs-init-function (params)
+  "Update PARAMS :repl-init-function for cljs connections."
+  (let ((cljs-type (plist-get params :cljs-repl-type)))
+    (plist-put params :repl-init-function
+               (lambda ()
+                 (cider--check-cljs cljs-type)
+                 (cider-nrepl-send-request
+                  (list "op" "eval"
+                        "ns" (cider-current-ns)
+                        "code" (cider-cljs-repl-form cljs-type))
+                  (cider-repl-handler (current-buffer)))
+                 (when (and (buffer-live-p nrepl-server-buffer)
+                            cider-offer-to-open-cljs-app-in-browser)
+                   (cider--offer-to-open-app-in-browser nrepl-server-buffer))))))
+
+
+;;; Aliases
+
+ ;;;###autoload
+(defalias 'cider-jack-in #'cider-jack-in-clj)
+ ;;;###autoload
+(defalias 'cider-jack-in-clojure #'cider-jack-in-clj)
+;;;###autoload
+(defalias 'cider-jack-in-clojurescript #'cider-jack-in-cljs)
+
+;;;###autoload
+(defalias 'cider-connect #'cider-connect-clj)
+;;;###autoload
+(defalias 'cider-connect-clojure #'cider-connect-clj)
+;;;###autoload
+(defalias 'cider-connect-clojurescript #'cider-connect-cljs)
+
+;;;###autoload
+(defalias 'cider-connect-sibling-clojure #'cider-connect-sibling-clj)
+;;;###autoload
+(defalias 'cider-connect-sibling-clojurescript #'cider-connect-sibling-cljs)
+
+
+;;; Helpers
+
+(defun cider-current-host ()
+  "Retrieve the current host."
+  (if (stringp buffer-file-name)
+      (file-remote-p buffer-file-name 'host)
+    "localhost"))
+
+(defun cider-select-endpoint ()
+  "Interactively select the host and port to connect to."
+  (dolist (endpoint cider-known-endpoints)
+    (unless (stringp (or (nth 2 endpoint)
+                         (nth 1 endpoint)))
+      (user-error "The port for %s in `cider-known-endpoints' should be a string"
+                  (nth 0 endpoint))))
+  (let* ((ssh-hosts (cider--ssh-hosts))
+         (hosts (seq-uniq (append (when cider-host-history
+                                    ;; history elements are strings of the form "host:port"
+                                    (list (split-string (car cider-host-history) ":")))
+                                  (list (list (cider-current-host)))
+                                  cider-known-endpoints
+                                  ssh-hosts
+                                  (when (file-remote-p default-directory)
+                                    ;; add localhost even in remote buffers
+                                    '(("localhost"))))))
+         (sel-host (cider--completing-read-host hosts))
+         (host (car sel-host))
+         (port (or (cadr sel-host)
+                   (cider--completing-read-port host (cider--infer-ports host ssh-hosts)))))
+    (cons host port)))
+
+(defun cider--ssh-hosts ()
+  "Retrieve all ssh host from local configuration files."
+  (seq-map (lambda (s) (list (replace-regexp-in-string ":$" "" s)))
+           ;; `tramp-completion-mode' is obsoleted in 26
+           (cl-progv (if (version< emacs-version "26")
+                         '(tramp-completion-mode)
+                       '(non-essential)) '(t)
+             (tramp-completion-handle-file-name-all-completions "" "/ssh:"))))
+
+(defun cider--completing-read-host (hosts)
+  "Interactively select host from HOSTS.
+Each element in HOSTS is one of: (host), (host port) or (label host port).
+Return a list of the form (HOST PORT), where PORT can be nil."
+  (let* ((hosts (cider-join-into-alist hosts))
+         (sel-host (completing-read "Host: " hosts nil nil nil
+                                    'cider-host-history (caar hosts)))
+         (host (or (cdr (assoc sel-host hosts)) (list sel-host))))
+    ;; remove the label
+    (if (= 3 (length host)) (cdr host) host)))
+
+(defun cider--infer-ports (host ssh-hosts)
+  "Infer nREPL ports on HOST.
+Return a list of elements of the form (directory port).  SSH-HOSTS is a list
+of remote SSH hosts."
+  (let ((localp (or (nrepl-local-host-p host)
+                    (not (assoc-string host ssh-hosts)))))
+    (if localp
+        ;; change dir: current file might be remote
+        (let* ((change-dir-p (file-remote-p default-directory))
+               (default-directory (if change-dir-p "~/" default-directory)))
+          (cider-locate-running-nrepl-ports (unless change-dir-p default-directory)))
+      (let ((vec (vector "sshx" nil host "" nil))
+            ;; change dir: user might want to connect to a different remote
+            (dir (when (file-remote-p default-directory)
+                   (with-parsed-tramp-file-name default-directory cur
+                     (when (string= cur-host host) default-directory)))))
+        (tramp-maybe-open-connection vec)
+        (with-current-buffer (tramp-get-connection-buffer vec)
+          (cider-locate-running-nrepl-ports dir))))))
+
+(defun cider--completing-read-port (host ports)
+  "Interactively select port for HOST from PORTS."
+  (let* ((ports (cider-join-into-alist ports))
+         (sel-port (completing-read (format "Port for %s: " host) ports
+                                    nil nil nil nil (caar ports)))
+         (port (or (cdr (assoc sel-port ports)) sel-port))
+         (port (if (listp port) (cadr port) port)))
+    (if (stringp port) (string-to-number port) port)))
+
+(defun cider-locate-running-nrepl-ports (&optional dir)
+  "Locate ports of running nREPL servers.
+When DIR is non-nil also look for nREPL port files in DIR.  Return a list
+of list of the form (project-dir port)."
+  (let* ((paths (cider--running-nrepl-paths))
+         (proj-ports (mapcar (lambda (d)
+                               (when-let* ((port (and d (nrepl-extract-port (cider--file-path d)))))
+                                 (list (file-name-nondirectory (directory-file-name d)) port)))
+                             (cons (clojure-project-dir dir) paths))))
+    (seq-uniq (delq nil proj-ports))))
+
+(defun cider--running-nrepl-paths ()
+  "Retrieve project paths of running nREPL servers.
+Use `cider-ps-running-nrepls-command' and `cider-ps-running-nrepl-path-regexp-list'."
+  (let (paths)
+    (with-temp-buffer
+      (insert (shell-command-to-string cider-ps-running-nrepls-command))
+      (dolist (regexp cider-ps-running-nrepl-path-regexp-list)
+        (goto-char 1)
+        (while (re-search-forward regexp nil t)
+          (setq paths (cons (match-string 1) paths)))))
+    (seq-uniq paths)))
+
+(defun cider--identify-buildtools-present (&optional project-dir)
+  "Identify build systems present by their build files in PROJECT-DIR.
+PROJECT-DIR defaults to current project."
+  (let* ((default-directory (or project-dir (clojure-project-dir (cider-current-dir))))
+         (build-files '(("lein" . "project.clj")
+                        ("boot" . "build.boot")
+                        ("clojure-cli" . "deps.edn")
+                        ("shadow-cljs" . "shadow-cljs.edn")
+                        ("gradle" . "build.gradle"))))
+    (delq nil
+          (mapcar (lambda (candidate)
+                    (when (file-exists-p (cdr candidate))
+                      (car candidate)))
+                  build-files))))
+
+(defun cider-project-type (&optional project-dir)
+  "Determine the type of the project in PROJECT-DIR.
+When multiple project file markers are present, check for a preferred build
+tool in `cider-preferred-build-tool', otherwise prompt the user to choose.
+PROJECT-DIR defaults to the current project."
+  (let* ((choices (cider--identify-buildtools-present project-dir))
+         (multiple-project-choices (> (length choices) 1))
+         (default (car choices)))
+    (cond ((and multiple-project-choices
+                (member cider-preferred-build-tool choices))
+           cider-preferred-build-tool)
+          (multiple-project-choices
+           (completing-read (format "Which command should be used (default %s): " default)
+                            choices nil t nil nil default))
+          (choices
+           (car choices))
+          (t cider-default-repl-command))))
+
+
+;; TODO: Implement a check for command presence over tramp
+(defun cider--resolve-command (command)
+  "Find COMMAND in exec path (see variable `exec-path').
+Return nil if not found.  In case `default-directory' is non-local we
+assume the command is available."
+  (when-let* ((command (or (and (file-remote-p default-directory) command)
+                           (executable-find command)
+                           (executable-find (concat command ".bat")))))
+    (shell-quote-argument command)))
+
+;;;###autoload
+(eval-after-load 'clojure-mode
+  '(progn
+     (define-key clojure-mode-map (kbd "C-c M-x") #'cider)
+     (define-key clojure-mode-map (kbd "C-c M-j") #'cider-jack-in-clj)
+     (define-key clojure-mode-map (kbd "C-c M-J") #'cider-jack-in-cljs)
+     (define-key clojure-mode-map (kbd "C-c M-c") #'cider-connect-clj)
+     (define-key clojure-mode-map (kbd "C-c M-C") #'cider-connect-cljs)
+     (define-key clojure-mode-map (kbd "C-c C-x") 'cider-start-map)
+     (define-key clojure-mode-map (kbd "C-c C-s") 'sesman-map)
+     (require 'sesman)
+     (sesman-install-menu clojure-mode-map)
+     (add-hook 'clojure-mode-hook (lambda () (setq-local sesman-system 'CIDER)))))
+
+(provide 'cider)
+
+;;; cider.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider.elc b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider.elc
new file mode 100644
index 0000000000..031948ee54
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/nrepl-client.el b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/nrepl-client.el
new file mode 100644
index 0000000000..a73f200ba7
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/nrepl-client.el
@@ -0,0 +1,1371 @@
+;;; nrepl-client.el --- Client for Clojure nREPL -*- lexical-binding: t -*-
+
+;; Copyright © 2012-2013 Tim King, Phil Hagelberg, Bozhidar Batsov
+;; Copyright © 2013-2018 Bozhidar Batsov, Artur Malabarba and CIDER contributors
+;;
+;; Author: Tim King <kingtim@gmail.com>
+;;         Phil Hagelberg <technomancy@gmail.com>
+;;         Bozhidar Batsov <bozhidar@batsov.com>
+;;         Artur Malabarba <bruce.connor.am@gmail.com>
+;;         Hugo Duncan <hugo@hugoduncan.org>
+;;         Steve Purcell <steve@sanityinc.com>
+;;         Reid McKenzie <me@arrdem.com>
+;;
+;; This program 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.
+;;
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+;;
+;; This file is not part of GNU Emacs.
+;;
+;;; Commentary:
+;;
+;; Provides an Emacs Lisp client to connect to Clojure nREPL servers.
+;;
+;; A connection is an abstract idea of the communication between Emacs (client)
+;; and nREPL server.  On the Emacs side connections are represented by two
+;; running processes.  The two processes are the server process and client
+;; process (the connection to the server).  Each of these is represented by its
+;; own process buffer, filter and sentinel.
+;;
+;; The nREPL communication process can be broadly represented as follows:
+;;
+;;    1) The server process is started as an Emacs subprocess (usually by
+;;       `cider-jack-in', which in turn fires up leiningen or boot).  Note that
+;;       if a connection was established using `cider-connect' there won't be
+;;       a server process.
+;;
+;;    2) The server's process filter (`nrepl-server-filter') detects the
+;;       connection port from the first plain text response from the server and
+;;       starts a communication process (socket connection) as another Emacs
+;;       subprocess.  This is the nREPL client process (`nrepl-client-filter').
+;;       All requests and responses handling happens through this client
+;;       connection.
+;;
+;;    3) Requests are sent by `nrepl-send-request' and
+;;       `nrepl-send-sync-request'.  A request is simply a list containing a
+;;       requested operation name and the parameters required by the
+;;       operation.  Each request has an associated callback that is called once
+;;       the response for the request has arrived.  Besides the above functions
+;;       there are specialized request senders for each type of common
+;;       operations.  Examples are `nrepl-request:eval', `nrepl-request:clone',
+;;       `nrepl-sync-request:describe'.
+;;
+;;    4) Responses from the server are decoded in `nrepl-client-filter' and are
+;;       physically represented by alists whose structure depends on the type of
+;;       the response.  After having been decoded, the data from the response is
+;;       passed over to the callback that was registered by the original
+;;       request.
+;;
+;; Please see the comments in dedicated sections of this file for more detailed
+;; description.
+
+;;; Code:
+(require 'seq)
+(require 'subr-x)
+(require 'cider-compat)
+(require 'cl-lib)
+(require 'nrepl-dict)
+(require 'queue)
+(require 'tramp)
+
+
+;;; Custom
+
+(defgroup nrepl nil
+  "Interaction with the Clojure nREPL Server."
+  :prefix "nrepl-"
+  :group 'applications)
+
+(defcustom nrepl-buffer-name-separator " "
+  "Used in constructing the REPL buffer name.
+The `nrepl-buffer-name-separator' separates cider-repl from the project name."
+  :type '(string)
+  :group 'nrepl)
+
+(defcustom nrepl-buffer-name-show-port nil
+  "Show the connection port in the nrepl REPL buffer name, if set to t."
+  :type 'boolean
+  :group 'nrepl)
+
+(defcustom nrepl-connected-hook nil
+  "List of functions to call when connecting to the nREPL server."
+  :type 'hook
+  :group 'nrepl)
+
+(defcustom nrepl-disconnected-hook nil
+  "List of functions to call when disconnected from the nREPL server."
+  :type 'hook
+  :group 'nrepl)
+
+(defcustom nrepl-file-loaded-hook nil
+  "List of functions to call when a load file has completed."
+  :type 'hook
+  :group 'nrepl)
+
+(defcustom nrepl-force-ssh-for-remote-hosts nil
+  "If non-nil, do not attempt a direct connection for remote hosts."
+  :type 'boolean
+  :group 'nrepl)
+
+(defcustom nrepl-use-ssh-fallback-for-remote-hosts nil
+  "If non-nil, attempt to connect via ssh to remote hosts when unable to connect directly."
+  :type 'boolean
+  :group 'nrepl)
+
+(defcustom nrepl-sync-request-timeout 10
+  "The number of seconds to wait for a sync response.
+Setting this to nil disables the timeout functionality."
+  :type 'integer
+  :group 'nrepl)
+
+(defcustom nrepl-hide-special-buffers nil
+  "Control the display of some special buffers in buffer switching commands.
+When true some special buffers like the server buffer will be hidden."
+  :type 'boolean
+  :group 'nrepl)
+
+
+;;; Buffer Local Declarations
+
+;; These variables are used to track the state of nREPL connections
+(defvar-local nrepl-connection-buffer nil)
+(defvar-local nrepl-server-buffer nil)
+(defvar-local nrepl-messages-buffer nil)
+(defvar-local nrepl-endpoint nil)
+(defvar-local nrepl-project-dir nil)
+(defvar-local nrepl-is-server nil)
+(defvar-local nrepl-server-command nil)
+(defvar-local nrepl-tunnel-buffer nil)
+
+(defvar-local nrepl-session nil
+  "Current nREPL session id.")
+
+(defvar-local nrepl-tooling-session nil
+  "Current nREPL tooling session id.
+To be used for tooling calls (i.e. completion, eldoc, etc)")
+
+(defvar-local nrepl-request-counter 0
+  "Continuation serial number counter.")
+
+(defvar-local nrepl-pending-requests nil)
+
+(defvar-local nrepl-completed-requests nil)
+
+(defvar-local nrepl-last-sync-response nil
+  "Result of the last sync request.")
+
+(defvar-local nrepl-last-sync-request-timestamp nil
+  "The time when the last sync request was initiated.")
+
+(defvar-local nrepl-ops nil
+  "Available nREPL server ops (from describe).")
+
+(defvar-local nrepl-versions nil
+  "Version information received from the describe op.")
+
+(defvar-local nrepl-aux nil
+  "Auxillary information received from the describe op.")
+
+
+;;; nREPL Buffer Names
+
+(defconst nrepl-message-buffer-name-template "*nrepl-messages %s*")
+(defconst nrepl-error-buffer-name "*nrepl-error*")
+(defconst nrepl-repl-buffer-name-template "*cider-repl%s*")
+(defconst nrepl-server-buffer-name-template "*nrepl-server%s*")
+(defconst nrepl-tunnel-buffer-name-template "*nrepl-tunnel%s*")
+
+(defun nrepl-format-buffer-name-template (buffer-name-template designation)
+  "Apply the DESIGNATION to the corresponding BUFFER-NAME-TEMPLATE."
+  (format buffer-name-template
+          (if (> (length designation) 0)
+              (concat nrepl-buffer-name-separator designation)
+            "")))
+
+(defun nrepl-make-buffer-name (buffer-name-template &optional project-dir host port extras dup-ok)
+  "Generate a buffer name using BUFFER-NAME-TEMPLATE.
+If not supplied PROJECT-DIR, HOST and PORT default to the buffer local
+value of the `nrepl-project-dir' and `nrepl-endpoint'.  The name will
+include the project name if available or the endpoint host if it is
+not.  The name will also include the connection port if
+`nrepl-buffer-name-show-port' is true.  EXTRAS is appended towards the end
+of the name.  If optional DUP-OK is non-nil, the returned buffer is not
+\"uniquified\" by a call to `generate-new-buffer-name'."
+  (let* ((project-dir (or project-dir nrepl-project-dir))
+         (project-name (when project-dir (file-name-nondirectory (directory-file-name project-dir))))
+         (nrepl-proj-port (or port (plist-get nrepl-endpoint :port)))
+         (name (nrepl-format-buffer-name-template
+                buffer-name-template
+                (concat (if project-name project-name (or host (plist-get nrepl-endpoint :host)))
+                        (if (and nrepl-proj-port
+                                 nrepl-buffer-name-show-port)
+                            (format ":%s" nrepl-proj-port) "")
+                        (if extras (format "(%s)" extras) "")))))
+    (if dup-ok
+        name
+      (generate-new-buffer-name name))))
+
+(defun nrepl--make-hidden-name (buffer-name)
+  "Apply a prefix to BUFFER-NAME that will hide the buffer."
+  (concat (if nrepl-hide-special-buffers " " "") buffer-name))
+
+(defun nrepl-repl-buffer-name (&optional project-dir host port dup-ok)
+  "Return the name of the repl buffer.
+PROJECT-DIR, HOST and PORT are as in `nrepl-make-buffer-name'.  DUP-OK is
+as in `nrepl-make-buffer-name'."
+  (nrepl-make-buffer-name nrepl-repl-buffer-name-template
+                          project-dir host port cider-repl-type dup-ok))
+
+(defun nrepl-connection-identifier (conn)
+  "Return the string which identifies a connection CONN."
+  (thread-last (buffer-name conn)
+    (replace-regexp-in-string "\\`*cider-repl " "")
+    (replace-regexp-in-string "*\\'" "" )))
+
+(defun nrepl-server-buffer-name (&optional project-dir host port)
+  "Return the name of the server buffer.
+PROJECT-DIR, HOST and PORT are as in `nrepl-make-buffer-name'."
+  (nrepl--make-hidden-name
+   (nrepl-make-buffer-name nrepl-server-buffer-name-template
+                           project-dir host port)))
+
+(defun nrepl-tunnel-buffer-name (&optional project-dir host port)
+  "Return the name of the tunnel buffer.
+PROJECT-DIR, HOST and PORT are as in `nrepl-make-buffer-name'."
+  (nrepl--make-hidden-name
+   (nrepl-make-buffer-name nrepl-tunnel-buffer-name-template
+                           project-dir host port)))
+
+
+;;; Utilities
+(defun nrepl-op-supported-p (op connection)
+  "Return t iff the given operation OP is supported by the nREPL CONNECTION."
+  (when (buffer-live-p connection)
+    (with-current-buffer connection
+      (and nrepl-ops (nrepl-dict-get nrepl-ops op)))))
+
+(defun nrepl-aux-info (key connection)
+  "Return KEY's aux info, as returned via the :describe op for CONNECTION."
+  (with-current-buffer connection
+    (and nrepl-aux (nrepl-dict-get nrepl-aux key))))
+
+(defun nrepl-local-host-p (host)
+  "Return t if HOST is local."
+  (string-match-p tramp-local-host-regexp host))
+
+(defun nrepl-extract-port (dir)
+  "Read port from .nrepl-port, nrepl-port or target/repl-port files in directory DIR."
+  (or (nrepl--port-from-file (expand-file-name "repl-port" dir))
+      (nrepl--port-from-file (expand-file-name ".nrepl-port" dir))
+      (nrepl--port-from-file (expand-file-name "target/repl-port" dir))
+      (nrepl--port-from-file (expand-file-name ".shadow-cljs/nrepl.port" dir))))
+
+(defun nrepl--port-from-file (file)
+  "Attempts to read port from a file named by FILE."
+  (when (file-exists-p file)
+    (with-temp-buffer
+      (insert-file-contents file)
+      (buffer-string))))
+
+
+;;; Bencode
+
+(cl-defstruct (nrepl-response-queue
+               (:include queue)
+               (:constructor nil)
+               (:constructor nrepl-response-queue (&optional stub)))
+  stub)
+
+(put 'nrepl-response-queue 'function-documentation
+     "Create queue object used by nREPL to store decoded server responses.
+The STUB slot stores a stack of nested, incompletely parsed objects.")
+
+(defun nrepl--bdecode-list (&optional stack)
+  "Decode a bencode list or dict starting at point.
+STACK is as in `nrepl--bdecode-1'."
+  ;; skip leading l or d
+  (forward-char 1)
+  (let* ((istack (nrepl--bdecode-1 stack))
+         (pos0 (point))
+         (info (car istack)))
+    (while (null info)
+      (setq istack (nrepl--bdecode-1 (cdr istack))
+            pos0 (point)
+            info (car istack)))
+    (cond ((eq info :e)
+           (cons nil (cdr istack)))
+          ((eq info :stub)
+           (goto-char pos0)
+           istack)
+          (t istack))))
+
+(defun nrepl--bdecode-1 (&optional stack)
+  "Decode one elementary bencode object starting at point.
+Bencoded object is either list, dict, integer or string.  See
+http://en.wikipedia.org/wiki/Bencode#Encoding_algorithm for the encoding
+rules.
+
+STACK is a list of so far decoded components of the current message.  Car
+of STACK is the innermost incompletely decoded object.  The algorithm pops
+this list when inner object was completely decoded or grows it by one when
+new list or dict was encountered.
+
+The returned value is of the form (INFO . STACK) where INFO is
+:stub, nil, :end or :eob and STACK is either an incomplete parsing state as
+above (INFO is :stub, nil or :eob) or a list of one component representing
+the completely decoded message (INFO is :end).  INFO is nil when an
+elementary non-root object was successfully decoded.  INFO is :end when this
+object is a root list or dict."
+  (cond
+   ;; list
+   ((eq (char-after) ?l)
+    (nrepl--bdecode-list (cons () stack)))
+   ;; dict
+   ((eq (char-after) ?d)
+    (nrepl--bdecode-list (cons '(dict) stack)))
+   ;; end of a list or a dict
+   ((eq (char-after) ?e)
+    (forward-char 1)
+    (cons (if (cdr stack) :e :end)
+          (nrepl--push (nrepl--nreverse (car stack))
+                       (cdr stack))))
+   ;; string
+   ((looking-at "\\([0-9]+\\):")
+    (let ((pos0 (point))
+          (beg (goto-char (match-end 0)))
+          (end (byte-to-position (+ (position-bytes (point))
+                                    (string-to-number (match-string 1))))))
+      (if (null end)
+          (progn (goto-char pos0)
+                 (cons :stub stack))
+        (goto-char end)
+        ;; normalise any platform-specific newlines
+        (let* ((original (buffer-substring-no-properties beg end))
+               ;; handle both \n\r and \r\n
+               (result (replace-regexp-in-string "\r\n\\|\n\r" "\n" original))
+               ;; we don't handle single carriage returns, insert newline
+               (result (replace-regexp-in-string "\r" "\n" result)))
+          (cons nil (nrepl--push result stack))))))
+   ;; integer
+   ((looking-at "i\\(-?[0-9]+\\)e")
+    (goto-char (match-end 0))
+    (cons nil (nrepl--push (string-to-number (match-string 1))
+                           stack)))
+   ;; should happen in tests only as eobp is checked in nrepl-bdecode.
+   ((eobp)
+    (cons :eob stack))
+   ;; truncation in the middle of an integer or in 123: string prefix
+   ((looking-at-p "[0-9i]")
+    (cons :stub stack))
+   ;; else, throw a quiet error
+   (t
+    (message "Invalid bencode message detected. See the %s buffer for details."
+             nrepl-error-buffer-name)
+    (nrepl-log-error
+     (format "Decoder error at position %d (`%s'):"
+             (point) (buffer-substring (point) (min (+ (point) 10) (point-max)))))
+    (nrepl-log-error (buffer-string))
+    (ding)
+    ;; Ensure loop break and clean queues' states in nrepl-bdecode:
+    (goto-char (point-max))
+    (cons :end nil))))
+
+(defun nrepl--bdecode-message (&optional stack)
+  "Decode one full message starting at point.
+STACK is as in `nrepl--bdecode-1'.  Return a cons (INFO . STACK)."
+  (let* ((istack (nrepl--bdecode-1 stack))
+         (info (car istack))
+         (stack (cdr istack)))
+    (while (or (null info)
+               (eq info :e))
+      (setq istack (nrepl--bdecode-1 stack)
+            info (car istack)
+            stack (cdr istack)))
+    istack))
+
+(defun nrepl-bdecode (string-q &optional response-q)
+  "Decode STRING-Q and place the results into RESPONSE-Q.
+STRING-Q is either a queue of strings or a string.  RESPONSE-Q is a queue of
+server requests (nREPL dicts).  STRING-Q and RESPONSE-Q are modified by side
+effects.
+
+Return a cons (STRING-Q . RESPONSE-Q) where STRING-Q is the original queue
+containing the remainder of the input strings which could not be
+decoded.  RESPONSE-Q is the original queue with successfully decoded messages
+enqueued and with slot STUB containing a nested stack of an incompletely
+decoded message or nil if the strings were completely decoded."
+  (with-temp-buffer
+    (if (queue-p string-q)
+        (while (queue-head string-q)
+          (insert (queue-dequeue string-q)))
+      (insert string-q)
+      (setq string-q (queue-create)))
+    (goto-char 1)
+    (unless response-q
+      (setq response-q (nrepl-response-queue)))
+    (let ((istack (nrepl--bdecode-message
+                   (nrepl-response-queue-stub response-q))))
+      (while (and (eq (car istack) :end)
+                  (not (eobp)))
+        (queue-enqueue response-q (cadr istack))
+        (setq istack (nrepl--bdecode-message)))
+      (unless (eobp)
+        (queue-enqueue string-q (buffer-substring (point) (point-max))))
+      (if (not (eq (car istack) :end))
+          (setf (nrepl-response-queue-stub response-q) (cdr istack))
+        (queue-enqueue response-q (cadr istack))
+        (setf (nrepl-response-queue-stub response-q) nil))
+      (cons string-q response-q))))
+
+(defun nrepl-bencode (object)
+  "Encode OBJECT with bencode.
+Integers, lists and nrepl-dicts are treated according to bencode
+specification.  Everything else is encoded as string."
+  (cond
+   ((integerp object) (format "i%de" object))
+   ((nrepl-dict-p object) (format "d%se" (mapconcat #'nrepl-bencode (cdr object) "")))
+   ((listp object) (format "l%se" (mapconcat #'nrepl-bencode object "")))
+   (t (format "%s:%s" (string-bytes object) object))))
+
+
+;;; Client: Process Filter
+
+(defvar nrepl-response-handler-functions nil
+  "List of functions to call on each nREPL message.
+Each of these functions should be a function with one argument, which will
+be called by `nrepl-client-filter' on every response received.  The current
+buffer will be connection (REPL) buffer of the process.  These functions
+should take a single argument, a dict representing the message.  See
+`nrepl--dispatch-response' for an example.
+
+These functions are called before the message's own callbacks, so that they
+can affect the behaviour of the callbacks.  Errors signaled by these
+functions are demoted to messages, so that they don't prevent the
+callbacks from running.")
+
+(defun nrepl-client-filter (proc string)
+  "Decode message(s) from PROC contained in STRING and dispatch them."
+  (let ((string-q (process-get proc :string-q)))
+    (queue-enqueue string-q string)
+    ;; Start decoding only if the last letter is 'e'
+    (when (eq ?e (aref string (1- (length string))))
+      (let ((response-q (process-get proc :response-q)))
+        (nrepl-bdecode string-q response-q)
+        (while (queue-head response-q)
+          (with-current-buffer (process-buffer proc)
+            (let ((response (queue-dequeue response-q)))
+              (with-demoted-errors "Error in one of the `nrepl-response-handler-functions': %s"
+                (run-hook-with-args 'nrepl-response-handler-functions response))
+              (nrepl--dispatch-response response))))))))
+
+(defun nrepl--dispatch-response (response)
+  "Dispatch the RESPONSE to associated callback.
+First we check the callbacks of pending requests.  If no callback was found,
+we check the completed requests, since responses could be received even for
+older requests with \"done\" status."
+  (nrepl-dbind-response response (id)
+    (nrepl-log-message response 'response)
+    (let ((callback (or (gethash id nrepl-pending-requests)
+                        (gethash id nrepl-completed-requests))))
+      (if callback
+          (funcall callback response)
+        (error "[nREPL] No response handler with id %s found" id)))))
+
+(defun nrepl-client-sentinel (process message)
+  "Handle sentinel events from PROCESS.
+Notify MESSAGE and if the process is closed run `nrepl-disconnected-hook'
+and kill the process buffer."
+  (if (string-match "deleted\\b" message)
+      (message "[nREPL] Connection closed")
+    (message "[nREPL] Connection closed unexpectedly (%s)"
+             (substring message 0 -1)))
+  (when (equal (process-status process) 'closed)
+    (when-let* ((client-buffer (process-buffer process)))
+      (nrepl--clear-client-sessions client-buffer)
+      (with-current-buffer client-buffer
+        (run-hooks 'nrepl-disconnected-hook)
+        (let ((server-buffer nrepl-server-buffer))
+          (when (and (buffer-live-p server-buffer)
+                     (not (plist-get (process-plist process) :no-server-kill)))
+            (setq nrepl-server-buffer nil)
+            (nrepl--maybe-kill-server-buffer server-buffer)))))))
+
+
+;;; Network
+
+(defun nrepl-connect (host port)
+  "Connect to the nREPL server identified by HOST and PORT.
+For local hosts use a direct connection.  For remote hosts, if
+`nrepl-force-ssh-for-remote-hosts' is nil, attempt a direct connection
+first.  If `nrepl-force-ssh-for-remote-hosts' is non-nil or the direct
+connection failed (and `nrepl-use-ssh-fallback-for-remote-hosts' is
+non-nil), try to start a SSH tunneled connection.  Return a plist of the
+form (:proc PROC :host \"HOST\" :port PORT) that might contain additional
+key-values depending on the connection type."
+  (let ((localp (if host
+                    (nrepl-local-host-p host)
+                  (not (file-remote-p default-directory)))))
+    (if localp
+        (nrepl--direct-connect (or host "localhost") port)
+      ;; we're dealing with a remote host
+      (if (and host (not nrepl-force-ssh-for-remote-hosts))
+          (or (nrepl--direct-connect host port 'no-error)
+              ;; direct connection failed
+              ;; fallback to ssh tunneling if enabled
+              (and nrepl-use-ssh-fallback-for-remote-hosts
+                   (message "[nREPL] Falling back to SSH tunneled connection ...")
+                   (nrepl--ssh-tunnel-connect host port))
+              ;; fallback is either not enabled or it failed as well
+              (error "[nREPL] Cannot connect to %s:%s" host port))
+        ;; `nrepl-force-ssh-for-remote-hosts' is non-nil
+        (nrepl--ssh-tunnel-connect host port)))))
+
+(defun nrepl--direct-connect (host port &optional no-error)
+  "If HOST and PORT are given, try to `open-network-stream'.
+If NO-ERROR is non-nil, show messages instead of throwing an error."
+  (if (not (and host port))
+      (unless no-error
+        (unless host
+          (error "[nREPL] Host not provided"))
+        (unless port
+          (error "[nREPL] Port not provided")))
+    (message "[nREPL] Establishing direct connection to %s:%s ..." host port)
+    (condition-case nil
+        (prog1 (list :proc (open-network-stream "nrepl-connection" nil host port)
+                     :host host :port port)
+          (message "[nREPL] Direct connection to %s:%s established" host port))
+      (error (let ((msg (format "[nREPL] Direct connection to %s:%s failed" host port)))
+               (if no-error
+                   (message msg)
+                 (error msg))
+               nil)))))
+
+(defun nrepl--ssh-tunnel-connect (host port)
+  "Connect to a remote machine identified by HOST and PORT through SSH tunnel."
+  (message "[nREPL] Establishing SSH tunneled connection to %s:%s ..." host port)
+  (let* ((remote-dir (if host (format "/ssh:%s:" host) default-directory))
+         (ssh (or (executable-find "ssh")
+                  (error "[nREPL] Cannot locate 'ssh' executable")))
+         (cmd (nrepl--ssh-tunnel-command ssh remote-dir port))
+         (tunnel-buf (nrepl-tunnel-buffer-name))
+         (tunnel (start-process-shell-command "nrepl-tunnel" tunnel-buf cmd)))
+    (process-put tunnel :waiting-for-port t)
+    (set-process-filter tunnel (nrepl--ssh-tunnel-filter port))
+    (while (and (process-live-p tunnel)
+                (process-get tunnel :waiting-for-port))
+      (accept-process-output nil 0.005))
+    (if (not (process-live-p tunnel))
+        (error "[nREPL] SSH port forwarding failed.  Check the '%s' buffer" tunnel-buf)
+      (message "[nREPL] SSH port forwarding established to localhost:%s" port)
+      (let ((endpoint (nrepl--direct-connect "localhost" port)))
+        (thread-first endpoint
+          (plist-put :tunnel tunnel)
+          (plist-put :remote-host host))))))
+
+(defun nrepl--ssh-tunnel-command (ssh dir port)
+  "Command string to open SSH tunnel to the host associated with DIR's PORT."
+  (with-parsed-tramp-file-name dir v
+    ;; this abuses the -v option for ssh to get output when the port
+    ;; forwarding is set up, which is used to synchronise on, so that
+    ;; the port forwarding is up when we try to connect.
+    (format-spec
+     "%s -v -N -L %p:localhost:%p %u'%h'"
+     `((?s . ,ssh)
+       (?p . ,port)
+       (?h . ,v-host)
+       (?u . ,(if v-user (format "-l '%s' " v-user) ""))))))
+
+(autoload 'comint-watch-for-password-prompt "comint"  "(autoload).")
+
+(defun nrepl--ssh-tunnel-filter (port)
+  "Return a process filter that waits for PORT to appear in process output."
+  (let ((port-string (format "LOCALHOST:%s" port)))
+    (lambda (proc string)
+      (when (string-match-p port-string string)
+        (process-put proc :waiting-for-port nil))
+      (when (and (process-live-p proc)
+                 (buffer-live-p (process-buffer proc)))
+        (with-current-buffer (process-buffer proc)
+          (let ((moving (= (point) (process-mark proc))))
+            (save-excursion
+              (goto-char (process-mark proc))
+              (insert string)
+              (set-marker (process-mark proc) (point))
+              (comint-watch-for-password-prompt string))
+            (if moving (goto-char (process-mark proc)))))))))
+
+
+;;; Client: Process Handling
+
+(defun nrepl--kill-process (proc)
+  "Kill PROC using the appropriate, os specific way.
+Implement a workaround to clean up an orphaned JVM process left around
+after exiting the REPL on some windows machines."
+  (if (memq system-type '(cygwin windows-nt))
+      (interrupt-process proc)
+    (kill-process proc)))
+
+(defun nrepl-kill-server-buffer (server-buf)
+  "Kill SERVER-BUF and its process."
+  (when (buffer-live-p server-buf)
+    (let ((proc (get-buffer-process server-buf)))
+      (when (process-live-p proc)
+        (set-process-query-on-exit-flag proc nil)
+        (nrepl--kill-process proc))
+      (kill-buffer server-buf))))
+
+(defun nrepl--maybe-kill-server-buffer (server-buf)
+  "Kill SERVER-BUF and its process.
+Do not kill the server if there is a REPL connected to that server."
+  (when (buffer-live-p server-buf)
+    (with-current-buffer server-buf
+      ;; Don't kill if there is at least one REPL connected to it.
+      (when (not (seq-find (lambda (b)
+                             (eq (buffer-local-value 'nrepl-server-buffer b)
+                                 server-buf))
+                           (buffer-list)))
+        (nrepl-kill-server-buffer server-buf)))))
+
+(defun nrepl-start-client-process (&optional host port server-proc buffer-builder)
+  "Create new client process identified by HOST and PORT.
+In remote buffers, HOST and PORT are taken from the current tramp
+connection.  SERVER-PROC must be a running nREPL server process within
+Emacs.  BUFFER-BUILDER is a function of one argument (endpoint returned by
+`nrepl-connect') which returns a client buffer (defaults to
+`nrepl-default-client-buffer-builder').  Return the newly created client
+process."
+  (let* ((endpoint (nrepl-connect host port))
+         (client-proc (plist-get endpoint :proc))
+         (builder (or buffer-builder #'nrepl-default-client-buffer-builder))
+         (client-buf (funcall builder endpoint)))
+
+    (set-process-buffer client-proc client-buf)
+
+    (set-process-filter client-proc 'nrepl-client-filter)
+    (set-process-sentinel client-proc 'nrepl-client-sentinel)
+    (set-process-coding-system client-proc 'utf-8-unix 'utf-8-unix)
+
+    (process-put client-proc :string-q (queue-create))
+    (process-put client-proc :response-q (nrepl-response-queue))
+
+    (with-current-buffer client-buf
+      (when-let* ((server-buf (and server-proc (process-buffer server-proc))))
+        (setq nrepl-project-dir (buffer-local-value 'nrepl-project-dir server-buf)
+              nrepl-server-buffer server-buf))
+      (setq nrepl-endpoint endpoint
+            nrepl-tunnel-buffer (when-let* ((tunnel (plist-get endpoint :tunnel)))
+                                  (process-buffer tunnel))
+            nrepl-pending-requests (make-hash-table :test 'equal)
+            nrepl-completed-requests (make-hash-table :test 'equal)))
+
+    (with-current-buffer client-buf
+      (nrepl--init-client-sessions client-proc)
+      (nrepl--init-capabilities client-buf)
+      (run-hooks 'nrepl-connected-hook))
+
+    client-proc))
+
+(defun nrepl--init-client-sessions (client)
+  "Initialize CLIENT connection nREPL sessions.
+We create two client nREPL sessions per connection - a main session and a
+tooling session.  The main session is general purpose and is used for pretty
+much every request that needs a session.  The tooling session is used only
+for functionality that's implemented in terms of the \"eval\" op, so that
+eval requests for functionality like pretty-printing won't clobber the
+values of *1, *2, etc."
+  (let* ((client-conn (process-buffer client))
+         (response-main (nrepl-sync-request:clone client-conn))
+         (response-tooling (nrepl-sync-request:clone client-conn t))) ; t for tooling
+    (nrepl-dbind-response response-main (new-session err)
+      (if new-session
+          (with-current-buffer client-conn
+            (setq nrepl-session new-session))
+        (error "Could not create new session (%s)" err)))
+    (nrepl-dbind-response response-tooling (new-session err)
+      (if new-session
+          (with-current-buffer client-conn
+            (setq nrepl-tooling-session new-session))
+        (error "Could not create new tooling session (%s)" err)))))
+
+(defun nrepl--init-capabilities (conn-buffer)
+  "Store locally in CONN-BUFFER the capabilities of nREPL server."
+  (let ((description (nrepl-sync-request:describe conn-buffer)))
+    (nrepl-dbind-response description (ops versions aux)
+      (with-current-buffer conn-buffer
+        (setq nrepl-ops ops)
+        (setq nrepl-versions versions)
+        (setq nrepl-aux aux)))))
+
+(defun nrepl--clear-client-sessions (conn-buffer)
+  "Clear information about nREPL sessions in CONN-BUFFER.
+CONN-BUFFER refers to a (presumably) dead connection, which we can eventually reuse."
+  (with-current-buffer conn-buffer
+    (setq nrepl-session nil)
+    (setq nrepl-tooling-session nil)))
+
+
+;;; Client: Response Handling
+;; After being decoded, responses (aka, messages from the server) are dispatched
+;; to handlers. Handlers are constructed with `nrepl-make-response-handler'.
+
+(defvar nrepl-err-handler nil
+  "Evaluation error handler.")
+
+(defun nrepl--mark-id-completed (id)
+  "Move ID from `nrepl-pending-requests' to `nrepl-completed-requests'.
+It is safe to call this function multiple times on the same ID."
+  ;; FIXME: This should go away eventually when we get rid of
+  ;; pending-request hash table
+  (when-let* ((handler (gethash id nrepl-pending-requests)))
+    (puthash id handler nrepl-completed-requests)
+    (remhash id nrepl-pending-requests)))
+
+(declare-function cider-repl--emit-interactive-output "cider-repl")
+(defun nrepl-notify (msg type)
+  "Handle \"notification\" server request.
+MSG is a string to be displayed.  TYPE is the type of the message.  All
+notifications are currently displayed with `message' function and emitted
+to the REPL."
+  (let* ((face (pcase type
+                 ((or "message" `nil) 'font-lock-builtin-face)
+                 ("warning" 'warning)
+                 ("error"   'error)))
+         (msg (if face
+                  (propertize msg 'face face)
+                (format "%s: %s" (upcase type) msg))))
+    (cider-repl--emit-interactive-output msg (or face 'font-lock-builtin-face))
+    (message msg)
+    ;; Interactive eval handler covers this message, but it won't be eval
+    ;; middleware using this functionality.
+    (sit-for 2)))
+
+(defvar cider-buffer-ns)
+(defvar cider-special-mode-truncate-lines)
+(declare-function cider-need-input "cider-client")
+(declare-function cider-set-buffer-ns "cider-mode")
+
+(defun nrepl-make-response-handler (buffer value-handler stdout-handler
+                                           stderr-handler done-handler
+                                           &optional eval-error-handler
+                                           pprint-out-handler
+                                           content-type-handler)
+  "Make a response handler for connection BUFFER.
+A handler is a function that takes one argument - response received from
+the server process.  The response is an alist that contains at least 'id'
+and 'session' keys.  Other standard response keys are 'value', 'out', 'err',
+'pprint-out' and 'status'.
+
+The presence of a particular key determines the type of the response.  For
+example, if 'value' key is present, the response is of type 'value', if
+'out' key is present the response is 'stdout' etc.
+
+Depending on the type, the handler dispatches the appropriate value to one
+of the supplied handlers: VALUE-HANDLER, STDOUT-HANDLER, STDERR-HANDLER,
+DONE-HANDLER, EVAL-ERROR-HANDLER, PPRINT-OUT-HANDLER and
+CONTENT-TYPE-HANDLER.
+
+Handlers are functions of the buffer and the value they handle, except for
+the optional CONTENT-TYPE-HANDLER which should be a function of the buffer,
+content, the content-type to be handled as a list `(type attrs)'.
+
+If the optional EVAL-ERROR-HANDLER is nil, the default `nrepl-err-handler'
+is used.  If any of the other supplied handlers are nil nothing happens for
+the corresponding type of response."
+  (lambda (response)
+    (nrepl-dbind-response response (content-type content-transfer-encoding body
+                                                 value ns out err status id
+                                                 pprint-out)
+      (when (buffer-live-p buffer)
+        (with-current-buffer buffer
+          (when (and ns (not (derived-mode-p 'clojure-mode)))
+            (cider-set-buffer-ns ns))))
+      (cond ((and content-type content-type-handler)
+             (funcall content-type-handler buffer
+                      (if (string= content-transfer-encoding "base64")
+                          (base64-decode-string body)
+                        body)
+                      content-type))
+            (value
+             (when value-handler
+               (funcall value-handler buffer value)))
+            (out
+             (when stdout-handler
+               (funcall stdout-handler buffer out)))
+            (pprint-out
+             (cond (pprint-out-handler (funcall pprint-out-handler buffer pprint-out))
+                   (stdout-handler (funcall stdout-handler buffer pprint-out))))
+            (err
+             (when stderr-handler
+               (funcall stderr-handler buffer err)))
+            (status
+             (when (member "notification" status)
+               (nrepl-dbind-response response (msg type)
+                 (nrepl-notify msg type)))
+             (when (member "interrupted" status)
+               (message "Evaluation interrupted."))
+             (when (member "eval-error" status)
+               (funcall (or eval-error-handler nrepl-err-handler)))
+             (when (member "namespace-not-found" status)
+               (message "Namespace not found."))
+             (when (member "need-input" status)
+               (cider-need-input buffer))
+             (when (member "done" status)
+               (nrepl--mark-id-completed id)
+               (when done-handler
+                 (funcall done-handler buffer))))))))
+
+
+;;; Client: Request Core API
+
+;; Requests are messages from an nREPL client (like CIDER) to an nREPL server.
+;; Requests can be asynchronous (sent with `nrepl-send-request') or
+;; synchronous (send with `nrepl-send-sync-request'). The request is a pair list
+;; of operation name and operation parameters. The core operations are described
+;; at https://github.com/clojure/tools.nrepl/blob/master/doc/ops.md. CIDER adds
+;; many more operations through nREPL middleware. See
+;; https://github.com/clojure-emacs/cider-nrepl#supplied-nrepl-middleware for
+;; the up-to-date list.
+
+(defun nrepl-next-request-id (connection)
+  "Return the next request id for CONNECTION."
+  (with-current-buffer connection
+    (number-to-string (cl-incf nrepl-request-counter))))
+
+(defun nrepl-send-request (request callback connection &optional tooling)
+  "Send REQUEST and register response handler CALLBACK using CONNECTION.
+REQUEST is a pair list of the form (\"op\" \"operation\" \"par1-name\"
+\"par1\" ... ). See the code of `nrepl-request:clone',
+`nrepl-request:stdin', etc. This expects that the REQUEST does not have a
+session already in it. This code will add it as appropriate to prevent
+connection/session drift.
+Return the ID of the sent message.
+Optional argument TOOLING Set to t if desiring the tooling session rather than the standard session."
+  (with-current-buffer connection
+    (when-let* ((session (if tooling nrepl-tooling-session nrepl-session)))
+      (setq request (append request `("session" ,session))))
+    (let* ((id (nrepl-next-request-id connection))
+           (request (cons 'dict (lax-plist-put request "id" id)))
+           (message (nrepl-bencode request)))
+      (nrepl-log-message request 'request)
+      (puthash id callback nrepl-pending-requests)
+      (process-send-string nil message)
+      id)))
+
+(defvar nrepl-ongoing-sync-request nil
+  "Dynamically bound to t while a sync request is ongoing.")
+
+(declare-function cider-repl-emit-interactive-stderr "cider-repl")
+(declare-function cider--render-stacktrace-causes "cider-eval")
+
+(defun nrepl-send-sync-request (request connection &optional abort-on-input tooling)
+  "Send REQUEST to the nREPL server synchronously using CONNECTION.
+Hold till final \"done\" message has arrived and join all response messages
+of the same \"op\" that came along.
+If ABORT-ON-INPUT is non-nil, the function will return nil at the first
+sign of user input, so as not to hang the interface.
+If TOOLING, use the tooling session rather than the standard session."
+  (let* ((time0 (current-time))
+         (response (cons 'dict nil))
+         (nrepl-ongoing-sync-request t)
+         status)
+    (nrepl-send-request request
+                        (lambda (resp) (nrepl--merge response resp))
+                        connection
+                        tooling)
+    (while (and (not (member "done" status))
+                (not (and abort-on-input
+                          (input-pending-p))))
+      (setq status (nrepl-dict-get response "status"))
+      ;; If we get a need-input message then the repl probably isn't going
+      ;; anywhere, and we'll just timeout. So we forward it to the user.
+      (if (member "need-input" status)
+          (progn (cider-need-input (current-buffer))
+                 ;; If the used took a few seconds to respond, we might
+                 ;; unnecessarily timeout, so let's reset the timer.
+                 (setq time0 (current-time)))
+        ;; break out in case we don't receive a response for a while
+        (when (and nrepl-sync-request-timeout
+                   (> (cadr (time-subtract (current-time) time0))
+                      nrepl-sync-request-timeout))
+          (error "Sync nREPL request timed out %s" request)))
+      ;; Clean up the response, otherwise we might repeatedly ask for input.
+      (nrepl-dict-put response "status" (remove "need-input" status))
+      (accept-process-output nil 0.01))
+    ;; If we couldn't finish, return nil.
+    (when (member "done" status)
+      (nrepl-dbind-response response (ex err eval-error pp-stacktrace id)
+        (when (and ex err)
+          (cond (eval-error (funcall nrepl-err-handler))
+                (pp-stacktrace (cider--render-stacktrace-causes
+                                pp-stacktrace (remove "done" status))))) ;; send the error type
+        (when id
+          (with-current-buffer connection
+            (nrepl--mark-id-completed id)))
+        response))))
+
+(defun nrepl-request:stdin (input callback connection)
+  "Send a :stdin request with INPUT using CONNECTION.
+Register CALLBACK as the response handler."
+  (nrepl-send-request `("op" "stdin"
+                        "stdin" ,input)
+                      callback
+                      connection))
+
+(defun nrepl-request:interrupt (pending-request-id callback connection)
+  "Send an :interrupt request for PENDING-REQUEST-ID.
+The request is dispatched using CONNECTION.
+Register CALLBACK as the response handler."
+  (nrepl-send-request `("op" "interrupt"
+                        "interrupt-id" ,pending-request-id)
+                      callback
+                      connection))
+
+(define-minor-mode cider-enlighten-mode nil nil (cider-mode " light")
+  :global t)
+
+(defun nrepl--eval-request (input &optional ns line column)
+  "Prepare :eval request message for INPUT.
+NS provides context for the request.
+If LINE and COLUMN are non-nil and current buffer is a file buffer, \"line\",
+\"column\" and \"file\" are added to the message."
+  (nconc (and ns `("ns" ,ns))
+         `("op" "eval"
+           "code" ,(substring-no-properties input))
+         (when cider-enlighten-mode
+           '("enlighten" "true"))
+         (let ((file (or (buffer-file-name) (buffer-name))))
+           (when (and line column file)
+             `("file" ,file
+               "line" ,line
+               "column" ,column)))))
+
+(defun nrepl-request:eval (input callback connection &optional ns line column additional-params tooling)
+  "Send the request INPUT and register the CALLBACK as the response handler.
+The request is dispatched via CONNECTION.  If NS is non-nil,
+include it in the request.  LINE and COLUMN, if non-nil, define the position
+of INPUT in its buffer.  A CONNECTION uniquely determines two connections
+available: the standard interaction one and the tooling session.  If the
+tooling is desired, set TOOLING to true.
+ADDITIONAL-PARAMS is a plist to be appended to the request message."
+  (nrepl-send-request (append (nrepl--eval-request input ns line column) additional-params)
+                      callback
+                      connection
+                      tooling))
+
+(defun nrepl-sync-request:clone (connection &optional tooling)
+  "Sent a :clone request to create a new client session.
+The request is dispatched via CONNECTION.
+Optional argument TOOLING Tooling is set to t if wanting the tooling session from CONNECTION."
+  (nrepl-send-sync-request '("op" "clone")
+                           connection
+                           nil tooling))
+
+(defun nrepl-sync-request:close (connection)
+  "Sent a :close request to close CONNECTION's SESSION."
+  (nrepl-send-sync-request '("op" "close") connection)
+  (nrepl-send-sync-request '("op" "close") connection nil t)) ;; close tooling session
+
+(defun nrepl-sync-request:describe (connection)
+  "Perform :describe request for CONNECTION and SESSION."
+  (nrepl-send-sync-request '("op" "describe")
+                           connection))
+
+(defun nrepl-sync-request:ls-sessions (connection)
+  "Perform :ls-sessions request for CONNECTION."
+  (nrepl-send-sync-request '("op" "ls-sessions") connection))
+
+(defun nrepl-sync-request:eval (input connection &optional ns tooling)
+  "Send the INPUT to the nREPL server synchronously.
+The request is dispatched via CONNECTION.
+If NS is non-nil, include it in the request
+If TOOLING is non-nil the evaluation is done using the tooling nREPL
+session."
+  (nrepl-send-sync-request
+   (nrepl--eval-request input ns)
+   connection
+   nil
+   tooling))
+
+(defun nrepl-sessions (connection)
+  "Get a list of active sessions on the nREPL server using CONNECTION."
+  (nrepl-dict-get (nrepl-sync-request:ls-sessions connection) "sessions"))
+
+
+;;; Server
+
+;; The server side process is started by `nrepl-start-server-process' and has a
+;; very simple filter that pipes its output directly into its process buffer
+;; (*nrepl-server*). The main purpose of this process is to start the actual
+;; nrepl communication client (`nrepl-client-filter') when the message "nREPL
+;; server started on port ..." is detected.
+
+;; internal variables used for state transfer between nrepl-start-server-process
+;; and nrepl-server-filter.
+(defvar-local nrepl-on-port-callback nil)
+
+(defun nrepl-server-p (buffer-or-process)
+  "Return t if BUFFER-OR-PROCESS is an nREPL server."
+  (let ((buffer (if (processp buffer-or-process)
+                    (process-buffer buffer-or-process)
+                  buffer-or-process)))
+    (buffer-local-value 'nrepl-is-server buffer)))
+
+(defun nrepl-start-server-process (directory cmd on-port-callback)
+  "Start nREPL server process in DIRECTORY using shell command CMD.
+Return a newly created process.  Set `nrepl-server-filter' as the process
+filter, which starts REPL process with its own buffer once the server has
+started.  ON-PORT-CALLBACK is a function of one argument (server buffer)
+which is called by the process filter once the port of the connection has
+been determined."
+  (let* ((default-directory (or directory default-directory))
+         (serv-buf (get-buffer-create
+                    (generate-new-buffer-name
+                     (nrepl-server-buffer-name default-directory)))))
+    (with-current-buffer serv-buf
+      (setq nrepl-is-server t
+            nrepl-project-dir default-directory
+            nrepl-server-command cmd
+            nrepl-on-port-callback on-port-callback))
+    (let ((serv-proc (start-file-process-shell-command
+                      "nrepl-server" serv-buf cmd)))
+      (set-process-filter serv-proc 'nrepl-server-filter)
+      (set-process-sentinel serv-proc 'nrepl-server-sentinel)
+      (set-process-coding-system serv-proc 'utf-8-unix 'utf-8-unix)
+      (message "[nREPL] Starting server via %s..."
+               (propertize cmd 'face 'font-lock-keyword-face))
+      serv-proc)))
+
+(defun nrepl-server-filter (process output)
+  "Process nREPL server output from PROCESS contained in OUTPUT."
+  ;; In Windows this can be false:
+  (let ((server-buffer (process-buffer process)))
+    (when (buffer-live-p server-buffer)
+      (with-current-buffer server-buffer
+        ;; auto-scroll on new output
+        (let ((moving (= (point) (process-mark process))))
+          (save-excursion
+            (goto-char (process-mark process))
+            (insert output)
+            (ansi-color-apply-on-region (process-mark process) (point))
+            (set-marker (process-mark process) (point)))
+          (when moving
+            (goto-char (process-mark process))
+            (when-let* ((win (get-buffer-window)))
+              (set-window-point win (point)))))
+        ;; detect the port the server is listening on from its output
+        (when (and (null nrepl-endpoint)
+                   (string-match "nREPL server started on port \\([0-9]+\\)" output))
+          (let ((port (string-to-number (match-string 1 output))))
+            (setq nrepl-endpoint (list :host nil :port port))
+            (message "[nREPL] server started on %s" port)
+            (when nrepl-on-port-callback
+              (funcall nrepl-on-port-callback (process-buffer process)))))))))
+
+(declare-function cider--close-connection "cider-connection")
+(defun nrepl-server-sentinel (process event)
+  "Handle nREPL server PROCESS EVENT."
+  (let* ((server-buffer (process-buffer process))
+         (clients (seq-filter (lambda (b)
+                                (eq (buffer-local-value 'nrepl-server-buffer b)
+                                    server-buffer))
+                              (buffer-list)))
+         (problem (if (and server-buffer (buffer-live-p server-buffer))
+                      (with-current-buffer server-buffer
+                        (buffer-substring (point-min) (point-max)))
+                    "")))
+    (when server-buffer
+      (kill-buffer server-buffer))
+    (cond
+     ((string-match-p "^killed\\|^interrupt" event)
+      nil)
+     ((string-match-p "^hangup" event)
+      (mapc #'cider--close-connection clients))
+     ;; On Windows, a failed start sends the "finished" event. On Linux it sends
+     ;; "exited abnormally with code 1".
+     (t (error "Could not start nREPL server: %s" problem)))))
+
+
+;;; Messages
+
+(defcustom nrepl-log-messages nil
+  "If non-nil, log protocol messages to an nREPL messages buffer.
+This is extremely useful for debug purposes, as it allows you to inspect
+the communication between Emacs and an nREPL server.  Enabling the logging
+might have a negative impact on performance, so it's not recommended to
+keep it enabled unless you need to debug something."
+  :type 'boolean
+  :group 'nrepl
+  :safe #'booleanp)
+
+(defconst nrepl-message-buffer-max-size 1000000
+  "Maximum size for the nREPL message buffer.
+Defaults to 1000000 characters, which should be an insignificant
+memory burden, while providing reasonable history.")
+
+(defconst nrepl-message-buffer-reduce-denominator 4
+  "Divisor by which to reduce message buffer size.
+When the maximum size for the nREPL message buffer is exceeded, the size of
+the buffer is reduced by one over this value.  Defaults to 4, so that 1/4
+of the buffer is removed, which should ensure the buffer's maximum is
+reasonably utilized, while limiting the number of buffer shrinking
+operations.")
+
+(defvar nrepl-messages-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "n")   #'next-line)
+    (define-key map (kbd "p")   #'previous-line)
+    (define-key map (kbd "TAB") #'forward-button)
+    (define-key map (kbd "RET") #'nrepl-log-expand-button)
+    (define-key map (kbd "e")   #'nrepl-log-expand-button)
+    (define-key map (kbd "E")   #'nrepl-log-expand-all-buttons)
+    (define-key map (kbd "<backtab>") #'backward-button)
+    map))
+
+(define-derived-mode nrepl-messages-mode special-mode "nREPL Messages"
+  "Major mode for displaying nREPL messages.
+
+\\{nrepl-messages-mode-map}"
+  (when cider-special-mode-truncate-lines
+    (setq-local truncate-lines t))
+  (setq-local sesman-system 'CIDER)
+  (setq-local electric-indent-chars nil)
+  (setq-local comment-start ";")
+  (setq-local comment-end "")
+  (setq-local paragraph-start "(-->\\|(<--")
+  (setq-local paragraph-separate "(<--"))
+
+(defun nrepl-decorate-msg (msg type)
+  "Decorate nREPL MSG according to its TYPE."
+  (pcase type
+    (`request (cons '--> (cdr msg)))
+    (`response (cons '<-- (cdr msg)))))
+
+(defun nrepl-log-message (msg type)
+  "Log the nREPL MSG.
+TYPE is either request or response.  The message is logged to a buffer
+described by `nrepl-message-buffer-name-template'."
+  (when nrepl-log-messages
+    ;; append a time-stamp to the message before logging it
+    ;; the time-stamps are quite useful for debugging
+    (setq msg (cons (car msg)
+                    (lax-plist-put (cdr msg) "time-stamp"
+                                   (format-time-string "%Y-%m-%0d %H:%M:%S.%N"))))
+    (with-current-buffer (nrepl-messages-buffer (current-buffer))
+      (setq buffer-read-only nil)
+      (when (> (buffer-size) nrepl-message-buffer-max-size)
+        (goto-char (/ (buffer-size) nrepl-message-buffer-reduce-denominator))
+        (re-search-forward "^(" nil t)
+        (delete-region (point-min) (- (point) 1)))
+      (goto-char (point-max))
+      (nrepl-log-pp-object (nrepl-decorate-msg msg type)
+                           (nrepl-log--message-color (lax-plist-get (cdr msg) "id"))
+                           t)
+      (when-let* ((win (get-buffer-window)))
+        (set-window-point win (point-max)))
+      (setq buffer-read-only t))))
+
+(defun nrepl-toggle-message-logging ()
+  "Toggle the value of `nrepl-log-messages' between nil and t.
+
+This in effect enables or disables the logging of nREPL messages."
+  (interactive)
+  (setq nrepl-log-messages (not nrepl-log-messages))
+  (if nrepl-log-messages
+      (message "nREPL message logging enabled")
+    (message "nREPL message logging disabled")))
+
+(defcustom nrepl-message-colors
+  '("red" "brown" "coral" "orange" "green" "deep sky blue" "blue" "dark violet")
+  "Colors used in the messages buffer."
+  :type '(repeat color)
+  :group 'nrepl)
+
+(defun nrepl-log-expand-button (&optional button)
+  "Expand the objects hidden in BUTTON's :nrepl-object property.
+BUTTON defaults the button at point."
+  (interactive)
+  (if-let* ((button (or button (button-at (point)))))
+      (let* ((start (overlay-start button))
+             (end   (overlay-end   button))
+             (obj   (overlay-get button :nrepl-object))
+             (inhibit-read-only t))
+        (save-excursion
+          (goto-char start)
+          (delete-overlay button)
+          (delete-region start end)
+          (nrepl-log-pp-object obj)
+          (delete-char -1)))
+    (error "No button at point")))
+
+(defun nrepl-log-expand-all-buttons ()
+  "Expand all buttons in nREPL log buffer."
+  (interactive)
+  (if (not (eq major-mode 'nrepl-messages-mode))
+      (user-error "Not in a `nrepl-messages-mode'")
+    (save-excursion
+      (let* ((pos (point-min))
+             (button (next-button pos)))
+        (while button
+          (setq pos (overlay-start button))
+          (nrepl-log-expand-button button)
+          (setq button (next-button pos)))))))
+
+(defun nrepl-log--expand-button-mouse (event)
+  "Expand the text hidden under overlay button.
+EVENT gives the button position on window."
+  (interactive "e")
+  (pcase (elt event 1)
+    (`(,window ,_ ,_ ,_ ,_ ,point . ,_)
+     (with-selected-window window
+       (nrepl-log-expand-button (button-at point))))))
+
+(defun nrepl-log-insert-button (label object)
+  "Insert button with LABEL and :nrepl-object property as OBJECT."
+  (insert-button label
+                 :nrepl-object object
+                 'action #'nrepl-log-expand-button
+                 'face 'link
+                 'help-echo "RET: Expand object."
+                 ;; Workaround for bug#1568 (don't use local-map here; it
+                 ;; overwrites major mode map.)
+                 'keymap `(keymap (mouse-1 . nrepl-log--expand-button-mouse)))
+  (insert "\n"))
+
+(defun nrepl-log--message-color (id)
+  "Return the color to use when pretty-printing the nREPL message with ID.
+If ID is nil, return nil."
+  (when id
+    (thread-first (string-to-number id)
+      (mod (length nrepl-message-colors))
+      (nth nrepl-message-colors))))
+
+(defun nrepl-log--pp-listlike (object &optional foreground button)
+  "Pretty print nREPL list like OBJECT.
+FOREGROUND and BUTTON are as in `nrepl-log-pp-object'."
+  (cl-flet ((color (str)
+                   (propertize str 'face
+                               (append '(:weight ultra-bold)
+                                       (when foreground `(:foreground ,foreground))))))
+    (let ((head (format "(%s" (car object))))
+      (insert (color head))
+      (if (null (cdr object))
+          (insert ")\n")
+        (let* ((indent (+ 2 (- (current-column) (length head))))
+               (sorted-pairs (sort (seq-partition (cl-copy-list (cdr object)) 2)
+                                   (lambda (a b)
+                                     (string< (car a) (car b)))))
+               (name-lengths (seq-map (lambda (pair) (length (car pair))) sorted-pairs))
+               (longest-name (seq-max name-lengths))
+               ;; Special entries are displayed first
+               (specialq (lambda (pair) (seq-contains '("id" "op" "session" "time-stamp") (car pair))))
+               (special-pairs (seq-filter specialq sorted-pairs))
+               (not-special-pairs (seq-remove specialq sorted-pairs))
+               (all-pairs (seq-concatenate 'list special-pairs not-special-pairs))
+               (sorted-object (apply 'seq-concatenate 'list all-pairs)))
+          (insert "\n")
+          (cl-loop for l on sorted-object by #'cddr
+                   do (let ((indent-str (make-string indent ?\s))
+                            (name-str (propertize (car l) 'face
+                                                  ;; Only highlight top-level keys.
+                                                  (unless (eq (car object) 'dict)
+                                                    'font-lock-keyword-face)))
+                            (spaces-str (make-string (- longest-name (length (car l))) ?\s)))
+                        (insert (format "%s%s%s " indent-str name-str spaces-str))
+                        (nrepl-log-pp-object (cadr l) nil button)))
+          (when (eq (car object) 'dict)
+            (delete-char -1))
+          (insert (color ")\n")))))))
+
+(defun nrepl-log-pp-object (object &optional foreground button)
+  "Pretty print nREPL OBJECT, delimited using FOREGROUND.
+If BUTTON is non-nil, try making a button from OBJECT instead of inserting
+it into the buffer."
+  (let ((min-dict-fold-size   1)
+        (min-list-fold-size   10)
+        (min-string-fold-size 60))
+    (if-let* ((head (car-safe object)))
+        ;; list-like objects
+        (cond
+         ;; top level dicts (always expanded)
+         ((memq head '(<-- -->))
+          (nrepl-log--pp-listlike object foreground button))
+         ;; inner dicts
+         ((eq head 'dict)
+          (if (and button (> (length object) min-dict-fold-size))
+              (nrepl-log-insert-button "(dict ...)" object)
+            (nrepl-log--pp-listlike object foreground button)))
+         ;; lists
+         (t
+          (if (and button (> (length object) min-list-fold-size))
+              (nrepl-log-insert-button (format "(%s ...)" (prin1-to-string head)) object)
+            (pp object (current-buffer)))))
+      ;; non-list objects
+      (if (stringp object)
+          (if (and button (> (length object) min-string-fold-size))
+              (nrepl-log-insert-button (format "\"%s...\"" (substring object 0 min-string-fold-size)) object)
+            (insert (prin1-to-string object) "\n"))
+        (pp object (current-buffer))
+        (insert "\n")))))
+
+(defun nrepl-messages-buffer-name (conn)
+  "Return the name for the message buffer matching CONN."
+  (format nrepl-message-buffer-name-template (nrepl-connection-identifier conn)))
+
+(defun nrepl-messages-buffer (conn)
+  "Return or create the buffer for CONN.
+The default buffer name is *nrepl-messages connection*."
+  (with-current-buffer conn
+    (or (and (buffer-live-p nrepl-messages-buffer)
+             nrepl-messages-buffer)
+        (setq nrepl-messages-buffer
+              (let ((buffer (get-buffer-create (nrepl-messages-buffer-name conn))))
+                (with-current-buffer buffer
+                  (buffer-disable-undo)
+                  (nrepl-messages-mode)
+                  buffer))))))
+
+(defun nrepl-error-buffer ()
+  "Return or create the buffer.
+The default buffer name is *nrepl-error*."
+  (or (get-buffer nrepl-error-buffer-name)
+      (let ((buffer (get-buffer-create nrepl-error-buffer-name)))
+        (with-current-buffer buffer
+          (buffer-disable-undo)
+          (fundamental-mode)
+          buffer))))
+
+(defun nrepl-log-error (msg)
+  "Log the given MSG to the buffer given by `nrepl-error-buffer'."
+  (with-current-buffer (nrepl-error-buffer)
+    (setq buffer-read-only nil)
+    (goto-char (point-max))
+    (insert msg)
+    (when-let* ((win (get-buffer-window)))
+      (set-window-point win (point-max)))
+    (setq buffer-read-only t)))
+
+(defun nrepl-default-client-buffer-builder (endpoint)
+  "Create an nREPL client process buffer.
+ENDPOINT is a plist returned by `nrepl-connect'."
+  (let ((buffer (generate-new-buffer
+                 (nrepl-repl-buffer-name
+                  default-directory
+                  (plist-get endpoint :host)
+                  (plist-get endpoint :port)))))
+    (with-current-buffer buffer
+      (buffer-disable-undo)
+      (setq-local kill-buffer-query-functions nil))
+    buffer))
+
+(provide 'nrepl-client)
+
+;;; nrepl-client.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/nrepl-client.elc b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/nrepl-client.elc
new file mode 100644
index 0000000000..215100d3dd
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/nrepl-client.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/nrepl-dict.el b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/nrepl-dict.el
new file mode 100644
index 0000000000..be143860c3
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/nrepl-dict.el
@@ -0,0 +1,187 @@
+;;; nrepl-dict.el --- Dictionary functions for Clojure nREPL -*- lexical-binding: t -*-
+
+;; Copyright © 2012-2013 Tim King, Phil Hagelberg, Bozhidar Batsov
+;; Copyright © 2013-2018 Bozhidar Batsov, Artur Malabarba and CIDER contributors
+;;
+;; Author: Tim King <kingtim@gmail.com>
+;;         Phil Hagelberg <technomancy@gmail.com>
+;;         Bozhidar Batsov <bozhidar@batsov.com>
+;;         Artur Malabarba <bruce.connor.am@gmail.com>
+;;         Hugo Duncan <hugo@hugoduncan.org>
+;;         Steve Purcell <steve@sanityinc.com>
+;;
+;; This program 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.
+;;
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+;;
+;; This file is not part of GNU Emacs.
+;;
+;;; Commentary:
+;;
+;; Provides functions to interact with and create `nrepl-dict's.  These are
+;; simply plists with an extra element at the head.
+
+;;; Code:
+(require 'cl-lib)
+
+
+(defun nrepl-dict (&rest key-vals)
+  "Create nREPL dict from KEY-VALS."
+  (cons 'dict key-vals))
+
+(defun nrepl-dict-p (object)
+  "Return t if OBJECT is an nREPL dict."
+  (and (listp object)
+       (eq (car object) 'dict)))
+
+(defun nrepl-dict-empty-p (dict)
+  "Return t if nREPL dict DICT is empty."
+  (null (cdr dict)))
+
+(defun nrepl-dict-contains (dict key)
+  "Return nil if nREPL dict DICT doesn't contain KEY.
+If DICT does contain KEY, then a non-nil value is returned.  Due to the
+current implementation, this return value is the tail of DICT's key-list
+whose car is KEY.  Comparison is done with `equal'."
+  (member key (nrepl-dict-keys dict)))
+
+(defun nrepl-dict-get (dict key &optional default)
+  "Get from DICT value associated with KEY, optional DEFAULT if KEY not in DICT.
+If dict is nil, return nil.  If DEFAULT not provided, and KEY not in DICT,
+return nil.  If DICT is not an nREPL dict object, an error is thrown."
+  (when dict
+    (if (nrepl-dict-p dict)
+        (if (nrepl-dict-contains dict key)
+            (lax-plist-get (cdr dict) key)
+          default)
+      (error "Not an nREPL dict object: %s" dict))))
+
+(defun nrepl-dict-put (dict key value)
+  "Associate in DICT, KEY to VALUE.
+Return new dict.  Dict is modified by side effects."
+  (if (null dict)
+      `(dict ,key ,value)
+    (if (not (nrepl-dict-p dict))
+        (error "Not an nREPL dict object: %s" dict)
+      (setcdr dict (lax-plist-put (cdr dict) key value))
+      dict)))
+
+(defun nrepl-dict-keys (dict)
+  "Return all the keys in the nREPL DICT."
+  (if (nrepl-dict-p dict)
+      (cl-loop for l on (cdr dict) by #'cddr
+               collect (car l))
+    (error "Not an nREPL dict")))
+
+(defun nrepl-dict-vals (dict)
+  "Return all the values in the nREPL DICT."
+  (if (nrepl-dict-p dict)
+      (cl-loop for l on (cdr dict) by #'cddr
+               collect (cadr l))
+    (error "Not an nREPL dict")))
+
+(defun nrepl-dict-map (fn dict)
+  "Map FN on nREPL DICT.
+FN must accept two arguments key and value."
+  (if (nrepl-dict-p dict)
+      (cl-loop for l on (cdr dict) by #'cddr
+               collect (funcall fn (car l) (cadr l)))
+    (error "Not an nREPL dict")))
+
+(defun nrepl-dict-merge (dict1 dict2)
+  "Destructively merge DICT2 into DICT1.
+Keys in DICT2 override those in DICT1."
+  (let ((base (or dict1 '(dict))))
+    (nrepl-dict-map (lambda (k v)
+                      (nrepl-dict-put base k v))
+                    (or dict2 '(dict)))
+    base))
+
+(defun nrepl-dict-get-in (dict keys)
+  "Return the value in a nested DICT.
+KEYS is a list of keys.  Return nil if any of the keys is not present or if
+any of the values is nil."
+  (let ((out dict))
+    (while (and keys out)
+      (setq out (nrepl-dict-get out (pop keys))))
+    out))
+
+(defun nrepl-dict-flat-map (function dict)
+  "Map FUNCTION over DICT and flatten the result.
+FUNCTION follows the same restrictions as in `nrepl-dict-map', and it must
+also alway return a sequence (since the result will be flattened)."
+  (when dict
+    (apply #'append (nrepl-dict-map function dict))))
+
+
+;;; More specific functions
+(defun nrepl--cons (car list-or-dict)
+  "Generic cons of CAR to LIST-OR-DICT."
+  (if (eq (car list-or-dict) 'dict)
+      (cons 'dict (cons car (cdr list-or-dict)))
+    (cons car list-or-dict)))
+
+(defun nrepl--nreverse (list-or-dict)
+  "Generic `nreverse' which works on LIST-OR-DICT."
+  (if (eq (car list-or-dict) 'dict)
+      (cons 'dict (nreverse (cdr list-or-dict)))
+    (nreverse list-or-dict)))
+
+(defun nrepl--push (obj stack)
+  "Cons OBJ to the top element of the STACK."
+  ;; stack is assumed to be a list
+  (if (eq (caar stack) 'dict)
+      (cons (cons 'dict (cons obj (cdar stack)))
+            (cdr stack))
+    (cons (if (null stack)
+              obj
+            (cons obj (car stack)))
+          (cdr stack))))
+
+(defun nrepl--merge (dict1 dict2 &optional no-join)
+  "Join nREPL dicts DICT1 and DICT2 in a meaningful way.
+String values for non \"id\" and \"session\" keys are concatenated. Lists
+are appended. nREPL dicts merged recursively. All other objects are
+accumulated into a list. DICT1 is modified destructively and
+then returned.
+If NO-JOIN is given, return the first non nil dict."
+  (if no-join
+      (or dict1 dict2)
+    (cond ((null dict1) dict2)
+          ((null dict2) dict1)
+          ((stringp dict1) (concat dict1 dict2))
+          ((nrepl-dict-p dict1)
+           (nrepl-dict-map
+            (lambda (k2 v2)
+              (nrepl-dict-put dict1 k2
+                              (nrepl--merge (nrepl-dict-get dict1 k2) v2
+                                            (member k2 '("id" "session")))))
+            dict2)
+           dict1)
+          ((and (listp dict2) (listp dict1)) (append dict1 dict2))
+          ((listp dict1) (append dict1 (list dict2)))
+          (t `(,dict1 ,dict2)))))
+
+
+;;; Dbind
+(defmacro nrepl-dbind-response (response keys &rest body)
+  "Destructure an nREPL RESPONSE dict.
+Bind the value of the provided KEYS and execute BODY."
+  (declare (debug (form (&rest symbolp) body)))
+  `(let ,(cl-loop for key in keys
+                  collect `(,key (nrepl-dict-get ,response ,(format "%s" key))))
+     ,@body))
+(put 'nrepl-dbind-response 'lisp-indent-function 2)
+
+(provide 'nrepl-dict)
+
+;;; nrepl-dict.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/nrepl-dict.elc b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/nrepl-dict.elc
new file mode 100644
index 0000000000..af75eb64f0
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/nrepl-dict.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/circe-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/circe-autoloads.el
new file mode 100644
index 0000000000..20f3a7807a
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/circe-autoloads.el
@@ -0,0 +1,226 @@
+;;; circe-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "circe" "circe.el" (23377 61594 971310 23000))
+;;; Generated autoloads from circe.el
+
+(autoload 'circe-version "circe" "\
+Display Circe's version.
+
+\(fn)" t nil)
+
+(autoload 'circe "circe" "\
+Connect to IRC.
+
+Connect to the given network specified by NETWORK-OR-SERVER.
+
+When this function is called, it collects options from the
+SERVER-OPTIONS argument, the user variable
+`circe-network-options', and the defaults found in
+`circe-network-defaults', in this order.
+
+If NETWORK-OR-SERVER is not found in any of these variables, the
+argument is assumed to be the host name for the server, and all
+relevant settings must be passed via SERVER-OPTIONS.
+
+All SERVER-OPTIONS are treated as variables by getting the string
+\"circe-\" prepended to their name. This variable is then set
+locally in the server buffer.
+
+See `circe-network-options' for a list of common options.
+
+\(fn NETWORK-OR-SERVER &rest SERVER-OPTIONS)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "circe-color-nicks" "circe-color-nicks.el"
+;;;;;;  (23377 61594 965904 520000))
+;;; Generated autoloads from circe-color-nicks.el
+
+(autoload 'enable-circe-color-nicks "circe-color-nicks" "\
+Enable the Color Nicks module for Circe.
+This module colors all encountered nicks in a cross-server fashion.
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "circe-display-images" "circe-display-images.el"
+;;;;;;  (23377 61594 968709 333000))
+;;; Generated autoloads from circe-display-images.el
+
+(autoload 'enable-circe-display-images "circe-display-images" "\
+Enable the Display Images module for Circe.
+This module displays various image types when they are linked in a channel
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "circe-lagmon" "circe-lagmon.el" (23377 61594
+;;;;;;  970011 224000))
+;;; Generated autoloads from circe-lagmon.el
+
+(defvar circe-lagmon-mode nil "\
+Non-nil if Circe-Lagmon mode is enabled.
+See the `circe-lagmon-mode' command
+for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `circe-lagmon-mode'.")
+
+(custom-autoload 'circe-lagmon-mode "circe-lagmon" nil)
+
+(autoload 'circe-lagmon-mode "circe-lagmon" "\
+Circe-lagmon-mode monitors the amount of lag on your
+connection to each server, and displays the lag time in seconds
+in the mode-line.
+
+\(fn &optional ARG)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "circe-new-day-notifier" "circe-new-day-notifier.el"
+;;;;;;  (23377 61594 980603 307000))
+;;; Generated autoloads from circe-new-day-notifier.el
+
+(autoload 'enable-circe-new-day-notifier "circe-new-day-notifier" "\
+
+
+\(fn)" t nil)
+
+(autoload 'disable-circe-new-day-notifier "circe-new-day-notifier" "\
+
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "lui-autopaste" "lui-autopaste.el" (23377 61594
+;;;;;;  974106 860000))
+;;; Generated autoloads from lui-autopaste.el
+
+(autoload 'enable-lui-autopaste "lui-autopaste" "\
+Enable the lui autopaste feature.
+
+If you enter more than `lui-autopaste-lines' at once, Lui will
+ask if you would prefer to use a paste service instead. If you
+agree, Lui will paste your input to `lui-autopaste-function' and
+replace it with the resulting URL.
+
+\(fn)" t nil)
+
+(autoload 'disable-lui-autopaste "lui-autopaste" "\
+Disable the lui autopaste feature.
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "lui-irc-colors" "lui-irc-colors.el" (23377
+;;;;;;  61594 983284 828000))
+;;; Generated autoloads from lui-irc-colors.el
+
+(autoload 'enable-lui-irc-colors "lui-irc-colors" "\
+Enable IRC color interpretation for Lui.
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "lui-track-bar" "lui-track-bar.el" (23377 61594
+;;;;;;  967329 142000))
+;;; Generated autoloads from lui-track-bar.el
+
+(autoload 'enable-lui-track-bar "lui-track-bar" "\
+Enable a bar in Lui buffers that shows where you stopped reading.
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "shorten" "shorten.el" (23377 61594 976651
+;;;;;;  52000))
+;;; Generated autoloads from shorten.el
+
+(autoload 'shorten-strings "shorten" "\
+Takes a list of strings and returns an alist ((STRING
+. SHORTENED-STRING) ...).  Uses `shorten-split-function' to split
+the strings, and `shorten-join-function' to join shortened
+components back together into SHORTENED-STRING.  See also
+`shorten-validate-component-function'.
+
+\(fn STRINGS)" nil nil)
+
+;;;***
+
+;;;### (autoloads nil "tracking" "tracking.el" (23377 61594 963081
+;;;;;;  521000))
+;;; Generated autoloads from tracking.el
+
+(defvar tracking-mode nil "\
+Non-nil if Tracking mode is enabled.
+See the `tracking-mode' command
+for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `tracking-mode'.")
+
+(custom-autoload 'tracking-mode "tracking" nil)
+
+(autoload 'tracking-mode "tracking" "\
+Allow cycling through modified buffers.
+This mode in itself does not track buffer modification, but
+provides an API for programs to add buffers as modified (using
+`tracking-add-buffer').
+
+Once this mode is active, modified buffers are shown in the mode
+line. The user can cycle through them using
+\\[tracking-next-buffer].
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'tracking-add-buffer "tracking" "\
+Add BUFFER as being modified with FACES.
+This does check whether BUFFER is currently visible.
+
+If FACES is given, it lists the faces that might be appropriate
+for BUFFER in the mode line. The highest-priority face of these
+and the current face of the buffer, if any, is used. Priority is
+decided according to `tracking-faces-priorities'.
+When `tracking-sort-faces-first' is non-nil, all buffers with any
+face set will be stable-sorted before any buffers with no face set.
+
+\(fn BUFFER &optional FACES)" nil nil)
+
+(autoload 'tracking-remove-buffer "tracking" "\
+Remove BUFFER from being tracked.
+
+\(fn BUFFER)" nil nil)
+
+(autoload 'tracking-next-buffer "tracking" "\
+Switch to the next active buffer.
+
+\(fn)" t nil)
+
+(autoload 'tracking-previous-buffer "tracking" "\
+Switch to the last active buffer.
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads nil nil ("circe-chanop.el" "circe-compat.el" "circe-pkg.el"
+;;;;;;  "irc.el" "lcs.el" "lui-format.el" "lui-logging.el" "lui.el"
+;;;;;;  "make-tls-process.el") (23377 61594 984675 379000))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; circe-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/circe-chanop.el b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/circe-chanop.el
new file mode 100644
index 0000000000..a5880e5f8c
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/circe-chanop.el
@@ -0,0 +1,97 @@
+;;; circe-chanop.el --- Provide common channel operator commands
+
+;; Copyright (C) 2006, 2015  Jorgen Schaefer
+
+;; Author: Jorgen Schaefer <forcer@forcix.cx>
+
+;; This file is part of Circe.
+
+;; This program 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.
+
+;; This program 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 this program; if not, write to the Free Software
+;; Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301  USA
+
+;;; Commentary:
+
+;; This Circe module provides some often-used chanop commands. I was
+;; very reluctant to add this. None of these commands will make it in
+;; the core, or even be provided by default. You should have to go to
+;; great lengths to use them.
+
+;; Always remember the Tao of IRC:
+;;
+;;     IGNORE is the weapon of an IRC knight. Not as clumsy or as
+;;     random as a kickban.
+
+;;; Code:
+
+(require 'circe)
+
+(defun circe-command-MODE (mode)
+  "Set MODE in the current channel."
+  (interactive "sMode change: ")
+  (cond
+   ((not (string-match "^[+-]" mode))
+    (irc-send-raw (circe-server-process)
+                  (format "MODE %s" mode)))
+   ((eq major-mode 'circe-channel-mode)
+    (irc-send-raw (circe-server-process)
+                  (format "MODE %s %s" circe-chat-target mode)))
+   (t
+    (circe-display-server-message "Not in a channel buffer."))))
+
+(defun circe-command-BANS (&optional ignored)
+  "Show channel bans"
+  (if (not circe-chat-target)
+      (circe-display-server-message "No target for current buffer")
+    (irc-send-raw (circe-server-process)
+                  (format "MODE %s +b" circe-chat-target))))
+
+(defun circe-command-KICK (nick &optional reason)
+  "Kick WHO from the current channel with optional REASON."
+  (interactive "sKick who: \nsWhy: ")
+  (if (not (eq major-mode 'circe-channel-mode))
+      (circe-display-server-message "Not in a channel buffer.")
+    (when (not reason)
+      (if (string-match "^\\([^ ]*\\) +\\(.+\\)" nick)
+          (setq reason (match-string 2 nick)
+                nick (match-string 1 nick))
+        (setq reason "-")))
+    (irc-send-raw (circe-server-process)
+                  (format "KICK %s %s :%s"
+                          circe-chat-target nick reason))))
+
+(defun circe-command-GETOP (&optional ignored)
+  "Ask chanserv for op on the current channel."
+  (interactive)
+  (if (not (eq major-mode 'circe-channel-mode))
+      (circe-display-server-message "Not in a channel buffer.")
+    (irc-send-PRIVMSG (circe-server-process)
+                      "chanserv"
+                      (format "op %s" circe-chat-target))))
+
+(defun circe-command-DROPOP (&optional ignored)
+  "Lose op mode on the current channel."
+  (interactive)
+  (if (not (eq major-mode 'circe-channel-mode))
+      (circe-display-server-message "Not in a channel buffer.")
+    (irc-send-raw (circe-server-process)
+                  (format "MODE %s -o %s"
+                          circe-chat-target
+                          (circe-nick)))))
+
+;; For KICKBAN (requested by Riastradh), we'd need a callback on a
+;; USERHOST command.
+
+(provide 'circe-chanop)
+;;; circe-chanop.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/circe-chanop.elc b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/circe-chanop.elc
new file mode 100644
index 0000000000..5b27c801d0
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/circe-chanop.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/circe-color-nicks.el b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/circe-color-nicks.el
new file mode 100644
index 0000000000..dd5e64e04f
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/circe-color-nicks.el
@@ -0,0 +1,340 @@
+;;; circe-color-nicks.el --- Color nicks in the channel
+
+;; Copyright (C) 2012  Taylan Ulrich Bayırlı/Kammer
+
+;; Author: Taylan Ulrich Bayırlı/Kammer <taylanbayirli@gmail.com>
+
+;; This file is part of Circe.
+
+;; This program 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.
+
+;; This program 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 this program; if not, write to the Free Software
+;; Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301  USA
+
+;;; Commentary:
+
+;; This Circe module adds the ability to assign a color to each
+;; nick in a channel.
+
+;; Some ideas/code copied from rcirc-colors.el.
+
+;; To use it, put the following into your .emacs:
+
+;; (require 'circe-color-nicks)
+;; (enable-circe-color-nicks)
+
+;;; Code:
+
+(require 'circe)
+(require 'color)
+(require 'cl-lib)
+
+;;;###autoload
+(defun enable-circe-color-nicks ()
+  "Enable the Color Nicks module for Circe.
+This module colors all encountered nicks in a cross-server fashion."
+  (interactive)
+  (dolist (buf (buffer-list))
+    (with-current-buffer buf
+      (when (eq major-mode 'circe-channel-mode)
+        (add-circe-color-nicks))))
+  (add-hook 'circe-channel-mode-hook
+            'add-circe-color-nicks))
+
+(defun disable-circe-color-nicks ()
+  "Disable the Color Nicks module for Circe.
+See `enable-circe-color-nicks'."
+  (interactive)
+  (dolist (buf (buffer-list))
+    (with-current-buffer buf
+      (when (eq major-mode 'circe-channel-mode)
+        (remove-circe-color-nicks))))
+  (remove-hook 'circe-channel-mode-hook
+               'add-circe-color-nicks))
+
+(defun add-circe-color-nicks ()
+  "Add `circe-color-nicks' to `lui-pre-output-hook'."
+  (add-hook 'lui-pre-output-hook 'circe-color-nicks))
+
+(defun remove-circe-color-nicks ()
+  "Remove `circe-color-nicks' from `lui-pre-output-hook'."
+  (remove-hook 'lui-pre-output-hook 'circe-color-nicks))
+
+
+(defgroup circe-color-nicks nil
+  "Nicks colorization for Circe"
+  :prefix "circe-color-nicks-"
+  :group 'circe)
+
+(defcustom circe-color-nicks-min-contrast-ratio 7
+  "Minimum contrast ratio from background for generated colors;
+recommended is 7:1, or at least 4.5:1 (7 stands for 7:1 here).
+Lower value allows higher color spread, but could lead to less
+readability."
+  :group 'circe-color-nicks)
+
+(defcustom circe-color-nicks-min-difference 17
+  "Minimum difference from each other for generated colors."
+  :group 'circe-color-nicks)
+
+(defcustom circe-color-nicks-min-fg-difference 17
+  "Minimum difference from foreground for generated colors."
+  :group 'circe-color-nicks)
+
+(defcustom circe-color-nicks-min-my-message-difference 0
+  "Minimum difference from own nick color for generated colors."
+  :group 'circe-color-nicks)
+
+(defcustom circe-color-nicks-everywhere nil
+  "Whether nicks should be colored in message bodies too."
+  :type 'boolean
+  :group 'circe-color-nicks)
+
+(defcustom circe-color-nicks-message-blacklist nil
+  "Blacklist for nicks that shall never be highlighted inside
+  images."
+  :type '(repeat string)
+  :group 'circe-color-nicks)
+
+(defcustom circe-color-nicks-pool-type 'adaptive
+  "Type of the color nick pool.
+Must be one of the following:
+
+'adaptive: Generate colors based on the current theme.
+
+List of strings: Pick colors from the specified list of hex codes
+or color names (see `color-name-rgb-alist')."
+  :type '(choice (const :tag "Adaptive" adaptive)
+                 (repeat string))
+  :group 'circe-color-nicks)
+
+
+;;; See http://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G18
+
+(defsubst circe-w3-contrast-c-to-l (c)
+  (if (<= c 0.03928)
+      (/ c 12.92)
+    (expt (/ (+ c 0.055) 1.055) 2.4)))
+
+(defsubst circe-w3-contrast-relative-luminance (rgb)
+  (apply #'+
+         (cl-mapcar (lambda (color coefficient)
+                      (* coefficient
+                         (circe-w3-contrast-c-to-l color)))
+                    rgb
+                    '(0.2126 0.7152 0.0722))))
+
+(defsubst circe-w3-contrast-contrast-ratio (color1 color2)
+  (let ((l1 (+ 0.05 (circe-w3-contrast-relative-luminance color1)))
+        (l2 (+ 0.05 (circe-w3-contrast-relative-luminance color2))))
+    (if (> l1 l2)
+        (/ l1 l2)
+        (/ l2 l1))))
+
+
+(defun circe-color-alist ()
+  "Return list of colors (name rgb lab) where rgb is 0 to 1."
+  (let ((alist (if (display-graphic-p)
+                   color-name-rgb-alist
+                 (mapcar (lambda (c)
+                           (cons (car c) (cddr c)))
+                         (tty-color-alist))))
+        (valmax (float (car (color-values "#ffffff")))))
+    (mapcar (lambda (c)
+              (let* ((name (car c))
+                     (rgb (mapcar (lambda (v)
+                                    (/ v valmax))
+                                  (cdr c)))
+                     (lab (apply #'color-srgb-to-lab rgb)))
+                (list name rgb lab)))
+            alist)))
+
+(defun circe-color-canonicalize-format (color)
+  "Turns COLOR into (name rgb lab) format.  Avoid calling this in
+a loop, it's very slow on a tty!"
+  (let* ((name color)
+         (rgb (circe-color-name-to-rgb color))
+         (lab (apply #'color-srgb-to-lab rgb)))
+   (list name rgb lab)))
+
+(defun circe-color-contrast-ratio (color1 color2)
+  "Gives the contrast ratio between two colors."
+  (circe-w3-contrast-contrast-ratio (nth 1 color1) (nth 1 color2)))
+
+(defun circe-color-diff (color1 color2)
+  "Gives the difference between two colors per CIEDE2000."
+  (color-cie-de2000 (nth 2 color1) (nth 2 color2)))
+
+(defun circe-color-name-to-rgb (color)
+  "Like `color-name-to-rgb' but also handles \"unspecified-bg\"
+and \"unspecified-fg\"."
+  (cond ((equal color "unspecified-bg") '(0 0 0))
+        ((equal color "unspecified-fg") '(1 1 1))
+        (t (color-name-to-rgb color))))
+
+
+(defun circe-nick-color-appropriate-p (color bg fg my-msg)
+  "Tells whether COLOR is appropriate for being a nick color.
+BG, FG, and MY-MSG are the background, foreground, and my-message
+colors; these are expected as parameters instead of computed here
+because computing them repeatedly is a heavy operation."
+  (and (>= (circe-color-contrast-ratio color bg)
+           circe-color-nicks-min-contrast-ratio)
+       (>= (circe-color-diff color fg)
+           circe-color-nicks-min-fg-difference)
+       (>= (circe-color-diff color my-msg)
+           circe-color-nicks-min-my-message-difference)))
+
+(defun circe-nick-colors-delete-similar (colors)
+  "Return list COLORS with pairs of colors filtered out that are
+too similar per `circe-color-nicks-min-difference'.  COLORS may
+be mutated."
+  (cl-mapl (lambda (rest)
+             (let ((color (car rest)))
+               (setcdr rest (cl-delete-if
+                             (lambda (c)
+                               (< (circe-color-diff color c)
+                                  circe-color-nicks-min-difference))
+                             (cdr rest)))))
+           colors)
+  colors)
+
+(defun circe-nick-color-generate-pool ()
+  "Return a list of appropriate nick colors."
+  (if (consp circe-color-nicks-pool-type)
+      circe-color-nicks-pool-type
+    (let ((bg (circe-color-canonicalize-format (face-background 'default)))
+          (fg (circe-color-canonicalize-format (face-foreground 'default)))
+          (my-msg (circe-color-canonicalize-format
+                   (face-attribute
+                    'circe-my-message-face :foreground nil 'default))))
+      (mapcar #'car (circe-nick-colors-delete-similar
+                     (cl-remove-if-not
+                      (lambda (c)
+                        (circe-nick-color-appropriate-p c bg fg my-msg))
+                      (circe-color-alist)))))))
+
+(defun circe-nick-color-pool-test ()
+  "Display all appropriate nick colors in a temp buffer."
+  (interactive)
+  (switch-to-buffer (get-buffer-create "*Circe color test*"))
+  (erase-buffer)
+  (let ((pool (circe-nick-color-generate-pool)))
+    (while pool
+      (let ((pt (point)))
+        (insert "The quick brown fox jumped over the lazy dog.\n")
+        (put-text-property pt (point) 'face `(:foreground ,(pop pool)))))))
+
+(defvar circe-nick-color-pool nil
+  "Pool of yet unused nick colors.")
+
+(defvar circe-nick-color-mapping (make-hash-table :test 'equal)
+  "Hash-table from nicks to colors.")
+
+(defun circe-nick-color-nick-list ()
+  "Return list of all nicks that should be colored in this channel.
+Own and blacklisted nicks are excluded."
+  (let ((our-nick (circe-nick))
+        (channel-nicks (circe-channel-nicks)))
+    (cl-remove-if (lambda (nick)
+                    (or (string= our-nick nick)
+                        (member nick circe-color-nicks-message-blacklist)))
+                  channel-nicks)))
+
+(defvar circe-nick-color-timestamps (make-hash-table :test 'equal)
+  "Hash-table from colors to the timestamp of their last use.")
+
+(defun circe-nick-color-for-nick (nick)
+  "Return the color for NICK.  Assigns a color to NICK if one
+wasn't assigned already."
+  (let ((color (gethash nick circe-nick-color-mapping)))
+    (when (not color)
+      ;; NOTE use this as entry point for taking NICK into account for
+      ;; picking the new color
+      (setq color (circe-nick-color-pick))
+      (puthash nick color circe-nick-color-mapping))
+    (puthash color (float-time) circe-nick-color-timestamps)
+    color))
+
+(defun circe-nick-color-pick ()
+  "Picks either a color from the pool of unused colors, or the
+color that was used least recently (i.e. nicks that have it
+assigned have been least recently active)."
+  (if (zerop (hash-table-count circe-nick-color-mapping))
+      (setq circe-nick-color-pool (circe-nick-color-generate-pool)))
+  (or (pop circe-nick-color-pool)
+      (circe-nick-color-pick-least-recent)))
+
+(defun circe-nick-color-pick-least-recent ()
+  "Pick the color that was used least recently.
+See `circe-nick-color-pick', which is where this is used."
+  (let ((least-recent-color nil)
+        (oldest-time (float-time)))
+    (maphash
+     (lambda (color time)
+       (if (< time oldest-time)
+           (progn
+             (setq least-recent-color color)
+             (setq oldest-time time))))
+     circe-nick-color-timestamps)
+    (if least-recent-color
+        least-recent-color
+      ;; Someone must have messed with `circe-nick-color-mapping', recover by
+      ;; re-filling the pool.
+      (setq circe-nick-color-pool (circe-nick-color-generate-pool))
+      (pop circe-nick-color-pool))))
+
+(defun circe-color-nicks ()
+  "Color nicks on this lui output line."
+  (when (eq major-mode 'circe-channel-mode)
+    (let ((nickstart (text-property-any (point-min) (point-max)
+                                        'lui-format-argument 'nick)))
+      (when nickstart
+        (goto-char nickstart)
+        (let ((nickend (next-single-property-change nickstart
+                                                    'lui-format-argument))
+              (nick (plist-get (plist-get (text-properties-at nickstart)
+                                          'lui-keywords)
+                               :nick)))
+          (when (not (circe-server-my-nick-p nick))
+            (let ((color (circe-nick-color-for-nick nick)))
+              (add-face-text-property nickstart nickend
+                                      `(:foreground ,color)))))))
+    (when circe-color-nicks-everywhere
+      (let ((body (text-property-any (point-min) (point-max)
+                                     'lui-format-argument 'body)))
+        (when body
+          (with-syntax-table circe-nick-syntax-table
+            (goto-char body)
+            (let* ((nicks (circe-nick-color-nick-list))
+                   (regex (regexp-opt nicks 'words)))
+              (let (case-fold-search)
+                (while (re-search-forward regex nil t)
+                  (let* ((nick (match-string-no-properties 0))
+                         (color (circe-nick-color-for-nick nick)))
+                    (add-face-text-property (match-beginning 0) (match-end 0)
+                                            `(:foreground ,color))))))))))))
+
+(defun circe-nick-color-reset ()
+  "Reset the nick color mapping (and some internal data).
+
+This is useful if you switched between frames supporting
+different color ranges and would like nicks to get new colors
+appropriate to the new color range."
+  (interactive)
+  (setq circe-nick-color-pool (circe-nick-color-generate-pool))
+  (setq circe-nick-color-mapping (make-hash-table :test 'equal))
+  (setq circe-nick-color-timestamps (make-hash-table :test 'equal)))
+
+(provide 'circe-color-nicks)
+;;; circe-color-nicks.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/circe-color-nicks.elc b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/circe-color-nicks.elc
new file mode 100644
index 0000000000..8758a95984
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/circe-color-nicks.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/circe-compat.el b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/circe-compat.el
new file mode 100644
index 0000000000..f509c66d5b
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/circe-compat.el
@@ -0,0 +1,53 @@
+;;; circe-compat.el --- Compatibility definitions
+
+;; Copyright (C) 2015  Jorgen Schaefer <contact@jorgenschaefer.de>
+
+;; Author: Jorgen Schaefer <contact@jorgenschaefer.de>
+
+;; This program 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.
+
+;; This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Define functions and variables as needed by Circe to remain
+;; compatible with older Emacsen.
+
+;;; Code:
+
+(when (not (fboundp 'string-trim))
+  (defun string-trim (string)
+    "Remove leading and trailing whitespace from STRING."
+    (if (string-match "\\` *\\(.*[^[:space:]]\\) *\\'" string)
+        (match-string 1 string)
+      string)))
+
+(when (not (fboundp 'add-face-text-property))
+  (defun add-face-text-property (start end face &optional append object)
+    (while (/= start end)
+      (let* ((next (next-single-property-change start 'face object end))
+             (prev (get-text-property start 'face object))
+             (value (if (listp prev) prev (list prev))))
+        (put-text-property start next 'face
+                           (if append
+                               (append value (list face))
+                             (append (list face) value))
+                           object)
+        (setq start next)))))
+
+(when (not (boundp 'mode-line-misc-info))
+  (defvar mode-line-misc-info nil
+    "Misc info in the mode line.")
+  (add-to-list 'mode-line-format 'mode-line-misc-info t))
+
+(provide 'circe-compat)
+;;; circe-compat.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/circe-compat.elc b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/circe-compat.elc
new file mode 100644
index 0000000000..bd4554cbac
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/circe-compat.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/circe-display-images.el b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/circe-display-images.el
new file mode 100644
index 0000000000..6c9e29a251
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/circe-display-images.el
@@ -0,0 +1,197 @@
+;;; circe-display-images.el --- Display images in the channel -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 Nathan Aclander
+
+;; Author: Nathan Aclander <nathan.aclander@gmail.com>
+
+;; This file is part of Circe.
+
+;; This program 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.
+
+;; This program 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 this program; if not, write to the Free Software
+;; Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301  USA
+
+;;; Commentary:
+
+;; This Circe modules adds the ability to display various image types when
+;; they are linked in a channel. Images are inserted on new lines after
+;; the message containing the URLs. This module requires ImageMagcik.
+
+;; To use it, put the following into your .emacs:
+
+;; (require 'circe-display-images)
+;; (enable-circe-display-images)
+
+;;; Code:
+
+(require 'circe)
+(require 'url)
+
+;;;###autoload
+(defun enable-circe-display-images ()
+  "Enable the Display Images module for Circe.
+This module displays various image types when they are linked in a channel"
+  (interactive)
+  (dolist (buf (buffer-list))
+    (with-current-buffer buf
+      (when (eq major-mode 'circe-channel-mode)
+        (add-circe-display-images))))
+  (add-hook 'circe-channel-mode-hook
+            'add-circe-display-images))
+
+(defun disable-circe-display-images ()
+  "Disable the Display Images module for Circe.
+See `enable-circe-display-images'."
+  (interactive)
+  (dolist (buf (buffer-list))
+    (with-current-buffer buf
+      (when (eq major-mode 'circe-channel-mode)
+        (remove-circe-display-images))))
+  (remove-hook 'circe-channel-mode-hook
+               'add-circe-display-images))
+
+(defun add-circe-display-images ()
+  "Add `circe-display-images' to `lui-pre-output-hook'."
+  (add-hook 'lui-pre-output-hook 'circe-display-images))
+
+(defun remove-circe-display-images ()
+  "Remove `circe-display-images' from `lui-pre-output-hook'."
+  (remove-hook 'lui-pre-output-hook 'circe-display-images))
+
+(defgroup circe-display-images nil
+  "Image display properties for Circe"
+  :prefix "circe-display-images"
+  :group 'circe)
+
+(defcustom circe-display-images-image-regex
+  "\\(https?:\/\/[^ ]*?\.\\\(?:png\\|jpg\\|jpeg\\|svg\\|gif\\)\\)"
+  "Regex used to find images in channel messages. This regex needs to be
+greedy to match multiple images on the same line."
+  :group 'circe-display-images)
+
+(defcustom circe-display-images-max-height 400
+  "The image's maximum allowed height. Images will be scaled down if they
+are larger than this"
+  :group 'circe-display-images)
+
+(defcustom circe-display-images-background nil
+  "Background used for the images background, if image supports transparency.
+Defaults to the frame's background color."
+  :group 'circe-display-images)
+
+(defcustom circe-display-images-animate-gifs nil
+  "Animate any gifs that are displayed. This might slow down Emacs."
+  :group 'circe-display-images)
+
+(defvar-local circe-display-images-text-property-map (make-hash-table
+                                                      :test 'equal)
+  "A hash map used to manage display transitions.
+
+The keys are urls, and the values are a plist with an `:image-property', and a
+`:display-image-p'. `:image-property' is the display property of the image, and
+`:display-image-p' is a flag telling us whether the image is currently visible
+or not. This map serves to keep track of display transitions, and as a mapping
+between the URL and its downloaded image.
+
+Unfortunately we can't map from URL to the image position in the buffer
+because 1) the lui library can move text around when executing the
+`lui-post-output-hooks' and 2) as we toggle images, that also changes other
+images' position in the buffer.")
+
+(defun circe-display-images-toggle-image-at-point ()
+  "Toggle the image corresponding to the url at point.
+
+This function iterates through all display properties in the buffer. We look
+for a match with the display property we got from our property map, with the
+url-at-point as the key. When we find a match, we either remove or add back
+the image. See `circe-display-images-text-property-map' for more details."
+  ;; Giant thank you to Malabarba who's S-O answer I slightly modified:
+  ;; https://emacs.stackexchange.com/a/566
+  (interactive)
+  (let*
+      ((inhibit-read-only t)
+       (url (url-get-url-at-point))
+       (image-data(gethash url circe-display-images-text-property-map))
+       (display-image-p (plist-get image-data :display-image-p))
+       (image-property-of-url (plist-get image-data :image-property))
+       (from (if display-image-p 'display 'display-backup))
+       (to (if display-image-p 'display-backup 'display))
+       (current-pos (point-min))
+       left current-image-property)
+    (while (and current-pos (/= current-pos (point-max)))
+      ;; Find the next image property in the buffer.
+      (if (get-text-property current-pos from)
+          (setq left current-pos)
+        (setq left (next-single-property-change current-pos from)))
+      (if (or (null left) (= left (point-max)))
+          (setq current-pos nil)
+        (setq current-image-property (get-text-property left from))
+        (setq current-pos (or (next-single-property-change left from)
+                              (point-max)))
+        ;; Swap the images if our current image matches the image from the URL.
+        (when (equal image-property-of-url current-image-property)
+          (add-text-properties
+           left current-pos (list from nil to current-image-property)))))
+    ;; Make sure to invert the :display-image-p flag after processing all
+    ;; images.
+    (puthash url `(:image-property ,image-property-of-url
+                   :display-image-p ,(not display-image-p))
+             circe-display-images-text-property-map)))
+
+(defun circe-display-images-insert-image-from-url (url)
+  "Attempt to download the image from URL, and insert it."
+  (let ((buffer (url-retrieve-synchronously url)))
+    (when buffer
+      (unwind-protect
+          (let* ((data (with-current-buffer buffer
+                         (goto-char (point-min))
+                         (search-forward "\n\n")
+                         (buffer-substring (point) (point-max))))
+                 (img (create-image
+                       data 'imagemagick t
+                       :max-height circe-display-images-max-height
+                       :background circe-display-images-background)))
+            (when img
+              (insert-image img)
+              ;; Store the image so that we can toggle it on and off later. We
+              ;; know the image is 1 behind us, since we just inserted it.
+              (let* ((image-property
+                      (get-text-property (- (point) 1) 'display)))
+                (puthash url
+                         `(:image-property ,image-property :display-image-p t)
+                         circe-display-images-text-property-map))
+              ;; This is safely a no-op if the image isn't a gif.
+              (when circe-display-images-animate-gifs
+                (image-animate img))))
+        (kill-buffer buffer)))))
+
+(defun circe-display-images-urls-in-body ()
+  "Return all urls that match the circe-display-images-image-regex"
+  (let (urls)
+    (while (re-search-forward circe-display-images-image-regex nil t)
+      (setq urls (cons (match-string-no-properties 1) urls)))
+    (reverse urls)))
+
+(defun circe-display-images ()
+  "Replace image link with downloaded image on this lui output line"
+  (let ((body (text-property-any (point-min) (point-max)
+                                 'lui-format-argument 'body)))
+    (when body
+      (goto-char body)
+      (dolist (url (circe-display-images-urls-in-body))
+        (newline)
+        (circe-display-images-insert-image-from-url url)
+        (newline)))))
+
+(provide 'circe-display-images)
+;;; circe-display-images.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/circe-display-images.elc b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/circe-display-images.elc
new file mode 100644
index 0000000000..4ebbda193b
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/circe-display-images.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/circe-lagmon.el b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/circe-lagmon.el
new file mode 100644
index 0000000000..42a37329ca
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/circe-lagmon.el
@@ -0,0 +1,243 @@
+;;; circe-lagmon.el --- Lag Monitor for Circe
+
+;; Copyright (C) 2011-2012 Jorgen Schaefer
+
+;; Author: John J Foerch <jjfoerch@earthlink.net>,
+;;         Jorgen Schaefer
+
+;; This file is part of Circe.
+
+;; This program 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.
+
+;; This program 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 this program; if not, write to the Free Software
+;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Commentary:
+;;;
+;;;   Circe-lagmon-mode monitors the amount of lag on your connection to
+;;; each server, and displays the lag time in seconds in the mode-line.
+;;; It works by managing two timers.  Timer1 sends CTCP LAGMON to yourself
+;;; on each server every 60 seconds.  Each time around, timer1 starts
+;;; timer2 to monitor for timeouts of these messages.  Timer2 cancels
+;;; itself when all of the pings in the round have been answered.
+;;;
+
+;;; Code:
+
+(require 'circe)
+
+;;; User variables
+
+(defgroup circe-lagmon nil
+  "Lag Monitor for Circe"
+  :prefix "circe-lagmon-"
+  :group 'circe)
+
+(defcustom circe-lagmon-timer-tick 5
+  "How often to check for lag.
+
+Increase this to improve performance at the cost of accuracy."
+  :type 'number
+  :group 'circe-lagmon)
+
+(defcustom circe-lagmon-check-interval 60
+  "Interval in seconds at which to send the CTCP message."
+  :type 'number
+  :group 'circe-lagmon)
+
+(defcustom circe-lagmon-reconnect-interval 120
+  "Seconds after which to automatically reconnect upon a timeout
+of a lag monitor message. A value of nil disables the feature."
+  :type '(choice (const :tag "Disable auto-reconnect" nil)
+                 number)
+  :group 'circe-lagmon)
+
+(defcustom circe-lagmon-mode-line-format-string "lag:%.1f "
+  "Format string for displaying the lag in the mode-line."
+  :type 'string
+  :group 'circe-lagmon)
+
+(defcustom circe-lagmon-mode-line-unknown-lag-string "lag:? "
+  "Indicator string for displaying unknown lag in the mode-line."
+  :type 'string
+  :group 'circe-lagmon)
+
+(defvar circe-lagmon-disabled nil
+  "A boolean value if lagmon should be disabled on this network.
+
+Don't set this by hand, use `circe-network-options'.")
+(make-variable-buffer-local 'circe-lagmon-disabled)
+
+
+;;; Internal variables
+;;;
+(defvar circe-lagmon-timer nil)
+
+(defvar circe-lagmon-server-lag nil)
+(make-variable-buffer-local 'circe-lagmon-server-lag)
+
+(defvar circe-lagmon-last-send-time nil)
+(make-variable-buffer-local 'circe-lagmon-last-send-time)
+
+(defvar circe-lagmon-last-receive-time nil)
+(make-variable-buffer-local 'circe-lagmon-last-receive-time)
+
+(defun circe-lagmon-timer-tick ()
+  "Function run periodically to check lag.
+
+This will call `circe-lagmon-server-check' in every active server
+buffer. You can call it yourself if you like to force an update,
+there is no harm in running it too often, but it really should be
+run sufficiently often with the timer."
+  (dolist (buffer (circe-server-buffers))
+    (with-current-buffer buffer
+      (when (and (eq major-mode 'circe-server-mode)
+                 circe-server-process
+                 (eq (irc-connection-state circe-server-process)
+                     'registered)
+                 (not circe-lagmon-disabled))
+        (circe-lagmon-server-check)))))
+
+(defun circe-lagmon-server-check ()
+  "Check the current server for lag.
+
+This will reconnect if we haven't heard back for too long, or
+send a request if it's time for that. See
+`circe-lagmon-reconnect-interval' and
+`circe-lagmon-check-interval' to configure the behavior.."
+  (let ((now (float-time)))
+    (cond
+     ;; No answer so far...
+     ((and circe-lagmon-last-send-time
+           (not circe-lagmon-last-receive-time))
+      ;; Count up until the answer comes.
+      (let ((lag (/ (- now circe-lagmon-last-send-time) 2)))
+        (when (or (not circe-lagmon-server-lag)
+                  (> lag circe-lagmon-server-lag))
+          (setq circe-lagmon-server-lag lag)
+          (circe-lagmon-force-mode-line-update)))
+      ;; Check for timeout.
+      (when (and circe-lagmon-reconnect-interval
+                 (> now
+                    (+ circe-lagmon-last-send-time
+                       circe-lagmon-reconnect-interval)))
+        (setq circe-lagmon-last-send-time nil
+              circe-lagmon-last-receive-time nil)
+        (circe-reconnect)))
+     ;; Nothing sent so far, or last send was too long ago.
+     ((or (not circe-lagmon-last-send-time)
+          (> now
+             (+ circe-lagmon-last-send-time
+                circe-lagmon-check-interval)))
+      (irc-send-raw (circe-server-process)
+                    (format "PRIVMSG %s :\C-aLAGMON %s\C-a"
+                            (circe-nick) now)
+                    :nowait)
+      (setq circe-lagmon-last-send-time now
+            circe-lagmon-last-receive-time nil))
+     )))
+
+(defun circe-lagmon-force-mode-line-update ()
+  "Call force-mode-line-update on a circe server buffer and all
+of its chat buffers."
+  (force-mode-line-update)
+  (dolist (b (circe-server-chat-buffers))
+    (with-current-buffer b
+      (force-mode-line-update))))
+
+(defun circe-lagmon-format-mode-line-entry ()
+  "Format the mode-line entry for displaying the lag."
+  (let ((buf (cond
+              ((eq major-mode 'circe-server-mode)
+               (current-buffer))
+              (circe-server-buffer
+               circe-server-buffer)
+              (t
+               nil))))
+    (when buf
+      (with-current-buffer buf
+        (cond
+         (circe-lagmon-disabled
+          nil)
+         (circe-lagmon-server-lag
+          (format circe-lagmon-mode-line-format-string
+                  circe-lagmon-server-lag))
+         (t
+          circe-lagmon-mode-line-unknown-lag-string))))))
+
+(defun circe-lagmon-init ()
+  "Initialize the values of the lag monitor for one server, and
+start the lag monitor if it has not been started."
+  (setq circe-lagmon-server-lag nil
+        circe-lagmon-last-send-time nil
+        circe-lagmon-last-receive-time nil)
+  (circe-lagmon-force-mode-line-update)
+  (unless circe-lagmon-timer
+    (setq circe-lagmon-timer
+          (run-at-time nil circe-lagmon-timer-tick
+                       'circe-lagmon-timer-tick))))
+
+(defun circe-lagmon--rpl-welcome-handler (conn &rest ignored)
+  (with-current-buffer (irc-connection-get conn :server-buffer)
+    (circe-lagmon-init)))
+
+(defun circe-lagmon--ctcp-lagmon-handler (conn event sender target argument)
+  (when (irc-current-nick-p conn (irc-userstring-nick sender))
+    (with-current-buffer (irc-connection-get conn :server-buffer)
+      (let* ((now (float-time))
+             (lag (/ (- now (string-to-number argument))
+                     2)))
+        (setq circe-lagmon-server-lag lag
+              circe-lagmon-last-receive-time now)
+        (circe-lagmon-force-mode-line-update)))))
+
+(defun circe-lagmon--nick-handler (conn event sender new-nick)
+  (when (irc-current-nick-p conn (irc-userstring-nick sender))
+    (with-current-buffer (irc-connection-get conn :server-buffer)
+      (setq circe-lagmon-last-send-time nil))))
+
+;;;###autoload
+(define-minor-mode circe-lagmon-mode
+  "Circe-lagmon-mode monitors the amount of lag on your
+connection to each server, and displays the lag time in seconds
+in the mode-line."
+  :global t
+  (let ((mode-line-entry '(:eval (circe-lagmon-format-mode-line-entry))))
+    (remove-hook 'mode-line-modes mode-line-entry)
+    (let ((table (circe-irc-handler-table)))
+      (irc-handler-remove table "001" 'circe-lagmon--rpl-welcome-handler)
+      (irc-handler-remove table "irc.ctcp.LAGMON"
+                          'circe-lagmon--ctcp-lagmon-handler)
+      (irc-handler-remove table "NICK" 'circe-lagmon--nick-handler))
+    (circe-set-display-handler "irc.ctcp.LAGMON" nil)
+    (when circe-lagmon-timer
+      (cancel-timer circe-lagmon-timer)
+      (setq circe-lagmon-timer nil))
+    (when circe-lagmon-mode
+      (add-hook 'mode-line-modes mode-line-entry)
+      (let ((table (circe-irc-handler-table)))
+        (irc-handler-add table "001" 'circe-lagmon--rpl-welcome-handler)
+        (irc-handler-add table "irc.ctcp.LAGMON"
+                         'circe-lagmon--ctcp-lagmon-handler)
+        (irc-handler-add table "NICK" 'circe-lagmon--nick-handler))
+      (circe-set-display-handler "irc.ctcp.LAGMON" 'circe-display-ignore)
+      (dolist (buffer (circe-server-buffers))
+        (with-current-buffer buffer
+          (setq circe-lagmon-server-lag nil)
+          (when (and circe-server-process
+                     (eq (irc-connection-state circe-server-process)
+                         'registered))
+            (circe-lagmon-init)))))))
+
+(provide 'circe-lagmon)
+;;; circe-lagmon.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/circe-lagmon.elc b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/circe-lagmon.elc
new file mode 100644
index 0000000000..39353b9814
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/circe-lagmon.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/circe-new-day-notifier.el b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/circe-new-day-notifier.el
new file mode 100644
index 0000000000..88d9a4b350
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/circe-new-day-notifier.el
@@ -0,0 +1,86 @@
+;;; circe-new-day-notifier.el --- Send a message every midnight to all
+;;; channels
+
+;; Copyright (C) 2015 Pásztor János
+
+;; Author: Pásztor János <model87@freemail.hu>
+
+;; This file is part of Circe.
+
+;; This program 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 2
+;; of the License, or (at your option) any later version.
+
+;; This program 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 this program; if not, write to the Free Software
+;; Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301 USA
+
+;;; Commentary:
+
+;; This Circe module adds the ability to send a notification to all
+;; channels every midnight
+
+;; Some ideas/code copied from circe-lagmon.el and
+;; circe-color-nicks.el
+
+;; To use it, put the following into your .emacs:
+
+;; (require 'circe-new-day-notifier)
+;; (enable-circe-new-day-notifier)
+
+;;; Code:
+
+(require 'circe)
+
+(defgroup circe-new-day-notifier nil
+  "Midnight notification to Circe"
+  :prefix "circe-new-day-notifier-"
+  :group 'circe)
+
+(defcustom circe-new-day-notifier-format-message "*** Day changed to {day}"
+  "The format string which will be printed to the channels. It
+should contain {day} to print the date. See `circe-display' for
+further documentation"
+  :type 'string
+  :group 'circe-new-day-notifier)
+
+(defcustom circe-new-day-notifier-date-format "%Y-%m-%d, %A"
+  "The date format, which will be used at
+circe-new-day-notifier-format-message. See `format-time-string' for
+documentation"
+  :type 'string
+  :group 'circe-new-day-notifier)
+
+(defvar circe-new-day-notifier-timer nil)
+
+;;;###autoload
+(defun enable-circe-new-day-notifier ()
+  (interactive)
+    (unless circe-new-day-notifier-timer
+      (setq circe-new-day-notifier-timer
+            (run-at-time "24:00:00" (* 24 60 60) 'circe-new-day-notification))))
+
+;;;###autoload
+(defun disable-circe-new-day-notifier ()
+  (interactive)
+  (when circe-new-day-notifier-timer
+    (cancel-timer circe-new-day-notifier-timer)
+    (setq circe-new-day-notifier-timer nil)))
+
+(defun circe-new-day-notification ()
+  "This function prints the new day notification to each query and chat buffer"
+  (dolist (buf (buffer-list))
+    (with-current-buffer buf
+      (when (derived-mode-p 'circe-chat-mode)
+        (circe-display 'circe-new-day-notifier-format-message
+                       :day (format-time-string circe-new-day-notifier-date-format))))))
+
+(provide 'circe-new-day-notifier)
+;;; circe-new-day-notifier.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/circe-new-day-notifier.elc b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/circe-new-day-notifier.elc
new file mode 100644
index 0000000000..070093319b
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/circe-new-day-notifier.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/circe-pkg.el b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/circe-pkg.el
new file mode 100644
index 0000000000..cf27de48b8
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/circe-pkg.el
@@ -0,0 +1,6 @@
+(define-package "circe" "20180525.531" "Client for IRC in Emacs"
+  '((cl-lib "0.5"))
+  :url "https://github.com/jorgenschaefer/circe")
+;; Local Variables:
+;; no-byte-compile: t
+;; End:
diff --git a/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/circe.el b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/circe.el
new file mode 100644
index 0000000000..721044dd2a
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/circe.el
@@ -0,0 +1,3602 @@
+;;; circe.el --- Client for IRC in Emacs -*- lexical-binding: t -*-
+
+;; Copyright (C) 2005 - 2015  Jorgen Schaefer
+
+;; Version: 2.10
+;; Keywords: IRC, chat
+;; Author: Jorgen Schaefer <forcer@forcix.cx>
+;; URL: https://github.com/jorgenschaefer/circe
+
+;; This file is part of Circe.
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Circe is a Client for IRC in Emacs. It integrates well with the rest
+;; of the editor, using standard Emacs key bindings and indicating
+;; activity in channels in the status bar so it stays out of your way
+;; unless you want to use it.
+
+;;; Code:
+
+(defvar circe-version "2.10"
+  "Circe version string.")
+
+(require 'circe-compat)
+
+(require 'ring)
+(require 'timer)
+(require 'lui)
+(require 'lui-format)
+(require 'lcs)
+(require 'irc)
+
+;; Used to be optional. But sorry, we're in the 21st century already.
+(require 'lui-irc-colors)
+
+;; necessary for inheriting from diff-added and diff-removed faces
+(require 'diff-mode)
+
+(defgroup circe nil
+  "Yet Another Emacs IRC Client."
+  :prefix "circe-"
+  :group 'applications)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; Customization Options ;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;;;;;;;;;;;;;;;
+;;;; Faces ;;;;
+;;;;;;;;;;;;;;;
+
+(defface circe-prompt-face
+  '((t (:weight bold :foreground "Black" :background "LightSeaGreen")))
+  "The face for the Circe prompt."
+  :group 'circe)
+
+(defface circe-server-face
+  '((((type tty)) (:foreground "blue" :weight bold))
+    (((background dark)) (:foreground "#5095cf"))
+    (((background light)) (:foreground "#3840b0"))
+    (t (:foreground "SteelBlue")))
+  "The face used to highlight server messages."
+  :group 'circe)
+
+(defface circe-highlight-nick-face
+  '((default (:weight bold))
+    (((type tty)) (:foreground "cyan"))
+    (((background dark)) (:foreground "#82e2ed"))
+    (((background light)) (:foreground "#0445b7"))
+    (t (:foreground "CadetBlue3")))
+  "The face used to highlight messages directed to us."
+  :group 'circe)
+
+(defface circe-my-message-face '((t))
+  "The face used to highlight our own messages."
+  :group 'circe)
+
+(defface circe-originator-face '((t))
+  "The face used to highlight the originator of a message."
+  :group 'circe)
+
+(defface circe-topic-diff-new-face '((t (:inherit diff-added)))
+  "The face used for text added to a topic.
+See the {topic-diff} parameter to `circe-format-server-topic'."
+  :group 'circe)
+
+(defface circe-topic-diff-removed-face '((t (:inherit diff-removed)))
+  "The face used for text removed from a topic.
+See the {topic-diff} parameter to `circe-format-server-topic'."
+  :group 'circe)
+
+(defface circe-fool-face
+  '((((type tty)) (:foreground "grey40" :bold t))
+    (t (:foreground "grey40")))
+  "The face used for fools.
+See `circe-fool-list'."
+  :group 'circe)
+
+;;;;;;;;;;;;;;;;;;;
+;;;; Variables ;;;;
+;;;;;;;;;;;;;;;;;;;
+
+(defcustom circe-default-nick (user-login-name)
+  "The default nick for circe."
+  :type 'string
+  :group 'circe)
+
+(defcustom circe-default-user circe-default-nick
+  "The default user name for circe."
+  :type 'string
+  :group 'circe)
+
+(defcustom circe-default-realname (if (string= (user-full-name) "")
+                                      circe-default-nick
+                                    (user-full-name))
+  "The default real name for circe."
+  :type 'string
+  :group 'circe)
+
+(defcustom circe-default-ip-family nil
+  "Default IP family to use.
+
+  'nil  - Use either IPv4 or IPv6.
+
+  'ipv4 - Use IPv4
+
+  'ipv6 - Use IPv6"
+  :type '(choice (const :tag "Both" nil)
+                 (const :tag "IPv4" ipv4)
+                 (const :tag "IPv6" ipv6))
+  :group 'circe)
+
+(defcustom circe-default-directory "~/"
+  "The value of `default-directory' for Circe buffers."
+  :type 'string
+  :group 'circe)
+
+(defcustom circe-network-options nil
+  "Network options.
+
+This alist maps network names to respective options.
+
+Common options:
+
+  :pass - The IRC server password to use for this network, or a
+          function to fetch it.
+  :nick - The nick name to use (defaults to `circe-default-nick')
+  :user - The user name to use (defaults to `circe-default-user')
+  :realname - The real name to use (defaults to `circe-default-realname')
+
+  :channels - A plist of channels to join (see `circe-channels').
+  :server-buffer-name - Format to be used for the server buffer name
+                        (see `circe-server-buffer-name')
+
+  :host - The host name of the server to connect to.
+  :port - The port or service name for the server.
+  :use-tls - A boolean indicating as to whether to use TLS or
+             not (defaults to nil). If you set this, you'll likely
+             have to set :port as well.
+  :ip-family - Option to enforce a specific IP version
+               (defaults to `circe-default-ip-family')
+
+  :nickserv-nick - The nick to authenticate with to nickserv, if configured.
+                   (defaults to the value of :nick)
+  :nickserv-password - The password to use for nickserv
+                       authentication or a function to fetch it.
+
+  :sasl-username - The username for SASL authentication.
+  :sasl-password - The password for SASL authentication."
+  :type '(alist :key-type string :value-type plist)
+  :group 'circe)
+
+(defvar circe-network-defaults
+  '(("Freenode" :host "irc.freenode.net" :port (6667 . 6697)
+     :tls t
+     :nickserv-mask "^NickServ!NickServ@services\\.$"
+     :nickserv-identify-challenge "\C-b/msg\\s-NickServ\\s-identify\\s-<password>\C-b"
+     :nickserv-identify-command "PRIVMSG NickServ :IDENTIFY {nick} {password}"
+     :nickserv-identify-confirmation "^You are now identified for .*\\.$"
+     :nickserv-ghost-command "PRIVMSG NickServ :GHOST {nick} {password}"
+     :nickserv-ghost-confirmation "has been ghosted\\.$\\|is not online\\.$"
+     )
+    ("Coldfront" :host "irc.coldfront.net" :port 6667
+     :nickserv-mask "^NickServ!services@coldfront\\.net$"
+     :nickserv-identify-challenge "/msg\\s-NickServ\\s-IDENTIFY\\s-\C-_password\C-_"
+     :nickserv-identify-command "PRIVMSG NickServ :IDENTIFY {password}"
+     )
+    ("Bitlbee" :host "localhost" :port 6667
+     :nickserv-mask "\\(bitlbee\\|root\\)!\\(bitlbee\\|root\\)@"
+     :nickserv-identify-challenge "use the \x02identify\x02 command to identify yourself"
+     :nickserv-identify-command "PRIVMSG &bitlbee :identify {password}"
+     :nickserv-identify-confirmation "Password accepted, settings and accounts loaded"
+     :lagmon-disabled t
+     )
+    ("OFTC" :host "irc.oftc.net" :port (6667 . 6697)
+     :nickserv-mask "^NickServ!services@services\\.oftc\\.net$"
+     :nickserv-identify-challenge "This nickname is registered and protected."
+     :nickserv-identify-command "PRIVMSG NickServ :IDENTIFY {password} {nick}"
+     :nickserv-identify-confirmation "^You are successfully identified as .*\\.$"
+     )
+    )
+  "Alist of networks and connection settings.
+
+See the `circe' command for details of this variable.")
+
+(defcustom circe-default-quit-message "Using Circe, the loveliest of all IRC clients"
+  "The default quit message when no other is given.
+
+This is sent when the server buffer is killed or when /QUIT is
+given with no argument."
+  :type 'string
+  :group 'circe)
+
+(defcustom circe-default-part-message "Using Circe, the loveliest of all IRC clients"
+  "How to part when a channel buffer is killed, or when no
+argument is given to /PART."
+  :type 'string
+  :group 'circe)
+
+(defcustom circe-auto-query-max 23
+  "The maximum number of queries which are opened automatically.
+If more messages arrive - typically in a flood situation - they
+are displayed in the server buffer."
+  :type 'integer
+  :group 'circe)
+
+(defcustom circe-use-cycle-completion nil
+  "Whether Circe should use cycle completion.
+
+If this is not nil, Circe will set `completion-cycle-threshold'
+to t locally in Circe buffers, enabling cycle completion for
+nicks no matter what completion style you use in the rest of
+Emacs. If you set this to nil, Circe will not touch your default
+completion style."
+  :type 'boolean
+  :group 'circe)
+
+(defcustom circe-reduce-lurker-spam nil
+  "If enabled, Circe will stop showing some messages.
+
+This means that JOIN, PART, QUIT and NICK messages are not shown
+for users on channels that have not spoken yet (\"lurker\"), or
+haven't spoken in `circe-active-users-timeout' seconds. When they
+speak for the first time, Circe displays their join time."
+  :type 'boolean
+  :group 'circe)
+
+(defcustom circe-active-users-timeout nil
+  "When non-nil, should be the number of seconds after which
+active users are regarded as inactive again after speaking."
+  :type 'integer
+  :group 'circe)
+
+(defcustom circe-prompt-string (concat (propertize ">"
+                                                   'face 'circe-prompt-face)
+                                       " ")
+  "The string to initialize the prompt with.
+To change the prompt dynamically or just in specific buffers, use
+`lui-set-prompt' in the appropriate hooks."
+  :type 'string
+  :group 'circe)
+
+(defcustom circe-extra-nicks nil
+  "List of other nicks than your current one to highlight."
+  :type '(repeat string)
+  :group 'circe)
+
+(defcustom circe-highlight-nick-type 'sender
+  "How to highlight occurrences of our own nick.
+
+  'sender     - Highlight the nick of the sender
+                (messages without a sender and your
+                own are highlighted with the occurrence
+                type instead)
+  'occurrence - Highlight the occurrences of the nick
+  'message    - Highlight the message without the sender
+  'all        - Highlight the whole line"
+  :type '(choice (const :tag "Sender" sender)
+                 (const :tag "Occurrences" occurrence)
+                 (const :tag "Message" message)
+                 (const :tag "Whole line" all))
+  :group 'circe)
+
+(defcustom circe-inhibit-nick-highlight-function nil
+  "Function for inhibiting nick highlighting.
+If non-nil, its value is called with the respective buffer
+selected and point in the line that's about to get highlighted.
+A non-nil return value inhibits any highlighting."
+  :type '(choice (const :tag "None" nil)
+                 function)
+  :group 'circe)
+
+(defcustom circe-completion-suffix ": "
+  "A suffix for completed nicks at the beginning of a line."
+  :type '(choice (const :tag "The standard suffix" ": "))
+  :group 'circe)
+
+(defcustom circe-ignore-list nil
+  "List of regular expressions to ignore.
+
+Each regular expression is matched against nick!user@host."
+  :type '(repeat regexp)
+  :group 'circe)
+
+(defcustom circe-fool-list nil
+  "List of regular expressions for fools.
+
+Each regular expression is matched against nick!user@host.
+
+Messages from such people are still inserted, but not shown. They
+can be displayed using \\[lui-fool-toggle-display]."
+  :type '(repeat regexp)
+  :group 'circe)
+
+(defcustom circe-ignore-functions nil
+  "A list of functions to check whether we should ignore a message.
+
+These functions get three arguments: NICK, USERHOST, and BODY. If
+one of them returns a non-nil value, the message is ignored."
+  :type 'hook
+  :group 'circe)
+
+(defcustom circe-split-line-length 440
+  "The maximum length of a single message.
+If a message exceeds this size, it is broken into multiple ones.
+
+IRC allows for lines up to 512 bytes. Two of them are CR LF.
+And a typical message looks like this:
+
+  :nicky!uhuser@host212223.dialin.fnordisp.net PRIVMSG #lazybastards :Hello!
+
+You can limit here the maximum length of the \"Hello!\" part.
+Good luck."
+  :type 'integer
+  :group 'circe)
+
+(defcustom circe-server-max-reconnect-attempts 5
+  "How often Circe should attempt to reconnect to the server.
+If this is 0, Circe will not reconnect at all. If this is nil,
+it will try to reconnect forever (not recommended)."
+  :type '(choice integer
+                 (const :tag "Forever" nil))
+  :group 'circe)
+
+(defcustom circe-netsplit-delay 60
+  "The number of seconds a netsplit may be dormant.
+If anything happens with a netsplit after this amount of time,
+the user is re-notified."
+  :type 'number
+  :group 'circe)
+
+(defcustom circe-server-killed-confirmation 'ask-and-kill-all
+  "How to ask for confirmation when a server buffer is killed.
+This can be one of the following values:
+  ask - Ask the user for confirmation
+  ask-and-kill-all - Ask the user, and kill all associated buffers
+  kill-all - Don't ask the user, and kill all associated buffers
+  nil - Kill first, ask never"
+  :type '(choice (const :tag "Ask before killing" ask)
+                 (const :tag "Ask, then kill all associated buffers"
+                        ask-and-kill-all)
+                 (const :tag "Don't ask, then kill all associated buffers"
+                        kill-all)
+                 (const :tag "Don't ask" nil))
+  :group 'circe)
+
+(defcustom circe-channel-killed-confirmation 'ask
+  "How to ask for confirmation when a channel buffer is killed.
+This can be one of the following values:
+  ask - Ask the user for confirmation
+  nil - Don't ask, just kill"
+  :type '(choice (const :tag "Ask before killing" ask)
+                 (const :tag "Don't ask" nil))
+  :group 'circe)
+
+(defcustom circe-track-faces-priorities '(circe-highlight-nick-face
+                                          lui-highlight-face
+                                          circe-my-message-face
+                                          circe-server-face)
+  "A list of faces which should show up in the tracking.
+The first face is kept if the new message has only lower faces,
+or faces that don't show up at all."
+  :type '(repeat face)
+  :group 'circe)
+
+(defcustom circe-server-send-unknown-command-p nil
+  "Non-nil when Circe should just pass on commands it doesn't know.
+E.g. /fnord foo bar would then just send \"fnord foo bar\" to the
+server."
+  :type 'boolean
+  :group 'circe)
+
+(defcustom circe-server-connected-hook nil
+  "Hook run when we successfully connected to a server.
+This is run from a 001 (RPL_WELCOME) message handler."
+  :type 'hook
+  :group 'circe)
+
+(defcustom circe-server-auto-join-default-type :immediate
+  "The default auto-join type to use.
+
+Possible options:
+
+:immediate - Immediately after registering on the server
+:after-auth - After nickserv authentication succeeded
+:after-cloak - After we have acquired a cloaked host name
+:after-nick - After we regained our preferred nick, or after
+              nickserv authentication if we don't need to regain
+              it. See `circe-nickserv-ghost-style'.
+
+See `circe-channels' for more details."
+  :type '(choice (const :tag "Immediately" :immediate)
+                 (const :tag "After Authentication" :after-auth)
+                 (const :tag "After Cloaking" :after-cloak)
+                 (const :tag "After Nick Regain" :after-nick))
+  :group 'circe)
+
+;;;;;;;;;;;;;;;;;
+;;;; Formats ;;;;
+;;;;;;;;;;;;;;;;;
+
+(defgroup circe-format nil
+  "Format strings for Circe.
+All these formats always allow the {mynick} and {chattarget} format
+strings."
+  :prefix "circe-format-"
+  :group 'circe)
+
+(defcustom circe-format-not-tracked
+  '(circe-format-server-message
+    circe-format-server-notice
+    circe--irc-format-server-numeric
+    circe-format-server-topic
+    circe-format-server-rejoin
+    circe-format-server-lurker-activity
+    circe-format-server-topic-time
+    circe-format-server-topic-time-for-channel
+    circe-format-server-netmerge
+    circe-format-server-join
+    circe-format-server-join-in-channel
+    circe-format-server-mode-change
+    circe-format-server-nick-change-self
+    circe-format-server-nick-change
+    circe-format-server-nick-regain
+    circe-format-server-part
+    circe-format-server-netsplit
+    circe-format-server-quit-channel
+    circe-format-server-quit)
+  "A list of formats that should not trigger tracking."
+  :type '(repeat symbol)
+  :group 'circe-format)
+
+(defcustom circe-format-server-message "*** {body}"
+  "The format for generic server messages.
+{body} - The body of the message."
+  :type 'string
+  :group 'circe-format)
+
+(defcustom circe-format-self-say "> {body}"
+  "The format for messages to queries or channels.
+{nick} - Your nick.
+{body} - The body of the message."
+  :type 'string
+  :group 'circe-format)
+
+(defcustom circe-format-self-action "* {nick} {body}"
+  "The format for actions to queries or channels.
+{nick} - Your nick.
+{body} - The body of the action."
+  :type 'string
+  :group 'circe-format)
+
+(defcustom circe-format-self-message "-> *{chattarget}* {body}"
+  "The format for messages sent to other people outside of queries.
+{chattarget} - The target nick.
+{body} - The body of the message."
+  :type 'string
+  :group 'circe-format)
+
+(defcustom circe-format-action "* {nick} {body}"
+  "The format for actions in queries or channels.
+{nick} - The nick doing the action.
+{body} - The body of the action."
+  :type 'string
+  :group 'circe-format)
+
+(defcustom circe-format-message-action "* *{nick}* {body}"
+  "The format for actions in messages outside of queries.
+{nick} - The nick doing the action.
+{body} - The body of the action."
+  :type 'string
+  :group 'circe-format)
+
+(defcustom circe-format-say "<{nick}> {body}"
+  "The format for normal channel or query talk.
+{nick} - The nick talking.
+{body} - The message."
+  :type 'string
+  :group 'circe-format)
+
+(defcustom circe-format-message "*{nick}* {body}"
+  "The format for a message outside of a query.
+{nick} - The originator.
+{body} - The message."
+  :type 'string
+  :group 'circe-format)
+
+(defcustom circe-format-notice "-{nick}- {body}"
+  "The format for a notice.
+{nick} - The originator.
+{body} - The notice."
+  :type 'string
+  :group 'circe-format)
+
+(defcustom circe-format-server-notice "-Server Notice- {body}"
+  "The format for a server notice.
+{body} - The notice."
+  :type 'string
+  :group 'circe-format)
+
+(defcustom circe-format-server-topic "*** Topic change by {nick} ({userhost}): {new-topic}"
+  "The format for topic changes.
+
+The following format arguments are available:
+
+  nick       - The nick of the user who changed the topic
+  userhost   - The user@host string of that user
+  channel    - Where the topic change happened
+  new-topic  - The new topic
+  old-topic  - The previous topic
+  topic-diff - A colorized diff of the topics"
+  :type 'string
+  :group 'circe-format)
+
+(defcustom circe-format-server-lurker-activity
+  "*** First activity: {nick} joined {joindelta} ago."
+  "The format for the first-activity notice of a user.
+{nick} - The originator.
+{jointime} - The join time of the user (in seconds).
+{joindelta} - The duration from joining until now."
+  :type 'string
+  :group 'circe-format)
+
+(defcustom circe-format-server-rejoin
+  "*** Re-join: {nick} ({userinfo}), left {departuredelta} ago"
+  "The format for the re-join notice of a user.
+
+The following format arguments are available:
+
+  nick           - The nick of the user who joined
+  userhost       - The user@host string of the user who joined
+  accountname    - The account name, if the server supports this
+  realname       - The real name, if the server supports this
+  userinfo       - A combination of userhost, accountname, and realname
+  channel        - A date string describing this time
+  departuretime  - Time in seconds when the originator had left.
+  departuredelta - Description of the time delta since the originator left."
+  :type 'string
+  :group 'circe-format)
+
+(defcustom circe-server-buffer-name "{host}:{port}"
+  "The format for the server buffer name.
+
+The following format arguments are available:
+
+  network  - The name of the network
+  host     - The host name of the server
+  port     - The port number or service name
+  service  - Alias for port"
+  :type 'string
+  :group 'circe-format)
+
+(defcustom circe-format-server-whois-idle-with-signon "*** {whois-nick} is {idle-duration} idle (signon on {signon-date}, {signon-ago} ago)"
+  "Format for RPL_WHOISIDLE messages.
+
+The following format arguments are available:
+
+  whois-nick      - The nick this is about
+  idle-seconds    - The number of seconds this nick has been idle
+  idle-duration   - A textual description of the duration of the idle time
+  signon-time     - The time (in seconds since the epoch) when this user
+                    signed on
+  signon-date     - A date string describing this time
+  signon-ago      - A textual description of the duraction since signon"
+  :type 'string
+  :group 'circe-format)
+
+(defcustom circe-format-server-whois-idle "*** {whois-nick} is {idle-duration} idle"
+  "Format for RPL_WHOISIDLE messages.
+
+The following format arguments are available:
+
+  whois-nick      - The nick this is about
+  idle-seconds    - The number of seconds this nick has been idle
+  idle-duration   - A textual description of the duration of the idle time"
+  :type 'string
+  :group 'circe-format)
+
+(defcustom circe-format-server-topic-time "*** Topic set by {setter} on {topic-date}, {topic-ago} ago"
+  "Format for RPL_TOPICWHOTIME messages for the current channel.
+
+The following format arguments are available:
+
+  channel         - The channel the topic is for
+  setter          - The nick of the person who set the topic
+  setter-userhost - The user@host string of the person who set the topic
+  topic-time      - The time the topic was set, in seconds since the epoch
+  topic-date      - A date string describing this time
+  topic-ago       - A textual description of the duration since the topic
+                    was set"
+  :type 'string
+  :group 'circe-format)
+
+(defcustom circe-format-server-topic-time-for-channel "*** Topic for {channel} set by {setter} on {topic-date}, {topic-ago} ago"
+  "Format for RPL_TOPICWHOTIME messages for a channel we are not on.
+
+The following format arguments are available:
+
+  channel         - The channel the topic is for
+  setter          - The nick of the person who set the topic
+  setter-userhost - The user@host string of the person who set the topic
+  topic-time      - The time the topic was set, in seconds since the epoch
+  topic-date      - A date string describing this time
+  topic-ago       - A textual description of the duration since the topic
+                    was set"
+  :type 'string
+  :group 'circe-format)
+
+(defcustom circe-format-server-channel-creation-time "*** Channel {channel} created on {date}, {ago} ago"
+  "Format for RPL_CREATIONTIME messages for the current channel.
+
+The following format arguments are available:
+
+  channel  - The channel the topic is for
+  date     - A date string describing this time
+  ago      - A textual description of the duration since the channel
+             was created"
+  :type 'string
+  :group 'circe-format)
+
+(defcustom circe-format-server-ctcp-ping "*** CTCP PING request from {nick} ({userhost}) to {target}: {body} ({ago} ago)"
+  "Format for CTCP PING requests.
+
+The following format arguments are available:
+
+  nick      - The nick of the user who sent this PING request
+  userhost  - The user@host string of the user who sent this request
+  target    - The target of the message, usually us, but can be a channel
+  body      - The argument of the PING request, usually a number
+  ago       - A textual description of the duration since the request
+              was sent, if parseable"
+  :type 'string
+  :group 'circe-format)
+
+(defcustom circe-format-server-ctcp-ping-reply "*** CTCP PING reply from {nick} ({userhost}) to {target}: {ago} ago ({body})"
+  "Format for CTCP PING replies.
+
+The following format arguments are available:
+
+  nick      - The nick of the user who sent this PING request
+  userhost  - The user@host string of the user who sent this request
+  target    - The target of the message, usually us, but can be a channel
+  body      - The argument of the PING request, usually a number
+  ago       - A textual description of the duration since the request
+              was sent, if parseable"
+  :type 'string
+  :group 'circe-format)
+
+(defcustom circe-format-server-ctcp "*** CTCP {command} request from {nick} ({userhost}) to {target}: {body}"
+  "Format for CTCP requests.
+
+The following format arguments are available:
+
+  nick      - The nick of the user who sent this PING request
+  userhost  - The user@host string of the user who sent this request
+  target    - The target of the message, usually us, but can be a channel
+  command   - The CTCP command used
+  body      - The argument of the PING request, usually a number"
+  :type 'string
+  :group 'circe-format)
+
+(defcustom circe-format-server-netsplit "*** Netsplit: {split} (Use /WL to see who left)"
+  "Format for netsplit notifications.
+
+The following format arguments are available:
+
+  split   - The name of the split, usually describing the servers involved"
+  :type 'string
+  :group 'circe-format)
+
+(defcustom circe-format-server-netmerge "*** Netmerge: {split}, split {ago} ago (Use /WL to see who's still missing)"
+  "Format for netmerge notifications.
+
+The following format arguments are available:
+
+  split   - The name of the split, usually describing the servers involved
+  time    - The time when this split happened, in seconds
+  date    - A date string describing this time
+  ago     - A textual description of the duration since the split happened"
+  :type 'string
+  :group 'circe-format)
+
+(defcustom circe-format-server-join "*** Join: {nick} ({userinfo})"
+  "Format for join messages in a channel buffer.
+
+The following format arguments are available:
+
+  nick         - The nick of the user joining
+  userhost     - The user@host string for the user
+  accountname  - The account name, if the server supports this
+  realname     - The real name, if the server supports this
+  userinfo     - A combination of userhost, accountname, and realname
+  channel      - The channel this user is joining"
+  :type 'string
+  :group 'circe-format)
+
+(defcustom circe-format-server-join-in-channel "*** Join: {nick} ({userinfo}) joined {channel}"
+  "Format for join messages in query buffers of the joining user.
+
+The following format arguments are available:
+
+  nick         - The nick of the user joining
+  userhost     - The user@host string for the user
+  accountname  - The account name, if the server supports this
+  realname     - The real name, if the server supports this
+  userinfo     - A combination of userhost, accountname, and realname
+  channel      - The channel this user is joining"
+  :type 'string
+  :group 'circe-format)
+
+(defcustom circe-format-server-mode-change "*** Mode change: {change} on {target} by {setter} ({userhost})"
+  "Format for mode changes.
+
+The following format arguments are available:
+
+  setter       - The name of the split, usually describing the servers involved
+  userhost     - The user@host string for the user
+  target       - The target of this mode change
+  change       - The actual changed modes"
+  :type 'string
+  :group 'circe-format)
+
+(defcustom circe-format-server-nick-change-self "*** Nick change: You are now known as {new-nick}"
+  "Format for nick changes of the current user.
+
+The following format arguments are available:
+
+  old-nick - The old nick this change was from
+  new-nick - The new nick this change was to
+  userhost - The user@host string for the user"
+  :type 'string
+  :group 'circe-format)
+
+(defcustom circe-format-server-nick-change "*** Nick change: {old-nick} ({userhost}) is now known as {new-nick}"
+  "Format for nick changes of the current user.
+
+The following format arguments are available:
+
+  old-nick - The old nick this change was from
+  new-nick - The new nick this change was to
+  userhost - The user@host string for the user"
+  :type 'string
+  :group 'circe-format)
+
+(defcustom circe-format-server-nick-regain "*** Nick regain: {old-nick} ({userhost}) is now known as {new-nick}"
+  "Format for nick changes of the current user.
+
+The following format arguments are available:
+
+  old-nick - The old nick this change was from
+  new-nick - The new nick this change was to
+  userhost - The user@host string for the user"
+  :type 'string
+  :group 'circe-format)
+
+(defcustom circe-format-server-part "*** Part: {nick} ({userhost}) left {channel}: {reason}"
+  "Format for users parting a channel.
+
+The following format arguments are available:
+
+  nick     - The nick of the user who left
+  userhost - The user@host string for this user
+  channel  - The channel they left
+  reason   - The reason they gave for leaving"
+  :type 'string
+  :group 'circe-format)
+
+(defcustom circe-format-server-quit-channel "*** Quit: {nick} ({userhost}) left {channel}: {reason}"
+  "Format for users quitting from a channel.
+
+The following format arguments are available:
+
+  nick     - The nick of the user who left
+  userhost - The user@host string for this user
+  channel  - The channel they left
+  reason   - The reason they gave for leaving"
+  :type 'string
+  :group 'circe-format)
+
+(defcustom circe-format-server-quit "*** Quit: {nick} ({userhost}) left IRC: {reason}"
+  "Format for users quitting.
+
+The following format arguments are available:
+
+  nick     - The nick of the user who left
+  userhost - The user@host string for this user
+  reason   - The reason they gave for leaving"
+  :type 'string
+  :group 'circe-format)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; Private variables ;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defvar circe-source-url "https://github.com/jorgenschaefer/circe"
+  "URL to Circe's source repository")
+
+(defvar circe-host nil
+  "The name of the server we're currently connected to.")
+(make-variable-buffer-local 'circe-host)
+
+(defvar circe-port nil
+  "The port number or service name of the server.")
+(make-variable-buffer-local 'circe-host)
+
+(defvar circe-network nil
+  "The network name of the server we're currently connected to.")
+(make-variable-buffer-local 'circe-network)
+
+(defvar circe-ip-family nil
+  "The IP family in use.
+See `make-network-process' and :family for valid values.")
+(make-variable-buffer-local 'circe-ip-family)
+
+(defvar circe-nick nil
+  "Our current nick.")
+(make-variable-buffer-local 'circe-nick)
+
+(defvar circe-user nil
+  "The current user name.")
+(make-variable-buffer-local 'circe-user)
+
+(defvar circe-realname nil
+  "The current real name.")
+(make-variable-buffer-local 'circe-realname)
+
+(defvar circe-pass nil
+  "The password for the current server or a function to recall it.
+
+If a function is set it will be called with the value of `circe-host'.")
+(make-variable-buffer-local 'circe-pass)
+
+(defvar circe-sasl-username nil
+  "The username for SASL authentication.")
+(make-variable-buffer-local 'circe-sasl-username)
+
+(defvar circe-sasl-password nil
+  "The password for SASL authentication.
+
+If a function is set it will be called with the value of
+`circe-host'.")
+(make-variable-buffer-local 'circe-sasl-password)
+
+(defvar circe-use-tls nil
+  "If non-nil, use `open-tls-stream' to connect to the server.")
+(make-variable-buffer-local 'circe-use-tls)
+
+(defvar circe-server-process nil
+  "The process of the server connection.")
+(make-variable-buffer-local 'circe-server-process)
+
+(defvar circe-server-last-active-buffer nil
+  "The last active circe buffer.")
+(make-variable-buffer-local 'circe-server-last-active-buffer)
+
+(defvar circe-display-table nil
+  "A hash table mapping commands to their display functions.")
+
+(defvar circe-server-inhibit-auto-reconnect-p nil
+  "Non-nil when Circe should not reconnect.
+
+This can be set from commands to avoid reconnecting when the
+server disconnects.")
+(make-variable-buffer-local 'circe-server-inhibit-auto-reconnect-p)
+
+(defvar circe-chat-calling-server-buffer-and-target nil
+  "Internal variable to pass the server buffer and target to chat modes.")
+
+(defvar circe-chat-target nil
+  "The current target for the buffer.
+This is either a channel or a nick name.")
+(make-variable-buffer-local 'circe-chat-target)
+
+(defvar circe-nick-syntax-table
+  (let ((table (make-syntax-table text-mode-syntax-table))
+        (special (string-to-list "[]\`_^{}|-")))
+    (dolist (char special)
+      (modify-syntax-entry char "w" table))
+    table)
+  "Syntax table to treat nicks as words.
+This is not entirely accurate, as exact chars constituting a nick
+can vary between networks.")
+
+(defvar circe-nickserv-mask nil
+  "The regular expression to identify the nickserv on this network.
+
+Matched against nick!user@host.")
+(make-variable-buffer-local 'circe-nickserv-mask)
+
+(defvar circe-nickserv-identify-challenge nil
+  "A regular expression matching the nickserv challenge to identify.")
+(make-variable-buffer-local 'circe-nickserv-identify-challenge)
+
+(defvar circe-nickserv-identify-command nil
+  "The IRC command to send to identify with nickserv.
+
+This must be a full IRC command. It accepts the following
+formatting options:
+
+ {nick} - The nick to identify as
+ {password} - The configured nickserv password")
+(make-variable-buffer-local 'circe-nickserv-identify-command)
+
+(defvar circe-nickserv-identify-confirmation nil
+  "A regular expression matching a confirmation of authentication.")
+(make-variable-buffer-local 'circe-nickserv-identify-confirmation)
+
+(defvar circe-nickserv-ghost-command nil
+  "The IRC command to send to regain/ghost your nick.
+
+This must be a full IRC command. It accepts the following
+formatting options:
+
+  {nick} - The nick to ghost
+  {password} - The configured nickserv password")
+(make-variable-buffer-local 'circe-nickserv-ghost-command)
+
+(defvar circe-nickserv-ghost-confirmation nil
+  "A regular expression matching a confirmation for the GHOST command.
+
+This is used to know when we can set our nick to the regained one
+Leave nil if regaining automatically sets your nick")
+(make-variable-buffer-local 'circe-nickserv-ghost-confirmation)
+
+(defvar circe-nickserv-nick nil
+  "The nick we are registered with for nickserv.
+
+Do not set this variable directly. Use `circe-network-options' or
+pass an argument to the `circe' function for this.")
+(make-variable-buffer-local 'circe-nickserv-nick)
+
+(defvar circe-nickserv-password nil
+  "The password we use for nickserv on this network.
+
+Can be either a string or a unary function of the nick returning
+a string.
+
+Do not set this variable directly. Use `circe-network-options' or
+pass an argument to the `circe' function for this.")
+(make-variable-buffer-local 'circe-nickserv-password)
+
+(defvar circe-channels nil
+  "The default channels to join on this server.
+
+Don't set this variable by hand, use `circe-network-options'.
+
+The value should be a list of channels to join, with optional
+keywords to configure the behavior of the following channels.
+
+Best explained in an example:
+
+\(\"#emacs\" :after-auth \"#channel\" \"#channel2\")
+
+Possible keyword options are:
+
+:immediate - Immediately after registering on the server
+:after-auth - After nickserv authentication succeeded
+:after-cloak - After we have acquired a cloaked host name
+:after-nick - After we regained our preferred nick, or after
+              nickserv authentication if we don't need to regain
+              it. See `circe-nickserv-ghost-style'.
+
+The default is set in `circe-server-auto-join-default-type'.
+
+A keyword in the first position of the channels list overrides
+`circe-server-auto-join-default-type' for re-joining manually
+joined channels.")
+(make-variable-buffer-local 'circe-channels)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;; Server Buffer Management ;;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; Every Circe buffer has an associated server buffer (which might be
+;; the buffer itself). Circe buffers should set the
+;; `circe-server-buffer' variable to the associated server buffer.
+
+(defun circe-server-buffer ()
+  "Return the server buffer for the current buffer."
+  (let ((buf (if (eq major-mode 'circe-server-mode)
+                 (current-buffer)
+               circe-server-buffer)))
+    (cond
+     ((not buf)
+      (error "Not in a Circe buffer"))
+     ((not (buffer-live-p buf))
+      (error "The server buffer died, functionality is limited"))
+     (t
+      buf))))
+
+(defmacro with-circe-server-buffer (&rest body)
+  "Run BODY with the current buffer being the current server buffer."
+  (declare (indent 0))
+  `(with-current-buffer (circe-server-buffer)
+     ,@body))
+
+;;;;;;;;;;;;;;;;;;;;;;;
+;;; Editor Commands ;;;
+;;;;;;;;;;;;;;;;;;;;;;;
+
+;;;###autoload
+(defun circe-version ()
+  "Display Circe's version."
+  (interactive)
+  (message "Circe %s" (circe--version)))
+
+(defun circe--version ()
+  "Return Circe's version"
+  (let ((circe-git-version (circe--git-version)))
+    (if circe-git-version
+        (format "%s-%s" circe-version circe-git-version)
+      (format "%s" circe-version))))
+
+(defun circe--git-version ()
+  (let ((current-file-path (or load-file-name buffer-file-name)))
+    (when (or (not current-file-path)
+              (not (equal (file-name-nondirectory current-file-path)
+                          "circe.el")))
+      (setq current-file-path (locate-library "circe.el")))
+    (let ((vcs-path (locate-dominating-file current-file-path ".git")))
+      (when vcs-path
+        (let ((default-directory vcs-path))
+          ;; chop off the trailing newline
+          (substring (shell-command-to-string "git rev-parse --short HEAD")
+                     0 -1))))))
+
+;;;###autoload
+(defun circe (network-or-server &rest server-options)
+  "Connect to IRC.
+
+Connect to the given network specified by NETWORK-OR-SERVER.
+
+When this function is called, it collects options from the
+SERVER-OPTIONS argument, the user variable
+`circe-network-options', and the defaults found in
+`circe-network-defaults', in this order.
+
+If NETWORK-OR-SERVER is not found in any of these variables, the
+argument is assumed to be the host name for the server, and all
+relevant settings must be passed via SERVER-OPTIONS.
+
+All SERVER-OPTIONS are treated as variables by getting the string
+\"circe-\" prepended to their name. This variable is then set
+locally in the server buffer.
+
+See `circe-network-options' for a list of common options."
+  (interactive (circe--read-network-and-options))
+  (let* ((options (circe--server-get-network-options network-or-server
+                                                     server-options))
+         (buffer (circe--server-generate-buffer options)))
+    (with-current-buffer buffer
+      (circe-server-mode)
+      (circe--server-set-variables options)
+      (circe-reconnect))
+    (pop-to-buffer-same-window buffer)))
+
+(defun circe--read-network-and-options ()
+  "Read a host or network name with completion.
+
+If it's not a network, also read some extra options.
+
+This uses `circe-network-defaults' and `circe-network-options' for
+network names."
+  (let ((default-network (if (null circe-network-options)
+                             (caar circe-network-defaults)
+                           (caar circe-network-options)))
+        (networks nil)
+        (completion-ignore-case t)
+        network-or-host)
+    (dolist (network-spec (append circe-network-options
+                                  circe-network-defaults))
+      (when (not (member (car network-spec) networks))
+        (push (car network-spec) networks)))
+    (setq networks (sort networks 'string-lessp))
+    (setq network-or-host (completing-read "Network or host: "
+                                           networks
+                                           nil nil nil nil
+                                           default-network))
+    (dolist (network-name networks)
+      (when (equal (downcase network-or-host)
+                   (downcase network-name))
+        (setq network-or-host network-name)))
+    (if (member network-or-host networks)
+        (list network-or-host)
+      (list network-or-host
+            :host network-or-host
+            :port (read-number "Port: " 6667)))))
+
+(defun circe--server-get-network-options (network server-options)
+  "Combine server and network options with network defaults.
+
+See `circe-network-options' and `circe-network-defaults'."
+  (let ((options (mapcar 'circe--translate-option-names
+                         (append server-options
+                                 (cdr (assoc network circe-network-options))
+                                 (cdr (assoc network circe-network-defaults))
+                                 (list :network network)))))
+    (when (not (plist-get options :host))
+      (plist-put options :host network))
+    (let ((port (plist-get options :port))
+          (use-tls (plist-get options :use-tls)))
+      (when (consp port)
+        (if use-tls
+            (plist-put options :port (cdr port))
+          (plist-put options :port (car port)))))
+    (dolist (required-option '(:host :port))
+      (when (not (plist-get options required-option))
+        (error (format "Network option %s not specified" required-option))))
+    options))
+
+(defun circe--translate-option-names (option)
+  "Translate option names to make them unique.
+
+Some options have multiple names, mainly for historical reasons.
+Unify them here."
+  (cond
+   ((eq option :service) :port)
+   ((eq option :tls) :use-tls)
+   ((eq option :family) :ip-family)
+   (t option)))
+
+(defun circe--server-generate-buffer (options)
+  "Return the server buffer for the connection described in OPTIONS."
+  (let* ((network (plist-get options :network))
+         (host (plist-get options :host))
+         (port (plist-get options :port))
+         (buffer-name (lui-format (or (plist-get options :server-buffer-name)
+                                      circe-server-buffer-name)
+                                  :network network
+                                  :host host
+                                  :port port
+                                  :service port)))
+    (generate-new-buffer buffer-name)))
+
+(defun circe--server-set-variables (options)
+  "Set buffer-local variables described in OPTIONS.
+
+OPTIONS is a plist as passed to `circe'. All options therein are
+set as buffer-local variables. Only the first occurrence of each
+variable is set."
+  (setq circe-nick circe-default-nick
+        circe-user circe-default-user
+        circe-realname circe-default-realname
+        circe-ip-family circe-default-ip-family)
+  (let ((done nil)
+        (todo options))
+    (while todo
+      (when (not (memq (car todo) done))
+        (push (car todo) done)
+        (let ((var (intern (format "circe-%s"
+                                   (substring (symbol-name (car todo)) 1))))
+              (val (cadr todo)))
+          (if (boundp var)
+              (set (make-local-variable var) val)
+            (warn "Unknown option %s, ignored" (car todo)))))
+      (setq todo (cddr todo)))))
+
+(defvar circe-server-reconnect-attempts 0
+  "The number of reconnect attempts that Circe has done so far.
+See `circe-server-max-reconnect-attempts'.")
+(make-variable-buffer-local 'circe-server-reconnect-attempts)
+
+(defun circe-reconnect ()
+  "Reconnect the current server."
+  (interactive)
+  (with-circe-server-buffer
+    (when (or (called-interactively-p 'any)
+              (circe--reconnect-p))
+      (setq circe-server-inhibit-auto-reconnect-p t
+            circe-server-reconnect-attempts (+ circe-server-reconnect-attempts
+                                               1))
+      (unwind-protect
+          (circe-reconnect--internal)
+        (setq circe-server-inhibit-auto-reconnect-p nil)))))
+
+(defun circe--reconnect-p ()
+  (cond
+   (circe-server-inhibit-auto-reconnect-p
+    nil)
+   ((not circe-server-max-reconnect-attempts)
+    t)
+   ((<= circe-server-reconnect-attempts
+        circe-server-max-reconnect-attempts)
+    t)
+   (t
+    nil)))
+
+(defun circe-reconnect--internal ()
+  "The internal function called for reconnecting unconditionally.
+
+Do not use this directly, use `circe-reconnect'"
+  (when (and circe-server-process
+             (process-live-p circe-server-process))
+    (delete-process circe-server-process))
+  (circe-display-server-message "Connecting...")
+  (dolist (buf (circe-server-chat-buffers))
+    (with-current-buffer buf
+      (circe-display-server-message "Connecting...")))
+  (setq circe-server-process
+        (irc-connect
+         :host circe-host
+         :service circe-port
+         :tls circe-use-tls
+         :ip-family circe-ip-family
+         :handler-table (circe-irc-handler-table)
+         :server-buffer (current-buffer)
+         :nick circe-nick
+         :nick-alternatives (list (circe--nick-next circe-nick)
+                                  (circe--nick-next
+                                   (circe--nick-next circe-nick)))
+         :user circe-user
+         :mode 8
+         :realname circe-realname
+         :pass (if (functionp circe-pass)
+                   (funcall circe-pass circe-host)
+                 circe-pass)
+         :cap-req (append (when (and circe-sasl-username
+                                     circe-sasl-password)
+                            '("sasl"))
+                          '("extended-join"))
+         :nickserv-nick (or circe-nickserv-nick
+                            circe-nick)
+         :nickserv-password (if (functionp circe-nickserv-password)
+                                (funcall circe-nickserv-password circe-host)
+                              circe-nickserv-password)
+         :nickserv-mask circe-nickserv-mask
+         :nickserv-identify-challenge circe-nickserv-identify-challenge
+         :nickserv-identify-command circe-nickserv-identify-command
+         :nickserv-identify-confirmation
+         circe-nickserv-identify-confirmation
+         :nickserv-ghost-command circe-nickserv-ghost-command
+         :nickserv-ghost-confirmation circe-nickserv-ghost-confirmation
+         :sasl-username circe-sasl-username
+         :sasl-password (if (functionp circe-sasl-password)
+                            (funcall circe-sasl-password
+                                     circe-host)
+                          circe-sasl-password)
+         :ctcp-version (format "Circe: Client for IRC in Emacs, version %s"
+                               circe-version)
+         :ctcp-source circe-source-url
+         :ctcp-clientinfo "CLIENTINFO PING SOURCE TIME VERSION"
+         :auto-join-after-registration
+         (append (circe--auto-join-channel-buffers)
+                 (circe--auto-join-list :immediate))
+         :auto-join-after-host-hiding
+         (circe--auto-join-list :after-cloak)
+         :auto-join-after-nick-acquisition
+         (circe--auto-join-list :after-nick)
+         :auto-join-after-nickserv-identification
+         (circe--auto-join-list :after-auth)
+         :auto-join-after-sasl-login
+         (circe--auto-join-list :after-auth))))
+
+(defun circe-reconnect-all ()
+  "Reconnect all Circe connections."
+  (interactive)
+  (dolist (buf (circe-server-buffers))
+    (with-current-buffer buf
+      (if (called-interactively-p 'any)
+          (call-interactively 'circe-reconnect)
+        (circe-reconnect)))))
+
+(defun circe--auto-join-list (type)
+  "Return the list of channels to join for type TYPE."
+  (let ((result nil)
+        (current-type circe-server-auto-join-default-type))
+    (dolist (channel circe-channels)
+      (cond
+       ((keywordp channel)
+        (setq current-type channel))
+       ((eq current-type type)
+        (push channel result))))
+    (nreverse result)))
+
+(defun circe--auto-join-channel-buffers ()
+  "Return a list of channels to join based on channel buffers.
+
+This includes all channel buffers of the current server, but
+excludes and channel that is already listed in
+`circe-channels'."
+  (let ((channels nil))
+    (dolist (buf (circe-server-chat-buffers))
+      (let ((name (with-current-buffer buf
+                    (when (derived-mode-p 'circe-channel-mode)
+                      circe-chat-target))))
+        (when (and name
+                   (not (member name circe-channels)))
+          (push name channels))))
+    channels))
+
+;;;;;;;;;;;;;;;;;
+;;; Base Mode ;;;
+;;;;;;;;;;;;;;;;;
+
+(defvar circe-mode-hook nil
+  "Hook run for any Circe mode.")
+
+(defvar circe-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "C-c C-j") 'circe-command-JOIN)
+    (define-key map (kbd "C-c C-r") 'circe-reconnect)
+    map)
+  "The base keymap for all Circe modes (server, channel, query)")
+
+(defvar circe-server-buffer nil
+  "The buffer of the server associated with the current chat buffer.")
+(make-variable-buffer-local 'circe-server-buffer)
+
+(define-derived-mode circe-mode lui-mode "Circe"
+  "Base mode for all Circe buffers.
+
+A buffer should never be in this mode directly, but rather in
+modes that derive from this.
+
+The mode inheritance hierarchy looks like this:
+
+lui-mode
+`-circe-mode
+  `-circe-server-mode
+  `-circe-chat-mode
+    `-circe-channel-mode
+    `-circe-query-mode"
+  (add-hook 'lui-pre-output-hook 'lui-irc-colors
+            t t)
+  (add-hook 'lui-pre-output-hook 'circe--output-highlight-nick
+            t t)
+  (add-hook 'completion-at-point-functions 'circe--completion-at-point
+            nil t)
+  (lui-set-prompt circe-prompt-string)
+  (goto-char (point-max))
+  (setq lui-input-function 'circe--input
+        default-directory (expand-file-name circe-default-directory)
+        circe-server-last-active-buffer (current-buffer)
+        flyspell-generic-check-word-p 'circe--flyspell-check-word-p)
+  (when circe-use-cycle-completion
+    (set (make-local-variable 'completion-cycle-threshold)
+         t))
+  ;; Tab completion should be case-insensitive
+  (set (make-local-variable 'completion-ignore-case)
+       t)
+  (set (make-local-variable 'tracking-faces-priorities)
+       circe-track-faces-priorities))
+
+;;;;;;;;;;;;;;;;;;;;
+;;;; Displaying ;;;;
+;;;;;;;;;;;;;;;;;;;;
+
+(defun circe-display (format &rest keywords)
+  "Display FORMAT formatted with KEYWORDS in the current Circe buffer.
+See `lui-format' for a description of the format.
+
+If FORMAT contains the word server, the resulting string receives
+a `circe-server-face'. If FORMAT contains the word self, the
+whole string receives a `circe-my-message-face'. If FORMAT is in
+`circe-format-not-tracked', a message of this type is never
+tracked by Lui.
+
+Keywords with the name :nick receive a `circe-originator-face'.
+
+It is always possible to use the mynick or target formats."
+  (when (not (circe--display-ignored-p format keywords))
+    (let* ((name (symbol-name format))
+           (face (cond
+                  ((string-match "\\<server\\>" name)
+                   'circe-server-face)
+                  ((string-match "\\<self\\>" name)
+                   'circe-my-message-face)))
+           (keywords (append `(:mynick ,(circe-nick)
+                                       :chattarget ,circe-chat-target)
+                             (circe--display-add-nick-property
+                              (if (and (not (null keywords))
+                                       (null (cdr keywords)))
+                                  (car keywords)
+                                keywords))))
+           (text (lui-format format keywords)))
+      (when (circe--display-fool-p format keywords)
+        (add-face-text-property 0 (length text)
+                                'circe-fool-face t text)
+        (put-text-property 0 (length text)
+                           'lui-fool t
+                           text))
+      (when face
+        (add-face-text-property 0 (length text)
+                                face t text))
+      (lui-insert text
+                  (memq format circe-format-not-tracked)))))
+
+(defun circe-display-server-message (message)
+  "Display MESSAGE as a server message."
+  (circe-display 'circe-format-server-message
+                 :body message))
+
+(defun circe--display-add-nick-property (keywords)
+  "Add a face to the value of the :nick property in KEYWORDS."
+  (let ((keyword nil))
+    (mapcar (lambda (entry)
+              (cond
+               ((or (eq keyword :nick)
+                    (eq keyword 'nick))
+                (setq keyword nil)
+                (propertize entry 'face 'circe-originator-face))
+               (t
+                (setq keyword entry)
+                entry)))
+            keywords)))
+
+(defun circe--display-ignored-p (_format keywords)
+  (let ((nick (plist-get keywords :nick))
+        (userhost (plist-get keywords :userhost))
+        (body (plist-get keywords :body)))
+    (circe--ignored-p nick userhost body)))
+
+(defun circe--display-fool-p (_format keywords)
+  (let ((nick (plist-get keywords :nick))
+        (userhost (plist-get keywords :userhost))
+        (body (plist-get keywords :body)))
+    (circe--fool-p nick userhost body)))
+
+(defun circe--ignored-p (nick userhost body)
+  "True if this user or message is being ignored.
+
+See `circe-ignore-functions' and `circe-ignore-list'.
+
+NICK, USER and HOST should be the sender of a the command
+COMMAND, which had the arguments ARGS."
+  (or (run-hook-with-args-until-success 'circe-ignore-functions
+                                        nick userhost body)
+      (circe--ignore-matches-p nick userhost body circe-ignore-list)))
+
+(defun circe--fool-p (nick userhost body)
+  "True if this user or message is a fool.
+
+See `circe-fool-list'.
+
+NICK, USER and HOST should be the sender of a the command
+COMMAND, which had the arguments ARGS."
+  (circe--ignore-matches-p nick userhost body circe-fool-list))
+
+(defun circe--ignore-matches-p (nick userhost body patterns)
+  "Check if a given command does match an ignore pattern.
+
+A pattern matches if it either matches the user NICK!USER@HOST,
+or if it matches the first word in BODY.
+
+PATTERNS should be the list of regular expressions."
+  (let ((string (format "%s!%s" nick userhost))
+        (target (when (and body
+                           (string-match "^\\([^ ]*\\)[:,]" body))
+                  (match-string 1 body))))
+    (catch 'return
+      (dolist (regex patterns)
+        (when (string-match regex string)
+          (throw 'return t))
+        (when (and (stringp target)
+                   (string-match regex target))
+          (throw 'return t)))
+      nil)))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;; Nick Highlighting ;;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun circe--output-highlight-nick ()
+  "Highlight the nick of the user in the buffer.
+
+This is used in `lui-pre-output-hook'."
+  (goto-char (or (text-property-any (point-min) (point-max)
+                                    'lui-format-argument 'body)
+                 (point-min)))
+  (when (or (not circe-inhibit-nick-highlight-function)
+            (not (funcall circe-inhibit-nick-highlight-function)))
+    (let* ((nick (circe-nick))
+           (nicks (append (and nick (list nick))
+                          circe-extra-nicks)))
+      (when nicks
+        ;; Can't use \<...\> because that won't match for \<forcer-\> We
+        ;; might eventually use \_< ... \_> if we define symbols to be
+        ;; nicks \\= is necessary, because it might be found right where we
+        ;; are, and that might not be the beginning of a line... (We start
+        ;; searching from the beginning of the body)
+        (let ((nick-regex (concat "\\(?:^\\|\\W\\|\\=\\)"
+                                  "\\(" (regexp-opt nicks) "\\)"
+                                  "\\(?:$\\|\\W\\)")))
+          (cond
+           ((eq circe-highlight-nick-type 'sender)
+            (if (text-property-any (point-min)
+                                   (point-max)
+                                   'face 'circe-originator-face)
+                (when (re-search-forward nick-regex nil t)
+                  (circe--extend-text-having-face
+                   (point-min) (point-max)
+                   'circe-originator-face
+                   'circe-highlight-nick-face))
+              (let ((circe-highlight-nick-type 'occurrence))
+                (circe--output-highlight-nick))))
+           ((eq circe-highlight-nick-type 'occurrence)
+            (while (re-search-forward nick-regex nil t)
+              (add-face-text-property (match-beginning 1)
+                                      (match-end 1)
+                                      'circe-highlight-nick-face)))
+           ((eq circe-highlight-nick-type 'message)
+            (when (re-search-forward nick-regex nil t)
+              (let* ((start (text-property-any (point-min)
+                                               (point-max)
+                                               'lui-format-argument 'body))
+                     (end (when start
+                            (next-single-property-change start
+                                                         'lui-format-argument))))
+                (when (and start end)
+                  (add-face-text-property start end
+                                          'circe-highlight-nick-face)))))
+           ((eq circe-highlight-nick-type 'all)
+            (when (re-search-forward nick-regex nil t)
+              (add-face-text-property (point-min) (point-max)
+                                      'circe-highlight-nick-face)))))))))
+
+(defun circe--extend-text-having-face (from to existing new)
+  "Extend property values.
+
+In the text between FROM and TO, find any text that has its face
+property set to EXISTING, and prepend NEW to the value of its
+face property, when necessary by turning it into a list."
+  (let ((beg (text-property-any from to 'face existing)))
+    (while beg
+      (let ((end (next-single-property-change beg 'face)))
+        (add-face-text-property beg end new)
+        (setq beg (text-property-any end to 'face existing))))))
+
+;;;;;;;;;;;;;;;
+;;;; Input ;;;;
+;;;;;;;;;;;;;;;
+
+(defun circe--input (str)
+  "Process STR as input.
+
+This detects commands and interprets them, or sends the input
+using the /SAY command."
+  (set-text-properties 0 (length str) nil str)
+  (cond
+   ((string= str "")
+    nil)
+   ;; Ignore commands in multiline input
+   ((and (not (string-match "\n" str))
+         (string-match "\\`/\\([^/ ][^ ]*\\|[^/ ]*\\) ?\\([^\n]*\\)\\'" str))
+    (let* ((command (match-string 1 str))
+           (args (match-string 2 str))
+           (handler (intern-soft (format "circe-command-%s"
+                                         (upcase command)))))
+      (cond
+       ((string= command "")
+        (circe-command-SAY args))
+       (handler
+        (funcall handler args))
+       (circe-server-send-unknown-command-p
+        (irc-send-raw (circe-server-process)
+                      (format "%s %s"
+                              (upcase command)
+                              args)))
+       (t
+        (circe-display-server-message (format "Unknown command: %s"
+                                      command))))))
+   (t
+    (mapc #'circe-command-SAY
+          (circe--list-drop-right (split-string str "\n")
+                                  "^ *$")))))
+
+;;;;;;;;;;;;;;;;;;
+;;;; Flyspell ;;;;
+;;;;;;;;;;;;;;;;;;
+
+(defun circe--flyspell-check-word-p ()
+  "Return a true value if flyspell check the word before point.
+
+This is a suitable value for `flyspell-generic-check-word-p'. It
+will also call `lui-flyspell-check-word-p'."
+  (cond
+   ((not (lui-flyspell-check-word-p))
+    nil)
+   ((circe-channel-user-p (circe--flyspell-nick-before-point))
+    nil)
+   (t
+    t)))
+
+(defun circe--flyspell-nick-before-point ()
+  "Return the IRC nick before point"
+  (with-syntax-table circe-nick-syntax-table
+    (let (beg end)
+      (save-excursion
+        (forward-word -1)
+        (setq beg (point))
+        (forward-word 1)
+        (setq end (point)))
+      (buffer-substring beg end))))
+
+;;;;;;;;;;;;;;;;;;;;
+;;;; Completion ;;;;
+;;;;;;;;;;;;;;;;;;;;
+
+(defun circe--completion-at-point ()
+  "Return a list of possible completions for the current buffer.
+
+This is used in `completion-at-point-functions'."
+  ;; Use markers so they move when input happens
+  (let ((start (make-marker))
+        (end (make-marker)))
+    (set-marker end (point))
+    (set-marker start
+                (save-excursion
+                  (when (or (looking-back (regexp-quote
+                                           circe-completion-suffix)
+                                          (length circe-completion-suffix))
+                            (looking-back " " 1))
+                    (goto-char (match-beginning 0)))
+                  (cond
+                   ((<= (point) lui-input-marker)
+                    lui-input-marker)
+                   ((re-search-backward "\\s-" lui-input-marker t)
+                    (1+ (point)))
+                   (t
+                    lui-input-marker))))
+    (list start end 'circe--completion-table)))
+
+(defun circe--completion-table (string pred action)
+  "Completion table to use for Circe buffers.
+
+See `minibuffer-completion-table' for details."
+  (cond
+   ;; Best completion of STRING
+   ((eq action nil)
+    (try-completion string
+                    (circe--completion-candidates
+                     (if (= (- (point) (length string))
+                            lui-input-marker)
+                         circe-completion-suffix
+                       " "))
+                    pred))
+   ;; A list of possible completions of STRING
+   ((eq action t)
+    (all-completions string
+                     (circe--completion-candidates
+                      (if (= (- (point) (length string))
+                             lui-input-marker)
+                          circe-completion-suffix
+                        " "))
+                     pred))
+   ;; t iff STRING is a valid completion as it stands
+   ((eq action 'lambda)
+    (test-completion string
+                     (circe--completion-candidates
+                      (if (= (- (point) (length string))
+                             lui-input-marker)
+                          circe-completion-suffix
+                        " "))
+                     pred))
+   ;; Boundaries
+   ((eq (car-safe action) 'boundaries)
+    `(boundaries 0 . ,(length (cdr action))))
+   ;; Metadata
+   ((eq action 'metadata)
+    '(metadata (cycle-sort-function . circe--completion-sort)))))
+
+(defun circe--completion-clean-nick (string)
+  (with-temp-buffer
+    (insert string)
+    (goto-char (point-max))
+    (when (or (looking-back circe-completion-suffix nil)
+              (looking-back " " nil))
+      (replace-match ""))
+    (buffer-string)))
+
+(defun circe--completion-sort (collection)
+  "Sort the COLLECTION by channel activity for nicks."
+  (let* ((proc (circe-server-process))
+         (channel (when (and circe-chat-target proc)
+                    (irc-connection-channel proc circe-chat-target)))
+         (decorated (mapcar (lambda (entry)
+                              (let* ((nick (circe--completion-clean-nick
+                                            entry))
+                                     (user (when channel
+                                             (irc-channel-user channel nick))))
+                                (list (when user
+                                        (irc-user-last-activity-time user))
+                                      (length entry)
+                                      entry)))
+                            collection))
+         (sorted (sort decorated
+                       (lambda (a b)
+                         (cond
+                          ((and (car a)
+                                (car b))
+                           (> (car a)
+                              (car b)))
+                          ((and (not (car a))
+                                (not (car b)))
+                           (< (cadr a)
+                              (cadr b)))
+                          ((car a)
+                           t)
+                          (t
+                           nil))))))
+    (mapcar (lambda (entry)
+              (nth 2 entry))
+            sorted)))
+
+;; FIXME: I do not know why this is here.
+(defvar circe--completion-old-completion-all-sorted-completions nil
+  "Variable to know if we can return a cached result.")
+(make-variable-buffer-local
+ 'circe--completion-old-completion-all-sorted-completions)
+(defvar circe--completion-cache nil
+  "The results we can cache.")
+(make-variable-buffer-local 'circe--completion-cache)
+
+(defun circe--completion-candidates (nick-suffix)
+  (if (and circe--completion-old-completion-all-sorted-completions
+           (eq completion-all-sorted-completions
+               circe--completion-old-completion-all-sorted-completions))
+      circe--completion-cache
+    (let ((completions (append (circe--commands-list)
+                               (mapcar (lambda (buf)
+                                         (with-current-buffer buf
+                                           circe-chat-target))
+                                       (circe-server-channel-buffers)))))
+      (cond
+       ;; In a server buffer, complete all nicks in all channels
+       ((eq major-mode 'circe-server-mode)
+        (dolist (buf (circe-server-channel-buffers))
+          (with-current-buffer buf
+            (dolist (nick (circe-channel-nicks))
+              (setq completions (cons (concat nick nick-suffix)
+                                      completions))))))
+       ;; In a channel buffer, only complete nicks in this channel
+       ((eq major-mode 'circe-channel-mode)
+        (setq completions (append (delete (concat (circe-nick)
+                                                  nick-suffix)
+                                          (mapcar (lambda (nick)
+                                                    (concat nick nick-suffix))
+                                                  (circe-channel-nicks)))
+                                  completions)))
+       ;; In a query buffer, only complete this query partner
+       ((eq major-mode 'circe-query-mode)
+        (setq completions (cons (concat circe-chat-target nick-suffix)
+                                completions)))
+       ;; Else, we're doing something wrong
+       (t
+        (error "`circe-possible-completions' called outside of Circe")))
+      (setq circe--completion-old-completion-all-sorted-completions
+            completion-all-sorted-completions
+            circe--completion-cache completions)
+      completions)))
+
+(defun circe--commands-list ()
+  "Return a list of possible Circe commands."
+  (mapcar (lambda (symbol)
+            (let ((str (symbol-name symbol)))
+              (if (string-match "^circe-command-\\(.*\\)" str)
+                  (concat "/" (match-string 1 str) " ")
+                str)))
+          (apropos-internal "^circe-command-")))
+
+;;;;;;;;;;;;;;;;;;;
+;;; Server Mode ;;;
+;;;;;;;;;;;;;;;;;;;
+
+(defvar circe-server-mode-hook nil
+  "Hook run when a new Circe server buffer is created.")
+
+(defvar circe-server-mode-map (make-sparse-keymap)
+  "The key map for server mode buffers.")
+
+(define-derived-mode circe-server-mode circe-mode "Circe Server"
+  "The mode for circe server buffers.
+
+This buffer represents a server connection. When you kill it, the
+server connection is closed. This will make all associated
+buffers unusable. Be sure to use \\[circe-reconnect] if you want
+to reconnect to the server.
+
+\\{circe-server-mode-map}"
+  (add-hook 'kill-buffer-hook 'circe-server-killed nil t))
+
+(defun circe-server-killed ()
+  "Run when the server buffer got killed.
+
+This will IRC, and ask the user whether to kill all of the
+server's chat buffers."
+  (when circe-server-killed-confirmation
+    (when (not (y-or-n-p
+                (if (eq circe-server-killed-confirmation 'ask-and-kill-all)
+                    "Really kill all buffers of this server? (if not, try `circe-reconnect') "
+                  "Really kill the IRC connection? (if not, try `circe-reconnect') ")))
+      (error "Buffer not killed as per user request")))
+  (setq circe-server-inhibit-auto-reconnect-p t)
+  (ignore-errors
+    (irc-send-QUIT circe-server-process circe-default-quit-message))
+  (ignore-errors
+    (delete-process circe-server-process))
+  (when (or (eq circe-server-killed-confirmation 'ask-and-kill-all)
+            (eq circe-server-killed-confirmation 'kill-all))
+    (dolist (buf (circe-server-chat-buffers))
+      (let ((circe-channel-killed-confirmation nil))
+        (kill-buffer buf)))))
+
+(defun circe-server-buffers ()
+  "Return a list of all server buffers in this Emacs instance."
+  (let ((result nil))
+    (dolist (buf (buffer-list))
+      (with-current-buffer buf
+        (when (eq major-mode 'circe-server-mode)
+          (setq result (cons buf result)))))
+    (nreverse result)))
+
+(defun circe-server-process ()
+  "Return the current server process."
+  (with-circe-server-buffer
+    circe-server-process))
+
+(defun circe-server-my-nick-p (nick)
+  "Return non-nil when NICK is our current nick."
+  (let ((proc (circe-server-process)))
+    (when proc
+      (irc-current-nick-p proc nick))))
+
+(defun circe-nick ()
+  "Return our current nick."
+  (let ((proc (circe-server-process)))
+    (when proc
+      (irc-current-nick proc))))
+
+(defun circe-server-last-active-buffer ()
+  "Return the last active buffer of this server."
+  (with-circe-server-buffer
+    (if (and circe-server-last-active-buffer
+             (bufferp circe-server-last-active-buffer)
+             (buffer-live-p circe-server-last-active-buffer))
+        circe-server-last-active-buffer
+      (current-buffer))))
+
+;; There really ought to be a hook for this
+(defadvice select-window (after circe-server-track-select-window
+                                (window &optional norecord))
+  "Remember the current buffer as the last active buffer.
+This is used by Circe to know where to put spurious messages."
+  (with-current-buffer (window-buffer window)
+    (when (derived-mode-p 'circe-mode)
+      (let ((buf (current-buffer)))
+        (ignore-errors
+          (with-circe-server-buffer
+            (setq circe-server-last-active-buffer buf)))))))
+(ad-activate 'select-window)
+
+(defun circe-reduce-lurker-spam ()
+  "Return the value of `circe-reduce-lurker-spam'.
+
+This uses a buffer-local value first, then the one in the server
+buffer.
+
+Use this instead of accessing the variable directly to enable
+setting the variable through network options."
+  (if (local-variable-p 'circe-reduce-lurker-spam)
+      circe-reduce-lurker-spam
+    (with-circe-server-buffer
+      circe-reduce-lurker-spam)))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;; Chat Buffer Management ;;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; Server buffers keep track of associated chat buffers. This enables
+;; us to not rely on buffer names staying the same, as well as keeping
+;; buffers from different servers and even server connections apart
+;; cleanly.
+
+(defvar circe-server-chat-buffer-table nil
+  "A hash table of chat buffers associated with this server.")
+(make-variable-buffer-local 'circe-server-chat-buffer-table)
+
+(defun circe-server-get-chat-buffer (target)
+  "Return the chat buffer addressing TARGET, or nil if none."
+  (with-circe-server-buffer
+    (when circe-server-chat-buffer-table
+      (let* ((target-name (irc-isupport--case-fold (circe-server-process)
+                                                   target))
+             (buf (gethash target-name circe-server-chat-buffer-table)))
+        (if (buffer-live-p buf)
+            buf
+          (remhash target-name circe-server-chat-buffer-table)
+          nil)))))
+
+(defun circe-server-create-chat-buffer (target chat-mode)
+  "Return a new buffer addressing TARGET in CHAT-MODE."
+  (with-circe-server-buffer
+    (let* ((target-name (irc-isupport--case-fold (circe-server-process)
+                                                 target))
+           (chat-buffer (generate-new-buffer target))
+           (server-buffer (current-buffer))
+           (circe-chat-calling-server-buffer-and-target (cons server-buffer
+                                                              target-name)))
+      (when (not circe-server-chat-buffer-table)
+        (setq circe-server-chat-buffer-table (make-hash-table :test 'equal)))
+      (puthash target-name chat-buffer circe-server-chat-buffer-table)
+      (with-current-buffer chat-buffer
+        (funcall chat-mode))
+      chat-buffer)))
+
+(defun circe-server-get-or-create-chat-buffer (target chat-mode)
+  "Return a buffer addressing TARGET; create one in CHAT-MODE if none exists."
+  (let ((buf (circe-server-get-chat-buffer target)))
+    (if buf
+        buf
+      (circe-server-create-chat-buffer target chat-mode))))
+
+(defun circe-server-remove-chat-buffer (target-or-buffer)
+  "Remove the buffer addressing TARGET-OR-BUFFER."
+  (with-circe-server-buffer
+    (let* ((target (if (bufferp target-or-buffer)
+                       (circe-server-chat-buffer-target target-or-buffer)
+                     target-or-buffer))
+           (target-name  (irc-isupport--case-fold (circe-server-process)
+                                                  target)))
+      (remhash target-name circe-server-chat-buffer-table))))
+
+(defun circe-server-rename-chat-buffer (old-name new-name)
+  "Note that the chat buffer addressing OLD-NAME now addresses NEW-NAME."
+  (with-circe-server-buffer
+    (let* ((old-target-name (irc-isupport--case-fold (circe-server-process)
+                                                     old-name))
+           (new-target-name (irc-isupport--case-fold (circe-server-process)
+                                                     new-name))
+           (buf (gethash old-target-name circe-server-chat-buffer-table)))
+      (when buf
+        (remhash old-target-name circe-server-chat-buffer-table)
+        (puthash new-target-name buf circe-server-chat-buffer-table)
+        (with-current-buffer buf
+          (setq circe-chat-target new-name)
+          (rename-buffer new-name t))))))
+
+(defun circe-server-chat-buffer-target (&optional buffer)
+  "Return the chat target of BUFFER, or the current buffer if none."
+  (if buffer
+      (with-current-buffer buffer
+        circe-chat-target)
+    circe-chat-target))
+
+(defun circe-server-chat-buffers ()
+  "Return the list of chat buffers on this server."
+  (with-circe-server-buffer
+    (when circe-server-chat-buffer-table
+      (let ((buffer-list nil))
+        (maphash (lambda (target-name buffer)
+                   (if (buffer-live-p buffer)
+                       (push buffer buffer-list)
+                     (remhash target-name circe-server-chat-buffer-table)))
+                 circe-server-chat-buffer-table)
+        buffer-list))))
+
+(defun circe-server-channel-buffers ()
+  "Return a list of all channel buffers of this server."
+  (let ((result nil))
+    (dolist (buf (circe-server-chat-buffers))
+      (with-current-buffer buf
+        (when (eq major-mode 'circe-channel-mode)
+          (setq result (cons buf result)))))
+    (nreverse result)))
+
+;;;;;;;;;;;;;;;;;
+;;; Chat Mode ;;;
+;;;;;;;;;;;;;;;;;
+
+(defvar circe-chat-mode-hook nil
+  "Hook run when a new chat buffer (channel or query) is created.")
+
+(defvar circe-chat-mode-map (make-sparse-keymap)
+  "Base key map for all Circe chat buffers (channel, query).")
+
+;; Defined here as we use it, but do not necessarily want to use the
+;; full module.
+(defvar lui-logging-format-arguments nil
+  "A list of arguments to be passed to `lui-format'.
+This can be used to extend the formatting possibilities of the
+file name for lui applications.")
+(make-variable-buffer-local 'lui-logging-format-arguments)
+
+(define-derived-mode circe-chat-mode circe-mode "Circe Chat"
+  "The circe chat major mode.
+
+This is the common mode used for both queries and channels.
+It should not be used directly.
+TARGET is the default target to send data to.
+SERVER-BUFFER is the server buffer of this chat buffer."
+  (setq circe-server-buffer (car circe-chat-calling-server-buffer-and-target)
+        circe-chat-target (cdr circe-chat-calling-server-buffer-and-target))
+  (let ((network (with-circe-server-buffer
+                   circe-network)))
+    (make-local-variable 'mode-line-buffer-identification)
+    (setq mode-line-buffer-identification
+          (list (format "%%b@%-8s" network)))
+    (setq lui-logging-format-arguments
+          `(:target ,circe-chat-target :network ,network)))
+  (when (equal circe-chat-target "#emacs-circe")
+    (set (make-local-variable 'lui-button-issue-tracker)
+         "https://github.com/jorgenschaefer/circe/issues/%s")))
+
+(defun circe-chat-disconnected ()
+  "The current buffer got disconnected."
+  (circe-display-server-message "Disconnected"))
+
+;;;;;;;;;;;;;;;;;;;;
+;;; Channel Mode ;;;
+;;;;;;;;;;;;;;;;;;;;
+
+(defvar circe-channel-mode-hook nil
+  "Hook run in a new channel buffer.")
+
+(defvar circe-channel-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "C-c C-n") 'circe-command-NAMES)
+    (define-key map (kbd "C-c C-t") 'circe-command-CHTOPIC)
+    map)
+  "The key map for channel mode buffers.")
+
+(define-derived-mode circe-channel-mode circe-chat-mode "Circe Channel"
+  "The circe channel chat major mode.
+This mode represents a channel you are talking in.
+
+TARGET is the default target to send data to.
+SERVER-BUFFER is the server buffer of this chat buffer.
+
+\\{circe-channel-mode-map}"
+  (add-hook 'kill-buffer-hook 'circe-channel-killed nil t))
+
+(defun circe-channel-killed ()
+  "Called when the channel buffer got killed.
+
+If we are not on the channel being killed, do nothing. Otherwise,
+if the server is live, and the user wants to kill the buffer,
+send PART to the server and clean up the channel's remaining
+state."
+  (when (buffer-live-p circe-server-buffer)
+    (when (and circe-channel-killed-confirmation
+               (not (y-or-n-p "Really leave this channel? ")))
+      (error "Channel not left."))
+    (ignore-errors
+      (irc-send-PART (circe-server-process)
+                     circe-chat-target
+                     circe-default-part-message))
+    (ignore-errors
+      (circe-server-remove-chat-buffer circe-chat-target))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;; Channel User Tracking ;;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; Channel mode buffers provide some utility functions to check if a
+;; given user is idle or not.
+
+(defun circe-channel-user-nick-regain-p (_old new)
+  "Return true if a nick change from OLD to NEW constitutes a nick regain.
+
+A nick was regained if the NEW nick was also a recent user."
+  (let ((channel (irc-connection-channel (circe-server-process)
+                                         circe-chat-target)))
+    (when channel
+      (irc-channel-recent-user channel new))))
+
+(defun circe-channel-user-p (nick)
+  "Return non-nil when NICK belongs to a channel user."
+  (cond
+   ((eq major-mode 'circe-query-mode)
+    (irc-string-equal-p (circe-server-process)
+                        nick
+                        circe-chat-target))
+   ((eq major-mode 'circe-channel-mode)
+    (let ((channel (irc-connection-channel (circe-server-process)
+                                           circe-chat-target)))
+      (when channel
+        (if (irc-channel-user channel nick)
+            t
+          nil))))))
+
+(defun circe-channel-nicks ()
+  "Return a list of nicks in the current channel."
+  (let* ((channel (irc-connection-channel (circe-server-process)
+                                          circe-chat-target))
+         (nicks nil))
+    (when channel
+      (maphash (lambda (_folded-nick user)
+                 (push (irc-user-nick user) nicks))
+               (irc-channel-users channel)))
+    nicks))
+
+(defun circe-user-channels (nick)
+  "Return a list of channel buffers for the user named NICK."
+  (let* ((result nil))
+    (dolist (channel (irc-connection-channel-list (circe-server-process)))
+      (when (irc-channel-user channel nick)
+        (let* ((name (irc-channel-name channel))
+               (buf (circe-server-get-chat-buffer name)))
+          (when buf
+            (push buf result)))))
+    result))
+
+(defun circe-lurker-p (nick)
+  "Return a true value if this nick is regarded inactive."
+  (let* ((channel (irc-connection-channel (circe-server-process)
+                                          circe-chat-target))
+         (user (when channel
+                 (irc-channel-user channel nick)))
+         (recent-user (when channel
+                        (irc-channel-recent-user channel nick)))
+         (last-active (cond
+                       (user
+                        (irc-user-last-activity-time user))
+                       (recent-user
+                        (irc-user-last-activity-time recent-user)))))
+    (cond
+     ;; If we do not track lurkers, no one is ever a lurker.
+     ((not (circe-reduce-lurker-spam))
+      nil)
+     ;; We ourselves are never lurkers (in this sense).
+     ((circe-server-my-nick-p nick)
+      nil)
+     ;; Someone who isn't even on the channel (e.g. NickServ) isn't a
+     ;; lurker, either.
+     ((and (not user)
+           (not recent-user))
+      nil)
+     ;; If someone has never been active, they most definitely *are* a
+     ;; lurker.
+     ((not last-active)
+      t)
+     ;; But if someone has been active, and we mark active users
+     ;; inactive again after a timeout ...
+     (circe-active-users-timeout
+      ;; They are still lurkers if their activity has been too long
+      ;; ago.
+      (> (- (float-time)
+            last-active)
+         circe-active-users-timeout))
+     ;; Otherwise, they have been active and we don't mark active
+     ;; users inactive again, so nope, not a lurker.
+     (t
+      nil))))
+
+(defun circe-lurker-rejoin-p (nick channel)
+  "Return true if NICK is rejoining CHANNEL.
+
+A user is considered to be rejoining if they were on the channel
+shortly before, and were active then."
+  (let* ((channel (irc-connection-channel (circe-server-process)
+                                          channel))
+         (user (when channel
+                 (irc-channel-recent-user channel nick))))
+    (when user
+      (irc-user-last-activity-time user))))
+
+(defun circe-lurker-display-active (nick userhost)
+  "Show that this user is active if they are a lurker."
+  (let* ((channel (irc-connection-channel (circe-server-process)
+                                          circe-chat-target))
+         (user (when channel
+                 (irc-channel-user channel nick)))
+         (join-time (when user
+                      (irc-user-join-time user))))
+    (when (and (circe-lurker-p nick)
+               ;; If we saw them when we joined the channel, no need to
+               ;; say "they're suddenly active!!111one".
+               join-time)
+      (circe-display 'circe-format-server-lurker-activity
+                     :nick nick
+                     :userhost (or userhost "server")
+                     :jointime join-time
+                     :joindelta (circe-duration-string
+                                 (- (float-time)
+                                    join-time))))))
+
+;;;;;;;;;;;;;;;;;;
+;;; Query Mode ;;;
+;;;;;;;;;;;;;;;;;;
+
+(defvar circe-query-mode-hook nil
+  "Hook run when query mode is activated.")
+
+(defvar circe-query-mode-map
+  (let ((map (make-sparse-keymap)))
+    (set-keymap-parent map circe-chat-mode-map)
+    map)
+  "The key map for query mode buffers.")
+
+(define-derived-mode circe-query-mode circe-chat-mode "Circe Query"
+  "The circe query chat major mode.
+This mode represents a query you are talking in.
+
+TARGET is the default target to send data to.
+SERVER-BUFFER is the server buffer of this chat buffer.
+
+\\{circe-query-mode-map}"
+  (add-hook 'kill-buffer-hook 'circe-query-killed nil t))
+
+(defun circe-query-killed ()
+  "Called when the query buffer got killed."
+  (ignore-errors
+    (circe-server-remove-chat-buffer circe-chat-target)))
+
+(defun circe-query-auto-query-buffer (who)
+  "Return a buffer for a query with `WHO'.
+
+This adheres to `circe-auto-query-max'."
+  (or (circe-server-get-chat-buffer who)
+      (when (< (circe--query-count)
+               circe-auto-query-max)
+        (circe-server-get-or-create-chat-buffer who 'circe-query-mode))))
+
+(defun circe--query-count ()
+  "Return the number of queries on the current server."
+  (let ((num 0))
+    (dolist (buf (circe-server-chat-buffers))
+      (with-current-buffer buf
+        (when (eq major-mode 'circe-query-mode)
+          (setq num (+ num 1)))))
+    num))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; IRC Protocol Handling ;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defvar circe--irc-handler-table nil
+  "The handler table for Circe's IRC connections.
+
+Do not use this directly. Instead, call `circe-irc-handler-table'.")
+
+(defun circe-irc-handler-table ()
+  (when (not circe--irc-handler-table)
+    (let ((table (irc-handler-table)))
+      (irc-handler-add table "irc.registered" #'circe--irc-conn-registered)
+      (irc-handler-add table "conn.disconnected" #'circe--irc-conn-disconnected)
+      (irc-handler-add table nil #'circe--irc-display-event)
+      (irc-handle-registration table)
+      (irc-handle-ping-pong table)
+      (irc-handle-isupport table)
+      (irc-handle-initial-nick-acquisition table)
+      (irc-handle-ctcp table)
+      (irc-handle-state-tracking table)
+      (irc-handle-nickserv table)
+      (irc-handle-auto-join table)
+      (setq circe--irc-handler-table table)))
+  circe--irc-handler-table)
+
+(defun circe--irc-conn-registered (conn _event _nick)
+  (with-current-buffer (irc-connection-get conn :server-buffer)
+    (setq circe-server-reconnect-attempts 0)
+    (run-hooks 'circe-server-connected-hook)))
+
+(defun circe--irc-conn-disconnected (conn _event)
+  (with-current-buffer (irc-connection-get conn :server-buffer)
+    (dolist (buf (circe-server-chat-buffers))
+      (with-current-buffer buf
+        (circe-chat-disconnected)))
+
+    (circe-reconnect)))
+
+(defun circe--irc-display-event (conn event &optional sender &rest args)
+  "Display an IRC message.
+
+NICK, USER and HOST specify the originator of COMMAND with ARGS
+as arguments."
+  (with-current-buffer (irc-connection-get conn :server-buffer)
+    (let* ((display (circe-get-display-handler event))
+           (nick (when sender
+                   (irc-userstring-nick sender)))
+           (userhost (when sender
+                       (irc-userstring-userhost sender))))
+      (cond
+       ;; Functions get called
+       ((functionp display)
+        (apply display nick userhost event args))
+       ;; Lists describe patterns
+       ((consp display)
+        (circe--irc-display-format (elt display 1)
+                                     (elt display 0)
+                                     nick userhost event args))
+       ;; No configured display handler, show a default
+       (t
+        (circe--irc-display-default nick userhost event args))))))
+
+(defvar circe--irc-format-server-numeric "*** %s"
+  "The format to use for server messages. Do not set this.")
+
+(defun circe--irc-display-format (format target nick userhost event args)
+  (let* ((target+name (circe--irc-display-target target nick args))
+         (target (car target+name))
+         (name (cdr target+name))
+         (origin (if userhost
+                     (format "%s (%s)" nick userhost)
+                   (format "%s" nick))))
+    (with-current-buffer (or target
+                             (circe-server-last-active-buffer))
+      (let ((circe--irc-format-server-numeric
+             (if target
+                 (format "*** %s" format)
+               (format "*** [%s] %s" name format))))
+        (circe-display 'circe--irc-format-server-numeric
+                       :nick (or nick "(unknown)")
+                       :userhost (or userhost "server")
+                       :origin origin
+                       :event event
+                       :command event
+                       :target name
+                       :indexed-args args)))))
+
+(defun circe--irc-display-target (target nick args)
+  "Return the target buffer and name.
+The buffer might be nil if it is not alive.
+
+See `circe-set-display-handler' for a description of target.
+
+NICK and USERHOST are the originator of COMMAND which had ARGS as
+arguments."
+  (cond
+   ((eq target 'nick)
+    (cons (circe-server-get-chat-buffer nick)
+          nick))
+   ((numberp target)
+    (let ((name (nth target
+                     args)))
+      (cons (circe-server-get-chat-buffer name)
+            name)))
+   ((eq target 'active)
+    (let ((buf (circe-server-last-active-buffer)))
+      (cons buf
+            (buffer-name buf))))
+   ((eq target 'server)
+    (cons (current-buffer) (buffer-name)))
+   (t
+    (error "Bad target in format string: %s" target))))
+
+(defun circe--irc-display-default (nick userhost event args)
+  (with-current-buffer (circe-server-last-active-buffer)
+    (let ((target (if (circe-server-my-nick-p (car args))
+                      ""
+                    (format " to %s" (car args)))))
+      (cond
+       ((string-match "\\`irc.ctcpreply.\\(.*\\)\\'" event)
+        (circe-display-server-message
+         (format "CTCP %s reply from %s (%s)%s: %s"
+                 (match-string 1 event) nick userhost target (cadr args))))
+       ((string-match "\\`irc.ctcp.\\(.*\\)\\'" event)
+        (circe-display-server-message
+         (format "Unknown CTCP request %s from %s (%s)%s: %s"
+                 (match-string 1 event) nick userhost target (cadr args))))
+       (t
+        (circe-display-server-message
+         (format "[%s from %s%s] %s"
+                 event
+                 nick
+                 (if userhost
+                     (format " (%s)" userhost)
+                   "")
+                 (mapconcat #'identity args " "))))))))
+
+(defun circe-set-display-handler (command handler)
+  "Set the display handler for COMMAND to HANDLER.
+
+A handler is either a function or a list.
+
+A function gets called in the server buffer with at least three
+arguments, but possibly more. There's at least NICK and USERHOST
+of the sender, which can be nil, and COMMAND, which is the event
+which triggered this. Further arguments are arguments to the
+event.
+
+Alternatively, the handler can be a list of two elements:
+
+  target   - The target of this message
+  format   - The format for this string
+
+The target can be any of:
+
+  'active  - The last active buffer of this server
+  'nick    - The nick who sent this message
+  'server  - The server buffer for this server
+  number   - The index of the argument of the target
+
+The format is passed to `lui-format'. Possible format string
+substitutions are {mynick}, {target}, {nick}, {userhost},
+{origin}, {command}, {target}, and indexed arguments for the
+arguments to the IRC message."
+  (when (not circe-display-table)
+    (setq circe-display-table (make-hash-table :test 'equal)))
+  (puthash command handler circe-display-table))
+
+(defun circe-get-display-handler (command)
+  "Return the display handler for COMMAND.
+
+See `circe-set-display-handler' for more information."
+  (when circe-display-table
+    (gethash command circe-display-table)))
+
+;;;;;;;;;;;;;;;;
+;;; Commands ;;;
+;;;;;;;;;;;;;;;;
+
+(defun circe-command-AWAY (reason)
+  "Set yourself away with REASON."
+  (interactive "sReason: ")
+  (irc-send-AWAY (circe-server-process) reason))
+
+(defun circe-command-BACK (&optional ignored)
+  "Mark yourself not away anymore.
+
+Arguments are IGNORED."
+  (interactive)
+  (irc-send-AWAY (circe-server-process)))
+
+(defun circe-command-CHTOPIC (&optional ignored)
+  "Insert the topic of the current channel.
+
+Arguments are IGNORED."
+  (interactive)
+  (if (not circe-chat-target)
+      (circe-display-server-message "No target for current buffer")
+    (let* ((channel (irc-connection-channel (circe-server-process)
+                                            circe-chat-target))
+           (topic (when channel
+                    (irc-channel-topic channel))))
+      (lui-replace-input (format "/TOPIC %s %s"
+                                 circe-chat-target (or topic ""))))
+    (goto-char (point-max))))
+
+(defun circe-command-CLEAR (&optional ignored)
+  "Delete all buffer contents before the lui prompt."
+  (let ((inhibit-read-only t))
+    (delete-region (point-min) lui-output-marker)))
+
+(defun circe-command-CTCP (who &optional command argument)
+  "Send a CTCP message to WHO containing COMMAND with ARGUMENT.
+If COMMAND is not given, WHO is parsed to contain all of who,
+command and argument.
+If ARGUMENT is nil, it is interpreted as no argument."
+  (when (not command)
+    (if (string-match "^\\([^ ]*\\) *\\([^ ]*\\) *\\(.*\\)" who)
+        (setq command (upcase (match-string 2 who))
+              argument (match-string 3 who)
+              who (match-string 1 who))
+      (circe-display-server-message "Usage: /CTCP <who> <what>")))
+  (when (not (string= "" command))
+    (irc-send-ctcp (circe-server-process)
+                   who
+                   command
+                   (if (and argument (not (equal argument "")))
+                       argument
+                     nil))))
+
+(defun circe-command-FOOL (line)
+  "Add the regex on LINE to the `circe-fool-list'."
+  (with-current-buffer (circe-server-last-active-buffer)
+    (cond
+     ((string-match "\\S-+" line)
+      (let ((regex (match-string 0 line)))
+        (add-to-list 'circe-fool-list regex)
+        (circe-display-server-message (format "Recognizing %s as a fool"
+                                      regex))))
+     ((not circe-fool-list)
+      (circe-display-server-message "Your do not know any fools"))
+     (t
+      (circe-display-server-message "Your list of fools:")
+      (dolist (regex circe-fool-list)
+        (circe-display-server-message (format "- %s" regex)))))))
+
+(defun circe-command-GAWAY (reason)
+  "Set yourself away on all servers with reason REASON."
+  (interactive "sReason: ")
+  (dolist (buf (circe-server-buffers))
+    (with-current-buffer buf
+      (irc-send-AWAY circe-server-process reason))))
+
+(defun circe-command-GQUIT (reason)
+  "Quit all servers with reason REASON."
+  (interactive "sReason: ")
+  (dolist (buf (circe-server-buffers))
+    (with-current-buffer buf
+      (when (eq (process-status circe-server-process)
+                'open)
+        (irc-send-QUIT circe-server-process reason)))))
+
+(defun circe-command-HELP (&optional ignored)
+  "Display a list of recognized commands, nicely formatted."
+  (circe-display-server-message
+   (concat "Recognized commands are: "
+	   (mapconcat (lambda (s) s) (circe--commands-list) ""))))
+
+(defun circe-command-IGNORE (line)
+  "Add the regex on LINE to the `circe-ignore-list'."
+  (with-current-buffer (circe-server-last-active-buffer)
+    (cond
+     ((string-match "\\S-+" line)
+      (let ((regex (match-string 0 line)))
+        (add-to-list 'circe-ignore-list regex)
+        (circe-display-server-message (format "Ignore list, meet %s"
+                                      regex))))
+     ((not circe-ignore-list)
+      (circe-display-server-message "Your ignore list is empty"))
+     (t
+      (circe-display-server-message "Your ignore list:")
+      (dolist (regex circe-ignore-list)
+        (circe-display-server-message (format "- %s" regex)))))))
+
+(defun circe-command-INVITE (nick &optional channel)
+  "Invite NICK to CHANNEL.
+When CHANNEL is not given, NICK is assumed to be a string
+consisting of two words, the nick and the channel."
+  (interactive "sInvite who: \nsWhere: ")
+  (when (not channel)
+    (if (string-match "^\\([^ ]+\\) +\\([^ ]+\\)" nick)
+        (setq channel (match-string 2 nick)
+              nick (match-string 1 nick))
+      (when (or (string= "" nick) (null nick))
+        (circe-display-server-message "Usage: /INVITE <nick> <channel>"))))
+  (irc-send-INVITE (circe-server-process)
+                   nick
+                   (if (and (null channel)
+                            (not (null nick)))
+                       circe-chat-target
+                     channel)))
+
+(defun circe-command-JOIN (channel)
+  "Join CHANNEL. This can also contain a key."
+  (interactive "sChannel: ")
+  (let (channels keys)
+    (when (string-match "^\\s-*\\([^ ]+\\)\\(:? \\([^ ]+\\)\\)?$" channel)
+      (setq channels (match-string 1 channel)
+            keys (match-string 3 channel))
+      (dolist (channel (split-string channels ","))
+        (pop-to-buffer
+         (circe-server-get-or-create-chat-buffer channel
+                                                 'circe-channel-mode)))
+      (irc-send-JOIN (circe-server-process) channels keys))))
+
+(defun circe-command-ME (line)
+  "Send LINE to IRC as an action."
+  (interactive "sAction: ")
+  (if (not circe-chat-target)
+      (circe-display-server-message "No target for current buffer")
+    (circe-display 'circe-format-self-action
+                   :body line
+                   :nick (circe-nick))
+    (irc-send-ctcp (circe-server-process)
+                   circe-chat-target
+                   "ACTION" line)))
+
+(defun circe-command-MSG (who &optional what)
+  "Send a message.
+
+Send WHO a message containing WHAT.
+
+If WHAT is not given, WHO should contain both the nick and the
+message separated by a space."
+  (when (not what)
+    (if (string-match "^\\([^ ]*\\) \\(.*\\)" who)
+        (setq what (match-string 2 who)
+              who (match-string 1 who))
+      (circe-display-server-message "Usage: /MSG <who> <what>")))
+  (when what
+    (let ((buf (circe-query-auto-query-buffer who)))
+      (if buf
+          (with-current-buffer buf
+            (circe-command-SAY what)
+            (lui-add-input what))
+        (with-current-buffer (circe-server-last-active-buffer)
+          (irc-send-PRIVMSG (circe-server-process)
+                            who what)
+          (circe-display 'circe-format-self-message
+                         :target who
+                         :body what))))))
+
+(defun circe-command-NAMES (&optional channel)
+  "List the names of the current channel or CHANNEL."
+  (interactive)
+  (let ((target (when channel
+                  (string-trim channel))))
+    (when (or (not target)
+              (equal target ""))
+      (setq target circe-chat-target))
+    (if (not target)
+        (circe-display-server-message "No target for current buffer")
+      (irc-send-NAMES (circe-server-process)
+                      target))))
+
+(defun circe-command-NICK (newnick)
+  "Change nick to NEWNICK."
+  (interactive "sNew nick: ")
+  (let ((newnick (string-trim newnick)))
+    (irc-send-NICK (circe-server-process) newnick)))
+
+(defun circe-command-PART (reason)
+  "Part the current channel because of REASON."
+  (interactive "sReason: ")
+  (if (not circe-chat-target)
+      (circe-display-server-message "No target for current buffer")
+    (irc-send-PART (circe-server-process)
+                   circe-chat-target
+                   (if (equal "" reason)
+                       circe-default-part-message
+                     reason))))
+
+(defun circe-command-PING (target)
+  "Send a CTCP PING request to TARGET."
+  (interactive "sWho: ")
+  (let ((target (string-trim target)))
+    (irc-send-ctcp (circe-server-process)
+                   target
+                   "PING" (format "%s" (float-time)))))
+
+(defun circe-command-QUERY (arg)
+  "Open a query with WHO."
+  ;; Eventually, this should probably be just the same as
+  ;; circe-command-MSG
+  (interactive "sQuery with: ")
+  (let* (who what)
+    (if (string-match "\\`\\s-*\\(\\S-+\\)\\s-\\(\\s-*\\S-.*\\)\\'" arg)
+        (setq who (match-string 1 arg)
+              what (match-string 2 arg))
+      (setq who (string-trim arg)))
+    (when (string= who "")
+      (circe-display-server-message "Usage: /query <nick> [something to say]"))
+    (pop-to-buffer
+     (circe-server-get-or-create-chat-buffer who 'circe-query-mode))
+    (when what
+      (circe-command-SAY what)
+      (lui-add-input what))))
+
+(defun circe-command-QUIT (reason)
+  "Quit the current server giving REASON."
+  (interactive "sReason: ")
+  (with-circe-server-buffer
+    (setq circe-server-inhibit-auto-reconnect-p t)
+    (irc-send-QUIT (circe-server-process)
+                   (if (equal "" reason)
+                       circe-default-quit-message
+                     reason))))
+
+(defun circe-command-QUOTE (line)
+  "Send LINE verbatim to the server."
+  (interactive "Line: ")
+  (irc-send-raw (circe-server-process) line)
+  (with-current-buffer (circe-server-last-active-buffer)
+    (circe-display-server-message (format "Sent to server: %s"
+                                  line))))
+
+(defun circe-command-SAY (line)
+  "Say LINE to the current target."
+  (interactive "sSay: ")
+  (if (not circe-chat-target)
+      (circe-display-server-message "No target for current buffer")
+    (dolist (line (circe--split-line line))
+      (circe-display 'circe-format-self-say
+                     :body line
+                     :nick (circe-nick))
+      (irc-send-PRIVMSG (circe-server-process)
+                        circe-chat-target
+                        ;; Some IRC servers give an error if there is
+                        ;; no text at all.
+                        (if (string= line "")
+                            " "
+                          line)))))
+
+(defun circe--split-line (longline)
+  "Splits LONGLINE into smaller components.
+
+IRC silently truncates long lines. This splits a long line into
+parts that each are not longer than `circe-split-line-length'."
+  (if (< (length longline)
+         circe-split-line-length)
+      (list longline)
+    (with-temp-buffer
+      (insert longline)
+      (let ((fill-column circe-split-line-length))
+        (fill-region (point-min) (point-max)
+                     nil t))
+      (split-string (buffer-string) "\n"))))
+
+(defun circe-command-SV (&optional ignored)
+  "Tell the current channel about your client and Emacs version.
+
+Arguments are IGNORED."
+  (interactive)
+  (circe-command-SAY (format (concat "I'm using Circe version %s "
+                                     "with %s %s (of %s)")
+                             (circe--version)
+                             "GNU Emacs"
+                             emacs-version
+                             (format-time-string "%Y-%m-%d"
+                                                 emacs-build-time))))
+
+(defun circe-command-TOPIC (channel &optional newtopic)
+  "Change the topic of CHANNEL to NEWTOPIC."
+  (interactive "sChannel: \nsNew topic: ")
+  (when (string-match "^\\s-*$" channel)
+    (setq channel nil))
+  (when (and channel
+             (not newtopic)
+             (string-match "^\\s-*\\(\\S-+\\)\\( \\(.*\\)\\)?" channel))
+    (setq newtopic (match-string 3 channel)
+          channel (match-string 1 channel)))
+  (cond
+   ((and channel newtopic)
+    (irc-send-TOPIC (circe-server-process) channel newtopic))
+   (channel
+    (irc-send-TOPIC (circe-server-process) channel))
+   (circe-chat-target
+    (irc-send-TOPIC (circe-server-process) circe-chat-target))
+   (t
+    (circe-display-server-message "No channel given, and no default target."))))
+
+(defun circe-command-UNFOOL (line)
+  "Remove the entry LINE from `circe-fool-list'."
+  (with-current-buffer (circe-server-last-active-buffer)
+    (cond
+     ((string-match "\\S-+" line)
+      (let ((regex (match-string 0 line)))
+        (setq circe-fool-list (delete regex circe-fool-list))
+        (circe-display-server-message (format "Assuming %s is not a fool anymore"
+                                      regex))))
+     (t
+      (circe-display-server-message
+       "No one is not a fool anymore? UNFOOL requires one argument")))))
+
+(defun circe-command-UNIGNORE (line)
+  "Remove the entry LINE from `circe-ignore-list'."
+  (with-current-buffer (circe-server-last-active-buffer)
+    (cond
+     ((string-match "\\S-+" line)
+      (let ((regex (match-string 0 line)))
+        (setq circe-ignore-list (delete regex circe-ignore-list))
+        (circe-display-server-message (format "Ignore list forgot about %s"
+                                      regex))))
+     (t
+      (circe-display-server-message
+       "Who do you want to unignore? UNIGNORE requires one argument")))))
+
+(defun circe-command-WHOAMI (&optional ignored)
+  "Request WHOIS information about yourself.
+
+Arguments are IGNORED."
+  (interactive)
+  (irc-send-WHOIS (circe-server-process)
+                  (circe-nick)))
+
+(defun circe-command-WHOIS (whom)
+  "Request WHOIS information about WHOM."
+  (interactive "sWhois: ")
+  (let* ((whom-server-name (split-string whom))
+         (whom (car whom-server-name))
+         (server-or-name (cadr whom-server-name)))
+    (irc-send-WHOIS (circe-server-process) whom server-or-name)))
+
+(defun circe-command-WHOWAS (whom)
+  "Request WHOWAS information about WHOM."
+  (interactive "sWhois: ")
+  (let ((whom (string-trim whom)))
+    (irc-send-WHOWAS (circe-server-process) whom)))
+
+(defun circe-command-STATS (query)
+  "Request statistics from a server."
+  (interactive)
+  ;; Split string into query and server if we can
+  (let ((query (split-string query)))
+    (irc-send-STATS (circe-server-process) (car query) (cadr query))))
+
+(defun circe-command-WL (&optional split)
+  "Show the people who left in a netsplit.
+Without any arguments, shows shows the current netsplits and how
+many people are missing. With an argument SPLIT, which must be a
+number, it shows the missing people due to that split."
+  (let ((circe-netsplit-list (with-circe-server-buffer
+                               circe-netsplit-list)))
+    (if (or (not split)
+            (and (stringp split)
+                 (string= split "")))
+        (if (null circe-netsplit-list)
+            (circe-display-server-message "No net split at the moment")
+          (let ((n 0))
+            (dolist (entry circe-netsplit-list)
+              (circe-display-server-message (format "(%d) Missing %d people due to %s"
+                                            n
+                                            (hash-table-count (nth 3 entry))
+                                            (car entry)))
+              (setq n (+ n 1)))))
+      (let* ((index (if (numberp split)
+                        split
+                      (string-to-number split)))
+             (entry (nth index circe-netsplit-list)))
+        (if (not entry)
+            (circe-display-server-message (format "No split number %s - use /WL to see a list"
+                                          split))
+          (let ((missing nil))
+            (maphash (lambda (_key value)
+                       (setq missing (cons value missing)))
+                     (nth 3 entry))
+            (circe-display-server-message
+             (format "Missing people due to %s: %s"
+                     (car entry)
+                     (mapconcat 'identity
+                                (sort missing
+                                      (lambda (a b)
+                                        (string< (downcase a)
+                                                 (downcase b))))
+                                ", ")))))))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;
+;;; Display Handlers ;;;
+;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun circe-display-ignore (_nick _userhost _command &rest _args)
+  "Don't show a this message.
+
+NICK and USERHOST are the originator of COMMAND which had ARGS as
+arguments."
+  'noop)
+
+(circe-set-display-handler "317" 'circe-display-317)
+(defun circe-display-317 (_sender ignored _numeric _target nick
+                                  idletime &optional signon-time body)
+  "Show a 317 numeric (RPL_WHOISIDLE).
+
+Arguments are either of the two:
+
+:<server> 317 <ournick> <nick> <idle> :seconds idle
+:<server> 317 <ournick> <nick> <idle> <signon> :seconds idle, signon time"
+  (with-current-buffer (circe-server-last-active-buffer)
+    (let ((seconds-idle (string-to-number idletime))
+          (signon-time (when body
+                         (string-to-number signon-time))))
+      (if signon-time
+          (circe-display 'circe-format-server-whois-idle-with-signon
+                         :whois-nick nick
+                         :idle-seconds seconds-idle
+                         :idle-duration (circe-duration-string seconds-idle)
+                         :signon-time signon-time
+                         :signon-date (current-time-string
+                                       (seconds-to-time signon-time))
+                         :signon-ago (circe-duration-string (- (float-time)
+                                                               signon-time)))
+        (circe-display 'circe-format-server-whois-idle
+                       :whois-nick nick
+                       :idle-seconds seconds-idle
+                       :idle-duration (circe-duration-string seconds-idle))))))
+
+(circe-set-display-handler "329" 'circe-display-329)
+(defun circe-display-329 (_server ignored _numeric _target channel timestamp)
+  "Show a 329 numeric (RPL_CREATIONTIME)."
+  (with-current-buffer (or (circe-server-get-chat-buffer channel)
+                           (circe-server-last-active-buffer))
+    (let ((creation-time (string-to-number timestamp)))
+      (circe-display 'circe-format-server-channel-creation-time
+                     :channel channel
+                     :date (current-time-string
+                            (seconds-to-time creation-time))
+                     :ago (circe-duration-string (- (float-time)
+                                                    creation-time))))))
+
+(circe-set-display-handler "333" 'circe-display-333)
+(defun circe-display-333 (_server ignored _numeric target
+                                  channel setter topic-time)
+  "Show a 333 numeric (RPL_TOPICWHOTIME).
+
+Arguments are either of the two:
+
+:<server> 333 <target> <channel> <nick> 1434996762
+:<server> 333 <target> <channel> <nick>!<user>@<host> 1434996803"
+  (let ((channel-buffer (circe-server-get-chat-buffer channel))
+        (topic-time (string-to-number topic-time)))
+    (with-current-buffer (or channel-buffer
+                             (circe-server-last-active-buffer))
+      (circe-display (if channel-buffer
+                         'circe-format-server-topic-time
+                       'circe-format-server-topic-time-for-channel)
+                     :nick target
+                     :channel channel
+                     :setter (irc-userstring-nick setter)
+                     :setter-userhost (or (irc-userstring-userhost setter)
+                                          "(unknown)")
+                     :topic-time topic-time
+                     :topic-date (current-time-string
+                                  (seconds-to-time topic-time))
+                     :topic-ago (circe-duration-string (- (float-time)
+                                                          topic-time))))))
+
+(circe-set-display-handler "AUTHENTICATE" 'circe-display-ignore)
+(circe-set-display-handler "CAP" 'circe-display-ignore)
+(circe-set-display-handler "conn.connected" 'circe-display-ignore)
+(circe-set-display-handler "conn.disconnected" 'circe-display-ignore)
+
+(circe-set-display-handler "irc.ctcp" 'circe-display-ignore)
+(circe-set-display-handler "irc.ctcpreply" 'circe-display-ignore)
+
+(circe-set-display-handler "irc.ctcp.ACTION" 'circe-display-ctcp-action)
+(defun circe-display-ctcp-action (nick userhost _command target text)
+  "Show an ACTION."
+  (cond
+   ;; Query
+   ((circe-server-my-nick-p target)
+    (let ((query-buffer (circe-query-auto-query-buffer nick)))
+      (with-current-buffer (or query-buffer
+                               (circe-server-last-active-buffer))
+        (circe-display (if query-buffer
+                           'circe-format-action
+                         'circe-format-message-action)
+                       :nick nick
+                       :userhost (or userhost "server")
+                       :body text))))
+   ;; Channel
+   (t
+    (with-current-buffer (circe-server-get-or-create-chat-buffer
+                          target 'circe-channel-mode)
+      (circe-lurker-display-active nick userhost)
+      (circe-display 'circe-format-action
+                     :nick nick
+                     :userhost (or userhost "server")
+                     :body text)))))
+
+(circe-set-display-handler "irc.ctcp.CLIENTINFO" 'circe-display-ctcp)
+
+(circe-set-display-handler "irc.ctcp.PING" 'circe-display-ctcp-ping)
+(defun circe-display-ctcp-ping (nick userhost _command target text)
+  "Show a CTCP PING request."
+  (with-current-buffer (circe-server-last-active-buffer)
+    (circe-display 'circe-format-server-ctcp-ping
+                   :nick nick
+                   :userhost (or userhost "server")
+                   :target target
+                   :body (or text "")
+                   :ago (let ((time (when text
+				      (string-to-number text))))
+                          (if time
+                              (format "%.2f seconds" (- (float-time) time))
+                            "unknown seconds")))))
+
+(circe-set-display-handler "irc.ctcpreply.PING" 'circe-display-ctcp-ping-reply)
+(defun circe-display-ctcp-ping-reply (nick userhost _command target text)
+  "Show a CTCP PING reply."
+  (with-current-buffer (circe-server-last-active-buffer)
+    (circe-display 'circe-format-server-ctcp-ping-reply
+                   :nick nick
+                   :userhost (or userhost "server")
+                   :target target
+                   :body text
+                   :ago (let ((time (string-to-number text)))
+                          (if time
+                              (format "%.2f seconds" (- (float-time) time))
+                            "unknown seconds")))))
+
+(circe-set-display-handler "irc.ctcp.SOURCE" 'circe-display-ctcp)
+(circe-set-display-handler "irc.ctcp.TIME" 'circe-display-ctcp)
+(circe-set-display-handler "irc.ctcp.VERSION" 'circe-display-ctcp)
+(defun circe-display-ctcp (nick userhost command target text)
+  "Show a CTCP request that does not require special handling."
+  (with-current-buffer (circe-server-last-active-buffer)
+    (circe-display 'circe-format-server-ctcp
+                   :nick nick
+                   :userhost (or userhost "server")
+                   :target target
+                   :command (substring command 9)
+                   :body (or text ""))))
+
+(circe-set-display-handler "irc.registered" 'circe-display-ignore)
+
+(circe-set-display-handler "JOIN" 'circe-display-JOIN)
+(defun circe-display-JOIN (nick userhost _command channel
+                                &optional accountname realname)
+  "Show a JOIN message.
+
+The command receives an extra argument, the account name, on some
+IRC servers."
+  (let* ((accountname (if (equal accountname "*")
+                          "(unauthenticated)"
+                        accountname))
+         (userinfo (if accountname
+                       (format "%s, %s: %s" userhost accountname realname)
+                     userhost))
+         (split (circe--netsplit-join nick)))
+    ;; First, update the channel
+    (with-current-buffer (circe-server-get-or-create-chat-buffer
+                          channel 'circe-channel-mode)
+      (cond
+       (split
+        (let ((split-time (cadr split)))
+          (when (< (+ split-time circe-netsplit-delay)
+                   (float-time))
+            (circe-display 'circe-format-server-netmerge
+                           :split (car split)
+                           :time (cadr split)
+                           :date (current-time-string
+                                  (seconds-to-time (cadr split)))
+                           :ago (circe-duration-string
+                                 (- (float-time) (cadr split)))))))
+       ((and (circe-reduce-lurker-spam)
+             (circe-lurker-rejoin-p nick circe-chat-target))
+        (let* ((channel (irc-connection-channel (circe-server-process)
+                                                circe-chat-target))
+               (user (when channel
+                       (irc-channel-recent-user channel nick)))
+               (departed (when user
+                           (irc-user-part-time user))))
+          (circe-display 'circe-format-server-rejoin
+                         :nick nick
+                         :userhost (or userhost "server")
+                         :accountname accountname
+                         :realname realname
+                         :userinfo userinfo
+                         :departuretime departed
+                         :departuredelta (circe-duration-string
+                                          (- (float-time)
+                                             departed)))))
+       ((not (circe-reduce-lurker-spam))
+        (circe-display 'circe-format-server-join
+                       :nick nick
+                       :userhost (or userhost "server")
+                       :accountname accountname
+                       :realname realname
+                       :userinfo userinfo
+                       :channel circe-chat-target))))
+    ;; Next, a possible query buffer. We do this even when the message
+    ;; should be ignored by a netsplit, since this can't flood.
+    (let ((buf (circe-server-get-chat-buffer nick)))
+      (when buf
+        (with-current-buffer buf
+          (circe-display 'circe-format-server-join-in-channel
+                         :nick nick
+                         :userhost (or userhost "server")
+                         :accountname accountname
+                         :realname realname
+                         :userinfo userinfo
+                         :channel circe-chat-target))))))
+
+(circe-set-display-handler "MODE" 'circe-display-MODE)
+(defun circe-display-MODE (setter userhost _command target &rest modes)
+  "Show a MODE message."
+  (with-current-buffer (or (circe-server-get-chat-buffer target)
+                           (circe-server-last-active-buffer))
+    (circe-display 'circe-format-server-mode-change
+                   :setter setter
+                   :userhost (or userhost "server")
+                   :target target
+                   :change (mapconcat #'identity modes " "))))
+
+(circe-set-display-handler "NICK" 'circe-display-NICK)
+(defun circe-display-NICK (old-nick userhost _command new-nick)
+  "Show a nick change."
+  (if (circe-server-my-nick-p new-nick)
+      (dolist (buf (cons (or circe-server-buffer
+                             (current-buffer))
+                         (circe-server-chat-buffers)))
+        (with-current-buffer buf
+          (circe-display 'circe-format-server-nick-change-self
+                         :old-nick old-nick
+                         :userhost (or userhost "server")
+                         :new-nick new-nick)))
+    (let ((query-buffer (circe-server-get-chat-buffer old-nick)))
+      (when query-buffer
+        (with-current-buffer query-buffer
+          (circe-server-rename-chat-buffer old-nick new-nick)
+          (circe-display 'circe-format-server-nick-change
+                         :old-nick old-nick
+                         :new-nick new-nick
+                         :userhost (or userhost "server")))))
+    (dolist (buf (circe-user-channels new-nick))
+      (with-current-buffer buf
+        (cond
+         ((and (circe-reduce-lurker-spam)
+               (circe-lurker-p new-nick))
+          nil)
+         ((circe-channel-user-nick-regain-p old-nick new-nick)
+          (circe-display 'circe-format-server-nick-regain
+                         :old-nick old-nick
+                         :new-nick new-nick
+                         :userhost (or userhost "server")))
+         (t
+          (circe-display 'circe-format-server-nick-change
+                         :old-nick old-nick
+                         :new-nick new-nick
+                         :userhost (or userhost "server"))))))))
+
+(circe-set-display-handler "nickserv.identified" 'circe-display-ignore)
+
+;; NOTICE is also used to encode CTCP replies. irc.el will send
+;; irc.notice events for NOTICEs without CTCP replies, so we show
+;; that, not the raw notice.
+(circe-set-display-handler "NOTICE" 'circe-display-ignore)
+(circe-set-display-handler "irc.notice" 'circe-display-NOTICE)
+(defun circe-display-NOTICE (nick userhost _command target text)
+  "Show a NOTICE message."
+  (cond
+   ((not userhost)
+    (with-current-buffer (circe-server-last-active-buffer)
+      (circe-display 'circe-format-server-notice
+                     :server nick
+                     :body text)))
+   ((circe-server-my-nick-p target)
+    (with-current-buffer (or (circe-server-get-chat-buffer nick)
+                             (circe-server-last-active-buffer))
+      (circe-display 'circe-format-notice
+                     :nick nick
+                     :userhost (or userhost "server")
+                     :body text)))
+   (t
+    (with-current-buffer (or (circe-server-get-chat-buffer target)
+                             (circe-server-last-active-buffer))
+      (circe-display 'circe-format-notice
+                     :nick nick
+                     :userhost (or userhost "server")
+                     :body text)))))
+
+(circe-set-display-handler "PART" 'circe-display-PART)
+(defun circe-display-PART (nick userhost _command channel &optional reason)
+  "Show a PART message."
+  (with-current-buffer (or (circe-server-get-chat-buffer channel)
+                           (circe-server-last-active-buffer))
+    (when (or (not circe-chat-target)
+              (not (circe-lurker-p nick)))
+      (circe-display 'circe-format-server-part
+                     :nick nick
+                     :userhost (or userhost "server")
+                     :channel channel
+                     :reason (or reason "[No reason given]")))))
+
+(circe-set-display-handler "PING" 'circe-display-ignore)
+(circe-set-display-handler "PONG" 'circe-display-ignore)
+
+;; PRIVMSG is also used to encode CTCP requests. irc.el will send
+;; irc.message events for PRIVMSGs without CTCP messages, so we show
+;; that, not the raw message.
+(circe-set-display-handler "PRIVMSG" 'circe-display-ignore)
+(circe-set-display-handler "irc.message" 'circe-display-PRIVMSG)
+(defun circe-display-PRIVMSG (nick userhost _command target text)
+  "Show a PRIVMSG message."
+  (cond
+   ((circe-server-my-nick-p target)
+    (let ((buf (circe-query-auto-query-buffer nick)))
+      (if buf
+          (with-current-buffer buf
+            (circe-display 'circe-format-say
+                           :nick nick
+                           :userhost (or userhost "server")
+                           :body text))
+        (with-current-buffer (circe-server-last-active-buffer)
+          (circe-display 'circe-format-message
+                         :nick nick
+                         :userhost (or userhost "server")
+                         :body text)))))
+   (t
+    (with-current-buffer (circe-server-get-or-create-chat-buffer
+                          target 'circe-channel-mode)
+      (circe-lurker-display-active nick userhost)
+      (circe-display 'circe-format-say
+                     :nick nick
+                     :userhost (or userhost "server")
+                     :body text)))))
+
+(circe-set-display-handler "TOPIC" 'circe-display-topic)
+(defun circe-display-topic (nick userhost _command channel new-topic)
+  "Show a TOPIC change."
+  (with-current-buffer (circe-server-get-or-create-chat-buffer
+                        channel 'circe-channel-mode)
+    (let* ((channel-obj (irc-connection-channel (circe-server-process)
+                                                channel))
+           (old-topic (or (when channel
+                            (irc-channel-last-topic channel-obj))
+                          "")))
+      (circe-display 'circe-format-server-topic
+                     :nick nick
+                     :userhost (or userhost "server")
+                     :channel channel
+                     :new-topic new-topic
+                     :old-topic old-topic
+                     :topic-diff (circe--topic-diff old-topic new-topic)))))
+
+(defun circe--topic-diff (old new)
+  "Return a colored topic diff between OLD and NEW."
+  (mapconcat (lambda (elt)
+               (cond
+                ((eq '+ (car elt))
+                 (let ((s (cadr elt)))
+                   (add-face-text-property 0 (length s)
+                                           'circe-topic-diff-new-face nil s)
+                   s))
+                ((eq '- (car elt))
+                 (let ((s (cadr elt)))
+                   (add-face-text-property 0 (length s)
+                                           'circe-topic-diff-removed-face nil s)
+                   s))
+                (t
+                 (cadr elt))))
+             (lcs-unified-diff (circe--topic-diff-split old)
+                               (circe--topic-diff-split new)
+                               'string=)
+             ""))
+
+(defun circe--topic-diff-split (str)
+  "Split STR into a list of components.
+The list consists of words and spaces."
+  (let ((lis nil))
+    (with-temp-buffer
+      (insert str)
+      (goto-char (point-min))
+      (while (< (point)
+                (point-max))
+        (if (or (looking-at "\\w+\\W*")
+                (looking-at ".\\s-*"))
+            (progn
+              (setq lis (cons (match-string 0)
+                              lis))
+              (replace-match ""))
+          (error "Can't happen"))))
+    (nreverse lis)))
+
+(circe-set-display-handler "channel.quit" 'circe-display-channel-quit)
+(defun circe-display-channel-quit (nick userhost _command channel
+                                        &optional reason)
+  "Show a QUIT message."
+  (let ((split (circe--netsplit-quit reason nick)))
+    (with-current-buffer (circe-server-get-or-create-chat-buffer
+                          channel 'circe-channel-mode)
+      (cond
+       (split
+        (when (< (+ split circe-netsplit-delay)
+                 (float-time))
+          (circe-display 'circe-format-server-netsplit
+                         :split reason)))
+       ((not (circe-lurker-p nick))
+        (circe-display 'circe-format-server-quit-channel
+                       :nick nick
+                       :userhost (or userhost "server")
+                       :channel channel
+                       :reason (or reason "[no reason given]")))))))
+
+(circe-set-display-handler "QUIT" 'circe-display-QUIT)
+(defun circe-display-QUIT (nick userhost _command &optional reason)
+  "Show a QUIT message.
+
+Channel quits are shown already, so just show quits in queries."
+  (let ((buf (circe-server-get-chat-buffer nick)))
+    (when buf
+      (with-current-buffer buf
+        (circe-display 'circe-format-server-quit
+                       :nick nick
+                       :userhost (or userhost "server")
+                       :reason (or reason "[no reason given]"))))))
+
+(defvar circe-netsplit-list nil
+  "A list of recorded netsplits.
+Every item is a list with four elements:
+- The quit message for this split.
+- The time when last we heard about a join in this split
+- The time when last we heard about a quit in this split
+- A hash table noting which nicks did leave")
+(make-variable-buffer-local 'circe-netsplit-list)
+
+(defun circe--netsplit-join (nick)
+  "Search for NICK in the netsplit lists.
+This either returns a pair whose car is the quit message of this
+split, and the cadr the time we last heard anything of the split
+of that user. If the NICK isn't split, this returns nil."
+  (with-circe-server-buffer
+    (catch 'return
+      (dolist (entry circe-netsplit-list)
+        (let ((table (nth 3 entry)))
+          (when (gethash nick table)
+            (let ((name (nth 0 entry))
+                  (time (nth 1 entry)))
+              (remhash nick table)
+              (when (= 0 (hash-table-count table))
+                (setq circe-netsplit-list
+                      (delq entry circe-netsplit-list)))
+              (setcar (cdr entry)
+                      (float-time))
+              (throw 'return (list name time))))))
+      nil)))
+
+(defun circe--netsplit-quit (reason nick)
+  "If REASON indicates a netsplit, mark NICK as splitted.
+This either returns the time when last we heard about this split,
+or nil when this isn't a split."
+  (when (circe--netsplit-reason-p reason)
+    (with-circe-server-buffer
+      (let ((entry (assoc reason circe-netsplit-list)))
+        (if entry
+            (let ((time (nth 2 entry))
+                  (table (nth 3 entry)))
+              (setcar (cddr entry)
+                      (float-time))
+              (puthash nick nick table)
+              time)
+          ;; New split!
+          (let ((table (make-hash-table :test 'equal)))
+            (puthash nick nick table)
+            (setq circe-netsplit-list
+                  (cons (list reason 0 (float-time) table)
+                        circe-netsplit-list))
+            0))))))
+
+(defun circe--netsplit-reason-p (reason)
+  "Return non-nil if REASON is the quit message of a netsplit.
+This is true when it contains exactly two hosts, with a single
+space in between them. The hosts must include at least one dot,
+and must not include colons or slashes (else they might be
+URLs). (Thanks to irssi for this criteria list)"
+  (if (string-match "^[^ :/]+\\.[^ :/]* [^ :/]+\\.[^ :/]*$"
+                    reason)
+      t
+    nil))
+
+(let ((simple-format-specifiers
+       '(("INVITE" active "Invite: {origin} invites you to {1}")
+         ("KICK" 0 "Kick: {1} kicked by {origin}: {2}")
+         ("ERROR" active "Error: {0-}")
+         ("001" server "{1}")
+         ("002" server "{1}")
+         ("003" server "{1}")
+         ("004" server "{1-}")
+         ("005" server "{1-}")
+         ;; IRCnet: * Please wait while we process your connection.
+         ("020" server "{0-}")
+         ;; IRCnet
+         ("042" server "Your unique ID is {1}")
+         ("200" active "{1-}")
+         ("201" active "{1-}")
+         ("203" active "{1-}")
+         ("204" active "{1-}")
+         ("205" active "{1-}")
+         ("206" active "{1-}")
+         ("207" active "{1-}")
+         ("208" active "{1-}")
+         ("209" active "{1-}")
+         ("211" active "{1-}")
+         ("212" active "{1-}")
+         ("219" active "{1-}")
+         ("221" active "User mode: {1-}")
+         ("234" active "Service: {1-}")
+         ("235" active "{1-}")
+         ("242" active "{1}")
+         ("243" active "{1-}")
+         ("250" server "{1}")
+         ("251" server "{1}")
+         ("252" server "{1-}")
+         ("253" server "{1-}")
+         ("254" server "{1-}")
+         ("255" server "{1}")
+         ("256" active "{1-}")
+         ("257" active "{1}")
+         ("258" active "{1}")
+         ("259" active "{1}")
+         ("261" active "{1-}")
+         ("262" active "{1-}")
+         ("263" active "{1-}")
+         ("265" server "{1-}")
+         ("266" server "{1-}")
+         ;; This is returned on both WHOIS and PRIVMSG. It
+         ;; should go to the active window for the former, and
+         ;; the query window for the latter. Oh well.
+         ("301" active "User away: {1}")
+         ("302" active "User hosts: {1}")
+         ("303" active "Users online: {1}")
+         ("305" active "{1}")
+         ("306" active "{1}")
+         ("307" active "{1-}")
+         ;; Coldfront: 310 <nick> is available for help.
+         ("310" active "{1-}")
+         ("311" active "{1} is {2}@{3} ({5})")
+         ("312" active "{1} is on {2} ({3})")
+         ("313" active "{1} {2}")
+         ("314" active "{1} was {2}@{3} ({5})")
+         ("315" active "{2}")
+         ("318" active "{2}")
+         ("319" active "{1} is on {2}")
+         ("320" active "{1-}")
+         ("322" active "{1-}")
+         ("323" active "{1-}")
+         ("324" 1 "Channel mode for {1}: {2-}")
+         ("325" 1 "Unique operator on {1} is {2}")
+         ("328" 1 "Channel homepage for {1}: {2-}")
+         ("330" active "{1} is logged in as {2}")
+         ("331" 1 "No topic for {1} set")
+         ("332" 1 "Topic for {1}: {2}")
+         ("341" active "Inviting {1} to {2}")
+         ("346" 1 "Invite mask: {2}")
+         ("347" 1 "{2}")
+         ("348" 1 "Except mask: {2}")
+         ("349" 1 "{2}")
+         ("351" active "{1-}")
+         ("352" active "{5} ({2}@{3}) in {1} on {4}: {6-}")
+         ("353" 2 "Names: {3}")
+         ("364" active "{1-}")
+         ("365" active "{1-}")
+         ("366" 1 "{2}")
+         ("367" 1 "Ban mask: {2}")
+         ("368" 1 "{2}")
+         ("369" active "{1} {2}")
+         ("371" active "{1}")
+         ("372" server "{1}")
+         ("374" active "{1}")
+         ("375" server "{1}")
+         ("376" server "{1}")
+         ("378" active "{1-}")
+         ("381" active "{1}")
+         ("382" active "{1-}")
+         ("391" active "Time on {1}: {2}")
+         ("401" active "No such nick: {1}")
+         ("402" active "No such server: {1}")
+         ("403" active "No such channel: {1}")
+         ("404" 1 "Can not send to channel {1}")
+         ("405" active "Can not join {1}: {2}")
+         ("406" active "{1-}")
+         ("407" active "{1-}")
+         ("408" active "No such service: {1}")
+         ("422" active "{1}")
+         ("432" active "Erroneous nick name: {1}")
+         ("433" active "Nick name in use: {1}")
+         ("437" active "Nick/channel is temporarily unavailable: {1}")
+         ("441" 2 "User not on channel: {1}")
+         ("442" active "You are not on {1}")
+         ("443" 2 "User {1} is already on channel {2}")
+         ;; Coldfront: 451 * :You have not registered
+         ("451" active "{1-}")
+         ("467" 1 "{2}")
+         ("470" 1 "{1} made you join {2}: {3-}")
+         ("471" 1 "{2}")
+         ("472" active "{1-}")
+         ("473" active "{1-}")
+         ("474" active "{1-}")
+         ("475" active "{1-}")
+         ("476" active "{1-}")
+         ("477" active "{1-}")
+         ("481" 1 "{2-}")
+         ("484" active "{1-}")
+         ;; Coldfront: 671 <nick> is using a Secure Connection
+         ("671" active "{1-}")
+         ("728" 1 "Quiet mask: {3}")
+         ("729" 1 "{3-}")
+         ;; Freenode SASL auth
+         ("900" active "SASL: {3-}")
+         ("903" active "{1-}"))))
+  (dolist (fmt simple-format-specifiers)
+    (circe-set-display-handler (car fmt) (cdr fmt))))
+
+(defun circe-set-message-target (command target)
+  "Set the target of COMMAND to TARGET.
+
+This can be used to change format-based display handlers more
+easily."
+  (let ((handler (circe-get-display-handler command)))
+    (when (not (consp handler))
+      (error "Handler of command %s is not a list" command))
+    (setcar handler target)))
+
+;;;;;;;;;;;;;;;;;;;;;;;;
+;;; Helper Functions ;;;
+;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun circe--list-drop-right (list pattern)
+  "Drop elements from the right of LIST that match PATTERN.
+
+LIST should be a list of strings, and PATTERN is used as a
+regular expression."
+  (let ((list (reverse list)))
+    (while (and list
+                (string-match pattern (car list)))
+      (setq list (cdr list)))
+    (nreverse list)))
+
+(defun circe--nick-next (oldnick)
+  "Return a new nick to try for OLDNICK."
+  (cond
+   ;; If the nick ends with -+, replace those with _
+   ((string-match "^\\(.*[^-]\\)\\(-+\\)$" oldnick)
+    (concat (match-string 1 oldnick)
+            (make-string (- (match-end 2)
+                            (match-beginning 2))
+                         ?_)))
+   ;; If the nick is 9 chars long, take prefix and rotate.
+   ((>= (length oldnick)
+        9)
+    (when (string-match "^\\(.*[^-_]\\)[-_]*$" oldnick)
+      (let ((nick (match-string 1 oldnick)))
+        (concat (substring nick 1)
+                (string (aref nick 0))))))
+   ;; If the nick ends with _+ replace those with - and add one
+   ((string-match "^\\(.*[^_]\\)\\(_+\\)$" oldnick)
+    (concat (match-string 1 oldnick)
+            (make-string (- (match-end 2)
+                            (match-beginning 2))
+                         ?-)
+            "-"))
+   ;; Else, just append -
+   (t
+    (concat oldnick "-"))))
+
+(defun circe-duration-string (duration)
+  "Return a description of a DURATION in seconds."
+  (let ((parts `((,(* 12 30 24 60 60) "year")
+                 (,(* 30 24 60 60) "month")
+                 (,(* 24 60 60) "day")
+                 (,(* 60 60) "hour")
+                 (60 "minute")
+                 (1 "second")))
+        (duration (round duration))
+        (result nil))
+    (dolist (part parts)
+      (let* ((seconds-per-part (car part))
+             (description (cadr part))
+             (count (/ duration seconds-per-part)))
+        (when (not (zerop count))
+          (setq result (cons (format "%d %s%s"
+                                     count description
+                                     (if (= count 1) "" "s"))
+                             result)))
+        (setq duration (- duration (* count seconds-per-part)))))
+    (if result
+        (mapconcat #'identity
+                   (nreverse result)
+                   " ")
+      "a moment")))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; Deprecated functions and variables
+
+(define-obsolete-function-alias 'circe-server-nick 'circe-nick
+  "Circe 2.0")
+
+(define-obsolete-function-alias 'circe-server-message
+  'circe-display-server-message
+  "Circe 2.0")
+
+(define-obsolete-variable-alias 'circe-networks 'circe-network-defaults
+  "Circe 2.0")
+
+(define-obsolete-variable-alias 'circe-server-name 'circe-host
+  "Circe 2.0")
+
+(define-obsolete-variable-alias 'circe-server-service 'circe-port
+  "Circe 2.0")
+
+(define-obsolete-variable-alias 'circe-server-network 'circe-network
+  "Circe 2.0")
+
+(define-obsolete-variable-alias 'circe-server-ip-family 'circe-ip-family
+  "Circe 2.0")
+
+(define-obsolete-variable-alias 'circe-server-nick 'circe-nick
+  "Circe 2.0")
+
+(define-obsolete-variable-alias 'circe-server-user 'circe-user
+  "Circe 2.0")
+
+(define-obsolete-variable-alias 'circe-server-pass 'circe-pass
+  "Circe 2.0")
+
+(define-obsolete-variable-alias 'circe-server-realname 'circe-realname
+  "Circe 2.0")
+
+(define-obsolete-variable-alias 'circe-server-use-tls 'circe-use-tls
+  "Circe 2.0")
+
+(define-obsolete-variable-alias 'circe-server-auto-join-channels
+  'circe-channels
+  "Circe 2.0")
+
+(provide 'circe)
+;;; circe.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/circe.elc b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/circe.elc
new file mode 100644
index 0000000000..110eafbad7
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/circe.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/irc.el b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/irc.el
new file mode 100644
index 0000000000..04b260c75a
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/irc.el
@@ -0,0 +1,1413 @@
+;;; irc.el --- Library to handle IRC connections -*- lexical-binding: t -*-
+
+;; Copyright (C) 2015  Jorgen Schaefer <contact@jorgenschaefer.de>
+
+;; Author: Jorgen Schaefer <contact@jorgenschaefer.de>
+;; URL: https://github.com/jorgenschaefer/circe
+
+;; This program 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.
+
+;; This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; The main entry function is `irc-connect'. This creates a new
+;; connection to an IRC server, and also takes an event handler table
+;; which is used to run various event handlers. Handlers receive a
+;; connection object which can be used for other API calls.
+
+;; IRC connection objects also accept connection options. These can be
+;; queried using `irc-connection-get', and are set by `irc-connect' or
+;; later using `irc-connection-put'.
+
+;; Event handler tables are simple maps of names to functions. See
+;; `irc-handler-table', `irc-handler-add' and `irc-handler-run' for
+;; the API.
+
+;; To send commands to the server, use `irc-send-raw' or
+;; `irc-send-command'.
+
+;; The rest of the library are handler packs that add support for
+;; various IRC features.
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'make-tls-process)
+
+(defvar irc-debug-log nil
+  "Emit protocol debug info if this is non-nil.")
+
+;;;;;;;;;;;;;;;;;;;;;;;
+;;; Connection function
+
+(defun irc-connect (&rest keywords)
+  "Connect to an IRC server.
+
+Supported keyword arguments:
+
+:name NAME -- The name for the process
+:host HOST -- The host to connect to
+:service SERVICE -- The service or port to connect to
+:tls BOOL -- Whether to use TLS
+:family IP-FAMILY -- Force using of ipv4 or ipv6
+:handler-table HANDLER -- The event handler table to send events to.
+
+The following events are supported:
+
+conn.connected conn -- The connection was established
+conn.failed conn -- The connection could not be established
+conn.disconnected conn -- A previously established connection was lost
+
+NNN conn sender args... -- A numeric reply from IRC was received
+COMMAND conn sender args... -- An IRC command message was received"
+  (let ((proc (funcall (if (plist-get keywords :tls)
+                           #'make-tls-process
+                         #'make-network-process)
+                       :name (or (plist-get keywords :name)
+                                 (plist-get keywords :host))
+                       :host (or (plist-get keywords :host)
+                                 (error "Must specify a :host to connect to"))
+                       :service (or (plist-get keywords :service)
+                                    (error "Must specify a :service to connect to"))
+                       :family (plist-get keywords :family)
+                       :coding 'no-conversion
+                       :nowait (featurep 'make-network-process '(:nowait t))
+                       :noquery t
+                       :filter #'irc--filter
+                       :sentinel #'irc--sentinel
+                       :plist keywords
+                       :keepalive t)))
+    ;; When we used `make-network-process' without :nowait, the
+    ;; sentinel is not called with the open event, so we do this
+    ;; manually.
+    (when (eq (process-status proc) 'open)
+      (irc--sentinel proc "open manually"))
+    proc))
+
+(defun irc-connection-get (conn propname)
+  "Return the value of CONN's PROPNAME property."
+  (process-get conn propname))
+
+(defun irc-connection-put (conn propname value)
+  "Change CONN's PROPNAME property to VALUE."
+  (process-put conn propname value))
+
+(defun irc--sentinel (proc event)
+  (cond
+   ((string-match "\\`failed" event)
+    (irc-event-emit proc "conn.failed"))
+   ((string-match "\\`open" event)
+    (irc-event-emit proc "conn.connected"))
+   ((string-match "\\`\\(connection broken\\|finished\\|exited abnormally\\)"
+                  event)
+    (irc-event-emit proc "conn.disconnected"))
+   ((string-match "\\`\\(deleted\\|killed\\)" event)
+    nil)
+   (t
+    (error "Unknown event in IRC sentinel: %S" event))))
+
+(defvar irc--filter-running-p nil
+  "Non-nil when we're currently processing a message.
+
+Yep, this is a mutex. Why would one need a mutex in Emacs, a
+single-threaded application, you ask? Easy!
+
+When, during the execution of a process filter, any piece of code
+waits for process output - e.g. because they started a some
+external program - Emacs will process any input from external
+processes. Including the one for the filter that is currently
+running.
+
+If that process does emit output, the filter is run again, while
+it is already running. If the filter is not careful, this can
+cause data to arrive out of order, or get lost.")
+
+(defun irc--filter (proc data)
+  "Handle data from the process."
+  (irc-connection-put proc :conn-data
+                      (concat (or (irc-connection-get proc :conn-data)
+                                  "")
+                              data))
+  (when (not irc--filter-running-p)
+    (let ((irc--filter-running-p t)
+          (data (irc-connection-get proc :conn-data)))
+      (while (string-match "\r?\n" data)
+        (let ((line (substring data 0 (match-beginning 0))))
+          (setq data (substring data (match-end 0)))
+          (irc-connection-put proc :conn-data data)
+          (irc--handle-line proc line)
+          (setq data (irc-connection-get proc :conn-data)))))))
+
+(defun irc--handle-line (proc line)
+  "Handle a single line from the IRC server.
+
+The command is simply passed to the event handler of the IRC
+connection."
+  (irc-debug-out proc "S: %s" line)
+  (let* ((parsed (irc--parse line))
+         (sender (car parsed))
+         (command (cadr parsed))
+         (args (cddr parsed)))
+    (apply #'irc-event-emit proc command sender args)))
+
+(defun irc--parse (line)
+  "Parse a line from IRC.
+
+Returns a list: (sender command args...)
+
+A line from IRC is a space-separated list of arguments. If the
+first word starts with a colon, that's the sender. The first or
+second word is the command. All further words are arguments. The
+first word to start with a colon ends the argument list.
+
+Examples:
+
+COMMAND
+COMMAND arg
+COMMAND arg1 arg2
+COMMAND arg1 arg2 :arg3 still arg3
+:sender COMMAND arg1 arg2 :arg3 still arg3"
+  (with-temp-buffer
+    (insert line)
+    (goto-char (point-min))
+    (let ((sender nil)
+          (args nil))
+      ;; Optional sender.
+      (when (looking-at ":\\([^ ]+\\) ")
+        (setq sender (decode-coding-string
+                      (match-string 1)
+                      'undecided))
+        (goto-char (match-end 0)))
+
+      ;; COMMAND.
+      (unless (looking-at "\\([^ ]+\\)")
+        (error "Invalid message: %s" line))
+      (push (decode-coding-string (match-string 1) 'undecided)
+            args)
+      (goto-char (match-end 0))
+
+      ;; Arguments.
+      (while (re-search-forward " :\\(.*\\)\\| \\([^ ]*\\)" nil t)
+        (push (decode-coding-string
+               (or (match-string 1)
+                   (match-string 2))
+               'undecided)
+              args))
+
+      (cons sender (nreverse args)))))
+
+(defun irc-userstring-nick (userstring)
+  "Return the nick in a given USERSTRING.
+
+USERSTRING is a typical nick!user@host prefix as used by IRC."
+  (if (string-match "\\`\\([^!]+\\)!\\([^@]+\\)@\\(.*\\)\\'" userstring)
+      (match-string 1 userstring)
+    userstring))
+
+(defun irc-userstring-userhost (userstring)
+  "Return the nick in a given USERSTRING.
+
+USERSTRING is a typical nick!user@host prefix as used by IRC."
+  (if (string-match "\\`\\([^!]+\\)!\\([^@]+@.*\\)\\'" userstring)
+      (match-string 2 userstring)
+    nil))
+
+(defun irc-event-emit (conn event &rest args)
+  "Run the event handlers for EVENT in CONN with ARGS."
+  (irc-debug-out conn
+                 "E: %S %s"
+                 event
+                 (mapconcat (lambda (elt) (format "%S" elt))
+                            args
+                            " "))
+  (let ((handler-table (irc-connection-get conn :handler-table)))
+    (when handler-table
+      (apply #'irc-handler-run handler-table event conn event args)
+      (apply #'irc-handler-run handler-table nil conn event args))))
+
+;;;;;;;;;;;;;;;;;;;;;;;
+;;; Event handler table
+
+(defun irc-handler-table ()
+  "Return a new event handler table."
+  (make-hash-table :test 'equal))
+
+(defun irc-handler-add (table event handler)
+  "Add HANDLER for EVENT to the event handler table TABLE."
+  (puthash event
+           (append (gethash event table)
+                   (list handler))
+           table))
+
+(defun irc-handler-remove (table event handler)
+  "Remove HANDLER for EVENT to the event handler table TABLE."
+  (puthash event
+           (delete handler
+                   (gethash event table))
+           table))
+
+(defun irc-handler-run (table event &rest args)
+  "Run the handlers for EVENT in TABLE, passing ARGS to each."
+  (dolist (handler (gethash event table))
+    (if debug-on-error
+        (apply handler args)
+      (condition-case err
+          (apply handler args)
+        (error
+         (message "Error running event %S handler %S: %S (args were %S)"
+                  event handler err args))))))
+
+;;;;;;;;;;;
+;;; Sending
+
+(defun irc-send-raw (conn line &optional flood-handling)
+  "Send a line LINE to the IRC connection CONN.
+
+LINE should not include the trailing newline.
+
+FLOOD-HANDLING defines how to handle the situation when we are
+sending too  much data. It can have three values:
+
+nil -- Add the message to a queue and send it later
+:nowait -- Send the message immediately, circumventing flood protection
+:drop -- Send the message only if we are not flooding, and drop it if
+   we have queued up messages.
+
+The flood protection algorithm works like the one detailed in RFC
+2813, section 5.8 \"Flood control of clients\".
+
+  * If `flood-last-message' is less than the current
+    time, set it equal.
+  * While `flood-last-message' is less than `flood-margin'
+    seconds ahead of the current time, send a message, and
+    increase `flood-last-message' by `flood-penalty'."
+  (cond
+   ((null flood-handling)
+    (irc-connection-put conn
+                        :flood-queue
+                        (append (irc-connection-get conn :flood-queue)
+                                (list line)))
+    (irc-send--queue conn))
+   ((eq flood-handling :nowait)
+    (irc-send--internal conn line))
+   ((eq flood-handling :drop)
+    (let ((queue (irc-connection-get conn :flood-queue)))
+      (when (not queue)
+        (irc-connection-put conn :flood-queue (list line))
+        (irc-send--queue conn))))))
+
+(defun irc-send--queue (conn)
+  "Send messages from the flood queue in CONN.
+
+See `irc-send-raw' for the algorithm."
+  (let ((queue (irc-connection-get conn :flood-queue))
+        (last-message (or (irc-connection-get conn :flood-last-message)
+                          0))
+        (margin (or (irc-connection-get conn :flood-margin)
+                    10))
+        (penalty (or (irc-connection-get conn :flood-penalty)
+                     3))
+        (now (float-time)))
+    (when (< last-message now)
+      (setq last-message now))
+    (while (and queue
+                (< last-message (+ now margin)))
+      (irc-send--internal conn (car queue))
+      (setq queue (cdr queue)
+            last-message (+ last-message penalty)))
+    (irc-connection-put conn :flood-queue queue)
+    (irc-connection-put conn :flood-last-message last-message)
+    (let ((timer (irc-connection-get conn :flood-timer)))
+      (when timer
+        (cancel-timer timer)
+        (irc-connection-put conn :flood-timer nil))
+      (when queue
+        (irc-connection-put conn
+                            :flood-timer
+                            (run-at-time 1 nil #'irc-send--queue conn))))))
+
+(defun irc-send--internal (conn line)
+  "Send LINE to CONN."
+  (irc-debug-out conn "C: %s" line)
+  (process-send-string conn
+                       (concat (encode-coding-string line 'utf-8)
+                               "\r\n")))
+
+(defun irc-send-command (conn command &rest args)
+  "Send COMMAND with ARGS to IRC connection CONN."
+  (irc-send-raw conn (apply #'irc--format-command command args)))
+
+(defun irc--format-command (command &rest args)
+  "Format COMMAND and ARGS for IRC.
+
+The last value in ARGS will be escaped with a leading colon if it
+contains a space. All other arguments are checked to make sure
+they do not contain a space."
+  (dolist (arg (cons command args))
+    (when (not (stringp arg))
+      (error "Argument must be a string")))
+  (let* ((prefix (cons command (butlast args)))
+         (last (last args)))
+    (dolist (arg prefix)
+      (when (string-match " " arg)
+        (error "IRC protocol error: Argument %S must not contain space"
+               arg)))
+    (when (and last (or (string-match " " (car last))
+                        (string-match "^:" (car last))
+                        (equal "" (car last))))
+      (setcar last (concat ":" (car last))))
+    (mapconcat #'identity
+               (append prefix last)
+               " ")))
+
+(defun irc-send-AUTHENTICATE (conn arg)
+  "Send an AUTHENTICATE message with ARG.
+
+See https://github.com/atheme/charybdis/blob/master/doc/sasl.txt
+for details."
+  (irc-send-command conn "AUTHENTICATE" arg))
+
+(defun irc-send-AWAY (conn &optional reason)
+  "Mark yourself as AWAY with reason REASON, or back if reason is nil."
+  (if reason
+      (irc-send-command conn "AWAY" reason)
+    (irc-send-command conn "AWAY")))
+
+(defun irc-send-CAP (conn &rest args)
+  "Send a CAP message.
+
+See https://tools.ietf.org/html/draft-mitchell-irc-capabilities-01
+for details."
+  (apply #'irc-send-command conn "CAP" args))
+
+(defun irc-send-INVITE (conn nick channel)
+  "Invite NICK to CHANNEL."
+  (irc-send-command conn "INVITE" nick channel))
+
+(defun irc-send-JOIN (conn channel &optional key)
+  "Join CHANNEL.
+
+If KEY is given, use it to join the password-protected channel."
+  (if key
+      (irc-send-command conn "JOIN" channel key)
+    (irc-send-command conn "JOIN" channel)))
+
+(defun irc-send-NAMES (conn &optional channel)
+  "Retrieve user names from the server, optionally limited to CHANNEL."
+  (if channel
+      (irc-send-command conn "NAMES" channel)
+    (irc-send-command conn "NAMES")))
+
+(defun irc-send-NICK (conn nick)
+  "Change your own nick to NICK."
+  (irc-send-command conn "NICK" nick))
+
+(defun irc-send-NOTICE (conn msgtarget text-to-be-sent)
+  "Send a private notice containing TEXT-TO-BE-SENT to MSGTARGET.
+
+MSGTARGET can be either a nick or a channel."
+  (irc-send-command conn "NOTICE" msgtarget text-to-be-sent))
+
+(defun irc-send-PART (conn channel reason)
+  "Leave CHANNEL with reason REASON."
+  (irc-send-command conn "PART" channel reason))
+
+(defun irc-send-PASS (conn password)
+  "Authenticate to the server using PASSWORD."
+  (irc-send-command conn "PASS" password))
+
+(defun irc-send-PONG (conn server)
+  "Respond to a PING message."
+  (irc-send-raw conn
+                (irc--format-command "PONG" server)
+                :nowait))
+
+(defun irc-send-PRIVMSG (conn msgtarget text-to-be-sent)
+  "Send a private message containing TEXT-TO-BE-SENT to MSGTARGET.
+
+MSGTARGET can be either a nick or a channel."
+  (irc-send-command conn "PRIVMSG" msgtarget text-to-be-sent))
+
+(defun irc-send-QUIT (conn reason)
+  "Leave IRC with reason REASON."
+  (irc-send-command conn "QUIT" reason))
+
+(defun irc-send-TOPIC (conn channel &optional new-topic)
+  "Retrieve or set the topic of CHANNEL
+
+If NEW-TOPIC is given, set this as the new topic. If it is
+omitted, retrieve the current topic."
+  (if new-topic
+      (irc-send-command conn "TOPIC" channel new-topic)
+    (irc-send-command conn "TOPIC" channel)))
+
+(defun irc-send-USER (conn user mode realname)
+  "Send a USER message for registration.
+
+MODE should be an integer as per RFC 2812"
+  (irc-send-command conn "USER" user (format "%s" mode) "*" realname))
+
+(defun irc-send-WHOIS (conn target &optional server-or-name)
+  "Retrieve current whois information on TARGET."
+  (if server-or-name
+      (irc-send-command conn "WHOIS" target server-or-name)
+    (irc-send-command conn "WHOIS" target)))
+
+(defun irc-send-WHOWAS (conn target)
+  "Retrieve past whois information on TARGET."
+  (irc-send-command conn "WHOWAS" target))
+
+(defun irc-send-STATS (conn query &optional server)
+  "Return statistics on current server, or SERVER if it is specified."
+  (if server
+      (irc-send-command conn "STATS" query server)
+    (irc-send-command conn "STATS" query)))
+
+;;;;;;;;;;;;;;;
+;;; Debug stuff
+
+(defun irc-debug-out (conn fmt &rest args)
+  (when irc-debug-log
+    (let ((name (format "*IRC Protocol %s:%s*"
+                        (irc-connection-get conn :host)
+                        (irc-connection-get conn :service))))
+      (with-current-buffer (get-buffer-create name)
+        (save-excursion
+          (goto-char (point-max))
+          (insert (apply #'format fmt args) "\n"))))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; Handler: Registration
+
+(defun irc-handle-registration (table)
+  "Add command handlers to TABLE to handle registration.
+
+This will send the usual startup messages after we are connected.
+
+Events emitted:
+
+\"irc.registered\" current-nick -- We have successfully
+  registered with the IRC server. Most commands can be used now.
+  In particular, joining channels is only possible now.
+
+\"sasl.login\" nick!user@host account -- SASL log in was
+  successful.
+
+Connection options used:
+
+:nick -- The nick to use to register with the server
+:user -- The user name to use
+:mode -- The initial mode to use; an integer. See RFC 2812 for
+   the meaning.
+:realname -- The realname to use for the registration
+:pass -- The server password to send
+:cap-req -- CAP protocol capabilities to request, if available
+:sasl-username -- The SASL username to send, if sasl is available
+:sasl-password -- The SASL password to send, if sasl is available
+
+Connection options set:
+
+:connection-state -- One of nil, connected, registered, disconnected
+  See `irc-connection-state' for an interface to this.
+:cap-supported-p -- Non-nil if the server supports the CAP protocol
+:cap-ack -- The list of active capabilities negotiated with the server"
+  (irc-handler-add table "conn.connected"
+                   #'irc-handle-registration--connected)
+  (irc-handler-add table "conn.disconnected"
+                   #'irc-handle-registration--disconnected)
+  (irc-handler-add table "001" ;; RPL_WELCOME
+                   #'irc-handle-registration--rpl-welcome)
+  (irc-handler-add table "CAP"
+                   #'irc-handle-registration--cap)
+  (irc-handler-add table "AUTHENTICATE"
+                   #'irc-handle-registration--authenticate)
+  (irc-handler-add table "900" ;; RPL_LOGGEDIN
+                   #'irc-handle-registration--logged-in))
+
+(defun irc-handle-registration--connected (conn _event)
+  (irc-connection-put conn :connection-state 'connected)
+  (when (irc-connection-get conn :cap-req)
+    (irc-send-CAP conn "LS"))
+  (let ((password (irc-connection-get conn :pass)))
+    (when password
+      (irc-send-PASS conn password)))
+  (irc-send-NICK conn (irc-connection-get conn :nick))
+  (irc-send-USER conn
+                 (irc-connection-get conn :user)
+                 (irc-connection-get conn :mode)
+                 (irc-connection-get conn :realname)))
+
+(defun irc-handle-registration--disconnected (conn _event)
+  (irc-connection-put conn :connection-state 'disconnected))
+
+(defun irc-handle-registration--rpl-welcome (conn _event _sender target
+                                                  &rest ignored)
+  (irc-connection-put conn :connection-state 'registered)
+  (irc-event-emit conn "irc.registered" target))
+
+(defun irc-handle-registration--cap (conn _event _sender _target
+                                          subcommand arg)
+  (cond
+   ((equal subcommand "LS")
+    (let ((supported (split-string arg))
+          (wanted nil))
+      (dolist (cap (irc-connection-get conn :cap-req))
+        (when (member cap supported)
+          (setq wanted (append wanted (list cap)))))
+      (if wanted
+          (irc-send-CAP conn "REQ" (mapconcat #'identity wanted " "))
+        (irc-send-CAP conn "END"))))
+   ((equal subcommand "ACK")
+    (let ((acked (split-string arg)))
+      (irc-connection-put conn :cap-ack acked)
+      (if (and (member "sasl" acked)
+               (irc-connection-get conn :sasl-username)
+               (irc-connection-get conn :sasl-password))
+          (irc-send-AUTHENTICATE conn "PLAIN")
+        (irc-send-CAP conn "END"))))
+   (t
+    (message "Unknown CAP response from server: %s %s" subcommand arg))))
+
+(defun irc-handle-registration--authenticate (conn _event _sender arg)
+  (if (equal arg "+")
+      (let ((username (irc-connection-get conn :sasl-username))
+            (password (irc-connection-get conn :sasl-password)))
+        (irc-send-AUTHENTICATE conn (base64-encode-string
+                                     (format "%s\x00%s\x00%s"
+                                             username username password)))
+        (irc-send-CAP conn "END"))
+    (message "Unknown AUTHENTICATE response from server: %s" arg)))
+
+(defun irc-handle-registration--logged-in (conn _event _sender _target
+                                                userhost account _message)
+  (irc-event-emit conn "sasl.login" userhost account))
+
+(defun irc-connection-state (conn)
+  "connecting connected registered disconnected"
+  (let ((state (irc-connection-get conn :connection-state)))
+    (if (null state)
+        'connecting
+      state)))
+
+;;;;;;;;;;;;;;;;;;;;;;
+;;; Handler: Ping-Pong
+
+(defun irc-handle-ping-pong (table)
+  "Add command handlers to respond to PING requests."
+  (irc-handler-add table "PING" #'irc-handle-ping-pong--ping))
+
+(defun irc-handle-ping-pong--ping (conn _event _sender argument)
+  (irc-send-PONG conn argument))
+
+;;;;;;;;;;;;;;;;;;;;;
+;;; Handler: ISUPPORT
+
+(defun irc-handle-isupport (table)
+  "Add command handlers to track 005 RPL_ISUPPORT capabilities."
+  (irc-handler-add table "005" #'irc-handle-isupport--005))
+
+(defun irc-handle-isupport--005 (conn _event _sender _target &rest args)
+  (irc-connection-put
+   conn :isupport
+   (append (irc-connection-get conn :isupport)
+           (irc-handle-isupport--capabilities-to-alist args))))
+
+(defun irc-handle-isupport--capabilities-to-alist (capabilities)
+  (mapcar (lambda (cap)
+            (if (string-match "\\`\\([^=]+\\)=\\(.*\\)\\'" cap)
+                (cons (match-string 1 cap)
+                      (match-string 2 cap))
+              (cons cap t)))
+          capabilities))
+
+(defun irc-isupport (conn capability)
+  "Return the value of CAPABILITY of CONN.
+
+These capabilities are set when the server sends a 005
+RPL_ISUPPORT message. The return value is either the value of the
+capability, or t if it is a boolean capability that is present.
+If the capability is not present, the return value is nil."
+  (cdr (assoc capability
+              (irc-connection-get conn :isupport))))
+
+(defun irc-string-equal-p (conn s1 s2)
+  "Compare S1 to S2 case-insensitively.
+
+What case means is defined by the server of CONN."
+  (equal (irc-isupport--case-fold conn s1)
+         (irc-isupport--case-fold conn s2)))
+
+(defvar irc-isupport--ascii-table
+  (let ((table (make-string 128 0))
+        (char 0))
+    (while (<= char 127)
+      (if (and (<= ?A char)
+               (<= char ?Z))
+          (aset table char (+ char (- ?a ?A)))
+        (aset table char char))
+      (setq char (1+ char)))
+    table)
+  "A case mapping table for the ascii CASEMAPPING.")
+
+(defvar irc-isupport--rfc1459-table
+  (let ((table (concat irc-isupport--ascii-table)))  ; copy string
+    (aset table ?\[ ?\{)
+    (aset table ?\] ?\})
+    (aset table ?\\ ?\|)
+    (aset table ?^ ?\~)
+    table)
+  "A case mapping table for the rfc1459 CASEMAPPING.")
+
+(defvar irc-isupport--rfc1459-strict-table
+  (let ((table (concat irc-isupport--ascii-table)))  ; copy string
+    (aset table ?\[ ?\{)
+    (aset table ?\] ?\})
+    (aset table ?\\ ?\|)
+    table)
+  "A case mapping table for the rfc1459-strict CASEMAPPING.")
+
+(defun irc-isupport--case-fold (conn s)
+  "Translate S to be a lower-case.
+
+This uses the case mapping defined by the IRC server for CONN."
+  (with-temp-buffer
+    (insert s)
+    (let ((mapping (or (irc-isupport conn "CASEMAPPING")
+                       "rfc1459")))
+      (cond
+       ((equal mapping "rfc1459")
+        (translate-region (point-min)
+                          (point-max)
+                          irc-isupport--rfc1459-table))
+       ((equal mapping "ascii")
+        (translate-region (point-min)
+                          (point-max)
+                          irc-isupport--ascii-table))
+       ((equal mapping "rfc1459-strict")
+        (translate-region (point-min)
+                          (point-max)
+                          irc-isupport--rfc1459-strict-table))))
+    (buffer-string)))
+
+(defun irc-channel-name-p (conn string)
+  "True iff STRING is a valid channel name for CONN.
+
+This depends on the CHANTYPES setting set by the server of CONN."
+  (let ((chantypes (string-to-list
+                    (or (irc-isupport conn "CHANTYPES")
+                        "#"))))
+    (if (and (> (length string) 0)
+             (member (aref string 0) chantypes))
+        t
+      nil)))
+
+(defun irc-nick-without-prefix (conn nick)
+  "Return NICK without any mode prefixes.
+
+For example, a user with op status might be shown as @Nick. This
+function would return Nick without the prefix. This uses the 005
+RPL_ISUPPORT setting of PREFIX set by the IRC server for CONN."
+  (let ((prefixes (irc-connection-get conn :nick-prefixes)))
+    (when (not prefixes)
+      (let ((prefix-string (or (irc-isupport conn "PREFIX")
+                               "(qaohv)~&@%+")))
+        (setq prefixes (string-to-list
+                        (if (string-match "(.*)\\(.*\\)" prefix-string)
+                            (match-string 1 prefix-string)
+                          "~&@%+")))
+        (irc-connection-put conn :nick-prefixes prefixes)))
+    (while (and (> (length nick) 0)
+                (member (aref nick 0) prefixes))
+      (setq nick (substring nick 1)))
+    nick))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; Handler: Initial nick acquisition
+
+(defun irc-handle-initial-nick-acquisition (table)
+  "Track the current nick of the user.
+
+Connection options used:
+
+:nick-alternatives -- A list of nicks to try if the first attempt
+  does not succeed."
+  (irc-handler-add table "432" ;; ERR_ERRONEUSNICKNAME
+                   #'irc-handle-initial-nick-acquisition--get-initial-nick)
+  (irc-handler-add table "433" ;; ERR_NICKNAMEINUSE
+                   #'irc-handle-initial-nick-acquisition--get-initial-nick)
+  (irc-handler-add table "437" ;; ERR_UNAVAILRESOURCE
+                   #'irc-handle-initial-nick-acquisition--get-initial-nick))
+
+(defun irc-handle-initial-nick-acquisition--get-initial-nick
+    (conn _event _sender current-nick _attempted-nick _reason)
+  (when (equal current-nick "*")
+    (let ((alternatives (irc-connection-get conn :nick-alternatives)))
+      (if (not alternatives)
+          (irc-send-NICK conn (irc-generate-nick))
+        (irc-connection-put conn :nick-alternatives (cdr alternatives))
+        (irc-send-NICK conn (car alternatives))))))
+
+(defun irc-generate-nick ()
+  "Return a random, valid IRC nick name.
+
+Valid nick names are at least (RFC 1459):
+
+<nick>       ::= <letter> { <letter> | <number> | <special> }
+<special>    ::= '-' | '[' | ']' | '\' | '`' | '^' | '{' | '}'"
+  (let ((chars "abcdefghijklmnopqrstuvwxyz"))
+    (mapconcat (lambda (_)
+                 (make-string 1 (aref chars (random (length chars)))))
+               (make-string 9 0)
+               "")))
+
+;;;;;;;;;;;;;;;;;
+;;; Handler: CTCP
+
+(defun irc-handle-ctcp (table)
+  "Add command handlers to TABLE to handle the CTCP protocol.
+
+Connection options used:
+
+:ctcp-version -- The response to a CTCP VERSION request.
+:ctcp-clientinfo -- The response to a CTCP CLIENTINFO request.
+:ctcp-source -- The response to a CTCP SOURCE request.
+
+Events emitted:
+
+\"irc.message\" sender target body -- A non-CTCP PRIVMSG
+\"irc.notice\" sender target body -- A non-CTCP NOTICE
+\"irc.ctcp\" sender target verb argument -- A CTCP request. ARGUMENT
+  can be nil if there was no argument, or the empty string if the
+  argument was empty.
+\"irc.ctcpreply\" sender target verb argument -- A CTCP reply.
+  ARGUMENT is similar to above.
+\"irc.ctcp.VERB\" sender target argument -- A CTCP request of
+  this specific type.
+\"irc.ctcpreply.VERB\" sender target argument -- A CTCP reply of
+  this specific type."
+  (irc-handler-add table "PRIVMSG"
+                   #'irc-handle-ctcp--privmsg)
+  (irc-handler-add table "irc.ctcp"
+                   #'irc-handle-ctcp--ctcp)
+  (irc-handler-add table "NOTICE"
+                   #'irc-handle-ctcp--notice)
+  (irc-handler-add table "irc.ctcpreply"
+                   #'irc-handle-ctcp--ctcpreply)
+  (irc-handler-add table "irc.ctcp.VERSION"
+                   #'irc-handle-ctcp--ctcp-version)
+  (irc-handler-add table "irc.ctcp.CLIENTINFO"
+                   #'irc-handle-ctcp--ctcp-clientinfo)
+  (irc-handler-add table "irc.ctcp.SOURCE"
+                   #'irc-handle-ctcp--ctcp-source)
+  (irc-handler-add table "irc.ctcp.PING"
+                   #'irc-handle-ctcp--ctcp-ping)
+  (irc-handler-add table "irc.ctcp.TIME"
+                   #'irc-handle-ctcp--ctcp-time)
+  )
+
+(defun irc-handle-ctcp--privmsg (conn _event sender target body)
+  (if (string-match "\\`\x01\\([^ ]+\\)\\(?: \\(.*\\)\\)?\x01\\'"
+                    body)
+      (irc-event-emit conn "irc.ctcp" sender target
+                      (match-string 1 body)
+                      (match-string 2 body))
+    (irc-event-emit conn "irc.message" sender target body)))
+
+(defun irc-handle-ctcp--ctcp (conn _event sender target verb argument)
+  (irc-event-emit conn
+                  (format "irc.ctcp.%s" (upcase verb))
+                  sender
+                  target
+                  argument))
+
+(defun irc-handle-ctcp--notice (conn _event sender target body)
+  (if (string-match "\\`\x01\\([^ ]+\\)\\(?: \\(.*\\)\\)?\x01\\'"
+                    body)
+      (irc-event-emit conn "irc.ctcpreply" sender target
+                      (match-string 1 body)
+                      (match-string 2 body))
+    (irc-event-emit conn "irc.notice" sender target body)))
+
+(defun irc-handle-ctcp--ctcpreply (conn _event sender target verb argument)
+  (irc-event-emit conn
+                  (format "irc.ctcpreply.%s" (upcase verb))
+                  sender
+                  target
+                  argument))
+
+(defun irc-handle-ctcp--ctcp-version (conn _event sender _target _argument)
+  (let ((version (irc-connection-get conn :ctcp-version)))
+    (when version
+      (irc-send-ctcpreply conn
+                          (irc-userstring-nick sender)
+                          "VERSION"
+                          version))))
+
+(defun irc-handle-ctcp--ctcp-clientinfo (conn _event sender _target _argument)
+  (let ((clientinfo (irc-connection-get conn :ctcp-clientinfo)))
+    (when clientinfo
+      (irc-send-ctcpreply conn
+                          (irc-userstring-nick sender)
+                          "CLIENTINFO"
+                          clientinfo))))
+
+(defun irc-handle-ctcp--ctcp-source (conn _event sender _target _argument)
+  (let ((source (irc-connection-get conn :ctcp-source)))
+    (when source
+      (irc-send-ctcpreply conn
+                          (irc-userstring-nick sender)
+                          "SOURCE"
+                          source))))
+
+(defun irc-handle-ctcp--ctcp-ping (conn _event sender _target argument)
+  (when argument
+    (irc-send-ctcpreply conn
+                        (irc-userstring-nick sender)
+                        "PING"
+                        argument)))
+
+(defun irc-handle-ctcp--ctcp-time (conn _event sender _target _argument)
+  (irc-send-ctcpreply conn
+                      (irc-userstring-nick sender)
+                      "TIME"
+                      (current-time-string)))
+
+(defun irc-send-ctcp (conn target verb &optional argument)
+  "Send a CTCP VERB request to TARGET, optionally with ARGUMENT."
+  (irc-send-PRIVMSG conn
+                    target
+                    (format "\x01%s%s\x01"
+                            verb
+                            (if argument
+                                (concat " " argument)
+                              ""))))
+
+(defun irc-send-ctcpreply (conn target verb &optional argument)
+  "Send a CTCP VERB reply to TARGET, optionally with ARGUMENT."
+  (irc-send-raw conn
+                (irc--format-command "NOTICE"
+                                     target
+                                     (format "\x01%s%s\x01"
+                                             verb
+                                             (if argument
+                                                 (concat " " argument)
+                                               "")))
+                :drop))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; Handler: State tracking
+
+(defun irc-handle-state-tracking (table)
+  "Add command handlers to TABLE to track the IRC state.
+
+Connection options used:
+
+:current-nick -- The current nick, or nil if not known/set yet.
+
+Use helper functions to access the information tracked by this
+handler:
+
+- `irc-current-nick'
+- `irc-current-nick-p'
+
+Events emitted:
+
+\"channel.quit\" sender channel reason -- A user quit IRC and
+    left this channel that way."
+  (irc-handler-add table "001" ;; RPL_WELCOME
+                   #'irc-handle-state-tracking--rpl-welcome)
+  (irc-handler-add table "JOIN"
+                   #'irc-handle-state-tracking--JOIN)
+  (irc-handler-add table "PART"
+                   #'irc-handle-state-tracking--PART)
+  (irc-handler-add table "KICK"
+                   #'irc-handle-state-tracking--KICK)
+  (irc-handler-add table "QUIT"
+                   #'irc-handle-state-tracking--QUIT)
+  (irc-handler-add table "NICK"
+                   #'irc-handle-state-tracking--NICK)
+  (irc-handler-add table "PRIVMSG"
+                   #'irc-handle-state-tracking--PRIVMSG)
+  (irc-handler-add table "353" ;; RPL_NAMREPLY
+                   #'irc-handle-state-tracking--rpl-namreply)
+  (irc-handler-add table "366" ;; RPL_ENDOFNAMES
+                   #'irc-handle-state-tracking--rpl-endofnames)
+
+  (irc-handler-add table "TOPIC"
+                   #'irc-handle-state-tracking--TOPIC)
+  (irc-handler-add table "331" ;; RPL_NOTOPIC
+                   #'irc-handle-state-tracking--rpl-notopic)
+  (irc-handler-add table "332" ;; RPL_TOPIC
+                   #'irc-handle-state-tracking--rpl-topic)
+  )
+
+(cl-defstruct irc-channel
+  name
+  topic
+  last-topic
+  folded-name
+  users
+  recent-users
+  receiving-names
+  connection)
+
+(defun irc-channel-from-name (conn name)
+  "Create a new IRC channel object on CONN, named NAME."
+  (make-irc-channel :name name
+                    :folded-name (irc-isupport--case-fold conn name)
+                    :users (make-hash-table :test 'equal)
+                    :recent-users (make-hash-table :test 'equal)
+                    :connection conn))
+
+(defun irc-connection-channel (conn channel-name)
+  "Return the channel object for CHANNEL-NAME on CONN."
+  (let ((channel-table (irc--connection-channel-table conn))
+        (folded-name (irc-isupport--case-fold conn channel-name)))
+    (gethash folded-name channel-table)))
+
+(defun irc-connection-channel-list (conn)
+  "Return the list of channel object on CONN."
+  (let ((channel-list nil))
+    (maphash (lambda (_folded-name channel)
+               (push channel channel-list))
+             (irc--connection-channel-table conn))
+    channel-list))
+
+(defun irc-connection-add-channel (conn channel-name)
+  "Add CHANNEL-NAME to the channel table of CONN."
+  (let* ((channel-table (irc--connection-channel-table conn))
+         (channel (irc-channel-from-name conn channel-name))
+         (folded-name (irc-channel-folded-name channel)))
+    (when (not (gethash folded-name channel-table))
+      (puthash folded-name channel channel-table))))
+
+(defun irc-connection-remove-channel (conn channel-name)
+  "Remove CHANNEL-NAME from the channel table of CONN."
+  (let* ((channel-table (irc--connection-channel-table conn))
+         (folded-name (irc-isupport--case-fold conn channel-name)))
+    (remhash folded-name channel-table)))
+
+(defun irc-current-nick (conn)
+  "Return the current nick on IRC connection CONN, or nil if not set yet."
+  (irc-connection-get conn :current-nick))
+
+(defun irc-current-nick-p (conn nick)
+  "Return t if NICK is our current nick on IRC connection CONN."
+  (let ((current-nick (irc-current-nick conn)))
+    (if (and (stringp nick)
+             (stringp current-nick))
+        (irc-string-equal-p conn current-nick nick)
+      nil)))
+
+(defun irc--connection-channel-table (conn)
+  (let ((table (irc-connection-get conn :channel-table)))
+    (when (not table)
+      (setq table (make-hash-table :test 'equal))
+      (irc-connection-put conn :channel-table table))
+    table))
+
+(cl-defstruct irc-user
+  nick
+  folded-nick
+  userhost
+  join-time
+  last-activity-time
+  part-time
+  connection)
+
+(defun irc-user-from-userstring (conn userstring)
+  "Create an irc-user struct on CONN from USERSTRING.
+
+USERSTRING should be a s tring of the form \"nick!user@host\"."
+  (let ((nick (irc-userstring-nick userstring)))
+    (make-irc-user :nick nick
+                   :folded-nick (irc-isupport--case-fold conn nick)
+                   :userhost (let ((nick-len (length nick)))
+                               (if (>= nick-len (length userstring))
+                                   nil
+                                 (substring userstring (1+ nick-len))))
+                   :connection conn)))
+
+(defun irc-channel-user (channel nick)
+  "Return a user named NICK on channel CHANNEL."
+  (let ((user-table (irc-channel-users channel))
+        (folded-nick (irc-isupport--case-fold (irc-channel-connection channel)
+                                              nick)))
+    (gethash folded-nick user-table)))
+
+(defun irc-channel-recent-user (channel nick)
+  "Return a recent user named NICK on channel CHANNEL."
+  (let ((user-table (irc-channel-recent-users channel))
+        (folded-nick (irc-isupport--case-fold (irc-channel-connection channel)
+                                              nick)))
+    (gethash folded-nick user-table)))
+
+(defun irc-channel-add-user (channel userstring)
+  "Add USER to CHANNEL."
+  (let* ((user-table (irc-channel-users channel))
+         (user (irc-user-from-userstring (irc-channel-connection channel)
+                                         userstring))
+         (folded-nick (irc-user-folded-nick user))
+         (recent-user (irc-channel-recent-user channel (irc-user-nick user))))
+    (when (not (gethash folded-nick user-table))
+      (when (and recent-user
+                 (equal (irc-user-userhost recent-user)
+                        (irc-user-userhost user)))
+        (setf (irc-user-last-activity-time user)
+              (irc-user-last-activity-time recent-user)))
+      (puthash folded-nick user user-table)
+      user)))
+
+(defun irc-channel-remove-user (channel nick)
+  "Remove NICK from CHANNEL."
+  (let* ((user-table (irc-channel-users channel))
+         (recent-user-table (irc-channel-recent-users channel))
+         (folded-nick (irc-isupport--case-fold (irc-channel-connection channel)
+                                               nick))
+         (user (gethash folded-nick user-table)))
+    (remhash folded-nick user-table)
+    (when user
+      (setf (irc-user-part-time user) (float-time))
+      (puthash folded-nick user recent-user-table)
+      (maphash (lambda (folded-nick user)
+                 (when (< (irc-user-part-time user)
+                          (- (float-time)
+                             (* 60 60)))
+                   (remhash folded-nick recent-user-table)))
+               recent-user-table))))
+
+(defun irc-channel-rename-user (channel oldnick newnick)
+  "Update CHANNEL so that the user with nick OLDNICK now has nick NEWNICK."
+  (let ((user-table (irc-channel-users channel))
+        (user (irc-channel-user channel oldnick))
+        (newnick-folded (irc-isupport--case-fold
+                         (irc-channel-connection channel)
+                         newnick))
+        (recent-user (irc-channel-recent-user channel newnick)))
+    (when user
+      (when (and recent-user
+                 (equal (irc-user-userhost recent-user)
+                        (irc-user-userhost user)))
+        (setf (irc-user-last-activity-time user)
+              (irc-user-last-activity-time recent-user)))
+      (remhash (irc-user-folded-nick user) user-table)
+      (setf (irc-user-nick user) newnick)
+      (setf (irc-user-folded-nick user) newnick-folded)
+      (puthash (irc-user-folded-nick user) user user-table))))
+
+(defun irc-handle-state-tracking--rpl-welcome (conn _event _sender target
+                                                    &rest ignored)
+  (irc-connection-put conn :current-nick target))
+
+(defun irc-handle-state-tracking--JOIN (conn _event sender target
+                                             &optional _account _realname)
+  (let ((nick (irc-userstring-nick sender)))
+    (cond
+     ((irc-current-nick-p conn nick)
+      (irc-connection-add-channel conn target))
+     (t
+      (let ((channel (irc-connection-channel conn target)))
+        (when channel
+          (let ((user (irc-channel-add-user channel sender)))
+            (when user
+              (setf (irc-user-join-time user) (float-time))))))))))
+
+(defun irc-handle-state-tracking--PART (conn _event sender target
+                                             &optional _reason)
+  (let ((nick (irc-userstring-nick sender)))
+    (cond
+     ((irc-current-nick-p conn nick)
+      (irc-connection-remove-channel conn target))
+     (t
+      (let ((channel (irc-connection-channel conn target)))
+        (when channel
+          (irc-channel-remove-user channel nick)))))))
+
+(defun irc-handle-state-tracking--KICK (conn _event _sender target nick
+                                             &optional _reason)
+  (cond
+   ((irc-current-nick-p conn nick)
+    (irc-connection-remove-channel conn target))
+   (t
+    (let ((channel (irc-connection-channel conn target)))
+      (when channel
+        (irc-channel-remove-user channel nick))))))
+
+(defun irc-handle-state-tracking--QUIT (conn _event sender
+                                             &optional reason)
+  (let ((nick (irc-userstring-nick sender)))
+    (if (irc-current-nick-p conn nick)
+        (dolist (channel (irc-connection-channel-list conn))
+          (irc-connection-remove-channel conn
+                                         (irc-channel-folded-name channel)))
+      (dolist (channel (irc-connection-channel-list conn))
+        (when (irc-channel-user channel nick)
+          (irc-event-emit conn "channel.quit"
+                          sender
+                          (irc-channel-name channel)
+                          reason))
+        (irc-channel-remove-user channel nick)))))
+
+(defun irc-handle-state-tracking--NICK (conn _event sender new-nick)
+  ;; Update channels
+  (let ((nick (irc-userstring-nick sender)))
+    (dolist (channel (irc-connection-channel-list conn))
+      (irc-channel-rename-user channel nick new-nick)))
+  ;; Update our own nick
+  (when (irc-current-nick-p conn (irc-userstring-nick sender))
+    (irc-connection-put conn :current-nick new-nick)))
+
+(defun irc-handle-state-tracking--PRIVMSG (conn _event sender target _message)
+  (let ((channel (irc-connection-channel conn target))
+        (nick (irc-userstring-nick sender)))
+    (when channel
+      (let ((user (irc-channel-user channel nick)))
+        (when user
+          (setf (irc-user-last-activity-time user) (float-time)))))))
+
+(defun irc-handle-state-tracking--rpl-namreply
+    (conn _event _sender _current-nick _channel-type channel-name nicks)
+  (let ((channel (irc-connection-channel conn channel-name)))
+    (when channel
+      (setf (irc-channel-receiving-names channel)
+            (append (irc-channel-receiving-names channel)
+                    (mapcar (lambda (nick)
+                              (irc-nick-without-prefix
+                               conn
+                               (string-trim nick)))
+                            (split-string nicks)))))))
+
+(defun irc-handle-state-tracking--rpl-endofnames
+    (conn _event _sender _current-nick channel-name _description)
+  (let ((channel (irc-connection-channel conn channel-name)))
+    (when channel
+      (irc-channel--synchronize-nicks channel
+                                      (irc-channel-receiving-names channel))
+      (setf (irc-channel-receiving-names channel) nil))))
+
+(defun irc-channel--synchronize-nicks (channel nicks)
+  "Update the user list of CHANNEL to match NICKS."
+  (let ((have (irc-channel-users channel))
+        (want (make-hash-table :test 'equal)))
+    (dolist (nick nicks)
+      (puthash (irc-isupport--case-fold (irc-channel-connection channel)
+                                        nick)
+               nick
+               want))
+    (maphash (lambda (nick-folded user)
+               (when (not (gethash nick-folded want))
+                 (irc-channel-remove-user channel
+                                          (irc-user-nick user))))
+             have)
+    (maphash (lambda (_nick-folded nick)
+               (irc-channel-add-user channel nick))
+             want)))
+
+(defun irc-handle-state-tracking--TOPIC (conn _event _sender channel new-topic)
+  (let ((channel (irc-connection-channel conn channel)))
+    (when channel
+      (setf (irc-channel-last-topic channel)
+            (irc-channel-topic channel))
+      (setf (irc-channel-topic channel) new-topic))))
+
+(defun irc-handle-state-tracking--rpl-notopic (conn _event _sender
+                                                    _current-nick channel
+                                                    _no-topic-desc)
+  (let ((channel (irc-connection-channel conn channel)))
+    (when channel
+      (setf (irc-channel-topic channel) nil))))
+
+(defun irc-handle-state-tracking--rpl-topic (conn _event _sender _current-nick
+                                                  channel topic)
+  (let ((channel (irc-connection-channel conn channel)))
+    (when channel
+      (setf (irc-channel-topic channel) topic))))
+
+;;;;;;;;;;;;;;,;;;;;;
+;;; Handler: NickServ
+
+(defun irc-handle-nickserv (table)
+  "Add command handlers to TABLE to deal with NickServ.
+
+Connection options used:
+
+:nickserv-nick -- The nick to register as
+
+:nickserv-password -- The password for nickserv; can be a function and
+  is then called with the IRC connection as its sole argument
+
+:nickserv-mask -- A regular expression matching the correct NickServ's
+  nick!user@host string to avoid fakes
+
+:nickserv-identify-challenge -- A regular expression matching the
+  challenge sent by NickServ to request identification
+
+:nickserv-identify-command -- The raw IRC command to send to identify;
+  expands {nick} and {password} when present
+
+:nickserv-identify-confirmation -- A regular expression matching the
+  confirmation message from NickServ after successful identification
+
+:nickserv-ghost-command -- The raw IRC comment to ghost your
+  original nick; expands {nick} and {password}. Set this to nil
+  to disable ghosting and nick regaining.
+
+:nickserv-ghost-confirmation -- A regular expression matching the
+  confirmation message that the nick was ghosted
+
+Events emitted:
+
+\"nickserv.identified\" -- We have successfully identified with nickserv.
+
+\"nickserv.ghosted\" -- We have ghosted a nick."
+  (irc-handler-add table "irc.registered" #'irc-handle-nickserv--registered)
+  (irc-handler-add table "NOTICE" #'irc-handle-nickserv--NOTICE)
+  (irc-handler-add table "PRIVMSG" #'irc-handle-nickserv--NOTICE)
+  (irc-handler-add table "NICK" #'irc-handle-nickserv--NICK))
+
+(defun irc-handle-nickserv--password (conn)
+  (let ((password (irc-connection-get conn :nickserv-password)))
+    (if (functionp password)
+        (funcall password conn)
+      password)))
+
+(defun irc-handle-nickserv--registered (conn _event current-nick)
+  (let ((ghost-command (irc-connection-get conn :nickserv-ghost-command))
+        (wanted-nick (irc-connection-get conn :nickserv-nick))
+        (password (irc-handle-nickserv--password conn)))
+    (when (and ghost-command
+               wanted-nick
+               password
+               (not (irc-string-equal-p conn current-nick wanted-nick)))
+      (irc-send-raw conn
+                    (irc-format ghost-command
+                                'nick wanted-nick
+                                'password password)))))
+
+(defun irc-handle-nickserv--NOTICE (conn _event sender _target message)
+  (let ((nickserv-mask (irc-connection-get conn :nickserv-mask))
+        identify-challenge identify-command identify-confirmation
+        ghost-confirmation
+        nickserv-nick nickserv-password)
+    (when (and nickserv-mask (string-match nickserv-mask sender))
+      (setq identify-challenge
+            (irc-connection-get conn :nickserv-identify-challenge))
+      (setq identify-command
+            (irc-connection-get conn :nickserv-identify-command))
+      (setq identify-confirmation
+            (irc-connection-get conn :nickserv-identify-confirmation))
+      (setq ghost-confirmation
+            (irc-connection-get conn :nickserv-ghost-confirmation))
+      (setq nickserv-nick (irc-connection-get conn :nickserv-nick))
+      (setq nickserv-password (irc-handle-nickserv--password conn))
+      (cond
+       ;; Identify
+       ((and identify-challenge
+             identify-command
+             nickserv-nick
+             nickserv-password
+             (string-match identify-challenge message))
+        (irc-send-raw conn
+                      (irc-format identify-command
+                                  'nick nickserv-nick
+                                  'password nickserv-password)))
+       ;; Identification confirmed
+       ((and identify-confirmation
+             (string-match identify-confirmation message))
+        (irc-event-emit conn "nickserv.identified"))
+       ;; Ghosting confirmed
+       ((and ghost-confirmation
+             (string-match ghost-confirmation message))
+        (irc-event-emit conn "nickserv.ghosted")
+        (irc-connection-put conn :nickserv-regaining-nick t)
+        (when nickserv-nick
+          (irc-send-NICK conn nickserv-nick)))))))
+
+(defun irc-handle-nickserv--NICK (conn _event _sender new-nick)
+  (when (and (irc-connection-get conn :nickserv-regaining-nick)
+             (irc-string-equal-p conn new-nick
+                                 (irc-connection-get conn :nickserv-nick)))
+    (irc-connection-put conn :nickserv-regaining-nick nil)
+    (irc-event-emit conn "nickserv.regained")))
+
+(defun irc-format (format &rest args)
+  "Return a formatted version of FORMAT, using substitutions from ARGS.
+
+The substitutions are identified by braces ('{' and '}')."
+  (with-temp-buffer
+    (insert format)
+    (goto-char (point-min))
+    (while (re-search-forward "{\\([^}]*\\)}" nil t)
+      (replace-match (format "%s" (plist-get args (intern (match-string 1))))
+                     t t))
+    (buffer-string)))
+
+;;;;;;;;;;;;;;;;;;;;;;
+;;; Handler: Auto-Join
+
+(defun irc-handle-auto-join (table)
+  "Add command handlers to TABLE to deal with NickServ.
+
+Connection options used:
+
+:auto-join-after-registration -- List of channels to join
+  immediately after registration with the server
+
+:auto-join-after-host-hiding -- List of channels to join
+  after our host was hidden
+
+:auto-join-after-nick-acquisition -- List of channels to join
+  after we gained our desired nick
+
+:auto-join-after-nickserv-identification -- List of channels
+  to join after we identified successfully with NickServ"
+  (irc-handler-add table "irc.registered" #'irc-handle-auto-join--registered)
+  (irc-handler-add table "396" ;; RPL_HOSTHIDDEN
+                   #'irc-handle-auto-join--rpl-hosthidden)
+  (irc-handler-add table "nickserv.regained"
+                   #'irc-handle-auto-join--nickserv-regained)
+  (irc-handler-add table "nickserv.identified"
+                   #'irc-handle-auto-join--nickserv-identified)
+  (irc-handler-add table "sasl.login"
+                   #'irc-handle-auto-join--sasl-login))
+
+(defun irc-handle-auto-join--registered (conn _event _current-nick)
+  (dolist (channel (irc-connection-get conn :auto-join-after-registration))
+    (irc-send-JOIN conn channel)))
+
+(defun irc-handle-auto-join--rpl-hosthidden (conn _event _sender _target _host
+                                                  _description)
+  (dolist (channel (irc-connection-get conn :auto-join-after-host-hiding))
+    (irc-send-JOIN conn channel)))
+
+(defun irc-handle-auto-join--nickserv-regained (conn _event)
+  (dolist (channel (irc-connection-get
+                    conn :auto-join-after-nick-acquisition))
+    (irc-send-JOIN conn channel)))
+
+(defun irc-handle-auto-join--nickserv-identified (conn event)
+  (dolist (channel (irc-connection-get
+                    conn :auto-join-after-nickserv-identification))
+    (irc-send-JOIN conn channel))
+  (if (irc-string-equal-p conn
+                          (irc-connection-get conn :nick)
+                          (irc-connection-get conn :nickserv-nick))
+      (irc-handle-auto-join--nickserv-regained conn event)))
+
+(defun irc-handle-auto-join--sasl-login (conn _event &rest ignored)
+  (dolist (channel (irc-connection-get
+                    conn :auto-join-after-sasl-login))
+    (irc-send-JOIN conn channel)))
+
+(provide 'irc)
+;;; irc.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/irc.elc b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/irc.elc
new file mode 100644
index 0000000000..9c9cd1508c
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/irc.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/lcs.el b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/lcs.el
new file mode 100644
index 0000000000..b5beb12ef1
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/lcs.el
@@ -0,0 +1,202 @@
+;;; lcs.el --- find out the longest common sequence
+
+;;   Copyright (c) 2002-2003 by Alex Shinn, All rights reserved.
+;;   Copyright (c) 2002-2003 by Shiro Kawai, All rights reserved.
+;;   Copyright (c) 2006, 2012 by Jorgen Schaefer, All rights reserved.
+
+;; Authors: Alex Shinn, Shiro Kawai
+;; Maintainer: Jorgen Schaefer <forcer@forcix.cx>
+;; URL: https://github.com/jorgenschaefer/circe/wiki/lcs
+
+;;   Redistribution and use in source and binary forms, with or without
+;;   modification, are permitted provided that the following conditions
+;;   are met:
+
+;;   1. Redistributions of source code must retain the above copyright
+;;      notice, this list of conditions and the following disclaimer.
+
+;;   2. Redistributions in binary form must reproduce the above copyright
+;;      notice, this list of conditions and the following disclaimer in the
+;;      documentation and/or other materials provided with the distribution.
+
+;;   3. Neither the name of the authors nor the names of its contributors
+;;      may be used to endorse or promote products derived from this
+;;      software without specific prior written permission.
+
+;;   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+;;   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+;;   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+;;   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+;;   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+;;   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+;;   TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+;;   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+;;   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+;;   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+;;   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+;;; Commentary:
+
+;; lcs.el is a library for other Emacs Lisp programs not useful by
+;; itself.
+
+;; This library provides functions to find the Longest Common Sequence
+;; (LCS) of two sequences. This is used to create a unified diff of to
+;; two lists. See `lcs-unified-diff' for a useful function to be
+;; called.
+
+;; The code is more or less a literal translation of (part of)
+;; Gauche's util/lcs.scm module to Emacs Lisp.
+
+;;; Code:
+
+(put 'lcs-for 'lisp-indent-function 4)
+(defmacro lcs-for (var from to step &rest body)
+  "A simple FOR loop macro.
+Count VAR from FROM to TO by stepsize STEP. Evaluate BODY in each
+iteration."
+  (let ((sto (make-symbol "to"))
+        (sstep (make-symbol "step")))
+    `(let ((,var ,from)
+           (,sto ,to)
+           (,sstep ,step))
+       (while (<= ,var ,sto)
+         (progn
+           ,@body)
+         (setq ,var (+ ,var ,sstep))))))
+
+(defun lcs-split-at (lis pos)
+  "Return a cons cell of the first POS elements of LIS and the rest."
+  (let ((head nil))
+    (while (> pos 0)
+      (setq head (cons (car lis)
+                       head)
+            pos (- pos 1)
+            lis (cdr lis)))
+    (cons (reverse head)
+          lis)))
+
+(defun lcs-finish (M+N V_l vl V_r vr)
+  "Finalize the LCS algorithm.
+Should be used only by `lcs-with-positions'."
+  (let ((maxl 0)
+        (r '()))
+    (lcs-for i (- M+N) M+N 1
+      (when (> (funcall vl i)
+               maxl)
+        (setq maxl (funcall vl i)
+              r (funcall vr i))))
+    (list maxl (reverse r))))
+
+(defun lcs-with-positions (a-ls b-ls &optional equalp)
+  "Return the longest common subsequence (LCS) of A-LS and B-LS.
+EQUALP can be any procedure which returns non-nil when two
+elements should be considered equal."
+  (let* ((A (vconcat a-ls))
+         (B (vconcat b-ls))
+         (N (length A))
+         (M (length B))
+         (M+N (+ M N))
+         (V_d (make-vector (+ 1 (* 2 M+N))
+                           0))
+         (V_r (make-vector (+ 1 (* 2 M+N))
+                           nil))
+         (V_l (make-vector (+ 1 (* 2 M+N))
+                           0))
+         (vd (lambda (i &optional x)
+               (if x
+                   (aset V_d (+ i M+N) x)
+                 (aref V_d (+ i M+N)))))
+         (vr (lambda (i &optional x)
+               (if x
+                   (aset V_r (+ i M+N) x)
+                 (aref V_r (+ i M+N)))))
+         (vl (lambda (i &optional x)
+               (if x
+                   (aset V_l (+ i M+N) x)
+                 (aref V_l (+ i M+N))))))
+    (when (not equalp)
+      (setq equalp 'equal))
+    (catch 'return
+      (if (= M+N 0)
+          (throw 'return '(0 ()))
+        (lcs-for d 0 M+N 1
+          (lcs-for k (- d) d 2
+            (let ((x nil)
+                  (y nil)
+                  (l nil)
+                  (r nil))
+              (if (or (= k (- d))
+                      (and (not (= k d))
+                           (< (funcall vd (- k 1))
+                              (funcall vd (+ k 1)))))
+                  (setq x (funcall vd (+ k 1))
+                        l (funcall vl (+ k 1))
+                        r (funcall vr (+ k 1)))
+                (setq x (+ 1 (funcall vd (- k 1)))
+                      l (funcall vl (- k 1))
+                      r (funcall vr (- k 1))))
+              (setq y (- x k))
+              (while (and (< x N)
+                          (< y M)
+                          (funcall equalp (aref A x) (aref B y)))
+                (setq r (cons (list (aref A x) x y)
+                              r)
+                      x (+ x 1)
+                      y (+ y 1)
+                      l (+ l 1)))
+              (funcall vd k x)
+              (funcall vr k r)
+              (funcall vl k l)
+              (when (and (>= x N)
+                         (>= y M))
+                (throw 'return(lcs-finish M+N V_l vl V_r vr)))))))
+      (error "Can't happen"))))
+
+(defun lcs-unified-diff (a b &optional equalp)
+  "Return a unified diff of the lists A and B.
+EQUALP should can be a procedure that returns non-nil when two
+elements of A and B should be considered equal. It's `equal' by
+default."
+  (let ((common (cadr (lcs-with-positions a b equalp)))
+        (a a)
+        (a-pos 0)
+        (b b)
+        (b-pos 0)
+        (diff '()))
+    (while common
+      (let* ((elt (car common))
+             (a-off (nth 1 elt))
+             (a-skip (- a-off a-pos))
+             (b-off (nth 2 elt))
+             (b-skip (- b-off b-pos))
+             (a-split (lcs-split-at a a-skip))
+             (a-head (car a-split))
+             (a-tail (cdr a-split))
+             (b-split (lcs-split-at b b-skip))
+             (b-head (car b-split))
+             (b-tail (cdr b-split)))
+        (setq diff (append diff
+                           (mapcar (lambda (a)
+                                     `(- ,a))
+                                   a-head)
+                           (mapcar (lambda (b)
+                                     `(+ ,b))
+                                   b-head)
+                           `((! ,(car elt))))
+
+              common (cdr common)
+              a (cdr a-tail)
+              a-pos (+ a-off 1)
+              b (cdr b-tail)
+              b-pos (+ b-off 1))))
+    (append diff
+            (mapcar (lambda (a)
+                      `(- ,a))
+                    a)
+            (mapcar (lambda (b)
+                      `(+ ,b))
+                    b))))
+
+(provide 'lcs)
+;;; lcs.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/lcs.elc b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/lcs.elc
new file mode 100644
index 0000000000..2db8b77a4c
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/lcs.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/lui-autopaste.el b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/lui-autopaste.el
new file mode 100644
index 0000000000..7582839c26
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/lui-autopaste.el
@@ -0,0 +1,115 @@
+;;; lui-autopaste.el --- Extension for lui for long text input
+
+;; Copyright (C) 2012  Jorgen Schaefer <forcer@forcix.cx>
+
+;; Author: Jorgen Schaefer <forcer@forcix.cx>
+
+;; This file is part of Lui.
+
+;; This program 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.
+
+;; This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This extension for lui will intercept long input and replace it by
+;; an URL to a paste service.
+
+;; What is considered "long" is defined by `lui-autopaste-lines'. You
+;; can configure which paste service to use by changing
+;; `lui-autopaste-function'.
+
+;; Run `enable-lui-autopaste' to enable this.
+
+;;; Code:
+
+(defgroup lui-autopaste nil
+  "The Lui autopaste extension."
+  :prefix "lui-autopaste-"
+  :group 'lui)
+
+(defcustom lui-autopaste-lines 3
+  "Starting at this number of lines, Lui will ask to paste the input."
+  :type 'integer
+  :group 'lui-autopaste)
+
+(defcustom lui-autopaste-function 'lui-autopaste-service-ixio
+  "Which paste service to use.
+
+This function will be called with some text as its only argument,
+and is expected to return an URL to view the contents."
+  :type '(choice (const :tag "ix.io" lui-autopaste-service-ixio)
+                 (const :tag "ptpb.pw" lui-autopaste-service-ptpb-pw))
+  :group 'lui-autopaste)
+
+;;;###autoload
+(defun enable-lui-autopaste ()
+  "Enable the lui autopaste feature.
+
+If you enter more than `lui-autopaste-lines' at once, Lui will
+ask if you would prefer to use a paste service instead. If you
+agree, Lui will paste your input to `lui-autopaste-function' and
+replace it with the resulting URL."
+  (interactive)
+  (add-hook 'lui-pre-input-hook 'lui-autopaste))
+
+;;;###autoload
+(defun disable-lui-autopaste ()
+  "Disable the lui autopaste feature."
+  (interactive)
+  (remove-hook 'lui-pre-input-hook 'lui-autopaste))
+
+(defun lui-autopaste ()
+  "Check if the lui input is too large. If so, paste it instead."
+  (when (and (>= (count-lines (point-min) (point-max))
+                 lui-autopaste-lines)
+             (y-or-n-p "That's pretty long, would you like to use a paste service instead? "))
+    (let ((url (funcall lui-autopaste-function
+                        (buffer-substring (point-min)
+                                          (point-max)))))
+      (delete-region (point-min) (point-max))
+      (insert url))))
+
+(defun lui-autopaste-service-ptpb-pw (text)
+  "Paste TEXT to ptpb.pw and return the paste url."
+  (let ((url-request-method "POST")
+        (url-request-extra-headers
+         '(("Content-Type" . "application/x-www-form-urlencoded")))
+        (url-request-data (format "c=%s" (url-hexify-string text)))
+        (url-http-attempt-keepalives nil))
+    (let ((buf (url-retrieve-synchronously "https://ptpb.pw/")))
+      (unwind-protect
+          (with-current-buffer buf
+            (goto-char (point-min))
+            (if (re-search-forward "^url: \\(.*\\)" nil t)
+                (match-string 1)
+              (error "Error during pasting to ptpb.pw")))
+        (kill-buffer buf)))))
+
+(defun lui-autopaste-service-ixio (text)
+  "Paste TEXT to ix.io and return the paste url."
+  (let ((url-request-method "POST")
+        (url-request-extra-headers
+         '(("Content-Type" . "application/x-www-form-urlencoded")))
+        (url-request-data (format "f:1=%s" (url-hexify-string text)))
+        (url-http-attempt-keepalives nil))
+    (let ((buf (url-retrieve-synchronously "http://ix.io/")))
+      (unwind-protect
+          (with-current-buffer buf
+            (goto-char (point-min))
+            (if (re-search-forward "\n\n" nil t)
+                (buffer-substring (point) (point-at-eol))
+              (error "Error during pasting to ix.io")))
+        (kill-buffer buf)))))
+
+(provide 'lui-autopaste)
+;;; lui-autopaste.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/lui-autopaste.elc b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/lui-autopaste.elc
new file mode 100644
index 0000000000..bbef287ff9
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/lui-autopaste.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/lui-format.el b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/lui-format.el
new file mode 100644
index 0000000000..68cc0ff000
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/lui-format.el
@@ -0,0 +1,198 @@
+;;; lui-format.el --- A formatting function for use with Lui
+
+;; Copyright (C) 2005, 2012  Jorgen Schaefer
+
+;; Author: Jorgen Schaefer <forcer@forcix.cx>
+
+;; This file is part of Lui.
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; An improved formatting function using named parameters.
+;;
+;; See the docstring of `lui-format' for more details.
+;;
+;; Most of the design is borrowed from Python's string.format.
+
+;;; Code:
+
+(require 'lui)
+
+(defun lui-display (format not-tracked-p &rest keywords)
+  "Display a formatted string in the current Lui interface.
+
+The string is formatted using FORMAT and `lui-format'.
+
+If NOT-TRACKED-P is given, the inserted string won't trigger
+tracking. See `lui-insert' for a description.
+
+KEYWORDS are the keyword arguments passed to `lui-format'.
+
+See `lui-format' for a full description of the arguments."
+  (lui-insert (lui-format format keywords)
+              not-tracked-p))
+
+(defun lui-format (format &rest keywords)
+  "Display FORMAT formatted with KEYWORDS.
+FORMAT should be a symbol whose value is taken. If the value is a
+procedure, the keyword list is passed as a single argument to it,
+and it should return the formatted string. If the value is a
+string, it is formatted according to the rules below.
+
+KEYWORDS is a plist of keywords and strings, or symbols and
+strings. They are used as format arguments.
+
+The string is taken verbatim, unless there is are opening or
+closing braces.
+
+Double opening or closing braces are replaced by single
+occurrences of those characters. Otherwise, the contents between
+opening and closing braces is a format description and replaced
+by a formatted string.
+
+The string between opening and closing braces is taken as a name
+of a keyword argument, and replaced by that argument's value. If
+there is a colon in the string, the keyword name is the part
+before the colon. The part after the colon is used to format the
+argument using standard `format'
+
+Example:
+
+  (lui-format \"Hello {foo:.1f}\" :foo 3.1415)
+
+is equivalent to
+
+  (format \"Hello %.1f\" 3.1415)
+
+If the name is either a number, a number followed by a dash, or
+two numbers with a dash in between them, this is taken as a
+special name that is looked up in the list given using the list
+argument to the :indexed-args keyword.
+
+{1} refers to the second element (element 1)
+{1-} refers to the second and all following elements
+{1-3} refers to the second through fourth element
+
+If more than one element is selected, the elements are separated
+by a single space character.
+
+All named arguments receive a property of `lui-format-argument'
+with the respective name as value. The whole string receives a
+`lui-format' property with FORMAT as a value, and a
+`lui-keywords' argument with KEYWORDS as a value."
+  ;; If it's only a single argument, that argument is a list.
+  (when (not (cdr keywords))
+    (setq keywords (car keywords)))
+  (cond
+   ((functionp format)
+    (apply format keywords))
+   ((and (symbolp format)
+         (functionp (symbol-value format)))
+    (apply (symbol-value format) keywords))
+   (t
+    (let* ((format-string (if (symbolp format)
+                              (symbol-value format)
+                            format))
+           (plist (mapcar (lambda (entry)
+                            (if (keywordp entry)
+                                ;; Keyword -> symbol
+                                (intern (substring (symbol-name entry)
+                                                   1))
+                              entry))
+                          keywords)))
+      (propertize (lui-format-internal format-string plist)
+                  'lui-format format
+                  'lui-keywords keywords)))))
+
+(defun lui-format-internal (fmt keywords)
+  "Internal function for `lui-format'.
+
+FMT is the format string and KEYWORDS is the symbol-based plist.
+
+See `lui-format'."
+  (with-temp-buffer
+    (insert fmt)
+    (goto-char (point-min))
+    (while (re-search-forward "{{\\|}}\\|{\\([^}]*\\)}" nil t)
+      (cond
+       ((string-equal (match-string 0) "3.1")
+        (replace-match "{"))
+       ((string-equal (match-string 0) "}}")
+        (replace-match "}"))
+       (t ;; (match-string 1)
+        (replace-match (save-match-data
+                         (lui-format-single (match-string 1) keywords))
+                       t t))))
+    (buffer-string)))
+
+(defun lui-format-single (specifier keywords)
+  "Format a single braced SPECIFIER according to KEYWORDS.
+See `lui-format' for details.
+
+This adds `lui-format-argument' as necessary."
+  (let* ((split (split-string specifier ":"))
+         (identifier (car split))
+         (format (cadr split)))
+    (when (not format)
+      (setq format "s"))
+    (propertize (format (concat "%" format)
+                        (lui-format-lookup identifier keywords))
+                'lui-format-argument (intern identifier))))
+
+(defun lui-format-lookup (identifier keywords)
+  "Lookup the format IDENTIFIER in KEYWORDS.
+
+See `lui-format' for details."
+  (cond
+   ((string-match "^\\([0-9]+\\)\\(-\\([0-9]+\\)?\\)?$" identifier)
+    (let ((from (match-string 1 identifier))
+          (rangep (match-string 2 identifier))
+          (to (match-string 3 identifier))
+          (indexed-args (plist-get keywords 'indexed-args)))
+      (if rangep
+          (mapconcat (lambda (element)
+                       (if (stringp element)
+                           element
+                         (format "%s" element)))
+                     (lui-sublist indexed-args
+                                  (string-to-number from)
+                                  (when to (string-to-number to)))
+                     " ")
+        (or (nth (string-to-number from)
+                 indexed-args)
+            ""))))
+   (t
+    (or (plist-get keywords (intern identifier))
+        (error "Unknown keyword argument %S" identifier)))))
+
+(defun lui-sublist (list from &optional to)
+  "Return the sublist from LIST starting at FROM and ending at TO."
+  (if (not to)
+      (nthcdr from list)
+    (let ((from-list (nthcdr from list))
+          (i (- to from))
+          (to-list nil))
+      (while (>= i 0)
+        (when (null from-list)
+          (error "Argument out of range: %S" to))
+        (setq to-list (cons (car from-list)
+                            to-list)
+              i (- i 1)
+              from-list (cdr from-list)))
+      (nreverse to-list))))
+
+(provide 'lui-format)
+;;; lui-format.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/lui-format.elc b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/lui-format.elc
new file mode 100644
index 0000000000..6d94859e5f
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/lui-format.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/lui-irc-colors.el b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/lui-irc-colors.el
new file mode 100644
index 0000000000..9b16ead2f9
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/lui-irc-colors.el
@@ -0,0 +1,182 @@
+;;; lui-irc-colors.el --- Add IRC color support to LUI
+
+;; Copyright (C) 2005  Jorgen Schaefer
+
+;; Author: Jorgen Schaefer <forcer@forcix.cx>
+
+;; This file is part of Lui.
+
+;; This program 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.
+
+;; This program 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 this program; if not, write to the Free Software
+;; Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301  USA
+
+;;; Commentary:
+
+;; This tells LUI how to display IRC colors:
+;; ^B - Bold
+;; ^_ - Underline
+;; ^V - Inverse
+;; ^] - Italic
+;; ^O - Return to normal
+;; ^C1,2 - Colors
+
+;; The colors are documented at http://www.mirc.co.uk/help/color.txt
+
+;;; Code:
+
+(require 'lui)
+
+(defgroup lui-irc-colors nil
+  "LUI IRC colors faces."
+  :group 'circe)
+
+(defface lui-irc-colors-inverse-face
+  '((t (:inverse-video t)))
+  "Face used for inverse video."
+  :group 'lui-irc-colors)
+
+(defun lui-irc-defface (face property on-dark on-light rest doc)
+  (custom-declare-face
+   face
+   `((((type graphic) (class color) (background dark))
+      (,property ,on-dark))
+     (((type graphic) (class color) (background light))
+      (,property ,on-light))
+     (t (,property ,rest)))
+   doc
+   :group 'lui-irc-colors))
+
+(defun lui-irc-defface-pair (number on-dark on-light rest name)
+  (lui-irc-defface
+   (intern (format "lui-irc-colors-fg-%d-face" number))
+   :foreground
+   on-dark on-light rest
+   (concat "Face used for foreground IRC color "
+	   (number-to-string number) " (" name ")."))
+  (lui-irc-defface
+   (intern (format "lui-irc-colors-bg-%d-face" number))
+   :background
+   on-light on-dark rest
+   (concat "Face used for background IRC color "
+	   (number-to-string number) " (" name ").")))
+
+(defun lui-irc-defface-bulk (colors)
+  (dotimes (n (length colors))
+    (apply 'lui-irc-defface-pair n (nth n colors))))
+
+(lui-irc-defface-bulk
+ '(("#ffffff" "#585858" "white"    "white")
+   ("#a5a5a5" "#000000" "black"    "black")
+   ("#9b9bff" "#0000ff" "blue4"    "blue")
+   ("#40eb51" "#006600" "green4"   "green")
+   ("#ff9696" "#b60000" "red"      "red")
+   ("#d19999" "#8f3d3d" "red4"     "brown")
+   ("#d68fff" "#9c009c" "magenta4" "purple")
+   ("#ffb812" "#7a4f00" "yellow4"  "orange")
+   ("#ffff00" "#5c5c00" "yellow"   "yellow")
+   ("#80ff95" "#286338" "green"    "light green")
+   ("#00b8b8" "#006078" "cyan4"    "teal")
+   ("#00ffff" "#006363" "cyan"     "light cyan")
+   ("#a8aeff" "#3f568c" "blue"     "light blue")
+   ("#ff8bff" "#853885" "magenta"  "pink")
+   ("#cfcfcf" "#171717" "dimgray"  "grey")
+   ("#e6e6e6" "#303030" "gray"     "light grey")))
+
+(defvar lui-irc-colors-regex
+  "\\(\x02\\|\x1F\\|\x16\\|\x1D\\|\x0F\\|\x03\\)"
+  "A regular expression matching IRC control codes.")
+
+;;;###autoload
+(defun enable-lui-irc-colors ()
+  "Enable IRC color interpretation for Lui."
+  (interactive)
+  (add-hook 'lui-pre-output-hook 'lui-irc-colors))
+
+(defun disable-lui-irc-colors ()
+  "Disable IRC color interpretation for Lui."
+  (interactive)
+  (remove-hook 'lui-pre-output-hook 'lui-irc-colors))
+
+(defun lui-irc-colors ()
+  "Add color faces for IRC colors.
+This is an appropriate function for `lui-pre-output-hook'."
+  (goto-char (point-min))
+  (let ((start (point))
+        (boldp nil)
+        (inversep nil)
+        (italicp nil)
+        (underlinep nil)
+        (fg nil)
+        (bg nil))
+    (while (re-search-forward lui-irc-colors-regex nil t)
+      (lui-irc-propertize start (point)
+                          boldp inversep italicp underlinep
+                          fg bg)
+      (let ((code (match-string 1)))
+        (replace-match "")
+        (setq start (point))
+        (cond
+         ((string= code "")
+          (setq boldp (not boldp)))
+         ((string= code "")
+          (setq inversep (not inversep)))
+         ((string= code "")
+          (setq italicp (not italicp)))
+         ((string= code "")
+          (setq underlinep (not underlinep)))
+         ((string= code "")
+          (setq boldp nil
+                inversep nil
+                italicp nil
+                underlinep nil
+                fg nil
+                bg nil))
+         ((string= code "")
+          (if (looking-at "\\([0-9][0-9]?\\)\\(,\\([0-9][0-9]?\\)\\)?")
+              (progn
+                (setq fg (string-to-number (match-string 1))
+                      bg (if (match-string 2)
+                             (string-to-number (match-string 3))
+                           bg))
+                (setq fg (if (and fg (not (= fg 99))) (mod fg 16) nil)
+                      bg (if (and bg (not (= bg 99))) (mod bg 16) nil))
+                (replace-match ""))
+            (setq fg nil
+                  bg nil)))
+         (t
+          (error "lui-irc-colors: Can't happen!")))))
+    (lui-irc-propertize (point) (point-max)
+                        boldp inversep italicp underlinep fg bg)))
+
+(defun lui-irc-propertize (start end boldp inversep italicp underlinep fg bg)
+  "Propertize the region between START and END."
+  (let ((faces (append (and boldp '(bold))
+                       (and inversep '(lui-irc-colors-inverse-face))
+                       (and italicp '(italic))
+                       (and underlinep '(underline))
+                       (and fg (list (lui-irc-colors-face 'fg fg)))
+                       (and bg (list (lui-irc-colors-face 'bg bg))))))
+    (when faces
+      (add-face-text-property start end faces))))
+
+(defun lui-irc-colors-face (type n)
+  "Return a face appropriate for face number N.
+TYPE is either 'fg or 'bg."
+  (if (and (<= 0 n)
+           (<= n 15))
+      (intern (format "lui-irc-colors-%s-%s-face" type n))
+    'default-face))
+
+(provide 'lui-irc-colors)
+;;; lui-irc-colors.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/lui-irc-colors.elc b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/lui-irc-colors.elc
new file mode 100644
index 0000000000..658dc80d7b
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/lui-irc-colors.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/lui-logging.el b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/lui-logging.el
new file mode 100644
index 0000000000..d24e051f92
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/lui-logging.el
@@ -0,0 +1,201 @@
+;;; lui-logging.el --- Logging support for lui
+
+;; Copyright (C) 2006  Jorgen Schaefer,
+;;               2012  Anthony Martinez
+
+;; Author: Anthony Martinez <pi+circe@pihost.us>
+
+;; This file is part of Lui.
+
+;; This program 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.
+
+;; This program 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 this program; if not, write to the Free Software
+;; Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301  USA
+
+;;; Commentary:
+
+;; This lui module enables logging. Lui applications can change the
+;; values of `lui-logging-format-arguments' to provide further
+;; possibilities of customizing `lui-logging-file-format' for users.
+
+;;; Code:
+
+(require 'lui-format)
+(require 'url-util)
+
+(defgroup lui-logging nil
+  "Logging support."
+  :prefix "lui-logging-"
+  :group 'lui)
+
+(defcustom lui-logging-format "[%T] {text}"
+  "The format used for log file entries.
+This is first passed through `format-time-string' and then through
+`lui-format'. The following format strings exist:
+
+  {text} - the text to be logged"
+  :type 'string
+  :group 'lui-logging)
+
+(defcustom lui-logging-directory "~/.logs"
+  "The directory where log files are stored."
+  :type 'directory
+  :group 'lui-logging)
+
+(defcustom lui-logging-file-format "{buffer}_%Y-%m-%d.txt"
+  "The format to be used for the log file name.
+This is first passed through `format-time-string', and then
+through `lui-format'. Possible lui format strings are:
+
+  {buffer} - the buffer name where the logging happened.
+
+Lui applications can provide further format strings. See
+`lui-logging-format-arguments' in the appropriate buffer."
+  :type 'string
+  :group 'lui-logging)
+
+(defcustom lui-logging-flush-delay 0
+  "The number of seconds to delay writing newly-received messages
+to disk. This can increase performance/decrease IO-wait at the
+cost of a little bit of safety."
+  :type 'integer
+  :group 'lui-logging)
+
+(defvar lui-logging-format-arguments nil
+  "A list of arguments to be passed to `lui-format'.
+This can be used to extend the formatting possibilities of the
+file name for lui applications.")
+(make-variable-buffer-local 'lui-logging-format-arguments)
+
+(defvar lui-logging-file-name-unreserved-chars
+  ;; All but '/' is fine actually, but also omit '%' because otherwise there's
+  ;; ambiguity between one introduced by encoding and a literal one.
+  '(?! ?\" ?# ?$ ?& ?` ?\( ?\) ?* ?+ ?,?: ?\; ?< ?= ?> ?? ?@?\[ ?\\ ?\] ?^ ?`
+       ?\{ ?| ?\})
+  "A list of characters that should not be percent-encoded by
+`url-hexify-string' while generating a logging file name.")
+
+(defvar lui-pending-logs
+  (make-hash-table :test 'equal)
+  "Storage for log messages awaiting write. It is structured as a
+hash table mapping filenames to a list-of-strings, which serves as
+a queue.")
+
+(defvar lui-logging-timer nil
+  "The timer used to flush lui-logged buffers")
+
+(defun lui-logging-delayed-p ()
+  (> lui-logging-flush-delay 0))
+
+(defun enable-lui-logging ()
+  "Enable lui logging for this buffer. Also create the log
+file's directory, should it not exist."
+  (interactive)
+  (add-hook 'lui-pre-output-hook 'lui-logging
+            nil t))
+
+(defun disable-lui-logging ()
+  "Disable lui logging for this buffer, and flush any pending
+logs to disk."
+  (interactive)
+  (remove-hook 'lui-pre-output-hook 'lui-logging t)
+  (lui-logging-flush))
+
+(defun enable-lui-logging-globally ()
+  "Enable lui logging for all Lui buffers.
+
+This affects current as well as future buffers."
+  (interactive)
+  (add-hook 'lui-mode-hook 'enable-lui-logging)
+  (dolist (buf (buffer-list))
+    (with-current-buffer buf
+      (when lui-input-marker
+        (enable-lui-logging)))))
+
+(defun disable-lui-logging-globally ()
+  "Disable logging in all future Lui buffers.
+
+This affects current as well as future buffers."
+  (interactive)
+  (remove-hook 'lui-mode-hook 'enable-lui-logging)
+  (dolist (buf (buffer-list))
+    (with-current-buffer buf
+      (when lui-input-marker
+        (disable-lui-logging)))))
+
+(defun lui-logging-file-name ()
+  "Create the name of the log file based on `lui-logging-file-format'."
+  (let* ((time-formatted (format-time-string lui-logging-file-format))
+         (buffer (let ((url-unreserved-chars
+                        (append url-unreserved-chars
+                                lui-logging-file-name-unreserved-chars))
+                       (downcased (downcase (buffer-name (current-buffer)))))
+                   (url-hexify-string downcased)))
+         (filename (apply 'lui-format
+                          time-formatted
+                          :buffer buffer
+                          lui-logging-format-arguments)))
+    (concat lui-logging-directory "/" filename)))
+
+(defun lui-logging-flush ()
+  "Flush out the lui-logging queue, and clear the timer set by
+`lui-logging'."
+  (maphash #'lui-logging-flush-file lui-pending-logs)
+  (clrhash lui-pending-logs)
+  (cancel-timer lui-logging-timer)
+  (setq lui-logging-timer nil))
+
+(defun lui-logging-write-to-log (file-name content)
+  "Actually perform a write to the logfile."
+  (let ((coding-system-for-write 'raw-text)
+        (dir (file-name-directory file-name)))
+    (when (not (file-directory-p dir))
+      (make-directory dir t))
+    (write-region content nil file-name t 'nomessage)))
+
+(defun lui-logging-flush-file (file-name queue)
+  "Consume the logging queue and write the content to the log
+file."
+  (let ((content (apply #'concat (nreverse queue))))
+    (lui-logging-write-to-log file-name content)))
+
+(defun lui-logging-format-string (text)
+  "Generate a string to be either directly written or enqueued."
+  (substring-no-properties
+   (lui-format
+    (format-time-string lui-logging-format)
+    :text text)))
+
+(defun lui-logging-enqueue (file-name text)
+  "Given a filename, push text onto its queue, and tickle the
+timer, if necessary."
+  (puthash file-name
+           (cons text (gethash file-name lui-pending-logs))
+           lui-pending-logs)
+  (when (null lui-logging-timer)
+    (setq lui-logging-timer
+          (run-with-timer lui-logging-flush-delay nil
+                          #'lui-logging-flush))))
+
+(defun lui-logging ()
+  "If output-queueing is enabled, append the to-be-logged string
+to the output queue. Otherwise, write directly to the logfile.
+This should be added to `lui-pre-output-hook' by way of
+`enable-lui-logging'."
+  (let ((text (lui-logging-format-string (buffer-string))))
+    (if (lui-logging-delayed-p)
+        (lui-logging-enqueue (lui-logging-file-name) text)
+      (lui-logging-write-to-log (lui-logging-file-name) text))))
+
+(provide 'lui-logging)
+;;; lui-logging.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/lui-logging.elc b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/lui-logging.elc
new file mode 100644
index 0000000000..2fa75d9c2a
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/lui-logging.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/lui-track-bar.el b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/lui-track-bar.el
new file mode 100644
index 0000000000..360ecf69d5
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/lui-track-bar.el
@@ -0,0 +1,110 @@
+;;; lui-track-bar.el --- Provides a bar to track the last read position
+
+;; Copyright (C) 2016 Vasilij Schneidermann <v.schneidermann@gmail.com>
+
+;; Author: Vasilij Schneidermann <v.schneidermann@gmail.com>
+
+;; This file is part of LUI.
+
+;; This program 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.
+
+;; This program 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 this program; if not, write to the Free Software
+;; Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301  USA
+
+;;; Commentary:
+
+;; This allows you to track where you've last left off a buffer.
+
+;; Use (enable-lui-track-bar) to enable this mode globally. You can
+;; customize `lui-track-bar-behavior' to change when the track bar
+;; moves. You can also use M-x lui-track-bar-move to move the track
+;; bar manually.
+
+;;; Code:
+
+(require 'lui)
+(require 'tracking)
+
+(defgroup lui-track-bar nil
+  "Last read position tracking for LUI"
+  :prefix "lui-track-bar-"
+  :group 'lui)
+
+(defcustom lui-track-bar-behavior 'before-switch-to-buffer
+  "When to move the track bar.
+
+The following values are possible.
+
+before-switch-to-buffer (default)
+  Move the bar to the bottom of the buffer when switching away
+  from a buffer.
+
+before-tracking-next-buffer
+  Move the bar when switching to the next buffer using
+  \\[tracking-next-buffer].
+
+after-send
+  Move the bar after sending a message."
+  :type '(choice (const :tag "Before switching buffers"
+                        before-switch-to-buffer)
+                 (const :tag "Before tracking switch"
+                        before-tracking-next-buffer)
+                 (const :tag "After sending"
+                        after-send))
+  :group 'lui-track-bar)
+
+(defface lui-track-bar
+  '((((type graphic) (background light))
+     :inherit default :background "dim gray" :height 0.1)
+    (((type graphic) (background dark))
+     :inherit default :background "light gray" :height 0.1)
+    (((type tty))
+     :inherit (font-lock-comment-face default) :underline t))
+  "Track bar face"
+  :group 'lui-track-bar)
+
+(defvar lui-track-bar-overlay nil)
+(make-variable-buffer-local 'lui-track-bar-overlay)
+
+;;;###autoload
+(defun enable-lui-track-bar ()
+  "Enable a bar in Lui buffers that shows where you stopped reading."
+  (interactive)
+  (defadvice switch-to-buffer (before lui-track-bar activate)
+    (when (and (eq lui-track-bar-behavior 'before-switch-to-buffer)
+               ;; Do not move the bar if the buffer is displayed still
+               (<= (length (get-buffer-window-list (current-buffer)))
+                   1))
+      (lui-track-bar-move)))
+  (defadvice tracking-next-buffer (before lui-track-bar activate)
+    (when (eq lui-track-bar-behavior 'before-tracking-next-buffer)
+      (lui-track-bar-move)))
+  (add-hook 'lui-pre-input-hook 'lui-track-bar--move-pre-input))
+
+(defun lui-track-bar--move-pre-input ()
+  (when (eq lui-track-bar-behavior 'after-send)
+    (lui-track-bar-move)))
+
+(defun lui-track-bar-move ()
+  "Move the track bar down."
+  (interactive)
+  (when (derived-mode-p 'lui-mode)
+    (when (not lui-track-bar-overlay)
+      (setq lui-track-bar-overlay (make-overlay (point-min) (point-min)))
+      (overlay-put lui-track-bar-overlay 'after-string
+                   (propertize "\n" 'face 'lui-track-bar)))
+    (move-overlay lui-track-bar-overlay
+                  lui-output-marker lui-output-marker)))
+
+(provide 'lui-track-bar)
+;;; lui-track-bar.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/lui-track-bar.elc b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/lui-track-bar.elc
new file mode 100644
index 0000000000..3fbf759b65
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/lui-track-bar.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/lui.el b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/lui.el
new file mode 100644
index 0000000000..07cc758f29
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/lui.el
@@ -0,0 +1,1513 @@
+;;; lui.el --- Linewise User Interface -*- lexical-binding: t -*-
+
+;; Copyright (C) 2005 - 2016  Jorgen Schaefer
+
+;; Author: Jorgen Schaefer <forcer@forcix.cx>
+;; URL: https://github.com/jorgenschaefer/circe/wiki/Lui
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Lui is a library for other Emacs Lisp programs and not useful by
+;; itself.
+
+;; This major mode provides a user interface for applications. The
+;; user interface is quite simple, consisting of an input line, a
+;; prompt, and some output area, but Lui includes a lot of common
+;; options, such as time stamps, filling, colorization, etc.
+
+;; Application programs should create modes derived from lui-mode.
+
+;; The application API consists of:
+
+;; lui-mode
+;; lui-set-prompt
+;; lui-insert
+;; lui-input-function
+;; lui-completion-function
+;; lui-time-stamp-time
+;; lui-time-stamp-zone
+;; and the 'lui-fool and 'lui-do-not-track text properties
+
+;;; Code:
+
+(require 'button)
+(require 'flyspell)
+(require 'help-mode)
+(require 'ispell)
+(require 'paren)
+(require 'ring)
+(require 'thingatpt)
+(require 'rx)
+
+(require 'tracking)
+
+
+;;;;;;;;;;;;;;;;;;;;;
+;;; Customization ;;;
+;;;;;;;;;;;;;;;;;;;;;
+
+(defgroup lui nil
+  "The Linewise User Interface."
+  :prefix "lui-"
+  :group 'applications)
+
+(defcustom lui-scroll-behavior t
+  "Set the behavior lui should exhibit for scrolling.
+
+The following values are possible. If in doubt, use post-output.
+
+nil
+  Use default Emacs scrolling.
+
+post-command
+  Keep the input line at the end of the window if point is
+  after the input mark.
+
+post-output
+  Keep the input line at the end of the window only after output.
+
+t
+  Combine both post-command and post-output.
+
+post-scroll
+  Keep the input line at the end of the window on every scroll
+  event. Careful, this might interact badly with other functions
+  on `window-scroll-functions'.
+
+
+It would be entirely sensible for Emacs to provide a setting to
+do this kind of scrolling by default in a buffer. It seems rather
+intuitive and sensible. But as noted on emacs-devel:
+
+  [T]hose who know the code know that it's going to be a pain to
+  implement, especially if you want acceptable performance. IOW,
+  patches welcome
+
+The full discussion can be found here:
+
+https://lists.gnu.org/archive/html/emacs-devel/2012-10/msg00652.html
+
+These settings are all hacks that try to give the user the choice
+between most correct behavior (post-scroll) and most compliant
+behavior (post-output)."
+  :type '(choice (const :tag "Post Command" t)
+                 (const :tag "Post Output" post-output)
+                 (const :tag "Post Scroll" post-scroll)
+                 (const :tag "Use default scrolling" nil))
+  :group 'lui)
+(defvaralias 'lui-scroll-to-bottom-p 'lui-scroll-behavior)
+
+(defcustom lui-flyspell-p nil
+  "Non-nil if Lui should spell-check your input.
+See the function `flyspell-mode' for more information."
+  :type 'boolean
+  :group 'lui)
+
+(defcustom lui-flyspell-alist nil
+  "Alist of buffer dictionaries.
+
+This is a list of mappings from buffers to dictionaries to use
+for the function `flyspell-mode'. The appropriate dictionary is
+automatically used when Lui is activated in a buffer with a
+matching buffer name.
+
+The entries are of the form (REGEXP DICTIONARY), where REGEXP
+must match a buffer name, and DICTIONARY specifies an existing
+dictionary for the function `flyspell-mode'. See
+`ispell-local-dictionary-alist' and `ispell-dictionary-alist' for
+a valid list of dictionaries."
+  :type 'string
+  :group 'lui)
+
+(defcustom lui-highlight-keywords nil
+  "A list of keywords to highlight.
+
+This specifies a list of keywords that Lui should highlight. Each
+entry is of one of the following forms (similar to
+`font-lock-keywords'):
+
+  REGEXP
+    Highlight every match in `lui-highlight-face'
+  (REGEXP SUBMATCH)
+    Highlight the SUBMATCH (a number) in REGEXP in
+    `lui-highlight-face'
+  (REGEXP FACE)
+    Highlight everything matching REGEXP in FACE (a symbol)
+  (REGEXP SUBMATCH FACE)
+    Highlight the SUBMATCH in REGEXP in FACE
+
+In all of these cases, the FACE can also be a property list which
+is then associated with the match.
+
+All matches are run, which means later matches can override
+changes by earlier ones."
+  :type '(repeat (choice
+                  (string :tag "Regular Expression")
+                  (list :tag "Submatch"
+                        (string :tag "Regular Expression")
+                        (integer :tag "Submatch"))
+                  (list :tag "Regular Expression in Specific Face"
+                        (string :tag "Regular Expression")
+                        (face :tag "Face"))
+                  (list :tag "Submatch in Specific Face"
+                        (string :tag "Regular Expression")
+                        (integer :tag "Submatch")
+                        (face :tag "Face"))))
+  :group 'lui)
+
+(defface lui-strong-face
+  '((t (:inherit bold)))
+  "Face used for strong markup."
+  :group 'lui-irc-colors)
+
+(defface lui-emphasis-face
+  '((t (:inherit italic)))
+  "Face for emphasis markup."
+  :group 'lui-irc-colors)
+
+(defface lui-deleted-face
+  '((t (:strike-through t)))
+  "Face for deleted messages"
+  :group 'lui-irc-colors)
+
+(defcustom lui-formatting-list nil
+  "List of enabled formatting types.
+Each list item is a list consisting of a regular expression
+matching the highlighted text, an integer for the submatch and a
+face for highlighting the match."
+  :type `(set
+          (const :tag "*Strong* text"
+                 (,(rx (or bol whitespace)
+                       (group "*" (+? (not (any whitespace "*"))) "*")
+                       (or eol whitespace))
+                  1 lui-strong-face))
+          (const :tag "_Emphasized_ text"
+                 (,(rx (or bol whitespace)
+                       (group "_" (+? (not (any whitespace "_"))) "_")
+                       (or eol whitespace))
+                  1 lui-emphasis-face)))
+  :group 'lui)
+
+(defcustom lui-buttons-list
+  `(("`\\([A-Za-z0-9+=*/-]+\\)'" 1
+     lui-button-elisp-symbol 1)
+    ("\\<debbugs[#:]\\([0-9]+\\)" 0
+     "https://debbugs.gnu.org/cgi/bugreport.cgi?bug=%s" 1)
+    ("\\<RFC ?\\([0-9]+\\)" 0
+     "http://www.ietf.org/rfc/rfc%s.txt" 1)
+    ("\\<CVE[- ]\\([0-9]+-[0-9]+\\)" 0
+     "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-%s" 1)
+    ("\\<SRFI[- ]?\\([0-9]+\\)" 0
+     "http://srfi.schemers.org/srfi-%s/srfi-%s.html" 1 1)
+    ("\\<PEP[- ]?\\([0-9]+\\)" 0 lui-button-pep 1)
+    ("\\<xkcd[ #]*\\([0-9]+\\)" 0
+     "https://xkcd.com/%s" 1)
+    ("\\([0-9a-zA-Z_.-]+/[0-9a-zA-Z_.-]+\\)#\\([0-9]+\\)" 0
+     "https://github.com/%s/issues/%s" 1 2))
+  "The list of buttons to buttonize.
+This consists of lists of four elements each:
+
+  (REGEXP SUBMATCH FUNCTION ARG-MATCH...)
+
+Whenever REGEXP is found, SUBMATCH is marked as a button. When
+that button is activated, FUNCTION is called with the matches
+specified in ARG-MATCHES as its arguments.
+
+If FUNCTION is a string, it is formatted with %s replaced by
+the matches in ARG-MATCHES."
+  :type '(repeat (list (regexp :tag "Regular expression")
+                       (integer :tag "Submatch to buttonize")
+                       (function :tag "Function to call for this button")
+                       (integer :tag "Submatch to pass as an argument")))
+  :group 'lui)
+
+(defcustom lui-button-issue-tracker nil
+  "A tracker URL for the current channel.
+
+This will cause simple #123 links to highlight as issue links to
+the given repository. Use %s to insert the actual number."
+  :type 'string
+  :group 'lui)
+
+(defcustom lui-fill-type "    "
+  "How Lui should fill its output.
+This can be one of the following values:
+
+  A string
+      This is used as the fill prefix
+  'variable
+      The first sequence of non-whitespace characters in the
+      output is used as an alignment, and the rest is filled with
+      spaces.
+  A number
+      The first sequence of non-whitespace characters is
+      right-aligned at this column, and the rest is filled to
+      this column.
+  nil
+      Turn filling off."
+  :type '(choice (string :tag "Fill Prefix")
+                 (const :tag "Variable Fill Prefix" variable)
+                 (integer :tag "Fill Column")
+                 (const :tag "No filling" nil))
+  :group 'lui)
+
+(defcustom lui-fill-column 70
+  "The column at which Lui should break output.
+See `fill-column'."
+  :type 'integer
+  :group 'lui)
+
+(defcustom lui-fill-remove-face-from-newline t
+  "Non-nil when filling should remove faces from newlines.
+Faces on a newline extend to the end of the displayed line, which
+is often not was is wanted."
+  :type 'boolean
+  :group 'lui)
+
+(defcustom lui-time-stamp-format "[%H:%M]"
+  "The format of time stamps.
+See `format-time-string' for a full description of available
+formatting directives."
+  :type 'string
+  :group 'lui)
+
+(defcustom lui-time-stamp-position 'right
+  "Where Lui should put time-stamps.
+This can be one of the following values:
+
+  A number
+      At this column of the first line of output
+  'right
+      At a column just right to `lui-fill-column'
+  'left
+      At the left side of the output. The output is thereby moved
+      to the right.
+  'right-margin
+      In the right margin.  You will need to set `right-margin-width'
+      in all circe buffers.
+  'left-margin
+      In the left margin.  You will need to set `left-margin-width'
+      in all circe buffers.
+  nil
+      Do not add any time stamp."
+  :type '(choice (const :tag "Right" right)
+                 (integer :tag "Column")
+                 (const :tag "Left" left)
+                 (const :tag "Right Margin" right-margin)
+                 (const :tag "Left Margin" left-margin)
+                 (const :tag "None" nil))
+  :group 'lui)
+
+(defcustom lui-time-stamp-only-when-changed-p t
+  "Non-nil if Lui should only add a time stamp when the time changes.
+If `lui-time-stamp-position' is 'left, this will still add the
+necessary whitespace."
+  :type 'boolean
+  :group 'lui)
+
+(defcustom lui-read-only-output-p t
+  "Non-nil if Lui should make the output read-only.
+Switching this off makes copying (by killing) easier for some."
+  :type 'boolean
+  :group 'lui)
+
+(defcustom lui-max-buffer-size 102400
+  "Non-nil if Lui should truncate the buffer if it grows too much.
+If the buffer size (in characters) exceeds this number, it is
+truncated at the top."
+  :type '(choice (const :tag "Never Truncate" nil)
+                 (integer :tag "Maximum Buffer Size"))
+  :group 'lui)
+
+(defcustom lui-input-ring-size 32
+  "The size of the input history of Lui.
+This is the size of the input history used by
+\\[lui-previous-input] and \\[lui-next-input]."
+  :type 'integer
+  :group 'lui)
+
+(defcustom lui-mode-hook nil
+  "The hook run when Lui is started."
+  :type 'hook
+  :group 'lui)
+
+(defcustom lui-pre-input-hook nil
+  "A hook run before Lui interprets the user input.
+It is called with the buffer narrowed to the input line.
+Functions can modify the input if they really want to, but the
+user won't see the modifications, so that's a bad idea."
+  :type 'hook
+  :group 'lui)
+
+(defcustom lui-pre-output-hook nil
+  "The hook run before output is formatted."
+  :type 'hook
+  :group 'lui)
+
+(defcustom lui-post-output-hook nil
+  "The hook run after output has been formatted."
+  :type 'hook
+  :group 'lui)
+
+(defface lui-time-stamp-face
+  '((t (:foreground "SlateBlue" :weight bold)))
+  "Lui mode face used for time stamps."
+  :group 'lui)
+
+(defface lui-highlight-face
+  ;; Taken from `font-lock-keyword-face'
+  '((((class grayscale) (background light)) (:foreground "LightGray" :weight bold))
+    (((class grayscale) (background dark)) (:foreground "DimGray" :weight bold))
+    (((class color) (background light)) (:foreground "Purple"))
+    (((class color) (background dark)) (:foreground "Cyan1"))
+    (t (:weight bold)))
+  "Lui mode face used for highlighting."
+  :group 'lui)
+
+(defface lui-button-face
+  '((((class color) (background light)) (:foreground "Purple" :underline t))
+    (((class color) (background dark)) (:foreground "Cyan" :underline t))
+    (t (:underline t)))
+  "Default face used for LUI buttons."
+  :group 'lui)
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;
+;;; Client interface ;;;
+;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defvar lui-input-function nil
+  "The function to be called for Lui input.
+This function is called with a single argument, the input
+string.")
+(make-variable-buffer-local 'lui-input-function)
+
+(defvar lui-completion-function 'completion-at-point
+  "A function called to actually do completion.")
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; Private variables ;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defvar lui-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "RET") 'lui-send-input)
+    (define-key map (kbd "TAB") 'lui-next-button-or-complete)
+    (define-key map (kbd "<backtab>") 'lui-previous-button)
+    (define-key map (kbd "<S-tab>") 'lui-previous-button)
+    (define-key map (kbd "M-p") 'lui-previous-input)
+    (define-key map (kbd "M-n") 'lui-next-input)
+    (define-key map (kbd "C-c C-u") 'lui-kill-to-beginning-of-line)
+    (define-key map (kbd "C-c C-i") 'lui-fool-toggle-display)
+    map)
+  "The key map used in Lui modes.")
+
+(defvar lui-input-marker nil
+  "The marker where input should be inserted.")
+(make-variable-buffer-local 'lui-input-marker)
+
+(defvar lui-output-marker nil
+  "The marker where output should be inserted.
+Use `lui-insert' instead of accessing this marker directly.")
+(make-variable-buffer-local 'lui-output-marker)
+
+(defvar lui-input-ring nil
+  "The input history ring.")
+(make-variable-buffer-local 'lui-input-ring)
+
+(defvar lui-input-ring-index nil
+  "The index to the current item in the input ring.")
+(make-variable-buffer-local 'lui-input-ring-index)
+
+
+;;;;;;;;;;;;;;
+;;; Macros ;;;
+;;;;;;;;;;;;;;
+
+(defmacro lui-save-undo-list (&rest body)
+  "Run BODY without modifying the undo list."
+  (let ((old-marker-sym (make-symbol "old-marker")))
+    `(let ((,old-marker-sym (marker-position lui-input-marker))
+           (val nil))
+       ;; Don't modify the undo list. The undo list is for the user's
+       ;; input only.
+       (let ((buffer-undo-list t))
+         (setq val (progn ,@body)))
+       (when (consp buffer-undo-list)
+         ;; Not t :-)
+         (lui-adjust-undo-list  ,old-marker-sym (- lui-input-marker
+                                                   ,old-marker-sym)))
+       val)))
+
+
+;;;;;;;;;;;;;;;;;;
+;;; Major Mode ;;;
+;;;;;;;;;;;;;;;;;;
+
+(define-derived-mode lui-mode nil "LUI"
+  "The Linewise User Interface mode.
+This can be used as a user interface for various applications.
+Those should define derived modes of this, so this function
+should never be called directly.
+
+It can be customized for an application by specifying a
+`lui-input-function'."
+  (setq lui-input-marker (make-marker)
+        lui-output-marker (make-marker)
+        lui-input-ring (make-ring lui-input-ring-size)
+        lui-input-ring-index nil
+        flyspell-generic-check-word-p 'lui-flyspell-check-word-p)
+  (set-marker lui-input-marker (point-max))
+  (set-marker lui-output-marker (point-max))
+  (add-hook 'window-scroll-functions 'lui-scroll-window nil t)
+  (add-hook 'post-command-hook 'lui-scroll-post-command)
+  (add-hook 'change-major-mode-hook 'lui-change-major-mode nil t)
+  (lui-paren-highlighting)
+  (lui-time-stamp-enable-filtering)
+  (tracking-mode 1)
+  (auto-fill-mode 0)
+  (when (fboundp 'cursor-intangible-mode)
+    (cursor-intangible-mode 1))
+  (when lui-flyspell-p
+    (require 'flyspell)
+    (lui-flyspell-change-dictionary)))
+
+(defun lui-change-major-mode ()
+  "Assure that the user really wants to change the major mode.
+This is a good value for a buffer-local `change-major-mode-hook'."
+  (when (not (y-or-n-p "Really change major mode in a Lui buffer? "))
+    (error "User disallowed mode change")))
+
+(defun lui-scroll-window (window _display-start)
+  "Scroll the input line to the bottom of the WINDOW.
+
+DISPLAY-START is passed by the hook `window-scroll-functions' and
+is ignored.
+
+See `lui-scroll-behavior' for how to customize this."
+  (when (and (eq lui-scroll-behavior 'post-scroll)
+             window
+             (window-live-p window))
+    (with-selected-window window
+      (when (or (>= (point) lui-input-marker)
+                (equal (point-max)
+                       (window-end nil t)))
+        (let ((resize-mini-windows nil))
+          (save-excursion
+            (goto-char (point-max))
+            (recenter -1)))))))
+
+(defun lui-scroll-post-command ()
+  "Scroll the input line to the bottom of the window.
+
+This is called from `post-command-hook'.
+
+See `lui-scroll-behavior' for how to customize this."
+  (condition-case err
+      (dolist (w (window-list))
+        (with-current-buffer (window-buffer w)
+          (when (and lui-input-marker
+                     (memq lui-scroll-behavior '(t post-command)))
+            ;; Code from ERC's erc-goodies.el. I think this was originally
+            ;; mine anyhow, not sure though.
+            (save-restriction
+              (widen)
+              (when (>= (point) lui-input-marker)
+                (save-excursion
+                  (goto-char (point-max))
+                  (with-selected-window w
+                    (recenter -1))))))))
+    (error
+     (message "Error in lui-scroll-post-command: %S" err)
+     )))
+
+(defun lui-scroll-post-output ()
+  "Scroll the input line to the bottom of the window.
+
+This is called when lui output happens.
+
+See `lui-scroll-behavior' for how to customize this."
+  (when (memq lui-scroll-behavior '(t post-output))
+    (let ((resize-mini-windows nil))
+      (dolist (window (get-buffer-window-list (current-buffer) nil t))
+        (when (or (>= (point) lui-input-marker)
+                  (equal (point-max)
+                         (window-end window)))
+          (with-selected-window window
+            (save-excursion
+              (goto-char (point-max))
+              (recenter -1))))))))
+
+
+;;;;;;;;;;;;;
+;;; Input ;;;
+;;;;;;;;;;;;;
+
+(defun lui-send-input ()
+  "Send the current input to the Lui application.
+If point is not in the input area, insert a newline."
+  (interactive)
+  (if (< (point) lui-input-marker)
+      (newline)
+    (save-restriction
+      (narrow-to-region lui-input-marker (point-max))
+      (run-hooks 'lui-pre-input-hook))
+    (let ((input (buffer-substring lui-input-marker (point-max))))
+      (delete-region lui-input-marker (point-max))
+      (lui-add-input input)
+      (if lui-input-function
+          (funcall lui-input-function input)
+        (error "No input function specified")))))
+
+(defun lui-add-input (input)
+  "Add INPUT as if entered by the user."
+  (ring-insert lui-input-ring input)
+  (setq lui-input-ring-index nil))
+
+
+;;;;;;;;;;;;;;;
+;;; Buttons ;;;
+;;;;;;;;;;;;;;;
+
+(define-button-type 'lui-button
+  'supertype 'button
+  'follow-link t
+  'face 'lui-button-face)
+
+(defun lui-buttonize ()
+  "Buttonize the current message."
+  (lui-buttonize-urls)
+  (lui-buttonize-custom)
+  (lui-buttonize-issues))
+
+(defun lui-buttonize-custom ()
+  "Add custom buttons to the current message.
+
+This uses `lui-buttons-list'."
+  (dolist (entry lui-buttons-list)
+    (let ((regex (nth 0 entry))
+          (submatch (nth 1 entry))
+          (function-or-url (nth 2 entry))
+          (arg-matches (nthcdr 3 entry)))
+      (goto-char (point-min))
+      (while (re-search-forward regex nil t)
+        ;; Ensure we're not inserting a button inside a URL button
+        (when (not (button-at (match-beginning 0)))
+          (let* ((function (if (functionp function-or-url)
+                               function-or-url
+                             'browse-url))
+                 (matches (mapcar (lambda (n)
+                                    (match-string-no-properties n))
+                                  arg-matches))
+                 (arguments (if (functionp function-or-url)
+                                matches
+                              (list (apply #'format function-or-url
+                                           matches)))))
+            (make-button (match-beginning submatch)
+                         (match-end submatch)
+                         'type 'lui-button
+                         'action 'lui-button-activate
+                         'lui-button-function function
+                         'lui-button-arguments arguments)))))))
+
+(defun lui-buttonize-issues ()
+  "Buttonize issue references in the current message, if configured."
+  (when lui-button-issue-tracker
+    (goto-char (point-min))
+    (while (re-search-forward "\\(?:^\\|\\W\\)\\(#\\([0-9]+\\)\\)" nil t)
+      ;; Ensure we're not inserting a button inside a URL button
+      (when (not (button-at (point)))
+        (make-button (match-beginning 1)
+                     (match-end 1)
+                     'type 'lui-button
+                     'action 'lui-button-activate
+                     'lui-button-function 'browse-url
+                     'lui-button-arguments
+                     (list (format lui-button-issue-tracker
+                                   (match-string 2))))))))
+
+(defun lui-buttonize-urls ()
+  "Buttonize URLs in the current message."
+  (let ((regex (regexp-opt thing-at-point-uri-schemes)))
+    (goto-char (point-min))
+    (while (re-search-forward regex nil t)
+      (let ((bounds (bounds-of-thing-at-point 'url)))
+        (when bounds
+          (make-button (car bounds)
+                       (cdr bounds)
+                       'type 'lui-button
+                       'action 'lui-button-activate
+                       'lui-button-function 'browse-url
+                       'lui-button-arguments
+                       (list (buffer-substring-no-properties
+                              (car bounds)
+                              (cdr bounds)))))))))
+
+(defun lui-button-activate (button)
+  "Activate BUTTON.
+This calls the function stored in the `lui-button-function'
+property with the argument stored in `lui-button-arguments'."
+  (apply (button-get button 'lui-button-function)
+         (button-get button 'lui-button-arguments)))
+
+(defun lui-next-button-or-complete ()
+  "Go to the next button, or complete at point.
+When point is in the input line, call `lui-completion-function'.
+Otherwise, we move to the next button."
+  (interactive)
+  (if (>= (point)
+          lui-input-marker)
+      (funcall lui-completion-function)
+    (forward-button 1)))
+
+(defun lui-previous-button ()
+  "Go to the previous button."
+  (interactive)
+  (backward-button 1))
+
+(defun lui-button-elisp-symbol (name)
+  "Show the documentation for the symbol named NAME."
+  (let ((sym (intern-soft name)))
+    (cond
+     ((not sym)
+      (message "No such symbol %s" name)
+      (ding))
+     (t
+      (help-xref-interned sym)))))
+
+(defun lui-button-pep (number)
+  "Browse the PEP NUMBER."
+  (browse-url (format "https://www.python.org/dev/peps/pep-%04i"
+                      (string-to-number number))))
+
+(defun lui-button-issue (issue)
+  "Browse the issue tracker number ISSUE, if configured."
+  (if lui-button-issue-tracker
+      (browse-url (format lui-button-issue-tracker issue))
+    (error "No issue tracker configured, see `lui-button-issue-tracker'")))
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; Input Line Killing ;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun lui-kill-to-beginning-of-line ()
+  "Kill the input from point to the beginning of the input."
+  (interactive)
+  (let* ((beg (point-at-bol))
+         (end (point))
+         (str (buffer-substring beg end)))
+    (delete-region beg end)
+    (kill-new str)))
+
+
+;;;;;;;;;;;;;;;;;;;;;
+;;; Input History ;;;
+;;;;;;;;;;;;;;;;;;;;;
+
+;; FIXME!
+;; These need some better algorithm. They clobber input when it is not
+;; in the ring!
+(defun lui-previous-input ()
+  "Cycle through the input history to the last input."
+  (interactive)
+  (when (> (ring-length lui-input-ring) 0)
+    (if (and lui-input-ring-index
+             (= (1- (ring-length lui-input-ring))
+                lui-input-ring-index))
+        ;; last item - insert a single empty line
+        (progn
+          (lui-replace-input "")
+          (setq lui-input-ring-index nil))
+      ;; If any input is left, store it in the input ring
+      (when (and (null lui-input-ring-index)
+                 (> (point-max) lui-input-marker))
+        (ring-insert lui-input-ring
+                     (buffer-substring lui-input-marker (point-max)))
+        (setq lui-input-ring-index 0))
+      ;; Increment the index
+      (setq lui-input-ring-index
+            (if lui-input-ring-index
+                (ring-plus1 lui-input-ring-index (ring-length lui-input-ring))
+              0))
+      ;; And insert the last input
+      (lui-replace-input (ring-ref lui-input-ring lui-input-ring-index))
+      (goto-char (point-max)))))
+
+(defun lui-next-input ()
+  "Cycle through the input history to the next input."
+  (interactive)
+  (when (> (ring-length lui-input-ring) 0)
+    (if (and lui-input-ring-index
+             (= 0 lui-input-ring-index))
+        ;; first item - insert a single empty line
+        (progn
+          (lui-replace-input "")
+          (setq lui-input-ring-index nil))
+      ;; If any input is left, store it in the input ring
+      (when (and (null lui-input-ring-index)
+                 (> (point-max) lui-input-marker))
+        (ring-insert lui-input-ring
+                     (buffer-substring lui-input-marker (point-max)))
+        (setq lui-input-ring-index 0))
+      ;; Decrement the index
+      (setq lui-input-ring-index (ring-minus1 (or lui-input-ring-index 0)
+                                              (ring-length lui-input-ring)))
+      ;; And insert the next input
+      (lui-replace-input (ring-ref lui-input-ring lui-input-ring-index))
+      (goto-char (point-max)))))
+
+(defun lui-replace-input (str)
+  "Replace input with STR."
+  (save-excursion
+    (goto-char lui-input-marker)
+    (delete-region lui-input-marker (point-max))
+    (insert str)))
+
+
+;;;;;;;;;;;;;
+;;; Fools ;;;
+;;;;;;;;;;;;;
+
+(defun lui-fools ()
+  "Propertize the current narrowing according to foolhardiness.
+That is, if any part of it has the text property 'lui-fool set,
+make the whole thing invisible."
+  (when (text-property-any (point-min)
+                           (point-max)
+                           'lui-fool t)
+    (add-text-properties (point-min)
+                         (point-max)
+                         '(invisible lui-fool))))
+
+(defun lui-fools-hidden-p ()
+  "Return whether fools are currently hidden."
+  (if (or (eq t buffer-invisibility-spec)
+          (memq 'lui-fool buffer-invisibility-spec))
+      t
+    nil))
+
+(defun lui-fool-toggle-display ()
+  "Display what fools have said."
+  (interactive)
+  (when (eq buffer-invisibility-spec t)
+    (add-to-invisibility-spec 'lui-fool))
+  (cond
+   ((lui-fools-hidden-p)
+    (message "Now showing the gibberish of fools")
+    (remove-from-invisibility-spec 'lui-fool))
+   (t
+    (message "Now hiding fools again *phew*")
+    (add-to-invisibility-spec 'lui-fool)))
+  ;; For some reason, after this, the display does not always update
+  ;; (issue #31). Force an update just in case.
+  (force-mode-line-update t))
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; Blink Paren and Show Paren Mode ;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun lui-paren-highlighting ()
+  "Enable sane parenthesis highlighting in this buffer."
+  (set (make-local-variable 'blink-paren-function)
+       'lui-blink-paren-function)
+  (when (boundp 'show-paren-data-function)
+    (set (make-local-variable 'show-paren-data-function)
+         'lui-show-paren-data-function)))
+
+(defun lui-blink-paren-function ()
+  "Do not blink opening parens outside of the lui input area.
+
+When point is within the lui input area, inserting a closing
+parenthesis should only blink parens within the input area, not
+outside of it.
+
+This is a suitable value for `blink-paren-function', which see."
+  (if (> (point) lui-input-marker)
+      (let ((blink-matching-paren-distance (- (point)
+                                              lui-input-marker)))
+        (blink-matching-open))
+    (blink-matching-open)))
+
+(defun lui-show-paren-data-function ()
+  "Show parens only within the input area.
+
+When `show-paren-mode' is enabled, and point is in the input
+area, parenthesis highlighting should only happen within the
+input area, not include the rest of the buffer.
+
+This is a suitable value for `show-paren-data-function', which see."
+  (when (fboundp 'show-paren--default)
+    (let ((range (show-paren--default)))
+      (if (or (< (point) lui-input-marker)
+              (not (elt range 2))
+              (>= (elt range 2) lui-input-marker))
+          range
+        nil))))
+
+
+;;;;;;;;;;;;;;;;
+;;; Flyspell ;;;
+;;;;;;;;;;;;;;;;
+
+(defun lui-flyspell-change-dictionary (&optional dictionary)
+  "*Change flyspell to DICTIONARY.
+If DICTIONARY is nil, set a default dictionary according to
+`lui-flyspell-alist'.
+If it is \"\", disable flyspell."
+  (interactive (list (completing-read
+                      "Use new dictionary (RET for none, SPC to complete): "
+                      (and (fboundp 'ispell-valid-dictionary-list)
+                           (mapcar 'list (ispell-valid-dictionary-list)))
+                      nil t)))
+  (let ((dictionary (or dictionary
+                        (lui-find-dictionary (buffer-name)))))
+    (when flyspell-mode
+      (flyspell-mode 0))
+    (when (and dictionary
+               (not (equal dictionary "")))
+      (ispell-change-dictionary dictionary))
+    (flyspell-mode 1)))
+
+
+(defun lui-find-dictionary (buffer-name)
+  "Return a dictionary appropriate for BUFFER-NAME."
+  (let ((lis lui-flyspell-alist)
+        (result nil))
+    (while lis
+      (if (string-match (caar lis) buffer-name)
+          (setq result (cadr (car lis))
+                lis nil)
+         (setq lis (cdr lis))))
+    result))
+
+(defun lui-flyspell-check-word-p ()
+  "Return non-nil when flyspell should verify at this position.
+This is the value of Lui for `flyspell-generic-check-word-p'."
+  (>= (point)
+      lui-input-marker))
+
+
+;;;;;;;;;;;;;;
+;;; Output ;;;
+;;;;;;;;;;;;;;
+
+(defvar lui-message-id 0
+  "Unique id for each message.
+Used to allow navigation between messages and editing and
+deleting.")
+(make-variable-buffer-local 'lui-message-id)
+
+(defvar lui-internal-text-properties '(lui-formatted-time-stamp
+                                       lui-time-stamp-last
+                                       lui-raw-text
+                                       lui-message-id
+                                       lui-saved-text-properties)
+  "Text properties used internally by lui.
+
+These are always kept when replacing messages.")
+
+(defun lui-insert (str &optional not-tracked-p)
+  "Insert STR into the current Lui buffer.
+
+If NOT-TRACKED-P is given, this insertion won't trigger tracking
+of the buffer."
+  (if not-tracked-p
+      (lui-insert-with-text-properties str 'not-tracked-p t)
+    (lui-insert-with-text-properties str)))
+
+(defun lui-plist-keys (plist)
+  "Get the keys from PLIST.
+
+PLIST should be a flat list with keys and values alternating,
+like used for setting and getting text properties."
+  (let ((key t) result)
+    (dolist (item plist (reverse result))
+      (when key
+        (push item result))
+      (setq key (not key)))))
+
+(defun lui-insert-with-text-properties (str &rest text-properties)
+  "Insert STR into the current Lui buffer.
+
+TEXT-PROPERTIES is a property list containing text properties to
+add to the inserted message."
+  (let ((not-tracked-p (plist-get text-properties 'not-tracked-p))
+        (saved-text-properties (append (lui-plist-keys text-properties)
+                                       lui-internal-text-properties)))
+    (lui-save-undo-list
+     (save-excursion
+       (save-restriction
+         (let ((inhibit-read-only t)
+               (inhibit-point-motion-hooks t))
+           (widen)
+           (goto-char lui-output-marker)
+           (let ((beg (point))
+                 (end nil))
+             (insert str "\n")
+             (setq end (point))
+             (set-marker lui-output-marker (point))
+             (narrow-to-region beg end))
+           (goto-char (point-min))
+           (add-text-properties (point-min)
+                                (point-max)
+                                `(lui-raw-text ,str))
+           (run-hooks 'lui-pre-output-hook)
+           (lui-apply-formatting)
+           (lui-highlight-keywords)
+           (lui-buttonize)
+           (lui-fill)
+           (lui-time-stamp
+            (plist-get text-properties 'lui-formatted-time-stamp))
+           (goto-char (point-min))
+           (add-text-properties
+            (point-min) (point-max)
+            (plist-put text-properties 'lui-message-id lui-message-id))
+           (setq lui-message-id (1+ lui-message-id))
+           (run-hooks 'lui-post-output-hook)
+           (lui-fools)
+           (goto-char (point-min))
+           (add-text-properties
+            (point-min) (point-max)
+            `(lui-saved-text-properties ,saved-text-properties))
+           (let ((faces (lui-faces-in-region (point-min)
+                                             (point-max)))
+                 (foolish (text-property-any (point-min)
+                                             (point-max)
+                                             'lui-fool t))
+                 (not-tracked-p
+                  (or not-tracked-p
+                      (text-property-any (point-min)
+                                         (point-max)
+                                         'lui-do-not-track t))))
+             (widen)
+             (lui-truncate)
+             (lui-read-only)
+             (when (and (not not-tracked-p)
+                        (not foolish))
+               (tracking-add-buffer (current-buffer)
+                                    faces)))
+           (lui-scroll-post-output)))))))
+
+(defun lui--adjust-p (pos old)
+  (and (numberp pos) (>= (abs pos) old)))
+
+(defun lui--new-pos (pos shift)
+  (* (if (< pos 0) -1 1) (+ (abs pos) shift)))
+
+(defun lui-adjust-undo-list (old-begin shift)
+  ;; Translate buffer positions in buffer-undo-list by SHIFT.
+  (unless (or (zerop shift) (atom buffer-undo-list))
+    (let ((list buffer-undo-list) elt)
+      (while list
+        (setq elt (car list))
+        (cond ((integerp elt)           ; POSITION
+               (if (lui--adjust-p elt old-begin)
+                   (setf (car list) (lui--new-pos elt shift))))
+              ((or (atom elt)           ; nil, EXTENT
+                   (markerp (car elt))) ; (MARKER . DISTANCE)
+               nil)
+              ((integerp (car elt))     ; (BEGIN . END)
+               (if (lui--adjust-p (car elt) old-begin)
+                   (setf (car elt) (lui--new-pos (car elt) shift)))
+               (if (lui--adjust-p (cdr elt) old-begin)
+                   (setf (cdr elt) (lui--new-pos (cdr elt) shift))))
+              ((stringp (car elt))      ; (TEXT . POSITION)
+               (if (lui--adjust-p (cdr elt) old-begin)
+                   (setf (cdr elt) (lui--new-pos (cdr elt) shift))))
+              ((null (car elt))         ; (nil PROPERTY VALUE BEG . END)
+               (let ((cons (nthcdr 3 elt)))
+                 (if (lui--adjust-p (car cons) old-begin)
+                     (setf (car cons) (lui--new-pos (car cons) shift)))
+                 (if (lui--adjust-p (cdr cons) old-begin)
+                     (setf (cdr cons) (lui--new-pos (cdr cons) shift)))))
+              ((and (featurep 'xemacs)
+                    (extentp (car elt))) ; (EXTENT START END)
+               (if (lui--adjust-p (nth 1 elt) old-begin)
+                     (setf (nth 1 elt) (lui--new-pos (nth 1 elt) shift)))
+                 (if (lui--adjust-p (nth 2 elt) old-begin)
+                     (setf (nth 2 elt) (lui--new-pos (nth 2 elt) shift)))))
+        (setq list (cdr list))))))
+
+(defvar lui-prompt-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "<end>") 'lui-prompt-end-of-line)
+    (define-key map (kbd "C-e") 'lui-prompt-end-of-line)
+    map)
+  "Keymap for Lui prompts.
+Since \\[end-of-line] can't move out of fields, this DTRT for an
+unexpecting user.")
+
+(defun lui-set-prompt (prompt)
+  "Set PROMPT as the current Lui prompt."
+  (let ((inhibit-read-only t))
+    (lui-save-undo-list
+     (save-excursion
+       (goto-char lui-output-marker)
+       (insert prompt)
+       (if (> lui-input-marker (point))
+           (delete-region (point) lui-input-marker)
+         (set-marker lui-input-marker (point)))
+       (add-text-properties lui-output-marker lui-input-marker
+                            `(read-only t
+                                        rear-nonsticky t
+                                        field lui-prompt
+                                        keymap ,lui-prompt-map
+                                        front-sticky t
+                                        ))))))
+
+(defun lui-prompt-end-of-line (&optional _N)
+  "Move past the prompt, and then to the end of the line.
+This uses `end-of-line'.
+
+The argument N is ignored."
+  (interactive "p")
+  (goto-char lui-input-marker)
+  (call-interactively 'end-of-line))
+
+(defun lui-faces-in-region (beg end)
+  "Return a face that describes the region between BEG and END."
+  (goto-char beg)
+  (let ((faces nil))
+    (while (not (= (point) end))
+      (let ((face (get-text-property (point) 'face)))
+        (dolist (face (if (consp face)
+                          face
+                        (list face)))
+          (when (and face
+                     (facep face)
+                     (face-differs-from-default-p face))
+            (push face faces)))
+        (goto-char (next-single-property-change (point) 'face
+                                                nil end))))
+    faces))
+
+
+
+;;;;;;;;;;;;;;;;;;;;
+;;; Highlighting ;;;
+;;;;;;;;;;;;;;;;;;;;
+
+(defun lui-highlight-keywords ()
+  "Highlight the entries in the variable `lui-highlight-keywords'.
+
+This is called automatically when new text is inserted."
+  (let ((regex (lambda (entry)
+                 (if (stringp entry)
+                     entry
+                   (car entry))))
+        (submatch (lambda (entry)
+                    (if (and (consp entry)
+                             (numberp (cadr entry)))
+                        (cadr entry)
+                      0)))
+        (properties (lambda (entry)
+                      (let ((face (cond
+                                   ;; REGEXP
+                                   ((stringp entry)
+                                    'lui-highlight-face)
+                                   ;; (REGEXP SUBMATCH)
+                                   ((and (numberp (cadr entry))
+                                         (null (cddr entry)))
+                                    'lui-highlight-face)
+                                   ;; (REGEXP FACE)
+                                   ((null (cddr entry))
+                                    (cadr entry))
+                                   ;; (REGEXP SUBMATCH FACE)
+                                   (t
+                                    (nth 2 entry)))))
+                        (if (facep face)
+                            `(face ,face)
+                          face)))))
+    (dolist (entry lui-highlight-keywords)
+      (goto-char (point-min))
+      (while (re-search-forward (funcall regex entry) nil t)
+        (let* ((exp (funcall submatch entry))
+               (beg (match-beginning exp))
+               (end (match-end exp)))
+          (when (not (text-property-any beg end 'lui-highlight-fontified-p t))
+            (add-text-properties beg end
+                                 (append (funcall properties entry)
+                                         '(lui-highlight-fontified-p t)))))))))
+
+(defun lui-apply-formatting ()
+  "Highlight the entries in `lui-formatting-list'."
+  (dolist (entry lui-formatting-list)
+    (goto-char (point-min))
+    (let ((re (car entry))
+          (subgroup (cadr entry))
+          (face (nth 2 entry)))
+      (while (re-search-forward re nil t)
+        (when face
+          (add-face-text-property (match-beginning subgroup) (match-end subgroup)
+                                  face nil (current-buffer)))))))
+
+
+;;;;;;;;;;;;;;;
+;;; Filling ;;;
+;;;;;;;;;;;;;;;
+
+(defun lui-fill ()
+  "Fill the text in the buffer.
+This is called automatically when new text is inserted. See
+`lui-fill-type' and `lui-fill-column' on how to customize this
+function."
+  (cond
+   ((stringp lui-fill-type)
+    (let ((fill-prefix lui-fill-type)
+          (fill-column (or lui-fill-column
+                           fill-column)))
+      (fill-region (point-min) (point-max)
+                   nil t)))
+   ((eq lui-fill-type 'variable)
+    (let ((fill-prefix (save-excursion
+                         (goto-char (point-min))
+                         (let ((beg (point)))
+                           (re-search-forward "\\s-" nil t)
+                           (make-string (- (point) beg) ? ))))
+          (fill-column (or lui-fill-column
+                           fill-column)))
+      (fill-region (point-min) (point-max)
+                   nil t)))
+   ((numberp lui-fill-type)
+    (let ((right-end (save-excursion
+                       (goto-char (point-min))
+                       (re-search-forward "\\s-" nil t)
+                       (- (point)
+                          (point-at-bol)))))
+      (goto-char (point-min))
+      (when (< right-end lui-fill-type)
+        (insert (make-string (- lui-fill-type
+                                right-end)
+                             ? )))
+      (let ((fill-prefix (make-string lui-fill-type ? ))
+            (fill-column (or lui-fill-column
+                             fill-column)))
+        (fill-region (point-min) (point-max)
+                     nil t)))))
+  (when lui-fill-remove-face-from-newline
+    (goto-char (point-min))
+    (while (re-search-forward "\n" nil t)
+      (put-text-property (match-beginning 0)
+                         (match-end 0)
+                         'face
+                         nil))))
+
+
+;;;;;;;;;;;;;;;;;;;
+;;; Time Stamps ;;;
+;;;;;;;;;;;;;;;;;;;
+
+(defvar lui-time-stamp-last nil
+  "The last time stamp.")
+(make-variable-buffer-local 'lui-time-stamp-last)
+
+(defvar lui-time-stamp-time nil
+  "A custom time to use as the time stamp for `lui-insert'.
+
+This variable should be let-bound when you wish to provide a
+custom time to be printed by `lui-time-stamp'.  If this variable
+is nil the current time is used.  See the TIME argument to
+`format-time-string' for more information.")
+
+(defvar lui-time-stamp-zone nil
+  "A custom timezone to use for the time stamp for `lui-insert'.
+
+This variable should be let-bound when you wish to provide a
+custom time zone when printing the time stamp with
+`lui-time-stamp'.  If this variable is nil local time is used.
+See the ZONE argument to `format-time-string' for more
+information.")
+
+(defun lui-time-stamp (&optional text)
+  "Add a time stamp to the current buffer.
+
+If TEXT is specified, use that instead of formatting a new time stamp."
+  (let ((ts (or text
+                (format-time-string lui-time-stamp-format
+                                    lui-time-stamp-time
+                                    lui-time-stamp-zone))))
+    (cond
+     ;; Time stamps right
+     ((or (numberp lui-time-stamp-position)
+          (eq lui-time-stamp-position 'right))
+      (when (or (not lui-time-stamp-only-when-changed-p)
+                (not lui-time-stamp-last)
+                (not (string= ts lui-time-stamp-last)))
+        (goto-char (point-min))
+        (goto-char (point-at-eol))
+        (let* ((curcol (current-column))
+               (col (if (numberp lui-time-stamp-position)
+                        lui-time-stamp-position
+                      (+ 2 (or lui-fill-column
+                               fill-column
+                               (point)))))
+               (indent (if (> col curcol)
+                           (- col curcol)
+                         1))
+               (ts-string (propertize
+                           (concat (make-string indent ?\s)
+                                   (propertize
+                                    ts
+                                    'face 'lui-time-stamp-face))
+                           'lui-time-stamp t))
+               (start (point)))
+          (insert ts-string)
+          (add-text-properties start (1+ (point)) '(intangible t))
+          (add-text-properties (1+ start) (point) '(cursor-intangible t)))))
+     ;; Time stamps left
+     ((eq lui-time-stamp-position 'left)
+      (let ((indent-string (propertize (make-string (length ts) ?\s)
+                                       'lui-time-stamp t)))
+        (goto-char (point-min))
+        (cond
+         ;; Time stamp
+         ((or (not lui-time-stamp-only-when-changed-p)
+              (not lui-time-stamp-last)
+              (not (string= ts lui-time-stamp-last)))
+          (insert (propertize ts
+                              'face 'lui-time-stamp-face
+                              'lui-time-stamp t)))
+         ;; Just indentation
+         (t
+          (insert indent-string)))
+        (forward-line 1)
+        (while (< (point) (point-max))
+          (insert indent-string)
+          (forward-line 1))))
+     ;; Time stamps in margin
+     ((or (eq lui-time-stamp-position 'right-margin)
+          (eq lui-time-stamp-position 'left-margin))
+      (when (or (not lui-time-stamp-only-when-changed-p)
+                (not lui-time-stamp-last)
+                (not (string= ts lui-time-stamp-last)))
+        (goto-char (point-min))
+        (when lui-fill-type
+          (goto-char (point-at-eol)))
+        (let* ((ts (propertize ts 'face 'lui-time-stamp-face))
+               (ts-margin (propertize
+                           " "
+                           'display `((margin ,lui-time-stamp-position)
+                                      ,ts)
+                           'lui-time-stamp t)))
+          (insert ts-margin)))))
+    (add-text-properties (point-min) (point-max)
+                         `(lui-formatted-time-stamp ,ts
+                           lui-time-stamp-last ,lui-time-stamp-last))
+    (setq lui-time-stamp-last ts)))
+
+(defun lui-time-stamp-enable-filtering ()
+  "Enable filtering of timestamps from copied text."
+  (set (make-local-variable 'filter-buffer-substring-functions)
+       '(lui-filter-buffer-time-stamps)))
+
+(defun lui-filter-buffer-time-stamps (fun beg end delete)
+  "Filter text from copied strings.
+
+This is meant for the variable `filter-buffer-substring-functions',
+which see for an explanation of the argument FUN, BEG, END and
+DELETE."
+  (let ((string (funcall fun beg end delete))
+        (inhibit-point-motion-hooks t)
+        (inhibit-read-only t)
+        ;; Emacs 24.4, 24.5
+        deactivate-mark)
+    (with-temp-buffer
+      (insert string)
+      (let ((start (text-property-any (point-min)
+                                      (point-max)
+                                      'lui-time-stamp t)))
+        (while start
+          (let ((end (next-single-property-change start 'lui-time-stamp
+                                                  nil (point-max))))
+            (delete-region start end)
+            (setq start (text-property-any (point-min) (point-max)
+                                           'lui-time-stamp t))))
+        (buffer-string)))))
+
+(defun lui-time-stamp-buffer-substring (buffer-string)
+  "Filter text from copied strings.
+
+This is meant for the variable `buffer-substring-filters',
+which see for an explanation of the argument BUFFER-STRING."
+  (lui-filter-buffer-time-stamps (lambda (_beg _end _delete)
+                                  buffer-string)
+                                nil nil nil))
+
+
+;;;;;;;;;;;;;;;;;;
+;;; Truncating ;;;
+;;;;;;;;;;;;;;;;;;
+
+(defun lui-truncate ()
+  "Truncate the current buffer if it exceeds `lui-max-buffer-size'."
+  (when (and lui-max-buffer-size
+             (> (point-max)
+                lui-max-buffer-size))
+    (goto-char (- (point-max)
+                  lui-max-buffer-size))
+    (forward-line 0)
+    (let ((inhibit-read-only t))
+      (delete-region (point-min) (point)))))
+
+
+;;;;;;;;;;;;;;;;;
+;;; Read-Only ;;;
+;;;;;;;;;;;;;;;;;
+
+(defun lui-read-only ()
+  "Make the current output read-only if `lui-read-only-output-p' is non-nil."
+  (when lui-read-only-output-p
+    (add-text-properties (point-min) lui-output-marker
+                         '(read-only t
+                           front-sticky t))))
+
+
+;;;;;;;;;;;;;;;;;;
+;;; Navigation ;;;
+;;;;;;;;;;;;;;;;;;
+
+(defun lui-at-message-p ()
+  "Check if point is on a message."
+  (get-text-property (point) 'lui-message-id))
+
+(defun lui-beginning-of-message-p ()
+  "Check if point is at the beginning of a message."
+  (or (= (point) (point-min))
+      (not (equal (get-text-property (point) 'lui-message-id)
+                  (get-text-property (1- (point)) 'lui-message-id)))))
+
+(defun lui-beginning-of-message ()
+  "Move point to the beginning of the message at point."
+  (goto-char (previous-single-property-change (point) 'lui-message-id)))
+
+(defun lui-forward-message ()
+  "Move point to the next message in the buffer and return point.
+If there is no next message, move to the end of the buffer instead."
+  (let ((current-id (get-text-property (point) 'lui-message-id))
+        (next-point
+         (next-single-property-change (point) 'lui-message-id)))
+    (if (not next-point)
+        (goto-char (point-max))
+      (let ((message-id
+             (get-text-property next-point 'lui-message-id)))
+        (goto-char next-point)
+        (when (or (not (or current-id message-id))
+                  (and current-id (not message-id))
+                  (and current-id message-id
+                       (= current-id message-id)))
+          (lui-forward-message))))
+    (point)))
+
+(defun lui-backward-message ()
+  "Move point to the previous message in the buffer and return point.
+If there is no previous message, move to the beginning of the
+buffer instead."
+  (let ((current-id (get-text-property (point) 'lui-message-id))
+        (prev-point
+         (previous-single-property-change (point) 'lui-message-id)))
+    (if (not prev-point)
+        (goto-char (point-min))
+      (let ((message-id
+             (get-text-property prev-point 'lui-message-id)))
+        (goto-char prev-point)
+        (when (or (not (or current-id message-id))
+                  (and current-id (not message-id))
+                  (and current-id message-id
+                       (= current-id message-id)))
+          (lui-backward-message))))
+    (point)))
+
+
+;;;;;;;;;;;;;;;
+;;; Editing ;;;
+;;;;;;;;;;;;;;;
+
+(defun lui-recover-output-marker ()
+  "Reset the output marker to just before the lui prompt."
+  (let ((input-position (marker-position lui-input-marker)))
+    (set-marker lui-output-marker
+                (field-beginning (1- input-position)))))
+
+(defun lui-build-plist (keys)
+  "Build a plist with KEYS taken from current text properties."
+  (let (result)
+    (dolist (key keys result)
+      (let ((value (get-text-property (point) key)))
+        (when value
+          (setq result (plist-put result key value)))))))
+
+(defun lui-replace-message (new-message)
+  "Replace the message at point with NEW-MESSAGE."
+  (unless (lui-at-message-p)
+    (error "Point is not on a message"))
+  (unless (lui-beginning-of-message-p)
+    (lui-beginning-of-message))
+  (let* ((saved-text-properties
+          (get-text-property (point) 'lui-saved-text-properties))
+         (text-properties (lui-build-plist saved-text-properties))
+         (inhibit-read-only t)
+         (lui-time-stamp-last
+          (get-text-property (point) 'lui-time-stamp-last))
+         (lui-message-id
+          (get-text-property (point) 'lui-message-id)))
+    (unwind-protect
+        (progn
+          (setq lui-output-marker (point-marker))
+          (delete-region (point)
+                         (next-single-property-change (point) 'lui-message-id))
+          (apply #'lui-insert-with-text-properties new-message
+                 (plist-put text-properties 'not-tracked-p t)))
+      (lui-recover-output-marker))))
+
+(defun lui-replace (new-message predicate)
+  "Replace a message with NEW-MESSAGE.
+
+PREDICATE should be a function that returns a non-nil value for
+the message that should be replaced."
+  (save-excursion
+    (goto-char (point-max))
+    (while (> (lui-backward-message) (point-min))
+      (when (funcall predicate)
+        (lui-replace-message new-message)))))
+
+(defun lui-delete-message ()
+  "Delete the message at point."
+  (unless (lui-at-message-p)
+    (error "Point is not on a message"))
+  (unless (lui-beginning-of-message-p)
+    (lui-beginning-of-message))
+  (let ((inhibit-read-only t))
+    (add-text-properties (point)
+                         (next-single-property-change (point) 'lui-message-id)
+                         '(face lui-deleted-face))))
+
+(defun lui-delete (predicate)
+  "Delete a message.
+
+PREDICATE should be a function that returns a non-nil value for
+the message that should be replaced."
+  (save-excursion
+    (goto-char (point-max))
+    (while (> (lui-backward-message) (point-min))
+      (when (funcall predicate)
+        (lui-delete-message)))))
+
+
+(provide 'lui)
+;;; lui.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/lui.elc b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/lui.elc
new file mode 100644
index 0000000000..5d812f5dc4
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/lui.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/make-tls-process.el b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/make-tls-process.el
new file mode 100644
index 0000000000..aa7508568b
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/make-tls-process.el
@@ -0,0 +1,194 @@
+;;; make-tls-process.el --- A non-blocking TLS connection function
+
+;; Copyright (C) 2015  Jorgen Schaefer <contact@jorgenschaefer.de>
+
+;; Author: Jorgen Schaefer <contact@jorgenschaefer.de>
+;; URL: https://github.com/jorgenschaefer/circe
+
+;; This program 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.
+
+;; This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; A `make-tls-process' function like `make-network-process', in
+;; particular supporting non-blocking connects.
+
+;;; Code:
+
+(require 'tls)
+
+(defcustom tls-connection-command
+  (if (executable-find "gnutls-cli")
+      "gnutls-cli --insecure -p %p %h"
+    "openssl s_client -connect %h:%p -ign_eof")
+  "The command to use to create a TLS connection.
+
+%h is replaced with server hostname, %p with port to connect to.
+The program should read input on stdin and write output to
+stdout.
+
+Also see `tls-success' for what the program should output after
+successful negotiation."
+  :group 'tls
+  :type 'string)
+
+(defvar tls-debug-output nil
+  "Non-nil if you want to see lots of debug messages.")
+
+(defun tls--debug (format-string &rest args)
+  "Display a message if debug output is enabled.
+
+If `tls-debug-output' is non-nil, this acts like `message'.
+Otherwise, it's a no-op."
+  (when tls-debug-output
+    (apply #'message format-string args)))
+
+(defun make-tls-process (&rest args)
+  "Create a TLS client process.
+
+A TLS network process is a command process that runs a command
+line program like gnutls or openssl, not a full network process.
+Network communication should work as usual, but the sentinel
+might receive process-specific events.
+
+Different from a process sentinel, but like a network sentinel,
+the sentinel is called with an event \"open\\n\" when the
+connection is established.
+
+This function uses `tls-connection-command' to connect to a
+server.
+
+Do NOT use `set-process-filter' or `set-process-sentinel' on the
+return value of this function. The connection setup uses special
+sentinels and filters to be deal with the program output used
+here. Use the :sentinel and :filter keyword arguments to set them
+once the connection is fully established.
+
+Arguments are specified as keyword/argument pairs, similar to
+`make-network-process'. The following arguments are defined:
+
+:name NAME -- NAME is name for process.  It is modified if necessary
+to make it unique.
+
+:buffer BUFFER -- BUFFER is the buffer (or buffer-name) to associate
+with the process.  Process output goes at end of that buffer, unless
+you specify an output stream or filter function to handle the output.
+BUFFER may be also nil, meaning that this process is not associated
+with any buffer.
+
+:host HOST -- HOST is name of the host to connect to, or its IP
+address.  The symbol `local' specifies the local host.  If specified
+for a server process, it must be a valid name or address for the local
+host, and only clients connecting to that address will be accepted.
+
+:service SERVICE -- SERVICE is name of the service desired, or an
+integer specifying a port number to connect to. If SERVICE is t,
+a random port number is selected for the server. (If Emacs was
+compiled with getaddrinfo, a port number can also be specified as
+a string, e.g. \"80\", as well as an integer. This is not
+portable.)
+
+:coding CODING -- If CODING is a symbol, it specifies the coding
+system used for both reading and writing for this process.  If CODING
+is a cons (DECODING . ENCODING), DECODING is used for reading, and
+ENCODING is used for writing.
+
+:noquery BOOL -- Query the user unless BOOL is non-nil, and process is
+running when Emacs is exited.
+
+:filter FILTER -- Install FILTER as the process filter.
+
+:sentinel SENTINEL -- Install SENTINEL as the process sentinel.
+
+:plist PLIST -- Install PLIST as the new process's initial plist."
+  (let* ((name (plist-get args :name))
+         (host (plist-get args :host))
+         (service (plist-get args :service))
+         (proc (tls--start-process name tls-connection-command host service)))
+    (process-put proc :tls-args args)
+    (set-process-sentinel proc #'tls--sentinel)
+    (set-process-filter proc #'tls--filter)
+    proc))
+
+(defun tls--sentinel (proc event)
+  "The default sentinel for TLS connections.
+
+Try the next command in the list, or fail if there are none
+left."
+  (tls--debug "tls--sentinel %S %S"
+              (process-status proc)
+              event)
+  (tls--debug "Failed TLS output: %s"
+              (process-get proc :tls-data))
+  (if (eq (process-status proc)
+          'exit)
+      (let ((sentinel (plist-get (process-get proc :tls-args)
+                                 :sentinel)))
+        (when sentinel
+          (funcall sentinel proc (format "failed with %s\n" event))))
+    (error "Unexpected event in tls sentinel: %S" event)))
+
+(defun tls--filter (proc data)
+  "The default filter for TLS connections.
+
+We wait until both `tls-success' and `tls-end-of-info' have been
+received. Once that happens, we are done and we can switch over
+to the real connection."
+  (let ((data (concat (or (process-get proc :tls-data)
+                          "")
+                      data)))
+    (if (and (string-match tls-success data)
+             (string-match tls-end-of-info data))
+        (let* ((remaining-data (substring data (match-end 0)))
+               (args (process-get proc :tls-args))
+               (buffer (plist-get args :buffer))
+               (coding (plist-get args :coding))
+               (noquery (plist-get args :noquery))
+               (filter (plist-get args :filter))
+               (sentinel (plist-get args :sentinel))
+               (plist (plist-get args :plist)))
+          (set-process-plist proc plist)
+          (set-process-sentinel proc sentinel)
+          (set-process-filter proc filter)
+          (set-process-buffer proc buffer)
+          (if (consp coding)
+              (set-process-coding-system proc (car coding) (cdr coding))
+            (set-process-coding-system proc coding coding))
+          (set-process-query-on-exit-flag proc (not noquery))
+          (when sentinel
+            (funcall sentinel proc "open\n"))
+          (when (and (not (equal remaining-data ""))
+                     filter)
+            (funcall filter proc remaining-data)))
+      (process-put proc :tls-data data))))
+
+(defun tls--start-process (name cmd host port)
+  "Start a single process for network communication.
+
+This code is mostly taken from tls.el."
+  (let ((process-connection-type tls-process-connection-type)
+        (formatted-cmd
+         (format-spec
+          cmd
+          (format-spec-make
+           ?h host
+           ?p (if (integerp port)
+                  (int-to-string port)
+                port)))))
+    (tls--debug "TLS starting process: %s" formatted-cmd)
+    (start-process name nil
+                   shell-file-name shell-command-switch
+                   formatted-cmd)))
+
+(provide 'make-tls-process)
+;;; make-tls-process.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/make-tls-process.elc b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/make-tls-process.elc
new file mode 100644
index 0000000000..d277296535
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/make-tls-process.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/shorten.el b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/shorten.el
new file mode 100644
index 0000000000..1ba6085b9c
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/shorten.el
@@ -0,0 +1,223 @@
+;;; shorten.el --- component-wise string shortener
+
+;; Copyright (C) 2013  John J Foerch <jjfoerch@earthlink.net>
+
+;; Keywords: extensions
+;; Author: John J Foerch <jjfoerch@earthlink.net>
+;; URL: https://github.com/jorgenschaefer/circe/blob/master/shorten.el
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This is a component-wise string shortener, meaning that, given a list
+;; of strings, it breaks each string into parts, then computes shortest
+;; prefix of each part with respect to others of the same 'depth', such
+;; that when joined back together, the shortened form of the whole string
+;; remains unique within the resulting list.  Many styles of shortening
+;; are made possible via three functions that the caller may provide: the
+;; split function, the join function, and the validate-component function.
+;;
+;; Strings are broken with the value of `shorten-split-function' (a
+;; procedure string->list), and shortened components are rejoined with the
+;; value of `shorten-join-function' (a procedure list->string[*]).  The
+;; default split and join functions break the string on word boundaries,
+;; and rejoin on the empty string.  Potential shortened forms of
+;; components are tested with `shorten-validate-component-function'; its
+;; default value passes only if its argument contains at least one
+;; word-constituent character (regexp \w), meaning that by default,
+;; components consisting entirely of non-word characters will not be
+;; shortened, and components that start with non-word characters will only
+;; be shortened so much that they have at least one word-constituent
+;; character in them.
+;;
+;; The main entry point is `shorten-strings', which takes a list of strings
+;; as its argument and returns an alist ((STRING . SHORTENED-STRING) ...).
+;;
+;; [*] Also takes a second argument; see docstring of
+;; `shorten-join-function'.
+
+;;; History:
+
+;; - Version 0.1 (March 7, 2013): initial release
+
+;;; Code:
+
+;; Tree utils
+;;
+(defsubst shorten-make-tree-root ()
+  (cons nil nil))
+
+(defsubst shorten-tree-make-entry (token short full)
+  (list token short full nil))
+
+(defsubst shorten-tree-token (entry)
+  (car entry))
+
+(defsubst shorten-tree-fullname (entry)
+  (nth 2 entry))
+
+(defsubst shorten-tree-descendants (entry)
+  (nthcdr 3 entry))
+
+(defsubst shorten-tree-set-shortened (entry short)
+  (setcar (cdr entry) short))
+
+(defsubst shorten-tree-set-fullname (entry full)
+  (setcar (nthcdr 2 entry) full))
+
+(defsubst shorten-tree-insert (node item)
+  (when (car node)
+    (setcdr node (cons (car node) (cdr node))))
+  (setcar node item))
+
+
+;; Caller configuration
+;;
+(defun shorten-split (s)
+  (split-string s "\\b" t))
+
+(defun shorten-join (lst &optional tail-count)
+  (mapconcat #'identity lst ""))
+
+(defun shorten-join-sans-tail (lst tail-count)
+  "A shorten-join that drops unnecessary tail components."
+  (shorten-join (butlast lst tail-count)))
+
+(defun shorten-validate-component (str)
+  (string-match-p "\\w" str))
+
+(defvar shorten-split-function #'shorten-split
+  "Value should be a function of string->list that breaks a
+string into components.  The default breaks on word-boundaries.
+To get simple prefix shortening, bind this to `list'.
+
+Users should not generally change the global value of this
+variable; instead, bind it dynamically around calls to
+`shorten-strings'.")
+
+(defvar shorten-join-function #'shorten-join
+  "A function that takes a list of components and a tail-count,
+and returns a joined string.  Tail-count is the number of
+components on the end of the list that are not needed to uniquify
+the result, and so may be safely dropped if aggressive shortening
+is desired.  The default preserves tail components, and joins the
+list on the empty string.
+
+Users should not generally change the global value of this
+variable; instead, bind it dynamically around calls to
+`shorten-strings'.")
+
+(defvar shorten-validate-component-function #'shorten-validate-component
+  "Predicate that returns t if a proposed shortened form of a
+single component is acceptable, nil if a longer one should be
+tried.  The default validates only when the candidate contains at
+least one word-constituent character, thus strings consisting of
+punctuation will not be shortened.  For aggressive shortening,
+bind to a procedure that always returns t.
+
+Users should not generally change the global value of this
+variable; instead, bind it dynamically around calls to
+`shorten-strings'.")
+
+
+;; Main procedures
+;;
+(defun shorten-one (str others)
+  "Return shortest unique prefix of STR among OTHERS, or STR if
+it cannot be shortened.  If STR is a member of OTHERS (tested
+with `eq') that entry is ignored.  The value of
+`shorten-validate-component-function' will be used to validate
+any prefix."
+  (let ((max (length str))
+        (len 1))
+    (or (catch 'return
+          (while (< len max)
+            (let ((prefix (substring str 0 len)))
+              (when (funcall shorten-validate-component-function prefix)
+                (when (catch 'return
+                        (dolist (other others t)
+                          (when (and (>= (length other) len)
+                                     (string= (substring other 0 len) prefix)
+                                     (not (eq other str)))
+                            (throw 'return nil))))
+                  (throw 'return prefix)))
+              (setq len (1+ len)))))
+        str)))
+
+(defun shorten-walk-internal (node path tail-count result-out)
+  (let ((others (mapcar #'car node)))
+    (setq tail-count (if (cdr node) 0 (1+ tail-count)))
+    (dolist (entry node)
+      (let* ((token (shorten-tree-token entry))
+             (shortened (shorten-one token others))
+             (path (cons shortened path))
+             (fullname (shorten-tree-fullname entry))
+             (descendants (shorten-tree-descendants entry))
+             (have-descendants (not (equal '(nil) descendants))))
+        (shorten-tree-set-shortened entry shortened)
+        ;; if this entry has a fullname, add to result-out
+        (when fullname
+          (let ((joined (funcall shorten-join-function
+                                 (reverse path)
+                                 (if have-descendants 0 tail-count))))
+            (shorten-tree-insert result-out (cons fullname joined))))
+        ;; if this entry has descendants, recurse
+        (when have-descendants
+          (shorten-walk-internal descendants path
+                                 (if fullname -1 tail-count)
+                                 result-out))))))
+
+(defun shorten-walk (tree)
+  "Takes a tree of the type made by `shorten-make-tree' and
+returns an alist ((STRING . SHORTENED-STRING) ...).  Uses
+`shorten-join-function' to join shortened components back
+together into SHORTENED-STRING.  See also
+`shorten-validate-component-function'."
+  (let ((result-out (shorten-make-tree-root)))
+    (shorten-walk-internal tree '() -1 result-out)
+    (if (equal '(nil) result-out) nil result-out)))
+
+(defun shorten-make-tree (strings)
+  "Takes a list of strings and returns a tree of the type used by
+`shorten-walk' to generate shortened strings.  Uses
+`shorten-split-function' to split the strings."
+  (let ((tree (shorten-make-tree-root)))
+    (dolist (s strings)
+      (let ((node tree)
+            (tokens (funcall shorten-split-function s))
+            (entry nil))
+        ;; create a path in tree for tokens
+        (dolist (token tokens)
+          (setq entry (assoc token node))
+          (when (not entry)
+            (setq entry (shorten-tree-make-entry token nil nil))
+            (shorten-tree-insert node entry))
+          (setq node (shorten-tree-descendants entry)))
+        ;; for the last token, set 'fullname'
+        (shorten-tree-set-fullname entry s)))
+    (if (equal tree '(nil)) nil tree)))
+
+;;;###autoload
+(defun shorten-strings (strings)
+  "Takes a list of strings and returns an alist ((STRING
+. SHORTENED-STRING) ...).  Uses `shorten-split-function' to split
+the strings, and `shorten-join-function' to join shortened
+components back together into SHORTENED-STRING.  See also
+`shorten-validate-component-function'."
+  (shorten-walk (shorten-make-tree strings)))
+
+
+(provide 'shorten)
+;;; shorten.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/shorten.elc b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/shorten.elc
new file mode 100644
index 0000000000..12bce2477e
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/shorten.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/tracking.el b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/tracking.el
new file mode 100644
index 0000000000..8fd53fcb29
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/tracking.el
@@ -0,0 +1,428 @@
+;;; tracking.el --- Buffer modification tracking
+
+;; Copyright (C) 2006, 2012 - 2015  Jorgen Schaefer
+
+;; Author: Jorgen Schaefer <forcer@forcix.cx>
+;; URL: https://github.com/jorgenschaefer/circe/wiki/Tracking
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; tracking.el is a library for other Emacs Lisp programs not useful
+;; by itself.
+
+;; The library provides a way to globally register buffers as being
+;; modified and scheduled for user review. The user can cycle through
+;; the buffers using C-c C-SPC. This is especially useful for buffers
+;; that interact with external sources, such as chat clients and
+;; similar programs.
+
+;;; Code:
+
+(require 'easy-mmode)
+(require 'shorten)
+(require 'cl-lib)
+
+;;; User customization
+(defgroup tracking nil
+  "Tracking of buffer activities."
+  :prefix "tracking-"
+  :group 'applications)
+
+(defcustom tracking-shorten-buffer-names-p t
+  "Whether to shorten buffer names in the mode line.
+A non-nil value will cause tracked buffer names to be shortened
+as much as possible to stay unambiguous when displaying them in
+the mode line."
+  :type 'boolean
+  :group 'tracking)
+
+(defcustom tracking-frame-behavior 'visible
+  "How to deal with frams to determine visibility of buffers.
+This is passed as the second argument to `get-buffer-window',
+see there for further explanation."
+  :type '(choice (const :tag "All visible frames" visible)
+                 (const :tag "Visible and iconified frames" 0)
+                 (const :tag "All frames" t)
+                 (const :tag "Selected frame only" nil))
+  :group 'tracking)
+
+(defcustom tracking-position 'before-modes
+  "Where tracked buffers should appear in the mode line.
+
+  'before-modes
+      Before the mode indicators
+  'after-modes
+      After the mode indicators
+  'end
+      At the end of the mode line"
+  :type '(choice (const :tag "Before the Mode Indicators" before-modes)
+                 (const :tag "Afterthe Mode Indicators" after-modes)
+                 (const :tag "At the End of the Mode Line" end))
+  :group 'tracking)
+
+(defcustom tracking-faces-priorities nil
+  "A list of faces which should be shown by tracking in the mode line.
+The first face found in this list is used."
+  :type '(repeat face)
+  :group 'tracking)
+
+(defcustom tracking-ignored-buffers nil
+  "A list of buffers that are never tracked.
+Each element of this list has one of the following forms:
+
+  regexp - Any buffer matching won't be tracked.
+  function - Any buffer matching won't be tracked.
+  (regexp faces ...) - Any buffer matching won't be tracked,
+      unless it has a face in FACES ... associated with it.
+      If no faces are given, `tracking-faces-priorities' is
+      used.
+  (function faces ...) - As per above, but with a function
+      as predicate instead of a regexp."
+  :type '(repeat (choice regexp
+                         function
+                         (list (choice regexp function)
+                               (repeat face))))
+  :group 'tracking)
+
+(defcustom tracking-most-recent-first nil
+  "When non-nil, newly tracked buffers will go to the front of the
+list, rather than to the end."
+  :type 'boolean
+  :group 'tracking)
+
+(defcustom tracking-sort-faces-first nil
+  "When non-nil, tracked buffers with any highlight face will go to
+the front of the tracking list.
+
+See `tracking-most-recent-first' for whether they are appended at the
+front or the back of the highlighted buffers."
+  :type 'boolean
+  :group 'tracking)
+
+(defcustom tracking-buffer-added-hook nil
+  "Hook run when a buffer has some activity.
+
+The functions are run in the context of the buffer.
+
+This can also happen when the buffer is already tracked. Check if the
+buffer name is in `tracking-buffers' if you want to see if it was
+added before."
+  :type 'hook
+  :group 'tracking)
+
+(defcustom tracking-buffer-removed-hook nil
+  "Hook run when a buffer becomes active and is removed.
+
+The functions are run in the context of the buffer."
+  :type 'hook
+  :group 'tracking)
+
+(defcustom tracking-max-mode-line-entries nil
+  "Maximum number of buffers shown in the mode-line.
+
+If set to nil, all buffers will be shown."
+  :type '(choice (const :tag "All" nil)
+                 (integer :tag "Maximum"))
+  :group 'tracking)
+
+;;; Internal variables
+(defvar tracking-buffers nil
+  "The list of currently tracked buffers.")
+
+(defvar tracking-mode-line-buffers ""
+  "The entry to the mode line.")
+(put 'tracking-mode-line-buffers 'risky-local-variable t)
+
+(defvar tracking-start-buffer nil
+  "The buffer we started from when cycling through the active buffers.")
+
+(defvar tracking-last-buffer nil
+  "The buffer we last switched to with `tracking-next-buffer'.
+When this is not the current buffer when we continue switching, a
+new `tracking-start-buffer' is created.")
+
+(defvar tracking-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "C-c C-SPC") 'tracking-next-buffer)
+    (define-key map (kbd "C-c C-@") 'tracking-next-buffer)
+    map)
+  "The keymap used for tracking mode.")
+
+;;;###autoload
+(define-minor-mode tracking-mode
+  "Allow cycling through modified buffers.
+This mode in itself does not track buffer modification, but
+provides an API for programs to add buffers as modified (using
+`tracking-add-buffer').
+
+Once this mode is active, modified buffers are shown in the mode
+line. The user can cycle through them using
+\\[tracking-next-buffer]."
+  :group 'tracking
+  :global t
+  (cond
+   (tracking-mode
+    (cond
+     ((eq tracking-position 'before-modes)
+      (let ((head nil)
+            (tail (default-value 'mode-line-format)))
+        (when (not (memq 'tracking-mode-line-buffers tail))
+          (catch 'return
+            (while tail
+              (if (not (eq (car tail)
+                           'mode-line-modes))
+                  (setq head (cons (car tail)
+                                   head)
+                        tail (cdr tail))
+                (setq-default mode-line-format
+                              (append (reverse head)
+                                      '(tracking-mode-line-buffers)
+                                      tail))
+                (throw 'return t)))))))
+     ((eq tracking-position 'after-modes)
+      (add-to-list 'mode-line-misc-info
+                   'tracking-mode-line-buffers))
+     ((eq tracking-position 'end)
+      (add-to-list 'mode-line-misc-info
+                   'tracking-mode-line-buffers
+                   t))
+     (t
+      (error "Invalid value for `tracking-position' (%s)" tracking-position)))
+    (add-hook 'window-configuration-change-hook
+              'tracking-remove-visible-buffers))
+   (t
+    (setq mode-line-misc-info (delq 'tracking-mode-line-buffers
+                                    mode-line-misc-info))
+    (setq-default mode-line-format (delq 'tracking-mode-line-buffers
+                                         (default-value 'mode-line-format)))
+    (remove-hook 'window-configuration-change-hook
+                 'tracking-remove-visible-buffers))))
+
+;;;###autoload
+(defun tracking-add-buffer (buffer &optional faces)
+  "Add BUFFER as being modified with FACES.
+This does check whether BUFFER is currently visible.
+
+If FACES is given, it lists the faces that might be appropriate
+for BUFFER in the mode line. The highest-priority face of these
+and the current face of the buffer, if any, is used. Priority is
+decided according to `tracking-faces-priorities'.
+When `tracking-sort-faces-first' is non-nil, all buffers with any
+face set will be stable-sorted before any buffers with no face set."
+  (when (and (not (get-buffer-window buffer tracking-frame-behavior))
+             (not (tracking-ignored-p buffer faces)))
+    (with-current-buffer buffer
+      (run-hooks 'tracking-buffer-added-hook))
+    (let* ((entry (member (buffer-name buffer)
+                          tracking-buffers)))
+      (if entry
+          (setcar entry (tracking-faces-merge (car entry)
+                                              faces))
+        (setq tracking-buffers
+              (if tracking-most-recent-first
+                  (cons (tracking-faces-merge (buffer-name buffer)
+                                              faces)
+                        tracking-buffers)
+                  (nconc tracking-buffers
+                         (list (tracking-faces-merge (buffer-name buffer)
+                                                     faces)))))))
+    (when tracking-sort-faces-first
+      (let ((with-any-face (cl-remove-if-not
+                            (lambda (str) (get-text-property 0 'face str))
+                            tracking-buffers))
+            (with-no-face (cl-remove-if
+                           (lambda (str) (get-text-property 0 'face str))
+                           tracking-buffers)))
+        (setq tracking-buffers (nconc with-any-face with-no-face))))
+    (setq tracking-mode-line-buffers (tracking-status))
+    (force-mode-line-update t)
+    ))
+
+;;;###autoload
+(defun tracking-remove-buffer (buffer)
+  "Remove BUFFER from being tracked."
+  (when (member (buffer-name buffer)
+                tracking-buffers)
+    (with-current-buffer buffer
+      (run-hooks 'tracking-buffer-removed-hook)))
+  (setq tracking-buffers (delete (buffer-name buffer)
+                                 tracking-buffers))
+  (setq tracking-mode-line-buffers (tracking-status))
+  (sit-for 0) ;; Update mode line
+  )
+
+;;;###autoload
+(defun tracking-next-buffer ()
+  "Switch to the next active buffer."
+  (interactive)
+  (cond
+   ((and (not tracking-buffers)
+         tracking-start-buffer)
+    (let ((buf tracking-start-buffer))
+      (setq tracking-start-buffer nil)
+      (if (buffer-live-p buf)
+          (switch-to-buffer buf)
+        (message "Original buffer does not exist anymore")
+        (ding))))
+   ((not tracking-buffers)
+    nil)
+   (t
+    (when (not (eq tracking-last-buffer
+                   (current-buffer)))
+      (setq tracking-start-buffer (current-buffer)))
+    (let ((new (car tracking-buffers)))
+      (when (buffer-live-p (get-buffer new))
+        (with-current-buffer new
+          (run-hooks 'tracking-buffer-removed-hook)))
+      (setq tracking-buffers (cdr tracking-buffers)
+            tracking-mode-line-buffers (tracking-status))
+      (if (buffer-live-p (get-buffer new))
+          (switch-to-buffer new)
+        (message "Buffer %s does not exist anymore" new)
+        (ding)
+        (setq tracking-mode-line-buffers (tracking-status))))
+    (setq tracking-last-buffer (current-buffer))
+    ;; Update mode line. See `force-mode-line-update' for the idea for
+    ;; this code. Using `sit-for' can be quite inefficient for larger
+    ;; buffers.
+    (dolist (w (window-list))
+      (with-current-buffer (window-buffer w)))
+    )))
+
+;;;###autoload
+(defun tracking-previous-buffer ()
+  "Switch to the last active buffer."
+  (interactive)
+  (when tracking-buffers
+    (switch-to-buffer (car (last tracking-buffers)))))
+
+(defun tracking-ignored-p (buffer faces)
+  "Return non-nil when BUFFER with FACES shouldn't be tracked.
+This uses `tracking-ignored-buffers'.  Actual returned value is
+the entry from tracking-ignored-buffers that causes this buffer
+to be ignored."
+  (catch 'return
+    (let ((buffer-name (buffer-name buffer)))
+      (dolist (entry tracking-ignored-buffers)
+        (cond
+         ((stringp entry)
+          (and (string-match entry buffer-name)
+               (throw 'return entry)))
+         ((functionp entry)
+          (and (funcall entry buffer-name)
+               (throw 'return entry)))
+         ((or (and (stringp (car entry))
+                   (string-match (car entry) buffer-name))
+              (and (functionp (car entry))
+                   (funcall (car entry) buffer-name)))
+          (when (not (tracking-any-in (or (cdr entry)
+                                          tracking-faces-priorities)
+                                      faces))
+            (throw 'return entry))))))
+    nil))
+
+(defun tracking-status ()
+  "Return the current track status.
+
+This returns a list suitable for `mode-line-format'.
+If `tracking-max-mode-line-entries' is a positive integer,
+only return that many entries, ending with '+n'."
+  (if (not tracking-buffers)
+      ""
+    (let* ((buffer-names (cl-remove-if-not #'get-buffer tracking-buffers))
+           (shortened-names (tracking-shorten tracking-buffers))
+           (result (list " ["))
+           (i 0))
+      (cl-block exit
+        (while buffer-names
+          (push `(:propertize
+                  ,(car shortened-names)
+                  face ,(get-text-property 0 'face (car buffer-names))
+                  keymap ,(let ((map (make-sparse-keymap)))
+                            (define-key map [mode-line down-mouse-1]
+                              `(lambda ()
+                                 (interactive)
+                                 (pop-to-buffer ,(car buffer-names))))
+                            map)
+                  mouse-face mode-line-highlight
+                  help-echo ,(format (concat "New activity in %s\n"
+                                             "mouse-1: pop to the buffer")
+                                     (car buffer-names)))
+                result)
+          (cl-incf i)
+          (setq buffer-names (cdr buffer-names)
+                shortened-names (cdr shortened-names))
+          (when (and tracking-max-mode-line-entries
+                     buffer-names
+                     (>= i tracking-max-mode-line-entries))
+            (push (concat " +" (number-to-string (length buffer-names))) result)
+            (cl-return-from exit))
+          (when buffer-names
+            (push "," result))))
+      (push "] " result)
+      (nreverse result))))
+
+(defun tracking-remove-visible-buffers ()
+  "Remove visible buffers from the tracked buffers.
+This is usually called via `window-configuration-changed-hook'."
+  (interactive)
+  (dolist (buffer-name tracking-buffers)
+    (let ((buffer (get-buffer buffer-name)))
+      (cond
+       ((not buffer)
+        (setq tracking-buffers (delete buffer-name tracking-buffers))
+        (setq tracking-mode-line-buffers (tracking-status))
+        (sit-for 0))
+       ((get-buffer-window buffer tracking-frame-behavior)
+        (tracking-remove-buffer buffer))))))
+
+;;; Helper functions
+(defun tracking-shorten (buffers)
+  "Shorten BUFFERS according to `tracking-shorten-buffer-names-p'."
+  (if tracking-shorten-buffer-names-p
+      (let ((all (shorten-strings (mapcar #'buffer-name (buffer-list)))))
+        (mapcar (lambda (buffer)
+                  (let ((short (cdr (assoc buffer all))))
+                    (set-text-properties
+                     0 (length short)
+                     (text-properties-at 0 buffer)
+                     short)
+                    short))
+                buffers))
+    buffers))
+
+(defun tracking-any-in (lista listb)
+  "Return non-nil when any element in LISTA is in LISTB"
+  (catch 'return
+    (dolist (entry lista)
+      (when (memq entry listb)
+        (throw 'return t)))
+    nil))
+
+(defun tracking-faces-merge (string faces)
+  "Merge faces into string, adhering to `tracking-faces-priorities'.
+This returns STRING with the new face."
+  (let ((faces (cons (get-text-property 0 'face string)
+                     faces)))
+    (catch 'return
+      (dolist (candidate tracking-faces-priorities)
+        (when (memq candidate faces)
+          (throw 'return
+                 (propertize string 'face candidate))))
+      string)))
+
+(provide 'tracking)
+;;; tracking.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/tracking.elc b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/tracking.elc
new file mode 100644
index 0000000000..75c63bd449
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/circe-20180525.531/tracking.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/clojure-mode-20180709.648/clojure-mode-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/clojure-mode-20180709.648/clojure-mode-autoloads.el
new file mode 100644
index 0000000000..121cb2c53f
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/clojure-mode-20180709.648/clojure-mode-autoloads.el
@@ -0,0 +1,144 @@
+;;; clojure-mode-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "clojure-mode" "clojure-mode.el" (23377 61664
+;;;;;;  156631 766000))
+;;; Generated autoloads from clojure-mode.el
+
+(autoload 'clojure-mode "clojure-mode" "\
+Major mode for editing Clojure code.
+
+\\{clojure-mode-map}
+
+\(fn)" t nil)
+
+(autoload 'clojure-unwind "clojure-mode" "\
+Unwind thread at point or above point by one level.
+Return nil if there are no more levels to unwind.
+
+\(fn)" t nil)
+
+(autoload 'clojure-unwind-all "clojure-mode" "\
+Fully unwind thread at point or above point.
+
+\(fn)" t nil)
+
+(autoload 'clojure-thread "clojure-mode" "\
+Thread by one more level an existing threading macro.
+
+\(fn)" t nil)
+
+(autoload 'clojure-thread-first-all "clojure-mode" "\
+Fully thread the form at point using ->.
+
+When BUT-LAST is non-nil, the last expression is not threaded.
+Default value is `clojure-thread-all-but-last'.
+
+\(fn BUT-LAST)" t nil)
+
+(autoload 'clojure-thread-last-all "clojure-mode" "\
+Fully thread the form at point using ->>.
+
+When BUT-LAST is non-nil, the last expression is not threaded.
+Default value is `clojure-thread-all-but-last'.
+
+\(fn BUT-LAST)" t nil)
+
+(autoload 'clojure-cycle-privacy "clojure-mode" "\
+Make public the current private def, or vice-versa.
+See: https://github.com/clojure-emacs/clj-refactor.el/wiki/cljr-cycle-privacy
+
+\(fn)" t nil)
+
+(autoload 'clojure-convert-collection-to-list "clojure-mode" "\
+Convert collection at (point) to list.
+
+\(fn)" t nil)
+
+(autoload 'clojure-convert-collection-to-quoted-list "clojure-mode" "\
+Convert collection at (point) to quoted list.
+
+\(fn)" t nil)
+
+(autoload 'clojure-convert-collection-to-map "clojure-mode" "\
+Convert collection at (point) to map.
+
+\(fn)" t nil)
+
+(autoload 'clojure-convert-collection-to-vector "clojure-mode" "\
+Convert collection at (point) to vector.
+
+\(fn)" t nil)
+
+(autoload 'clojure-convert-collection-to-set "clojure-mode" "\
+Convert collection at (point) to set.
+
+\(fn)" t nil)
+
+(autoload 'clojure-cycle-if "clojure-mode" "\
+Change a surrounding if to if-not, or vice-versa.
+
+See: https://github.com/clojure-emacs/clj-refactor.el/wiki/cljr-cycle-if
+
+\(fn)" t nil)
+
+(autoload 'clojure-cycle-when "clojure-mode" "\
+Change a surrounding when to when-not, or vice-versa.
+
+\(fn)" t nil)
+
+(autoload 'clojure-let-backward-slurp-sexp "clojure-mode" "\
+Slurp the s-expression before the let form into the let form.
+With a numberic prefix argument slurp the previous N s-expression into the let form.
+
+\(fn &optional N)" t nil)
+
+(autoload 'clojure-let-forward-slurp-sexp "clojure-mode" "\
+Slurp the next s-expression after the let form into the let form.
+With a numeric prefix argument slurp the next N s-expressions into the let form.
+
+\(fn &optional N)" t nil)
+
+(autoload 'clojure-introduce-let "clojure-mode" "\
+Create a let form, binding the form at point.
+With a numeric prefix argument the let is introduced N lists up.
+
+\(fn &optional N)" t nil)
+
+(autoload 'clojure-move-to-let "clojure-mode" "\
+Move the form at point to a binding in the nearest let.
+
+\(fn)" t nil)
+
+(autoload 'clojurescript-mode "clojure-mode" "\
+Major mode for editing ClojureScript code.
+
+\\{clojurescript-mode-map}
+
+\(fn)" t nil)
+
+(autoload 'clojurec-mode "clojure-mode" "\
+Major mode for editing ClojureC code.
+
+\\{clojurec-mode-map}
+
+\(fn)" t nil)
+
+(add-to-list 'auto-mode-alist '("\\.\\(clj\\|dtm\\|edn\\)\\'" . clojure-mode))
+
+(add-to-list 'auto-mode-alist '("\\.cljc\\'" . clojurec-mode))
+
+(add-to-list 'auto-mode-alist '("\\.cljs\\'" . clojurescript-mode))
+
+(add-to-list 'auto-mode-alist '("\\(?:build\\|profile\\)\\.boot\\'" . clojure-mode))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; clojure-mode-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/clojure-mode-20180709.648/clojure-mode-pkg.el b/configs/shared/emacs/.emacs.d/elpa/clojure-mode-20180709.648/clojure-mode-pkg.el
new file mode 100644
index 0000000000..d8063ba86f
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/clojure-mode-20180709.648/clojure-mode-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "clojure-mode" "20180709.648" "Major mode for Clojure code" '((emacs "25.1")))
diff --git a/configs/shared/emacs/.emacs.d/elpa/clojure-mode-20180709.648/clojure-mode.el b/configs/shared/emacs/.emacs.d/elpa/clojure-mode-20180709.648/clojure-mode.el
new file mode 100644
index 0000000000..a98ba5fc5e
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/clojure-mode-20180709.648/clojure-mode.el
@@ -0,0 +1,2596 @@
+;;; clojure-mode.el --- Major mode for Clojure code -*- lexical-binding: t; -*-
+
+;; Copyright © 2007-2018 Jeffrey Chu, Lennart Staflin, Phil Hagelberg
+;; Copyright © 2013-2018 Bozhidar Batsov, Artur Malabarba
+;;
+;; Authors: Jeffrey Chu <jochu0@gmail.com>
+;;       Lennart Staflin <lenst@lysator.liu.se>
+;;       Phil Hagelberg <technomancy@gmail.com>
+;;       Bozhidar Batsov <bozhidar@batsov.com>
+;;       Artur Malabarba <bruce.connor.am@gmail.com>
+;; URL: http://github.com/clojure-emacs/clojure-mode
+;; Package-Version: 20180709.648
+;; Keywords: languages clojure clojurescript lisp
+;; Version: 5.9.0-snapshot
+;; Package-Requires: ((emacs "25.1"))
+
+;; This file is not part of GNU Emacs.
+
+;;; Commentary:
+
+;; Provides font-lock, indentation, navigation and basic refactoring for the
+;; Clojure programming language (http://clojure.org).
+
+;; Using clojure-mode with paredit or smartparens is highly recommended.
+
+;; Here are some example configurations:
+
+;;   ;; require or autoload paredit-mode
+;;   (add-hook 'clojure-mode-hook #'paredit-mode)
+
+;;   ;; require or autoload smartparens
+;;   (add-hook 'clojure-mode-hook #'smartparens-strict-mode)
+
+;; See inf-clojure (http://github.com/clojure-emacs/inf-clojure) for
+;; basic interaction with Clojure subprocesses.
+
+;; See CIDER (http://github.com/clojure-emacs/cider) for
+;; better interaction with subprocesses via nREPL.
+
+;;; License:
+
+;; This program 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.
+;;
+;; This program 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; see the file COPYING.  If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Code:
+
+
+(eval-when-compile
+  (defvar calculate-lisp-indent-last-sexp)
+  (defvar font-lock-beg)
+  (defvar font-lock-end)
+  (defvar paredit-space-for-delimiter-predicates)
+  (defvar paredit-version)
+  (defvar paredit-mode))
+
+(require 'cl-lib)
+(require 'imenu)
+(require 'newcomment)
+(require 'align)
+(require 'subr-x)
+
+(declare-function lisp-fill-paragraph  "lisp-mode" (&optional justify))
+
+(defgroup clojure nil
+  "Major mode for editing Clojure code."
+  :prefix "clojure-"
+  :group 'languages
+  :link '(url-link :tag "GitHub" "https://github.com/clojure-emacs/clojure-mode")
+  :link '(emacs-commentary-link :tag "Commentary" "clojure-mode"))
+
+(defconst clojure-mode-version "5.9.0-snapshot"
+  "The current version of `clojure-mode'.")
+
+(defface clojure-keyword-face
+  '((t (:inherit font-lock-constant-face)))
+  "Face used to font-lock Clojure keywords (:something)."
+  :package-version '(clojure-mode . "3.0.0"))
+
+(defface clojure-character-face
+  '((t (:inherit font-lock-string-face)))
+  "Face used to font-lock Clojure character literals."
+  :package-version '(clojure-mode . "3.0.0"))
+
+(defcustom clojure-indent-style :always-align
+  "Indentation style to use for function forms and macro forms.
+There are two cases of interest configured by this variable.
+
+- Case (A) is when at least one function argument is on the same
+  line as the function name.
+- Case (B) is the opposite (no arguments are on the same line as
+  the function name).  Note that the body of macros is not
+  affected by this variable, it is always indented by
+  `lisp-body-indent' (default 2) spaces.
+
+Note that this variable configures the indentation of function
+forms (and function-like macros), it does not affect macros that
+already use special indentation rules.
+
+The possible values for this variable are keywords indicating how
+to indent function forms.
+
+    `:always-align' - Follow the same rules as `lisp-mode'.  All
+    args are vertically aligned with the first arg in case (A),
+    and vertically aligned with the function name in case (B).
+    For instance:
+        (reduce merge
+                some-coll)
+        (reduce
+         merge
+         some-coll)
+
+    `:always-indent' - All args are indented like a macro body.
+        (reduce merge
+          some-coll)
+        (reduce
+          merge
+          some-coll)
+
+    `:align-arguments' - Case (A) is indented like `lisp', and
+    case (B) is indented like a macro body.
+        (reduce merge
+                some-coll)
+        (reduce
+          merge
+          some-coll)"
+  :safe #'keywordp
+  :type '(choice (const :tag "Same as `lisp-mode'" :always-align)
+                 (const :tag "Indent like a macro body" :always-indent)
+                 (const :tag "Indent like a macro body unless first arg is on the same line"
+                        :align-arguments))
+  :package-version '(clojure-mode . "5.2.0"))
+
+(define-obsolete-variable-alias 'clojure-defun-style-default-indent
+  'clojure-indent-style "5.2.0")
+
+(defcustom clojure-use-backtracking-indent t
+  "When non-nil, enable context sensitive indentation."
+  :type 'boolean
+  :safe 'booleanp)
+
+(defcustom clojure-max-backtracking 3
+  "Maximum amount to backtrack up a list to check for context."
+  :type 'integer
+  :safe 'integerp)
+
+(defcustom clojure-docstring-fill-column fill-column
+  "Value of `fill-column' to use when filling a docstring."
+  :type 'integer
+  :safe 'integerp)
+
+(defcustom clojure-docstring-fill-prefix-width 2
+  "Width of `fill-prefix' when filling a docstring.
+The default value conforms with the de facto convention for
+Clojure docstrings, aligning the second line with the opening
+double quotes on the third column."
+  :type 'integer
+  :safe 'integerp)
+
+(defcustom clojure-omit-space-between-tag-and-delimiters '(?\[ ?\{ ?\()
+  "Allowed opening delimiter characters after a reader literal tag.
+For example, \[ is allowed in :db/id[:db.part/user]."
+  :type '(set (const :tag "[" ?\[)
+              (const :tag "{" ?\{)
+              (const :tag "(" ?\()
+              (const :tag "\"" ?\"))
+  :safe (lambda (value)
+          (and (listp value)
+               (cl-every 'characterp value))))
+
+(defcustom clojure-build-tool-files
+  '("project.clj"     ; Leiningen
+    "build.boot"      ; Boot
+    "build.gradle"    ; Gradle
+    "deps.edn"        ; Clojure CLI (a.k.a. tools.deps)
+    "shadow-cljs.edn" ; shadow-cljs
+    )
+  "A list of files, which identify a Clojure project's root.
+Out-of-the box `clojure-mode' understands lein, boot, gradle,
+ shadow-cljs and tools.deps."
+  :type '(repeat string)
+  :package-version '(clojure-mode . "5.0.0")
+  :safe (lambda (value)
+          (and (listp value)
+               (cl-every 'stringp value))))
+
+(defcustom clojure-project-root-function #'clojure-project-root-path
+  "Function to locate clojure project root directory."
+  :type 'function
+  :risky t
+  :package-version '(clojure-mode . "5.7.0"))
+
+(defcustom clojure-refactor-map-prefix (kbd "C-c C-r")
+  "Clojure refactor keymap prefix."
+  :type 'string
+  :package-version '(clojure-mode . "5.6.0"))
+
+(defvar clojure-refactor-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "C-t") #'clojure-thread)
+    (define-key map (kbd "t") #'clojure-thread)
+    (define-key map (kbd "C-u") #'clojure-unwind)
+    (define-key map (kbd "u") #'clojure-unwind)
+    (define-key map (kbd "C-f") #'clojure-thread-first-all)
+    (define-key map (kbd "f") #'clojure-thread-first-all)
+    (define-key map (kbd "C-l") #'clojure-thread-last-all)
+    (define-key map (kbd "l") #'clojure-thread-last-all)
+    (define-key map (kbd "C-a") #'clojure-unwind-all)
+    (define-key map (kbd "a") #'clojure-unwind-all)
+    (define-key map (kbd "C-p") #'clojure-cycle-privacy)
+    (define-key map (kbd "p") #'clojure-cycle-privacy)
+    (define-key map (kbd "C-(") #'clojure-convert-collection-to-list)
+    (define-key map (kbd "(") #'clojure-convert-collection-to-list)
+    (define-key map (kbd "C-'") #'clojure-convert-collection-to-quoted-list)
+    (define-key map (kbd "'") #'clojure-convert-collection-to-quoted-list)
+    (define-key map (kbd "C-{") #'clojure-convert-collection-to-map)
+    (define-key map (kbd "{") #'clojure-convert-collection-to-map)
+    (define-key map (kbd "C-[") #'clojure-convert-collection-to-vector)
+    (define-key map (kbd "[") #'clojure-convert-collection-to-vector)
+    (define-key map (kbd "C-#") #'clojure-convert-collection-to-set)
+    (define-key map (kbd "#") #'clojure-convert-collection-to-set)
+    (define-key map (kbd "C-i") #'clojure-cycle-if)
+    (define-key map (kbd "i") #'clojure-cycle-if)
+    (define-key map (kbd "C-w") #'clojure-cycle-when)
+    (define-key map (kbd "w") #'clojure-cycle-when)
+    (define-key map (kbd "C-o") #'clojure-cycle-not)
+    (define-key map (kbd "o") #'clojure-cycle-not)
+    (define-key map (kbd "n i") #'clojure-insert-ns-form)
+    (define-key map (kbd "n h") #'clojure-insert-ns-form-at-point)
+    (define-key map (kbd "n u") #'clojure-update-ns)
+    (define-key map (kbd "n s") #'clojure-sort-ns)
+    (define-key map (kbd "s i") #'clojure-introduce-let)
+    (define-key map (kbd "s m") #'clojure-move-to-let)
+    (define-key map (kbd "s f") #'clojure-let-forward-slurp-sexp)
+    (define-key map (kbd "s b") #'clojure-let-backward-slurp-sexp)
+    map)
+  "Keymap for Clojure refactoring commands.")
+(fset 'clojure-refactor-map clojure-refactor-map)
+
+(defvar clojure-mode-map
+  (let ((map (make-sparse-keymap)))
+    (set-keymap-parent map prog-mode-map)
+    (define-key map (kbd "C-:") #'clojure-toggle-keyword-string)
+    (define-key map (kbd "C-c SPC") #'clojure-align)
+    (define-key map clojure-refactor-map-prefix 'clojure-refactor-map)
+    (easy-menu-define clojure-mode-menu map "Clojure Mode Menu"
+      '("Clojure"
+        ["Toggle between string & keyword" clojure-toggle-keyword-string]
+        ["Align expression" clojure-align]
+        ["Cycle privacy" clojure-cycle-privacy]
+        ["Cycle if, if-not" clojure-cycle-if]
+        ["Cycle when, when-not" clojure-cycle-when]
+        ["Cycle not" clojure-cycle-not]
+        ("ns forms"
+         ["Insert ns form at the top" clojure-insert-ns-form]
+         ["Insert ns form here" clojure-insert-ns-form-at-point]
+         ["Update ns form" clojure-update-ns]
+         ["Sort ns form" clojure-sort-ns])
+        ("Convert collection"
+         ["Convert to list" clojure-convert-collection-to-list]
+         ["Convert to quoted list" clojure-convert-collection-to-quoted-list]
+         ["Convert to map" clojure-convert-collection-to-map]
+         ["Convert to vector" clojure-convert-collection-to-vector]
+         ["Convert to set" clojure-convert-collection-to-set])
+        ("Refactor -> and ->>"
+         ["Thread once more" clojure-thread]
+         ["Fully thread a form with ->" clojure-thread-first-all]
+         ["Fully thread a form with ->>" clojure-thread-last-all]
+         "--"
+         ["Unwind once" clojure-unwind]
+         ["Fully unwind a threading macro" clojure-unwind-all])
+        ("Let expression"
+         ["Introduce let" clojure-introduce-let]
+         ["Move to let" clojure-move-to-let]
+         ["Forward slurp form into let" clojure-let-forward-slurp-sexp]
+         ["Backward slurp form into let" clojure-let-backward-slurp-sexp])
+        ("Documentation"
+         ["View a Clojure guide" clojure-view-guide]
+         ["View a Clojure reference section" clojure-view-reference-section]
+         ["View the Clojure cheatsheet" clojure-view-cheatsheet]
+         ["View the Clojure Grimoire" clojure-view-grimoire]
+         ["View the Clojure style guide" clojure-view-style-guide])
+        "--"
+        ["Report a clojure-mode bug" clojure-mode-report-bug]
+        ["Clojure-mode version" clojure-mode-display-version]))
+    map)
+  "Keymap for Clojure mode.")
+
+(defvar clojure-mode-syntax-table
+  (let ((table (copy-syntax-table emacs-lisp-mode-syntax-table)))
+    (modify-syntax-entry ?\{ "(}" table)
+    (modify-syntax-entry ?\} "){" table)
+    (modify-syntax-entry ?\[ "(]" table)
+    (modify-syntax-entry ?\] ")[" table)
+    (modify-syntax-entry ?? "_ p" table) ; ? is a prefix outside symbols
+    (modify-syntax-entry ?# "_ p" table) ; # is allowed inside keywords (#399)
+    (modify-syntax-entry ?~ "'" table)
+    (modify-syntax-entry ?^ "'" table)
+    (modify-syntax-entry ?@ "'" table)
+    table)
+  "Syntax table for Clojure mode.
+Inherits from `emacs-lisp-mode-syntax-table'.")
+
+(defconst clojure--prettify-symbols-alist
+  '(("fn"  . ?λ)))
+
+(defvar-local clojure-expected-ns-function nil
+  "The function used to determine the expected namespace of a file.
+`clojure-mode' ships a basic function named `clojure-expected-ns'
+that does basic heuristics to figure this out.
+CIDER provides a more complex version which does classpath analysis.")
+
+(defun clojure-mode-display-version ()
+  "Display the current `clojure-mode-version' in the minibuffer."
+  (interactive)
+  (message "clojure-mode (version %s)" clojure-mode-version))
+
+(defconst clojure-mode-report-bug-url "https://github.com/clojure-emacs/clojure-mode/issues/new"
+  "The URL to report a `clojure-mode' issue.")
+
+(defun clojure-mode-report-bug ()
+  "Report a bug in your default browser."
+  (interactive)
+  (browse-url clojure-mode-report-bug-url))
+
+(defconst clojure-guides-base-url "https://clojure.org/guides/"
+  "The base URL for official Clojure guides.")
+
+(defconst clojure-guides '(("Getting Started" . "getting_started")
+                           ("FAQ" . "faq")
+                           ("spec" . "spec")
+                           ("Destructuring" . "destructuring")
+                           ("Threading Macros" . "threading_macros")
+                           ("Comparators" . "comparators")
+                           ("Reader Conditionals" . "reader_conditionals"))
+  "A list of all official Clojure guides.")
+
+(defun clojure-view-guide ()
+  "Open a Clojure guide in your default browser.
+
+The command will prompt you to select one of the available guides."
+  (interactive)
+  (let ((guide (completing-read "Select a guide: " (mapcar #'car clojure-guides))))
+    (when guide
+      (let ((guide-url (concat clojure-guides-base-url (cdr (assoc guide clojure-guides)))))
+        (browse-url guide-url)))))
+
+(defconst clojure-reference-base-url "https://clojure.org/reference/"
+  "The base URL for the official Clojure reference.")
+
+(defconst clojure-reference-sections '(("The Reader" . "reader")
+                                       ("The REPL and main" . "repl_and_main")
+                                       ("Evaluation" . "evaluation")
+                                       ("Special Forms" . "special_forms")
+                                       ("Macros" . "macros")
+                                       ("Other Functions" . "other_functions")
+                                       ("Data Structures" . "data_structures")
+                                       ("Datatypes" . "datatypes")
+                                       ("Sequences" . "sequences")
+                                       ("Transients" . "transients")
+                                       ("Transducers" . "transducers")
+                                       ("Multimethods and Hierarchies" . "multimethods")
+                                       ("Protocols" . "protocols")
+                                       ("Metadata" . "metadata")
+                                       ("Namespaces" . "namespaces")
+                                       ("Libs" . "libs")
+                                       ("Vars and Environments" . "vars")
+                                       ("Refs and Transactions" . "refs")
+                                       ("Agents" . "agents")
+                                       ("Atoms" . "atoms")
+                                       ("Reducers" . "reducers")
+                                       ("Java Interop" . "java_interop")
+                                       ("Compilation and Class Generation" . "compilation")
+                                       ("Other Libraries" . "other_libraries")
+                                       ("Differences with Lisps" . "lisps")))
+
+(defun clojure-view-reference-section ()
+  "Open a Clojure reference section in your default browser.
+
+The command will prompt you to select one of the available sections."
+  (interactive)
+  (let ((section (completing-read "Select a reference section: " (mapcar #'car clojure-reference-sections))))
+    (when section
+      (let ((section-url (concat clojure-reference-base-url (cdr (assoc section clojure-reference-sections)))))
+        (browse-url section-url)))))
+
+(defconst clojure-cheatsheet-url "http://clojure.org/api/cheatsheet"
+  "The URL of the official Clojure cheatsheet.")
+
+(defun clojure-view-cheatsheet ()
+  "Open the Clojure cheatsheet in your default browser."
+  (interactive)
+  (browse-url clojure-cheatsheet-url))
+
+(defconst clojure-grimoire-url "https://www.conj.io/"
+  "The URL of the Grimoire community documentation site.")
+
+(defun clojure-view-grimoire ()
+  "Open the Clojure Grimoire in your default browser."
+  (interactive)
+  (browse-url clojure-grimoire-url))
+
+(defconst clojure-style-guide-url "https://github.com/bbatsov/clojure-style-guide"
+  "The URL of the Clojure style guide.")
+
+(defun clojure-view-style-guide ()
+  "Open the Clojure style guide in your default browser."
+  (interactive)
+  (browse-url clojure-style-guide-url))
+
+(defun clojure-space-for-delimiter-p (endp delim)
+  "Prevent paredit from inserting useless spaces.
+See `paredit-space-for-delimiter-predicates' for the meaning of
+ENDP and DELIM."
+  (or endp
+      (not (memq delim '(?\" ?{ ?\( )))
+      (not (or (derived-mode-p 'clojure-mode)
+               (derived-mode-p 'cider-repl-mode)))
+      (save-excursion
+        (backward-char)
+        (cond ((eq (char-after) ?#)
+               (and (not (bobp))
+                    (or (char-equal ?w (char-syntax (char-before)))
+                        (char-equal ?_ (char-syntax (char-before))))))
+              ((and (eq delim ?\()
+                    (eq (char-after) ??)
+                    (eq (char-before) ?#))
+               nil)
+              (t)))))
+
+(defconst clojure--collection-tag-regexp "#\\(::[a-zA-Z0-9._-]*\\|:?\\([a-zA-Z0-9._-]+/\\)?[a-zA-Z0-9._-]+\\)"
+    "Collection reader macro tag regexp.
+It is intended to check for allowed strings that can come before a
+collection literal (e.g. '[]' or '{}'), as reader macro tags.
+This includes #fully.qualified/my-ns[:kw val] and #::my-ns{:kw
+val} as of Clojure 1.9.")
+
+(defun clojure-no-space-after-tag (endp delimiter)
+  "Prevent inserting a space after a reader-literal tag.
+
+When a reader-literal tag is followed be an opening delimiter
+listed in `clojure-omit-space-between-tag-and-delimiters', this
+function returns t.
+
+This allows you to write things like #db/id[:db.part/user]
+and #::my-ns{:some \"map\"} without inserting a space between
+the tag and the opening bracket.
+
+See `paredit-space-for-delimiter-predicates' for the meaning of
+ENDP and DELIMITER."
+  (if endp
+      t
+    (or (not (member delimiter clojure-omit-space-between-tag-and-delimiters))
+        (save-excursion
+          (let ((orig-point (point)))
+            (not (and (re-search-backward
+                       clojure--collection-tag-regexp
+                       (line-beginning-position)
+                       t)
+                      (= orig-point (match-end 0)))))))))
+
+(declare-function paredit-open-curly "ext:paredit")
+(declare-function paredit-close-curly "ext:paredit")
+(declare-function paredit-convolute-sexp "ext:paredit")
+
+(defun clojure--replace-let-bindings-and-indent (orig-fun &rest args)
+  "Advise ORIG-FUN to replace let bindings.
+
+Sexps are replace by their bound name if a let form was
+convoluted.
+
+ORIG-FUN should be `paredit-convolute-sexp'.
+
+ARGS are passed to ORIG-FUN, as with all advice."
+  (save-excursion
+    (backward-sexp)
+    (when (looking-back clojure--let-regexp)
+      (clojure--replace-sexps-with-bindings-and-indent))))
+
+(defun clojure-paredit-setup (&optional keymap)
+  "Make \"paredit-mode\" play nice with `clojure-mode'.
+
+If an optional KEYMAP is passed the changes are applied to it,
+instead of to `clojure-mode-map'.
+Also advice `paredit-convolute-sexp' when used on a let form as drop in
+replacement for `cljr-expand-let`."
+  (when (>= paredit-version 21)
+    (let ((keymap (or keymap clojure-mode-map)))
+      (define-key keymap "{" #'paredit-open-curly)
+      (define-key keymap "}" #'paredit-close-curly))
+    (add-to-list 'paredit-space-for-delimiter-predicates
+                 #'clojure-space-for-delimiter-p)
+    (add-to-list 'paredit-space-for-delimiter-predicates
+                 #'clojure-no-space-after-tag)
+    (advice-add 'paredit-convolute-sexp :after #'clojure--replace-let-bindings-and-indent)))
+
+(defun clojure-mode-variables ()
+  "Set up initial buffer-local variables for Clojure mode."
+  (add-to-list 'imenu-generic-expression '(nil clojure-match-next-def 0))
+  (setq-local indent-tabs-mode nil)
+  (setq-local paragraph-ignore-fill-prefix t)
+  (setq-local outline-regexp ";;;\\(;* [^ \t\n]\\)\\|(")
+  (setq-local outline-level 'lisp-outline-level)
+  (setq-local comment-start ";")
+  (setq-local comment-start-skip ";+ *")
+  (setq-local comment-add 1) ; default to `;;' in comment-region
+  (setq-local comment-column 40)
+  (setq-local comment-use-syntax t)
+  (setq-local multibyte-syntax-as-symbol t)
+  (setq-local electric-pair-skip-whitespace 'chomp)
+  (setq-local electric-pair-open-newline-between-pairs nil)
+  (setq-local fill-paragraph-function #'clojure-fill-paragraph)
+  (setq-local adaptive-fill-function #'clojure-adaptive-fill-function)
+  (setq-local normal-auto-fill-function #'clojure-auto-fill-function)
+  (setq-local comment-start-skip
+              "\\(\\(^\\|[^\\\\\n]\\)\\(\\\\\\\\\\)*\\)\\(;+\\|#|\\) *")
+  (setq-local indent-line-function #'clojure-indent-line)
+  (setq-local indent-region-function #'clojure-indent-region)
+  (setq-local lisp-indent-function #'clojure-indent-function)
+  (setq-local lisp-doc-string-elt-property 'clojure-doc-string-elt)
+  (setq-local clojure-expected-ns-function #'clojure-expected-ns)
+  (setq-local parse-sexp-ignore-comments t)
+  (setq-local prettify-symbols-alist clojure--prettify-symbols-alist)
+  (setq-local open-paren-in-column-0-is-defun-start nil))
+
+(defsubst clojure-in-docstring-p ()
+  "Check whether point is in a docstring."
+  (let ((ppss (syntax-ppss)))
+    ;; are we in a string?
+    (when (nth 3 ppss)
+      ;; check font lock at the start of the string
+      (eq (get-text-property (nth 8 ppss) 'face)
+          'font-lock-doc-face))))
+
+;;;###autoload
+(define-derived-mode clojure-mode prog-mode "Clojure"
+  "Major mode for editing Clojure code.
+
+\\{clojure-mode-map}"
+  (clojure-mode-variables)
+  (clojure-font-lock-setup)
+  (add-hook 'paredit-mode-hook #'clojure-paredit-setup)
+  ;; `electric-layout-post-self-insert-function' prevents indentation in strings
+  ;; and comments, force indentation in docstrings:
+  (add-hook 'electric-indent-functions
+            (lambda (_char) (if (clojure-in-docstring-p) 'do-indent)))
+  ;; integration with project.el
+  (add-hook 'project-find-functions #'clojure-current-project))
+
+(defcustom clojure-verify-major-mode t
+  "If non-nil, warn when activating the wrong `major-mode'."
+  :type 'boolean
+  :safe #'booleanp
+  :package-version '(clojure-mode "5.3.0"))
+
+(defun clojure--check-wrong-major-mode ()
+  "Check if the current `major-mode' matches the file extension.
+
+If it doesn't, issue a warning if `clojure-verify-major-mode' is
+non-nil."
+  (when (and clojure-verify-major-mode
+             (stringp (buffer-file-name)))
+    (let* ((case-fold-search t)
+           (problem (cond ((and (string-match "\\.clj\\'" (buffer-file-name))
+                                (not (eq major-mode 'clojure-mode)))
+                           'clojure-mode)
+                          ((and (string-match "\\.cljs\\'" (buffer-file-name))
+                                (not (eq major-mode 'clojurescript-mode)))
+                           'clojurescript-mode)
+                          ((and (string-match "\\.cljc\\'" (buffer-file-name))
+                                (not (eq major-mode 'clojurec-mode)))
+                           'clojurec-mode))))
+      (when problem
+        (message "[WARNING] %s activated `%s' instead of `%s' in this buffer.
+This could cause problems.
+\(See `clojure-verify-major-mode' to disable this message.)"
+                 (if (eq major-mode real-this-command)
+                     "You have"
+                   "Something in your configuration")
+                 major-mode
+                 problem)))))
+
+(add-hook 'clojure-mode-hook #'clojure--check-wrong-major-mode)
+
+(defsubst clojure-docstring-fill-prefix ()
+  "The prefix string used by `clojure-fill-paragraph'.
+It is simply `clojure-docstring-fill-prefix-width' number of spaces."
+  (make-string clojure-docstring-fill-prefix-width ? ))
+
+(defun clojure-adaptive-fill-function ()
+  "Clojure adaptive fill function.
+This only takes care of filling docstring correctly."
+  (when (clojure-in-docstring-p)
+    (clojure-docstring-fill-prefix)))
+
+(defun clojure-fill-paragraph (&optional justify)
+  "Like `fill-paragraph', but can handle Clojure docstrings.
+If JUSTIFY is non-nil, justify as well as fill the paragraph."
+  (if (clojure-in-docstring-p)
+      (let ((paragraph-start
+             (concat paragraph-start
+                     "\\|\\s-*\\([(:\"[]\\|~@\\|`(\\|#'(\\)"))
+            (paragraph-separate
+             (concat paragraph-separate "\\|\\s-*\".*[,\\.]$"))
+            (fill-column (or clojure-docstring-fill-column fill-column))
+            (fill-prefix (clojure-docstring-fill-prefix)))
+        ;; we are in a string and string start pos (8th element) is non-nil
+        (let* ((beg-doc (nth 8 (syntax-ppss)))
+               (end-doc (save-excursion
+                          (goto-char beg-doc)
+                          (or (ignore-errors (forward-sexp) (point))
+                              (point-max)))))
+          (save-restriction
+            (narrow-to-region beg-doc end-doc)
+            (fill-paragraph justify))))
+    (let ((paragraph-start (concat paragraph-start
+                                   "\\|\\s-*\\([(:\"[]\\|`(\\|#'(\\)"))
+          (paragraph-separate
+           (concat paragraph-separate "\\|\\s-*\".*[,\\.[]$")))
+      (or (fill-comment-paragraph justify)
+          (fill-paragraph justify))
+      ;; Always return `t'
+      t)))
+
+(defun clojure-auto-fill-function ()
+  "Clojure auto-fill function."
+  ;; Check if auto-filling is meaningful.
+  (let ((fc (current-fill-column)))
+    (when (and fc (> (current-column) fc))
+      (let ((fill-column (if (clojure-in-docstring-p)
+                             clojure-docstring-fill-column
+                           fill-column))
+            (fill-prefix (clojure-adaptive-fill-function)))
+        (do-auto-fill)))))
+
+
+;;; #_ comments font-locking
+;; Code heavily borrowed from Slime.
+;; https://github.com/slime/slime/blob/master/contrib/slime-fontifying-fu.el#L186
+(defvar clojure--comment-macro-regexp
+  (rx "#_" (* " ") (group-n 1 (not (any " "))))
+  "Regexp matching the start of a comment sexp.
+The beginning of match-group 1 should be before the sexp to be
+marked as a comment.  The end of sexp is found with
+`clojure-forward-logical-sexp'.")
+
+(defvar clojure--reader-and-comment-regexp
+  "#_ *\\(?1:[^ ]\\)\\|\\(?1:(comment\\_>\\)"
+  "Regexp matching both `#_' macro and a comment sexp." )
+
+(defcustom clojure-comment-regexp clojure--comment-macro-regexp
+  "Comment mode.
+
+The possible values for this variable are keywords indicating
+what is considered a comment (affecting font locking).
+
+    - Reader macro `#_' only - the default
+    - Reader macro `#_' and `(comment)'"
+  :type '(choice (const :tag "Reader macro `#_' and `(comment)'" clojure--reader-and-comment-regexp)
+                 (other :tag "Reader macro `#_' only" clojure--comment-macro-regexp))
+  :package-version '(clojure-mode . "5.7.0"))
+
+(defun clojure--search-comment-macro-internal (limit)
+  "Search for a comment forward stopping at LIMIT."
+  (when (search-forward-regexp clojure-comment-regexp limit t)
+    (let* ((md (match-data))
+           (start (match-beginning 1))
+           (state (syntax-ppss start)))
+      ;; inside string or comment?
+      (if (or (nth 3 state)
+              (nth 4 state))
+          (clojure--search-comment-macro-internal limit)
+        (goto-char start)
+        (clojure-forward-logical-sexp 1)
+        ;; Data for (match-end 1).
+        (setf (elt md 3) (point))
+        (set-match-data md)
+        t))))
+
+(defun clojure--search-comment-macro (limit)
+  "Find comment macros and set the match data.
+Search from point up to LIMIT.  The region that should be
+considered a comment is between `(match-beginning 1)'
+and `(match-end 1)'."
+  (let ((result 'retry))
+    (while (and (eq result 'retry) (<= (point) limit))
+      (condition-case nil
+          (setq result (clojure--search-comment-macro-internal limit))
+        (end-of-file (setq result nil))
+        (scan-error  (setq result 'retry))))
+    result))
+
+
+;;; General font-locking
+(defun clojure-match-next-def ()
+  "Scans the buffer backwards for the next \"top-level\" definition.
+Called by `imenu--generic-function'."
+  ;; we have to take into account namespace-definition forms
+  ;; e.g. s/defn
+  (when (re-search-backward "^[ \t]*(\\([a-z0-9.-]+/\\)?\\(def\\sw*\\)" nil t)
+    (save-excursion
+      (let (found?
+            (deftype (match-string 2))
+            (start (point)))
+        (down-list)
+        (forward-sexp)
+        (while (not found?)
+          (ignore-errors
+            (forward-sexp))
+          (or (when (char-equal ?\[ (char-after (point)))
+                (backward-sexp))
+              (when (char-equal ?\) (char-after (point)))
+                (backward-sexp)))
+          (cl-destructuring-bind (def-beg . def-end) (bounds-of-thing-at-point 'sexp)
+            (if (char-equal ?^ (char-after def-beg))
+                (progn (forward-sexp) (backward-sexp))
+              (setq found? t)
+              (when (string= deftype "defmethod")
+                (setq def-end (progn (goto-char def-end)
+                                     (forward-sexp)
+                                     (point))))
+              (set-match-data (list def-beg def-end)))))
+        (goto-char start)))))
+
+(eval-and-compile
+  (defconst clojure--sym-forbidden-rest-chars "][\";\'@\\^`~\(\)\{\}\\,\s\t\n\r"
+    "A list of chars that a Clojure symbol cannot contain.
+See definition of 'macros': URL `http://git.io/vRGLD'.")
+  (defconst clojure--sym-forbidden-1st-chars (concat clojure--sym-forbidden-rest-chars "0-9:")
+    "A list of chars that a Clojure symbol cannot start with.
+See the for-loop: URL `http://git.io/vRGTj' lines: URL
+`http://git.io/vRGIh', URL `http://git.io/vRGLE' and value
+definition of 'macros': URL `http://git.io/vRGLD'.")
+  (defconst clojure--sym-regexp
+    (concat "[^" clojure--sym-forbidden-1st-chars "][^" clojure--sym-forbidden-rest-chars "]*")
+    "A regexp matching a Clojure symbol or namespace alias.
+Matches the rule `clojure--sym-forbidden-1st-chars' followed by
+any number of matches of `clojure--sym-forbidden-rest-chars'."))
+
+(defconst clojure-font-lock-keywords
+  (eval-when-compile
+    `( ;; Top-level variable definition
+      (,(concat "(\\(?:clojure.core/\\)?\\("
+                (regexp-opt '("def" "defonce"))
+                ;; variable declarations
+                "\\)\\>"
+                ;; Any whitespace
+                "[ \r\n\t]*"
+                ;; Possibly type or metadata
+                "\\(?:#?^\\(?:{[^}]*}\\|\\sw+\\)[ \r\n\t]*\\)*"
+                "\\(\\sw+\\)?")
+       (1 font-lock-keyword-face)
+       (2 font-lock-variable-name-face nil t))
+      ;; Type definition
+      (,(concat "(\\(?:clojure.core/\\)?\\("
+                (regexp-opt '("defstruct" "deftype" "defprotocol"
+                              "defrecord"))
+                ;; type declarations
+                "\\)\\>"
+                ;; Any whitespace
+                "[ \r\n\t]*"
+                ;; Possibly type or metadata
+                "\\(?:#?^\\(?:{[^}]*}\\|\\sw+\\)[ \r\n\t]*\\)*"
+                "\\(\\sw+\\)?")
+       (1 font-lock-keyword-face)
+       (2 font-lock-type-face nil t))
+      ;; Function definition (anything that starts with def and is not
+      ;; listed above)
+      (,(concat "(\\(?:" clojure--sym-regexp "/\\)?"
+                "\\(def[^ \r\n\t]*\\)"
+                ;; Function declarations
+                "\\>"
+                ;; Any whitespace
+                "[ \r\n\t]*"
+                ;; Possibly type or metadata
+                "\\(?:#?^\\(?:{[^}]*}\\|\\sw+\\)[ \r\n\t]*\\)*"
+                "\\(\\sw+\\)?")
+       (1 font-lock-keyword-face)
+       (2 font-lock-function-name-face nil t))
+      ;; (fn name? args ...)
+      (,(concat "(\\(?:clojure.core/\\)?\\(fn\\)[ \t]+"
+                ;; Possibly type
+                "\\(?:#?^\\sw+[ \t]*\\)?"
+                ;; Possibly name
+                "\\(\\sw+\\)?" )
+       (1 font-lock-keyword-face)
+       (2 font-lock-function-name-face nil t))
+      ;; lambda arguments - %, %&, %1, %2, etc
+      ("\\<%[&1-9]?" (0 font-lock-variable-name-face))
+      ;; Special forms
+      (,(concat
+         "("
+         (regexp-opt
+          '("def" "do" "if" "let" "let*" "var" "fn" "fn*" "loop" "loop*"
+            "recur" "throw" "try" "catch" "finally"
+            "set!" "new" "."
+            "monitor-enter" "monitor-exit" "quote") t)
+         "\\>")
+       1 font-lock-keyword-face)
+      ;; Built-in binding and flow of control forms
+      (,(concat
+         "(\\(?:clojure.core/\\)?"
+         (regexp-opt
+          '("letfn" "case" "cond" "cond->" "cond->>" "condp"
+            "for" "when" "when-not" "when-let" "when-first" "when-some"
+            "if-let" "if-not" "if-some"
+            ".." "->" "->>" "as->" "doto" "and" "or"
+            "dosync" "doseq" "dotimes" "dorun" "doall"
+            "ns" "in-ns"
+            "with-open" "with-local-vars" "binding"
+            "with-redefs" "with-redefs-fn"
+            "declare") t)
+         "\\>")
+       1 font-lock-keyword-face)
+      ;; Macros similar to let, when, and while
+      (,(rx symbol-start
+            (or "let" "when" "while") "-"
+            (1+ (or (syntax word) (syntax symbol)))
+            symbol-end)
+       0 font-lock-keyword-face)
+      (,(concat
+         "\\<"
+         (regexp-opt
+          '("*1" "*2" "*3" "*agent*"
+            "*allow-unresolved-vars*" "*assert*" "*clojure-version*"
+            "*command-line-args*" "*compile-files*"
+            "*compile-path*" "*data-readers*" "*default-data-reader-fn*"
+            "*e" "*err*" "*file*" "*flush-on-newline*"
+            "*in*" "*macro-meta*" "*math-context*" "*ns*" "*out*"
+            "*print-dup*" "*print-length*" "*print-level*"
+            "*print-meta*" "*print-readably*"
+            "*read-eval*" "*source-path*"
+            "*unchecked-math*"
+            "*use-context-classloader*" "*warn-on-reflection*")
+          t)
+         "\\>")
+       0 font-lock-builtin-face)
+      ;; Dynamic variables - *something* or @*something*
+      ("\\(?:\\<\\|/\\)@?\\(\\*[a-z-]*\\*\\)\\>" 1 font-lock-variable-name-face)
+      ;; Global constants - nil, true, false
+      (,(concat
+         "\\<"
+         (regexp-opt
+          '("true" "false" "nil") t)
+         "\\>")
+       0 font-lock-constant-face)
+      ;; Character literals - \1, \a, \newline, \u0000
+      ("\\\\\\([[:punct:]]\\|[a-z0-9]+\\>\\)" 0 'clojure-character-face)
+
+      ;; namespace definitions: (ns foo.bar)
+      (,(concat "(\\<ns\\>[ \r\n\t]*"
+                ;; Possibly metadata
+                "\\(?:\\^?{[^}]+}[ \r\n\t]*\\)*"
+                ;; namespace
+                "\\(" clojure--sym-regexp "\\)")
+       (1 font-lock-type-face))
+
+      ;; TODO dedupe the code for matching of keywords, type-hints and unmatched symbols
+
+      ;; keywords: {:oneword/ve/yCom|pLex.stu-ff 0}
+      (,(concat "\\(:\\{1,2\\}\\)\\(" clojure--sym-regexp "?\\)\\(/\\)\\(" clojure--sym-regexp "\\)")
+       (1 'clojure-keyword-face)
+       (2 font-lock-type-face)
+       ;; (2 'clojure-keyword-face)
+       (3 'default)
+       (4 'clojure-keyword-face))
+      (,(concat "\\(:\\{1,2\\}\\)\\(" clojure--sym-regexp "\\)")
+       (1 'clojure-keyword-face)
+       (2 'clojure-keyword-face))
+
+      ;; type-hints: #^oneword
+      (,(concat "\\(#^\\)\\(" clojure--sym-regexp "?\\)\\(/\\)\\(" clojure--sym-regexp "\\)")
+       (1 'default)
+       (2 font-lock-type-face)
+       (3 'default)
+       (4 'default))
+      (,(concat "\\(#^\\)\\(" clojure--sym-regexp "\\)")
+       (1 'default)
+       (2 font-lock-type-face))
+
+      ;; clojure symbols not matched by the previous regexps; influences CIDER's
+      ;; dynamic syntax highlighting (CDSH). See https://git.io/vxEEA:
+      (,(concat "\\(" clojure--sym-regexp "?\\)\\(/\\)\\(" clojure--sym-regexp "\\)")
+       (1 font-lock-type-face)
+       ;; 2nd and 3th matching groups can be font-locked to `nil' or `default'.
+       ;; CDSH seems to kick in only for functions and variables referenced w/o
+       ;; writing their namespaces.
+       (2 nil)
+       (3 nil))
+      (,(concat "\\(" clojure--sym-regexp "\\)")
+       ;; this matching group must be font-locked to `nil' otherwise CDSH breaks.
+       (1 nil))
+
+      ;; #_ and (comment ...) macros.
+      (clojure--search-comment-macro 1 font-lock-comment-face t)
+      ;; Highlight `code` marks, just like `elisp'.
+      (,(rx "`" (group-n 1 (optional "#'")
+                         (+ (or (syntax symbol) (syntax word)))) "`")
+       (1 'font-lock-constant-face prepend))
+      ;; Highlight escaped characters in strings.
+      (clojure-font-lock-escaped-chars 0 'bold prepend)
+      ;; Highlight grouping constructs in regular expressions
+      (clojure-font-lock-regexp-groups
+       (1 'font-lock-regexp-grouping-construct prepend))))
+  "Default expressions to highlight in Clojure mode.")
+
+(defun clojure-font-lock-syntactic-face-function (state)
+  "Find and highlight text with a Clojure-friendly syntax table.
+
+This function is passed to `font-lock-syntactic-face-function',
+which is called with a single parameter, STATE (which is, in
+turn, returned by `parse-partial-sexp' at the beginning of the
+highlighted region)."
+  (if (nth 3 state)
+      ;; This might be a (doc)string or a |...| symbol.
+      (let ((startpos (nth 8 state)))
+        (if (eq (char-after startpos) ?|)
+            ;; This is not a string, but a |...| symbol.
+            nil
+          (let* ((listbeg (nth 1 state))
+                 (firstsym (and listbeg
+                                (save-excursion
+                                  (goto-char listbeg)
+                                  (and (looking-at "([ \t\n]*\\(\\(\\sw\\|\\s_\\)+\\)")
+                                       (match-string 1)))))
+                 (docelt (and firstsym
+                              (function-get (intern-soft firstsym)
+                                            lisp-doc-string-elt-property))))
+            (if (and docelt
+                     ;; It's a string in a form that can have a docstring.
+                     ;; Check whether it's in docstring position.
+                     (save-excursion
+                       (when (functionp docelt)
+                         (goto-char (match-end 1))
+                         (setq docelt (funcall docelt)))
+                       (goto-char listbeg)
+                       (forward-char 1)
+                       (ignore-errors
+                         (while (and (> docelt 0) (< (point) startpos)
+                                     (progn (forward-sexp 1) t))
+                           ;; ignore metadata and type hints
+                           (unless (looking-at "[ \n\t]*\\(\\^[A-Z:].+\\|\\^?{.+\\)")
+                             (setq docelt (1- docelt)))))
+                       (and (zerop docelt) (<= (point) startpos)
+                            (progn (forward-comment (point-max)) t)
+                            (= (point) (nth 8 state)))))
+                font-lock-doc-face
+              font-lock-string-face))))
+    font-lock-comment-face))
+
+(defun clojure-font-lock-setup ()
+  "Configures font-lock for editing Clojure code."
+  (setq-local font-lock-multiline t)
+  (add-to-list 'font-lock-extend-region-functions
+               #'clojure-font-lock-extend-region-def t)
+  (setq font-lock-defaults
+        '(clojure-font-lock-keywords    ; keywords
+          nil nil
+          (("+-*/.<>=!?$%_&:" . "w")) ; syntax alist
+          nil
+          (font-lock-mark-block-function . mark-defun)
+          (font-lock-syntactic-face-function
+           . clojure-font-lock-syntactic-face-function))))
+
+(defun clojure-font-lock-def-at-point (point)
+  "Range between the top-most def* and the fourth element after POINT.
+Note that this means that there is no guarantee of proper font
+locking in def* forms that are not at top level."
+  (goto-char point)
+  (ignore-errors
+    (beginning-of-defun))
+
+  (let ((beg-def (point)))
+    (when (and (not (= point beg-def))
+               (looking-at "(def"))
+      (ignore-errors
+        ;; move forward as much as possible until failure (or success)
+        (forward-char)
+        (dotimes (_ 4)
+          (forward-sexp)))
+      (cons beg-def (point)))))
+
+(defun clojure-font-lock-extend-region-def ()
+  "Set region boundaries to include the first four elements of def* forms."
+  (let ((changed nil))
+    (let ((def (clojure-font-lock-def-at-point font-lock-beg)))
+      (when def
+        (cl-destructuring-bind (def-beg . def-end) def
+          (when (and (< def-beg font-lock-beg)
+                     (< font-lock-beg def-end))
+            (setq font-lock-beg def-beg
+                  changed t)))))
+    (let ((def (clojure-font-lock-def-at-point font-lock-end)))
+      (when def
+        (cl-destructuring-bind (def-beg . def-end) def
+          (when (and (< def-beg font-lock-end)
+                     (< font-lock-end def-end))
+            (setq font-lock-end def-end
+                  changed t)))))
+    changed))
+
+(defun clojure--font-locked-as-string-p (&optional regexp)
+  "Non-nil if the char before point is font-locked as a string.
+If REGEXP is non-nil, also check whether current string is
+preceeded by a #."
+  (let ((face (get-text-property (1- (point)) 'face)))
+    (and (or (and (listp face)
+                  (memq 'font-lock-string-face face))
+             (eq 'font-lock-string-face face))
+         (or (clojure-string-start t)
+             (unless regexp
+               (clojure-string-start nil))))))
+
+(defun clojure-font-lock-escaped-chars (bound)
+  "Highlight \escaped chars in strings.
+BOUND denotes a buffer position to limit the search."
+  (let ((found nil))
+    (while (and (not found)
+                (re-search-forward "\\\\." bound t))
+
+      (setq found (clojure--font-locked-as-string-p)))
+    found))
+
+(defun clojure-font-lock-regexp-groups (bound)
+  "Highlight grouping constructs in regular expression.
+
+BOUND denotes the maximum number of characters (relative to the
+point) to check."
+  (let ((found nil))
+    (while (and (not found)
+                (re-search-forward (eval-when-compile
+                                     (concat
+                                      ;; A group may start using several alternatives:
+                                      "\\(\\(?:"
+                                      ;; 1. (? special groups
+                                      "(\\?\\(?:"
+                                      ;; a) non-capturing group (?:X)
+                                      ;; b) independent non-capturing group (?>X)
+                                      ;; c) zero-width positive lookahead (?=X)
+                                      ;; d) zero-width negative lookahead (?!X)
+                                      "[:=!>]\\|"
+                                      ;; e) zero-width positive lookbehind (?<=X)
+                                      ;; f) zero-width negative lookbehind (?<!X)
+                                      "<[=!]\\|"
+                                      ;; g) named capturing group (?<name>X)
+                                      "<[[:alnum:]]+>"
+                                      "\\)\\|" ;; end of special groups
+                                      ;; 2. normal capturing groups (
+                                      ;; 3. we also highlight alternative
+                                      ;; separarators |, and closing parens )
+                                      "[|()]"
+                                      "\\)\\)"))
+                                   bound t))
+      (setq found (clojure--font-locked-as-string-p 'regexp)))
+    found))
+
+;; Docstring positions
+(put 'ns 'clojure-doc-string-elt 2)
+(put 'def 'clojure-doc-string-elt 2)
+(put 'defn 'clojure-doc-string-elt 2)
+(put 'defn- 'clojure-doc-string-elt 2)
+(put 'defmulti 'clojure-doc-string-elt 2)
+(put 'defmacro 'clojure-doc-string-elt 2)
+(put 'definline 'clojure-doc-string-elt 2)
+(put 'defprotocol 'clojure-doc-string-elt 2)
+(put 'deftask 'clojure-doc-string-eld 2) ;; common Boot macro
+
+;;; Vertical alignment
+(defcustom clojure-align-forms-automatically nil
+  "If non-nil, vertically align some forms automatically.
+Automatically means it is done as part of indenting code.  This
+applies to binding forms (`clojure-align-binding-forms'), to cond
+forms (`clojure-align-cond-forms') and to map literals.  For
+instance, selecting a map a hitting \\<clojure-mode-map>`\\[indent-for-tab-command]'
+will align the values like this:
+    {:some-key 10
+     :key2     20}"
+  :package-version '(clojure-mode . "5.1")
+  :safe #'booleanp
+  :type 'boolean)
+
+(defcustom clojure-align-binding-forms
+  '("let" "when-let" "when-some" "if-let" "if-some" "binding" "loop"
+    "doseq" "for" "with-open" "with-local-vars" "with-redefs")
+  "List of strings matching forms that have binding forms."
+  :package-version '(clojure-mode . "5.1")
+  :safe #'listp
+  :type '(repeat string))
+
+(defcustom clojure-align-cond-forms '("condp" "cond" "cond->" "cond->>" "case" "are")
+  "List of strings identifying cond-like forms."
+  :package-version '(clojure-mode . "5.1")
+  :safe #'listp
+  :type '(repeat string))
+
+(defun clojure--position-for-alignment ()
+  "Non-nil if the sexp around point should be automatically aligned.
+This function expects to be called immediately after an
+open-brace or after the function symbol in a function call.
+
+First check if the sexp around point is a map literal, or is a
+call to one of the vars listed in `clojure-align-cond-forms'.  If
+it isn't, return nil.  If it is, return non-nil and place point
+immediately before the forms that should be aligned.
+
+For instance, in a map literal point is left immediately before
+the first key; while, in a let-binding, point is left inside the
+binding vector and immediately before the first binding
+construct."
+  ;; Are we in a map?
+  (or (and (eq (char-before) ?{)
+           (not (eq (char-before (1- (point))) ?\#)))
+      ;; Are we in a cond form?
+      (let* ((fun    (car (member (thing-at-point 'symbol) clojure-align-cond-forms)))
+             (method (and fun (clojure--get-indent-method fun)))
+             ;; The number of special arguments in the cond form is
+             ;; the number of sexps we skip before aligning.
+             (skip   (cond ((numberp method) method)
+                           ((null method) 0)
+                           ((sequencep method) (elt method 0)))))
+        (when (and fun (numberp skip))
+          (clojure-forward-logical-sexp skip)
+          (comment-forward (point-max))
+          fun)) ; Return non-nil (the var name).
+      ;; Are we in a let-like form?
+      (when (member (thing-at-point 'symbol)
+                    clojure-align-binding-forms)
+        ;; Position inside the binding vector.
+        (clojure-forward-logical-sexp)
+        (backward-sexp)
+        (when (eq (char-after) ?\[)
+          (forward-char 1)
+          (comment-forward (point-max))
+          ;; Return non-nil.
+          t))))
+
+(defun clojure--find-sexp-to-align (end)
+  "Non-nil if there's a sexp ahead to be aligned before END.
+Place point as in `clojure--position-for-alignment'."
+  ;; Look for a relevant sexp.
+  (let ((found))
+    (while (and (not found)
+                (search-forward-regexp
+                 (concat "{\\|(" (regexp-opt
+                                  (append clojure-align-binding-forms
+                                          clojure-align-cond-forms)
+                                  'symbols))
+                 end 'noerror))
+
+      (let ((ppss (syntax-ppss)))
+        ;; If we're in a string or comment.
+        (unless (or (elt ppss 3)
+                    (elt ppss 4))
+          ;; Only stop looking if we successfully position
+          ;; the point.
+          (setq found (clojure--position-for-alignment)))))
+    found))
+
+(defun clojure--search-whitespace-after-next-sexp (&optional bound _noerror)
+  "Move point after all whitespace after the next sexp.
+
+Set the match data group 1 to be this region of whitespace and
+return point.
+
+BOUND is bounds the whitespace search."
+  (unwind-protect
+      (ignore-errors
+        (clojure-forward-logical-sexp 1)
+        (search-forward-regexp "\\([,\s\t]*\\)" bound)
+        (pcase (syntax-after (point))
+          ;; End-of-line, try again on next line.
+          (`(12) (clojure--search-whitespace-after-next-sexp bound))
+          ;; Closing paren, stop here.
+          (`(5 . ,_) nil)
+          ;; Anything else is something to align.
+          (_ (point))))
+    (when (and bound (> (point) bound))
+      (goto-char bound))))
+
+(defun clojure-align (beg end)
+  "Vertically align the contents of the sexp around point.
+If region is active, align it.  Otherwise, align everything in the
+current \"top-level\" sexp.
+When called from lisp code align everything between BEG and END."
+  (interactive (if (use-region-p)
+                   (list (region-beginning) (region-end))
+                 (save-excursion
+                   (let ((end (progn (end-of-defun)
+                                     (point))))
+                     (clojure-backward-logical-sexp)
+                     (list (point) end)))))
+  (setq end (copy-marker end))
+  (save-excursion
+    (goto-char beg)
+    (while (clojure--find-sexp-to-align end)
+      (let ((sexp-end (save-excursion
+                        (backward-up-list)
+                        (forward-sexp 1)
+                        (point-marker)))
+            (clojure-align-forms-automatically nil)
+            (count 1))
+        ;; For some bizarre reason, we need to `align-region' once for each
+        ;; group.
+        (save-excursion
+          (while (search-forward-regexp "^ *\n" sexp-end 'noerror)
+            (cl-incf count)))
+        (dotimes (_ count)
+          (align-region (point) sexp-end nil
+                        '((clojure-align (regexp . clojure--search-whitespace-after-next-sexp)
+                                         (group . 1)
+                                         (separate . "^ *$")
+                                         (repeat . t)))
+                        nil))
+        ;; Reindent after aligning because of #360.
+        (indent-region (point) sexp-end)))))
+
+;;; Indentation
+(defun clojure-indent-region (beg end)
+  "Like `indent-region', but also maybe align forms.
+Forms between BEG and END are aligned according to
+`clojure-align-forms-automatically'."
+  (prog1 (let ((indent-region-function nil))
+           (indent-region beg end))
+    (when clojure-align-forms-automatically
+      (condition-case nil
+          (clojure-align beg end)
+        (scan-error nil)))))
+
+(defun clojure-indent-line ()
+  "Indent current line as Clojure code."
+  (if (clojure-in-docstring-p)
+      (save-excursion
+        (beginning-of-line)
+        (when (and (looking-at "^\\s-*")
+                   (<= (string-width (match-string-no-properties 0))
+                       (string-width (clojure-docstring-fill-prefix))))
+          (replace-match (clojure-docstring-fill-prefix))))
+    (lisp-indent-line)))
+
+(defvar clojure-get-indent-function nil
+  "Function to get the indent spec of a symbol.
+This function should take one argument, the name of the symbol as
+a string.  This name will be exactly as it appears in the buffer,
+so it might start with a namespace alias.
+
+This function is analogous to the `clojure-indent-function'
+symbol property, and its return value should match one of the
+allowed values of this property.  See `clojure-indent-function'
+for more information.")
+
+(defun clojure--get-indent-method (function-name)
+  "Return the indent spec for the symbol named FUNCTION-NAME.
+FUNCTION-NAME is a string.  If it contains a `/', also try only
+the part after the `/'.
+
+Look for a spec using `clojure-get-indent-function', then try the
+`clojure-indent-function' and `clojure-backtracking-indent'
+symbol properties."
+  (or (when (functionp clojure-get-indent-function)
+        (funcall clojure-get-indent-function function-name))
+      (get (intern-soft function-name) 'clojure-indent-function)
+      (get (intern-soft function-name) 'clojure-backtracking-indent)
+      (when (string-match "/\\([^/]+\\)\\'" function-name)
+        (or (get (intern-soft (match-string 1 function-name))
+                 'clojure-indent-function)
+            (get (intern-soft (match-string 1 function-name))
+                 'clojure-backtracking-indent)))
+      (when (string-match (rx (or "let" "when" "while") (syntax symbol))
+                          function-name)
+        (clojure--get-indent-method (substring (match-string 0 function-name) 0 -1)))))
+
+(defvar clojure--current-backtracking-depth 0)
+
+(defun clojure--find-indent-spec-backtracking ()
+  "Return the indent sexp that applies to the sexp at point.
+Implementation function for `clojure--find-indent-spec'."
+  (when (and (>= clojure-max-backtracking clojure--current-backtracking-depth)
+             (not (looking-at "^")))
+    (let ((clojure--current-backtracking-depth (1+ clojure--current-backtracking-depth))
+          (pos 0))
+      ;; Count how far we are from the start of the sexp.
+      (while (ignore-errors (clojure-backward-logical-sexp 1)
+                            (not (or (bobp)
+                                     (eq (char-before) ?\n))))
+        (cl-incf pos))
+      (let* ((function (thing-at-point 'symbol))
+             (method (or (when function ;; Is there a spec here?
+                           (clojure--get-indent-method function))
+                         (ignore-errors
+                           ;; Otherwise look higher up.
+                           (pcase (syntax-ppss)
+                             (`(,(pred (< 0)) ,start . ,_)
+                              (goto-char start)
+                              (clojure--find-indent-spec-backtracking)))))))
+        (when (numberp method)
+          (setq method (list method)))
+        (pcase method
+          ((pred functionp)
+           (when (= pos 0)
+             method))
+          ((pred sequencep)
+           (pcase (length method)
+             (`0 nil)
+             (`1 (let ((head (elt method 0)))
+                   (when (or (= pos 0) (sequencep head))
+                     head)))
+             (l (if (>= pos l)
+                    (elt method (1- l))
+                  (elt method pos)))))
+          ((or `defun `:defn)
+           (when (= pos 0)
+             :defn))
+          (_
+           (message "Invalid indent spec for `%s': %s" function method)
+           nil))))))
+
+(defun clojure--find-indent-spec ()
+  "Return the indent spec that applies to current sexp.
+If `clojure-use-backtracking-indent' is non-nil, also do
+backtracking up to a higher-level sexp in order to find the
+spec."
+  (if clojure-use-backtracking-indent
+      (save-excursion
+        (clojure--find-indent-spec-backtracking))
+    (let ((function (thing-at-point 'symbol)))
+      (clojure--get-indent-method function))))
+
+(defun clojure--normal-indent (last-sexp indent-mode)
+  "Return the normal indentation column for a sexp.
+Point should be after the open paren of the _enclosing_ sexp, and
+LAST-SEXP is the start of the previous sexp (immediately before
+the sexp being indented).  INDENT-MODE is any of the values
+accepted by `clojure-indent-style'."
+  (goto-char last-sexp)
+  (forward-sexp 1)
+  (clojure-backward-logical-sexp 1)
+  (let ((last-sexp-start nil))
+    (if (ignore-errors
+          ;; `backward-sexp' until we reach the start of a sexp that is the
+          ;; first of its line (the start of the enclosing sexp).
+          (while (string-match
+                  "[^[:blank:]]"
+                  (buffer-substring (line-beginning-position) (point)))
+            (setq last-sexp-start (prog1 (point)
+                                    (forward-sexp -1))))
+          t)
+        ;; Here we have found an arg before the arg we're indenting which is at
+        ;; the start of a line. Every mode simply aligns on this case.
+        (current-column)
+      ;; Here we have reached the start of the enclosing sexp (point is now at
+      ;; the function name), so the behaviour depends on INDENT-MODE and on
+      ;; whether there's also an argument on this line (case A or B).
+      (let ((case-a ; The meaning of case-a is explained in `clojure-indent-style'.
+             (and last-sexp-start
+                  (< last-sexp-start (line-end-position)))))
+        (cond
+         ;; For compatibility with the old `clojure-defun-style-default-indent', any
+         ;; value other than these 3 is equivalent to `always-body'.
+         ((not (memq indent-mode '(:always-align :align-arguments nil)))
+          (+ (current-column) lisp-body-indent -1))
+         ;; There's an arg after the function name, so align with it.
+         (case-a (goto-char last-sexp-start)
+                 (current-column))
+         ;; Not same line.
+         ((eq indent-mode :align-arguments)
+          (+ (current-column) lisp-body-indent -1))
+         ;; Finally, just align with the function name.
+         (t (current-column)))))))
+
+(defun clojure--not-function-form-p ()
+  "Non-nil if form at point doesn't represent a function call."
+  (or (member (char-after) '(?\[ ?\{))
+      (save-excursion ;; Catch #?@ (:cljs ...)
+        (skip-chars-backward "\r\n[:blank:]")
+        (when (eq (char-before) ?@)
+          (forward-char -1))
+        (and (eq (char-before) ?\?)
+             (eq (char-before (1- (point))) ?\#)))
+      ;; Car of form is not a symbol.
+      (not (looking-at ".\\(?:\\sw\\|\\s_\\)"))))
+
+;; Check the general context, and provide indentation for data structures and
+;; special macros. If current form is a function (or non-special macro),
+;; delegate indentation to `clojure--normal-indent'.
+(defun clojure-indent-function (indent-point state)
+  "When indenting a line within a function call, indent properly.
+
+INDENT-POINT is the position where the user typed TAB, or equivalent.
+Point is located at the point to indent under (for default indentation);
+STATE is the `parse-partial-sexp' state for that position.
+
+If the current line is in a call to a Clojure function with a
+non-nil property `clojure-indent-function', that specifies how to do
+the indentation.
+
+The property value can be
+
+- `defun', meaning indent `defun'-style;
+- an integer N, meaning indent the first N arguments specially
+  like ordinary function arguments and then indent any further
+  arguments like a body;
+- a function to call just as this function was called.
+  If that function returns nil, that means it doesn't specify
+  the indentation.
+- a list, which is used by `clojure-backtracking-indent'.
+
+This function also returns nil meaning don't specify the indentation."
+  ;; Goto to the open-paren.
+  (goto-char (elt state 1))
+  ;; Maps, sets, vectors and reader conditionals.
+  (if (clojure--not-function-form-p)
+      (1+ (current-column))
+    ;; Function or macro call.
+    (forward-char 1)
+    (let ((method (clojure--find-indent-spec))
+          (last-sexp calculate-lisp-indent-last-sexp)
+          (containing-form-column (1- (current-column))))
+      (pcase method
+        ((or (pred integerp) `(,method))
+         (let ((pos -1))
+           (condition-case nil
+               (while (and (<= (point) indent-point)
+                           (not (eobp)))
+                 (clojure-forward-logical-sexp 1)
+                 (cl-incf pos))
+             ;; If indent-point is _after_ the last sexp in the
+             ;; current sexp, we detect that by catching the
+             ;; `scan-error'. In that case, we should return the
+             ;; indentation as if there were an extra sexp at point.
+             (scan-error (cl-incf pos)))
+           (cond
+            ;; The first non-special arg. Rigidly reduce indentation.
+            ((= pos (1+ method))
+             (+ lisp-body-indent containing-form-column))
+            ;; Further non-special args, align with the arg above.
+            ((> pos (1+ method))
+             (clojure--normal-indent last-sexp :always-align))
+            ;; Special arg. Rigidly indent with a large indentation.
+            (t
+             (+ (* 2 lisp-body-indent) containing-form-column)))))
+        (`:defn
+         (+ lisp-body-indent containing-form-column))
+        ((pred functionp)
+         (funcall method indent-point state))
+        ;; No indent spec, do the default.
+        (`nil
+         (let ((function (thing-at-point 'symbol)))
+           (cond
+            ;; Preserve useful alignment of :require (and friends) in `ns' forms.
+            ((and function (string-match "^:" function))
+             (clojure--normal-indent last-sexp :always-align))
+            ;; This is should be identical to the :defn above.
+            ((and function
+                  (string-match "\\`\\(?:\\S +/\\)?\\(def[a-z]*\\|with-\\)"
+                                function)
+                  (not (string-match "\\`default" (match-string 1 function))))
+             (+ lisp-body-indent containing-form-column))
+            ;; Finally, nothing special here, just respect the user's
+            ;; preference.
+            (t (clojure--normal-indent last-sexp clojure-indent-style)))))))))
+
+;;; Setting indentation
+(defun put-clojure-indent (sym indent)
+  "Instruct `clojure-indent-function' to indent the body of SYM by INDENT."
+  (put sym 'clojure-indent-function indent))
+
+(defmacro define-clojure-indent (&rest kvs)
+  "Call `put-clojure-indent' on a series, KVS."
+  `(progn
+     ,@(mapcar (lambda (x) `(put-clojure-indent
+                             (quote ,(car x)) ,(cadr x)))
+               kvs)))
+
+(defun add-custom-clojure-indents (name value)
+  "Allow `clojure-defun-indents' to indent user-specified macros.
+
+Requires the macro's NAME and a VALUE."
+  (custom-set-default name value)
+  (mapcar (lambda (x)
+            (put-clojure-indent x 'defun))
+          value))
+
+(defcustom clojure-defun-indents nil
+  "List of additional symbols with defun-style indentation in Clojure.
+
+You can use this to let Emacs indent your own macros the same way
+that it indents built-in macros like with-open.  This variable
+only works when set via the customize interface (`setq' won't
+work).  To set it from Lisp code, use
+     (put-clojure-indent \\='some-symbol :defn)."
+  :type '(repeat symbol)
+  :set 'add-custom-clojure-indents)
+
+(define-clojure-indent
+  ;; built-ins
+  (ns 1)
+  (fn :defn)
+  (def :defn)
+  (defn :defn)
+  (bound-fn :defn)
+  (if 1)
+  (if-not 1)
+  (case 1)
+  (cond 0)
+  (condp 2)
+  (cond-> 1)
+  (cond->> 1)
+  (when 1)
+  (while 1)
+  (when-not 1)
+  (when-first 1)
+  (do 0)
+  (future 0)
+  (comment 0)
+  (doto 1)
+  (locking 1)
+  (proxy '(2 nil nil (:defn)))
+  (as-> 2)
+  (fdef 1)
+
+  (reify '(:defn (1)))
+  (deftype '(2 nil nil (:defn)))
+  (defrecord '(2 nil nil (:defn)))
+  (defprotocol '(1 (:defn)))
+  (definterface '(1 (:defn)))
+  (extend 1)
+  (extend-protocol '(1 :defn))
+  (extend-type '(1 :defn))
+  ;; specify and specify! are from ClojureScript
+  (specify '(1 :defn))
+  (specify! '(1 :defn))
+  (try 0)
+  (catch 2)
+  (finally 0)
+
+  ;; binding forms
+  (let 1)
+  (letfn '(1 ((:defn)) nil))
+  (binding 1)
+  (loop 1)
+  (for 1)
+  (doseq 1)
+  (dotimes 1)
+  (when-let 1)
+  (if-let 1)
+  (when-some 1)
+  (if-some 1)
+  (this-as 1) ; ClojureScript
+
+  (defmethod :defn)
+
+  ;; clojure.test
+  (testing 1)
+  (deftest :defn)
+  (are 2)
+  (use-fixtures :defn)
+
+  ;; core.logic
+  (run :defn)
+  (run* :defn)
+  (fresh :defn)
+
+  ;; core.async
+  (alt! 0)
+  (alt!! 0)
+  (go 0)
+  (go-loop 1)
+  (thread 0))
+
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Better docstring filling for clojure-mode
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun clojure-string-start (&optional regex)
+  "Return the position of the \" that begins the string at point.
+If REGEX is non-nil, return the position of the # that begins the
+regex at point.  If point is not inside a string or regex, return
+nil."
+  (when (nth 3 (syntax-ppss)) ;; Are we really in a string?
+    (save-excursion
+      (save-match-data
+        ;; Find a quote that appears immediately after whitespace,
+        ;; beginning of line, hash, or an open paren, brace, or bracket
+        (re-search-backward "\\(\\s-\\|^\\|#\\|(\\|\\[\\|{\\)\\(\"\\)")
+        (let ((beg (match-beginning 2)))
+          (when beg
+            (if regex
+                (and (char-before beg) (eq ?# (char-before beg)) (1- beg))
+              (when (not (eq ?# (char-before beg)))
+                beg))))))))
+
+(defun clojure-char-at-point ()
+  "Return the char at point or nil if at buffer end."
+  (when (not (= (point) (point-max)))
+    (buffer-substring-no-properties (point) (1+ (point)))))
+
+(defun clojure-char-before-point ()
+  "Return the char before point or nil if at buffer beginning."
+  (when (not (= (point) (point-min)))
+    (buffer-substring-no-properties (point) (1- (point)))))
+
+(defun clojure-toggle-keyword-string ()
+  "Convert the string or keyword at point to keyword or string."
+  (interactive)
+  (let ((original-point (point)))
+    (while (and (> (point) 1)
+                (not (equal "\"" (buffer-substring-no-properties (point) (+ 1 (point)))))
+                (not (equal ":" (buffer-substring-no-properties (point) (+ 1 (point))))))
+      (backward-char))
+    (cond
+     ((equal 1 (point))
+      (error "Beginning of file reached, this was probably a mistake"))
+     ((equal "\"" (buffer-substring-no-properties (point) (+ 1 (point))))
+      (insert ":" (substring (clojure-delete-and-extract-sexp) 1 -1)))
+     ((equal ":" (buffer-substring-no-properties (point) (+ 1 (point))))
+      (insert "\"" (substring (clojure-delete-and-extract-sexp) 1) "\"")))
+    (goto-char original-point)))
+
+(defun clojure-delete-and-extract-sexp ()
+  "Delete the surrounding sexp and return it."
+  (let ((begin (point)))
+    (forward-sexp)
+    (let ((result (buffer-substring begin (point))))
+      (delete-region begin (point))
+      result)))
+
+
+
+(defcustom clojure-cache-project-dir t
+  "Whether to cache the results of `clojure-project-dir'."
+  :type 'boolean
+  :safe #'booleanp
+  :package-version '(clojure-mode . "5.8.0"))
+
+(defvar-local clojure-cached-project-dir nil
+  "A project dir cache used to speed up related operations.")
+
+(defun clojure-project-dir (&optional dir-name)
+  "Return the absolute path to the project's root directory.
+
+Call is delegated down to `clojure-project-root-function' with
+optional DIR-NAME as argument.
+
+When `clojure-cache-project-dir' is t the results of the command
+are cached in a buffer local variable (`clojure-cached-project-dir')."
+  (let ((project-dir (or clojure-cached-project-dir
+                         (funcall clojure-project-root-function dir-name))))
+    (when (and clojure-cache-project-dir
+               (derived-mode-p 'clojure-mode)
+               (not clojure-cached-project-dir))
+      (setq clojure-cached-project-dir project-dir))
+    project-dir))
+
+(defun clojure-current-project (&optional dir-name)
+  "Return the current project as a cons cell usable by project.el.
+
+Call is delegated down to `clojure-clojure-dir' with
+optional DIR-NAME as argument."
+  (let ((project-dir (clojure-project-dir dir-name)))
+    (if project-dir
+        (cons 'clojure project-dir)
+      nil)))
+
+(defun clojure-project-root-path (&optional dir-name)
+  "Return the absolute path to the project's root directory.
+
+Use `default-directory' if DIR-NAME is nil.
+Return nil if not inside a project."
+  (let* ((dir-name (or dir-name default-directory))
+         (choices (delq nil
+                        (mapcar (lambda (fname)
+                                  (locate-dominating-file dir-name fname))
+                                clojure-build-tool-files))))
+    (when (> (length choices) 0)
+      (car (sort choices #'file-in-directory-p)))))
+
+(defun clojure-project-relative-path (path)
+  "Denormalize PATH by making it relative to the project root."
+  (file-relative-name path (clojure-project-dir)))
+
+
+;;; ns manipulation
+(defun clojure-expected-ns (&optional path)
+  "Return the namespace matching PATH.
+
+PATH is expected to be an absolute file path.
+
+If PATH is nil, use the path to the file backing the current buffer."
+  (let* ((path (or path (file-truename (buffer-file-name))))
+         (relative (clojure-project-relative-path path))
+         (sans-file-type (substring relative 0 (- (length (file-name-extension path t)))))
+         (sans-file-sep (mapconcat 'identity (cdr (split-string sans-file-type "/")) "."))
+         (sans-underscores (replace-regexp-in-string "_" "-" sans-file-sep)))
+    ;; Drop prefix from ns for projects with structure src/{clj,cljs,cljc}
+    (replace-regexp-in-string "\\`clj[scx]?\\." "" sans-underscores)))
+
+(defun clojure-insert-ns-form-at-point ()
+  "Insert a namespace form at point."
+  (interactive)
+  (insert (format "(ns %s)" (funcall clojure-expected-ns-function))))
+
+(defun clojure-insert-ns-form ()
+  "Insert a namespace form at the beginning of the buffer."
+  (interactive)
+  (widen)
+  (goto-char (point-min))
+  (clojure-insert-ns-form-at-point))
+
+(defun clojure-update-ns ()
+  "Update the namespace of the current buffer.
+Useful if a file has been renamed."
+  (interactive)
+  (let ((nsname (funcall clojure-expected-ns-function)))
+    (when nsname
+      (save-excursion
+        (save-match-data
+          (if (clojure-find-ns)
+              (progn
+                (replace-match nsname nil nil nil 4)
+                (message "ns form updated to `%s'" nsname)
+                (setq clojure-cached-ns nsname))
+            (error "Namespace not found")))))))
+
+(defun clojure--sort-following-sexps ()
+  "Sort sexps between point and end of current sexp.
+Comments at the start of a line are considered part of the
+following sexp.  Comments at the end of a line (after some other
+content) are considered part of the preceding sexp."
+  ;; Here we're after the :require/:import symbol.
+  (save-restriction
+    (narrow-to-region (point) (save-excursion
+                                (up-list)
+                                (1- (point))))
+    (skip-chars-forward "\r\n[:blank:]")
+    (sort-subr nil
+               (lambda () (skip-chars-forward "\r\n[:blank:]"))
+               ;; Move to end of current top-level thing.
+               (lambda ()
+                 (condition-case nil
+                     (while t (up-list))
+                   (scan-error nil))
+                 ;; We could be inside a symbol instead of a sexp.
+                 (unless (looking-at "\\s-\\|$")
+                   (clojure-forward-logical-sexp))
+                 ;; move past comments at the end of the line.
+                 (search-forward-regexp "$"))
+               ;; Move to start of ns name.
+               (lambda ()
+                 (comment-forward)
+                 (skip-chars-forward "[:blank:]\n\r[(")
+                 (clojure-forward-logical-sexp)
+                 (forward-sexp -1)
+                 nil)
+               ;; Move to end of ns name.
+               (lambda ()
+                 (clojure-forward-logical-sexp)))
+    (goto-char (point-max))
+    ;; Does the last line now end in a comment?
+    (when (nth 4 (parse-partial-sexp (point-min) (point)))
+      (insert "\n"))))
+
+(defun clojure-sort-ns ()
+  "Internally sort each sexp inside the ns form."
+  (interactive)
+  (comment-normalize-vars)
+  (if (clojure-find-ns)
+      (save-excursion
+        (goto-char (match-beginning 0))
+        (redisplay)
+        (let ((beg (point))
+              (ns))
+          (forward-sexp 1)
+          (setq ns (buffer-substring beg (point)))
+          (forward-char -1)
+          (while (progn (forward-sexp -1)
+                        (looking-at "(:[a-z]"))
+            (save-excursion
+              (forward-char 1)
+              (forward-sexp 1)
+              (clojure--sort-following-sexps)))
+          (goto-char beg)
+          (if (looking-at (regexp-quote ns))
+              (message "ns form is already sorted")
+            (sleep-for 0.1)
+            (redisplay)
+            (message "ns form has been sorted")
+            (sleep-for 0.1))))
+    (user-error "Namespace not found")))
+
+(defconst clojure-namespace-name-regex
+  (rx line-start
+      "("
+      (zero-or-one (group (regexp "clojure.core/")))
+      (zero-or-one (submatch "in-"))
+      "ns"
+      (zero-or-one "+")
+      (one-or-more (any whitespace "\n"))
+      (zero-or-more (or (submatch (zero-or-one "#")
+                                  "^{"
+                                  (zero-or-more (not (any "}")))
+                                  "}")
+                        (zero-or-more "^:"
+                                      (one-or-more (not (any whitespace)))))
+                    (one-or-more (any whitespace "\n")))
+      (zero-or-one (any ":'")) ;; (in-ns 'foo) or (ns+ :user)
+      (group (one-or-more (not (any "()\"" whitespace))) symbol-end)))
+
+(defcustom clojure-cache-ns t
+  "Whether to cache the results of `clojure-find-ns'.
+
+Note that this won't work well in buffers with multiple namespace
+declarations (which rarely occur in practice) and you'll
+have to invalidate this manually after changing the ns for
+a buffer."
+  :type 'boolean
+  :safe #'booleanp
+  :package-version '(clojure-mode . "5.8.0"))
+
+(defvar-local clojure-cached-ns nil
+  "A buffer ns cache used to speed up ns-related operations.")
+
+(defun clojure-find-ns ()
+  "Return the namespace of the current Clojure buffer.
+Return the namespace closest to point and above it.  If there are
+no namespaces above point, return the first one in the buffer.
+
+The results will be cached if `clojure-cache-ns' is set to t."
+  (if (and clojure-cache-ns clojure-cached-ns)
+      clojure-cached-ns
+    (let ((ns (save-excursion
+                (save-restriction
+                  (widen)
+
+                  ;; Move to top-level to avoid searching from inside ns
+                  (ignore-errors (while t (up-list nil t t)))
+
+                  ;; The closest ns form above point.
+                  (when (or (re-search-backward clojure-namespace-name-regex nil t)
+                            ;; Or any form at all.
+                            (and (goto-char (point-min))
+                                 (re-search-forward clojure-namespace-name-regex nil t)))
+                    (match-string-no-properties 4))))))
+      (setq clojure-cached-ns ns)
+      ns)))
+
+(defun clojure-show-cache ()
+  "Display cached values if present.
+Useful for debugging."
+  (interactive)
+  (message "Cached Project: %s, Cached Namespace: %s" clojure-cached-project-dir clojure-cached-ns))
+
+(defun clojure-clear-cache ()
+  "Clear all buffer-local cached values.
+
+Normally you'd need to do this very infrequently - e.g.
+after renaming the root folder of project or after
+renaming a namespace."
+  (interactive)
+  (setq clojure-cached-project-dir nil
+        clojure-cached-ns nil)
+  (message "Buffer-local clojure-mode cache cleared"))
+
+(defconst clojure-def-type-and-name-regex
+  (concat "(\\(?:\\(?:\\sw\\|\\s_\\)+/\\)?"
+          ;; Declaration
+          "\\(def\\(?:\\sw\\|\\s_\\)*\\)\\>"
+          ;; Any whitespace
+          "[ \r\n\t]*"
+          ;; Possibly type or metadata
+          "\\(?:#?^\\(?:{[^}]*}\\|\\(?:\\sw\\|\\s_\\)+\\)[ \r\n\t]*\\)*"
+          ;; Symbol name
+          "\\(\\(?:\\sw\\|\\s_\\)+\\)"))
+
+(defun clojure-find-def ()
+  "Find the var declaration macro and symbol name of the current form.
+Returns a list pair, e.g. (\"defn\" \"abc\") or (\"deftest\" \"some-test\")."
+  (save-excursion
+    (unless (looking-at clojure-def-type-and-name-regex)
+      (beginning-of-defun))
+    (when (search-forward-regexp clojure-def-type-and-name-regex nil t)
+      (list (match-string-no-properties 1)
+            (match-string-no-properties 2)))))
+
+
+;;; Sexp navigation
+(defun clojure--looking-at-non-logical-sexp ()
+  "Return non-nil if text after point is \"non-logical\" sexp.
+\"Non-logical\" sexp are ^metadata and #reader.macros."
+  (comment-normalize-vars)
+  (comment-forward (point-max))
+  (looking-at-p "\\^\\|#[[:alpha:]]"))
+
+(defun clojure-forward-logical-sexp (&optional n)
+  "Move forward N logical sexps.
+This will skip over sexps that don't represent objects, so that ^hints and
+#reader.macros are considered part of the following sexp."
+  (interactive "p")
+  (unless n (setq n 1))
+  (if (< n 0)
+      (clojure-backward-logical-sexp (- n))
+    (let ((forward-sexp-function nil))
+      (while (> n 0)
+        (while (clojure--looking-at-non-logical-sexp)
+          (forward-sexp 1))
+        ;; The actual sexp
+        (forward-sexp 1)
+        (skip-chars-forward ",")
+        (setq n (1- n))))))
+
+(defun clojure-backward-logical-sexp (&optional n)
+  "Move backward N logical sexps.
+This will skip over sexps that don't represent objects, so that ^hints and
+#reader.macros are considered part of the following sexp."
+  (interactive "p")
+  (unless n (setq n 1))
+  (if (< n 0)
+      (clojure-forward-logical-sexp (- n))
+    (let ((forward-sexp-function nil))
+      (while (> n 0)
+        ;; The actual sexp
+        (backward-sexp 1)
+        ;; Non-logical sexps.
+        (while (and (not (bobp))
+                    (ignore-errors
+                      (save-excursion
+                        (backward-sexp 1)
+                        (clojure--looking-at-non-logical-sexp))))
+          (backward-sexp 1))
+        (setq n (1- n))))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Refactoring support
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;;; Threading macros related
+(defcustom clojure-thread-all-but-last nil
+  "Non-nil means do not thread the last expression.
+This means that `clojure-thread-first-all' and
+`clojure-thread-last-all' not thread the deepest sexp inside the
+current sexp."
+  :package-version '(clojure-mode . "5.4.0")
+  :safe #'booleanp
+  :type 'boolean)
+
+(defun clojure--point-after (&rest actions)
+  "Return POINT after performing ACTIONS.
+
+An action is either the symbol of a function or a two element
+list of (fn args) to pass to `apply''"
+  (save-excursion
+    (dolist (fn-and-args actions)
+      (let ((f (if (listp fn-and-args) (car fn-and-args) fn-and-args))
+            (args (if (listp fn-and-args) (cdr fn-and-args) nil)))
+        (apply f args)))
+    (point)))
+
+(defun clojure--maybe-unjoin-line ()
+  "Undo a `join-line' done by a threading command."
+  (when (get-text-property (point) 'clojure-thread-line-joined)
+    (remove-text-properties (point) (1+ (point)) '(clojure-thread-line-joined t))
+    (insert "\n")))
+
+(defun clojure--unwind-last ()
+  "Unwind a thread last macro once.
+
+Point must be between the opening paren and the ->> symbol."
+  (forward-sexp)
+  (save-excursion
+    (let ((beg (point))
+          (contents (clojure-delete-and-extract-sexp)))
+      (when (looking-at " *\n")
+        (join-line 'following))
+      (clojure--ensure-parens-around-function-names)
+      (let* ((sexp-beg-line (line-number-at-pos))
+             (sexp-end-line (progn (forward-sexp)
+                                   (line-number-at-pos)))
+             (multiline-sexp-p (not (= sexp-beg-line sexp-end-line))))
+        (down-list -1)
+        (if multiline-sexp-p
+            (insert "\n")
+          ;; `clojure--maybe-unjoin-line' only works when unwinding sexps that were
+          ;; threaded in the same Emacs session, but it also catches cases that
+          ;; `multiline-sexp-p' doesn't.
+          (clojure--maybe-unjoin-line))
+        (insert contents))))
+  (forward-char))
+
+(defun clojure--ensure-parens-around-function-names ()
+  "Insert parens around function names if necessary."
+  (clojure--looking-at-non-logical-sexp)
+  (unless (looking-at "(")
+    (insert-parentheses 1)
+    (backward-up-list)))
+
+(defun clojure--unwind-first ()
+  "Unwind a thread first macro once.
+
+Point must be between the opening paren and the -> symbol."
+  (forward-sexp)
+  (save-excursion
+    (let ((contents (clojure-delete-and-extract-sexp)))
+      (when (looking-at " *\n")
+        (join-line 'following))
+      (clojure--ensure-parens-around-function-names)
+      (down-list)
+      (forward-sexp)
+      (insert contents)
+      (forward-sexp -1)
+      (clojure--maybe-unjoin-line)))
+  (forward-char))
+
+(defun clojure--pop-out-of-threading ()
+  "Raise a sexp up a level to unwind a threading form."
+  (save-excursion
+    (down-list 2)
+    (backward-up-list)
+    (raise-sexp)))
+
+(defun clojure--nothing-more-to-unwind ()
+  "Return non-nil if a threaded form cannot be unwound further."
+  (save-excursion
+    (let ((beg (point)))
+      (forward-sexp)
+      (down-list -1)
+      (backward-sexp 2) ;; the last sexp, the threading macro
+      (when (looking-back "(\\s-*" (line-beginning-position))
+        (backward-up-list)) ;; and the paren
+      (= beg (point)))))
+
+(defun clojure--fix-sexp-whitespace (&optional move-out)
+  "Fix whitespace after unwinding a threading form.
+
+Optional argument MOVE-OUT, if non-nil, means moves up a list
+before fixing whitespace."
+  (save-excursion
+    (when move-out (backward-up-list))
+    (let ((sexp (bounds-of-thing-at-point 'sexp)))
+      (clojure-indent-region (car sexp) (cdr sexp))
+      (delete-trailing-whitespace (car sexp) (cdr sexp)))))
+
+;;;###autoload
+(defun clojure-unwind ()
+  "Unwind thread at point or above point by one level.
+Return nil if there are no more levels to unwind."
+  (interactive)
+  (save-excursion
+    (let ((limit (save-excursion
+                   (beginning-of-defun)
+                   (point))))
+      (ignore-errors
+        (when (looking-at "(")
+          (forward-char 1)
+          (forward-sexp 1)))
+      (search-backward-regexp "([^-]*->" limit)
+      (if (clojure--nothing-more-to-unwind)
+          (progn (clojure--pop-out-of-threading)
+                 (clojure--fix-sexp-whitespace)
+                 nil)
+        (down-list)
+        (prog1 (cond
+                ((looking-at "[^-]*->\\_>")  (clojure--unwind-first))
+                ((looking-at "[^-]*->>\\_>") (clojure--unwind-last)))
+          (clojure--fix-sexp-whitespace 'move-out))
+        t))))
+
+;;;###autoload
+(defun clojure-unwind-all ()
+  "Fully unwind thread at point or above point."
+  (interactive)
+  (while (clojure-unwind)))
+
+(defun clojure--remove-superfluous-parens ()
+  "Remove extra parens from a form."
+  (when (looking-at "([^ )]+)")
+    (delete-pair)))
+
+(defun clojure--thread-first ()
+  "Thread a nested sexp using ->."
+  (down-list)
+  (forward-symbol 1)
+  (unless (looking-at ")")
+    (let ((contents (clojure-delete-and-extract-sexp)))
+      (backward-up-list)
+      (just-one-space 0)
+      (save-excursion
+        (insert contents "\n")
+        (clojure--remove-superfluous-parens))
+      (when (looking-at "\\s-*\n")
+        (join-line 'following)
+        (forward-char 1)
+        (put-text-property (point) (1+ (point))
+                           'clojure-thread-line-joined t))
+      t)))
+
+(defun clojure--thread-last ()
+  "Thread a nested sexp using ->>."
+  (forward-sexp 2)
+  (down-list -1)
+  (backward-sexp)
+  (unless (eq (char-before) ?\()
+    (let ((contents (clojure-delete-and-extract-sexp)))
+      (just-one-space 0)
+      (backward-up-list)
+      (insert contents "\n")
+      (clojure--remove-superfluous-parens)
+      ;; cljr #255 Fix dangling parens
+      (forward-sexp)
+      (when (looking-back "^\\s-*\\()+\\)\\s-*" (line-beginning-position))
+        (let ((pos (match-beginning 1)))
+          (put-text-property pos (1+ pos) 'clojure-thread-line-joined t))
+        (join-line))
+      t)))
+
+(defun clojure--threadable-p ()
+  "Return non-nil if a form can be threaded."
+  (save-excursion
+    (forward-symbol 1)
+    (looking-at "[\n\r\t ]*(")))
+
+;;;###autoload
+(defun clojure-thread ()
+  "Thread by one more level an existing threading macro."
+  (interactive)
+  (ignore-errors
+    (when (looking-at "(")
+      (forward-char 1)
+      (forward-sexp 1)))
+  (search-backward-regexp "([^-]*->")
+  (down-list)
+  (when (clojure--threadable-p)
+    (prog1 (cond
+            ((looking-at "[^-]*->\\_>")  (clojure--thread-first))
+            ((looking-at "[^-]*->>\\_>") (clojure--thread-last)))
+      (clojure--fix-sexp-whitespace 'move-out))))
+
+(defun clojure--thread-all (first-or-last-thread but-last)
+  "Fully thread the form at point.
+
+FIRST-OR-LAST-THREAD is \"->\" or \"->>\".
+
+When BUT-LAST is non-nil, the last expression is not threaded.
+Default value is `clojure-thread-all-but-last'."
+  (save-excursion
+    (insert-parentheses 1)
+    (insert first-or-last-thread))
+  (while (save-excursion (clojure-thread)))
+  (when (or but-last clojure-thread-all-but-last)
+    (clojure-unwind)))
+
+;;;###autoload
+(defun clojure-thread-first-all (but-last)
+  "Fully thread the form at point using ->.
+
+When BUT-LAST is non-nil, the last expression is not threaded.
+Default value is `clojure-thread-all-but-last'."
+  (interactive "P")
+  (clojure--thread-all "-> " but-last))
+
+;;;###autoload
+(defun clojure-thread-last-all (but-last)
+  "Fully thread the form at point using ->>.
+
+When BUT-LAST is non-nil, the last expression is not threaded.
+Default value is `clojure-thread-all-but-last'."
+  (interactive "P")
+  (clojure--thread-all "->> " but-last))
+
+;;; Cycling stuff
+
+(defcustom clojure-use-metadata-for-privacy nil
+  "If nil, `clojure-cycle-privacy' will use (defn- f []).
+If t, it will use (defn ^:private f [])."
+  :package-version '(clojure-mode . "5.5.0")
+  :safe #'booleanp
+  :type 'boolean)
+
+;;;###autoload
+(defun clojure-cycle-privacy ()
+  "Make public the current private def, or vice-versa.
+See: https://github.com/clojure-emacs/clj-refactor.el/wiki/cljr-cycle-privacy"
+  (interactive)
+  (save-excursion
+    (ignore-errors (forward-char 7))
+    (search-backward-regexp "(defn?\\(-\\| ^:private\\)?\\_>")
+    (if (match-string 1)
+        (replace-match "" nil nil nil 1)
+      (goto-char (match-end 0))
+      (insert (if (or clojure-use-metadata-for-privacy
+                      (equal (match-string 0) "(def"))
+                  " ^:private"
+                "-")))))
+
+(defun clojure--convert-collection (coll-open coll-close)
+  "Convert the collection at (point) by unwrapping it an wrapping it between COLL-OPEN and COLL-CLOSE."
+  (save-excursion
+    (while (and
+            (not (bobp))
+            (not (looking-at "(\\|{\\|\\[")))
+      (backward-char))
+    (when (or (eq ?\# (char-before))
+              (eq ?\' (char-before)))
+      (delete-char -1))
+    (when (and (bobp)
+               (not (memq (char-after) '(?\{ ?\( ?\[))))
+      (user-error "Beginning of file reached, collection is not found"))
+    (insert coll-open (substring (clojure-delete-and-extract-sexp) 1 -1) coll-close)))
+
+;;;###autoload
+(defun clojure-convert-collection-to-list ()
+  "Convert collection at (point) to list."
+  (interactive)
+  (clojure--convert-collection "(" ")"))
+
+;;;###autoload
+(defun clojure-convert-collection-to-quoted-list ()
+  "Convert collection at (point) to quoted list."
+  (interactive)
+  (clojure--convert-collection "'(" ")"))
+
+;;;###autoload
+(defun clojure-convert-collection-to-map ()
+  "Convert collection at (point) to map."
+  (interactive)
+  (clojure--convert-collection "{" "}"))
+
+;;;###autoload
+(defun clojure-convert-collection-to-vector ()
+  "Convert collection at (point) to vector."
+  (interactive)
+  (clojure--convert-collection "[" "]"))
+
+;;;###autoload
+(defun clojure-convert-collection-to-set ()
+  "Convert collection at (point) to set."
+  (interactive)
+  (clojure--convert-collection "#{" "}"))
+
+(defun clojure--in-string-p ()
+  "Check whether the point is currently in a string."
+  (nth 3 (syntax-ppss)))
+
+(defun clojure--goto-if ()
+  "Find the first surrounding if or if-not expression."
+  (when (clojure--in-string-p)
+    (while (or (not (looking-at "("))
+               (clojure--in-string-p))
+      (backward-char)))
+  (while (not (looking-at "\\((if \\)\\|\\((if-not \\)"))
+    (condition-case nil
+        (backward-up-list)
+      (scan-error (user-error "No if or if-not found")))))
+
+;;;###autoload
+(defun clojure-cycle-if ()
+  "Change a surrounding if to if-not, or vice-versa.
+
+See: https://github.com/clojure-emacs/clj-refactor.el/wiki/cljr-cycle-if"
+  (interactive)
+  (save-excursion
+    (clojure--goto-if)
+    (cond
+     ((looking-at "(if-not")
+      (forward-char 3)
+      (delete-char 4)
+      (forward-sexp 2)
+      (transpose-sexps 1))
+     ((looking-at "(if")
+      (forward-char 3)
+      (insert "-not")
+      (forward-sexp 2)
+      (transpose-sexps 1)))))
+
+;; TODO: Remove code duplication with `clojure--goto-if'.
+(defun clojure--goto-when ()
+  "Find the first surrounding when or when-not expression."
+  (when (clojure--in-string-p)
+    (while (or (not (looking-at "("))
+               (clojure--in-string-p))
+      (backward-char)))
+  (while (not (looking-at "\\((when \\)\\|\\((when-not \\)"))
+    (condition-case nil
+        (backward-up-list)
+      (scan-error (user-error "No when or when-not found")))))
+
+;;;###autoload
+(defun clojure-cycle-when ()
+  "Change a surrounding when to when-not, or vice-versa."
+  (interactive)
+  (save-excursion
+    (clojure--goto-when)
+    (cond
+     ((looking-at "(when-not")
+      (forward-char 9)
+      (delete-char -4))
+     ((looking-at "(when")
+      (forward-char 5)
+      (insert "-not")))))
+
+(defun clojure-cycle-not ()
+  "Add or remove a not form around the current form."
+  (interactive)
+  (save-excursion
+    (condition-case nil
+        (backward-up-list)
+      (scan-error (user-error "`clojure-cycle-not' must be invoked inside a list")))
+    (if (looking-back "(not ")
+        (progn
+          (delete-char -5)
+          (forward-sexp)
+          (delete-char 1))
+      (insert "(not ")
+      (forward-sexp)
+      (insert ")"))))
+
+;;; let related stuff
+
+(defvar clojure--let-regexp
+  "\(\\(when-let\\|if-let\\|let\\)\\(\\s-*\\|\\[\\)"
+  "Regexp matching let like expressions, i.e. \"let\", \"when-let\", \"if-let\".
+
+The first match-group is the let expression.
+
+The second match-group is the whitespace or the opening square
+bracket if no whitespace between the let expression and the
+bracket.")
+
+(defun clojure--goto-let ()
+  "Go to the beginning of the nearest let form."
+  (when (clojure--in-string-p)
+    (while (or (not (looking-at "("))
+               (clojure--in-string-p))
+      (backward-char)))
+  (ignore-errors
+    (while (not (looking-at clojure--let-regexp))
+      (backward-up-list)))
+  (looking-at clojure--let-regexp))
+
+(defun clojure--inside-let-binding-p ()
+  "Return non-nil if point is inside a let binding."
+  (ignore-errors
+    (save-excursion
+      (let ((pos (point)))
+        (clojure--goto-let)
+        (re-search-forward "\\[")
+        (if (< pos (point))
+            nil
+          (forward-sexp)
+          (up-list)
+          (< pos (point)))))))
+
+(defun clojure--beginning-of-current-let-binding ()
+  "Move before the bound name of the current binding.
+Assume that point is in the binding form of a let."
+  (let ((current-point (point)))
+    (clojure--goto-let)
+    (search-forward "[")
+    (forward-char)
+    (while (> current-point (point))
+      (forward-sexp))
+    (backward-sexp 2)))
+
+(defun clojure--previous-line ()
+  "Keep the column position while go the previous line."
+  (let ((col (current-column)))
+    (forward-line -1)
+    (move-to-column col)))
+
+(defun clojure--prepare-to-insert-new-let-binding ()
+  "Move to right place in the let form to insert a new binding and indent."
+  (if (clojure--inside-let-binding-p)
+      (progn
+        (clojure--beginning-of-current-let-binding)
+        (newline-and-indent)
+        (clojure--previous-line)
+        (indent-for-tab-command))
+    (clojure--goto-let)
+    (search-forward "[")
+    (backward-up-list)
+    (forward-sexp)
+    (down-list -1)
+    (backward-char)
+    (if (looking-at "\\[\\s-*\\]")
+        (forward-char)
+      (forward-char)
+      (newline-and-indent))))
+
+(defun clojure--sexp-regexp (sexp)
+  "Return a regexp for matching SEXP."
+  (concat "\\([^[:word:]^-]\\)"
+          (mapconcat #'identity (mapcar 'regexp-quote (split-string sexp))
+                     "[[:space:]\n\r]+")
+          "\\([^[:word:]^-]\\)"))
+
+(defun clojure--replace-sexp-with-binding (bound-name init-expr)
+  "Replace a binding with its bound name in the let form.
+
+BOUND-NAME is the name (left-hand side) of a binding.
+
+INIT-EXPR is the value (right-hand side) of a binding."
+  (save-excursion
+    (while (re-search-forward
+            (clojure--sexp-regexp init-expr)
+            (clojure--point-after 'clojure--goto-let 'forward-sexp)
+            t)
+      (replace-match (concat "\\1" bound-name "\\2")))))
+
+(defun clojure--replace-sexps-with-bindings (bindings)
+  "Replace bindings with their respective bound names in the let form.
+
+BINDINGS is the list of bound names and init expressions."
+  (let ((bound-name (pop bindings))
+        (init-expr (pop bindings)))
+    (when bound-name
+      (clojure--replace-sexp-with-binding bound-name init-expr)
+      (clojure--replace-sexps-with-bindings bindings))))
+
+(defun clojure--replace-sexps-with-bindings-and-indent ()
+  "Replace sexps with bindings."
+  (clojure--replace-sexps-with-bindings
+   (clojure--read-let-bindings))
+  (clojure-indent-region
+   (clojure--point-after 'clojure--goto-let)
+   (clojure--point-after 'clojure--goto-let 'forward-sexp)))
+
+(defun clojure--read-let-bindings ()
+  "Read the bound-name and init expression pairs in the binding form.
+Return a list: odd elements are bound names, even elements init expressions."
+  (clojure--goto-let)
+  (down-list 2)
+  (let* ((start (point))
+         (sexp-start start)
+         (end (save-excursion
+                (backward-char)
+                (forward-sexp)
+                (down-list -1)
+                (point)))
+         bindings)
+    (while (/= sexp-start end)
+      (forward-sexp)
+      (push
+       (string-trim (buffer-substring-no-properties sexp-start (point)))
+       bindings)
+      (skip-chars-forward "\r\n\t[:blank:]")
+      (setq sexp-start (point)))
+    (nreverse bindings)))
+
+(defun clojure--introduce-let-internal (name &optional n)
+  "Create a let form, binding the form at point with NAME.
+
+Optional numeric argument N, if non-nil, introduces the let N
+lists up."
+  (if (numberp n)
+      (let ((init-expr-sexp (clojure-delete-and-extract-sexp)))
+        (insert name)
+        (ignore-errors (backward-up-list n))
+        (insert "(let" (clojure-delete-and-extract-sexp) ")")
+        (backward-sexp)
+        (down-list)
+        (forward-sexp)
+        (insert " [" name " " init-expr-sexp "]\n")
+        (clojure--replace-sexps-with-bindings-and-indent))
+    (insert "[ " (clojure-delete-and-extract-sexp) "]")
+    (backward-sexp)
+    (insert "(let " (clojure-delete-and-extract-sexp) ")")
+    (backward-sexp)
+    (down-list 2)
+    (insert name)
+    (forward-sexp)
+    (up-list)
+    (newline-and-indent)
+    (insert name)))
+
+(defun clojure--move-to-let-internal (name)
+  "Bind the form at point to NAME in the nearest let."
+  (if (not (save-excursion (clojure--goto-let)))
+      (clojure--introduce-let-internal name)
+    (let ((contents (clojure-delete-and-extract-sexp)))
+      (insert name)
+      (clojure--prepare-to-insert-new-let-binding)
+      (insert contents)
+      (backward-sexp)
+      (insert " ")
+      (backward-char)
+      (insert name)
+      (clojure--replace-sexps-with-bindings-and-indent))))
+
+(defun clojure--let-backward-slurp-sexp-internal ()
+  "Slurp the s-expression before the let form into the let form."
+  (clojure--goto-let)
+  (backward-sexp)
+  (let ((sexp (string-trim (clojure-delete-and-extract-sexp))))
+    (delete-blank-lines)
+    (down-list)
+    (forward-sexp 2)
+    (newline-and-indent)
+    (insert sexp)
+    (clojure--replace-sexps-with-bindings-and-indent)))
+
+;;;###autoload
+(defun clojure-let-backward-slurp-sexp (&optional n)
+  "Slurp the s-expression before the let form into the let form.
+With a numberic prefix argument slurp the previous N s-expression into the let form."
+  (interactive "p")
+  (unless n (setq n 1))
+  (dotimes (k n)
+    (save-excursion (clojure--let-backward-slurp-sexp-internal))))
+
+(defun clojure--let-forward-slurp-sexp-internal ()
+  "Slurp the next s-expression after the let form into the let form."
+  (clojure--goto-let)
+  (forward-sexp)
+  (let ((sexp (string-trim (clojure-delete-and-extract-sexp))))
+    (down-list -1)
+    (newline-and-indent)
+    (insert sexp)
+    (clojure--replace-sexps-with-bindings-and-indent)))
+
+;;;###autoload
+(defun clojure-let-forward-slurp-sexp (&optional n)
+  "Slurp the next s-expression after the let form into the let form.
+With a numeric prefix argument slurp the next N s-expressions into the let form."
+  (interactive "p")
+  (unless n (setq n 1))
+  (dotimes (k n)
+    (save-excursion (clojure--let-forward-slurp-sexp-internal))))
+
+;;;###autoload
+(defun clojure-introduce-let (&optional n)
+  "Create a let form, binding the form at point.
+With a numeric prefix argument the let is introduced N lists up."
+  (interactive "P")
+  (clojure--introduce-let-internal (read-from-minibuffer "Name of bound symbol: ") n))
+
+;;;###autoload
+(defun clojure-move-to-let ()
+  "Move the form at point to a binding in the nearest let."
+  (interactive)
+  (clojure--move-to-let-internal (read-from-minibuffer "Name of bound symbol: ")))
+
+
+;;; ClojureScript
+(defconst clojurescript-font-lock-keywords
+  (eval-when-compile
+    `(;; ClojureScript built-ins
+      (,(concat "(\\(?:\.*/\\)?"
+                (regexp-opt '("js-obj" "js-delete" "clj->js" "js->clj"))
+                "\\>")
+       0 font-lock-builtin-face)))
+  "Additional font-locking for `clojurescript-mode'.")
+
+;;;###autoload
+(define-derived-mode clojurescript-mode clojure-mode "ClojureScript"
+  "Major mode for editing ClojureScript code.
+
+\\{clojurescript-mode-map}"
+  (font-lock-add-keywords nil clojurescript-font-lock-keywords))
+
+;;;###autoload
+(define-derived-mode clojurec-mode clojure-mode "ClojureC"
+  "Major mode for editing ClojureC code.
+
+\\{clojurec-mode-map}")
+
+;;;###autoload
+(progn
+  (add-to-list 'auto-mode-alist
+               '("\\.\\(clj\\|dtm\\|edn\\)\\'" . clojure-mode))
+  (add-to-list 'auto-mode-alist '("\\.cljc\\'" . clojurec-mode))
+  (add-to-list 'auto-mode-alist '("\\.cljs\\'" . clojurescript-mode))
+  ;; boot build scripts are Clojure source files
+  (add-to-list 'auto-mode-alist '("\\(?:build\\|profile\\)\\.boot\\'" . clojure-mode)))
+
+(provide 'clojure-mode)
+
+;; Local Variables:
+;; coding: utf-8
+;; End:
+
+;;; clojure-mode.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/clojure-mode-20180709.648/clojure-mode.elc b/configs/shared/emacs/.emacs.d/elpa/clojure-mode-20180709.648/clojure-mode.elc
new file mode 100644
index 0000000000..0cc69ca8bc
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/clojure-mode-20180709.648/clojure-mode.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-abbrev.el b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-abbrev.el
new file mode 100644
index 0000000000..24ec3b775d
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-abbrev.el
@@ -0,0 +1,50 @@
+;;; company-abbrev.el --- company-mode completion backend for abbrev
+
+;; Copyright (C) 2009-2011, 2015  Free Software Foundation, Inc.
+
+;; Author: Nikolaj Schumacher
+
+;; 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:
+;;
+
+;;; Code:
+
+(require 'company)
+(require 'cl-lib)
+(require 'abbrev)
+
+(defun company-abbrev-insert (match)
+  "Replace MATCH with the expanded abbrev."
+  (expand-abbrev))
+
+;;;###autoload
+(defun company-abbrev (command &optional arg &rest ignored)
+  "`company-mode' completion backend for abbrev."
+  (interactive (list 'interactive))
+  (cl-case command
+    (interactive (company-begin-backend 'company-abbrev
+                                        'company-abbrev-insert))
+    (prefix (company-grab-symbol))
+    (candidates (nconc
+                 (delete "" (all-completions arg global-abbrev-table))
+                 (delete "" (all-completions arg local-abbrev-table))))
+    (meta (abbrev-expansion arg))))
+
+(provide 'company-abbrev)
+;;; company-abbrev.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-abbrev.elc b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-abbrev.elc
new file mode 100644
index 0000000000..ba5c2c5e33
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-abbrev.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-autoloads.el
new file mode 100644
index 0000000000..3e24df961f
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-autoloads.el
@@ -0,0 +1,318 @@
+;;; company-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "company" "company.el" (23377 61602 211961
+;;;;;;  604000))
+;;; Generated autoloads from company.el
+
+(autoload 'company-mode "company" "\
+\"complete anything\"; is an in-buffer completion framework.
+Completion starts automatically, depending on the values
+`company-idle-delay' and `company-minimum-prefix-length'.
+
+Completion can be controlled with the commands:
+`company-complete-common', `company-complete-selection', `company-complete',
+`company-select-next', `company-select-previous'.  If these commands are
+called before `company-idle-delay', completion will also start.
+
+Completions can be searched with `company-search-candidates' or
+`company-filter-candidates'.  These can be used while completion is
+inactive, as well.
+
+The completion data is retrieved using `company-backends' and displayed
+using `company-frontends'.  If you want to start a specific backend, call
+it interactively or use `company-begin-backend'.
+
+By default, the completions list is sorted alphabetically, unless the
+backend chooses otherwise, or `company-transformers' changes it later.
+
+regular keymap (`company-mode-map'):
+
+\\{company-mode-map}
+keymap during active completions (`company-active-map'):
+
+\\{company-active-map}
+
+\(fn &optional ARG)" t nil)
+
+(defvar global-company-mode nil "\
+Non-nil if Global Company mode is enabled.
+See the `global-company-mode' command
+for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `global-company-mode'.")
+
+(custom-autoload 'global-company-mode "company" nil)
+
+(autoload 'global-company-mode "company" "\
+Toggle Company mode in all buffers.
+With prefix ARG, enable Global Company mode if ARG is positive;
+otherwise, disable it.  If called from Lisp, enable the mode if
+ARG is omitted or nil.
+
+Company mode is enabled in all buffers where
+`company-mode-on' would do it.
+See `company-mode' for more information on Company mode.
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'company-manual-begin "company" "\
+
+
+\(fn)" t nil)
+
+(autoload 'company-complete "company" "\
+Insert the common part of all candidates or the current selection.
+The first time this is called, the common part is inserted, the second
+time, or when the selection has been changed, the selected candidate is
+inserted.
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "company-abbrev" "company-abbrev.el" (23377
+;;;;;;  61602 235079 386000))
+;;; Generated autoloads from company-abbrev.el
+
+(autoload 'company-abbrev "company-abbrev" "\
+`company-mode' completion backend for abbrev.
+
+\(fn COMMAND &optional ARG &rest IGNORED)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "company-bbdb" "company-bbdb.el" (23377 61602
+;;;;;;  227668 328000))
+;;; Generated autoloads from company-bbdb.el
+
+(autoload 'company-bbdb "company-bbdb" "\
+`company-mode' completion backend for BBDB.
+
+\(fn COMMAND &optional ARG &rest IGNORE)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "company-css" "company-css.el" (23377 61602
+;;;;;;  209371 443000))
+;;; Generated autoloads from company-css.el
+
+(autoload 'company-css "company-css" "\
+`company-mode' completion backend for `css-mode'.
+
+\(fn COMMAND &optional ARG &rest IGNORED)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "company-dabbrev" "company-dabbrev.el" (23377
+;;;;;;  61602 220002 239000))
+;;; Generated autoloads from company-dabbrev.el
+
+(autoload 'company-dabbrev "company-dabbrev" "\
+dabbrev-like `company-mode' completion backend.
+
+\(fn COMMAND &optional ARG &rest IGNORED)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "company-dabbrev-code" "company-dabbrev-code.el"
+;;;;;;  (23377 61602 217036 189000))
+;;; Generated autoloads from company-dabbrev-code.el
+
+(autoload 'company-dabbrev-code "company-dabbrev-code" "\
+dabbrev-like `company-mode' backend for code.
+The backend looks for all symbols in the current buffer that aren't in
+comments or strings.
+
+\(fn COMMAND &optional ARG &rest IGNORED)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "company-elisp" "company-elisp.el" (23377 61602
+;;;;;;  238059 315000))
+;;; Generated autoloads from company-elisp.el
+
+(autoload 'company-elisp "company-elisp" "\
+`company-mode' completion backend for Emacs Lisp.
+
+\(fn COMMAND &optional ARG &rest IGNORED)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "company-etags" "company-etags.el" (23377 61602
+;;;;;;  213968 214000))
+;;; Generated autoloads from company-etags.el
+
+(autoload 'company-etags "company-etags" "\
+`company-mode' completion backend for etags.
+
+\(fn COMMAND &optional ARG &rest IGNORED)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "company-files" "company-files.el" (23377 61602
+;;;;;;  221469 981000))
+;;; Generated autoloads from company-files.el
+
+(autoload 'company-files "company-files" "\
+`company-mode' completion backend existing file names.
+Completions works for proper absolute and relative files paths.
+File paths with spaces are only supported inside strings.
+
+\(fn COMMAND &optional ARG &rest IGNORED)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "company-gtags" "company-gtags.el" (23377 61602
+;;;;;;  197083 363000))
+;;; Generated autoloads from company-gtags.el
+
+(autoload 'company-gtags "company-gtags" "\
+`company-mode' completion backend for GNU Global.
+
+\(fn COMMAND &optional ARG &rest IGNORED)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "company-ispell" "company-ispell.el" (23377
+;;;;;;  61602 236603 303000))
+;;; Generated autoloads from company-ispell.el
+
+(autoload 'company-ispell "company-ispell" "\
+`company-mode' completion backend using Ispell.
+
+\(fn COMMAND &optional ARG &rest IGNORED)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "company-keywords" "company-keywords.el" (23377
+;;;;;;  61602 224410 815000))
+;;; Generated autoloads from company-keywords.el
+
+(autoload 'company-keywords "company-keywords" "\
+`company-mode' backend for programming language keywords.
+
+\(fn COMMAND &optional ARG &rest IGNORED)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "company-nxml" "company-nxml.el" (23377 61602
+;;;;;;  230673 993000))
+;;; Generated autoloads from company-nxml.el
+
+(autoload 'company-nxml "company-nxml" "\
+`company-mode' completion backend for `nxml-mode'.
+
+\(fn COMMAND &optional ARG &rest IGNORED)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "company-oddmuse" "company-oddmuse.el" (23377
+;;;;;;  61602 204423 216000))
+;;; Generated autoloads from company-oddmuse.el
+
+(autoload 'company-oddmuse "company-oddmuse" "\
+`company-mode' completion backend for `oddmuse-mode'.
+
+\(fn COMMAND &optional ARG &rest IGNORED)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "company-semantic" "company-semantic.el" (23377
+;;;;;;  61602 199549 495000))
+;;; Generated autoloads from company-semantic.el
+
+(autoload 'company-semantic "company-semantic" "\
+`company-mode' completion backend using CEDET Semantic.
+
+\(fn COMMAND &optional ARG &rest IGNORED)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "company-tempo" "company-tempo.el" (23377 61602
+;;;;;;  218510 976000))
+;;; Generated autoloads from company-tempo.el
+
+(autoload 'company-tempo "company-tempo" "\
+`company-mode' completion backend for tempo.
+
+\(fn COMMAND &optional ARG &rest IGNORED)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "company-tng" "company-tng.el" (23377 61602
+;;;;;;  229133 386000))
+;;; Generated autoloads from company-tng.el
+
+(autoload 'company-tng-frontend "company-tng" "\
+When the user changes the selection at least once, this
+frontend will display the candidate in the buffer as if it's
+already there and any key outside of `company-active-map' will
+confirm the selection and finish the completion.
+
+\(fn COMMAND)" nil nil)
+
+(autoload 'company-tng-configure-default "company-tng" "\
+Applies the default configuration to enable company-tng.
+
+\(fn)" nil nil)
+
+;;;***
+
+;;;### (autoloads nil "company-xcode" "company-xcode.el" (23377 61602
+;;;;;;  233639 935000))
+;;; Generated autoloads from company-xcode.el
+
+(autoload 'company-xcode "company-xcode" "\
+`company-mode' completion backend for Xcode projects.
+
+\(fn COMMAND &optional ARG &rest IGNORED)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "company-yasnippet" "company-yasnippet.el"
+;;;;;;  (23377 61602 232152 50000))
+;;; Generated autoloads from company-yasnippet.el
+
+(autoload 'company-yasnippet "company-yasnippet" "\
+`company-mode' backend for `yasnippet'.
+
+This backend should be used with care, because as long as there are
+snippets defined for the current major mode, this backend will always
+shadow backends that come after it.  Recommended usages:
+
+* In a buffer-local value of `company-backends', grouped with a backend or
+  several that provide actual text completions.
+
+  (add-hook 'js-mode-hook
+            (lambda ()
+              (set (make-local-variable 'company-backends)
+                   '((company-dabbrev-code company-yasnippet)))))
+
+* After keyword `:with', grouped with other backends.
+
+  (push '(company-semantic :with company-yasnippet) company-backends)
+
+* Not in `company-backends', just bound to a key.
+
+  (global-set-key (kbd \"C-c y\") 'company-yasnippet)
+
+\(fn COMMAND &optional ARG &rest IGNORE)" t nil)
+
+;;;***
+
+;;;### (autoloads nil nil ("company-capf.el" "company-clang.el" "company-cmake.el"
+;;;;;;  "company-eclim.el" "company-pkg.el" "company-template.el")
+;;;;;;  (23377 61602 226063 308000))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; company-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-bbdb.el b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-bbdb.el
new file mode 100644
index 0000000000..872e1fcf05
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-bbdb.el
@@ -0,0 +1,61 @@
+;;; company-bbdb.el --- company-mode completion backend for BBDB in message-mode
+
+;; Copyright (C) 2013-2014, 2016  Free Software Foundation, Inc.
+
+;; Author: Jan Tatarik <jan.tatarik@gmail.com>
+
+;; 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/>.
+
+(require 'company)
+(require 'cl-lib)
+
+(declare-function bbdb-record-get-field "bbdb")
+(declare-function bbdb-records "bbdb")
+(declare-function bbdb-dwim-mail "bbdb-com")
+(declare-function bbdb-search "bbdb-com")
+
+(defgroup company-bbdb nil
+  "Completion backend for BBDB."
+  :group 'company)
+
+(defcustom company-bbdb-modes '(message-mode)
+  "Major modes in which `company-bbdb' may complete."
+  :type '(repeat (symbol :tag "Major mode"))
+  :package-version '(company . "0.8.8"))
+
+(defun company-bbdb--candidates (arg)
+  (cl-mapcan (lambda (record)
+               (mapcar (lambda (mail) (bbdb-dwim-mail record mail))
+                       (bbdb-record-get-field record 'mail)))
+             (eval '(bbdb-search (bbdb-records) arg nil arg))))
+
+;;;###autoload
+(defun company-bbdb (command &optional arg &rest ignore)
+  "`company-mode' completion backend for BBDB."
+  (interactive (list 'interactive))
+  (cl-case command
+    (interactive (company-begin-backend 'company-bbdb))
+    (prefix (and (memq major-mode company-bbdb-modes)
+                 (featurep 'bbdb-com)
+                 (looking-back "^\\(To\\|Cc\\|Bcc\\): *.*? *\\([^,;]*\\)"
+                               (line-beginning-position))
+                 (match-string-no-properties 2)))
+    (candidates (company-bbdb--candidates arg))
+    (sorted t)
+    (no-cache t)))
+
+(provide 'company-bbdb)
+;;; company-bbdb.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-bbdb.elc b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-bbdb.elc
new file mode 100644
index 0000000000..f93ed32ac8
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-bbdb.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-capf.el b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-capf.el
new file mode 100644
index 0000000000..343edcabd6
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-capf.el
@@ -0,0 +1,189 @@
+;;; company-capf.el --- company-mode completion-at-point-functions backend -*- lexical-binding: t -*-
+
+;; Copyright (C) 2013-2018  Free Software Foundation, Inc.
+
+;; Author: Stefan Monnier <monnier@iro.umontreal.ca>
+
+;; 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:
+;;
+;; The CAPF back-end provides a bridge to the standard
+;; completion-at-point-functions facility, and thus can support any major mode
+;; that defines a proper completion function, including emacs-lisp-mode,
+;; css-mode and nxml-mode.
+
+;;; Code:
+
+(require 'company)
+(require 'cl-lib)
+
+(defvar company--capf-cache nil)
+
+(defun company--capf-data ()
+  (let ((cache company--capf-cache))
+    (if (and (equal (current-buffer) (car cache))
+             (equal (point) (car (setq cache (cdr cache))))
+             (equal (buffer-chars-modified-tick) (car (setq cache (cdr cache)))))
+        (cadr cache)
+      (let ((data (company--capf-data-real)))
+        (setq company--capf-cache
+              (list (current-buffer) (point) (buffer-chars-modified-tick) data))
+        data))))
+
+(defun company--capf-data-real ()
+  (cl-letf* (((default-value 'completion-at-point-functions)
+              ;; Ignore tags-completion-at-point-function because it subverts
+              ;; company-etags in the default value of company-backends, where
+              ;; the latter comes later.
+              (remove 'tags-completion-at-point-function
+                      (default-value 'completion-at-point-functions)))
+             (completion-at-point-functions (company--capf-workaround))
+             (data (run-hook-wrapped 'completion-at-point-functions
+                                     ;; Ignore misbehaving functions.
+                                     #'completion--capf-wrapper 'optimist)))
+    (when (and (consp (cdr data)) (integer-or-marker-p (nth 1 data))) data)))
+
+(declare-function python-shell-get-process "python")
+
+(defun company--capf-workaround ()
+  ;; For http://debbugs.gnu.org/cgi/bugreport.cgi?bug=18067
+  (if (or (not (listp completion-at-point-functions))
+          (not (memq 'python-completion-complete-at-point completion-at-point-functions))
+          (python-shell-get-process))
+      completion-at-point-functions
+    (remq 'python-completion-complete-at-point completion-at-point-functions)))
+
+(defun company-capf (command &optional arg &rest _args)
+  "`company-mode' backend using `completion-at-point-functions'."
+  (interactive (list 'interactive))
+  (pcase command
+    (`interactive (company-begin-backend 'company-capf))
+    (`prefix
+     (let ((res (company--capf-data)))
+       (when res
+         (let ((length (plist-get (nthcdr 4 res) :company-prefix-length))
+               (prefix (buffer-substring-no-properties (nth 1 res) (point))))
+           (cond
+            ((> (nth 2 res) (point)) 'stop)
+            (length (cons prefix length))
+            (t prefix))))))
+    (`candidates
+     (let ((res (company--capf-data)))
+       (when res
+         (let* ((table (nth 3 res))
+                (pred (plist-get (nthcdr 4 res) :predicate))
+                (meta (completion-metadata
+                       (buffer-substring (nth 1 res) (nth 2 res))
+                       table pred))
+                (sortfun (cdr (assq 'display-sort-function meta)))
+                (candidates (completion-all-completions arg table pred (length arg)))
+                (last (last candidates))
+                (base-size (and (numberp (cdr last)) (cdr last))))
+           (when base-size
+             (setcdr last nil))
+           (when sortfun
+             (setq candidates (funcall sortfun candidates)))
+           (if (not (zerop (or base-size 0)))
+               (let ((before (substring arg 0 base-size)))
+                 (mapcar (lambda (candidate)
+                           (concat before candidate))
+                         candidates))
+             candidates)))))
+    (`sorted
+     (let ((res (company--capf-data)))
+       (when res
+         (let ((meta (completion-metadata
+                      (buffer-substring (nth 1 res) (nth 2 res))
+                      (nth 3 res) (plist-get (nthcdr 4 res) :predicate))))
+           (cdr (assq 'display-sort-function meta))))))
+    (`match
+     ;; Ask the for the `:company-match' function.  If that doesn't help,
+     ;; fallback to sniffing for face changes to get a suitable value.
+     (let ((f (plist-get (nthcdr 4 (company--capf-data)) :company-match)))
+       (if f (funcall f arg)
+         (let* ((match-start nil) (pos -1)
+                (prop-value nil)  (faces nil)
+                (has-face-p nil)  chunks
+                (limit (length arg)))
+           (while (< pos limit)
+             (setq pos
+                   (if (< pos 0) 0 (next-property-change pos arg limit)))
+             (setq prop-value (or
+                               (get-text-property pos 'face arg)
+                               (get-text-property pos 'font-lock-face arg))
+                   faces (if (listp prop-value) prop-value (list prop-value))
+                   has-face-p (memq 'completions-common-part faces))
+             (cond ((and (not match-start) has-face-p)
+                    (setq match-start pos))
+                   ((and match-start (not has-face-p))
+                    (push (cons match-start pos) chunks)
+                    (setq match-start nil))))
+           (nreverse chunks)))))
+    (`duplicates t)
+    (`no-cache t)   ;Not much can be done here, as long as we handle
+                    ;non-prefix matches.
+    (`meta
+     (let ((f (plist-get (nthcdr 4 (company--capf-data)) :company-docsig)))
+       (when f (funcall f arg))))
+    (`doc-buffer
+     (let ((f (plist-get (nthcdr 4 (company--capf-data)) :company-doc-buffer)))
+       (when f (funcall f arg))))
+    (`location
+     (let ((f (plist-get (nthcdr 4 (company--capf-data)) :company-location)))
+       (when f (funcall f arg))))
+    (`annotation
+     (save-excursion
+       ;; FIXME: `company-begin' sets `company-point' after calling
+       ;; `company--begin-new'.  We shouldn't rely on `company-point' here,
+       ;; better to cache the capf-data value instead.  However: we can't just
+       ;; save the last capf-data value in `prefix', because that command can
+       ;; get called more often than `candidates', and at any point in the
+       ;; buffer (https://github.com/company-mode/company-mode/issues/153).
+       ;; We could try propertizing the returned prefix string, but it's not
+       ;; passed to `annotation', and `company-prefix' is set only after
+       ;; `company--strip-duplicates' is called.
+       (when company-point
+         (goto-char company-point))
+       (let ((f (plist-get (nthcdr 4 (company--capf-data)) :annotation-function)))
+         (when f (funcall f arg)))))
+    (`require-match
+     (plist-get (nthcdr 4 (company--capf-data)) :company-require-match))
+    (`init nil)      ;Don't bother: plenty of other ways to initialize the code.
+    (`post-completion
+     (company--capf-post-completion arg))
+    ))
+
+(defun company--capf-post-completion (arg)
+  (let* ((res (company--capf-data))
+         (exit-function (plist-get (nthcdr 4 res) :exit-function))
+         (table (nth 3 res))
+         (pred (plist-get (nthcdr 4 res) :predicate)))
+    (if exit-function
+        ;; Follow the example of `completion--done'.
+        (funcall exit-function arg
+                 ;; FIXME: Should probably use an additional heuristic:
+                 ;; completion-at-point doesn't know when the user picked a
+                 ;; particular candidate explicitly (it only checks whether
+                 ;; futher completions exist). Whereas company user can press
+                 ;; RET (or use implicit completion with company-tng).
+                 (if (eq (try-completion arg table pred) t)
+                     'finished 'sole)))))
+
+(provide 'company-capf)
+
+;;; company-capf.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-capf.elc b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-capf.elc
new file mode 100644
index 0000000000..899dcb6142
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-capf.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-clang.el b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-clang.el
new file mode 100644
index 0000000000..962db1e31f
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-clang.el
@@ -0,0 +1,350 @@
+;;; company-clang.el --- company-mode completion backend for Clang  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2009, 2011, 2013-2017  Free Software Foundation, Inc.
+
+;; Author: Nikolaj Schumacher
+
+;; 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:
+;;
+
+;;; Code:
+
+(require 'company)
+(require 'company-template)
+(require 'cl-lib)
+
+(defgroup company-clang nil
+  "Completion backend for Clang."
+  :group 'company)
+
+(defcustom company-clang-executable
+  (executable-find "clang")
+  "Location of clang executable."
+  :type 'file)
+
+(defcustom company-clang-begin-after-member-access t
+  "When non-nil, automatic completion will start whenever the current
+symbol is preceded by \".\", \"->\" or \"::\", ignoring
+`company-minimum-prefix-length'.
+
+If `company-begin-commands' is a list, it should include `c-electric-lt-gt'
+and `c-electric-colon', for automatic completion right after \">\" and
+\":\"."
+  :type 'boolean)
+
+(defcustom company-clang-arguments nil
+  "Additional arguments to pass to clang when completing.
+Prefix files (-include ...) can be selected with `company-clang-set-prefix'
+or automatically through a custom `company-clang-prefix-guesser'."
+  :type '(repeat (string :tag "Argument")))
+
+(defcustom company-clang-prefix-guesser 'company-clang-guess-prefix
+  "A function to determine the prefix file for the current buffer."
+  :type '(function :tag "Guesser function" nil))
+
+(defvar company-clang-modes '(c-mode c++-mode objc-mode)
+  "Major modes which clang may complete.")
+
+(defcustom company-clang-insert-arguments t
+  "When non-nil, insert function arguments as a template after completion."
+  :type 'boolean
+  :package-version '(company . "0.8.0"))
+
+;; prefix ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defvar company-clang--prefix nil)
+
+(defsubst company-clang--guess-pch-file (file)
+  (let ((dir (directory-file-name (file-name-directory file))))
+    (when (equal (file-name-nondirectory dir) "Classes")
+      (setq dir (file-name-directory dir)))
+    (car (directory-files dir t "\\([^.]h\\|[^h]\\).pch\\'" t))))
+
+(defsubst company-clang--file-substring (file beg end)
+  (with-temp-buffer
+    (insert-file-contents-literally file nil beg end)
+    (buffer-string)))
+
+(defun company-clang-guess-prefix ()
+  "Try to guess the prefix file for the current buffer."
+  ;; Prefixes seem to be called .pch.  Pre-compiled headers do, too.
+  ;; So we look at the magic number to rule them out.
+  (let* ((file (company-clang--guess-pch-file buffer-file-name))
+         (magic-number (and file (company-clang--file-substring file 0 4))))
+    (unless (member magic-number '("CPCH" "gpch"))
+      file)))
+
+(defun company-clang-set-prefix (&optional prefix)
+  "Use PREFIX as a prefix (-include ...) file for clang completion."
+  (interactive (let ((def (funcall company-clang-prefix-guesser)))
+     (unless (stringp def)
+       (setq def default-directory))
+     (list (read-file-name "Prefix file: "
+                           (when def (file-name-directory def))
+                           def t (when def (file-name-nondirectory def))))))
+  ;; TODO: pre-compile?
+  (setq company-clang--prefix (and (stringp prefix)
+                                   (file-regular-p prefix)
+                                   prefix)))
+
+;; Clean-up on exit.
+(add-hook 'kill-emacs-hook 'company-clang-set-prefix)
+
+;; parsing ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; TODO: Handle Pattern (syntactic hints would be neat).
+;; Do we ever see OVERLOAD (or OVERRIDE)?
+(defconst company-clang--completion-pattern
+  "^COMPLETION: \\_<\\(%s[a-zA-Z0-9_:]*\\)\\(?: : \\(.*\\)$\\)?$")
+
+(defconst company-clang--error-buffer-name "*clang-error*")
+
+(defun company-clang--lang-option ()
+     (if (eq major-mode 'objc-mode)
+         (if (string= "m" (file-name-extension buffer-file-name))
+             "objective-c" "objective-c++")
+       (substring (symbol-name major-mode) 0 -5)))
+
+(defun company-clang--parse-output (prefix _objc)
+  (goto-char (point-min))
+  (let ((pattern (format company-clang--completion-pattern
+                         (regexp-quote prefix)))
+        (case-fold-search nil)
+        lines match)
+    (while (re-search-forward pattern nil t)
+      (setq match (match-string-no-properties 1))
+      (unless (equal match "Pattern")
+        (save-match-data
+          (when (string-match ":" match)
+            (setq match (substring match 0 (match-beginning 0)))))
+        (let ((meta (match-string-no-properties 2)))
+          (when (and meta (not (string= match meta)))
+            (put-text-property 0 1 'meta
+                               (company-clang--strip-formatting meta)
+                               match)))
+        (push match lines)))
+    lines))
+
+(defun company-clang--meta (candidate)
+  (get-text-property 0 'meta candidate))
+
+(defun company-clang--annotation (candidate)
+  (let ((ann (company-clang--annotation-1 candidate)))
+    (if (not (and ann (string-prefix-p "(*)" ann)))
+        ann
+      (with-temp-buffer
+        (insert ann)
+        (search-backward ")")
+        (let ((pt (1+ (point))))
+          (re-search-forward ".\\_>" nil t)
+          (delete-region pt (point)))
+        (buffer-string)))))
+
+(defun company-clang--annotation-1 (candidate)
+  (let ((meta (company-clang--meta candidate)))
+    (cond
+     ((null meta) nil)
+     ((string-match "[^:]:[^:]" meta)
+      (substring meta (1+ (match-beginning 0))))
+     ((string-match "(anonymous)" meta) nil)
+     ((string-match "\\((.*)[ a-z]*\\'\\)" meta)
+      (let ((paren (match-beginning 1)))
+        (if (not (eq (aref meta (1- paren)) ?>))
+            (match-string 1 meta)
+          (with-temp-buffer
+            (insert meta)
+            (goto-char paren)
+            (substring meta (1- (search-backward "<"))))))))))
+
+(defun company-clang--strip-formatting (text)
+  (replace-regexp-in-string
+   "#]" " "
+   (replace-regexp-in-string "[<{[]#\\|#[>}]" "" text t)
+   t))
+
+(defun company-clang--handle-error (res args)
+  (goto-char (point-min))
+  (let* ((buf (get-buffer-create company-clang--error-buffer-name))
+         (cmd (concat company-clang-executable " " (mapconcat 'identity args " ")))
+         (pattern (format company-clang--completion-pattern ""))
+         (message-truncate-lines t)
+         (err (if (re-search-forward pattern nil t)
+                  (buffer-substring-no-properties (point-min)
+                                                  (1- (match-beginning 0)))
+                ;; Warn the user more aggressively if no match was found.
+                (message "clang failed with error %d: %s" res cmd)
+                (buffer-string))))
+
+    (with-current-buffer buf
+      (let ((inhibit-read-only t))
+        (erase-buffer)
+        (insert (current-time-string)
+                (format "\nclang failed with error %d:\n" res)
+                cmd "\n\n")
+        (insert err)
+        (setq buffer-read-only t)
+        (goto-char (point-min))))))
+
+(defun company-clang--start-process (prefix callback &rest args)
+  (let* ((objc (derived-mode-p 'objc-mode))
+         (buf (get-buffer-create "*clang-output*"))
+         ;; Looks unnecessary in Emacs 25.1 and later.
+         (process-adaptive-read-buffering nil)
+         (existing-process (get-buffer-process buf)))
+    (when existing-process
+      (kill-process existing-process))
+    (with-current-buffer buf
+      (erase-buffer)
+      (setq buffer-undo-list t))
+    (let* ((process-connection-type nil)
+           (process (apply #'start-file-process "company-clang" buf
+                           company-clang-executable args)))
+      (set-process-sentinel
+       process
+       (lambda (proc status)
+         (unless (string-match-p "hangup\\|killed" status)
+           (funcall
+            callback
+            (let ((res (process-exit-status proc)))
+              (with-current-buffer buf
+                (unless (eq 0 res)
+                  (company-clang--handle-error res args))
+                ;; Still try to get any useful input.
+                (company-clang--parse-output prefix objc)))))))
+      (unless (company-clang--auto-save-p)
+        (send-region process (point-min) (point-max))
+        (send-string process "\n")
+        (process-send-eof process)))))
+
+(defsubst company-clang--build-location (pos)
+  (save-excursion
+    (goto-char pos)
+    (format "%s:%d:%d"
+            (if (company-clang--auto-save-p) buffer-file-name "-")
+            (line-number-at-pos)
+            (1+ (length
+                 (encode-coding-region
+                  (line-beginning-position)
+                  (point)
+                  'utf-8
+                  t))))))
+
+(defsubst company-clang--build-complete-args (pos)
+  (append '("-fsyntax-only" "-Xclang" "-code-completion-macros")
+          (unless (company-clang--auto-save-p)
+            (list "-x" (company-clang--lang-option)))
+          company-clang-arguments
+          (when (stringp company-clang--prefix)
+            (list "-include" (expand-file-name company-clang--prefix)))
+          (list "-Xclang" (format "-code-completion-at=%s"
+                                  (company-clang--build-location pos)))
+          (list (if (company-clang--auto-save-p) buffer-file-name "-"))))
+
+(defun company-clang--candidates (prefix callback)
+  (and (company-clang--auto-save-p)
+       (buffer-modified-p)
+       (basic-save-buffer))
+  (when (null company-clang--prefix)
+    (company-clang-set-prefix (or (funcall company-clang-prefix-guesser)
+                                  'none)))
+  (apply 'company-clang--start-process
+         prefix
+         callback
+         (company-clang--build-complete-args
+          (if (company-clang--check-version 4.0 9.0)
+              (point)
+            (- (point) (length prefix))))))
+
+(defun company-clang--prefix ()
+  (if company-clang-begin-after-member-access
+      (company-grab-symbol-cons "\\.\\|->\\|::" 2)
+    (company-grab-symbol)))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defconst company-clang-required-version 1.1)
+
+(defvar company-clang--version nil)
+
+(defun company-clang--auto-save-p ()
+  (not
+   (company-clang--check-version 2.9 3.1)))
+
+(defun company-clang--check-version (min apple-min)
+  (pcase company-clang--version
+    (`(apple . ,ver) (>= ver apple-min))
+    (`(normal . ,ver) (>= ver min))
+    (_ (error "pcase-exhaustive is not in Emacs 24.3!"))))
+
+(defsubst company-clang-version ()
+  "Return the version of `company-clang-executable'."
+  (with-temp-buffer
+    (call-process company-clang-executable nil t nil "--version")
+    (goto-char (point-min))
+    (if (re-search-forward "\\(clang\\|Apple LLVM\\) version \\([0-9.]+\\)" nil t)
+        (cons
+         (if (equal (match-string-no-properties 1) "Apple LLVM")
+             'apple
+           'normal)
+         (string-to-number (match-string-no-properties 2)))
+      0)))
+
+(defun company-clang (command &optional arg &rest ignored)
+  "`company-mode' completion backend for Clang.
+Clang is a parser for C and ObjC.  Clang version 1.1 or newer is required.
+
+Additional command line arguments can be specified in
+`company-clang-arguments'.  Prefix files (-include ...) can be selected
+with `company-clang-set-prefix' or automatically through a custom
+`company-clang-prefix-guesser'.
+
+With Clang versions before 2.9, we have to save the buffer before
+performing completion.  With Clang 2.9 and later, buffer contents are
+passed via standard input."
+  (interactive (list 'interactive))
+  (cl-case command
+    (interactive (company-begin-backend 'company-clang))
+    (init (when (memq major-mode company-clang-modes)
+            (unless company-clang-executable
+              (error "Company found no clang executable"))
+            (setq company-clang--version (company-clang-version))
+            (unless (company-clang--check-version
+                     company-clang-required-version
+                     company-clang-required-version)
+              (error "Company requires clang version %s"
+                     company-clang-required-version))))
+    (prefix (and (memq major-mode company-clang-modes)
+                 buffer-file-name
+                 company-clang-executable
+                 (not (company-in-string-or-comment))
+                 (or (company-clang--prefix) 'stop)))
+    (candidates (cons :async
+                      (lambda (cb) (company-clang--candidates arg cb))))
+    (meta       (company-clang--meta arg))
+    (annotation (company-clang--annotation arg))
+    (post-completion (let ((anno (company-clang--annotation arg)))
+                       (when (and company-clang-insert-arguments anno)
+                         (insert anno)
+                         (if (string-match "\\`:[^:]" anno)
+                             (company-template-objc-templatify anno)
+                           (company-template-c-like-templatify
+                            (concat arg anno))))))))
+
+(provide 'company-clang)
+;;; company-clang.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-clang.elc b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-clang.elc
new file mode 100644
index 0000000000..eb24976e62
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-clang.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-cmake.el b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-cmake.el
new file mode 100644
index 0000000000..1bfb20bae5
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-cmake.el
@@ -0,0 +1,206 @@
+;;; company-cmake.el --- company-mode completion backend for CMake
+
+;; Copyright (C) 2013-2014, 2017-2018  Free Software Foundation, Inc.
+
+;; Author: Chen Bin <chenbin DOT sh AT gmail>
+;; Version: 0.2
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;
+;; company-cmake offers completions for module names, variable names and
+;; commands used by CMake.  And their descriptions.
+
+;;; Code:
+
+(require 'company)
+(require 'cl-lib)
+
+(defgroup company-cmake nil
+  "Completion backend for CMake."
+  :group 'company)
+
+(defcustom company-cmake-executable
+  (executable-find "cmake")
+  "Location of cmake executable."
+  :type 'file)
+
+(defvar company-cmake-executable-arguments
+  '("--help-command-list"
+    "--help-module-list"
+    "--help-variable-list")
+  "The arguments we pass to cmake, separately.
+They affect which types of symbols we get completion candidates for.")
+
+(defvar company-cmake--completion-pattern
+  "^\\(%s[a-zA-Z0-9_<>]%s\\)$"
+  "Regexp to match the candidates.")
+
+(defvar company-cmake-modes '(cmake-mode)
+  "Major modes in which cmake may complete.")
+
+(defvar company-cmake--candidates-cache nil
+  "Cache for the raw candidates.")
+
+(defvar company-cmake--meta-command-cache nil
+  "Cache for command arguments to retrieve descriptions for the candidates.")
+
+(defun company-cmake--replace-tags (rlt)
+  (setq rlt (replace-regexp-in-string
+             "\\(.*?\\(IS_GNU\\)?\\)<LANG>\\(.*\\)"
+             (lambda (_match)
+               (mapconcat 'identity
+                          (if (match-beginning 2)
+                              '("\\1CXX\\3" "\\1C\\3" "\\1G77\\3")
+                            '("\\1CXX\\3" "\\1C\\3" "\\1Fortran\\3"))
+                          "\n"))
+             rlt t))
+  (setq rlt (replace-regexp-in-string
+             "\\(.*\\)<CONFIG>\\(.*\\)"
+             (mapconcat 'identity '("\\1DEBUG\\2" "\\1RELEASE\\2"
+                                    "\\1RELWITHDEBINFO\\2" "\\1MINSIZEREL\\2")
+                        "\n")
+             rlt))
+  rlt)
+
+(defun company-cmake--fill-candidates-cache (arg)
+  "Fill candidates cache if needed."
+  (let (rlt)
+    (unless company-cmake--candidates-cache
+      (setq company-cmake--candidates-cache (make-hash-table :test 'equal)))
+
+    ;; If hash is empty, fill it.
+    (unless (gethash arg company-cmake--candidates-cache)
+      (with-temp-buffer
+        (let ((res (call-process company-cmake-executable nil t nil arg)))
+          (unless (zerop res)
+            (message "cmake executable exited with error=%d" res)))
+        (setq rlt (buffer-string)))
+      (setq rlt (company-cmake--replace-tags rlt))
+      (puthash arg rlt company-cmake--candidates-cache))
+    ))
+
+(defun company-cmake--parse (prefix content cmd)
+  (let ((start 0)
+        (pattern (format company-cmake--completion-pattern
+                         (regexp-quote prefix)
+                         (if (zerop (length prefix)) "+" "*")))
+        (lines (split-string content "\n"))
+        match
+        rlt)
+    (dolist (line lines)
+      (when (string-match pattern line)
+        (let ((match (match-string 1 line)))
+          (when match
+            (puthash match cmd company-cmake--meta-command-cache)
+            (push match rlt)))))
+    rlt))
+
+(defun company-cmake--candidates (prefix)
+  (let (results
+        cmd-opts
+        str)
+
+    (unless company-cmake--meta-command-cache
+      (setq company-cmake--meta-command-cache (make-hash-table :test 'equal)))
+
+    (dolist (arg company-cmake-executable-arguments)
+      (company-cmake--fill-candidates-cache arg)
+      (setq cmd-opts (replace-regexp-in-string "-list$" "" arg) )
+
+      (setq str (gethash arg company-cmake--candidates-cache))
+      (when str
+        (setq results (nconc results
+                             (company-cmake--parse prefix str cmd-opts)))))
+    results))
+
+(defun company-cmake--unexpand-candidate (candidate)
+  (cond
+   ((string-match "^CMAKE_\\(C\\|CXX\\|Fortran\\)\\(_.*\\)$" candidate)
+    (setq candidate (concat "CMAKE_<LANG>" (match-string 2 candidate))))
+
+   ;; C flags
+   ((string-match "^\\(.*_\\)IS_GNU\\(C\\|CXX\\|G77\\)$" candidate)
+    (setq candidate (concat (match-string 1 candidate) "IS_GNU<LANG>")))
+
+   ;; C flags
+   ((string-match "^\\(.*_\\)OVERRIDE_\\(C\\|CXX\\|Fortran\\)$" candidate)
+    (setq candidate (concat (match-string 1 candidate) "OVERRIDE_<LANG>")))
+
+   ((string-match "^\\(.*\\)\\(_DEBUG\\|_RELEASE\\|_RELWITHDEBINFO\\|_MINSIZEREL\\)\\(.*\\)$" candidate)
+    (setq candidate (concat (match-string 1 candidate)
+                            "_<CONFIG>"
+                            (match-string 3 candidate)))))
+  candidate)
+
+(defun company-cmake--meta (candidate)
+  (let ((cmd-opts (gethash candidate company-cmake--meta-command-cache))
+        result)
+    (setq candidate (company-cmake--unexpand-candidate candidate))
+
+    ;; Don't cache the documentation of every candidate (command)
+    ;; Cache in this case will cost too much memory.
+    (with-temp-buffer
+      (call-process company-cmake-executable nil t nil cmd-opts candidate)
+      ;; Go to the third line, trim it and return the result.
+      ;; Tested with cmake 2.8.9.
+      (goto-char (point-min))
+      (forward-line 2)
+      (setq result (buffer-substring-no-properties (line-beginning-position)
+                                                   (line-end-position)))
+      (setq result (replace-regexp-in-string "^[ \t\n\r]+" "" result))
+      result)))
+
+(defun company-cmake--doc-buffer (candidate)
+  (let ((cmd-opts (gethash candidate company-cmake--meta-command-cache)))
+
+    (setq candidate (company-cmake--unexpand-candidate candidate))
+    (with-temp-buffer
+      (call-process company-cmake-executable nil t nil cmd-opts candidate)
+      ;; Go to the third line, trim it and return the doc buffer.
+      ;; Tested with cmake 2.8.9.
+      (goto-char (point-min))
+      (forward-line 2)
+      (company-doc-buffer
+       (buffer-substring-no-properties (line-beginning-position)
+                                       (point-max))))))
+
+(defun company-cmake-prefix-dollar-brace-p ()
+  "Test if the current symbol follows ${."
+  (save-excursion
+    (skip-syntax-backward "w_")
+    (and (eq (char-before (point)) ?\{)
+         (eq (char-before (1- (point))) ?$))))
+
+(defun company-cmake (command &optional arg &rest ignored)
+  "`company-mode' completion backend for CMake.
+CMake is a cross-platform, open-source make system."
+  (interactive (list 'interactive))
+  (cl-case command
+    (interactive (company-begin-backend 'company-cmake))
+    (init (when (memq major-mode company-cmake-modes)
+            (unless company-cmake-executable
+              (error "Company found no cmake executable"))))
+    (prefix (and (memq major-mode company-cmake-modes)
+                 (or (not (company-in-string-or-comment))
+                     (company-cmake-prefix-dollar-brace-p))
+                 (company-grab-symbol)))
+    (candidates (company-cmake--candidates arg))
+    (meta (company-cmake--meta arg))
+    (doc-buffer (company-cmake--doc-buffer arg))
+    ))
+
+(provide 'company-cmake)
+;;; company-cmake.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-cmake.elc b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-cmake.elc
new file mode 100644
index 0000000000..f9d91cbd47
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-cmake.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-css.el b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-css.el
new file mode 100644
index 0000000000..d3ece74dc5
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-css.el
@@ -0,0 +1,446 @@
+;;; company-css.el --- company-mode completion backend for css-mode  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2009, 2011, 2014, 2018  Free Software Foundation, Inc.
+
+;; Author: Nikolaj Schumacher
+
+;; 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:
+;;
+;; In Emacs >= 26, company-capf is used instead.
+
+;;; Code:
+
+(require 'company)
+(require 'cl-lib)
+
+(declare-function web-mode-language-at-pos "web-mode" (&optional pos))
+
+(defconst company-css-property-alist
+  ;; see http://www.w3.org/TR/CSS21/propidx.html
+  '(("azimuth" angle "left-side" "far-left" "left" "center-left" "center"
+     "center-right" "right" "far-right" "right-side" "behind" "leftwards"
+     "rightwards")
+    ("background" background-color background-image background-repeat
+     background-attachment background-position
+     background-clip background-origin background-size)
+    ("background-attachment" "scroll" "fixed")
+    ("background-color" color "transparent")
+    ("background-image" uri "none")
+    ("background-position" percentage length "left" "center" "right" percentage
+     length "top" "center" "bottom" "left" "center" "right" "top" "center"
+     "bottom")
+    ("background-repeat" "repeat" "repeat-x" "repeat-y" "no-repeat")
+    ("border" border-width border-style border-color)
+    ("border-bottom" border)
+    ("border-bottom-color" border-color)
+    ("border-bottom-style" border-style)
+    ("border-bottom-width" border-width)
+    ("border-collapse" "collapse" "separate")
+    ("border-color" color "transparent")
+    ("border-left" border)
+    ("border-left-color" border-color)
+    ("border-left-style" border-style)
+    ("border-left-width" border-width)
+    ("border-right" border)
+    ("border-right-color" border-color)
+    ("border-right-style" border-style)
+    ("border-right-width" border-width)
+    ("border-spacing" length length)
+    ("border-style" border-style)
+    ("border-top" border)
+    ("border-top-color" border-color)
+    ("border-top-style" border-style)
+    ("border-top-width" border-width)
+    ("border-width" border-width)
+    ("bottom" length percentage "auto")
+    ("caption-side" "top" "bottom")
+    ("clear" "none" "left" "right" "both")
+    ("clip" shape "auto")
+    ("color" color)
+    ("content" "normal" "none" string uri counter "attr()" "open-quote"
+     "close-quote" "no-open-quote" "no-close-quote")
+    ("counter-increment" identifier integer "none")
+    ("counter-reset" identifier integer "none")
+    ("cue" cue-before cue-after)
+    ("cue-after" uri "none")
+    ("cue-before" uri "none")
+    ("cursor" uri "*" "auto" "crosshair" "default" "pointer" "move" "e-resize"
+     "ne-resize" "nw-resize" "n-resize" "se-resize" "sw-resize" "s-resize"
+     "w-resize" "text" "wait" "help" "progress")
+    ("direction" "ltr" "rtl")
+    ("display" "inline" "block" "list-item" "run-in" "inline-block" "table"
+     "inline-table" "table-row-group" "table-header-group" "table-footer-group"
+     "table-row" "table-column-group" "table-column" "table-cell"
+     "table-caption" "none")
+    ("elevation" angle "below" "level" "above" "higher" "lower")
+    ("empty-cells" "show" "hide")
+    ("float" "left" "right" "none")
+    ("font" font-style font-weight font-size "/" line-height
+     font-family "caption" "icon" "menu" "message-box" "small-caption"
+     "status-bar" "normal" "small-caps"
+     ;; CSS3
+     font-stretch)
+    ("font-family" family-name generic-family)
+    ("font-size" absolute-size relative-size length percentage)
+    ("font-style" "normal" "italic" "oblique")
+    ("font-weight" "normal" "bold" "bolder" "lighter" "100" "200" "300" "400"
+     "500" "600" "700" "800" "900")
+    ("height" length percentage "auto")
+    ("left" length percentage "auto")
+    ("letter-spacing" "normal" length)
+    ("line-height" "normal" number length percentage)
+    ("list-style" list-style-type list-style-position list-style-image)
+    ("list-style-image" uri "none")
+    ("list-style-position" "inside" "outside")
+    ("list-style-type" "disc" "circle" "square" "decimal" "decimal-leading-zero"
+     "lower-roman" "upper-roman" "lower-greek" "lower-latin" "upper-latin"
+     "armenian" "georgian" "lower-alpha" "upper-alpha" "none")
+    ("margin" margin-width)
+    ("margin-bottom" margin-width)
+    ("margin-left" margin-width)
+    ("margin-right" margin-width)
+    ("margin-top" margin-width)
+    ("max-height" length percentage "none")
+    ("max-width" length percentage "none")
+    ("min-height" length percentage)
+    ("min-width" length percentage)
+    ("orphans" integer)
+    ("outline" outline-color outline-style outline-width)
+    ("outline-color" color "invert")
+    ("outline-style" border-style)
+    ("outline-width" border-width)
+    ("overflow" "visible" "hidden" "scroll" "auto"
+     ;; CSS3:
+     "no-display" "no-content")
+    ("padding" padding-width)
+    ("padding-bottom" padding-width)
+    ("padding-left" padding-width)
+    ("padding-right" padding-width)
+    ("padding-top" padding-width)
+    ("page-break-after" "auto" "always" "avoid" "left" "right")
+    ("page-break-before" "auto" "always" "avoid" "left" "right")
+    ("page-break-inside" "avoid" "auto")
+    ("pause" time percentage)
+    ("pause-after" time percentage)
+    ("pause-before" time percentage)
+    ("pitch" frequency "x-low" "low" "medium" "high" "x-high")
+    ("pitch-range" number)
+    ("play-during" uri "mix" "repeat" "auto" "none")
+    ("position" "static" "relative" "absolute" "fixed")
+    ("quotes" string string "none")
+    ("richness" number)
+    ("right" length percentage "auto")
+    ("speak" "normal" "none" "spell-out")
+    ("speak-header" "once" "always")
+    ("speak-numeral" "digits" "continuous")
+    ("speak-punctuation" "code" "none")
+    ("speech-rate" number "x-slow" "slow" "medium" "fast" "x-fast" "faster"
+     "slower")
+    ("stress" number)
+    ("table-layout" "auto" "fixed")
+    ("text-align" "left" "right" "center" "justify")
+    ("text-indent" length percentage)
+    ("text-transform" "capitalize" "uppercase" "lowercase" "none")
+    ("top" length percentage "auto")
+    ("unicode-bidi" "normal" "embed" "bidi-override")
+    ("vertical-align" "baseline" "sub" "super" "top" "text-top" "middle"
+     "bottom" "text-bottom" percentage length)
+    ("visibility" "visible" "hidden" "collapse")
+    ("voice-family" specific-voice generic-voice "*" specific-voice
+     generic-voice)
+    ("volume" number percentage "silent" "x-soft" "soft" "medium" "loud"
+     "x-loud")
+    ("white-space" "normal" "pre" "nowrap" "pre-wrap" "pre-line")
+    ("widows" integer)
+    ("width" length percentage "auto")
+    ("word-spacing" "normal" length)
+    ("z-index" "auto" integer)
+    ;; CSS3
+    ("align-content" align-stretch "space-between" "space-around")
+    ("align-items" align-stretch "baseline")
+    ("align-self" align-items "auto")
+    ("animation" animation-name animation-duration animation-timing-function
+     animation-delay animation-iteration-count animation-direction
+     animation-fill-mode)
+    ("animation-delay" time)
+    ("animation-direction" "normal" "reverse" "alternate" "alternate-reverse")
+    ("animation-duration" time)
+    ("animation-fill-mode" "none" "forwards" "backwards" "both")
+    ("animation-iteration-count" integer "infinite")
+    ("animation-name" "none")
+    ("animation-play-state" "paused" "running")
+    ("animation-timing-function" transition-timing-function
+     "step-start" "step-end" "steps(,)")
+    ("backface-visibility" "visible" "hidden")
+    ("background-clip" background-origin)
+    ("background-origin" "border-box" "padding-box" "content-box")
+    ("background-size" length percentage "auto" "cover" "contain")
+    ("border-image" border-image-outset border-image-repeat border-image-source
+     border-image-slice border-image-width)
+    ("border-image-outset" length)
+    ("border-image-repeat" "stretch" "repeat" "round" "space")
+    ("border-image-source" uri "none")
+    ("border-image-slice" length)
+    ("border-image-width" length percentage)
+    ("border-radius" length)
+    ("border-top-left-radius" length)
+    ("border-top-right-radius" length)
+    ("border-bottom-left-radius" length)
+    ("border-bottom-right-radius" length)
+    ("box-decoration-break" "slice" "clone")
+    ("box-shadow" length color)
+    ("box-sizing" "content-box" "border-box")
+    ("break-after" "auto" "always" "avoid" "left" "right" "page" "column"
+     "avoid-page" "avoid-column")
+    ("break-before" break-after)
+    ("break-inside" "avoid" "auto")
+    ("columns" column-width column-count)
+    ("column-count" integer)
+    ("column-fill" "auto" "balance")
+    ("column-gap" length "normal")
+    ("column-rule" column-rule-width column-rule-style column-rule-color)
+    ("column-rule-color" color)
+    ("column-rule-style" border-style)
+    ("column-rule-width" border-width)
+    ("column-span" "all" "none")
+    ("column-width" length "auto")
+    ("filter" url "blur()" "brightness()" "contrast()" "drop-shadow()"
+     "grayscale()" "hue-rotate()" "invert()" "opacity()" "saturate()" "sepia()")
+    ("flex" flex-grow flex-shrink flex-basis)
+    ("flex-basis" percentage length "auto")
+    ("flex-direction" "row" "row-reverse" "column" "column-reverse")
+    ("flex-flow" flex-direction flex-wrap)
+    ("flex-grow" number)
+    ("flex-shrink" number)
+    ("flex-wrap" "nowrap" "wrap" "wrap-reverse")
+    ("font-feature-setting" normal string number)
+    ("font-kerning" "auto" "normal" "none")
+    ("font-language-override" "normal" string)
+    ("font-size-adjust" "none" number)
+    ("font-stretch" "normal" "ultra-condensed" "extra-condensed" "condensed"
+     "semi-condensed" "semi-expanded" "expanded" "extra-expanded" "ultra-expanded")
+    ("font-synthesis" "none" "weight" "style")
+    ("font-variant" font-variant-alternates font-variant-caps
+     font-variant-east-asian font-variant-ligatures font-variant-numeric
+     font-variant-position)
+    ("font-variant-alternates" "normal" "historical-forms" "stylistic()"
+     "styleset()" "character-variant()" "swash()" "ornaments()" "annotation()")
+    ("font-variant-caps" "normal" "small-caps" "all-small-caps" "petite-caps"
+     "all-petite-caps" "unicase" "titling-caps")
+    ("font-variant-east-asian" "jis78" "jis83" "jis90" "jis04" "simplified"
+     "traditional" "full-width" "proportional-width" "ruby")
+    ("font-variant-ligatures" "normal" "none" "common-ligatures"
+     "no-common-ligatures" "discretionary-ligatures" "no-discretionary-ligatures"
+     "historical-ligatures" "no-historical-ligatures" "contextual" "no-contextual")
+    ("font-variant-numeric" "normal" "ordinal" "slashed-zero"
+     "lining-nums" "oldstyle-nums" "proportional-nums" "tabular-nums"
+     "diagonal-fractions" "stacked-fractions")
+    ("font-variant-position" "normal" "sub" "super")
+    ("hyphens" "none" "manual" "auto")
+    ("justify-content" align-common "space-between" "space-around")
+    ("line-break" "auto" "loose" "normal" "strict")
+    ("marquee-direction" "forward" "reverse")
+    ("marquee-play-count" integer "infinite")
+    ("marquee-speed" "slow" "normal" "fast")
+    ("marquee-style" "scroll" "slide" "alternate")
+    ("opacity" number)
+    ("order" number)
+    ("outline-offset" length)
+    ("overflow-x" overflow)
+    ("overflow-y" overflow)
+    ("overflow-style" "auto" "marquee-line" "marquee-block")
+    ("overflow-wrap" "normal" "break-word")
+    ("perspective" "none" length)
+    ("perspective-origin" percentage length "left" "center" "right" "top" "bottom")
+    ("resize" "none" "both" "horizontal" "vertical")
+    ("tab-size" integer length)
+    ("text-align-last" "auto" "start" "end" "left" "right" "center" "justify")
+    ("text-decoration" text-decoration-color text-decoration-line text-decoration-style)
+    ("text-decoration-color" color)
+    ("text-decoration-line" "none" "underline" "overline" "line-through" "blink")
+    ("text-decoration-style" "solid" "double" "dotted" "dashed" "wavy")
+    ("text-overflow" "clip" "ellipsis")
+    ("text-shadow" color length)
+    ("text-underline-position" "auto" "under" "left" "right")
+    ("transform" "matrix(,,,,,)" "translate(,)" "translateX()" "translateY()"
+     "scale()" "scaleX()" "scaleY()" "rotate()" "skewX()" "skewY()" "none")
+    ("transform-origin" perspective-origin)
+    ("transform-style" "flat" "preserve-3d")
+    ("transition" transition-property transition-duration
+     transition-timing-function transition-delay)
+    ("transition-delay" time)
+    ("transition-duration" time)
+    ("transition-timing-function"
+     "ease" "linear" "ease-in" "ease-out" "ease-in-out" "cubic-bezier(,,,)")
+    ("transition-property" "none" "all" identifier)
+    ("word-wrap" overflow-wrap)
+    ("word-break" "normal" "break-all" "keep-all"))
+  "A list of CSS properties and their possible values.")
+
+(defconst company-css-value-classes
+  '((absolute-size "xx-small" "x-small" "small" "medium" "large" "x-large"
+                   "xx-large")
+    (align-common "flex-start" "flex-end" "center")
+    (align-stretch align-common "stretch")
+    (border-style "none" "hidden" "dotted" "dashed" "solid" "double" "groove"
+                  "ridge" "inset" "outset")
+    (border-width "thick" "medium" "thin")
+    (color "aqua" "black" "blue" "fuchsia" "gray" "green" "lime" "maroon" "navy"
+           "olive" "orange" "purple" "red" "silver" "teal" "white" "yellow")
+    (counter "counter(,)")
+    (family-name "Courier" "Helvetica" "Times")
+    (generic-family "serif" "sans-serif" "cursive" "fantasy" "monospace")
+    (generic-voice "male" "female" "child")
+    (margin-width "auto") ;; length percentage
+    (relative-size "larger" "smaller")
+    (shape "rect(,,,)")
+    (uri "url()"))
+  "A list of CSS property value classes and their contents.")
+;; missing, because not completable
+;; <angle><frequency><identifier><integer><length><number><padding-width>
+;; <percentage><specific-voice><string><time><uri>
+
+(defconst company-css-html-tags
+  '("a" "abbr" "acronym" "address" "applet" "area" "b" "base" "basefont" "bdo"
+    "big" "blockquote" "body" "br" "button" "caption" "center" "cite" "code"
+    "col" "colgroup" "dd" "del" "dfn" "dir" "div" "dl" "dt" "em" "fieldset"
+    "font" "form" "frame" "frameset" "h1" "h2" "h3" "h4" "h5" "h6" "head" "hr"
+    "html" "i" "iframe" "img" "input" "ins" "isindex" "kbd" "label" "legend"
+    "li" "link" "map" "menu" "meta" "noframes" "noscript" "object" "ol"
+    "optgroup" "option" "p" "param" "pre" "q" "s" "samp" "script" "select"
+    "small" "span" "strike" "strong" "style" "sub" "sup" "table" "tbody" "td"
+    "textarea" "tfoot" "th" "thead" "title" "tr" "tt" "u" "ul" "var"
+    ;; HTML5
+    "section" "article" "aside" "header" "footer" "nav" "figure" "figcaption"
+    "time" "mark" "main")
+  "A list of HTML tags for use in CSS completion.")
+
+(defconst company-css-pseudo-classes
+  '("active" "after" "before" "first" "first-child" "first-letter" "first-line"
+    "focus" "hover" "lang" "left" "link" "right" "visited")
+  "Identifiers for CSS pseudo-elements and pseudo-classes.")
+
+(defconst company-css-property-cache (make-hash-table :size 115 :test 'equal))
+
+(defun company-css-property-values (attribute)
+  "Access the `company-css-property-alist' cached and flattened."
+  (or (gethash attribute company-css-property-cache)
+      (let (results)
+        (dolist (value (cdr (assoc attribute company-css-property-alist)))
+          (if (symbolp value)
+              (dolist (child (or (cdr (assoc value company-css-value-classes))
+                                 (company-css-property-values
+                                  (symbol-name value))))
+                (push child results))
+            (push value results)))
+        (setq results (sort results 'string<))
+        (puthash attribute
+                 (if (fboundp 'delete-consecutive-dups)
+                     (delete-consecutive-dups results)
+                   (delete-dups results))
+                 company-css-property-cache)
+        results)))
+
+;;; bracket detection
+
+(defconst company-css-braces-syntax-table
+  (let ((table (make-syntax-table)))
+    (setf (aref table ?{) '(4 . 125))
+    (setf (aref table ?}) '(5 . 123))
+    table)
+  "A syntax table giving { and } paren syntax.")
+
+(defun company-css-inside-braces-p ()
+  "Return non-nil, if point is within matched { and }."
+  (ignore-errors
+    (with-syntax-table company-css-braces-syntax-table
+      (let ((parse-sexp-ignore-comments t))
+        (scan-lists (point) -1 1)))))
+
+;;; tags
+(defconst company-css-tag-regexp
+  (concat "\\(?:\\`\\|}\\)[[:space:]]*"
+          ;; multiple
+          "\\(?:"
+          ;; previous tags:
+          "\\(?:#\\|\\_<[[:alpha:]]\\)[[:alnum:]-#]*\\(?:\\[[^]]*\\]\\)?"
+          ;; space or selectors
+          "\\(?:[[:space:]]+\\|[[:space:]]*[+,>][[:space:]]*\\)"
+          "\\)*"
+          "\\(\\(?:#\\|\\_<[[:alpha:]]\\)\\(?:[[:alnum:]-#]*\\_>\\)?\\_>\\|\\)"
+          "\\=")
+  "A regular expression matching CSS tags.")
+
+;;; pseudo id
+(defconst company-css-pseudo-regexp
+  (concat "\\(?:\\`\\|}\\)[[:space:]]*"
+          ;; multiple
+          "\\(?:"
+          ;; previous tags:
+          "\\(?:#\\|\\_<[[:alpha:]]\\)[[:alnum:]-#]*\\(?:\\[[^]]*\\]\\)?"
+          ;; space or delimiters
+          "\\(?:[[:space:]]+\\|[[:space:]]*[+,>][[:space:]]*\\)"
+          "\\)*"
+          "\\(?:\\(?:\\#\\|\\_<[[:alpha:]]\\)[[:alnum:]-#]*\\):"
+          "\\([[:alpha:]-]+\\_>\\|\\)\\_>\\=")
+  "A regular expression matching CSS pseudo classes.")
+
+;;; properties
+
+(defun company-css-grab-property ()
+  "Return the CSS property before point, if any.
+Returns \"\" if no property found, but feasible at this position."
+  (when (company-css-inside-braces-p)
+    (company-grab-symbol)))
+
+;;; values
+(defconst company-css-property-value-regexp
+  "\\_<\\([[:alpha:]-]+\\):\\(?:[^{};]*[[:space:]]+\\)?\\([^{};]*\\_>\\|\\)\\="
+  "A regular expression matching CSS tags.")
+
+;;;###autoload
+(defun company-css (command &optional arg &rest ignored)
+  "`company-mode' completion backend for `css-mode'."
+  (interactive (list 'interactive))
+  (cl-case command
+    (interactive (company-begin-backend 'company-css))
+    (prefix (and (or (derived-mode-p 'css-mode)
+                     (and (derived-mode-p 'web-mode)
+                          (string= (web-mode-language-at-pos) "css")))
+                 (or (company-grab company-css-tag-regexp 1)
+                     (company-grab company-css-pseudo-regexp 1)
+                     (company-grab company-css-property-value-regexp 2
+                                   (line-beginning-position))
+                     (company-css-grab-property))))
+    (candidates
+     (cond
+      ((company-grab company-css-tag-regexp 1)
+       (all-completions arg company-css-html-tags))
+      ((company-grab company-css-pseudo-regexp 1)
+       (all-completions arg company-css-pseudo-classes))
+      ((company-grab company-css-property-value-regexp 2
+                     (line-beginning-position))
+       (all-completions arg
+                        (company-css-property-values
+                         (company-grab company-css-property-value-regexp 1))))
+      ((company-css-grab-property)
+       (all-completions arg company-css-property-alist))))
+    (sorted t)))
+
+(provide 'company-css)
+;;; company-css.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-css.elc b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-css.elc
new file mode 100644
index 0000000000..e4c8fa51b6
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-css.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-dabbrev-code.el b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-dabbrev-code.el
new file mode 100644
index 0000000000..37f287c520
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-dabbrev-code.el
@@ -0,0 +1,104 @@
+;;; company-dabbrev-code.el --- dabbrev-like company-mode backend for code  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2009, 2011, 2014  Free Software Foundation, Inc.
+
+;; Author: Nikolaj Schumacher
+
+;; 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:
+;;
+
+;;; Code:
+
+(require 'company)
+(require 'company-dabbrev)
+(require 'cl-lib)
+
+(defgroup company-dabbrev-code nil
+  "dabbrev-like completion backend for code."
+  :group 'company)
+
+(defcustom company-dabbrev-code-modes
+  '(prog-mode
+    batch-file-mode csharp-mode css-mode erlang-mode haskell-mode jde-mode
+    lua-mode python-mode)
+  "Modes that use `company-dabbrev-code'.
+In all these modes (and their derivatives) `company-dabbrev-code' will
+complete only symbols, not text in comments or strings.  In other modes
+`company-dabbrev-code' will pass control to other backends
+\(e.g. `company-dabbrev'\).  Value t means complete in all modes."
+  :type '(choice (repeat :tag "Some modes" (symbol :tag "Major mode"))
+                 (const :tag "All modes" t)))
+
+(defcustom company-dabbrev-code-other-buffers t
+  "Determines whether `company-dabbrev-code' should search other buffers.
+If `all', search all other buffers, except the ignored ones.  If t, search
+buffers with the same major mode.  If `code', search all buffers with major
+modes in `company-dabbrev-code-modes', or derived from one of them.  See
+also `company-dabbrev-code-time-limit'."
+  :type '(choice (const :tag "Off" nil)
+                 (const :tag "Same major mode" t)
+                 (const :tag "Code major modes" code)
+                 (const :tag "All" all)))
+
+(defcustom company-dabbrev-code-time-limit .1
+  "Determines how long `company-dabbrev-code' should look for matches."
+  :type '(choice (const :tag "Off" nil)
+                 (number :tag "Seconds")))
+
+(defcustom company-dabbrev-code-everywhere nil
+  "Non-nil to offer completions in comments and strings."
+  :type 'boolean)
+
+(defcustom company-dabbrev-code-ignore-case nil
+  "Non-nil to ignore case when collecting completion candidates."
+  :type 'boolean)
+
+(defun company-dabbrev-code--make-regexp (prefix)
+  (concat "\\_<" (if (equal prefix "")
+                     "\\([a-zA-Z]\\|\\s_\\)"
+                   (regexp-quote prefix))
+          "\\(\\sw\\|\\s_\\)*\\_>"))
+
+;;;###autoload
+(defun company-dabbrev-code (command &optional arg &rest ignored)
+  "dabbrev-like `company-mode' backend for code.
+The backend looks for all symbols in the current buffer that aren't in
+comments or strings."
+  (interactive (list 'interactive))
+  (cl-case command
+    (interactive (company-begin-backend 'company-dabbrev-code))
+    (prefix (and (or (eq t company-dabbrev-code-modes)
+                     (apply #'derived-mode-p company-dabbrev-code-modes))
+                 (or company-dabbrev-code-everywhere
+                     (not (company-in-string-or-comment)))
+                 (or (company-grab-symbol) 'stop)))
+    (candidates (let ((case-fold-search company-dabbrev-code-ignore-case))
+                  (company-dabbrev--search
+                   (company-dabbrev-code--make-regexp arg)
+                   company-dabbrev-code-time-limit
+                   (pcase company-dabbrev-code-other-buffers
+                     (`t (list major-mode))
+                     (`code company-dabbrev-code-modes)
+                     (`all `all))
+                   (not company-dabbrev-code-everywhere))))
+    (ignore-case company-dabbrev-code-ignore-case)
+    (duplicates t)))
+
+(provide 'company-dabbrev-code)
+;;; company-dabbrev-code.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-dabbrev-code.elc b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-dabbrev-code.elc
new file mode 100644
index 0000000000..32f3b6182c
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-dabbrev-code.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-dabbrev.el b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-dabbrev.el
new file mode 100644
index 0000000000..5d2f318675
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-dabbrev.el
@@ -0,0 +1,206 @@
+;;; company-dabbrev.el --- dabbrev-like company-mode completion backend  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2009, 2011, 2014, 2015, 2016  Free Software Foundation, Inc.
+
+;; Author: Nikolaj Schumacher
+
+;; 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:
+;;
+
+;;; Code:
+
+(require 'company)
+(require 'cl-lib)
+
+(defgroup company-dabbrev nil
+  "dabbrev-like completion backend."
+  :group 'company)
+
+(defcustom company-dabbrev-other-buffers 'all
+  "Determines whether `company-dabbrev' should search other buffers.
+If `all', search all other buffers, except the ignored ones.  If t, search
+buffers with the same major mode.  See also `company-dabbrev-time-limit'."
+  :type '(choice (const :tag "Off" nil)
+                 (const :tag "Same major mode" t)
+                 (const :tag "All" all)))
+
+(defcustom company-dabbrev-ignore-buffers "\\`[ *]"
+  "Regexp matching the names of buffers to ignore.
+Or a function that returns non-nil for such buffers."
+  :type '(choice (regexp :tag "Regexp")
+                 (function :tag "Predicate"))
+  :package-version '(company . "0.9.0"))
+
+(defcustom company-dabbrev-time-limit .1
+  "Determines how many seconds `company-dabbrev' should look for matches."
+  :type '(choice (const :tag "Off" nil)
+                 (number :tag "Seconds")))
+
+(defcustom company-dabbrev-char-regexp "\\sw"
+  "A regular expression matching the characters `company-dabbrev' looks for."
+  :type 'regexp)
+
+(defcustom company-dabbrev-ignore-case 'keep-prefix
+  "Non-nil to ignore case when collecting completion candidates.
+When it's `keep-prefix', the text before point will remain unchanged after
+candidate is inserted, even some of its characters have different case."
+  :type '(choice
+          (const :tag "Don't ignore case" nil)
+          (const :tag "Ignore case" t)
+          (const :tag "Keep case before point" keep-prefix)))
+
+(defcustom company-dabbrev-downcase 'case-replace
+  "Whether to downcase the returned candidates.
+
+The value of nil means keep them as-is.
+`case-replace' means use the value of `case-replace'.
+Any other value means downcase.
+
+If you set this value to nil, you may also want to set
+`company-dabbrev-ignore-case' to any value other than `keep-prefix'."
+  :type '(choice
+          (const :tag "Keep as-is" nil)
+          (const :tag "Downcase" t)
+          (const :tag "Use case-replace" case-replace)))
+
+(defcustom company-dabbrev-minimum-length 4
+  "The minimum length for the completion candidate to be included.
+This variable affects both `company-dabbrev' and `company-dabbrev-code'."
+  :type 'integer
+  :package-version '(company . "0.8.3"))
+
+(defcustom company-dabbrev-ignore-invisible nil
+  "Non-nil to skip invisible text."
+  :type 'boolean
+  :package-version '(company . "0.9.0"))
+
+(defmacro company-dabbrev--time-limit-while (test start limit freq &rest body)
+  (declare (indent 3) (debug t))
+  `(let ((company-time-limit-while-counter 0))
+     (catch 'done
+       (while ,test
+         ,@body
+         (and ,limit
+              (= (cl-incf company-time-limit-while-counter) ,freq)
+              (setq company-time-limit-while-counter 0)
+              (> (float-time (time-since ,start)) ,limit)
+              (throw 'done 'company-time-out))))))
+
+(defun company-dabbrev--make-regexp ()
+  (concat "\\(?:" company-dabbrev-char-regexp "\\)+"))
+
+(defun company-dabbrev--search-buffer (regexp pos symbols start limit
+                                       ignore-comments)
+  (save-excursion
+    (cl-labels ((maybe-collect-match
+                 ()
+                 (let ((match (match-string-no-properties 0)))
+                   (when (and (>= (length match) company-dabbrev-minimum-length)
+                              (not (and company-dabbrev-ignore-invisible
+                                        (invisible-p (match-beginning 0)))))
+                     (push match symbols)))))
+      (goto-char (if pos (1- pos) (point-min)))
+      ;; Search before pos.
+      (let ((tmp-end (point)))
+        (company-dabbrev--time-limit-while (and (not (input-pending-p))
+                                                (> tmp-end (point-min)))
+            start limit 1
+          (ignore-errors
+            (forward-char -10000))
+          (forward-line 0)
+          (save-excursion
+            ;; Before, we used backward search, but it matches non-greedily, and
+            ;; that forced us to use the "beginning/end of word" anchors in
+            ;; `company-dabbrev--make-regexp'.  It's also about 2x slower.
+            (while (and (not (input-pending-p))
+                        (re-search-forward regexp tmp-end t))
+              (if (and ignore-comments (save-match-data (company-in-string-or-comment)))
+                  (re-search-forward "\\s>\\|\\s!\\|\\s\"" tmp-end t)
+                (maybe-collect-match))))
+          (setq tmp-end (point))))
+      (goto-char (or pos (point-min)))
+      ;; Search after pos.
+      (company-dabbrev--time-limit-while (and (not (input-pending-p))
+                                              (re-search-forward regexp nil t))
+          start limit 25
+        (if (and ignore-comments (save-match-data (company-in-string-or-comment)))
+            (re-search-forward "\\s>\\|\\s!\\|\\s\"" nil t)
+          (maybe-collect-match)))
+      symbols)))
+
+(defun company-dabbrev--search (regexp &optional limit other-buffer-modes
+                                ignore-comments)
+  (let* ((start (current-time))
+         (symbols (company-dabbrev--search-buffer regexp (point) nil start limit
+                                                  ignore-comments)))
+    (when other-buffer-modes
+      (cl-dolist (buffer (delq (current-buffer) (buffer-list)))
+        (unless (if (stringp company-dabbrev-ignore-buffers)
+                    (string-match-p company-dabbrev-ignore-buffers
+                                    (buffer-name buffer))
+                  (funcall company-dabbrev-ignore-buffers buffer))
+          (with-current-buffer buffer
+            (when (or (eq other-buffer-modes 'all)
+                      (apply #'derived-mode-p other-buffer-modes))
+              (setq symbols
+                    (company-dabbrev--search-buffer regexp nil symbols start
+                                                    limit ignore-comments)))))
+        (and limit
+             (> (float-time (time-since start)) limit)
+             (cl-return))))
+    symbols))
+
+(defun company-dabbrev--prefix ()
+  ;; Not in the middle of a word.
+  (unless (looking-at company-dabbrev-char-regexp)
+    ;; Emacs can't do greedy backward-search.
+    (company-grab-line (format "\\(?:^\\| \\)[^ ]*?\\(\\(?:%s\\)*\\)"
+                               company-dabbrev-char-regexp)
+                       1)))
+
+(defun company-dabbrev--filter (prefix candidates)
+  (let ((completion-ignore-case company-dabbrev-ignore-case))
+    (all-completions prefix candidates)))
+
+;;;###autoload
+(defun company-dabbrev (command &optional arg &rest ignored)
+  "dabbrev-like `company-mode' completion backend."
+  (interactive (list 'interactive))
+  (cl-case command
+    (interactive (company-begin-backend 'company-dabbrev))
+    (prefix (company-dabbrev--prefix))
+    (candidates
+     (let* ((case-fold-search company-dabbrev-ignore-case)
+            (words (company-dabbrev--search (company-dabbrev--make-regexp)
+                                            company-dabbrev-time-limit
+                                            (pcase company-dabbrev-other-buffers
+                                              (`t (list major-mode))
+                                              (`all `all))))
+            (downcase-p (if (eq company-dabbrev-downcase 'case-replace)
+                            case-replace
+                          company-dabbrev-downcase)))
+       (setq words (company-dabbrev--filter arg words))
+       (if downcase-p
+           (mapcar 'downcase words)
+         words)))
+    (ignore-case company-dabbrev-ignore-case)
+    (duplicates t)))
+
+(provide 'company-dabbrev)
+;;; company-dabbrev.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-dabbrev.elc b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-dabbrev.elc
new file mode 100644
index 0000000000..dd18ea1a28
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-dabbrev.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-eclim.el b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-eclim.el
new file mode 100644
index 0000000000..b37f75602e
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-eclim.el
@@ -0,0 +1,186 @@
+;;; company-eclim.el --- company-mode completion backend for Eclim
+
+;; Copyright (C) 2009, 2011, 2013, 2015  Free Software Foundation, Inc.
+
+;; Author: Nikolaj Schumacher
+
+;; 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:
+;;
+;; Using `emacs-eclim' together with (or instead of) this backend is
+;; recommended, as it allows you to use other Eclim features.
+;;
+;; The alternative backend provided by `emacs-eclim' uses `yasnippet'
+;; instead of `company-template' to expand function calls, and it supports
+;; some languages other than Java.
+
+;;; Code:
+
+(require 'company)
+(require 'company-template)
+(require 'cl-lib)
+
+(defgroup company-eclim nil
+  "Completion backend for Eclim."
+  :group 'company)
+
+(defun company-eclim-executable-find ()
+  (let (file)
+    (cl-dolist (eclipse-root '("/Applications/eclipse" "/usr/lib/eclipse"
+                            "/usr/local/lib/eclipse"))
+      (and (file-exists-p (setq file (expand-file-name "plugins" eclipse-root)))
+           (setq file (car (last (directory-files file t "^org.eclim_"))))
+           (file-exists-p (setq file (expand-file-name "bin/eclim" file)))
+           (cl-return file)))))
+
+(defcustom company-eclim-executable
+  (or (bound-and-true-p eclim-executable)
+      (executable-find "eclim")
+      (company-eclim-executable-find))
+  "Location of eclim executable."
+  :type 'file)
+
+(defcustom company-eclim-auto-save t
+  "Determines whether to save the buffer when retrieving completions.
+eclim can only complete correctly when the buffer has been saved."
+  :type '(choice (const :tag "Off" nil)
+                 (const :tag "On" t)))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defvar-local company-eclim--project-dir 'unknown)
+
+(defvar-local company-eclim--project-name nil)
+
+(declare-function json-read "json")
+(defvar json-array-type)
+
+(defun company-eclim--call-process (&rest args)
+  (let ((coding-system-for-read 'utf-8)
+        res)
+    (require 'json)
+    (with-temp-buffer
+      (if (= 0 (setq res (apply 'call-process company-eclim-executable nil t nil
+                                "-command" args)))
+          (let ((json-array-type 'list))
+            (goto-char (point-min))
+            (unless (eobp)
+              (json-read)))
+        (message "Company-eclim command failed with error %d:\n%s" res
+                 (buffer-substring (point-min) (point-max)))
+        nil))))
+
+(defun company-eclim--project-list ()
+  (company-eclim--call-process "project_list"))
+
+(defun company-eclim--project-dir ()
+  (if (eq company-eclim--project-dir 'unknown)
+      (let ((dir (locate-dominating-file buffer-file-name ".project")))
+        (when dir
+          (setq company-eclim--project-dir
+                (directory-file-name
+                 (expand-file-name dir)))))
+    company-eclim--project-dir))
+
+(defun company-eclim--project-name ()
+  (or company-eclim--project-name
+      (let ((dir (company-eclim--project-dir)))
+        (when dir
+          (setq company-eclim--project-name
+                (cl-loop for project in (company-eclim--project-list)
+                         when (equal (cdr (assoc 'path project)) dir)
+                         return (cdr (assoc 'name project))))))))
+
+(defun company-eclim--candidates (prefix)
+  (interactive "d")
+  (let ((project-file (file-relative-name buffer-file-name
+                                          (company-eclim--project-dir)))
+        completions)
+    (when company-eclim-auto-save
+      (when (buffer-modified-p)
+        (basic-save-buffer))
+      ;; FIXME: Sometimes this isn't finished when we complete.
+      (company-eclim--call-process "java_src_update"
+                                   "-p" (company-eclim--project-name)
+                                   "-f" project-file))
+    (dolist (item (cdr (assoc 'completions
+                              (company-eclim--call-process
+                               "java_complete" "-p" (company-eclim--project-name)
+                               "-f" project-file
+                               "-o" (number-to-string
+                                     (company-eclim--search-point prefix))
+                               "-e" "utf-8"
+                               "-l" "standard"))))
+      (let* ((meta (cdr (assoc 'info item)))
+             (completion meta))
+        (when (string-match " ?[(:-]" completion)
+          (setq completion (substring completion 0 (match-beginning 0))))
+        (put-text-property 0 1 'meta meta completion)
+        (push completion completions)))
+    (let ((completion-ignore-case nil))
+      (all-completions prefix completions))))
+
+(defun company-eclim--search-point (prefix)
+  (if (or (cl-plusp (length prefix)) (eq (char-before) ?.))
+      (1- (point))
+    (point)))
+
+(defun company-eclim--meta (candidate)
+  (get-text-property 0 'meta candidate))
+
+(defun company-eclim--annotation (candidate)
+  (let ((meta (company-eclim--meta candidate)))
+    (when (string-match "\\(([^-]*\\) -" meta)
+      (substring meta (match-beginning 1) (match-end 1)))))
+
+(defun company-eclim--prefix ()
+  (let ((prefix (company-grab-symbol)))
+    (when prefix
+      ;; Completion candidates for annotations don't include '@'.
+      (when (eq ?@ (string-to-char prefix))
+        (setq prefix (substring prefix 1)))
+      prefix)))
+
+(defun company-eclim (command &optional arg &rest ignored)
+  "`company-mode' completion backend for Eclim.
+Eclim provides access to Eclipse Java IDE features for other editors.
+
+Eclim version 1.7.13 or newer (?) is required.
+
+Completions only work correctly when the buffer has been saved.
+`company-eclim-auto-save' determines whether to do this automatically."
+  (interactive (list 'interactive))
+  (cl-case command
+    (interactive (company-begin-backend 'company-eclim))
+    (prefix (and (derived-mode-p 'java-mode 'jde-mode)
+                 buffer-file-name
+                 company-eclim-executable
+                 (company-eclim--project-name)
+                 (not (company-in-string-or-comment))
+                 (or (company-eclim--prefix) 'stop)))
+    (candidates (company-eclim--candidates arg))
+    (meta (company-eclim--meta arg))
+    ;; because "" doesn't return everything
+    (no-cache (equal arg ""))
+    (annotation (company-eclim--annotation arg))
+    (post-completion (let ((anno (company-eclim--annotation arg)))
+                       (when anno
+                         (insert anno)
+                         (company-template-c-like-templatify anno))))))
+
+(provide 'company-eclim)
+;;; company-eclim.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-eclim.elc b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-eclim.elc
new file mode 100644
index 0000000000..9a44edceb4
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-eclim.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-elisp.el b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-elisp.el
new file mode 100644
index 0000000000..db1653da18
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-elisp.el
@@ -0,0 +1,226 @@
+;;; company-elisp.el --- company-mode completion backend for Emacs Lisp -*- lexical-binding: t -*-
+
+;; Copyright (C) 2009, 2011-2013, 2017  Free Software Foundation, Inc.
+
+;; Author: Nikolaj Schumacher
+
+;; 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:
+;;
+;; In newer versions of Emacs, company-capf is used instead.
+
+;;; Code:
+
+(require 'company)
+(require 'cl-lib)
+(require 'help-mode)
+(require 'find-func)
+
+(defgroup company-elisp nil
+  "Completion backend for Emacs Lisp."
+  :group 'company)
+
+(defcustom company-elisp-detect-function-context t
+  "If enabled, offer Lisp functions only in appropriate contexts.
+Functions are offered for completion only after ' and \(."
+  :type '(choice (const :tag "Off" nil)
+                 (const :tag "On" t)))
+
+(defcustom company-elisp-show-locals-first t
+  "If enabled, locally bound variables and functions are displayed
+first in the candidates list."
+  :type '(choice (const :tag "Off" nil)
+                 (const :tag "On" t)))
+
+(defun company-elisp--prefix ()
+  (let ((prefix (company-grab-symbol)))
+    (if prefix
+        (when (if (company-in-string-or-comment)
+                  (= (char-before (- (point) (length prefix))) ?`)
+                (company-elisp--should-complete))
+          prefix)
+      'stop)))
+
+(defun company-elisp--predicate (symbol)
+  (or (boundp symbol)
+      (fboundp symbol)
+      (facep symbol)
+      (featurep symbol)))
+
+(defun company-elisp--fns-regexp (&rest names)
+  (concat "\\_<\\(?:cl-\\)?" (regexp-opt names) "\\*?\\_>"))
+
+(defvar company-elisp-parse-limit 30)
+(defvar company-elisp-parse-depth 100)
+
+(defvar company-elisp-defun-names '("defun" "defmacro" "defsubst"))
+
+(defvar company-elisp-var-binding-regexp
+  (apply #'company-elisp--fns-regexp "let" "lambda" "lexical-let"
+         company-elisp-defun-names)
+  "Regular expression matching head of a multiple variable bindings form.")
+
+(defvar company-elisp-var-binding-regexp-1
+  (company-elisp--fns-regexp "dolist" "dotimes")
+  "Regular expression matching head of a form with one variable binding.")
+
+(defvar company-elisp-fun-binding-regexp
+  (company-elisp--fns-regexp "flet" "labels")
+  "Regular expression matching head of a function bindings form.")
+
+(defvar company-elisp-defuns-regexp
+  (concat "([ \t\n]*"
+          (apply #'company-elisp--fns-regexp company-elisp-defun-names)))
+
+(defun company-elisp--should-complete ()
+  (let ((start (point))
+        (depth (car (syntax-ppss))))
+    (not
+     (when (> depth 0)
+       (save-excursion
+         (up-list (- depth))
+         (when (looking-at company-elisp-defuns-regexp)
+           (forward-char)
+           (forward-sexp 1)
+           (unless (= (point) start)
+             (condition-case nil
+                 (let ((args-end (scan-sexps (point) 2)))
+                   (or (null args-end)
+                       (> args-end start)))
+               (scan-error
+                t)))))))))
+
+(defun company-elisp--locals (prefix functions-p)
+  (let ((regexp (concat "[ \t\n]*\\(\\_<" (regexp-quote prefix)
+                        "\\(?:\\sw\\|\\s_\\)*\\_>\\)"))
+        (pos (point))
+        res)
+    (condition-case nil
+        (save-excursion
+          (dotimes (_ company-elisp-parse-depth)
+            (up-list -1)
+            (save-excursion
+              (when (eq (char-after) ?\()
+                (forward-char 1)
+                (when (ignore-errors
+                        (save-excursion (forward-list)
+                                        (<= (point) pos)))
+                  (skip-chars-forward " \t\n")
+                  (cond
+                   ((looking-at (if functions-p
+                                    company-elisp-fun-binding-regexp
+                                  company-elisp-var-binding-regexp))
+                    (down-list 1)
+                    (condition-case nil
+                        (dotimes (_ company-elisp-parse-limit)
+                          (save-excursion
+                            (when (looking-at "[ \t\n]*(")
+                              (down-list 1))
+                            (when (looking-at regexp)
+                              (cl-pushnew (match-string-no-properties 1) res)))
+                          (forward-sexp))
+                      (scan-error nil)))
+                   ((unless functions-p
+                      (looking-at company-elisp-var-binding-regexp-1))
+                    (down-list 1)
+                    (when (looking-at regexp)
+                      (cl-pushnew (match-string-no-properties 1) res)))))))))
+      (scan-error nil))
+    res))
+
+(defun company-elisp-candidates (prefix)
+  (let* ((predicate (company-elisp--candidates-predicate prefix))
+         (locals (company-elisp--locals prefix (eq predicate 'fboundp)))
+         (globals (company-elisp--globals prefix predicate))
+         (locals (cl-loop for local in locals
+                          when (not (member local globals))
+                          collect local)))
+    (if company-elisp-show-locals-first
+        (append (sort locals 'string<)
+                (sort globals 'string<))
+      (append locals globals))))
+
+(defun company-elisp--globals (prefix predicate)
+  (all-completions prefix obarray predicate))
+
+(defun company-elisp--candidates-predicate (prefix)
+  (let* ((completion-ignore-case nil)
+         (beg (- (point) (length prefix)))
+         (before (char-before beg)))
+    (if (and company-elisp-detect-function-context
+             (not (memq before '(?' ?`))))
+        (if (and (eq before ?\()
+                 (not
+                  (save-excursion
+                    (ignore-errors
+                      (goto-char (1- beg))
+                      (or (company-elisp--before-binding-varlist-p)
+                          (progn
+                            (up-list -1)
+                            (company-elisp--before-binding-varlist-p)))))))
+            'fboundp
+          'boundp)
+      'company-elisp--predicate)))
+
+(defun company-elisp--before-binding-varlist-p ()
+  (save-excursion
+    (and (prog1 (search-backward "(")
+           (forward-char 1))
+         (looking-at company-elisp-var-binding-regexp))))
+
+(defun company-elisp--doc (symbol)
+  (let* ((symbol (intern symbol))
+         (doc (if (fboundp symbol)
+                  (documentation symbol t)
+                (documentation-property symbol 'variable-documentation t))))
+    (and (stringp doc)
+         (string-match ".*$" doc)
+         (match-string 0 doc))))
+
+;;;###autoload
+(defun company-elisp (command &optional arg &rest ignored)
+  "`company-mode' completion backend for Emacs Lisp."
+  (interactive (list 'interactive))
+  (cl-case command
+    (interactive (company-begin-backend 'company-elisp))
+    (prefix (and (derived-mode-p 'emacs-lisp-mode 'inferior-emacs-lisp-mode)
+                 (company-elisp--prefix)))
+    (candidates (company-elisp-candidates arg))
+    (sorted company-elisp-show-locals-first)
+    (meta (company-elisp--doc arg))
+    (doc-buffer (let ((symbol (intern arg)))
+                  (save-window-excursion
+                    (ignore-errors
+                      (cond
+                       ((fboundp symbol) (describe-function symbol))
+                       ((boundp symbol) (describe-variable symbol))
+                       ((featurep symbol) (describe-package symbol))
+                       ((facep symbol) (describe-face symbol))
+                       (t (signal 'user-error nil)))
+                      (help-buffer)))))
+    (location (let ((sym (intern arg)))
+                (cond
+                 ((fboundp sym) (find-definition-noselect sym nil))
+                 ((boundp sym) (find-definition-noselect sym 'defvar))
+                 ((featurep sym) (cons (find-file-noselect (find-library-name
+                                                            (symbol-name sym)))
+                                       0))
+                 ((facep sym) (find-definition-noselect sym 'defface)))))))
+
+(provide 'company-elisp)
+;;; company-elisp.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-elisp.elc b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-elisp.elc
new file mode 100644
index 0000000000..e80cb8f912
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-elisp.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-etags.el b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-etags.el
new file mode 100644
index 0000000000..d0c27c9c3c
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-etags.el
@@ -0,0 +1,108 @@
+;;; company-etags.el --- company-mode completion backend for etags
+
+;; Copyright (C) 2009-2011, 2014  Free Software Foundation, Inc.
+
+;; Author: Nikolaj Schumacher
+
+;; 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:
+;;
+
+;;; Code:
+
+(require 'company)
+(require 'cl-lib)
+(require 'etags)
+
+(defgroup company-etags nil
+  "Completion backend for etags."
+  :group 'company)
+
+(defcustom company-etags-use-main-table-list t
+  "Always search `tags-table-list' if set.
+If this is disabled, `company-etags' will try to find the one table for each
+buffer automatically."
+  :type '(choice (const :tag "off" nil)
+                 (const :tag "on" t)))
+
+(defcustom company-etags-ignore-case nil
+  "Non-nil to ignore case in completion candidates."
+  :type 'boolean
+  :package-version '(company . "0.7.3"))
+
+(defcustom company-etags-everywhere nil
+  "Non-nil to offer completions in comments and strings.
+Set it to t or to a list of major modes."
+  :type '(choice (const :tag "Off" nil)
+                 (const :tag "Any supported mode" t)
+                 (repeat :tag "Some major modes"
+                         (symbol :tag "Major mode")))
+  :package-version '(company . "0.9.0"))
+
+(defvar company-etags-modes '(prog-mode c-mode objc-mode c++-mode java-mode
+                              jde-mode pascal-mode perl-mode python-mode))
+
+(defvar-local company-etags-buffer-table 'unknown)
+
+(defun company-etags-find-table ()
+  (let ((file (expand-file-name
+               "TAGS"
+               (locate-dominating-file (or buffer-file-name
+                                           default-directory)
+                                       "TAGS"))))
+    (when (and file (file-regular-p file))
+      (list file))))
+
+(defun company-etags-buffer-table ()
+  (or (and company-etags-use-main-table-list tags-table-list)
+      (if (eq company-etags-buffer-table 'unknown)
+          (setq company-etags-buffer-table (company-etags-find-table))
+        company-etags-buffer-table)))
+
+(defun company-etags--candidates (prefix)
+  (let ((tags-table-list (company-etags-buffer-table))
+        (tags-file-name tags-file-name)
+        (completion-ignore-case company-etags-ignore-case))
+    (and (or tags-file-name tags-table-list)
+         (fboundp 'tags-completion-table)
+         (save-excursion
+           (visit-tags-table-buffer)
+           (all-completions prefix (tags-completion-table))))))
+
+;;;###autoload
+(defun company-etags (command &optional arg &rest ignored)
+  "`company-mode' completion backend for etags."
+  (interactive (list 'interactive))
+  (cl-case command
+    (interactive (company-begin-backend 'company-etags))
+    (prefix (and (apply #'derived-mode-p company-etags-modes)
+                 (or (eq t company-etags-everywhere)
+                     (apply #'derived-mode-p company-etags-everywhere)
+                     (not (company-in-string-or-comment)))
+                 (company-etags-buffer-table)
+                 (or (company-grab-symbol) 'stop)))
+    (candidates (company-etags--candidates arg))
+    (location (let ((tags-table-list (company-etags-buffer-table)))
+                (when (fboundp 'find-tag-noselect)
+                  (save-excursion
+                    (let ((buffer (find-tag-noselect arg)))
+                      (cons buffer (with-current-buffer buffer (point))))))))
+    (ignore-case company-etags-ignore-case)))
+
+(provide 'company-etags)
+;;; company-etags.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-etags.elc b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-etags.elc
new file mode 100644
index 0000000000..ba26bf397c
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-etags.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-files.el b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-files.el
new file mode 100644
index 0000000000..c6102a1b06
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-files.el
@@ -0,0 +1,148 @@
+;;; company-files.el --- company-mode completion backend for file names
+
+;; Copyright (C) 2009-2011, 2014-2015  Free Software Foundation, Inc.
+
+;; Author: Nikolaj Schumacher
+
+;; 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:
+;;
+
+;;; Code:
+
+(require 'company)
+(require 'cl-lib)
+
+(defgroup company-files nil
+  "Completion backend for file names."
+  :group 'company)
+
+(defcustom company-files-exclusions nil
+  "File name extensions and directory names to ignore.
+The values should use the same format as `completion-ignored-extensions'."
+  :type '(const string)
+  :package-version '(company . "0.9.1"))
+
+(defun company-files--directory-files (dir prefix)
+  ;; Don't use directory-files. It produces directories without trailing /.
+  (condition-case err
+      (let ((comp (sort (file-name-all-completions prefix dir)
+                        (lambda (s1 s2) (string-lessp (downcase s1) (downcase s2))))))
+        (when company-files-exclusions
+          (setq comp (company-files--exclusions-filtered comp)))
+        (if (equal prefix "")
+            (delete "../" (delete "./" comp))
+          comp))
+    (file-error nil)))
+
+(defun company-files--exclusions-filtered (completions)
+  (let* ((dir-exclusions (cl-delete-if-not #'company-files--trailing-slash-p
+                                           company-files-exclusions))
+         (file-exclusions (cl-set-difference company-files-exclusions
+                                             dir-exclusions)))
+    (cl-loop for c in completions
+             unless (if (company-files--trailing-slash-p c)
+                        (member c dir-exclusions)
+                      (cl-find-if (lambda (exclusion)
+                                    (string-suffix-p exclusion c))
+                                  file-exclusions))
+             collect c)))
+
+(defvar company-files--regexps
+  (let* ((root (if (eq system-type 'windows-nt)
+                   "[a-zA-Z]:/"
+                 "/"))
+         (begin (concat "\\(?:\\.\\{1,2\\}/\\|~/\\|" root "\\)")))
+    (list (concat "\"\\(" begin "[^\"\n]*\\)")
+          (concat "\'\\(" begin "[^\'\n]*\\)")
+          (concat "\\(?:[ \t=]\\|^\\)\\(" begin "[^ \t\n]*\\)"))))
+
+(defun company-files--grab-existing-name ()
+  ;; Grab the file name.
+  ;; When surrounded with quotes, it can include spaces.
+  (let (file dir)
+    (and (cl-dolist (regexp company-files--regexps)
+           (when (setq file (company-grab-line regexp 1))
+             (cl-return file)))
+         (company-files--connected-p file)
+         (setq dir (file-name-directory file))
+         (not (string-match "//" dir))
+         (file-exists-p dir)
+         file)))
+
+(defun company-files--connected-p (file)
+  (or (not (file-remote-p file))
+      (file-remote-p file nil t)))
+
+(defun company-files--trailing-slash-p (file)
+  ;; `file-directory-p' is very expensive on remotes. We are relying on
+  ;; `file-name-all-completions' returning directories with trailing / instead.
+  (let ((len (length file)))
+    (and (> len 0) (eq (aref file (1- len)) ?/))))
+
+(defvar company-files--completion-cache nil)
+
+(defun company-files--complete (prefix)
+  (let* ((dir (file-name-directory prefix))
+         (file (file-name-nondirectory prefix))
+         (key (list file
+                    (expand-file-name dir)
+                    (nth 5 (file-attributes dir))))
+         (completion-ignore-case read-file-name-completion-ignore-case))
+    (unless (company-file--keys-match-p key (car company-files--completion-cache))
+      (let* ((candidates (mapcar (lambda (f) (concat dir f))
+                                 (company-files--directory-files dir file)))
+             (directories (unless (file-remote-p dir)
+                            (cl-remove-if-not (lambda (f)
+                                                (and (company-files--trailing-slash-p f)
+                                                     (not (file-remote-p f))
+                                                     (company-files--connected-p f)))
+                                              candidates)))
+             (children (and directories
+                            (cl-mapcan (lambda (d)
+                                         (mapcar (lambda (c) (concat d c))
+                                                 (company-files--directory-files d "")))
+                                       directories))))
+        (setq company-files--completion-cache
+              (cons key (append candidates children)))))
+    (all-completions prefix
+                     (cdr company-files--completion-cache))))
+
+(defun company-file--keys-match-p (new old)
+  (and (equal (cdr old) (cdr new))
+       (string-prefix-p (car old) (car new))))
+
+;;;###autoload
+(defun company-files (command &optional arg &rest ignored)
+  "`company-mode' completion backend existing file names.
+Completions works for proper absolute and relative files paths.
+File paths with spaces are only supported inside strings."
+  (interactive (list 'interactive))
+  (cl-case command
+    (interactive (company-begin-backend 'company-files))
+    (prefix (company-files--grab-existing-name))
+    (candidates (company-files--complete arg))
+    (location (cons (dired-noselect
+                     (file-name-directory (directory-file-name arg))) 1))
+    (post-completion (when (company-files--trailing-slash-p arg)
+                       (delete-char -1)))
+    (sorted t)
+    (no-cache t)))
+
+(provide 'company-files)
+;;; company-files.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-files.elc b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-files.elc
new file mode 100644
index 0000000000..b0b2dffd96
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-files.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-gtags.el b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-gtags.el
new file mode 100644
index 0000000000..02513ca019
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-gtags.el
@@ -0,0 +1,117 @@
+;;; company-gtags.el --- company-mode completion backend for GNU Global
+
+;; Copyright (C) 2009-2011, 2014  Free Software Foundation, Inc.
+
+;; Author: Nikolaj Schumacher
+
+;; 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:
+;;
+
+;;; Code:
+
+(require 'company)
+(require 'company-template)
+(require 'cl-lib)
+
+(defgroup company-gtags nil
+  "Completion backend for GNU Global."
+  :group 'company)
+
+(defcustom company-gtags-executable
+  (executable-find "global")
+  "Location of GNU global executable."
+  :type 'string)
+
+(define-obsolete-variable-alias
+  'company-gtags-gnu-global-program-name
+  'company-gtags-executable "earlier")
+
+(defcustom company-gtags-insert-arguments t
+  "When non-nil, insert function arguments as a template after completion."
+  :type 'boolean
+  :package-version '(company . "0.8.1"))
+
+(defvar-local company-gtags--tags-available-p 'unknown)
+
+(defcustom company-gtags-modes '(prog-mode jde-mode)
+  "Modes that use `company-gtags'.
+In all these modes (and their derivatives) `company-gtags' will perform
+completion."
+  :type '(repeat (symbol :tag "Major mode"))
+  :package-version '(company . "0.8.4"))
+
+(defun company-gtags--tags-available-p ()
+  (if (eq company-gtags--tags-available-p 'unknown)
+      (setq company-gtags--tags-available-p
+            (locate-dominating-file buffer-file-name "GTAGS"))
+    company-gtags--tags-available-p))
+
+(defun company-gtags--fetch-tags (prefix)
+  (with-temp-buffer
+    (let (tags)
+      (when (= 0 (process-file company-gtags-executable nil
+                               ;; "-T" goes through all the tag files listed in GTAGSLIBPATH
+                               (list (current-buffer) nil) nil "-xGqT" (concat "^" prefix)))
+        (goto-char (point-min))
+        (cl-loop while
+                 (re-search-forward (concat
+                                     "^"
+                                     "\\([^ ]*\\)" ;; completion
+                                     "[ \t]+\\([[:digit:]]+\\)" ;; linum
+                                     "[ \t]+\\([^ \t]+\\)" ;; file
+                                     "[ \t]+\\(.*\\)" ;; definition
+                                     "$"
+                                     ) nil t)
+                 collect
+                 (propertize (match-string 1)
+                             'meta (match-string 4)
+                             'location (cons (expand-file-name (match-string 3))
+                                             (string-to-number (match-string 2)))
+                             ))))))
+
+(defun company-gtags--annotation (arg)
+  (let ((meta (get-text-property 0 'meta arg)))
+    (when (string-match (concat arg "\\((.*)\\).*") meta)
+      (match-string 1 meta))))
+
+;;;###autoload
+(defun company-gtags (command &optional arg &rest ignored)
+  "`company-mode' completion backend for GNU Global."
+  (interactive (list 'interactive))
+  (cl-case command
+    (interactive (company-begin-backend 'company-gtags))
+    (prefix (and company-gtags-executable
+                 buffer-file-name
+                 (apply #'derived-mode-p company-gtags-modes)
+                 (not (company-in-string-or-comment))
+                 (company-gtags--tags-available-p)
+                 (or (company-grab-symbol) 'stop)))
+    (candidates (company-gtags--fetch-tags arg))
+    (sorted t)
+    (duplicates t)
+    (annotation (company-gtags--annotation arg))
+    (meta (get-text-property 0 'meta arg))
+    (location (get-text-property 0 'location arg))
+    (post-completion (let ((anno (company-gtags--annotation arg)))
+                       (when (and company-gtags-insert-arguments anno)
+                         (insert anno)
+                         (company-template-c-like-templatify anno))))))
+
+(provide 'company-gtags)
+;;; company-gtags.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-gtags.elc b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-gtags.elc
new file mode 100644
index 0000000000..23ee9c63b2
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-gtags.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-ispell.el b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-ispell.el
new file mode 100644
index 0000000000..c275bbe410
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-ispell.el
@@ -0,0 +1,82 @@
+;;; company-ispell.el --- company-mode completion backend using Ispell
+
+;; Copyright (C) 2009-2011, 2013-2016  Free Software Foundation, Inc.
+
+;; Author: Nikolaj Schumacher
+
+;; 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:
+;;
+
+;;; Code:
+
+(require 'company)
+(require 'cl-lib)
+(require 'ispell)
+
+(defgroup company-ispell nil
+  "Completion backend using Ispell."
+  :group 'company)
+
+(defcustom company-ispell-dictionary nil
+  "Dictionary to use for `company-ispell'.
+If nil, use `ispell-complete-word-dict'."
+  :type '(choice (const :tag "default (nil)" nil)
+                 (file :tag "dictionary" t)))
+
+(defvar company-ispell-available 'unknown)
+
+(defalias 'company-ispell--lookup-words
+  (if (fboundp 'ispell-lookup-words)
+      'ispell-lookup-words
+    'lookup-words))
+
+(defun company-ispell-available ()
+  (when (eq company-ispell-available 'unknown)
+    (condition-case err
+        (progn
+          (company-ispell--lookup-words "WHATEVER")
+          (setq company-ispell-available t))
+      (error
+       (message "Company: ispell-look-command not found")
+       (setq company-ispell-available nil))))
+  company-ispell-available)
+
+;;;###autoload
+(defun company-ispell (command &optional arg &rest ignored)
+  "`company-mode' completion backend using Ispell."
+  (interactive (list 'interactive))
+  (cl-case command
+    (interactive (company-begin-backend 'company-ispell))
+    (prefix (when (company-ispell-available)
+              (company-grab-word)))
+    (candidates
+     (let ((words (company-ispell--lookup-words
+                   arg
+                   (or company-ispell-dictionary ispell-complete-word-dict)))
+           (completion-ignore-case t))
+       (if (string= arg "")
+           ;; Small optimization.
+           words
+         ;; Work around issue #284.
+         (all-completions arg words))))
+    (sorted t)
+    (ignore-case 'keep-prefix)))
+
+(provide 'company-ispell)
+;;; company-ispell.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-ispell.elc b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-ispell.elc
new file mode 100644
index 0000000000..3c773810f3
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-ispell.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-keywords.el b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-keywords.el
new file mode 100644
index 0000000000..2ba12fe537
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-keywords.el
@@ -0,0 +1,300 @@
+;;; company-keywords.el --- A company backend for programming language keywords
+
+;; Copyright (C) 2009-2011, 2016  Free Software Foundation, Inc.
+
+;; Author: Nikolaj Schumacher
+
+;; 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:
+;;
+
+;;; Code:
+
+(require 'company)
+(require 'cl-lib)
+
+(defun company-keywords-upper-lower (&rest lst)
+  ;; Upcase order is different for _.
+  (nconc (sort (mapcar 'upcase lst) 'string<) lst))
+
+(defvar company-keywords-alist
+  ;; Please contribute corrections or additions.
+  `((c++-mode
+     "alignas" "alignof" "asm" "auto" "bool" "break" "case" "catch" "char"
+     "char16_t" "char32_t" "class" "const" "const_cast" "constexpr" "continue"
+     "decltype" "default" "delete" "do" "double" "dynamic_cast" "else" "enum"
+     "explicit" "export" "extern" "false" "final" "float" "for" "friend"
+     "goto" "if" "inline" "int" "long" "mutable" "namespace" "new" "noexcept"
+     "nullptr" "operator" "override"
+     "private" "protected" "public" "register" "reinterpret_cast"
+     "return" "short" "signed" "sizeof" "static" "static_assert"
+     "static_cast" "struct" "switch" "template" "this" "thread_local"
+     "throw" "true" "try" "typedef" "typeid" "typename"
+     "union" "unsigned" "using" "virtual" "void" "volatile" "wchar_t" "while")
+    (c-mode
+     "auto" "break" "case" "char" "const" "continue" "default" "do"
+     "double" "else" "enum" "extern" "float" "for" "goto" "if" "int" "long"
+     "register" "return" "short" "signed" "sizeof" "static" "struct"
+     "switch" "typedef" "union" "unsigned" "void" "volatile" "while")
+    (csharp-mode
+     "abstract" "add" "alias" "as" "base" "bool" "break" "byte" "case"
+     "catch" "char" "checked" "class" "const" "continue" "decimal" "default"
+     "delegate" "do" "double" "else" "enum" "event" "explicit" "extern"
+     "false" "finally" "fixed" "float" "for" "foreach" "get" "global" "goto"
+     "if" "implicit" "in" "int" "interface" "internal" "is" "lock" "long"
+     "namespace" "new" "null" "object" "operator" "out" "override" "params"
+     "partial" "private" "protected" "public" "readonly" "ref" "remove"
+     "return" "sbyte" "sealed" "set" "short" "sizeof" "stackalloc" "static"
+     "string" "struct" "switch" "this" "throw" "true" "try" "typeof" "uint"
+     "ulong" "unchecked" "unsafe" "ushort" "using" "value" "var" "virtual"
+     "void" "volatile" "where" "while" "yield")
+    (d-mode
+     ;; from http://www.digitalmars.com/d/2.0/lex.html
+     "abstract" "alias" "align" "asm"
+     "assert" "auto" "body" "bool" "break" "byte" "case" "cast" "catch"
+     "cdouble" "cent" "cfloat" "char" "class" "const" "continue" "creal"
+     "dchar" "debug" "default" "delegate" "delete" "deprecated" "do"
+     "double" "else" "enum" "export" "extern" "false" "final" "finally"
+     "float" "for" "foreach" "foreach_reverse" "function" "goto" "idouble"
+     "if" "ifloat" "import" "in" "inout" "int" "interface" "invariant"
+     "ireal" "is" "lazy" "long" "macro" "mixin" "module" "new" "nothrow"
+     "null" "out" "override" "package" "pragma" "private" "protected"
+     "public" "pure" "real" "ref" "return" "scope" "short" "static" "struct"
+     "super" "switch" "synchronized" "template" "this" "throw" "true" "try"
+     "typedef" "typeid" "typeof" "ubyte" "ucent" "uint" "ulong" "union"
+     "unittest" "ushort" "version" "void" "volatile" "wchar" "while" "with")
+    (f90-mode .
+     ;; from f90.el
+     ;; ".AND." ".GE." ".GT." ".LT." ".LE." ".NE." ".OR." ".TRUE." ".FALSE."
+     ,(company-keywords-upper-lower
+      "abs" "abstract" "achar" "acos" "adjustl" "adjustr" "aimag" "aint"
+      "align" "all" "all_prefix" "all_scatter" "all_suffix" "allocatable"
+      "allocate" "allocated" "and" "anint" "any" "any_prefix" "any_scatter"
+      "any_suffix" "asin" "assign" "assignment" "associate" "associated"
+      "asynchronous" "atan" "atan2" "backspace" "bind" "bit_size" "block"
+      "btest" "c_alert" "c_associated" "c_backspace" "c_bool"
+      "c_carriage_return" "c_char" "c_double" "c_double_complex" "c_f_pointer"
+      "c_f_procpointer" "c_float" "c_float_complex" "c_form_feed" "c_funloc"
+      "c_funptr" "c_horizontal_tab" "c_int" "c_int16_t" "c_int32_t" "c_int64_t"
+      "c_int8_t" "c_int_fast16_t" "c_int_fast32_t" "c_int_fast64_t"
+      "c_int_fast8_t" "c_int_least16_t" "c_int_least32_t" "c_int_least64_t"
+      "c_int_least8_t" "c_intmax_t" "c_intptr_t" "c_loc" "c_long"
+      "c_long_double" "c_long_double_complex" "c_long_long" "c_new_line"
+      "c_null_char" "c_null_funptr" "c_null_ptr" "c_ptr" "c_short"
+      "c_signed_char" "c_size_t" "c_vertical_tab" "call" "case" "ceiling"
+      "char" "character" "character_storage_size" "class" "close" "cmplx"
+      "command_argument_count" "common" "complex" "conjg" "contains" "continue"
+      "copy_prefix" "copy_scatter" "copy_suffix" "cos" "cosh" "count"
+      "count_prefix" "count_scatter" "count_suffix" "cpu_time" "cshift"
+      "cycle" "cyclic" "data" "date_and_time" "dble" "deallocate" "deferred"
+      "digits" "dim" "dimension" "distribute" "do" "dot_product" "double"
+      "dprod" "dynamic" "elemental" "else" "elseif" "elsewhere" "end" "enddo"
+      "endfile" "endif" "entry" "enum" "enumerator" "eoshift" "epsilon" "eq"
+      "equivalence" "eqv" "error_unit" "exit" "exp" "exponent" "extends"
+      "extends_type_of" "external" "extrinsic" "false" "file_storage_size"
+      "final" "floor" "flush" "forall" "format" "fraction" "function" "ge"
+      "generic" "get_command" "get_command_argument" "get_environment_variable"
+      "goto" "grade_down" "grade_up" "gt" "hpf_alignment" "hpf_distribution"
+      "hpf_template" "huge" "iachar" "iall" "iall_prefix" "iall_scatter"
+      "iall_suffix" "iand" "iany" "iany_prefix" "iany_scatter" "iany_suffix"
+      "ibclr" "ibits" "ibset" "ichar" "ieee_arithmetic" "ieee_exceptions"
+      "ieee_features" "ieee_get_underflow_mode" "ieee_set_underflow_mode"
+      "ieee_support_underflow_control" "ieor" "if" "ilen" "implicit"
+      "import" "include" "independent" "index" "inherit" "input_unit"
+      "inquire" "int" "integer" "intent" "interface" "intrinsic" "ior"
+      "iostat_end" "iostat_eor" "iparity" "iparity_prefix" "iparity_scatter"
+      "iparity_suffix" "ishft" "ishftc" "iso_c_binding" "iso_fortran_env"
+      "kind" "lbound" "le" "leadz" "len" "len_trim" "lge" "lgt" "lle" "llt"
+      "log" "log10" "logical" "lt" "matmul" "max" "maxexponent" "maxloc"
+      "maxval" "maxval_prefix" "maxval_scatter" "maxval_suffix" "merge"
+      "min" "minexponent" "minloc" "minval" "minval_prefix" "minval_scatter"
+      "minval_suffix" "mod" "module" "modulo" "move_alloc" "mvbits" "namelist"
+      "ne" "nearest" "neqv" "new" "new_line" "nint" "non_intrinsic"
+      "non_overridable" "none" "nopass" "not" "null" "nullify"
+      "number_of_processors" "numeric_storage_size" "only" "onto" "open"
+      "operator" "optional" "or" "output_unit" "pack" "parameter" "parity"
+      "parity_prefix" "parity_scatter" "parity_suffix" "pass" "pause"
+      "pointer" "popcnt" "poppar" "precision" "present" "print" "private"
+      "procedure" "processors" "processors_shape" "product" "product_prefix"
+      "product_scatter" "product_suffix" "program" "protected" "public"
+      "pure" "radix" "random_number" "random_seed" "range" "read" "real"
+      "realign" "recursive" "redistribute" "repeat" "reshape" "result"
+      "return" "rewind" "rrspacing" "same_type_as" "save" "scale" "scan"
+      "select" "selected_char_kind" "selected_int_kind" "selected_real_kind"
+      "sequence" "set_exponent" "shape" "sign" "sin" "sinh" "size" "spacing"
+      "spread" "sqrt" "stop" "subroutine" "sum" "sum_prefix" "sum_scatter"
+      "sum_suffix" "system_clock" "tan" "tanh" "target" "template" "then"
+      "tiny" "transfer" "transpose" "trim" "true" "type" "ubound" "unpack"
+      "use" "value" "verify" "volatile" "wait" "where" "while" "with" "write"))
+    (java-mode
+     "abstract" "assert" "boolean" "break" "byte" "case" "catch" "char" "class"
+     "continue" "default" "do" "double" "else" "enum" "extends" "final"
+     "finally" "float" "for" "if" "implements" "import" "instanceof" "int"
+     "interface" "long" "native" "new" "package" "private" "protected" "public"
+     "return" "short" "static" "strictfp" "super" "switch" "synchronized"
+     "this" "throw" "throws" "transient" "try" "void" "volatile" "while")
+    (javascript-mode
+     ;; https://tc39.github.io/ecma262/ + async, static and undefined
+     "async" "await" "break" "case" "catch" "class" "const" "continue"
+     "debugger" "default" "delete" "do" "else" "enum" "export" "extends" "false"
+     "finally" "for" "function" "if" "import" "in" "instanceof" "let" "new"
+     "null" "return" "static" "super" "switch" "this" "throw" "true" "try"
+     "typeof" "undefined" "var" "void" "while" "with" "yield")
+    (kotlin-mode
+     "abstract" "annotation" "as" "break" "by" "catch" "class" "companion"
+     "const" "constructor" "continue" "data" "do" "else" "enum" "false" "final"
+     "finally" "for" "fun" "if" "import" "in" "init" "inner" "interface"
+     "internal" "is" "lateinit" "nested" "null" "object" "open" "out" "override"
+     "package" "private" "protected" "public" "return" "super" "this" "throw"
+     "trait" "true" "try" "typealias" "val" "var" "when" "while")
+    (objc-mode
+     "@catch" "@class" "@encode" "@end" "@finally" "@implementation"
+     "@interface" "@private" "@protected" "@protocol" "@public"
+     "@selector" "@synchronized" "@throw" "@try" "alloc" "autorelease"
+     "bycopy" "byref" "in" "inout" "oneway" "out" "release" "retain")
+    (perl-mode
+     ;; from cperl.el
+     "AUTOLOAD" "BEGIN" "CHECK" "CORE" "DESTROY" "END" "INIT" "__END__"
+     "__FILE__" "__LINE__" "abs" "accept" "alarm" "and" "atan2" "bind"
+     "binmode" "bless" "caller" "chdir" "chmod" "chomp" "chop" "chown" "chr"
+     "chroot" "close" "closedir" "cmp" "connect" "continue" "cos"
+     "crypt" "dbmclose" "dbmopen" "defined" "delete" "die" "do" "dump" "each"
+     "else" "elsif" "endgrent" "endhostent" "endnetent" "endprotoent"
+     "endpwent" "endservent" "eof" "eq" "eval" "exec" "exists" "exit" "exp"
+     "fcntl" "fileno" "flock" "for" "foreach" "fork" "format" "formline"
+     "ge" "getc" "getgrent" "getgrgid" "getgrnam" "gethostbyaddr"
+     "gethostbyname" "gethostent" "getlogin" "getnetbyaddr" "getnetbyname"
+     "getnetent" "getpeername" "getpgrp" "getppid" "getpriority"
+     "getprotobyname" "getprotobynumber" "getprotoent" "getpwent" "getpwnam"
+     "getpwuid" "getservbyname" "getservbyport" "getservent" "getsockname"
+     "getsockopt" "glob" "gmtime" "goto" "grep" "gt" "hex" "if" "index" "int"
+     "ioctl" "join" "keys" "kill" "last" "lc" "lcfirst" "le" "length"
+     "link" "listen" "local" "localtime" "lock" "log" "lstat" "lt" "map"
+     "mkdir" "msgctl" "msgget" "msgrcv" "msgsnd" "my" "ne" "next" "no"
+     "not" "oct" "open" "opendir" "or" "ord" "our" "pack" "package" "pipe"
+     "pop" "pos" "print" "printf" "push" "q" "qq" "quotemeta" "qw" "qx"
+     "rand" "read" "readdir" "readline" "readlink" "readpipe" "recv" "redo"
+     "ref" "rename" "require" "reset" "return" "reverse" "rewinddir" "rindex"
+     "rmdir" "scalar" "seek" "seekdir" "select" "semctl" "semget" "semop"
+     "send" "setgrent" "sethostent" "setnetent" "setpgrp" "setpriority"
+     "setprotoent" "setpwent" "setservent" "setsockopt" "shift" "shmctl"
+     "shmget" "shmread" "shmwrite" "shutdown" "sin" "sleep" "socket"
+     "socketpair" "sort" "splice" "split" "sprintf" "sqrt" "srand" "stat"
+     "study" "sub" "substr" "symlink" "syscall" "sysopen" "sysread" "system"
+     "syswrite" "tell" "telldir" "tie" "time" "times" "tr" "truncate" "uc"
+     "ucfirst" "umask" "undef" "unless" "unlink" "unpack" "unshift" "untie"
+     "until" "use" "utime" "values" "vec" "wait" "waitpid"
+     "wantarray" "warn" "while" "write" "x" "xor" "y")
+    (php-mode
+     "__CLASS__" "__DIR__" "__FILE__" "__FUNCTION__" "__LINE__" "__METHOD__"
+     "__NAMESPACE__" "_once" "abstract" "and" "array" "as" "break" "case"
+     "catch" "cfunction" "class" "clone" "const" "continue" "declare"
+     "default" "die" "do" "echo" "else" "elseif" "empty" "enddeclare"
+     "endfor" "endforeach" "endif" "endswitch" "endwhile" "eval" "exception"
+     "exit" "extends" "final" "for" "foreach" "function" "global"
+     "goto" "if" "implements" "include" "instanceof" "interface"
+     "isset" "list" "namespace" "new" "old_function" "or" "php_user_filter"
+     "print" "private" "protected" "public" "require" "require_once" "return"
+     "static" "switch" "this" "throw" "try" "unset" "use" "var" "while" "xor")
+    (python-mode
+     ;; https://docs.python.org/3/reference/lexical_analysis.html#keywords
+     "False" "None" "True" "and" "as" "assert" "break" "class" "continue" "def"
+     "del" "elif" "else" "except" "exec" "finally" "for" "from" "global" "if"
+     "import" "in" "is" "lambda" "nonlocal" "not" "or" "pass" "print" "raise"
+     "return" "try" "while" "with" "yield")
+    (ruby-mode
+     "BEGIN" "END" "alias" "and"  "begin" "break" "case" "class" "def" "defined?"
+     "do" "else" "elsif"  "end" "ensure" "false" "for" "if" "in" "module"
+     "next" "nil" "not" "or" "redo" "rescue" "retry" "return" "self" "super"
+     "then" "true" "undef" "unless" "until" "when" "while" "yield")
+    ;; From https://doc.rust-lang.org/grammar.html#keywords
+    ;; but excluding unused reserved words: https://www.reddit.com/r/rust/comments/34fq0k/is_there_a_good_list_of_rusts_keywords/cqucvnj
+    (go-mode
+     "break" "case" "chan" "const" "continue" "default" "defer" "else" "fallthrough"
+     "for" "func" "go" "goto" "if" "import" "interface" "map" "package" "range"
+     "return" "select" "struct" "switch" "type" "var")
+    (rust-mode
+     "Self"
+     "as" "box" "break" "const" "continue" "crate" "else" "enum" "extern"
+     "false" "fn" "for" "if" "impl" "in" "let" "loop" "macro" "match" "mod"
+     "move" "mut" "pub" "ref" "return" "self" "static" "struct" "super"
+     "trait" "true" "type" "unsafe" "use" "where" "while")
+    (scala-mode
+     "abstract" "case" "catch" "class" "def" "do" "else" "extends" "false"
+     "final" "finally" "for" "forSome" "if" "implicit" "import" "lazy" "match"
+     "new" "null" "object" "override" "package" "private" "protected"
+     "return" "sealed" "super" "this" "throw" "trait" "true" "try" "type" "val"
+     "var" "while" "with" "yield")
+    (swift-mode
+     "Protocol" "Self" "Type" "and" "as" "assignment" "associatedtype"
+     "associativity" "available" "break" "case" "catch" "class" "column" "continue"
+     "convenience" "default" "defer" "deinit" "didSet" "do" "dynamic" "dynamicType"
+     "else" "elseif" "endif" "enum" "extension" "fallthrough" "false" "file"
+     "fileprivate" "final" "for" "func" "function" "get" "guard" "higherThan" "if"
+     "import" "in" "indirect" "infix" "init" "inout" "internal" "is" "lazy" "left"
+     "let" "line" "lowerThan" "mutating" "nil" "none" "nonmutating" "open"
+     "operator" "optional" "override" "postfix" "precedence" "precedencegroup"
+     "prefix" "private" "protocol" "public" "repeat" "required" "rethrows" "return"
+     "right" "selector" "self" "set" "static" "struct" "subscript" "super" "switch"
+     "throw" "throws" "true" "try" "typealias" "unowned" "var" "weak" "where"
+     "while" "willSet")
+    (julia-mode
+     "abstract" "break" "case" "catch" "const" "continue" "do" "else" "elseif"
+     "end" "eval" "export" "false" "finally" "for" "function" "global" "if"
+     "ifelse" "immutable" "import" "importall" "in" "let" "macro" "module"
+     "otherwise" "quote" "return" "switch" "throw" "true" "try" "type"
+     "typealias" "using" "while"
+     )
+    ;; From https://github.com/apache/thrift/blob/master/contrib/thrift.el
+    (thrift-mode
+     "binary" "bool" "byte" "const" "double" "enum" "exception" "extends"
+     "i16" "i32" "i64" "include" "list" "map" "oneway" "optional" "required"
+     "service" "set" "string" "struct" "throws" "typedef" "void"
+     )
+    ;; aliases
+    (js2-mode . javascript-mode)
+    (js2-jsx-mode . javascript-mode)
+    (espresso-mode . javascript-mode)
+    (js-mode . javascript-mode)
+    (js-jsx-mode . javascript-mode)
+    (rjsx-mode . javascript-mode)
+    (cperl-mode . perl-mode)
+    (jde-mode . java-mode)
+    (ess-julia-mode . julia-mode)
+    (enh-ruby-mode . ruby-mode))
+  "Alist mapping major-modes to sorted keywords for `company-keywords'.")
+
+;;;###autoload
+(defun company-keywords (command &optional arg &rest ignored)
+  "`company-mode' backend for programming language keywords."
+  (interactive (list 'interactive))
+  (cl-case command
+    (interactive (company-begin-backend 'company-keywords))
+    (prefix (and (assq major-mode company-keywords-alist)
+                 (not (company-in-string-or-comment))
+                 (or (company-grab-symbol) 'stop)))
+    (candidates
+     (let ((completion-ignore-case nil)
+           (symbols (cdr (assq major-mode company-keywords-alist))))
+       (all-completions arg (if (consp symbols)
+                                symbols
+                              (cdr (assq symbols company-keywords-alist))))))
+    (sorted t)))
+
+(provide 'company-keywords)
+;;; company-keywords.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-keywords.elc b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-keywords.elc
new file mode 100644
index 0000000000..a35516d104
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-keywords.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-nxml.el b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-nxml.el
new file mode 100644
index 0000000000..36ff1cebd6
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-nxml.el
@@ -0,0 +1,143 @@
+;;; company-nxml.el --- company-mode completion backend for nxml-mode
+
+;; Copyright (C) 2009-2011, 2013, 2018  Free Software Foundation, Inc.
+
+;; Author: Nikolaj Schumacher
+
+;; 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:
+;;
+;; In Emacs >= 26, company-capf is used instead.
+
+;;; Code:
+
+(require 'company)
+(require 'cl-lib)
+
+(defvar rng-open-elements)
+(defvar rng-validate-mode)
+(defvar rng-in-attribute-regex)
+(defvar rng-in-attribute-value-regex)
+(declare-function rng-set-state-after "rng-nxml")
+(declare-function rng-match-possible-start-tag-names "rng-match")
+(declare-function rng-adjust-state-for-attribute "rng-nxml")
+(declare-function rng-match-possible-attribute-names "rng-match")
+(declare-function rng-adjust-state-for-attribute-value "rng-nxml")
+(declare-function rng-match-possible-value-strings "rng-match")
+
+(defconst company-nxml-token-regexp
+  "\\(?:[_[:alpha:]][-._[:alnum:]]*\\_>\\)")
+
+(defvar company-nxml-in-attribute-value-regexp
+  (replace-regexp-in-string "w" company-nxml-token-regexp
+   "<w\\(?::w\\)?\
+\\(?:[ \t\r\n]+w\\(?::w\\)?[ \t\r\n]*=\
+\[ \t\r\n]*\\(?:\"[^\"]*\"\\|'[^']*'\\)\\)*\
+\[ \t\r\n]+\\(w\\(:w\\)?\\)[ \t\r\n]*=[ \t\r\n]*\
+\\(\"\\([^\"]*\\>\\)\\|'\\([^']*\\>\\)\\)\\="
+   t t))
+
+(defvar company-nxml-in-tag-name-regexp
+  (replace-regexp-in-string "w" company-nxml-token-regexp
+                            "<\\(/?w\\(?::w?\\)?\\)?\\=" t t))
+
+(defun company-nxml-all-completions (prefix alist)
+  (let ((candidates (mapcar 'cdr alist))
+        (case-fold-search nil)
+        filtered)
+    (when (cdar rng-open-elements)
+      (push (concat "/" (cdar rng-open-elements)) candidates))
+    (setq candidates (sort (all-completions prefix candidates) 'string<))
+    (while candidates
+      (unless (equal (car candidates) (car filtered))
+        (push (car candidates) filtered))
+      (pop candidates))
+    (nreverse filtered)))
+
+(defmacro company-nxml-prepared (&rest body)
+  (declare (indent 0) (debug t))
+  `(let ((lt-pos (save-excursion (search-backward "<" nil t)))
+         xmltok-dtd)
+     (when (and lt-pos (= (rng-set-state-after lt-pos) lt-pos))
+       ,@body)))
+
+(defun company-nxml-tag (command &optional arg &rest ignored)
+  (cl-case command
+    (prefix (and (derived-mode-p 'nxml-mode)
+                 rng-validate-mode
+                 (company-grab company-nxml-in-tag-name-regexp 1)))
+    (candidates (company-nxml-prepared
+                 (company-nxml-all-completions
+                  arg (rng-match-possible-start-tag-names))))
+    (sorted t)))
+
+(defun company-nxml-attribute (command &optional arg &rest ignored)
+  (cl-case command
+    (prefix (and (derived-mode-p 'nxml-mode)
+                 rng-validate-mode
+                 (memq (char-after) '(?\  ?\t ?\n)) ;; outside word
+                 (company-grab rng-in-attribute-regex 1)))
+    (candidates (company-nxml-prepared
+                 (and (rng-adjust-state-for-attribute
+                       lt-pos (- (point) (length arg)))
+                      (company-nxml-all-completions
+                       arg (rng-match-possible-attribute-names)))))
+    (sorted t)))
+
+(defun company-nxml-attribute-value (command &optional arg &rest ignored)
+  (cl-case command
+    (prefix (and (derived-mode-p 'nxml-mode)
+                 rng-validate-mode
+                 (and (memq (char-after) '(?' ?\" ?\  ?\t ?\n)) ;; outside word
+                      (looking-back company-nxml-in-attribute-value-regexp nil)
+                      (or (match-string-no-properties 4)
+                          (match-string-no-properties 5)
+                          ""))))
+    (candidates (company-nxml-prepared
+                 (let (attr-start attr-end colon)
+                   (and (looking-back rng-in-attribute-value-regex lt-pos)
+                        (setq colon (match-beginning 2)
+                              attr-start (match-beginning 1)
+                              attr-end (match-end 1))
+                        (rng-adjust-state-for-attribute lt-pos attr-start)
+                        (rng-adjust-state-for-attribute-value
+                         attr-start colon attr-end)
+                        (all-completions
+                         arg (rng-match-possible-value-strings))))))))
+
+;;;###autoload
+(defun company-nxml (command &optional arg &rest ignored)
+  "`company-mode' completion backend for `nxml-mode'."
+  (interactive (list 'interactive))
+  (cl-case command
+    (interactive (company-begin-backend 'company-nxml))
+    (prefix (or (company-nxml-tag 'prefix)
+                (company-nxml-attribute 'prefix)
+                (company-nxml-attribute-value 'prefix)))
+    (candidates (cond
+                 ((company-nxml-tag 'prefix)
+                  (company-nxml-tag 'candidates arg))
+                 ((company-nxml-attribute 'prefix)
+                  (company-nxml-attribute 'candidates arg))
+                 ((company-nxml-attribute-value 'prefix)
+                  (sort (company-nxml-attribute-value 'candidates arg)
+                        'string<))))
+    (sorted t)))
+
+(provide 'company-nxml)
+;;; company-nxml.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-nxml.elc b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-nxml.elc
new file mode 100644
index 0000000000..7a232a3abd
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-nxml.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-oddmuse.el b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-oddmuse.el
new file mode 100644
index 0000000000..1b6895093e
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-oddmuse.el
@@ -0,0 +1,57 @@
+;;; company-oddmuse.el --- company-mode completion backend for oddmuse-mode
+
+;; Copyright (C) 2009-2011, 2014  Free Software Foundation, Inc.
+
+;; Author: Nikolaj Schumacher
+
+;; 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:
+;;
+
+;;; Code:
+
+(require 'company)
+(require 'cl-lib)
+(eval-when-compile (require 'yaoddmuse nil t))
+(eval-when-compile (require 'oddmuse nil t))
+
+(defvar company-oddmuse-link-regexp
+  "\\(\\<[A-Z][[:alnum:]]*\\>\\)\\|\\[\\[\\([[:alnum:]]+\\>\\|\\)")
+
+(defun company-oddmuse-get-page-table ()
+  (cl-case major-mode
+    (yaoddmuse-mode (with-no-warnings
+                      (yaoddmuse-get-pagename-table yaoddmuse-wikiname)))
+    (oddmuse-mode (with-no-warnings
+                    (oddmuse-make-completion-table oddmuse-wiki)))))
+
+;;;###autoload
+(defun company-oddmuse (command &optional arg &rest ignored)
+  "`company-mode' completion backend for `oddmuse-mode'."
+  (interactive (list 'interactive))
+  (cl-case command
+    (interactive (company-begin-backend 'company-oddmuse))
+    (prefix (let ((case-fold-search nil))
+              (and (memq major-mode '(oddmuse-mode yaoddmuse-mode))
+                   (looking-back company-oddmuse-link-regexp (point-at-bol))
+                   (or (match-string 1)
+                       (match-string 2)))))
+    (candidates (all-completions arg (company-oddmuse-get-page-table)))))
+
+(provide 'company-oddmuse)
+;;; company-oddmuse.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-oddmuse.elc b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-oddmuse.elc
new file mode 100644
index 0000000000..9b95ab6126
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-oddmuse.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-pkg.el b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-pkg.el
new file mode 100644
index 0000000000..a6d6e6894f
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-pkg.el
@@ -0,0 +1,8 @@
+(define-package "company" "20180704.701" "Modular text completion framework"
+  '((emacs "24.3"))
+  :keywords
+  '("abbrev" "convenience" "matching")
+  :url "http://company-mode.github.io/")
+;; Local Variables:
+;; no-byte-compile: t
+;; End:
diff --git a/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-semantic.el b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-semantic.el
new file mode 100644
index 0000000000..2f6fe2afbc
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-semantic.el
@@ -0,0 +1,168 @@
+;;; company-semantic.el --- company-mode completion backend using Semantic
+
+;; Copyright (C) 2009-2011, 2013-2016  Free Software Foundation, Inc.
+
+;; Author: Nikolaj Schumacher
+
+;; 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:
+;;
+
+;;; Code:
+
+(require 'company)
+(require 'company-template)
+(require 'cl-lib)
+
+(defvar semantic-idle-summary-function)
+(declare-function semantic-documentation-for-tag "semantic/doc" )
+(declare-function semantic-analyze-current-context "semantic/analyze")
+(declare-function semantic-analyze-possible-completions "semantic/complete")
+(declare-function semantic-analyze-find-tags-by-prefix "semantic/analyze/fcn")
+(declare-function semantic-tag-class "semantic/tag")
+(declare-function semantic-tag-name "semantic/tag")
+(declare-function semantic-tag-start "semantic/tag")
+(declare-function semantic-tag-buffer "semantic/tag")
+(declare-function semantic-active-p "semantic")
+(declare-function semantic-format-tag-prototype "semantic/format")
+
+(defgroup company-semantic nil
+  "Completion backend using Semantic."
+  :group 'company)
+
+(defcustom company-semantic-metadata-function 'company-semantic-summary-and-doc
+  "The function turning a semantic tag into doc information."
+  :type 'function)
+
+(defcustom company-semantic-begin-after-member-access t
+  "When non-nil, automatic completion will start whenever the current
+symbol is preceded by \".\", \"->\" or \"::\", ignoring
+`company-minimum-prefix-length'.
+
+If `company-begin-commands' is a list, it should include `c-electric-lt-gt'
+and `c-electric-colon', for automatic completion right after \">\" and
+\":\"."
+  :type 'boolean)
+
+(defcustom company-semantic-insert-arguments t
+  "When non-nil, insert function arguments as a template after completion."
+  :type 'boolean
+  :package-version '(company . "0.9.0"))
+
+(defvar company-semantic-modes '(c-mode c++-mode jde-mode java-mode))
+
+(defvar-local company-semantic--current-tags nil
+  "Tags for the current context.")
+
+(defun company-semantic-documentation-for-tag (tag)
+  (when (semantic-tag-buffer tag)
+    ;; When TAG's buffer is unknown, the function below raises an error.
+    (semantic-documentation-for-tag tag)))
+
+(defun company-semantic-doc-or-summary (tag)
+  (or (company-semantic-documentation-for-tag tag)
+      (and (require 'semantic-idle nil t)
+           (require 'semantic/idle nil t)
+           (funcall semantic-idle-summary-function tag nil t))))
+
+(defun company-semantic-summary-and-doc (tag)
+  (let ((doc (company-semantic-documentation-for-tag tag))
+        (summary (funcall semantic-idle-summary-function tag nil t)))
+    (and (stringp doc)
+         (string-match "\n*\\(.*\\)$" doc)
+         (setq doc (match-string 1 doc)))
+    (concat summary
+            (when doc
+                  (if (< (+ (length doc) (length summary) 4) (window-width))
+                      " -- "
+                    "\n"))
+            doc)))
+
+(defun company-semantic-doc-buffer (tag)
+  (let ((doc (company-semantic-documentation-for-tag tag)))
+    (when doc
+      (company-doc-buffer
+       (concat (funcall semantic-idle-summary-function tag nil t)
+               "\n"
+               doc)))))
+
+(defsubst company-semantic-completions (prefix)
+  (ignore-errors
+    (let ((completion-ignore-case nil)
+          (context (semantic-analyze-current-context)))
+      (setq company-semantic--current-tags
+            (semantic-analyze-possible-completions context 'no-unique))
+      (all-completions prefix company-semantic--current-tags))))
+
+(defun company-semantic-completions-raw (prefix)
+  (setq company-semantic--current-tags nil)
+  (dolist (tag (semantic-analyze-find-tags-by-prefix prefix))
+    (unless (eq (semantic-tag-class tag) 'include)
+      (push tag company-semantic--current-tags)))
+  (delete "" (mapcar 'semantic-tag-name company-semantic--current-tags)))
+
+(defun company-semantic-annotation (argument tags)
+  (let* ((tag (assq argument tags))
+         (kind (when tag (elt tag 1))))
+    (cl-case kind
+      (function (let* ((prototype (semantic-format-tag-prototype tag nil nil))
+                       (par-pos (string-match "(" prototype)))
+                  (when par-pos (substring prototype par-pos)))))))
+
+(defun company-semantic--prefix ()
+  (if company-semantic-begin-after-member-access
+      (company-grab-symbol-cons "\\.\\|->\\|::" 2)
+    (company-grab-symbol)))
+
+;;;###autoload
+(defun company-semantic (command &optional arg &rest ignored)
+  "`company-mode' completion backend using CEDET Semantic."
+  (interactive (list 'interactive))
+  (cl-case command
+    (interactive (company-begin-backend 'company-semantic))
+    (prefix (and (featurep 'semantic)
+                 (semantic-active-p)
+                 (memq major-mode company-semantic-modes)
+                 (not (company-in-string-or-comment))
+                 (or (company-semantic--prefix) 'stop)))
+    (candidates (if (and (equal arg "")
+                         (not (looking-back "->\\|\\.\\|::" (- (point) 2))))
+                    (company-semantic-completions-raw arg)
+                  (company-semantic-completions arg)))
+    (meta (funcall company-semantic-metadata-function
+                   (assoc arg company-semantic--current-tags)))
+    (annotation (company-semantic-annotation arg
+                                             company-semantic--current-tags))
+    (doc-buffer (company-semantic-doc-buffer
+                 (assoc arg company-semantic--current-tags)))
+    ;; Because "" is an empty context and doesn't return local variables.
+    (no-cache (equal arg ""))
+    (duplicates t)
+    (location (let ((tag (assoc arg company-semantic--current-tags)))
+                (when (buffer-live-p (semantic-tag-buffer tag))
+                  (cons (semantic-tag-buffer tag)
+                        (semantic-tag-start tag)))))
+    (post-completion (let ((anno (company-semantic-annotation
+                                  arg company-semantic--current-tags)))
+                       (when (and company-semantic-insert-arguments anno)
+                         (insert anno)
+                         (company-template-c-like-templatify (concat arg anno)))
+                       ))))
+
+(provide 'company-semantic)
+;;; company-semantic.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-semantic.elc b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-semantic.elc
new file mode 100644
index 0000000000..73794cf2aa
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-semantic.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-template.el b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-template.el
new file mode 100644
index 0000000000..930e638e9d
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-template.el
@@ -0,0 +1,260 @@
+;;; company-template.el --- utility library for template expansion
+
+;; Copyright (C) 2009, 2010, 2014-2017 Free Software Foundation, Inc.
+
+;; Author: Nikolaj Schumacher
+
+;; 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/>.
+
+;;; Code:
+
+(require 'cl-lib)
+
+(defface company-template-field
+  '((((background dark)) (:background "yellow" :foreground "black"))
+    (((background light)) (:background "orange" :foreground "black")))
+  "Face used for editable text in template fields."
+  :group 'company)
+
+(defvar company-template-nav-map
+  (let ((keymap (make-sparse-keymap)))
+    (define-key keymap [tab] 'company-template-forward-field)
+    (define-key keymap (kbd "TAB") 'company-template-forward-field)
+    keymap))
+
+(defvar company-template-field-map
+  (let ((keymap (make-sparse-keymap)))
+    (set-keymap-parent keymap company-template-nav-map)
+    (define-key keymap (kbd "C-d") 'company-template-clear-field)
+    keymap))
+
+(defvar-local company-template--buffer-templates nil)
+
+;; interactive ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun company-template-templates-at (pos)
+  (let (os)
+    (dolist (o (overlays-at pos))
+      ;; FIXME: Always return the whole list of templates?
+      ;; We remove templates not at point after every command.
+      (when (memq o company-template--buffer-templates)
+        (push o os)))
+    os))
+
+(defun company-template-move-to-first (templ)
+  (interactive)
+  (goto-char (overlay-start templ))
+  (company-template-forward-field))
+
+(defun company-template-forward-field ()
+  (interactive)
+  (let ((start (point))
+        (next-field-start (company-template-find-next-field)))
+    (push-mark)
+    (goto-char next-field-start)
+    (company-template-remove-field (company-template-field-at start))))
+
+(defun company-template-clear-field ()
+  "Clear the field at point."
+  (interactive)
+  (let ((ovl (company-template-field-at (point))))
+    (when ovl
+      (company-template-remove-field ovl t)
+      (let ((after-clear-fn
+             (overlay-get ovl 'company-template-after-clear)))
+        (when (functionp after-clear-fn)
+          (funcall after-clear-fn))))))
+
+(defun company-template--after-clear-c-like-field ()
+  "Function that can be called after deleting a field of a c-like template.
+For c-like templates it is set as `after-post-fn' property on fields in
+`company-template-add-field'.  If there is a next field, delete everything
+from point to it.  If there is no field after point, remove preceding comma
+if present."
+  (let* ((pos (point))
+         (next-field-start (company-template-find-next-field))
+         (last-field-p (not (company-template-field-at next-field-start))))
+    (cond ((and (not last-field-p)
+                (< pos next-field-start)
+                (string-match "^[ ]*,+[ ]*$" (buffer-substring-no-properties
+                                              pos next-field-start)))
+           (delete-region pos next-field-start))
+          ((and last-field-p
+                (looking-back ",+[ ]*" (line-beginning-position)))
+           (delete-region (match-beginning 0) pos)))))
+
+(defun company-template-find-next-field ()
+  (let* ((start (point))
+         (templates (company-template-templates-at start))
+         (minimum (apply 'max (mapcar 'overlay-end templates)))
+         (fields (cl-loop for templ in templates
+                          append (overlay-get templ 'company-template-fields))))
+    (dolist (pos (mapcar 'overlay-start fields) minimum)
+      (and pos
+           (> pos start)
+           (< pos minimum)
+           (setq minimum pos)))))
+
+(defun company-template-field-at (&optional point)
+  (cl-loop for ovl in (overlays-at (or point (point)))
+           when (overlay-get ovl 'company-template-parent)
+           return ovl))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun company-template-declare-template (beg end)
+  (let ((ov (make-overlay beg end)))
+    ;; (overlay-put ov 'face 'highlight)
+    (overlay-put ov 'keymap company-template-nav-map)
+    (overlay-put ov 'priority 101)
+    (overlay-put ov 'evaporate t)
+    (push ov company-template--buffer-templates)
+    (add-hook 'post-command-hook 'company-template-post-command nil t)
+    ov))
+
+(defun company-template-remove-template (templ)
+  (mapc 'company-template-remove-field
+        (overlay-get templ 'company-template-fields))
+  (setq company-template--buffer-templates
+        (delq templ company-template--buffer-templates))
+  (delete-overlay templ))
+
+(defun company-template-add-field (templ beg end &optional display after-clear-fn)
+  "Add new field to template TEMPL spanning from BEG to END.
+When DISPLAY is non-nil, set the respective property on the overlay.
+Leave point at the end of the field.
+AFTER-CLEAR-FN is a function that can be used to apply custom behavior
+after deleting a field in `company-template-remove-field'."
+  (cl-assert templ)
+  (when (> end (overlay-end templ))
+    (move-overlay templ (overlay-start templ) end))
+  (let ((ov (make-overlay beg end))
+        (siblings (overlay-get templ 'company-template-fields)))
+    ;; (overlay-put ov 'evaporate t)
+    (overlay-put ov 'intangible t)
+    (overlay-put ov 'face 'company-template-field)
+    (when display
+      (overlay-put ov 'display display))
+    (overlay-put ov 'company-template-parent templ)
+    (overlay-put ov 'insert-in-front-hooks '(company-template-insert-hook))
+    (when after-clear-fn
+      (overlay-put ov 'company-template-after-clear after-clear-fn))
+    (overlay-put ov 'keymap company-template-field-map)
+    (overlay-put ov 'priority 101)
+    (push ov siblings)
+    (overlay-put templ 'company-template-fields siblings)))
+
+(defun company-template-remove-field (ovl &optional clear)
+  (when (overlayp ovl)
+    (when (overlay-buffer ovl)
+      (when clear
+        (delete-region (overlay-start ovl) (overlay-end ovl)))
+      (delete-overlay ovl))
+    (let* ((templ (overlay-get ovl 'company-template-parent))
+           (siblings (overlay-get templ 'company-template-fields)))
+      (setq siblings (delq ovl siblings))
+      (overlay-put templ 'company-template-fields siblings))))
+
+(defun company-template-clean-up (&optional pos)
+  "Clean up all templates that don't contain POS."
+  (let ((local-ovs (overlays-at (or pos (point)))))
+    (dolist (templ company-template--buffer-templates)
+      (unless (memq templ local-ovs)
+        (company-template-remove-template templ)))))
+
+;; hooks ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun company-template-insert-hook (ovl after-p &rest _ignore)
+  "Called when a snippet input prompt is modified."
+  (unless after-p
+    (company-template-remove-field ovl t)))
+
+(defun company-template-post-command ()
+  (company-template-clean-up)
+  (unless company-template--buffer-templates
+    (remove-hook 'post-command-hook 'company-template-post-command t)))
+
+;; common ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun company-template-c-like-templatify (call)
+  (let* ((end (point-marker))
+         (beg (- (point) (length call)))
+         (templ (company-template-declare-template beg end))
+         paren-open paren-close)
+    (with-syntax-table (make-syntax-table (syntax-table))
+      (modify-syntax-entry ?< "(")
+      (modify-syntax-entry ?> ")")
+      (when (search-backward ")" beg t)
+        (setq paren-close (point-marker))
+        (forward-char 1)
+        (delete-region (point) end)
+        (backward-sexp)
+        (forward-char 1)
+        (setq paren-open (point-marker)))
+      (when (search-backward ">" beg t)
+        (let ((angle-close (point-marker)))
+          (forward-char 1)
+          (backward-sexp)
+          (forward-char)
+          (company-template--c-like-args templ angle-close)))
+      (when (looking-back "\\((\\*)\\)(" (line-beginning-position))
+        (delete-region (match-beginning 1) (match-end 1)))
+      (when paren-open
+        (goto-char paren-open)
+        (company-template--c-like-args templ paren-close)))
+    (if (overlay-get templ 'company-template-fields)
+        (company-template-move-to-first templ)
+      (company-template-remove-template templ)
+      (goto-char end))))
+
+(defun company-template--c-like-args (templ end)
+  (let ((last-pos (point)))
+    (while (re-search-forward "\\([^,]+\\),?" end 'move)
+      (when (zerop (car (parse-partial-sexp last-pos (point))))
+        (company-template-add-field templ last-pos (match-end 1) nil
+                                    #'company-template--after-clear-c-like-field)
+        (skip-chars-forward " ")
+        (setq last-pos (point))))))
+
+;; objc ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun company-template-objc-templatify (selector)
+  (let* ((end (point-marker))
+         (beg (- (point) (length selector) 1))
+         (templ (company-template-declare-template beg end))
+         (cnt 0))
+    (save-excursion
+      (goto-char beg)
+      (catch 'stop
+        (while (search-forward ":" end t)
+          (if (looking-at "\\(([^)]*)\\) ?")
+              (company-template-add-field templ (point) (match-end 1))
+            ;; Not sure which conditions this case manifests under, but
+            ;; apparently it did before, when I wrote the first test for this
+            ;; function.  FIXME: Revisit it.
+            (company-template-add-field templ (point)
+                                        (progn
+                                          (insert (format "arg%d" cnt))
+                                          (point)))
+            (when (< (point) end)
+              (insert " "))
+            (cl-incf cnt))
+          (when (>= (point) end)
+            (throw 'stop t)))))
+    (company-template-move-to-first templ)))
+
+(provide 'company-template)
+;;; company-template.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-template.elc b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-template.elc
new file mode 100644
index 0000000000..adaf8080ff
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-template.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-tempo.el b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-tempo.el
new file mode 100644
index 0000000000..cba42c3e36
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-tempo.el
@@ -0,0 +1,71 @@
+;;; company-tempo.el --- company-mode completion backend for tempo
+
+;; Copyright (C) 2009-2011, 2015  Free Software Foundation, Inc.
+
+;; Author: Nikolaj Schumacher
+
+;; 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:
+;;
+
+;;; Code:
+
+(require 'company)
+(require 'cl-lib)
+(require 'tempo)
+
+(defgroup company-tempo nil
+  "Tempo completion backend."
+  :group 'company)
+
+(defcustom company-tempo-expand nil
+  "Whether to expand a tempo tag after completion."
+  :type '(choice (const :tag "Off" nil)
+                 (const :tag "On" t)))
+
+(defsubst company-tempo-lookup (match)
+  (cdr (assoc match (tempo-build-collection))))
+
+(defun company-tempo-insert (match)
+  "Replace MATCH with the expanded tempo template."
+  (search-backward match)
+  (goto-char (match-beginning 0))
+  (replace-match "")
+  (call-interactively (company-tempo-lookup match)))
+
+(defsubst company-tempo-meta (match)
+  (let ((templ (company-tempo-lookup match))
+        doc)
+    (and templ
+         (setq doc (documentation templ t))
+         (car (split-string doc "\n" t)))))
+
+;;;###autoload
+(defun company-tempo (command &optional arg &rest ignored)
+  "`company-mode' completion backend for tempo."
+  (interactive (list 'interactive))
+  (cl-case command
+    (interactive (company-begin-backend 'company-tempo))
+    (prefix (or (car (tempo-find-match-string tempo-match-finder)) ""))
+    (candidates (all-completions arg (tempo-build-collection)))
+    (meta (company-tempo-meta arg))
+    (post-completion (when company-tempo-expand (company-tempo-insert arg)))
+    (sorted t)))
+
+(provide 'company-tempo)
+;;; company-tempo.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-tempo.elc b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-tempo.elc
new file mode 100644
index 0000000000..bbc42e1c29
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-tempo.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-tng.el b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-tng.el
new file mode 100644
index 0000000000..a1d71737ea
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-tng.el
@@ -0,0 +1,174 @@
+;;; company-tng.el --- company-mode configuration for single-button interaction
+
+;; Copyright (C) 2017  Free Software Foundation, Inc.
+
+;; Author: Nikita Leshenko
+
+;; 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:
+;;
+;; company-tng (Tab and Go) allows you to perform completion using just TAB.
+;; Pressing it will both select the next completion candidate in the list and
+;; insert it into the buffer (or make it look like it's inserted, in fact).
+;;
+;; It cycles the candidates like `yank-pop' or `dabbrev-expand' or Vim:
+;; Pressing TAB selects the first item in the completion menu and inserts it in
+;; the buffer. Pressing TAB again selects the second item and replaces the
+;; "inserted" item with the second one. This can continue as long as the user
+;; wishes to cycle through the menu. You can also press S-TAB to select the
+;; previous candidate, of course.
+;;
+;; The benefits are that you only have to use one shortcut key and there is no
+;; need to confirm the entry.
+;;
+;; Usage:
+;;
+;; To apply the default configuration for company-tng call
+;; `company-tng-configure-default' from your init script.
+;;
+;; You can also configure company-tng manually:
+;;
+;; Add `company-tng-frontend' to `company-frontends':
+;;
+;;   (add-to-list 'company-frontends 'company-tng-frontend)
+;;
+;; We recommend to bind TAB to `company-select-next', S-TAB to
+;; `company-select-previous', and unbind RET and other now-unnecessary
+;; keys from `company-active-map':
+;;
+;;   (define-key company-active-map (kbd "TAB") 'company-select-next)
+;;   (define-key company-active-map (kbd "<backtab>") 'company-select-previous)
+;;   (define-key company-active-map (kbd "RET") nil)
+;;
+;; Note that it's not necessary to rebind keys to use this frontend,
+;; you can use the arrow keys or M-n/M-p to select and insert
+;; candidates. You also need to decide which keys to unbind, depending
+;; on whether you want them to do the Company action or the default
+;; Emacs action (for example C-s or C-w).
+;;
+;; We recommend to disable `company-require-match' to allow free typing at any
+;; point.
+
+;;; Code:
+
+(require 'company)
+(require 'cl-lib)
+
+(defvar-local company-tng--overlay nil)
+
+;;;###autoload
+(defun company-tng-frontend (command)
+  "When the user changes the selection at least once, this
+frontend will display the candidate in the buffer as if it's
+already there and any key outside of `company-active-map' will
+confirm the selection and finish the completion."
+  (cl-case command
+    (show
+     (let ((ov (make-overlay (point) (point))))
+       (setq company-tng--overlay ov)
+       (overlay-put ov 'priority 2))
+     (advice-add 'company-select-next :before-until 'company-tng--allow-unselected)
+     (advice-add 'company-fill-propertize :filter-args 'company-tng--adjust-tooltip-highlight))
+    (update
+     (let ((ov company-tng--overlay)
+           (selected (nth company-selection company-candidates))
+           (prefix (length company-prefix)))
+       (move-overlay ov (- (point) prefix) (point))
+       (overlay-put ov
+                    (if (= prefix 0) 'after-string 'display)
+                    (and company-selection-changed selected))))
+    (hide
+     (when company-tng--overlay
+       (delete-overlay company-tng--overlay)
+       (kill-local-variable 'company-tng--overlay))
+     (advice-remove 'company-select-next 'company-tng--allow-unselected)
+     (advice-remove 'company-fill-propertize 'company-tng--adjust-tooltip-highlight))
+    (pre-command
+     (when (and company-selection-changed
+                (not (company--company-command-p (this-command-keys))))
+       (company--unread-this-command-keys)
+       (setq this-command 'company-complete-selection)
+       (advice-add 'company-call-backend :before-until 'company-tng--supress-post-completion)))))
+
+;;;###autoload
+(defun company-tng-configure-default ()
+  "Applies the default configuration to enable company-tng."
+  (setq company-require-match nil)
+  (setq company-frontends '(company-tng-frontend
+                            company-pseudo-tooltip-frontend
+                            company-echo-metadata-frontend))
+  (let ((keymap company-active-map))
+    (define-key keymap [return] nil)
+    (define-key keymap (kbd "RET") nil)
+    (define-key keymap [tab] 'company-select-next)
+    (define-key keymap (kbd "TAB") 'company-select-next)
+    (define-key keymap [backtab] 'company-select-previous)
+    (define-key keymap (kbd "S-TAB") 'company-select-previous)))
+
+(defun company-tng--allow-unselected (&optional arg)
+  "Advice `company-select-next' to allow for an 'unselected'
+state. Unselected means that no user interaction took place on the
+completion candidates and it's marked by setting
+`company-selection-changed' to nil. This advice will call the underlying
+`company-select-next' unless we need to transition to or from an unselected
+state.
+
+Possible state transitions:
+- (arg > 0) unselected -> first candidate selected
+- (arg < 0) first candidate selected -> unselected
+- (arg < 0 wrap-round) unselected -> last candidate selected
+- (arg < 0 no wrap-round) unselected -> unselected
+
+There is no need to advice `company-select-previous' because it calls
+`company-select-next' internally."
+  (cond
+   ;; Selecting next
+   ((or (not arg) (> arg 0))
+    (unless company-selection-changed
+      (company-set-selection (1- (or arg 1)) 'force-update)
+      t))
+   ;; Selecting previous
+   ((< arg 0)
+    (when (and company-selection-changed
+               (< (+ company-selection arg) 0))
+      (company-set-selection 0)
+      (setq company-selection-changed nil)
+      (company-call-frontends 'update)
+      t)
+    )))
+
+(defun company-tng--adjust-tooltip-highlight (args)
+  "Prevent the tooltip from highlighting the current selection if it wasn't
+made explicitly (i.e. `company-selection-changed' is true)"
+  (unless company-selection-changed
+    ;; The 4th arg of `company-fill-propertize' is selected
+    (setf (nth 3 args) nil))
+  args)
+
+(defun company-tng--supress-post-completion (command &rest args)
+  "Installed as a :before-until advice on `company-call-backend' and
+prevents the 'post-completion command from being delivered to the backend
+for the next iteration. post-completion do things like expand snippets
+which are undesirable because completions are implicit in company-tng and
+visible side-effects after the completion are surprising."
+  (when (eq command 'post-completion)
+    (advice-remove 'company-call-backend 'company-tng--supress-post-completion)
+    t))
+
+(provide 'company-tng)
+;;; company-tng.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-tng.elc b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-tng.elc
new file mode 100644
index 0000000000..b785f35fef
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-tng.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-xcode.el b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-xcode.el
new file mode 100644
index 0000000000..56da19890b
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-xcode.el
@@ -0,0 +1,123 @@
+;;; company-xcode.el --- company-mode completion backend for Xcode projects
+
+;; Copyright (C) 2009-2011, 2014  Free Software Foundation, Inc.
+
+;; Author: Nikolaj Schumacher
+
+;; 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:
+;;
+
+;;; Code:
+
+(require 'company)
+(require 'cl-lib)
+
+(defgroup company-xcode nil
+  "Completion backend for Xcode projects."
+  :group 'company)
+
+(defcustom company-xcode-xcodeindex-executable (executable-find "xcodeindex")
+  "Location of xcodeindex executable."
+  :type 'file)
+
+(defvar company-xcode-tags nil)
+
+(defun company-xcode-reset ()
+  "Reset the cached tags."
+  (interactive)
+  (setq company-xcode-tags nil))
+
+(defcustom company-xcode-types
+  '("Class" "Constant" "Enum" "Macro" "Modeled Class" "Structure"
+    "Type" "Union" "Function")
+  "The types of symbols offered by `company-xcode'.
+No context-enabled completion is available.  Types like methods will be
+offered regardless of whether the class supports them.  The defaults should be
+valid in most contexts."
+  :set (lambda (variable value)
+         (set variable value)
+         (company-xcode-reset))
+  :type '(set (const "Category") (const "Class") (const "Class Method")
+              (const "Class Variable") (const "Constant") (const "Enum")
+              (const "Field") (const "Instance Method")
+              (const "Instance Variable") (const "Macro")
+              (const "Modeled Class") (const "Modeled Method")
+              (const "Modeled Property") (const "Property") (const "Protocol")
+              (const "Structure") (const "Type") (const "Union")
+              (const "Variable") (const "Function")))
+
+(defvar-local company-xcode-project 'unknown)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun company-xcode-fetch (project-bundle)
+  (setq project-bundle (directory-file-name project-bundle))
+  (message "Retrieving dump from %s..." project-bundle)
+  (with-temp-buffer
+    (let ((default-directory (file-name-directory project-bundle)))
+      (call-process company-xcode-xcodeindex-executable nil (current-buffer)
+                    nil "dump" "-project"
+                    (file-name-nondirectory project-bundle) "-quiet")
+      (goto-char (point-min))
+      (let ((regexp (concat "^\\([^\t\n]*\\)\t[^\t\n]*\t"
+                            (regexp-opt company-xcode-types)
+                            "\t[^\t\n]*\t[^\t\n]*"))
+            candidates)
+        (while (re-search-forward regexp nil t)
+          (cl-pushnew (match-string 1) candidates :test #'equal))
+        (message "Retrieving dump from %s...done" project-bundle)
+        candidates))))
+
+(defun company-xcode-find-project ()
+  (let ((dir (if buffer-file-name
+                 (file-name-directory buffer-file-name)
+               (expand-file-name default-directory)))
+        (prev-dir nil)
+        file)
+    (while (not (or file (equal dir prev-dir)))
+      (setq file (car (directory-files dir t ".xcodeproj\\'" t))
+            prev-dir dir
+            dir (file-name-directory (directory-file-name dir))))
+    file))
+
+(defun company-xcode-tags ()
+  (when (eq company-xcode-project 'unknown)
+    (setq company-xcode-project (company-xcode-find-project)))
+  (when company-xcode-project
+    (cdr (or (assoc company-xcode-project company-xcode-tags)
+             (car (push (cons company-xcode-project
+                              (company-xcode-fetch company-xcode-project))
+                        company-xcode-tags))))))
+;;;###autoload
+(defun company-xcode (command &optional arg &rest ignored)
+  "`company-mode' completion backend for Xcode projects."
+  (interactive (list 'interactive))
+  (cl-case command
+    (interactive (company-begin-backend 'company-xcode))
+    (prefix (and company-xcode-xcodeindex-executable
+                 (company-xcode-tags)
+                 (not (company-in-string-or-comment))
+                 (or (company-grab-symbol) 'stop)))
+    (candidates (let ((completion-ignore-case nil))
+                  (company-xcode-tags)
+                  (all-completions arg (company-xcode-tags))))))
+
+
+(provide 'company-xcode)
+;;; company-xcode.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-xcode.elc b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-xcode.elc
new file mode 100644
index 0000000000..2e2a5d8f54
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-xcode.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-yasnippet.el b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-yasnippet.el
new file mode 100644
index 0000000000..e5fded4d19
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-yasnippet.el
@@ -0,0 +1,147 @@
+;;; company-yasnippet.el --- company-mode completion backend for Yasnippet
+
+;; Copyright (C) 2014, 2015  Free Software Foundation, Inc.
+
+;; Author: Dmitry Gutov
+
+;; 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:
+;;
+
+;;; Code:
+
+(require 'company)
+(require 'cl-lib)
+
+(declare-function yas--table-hash "yasnippet")
+(declare-function yas--get-snippet-tables "yasnippet")
+(declare-function yas-expand-snippet "yasnippet")
+(declare-function yas--template-content "yasnippet")
+(declare-function yas--template-expand-env "yasnippet")
+(declare-function yas--warning "yasnippet")
+
+(defun company-yasnippet--key-prefixes ()
+  ;; Mostly copied from `yas--templates-for-key-at-point'.
+  (defvar yas-key-syntaxes)
+  (save-excursion
+    (let ((original (point))
+          (methods yas-key-syntaxes)
+          prefixes
+          method)
+      (while methods
+        (unless (eq method (car methods))
+          (goto-char original))
+        (setq method (car methods))
+        (cond ((stringp method)
+               (skip-syntax-backward method)
+               (setq methods (cdr methods)))
+              ((functionp method)
+               (unless (eq (funcall method original)
+                           'again)
+                 (setq methods (cdr methods))))
+              (t
+               (setq methods (cdr methods))
+               (yas--warning "Invalid element `%s' in `yas-key-syntaxes'" method)))
+        (let ((prefix (buffer-substring-no-properties (point) original)))
+          (unless (equal prefix (car prefixes))
+            (push prefix prefixes))))
+      prefixes)))
+
+(defun company-yasnippet--candidates (prefix)
+  ;; Process the prefixes in reverse: unlike Yasnippet, we look for prefix
+  ;; matches, so the longest prefix with any matches should be the most useful.
+  (cl-loop with tables = (yas--get-snippet-tables)
+           for key-prefix in (company-yasnippet--key-prefixes)
+           ;; Only consider keys at least as long as the symbol at point.
+           when (>= (length key-prefix) (length prefix))
+           thereis (company-yasnippet--completions-for-prefix prefix
+                                                              key-prefix
+                                                              tables)))
+
+(defun company-yasnippet--completions-for-prefix (prefix key-prefix tables)
+  (cl-mapcan
+   (lambda (table)
+     (let ((keyhash (yas--table-hash table))
+           res)
+       (when keyhash
+         (maphash
+          (lambda (key value)
+            (when (and (stringp key)
+                       (string-prefix-p key-prefix key))
+              (maphash
+               (lambda (name template)
+                 (push
+                  (propertize key
+                              'yas-annotation name
+                              'yas-template template
+                              'yas-prefix-offset (- (length key-prefix)
+                                                    (length prefix)))
+                  res))
+               value)))
+          keyhash))
+       res))
+   tables))
+
+;;;###autoload
+(defun company-yasnippet (command &optional arg &rest ignore)
+  "`company-mode' backend for `yasnippet'.
+
+This backend should be used with care, because as long as there are
+snippets defined for the current major mode, this backend will always
+shadow backends that come after it.  Recommended usages:
+
+* In a buffer-local value of `company-backends', grouped with a backend or
+  several that provide actual text completions.
+
+  (add-hook 'js-mode-hook
+            (lambda ()
+              (set (make-local-variable 'company-backends)
+                   '((company-dabbrev-code company-yasnippet)))))
+
+* After keyword `:with', grouped with other backends.
+
+  (push '(company-semantic :with company-yasnippet) company-backends)
+
+* Not in `company-backends', just bound to a key.
+
+  (global-set-key (kbd \"C-c y\") 'company-yasnippet)
+"
+  (interactive (list 'interactive))
+  (cl-case command
+    (interactive (company-begin-backend 'company-yasnippet))
+    (prefix
+     ;; Should probably use `yas--current-key', but that's bound to be slower.
+     ;; How many trigger keys start with non-symbol characters anyway?
+     (and (bound-and-true-p yas-minor-mode)
+          (company-grab-symbol)))
+    (annotation
+     (concat
+      (unless company-tooltip-align-annotations " -> ")
+      (get-text-property 0 'yas-annotation arg)))
+    (candidates (company-yasnippet--candidates arg))
+    (no-cache t)
+    (post-completion
+     (let ((template (get-text-property 0 'yas-template arg))
+           (prefix-offset (get-text-property 0 'yas-prefix-offset arg)))
+       (yas-expand-snippet (yas--template-content template)
+                           (- (point) (length arg) prefix-offset)
+                           (point)
+                           (yas--template-expand-env template))))))
+
+(provide 'company-yasnippet)
+;;; company-yasnippet.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-yasnippet.elc b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-yasnippet.elc
new file mode 100644
index 0000000000..cf6f2a307d
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company-yasnippet.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company.el b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company.el
new file mode 100644
index 0000000000..1259b6c72a
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company.el
@@ -0,0 +1,3182 @@
+;;; company.el --- Modular text completion framework  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2009-2018  Free Software Foundation, Inc.
+
+;; Author: Nikolaj Schumacher
+;; Maintainer: Dmitry Gutov <dgutov@yandex.ru>
+;; URL: http://company-mode.github.io/
+;; Version: 0.9.6
+;; Keywords: abbrev, convenience, matching
+;; Package-Requires: ((emacs "24.3"))
+
+;; 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:
+;;
+;; Company is a modular completion framework.  Modules for retrieving completion
+;; candidates are called backends, modules for displaying them are frontends.
+;;
+;; Company comes with many backends, e.g. `company-etags'.  These are
+;; distributed in separate files and can be used individually.
+;;
+;; Enable `company-mode' in all buffers with M-x global-company-mode.  For
+;; further information look at the documentation for `company-mode' (C-h f
+;; company-mode RET).
+;;
+;; If you want to start a specific backend, call it interactively or use
+;; `company-begin-backend'.  For example:
+;; M-x company-abbrev will prompt for and insert an abbrev.
+;;
+;; To write your own backend, look at the documentation for `company-backends'.
+;; Here is a simple example completing "foo":
+;;
+;; (defun company-my-backend (command &optional arg &rest ignored)
+;;   (interactive (list 'interactive))
+;;   (pcase command
+;;     (`interactive (company-begin-backend 'company-my-backend))
+;;     (`prefix (company-grab-symbol))
+;;     (`candidates (list "foobar" "foobaz" "foobarbaz"))
+;;     (`meta (format "This value is named %s" arg))))
+;;
+;; Sometimes it is a good idea to mix several backends together, for example to
+;; enrich gtags with dabbrev-code results (to emulate local variables).  To do
+;; this, add a list with both backends as an element in `company-backends'.
+;;
+;;; Change Log:
+;;
+;; See NEWS.md in the repository.
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'newcomment)
+(require 'pcase)
+
+;;; Compatibility
+(eval-and-compile
+  ;; Defined in Emacs 24.4
+  (unless (fboundp 'string-suffix-p)
+    (defun string-suffix-p (suffix string  &optional ignore-case)
+      "Return non-nil if SUFFIX is a suffix of STRING.
+If IGNORE-CASE is non-nil, the comparison is done without paying
+attention to case differences."
+      (let ((start-pos (- (length string) (length suffix))))
+        (and (>= start-pos 0)
+             (eq t (compare-strings suffix nil nil
+                                    string start-pos nil ignore-case)))))))
+
+(defgroup company nil
+  "Extensible inline text completion mechanism"
+  :group 'abbrev
+  :group 'convenience
+  :group 'matching)
+
+(defface company-tooltip
+  '((default :foreground "black")
+    (((class color) (min-colors 88) (background light))
+     (:background "cornsilk"))
+    (((class color) (min-colors 88) (background dark))
+     (:background "yellow")))
+  "Face used for the tooltip.")
+
+(defface company-tooltip-selection
+  '((((class color) (min-colors 88) (background light))
+     (:background "light blue"))
+    (((class color) (min-colors 88) (background dark))
+     (:background "orange1"))
+    (t (:background "green")))
+  "Face used for the selection in the tooltip.")
+
+(defface company-tooltip-search
+  '((default :inherit highlight))
+  "Face used for the search string in the tooltip.")
+
+(defface company-tooltip-search-selection
+  '((default :inherit highlight))
+  "Face used for the search string inside the selection in the tooltip.")
+
+(defface company-tooltip-mouse
+  '((default :inherit highlight))
+  "Face used for the tooltip item under the mouse.")
+
+(defface company-tooltip-common
+  '((((background light))
+     :foreground "darkred")
+    (((background dark))
+     :foreground "red"))
+  "Face used for the common completion in the tooltip.")
+
+(defface company-tooltip-common-selection
+  '((default :inherit company-tooltip-common))
+  "Face used for the selected common completion in the tooltip.")
+
+(defface company-tooltip-annotation
+  '((((background light))
+     :foreground "firebrick4")
+    (((background dark))
+     :foreground "red4"))
+  "Face used for the completion annotation in the tooltip.")
+
+(defface company-tooltip-annotation-selection
+  '((default :inherit company-tooltip-annotation))
+  "Face used for the selected completion annotation in the tooltip.")
+
+(defface company-scrollbar-fg
+  '((((background light))
+     :background "darkred")
+    (((background dark))
+     :background "red"))
+  "Face used for the tooltip scrollbar thumb.")
+
+(defface company-scrollbar-bg
+  '((((background light))
+     :background "wheat")
+    (((background dark))
+     :background "gold"))
+  "Face used for the tooltip scrollbar background.")
+
+(defface company-preview
+  '((((background light))
+     :inherit (company-tooltip-selection company-tooltip))
+    (((background dark))
+     :background "blue4"
+     :foreground "wheat"))
+  "Face used for the completion preview.")
+
+(defface company-preview-common
+  '((((background light))
+     :inherit company-tooltip-common-selection)
+    (((background dark))
+     :inherit company-preview
+     :foreground "red"))
+  "Face used for the common part of the completion preview.")
+
+(defface company-preview-search
+  '((((background light))
+     :inherit company-tooltip-common-selection)
+    (((background dark))
+     :inherit company-preview
+     :background "blue1"))
+  "Face used for the search string in the completion preview.")
+
+(defface company-echo nil
+  "Face used for completions in the echo area.")
+
+(defface company-echo-common
+  '((((background dark)) (:foreground "firebrick1"))
+    (((background light)) (:background "firebrick4")))
+  "Face used for the common part of completions in the echo area.")
+
+(defun company-frontends-set (variable value)
+  ;; Uniquify.
+  (let ((value (delete-dups (copy-sequence value))))
+    (and (or (and (memq 'company-pseudo-tooltip-unless-just-one-frontend value)
+                  (memq 'company-pseudo-tooltip-frontend value))
+             (and (memq 'company-pseudo-tooltip-unless-just-one-frontend-with-delay value)
+                  (memq 'company-pseudo-tooltip-frontend value))
+             (and (memq 'company-pseudo-tooltip-unless-just-one-frontend-with-delay value)
+                  (memq 'company-pseudo-tooltip-unless-just-one-frontend value)))
+         (user-error "Pseudo tooltip frontend cannot be used more than once"))
+    (and (or (and (memq 'company-preview-if-just-one-frontend value)
+                  (memq 'company-preview-frontend value))
+             (and (memq 'company-preview-if-just-one-frontend value)
+                  (memq 'company-preview-common-frontend value))
+             (and (memq 'company-preview-frontend value)
+                  (memq 'company-preview-common-frontend value))
+             )
+         (user-error "Preview frontend cannot be used twice"))
+    (and (memq 'company-echo value)
+         (memq 'company-echo-metadata-frontend value)
+         (user-error "Echo area cannot be used twice"))
+    ;; Preview must come last.
+    (dolist (f '(company-preview-if-just-one-frontend company-preview-frontend company-preview-common-frontend))
+      (when (cdr (memq f value))
+        (setq value (append (delq f value) (list f)))))
+    (set variable value)))
+
+(defcustom company-frontends '(company-pseudo-tooltip-unless-just-one-frontend
+                               company-preview-if-just-one-frontend
+                               company-echo-metadata-frontend)
+  "The list of active frontends (visualizations).
+Each frontend is a function that takes one argument.  It is called with
+one of the following arguments:
+
+`show': When the visualization should start.
+
+`hide': When the visualization should end.
+
+`update': When the data has been updated.
+
+`pre-command': Before every command that is executed while the
+visualization is active.
+
+`post-command': After every command that is executed while the
+visualization is active.
+
+The visualized data is stored in `company-prefix', `company-candidates',
+`company-common', `company-selection', `company-point' and
+`company-search-string'."
+  :set 'company-frontends-set
+  :type '(repeat (choice (const :tag "echo" company-echo-frontend)
+                         (const :tag "echo, strip common"
+                                company-echo-strip-common-frontend)
+                         (const :tag "show echo meta-data in echo"
+                                company-echo-metadata-frontend)
+                         (const :tag "pseudo tooltip"
+                                company-pseudo-tooltip-frontend)
+                         (const :tag "pseudo tooltip, multiple only"
+                                company-pseudo-tooltip-unless-just-one-frontend)
+                         (const :tag "pseudo tooltip, multiple only, delayed"
+                                company-pseudo-tooltip-unless-just-one-frontend-with-delay)
+                         (const :tag "preview" company-preview-frontend)
+                         (const :tag "preview, unique only"
+                                company-preview-if-just-one-frontend)
+                         (const :tag "preview, common"
+                                company-preview-common-frontend)
+                         (function :tag "custom function" nil))))
+
+(defcustom company-tooltip-limit 10
+  "The maximum number of candidates in the tooltip."
+  :type 'integer)
+
+(defcustom company-tooltip-minimum 6
+  "The minimum height of the tooltip.
+If this many lines are not available, prefer to display the tooltip above."
+  :type 'integer)
+
+(defcustom company-tooltip-minimum-width 0
+  "The minimum width of the tooltip's inner area.
+This doesn't include the margins and the scroll bar."
+  :type 'integer
+  :package-version '(company . "0.8.0"))
+
+(defcustom company-tooltip-maximum-width most-positive-fixnum
+  "The maximum width of the tooltip's inner area.
+This doesn't include the margins and the scroll bar."
+  :type 'integer
+  :package-version '(company . "0.9.5"))
+
+(defcustom company-tooltip-margin 1
+  "Width of margin columns to show around the toolip."
+  :type 'integer)
+
+(defcustom company-tooltip-offset-display 'scrollbar
+  "Method using which the tooltip displays scrolling position.
+`scrollbar' means draw a scrollbar to the right of the items.
+`lines' means wrap items in lines with \"before\" and \"after\" counters."
+  :type '(choice (const :tag "Scrollbar" scrollbar)
+                 (const :tag "Two lines" lines)))
+
+(defcustom company-tooltip-align-annotations nil
+  "When non-nil, align annotations to the right tooltip border."
+  :type 'boolean
+  :package-version '(company . "0.7.1"))
+
+(defcustom company-tooltip-flip-when-above nil
+  "Whether to flip the tooltip when it's above the current line."
+  :type 'boolean
+  :package-version '(company . "0.8.1"))
+
+(defvar company-safe-backends
+  '((company-abbrev . "Abbrev")
+    (company-bbdb . "BBDB")
+    (company-capf . "completion-at-point-functions")
+    (company-clang . "Clang")
+    (company-cmake . "CMake")
+    (company-css . "CSS")
+    (company-dabbrev . "dabbrev for plain text")
+    (company-dabbrev-code . "dabbrev for code")
+    (company-eclim . "Eclim (an Eclipse interface)")
+    (company-elisp . "Emacs Lisp")
+    (company-etags . "etags")
+    (company-files . "Files")
+    (company-gtags . "GNU Global")
+    (company-ispell . "Ispell")
+    (company-keywords . "Programming language keywords")
+    (company-nxml . "nxml")
+    (company-oddmuse . "Oddmuse")
+    (company-semantic . "Semantic")
+    (company-tempo . "Tempo templates")
+    (company-xcode . "Xcode")))
+(put 'company-safe-backends 'risky-local-variable t)
+
+(defun company-safe-backends-p (backends)
+  (and (consp backends)
+       (not (cl-dolist (backend backends)
+              (unless (if (consp backend)
+                          (company-safe-backends-p backend)
+                        (assq backend company-safe-backends))
+                (cl-return t))))))
+
+(defcustom company-backends `(,@(unless (version< "24.3.51" emacs-version)
+                                  (list 'company-elisp))
+                              company-bbdb
+                              ,@(unless (version<= "26" emacs-version)
+                                  (list 'company-nxml))
+                              ,@(unless (version<= "26" emacs-version)
+                                  (list 'company-css))
+                              company-eclim company-semantic company-clang
+                              company-xcode company-cmake
+                              company-capf
+                              company-files
+                              (company-dabbrev-code company-gtags company-etags
+                               company-keywords)
+                              company-oddmuse company-dabbrev)
+  "The list of active backends (completion engines).
+
+Only one backend is used at a time.  The choice depends on the order of
+the items in this list, and on the values they return in response to the
+`prefix' command (see below).  But a backend can also be a \"grouped\"
+one (see below).
+
+`company-begin-backend' can be used to start a specific backend,
+`company-other-backend' will skip to the next matching backend in the list.
+
+Each backend is a function that takes a variable number of arguments.
+The first argument is the command requested from the backend.  It is one
+of the following:
+
+`prefix': The backend should return the text to be completed.  It must be
+text immediately before point.  Returning nil from this command passes
+control to the next backend.  The function should return `stop' if it
+should complete but cannot (e.g. when in the middle of a symbol).
+Instead of a string, the backend may return a cons (PREFIX . LENGTH)
+where LENGTH is a number used in place of PREFIX's length when
+comparing against `company-minimum-prefix-length'.  LENGTH can also
+be just t, and in the latter case the test automatically succeeds.
+
+`candidates': The second argument is the prefix to be completed.  The
+return value should be a list of candidates that match the prefix.
+
+Non-prefix matches are also supported (candidates that don't start with the
+prefix, but match it in some backend-defined way).  Backends that use this
+feature must disable cache (return t to `no-cache') and might also want to
+respond to `match'.
+
+Optional commands
+=================
+
+`sorted': Return t here to indicate that the candidates are sorted and will
+not need to be sorted again.
+
+`duplicates': If non-nil, company will take care of removing duplicates
+from the list.
+
+`no-cache': Usually company doesn't ask for candidates again as completion
+progresses, unless the backend returns t for this command.  The second
+argument is the latest prefix.
+
+`ignore-case': Return t here if the backend returns case-insensitive
+matches.  This value is used to determine the longest common prefix (as
+used in `company-complete-common'), and to filter completions when fetching
+them from cache.
+
+`meta': The second argument is a completion candidate.  Return a (short)
+documentation string for it.
+
+`doc-buffer': The second argument is a completion candidate.  Return a
+buffer with documentation for it.  Preferably use `company-doc-buffer'.  If
+not all buffer contents pertain to this candidate, return a cons of buffer
+and window start position.
+
+`location': The second argument is a completion candidate.  Return a cons
+of buffer and buffer location, or of file and line number where the
+completion candidate was defined.
+
+`annotation': The second argument is a completion candidate.  Return a
+string to be displayed inline with the candidate in the popup.  If
+duplicates are removed by company, candidates with equal string values will
+be kept if they have different annotations.  For that to work properly,
+backends should store the related information on candidates using text
+properties.
+
+`match': The second argument is a completion candidate.  Return a positive
+integer, the index after the end of text matching `prefix' within the
+candidate string.  Alternatively, return a list of (CHUNK-START
+. CHUNK-END) elements, where CHUNK-START and CHUNK-END are indexes within
+the candidate string.  The corresponding regions are be used when rendering
+the popup.  This command only makes sense for backends that provide
+non-prefix completion.
+
+`require-match': If this returns t, the user is not allowed to enter
+anything not offered as a candidate.  Please don't use that value in normal
+backends.  The default value nil gives the user that choice with
+`company-require-match'.  Return value `never' overrides that option the
+other way around.
+
+`init': Called once for each buffer. The backend can check for external
+programs and files and load any required libraries.  Raising an error here
+will show up in message log once, and the backend will not be used for
+completion.
+
+`post-completion': Called after a completion candidate has been inserted
+into the buffer.  The second argument is the candidate.  Can be used to
+modify it, e.g. to expand a snippet.
+
+The backend should return nil for all commands it does not support or
+does not know about.  It should also be callable interactively and use
+`company-begin-backend' to start itself in that case.
+
+Grouped backends
+================
+
+An element of `company-backends' can also be a list of backends.  The
+completions from backends in such groups are merged, but only from those
+backends which return the same `prefix'.
+
+If a backend command takes a candidate as an argument (e.g. `meta'), the
+call is dispatched to the backend the candidate came from.  In other
+cases (except for `duplicates' and `sorted'), the first non-nil value among
+all the backends is returned.
+
+The group can also contain keywords.  Currently, `:with' and `:separate'
+keywords are defined.  If the group contains keyword `:with', the backends
+listed after this keyword are ignored for the purpose of the `prefix'
+command.  If the group contains keyword `:separate', the candidates that
+come from different backends are sorted separately in the combined list.
+
+Asynchronous backends
+=====================
+
+The return value of each command can also be a cons (:async . FETCHER)
+where FETCHER is a function of one argument, CALLBACK.  When the data
+arrives, FETCHER must call CALLBACK and pass it the appropriate return
+value, as described above.  That call must happen in the same buffer as
+where completion was initiated.
+
+True asynchronous operation is only supported for command `candidates', and
+only during idle completion.  Other commands will block the user interface,
+even if the backend uses the asynchronous calling convention."
+  :type `(repeat
+          (choice
+           :tag "backend"
+           ,@(mapcar (lambda (b) `(const :tag ,(cdr b) ,(car b)))
+                     company-safe-backends)
+           (symbol :tag "User defined")
+           (repeat :tag "Merged backends"
+                   (choice :tag "backend"
+                           ,@(mapcar (lambda (b)
+                                       `(const :tag ,(cdr b) ,(car b)))
+                                     company-safe-backends)
+                           (const :tag "With" :with)
+                           (symbol :tag "User defined"))))))
+
+(put 'company-backends 'safe-local-variable 'company-safe-backends-p)
+
+(defcustom company-transformers nil
+  "Functions to change the list of candidates received from backends.
+
+Each function gets called with the return value of the previous one.
+The first one gets passed the list of candidates, already sorted and
+without duplicates."
+  :type '(choice
+          (const :tag "None" nil)
+          (const :tag "Sort by occurrence" (company-sort-by-occurrence))
+          (const :tag "Sort by backend importance"
+                 (company-sort-by-backend-importance))
+          (const :tag "Prefer case sensitive prefix"
+                 (company-sort-prefer-same-case-prefix))
+          (repeat :tag "User defined" (function))))
+
+(defcustom company-completion-started-hook nil
+  "Hook run when company starts completing.
+The hook is called with one argument that is non-nil if the completion was
+started manually."
+  :type 'hook)
+
+(defcustom company-completion-cancelled-hook nil
+  "Hook run when company cancels completing.
+The hook is called with one argument that is non-nil if the completion was
+aborted manually."
+  :type 'hook)
+
+(defcustom company-completion-finished-hook nil
+  "Hook run when company successfully completes.
+The hook is called with the selected candidate as an argument.
+
+If you indend to use it to post-process candidates from a specific
+backend, consider using the `post-completion' command instead."
+  :type 'hook)
+
+(defcustom company-minimum-prefix-length 3
+  "The minimum prefix length for idle completion."
+  :type '(integer :tag "prefix length"))
+
+(defcustom company-abort-manual-when-too-short nil
+  "If enabled, cancel a manually started completion when the prefix gets
+shorter than both `company-minimum-prefix-length' and the length of the
+prefix it was started from."
+  :type 'boolean
+  :package-version '(company . "0.8.0"))
+
+(defcustom company-require-match 'company-explicit-action-p
+  "If enabled, disallow non-matching input.
+This can be a function do determine if a match is required.
+
+This can be overridden by the backend, if it returns t or `never' to
+`require-match'.  `company-auto-complete' also takes precedence over this."
+  :type '(choice (const :tag "Off" nil)
+                 (function :tag "Predicate function")
+                 (const :tag "On, if user interaction took place"
+                        'company-explicit-action-p)
+                 (const :tag "On" t)))
+
+(defcustom company-auto-complete nil
+  "Determines when to auto-complete.
+If this is enabled, all characters from `company-auto-complete-chars'
+trigger insertion of the selected completion candidate.
+This can also be a function."
+  :type '(choice (const :tag "Off" nil)
+                 (function :tag "Predicate function")
+                 (const :tag "On, if user interaction took place"
+                        'company-explicit-action-p)
+                 (const :tag "On" t)))
+
+(defcustom company-auto-complete-chars '(?\  ?\) ?.)
+  "Determines which characters trigger auto-completion.
+See `company-auto-complete'.  If this is a string, each string character
+tiggers auto-completion.  If it is a list of syntax description characters (see
+`modify-syntax-entry'), all characters with that syntax auto-complete.
+
+This can also be a function, which is called with the new input and should
+return non-nil if company should auto-complete.
+
+A character that is part of a valid candidate never triggers auto-completion."
+  :type '(choice (string :tag "Characters")
+                 (set :tag "Syntax"
+                      (const :tag "Whitespace" ?\ )
+                      (const :tag "Symbol" ?_)
+                      (const :tag "Opening parentheses" ?\()
+                      (const :tag "Closing parentheses" ?\))
+                      (const :tag "Word constituent" ?w)
+                      (const :tag "Punctuation." ?.)
+                      (const :tag "String quote." ?\")
+                      (const :tag "Paired delimiter." ?$)
+                      (const :tag "Expression quote or prefix operator." ?\')
+                      (const :tag "Comment starter." ?<)
+                      (const :tag "Comment ender." ?>)
+                      (const :tag "Character-quote." ?/)
+                      (const :tag "Generic string fence." ?|)
+                      (const :tag "Generic comment fence." ?!))
+                 (function :tag "Predicate function")))
+
+(defcustom company-idle-delay .5
+  "The idle delay in seconds until completion starts automatically.
+The prefix still has to satisfy `company-minimum-prefix-length' before that
+happens.  The value of nil means no idle completion."
+  :type '(choice (const :tag "never (nil)" nil)
+                 (const :tag "immediate (0)" 0)
+                 (number :tag "seconds")))
+
+(defcustom company-tooltip-idle-delay .5
+  "The idle delay in seconds until tooltip is shown when using
+`company-pseudo-tooltip-unless-just-one-frontend-with-delay'."
+  :type '(choice (const :tag "never (nil)" nil)
+                 (const :tag "immediate (0)" 0)
+                 (number :tag "seconds")))
+
+(defcustom company-begin-commands '(self-insert-command
+                                    org-self-insert-command
+                                    orgtbl-self-insert-command
+                                    c-scope-operator
+                                    c-electric-colon
+                                    c-electric-lt-gt
+                                    c-electric-slash)
+  "A list of commands after which idle completion is allowed.
+If this is t, it can show completions after any command except a few from a
+pre-defined list.  See `company-idle-delay'.
+
+Alternatively, any command with a non-nil `company-begin' property is
+treated as if it was on this list."
+  :type '(choice (const :tag "Any command" t)
+                 (const :tag "Self insert command" '(self-insert-command))
+                 (repeat :tag "Commands" function))
+  :package-version '(company . "0.8.4"))
+
+(defcustom company-continue-commands '(not save-buffer save-some-buffers
+                                           save-buffers-kill-terminal
+                                           save-buffers-kill-emacs
+                                           completion-at-point)
+  "A list of commands that are allowed during completion.
+If this is t, or if `company-begin-commands' is t, any command is allowed.
+Otherwise, the value must be a list of symbols.  If it starts with `not',
+the cdr is the list of commands that abort completion.  Otherwise, all
+commands except those in that list, or in `company-begin-commands', or
+commands in the `company-' namespace, abort completion."
+  :type '(choice (const :tag "Any command" t)
+                 (cons  :tag "Any except"
+                        (const not)
+                        (repeat :tag "Commands" function))
+                 (repeat :tag "Commands" function)))
+
+(defcustom company-show-numbers nil
+  "If enabled, show quick-access numbers for the first ten candidates."
+  :type '(choice (const :tag "off" nil)
+                 (const :tag "on" t)))
+
+(defcustom company-selection-wrap-around nil
+  "If enabled, selecting item before first or after last wraps around."
+  :type '(choice (const :tag "off" nil)
+                 (const :tag "on" t)))
+
+(defvar company-async-wait 0.03
+  "Pause between checks to see if the value's been set when turning an
+asynchronous call into synchronous.")
+
+(defvar company-async-timeout 2
+  "Maximum wait time for a value to be set during asynchronous call.")
+
+;;; mode ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defvar company-mode-map (make-sparse-keymap)
+  "Keymap used by `company-mode'.")
+
+(defvar company-active-map
+  (let ((keymap (make-sparse-keymap)))
+    (define-key keymap "\e\e\e" 'company-abort)
+    (define-key keymap "\C-g" 'company-abort)
+    (define-key keymap (kbd "M-n") 'company-select-next)
+    (define-key keymap (kbd "M-p") 'company-select-previous)
+    (define-key keymap (kbd "<down>") 'company-select-next-or-abort)
+    (define-key keymap (kbd "<up>") 'company-select-previous-or-abort)
+    (define-key keymap [remap scroll-up-command] 'company-next-page)
+    (define-key keymap [remap scroll-down-command] 'company-previous-page)
+    (define-key keymap [down-mouse-1] 'ignore)
+    (define-key keymap [down-mouse-3] 'ignore)
+    (define-key keymap [mouse-1] 'company-complete-mouse)
+    (define-key keymap [mouse-3] 'company-select-mouse)
+    (define-key keymap [up-mouse-1] 'ignore)
+    (define-key keymap [up-mouse-3] 'ignore)
+    (define-key keymap [return] 'company-complete-selection)
+    (define-key keymap (kbd "RET") 'company-complete-selection)
+    (define-key keymap [tab] 'company-complete-common)
+    (define-key keymap (kbd "TAB") 'company-complete-common)
+    (define-key keymap (kbd "<f1>") 'company-show-doc-buffer)
+    (define-key keymap (kbd "C-h") 'company-show-doc-buffer)
+    (define-key keymap "\C-w" 'company-show-location)
+    (define-key keymap "\C-s" 'company-search-candidates)
+    (define-key keymap "\C-\M-s" 'company-filter-candidates)
+    (dotimes (i 10)
+      (define-key keymap (read-kbd-macro (format "M-%d" i)) 'company-complete-number))
+     keymap)
+  "Keymap that is enabled during an active completion.")
+
+(defvar company--disabled-backends nil)
+
+(defun company-init-backend (backend)
+  (and (symbolp backend)
+       (not (fboundp backend))
+       (ignore-errors (require backend nil t)))
+  (cond
+   ((symbolp backend)
+    (condition-case err
+        (progn
+          (funcall backend 'init)
+          (put backend 'company-init t))
+      (error
+       (put backend 'company-init 'failed)
+       (unless (memq backend company--disabled-backends)
+         (message "Company backend '%s' could not be initialized:\n%s"
+                  backend (error-message-string err)))
+       (cl-pushnew backend company--disabled-backends)
+       nil)))
+   ;; No initialization for lambdas.
+   ((functionp backend) t)
+   (t ;; Must be a list.
+    (cl-dolist (b backend)
+      (unless (keywordp b)
+        (company-init-backend b))))))
+
+(defun company--maybe-init-backend (backend)
+  (or (not (symbolp backend))
+      (eq t (get backend 'company-init))
+      (unless (get backend 'company-init)
+        (company-init-backend backend))))
+
+(defcustom company-lighter-base "company"
+  "Base string to use for the `company-mode' lighter."
+  :type 'string
+  :package-version '(company . "0.8.10"))
+
+(defvar company-lighter '(" "
+                          (company-candidates
+                           (:eval
+                            (if (consp company-backend)
+                                (company--group-lighter (nth company-selection
+                                                             company-candidates)
+                                                        company-lighter-base)
+                              (symbol-name company-backend)))
+                           company-lighter-base))
+  "Mode line lighter for Company.
+
+The value of this variable is a mode line template as in
+`mode-line-format'.")
+
+(put 'company-lighter 'risky-local-variable t)
+
+;;;###autoload
+(define-minor-mode company-mode
+  "\"complete anything\"; is an in-buffer completion framework.
+Completion starts automatically, depending on the values
+`company-idle-delay' and `company-minimum-prefix-length'.
+
+Completion can be controlled with the commands:
+`company-complete-common', `company-complete-selection', `company-complete',
+`company-select-next', `company-select-previous'.  If these commands are
+called before `company-idle-delay', completion will also start.
+
+Completions can be searched with `company-search-candidates' or
+`company-filter-candidates'.  These can be used while completion is
+inactive, as well.
+
+The completion data is retrieved using `company-backends' and displayed
+using `company-frontends'.  If you want to start a specific backend, call
+it interactively or use `company-begin-backend'.
+
+By default, the completions list is sorted alphabetically, unless the
+backend chooses otherwise, or `company-transformers' changes it later.
+
+regular keymap (`company-mode-map'):
+
+\\{company-mode-map}
+keymap during active completions (`company-active-map'):
+
+\\{company-active-map}"
+  nil company-lighter company-mode-map
+  (if company-mode
+      (progn
+        (add-hook 'pre-command-hook 'company-pre-command nil t)
+        (add-hook 'post-command-hook 'company-post-command nil t)
+        (mapc 'company-init-backend company-backends))
+    (remove-hook 'pre-command-hook 'company-pre-command t)
+    (remove-hook 'post-command-hook 'company-post-command t)
+    (company-cancel)
+    (kill-local-variable 'company-point)))
+
+(defcustom company-global-modes t
+  "Modes for which `company-mode' mode is turned on by `global-company-mode'.
+If nil, means no modes.  If t, then all major modes have it turned on.
+If a list, it should be a list of `major-mode' symbol names for which
+`company-mode' should be automatically turned on.  The sense of the list is
+negated if it begins with `not'.  For example:
+ (c-mode c++-mode)
+means that `company-mode' is turned on for buffers in C and C++ modes only.
+ (not message-mode)
+means that `company-mode' is always turned on except in `message-mode' buffers."
+  :type '(choice (const :tag "none" nil)
+                 (const :tag "all" t)
+                 (set :menu-tag "mode specific" :tag "modes"
+                      :value (not)
+                      (const :tag "Except" not)
+                      (repeat :inline t (symbol :tag "mode")))))
+
+;;;###autoload
+(define-globalized-minor-mode global-company-mode company-mode company-mode-on)
+
+(defun company-mode-on ()
+  (when (and (not (or noninteractive (eq (aref (buffer-name) 0) ?\s)))
+             (cond ((eq company-global-modes t)
+                    t)
+                   ((eq (car-safe company-global-modes) 'not)
+                    (not (memq major-mode (cdr company-global-modes))))
+                   (t (memq major-mode company-global-modes))))
+    (company-mode 1)))
+
+(defsubst company-assert-enabled ()
+  (unless company-mode
+    (company-uninstall-map)
+    (user-error "Company not enabled")))
+
+;;; keymaps ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defvar-local company-my-keymap nil)
+
+(defvar company-emulation-alist '((t . nil)))
+
+(defsubst company-enable-overriding-keymap (keymap)
+  (company-uninstall-map)
+  (setq company-my-keymap keymap))
+
+(defun company-ensure-emulation-alist ()
+  (unless (eq 'company-emulation-alist (car emulation-mode-map-alists))
+    (setq emulation-mode-map-alists
+          (cons 'company-emulation-alist
+                (delq 'company-emulation-alist emulation-mode-map-alists)))))
+
+(defun company-install-map ()
+  (unless (or (cdar company-emulation-alist)
+              (null company-my-keymap))
+    (setf (cdar company-emulation-alist) company-my-keymap)))
+
+(defun company-uninstall-map ()
+  (setf (cdar company-emulation-alist) nil))
+
+(defun company--company-command-p (keys)
+  "Checks if the keys are part of company's overriding keymap"
+  (or (equal [company-dummy-event] keys)
+      (lookup-key company-my-keymap keys)))
+
+;; Hack:
+;; Emacs calculates the active keymaps before reading the event.  That means we
+;; cannot change the keymap from a timer.  So we send a bogus command.
+;; XXX: Even in Emacs 24.4, seems to be needed in the terminal.
+(defun company-ignore ()
+  (interactive)
+  (setq this-command last-command))
+
+(global-set-key '[company-dummy-event] 'company-ignore)
+
+(defun company-input-noop ()
+  (push 'company-dummy-event unread-command-events))
+
+;; To avoid warnings in Emacs < 26.
+(declare-function line-number-display-width "indent.c")
+
+(defun company--posn-col-row (posn)
+  (let ((col (car (posn-col-row posn)))
+        ;; `posn-col-row' doesn't work well with lines of different height.
+        ;; `posn-actual-col-row' doesn't handle multiple-width characters.
+        (row (cdr (or (posn-actual-col-row posn)
+                      ;; When position is non-visible for some reason.
+                      (posn-col-row posn)))))
+    (when (and header-line-format (version< emacs-version "24.3.93.3"))
+      ;; http://debbugs.gnu.org/18384
+      (cl-decf row))
+    (when (bound-and-true-p display-line-numbers)
+      (cl-decf col (+ 2 (line-number-display-width))))
+    (cons (+ col (window-hscroll)) row)))
+
+(defun company--col-row (&optional pos)
+  (company--posn-col-row (posn-at-point pos)))
+
+(defun company--row (&optional pos)
+  (cdr (company--col-row pos)))
+
+;;; backends ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defvar-local company-backend nil)
+
+(defun company-grab (regexp &optional expression limit)
+  (when (looking-back regexp limit)
+    (or (match-string-no-properties (or expression 0)) "")))
+
+(defun company-grab-line (regexp &optional expression)
+  "Return a match string for REGEXP if it matches text before point.
+If EXPRESSION is non-nil, return the match string for the respective
+parenthesized expression in REGEXP.
+Matching is limited to the current line."
+  (let ((inhibit-field-text-motion t))
+    (company-grab regexp expression (point-at-bol))))
+
+(defun company-grab-symbol ()
+  "If point is at the end of a symbol, return it.
+Otherwise, if point is not inside a symbol, return an empty string."
+  (if (looking-at "\\_>")
+      (buffer-substring (point) (save-excursion (skip-syntax-backward "w_")
+                                                (point)))
+    (unless (and (char-after) (memq (char-syntax (char-after)) '(?w ?_)))
+      "")))
+
+(defun company-grab-word ()
+  "If point is at the end of a word, return it.
+Otherwise, if point is not inside a symbol, return an empty string."
+  (if (looking-at "\\>")
+      (buffer-substring (point) (save-excursion (skip-syntax-backward "w")
+                                                (point)))
+    (unless (and (char-after) (eq (char-syntax (char-after)) ?w))
+      "")))
+
+(defun company-grab-symbol-cons (idle-begin-after-re &optional max-len)
+  "Return a string SYMBOL or a cons (SYMBOL . t).
+SYMBOL is as returned by `company-grab-symbol'.  If the text before point
+matches IDLE-BEGIN-AFTER-RE, return it wrapped in a cons."
+  (let ((symbol (company-grab-symbol)))
+    (when symbol
+      (save-excursion
+        (forward-char (- (length symbol)))
+        (if (looking-back idle-begin-after-re (if max-len
+                                                  (- (point) max-len)
+                                                (line-beginning-position)))
+            (cons symbol t)
+          symbol)))))
+
+(defun company-in-string-or-comment ()
+  "Return non-nil if point is within a string or comment."
+  (let ((ppss (syntax-ppss)))
+    (or (car (setq ppss (nthcdr 3 ppss)))
+        (car (setq ppss (cdr ppss)))
+        (nth 3 ppss))))
+
+(defun company-call-backend (&rest args)
+  (company--force-sync #'company-call-backend-raw args company-backend))
+
+(defun company--force-sync (fun args backend)
+  (let ((value (apply fun args)))
+    (if (not (eq (car-safe value) :async))
+        value
+      (let ((res 'trash)
+            (start (time-to-seconds)))
+        (funcall (cdr value)
+                 (lambda (result) (setq res result)))
+        (while (eq res 'trash)
+          (if (> (- (time-to-seconds) start) company-async-timeout)
+              (error "Company: backend %s async timeout with args %s"
+                     backend args)
+            ;; XXX: Reusing the trick from company--fetch-candidates here
+            ;; doesn't work well: sit-for isn't a good fit when we want to
+            ;; ignore pending input (results in too many calls).
+            ;; FIXME: We should deal with this by standardizing on a kind of
+            ;; Future object that knows how to sync itself. In most cases (but
+            ;; not all), by calling accept-process-output, probably.
+            (sleep-for company-async-wait)))
+        res))))
+
+(defun company-call-backend-raw (&rest args)
+  (condition-case-unless-debug err
+      (if (functionp company-backend)
+          (apply company-backend args)
+        (apply #'company--multi-backend-adapter company-backend args))
+    (user-error (user-error
+                 "Company: backend %s user-error: %s"
+                 company-backend (error-message-string err)))
+    (error (error "Company: backend %s error \"%s\" with args %s"
+                  company-backend (error-message-string err) args))))
+
+(defun company--multi-backend-adapter (backends command &rest args)
+  (let ((backends (cl-loop for b in backends
+                           when (or (keywordp b)
+                                    (company--maybe-init-backend b))
+                           collect b))
+        (separate (memq :separate backends)))
+
+    (when (eq command 'prefix)
+      (setq backends (butlast backends (length (member :with backends)))))
+
+    (setq backends (cl-delete-if #'keywordp backends))
+
+    (pcase command
+      (`candidates
+       (company--multi-backend-adapter-candidates backends (car args) separate))
+      (`sorted separate)
+      (`duplicates (not separate))
+      ((or `prefix `ignore-case `no-cache `require-match)
+       (let (value)
+         (cl-dolist (backend backends)
+           (when (setq value (company--force-sync
+                              backend (cons command args) backend))
+             (cl-return value)))))
+      (_
+       (let ((arg (car args)))
+         (when (> (length arg) 0)
+           (let ((backend (or (get-text-property 0 'company-backend arg)
+                              (car backends))))
+             (apply backend command args))))))))
+
+(defun company--multi-backend-adapter-candidates (backends prefix separate)
+  (let ((pairs (cl-loop for backend in backends
+                        when (equal (company--prefix-str
+                                     (let ((company-backend backend))
+                                       (company-call-backend 'prefix)))
+                                    prefix)
+                        collect (cons (funcall backend 'candidates prefix)
+                                      (company--multi-candidates-mapper
+                                       backend
+                                       separate
+                                       ;; Small perf optimization: don't tag the
+                                       ;; candidates received from the first
+                                       ;; backend in the group.
+                                       (not (eq backend (car backends))))))))
+    (company--merge-async pairs (lambda (values) (apply #'append values)))))
+
+(defun company--multi-candidates-mapper (backend separate tag)
+  (lambda (candidates)
+    (when separate
+      (let ((company-backend backend))
+        (setq candidates
+              (company--preprocess-candidates candidates))))
+    (when tag
+      (setq candidates
+            (mapcar
+             (lambda (str)
+               (propertize str 'company-backend backend))
+             candidates)))
+    candidates))
+
+(defun company--merge-async (pairs merger)
+  (let ((async (cl-loop for pair in pairs
+                        thereis
+                        (eq :async (car-safe (car pair))))))
+    (if (not async)
+        (funcall merger (cl-loop for (val . mapper) in pairs
+                                 collect (funcall mapper val)))
+      (cons
+       :async
+       (lambda (callback)
+         (let* (lst
+                (pending (mapcar #'car pairs))
+                (finisher (lambda ()
+                            (unless pending
+                              (funcall callback
+                                       (funcall merger
+                                                (nreverse lst)))))))
+           (dolist (pair pairs)
+             (push nil lst)
+             (let* ((cell lst)
+                    (val (car pair))
+                    (mapper (cdr pair))
+                    (this-finisher (lambda (res)
+                                     (setq pending (delq val pending))
+                                     (setcar cell (funcall mapper res))
+                                     (funcall finisher))))
+               (if (not (eq :async (car-safe val)))
+                   (funcall this-finisher val)
+                 (let ((fetcher (cdr val)))
+                   (funcall fetcher this-finisher)))))))))))
+
+(defun company--prefix-str (prefix)
+  (or (car-safe prefix) prefix))
+
+;;; completion mechanism ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defvar-local company-prefix nil)
+
+(defvar-local company-candidates nil)
+
+(defvar-local company-candidates-length nil)
+
+(defvar-local company-candidates-cache nil)
+
+(defvar-local company-candidates-predicate nil)
+
+(defvar-local company-common nil)
+
+(defvar-local company-selection 0)
+
+(defvar-local company-selection-changed nil)
+
+(defvar-local company--manual-action nil
+  "Non-nil, if manual completion took place.")
+
+(defvar-local company--manual-prefix nil)
+
+(defvar company--auto-completion nil
+  "Non-nil when current candidate is being inserted automatically.
+Controlled by `company-auto-complete'.")
+
+(defvar-local company--point-max nil)
+
+(defvar-local company-point nil)
+
+(defvar company-timer nil)
+(defvar company-tooltip-timer nil)
+
+(defsubst company-strip-prefix (str)
+  (substring str (length company-prefix)))
+
+(defun company--insert-candidate (candidate)
+  (when (> (length candidate) 0)
+    (setq candidate (substring-no-properties candidate))
+    ;; XXX: Return value we check here is subject to change.
+    (if (eq (company-call-backend 'ignore-case) 'keep-prefix)
+        (insert (company-strip-prefix candidate))
+      (unless (equal company-prefix candidate)
+        (delete-region (- (point) (length company-prefix)) (point))
+        (insert candidate)))))
+
+(defmacro company-with-candidate-inserted (candidate &rest body)
+  "Evaluate BODY with CANDIDATE temporarily inserted.
+This is a tool for backends that need candidates inserted before they
+can retrieve meta-data for them."
+  (declare (indent 1))
+  `(let ((inhibit-modification-hooks t)
+         (inhibit-point-motion-hooks t)
+         (modified-p (buffer-modified-p)))
+     (company--insert-candidate ,candidate)
+     (unwind-protect
+         (progn ,@body)
+       (delete-region company-point (point))
+       (set-buffer-modified-p modified-p))))
+
+(defun company-explicit-action-p ()
+  "Return whether explicit completion action was taken by the user."
+  (or company--manual-action
+      company-selection-changed))
+
+(defun company-reformat (candidate)
+  ;; company-ispell needs this, because the results are always lower-case
+  ;; It's mory efficient to fix it only when they are displayed.
+  ;; FIXME: Adopt the current text's capitalization instead?
+  (if (eq (company-call-backend 'ignore-case) 'keep-prefix)
+      (concat company-prefix (substring candidate (length company-prefix)))
+    candidate))
+
+(defun company--should-complete ()
+  (and (eq company-idle-delay 'now)
+       (not (or buffer-read-only
+                overriding-local-map))
+       ;; Check if in the middle of entering a key combination.
+       (or (equal (this-command-keys-vector) [])
+           (not (keymapp (key-binding (this-command-keys-vector)))))
+       (not (and transient-mark-mode mark-active))))
+
+(defun company--should-continue ()
+  (or (eq t company-begin-commands)
+      (eq t company-continue-commands)
+      (if (eq 'not (car company-continue-commands))
+          (not (memq this-command (cdr company-continue-commands)))
+        (or (memq this-command company-begin-commands)
+            (memq this-command company-continue-commands)
+            (and (symbolp this-command)
+                 (string-match-p "\\`company-" (symbol-name this-command)))))))
+
+(defun company-call-frontends (command)
+  (dolist (frontend company-frontends)
+    (condition-case-unless-debug err
+        (funcall frontend command)
+      (error (error "Company: frontend %s error \"%s\" on command %s"
+                    frontend (error-message-string err) command)))))
+
+(defun company-set-selection (selection &optional force-update)
+  (setq selection
+        (if company-selection-wrap-around
+            (mod selection company-candidates-length)
+          (max 0 (min (1- company-candidates-length) selection))))
+  (when (or force-update (not (equal selection company-selection)))
+    (setq company-selection selection
+          company-selection-changed t)
+    (company-call-frontends 'update)))
+
+(defun company--group-lighter (candidate base)
+  (let ((backend (or (get-text-property 0 'company-backend candidate)
+                     (cl-some (lambda (x) (and (not (keywordp x)) x))
+                              company-backend))))
+    (when (and backend (symbolp backend))
+      (let ((name (replace-regexp-in-string "company-\\|-company" ""
+                                            (symbol-name backend))))
+        (format "%s-<%s>" base name)))))
+
+(defun company-update-candidates (candidates)
+  (setq company-candidates-length (length candidates))
+  (if company-selection-changed
+      ;; Try to restore the selection
+      (let ((selected (nth company-selection company-candidates)))
+        (setq company-selection 0
+              company-candidates candidates)
+        (when selected
+          (catch 'found
+            (while candidates
+              (let ((candidate (pop candidates)))
+                (when (and (string= candidate selected)
+                           (equal (company-call-backend 'annotation candidate)
+                                  (company-call-backend 'annotation selected)))
+                  (throw 'found t)))
+              (cl-incf company-selection))
+            (setq company-selection 0
+                  company-selection-changed nil))))
+    (setq company-selection 0
+          company-candidates candidates))
+  ;; Calculate common.
+  (let ((completion-ignore-case (company-call-backend 'ignore-case)))
+    ;; We want to support non-prefix completion, so filtering is the
+    ;; responsibility of each respective backend, not ours.
+    ;; On the other hand, we don't want to replace non-prefix input in
+    ;; `company-complete-common', unless there's only one candidate.
+    (setq company-common
+          (if (cdr company-candidates)
+              (let ((common (try-completion "" company-candidates)))
+                (when (string-prefix-p company-prefix common
+                                       completion-ignore-case)
+                  common))
+            (car company-candidates)))))
+
+(defun company-calculate-candidates (prefix)
+  (let ((candidates (cdr (assoc prefix company-candidates-cache)))
+        (ignore-case (company-call-backend 'ignore-case)))
+    (or candidates
+        (when company-candidates-cache
+          (let ((len (length prefix))
+                (completion-ignore-case ignore-case)
+                prev)
+            (cl-dotimes (i (1+ len))
+              (when (setq prev (cdr (assoc (substring prefix 0 (- len i))
+                                           company-candidates-cache)))
+                (setq candidates (all-completions prefix prev))
+                (cl-return t)))))
+        (progn
+          ;; No cache match, call the backend.
+          (setq candidates (company--preprocess-candidates
+                            (company--fetch-candidates prefix)))
+          ;; Save in cache.
+          (push (cons prefix candidates) company-candidates-cache)))
+    ;; Only now apply the predicate and transformers.
+    (setq candidates (company--postprocess-candidates candidates))
+    (when candidates
+      (if (or (cdr candidates)
+              (not (eq t (compare-strings (car candidates) nil nil
+                                          prefix nil nil ignore-case))))
+          candidates
+        ;; Already completed and unique; don't start.
+        t))))
+
+(defun company--fetch-candidates (prefix)
+  (let* ((non-essential (not (company-explicit-action-p)))
+         (c (if (or company-selection-changed
+                    ;; FIXME: This is not ideal, but we have not managed to deal
+                    ;; with these situations in a better way yet.
+                    (company-require-match-p))
+                (company-call-backend 'candidates prefix)
+              (company-call-backend-raw 'candidates prefix))))
+    (if (not (eq (car c) :async))
+        c
+      (let ((res 'none)
+            (inhibit-redisplay t))
+        (funcall
+         (cdr c)
+         (lambda (candidates)
+           (when (eq res 'none)
+             (push 'company-foo unread-command-events))
+           (setq res candidates)))
+        (if (company--flyspell-workaround-p)
+            (while (and (eq res 'none)
+                        (not (input-pending-p)))
+              (sleep-for company-async-wait))
+          (while (and (eq res 'none)
+                      (sit-for 0.5 t))))
+        (while (member (car unread-command-events)
+                       '(company-foo (t . company-foo)))
+          (pop unread-command-events))
+        (prog1
+            (and (consp res) res)
+          (setq res 'exited))))))
+
+(defun company--flyspell-workaround-p ()
+  ;; https://debbugs.gnu.org/23980
+  (and (bound-and-true-p flyspell-mode)
+       (version< emacs-version "27")))
+
+(defun company--preprocess-candidates (candidates)
+  (cl-assert (cl-every #'stringp candidates))
+  (unless (company-call-backend 'sorted)
+    (setq candidates (sort candidates 'string<)))
+  (when (company-call-backend 'duplicates)
+    (company--strip-duplicates candidates))
+  candidates)
+
+(defun company--postprocess-candidates (candidates)
+  (when (or company-candidates-predicate company-transformers)
+    (setq candidates (copy-sequence candidates)))
+  (when company-candidates-predicate
+    (setq candidates (cl-delete-if-not company-candidates-predicate candidates)))
+  (company--transform-candidates candidates))
+
+(defun company--strip-duplicates (candidates)
+  (let ((c2 candidates)
+        (annos 'unk))
+    (while c2
+      (setcdr c2
+              (let ((str (pop c2)))
+                (while (let ((str2 (car c2)))
+                         (if (not (equal str str2))
+                             (progn
+                               (setq annos 'unk)
+                               nil)
+                           (when (eq annos 'unk)
+                             (setq annos (list (company-call-backend
+                                                'annotation str))))
+                           (let ((anno2 (company-call-backend
+                                         'annotation str2)))
+                             (if (member anno2 annos)
+                                 t
+                               (push anno2 annos)
+                               nil))))
+                  (pop c2))
+                c2)))))
+
+(defun company--transform-candidates (candidates)
+  (let ((c candidates))
+    (dolist (tr company-transformers)
+      (setq c (funcall tr c)))
+    c))
+
+(defcustom company-occurrence-weight-function
+  #'company-occurrence-prefer-closest-above
+  "Function to weigh matches in `company-sort-by-occurrence'.
+It's called with three arguments: cursor position, the beginning and the
+end of the match."
+  :type '(choice
+          (const :tag "First above point, then below point"
+                 company-occurrence-prefer-closest-above)
+          (const :tag "Prefer closest in any direction"
+                 company-occurrence-prefer-any-closest)))
+
+(defun company-occurrence-prefer-closest-above (pos match-beg match-end)
+  "Give priority to the matches above point, then those below point."
+  (if (< match-beg pos)
+      (- pos match-end)
+    (- match-beg (window-start))))
+
+(defun company-occurrence-prefer-any-closest (pos _match-beg match-end)
+  "Give priority to the matches closest to the point."
+  (abs (- pos match-end)))
+
+(defun company-sort-by-occurrence (candidates)
+  "Sort CANDIDATES according to their occurrences.
+Searches for each in the currently visible part of the current buffer and
+prioritizes the matches according to `company-occurrence-weight-function'.
+The rest of the list is appended unchanged.
+Keywords and function definition names are ignored."
+  (let* ((w-start (window-start))
+         (w-end (window-end))
+         (start-point (point))
+         occurs
+         (noccurs
+          (save-excursion
+            (cl-delete-if
+             (lambda (candidate)
+               (when (catch 'done
+                       (goto-char w-start)
+                       (while (search-forward candidate w-end t)
+                         (when (and (not (eq (point) start-point))
+                                    (save-match-data
+                                      (company--occurrence-predicate)))
+                           (throw 'done t))))
+                 (push
+                  (cons candidate
+                        (funcall company-occurrence-weight-function
+                                 start-point
+                                 (match-beginning 0)
+                                 (match-end 0)))
+                  occurs)
+                 t))
+             candidates))))
+    (nconc
+     (mapcar #'car (sort occurs (lambda (e1 e2) (<= (cdr e1) (cdr e2)))))
+     noccurs)))
+
+(defun company--occurrence-predicate ()
+  (defvar comint-last-prompt)
+  (let ((beg (match-beginning 0))
+        (end (match-end 0))
+        (comint-last-prompt (bound-and-true-p comint-last-prompt)))
+    (save-excursion
+      (goto-char end)
+      ;; Workaround for python-shell-completion-at-point's behavior:
+      ;; https://github.com/company-mode/company-mode/issues/759
+      ;; https://github.com/company-mode/company-mode/issues/549
+      (when (derived-mode-p 'inferior-python-mode)
+        (let ((lbp (line-beginning-position)))
+          (setq comint-last-prompt (cons lbp lbp))))
+      (and (not (memq (get-text-property (1- (point)) 'face)
+                      '(font-lock-function-name-face
+                        font-lock-keyword-face)))
+           (let ((prefix (company--prefix-str
+                          (company-call-backend 'prefix))))
+             (and (stringp prefix)
+                  (= (length prefix) (- end beg))))))))
+
+(defun company-sort-by-backend-importance (candidates)
+  "Sort CANDIDATES as two priority groups.
+If `company-backend' is a function, do nothing.  If it's a list, move
+candidates from backends before keyword `:with' to the front.  Candidates
+from the rest of the backends in the group, if any, will be left at the end."
+  (if (functionp company-backend)
+      candidates
+    (let ((low-priority (cdr (memq :with company-backend))))
+      (if (null low-priority)
+          candidates
+        (sort candidates
+              (lambda (c1 c2)
+                (and
+                 (let ((b2 (get-text-property 0 'company-backend c2)))
+                   (and b2 (memq b2 low-priority)))
+                 (let ((b1 (get-text-property 0 'company-backend c1)))
+                   (or (not b1) (not (memq b1 low-priority)))))))))))
+
+(defun company-sort-prefer-same-case-prefix (candidates)
+  "Prefer CANDIDATES with the exact same prefix.
+If a backend returns case insensitive matches, candidates with the an exact
+prefix match (same case) will be prioritized."
+  (cl-loop for candidate in candidates
+           if (string-prefix-p company-prefix candidate)
+           collect candidate into same-case
+           else collect candidate into other-case
+           finally return (append same-case other-case)))
+
+(defun company-idle-begin (buf win tick pos)
+  (and (eq buf (current-buffer))
+       (eq win (selected-window))
+       (eq tick (buffer-chars-modified-tick))
+       (eq pos (point))
+       (when (company-auto-begin)
+         (company-input-noop)
+         (let ((this-command 'company-idle-begin))
+           (company-post-command)))))
+
+(defun company-auto-begin ()
+  (and company-mode
+       (not company-candidates)
+       (let ((company-idle-delay 'now))
+         (condition-case-unless-debug err
+             (progn
+               (company--perform)
+               ;; Return non-nil if active.
+               company-candidates)
+           (error (message "Company: An error occurred in auto-begin")
+                  (message "%s" (error-message-string err))
+                  (company-cancel))
+           (quit (company-cancel))))))
+
+;;;###autoload
+(defun company-manual-begin ()
+  (interactive)
+  (company-assert-enabled)
+  (setq company--manual-action t)
+  (unwind-protect
+      (let ((company-minimum-prefix-length 0))
+        (or company-candidates
+            (company-auto-begin)))
+    (unless company-candidates
+      (setq company--manual-action nil))))
+
+(defun company-other-backend (&optional backward)
+  (interactive (list current-prefix-arg))
+  (company-assert-enabled)
+  (let* ((after (if company-backend
+                    (cdr (member company-backend company-backends))
+                  company-backends))
+         (before (cdr (member company-backend (reverse company-backends))))
+         (next (if backward
+                   (append before (reverse after))
+                 (append after (reverse before)))))
+    (company-cancel)
+    (cl-dolist (backend next)
+      (when (ignore-errors (company-begin-backend backend))
+        (cl-return t))))
+  (unless company-candidates
+    (user-error "No other backend")))
+
+(defun company-require-match-p ()
+  (let ((backend-value (company-call-backend 'require-match)))
+    (or (eq backend-value t)
+        (and (not (eq backend-value 'never))
+             (if (functionp company-require-match)
+                 (funcall company-require-match)
+               (eq company-require-match t))))))
+
+(defun company-auto-complete-p (input)
+  "Return non-nil if INPUT should trigger auto-completion."
+  (and (if (functionp company-auto-complete)
+           (funcall company-auto-complete)
+         company-auto-complete)
+       (if (functionp company-auto-complete-chars)
+           (funcall company-auto-complete-chars input)
+         (if (consp company-auto-complete-chars)
+             (memq (char-syntax (string-to-char input))
+                   company-auto-complete-chars)
+           (string-match (regexp-quote (substring input 0 1))
+                          company-auto-complete-chars)))))
+
+(defun company--incremental-p ()
+  (and (> (point) company-point)
+       (> (point-max) company--point-max)
+       (not (eq this-command 'backward-delete-char-untabify))
+       (equal (buffer-substring (- company-point (length company-prefix))
+                                company-point)
+              company-prefix)))
+
+(defun company--continue-failed (new-prefix)
+  (cond
+   ((and (or (not (company-require-match-p))
+             ;; Don't require match if the new prefix
+             ;; doesn't continue the old one, and the latter was a match.
+             (not (stringp new-prefix))
+             (<= (length new-prefix) (length company-prefix)))
+         (member company-prefix company-candidates))
+    ;; Last input was a success,
+    ;; but we're treating it as an abort + input anyway,
+    ;; like the `unique' case below.
+    (company-cancel 'non-unique))
+   ((company-require-match-p)
+    ;; Wrong incremental input, but required match.
+    (delete-char (- company-point (point)))
+    (ding)
+    (message "Matching input is required")
+    company-candidates)
+   (t (company-cancel))))
+
+(defun company--good-prefix-p (prefix)
+  (and (stringp (company--prefix-str prefix)) ;excludes 'stop
+       (or (eq (cdr-safe prefix) t)
+           (let ((len (or (cdr-safe prefix) (length prefix))))
+             (if company--manual-prefix
+                 (or (not company-abort-manual-when-too-short)
+                     ;; Must not be less than minimum or initial length.
+                     (>= len (min company-minimum-prefix-length
+                                  (length company--manual-prefix))))
+               (>= len company-minimum-prefix-length))))))
+
+(defun company--continue ()
+  (when (company-call-backend 'no-cache company-prefix)
+    ;; Don't complete existing candidates, fetch new ones.
+    (setq company-candidates-cache nil))
+  (let* ((new-prefix (company-call-backend 'prefix))
+         (c (when (and (company--good-prefix-p new-prefix)
+                       (setq new-prefix (company--prefix-str new-prefix))
+                       (= (- (point) (length new-prefix))
+                          (- company-point (length company-prefix))))
+              (company-calculate-candidates new-prefix))))
+    (cond
+     ((eq c t)
+      ;; t means complete/unique.
+      ;; Handle it like completion was aborted, to differentiate from user
+      ;; calling one of Company's commands to insert the candidate,
+      ;; not to trigger template expansion, etc.
+      (company-cancel 'unique))
+     ((consp c)
+      ;; incremental match
+      (setq company-prefix new-prefix)
+      (company-update-candidates c)
+      c)
+     ((and (> (point) company-point)
+           (company-auto-complete-p (buffer-substring-no-properties
+                                     (point) company-point)))
+      ;; auto-complete
+      (save-excursion
+        (goto-char company-point)
+        (let ((company--auto-completion t))
+          (company-complete-selection))
+        nil))
+     ((not (company--incremental-p))
+      (company-cancel))
+     (t (company--continue-failed new-prefix)))))
+
+(defun company--begin-new ()
+  (let (prefix c)
+    (cl-dolist (backend (if company-backend
+                            ;; prefer manual override
+                            (list company-backend)
+                          company-backends))
+      (setq prefix
+            (if (or (symbolp backend)
+                    (functionp backend))
+                (when (company--maybe-init-backend backend)
+                  (let ((company-backend backend))
+                    (company-call-backend 'prefix)))
+              (company--multi-backend-adapter backend 'prefix)))
+      (when prefix
+        (when (company--good-prefix-p prefix)
+          (setq company-prefix (company--prefix-str prefix)
+                company-backend backend
+                c (company-calculate-candidates company-prefix))
+          (if (not (consp c))
+              (progn
+                (when company--manual-action
+                  (message "No completion found"))
+                (when (eq c t)
+                  ;; t means complete/unique.
+                  ;; Run the hooks anyway, to e.g. clear the cache.
+                  (company-cancel 'unique)))
+            (when company--manual-action
+              (setq company--manual-prefix prefix))
+            (company-update-candidates c)
+            (run-hook-with-args 'company-completion-started-hook
+                                (company-explicit-action-p))
+            (company-call-frontends 'show)))
+        (cl-return c)))))
+
+(defun company--perform ()
+  (or (and company-candidates (company--continue))
+      (and (company--should-complete) (company--begin-new)))
+  (if (not company-candidates)
+      (setq company-backend nil)
+    (setq company-point (point)
+          company--point-max (point-max))
+    (company-ensure-emulation-alist)
+    (company-enable-overriding-keymap company-active-map)
+    (company-call-frontends 'update)))
+
+(defun company-cancel (&optional result)
+  (let ((prefix company-prefix)
+        (backend company-backend))
+    (setq company-backend nil
+          company-prefix nil
+          company-candidates nil
+          company-candidates-length nil
+          company-candidates-cache nil
+          company-candidates-predicate nil
+          company-common nil
+          company-selection 0
+          company-selection-changed nil
+          company--manual-action nil
+          company--manual-prefix nil
+          company--point-max nil
+          company-point nil)
+    (when company-timer
+      (cancel-timer company-timer))
+    (company-echo-cancel t)
+    (company-search-mode 0)
+    (company-call-frontends 'hide)
+    (company-enable-overriding-keymap nil)
+    (when prefix
+      ;; FIXME: RESULT can also be e.g. `unique'.  We should call
+      ;; `company-completion-finished-hook' in that case, with right argument.
+      (if (stringp result)
+          (let ((company-backend backend))
+            (run-hook-with-args 'company-completion-finished-hook result)
+            (company-call-backend 'post-completion result))
+        (run-hook-with-args 'company-completion-cancelled-hook result))))
+  ;; Make return value explicit.
+  nil)
+
+(defun company-abort ()
+  (interactive)
+  (company-cancel 'abort))
+
+(defun company-finish (result)
+  (company--insert-candidate result)
+  (company-cancel result))
+
+(defsubst company-keep (command)
+  (and (symbolp command) (get command 'company-keep)))
+
+(defun company-pre-command ()
+  (company--electric-restore-window-configuration)
+  (unless (company-keep this-command)
+    (condition-case-unless-debug err
+        (when company-candidates
+          (company-call-frontends 'pre-command)
+          (unless (company--should-continue)
+            (company-abort)))
+      (error (message "Company: An error occurred in pre-command")
+             (message "%s" (error-message-string err))
+             (company-cancel))))
+  (when company-timer
+    (cancel-timer company-timer)
+    (setq company-timer nil))
+  (company-echo-cancel t)
+  (company-uninstall-map))
+
+(defun company-post-command ()
+  (when (and company-candidates
+             (null this-command))
+    ;; Happens when the user presses `C-g' while inside
+    ;; `flyspell-post-command-hook', for example.
+    ;; Or any other `post-command-hook' function that can call `sit-for',
+    ;; or any quittable timer function.
+    (company-abort)
+    (setq this-command 'company-abort))
+  (unless (company-keep this-command)
+    (condition-case-unless-debug err
+        (progn
+          (unless (equal (point) company-point)
+            (let (company-idle-delay) ; Against misbehavior while debugging.
+              (company--perform)))
+          (if company-candidates
+              (company-call-frontends 'post-command)
+            (and (or (numberp company-idle-delay)
+                     ;; Deprecated.
+                     (eq company-idle-delay t))
+                 (not defining-kbd-macro)
+                 (company--should-begin)
+                 (setq company-timer
+                       (run-with-timer (company--idle-delay) nil
+                                       'company-idle-begin
+                                       (current-buffer) (selected-window)
+                                       (buffer-chars-modified-tick) (point))))))
+      (error (message "Company: An error occurred in post-command")
+             (message "%s" (error-message-string err))
+             (company-cancel))))
+  (company-install-map))
+
+(defun company--idle-delay ()
+  (if (memql company-idle-delay '(t 0 0.0))
+      0.01
+    company-idle-delay))
+
+(defvar company--begin-inhibit-commands '(company-abort
+                                          company-complete-mouse
+                                          company-complete
+                                          company-complete-common
+                                          company-complete-selection
+                                          company-complete-number)
+  "List of commands after which idle completion is (still) disabled when
+`company-begin-commands' is t.")
+
+(defun company--should-begin ()
+  (if (eq t company-begin-commands)
+      (not (memq this-command company--begin-inhibit-commands))
+    (or
+     (memq this-command company-begin-commands)
+     (and (symbolp this-command) (get this-command 'company-begin)))))
+
+;;; search ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defcustom company-search-regexp-function #'regexp-quote
+  "Function to construct the search regexp from input.
+It's called with one argument, the current search input.  It must return
+either a regexp without groups, or one where groups don't intersect and
+each one wraps a part of the input string."
+  :type '(choice
+          (const :tag "Exact match" regexp-quote)
+          (const :tag "Words separated with spaces" company-search-words-regexp)
+          (const :tag "Words separated with spaces, in any order"
+                 company-search-words-in-any-order-regexp)
+          (const :tag "All characters in given order, with anything in between"
+                 company-search-flex-regexp)))
+
+(defvar-local company-search-string "")
+
+(defvar company-search-lighter '(" "
+                                 (company-search-filtering "Filter" "Search")
+                                 ": \""
+                                 company-search-string
+                                 "\""))
+
+(defvar-local company-search-filtering nil
+  "Non-nil to filter the completion candidates by the search string")
+
+(defvar-local company--search-old-selection 0)
+
+(defvar-local company--search-old-changed nil)
+
+(defun company-search-words-regexp (input)
+  (mapconcat (lambda (word) (format "\\(%s\\)" (regexp-quote word)))
+             (split-string input " +" t) ".*"))
+
+(defun company-search-words-in-any-order-regexp (input)
+  (let* ((words (mapcar (lambda (word) (format "\\(%s\\)" (regexp-quote word)))
+                        (split-string input " +" t)))
+         (permutations (company--permutations words)))
+    (mapconcat (lambda (words)
+                 (mapconcat #'identity words ".*"))
+               permutations
+               "\\|")))
+
+(defun company-search-flex-regexp (input)
+  (if (zerop (length input))
+      ""
+    (concat (regexp-quote (string (aref input 0)))
+            (mapconcat (lambda (c)
+                         (concat "[^" (string c) "]*"
+                                 (regexp-quote (string c))))
+                       (substring input 1) ""))))
+
+(defun company--permutations (lst)
+  (if (not lst)
+      '(nil)
+    (cl-mapcan
+     (lambda (e)
+       (mapcar (lambda (perm) (cons e perm))
+               (company--permutations (cl-remove e lst :count 1))))
+     lst)))
+
+(defun company--search (text lines)
+  (let ((re (funcall company-search-regexp-function text))
+        (i 0))
+    (cl-dolist (line lines)
+      (when (string-match-p re line (length company-prefix))
+        (cl-return i))
+      (cl-incf i))))
+
+(defun company-search-keypad ()
+  (interactive)
+  (let* ((name (symbol-name last-command-event))
+         (last-command-event (aref name (1- (length name)))))
+    (company-search-printing-char)))
+
+(defun company-search-printing-char ()
+  (interactive)
+  (company--search-assert-enabled)
+  (let ((ss (concat company-search-string (string last-command-event))))
+    (when company-search-filtering
+      (company--search-update-predicate ss))
+    (company--search-update-string ss)))
+
+(defun company--search-update-predicate (ss)
+  (let* ((re (funcall company-search-regexp-function ss))
+         (company-candidates-predicate
+          (and (not (string= re ""))
+               company-search-filtering
+               (lambda (candidate) (string-match re candidate))))
+         (cc (company-calculate-candidates company-prefix)))
+    (unless cc (user-error "No match"))
+    (company-update-candidates cc)))
+
+(defun company--search-update-string (new)
+  (let* ((pos (company--search new (nthcdr company-selection company-candidates))))
+    (if (null pos)
+        (ding)
+      (setq company-search-string new)
+      (company-set-selection (+ company-selection pos) t))))
+
+(defun company--search-assert-input ()
+  (company--search-assert-enabled)
+  (when (string= company-search-string "")
+    (user-error "Empty search string")))
+
+(defun company-search-repeat-forward ()
+  "Repeat the incremental search in completion candidates forward."
+  (interactive)
+  (company--search-assert-input)
+  (let ((pos (company--search company-search-string
+                              (cdr (nthcdr company-selection
+                                           company-candidates)))))
+    (if (null pos)
+        (ding)
+      (company-set-selection (+ company-selection pos 1) t))))
+
+(defun company-search-repeat-backward ()
+  "Repeat the incremental search in completion candidates backwards."
+  (interactive)
+  (company--search-assert-input)
+  (let ((pos (company--search company-search-string
+                              (nthcdr (- company-candidates-length
+                                         company-selection)
+                                      (reverse company-candidates)))))
+    (if (null pos)
+        (ding)
+      (company-set-selection (- company-selection pos 1) t))))
+
+(defun company-search-toggle-filtering ()
+  "Toggle `company-search-filtering'."
+  (interactive)
+  (company--search-assert-enabled)
+  (setq company-search-filtering (not company-search-filtering))
+  (let ((ss company-search-string))
+    (company--search-update-predicate ss)
+    (company--search-update-string ss)))
+
+(defun company-search-abort ()
+  "Abort searching the completion candidates."
+  (interactive)
+  (company--search-assert-enabled)
+  (company-search-mode 0)
+  (company-set-selection company--search-old-selection t)
+  (setq company-selection-changed company--search-old-changed))
+
+(defun company-search-other-char ()
+  (interactive)
+  (company--search-assert-enabled)
+  (company-search-mode 0)
+  (company--unread-this-command-keys))
+
+(defun company-search-delete-char ()
+  (interactive)
+  (company--search-assert-enabled)
+  (if (string= company-search-string "")
+      (ding)
+    (let ((ss (substring company-search-string 0 -1)))
+      (when company-search-filtering
+        (company--search-update-predicate ss))
+      (company--search-update-string ss))))
+
+(defvar company-search-map
+  (let ((i 0)
+        (keymap (make-keymap)))
+    (if (fboundp 'max-char)
+        (set-char-table-range (nth 1 keymap) (cons #x100 (max-char))
+                              'company-search-printing-char)
+      (with-no-warnings
+        ;; obsolete in Emacs 23
+        (let ((l (generic-character-list))
+              (table (nth 1 keymap)))
+          (while l
+            (set-char-table-default table (car l) 'company-search-printing-char)
+            (setq l (cdr l))))))
+    (define-key keymap [t] 'company-search-other-char)
+    (while (< i ?\s)
+      (define-key keymap (make-string 1 i) 'company-search-other-char)
+      (cl-incf i))
+    (while (< i 256)
+      (define-key keymap (vector i) 'company-search-printing-char)
+      (cl-incf i))
+    (dotimes (i 10)
+      (define-key keymap (read (format "[kp-%s]" i)) 'company-search-keypad))
+    (let ((meta-map (make-sparse-keymap)))
+      (define-key keymap (char-to-string meta-prefix-char) meta-map)
+      (define-key keymap [escape] meta-map))
+    (define-key keymap (vector meta-prefix-char t) 'company-search-other-char)
+    (define-key keymap (kbd "M-n") 'company-select-next)
+    (define-key keymap (kbd "M-p") 'company-select-previous)
+    (define-key keymap (kbd "<down>") 'company-select-next-or-abort)
+    (define-key keymap (kbd "<up>") 'company-select-previous-or-abort)
+    (define-key keymap "\e\e\e" 'company-search-other-char)
+    (define-key keymap [escape escape escape] 'company-search-other-char)
+    (define-key keymap (kbd "DEL") 'company-search-delete-char)
+    (define-key keymap [backspace] 'company-search-delete-char)
+    (define-key keymap "\C-g" 'company-search-abort)
+    (define-key keymap "\C-s" 'company-search-repeat-forward)
+    (define-key keymap "\C-r" 'company-search-repeat-backward)
+    (define-key keymap "\C-o" 'company-search-toggle-filtering)
+    (dotimes (i 10)
+      (define-key keymap (read-kbd-macro (format "M-%d" i)) 'company-complete-number))
+    keymap)
+  "Keymap used for incrementally searching the completion candidates.")
+
+(define-minor-mode company-search-mode
+  "Search mode for completion candidates.
+Don't start this directly, use `company-search-candidates' or
+`company-filter-candidates'."
+  nil company-search-lighter nil
+  (if company-search-mode
+      (if (company-manual-begin)
+          (progn
+            (setq company--search-old-selection company-selection
+                  company--search-old-changed company-selection-changed)
+            (company-call-frontends 'update)
+            (company-enable-overriding-keymap company-search-map))
+        (setq company-search-mode nil))
+    (kill-local-variable 'company-search-string)
+    (kill-local-variable 'company-search-filtering)
+    (kill-local-variable 'company--search-old-selection)
+    (kill-local-variable 'company--search-old-changed)
+    (when company-backend
+      (company--search-update-predicate "")
+      (company-call-frontends 'update))
+    (company-enable-overriding-keymap company-active-map)))
+
+(defun company--search-assert-enabled ()
+  (company-assert-enabled)
+  (unless company-search-mode
+    (company-uninstall-map)
+    (user-error "Company not in search mode")))
+
+(defun company-search-candidates ()
+  "Start searching the completion candidates incrementally.
+
+\\<company-search-map>Search can be controlled with the commands:
+- `company-search-repeat-forward' (\\[company-search-repeat-forward])
+- `company-search-repeat-backward' (\\[company-search-repeat-backward])
+- `company-search-abort' (\\[company-search-abort])
+- `company-search-delete-char' (\\[company-search-delete-char])
+
+Regular characters are appended to the search string.
+
+Customize `company-search-regexp-function' to change how the input
+is interpreted when searching.
+
+The command `company-search-toggle-filtering' (\\[company-search-toggle-filtering])
+uses the search string to filter the completion candidates."
+  (interactive)
+  (company-search-mode 1))
+
+(defvar company-filter-map
+  (let ((keymap (make-keymap)))
+    (define-key keymap [remap company-search-printing-char]
+      'company-filter-printing-char)
+    (set-keymap-parent keymap company-search-map)
+    keymap)
+  "Keymap used for incrementally searching the completion candidates.")
+
+(defun company-filter-candidates ()
+  "Start filtering the completion candidates incrementally.
+This works the same way as `company-search-candidates' immediately
+followed by `company-search-toggle-filtering'."
+  (interactive)
+  (company-search-mode 1)
+  (setq company-search-filtering t))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun company-select-next (&optional arg)
+  "Select the next candidate in the list.
+
+With ARG, move by that many elements."
+  (interactive "p")
+  (when (company-manual-begin)
+    (company-set-selection (+ (or arg 1) company-selection))))
+
+(defun company-select-previous (&optional arg)
+  "Select the previous candidate in the list.
+
+With ARG, move by that many elements."
+  (interactive "p")
+  (company-select-next (if arg (- arg) -1)))
+
+(defun company-select-next-or-abort (&optional arg)
+  "Select the next candidate if more than one, else abort
+and invoke the normal binding.
+
+With ARG, move by that many elements."
+  (interactive "p")
+  (if (> company-candidates-length 1)
+      (company-select-next arg)
+    (company-abort)
+    (company--unread-this-command-keys)))
+
+(defun company-select-previous-or-abort (&optional arg)
+  "Select the previous candidate if more than one, else abort
+and invoke the normal binding.
+
+With ARG, move by that many elements."
+  (interactive "p")
+  (if (> company-candidates-length 1)
+      (company-select-previous arg)
+    (company-abort)
+    (company--unread-this-command-keys)))
+
+(defun company-next-page ()
+  "Select the candidate one page further."
+  (interactive)
+  (when (company-manual-begin)
+    (if (and company-selection-wrap-around
+             (= company-selection (1- company-candidates-length)))
+        (company-set-selection 0)
+      (let (company-selection-wrap-around)
+        (company-set-selection (+ company-selection
+                                  company-tooltip-limit))))))
+
+(defun company-previous-page ()
+  "Select the candidate one page earlier."
+  (interactive)
+  (when (company-manual-begin)
+    (if (and company-selection-wrap-around
+             (zerop company-selection))
+        (company-set-selection (1- company-candidates-length))
+      (let (company-selection-wrap-around)
+        (company-set-selection (- company-selection
+                                  company-tooltip-limit))))))
+
+(defvar company-pseudo-tooltip-overlay)
+
+(defvar company-tooltip-offset)
+
+(defun company--inside-tooltip-p (event-col-row row height)
+  (let* ((ovl company-pseudo-tooltip-overlay)
+         (column (overlay-get ovl 'company-column))
+         (width (overlay-get ovl 'company-width))
+         (evt-col (car event-col-row))
+         (evt-row (cdr event-col-row)))
+    (and (>= evt-col column)
+         (< evt-col (+ column width))
+         (if (> height 0)
+             (and (> evt-row row)
+                  (<= evt-row (+ row height) ))
+           (and (< evt-row row)
+                (>= evt-row (+ row height)))))))
+
+(defun company--event-col-row (event)
+  (company--posn-col-row (event-start event)))
+
+(defun company-select-mouse (event)
+  "Select the candidate picked by the mouse."
+  (interactive "e")
+  (let ((event-col-row (company--event-col-row event))
+        (ovl-row (company--row))
+        (ovl-height (and company-pseudo-tooltip-overlay
+                         (min (overlay-get company-pseudo-tooltip-overlay
+                                           'company-height)
+                              company-candidates-length))))
+    (if (and ovl-height
+             (company--inside-tooltip-p event-col-row ovl-row ovl-height))
+        (progn
+          (company-set-selection (+ (cdr event-col-row)
+                                    (1- company-tooltip-offset)
+                                    (if (and (eq company-tooltip-offset-display 'lines)
+                                             (not (zerop company-tooltip-offset)))
+                                        -1 0)
+                                    (- ovl-row)
+                                    (if (< ovl-height 0)
+                                        (- 1 ovl-height)
+                                      0)))
+          t)
+      (company-abort)
+      (company--unread-this-command-keys)
+      nil)))
+
+(defun company-complete-mouse (event)
+  "Insert the candidate picked by the mouse."
+  (interactive "e")
+  (when (company-select-mouse event)
+    (company-complete-selection)))
+
+(defun company-complete-selection ()
+  "Insert the selected candidate."
+  (interactive)
+  (when (company-manual-begin)
+    (let ((result (nth company-selection company-candidates)))
+      (company-finish result))))
+
+(defun company-complete-common ()
+  "Insert the common part of all candidates."
+  (interactive)
+  (when (company-manual-begin)
+    (if (and (not (cdr company-candidates))
+             (equal company-common (car company-candidates)))
+        (company-complete-selection)
+      (company--insert-candidate company-common))))
+
+(defun company-complete-common-or-cycle (&optional arg)
+  "Insert the common part of all candidates, or select the next one.
+
+With ARG, move by that many elements."
+  (interactive "p")
+  (when (company-manual-begin)
+    (let ((tick (buffer-chars-modified-tick)))
+      (call-interactively 'company-complete-common)
+      (when (eq tick (buffer-chars-modified-tick))
+        (let ((company-selection-wrap-around t)
+              (current-prefix-arg arg))
+          (call-interactively 'company-select-next))))))
+
+(defun company-indent-or-complete-common ()
+  "Indent the current line or region, or complete the common part."
+  (interactive)
+  (cond
+   ((use-region-p)
+    (indent-region (region-beginning) (region-end)))
+   ((memq indent-line-function
+          '(indent-relative indent-relative-maybe))
+    (company-complete-common))
+   ((let ((old-point (point))
+          (old-tick (buffer-chars-modified-tick))
+          (tab-always-indent t))
+      (call-interactively #'indent-for-tab-command)
+      (when (and (eq old-point (point))
+                 (eq old-tick (buffer-chars-modified-tick)))
+        (company-complete-common))))))
+
+(defun company-select-next-if-tooltip-visible-or-complete-selection ()
+  "Insert selection if appropriate, or select the next candidate.
+Insert selection if only preview is showing or only one candidate,
+otherwise select the next candidate."
+  (interactive)
+  (if (and (company-tooltip-visible-p) (> company-candidates-length 1))
+      (call-interactively 'company-select-next)
+    (call-interactively 'company-complete-selection)))
+
+;;;###autoload
+(defun company-complete ()
+  "Insert the common part of all candidates or the current selection.
+The first time this is called, the common part is inserted, the second
+time, or when the selection has been changed, the selected candidate is
+inserted."
+  (interactive)
+  (when (company-manual-begin)
+    (if (or company-selection-changed
+            (eq last-command 'company-complete-common))
+        (call-interactively 'company-complete-selection)
+      (call-interactively 'company-complete-common)
+      (setq this-command 'company-complete-common))))
+
+(defun company-complete-number (n)
+  "Insert the Nth candidate visible in the tooltip.
+To show the number next to the candidates in some backends, enable
+`company-show-numbers'.  When called interactively, uses the last typed
+character, stripping the modifiers.  That character must be a digit."
+  (interactive
+   (list (let* ((type (event-basic-type last-command-event))
+                (char (if (characterp type)
+                          ;; Number on the main row.
+                          type
+                        ;; Keypad number, if bound directly.
+                        (car (last (string-to-list (symbol-name type))))))
+                (n (- char ?0)))
+           (if (zerop n) 10 n))))
+  (when (company-manual-begin)
+    (and (or (< n 1) (> n (- company-candidates-length
+                             company-tooltip-offset)))
+         (user-error "No candidate number %d" n))
+    (cl-decf n)
+    (company-finish (nth (+ n company-tooltip-offset)
+                         company-candidates))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defconst company-space-strings-limit 100)
+
+(defconst company-space-strings
+  (let (lst)
+    (dotimes (i company-space-strings-limit)
+      (push (make-string (- company-space-strings-limit 1 i) ?\  ) lst))
+    (apply 'vector lst)))
+
+(defun company-space-string (len)
+  (if (< len company-space-strings-limit)
+      (aref company-space-strings len)
+    (make-string len ?\ )))
+
+(defun company-safe-substring (str from &optional to)
+  (let ((bis buffer-invisibility-spec))
+    (if (> from (string-width str))
+        ""
+      (with-temp-buffer
+        (setq buffer-invisibility-spec bis)
+        (insert str)
+        (move-to-column from)
+        (let ((beg (point)))
+          (if to
+              (progn
+                (move-to-column to)
+                (concat (buffer-substring beg (point))
+                        (let ((padding (- to (current-column))))
+                          (when (> padding 0)
+                            (company-space-string padding)))))
+            (buffer-substring beg (point-max))))))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defvar-local company-last-metadata nil)
+
+(defun company-fetch-metadata ()
+  (let ((selected (nth company-selection company-candidates)))
+    (unless (eq selected (car company-last-metadata))
+      (setq company-last-metadata
+            (cons selected (company-call-backend 'meta selected))))
+    (cdr company-last-metadata)))
+
+(defun company-doc-buffer (&optional string)
+  (with-current-buffer (get-buffer-create "*company-documentation*")
+    (erase-buffer)
+    (when string
+      (save-excursion
+        (insert string)))
+    (current-buffer)))
+
+(defvar company--electric-saved-window-configuration nil)
+
+(defvar company--electric-commands
+  '(scroll-other-window scroll-other-window-down mwheel-scroll)
+  "List of Commands that won't break out of electric commands.")
+
+(defun company--electric-restore-window-configuration ()
+  "Restore window configuration (after electric commands)."
+  (when (and company--electric-saved-window-configuration
+             (not (memq this-command company--electric-commands)))
+    (set-window-configuration company--electric-saved-window-configuration)
+    (setq company--electric-saved-window-configuration nil)))
+
+(defmacro company--electric-do (&rest body)
+  (declare (indent 0) (debug t))
+  `(when (company-manual-begin)
+     (cl-assert (null company--electric-saved-window-configuration))
+     (setq company--electric-saved-window-configuration (current-window-configuration))
+     (let ((height (window-height))
+           (row (company--row)))
+       ,@body
+       (and (< (window-height) height)
+            (< (- (window-height) row 2) company-tooltip-limit)
+            (recenter (- (window-height) row 2))))))
+
+(defun company--unread-this-command-keys ()
+  (when (> (length (this-command-keys)) 0)
+    (setq unread-command-events (nconc
+                                 (listify-key-sequence (this-command-keys))
+                                 unread-command-events))
+    (clear-this-command-keys t)))
+
+(defun company-show-doc-buffer ()
+  "Temporarily show the documentation buffer for the selection."
+  (interactive)
+  (let (other-window-scroll-buffer)
+    (company--electric-do
+      (let* ((selected (nth company-selection company-candidates))
+             (doc-buffer (or (company-call-backend 'doc-buffer selected)
+                             (user-error "No documentation available")))
+             start)
+        (when (consp doc-buffer)
+          (setq start (cdr doc-buffer)
+                doc-buffer (car doc-buffer)))
+        (setq other-window-scroll-buffer (get-buffer doc-buffer))
+        (let ((win (display-buffer doc-buffer t)))
+          (set-window-start win (if start start (point-min))))))))
+(put 'company-show-doc-buffer 'company-keep t)
+
+(defun company-show-location ()
+  "Temporarily display a buffer showing the selected candidate in context."
+  (interactive)
+  (let (other-window-scroll-buffer)
+    (company--electric-do
+      (let* ((selected (nth company-selection company-candidates))
+             (location (company-call-backend 'location selected))
+             (pos (or (cdr location) (user-error "No location available")))
+             (buffer (or (and (bufferp (car location)) (car location))
+                         (find-file-noselect (car location) t))))
+        (setq other-window-scroll-buffer (get-buffer buffer))
+        (with-selected-window (display-buffer buffer t)
+          (save-restriction
+            (widen)
+            (if (bufferp (car location))
+                (goto-char pos)
+              (goto-char (point-min))
+              (forward-line (1- pos))))
+          (set-window-start nil (point)))))))
+(put 'company-show-location 'company-keep t)
+
+;;; package functions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defvar-local company-callback nil)
+
+(defun company-remove-callback (&optional ignored)
+  (remove-hook 'company-completion-finished-hook company-callback t)
+  (remove-hook 'company-completion-cancelled-hook 'company-remove-callback t)
+  (remove-hook 'company-completion-finished-hook 'company-remove-callback t))
+
+(defun company-begin-backend (backend &optional callback)
+  "Start a completion at point using BACKEND."
+  (interactive (let ((val (completing-read "Company backend: "
+                                           obarray
+                                           'functionp nil "company-")))
+                 (when val
+                   (list (intern val)))))
+  (when (setq company-callback callback)
+    (add-hook 'company-completion-finished-hook company-callback nil t))
+  (add-hook 'company-completion-cancelled-hook 'company-remove-callback nil t)
+  (add-hook 'company-completion-finished-hook 'company-remove-callback nil t)
+  (setq company-backend backend)
+  ;; Return non-nil if active.
+  (or (company-manual-begin)
+      (user-error "Cannot complete at point")))
+
+(defun company-begin-with (candidates
+                           &optional prefix-length require-match callback)
+  "Start a completion at point.
+CANDIDATES is the list of candidates to use and PREFIX-LENGTH is the length
+of the prefix that already is in the buffer before point.
+It defaults to 0.
+
+CALLBACK is a function called with the selected result if the user
+successfully completes the input.
+
+Example: \(company-begin-with '\(\"foo\" \"foobar\" \"foobarbaz\"\)\)"
+  (let ((begin-marker (copy-marker (point) t)))
+    (company-begin-backend
+     (lambda (command &optional arg &rest ignored)
+       (pcase command
+         (`prefix
+          (when (equal (point) (marker-position begin-marker))
+            (buffer-substring (- (point) (or prefix-length 0)) (point))))
+         (`candidates
+          (all-completions arg candidates))
+         (`require-match
+          require-match)))
+     callback)))
+
+(declare-function find-library-name "find-func")
+(declare-function lm-version "lisp-mnt")
+
+(defun company-version (&optional show-version)
+  "Get the Company version as string.
+
+If SHOW-VERSION is non-nil, show the version in the echo area."
+  (interactive (list t))
+  (with-temp-buffer
+    (require 'find-func)
+    (insert-file-contents (find-library-name "company"))
+    (require 'lisp-mnt)
+    (if show-version
+        (message "Company version: %s" (lm-version))
+      (lm-version))))
+
+(defun company-diag ()
+  "Pop a buffer with information about completions at point."
+  (interactive)
+  (let* ((bb company-backends)
+         (mode (symbol-name major-mode))
+         backend
+         (prefix (cl-loop for b in bb
+                          thereis (let ((company-backend b))
+                                    (setq backend b)
+                                    (company-call-backend 'prefix))))
+         cc annotations)
+    (when (or (stringp prefix) (consp prefix))
+      (let ((company-backend backend))
+        (condition-case nil
+            (setq cc (company-call-backend 'candidates (company--prefix-str prefix))
+                  annotations
+                  (mapcar
+                   (lambda (c) (cons c (company-call-backend 'annotation c)))
+                   cc))
+          (error (setq annotations 'error)))))
+    (pop-to-buffer (get-buffer-create "*company-diag*"))
+    (setq buffer-read-only nil)
+    (erase-buffer)
+    (insert (format "Emacs %s (%s) of %s on %s"
+                    emacs-version system-configuration
+                    (format-time-string "%Y-%m-%d" emacs-build-time)
+                    emacs-build-system))
+    (insert "\nCompany " (company-version) "\n\n")
+    (insert "company-backends: " (pp-to-string bb))
+    (insert "\n")
+    (insert "Used backend: " (pp-to-string backend))
+    (insert "\n")
+    (insert "Major mode: " mode)
+    (insert "\n")
+    (insert "Prefix: " (pp-to-string prefix))
+    (insert "\n")
+    (insert (message  "Completions:"))
+    (unless cc (insert " none"))
+    (if (eq annotations 'error)
+        (insert "(error fetching)")
+      (save-excursion
+        (dolist (c annotations)
+          (insert "\n  " (prin1-to-string (car c)))
+          (when (cdr c)
+            (insert " " (prin1-to-string (cdr c)))))))
+    (special-mode)))
+
+;;; pseudo-tooltip ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defvar-local company-pseudo-tooltip-overlay nil)
+
+(defvar-local company-tooltip-offset 0)
+
+(defun company-tooltip--lines-update-offset (selection num-lines limit)
+  (cl-decf limit 2)
+  (setq company-tooltip-offset
+        (max (min selection company-tooltip-offset)
+             (- selection -1 limit)))
+
+  (when (<= company-tooltip-offset 1)
+    (cl-incf limit)
+    (setq company-tooltip-offset 0))
+
+  (when (>= company-tooltip-offset (- num-lines limit 1))
+    (cl-incf limit)
+    (when (= selection (1- num-lines))
+      (cl-decf company-tooltip-offset)
+      (when (<= company-tooltip-offset 1)
+        (setq company-tooltip-offset 0)
+        (cl-incf limit))))
+
+  limit)
+
+(defun company-tooltip--simple-update-offset (selection _num-lines limit)
+  (setq company-tooltip-offset
+        (if (< selection company-tooltip-offset)
+            selection
+          (max company-tooltip-offset
+               (- selection limit -1)))))
+
+;;; propertize
+
+(defsubst company-round-tab (arg)
+  (* (/ (+ arg tab-width) tab-width) tab-width))
+
+(defun company-plainify (str)
+  (let ((prefix (get-text-property 0 'line-prefix str)))
+    (when prefix ; Keep the original value unmodified, for no special reason.
+      (setq str (concat prefix str))
+      (remove-text-properties 0 (length str) '(line-prefix) str)))
+  (let* ((pieces (split-string str "\t"))
+         (copy pieces))
+    (while (cdr copy)
+      (setcar copy (company-safe-substring
+                    (car copy) 0 (company-round-tab (string-width (car copy)))))
+      (pop copy))
+    (apply 'concat pieces)))
+
+(defun company-fill-propertize (value annotation width selected left right)
+  (let* ((margin (length left))
+         (common (or (company-call-backend 'match value)
+                     (if company-common
+                         (string-width company-common)
+                       0)))
+         (_ (setq value (company--pre-render value)
+                  annotation (and annotation (company--pre-render annotation t))))
+         (ann-ralign company-tooltip-align-annotations)
+         (ann-truncate (< width
+                          (+ (length value) (length annotation)
+                             (if ann-ralign 1 0))))
+         (ann-start (+ margin
+                       (if ann-ralign
+                           (if ann-truncate
+                               (1+ (length value))
+                             (- width (length annotation)))
+                         (length value))))
+         (ann-end (min (+ ann-start (length annotation)) (+ margin width)))
+         (line (concat left
+                       (if (or ann-truncate (not ann-ralign))
+                           (company-safe-substring
+                            (concat value
+                                    (when (and annotation ann-ralign) " ")
+                                    annotation)
+                            0 width)
+                         (concat
+                          (company-safe-substring value 0
+                                                  (- width (length annotation)))
+                          annotation))
+                       right)))
+    (setq width (+ width margin (length right)))
+
+    (font-lock-append-text-property 0 width 'mouse-face
+                                    'company-tooltip-mouse
+                                    line)
+    (when (< ann-start ann-end)
+      (font-lock-append-text-property ann-start ann-end 'face
+                                      (if selected
+                                          'company-tooltip-annotation-selection
+                                        'company-tooltip-annotation)
+                                      line))
+    (cl-loop
+     with width = (- width (length right))
+     for (comp-beg . comp-end) in (if (integerp common) `((0 . ,common)) common)
+     for inline-beg = (+ margin comp-beg)
+     for inline-end = (min (+ margin comp-end) width)
+     when (< inline-beg width)
+     do (font-lock-prepend-text-property inline-beg inline-end 'face
+                                         (if selected
+                                             'company-tooltip-common-selection
+                                           'company-tooltip-common)
+                                         line))
+    (when (let ((re (funcall company-search-regexp-function
+                             company-search-string)))
+            (and (not (string= re ""))
+                 (string-match re value (length company-prefix))))
+      (pcase-dolist (`(,mbeg . ,mend) (company--search-chunks))
+        (let ((beg (+ margin mbeg))
+              (end (+ margin mend))
+              (width (- width (length right))))
+          (when (< beg width)
+            (font-lock-prepend-text-property beg (min end width) 'face
+                                             (if selected
+                                                 'company-tooltip-search-selection
+                                               'company-tooltip-search)
+                                             line)))))
+    (when selected
+      (font-lock-append-text-property 0 width 'face
+                                      'company-tooltip-selection
+                                      line))
+    (font-lock-append-text-property 0 width 'face
+                                    'company-tooltip
+                                    line)
+    line))
+
+(defun company--search-chunks ()
+  (let ((md (match-data t))
+        res)
+    (if (<= (length md) 2)
+        (push (cons (nth 0 md) (nth 1 md)) res)
+      (while (setq md (nthcdr 2 md))
+        (when (car md)
+          (push (cons (car md) (cadr md)) res))))
+    res))
+
+(defun company--pre-render (str &optional annotation-p)
+  (or (company-call-backend 'pre-render str annotation-p)
+      (progn
+        (when (or (text-property-not-all 0 (length str) 'face nil str)
+                  (text-property-not-all 0 (length str) 'mouse-face nil str))
+          (setq str (copy-sequence str))
+          (remove-text-properties 0 (length str)
+                                  '(face nil font-lock-face nil mouse-face nil)
+                                  str))
+        str)))
+
+(defun company--clean-string (str)
+  (replace-regexp-in-string
+   "\\([^[:graph:] ]\\)\\|\\(\ufeff\\)\\|[[:multibyte:]]"
+   (lambda (match)
+     (cond
+      ((match-beginning 1)
+       ;; FIXME: Better char for 'non-printable'?
+       ;; We shouldn't get any of these, but sometimes we might.
+       "\u2017")
+      ((match-beginning 2)
+       ;; Zero-width non-breakable space.
+       "")
+      ((> (string-width match) 1)
+       (concat
+        (make-string (1- (string-width match)) ?\ufeff)
+        match))
+      (t match)))
+   str))
+
+;;; replace
+
+(defun company-buffer-lines (beg end)
+  (goto-char beg)
+  (let (lines lines-moved)
+    (while (and (not (eobp)) ; http://debbugs.gnu.org/19553
+                (> (setq lines-moved (vertical-motion 1)) 0)
+                (<= (point) end))
+      (let ((bound (min end (point))))
+        ;; A visual line can contain several physical lines (e.g. with outline's
+        ;; folding overlay).  Take only the first one.
+        (push (buffer-substring beg
+                                (save-excursion
+                                  (goto-char beg)
+                                  (re-search-forward "$" bound 'move)
+                                  (point)))
+              lines))
+      ;; One physical line can be displayed as several visual ones as well:
+      ;; add empty strings to the list, to even the count.
+      (dotimes (_ (1- lines-moved))
+        (push "" lines))
+      (setq beg (point)))
+    (unless (eq beg end)
+      (push (buffer-substring beg end) lines))
+    (nreverse lines)))
+
+(defun company-modify-line (old new offset)
+  (concat (company-safe-substring old 0 offset)
+          new
+          (company-safe-substring old (+ offset (length new)))))
+
+(defsubst company--window-height ()
+  (if (fboundp 'window-screen-lines)
+      (floor (window-screen-lines))
+    (window-body-height)))
+
+(defun company--window-width ()
+  (let ((ww (window-body-width)))
+    ;; Account for the line continuation column.
+    (when (zerop (cadr (window-fringes)))
+      (cl-decf ww))
+    (when (bound-and-true-p display-line-numbers)
+      (cl-decf ww (+ 2 (line-number-display-width))))
+    (unless (or (display-graphic-p)
+                (version< "24.3.1" emacs-version))
+      ;; Emacs 24.3 and earlier included margins
+      ;; in window-width when in TTY.
+      (cl-decf ww
+               (let ((margins (window-margins)))
+                 (+ (or (car margins) 0)
+                    (or (cdr margins) 0)))))
+    (when (and word-wrap
+               (version< emacs-version "24.4.51.5"))
+      ;; http://debbugs.gnu.org/19300
+      (cl-decf ww))
+    ;; whitespace-mode with newline-mark
+    (when (and buffer-display-table
+               (aref buffer-display-table ?\n))
+      (cl-decf ww (1- (length (aref buffer-display-table ?\n)))))
+    ww))
+
+(defun company--replacement-string (lines old column nl &optional align-top)
+  (cl-decf column company-tooltip-margin)
+
+  (when (and align-top company-tooltip-flip-when-above)
+    (setq lines (reverse lines)))
+
+  (let ((width (length (car lines)))
+        (remaining-cols (- (+ (company--window-width) (window-hscroll))
+                           column)))
+    (when (> width remaining-cols)
+      (cl-decf column (- width remaining-cols))))
+
+  (let ((offset (and (< column 0) (- column)))
+        new)
+    (when offset
+      (setq column 0))
+    (when align-top
+      ;; untouched lines first
+      (dotimes (_ (- (length old) (length lines)))
+        (push (pop old) new)))
+    ;; length into old lines.
+    (while old
+      (push (company-modify-line (pop old)
+                                 (company--offset-line (pop lines) offset)
+                                 column)
+            new))
+    ;; Append whole new lines.
+    (while lines
+      (push (concat (company-space-string column)
+                    (company--offset-line (pop lines) offset))
+            new))
+
+    (let ((str (concat (when nl " \n")
+                       (mapconcat 'identity (nreverse new) "\n")
+                       "\n")))
+      (font-lock-append-text-property 0 (length str) 'face 'default str)
+      (when nl (put-text-property 0 1 'cursor t str))
+      str)))
+
+(defun company--offset-line (line offset)
+  (if (and offset line)
+      (substring line offset)
+    line))
+
+(defun company--create-lines (selection limit)
+  (let ((len company-candidates-length)
+        (window-width (company--window-width))
+        lines
+        width
+        lines-copy
+        items
+        previous
+        remainder
+        scrollbar-bounds)
+
+    ;; Maybe clear old offset.
+    (when (< len (+ company-tooltip-offset limit))
+      (setq company-tooltip-offset 0))
+
+    ;; Scroll to offset.
+    (if (eq company-tooltip-offset-display 'lines)
+        (setq limit (company-tooltip--lines-update-offset selection len limit))
+      (company-tooltip--simple-update-offset selection len limit))
+
+    (cond
+     ((eq company-tooltip-offset-display 'scrollbar)
+      (setq scrollbar-bounds (company--scrollbar-bounds company-tooltip-offset
+                                                        limit len)))
+     ((eq company-tooltip-offset-display 'lines)
+      (when (> company-tooltip-offset 0)
+        (setq previous (format "...(%d)" company-tooltip-offset)))
+      (setq remainder (- len limit company-tooltip-offset)
+            remainder (when (> remainder 0)
+                        (setq remainder (format "...(%d)" remainder))))))
+
+    (cl-decf selection company-tooltip-offset)
+    (setq width (max (length previous) (length remainder))
+          lines (nthcdr company-tooltip-offset company-candidates)
+          len (min limit len)
+          lines-copy lines)
+
+    (cl-decf window-width (* 2 company-tooltip-margin))
+    (when scrollbar-bounds (cl-decf window-width))
+
+    (dotimes (_ len)
+      (let* ((value (pop lines-copy))
+             (annotation (company-call-backend 'annotation value)))
+        (setq value (company--clean-string (company-reformat value)))
+        (when annotation
+          (setq annotation (company--clean-string annotation))
+          (when company-tooltip-align-annotations
+            ;; `lisp-completion-at-point' adds a space.
+            (setq annotation (comment-string-strip annotation t nil))))
+        (push (cons value annotation) items)
+        (setq width (max (+ (length value)
+                            (if (and annotation company-tooltip-align-annotations)
+                                (1+ (length annotation))
+                              (length annotation)))
+                         width))))
+
+    (setq width (min window-width
+                     company-tooltip-maximum-width
+                     (max company-tooltip-minimum-width
+                          (if company-show-numbers
+                              (+ 2 width)
+                            width))))
+
+    (let ((items (nreverse items))
+          (numbered (if company-show-numbers 0 99999))
+          new)
+      (when previous
+        (push (company--scrollpos-line previous width) new))
+
+      (dotimes (i len)
+        (let* ((item (pop items))
+               (str (car item))
+               (annotation (cdr item))
+               (right (company-space-string company-tooltip-margin))
+               (width width))
+          (when (< numbered 10)
+            (cl-decf width 2)
+            (cl-incf numbered)
+            (setq right (concat (format " %d" (mod numbered 10)) right)))
+          (push (concat
+                 (company-fill-propertize str annotation
+                                          width (equal i selection)
+                                          (company-space-string
+                                           company-tooltip-margin)
+                                          right)
+                 (when scrollbar-bounds
+                   (company--scrollbar i scrollbar-bounds)))
+                new)))
+
+      (when remainder
+        (push (company--scrollpos-line remainder width) new))
+
+      (nreverse new))))
+
+(defun company--scrollbar-bounds (offset limit length)
+  (when (> length limit)
+    (let* ((size (ceiling (* limit (float limit)) length))
+           (lower (floor (* limit (float offset)) length))
+           (upper (+ lower size -1)))
+      (cons lower upper))))
+
+(defun company--scrollbar (i bounds)
+  (propertize " " 'face
+              (if (and (>= i (car bounds)) (<= i (cdr bounds)))
+                  'company-scrollbar-fg
+                'company-scrollbar-bg)))
+
+(defun company--scrollpos-line (text width)
+  (propertize (concat (company-space-string company-tooltip-margin)
+                      (company-safe-substring text 0 width)
+                      (company-space-string company-tooltip-margin))
+              'face 'company-tooltip))
+
+;; show
+
+(defun company--pseudo-tooltip-height ()
+  "Calculate the appropriate tooltip height.
+Returns a negative number if the tooltip should be displayed above point."
+  (let* ((lines (company--row))
+         (below (- (company--window-height) 1 lines)))
+    (if (and (< below (min company-tooltip-minimum company-candidates-length))
+             (> lines below))
+        (- (max 3 (min company-tooltip-limit lines)))
+      (max 3 (min company-tooltip-limit below)))))
+
+(defun company-pseudo-tooltip-show (row column selection)
+  (company-pseudo-tooltip-hide)
+  (save-excursion
+
+    (let* ((height (company--pseudo-tooltip-height))
+           above)
+
+      (when (< height 0)
+        (setq row (+ row height -1)
+              above t))
+
+      (let* ((nl (< (move-to-window-line row) row))
+             (beg (point))
+             (end (save-excursion
+                    (move-to-window-line (+ row (abs height)))
+                    (point)))
+             (ov (make-overlay beg end nil t))
+             (args (list (mapcar 'company-plainify
+                                 (company-buffer-lines beg end))
+                         column nl above)))
+
+        (setq company-pseudo-tooltip-overlay ov)
+        (overlay-put ov 'company-replacement-args args)
+
+        (let ((lines (company--create-lines selection (abs height))))
+          (overlay-put ov 'company-display
+                       (apply 'company--replacement-string lines args))
+          (overlay-put ov 'company-width (string-width (car lines))))
+
+        (overlay-put ov 'company-column column)
+        (overlay-put ov 'company-height height)))))
+
+(defun company-pseudo-tooltip-show-at-point (pos column-offset)
+  (let* ((col-row (company--col-row pos))
+         (col (- (car col-row) column-offset)))
+    (when (< col 0) (setq col 0))
+    (company-pseudo-tooltip-show (1+ (cdr col-row)) col company-selection)))
+
+(defun company-pseudo-tooltip-edit (selection)
+  (let* ((height (overlay-get company-pseudo-tooltip-overlay 'company-height))
+         (lines  (company--create-lines selection (abs height))))
+    (overlay-put company-pseudo-tooltip-overlay 'company-width
+                 (string-width (car lines)))
+    (overlay-put company-pseudo-tooltip-overlay 'company-display
+                 (apply 'company--replacement-string
+                        lines
+                        (overlay-get company-pseudo-tooltip-overlay
+                                     'company-replacement-args)))))
+
+(defun company-pseudo-tooltip-hide ()
+  (when company-pseudo-tooltip-overlay
+    (delete-overlay company-pseudo-tooltip-overlay)
+    (setq company-pseudo-tooltip-overlay nil)))
+
+(defun company-pseudo-tooltip-hide-temporarily ()
+  (when (overlayp company-pseudo-tooltip-overlay)
+    (overlay-put company-pseudo-tooltip-overlay 'invisible nil)
+    (overlay-put company-pseudo-tooltip-overlay 'line-prefix nil)
+    (overlay-put company-pseudo-tooltip-overlay 'after-string nil)
+    (overlay-put company-pseudo-tooltip-overlay 'display nil)))
+
+(defun company-pseudo-tooltip-unhide ()
+  (when company-pseudo-tooltip-overlay
+    (let* ((ov company-pseudo-tooltip-overlay)
+           (disp (overlay-get ov 'company-display)))
+      ;; Beat outline's folding overlays, at least.
+      (overlay-put ov 'priority 1)
+      ;; No (extra) prefix for the first line.
+      (overlay-put ov 'line-prefix "")
+      ;; `display' is better
+      ;; (http://debbugs.gnu.org/18285, http://debbugs.gnu.org/20847),
+      ;; but it doesn't work on 0-length overlays.
+      (if (< (overlay-start ov) (overlay-end ov))
+          (overlay-put ov 'display disp)
+        (overlay-put ov 'after-string disp)
+        (overlay-put ov 'invisible t))
+      (overlay-put ov 'window (selected-window)))))
+
+(defun company-pseudo-tooltip-guard ()
+  (list
+   (save-excursion (beginning-of-visual-line))
+   (window-width)
+   (let ((ov company-pseudo-tooltip-overlay)
+         (overhang (save-excursion (end-of-visual-line)
+                                   (- (line-end-position) (point)))))
+     (when (>= (overlay-get ov 'company-height) 0)
+       (cons
+        (buffer-substring-no-properties (point) (overlay-start ov))
+        (when (>= overhang 0) overhang))))))
+
+(defun company-pseudo-tooltip-frontend (command)
+  "`company-mode' frontend similar to a tooltip but based on overlays."
+  (cl-case command
+    (pre-command (company-pseudo-tooltip-hide-temporarily))
+    (post-command
+     (unless (when (overlayp company-pseudo-tooltip-overlay)
+              (let* ((ov company-pseudo-tooltip-overlay)
+                     (old-height (overlay-get ov 'company-height))
+                     (new-height (company--pseudo-tooltip-height)))
+                (and
+                 (>= (* old-height new-height) 0)
+                 (>= (abs old-height) (abs new-height))
+                 (equal (company-pseudo-tooltip-guard)
+                        (overlay-get ov 'company-guard)))))
+       ;; Redraw needed.
+       (company-pseudo-tooltip-show-at-point (point) (length company-prefix))
+       (overlay-put company-pseudo-tooltip-overlay
+                    'company-guard (company-pseudo-tooltip-guard)))
+     (company-pseudo-tooltip-unhide))
+    (hide (company-pseudo-tooltip-hide)
+          (setq company-tooltip-offset 0))
+    (update (when (overlayp company-pseudo-tooltip-overlay)
+              (company-pseudo-tooltip-edit company-selection)))))
+
+(defun company-pseudo-tooltip-unless-just-one-frontend (command)
+  "`company-pseudo-tooltip-frontend', but not shown for single candidates."
+  (unless (and (eq command 'post-command)
+               (company--show-inline-p))
+    (company-pseudo-tooltip-frontend command)))
+
+(defun company-pseudo-tooltip-unless-just-one-frontend-with-delay (command)
+  "`compandy-pseudo-tooltip-frontend', but shown after a delay.
+Delay is determined by `company-tooltip-idle-delay'."
+  (defvar company-preview-overlay)
+  (when (and (memq command '(pre-command hide))
+             company-tooltip-timer)
+    (cancel-timer company-tooltip-timer)
+    (setq company-tooltip-timer nil))
+  (cl-case command
+    (post-command
+     (if (or company-tooltip-timer
+             (overlayp company-pseudo-tooltip-overlay))
+         (if (not (overlayp company-preview-overlay))
+             (company-pseudo-tooltip-unless-just-one-frontend command)
+           (let (company-tooltip-timer)
+             (company-call-frontends 'pre-command))
+           (company-call-frontends 'post-command))
+       (setq company-tooltip-timer
+             (run-with-timer company-tooltip-idle-delay nil
+                             'company-pseudo-tooltip-unless-just-one-frontend-with-delay
+                             'post-command))))
+    (t
+     (company-pseudo-tooltip-unless-just-one-frontend command))))
+
+;;; overlay ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defvar-local company-preview-overlay nil)
+
+(defun company-preview-show-at-point (pos completion)
+  (company-preview-hide)
+
+  (setq completion (copy-sequence (company--pre-render completion)))
+  (font-lock-append-text-property 0 (length completion)
+                                  'face 'company-preview
+                                  completion)
+    (font-lock-prepend-text-property 0 (length company-common)
+                                     'face 'company-preview-common
+                                     completion)
+
+    ;; Add search string
+    (and (string-match (funcall company-search-regexp-function
+                                company-search-string)
+                       completion)
+         (pcase-dolist (`(,mbeg . ,mend) (company--search-chunks))
+           (font-lock-prepend-text-property mbeg mend
+                                            'face 'company-preview-search
+                                            completion)))
+
+    (setq completion (company-strip-prefix completion))
+
+    (and (equal pos (point))
+         (not (equal completion ""))
+         (add-text-properties 0 1 '(cursor 1) completion))
+
+    (let* ((beg pos)
+           (pto company-pseudo-tooltip-overlay)
+           (ptf-workaround (and
+                            pto
+                            (char-before pos)
+                            (eq pos (overlay-start pto)))))
+      ;; Try to accomodate for the pseudo-tooltip overlay,
+      ;; which may start at the same position if it's at eol.
+      (when ptf-workaround
+        (cl-decf beg)
+        (setq completion (concat (buffer-substring beg pos) completion)))
+
+      (setq company-preview-overlay (make-overlay beg pos))
+
+      (let ((ov company-preview-overlay))
+        (overlay-put ov (if ptf-workaround 'display 'after-string)
+                     completion)
+        (overlay-put ov 'window (selected-window)))))
+
+(defun company-preview-hide ()
+  (when company-preview-overlay
+    (delete-overlay company-preview-overlay)
+    (setq company-preview-overlay nil)))
+
+(defun company-preview-frontend (command)
+  "`company-mode' frontend showing the selection as if it had been inserted."
+  (pcase command
+    (`pre-command (company-preview-hide))
+    (`post-command (company-preview-show-at-point (point)
+                                                  (nth company-selection company-candidates)))
+    (`hide (company-preview-hide))))
+
+(defun company-preview-if-just-one-frontend (command)
+  "`company-preview-frontend', but only shown for single candidates."
+  (when (or (not (eq command 'post-command))
+            (company--show-inline-p))
+    (company-preview-frontend command)))
+
+(defun company--show-inline-p ()
+  (and (not (cdr company-candidates))
+       company-common
+       (or (eq (company-call-backend 'ignore-case) 'keep-prefix)
+           (string-prefix-p company-prefix company-common))))
+
+(defun company-tooltip-visible-p ()
+  "Returns whether the tooltip is visible."
+  (when (overlayp company-pseudo-tooltip-overlay)
+    (not (overlay-get company-pseudo-tooltip-overlay 'invisible))))
+
+(defun company-preview-common--show-p ()
+  "Returns whether the preview of common can be showed or not"
+  (and company-common
+       (or (eq (company-call-backend 'ignore-case) 'keep-prefix)
+           (string-prefix-p company-prefix company-common))))
+
+(defun company-preview-common-frontend (command)
+  "`company-mode' frontend preview the common part of candidates."
+  (when (or (not (eq command 'post-command))
+            (company-preview-common--show-p))
+    (pcase command
+      (`pre-command (company-preview-hide))
+      (`post-command (company-preview-show-at-point (point) company-common))
+      (`hide (company-preview-hide)))))
+
+;;; echo ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defvar-local company-echo-last-msg nil)
+
+(defvar company-echo-timer nil)
+
+(defvar company-echo-delay .01)
+
+(defcustom company-echo-truncate-lines t
+  "Whether frontend messages written to the echo area should be truncated."
+  :type 'boolean
+  :package-version '(company . "0.9.3"))
+
+(defun company-echo-show (&optional getter)
+  (when getter
+    (setq company-echo-last-msg (funcall getter)))
+  (let ((message-log-max nil)
+        (message-truncate-lines company-echo-truncate-lines))
+    (if company-echo-last-msg
+        (message "%s" company-echo-last-msg)
+      (message ""))))
+
+(defun company-echo-show-soon (&optional getter)
+  (company-echo-cancel)
+  (setq company-echo-timer (run-with-timer 0 nil 'company-echo-show getter)))
+
+(defun company-echo-cancel (&optional unset)
+  (when company-echo-timer
+    (cancel-timer company-echo-timer))
+  (when unset
+    (setq company-echo-timer nil)))
+
+(defun company-echo-show-when-idle (&optional getter)
+  (company-echo-cancel)
+  (setq company-echo-timer
+        (run-with-idle-timer company-echo-delay nil 'company-echo-show getter)))
+
+(defun company-echo-format ()
+
+  (let ((limit (window-body-width (minibuffer-window)))
+        (len -1)
+        ;; Roll to selection.
+        (candidates (nthcdr company-selection company-candidates))
+        (i (if company-show-numbers company-selection 99999))
+        comp msg)
+
+    (while candidates
+      (setq comp (company-reformat (pop candidates))
+            len (+ len 1 (length comp)))
+      (if (< i 10)
+          ;; Add number.
+          (progn
+            (setq comp (propertize (format "%d: %s" i comp)
+                                   'face 'company-echo))
+            (cl-incf len 3)
+            (cl-incf i)
+            (add-text-properties 3 (+ 3 (length company-common))
+                                 '(face company-echo-common) comp))
+        (setq comp (propertize comp 'face 'company-echo))
+        (add-text-properties 0 (length company-common)
+                             '(face company-echo-common) comp))
+      (if (>= len limit)
+          (setq candidates nil)
+        (push comp msg)))
+
+    (mapconcat 'identity (nreverse msg) " ")))
+
+(defun company-echo-strip-common-format ()
+
+  (let ((limit (window-body-width (minibuffer-window)))
+        (len (+ (length company-prefix) 2))
+        ;; Roll to selection.
+        (candidates (nthcdr company-selection company-candidates))
+        (i (if company-show-numbers company-selection 99999))
+        msg comp)
+
+    (while candidates
+      (setq comp (company-strip-prefix (pop candidates))
+            len (+ len 2 (length comp)))
+      (when (< i 10)
+        ;; Add number.
+        (setq comp (format "%s (%d)" comp i))
+        (cl-incf len 4)
+        (cl-incf i))
+      (if (>= len limit)
+          (setq candidates nil)
+        (push (propertize comp 'face 'company-echo) msg)))
+
+    (concat (propertize company-prefix 'face 'company-echo-common) "{"
+            (mapconcat 'identity (nreverse msg) ", ")
+            "}")))
+
+(defun company-echo-hide ()
+  (unless (equal company-echo-last-msg "")
+    (setq company-echo-last-msg "")
+    (company-echo-show)))
+
+(defun company-echo-frontend (command)
+  "`company-mode' frontend showing the candidates in the echo area."
+  (pcase command
+    (`post-command (company-echo-show-soon 'company-echo-format))
+    (`hide (company-echo-hide))))
+
+(defun company-echo-strip-common-frontend (command)
+  "`company-mode' frontend showing the candidates in the echo area."
+  (pcase command
+    (`post-command (company-echo-show-soon 'company-echo-strip-common-format))
+    (`hide (company-echo-hide))))
+
+(defun company-echo-metadata-frontend (command)
+  "`company-mode' frontend showing the documentation in the echo area."
+  (pcase command
+    (`post-command (company-echo-show-when-idle 'company-fetch-metadata))
+    (`hide (company-echo-hide))))
+
+(provide 'company)
+;;; company.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company.elc b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company.elc
new file mode 100644
index 0000000000..35197affbf
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/company-20180704.701/company.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/company-flow-20180225.1359/company-flow-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/company-flow-20180225.1359/company-flow-autoloads.el
new file mode 100644
index 0000000000..e8090c8717
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/company-flow-20180225.1359/company-flow-autoloads.el
@@ -0,0 +1,22 @@
+;;; company-flow-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "company-flow" "company-flow.el" (23377 61675
+;;;;;;  958217 269000))
+;;; Generated autoloads from company-flow.el
+
+(autoload 'company-flow "company-flow" "\
+
+
+\(fn COMMAND &optional ARG &rest ARGS)" t nil)
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; company-flow-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/company-flow-20180225.1359/company-flow-pkg.el b/configs/shared/emacs/.emacs.d/elpa/company-flow-20180225.1359/company-flow-pkg.el
new file mode 100644
index 0000000000..c9aff47c4c
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/company-flow-20180225.1359/company-flow-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "company-flow" "20180225.1359" "Flow backend for company-mode" '((company "0.8.0") (dash "2.13.0")))
diff --git a/configs/shared/emacs/.emacs.d/elpa/company-flow-20180225.1359/company-flow.el b/configs/shared/emacs/.emacs.d/elpa/company-flow-20180225.1359/company-flow.el
new file mode 100644
index 0000000000..28332c394a
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/company-flow-20180225.1359/company-flow.el
@@ -0,0 +1,209 @@
+;;; company-flow.el --- Flow backend for company-mode  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2016 by Aaron Jensen
+
+;; Author: Aaron Jensen <aaronjensen@gmail.com>
+;; URL: https://github.com/aaronjensen/company-flow
+;; Package-Version: 20180225.1359
+;; Version: 0.1.0
+;; Package-Requires: ((company "0.8.0") (dash "2.13.0"))
+
+;;; Commentary:
+
+;; This package adds support for flow to company. It requires
+;; flow to be in your path.
+
+;; To use it, add to your company-backends:
+
+;;   (eval-after-load 'company
+;;     '(add-to-list 'company-backends 'company-flow))
+
+;;; License:
+
+;; This file is not part of GNU Emacs.
+;; However, it is distributed under the same license.
+
+;; 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, 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; see the file COPYING.  If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Code:
+(require 'company)
+(require 'dash)
+
+(defgroup company-flow ()
+  "Flow company backend."
+  :group 'company
+  :prefix "company-flow-")
+
+(defcustom company-flow-executable "flow"
+  "Flow executable to run."
+  :group 'company-flow
+  :type 'string)
+(make-variable-buffer-local 'company-flow-executable)
+
+(defcustom company-flow-modes '(
+                                js-mode
+                                js-jsx-mode
+                                js2-mode
+                                js2-jsx-mode
+                                rjsx-mode
+                                web-mode
+                                )
+  "List of major modes where company-flow will be providing completions."
+  :type '(choice (const :tag "All" nil)
+                 (repeat (symbol :tag "Major mode")))
+  :group 'company-flow)
+
+(defun company-flow--handle-signal (process _event)
+  (when (memq (process-status process) '(signal exit))
+    (let ((callback (process-get process 'company-flow-callback))
+          (prefix (process-get process 'company-flow-prefix)))
+      (if (and (eq (process-status process) 'exit)
+               (eq (process-exit-status process) 0))
+          (funcall callback (->> process
+                                 company-flow--get-output
+                                 company-flow--parse-output
+                                 ;; Remove nils
+                                 (--filter it)))
+        (funcall callback nil)))))
+
+(defun company-flow--make-candidate (line)
+  "Creates a candidate with a meta property from LINE.
+
+LINE is expected to look like:
+registrationSuccess () => {type: 'REGISTRATION_SUCCESS'}"
+  (let ((first-space (string-match " " line)))
+    (when first-space
+      (let ((text (substring line 0 first-space))
+            (meta (substring line (+ 1 first-space))))
+        (propertize text 'meta meta)))))
+
+(defun company-flow--parse-output (output)
+  (when (not (equal output "Error: not enough type information to autocomplete\n"))
+    (mapcar 'company-flow--make-candidate
+            (split-string output "\n"))))
+
+(defun company-flow--get-output (process)
+  "Get the complete output of PROCESS."
+  (with-demoted-errors "Error while retrieving process output: %S"
+    (let ((pending-output (process-get process 'company-flow-pending-output)))
+      (apply #'concat (nreverse pending-output)))))
+
+(defun company-flow--receive-checker-output (process output)
+  "Receive a syntax checking PROCESS OUTPUT."
+  (push output (process-get process 'company-flow-pending-output)))
+
+(defun company-flow--process-send-buffer (process)
+  "Send all contents of current buffer to PROCESS.
+
+Sends all contents of the current buffer to the standard input of
+PROCESS, and terminates standard input with EOF."
+  (save-restriction
+    (widen)
+    (process-send-region process (point-min) (point-max)))
+  ;; flow requires EOF be on its own line
+  (process-send-string process "\n")
+  (process-send-eof process))
+
+(defun company-flow--candidates-query (prefix callback)
+  (let* ((line (line-number-at-pos (point)))
+         (col (+ 1 (current-column)))
+         (command (list (executable-find company-flow-executable)
+                        "autocomplete"
+                        "--quiet"
+                        buffer-file-name
+                        (number-to-string line)
+                        (number-to-string col)))
+         (process-connection-type nil)
+         (process (apply 'start-process "company-flow" nil command)))
+    (set-process-sentinel process #'company-flow--handle-signal)
+    (set-process-filter process #'company-flow--receive-checker-output)
+    (process-put process 'company-flow-callback callback)
+    (process-put process 'company-flow-prefix prefix)
+    (company-flow--process-send-buffer process)))
+
+(defun company-flow--prefix ()
+  "Grab prefix for flow."
+  (and (or (null company-flow-modes)
+           (-contains? company-flow-modes major-mode))
+       company-flow-executable
+       (executable-find company-flow-executable)
+       buffer-file-name
+       (file-exists-p buffer-file-name)
+       (not (company-in-string-or-comment))
+       (locate-dominating-file buffer-file-name ".flowconfig")
+       (or (company-grab-symbol-cons "\\." 1)
+           'stop)))
+
+(defun company-flow--annotation (candidate)
+  (format " %s" (get-text-property 0 'meta candidate)))
+
+(defun company-flow--meta (candidate)
+  (format "%s: %s" candidate (get-text-property 0 'meta candidate)))
+
+(defvar-local company-flow--debounce-state nil)
+
+(defun company-flow--debounce-callback (prefix callback)
+  (lambda (candidates)
+    (let ((current-prefix (car company-flow--debounce-state))
+          (current-callback (cdr company-flow--debounce-state)))
+      (when (and current-prefix
+                 (company-flow--string-prefix-p prefix current-prefix))
+        (setq company-flow--debounce-state nil)
+        (funcall current-callback (all-completions current-prefix candidates))))))
+
+(defun company-flow--prefix-to-string (prefix)
+  "Return a string or nil from a prefix.
+  `company-grab-symbol-cons' can return (\"prefix\" . t) or just
+  \"prefix\", but we only care about the string."
+  (if (consp prefix)
+      (car prefix)
+    prefix))
+
+(defun company-flow--string-prefix-p (a b)
+  (string-prefix-p (company-flow--prefix-to-string a) (company-flow--prefix-to-string b)))
+
+(defun company-flow--debounce-async (prefix candidate-fn)
+  "Return a function that will properly debounce candidate queries by comparing the
+in-flight query's prefix to PREFIX. CANDIDATE-FN should take two arguments, PREFIX
+and the typical async callback.
+
+Note that the candidate list provided to the callback by CANDIDATE-FN will be
+filtered via `all-completions' with the most current prefix, so it is not necessary
+to do this filtering in CANDIDATE-FN.
+
+Use like:
+
+  (cons :async (company-flow--debounce-async arg 'your-query-fn))"
+  (lambda (callback)
+    (let ((current-prefix (car company-flow--debounce-state)))
+      (unless (and current-prefix
+                   (company-flow--string-prefix-p prefix current-prefix))
+        (funcall candidate-fn prefix (company-flow--debounce-callback prefix callback)))
+      (setq company-flow--debounce-state (cons (company-flow--prefix-to-string prefix) callback)))))
+
+;;;###autoload
+(defun company-flow (command &optional arg &rest _args)
+  (interactive (list 'interactive))
+  (pcase command
+    (`interactive (company-begin-backend 'company-flow))
+    (`prefix (company-flow--prefix))
+    (`annotation (company-flow--annotation arg))
+    (`meta (company-flow--meta arg))
+    (`sorted t)
+    (`candidates (cons :async (company-flow--debounce-async arg 'company-flow--candidates-query)))))
+
+(provide 'company-flow)
+;;; company-flow.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/company-flow-20180225.1359/company-flow.elc b/configs/shared/emacs/.emacs.d/elpa/company-flow-20180225.1359/company-flow.elc
new file mode 100644
index 0000000000..a6890a6f45
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/company-flow-20180225.1359/company-flow.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/company-lsp-20180828.438/company-lsp-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/company-lsp-20180828.438/company-lsp-autoloads.el
new file mode 100644
index 0000000000..f0118fde52
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/company-lsp-20180828.438/company-lsp-autoloads.el
@@ -0,0 +1,24 @@
+;;; company-lsp-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "company-lsp" "company-lsp.el" (23430 63890
+;;;;;;  645936 507000))
+;;; Generated autoloads from company-lsp.el
+
+(autoload 'company-lsp "company-lsp" "\
+Define a company backend for lsp-mode.
+
+See the documentation of `company-backends' for COMMAND and ARG.
+
+\(fn COMMAND &optional ARG &rest _)" t nil)
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; company-lsp-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/company-lsp-20180828.438/company-lsp-pkg.el b/configs/shared/emacs/.emacs.d/elpa/company-lsp-20180828.438/company-lsp-pkg.el
new file mode 100644
index 0000000000..7dec1faf2d
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/company-lsp-20180828.438/company-lsp-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "company-lsp" "20180828.438" "Company completion backend for lsp-mode." '((emacs "25.1") (lsp-mode "3.4") (company "0.9.0") (s "1.2.0") (dash "2.11.0")) :commit "82c3f1a0446060da57dffa638be873382e8efc74" :url "https://github.com/tigersoldier/company-lsp")
diff --git a/configs/shared/emacs/.emacs.d/elpa/company-lsp-20180828.438/company-lsp.el b/configs/shared/emacs/.emacs.d/elpa/company-lsp-20180828.438/company-lsp.el
new file mode 100644
index 0000000000..884aff9e20
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/company-lsp-20180828.438/company-lsp.el
@@ -0,0 +1,435 @@
+;;; company-lsp.el --- Company completion backend for lsp-mode.  -*- lexical-binding: t -*-
+
+;; Version: 2.0.2
+;; Package-Version: 20180828.438
+;; Package-Requires: ((emacs "25.1") (lsp-mode "3.4") (company "0.9.0") (s "1.2.0") (dash "2.11.0"))
+;; URL: https://github.com/tigersoldier/company-lsp
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; `company-lsp' is a `company' completion backend for `lsp-mode'.
+;; To use it, add `company-lsp' to `company-backends':
+
+;;     (require 'company-lsp)
+;;     (push 'company-lsp company-backends)
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'company)
+(require 'lsp-mode)
+(require 's)
+(require 'dash)
+
+(defgroup company-lsp nil
+  "Company completion backend for lsp-mode."
+  :prefix "company-lsp-"
+  :group 'tools)
+
+(defcustom company-lsp-cache-candidates 'auto
+  "Whether or not to cache completion candidates.
+
+When set to 'auto, company-lsp caches the completion. It sends
+incremental completion requests to the server if and only if the
+cached results are incomplete. The candidate list may not be
+sorted or filtered as the server would for cached completion
+results.
+
+When set to t, company-mode caches the completion. It won't send
+incremental completion requests to the server.
+
+When set to nil, results are not cached at all. The candidates
+are always sorted and filtered by the server. Use this option if
+the server handles caching for incremental completion or
+sorting/matching provided by the server is critical."
+  :type '(choice (const :tag "Respect server response" auto)
+                 (const :tag "Always cache" t)
+                 (const :tag "Never cache" nil))
+  :group 'company-lsp)
+
+(defcustom company-lsp-async t
+  "Whether or not to use async operations to fetch data."
+  :type 'boolean
+  :group 'company-lsp)
+
+(defcustom company-lsp-enable-snippet t
+  "Whether or not to support expanding completion snippet.
+
+If set to non-nil, company-lsp will register client capabilities
+for snippet support. When the server returns completion item with
+snippet, company-lsp will replace the label of the completion
+item with the snippet and use yas-snippet to expand it."
+  :type 'boolean
+  :group 'company-lsp)
+
+(defcustom company-lsp-enable-recompletion nil
+  "Whether or not to re-trigger completion for trigger characters.
+
+If set to non-nil, when company-lsp finishes completion, it checks if
+the current point is before any completion trigger characters. If yes,
+it re-triggers another completion request.
+
+This is useful in cases such as 'std' is completed as 'std::' in C++."
+  :type 'boolean
+  :group 'company-lsp)
+
+(declare-function yas-expand-snippet "ext:yasnippet.el")
+
+(defvar company-lsp--snippet-functions '(("rust" . company-lsp--rust-completion-snippet))
+  "Alist of functions to insert our snippets for each language.")
+
+(defvar-local company-lsp--completion-cache nil
+  "Cached completion. It's an alist of (prefix . completion).
+
+PREFIX is the prefix string.
+COMPLETION is a cache-item created by `company-lsp--cache-item-new'.")
+
+(defun company-lsp--trigger-characters ()
+  "Return a list of completion trigger characters specified by server."
+  (let ((provider (lsp--capability "completionProvider")))
+    (and provider (gethash "triggerCharacters" provider))))
+
+(defun company-lsp--completion-prefix ()
+  "Return the completion prefix.
+
+Return value is compatible with the `prefix' command of a company backend.
+
+Return nil if no completion should be triggered. Return a string
+as the prefix to be completed, or a cons cell of (prefix . t) to bypass
+`company-minimum-prefix-length' for trigger characters."
+  (let ((trigger-chars (company-lsp--trigger-characters)))
+    (if trigger-chars
+        (let* ((max-trigger-len (apply 'max (mapcar (lambda (trigger-char)
+                                                      (length trigger-char))
+                                                    trigger-chars)))
+               (trigger-regex (s-join "\\|" (mapcar #'regexp-quote trigger-chars)))
+               (symbol-cons (company-grab-symbol-cons trigger-regex max-trigger-len)))
+          ;; Some major modes define trigger characters as part of the symbol. For
+          ;; example "@" is considered a vaild part of symbol in java-mode.
+          ;; Company will grab the trigger character as part of the prefix while
+          ;; the server doesn't. Remove the leading trigger character to solve
+          ;; this issue.
+          (let* ((symbol (if (consp symbol-cons)
+                             (car symbol-cons)
+                           symbol-cons))
+                 (trigger-char (seq-find (lambda (trigger-char)
+                                           (s-starts-with? trigger-char symbol))
+                                         trigger-chars)))
+            (if trigger-char
+                (cons (substring symbol (length trigger-char)) t)
+              symbol-cons)))
+      (company-grab-symbol))))
+
+(defun company-lsp--make-candidate (item prefix)
+  "Convert a CompletionItem JSON data to a string.
+
+ITEM is a hashtable representing the CompletionItem interface.
+PREFIX is the currently active prefix.
+
+The returned string has a lsp-completion-item property with the
+value of ITEM."
+  ;; The property has to be the same as added by `lsp--make-completion-item' so
+  ;; that `lsp--annotate' can use it.
+  (propertize (gethash "label" item) 'lsp-completion-item item 'lsp-completion-prefix prefix))
+
+(defun company-lsp--candidate-item (candidate)
+  "Retrieve the CompletionItem hashtable associated with CANDIDATE.
+
+CANDIDATE is a string returned by `company-lsp--make-candidate'."
+  (plist-get (text-properties-at 0 candidate) 'lsp-completion-item))
+
+(defun company-lsp--candidate-prefix (candidate)
+  "Retrieves the prefix that was active during creation of the candidate.
+
+CANDIDATE is a string returned by `company-lsp--make-candidate'."
+  (plist-get (text-properties-at 0 candidate) 'lsp-completion-prefix))
+
+(defun company-lsp--resolve-candidate (candidate &rest props)
+  "Resolve a completion candidate to fill some properties.
+
+CANDIDATE is a string returned by `company-lsp--make-candidate'.
+PROPS are strings of property names of CompletionItem hashtable
+to be resolved.
+
+The completionItem/resolve request will only be sent to the
+server if the candidate has not been resolved before, and at lest
+one of the PROPS of the CompletionItem is missing.
+
+Returns CANDIDATE with the resolved CompletionItem."
+  (unless (plist-get (text-properties-at 0 candidate) 'company-lsp-resolved)
+    (let ((item (company-lsp--candidate-item candidate)))
+      (when (seq-some (lambda (prop)
+                        (null (gethash prop item)))
+                      props)
+        (let ((resolved-item (lsp--resolve-completion item))
+              (len (length candidate)))
+          (put-text-property 0 len
+                             'lsp-completion-item resolved-item
+                             candidate)
+          (put-text-property 0 len
+                             'company-lsp-resolved t
+                             candidate)))))
+  candidate)
+
+(defun company-lsp--rust-completion-snippet (item)
+  "Function providing snippet with the rust language.
+It parses the function's signature in ITEM (a CompletionItem)
+to expand its arguments."
+  (-when-let* ((kind (gethash "kind" item))
+               (is-function (= kind 3)))
+    (let* ((detail (gethash "detail" item))
+           (snippet (when (and detail (s-matches? "^\\(pub \\)?\\(unsafe \\)?fn " detail))
+                      (-some--> (substring detail (1+ (s-index-of "(" detail)) (s-index-of ")" detail))
+                                (replace-regexp-in-string "^[^,]*self\\(, \\)?" "" it)
+                                (and (not (s-blank-str? it)) it)
+                                (s-split ", " it)
+                                (mapconcat (lambda (x) (format "${%s}" x)) it ", ")))))
+      (concat "(" (or snippet "$1") ")$0"))))
+
+(defun company-lsp--fallback-snippet (item)
+  "Return the fallback snippet to expand for ITEM.
+
+It looks for function corresponding to the language in
+`company-lsp--snippet-functions'.
+
+ITEM is a hashtable of the CompletionItem message.
+
+Return a string of the snippet to expand, or nil if no snippet is available."
+  (-when-let* ((language-id-fn (lsp--client-language-id (lsp--workspace-client lsp--cur-workspace)))
+               (language-id (funcall language-id-fn (current-buffer)))
+               (fn-cons (assoc language-id company-lsp--snippet-functions))
+               (fn (cdr fn-cons)))
+    (funcall fn item)))
+
+(defun company-lsp--looking-back-trigger-characters-p ()
+  "Return non-nil if text before point matches any of the trigger characters."
+  (let ((trigger-chars (company-lsp--trigger-characters)))
+    (cl-some (lambda (trigger-char)
+               (equal (buffer-substring-no-properties (- (point) (length trigger-char)) (point))
+                      trigger-char))
+             trigger-chars)))
+
+(defun company-lsp--post-completion (candidate)
+  "Replace a CompletionItem's label with its insertText. Apply text edits.
+
+CANDIDATE is a string returned by `company-lsp--make-candidate'."
+  (let* ((resolved-candidate (company-lsp--resolve-candidate candidate
+                                                             "insertText"
+                                                             "textEdit"
+                                                             "additionalTextEdits"))
+         (item (company-lsp--candidate-item resolved-candidate))
+         (prefix (company-lsp--candidate-prefix candidate))
+         (label (gethash "label" item))
+         (start (- (point) (length label)))
+         (insert-text (gethash "insertText" item))
+         ;; 1 = plaintext, 2 = snippet
+         (insert-text-format (gethash "insertTextFormat" item))
+         (text-edit (gethash "textEdit" item))
+         (additional-text-edits (gethash "additionalTextEdits" item)))
+    (cond
+     (text-edit
+      (setq insert-text (gethash "newText" text-edit))
+      (delete-region (- (point) (length candidate)) (point))
+      (insert prefix)
+      (let* ((range (gethash "range" text-edit))
+             (start-point (lsp--position-to-point (gethash "start" range)))
+             (new-text-length (length insert-text)))
+        (lsp--apply-text-edit text-edit)
+        (goto-char (+ start-point new-text-length))))
+     ((and insert-text (not (eq insert-text-format 2)))
+      (cl-assert (string-equal (buffer-substring-no-properties start (point)) label))
+      (goto-char start)
+      (delete-char (length label))
+      (insert insert-text)))
+
+    (let ((start-marker (set-marker (make-marker) start)))
+      (when additional-text-edits
+        (lsp--apply-text-edits additional-text-edits))
+      (when (and company-lsp-enable-snippet
+                 (fboundp 'yas-expand-snippet))
+        (if (and insert-text (eq insert-text-format 2))
+            (yas-expand-snippet insert-text (marker-position start-marker) (point))
+          (-when-let (fallback-snippet (company-lsp--fallback-snippet item))
+            (yas-expand-snippet fallback-snippet))))
+      (set-marker start-marker nil))
+    ;; Here we set this-command to a `self-insert-command'
+    ;; so that company may retrigger idle completion after the snippet expansion
+    ;; (~`company-post-command').
+    ;; This is a bit of a hack and maybe that will change in the future.
+    ;; This is useful for example when the completed candidate is a namespace
+    ;; and the annotation text (inserted snippet) is the scope operator.
+    ;;
+    ;; std| -> std::   (=> idle completion desired here)
+    ;;         stderr
+    ;;         ...
+    ;;
+    ;; See https://github.com/company-mode/company-mode/issues/143
+    (when (and company-lsp-enable-recompletion
+               (company-lsp--looking-back-trigger-characters-p))
+      (setq this-command 'self-insert-command))))
+
+(defun company-lsp--on-completion (response prefix)
+  "Handle completion RESPONSE.
+
+PREFIX is a string of the prefix when the completion is requested.
+
+Return a list of strings as the completion candidates."
+  (let* ((incomplete (and (hash-table-p response) (gethash "isIncomplete" response)))
+         (items (cond ((hash-table-p response) (gethash "items" response))
+                      ((sequencep response) response)))
+         (candidates (mapcar (lambda (item)
+                               (company-lsp--make-candidate item prefix))
+                             (lsp--sort-completions items))))
+    (when (null company-lsp--completion-cache)
+      (add-hook 'company-completion-cancelled-hook #'company-lsp--cleanup-cache)
+      (add-hook 'company-completion-finished-hook #'company-lsp--cleanup-cache))
+    (when (eq company-lsp-cache-candidates 'auto)
+      ;; Only cache candidates on auto mode. If it's t company caches the
+      ;; candidates for us.
+      (company-lsp--cache-put prefix (company-lsp--cache-item-new candidates incomplete)))
+    candidates))
+
+(defun company-lsp--cleanup-cache (_)
+  "Clean up completion cache and company hooks."
+  (setq company-lsp--completion-cache nil)
+  (remove-hook 'company-completion-finished-hook #'company-lsp--cleanup-cache)
+  (remove-hook 'company-completion-cancelled-hook #'company-lsp--cleanup-cache))
+
+(defun company-lsp--cache-put (prefix candidates)
+  "Set cache for PREFIX to be CANDIDATES.
+
+CANDIDATES is a cache item created by `company-lsp--cache-item-new'."
+  (setq company-lsp--completion-cache
+        (cons (cons prefix candidates)
+              company-lsp--completion-cache)))
+
+(defun company-lsp--cache-get (prefix)
+  "Get the cached completion for PREFIX.
+
+Return a cache item if cache for PREFIX exists. Otherwise return nil."
+  (let ((cache (cdr (assoc prefix company-lsp--completion-cache)))
+        (len (length prefix))
+        previous-cache)
+    (if cache
+        cache
+      (cl-dotimes (i len)
+        (when (setq previous-cache
+                    (cdr (assoc (substring prefix 0 (- len i 1))
+                                company-lsp--completion-cache)))
+          (if (company-lsp--cache-item-incomplete-p previous-cache)
+              (cl-return nil)
+            ;; TODO: Allow customizing matching functions to support fuzzy matching.
+            ;; Consider supporting company-flx out of box.
+            (let* ((previous-candidates (company-lsp--cache-item-candidates previous-cache))
+                   (new-candidates (all-completions prefix previous-candidates))
+                   (new-cache (company-lsp--cache-item-new new-candidates nil)))
+              (company-lsp--cache-put prefix new-cache)
+              (cl-return new-cache))))))))
+
+(defun company-lsp--cache-item-new (candidates incomplete)
+  "Create a new cache item.
+
+CANDIDATES: A list of strings. The completion candidates.
+INCOMPLETE: t or nil. Whether the candidates are incomplete or not."
+  (list :incomplete incomplete :candidates candidates))
+
+(defun company-lsp--cache-item-incomplete-p (cache-item)
+  "Determine whether a CACHE-ITEM is incomplete."
+  (plist-get cache-item :incomplete))
+
+(defun company-lsp--cache-item-candidates (cache-item)
+  "Get candidates from a CACHE-ITEM."
+  (plist-get cache-item :candidates))
+
+(defun company-lsp--documentation (candidate)
+  "Get the documentation from the item in the CANDIDATE.
+
+The documentation can be either string or MarkupContent. This method
+will return markdown string if it is MarkupContent, original string
+otherwise. If the documentation is not present, it will return nil
+which company can handle."
+  (let* ((resolved-candidate (company-lsp--resolve-candidate candidate "documentation"))
+         (item (company-lsp--candidate-item resolved-candidate))
+         (documentation (gethash "documentation" item)))
+    (if
+        (hash-table-p documentation)  ;; If true, then the documentation is a MarkupContent. String otherwise.
+        (gethash "value" documentation)
+      documentation)))
+
+(defun company-lsp--candidates-sync (prefix)
+  "Get completion candidates synchronously.
+
+PREFIX is the prefix string for completion.
+
+Return a list of strings as completion candidates."
+  (let ((req (lsp--make-request "textDocument/completion"
+                                (lsp--text-document-position-params))))
+    (company-lsp--on-completion (lsp--send-request req) prefix)))
+
+(defun company-lsp--candidates-async (prefix callback)
+  "Get completion candidates asynchronously.
+
+PREFIX is the prefix string for completion.
+CALLBACK is a function that takes a list of strings as completion candidates."
+  (let ((req (lsp--make-request "textDocument/completion"
+                                (lsp--text-document-position-params))))
+    (lsp--send-request-async req
+                             (lambda (resp)
+                               (funcall callback (company-lsp--on-completion resp prefix))))))
+
+;;;###autoload
+(defun company-lsp (command &optional arg &rest _)
+  "Define a company backend for lsp-mode.
+
+See the documentation of `company-backends' for COMMAND and ARG."
+  (interactive (list 'interactive))
+  (cl-case command
+    (interactive (company-begin-backend #'company-lsp))
+    (prefix (and
+             (bound-and-true-p lsp-mode)
+             (lsp--capability "completionProvider")
+             (not (company-in-string-or-comment))
+             (or (company-lsp--completion-prefix) 'stop)))
+    (candidates
+     ;; If the completion items in the response have textEdit action populated,
+     ;; we'll apply them in `company-lsp--post-completion'. However, textEdit
+     ;; actions only apply to the pre-completion content. We backup the current
+     ;; prefix and restore it after company completion is done, so the content
+     ;; is restored and textEdit actions can be applied.
+     (or (company-lsp--cache-item-candidates (company-lsp--cache-get arg))
+         (and company-lsp-async
+              (cons :async (lambda (callback)
+                             (company-lsp--candidates-async arg callback))))
+         (company-lsp--candidates-sync arg)))
+    (sorted t)
+    (no-cache (not (eq company-lsp-cache-candidates t)))
+    (annotation (lsp--annotate arg))
+    (quickhelp-string (company-lsp--documentation arg))
+    (doc-buffer (company-doc-buffer (company-lsp--documentation arg)))
+    (match (length arg))
+    (post-completion (company-lsp--post-completion arg))))
+
+(defun company-lsp--client-capabilities ()
+  "Return the extra client capabilities supported by company-lsp."
+  (when company-lsp-enable-snippet
+    '(:textDocument (:completion (:completionItem (:snippetSupport t))))))
+
+(add-hook 'lsp-before-initialize-hook
+          (lambda ()
+            (lsp-register-client-capabilities 'company-lsp #'company-lsp--client-capabilities)))
+
+(provide 'company-lsp)
+;;; company-lsp.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/company-lsp-20180828.438/company-lsp.elc b/configs/shared/emacs/.emacs.d/elpa/company-lsp-20180828.438/company-lsp.elc
new file mode 100644
index 0000000000..40ce02336d
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/company-lsp-20180828.438/company-lsp.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/counsel-20180719.1303/counsel-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/counsel-20180719.1303/counsel-autoloads.el
new file mode 100644
index 0000000000..f1c0b2ff7d
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/counsel-20180719.1303/counsel-autoloads.el
@@ -0,0 +1,430 @@
+;;; counsel-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "counsel" "counsel.el" (23377 60992 647032
+;;;;;;  45000))
+;;; Generated autoloads from counsel.el
+
+(autoload 'counsel-el "counsel" "\
+Elisp completion at point.
+
+\(fn)" t nil)
+
+(autoload 'counsel-cl "counsel" "\
+Common Lisp completion at point.
+
+\(fn)" t nil)
+
+(autoload 'counsel-clj "counsel" "\
+Clojure completion at point.
+
+\(fn)" t nil)
+
+(autoload 'counsel-company "counsel" "\
+Complete using `company-candidates'.
+
+\(fn)" t nil)
+
+(autoload 'counsel-irony "counsel" "\
+Inline C/C++ completion using Irony.
+
+\(fn)" t nil)
+
+(autoload 'counsel-describe-variable "counsel" "\
+Forward to `describe-variable'.
+
+Variables declared using `defcustom' are highlighted according to
+`ivy-highlight-face'.
+
+\(fn)" t nil)
+
+(autoload 'counsel-describe-function "counsel" "\
+Forward to `describe-function'.
+
+Interactive functions (i.e., commands) are highlighted according
+to `ivy-highlight-face'.
+
+\(fn)" t nil)
+
+(autoload 'counsel-set-variable "counsel" "\
+Set a variable, with completion.
+
+When the selected variable is a `defcustom' with the type boolean
+or radio, offer completion of all possible values.
+
+Otherwise, offer a variant of `eval-expression', with the initial
+input corresponding to the chosen variable.
+
+With a prefix arg, restrict list to variables defined using
+`defcustom'.
+
+\(fn SYM)" t nil)
+
+(autoload 'counsel-apropos "counsel" "\
+Show all matching symbols.
+See `apropos' for further information about what is considered
+a symbol and how to search for them.
+
+\(fn)" t nil)
+
+(autoload 'counsel-info-lookup-symbol "counsel" "\
+Forward to `info-lookup-symbol' with ivy completion.
+
+\(fn SYMBOL &optional MODE)" t nil)
+
+(autoload 'counsel-M-x "counsel" "\
+Ivy version of `execute-extended-command'.
+Optional INITIAL-INPUT is the initial input in the minibuffer.
+This function integrates with either the `amx' or `smex' package
+when available, in that order of precedence.
+
+\(fn &optional INITIAL-INPUT)" t nil)
+
+(autoload 'counsel-load-library "counsel" "\
+Load a selected the Emacs Lisp library.
+The libraries are offered from `load-path'.
+
+\(fn)" t nil)
+
+(autoload 'counsel-find-library "counsel" "\
+Visit a selected the Emacs Lisp library.
+The libraries are offered from `load-path'.
+
+\(fn)" t nil)
+
+(autoload 'counsel-load-theme "counsel" "\
+Forward to `load-theme'.
+Usable with `ivy-resume', `ivy-next-line-and-call' and
+`ivy-previous-line-and-call'.
+
+\(fn)" t nil)
+
+(autoload 'counsel-descbinds "counsel" "\
+Show a list of all defined keys and their definitions.
+If non-nil, show only bindings that start with PREFIX.
+BUFFER defaults to the current one.
+
+\(fn &optional PREFIX BUFFER)" t nil)
+
+(autoload 'counsel-faces "counsel" "\
+Complete faces with preview.
+Actions are provided by default for describing or customizing the
+selected face.
+
+\(fn)" t nil)
+
+(autoload 'counsel-git "counsel" "\
+Find file in the current Git repository.
+INITIAL-INPUT can be given as the initial minibuffer input.
+
+\(fn &optional INITIAL-INPUT)" t nil)
+
+(autoload 'counsel-git-grep "counsel" "\
+Grep for a string in the current git repository.
+When CMD is a string, use it as a \"git grep\" command.
+When CMD is non-nil, prompt for a specific \"git grep\" command.
+INITIAL-INPUT can be given as the initial minibuffer input.
+
+\(fn &optional CMD INITIAL-INPUT)" t nil)
+
+(autoload 'counsel-git-stash "counsel" "\
+Search through all available git stashes.
+
+\(fn)" t nil)
+
+(autoload 'counsel-git-change-worktree "counsel" "\
+Find the file corresponding to the current buffer on a different worktree.
+
+\(fn)" t nil)
+
+(autoload 'counsel-git-checkout "counsel" "\
+Call the \"git checkout\" command.
+
+\(fn)" t nil)
+
+(autoload 'counsel-git-log "counsel" "\
+Call the \"git log --grep\" shell command.
+
+\(fn)" t nil)
+
+(autoload 'counsel-find-file "counsel" "\
+Forward to `find-file'.
+When INITIAL-INPUT is non-nil, use it in the minibuffer during completion.
+
+\(fn &optional INITIAL-INPUT)" t nil)
+
+(autoload 'counsel-recentf "counsel" "\
+Find a file on `recentf-list'.
+
+\(fn)" t nil)
+
+(autoload 'counsel-bookmark "counsel" "\
+Forward to `bookmark-jump' or `bookmark-set' if bookmark doesn't exist.
+
+\(fn)" t nil)
+
+(autoload 'counsel-file-register "counsel" "\
+Search file in register.
+
+You cannot use Emacs' normal register commands to create file
+registers.  Instead you must use the `set-register' function like
+so: `(set-register ?i \"/home/eric/.emacs.d/init.el\")'.  Now you
+can use `C-x r j i' to open that file.
+
+\(fn)" t nil)
+
+(autoload 'counsel-locate "counsel" "\
+Call the \"locate\" shell command.
+INITIAL-INPUT can be given as the initial minibuffer input.
+
+\(fn &optional INITIAL-INPUT)" t nil)
+
+(autoload 'counsel-fzf "counsel" "\
+Open a file using the fzf shell command.
+INITIAL-INPUT can be given as the initial minibuffer input.
+INITIAL-DIRECTORY, if non-nil, is used as the root directory for search.
+FZF-PROMPT, if non-nil, is passed as `ivy-read' prompt argument.
+
+\(fn &optional INITIAL-INPUT INITIAL-DIRECTORY FZF-PROMPT)" t nil)
+
+(autoload 'counsel-dpkg "counsel" "\
+Call the \"dpkg\" shell command.
+
+\(fn)" t nil)
+
+(autoload 'counsel-rpm "counsel" "\
+Call the \"rpm\" shell command.
+
+\(fn)" t nil)
+
+(autoload 'counsel-file-jump "counsel" "\
+Jump to a file below the current directory.
+List all files within the current directory or any of its subdirectories.
+INITIAL-INPUT can be given as the initial minibuffer input.
+INITIAL-DIRECTORY, if non-nil, is used as the root directory for search.
+
+\(fn &optional INITIAL-INPUT INITIAL-DIRECTORY)" t nil)
+
+(autoload 'counsel-dired-jump "counsel" "\
+Jump to a directory (in dired) below the current directory.
+List all subdirectories within the current directory.
+INITIAL-INPUT can be given as the initial minibuffer input.
+INITIAL-DIRECTORY, if non-nil, is used as the root directory for search.
+
+\(fn &optional INITIAL-INPUT INITIAL-DIRECTORY)" t nil)
+
+(autoload 'counsel-ag "counsel" "\
+Grep for a string in the current directory using ag.
+INITIAL-INPUT can be given as the initial minibuffer input.
+INITIAL-DIRECTORY, if non-nil, is used as the root directory for search.
+EXTRA-AG-ARGS string, if non-nil, is appended to `counsel-ag-base-command'.
+AG-PROMPT, if non-nil, is passed as `ivy-read' prompt argument.
+
+\(fn &optional INITIAL-INPUT INITIAL-DIRECTORY EXTRA-AG-ARGS AG-PROMPT)" t nil)
+
+(autoload 'counsel-pt "counsel" "\
+Grep for a string in the current directory using pt.
+INITIAL-INPUT can be given as the initial minibuffer input.
+This uses `counsel-ag' with `counsel-pt-base-command' instead of
+`counsel-ag-base-command'.
+
+\(fn &optional INITIAL-INPUT)" t nil)
+
+(autoload 'counsel-ack "counsel" "\
+Grep for a string in the current directory using ack.
+INITIAL-INPUT can be given as the initial minibuffer input.
+This uses `counsel-ag' with `counsel-ack-base-command' replacing
+`counsel-ag-base-command'.
+
+\(fn &optional INITIAL-INPUT)" t nil)
+
+(autoload 'counsel-rg "counsel" "\
+Grep for a string in the current directory using rg.
+INITIAL-INPUT can be given as the initial minibuffer input.
+INITIAL-DIRECTORY, if non-nil, is used as the root directory for search.
+EXTRA-RG-ARGS string, if non-nil, is appended to `counsel-rg-base-command'.
+RG-PROMPT, if non-nil, is passed as `ivy-read' prompt argument.
+
+\(fn &optional INITIAL-INPUT INITIAL-DIRECTORY EXTRA-RG-ARGS RG-PROMPT)" t nil)
+
+(autoload 'counsel-grep "counsel" "\
+Grep for a string in the file visited by the current buffer.
+When non-nil, INITIAL-INPUT is the initial search pattern.
+
+\(fn &optional INITIAL-INPUT)" t nil)
+
+(autoload 'counsel-grep-or-swiper "counsel" "\
+Call `swiper' for small buffers and `counsel-grep' for large ones.
+When non-nil, INITIAL-INPUT is the initial search pattern.
+
+\(fn &optional INITIAL-INPUT)" t nil)
+
+(autoload 'counsel-org-tag "counsel" "\
+Add or remove tags in `org-mode'.
+
+\(fn)" t nil)
+
+(autoload 'counsel-org-tag-agenda "counsel" "\
+Set tags for the current agenda item.
+
+\(fn)" t nil)
+
+(autoload 'counsel-org-goto "counsel" "\
+Go to a different location in the current file.
+
+\(fn)" t nil)
+
+(autoload 'counsel-org-goto-all "counsel" "\
+Go to a different location in any org file.
+
+\(fn)" t nil)
+
+(autoload 'counsel-org-file "counsel" "\
+Browse all attachments for current Org file.
+
+\(fn)" t nil)
+
+(autoload 'counsel-org-entity "counsel" "\
+Complete Org entities using Ivy.
+
+\(fn)" t nil)
+
+(autoload 'counsel-org-capture "counsel" "\
+Capture something.
+
+\(fn)" t nil)
+
+(autoload 'counsel-org-agenda-headlines "counsel" "\
+Choose from headers of `org-mode' files in the agenda.
+
+\(fn)" t nil)
+
+(autoload 'counsel-tmm "counsel" "\
+Text-mode emulation of looking and choosing from a menubar.
+
+\(fn)" t nil)
+
+(autoload 'counsel-yank-pop "counsel" "\
+Ivy replacement for `yank-pop'.
+ARG has the same meaning as in `yank-pop', but its default value
+can be controlled with `counsel-yank-pop-preselect-last', which
+see.  See also `counsel-yank-pop-filter' for how to filter
+candidates.
+Note: Duplicate elements of `kill-ring' are always deleted.
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'counsel-imenu "counsel" "\
+Jump to a buffer position indexed by imenu.
+
+\(fn)" t nil)
+
+(autoload 'counsel-list-processes "counsel" "\
+Offer completion for `process-list'.
+The default action deletes the selected process.
+An extra action allows to switch to the process buffer.
+
+\(fn)" t nil)
+
+(autoload 'counsel-expression-history "counsel" "\
+Select an element of `read-expression-history'.
+And insert it into the minibuffer.  Useful during `eval-expression'.
+
+\(fn)" t nil)
+
+(autoload 'counsel-shell-command-history "counsel" "\
+Browse shell command history.
+
+\(fn)" t nil)
+
+(autoload 'counsel-minibuffer-history "counsel" "\
+Browse minibuffer history.
+
+\(fn)" t nil)
+
+(autoload 'counsel-esh-history "counsel" "\
+Browse Eshell history.
+
+\(fn)" t nil)
+
+(autoload 'counsel-shell-history "counsel" "\
+Browse shell history.
+
+\(fn)" t nil)
+
+(autoload 'counsel-outline "counsel" "\
+Jump to outline with completion.
+
+\(fn)" t nil)
+
+(autoload 'counsel-ibuffer "counsel" "\
+Use ibuffer to switch to another buffer.
+NAME specifies the name of the buffer (defaults to \"*Ibuffer*\").
+
+\(fn &optional NAME)" t nil)
+
+(autoload 'counsel-switch-to-shell-buffer "counsel" "\
+Switch to a shell buffer, or create one.
+
+\(fn)" t nil)
+
+(autoload 'counsel-unicode-char "counsel" "\
+Insert COUNT copies of a Unicode character at point.
+COUNT defaults to 1.
+
+\(fn &optional COUNT)" t nil)
+
+(autoload 'counsel-colors-emacs "counsel" "\
+Show a list of all supported colors for a particular frame.
+
+You can insert or kill the name or hexadecimal RGB value of the
+selected color.
+
+\(fn)" t nil)
+
+(autoload 'counsel-colors-web "counsel" "\
+Show a list of all W3C web colors for use in CSS.
+
+You can insert or kill the name or hexadecimal RGB value of the
+selected color.
+
+\(fn)" t nil)
+
+(autoload 'counsel-rhythmbox "counsel" "\
+Choose a song from the Rhythmbox library to play or enqueue.
+
+\(fn)" t nil)
+
+(autoload 'counsel-linux-app "counsel" "\
+Launch a Linux desktop application, similar to Alt-<F2>.
+
+\(fn)" t nil)
+
+(defvar counsel-mode nil "\
+Non-nil if Counsel mode is enabled.
+See the `counsel-mode' command
+for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `counsel-mode'.")
+
+(custom-autoload 'counsel-mode "counsel" nil)
+
+(autoload 'counsel-mode "counsel" "\
+Toggle Counsel mode on or off.
+Turn Counsel mode on if ARG is positive, off otherwise. Counsel
+mode remaps built-in emacs functions that have counsel
+replacements.
+
+\(fn &optional ARG)" t nil)
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; counsel-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/counsel-20180719.1303/counsel-pkg.el b/configs/shared/emacs/.emacs.d/elpa/counsel-20180719.1303/counsel-pkg.el
new file mode 100644
index 0000000000..55fbf29c08
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/counsel-20180719.1303/counsel-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "counsel" "20180719.1303" "Various completion functions using Ivy" '((emacs "24.3") (swiper "0.9.0")))
diff --git a/configs/shared/emacs/.emacs.d/elpa/counsel-20180719.1303/counsel.el b/configs/shared/emacs/.emacs.d/elpa/counsel-20180719.1303/counsel.el
new file mode 100644
index 0000000000..1ec2b94c16
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/counsel-20180719.1303/counsel.el
@@ -0,0 +1,4668 @@
+;;; counsel.el --- Various completion functions using Ivy -*- lexical-binding: t -*-
+
+;; Copyright (C) 2015-2018  Free Software Foundation, Inc.
+
+;; Author: Oleh Krehel <ohwoeowho@gmail.com>
+;; URL: https://github.com/abo-abo/swiper
+;; Package-Version: 20180719.1303
+;; Version: 0.10.0
+;; Package-Requires: ((emacs "24.3") (swiper "0.9.0"))
+;; Keywords: convenience, matching, tools
+
+;; This file is part of GNU Emacs.
+
+;; This file 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, or (at your option)
+;; any later version.
+
+;; This program 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.
+
+;; For a full copy of the GNU General Public License
+;; see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Just call one of the interactive functions in this file to complete
+;; the corresponding thing using `ivy'.
+;;
+;; Currently available:
+;; - Symbol completion for Elisp, Common Lisp, Python, Clojure, C, C++.
+;; - Describe fuctions for Elisp: function, variable, library, command,
+;;   bindings, theme.
+;; - Navigation functions: imenu, ace-line, semantic, outline.
+;; - Git utilities: git-files, git-grep, git-log, git-stash, git-checkout.
+;; - Grep utitilies: grep, ag, pt, recoll, ack, rg.
+;; - System utilities: process list, rhythmbox, linux-app.
+;; - Many more.
+
+;;; Code:
+
+(require 'swiper)
+(require 'compile)
+(require 'dired)
+
+;;* Utility
+(defvar counsel-more-chars-alist
+  '((counsel-grep . 2)
+    (t . 3))
+  "Map commands to their minimum required input length.
+That is the number of characters prompted for before fetching
+candidates.  The special key t is used as a fallback.")
+
+(defun counsel-more-chars ()
+  "Return two fake candidates prompting for at least N input.
+N is obtained from `counsel-more-chars-alist'."
+  (let ((diff (- (ivy-alist-setting counsel-more-chars-alist)
+                 (length ivy-text))))
+    (when (> diff 0)
+      (list "" (format "%d chars more" diff)))))
+
+(defun counsel-unquote-regex-parens (str)
+  "Unquote regex parenthesis in STR."
+  (if (consp str)
+      (mapconcat
+       #'car
+       (cl-remove-if-not #'cdr str)
+       ".*")
+    (let ((start 0)
+          ms)
+      (while (setq start (string-match "\\\\)\\|\\\\(\\|\\\\{\\|\\\\}\\|[()]" str start))
+        (setq ms (match-string-no-properties 0 str))
+        (cond ((equal ms "\\(")
+               (setq str (replace-match "(" nil t str))
+               (setq start (+ start 1)))
+              ((equal ms "\\{")
+               (setq str (replace-match "{" nil t str))
+               (setq start (+ start 1)))
+              ((equal ms "\\}")
+               (setq str (replace-match "}" nil t str))
+               (setq start (+ start 1)))
+              ((equal ms "\\)")
+               (setq str (replace-match ")" nil t str))
+               (setq start (+ start 1)))
+              ((equal ms "(")
+               (setq str (replace-match "\\(" nil t str))
+               (setq start (+ start 2)))
+              ((equal ms ")")
+               (setq str (replace-match "\\)" nil t str))
+               (setq start (+ start 2)))
+              (t
+               (error "Unexpected"))))
+      str)))
+
+(defun counsel-directory-name (dir)
+  "Return the name of directory DIR with a slash."
+  (file-name-as-directory
+   (file-name-nondirectory
+    (directory-file-name dir))))
+
+(defun counsel-string-compose (prefix str)
+  "Make PREFIX the display prefix of STR through text properties."
+  (let ((str (copy-sequence str)))
+    (put-text-property
+     0 1 'display
+     (concat prefix (substring str 0 1))
+     str)
+    str))
+
+(defun counsel-require-program (program)
+  "Check system for PROGRAM, printing error if unfound."
+  (or (and (stringp program)
+           (not (string= program ""))
+           (executable-find program))
+      (user-error "Required program \"%s\" not found in your path" program)))
+
+(make-obsolete-variable
+ 'counsel-prompt-function
+ 'ivy-set-prompt
+ "0.8.0 <2016-06-20 Mon>")
+
+(defcustom counsel-prompt-function #'counsel-prompt-function-default
+  "A function to return a full prompt string from a basic prompt string."
+  :group 'ivy
+  :type '(radio
+          (function-item counsel-prompt-function-default)
+          (function-item counsel-prompt-function-dir)
+          (function :tag "Custom")))
+
+(defun counsel-prompt-function-default ()
+  "Return prompt appended with a semicolon."
+  (ivy-add-prompt-count
+   (format "%s: " (ivy-state-prompt ivy-last))))
+
+(declare-function eshell-split-path "esh-util")
+
+(defun counsel-prompt-function-dir ()
+  "Return prompt appended with the parent directory."
+  (require 'esh-util)
+  (ivy-add-prompt-count
+   (let ((directory (ivy-state-directory ivy-last)))
+     (format "%s [%s]: "
+             (ivy-state-prompt ivy-last)
+             (let ((dir-list (eshell-split-path directory)))
+               (if (> (length dir-list) 3)
+                   (apply #'concat
+                          (append '("...")
+                                  (cl-subseq dir-list (- (length dir-list) 3))))
+                 directory))))))
+
+;;* Async Utility
+(defvar counsel--async-time nil
+  "Store the time when a new process was started.
+Or the time of the last minibuffer update.")
+
+(defvar counsel--async-start nil
+  "Store the time when a new process was started.
+Or the time of the last minibuffer update.")
+
+(defvar counsel--async-duration nil
+  "Store the time a process takes to gather all its candidates.
+The time is measured in seconds.")
+
+(defvar counsel--async-exit-code-plist ()
+  "Associate commands with their exit code descriptions.
+This plist maps commands to a plist mapping their exit codes to
+descriptions.")
+
+(defun counsel-set-async-exit-code (cmd number str)
+  "For CMD, associate NUMBER exit code with STR."
+  (let ((plist (plist-get counsel--async-exit-code-plist cmd)))
+    (setq counsel--async-exit-code-plist
+          (plist-put counsel--async-exit-code-plist
+                     cmd
+                     (plist-put plist number str)))))
+
+(defvar counsel-async-split-string-re "\n"
+  "Store the regexp for splitting shell command output.")
+
+(defvar counsel-async-ignore-re nil
+  "Regexp matching candidates to ignore in `counsel--async-filter'.")
+
+(defun counsel--async-command (cmd &optional sentinel filter name)
+  "Start and return new counsel process by calling CMD.
+If the default counsel process or one with NAME already exists,
+kill it and its associated buffer before starting a new one.
+Give the process the functions SENTINEL and FILTER, which default
+to `counsel--async-sentinel' and `counsel--async-filter',
+respectively."
+  (counsel-delete-process name)
+  (let ((name (or name " *counsel*"))
+        proc)
+    (when (get-buffer name)
+      (kill-buffer name))
+    (setq proc (start-file-process-shell-command
+                name (get-buffer-create name) cmd))
+    (setq counsel--async-time (current-time))
+    (setq counsel--async-start counsel--async-time)
+    (set-process-sentinel proc (or sentinel #'counsel--async-sentinel))
+    (set-process-filter proc (or filter #'counsel--async-filter))
+    proc))
+
+(defvar counsel-grep-last-line nil)
+
+(defun counsel--async-sentinel (process _msg)
+  "Sentinel function for an asynchronous counsel PROCESS."
+  (when (eq (process-status process) 'exit)
+    (if (zerop (process-exit-status process))
+        (progn
+          (ivy--set-candidates
+           (ivy--sort-maybe
+            (with-current-buffer (process-buffer process)
+              (split-string (buffer-string) counsel-async-split-string-re t))))
+          (setq counsel-grep-last-line nil)
+          (when counsel--async-start
+            (setq counsel--async-duration
+                  (time-to-seconds (time-since counsel--async-start))))
+          (let ((re (ivy-re-to-str (funcall ivy--regex-function ivy-text))))
+            (if ivy--old-cands
+                (ivy--recompute-index ivy-text re ivy--all-candidates)
+              (unless (ivy-set-index
+                       (ivy--preselect-index
+                        (ivy-state-preselect ivy-last)
+                        ivy--all-candidates))
+                (ivy--recompute-index ivy-text re ivy--all-candidates))))
+          (setq ivy--old-cands ivy--all-candidates)
+          (if ivy--all-candidates
+              (ivy--exhibit)
+            (ivy--insert-minibuffer "")))
+      (setq ivy--all-candidates
+            (let ((status (process-exit-status process))
+                  (plist (plist-get counsel--async-exit-code-plist
+                                    (ivy-state-caller ivy-last))))
+              (list (or (plist-get plist status)
+                        (format "error code %d" status)))))
+      (setq ivy--old-cands ivy--all-candidates)
+      (ivy--exhibit))))
+
+(defcustom counsel-async-filter-update-time 500000
+  "The amount of time in microseconds to wait until updating
+`counsel--async-filter'."
+  :type 'integer
+  :group 'ivy)
+
+(defun counsel--async-filter (process str)
+  "Receive from PROCESS the output STR.
+Update the minibuffer with the amount of lines collected every
+`counsel-async-filter-update-time' microseconds since the last update."
+  (with-current-buffer (process-buffer process)
+    (insert str))
+  (when (time-less-p (list 0 0 counsel-async-filter-update-time)
+                     (time-since counsel--async-time))
+    (let (numlines)
+      (with-current-buffer (process-buffer process)
+        (setq numlines (count-lines (point-min) (point-max)))
+        (ivy--set-candidates
+         (let ((lines (split-string (buffer-string)
+                                    counsel-async-split-string-re
+                                    t)))
+           (if (stringp counsel-async-ignore-re)
+               (cl-remove-if (lambda (line)
+                               (string-match-p counsel-async-ignore-re line))
+                             lines)
+             lines))))
+      (let ((ivy--prompt (format (concat "%d++ " (ivy-state-prompt ivy-last))
+                                 numlines)))
+        (ivy--insert-minibuffer (ivy--format ivy--all-candidates)))
+      (setq counsel--async-time (current-time)))))
+
+(defun counsel-delete-process (&optional name)
+  "Delete current counsel process or that with NAME."
+  (let ((process (get-process (or name " *counsel*"))))
+    (when process
+      (delete-process process))))
+
+;;* Completion at point
+;;** `counsel-el'
+;;;###autoload
+(defun counsel-el ()
+  "Elisp completion at point."
+  (interactive)
+  (let* ((bnd (unless (and (looking-at ")")
+                           (eq (char-before) ?\())
+                (bounds-of-thing-at-point 'symbol)))
+         (str (if bnd
+                  (buffer-substring-no-properties
+                   (car bnd)
+                   (cdr bnd))
+                ""))
+         (pred (and (eq (char-before (car bnd)) ?\()
+                    #'fboundp))
+         symbol-names)
+    (setq ivy-completion-beg (car bnd))
+    (setq ivy-completion-end (cdr bnd))
+    (if (string= str "")
+        (mapatoms
+         (lambda (x)
+           (when (symbolp x)
+             (push (symbol-name x) symbol-names))))
+      (setq symbol-names (all-completions str obarray pred)))
+    (ivy-read "Symbol name: " symbol-names
+              :caller 'counsel-el
+              :predicate pred
+              :initial-input str
+              :action #'ivy-completion-in-region-action)))
+
+(add-to-list 'ivy-height-alist '(counsel-el . 7))
+
+;;** `counsel-cl'
+(declare-function slime-symbol-start-pos "ext:slime")
+(declare-function slime-symbol-end-pos "ext:slime")
+(declare-function slime-contextual-completions "ext:slime-c-p-c")
+
+;;;###autoload
+(defun counsel-cl ()
+  "Common Lisp completion at point."
+  (interactive)
+  (setq ivy-completion-beg (slime-symbol-start-pos))
+  (setq ivy-completion-end (slime-symbol-end-pos))
+  (ivy-read "Symbol name: "
+            (car (slime-contextual-completions
+                  ivy-completion-beg
+                  ivy-completion-end))
+            :action #'ivy-completion-in-region-action))
+
+;;** `counsel-jedi'
+(declare-function deferred:sync! "ext:deferred")
+(declare-function jedi:complete-request "ext:jedi-core")
+(declare-function jedi:ac-direct-matches "ext:jedi")
+
+(defun counsel-jedi ()
+  "Python completion at point."
+  (interactive)
+  (let ((bnd (bounds-of-thing-at-point 'symbol)))
+    (setq ivy-completion-beg (car bnd))
+    (setq ivy-completion-end (cdr bnd)))
+  (deferred:sync!
+      (jedi:complete-request))
+  (ivy-read "Symbol name: " (jedi:ac-direct-matches)
+            :action #'counsel--py-action))
+
+(defun counsel--py-action (symbol-name)
+  "Insert SYMBOL-NAME, erasing the previous one."
+  (when (stringp symbol-name)
+    (with-ivy-window
+      (when ivy-completion-beg
+        (delete-region
+         ivy-completion-beg
+         ivy-completion-end))
+      (setq ivy-completion-beg (point))
+      (insert symbol-name)
+      (setq ivy-completion-end (point))
+      (when (equal (get-text-property 0 'symbol symbol-name) "f")
+        (insert "()")
+        (setq ivy-completion-end (point))
+        (backward-char)))))
+
+;;** `counsel-clj'
+(declare-function cider-sync-request:complete "ext:cider-client")
+(defun counsel--generic (completion-fn)
+  "Complete thing at point with COMPLETION-FN."
+  (let* ((bnd (or (bounds-of-thing-at-point 'symbol)
+                  (cons (point) (point))))
+         (str (buffer-substring-no-properties
+               (car bnd) (cdr bnd)))
+         (candidates (funcall completion-fn str))
+         (res (ivy-read (format "pattern (%s): " str)
+                        candidates
+                        :caller 'counsel--generic)))
+    (when (stringp res)
+      (when bnd
+        (delete-region (car bnd) (cdr bnd)))
+      (insert res))))
+
+(add-to-list 'ivy-height-alist '(counsel--generic . 7))
+
+;;;###autoload
+(defun counsel-clj ()
+  "Clojure completion at point."
+  (interactive)
+  (counsel--generic
+   (lambda (str)
+     (mapcar
+      #'cl-caddr
+      (cider-sync-request:complete str ":same")))))
+
+;;** `counsel-company'
+(defvar company-candidates)
+(defvar company-point)
+(defvar company-common)
+(declare-function company-complete "ext:company")
+(declare-function company-mode "ext:company")
+(declare-function company-complete-common "ext:company")
+
+;;;###autoload
+(defun counsel-company ()
+  "Complete using `company-candidates'."
+  (interactive)
+  (company-mode 1)
+  (unless company-candidates
+    (company-complete))
+  (when company-point
+    (when (looking-back company-common (line-beginning-position))
+      (setq ivy-completion-beg (match-beginning 0))
+      (setq ivy-completion-end (match-end 0)))
+    (ivy-read "company cand: " company-candidates
+              :action #'ivy-completion-in-region-action)))
+
+;;** `counsel-irony'
+;;;###autoload
+(defun counsel-irony ()
+  "Inline C/C++ completion using Irony."
+  (interactive)
+  (irony-completion-candidates-async 'counsel-irony-callback))
+
+(defun counsel-irony-callback (candidates)
+  "Callback function for Irony to search among CANDIDATES."
+  (interactive)
+  (let* ((symbol-bounds (irony-completion-symbol-bounds))
+         (beg (car symbol-bounds))
+         (end (cdr symbol-bounds))
+         (prefix (buffer-substring-no-properties beg end)))
+    (setq ivy-completion-beg beg
+          ivy-completion-end end)
+    (ivy-read "code: " (mapcar #'counsel-irony-annotate candidates)
+              :predicate (lambda (candidate)
+                           (string-prefix-p prefix (car candidate)))
+              :caller 'counsel-irony
+              :action 'ivy-completion-in-region-action)))
+
+(defun counsel-irony-annotate (x)
+  "Make Ivy candidate from Irony candidate X."
+  (cons (concat (car x) (irony-completion-annotation x))
+        (car x)))
+
+(add-to-list 'ivy-display-functions-alist '(counsel-irony . ivy-display-function-overlay))
+
+(declare-function irony-completion-candidates-async "ext:irony-completion")
+(declare-function irony-completion-symbol-bounds "ext:irony-completion")
+(declare-function irony-completion-annotation "ext:irony-completion")
+
+;;* Elisp symbols
+;;** `counsel-describe-variable'
+(defvar counsel-describe-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "C-.") #'counsel-find-symbol)
+    (define-key map (kbd "C-,") #'counsel--info-lookup-symbol)
+    map))
+
+(ivy-set-actions
+ 'counsel-describe-variable
+ '(("I" counsel-info-lookup-symbol "info")
+   ("d" counsel--find-symbol "definition")))
+
+(defvar counsel-describe-symbol-history nil
+  "History for `counsel-describe-variable' and `counsel-describe-function'.")
+
+(defun counsel-find-symbol ()
+  "Jump to the definition of the current symbol."
+  (interactive)
+  (ivy-exit-with-action #'counsel--find-symbol))
+
+(defun counsel--info-lookup-symbol ()
+  "Lookup the current symbol in the info docs."
+  (interactive)
+  (ivy-exit-with-action #'counsel-info-lookup-symbol))
+
+(defvar find-tag-marker-ring)
+(declare-function xref-push-marker-stack "xref")
+
+(defalias 'counsel--push-xref-marker
+    (if (require 'xref nil t)
+        #'xref-push-marker-stack
+      (require 'etags)
+      (lambda (&optional m)
+        (ring-insert (with-no-warnings find-tag-marker-ring) (or m (point-marker)))))
+  "Compatibility shim for `xref-push-marker-stack'.")
+
+(defun counsel--find-symbol (x)
+  "Find symbol definition that corresponds to string X."
+  (with-ivy-window
+    (counsel--push-xref-marker)
+    (let ((full-name (get-text-property 0 'full-name x)))
+      (if full-name
+          (find-library full-name)
+        (let ((sym (read x)))
+          (cond ((and (eq (ivy-state-caller ivy-last)
+                          'counsel-describe-variable)
+                      (boundp sym))
+                 (find-variable sym))
+                ((fboundp sym)
+                 (find-function sym))
+                ((boundp sym)
+                 (find-variable sym))
+                ((or (featurep sym)
+                     (locate-library
+                      (prin1-to-string sym)))
+                 (find-library
+                  (prin1-to-string sym)))
+                (t
+                 (error "Couldn't find definition of %s"
+                        sym))))))))
+
+(define-obsolete-function-alias 'counsel-symbol-at-point
+    'ivy-thing-at-point "0.7.0")
+
+(defun counsel-variable-list ()
+  "Return the list of all currently bound variables."
+  (let (cands)
+    (mapatoms
+     (lambda (vv)
+       (when (or (get vv 'variable-documentation)
+                 (and (boundp vv) (not (keywordp vv))))
+         (push (symbol-name vv) cands))))
+    (delete "" cands)))
+
+(defcustom counsel-describe-variable-function #'describe-variable
+  "Function to call to describe a variable passed as parameter."
+  :type 'function
+  :group 'ivy)
+
+(defun counsel-describe-variable-transformer (var)
+  "Propertize VAR if it's a custom variable."
+  (if (custom-variable-p (intern var))
+      (ivy-append-face var 'ivy-highlight-face)
+    var))
+
+(ivy-set-display-transformer
+ 'counsel-describe-variable 'counsel-describe-variable-transformer)
+
+;;;###autoload
+(defun counsel-describe-variable ()
+  "Forward to `describe-variable'.
+
+Variables declared using `defcustom' are highlighted according to
+`ivy-highlight-face'."
+  (interactive)
+  (let ((enable-recursive-minibuffers t))
+    (ivy-read
+     "Describe variable: "
+     (counsel-variable-list)
+     :keymap counsel-describe-map
+     :preselect (ivy-thing-at-point)
+     :history 'counsel-describe-symbol-history
+     :require-match t
+     :sort t
+     :action (lambda (x)
+               (funcall counsel-describe-variable-function (intern x)))
+     :caller 'counsel-describe-variable)))
+
+;;** `counsel-describe-function'
+(ivy-set-actions
+ 'counsel-describe-function
+ '(("I" counsel-info-lookup-symbol "info")
+   ("d" counsel--find-symbol "definition")))
+
+(defcustom counsel-describe-function-function #'describe-function
+  "Function to call to describe a function passed as parameter."
+  :type 'function
+  :group 'ivy)
+
+(defun counsel-describe-function-transformer (function-name)
+  "Propertize FUNCTION-NAME if it's an interactive function."
+  (if (commandp (intern function-name))
+      (ivy-append-face function-name 'ivy-highlight-face)
+    function-name))
+
+(ivy-set-display-transformer
+ 'counsel-describe-function 'counsel-describe-function-transformer)
+
+(defun ivy-function-called-at-point ()
+  (let ((f (function-called-at-point)))
+    (and f (symbol-name f))))
+
+(defcustom counsel-describe-function-preselect #'ivy-thing-at-point
+  "Determine what `counsel-describe-function' should preselect."
+  :group 'ivy
+  :type '(radio
+          (function-item ivy-thing-at-point)
+          (function-item ivy-function-called-at-point)))
+
+;;;###autoload
+(defun counsel-describe-function ()
+  "Forward to `describe-function'.
+
+Interactive functions \(i.e., commands) are highlighted according
+to `ivy-highlight-face'."
+  (interactive)
+  (let ((enable-recursive-minibuffers t))
+    (ivy-read "Describe function: "
+              (let (cands)
+                (mapatoms
+                 (lambda (x)
+                   (when (fboundp x)
+                     (push (symbol-name x) cands))))
+                cands)
+              :keymap counsel-describe-map
+              :preselect (funcall counsel-describe-function-preselect)
+              :history 'counsel-describe-symbol-history
+              :require-match t
+              :sort t
+              :action (lambda (x)
+                        (funcall counsel-describe-function-function (intern x)))
+              :caller 'counsel-describe-function)))
+
+;;** `counsel-set-variable'
+(defvar counsel-set-variable-history nil
+  "Store history for `counsel-set-variable'.")
+
+(defun counsel-read-setq-expression (sym)
+  "Read and eval a setq expression for SYM."
+  (setq this-command 'eval-expression)
+  (let* ((minibuffer-completing-symbol t)
+         (sym-value (symbol-value sym))
+         (expr (minibuffer-with-setup-hook
+                   (lambda ()
+                     (add-function :before-until (local 'eldoc-documentation-function)
+                                   #'elisp-eldoc-documentation-function)
+                     (add-hook 'completion-at-point-functions #'elisp-completion-at-point nil t)
+                     (run-hooks 'eval-expression-minibuffer-setup-hook)
+                     (goto-char (minibuffer-prompt-end))
+                     (forward-char 6)
+                     (insert (format "%S " sym)))
+                 (read-from-minibuffer "Eval: "
+                                       (format
+                                        (if (and sym-value (consp sym-value))
+                                            "(setq '%S)"
+                                          "(setq %S)")
+                                        sym-value)
+                                       read-expression-map t
+                                       'read-expression-history))))
+    (eval-expression expr)))
+
+(defun counsel--setq-doconst (x)
+  "Return a cons of description and value for X.
+X is an item of a radio- or choice-type defcustom."
+  (let (y)
+    (when (and (listp x)
+               (consp (setq y (last x))))
+      (unless (equal y '(function))
+        (setq x (car y))
+        (cons (prin1-to-string x)
+              (if (symbolp x)
+                  (list 'quote x)
+                x))))))
+
+(declare-function lv-message "ext:lv")
+(declare-function lv-delete-window "ext:lv")
+(declare-function custom-variable-documentation "cus-edit")
+
+;;;###autoload
+(defun counsel-set-variable (sym)
+  "Set a variable, with completion.
+
+When the selected variable is a `defcustom' with the type boolean
+or radio, offer completion of all possible values.
+
+Otherwise, offer a variant of `eval-expression', with the initial
+input corresponding to the chosen variable.
+
+With a prefix arg, restrict list to variables defined using
+`defcustom'."
+  (interactive (list (intern
+                      (ivy-read "Variable: " (counsel-variable-list)
+                                :predicate (and current-prefix-arg
+                                                (lambda (varname)
+                                                  (get (intern varname) 'custom-type)))
+                                :preselect (ivy-thing-at-point)
+                                :history 'counsel-set-variable-history))))
+  (let ((doc (and (require 'cus-edit)
+                  (require 'lv nil t)
+                  (not (string= "nil" (custom-variable-documentation sym)))
+                  (propertize (custom-variable-documentation sym)
+                              'face 'font-lock-comment-face)))
+        sym-type
+        cands)
+    (unwind-protect
+         (progn
+           (when doc
+             (lv-message doc))
+           (if (and (boundp sym)
+                    (setq sym-type (get sym 'custom-type))
+                    (cond
+                      ((and (consp sym-type)
+                            (memq (car sym-type) '(choice radio)))
+                       (setq cands (delq nil (mapcar #'counsel--setq-doconst (cdr sym-type)))))
+                      ((eq sym-type 'boolean)
+                       (setq cands '(("nil" . nil) ("t" . t))))
+                      (t nil)))
+               (let* ((sym-val (symbol-value sym))
+                      ;; Escape '%' chars if present
+                      (sym-val-str (replace-regexp-in-string "%" "%%" (format "%s" sym-val)))
+                      (res (ivy-read (format "Set (%S <%s>): " sym sym-val-str)
+                                     cands
+                                     :preselect (prin1-to-string sym-val))))
+                 (when res
+                   (setq res
+                         (if (assoc res cands)
+                             (cdr (assoc res cands))
+                           (read res)))
+                   (set sym (if (and (listp res) (eq (car res) 'quote))
+                                (cadr res)
+                              res))))
+             (unless (boundp sym)
+               (set sym nil))
+             (counsel-read-setq-expression sym)))
+      (when doc
+        (lv-delete-window)))))
+
+;;** `counsel-apropos'
+;;;###autoload
+(defun counsel-apropos ()
+  "Show all matching symbols.
+See `apropos' for further information about what is considered
+a symbol and how to search for them."
+  (interactive)
+  (ivy-read "Search for symbol (word list or regexp): "
+            (counsel-symbol-list)
+            :history 'counsel-apropos-history
+            :action (lambda (pattern)
+                      (when (string-equal pattern "")
+                        (user-error "Please specify a pattern"))
+                      ;; If the user selected a candidate form the list, we use
+                      ;; a pattern which matches only the selected symbol.
+                      (if (memq this-command '(ivy-immediate-done ivy-alt-done))
+                          ;; Regexp pattern are passed verbatim, other input is
+                          ;; split into words.
+                          (if (string-equal (regexp-quote pattern) pattern)
+                              (apropos (split-string pattern "[ \t]+" t))
+                            (apropos pattern))
+                        (apropos (concat "^" pattern "$"))))
+            :caller 'counsel-apropos))
+
+(defun counsel-symbol-list ()
+  "Return a list of all symbols."
+  (let (cands)
+    (mapatoms
+     (lambda (symbol)
+       (when (or (boundp symbol) (fboundp symbol))
+         (push (symbol-name symbol) cands))))
+    (delete "" cands)))
+
+;;** `counsel-info-lookup-symbol'
+(defvar info-lookup-mode)
+(declare-function info-lookup-guess-default "info-look")
+(declare-function info-lookup->completions "info-look")
+(declare-function info-lookup->mode-value "info-look")
+(declare-function info-lookup-select-mode "info-look")
+(declare-function info-lookup-change-mode "info-look")
+(declare-function info-lookup "info-look")
+
+;;;###autoload
+(defun counsel-info-lookup-symbol (symbol &optional mode)
+  "Forward to `info-lookup-symbol' with ivy completion."
+  (interactive
+   (progn
+     (require 'info-look)
+     ;; Courtesy of `info-lookup-interactive-arguments'
+     (let* ((topic 'symbol)
+            (mode (cond (current-prefix-arg
+                         (info-lookup-change-mode topic))
+                        ((info-lookup->mode-value
+                          topic (info-lookup-select-mode))
+                         info-lookup-mode)
+                        ((info-lookup-change-mode topic))))
+            (enable-recursive-minibuffers t))
+       (list (ivy-read "Describe symbol: " (info-lookup->completions topic mode)
+                       :history 'info-lookup-history
+                       :preselect (info-lookup-guess-default topic mode)
+                       :sort t
+                       :caller 'counsel-info-lookup-symbol)
+             mode))))
+  (info-lookup-symbol symbol mode))
+
+;;** `counsel-M-x'
+(defface counsel-key-binding
+  '((t :inherit font-lock-keyword-face))
+  "Face used by `counsel-M-x' for key bindings."
+  :group 'ivy-faces)
+
+(defun counsel-M-x-transformer (cmd)
+  "Return CMD annotated with its active key binding, if any."
+  (let ((key (where-is-internal (intern cmd) nil t)))
+    (if (not key)
+        cmd
+      ;; Prefer `<f2>' over `C-x 6' where applicable
+      (let ((i (cl-search [?\C-x ?6] key)))
+        (when i
+          (let ((dup (vconcat (substring key 0 i) [f2] (substring key (+ i 2))))
+                (map (current-global-map)))
+            (when (equal (lookup-key map key)
+                         (lookup-key map dup))
+              (setq key dup)))))
+      (setq key (key-description key))
+      (put-text-property 0 (length key) 'face 'counsel-key-binding key)
+      (format "%s (%s)" cmd key))))
+
+(defvar amx-initialized)
+(defvar amx-cache)
+(declare-function amx-initialize "ext:amx")
+(declare-function amx-detect-new-commands "ext:amx")
+(declare-function amx-update "ext:amx")
+(declare-function amx-rank "ext:amx")
+(defvar smex-initialized-p)
+(defvar smex-ido-cache)
+(declare-function smex-initialize "ext:smex")
+(declare-function smex-detect-new-commands "ext:smex")
+(declare-function smex-update "ext:smex")
+(declare-function smex-rank "ext:smex")
+
+(defun counsel--M-x-externs ()
+  "Return `counsel-M-x' candidates from external packages.
+The currently supported packages are, in order of precedence,
+`amx' and `smex'."
+  (cond ((require 'amx nil t)
+         (unless amx-initialized
+           (amx-initialize))
+         (when (amx-detect-new-commands)
+           (amx-update))
+         (mapcar
+          (lambda (command-item) (symbol-name (car command-item))) amx-cache))
+        ((require 'smex nil t)
+         (unless smex-initialized-p
+           (smex-initialize))
+         (when (smex-detect-new-commands)
+           (smex-update))
+         smex-ido-cache)))
+
+(defun counsel--M-x-prompt ()
+  "String for `M-x' plus the string representation of `current-prefix-arg'."
+  (if (not current-prefix-arg)
+      "M-x "
+    (concat
+     (if (eq current-prefix-arg '-)
+         "- "
+       (if (integerp current-prefix-arg)
+           (format "%d " current-prefix-arg)
+         (if (= (car current-prefix-arg) 4)
+             "C-u "
+           (format "%d " (car current-prefix-arg)))))
+     "M-x ")))
+
+(defvar counsel-M-x-history nil
+  "History for `counsel-M-x'.")
+
+;;;###autoload
+(defun counsel-M-x (&optional initial-input)
+  "Ivy version of `execute-extended-command'.
+Optional INITIAL-INPUT is the initial input in the minibuffer.
+This function integrates with either the `amx' or `smex' package
+when available, in that order of precedence."
+  (interactive)
+  ;; When `counsel-M-x' returns, `last-command' would be set to
+  ;; `counsel-M-x' because :action hasn't been invoked yet.
+  ;; Instead, preserve the old value of `this-command'.
+  (setq this-command last-command)
+  (setq real-this-command real-last-command)
+  (let ((externs (counsel--M-x-externs)))
+    (ivy-read (counsel--M-x-prompt) (or externs obarray)
+              :predicate (and (not externs) #'commandp)
+              :require-match t
+              :history 'counsel-M-x-history
+              :action (lambda (cmd)
+                        (setq cmd (intern cmd))
+                        (cond ((bound-and-true-p amx-initialized)
+                               (amx-rank cmd))
+                              ((bound-and-true-p smex-initialized-p)
+                               (smex-rank cmd)))
+                        (setq prefix-arg current-prefix-arg)
+                        (setq this-command cmd)
+                        (setq real-this-command cmd)
+                        (command-execute cmd 'record))
+              :sort (not externs)
+              :keymap counsel-describe-map
+              :initial-input initial-input
+              :caller 'counsel-M-x)))
+
+(ivy-set-actions
+ 'counsel-M-x
+ `(("d" counsel--find-symbol "definition")
+   ("h" ,(lambda (x) (describe-function (intern x))) "help")))
+
+(ivy-set-display-transformer
+ 'counsel-M-x
+ 'counsel-M-x-transformer)
+
+;;** `counsel-command-history'
+(defun counsel-command-history-action-eval (cmd)
+  "Eval the command CMD."
+  (eval (read cmd)))
+
+(defun counsel-command-history-action-edit-and-eval (cmd)
+  "Edit and eval the command CMD."
+  (edit-and-eval-command "Eval: " (read cmd)))
+
+(ivy-set-actions
+ 'counsel-command-history
+ '(("r" counsel-command-history-action-eval           "eval command")
+   ("e" counsel-command-history-action-edit-and-eval  "edit and eval command")))
+
+(defun counsel-command-history ()
+  "Show the history of commands."
+  (interactive)
+  (ivy-read "%d Command: " (mapcar #'prin1-to-string command-history)
+            :require-match t
+            :action #'counsel-command-history-action-eval
+            :caller 'counsel-command-history))
+
+;;** `counsel-load-library'
+(defun counsel-library-candidates ()
+  "Return a list of completion candidates for `counsel-load-library'."
+  (interactive)
+  (let ((dirs load-path)
+        (suffix (concat (regexp-opt '(".el" ".el.gz") t) "\\'"))
+        (cands (make-hash-table :test #'equal))
+        short-name
+        old-val
+        dir-parent
+        res)
+    (dolist (dir dirs)
+      (when (file-directory-p dir)
+        (dolist (file (file-name-all-completions "" dir))
+          (when (string-match suffix file)
+            (unless (string-match "pkg.elc?$" file)
+              (setq short-name (substring file 0 (match-beginning 0)))
+              (if (setq old-val (gethash short-name cands))
+                  (progn
+                    ;; assume going up directory once will resolve name clash
+                    (setq dir-parent (counsel-directory-name (cdr old-val)))
+                    (puthash short-name
+                             (cons
+                              (counsel-string-compose dir-parent (car old-val))
+                              (cdr old-val))
+                             cands)
+                    (setq dir-parent (counsel-directory-name dir))
+                    (puthash (concat dir-parent short-name)
+                             (cons
+                              (propertize
+                               (counsel-string-compose
+                                dir-parent short-name)
+                               'full-name (expand-file-name file dir))
+                              dir)
+                             cands))
+                (puthash short-name
+                         (cons (propertize
+                                short-name
+                                'full-name (expand-file-name file dir))
+                               dir) cands)))))))
+    (maphash (lambda (_k v) (push (car v) res)) cands)
+    (nreverse res)))
+
+;;;###autoload
+(defun counsel-load-library ()
+  "Load a selected the Emacs Lisp library.
+The libraries are offered from `load-path'."
+  (interactive)
+  (let ((cands (counsel-library-candidates)))
+    (ivy-read "Load library: " cands
+              :action (lambda (x)
+                        (load-library
+                         (get-text-property 0 'full-name x)))
+              :keymap counsel-describe-map)))
+
+(ivy-set-actions
+ 'counsel-load-library
+ '(("d" counsel--find-symbol "definition")))
+
+;;** `counsel-find-library'
+(declare-function find-library-name "find-func")
+(defun counsel-find-library-other-window (library)
+  (let ((buf (find-file-noselect (find-library-name library))))
+    (pop-to-buffer buf 'other-window)))
+
+(defun counsel-find-library-other-frame (library)
+  (let ((buf (find-file-noselect (find-library-name library))))
+    (condition-case nil
+        (switch-to-buffer-other-frame buf)
+      (error (pop-to-buffer buf)))))
+
+(ivy-set-actions
+ 'counsel-find-library
+ '(("j" counsel-find-library-other-window "other window")
+   ("f" counsel-find-library-other-frame "other frame")))
+
+;;;###autoload
+(defun counsel-find-library ()
+  "Visit a selected the Emacs Lisp library.
+The libraries are offered from `load-path'."
+  (interactive)
+  (let ((cands (counsel-library-candidates)))
+    (ivy-read "Find library: " cands
+              :action #'counsel--find-symbol
+              :keymap counsel-describe-map
+              :caller 'counsel-find-library)))
+
+;;** `counsel-load-theme'
+(declare-function powerline-reset "ext:powerline")
+
+(defun counsel-load-theme-action (x)
+  "Disable current themes and load theme X."
+  (condition-case nil
+      (progn
+        (mapc #'disable-theme custom-enabled-themes)
+        (load-theme (intern x) t)
+        (when (fboundp 'powerline-reset)
+          (powerline-reset)))
+    (error "Problem loading theme %s" x)))
+
+;;;###autoload
+(defun counsel-load-theme ()
+  "Forward to `load-theme'.
+Usable with `ivy-resume', `ivy-next-line-and-call' and
+`ivy-previous-line-and-call'."
+  (interactive)
+  (ivy-read "Load custom theme: "
+            (mapcar 'symbol-name
+                    (custom-available-themes))
+            :action #'counsel-load-theme-action
+            :caller 'counsel-load-theme))
+
+;;** `counsel-descbinds'
+(ivy-set-actions
+ 'counsel-descbinds
+ '(("d" counsel-descbinds-action-find "definition")
+   ("I" counsel-descbinds-action-info "info")))
+
+(defvar counsel-descbinds-history nil
+  "History for `counsel-descbinds'.")
+
+(defun counsel--descbinds-cands (&optional prefix buffer)
+  "Get key bindings starting with PREFIX in BUFFER.
+See `describe-buffer-bindings' for further information."
+  (let ((buffer (or buffer (current-buffer)))
+        (re-exclude (regexp-opt
+                     '("<vertical-line>" "<bottom-divider>" "<right-divider>"
+                       "<mode-line>" "<C-down-mouse-2>" "<left-fringe>"
+                       "<right-fringe>" "<header-line>"
+                       "<vertical-scroll-bar>" "<horizontal-scroll-bar>")))
+        res)
+    (with-temp-buffer
+      (let ((indent-tabs-mode t))
+        (describe-buffer-bindings buffer prefix))
+      (goto-char (point-min))
+      ;; Skip the "Key translations" section
+      (re-search-forward "")
+      (forward-char 1)
+      (while (not (eobp))
+        (when (looking-at "^\\([^\t\n]+\\)[\t ]*\\(.*\\)$")
+          (let ((key (match-string 1))
+                (fun (match-string 2))
+                cmd)
+            (unless (or (member fun '("??" "self-insert-command"))
+                        (string-match re-exclude key)
+                        (not (or (commandp (setq cmd (intern-soft fun)))
+                                 (member fun '("Prefix Command")))))
+              (push
+               (cons (format
+                      "%-15s %s"
+                      (propertize key 'face 'font-lock-builtin-face)
+                      fun)
+                     (cons key cmd))
+               res))))
+        (forward-line 1)))
+    (nreverse res)))
+
+(defun counsel-descbinds-action-describe (x)
+  "Describe function of candidate X.
+See `describe-function' for further information."
+  (let ((cmd (cddr x)))
+    (describe-function cmd)))
+
+(defun counsel-descbinds-action-find (x)
+  "Find symbol definition of candidate X.
+See `counsel--find-symbol' for further information."
+  (let ((cmd (cddr x)))
+    (counsel--find-symbol (symbol-name cmd))))
+
+(defun counsel-descbinds-action-info (x)
+  "Display symbol definition of candidate X, as found in the relevant manual.
+See `info-lookup-symbol' for further information."
+  (let ((cmd (cddr x)))
+    (counsel-info-lookup-symbol (symbol-name cmd))))
+
+;;;###autoload
+(defun counsel-descbinds (&optional prefix buffer)
+  "Show a list of all defined keys and their definitions.
+If non-nil, show only bindings that start with PREFIX.
+BUFFER defaults to the current one."
+  (interactive)
+  (ivy-read "Bindings: " (counsel--descbinds-cands prefix buffer)
+            :action #'counsel-descbinds-action-describe
+            :history 'counsel-descbinds-history
+            :caller 'counsel-descbinds))
+
+;;** `counsel-describe-face'
+(defcustom counsel-describe-face-function #'describe-face
+  "Function to call to describe a face or face name argument."
+  :type 'function
+  :group 'ivy)
+
+(defun counsel--face-at-point ()
+  "Return name of face around point.
+Try detecting a face name in the text around point before falling
+back to the face of the character after point, and finally the
+`default' face."
+  (symbol-name (or (face-at-point t) 'default)))
+
+(defun counsel-describe-face ()
+  "Completion for `describe-face'."
+  (interactive)
+  (ivy-read "Face: " (face-list)
+            :require-match t
+            :history 'face-name-history
+            :preselect (counsel--face-at-point)
+            :sort t
+            :action counsel-describe-face-function
+            :caller 'counsel-describe-face))
+
+(defun counsel-customize-face (name)
+  "Customize face with NAME."
+  (customize-face (intern name)))
+
+(defun counsel-customize-face-other-window (name)
+  "Customize face with NAME in another window."
+  (customize-face-other-window (intern name)))
+
+(ivy-set-actions
+ 'counsel-describe-face
+ '(("c" counsel-customize-face "customize")
+   ("C" counsel-customize-face-other-window "customize other window")))
+
+;;** `counsel-faces'
+(defun counsel--faces-format-function (format)
+  "Return an `ivy-format-function' for `counsel-faces'.
+Each candidate is formatted based on the given FORMAT string."
+  (let ((formatter (lambda (name)
+                     (format format name (propertize list-faces-sample-text
+                                                     'face (intern name))))))
+    (lambda (names)
+      (ivy--format-function-generic
+       (lambda (name)
+         (funcall formatter (ivy--add-face name 'ivy-current-match)))
+       formatter names "\n"))))
+
+;;;###autoload
+(defun counsel-faces ()
+  "Complete faces with preview.
+Actions are provided by default for describing or customizing the
+selected face."
+  (interactive)
+  (let* ((names (mapcar #'symbol-name (face-list)))
+         (ivy-format-function
+          (counsel--faces-format-function
+           (format "%%-%ds %%s"
+                   (apply #'max 0 (mapcar #'string-width names))))))
+    (ivy-read "Face: " names
+              :require-match t
+              :history 'face-name-history
+              :preselect (counsel--face-at-point)
+              :sort t
+              :action counsel-describe-face-function
+              :caller 'counsel-faces)))
+
+(ivy-set-actions
+ 'counsel-faces
+ '(("c" counsel-customize-face "customize")
+   ("C" counsel-customize-face-other-window "customize other window")))
+
+;;* Git
+;;** `counsel-git'
+(defvar counsel-git-cmd "git ls-files --full-name --"
+  "Command for `counsel-git'.")
+
+(ivy-set-actions
+ 'counsel-git
+ '(("j" find-file-other-window "other window")
+   ("x" counsel-find-file-extern "open externally")))
+
+(defun counsel-locate-git-root ()
+  "Locate the root of the git repository containing the current buffer."
+  (or (locate-dominating-file default-directory ".git")
+      (error "Not in a git repository")))
+
+;;;###autoload
+(defun counsel-git (&optional initial-input)
+  "Find file in the current Git repository.
+INITIAL-INPUT can be given as the initial minibuffer input."
+  (interactive)
+  (counsel-require-program (car (split-string counsel-git-cmd)))
+  (ivy-set-prompt 'counsel-git counsel-prompt-function)
+  (let* ((default-directory (expand-file-name (counsel-locate-git-root)))
+         (cands (split-string
+                 (shell-command-to-string counsel-git-cmd)
+                 "\n"
+                 t)))
+    (ivy-read "Find file" cands
+              :initial-input initial-input
+              :action #'counsel-git-action
+              :caller 'counsel-git)))
+
+(defun counsel-git-action (x)
+  "Find file X in current Git repository."
+  (with-ivy-window
+    (let ((default-directory (ivy-state-directory ivy-last)))
+      (find-file x))))
+
+(defun counsel-git-occur ()
+  "Occur function for `counsel-git' using `counsel-cmd-to-dired'."
+  (cd (ivy-state-directory ivy-last))
+  (counsel-cmd-to-dired
+   (counsel--expand-ls
+    (format "%s | grep -i -E '%s' | xargs ls"
+            counsel-git-cmd
+            (counsel-unquote-regex-parens ivy--old-re)))))
+
+(defvar counsel-dired-listing-switches "-alh"
+  "Switches passed to `ls' for `counsel-cmd-to-dired'.")
+
+(defun counsel-cmd-to-dired (full-cmd &optional filter)
+  "Adapted from `find-dired'."
+  (let ((inhibit-read-only t))
+    (erase-buffer)
+    (dired-mode default-directory counsel-dired-listing-switches)
+    (insert "  " default-directory ":\n")
+    (let ((point (point)))
+      (insert "  " full-cmd "\n")
+      (dired-insert-set-properties point (point)))
+    (setq-local dired-sort-inhibit t)
+    (setq-local revert-buffer-function
+                (lambda (_1 _2) (counsel-cmd-to-dired full-cmd)))
+    (setq-local dired-subdir-alist
+                (list (cons default-directory (point-min-marker))))
+    (let ((proc (start-process-shell-command
+                 "counsel-cmd" (current-buffer) full-cmd)))
+      (set-process-filter proc filter)
+      (set-process-sentinel
+       proc
+       (lambda (process _msg)
+         (when (and (eq (process-status process) 'exit)
+                    (zerop (process-exit-status process)))
+           (goto-char (point-min))
+           (forward-line 2)
+           (dired-move-to-filename)))))))
+
+(ivy-set-occur 'counsel-git 'counsel-git-occur)
+
+;;** `counsel-git-grep'
+(defvar counsel-git-grep-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "C-l") 'ivy-call-and-recenter)
+    (define-key map (kbd "M-q") 'counsel-git-grep-query-replace)
+    (define-key map (kbd "C-c C-m") 'counsel-git-grep-switch-cmd)
+    map))
+
+(ivy-set-occur 'counsel-git-grep 'counsel-git-grep-occur)
+(ivy-set-display-transformer 'counsel-git-grep 'counsel-git-grep-transformer)
+
+(defvar counsel-git-grep-cmd-default "git --no-pager grep --full-name -n --no-color -i -I -e \"%s\""
+  "Initial command for `counsel-git-grep'.")
+
+(defvar counsel-git-grep-cmd nil
+  "Store the command for `counsel-git-grep'.")
+
+(defvar counsel--git-grep-count nil
+  "Store the line count in current repository.")
+
+(defvar counsel--git-grep-count-threshold 20000
+  "The maximum threshold beyond which repositories are considered large.")
+
+(defvar counsel-git-grep-history nil
+  "History for `counsel-git-grep'.")
+
+(defvar counsel-git-grep-cmd-history
+  (list counsel-git-grep-cmd-default)
+  "History for `counsel-git-grep' shell commands.")
+
+(defcustom counsel-grep-post-action-hook nil
+  "Hook that runs after the point moves to the next candidate.
+Typical value: '(recenter)."
+  :type 'hook
+  :group 'ivy)
+
+(defun counsel-git-grep-function (str &optional _pred &rest _unused)
+  "Grep in the current git repository for STRING."
+  (or
+   (and (> counsel--git-grep-count counsel--git-grep-count-threshold)
+        (counsel-more-chars))
+   (let* ((default-directory (ivy-state-directory ivy-last))
+          (cmd (format counsel-git-grep-cmd
+                       (setq ivy--old-re (ivy--regex str t)))))
+     (if (<= counsel--git-grep-count counsel--git-grep-count-threshold)
+         (split-string (shell-command-to-string cmd) "\n" t)
+       (counsel--gg-candidates (ivy--regex str))
+       nil))))
+
+(defun counsel-git-grep-action (x)
+  "Go to occurrence X in current Git repository."
+  (when (string-match "\\`\\(.*?\\):\\([0-9]+\\):\\(.*\\)\\'" x)
+    (let ((file-name (match-string-no-properties 1 x))
+          (line-number (match-string-no-properties 2 x)))
+      (find-file (expand-file-name
+                  file-name
+                  (ivy-state-directory ivy-last)))
+      (goto-char (point-min))
+      (forward-line (1- (string-to-number line-number)))
+      (re-search-forward (ivy--regex ivy-text t) (line-end-position) t)
+      (swiper--ensure-visible)
+      (run-hooks 'counsel-grep-post-action-hook)
+      (unless (eq ivy-exit 'done)
+        (swiper--cleanup)
+        (swiper--add-overlays (ivy--regex ivy-text))))))
+
+(defun counsel-git-grep-matcher (regexp candidates)
+  "Return REGEXP matching CANDIDATES for `counsel-git-grep'."
+  (or (and (equal regexp ivy--old-re)
+           ivy--old-cands)
+      (prog1
+          (setq ivy--old-cands
+                (cl-remove-if-not
+                 (lambda (x)
+                   (ignore-errors
+                     (when (string-match "^[^:]+:[^:]+:" x)
+                       (setq x (substring x (match-end 0)))
+                       (if (stringp regexp)
+                           (string-match regexp x)
+                         (let ((res t))
+                           (dolist (re regexp)
+                             (setq res
+                                   (and res
+                                        (ignore-errors
+                                          (if (cdr re)
+                                              (string-match (car re) x)
+                                            (not (string-match (car re) x)))))))
+                           res)))))
+                 candidates))
+        (setq ivy--old-re regexp))))
+
+(defun counsel-git-grep-transformer (str)
+  "Higlight file and line number in STR."
+  (when (string-match "\\`\\([^:]+\\):\\([^:]+\\):" str)
+    (ivy-add-face-text-property (match-beginning 1) (match-end 1)
+                                'compilation-info
+                                str)
+    (ivy-add-face-text-property (match-beginning 2) (match-end 2)
+                                'compilation-line-number
+                                str))
+  str)
+
+(defvar counsel-git-grep-projects-alist nil
+  "An alist of project directory to \"git-grep\" command.
+Allows to automatically use a custom \"git-grep\" command for all
+files in a project.")
+
+(defun counsel--git-grep-cmd-and-proj (cmd)
+  (let ((dd (expand-file-name default-directory))
+        proj)
+    (cond
+      ((stringp cmd))
+      (cmd
+       (if (setq proj
+                 (cl-find-if
+                  (lambda (x)
+                    (string-match (car x) dd))
+                  counsel-git-grep-projects-alist))
+           (setq cmd (cdr proj))
+         (setq cmd
+               (ivy-read "cmd: " counsel-git-grep-cmd-history
+                         :history 'counsel-git-grep-cmd-history
+                         :re-builder #'ivy--regex))
+         (setq counsel-git-grep-cmd-history
+               (delete-dups counsel-git-grep-cmd-history))))
+      (t
+       (setq cmd counsel-git-grep-cmd-default)))
+    (cons proj cmd)))
+
+(defun counsel--git-grep-count-func-default ()
+  "Default defun to calculate `counsel--git-grep-count'."
+  (if (eq system-type 'windows-nt)
+      0
+    (read (shell-command-to-string "du -s \"$(git rev-parse --git-dir)\" 2>/dev/null"))))
+
+(defvar counsel--git-grep-count-func #'counsel--git-grep-count-func-default
+  "Defun to calculate `counsel--git-grep-count' for `counsel-git-grep'.")
+
+;;;###autoload
+(defun counsel-git-grep (&optional cmd initial-input)
+  "Grep for a string in the current git repository.
+When CMD is a string, use it as a \"git grep\" command.
+When CMD is non-nil, prompt for a specific \"git grep\" command.
+INITIAL-INPUT can be given as the initial minibuffer input."
+  (interactive "P")
+  (ivy-set-prompt 'counsel-git-grep counsel-prompt-function)
+  (let ((proj-and-cmd (counsel--git-grep-cmd-and-proj cmd))
+        proj)
+    (setq proj (car proj-and-cmd))
+    (setq counsel-git-grep-cmd (cdr proj-and-cmd))
+    (counsel-require-program (car (split-string counsel-git-grep-cmd)))
+    (let ((collection-function
+           (if proj
+               #'counsel-git-grep-proj-function
+             #'counsel-git-grep-function))
+          (unwind-function
+           (if proj
+               (lambda ()
+                 (counsel-delete-process)
+                 (swiper--cleanup))
+             (lambda ()
+               (swiper--cleanup))))
+          (default-directory (if proj
+                                 (car proj)
+                               (counsel-locate-git-root))))
+      (setq counsel--git-grep-count (funcall counsel--git-grep-count-func))
+      (ivy-read "git grep" collection-function
+                :initial-input initial-input
+                :matcher #'counsel-git-grep-matcher
+                :dynamic-collection (or proj
+                                        (>
+                                         counsel--git-grep-count
+                                         counsel--git-grep-count-threshold))
+                :keymap counsel-git-grep-map
+                :action #'counsel-git-grep-action
+                :unwind unwind-function
+                :history 'counsel-git-grep-history
+                :caller 'counsel-git-grep))))
+(cl-pushnew 'counsel-git-grep ivy-highlight-grep-commands)
+
+(defun counsel-git-grep-proj-function (str)
+  "Grep for STR in the current git repository."
+  (or
+   (counsel-more-chars)
+   (let ((regex (setq ivy--old-re
+                      (ivy--regex str t))))
+     (counsel--async-command (format counsel-git-grep-cmd regex))
+     nil)))
+
+(defun counsel-git-grep-switch-cmd ()
+  "Set `counsel-git-grep-cmd' to a different value."
+  (interactive)
+  (setq counsel-git-grep-cmd
+        (ivy-read "cmd: " counsel-git-grep-cmd-history
+                  :history 'counsel-git-grep-cmd-history))
+  (setq counsel-git-grep-cmd-history
+        (delete-dups counsel-git-grep-cmd-history))
+  (unless (ivy-state-dynamic-collection ivy-last)
+    (setq ivy--all-candidates
+          (all-completions "" 'counsel-git-grep-function))))
+
+(defvar counsel-gg-state nil
+  "The current state of candidates / count sync.")
+
+(defun counsel--gg-candidates (regex)
+  "Return git grep candidates for REGEX."
+  (setq counsel-gg-state -2)
+  (counsel--gg-count regex)
+  (let ((default-directory (ivy-state-directory ivy-last)))
+    (set-process-filter
+     (counsel--async-command (concat (format counsel-git-grep-cmd regex)
+                                     " | head -n 200")
+                             #'counsel--gg-sentinel)
+     nil)))
+
+(defun counsel--gg-sentinel (process _msg)
+  "Sentinel function for a `counsel-git-grep' PROCESS."
+  (when (eq (process-status process) 'exit)
+    (cl-case (process-exit-status process)
+      ((0 141)
+       (with-current-buffer (process-buffer process)
+         (setq ivy--all-candidates
+               (or (split-string (buffer-string) "\n" t)
+                   '("")))
+         (setq ivy--old-cands ivy--all-candidates))
+       (when (zerop (cl-incf counsel-gg-state))
+         (ivy--exhibit)))
+      (1
+       (setq ivy--all-candidates '("Error"))
+       (setq ivy--old-cands ivy--all-candidates)
+       (ivy--exhibit)))))
+
+(defun counsel--gg-count-sentinel (process _msg)
+  "Sentinel function for a `counsel--gg-count' PROCESS."
+  (when (and (eq (process-status process) 'exit)
+             (zerop (process-exit-status process)))
+    (with-current-buffer (process-buffer process)
+      (setq ivy--full-length (string-to-number (buffer-string))))
+    (when (zerop (cl-incf counsel-gg-state))
+      (ivy--exhibit))))
+
+(defun counsel--gg-count (regex &optional no-async)
+  "Count the number of results matching REGEX in `counsel-git-grep'.
+The command to count the matches is called asynchronously.
+If NO-ASYNC is non-nil, do it synchronously instead."
+  (let ((default-directory (ivy-state-directory ivy-last))
+        (cmd (concat
+              (format (replace-regexp-in-string
+                       "--full-name" "-c"
+                       counsel-git-grep-cmd)
+                      ;; "git grep -i -c '%s'"
+                      (replace-regexp-in-string
+                       "-" "\\\\-"
+                       (replace-regexp-in-string "'" "''" regex)))
+              " | sed 's/.*:\\(.*\\)/\\1/g' | awk '{s+=$1} END {print s}'")))
+    (if no-async
+        (string-to-number (shell-command-to-string cmd))
+      (set-process-filter
+       (counsel--async-command cmd #'counsel--gg-count-sentinel
+                               nil " *counsel-gg-count*")
+       nil))))
+
+(defun counsel-git-grep-occur ()
+  "Generate a custom occur buffer for `counsel-git-grep'.
+When REVERT is non-nil, regenerate the current *ivy-occur* buffer."
+  (unless (eq major-mode 'ivy-occur-grep-mode)
+    (ivy-occur-grep-mode)
+    (setq default-directory (ivy-state-directory ivy-last)))
+  (setq ivy-text
+        (and (string-match "\"\\(.*\\)\"" (buffer-name))
+             (match-string 1 (buffer-name))))
+  (let* ((regex (funcall ivy--regex-function ivy-text))
+         (positive-pattern (replace-regexp-in-string
+                            ;; git-grep can't handle .*?
+                            "\\.\\*\\?" ".*"
+                            (if (stringp regex) regex (caar regex))))
+         (negative-patterns
+          (if (stringp regex) ""
+            (mapconcat (lambda (x)
+                         (and (null (cdr x))
+                              (format "| grep -v %s" (car x))))
+                       regex
+                       " ")))
+         (cmd (concat (format counsel-git-grep-cmd positive-pattern) negative-patterns))
+         cands)
+    (setq cands (split-string
+                 (shell-command-to-string cmd)
+                 "\n"
+                 t))
+    ;; Need precise number of header lines for `wgrep' to work.
+    (insert (format "-*- mode:grep; default-directory: %S -*-\n\n\n"
+                    default-directory))
+    (insert (format "%d candidates:\n" (length cands)))
+    (ivy--occur-insert-lines
+     (mapcar
+      (lambda (cand) (concat "./" cand))
+      cands))))
+
+(defun counsel-git-grep-query-replace ()
+  "Start `query-replace' with string to replace from last search string."
+  (interactive)
+  (unless (window-minibuffer-p)
+    (user-error
+     "Should only be called in the minibuffer through `counsel-git-grep-map'"))
+  (let* ((enable-recursive-minibuffers t)
+         (from (ivy--regex ivy-text))
+         (to (query-replace-read-to from "Query replace" t)))
+    (ivy-exit-with-action
+     (lambda (_)
+       (let (done-buffers)
+         (dolist (cand ivy--old-cands)
+           (when (string-match "\\`\\(.*?\\):\\([0-9]+\\):\\(.*\\)\\'" cand)
+             (with-ivy-window
+               (let ((file-name (match-string-no-properties 1 cand)))
+                 (setq file-name (expand-file-name
+                                  file-name
+                                  (ivy-state-directory ivy-last)))
+                 (unless (member file-name done-buffers)
+                   (push file-name done-buffers)
+                   (find-file file-name)
+                   (goto-char (point-min)))
+                 (perform-replace from to t t nil))))))))))
+
+;;** `counsel-git-stash'
+(defun counsel-git-stash-kill-action (x)
+  "Add git stash command to kill ring.
+The git command applies the stash entry where candidate X was found in."
+  (when (string-match "\\([^:]+\\):" x)
+    (kill-new (message (format "git stash apply %s" (match-string 1 x))))))
+
+;;;###autoload
+(defun counsel-git-stash ()
+  "Search through all available git stashes."
+  (interactive)
+  (let* ((default-directory (counsel-locate-git-root))
+         (cands (split-string (shell-command-to-string
+                               "IFS=$'\n'
+for i in `git stash list --format=\"%gd\"`; do
+    git stash show -p $i | grep -H --label=\"$i\" \"$1\"
+done") "\n" t)))
+    (ivy-read "git stash: " cands
+              :action 'counsel-git-stash-kill-action
+              :caller 'counsel-git-stash)))
+
+;;** `counsel-git-log'
+(defvar counsel-git-log-cmd "GIT_PAGER=cat git log --grep '%s'"
+  "Command used for \"git log\".")
+
+(defvar counsel-git-log-split-string-re "\ncommit "
+  "The `split-string' separates when split output of `counsel-git-log-cmd'.")
+
+(defun counsel-git-log-function (str)
+  "Search for STR in git log."
+  (or
+   (counsel-more-chars)
+   (progn
+     ;; `counsel--yank-pop-format-function' uses this
+     (setq ivy--old-re (funcall ivy--regex-function str))
+     (counsel--async-command
+      ;; "git log --grep" likes to have groups quoted e.g. \(foo\).
+      ;; But it doesn't like the non-greedy ".*?".
+      (format counsel-git-log-cmd
+              (replace-regexp-in-string "\\.\\*\\?" ".*"
+                                        (ivy-re-to-str ivy--old-re))))
+     nil)))
+
+(defun counsel-git-log-action (x)
+  "Add candidate X to kill ring."
+  (message "%S" (kill-new x)))
+
+;;** `counsel-git-change-worktree'
+(defun counsel-git-change-worktree-action (git-root-dir tree)
+  "Find the corresponding file in the worktree located at tree.
+The current buffer is assumed to be in a subdirectory of GIT-ROOT-DIR.
+TREE is the selected candidate."
+  (let* ((new-root-dir (counsel-git-worktree-parse-root tree))
+         (tree-filename (file-relative-name (buffer-file-name) git-root-dir))
+         (file-name (expand-file-name tree-filename new-root-dir)))
+    (find-file file-name)))
+
+(defun counsel-git-worktree-list ()
+  "List worktrees in the git repository containing the current buffer."
+  (let ((default-directory (counsel-locate-git-root)))
+    (split-string (shell-command-to-string "git worktree list") "\n" t)))
+
+(defun counsel-git-worktree-parse-root (tree)
+  "Return worktree from candidate TREE."
+  (substring tree 0 (string-match " " tree)))
+
+(defun counsel-git-close-worktree-files-action (root-dir)
+  "Close all buffers from the worktree located at ROOT-DIR."
+  (setq root-dir (counsel-git-worktree-parse-root root-dir))
+  (save-excursion
+    (dolist (buf (buffer-list))
+      (set-buffer buf)
+      (and buffer-file-name
+           (string= "." (file-relative-name root-dir (counsel-locate-git-root)))
+           (kill-buffer buf)))))
+
+(ivy-set-actions
+ 'counsel-git-change-worktree
+ '(("k" counsel-git-close-worktree-files-action "kill all")))
+
+;;;###autoload
+(defun counsel-git-change-worktree ()
+  "Find the file corresponding to the current buffer on a different worktree."
+  (interactive)
+  (let ((default-directory (counsel-locate-git-root)))
+    (ivy-read "Select worktree: "
+              (or (cl-delete default-directory (counsel-git-worktree-list)
+                             :key #'counsel-git-worktree-parse-root :test #'string=)
+                  (error "No other worktrees!"))
+              :action (lambda (tree)
+                        (counsel-git-change-worktree-action
+                         (ivy-state-directory ivy-last) tree))
+              :require-match t
+              :caller 'counsel-git-change-worktree)))
+
+;;** `counsel-git-checkout'
+(defun counsel-git-checkout-action (branch)
+  "Call the \"git checkout BRANCH\" command.
+
+BRANCH is a string whose first word designates the command argument."
+  (shell-command
+   (format "git checkout %s" (substring branch 0 (string-match " " branch)))))
+
+(defun counsel-git-branch-list ()
+  "Return list of branches in the current git repository.
+Value comprises all local and remote branches bar the one
+currently checked out."
+  (cl-mapcan (lambda (line)
+               (and (string-match "\\`[[:blank:]]+" line)
+                    (list (substring line (match-end 0)))))
+             (let ((default-directory (counsel-locate-git-root)))
+               (split-string (shell-command-to-string "git branch -vv --all")
+                             "\n" t))))
+
+;;;###autoload
+(defun counsel-git-checkout ()
+  "Call the \"git checkout\" command."
+  (interactive)
+  (ivy-read "Checkout branch: " (counsel-git-branch-list)
+            :action #'counsel-git-checkout-action
+            :caller 'counsel-git-checkout))
+
+(defvar counsel-yank-pop-truncate-radius)
+
+;;;###autoload
+(defun counsel-git-log ()
+  "Call the \"git log --grep\" shell command."
+  (interactive)
+  (let ((counsel-async-split-string-re counsel-git-log-split-string-re)
+        (counsel-async-ignore-re "^[ \n]*$")
+        (counsel-yank-pop-truncate-radius 5)
+        (ivy-format-function #'counsel--yank-pop-format-function))
+    (ivy-read "Grep log: " #'counsel-git-log-function
+              :dynamic-collection t
+              :action #'counsel-git-log-action
+              :unwind #'counsel-delete-process
+              :caller 'counsel-git-log)))
+
+(add-to-list 'ivy-height-alist '(counsel-git-log . 4))
+
+;;* File
+;;** `counsel-find-file'
+(defvar counsel-find-file-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "C-DEL") 'counsel-up-directory)
+    (define-key map (kbd "C-<backspace>") 'counsel-up-directory)
+    (define-key map (kbd "C-M-y") 'counsel-yank-directory)
+    map))
+
+(defun counsel-yank-directory ()
+  "Yank the current directory into the minibuffer."
+  (interactive)
+  (insert ivy--directory))
+
+(when (executable-find "git")
+  (add-to-list 'ivy-ffap-url-functions 'counsel-github-url-p)
+  (add-to-list 'ivy-ffap-url-functions 'counsel-emacs-url-p))
+(add-to-list 'ivy-ffap-url-functions 'counsel-url-expand)
+(defun counsel-find-file-cd-bookmark-action (_)
+  "Reset `counsel-find-file' from selected directory."
+  (ivy-read "cd: "
+            (progn
+              (ivy--virtual-buffers)
+              (delete-dups
+               (mapcar (lambda (x) (file-name-directory (cdr x)))
+                       ivy--virtual-buffers)))
+            :action (lambda (x)
+                      (let ((default-directory (file-name-directory x)))
+                        (counsel-find-file)))))
+
+(defcustom counsel-root-command "sudo"
+  "Command to gain root privileges."
+  :type 'string
+  :group 'ivy)
+
+(defun counsel-find-file-as-root (x)
+  "Find file X with root privileges."
+  (counsel-require-program counsel-root-command)
+  (let* ((host (file-remote-p x 'host))
+         (file-name (format "/%s:%s:%s"
+                            counsel-root-command
+                            (or host "")
+                            (expand-file-name
+                             (if host
+                                 (file-remote-p x 'localname)
+                               x)))))
+    ;; If the current buffer visits the same file we are about to open,
+    ;; replace the current buffer with the new one.
+    (if (eq (current-buffer) (get-file-buffer x))
+        (find-alternate-file file-name)
+      (find-file file-name))))
+
+(defun counsel-find-file-delete (x)
+  "Delete file X."
+  (dired-delete-file x dired-recursive-deletes delete-by-moving-to-trash))
+
+(defun counsel-find-file-move (x)
+  "Move or rename file X."
+  (ivy-read "Rename file to: " 'read-file-name-internal
+            :matcher #'counsel--find-file-matcher
+            :action (lambda (new-name)
+                      (require 'dired-aux)
+                      (dired-rename-file x new-name 1))
+            :keymap counsel-find-file-map
+            :caller 'counsel-find-file-move))
+
+(defun counsel-find-file-mkdir-action (_x)
+  (make-directory (expand-file-name ivy-text ivy--directory)))
+
+(ivy-set-actions
+ 'counsel-find-file
+ '(("j" find-file-other-window "other window")
+   ("f" find-file-other-frame "other frame")
+   ("b" counsel-find-file-cd-bookmark-action "cd bookmark")
+   ("x" counsel-find-file-extern "open externally")
+   ("r" counsel-find-file-as-root "open as root")
+   ("k" counsel-find-file-delete "delete")
+   ("m" counsel-find-file-move "move or rename")
+   ("d" counsel-find-file-mkdir-action "mkdir")))
+
+(defcustom counsel-find-file-at-point nil
+  "When non-nil, add file-at-point to the list of candidates."
+  :type 'boolean
+  :group 'ivy)
+
+(defcustom counsel-preselect-current-file nil
+  "When non-nil, preselect current file in list of candidates."
+  :type 'boolean
+  :group 'ivy)
+
+(defcustom counsel-find-file-ignore-regexp nil
+  "A regexp of files to ignore while in `counsel-find-file'.
+These files are un-ignored if `ivy-text' matches them.  The
+common way to show all files is to start `ivy-text' with a dot.
+
+Example value: \"\\(?:\\`[#.]\\)\\|\\(?:[#~]\\'\\)\".  This will hide
+temporary and lock files.
+\\<ivy-minibuffer-map>
+Choosing the dotfiles option, \"\\`\\.\", might be convenient,
+since you can still access the dotfiles if your input starts with
+a dot. The generic way to toggle ignored files is \\[ivy-toggle-ignore],
+but the leading dot is a lot faster."
+  :group 'ivy
+  :type `(choice
+          (const :tag "None" nil)
+          (const :tag "Dotfiles" "\\`\\.")
+          (const :tag "Ignored Extensions"
+                 ,(regexp-opt completion-ignored-extensions))
+          (regexp :tag "Regex")))
+
+(defun counsel--find-file-matcher (regexp candidates)
+  "Return REGEXP matching CANDIDATES.
+Skip some dotfiles unless `ivy-text' requires them."
+  (let ((res
+         (ivy--re-filter
+          regexp candidates
+          (lambda (re-str)
+            (lambda (x)
+              (string-match re-str (directory-file-name x)))))))
+    (if (or (null ivy-use-ignore)
+            (null counsel-find-file-ignore-regexp)
+            (string-match "\\`\\." ivy-text))
+        res
+      (or (cl-remove-if
+           (lambda (x)
+             (and
+              (string-match counsel-find-file-ignore-regexp x)
+              (not (member x ivy-extra-directories))))
+           res)
+          res))))
+
+(declare-function ffap-guesser "ffap")
+
+(defvar counsel-find-file-speedup-remote t
+  "Speed up opening remote files by disabling `find-file-hook' for them.")
+
+(defun counsel-find-file-action (x)
+  "Find file X."
+  (with-ivy-window
+    (if (and counsel-find-file-speedup-remote
+             (file-remote-p ivy--directory))
+        (let ((find-file-hook nil))
+          (find-file (expand-file-name x ivy--directory)))
+      (find-file (expand-file-name x ivy--directory)))))
+
+(defun counsel--preselect-file ()
+  "Return candidate to preselect during filename completion.
+The preselect behaviour can be customized via user options
+`counsel-find-file-at-point' and
+`counsel-preselect-current-file', which see."
+  (or
+   (when counsel-find-file-at-point
+     (require 'ffap)
+     (let ((f (ffap-guesser)))
+       (when f (expand-file-name f))))
+   (and counsel-preselect-current-file
+        buffer-file-name
+        (file-name-nondirectory buffer-file-name))))
+
+;;;###autoload
+(defun counsel-find-file (&optional initial-input)
+  "Forward to `find-file'.
+When INITIAL-INPUT is non-nil, use it in the minibuffer during completion."
+  (interactive)
+  (ivy-read "Find file: " 'read-file-name-internal
+            :matcher #'counsel--find-file-matcher
+            :initial-input initial-input
+            :action #'counsel-find-file-action
+            :preselect (counsel--preselect-file)
+            :require-match 'confirm-after-completion
+            :history 'file-name-history
+            :keymap counsel-find-file-map
+            :caller 'counsel-find-file))
+
+(ivy-set-occur 'counsel-find-file 'counsel-find-file-occur)
+
+(defvar counsel-find-file-occur-cmd "ls -a | grep -i -E '%s' | xargs -d '\\n' ls -d --group-directories-first"
+  "Format string for `counsel-find-file-occur'.")
+
+(defvar counsel-find-file-occur-use-find nil
+  "When non-nil, `counsel-find-file-occur' will use \"find\" as the base cmd.")
+
+(defun counsel--expand-ls (cmd)
+  "Expand CMD that ends in \"ls\" with switches."
+  (concat cmd " " counsel-dired-listing-switches " | sed -e \"s/^/  /\""))
+
+(defun counsel--occur-cmd-find ()
+  (let* ((regex (counsel-unquote-regex-parens ivy--old-re))
+         (cmd (format
+               "find . -maxdepth 1 | grep -i -E '%s' | xargs -I {} find {} -maxdepth 0 -ls"
+               regex)))
+    (concat
+     (counsel--cmd-to-dired-by-type "d" cmd)
+     " && "
+     (counsel--cmd-to-dired-by-type "f" cmd))))
+
+(defun counsel--cmd-to-dired-by-type (type cmd)
+  (let ((exclude-dots
+         (if (string-match "^\\." ivy-text)
+             ""
+           " | grep -v '/\\\\.'")))
+    (replace-regexp-in-string
+     " | grep"
+     (concat " -type " type exclude-dots " | grep") cmd)))
+
+(defun counsel-find-file-occur ()
+  (require 'find-dired)
+  (cd ivy--directory)
+  (if counsel-find-file-occur-use-find
+      (counsel-cmd-to-dired
+       (counsel--occur-cmd-find)
+       'find-dired-filter)
+    (counsel-cmd-to-dired
+     (counsel--expand-ls
+      (format counsel-find-file-occur-cmd
+              (counsel-unquote-regex-parens ivy--old-re))))))
+
+(defun counsel-up-directory ()
+  "Go to the parent directory preselecting the current one.
+
+If the current directory is remote and it's not possible to go up any
+further, make the remote prefix editable"
+  (interactive)
+  (let* ((cur-dir (directory-file-name (expand-file-name ivy--directory)))
+         (up-dir (file-name-directory cur-dir)))
+    (if (and (file-remote-p cur-dir) (string-equal cur-dir up-dir))
+        (progn
+          ;; make the remote prefix editable
+          (setq ivy--old-cands nil)
+          (setq ivy--old-re nil)
+          (ivy-set-index 0)
+          (setq ivy--directory "")
+          (setq ivy--all-candidates nil)
+          (setq ivy-text "")
+          (delete-minibuffer-contents)
+          (insert up-dir))
+      (ivy--cd up-dir)
+      (setf (ivy-state-preselect ivy-last)
+            (file-name-as-directory (file-name-nondirectory cur-dir))))))
+
+(defun counsel-at-git-issue-p ()
+  "When point is at an issue in a Git-versioned file, return the issue string."
+  (and (looking-at "#[0-9]+")
+       (or (eq (vc-backend buffer-file-name) 'Git)
+           (eq major-mode 'magit-commit-mode)
+           (bound-and-true-p magit-commit-mode))
+       (match-string-no-properties 0)))
+
+(defun counsel-github-url-p ()
+  "Return a Github issue URL at point."
+  (counsel-require-program "git")
+  (let ((url (counsel-at-git-issue-p)))
+    (when url
+      (let ((origin (shell-command-to-string
+                     "git remote get-url origin"))
+            user repo)
+        (cond ((string-match "\\`git@github.com:\\([^/]+\\)/\\(.*\\)\\.git$"
+                             origin)
+               (setq user (match-string 1 origin))
+               (setq repo (match-string 2 origin)))
+              ((string-match "\\`https://github.com/\\([^/]+\\)/\\(.*\\)$"
+                             origin)
+               (setq user (match-string 1 origin))
+               (setq repo (match-string 2 origin))))
+        (when user
+          (setq url (format "https://github.com/%s/%s/issues/%s"
+                            user repo (substring url 1))))))))
+
+(defun counsel-emacs-url-p ()
+  "Return a Debbugs issue URL at point."
+  (counsel-require-program "git")
+  (let ((url (counsel-at-git-issue-p)))
+    (when url
+      (let ((origin (shell-command-to-string
+                     "git remote get-url origin")))
+        (when (string-match "git.sv.gnu.org:/srv/git/emacs.git" origin)
+          (format "http://debbugs.gnu.org/cgi/bugreport.cgi?bug=%s"
+                  (substring url 1)))))))
+
+(defvar counsel-url-expansions-alist nil
+  "Map of regular expressions to expansions.
+
+This variable should take the form of a list of (REGEXP . FORMAT)
+pairs.
+
+`counsel-url-expand' will expand the word at point according to
+FORMAT for the first matching REGEXP.  FORMAT can be either a
+string or a function.  If it is a string, it will be used as the
+format string for the `format' function, with the word at point
+as the next argument.  If it is a function, it will be called
+with the word at point as the sole argument.
+
+For example, a pair of the form:
+  '(\"\\`BSERV-[[:digit:]]+\\'\" . \"https://jira.atlassian.com/browse/%s\")
+will expand to URL `https://jira.atlassian.com/browse/BSERV-100'
+when the word at point is BSERV-100.
+
+If the format element is a function, more powerful
+transformations are possible.  As an example,
+  '(\"\\`issue\\([[:digit:]]+\\)\\'\" .
+    (lambda (word)
+      (concat \"http://debbugs.gnu.org/cgi/bugreport.cgi?bug=\"
+              (match-string 1 word))))
+trims the \"issue\" prefix from the word at point before creating the URL.")
+
+(defun counsel-url-expand ()
+  "Expand word at point using `counsel-url-expansions-alist'.
+The first pair in the list whose regexp matches the word at point
+will be expanded according to its format.  This function is
+intended to be used in `ivy-ffap-url-functions' to browse the
+result as a URL."
+  (let ((word-at-point (current-word)))
+    (cl-some
+     (lambda (pair)
+       (let ((regexp (car pair))
+             (formatter (cdr pair)))
+         (when (string-match regexp word-at-point)
+           (if (functionp formatter)
+               (funcall formatter word-at-point)
+             (format formatter word-at-point)))))
+     counsel-url-expansions-alist)))
+
+;;** `counsel-recentf'
+(defvar recentf-list)
+(declare-function recentf-mode "recentf")
+
+;;;###autoload
+(defun counsel-recentf ()
+  "Find a file on `recentf-list'."
+  (interactive)
+  (require 'recentf)
+  (recentf-mode)
+  (ivy-read "Recentf: " (mapcar #'substring-no-properties recentf-list)
+            :action (lambda (f)
+                      (with-ivy-window
+                        (find-file f)))
+            :caller 'counsel-recentf))
+(ivy-set-actions
+ 'counsel-recentf
+ '(("j" find-file-other-window "other window")
+   ("f" find-file-other-frame "other frame")
+   ("x" counsel-find-file-extern "open externally")))
+
+;;** `counsel-bookmark'
+(defcustom counsel-bookmark-avoid-dired nil
+  "If non-nil, open directory bookmarks with `counsel-find-file'.
+By default `counsel-bookmark' opens a dired buffer for directories."
+  :type 'boolean
+  :group 'ivy)
+
+(declare-function bookmark-all-names "bookmark")
+(declare-function bookmark-location "bookmark")
+
+;;;###autoload
+(defun counsel-bookmark ()
+  "Forward to `bookmark-jump' or `bookmark-set' if bookmark doesn't exist."
+  (interactive)
+  (require 'bookmark)
+  (ivy-read "Create or jump to bookmark: "
+            (bookmark-all-names)
+            :action (lambda (x)
+                      (cond ((and counsel-bookmark-avoid-dired
+                                  (member x (bookmark-all-names))
+                                  (file-directory-p (bookmark-location x)))
+                             (with-ivy-window
+                               (let ((default-directory (bookmark-location x)))
+                                 (counsel-find-file))))
+                            ((member x (bookmark-all-names))
+                             (with-ivy-window
+                               (bookmark-jump x)))
+                            (t
+                             (bookmark-set x))))
+            :caller 'counsel-bookmark))
+
+(defun counsel--apply-bookmark-fn (fn)
+  "Return a function applyinig FN to a bookmark's location."
+  (lambda (bookmark)
+    (funcall fn (bookmark-location bookmark))))
+
+(ivy-set-actions
+ 'counsel-bookmark
+ `(("d" bookmark-delete "delete")
+   ("e" bookmark-rename "edit")
+   ("x" ,(counsel--apply-bookmark-fn #'counsel-find-file-extern)
+        "open externally")
+   ("r" ,(counsel--apply-bookmark-fn #'counsel-find-file-as-root)
+        "open as root")))
+
+;;** `counsel-file-register'
+;;;###autoload
+(defun counsel-file-register ()
+  "Search file in register.
+
+You cannot use Emacs' normal register commands to create file
+registers.  Instead you must use the `set-register' function like
+so: `(set-register ?i \"/home/eric/.emacs.d/init.el\")'.  Now you
+can use `C-x r j i' to open that file."
+  (interactive)
+  (ivy-read "File Register: "
+            ;; Use the `register-alist' variable to filter out file
+            ;; registers.  Each entry for a file registar will have the
+            ;; following layout:
+            ;;
+            ;;     (NUMBER 'file . "string/path/to/file")
+            ;;
+            ;; So we go through each entry and see if the `cadr' is
+            ;; `eq' to the symbol `file'.  If so then add the filename
+            ;; (`cddr') which `ivy-read' will use for its choices.
+            (mapcar (lambda (register-alist-entry)
+                      (if (eq 'file (cadr register-alist-entry))
+                          (cddr register-alist-entry)))
+                    register-alist)
+            :sort t
+            :require-match t
+            :history 'counsel-file-register
+            :caller 'counsel-file-register
+            :action (lambda (register-file)
+                      (with-ivy-window (find-file register-file)))))
+
+(ivy-set-actions
+ 'counsel-file-register
+ '(("j" find-file-other-window "other window")))
+
+;;** `counsel-locate'
+(defcustom counsel-locate-cmd (cond ((eq system-type 'darwin)
+                                     'counsel-locate-cmd-noregex)
+                                    ((and (eq system-type 'windows-nt)
+                                          (executable-find "es.exe"))
+                                     'counsel-locate-cmd-es)
+                                    (t
+                                     'counsel-locate-cmd-default))
+  "The function for producing a locate command string from the input.
+
+The function takes a string - the current input, and returns a
+string - the full shell command to run."
+  :group 'ivy
+  :type '(choice
+          (const :tag "Default" counsel-locate-cmd-default)
+          (const :tag "No regex" counsel-locate-cmd-noregex)
+          (const :tag "mdfind" counsel-locate-cmd-mdfind)
+          (const :tag "everything" counsel-locate-cmd-es)))
+
+(ivy-set-actions
+ 'counsel-locate
+ '(("x" counsel-locate-action-extern "xdg-open")
+   ("d" counsel-locate-action-dired "dired")))
+
+(counsel-set-async-exit-code 'counsel-locate 1 "Nothing found")
+
+(defvar counsel-locate-history nil
+  "History for `counsel-locate'.")
+
+(defun counsel-locate-action-extern (x)
+  "Pass X to `xdg-open' or equivalent command via the shell."
+  (interactive "FFile: ")
+  (if (and (eq system-type 'windows-nt)
+           (fboundp 'w32-shell-execute))
+      (w32-shell-execute "open" x)
+    (start-process-shell-command shell-file-name nil
+                                 (format "%s %s"
+                                         (cl-case system-type
+                                           (darwin "open")
+                                           (cygwin "cygstart")
+                                           (t "xdg-open"))
+                                         (shell-quote-argument x)))))
+
+(defalias 'counsel-find-file-extern 'counsel-locate-action-extern)
+
+(declare-function dired-jump "dired-x")
+
+(defun counsel-locate-action-dired (x)
+  "Use `dired-jump' on X."
+  (dired-jump nil x))
+
+(defun counsel-locate-cmd-default (input)
+  "Return a shell command based on INPUT."
+  (counsel-require-program "locate")
+  (format "locate -i --regex '%s'"
+          (counsel-unquote-regex-parens
+           (ivy--regex input))))
+
+(defun counsel-locate-cmd-noregex (input)
+  "Return a shell command based on INPUT."
+  (counsel-require-program "locate")
+  (format "locate -i '%s'" input))
+
+(defun counsel-locate-cmd-mdfind (input)
+  "Return a shell command based on INPUT."
+  (counsel-require-program "mdfind")
+  (format "mdfind -name '%s'" input))
+
+(defun counsel-locate-cmd-es (input)
+  "Return a shell command based on INPUT."
+  (counsel-require-program "es.exe")
+  (format "es.exe -i -r -p %s"
+          (counsel-unquote-regex-parens
+           (ivy--regex input t))))
+
+(defun counsel-locate-function (input)
+  "Call the \"locate\" shell command with INPUT."
+  (or
+   (counsel-more-chars)
+   (progn
+     (counsel--async-command
+      (funcall counsel-locate-cmd input))
+     '("" "working..."))))
+
+;;;###autoload
+(defun counsel-locate (&optional initial-input)
+  "Call the \"locate\" shell command.
+INITIAL-INPUT can be given as the initial minibuffer input."
+  (interactive)
+  (ivy-read "Locate: " #'counsel-locate-function
+            :initial-input initial-input
+            :dynamic-collection t
+            :history 'counsel-locate-history
+            :action (lambda (file)
+                      (when file
+                        (with-ivy-window
+                          (find-file file))))
+            :unwind #'counsel-delete-process
+            :caller 'counsel-locate))
+
+;;** `counsel-fzf'
+(defvar counsel-fzf-cmd "fzf -f \"%s\""
+  "Command for `counsel-fzf'.")
+
+(defvar counsel--fzf-dir nil
+  "Store the base fzf directory.")
+
+(defvar counsel-fzf-dir-function 'counsel-fzf-dir-function-projectile
+  "Function that returns a directory for fzf to use.")
+
+(defun counsel-fzf-dir-function-projectile ()
+  (if (and
+       (fboundp 'projectile-project-p)
+       (fboundp 'projectile-project-root)
+       (projectile-project-p))
+      (projectile-project-root)
+    default-directory))
+
+(defun counsel-fzf-function (str)
+  (let ((default-directory counsel--fzf-dir))
+    (counsel--async-command
+     (format counsel-fzf-cmd
+             (if (string-equal str "")
+                 "\"\""
+               (setq ivy--old-re (ivy--regex-fuzzy str))
+               str))))
+  nil)
+
+;;;###autoload
+(defun counsel-fzf (&optional initial-input initial-directory fzf-prompt)
+  "Open a file using the fzf shell command.
+INITIAL-INPUT can be given as the initial minibuffer input.
+INITIAL-DIRECTORY, if non-nil, is used as the root directory for search.
+FZF-PROMPT, if non-nil, is passed as `ivy-read' prompt argument."
+  (interactive
+   (let ((fzf-basename (car (split-string counsel-fzf-cmd))))
+     (list nil
+           (when current-prefix-arg
+             (read-directory-name (concat
+                                   fzf-basename
+                                   " in directory: "))))))
+
+  (let ((fzf-basename (car (split-string counsel-fzf-cmd))))
+    (counsel-require-program fzf-basename)
+    (setq counsel--fzf-dir
+          (or initial-directory
+              (funcall counsel-fzf-dir-function)))
+    (ivy-set-prompt 'counsel-fzf counsel-prompt-function)
+    (ivy-read (or fzf-prompt (concat fzf-basename ": "))
+              #'counsel-fzf-function
+              :initial-input initial-input
+              :re-builder #'ivy--regex-fuzzy
+              :dynamic-collection t
+              :action #'counsel-fzf-action
+              :unwind #'counsel-delete-process
+              :caller 'counsel-fzf)))
+
+(defun counsel-fzf-action (x)
+  "Find file X in current fzf directory."
+  (with-ivy-window
+    (let ((default-directory counsel--fzf-dir))
+      (find-file x))))
+
+(defun counsel-fzf-occur ()
+  "Occur function for `counsel-fzf' using `counsel-cmd-to-dired'."
+  (cd counsel--fzf-dir)
+  (counsel-cmd-to-dired
+   (counsel--expand-ls
+    (format
+     "%s --print0 | xargs -0 ls"
+     (format counsel-fzf-cmd ivy-text)))))
+
+(ivy-set-occur 'counsel-fzf 'counsel-fzf-occur)
+
+(ivy-set-actions
+ 'counsel-fzf
+ '(("x" counsel-locate-action-extern "xdg-open")
+   ("d" counsel-locate-action-dired "dired")))
+
+(counsel-set-async-exit-code 'counsel-fzf 1 "Nothing found")
+
+;;** `counsel-dpkg'
+;;;###autoload
+(defun counsel-dpkg ()
+  "Call the \"dpkg\" shell command."
+  (interactive)
+  (counsel-require-program "dpkg")
+  (let ((cands (mapcar
+                (lambda (x)
+                  (let ((y (split-string x "  +")))
+                    (cons (format "%-40s   %s"
+                                  (ivy--truncate-string
+                                   (nth 1 y) 40)
+                                  (nth 4 y))
+                          (mapconcat #'identity y " "))))
+                (split-string
+                 (shell-command-to-string "dpkg -l | tail -n+6") "\n" t))))
+    (ivy-read "dpkg: " cands
+              :action (lambda (x)
+                        (message (cdr x)))
+              :caller 'counsel-dpkg)))
+
+;;** `counsel-rpm'
+;;;###autoload
+(defun counsel-rpm ()
+  "Call the \"rpm\" shell command."
+  (interactive)
+  (counsel-require-program "rpm")
+  (let ((cands (mapcar
+                (lambda (x)
+                  (let ((y (split-string x "|")))
+                    (cons (format "%-40s   %s"
+                                  (ivy--truncate-string
+                                   (nth 0 y) 40)
+                                  (nth 1 y))
+                          (mapconcat #'identity y " "))))
+                (split-string
+                 (shell-command-to-string "rpm -qa --qf \"%{NAME}|%{SUMMARY}\\n\"") "\n" t))))
+    (ivy-read "rpm: " cands
+              :action (lambda (x)
+                        (message (cdr x)))
+              :caller 'counsel-rpm)))
+
+;;** `counsel-file-jump'
+;;;###autoload
+(defun counsel-file-jump (&optional initial-input initial-directory)
+  "Jump to a file below the current directory.
+List all files within the current directory or any of its subdirectories.
+INITIAL-INPUT can be given as the initial minibuffer input.
+INITIAL-DIRECTORY, if non-nil, is used as the root directory for search."
+  (interactive
+   (list nil
+         (when current-prefix-arg
+           (read-directory-name "From directory: "))))
+  (counsel-require-program "find")
+  (let* ((default-directory (or initial-directory default-directory)))
+    (ivy-read "Find file: "
+              (split-string
+               (shell-command-to-string
+                (concat find-program " * -type f -not -path '*\/.git*'"))
+               "\n" t)
+              :matcher #'counsel--find-file-matcher
+              :initial-input initial-input
+              :action (lambda (x)
+                        (with-ivy-window
+                          (find-file (expand-file-name x ivy--directory))))
+              :preselect (counsel--preselect-file)
+              :require-match 'confirm-after-completion
+              :history 'file-name-history
+              :keymap counsel-find-file-map
+              :caller 'counsel-file-jump)))
+
+;;** `counsel-dired-jump'
+;;;###autoload
+(defun counsel-dired-jump (&optional initial-input initial-directory)
+  "Jump to a directory (in dired) below the current directory.
+List all subdirectories within the current directory.
+INITIAL-INPUT can be given as the initial minibuffer input.
+INITIAL-DIRECTORY, if non-nil, is used as the root directory for search."
+  (interactive
+   (list nil
+         (when current-prefix-arg
+           (read-directory-name "From directory: "))))
+  (counsel-require-program "find")
+  (let* ((default-directory (or initial-directory default-directory)))
+    (ivy-read "Directory: "
+              (split-string
+               (shell-command-to-string
+                (concat find-program " * -type d -not -path '*\/.git*'"))
+               "\n" t)
+              :initial-input initial-input
+              :action (lambda (d) (dired-jump nil (expand-file-name d)))
+              :caller 'counsel-dired-jump)))
+
+;;* Grep
+(defun counsel--grep-mode-occur (git-grep-dir-is-file)
+  "Generate a custom occur buffer for grep like commands.
+If GIT-GREP-DIR-IS-FILE is t, then `ivy-state-directory' is treated as a full
+path to a file rather than a directory (e.g. for `counsel-grep-occur').
+
+This function expects that the candidates have already been filtered.
+It applies no filtering to ivy--all-candidates."
+  (unless (eq major-mode 'ivy-occur-grep-mode)
+    (ivy-occur-grep-mode))
+  (let* ((directory
+          (if git-grep-dir-is-file
+              (file-name-directory (ivy-state-directory ivy-last))
+            (ivy-state-directory ivy-last)))
+         (prepend
+          (if git-grep-dir-is-file
+              (concat (file-name-nondirectory
+                       (ivy-state-directory ivy-last)) ":")
+            "")))
+    (setq default-directory directory)
+    ;; Need precise number of header lines for `wgrep' to work.
+    (insert (format "-*- mode:grep; default-directory: %S -*-\n\n\n" default-directory))
+    (insert (format "%d candidates:\n" (length ivy--all-candidates)))
+    (ivy--occur-insert-lines
+     (mapcar (lambda (cand) (concat "./" prepend cand)) ivy--all-candidates))))
+
+;;** `counsel-ag'
+(defvar counsel-ag-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "C-l") 'ivy-call-and-recenter)
+    (define-key map (kbd "M-q") 'counsel-git-grep-query-replace)
+    map))
+
+(defcustom counsel-ag-base-command
+  (if (memq system-type '(ms-dos windows-nt))
+      "ag --vimgrep %s"
+    "ag --nocolor --nogroup %s")
+  "Format string to use in `counsel-ag-function' to construct the command.
+The %s will be replaced by optional extra ag arguments followed by the
+regex string."
+  :type 'string
+  :group 'ivy)
+
+(defvar counsel-ag-command nil)
+
+(counsel-set-async-exit-code 'counsel-ag 1 "No matches found")
+(ivy-set-occur 'counsel-ag 'counsel-ag-occur)
+(ivy-set-display-transformer 'counsel-ag 'counsel-git-grep-transformer)
+
+(defun counsel-ag-function (str)
+  "Grep in the current directory for STRING using BASE-CMD.
+If non-nil, append EXTRA-AG-ARGS to BASE-CMD."
+  (or
+   (counsel-more-chars)
+   (let ((default-directory (ivy-state-directory ivy-last))
+         (regex (counsel-unquote-regex-parens
+                 (setq ivy--old-re
+                       (ivy--regex str)))))
+     (counsel--async-command (format counsel-ag-command
+                                     (shell-quote-argument regex)))
+     nil)))
+
+;;;###autoload
+(defun counsel-ag (&optional initial-input initial-directory extra-ag-args ag-prompt)
+  "Grep for a string in the current directory using ag.
+INITIAL-INPUT can be given as the initial minibuffer input.
+INITIAL-DIRECTORY, if non-nil, is used as the root directory for search.
+EXTRA-AG-ARGS string, if non-nil, is appended to `counsel-ag-base-command'.
+AG-PROMPT, if non-nil, is passed as `ivy-read' prompt argument."
+  (interactive)
+  (setq counsel-ag-command counsel-ag-base-command)
+  (counsel-require-program (car (split-string counsel-ag-command)))
+  (when current-prefix-arg
+    (setq initial-directory
+          (or initial-directory
+              (read-directory-name (concat
+                                    (car (split-string counsel-ag-command))
+                                    " in directory: "))))
+    (setq extra-ag-args
+          (or extra-ag-args
+              (read-from-minibuffer (format
+                                     "%s args: "
+                                     (car (split-string counsel-ag-command)))))))
+  (when (null extra-ag-args)
+    (setq extra-ag-args ""))
+  (let* ((args-end (string-match "-- " extra-ag-args))
+         (file (if args-end
+                   (substring-no-properties extra-ag-args (match-end 0))
+                 ""))
+         (extra-ag-args (if args-end
+                            (substring-no-properties extra-ag-args 0 args-end)
+                          extra-ag-args)))
+    (setq counsel-ag-command (format counsel-ag-command
+                                     (concat extra-ag-args
+                                             " -- %s "
+                                             file))))
+  (ivy-set-prompt 'counsel-ag counsel-prompt-function)
+  (let ((default-directory (or initial-directory
+                               (locate-dominating-file default-directory ".git")
+                               default-directory)))
+    (ivy-read (or ag-prompt (car (split-string counsel-ag-command)))
+              #'counsel-ag-function
+              :initial-input initial-input
+              :dynamic-collection t
+              :keymap counsel-ag-map
+              :history 'counsel-git-grep-history
+              :action #'counsel-git-grep-action
+              :unwind (lambda ()
+                        (counsel-delete-process)
+                        (swiper--cleanup))
+              :caller 'counsel-ag)))
+(cl-pushnew 'counsel-ag ivy-highlight-grep-commands)
+
+(defun counsel-grep-like-occur (cmd-template)
+  (unless (eq major-mode 'ivy-occur-grep-mode)
+    (ivy-occur-grep-mode)
+    (setq default-directory (ivy-state-directory ivy-last)))
+  (setq ivy-text
+        (and (string-match "\"\\(.*\\)\"" (buffer-name))
+             (match-string 1 (buffer-name))))
+  (let* ((cmd (format cmd-template
+                      (shell-quote-argument
+                       (counsel-unquote-regex-parens
+                        (ivy--regex ivy-text)))))
+         (cands (split-string (shell-command-to-string cmd) "\n" t)))
+    ;; Need precise number of header lines for `wgrep' to work.
+    (insert (format "-*- mode:grep; default-directory: %S -*-\n\n\n"
+                    default-directory))
+    (insert (format "%d candidates:\n" (length cands)))
+    (ivy--occur-insert-lines
+     (mapcar
+      (lambda (cand) (concat "./" cand))
+      cands))))
+
+(defun counsel-ag-occur ()
+  "Generate a custom occur buffer for `counsel-ag'."
+  (counsel-grep-like-occur
+   counsel-ag-command))
+
+;;** `counsel-pt'
+(defcustom counsel-pt-base-command "pt --nocolor --nogroup -e %s"
+  "Alternative to `counsel-ag-base-command' using pt."
+  :type 'string
+  :group 'ivy)
+
+;;;###autoload
+(defun counsel-pt (&optional initial-input)
+  "Grep for a string in the current directory using pt.
+INITIAL-INPUT can be given as the initial minibuffer input.
+This uses `counsel-ag' with `counsel-pt-base-command' instead of
+`counsel-ag-base-command'."
+  (interactive)
+  (let ((counsel-ag-base-command counsel-pt-base-command))
+    (counsel-ag initial-input)))
+(cl-pushnew 'counsel-pt ivy-highlight-grep-commands)
+
+;;** `counsel-ack'
+(defcustom counsel-ack-base-command
+  (concat
+   (file-name-nondirectory
+    (or (executable-find "ack-grep") "ack"))
+   " --nocolor --nogroup %s")
+  "Alternative to `counsel-ag-base-command' using ack."
+  :type 'string
+  :group 'ivy)
+
+;;;###autoload
+(defun counsel-ack (&optional initial-input)
+  "Grep for a string in the current directory using ack.
+INITIAL-INPUT can be given as the initial minibuffer input.
+This uses `counsel-ag' with `counsel-ack-base-command' replacing
+`counsel-ag-base-command'."
+  (interactive)
+  (let ((counsel-ag-base-command counsel-ack-base-command))
+    (counsel-ag initial-input)))
+
+
+;;** `counsel-rg'
+(defcustom counsel-rg-base-command "rg -S --no-heading --line-number --color never %s ."
+  "Alternative to `counsel-ag-base-command' using ripgrep.
+
+Note: don't use single quotes for the regex."
+  :type 'string
+  :group 'ivy)
+
+(counsel-set-async-exit-code 'counsel-rg 1 "No matches found")
+(ivy-set-occur 'counsel-rg 'counsel-ag-occur)
+(ivy-set-display-transformer 'counsel-rg 'counsel-git-grep-transformer)
+
+;;;###autoload
+(defun counsel-rg (&optional initial-input initial-directory extra-rg-args rg-prompt)
+  "Grep for a string in the current directory using rg.
+INITIAL-INPUT can be given as the initial minibuffer input.
+INITIAL-DIRECTORY, if non-nil, is used as the root directory for search.
+EXTRA-RG-ARGS string, if non-nil, is appended to `counsel-rg-base-command'.
+RG-PROMPT, if non-nil, is passed as `ivy-read' prompt argument."
+  (interactive)
+  (let ((counsel-ag-base-command counsel-rg-base-command))
+    (counsel-ag initial-input initial-directory extra-rg-args rg-prompt)))
+(cl-pushnew 'counsel-rg ivy-highlight-grep-commands)
+
+;;** `counsel-grep'
+(defcustom counsel-grep-base-command "grep -E -n -e %s %s"
+  "Format string used by `counsel-grep' to build a shell command.
+It should contain two %-sequences (see function `format') to be
+substituted by the search regexp and file, respectively.  Neither
+%-sequence should be contained in single quotes."
+  :type 'string
+  :group 'ivy)
+
+(defvar counsel-grep-command nil)
+
+(defun counsel-grep-function (string)
+  "Grep in the current directory for STRING."
+  (or
+   (counsel-more-chars)
+   (let ((regex (counsel-unquote-regex-parens
+                 (setq ivy--old-re
+                       (ivy--regex string)))))
+     (counsel--async-command
+      (format counsel-grep-command (shell-quote-argument regex)))
+     nil)))
+
+(defun counsel-grep-action (x)
+  "Go to candidate X."
+  (with-ivy-window
+    (swiper--cleanup)
+    (let ((default-directory
+           (file-name-directory
+            (ivy-state-directory ivy-last)))
+          file-name line-number)
+      (when (cond ((string-match "\\`\\([0-9]+\\):\\(.*\\)\\'" x)
+                   (setq file-name (buffer-file-name (ivy-state-buffer ivy-last)))
+                   (setq line-number (match-string-no-properties 1 x)))
+                  ((string-match "\\`\\([^:]+\\):\\([0-9]+\\):\\(.*\\)\\'" x)
+                   (setq file-name (match-string-no-properties 1 x))
+                   (setq line-number (match-string-no-properties 2 x))))
+        ;; If the file buffer is already open, just get it. Prevent doing
+        ;; `find-file', as that file could have already been opened using
+        ;; `find-file-literally'.
+        (with-current-buffer (or (get-file-buffer file-name)
+                                 (find-file file-name))
+          (setq line-number (string-to-number line-number))
+          (if counsel-grep-last-line
+              (forward-line (- line-number counsel-grep-last-line))
+            (goto-char (point-min))
+            (forward-line (1- line-number)))
+          (setq counsel-grep-last-line line-number)
+          (re-search-forward (ivy--regex ivy-text t) (line-end-position) t)
+          (run-hooks 'counsel-grep-post-action-hook)
+          (if (eq ivy-exit 'done)
+              (swiper--ensure-visible)
+            (isearch-range-invisible (line-beginning-position)
+                                     (line-end-position))
+            (swiper--add-overlays (ivy--regex ivy-text))))))))
+
+(defun counsel-grep-occur ()
+  "Generate a custom occur buffer for `counsel-grep'."
+  (counsel-grep-like-occur
+   (format
+    "grep -niE %%s %s /dev/null"
+    (shell-quote-argument
+     (file-name-nondirectory
+      (buffer-file-name
+       (ivy-state-buffer ivy-last)))))))
+
+(ivy-set-occur 'counsel-grep 'counsel-grep-occur)
+(counsel-set-async-exit-code 'counsel-grep 1 "")
+
+;;;###autoload
+(defun counsel-grep (&optional initial-input)
+  "Grep for a string in the file visited by the current buffer.
+When non-nil, INITIAL-INPUT is the initial search pattern."
+  (interactive)
+  (unless buffer-file-name
+    (user-error "Current buffer is not visiting a file"))
+  (counsel-require-program (car (split-string counsel-grep-base-command)))
+  (setq counsel-grep-last-line nil)
+  (setq counsel-grep-command
+        (format counsel-grep-base-command
+                "%s" (shell-quote-argument buffer-file-name)))
+  (let ((init-point (point))
+        res)
+    (unwind-protect
+         (setq res (ivy-read "grep: " 'counsel-grep-function
+                             :initial-input initial-input
+                             :dynamic-collection t
+                             :preselect
+                             (when (< (- (line-end-position) (line-beginning-position)) 300)
+                               (format "%d:%s"
+                                       (line-number-at-pos)
+                                       (regexp-quote
+                                        (buffer-substring-no-properties
+                                         (line-beginning-position)
+                                         (line-end-position)))))
+
+                             :history 'counsel-git-grep-history
+                             :update-fn (lambda ()
+                                          (counsel-grep-action (ivy-state-current ivy-last)))
+                             :re-builder #'ivy--regex
+                             :action #'counsel-grep-action
+                             :unwind (lambda ()
+                                       (counsel-delete-process)
+                                       (swiper--cleanup))
+                             :caller 'counsel-grep))
+      (unless res
+        (goto-char init-point)))))
+
+;;** `counsel-grep-or-swiper'
+(defcustom counsel-grep-swiper-limit 300000
+  "Buffer size threshold for `counsel-grep-or-swiper'.
+When the number of characters in a buffer exceeds this threshold,
+`counsel-grep' will be used instead of `swiper'."
+  :type 'integer
+  :group 'ivy)
+
+;;;###autoload
+(defun counsel-grep-or-swiper (&optional initial-input)
+  "Call `swiper' for small buffers and `counsel-grep' for large ones.
+When non-nil, INITIAL-INPUT is the initial search pattern."
+  (interactive)
+  (if (or (not buffer-file-name)
+          (buffer-narrowed-p)
+          (ignore-errors
+            (file-remote-p buffer-file-name))
+          (jka-compr-get-compression-info buffer-file-name)
+          (<= (buffer-size)
+              (/ counsel-grep-swiper-limit
+                 (if (eq major-mode 'org-mode) 4 1))))
+      (swiper initial-input)
+    (when (file-writable-p buffer-file-name)
+      (save-buffer))
+    (counsel-grep initial-input)))
+
+;;** `counsel-recoll'
+(defun counsel-recoll-function (str)
+  "Run recoll for STR."
+  (or
+   (counsel-more-chars)
+   (progn
+     (counsel--async-command
+      (format "recoll -t -b %s"
+              (shell-quote-argument str)))
+     nil)))
+
+;; This command uses the recollq command line tool that comes together
+;; with the recoll (the document indexing database) source:
+;;     http://www.lesbonscomptes.com/recoll/download.html
+;; You need to build it yourself (together with recoll):
+;;     cd ./query && make && sudo cp recollq /usr/local/bin
+;; You can try the GUI version of recoll with:
+;;     sudo apt-get install recoll
+;; Unfortunately, that does not install recollq.
+(defun counsel-recoll (&optional initial-input)
+  "Search for a string in the recoll database.
+You'll be given a list of files that match.
+Selecting a file will launch `swiper' for that file.
+INITIAL-INPUT can be given as the initial minibuffer input."
+  (interactive)
+  (counsel-require-program "recoll")
+  (ivy-read "recoll: " 'counsel-recoll-function
+            :initial-input initial-input
+            :dynamic-collection t
+            :history 'counsel-git-grep-history
+            :action (lambda (x)
+                      (when (string-match "file://\\(.*\\)\\'" x)
+                        (let ((file-name (match-string 1 x)))
+                          (find-file file-name)
+                          (unless (string-match "pdf$" x)
+                            (swiper ivy-text)))))
+            :unwind #'counsel-delete-process
+            :caller 'counsel-recoll))
+
+;;* Org
+;;** `counsel-org-tag'
+(defvar counsel-org-tags nil
+  "Store the current list of tags.")
+
+(defvar org-outline-regexp)
+(defvar org-indent-mode)
+(defvar org-indent-indentation-per-level)
+(defvar org-tags-column)
+(declare-function org-get-tags-string "org")
+(declare-function org-move-to-column "org-compat")
+
+(defun counsel-org-change-tags (tags)
+  "Change tags of current org headline to TAGS."
+  (let ((current (org-get-tags-string))
+        (col (current-column))
+        level)
+    ;; Insert new tags at the correct column
+    (beginning-of-line 1)
+    (setq level (or (and (looking-at org-outline-regexp)
+                         (- (match-end 0) (point) 1))
+                    1))
+    (cond
+      ((and (equal current "") (equal tags "")))
+      ((re-search-forward
+        (concat "\\([ \t]*" (regexp-quote current) "\\)[ \t]*$")
+        (line-end-position) t)
+       (if (equal tags "")
+           (delete-region
+            (match-beginning 0)
+            (match-end 0))
+         (goto-char (match-beginning 0))
+         (let* ((c0 (current-column))
+                ;; compute offset for the case of org-indent-mode active
+                (di (if (bound-and-true-p org-indent-mode)
+                        (* (1- org-indent-indentation-per-level) (1- level))
+                      0))
+                (p0 (if (equal (char-before) ?*) (1+ (point)) (point)))
+                (tc (+ org-tags-column (if (> org-tags-column 0) (- di) di)))
+                (c1 (max (1+ c0) (if (> tc 0) tc (- (- tc) (string-width tags)))))
+                (rpl (concat (make-string (max 0 (- c1 c0)) ?\ ) tags)))
+           (replace-match rpl t t)
+           (and c0 indent-tabs-mode (tabify p0 (point)))
+           tags)))
+      (t (error "Tags alignment failed")))
+    (org-move-to-column col)))
+
+(defun counsel-org--set-tags ()
+  "Set tags of current org headline to `counsel-org-tags'."
+  (counsel-org-change-tags
+   (if counsel-org-tags
+       (format ":%s:"
+               (mapconcat #'identity counsel-org-tags ":"))
+     "")))
+
+(defvar org-agenda-bulk-marked-entries)
+
+(declare-function org-get-at-bol "org")
+(declare-function org-agenda-error "org-agenda")
+
+(defun counsel-org-tag-action (x)
+  "Add tag X to `counsel-org-tags'.
+If X is already part of the list, remove it instead.  Quit the selection if
+X is selected by either `ivy-done', `ivy-alt-done' or `ivy-immediate-done',
+otherwise continue prompting for tags."
+  (if (member x counsel-org-tags)
+      (progn
+        (setq counsel-org-tags (delete x counsel-org-tags)))
+    (unless (equal x "")
+      (setq counsel-org-tags (append counsel-org-tags (list x)))
+      (unless (member x ivy--all-candidates)
+        (setq ivy--all-candidates (append ivy--all-candidates (list x))))))
+  (let ((prompt (counsel-org-tag-prompt)))
+    (setf (ivy-state-prompt ivy-last) prompt)
+    (setq ivy--prompt (concat "%-4d " prompt)))
+  (cond ((memq this-command '(ivy-done
+                              ivy-alt-done
+                              ivy-immediate-done))
+         (if (eq major-mode 'org-agenda-mode)
+             (if (null org-agenda-bulk-marked-entries)
+                 (let ((hdmarker (or (org-get-at-bol 'org-hd-marker)
+                                     (org-agenda-error))))
+                   (with-current-buffer (marker-buffer hdmarker)
+                     (goto-char hdmarker)
+                     (counsel-org--set-tags)))
+               (let ((add-tags (copy-sequence counsel-org-tags)))
+                 (dolist (m org-agenda-bulk-marked-entries)
+                   (with-current-buffer (marker-buffer m)
+                     (save-excursion
+                       (goto-char m)
+                       (setq counsel-org-tags
+                             (delete-dups
+                              (append (split-string (org-get-tags-string) ":" t)
+                                      add-tags)))
+                       (counsel-org--set-tags))))))
+           (counsel-org--set-tags)))
+        ((eq this-command 'ivy-call)
+         (with-selected-window (active-minibuffer-window)
+           (delete-minibuffer-contents)))))
+
+(defun counsel-org-tag-prompt ()
+  "Return prompt for `counsel-org-tag'."
+  (format "Tags (%s): "
+          (mapconcat #'identity counsel-org-tags ", ")))
+
+(defvar org-setting-tags)
+(defvar org-last-tags-completion-table)
+(defvar org-tag-persistent-alist)
+(defvar org-tag-alist)
+(defvar org-complete-tags-always-offer-all-agenda-tags)
+
+(declare-function org-at-heading-p "org")
+(declare-function org-back-to-heading "org")
+(declare-function org-get-buffer-tags "org")
+(declare-function org-global-tags-completion-table "org")
+(declare-function org-agenda-files "org")
+(declare-function org-agenda-set-tags "org-agenda")
+(declare-function org-tags-completion-function "org")
+
+;;;###autoload
+(defun counsel-org-tag ()
+  "Add or remove tags in `org-mode'."
+  (interactive)
+  (save-excursion
+    (if (eq major-mode 'org-agenda-mode)
+        (if org-agenda-bulk-marked-entries
+            (setq counsel-org-tags nil)
+          (let ((hdmarker (or (org-get-at-bol 'org-hd-marker)
+                              (org-agenda-error))))
+            (with-current-buffer (marker-buffer hdmarker)
+              (goto-char hdmarker)
+              (setq counsel-org-tags
+                    (split-string (org-get-tags-string) ":" t)))))
+      (unless (org-at-heading-p)
+        (org-back-to-heading t))
+      (setq counsel-org-tags (split-string (org-get-tags-string) ":" t)))
+    (let ((org-last-tags-completion-table
+           (append (and (or org-complete-tags-always-offer-all-agenda-tags
+                            (eq major-mode 'org-agenda-mode))
+                        (org-global-tags-completion-table
+                         (org-agenda-files)))
+                   (unless (boundp 'org-current-tag-alist)
+                     org-tag-persistent-alist)
+                   (or (if (boundp 'org-current-tag-alist)
+                           org-current-tag-alist
+                         org-tag-alist)
+                       (org-get-buffer-tags)))))
+      (ivy-read (counsel-org-tag-prompt)
+                (lambda (str _pred _action)
+                  (delete-dups
+                   (all-completions str #'org-tags-completion-function)))
+                :history 'org-tags-history
+                :action #'counsel-org-tag-action
+                :caller 'counsel-org-tag))))
+
+;;;###autoload
+(defun counsel-org-tag-agenda ()
+  "Set tags for the current agenda item."
+  (interactive)
+  (let ((store (symbol-function 'org-set-tags)))
+    (unwind-protect
+         (progn
+           (fset 'org-set-tags
+                 (symbol-function 'counsel-org-tag))
+           (org-agenda-set-tags nil nil))
+      (fset 'org-set-tags store))))
+
+(define-obsolete-variable-alias 'counsel-org-goto-display-style
+    'counsel-org-headline-display-style "0.10.0")
+
+(defcustom counsel-org-headline-display-style 'path
+  "The style used when displaying matched `org-mode'-headlines.
+
+If headline, the title and the leading stars are displayed.
+
+If path, the path hierarchy is displayed.  For each entry the title is shown.
+`counsel-org-headline-path-separator' is used as separator between entries.
+
+If title or any other value, only the title of the headline is displayed.
+
+Use `counsel-org-headline-display-tags' and
+`counsel-org-headline-display-todo' to display tags and todo
+keywords, respectively."
+  :type '(choice
+          (const :tag "Title only" title)
+          (const :tag "Headline" headline)
+          (const :tag "Path" path))
+  :group 'ivy)
+
+(define-obsolete-variable-alias 'counsel-org-goto-separator
+    'counsel-org-headline-path-separator "0.10.0")
+
+(defcustom counsel-org-headline-path-separator "/"
+  "Character(s) to separate path entries in matched `org-mode'-headlines.
+
+This variable has no effect unless `counsel-org-headline-display-style' is
+set to path."
+  :type 'string
+  :group 'ivy)
+
+(define-obsolete-variable-alias 'counsel-org-goto-display-tags
+    'counsel-org-headline-display-tags "0.10.0")
+
+(defcustom counsel-org-headline-display-tags nil
+  "If non-nil, display tags in matched `org-mode' headlines."
+  :type 'boolean
+  :group 'ivy)
+
+(define-obsolete-variable-alias 'counsel-org-goto-display-todo
+    'counsel-org-headline-display-todo "0.10.0")
+
+(defcustom counsel-org-headline-display-todo nil
+  "If non-nil, display todo keywords in matched `org-mode' headlines."
+  :type 'boolean
+  :group 'ivy)
+
+(defcustom counsel-org-headline-display-priority nil
+  "If non-nil, display priorities in matched `org-mode' headlines."
+  :type 'boolean
+  :group 'ivy)
+
+(defcustom counsel-org-goto-face-style nil
+  "The face used for displaying headlines in `counsel-org-goto' functions.
+
+If org, the default faces from `org-mode' are applied, i.e. org-level-1
+through org-level-8.  Note that no cycling is in effect, therefore headlines
+on levels 9 and higher will not be styled.
+
+If verbatim, the face used in the buffer is applied.  For simple headlines
+this is usually the same as org except that it depends on how much of the
+buffer has been completely loaded.  If your buffer exceeds a certain size,
+headlines are styled lazily depending on which parts of the tree are visible.
+Headlines which are not styled yet in the buffer will appear unstyled in the
+minibuffer as well.  If your headlines contain parts which are fontified
+differently than the headline itself (eg. todo keywords, tags, links) and you
+want these parts to be styled properly, verbatim is the way to go, otherwise
+you are probably better off using org instead.
+
+If custom, the faces defined in `counsel-org-goto-custom-faces' are applied.
+Note that no cycling is in effect, therefore if there is no face defined
+for a certain level, headlines on that level will not be styled.
+
+If nil or any other value, no face is applied to the headline.
+
+See `counsel-org-headline-display-tags' and
+`counsel-org-headline-display-todo' if you want to display tags and todo
+keywords in your headlines."
+  :type '(choice
+          (const :tag "Same as org-mode" org)
+          (const :tag "Verbatim" verbatim)
+          (const :tag "Custom" custom))
+  :group 'ivy)
+
+(defcustom counsel-org-goto-custom-faces nil
+  "Custom faces for displaying headlines in `counsel-org-goto' functions.
+
+The n-th entry is used for headlines on level n, starting with n = 1.  If
+a headline is an a level for which there is no entry in the list, it will
+not be styled.
+
+This variable has no effect unless `counsel-org-goto-face-style' is set
+to custom."
+  :type '(repeat face)
+  :group 'ivy)
+
+(declare-function org-get-heading "org")
+(declare-function org-goto-marker-or-bmk "org")
+(declare-function outline-next-heading "outline")
+
+;;;###autoload
+(defun counsel-org-goto ()
+  "Go to a different location in the current file."
+  (interactive)
+  (ivy-read "Goto: " (counsel-org-goto--get-headlines)
+            :history 'counsel-org-goto-history
+            :action 'counsel-org-goto-action
+            :caller 'counsel-org-goto))
+
+;;;###autoload
+(defun counsel-org-goto-all ()
+  "Go to a different location in any org file."
+  (interactive)
+  (let (entries)
+    (dolist (b (buffer-list))
+      (with-current-buffer b
+        (when (derived-mode-p 'org-mode)
+          (setq entries (nconc entries (counsel-org-goto--get-headlines))))))
+    (ivy-read "Goto: " entries
+              :history 'counsel-org-goto-history
+              :action 'counsel-org-goto-action
+              :caller 'counsel-org-goto-all)))
+
+(defun counsel-org-goto-action (x)
+  "Go to headline in candidate X."
+  (org-goto-marker-or-bmk (cdr x)))
+
+(defvar org-version)
+
+(defun counsel--org-get-heading-args ()
+  "Return list of arguments for `org-get-heading'.
+Try to return the right number of arguments for the current Org
+version.  Argument values are based on the
+`counsel-org-headline-display-*' user options."
+  (nbutlast (mapcar #'not (list counsel-org-headline-display-tags
+                                counsel-org-headline-display-todo
+                                counsel-org-headline-display-priority))
+            (if (if (fboundp 'func-arity)
+                    (< (cdr (func-arity #'org-get-heading)) 3)
+                  (version< org-version "9.1.1"))
+                1 0)))
+
+(defun counsel-org-goto--get-headlines ()
+  "Get all headlines from the current org buffer."
+  (save-excursion
+    (let (entries
+          start-pos
+          stack
+          (stack-level 0)
+          (heading-args (counsel--org-get-heading-args)))
+      (goto-char (point-min))
+      (setq start-pos (or (and (org-at-heading-p)
+                               (point))
+                          (outline-next-heading)))
+      (while start-pos
+        (let ((name (or (apply #'org-get-heading heading-args) ""))
+              level)
+          (search-forward " ")
+          (setq level
+                (- (length (buffer-substring-no-properties start-pos (point)))
+                   1))
+          (cond ((eq counsel-org-headline-display-style 'path)
+                 ;; Update stack. The empty entry guards against incorrect
+                 ;; headline hierarchies e.g. a level 3 headline immediately
+                 ;; following a level 1 entry.
+                 (while (<= level stack-level)
+                   (pop stack)
+                   (cl-decf stack-level))
+                 (while (> level stack-level)
+                   (push "" stack)
+                   (cl-incf stack-level))
+                 (setf (car stack) (counsel-org-goto--add-face name level))
+                 (setq name (mapconcat
+                             #'identity
+                             (reverse stack)
+                             counsel-org-headline-path-separator)))
+                (t
+                 (when (eq counsel-org-headline-display-style 'headline)
+                   (setq name (concat (make-string level ?*) " " name)))
+                 (setq name (counsel-org-goto--add-face name level))))
+          (push (cons name (point-marker)) entries))
+        (setq start-pos (outline-next-heading)))
+      (nreverse entries))))
+
+(defun counsel-org-goto--add-face (name level)
+  "Add face to headline NAME on LEVEL.
+The face can be customized through `counsel-org-goto-face-style'."
+  (or (and (eq counsel-org-goto-face-style 'org)
+           (propertize
+            name
+            'face
+            (concat "org-level-" (number-to-string level))))
+      (and (eq counsel-org-goto-face-style 'verbatim)
+           name)
+      (and (eq counsel-org-goto-face-style 'custom)
+           (propertize
+            name
+            'face
+            (nth (1- level) counsel-org-goto-custom-faces)))
+      (propertize name 'face 'minibuffer-prompt)))
+
+;;** `counsel-org-file'
+(declare-function org-attach-dir "org-attach")
+(declare-function org-attach-file-list "org-attach")
+(defvar org-attach-directory)
+
+(defun counsel-org-files ()
+  "Return list of all files under current Org attachment directories.
+Filenames returned are relative to `default-directory'.  For each
+attachment directory associated with the current buffer, all
+contained files are listed, so the return value could conceivably
+include attachments of other Org buffers."
+  (require 'org-attach)
+  (let* ((ids (let (res)
+                (save-excursion
+                  (goto-char (point-min))
+                  (while (re-search-forward "^:ID:[\t ]+\\(.*\\)$" nil t)
+                    (push (match-string-no-properties 1) res))
+                  (nreverse res))))
+         (files
+          (cl-remove-if-not
+           #'file-exists-p
+           (mapcar (lambda (id)
+                     (expand-file-name
+                      (concat (substring id 0 2) "/" (substring id 2))
+                      org-attach-directory))
+                   ids))))
+    (cl-mapcan
+     (lambda (dir)
+       (mapcar (lambda (file)
+                 (file-relative-name (expand-file-name file dir)))
+               (org-attach-file-list dir)))
+     files)))
+
+;;;###autoload
+(defun counsel-org-file ()
+  "Browse all attachments for current Org file."
+  (interactive)
+  (ivy-read "file: " (counsel-org-files)
+            :action 'counsel-locate-action-dired
+            :caller 'counsel-org-file))
+
+;;** `counsel-org-entity'
+(defvar org-entities)
+(defvar org-entities-user)
+
+;;;###autoload
+(defun counsel-org-entity ()
+  "Complete Org entities using Ivy."
+  (interactive)
+  (require 'org)
+  (ivy-read "Entity: " (cl-loop for element in (append org-entities org-entities-user)
+                          unless (stringp element)
+                          collect (cons
+                                   (format "%20s | %20s | %20s | %s"
+                                           (cl-first element)    ; name
+                                           (cl-second element)   ; latex
+                                           (cl-fourth element)   ; html
+                                           (cl-seventh element)) ; utf-8
+                                   element))
+            :require-match t
+            :action '(1
+                      ("u" (lambda (candidate)
+                             (insert (cl-seventh (cdr candidate)))) "utf-8")
+                      ("o" (lambda (candidate)
+                             (insert "\\" (cl-first (cdr candidate)))) "org-entity")
+                      ("l" (lambda (candidate)
+                             (insert (cl-second (cdr candidate)))) "latex")
+                      ("h" (lambda (candidate)
+                             (insert (cl-fourth (cdr candidate)))) "html")
+                      ("a" (lambda (candidate)
+                             (insert (cl-fifth (cdr candidate)))) "ascii")
+                      ("L" (lambda (candidate)
+                             (insert (cl-sixth (cdr candidate))) "Latin-1")))))
+
+;;** `counsel-org-capture'
+(defvar org-capture-templates)
+(defvar org-capture-templates-contexts)
+(declare-function org-contextualize-keys "org")
+(declare-function org-capture-goto-last-stored "org-capture")
+(declare-function org-capture-goto-target "org-capture")
+(declare-function org-capture-upgrade-templates "org-capture")
+
+;;;###autoload
+(defun counsel-org-capture ()
+  "Capture something."
+  (interactive)
+  (require 'org-capture)
+  (ivy-read "Capture template: "
+            (delq nil
+                  (mapcar
+                   (lambda (x)
+                     (when (> (length x) 2)
+                       (format "%-5s %s" (nth 0 x) (nth 1 x))))
+                   ;; We build the list of capture templates as in
+                   ;; `org-capture-select-template':
+                   (or (org-contextualize-keys
+                        (org-capture-upgrade-templates org-capture-templates)
+                        org-capture-templates-contexts)
+                       '(("t" "Task" entry (file+headline "" "Tasks")
+                          "* TODO %?\n  %u\n  %a")))))
+            :require-match t
+            :action (lambda (x)
+                      (org-capture nil (car (split-string x))))
+            :caller 'counsel-org-capture))
+
+(ivy-set-actions
+ 'counsel-org-capture
+ `(("t" ,(lambda (x)
+           (org-capture-goto-target (car (split-string x))))
+        "go to target")
+   ("l" ,(lambda (_x)
+           (org-capture-goto-last-stored))
+        "go to last stored")
+   ("p" ,(lambda (x)
+           (org-capture 0 (car (split-string x))))
+        "insert template at point")
+   ("c" ,(lambda (_x)
+           (customize-variable 'org-capture-templates))
+        "customize org-capture-templates")))
+
+;;** `counsel-org-agenda-headlines'
+(defvar org-odd-levels-only)
+(declare-function org-set-startup-visibility "org")
+(declare-function org-show-entry "org")
+(declare-function org-map-entries "org")
+(declare-function org-heading-components "org")
+
+(defun counsel-org-agenda-headlines-action-goto (headline)
+  "Go to the `org-mode' agenda HEADLINE."
+  (find-file (nth 1 headline))
+  (org-set-startup-visibility)
+  (goto-char (nth 2 headline))
+  (org-show-entry))
+
+(ivy-set-actions
+ 'counsel-org-agenda-headlines
+ '(("g" counsel-org-agenda-headlines-action-goto "goto headline")))
+
+(defvar counsel-org-agenda-headlines-history nil
+  "History for `counsel-org-agenda-headlines'.")
+
+(declare-function org-get-outline-path "org")
+
+(defun counsel-org-agenda-headlines--candidates ()
+  "Return a list of completion candidates for `counsel-org-agenda-headlines'."
+  (org-map-entries
+   (lambda ()
+     (let* ((components (org-heading-components))
+            (level (and (eq counsel-org-headline-display-style 'headline)
+                        (make-string
+                         (if org-odd-levels-only
+                             (nth 1 components)
+                           (nth 0 components))
+                         ?*)))
+            (todo (and counsel-org-headline-display-todo
+                       (nth 2 components)))
+            (path (and (eq counsel-org-headline-display-style 'path)
+                       (org-get-outline-path)))
+            (priority (and counsel-org-headline-display-priority
+                           (nth 3 components)))
+            (text (nth 4 components))
+            (tags (and counsel-org-headline-display-tags
+                       (nth 5 components))))
+       (list
+        (mapconcat
+         'identity
+         (cl-remove-if 'null
+                       (list
+                        level
+                        todo
+                        (and priority (format "[#%c]" priority))
+                        (mapconcat 'identity
+                                   (append path (list text))
+                                   counsel-org-headline-path-separator)
+                        tags))
+         " ")
+        (buffer-file-name) (point))))
+   nil
+   'agenda))
+
+;;;###autoload
+(defun counsel-org-agenda-headlines ()
+  "Choose from headers of `org-mode' files in the agenda."
+  (interactive)
+  (require 'org)
+  (let ((minibuffer-allow-text-properties t))
+    (ivy-read "Org headline: "
+              (counsel-org-agenda-headlines--candidates)
+              :action #'counsel-org-agenda-headlines-action-goto
+              :history 'counsel-org-agenda-headlines-history
+              :caller 'counsel-org-agenda-headlines)))
+
+;;* Misc. Emacs
+;;** `counsel-mark-ring'
+(defun counsel-mark-ring ()
+  "Browse `mark-ring' interactively.
+Obeys `widen-automatically', which see."
+  (interactive)
+  (let ((cands
+         (save-excursion
+           (save-restriction
+             ;; Widen, both to save `line-number-at-pos' the trouble
+             ;; and for `buffer-substring' to work.
+             (widen)
+             (let ((fmt (format "%%%dd %%s"
+                                (length (number-to-string
+                                         (line-number-at-pos (point-max)))))))
+               (mapcar (lambda (mark)
+                         (goto-char (marker-position mark))
+                         (let ((linum (line-number-at-pos))
+                               (line  (buffer-substring
+                                       (line-beginning-position)
+                                       (line-end-position))))
+                           (cons (format fmt linum line) (point))))
+                       (sort (delete-dups (copy-sequence mark-ring)) #'<)))))))
+    (if cands
+        (ivy-read "Mark: " cands
+                  :require-match t
+                  :action (lambda (cand)
+                            (let ((pos (cdr-safe cand)))
+                              (when pos
+                                (unless (<= (point-min) pos (point-max))
+                                  (if widen-automatically
+                                      (widen)
+                                    (error "\
+Position of selected mark outside accessible part of buffer")))
+                                (goto-char pos))))
+                  :caller 'counsel-mark-ring)
+      (message "Mark ring is empty"))))
+
+;;** `counsel-package'
+(defvar package--initialized)
+(defvar package-alist)
+(defvar package-archive-contents)
+(declare-function package-installed-p "package")
+(declare-function package-delete "package")
+
+(defun counsel-package ()
+  "Install or delete packages.
+
+Packages not currently installed have a \"+\" prepended.  Selecting one
+of these will try to install it.  Currently installed packages have a
+\"-\" prepended, and selecting one of these will delete the package.
+
+Additional Actions:
+
+  \\<ivy-minibuffer-map>\\[ivy-dispatching-done] d: describe package"
+  (interactive)
+  (unless package--initialized
+    (package-initialize t))
+  (unless package-archive-contents
+    (package-refresh-contents))
+  (let ((cands (mapcar #'counsel-package-make-package-cell
+                       package-archive-contents)))
+    (ivy-read "Packages (install +pkg or delete -pkg): "
+              (sort cands #'counsel--package-sort)
+              :action #'counsel-package-action
+              :initial-input "^+ "
+              :require-match t
+              :caller 'counsel-package)))
+
+(defun counsel-package-make-package-cell (pkg)
+  "Make candidate for package PKG."
+  (let* ((pkg-sym (car pkg))
+         (pkg-name (symbol-name pkg-sym)))
+    (cons (format "%s%s"
+                  (if (package-installed-p pkg-sym) "-" "+")
+                  pkg-name)
+          pkg)))
+
+(defun counsel-package-action (pkg-cons)
+  "Delete or install package in PKG-CONS."
+  (let ((pkg (cadr pkg-cons)))
+    (if (package-installed-p pkg)
+        (package-delete
+         (cadr (assoc pkg package-alist)))
+      (package-install pkg))))
+
+(defun counsel-package-action-describe (pkg-cons)
+  "Call `describe-package' for package in PKG-CONS."
+  (describe-package (cadr pkg-cons)))
+
+(declare-function package-desc-extras "package")
+
+(defun counsel-package-action-homepage (pkg-cons)
+  "Open homepage for package in PKG-CONS."
+  (let* ((desc-list (cddr pkg-cons))
+         (desc (if (listp desc-list) (car desc-list) desc-list))
+         (url (cdr (assoc :url (package-desc-extras desc)))))
+    (when url
+      (require 'browse-url)
+      (browse-url url))))
+
+(defun counsel--package-sort (a b)
+  "Sort function for `counsel-package'.
+A is the left hand side, B the right hand side."
+  (let* ((a (car a))
+         (b (car b))
+         (a-inst (= (string-to-char a) ?+))
+         (b-inst (= (string-to-char b) ?+)))
+    (or (and a-inst (not b-inst))
+        (and (eq a-inst b-inst) (string-lessp a b)))))
+
+(ivy-set-actions
+ 'counsel-package
+ '(("d" counsel-package-action-describe "describe package")
+   ("h" counsel-package-action-homepage "open package homepage")))
+
+;;** `counsel-tmm'
+(defvar tmm-km-list nil)
+(declare-function tmm-get-keymap "tmm")
+(declare-function tmm--completion-table "tmm")
+(declare-function tmm-get-keybind "tmm")
+
+(defun counsel-tmm-prompt (menu)
+  "Select and call an item from the MENU keymap."
+  (let (out
+        choice
+        chosen-string)
+    (setq tmm-km-list nil)
+    (map-keymap (lambda (k v) (tmm-get-keymap (cons k v))) menu)
+    (setq tmm-km-list (nreverse tmm-km-list))
+    (setq out (ivy-read "Menu bar: " (tmm--completion-table tmm-km-list)
+                        :require-match t
+                        :sort nil))
+    (setq choice (cdr (assoc out tmm-km-list)))
+    (setq chosen-string (car choice))
+    (setq choice (cdr choice))
+    (cond ((keymapp choice)
+           (counsel-tmm-prompt choice))
+          ((and choice chosen-string)
+           (setq last-command-event chosen-string)
+           (call-interactively choice)))))
+
+(defvar tmm-table-undef)
+
+;;;###autoload
+(defun counsel-tmm ()
+  "Text-mode emulation of looking and choosing from a menubar."
+  (interactive)
+  (require 'tmm)
+  (run-hooks 'menu-bar-update-hook)
+  (setq tmm-table-undef nil)
+  (counsel-tmm-prompt (tmm-get-keybind [menu-bar])))
+
+;;** `counsel-yank-pop'
+(defcustom counsel-yank-pop-truncate-radius 2
+  "Number of context lines around `counsel-yank-pop' candidates."
+  :type 'integer
+  :group 'ivy)
+
+(defun counsel--yank-pop-truncate (str)
+  "Truncate STR for use in `counsel-yank-pop'."
+  (condition-case nil
+      (let* ((lines (split-string str "\n" t))
+             (n (length lines))
+             (re (ivy-re-to-str ivy--old-re))
+             (first-match (cl-position-if
+                           (lambda (s) (string-match re s))
+                           lines))
+             (beg (max 0 (- first-match
+                            counsel-yank-pop-truncate-radius)))
+             (end (min n (+ first-match
+                            counsel-yank-pop-truncate-radius
+                            1)))
+             (seq (cl-subseq lines beg end)))
+        (if (null first-match)
+            (error "Could not match %s" str)
+          (when (> beg 0)
+            (setcar seq (concat "[...] " (car seq))))
+          (when (< end n)
+            (setcar (last seq)
+                    (concat (car (last seq)) " [...]")))
+          (mapconcat #'identity seq "\n")))
+    (error str)))
+
+(defcustom counsel-yank-pop-separator "\n"
+  "Separator for the kill ring strings in `counsel-yank-pop'."
+  :group 'ivy
+  :type 'string)
+
+(make-obsolete-variable
+ 'counsel-yank-pop-height
+ 'ivy-height-alist
+ "<2018-04-14 Fri>") ;; TODO: Add version tag
+
+(defcustom counsel-yank-pop-height 5
+  "The `ivy-height' of `counsel-yank-pop'."
+  :group 'ivy
+  :type 'integer)
+
+(defun counsel--yank-pop-format-function (cand-pairs)
+  "Transform CAND-PAIRS into a string for `counsel-yank-pop'."
+  (ivy--format-function-generic
+   (lambda (str)
+     (mapconcat
+      (lambda (s)
+        (ivy--add-face s 'ivy-current-match))
+      (split-string
+       (counsel--yank-pop-truncate str) "\n" t)
+      "\n"))
+   (lambda (str)
+     (counsel--yank-pop-truncate str))
+   cand-pairs
+   counsel-yank-pop-separator))
+
+(defun counsel--yank-pop-position (s)
+  "Return position of S in `kill-ring' relative to last yank."
+  (or (cl-position s kill-ring-yank-pointer :test #'equal-including-properties)
+      (cl-position s kill-ring-yank-pointer :test #'equal)
+      (+ (or (cl-position s kill-ring :test #'equal-including-properties)
+             (cl-position s kill-ring :test #'equal))
+         (- (length kill-ring-yank-pointer)
+            (length kill-ring)))))
+
+(defun counsel-string-non-blank-p (s)
+  "Return non-nil if S includes non-blank characters.
+Newlines and carriage returns are considered blank."
+  (not (string-match-p "\\`[\n\r[:blank:]]*\\'" s)))
+
+(defcustom counsel-yank-pop-filter #'counsel-string-non-blank-p
+  "Unary filter function applied to `counsel-yank-pop' candidates.
+All elements of `kill-ring' for which this function returns nil
+will be destructively removed from `kill-ring' before completion.
+All blank strings are deleted from `kill-ring' by default."
+  :group 'ivy
+  :type '(radio
+          (function-item counsel-string-non-blank-p)
+          (function-item identity)
+          (function :tag "Other")))
+
+(defun counsel--yank-pop-kills ()
+  "Return filtered `kill-ring' for `counsel-yank-pop' completion.
+Both `kill-ring' and `kill-ring-yank-pointer' may be
+destructively modifed to eliminate duplicates under
+`equal-including-properties', satisfy `counsel-yank-pop-filter',
+and incorporate `interprogram-paste-function'."
+  ;; Protect against `kill-ring' and result of
+  ;; `interprogram-paste-function' both being nil
+  (ignore-errors (current-kill 0))
+  ;; Keep things consistent with the rest of Emacs
+  (dolist (sym '(kill-ring kill-ring-yank-pointer))
+    (set sym (cl-delete-duplicates
+              (cl-delete-if-not counsel-yank-pop-filter (symbol-value sym))
+              :test #'equal-including-properties :from-end t)))
+  kill-ring)
+
+(defun counsel-yank-pop-action (s)
+  "Like `yank-pop', but insert the kill corresponding to S.
+Signal a `buffer-read-only' error if called from a read-only
+buffer position."
+  (with-ivy-window
+    (barf-if-buffer-read-only)
+    (setq last-command 'yank)
+    (setq yank-window-start (window-start))
+    ;; Avoid unexpected additions to `kill-ring'
+    (let (interprogram-paste-function)
+      (yank-pop (counsel--yank-pop-position s)))
+    (setq ivy-completion-end (point))))
+
+(defun counsel-yank-pop-action-remove (s)
+  "Remove all occurrences of S from the kill ring."
+  (dolist (sym '(kill-ring kill-ring-yank-pointer))
+    (set sym (cl-delete s (symbol-value sym)
+                        :test #'equal-including-properties)))
+  ;; Update collection and preselect for next `ivy-call'
+  (setf (ivy-state-collection ivy-last) kill-ring)
+  (setf (ivy-state-preselect ivy-last)
+        (nth (min ivy--index (1- (length kill-ring)))
+             kill-ring))
+  (ivy--reset-state ivy-last))
+
+(defun counsel-yank-pop-action-rotate (s)
+  "Rotate the yanking point to S in the kill ring.
+See `current-kill' for how this interacts with the window system
+selection."
+  (let ((i (counsel--yank-pop-position s)))
+    ;; Avoid unexpected additions to `kill-ring'
+    (let (interprogram-paste-function)
+      (setf (ivy-state-preselect ivy-last) (current-kill i)))
+    ;; Manually change window system selection because `current-kill' won't
+    (when (and (zerop i)
+               yank-pop-change-selection
+               interprogram-cut-function)
+      (funcall interprogram-cut-function (car kill-ring-yank-pointer))))
+  (ivy--reset-state ivy-last))
+
+(defcustom counsel-yank-pop-preselect-last nil
+  "Whether `counsel-yank-pop' preselects the last kill by default.
+
+The command `counsel-yank-pop' always preselects the same kill
+that `yank-pop' would have inserted, given the same prefix
+argument.
+
+When `counsel-yank-pop-preselect-last' is nil (the default), the
+prefix argument of `counsel-yank-pop' defaults to 1 (as per
+`yank-pop'), which causes the next-to-last kill to be
+preselected.  Otherwise, the prefix argument defaults to 0, which
+results in the most recent kill being preselected."
+  :group 'ivy
+  :type 'boolean)
+
+;;;###autoload
+(defun counsel-yank-pop (&optional arg)
+  "Ivy replacement for `yank-pop'.
+ARG has the same meaning as in `yank-pop', but its default value
+can be controlled with `counsel-yank-pop-preselect-last', which
+see.  See also `counsel-yank-pop-filter' for how to filter
+candidates.
+Note: Duplicate elements of `kill-ring' are always deleted."
+  ;; Do not specify `*' to allow browsing `kill-ring' in read-only buffers
+  (interactive "P")
+  (let ((ivy-format-function #'counsel--yank-pop-format-function)
+        (kills (counsel--yank-pop-kills)))
+    (unless kills
+      (error "Kill ring is empty or blank"))
+    (unless (eq last-command 'yank)
+      (push-mark))
+    (setq ivy-completion-beg (mark t))
+    (setq ivy-completion-end (point))
+    (ivy-read "kill-ring: " kills
+              :require-match t
+              :preselect (let (interprogram-paste-function)
+                           (current-kill (cond
+                                           (arg (prefix-numeric-value arg))
+                                           (counsel-yank-pop-preselect-last 0)
+                                           (t 1))
+                                         t))
+              :action #'counsel-yank-pop-action
+              :caller 'counsel-yank-pop)))
+
+(add-to-list 'ivy-height-alist '(counsel-yank-pop . 5))
+
+(ivy-set-actions
+ 'counsel-yank-pop
+ '(("d" counsel-yank-pop-action-remove "delete")
+   ("r" counsel-yank-pop-action-rotate "rotate")))
+
+;;** `counsel-evil-registers'
+(make-obsolete-variable
+ 'counsel-evil-registers-height
+ 'ivy-height-alist
+ "<2018-04-14 Fri>") ;; TODO: Add version tag
+
+(defcustom counsel-evil-registers-height 5
+  "The `ivy-height' of `counsel-evil-registers'."
+  :group 'ivy
+  :type 'integer)
+
+(defun counsel-evil-registers ()
+  "Ivy replacement for `evil-show-registers'."
+  (interactive)
+  (if (fboundp 'evil-register-list)
+      (let ((ivy-format-function #'counsel--yank-pop-format-function))
+        (ivy-read "evil-registers: "
+                  (cl-loop for (key . val) in (evil-register-list)
+                     collect (format "[%c]: %s" key (if (stringp val) val "")))
+                  :require-match t
+                  :action #'counsel-evil-registers-action
+                  :caller 'counsel-evil-registers))
+    (user-error "Required feature `evil' not installed.")))
+
+(add-to-list 'ivy-height-alist '(counsel-evil-registers . 5))
+
+(defun counsel-evil-registers-action (s)
+  "Paste contents of S, trimming the register part.
+
+S will be of the form \"[register]: content\"."
+  (with-ivy-window
+    (insert
+     (replace-regexp-in-string "\\`\\[.*?\\]: " "" s))))
+
+;;** `counsel-imenu'
+(defvar imenu-auto-rescan)
+(defvar imenu-auto-rescan-maxout)
+(declare-function imenu--subalist-p "imenu")
+(declare-function imenu--make-index-alist "imenu")
+
+(defun counsel-imenu-get-candidates-from (alist &optional prefix)
+  "Create a list of (key . value) from ALIST.
+PREFIX is used to create the key."
+  (cl-mapcan (lambda (elm)
+               (if (imenu--subalist-p elm)
+                   (counsel-imenu-get-candidates-from
+                    (cl-loop for (e . v) in (cdr elm) collect
+                         (cons e (if (integerp v) (copy-marker v) v)))
+                    ;; pass the prefix to next recursive call
+                    (concat prefix (if prefix ".") (car elm)))
+                 (let ((key (concat
+                             (when prefix
+                               (concat
+                                (propertize prefix 'face 'compilation-info)
+                                ": "))
+                             (car elm))))
+                   (list (cons key
+                               ;; create a imenu candidate here
+                               (cons key (if (overlayp (cdr elm))
+                                             (overlay-start (cdr elm))
+                                           (cdr elm))))))))
+             alist))
+
+(defvar counsel-imenu-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "C-l") 'ivy-call-and-recenter)
+    map))
+
+(defun counsel-imenu-categorize-functions (items)
+  "Categorize all the functions of imenu."
+  (let* ((others (cl-remove-if-not (lambda (x) (listp (cdr x))) items))
+         (functions (cl-remove-if (lambda (x) (listp (cdr x))) items)))
+    (if functions
+        (append others `(("Functions" ,@functions)))
+      items)))
+
+;;;###autoload
+(defun counsel-imenu ()
+  "Jump to a buffer position indexed by imenu."
+  (interactive)
+  (unless (featurep 'imenu)
+    (require 'imenu nil t))
+  (let* ((imenu-auto-rescan t)
+         (imenu-auto-rescan-maxout (if current-prefix-arg
+                                       (buffer-size)
+                                     imenu-auto-rescan-maxout))
+         (items (imenu--make-index-alist t))
+         (items (delete (assoc "*Rescan*" items) items))
+         (items (counsel-imenu-categorize-functions items)))
+    (ivy-read "imenu items: " (counsel-imenu-get-candidates-from items)
+              :preselect (thing-at-point 'symbol)
+              :require-match t
+              :action (lambda (candidate)
+                        (with-ivy-window
+                          ;; In org-mode, (imenu candidate) will expand child node
+                          ;; after jump to the candidate position
+                          (imenu (cdr candidate))))
+              :keymap counsel-imenu-map
+              :caller 'counsel-imenu)))
+
+;;** `counsel-list-processes'
+(defun counsel-list-processes-action-delete (x)
+  "Delete process X."
+  (delete-process x)
+  (setf (ivy-state-collection ivy-last)
+        (setq ivy--all-candidates
+              (delete x ivy--all-candidates))))
+
+(defun counsel-list-processes-action-switch (x)
+  "Switch to buffer of process X."
+  (let* ((proc (get-process x))
+         (buf (and proc (process-buffer proc))))
+    (if buf
+        (switch-to-buffer buf)
+      (message "Process %s doesn't have a buffer" x))))
+
+;;;###autoload
+(defun counsel-list-processes ()
+  "Offer completion for `process-list'.
+The default action deletes the selected process.
+An extra action allows to switch to the process buffer."
+  (interactive)
+  (with-temp-buffer
+    (list-processes--refresh))
+  (ivy-read "Process: " (mapcar #'process-name (process-list))
+            :require-match t
+            :action
+            '(1
+              ("o" counsel-list-processes-action-delete "kill")
+              ("s" counsel-list-processes-action-switch "switch"))
+            :caller 'counsel-list-processes))
+
+;;** `counsel-ace-link'
+(defun counsel-ace-link ()
+  "Use Ivy completion for `ace-link'."
+  (interactive)
+  (let (collection action)
+    (cond ((eq major-mode 'Info-mode)
+           (setq collection 'ace-link--info-collect)
+           (setq action 'ace-link--info-action))
+          ((eq major-mode 'help-mode)
+           (setq collection 'ace-link--help-collect)
+           (setq action 'ace-link--help-action))
+          ((eq major-mode 'woman-mode)
+           (setq collection 'ace-link--woman-collect)
+           (setq action 'ace-link--woman-action))
+          ((eq major-mode 'eww-mode)
+           (setq collection 'ace-link--eww-collect)
+           (setq action 'ace-link--eww-action))
+          ((eq major-mode 'compilation-mode)
+           (setq collection 'ace-link--eww-collect)
+           (setq action 'ace-link--compilation-action))
+          ((eq major-mode 'org-mode)
+           (setq collection 'ace-link--org-collect)
+           (setq action 'ace-link--org-action)))
+    (if (null collection)
+        (error "%S is not supported" major-mode)
+      (ivy-read "Ace-Link: " (funcall collection)
+                :action (lambda (x) (funcall action (cdr x)))
+                :require-match t
+                :caller 'counsel-ace-link))))
+
+;;** `counsel-minibuffer-history'
+(make-obsolete
+ 'counsel-expression-history
+ 'counsel-minibuffer-history
+ "0.10.0 <2017-11-13 Mon>")
+
+(make-obsolete
+ 'counsel-shell-command-history
+ 'counsel-minibuffer-history
+ "0.10.0 <2017-11-13 Mon>")
+
+;;;###autoload
+(defun counsel-expression-history ()
+  "Select an element of `read-expression-history'.
+And insert it into the minibuffer.  Useful during `eval-expression'."
+  (interactive)
+  (let ((enable-recursive-minibuffers t))
+    (ivy-read "Expression: "
+              (delete-dups (copy-sequence read-expression-history))
+              :action #'insert
+              :caller 'counsel-expression-history)))
+
+;;;###autoload
+(defun counsel-shell-command-history ()
+  "Browse shell command history."
+  (interactive)
+  (ivy-read "Command: " shell-command-history
+            :action #'insert
+            :caller 'counsel-shell-command-history))
+
+;;;###autoload
+(defun counsel-minibuffer-history ()
+  "Browse minibuffer history."
+  (interactive)
+  (let ((enable-recursive-minibuffers t))
+    (ivy-read "History: "
+              (delete-dups (copy-sequence
+                            (symbol-value minibuffer-history-variable)))
+              :action #'insert
+              :caller 'counsel-minibuffer-history)))
+
+;;** `counsel-esh-history'
+(defun counsel--browse-history (elements)
+  "Use Ivy to navigate through ELEMENTS."
+  (setq ivy-completion-beg (point))
+  (setq ivy-completion-end (point))
+  (ivy-read "Symbol name: "
+            (delete-dups
+             (when (> (ring-size elements) 0)
+               (ring-elements elements)))
+            :action #'ivy-completion-in-region-action))
+
+(defvar eshell-history-ring)
+
+;;;###autoload
+(defun counsel-esh-history ()
+  "Browse Eshell history."
+  (interactive)
+  (require 'em-hist)
+  (counsel--browse-history eshell-history-ring))
+
+(defvar comint-input-ring)
+
+;;;###autoload
+(defun counsel-shell-history ()
+  "Browse shell history."
+  (interactive)
+  (require 'comint)
+  (counsel--browse-history comint-input-ring))
+
+;;** `counsel-hydra-heads'
+(defvar hydra-curr-body-fn)
+(declare-function hydra-keyboard-quit "ext:hydra")
+
+(defun counsel-hydra-heads ()
+  "Call a head of the current/last hydra."
+  (interactive)
+  (let* ((base (substring
+                (prin1-to-string hydra-curr-body-fn)
+                0 -4))
+         (heads (eval (intern (concat base "heads"))))
+         (keymap (eval (intern (concat base "keymap"))))
+         (head-names
+          (mapcar (lambda (x)
+                    (cons
+                     (if (nth 2 x)
+                         (format "[%s] %S (%s)" (nth 0 x) (nth 1 x) (nth 2 x))
+                       (format "[%s] %S" (nth 0 x) (nth 1 x)))
+                     (lookup-key keymap (kbd (nth 0 x)))))
+                  heads)))
+    (ivy-read "head: " head-names
+              :action (lambda (x) (call-interactively (cdr x))))
+    (hydra-keyboard-quit)))
+;;** `counsel-semantic'
+(declare-function semantic-tag-start "semantic/tag")
+(declare-function semantic-tag-class "semantic/tag")
+(declare-function semantic-tag-name "semantic/tag")
+(declare-function semantic-tag-put-attribute "semantic/tag")
+(declare-function semantic-tag-get-attribute "semantic/tag")
+(declare-function semantic-fetch-tags "semantic")
+(declare-function semantic-format-tag-summarize "semantic/format")
+(declare-function semantic-active-p "semantic/fw")
+
+(defun counsel-semantic-action (x)
+  "Got to semantic TAG."
+  (goto-char (semantic-tag-start (cdr x))))
+
+(defvar counsel-semantic-history nil
+  "History for `counsel-semantic'.")
+
+(defun counsel-semantic-format-tag (tag)
+  "Return a pretty string representation of TAG."
+  (let ((depth (or (semantic-tag-get-attribute tag :depth) 0))
+        (parent (semantic-tag-get-attribute tag :parent)))
+    (concat (make-string (* depth 2) ?\ )
+            (if parent
+                (concat "(" parent ") ")
+              "")
+            (semantic-format-tag-summarize tag nil t))))
+
+(defun counsel-flatten-forest (func treep forest)
+  "Use FUNC and TREEP to flatten FOREST.
+FUNC is applied to each node.
+TREEP is used to expand internal nodes."
+  (cl-labels ((reducer (forest out depth)
+                (dolist (tree forest)
+                  (let ((this (cons (funcall func tree depth) out))
+                        (leafs (funcall treep tree)))
+                    (setq out
+                          (if leafs
+                              (reducer leafs this (1+ depth))
+                            this))))
+                out))
+    (nreverse (reducer forest nil 0))))
+
+(defun counsel-semantic-tags ()
+  "Fetch semantic tags."
+  (counsel-flatten-forest
+   (lambda (tree depth)
+     (semantic-tag-put-attribute tree :depth depth))
+   (lambda (tag)
+     (when (eq (semantic-tag-class tag) 'type)
+       (let ((name (semantic-tag-name tag)))
+         (mapcar
+          (lambda (x) (semantic-tag-put-attribute x :parent name))
+          (semantic-tag-get-attribute tag :members)))))
+   (semantic-fetch-tags)))
+
+(defun counsel-semantic ()
+  "Jump to a semantic tag in the current buffer."
+  (interactive)
+  (let ((tags (mapcar
+               (lambda (x)
+                 (cons
+                  (counsel-semantic-format-tag x)
+                  x))
+               (counsel-semantic-tags))))
+    (ivy-read "tag: " tags
+              :action 'counsel-semantic-action
+              :history 'counsel-semantic-history
+              :caller 'counsel-semantic)))
+
+(defun counsel-semantic-or-imenu ()
+  (interactive)
+  (require 'semantic/fw)
+  (if (semantic-active-p)
+      (counsel-semantic)
+    (counsel-imenu)))
+
+;;** `counsel-outline'
+(defun counsel-outline-candidates ()
+  "Return outline candidates."
+  (let (cands)
+    (save-excursion
+      (goto-char (point-min))
+      (while (re-search-forward outline-regexp nil t)
+        (skip-chars-forward " ")
+        (push (cons (buffer-substring-no-properties
+                     (point) (line-end-position))
+                    (line-beginning-position))
+              cands))
+      (nreverse cands))))
+
+(defun counsel-outline-action (x)
+  "Go to outline X."
+  (with-ivy-window
+    (goto-char (cdr x))))
+
+;;;###autoload
+(defun counsel-outline ()
+  "Jump to outline with completion."
+  (interactive)
+  (ivy-read "outline: " (counsel-outline-candidates)
+            :action #'counsel-outline-action))
+
+;;** `counsel-ibuffer'
+(defvar counsel-ibuffer--buffer-name nil
+  "Name of the buffer to use for `counsel-ibuffer'.")
+
+;;;###autoload
+(defun counsel-ibuffer (&optional name)
+  "Use ibuffer to switch to another buffer.
+NAME specifies the name of the buffer (defaults to \"*Ibuffer*\")."
+  (interactive)
+  (setq counsel-ibuffer--buffer-name (or name "*Ibuffer*"))
+  (ivy-read "Switch to buffer: " (counsel-ibuffer--get-buffers)
+            :history 'counsel-ibuffer-history
+            :action #'counsel-ibuffer-visit-buffer
+            :caller 'counsel-ibuffer))
+
+(declare-function ibuffer-update "ibuffer")
+(declare-function ibuffer-current-buffer "ibuffer")
+(declare-function ibuffer-forward-line "ibuffer")
+(defvar ibuffer-movement-cycle)
+
+(defun counsel-ibuffer--get-buffers ()
+  "Return list of buffer-related lines in Ibuffer as strings."
+  (let ((oldbuf (get-buffer counsel-ibuffer--buffer-name)))
+    (unless oldbuf
+      ;; Avoid messing with the user's precious window/frame configuration.
+      (save-window-excursion
+        (let ((display-buffer-overriding-action
+               '(display-buffer-same-window (inhibit-same-window . nil))))
+          (ibuffer nil counsel-ibuffer--buffer-name nil t))))
+    (with-current-buffer counsel-ibuffer--buffer-name
+      (when oldbuf
+        ;; Forcibly update possibly stale existing buffer.
+        (ibuffer-update nil t))
+      (goto-char (point-min))
+      (let ((ibuffer-movement-cycle nil)
+            entries)
+        (while (not (eobp))
+          (ibuffer-forward-line 1 t)
+          (let ((buf (ibuffer-current-buffer)))
+            ;; We are only interested in buffers we can actually visit.
+            ;; This filters out headings and other unusable entries.
+            (when (buffer-live-p buf)
+              (push (cons (buffer-substring-no-properties
+                           (line-beginning-position)
+                           (line-end-position))
+                          buf)
+                    entries))))
+        (nreverse entries)))))
+
+(defun counsel-ibuffer-visit-buffer (x)
+  "Switch to buffer of candidate X."
+  (switch-to-buffer (cdr x)))
+
+(defun counsel-ibuffer-visit-buffer-other-window (x)
+  "Switch to buffer of candidate X in another window."
+  (switch-to-buffer-other-window (cdr x)))
+
+(defun counsel-ibuffer-visit-ibuffer (_)
+  "Switch to Ibuffer buffer."
+  (switch-to-buffer counsel-ibuffer--buffer-name))
+
+(ivy-set-actions
+ 'counsel-ibuffer
+ '(("j" counsel-ibuffer-visit-buffer-other-window "other window")
+   ("v" counsel-ibuffer-visit-ibuffer "switch to Ibuffer")))
+
+;;** `counsel-switch-to-shell-buffer'
+(defun counsel--buffers-with-mode (mode)
+  "Return names of buffers with MODE as their `major-mode'."
+  (let (bufs)
+    (dolist (buf (buffer-list))
+      (when (eq (buffer-local-value 'major-mode buf) mode)
+        (push (buffer-name buf) bufs)))
+    (nreverse bufs)))
+
+(declare-function shell-mode "shell")
+
+;;;###autoload
+(defun counsel-switch-to-shell-buffer ()
+  "Switch to a shell buffer, or create one."
+  (interactive)
+  (ivy-read "Shell buffer: " (counsel--buffers-with-mode #'shell-mode)
+            :action #'counsel--switch-to-shell
+            :caller 'counsel-switch-to-shell-buffer))
+
+(defun counsel--switch-to-shell (name)
+  "Display shell buffer with NAME and select its window.
+Reuse any existing window already displaying the named buffer.
+If there is no such buffer, start a new `shell' with NAME."
+  (if (get-buffer name)
+      (pop-to-buffer name '((display-buffer-reuse-window
+                             display-buffer-same-window)
+                            (inhibit-same-window . nil)
+                            (reusable-frames . visible)))
+    (shell name)))
+
+;;** `counsel-unicode-char'
+(defvar counsel-unicode-char-history nil
+  "History for `counsel-unicode-char'.")
+
+(defun counsel--unicode-names ()
+  "Return formatted and sorted list of `ucs-names'.
+The result of `ucs-names' is mostly, but not completely, sorted,
+so this function ensures lexicographic order."
+  (let* (cands
+         (table (ucs-names))            ; Either hash map or alist
+         (fmt   (lambda (name code)     ; Common format function
+                  (push (propertize (format "%06X %-58s %c" code name code)
+                                    'code code)
+                        cands))))
+    (if (not (hash-table-p table))
+        ;; Support `ucs-names' returning an alist in Emacs < 26.
+        ;; The result of `ucs-names' comes pre-reversed so no need to repeat.
+        (dolist (entry table)
+          (funcall fmt (car entry) (cdr entry)))
+      (maphash fmt table)
+      ;; Reverse to speed up sorting
+      (setq cands (nreverse cands)))
+    (sort cands #'string-lessp)))
+
+(defvar counsel--unicode-table
+  (lazy-completion-table counsel--unicode-table counsel--unicode-names)
+  "Lazy completion table for `counsel-unicode-char'.
+Candidates comprise `counsel--unicode-names', which see.")
+
+;;;###autoload
+(defun counsel-unicode-char (&optional count)
+  "Insert COUNT copies of a Unicode character at point.
+COUNT defaults to 1."
+  (interactive "p")
+  (let ((ivy-sort-max-size (expt 256 6)))
+    (setq ivy-completion-beg (point))
+    (setq ivy-completion-end (point))
+    (ivy-read "Unicode name: " counsel--unicode-table
+              :action (lambda (name)
+                        (with-ivy-window
+                          (delete-region ivy-completion-beg ivy-completion-end)
+                          (setq ivy-completion-beg (point))
+                          (insert-char (get-text-property 0 'code name) count)
+                          (setq ivy-completion-end (point))))
+              :history 'counsel-unicode-char-history
+              :caller 'counsel-unicode-char
+              :sort t)))
+
+;;** `counsel-colors'
+(defun counsel-colors-action-insert-hex (color)
+  "Insert the hexadecimal RGB value of COLOR."
+  (insert (get-text-property 0 'hex color)))
+
+(defun counsel-colors-action-kill-hex (color)
+  "Kill the hexadecimal RGB value of COLOR."
+  (kill-new (get-text-property 0 'hex color)))
+
+;;** `counsel-colors-emacs'
+(defvar counsel-colors-emacs-history ()
+  "History for `counsel-colors-emacs'.")
+
+(defun counsel-colors--name-to-hex (name)
+  "Return hexadecimal RGB value of color with NAME."
+  (apply #'color-rgb-to-hex (color-name-to-rgb name)))
+
+(defvar shr-color-visible-luminance-min)
+(declare-function shr-color-visible "shr-color")
+
+(defun counsel-colors--formatter (formatter)
+  "Turn FORMATTER into format function for `counsel-colors-*'.
+Return closure suitable for `ivy-format-function'."
+  (require 'shr-color)
+  (lambda (colors)
+    (ivy--format-function-generic
+     (lambda (color)
+       (let* ((hex (get-text-property 0 'hex color))
+              (shr-color-visible-luminance-min 100)
+              (fg (cadr (shr-color-visible hex "black" t))))
+         (propertize (funcall formatter color)
+                     'face (list :foreground fg :background hex))))
+     formatter colors "\n")))
+
+;;;###autoload
+(defun counsel-colors-emacs ()
+  "Show a list of all supported colors for a particular frame.
+
+You can insert or kill the name or hexadecimal RGB value of the
+selected color."
+  (interactive)
+  (let* ((colors (mapcar (lambda (cell)
+                           (let ((name (car cell)))
+                             (propertize name
+                                         'hex (counsel-colors--name-to-hex name)
+                                         'dups (cdr cell))))
+                         (list-colors-duplicates)))
+         (fmt (format "%%-%ds %%s %%s%%s"
+                      (apply #'max 0 (mapcar #'string-width colors))))
+         (blank (make-string 10 ?\s))
+         (ivy-format-function
+          (counsel-colors--formatter
+           (lambda (color)
+             (let ((fg (list :foreground color)))
+               (format fmt color
+                       (propertize (get-text-property 0 'hex color) 'face fg)
+                       (propertize blank 'face (list :background color))
+                       (propertize (mapconcat (lambda (dup)
+                                                (concat " " dup))
+                                              (get-text-property 0 'dups color)
+                                              ",")
+                                   'face fg)))))))
+    (ivy-read "Emacs color: " colors
+              :require-match t
+              :history 'counsel-colors-emacs-history
+              :action #'insert
+              :caller 'counsel-colors-emacs)))
+
+(ivy-set-actions
+ 'counsel-colors-emacs
+ '(("h" counsel-colors-action-insert-hex "insert hexadecimal value")
+   ("H" counsel-colors-action-kill-hex "kill hexadecimal value")))
+
+;;** `counsel-colors-web'
+(defvar shr-color-html-colors-alist)
+
+(defun counsel-colors--web-alist ()
+  "Return list of CSS colours for `counsel-colors-web'."
+  (require 'shr-color)
+  (let* ((alist (copy-alist shr-color-html-colors-alist))
+         (mp  (assoc "MediumPurple"  alist))
+         (pvr (assoc "PaleVioletRed" alist))
+         (rp  (assoc "RebeccaPurple" alist)))
+    ;; Backport GNU Emacs bug#30377
+    (when mp (setcdr mp "#9370db"))
+    (when pvr (setcdr pvr "#db7093"))
+    (unless rp (push (cons "rebeccapurple" "#663399") alist))
+    (sort (mapcar (lambda (cell)
+                    (propertize (downcase (car cell))
+                                'hex (downcase (cdr cell))))
+                  alist)
+          #'string-lessp)))
+
+(defvar counsel-colors-web-history ()
+  "History for `counsel-colors-web'.")
+
+;;;###autoload
+(defun counsel-colors-web ()
+  "Show a list of all W3C web colors for use in CSS.
+
+You can insert or kill the name or hexadecimal RGB value of the
+selected color."
+  (interactive)
+  (let* ((colors (counsel-colors--web-alist))
+         (blank (make-string 10 ?\s))
+         (fmt (format "%%-%ds %%s %%s"
+                      (apply #'max 0 (mapcar #'string-width colors))))
+         (ivy-format-function
+          (counsel-colors--formatter
+           (lambda (color)
+             (let ((hex (get-text-property 0 'hex color)))
+               (format fmt color
+                       (propertize hex 'face (list :foreground hex))
+                       (propertize blank 'face (list :background hex))))))))
+    (ivy-read "Web color: " colors
+              :require-match t
+              :history 'counsel-colors-web-history
+              :sort t
+              :action #'insert
+              :caller 'counsel-colors-web)))
+
+(ivy-set-actions
+ 'counsel-colors-web
+ '(("h" counsel-colors-action-insert-hex "insert hexadecimal value")
+   ("H" counsel-colors-action-kill-hex "kill hexadecimal value")))
+
+;;* Misc. OS
+;;** `counsel-rhythmbox'
+(declare-function dbus-call-method "dbus")
+(declare-function dbus-get-property "dbus")
+
+(defun counsel-rhythmbox-play-song (song)
+  "Let Rhythmbox play SONG."
+  (let ((service "org.gnome.Rhythmbox3")
+        (path "/org/mpris/MediaPlayer2")
+        (interface "org.mpris.MediaPlayer2.Player"))
+    (dbus-call-method :session service path interface
+                      "OpenUri" (cdr song))))
+
+(defun counsel-rhythmbox-enqueue-song (song)
+  "Let Rhythmbox enqueue SONG."
+  (let ((service "org.gnome.Rhythmbox3")
+        (path "/org/gnome/Rhythmbox3/PlayQueue")
+        (interface "org.gnome.Rhythmbox3.PlayQueue"))
+    (dbus-call-method :session service path interface
+                      "AddToQueue" (cdr song))))
+
+(defvar counsel-rhythmbox-history nil
+  "History for `counsel-rhythmbox'.")
+
+(defvar counsel-rhythmbox-songs nil)
+
+(defun counsel-rhythmbox-current-song ()
+  "Return the currently playing song title."
+  (ignore-errors
+    (let* ((entry (dbus-get-property
+                   :session
+                   "org.mpris.MediaPlayer2.rhythmbox"
+                   "/org/mpris/MediaPlayer2"
+                   "org.mpris.MediaPlayer2.Player"
+                   "Metadata"))
+           (artist (caar (cadr (assoc "xesam:artist" entry))))
+           (album (cl-caadr (assoc "xesam:album" entry)))
+           (title (cl-caadr (assoc "xesam:title" entry))))
+      (format "%s - %s - %s" artist album title))))
+
+;;;###autoload
+(defun counsel-rhythmbox ()
+  "Choose a song from the Rhythmbox library to play or enqueue."
+  (interactive)
+  (require 'dbus)
+  (unless counsel-rhythmbox-songs
+    (let* ((service "org.gnome.Rhythmbox3")
+           (path "/org/gnome/UPnP/MediaServer2/Library/all")
+           (interface "org.gnome.UPnP.MediaContainer2")
+           (nb-songs (dbus-get-property
+                      :session service path interface "ChildCount")))
+      (if (not nb-songs)
+          (error "Couldn't connect to Rhythmbox")
+        (setq counsel-rhythmbox-songs
+              (mapcar (lambda (x)
+                        (cons
+                         (format
+                          "%s - %s - %s"
+                          (cl-caadr (assoc "Artist" x))
+                          (cl-caadr (assoc "Album" x))
+                          (cl-caadr (assoc "DisplayName" x)))
+                         (cl-caaadr (assoc "URLs" x))))
+                      (dbus-call-method
+                       :session service path interface "ListChildren"
+                       0 nb-songs '("*")))))))
+  (ivy-read "Rhythmbox: " counsel-rhythmbox-songs
+            :history 'counsel-rhythmbox-history
+            :preselect (counsel-rhythmbox-current-song)
+            :action
+            '(1
+              ("p" counsel-rhythmbox-play-song "Play song")
+              ("e" counsel-rhythmbox-enqueue-song "Enqueue song"))
+            :caller 'counsel-rhythmbox))
+
+;;** `counsel-linux-app'
+(defcustom counsel-linux-apps-directories
+  '("~/.local/share/applications/"
+    "~/.guix-profile/share/applications/"
+    "/usr/local/share/applications/"
+    "/usr/share/applications/")
+  "Directories in which to search for applications (.desktop files)."
+  :group 'ivy
+  :type '(repeat directory))
+
+(defcustom counsel-linux-app-format-function #'counsel-linux-app-format-function-default
+  "Function to format Linux application names the `counsel-linux-app' menu.
+The format function will be passed the application's name, comment, and command
+as arguments."
+  :group 'ivy
+  :type '(choice
+          (const :tag "Command : Name - Comment" counsel-linux-app-format-function-default)
+          (const :tag "Name - Comment (Command)" counsel-linux-app-format-function-name-first)
+          (const :tag "Name - Comment" counsel-linux-app-format-function-name-only)
+          (const :tag "Command" counsel-linux-app-format-function-command-only)
+          (function :tag "Custom")))
+
+(defvar counsel-linux-apps-faulty nil
+  "List of faulty desktop files.")
+
+(defvar counsel--linux-apps-cache nil
+  "Cache of desktop files data.")
+
+(defvar counsel--linux-apps-cached-files nil
+  "List of cached desktop files.")
+
+(defvar counsel--linux-apps-cache-timestamp nil
+  "Time when we last updated the cached application list.")
+
+(defvar counsel--linux-apps-cache-format-function nil
+  "The function used to format the cached Linux application menu.")
+
+(defun counsel-linux-app-format-function-default (name comment exec)
+  "Default Linux application name formatter.
+NAME is the name of the application, COMMENT its comment and EXEC
+the command to launch it."
+  (format "% -45s: %s%s"
+          (propertize exec 'face 'font-lock-builtin-face)
+          name
+          (if comment
+              (concat " - " comment)
+            "")))
+
+(defun counsel-linux-app-format-function-name-first (name comment exec)
+  "Format Linux application names with the NAME (and COMMENT) first.
+EXEC is the command to launch the application."
+  (format "%s%s (%s)"
+          name
+          (if comment
+              (concat " - " comment)
+            "")
+          (propertize exec 'face 'font-lock-builtin-face)))
+
+(defun counsel-linux-app-format-function-name-only (name comment _exec)
+  "Format Linux application names with the NAME (and COMMENT) only."
+  (format "%s%s"
+          name
+          (if comment
+              (concat " - " comment)
+            "")))
+
+(defun counsel-linux-app-format-function-command-only (_name _comment exec)
+  "Display only the command EXEC when formatting Linux application names."
+  exec)
+
+(defun counsel-linux-apps-list-desktop-files ()
+  "Return an alist of all Linux applications.
+Each list entry is a pair of (desktop-name . desktop-file).
+This function always returns its elements in a stable order."
+  (let ((hash (make-hash-table :test #'equal))
+        result)
+    (dolist (dir counsel-linux-apps-directories)
+      (when (file-exists-p dir)
+        (let ((dir (file-name-as-directory dir)))
+          (dolist (file (directory-files-recursively dir ".*\\.desktop$"))
+            (let ((id (subst-char-in-string ?/ ?- (file-relative-name file dir))))
+              (unless (gethash id hash)
+                (push (cons id file) result)
+                (puthash id file hash)))))))
+    result))
+
+(defun counsel-linux-apps-parse (desktop-entries-alist)
+  "Parse the given alist of Linux desktop entries.
+Each entry in DESKTOP-ENTRIES-ALIST is a pair of ((id . file-name)).
+Any desktop entries that fail to parse are recorded in
+`counsel-linux-apps-faulty'."
+  (let (result)
+    (setq counsel-linux-apps-faulty nil)
+    (dolist (entry desktop-entries-alist result)
+      (let ((id (car entry))
+            (file (cdr entry)))
+        (with-temp-buffer
+          (insert-file-contents file)
+          (goto-char (point-min))
+          (let ((start (re-search-forward "^\\[Desktop Entry\\] *$" nil t))
+                (end (re-search-forward "^\\[" nil t))
+                name comment exec)
+            (catch 'break
+              (unless start
+                (push file counsel-linux-apps-faulty)
+                (message "Warning: File %s has no [Desktop Entry] group" file)
+                (throw 'break nil))
+
+              (goto-char start)
+              (when (re-search-forward "^\\(Hidden\\|NoDisplay\\) *= *\\(1\\|true\\) *$" end t)
+                (throw 'break nil))
+              (setq name (match-string 1))
+
+              (goto-char start)
+              (unless (re-search-forward "^Type *= *Application *$" end t)
+                (throw 'break nil))
+              (setq name (match-string 1))
+
+              (goto-char start)
+              (unless (re-search-forward "^Name *= *\\(.+\\)$" end t)
+                (push file counsel-linux-apps-faulty)
+                (message "Warning: File %s has no Name" file)
+                (throw 'break nil))
+              (setq name (match-string 1))
+
+              (goto-char start)
+              (when (re-search-forward "^Comment *= *\\(.+\\)$" end t)
+                (setq comment (match-string 1)))
+
+              (goto-char start)
+              (unless (re-search-forward "^Exec *= *\\(.+\\)$" end t)
+                ;; Don't warn because this can technically be a valid desktop file.
+                (throw 'break nil))
+              (setq exec (match-string 1))
+
+              (goto-char start)
+              (when (re-search-forward "^TryExec *= *\\(.+\\)$" end t)
+                (let ((try-exec (match-string 1)))
+                  (unless (locate-file try-exec exec-path nil #'file-executable-p)
+                    (throw 'break nil))))
+
+              (push
+               (cons (funcall counsel-linux-app-format-function name comment exec) id)
+               result))))))))
+
+(defun counsel-linux-apps-list ()
+  "Return list of all Linux desktop applications."
+  (let* ((new-desktop-alist (counsel-linux-apps-list-desktop-files))
+         (new-files (mapcar 'cdr new-desktop-alist)))
+    (unless (and
+             (eq counsel-linux-app-format-function
+                 counsel--linux-apps-cache-format-function)
+             (equal new-files counsel--linux-apps-cached-files)
+             (null (cl-find-if
+                    (lambda (file)
+                      (time-less-p
+                       counsel--linux-apps-cache-timestamp
+                       (nth 5 (file-attributes file))))
+                    new-files)))
+      (setq counsel--linux-apps-cache (counsel-linux-apps-parse new-desktop-alist)
+            counsel--linux-apps-cache-format-function counsel-linux-app-format-function
+            counsel--linux-apps-cache-timestamp (current-time)
+            counsel--linux-apps-cached-files new-files)))
+  counsel--linux-apps-cache)
+
+
+(defun counsel-linux-app-action-default (desktop-shortcut)
+  "Launch DESKTOP-SHORTCUT."
+  (call-process "gtk-launch" nil 0 nil (cdr desktop-shortcut)))
+
+(defun counsel-linux-app-action-file (desktop-shortcut)
+  "Launch DESKTOP-SHORTCUT with a selected file."
+  (call-process "gtk-launch" nil 0 nil
+                (cdr desktop-shortcut)
+                (read-file-name "File: ")))
+
+(defun counsel-linux-app-action-open-desktop (desktop-shortcut)
+  "Open DESKTOP-SHORTCUT."
+  (let* ((app (cdr desktop-shortcut))
+         (file (cdr (assoc app (counsel-linux-apps-list-desktop-files)))))
+    (if file
+        (find-file file)
+      (error "Could not find location of file %s" app))))
+
+(ivy-set-actions
+ 'counsel-linux-app
+ '(("f" counsel-linux-app-action-file "run on a file")
+   ("d" counsel-linux-app-action-open-desktop "open desktop file")))
+
+;;;###autoload
+(defun counsel-linux-app ()
+  "Launch a Linux desktop application, similar to Alt-<F2>."
+  (interactive)
+  (ivy-read "Run a command: " (counsel-linux-apps-list)
+            :action #'counsel-linux-app-action-default
+            :caller 'counsel-linux-app))
+
+;;** `counsel-wmctrl'
+(defun counsel-wmctrl-action (x)
+  "Select the desktop window that corresponds to X."
+  (shell-command
+   (format "wmctrl -i -a \"%s\"" (cdr x))))
+
+(defvar counsel-wmctrl-ignore '("XdndCollectionWindowImp"
+                                "unity-launcher" "unity-panel" "unity-dash"
+                                "Hud" "Desktop")
+  "List of window titles to ignore for `counsel-wmctrl'.")
+
+(defun counsel-wmctrl ()
+  "Select a desktop window using wmctrl."
+  (interactive)
+  (let* ((cands1 (split-string (shell-command-to-string "wmctrl -l") "\n" t))
+         (cands2
+          (mapcar (lambda (s)
+                    (when (string-match
+                           "\\`\\([0-9a-fx]+\\)  \\([0-9]+\\) \\([^ ]+\\) \\(.+\\)\\'"
+                           s)
+                      (let ((title (match-string 4 s))
+                            (id (match-string 1 s)))
+                        (unless (member title counsel-wmctrl-ignore)
+                          (cons title id)))))
+                  cands1)))
+    (ivy-read "window: " cands2
+              :action #'counsel-wmctrl-action
+              :caller 'counsel-wmctrl)))
+
+;;* `counsel-mode'
+(defvar counsel-mode-map
+  (let ((map (make-sparse-keymap)))
+    (dolist (binding
+              '((execute-extended-command . counsel-M-x)
+                (describe-bindings . counsel-descbinds)
+                (describe-function . counsel-describe-function)
+                (describe-variable . counsel-describe-variable)
+                (describe-face . counsel-describe-face)
+                (list-faces-display . counsel-faces)
+                (find-file . counsel-find-file)
+                (find-library . counsel-find-library)
+                (imenu . counsel-imenu)
+                (load-library . counsel-load-library)
+                (load-theme . counsel-load-theme)
+                (yank-pop . counsel-yank-pop)
+                (info-lookup-symbol . counsel-info-lookup-symbol)
+                (pop-to-mark-command . counsel-mark-ring)
+                (bookmark-jump . counsel-bookmark)))
+      (define-key map (vector 'remap (car binding)) (cdr binding)))
+    map)
+  "Map for `counsel-mode'.
+Remaps built-in functions to counsel replacements.")
+
+(defcustom counsel-mode-override-describe-bindings nil
+  "Whether to override `describe-bindings' when `counsel-mode' is active."
+  :group 'ivy
+  :type 'boolean)
+
+;;;###autoload
+(define-minor-mode counsel-mode
+  "Toggle Counsel mode on or off.
+Turn Counsel mode on if ARG is positive, off otherwise. Counsel
+mode remaps built-in emacs functions that have counsel
+replacements. "
+  :group 'ivy
+  :global t
+  :keymap counsel-mode-map
+  :lighter " counsel"
+  (if counsel-mode
+      (progn
+        (when (and (fboundp 'advice-add)
+                   counsel-mode-override-describe-bindings)
+          (advice-add #'describe-bindings :override #'counsel-descbinds))
+        (define-key minibuffer-local-map (kbd "C-r")
+          'counsel-minibuffer-history))
+    (when (fboundp 'advice-remove)
+      (advice-remove #'describe-bindings #'counsel-descbinds))))
+
+(provide 'counsel)
+
+;;; counsel.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/counsel-20180719.1303/counsel.elc b/configs/shared/emacs/.emacs.d/elpa/counsel-20180719.1303/counsel.elc
new file mode 100644
index 0000000000..a69ed85687
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/counsel-20180719.1303/counsel.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/counsel-projectile-20180718.842/counsel-projectile-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/counsel-projectile-20180718.842/counsel-projectile-autoloads.el
new file mode 100644
index 0000000000..1ccb5e69bf
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/counsel-projectile-20180718.842/counsel-projectile-autoloads.el
@@ -0,0 +1,122 @@
+;;; counsel-projectile-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "counsel-projectile" "counsel-projectile.el"
+;;;;;;  (23377 60993 161534 700000))
+;;; Generated autoloads from counsel-projectile.el
+
+(autoload 'counsel-projectile-find-file "counsel-projectile" "\
+Jump to a file in the current project.
+
+With a prefix ARG, invalidate the cache first.
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'counsel-projectile-find-dir "counsel-projectile" "\
+Jump to a directory in the current project.
+
+With a prefix ARG, invalidate the cache first.
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'counsel-projectile-switch-to-buffer "counsel-projectile" "\
+Jump to a buffer in the current project.
+
+\(fn)" t nil)
+
+(autoload 'counsel-projectile-ag "counsel-projectile" "\
+Search the current project with ag.
+
+OPTIONS, if non-nil, is a string containing additional options to
+be passed to ag. It is read from the minibuffer if the function
+is called with a prefix argument.
+
+\(fn &optional OPTIONS)" t nil)
+
+(autoload 'counsel-projectile-rg "counsel-projectile" "\
+Search the current project with rg.
+
+OPTIONS, if non-nil, is a string containing additional options to
+be passed to rg. It is read from the minibuffer if the function
+is called with a prefix argument.
+
+\(fn &optional OPTIONS)" t nil)
+
+(autoload 'counsel-projectile-org-capture "counsel-projectile" "\
+Capture into the current project.
+
+This command is a replacement for `org-capture' (or
+`counsel-org-capture') offering project-specific capture
+templates, in addition to the regular templates available from
+`org-capture'. These project templates, which are \"expanded\"
+relatively to the current project, are determined by the
+variables `counsel-projectile-org-capture-templates' and
+`counsel-projectile-org-capture-templates-contexts'. See the
+former variable in particular for details.
+
+Optional argument FROM-BUFFER specifies the buffer from which to
+capture.
+
+\(fn &optional FROM-BUFFER)" t nil)
+
+(autoload 'counsel-projectile-org-agenda "counsel-projectile" "\
+Open project agenda.
+
+This command simply calls `org-agenda' after filtering out all
+agenda files that do not belong to the current project.
+
+Optional arguments ARG, ORG-KEYS, and RESTRICTION are as in
+`org-agenda'.
+
+\(fn &optional ARG ORG-KEYS RESTRICTION)" t nil)
+
+(autoload 'counsel-projectile-switch-project "counsel-projectile" "\
+Switch project.
+
+\(fn)" t nil)
+
+(autoload 'counsel-projectile "counsel-projectile" "\
+Jump to a buffer or file in the current project.
+
+With a prefix ARG, invalidate the cache first.
+
+If not inside a project, call `counsel-projectile-switch-project'.
+
+\(fn &optional ARG)" t nil)
+
+(defvar counsel-projectile-mode nil "\
+Non-nil if Counsel-Projectile mode is enabled.
+See the `counsel-projectile-mode' command
+for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `counsel-projectile-mode'.")
+
+(custom-autoload 'counsel-projectile-mode "counsel-projectile" nil)
+
+(autoload 'counsel-projectile-mode "counsel-projectile" "\
+Toggle Counsel-Projectile mode on or off.
+
+With a prefix argument ARG, enable the mode if ARG is positive,
+and disable it otherwise.  If called from Lisp, enable the mode
+if ARG is omitted or nil, and toggle it if ARG is `toggle'.
+
+Counsel-Projectile mode triggers Projectile mode, remaps
+Projectile commands that have counsel replacements, and adds key
+bindings for Counsel-Projectile commands that have no Projectile
+counterpart.
+
+\\{counsel-projectile-mode-map}
+
+\(fn &optional ARG)" t nil)
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; counsel-projectile-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/counsel-projectile-20180718.842/counsel-projectile-pkg.el b/configs/shared/emacs/.emacs.d/elpa/counsel-projectile-20180718.842/counsel-projectile-pkg.el
new file mode 100644
index 0000000000..4cb03cb5a6
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/counsel-projectile-20180718.842/counsel-projectile-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "counsel-projectile" "20180718.842" "Ivy integration for Projectile" '((counsel "0.10.0") (projectile "0.14.0")))
diff --git a/configs/shared/emacs/.emacs.d/elpa/counsel-projectile-20180718.842/counsel-projectile.el b/configs/shared/emacs/.emacs.d/elpa/counsel-projectile-20180718.842/counsel-projectile.el
new file mode 100644
index 0000000000..ff9a28072f
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/counsel-projectile-20180718.842/counsel-projectile.el
@@ -0,0 +1,1408 @@
+;;; counsel-projectile.el --- Ivy integration for Projectile -*- lexical-binding: t -*-
+
+;; Copyright (C) 2016-2018 Eric Danan
+
+;; Author: Eric Danan
+;; URL: https://github.com/ericdanan/counsel-projectile
+;; Package-Version: 20180718.842
+;; Keywords: project, convenience
+;; Version: 0.2.0
+;; Package-Requires: ((counsel "0.10.0") (projectile "0.14.0"))
+
+;; This file is NOT part of GNU Emacs.
+
+;;; License:
+
+;; This program 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, or (at
+;; your option) any later version.
+;;
+;; This program 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; see the file COPYING.  If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+;;
+;; Projectile has native support for using ivy as its completion
+;; system. Counsel-projectile provides further ivy integration into
+;; projectile by taking advantage of ivy's support for selecting from
+;; a list of actions and applying an action without leaving the
+;; completion session. Concretely, counsel-projectile defines
+;; replacements for existing projectile commands as well as new
+;; commands that have no projectile counterparts. A minor mode is also
+;; provided that adds key bindings for all these commands on top of
+;; the projectile key bindings.
+;;
+;;; Code:
+;;;; require
+
+(require 'counsel)
+(require 'projectile)
+
+;;;; global
+
+(defgroup counsel-projectile nil
+  "Ivy integration for Projectile."
+  :group 'ivy
+  :group 'projectile)
+
+(defun counsel-projectile--defcustom-action (command action group)
+  "Create a custom variable named \"COMMAND-action\" in GROUP,
+with default value ACTION, to be used as `:action' parameter for
+COMMAND's `ivy-read' call.
+
+This variable holds either a single action function, or an action
+list whose first element is the index of the default action in
+the list and the remaining elements are the actions (a key, a
+function, and a name for each action)."
+  (eval
+   `(defcustom ,(intern (format "%s-action" command))
+      ',action
+      ,(format "Action(s) for `%s'.
+
+This variable holds either a single action function (function of
+one variable, the selected candidate) or an action list
+consisting of:
+
+- the index of the default action in the list (1 for the first
+  action, etc),
+- the available actions, each of which consists of:
+  - a key (string) to call the action,
+  - an action function of one variable,
+  - a name (string) for the action.
+
+In both cases, extra actions can be added with `ivy-set-actions'.
+An action is triggered for the selected candidate with `M-o
+<key>' or `C-M-o <key>'.  The default action can also be
+triggered with `M-RET' or `C-M-RET'. If this variable holds a
+single action function, this action becomes the default action
+and is assigned the key \"o\".  For an action list, it is also
+usual to assign the key \"o\" to the default action." command)
+      :type '(choice
+              (function :tag "Single action function")
+              (cons :tag "Action list"
+                    (integer :tag "Index of default action" :value 1)
+                    (repeat :tag "Actions"
+                            (list :tag "Action"
+                                  (string   :tag "     key")
+                                  (function :tag "function")
+                                  (string   :tag "    name")))))
+      :group ',group)))
+
+(defun counsel-projectile--action-index (action-item action-list)
+  "Return the index in ACTION-LIST of the action whose key,
+function, name, or index in the list (1 for the first action,
+etc) is ACTION-ITEM.  If there is no such action, throw an error.
+
+ACTION-LIST is an action list whose first element is the index of
+the default action in the list and the remaining elements are the
+actions (a key, a function, and a name for each action)."
+  (let (index)
+    (if (integerp action-item)
+        (when (< 0 action-item (length action-list))
+          (setq index action-item))
+      (setq index (cl-position-if
+                   (cond
+                    ((functionp action-item)
+                     (lambda (action)
+                       (equal action-item
+                              (cadr action))))
+                    ((stringp action-item)
+                     (lambda (action)
+                       (member action-item
+                               (list (car action) (cl-caddr action))))))
+                   (cdr action-list)))
+      (when index
+        (setq index (1+ index))))
+    (or index
+        (error "Action not found: %s" action-item))))
+
+(defun counsel-projectile-modify-action (action-var modifications)
+  "Make MODIFICATIONS to ACTION-VAR.
+
+ACTION-VAR is a variable holding an action list whose first
+element is the index of the default action in the list and the
+remaining elements are the actions (a key, a function, and a name
+for each action).
+
+MODIFICATIONS is a list of modifications to be applied
+sequentially to ACTION-LIST. Each modification has one of the
+following formats:
+
+    (remove ACTION-ITEM)
+        Remove the action whose key, function, name, or index in
+        the list (1 for the first action, etc) is ACTION-ITEM
+        from the list.
+
+    (add ACTION TARGET-ITEM)
+        Add ACTION (a list containing a key, a function, and a
+        name) to the list, just before the action whose key,
+        function, name, or index in the list (1 for the first
+        action, etc) is TARGET-ITEM.  If TARGET-ITEM is omitted,
+        add the action at the end of the list.
+
+    (move ACTION-ITEM TARGET-ITEM)
+        Move the action whose key, function, name, or index in
+        the list (1 for the first action, etc) is ACTION-ITEM
+        just before the action whose key, function, name, or
+        index in the list (1 for the first action, etc) is
+        TARGET-ITEM.  If TARGET-ITEM is omitted, move the action
+        to the end of the list.
+
+    (setkey ACTION-ITEM KEY)
+        Set the key of the action whose key, function, name, or
+        index in the list (1 for the first action, etc) is
+        ACTION-ITEM to KEY.
+
+    (setfun ACTION-ITEM FUNCTION)
+        Set the function of the action whose key, function, name,
+        or index in the list (1 for the first action, etc) is
+        ACTION-ITEM to FUNCTION.
+
+    (setname ACTION-ITEM NAME)
+        Set the name of the action whose key, function, name, or
+        index in the list (1 for the first action, etc) is
+        ACTION-ITEM to NAME.
+
+    (default ACTION-ITEM)
+        Set the index of the default action in the list to that
+        of the action whose key, function, name, or index in the
+        list (1 for the first action, etc) is ACTION-ITEM.
+
+If anything goes wrong, throw an error and do not modify ACTION-VAR."
+  (let ((action-list (symbol-value action-var))
+        mod)
+    ;; Make sure ACTION-VAR actually holds a list and not a single
+    ;; action function
+    (unless (listp action-list)
+      (error "%s's value is not a list" action-var))
+    (while (setq mod (pop modifications))
+      (pcase mod
+        (`(remove ,action-item)
+         (setq action-list
+               (remove (nth (counsel-projectile--action-index action-item action-list)
+                            action-list)
+                       action-list)))
+        (`(add ,action ,target-item)
+         (let ((index (counsel-projectile--action-index target-item action-list)))
+           ;; copied from `helm-append-at-nth'
+           (setq action-list (cl-loop for a in action-list
+                                      for count from 1
+                                      collect a
+                                      when (= count index)
+                                      collect action))))
+        (`(add ,action)
+         (setq action-list (append action-list (list action))))
+        (`(move ,action-item ,target-item)
+         (push `(add ,(nth (counsel-projectile--action-index action-item action-list)
+                           action-list)
+                     ,target-item)
+               modifications)
+         (push `(remove ,action-item)
+               modifications))
+        (`(move ,action-item)
+         (push `(add ,(nth (counsel-projectile--action-index action-item action-list)
+                           action-list))
+               modifications)
+         (push `(remove ,action-item)
+               modifications))
+        (`(setkey ,action-item ,key)
+         (let ((index (counsel-projectile--action-index action-item action-list)))
+           (setq action-list (cl-loop for a in action-list
+                                      for count from 0
+                                      if (= count index)
+                                      collect (cons key (cdr a))
+                                      else
+                                      collect a))))
+        (`(setfun ,action-item ,fun)
+         (let ((index (counsel-projectile--action-index action-item action-list)))
+           (setq action-list (cl-loop for a in action-list
+                                      for count from 0
+                                      if (= count index)
+                                      collect (list (car a) fun (cl-caddr a))
+                                      else
+                                      collect a))))
+        (`(setname ,action-item ,name)
+         (let ((index (counsel-projectile--action-index action-item action-list)))
+           (setq action-list (cl-loop for a in action-list
+                                      for count from 0
+                                      if (= count index)
+                                      collect (list (car a) (cadr a) name)
+                                      else
+                                      collect a))))
+        (`(default ,action-item)
+         (setq action-list
+               (cons (counsel-projectile--action-index action-item action-list)
+                     (cdr action-list))))))
+    (set action-var action-list)))
+
+;;;; counsel-projectile-find-file
+
+(defcustom counsel-projectile-sort-files nil
+  "Non-nil if files should be sorted in
+`counsel-projectile-find-file' and `counsel-projectile'.
+
+The sorting function can be modified by adding an entry for
+`counsel-projectile-find-file' in `ivy-sort-functions-alist'."
+  :type 'boolean
+  :group 'counsel-projectile)
+
+(defcustom counsel-projectile-find-file-matcher 'counsel--find-file-matcher
+  "Function returning candidates matching minibuffer input in
+`counsel-projectile-find-file', also used to match files in
+`counsel-projectile'.
+
+Several choices are proposed:
+
+- Ivy generic matcher (`ivy--re-filter'). This is the matcher
+  used by default in all ivy commands.
+
+- Counsel matcher (`counsel--find-file-matcher').  This is the
+  matcher used in `counsel-find-file', allowing to ignore some
+  files based on `counsel-find-file-ignore-regexp'.
+
+- Counsel-projectile basename
+  matcher (`counsel-projectile-basename-matcher').  This one only
+  displays files whose basename matches minibuffer input, or if
+  there is none all files whose name (relative to the project
+  root) matches. It also uses the counsel matcher to ignore some
+  files.
+
+It is also possible to use a custom matcher.  It must be a function taking two argument, the regexp and the candidates (see e.g. `counsel--find-file-matcher')."
+  :type '(choice
+          (const :tag "Ivy generic matcher" ivy--re-filter)
+          (const :tag "Counsel matcher" counsel--find-file-matcher)
+          (const :tag "Counsel-projectile basename matcher" counsel-projectile-find-file-matcher-basename)
+          (function :tag "Custom function"))
+  :group 'counsel-projectile)
+
+(counsel-projectile--defcustom-action
+ 'counsel-projectile-find-file
+ '(1
+   ("o" counsel-projectile-find-file-action
+    "current window")
+   ("j" counsel-projectile-find-file-action-other-window
+    "other window")
+   ("x" counsel-projectile-find-file-action-extern
+    "open externally")
+   ("r" counsel-projectile-find-file-action-root
+    "open as root")
+   ("m" counsel-projectile-find-file-action-find-file-manually
+    "find file manually")
+   ("p" (lambda (_) (counsel-projectile-switch-project))
+    "switch project"))
+ 'counsel-projectile)
+
+(defun counsel-projectile-find-file-matcher-basename (regexp candidates)
+  "Return the list of CANDIDATES whose basename matches REGEXP,
+or if there is none the list of all CANDIDATES matching REGEXP.
+Also uses `counsel--find-file-matcher' to ignore candidates based
+on `counsel-find-file-ignore-regexp'."
+  (let ((cands (ivy--re-filter regexp candidates)))
+    (or (and (not (string= ivy-text ""))
+             ;; We first filter `cands' to retain only matches in file
+             ;; basename. This is almost copied from `ivy--re-filter'
+             ;; because we can't quite use it directly.
+             (let ((re-list (if (stringp regexp)
+                                (list (cons regexp t))
+                              regexp))
+                   (res cands))
+               (dolist (re re-list)
+                 (setq res
+                       (ignore-errors
+                         (funcall
+                          (if (cdr re)
+                              #'cl-remove-if-not
+                            #'cl-remove-if)
+                          (let ((re-str (car re)))
+                            (lambda (x)
+                              (string-match re-str
+                                            (file-name-nondirectory x))))
+                          res))))
+               ;; We then apply `counsel--find-file-matcher' to `res'
+               ;; so we can honor `ivy-use-ignore', but we don't need
+               ;; to filter again.
+               (counsel--find-file-matcher nil res)))
+        ;; We apply `counsel--find-file-matcher' to `cands' so we can
+        ;; honor `ivy-use-ignore', but we don't need to filter
+        ;; again.
+        (counsel--find-file-matcher nil cands))))     
+
+(defun counsel-projectile-find-file-action (file)
+  "Find FILE and run `projectile-find-file-hook'."
+  (find-file (projectile-expand-root file))
+  (run-hooks 'projectile-find-file-hook))
+
+(defun counsel-projectile-find-file-action-other-window (file)
+  "Find FILE in another window and run
+`projectile-find-file-hook'."
+  (find-file-other-window (projectile-expand-root file))
+  (run-hooks 'projectile-find-file-hook))
+
+(defun counsel-projectile-find-file-action-find-file-manually (file)
+  "Call `counsel-find-file' from FILE's directory."
+  (let* ((f (projectile-expand-root file))
+         (default-directory (file-name-directory f)))
+    (counsel-find-file)))
+
+(defun counsel-projectile-find-file-action-extern (file)
+  "Find FILE externally and run `projectile-find-file-hook'."
+  (counsel-find-file-extern (projectile-expand-root file))
+  (run-hooks 'projectile-find-file-hook))
+
+(defun counsel-projectile-find-file-action-root (file)
+  "Find FILE as root and run `projectile-find-file-hook'."
+  (counsel-find-file-as-root (projectile-expand-root file))
+  (run-hooks 'projectile-find-file-hook))
+
+(defun counsel-projectile-find-file-transformer (str)
+  "Transform non-visited file names with `ivy-virtual' face."
+  (if (not (get-file-buffer (projectile-expand-root str)))
+      (propertize str 'face 'ivy-virtual)
+    str))
+
+;;;###autoload
+(defun counsel-projectile-find-file (&optional arg)
+  "Jump to a file in the current project.
+
+With a prefix ARG, invalidate the cache first."
+  (interactive "P")
+  (projectile-maybe-invalidate-cache arg)
+  (ivy-read (projectile-prepend-project-name "Find file: ")
+            (projectile-current-project-files)
+            :matcher counsel-projectile-find-file-matcher
+            :require-match t
+            :sort counsel-projectile-sort-files
+            :action counsel-projectile-find-file-action
+            :caller 'counsel-projectile-find-file))
+
+(ivy-set-display-transformer
+ 'counsel-projectile-find-file
+ 'counsel-projectile-find-file-transformer)
+
+;;;; counsel-projectile-find-dir
+
+(defcustom counsel-projectile-sort-directories nil
+  "Non-nil if directories should be sorted in
+`counsel-projectile-find-dir'.
+
+The sorting function can be modified by adding an entry for
+`counsel-projectile-find-dir' in `ivy-sort-functions-alist'."
+  :type 'boolean
+  :group 'counsel-projectile)
+
+(counsel-projectile--defcustom-action
+ 'counsel-projectile-find-dir
+ '(1
+   ("o" counsel-projectile-find-dir-action
+    "current window")
+   ("j" counsel-projectile-find-dir-action-other-window
+    "other window")
+   ("x" counsel-projectile-find-dir-action-extern
+    "open externally")
+   ("r" counsel-projectile-find-dir-action-root
+    "open as root")
+   ("m" counsel-projectile-find-file-action-find-file-manually
+    "find file manually")
+   ("p" (lambda (_) (counsel-projectile-switch-project))
+    "switch project"))
+ 'counsel-projectile)
+ 
+(defun counsel-projectile--project-directories ()
+  "Return a list of current project's directories."
+  (if projectile-find-dir-includes-top-level
+      (append '("./") (projectile-current-project-dirs))
+    (projectile-current-project-dirs)))
+
+(defun counsel-projectile-find-dir-action (dir)
+  "Visit DIR with dired and run `projectile-find-dir-hook'."
+  (dired (projectile-expand-root dir))
+  (run-hooks 'projectile-find-dir-hook))
+
+(defun counsel-projectile-find-dir-action-other-window (dir)
+  "Visit DIR with dired in another window and run
+`projectile-find-dir-hook'."
+  (dired-other-window (projectile-expand-root dir))
+  (run-hooks 'projectile-find-dir-hook))
+
+(defun counsel-projectile-find-dir-action-extern (dir)
+  "Visit DIR externally and run `projectile-find-dir-hook'."
+  (counsel-find-file-extern (projectile-expand-root dir))
+  (run-hooks 'projectile-find-dir-hook))
+
+(defun counsel-projectile-find-dir-action-root (dir)
+  "Visit DIR as root and run `projectile-find-dir-hook'."
+  (counsel-find-file-as-root (projectile-expand-root dir))
+  (run-hooks 'projectile-find-dir-hook))
+
+(defun counsel-projectile-find-dir-transformer (str)
+  "Transform candidates with `ivy-subdir' face."
+  (propertize str 'face 'ivy-subdir))
+
+;;;###autoload
+(defun counsel-projectile-find-dir (&optional arg)
+  "Jump to a directory in the current project.
+
+With a prefix ARG, invalidate the cache first."
+  (interactive "P")
+  (projectile-maybe-invalidate-cache arg)
+  (ivy-read (projectile-prepend-project-name "Find dir: ")
+            (counsel-projectile--project-directories)
+            :require-match t
+            :sort counsel-projectile-sort-directories
+            :action counsel-projectile-find-dir-action
+            :caller 'counsel-projectile-find-dir))
+
+(ivy-set-display-transformer
+ 'counsel-projectile-find-dir
+ 'counsel-projectile-find-dir-transformer)
+
+;;;; counsel-projectile-switch-to-buffer
+
+(defcustom counsel-projectile-sort-buffers nil
+  "Non-nil if buffers should be sorted in
+`counsel-projectile-switch-to-buffer' and `counsel-projectile'.
+
+The sorting function can be modified by adding an entry for
+`counsel-projectile-switch-to-buffer' in
+`ivy-sort-functions-alist'."
+  :type 'boolean
+  :group 'counsel-projectile)
+
+(defcustom counsel-projectile-remove-current-buffer nil
+  "Non-nil if current buffer should be removed from the
+candidates list of `counsel-projectile-switch-to-buffer' and
+`counsel-projectile'."
+  :type 'boolean
+  :group 'counsel-projectile)
+
+(counsel-projectile--defcustom-action
+ 'counsel-projectile-switch-to-buffer
+ '(1
+   ("o" counsel-projectile-switch-to-buffer-action
+    "current window")
+   ("j" switch-to-buffer-other-window
+    "other window")
+   ("k" ivy--kill-buffer-action
+    "kill")
+   ("m" counsel-projectile-switch-to-buffer-action-find-file-manually
+    "find file manually")
+   ("p" (lambda (_) (counsel-projectile-switch-project))
+    "switch project"))
+ 'counsel-projectile)
+
+(defvar counsel-projectile-switch-to-buffer-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "C-c C-k") (lambda ()
+                                      (interactive)
+                                      (ivy--kill-buffer-action (ivy-state-current ivy-last))))
+    map)
+  "Keymap for `counsel-projectile-switch-to-buffer'.")
+
+(defun counsel-projectile--project-buffers (&rest _)
+  ;; The ignored arguments are so that the function can be used as
+  ;; collection function in `counsel-projectile-switch-to-buffer'.
+  "Return a list of buffers in the current project.
+
+Like `projectile-project-buffer-names', but propertize buffer
+names as in `ivy--buffer-list', and remove current buffer if
+`counsel-projectile-remove-currennt-buffer' is non-nil."
+  (let ((buffer-names (projectile-project-buffer-names)))
+    (when counsel-projectile-remove-current-buffer
+      (setq buffer-names (delete (buffer-name (current-buffer)) buffer-names)))
+    (ivy--buffer-list "" nil
+                      (lambda (x)
+                        (member (car x) buffer-names)))))
+
+(defun counsel-projectile-switch-to-buffer-action (buffer)
+  "Switch to BUFFER."
+  (switch-to-buffer buffer nil 'force-same-window))
+
+(defun counsel-projectile-switch-to-buffer-action-find-file-manually (buffer)
+  "Call `counsel-find-file' from BUFFER's default directory."
+  (let* ((b (get-buffer buffer))
+         (default-directory
+           (or (and b (buffer-local-value 'default-directory b))
+               (projectile-project-root))))
+    (counsel-find-file)))
+
+(defun counsel-projectile-switch-to-buffer-transformer (str)
+  "Transform candidate STR when switching project buffers.
+
+This simply applies the same transformer as in `ivy-switch-buffer', which is `ivy-switch-buffer-transformer' by default but could have been modified e.g. by the ivy-rich package."
+  (funcall (plist-get ivy--display-transformers-list 'ivy-switch-buffer)
+           str))
+
+;;;###autoload
+(defun counsel-projectile-switch-to-buffer ()
+  "Jump to a buffer in the current project."
+  (interactive)
+  (ivy-read (projectile-prepend-project-name "Switch to buffer: ")
+            ;; We use a collection function so that it is called each
+            ;; time the `ivy-state' is reset. This is needed for the
+            ;; "kill buffer" action.
+            #'counsel-projectile--project-buffers
+            :matcher #'ivy--switch-buffer-matcher
+            :require-match t
+            :sort counsel-projectile-sort-buffers
+            :action counsel-projectile-switch-to-buffer-action
+            :keymap counsel-projectile-switch-to-buffer-map
+            :caller 'counsel-projectile-switch-to-buffer))
+
+(ivy-set-display-transformer
+ 'counsel-projectile-switch-to-buffer
+ 'counsel-projectile-switch-to-buffer-transformer)
+
+;;;; counsel-projectile-grep
+
+(defcustom counsel-projectile-grep-initial-input nil
+  "Initial minibuffer input for `counsel-projectile-grep'.  If
+non-nil, it should be a Lisp expression whose evaluation yields
+the initial input string.
+
+Note that you can always insert the value
+of `(ivy-thing-at-point)' by hitting \"M-n\" in the minibuffer."
+  :type '(choice
+          (const :tag "None" nil)
+          (const :tag "Symbol at point (generic)" '(thing-at-point 'symbol t))
+          (const :tag "Symbol or selection at point (projectile)" '(projectile-symbol-or-selection-at-point))
+          (const :tag "Thing at point (ivy)" '(ivy-thing-at-point))
+          (sexp  :tag "Custom expression"))
+  :group 'counsel-projectile)
+
+(defvar counsel-projectile-grep-base-command "grep -rnE %s -- %%s ."
+  "Format string to use in `cousel-projectile-grep-function' to
+construct the command.")
+
+(defvar counsel-projectile-grep-command nil)
+
+(defvar counsel-projectile-grep-options-history nil
+  "History for `counsel-projectile-grep' options.")
+
+(defun counsel-projectile-grep-function (string)
+  "Grep for STRING in the current project."
+  (or (counsel-more-chars)
+      (let ((default-directory (ivy-state-directory ivy-last))
+            (regex (counsel-unquote-regex-parens
+                    (setq ivy--old-re
+                          (ivy--regex string)))))
+        (counsel--async-command (format counsel-projectile-grep-command
+                                        (shell-quote-argument regex)))
+        nil)))
+
+(defun counsel-projectile-grep-transformer (str)
+  "Higlight file and line number in STR, first removing the
+\"./\" prefix from the filename."
+  ;; This makes the display consistent with `counsel-git-grep' and
+  ;; `counsel-ag'-like commands.
+  (counsel-git-grep-transformer (string-remove-prefix "./" str)))
+
+(defun counsel-projectile-grep-occur ()
+  "Generate a custom occur buffer for `counsel-projectile-grep'."
+  ;; Copied from `counsel-grep-like-occur', except that we don't
+  ;; prepend "./" to the candidates since grep already does so.
+  (unless (eq major-mode 'ivy-occur-grep-mode)
+    (ivy-occur-grep-mode)
+    (setq default-directory (ivy-state-directory ivy-last)))
+  (setq ivy-text
+        (and (string-match "\"\\(.*\\)\"" (buffer-name))
+             (match-string 1 (buffer-name))))
+  (let* ((cmd (format counsel-projectile-grep-command
+                      (shell-quote-argument
+                       (counsel-unquote-regex-parens
+                        (ivy--regex ivy-text)))))
+         (cands (split-string (shell-command-to-string cmd) "\n" t)))
+    ;; Need precise number of header lines for `wgrep' to work.
+    (insert (format "-*- mode:grep; default-directory: %S -*-\n\n\n"
+                    default-directory))
+    (insert (format "%d candidates:\n" (length cands)))
+    (ivy--occur-insert-lines cands)))
+
+(defun counsel-projectile-grep (&optional options-or-cmd)
+  "Search the current project with grep.
+
+If inside a git project and `projectile-use-git-grep' is non-nil,
+use `counsel-git-grep'. Otherwise use grep recursively.
+
+OPTIONS-OR-CMD, if non-nil, is a string containing either
+additional options to be passed to grep, or an alternative git
+grep command. It is read from the minibuffer if the function is
+called with a prefix argument."
+  (interactive)
+  (if (and (eq (projectile-project-vcs) 'git)
+           projectile-use-git-grep)
+      (let ((counsel-prompt-function
+             (lambda ()
+               (ivy-add-prompt-count
+                (format "%s: " (projectile-prepend-project-name (ivy-state-prompt ivy-last)))))))
+        (counsel-git-grep (or current-prefix-arg options-or-cmd)
+                          counsel-projectile-grep-initial-input))
+    (counsel-require-program (car (split-string counsel-projectile-grep-base-command)))
+    (let* ((ignored-files (mapconcat (lambda (i)
+                                       (concat "--exclude="
+                                               (shell-quote-argument i)
+                                               " "))
+                                     (projectile-ignored-files-rel)
+                                     ""))
+           (ignored-dirs (mapconcat (lambda (i)
+                                      (concat "--exclude-dir="
+                                              (shell-quote-argument i)
+                                              " "))
+                                    (projectile-ignored-directories-rel)
+                                    ""))
+           (ignored (concat ignored-files ignored-dirs))
+           (options
+            (if current-prefix-arg
+                (read-string (projectile-prepend-project-name "grep options: ")
+                             ignored
+                             'counsel-projectile-grep-options-history)
+              (concat ignored options-or-cmd)))
+           (default-directory (projectile-project-root)))
+      (setq counsel-projectile-grep-command
+            (format counsel-projectile-grep-base-command options))
+      (ivy-set-prompt 'counsel-projectile-grep counsel-prompt-function)
+      (ivy-read (projectile-prepend-project-name "grep")
+                #'counsel-projectile-grep-function
+                :initial-input counsel-projectile-grep-initial-input
+                :dynamic-collection t
+                :keymap counsel-ag-map
+                :history 'counsel-git-grep-history
+                :action #'counsel-git-grep-action
+                :unwind (lambda ()
+                          (counsel-delete-process)
+                          (swiper--cleanup))
+                :caller 'counsel-projectile-grep))))
+
+(counsel-set-async-exit-code 'counsel-projectile-grep 1 "No matches found")
+(ivy-set-occur 'counsel-projectile-grep 'counsel-projectile-grep-occur)
+(ivy-set-display-transformer 'counsel-projectile-grep  'counsel-projectile-grep-transformer)
+
+;;;; counsel-projectile-ag
+
+(defcustom counsel-projectile-ag-initial-input nil
+  "Initial minibuffer input for `counsel-projectile-ag'.  If
+non-nil, it should be a Lisp expression whose evaluation yields
+the initial input string.
+
+Note that you can always insert the value
+of `(ivy-thing-at-point)' by hitting \"M-n\" in the minibuffer."
+  :type '(choice
+          (const :tag "None" nil)
+          (const :tag "Symbol at point (generic)" '(thing-at-point 'symbol t))
+          (const :tag "Symbol or selection at point (projectile)" '(projectile-symbol-or-selection-at-point))
+          (const :tag "Thing at point (ivy)" '(ivy-thing-at-point))
+          (sexp  :tag "Custom expression"))
+  :group 'counsel-projectile)
+
+(defvar counsel-projectile-ag-options-history nil
+  "History for `counsel-projectile-ag' options.")
+
+;;;###autoload
+(defun counsel-projectile-ag (&optional options)
+  "Search the current project with ag.
+
+OPTIONS, if non-nil, is a string containing additional options to
+be passed to ag. It is read from the minibuffer if the function
+is called with a prefix argument."
+  (interactive)
+  (let* ((ignored (mapconcat (lambda (i)
+                               (concat "--ignore "
+                                       (shell-quote-argument i)
+                                       " "))
+                             (append (projectile-ignored-files-rel)
+                                     (projectile-ignored-directories-rel))
+                             ""))
+         (options
+          (if current-prefix-arg
+              (read-string (projectile-prepend-project-name "ag options: ")
+                           ignored
+                           'counsel-projectile-ag-options-history)
+            (concat ignored options))))
+    (counsel-ag (eval counsel-projectile-ag-initial-input)
+                (projectile-project-root)
+                options
+                (projectile-prepend-project-name "ag"))))
+
+;;;; counsel-projectile-rg
+
+(defcustom counsel-projectile-rg-initial-input nil
+  "Initial minibuffer input for `counsel-projectile-rg'.  If
+non-nil, it should be a Lisp expression whose evaluation yields
+the initial input string.
+
+Note that you can always insert the value
+of `(ivy-thing-at-point)' by hitting \"M-n\" in the minibuffer."
+  :type '(choice
+          (const :tag "None" nil)
+          (const :tag "Symbol at point (generic)" '(thing-at-point 'symbol t))
+          (const :tag "Symbol or selection at point (projectile)" '(projectile-symbol-or-selection-at-point))
+          (const :tag "Thing at point (ivy)" '(ivy-thing-at-point))
+          (sexp  :tag "Custom expression"))
+  :group 'counsel-projectile)
+
+(defvar counsel-projectile-rg-options-history nil
+  "History for `counsel-projectile-rg' options.")
+
+;;;###autoload
+(defun counsel-projectile-rg (&optional options)
+  "Search the current project with rg.
+
+OPTIONS, if non-nil, is a string containing additional options to
+be passed to rg. It is read from the minibuffer if the function
+is called with a prefix argument."
+  (interactive)
+  (let* ((ignored (mapconcat (lambda (i)
+                               (concat "--glob "
+                                       (shell-quote-argument (concat "!" i))
+                                       " "))
+                             (append (projectile-ignored-files-rel)
+                                     (projectile-ignored-directories-rel))
+                             ""))
+         (options
+          (if current-prefix-arg
+              (read-string (projectile-prepend-project-name "rg options: ")
+                           ignored
+                           'counsel-projectile-rg-options-history)
+            (concat ignored options))))
+    (counsel-rg (eval counsel-projectile-rg-initial-input)
+                (projectile-project-root)
+                options
+                (projectile-prepend-project-name "rg"))))
+
+;;;; counsel-projectile-org-capture
+
+(defvar org-capture-templates)
+(defvar org-capture-templates-contexts)
+
+(defcustom counsel-projectile-org-capture-templates
+  '(("t" "[${name}] Task" entry (file+headline "${root}/notes.org" "Tasks")
+     "* TODO %?\n  %u\n  %a"))
+  "Project-specific templates for the creation of new entries
+with `counsel-projectile-org-capture'.
+
+The format is the same as in `org-capture-templates', except that
+in a template's name or target, the placeholders \"${root}\" and
+\"${name}\" can be used to stand for the current project root and
+name, respectively.
+
+The default value contains a single template, whose name is
+\"[${name}] Task\" and whose target is:
+
+    \(file+headline \"${root}/notes.org}\" \"Tasks\"\)
+
+This points to headline \"Tasks\" in file \"notes.org\" in the
+project root directory (one file per project).
+
+Two other examples of valid targets are:
+
+    \(file+headline \"${root}/${name}.org}\" \"Tasks\"\)
+    \(file+olp \"~/notes.org\" \"${root}\" \"Tasks\"\)
+
+The first one is similar to the default value's target, except
+that the file is named after the project name (this can be handy
+if you use org-mode's agenda since the project name is then
+displayed as category). The second one points to outline path
+\"<project-root>/Tasks\" in file \"~/notes.org\" (same file for
+all projects)."
+  :type ;; copied from `org-capture-templates'
+  (let ((file-variants '(choice :tag "Filename       "
+                                (file :tag "Literal")
+                                (function :tag "Function")
+                                (variable :tag "Variable")
+                                (sexp :tag "Form"))))
+    `(repeat
+      (choice :value ("" "" entry (file "~/org/notes.org") "")
+              (list :tag "Multikey description"
+                    (string :tag "Keys       ")
+                    (string :tag "Description"))
+              (list :tag "Template entry"
+                    (string :tag "Keys           ")
+                    (string :tag "Description    ")
+                    (choice :tag "Capture Type   " :value entry
+                            (const :tag "Org entry" entry)
+                            (const :tag "Plain list item" item)
+                            (const :tag "Checkbox item" checkitem)
+                            (const :tag "Plain text" plain)
+                            (const :tag "Table line" table-line))
+                    (choice :tag "Target location"
+                            (list :tag "File"
+                                  (const :format "" file)
+                                  ,file-variants)
+                            (list :tag "ID"
+                                  (const :format "" id)
+                                  (string :tag "  ID"))
+                            (list :tag "File & Headline"
+                                  (const :format "" file+headline)
+                                  ,file-variants
+                                  (string :tag "  Headline"))
+                            (list :tag "File & Outline path"
+                                  (const :format "" file+olp)
+                                  ,file-variants
+                                  (repeat :tag "Outline path" :inline t
+                                          (string :tag "Headline")))
+                            (list :tag "File & Regexp"
+                                  (const :format "" file+regexp)
+                                  ,file-variants
+                                  (regexp :tag "  Regexp"))
+                            (list :tag "File [ & Outline path ] & Date tree"
+                                  (const :format "" file+olp+datetree)
+                                  ,file-variants
+                                  (option (repeat :tag "Outline path" :inline t
+                                                  (string :tag "Headline"))))
+                            (list :tag "File & function"
+                                  (const :format "" file+function)
+                                  ,file-variants
+                                  (sexp :tag "  Function"))
+                            (list :tag "Current clocking task"
+                                  (const :format "" clock))
+                            (list :tag "Function"
+                                  (const :format "" function)
+                                  (sexp :tag "  Function")))
+                    (choice :tag "Template       "
+                            (string)
+                            (list :tag "File"
+                                  (const :format "" file)
+                                  (file :tag "Template file"))
+                            (list :tag "Function"
+                                  (const :format "" function)
+                                  (function :tag "Template function")))
+                    (plist :inline t
+                           ;; Give the most common options as checkboxes
+                           :options (((const :format "%v " :prepend) (const t))
+                                     ((const :format "%v " :immediate-finish) (const t))
+                                     ((const :format "%v " :jump-to-captured) (const t))
+                                     ((const :format "%v " :empty-lines) (const 1))
+                                     ((const :format "%v " :empty-lines-before) (const 1))
+                                     ((const :format "%v " :empty-lines-after) (const 1))
+                                     ((const :format "%v " :clock-in) (const t))
+                                     ((const :format "%v " :clock-keep) (const t))
+                                     ((const :format "%v " :clock-resume) (const t))
+                                     ((const :format "%v " :time-prompt) (const t))
+                                     ((const :format "%v " :tree-type) (const week))
+                                     ((const :format "%v " :unnarrowed) (const t))
+                                     ((const :format "%v " :table-line-pos) (string))
+                                     ((const :format "%v " :kill-buffer) (const t))))))))
+  :group 'counsel-projectile)
+
+(defcustom counsel-projectile-org-capture-templates-contexts nil
+  "Alist of capture templates and valid contexts for `counsel-projectile-org-capture'.
+
+The format is the same as in `org-capture-templates-contexts'."
+  :type ;; copied from `org-capture-target-templates'
+  '(repeat (list :tag "Rule"
+                 (string :tag "        Capture key")
+                 (string :tag "Replace by template")
+                 (repeat :tag "Available when"
+                         (choice
+                          (cons :tag "Condition"
+                                (choice
+                                 (const :tag "In file" in-file)
+                                 (const :tag "Not in file" not-in-file)
+                                 (const :tag "In buffer" in-buffer)
+                                 (const :tag "Not in buffer" not-in-buffer)
+                                 (const :tag "In mode" in-mode)
+                                 (const :tag "Not in mode" not-in-mode))
+                                (regexp))
+                          (function :tag "Custom function")))))
+  :group 'counsel-projectile)
+
+;;;###autoload
+(defun counsel-projectile-org-capture (&optional from-buffer)
+  "Capture into the current project.
+
+This command is a replacement for `org-capture' (or
+`counsel-org-capture') offering project-specific capture
+templates, in addition to the regular templates available from
+`org-capture'. These project templates, which are \"expanded\"
+relatively to the current project, are determined by the
+variables `counsel-projectile-org-capture-templates' and
+`counsel-projectile-org-capture-templates-contexts'. See the
+former variable in particular for details.
+
+Optional argument FROM-BUFFER specifies the buffer from which to
+capture."
+  (interactive)
+  (require 'org-capture)
+  (let* ((root (ignore-errors (projectile-project-root)))
+         (name (projectile-project-name))
+         (org-capture-templates-contexts
+          (append (when root
+                    counsel-projectile-org-capture-templates-contexts)
+                  org-capture-templates-contexts))
+         (org-capture-templates
+          (append
+           (when root
+             (cl-loop
+              with replace-fun = `(lambda (string)
+                                    (replace-regexp-in-string
+                                     "\\${[^}]+}"
+                                     (lambda (s)
+                                       (pcase s
+                                         ("${root}" ,root)
+                                         ("${name}" ,name)))
+                                     string))
+              for template in counsel-projectile-org-capture-templates
+              collect (cl-loop
+                       for item in template
+                       if (= (cl-position item template) 1) ;; template's name
+                       collect (funcall replace-fun item)
+                       else if (= (cl-position item template) 3) ;; template's target
+                       collect (cl-loop
+                                for x in item
+                                if (stringp x)
+                                collect (funcall replace-fun x)
+                                else
+                                collect x)
+                       else
+                       collect item)))
+           org-capture-templates)))
+    (with-current-buffer (or from-buffer (current-buffer))
+      (counsel-org-capture))))
+
+;;;; counsel-projectile-org-agenda
+
+;;;###autoload
+(defun counsel-projectile-org-agenda (&optional arg org-keys restriction)
+  "Open project agenda.
+
+This command simply calls `org-agenda' after filtering out all
+agenda files that do not belong to the current project.
+
+Optional arguments ARG, ORG-KEYS, and RESTRICTION are as in
+`org-agenda'."
+  (interactive "P")
+  (let* ((root (projectile-project-root))
+         (org-agenda-files
+          (cl-remove-if-not (lambda (file)
+                              (string-prefix-p root file))
+                            (org-agenda-files t 'ifmode))))
+    (org-agenda arg org-keys restriction)))
+
+;;;; counsel-projectile-switch-project
+
+(defcustom counsel-projectile-sort-projects nil
+  "Non-nil if projects should be sorted in
+`counsel-projectile-switch-project'.
+
+The sorting function can be modified by adding an entry for
+`counsel-projectile-switch-project' in
+`ivy-sort-functions-alist'."
+  :type 'boolean
+  :group 'counsel-projectile)
+
+(defcustom counsel-projectile-remove-current-project nil
+  "Non-nil if current project should be removed from the
+candidates list of `counsel-projectile-switch-project'."
+  :type 'boolean
+  :group 'counsel-projectile)
+
+(counsel-projectile--defcustom-action
+ 'counsel-projectile-switch-project
+ '(1
+   ("o" counsel-projectile-switch-project-action
+    "jump to a project buffer or file")
+   ("f" counsel-projectile-switch-project-action-find-file
+    "jump to a project file")
+   ("d" counsel-projectile-switch-project-action-find-dir
+    "jump to a project directory")
+   ("b" counsel-projectile-switch-project-action-switch-to-buffer
+    "jump to a project buffer")
+   ("m" counsel-projectile-switch-project-action-find-file-manually
+    "find file manually from project root")
+   ("S" counsel-projectile-switch-project-action-save-all-buffers
+    "save all project buffers")
+   ("k" counsel-projectile-switch-project-action-kill-buffers
+    "kill all project buffers")
+   ("K" counsel-projectile-switch-project-action-remove-known-project
+    "remove project from known projects")
+   ("c" counsel-projectile-switch-project-action-compile
+    "run project compilation command")
+   ("C" counsel-projectile-switch-project-action-configure
+    "run project configure command")
+   ("E" counsel-projectile-switch-project-action-edit-dir-locals
+    "edit project dir-locals")
+   ("v" counsel-projectile-switch-project-action-vc
+    "open project in vc-dir / magit / monky")
+   ("sg" counsel-projectile-switch-project-action-grep
+    "search project with grep")
+   ("ss" counsel-projectile-switch-project-action-ag
+    "search project with ag")
+   ("sr" counsel-projectile-switch-project-action-rg
+    "search project with rg")
+   ("xs" counsel-projectile-switch-project-action-run-shell
+    "invoke shell from project root")
+   ("xe" counsel-projectile-switch-project-action-run-eshell
+    "invoke eshell from project root")
+   ("xt" counsel-projectile-switch-project-action-run-term
+    "invoke term from project root")
+   ("Oc" counsel-projectile-switch-project-action-org-capture
+    "capture into project")
+   ("Oa" counsel-projectile-switch-project-action-org-capture
+    "open project agenda"))
+ 'counsel-projectile)
+
+(defun counsel-projectile-switch-project-by-name (project)
+  "Switch to PROJECT.
+Invokes the command referenced by
+`projectile-switch-project-action' on switch.
+
+This is a replacement for `projectile-switch-project-by-name'
+with a different switching mechanism: the switch-project action
+is called from a dedicated buffer rather than the initial buffer.
+Also, PROJECT's dir-local variables are loaded before calling the
+action."
+  (run-hooks 'projectile-before-switch-project-hook)
+  ;; Kill and recreate the switch buffer to get rid of any local
+  ;; variable
+  (ignore-errors (kill-buffer " *counsel-projectile*"))
+  (set-buffer (get-buffer-create " *counsel-projectile*"))
+  (setq default-directory project)
+  ;; Load the project dir-local variables into the switch buffer, so
+  ;; the action can make use of them
+  (hack-dir-local-variables-non-file-buffer)
+  (funcall projectile-switch-project-action)
+  ;; If the action relies on `ivy-read' then, after one of its
+  ;; `ivy-read' actions is executed, the current buffer will be set
+  ;; back to the initial buffer. Hence we make sure tu evaluate
+  ;; `projectile-after-switch-project-hook' from the switch buffer.
+  (with-current-buffer " *counsel-projectile*"
+    (run-hooks 'projectile-after-switch-project-hook)))
+
+(defun counsel-projectile-switch-project-action (project)
+  "Jump to a file or buffer in PROJECT."
+  (let ((projectile-switch-project-action
+         (lambda ()
+           (counsel-projectile ivy-current-prefix-arg))))
+    (counsel-projectile-switch-project-by-name project)))
+
+(defun counsel-projectile-switch-project-action-find-file (project)
+  "Jump to a file in PROJECT."
+  (let ((projectile-switch-project-action
+         (lambda ()
+           (counsel-projectile-find-file ivy-current-prefix-arg))))
+    (counsel-projectile-switch-project-by-name project)))
+
+(defun counsel-projectile-switch-project-action-find-file-manually (project)
+  "Call `find-file' from PROJECT's root."
+  (let ((projectile-switch-project-action
+         (lambda ()
+           (counsel-find-file project))))
+    (counsel-projectile-switch-project-by-name project)))
+
+(defun counsel-projectile-switch-project-action-find-dir (project)
+  "Jump to a directory in PROJECT."
+  (let ((projectile-switch-project-action
+         (lambda ()
+           (counsel-projectile-find-dir ivy-current-prefix-arg))))
+    (counsel-projectile-switch-project-by-name project)))
+
+(defun counsel-projectile-switch-project-action-switch-to-buffer (project)
+  "Jump to a buffer in PROJECT."
+  (let ((projectile-switch-project-action 'counsel-projectile-switch-to-buffer))
+    (counsel-projectile-switch-project-by-name project)))
+
+(defun counsel-projectile-switch-project-action-save-all-buffers (project)
+  "Save all buffers in PROJECT."
+  (let ((projectile-switch-project-action 'projectile-save-project-buffers))
+    (counsel-projectile-switch-project-by-name project)))
+
+(defun counsel-projectile-switch-project-action-kill-buffers (project)
+  "Kill all buffers in PROJECT."
+  (let ((projectile-switch-project-action 'projectile-kill-buffers))
+    (counsel-projectile-switch-project-by-name project)))
+
+(defun counsel-projectile-switch-project-action-remove-known-project (project)
+  "Remove PROJECT from the list of known projects."
+  (projectile-remove-known-project project)
+  (setq ivy--all-candidates
+        (delete project ivy--all-candidates))
+  (ivy--reset-state ivy-last))
+
+(defun counsel-projectile-switch-project-action-compile (project)
+  "Run PROJECT compliation command."
+  (let ((projectile-switch-project-action
+         (lambda ()
+           (projectile-compile-project ivy-current-prefix-arg))))
+    (counsel-projectile-switch-project-by-name project)))
+
+(defun counsel-projectile-switch-project-action-configure (project)
+  "Run PROJECT configure command."
+  (let ((projectile-switch-project-action
+         (lambda ()
+           (projectile-configure-project ivy-current-prefix-arg))))
+    (counsel-projectile-switch-project-by-name project)))
+
+(defun counsel-projectile-switch-project-action-edit-dir-locals (project)
+  "Edit PROJECT's dir-locals."
+  (let ((projectile-switch-project-action 'projectile-edit-dir-locals))
+    (counsel-projectile-switch-project-by-name project)))
+
+(defun counsel-projectile-switch-project-action-vc (project)
+  "Open PROJECT in vc-dir / magit / monky."
+  (let ((projectile-switch-project-action 'projectile-vc))
+    (counsel-projectile-switch-project-by-name project)))
+
+(defun counsel-projectile-switch-project-action-run-shell (project)
+  "Invoke `shell' from PROJECT's root."
+  (let ((projectile-switch-project-action 'projectile-run-shell))
+    (counsel-projectile-switch-project-by-name project)))
+
+(defun counsel-projectile-switch-project-action-run-eshell (project)
+  "Invoke `eshell' from PROJECT's root."
+  (let ((projectile-switch-project-action 'projectile-run-eshell))
+    (counsel-projectile-switch-project-by-name project)))
+
+(defun counsel-projectile-switch-project-action-run-term (project)
+  "Invoke `term' from PROJECT's root."
+  (let ((projectile-switch-project-action
+         (lambda ()
+           (projectile-run-term nil))))
+    (counsel-projectile-switch-project-by-name project)))
+
+(defun counsel-projectile-switch-project-action-grep (project)
+  "Search PROJECT with `grep'."
+  (let ((projectile-switch-project-action 'counsel-projectile-grep))
+    (counsel-projectile-switch-project-by-name project)))
+
+(defun counsel-projectile-switch-project-action-ag (project)
+  "Search PROJECT with `ag'."
+  (let ((projectile-switch-project-action 'counsel-projectile-ag))
+    (counsel-projectile-switch-project-by-name project)))
+
+(defun counsel-projectile-switch-project-action-rg (project)
+  "Search PROJECT with `rg'."
+  (let ((projectile-switch-project-action 'counsel-projectile-rg))
+    (counsel-projectile-switch-project-by-name project)))
+
+(defun counsel-projectile-switch-project-action-org-capture (project)
+  "Org-capture into PROJECT."
+  (let* ((from-buffer (ivy-state-buffer ivy-last))
+         (projectile-switch-project-action `(lambda ()
+                                              (counsel-projectile-org-capture ,from-buffer))))
+    (counsel-projectile-switch-project-by-name project)))
+
+;;;###autoload
+(defun counsel-projectile-switch-project ()
+  "Switch project."
+  (interactive)
+  (ivy-read (projectile-prepend-project-name "Switch to project: ")
+            (if counsel-projectile-remove-current-project
+                (projectile-relevant-known-projects)
+              projectile-known-projects)
+            :preselect (and (projectile-project-p)
+                            (abbreviate-file-name (projectile-project-root)))
+            :action counsel-projectile-switch-project-action
+            :require-match t
+            :sort counsel-projectile-sort-projects
+            :caller 'counsel-projectile-switch-project))
+
+;;;; counsel-projectile
+
+(counsel-projectile--defcustom-action
+ 'counsel-projectile
+ '(1
+   ("o" counsel-projectile-action
+    "current window")
+   ("j" counsel-projectile-action-other-window
+    "other window")
+   ("k" counsel-projectile-action-kill-buffer
+    "kill buffer")
+   ("x" counsel-projectile-action-file-extern
+    "open file externally")
+   ("r" counsel-projectile-action-file-root
+    "open file as root")
+   ("m" counsel-projectile-action-find-file-manually
+    "find file manually")
+   ("p" (lambda (_) (counsel-projectile-switch-project))
+    "switch project"))
+ 'counsel-projectile)
+
+(defvar counsel-projectile-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "C-c C-k") (lambda ()
+                                      (interactive)
+                                      (counsel-projectile-action-kill-buffer (ivy-state-current ivy-last))))
+    map)
+  "Keymap for `counsel-projectile'.")
+
+(defvar counsel-projectile--buffers nil
+  "Stores a list of project buffers.")
+
+(defvar counsel-projectile--non-visited-files nil
+  "Stores a list of project files that are not currently
+  visited by a buffer.")
+
+(defun counsel-projectile--project-buffers-and-files (&rest _)
+  ;; The ignored arguments are so that the function can be used as
+  ;; collection function in `counsel-projectile'.
+  "Return a list of buffers and non-visited files in the current
+  project.  Buffers and files are separately sorted depending on
+  `counsel-projectile-sort-buffers' and
+  `counsel-projectile-sort-files', respectively."
+  (let ((buffers (counsel-projectile--project-buffers))
+        (files (projectile-current-project-files))
+        (root (projectile-project-root))
+        file sort-fn)
+    ;; Remove files that are visited by a buffer:
+    (dolist (buffer buffers files)
+      (when (setq file (buffer-file-name (get-buffer buffer)))
+        (setq files (remove (file-relative-name file root) files))))
+    ;; Sort buffers and files depending on
+    ;; `counsel-projectile-sort-buffers' and
+    ;; `counsel-projectile-sort-files', respectively.
+    ;; We need to do this here because matching will be done against
+    ;; the variables `counsel-projectile--buffers' and
+    ;; `counsel-projectile--non-visited-files', not against the
+    ;; returned collection, so ivy's native sorting mechanism won't
+    ;; work.
+    (when (and counsel-projectile-sort-buffers
+               (<= (length buffers) ivy-sort-max-size)
+               (setq sort-fn (ivy--sort-function 'counsel-projectile-switch-to-buffer)))
+      (setq buffers (sort (copy-sequence buffers) sort-fn)))
+    (when (and counsel-projectile-sort-files
+               (<= (length files) ivy-sort-max-size)
+               (setq sort-fn (ivy--sort-function 'counsel-projectile-find-file)))
+      (setq files (sort (copy-sequence files) sort-fn)))
+    ;; Finally, bind `counsel-projectile--buffers' and
+    ;; `counsel-projectile--non-visited-files' and return the whole
+    ;; collection.
+    (append (setq counsel-projectile--buffers buffers)
+            (setq counsel-projectile--non-visited-files files))))
+
+(defun counsel-projectile--matcher (regexp _candidates)
+  "Return REGEXP-matching CANDIDATES for `counsel-projectile'.
+
+Relies on `ivy--switch-buffer-matcher' for buffers and the
+matcher specified in `counsel-projectile-find-file-matcher' for
+files."
+  (append (ivy--switch-buffer-matcher regexp counsel-projectile--buffers)
+          (funcall counsel-projectile-find-file-matcher regexp counsel-projectile--non-visited-files)))
+
+(defun counsel-projectile-action (name)
+  "Switch to buffer or find file named NAME."
+  (if (member name counsel-projectile--buffers)
+      (counsel-projectile-switch-to-buffer-action name)
+    (counsel-projectile-find-file-action name)))
+
+(defun counsel-projectile-action-other-window (name)
+  "Switch to buffer or find file named NAME in another window."
+  (if (member name counsel-projectile--buffers)
+      (switch-to-buffer-other-window name)
+    (counsel-projectile-find-file-action-other-window name)))
+
+(defun counsel-projectile-action-kill-buffer (name)
+  "Kill buffer named NAME."
+  (if (member name counsel-projectile--buffers)
+      (ivy--kill-buffer-action name)
+    (message "This action only applies to buffers.")))
+  
+(defun counsel-projectile-action-find-file-manually (name)
+  "Call `counsel-find-file' from default directory of buffer
+directory of file named NAME."
+  (if (member name counsel-projectile--buffers)
+      (counsel-projectile-switch-to-buffer-action-find-file-manually name)
+    (counsel-projectile-find-file-action-find-file-manually name)))
+
+(defun counsel-projectile-action-file-extern (name)
+  "Find file named NAME externally."
+  (if (member name counsel-projectile--buffers)
+      (message "This action does not apply to buffers.")
+    (counsel-projectile-find-file-action-extern name)))
+
+(defun counsel-projectile-action-file-root (name)
+  "Find file named NAME as root."
+  (if (member name counsel-projectile--buffers)
+      (message "This action does not apply to buffers.")
+    (counsel-projectile-find-file-action-root name)))
+
+(defun counsel-projectile-transformer (str)
+  "Fontifies modified, file-visiting buffers as well as non-visited files."
+  (if (member str counsel-projectile--buffers)
+      (counsel-projectile-switch-to-buffer-transformer str)
+    (propertize str 'face 'ivy-virtual)))
+
+;;;###autoload
+(defun counsel-projectile (&optional arg)
+  "Jump to a buffer or file in the current project.
+
+With a prefix ARG, invalidate the cache first.
+
+If not inside a project, call `counsel-projectile-switch-project'."
+  (interactive "P")
+  (if (not (projectile-project-p))
+      (counsel-projectile-switch-project)
+    (projectile-maybe-invalidate-cache arg)
+    (ivy-read (projectile-prepend-project-name "Load buffer or file: ")
+              ;; We use a collection function so that it is called each
+              ;; time the `ivy-state' is reset. This is needed for the
+              ;; "kill buffer" action.
+              #'counsel-projectile--project-buffers-and-files
+              :matcher #'counsel-projectile--matcher
+              :require-match t
+              :action counsel-projectile-action
+              :keymap counsel-projectile-map
+              :caller 'counsel-projectile)))
+
+(ivy-set-display-transformer
+ 'counsel-projectile
+ 'counsel-projectile-transformer)
+
+;;;; counsel-projectile-mode
+
+(defvar counsel-projectile-command-map
+  (let ((map (make-sparse-keymap)))
+    (set-keymap-parent map projectile-command-map)
+    (define-key map (kbd "s r") 'counsel-projectile-rg)
+    (define-key map (kbd "O c") 'counsel-projectile-org-capture)
+    (define-key map (kbd "O a") 'counsel-projectile-org-agenda)
+    (define-key map (kbd "SPC") 'counsel-projectile)
+    map)
+  "Keymap for Counesl-Projectile commands after `projectile-keymap-prefix'.")
+(fset 'counsel-projectile-command-map counsel-projectile-command-map)
+
+(defvar counsel-projectile-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map projectile-keymap-prefix 'counsel-projectile-command-map)
+    (define-key map [remap projectile-find-file] 'counsel-projectile-find-file)
+    (define-key map [remap projectile-find-dir] 'counsel-projectile-find-dir)
+    (define-key map [remap projectile-switch-to-buffer] 'counsel-projectile-switch-to-buffer)
+    (define-key map [remap projectile-grep] 'counsel-projectile-grep)
+    (define-key map [remap projectile-ag] 'counsel-projectile-ag)
+    (define-key map [remap projectile-switch-project] 'counsel-projectile-switch-project)
+    map)
+  "Keymap for Counsel-Projectile mode.")
+
+;;;###autoload
+(define-minor-mode counsel-projectile-mode
+  "Toggle Counsel-Projectile mode on or off.
+
+With a prefix argument ARG, enable the mode if ARG is positive,
+and disable it otherwise.  If called from Lisp, enable the mode
+if ARG is omitted or nil, and toggle it if ARG is `toggle'.
+
+Counsel-Projectile mode triggers Projectile mode, remaps
+Projectile commands that have counsel replacements, and adds key
+bindings for Counsel-Projectile commands that have no Projectile
+counterpart.
+
+\\{counsel-projectile-mode-map}"
+  :group 'counsel-projectile
+  :require 'counsel-projectile
+  :keymap counsel-projectile-mode-map
+  :global t
+  (if counsel-projectile-mode
+      (projectile-mode)
+    (projectile-mode -1)))
+
+;;;; provide
+
+(provide 'counsel-projectile)
+
+;;; counsel-projectile.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/counsel-projectile-20180718.842/counsel-projectile.elc b/configs/shared/emacs/.emacs.d/elpa/counsel-projectile-20180718.842/counsel-projectile.elc
new file mode 100644
index 0000000000..50403f5dcd
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/counsel-projectile-20180718.842/counsel-projectile.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/cycle-themes-20150402.2009/cycle-themes-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/cycle-themes-20150402.2009/cycle-themes-autoloads.el
new file mode 100644
index 0000000000..41c91abee4
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cycle-themes-20150402.2009/cycle-themes-autoloads.el
@@ -0,0 +1,32 @@
+;;; cycle-themes-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "cycle-themes" "cycle-themes.el" (23377 61283
+;;;;;;  849762 346000))
+;;; Generated autoloads from cycle-themes.el
+
+(defvar cycle-themes-mode nil "\
+Non-nil if Cycle-Themes mode is enabled.
+See the `cycle-themes-mode' command
+for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `cycle-themes-mode'.")
+
+(custom-autoload 'cycle-themes-mode "cycle-themes" nil)
+
+(autoload 'cycle-themes-mode "cycle-themes" "\
+Minor mode for cycling between themes.
+
+\(fn &optional ARG)" t nil)
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; cycle-themes-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/cycle-themes-20150402.2009/cycle-themes-pkg.el b/configs/shared/emacs/.emacs.d/elpa/cycle-themes-20150402.2009/cycle-themes-pkg.el
new file mode 100644
index 0000000000..5a7632b001
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cycle-themes-20150402.2009/cycle-themes-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "cycle-themes" "20150402.2009" "A global minor mode to make switching themes easier" '((cl-lib "0.5")))
diff --git a/configs/shared/emacs/.emacs.d/elpa/cycle-themes-20150402.2009/cycle-themes.el b/configs/shared/emacs/.emacs.d/elpa/cycle-themes-20150402.2009/cycle-themes.el
new file mode 100644
index 0000000000..0a936f71ee
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cycle-themes-20150402.2009/cycle-themes.el
@@ -0,0 +1,155 @@
+;;; cycle-themes.el --- A global minor mode to make switching themes easier
+
+;; Copyright (C) 2015 Katherine Whitlock
+;;
+;; Authors: Katherine Whitlock <toroidalcode@gmail.com>
+;; URL: http://github.com/toroidal-code/cycle-themes.el
+;; Package-Version: 20150402.2009
+;; Version: 1.0
+;; Package-Requires: ((cl-lib "0.5"))
+;; Keywords: Themes, Utility, Global Minor Mode
+
+;; This file is not part of GNU Emacs.
+
+;;; Commentary:
+
+;; Allows switching between themes easily.
+
+;;; Installation
+
+;; In your Emacs config, define a list of themes you want to be
+;; able to switch between.  Then, enable the global minor mode.
+;;
+;;     (setq cycle-themes-theme-list
+;;           '(leuven monokai solarized-dark))
+;;     (require 'cycle-themes)
+;;     (cycle-themes-mode)
+;;
+;; `cycle-themes' is bound to 'C-c C-t' by default.
+;;
+;; You can optionally add hooks to be run after switching themes:
+;;
+;; (add-hook 'cycle-themes-after-cycle-hook
+;;           #'(lambda () (Do-something-fn ...)))
+;;
+
+;;; License:
+
+;; This program 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.
+;;
+;; This program 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; see the file COPYING.  If not, write to the Free Software
+;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+;; USA.
+
+;;; Code:
+
+(eval-when-compile
+  (require 'cl-lib))
+
+(defgroup cycle-themes nil
+  "The cycle-themes group"
+  :group 'appearance
+  :prefix "cycle-themes-")
+
+(defcustom cycle-themes-after-cycle-hook nil
+  "Hooks that are run after switching themes."
+  :group 'cycle-themes
+  :type 'hook)
+
+(defcustom cycle-themes-theme-list (custom-available-themes)
+  "The list of themes to cycle through on calling `cycle-themes'."
+  :group 'cycle-themes
+  :type '(list symbol))
+
+(defcustom cycle-themes-allow-multiple-themes nil
+  "Whether to allow the application of more than one theme at once."
+  :group 'cycle-themes
+  :type 'boolean)
+
+(defconst cycle-themes-last-theme-set custom-enabled-themes
+  "Used with multiple theme layering.")
+
+(defconst cycle-themes-first-start t
+  "load-theme reapplies all minor-modes, so we need this to avoid a stack overflow.")
+
+(defun cycle-themes-get-next-valid-theme ()
+  "Get the next valid theme from the list."
+  ;; save our starting theme for a infinite-loop check
+  ;; if there's no theme applied,
+  (let* ((start-theme (or (first custom-enabled-themes)
+                          (car (last cycle-themes-theme-list))))
+         (current-theme start-theme))
+    ;; do-while
+    (while
+        (progn
+          ;; Fancy way to move to the next theme
+          ;; with modular arithmetic so we never reach the end.
+          (setq current-theme
+                (nth (mod (1+ (cl-position current-theme cycle-themes-theme-list))
+                          (length cycle-themes-theme-list))
+                     cycle-themes-theme-list))
+          ;; Make sure we didn't loop all the way through
+          (when (eq current-theme start-theme)
+            (error "No valid themes in cycle-themes-theme-list"))
+          (not (custom-theme-p current-theme))))
+    current-theme))
+
+
+(defun cycle-themes ()
+  "Cycle to the next theme."
+  (interactive)
+  (let ((new-theme (cycle-themes-get-next-valid-theme))
+        (current-theme (first custom-enabled-themes))
+        (current-theme-set custom-enabled-themes))
+    ;; disable the current theme only if we want multiple themes
+    ;; and we had it before
+    (unless (and cycle-themes-allow-multiple-themes
+                 (member current-theme cycle-themes-last-theme-set))
+      (disable-theme current-theme))
+    (load-theme new-theme t)
+    (setq cycle-themes-last-theme-set current-theme-set)
+    (run-hooks 'cycle-themes-after-cycle-hook)))
+
+;;;###autoload
+(define-minor-mode cycle-themes-mode
+  "Minor mode for cycling between themes."
+  :lighter ""
+  :keymap (let ((map (make-sparse-keymap)))
+            (define-key map (kbd "C-c C-t") 'cycle-themes)
+            map)
+  :global t
+  (progn
+    ;; remove any lingering themes other than the primary
+    (dolist (theme (cl-set-difference (custom-available-themes)
+                                      custom-enabled-themes))
+      (disable-theme theme))
+
+    ;; If we _aren't_ already trying to start up
+    (when cycle-themes-first-start
+      (setq cycle-themes-first-start nil)
+
+      ;; if there are no themes enabled, enable
+      ;; the first one in the list
+      (if (null custom-enabled-themes)
+          (add-hook 'emacs-startup-hook
+                    #'(lambda ()
+                        (load-theme (car cycle-themes-theme-list))
+                        (run-hooks 'cycle-themes-after-cycle-hook)))
+        
+        ;; otherwise, ensure they're _actually_ loaded
+        (add-hook 'emacs-startup-hook #'(lambda ()
+                                          (dolist (theme (reverse custom-enabled-themes))
+                                            (load-theme theme))
+                                          (run-hooks 'cycle-themes-after-cycle-hook)))))))
+
+(provide 'cycle-themes)
+;;; cycle-themes.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/cycle-themes-20150402.2009/cycle-themes.elc b/configs/shared/emacs/.emacs.d/elpa/cycle-themes-20150402.2009/cycle-themes.elc
new file mode 100644
index 0000000000..29bde165f3
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/cycle-themes-20150402.2009/cycle-themes.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/dash-20180413.30/dash-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/dash-20180413.30/dash-autoloads.el
new file mode 100644
index 0000000000..f32ce6e298
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/dash-20180413.30/dash-autoloads.el
@@ -0,0 +1,15 @@
+;;; dash-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil nil ("dash.el") (23377 60758 277481 359000))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; dash-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/dash-20180413.30/dash-pkg.el b/configs/shared/emacs/.emacs.d/elpa/dash-20180413.30/dash-pkg.el
new file mode 100644
index 0000000000..26af393fa9
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/dash-20180413.30/dash-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "dash" "20180413.30" "A modern list library for Emacs" 'nil)
diff --git a/configs/shared/emacs/.emacs.d/elpa/dash-20180413.30/dash.el b/configs/shared/emacs/.emacs.d/elpa/dash-20180413.30/dash.el
new file mode 100644
index 0000000000..c0553497ba
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/dash-20180413.30/dash.el
@@ -0,0 +1,2800 @@
+;;; dash.el --- A modern list library for Emacs  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2012-2016 Free Software Foundation, Inc.
+
+;; Author: Magnar Sveen <magnars@gmail.com>
+;; Version: 2.14.1
+;; Package-Version: 20180413.30
+;; Keywords: lists
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; A modern list api for Emacs.
+;;
+;; See documentation on https://github.com/magnars/dash.el#functions
+;;
+;; **Please note** The lexical binding in this file is not utilised at the
+;; moment. We will take full advantage of lexical binding in an upcoming 3.0
+;; release of Dash. In the meantime, we've added the pragma to avoid a bug that
+;; you can read more about in https://github.com/magnars/dash.el/issues/130.
+;;
+
+;;; Code:
+
+(defgroup dash ()
+  "Customize group for dash.el"
+  :group 'lisp
+  :prefix "dash-")
+
+(defun dash--enable-fontlock (symbol value)
+  (when value
+    (dash-enable-font-lock))
+  (set-default symbol value))
+
+(defcustom dash-enable-fontlock nil
+  "If non-nil, enable fontification of dash functions, macros and
+special values."
+  :type 'boolean
+  :set 'dash--enable-fontlock
+  :group 'dash)
+
+(defmacro !cons (car cdr)
+  "Destructive: Set CDR to the cons of CAR and CDR."
+  `(setq ,cdr (cons ,car ,cdr)))
+
+(defmacro !cdr (list)
+  "Destructive: Set LIST to the cdr of LIST."
+  `(setq ,list (cdr ,list)))
+
+(defmacro --each (list &rest body)
+  "Anaphoric form of `-each'."
+  (declare (debug (form body))
+           (indent 1))
+  (let ((l (make-symbol "list")))
+    `(let ((,l ,list)
+           (it-index 0))
+       (while ,l
+         (let ((it (car ,l)))
+           ,@body)
+         (setq it-index (1+ it-index))
+         (!cdr ,l)))))
+
+(defmacro -doto (eval-initial-value &rest forms)
+  "Eval a form, then insert that form as the 2nd argument to other forms.
+The EVAL-INITIAL-VALUE form is evaluated once. Its result is
+passed to FORMS, which are then evaluated sequentially. Returns
+the target form."
+  (declare (indent 1))
+  (let ((retval (make-symbol "value")))
+    `(let ((,retval ,eval-initial-value))
+       ,@(mapcar (lambda (form)
+                   (if (sequencep form)
+                       `(,(-first-item form) ,retval ,@(cdr form))
+                     `(funcall form ,retval)))
+                 forms)
+       ,retval)))
+
+(defun -each (list fn)
+  "Call FN with every item in LIST. Return nil, used for side-effects only."
+  (--each list (funcall fn it)))
+
+(put '-each 'lisp-indent-function 1)
+
+(defalias '--each-indexed '--each)
+
+(defun -each-indexed (list fn)
+  "Call (FN index item) for each item in LIST.
+
+In the anaphoric form `--each-indexed', the index is exposed as symbol `it-index'.
+
+See also: `-map-indexed'."
+  (--each list (funcall fn it-index it)))
+(put '-each-indexed 'lisp-indent-function 1)
+
+(defmacro --each-while (list pred &rest body)
+  "Anaphoric form of `-each-while'."
+  (declare (debug (form form body))
+           (indent 2))
+  (let ((l (make-symbol "list"))
+        (c (make-symbol "continue")))
+    `(let ((,l ,list)
+           (,c t)
+           (it-index 0))
+       (while (and ,l ,c)
+         (let ((it (car ,l)))
+           (if (not ,pred) (setq ,c nil) ,@body))
+         (setq it-index (1+ it-index))
+         (!cdr ,l)))))
+
+(defun -each-while (list pred fn)
+  "Call FN with every item in LIST while (PRED item) is non-nil.
+Return nil, used for side-effects only."
+  (--each-while list (funcall pred it) (funcall fn it)))
+
+(put '-each-while 'lisp-indent-function 2)
+
+(defmacro --dotimes (num &rest body)
+  "Repeatedly executes BODY (presumably for side-effects) with symbol `it' bound to integers from 0 through NUM-1."
+  (declare (debug (form body))
+           (indent 1))
+  (let ((n (make-symbol "num")))
+    `(let ((,n ,num)
+           (it 0))
+       (while (< it ,n)
+         ,@body
+         (setq it (1+ it))))))
+
+(defun -dotimes (num fn)
+  "Repeatedly calls FN (presumably for side-effects) passing in integers from 0 through NUM-1."
+  (--dotimes num (funcall fn it)))
+
+(put '-dotimes 'lisp-indent-function 1)
+
+(defun -map (fn list)
+  "Return a new list consisting of the result of applying FN to the items in LIST."
+  (mapcar fn list))
+
+(defmacro --map (form list)
+  "Anaphoric form of `-map'."
+  (declare (debug (form form)))
+  `(mapcar (lambda (it) ,form) ,list))
+
+(defmacro --reduce-from (form initial-value list)
+  "Anaphoric form of `-reduce-from'."
+  (declare (debug (form form form)))
+  `(let ((acc ,initial-value))
+     (--each ,list (setq acc ,form))
+     acc))
+
+(defun -reduce-from (fn initial-value list)
+  "Return the result of applying FN to INITIAL-VALUE and the
+first item in LIST, then applying FN to that result and the 2nd
+item, etc. If LIST contains no items, return INITIAL-VALUE and
+FN is not called.
+
+In the anaphoric form `--reduce-from', the accumulated value is
+exposed as symbol `acc'.
+
+See also: `-reduce', `-reduce-r'"
+  (--reduce-from (funcall fn acc it) initial-value list))
+
+(defmacro --reduce (form list)
+  "Anaphoric form of `-reduce'."
+  (declare (debug (form form)))
+  (let ((lv (make-symbol "list-value")))
+    `(let ((,lv ,list))
+       (if ,lv
+           (--reduce-from ,form (car ,lv) (cdr ,lv))
+         (let (acc it) ,form)))))
+
+(defun -reduce (fn list)
+  "Return the result of applying FN to the first 2 items in LIST,
+then applying FN to that result and the 3rd item, etc. If LIST
+contains no items, FN must accept no arguments as well, and
+reduce return the result of calling FN with no arguments. If
+LIST has only 1 item, it is returned and FN is not called.
+
+In the anaphoric form `--reduce', the accumulated value is
+exposed as symbol `acc'.
+
+See also: `-reduce-from', `-reduce-r'"
+  (if list
+      (-reduce-from fn (car list) (cdr list))
+    (funcall fn)))
+
+(defun -reduce-r-from (fn initial-value list)
+  "Replace conses with FN, nil with INITIAL-VALUE and evaluate
+the resulting expression. If LIST is empty, INITIAL-VALUE is
+returned and FN is not called.
+
+Note: this function works the same as `-reduce-from' but the
+operation associates from right instead of from left.
+
+See also: `-reduce-r', `-reduce'"
+  (if (not list) initial-value
+    (funcall fn (car list) (-reduce-r-from fn initial-value (cdr list)))))
+
+(defmacro --reduce-r-from (form initial-value list)
+  "Anaphoric version of `-reduce-r-from'."
+  (declare (debug (form form form)))
+  `(-reduce-r-from (lambda (&optional it acc) ,form) ,initial-value ,list))
+
+(defun -reduce-r (fn list)
+  "Replace conses with FN and evaluate the resulting expression.
+The final nil is ignored. If LIST contains no items, FN must
+accept no arguments as well, and reduce return the result of
+calling FN with no arguments. If LIST has only 1 item, it is
+returned and FN is not called.
+
+The first argument of FN is the new item, the second is the
+accumulated value.
+
+Note: this function works the same as `-reduce' but the operation
+associates from right instead of from left.
+
+See also: `-reduce-r-from', `-reduce'"
+  (cond
+   ((not list) (funcall fn))
+   ((not (cdr list)) (car list))
+   (t (funcall fn (car list) (-reduce-r fn (cdr list))))))
+
+(defmacro --reduce-r (form list)
+  "Anaphoric version of `-reduce-r'."
+  (declare (debug (form form)))
+  `(-reduce-r (lambda (&optional it acc) ,form) ,list))
+
+(defun -reductions-from (fn init list)
+  "Return a list of the intermediate values of the reduction.
+
+See `-reduce-from' for explanation of the arguments.
+
+See also: `-reductions', `-reductions-r', `-reduce-r'"
+  (nreverse (--reduce-from (cons (funcall fn (car acc) it) acc) (list init) list)))
+
+(defun -reductions (fn list)
+  "Return a list of the intermediate values of the reduction.
+
+See `-reduce' for explanation of the arguments.
+
+See also: `-reductions-from', `-reductions-r', `-reduce-r'"
+  (-reductions-from fn (car list) (cdr list)))
+
+(defun -reductions-r-from (fn init list)
+  "Return a list of the intermediate values of the reduction.
+
+See `-reduce-r-from' for explanation of the arguments.
+
+See also: `-reductions-r', `-reductions', `-reduce'"
+  (--reduce-r-from (cons (funcall fn it (car acc)) acc) (list init) list))
+
+(defun -reductions-r (fn list)
+  "Return a list of the intermediate values of the reduction.
+
+See `-reduce-r' for explanation of the arguments.
+
+See also: `-reductions-r-from', `-reductions', `-reduce'"
+  (-reductions-r-from fn (-last-item list) (-butlast list)))
+
+(defmacro --filter (form list)
+  "Anaphoric form of `-filter'.
+
+See also: `--remove'."
+  (declare (debug (form form)))
+  (let ((r (make-symbol "result")))
+    `(let (,r)
+       (--each ,list (when ,form (!cons it ,r)))
+       (nreverse ,r))))
+
+(defun -filter (pred list)
+  "Return a new list of the items in LIST for which PRED returns a non-nil value.
+
+Alias: `-select'
+
+See also: `-keep', `-remove'."
+  (--filter (funcall pred it) list))
+
+(defalias '-select '-filter)
+(defalias '--select '--filter)
+
+(defmacro --remove (form list)
+  "Anaphoric form of `-remove'.
+
+See also `--filter'."
+  (declare (debug (form form)))
+  `(--filter (not ,form) ,list))
+
+(defun -remove (pred list)
+  "Return a new list of the items in LIST for which PRED returns nil.
+
+Alias: `-reject'
+
+See also: `-filter'."
+  (--remove (funcall pred it) list))
+
+(defalias '-reject '-remove)
+(defalias '--reject '--remove)
+
+(defun -remove-first (pred list)
+  "Return a new list with the first item matching PRED removed.
+
+Alias: `-reject-first'
+
+See also: `-remove', `-map-first'"
+  (let (front)
+    (while (and list (not (funcall pred (car list))))
+      (push (car list) front)
+      (!cdr list))
+    (if list
+        (-concat (nreverse front) (cdr list))
+      (nreverse front))))
+
+(defmacro --remove-first (form list)
+  "Anaphoric form of `-remove-first'."
+  (declare (debug (form form)))
+  `(-remove-first (lambda (it) ,form) ,list))
+
+(defalias '-reject-first '-remove-first)
+(defalias '--reject-first '--remove-first)
+
+(defun -remove-last (pred list)
+  "Return a new list with the last item matching PRED removed.
+
+Alias: `-reject-last'
+
+See also: `-remove', `-map-last'"
+  (nreverse (-remove-first pred (reverse list))))
+
+(defmacro --remove-last (form list)
+  "Anaphoric form of `-remove-last'."
+  (declare (debug (form form)))
+  `(-remove-last (lambda (it) ,form) ,list))
+
+(defalias '-reject-last '-remove-last)
+(defalias '--reject-last '--remove-last)
+
+(defun -remove-item (item list)
+  "Remove all occurences of ITEM from LIST.
+
+Comparison is done with `equal'."
+  (declare (pure t) (side-effect-free t))
+  (--remove (equal it item) list))
+
+(defmacro --keep (form list)
+  "Anaphoric form of `-keep'."
+  (declare (debug (form form)))
+  (let ((r (make-symbol "result"))
+        (m (make-symbol "mapped")))
+    `(let (,r)
+       (--each ,list (let ((,m ,form)) (when ,m (!cons ,m ,r))))
+       (nreverse ,r))))
+
+(defun -keep (fn list)
+  "Return a new list of the non-nil results of applying FN to the items in LIST.
+
+If you want to select the original items satisfying a predicate use `-filter'."
+  (--keep (funcall fn it) list))
+
+(defun -non-nil (list)
+  "Return all non-nil elements of LIST."
+  (declare (pure t) (side-effect-free t))
+  (-remove 'null list))
+
+(defmacro --map-indexed (form list)
+  "Anaphoric form of `-map-indexed'."
+  (declare (debug (form form)))
+  (let ((r (make-symbol "result")))
+    `(let (,r)
+       (--each ,list
+         (!cons ,form ,r))
+       (nreverse ,r))))
+
+(defun -map-indexed (fn list)
+  "Return a new list consisting of the result of (FN index item) for each item in LIST.
+
+In the anaphoric form `--map-indexed', the index is exposed as symbol `it-index'.
+
+See also: `-each-indexed'."
+  (--map-indexed (funcall fn it-index it) list))
+
+(defmacro --map-when (pred rep list)
+  "Anaphoric form of `-map-when'."
+  (declare (debug (form form form)))
+  (let ((r (make-symbol "result")))
+    `(let (,r)
+       (--each ,list (!cons (if ,pred ,rep it) ,r))
+       (nreverse ,r))))
+
+(defun -map-when (pred rep list)
+  "Return a new list where the elements in LIST that do not match the PRED function
+are unchanged, and where the elements in LIST that do match the PRED function are mapped
+through the REP function.
+
+Alias: `-replace-where'
+
+See also: `-update-at'"
+  (--map-when (funcall pred it) (funcall rep it) list))
+
+(defalias '-replace-where '-map-when)
+(defalias '--replace-where '--map-when)
+
+(defun -map-first (pred rep list)
+  "Replace first item in LIST satisfying PRED with result of REP called on this item.
+
+See also: `-map-when', `-replace-first'"
+  (let (front)
+    (while (and list (not (funcall pred (car list))))
+      (push (car list) front)
+      (!cdr list))
+    (if list
+        (-concat (nreverse front) (cons (funcall rep (car list)) (cdr list)))
+      (nreverse front))))
+
+(defmacro --map-first (pred rep list)
+  "Anaphoric form of `-map-first'."
+  `(-map-first (lambda (it) ,pred) (lambda (it) (ignore it) ,rep) ,list))
+
+(defun -map-last (pred rep list)
+  "Replace last item in LIST satisfying PRED with result of REP called on this item.
+
+See also: `-map-when', `-replace-last'"
+  (nreverse (-map-first pred rep (reverse list))))
+
+(defmacro --map-last (pred rep list)
+  "Anaphoric form of `-map-last'."
+  `(-map-last (lambda (it) ,pred) (lambda (it) (ignore it) ,rep) ,list))
+
+(defun -replace (old new list)
+  "Replace all OLD items in LIST with NEW.
+
+Elements are compared using `equal'.
+
+See also: `-replace-at'"
+  (declare (pure t) (side-effect-free t))
+  (--map-when (equal it old) new list))
+
+(defun -replace-first (old new list)
+  "Replace the first occurence of OLD with NEW in LIST.
+
+Elements are compared using `equal'.
+
+See also: `-map-first'"
+  (declare (pure t) (side-effect-free t))
+  (--map-first (equal old it) new list))
+
+(defun -replace-last (old new list)
+  "Replace the last occurence of OLD with NEW in LIST.
+
+Elements are compared using `equal'.
+
+See also: `-map-last'"
+  (declare (pure t) (side-effect-free t))
+  (--map-last (equal old it) new list))
+
+(defmacro --mapcat (form list)
+  "Anaphoric form of `-mapcat'."
+  (declare (debug (form form)))
+  `(apply 'append (--map ,form ,list)))
+
+(defun -mapcat (fn list)
+  "Return the concatenation of the result of mapping FN over LIST.
+Thus function FN should return a list."
+  (--mapcat (funcall fn it) list))
+
+(defun -flatten (l)
+  "Take a nested list L and return its contents as a single, flat list.
+
+Note that because `nil' represents a list of zero elements (an
+empty list), any mention of nil in L will disappear after
+flattening.  If you need to preserve nils, consider `-flatten-n'
+or map them to some unique symbol and then map them back.
+
+Conses of two atoms are considered \"terminals\", that is, they
+aren't flattened further.
+
+See also: `-flatten-n'"
+  (declare (pure t) (side-effect-free t))
+  (if (and (listp l) (listp (cdr l)))
+      (-mapcat '-flatten l)
+    (list l)))
+
+(defmacro --iterate (form init n)
+  "Anaphoric version of `-iterate'."
+  (declare (debug (form form form)))
+  `(-iterate (lambda (it) ,form) ,init ,n))
+
+(defun -flatten-n (num list)
+  "Flatten NUM levels of a nested LIST.
+
+See also: `-flatten'"
+  (declare (pure t) (side-effect-free t))
+  (-last-item (--iterate (--mapcat (-list it) it) list (1+ num))))
+
+(defun -concat (&rest lists)
+  "Return a new list with the concatenation of the elements in the supplied LISTS."
+  (declare (pure t) (side-effect-free t))
+  (apply 'append lists))
+
+(defalias '-copy 'copy-sequence
+  "Create a shallow copy of LIST.
+
+\(fn LIST)")
+
+(defun -splice (pred fun list)
+  "Splice lists generated by FUN in place of elements matching PRED in LIST.
+
+FUN takes the element matching PRED as input.
+
+This function can be used as replacement for `,@' in case you
+need to splice several lists at marked positions (for example
+with keywords).
+
+See also: `-splice-list', `-insert-at'"
+  (let (r)
+    (--each list
+      (if (funcall pred it)
+          (let ((new (funcall fun it)))
+            (--each new (!cons it r)))
+        (!cons it r)))
+    (nreverse r)))
+
+(defmacro --splice (pred form list)
+  "Anaphoric form of `-splice'."
+  `(-splice (lambda (it) ,pred) (lambda (it) ,form) ,list))
+
+(defun -splice-list (pred new-list list)
+  "Splice NEW-LIST in place of elements matching PRED in LIST.
+
+See also: `-splice', `-insert-at'"
+  (-splice pred (lambda (_) new-list) list))
+
+(defmacro --splice-list (pred new-list list)
+  "Anaphoric form of `-splice-list'."
+  `(-splice-list (lambda (it) ,pred) ,new-list ,list))
+
+(defun -cons* (&rest args)
+  "Make a new list from the elements of ARGS.
+
+The last 2 members of ARGS are used as the final cons of the
+result so if the final member of ARGS is not a list the result is
+a dotted list."
+  (declare (pure t) (side-effect-free t))
+  (-reduce-r 'cons args))
+
+(defun -snoc (list elem &rest elements)
+  "Append ELEM to the end of the list.
+
+This is like `cons', but operates on the end of list.
+
+If ELEMENTS is non nil, append these to the list as well."
+  (-concat list (list elem) elements))
+
+(defmacro --first (form list)
+  "Anaphoric form of `-first'."
+  (declare (debug (form form)))
+  (let ((n (make-symbol "needle")))
+    `(let (,n)
+       (--each-while ,list (not ,n)
+         (when ,form (setq ,n it)))
+       ,n)))
+
+(defun -first (pred list)
+  "Return the first x in LIST where (PRED x) is non-nil, else nil.
+
+To get the first item in the list no questions asked, use `car'.
+
+Alias: `-find'"
+  (--first (funcall pred it) list))
+
+(defalias '-find '-first)
+(defalias '--find '--first)
+
+(defmacro --some (form list)
+  "Anaphoric form of `-some'."
+  (declare (debug (form form)))
+  (let ((n (make-symbol "needle")))
+    `(let (,n)
+       (--each-while ,list (not ,n)
+         (setq ,n ,form))
+       ,n)))
+
+(defun -some (pred list)
+  "Return (PRED x) for the first LIST item where (PRED x) is non-nil, else nil.
+
+Alias: `-any'"
+  (--some (funcall pred it) list))
+
+(defalias '-any '-some)
+(defalias '--any '--some)
+
+(defmacro --last (form list)
+  "Anaphoric form of `-last'."
+  (declare (debug (form form)))
+  (let ((n (make-symbol "needle")))
+    `(let (,n)
+       (--each ,list
+         (when ,form (setq ,n it)))
+       ,n)))
+
+(defun -last (pred list)
+  "Return the last x in LIST where (PRED x) is non-nil, else nil."
+  (--last (funcall pred it) list))
+
+(defalias '-first-item 'car
+  "Return the first item of LIST, or nil on an empty list.
+
+See also: `-second-item', `-last-item'.
+
+\(fn LIST)")
+
+;; Ensure that calls to `-first-item' are compiled to a single opcode,
+;; just like `car'.
+(put '-first-item 'byte-opcode 'byte-car)
+(put '-first-item 'byte-compile 'byte-compile-one-arg)
+
+(defalias '-second-item 'cadr
+  "Return the second item of LIST, or nil if LIST is too short.
+
+See also: `-third-item'.
+
+\(fn LIST)")
+
+(defalias '-third-item 'caddr
+  "Return the third item of LIST, or nil if LIST is too short.
+
+See also: `-fourth-item'.
+
+\(fn LIST)")
+
+(defun -fourth-item (list)
+  "Return the fourth item of LIST, or nil if LIST is too short.
+
+See also: `-fifth-item'."
+  (declare (pure t) (side-effect-free t))
+  (car (cdr (cdr (cdr list)))))
+
+(defun -fifth-item (list)
+  "Return the fifth item of LIST, or nil if LIST is too short.
+
+See also: `-last-item'."
+  (declare (pure t) (side-effect-free t))
+  (car (cdr (cdr (cdr (cdr list))))))
+
+;; TODO: gv was introduced in 24.3, so we can remove the if statement
+;; when support for earlier versions is dropped
+(eval-when-compile
+  (require 'cl)
+  (if (fboundp 'gv-define-simple-setter)
+      (gv-define-simple-setter -first-item setcar)
+    (require 'cl)
+    (with-no-warnings
+      (defsetf -first-item (x) (val) `(setcar ,x ,val)))))
+
+(defun -last-item (list)
+  "Return the last item of LIST, or nil on an empty list."
+  (declare (pure t) (side-effect-free t))
+  (car (last list)))
+
+;; TODO: gv was introduced in 24.3, so we can remove the if statement
+;; when support for earlier versions is dropped
+(eval-when-compile
+  (if (fboundp 'gv-define-setter)
+      (gv-define-setter -last-item (val x) `(setcar (last ,x) ,val))
+    (with-no-warnings
+      (defsetf -last-item (x) (val) `(setcar (last ,x) ,val)))))
+
+(defun -butlast (list)
+  "Return a list of all items in list except for the last."
+  ;; no alias as we don't want magic optional argument
+  (declare (pure t) (side-effect-free t))
+  (butlast list))
+
+(defmacro --count (pred list)
+  "Anaphoric form of `-count'."
+  (declare (debug (form form)))
+  (let ((r (make-symbol "result")))
+    `(let ((,r 0))
+       (--each ,list (when ,pred (setq ,r (1+ ,r))))
+       ,r)))
+
+(defun -count (pred list)
+  "Counts the number of items in LIST where (PRED item) is non-nil."
+  (--count (funcall pred it) list))
+
+(defun ---truthy? (val)
+  (declare (pure t) (side-effect-free t))
+  (not (null val)))
+
+(defmacro --any? (form list)
+  "Anaphoric form of `-any?'."
+  (declare (debug (form form)))
+  `(---truthy? (--some ,form ,list)))
+
+(defun -any? (pred list)
+  "Return t if (PRED x) is non-nil for any x in LIST, else nil.
+
+Alias: `-any-p', `-some?', `-some-p'"
+  (--any? (funcall pred it) list))
+
+(defalias '-some? '-any?)
+(defalias '--some? '--any?)
+(defalias '-any-p '-any?)
+(defalias '--any-p '--any?)
+(defalias '-some-p '-any?)
+(defalias '--some-p '--any?)
+
+(defmacro --all? (form list)
+  "Anaphoric form of `-all?'."
+  (declare (debug (form form)))
+  (let ((a (make-symbol "all")))
+    `(let ((,a t))
+       (--each-while ,list ,a (setq ,a ,form))
+       (---truthy? ,a))))
+
+(defun -all? (pred list)
+  "Return t if (PRED x) is non-nil for all x in LIST, else nil.
+
+Alias: `-all-p', `-every?', `-every-p'"
+  (--all? (funcall pred it) list))
+
+(defalias '-every? '-all?)
+(defalias '--every? '--all?)
+(defalias '-all-p '-all?)
+(defalias '--all-p '--all?)
+(defalias '-every-p '-all?)
+(defalias '--every-p '--all?)
+
+(defmacro --none? (form list)
+  "Anaphoric form of `-none?'."
+  (declare (debug (form form)))
+  `(--all? (not ,form) ,list))
+
+(defun -none? (pred list)
+  "Return t if (PRED x) is nil for all x in LIST, else nil.
+
+Alias: `-none-p'"
+  (--none? (funcall pred it) list))
+
+(defalias '-none-p '-none?)
+(defalias '--none-p '--none?)
+
+(defmacro --only-some? (form list)
+  "Anaphoric form of `-only-some?'."
+  (declare (debug (form form)))
+  (let ((y (make-symbol "yes"))
+        (n (make-symbol "no")))
+    `(let (,y ,n)
+       (--each-while ,list (not (and ,y ,n))
+         (if ,form (setq ,y t) (setq ,n t)))
+       (---truthy? (and ,y ,n)))))
+
+(defun -only-some? (pred list)
+  "Return `t` if at least one item of LIST matches PRED and at least one item of LIST does not match PRED.
+Return `nil` both if all items match the predicate or if none of the items match the predicate.
+
+Alias: `-only-some-p'"
+  (--only-some? (funcall pred it) list))
+
+(defalias '-only-some-p '-only-some?)
+(defalias '--only-some-p '--only-some?)
+
+(defun -slice (list from &optional to step)
+  "Return copy of LIST, starting from index FROM to index TO.
+
+FROM or TO may be negative.  These values are then interpreted
+modulo the length of the list.
+
+If STEP is a number, only each STEPth item in the resulting
+section is returned.  Defaults to 1."
+  (declare (pure t) (side-effect-free t))
+  (let ((length (length list))
+        (new-list nil))
+    ;; to defaults to the end of the list
+    (setq to (or to length))
+    (setq step (or step 1))
+    ;; handle negative indices
+    (when (< from 0)
+      (setq from (mod from length)))
+    (when (< to 0)
+      (setq to (mod to length)))
+
+    ;; iterate through the list, keeping the elements we want
+    (--each-while list (< it-index to)
+      (when (and (>= it-index from)
+                 (= (mod (- from it-index) step) 0))
+        (push it new-list)))
+    (nreverse new-list)))
+
+(defun -take (n list)
+  "Return a new list of the first N items in LIST, or all items if there are fewer than N.
+
+See also: `-take-last'"
+  (declare (pure t) (side-effect-free t))
+  (let (result)
+    (--dotimes n
+      (when list
+        (!cons (car list) result)
+        (!cdr list)))
+    (nreverse result)))
+
+(defun -take-last (n list)
+  "Return the last N items of LIST in order.
+
+See also: `-take'"
+  (declare (pure t) (side-effect-free t))
+  (copy-sequence (last list n)))
+
+(defalias '-drop 'nthcdr
+  "Return the tail of LIST without the first N items.
+
+See also: `-drop-last'
+
+\(fn N LIST)")
+
+(defun -drop-last (n list)
+  "Remove the last N items of LIST and return a copy.
+
+See also: `-drop'"
+  ;; No alias because we don't want magic optional argument
+  (declare (pure t) (side-effect-free t))
+  (butlast list n))
+
+(defmacro --take-while (form list)
+  "Anaphoric form of `-take-while'."
+  (declare (debug (form form)))
+  (let ((r (make-symbol "result")))
+    `(let (,r)
+       (--each-while ,list ,form (!cons it ,r))
+       (nreverse ,r))))
+
+(defun -take-while (pred list)
+  "Return a new list of successive items from LIST while (PRED item) returns a non-nil value."
+  (--take-while (funcall pred it) list))
+
+(defmacro --drop-while (form list)
+  "Anaphoric form of `-drop-while'."
+  (declare (debug (form form)))
+  (let ((l (make-symbol "list")))
+    `(let ((,l ,list))
+       (while (and ,l (let ((it (car ,l))) ,form))
+         (!cdr ,l))
+       ,l)))
+
+(defun -drop-while (pred list)
+  "Return the tail of LIST starting from the first item for which (PRED item) returns nil."
+  (--drop-while (funcall pred it) list))
+
+(defun -split-at (n list)
+  "Return a list of ((-take N LIST) (-drop N LIST)), in no more than one pass through the list."
+  (declare (pure t) (side-effect-free t))
+  (let (result)
+    (--dotimes n
+      (when list
+        (!cons (car list) result)
+        (!cdr list)))
+    (list (nreverse result) list)))
+
+(defun -rotate (n list)
+  "Rotate LIST N places to the right.  With N negative, rotate to the left.
+The time complexity is O(n)."
+  (declare (pure t) (side-effect-free t))
+  (if (> n 0)
+      (append (last list n) (butlast list n))
+    (append (-drop (- n) list) (-take (- n) list))))
+
+(defun -insert-at (n x list)
+  "Return a list with X inserted into LIST at position N.
+
+See also: `-splice', `-splice-list'"
+  (declare (pure t) (side-effect-free t))
+  (let ((split-list (-split-at n list)))
+    (nconc (car split-list) (cons x (cadr split-list)))))
+
+(defun -replace-at (n x list)
+  "Return a list with element at Nth position in LIST replaced with X.
+
+See also: `-replace'"
+  (declare (pure t) (side-effect-free t))
+  (let ((split-list (-split-at n list)))
+    (nconc (car split-list) (cons x (cdr (cadr split-list))))))
+
+(defun -update-at (n func list)
+  "Return a list with element at Nth position in LIST replaced with `(func (nth n list))`.
+
+See also: `-map-when'"
+  (let ((split-list (-split-at n list)))
+    (nconc (car split-list) (cons (funcall func (car (cadr split-list))) (cdr (cadr split-list))))))
+
+(defmacro --update-at (n form list)
+  "Anaphoric version of `-update-at'."
+  (declare (debug (form form form)))
+  `(-update-at ,n (lambda (it) ,form) ,list))
+
+(defun -remove-at (n list)
+  "Return a list with element at Nth position in LIST removed.
+
+See also: `-remove-at-indices', `-remove'"
+  (declare (pure t) (side-effect-free t))
+  (-remove-at-indices (list n) list))
+
+(defun -remove-at-indices (indices list)
+  "Return a list whose elements are elements from LIST without
+elements selected as `(nth i list)` for all i
+from INDICES.
+
+See also: `-remove-at', `-remove'"
+  (declare (pure t) (side-effect-free t))
+  (let* ((indices (-sort '< indices))
+         (diffs (cons (car indices) (-map '1- (-zip-with '- (cdr indices) indices))))
+         r)
+    (--each diffs
+      (let ((split (-split-at it list)))
+        (!cons (car split) r)
+        (setq list (cdr (cadr split)))))
+    (!cons list r)
+    (apply '-concat (nreverse r))))
+
+(defmacro --split-with (pred list)
+  "Anaphoric form of `-split-with'."
+  (declare (debug (form form)))
+  (let ((l (make-symbol "list"))
+        (r (make-symbol "result"))
+        (c (make-symbol "continue")))
+    `(let ((,l ,list)
+           (,r nil)
+           (,c t))
+       (while (and ,l ,c)
+         (let ((it (car ,l)))
+           (if (not ,pred)
+               (setq ,c nil)
+             (!cons it ,r)
+             (!cdr ,l))))
+       (list (nreverse ,r) ,l))))
+
+(defun -split-with (pred list)
+  "Return a list of ((-take-while PRED LIST) (-drop-while PRED LIST)), in no more than one pass through the list."
+  (--split-with (funcall pred it) list))
+
+(defmacro -split-on (item list)
+  "Split the LIST each time ITEM is found.
+
+Unlike `-partition-by', the ITEM is discarded from the results.
+Empty lists are also removed from the result.
+
+Comparison is done by `equal'.
+
+See also `-split-when'"
+  (declare (debug (form form)))
+  `(-split-when (lambda (it) (equal it ,item)) ,list))
+
+(defmacro --split-when (form list)
+  "Anaphoric version of `-split-when'."
+  (declare (debug (form form)))
+  `(-split-when (lambda (it) ,form) ,list))
+
+(defun -split-when (fn list)
+  "Split the LIST on each element where FN returns non-nil.
+
+Unlike `-partition-by', the \"matched\" element is discarded from
+the results.  Empty lists are also removed from the result.
+
+This function can be thought of as a generalization of
+`split-string'."
+  (let (r s)
+    (while list
+      (if (not (funcall fn (car list)))
+          (push (car list) s)
+        (when s (push (nreverse s) r))
+        (setq s nil))
+      (!cdr list))
+    (when s (push (nreverse s) r))
+    (nreverse r)))
+
+(defmacro --separate (form list)
+  "Anaphoric form of `-separate'."
+  (declare (debug (form form)))
+  (let ((y (make-symbol "yes"))
+        (n (make-symbol "no")))
+    `(let (,y ,n)
+       (--each ,list (if ,form (!cons it ,y) (!cons it ,n)))
+       (list (nreverse ,y) (nreverse ,n)))))
+
+(defun -separate (pred list)
+  "Return a list of ((-filter PRED LIST) (-remove PRED LIST)), in one pass through the list."
+  (--separate (funcall pred it) list))
+
+(defun ---partition-all-in-steps-reversed (n step list)
+  "Private: Used by -partition-all-in-steps and -partition-in-steps."
+  (when (< step 1)
+    (error "Step must be a positive number, or you're looking at some juicy infinite loops."))
+  (let ((result nil))
+    (while list
+      (!cons (-take n list) result)
+      (setq list (-drop step list)))
+    result))
+
+(defun -partition-all-in-steps (n step list)
+  "Return a new list with the items in LIST grouped into N-sized sublists at offsets STEP apart.
+The last groups may contain less than N items."
+  (declare (pure t) (side-effect-free t))
+  (nreverse (---partition-all-in-steps-reversed n step list)))
+
+(defun -partition-in-steps (n step list)
+  "Return a new list with the items in LIST grouped into N-sized sublists at offsets STEP apart.
+If there are not enough items to make the last group N-sized,
+those items are discarded."
+  (declare (pure t) (side-effect-free t))
+  (let ((result (---partition-all-in-steps-reversed n step list)))
+    (while (and result (< (length (car result)) n))
+      (!cdr result))
+    (nreverse result)))
+
+(defun -partition-all (n list)
+  "Return a new list with the items in LIST grouped into N-sized sublists.
+The last group may contain less than N items."
+  (declare (pure t) (side-effect-free t))
+  (-partition-all-in-steps n n list))
+
+(defun -partition (n list)
+  "Return a new list with the items in LIST grouped into N-sized sublists.
+If there are not enough items to make the last group N-sized,
+those items are discarded."
+  (declare (pure t) (side-effect-free t))
+  (-partition-in-steps n n list))
+
+(defmacro --partition-by (form list)
+  "Anaphoric form of `-partition-by'."
+  (declare (debug (form form)))
+  (let ((r (make-symbol "result"))
+        (s (make-symbol "sublist"))
+        (v (make-symbol "value"))
+        (n (make-symbol "new-value"))
+        (l (make-symbol "list")))
+    `(let ((,l ,list))
+       (when ,l
+         (let* ((,r nil)
+                (it (car ,l))
+                (,s (list it))
+                (,v ,form)
+                (,l (cdr ,l)))
+           (while ,l
+             (let* ((it (car ,l))
+                    (,n ,form))
+               (unless (equal ,v ,n)
+                 (!cons (nreverse ,s) ,r)
+                 (setq ,s nil)
+                 (setq ,v ,n))
+               (!cons it ,s)
+               (!cdr ,l)))
+           (!cons (nreverse ,s) ,r)
+           (nreverse ,r))))))
+
+(defun -partition-by (fn list)
+  "Apply FN to each item in LIST, splitting it each time FN returns a new value."
+  (--partition-by (funcall fn it) list))
+
+(defmacro --partition-by-header (form list)
+  "Anaphoric form of `-partition-by-header'."
+  (declare (debug (form form)))
+  (let ((r (make-symbol "result"))
+        (s (make-symbol "sublist"))
+        (h (make-symbol "header-value"))
+        (b (make-symbol "seen-body?"))
+        (n (make-symbol "new-value"))
+        (l (make-symbol "list")))
+    `(let ((,l ,list))
+       (when ,l
+         (let* ((,r nil)
+                (it (car ,l))
+                (,s (list it))
+                (,h ,form)
+                (,b nil)
+                (,l (cdr ,l)))
+           (while ,l
+             (let* ((it (car ,l))
+                    (,n ,form))
+               (if (equal ,h ,n)
+                   (when ,b
+                     (!cons (nreverse ,s) ,r)
+                     (setq ,s nil)
+                     (setq ,b nil))
+                 (setq ,b t))
+               (!cons it ,s)
+               (!cdr ,l)))
+           (!cons (nreverse ,s) ,r)
+           (nreverse ,r))))))
+
+(defun -partition-by-header (fn list)
+  "Apply FN to the first item in LIST. That is the header
+value. Apply FN to each item in LIST, splitting it each time FN
+returns the header value, but only after seeing at least one
+other value (the body)."
+  (--partition-by-header (funcall fn it) list))
+
+(defun -partition-after-pred (pred list)
+  "Partition directly after each time PRED is true on an element of LIST."
+  (when list
+    (let ((rest (-partition-after-pred pred
+                                       (cdr list))))
+      (if (funcall pred (car list))
+          ;;split after (car list)
+          (cons (list (car list))
+                rest)
+
+        ;;don't split after (car list)
+        (cons (cons (car list)
+                    (car rest))
+              (cdr rest))))))
+
+(defun -partition-before-pred (pred list)
+  "Partition directly before each time PRED is true on an element of LIST."
+  (nreverse (-map #'reverse
+                  (-partition-after-pred pred (reverse list)))))
+
+(defun -partition-after-item (item list)
+  "Partition directly after each time ITEM appears in LIST."
+  (-partition-after-pred (lambda (ele) (equal ele item))
+                         list))
+
+(defun -partition-before-item (item list)
+  "Partition directly before each time ITEM appears in LIST."
+  (-partition-before-pred (lambda (ele) (equal ele item))
+                          list))
+
+(defmacro --group-by (form list)
+  "Anaphoric form of `-group-by'."
+  (declare (debug t))
+  (let ((n (make-symbol "n"))
+        (k (make-symbol "k"))
+        (grp (make-symbol "grp")))
+    `(nreverse
+      (-map
+       (lambda (,n)
+         (cons (car ,n)
+               (nreverse (cdr ,n))))
+       (--reduce-from
+        (let* ((,k (,@form))
+               (,grp (assoc ,k acc)))
+          (if ,grp
+              (setcdr ,grp (cons it (cdr ,grp)))
+            (push
+             (list ,k it)
+             acc))
+          acc)
+        nil ,list)))))
+
+(defun -group-by (fn list)
+  "Separate LIST into an alist whose keys are FN applied to the
+elements of LIST.  Keys are compared by `equal'."
+  (--group-by (funcall fn it) list))
+
+(defun -interpose (sep list)
+  "Return a new list of all elements in LIST separated by SEP."
+  (declare (pure t) (side-effect-free t))
+  (let (result)
+    (when list
+      (!cons (car list) result)
+      (!cdr list))
+    (while list
+      (setq result (cons (car list) (cons sep result)))
+      (!cdr list))
+    (nreverse result)))
+
+(defun -interleave (&rest lists)
+  "Return a new list of the first item in each list, then the second etc."
+  (declare (pure t) (side-effect-free t))
+  (when lists
+    (let (result)
+      (while (-none? 'null lists)
+        (--each lists (!cons (car it) result))
+        (setq lists (-map 'cdr lists)))
+      (nreverse result))))
+
+(defmacro --zip-with (form list1 list2)
+  "Anaphoric form of `-zip-with'.
+
+The elements in list1 are bound as symbol `it', the elements in list2 as symbol `other'."
+  (declare (debug (form form form)))
+  (let ((r (make-symbol "result"))
+        (l1 (make-symbol "list1"))
+        (l2 (make-symbol "list2")))
+    `(let ((,r nil)
+           (,l1 ,list1)
+           (,l2 ,list2))
+       (while (and ,l1 ,l2)
+         (let ((it (car ,l1))
+               (other (car ,l2)))
+           (!cons ,form ,r)
+           (!cdr ,l1)
+           (!cdr ,l2)))
+       (nreverse ,r))))
+
+(defun -zip-with (fn list1 list2)
+  "Zip the two lists LIST1 and LIST2 using a function FN.  This
+function is applied pairwise taking as first argument element of
+LIST1 and as second argument element of LIST2 at corresponding
+position.
+
+The anaphoric form `--zip-with' binds the elements from LIST1 as symbol `it',
+and the elements from LIST2 as symbol `other'."
+  (--zip-with (funcall fn it other) list1 list2))
+
+(defun -zip (&rest lists)
+  "Zip LISTS together.  Group the head of each list, followed by the
+second elements of each list, and so on. The lengths of the returned
+groupings are equal to the length of the shortest input list.
+
+If two lists are provided as arguments, return the groupings as a list
+of cons cells. Otherwise, return the groupings as a list of lists.
+
+Please note! This distinction is being removed in an upcoming 3.0
+release of Dash. If you rely on this behavior, use -zip-pair instead."
+  (declare (pure t) (side-effect-free t))
+  (when lists
+    (let (results)
+      (while (-none? 'null lists)
+        (setq results (cons (mapcar 'car lists) results))
+        (setq lists (mapcar 'cdr lists)))
+      (setq results (nreverse results))
+      (if (= (length lists) 2)
+          ;; to support backward compatability, return
+          ;; a cons cell if two lists were provided
+          (--map (cons (car it) (cadr it)) results)
+        results))))
+
+(defalias '-zip-pair '-zip)
+
+(defun -zip-fill (fill-value &rest lists)
+  "Zip LISTS, with FILL-VALUE padded onto the shorter lists. The
+lengths of the returned groupings are equal to the length of the
+longest input list."
+  (declare (pure t) (side-effect-free t))
+  (apply '-zip (apply '-pad (cons fill-value lists))))
+
+(defun -unzip (lists)
+  "Unzip LISTS.
+
+This works just like `-zip' but takes a list of lists instead of
+a variable number of arguments, such that
+
+  (-unzip (-zip L1 L2 L3 ...))
+
+is identity (given that the lists are the same length).
+
+See also: `-zip'"
+  (apply '-zip lists))
+
+(defun -cycle (list)
+  "Return an infinite copy of LIST that will cycle through the
+elements and repeat from the beginning."
+  (declare (pure t) (side-effect-free t))
+  (let ((newlist (-map 'identity list)))
+    (nconc newlist newlist)))
+
+(defun -pad (fill-value &rest lists)
+  "Appends FILL-VALUE to the end of each list in LISTS such that they
+will all have the same length."
+  (let* ((annotations (-annotate 'length lists))
+         (n (-max (-map 'car annotations))))
+    (--map (append (cdr it) (-repeat (- n (car it)) fill-value)) annotations)))
+
+(defun -annotate (fn list)
+  "Return a list of cons cells where each cell is FN applied to each
+element of LIST paired with the unmodified element of LIST."
+  (-zip (-map fn list) list))
+
+(defmacro --annotate (form list)
+  "Anaphoric version of `-annotate'."
+  (declare (debug (form form)))
+  `(-annotate (lambda (it) ,form) ,list))
+
+(defun dash--table-carry (lists restore-lists &optional re)
+  "Helper for `-table' and `-table-flat'.
+
+If a list overflows, carry to the right and reset the list."
+  (while (not (or (car lists)
+                  (equal lists '(nil))))
+    (setcar lists (car restore-lists))
+    (pop (cadr lists))
+    (!cdr lists)
+    (!cdr restore-lists)
+    (when re
+      (push (nreverse (car re)) (cadr re))
+      (setcar re nil)
+      (!cdr re))))
+
+(defun -table (fn &rest lists)
+  "Compute outer product of LISTS using function FN.
+
+The function FN should have the same arity as the number of
+supplied lists.
+
+The outer product is computed by applying fn to all possible
+combinations created by taking one element from each list in
+order.  The dimension of the result is (length lists).
+
+See also: `-table-flat'"
+  (let ((restore-lists (copy-sequence lists))
+        (last-list (last lists))
+        (re (make-list (length lists) nil)))
+    (while (car last-list)
+      (let ((item (apply fn (-map 'car lists))))
+        (push item (car re))
+        (setcar lists (cdar lists)) ;; silence byte compiler
+        (dash--table-carry lists restore-lists re)))
+    (nreverse (car (last re)))))
+
+(defun -table-flat (fn &rest lists)
+  "Compute flat outer product of LISTS using function FN.
+
+The function FN should have the same arity as the number of
+supplied lists.
+
+The outer product is computed by applying fn to all possible
+combinations created by taking one element from each list in
+order.  The results are flattened, ignoring the tensor structure
+of the result.  This is equivalent to calling:
+
+  (-flatten-n (1- (length lists)) (apply \\='-table fn lists))
+
+but the implementation here is much more efficient.
+
+See also: `-flatten-n', `-table'"
+  (let ((restore-lists (copy-sequence lists))
+        (last-list (last lists))
+        re)
+    (while (car last-list)
+      (let ((item (apply fn (-map 'car lists))))
+        (push item re)
+        (setcar lists (cdar lists)) ;; silence byte compiler
+        (dash--table-carry lists restore-lists)))
+    (nreverse re)))
+
+(defun -partial (fn &rest args)
+  "Take a function FN and fewer than the normal arguments to FN,
+and return a fn that takes a variable number of additional ARGS.
+When called, the returned function calls FN with ARGS first and
+then additional args."
+  (apply 'apply-partially fn args))
+
+(defun -elem-index (elem list)
+  "Return the index of the first element in the given LIST which
+is equal to the query element ELEM, or nil if there is no
+such element."
+  (declare (pure t) (side-effect-free t))
+  (car (-elem-indices elem list)))
+
+(defun -elem-indices (elem list)
+  "Return the indices of all elements in LIST equal to the query
+element ELEM, in ascending order."
+  (declare (pure t) (side-effect-free t))
+  (-find-indices (-partial 'equal elem) list))
+
+(defun -find-indices (pred list)
+  "Return the indices of all elements in LIST satisfying the
+predicate PRED, in ascending order."
+  (apply 'append (--map-indexed (when (funcall pred it) (list it-index)) list)))
+
+(defmacro --find-indices (form list)
+  "Anaphoric version of `-find-indices'."
+  (declare (debug (form form)))
+  `(-find-indices (lambda (it) ,form) ,list))
+
+(defun -find-index (pred list)
+  "Take a predicate PRED and a LIST and return the index of the
+first element in the list satisfying the predicate, or nil if
+there is no such element.
+
+See also `-first'."
+  (car (-find-indices pred list)))
+
+(defmacro --find-index (form list)
+  "Anaphoric version of `-find-index'."
+  (declare (debug (form form)))
+  `(-find-index (lambda (it) ,form) ,list))
+
+(defun -find-last-index (pred list)
+  "Take a predicate PRED and a LIST and return the index of the
+last element in the list satisfying the predicate, or nil if
+there is no such element.
+
+See also `-last'."
+  (-last-item (-find-indices pred list)))
+
+(defmacro --find-last-index (form list)
+  "Anaphoric version of `-find-last-index'."
+  `(-find-last-index (lambda (it) ,form) ,list))
+
+(defun -select-by-indices (indices list)
+  "Return a list whose elements are elements from LIST selected
+as `(nth i list)` for all i from INDICES."
+  (declare (pure t) (side-effect-free t))
+  (let (r)
+    (--each indices
+      (!cons (nth it list) r))
+    (nreverse r)))
+
+(defun -select-columns (columns table)
+  "Select COLUMNS from TABLE.
+
+TABLE is a list of lists where each element represents one row.
+It is assumed each row has the same length.
+
+Each row is transformed such that only the specified COLUMNS are
+selected.
+
+See also: `-select-column', `-select-by-indices'"
+  (declare (pure t) (side-effect-free t))
+  (--map (-select-by-indices columns it) table))
+
+(defun -select-column (column table)
+  "Select COLUMN from TABLE.
+
+TABLE is a list of lists where each element represents one row.
+It is assumed each row has the same length.
+
+The single selected column is returned as a list.
+
+See also: `-select-columns', `-select-by-indices'"
+  (declare (pure t) (side-effect-free t))
+  (--mapcat (-select-by-indices (list column) it) table))
+
+(defmacro -> (x &optional form &rest more)
+  "Thread the expr through the forms. Insert X as the second item
+in the first form, making a list of it if it is not a list
+already. If there are more forms, insert the first form as the
+second item in second form, etc."
+  (declare (debug (form &rest [&or symbolp (sexp &rest form)])))
+  (cond
+   ((null form) x)
+   ((null more) (if (listp form)
+                    `(,(car form) ,x ,@(cdr form))
+                  (list form x)))
+   (:else `(-> (-> ,x ,form) ,@more))))
+
+(defmacro ->> (x &optional form &rest more)
+  "Thread the expr through the forms. Insert X as the last item
+in the first form, making a list of it if it is not a list
+already. If there are more forms, insert the first form as the
+last item in second form, etc."
+  (declare (debug ->))
+  (cond
+   ((null form) x)
+   ((null more) (if (listp form)
+                    `(,@form ,x)
+                  (list form x)))
+   (:else `(->> (->> ,x ,form) ,@more))))
+
+(defmacro --> (x &rest forms)
+  "Starting with the value of X, thread each expression through FORMS.
+
+Insert X at the position signified by the symbol `it' in the first
+form.  If there are more forms, insert the first form at the position
+signified by `it' in in second form, etc."
+  (declare (debug (form body)))
+  `(-as-> ,x it ,@forms))
+
+(defmacro -as-> (value variable &rest forms)
+  "Starting with VALUE, thread VARIABLE through FORMS.
+
+In the first form, bind VARIABLE to VALUE.  In the second form, bind
+VARIABLE to the result of the first form, and so forth."
+  (declare (debug (form symbolp body)))
+  (if (null forms)
+      `,value
+    `(let ((,variable ,value))
+       (-as-> ,(if (symbolp (car forms))
+                 (list (car forms) variable)
+               (car forms))
+            ,variable
+              ,@(cdr forms)))))
+
+(defmacro -some-> (x &optional form &rest more)
+  "When expr is non-nil, thread it through the first form (via `->'),
+and when that result is non-nil, through the next form, etc."
+  (declare (debug ->))
+  (if (null form) x
+    (let ((result (make-symbol "result")))
+      `(-some-> (-when-let (,result ,x)
+                  (-> ,result ,form))
+                ,@more))))
+
+(defmacro -some->> (x &optional form &rest more)
+  "When expr is non-nil, thread it through the first form (via `->>'),
+and when that result is non-nil, through the next form, etc."
+  (declare (debug ->))
+  (if (null form) x
+    (let ((result (make-symbol "result")))
+      `(-some->> (-when-let (,result ,x)
+                   (->> ,result ,form))
+                 ,@more))))
+
+(defmacro -some--> (x &optional form &rest more)
+  "When expr in non-nil, thread it through the first form (via `-->'),
+and when that result is non-nil, through the next form, etc."
+  (declare (debug ->))
+  (if (null form) x
+    (let ((result (make-symbol "result")))
+      `(-some--> (-when-let (,result ,x)
+                   (--> ,result ,form))
+                 ,@more))))
+
+(defun -grade-up (comparator list)
+  "Grade elements of LIST using COMPARATOR relation, yielding a
+permutation vector such that applying this permutation to LIST
+sorts it in ascending order."
+  ;; ugly hack to "fix" lack of lexical scope
+  (let ((comp `(lambda (it other) (funcall ',comparator (car it) (car other)))))
+    (->> (--map-indexed (cons it it-index) list)
+         (-sort comp)
+         (-map 'cdr))))
+
+(defun -grade-down (comparator list)
+  "Grade elements of LIST using COMPARATOR relation, yielding a
+permutation vector such that applying this permutation to LIST
+sorts it in descending order."
+  ;; ugly hack to "fix" lack of lexical scope
+  (let ((comp `(lambda (it other) (funcall ',comparator (car other) (car it)))))
+    (->> (--map-indexed (cons it it-index) list)
+         (-sort comp)
+         (-map 'cdr))))
+
+(defvar dash--source-counter 0
+  "Monotonic counter for generated symbols.")
+
+(defun dash--match-make-source-symbol ()
+  "Generate a new dash-source symbol.
+
+All returned symbols are guaranteed to be unique."
+  (prog1 (make-symbol (format "--dash-source-%d--" dash--source-counter))
+    (setq dash--source-counter (1+ dash--source-counter))))
+
+(defun dash--match-ignore-place-p (symbol)
+  "Return non-nil if SYMBOL is a symbol and starts with _."
+  (and (symbolp symbol)
+       (eq (aref (symbol-name symbol) 0) ?_)))
+
+(defun dash--match-cons-skip-cdr (skip-cdr source)
+  "Helper function generating idiomatic shifting code."
+  (cond
+   ((= skip-cdr 0)
+    `(pop ,source))
+   (t
+    `(prog1 ,(dash--match-cons-get-car skip-cdr source)
+       (setq ,source ,(dash--match-cons-get-cdr (1+ skip-cdr) source))))))
+
+(defun dash--match-cons-get-car (skip-cdr source)
+  "Helper function generating idiomatic code to get nth car."
+  (cond
+   ((= skip-cdr 0)
+    `(car ,source))
+   ((= skip-cdr 1)
+    `(cadr ,source))
+   (t
+    `(nth ,skip-cdr ,source))))
+
+(defun dash--match-cons-get-cdr (skip-cdr source)
+  "Helper function generating idiomatic code to get nth cdr."
+  (cond
+   ((= skip-cdr 0)
+    source)
+   ((= skip-cdr 1)
+    `(cdr ,source))
+   (t
+    `(nthcdr ,skip-cdr ,source))))
+
+(defun dash--match-cons (match-form source)
+  "Setup a cons matching environment and call the real matcher."
+  (let ((s (dash--match-make-source-symbol))
+        (n 0)
+        (m match-form))
+    (while (and (consp m)
+                (dash--match-ignore-place-p (car m)))
+      (setq n (1+ n)) (!cdr m))
+    (cond
+     ;; when we only have one pattern in the list, we don't have to
+     ;; create a temporary binding (--dash-source--) for the source
+     ;; and just use the input directly
+     ((and (consp m)
+           (not (cdr m)))
+      (dash--match (car m) (dash--match-cons-get-car n source)))
+     ;; handle other special types
+     ((> n 0)
+      (dash--match m (dash--match-cons-get-cdr n source)))
+     ;; this is the only entry-point for dash--match-cons-1, that's
+     ;; why we can't simply use the above branch, it would produce
+     ;; infinite recursion
+     (t
+      (cons (list s source) (dash--match-cons-1 match-form s))))))
+
+(defun dash--match-cons-1 (match-form source &optional props)
+  "Match MATCH-FORM against SOURCE.
+
+MATCH-FORM is a proper or improper list.  Each element of
+MATCH-FORM is either a symbol, which gets bound to the respective
+value in source or another match form which gets destructured
+recursively.
+
+If the cdr of last cons cell in the list is `nil', matching stops
+there.
+
+SOURCE is a proper or improper list."
+  (let ((skip-cdr (or (plist-get props :skip-cdr) 0)))
+    (cond
+     ((consp match-form)
+      (cond
+       ((cdr match-form)
+        (cond
+         ((and (symbolp (car match-form))
+               (memq (car match-form) '(&keys &plist &alist &hash)))
+          (dash--match-kv match-form (dash--match-cons-get-cdr skip-cdr source)))
+         ((dash--match-ignore-place-p (car match-form))
+          (dash--match-cons-1 (cdr match-form) source
+                              (plist-put props :skip-cdr (1+ skip-cdr))))
+         (t
+          (-concat (dash--match (car match-form) (dash--match-cons-skip-cdr skip-cdr source))
+                   (dash--match-cons-1 (cdr match-form) source)))))
+       (t ;; Last matching place, no need for shift
+        (dash--match (car match-form) (dash--match-cons-get-car skip-cdr source)))))
+     ((eq match-form nil)
+      nil)
+     (t ;; Handle improper lists.  Last matching place, no need for shift
+      (dash--match match-form (dash--match-cons-get-cdr skip-cdr source))))))
+
+(defun dash--vector-tail (seq start)
+  "Return the tail of SEQ starting at START."
+  (cond
+   ((vectorp seq)
+    (let* ((re-length (- (length seq) start))
+           (re (make-vector re-length 0)))
+      (--dotimes re-length (aset re it (aref seq (+ it start))))
+      re))
+   ((stringp seq)
+    (substring seq start))))
+
+(defun dash--match-vector (match-form source)
+  "Setup a vector matching environment and call the real matcher."
+  (let ((s (dash--match-make-source-symbol)))
+    (cond
+     ;; don't bind `s' if we only have one sub-pattern
+     ((= (length match-form) 1)
+      (dash--match (aref match-form 0) `(aref ,source 0)))
+     ;; if the source is a symbol, we don't need to re-bind it
+     ((symbolp source)
+      (dash--match-vector-1 match-form source))
+     ;; don't bind `s' if we only have one sub-pattern which is not ignored
+     ((let* ((ignored-places (mapcar 'dash--match-ignore-place-p match-form))
+             (ignored-places-n (length (-remove 'null ignored-places))))
+        (when (= ignored-places-n (1- (length match-form)))
+          (let ((n (-find-index 'null ignored-places)))
+            (dash--match (aref match-form n) `(aref ,source ,n))))))
+     (t
+      (cons (list s source) (dash--match-vector-1 match-form s))))))
+
+(defun dash--match-vector-1 (match-form source)
+  "Match MATCH-FORM against SOURCE.
+
+MATCH-FORM is a vector.  Each element of MATCH-FORM is either a
+symbol, which gets bound to the respective value in source or
+another match form which gets destructured recursively.
+
+If second-from-last place in MATCH-FORM is the symbol &rest, the
+next element of the MATCH-FORM is matched against the tail of
+SOURCE, starting at index of the &rest symbol.  This is
+conceptually the same as the (head . tail) match for improper
+lists, where dot plays the role of &rest.
+
+SOURCE is a vector.
+
+If the MATCH-FORM vector is shorter than SOURCE vector, only
+the (length MATCH-FORM) places are bound, the rest of the SOURCE
+is discarded."
+  (let ((i 0)
+        (l (length match-form))
+        (re))
+    (while (< i l)
+      (let ((m (aref match-form i)))
+        (push (cond
+               ((and (symbolp m)
+                     (eq m '&rest))
+                (prog1 (dash--match
+                        (aref match-form (1+ i))
+                        `(dash--vector-tail ,source ,i))
+                  (setq i l)))
+               ((and (symbolp m)
+                     ;; do not match symbols starting with _
+                     (not (eq (aref (symbol-name m) 0) ?_)))
+                (list (list m `(aref ,source ,i))))
+               ((not (symbolp m))
+                (dash--match m `(aref ,source ,i))))
+              re)
+        (setq i (1+ i))))
+    (-flatten-n 1 (nreverse re))))
+
+(defun dash--match-kv (match-form source)
+  "Setup a kv matching environment and call the real matcher.
+
+kv can be any key-value store, such as plist, alist or hash-table."
+  (let ((s (dash--match-make-source-symbol)))
+    (cond
+     ;; don't bind `s' if we only have one sub-pattern (&type key val)
+     ((= (length match-form) 3)
+      (dash--match-kv-1 (cdr match-form) source (car match-form)))
+     ;; if the source is a symbol, we don't need to re-bind it
+     ((symbolp source)
+      (dash--match-kv-1 (cdr match-form) source (car match-form)))
+     (t
+      (cons (list s source) (dash--match-kv-1 (cdr match-form) s (car match-form)))))))
+
+(defun dash--match-kv-1 (match-form source type)
+  "Match MATCH-FORM against SOURCE of type TYPE.
+
+MATCH-FORM is a proper list of the form (key1 place1 ... keyN
+placeN).  Each placeK is either a symbol, which gets bound to the
+value of keyK retrieved from the key-value store, or another
+match form which gets destructured recursively.
+
+SOURCE is a key-value store of type TYPE, which can be a plist,
+an alist or a hash table.
+
+TYPE is a token specifying the type of the key-value store.
+Valid values are &plist, &alist and &hash."
+  (-flatten-n 1 (-map
+                 (lambda (kv)
+                   (let* ((k (car kv))
+                          (v (cadr kv))
+                          (getter (cond
+                                   ((or (eq type '&plist) (eq type '&keys))
+                                    `(plist-get ,source ,k))
+                                   ((eq type '&alist)
+                                    `(cdr (assoc ,k ,source)))
+                                   ((eq type '&hash)
+                                    `(gethash ,k ,source)))))
+                     (cond
+                      ((symbolp v)
+                       (list (list v getter)))
+                      (t (dash--match v getter)))))
+                 (-partition 2 match-form))))
+
+(defun dash--match-symbol (match-form source)
+  "Bind a symbol.
+
+This works just like `let', there is no destructuring."
+  (list (list match-form source)))
+
+(defun dash--match (match-form source)
+  "Match MATCH-FORM against SOURCE.
+
+This function tests the MATCH-FORM and dispatches to specific
+matchers based on the type of the expression.
+
+Key-value stores are disambiguated by placing a token &plist,
+&alist or &hash as a first item in the MATCH-FORM."
+  (cond
+   ((symbolp match-form)
+    (dash--match-symbol match-form source))
+   ((consp match-form)
+    (cond
+     ;; Handle the "x &as" bindings first.
+     ((and (consp (cdr match-form))
+           (symbolp (car match-form))
+           (eq '&as (cadr match-form)))
+      (let ((s (car match-form)))
+        (cons (list s source)
+              (dash--match (cddr match-form) s))))
+     ((memq (car match-form) '(&keys &plist &alist &hash))
+      (dash--match-kv match-form source))
+     (t (dash--match-cons match-form source))))
+   ((vectorp match-form)
+    ;; We support the &as binding in vectors too
+    (cond
+     ((and (> (length match-form) 2)
+           (symbolp (aref match-form 0))
+           (eq '&as (aref match-form 1)))
+      (let ((s (aref match-form 0)))
+        (cons (list s source)
+              (dash--match (dash--vector-tail match-form 2) s))))
+     (t (dash--match-vector match-form source))))))
+
+(defmacro -let* (varlist &rest body)
+  "Bind variables according to VARLIST then eval BODY.
+
+VARLIST is a list of lists of the form (PATTERN SOURCE).  Each
+PATTERN is matched against the SOURCE structurally.  SOURCE is
+only evaluated once for each PATTERN.
+
+Each SOURCE can refer to the symbols already bound by this
+VARLIST.  This is useful if you want to destructure SOURCE
+recursively but also want to name the intermediate structures.
+
+See `-let' for the list of all possible patterns."
+  (declare (debug ((&rest (sexp form)) body))
+           (indent 1))
+  (let ((bindings (--mapcat (dash--match (car it) (cadr it)) varlist)))
+    `(let* ,bindings
+       ,@body)))
+
+(defmacro -let (varlist &rest body)
+  "Bind variables according to VARLIST then eval BODY.
+
+VARLIST is a list of lists of the form (PATTERN SOURCE).  Each
+PATTERN is matched against the SOURCE \"structurally\".  SOURCE
+is only evaluated once for each PATTERN.  Each PATTERN is matched
+recursively, and can therefore contain sub-patterns which are
+matched against corresponding sub-expressions of SOURCE.
+
+All the SOURCEs are evalled before any symbols are
+bound (i.e. \"in parallel\").
+
+If VARLIST only contains one (PATTERN SOURCE) element, you can
+optionally specify it using a vector and discarding the
+outer-most parens.  Thus
+
+  (-let ((PATTERN SOURCE)) ..)
+
+becomes
+
+  (-let [PATTERN SOURCE] ..).
+
+`-let' uses a convention of not binding places (symbols) starting
+with _ whenever it's possible.  You can use this to skip over
+entries you don't care about.  However, this is not *always*
+possible (as a result of implementation) and these symbols might
+get bound to undefined values.
+
+Following is the overview of supported patterns.  Remember that
+patterns can be matched recursively, so every a, b, aK in the
+following can be a matching construct and not necessarily a
+symbol/variable.
+
+Symbol:
+
+  a - bind the SOURCE to A.  This is just like regular `let'.
+
+Conses and lists:
+
+  (a) - bind `car' of cons/list to A
+
+  (a . b) - bind car of cons to A and `cdr' to B
+
+  (a b) - bind car of list to A and `cadr' to B
+
+  (a1 a2 a3  ...) - bind 0th car of list to A1, 1st to A2, 2nd to A3 ...
+
+  (a1 a2 a3 ... aN . rest) - as above, but bind the Nth cdr to REST.
+
+Vectors:
+
+  [a] - bind 0th element of a non-list sequence to A (works with
+        vectors, strings, bit arrays...)
+
+  [a1 a2 a3 ...] - bind 0th element of non-list sequence to A0, 1st to
+                   A1, 2nd to A2, ...
+                   If the PATTERN is shorter than SOURCE, the values at
+                   places not in PATTERN are ignored.
+                   If the PATTERN is longer than SOURCE, an `error' is
+                   thrown.
+
+  [a1 a2 a3 ... &rest rest] - as above, but bind the rest of
+                              the sequence to REST.  This is
+                              conceptually the same as improper list
+                              matching (a1 a2 ... aN . rest)
+
+Key/value stores:
+
+  (&plist key0 a0 ... keyN aN) - bind value mapped by keyK in the
+                                 SOURCE plist to aK.  If the
+                                 value is not found, aK is nil.
+
+  (&alist key0 a0 ... keyN aN) - bind value mapped by keyK in the
+                                 SOURCE alist to aK.  If the
+                                 value is not found, aK is nil.
+
+  (&hash key0 a0 ... keyN aN) - bind value mapped by keyK in the
+                                SOURCE hash table to aK.  If the
+                                value is not found, aK is nil.
+
+Further, special keyword &keys supports \"inline\" matching of
+plist-like key-value pairs, similarly to &keys keyword of
+`cl-defun'.
+
+  (a1 a2 ... aN &keys key1 b1 ... keyN bK)
+
+This binds N values from the list to a1 ... aN, then interprets
+the cdr as a plist (see key/value matching above).
+
+You can name the source using the syntax SYMBOL &as PATTERN.
+This syntax works with lists (proper or improper), vectors and
+all types of maps.
+
+  (list &as a b c) (list 1 2 3)
+
+binds A to 1, B to 2, C to 3 and LIST to (1 2 3).
+
+Similarly:
+
+  (bounds &as beg . end) (cons 1 2)
+
+binds BEG to 1, END to 2 and BOUNDS to (1 . 2).
+
+  (items &as first . rest) (list 1 2 3)
+
+binds FIRST to 1, REST to (2 3) and ITEMS to (1 2 3)
+
+  [vect &as _ b c] [1 2 3]
+
+binds B to 2, C to 3 and VECT to [1 2 3] (_ avoids binding as usual).
+
+  (plist &as &plist :b b) (list :a 1 :b 2 :c 3)
+
+binds B to 2 and PLIST to (:a 1 :b 2 :c 3).  Same for &alist and &hash.
+
+This is especially useful when we want to capture the result of a
+computation and destructure at the same time.  Consider the
+form (function-returning-complex-structure) returning a list of
+two vectors with two items each.  We want to capture this entire
+result and pass it to another computation, but at the same time
+we want to get the second item from each vector.  We can achieve
+it with pattern
+
+  (result &as [_ a] [_ b]) (function-returning-complex-structure)
+
+Note: Clojure programmers may know this feature as the \":as
+binding\".  The difference is that we put the &as at the front
+because we need to support improper list binding."
+  (declare (debug ([&or (&rest (sexp form))
+                        (vector [&rest [sexp form]])]
+                   body))
+           (indent 1))
+  (if (vectorp varlist)
+      `(let* ,(dash--match (aref varlist 0) (aref varlist 1))
+         ,@body)
+    (let* ((inputs (--map-indexed (list (make-symbol (format "input%d" it-index)) (cadr it)) varlist))
+           (new-varlist (--map (list (caar it) (cadr it)) (-zip varlist inputs))))
+      `(let ,inputs
+         (-let* ,new-varlist ,@body)))))
+
+(defmacro -lambda (match-form &rest body)
+  "Return a lambda which destructures its input as MATCH-FORM and executes BODY.
+
+Note that you have to enclose the MATCH-FORM in a pair of parens,
+such that:
+
+  (-lambda (x) body)
+  (-lambda (x y ...) body)
+
+has the usual semantics of `lambda'.  Furthermore, these get
+translated into normal lambda, so there is no performance
+penalty.
+
+See `-let' for the description of destructuring mechanism."
+  (declare (doc-string 2) (indent defun)
+           (debug (&define sexp
+                           [&optional stringp]
+                           [&optional ("interactive" interactive)]
+                           def-body)))
+  (cond
+   ((not (consp match-form))
+    (signal 'wrong-type-argument "match-form must be a list"))
+   ;; no destructuring, so just return regular lambda to make things faster
+   ((-all? 'symbolp match-form)
+    `(lambda ,match-form ,@body))
+   (t
+    (let* ((inputs (--map-indexed (list it (make-symbol (format "input%d" it-index))) match-form)))
+      ;; TODO: because inputs to the lambda are evaluated only once,
+      ;; -let* need not to create the extra bindings to ensure that.
+      ;; We should find a way to optimize that.  Not critical however.
+      `(lambda ,(--map (cadr it) inputs)
+         (-let* ,inputs ,@body))))))
+
+(defmacro -if-let* (vars-vals then &rest else)
+  "If all VALS evaluate to true, bind them to their corresponding
+VARS and do THEN, otherwise do ELSE. VARS-VALS should be a list
+of (VAR VAL) pairs.
+
+Note: binding is done according to `-let*'.  VALS are evaluated
+sequentially, and evaluation stops after the first nil VAL is
+encountered."
+  (declare (debug ((&rest (sexp form)) form body))
+           (indent 2))
+  (->> vars-vals
+       (--mapcat (dash--match (car it) (cadr it)))
+       (--reduce-r-from
+        (let ((var (car it))
+              (val (cadr it)))
+          `(let ((,var ,val))
+             (if ,var ,acc ,@else)))
+        then)))
+
+(defmacro -if-let (var-val then &rest else)
+  "If VAL evaluates to non-nil, bind it to VAR and do THEN,
+otherwise do ELSE.
+
+Note: binding is done according to `-let'.
+
+\(fn (VAR VAL) THEN &rest ELSE)"
+  (declare (debug ((sexp form) form body))
+           (indent 2))
+  `(-if-let* (,var-val) ,then ,@else))
+
+(defmacro --if-let (val then &rest else)
+  "If VAL evaluates to non-nil, bind it to symbol `it' and do THEN,
+otherwise do ELSE."
+  (declare (debug (form form body))
+           (indent 2))
+  `(-if-let (it ,val) ,then ,@else))
+
+(defmacro -when-let* (vars-vals &rest body)
+  "If all VALS evaluate to true, bind them to their corresponding
+VARS and execute body. VARS-VALS should be a list of (VAR VAL)
+pairs.
+
+Note: binding is done according to `-let*'.  VALS are evaluated
+sequentially, and evaluation stops after the first nil VAL is
+encountered."
+  (declare (debug ((&rest (sexp form)) body))
+           (indent 1))
+  `(-if-let* ,vars-vals (progn ,@body)))
+
+(defmacro -when-let (var-val &rest body)
+  "If VAL evaluates to non-nil, bind it to VAR and execute body.
+
+Note: binding is done according to `-let'.
+
+\(fn (VAR VAL) &rest BODY)"
+  (declare (debug ((sexp form) body))
+           (indent 1))
+  `(-if-let ,var-val (progn ,@body)))
+
+(defmacro --when-let (val &rest body)
+  "If VAL evaluates to non-nil, bind it to symbol `it' and
+execute body."
+  (declare (debug (form body))
+           (indent 1))
+  `(--if-let ,val (progn ,@body)))
+
+(defvar -compare-fn nil
+  "Tests for equality use this function or `equal' if this is nil.
+It should only be set using dynamic scope with a let, like:
+
+  (let ((-compare-fn #\\='=)) (-union numbers1 numbers2 numbers3)")
+
+(defun -distinct (list)
+  "Return a new list with all duplicates removed.
+The test for equality is done with `equal',
+or with `-compare-fn' if that's non-nil.
+
+Alias: `-uniq'"
+  (let (result)
+    (--each list (unless (-contains? result it) (!cons it result)))
+    (nreverse result)))
+
+(defalias '-uniq '-distinct)
+
+(defun -union (list list2)
+  "Return a new list containing the elements of LIST and elements of LIST2 that are not in LIST.
+The test for equality is done with `equal',
+or with `-compare-fn' if that's non-nil."
+  ;; We fall back to iteration implementation if the comparison
+  ;; function isn't one of `eq', `eql' or `equal'.
+  (let* ((result (reverse list))
+         ;; TODO: get rid of this dynamic variable, pass it as an
+         ;; argument instead.
+         (-compare-fn (if (bound-and-true-p -compare-fn)
+                          -compare-fn
+                        'equal)))
+    (if (memq -compare-fn '(eq eql equal))
+        (let ((ht (make-hash-table :test -compare-fn)))
+          (--each list (puthash it t ht))
+          (--each list2 (unless (gethash it ht) (!cons it result))))
+      (--each list2 (unless (-contains? result it) (!cons it result))))
+    (nreverse result)))
+
+(defun -intersection (list list2)
+  "Return a new list containing only the elements that are members of both LIST and LIST2.
+The test for equality is done with `equal',
+or with `-compare-fn' if that's non-nil."
+  (--filter (-contains? list2 it) list))
+
+(defun -difference (list list2)
+  "Return a new list with only the members of LIST that are not in LIST2.
+The test for equality is done with `equal',
+or with `-compare-fn' if that's non-nil."
+  (--filter (not (-contains? list2 it)) list))
+
+(defun -powerset (list)
+  "Return the power set of LIST."
+  (if (null list) '(())
+    (let ((last (-powerset (cdr list))))
+      (append (mapcar (lambda (x) (cons (car list) x)) last)
+              last))))
+
+(defun -permutations (list)
+  "Return the permutations of LIST."
+  (if (null list) '(())
+    (apply #'append
+           (mapcar (lambda (x)
+                     (mapcar (lambda (perm) (cons x perm))
+                             (-permutations (remove x list))))
+                   list))))
+
+(defun -inits (list)
+  "Return all prefixes of LIST."
+  (nreverse (-map 'reverse (-tails (nreverse list)))))
+
+(defun -tails (list)
+  "Return all suffixes of LIST"
+  (-reductions-r-from 'cons nil list))
+
+(defun -common-prefix (&rest lists)
+  "Return the longest common prefix of LISTS."
+  (declare (pure t) (side-effect-free t))
+  (--reduce (--take-while (and acc (equal (pop acc) it)) it)
+            lists))
+
+(defun -contains? (list element)
+  "Return non-nil if LIST contains ELEMENT.
+
+The test for equality is done with `equal', or with `-compare-fn'
+if that's non-nil.
+
+Alias: `-contains-p'"
+  (not
+   (null
+    (cond
+     ((null -compare-fn)    (member element list))
+     ((eq -compare-fn 'eq)  (memq element list))
+     ((eq -compare-fn 'eql) (memql element list))
+     (t
+      (let ((lst list))
+        (while (and lst
+                    (not (funcall -compare-fn element (car lst))))
+          (setq lst (cdr lst)))
+        lst))))))
+
+(defalias '-contains-p '-contains?)
+
+(defun -same-items? (list list2)
+  "Return true if LIST and LIST2 has the same items.
+
+The order of the elements in the lists does not matter.
+
+Alias: `-same-items-p'"
+  (let ((length-a (length list))
+        (length-b (length list2)))
+    (and
+     (= length-a length-b)
+     (= length-a (length (-intersection list list2))))))
+
+(defalias '-same-items-p '-same-items?)
+
+(defun -is-prefix? (prefix list)
+  "Return non-nil if PREFIX is prefix of LIST.
+
+Alias: `-is-prefix-p'"
+  (declare (pure t) (side-effect-free t))
+  (--each-while list (equal (car prefix) it)
+    (!cdr prefix))
+  (not prefix))
+
+(defun -is-suffix? (suffix list)
+  "Return non-nil if SUFFIX is suffix of LIST.
+
+Alias: `-is-suffix-p'"
+  (declare (pure t) (side-effect-free t))
+  (-is-prefix? (reverse suffix) (reverse list)))
+
+(defun -is-infix? (infix list)
+  "Return non-nil if INFIX is infix of LIST.
+
+This operation runs in O(n^2) time
+
+Alias: `-is-infix-p'"
+  (declare (pure t) (side-effect-free t))
+  (let (done)
+    (while (and (not done) list)
+      (setq done (-is-prefix? infix list))
+      (!cdr list))
+    done))
+
+(defalias '-is-prefix-p '-is-prefix?)
+(defalias '-is-suffix-p '-is-suffix?)
+(defalias '-is-infix-p '-is-infix?)
+
+(defun -sort (comparator list)
+  "Sort LIST, stably, comparing elements using COMPARATOR.
+Return the sorted list.  LIST is NOT modified by side effects.
+COMPARATOR is called with two elements of LIST, and should return non-nil
+if the first element should sort before the second."
+  (sort (copy-sequence list) comparator))
+
+(defmacro --sort (form list)
+  "Anaphoric form of `-sort'."
+  (declare (debug (form form)))
+  `(-sort (lambda (it other) ,form) ,list))
+
+(defun -list (&rest args)
+  "Return a list with ARGS.
+
+If first item of ARGS is already a list, simply return ARGS.  If
+not, return a list with ARGS as elements."
+  (declare (pure t) (side-effect-free t))
+  (let ((arg (car args)))
+    (if (listp arg) arg args)))
+
+(defun -repeat (n x)
+  "Return a list with X repeated N times.
+Return nil if N is less than 1."
+  (declare (pure t) (side-effect-free t))
+  (let (ret)
+    (--dotimes n (!cons x ret))
+    ret))
+
+(defun -sum (list)
+  "Return the sum of LIST."
+  (declare (pure t) (side-effect-free t))
+  (apply '+ list))
+
+(defun -running-sum (list)
+  "Return a list with running sums of items in LIST.
+
+LIST must be non-empty."
+  (declare (pure t) (side-effect-free t))
+  (unless (consp list)
+    (error "LIST must be non-empty"))
+  (-reductions '+ list))
+
+(defun -product (list)
+  "Return the product of LIST."
+  (declare (pure t) (side-effect-free t))
+  (apply '* list))
+
+(defun -running-product (list)
+  "Return a list with running products of items in LIST.
+
+LIST must be non-empty."
+  (declare (pure t) (side-effect-free t))
+  (unless (consp list)
+    (error "LIST must be non-empty"))
+  (-reductions '* list))
+
+(defun -max (list)
+  "Return the largest value from LIST of numbers or markers."
+  (declare (pure t) (side-effect-free t))
+  (apply 'max list))
+
+(defun -min (list)
+  "Return the smallest value from LIST of numbers or markers."
+  (declare (pure t) (side-effect-free t))
+  (apply 'min list))
+
+(defun -max-by (comparator list)
+  "Take a comparison function COMPARATOR and a LIST and return
+the greatest element of the list by the comparison function.
+
+See also combinator `-on' which can transform the values before
+comparing them."
+  (--reduce (if (funcall comparator it acc) it acc) list))
+
+(defun -min-by (comparator list)
+  "Take a comparison function COMPARATOR and a LIST and return
+the least element of the list by the comparison function.
+
+See also combinator `-on' which can transform the values before
+comparing them."
+  (--reduce (if (funcall comparator it acc) acc it) list))
+
+(defmacro --max-by (form list)
+  "Anaphoric version of `-max-by'.
+
+The items for the comparator form are exposed as \"it\" and \"other\"."
+  (declare (debug (form form)))
+  `(-max-by (lambda (it other) ,form) ,list))
+
+(defmacro --min-by (form list)
+  "Anaphoric version of `-min-by'.
+
+The items for the comparator form are exposed as \"it\" and \"other\"."
+  (declare (debug (form form)))
+  `(-min-by (lambda (it other) ,form) ,list))
+
+(defun -iterate (fun init n)
+  "Return a list of iterated applications of FUN to INIT.
+
+This means a list of form:
+
+  (init (fun init) (fun (fun init)) ...)
+
+N is the length of the returned list."
+  (if (= n 0) nil
+    (let ((r (list init)))
+      (--dotimes (1- n)
+        (push (funcall fun (car r)) r))
+      (nreverse r))))
+
+(defun -fix (fn list)
+  "Compute the (least) fixpoint of FN with initial input LIST.
+
+FN is called at least once, results are compared with `equal'."
+  (let ((re (funcall fn list)))
+    (while (not (equal list re))
+      (setq list re)
+      (setq re (funcall fn re)))
+    re))
+
+(defmacro --fix (form list)
+  "Anaphoric form of `-fix'."
+  `(-fix (lambda (it) ,form) ,list))
+
+(defun -unfold (fun seed)
+  "Build a list from SEED using FUN.
+
+This is \"dual\" operation to `-reduce-r': while -reduce-r
+consumes a list to produce a single value, `-unfold' takes a
+seed value and builds a (potentially infinite!) list.
+
+FUN should return `nil' to stop the generating process, or a
+cons (A . B), where A will be prepended to the result and B is
+the new seed."
+  (let ((last (funcall fun seed)) r)
+    (while last
+      (push (car last) r)
+      (setq last (funcall fun (cdr last))))
+    (nreverse r)))
+
+(defmacro --unfold (form seed)
+  "Anaphoric version of `-unfold'."
+  (declare (debug (form form)))
+  `(-unfold (lambda (it) ,form) ,seed))
+
+(defun -cons-pair? (con)
+  "Return non-nil if CON is true cons pair.
+That is (A . B) where B is not a list."
+  (declare (pure t) (side-effect-free t))
+  (and (listp con)
+       (not (listp (cdr con)))))
+
+(defun -cons-to-list (con)
+  "Convert a cons pair to a list with `car' and `cdr' of the pair respectively."
+  (declare (pure t) (side-effect-free t))
+  (list (car con) (cdr con)))
+
+(defun -value-to-list (val)
+  "Convert a value to a list.
+
+If the value is a cons pair, make a list with two elements, `car'
+and `cdr' of the pair respectively.
+
+If the value is anything else, wrap it in a list."
+  (declare (pure t) (side-effect-free t))
+  (cond
+   ((-cons-pair? val) (-cons-to-list val))
+   (t (list val))))
+
+(defun -tree-mapreduce-from (fn folder init-value tree)
+  "Apply FN to each element of TREE, and make a list of the results.
+If elements of TREE are lists themselves, apply FN recursively to
+elements of these nested lists.
+
+Then reduce the resulting lists using FOLDER and initial value
+INIT-VALUE. See `-reduce-r-from'.
+
+This is the same as calling `-tree-reduce-from' after `-tree-map'
+but is twice as fast as it only traverse the structure once."
+  (cond
+   ((not tree) nil)
+   ((-cons-pair? tree) (funcall fn tree))
+   ((listp tree)
+    (-reduce-r-from folder init-value (mapcar (lambda (x) (-tree-mapreduce-from fn folder init-value x)) tree)))
+   (t (funcall fn tree))))
+
+(defmacro --tree-mapreduce-from (form folder init-value tree)
+  "Anaphoric form of `-tree-mapreduce-from'."
+  (declare (debug (form form form form)))
+  `(-tree-mapreduce-from (lambda (it) ,form) (lambda (it acc) ,folder) ,init-value ,tree))
+
+(defun -tree-mapreduce (fn folder tree)
+  "Apply FN to each element of TREE, and make a list of the results.
+If elements of TREE are lists themselves, apply FN recursively to
+elements of these nested lists.
+
+Then reduce the resulting lists using FOLDER and initial value
+INIT-VALUE. See `-reduce-r-from'.
+
+This is the same as calling `-tree-reduce' after `-tree-map'
+but is twice as fast as it only traverse the structure once."
+  (cond
+   ((not tree) nil)
+   ((-cons-pair? tree) (funcall fn tree))
+   ((listp tree)
+    (-reduce-r folder (mapcar (lambda (x) (-tree-mapreduce fn folder x)) tree)))
+   (t (funcall fn tree))))
+
+(defmacro --tree-mapreduce (form folder tree)
+  "Anaphoric form of `-tree-mapreduce'."
+  (declare (debug (form form form)))
+  `(-tree-mapreduce (lambda (it) ,form) (lambda (it acc) ,folder) ,tree))
+
+(defun -tree-map (fn tree)
+  "Apply FN to each element of TREE while preserving the tree structure."
+  (cond
+   ((not tree) nil)
+   ((-cons-pair? tree) (funcall fn tree))
+   ((listp tree)
+    (mapcar (lambda (x) (-tree-map fn x)) tree))
+   (t (funcall fn tree))))
+
+(defmacro --tree-map (form tree)
+  "Anaphoric form of `-tree-map'."
+  (declare (debug (form form)))
+  `(-tree-map (lambda (it) ,form) ,tree))
+
+(defun -tree-reduce-from (fn init-value tree)
+  "Use FN to reduce elements of list TREE.
+If elements of TREE are lists themselves, apply the reduction recursively.
+
+FN is first applied to INIT-VALUE and first element of the list,
+then on this result and second element from the list etc.
+
+The initial value is ignored on cons pairs as they always contain
+two elements."
+  (cond
+   ((not tree) nil)
+   ((-cons-pair? tree) tree)
+   ((listp tree)
+    (-reduce-r-from fn init-value (mapcar (lambda (x) (-tree-reduce-from fn init-value x)) tree)))
+   (t tree)))
+
+(defmacro --tree-reduce-from (form init-value tree)
+  "Anaphoric form of `-tree-reduce-from'."
+  (declare (debug (form form form)))
+  `(-tree-reduce-from (lambda (it acc) ,form) ,init-value ,tree))
+
+(defun -tree-reduce (fn tree)
+  "Use FN to reduce elements of list TREE.
+If elements of TREE are lists themselves, apply the reduction recursively.
+
+FN is first applied to first element of the list and second
+element, then on this result and third element from the list etc.
+
+See `-reduce-r' for how exactly are lists of zero or one element handled."
+  (cond
+   ((not tree) nil)
+   ((-cons-pair? tree) tree)
+   ((listp tree)
+    (-reduce-r fn (mapcar (lambda (x) (-tree-reduce fn x)) tree)))
+   (t tree)))
+
+(defmacro --tree-reduce (form tree)
+  "Anaphoric form of `-tree-reduce'."
+  (declare (debug (form form)))
+  `(-tree-reduce (lambda (it acc) ,form) ,tree))
+
+(defun -tree-map-nodes (pred fun tree)
+  "Call FUN on each node of TREE that satisfies PRED.
+
+If PRED returns nil, continue descending down this node.  If PRED
+returns non-nil, apply FUN to this node and do not descend
+further."
+  (if (funcall pred tree)
+      (funcall fun tree)
+    (if (and (listp tree)
+             (not (-cons-pair? tree)))
+        (-map (lambda (x) (-tree-map-nodes pred fun x)) tree)
+      tree)))
+
+(defmacro --tree-map-nodes (pred form tree)
+  "Anaphoric form of `-tree-map-nodes'."
+  `(-tree-map-nodes (lambda (it) ,pred) (lambda (it) ,form) ,tree))
+
+(defun -tree-seq (branch children tree)
+  "Return a sequence of the nodes in TREE, in depth-first search order.
+
+BRANCH is a predicate of one argument that returns non-nil if the
+passed argument is a branch, that is, a node that can have children.
+
+CHILDREN is a function of one argument that returns the children
+of the passed branch node.
+
+Non-branch nodes are simply copied."
+  (cons tree
+        (when (funcall branch tree)
+          (-mapcat (lambda (x) (-tree-seq branch children x))
+                   (funcall children tree)))))
+
+(defmacro --tree-seq (branch children tree)
+  "Anaphoric form of `-tree-seq'."
+  `(-tree-seq (lambda (it) ,branch) (lambda (it) ,children) ,tree))
+
+(defun -clone (list)
+  "Create a deep copy of LIST.
+The new list has the same elements and structure but all cons are
+replaced with new ones.  This is useful when you need to clone a
+structure such as plist or alist."
+  (declare (pure t) (side-effect-free t))
+  (-tree-map 'identity list))
+
+(defun dash-enable-font-lock ()
+  "Add syntax highlighting to dash functions, macros and magic values."
+  (eval-after-load 'lisp-mode
+    '(progn
+       (let ((new-keywords '(
+                             "!cons"
+                             "!cdr"
+                             "-each"
+                             "--each"
+                             "-each-indexed"
+                             "--each-indexed"
+                             "-each-while"
+                             "--each-while"
+                             "-doto"
+                             "-dotimes"
+                             "--dotimes"
+                             "-map"
+                             "--map"
+                             "-reduce-from"
+                             "--reduce-from"
+                             "-reduce"
+                             "--reduce"
+                             "-reduce-r-from"
+                             "--reduce-r-from"
+                             "-reduce-r"
+                             "--reduce-r"
+                             "-reductions-from"
+                             "-reductions-r-from"
+                             "-reductions"
+                             "-reductions-r"
+                             "-filter"
+                             "--filter"
+                             "-select"
+                             "--select"
+                             "-remove"
+                             "--remove"
+                             "-reject"
+                             "--reject"
+                             "-remove-first"
+                             "--remove-first"
+                             "-reject-first"
+                             "--reject-first"
+                             "-remove-last"
+                             "--remove-last"
+                             "-reject-last"
+                             "--reject-last"
+                             "-remove-item"
+                             "-non-nil"
+                             "-keep"
+                             "--keep"
+                             "-map-indexed"
+                             "--map-indexed"
+                             "-splice"
+                             "--splice"
+                             "-splice-list"
+                             "--splice-list"
+                             "-map-when"
+                             "--map-when"
+                             "-replace-where"
+                             "--replace-where"
+                             "-map-first"
+                             "--map-first"
+                             "-map-last"
+                             "--map-last"
+                             "-replace"
+                             "-replace-first"
+                             "-replace-last"
+                             "-flatten"
+                             "-flatten-n"
+                             "-concat"
+                             "-mapcat"
+                             "--mapcat"
+                             "-copy"
+                             "-cons*"
+                             "-snoc"
+                             "-first"
+                             "--first"
+                             "-find"
+                             "--find"
+                             "-some"
+                             "--some"
+                             "-any"
+                             "--any"
+                             "-last"
+                             "--last"
+                             "-first-item"
+                             "-second-item"
+                             "-third-item"
+                             "-fourth-item"
+                             "-fifth-item"
+                             "-last-item"
+                             "-butlast"
+                             "-count"
+                             "--count"
+                             "-any?"
+                             "--any?"
+                             "-some?"
+                             "--some?"
+                             "-any-p"
+                             "--any-p"
+                             "-some-p"
+                             "--some-p"
+                             "-some->"
+                             "-some->>"
+                             "-some-->"
+                             "-all?"
+                             "-all-p"
+                             "--all?"
+                             "--all-p"
+                             "-every?"
+                             "--every?"
+                             "-all-p"
+                             "--all-p"
+                             "-every-p"
+                             "--every-p"
+                             "-none?"
+                             "--none?"
+                             "-none-p"
+                             "--none-p"
+                             "-only-some?"
+                             "--only-some?"
+                             "-only-some-p"
+                             "--only-some-p"
+                             "-slice"
+                             "-take"
+                             "-drop"
+                             "-drop-last"
+                             "-take-last"
+                             "-take-while"
+                             "--take-while"
+                             "-drop-while"
+                             "--drop-while"
+                             "-split-at"
+                             "-rotate"
+                             "-insert-at"
+                             "-replace-at"
+                             "-update-at"
+                             "--update-at"
+                             "-remove-at"
+                             "-remove-at-indices"
+                             "-split-with"
+                             "--split-with"
+                             "-split-on"
+                             "-split-when"
+                             "--split-when"
+                             "-separate"
+                             "--separate"
+                             "-partition-all-in-steps"
+                             "-partition-in-steps"
+                             "-partition-all"
+                             "-partition"
+                             "-partition-after-item"
+                             "-partition-after-pred"
+                             "-partition-before-item"
+                             "-partition-before-pred"
+                             "-partition-by"
+                             "--partition-by"
+                             "-partition-by-header"
+                             "--partition-by-header"
+                             "-group-by"
+                             "--group-by"
+                             "-interpose"
+                             "-interleave"
+                             "-unzip"
+                             "-zip-with"
+                             "--zip-with"
+                             "-zip"
+                             "-zip-fill"
+                             "-zip-pair"
+                             "-cycle"
+                             "-pad"
+                             "-annotate"
+                             "--annotate"
+                             "-table"
+                             "-table-flat"
+                             "-partial"
+                             "-elem-index"
+                             "-elem-indices"
+                             "-find-indices"
+                             "--find-indices"
+                             "-find-index"
+                             "--find-index"
+                             "-find-last-index"
+                             "--find-last-index"
+                             "-select-by-indices"
+                             "-select-columns"
+                             "-select-column"
+                             "-grade-up"
+                             "-grade-down"
+                             "->"
+                             "->>"
+                             "-->"
+                             "-as->"
+                             "-when-let"
+                             "-when-let*"
+                             "--when-let"
+                             "-if-let"
+                             "-if-let*"
+                             "--if-let"
+                             "-let*"
+                             "-let"
+                             "-lambda"
+                             "-distinct"
+                             "-uniq"
+                             "-union"
+                             "-intersection"
+                             "-difference"
+                             "-powerset"
+                             "-permutations"
+                             "-inits"
+                             "-tails"
+                             "-common-prefix"
+                             "-contains?"
+                             "-contains-p"
+                             "-same-items?"
+                             "-same-items-p"
+                             "-is-prefix-p"
+                             "-is-prefix?"
+                             "-is-suffix-p"
+                             "-is-suffix?"
+                             "-is-infix-p"
+                             "-is-infix?"
+                             "-sort"
+                             "--sort"
+                             "-list"
+                             "-repeat"
+                             "-sum"
+                             "-running-sum"
+                             "-product"
+                             "-running-product"
+                             "-max"
+                             "-min"
+                             "-max-by"
+                             "--max-by"
+                             "-min-by"
+                             "--min-by"
+                             "-iterate"
+                             "--iterate"
+                             "-fix"
+                             "--fix"
+                             "-unfold"
+                             "--unfold"
+                             "-cons-pair?"
+                             "-cons-to-list"
+                             "-value-to-list"
+                             "-tree-mapreduce-from"
+                             "--tree-mapreduce-from"
+                             "-tree-mapreduce"
+                             "--tree-mapreduce"
+                             "-tree-map"
+                             "--tree-map"
+                             "-tree-reduce-from"
+                             "--tree-reduce-from"
+                             "-tree-reduce"
+                             "--tree-reduce"
+                             "-tree-seq"
+                             "--tree-seq"
+                             "-tree-map-nodes"
+                             "--tree-map-nodes"
+                             "-clone"
+                             "-rpartial"
+                             "-juxt"
+                             "-applify"
+                             "-on"
+                             "-flip"
+                             "-const"
+                             "-cut"
+                             "-orfn"
+                             "-andfn"
+                             "-iteratefn"
+                             "-fixfn"
+                             "-prodfn"
+                             ))
+             (special-variables '(
+                                  "it"
+                                  "it-index"
+                                  "acc"
+                                  "other"
+                                  )))
+         (font-lock-add-keywords 'emacs-lisp-mode `((,(concat "\\_<" (regexp-opt special-variables 'paren) "\\_>")
+                                                     1 font-lock-variable-name-face)) 'append)
+         (font-lock-add-keywords 'emacs-lisp-mode `((,(concat "(\\s-*" (regexp-opt new-keywords 'paren) "\\_>")
+                                                     1 font-lock-keyword-face)) 'append))
+       (--each (buffer-list)
+         (with-current-buffer it
+           (when (and (eq major-mode 'emacs-lisp-mode)
+                      (boundp 'font-lock-mode)
+                      font-lock-mode)
+             (font-lock-refresh-defaults)))))))
+
+(provide 'dash)
+;;; dash.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/dash-20180413.30/dash.elc b/configs/shared/emacs/.emacs.d/elpa/dash-20180413.30/dash.elc
new file mode 100644
index 0000000000..7a9ab22551
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/dash-20180413.30/dash.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/dash-functional-20180107.818/dash-functional-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/dash-functional-20180107.818/dash-functional-autoloads.el
new file mode 100644
index 0000000000..c36c5328b1
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/dash-functional-20180107.818/dash-functional-autoloads.el
@@ -0,0 +1,16 @@
+;;; dash-functional-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil nil ("dash-functional.el") (23377 61505 65755
+;;;;;;  274000))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; dash-functional-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/dash-functional-20180107.818/dash-functional-pkg.el b/configs/shared/emacs/.emacs.d/elpa/dash-functional-20180107.818/dash-functional-pkg.el
new file mode 100644
index 0000000000..e44bec2ede
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/dash-functional-20180107.818/dash-functional-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "dash-functional" "20180107.818" "Collection of useful combinators for Emacs Lisp" '((dash "2.0.0") (emacs "24")))
diff --git a/configs/shared/emacs/.emacs.d/elpa/dash-functional-20180107.818/dash-functional.el b/configs/shared/emacs/.emacs.d/elpa/dash-functional-20180107.818/dash-functional.el
new file mode 100644
index 0000000000..7479f23661
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/dash-functional-20180107.818/dash-functional.el
@@ -0,0 +1,219 @@
+;;; dash-functional.el --- Collection of useful combinators for Emacs Lisp  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2013-2014 Free Software Foundation, Inc.
+
+;; Authors: Matus Goljer <matus.goljer@gmail.com>
+;;          Magnar Sveen <magnars@gmail.com>
+;; Version: 1.2.0
+;; Package-Version: 20180107.818
+;; Package-Requires: ((dash "2.0.0") (emacs "24"))
+;; Keywords: lisp functions combinators
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Collection of useful combinators for Emacs Lisp
+;;
+;; See documentation on https://github.com/magnars/dash.el#functions
+
+;;; Code:
+
+(require 'dash)
+
+(defun -partial (fn &rest args)
+  "Takes a function FN and fewer than the normal arguments to FN,
+and returns a fn that takes a variable number of additional ARGS.
+When called, the returned function calls FN with ARGS first and
+then additional args."
+  (apply 'apply-partially fn args))
+
+(defun -rpartial (fn &rest args)
+  "Takes a function FN and fewer than the normal arguments to FN,
+and returns a fn that takes a variable number of additional ARGS.
+When called, the returned function calls FN with the additional
+args first and then ARGS."
+  (lambda (&rest args-before) (apply fn (append args-before args))))
+
+(defun -juxt (&rest fns)
+  "Takes a list of functions and returns a fn that is the
+juxtaposition of those fns. The returned fn takes a variable
+number of args, and returns a list containing the result of
+applying each fn to the args (left-to-right)."
+  (lambda (&rest args) (mapcar (lambda (x) (apply x args)) fns)))
+
+(defun -compose (&rest fns)
+  "Takes a list of functions and returns a fn that is the
+composition of those fns. The returned fn takes a variable
+number of arguments, and returns the result of applying
+each fn to the result of applying the previous fn to
+the arguments (right-to-left)."
+  (lambda (&rest args)
+    (car (-reduce-r-from (lambda (fn xs) (list (apply fn xs)))
+                         args fns))))
+
+(defun -applify (fn)
+  "Changes an n-arity function FN to a 1-arity function that
+expects a list with n items as arguments"
+  (apply-partially 'apply fn))
+
+(defun -on (operator transformer)
+  "Return a function of two arguments that first applies
+TRANSFORMER to each of them and then applies OPERATOR on the
+results (in the same order).
+
+In types: (b -> b -> c) -> (a -> b) -> a -> a -> c"
+  (lambda (x y) (funcall operator (funcall transformer x) (funcall transformer y))))
+
+(defun -flip (func)
+  "Swap the order of arguments for binary function FUNC.
+
+In types: (a -> b -> c) -> b -> a -> c"
+  (lambda (x y) (funcall func y x)))
+
+(defun -const (c)
+  "Return a function that returns C ignoring any additional arguments.
+
+In types: a -> b -> a"
+  (lambda (&rest _) c))
+
+(defmacro -cut (&rest params)
+  "Take n-ary function and n arguments and specialize some of them.
+Arguments denoted by <> will be left unspecialized.
+
+See SRFI-26 for detailed description."
+  (let* ((i 0)
+         (args (mapcar (lambda (_) (setq i (1+ i)) (make-symbol (format "D%d" i)))
+                       (-filter (-partial 'eq '<>) params))))
+    `(lambda ,args
+       ,(let ((body (--map (if (eq it '<>) (pop args) it) params)))
+          (if (eq (car params) '<>)
+              (cons 'funcall body)
+            body)))))
+
+(defun -not (pred)
+  "Take a unary predicate PRED and return a unary predicate
+that returns t if PRED returns nil and nil if PRED returns
+non-nil."
+  (lambda (x) (not (funcall pred x))))
+
+(defun -orfn (&rest preds)
+  "Take list of unary predicates PREDS and return a unary
+predicate with argument x that returns non-nil if at least one of
+the PREDS returns non-nil on x.
+
+In types: [a -> Bool] -> a -> Bool"
+  (lambda (x) (-any? (-cut funcall <> x) preds)))
+
+(defun -andfn (&rest preds)
+  "Take list of unary predicates PREDS and return a unary
+predicate with argument x that returns non-nil if all of the
+PREDS returns non-nil on x.
+
+In types: [a -> Bool] -> a -> Bool"
+  (lambda (x) (-all? (-cut funcall <> x) preds)))
+
+(defun -iteratefn (fn n)
+  "Return a function FN composed N times with itself.
+
+FN is a unary function.  If you need to use a function of higher
+arity, use `-applify' first to turn it into a unary function.
+
+With n = 0, this acts as identity function.
+
+In types: (a -> a) -> Int -> a -> a.
+
+This function satisfies the following law:
+
+  (funcall (-iteratefn fn n) init) = (-last-item (-iterate fn init (1+ n)))."
+  (lambda (x) (--dotimes n (setq x (funcall fn x))) x))
+
+(defun -counter (&optional beg end inc)
+  "Return a closure that counts from BEG to END, with increment INC.
+
+The closure will return the next value in the counting sequence
+each time it is called, and nil after END is reached. BEG
+defaults to 0, INC defaults to 1, and if END is nil, the counter
+will increment indefinitely.
+
+The closure accepts any number of arguments, which are discarded."
+  (let ((inc (or inc 1))
+        (n (or beg 0)))
+    (lambda (&rest _)
+      (when (or (not end) (< n end))
+        (prog1 n
+          (setq n (+ n inc)))))))
+
+(defvar -fixfn-max-iterations 1000
+  "The default maximum number of iterations performed by `-fixfn'
+  unless otherwise specified.")
+
+(defun -fixfn (fn &optional equal-test halt-test)
+  "Return a function that computes the (least) fixpoint of FN.
+
+FN must be a unary function. The returned lambda takes a single
+argument, X, the initial value for the fixpoint iteration. The
+iteration halts when either of the following conditions is satisified:
+
+ 1. Iteration converges to the fixpoint, with equality being
+    tested using EQUAL-TEST. If EQUAL-TEST is not specified,
+    `equal' is used. For functions over the floating point
+    numbers, it may be necessary to provide an appropriate
+    appoximate comparsion test.
+
+ 2. HALT-TEST returns a non-nil value. HALT-TEST defaults to a
+    simple counter that returns t after `-fixfn-max-iterations',
+    to guard against infinite iteration. Otherwise, HALT-TEST
+    must be a function that accepts a single argument, the
+    current value of X, and returns non-nil as long as iteration
+    should continue. In this way, a more sophisticated
+    convergence test may be supplied by the caller.
+
+The return value of the lambda is either the fixpoint or, if
+iteration halted before converging, a cons with car `halted' and
+cdr the final output from HALT-TEST.
+
+In types: (a -> a) -> a -> a."
+  (let ((eqfn   (or equal-test 'equal))
+    (haltfn (or halt-test
+            (-not
+              (-counter 0 -fixfn-max-iterations)))))
+    (lambda (x)
+      (let ((re (funcall fn x))
+        (halt? (funcall haltfn x)))
+    (while (and (not halt?) (not (funcall eqfn x re)))
+      (setq x     re
+        re    (funcall fn re)
+        halt? (funcall haltfn re)))
+    (if halt? (cons 'halted halt?)
+      re)))))
+
+(defun -prodfn (&rest fns)
+  "Take a list of n functions and return a function that takes a
+list of length n, applying i-th function to i-th element of the
+input list.  Returns a list of length n.
+
+In types (for n=2): ((a -> b), (c -> d)) -> (a, c) -> (b, d)
+
+This function satisfies the following laws:
+
+  (-compose (-prodfn f g ...) (-prodfn f\\=' g\\=' ...)) = (-prodfn (-compose f f\\=') (-compose g g\\=') ...)
+  (-prodfn f g ...) = (-juxt (-compose f (-partial \\='nth 0)) (-compose g (-partial \\='nth 1)) ...)
+  (-compose (-prodfn f g ...) (-juxt f\\=' g\\=' ...)) = (-juxt (-compose f f\\=') (-compose g g\\=') ...)
+  (-compose (-partial \\='nth n) (-prod f1 f2 ...)) = (-compose fn (-partial \\='nth n))"
+  (lambda (x) (-zip-with 'funcall fns x)))
+
+(provide 'dash-functional)
+
+;;; dash-functional.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/dash-functional-20180107.818/dash-functional.elc b/configs/shared/emacs/.emacs.d/elpa/dash-functional-20180107.818/dash-functional.elc
new file mode 100644
index 0000000000..267a08033e
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/dash-functional-20180107.818/dash-functional.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/diminish-20170419.1036/diminish-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/diminish-20170419.1036/diminish-autoloads.el
new file mode 100644
index 0000000000..760876a292
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/diminish-20170419.1036/diminish-autoloads.el
@@ -0,0 +1,57 @@
+;;; diminish-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "diminish" "diminish.el" (23377 61284 359176
+;;;;;;  630000))
+;;; Generated autoloads from diminish.el
+
+(autoload 'diminish "diminish" "\
+Diminish mode-line display of minor mode MODE to TO-WHAT (default \"\").
+
+Interactively, enter (with completion) the name of any minor mode, followed
+on the next line by what you want it diminished to (default empty string).
+The response to neither prompt should be quoted.  However, in Lisp code,
+both args must be quoted, the first as a symbol, the second as a string,
+as in (diminish 'jiggle-mode \" Jgl\").
+
+The mode-line displays of minor modes usually begin with a space, so
+the modes' names appear as separate words on the mode line.  However, if
+you're having problems with a cramped mode line, you may choose to use single
+letters for some modes, without leading spaces.  Capitalizing them works
+best; if you then diminish some mode to \"X\" but have abbrev-mode enabled as
+well, you'll get a display like \"AbbrevX\".  This function prepends a space
+to TO-WHAT if it's > 1 char long & doesn't already begin with a space.
+
+\(fn MODE &optional TO-WHAT)" t nil)
+
+(autoload 'diminish-undo "diminish" "\
+Restore mode-line display of diminished mode MODE to its minor-mode value.
+Do nothing if the arg is a minor mode that hasn't been diminished.
+
+Interactively, enter (with completion) the name of any diminished mode (a
+mode that was formerly a minor mode on which you invoked \\[diminish]).
+To restore all diminished modes to minor status, answer `diminished-modes'.
+The response to the prompt shouldn't be quoted.  However, in Lisp code,
+the arg must be quoted as a symbol, as in (diminish-undo 'diminished-modes).
+
+\(fn MODE)" t nil)
+
+(autoload 'diminished-modes "diminish" "\
+Echo all active diminished or minor modes as if they were minor.
+The display goes in the echo area; if it's too long even for that,
+you can see the whole thing in the *Messages* buffer.
+This doesn't change the status of any modes; it just lets you see
+what diminished modes would be on the mode-line if they were still minor.
+
+\(fn)" t nil)
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; diminish-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/diminish-20170419.1036/diminish-pkg.el b/configs/shared/emacs/.emacs.d/elpa/diminish-20170419.1036/diminish-pkg.el
new file mode 100644
index 0000000000..9a447f4dc3
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/diminish-20170419.1036/diminish-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "diminish" "20170419.1036" "Diminished modes are minor modes with no modeline display" 'nil)
diff --git a/configs/shared/emacs/.emacs.d/elpa/diminish-20170419.1036/diminish.el b/configs/shared/emacs/.emacs.d/elpa/diminish-20170419.1036/diminish.el
new file mode 100644
index 0000000000..6efe740c48
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/diminish-20170419.1036/diminish.el
@@ -0,0 +1,294 @@
+;;; diminish.el --- Diminished modes are minor modes with no modeline display
+
+;; Copyright (C) 1998 Free Software Foundation, Inc.
+
+;; Author: Will Mengarini <seldon@eskimo.com>
+;; Maintainer: Martin Yrjölä <martin.yrjola@gmail.com>
+;; URL: <https://github.com/myrjola/diminish.el>
+;; Package-Version: 20170419.1036
+;; Created: Th 19 Feb 98
+;; Version: 0.45
+;; Keywords: extensions, diminish, minor, codeprose
+
+;; This program 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 2, or (at your option)
+;; any later version.
+
+;; This program 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
+;; this program; see the file LICENSE. If not, write to the write to the Free
+;; Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+;; 02110-1301, USA.
+
+;;; Commentary:
+
+;; Minor modes each put a word on the mode line to signify that they're
+;; active.  This can cause other displays, such as % of file that point is
+;; at, to run off the right side of the screen.  For some minor modes, such
+;; as mouse-avoidance-mode, the display is a waste of space, since users
+;; typically set the mode in their .emacs & never change it.  For other
+;; modes, such as my jiggle-mode, it's a waste because there's already a
+;; visual indication of whether the mode is in effect.
+
+;; A diminished mode is a minor mode that has had its mode line
+;; display diminished, usually to nothing, although diminishing to a
+;; shorter word or a single letter is also supported.  This package
+;; implements diminished modes.
+
+;; You can use this package either interactively or from your .emacs file.
+;; In either case, first you'll need to copy this file to a directory that
+;; appears in your load-path.  `load-path' is the name of a variable that
+;; contains a list of directories Emacs searches for files to load.
+;; To prepend another directory to load-path, put a line like
+;; (add-to-list 'load-path "c:/My_Directory") in your .emacs file.
+
+;; To create diminished modes interactively, type
+;;   M-x load-library
+;; to get a prompt like
+;;   Load library:
+;; and respond `diminish' (unquoted).  Then type
+;;   M-x diminish
+;; to get a prompt like
+;;   Diminish what minor mode:
+;; and respond with the name of some minor mode, like mouse-avoidance-mode.
+;; You'll then get this prompt:
+;;   To what mode-line display:
+;; Respond by just hitting <Enter> if you want the name of the mode
+;; completely removed from the mode line.  If you prefer, you can abbreviate
+;; the name.  If your abbreviation is 2 characters or more, such as "Av",
+;; it'll be displayed as a separate word on the mode line, just like minor
+;; modes' names.  If it's a single character, such as "V", it'll be scrunched
+;; up against the previous word, so for example if the undiminished mode line
+;; display had been "Abbrev Fill Avoid", it would become "Abbrev FillV".
+;; Multiple single-letter diminished modes will all be scrunched together.
+;; The display of undiminished modes will not be affected.
+
+;; To find out what the mode line would look like if all diminished modes
+;; were still minor, type M-x diminished-modes.  This displays in the echo
+;; area the complete list of minor or diminished modes now active, but
+;; displays them all as minor.  They remain diminished on the mode line.
+
+;; To convert a diminished mode back to a minor mode, type M-x diminish-undo
+;; to get a prompt like
+;;   Restore what diminished mode:
+;; Respond with the name of some diminished mode.  To convert all
+;; diminished modes back to minor modes, respond to that prompt
+;; with `diminished-modes' (unquoted, & note the hyphen).
+
+;; When you're responding to the prompts for mode names, you can use
+;; completion to avoid extra typing; for example, m o u SPC SPC SPC
+;; is usually enough to specify mouse-avoidance-mode.  Mode names
+;; typically end in "-mode", but for historical reasons
+;; auto-fill-mode is named by "auto-fill-function".
+
+;; To create diminished modes noninteractively in your .emacs file, put
+;; code like
+;;   (require 'diminish)
+;;   (diminish 'abbrev-mode "Abv")
+;;   (diminish 'jiggle-mode)
+;;   (diminish 'mouse-avoidance-mode "M")
+;; near the end of your .emacs file.  It should be near the end so that any
+;; minor modes your .emacs loads will already have been loaded by the time
+;; they're to be converted to diminished modes.
+
+;; To diminish a major mode, (setq mode-name "whatever") in the mode hook.
+
+;;; Epigraph:
+
+;;         "The quality of our thoughts is bordered on all sides
+;;          by our facility with language."
+;;               --J. Michael Straczynski
+
+;;; Code:
+
+(eval-when-compile (require 'cl))
+
+(defvar diminish-must-not-copy-minor-mode-alist nil
+  "Non-nil means loading diminish.el won't (copy-alist minor-mode-alist).
+Normally `minor-mode-alist' is setq to that copy on loading diminish because
+at least one of its cons cells, that for abbrev-mode, is read-only (see
+ELisp Info on \"pure storage\").  If you setq this variable to t & then
+try to diminish abbrev-mode under GNU Emacs 19.34, you'll get the error
+message \"Attempt to modify read-only object\".")
+
+(or diminish-must-not-copy-minor-mode-alist
+    (callf copy-alist minor-mode-alist))
+
+(defvar diminished-mode-alist nil
+  "The original `minor-mode-alist' value of all (diminish)ed modes.")
+
+(defvar diminish-history-symbols nil
+  "Command history for symbols of diminished modes.")
+
+(defvar diminish-history-names nil
+  "Command history for names of diminished modes.")
+
+;; When we diminish a mode, we are saying we want it to continue doing its
+;; work for us, but we no longer want to be reminded of it.  It becomes a
+;; night worker, like a janitor; it becomes an invisible man; it remains a
+;; component, perhaps an important one, sometimes an indispensable one, of
+;; the mechanism that maintains the day-people's world, but its place in
+;; their thoughts is diminished, usually to nothing.  As we grow old we
+;; diminish more and more such thoughts, such people, usually to nothing.
+
+;; "The wise man knows that to keep under is to endure."  The diminished
+;; often come to value their invisibility.  We speak--speak--of "the strong
+;; silent type", but only as a superficiality; a stereotype in a movie,
+;; perhaps, but even if an acquaintance, necessarily, by hypothesis, a
+;; distant one.  The strong silent type is actually a process.  It begins
+;; with introspection, continues with judgment, and is shaped by the
+;; discovery that these judgments are impractical to share; there is no
+;; appetite for the wisdom of the self-critical among the creatures of
+;; material appetite who dominate our world.  Their dominance's Darwinian
+;; implications reinforce the self-doubt that is the germ of higher wisdom.
+;; The thoughtful contemplate the evolutionary triumph of the predator.
+;; Gnostics deny the cosmos could be so evil; this must all be a prank; the
+;; thoughtful remain silent, invisible, self-diminished, and discover,
+;; perhaps at first in surprise, the freedom they thus gain, and grow strong.
+
+;;;###autoload
+(defun diminish (mode &optional to-what)
+  "Diminish mode-line display of minor mode MODE to TO-WHAT (default \"\").
+
+Interactively, enter (with completion) the name of any minor mode, followed
+on the next line by what you want it diminished to (default empty string).
+The response to neither prompt should be quoted.  However, in Lisp code,
+both args must be quoted, the first as a symbol, the second as a string,
+as in (diminish 'jiggle-mode \" Jgl\").
+
+The mode-line displays of minor modes usually begin with a space, so
+the modes' names appear as separate words on the mode line.  However, if
+you're having problems with a cramped mode line, you may choose to use single
+letters for some modes, without leading spaces.  Capitalizing them works
+best; if you then diminish some mode to \"X\" but have abbrev-mode enabled as
+well, you'll get a display like \"AbbrevX\".  This function prepends a space
+to TO-WHAT if it's > 1 char long & doesn't already begin with a space."
+  (interactive (list (read (completing-read
+                            "Diminish what minor mode: "
+                            (mapcar (lambda (x) (list (symbol-name (car x))))
+                                    minor-mode-alist)
+                            nil t nil 'diminish-history-symbols))
+                     (read-from-minibuffer
+                      "To what mode-line display: "
+                      nil nil nil 'diminish-history-names)))
+  (let ((minor (assq mode minor-mode-alist)))
+    (when minor
+        (progn (callf or to-what "")
+               (when (and (stringp to-what)
+                          (> (length to-what) 1))
+                 (or (= (string-to-char to-what) ?\ )
+                     (callf2 concat " " to-what)))
+               (or (assq mode diminished-mode-alist)
+                   (push (copy-sequence minor) diminished-mode-alist))
+               (setcdr minor (list to-what))))))
+
+;; But an image comes to me, vivid in its unreality, of a loon alone on his
+;; forest lake, shrieking his soul out into a canopy of stars.  Alone this
+;; afternoon in my warm city apartment, I can feel the bite of his night air,
+;; and smell his conifers.  In him there is no acceptance of diminishment.
+
+;; "I have a benevolent habit of pouring out myself to everybody,
+;;  and would even pay for a listener, and I am afraid
+;;  that the Athenians may think me too talkative."
+;;       --Socrates, in the /Euthyphro/
+
+;; I remember a news story about a retired plumber who had somehow managed to
+;; steal a military tank.  He rode it down city streets, rode over a parked
+;; car--no one was hurt--rode onto a freeway, that concrete symbol of the
+;; American spirit, or so we fancy it, shouting "Plumber Bob!  Plumber Bob!".
+;; He was shot dead by police.
+
+;;;###autoload
+(defun diminish-undo (mode)
+  "Restore mode-line display of diminished mode MODE to its minor-mode value.
+Do nothing if the arg is a minor mode that hasn't been diminished.
+
+Interactively, enter (with completion) the name of any diminished mode (a
+mode that was formerly a minor mode on which you invoked \\[diminish]).
+To restore all diminished modes to minor status, answer `diminished-modes'.
+The response to the prompt shouldn't be quoted.  However, in Lisp code,
+the arg must be quoted as a symbol, as in (diminish-undo 'diminished-modes)."
+  (interactive
+   (list (read (completing-read
+                "Restore what diminished mode: "
+                (cons (list "diminished-modes")
+                      (mapcar (lambda (x) (list (symbol-name (car x))))
+                              diminished-mode-alist))
+                nil t nil 'diminish-history-symbols))))
+  (if (eq mode 'diminished-modes)
+      (let ((diminished-modes diminished-mode-alist))
+        (while diminished-modes
+          (diminish-undo (caar diminished-modes))
+          (callf cdr diminished-modes)))
+    (let ((minor      (assq mode      minor-mode-alist))
+          (diminished (assq mode diminished-mode-alist)))
+      (or minor
+          (error "%S is not currently registered as a minor mode" mode))
+      (when diminished
+        (setcdr minor (cdr diminished))))))
+
+;; Plumber Bob was not from Seattle, my grey city, for rainy Seattle is a
+;; city of interiors, a city of the self-diminished.  When I moved here one
+;; sunny June I was delighted to find that ducks and geese were common in
+;; the streets.  But I hoped to find a loon or two, and all I found were
+;; ducks and geese.  I wondered about this; I wondered why there were no
+;; loons in Seattle; but my confusion resulted from my ignorance of the
+;; psychology of rain, which is to say my ignorance of diminished modes.
+;; What I needed, and lacked, was a way to discover they were there.
+
+;;;###autoload
+(defun diminished-modes ()
+  "Echo all active diminished or minor modes as if they were minor.
+The display goes in the echo area; if it's too long even for that,
+you can see the whole thing in the *Messages* buffer.
+This doesn't change the status of any modes; it just lets you see
+what diminished modes would be on the mode-line if they were still minor."
+  (interactive)
+  (let ((minor-modes minor-mode-alist)
+        message)
+    (while minor-modes
+      (when (symbol-value (caar minor-modes))
+        ;; This minor mode is active in this buffer
+        (let* ((mode-pair (car minor-modes))
+               (mode (car mode-pair))
+               (minor-pair (or (assq mode diminished-mode-alist) mode-pair))
+               (minor-name (cadr minor-pair)))
+          (when (symbolp minor-name)
+            ;; This minor mode uses symbol indirection in the cdr
+            (let ((symbols-seen (list minor-name)))
+              (while (and (symbolp (callf symbol-value minor-name))
+                          (not (memq minor-name symbols-seen)))
+                (push minor-name symbols-seen))))
+          (push minor-name message)))
+      (callf cdr minor-modes))
+    (setq message (mapconcat 'identity (nreverse message) ""))
+    (when (= (string-to-char message) ?\ )
+      (callf substring message 1))
+    (message "%s" message)))
+
+;; A human mind is a Black Forest of diminished modes.  Some are dangerous;
+;; most of the mind of an intimate is a secret stranger, and these diminished
+;; modes are rendered more unpredictable by their long isolation from the
+;; corrective influence of interaction with reality.  The student of history
+;; learns that this description applies to whole societies as well.  In some
+;; ways the self-diminished are better able to discern the night worker.
+;; They are rendered safer by their heightened awareness of others'
+;; diminished modes, and more congenial by the spare blandness of their own
+;; mode lines.  To some people rain is truly depressing, but others it just
+;; makes pensive, and, forcing them indoors where they may not have the
+;; luxury of solitude, teaches them to self-diminish.  That was what I had
+;; not understood when I was searching for loons among the ducks and geese.
+;; Loons come to Seattle all the time, but the ones that like it learn to be
+;; silent, learn to self-diminish, and take on the colors of ducks and geese.
+;; Now, here a dozen years, I can recognize them everywhere, standing quietly
+;; in line with the ducks and geese at the espresso counter, gazing placidly
+;; out on the world through loon-red eyes, thinking secret thoughts.
+
+(provide 'diminish)
+
+;;; diminish.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/diminish-20170419.1036/diminish.elc b/configs/shared/emacs/.emacs.d/elpa/diminish-20170419.1036/diminish.elc
new file mode 100644
index 0000000000..cd66baaa52
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/diminish-20170419.1036/diminish.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/docker-20180710.743/docker-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/docker-20180710.743/docker-autoloads.el
new file mode 100644
index 0000000000..48aa606519
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/docker-20180710.743/docker-autoloads.el
@@ -0,0 +1,256 @@
+;;; docker-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "docker-container" "docker-container.el" (23377
+;;;;;;  61612 979207 18000))
+;;; Generated autoloads from docker-container.el
+
+(autoload 'docker-start "docker-container" "\
+Start the container named NAME.
+
+\(fn NAME)" t nil)
+
+(autoload 'docker-stop "docker-container" "\
+Stop the container named NAME.
+
+TIMEOUT is the number of seconds to wait for the container to stop before killing it.
+
+\(fn NAME &optional TIMEOUT)" t nil)
+
+(autoload 'docker-restart "docker-container" "\
+Restart the container named NAME.
+
+TIMEOUT is the number of seconds to wait for the container to stop before killing it.
+
+\(fn NAME &optional TIMEOUT)" t nil)
+
+(autoload 'docker-pause "docker-container" "\
+Pause the container named NAME.
+
+\(fn NAME)" t nil)
+
+(autoload 'docker-unpause "docker-container" "\
+Unpause the container named NAME.
+
+\(fn NAME)" t nil)
+
+(autoload 'docker-rm "docker-container" "\
+Remove the container named NAME.
+
+With prefix argument, sets FORCE to true.
+
+Force the removal even if the container is running when FORCE is set.
+Remove the specified link and not the underlying container when LINK is set.
+Remove the volumes associated with the container when VOLUMES is set.
+
+\(fn NAME &optional FORCE LINK VOLUMES)" t nil)
+
+(autoload 'docker-kill "docker-container" "\
+Kill the container named NAME using SIGNAL.
+
+\(fn NAME &optional SIGNAL)" t nil)
+
+(autoload 'docker-inspect "docker-container" "\
+Inspect the container named NAME.
+
+\(fn NAME)" t nil)
+
+(autoload 'docker-diff "docker-container" "\
+Diff the container named NAME.
+
+\(fn NAME)" t nil)
+
+(autoload 'docker-rename "docker-container" "\
+Rename CONTAINER using NAME.
+
+\(fn CONTAINER NAME)" t nil)
+
+(autoload 'docker-logs "docker-container" "\
+Show the logs from container NAME.
+
+If FOLLOW is set, run in `async-shell-command'.
+
+\(fn NAME &optional FOLLOW)" t nil)
+
+(autoload 'docker-container-find-file "docker-container" "\
+Inside CONTAINER open FILE.
+
+\(fn CONTAINER FILE)" t nil)
+
+(autoload 'docker-container-find-directory "docker-container" "\
+Inside CONTAINER open DIRECTORY.
+
+\(fn CONTAINER DIRECTORY)" t nil)
+
+(autoload 'docker-container-shell "docker-container" "\
+Open `shell' in CONTAINER.
+
+\(fn CONTAINER)" t nil)
+
+(autoload 'docker-container-eshell "docker-container" "\
+Open `eshell' in CONTAINER.
+
+\(fn CONTAINER)" t nil)
+
+(autoload 'docker-containers "docker-container" "\
+List docker containers.
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "docker-image" "docker-image.el" (23377 61612
+;;;;;;  980588 315000))
+;;; Generated autoloads from docker-image.el
+
+(autoload 'docker-pull "docker-image" "\
+Pull the image named NAME.  If ALL is set, use \"-a\".
+
+\(fn NAME &optional ALL)" t nil)
+
+(autoload 'docker-push "docker-image" "\
+Push the image named NAME.
+
+\(fn NAME)" t nil)
+
+(autoload 'docker-rmi "docker-image" "\
+Destroy or untag the image named NAME.
+
+Force removal of the image when FORCE is set.
+Do not delete untagged parents when NO-PRUNE is set.
+
+\(fn NAME &optional FORCE NO-PRUNE)" t nil)
+
+(autoload 'docker-tag "docker-image" "\
+Tag IMAGE using NAME.
+
+\(fn IMAGE NAME)" t nil)
+
+(autoload 'docker-images "docker-image" "\
+List docker images.
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "docker-machine" "docker-machine.el" (23377
+;;;;;;  61612 976526 978000))
+;;; Generated autoloads from docker-machine.el
+
+(autoload 'docker-machine-config "docker-machine" "\
+Print the connection config for the machine NAME.
+
+\(fn NAME)" t nil)
+
+(autoload 'docker-machine-inspect "docker-machine" "\
+Inspect information about the machine NAME.
+
+\(fn NAME)" t nil)
+
+(autoload 'docker-machine-ip "docker-machine" "\
+Get the IP address of the machine NAME.
+
+\(fn NAME)" t nil)
+
+(autoload 'docker-machine-status "docker-machine" "\
+Get the status of the machine NAME.
+
+\(fn NAME)" t nil)
+
+(autoload 'docker-machine-upgrade "docker-machine" "\
+Upgrade the machine NAME to the latest version of Docker.
+
+\(fn NAME)" t nil)
+
+(autoload 'docker-machine-kill "docker-machine" "\
+Kill the machine NAME.
+
+\(fn NAME)" t nil)
+
+(autoload 'docker-machine-create "docker-machine" "\
+Create a machine NAME using DRIVER.
+
+\(fn NAME DRIVER)" t nil)
+
+(autoload 'docker-machine-start "docker-machine" "\
+Start the machine NAME.
+
+\(fn NAME)" t nil)
+
+(autoload 'docker-machine-env "docker-machine" "\
+Parse and set environment variables from \"docker-machine env NAME\" output.
+
+\(fn NAME)" t nil)
+
+(autoload 'docker-machine-stop "docker-machine" "\
+Stop the machine NAME.
+
+\(fn NAME)" t nil)
+
+(autoload 'docker-machine-restart "docker-machine" "\
+Restart the machine NAME.
+
+\(fn NAME)" t nil)
+
+(autoload 'docker-machine-rm "docker-machine" "\
+Destroy or uncommand the machine NAME.  If FORCE is set, use \"--force\".
+
+\(fn NAME &optional FORCE)" t nil)
+
+(autoload 'docker-machines "docker-machine" "\
+List docker machines.
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "docker-network" "docker-network.el" (23377
+;;;;;;  61612 983483 625000))
+;;; Generated autoloads from docker-network.el
+
+(autoload 'docker-network-rm "docker-network" "\
+Destroy the network named NAME.
+
+\(fn NAME)" t nil)
+
+(autoload 'docker-networks "docker-network" "\
+List docker networks.
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "docker-volume" "docker-volume.el" (23377 61612
+;;;;;;  972590 516000))
+;;; Generated autoloads from docker-volume.el
+
+(autoload 'docker-volume-rm "docker-volume" "\
+Destroy the volume named NAME.
+
+\(fn NAME)" t nil)
+
+(autoload 'docker-volume-dired "docker-volume" "\
+
+
+\(fn NAME)" t nil)
+
+(autoload 'docker-volumes "docker-volume" "\
+List docker volumes.
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads nil nil ("docker-pkg.el" "docker-process.el" "docker-utils.el"
+;;;;;;  "docker.el") (23377 61612 982050 23000))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; docker-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/docker-20180710.743/docker-container.el b/configs/shared/emacs/.emacs.d/elpa/docker-20180710.743/docker-container.el
new file mode 100644
index 0000000000..ceebd82c7a
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/docker-20180710.743/docker-container.el
@@ -0,0 +1,478 @@
+;;; docker-container.el --- Emacs interface to docker-container  -*- lexical-binding: t -*-
+
+;; Author: Philippe Vaucher <philippe.vaucher@gmail.com>
+;;         Yuki Inoue <inouetakahiroki@gmail.com>
+
+;; This file is NOT part of GNU Emacs.
+
+;; This program 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, or (at your option)
+;; any later version.
+;;
+;; This program 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; see the file COPYING.  If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;;; Code:
+
+(require 'docker-process)
+(require 'docker-utils)
+(require 'magit-popup)
+(require 'tablist)
+(require 'json)
+
+(defcustom docker-container-show-all t
+  "Show non-running containers."
+  :group 'docker
+  :type 'boolean)
+
+(defcustom docker-container-shell-file-name shell-file-name
+  "Shell to use when entering containers.
+For more information see the variable `shell-file-name'."
+  :group 'docker
+  :type 'string)
+
+(defcustom docker-container-default-sort-key '("Image" . nil)
+  "Sort key for docker containers.
+
+This should be a cons cell (NAME . FLIP) where
+NAME is a string matching one of the column names
+and FLIP is a boolean to specify the sort order."
+  :group 'docker
+  :type '(cons (choice (const "Id")
+                       (const "Image")
+                       (const "Command")
+                       (const "Created")
+                       (const "Status")
+                       (const "Ports")
+                       (const "Names"))
+               (choice (const :tag "Ascending" nil)
+                       (const :tag "Descending" t))))
+
+(defun docker-container-parse (line)
+  "Convert a LINE from \"docker ps\" to a `tabulated-list-entries' entry."
+  (let (data)
+    (condition-case nil
+        (setq data (json-read-from-string line))
+      (json-readtable-error
+       (error "Could not read following string as json:\n%s" line)))
+    (list (aref data 6) data)))
+
+(defun docker-container-entries ()
+  "Return the docker containers data for `tabulated-list-entries'."
+  (let* ((fmt "[{{json .ID}},{{json .Image}},{{json .Command}},{{json .RunningFor}},{{json .Status}},{{json .Ports}},{{json .Names}}]")
+         (data (docker-run "ps" (format "--format=\"%s\"" fmt) (when docker-container-show-all "-a ")))
+         (lines (s-split "\n" data t)))
+    (-map #'docker-container-parse lines)))
+
+(defun docker-container-refresh ()
+  "Refresh the containers list."
+  (setq tabulated-list-entries (docker-container-entries)))
+
+(defun docker-container-read-name ()
+  "Read an container name."
+  (completing-read "Container: " (-map #'car (docker-container-entries))))
+
+;;;###autoload
+(defun docker-start (name)
+  "Start the container named NAME."
+  (interactive (list (docker-container-read-name)))
+  (docker-run "start" name))
+
+;;;###autoload
+(defun docker-stop (name &optional timeout)
+  "Stop the container named NAME.
+
+TIMEOUT is the number of seconds to wait for the container to stop before killing it."
+  (interactive (list (docker-container-read-name) current-prefix-arg))
+  (docker-run "stop" (when timeout (format "-t %d" timeout)) name))
+
+;;;###autoload
+(defun docker-restart (name &optional timeout)
+  "Restart the container named NAME.
+
+TIMEOUT is the number of seconds to wait for the container to stop before killing it."
+  (interactive (list (docker-container-read-name) current-prefix-arg))
+  (docker-run "restart" (when timeout (format "-t %d" timeout)) name))
+
+;;;###autoload
+(defun docker-pause (name)
+  "Pause the container named NAME."
+  (interactive (list (docker-container-read-name)))
+  (docker-run "pause" name))
+
+;;;###autoload
+(defun docker-unpause (name)
+  "Unpause the container named NAME."
+  (interactive (list (docker-container-read-name)))
+  (docker-run "unpause" name))
+
+;;;###autoload
+(defun docker-rm (name &optional force link volumes)
+  "Remove the container named NAME.
+
+With prefix argument, sets FORCE to true.
+
+Force the removal even if the container is running when FORCE is set.
+Remove the specified link and not the underlying container when LINK is set.
+Remove the volumes associated with the container when VOLUMES is set."
+  (interactive (list (docker-container-read-name) current-prefix-arg))
+  (docker-run "rm" (when force "-f") (when link "-l") (when volumes "-v") name))
+
+;;;###autoload
+(defun docker-kill (name &optional signal)
+  "Kill the container named NAME using SIGNAL."
+  (interactive (list (docker-container-read-name)))
+  (docker-run "kill" (when signal (format "-s %s" signal)) name))
+
+;;;###autoload
+(defun docker-inspect (name)
+  "Inspect the container named NAME."
+  (interactive (list (docker-container-read-name)))
+  (docker-utils-with-buffer (format "inspect %s" name)
+    (insert (docker-run "inspect" name))
+    (json-mode)))
+
+;;;###autoload
+(defun docker-diff (name)
+  "Diff the container named NAME."
+  (interactive (list (docker-container-read-name)))
+  (docker-utils-with-buffer (format "diff %s" name)
+   (insert (docker-run "diff" name))))
+
+;;;###autoload
+(defun docker-rename (container name)
+  "Rename CONTAINER using NAME."
+  (interactive (list (docker-container-read-name) (read-string "Name: ")))
+  (docker-run "rename" container name))
+
+;;;###autoload
+(defun docker-logs (name &optional follow)
+  "Show the logs from container NAME.
+
+If FOLLOW is set, run in `async-shell-command'."
+  (interactive (list (docker-container-read-name)))
+  (if follow
+      (async-shell-command (format "%s logs -f %s" docker-command name) (format "* docker logs %s *" name))
+    (docker-utils-with-buffer (format "logs %s" name)
+      (insert (docker-run "logs" name)))))
+
+;;;###autoload
+(defun docker-container-find-file (container file)
+  "Inside CONTAINER open FILE."
+  (interactive
+   (let* ((container-name (docker-container-read-name))
+          (tramp-filename (read-file-name "File: " (format "/docker:%s:/" container-name))))
+     (with-parsed-tramp-file-name tramp-filename nil
+       (list host localname))))
+  (find-file (format "/docker:%s:%s" container file)))
+
+;;;###autoload
+(defun docker-container-find-directory (container directory)
+  "Inside CONTAINER open DIRECTORY."
+  (interactive
+   (let* ((container-name (docker-container-read-name))
+          (tramp-filename (read-directory-name "Directory: " (format "/docker:%s:/" container-name))))
+     (with-parsed-tramp-file-name tramp-filename nil
+       (list host localname))))
+  (dired (format "/docker:%s:%s" container directory)))
+
+(defalias 'docker-container-dired 'docker-container-find-directory)
+
+;;;###autoload
+(defun docker-container-shell (container)
+  "Open `shell' in CONTAINER."
+  (interactive (list (docker-container-read-name)))
+  (let* ((shell-file-name docker-container-shell-file-name)
+         (container-address (format "docker:%s:/" container))
+         (file-prefix (if (file-remote-p default-directory)
+                          (with-parsed-tramp-file-name default-directory nil
+                            (format "/%s:%s|" method host))
+                        "/"))
+         (default-directory (format "%s%s" file-prefix container-address)))
+    (shell (format "*shell %s*" default-directory))))
+
+;;;###autoload
+(defun docker-container-eshell (container)
+  "Open `eshell' in CONTAINER."
+  (interactive (list (docker-container-read-name)))
+  (let* ((container-address (format "docker:%s:/" container))
+         (file-prefix (if (file-remote-p default-directory)
+                          (with-parsed-tramp-file-name default-directory nil
+                            (format "/%s:%s|" method host))
+                        "/"))
+         (default-directory (format "%s%s" file-prefix container-address))
+         (eshell-buffer-name (format "*eshell %s*" default-directory)))
+    (eshell)))
+
+(defun docker-container-start-selection ()
+  "Run `docker-start' on the containers selection."
+  (interactive)
+  (--each (docker-utils-get-marked-items-ids)
+    (docker-run "start" (docker-container-start-arguments) it))
+  (tablist-revert))
+
+(defun docker-container-stop-selection ()
+  "Run `docker-stop' on the containers selection."
+  (interactive)
+  (--each (docker-utils-get-marked-items-ids)
+    (docker-run "stop" (docker-container-stop-arguments) it))
+  (tablist-revert))
+
+(defun docker-container-restart-selection ()
+  "Run `docker-restart' on the containers selection."
+  (interactive)
+  (--each (docker-utils-get-marked-items-ids)
+    (docker-run "restart" (docker-container-restart-arguments) it))
+  (tablist-revert))
+
+(defun docker-container-pause-selection ()
+  "Run `docker-pause' on the containers selection."
+  (interactive)
+  (--each (docker-utils-get-marked-items-ids)
+    (docker-run "pause" (docker-container-pause-arguments) it))
+  (tablist-revert))
+
+(defun docker-container-unpause-selection ()
+  "Run `docker-unpause' on the containers selection."
+  (interactive)
+  (--each (docker-utils-get-marked-items-ids)
+    (docker-run "unpause" (docker-container-unpause-arguments) it))
+  (tablist-revert))
+
+(defun docker-container-rm-selection ()
+  "Run `docker-rm' on the containers selection."
+  (interactive)
+  (--each (docker-utils-get-marked-items-ids)
+    (docker-run "rm" (docker-container-rm-arguments) it))
+  (tablist-revert))
+
+(defun docker-container-kill-selection ()
+  "Run `docker-kill' on the containers selection."
+  (interactive)
+  (--each (docker-utils-get-marked-items-ids)
+    (docker-run "kill" (docker-container-kill-arguments) it))
+  (tablist-revert))
+
+(defun docker-container-inspect-selection ()
+  "Run `docker-inspect' on the containers selection."
+  (interactive)
+  (--each (docker-utils-get-marked-items-ids)
+    (docker-utils-with-buffer (format "inspect %s" it)
+      (insert (docker-run "inspect" (docker-container-inspect-arguments) it))
+      (json-mode))))
+
+(defun docker-container-diff-selection ()
+  "Run `docker-diff' on the containers selection."
+  (interactive)
+  (--each (docker-utils-get-marked-items-ids)
+    (docker-utils-with-buffer (format "diff %s" it)
+      (insert (docker-run "diff" (docker-container-diff-arguments) it)))))
+
+(defun docker-container-rename-selection ()
+  "Rename containers."
+  (interactive)
+  (docker-utils-select-if-empty)
+  (--each (docker-utils-get-marked-items-ids)
+    (docker-rename it (read-string (format "New name for %s: " it))))
+  (tablist-revert))
+
+(defun docker-container-logs-selection ()
+  "Run \"docker logs\" on the containers selection."
+  (interactive)
+  (--each (docker-utils-get-marked-items-ids)
+    (async-shell-command
+     (format "%s logs %s %s" docker-command (s-join " " (docker-container-logs-arguments)) it)
+     (format "* docker logs %s *" it))))
+
+(defun docker-container-find-file-selection (path)
+  "Run `docker-container-find-file' on the containers selection."
+  (interactive "sPath: ")
+  (--each (docker-utils-get-marked-items-ids)
+    (docker-container-find-file it path)))
+
+(defun docker-container-shell-selection ()
+  "Run `docker-container-shell' on the containers selection."
+  (interactive)
+  (--each (docker-utils-get-marked-items-ids)
+    (docker-container-shell it)))
+
+(defun docker-container-eshell-selection ()
+  "Run `docker-container-eshell' on the containers selection."
+  (interactive)
+  (--each (docker-utils-get-marked-items-ids)
+    (docker-container-eshell it)))
+
+(defun docker-container-cp-from-selection (container-path host-path)
+  "Run \"docker cp\" from CONTAINER-PATH to HOST-PATH for selected container."
+  (interactive "sContainer path: \nFHost path: ")
+  (--each (docker-utils-get-marked-items-ids)
+    (docker-run "cp" (concat it ":" container-path) host-path)))
+
+(defun docker-container-cp-to-selection (host-path container-path)
+  "Run \"docker cp\" from HOST-PATH to CONTAINER-PATH for selected containers."
+  (interactive "fHost path: \nsContainer path: ")
+  (--each (docker-utils-get-marked-items-ids)
+    (docker-run "cp" host-path (concat it ":" container-path))))
+
+(magit-define-popup docker-container-start-popup
+  "Popup for starting containers."
+  'docker-container-popups
+  :man-page "docker-start"
+  :actions  '((?S "Start" docker-container-start-selection))
+  :setup-function #'docker-utils-setup-popup)
+
+(magit-define-popup docker-container-stop-popup
+  "Popup for stoping containers."
+  'docker-container-popups
+  :man-page "docker-stop"
+  :options '((?t "Timeout" "-t "))
+  :actions '((?O "Stop" docker-container-stop-selection))
+  :setup-function #'docker-utils-setup-popup)
+
+(magit-define-popup docker-container-restart-popup
+  "Popup for restarting containers."
+  'docker-container-popups
+  :man-page "docker-restart"
+  :options '((?t "Timeout" "-t "))
+  :actions '((?R "Restart" docker-container-restart-selection))
+  :setup-function #'docker-utils-setup-popup)
+
+(magit-define-popup docker-container-pause-popup
+  "Popup for pauseing containers."
+  'docker-container-popups
+  :man-page "docker-pause"
+  :actions  '((?P "Pause" docker-container-pause-selection)
+              (?U "Unpause" docker-container-unpause-selection))
+  :setup-function #'docker-utils-setup-popup)
+
+(magit-define-popup docker-container-rm-popup
+  "Popup for removing containers."
+  'docker-container-popups
+  :man-page "docker-rm"
+  :switches '((?f "Force" "-f")
+              (?v "Volumes" "-v"))
+  :actions  '((?D "Remove" docker-container-rm-selection))
+  :setup-function #'docker-utils-setup-popup)
+
+(magit-define-popup docker-container-kill-popup
+  "Popup for kill signaling containers"
+  'docker-container-popups
+  :man-page "docker-kill"
+  :options  '((?s "Signal" "-s "))
+  :actions  '((?K "Kill" docker-container-kill-selection))
+  :setup-function #'docker-utils-setup-popup)
+
+(magit-define-popup docker-container-inspect-popup
+  "Popup for inspecting containers."
+  'docker-container-popups
+  :man-page "docker-inspect"
+  :actions  '((?I "Inspect" docker-container-inspect-selection))
+  :setup-function #'docker-utils-setup-popup)
+
+(magit-define-popup docker-container-diff-popup
+  "Popup for showing containers diffs."
+  'docker-container-popups
+  :man-page "docker-diff"
+  :actions  '((?d "Diff" docker-container-diff-selection))
+  :setup-function #'docker-utils-setup-popup)
+
+(magit-define-popup docker-container-logs-popup
+  "Popup for showing containers logs."
+  'docker-container-popups
+  :man-page "docker-logs"
+  :switches '((?f "Follow" "-f"))
+  :actions  '((?L "Logs" docker-container-logs-selection))
+  :setup-function #'docker-utils-setup-popup)
+
+(magit-define-popup docker-container-find-file-popup
+  "Popup for opening containers files."
+  'docker-container-popups
+  :actions  '((?f "Open file" docker-container-find-file-selection))
+  :setup-function #'docker-utils-setup-popup)
+
+(magit-define-popup docker-container-shell-popup
+  "Popup for doing M-x `shell'/`eshell' to containers."
+  'docker-container-popups
+  :actions  '((?b "Shell" docker-container-shell-selection)
+              (?e "Eshell" docker-container-eshell-selection))
+  :setup-function #'docker-utils-setup-popup)
+
+(magit-define-popup docker-container-cp-popup
+  "Popup for copying files from/to containers."
+  'docker-container-popups
+  :man-page "docker-cp"
+  :actions  '((?F "Copy From" docker-container-cp-from-selection)
+              (?T "Copy To" docker-container-cp-to-selection))
+  :setup-function #'docker-utils-setup-popup)
+
+(magit-define-popup docker-container-help-popup
+  "Help popup for docker containers."
+  :actions '("Docker containers help"
+             (?C "Copy"       docker-container-cp-popup)
+             (?D "Remove"     docker-container-rm-popup)
+             (?I "Inspect"    docker-container-inspect-popup)
+             (?K "Kill"       docker-container-kill-popup)
+             (?L "Logs"       docker-container-logs-popup)
+             (?O "Stop"       docker-container-stop-popup)
+             (?P "Pause"      docker-container-pause-popup)
+             (?R "Restart"    docker-container-restart-popup)
+             (?S "Start"      docker-container-start-popup)
+             (?b "Shell"      docker-container-shell-popup)
+             (?d "Diff"       docker-container-diff-popup)
+             (?f "Find file"  docker-container-find-file-popup)
+             (?r "Rename"     docker-container-rename-selection)
+             "Switch to other parts"
+             (?i "Images"     docker-images)
+             (?m "Machines"   docker-machines)
+             (?n "Networks"   docker-networks)
+             (?v "Volumes"    docker-volumes)))
+
+(defvar docker-container-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map "?" 'docker-container-help-popup)
+    (define-key map "C" 'docker-container-cp-popup)
+    (define-key map "D" 'docker-container-rm-popup)
+    (define-key map "I" 'docker-container-inspect-popup)
+    (define-key map "K" 'docker-container-kill-popup)
+    (define-key map "L" 'docker-container-logs-popup)
+    (define-key map "O" 'docker-container-stop-popup)
+    (define-key map "P" 'docker-container-pause-popup)
+    (define-key map "R" 'docker-container-restart-popup)
+    (define-key map "S" 'docker-container-start-popup)
+    (define-key map "b" 'docker-container-shell-popup)
+    (define-key map "d" 'docker-container-diff-popup)
+    (define-key map "f" 'docker-container-find-file-popup)
+    (define-key map "r" 'docker-container-rename-selection)
+    map)
+  "Keymap for `docker-container-mode'.")
+
+;;;###autoload
+(defun docker-containers ()
+  "List docker containers."
+  (interactive)
+  (docker-utils-pop-to-buffer "*docker-containers*")
+  (docker-container-mode)
+  (tablist-revert))
+
+(define-derived-mode docker-container-mode tabulated-list-mode "Containers Menu"
+  "Major mode for handling a list of docker containers."
+  (setq tabulated-list-format [("Id" 16 t)("Image" 15 t)("Command" 30 t)("Created" 15 t)("Status" 20 t)("Ports" 10 t)("Names" 10 t)])
+  (setq tabulated-list-padding 2)
+  (setq tabulated-list-sort-key docker-container-default-sort-key)
+  (add-hook 'tabulated-list-revert-hook 'docker-container-refresh nil t)
+  (tabulated-list-init-header)
+  (tablist-minor-mode))
+
+(provide 'docker-container)
+
+;;; docker-container.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/docker-20180710.743/docker-container.elc b/configs/shared/emacs/.emacs.d/elpa/docker-20180710.743/docker-container.elc
new file mode 100644
index 0000000000..c7351abce9
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/docker-20180710.743/docker-container.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/docker-20180710.743/docker-image.el b/configs/shared/emacs/.emacs.d/elpa/docker-20180710.743/docker-image.el
new file mode 100644
index 0000000000..a9e3420bdf
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/docker-20180710.743/docker-image.el
@@ -0,0 +1,245 @@
+;;; docker-image.el --- Emacs interface to docker-image  -*- lexical-binding: t -*-
+
+;; Author: Philippe Vaucher <philippe.vaucher@gmail.com>
+
+;; This file is NOT part of GNU Emacs.
+
+;; This program 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, or (at your option)
+;; any later version.
+;;
+;; This program 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; see the file COPYING.  If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;;; Code:
+
+(require 'docker-process)
+(require 'docker-utils)
+(require 'magit-popup)
+(require 'tablist)
+
+(defcustom docker-image-default-sort-key '("Repository" . nil)
+  "Sort key for docker images.
+
+This should be a cons cell (NAME . FLIP) where
+NAME is a string matching one of the column names
+and FLIP is a boolean to specify the sort order."
+  :group 'docker
+  :type '(cons (choice (const "Repository")
+                       (const "Tag")
+                       (const "Id")
+                       (const "Created")
+                       (const "Size"))
+               (choice (const :tag "Ascending" nil)
+                       (const :tag "Descending" t))))
+
+(defun docker-image-parse (line)
+  "Convert a LINE from \"docker images\" to a `tabulated-list-entries' entry."
+  (let* ((data (s-split "\t" line))
+         (name (format "%s:%s" (nth 0 data) (nth 1 data))))
+    (list
+     (if (s-contains? "<none>" name) (nth 2 data) name)
+     (apply #'vector data))))
+
+(defun docker-image-entries ()
+  "Return the docker images data for `tabulated-list-entries'."
+  (let* ((fmt "{{.Repository}}\\t{{.Tag}}\\t{{.ID}}\\t{{.CreatedSince}}\\t{{.Size}}")
+         (data (docker-run "images" (format "--format=\"%s\"" fmt)))
+         (lines (s-split "\n" data t)))
+    (-map #'docker-image-parse lines)))
+
+(defun docker-image-refresh ()
+  "Refresh the images list."
+  (setq tabulated-list-entries (docker-image-entries)))
+
+(defun docker-image-read-name ()
+  "Read an image name."
+  (completing-read "Image: " (-map #'car (docker-image-entries))))
+
+;;;###autoload
+(defun docker-pull (name &optional all)
+  "Pull the image named NAME.  If ALL is set, use \"-a\"."
+  (interactive (list (docker-image-read-name) current-prefix-arg))
+  (docker-run "pull" (when all "-a ") name))
+
+;;;###autoload
+(defun docker-push (name)
+  "Push the image named NAME."
+  (interactive (list (docker-image-read-name)))
+  (docker-run "push" name))
+
+;;;###autoload
+(defun docker-rmi (name &optional force no-prune)
+  "Destroy or untag the image named NAME.
+
+Force removal of the image when FORCE is set.
+Do not delete untagged parents when NO-PRUNE is set."
+  (interactive (list (docker-image-read-name) current-prefix-arg))
+  (docker-run "rmi" (when force "-f") (when no-prune "--no-prune") name))
+
+;;;###autoload
+(defun docker-tag (image name)
+  "Tag IMAGE using NAME."
+  (interactive (list (docker-image-read-name) (read-string "Name: ")))
+  (docker-run "tag" image name))
+
+(defun docker-image-rm-selection ()
+  "Run \"docker rmi\" on the images selection."
+  (interactive)
+  (--each (docker-utils-get-marked-items-ids)
+    (docker-run "rmi" (docker-image-rm-arguments) it))
+  (tablist-revert))
+
+(defun docker-image-pull-selection ()
+  "Run \"docker pull\" on the images selection."
+  (interactive)
+  (--each (docker-utils-get-marked-items-ids)
+    (docker-run "pull" (docker-image-pull-arguments) it))
+  (tablist-revert))
+
+(defun docker-image-push-selection ()
+  "Run \"docker push\" on the images selection."
+  (interactive)
+  (--each (docker-utils-get-marked-items-ids)
+    (docker-run "push" (docker-image-push-arguments) it)))
+
+(defun docker-image-run-selection (command)
+  "Run \"docker run\" on the images selection."
+  (interactive "sCommand: ")
+  (let ((default-directory (if (and docker-run-as-root
+                                    (not (file-remote-p default-directory)))
+                               "/sudo::"
+                             default-directory)))
+    (--each (docker-utils-get-marked-items-ids)
+      (async-shell-command
+       (format "%s run %s %s %s" docker-command (s-join " " (docker-image-run-arguments)) it command)
+       (format "*run %s*" it)))))
+
+(defun docker-image-inspect-selection ()
+  "Run \"docker inspect\" on the images selection."
+  (interactive)
+  (--each (docker-utils-get-marked-items-ids)
+    (docker-utils-with-buffer (format "inspect %s" it)
+      (insert (docker-run "inspect" (docker-image-inspect-arguments) it))
+      (json-mode))))
+
+(defun docker-image-tag-selection ()
+  "Tag images."
+  (interactive)
+  (docker-utils-select-if-empty)
+  (--each (docker-utils-get-marked-items-ids)
+    (docker-tag it (read-string (format "Tag for %s: " it))))
+  (tablist-revert))
+
+(magit-define-popup docker-image-rm-popup
+  "Popup for removing images."
+  'docker-image-popups
+  :man-page "docker-rmi"
+  :switches '((?f "Force" "-f")
+              (?n "Don't prune" "--no-prune"))
+  :actions  '((?D "Remove" docker-image-rm-selection))
+  :setup-function #'docker-utils-setup-popup)
+
+(magit-define-popup docker-image-pull-popup
+  "Popup for pulling images."
+  'docker-image-popups
+  :man-page "docker-pull"
+  :switches '((?a "All" "-a"))
+  :actions  '((?F "Pull" docker-image-pull-selection))
+  :setup-function #'docker-utils-setup-popup)
+
+(magit-define-popup docker-image-push-popup
+  "Popup for pushing images."
+  'docker-image-popups
+  :man-page "docker-push"
+  :actions  '((?P "Push" docker-image-push-selection))
+  :setup-function #'docker-utils-setup-popup)
+
+(magit-define-popup docker-image-inspect-popup
+  "Popup for inspecting images."
+  'docker-image-popups
+  :man-page "docker-inspect"
+  :actions  '((?I "Inspect" docker-image-inspect-selection))
+  :setup-function #'docker-utils-setup-popup)
+
+(magit-define-popup docker-image-run-popup
+  "Popup for running images."
+  'docker-image-popups
+  :man-page "docker-run"
+  :switches '((?d "Daemonize" "-d")
+              (?i "Interactive" "-i")
+              (?t "TTY" "-t")
+              (?r "Remove" "--rm")
+              (?p "Privileged" "--privileged")
+              (?o "Read only" "--read-only")
+              (?T "Synchronize time" "-v /etc/localtime:/etc/localtime:ro")
+              (?W "Web ports" "-p 80:80 -p 443:443 -p 8080:8080")
+              (?D "With display" "-v /tmp/.X11-unix:/tmp/.X11-unix -e DISPLAY"))
+  :options  '((?v "volume" "-v ")
+              (?m "name" "--name ")
+              (?e "environment" "-e ")
+              (?p "port" "-p ")
+              (?w "workdir" "-w ")
+              (?u "user" "-u ")
+              (?n "entrypoint" "--entrypoint "))
+  :actions  '((?R "Run images" docker-image-run-selection))
+  :default-arguments '("-i" "-t" "--rm")
+  :setup-function #'docker-utils-setup-popup)
+
+(magit-define-popup docker-image-help-popup
+  "Help popup for docker images."
+  :actions '("Docker images help"
+             (?D "Remove"  docker-image-rm-popup)
+             (?F "Pull"    docker-image-pull-popup)
+             (?I "Inspect" docker-image-inspect-popup)
+             (?P "Push"    docker-image-push-popup)
+             (?R "Run"     docker-image-run-popup)
+             (?T "Tag"     docker-image-tag-selection)
+             "Switch to other parts"
+             (?c "Containers" docker-containers)
+             (?m "Machines"   docker-machines)
+             (?n "Networks"   docker-networks)
+             (?v "Volumes"    docker-volumes)))
+
+(defvar docker-image-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map "?" 'docker-image-help-popup)
+    (define-key map "D" 'docker-image-rm-popup)
+    (define-key map "F" 'docker-image-pull-popup)
+    (define-key map "I" 'docker-image-inspect-popup)
+    (define-key map "P" 'docker-image-push-popup)
+    (define-key map "R" 'docker-image-run-popup)
+    (define-key map "T" 'docker-image-tag-selection)
+    map)
+  "Keymap for `docker-image-mode'.")
+
+;;;###autoload
+(defun docker-images ()
+  "List docker images."
+  (interactive)
+  (docker-utils-pop-to-buffer "*docker-images*")
+  (docker-image-mode)
+  (tablist-revert))
+
+(define-derived-mode docker-image-mode tabulated-list-mode "Images Menu"
+  "Major mode for handling a list of docker images."
+  (setq tabulated-list-format [("Repository" 30 t)("Tag" 20 t)("Id" 16 t)("Created" 25 t)("Size" 10 t)])
+  (setq tabulated-list-padding 2)
+  (setq tabulated-list-sort-key docker-image-default-sort-key)
+  (add-hook 'tabulated-list-revert-hook 'docker-image-refresh nil t)
+  (tabulated-list-init-header)
+  (tablist-minor-mode))
+
+(provide 'docker-image)
+
+;;; docker-image.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/docker-20180710.743/docker-image.elc b/configs/shared/emacs/.emacs.d/elpa/docker-20180710.743/docker-image.elc
new file mode 100644
index 0000000000..e3ce5f96cc
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/docker-20180710.743/docker-image.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/docker-20180710.743/docker-machine.el b/configs/shared/emacs/.emacs.d/elpa/docker-20180710.743/docker-machine.el
new file mode 100644
index 0000000000..cf72812aea
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/docker-20180710.743/docker-machine.el
@@ -0,0 +1,260 @@
+;;; docker-machine.el --- Emacs interface to docker-machine  -*- lexical-binding: t -*-
+
+;; Author: Ben Swift <ben@benswift.me>
+
+;; This file is NOT part of GNU Emacs.
+
+;; This program 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, or (at your option)
+;; any later version.
+;;
+;; This program 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; see the file COPYING.  If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;;; Code:
+
+(require 'docker-process)
+(require 'docker-utils)
+(require 'magit-popup)
+(require 'tablist)
+
+(defun docker-machine-parse (line)
+  "Convert a LINE from \"docker machine ls\" to a `tabulated-list-entries' entry."
+  (let ((data (s-split "\t" line)))
+    (list (car data) (apply #'vector data))))
+
+(defun docker-machine-entries ()
+  "Return the docker machines data for `tabulated-list-entries'."
+  (let* ((fmt "{{.Name}}\\t{{.Active}}\\t{{.DriverName}}\\t{{.State}}\\t{{.URL}}\\t{{.Swarm}}\\t{{.DockerVersion}}\\t{{.Error}}")
+         (data (shell-command-to-string (format "docker-machine ls %s" (format "--format=\"%s\"" fmt))))
+         (lines (s-split "\n" data t)))
+    (-map #'docker-machine-parse lines)))
+
+(defun docker-machine-refresh ()
+  "Refresh the machines list."
+  (setq tabulated-list-entries (docker-machine-entries)))
+
+(defun docker-machine-read-name ()
+  "Read a machine name."
+  (completing-read "Machine: " (-map #'car (docker-machine-entries))))
+
+(defun docker-machine-run (action &rest args)
+  "Execute \"docker-machine ACTION\" passing arguments ARGS."
+  (let ((command (format "docker-machine %s %s" action (s-join " " (-non-nil args)))))
+    (message command)
+    (shell-command-to-string command)))
+
+;;;###autoload
+(defun docker-machine-config (name)
+  "Print the connection config for the machine NAME."
+  (interactive (list (docker-machine-read-name)))
+  (docker-machine-run "config" name))
+
+;;;###autoload
+(defun docker-machine-inspect (name)
+  "Inspect information about the machine NAME."
+  (interactive (list (docker-machine-read-name)))
+  (docker-machine-run "inspect" name))
+
+;;;###autoload
+(defun docker-machine-ip (name)
+  "Get the IP address of the machine NAME."
+  (interactive (list (docker-machine-read-name)))
+  (docker-machine-run "ip" name))
+
+;;;###autoload
+(defun docker-machine-status (name)
+  "Get the status of the machine NAME."
+  (interactive (list (docker-machine-read-name)))
+  (docker-machine-run "status" name))
+
+;;;###autoload
+(defun docker-machine-upgrade (name)
+  "Upgrade the machine NAME to the latest version of Docker."
+  (interactive (list (docker-machine-read-name)))
+  (docker-machine-run "upgrade" name))
+
+;;;###autoload
+(defun docker-machine-kill (name)
+  "Kill the machine NAME."
+  (interactive (list (docker-machine-read-name)))
+  (docker-machine-run "kill" name))
+
+;;;###autoload
+(defun docker-machine-create (name driver)
+  "Create a machine NAME using DRIVER."
+  (interactive "sName: \nsDriver: ")
+  (docker-machine-run "create" name "-d" driver))
+
+;;;###autoload
+(defun docker-machine-start (name)
+  "Start the machine NAME."
+  (interactive (list (docker-machine-read-name)))
+  (docker-machine-run "start" name))
+
+(defun docker-machine-env-export (line)
+  "Export the env for LINE."
+  (let ((index (s-index-of "=" line)))
+    (unless index
+      (error (format "Cannot find separator in %s" line)))
+    (setenv (substring line (length "export ") index) (substring line (+ 2 index) -1))))
+
+;;;###autoload
+(defun docker-machine-env (name)
+  "Parse and set environment variables from \"docker-machine env NAME\" output."
+  (interactive (list (docker-machine-read-name)))
+  (--each-while
+      (s-lines (docker-machine-run "env" name))
+      (s-prefix? "export" it)
+    (docker-machine-env-export it)))
+
+;;;###autoload
+(defun docker-machine-stop (name)
+  "Stop the machine NAME."
+  (interactive (list (docker-machine-read-name) current-prefix-arg))
+  (docker-machine-run "stop" name))
+
+;;;###autoload
+(defun docker-machine-restart (name)
+  "Restart the machine NAME."
+  (interactive (list (docker-machine-read-name) current-prefix-arg))
+  (docker-machine-run "restart" name))
+
+;;;###autoload
+(defun docker-machine-rm (name &optional force)
+  "Destroy or uncommand the machine NAME.  If FORCE is set, use \"--force\"."
+  (interactive (list (docker-machine-read-name) current-prefix-arg))
+  (docker-machine-run "rm" (when force "--force") name))
+
+(defun docker-machine-start-selection ()
+  "Run `docker-machine-start' on the machines selection."
+  (interactive)
+  (--each (docker-utils-get-marked-items-ids)
+    (docker-machine-run "start" (docker-machine-start-arguments)))
+  (tablist-revert))
+
+(defun docker-machine-stop-selection ()
+  "Run `docker-machine-stop' on the machines selection."
+  (interactive)
+  (--each (docker-utils-get-marked-items-ids)
+    (docker-machine-run "stop" (docker-machine-stop-arguments)))
+  (tablist-revert))
+
+(defun docker-machine-restart-selection ()
+  "Run `docker-machine-restart' on the machines selection."
+  (interactive)
+  (--each (docker-utils-get-marked-items-ids)
+    (docker-machine-run "restart" (docker-machine-restart-arguments)))
+  (tablist-revert))
+
+(defun docker-machine-rm-selection ()
+  "Run `docker-machine-rm' on the machines selection."
+  (interactive)
+  (--each (docker-utils-get-marked-items-ids)
+    (docker-machine-run "rm" (docker-machine-rm-arguments)))
+  (tablist-revert))
+
+(defun docker-machine-env-selection ()
+  "Run \"docker-machine env\" on selected machine."
+  (interactive)
+  (let ((marked (docker-utils-get-marked-items-ids)))
+    (when (/= (length marked) 1)
+      (error "Can only set environment vars for one machine at a time"))
+    (docker-machine-env (car marked))
+    (tablist-revert)))
+
+(magit-define-popup docker-machine-start-popup
+  "Popup for starting machines."
+  'docker-machine-popups
+  :man-page "docker-machine-start"
+  :actions  '((?S "Start" docker-machine-start-selection))
+  :setup-function #'docker-utils-setup-popup)
+
+(magit-define-popup docker-machine-env-popup
+  "Popup for setting up environment variables."
+  'docker-machine-popups
+  :man-page "docker-machine-env"
+  :actions '((?E "Env" docker-machine-env-selection))
+  :setup-function #'docker-utils-setup-popup)
+
+(magit-define-popup docker-machine-stop-popup
+  "Popup for stoping machines."
+  'docker-machine-popups
+  :man-page "docker-machine-stop"
+  :actions '((?O "Stop" docker-machine-stop-selection))
+  :setup-function #'docker-utils-setup-popup)
+
+(magit-define-popup docker-machine-restart-popup
+  "Popup for restarting machines."
+  'docker-machine-popups
+  :man-page "docker-machine-restart"
+  :actions '((?R "Restart" docker-machine-restart-selection))
+  :setup-function #'docker-utils-setup-popup)
+
+(magit-define-popup docker-machine-rm-popup
+  "Popup for removing machines."
+  'docker-machine-popups
+  :man-page "docker-machine-rm"
+  :switches '((?y "Automatic yes" "-y")
+              (?f "Force" "-f"))
+  :actions  '((?D "Remove" docker-machine-rm-selection))
+  :default-arguments '("-y")
+  :setup-function #'docker-utils-setup-popup)
+
+(magit-define-popup docker-machine-help-popup
+  "Help popup for docker machine."
+  :actions '("Docker machines help"
+             (?C "Create"     docker-machine-create)
+             (?D "Remove"     docker-machine-rm-popup)
+             (?E "Env"        docker-machine-env-popup)
+             (?O "Stop"       docker-machine-stop-popup)
+             (?R "Restart"    docker-machine-restart-popup)
+             (?S "Start"      docker-machine-start-popup)
+             "Switch to other parts"
+             (?c "Containers" docker-containers)
+             (?i "Images"     docker-images)
+             (?n "Networks"   docker-networks)
+             (?v "Volumes"    docker-volumes)))
+
+(defvar docker-machine-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map "?" 'docker-machine-help-popup)
+    (define-key map "C" 'docker-machine-create)
+    (define-key map "D" 'docker-machine-rm-popup)
+    (define-key map "E" 'docker-machine-env-popup)
+    (define-key map "O" 'docker-machine-stop-popup)
+    (define-key map "R" 'docker-machine-restart-popup)
+    (define-key map "S" 'docker-machine-start-popup)
+    map)
+  "Keymap for `docker-machine-mode'.")
+
+;;;###autoload
+(defun docker-machines ()
+  "List docker machines."
+  (interactive)
+  (docker-utils-pop-to-buffer "*docker-machines*")
+  (docker-machine-mode)
+  (tablist-revert))
+
+(define-derived-mode docker-machine-mode tabulated-list-mode "Machines Menu"
+  "Major mode for handling a list of docker machines."
+  (setq tabulated-list-format [("Name" 16 t)("Active" 7 t)("Driver" 12 t)("State" 12 t)("URL" 30 t)("Swarm" 10 t)("Docker" 10 t)("Errors" 10 t)])
+  (setq tabulated-list-padding 2)
+  (setq tabulated-list-sort-key (cons "Name" nil))
+  (add-hook 'tabulated-list-revert-hook 'docker-machine-refresh nil t)
+  (tabulated-list-init-header)
+  (tablist-minor-mode))
+
+(provide 'docker-machine)
+
+;;; docker-machine.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/docker-20180710.743/docker-machine.elc b/configs/shared/emacs/.emacs.d/elpa/docker-20180710.743/docker-machine.elc
new file mode 100644
index 0000000000..c3b2b1e4ed
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/docker-20180710.743/docker-machine.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/docker-20180710.743/docker-network.el b/configs/shared/emacs/.emacs.d/elpa/docker-20180710.743/docker-network.el
new file mode 100644
index 0000000000..78cad55291
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/docker-20180710.743/docker-network.el
@@ -0,0 +1,106 @@
+;;; docker-network.el --- Emacs interface to docker-network  -*- lexical-binding: t -*-
+
+;; Author: Philippe Vaucher <philippe.vaucher@gmail.com>
+
+;; This file is NOT part of GNU Emacs.
+
+;; This program 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, or (at your option)
+;; any later version.
+;;
+;; This program 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; see the file COPYING.  If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;;; Code:
+
+(require 'docker-process)
+(require 'docker-utils)
+(require 'magit-popup)
+(require 'tablist)
+
+(defun docker-network-parse (line)
+  "Convert a LINE from \"docker network ls\" to a `tabulated-list-entries' entry."
+  (let ((data (s-split " \\{3,\\}" line t)))
+    (list (nth 1 data) (apply #'vector data))))
+
+(defun docker-network-entries ()
+  "Return the docker networks data for `tabulated-list-entries'."
+  (let* ((data (docker-run "network" "ls"))
+         (lines (cdr (s-split "\n" data t))))
+    (-map #'docker-network-parse lines)))
+
+(defun docker-network-refresh ()
+  "Refresh the networks list."
+  (setq tabulated-list-entries (docker-network-entries)))
+
+(defun docker-network-read-name ()
+  "Read a network name."
+  (completing-read "Network: " (-map #'car (docker-network-entries))))
+
+;;;###autoload
+(defun docker-network-rm (name)
+  "Destroy the network named NAME."
+  (interactive (list (docker-network-read-name)))
+  (docker-run "network rm" name))
+
+(defun docker-network-rm-selection ()
+  "Run \"docker network rm\" on the selection."
+  (interactive)
+  (--each (docker-utils-get-marked-items-ids)
+    (docker-run "network rm" it))
+  (tablist-revert))
+
+(magit-define-popup docker-network-rm-popup
+  "Popup for removing networks."
+  'docker-network-popups
+  :man-page "docker-network-rm"
+  :actions  '((?D "Remove" docker-network-rm-selection))
+  :setup-function #'docker-utils-popup-setup)
+
+(magit-define-popup docker-network-help-popup
+  "Help popup for docker networks."
+  :actions '("Docker networks help"
+             (?D "Remove"     docker-network-rm-popup)
+             "Switch to other parts"
+             (?c "Containers" docker-containers)
+             (?i "Images"     docker-images)
+             (?m "Machines"   docker-machines)
+             (?v "Volumes"    docker-volumes)))
+
+(defvar docker-network-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map "?" 'docker-network-help-popup)
+    (define-key map "D" 'docker-network-rm-popup)
+    map)
+  "Keymap for `docker-network-mode'.")
+
+;;;###autoload
+(defun docker-networks ()
+  "List docker networks."
+  (interactive)
+  (docker-utils-pop-to-buffer "*docker-networks*")
+  (docker-network-mode)
+  (tablist-revert))
+
+(define-derived-mode docker-network-mode tabulated-list-mode "Networks Menu"
+  "Major mode for handling a list of docker networks."
+  (setq tabulated-list-format [("Network ID" 20 t)("Name" 50 t)("Driver" 10 t)])
+  (setq tabulated-list-padding 2)
+  (setq tabulated-list-sort-key (cons "Name" nil))
+  (add-hook 'tabulated-list-revert-hook 'docker-network-refresh nil t)
+  (tabulated-list-init-header)
+  (tablist-minor-mode))
+
+(provide 'docker-network)
+
+;;; docker-network.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/docker-20180710.743/docker-network.elc b/configs/shared/emacs/.emacs.d/elpa/docker-20180710.743/docker-network.elc
new file mode 100644
index 0000000000..6686fec7d5
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/docker-20180710.743/docker-network.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/docker-20180710.743/docker-pkg.el b/configs/shared/emacs/.emacs.d/elpa/docker-20180710.743/docker-pkg.el
new file mode 100644
index 0000000000..67b3013a5d
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/docker-20180710.743/docker-pkg.el
@@ -0,0 +1,14 @@
+(define-package "docker" "20180710.743" "Emacs interface to Docker"
+  '((emacs "24.5")
+    (dash "2.14.1")
+    (docker-tramp "0.1")
+    (magit-popup "2.12.3")
+    (s "1.12.0")
+    (tablist "0.70")
+    (json-mode "1.7.0"))
+  :keywords
+  '("filename" "convenience")
+  :url "https://github.com/Silex/docker.el")
+;; Local Variables:
+;; no-byte-compile: t
+;; End:
diff --git a/configs/shared/emacs/.emacs.d/elpa/docker-20180710.743/docker-process.el b/configs/shared/emacs/.emacs.d/elpa/docker-20180710.743/docker-process.el
new file mode 100644
index 0000000000..31a3706128
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/docker-20180710.743/docker-process.el
@@ -0,0 +1,48 @@
+;;; docker-process.el --- Emacs interface to Docker  -*- lexical-binding: t -*-
+
+;; Author: Philippe Vaucher <philippe.vaucher@gmail.com>
+
+;; This file is NOT part of GNU Emacs.
+
+;; This program 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, or (at your option)
+;; any later version.
+;;
+;; This program 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; see the file COPYING.  If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;;; Code:
+
+(require 's)
+(require 'dash)
+
+(defcustom docker-run-as-root nil
+  "Run docker as root."
+  :type 'boolean
+  :group 'docker)
+
+(defcustom docker-command "docker"
+  "The docker binary."
+  :type 'string
+  :group 'docker)
+
+(defun docker-run (action &rest args)
+  "Execute docker ACTION passing arguments ARGS."
+  (let ((default-directory (if (and docker-run-as-root (not (file-remote-p default-directory))) "/sudo::" default-directory)))
+    (let ((command (format "%s %s %s" docker-command action (s-join " " (-flatten (-non-nil args))))))
+      (message command)
+      (shell-command-to-string command))))
+
+(provide 'docker-process)
+
+;;; docker-process.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/docker-20180710.743/docker-process.elc b/configs/shared/emacs/.emacs.d/elpa/docker-20180710.743/docker-process.elc
new file mode 100644
index 0000000000..1354153b0a
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/docker-20180710.743/docker-process.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/docker-20180710.743/docker-utils.el b/configs/shared/emacs/.emacs.d/elpa/docker-20180710.743/docker-utils.el
new file mode 100644
index 0000000000..c56bce55a4
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/docker-20180710.743/docker-utils.el
@@ -0,0 +1,73 @@
+;;; docker-utils.el --- Random utilities  -*- lexical-binding: t -*-
+
+;; Author: Philippe Vaucher <philippe.vaucher@gmail.com>
+
+;; This file is NOT part of GNU Emacs.
+
+;; This program 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, or (at your option)
+;; any later version.
+;;
+;; This program 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; see the file COPYING.  If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;;; Code:
+
+(defun docker-utils-get-marked-items ()
+  "Get the marked items data from `tabulated-list-entries'."
+  (save-excursion
+    (goto-char (point-min))
+    (let ((selection ()))
+      (while (not (eobp))
+        (when (not (null (tablist-get-mark-state)))
+          (setq selection (-snoc selection (cons (tabulated-list-get-id) (tabulated-list-get-entry)))))
+        (forward-line))
+      selection)))
+
+(defun docker-utils-get-marked-items-ids ()
+  "Get the id part of `docker-utils-get-marked-items'."
+  (-map #'car (docker-utils-get-marked-items)))
+
+(defun docker-utils-setup-popup (val def)
+  (magit-with-pre-popup-buffer (docker-utils-select-if-empty))
+  (magit-popup-default-setup val def))
+
+(defun docker-utils-select-if-empty (&optional arg)
+  "Select current row is selection is empty.
+ARG is unused here, but is required by `add-function'."
+  (save-excursion
+    (when (null (docker-utils-get-marked-items))
+      (tablist-put-mark))))
+
+(defun docker-utils-pop-to-buffer (name)
+  "Like `pop-to-buffer', but suffix NAME with the host if on a remote host."
+  (pop-to-buffer
+   (if (file-remote-p default-directory)
+       (with-parsed-tramp-file-name default-directory nil (concat name " - " host))
+     name)))
+
+(defmacro docker-utils-with-buffer (name &rest body)
+  "Wrapper around `with-current-buffer'.
+Execute BODY in a buffer."
+  (declare (indent defun))
+  `(with-current-buffer (generate-new-buffer (format "* docker - %s *" ,name))
+     (setq buffer-read-only nil)
+     (erase-buffer)
+     ,@body
+     (setq buffer-read-only t)
+     (goto-char (point-min))
+     (pop-to-buffer (current-buffer))))
+
+(provide 'docker-utils)
+
+;;; docker-utils.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/docker-20180710.743/docker-utils.elc b/configs/shared/emacs/.emacs.d/elpa/docker-20180710.743/docker-utils.elc
new file mode 100644
index 0000000000..0e14b441d9
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/docker-20180710.743/docker-utils.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/docker-20180710.743/docker-volume.el b/configs/shared/emacs/.emacs.d/elpa/docker-20180710.743/docker-volume.el
new file mode 100644
index 0000000000..7e487f3919
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/docker-20180710.743/docker-volume.el
@@ -0,0 +1,121 @@
+;;; docker-volume.el --- Emacs interface to docker-volume  -*- lexical-binding: t -*-
+
+;; Author: Philippe Vaucher <philippe.vaucher@gmail.com>
+
+;; This file is NOT part of GNU Emacs.
+
+;; This program 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, or (at your option)
+;; any later version.
+;;
+;; This program 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; see the file COPYING.  If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;;; Code:
+
+(require 'docker-process)
+(require 'docker-utils)
+(require 'magit-popup)
+(require 'tablist)
+
+(defun docker-volume-parse (line)
+  "Convert a LINE from \"docker volume ls\" to a `tabulated-list-entries' entry."
+  (let ((data (s-split " \\{3,15\\}" line t)))
+    (list (nth 1 data) (apply #'vector data))))
+
+(defun docker-volume-entries ()
+  "Return the docker volumes data for `tabulated-list-entries'."
+  (let* ((data (docker-run "volume" "ls"))
+         (lines (cdr (s-split "\n" data t))))
+    (-map #'docker-volume-parse lines)))
+
+(defun docker-volume-refresh ()
+  "Refresh the volumes list."
+  (setq tabulated-list-entries (docker-volume-entries)))
+
+(defun docker-volume-read-name ()
+  "Read a volume name."
+  (completing-read "Volume: " (-map #'car (docker-volume-entries))))
+
+;;;###autoload
+(defun docker-volume-rm (name)
+  "Destroy the volume named NAME."
+  (interactive (list (docker-volume-read-name)))
+  (docker-run "volume rm" name))
+
+;;;###autoload
+(defun docker-volume-dired (name)
+  (interactive (list (docker-volume-read-name)))
+  (let ((path (docker-run "inspect" "-f" "\"{{ .Mountpoint }}\"" name)))
+    (dired (format "/sudo::%s" path))))
+
+(defun docker-volume-rm-selection ()
+  "Run \"docker volume rm\" on the volumes selection."
+  (interactive)
+  (--each (docker-utils-get-marked-items-ids)
+    (docker-run "volume rm" it))
+  (tablist-revert))
+
+(defun docker-volume-dired-selection ()
+  "Run `docker-volume-dired' on the volumes selection."
+  (interactive)
+  (docker-utils-select-if-empty)
+  (--each (docker-utils-get-marked-items-ids)
+    (docker-volume-dired it)))
+
+(magit-define-popup docker-volume-rm-popup
+  "Popup for removing volumes."
+  'docker-volume-popups
+  :man-page "docker-volume-rm"
+  :actions  '((?D "Remove" docker-volume-rm-selection))
+  :setup-function #'docker-utils-setup-popup)
+
+(magit-define-popup docker-volume-help-popup
+  "Help popup for docker volumes."
+  :actions '("Docker volumes help"
+             (?D "Remove"     docker-volume-rm-popup)
+             (?d "dired"      docker-volume-dired-selection)
+             "Switch to other parts"
+             (?c "Containers" docker-containers)
+             (?i "Images"     docker-images)
+             (?m "Machines"   docker-machines)
+             (?n "Networks"   docker-networks)))
+
+(defvar docker-volume-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map "?" 'docker-volume-help-popup)
+    (define-key map "D" 'docker-volume-rm-popup)
+    (define-key map "d" 'docker-volume-dired-selection)
+    map)
+  "Keymap for `docker-volume-mode'.")
+
+;;;###autoload
+(defun docker-volumes ()
+  "List docker volumes."
+  (interactive)
+  (docker-utils-pop-to-buffer "*docker-volumes*")
+  (docker-volume-mode)
+  (tablist-revert))
+
+(define-derived-mode docker-volume-mode tabulated-list-mode "Volumes Menu"
+  "Major mode for handling a list of docker volumes."
+  (setq tabulated-list-format [("Driver" 10 t)("Name" 10 t)])
+  (setq tabulated-list-padding 2)
+  (setq tabulated-list-sort-key (cons "Driver" nil))
+  (add-hook 'tabulated-list-revert-hook 'docker-volume-refresh nil t)
+  (tabulated-list-init-header)
+  (tablist-minor-mode))
+
+(provide 'docker-volume)
+
+;;; docker-volume.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/docker-20180710.743/docker-volume.elc b/configs/shared/emacs/.emacs.d/elpa/docker-20180710.743/docker-volume.elc
new file mode 100644
index 0000000000..e4b8629b9a
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/docker-20180710.743/docker-volume.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/docker-20180710.743/docker.el b/configs/shared/emacs/.emacs.d/elpa/docker-20180710.743/docker.el
new file mode 100644
index 0000000000..19c9d9d787
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/docker-20180710.743/docker.el
@@ -0,0 +1,51 @@
+;;; docker.el --- Emacs interface to Docker  -*- lexical-binding: t -*-
+
+;; Author: Philippe Vaucher <philippe.vaucher@gmail.com>
+;; URL: https://github.com/Silex/docker.el
+;; Keywords: filename, convenience
+;; Version: 0.7.0
+;; Package-Requires: ((emacs "24.5") (dash "2.14.1") (docker-tramp "0.1") (magit-popup "2.12.3") (s "1.12.0") (tablist "0.70") (json-mode "1.7.0"))
+
+;; This file is NOT part of GNU Emacs.
+
+;; This program 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, or (at your option)
+;; any later version.
+;;
+;; This program 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; see the file COPYING.  If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; # Emacs interface to Docker!
+;;
+;; This package allows you to manipulate docker images, containers & more from Emacs.
+
+;;; Code:
+
+(require 'magit-popup)
+
+(defgroup docker nil
+  "Docker customization group."
+  :group 'convenience)
+
+(magit-define-popup docker
+  "Popup console for dispatching other popups."
+  :actions '("Docker"
+             (?c "Containers" docker-containers)
+             (?i "Images"     docker-images)
+             (?m "Machines"   docker-machines)
+             (?n "Networks"   docker-networks)
+             (?v "Volumes"    docker-volumes)))
+
+(provide 'docker)
+
+;;; docker.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/docker-20180710.743/docker.elc b/configs/shared/emacs/.emacs.d/elpa/docker-20180710.743/docker.elc
new file mode 100644
index 0000000000..6fc2976ad5
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/docker-20180710.743/docker.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/docker-tramp-20170206.1925/docker-tramp-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/docker-tramp-20170206.1925/docker-tramp-autoloads.el
new file mode 100644
index 0000000000..229248f448
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/docker-tramp-20170206.1925/docker-tramp-autoloads.el
@@ -0,0 +1,45 @@
+;;; docker-tramp-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "docker-tramp" "docker-tramp.el" (23377 61612
+;;;;;;  469221 507000))
+;;; Generated autoloads from docker-tramp.el
+
+(defvar docker-tramp-docker-options nil "\
+List of docker options.")
+
+(custom-autoload 'docker-tramp-docker-options "docker-tramp" t)
+
+(defconst docker-tramp-completion-function-alist '((docker-tramp--parse-running-containers "")) "\
+Default list of (FUNCTION FILE) pairs to be examined for docker method.")
+
+(defconst docker-tramp-method "docker" "\
+Method to connect docker containers.")
+
+(autoload 'docker-tramp-cleanup "docker-tramp" "\
+Cleanup TRAMP cache for docker method.
+
+\(fn)" t nil)
+
+(autoload 'docker-tramp-add-method "docker-tramp" "\
+Add docker tramp method.
+
+\(fn)" nil nil)
+
+(eval-after-load 'tramp '(progn (docker-tramp-add-method) (tramp-set-completion-function docker-tramp-method docker-tramp-completion-function-alist)))
+
+;;;***
+
+;;;### (autoloads nil nil ("docker-tramp-compat.el" "docker-tramp-pkg.el")
+;;;;;;  (23377 61612 467434 581000))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; docker-tramp-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/docker-tramp-20170206.1925/docker-tramp-compat.el b/configs/shared/emacs/.emacs.d/elpa/docker-tramp-20170206.1925/docker-tramp-compat.el
new file mode 100644
index 0000000000..070b151931
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/docker-tramp-20170206.1925/docker-tramp-compat.el
@@ -0,0 +1,87 @@
+;;; docker-tramp-compat.el --- TRAMP integration for docker containers  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2015 Mario Rodas <marsam@users.noreply.github.com>
+
+;; Author: Mario Rodas <marsam@users.noreply.github.com>
+;; URL: https://github.com/emacs-pe/docker-tramp.el
+;; Keywords: docker, convenience
+;; Version: 0.1
+;; Package-Requires: ((emacs "24"))
+
+;; This file is NOT part of GNU Emacs.
+
+;;; License:
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;; Code:
+(require 'tramp-sh)
+
+(when (version< tramp-version "2.3")
+;; Overwrite `tramp-wait-for-output' to work with Alpine busy boxes in Tramp<2.3
+;;
+;; See:
+;; + https://lists.gnu.org/archive/html/tramp-devel/2016-05/msg00000.html
+;; + http://git.savannah.gnu.org/cgit/tramp.git/commit/?id=98a511248a9405848ed44de48a565b0b725af82c
+(defconst tramp-device-escape-sequence-regexp "\e[[0-9]+n"
+  "Terminal control escape sequences for device status.")
+
+(defun tramp-wait-for-output (proc &optional timeout)
+  "Wait for output from remote command."
+  (unless (buffer-live-p (process-buffer proc))
+    (delete-process proc)
+    (tramp-error proc 'file-error "Process `%s' not available, try again" proc))
+  (with-current-buffer (process-buffer proc)
+    (let* (;; Initially, `tramp-end-of-output' is "#$ ".  There might
+	   ;; be leading escape sequences, which must be ignored.
+	   ;; Busyboxes built with the EDITING_ASK_TERMINAL config
+	   ;; option send also escape sequences, which must be
+	   ;; ignored.
+	   (regexp (format "[^#$\n]*%s\\(%s\\)?\r?$"
+			   (regexp-quote tramp-end-of-output)
+			   tramp-device-escape-sequence-regexp))
+	   ;; Sometimes, the commands do not return a newline but a
+	   ;; null byte before the shell prompt, for example "git
+	   ;; ls-files -c -z ...".
+	   (regexp1 (format "\\(^\\|\000\\)%s" regexp))
+	   (found (tramp-wait-for-regexp proc timeout regexp1)))
+      (if found
+	  (let (buffer-read-only)
+	    ;; A simple-minded busybox has sent " ^H" sequences.
+	    ;; Delete them.
+	    (goto-char (point-min))
+	    (when (re-search-forward "^\\(.\b\\)+$" (point-at-eol) t)
+	      (forward-line 1)
+	      (delete-region (point-min) (point)))
+	    ;; Delete the prompt.
+	    (goto-char (point-max))
+	    (re-search-backward regexp nil t)
+	    (delete-region (point) (point-max)))
+	(if timeout
+	    (tramp-error
+	     proc 'file-error
+	     "[[Remote prompt `%s' not found in %d secs]]"
+	     tramp-end-of-output timeout)
+	  (tramp-error
+	   proc 'file-error
+	   "[[Remote prompt `%s' not found]]" tramp-end-of-output)))
+      ;; Return value is whether end-of-output sentinel was found.
+      found)))
+)
+
+(provide 'docker-tramp-compat)
+
+;;; docker-tramp-compat.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/docker-tramp-20170206.1925/docker-tramp-compat.elc b/configs/shared/emacs/.emacs.d/elpa/docker-tramp-20170206.1925/docker-tramp-compat.elc
new file mode 100644
index 0000000000..bd97d27108
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/docker-tramp-20170206.1925/docker-tramp-compat.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/docker-tramp-20170206.1925/docker-tramp-pkg.el b/configs/shared/emacs/.emacs.d/elpa/docker-tramp-20170206.1925/docker-tramp-pkg.el
new file mode 100644
index 0000000000..66d64b4653
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/docker-tramp-20170206.1925/docker-tramp-pkg.el
@@ -0,0 +1,9 @@
+(define-package "docker-tramp" "20170206.1925" "TRAMP integration for docker containers"
+  '((emacs "24")
+    (cl-lib "0.5"))
+  :keywords
+  '("docker" "convenience")
+  :url "https://github.com/emacs-pe/docker-tramp.el")
+;; Local Variables:
+;; no-byte-compile: t
+;; End:
diff --git a/configs/shared/emacs/.emacs.d/elpa/docker-tramp-20170206.1925/docker-tramp.el b/configs/shared/emacs/.emacs.d/elpa/docker-tramp-20170206.1925/docker-tramp.el
new file mode 100644
index 0000000000..a5f690ab4b
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/docker-tramp-20170206.1925/docker-tramp.el
@@ -0,0 +1,156 @@
+;;; docker-tramp.el --- TRAMP integration for docker containers  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2015 Mario Rodas <marsam@users.noreply.github.com>
+
+;; Author: Mario Rodas <marsam@users.noreply.github.com>
+;; URL: https://github.com/emacs-pe/docker-tramp.el
+;; Keywords: docker, convenience
+;; Version: 0.1
+;; Package-Requires: ((emacs "24") (cl-lib "0.5"))
+
+;; This file is NOT part of GNU Emacs.
+
+;;; License:
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;
+;; `docker-tramp.el' offers a TRAMP method for Docker containers.
+;;
+;; > **NOTE**: `docker-tramp.el' relies in the `docker exec` command.  Tested
+;; > with docker version 1.6.x but should work with versions >1.3
+;;
+;; ## Usage
+;;
+;; Offers the TRAMP method `docker` to access running containers
+;;
+;;     C-x C-f /docker:user@container:/path/to/file
+;;
+;;     where
+;;       user           is the user that you want to use (optional)
+;;       container      is the id or name of the container
+;;
+;; ## Troubleshooting
+;;
+;; ### Tramp hangs on Alpine container
+;;
+;; Busyboxes built with the `ENABLE_FEATURE_EDITING_ASK_TERMINAL' config option
+;; send also escape sequences, which `tramp-wait-for-output' doesn't ignores
+;; correctly.  Tramp upstream fixed in [98a5112][] and is available since
+;; Tramp>=2.3.
+;;
+;; For older versions of Tramp you can dump [docker-tramp-compat.el][] in your
+;; `load-path' somewhere and add the following to your `init.el', which
+;; overwrites `tramp-wait-for-output' with the patch applied:
+;;
+;;     (require 'docker-tramp-compat)
+;;
+;; [98a5112]: http://git.savannah.gnu.org/cgit/tramp.git/commit/?id=98a511248a9405848ed44de48a565b0b725af82c
+;; [docker-tramp-compat.el]: https://github.com/emacs-pe/docker-tramp.el/raw/master/docker-tramp-compat.el
+
+;;; Code:
+(eval-when-compile (require 'cl-lib))
+
+(require 'tramp)
+(require 'tramp-cache)
+
+(defgroup docker-tramp nil
+  "TRAMP integration for Docker containers."
+  :prefix "docker-tramp-"
+  :group 'applications
+  :link '(url-link :tag "Github" "https://github.com/emacs-pe/docker-tramp.el")
+  :link '(emacs-commentary-link :tag "Commentary" "docker-tramp"))
+
+(defcustom docker-tramp-docker-executable "docker"
+  "Path to docker executable."
+  :type 'string
+  :group 'docker-tramp)
+
+;;;###autoload
+(defcustom docker-tramp-docker-options nil
+  "List of docker options."
+  :type '(repeat string)
+  :group 'docker-tramp)
+
+(defcustom docker-tramp-use-names nil
+  "Whether use names instead of id."
+  :type 'boolean
+  :group 'docker-tramp)
+
+;;;###autoload
+(defconst docker-tramp-completion-function-alist
+  '((docker-tramp--parse-running-containers  ""))
+  "Default list of (FUNCTION FILE) pairs to be examined for docker method.")
+
+;;;###autoload
+(defconst docker-tramp-method "docker"
+  "Method to connect docker containers.")
+
+(defun docker-tramp--running-containers ()
+  "Collect docker running containers.
+
+Return a list of containers of the form: \(ID NAME\)"
+  (cl-loop for line in (cdr (ignore-errors (apply #'process-lines docker-tramp-docker-executable (append docker-tramp-docker-options (list "ps")))))
+           for info = (split-string line "[[:space:]]+" t)
+           collect (cons (car info) (last info))))
+
+(defun docker-tramp--parse-running-containers (&optional ignored)
+  "Return a list of (user host) tuples.
+
+TRAMP calls this function with a filename which is IGNORED.  The
+user is an empty string because the docker TRAMP method uses bash
+to connect to the default user containers."
+  (cl-loop for (id name) in (docker-tramp--running-containers)
+           collect (list "" (if docker-tramp-use-names name id))))
+
+;;;###autoload
+(defun docker-tramp-cleanup ()
+  "Cleanup TRAMP cache for docker method."
+  (interactive)
+  (let ((containers (apply 'append (docker-tramp--running-containers))))
+    (maphash (lambda (key _)
+               (and (vectorp key)
+                    (string-equal docker-tramp-method (tramp-file-name-method key))
+                    (not (member (tramp-file-name-host key) containers))
+                    (remhash key tramp-cache-data)))
+             tramp-cache-data))
+  (setq tramp-cache-data-changed t)
+  (if (zerop (hash-table-count tramp-cache-data))
+      (ignore-errors (delete-file tramp-persistency-file-name))
+    (tramp-dump-connection-properties)))
+
+;;;###autoload
+(defun docker-tramp-add-method ()
+  "Add docker tramp method."
+  (add-to-list 'tramp-methods
+               `(,docker-tramp-method
+                 (tramp-login-program      ,docker-tramp-docker-executable)
+                 (tramp-login-args         (,docker-tramp-docker-options ("exec" "-it") ("-u" "%u") ("%h") ("sh")))
+                 (tramp-remote-shell       "/bin/sh")
+                 (tramp-remote-shell-args  ("-i" "-c")))))
+
+;;;###autoload
+(eval-after-load 'tramp
+  '(progn
+     (docker-tramp-add-method)
+     (tramp-set-completion-function docker-tramp-method docker-tramp-completion-function-alist)))
+
+(provide 'docker-tramp)
+
+;; Local Variables:
+;; indent-tabs-mode: nil
+;; End:
+
+;;; docker-tramp.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/docker-tramp-20170206.1925/docker-tramp.elc b/configs/shared/emacs/.emacs.d/elpa/docker-tramp-20170206.1925/docker-tramp.elc
new file mode 100644
index 0000000000..f78a3f40bb
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/docker-tramp-20170206.1925/docker-tramp.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/dockerfile-mode-20180628.959/dockerfile-mode-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/dockerfile-mode-20180628.959/dockerfile-mode-autoloads.el
new file mode 100644
index 0000000000..563d3840a9
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/dockerfile-mode-20180628.959/dockerfile-mode-autoloads.el
@@ -0,0 +1,36 @@
+;;; dockerfile-mode-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "dockerfile-mode" "dockerfile-mode.el" (23377
+;;;;;;  61613 660798 504000))
+;;; Generated autoloads from dockerfile-mode.el
+
+(autoload 'dockerfile-build-buffer "dockerfile-mode" "\
+Build an image called IMAGE-NAME based upon the buffer.
+If prefix arg NO-CACHE is set, don't cache the image.
+
+\(fn IMAGE-NAME &optional NO-CACHE)" t nil)
+
+(autoload 'dockerfile-build-no-cache-buffer "dockerfile-mode" "\
+Build an image called IMAGE-NAME based upon the buffer without cache.
+
+\(fn IMAGE-NAME)" t nil)
+
+(autoload 'dockerfile-mode "dockerfile-mode" "\
+A major mode to edit Dockerfiles.
+\\{dockerfile-mode-map}
+
+\(fn)" t nil)
+
+(add-to-list 'auto-mode-alist '("Dockerfile\\(?:\\..*\\)?\\'" . dockerfile-mode))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; dockerfile-mode-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/dockerfile-mode-20180628.959/dockerfile-mode-pkg.el b/configs/shared/emacs/.emacs.d/elpa/dockerfile-mode-20180628.959/dockerfile-mode-pkg.el
new file mode 100644
index 0000000000..1e5199fc81
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/dockerfile-mode-20180628.959/dockerfile-mode-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "dockerfile-mode" "20180628.959" "Major mode for editing Docker's Dockerfiles" '((emacs "24") (s "1.12")))
diff --git a/configs/shared/emacs/.emacs.d/elpa/dockerfile-mode-20180628.959/dockerfile-mode.el b/configs/shared/emacs/.emacs.d/elpa/dockerfile-mode-20180628.959/dockerfile-mode.el
new file mode 100644
index 0000000000..ab32692460
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/dockerfile-mode-20180628.959/dockerfile-mode.el
@@ -0,0 +1,188 @@
+;;; dockerfile-mode.el --- Major mode for editing Docker's Dockerfiles -*- lexical-binding: t -*-
+
+;; Copyright (c) 2013 Spotify AB
+;; Package-Requires: ((emacs "24") (s "1.12"))
+;; Package-Version: 20180628.959
+;; Homepage: https://github.com/spotify/dockerfile-mode
+;;
+;; Licensed under the Apache License, Version 2.0 (the "License"); you may not
+;; use this file except in compliance with the License. You may obtain a copy of
+;; the License at
+;;
+;; http://www.apache.org/licenses/LICENSE-2.0
+;;
+;; Unless required by applicable law or agreed to in writing, software
+;; distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+;; WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+;; License for the specific language governing permissions and limitations under
+;; the License.
+
+;;; Commentary:
+
+;; Provides a major mode `dockerfile-mode' for use with the standard
+;; `Dockerfile' file format.  Additional convenience functions allow
+;; images to be built easily.
+
+;;; Code:
+
+(require 'sh-script)
+(require 'rx)
+(require 's)
+
+
+(declare-function cygwin-convert-file-name-to-windows "cygw32.c" (file &optional absolute-p))
+
+(defgroup dockerfile nil
+  "dockerfile code editing commands for Emacs."
+  :link '(custom-group-link :tag "Font Lock Faces group" font-lock-faces)
+  :prefix "dockerfile-"
+  :group 'languages)
+
+(defcustom dockerfile-mode-hook nil
+  "*Hook called by `dockerfile-mode'."
+  :type 'hook
+  :group 'dockerfile)
+
+(defcustom dockerfile-use-sudo nil
+  "Runs docker builder command with sudo."
+  :type 'boolean
+  :group 'dockerfile)
+
+(defcustom dockerfile-build-args nil
+  "List of --build-arg to pass to docker build.
+
+Each element of the list will be passed as a separate
+ --build-arg to the docker build command."
+  :type '(repeat string)
+  :group 'dockerfile)
+
+(defface dockerfile-image-name
+  '((t (:inherit (font-lock-type-face bold))))
+  "Face to highlight the base image name after FROM instruction.")
+
+(defface dockerfile-image-alias
+  '((t (:inherit (font-lock-constant-face bold))))
+  "Face to highlight the base image alias inf FROM ... AS <alias> construct.")
+
+(defvar dockerfile-font-lock-keywords
+  `(,(cons (rx (or line-start "onbuild ")
+               (group (or "from" "maintainer" "run" "cmd" "expose" "env" "arg"
+                          "add" "copy" "entrypoint" "volume" "user" "workdir" "onbuild"
+                          "label" "stopsignal" "shell" "healthcheck"))
+               word-boundary)
+           font-lock-keyword-face)
+    (,(rx "FROM " (group (+? nonl)) (or " " eol) (? "as " (group (1+ nonl))))
+     (1 'dockerfile-image-name)
+     (2 'dockerfile-image-alias nil t))
+    ,@(sh-font-lock-keywords)
+    ,@(sh-font-lock-keywords-2)
+    ,@(sh-font-lock-keywords-1))
+  "Default `font-lock-keywords' for `dockerfile mode'.")
+
+(defvar dockerfile-mode-map
+  (let ((map (make-sparse-keymap))
+        (menu-map (make-sparse-keymap)))
+    (define-key map "\C-c\C-b" 'dockerfile-build-buffer)
+    (define-key map "\C-c\M-b" 'dockerfile-build-no-cache-buffer)
+    (define-key map "\C-c\C-z" 'dockerfile-test-function)
+    (define-key map "\C-c\C-c" 'comment-region)
+    (define-key map [menu-bar dockerfile-mode] (cons "Dockerfile" menu-map))
+    (define-key menu-map [dfc]
+      '(menu-item "Comment Region" comment-region
+                  :help "Comment Region"))
+    (define-key menu-map [dfb]
+      '(menu-item "Build" dockerfile-build-buffer
+                  :help "Send the Dockerfile to docker build"))
+    (define-key menu-map [dfb]
+      '(menu-item "Build without cache" dockerfile-build-no-cache-buffer
+                  :help "Send the Dockerfile to docker build without cache"))
+    map))
+
+(defvar dockerfile-mode-syntax-table
+  (let ((table (make-syntax-table)))
+    (modify-syntax-entry ?# "<" table)
+    (modify-syntax-entry ?\n ">" table)
+    (modify-syntax-entry ?' "\"" table)
+    (modify-syntax-entry ?= "." table)
+    table)
+  "Syntax table for `dockerfile-mode'.")
+
+(define-abbrev-table 'dockerfile-mode-abbrev-table nil
+  "Abbrev table used while in `dockerfile-mode'.")
+
+(unless dockerfile-mode-abbrev-table
+  (define-abbrev-table 'dockerfile-mode-abbrev-table ()))
+
+(defun dockerfile-build-arg-string ()
+  "Create a --build-arg string for each element in `dockerfile-build-args'."
+  (mapconcat (lambda (arg) (concat "--build-arg " (shell-quote-argument arg)))
+             dockerfile-build-args " "))
+
+(defun dockerfile-standard-filename (file)
+  "Convert the FILE name to OS standard.
+If in Cygwin environment, uses Cygwin specific function to convert the
+file name.  Otherwise, uses Emacs' standard conversion function."
+  (if (fboundp 'cygwin-convert-file-name-to-windows)
+      (s-replace "\\" "\\\\" (cygwin-convert-file-name-to-windows file))
+    (convert-standard-filename file)))
+
+(defvar dockerfile-image-name nil
+  "Name of the dockerfile currently being used.
+This can be set in file or directory-local variables.")
+(define-obsolete-variable-alias 'docker-image-name 'dockerfile-image-name)
+
+(defvar dockerfile-image-name-history nil
+  "History of image names read by `dockerfile-read-image-name'.")
+
+(defun dockerfile-read-image-name ()
+  "Read a docker image name."
+  (read-string "Image name: " dockerfile-image-name 'dockerfile-image-name-history))
+
+
+;;;###autoload
+(defun dockerfile-build-buffer (image-name &optional no-cache)
+  "Build an image called IMAGE-NAME based upon the buffer.
+If prefix arg NO-CACHE is set, don't cache the image."
+  (interactive (list (dockerfile-read-image-name) prefix-arg))
+  (save-buffer)
+  (if (stringp image-name)
+      (compilation-start
+       (format
+        "%sdocker build %s -t %s %s -f %s %s"
+        (if dockerfile-use-sudo "sudo " "")
+        (if no-cache "--no-cache" "")
+        (shell-quote-argument image-name)
+        (dockerfile-build-arg-string)
+        (shell-quote-argument (dockerfile-standard-filename (buffer-file-name)))
+        (shell-quote-argument (dockerfile-standard-filename default-directory)))
+       nil
+       (lambda (_) (format "*docker-build-output: %s *" image-name)))
+    (print "dockerfile-image-name must be a string, consider surrounding it with double quotes")))
+
+;;;###autoload
+(defun dockerfile-build-no-cache-buffer (image-name)
+  "Build an image called IMAGE-NAME based upon the buffer without cache."
+  (interactive (list (dockerfile-read-image-name)))
+  (dockerfile-build-buffer image-name t))
+
+;;;###autoload
+(define-derived-mode dockerfile-mode prog-mode "Dockerfile"
+  "A major mode to edit Dockerfiles.
+\\{dockerfile-mode-map}
+"
+  (set-syntax-table dockerfile-mode-syntax-table)
+  (set (make-local-variable 'require-final-newline) mode-require-final-newline)
+  (set (make-local-variable 'comment-start) "#")
+  (set (make-local-variable 'comment-end) "")
+  (set (make-local-variable 'comment-start-skip) "#+ *")
+  (set (make-local-variable 'parse-sexp-ignore-comments) t)
+  (set (make-local-variable 'font-lock-defaults)
+       '(dockerfile-font-lock-keywords nil t))
+  (setq local-abbrev-table dockerfile-mode-abbrev-table))
+
+;;;###autoload
+(add-to-list 'auto-mode-alist '("Dockerfile\\(?:\\..*\\)?\\'" . dockerfile-mode))
+
+(provide 'dockerfile-mode)
+
+;;; dockerfile-mode.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/dockerfile-mode-20180628.959/dockerfile-mode.elc b/configs/shared/emacs/.emacs.d/elpa/dockerfile-mode-20180628.959/dockerfile-mode.elc
new file mode 100644
index 0000000000..3a650965b9
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/dockerfile-mode-20180628.959/dockerfile-mode.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-challenger-deep-theme.el b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-challenger-deep-theme.el
new file mode 100644
index 0000000000..b8d122f033
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-challenger-deep-theme.el
@@ -0,0 +1,164 @@
+;;; doom-challenger-deep-theme.el --- inspired by Atom City Lights
+(require 'doom-themes)
+
+;;
+(defgroup doom-challenger-deep-theme nil
+  "Options for doom-themes"
+  :group 'doom-themes)
+
+(defcustom doom-challenger-deep-brighter-modeline nil
+  "If non-nil, more vivid colors will be used to style the mode-line."
+  :group 'doom-challenger-deep-theme
+  :type 'boolean)
+
+(defcustom doom-challenger-deep-brighter-comments nil
+  "If non-nil, comments will be highlighted in more vivid colors."
+  :group 'doom-challenger-deep-theme
+  :type 'boolean)
+
+(defcustom doom-challenger-deep-comment-bg doom-challenger-deep-brighter-comments
+  "If non-nil, comments will have a subtle, darker background. Enhancing their
+legibility."
+  :group 'doom-challenger-deep-theme
+  :type 'boolean)
+
+(defcustom doom-challenger-deep-padded-modeline doom-themes-padded-modeline
+  "If non-nil, adds a 4px padding to the mode-line. Can be an integer to
+determine the exact padding."
+  :group 'doom-challenger-deep-theme
+  :type '(or integer boolean))
+
+;;
+(def-doom-theme doom-challenger-deep
+  "A dark theme inspired by Atom One Dark"
+
+  ;; name        default   256       16
+  ((bg         '("#1b182c" "#1c1c1c" nil            ))
+   (bg-alt     '("#12111E" nil       nil            ))
+   (base0      '("#100e23" "black"   "black"        ))
+   (base1      '("#292F37" "#1e1e1e" "brightblack"  ))
+   (base2      '("#3d4551" "#2e2e2e" "brightblack"  ))
+   (base3      '("#4C4B68" "#262626" "brightblack"  ))
+   (base4      '("#565575" "#3f3f3f" "brightblack"  ))
+   (base5      '("#858FA5" "#525252" "brightblack"  ))
+   (base6      '("#9BA7BF" "#6b6b6b" "brightblack"  ))
+   (base7      '("#B0BED8" "#979797" "brightblack"  ))
+   (base8      '("#BAC9E4" "#dfdfdf" "white"        ))
+   (fg-alt     '("#cbe3e7" "#bfbfbf" "brightwhite"  ))
+   (fg         '("#cbe3e7" "#2d2d2d" "white"        ))
+
+   (grey       base4)
+   (red        '("#ff8080" "#ff6655" "red"          ))
+   (orange     '("#ffb378" "#dd8844" "brightred"    ))
+   (green      '("#95ffa4" "#99bb66" "green"        ))
+   (teal       '("#63f2f1" "#44b9b1" "brightgreen"  ))
+   (yellow     '("#ffe9aa" "#ECBE7B" "yellow"       ))
+   (blue       '("#91ddff" "#51afef" "brightblue"   ))
+   (dark-blue  '("#65b2ff" "#2257A0" "blue"         ))
+   (magenta    '("#c991e1" "#c678dd" "magenta"      ))
+   (violet     '("#906cff" "#a9a1e1" "brightmagenta"))
+   (cyan       '("#aaffe4" "#46D9FF" "brightcyan"   ))
+   (dark-cyan  '("#62d196" "#5699AF" "cyan"   ))
+
+   ;; face categories -- required for all themes
+   (highlight      violet)
+   (vertical-bar base1)
+   (selection      violet)
+   (builtin        magenta)
+   (comments       (if doom-challenger-deep-brighter-comments base3 base2))
+   (doc-comments   (if doom-challenger-deep-brighter-comments (doom-darken dark-cyan 0.3) base5) )
+   (constants      cyan)
+   (functions      magenta)
+   (keywords       red)
+   (methods        magenta)
+   (operators      dark-cyan)
+   (type           blue)
+   (strings        yellow)
+   (variables      yellow)
+   (numbers        orange)
+   (region         base2)
+   (error          red)
+   (warning        yellow)
+   (success        green)
+   (vc-modified    orange)
+   (vc-added       green)
+   (vc-deleted     red)
+
+   ;; custom categories
+   (hidden     `(,(car bg) "black" "black"))
+   (-modeline-bright doom-challenger-deep-brighter-modeline)
+   (-modeline-pad
+    (when doom-challenger-deep-padded-modeline
+      (if (integerp doom-challenger-deep-padded-modeline) doom-challenger-deep-padded-modeline 4)))
+
+   (modeline-fg     nil)
+   (modeline-fg-alt base5)
+
+   (modeline-bg
+    (if -modeline-bright
+        base3
+      `(,(doom-darken (car bg) 0.15) ,@(cdr base0))))
+   (modeline-bg-l
+    (if -modeline-bright
+        base3
+      `(,(doom-darken (car bg) 0.1) ,@(cdr base0))))
+   (modeline-bg-inactive   (doom-darken bg 0.1))
+   (modeline-bg-inactive-l `(,(car bg) ,@(cdr base1))))
+
+
+  ;; --- extra faces ------------------------
+  ((elscreen-tab-other-screen-face :background "#353a42" :foreground "#1e2022")
+
+   ((line-number &override) :foreground base4)
+   ((line-number-current-line &override) :foreground fg)
+
+   (font-lock-comment-face
+    :foreground comments
+    :background (if doom-challenger-deep-comment-bg (doom-lighten bg 0.05)))
+   (font-lock-doc-face
+    :inherit 'font-lock-comment-face
+    :foreground doc-comments)
+
+   (doom-modeline-bar :background (if -modeline-bright modeline-bg highlight))
+
+   (mode-line
+    :background modeline-bg :foreground modeline-fg
+    :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))
+   (mode-line-inactive
+    :background modeline-bg-inactive :foreground modeline-fg-alt
+    :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive)))
+   (mode-line-emphasis
+    :foreground (if -modeline-bright base8 highlight))
+
+   (solaire-mode-line-face
+    :inherit 'mode-line
+    :background modeline-bg-l
+    :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-l)))
+   (solaire-mode-line-inactive-face
+    :inherit 'mode-line-inactive
+    :background modeline-bg-inactive-l
+    :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive-l)))
+
+   ;; --- major-mode faces -------------------
+   ;; css-mode / scss-mode
+   (css-proprietary-property :foreground orange)
+   (css-property             :foreground green)
+   (css-selector             :foreground blue)
+
+   ;; markdown-mode
+   (markdown-markup-face :foreground base5)
+   (markdown-header-face :inherit 'bold :foreground red)
+   (markdown-code-face :background (doom-lighten base3 0.05))
+
+   ;; org-mode
+   (org-hide :foreground hidden)
+   (org-block :background base2)
+   (org-block-begin-line :background base2 :foreground comments)
+   (solaire-org-hide-face :foreground hidden))
+
+
+  ;; --- extra variables ---------------------
+  ;; ()
+  )
+
+;;; doom-challenger-deep-theme.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-challenger-deep-theme.elc b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-challenger-deep-theme.elc
new file mode 100644
index 0000000000..e0df946a5a
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-challenger-deep-theme.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-city-lights-theme.el b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-city-lights-theme.el
new file mode 100644
index 0000000000..c249fe692d
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-city-lights-theme.el
@@ -0,0 +1,164 @@
+;;; doom-city-lights-theme.el --- inspired by Atom City Lights
+(require 'doom-themes)
+
+;;
+(defgroup doom-city-lights-theme nil
+  "Options for doom-themes"
+  :group 'doom-themes)
+
+(defcustom doom-city-lights-brighter-modeline nil
+  "If non-nil, more vivid colors will be used to style the mode-line."
+  :group 'doom-city-lights-theme
+  :type 'boolean)
+
+(defcustom doom-city-lights-brighter-comments nil
+  "If non-nil, comments will be highlighted in more vivid colors."
+  :group 'doom-city-lights-theme
+  :type 'boolean)
+
+(defcustom doom-city-lights-comment-bg doom-city-lights-brighter-comments
+  "If non-nil, comments will have a subtle, darker background. Enhancing their
+legibility."
+  :group 'doom-city-lights-theme
+  :type 'boolean)
+
+(defcustom doom-city-lights-padded-modeline doom-themes-padded-modeline
+  "If non-nil, adds a 4px padding to the mode-line. Can be an integer to
+determine the exact padding."
+  :group 'doom-city-lights-theme
+  :type '(or integer boolean))
+
+;;
+(def-doom-theme doom-city-lights
+  "A dark theme inspired by Atom One Dark"
+
+  ;; name        default   256       16
+  ((bg         '("#1D252C" nil       nil            ))
+   (bg-alt     '("#181E24" nil       nil            ))
+   (base0      '("#10151C" "black"   "black"        ))
+   (base1      '("#171D22" "#1e1e1e" "brightblack"  ))
+   (base2      '("#20282F" "#2e2e2e" "brightblack"  ))
+   (base3      '("#28323B" "#262626" "brightblack"  ))
+   (base4      '("#384551" "#3f3f3f" "brightblack"  ))
+   (base5      '("#56697A" "#525252" "brightblack"  ))
+   (base6      '("#688094" "#6b6b6b" "brightblack"  ))
+   (base7      '("#7FA0B7" "#979797" "brightblack"  ))
+   (base8      '("#9CAABB" "#dfdfdf" "white"        ))
+   (fg-alt     '("#728CA0" "#bfbfbf" "brightwhite"  ))
+   (fg         '("#A0B3C5" "#2d2d2d" "white"        ))
+
+   (grey       base4)
+   (red        '("#D95468" "#ff6655" "red"          ))
+   (orange     '("#D98E48" "#dd8844" "brightred"    ))
+   (green      '("#8BD49C" "#99bb66" "green"        ))
+   (teal       '("#4db5bd" "#44b9b1" "brightgreen"  ))
+   (yellow     '("#EBBF83" "#ECBE7B" "yellow"       ))
+   (blue       '("#5EC4FF" "#51afef" "brightblue"   ))
+   (dark-blue  '("#5C748E" "#2257A0" "blue"         ))
+   (magenta    '("#E27E8D" "#c678dd" "magenta"      ))
+   (violet     '("#B62D65" "#a9a1e1" "brightmagenta"))
+   (cyan       '("#70E1E8" "#46D9FF" "brightcyan"   ))
+   (dark-cyan  '("#41858C" "#5699AF" "cyan"   ))
+
+   ;; face categories -- required for all themes
+   (highlight      blue)
+   (vertical-bar   (doom-darken base1 0.5))
+   (selection      dark-blue)
+   (builtin        blue)
+   (comments       (if doom-city-lights-brighter-comments dark-cyan base5))
+   (doc-comments   (doom-lighten (if doom-city-lights-brighter-comments dark-cyan base5) 0.25))
+   (constants      red)
+   (functions      teal)
+   (keywords       blue)
+   (methods        cyan)
+   (operators      blue)
+   (type           yellow)
+   (strings        base7)
+   (variables      base8)
+   (numbers        magenta)
+   (region         base3)
+   (error          red)
+   (warning        yellow)
+   (success        green)
+   (vc-modified    orange)
+   (vc-added       green)
+   (vc-deleted     red)
+
+   ;; custom categories
+   (hidden     `(,(car bg) "black" "black"))
+   (-modeline-bright doom-city-lights-brighter-modeline)
+   (-modeline-pad
+    (when doom-city-lights-padded-modeline
+      (if (integerp doom-city-lights-padded-modeline) doom-city-lights-padded-modeline 4)))
+
+   (modeline-fg     nil)
+   (modeline-fg-alt base5)
+
+   (modeline-bg
+    (if -modeline-bright
+        base3
+        `(,(doom-darken (car bg) 0.15) ,@(cdr base0))))
+   (modeline-bg-l
+    (if -modeline-bright
+        base3
+        `(,(doom-darken (car bg) 0.1) ,@(cdr base0))))
+   (modeline-bg-inactive   (doom-darken bg 0.1))
+   (modeline-bg-inactive-l `(,(car bg) ,@(cdr base1))))
+
+
+  ;; --- extra faces ------------------------
+  ((elscreen-tab-other-screen-face :background "#353a42" :foreground "#1e2022")
+
+   ((line-number &override) :foreground base4)
+   ((line-number-current-line &override) :foreground fg)
+
+   (font-lock-comment-face
+    :foreground comments
+    :background (if doom-city-lights-comment-bg (doom-lighten bg 0.05)))
+   (font-lock-doc-face
+    :inherit 'font-lock-comment-face
+    :foreground doc-comments)
+
+   (doom-modeline-bar :background (if -modeline-bright modeline-bg highlight))
+
+   (mode-line
+    :background modeline-bg :foreground modeline-fg
+    :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))
+   (mode-line-inactive
+    :background modeline-bg-inactive :foreground modeline-fg-alt
+    :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive)))
+   (mode-line-emphasis
+    :foreground (if -modeline-bright base8 highlight))
+
+   (solaire-mode-line-face
+    :inherit 'mode-line
+    :background modeline-bg-l
+    :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-l)))
+   (solaire-mode-line-inactive-face
+    :inherit 'mode-line-inactive
+    :background modeline-bg-inactive-l
+    :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive-l)))
+
+   ;; --- major-mode faces -------------------
+   ;; css-mode / scss-mode
+   (css-proprietary-property :foreground orange)
+   (css-property             :foreground green)
+   (css-selector             :foreground blue)
+
+   ;; markdown-mode
+   (markdown-markup-face :foreground base5)
+   (markdown-header-face :inherit 'bold :foreground red)
+   (markdown-code-face :background (doom-lighten base3 0.05))
+
+   ;; org-mode
+   (org-hide :foreground hidden)
+   (org-block :background base2)
+   (org-block-begin-line :background base2 :foreground comments)
+   (solaire-org-hide-face :foreground hidden))
+
+
+  ;; --- extra variables ---------------------
+  ;; ()
+  )
+
+;;; doom-city-lights-theme.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-city-lights-theme.elc b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-city-lights-theme.elc
new file mode 100644
index 0000000000..ca4a0e740b
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-city-lights-theme.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-dracula-theme.el b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-dracula-theme.el
new file mode 100644
index 0000000000..5b738beee7
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-dracula-theme.el
@@ -0,0 +1,212 @@
+;;; doom-dracula-theme.el - based on https://draculatheme.com/
+(require 'doom-themes)
+
+;;
+(defgroup doom-dracula-theme nil
+  "Options for doom-themes"
+  :group 'doom-themes)
+
+(defcustom doom-dracula-brighter-modeline nil
+  "If non-nil, more vivid colors will be used to style the mode-line."
+  :group 'doom-dracula-theme
+  :type 'boolean)
+
+(defcustom doom-dracula-brighter-comments nil
+  "If non-nil, comments will be highlighted in more vivid colors."
+  :group 'doom-dracula-theme
+  :type 'boolean)
+
+(defcustom doom-dracula-colorful-headers nil
+  "If non-nil, headers in org-mode will be more colorful; which is truer to the
+original Dracula Emacs theme."
+  :group 'doom-dracula-theme
+  :type 'boolean)
+
+(defcustom doom-dracula-comment-bg doom-dracula-brighter-comments
+  "If non-nil, comments will have a subtle, darker background. Enhancing their
+legibility."
+  :group 'doom-dracula-theme
+  :type 'boolean)
+
+(defcustom doom-dracula-padded-modeline doom-themes-padded-modeline
+  "If non-nil, adds a 4px padding to the mode-line. Can be an integer to
+determine the exact padding."
+  :group 'doom-dracula-theme
+  :type '(or integer boolean))
+
+;;
+(def-doom-theme doom-dracula
+  "A dark theme inspired by Atom One Dark"
+
+  ;; name        default   256       16
+  ((bg         '("#282a36" nil       nil            ))
+   (bg-alt     '("#1E2029" nil       nil            ))
+   (base0      '("#1E2029" "black"   "black"        ))
+   (base1      '("#282a36" "#1e1e1e" "brightblack"  ))
+   (base2      '("#373844" "#2e2e2e" "brightblack"  ))
+   (base3      '("#44475a" "#262626" "brightblack"  ))
+   (base4      '("#565761" "#3f3f3f" "brightblack"  ))
+   (base5      '("#6272a4" "#525252" "brightblack"  ))
+   (base6      '("#b6b6b2" "#6b6b6b" "brightblack"  ))
+   (base7      '("#ccccc7" "#979797" "brightblack"  ))
+   (base8      '("#f8f8f2" "#dfdfdf" "white"        ))
+   (fg         '("#f8f8f2" "#2d2d2d" "white"        ))
+   (fg-alt     '("#e2e2dc" "#bfbfbf" "brightwhite"  ))
+
+   (grey       base4)
+   (red        '("#ff5555" "#ff6655" "red"          ))
+   (orange     '("#ffb86c" "#dd8844" "brightred"    ))
+   (green      '("#50fa7b" "#99bb66" "green"        ))
+   (teal       '("#0189cc" "#44b9b1" "brightgreen"  ))
+   (yellow     '("#f1fa8c" "#ECBE7B" "yellow"       ))
+   (blue       '("#61bfff" "#61bfff" "brightblue"   ))
+   (dark-blue  '("#0189cc" "#2257A0" "blue"         ))
+   (magenta    '("#ff79c6" "#c678dd" "magenta"      ))
+   (violet     '("#bd93f9" "#a9a1e1" "brightmagenta"))
+   (cyan       '("#8be9fd" "#46D9FF" "brightcyan"   ))
+   (dark-cyan  '("#8be9fd" "#5699AF" "cyan"         ))
+
+   ;; face categories -- required for all themes
+   (highlight      violet)
+   (vertical-bar   (doom-darken base1 0.1))
+   (selection      dark-blue)
+   (builtin        orange)
+   (comments       (if doom-dracula-brighter-comments dark-cyan base5))
+   (doc-comments   (doom-lighten (if doom-dracula-brighter-comments dark-cyan base5) 0.25))
+   (constants      cyan)
+   (functions      green)
+   (keywords       magenta)
+   (methods        teal)
+   (operators      violet)
+   (type           blue)
+   (strings        yellow)
+   (variables      base8)
+   (numbers        red)
+   (region         base3)
+   (error          red)
+   (warning        yellow)
+   (success        green)
+   (vc-modified    orange)
+   (vc-added       green)
+   (vc-deleted     red)
+
+   ;; custom categories
+   (level1 magenta)
+   (level2 violet)
+   (level3 (if doom-dracula-colorful-headers green   (doom-lighten violet 0.35)))
+   (level4 (if doom-dracula-colorful-headers yellow  (doom-lighten magenta 0.35)))
+   (level5 (if doom-dracula-colorful-headers cyan    (doom-lighten violet 0.6)))
+   (level6 (if doom-dracula-colorful-headers orange  (doom-lighten magenta 0.6)))
+   (level7 (if doom-dracula-colorful-headers blue    (doom-lighten violet 0.85)))
+   (level8 (if doom-dracula-colorful-headers magenta (doom-lighten magenta 0.85)))
+   (level9 (if doom-dracula-colorful-headers violet  (doom-lighten violet 0.95)))
+
+   (hidden     base1)
+   (-modeline-bright doom-dracula-brighter-modeline)
+   (-modeline-pad
+    (when doom-dracula-padded-modeline
+      (if (integerp doom-dracula-padded-modeline) doom-dracula-padded-modeline 4)))
+
+   (modeline-fg     nil)
+   (modeline-fg-alt base5)
+
+   (modeline-bg
+
+    (if -modeline-bright
+        (doom-darken  magenta 0.675)
+      `(,(car bg) ,@(cdr base0))))
+   (modeline-bg-l
+    (if -modeline-bright
+        (doom-darken magenta 0.6)
+      `(,(doom-darken (car bg) 0.15) ,@(cdr base0))))
+   (modeline-bg-inactive   (doom-darken bg 0.1))
+   (modeline-bg-inactive-l `(,(doom-darken (car bg) 0.075) ,@(cdr base1))))
+
+
+  ;; --- extra faces ------------------------
+  ((elscreen-tab-other-screen-face :background "#353a42" :foreground "#1e2022")
+
+   ((line-number &override) :foreground base4)
+   ((line-number-current-line &override) :foreground fg)
+
+   (font-lock-comment-face
+    :foreground comments
+    :background (if doom-dracula-comment-bg (doom-lighten bg 0.05)))
+   (font-lock-doc-face
+    :inherit 'font-lock-comment-face
+    :foreground doc-comments)
+   (solaire-hl-line-face :background base2)
+   (doom-modeline-bar :background (if -modeline-bright modeline-bg highlight))
+   (mode-line
+    :background modeline-bg :foreground modeline-fg
+    :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))
+   (mode-line-inactive
+    :background modeline-bg-inactive :foreground modeline-fg-alt
+    :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive)))
+   (mode-line-emphasis
+    :foreground (if -modeline-bright base8 highlight))
+
+   (solaire-mode-line-face
+    :inherit 'mode-line
+    :background modeline-bg-l
+    :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-l)))
+   (solaire-mode-line-inactive-face
+    :inherit 'mode-line-inactive
+    :background modeline-bg-inactive-l
+    :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive-l)))
+
+   ;; --- major-mode faces -------------------
+   ;; css-mode / scss-mode
+   (css-proprietary-property :foreground orange)
+   (css-property             :foreground green)
+   (css-selector             :foreground blue)
+
+   ;; markdown-mode
+   (markdown-markup-face :foreground base5)
+   (markdown-header-face :inherit 'bold :foreground red)
+   (markdown-code-face :background (doom-lighten base3 0.05))
+
+   ;; org-mode
+   (org-level-1 :background base1 :foreground level1 :height 1.2 :weight 'bold)
+   (org-level-2 :foreground level2 :weight 'bold)
+   (org-level-3 :inherit 'org-level-2 :foreground level3)
+   (org-level-4 :inherit 'org-level-2 :foreground level4)
+   (org-level-5 :inherit 'org-level-2 :foreground level5)
+   (org-level-6 :inherit 'org-level-2 :foreground level6)
+   (org-level-7 :inherit 'org-level-2 :foreground level7)
+   (org-todo :foreground orange :bold 'inherit :background (doom-darken base1 0.02))
+   (org-done :foreground green :strike-through nil :background base2 :bold t)
+   (org-headline-done :foreground base4 :strike-through nil)
+   ((org-tag &override) :foreground (doom-lighten orange 0.3))
+   (org-agenda-date :foreground cyan)
+   (org-agenda-dimmed-todo-face :foreground comments)
+   (org-agenda-done :foreground base4)
+   (org-agenda-structure :foreground violet)
+   (org-block            :background (doom-darken base1 0.125) :foreground violet)
+   (org-block-begin-line :background (doom-darken base1 0.125) :foreground comments)
+   (org-code :foreground yellow)
+   (org-column :background base1)
+   (org-column-title :background base1 :bold t :underline t)
+   (org-date :foreground cyan)
+   (org-document-info :foreground blue)
+   (org-document-info-keyword :foreground comments)
+   (org-ellipsis :foreground comments)
+   (org-footnote :foreground blue)
+   (org-headline-base :foreground comments :strike-through t :bold nil)
+   (org-link :foreground orange :underline t :weight 'bold)
+   (org-priority :foreground cyan)
+   (org-scheduled :foreground green)
+   (org-scheduled-previously :foreground yellow)
+   (org-scheduled-today :foreground orange)
+   (org-sexp-date :foreground base4)
+   (org-special-keyword :foreground yellow)
+   (org-table :foreground violet)
+   (org-upcoming-deadline :foreground yellow)
+   (org-warning :foreground magenta)
+   )
+
+  ;; --- extra variables ---------------------
+  ;; ()
+  )
+
+;;; doom-dracula-theme.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-dracula-theme.elc b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-dracula-theme.elc
new file mode 100644
index 0000000000..2239efffd2
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-dracula-theme.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-molokai-theme.el b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-molokai-theme.el
new file mode 100644
index 0000000000..4b799722e7
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-molokai-theme.el
@@ -0,0 +1,171 @@
+;; doom-molokai-theme.el --- inspired by Textmate's monokai
+(require 'doom-themes)
+
+;;
+(defgroup doom-molokai-theme nil
+  "Options for doom-molokai."
+  :group 'doom-themes)
+
+(defcustom doom-molokai-brighter-comments nil
+  "If non-nil, comments will be highlighted in more vivid colors."
+  :group 'doom-molokai-theme
+  :type 'boolean)
+
+(defcustom doom-molokai-padded-modeline doom-themes-padded-modeline
+  "If non-nil, adds a 4px padding to the mode-line. Can be an integer to
+determine the exact padding."
+  :group 'doom-molokai-theme
+  :type '(or integer boolean))
+
+;;
+(def-doom-theme doom-molokai
+  "A dark, vibrant theme inspired by Textmate's monokai."
+
+  ;; name        gui       256       16
+  ((bg         '("#1c1e1f" nil       nil))
+   (bg-alt     '("#222323" nil       nil))
+   (base0      '("#000000"))
+   (base1      '("#151617" "#101010" "brightblack"))
+   (base2      '("#1d1f20" "#191919" "brightblack"))
+   (base3      '("#2d2e2e" "#252525" "brightblack"))
+   (base4      '("#4e4e4e" "#454545" "brightblack"))
+   (base5      '("#555556" "#6b6b6b" "brightblack"))
+   (base6      '("#767679" "#7b7b7b" "brightblack"))
+   (base7      '("#cfc0c5" "#c1c1c1" "brightblack"))
+   (base8      '("#ffffff" "#ffffff" "brightwhite"))
+   (fg         '("#d6d6d4" "#dfdfdf" "brightwhite"))
+   (fg-alt     '("#556172" "#4d4d4d" "white"))
+
+   (grey       '("#525254" "#515154" "brightblack"))
+   (red        '("#e74c3c" "#e74c3c" "red"))
+   (orange     '("#fd971f" "#fd971f" "brightred"))
+   (green      '("#b6e63e" "#b6e63e" "green"))
+   (teal       green)
+   (yellow     '("#e2c770" "#e2c770" "yellow"))
+   (blue       '("#268bd2" "#2686D6" "brightblue"))
+   (dark-blue  '("#727280" "#727280" "blue"))
+   (magenta    '("#fb2874" "#fb2874" "magenta"))
+   (violet     '("#9c91e4" "#9c91e4" "brightmagenta"))
+   (cyan       '("#66d9ef" "#66d9ef" "brightcyan"))
+   (dark-cyan  '("#8fa1b3" "#8FA1B3" "cyan"))
+
+   ;; face categories
+   (highlight      orange)
+   (vertical-bar   (doom-lighten bg 0.1))
+   (selection      base0)
+   (builtin        orange)
+   (comments       (if doom-molokai-brighter-comments violet base5))
+   (doc-comments   (if doom-molokai-brighter-comments (doom-lighten violet 0.1) (doom-lighten base5 0.25)))
+   (constants      orange)
+   (functions      green)
+   (keywords       magenta)
+   (methods        cyan)
+   (operators      violet)
+   (type           cyan)
+   (strings        yellow)
+   (variables      orange)
+   (numbers        violet)
+   (region         base4)
+   (error          red)
+   (warning        yellow)
+   (success        green)
+   (vc-modified    base4)
+   (vc-added       (doom-darken green 0.15))
+   (vc-deleted     red)
+
+   ;; custom categories
+   (-modeline-pad
+    (when doom-molokai-padded-modeline
+      (if (integerp doom-molokai-padded-modeline)
+          doom-molokai-padded-modeline
+        4)))
+
+   (org-quote `(,(doom-lighten (car bg) 0.05) "#1f1f1f")))
+
+
+  ;; --- extra faces ------------------------
+  ((lazy-highlight :background violet :foreground base0 :distant-foreground base0 :bold bold)
+   (cursor :background magenta)
+
+   (mode-line
+    :background base3 :foreground base8
+    :box (if -modeline-pad `(:line-width ,-modeline-pad :color base3)))
+   (mode-line-inactive
+    :background (doom-darken base2 0.2) :foreground base4
+    :box (if -modeline-pad `(:line-width ,-modeline-pad :color base2)))
+   (doom-modeline-bar :background green)
+
+   (doom-modeline-buffer-modified :inherit 'bold :foreground orange)
+   (doom-modeline-buffer-path :inherit 'bold :foreground green)
+
+   ((line-number &override) :foreground base5 :distant-foreground nil)
+   ((line-number-current-line &override) :foreground base7 :distant-foreground nil)
+
+   (isearch :foreground base0 :background green)
+
+   ;; ediff
+   (ediff-fine-diff-A :background (doom-blend magenta bg 0.3) :weight 'bold)
+
+   ;; evil-mode
+   (evil-search-highlight-persist-highlight-face :background violet)
+
+   ;; evil-snipe
+   (evil-snipe-first-match-face :foreground base0 :background green)
+   (evil-snipe-matches-face     :foreground green :underline t)
+
+   ;; flycheck
+   (flycheck-error   :underline `(:style wave :color ,red)    :background base3)
+   (flycheck-warning :underline `(:style wave :color ,yellow) :background base3)
+   (flycheck-info    :underline `(:style wave :color ,green)  :background base3)
+
+   ;; helm
+   (helm-swoop-target-line-face :foreground magenta :inverse-video t)
+
+   ;; ivy
+   (ivy-current-match :background base3)
+   (ivy-minibuffer-match-face-1 :background base1 :foreground base4)
+
+   ;; neotree
+   (neo-dir-link-face   :foreground cyan)
+   (neo-expand-btn-face :foreground magenta)
+
+   ;; rainbow-delimiters
+   (rainbow-delimiters-depth-1-face :foreground magenta)
+   (rainbow-delimiters-depth-2-face :foreground orange)
+   (rainbow-delimiters-depth-3-face :foreground green)
+   (rainbow-delimiters-depth-4-face :foreground cyan)
+   (rainbow-delimiters-depth-5-face :foreground magenta)
+   (rainbow-delimiters-depth-6-face :foreground orange)
+   (rainbow-delimiters-depth-7-face :foreground green)
+
+
+   ;; --- major-mode faces -------------------
+   ;; css-mode / scss-mode
+   (css-proprietary-property :foreground keywords)
+
+   ;; markdown-mode
+   (markdown-blockquote-face :inherit 'italic :foreground dark-blue)
+   (markdown-list-face :foreground magenta)
+   (markdown-pre-face  :foreground cyan)
+   (markdown-link-face :inherit 'bold :foreground blue)
+   (markdown-code-face :background (doom-lighten base2 0.045))
+
+   ;; org-mode
+   (org-level-1 :background base2 :foreground magenta :bold bold :height 1.2)
+   (org-level-2 :inherit 'org-level-1 :foreground orange)
+   (org-level-3 :bold bold :foreground violet)
+   (org-level-4 :inherit 'org-level-3)
+   (org-level-5 :inherit 'org-level-3)
+   (org-level-6 :inherit 'org-level-3)
+   (org-ellipsis :underline nil :background base2 :foreground orange)
+   (org-tag :foreground yellow :bold nil)
+   (org-quote :inherit 'italic :foreground base7 :background org-quote)
+   (org-todo :foreground yellow :bold 'inherit)
+   (org-list-dt :foreground yellow))
+
+
+  ;; --- extra variables --------------------
+  ;; ()
+  )
+
+;;; doom-molokai-theme.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-molokai-theme.elc b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-molokai-theme.elc
new file mode 100644
index 0000000000..cc113a35bd
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-molokai-theme.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-nord-light-theme.el b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-nord-light-theme.el
new file mode 100644
index 0000000000..5f312332cc
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-nord-light-theme.el
@@ -0,0 +1,189 @@
+;;; doom-nord-light-theme.el --- inspired by Nord
+(require 'doom-themes)
+
+;;
+(defgroup doom-nord-light-theme nil
+  "Options for doom-themes"
+  :group 'doom-themes)
+
+(defcustom doom-nord-light-brighter-modeline nil
+  "If non-nil, more vivid colors will be used to style the mode-line."
+  :group 'doom-nord-light-theme
+  :type 'boolean)
+
+(defcustom doom-nord-light-brighter-comments nil
+  "If non-nil, comments will be highlighted in more vivid colors."
+  :group 'doom-nord-light-theme
+  :type 'boolean)
+
+(defcustom doom-nord-light-comment-bg doom-nord-light-brighter-comments
+  "If non-nil, comments will have a subtle, darker background. Enhancing their
+legibility."
+  :group 'doom-nord-light-theme
+  :type 'boolean)
+
+(defcustom doom-nord-light-padded-modeline doom-themes-padded-modeline
+  "If non-nil, adds a 4px padding to the mode-line. Can be an integer to
+determine the exact padding."
+  :group 'doom-nord-light-theme
+  :type '(or integer boolean))
+
+(defcustom doom-nord-light-region-highlight t
+  "Determines the selection highlight style. Can be 'frost, 'snowstorm or t
+(default)."
+  :group 'doom-nord-light-theme
+  :type 'symbol)
+
+;;
+(def-doom-theme doom-nord-light
+  "A dark theme inspired by Nord-Light."
+
+  ;; name        default   256       16
+  ((bg '("#E5E9F0" nil nil))
+   (bg-alt '("#D8DEE9" nil nil))
+   (base0 '("#F0F4FC" "black" "black"))
+   (base1 '("#E3EAF5" "#1e1e1e" "brightblack"))
+   (base2 '("#D8DEE9" "#2e2e2e" "brightblack"))
+   (base3 '("#C2D0E7" "#262626" "brightblack"))
+   (base4 '("#B8C5DB" "#3f3f3f" "brightblack"))
+   (base5 '("#AEBACF" "#525252" "brightblack"))
+   (base6 '("#A1ACC0" "#6b6b6b" "brightblack"))
+   (base7 '("#60728C" "#979797" "brightblack"))
+   (base8 '("#485163" "#dfdfdf" "white"))
+   (fg '("#3B4252" "#2d2d2d" "white"))
+   (fg-alt '("#2E3440" "#bfbfbf" "brightwhite"))
+
+   (grey base4)
+   (red       '("#99324B" "#ff6655" "red"))
+   (orange    '("#AC4426" "#dd8844" "brightred"))
+   (green     '("#4F894C" "#99bb66" "green"))
+   (teal      '("#29838D" "#44b9b1" "brightgreen"))
+   (yellow    '("#9A7500" "#ECBE7B" "yellow"))
+   (blue      '("#3B6EA8" "#51afef" "brightblue"))
+   (dark-blue '("#5272AF" "#2257A0" "blue"))
+   (magenta   '("#97365B" "#c678dd" "magenta"))
+   (violet    '("#842879" "#a9a1e1" "brightmagenta"))
+   (cyan      '("#398EAC" "#46D9FF" "brightcyan"))
+   (dark-cyan '("#2C7088" "#5699AF" "cyan"))
+
+   ;; face categories -- required for all themes
+   (highlight (doom-blend blue bg 0.8))
+   (vertical-bar (doom-darken bg 0.15))
+   (selection (doom-blend blue bg 0.5))
+   (builtin teal)
+   (comments (if doom-nord-light-brighter-comments dark-cyan (doom-darken base5 0.2)))
+   (doc-comments (doom-darken (if doom-nord-light-brighter-comments dark-cyan base5) 0.25))
+   (constants magenta)
+   (functions teal)
+   (keywords blue)
+   (methods teal)
+   (operators blue)
+   (type yellow)
+   (strings green)
+   (variables violet)
+   (numbers magenta)
+   (region (pcase doom-nord-light-region-highlight
+             ((\` frost) (doom-lighten teal 0.5))
+             ((\` snowstorm) base0)
+             (_ base4)))
+   (error red)
+   (warning yellow)
+   (success green)
+   (vc-modified orange)
+   (vc-added green)
+   (vc-deleted red)
+
+   ;; custom categories
+   (hidden `(,(car bg) "black" "black"))
+   (-modeline-bright doom-nord-light-brighter-modeline)
+   (-modeline-pad
+    (when doom-nord-light-padded-modeline
+      (if (integerp doom-nord-light-padded-modeline) doom-nord-light-padded-modeline 4)))
+
+   (modeline-fg nil)
+   (modeline-fg-alt base6)
+
+   (modeline-bg
+    (if -modeline-bright
+        (doom-blend bg blue 0.7)
+      `(,(doom-darken (car bg) 0.03) ,@(cdr base0))))
+   (modeline-bg-l
+    (if -modeline-bright
+        (doom-blend bg blue 0.7)
+      `(,(doom-darken (car bg) 0.02) ,@(cdr base0))))
+   (modeline-bg-inactive (doom-darken bg 0.01))
+   (modeline-bg-inactive-l `(,(car bg) ,@(cdr base1))))
+
+
+  ;; --- extra faces ------------------------
+  (((region &override)
+    :foreground
+    (when (memq doom-nord-light-region-highlight '(frost snowstorm))
+      bg-alt))
+
+   ((lazy-highlight &override) :background (doom-blend teal bg 0.8))
+   ((line-number &override) :foreground (doom-lighten 'base5 0.2))
+   ((line-number-current-line &override) :foreground base7)
+   ((paren-face-match &override) :foreground red :background base3 :weight 'ultra-bold)
+   ((paren-face-mismatch &override) :foreground base3 :background red :weight 'ultra-bold)
+   ((vimish-fold-overlay &override) :inherit 'font-lock-comment-face :background base3 :weight 'light)
+   ((vimish-fold-fringe &override) :foreground teal)
+   (font-lock-comment-face
+    :foreground comments
+    :background (if doom-nord-light-comment-bg (doom-lighten bg 0.05)))
+   (font-lock-doc-face
+    :inherit 'font-lock-comment-face
+    :foreground doc-comments)
+
+   (doom-modeline-bar :background (if -modeline-bright modeline-bg highlight))
+
+   (mode-line
+    :background modeline-bg :foreground modeline-fg
+    :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))
+   (mode-line-inactive
+    :background modeline-bg-inactive :foreground modeline-fg-alt
+    :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive)))
+   (mode-line-emphasis
+    :foreground (if -modeline-bright base8 highlight))
+
+   (doom-modeline-project-root-dir :foreground base6)
+   (solaire-mode-line-face
+    :inherit 'mode-line
+    :background modeline-bg-l
+    :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-l)))
+   (solaire-mode-line-inactive-face
+    :inherit 'mode-line-inactive
+    :background modeline-bg-inactive-l
+    :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive-l)))
+
+   ;; elscreen
+   (elscreen-tab-other-screen-face :background "#353a42" :foreground "#1e2022")
+
+   (magit-diff-hunk-heading-highlight :foreground bg :background blue :weight 'bold)
+   (magit-diff-hunk-heading :foreground bg :background (doom-blend blue bg 0.3))
+   (ivy-posframe :background (doom-blend blue bg 0.2))
+   (ivy-virtual :foreground (doom-blend blue bg 0.8))
+   (ivy-minibuffer-match-face-1 :background nil :foreground (doom-blend fg bg 0.5) :weight 'light)
+   (internal-border :foreground (doom-blend blue bg 0.2) :background (doom-blend blue bg 0.2))
+   ;; --- major-mode faces -------------------
+   ;; css-mode / scss-mode
+   (css-proprietary-property :foreground orange)
+   (css-property :foreground green)
+   (css-selector :foreground blue)
+
+   ;; markdown-mode
+   (markdown-markup-face :foreground base5)
+   (markdown-header-face :inherit 'bold :foreground red)
+   (markdown-code-face :background (doom-lighten base3 0.05))
+
+   (nav-flash-face :background region :foreground base8 :weight 'bold)
+   ;; org-mode
+   (org-hide :foreground hidden)
+   (solaire-org-hide-face :foreground hidden))
+
+
+  ;; --- extra variables ---------------------
+  ;; ()
+  )
+
+;;; doom-nord-light-theme.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-nord-light-theme.elc b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-nord-light-theme.elc
new file mode 100644
index 0000000000..a31910ab72
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-nord-light-theme.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-nord-theme.el b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-nord-theme.el
new file mode 100644
index 0000000000..02f6e444f9
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-nord-theme.el
@@ -0,0 +1,190 @@
+;;; doom-nord-theme.el --- inspired by Nord
+(require 'doom-themes)
+
+;;
+(defgroup doom-nord-theme nil
+  "Options for doom-themes"
+  :group 'doom-themes)
+
+(defcustom doom-nord-brighter-modeline nil
+  "If non-nil, more vivid colors will be used to style the mode-line."
+  :group 'doom-nord-theme
+  :type 'boolean)
+
+(defcustom doom-nord-brighter-comments nil
+  "If non-nil, comments will be highlighted in more vivid colors."
+  :group 'doom-nord-theme
+  :type 'boolean)
+
+(defcustom doom-nord-comment-bg doom-nord-brighter-comments
+  "If non-nil, comments will have a subtle, darker background. Enhancing their
+legibility."
+  :group 'doom-nord-theme
+  :type 'boolean)
+
+(defcustom doom-nord-padded-modeline doom-themes-padded-modeline
+  "If non-nil, adds a 4px padding to the mode-line. Can be an integer to
+determine the exact padding."
+  :group 'doom-nord-theme
+  :type '(or integer boolean))
+
+(eval-and-compile
+  (defcustom doom-nord-region-highlight t
+    "Determines the selection highlight style. Can be 'frost, 'snowstorm or t
+(default)."
+    :group 'doom-nord-theme
+    :type 'symbol))
+
+;;
+(def-doom-theme doom-nord
+  "A dark theme inspired by Nord."
+
+  ;; name        default   256       16
+  ((bg         '("#3B4252" nil       nil            ))
+   (bg-alt     '("#2E3440" nil       nil            ))
+   (base0      '("#191C25" "black"   "black"        ))
+   (base1      '("#242832" "#1e1e1e" "brightblack"  ))
+   (base2      '("#2C333F" "#2e2e2e" "brightblack"  ))
+   (base3      '("#373E4C" "#262626" "brightblack"  ))
+   (base4      '("#434C5E" "#3f3f3f" "brightblack"  ))
+   (base5      '("#4C566A" "#525252" "brightblack"  ))
+   (base6      '("#9099AB" "#6b6b6b" "brightblack"  ))
+   (base7      '("#D8DEE9" "#979797" "brightblack"  ))
+   (base8      '("#F0F4FC" "#dfdfdf" "white"        ))
+   (fg         '("#ECEFF4" "#2d2d2d" "white"        ))
+   (fg-alt     '("#E5E9F0" "#bfbfbf" "brightwhite"  ))
+
+   (grey       base4)
+   (red        '("#C16069" "#ff6655" "red"          ))
+   (orange     '("#D2876D" "#dd8844" "brightred"    ))
+   (green      '("#A2BF8A" "#99bb66" "green"        ))
+   (teal       '("#8EBCBB" "#44b9b1" "brightgreen"  ))
+   (yellow     '("#ECCC87" "#ECBE7B" "yellow"       ))
+   (blue       '("#80A0C2" "#51afef" "brightblue"   ))
+   (dark-blue  '("#5C748E" "#2257A0" "blue"         ))
+   (magenta    '("#B58DAE" "#c678dd" "magenta"      ))
+   (violet     '("#5D80AE" "#a9a1e1" "brightmagenta"))
+   (cyan       '("#86C0D1" "#46D9FF" "brightcyan"   ))
+   (dark-cyan  '("#507681" "#5699AF" "cyan"         ))
+
+   ;; face categories -- required for all themes
+   (highlight      blue)
+   (vertical-bar   (doom-darken base1 0.2))
+   (selection      dark-blue)
+   (builtin        teal)
+   (comments       (if doom-nord-brighter-comments dark-cyan (doom-lighten base5 0.2)))
+   (doc-comments   (doom-lighten (if doom-nord-brighter-comments dark-cyan base5) 0.25))
+   (constants      magenta)
+   (functions      teal)
+   (keywords       blue)
+   (methods        teal)
+   (operators      blue)
+   (type           yellow)
+   (strings        green)
+   (variables      (doom-lighten magenta 0.5))
+   (numbers        magenta)
+   (region         (pcase doom-nord-region-highlight
+                     (`frost teal)
+                     (`snowstorm base7)
+                     (_ base4)))
+   (error          red)
+   (warning        yellow)
+   (success        green)
+   (vc-modified    orange)
+   (vc-added       green)
+   (vc-deleted     red)
+
+   ;; custom categories
+   (hidden     `(,(car bg) "black" "black"))
+   (-modeline-bright doom-nord-brighter-modeline)
+   (-modeline-pad
+    (when doom-nord-padded-modeline
+      (if (integerp doom-nord-padded-modeline) doom-nord-padded-modeline 4)))
+
+   (region-fg
+    (when (memq doom-nord-region-highlight '(frost snowstorm))
+      bg-alt))
+
+   (modeline-fg     nil)
+   (modeline-fg-alt base6)
+
+   (modeline-bg
+    (if -modeline-bright
+        (doom-blend bg base5 0.2)
+      `(,(doom-darken (car bg) 0.15) ,@(cdr base0))))
+   (modeline-bg-l
+    (if -modeline-bright
+        (doom-blend bg base5 0.2)
+      `(,(doom-darken (car bg) 0.1) ,@(cdr base0))))
+   (modeline-bg-inactive   (doom-darken bg 0.1))
+   (modeline-bg-inactive-l `(,(car bg) ,@(cdr base1))))
+
+
+  ;; --- extra faces ------------------------
+  (((region &override) :foreground region-fg)
+
+   ((line-number &override) :foreground (doom-lighten 'base5 0.2))
+   ((line-number-current-line &override) :foreground base7)
+   ((paren-face-match &override) :foreground red :background base3 :weight 'ultra-bold)
+   ((paren-face-mismatch &override) :foreground base3 :background red :weight 'ultra-bold)
+   ((vimish-fold-overlay &override) :inherit 'font-lock-comment-face :background base3 :weight 'light)
+   ((vimish-fold-fringe &override)  :foreground teal)
+
+   (font-lock-comment-face
+    :foreground comments
+    :background (if doom-nord-comment-bg (doom-lighten bg 0.05)))
+   (font-lock-doc-face
+    :inherit 'font-lock-comment-face
+    :foreground doc-comments)
+
+   (doom-modeline-bar :background (if -modeline-bright modeline-bg highlight))
+
+   (mode-line
+    :background modeline-bg :foreground modeline-fg
+    :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))
+   (mode-line-inactive
+    :background modeline-bg-inactive :foreground modeline-fg-alt
+    :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive)))
+   (mode-line-emphasis
+    :foreground (if -modeline-bright base8 highlight))
+
+   (doom-modeline-project-root-dir :foreground base6)
+   (solaire-mode-line-face
+    :inherit 'mode-line
+    :background modeline-bg-l
+    :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-l)))
+   (solaire-mode-line-inactive-face
+    :inherit 'mode-line-inactive
+    :background modeline-bg-inactive-l
+    :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive-l)))
+
+   ;; ediff
+   (ediff-fine-diff-A    :background (doom-darken violet 0.4) :weight 'bold)
+   (ediff-current-diff-A :background (doom-darken base0 0.25))
+
+   ;; elscreen
+   (elscreen-tab-other-screen-face :background "#353a42" :foreground "#1e2022")
+
+   ;; --- major-mode faces -------------------
+   ;; css-mode / scss-mode
+   (css-proprietary-property :foreground orange)
+   (css-property             :foreground green)
+   (css-selector             :foreground blue)
+
+   ;; markdown-mode
+   (markdown-markup-face :foreground base5)
+   (markdown-header-face :inherit 'bold :foreground red)
+   (markdown-code-face :background (doom-lighten base3 0.05))
+
+   ;; org-mode
+   (org-hide :foreground hidden)
+   (solaire-org-hide-face :foreground hidden))
+
+
+  ;; --- extra variables ---------------------
+  ;; ()
+
+
+  )
+
+;;; doom-nord-theme.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-nord-theme.elc b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-nord-theme.elc
new file mode 100644
index 0000000000..bf2c0a6daa
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-nord-theme.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-nova-theme.el b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-nova-theme.el
new file mode 100644
index 0000000000..12bc33e63c
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-nova-theme.el
@@ -0,0 +1,160 @@
+;;; doom-nova-theme.el --- inspired by Trevord Miller's Nova
+(require 'doom-themes)
+
+(defgroup doom-nova-theme nil
+  "Options for doom-themes"
+  :group 'doom-themes)
+
+(defcustom doom-nova-padded-modeline doom-themes-padded-modeline
+  "If non-nil, adds a 4px padding to the mode-line. Can be an integer to
+determine the exact padding."
+  :group 'doom-nova-theme
+  :type '(or integer boolean))
+
+(def-doom-theme doom-nova
+  "A light theme inspired by Trevord Miller's Nova. See
+<https://trevordmiller.com/projects/nova>."
+
+  ;; name      gui
+  ((bg         '("#3c4c55" nil       nil))
+   (bg-alt     '("#44545d" "#445566" "black"))
+
+   ;; FIXME Tweak these
+   (base0      '("#0d0f11" "#0d0f11" "black"      )) ; FIXME black
+   (base1      '("#1e272c" "#1b1b1b"              ))
+   (base2      '("#212122" "#1e1e1e"              )) ;
+   (base3      '("#2f3f48" "#292929" "brightblack")) ;
+   (base4      '("#3c4c55" "#3f3f3f" "brightblack")) ;
+   (base5      '("#556873" "#525252" "brightblack"))
+   (base6      '("#6A7D89" "#6b6b6b" "brightblack"))
+   (base7      '("#899BA6" "#878797" "brightblack"))
+   (base8      '("#e6eef3" "#efefef" "brightwhite")) ; FIXME white
+   (fg         '("#c5c8c6" "#c5c6c6" "white"      )) ;; TODO set correct color
+   (fg-alt     (doom-darken fg 0.6)) ;; TODO set correct color
+
+   (light-grey "#E6EEF3")
+   (grey       base7)
+   (dark-grey  base3)
+
+   (red        "#DF8C8C")
+   (orange     "#F2C38F")
+   (yellow     "#DADA93")
+   (green      "#A8CE93")
+   (blue       "#83AFE5")
+   (dark-blue  (doom-darken blue 0.7))
+   (teal       blue)
+   (magenta    (doom-lighten "#b294bb" 0.3)) ; FIXME TODO set correct color
+   (violet     "#9A93E1")
+   (cyan       "#7FC1CA")
+   (dark-cyan  (doom-darken cyan 0.4))
+
+   ;; face categories
+   (highlight      cyan)
+   (vertical-bar   (doom-lighten bg 0.1))
+   (selection      highlight)
+   (builtin        blue)
+   (comments       grey)
+   (doc-comments   (doom-lighten grey 0.1))
+   (constants      highlight)
+   (functions      blue)
+   (keywords       violet)
+   (methods        blue)
+   (operators      green)
+   (type           green)
+   (strings        cyan)
+   (variables      red)
+   (numbers        highlight)
+   (region         selection)
+   (error          red)
+   (warning        yellow)
+   (success        green)
+   (vc-modified    violet)
+   (vc-added       green)
+   (vc-deleted     red)
+
+   ;; custom categories
+   (current-line    base5) ; (doom-lighten bg-alt 0.04)
+   (modeline-fg     blue)
+   (modeline-bg     base5) ; bg-alt
+   (modeline-fg-alt (doom-lighten bg-alt 0.4))
+   (modeline-bg-alt base4)
+
+   (-modeline-pad
+    (when doom-nova-padded-modeline
+      (if (integerp doom-nova-padded-modeline)
+          doom-nova-padded-modeline
+        4))))
+
+  ;; --- faces ------------------------------
+  ((doom-modeline-buffer-path       :foreground violet :bold nil)
+   (doom-modeline-buffer-major-mode :inherit 'doom-modeline-buffer-path)
+   (doom-modeline-bar :inherit 'mode-line-highlight)
+
+   (fringe :inherit 'default :foreground "#6c808d")
+   (region :background (doom-lighten current-line 0.1) :foreground nil :distant-foreground nil :weight 'bold)
+
+   ((line-number &override) :foreground "#6c808d")
+   ((line-number-current-line &override) :foreground highlight :weight 'bold)
+
+   ;; rainbow-delimiters
+   (rainbow-delimiters-depth-1-face :foreground violet)
+   (rainbow-delimiters-depth-2-face :foreground blue)
+   (rainbow-delimiters-depth-3-face :foreground orange)
+   (rainbow-delimiters-depth-4-face :foreground green)
+   (rainbow-delimiters-depth-5-face :foreground magenta)
+   (rainbow-delimiters-depth-6-face :foreground yellow)
+   (rainbow-delimiters-depth-7-face :foreground teal)
+
+   (hl-line :background current-line)
+   (solaire-hl-line-face :inherit 'hl-line)
+
+   (mode-line
+    :background modeline-bg :foreground modeline-fg
+    :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))
+   (mode-line-inactive
+    :background modeline-bg-alt :foreground modeline-fg-alt
+    :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-alt)))
+
+   (solaire-mode-line-face
+    :background modeline-bg :foreground modeline-fg
+    :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))
+   (solaire-mode-line-inactive-face
+    :background modeline-bg-alt :foreground modeline-fg-alt
+    :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-alt)))
+
+   ;; helm
+   (helm-selection :background current-line :weight 'bold)
+   (helm-match     :foreground highlight)
+   (helm-source-header :foreground base0 :background base6)
+
+   ;; ivy
+   (ivy-current-match :background current-line :distant-foreground base0)
+
+   ;; company
+   (company-tooltip            :inherit 'tooltip :background (doom-lighten bg 0.075))
+   (company-tooltip-selection  :background base5 :foreground base8 :weight 'bold)
+   (company-tooltip-common     :foreground cyan :distant-foreground cyan :weight 'bold)
+   (company-tooltip-search     :background highlight :foreground base1 :weight 'ultra-bold)
+   (company-tooltip-search-selection :background highlight :foreground base1 :weight 'ultra-bold)
+   (company-tooltip-mouse      :background base6 :foreground bg :distant-foreground fg)
+
+   ;; ediff
+   (ediff-fine-diff-A    :background base3 :weight 'bold)
+   (ediff-current-diff-A :inherit 'hl-line)
+   (ediff-even-diff-A    :background base3)
+
+   ;; show-paren
+   ((paren-face-match &override)    :foreground red :background (doom-darken violet 0.4))
+   ((paren-face-mismatch &override) :foreground (doom-darken red 0.4) :background cyan)
+
+   ;; org-mode
+   (org-level-1
+    :foreground blue :background (doom-darken bg 0.025)
+    :bold bold :height 1.2))
+
+  ;; --- variables --------------------------
+  ;; ()
+  )
+
+(provide 'doom-nova-theme)
+;;; doom-nova-theme.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-nova-theme.elc b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-nova-theme.elc
new file mode 100644
index 0000000000..a7b8900c3d
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-nova-theme.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-one-light-theme.el b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-one-light-theme.el
new file mode 100644
index 0000000000..45ee075bf0
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-one-light-theme.el
@@ -0,0 +1,199 @@
+;;; doom-one-light-theme.el --- inspired by Atom One Light
+(require 'doom-themes)
+
+;;
+(defgroup doom-one-light-theme nil
+  "Options for doom-themes"
+  :group 'doom-themes)
+
+(defcustom doom-one-light-brighter-modeline nil
+  "If non-nil, more vivid colors will be used to style the mode-line."
+  :group 'doom-one-light-theme
+  :type 'boolean)
+
+(defcustom doom-one-light-brighter-comments nil
+  "If non-nil, comments will be highlighted in more vivid colors."
+  :group 'doom-one-light-theme
+  :type 'boolean)
+
+(defcustom doom-one-light-comment-bg doom-one-light-brighter-comments
+  "If non-nil, comments will have a subtle, darker background. Enhancing their
+legibility."
+  :group 'doom-one-light-theme
+  :type 'boolean)
+
+(defcustom doom-one-light-padded-modeline doom-themes-padded-modeline
+  "If non-nil, adds a 4px padding to the mode-line. Can be an integer to
+determine the exact padding."
+  :group 'doom-one-light-theme
+  :type '(or integer boolean))
+
+;;
+(def-doom-theme doom-one-light
+  "A light theme inspired by Atom One"
+
+  ;; name        default   256       16
+  ((bg         '("#fafafa" nil       nil            ))
+   (bg-alt     '("#f0f0f0" nil       nil            ))
+   (base0      '("#f0f0f0" "#f0f0f0" "white"        ))
+   (base1      '("#e7e7e7" "#e7e7e7" "brightblack"  ))
+   (base2      '("#dfdfdf" "#dfdfdf" "brightblack"  ))
+   (base3      '("#c6c7c7" "#c6c7c7" "brightblack"  ))
+   (base4      '("#9ca0a4" "#9ca0a4" "brightblack"  ))
+   (base5      '("#383a42" "#424242" "brightblack"  ))
+   (base6      '("#202328" "#2e2e2e" "brightblack"  ))
+   (base7      '("#1c1f24" "#1e1e1e" "brightblack"  ))
+   (base8      '("#1b2229" "black"   "black"        ))
+   (fg         '("#383a42" "#424242" "black"        ))
+   (fg-alt     '("#c6c7c7" "#c7c7c7" "brightblack"  ))
+
+   (grey       base4)
+   (red        '("#e45649" "#e45649" "red"          ))
+   (orange     '("#da8548" "#dd8844" "brightred"    ))
+   (green      '("#50a14f" "#50a14f" "green"        ))
+   (teal       '("#4db5bd" "#44b9b1" "brightgreen"  ))
+   (yellow     '("#986801" "#986801" "yellow"       ))
+   (blue       '("#4078f2" "#4078f2" "brightblue"   ))
+   (dark-blue  '("#a0bcf8" "#a0bcf8" "blue"         ))
+   (magenta    '("#a626a4" "#a626a4" "magenta"      ))
+   (violet     '("#b751b6" "#b751b6" "brightmagenta"))
+   (cyan       '("#0184bc" "#0184bc" "brightcyan"   ))
+   (dark-cyan  '("#005478" "#005478" "cyan"         ))
+
+   ;; face categories -- required for all themes
+   (highlight      blue)
+   (vertical-bar   (doom-darken base2 0.1))
+   (selection      dark-blue)
+   (builtin        magenta)
+   (comments       (if doom-one-light-brighter-comments cyan base4))
+   (doc-comments   (doom-darken comments 0.15))
+   (constants      violet)
+   (functions      magenta)
+   (keywords       red)
+   (methods        cyan)
+   (operators      blue)
+   (type           yellow)
+   (strings        green)
+   (variables      (doom-darken magenta 0.36))
+   (numbers        orange)
+   (region         `(,(doom-darken (car bg-alt) 0.1) ,@(doom-darken (cdr base0) 0.3)))
+   (error          red)
+   (warning        yellow)
+   (success        green)
+   (vc-modified    orange)
+   (vc-added       green)
+   (vc-deleted     red)
+
+   ;; custom categories
+   (-modeline-bright doom-one-light-brighter-modeline)
+   (-modeline-pad
+    (when doom-one-light-padded-modeline
+      (if (integerp doom-one-light-padded-modeline) doom-one-light-padded-modeline 4)))
+
+   (modeline-fg     nil)
+   (modeline-fg-alt (doom-blend violet base4 (if -modeline-bright 0.5 0.2)))
+
+   (modeline-bg
+    (if -modeline-bright
+        (doom-darken base2 0.05)
+      base1))
+   (modeline-bg-l
+    (if -modeline-bright
+        (doom-darken base2 0.1)
+      base2))
+   (modeline-bg-inactive (doom-darken bg 0.1))
+   (modeline-bg-inactive-l `(,(doom-darken (car bg-alt) 0.05) ,@(cdr base1))))
+
+  ;; --- extra faces ------------------------
+  ((font-lock-comment-face
+    :foreground comments
+    :background (if doom-one-light-comment-bg base0))
+   (font-lock-doc-face
+    :inherit 'font-lock-comment-face
+    :foreground doc-comments
+    :slant 'italic)
+
+   ((line-number &override) :foreground (doom-lighten base4 0.15))
+   ((line-number-current-line &override) :foreground base8)
+
+   (solaire-hl-line-face :inherit 'hl-line :background base0)
+
+   (doom-modeline-bar :background (if -modeline-bright modeline-bg highlight))
+
+   (mode-line
+    :background modeline-bg :foreground modeline-fg
+    :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))
+   (mode-line-inactive
+    :background modeline-bg-inactive :foreground modeline-fg-alt
+    :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive)))
+   (mode-line-emphasis
+    :foreground (if -modeline-bright base8 highlight))
+
+   (solaire-mode-line-face
+    :inherit 'mode-line
+    :background modeline-bg-l
+    :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-l)))
+   (solaire-mode-line-inactive-face
+    :inherit 'mode-line-inactive
+    :background modeline-bg-inactive-l
+    :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive-l)))
+
+   ;; magit
+   (magit-blame-heading     :foreground orange :background bg-alt)
+   (magit-diff-removed :foreground (doom-darken red 0.2) :background (doom-blend red bg 0.1))
+   (magit-diff-removed-highlight :foreground red :background (doom-blend red bg 0.2) :bold bold)
+
+   ;; --- major-mode faces -------------------
+   ;; css-mode / scss-mode
+   (css-proprietary-property :foreground orange)
+   (css-property             :foreground green)
+   (css-selector             :foreground blue)
+
+   ;; markdown-mode
+   (markdown-markup-face     :foreground base5)
+   (markdown-header-face     :inherit 'bold :foreground red)
+   (markdown-code-face       :background base1)
+   (mmm-default-submode-face :background base1)
+
+   ;; org-mode
+   (org-block            :background base1)
+   (org-block-begin-line :foreground fg :slant 'italic)
+   (org-level-1          :foreground red    :weight 'ultra-bold :height 1.2)
+   (org-level-2          :foreground orange :weight 'extra-bold :height 1.1)
+   (org-level-3          :foreground violet :bold bold          :height 1.1)
+   (org-ellipsis         :underline nil :background bg     :foreground red)
+   (org-quote            :background base1)
+
+   ;; helm
+   (helm-candidate-number :background blue :foreground bg)
+
+   ;; web-mode
+   (web-mode-current-element-highlight-face :background dark-blue :foreground bg)
+
+   ;; wgrep
+   (wgrep-face :background base1)
+
+   ;; ediff
+   (ediff-current-diff-A        :foreground red   :background (doom-lighten red 0.8))
+   (ediff-current-diff-B        :foreground green :background (doom-lighten green 0.8))
+   (ediff-current-diff-C        :foreground blue  :background (doom-lighten blue 0.8))
+   (ediff-current-diff-Ancestor :foreground teal  :background (doom-lighten teal 0.8))
+
+   ;; tooltip
+   (tooltip :background base1 :foreground fg)
+
+   ;; posframe
+   (ivy-posframe               :background base0)
+
+   ;; lsp
+   (lsp-ui-doc-background      :background base0)
+   (lsp-face-highlight-read    :background (doom-blend red bg 0.3))
+   (lsp-face-highlight-textual :inherit 'lsp-face-highlight-read)
+   (lsp-face-highlight-write   :inherit 'lsp-face-highlight-read)
+   )
+
+  ;; --- extra variables ---------------------
+  ;; ()
+  )
+
+;;; doom-one-light-theme.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-one-light-theme.elc b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-one-light-theme.elc
new file mode 100644
index 0000000000..beadaff077
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-one-light-theme.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-one-theme.el b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-one-theme.el
new file mode 100644
index 0000000000..945cb2aaa8
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-one-theme.el
@@ -0,0 +1,167 @@
+;;; doom-one-theme.el --- inspired by Atom One Dark
+(require 'doom-themes)
+
+;;
+(defgroup doom-one-theme nil
+  "Options for doom-themes"
+  :group 'doom-themes)
+
+(defcustom doom-one-brighter-modeline nil
+  "If non-nil, more vivid colors will be used to style the mode-line."
+  :group 'doom-one-theme
+  :type 'boolean)
+
+(defcustom doom-one-brighter-comments nil
+  "If non-nil, comments will be highlighted in more vivid colors."
+  :group 'doom-one-theme
+  :type 'boolean)
+
+(defcustom doom-one-comment-bg doom-one-brighter-comments
+  "If non-nil, comments will have a subtle, darker background. Enhancing their
+legibility."
+  :group 'doom-one-theme
+  :type 'boolean)
+
+(defcustom doom-one-padded-modeline doom-themes-padded-modeline
+  "If non-nil, adds a 4px padding to the mode-line. Can be an integer to
+determine the exact padding."
+  :group 'doom-one-theme
+  :type '(or integer boolean))
+
+;;
+(def-doom-theme doom-one
+  "A dark theme inspired by Atom One Dark"
+
+  ;; name        default   256       16
+  ((bg         '("#282c34" nil       nil            ))
+   (bg-alt     '("#21242b" nil       nil            ))
+   (base0      '("#1B2229" "black"   "black"        ))
+   (base1      '("#1c1f24" "#1e1e1e" "brightblack"  ))
+   (base2      '("#202328" "#2e2e2e" "brightblack"  ))
+   (base3      '("#23272e" "#262626" "brightblack"  ))
+   (base4      '("#3f444a" "#3f3f3f" "brightblack"  ))
+   (base5      '("#5B6268" "#525252" "brightblack"  ))
+   (base6      '("#73797e" "#6b6b6b" "brightblack"  ))
+   (base7      '("#9ca0a4" "#979797" "brightblack"  ))
+   (base8      '("#DFDFDF" "#dfdfdf" "white"        ))
+   (fg         '("#bbc2cf" "#bfbfbf" "brightwhite"  ))
+   (fg-alt     '("#5B6268" "#2d2d2d" "white"        ))
+
+   (grey       base4)
+   (red        '("#ff6c6b" "#ff6655" "red"          ))
+   (orange     '("#da8548" "#dd8844" "brightred"    ))
+   (green      '("#98be65" "#99bb66" "green"        ))
+   (teal       '("#4db5bd" "#44b9b1" "brightgreen"  ))
+   (yellow     '("#ECBE7B" "#ECBE7B" "yellow"       ))
+   (blue       '("#51afef" "#51afef" "brightblue"   ))
+   (dark-blue  '("#2257A0" "#2257A0" "blue"         ))
+   (magenta    '("#c678dd" "#c678dd" "magenta"      ))
+   (violet     '("#a9a1e1" "#a9a1e1" "brightmagenta"))
+   (cyan       '("#46D9FF" "#46D9FF" "brightcyan"   ))
+   (dark-cyan  '("#5699AF" "#5699AF" "cyan"         ))
+
+   ;; face categories -- required for all themes
+   (highlight      blue)
+   (vertical-bar   (doom-darken base1 0.1))
+   (selection      dark-blue)
+   (builtin        magenta)
+   (comments       (if doom-one-brighter-comments dark-cyan base5))
+   (doc-comments   (doom-lighten (if doom-one-brighter-comments dark-cyan base5) 0.25))
+   (constants      violet)
+   (functions      magenta)
+   (keywords       blue)
+   (methods        cyan)
+   (operators      blue)
+   (type           yellow)
+   (strings        green)
+   (variables      (doom-lighten magenta 0.4))
+   (numbers        orange)
+   (region         `(,(doom-lighten (car bg-alt) 0.15) ,@(doom-lighten (cdr base0) 0.35)))
+   (error          red)
+   (warning        yellow)
+   (success        green)
+   (vc-modified    orange)
+   (vc-added       green)
+   (vc-deleted     red)
+
+   ;; custom categories
+   (hidden     `(,(car bg) "black" "black"))
+   (-modeline-bright doom-one-brighter-modeline)
+   (-modeline-pad
+    (when doom-one-padded-modeline
+      (if (integerp doom-one-padded-modeline) doom-one-padded-modeline 4)))
+
+   (modeline-fg     nil)
+   (modeline-fg-alt base5)
+
+   (modeline-bg
+    (if -modeline-bright
+        (doom-darken blue 0.475)
+      `(,(doom-darken (car bg-alt) 0.15) ,@(cdr base0))))
+   (modeline-bg-l
+    (if -modeline-bright
+        (doom-darken blue 0.45)
+      `(,(doom-darken (car bg-alt) 0.1) ,@(cdr base0))))
+   (modeline-bg-inactive   (doom-darken bg-alt 0.1))
+   (modeline-bg-inactive-l `(,(car bg-alt) ,@(cdr base1))))
+
+
+  ;; --- extra faces ------------------------
+  ((elscreen-tab-other-screen-face :background "#353a42" :foreground "#1e2022")
+
+   (evil-goggles-default-face :inherit 'region :background (doom-blend region bg 0.5))
+
+   ((line-number &override) :foreground base4)
+   ((line-number-current-line &override) :foreground fg)
+
+   (font-lock-comment-face
+    :foreground comments
+    :background (if doom-one-comment-bg (doom-lighten bg 0.05)))
+   (font-lock-doc-face
+    :inherit 'font-lock-comment-face
+    :foreground doc-comments)
+
+   (doom-modeline-bar :background (if -modeline-bright modeline-bg highlight))
+
+   (mode-line
+    :background modeline-bg :foreground modeline-fg
+    :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))
+   (mode-line-inactive
+    :background modeline-bg-inactive :foreground modeline-fg-alt
+    :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive)))
+   (mode-line-emphasis
+    :foreground (if -modeline-bright base8 highlight))
+
+   (solaire-mode-line-face
+    :inherit 'mode-line
+    :background modeline-bg-l
+    :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-l)))
+   (solaire-mode-line-inactive-face
+    :inherit 'mode-line-inactive
+    :background modeline-bg-inactive-l
+    :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive-l)))
+
+   ;; ivy-mode
+   (ivy-current-match :background dark-blue :distant-foreground base0 :weight 'normal)
+
+   ;; --- major-mode faces -------------------
+   ;; css-mode / scss-mode
+   (css-proprietary-property :foreground orange)
+   (css-property             :foreground green)
+   (css-selector             :foreground blue)
+
+   ;; markdown-mode
+   (markdown-markup-face :foreground base5)
+   (markdown-header-face :inherit 'bold :foreground red)
+   (markdown-code-face :background (doom-lighten base3 0.05))
+
+   ;; org-mode
+   (org-hide :foreground hidden)
+   (solaire-org-hide-face :foreground hidden))
+
+
+  ;; --- extra variables ---------------------
+  ;; ()
+  )
+
+;;; doom-one-theme.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-one-theme.elc b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-one-theme.elc
new file mode 100644
index 0000000000..4a248434da
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-one-theme.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-opera-light-theme.el b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-opera-light-theme.el
new file mode 100644
index 0000000000..6f28c9a3e7
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-opera-light-theme.el
@@ -0,0 +1,145 @@
+;;; doom-opera-light-theme.el --- Opera-Light theme
+
+(require 'doom-themes)
+
+(defgroup doom-opera-light-theme nil
+  "Options for doom-themes"
+  :group 'doom-themes)
+
+(defcustom doom-opera-light-brighter-modeline nil
+  "If non-nil, more vivid colors will be used to style the mode-line."
+  :group 'doom-opera-light-theme
+  :type 'boolean)
+
+(defcustom doom-opera-light-brighter-comments nil
+  "If non-nil, comments will be highlighted in more vivid colors."
+  :group 'doom-opera-light-theme
+  :type 'boolean)
+
+(defcustom doom-opera-light-comment-bg doom-opera-light-brighter-comments
+  "If non-nil, comments will have a subtle, darker background. Enhancing their
+legibility."
+  :group 'doom-opera-light-theme
+  :type 'boolean)
+
+(defcustom doom-opera-light-padded-modeline doom-themes-padded-modeline
+  "If non-nil, adds a 4px padding to the mode-line. Can be an integer to
+determine the exact padding."
+  :group 'doom-opera-light-theme
+  :type '(or integer boolean))
+
+(defcustom doom-opera-light-region-highlight t
+  "Determines the selection highlight style. Can be 'frost, 'snowstorm or t
+(default)."
+  :group 'doom-opera-light-theme
+  :type 'symbol)
+
+(def-doom-theme doom-opera-light
+  "A dark opera-light theme."
+
+  ;; name        default   256       16
+  ((bg         '("#fafafa" nil       nil ))
+   (bg-alt     '("#eeeeee" nil       nil ))
+   (base0      '("#fafafa" "#dfdfdf" nil ))
+   (base1      '("#f5f5f5" "#979797" nil ))
+   (base2      '("#eeeeee" "#6b6b6b" nil ))
+   (base3      '("#e0e0e0" "#525252" nil ))
+   (base4      '("#bdbdbd" "#3f3f3f" nil ))
+   (base5      '("#9e9e9e" "#262626" nil ))
+   (base6      '("#757575" "#2e2e2e" nil ))
+   (base7      '("#616161" "#1e1e1e" nil ))
+   (base8      '("#424242" "black"   nil ))
+   (fg         '("#2a2a2a" "#2a2a2a" nil ))
+   (fg-alt     '("#454545" "#757575" nil ))
+
+   (grey       base4)
+   (red        '("#99324b" "#ff6655" nil ))
+   (orange     '("#ac4426" "#dd8844" nil ))
+   (green      '("#4f894c" "#99bb66" nil ))
+   (teal       '("#29838d" "#44b9b1" nil ))
+   (yellow     '("#9a7500" "#ECBE7B" nil ))
+   (blue       '("#3b6ea8" "#51afef" nil ))
+   (dark-blue  '("#5272AF" "#2257A0" nil ))
+   (magenta    '("#97365b" "#c678dd" nil ))
+   (violet     '("#842879" "#a9a1e1" nil ))
+   (cyan       '("#398eac" "#46D9FF" nil ))
+   (dark-cyan  '("#2c7088" "#5699AF" nil ))
+
+   ;; face categories -- required for all themes
+   (highlight      blue)
+   (vertical-bar   (doom-darken base1 0.2))
+   (selection      dark-blue)
+   (builtin        teal)
+   (comments       (if doom-opera-light-brighter-comments dark-cyan (doom-lighten base5 0.2)))
+   (doc-comments   (doom-lighten (if doom-opera-light-brighter-comments dark-cyan base5) 0.25))
+   (constants      magenta)
+   (functions      teal)
+   (keywords       blue)
+   (methods        teal)
+   (operators      blue)
+   (type           yellow)
+   (strings        green)
+   (variables      (doom-lighten magenta 0.5))
+   (numbers        magenta)
+   (region         base4)
+   (error          red)
+   (warning        yellow)
+   (success        green)
+   (vc-modified    orange)
+   (vc-added       green)
+   (vc-deleted     red)
+
+   ;; custom categories
+   (hidden     `(,(car bg) "black" "black"))
+   (-modeline-bright doom-opera-light-brighter-modeline)
+   (-modeline-pad
+    (when doom-opera-light-padded-modeline
+      (if (integerp doom-opera-light-padded-modeline) doom-opera-light-padded-modeline 4)))
+
+   (modeline-fg     nil)
+   (modeline-fg-alt base5)
+
+   (modeline-bg
+    (if -modeline-bright
+        (doom-darken blue 0.475)
+      `(,(doom-darken (car bg-alt) 0.15) ,@(cdr base0))))
+   (modeline-bg-l
+    (if -modeline-bright
+        (doom-darken blue 0.45)
+      `(,(doom-darken (car bg-alt) 0.1) ,@(cdr base0))))
+   (modeline-bg-inactive   (doom-darken bg-alt 0.1))
+   (modeline-bg-inactive-l `(,(car bg-alt) ,@(cdr base1))))
+
+  ;; --- extra faces ------------------------
+  (
+   ((line-number &override) :foreground fg-alt)
+   ((line-number-current-line &override) :foreground fg)
+
+   (font-lock-comment-face
+    :foreground comments
+    :background (if doom-opera-light-comment-bg (doom-lighten bg 0.05)))
+   (font-lock-doc-face
+    :inherit 'font-lock-comment-face
+    :foreground doc-comments)
+
+   (doom-modeline-bar :background (if -modeline-bright modeline-bg highlight))
+
+   (mode-line
+    :background modeline-bg :foreground modeline-fg
+    :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))
+   (mode-line-inactive
+    :background modeline-bg-inactive :foreground modeline-fg-alt
+    :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive)))
+   (mode-line-emphasis
+    :foreground (if -modeline-bright base8 highlight))
+
+   (solaire-mode-line-face
+    :inherit 'mode-line
+    :background modeline-bg-l
+    :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-l)))
+   (solaire-mode-line-inactive-face
+    :inherit 'mode-line-inactive
+    :background modeline-bg-inactive-l
+    :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive-l)))))
+
+;;; doom-opera-light-theme.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-opera-light-theme.elc b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-opera-light-theme.elc
new file mode 100644
index 0000000000..1242a65cd4
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-opera-light-theme.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-opera-theme.el b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-opera-theme.el
new file mode 100644
index 0000000000..8f852bc462
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-opera-theme.el
@@ -0,0 +1,145 @@
+;;; doom-opera-theme.el --- Opera theme
+
+(require 'doom-themes)
+
+(defgroup doom-opera-theme nil
+  "Options for doom-themes"
+  :group 'doom-themes)
+
+(defcustom doom-opera-brighter-modeline nil
+  "If non-nil, more vivid colors will be used to style the mode-line."
+  :group 'doom-opera-theme
+  :type 'boolean)
+
+(defcustom doom-opera-brighter-comments nil
+  "If non-nil, comments will be highlighted in more vivid colors."
+  :group 'doom-opera-theme
+  :type 'boolean)
+
+(defcustom doom-opera-comment-bg doom-opera-brighter-comments
+  "If non-nil, comments will have a subtle, darker background. Enhancing their
+legibility."
+  :group 'doom-opera-theme
+  :type 'boolean)
+
+(defcustom doom-opera-padded-modeline doom-themes-padded-modeline
+  "If non-nil, adds a 4px padding to the mode-line. Can be an integer to
+determine the exact padding."
+  :group 'doom-opera-theme
+  :type '(or integer boolean))
+
+(defcustom doom-opera-region-highlight t
+  "Determines the selection highlight style. Can be 'frost, 'snowstorm or t
+(default)."
+  :group 'doom-opera-theme
+  :type 'symbol)
+
+(def-doom-theme doom-opera
+  "A dark opera theme."
+
+  ;; name        default   256       16
+  ((bg         '("#323334" nil       nil            ))
+   (bg-alt     '("#222224" nil       nil            ))
+   (base0      '("#000000" "black"   "black"        ))
+   (base1      '("#1e1e1e" "#1e1e1e" "brightblack"  ))
+   (base2      '("#2e2e2e" "#2e2e2e" "brightblack"  ))
+   (base3      '("#262626" "#262626" "brightblack"  ))
+   (base4      '("#3f3f3f" "#3f3f3f" "brightblack"  ))
+   (base5      '("#525252" "#525252" "brightblack"  ))
+   (base6      '("#6b6b6b" "#6b6b6b" "brightblack"  ))
+   (base7      '("#979797" "#979797" "brightblack"  ))
+   (base8      '("#dfdfdf" "#dfdfdf" "white"        ))
+   (fg         '("#eceff4" "#dfdfdf" "white"        ))
+   (fg-alt     '("#727269" "#bfbfbf" "brightwhite"  ))
+
+   (grey       base4)
+   (red        '("#C16069" "#ff6655" "red"          ))
+   (orange     '("#D2876D" "#dd8844" "brightred"    ))
+   (green      '("#A2BF8A" "#99bb66" "green"        ))
+   (teal       '("#8EBCBB" "#44b9b1" "brightgreen"  ))
+   (yellow     '("#ECCC87" "#ECBE7B" "yellow"       ))
+   (blue       '("#80A0C2" "#51afef" "brightblue"   ))
+   (dark-blue  '("#5C748E" "#2257A0" "blue"         ))
+   (magenta    '("#B58DAE" "#c678dd" "magenta"      ))
+   (violet     '("#5D80AE" "#a9a1e1" "brightmagenta"))
+   (cyan       '("#86C0D1" "#46D9FF" "brightcyan"   ))
+   (dark-cyan  '("#507681" "#5699AF" "cyan"         ))
+
+   ;; face categories -- required for all themes
+   (highlight      blue)
+   (vertical-bar   (doom-darken base1 0.2))
+   (selection      dark-blue)
+   (builtin        teal)
+   (comments       (if doom-opera-brighter-comments dark-cyan (doom-lighten base5 0.2)))
+   (doc-comments   (doom-lighten (if doom-opera-brighter-comments dark-cyan base5) 0.25))
+   (constants      magenta)
+   (functions      teal)
+   (keywords       blue)
+   (methods        teal)
+   (operators      blue)
+   (type           yellow)
+   (strings        green)
+   (variables      (doom-lighten magenta 0.5))
+   (numbers        magenta)
+   (region         base4)
+   (error          red)
+   (warning        yellow)
+   (success        green)
+   (vc-modified    orange)
+   (vc-added       green)
+   (vc-deleted     red)
+
+   ;; custom categories
+   (hidden     `(,(car bg) "black" "black"))
+   (-modeline-bright doom-opera-brighter-modeline)
+   (-modeline-pad
+    (when doom-opera-padded-modeline
+      (if (integerp doom-opera-padded-modeline) doom-opera-padded-modeline 4)))
+
+   (modeline-fg     nil)
+   (modeline-fg-alt base5)
+
+   (modeline-bg
+    (if -modeline-bright
+        (doom-darken blue 0.475)
+      `(,(doom-darken (car bg-alt) 0.15) ,@(cdr base0))))
+   (modeline-bg-l
+    (if -modeline-bright
+        (doom-darken blue 0.45)
+      `(,(doom-darken (car bg-alt) 0.1) ,@(cdr base0))))
+   (modeline-bg-inactive   (doom-darken bg-alt 0.1))
+   (modeline-bg-inactive-l `(,(car bg-alt) ,@(cdr base1))))
+
+  ;; --- extra faces ------------------------
+  (
+   ((line-number &override) :foreground fg-alt)
+   ((line-number-current-line &override) :foreground fg)
+
+   (font-lock-comment-face
+    :foreground comments
+    :background (if doom-opera-comment-bg (doom-lighten bg 0.05)))
+   (font-lock-doc-face
+    :inherit 'font-lock-comment-face
+    :foreground doc-comments)
+
+   (doom-modeline-bar :background (if -modeline-bright modeline-bg highlight))
+
+   (mode-line
+    :background modeline-bg :foreground modeline-fg
+    :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))
+   (mode-line-inactive
+    :background modeline-bg-inactive :foreground modeline-fg-alt
+    :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive)))
+   (mode-line-emphasis
+    :foreground (if -modeline-bright base8 highlight))
+
+   (solaire-mode-line-face
+    :inherit 'mode-line
+    :background modeline-bg-l
+    :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-l)))
+   (solaire-mode-line-inactive-face
+    :inherit 'mode-line-inactive
+    :background modeline-bg-inactive-l
+    :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive-l)))))
+
+;;; doom-opera-theme.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-opera-theme.elc b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-opera-theme.elc
new file mode 100644
index 0000000000..9cf2d63fef
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-opera-theme.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-peacock-theme.el b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-peacock-theme.el
new file mode 100644
index 0000000000..9f6b827ac5
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-peacock-theme.el
@@ -0,0 +1,185 @@
+;;; doom-peacock-theme.el
+(require 'doom-themes)
+
+(defgroup doom-peacock-theme nil
+  "Options for doom-themes"
+  :group 'doom-themes)
+
+(defcustom doom-peacock-brighter-modeline nil
+  "If non-nil, more vivid colors will be used to style the mode-line."
+  :group 'doom-peacock-theme
+  :type 'boolean)
+
+(defcustom doom-peacock-brighter-comments nil
+  "If non-nil, comments will be highlighted in more vivid colors."
+  :group 'doom-peacock-theme
+  :type 'boolean)
+
+(defcustom doom-peacock-comment-bg doom-peacock-brighter-comments
+  "If non-nil, comments will have a subtle, darker background. Enhancing their
+legibility."
+  :group 'doom-peacock-theme
+  :type 'boolean)
+
+(defcustom doom-peacock-padded-modeline doom-themes-padded-modeline
+  "If non-nil, adds a 4px padding to the mode-line. Can be an integer to
+determine the exact padding."
+  :group 'doom-peacock-theme
+  :type '(or integer boolean))
+
+;;
+(def-doom-theme doom-peacock
+  "peacock theme!"
+
+  ;; name        default   256       16
+  ((bg         '("#2b2a27" nil       nil            ))
+   (bg-alt     '("#282725" nil       nil            )) ;; arbitrarily picked this colour to change hline
+   (base0      '("#2b2a27" "black"   "black"        ))
+   (base1      '("#1c1f24" "#1e1e1e" "brightblack"  ))
+   (base2      '("#202328" "#2e2e2e" "brightblack"  ))
+   (base3      '("#23272e" "#262626" "brightblack"  ))
+   (base4      '("#3f444a" "#3f3f3f" "brightblack"  ))
+   (base5      '("#5B6268" "#525252" "brightblack"  ))
+   (base6      '("#73797e" "#6b6b6b" "brightblack"  ))
+   (base7      '("#9ca0a4" "#979797" "brightblack"  ))
+   (base8      '("#DFDFDF" "#dfdfdf" "white"        ))
+   (fg         '("#ede0ce" "#bfbfbf" "brightwhite"  ))
+   (fg-alt     '("#5B6268" "#2d2d2d" "white"        ))
+
+   (grey       base4)
+   (white      '("#f8f8f0" "base4"   "base4"        ))
+   (red        '("#ff5d38" "#ff6655" "red"          )) ;; peacock todo 16
+   (orange     '("#cb4b16" "#dd8844" "brightred"    ))
+   (green      '("#98be65" "#99bb66" "green"        ))
+   (teal       '("#26a6a6" "#44b9b1" "brightgreen"  )) ;; peacock
+   (yellow     '("#bcd42a" "#ECBE7B" "yellow"       )) ;; peacock, todo 16
+   (blue       '("#51afef" "#51afef" "brightblue"   ))
+   (dark-blue  '("#2257A0" "#2257A0" "blue"         ))
+   (magenta    '("#c678dd" "#c678dd" "magenta"      ))
+   (violet     '("#a9a1e1" "#a9a1e1" "brightmagenta"))
+   (cyan       '("#46D9FF" "#46D9FF" "brightcyan"   ))
+   (dark-cyan  '("#5699AF" "#5699AF" "cyan"         ))
+   (coral-popup  '("#a60033" "#f6bfbc" "coral-popup"         ))
+
+   ;; face categories -- required for all themes
+   (highlight      red)
+   (vertical-bar   (doom-lighten bg 0.1))
+   (selection      coral-popup)
+   (builtin        red)
+   (comments       (if doom-peacock-brighter-comments dark-cyan base5)) ;; TODO
+   (doc-comments   (doom-lighten (if doom-peacock-brighter-comments dark-cyan base5) 0.25)) ;; TODO
+   (constants      red)        ;; done
+   (functions      yellow)     ;; done
+   (keywords       teal)       ;; done
+   (methods        yellow)     ;; not sure how to test this.
+   (operators      red)        ;; not showing up on `=` etc.
+   (type           white)      ;;
+   (strings        yellow)
+   (variables      white)      ;; done
+   (numbers        red)        ;; done
+
+   (region         `(,(doom-lighten (car bg-alt) 0.15) ,@(doom-lighten (cdr base0) 0.35)))
+   (error          red)
+   (warning        yellow)
+   (success        green)
+   (vc-modified    orange)
+   (vc-added       green)
+   (vc-deleted     red)
+
+   ;; custom categories
+   (-modeline-bright doom-peacock-brighter-modeline)
+   (-modeline-pad
+    (when doom-peacock-padded-modeline
+      (if (integerp doom-peacock-padded-modeline) doom-peacock-padded-modeline 4)))
+
+   (modeline-fg     nil)
+   (modeline-fg-alt (doom-blend violet base4 (if -modeline-bright 0.5 0.2)))
+
+   (modeline-bg
+    (if -modeline-bright
+        (doom-darken bg 0.475)
+      `(,(doom-darken (car bg) 0.15) ,@(cdr base0))))
+   (modeline-bg-l
+    (if -modeline-bright
+        (doom-darken blue 0.45)
+      `(,(doom-darken (car bg-alt) 0.1) ,@(cdr base0))))
+   (modeline-bg-inactive   (doom-darken bg 0.1))
+   (modeline-bg-inactive-l `(,(car bg) ,@(cdr base1))))
+
+
+  ;; --- extra faces ------------------------
+  ((elscreen-tab-other-screen-face :background "#353a42" :foreground "#1e2022")
+
+   (font-lock-comment-face
+    :foreground comments
+    :background (if doom-peacock-comment-bg (doom-lighten bg 0.05)))
+   (font-lock-doc-face
+    :inherit 'font-lock-comment-face
+    :foreground doc-comments)
+
+   ((line-number &override) :foreground base4)
+   ((line-number-current-line &override) :foreground base7)
+
+   ;; tooltip
+   (tooltip              :background bg-alt :foreground fg)
+
+   ;; company
+    (company-tooltip            :inherit 'tooltip)
+    (company-tooltip-common                           :foreground highlight)
+    (company-tooltip-search     :background highlight :foreground bg :distant-foreground fg)
+    (company-tooltip-selection  :background selection)
+    (company-tooltip-mouse      :background magenta   :foreground bg :distant-foreground fg)
+    (company-tooltip-annotation                       :foreground violet)
+    (company-scrollbar-bg       :inherit 'tooltip)
+    (company-scrollbar-fg       :background highlight)
+    (company-preview                                  :foreground highlight)
+    (company-preview-common     :background base3 :foreground magenta)
+    (company-preview-search     :inherit 'company-tooltip-search)
+    (company-template-field     :inherit 'match)
+
+   ;; popup
+   (popup-face :inherit 'tooltip)
+   (popup-selection-face :inherit 'tooltip)
+
+   ;; pos-tip
+   (popup          :inherit 'tooltip)
+   (popup-tip-face :inherit 'tooltip)
+
+
+   (doom-modeline-bar :background (if -modeline-bright modeline-bg highlight))
+
+   (mode-line
+    :background modeline-bg :foreground modeline-fg
+    :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))
+   (mode-line-inactive
+    :background modeline-bg-inactive :foreground modeline-fg-alt
+    :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive)))
+   (mode-line-emphasis
+    :foreground (if -modeline-bright base8 highlight))
+
+   (solaire-mode-line-face
+    :inherit 'mode-line
+    :background modeline-bg-l
+    :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-l)))
+   (solaire-mode-line-inactive-face
+    :inherit 'mode-line-inactive
+    :background modeline-bg-inactive-l
+    :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive-l)))
+
+   ;; --- major-mode faces -------------------
+   ;; css-mode / scss-mode
+   (css-proprietary-property :foreground orange)
+   (css-property             :foreground green)
+   (css-selector             :foreground blue)
+
+   ;; markdown-mode
+   (markdown-markup-face :foreground base5)
+   (markdown-header-face :inherit 'bold :foreground red)
+   (markdown-code-face :background (doom-lighten base3 0.05)))
+
+
+  ;; --- extra variables ---------------------
+  ;; ()
+  )
+
+;;; doom-peacock-theme.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-peacock-theme.elc b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-peacock-theme.elc
new file mode 100644
index 0000000000..10c3392e08
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-peacock-theme.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-solarized-light-theme.el b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-solarized-light-theme.el
new file mode 100644
index 0000000000..03fdbfbd8a
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-solarized-light-theme.el
@@ -0,0 +1,185 @@
+;;; doom-solarized-light-theme.el --- inspired by Atom One Dark
+(require 'doom-themes)
+
+;;
+(defgroup doom-solarized-light-theme nil
+  "Options for doom-themes"
+  :group 'doom-themes)
+
+(defcustom doom-solarized-light-brighter-modeline nil
+  "If non-nil, more vivid colors will be used to style the mode-line."
+  :group 'doom-solarized-light-theme
+  :type 'boolean)
+
+(defcustom doom-solarized-light-brighter-comments nil
+  "If non-nil, comments will be highlighted in more vivid colors."
+  :group 'doom-solarized-light-theme
+  :type 'boolean)
+
+(defcustom doom-solarized-light-comment-bg doom-solarized-light-brighter-comments
+  "If non-nil, comments will have a subtle, darker background. Enhancing their
+legibility."
+  :group 'doom-solarized-light-theme
+  :type 'boolean)
+
+(defcustom doom-solarized-light-padded-modeline doom-themes-padded-modeline
+  "If non-nil, adds a 4px padding to the mode-line. Can be an integer to
+determine the exact padding."
+  :group 'doom-solarized-light-theme
+  :type '(or integer boolean))
+
+;;
+(def-doom-theme doom-solarized-light
+  "A light theme inspired by Solarized light"
+
+  ;; name        default   256       16
+  ((bg         '("#FDF6E3" nil       nil            ))
+   (bg-alt     '("#FFFBEA" nil       nil            ))
+   (base0      '("#FFFBF0" "black"   "black"        ))
+   (base1      '("#FCF8ED" "#1e1e1e" "brightblack"  ))
+   (base2      '("#FCF7E8" "#2e2e2e" "brightblack"  ))
+   (base3      '("#F2E6CE" "#262626" "brightblack"  ))
+   (base4      '("#E1DBCD" "#3f3f3f" "brightblack"  ))
+   (base5      '("#D6D6D6" "#525252" "brightblack"  ))
+   (base6      '("#96A7A9" "#6b6b6b" "brightblack"  ))
+   (base7      '("#788484" "#979797" "brightblack"  ))
+   (base8      '("#626C6C" "#dfdfdf" "white"        ))
+   (fg         '("#556b72" "#2d2d2d" "white"        ))
+   (fg-alt     '("#7B8787" "#bfbfbf" "brightwhite"  ))
+
+   (grey       base4)
+   (red        '("#dc322f" "#ff6655" "red"          ))
+   (orange     '("#cb4b16" "#dd8844" "brightred"    ))
+   (green      '("#859900" "#99bb66" "green"        ))
+   (teal       '("#35a69c" "#33aa99" "brightgreen"  ))
+   (yellow     '("#b58900" "#ECBE7B" "yellow"       ))
+   (blue       '("#268bd2" "#51afef" "brightblue"   ))
+   (dark-blue  '("#E1E3E5" "#2257A0" "blue"         ))
+   (magenta    '("#d33682" "#c678dd" "magenta"      ))
+   (violet     '("#6c71c4" "#a9a1e1" "brightmagenta"))
+   (cyan       '("#2aa198" "#46D9FF" "brightcyan"   ))
+   (dark-cyan  '("#D7DDD7" "#5699AF" "cyan"         ))
+
+   ;; face categories -- required for all themes
+   (highlight      blue)
+   (vertical-bar   base4)
+   (selection      dark-blue)
+   (builtin        magenta)
+   (comments       (if doom-solarized-light-brighter-comments
+                       (doom-lighten teal 0.25)
+                     base6))
+   (doc-comments   teal)
+   (constants      violet)
+   (functions      magenta)
+   (keywords       green)
+   (methods        cyan)
+   (operators      blue)
+   (type           yellow)
+   (strings        cyan)
+   (variables      blue)
+   (numbers        violet)
+   (region         `(,(doom-darken (car bg-alt) 0.1) ,@(doom-darken (cdr base0) 0.1)))
+   (error          red)
+   (warning        yellow)
+   (success        green)
+   (vc-modified    orange)
+   (vc-added       green)
+   (vc-deleted     red)
+
+   ;; custom categories
+   (hidden     `(,(car bg) "black" "black"))
+   (-modeline-bright doom-solarized-light-brighter-modeline)
+   (-modeline-pad
+    (when doom-solarized-light-padded-modeline
+      (if (integerp doom-solarized-light-padded-modeline) doom-solarized-light-padded-modeline 4)))
+
+   (modeline-fg     nil)
+   (modeline-fg-alt base6)
+
+   (modeline-bg
+    (if -modeline-bright
+        (doom-lighten bg 0.7)
+      (doom-lighten base3 0.2)))
+   (modeline-bg-l
+    (if -modeline-bright
+        (doom-lighten bg 0.7)
+      (doom-darken bg 0.05)))
+   (modeline-bg-inactive   (doom-darken bg 0.02))
+   (modeline-bg-inactive-l (doom-darken bg 0.025)))
+
+
+  ;; --- extra faces ------------------------
+  ((elscreen-tab-other-screen-face :background "#353a42" :foreground "#1e2022")
+
+   (hl-line :background nil)
+
+   ((line-number &override) :foreground base6)
+   ((line-number-current-line &override) :foreground fg :background region :weight 'bold)
+
+   (org-block :background (doom-blend yellow bg 0.04))
+   (org-block-background :background (doom-blend yellow bg 0.04))
+   (org-block-begin-line :background (doom-blend yellow bg 0.08))
+   (org-block-end-line :background (doom-blend yellow bg 0.08))
+   (font-lock-comment-face
+    :slant 'italic
+    :foreground comments
+    :background (if doom-solarized-light-comment-bg (doom-blend teal base0 0.07)))
+   ((font-lock-doc-face &override) :foreground doc-comments)
+   ((font-lock-type-face &override) :slant 'italic)
+   ((font-lock-builtin-face &override) :slant 'italic)
+   ((font-lock-function-name-face &override) :foreground type)
+
+
+   (doom-modeline-bar :background (if -modeline-bright modeline-bg highlight))
+
+   (mode-line
+    :background modeline-bg :foreground modeline-fg
+    :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))
+   (mode-line-inactive
+    :background modeline-bg-inactive :foreground modeline-fg-alt
+    :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive)))
+   (mode-line-emphasis
+    :foreground (if -modeline-bright base8 highlight))
+
+   (solaire-mode-line-face
+    :inherit 'mode-line
+    :background modeline-bg-l
+    :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-l)))
+   (solaire-mode-line-inactive-face
+    :inherit 'mode-line-inactive
+    :background modeline-bg-inactive-l
+    :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive-l)))
+
+   ;; --- major-mode faces -------------------
+   ;; css-mode / scss-mode
+   (css-proprietary-property :foreground orange)
+   (css-property             :foreground green)
+   (css-selector             :foreground blue)
+
+   ;; markdown-mode
+   (markdown-markup-face :foreground base5)
+   (markdown-header-face :inherit 'bold :foreground red)
+   (markdown-code-face :background (doom-lighten base3 0.05))
+
+   ;; ivy-mode
+   (ivy-current-match :background (doom-lighten yellow 0.65) :distant-foreground fg)
+   (ivy-minibuffer-match-face-1
+    :foreground comments
+    :weight 'light)
+   (ivy-minibuffer-match-face-2 :foreground magenta :background base3 :weight 'bold)
+   (ivy-minibuffer-match-face-3 :foreground green   :background base3 :weight 'bold)
+   (ivy-minibuffer-match-face-4 :foreground yellow  :background base3 :weight 'bold)
+   (ivy-minibuffer-match-highlight :foreground violet :weight 'bold)
+
+   ;; posframe
+   (ivy-posframe :background modeline-bg-l)
+   ;; org-mode
+   (org-hide :foreground hidden)
+   (solaire-org-hide-face :foreground hidden))
+
+
+  ;; --- extra variables ---------------------
+  ;; ()
+  )
+
+;;; doom-solarized-light-theme.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-solarized-light-theme.elc b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-solarized-light-theme.elc
new file mode 100644
index 0000000000..3e12284bcb
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-solarized-light-theme.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-spacegrey-theme.el b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-spacegrey-theme.el
new file mode 100644
index 0000000000..7f89bc3fb4
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-spacegrey-theme.el
@@ -0,0 +1,182 @@
+;;; doom-spacegrey-theme.el --- inspired by Atom One Dark
+(require 'doom-themes)
+
+(defgroup doom-spacegrey-theme nil
+  "Options for doom-themes"
+  :group 'doom-themes)
+
+(defcustom doom-spacegrey-brighter-modeline nil
+  "If non-nil, more vivid colors will be used to style the mode-line."
+  :group 'doom-spacegrey-theme
+  :type 'boolean)
+
+(defcustom doom-spacegrey-brighter-comments nil
+  "If non-nil, comments will be highlighted in more vivid colors."
+  :group 'doom-spacegrey-theme
+  :type 'boolean)
+
+(defcustom doom-spacegrey-comment-bg doom-spacegrey-brighter-comments
+  "If non-nil, comments will have a subtle, darker background. Enhancing their
+legibility."
+  :group 'doom-spacegrey-theme
+  :type 'boolean)
+
+(defcustom doom-spacegrey-padded-modeline doom-themes-padded-modeline
+  "If non-nil, adds a 4px padding to the mode-line. Can be an integer to
+determine the exact padding."
+  :group 'doom-spacegrey-theme
+  :type '(or integer boolean))
+
+;;
+(def-doom-theme doom-spacegrey
+  "A dark theme inspired by Atom spacegrey Dark"
+
+  ;; name        default   256       16
+  ((bg         '("#2F3841" nil       nil            ))
+   (bg-alt     '("#343D46" nil       nil            ))
+   (base0      '("#1B2229" "black"   "black"        ))
+   (base1      '("#1c1f24" "#1e1e1e" "brightblack"  ))
+   (base2      '("#202328" "#2e2e2e" "brightblack"  ))
+   (base3      '("#2F3237" "#2F3237" "brightblack"  ))
+   (base4      '("#4f5b66" "#4f5b66" "brightblack"  ))
+   (base5      '("#65737E" "#65737E" "brightblack"  ))
+   (base6      '("#73797e" "#6b6b6b" "brightblack"  ))
+   (base7      '("#9ca0a4" "#979797" "brightblack"  ))
+   (base8      '("#DFDFDF" "#dfdfdf" "white"        ))
+   (fg         '("#c0c5ce" "#c0c5ce" "brightwhite"  ))
+   (fg-alt     '("#c0c5ce" "#c0c5ce" "white"        ))
+
+   (grey       base4)
+   (red        '("#BF616A" "#BF616A" "red"          ))
+   (orange     '("#D08770" "#D08770" "brightred"    ))
+   (green      '("#A3BE8C" "#A3BE8C" "green"        ))
+   (blue       '("#8FA1B3" "#8FA1B3" "brightblue"   ))
+   (violet     '("#b48ead" "#b48ead" "brightmagenta"))
+   (teal       '("#4db5bd" "#44b9b1" "brightgreen"  ))
+   (yellow     '("#ECBE7B" "#ECBE7B" "yellow"       ))
+   (dark-blue  '("#2257A0" "#2257A0" "blue"         ))
+   (magenta    '("#c678dd" "#c678dd" "magenta"      ))
+   (cyan       '("#46D9FF" "#46D9FF" "brightcyan"   ))
+   (dark-cyan  '("#5699AF" "#5699AF" "cyan"         ))
+
+   ;; face categories -- required for all themes
+   (highlight      orange)
+   (vertical-bar   (doom-darken bg 0.25))
+   (selection      base4)
+   (builtin        orange)
+   (comments       base5)
+   (doc-comments   (doom-lighten (if doom-spacegrey-brighter-comments dark-cyan base5) 0.25))
+   (constants      orange)
+   (functions      blue)
+   (keywords       violet)
+   (methods        blue)
+   (operators      fg)
+   (type           yellow)
+   (strings        green)
+   (variables      (doom-lighten magenta 0.4))
+   (numbers        orange)
+   (region         selection)
+   (error          red)
+   (warning        yellow)
+   (success        green)
+   (vc-modified    orange)
+   (vc-added       green)
+   (vc-deleted     red)
+
+   ;; custom categories
+   (hidden     `(,(car bg-alt) "black" "black"))
+   (-modeline-bright doom-spacegrey-brighter-modeline)
+   (-modeline-pad
+    (when doom-spacegrey-padded-modeline
+      (if (integerp doom-spacegrey-padded-modeline) doom-spacegrey-padded-modeline 4)))
+
+
+
+   ;; --- Modeline config -------------------
+
+   (modeline-fg     nil)
+   (modeline-fg-alt (doom-blend violet base4 (if -modeline-bright 0.5 0.2)))
+
+   (modeline-bg
+    (if -modeline-bright
+        (doom-darken base3 0.05)
+      base3))
+   (modeline-bg-l
+    (if -modeline-bright
+        (doom-darken base3 0.1)
+      base3))
+   (modeline-bg-inactive (doom-darken bg 0.1))
+   (modeline-bg-inactive-l `(,(doom-darken (car bg-alt) 0.05) ,@(cdr base1))))
+
+
+  ;; --- extra faces ------------------------
+  ((elscreen-tab-other-screen-face :background "#353a42" :foreground "#1e2022")
+
+   ((line-number &override) :foreground base4)
+   ((line-number-current-line &override) :foreground fg)
+
+   (font-lock-comment-face
+    :foreground comments
+    :background (if doom-spacegrey-comment-bg (doom-lighten bg 0.05)))
+   (font-lock-doc-face
+    :inherit 'font-lock-comment-face
+    :foreground doc-comments)
+
+   (doom-modeline-bar :background (if -modeline-bright modeline-bg highlight))
+
+   (mode-line
+    :background modeline-bg :foreground modeline-fg
+    :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))
+   (mode-line-inactive
+    :background modeline-bg-inactive :foreground modeline-fg-alt
+    :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive)))
+   (mode-line-emphasis
+    :foreground (if -modeline-bright base8 highlight))
+
+   (solaire-mode-line-face
+    :inherit 'mode-line
+    :background modeline-bg-l
+    :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-l)))
+   (solaire-mode-line-inactive-face
+    :inherit 'mode-line-inactive
+    :background modeline-bg-inactive-l
+    :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive-l)))
+
+   ;; --- major-mode faces -------------------
+   ;; css-mode / scss-mode
+   (css-proprietary-property :foreground orange)
+   (css-property             :foreground fg)
+   (css-selector             :foreground red)
+
+   ;; markdown-mode
+   (markdown-markup-face :foreground base5)
+   (markdown-header-face :inherit 'bold :foreground red)
+   (markdown-code-face :background (doom-darken bg 0.1))
+
+   ;; org-mode
+   (org-block            :background (doom-darken bg-alt 0.04))
+   (org-block-begin-line :foreground base4 :slant 'italic :background (doom-darken bg 0.04))
+
+   (org-level-1 :foreground fg   :weight 'ultra-bold :inherit 'hl-line :height 1.2)
+   (org-level-2 :foreground (doom-blend fg blue 0.35) :weight 'bold)
+   (org-level-3 :foreground (doom-blend fg blue 0.7)  :weight 'bold)
+   (org-level-4 :foreground blue       :weight 'bold)
+   (org-level-5 :foreground (doom-blend magenta blue 0.2) :weight 'bold)
+   (org-level-6 :foreground (doom-blend magenta blue 0.4) :weight 'bold)
+   (org-level-7 :foreground (doom-blend magenta blue 0.6) :weight 'bold)
+   (org-level-8 :foreground fg :weight 'semi-bold)
+
+   (org-ellipsis         :underline nil :background bg    :foreground red)
+   (org-quote            :background base1)
+
+   ;; org-mode
+   (org-hide :foreground hidden)
+   (solaire-org-hide-face :foreground hidden)
+
+   )
+
+  ;; --- extra variables ---------------------
+  ;; ()
+  )
+
+;;; doom-spacegrey-theme.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-spacegrey-theme.elc b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-spacegrey-theme.elc
new file mode 100644
index 0000000000..a2cfb2d8f5
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-spacegrey-theme.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-themes-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-themes-autoloads.el
new file mode 100644
index 0000000000..b411bdbc1d
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-themes-autoloads.el
@@ -0,0 +1,101 @@
+;;; doom-themes-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "doom-themes" "doom-themes.el" (23377 61285
+;;;;;;  465453 628000))
+;;; Generated autoloads from doom-themes.el
+
+(autoload 'doom-name-to-rgb "doom-themes" "\
+Retrieves the hexidecimal string repesented the named COLOR (e.g. \"red\")
+for FRAME (defaults to the current frame).
+
+\(fn COLOR &optional FRAME)" nil nil)
+
+(autoload 'doom-blend "doom-themes" "\
+Blend two colors (hexidecimal strings) together by a coefficient ALPHA (a
+float between 0 and 1)
+
+\(fn COLOR1 COLOR2 ALPHA)" nil nil)
+
+(autoload 'doom-darken "doom-themes" "\
+Darken a COLOR (a hexidecimal string) by a coefficient ALPHA (a float between
+0 and 1).
+
+\(fn COLOR ALPHA)" nil nil)
+
+(autoload 'doom-lighten "doom-themes" "\
+Brighten a COLOR (a hexidecimal string) by a coefficient ALPHA (a float
+between 0 and 1).
+
+\(fn COLOR ALPHA)" nil nil)
+
+(autoload 'doom-color "doom-themes" "\
+Retrieve a specific color named NAME (a symbol) from the current theme.
+
+\(fn NAME &optional TYPE)" nil nil)
+
+(autoload 'doom-ref "doom-themes" "\
+TODO
+
+\(fn FACE PROP &optional CLASS)" nil nil)
+
+(autoload 'doom-themes-set-faces "doom-themes" "\
+Customize THEME (a symbol) with FACES.
+
+\(fn THEME &rest FACES)" nil t)
+
+(function-put 'doom-themes-set-faces 'lisp-indent-function 'defun)
+
+(autoload 'doom-themes-org-config "doom-themes" "\
+Enable custom fontification and improves doom-themes integration with org-mode.
+
+\(fn)" nil nil)
+
+(autoload 'doom-themes-neotree-config "doom-themes" "\
+Install doom-themes' neotree configuration.
+
+Includes an Atom-esque icon theme and highlighting based on filetype.
+
+\(fn)" nil nil)
+
+(autoload 'doom-themes-treemacs-config "doom-themes" "\
+Install doom-themes' treemacs configuration.
+
+Includes an Atom-esque icon theme and highlighting based on filetype.
+
+\(fn)" nil nil)
+
+(autoload 'doom-themes-visual-bell-config "doom-themes" "\
+Enable flashing the mode-line on error.
+
+\(fn)" nil nil)
+
+(autoload 'doom-themes-visual-bell-fn "doom-themes" "\
+Blink the mode-line red briefly. Set `ring-bell-function' to this to use it.
+
+\(fn)" nil nil)
+
+(when (and (boundp 'custom-theme-load-path) load-file-name) (let* ((base (file-name-directory load-file-name)) (dir (expand-file-name "themes/" base))) (add-to-list 'custom-theme-load-path (or (and (file-directory-p dir) dir) base))))
+
+;;;***
+
+;;;### (autoloads nil nil ("doom-challenger-deep-theme.el" "doom-city-lights-theme.el"
+;;;;;;  "doom-dracula-theme.el" "doom-molokai-theme.el" "doom-nord-light-theme.el"
+;;;;;;  "doom-nord-theme.el" "doom-nova-theme.el" "doom-one-light-theme.el"
+;;;;;;  "doom-one-theme.el" "doom-opera-light-theme.el" "doom-opera-theme.el"
+;;;;;;  "doom-peacock-theme.el" "doom-solarized-light-theme.el" "doom-spacegrey-theme.el"
+;;;;;;  "doom-themes-common.el" "doom-themes-neotree.el" "doom-themes-org.el"
+;;;;;;  "doom-themes-pkg.el" "doom-themes-treemacs.el" "doom-tomorrow-day-theme.el"
+;;;;;;  "doom-tomorrow-night-theme.el" "doom-vibrant-theme.el") (23377
+;;;;;;  61285 492218 786000))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; doom-themes-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-themes-common.el b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-themes-common.el
new file mode 100644
index 0000000000..e91518fc1a
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-themes-common.el
@@ -0,0 +1,1377 @@
+;;; doom-themes-common.el -*- lexical-binding: t; -*-
+
+(defvar doom-themes-common-faces
+  '(;; --- custom faces -----------------------
+    (doom-modeline-error
+     :background (doom-darken red 0.25)
+     :foreground base0
+     :distant-foreground base0)
+
+    ;; --- base faces -------------------------
+    (bold        :weight 'bold :foreground (unless bold base8))
+    (italic      :slant  'italic)
+    (bold-italic :inherit '(bold italic))
+
+    (default :background bg :foreground fg)
+    (fringe :inherit 'default :foreground base4)
+    (region               :background region     :foreground nil   :distant-foreground (doom-darken fg 0.2))
+    (highlight            :background highlight  :foreground base0 :distant-foreground base8)
+    (cursor               :background highlight)
+    (shadow               :foreground base5)
+    (minibuffer-prompt    :foreground highlight)
+    (tooltip              :background base3 :foreground fg)
+    (secondary-selection  :background grey)
+    (lazy-highlight       :background dark-blue  :foreground base8 :distant-foreground base0 :weight 'bold)
+    (match                :foreground green      :background base0 :weight 'bold)
+    (trailing-whitespace  :background red)
+    (nobreak-space        :inherit 'default :underline nil)
+    (vertical-border      :background vertical-bar :foreground vertical-bar)
+    (link                 :foreground highlight :underline t :weight 'bold)
+
+    (error   :foreground error)
+    (warning :foreground warning)
+    (success :foreground success)
+
+    (font-lock-builtin-face              :foreground builtin)
+    (font-lock-comment-face              :foreground comments)
+    (font-lock-comment-delimiter-face    :inherit 'font-lock-comment-face)
+    (font-lock-doc-face                  :inherit 'font-lock-comment-face :foreground doc-comments)
+    (font-lock-constant-face             :foreground constants)
+    (font-lock-function-name-face        :foreground functions)
+    (font-lock-keyword-face              :foreground keywords)
+    (font-lock-string-face               :foreground strings)
+    (font-lock-type-face                 :foreground type)
+    (font-lock-variable-name-face        :foreground variables)
+    (font-lock-warning-face              :inherit 'warning)
+    (font-lock-negation-char-face        :inherit 'bold :foreground operators)
+    (font-lock-preprocessor-face         :inherit 'bold :foreground operators)
+    (font-lock-preprocessor-char-face    :inherit 'bold :foreground operators)
+    (font-lock-regexp-grouping-backslash :inherit 'bold :foreground operators)
+    (font-lock-regexp-grouping-construct :inherit 'bold :foreground operators)
+
+    ;; mode-line / header-line
+    (mode-line           :background bg     :foreground fg     :distant-foreground bg)
+    (mode-line-inactive  :background bg-alt :foreground fg-alt :distant-foreground bg-alt)
+    (mode-line-emphasis  :foreground highlight :distant-foreground bg)
+    (mode-line-highlight :inherit 'highlight :distant-foreground bg)
+    (mode-line-buffer-id :weight 'bold)
+    (header-line :inherit 'mode-line :distant-foreground bg)
+
+    ;; 1. Line number faces must explicitly disable its text style attributes
+    ;;    because nearby faces may "bleed" into the line numbers otherwise.
+    ;; 2. All other line number plugin faces should &inherit from these.
+    (line-number
+     :inherit 'default
+     :foreground base5 :distant-foreground nil
+     :weight 'normal :italic nil :underline nil :strike-through nil)
+    (line-number-current-line
+     :inherit '(hl-line default)
+     :foreground fg :distant-foreground nil
+     :weight 'normal :italic nil :underline nil :strike-through nil)
+
+
+    ;; --- built-in plugin faces --------------
+    ;; cperl
+    (cperl-array-face          :weight 'bold :inherit 'font-lock-variable-name-face)
+    (cperl-hash-face           :weight 'bold :slant 'italic :inherit 'font-lock-variable-name-face)
+    (cperl-nonoverridable-face :inherit 'font-lock-builtin-face)
+
+    ;; compilation
+    (compilation-column-number  :inherit 'font-lock-comment-face)
+    (compilation-line-number    :foreground highlight)
+    (compilation-error   :inherit 'error   :weight 'bold)
+    (compilation-warning :inherit 'warning :slant 'italic)
+    (compilation-info    :inherit 'success)
+    (compilation-mode-line-exit :inherit 'compilation-info)
+    (compilation-mode-line-fail :inherit 'compilation-error)
+
+    ;; custom
+    (custom-button                  :foreground blue   :background bg     :box '(:line-width 1 :style none))
+    (custom-button-unraised         :foreground violet :background bg     :box '(:line-width 1 :style none))
+    (custom-button-pressed-unraised :foreground bg     :background violet :box '(:line-width 1 :style none))
+    (custom-button-pressed          :foreground bg     :background blue   :box '(:line-width 1 :style none))
+    (custom-button-mouse            :foreground bg     :background blue   :box '(:line-width 1 :style none))
+
+    (custom-variable-button   :foreground green :underline t)
+    (custom-saved             :foreground green :background (doom-blend green bg 0.2) :bold bold)
+    (custom-comment           :foreground fg :background region)
+    (custom-comment-tag       :foreground grey)
+    (custom-modified          :foreground blue :background (doom-blend blue bg 0.2))
+    (custom-variable-tag      :foreground magenta)
+    (custom-visibility        :foreground blue :underline nil)
+    (custom-group-subtitle    :foreground red)
+    (custom-group-tag         :foreground violet)
+    (custom-group-tag-1       :foreground blue)
+    (custom-set               :foreground yellow :background bg)
+    (custom-themed            :foreground yellow :background bg)
+    (custom-invalid           :foreground red :background (doom-blend red bg 0.2))
+    (custom-variable-obsolete :foreground grey :background bg)
+    (custom-state             :foreground green :background (doom-blend green bg 0.2))
+    (custom-changed           :foreground blue :background bg)
+
+    ;; dired
+    (dired-directory  :foreground builtin)
+    (dired-ignored    :foreground comments)
+    (dired-flagged    :foreground red)
+    (dired-header     :foreground blue :weight 'bold)
+    (dired-mark       :foreground orange :weight 'bold)
+    (dired-marked     :foreground magenta :weight 'bold)
+    (dired-perm-write :foreground fg :underline t)
+    (dired-symlink    :foreground cyan :weight 'bold)
+    (dired-warning    :foreground warning)
+
+    ;; ediff
+    (ediff-fine-diff-A    :background (doom-blend selection bg 0.7) :weight 'bold)
+    (ediff-fine-diff-B    :inherit 'ediff-fine-diff-A)
+    (ediff-fine-diff-C    :inherit 'ediff-fine-diff-A)
+    (ediff-current-diff-A :background (doom-blend selection bg 0.3))
+    (ediff-current-diff-B :inherit 'ediff-current-diff-A)
+    (ediff-current-diff-C :inherit 'ediff-current-diff-A)
+    (ediff-even-diff-A    :inherit 'hl-line)
+    (ediff-even-diff-B    :inherit 'ediff-even-diff-A)
+    (ediff-even-diff-C    :inherit 'ediff-even-diff-A)
+    (ediff-odd-diff-A     :inherit 'ediff-even-diff-A)
+    (ediff-odd-diff-B     :inherit 'ediff-odd-diff-A)
+    (ediff-odd-diff-C     :inherit 'ediff-odd-diff-A)
+
+    ;; elfeed
+    (elfeed-log-debug-level-face :foreground comments)
+    (elfeed-log-error-level-face :inherit 'error)
+    (elfeed-log-info-level-face  :inherit 'success)
+    (elfeed-log-warn-level-face  :inherit 'warning)
+    (elfeed-search-date-face     :foreground violet)
+    (elfeed-search-feed-face     :foreground blue)
+    (elfeed-search-tag-face      :foreground comments)
+    (elfeed-search-title-face    :foreground comments)
+    (elfeed-search-filter-face   :foreground violet)
+    (elfeed-search-unread-count-face :foreground yellow)
+    (elfeed-search-unread-title-face :foreground fg :weight 'bold)
+
+    ;; eshell
+    (eshell-prompt        :foreground highlight :weight 'bold)
+    (eshell-ls-archive    :foreground magenta)
+    (eshell-ls-backup     :foreground yellow)
+    (eshell-ls-clutter    :foreground red)
+    (eshell-ls-directory  :foreground blue)
+    (eshell-ls-executable :foreground green)
+    (eshell-ls-missing    :foreground red)
+    (eshell-ls-product    :foreground orange)
+    (eshell-ls-readonly   :foreground orange)
+    (eshell-ls-special    :foreground violet)
+    (eshell-ls-symlink    :foreground cyan)
+    (eshell-ls-unreadable :foreground base5)
+
+    ;; flx-ido
+    (flx-highlight-face :weight 'bold :foreground yellow :underline nil)
+
+    ;; hl-line
+    (hl-line :background bg-alt)
+
+    ;; ido
+    (ido-first-match :foreground orange)
+    (ido-indicator   :foreground red :background bg)
+    (ido-only-match  :foreground green)
+    (ido-subdir      :foreground violet)
+    (ido-virtual     :foreground comments)
+
+    ;; isearch
+    (isearch :background highlight :foreground base0 :weight 'bold)
+
+    ;; linum
+    ((linum &inherit line-number))
+
+    ;; message
+    (message-header-name       :foreground green)
+    (message-header-subject    :foreground highlight :weight 'bold)
+    (message-header-to         :foreground highlight :weight 'bold)
+    (message-header-cc         :inherit 'message-header-to :foreground (doom-darken highlight 0.15))
+    (message-header-other      :foreground violet)
+    (message-header-newsgroups :foreground yellow)
+    (message-header-xheader    :foreground doc-comments)
+    (message-separator         :foreground comments)
+    (message-mml               :foreground comments :slant 'italic)
+    (message-cited-text        :foreground magenta)
+
+    ;; term
+    (term               :foreground fg)
+    (term-bold          :weight 'bold)
+    (term-color-black   :background base0   :foreground base0)
+    (term-color-red     :background red     :foreground red)
+    (term-color-green   :background green   :foreground green)
+    (term-color-yellow  :background yellow  :foreground yellow)
+    (term-color-blue    :background blue    :foreground blue)
+    (term-color-magenta :background magenta :foreground magenta)
+    (term-color-cyan    :background cyan    :foreground cyan)
+    (term-color-white   :background base8   :foreground base8)
+
+    ;; window-divider
+    (window-divider :inherit 'vertical-border)
+    (window-divider-first-pixel :inherit 'window-divider)
+    (window-divider-last-pixel  :inherit 'window-divider)
+
+
+    ;; --- plugin faces -----------------------
+    ;; all-the-icons
+    (all-the-icons-red      :foreground red)
+    (all-the-icons-lred     :foreground (doom-lighten red 0.3))
+    (all-the-icons-dred     :foreground (doom-darken red 0.3))
+    (all-the-icons-green    :foreground green)
+    (all-the-icons-lgreen   :foreground (doom-lighten green 0.3))
+    (all-the-icons-dgreen   :foreground (doom-darken green 0.3))
+    (all-the-icons-yellow   :foreground yellow)
+    (all-the-icons-lyellow  :foreground (doom-lighten yellow 0.3))
+    (all-the-icons-dyellow  :foreground (doom-darken yellow 0.3))
+    (all-the-icons-blue     :foreground blue)
+    (all-the-icons-blue-alt :foreground teal)
+    (all-the-icons-lblue    :foreground (doom-lighten blue 0.3))
+    (all-the-icons-dblue    :foreground dark-blue)
+    (all-the-icons-maroon   :foreground magenta)
+    (all-the-icons-lmaroon  :foreground (doom-lighten magenta 0.3))
+    (all-the-icons-dmaroon  :foreground (doom-darken magenta 0.3))
+    (all-the-icons-purple   :foreground violet)
+    (all-the-icons-lpurple  :foreground (doom-lighten violet 0.3))
+    (all-the-icons-dpurple  :foreground (doom-darken violet 0.3))
+    (all-the-icons-cyan     :foreground cyan)
+    (all-the-icons-cyan-alt :foreground cyan)
+    (all-the-icons-lcyan    :foreground (doom-lighten cyan 0.3))
+    (all-the-icons-dcyan    :foreground dark-cyan)
+    (all-the-icons-pink     :foreground (doom-lighten red 0.35))
+    (all-the-icons-lpink    :foreground (doom-lighten red 0.55))
+    (all-the-icons-dpink    :foreground red)
+    (all-the-icons-silver   :foreground grey)
+    (all-the-icons-lsilver  :foreground (doom-lighten grey 0.3))
+    (all-the-icons-dsilver  :foreground (doom-darken grey 0.3))
+
+    ;; avy
+    (avy-background-face :foreground comments)
+    (avy-lead-face :background highlight :foreground bg :distant-foreground fg :weight 'bold)
+    (avy-lead-face-0
+     (&all   :inherit 'avy-lead-face)
+     (&dark  :background (doom-lighten highlight 0.3))
+     (&light :background (doom-darken highlight 0.3)))
+    (avy-lead-face-1
+     (&all   :inherit 'avy-lead-face)
+     (&dark  :background (doom-lighten highlight 0.6))
+     (&light :background (doom-darken highlight 0.6)))
+    (avy-lead-face-2
+     (&all   :inherit 'avy-lead-face)
+     (&dark  :background (doom-lighten highlight 0.9))
+     (&light :background (doom-darken highlight 0.9)))
+
+    ;; bookmark+
+    (bmkp-*-mark :foreground bg :background yellow)
+    (bmkp->-mark :foreground yellow)
+    (bmkp-D-mark :foreground bg :background red)
+    (bmkp-X-mark :foreground red)
+    (bmkp-a-mark :background red)
+    (bmkp-bad-bookmark :foreground bg :background yellow)
+    (bmkp-bookmark-file :foreground violet :background bg-alt)
+    (bmkp-bookmark-list :background bg-alt)
+    (bmkp-buffer :foreground blue)
+    (bmkp-desktop :foreground bg :background violet)
+    (bmkp-file-handler :background red)
+    (bmkp-function :foreground green)
+    (bmkp-gnus :foreground orange)
+    (bmkp-heading :foreground yellow)
+    (bmkp-info :foreground cyan)
+    (bmkp-light-autonamed :foreground bg-alt :background cyan)
+    (bmkp-light-autonamed-region :foreground bg-alt :background red)
+    (bmkp-light-fringe-autonamed :foreground bg-alt :background violet)
+    (bmkp-light-fringe-non-autonamed :foreground bg-alt :background green)
+    (bmkp-light-mark :foreground bg :background cyan)
+    (bmkp-light-non-autonamed :foreground bg :background violet)
+    (bmkp-light-non-autonamed-region :foreground bg :background red)
+    (bmkp-local-directory :foreground bg :background violet)
+    (bmkp-local-file-with-region :foreground yellow)
+    (bmkp-local-file-without-region :foreground comments)
+    (bmkp-man :foreground violet)
+    (bmkp-no-jump :foreground comments)
+    (bmkp-no-local :foreground yellow)
+    (bmkp-non-file :foreground green)
+    (bmkp-remote-file :foreground orange)
+    (bmkp-sequence :foreground blue)
+    (bmkp-su-or-sudo :foreground red)
+    (bmkp-t-mark :foreground violet)
+    (bmkp-url :foreground blue :underline t)
+    (bmkp-variable-list :foreground green)
+
+    ;; calfw
+    (cfw:face-title              :foreground blue                     :weight 'bold :height 2.0 :inherit 'variable-pitch)
+    (cfw:face-header             :foreground (doom-blend blue bg 0.8) :weight 'bold)
+    (cfw:face-sunday             :foreground (doom-blend red bg 0.8)  :weight 'bold)
+    (cfw:face-saturday           :foreground (doom-blend red bg 0.8)  :weight 'bold)
+    (cfw:face-holiday            :foreground nil :background bg-alt   :weight 'bold)
+    (cfw:face-grid               :foreground vertical-bar)
+    (cfw:face-periods            :foreground yellow)
+    (cfw:face-toolbar            :foreground nil :background nil)
+    (cfw:face-toolbar-button-off :foreground base6                    :weight 'bold             :inherit 'variable-pitch)
+    (cfw:face-toolbar-button-on  :foreground blue                     :weight 'bold             :inherit 'variable-pitch)
+    (cfw:face-default-content    :foreground fg)
+    (cfw:face-day-title          :foreground fg                       :weight 'bold)
+    (cfw:face-today-title        :foreground bg  :background blue     :weight 'bold)
+    (cfw:face-default-day                                             :weight 'bold)
+    (cfw:face-today              :foreground nil :background nil      :weight 'bold)
+    (cfw:face-annotation         :foreground violet)
+    (cfw:face-disable            :foreground grey)
+    (cfw:face-select             :background region)
+
+    ;; company
+    (company-tooltip            :inherit 'tooltip)
+    (company-tooltip-common                           :foreground highlight :distant-foreground base0 :weight 'bold)
+    (company-tooltip-search     :background highlight :foreground bg :distant-foreground fg :weight 'bold)
+    (company-tooltip-search-selection :background (doom-darken selection 0.25))
+    (company-tooltip-selection  :background selection :weight 'bold)
+    (company-tooltip-mouse      :background magenta   :foreground bg :distant-foreground fg)
+    (company-tooltip-annotation                       :foreground violet :distant-foreground bg)
+    (company-scrollbar-bg       :inherit 'tooltip)
+    (company-scrollbar-fg       :background highlight)
+    (company-preview                              :foreground comments)
+    (company-preview-common     :background base3 :foreground highlight)
+    (company-preview-search     :inherit 'company-tooltip-search)
+    (company-template-field     :inherit 'match)
+
+    ;; company-box
+    (company-box-candidate :foreground fg)
+
+    ;; circe
+    (circe-fool :foreground doc-comments)
+    (circe-highlight-nick-face :weight 'bold :foreground constants)
+    (circe-prompt-face :weight 'bold :foreground highlight)
+    (circe-server-face :foreground comments)
+    (circe-my-message-face :weight 'bold)
+
+    ;; diff-hl
+    (diff-hl-change :foreground vc-modified)
+    (diff-hl-delete :foreground vc-deleted)
+    (diff-hl-insert :foreground vc-added)
+
+    ;; diff-mode
+    (diff-added   :inherit 'hl-line :foreground green)
+    (diff-changed :foreground violet)
+    (diff-context
+     (&dark  :foreground (doom-darken fg 0.12))
+     (&light :foreground (doom-lighten fg 0.12)))
+    (diff-removed :foreground red :background base3)
+    (diff-header  :foreground cyan :background nil)
+    (diff-file-header :foreground blue :background nil)
+    (diff-hunk-header :foreground violet)
+    (diff-refine-added   :inherit 'diff-added :inverse-video t)
+    (diff-refine-changed :inherit 'diff-changed :inverse-video t)
+    (diff-refine-removed :inherit 'diff-removed :inverse-video t)
+
+    ;; dired+
+    (diredp-file-name              :foreground base8)
+    (diredp-dir-name               :foreground base8 :weight 'bold)
+    (diredp-ignored-file-name      :foreground base5)
+    (diredp-compressed-file-suffix :foreground base5)
+    (diredp-symlink                :foreground violet)
+    (diredp-dir-heading            :foreground blue  :weight 'bold)
+    (diredp-file-suffix            :foreground violet)
+    (diredp-read-priv              :foreground magenta)
+    (diredp-write-priv             :foreground green)
+    (diredp-exec-priv              :foreground yellow)
+    (diredp-rare-priv              :foreground red   :weight 'bold)
+    (diredp-dir-priv               :foreground blue  :weight 'bold)
+    (diredp-no-priv                :foreground base5)
+    (diredp-number                 :foreground magenta)
+    (diredp-date-time              :foreground blue)
+
+    ;; dired-k
+    (dired-k-directory :foreground blue)
+
+    ;; dired-subtree
+    (dired-subtree-depth-1-face :background (doom-darken bg-alt 0.02))
+    (dired-subtree-depth-2-face :background (doom-darken bg-alt 0.04))
+    (dired-subtree-depth-3-face :background (doom-darken bg-alt 0.06))
+    (dired-subtree-depth-4-face :background (doom-darken bg-alt 0.08))
+    (dired-subtree-depth-5-face :background (doom-darken bg-alt 0.10))
+    (dired-subtree-depth-6-face :background (doom-darken bg-alt 0.12))
+
+    ;; diredfl
+    (diredfl-autofile-name          :foreground base4 :background bg-alt)
+    (diredfl-compressed-file-name   :foreground yellow :background bg-alt)
+    (diredfl-compressed-file-suffix :foreground (doom-blend orange bg-alt 0.6) :background bg-alt)
+    (diredfl-date-time              :foreground cyan :background bg-alt :weight 'light)
+    (diredfl-deletion               :foreground red :background (doom-blend red bg-alt 0.2) :weight 'bold)
+    (diredfl-deletion-file-name     :foreground red :background (doom-blend red bg-alt 0.2))
+    (diredfl-dir-heading            :foreground blue :background bg-alt :weight 'bold)
+    (diredfl-dir-name               :foreground blue :background bg-alt)
+    (diredfl-dir-priv               :foreground blue :background bg-alt)
+    (diredfl-exec-priv              :foreground green :background bg-alt)
+    (diredfl-executable-tag         :foreground green :background bg-alt)
+    (diredfl-file-name              :foreground fg :background bg-alt)
+    (diredfl-file-suffix            :foreground (doom-blend fg bg-alt 0.6) :background bg-alt)
+    (diredfl-flag-mark              :foreground yellow :background (doom-blend yellow bg-alt 0.2) :weight 'bold)
+    (diredfl-flag-mark-line         :background (doom-blend yellow bg-alt 0.1))
+    (diredfl-ignored-file-name      :foreground comments :background bg-alt)
+    (diredfl-link-priv              :foreground violet :background bg-alt)
+    (diredfl-no-priv                :foreground fg :background bg-alt)
+    (diredfl-number                 :foreground orange :background bg-alt)
+    (diredfl-other-priv             :foreground magenta :background bg-alt)
+    (diredfl-rare-priv              :foreground fg :background bg-alt)
+    (diredfl-read-priv              :foreground yellow :background bg-alt)
+    (diredfl-symlink                :foreground violet :background bg-alt)
+    (diredfl-tagged-autofile-name   :foreground base5 :background bg-alt)
+    (diredfl-write-priv             :foreground red :background bg-alt)
+
+    ;; elscreen
+    (elscreen-tab-background-face     :background bg)
+    (elscreen-tab-control-face        :background bg     :foreground bg)
+    (elscreen-tab-current-screen-face :background bg-alt :foreground fg)
+    (elscreen-tab-other-screen-face   :background bg     :foreground fg-alt)
+
+    ;; erc
+    (erc-button :weight 'bold :underline t)
+    (erc-default-face :inherit 'default)
+    (erc-action-face  :weight 'bold)
+    (erc-command-indicator-face :weight 'bold)
+    (erc-direct-msg-face :foreground magenta)
+    (erc-error-face :inherit 'error)
+    (erc-header-line :background (doom-darken bg-alt 0.15) :foreground highlight)
+    (erc-input-face :foreground green)
+    (erc-current-nick-face :foreground green :weight 'bold)
+    (erc-timestamp-face :foreground blue :weight 'bold)
+    (erc-nick-default-face :weight 'bold)
+    (erc-nick-msg-face :foreground magenta)
+    (erc-nick-prefix-face :inherit 'erc-nick-default-face)
+    (erc-my-nick-face :foreground green :weight 'bold)
+    (erc-my-nick-prefix-face :inherit 'erc-my-nick-face)
+    (erc-notice-face :foreground comments)
+    (erc-prompt-face :foreground highlight :weight 'bold)
+
+    ;; evil
+    (evil-ex-info                   :foreground error :slant 'italic)
+    (evil-ex-substitute-matches     :background base0 :foreground red   :strike-through t :weight 'bold)
+    (evil-ex-substitute-replacement :background base0 :foreground green :weight 'bold)
+    (evil-search-highlight-persist-highlight-face :inherit 'lazy-highlight)
+
+    ;; evil-mc
+    (evil-mc-cursor-default-face :background magenta :foreground base0 :inverse-video nil)
+    (evil-mc-region-face :inherit 'region)
+    (evil-mc-cursor-bar-face :height 1 :background magenta :foreground base0)
+    (evil-mc-cursor-hbar-face :underline `(:color ,highlight))
+
+    ;; evil-snipe
+    (evil-snipe-first-match-face :foreground highlight :background dark-blue :weight 'bold)
+    (evil-snipe-matches-face     :foreground highlight :underline t :weight 'bold)
+
+    ;; evil-googles
+    (evil-goggles-default-face :inherit 'region)
+
+    ;; flycheck
+    (flycheck-error     :underline `(:style wave :color ,red))
+    (flycheck-warning   :underline `(:style wave :color ,yellow))
+    (flycheck-info      :underline `(:style wave :color ,green))
+
+    ;; flycheck-posframe
+    (flycheck-posframe-face :inherit 'default)
+    (flycheck-posframe-background-face :background bg-alt)
+    (flycheck-posframe-error-face   :inherit 'flycheck-posframe-face :foreground error)
+    (flycheck-posframe-info-face    :inherit 'flycheck-posframe-face :foreground fg)
+    (flycheck-posframe-warning-face :inherit 'flycheck-posframe-face :foreground warning)
+
+    ;; flymake
+    (flymake-error   :underline `(:style wave :color ,red))
+    (flymake-note    :underline `(:style wave :color ,green))
+    (flymake-warning :underline `(:style wave :color ,orange))
+
+    ;; flyspell
+    (flyspell-incorrect :underline `(:style wave :color ,error) :inherit 'unspecified)
+
+    ;; git-commit
+    (git-commit-summary :foreground strings)
+    (git-commit-overlong-summary :inherit 'error :background base0 :slant 'italic :weight 'bold)
+    (git-commit-nonempty-second-line :inherit 'git-commit-overlong-summary)
+    (git-commit-note :foreground cyan :slant 'italic)
+    (git-commit-pseudo-header :foreground doc-comments :slant 'italic)
+    (git-commit-known-pseudo-header :foreground doc-comments :weight 'bold :slant 'italic)
+    (git-commit-comment-branch-local :foreground magenta)
+    (git-commit-comment-branch-remote :foreground green)
+    (git-commit-comment-detached :foreground orange)
+    (git-commit-comment-heading :foreground keywords)
+    (git-commit-comment-file :foreground violet)
+    (git-commit-comment-action)
+
+    ;; git-gutter
+    (git-gutter:modified :foreground vc-modified)
+    (git-gutter:added    :foreground vc-added)
+    (git-gutter:deleted  :foreground vc-deleted)
+
+    ;; git-gutter+
+    (git-gutter+-modified :foreground vc-modified :background nil)
+    (git-gutter+-added    :foreground vc-added :background nil)
+    (git-gutter+-deleted  :foreground vc-deleted :background nil)
+
+    ;; git-gutter-fringe
+    ((git-gutter-fr:modified &inherit git-gutter:modified))
+    ((git-gutter-fr:added    &inherit git-gutter:added))
+    ((git-gutter-fr:deleted  &inherit git-gutter:deleted))
+
+    ;; gnus
+    (gnus-group-mail-1           :weight 'bold :foreground fg)
+    (gnus-group-mail-2           :inherit 'gnus-group-mail-1)
+    (gnus-group-mail-3           :inherit 'gnus-group-mail-1)
+    (gnus-group-mail-1-empty     :foreground base5)
+    (gnus-group-mail-2-empty     :inherit 'gnus-group-mail-1-empty)
+    (gnus-group-mail-3-empty     :inherit 'gnus-group-mail-1-empty)
+    (gnus-group-news-1           :inherit 'gnus-group-mail-1)
+    (gnus-group-news-2           :inherit 'gnus-group-news-1)
+    (gnus-group-news-3           :inherit 'gnus-group-news-1)
+    (gnus-group-news-4           :inherit 'gnus-group-news-1)
+    (gnus-group-news-5           :inherit 'gnus-group-news-1)
+    (gnus-group-news-6           :inherit 'gnus-group-news-1)
+    (gnus-group-news-1-empty     :inherit 'gnus-group-mail-1-empty)
+    (gnus-group-news-2-empty     :inherit 'gnus-groupnews-1-empty)
+    (gnus-group-news-3-empty     :inherit 'gnus-groupnews-1-empty)
+    (gnus-group-news-4-empty     :inherit 'gnus-groupnews-1-empty)
+    (gnus-group-news-5-empty     :inherit 'gnus-groupnews-1-empty)
+    (gnus-group-news-6-empty     :inherit 'gnus-groupnews-1-empty)
+    (gnus-group-mail-low         :inherit 'gnus-group-mail-1 :weight 'normal)
+    (gnus-group-mail-low-empty   :inherit 'gnus-group-mail-1-empty)
+    (gnus-group-news-low         :inherit 'gnus-group-mail-1 :foreground base5)
+    (gnus-group-news-low-empty   :inherit 'gnus-group-news-low :weight 'normal)
+    (gnus-header-content         :inherit 'message-header-other)
+    (gnus-header-from            :inherit 'message-header-other)
+    (gnus-header-name            :inherit 'message-header-name)
+    (gnus-header-newsgroups      :inherit 'message-header-other)
+    (gnus-header-subject         :inherit 'message-header-subject)
+    (gnus-summary-cancelled      :foreground red :strike-through t)
+    (gnus-summary-high-ancient   :foreground (doom-lighten base5 0.2) :inherit 'italic)
+    (gnus-summary-high-read      :foreground (doom-lighten fg 0.2))
+    (gnus-summary-high-ticked    :foreground (doom-lighten magenta 0.2))
+    (gnus-summary-high-unread    :foreground (doom-lighten green 0.2))
+    (gnus-summary-low-ancient    :foreground (doom-darken base5 0.2) :inherit 'italic)
+    (gnus-summary-low-read       :foreground (doom-darken fg 0.2))
+    (gnus-summary-low-ticked     :foreground (doom-darken magenta 0.2))
+    (gnus-summary-low-unread     :foreground (doom-darken green 0.2))
+    (gnus-summary-normal-ancient :foreground base5 :inherit 'italic)
+    (gnus-summary-normal-read    :foreground fg)
+    (gnus-summary-normal-ticked  :foreground magenta)
+    (gnus-summary-normal-unread  :foreground green :inherit 'bold)
+    (gnus-summary-selected       :foreground blue :weight 'bold)
+    (gnus-cite-1                 :foreground violet)
+    (gnus-cite-2                 :foreground violet)
+    (gnus-cite-3                 :foreground violet)
+    (gnus-cite-4                 :foreground green)
+    (gnus-cite-5                 :foreground green)
+    (gnus-cite-6                 :foreground green)
+    (gnus-cite-7                 :foreground magenta)
+    (gnus-cite-8                 :foreground magenta)
+    (gnus-cite-9                 :foreground magenta)
+    (gnus-cite-10                :foreground yellow)
+    (gnus-cite-11                :foreground yellow)
+    (gnus-signature              :foreground yellow)
+    (gnus-x-face                 :background base5 :foreground fg)
+
+    ;; helm
+    (helm-selection
+     (&all :inherit 'bold :background selection)
+     (&dark  :distant-foreground highlight)
+     (&light :distant-foreground base0))
+    (helm-match :foreground highlight :distant-foreground base8 :underline t)
+    (helm-source-header          :background base2 :foreground base5)
+    (helm-swoop-target-line-face :foreground highlight :inverse-video t)
+    (helm-visible-mark           :inherit '(bold highlight))
+    (helm-ff-file                :foreground fg)
+    (helm-ff-prefix              :foreground keywords)
+    (helm-ff-dotted-directory    :foreground grey)
+    (helm-ff-directory           :foreground variables)
+    (helm-ff-executable          :foreground base8 :inherit 'italic)
+    (helm-grep-match             :foreground highlight :distant-foreground red)
+    (helm-grep-file              :foreground methods)
+    (helm-grep-lineno            :foreground base5)
+    (helm-grep-finish            :foreground green)
+    (helm-swoop-target-line-face       :foreground highlight :inverse-video t)
+    (helm-swoop-target-line-block-face :foreground yellow)
+    (helm-swoop-target-word-face       :foreground green :inherit 'bold)
+    (helm-swoop-target-number-face     :foreground base5)
+
+    ;; helpful
+    (helpful-heading :weight 'bold :height 1.2)
+
+    ;; hideshow
+    (+doom-folded-face :inherit 'font-lock-comment-face
+                       :weight 'light
+                       :background (doom-darken bg 0.125))
+
+    ;; highlight-indentation-mode
+    (highlight-indentation-face                :inherit 'hl-line)
+    (highlight-indentation-current-column-face :background base1)
+    (highlight-indentation-guides-odd-face     :inherit 'highlight-indentation-face)
+    (highlight-indentation-guides-even-face    :inherit 'highlight-indentation-face)
+
+    ;; highlight-quoted-mode
+    (highlight-quoted-symbol :foreground type)
+    (highlight-quoted-quote  :foreground operators)
+
+    ;; highlight-numbers-mode
+    (highlight-numbers-number :inherit 'bold :foreground numbers)
+
+    ;; hlinum
+    (linum-highlight-face :foreground fg :distant-foreground nil :weight 'normal)
+
+    ;; hl-todo
+    (hl-todo :foreground red :weight 'bold)
+
+    ;; hydra
+    (hydra-face-red      :foreground red     :weight 'bold)
+    (hydra-face-blue     :foreground blue    :weight 'bold)
+    (hydra-face-amaranth :foreground magenta :weight 'bold)
+    (hydra-face-pink     :foreground violet  :weight 'bold)
+    (hydra-face-teal     :foreground teal    :weight 'bold)
+
+    ;; iedit
+    (iedit-occurrence :foreground magenta :weight 'bold :inverse-video t)
+    (iedit-read-only-occurrence :inherit 'region)
+
+    ;; imenu-list
+    ;; (imenu-list-entry-face)
+    (imenu-list-entry-face-0 :foreground highlight)
+    (imenu-list-entry-subalist-face-0 :inherit 'imenu-list-entry-face-0 :weight 'bold)
+    (imenu-list-entry-face-1 :foreground green)
+    (imenu-list-entry-subalist-face-1 :inherit 'imenu-list-entry-face-1 :weight 'bold)
+    (imenu-list-entry-face-2 :foreground yellow)
+    (imenu-list-entry-subalist-face-2 :inherit 'imenu-list-entry-face-2 :weight 'bold)
+
+    ;; indent-guide
+    ((indent-guide-face &inherit highlight-indentation-face))
+
+    ;; ivy
+    (ivy-current-match :background region :distant-foreground nil)
+    (ivy-minibuffer-match-face-1
+     :background nil
+     :foreground (doom-lighten grey 0.14)
+     :weight 'light)
+    (ivy-minibuffer-match-face-2
+     :inherit 'ivy-minibuffer-match-face-1
+     :foreground magenta :background base1 :weight 'semi-bold)
+    (ivy-minibuffer-match-face-3
+     :inherit 'ivy-minibuffer-match-face-2
+     :foreground green :weight 'semi-bold)
+    (ivy-minibuffer-match-face-4
+     :inherit 'ivy-minibuffer-match-face-2
+     :foreground yellow :weight 'semi-bold)
+    (ivy-minibuffer-match-highlight :foreground violet)
+    (ivy-highlight-face :foreground violet)
+    (ivy-confirm-face :foreground success)
+    (ivy-match-required-face :foreground error)
+    (ivy-virtual :inherit 'italic :foreground doc-comments)
+    (ivy-modified-buffer :inherit 'bold :foreground vc-modified)
+
+    ;; ivy-posframe
+    (ivy-posframe :background (doom-darken bg-alt 0.2))
+
+    ;; jabber
+    (jabber-activity-face          :foreground red   :weight 'bold)
+    (jabber-activity-personal-face :foreground blue  :weight 'bold)
+    (jabber-chat-error             :foreground red   :weight 'bold)
+    (jabber-chat-prompt-foreign    :foreground red   :weight 'bold)
+    (jabber-chat-prompt-local      :foreground blue  :weight 'bold)
+    (jabber-chat-prompt-system     :foreground green :weight 'bold)
+    (jabber-chat-text-foreign      :foreground fg)
+    (jabber-chat-text-local        :foreground fg)
+    (jabber-rare-time-face         :foreground green)
+    (jabber-roster-user-away       :foreground yellow)
+    (jabber-roster-user-chatty     :foreground green :weight 'bold)
+    (jabber-roster-user-dnd        :foreground red)
+    (jabber-roster-user-error      :foreground red)
+    (jabber-roster-user-offline    :foreground fg)
+    (jabber-roster-user-online     :foreground green :weight 'bold)
+    (jabber-roster-user-xa         :foreground cyan)
+
+    ;; linum-relative
+    ((linum-relative-current-face &inherit line-number-current-line))
+
+    ;; lui
+    (lui-time-stamp-face :foreground violet)
+    (lui-highlight-face :foreground highlight)
+    (lui-button-face :foreground builtin :underline t)
+
+    ;; multiple cursors
+    (mc/cursor-face :inherit 'cursor)
+
+    ;; nav-flash
+    (nav-flash-face :background selection :foreground base8 :weight 'bold)
+
+    ;; neotree
+    (neo-root-dir-face   :foreground strings :background bg :box `(:line-width 4 :color ,bg))
+    (neo-file-link-face  :foreground fg)
+    (neo-dir-link-face   :foreground highlight)
+    (neo-expand-btn-face :foreground highlight)
+    (neo-vc-edited-face  :foreground yellow)
+    (neo-vc-added-face   :foreground green)
+    (neo-vc-removed-face :foreground red :strike-through t)
+    (neo-vc-conflict-face :foreground magenta :weight 'bold)
+    (neo-vc-ignored-face  :foreground comments)
+    (doom-neotree-dir-face :foreground highlight)
+    (doom-neotree-file-face :foreground base8)
+    (doom-neotree-hidden-file-face :foreground comments)
+    (doom-neotree-text-file-face :foreground fg)
+    (doom-neotree-data-file-face :foreground violet)
+    (doom-neotree-media-file-face :inherit 'doom-neotree-hidden-file-face)
+
+    ;; nlinum
+    ((nlinum-current-line &inherit line-number-current-line))
+
+    ;; nlinum-hl
+    ((nlinum-hl-face &inherit line-number-current-line))
+
+    ;; nlinum-relative
+    ((nlinum-relative-current-face &inherit line-number-current-line))
+
+    ;; lsp
+    ;; TODO Add light versions
+    (lsp-face-highlight-textual :background dark-blue :foreground base8 :distant-foreground base0 :weight 'bold)
+    (lsp-face-highlight-read    :background dark-blue :foreground base8 :distant-foreground base0 :weight 'bold)
+    (lsp-face-highlight-write   :background dark-blue :foreground base8 :distant-foreground base0 :weight 'bold)
+    (lsp-ui-peek-filename :inherit 'doom-modeline-buffer-file)
+    (lsp-ui-peek-header :foreground fg :background (doom-lighten bg 0.1) :bold bold)
+    (lsp-ui-peek-selection :foreground bg :background blue :bold bold)
+    (lsp-ui-peek-list :background (doom-darken bg 0.1))
+    (lsp-ui-peek-peek :background (doom-darken bg 0.1))
+    (lsp-ui-peek-highlight :inherit 'lsp-ui-peek-header :background region :foreground bg :box t)
+    (lsp-ui-peek-line-number :foreground success)
+
+    ;; magit
+    (magit-bisect-bad        :foreground red)
+    (magit-bisect-good       :foreground green)
+    (magit-bisect-skip       :foreground orange)
+    (magit-blame-date        :foreground red)
+    (magit-blame-heading     :foreground orange :background base3)
+    (magit-branch-current    :foreground blue)
+    (magit-branch-local      :foreground cyan)
+    (magit-branch-remote     :foreground green)
+    (magit-cherry-equivalent :foreground violet)
+    (magit-cherry-unmatched  :foreground cyan)
+    (magit-diff-added             :foreground (doom-darken green 0.2)  :background (doom-blend green bg 0.1))
+    (magit-diff-added-highlight   :foreground green                    :background (doom-blend green bg 0.2) :weight 'bold)
+    (magit-diff-base              :foreground (doom-darken orange 0.2) :background (doom-blend orange bg 0.1))
+    (magit-diff-base-highlight    :foreground orange                   :background (doom-blend orange bg 0.2) :weight 'bold)
+    (magit-diff-context           :foreground (doom-darken fg 0.4) :background bg)
+    (magit-diff-context-highlight :foreground fg                   :background bg-alt)
+    (magit-diff-file-heading           :foreground fg :weight 'bold)
+    (magit-diff-file-heading-selection :foreground magenta               :background dark-blue :weight 'bold)
+    (magit-diff-hunk-heading           :foreground bg                    :background (doom-blend violet bg 0.3))
+    (magit-diff-hunk-heading-highlight :foreground bg                    :background violet :weight 'bold)
+    (magit-diff-removed                :foreground (doom-darken red 0.2) :background (doom-blend red base3 0.1))
+    (magit-diff-removed-highlight      :foreground red                   :background (doom-blend red base3 0.2) :weight 'bold)
+    (magit-diff-lines-heading          :foreground yellow     :background red)
+    (magit-diffstat-added              :foreground green)
+    (magit-diffstat-removed            :foreground red)
+    (magit-dimmed :foreground comments)
+    (magit-hash :foreground comments)
+    (magit-header-line :background dark-blue :foreground base8 :weight 'bold
+                       :box `(:line-width 3 :color ,dark-blue))
+    (magit-log-author :foreground orange)
+    (magit-log-date :foreground blue)
+    (magit-log-graph :foreground comments)
+    (magit-process-ng :inherit 'error)
+    (magit-process-ok :inherit 'success)
+    (magit-reflog-amend :foreground magenta)
+    (magit-reflog-checkout :foreground blue)
+    (magit-reflog-cherry-pick :foreground green)
+    (magit-reflog-commit :foreground green)
+    (magit-reflog-merge :foreground green)
+    (magit-reflog-other :foreground cyan)
+    (magit-reflog-rebase :foreground magenta)
+    (magit-reflog-remote :foreground cyan)
+    (magit-reflog-reset :inherit 'error)
+    (magit-refname :foreground comments)
+    (magit-section-heading           :foreground blue :weight 'bold)
+    (magit-section-heading-selection :foreground orange :weight 'bold)
+    (magit-section-highlight :inherit 'hl-line)
+    (magit-sequence-drop :foreground red)
+    (magit-sequence-head :foreground blue)
+    (magit-sequence-part :foreground orange)
+    (magit-sequence-stop :foreground green)
+    (magit-signature-bad :inherit 'error)
+    (magit-signature-error :inherit 'error)
+    (magit-signature-expired :foreground orange)
+    (magit-signature-good :inherit 'success)
+    (magit-signature-revoked :foreground magenta)
+    (magit-signature-untrusted :foreground yellow)
+    (magit-tag :foreground yellow)
+    (magit-filename :foreground violet)
+    (magit-section-secondary-heading :foreground violet :weight 'bold)
+
+    ;; mic-paren
+    (paren-face-match    :foreground red   :background base0 :weight 'ultra-bold)
+    (paren-face-mismatch :foreground base0 :background red   :weight 'ultra-bold)
+    (paren-face-no-match :inherit 'paren-face-mismatch :weight 'ultra-bold)
+
+    ;; parenface
+    (paren-face :foreground comments)
+
+    ;; perspective
+    (persp-selected-face :foreground blue :weight 'bold)
+
+    ;; persp-mode
+    (persp-face-lighter-buffer-not-in-persp :foreground warning :slant 'italic)
+    (persp-face-lighter-nil-persp :foreground comments)
+
+    ;; popup
+    (popup-face :inherit 'tooltip)
+    (popup-tip-face :inherit 'popup-face :foreground violet :background base0)
+    (popup-selection-face :background selection)
+
+    ;; rainbow-delimiters
+    (rainbow-delimiters-depth-1-face :foreground blue)
+    (rainbow-delimiters-depth-2-face :foreground magenta)
+    (rainbow-delimiters-depth-3-face :foreground green)
+    (rainbow-delimiters-depth-4-face :foreground orange)
+    (rainbow-delimiters-depth-5-face :foreground violet)
+    (rainbow-delimiters-depth-6-face :foreground yellow)
+    (rainbow-delimiters-depth-7-face :foreground teal)
+    (rainbow-delimiters-unmatched-face  :foreground red :weight 'bold :inverse-video t)
+    (rainbow-delimiters-mismatched-face :inherit 'rainbow-delimiters-unmatched-face)
+
+    ;; re-builder
+    (reb-match-0 :foreground orange  :inverse-video t)
+    (reb-match-1 :foreground magenta :inverse-video t)
+    (reb-match-2 :foreground green   :inverse-video t)
+    (reb-match-3 :foreground yellow  :inverse-video t)
+
+    ;; show-paren
+    ((show-paren-match &inherit paren-face-match))
+    ((show-paren-mismatch &inherit paren-face-mismatch))
+
+    ;; smartparens
+    (sp-pair-overlay-face :background region)
+
+    ;; smartparens
+    ((sp-show-pair-match-face    &inherit show-paren-match))
+    ((sp-show-pair-mismatch-face &inherit show-paren-mismatch))
+
+    ;; smerge-tool
+    (smerge-lower :background (doom-blend green bg 0.2))
+    (smerge-upper :background (doom-blend red base3 0.2))
+    (smerge-base  :background (doom-blend blue bg 0.2))
+    (smerge-markers :background comments :foreground bg :distant-foreground fg :weight 'bold)
+    ;; Emacs <25 compatibility
+    ((smerge-mine  &inherit smerge-upper))
+    ((smerge-other &inherit smerge-lower))
+
+    ;; solaire-mode
+    (solaire-default-face  :inherit 'default :background bg-alt)
+    (solaire-hl-line-face  :inherit 'hl-line :background bg)
+    (solaire-org-hide-face :foreground bg-alt)
+
+    ;; stripe-buffer
+    (stripe-highlight
+     (&light :background base5)
+     (&dark  :background base3))
+
+    ;; swiper
+    (swiper-line-face    :background blue    :foreground base0)
+    (swiper-match-face-1 :inherit 'unspecified :background base0   :foreground base5)
+    (swiper-match-face-2 :inherit 'unspecified :background orange  :foreground base0 :weight 'bold)
+    (swiper-match-face-3 :inherit 'unspecified :background magenta :foreground base0 :weight 'bold)
+    (swiper-match-face-4 :inherit 'unspecified :background green   :foreground base0 :weight 'bold)
+
+    ;; tabbar
+    (tabbar-default             :foreground bg :background bg :height 1.0)
+    (tabbar-highlight           :foreground fg :background selection :distant-foreground bg)
+    (tabbar-button              :foreground fg :background bg)
+    (tabbar-button-highlight    :inherit 'tabbar-button :inverse-video t)
+    (tabbar-modified            :inherit 'tabbar-default :foreground red :weight 'bold)
+    (tabbar-unselected          :inherit 'tabbar-default :foreground base5)
+    (tabbar-unselected-modified :inherit 'tabbar-modified)
+    (tabbar-selected
+     :inherit 'tabbar-default :weight 'bold
+     :foreground fg :background bg-alt)
+    (tabbar-selected-modified :inherit 'tabbar-selected :foreground green)
+
+    ;; tldr
+    (tldr-command-itself   :foreground bg :background green :weight 'semi-bold)
+    (tldr-title            :foreground yellow :bold t :height 1.4)
+    (tldr-description      :foreground fg :weight 'semi-bold)
+    (tldr-introduction     :foreground (doom-blend blue bg 0.8) :weight 'semi-bold)
+    (tldr-code-block       :foreground green :background region :weight 'semi-bold)
+    (tldr-command-argument :foreground fg :background region )
+
+    ;; treemacs
+    (treemacs-root-face :inherit 'font-lock-string-face :weight 'bold :height 1.2)
+    (treemacs-file-face :foreground fg)
+    (treemacs-directory-face :foreground fg)
+    (treemacs-tags-face :foreground highlight)
+    (treemacs-git-modified-face :foreground violet)
+    (treemacs-git-added-face :foreground green)
+    (treemacs-git-conflict-face :foreground red)
+    (treemacs-git-untracked-face :inherit 'font-lock-doc-face)
+
+    ;; twittering-mode
+    (twitter-divider  ; custom face in Doom Emacs
+     (&light :underline '(:color (doom-lighten vertical-bar 0.2)))
+     (&dark  :underline '(:color (doom-darken vertical-bar 0.2))))
+
+    ;; undo-tree
+    (undo-tree-visualizer-default-face :foreground base5)
+    (undo-tree-visualizer-current-face :foreground green :weight 'bold)
+    (undo-tree-visualizer-unmodified-face :foreground base5)
+    (undo-tree-visualizer-active-branch-face :foreground blue)
+    (undo-tree-visualizer-register-face :foreground yellow)
+
+    ;; vimish-fold
+    (vimish-fold-overlay :inherit 'font-lock-comment-face :background base0 :weight 'light)
+    (vimish-fold-fringe  :foreground magenta)
+
+    ;; volatile-highlights
+    (vhl/default-face :background grey)
+
+    ;; wgrep
+    (wgrep-face :weight 'bold :foreground green :background base5)
+    (wgrep-delete-face :foreground base3 :background red)
+    (wgrep-done-face   :foreground blue)
+    (wgrep-file-face   :foreground comments)
+    (wgrep-reject-face :foreground red :weight 'bold)
+
+    ;; which-func
+    (which-func :foreground blue)
+
+    ;; which-key
+    (which-key-key-face                   :foreground green)
+    (which-key-group-description-face     :foreground violet)
+    (which-key-command-description-face   :foreground blue)
+    (which-key-local-map-description-face :foreground magenta)
+
+    ;; whitespace
+    (whitespace-empty    :background base3)
+    (whitespace-space    :foreground base4)
+    (whitespace-tab      :foreground base4 :background (unless indent-tabs-mode base3))
+    (whitespace-newline  :foreground base4)
+    (whitespace-indentation :foreground red :background yellow)
+    (whitespace-trailing :inherit 'trailing-whitespace)
+    (whitespace-line     :background base0 :foreground red :weight 'bold)
+
+    ;; workgroups2
+    (wg-current-workgroup-face :foreground base0 :background highlight)
+    (wg-other-workgroup-face   :foreground base5)
+    (wg-divider-face           :foreground grey)
+    (wg-brace-face             :foreground highlight)
+
+    ;; yasnippet
+    (yas-field-highlight-face :inherit 'match)
+
+
+    ;; --- major-mode faces -------------------
+    ;; auctex (latex-mode)
+    (font-latex-bold-face         :inherit 'bold)
+    (font-latex-italic-face       :inherit 'italic)
+    (font-latex-math-face         :foreground blue)
+    (font-latex-sectioning-0-face :foreground blue    :weight 'ultra-bold :height 1.4)
+    (font-latex-sectioning-1-face :foreground magenta :weight 'semi-bold  :height 1.2)
+    (font-latex-sectioning-2-face :foreground violet  :weight 'semi-bold)
+    (font-latex-sectioning-3-face :foreground (doom-lighten blue 0.3)    :weight 'semi-bold)
+    (font-latex-sectioning-4-face :foreground (doom-lighten magenta 0.3) :weight 'semi-bold)
+    (font-latex-sectioning-5-face :foreground (doom-lighten violet 0.3)  :weight 'semi-bold)
+    (font-latex-script-char-face  :foreground dark-blue)
+    (font-latex-string-face       :inherit 'font-lock-string-face)
+    (font-latex-warning-face      :inherit 'font-lock-warning-face)
+    (font-latex-verbatim-face     :inherit 'fixed-pitch :foreground violet :slant 'italic)
+
+    ;; elixir-mode
+    (elixir-atom-face (&light :foreground dark-blue)
+                      (&dark  :foreground cyan))
+    (elixir-attribute-face :foreground violet)
+
+    ;; enh-ruby-mode
+    (enh-ruby-op-face :foreground operators)
+    (enh-ruby-string-delimiter-face  :inherit 'font-lock-string-face)
+    (enh-ruby-heredoc-delimiter-face :inherit 'font-lock-string-face)
+    (enh-ruby-regexp-face :foreground constants)
+    (enh-ruby-regexp-delimiter-face  :inherit 'enh-ruby-regexp-face)
+    (erm-syn-errline  :underline `(:style wave :color ,error))
+    (erm-syn-warnline :underline `(:style wave :color ,warning))
+
+    ;; jdee-mode
+    (jdee-font-lock-number-face :foreground numbers)
+    (jdee-font-lock-operator-face :foreground operators)
+    (jdee-font-lock-constant-face :inherit 'font-lock-constant-face)
+    (jdee-font-lock-constructor-face :foreground methods)
+    (jdee-font-lock-public-face :inherit 'font-lock-keyword-face)
+    (jdee-font-lock-protected-face :inherit 'font-lock-keyword-face)
+    (jdee-font-lock-private-face :inherit 'font-lock-keyword-face)
+    (jdee-font-lock-modifier-face :inherit 'font-lock-type-face)
+    (jdee-font-lock-doc-tag-face :foreground violet)
+    (jdee-font-lock-italic-face :inherit 'italic)
+    (jdee-font-lock-bold-face :inherit 'bold)
+    (jdee-font-lock-link-face :foreground blue :italic nil :underline t)
+
+    ;; js2-mode
+    (js2-function-param  :foreground variables)
+    (js2-function-call   :foreground functions)
+    (js2-object-property :foreground violet)
+    (js2-jsdoc-tag       :foreground doc-comments)
+
+    ;; ledger-mode
+    (ledger-font-posting-date-face :foreground blue)
+    (ledger-font-posting-amount-face :foreground yellow)
+    (ledger-font-posting-account-face :foreground base8)
+    (ledger-font-payee-cleared-face :foreground violet :weight 'bold :height 1.2)
+    (ledger-font-payee-uncleared-face :foreground base5 :weight 'bold :height 1.2)
+    (ledger-font-xact-highlight-face :background base0)
+
+    ;; makefile-*-mode
+    (makefile-targets :foreground blue)
+
+    ;; markdown-mode
+    (markdown-header-face           :inherit 'bold :foreground highlight)
+    (markdown-header-delimiter-face :inherit 'markdown-header-face)
+    (markdown-metadata-key-face     :foreground red)
+    (markdown-list-face             :foreground red)
+    (markdown-link-face             :inherit 'bold :foreground blue)
+    (markdown-url-face              :foreground magenta :weight 'normal)
+    (markdown-italic-face           :inherit 'italic :foreground violet)
+    (markdown-bold-face             :inherit 'bold   :foreground orange)
+    (markdown-markup-face           :foreground operators)
+    (markdown-blockquote-face       :inherit 'italic :foreground doc-comments)
+    (markdown-pre-face              :foreground strings)
+    (markdown-code-face :background base3)
+    (markdown-inline-code-face :inherit '(markdown-code-face markdown-pre-face))
+
+    ;; notmuch
+    ;; (notmuch-crypto-decryption               :foreground blue-l)
+    ;; (notmuch-crypto-part-header              :foreground yellow-l)
+    ;; (notmuch-crypto-signature-bad            :foreground red-l)
+    ;; (notmuch-crypto-signature-good           :foreground base1)
+    ;; (notmuch-crypto-signature-good-key       :foreground aqua-l)
+    ;; (notmuch-crypto-signature-unknown        :foreground yellow)
+    ;; (notmuch-hello-logo-background           :foreground fg)
+    (notmuch-message-summary-face            :foreground grey :background nil)
+    (notmuch-search-count                    :foreground comments)
+    (notmuch-search-date                     :foreground numbers :weight 'bold)
+    (notmuch-search-flagged-face             :foreground (doom-blend red base4 0.5))
+    (notmuch-search-matching-authors         :foreground blue :weight 'bold)
+    (notmuch-search-non-matching-authors     :foreground blue)
+    (notmuch-search-subject                  :foreground fg)
+    (notmuch-search-unread-face              :foreground base8)
+    (notmuch-tag-added                       :foreground green :weight 'normal)
+    (notmuch-tag-deleted                     :foreground red :weight 'normal)
+    (notmuch-tag-face                        :foreground yellow :weight 'normal)
+    (notmuch-tag-flagged                     :foreground yellow :weight 'normal)
+    (notmuch-tag-unread                      :foreground yellow :weight 'normal)
+    (notmuch-tree-match-author-face          :foreground blue :weight 'bold)
+    (notmuch-tree-match-date-face            :foreground numbers :weight 'bold)
+    (notmuch-tree-match-face                 :foreground fg)
+    (notmuch-tree-match-subject-face         :foreground fg)
+    (notmuch-tree-match-tag-face             :foreground yellow)
+    (notmuch-tree-match-tree-face            :foreground comments)
+    (notmuch-tree-no-match-author-face       :foreground blue)
+    (notmuch-tree-no-match-date-face         :foreground numbers)
+    (notmuch-tree-no-match-face              :foreground base5)
+    (notmuch-tree-no-match-subject-face      :foreground base5)
+    (notmuch-tree-no-match-tag-face          :foreground yellow)
+    (notmuch-tree-no-match-tree-face         :foreground yellow)
+    (notmuch-wash-cited-text                 :foreground base4)
+    (notmuch-wash-toggle-button :foreground fg)
+
+    ;; outline
+    (outline-1 :inherit 'org-level-1)
+    (outline-2 :inherit 'org-level-2)
+    (outline-3 :inherit 'org-level-3)
+    (outline-4 :inherit 'org-level-4)
+    (outline-5 :inherit 'org-level-5)
+    (outline-6 :inherit 'org-level-6)
+    (outline-7 :inherit 'org-level-7)
+    (outline-8 :inherit 'org-level-8)
+
+    ;; org-mode
+    (org-archived                 :foreground doc-comments)
+    (org-block                    :background base3)
+    (org-block-background         :background base3)
+    (org-block-begin-line         :foreground comments :background base3)
+    (org-block-end-line           :inherit 'org-block-begin-line)
+    (org-checkbox                 :inherit 'org-todo)
+    (org-checkbox-statistics-done :inherit 'org-done)
+    (org-checkbox-statistics-todo :inherit 'org-todo)
+    (org-code                     :foreground orange)
+    (org-date                     :foreground yellow)
+    (org-default                  :inherit 'variable-pitch)
+    (org-document-info            :foreground builtin)
+    (org-document-title           :foreground builtin :weight 'bold)
+    (org-done                     :inherit 'org-headline-done :bold 'inherit)
+    (org-ellipsis                 :underline nil :background nil :foreground grey)
+    (org-footnote                 :foreground orange)
+    (org-formula                  :foreground cyan)
+    (org-headline-done            :foreground base5)
+    (org-hide                     :foreground bg)
+
+    (org-level-1 :foreground blue     :background base3 :weight 'ultra-bold :height 1.25)
+    (org-level-2 :foreground magenta  :weight 'semi-bold)
+    (org-level-3 :foreground violet   :weight 'semi-bold)
+    (org-level-4 :foreground (doom-lighten blue 0.25)    :weight 'semi-bold)
+    (org-level-5 :foreground (doom-lighten magenta 0.25) :weight 'semi-bold)
+    (org-level-6 :foreground (doom-lighten blue 0.5)  :weight 'semi-bold)
+    (org-level-7 :foreground (doom-lighten magenta 0.5)    :weight 'semi-bold)
+    (org-level-8 :foreground (doom-lighten blue 0.8) :weight 'semi-bold)
+
+    (org-list-dt         :foreground highlight)
+    (org-meta-line       :foreground doc-comments)
+    (org-priority        :foreground red)
+    (org-property-value  :foreground doc-comments)
+    (org-quote           :background base3 :slant 'italic)
+    (org-special-keyword :foreground doc-comments)
+    (org-table           :foreground violet)
+    (org-tag             :foreground doc-comments :weight 'normal)
+    (org-ref-cite-face   :foreground yellow :weight 'light :underline t)
+    (org-todo            :foreground highlight :bold 'inherit)
+    (org-verbatim        :foreground green)
+    (org-warning         :foreground warning)
+
+    ;; org-agenda
+    (org-agenda-done :inherit 'org-done)
+    (org-agenda-dimmed-todo-face :foreground comments)
+    (org-agenda-date          :foreground violet :weight 'ultra-bold)
+    (org-agenda-date-today    :foreground (doom-lighten violet 0.4)   :weight 'ultra-bold)
+    (org-agenda-date-weekend  :foreground (doom-darken violet 0.4)  :weight 'ultra-bold)
+    (org-agenda-structure     :foreground fg :weight 'ultra-bold)
+    (org-agenda-clocking      :background (doom-blend blue bg 0.2))
+    (org-upcoming-deadline         :foreground (doom-blend fg bg 0.8))
+    (org-upcoming-distant-deadline :foreground (doom-blend fg bg 0.5))
+    (org-scheduled            :foreground fg)
+    (org-scheduled-today      :foreground base7)
+    (org-scheduled-previously :foreground base8)
+    (org-time-grid            :foreground comments)
+    (org-sexp-date            :foreground fg)
+
+    ;; org-habit
+    (org-habit-clear-face          :weight 'bold :background bg-alt :foreground bg-alt)
+    (org-habit-clear-future-face   :weight 'bold :background bg-alt :foreground bg-alt)
+    (org-habit-ready-face          :weight 'bold :background (doom-blend blue bg-alt 0.5)   :foreground (doom-blend blue bg-alt 0.5))
+    (org-habit-ready-future-face   :weight 'bold :background (doom-blend blue bg-alt 0.5)   :foreground (doom-blend blue bg-alt 0.5))
+    (org-habit-alert-face          :weight 'bold :background (doom-blend yellow bg-alt 0.5) :foreground (doom-blend yellow bg-alt 0.5))
+    (org-habit-alert-future-face   :weight 'bold :background (doom-blend yellow bg-alt 0.5) :foreground (doom-blend yellow bg-alt 0.5))
+    (org-habit-overdue-face        :weight 'bold :background (doom-blend red bg-alt 0.5)    :foreground (doom-blend red bg-alt 0.5))
+    (org-habit-overdue-future-face :weight 'bold :background (doom-blend red bg-alt 0.5)    :foreground (doom-blend red bg-alt 0.5))
+
+    ;; rpm-spec-mode
+    (rpm-spec-macro-face        :foreground yellow)
+    (rpm-spec-var-face          :foreground violet)
+    (rpm-spec-tag-face          :foreground blue)
+    (rpm-spec-obsolete-tag-face :foreground red)
+    (rpm-spec-package-face      :foreground orange)
+    (rpm-spec-dir-face          :foreground green)
+    (rpm-spec-doc-face          :foreground orange)
+    (rpm-spec-ghost-face        :foreground comments)
+    (rpm-spec-section-face      :foreground magenta)
+
+    ;; typescript-mode
+    (typescript-jsdoc-tag :foreground doc-comments)
+    (typescript-jsdoc-type :foreground (doom-darken doc-comments 0.15))
+    (typescript-jsdoc-value :foreground (doom-lighten doc-comments 0.15))
+
+    ;; sh-mode
+    (sh-heredoc :inherit 'font-lock-string-face :weight 'normal)
+    (sh-quoted-exec :inherit 'font-lock-preprocessor-face)
+
+    ;; web-mode
+    (web-mode-doctype-face           :foreground comments)
+    (web-mode-html-tag-face          :foreground methods)
+    (web-mode-html-tag-bracket-face  :foreground methods)
+    (web-mode-html-attr-name-face    :foreground type)
+    (web-mode-html-entity-face       :foreground cyan :inherit 'italic)
+    (web-mode-block-control-face     :foreground orange)
+    (web-mode-html-tag-bracket-face  :foreground operators))
+  "TODO")
+
+(defvar doom-themes-common-vars
+  '((ansi-color-names-vector
+     (vconcat (mapcar #'doom-color '(base0 red green yellow blue magenta cyan base8))))
+
+    (fci-rule-color (doom-color 'base5))
+
+    (jdee-db-spec-breakpoint-face-colors `(cons ,(doom-color 'base0) ,(doom-color 'grey)))
+    (jdee-db-requested-breakpoint-face-colors `(cons ,(doom-color 'base0) ,(doom-color 'green)))
+    (jdee-db-active-breakpoint-face-colors `(cons ,(doom-color 'base0) ,(doom-color 'highlight)))
+
+    (vc-annotate-color-map
+     `(list (cons 20  ,(doom-color 'green))
+            (cons 40  ,(doom-blend 'yellow 'green (/ 1.0 3)))
+            (cons 60  ,(doom-blend 'yellow 'green (/ 2.0 3)))
+            (cons 80  ,(doom-color 'yellow))
+            (cons 100 ,(doom-blend 'orange 'yellow (/ 1.0 3)))
+            (cons 120 ,(doom-blend 'orange 'yellow (/ 2.0 3)))
+            (cons 140 ,(doom-color 'orange))
+            (cons 160 ,(doom-blend 'magenta 'orange (/ 1.0 3)))
+            (cons 180 ,(doom-blend 'magenta 'orange (/ 2.0 3)))
+            (cons 200 ,(doom-color 'magenta))
+            (cons 220 ,(doom-blend 'red 'magenta (/ 1.0 3)))
+            (cons 240 ,(doom-blend 'red 'magenta (/ 2.0 3)))
+            (cons 260 ,(doom-color 'red))
+            (cons 280 ,(doom-blend 'grey 'red (/ 1.0 4)))
+            (cons 300 ,(doom-blend 'grey 'red (/ 2.0 4)))
+            (cons 320 ,(doom-blend 'grey 'red (/ 3.0 4)))
+            (cons 340 ,(doom-color 'base5))
+            (cons 360 ,(doom-color 'base5))))
+    (vc-annotate-very-old-color nil)
+    (vc-annotate-background (doom-color 'bg)))
+  "TODO")
+
+
+;;
+;; Library
+;;
+
+(defvar doom-themes--colors)
+(defvar doom--min-colors '(257 256 16))
+(defvar doom--quoted-p nil)
+(defvar doom-themes--faces nil)
+
+(defun doom-themes--colors-p (item)
+  (declare (pure t) (side-effect-free t))
+  (when item
+    (cond ((listp item)
+           (let ((car (car item)))
+             (cond ((memq car '(quote doom-color)) nil)
+
+                   ((memq car '(backquote \`))
+                    (let ((doom--quoted-p t))
+                      (doom-themes--colors-p (cdr item))))
+
+                   ((eq car '\,)
+                    (let (doom--quoted-p)
+                      (doom-themes--colors-p (cdr item))))
+
+                   ((or (doom-themes--colors-p car)
+                        (doom-themes--colors-p (cdr-safe item)))))))
+
+          ((and (symbolp item)
+                (not (keywordp item))
+                (not doom--quoted-p)
+                (not (equal (substring (symbol-name item) 0 1) "-"))
+                (assq item doom-themes--colors))))))
+
+(defun doom-themes--apply-faces (new-faces &optional default-faces)
+  (declare (pure t) (side-effect-free t))
+  (let ((default-faces (or default-faces doom-themes-common-faces))
+        (faces (make-hash-table :test #'eq :size (+ (length default-faces) (length new-faces))))
+        (directives (make-hash-table :test #'eq)))
+    (dolist (spec (append (mapcar #'copy-sequence default-faces) new-faces))
+      (if (listp (car spec))
+          (cl-destructuring-bind (face action &optional arg) (car spec)
+            (unless (assq face new-faces)
+              (puthash face (list action arg (cdr spec))
+                       directives)))
+        (puthash (car spec) (cdr spec) faces)))
+    (cl-loop for face being the hash-keys of directives
+             for (action target spec) = (gethash face directives)
+             unless (memq action '(&inherit &extend &override))
+             do (error "Invalid operation (%s) for '%s' face" action face)
+             if (eq (car spec) 'quote)
+             do (error "Can't extend literal face spec (for '%s')" face)
+             ;; TODO Add &all/&light/&dark extension support
+             else if (memq (car spec) '(&all &light &dark))
+             do (error "Can't extend face with &all, &light or &dark specs (for '%s')" face)
+             else do
+             (puthash face
+                      (let ((old-spec (gethash (or target face) faces))
+                            (plist spec))
+                        ;; remove duplicates
+                        (while (keywordp (car plist))
+                          (setq old-spec (plist-put old-spec (car plist) (cadr plist))
+                                plist (cddr plist)))
+                        old-spec)
+                      faces))
+    (let (results)
+      (maphash (lambda (face plist)
+                 (when (keywordp (car plist))
+                   ;; TODO Clean up duplicates in &all/&light/&dark blocks
+                   (dolist (prop (append (unless doom-themes-enable-bold   '(:weight normal :bold nil))
+                                         (unless doom-themes-enable-italic '(:slant normal :italic nil))))
+                     (when (and (plist-member plist prop)
+                                (not (eq (plist-get plist prop) 'inherit)))
+                       (plist-put plist prop
+                                  (if (memq prop '(:weight :slant))
+                                      (quote 'normal))))))
+                 (push (cons face plist) results))
+               faces)
+      (nreverse results))))
+
+(defun doom-themes--colorize (item type)
+  (declare (pure t) (side-effect-free t))
+  (when item
+    (let ((doom--quoted-p doom--quoted-p))
+      (cond ((listp item)
+             (cond ((memq (car item) '(quote doom-color))
+                    item)
+                   ((eq (car item) 'doom-ref)
+                    (doom-themes--colorize
+                     (apply #'doom-ref (cdr item)) type))
+                   ((let* ((item (append item nil))
+                           (car (car item))
+                           (doom--quoted-p
+                            (cond ((memq car '(backquote \`)) t)
+                                  ((eq car '\,) nil)
+                                  (t doom--quoted-p))))
+                      (cons car
+                            (cl-loop
+                             for i in (cdr item)
+                             collect (doom-themes--colorize i type)))))))
+
+            ((and (symbolp item)
+                  (not (keywordp item))
+                  (not doom--quoted-p)
+                  (not (equal (substring (symbol-name item) 0 1) "-"))
+                  (assq item doom-themes--colors))
+             `(doom-color ',item ',type))
+
+            (item)))))
+
+(defun doom-themes--build-face (face)
+  (declare (pure t) (side-effect-free t))
+  `(list
+    ',(car face)
+    ,(let ((face-body (cdr face)))
+       (cond ((keywordp (car face-body))
+              (let ((real-attrs face-body)
+                    defs)
+                (if (doom-themes--colors-p real-attrs)
+                    (dolist (cl doom--min-colors `(list ,@(nreverse defs)))
+                      (push `(list '((class color) (min-colors ,cl))
+                                   (list ,@(doom-themes--colorize real-attrs cl)))
+                            defs))
+                  `(list (list 't (list ,@real-attrs))))))
+
+             ((memq (car-safe (car face-body)) '(quote backquote \`))
+              (car face-body))
+
+             ((let (all-attrs defs)
+                (dolist (attrs face-body `(list ,@(nreverse defs)))
+                  (cond ((eq (car attrs) '&all)
+                         (setq all-attrs (append all-attrs (cdr attrs))))
+
+                        ((memq (car attrs) '(&dark &light))
+                         (let ((bg (if (eq (car attrs) '&dark) 'dark 'light))
+                               (real-attrs (append all-attrs (cdr attrs) '())))
+                           (cond ((doom-themes--colors-p real-attrs)
+                                  (dolist (cl doom--min-colors)
+                                    (push `(list '((class color) (min-colors ,cl) (background ,bg))
+                                                 (list ,@(doom-themes--colorize real-attrs cl)))
+                                          defs)))
+
+                                 ((push `(list '((background ,bg)) (list ,@real-attrs))
+                                        defs)))))))))))))
+
+
+;;
+;; Public functions
+;;
+
+(defun doom-themes-prepare-facelist (custom-faces)
+  "Return an alist of face definitions for `custom-theme-set-faces'.
+
+Faces in EXTRA-FACES override the default faces."
+  (declare (pure t) (side-effect-free t))
+  (setq doom-themes--faces (doom-themes--apply-faces custom-faces))
+  (mapcar #'doom-themes--build-face doom-themes--faces))
+
+(defun doom-themes-prepare-varlist (vars)
+  "Return an alist of variable definitions for `custom-theme-set-variables'.
+
+Variables in EXTRA-VARS override the default ones."
+  (declare (pure t) (side-effect-free t))
+  (cl-loop for (var val) in (append doom-themes-common-vars vars)
+           collect `(list ',var ,val)))
+
+(provide 'doom-themes-common)
+;;; doom-themes-common.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-themes-common.elc b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-themes-common.elc
new file mode 100644
index 0000000000..f9f3b46c78
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-themes-common.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-themes-neotree.el b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-themes-neotree.el
new file mode 100644
index 0000000000..0b7a5134e7
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-themes-neotree.el
@@ -0,0 +1,359 @@
+;;; doom-themes-neotree.el -*- lexical-binding: t; -*-
+
+(unless doom-themes--inhibit-warning
+  (message "doom-themes: loading `doom-themes-neotree' directly is obsolete, call `doom-themes-neotree-config' instead"))
+
+(defgroup doom-neotree nil
+  "Options for doom's neotree theme"
+  :group 'doom-themes)
+
+;;
+(defface doom-neotree-dir-face  '((t (:inherit neo-dir-link-face)))
+  "Face for directory labels."
+  :group 'doom-neotree)
+
+(defface doom-neotree-file-face '((t (:inherit neo-file-link-face)))
+  "Face for file name labels."
+  :group 'doom-neotree)
+
+;; file type faces
+(defface doom-neotree-hidden-file-face '((t (:inherit font-lock-comment-face)))
+  "Face for labels of hidden files. See `doom-neotree-file-face-re-alist'."
+  :group 'doom-neotree)
+
+(defface doom-neotree-text-file-face '((t (:inherit neo-file-link-face)))
+  "Face for labels of text/documentation files (readmes, org files, etc). See
+`doom-neotree-file-face-re-alist'."
+  :group 'doom-neotree)
+
+(defface doom-neotree-media-file-face '((t (:inherit neo-file-link-face)))
+  "Face for labels of media files. See `doom-neotree-file-face-re-alist'."
+  :group 'doom-neotree)
+
+(defface doom-neotree-data-file-face '((t (:inherit neo-file-link-face)))
+  "Face for labels of data files (json, yaml, xml, etc). See
+`doom-neotree-file-face-re-alist'."
+  :group 'doom-neotree)
+
+(defface doom-neotree-executable-file-face '((t (:inherit neo-file-link-face)))
+  "TODO"
+  :group 'doom-neotree)
+
+
+;;
+(defcustom doom-neotree-project-size 1.4
+  "What :height to display the project icon at the top at."
+  :type 'float
+  :group 'doom-neotree)
+
+(defcustom doom-neotree-folder-size 1.05
+  "What :height to display the folder icons at."
+  :type 'float
+  :group 'doom-neotree)
+
+(defcustom doom-neotree-chevron-size 0.8
+  "What :height to display the chevron icons at."
+  :type 'float
+  :group 'doom-neotree)
+
+(defcustom doom-neotree-line-spacing 2
+  "Line-spacing for neotree buffer."
+  :type 'symbol
+  :group 'doom-neotree)
+
+(define-obsolete-variable-alias 'doom-neotree-enable-file-icons 'doom-neotree-file-icons)
+(defcustom doom-neotree-file-icons 'simple
+  "The style to use for the file icons. Can be nil (disabled), non-nil (for a
+diverse iconset), or 'simple, which is closest's to Atom's style as it only
+distinguishes text, source, pdfs, images and binary files."
+  :type '(choice
+          (const :tag "A diverse array of file icons based on file type" t)
+          (const :tag "Minimalistic file icons (like Atom's)" 'simple)
+          (const :tag "Disable file icons" nil))
+  :group 'doom-neotree)
+
+(defcustom doom-neotree-enable-folder-icons t
+  "If non-nil, display folder icons next to each file. Different icons are used
+depending on whether the folder is a repo, symlink or regular folder."
+  :type 'boolean
+  :group 'doom-neotree)
+
+(defcustom doom-neotree-enable-open-chevron-icons t
+  "If non-nil, display the chevron-down icon next to each expanded folder."
+  :type 'boolean
+  :group 'doom-neotree)
+
+(defcustom doom-neotree-enable-closed-chevron-icons t
+  "If non-nil, display the chevron-right icon next to each collapsed folder."
+  :type 'boolean
+  :group 'doom-neotree)
+
+(defcustom doom-neotree-enable-variable-pitch nil
+  "If non-nil, labels will use the `doom-neotree-dir-face' and
+`doom-neotree-dir-face' faces, which inherit from the `variable-pitch' face."
+  :type 'boolean
+  :group 'doom-neotree)
+
+(defcustom doom-neotree-enable-type-colors t
+  "If non-nil, color each file/folder based on the categories determined by
+`doom-neotree-file-face-re-alist'."
+  :type 'boolean
+  :group 'doom-neotree)
+
+
+(defun doom--neo-is-repo-dir-p (path)
+  (or (file-exists-p (format "%s/.git" path))
+      (all-the-icons-dir-is-submodule path)))
+
+(defvar doom-neotree-dir-rules
+  (eval-when-compile
+    `(("/\\(?:node_modules\\|vendor\\)$"
+       :face doom-neotree-hidden-file-face)
+      ("/\\.[^$/#]+$"
+       :face doom-neotree-hidden-file-face)
+      (file-symlink-p
+       :icon (all-the-icons-octicon "file-symlink-directory"))
+      (doom--neo-is-repo-dir-p
+       :icon (all-the-icons-octicon "file-submodule"))
+      (t :icon (all-the-icons-octicon "file-directory"))))
+  "TODO")
+
+(defvar doom-neotree-file-rules
+  (eval-when-compile
+    `((file-symlink-p
+       :icon (all-the-icons-octicon "file-symlink-file"))
+      (file-executable-p
+       :face doom-neotree-executable-file-face
+       :icon (all-the-icons-octicon "file-binary"))
+      ("\\.\\(?:md\\|org\\|rst\\|log\\)\\|/[A-Z_-]+\\(?:\\.[a-z]+\\)?$"
+       :face doom-neotree-text-file-face
+       :icon (all-the-icons-octicon "file-text"))
+      (,(concat "\\." (regexp-opt '("htm" "html" "phtml" "tpl" "erb" "mustache"
+                                    "twig" "ejs" "erb" "jsx" "haml" "inky-haml"
+                                    "inky-slim" "slim" "pug" "jade"))
+                "$")
+       :icon (all-the-icons-octicon "file-code"))
+      (,(concat "\\(?:/\\(?:Gemfile\\|Vagrantfile\\|Makefile\\|Rakefile\\|Cask\\|\\.[^$]+rc\\|\\)\\|"
+                "\\." (regexp-opt '("json" "cson" "yaml" "yml" "xml" "toml"
+                                    "tpl" "ini" "erb" "mustache" "twig" "ejs"
+                                    "mk" "haml" "pug" "jade"))
+                "\\)$")
+       :icon (all-the-icons-octicon "file-code"))
+      (,(concat "\\."
+                (regexp-opt '("png" "jpg" "jpeg" "gif" "ico" "tif" "tiff"
+                              "svg" "bmp" "psd" "ai" "eps" "indd"         ; images
+                              "mov" "avi" "mp4" "webm" "mkv"              ; video
+                              "wav" "mp3" "ogg" "midi"))                  ; audio
+                "$")
+       :face doom-neotree-data-file-face
+       :icon (all-the-icons-octicon "file-media"))
+      (,(concat "\\.\\(?:[gl]?zip\\|bzip2\\|deb\\|dmg\\|iso\\|7z\\|rpm\\|pkg\\|dat\\|[rjt]ar\\(?:\\.gz\\)?\\)$")
+       :face doom-neotree-data-file-face
+       :icon (all-the-icons-octicon "file-zip"))
+      ("\\.pdf$"
+       :face doom-neotree-data-file-face
+       :icon (all-the-icons-octicon "file-pdf"))
+      ("\\.\\(?:lock\\|resolved\\|dll\\|so\\|pyc\\|elc\\|class\\|css\\.map\\)$"
+       :face doom-neotree-hidden-file-face
+       :icon (all-the-icons-octicon "file-binary"))
+      ("/\\.[^$/#]+$"
+       :face doom-neotree-hidden-file-face)
+      (t :icon (all-the-icons-octicon "file-text"))))
+  "TODO")
+
+
+;;
+(defun doom--neotree-no-fringes ()
+  "Remove fringes in neotree. They get reset each time you select the neotree
+pane and are highlighted incorrectly."
+  (set-window-fringes neo-global--window 0 0))
+
+(defun doom--neotree-setup (&rest _)
+  (setq line-spacing doom-neotree-line-spacing
+        tab-width 1)
+  (when (featurep 'hl-line)
+    (set (make-local-variable 'hl-line-sticky-flag) t)
+    (hl-line-mode +1)))
+
+(defun doom-neotree-spec (node rules)
+  (let (case-fold-search)
+    (cl-loop for spec in rules
+             for pred = (car spec)
+             for plist = (cdr spec)
+             when
+             (cond ((eq pred 't))
+                   ((symbolp pred) (funcall pred node))
+                   ((stringp pred) (string-match-p pred node)))
+             return plist)))
+
+(defun doom--neotree-insert-file-icon (node icon &optional faces)
+  (if node
+      (cond ((eq doom-neotree-file-icons 'simple)
+             (propertize
+              (if icon
+                  (apply (car icon) (cdr icon))
+                (all-the-icons-octicon "file-text"))
+              'face `(:inherit ,faces
+                               :family ,(all-the-icons-octicon-family)
+                               :height 1.3)
+              'display '(raise 0)))
+            (t (all-the-icons-icon-for-file node)))
+    (all-the-icons-fileicon "default")))
+
+(defun doom--neotree-insert-dir-icon (node type &optional faces)
+  (concat (if type
+              (all-the-icons-octicon
+               (format "chevron-%s" (if (eq type 'open) "down" "right"))
+               :v-adjust 0.1
+               :height doom-neotree-chevron-size
+               :face `(:inherit ,faces
+                                :family ,(all-the-icons-octicon-family)
+                                :height ,doom-neotree-chevron-size))
+            "\t")
+          "\t"
+          (when doom-neotree-enable-folder-icons
+            (all-the-icons-octicon
+             (cond ((file-symlink-p node) "file-symlink-directory")
+                   ((file-exists-p (format "%s/.git" node)) "file-submodule")
+                   ((all-the-icons-dir-is-submodule node) "file-submodule")
+                   ("file-directory"))
+             :v-adjust 0
+             :height doom-neotree-folder-size
+             :face `(:inherit ,faces
+                     :family ,(all-the-icons-octicon-family)
+                     :height ,doom-neotree-folder-size)))))
+
+(defun doom--neotree-insert-icon (type node &optional icon faces)
+  "Custom hybrid unicode theme with leading whitespace."
+  (let ((spc "\t")
+        (vspc (propertize "  " 'face 'variable-pitch)))
+    (cond ((eq type 'open)
+           (insert
+            (concat spc
+                    (doom--neotree-insert-dir-icon
+                     node (if doom-neotree-enable-open-chevron-icons type)
+                     faces)
+                    vspc)))
+          ((eq type 'close)
+           (insert
+            (concat spc
+                    (doom--neotree-insert-dir-icon
+                     node (if doom-neotree-enable-closed-chevron-icons type)
+                     faces)
+                    vspc)))
+          ((eq type 'leaf)
+           (insert
+            (concat (when (or doom-neotree-enable-open-chevron-icons
+                              doom-neotree-enable-closed-chevron-icons)
+                      spc)
+                    (when doom-neotree-enable-folder-icons spc)
+                    (when doom-neotree-file-icons
+                      (concat spc (doom--neotree-insert-file-icon node icon faces)))
+                    vspc))))))
+
+;;
+(defun doom-neotree-insert-root (node)
+  ;; insert icon
+  (when (display-graphic-p)
+    (insert
+     (concat (propertize "\t" 'face 'neo-root-dir-face)
+             (all-the-icons-octicon
+              "repo"
+              :height doom-neotree-project-size
+              :face 'neo-root-dir-face
+              :v-adjust -0.1)
+             (propertize " " 'face 'neo-root-dir-face))))
+  ;; insert project name
+  (insert
+   (propertize
+    (concat (or (neo-path--file-short-name node) "-")
+            "\n")
+    'face `(:inherit ,(append (if doom-neotree-enable-variable-pitch '(variable-pitch))
+                              '(neo-root-dir-face))))))
+
+(defun doom-neotree-insert-dir (node depth expanded)
+  (let ((short-name (neo-path--file-short-name node))
+        (faces '(doom-neotree-dir-face))
+        icon-text)
+    ;; insert indentation
+    (insert-char ?\s (* (- depth 1) 2))
+    ;; vcs integration
+    (let ((vc (if neo-vc-integration (neo-vc-for-node node))))
+      (when (memq 'char neo-vc-integration)
+        (insert-char (car vc))
+        (insert-char ?\s))
+      (unless (and (memq 'face neo-vc-integration)
+                   (not (eq (cdr vc) 'neo-vc-up-to-date-face))
+                   (setq faces (list (cdr vc))))
+        (cl-destructuring-bind (&key face icon)
+            (doom-neotree-spec node doom-neotree-dir-rules)
+          (if face (push face faces))
+          (if icon (setq icon-text icon)))))
+    ;; insert icon
+    (let ((type (if expanded 'open 'close)))
+      (if (display-graphic-p)
+          (doom--neotree-insert-icon type node icon-text faces)
+        (neo-buffer--insert-fold-symbol type node)))
+    ;; insert label button
+    (when doom-neotree-enable-variable-pitch
+      (push 'variable-pitch faces))
+    (insert-button short-name
+                   'follow-link t
+                   'face `(:inherit (,@faces))
+                   'neo-full-path node
+                   'keymap neotree-dir-button-keymap)
+    ;; metadata + newline
+    (neo-buffer--node-list-set nil node)
+    (neo-buffer--newline-and-begin)))
+
+(defun doom-neotree-insert-file (node depth)
+  (let ((short-name (neo-path--file-short-name node))
+        (vc (if neo-vc-integration (neo-vc-for-node node)))
+        (faces '(doom-neotree-file-face))
+        icon-text)
+    ;; insert indentation
+    (insert-char ?\s (* (- depth 1) 2))
+    ;; vcs integration
+    (unless (and (memq 'face neo-vc-integration)
+                 (not (eq (cdr vc) 'neo-vc-up-to-date-face))
+                 (setq faces (list (cdr vc))))
+      (cl-destructuring-bind (&key face icon)
+          (doom-neotree-spec node doom-neotree-file-rules)
+        (if face (push face faces))
+        (if icon (setq icon-text icon))))
+    ;; insert icon
+    (if (display-graphic-p)
+        (doom--neotree-insert-icon 'leaf node icon-text faces)
+      (neo-buffer--insert-fold-symbol 'leaf node))
+    ;; insert label button
+    (when doom-neotree-enable-variable-pitch
+      (push 'variable-pitch faces))
+    (insert-button short-name
+                   'follow-link t
+                   'face `(:inherit (,@faces))
+                   'neo-full-path node
+                   'keymap neotree-file-button-keymap)
+    ;; metadata + newline
+    (neo-buffer--node-list-set nil node)
+    (neo-buffer--newline-and-begin)))
+
+;;
+(eval-after-load 'neotree
+  (lambda ()
+    (unless (require 'all-the-icons nil t)
+      (error "all-the-icons isn't installed"))
+
+    ;; Enable buffer-local hl-line and adjust line-spacing
+    (add-hook 'neo-after-create-hook #'doom--neotree-setup)
+    ;; Incompatible
+    (setq neo-vc-integration nil)
+    ;; Remove fringes in Neotree pane
+    (advice-add #'neo-global--select-window :after #'doom--neotree-no-fringes)
+    ;; Patch neotree to use `doom--neotree-insert-icon'
+    (advice-add #'neo-buffer--insert-file-entry :override #'doom-neotree-insert-file)
+    (advice-add #'neo-buffer--insert-dir-entry  :override #'doom-neotree-insert-dir)
+    ;; Shorter pwd in neotree                    override
+    (advice-add #'neo-buffer--insert-root-entry :override #'doom-neotree-insert-root)))
+
+(provide 'doom-themes-neotree)
+;;; doom-themes-neotree.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-themes-neotree.elc b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-themes-neotree.elc
new file mode 100644
index 0000000000..178bffd8f0
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-themes-neotree.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-themes-org.el b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-themes-org.el
new file mode 100644
index 0000000000..7914e9237d
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-themes-org.el
@@ -0,0 +1,86 @@
+;;; doom-themes-org.el --- improve org-mode support for doom-themes -*- lexical-binding: t; -*-
+
+(defgroup doom-org nil
+  "Options for doom's org customizations."
+  :group 'doom-themes)
+
+(defcustom doom-org-special-tags t
+  "If non-nil, highlight #hashtags and @attags especially."
+  :type 'boolean
+  :group 'doom-org)
+
+;; TODO Remove this once released with org-mode
+(defface org-upcoming-distant-deadline '((t :inherit font-lock-comment-face))
+  "Face for items scheduled previously, not done, and have a distant deadline.
+See also `org-agenda-deadline-faces'."
+  :group 'doom-org)
+
+;;
+(defsubst doom-org--tag-face (n)
+  (let ((kwd (match-string n)))
+    (or (and (equal kwd "#") 'org-tag)
+        (and (equal kwd "@") 'org-formula))))
+
+(defun doom-org-custom-fontification ()
+  "Correct (and improve) org-mode's font-lock keywords.
+
+  1. Re-set `org-todo' & `org-headline-done' faces, to make them respect
+     (inherit) underlying faces.
+  2. Make statistic cookies respect (inherit) underlying faces.
+  3. Fontify item bullets (make them stand out)
+  4. Fontify item checkboxes (and when they're marked done), like TODOs that are
+     marked done.
+  5. Fontify dividers/separators (5+ dashes)
+  6. Fontify #hashtags and @at-tags, for personal convenience; see
+     `doom-org-special-tags' to disable this."
+  (let ((org-todo (format org-heading-keyword-regexp-format
+                          org-todo-regexp))
+        (org-done (format org-heading-keyword-regexp-format
+                          (concat "\\(?:" (mapconcat #'regexp-quote org-done-keywords "\\|") "\\)"))))
+    (setq
+     org-font-lock-extra-keywords
+     (append (org-delete-all
+              (append `(("\\[\\([0-9]*%\\)\\]\\|\\[\\([0-9]*\\)/\\([0-9]*\\)\\]"
+                         (0 (org-get-checkbox-statistics-face) t))
+                        (,org-todo (2 (org-get-todo-face 2) t))
+                        (,org-done (2 'org-headline-done t)))
+                      (when (memq 'date org-activate-links)
+                        '((org-activate-dates (0 'org-date t)))))
+              org-font-lock-extra-keywords)
+             ;; respsect underlying faces!
+             `((,org-todo (2 (org-get-todo-face 2) prepend))
+               (,org-done (2 'org-headline-done prepend)))
+             (when (memq 'date org-activate-links)
+               '((org-activate-dates (0 'org-date prepend))))
+             ;; Make checkbox statistic cookies respect underlying faces
+             '(("\\[\\([0-9]*%\\)\\]\\|\\[\\([0-9]*\\)/\\([0-9]*\\)\\]"
+                (0 (org-get-checkbox-statistics-face) prepend))
+               ;; I like how org-mode fontifies checked TODOs and want this to extend to
+               ;; checked checkbox items:
+               ("^[ \t]*\\(?:[-+*]\\|[0-9]+[).]\\)[ \t]+\\(\\(?:\\[@\\(?:start:\\)?[0-9]+\\][ \t]*\\)?\\[\\(?:X\\|\\([0-9]+\\)/\\2\\)\\][^\n]*\n\\)"
+                1 'org-headline-done prepend)
+               ;; make plain list bullets stand out
+               ("^ *\\([-+]\\|[0-9]+[).]\\) " 1 'org-list-dt append)
+               ;; and separators/dividers
+               ("^ *\\(-----+\\)$" 1 'org-meta-line))
+             ;; custom #hashtags & @at-tags for another level of organization
+             (when doom-org-special-tags
+               '(("\\s-\\(\\([#@]\\)[^+ \n.,]+\\)" 1 (doom-org--tag-face 2) prepend)))))))
+
+
+;; Bootstrap
+(setq org-hide-leading-stars t
+      org-hide-leading-stars-before-indent-mode t
+      org-fontify-done-headline t
+      org-fontify-quote-and-verse-blocks t
+      org-fontify-whole-heading-line t
+      org-agenda-deadline-faces
+      '((1.001 . error)
+        (1.0 . org-warning)
+        (0.5 . org-upcoming-deadline)
+        (0.0 . org-upcoming-distant-deadline)))
+
+(add-hook 'org-font-lock-set-keywords-hook #'doom-org-custom-fontification)
+
+(provide 'doom-themes-org)
+;;; doom-themes-org.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-themes-org.elc b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-themes-org.elc
new file mode 100644
index 0000000000..7ec67cc402
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-themes-org.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-themes-pkg.el b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-themes-pkg.el
new file mode 100644
index 0000000000..d70fe7ae06
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-themes-pkg.el
@@ -0,0 +1,10 @@
+(define-package "doom-themes" "20180720.438" "an opinionated pack of modern color-themes"
+  '((emacs "24.4")
+    (all-the-icons "1.0.0")
+    (cl-lib "0.5"))
+  :keywords
+  '("dark" "light" "blue" "atom" "one" "theme" "neotree" "icons" "faces" "nova")
+  :url "https://github.com/hlissner/emacs-doom-theme")
+;; Local Variables:
+;; no-byte-compile: t
+;; End:
diff --git a/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-themes-treemacs.el b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-themes-treemacs.el
new file mode 100644
index 0000000000..45499b7530
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-themes-treemacs.el
@@ -0,0 +1,115 @@
+;;; doom-themes-treemacs.el --- description -*- lexical-binding: t; -*-
+
+(defgroup doom-treemacs nil
+  "Options for doom's treemacs theme"
+  :group 'doom-themes)
+
+(defcustom doom-treemacs-enable-variable-pitch t
+  "If non-nil, the labels for files, folders and projects are displayed with the
+variable-pitch face."
+  :type 'boolean
+  :group 'doom-treemacs)
+
+(defcustom doom-treemacs-line-spacing 1
+  "Line-spacing for treemacs buffer."
+  :type 'symbol
+  :group 'doom-treemacs)
+
+(defun doom--treemacs-no-fringes ()
+  "Remove fringes in treemacs. They get reset each time you select the neotree
+pane and are highlighted incorrectly when used with `solaire-mode'."
+  (when (display-graphic-p)
+    (set-window-fringes nil 0 0)))
+
+(defun doom--treemacs-setup (&rest _)
+  (setq line-spacing doom-treemacs-line-spacing
+        tab-width 1))
+
+(defun doom--treemacs-hide-modeline ()
+  (setq mode-line-format nil))
+
+(defun doom--treemacs-variable-pitch-labels (&rest _)
+  (when doom-treemacs-enable-variable-pitch
+    (dolist (face '(treemacs-root-face
+                    treemacs-git-unmodified-face
+                    treemacs-git-modified-face
+                    treemacs-git-renamed-face
+                    treemacs-git-ignored-face
+                    treemacs-git-untracked-face
+                    treemacs-git-added-face
+                    treemacs-git-conflict-face
+                    treemacs-directory-face
+                    treemacs-directory-collapsed-face
+                    treemacs-file-face))
+      (let ((faces (face-attribute face :inherit nil)))
+        (set-face-attribute face nil :inherit `(variable-pitch ,@(delq 'unspecified (doom-enlist faces))))))))
+
+(eval-after-load 'treemacs
+  (lambda ()
+    (unless (require 'all-the-icons nil t)
+      (error "all-the-icons isn't installed"))
+
+    ;; Silence plistp error with all-the-icons
+    (advice-add #'treemacs--pulse-png-advice :override #'ignore)
+
+    (add-hook 'treemacs-mode-hook #'doom--treemacs-setup)
+    (add-hook 'treemacs-mode-hook #'doom--treemacs-hide-modeline)
+
+    ;; no fringes in treemacs window
+    (add-hook 'treemacs-mode-hook #'doom--treemacs-no-fringes)
+    (advice-add #'treemacs-select-window :after #'doom--treemacs-no-fringes)
+
+    ;; variable-pitch labels for files/folders
+    (doom--treemacs-variable-pitch-labels)
+    (advice-add #'load-theme :after #'doom--treemacs-variable-pitch-labels)
+
+    ;; minimalistic atom-inspired icon theme
+    (let ((all-the-icons-default-adjust 0))
+      (setq treemacs-icon-root-png
+            (concat " " (all-the-icons-octicon "repo" :v-adjust -0.1 :height 1.6
+                                               :face 'font-lock-string-face)
+                    " ")
+
+            treemacs-icon-tag-open-png
+            (all-the-icons-octicon "chevron-down" :v-adjust 0.1)
+            treemacs-icon-tag-closed-png
+            (all-the-icons-octicon "chevron-right" :v-adjust 0.1)
+
+            treemacs-indentation-string "  "
+            treemacs-indentation 1
+
+            treemacs-icon-open-png
+            (concat (all-the-icons-octicon "file-directory" :v-adjust 0 :height 1.15)
+                    " ")
+            treemacs-icon-closed-png
+            (concat (all-the-icons-octicon "file-directory" :v-adjust 0 :height 1.15 :face 'font-lock-doc-face)
+                    " ")
+
+            treemacs-icon-tag-node-open-png
+            (concat (all-the-icons-octicon "chevron-down"  :height 0.75 :face 'font-lock-keyword-face)
+                    "\t")
+            treemacs-icon-tag-node-closed-png
+            (concat (all-the-icons-octicon "chevron-right" :height 0.9  :face 'font-lock-keyword-face)
+                    "\t")
+            treemacs-icon-tag-leaf-png "- ")
+
+      ;; File type icons
+      (setq treemacs-icons-hash (make-hash-table :size 200 :test #'equal)
+            treemacs-icon-fallback (concat (all-the-icons-octicon "file-code" :height 1.2 :v-adjust 0) " ")
+            treemacs-icon-text     treemacs-icon-fallback)
+
+      (treemacs-define-custom-icon (all-the-icons-octicon "file-media" :height 1.2)
+                                   "png" "jpg" "jpeg" "gif" "ico" "tif" "tiff" "svg" "bmp"
+                                   "psd" "ai" "eps" "indd" "mov" "avi" "mp4" "webm" "mkv"
+                                   "wav" "mp3" "ogg" "midi")
+
+      (treemacs-define-custom-icon (all-the-icons-octicon "file-text" :height 1.2)
+                                   "md" "markdown" "rst" "log" "org" "txt"
+                                   "CONTRIBUTE" "LICENSE" "README" "CHANGELOG")
+
+      (treemacs-define-custom-icon (all-the-icons-octicon "file-code" :height 1.2)
+                                   "yaml" "yml" "json" "xml" "toml" "cson" "ini"
+                                   "tpl" "erb" "mustache" "twig" "ejs" "mk" "haml" "pug" "jade"))))
+
+(provide 'doom-themes-treemacs)
+;;; doom-themes-treemacs.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-themes-treemacs.elc b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-themes-treemacs.elc
new file mode 100644
index 0000000000..609ed1f391
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-themes-treemacs.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-themes.el b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-themes.el
new file mode 100644
index 0000000000..53fe97eca4
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-themes.el
@@ -0,0 +1,270 @@
+;;; doom-themes.el --- an opinionated pack of modern color-themes -*- lexical-binding: t; -*-
+;;
+;; Copyright (C) 2016-2018 Henrik Lissner
+;;
+;; Author: Henrik Lissner <http://github/hlissner>
+;; Maintainer: Henrik Lissner <henrik@lissner.net>
+;; Created: May 22, 2016
+;; Modified: July 10, 2018
+;; Version: 2.1.5
+;; Keywords: dark light blue atom one theme neotree icons faces nova
+;; Homepage: https://github.com/hlissner/emacs-doom-theme
+;; Package-Requires: ((emacs "24.4") (all-the-icons "1.0.0") (cl-lib "0.5"))
+;;
+;; This file is not part of GNU Emacs.
+;;
+;;; Commentary:
+;;
+;; DOOM Themes is an opinionated UI plugin and pack of themes extracted from my
+;; [emacs.d], inspired by some of my favorite color themes including:
+;;
+;; Flagship themes
+;;   `doom-one'
+;;   `doom-one-light'
+;;   `doom-vibrant'
+;;
+;; Additional themes
+;;   [X] `doom-city-lights' (added by fuxialexnder)
+;;   [X] `doom-darcula' (added by fuxialexnder)
+;;   [X] `doom-molokai'
+;;   [X] `doom-nord' (added by fuxialexnder)
+;;   [X] `doom-nord-light' (added by fuxialexnder)
+;;   [X] `doom-opera' (added by jwintz)
+;;   [X] `doom-opera-light' (added by jwintz)
+;;   [X] `doom-nova' (added by bigardone)
+;;   [X] `doom-peacock' (added by teesloane)
+;;   [X] `doom-solarized-light' (added by fuxialexnder)
+;;   [X] `doom-spacegrey' (added by teesloane)
+;;   [X] `doom-tomorrow-night'
+;;   [X] `doom-tomorrow-day'
+;;   [ ] `doom-mono-dark' / `doom-mono-light'
+;;   [ ] `doom-tron'
+;;
+;; ## Install
+;;
+;;   `M-x package-install RET doom-themes`
+;;
+;; A comprehensive configuration example:
+;;
+;;   (require 'doom-themes)
+;;
+;;   ;; Global settings (defaults)
+;;   (setq doom-themes-enable-bold t    ; if nil, bold is universally disabled
+;;         doom-themes-enable-italic t) ; if nil, italics is universally disabled
+;;
+;;   ;; Load the theme (doom-one, doom-molokai, etc); keep in mind that each
+;;   ;; theme may have their own settings.
+;;   (load-theme 'doom-one t)
+;;
+;;   ;; Enable flashing mode-line on errors
+;;   (doom-themes-visual-bell-config)
+;;
+;;   ;; Enable custom neotree theme
+;;   (doom-themes-neotree-config)  ; all-the-icons fonts must be installed!
+;;
+;;; Code:
+
+(require 'cl-lib)
+(require 'doom-themes-common)
+
+(defgroup doom-themes nil
+  "Options for doom-themes."
+  :group 'faces)
+
+(defface doom-modeline-error '((t (:inherit error :inverse-video t)))
+  "Face to use for the mode-line when `doom-themes-visual-bell-config' is used."
+  :group 'doom-themes)
+
+;;
+(defcustom doom-themes-enable-bold t
+  "If nil, bold will be disabled across all faces."
+  :group 'doom-themes
+  :type 'boolean)
+
+(defcustom doom-themes-enable-italic t
+  "If nil, italics will be disabled across all faces."
+  :group 'doom-themes
+  :type 'boolean)
+
+(defcustom doom-themes-padded-modeline nil
+  "Default value for padded-modeline setting for themes that support it."
+  :group 'doom-themes
+  :type '(or integer boolean))
+
+(define-obsolete-variable-alias 'doom-enable-italic 'doom-themes-enable-italic "1.2.9")
+(define-obsolete-variable-alias 'doom-enable-bold   'doom-themes-enable-bold "1.2.9")
+
+(defvar doom-themes--colors nil)
+(defvar doom-themes--inhibit-warning nil)
+(defvar doom-themes--bell-p nil)
+
+
+;; Color helper functions
+;; Shamelessly *borrowed* from solarized
+;;;###autoload
+(defun doom-name-to-rgb (color &optional frame)
+  "Retrieves the hexidecimal string repesented the named COLOR (e.g. \"red\")
+for FRAME (defaults to the current frame)."
+  (cl-loop for x in (color-values color frame)
+           collect (/ x (float (car (color-values "#ffffff"))))))
+
+;;;###autoload
+(defun doom-blend (color1 color2 alpha)
+  "Blend two colors (hexidecimal strings) together by a coefficient ALPHA (a
+float between 0 and 1)"
+  (when (and color1 color2)
+    (cond ((and color1 color2 (symbolp color1) (symbolp color2))
+           (doom-blend (doom-color color1) (doom-color color2) alpha))
+
+          ((or (listp color1) (listp color2))
+           (cl-loop for x in color1
+                    when (if (listp color2) (pop color2) color2)
+                    collect (doom-blend x it alpha)))
+
+          ((and (string-prefix-p "#" color1) (string-prefix-p "#" color2))
+           (apply (lambda (r g b) (format "#%02x%02x%02x" (* r 255) (* g 255) (* b 255)))
+                  (cl-loop for it    in (doom-name-to-rgb color1)
+                           for other in (doom-name-to-rgb color2)
+                           collect (+ (* alpha it) (* other (- 1 alpha))))))
+
+          (t color1))))
+
+;;;###autoload
+(defun doom-darken (color alpha)
+  "Darken a COLOR (a hexidecimal string) by a coefficient ALPHA (a float between
+0 and 1)."
+  (cond ((and color (symbolp color))
+         (doom-darken (doom-color color) alpha))
+
+        ((listp color)
+         (cl-loop for c in color collect (doom-darken c alpha)))
+
+        (t
+         (doom-blend color "#000000" (- 1 alpha)))))
+
+;;;###autoload
+(defun doom-lighten (color alpha)
+  "Brighten a COLOR (a hexidecimal string) by a coefficient ALPHA (a float
+between 0 and 1)."
+  (cond ((and color (symbolp color))
+         (doom-lighten (doom-color color) alpha))
+
+        ((listp color)
+         (cl-loop for c in color collect (doom-lighten c alpha)))
+
+        (t
+         (doom-blend color "#FFFFFF" (- 1 alpha)))))
+
+;;;###autoload
+(defun doom-color (name &optional type)
+  "Retrieve a specific color named NAME (a symbol) from the current theme."
+  (let ((colors (if (listp name)
+                    name
+                  (cdr-safe (assq name doom-themes--colors)))))
+    (and colors
+         (cond ((listp colors)
+                (let ((i (or (plist-get '(256 1 16 2 8 3) type) 0)))
+                  (if (> i (1- (length colors)))
+                      (car (last colors))
+                    (nth i colors))))
+               (t colors)))))
+
+;;;###autoload
+(defun doom-ref (face prop &optional class)
+  "TODO"
+  (let ((spec (or (cdr (assq face doom-themes--faces))
+                  (error "Couldn't find the '%s' face" face))))
+    (when (memq (car spec) '(quote backquote \`))
+      (user-error "Can't fetch the literal spec for '%s'" face))
+    (when class
+      (setq spec (cdr (assq class spec)))
+      (unless spec
+        (error "Couldn't find the '%s' class in the '%s' face"
+               class face)))
+    (unless (plist-member spec prop)
+      (error "Couldn't find the '%s' property in the '%s' face%s"
+             prop face (if class (format "'s '%s' class" class) "")))
+    (plist-get spec prop)))
+
+;;;###autoload
+(defmacro doom-themes-set-faces (theme &rest faces)
+  "Customize THEME (a symbol) with FACES."
+  (declare (indent defun))
+  `(custom-theme-set-faces
+    ,theme
+    ,@(mapcar #'doom-themes--build-face faces)))
+
+(defmacro def-doom-theme (name docstring defs &optional extra-faces extra-vars)
+  "Define a DOOM theme, named NAME (a symbol)."
+  (declare (doc-string 2))
+  (let ((doom-themes--colors defs))
+    `(let* ((bold   doom-themes-enable-bold)
+            (italic doom-themes-enable-italic)
+            ,@defs)
+       (setq doom-themes--colors
+             (list ,@(cl-loop for (var val) in defs
+                              collect `(cons ',var ,val))))
+       (deftheme ,name ,docstring)
+       (custom-theme-set-faces
+        ',name ,@(doom-themes-prepare-facelist extra-faces))
+       (custom-theme-set-variables
+        ',name ,@(doom-themes-prepare-varlist extra-vars))
+       (provide-theme ',name))))
+
+;;;###autoload
+(defun doom-themes-org-config ()
+  "Enable custom fontification and improves doom-themes integration with org-mode."
+  (require 'doom-themes-org))
+
+;;;###autoload
+(defun doom-themes-neotree-config ()
+  "Install doom-themes' neotree configuration.
+
+Includes an Atom-esque icon theme and highlighting based on filetype."
+  (let ((doom-themes--inhibit-warning t))
+    (require 'doom-themes-neotree)))
+
+;;;###autoload
+(defun doom-themes-treemacs-config ()
+  "Install doom-themes' treemacs configuration.
+
+Includes an Atom-esque icon theme and highlighting based on filetype."
+  (require 'doom-themes-treemacs))
+
+;;;###autoload
+(defun doom-themes-visual-bell-config ()
+  "Enable flashing the mode-line on error."
+  (setq ring-bell-function #'doom-themes-visual-bell-fn
+        visible-bell t))
+
+;;;###autoload
+(defun doom-themes-visual-bell-fn ()
+  "Blink the mode-line red briefly. Set `ring-bell-function' to this to use it."
+  (unless doom-themes--bell-p
+    (let ((old-remap (copy-alist face-remapping-alist)))
+      (setq doom-themes--bell-p t)
+      (setq face-remapping-alist
+            (append (delete (assq 'mode-line face-remapping-alist)
+                            face-remapping-alist)
+                    '((mode-line doom-modeline-error))))
+      (force-mode-line-update)
+      (run-with-timer 0.15 nil
+                      (lambda (remap buf)
+                        (with-current-buffer buf
+                          (when (assq 'mode-line face-remapping-alist)
+                            (setq face-remapping-alist remap
+                                  doom-themes--bell-p nil))
+                          (force-mode-line-update)))
+                      old-remap
+                      (current-buffer)))))
+
+;;;###autoload
+(when (and (boundp 'custom-theme-load-path) load-file-name)
+  (let* ((base (file-name-directory load-file-name))
+         (dir (expand-file-name "themes/" base)))
+    (add-to-list 'custom-theme-load-path
+                 (or (and (file-directory-p dir) dir)
+                     base))))
+
+(provide 'doom-themes)
+;;; doom-themes.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-themes.elc b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-themes.elc
new file mode 100644
index 0000000000..57408d0d60
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-themes.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-tomorrow-day-theme.el b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-tomorrow-day-theme.el
new file mode 100644
index 0000000000..01f7aa2a36
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-tomorrow-day-theme.el
@@ -0,0 +1,121 @@
+;;; doom-tomorrow-day-theme.el -- port of tomorrow theme
+;;; Commentary:
+;; This file is part of emacs-doom-themes, which provides license
+;; information.
+;;; Code:
+
+(require 'doom-themes)
+
+(defgroup doom-tomorrow-day-theme nil
+  "Options for doom-themes"
+  :group 'doom-themes)
+
+(defcustom doom-tomorrow-day-padded-modeline doom-themes-padded-modeline
+  "If non-nil, adds a 4px padding to the mode-line.
+Can be an integer to determine the exact padding."
+  :group 'doom-tomorrow-day-theme
+  :type '(or integer boolean))
+
+(def-doom-theme doom-tomorrow-day
+  "A theme based off of Chris Kempson's Tomorrow Dark."
+
+  ;; name        gui       256       16
+  ((bg         '("#ffffff" "white"   "white" ))
+   (bg-alt     '("#eaeaea" nil       nil     ))
+   (base0      '("#f2f2f2" "white"   "white" ))
+   (base1      '("#e4e4e4" "#e4e4e4"         ))
+   (base2      '("#dedede" "#cccccc"         ))
+   (base3      '("#d6d4d4" "#cccccc" "silver"))
+   (base4      '("#C0bfbf" "#c0c0c0" "silver"))
+   (base5      '("#a3a1a1" "#adadad" "silver"))
+   (base6      '("#8a8787" "#949494" "silver"))
+   (base7      '("#696769" "#6b6b6b" "silver"))
+   (base8      '("#000000" "#000000" "black" ))
+   (fg         '("#4d4d4c" "#3a3a3a" "black"))
+   (fg-alt     (doom-darken fg 0.6))
+
+   (grey       '("#a5a4a5" "#999999" "silver"))
+   (red        '("#c82829" "#cc3333" "red"))
+   (orange     '("#f5871f" "#ff9933" "brightred"))
+   (yellow     '("#eab700" "#ffcc00" "yellow"))
+   (green      '("#718c00" "#669900" "green"))
+   (blue       '("#3e999f" "#339999" "brightblue"))
+   (dark-blue  '("#4271ae" "#336699" "blue"))
+   (teal       blue) ; FIXME replace with real teal
+   (magenta    '("#c9b4cf" "#c9b4cf" "magenta"))
+   (violet     '("#8959a8" "#996699" "brightmagenta"))
+   (cyan       '("#8abeb7" "#8abeb7" "cyan"))
+   (dark-cyan  (doom-lighten cyan 0.4))
+
+   ;; face categories
+   (highlight      dark-blue)
+   (vertical-bar   base0)
+   (selection      base3)
+   (builtin        blue)
+   (comments       grey)
+   (doc-comments   (doom-darken grey 0.1))
+   (constants      orange)
+   (functions      blue)
+   (keywords       violet)
+   (methods        blue)
+   (operators      fg)
+   (type           yellow)
+   (strings        green)
+   (variables      red)
+   (numbers        orange)
+   (region         selection)
+   (error          red)
+   (warning        yellow)
+   (success        green)
+   (vc-modified    fg-alt)
+   (vc-added       green)
+   (vc-deleted     red)
+
+   ;; custom categories
+   (modeline-bg     `(,(doom-darken (car bg) 0.1) ,@(cdr base3)))
+   (modeline-bg-alt `(,(doom-darken (car bg) 0.14) ,@(cdr base1)))
+   (modeline-fg     base8)
+   (modeline-fg-alt comments)
+   (-modeline-pad
+    (when doom-tomorrow-day-padded-modeline
+      (if (integerp doom-tomorrow-day-padded-modeline)
+          doom-tomorrow-day-padded-modeline
+        4))))
+
+  ;; --- faces ------------------------------
+  ((doom-modeline-buffer-path       :foreground violet :bold bold)
+   (doom-modeline-buffer-major-mode :inherit 'doom-modeline-buffer-path)
+
+   ((line-number &override) :foreground base4)
+   ((line-number-current-line &override) :foreground blue :bold bold)
+
+   (ivy-current-match :background region :distant-foreground grey :weight 'ultra-bold)
+   (ivy-minibuffer-match-face-1
+    :foreground base5
+    :weight 'light)
+   (ivy-minibuffer-match-face-2 :inherit 'ivy-minibuffer-match-face-1 :foreground violet :weight 'ultra-bold)
+   (ivy-minibuffer-match-face-3 :inherit 'ivy-minibuffer-match-face-2 :foreground blue)
+   (ivy-minibuffer-match-face-4 :inherit 'ivy-minibuffer-match-face-2 :foreground red)
+
+   ;; rainbow-delimiters
+   (rainbow-delimiters-depth-1-face :foreground violet)
+   (rainbow-delimiters-depth-2-face :foreground blue)
+   (rainbow-delimiters-depth-3-face :foreground orange)
+   (rainbow-delimiters-depth-4-face :foreground green)
+   (rainbow-delimiters-depth-5-face :foreground magenta)
+   (rainbow-delimiters-depth-6-face :foreground yellow)
+   (rainbow-delimiters-depth-7-face :foreground teal)
+
+   (mode-line
+    :background modeline-bg :foreground modeline-fg
+    :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))
+   (mode-line-inactive
+    :background modeline-bg-alt :foreground modeline-fg-alt
+    :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-alt))))
+
+  ;; --- variables --------------------------
+  ;; ()
+  )
+
+(provide 'doom-tomorrow-day-theme)
+;;; doom-tomorrow-day-theme.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-tomorrow-day-theme.elc b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-tomorrow-day-theme.elc
new file mode 100644
index 0000000000..2eb1be576d
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-tomorrow-day-theme.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-tomorrow-night-theme.el b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-tomorrow-night-theme.el
new file mode 100644
index 0000000000..c90b69b0d6
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-tomorrow-night-theme.el
@@ -0,0 +1,108 @@
+;;; doom-tomorrow-night-theme.el
+(require 'doom-themes)
+
+(defgroup doom-tomorrow-night-theme nil
+  "Options for doom-themes"
+  :group 'doom-themes)
+
+(defcustom doom-tomorrow-night-padded-modeline doom-themes-padded-modeline
+  "If non-nil, adds a 4px padding to the mode-line. Can be an integer to
+determine the exact padding."
+  :group 'doom-tomorrow-night-theme
+  :type '(or integer boolean))
+
+(def-doom-theme doom-tomorrow-night
+  "A theme based off of Chris Kempson's Tomorrow Dark."
+
+  ;; name        gui       256       16
+  ((bg         '("#1d1f21" nil       nil          ))
+   (bg-alt     '("#232527" nil       nil          ))
+   (base0      '("#0d0d0d" "black"   "black"      ))
+   (base1      '("#1b1b1b" "#1b1b1b"              ))
+   (base2      '("#212122" "#1e1e1e"              ))
+   (base3      '("#292b2b" "#292929" "brightblack"))
+   (base4      '("#3f4040" "#3f3f3f" "brightblack"))
+   (base5      '("#5c5e5e" "#525252" "brightblack"))
+   (base6      '("#757878" "#6b6b6b" "brightblack"))
+   (base7      '("#969896" "#979797" "brightblack"))
+   (base8      '("#ffffff" "#ffffff" "white"      ))
+   (fg         '("#c5c8c6" "#c5c5c5" "white"))
+   (fg-alt     (doom-darken fg 0.6))
+
+   (grey       '("#5a5b5a" "#5a5a5a" "brightblack"))
+   (red        '("#cc6666" "#cc6666" "red"))
+   (orange     '("#de935f" "#dd9955" "brightred"))
+   (yellow     '("#f0c674" "#f0c674" "yellow"))
+   (green      '("#b5bd68" "#b5bd68" "green"))
+   (blue       '("#81a2be" "#88aabb" "brightblue"))
+   (dark-blue  '("#41728e" "#41728e" "blue"))
+   (teal       blue) ; FIXME replace with real teal
+   (magenta    '("#c9b4cf" "#c9b4cf" "magenta"))
+   (violet     '("#b294bb" "#b294bb" "brightmagenta"))
+   (cyan       '("#8abeb7" "#8abeb7" "cyan"))
+   (dark-cyan  (doom-darken cyan 0.4))
+
+   ;; face categories
+   (highlight      dark-blue)
+   (vertical-bar   base0)
+   (selection      (doom-lighten bg 0.1))
+   (builtin        blue)
+   (comments       grey)
+   (doc-comments   (doom-lighten grey 0.1))
+   (constants      orange)
+   (functions      blue)
+   (keywords       violet)
+   (methods        blue)
+   (operators      fg)
+   (type           yellow)
+   (strings        green)
+   (variables      red)
+   (numbers        orange)
+   (region         selection)
+   (error          red)
+   (warning        yellow)
+   (success        green)
+   (vc-modified    fg-alt)
+   (vc-added       green)
+   (vc-deleted     red)
+
+   ;; custom categories
+   (modeline-bg     `(,(doom-darken (car bg-alt) 0.3) ,@(cdr base3)))
+   (modeline-bg-alt `(,(car bg) ,@(cdr base1)))
+   (modeline-fg     base8)
+   (modeline-fg-alt comments)
+   (-modeline-pad
+    (when doom-tomorrow-night-padded-modeline
+      (if (integerp doom-tomorrow-night-padded-modeline)
+          doom-tomorrow-night-padded-modeline
+        4))))
+
+  ;; --- faces ------------------------------
+  ((doom-modeline-buffer-path       :foreground violet :bold bold)
+   (doom-modeline-buffer-major-mode :inherit 'doom-modeline-buffer-path)
+
+   ((line-number &override) :foreground base4)
+   ((line-number-current-line &override) :foreground blue :bold bold)
+
+   ;; rainbow-delimiters
+   (rainbow-delimiters-depth-1-face :foreground violet)
+   (rainbow-delimiters-depth-2-face :foreground blue)
+   (rainbow-delimiters-depth-3-face :foreground orange)
+   (rainbow-delimiters-depth-4-face :foreground green)
+   (rainbow-delimiters-depth-5-face :foreground magenta)
+   (rainbow-delimiters-depth-6-face :foreground yellow)
+   (rainbow-delimiters-depth-7-face :foreground teal)
+
+   (mode-line
+    :background modeline-bg :foreground modeline-fg
+    :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))
+   (mode-line-inactive
+    :background modeline-bg-alt :foreground modeline-fg-alt
+    :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-alt))))
+
+  ;; --- variables --------------------------
+  ;; ()
+  )
+
+(provide 'doom-tomorrow-night-theme)
+;;; doom-tomorrow-night-theme.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-tomorrow-night-theme.elc b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-tomorrow-night-theme.elc
new file mode 100644
index 0000000000..b67d063559
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-tomorrow-night-theme.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-vibrant-theme.el b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-vibrant-theme.el
new file mode 100644
index 0000000000..296bb3b39d
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-vibrant-theme.el
@@ -0,0 +1,162 @@
+;; doom-vibrant-theme.el --- a more vibrant version of doom-one
+(require 'doom-themes)
+
+;;
+(defgroup doom-vibrant-theme nil
+  "Options for doom-themes"
+  :group 'doom-themes)
+
+(defcustom doom-vibrant-brighter-modeline nil
+  "If non-nil, more vivid colors will be used to style the mode-line."
+  :group 'doom-vibrant-theme
+  :type 'boolean)
+
+(defcustom doom-vibrant-brighter-comments nil
+  "If non-nil, comments will be highlighted in more vivid colors."
+  :group 'doom-vibrant-theme
+  :type 'boolean)
+
+(defcustom doom-vibrant-comment-bg doom-vibrant-brighter-comments
+  "If non-nil, comments will have a subtle, darker background. Enhancing their
+legibility."
+  :group 'doom-vibrant-theme
+  :type 'boolean)
+
+(defcustom doom-vibrant-padded-modeline doom-themes-padded-modeline
+  "If non-nil, adds a 4px padding to the mode-line. Can be an integer to
+determine the exact padding."
+  :group 'doom-vibrant-theme
+  :type '(or integer boolean))
+
+
+;;
+(def-doom-theme doom-vibrant
+  "A dark theme based off of doom-one with more vibrant colors."
+
+  ;; name        gui       256       16
+  ((bg         '("#242730" nil       nil))
+   (bg-alt     '("#2a2e38" nil       nil))
+   (base0      '("#1c1f24" "#101010" "black"        ))
+   (base1      '("#1c1f24" "#1e1e1e" "brightblack"  ))
+   (base2      '("#21272d" "#21212d" "brightblack"  ))
+   (base3      '("#23272e" "#262626" "brightblack"  ))
+   (base4      '("#484854" "#5e5e5e" "brightblack"  ))
+   (base5      '("#62686E" "#666666" "brightblack"  ))
+   (base6      '("#757B80" "#7b7b7b" "brightblack"  ))
+   (base7      '("#9ca0a4" "#979797" "brightblack"  ))
+   (base8      '("#DFDFDF" "#dfdfdf" "white"        ))
+   (fg         '("#bbc2cf" "#bfbfbf" ))
+   (fg-alt     '("#5D656B" "#5d5d5d" ))
+
+   (grey       base4)
+   (red        '("#ff665c" "#ff6655" ))
+   (orange     '("#e69055" "#dd8844" ))
+   (green      '("#7bc275" "#99bb66" ))
+   (teal       '("#4db5bd" "#44b9b1" ))
+   (yellow     '("#FCCE7B"           ))
+   (blue       '("#51afef"           ))
+   (dark-blue  '("#1f5582"           ))
+   (magenta    '("#C57BDB"           ))
+   (violet     '("#a991f1"           )) ;a9a1e1
+   (cyan       '("#5cEfFF"           ))
+   (dark-cyan  '("#6A8FBF"           ))
+
+   ;; face categories
+   (highlight      blue)
+   (vertical-bar   base0)
+   (selection      dark-blue)
+   (builtin        magenta)
+   (comments       (if doom-vibrant-brighter-comments dark-cyan base5))
+   (doc-comments   (if doom-vibrant-brighter-comments (doom-lighten dark-cyan 0.15) (doom-lighten base4 0.3)))
+   (constants      violet)
+   (functions      cyan)
+   (keywords       blue)
+   (methods        violet)
+   (operators      magenta)
+   (type           yellow)
+   (strings        green)
+   (variables      base8)
+   (numbers        orange)
+   (region         "#3d4451")
+   (error          red)
+   (warning        yellow)
+   (success        green)
+   (vc-modified    yellow)
+   (vc-added       green)
+   (vc-deleted     red)
+
+   ;; custom categories
+   (hidden     `(,(car bg) "black" "black"))
+   (hidden-alt `(,(car bg-alt) "black" "black"))
+   (-modeline-pad
+    (when doom-vibrant-padded-modeline
+      (if (integerp doom-vibrant-padded-modeline) doom-vibrant-padded-modeline 4)))
+
+   (modeline-fg     "#bbc2cf")
+   (modeline-fg-alt (doom-blend blue grey (if doom-vibrant-brighter-modeline 0.4 0.08)))
+
+   (modeline-bg
+    (if doom-vibrant-brighter-modeline
+        `("#383f58" ,@(cdr base1))
+      `(,(car bg-alt) ,@(cdr base0))))
+   (modeline-bg-l
+    (if doom-vibrant-brighter-modeline
+        modeline-bg
+      `(,(doom-darken (car bg) 0.15) ,@(cdr base1))))
+   (modeline-bg-inactive   (doom-darken bg 0.25))
+   (modeline-bg-inactive-l `(,(doom-darken (car bg-alt) 0.2) ,@(cdr base0))))
+
+
+  ;; --- extra faces ------------------------
+  ((elscreen-tab-other-screen-face :background "#353a42" :foreground "#1e2022")
+
+   (font-lock-comment-face
+    :foreground comments
+    :background (if doom-vibrant-comment-bg (doom-darken bg-alt 0.095)))
+   (font-lock-doc-face
+    :inherit 'font-lock-comment-face
+    :foreground doc-comments)
+
+   ((line-number &override) :foreground base4)
+   ((line-number-current-line &override) :foreground blue :bold bold)
+
+   (doom-modeline-bar :background (if doom-vibrant-brighter-modeline modeline-bg highlight))
+   (doom-modeline-buffer-path :foreground (if doom-vibrant-brighter-modeline base8 blue) :bold bold)
+
+   (mode-line
+    :background modeline-bg :foreground modeline-fg
+    :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg)))
+   (mode-line-inactive
+    :background modeline-bg-inactive :foreground modeline-fg-alt
+    :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive)))
+   (mode-line-emphasis
+    :foreground (if doom-vibrant-brighter-modeline base8 highlight))
+
+   (solaire-mode-line-face
+    :inherit 'mode-line
+    :background modeline-bg-l
+    :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-l)))
+   (solaire-mode-line-inactive-face
+    :inherit 'mode-line-inactive
+    :background modeline-bg-inactive-l
+    :box (if -modeline-pad `(:line-width ,-modeline-pad :color ,modeline-bg-inactive-l)))
+
+   ;; --- major-mode faces -------------------
+   ;; css-mode / scss-mode
+   (css-proprietary-property :foreground orange)
+   (css-property             :foreground green)
+   (css-selector             :foreground blue)
+
+   ;; markdown-mode
+   (markdown-header-face :inherit 'bold :foreground red)
+
+   ;; org-mode
+   (org-hide :foreground hidden)
+   (solaire-org-hide-face :foreground hidden-alt))
+
+
+  ;; --- extra variables --------------------
+  ;; ()
+  )
+
+;;; doom-vibrant-theme.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-vibrant-theme.elc b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-vibrant-theme.elc
new file mode 100644
index 0000000000..57cbbf7607
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/doom-themes-20180720.438/doom-vibrant-theme.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/elisp-slime-nav-20160128.1109/elisp-slime-nav-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/elisp-slime-nav-20160128.1109/elisp-slime-nav-autoloads.el
new file mode 100644
index 0000000000..0cf4313593
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/elisp-slime-nav-20160128.1109/elisp-slime-nav-autoloads.el
@@ -0,0 +1,49 @@
+;;; elisp-slime-nav-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "elisp-slime-nav" "elisp-slime-nav.el" (23377
+;;;;;;  61613 957143 248000))
+;;; Generated autoloads from elisp-slime-nav.el
+
+(autoload 'elisp-slime-nav-mode "elisp-slime-nav" "\
+Enable Slime-style navigation of elisp symbols using M-. and M-,
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'turn-on-elisp-slime-nav-mode "elisp-slime-nav" "\
+Explicitly enable `elisp-slime-nav-mode'.
+
+\(fn)" nil nil)
+
+(autoload 'elisp-slime-nav-find-elisp-thing-at-point "elisp-slime-nav" "\
+Find the elisp thing at point, be it a function, variable, library or face.
+
+With a prefix arg, or if there is no thing at point, prompt for
+the symbol to jump to.
+
+Argument SYM-NAME is the thing to find.
+
+\(fn SYM-NAME)" t nil)
+
+(autoload 'elisp-slime-nav-describe-elisp-thing-at-point "elisp-slime-nav" "\
+Display the full documentation of the elisp thing at point.
+
+The named subject may be a function, variable, library or face.
+
+With a prefix arg, or if there is not \"thing\" at point, prompt
+for the symbol to jump to.
+
+Argument SYM-NAME is the thing to find.
+
+\(fn SYM-NAME)" t nil)
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; elisp-slime-nav-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/elisp-slime-nav-20160128.1109/elisp-slime-nav-pkg.el b/configs/shared/emacs/.emacs.d/elpa/elisp-slime-nav-20160128.1109/elisp-slime-nav-pkg.el
new file mode 100644
index 0000000000..fe6e5d7bf2
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/elisp-slime-nav-20160128.1109/elisp-slime-nav-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "elisp-slime-nav" "20160128.1109" "Make M-. and M-, work in elisp like they do in slime" '((cl-lib "0.2")))
diff --git a/configs/shared/emacs/.emacs.d/elpa/elisp-slime-nav-20160128.1109/elisp-slime-nav.el b/configs/shared/emacs/.emacs.d/elpa/elisp-slime-nav-20160128.1109/elisp-slime-nav.el
new file mode 100644
index 0000000000..267d39fecd
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/elisp-slime-nav-20160128.1109/elisp-slime-nav.el
@@ -0,0 +1,140 @@
+;;; elisp-slime-nav.el --- Make M-. and M-, work in elisp like they do in slime
+
+;; Copyright (C) 2016  Steve Purcell
+
+;; Author: Steve Purcell <steve@sanityinc.com>
+;; Keywords: navigation slime elisp emacs-lisp
+;; URL: https://github.com/purcell/elisp-slime-nav
+;; Package-Version: 20160128.1109
+;; Package-X-Original-Version: 0
+;; Package-Requires: ((cl-lib "0.2"))
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;
+;; This package provides Slime's convenient "M-." and "M-," navigation
+;; in `emacs-lisp-mode', together with an elisp equivalent of
+;; `slime-describe-symbol', bound by default to `C-c C-d d`.
+;;
+;; When the main functions are given a prefix argument, they will
+;; prompt for the symbol upon which to operate.
+;;
+;; Usage:
+;;
+;; Enable the package in elisp and ielm modes as follows:
+;;
+;;   (require 'elisp-slime-nav) ;; optional if installed via package.el
+;;   (dolist (hook '(emacs-lisp-mode-hook ielm-mode-hook))
+;;     (add-hook hook 'turn-on-elisp-slime-nav-mode))
+;;
+;; Known issues:
+;;
+;;   When navigating into Emacs' C source, "M-," will not be bound to
+;;   the same command, but "M-*" will typically do the trick.
+;;
+;;; Code:
+
+(require 'etags)
+(require 'help-mode)
+
+(defvar elisp-slime-nav-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "M-.")         'elisp-slime-nav-find-elisp-thing-at-point)
+    (define-key map (kbd "M-,")         'pop-tag-mark)
+    (define-key map (kbd "C-c C-d d")   'elisp-slime-nav-describe-elisp-thing-at-point)
+    (define-key map (kbd "C-c C-d C-d") 'elisp-slime-nav-describe-elisp-thing-at-point)
+    map))
+
+;;;###autoload
+(define-minor-mode elisp-slime-nav-mode
+  "Enable Slime-style navigation of elisp symbols using M-. and M-,"
+  nil " SliNav" elisp-slime-nav-mode-map)
+
+;;;###autoload
+(defun turn-on-elisp-slime-nav-mode ()
+  "Explicitly enable `elisp-slime-nav-mode'."
+  (elisp-slime-nav-mode 1))
+
+(defun elisp-slime-nav--all-navigable-symbol-names ()
+  "Return a list of strings for the symbols to which navigation is possible."
+  (let ((result '()))
+    (mapatoms
+     (lambda (x)
+       (when (or (fboundp x) (boundp x) (symbol-plist x) (facep x))
+         (push (symbol-name x) result))))
+    result))
+
+(defun elisp-slime-nav--read-symbol-at-point ()
+  "Return the symbol at point as a string.
+If `current-prefix-arg' is not nil, the user is prompted for the symbol."
+  (let* ((sym-at-point (symbol-at-point))
+         (at-point (and sym-at-point (symbol-name sym-at-point))))
+    (if (or current-prefix-arg (null at-point))
+        (completing-read "Symbol: "
+                         (elisp-slime-nav--all-navigable-symbol-names)
+                         nil t nil nil at-point)
+      at-point)))
+
+;;;###autoload
+(defun elisp-slime-nav-find-elisp-thing-at-point (sym-name)
+  "Find the elisp thing at point, be it a function, variable, library or face.
+
+With a prefix arg, or if there is no thing at point, prompt for
+the symbol to jump to.
+
+Argument SYM-NAME is the thing to find."
+  (interactive (list (elisp-slime-nav--read-symbol-at-point)))
+  (when sym-name
+    (let ((sym (intern sym-name)))
+      (message "Searching for %s..." sym-name)
+      (if (fboundp 'xref-push-marker-stack)
+          (xref-push-marker-stack)
+        (with-no-warnings
+          (ring-insert find-tag-marker-ring (point-marker))))
+      (cond
+       ((fboundp sym)
+        (find-function sym))
+       ((boundp sym)
+        (find-variable sym))
+       ((or (featurep sym) (locate-library sym-name))
+        (find-library sym-name))
+       ((facep sym)
+        (find-face-definition sym))
+       (t
+        (pop-tag-mark)
+        (error "Don't know how to find '%s'" sym))))))
+
+;;;###autoload
+(defun elisp-slime-nav-describe-elisp-thing-at-point (sym-name)
+  "Display the full documentation of the elisp thing at point.
+
+The named subject may be a function, variable, library or face.
+
+With a prefix arg, or if there is not \"thing\" at point, prompt
+for the symbol to jump to.
+
+Argument SYM-NAME is the thing to find."
+  (interactive (list (elisp-slime-nav--read-symbol-at-point)))
+  (if (fboundp 'describe-symbol)
+      (describe-symbol (intern sym-name))
+    (with-no-warnings
+      (help-xref-interned (intern sym-name)))))
+
+
+(provide 'elisp-slime-nav)
+;; Local Variables:
+;; indent-tabs-mode: nil
+;; End:
+;;; elisp-slime-nav.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/elisp-slime-nav-20160128.1109/elisp-slime-nav.elc b/configs/shared/emacs/.emacs.d/elpa/elisp-slime-nav-20160128.1109/elisp-slime-nav.elc
new file mode 100644
index 0000000000..c861b56ae0
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/elisp-slime-nav-20160128.1109/elisp-slime-nav.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/emojify-20180611.838/data/emoji-sets.json b/configs/shared/emacs/.emacs.d/elpa/emojify-20180611.838/data/emoji-sets.json
new file mode 100644
index 0000000000..f501830271
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/emojify-20180611.838/data/emoji-sets.json
@@ -0,0 +1,26 @@
+{
+    "emojione-v2-22" : {
+        "description" : "Emojis provided by Emoji One (version 2), resized to 22px",
+        "website" : "http://emojione.com",
+        "url" : "https://github.com/iqbalansari/emacs-emojify/blob/a81cfd11cdd0eb5b6840d2a7fe95a9505195c1a3/emojione-v2-22.tar?raw=true",
+        "sha256" : "adbe3cf2c776fe7daf375d8e8dbd4c40567a1dbb753dce1d05e61a2f815572d3"
+    },
+    "emojione-v2" : {
+        "description" : "Emojis provided by Emoji One (version 2)",
+        "website" : "http://emojione.com",
+        "url" : "https://github.com/iqbalansari/emacs-emojify/blob/a81cfd11cdd0eb5b6840d2a7fe95a9505195c1a3/emojione-v2.tar?raw=true",
+        "sha256" : "46c5a600a148897da22d42d36f42ad764868568943e96917c33e0fe44113afef"
+    },
+    "emojione-v2.2.6-22" : {
+        "description" : "Emojis provided by Emoji One (version 2.2.6), resized to 22px",
+        "website" : "http://emojione.com",
+        "url" : "https://github.com/iqbalansari/emacs-emojify/blob/4e91ba8c2b3415cd78f53e7026fc76b9ac935fc3/emojione-v2.2.6-22.tar?raw=true",
+        "sha256" : "56dede1c77ad690eebc21e00913b9c7525d290f1a936f87aad282014b04bf2a7"
+    },
+    "emojione-v2.2.6" : {
+        "description" : "Emojis provided by Emoji One (version 2.2.6)",
+        "website" : "http://emojione.com",
+        "url" : "https://github.com/iqbalansari/emacs-emojify/blob/4e91ba8c2b3415cd78f53e7026fc76b9ac935fc3/emojione-v2.2.6.tar?raw=true",
+        "sha256" : "416b5807d9836a7030434710c9b859accce1e2e5c3c0dcae8ef2a0d9483ff2e9"
+    }
+}
diff --git a/configs/shared/emacs/.emacs.d/elpa/emojify-20180611.838/data/emoji.json b/configs/shared/emacs/.emacs.d/elpa/emojify-20180611.838/data/emoji.json
new file mode 100644
index 0000000000..020a637d09
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/emojify-20180611.838/data/emoji.json
@@ -0,0 +1,31306 @@
+{
+    ":man-with-gua-pi-mao-tone3:": {
+        "style": "github", 
+        "image": "1f472-1f3fd.png", 
+        "unicode": "👲🏽", 
+        "name": "Man With Gua Pi Mao - Tone 3"
+    }, 
+    ":couplekiss_mm:": {
+        "style": "github", 
+        "image": "1f468-2764-1f48b-1f468.png", 
+        "unicode": "👨❤💋👨", 
+        "name": "Kiss (man,man)"
+    }, 
+    "🎍": {
+        "style": "unicode", 
+        "image": "1f38d.png", 
+        "name": "Pine Decoration"
+    }, 
+    ":thumbsup-tone5:": {
+        "style": "github", 
+        "image": "1f44d-1f3ff.png", 
+        "unicode": "👍🏿", 
+        "name": "Thumbs Up Sign - Tone 5"
+    }, 
+    "🦑": {
+        "style": "unicode", 
+        "image": "1f991.png", 
+        "name": "Squid"
+    }, 
+    ":mp:": {
+        "style": "github", 
+        "image": "1f1f2-1f1f5.png", 
+        "unicode": "🇲🇵", 
+        "name": "Northern Mariana Islands"
+    }, 
+    ":person_frowning_tone2:": {
+        "style": "github", 
+        "image": "1f64d-1f3fc.png", 
+        "unicode": "🙍🏼", 
+        "name": "Person Frowning - Tone 2"
+    }, 
+    ":point-up-tone2:": {
+        "style": "github", 
+        "image": "261d-1f3fc.png", 
+        "unicode": "☝🏼", 
+        "name": "White Up Pointing Index - Tone 2"
+    }, 
+    "🤦": {
+        "style": "unicode", 
+        "image": "1f926.png", 
+        "name": "Face Palm"
+    }, 
+    ":raised_hands_tone3:": {
+        "style": "github", 
+        "image": "1f64c-1f3fd.png", 
+        "unicode": "🙌🏽", 
+        "name": "Person Raising Both Hands In Celebration - Tone 3"
+    }, 
+    ":face_with_head_bandage:": {
+        "style": "github", 
+        "image": "1f915.png", 
+        "unicode": "🤕", 
+        "name": "Face With Head-bandage"
+    }, 
+    ":school_satchel:": {
+        "style": "github", 
+        "image": "1f392.png", 
+        "unicode": "🎒", 
+        "name": "School Satchel"
+    }, 
+    "✅": {
+        "style": "unicode", 
+        "image": "2705.png", 
+        "name": "White Heavy Check Mark"
+    }, 
+    ":guardsman_tone5:": {
+        "style": "github", 
+        "image": "1f482-1f3ff.png", 
+        "unicode": "💂🏿", 
+        "name": "Guardsman - Tone 5"
+    }, 
+    ":yum:": {
+        "style": "github", 
+        "image": "1f60b.png", 
+        "unicode": "😋", 
+        "name": "Face Savouring Delicious Food"
+    }, 
+    "😏": {
+        "style": "unicode", 
+        "image": "1f60f.png", 
+        "name": "Smirking Face"
+    }, 
+    ":red_car:": {
+        "style": "github", 
+        "image": "1f697.png", 
+        "unicode": "🚗", 
+        "name": "Automobile"
+    }, 
+    "↖": {
+        "style": "unicode", 
+        "image": "2196.png", 
+        "name": "North West Arrow"
+    }, 
+    "🚤": {
+        "style": "unicode", 
+        "image": "1f6a4.png", 
+        "name": "Speedboat"
+    }, 
+    "☯": {
+        "style": "unicode", 
+        "image": "262f.png", 
+        "name": "Yin Yang"
+    }, 
+    ":v_tone5:": {
+        "style": "github", 
+        "image": "270c-1f3ff.png", 
+        "unicode": "✌🏿", 
+        "name": "Victory Hand - Tone 5"
+    }, 
+    ":bar-chart:": {
+        "style": "github", 
+        "image": "1f4ca.png", 
+        "unicode": "📊", 
+        "name": "Bar Chart"
+    }, 
+    ":flag-ls:": {
+        "style": "github", 
+        "image": "1f1f1-1f1f8.png", 
+        "unicode": "🇱🇸", 
+        "name": "Lesotho"
+    }, 
+    "🔹": {
+        "style": "unicode", 
+        "image": "1f539.png", 
+        "name": "Small Blue Diamond"
+    }, 
+    ":slight_smile:": {
+        "style": "github", 
+        "ascii": ":)", 
+        "image": "1f642.png", 
+        "unicode": "🙂", 
+        "name": "Slightly Smiling Face"
+    }, 
+    ":secret:": {
+        "style": "github", 
+        "image": "3299.png", 
+        "unicode": "㊙", 
+        "name": "Circled Ideograph Secret"
+    }, 
+    "⛄": {
+        "style": "unicode", 
+        "image": "26c4.png", 
+        "name": "Snowman Without Snow"
+    }, 
+    ":hand_splayed_tone2:": {
+        "style": "github", 
+        "image": "1f590-1f3fc.png", 
+        "unicode": "🖐🏼", 
+        "name": "Raised Hand With Fingers Splayed - Tone 2"
+    }, 
+    ":family_mwg:": {
+        "style": "github", 
+        "image": "1f468-1f469-1f467.png", 
+        "unicode": "👨👩👧", 
+        "name": "Family (man,woman,girl)"
+    }, 
+    ":flag_ae:": {
+        "style": "github", 
+        "image": "1f1e6-1f1ea.png", 
+        "unicode": "🇦🇪", 
+        "name": "The United Arab Emirates"
+    }, 
+    "👣": {
+        "style": "unicode", 
+        "image": "1f463.png", 
+        "name": "Footprints"
+    }, 
+    ":blue-car:": {
+        "style": "github", 
+        "image": "1f699.png", 
+        "unicode": "🚙", 
+        "name": "Recreational Vehicle"
+    }, 
+    ":man_dancing_tone3:": {
+        "style": "github", 
+        "image": "1f57a-1f3fd.png", 
+        "unicode": "🕺🏽", 
+        "name": "Man Dancing - Tone 3"
+    }, 
+    ":basketball-player-tone5:": {
+        "style": "github", 
+        "image": "26f9-1f3ff.png", 
+        "unicode": "⛹🏿", 
+        "name": "Person With Ball - Tone 5"
+    }, 
+    ":man_tone2:": {
+        "style": "github", 
+        "image": "1f468-1f3fc.png", 
+        "unicode": "👨🏼", 
+        "name": "Man - Tone 2"
+    }, 
+    "📸": {
+        "style": "unicode", 
+        "image": "1f4f8.png", 
+        "name": "Camera With Flash"
+    }, 
+    ":kiwifruit:": {
+        "style": "github", 
+        "image": "1f95d.png", 
+        "unicode": "🥝", 
+        "name": "Kiwifruit"
+    }, 
+    ":studio_microphone:": {
+        "style": "github", 
+        "image": "1f399.png", 
+        "unicode": "🎙", 
+        "name": "Studio Microphone"
+    }, 
+    ":flag_ve:": {
+        "style": "github", 
+        "image": "1f1fb-1f1ea.png", 
+        "unicode": "🇻🇪", 
+        "name": "Venezuela"
+    }, 
+    ":sm:": {
+        "style": "github", 
+        "image": "1f1f8-1f1f2.png", 
+        "unicode": "🇸🇲", 
+        "name": "San Marino"
+    }, 
+    ":wilted-rose:": {
+        "style": "github", 
+        "image": "1f940.png", 
+        "unicode": "🥀", 
+        "name": "Wilted Flower"
+    }, 
+    "⬜": {
+        "style": "unicode", 
+        "image": "2b1c.png", 
+        "name": "White Large Square"
+    }, 
+    ":family_mwbb:": {
+        "style": "github", 
+        "image": "1f468-1f469-1f466-1f466.png", 
+        "unicode": "👨👩👦👦", 
+        "name": "Family (man,woman,boy,boy)"
+    }, 
+    "🎷": {
+        "style": "unicode", 
+        "image": "1f3b7.png", 
+        "name": "Saxophone"
+    }, 
+    ":prayer_beads:": {
+        "style": "github", 
+        "image": "1f4ff.png", 
+        "unicode": "📿", 
+        "name": "Prayer Beads"
+    }, 
+    ":regional_indicator_b:": {
+        "style": "github", 
+        "image": "1f1e7.png", 
+        "unicode": "🇧", 
+        "name": "Regional Indicator Symbol Letter B"
+    }, 
+    "🍌": {
+        "style": "unicode", 
+        "image": "1f34c.png", 
+        "name": "Banana"
+    }, 
+    "🥐": {
+        "style": "unicode", 
+        "image": "1f950.png", 
+        "name": "Croissant"
+    }, 
+    ":middle_finger_tone3:": {
+        "style": "github", 
+        "image": "1f595-1f3fd.png", 
+        "unicode": "🖕🏽", 
+        "name": "Reversed Hand With Middle Finger Extended - Tone 3"
+    }, 
+    ":sl:": {
+        "style": "github", 
+        "image": "1f1f8-1f1f1.png", 
+        "unicode": "🇸🇱", 
+        "name": "Sierra Leone"
+    }, 
+    "🛥": {
+        "style": "unicode", 
+        "image": "1f6e5.png", 
+        "name": "Motorboat"
+    }, 
+    ":left_right_arrow:": {
+        "style": "github", 
+        "image": "2194.png", 
+        "unicode": "↔", 
+        "name": "Left Right Arrow"
+    }, 
+    ":flag-tc:": {
+        "style": "github", 
+        "image": "1f1f9-1f1e8.png", 
+        "unicode": "🇹🇨", 
+        "name": "Turks And Caicos Islands"
+    }, 
+    ":place-of-worship:": {
+        "style": "github", 
+        "image": "1f6d0.png", 
+        "unicode": "🛐", 
+        "name": "Place Of Worship"
+    }, 
+    ":wave_tone5:": {
+        "style": "github", 
+        "image": "1f44b-1f3ff.png", 
+        "unicode": "👋🏿", 
+        "name": "Waving Hand Sign - Tone 5"
+    }, 
+    ":tired_face:": {
+        "style": "github", 
+        "image": "1f62b.png", 
+        "unicode": "😫", 
+        "name": "Tired Face"
+    }, 
+    "💖": {
+        "style": "unicode", 
+        "image": "1f496.png", 
+        "name": "Sparkling Heart"
+    }, 
+    ":pen_ballpoint:": {
+        "style": "github", 
+        "image": "1f58a.png", 
+        "unicode": "🖊", 
+        "name": "Lower Left Ballpoint Pen"
+    }, 
+    ":two_women_holding_hands:": {
+        "style": "github", 
+        "image": "1f46d.png", 
+        "unicode": "👭", 
+        "name": "Two Women Holding Hands"
+    }, 
+    ":relaxed:": {
+        "style": "github", 
+        "image": "263a.png", 
+        "unicode": "☺", 
+        "name": "White Smiling Face"
+    }, 
+    ":large_orange_diamond:": {
+        "style": "github", 
+        "image": "1f536.png", 
+        "unicode": "🔶", 
+        "name": "Large Orange Diamond"
+    }, 
+    ":flag_ao:": {
+        "style": "github", 
+        "image": "1f1e6-1f1f4.png", 
+        "unicode": "🇦🇴", 
+        "name": "Angola"
+    }, 
+    ":flag_pw:": {
+        "style": "github", 
+        "image": "1f1f5-1f1fc.png", 
+        "unicode": "🇵🇼", 
+        "name": "Palau"
+    }, 
+    "🐹": {
+        "style": "unicode", 
+        "image": "1f439.png", 
+        "name": "Hamster Face"
+    }, 
+    ":flag-mt:": {
+        "style": "github", 
+        "image": "1f1f2-1f1f9.png", 
+        "unicode": "🇲🇹", 
+        "name": "Malta"
+    }, 
+    ":pregnant-woman-tone1:": {
+        "style": "github", 
+        "image": "1f930-1f3fb.png", 
+        "unicode": "🤰🏻", 
+        "name": "Pregnant Woman - Tone 1"
+    }, 
+    ":writing-hand:": {
+        "style": "github", 
+        "image": "270d.png", 
+        "unicode": "✍", 
+        "name": "Writing Hand"
+    }, 
+    ":water_polo_tone5:": {
+        "style": "github", 
+        "image": "1f93d-1f3ff.png", 
+        "unicode": "🤽🏿", 
+        "name": "Water Polo - Tone 5"
+    }, 
+    ":deciduous_tree:": {
+        "style": "github", 
+        "image": "1f333.png", 
+        "unicode": "🌳", 
+        "name": "Deciduous Tree"
+    }, 
+    "📎": {
+        "style": "unicode", 
+        "image": "1f4ce.png", 
+        "name": "Paperclip"
+    }, 
+    ":no-entry-sign:": {
+        "style": "github", 
+        "image": "1f6ab.png", 
+        "unicode": "🚫", 
+        "name": "No Entry Sign"
+    }, 
+    ":flag-sc:": {
+        "style": "github", 
+        "image": "1f1f8-1f1e8.png", 
+        "unicode": "🇸🇨", 
+        "name": "The Seychelles"
+    }, 
+    ":flag-kr:": {
+        "style": "github", 
+        "image": "1f1f0-1f1f7.png", 
+        "unicode": "🇰🇷", 
+        "name": "Korea"
+    }, 
+    "🕣": {
+        "style": "unicode", 
+        "image": "1f563.png", 
+        "name": "Clock Face Eight-thirty"
+    }, 
+    ":raising-hand-tone2:": {
+        "style": "github", 
+        "image": "1f64b-1f3fc.png", 
+        "unicode": "🙋🏼", 
+        "name": "Happy Person Raising One Hand Tone2"
+    }, 
+    ":flag-pr:": {
+        "style": "github", 
+        "image": "1f1f5-1f1f7.png", 
+        "unicode": "🇵🇷", 
+        "name": "Puerto Rico"
+    }, 
+    ":circus-tent:": {
+        "style": "github", 
+        "image": "1f3aa.png", 
+        "unicode": "🎪", 
+        "name": "Circus Tent"
+    }, 
+    ":bow_tone3:": {
+        "style": "github", 
+        "image": "1f647-1f3fd.png", 
+        "unicode": "🙇🏽", 
+        "name": "Person Bowing Deeply - Tone 3"
+    }, 
+    ":money_mouth_face:": {
+        "style": "github", 
+        "image": "1f911.png", 
+        "unicode": "🤑", 
+        "name": "Money-mouth Face"
+    }, 
+    "☘": {
+        "style": "unicode", 
+        "image": "2618.png", 
+        "name": "Shamrock"
+    }, 
+    ":date:": {
+        "style": "github", 
+        "image": "1f4c5.png", 
+        "unicode": "📅", 
+        "name": "Calendar"
+    }, 
+    ":flag_nu:": {
+        "style": "github", 
+        "image": "1f1f3-1f1fa.png", 
+        "unicode": "🇳🇺", 
+        "name": "Niue"
+    }, 
+    ":stuffed_pita:": {
+        "style": "github", 
+        "image": "1f959.png", 
+        "unicode": "🥙", 
+        "name": "Stuffed Flatbread"
+    }, 
+    ":tropical_drink:": {
+        "style": "github", 
+        "image": "1f379.png", 
+        "unicode": "🍹", 
+        "name": "Tropical Drink"
+    }, 
+    ":flag_za:": {
+        "style": "github", 
+        "image": "1f1ff-1f1e6.png", 
+        "unicode": "🇿🇦", 
+        "name": "South Africa"
+    }, 
+    "👩👩👧👧": {
+        "style": "unicode", 
+        "image": "1f469-1f469-1f467-1f467.png", 
+        "name": "Family (woman,woman,girl,girl)"
+    }, 
+    "👩👩👧👦": {
+        "style": "unicode", 
+        "image": "1f469-1f469-1f467-1f466.png", 
+        "name": "Family (woman,woman,girl,boy)"
+    }, 
+    "🏡": {
+        "style": "unicode", 
+        "image": "1f3e1.png", 
+        "name": "House With Garden"
+    }, 
+    ":kaaba:": {
+        "style": "github", 
+        "image": "1f54b.png", 
+        "unicode": "🕋", 
+        "name": "Kaaba"
+    }, 
+    "🍶": {
+        "style": "unicode", 
+        "image": "1f376.png", 
+        "name": "Sake Bottle And Cup"
+    }, 
+    "🕺": {
+        "style": "unicode", 
+        "image": "1f57a.png", 
+        "name": "Man Dancing"
+    }, 
+    "🤽🏽": {
+        "style": "unicode", 
+        "image": "1f93d-1f3fd.png", 
+        "name": "Water Polo - Tone 3"
+    }, 
+    "🤽🏼": {
+        "style": "unicode", 
+        "image": "1f93d-1f3fc.png", 
+        "name": "Water Polo - Tone 2"
+    }, 
+    "🤽🏿": {
+        "style": "unicode", 
+        "image": "1f93d-1f3ff.png", 
+        "name": "Water Polo - Tone 5"
+    }, 
+    "🤽🏾": {
+        "style": "unicode", 
+        "image": "1f93d-1f3fe.png", 
+        "name": "Water Polo - Tone 4"
+    }, 
+    "🐏": {
+        "style": "unicode", 
+        "image": "1f40f.png", 
+        "name": "Ram"
+    }, 
+    ":fork_knife_plate:": {
+        "style": "github", 
+        "image": "1f37d.png", 
+        "unicode": "🍽", 
+        "name": "Fork And Knife With Plate"
+    }, 
+    ":high-brightness:": {
+        "style": "github", 
+        "image": "1f506.png", 
+        "unicode": "🔆", 
+        "name": "High Brightness Symbol"
+    }, 
+    ":zipper-mouth:": {
+        "style": "github", 
+        "image": "1f910.png", 
+        "unicode": "🤐", 
+        "name": "Zipper-mouth Face"
+    }, 
+    ":regional-indicator-g:": {
+        "style": "github", 
+        "image": "1f1ec.png", 
+        "unicode": "🇬", 
+        "name": "Regional Indicator Symbol Letter G"
+    }, 
+    ":blue_car:": {
+        "style": "github", 
+        "image": "1f699.png", 
+        "unicode": "🚙", 
+        "name": "Recreational Vehicle"
+    }, 
+    "🤽": {
+        "style": "unicode", 
+        "image": "1f93d.png", 
+        "name": "Water Polo"
+    }, 
+    ":cartwheel-tone1:": {
+        "style": "github", 
+        "image": "1f938-1f3fb.png", 
+        "unicode": "🤸🏻", 
+        "name": "Person Doing Cartwheel - Tone 1"
+    }, 
+    ":speaking_head_in_silhouette:": {
+        "style": "github", 
+        "image": "1f5e3.png", 
+        "unicode": "🗣", 
+        "name": "Speaking Head In Silhouette"
+    }, 
+    ":mailbox:": {
+        "style": "github", 
+        "image": "1f4eb.png", 
+        "unicode": "📫", 
+        "name": "Closed Mailbox With Raised Flag"
+    }, 
+    ":department-store:": {
+        "style": "github", 
+        "image": "1f3ec.png", 
+        "unicode": "🏬", 
+        "name": "Department Store"
+    }, 
+    ":fk:": {
+        "style": "github", 
+        "image": "1f1eb-1f1f0.png", 
+        "unicode": "🇫🇰", 
+        "name": "Falkland Islands"
+    }, 
+    ":slight-frown:": {
+        "style": "github", 
+        "image": "1f641.png", 
+        "unicode": "🙁", 
+        "name": "Slightly Frowning Face"
+    }, 
+    ":eg:": {
+        "style": "github", 
+        "image": "1f1ea-1f1ec.png", 
+        "unicode": "🇪🇬", 
+        "name": "Egypt"
+    }, 
+    ":ok-hand-tone5:": {
+        "style": "github", 
+        "image": "1f44c-1f3ff.png", 
+        "unicode": "👌🏿", 
+        "name": "Ok Hand Sign - Tone 5"
+    }, 
+    ":calendar_spiral:": {
+        "style": "github", 
+        "image": "1f5d3.png", 
+        "unicode": "🗓", 
+        "name": "Spiral Calendar Pad"
+    }, 
+    ":virgo:": {
+        "style": "github", 
+        "image": "264d.png", 
+        "unicode": "♍", 
+        "name": "Virgo"
+    }, 
+    ":boy-tone2:": {
+        "style": "github", 
+        "image": "1f466-1f3fc.png", 
+        "unicode": "👦🏼", 
+        "name": "Boy - Tone 2"
+    }, 
+    ":womens:": {
+        "style": "github", 
+        "image": "1f6ba.png", 
+        "unicode": "🚺", 
+        "name": "Womens Symbol"
+    }, 
+    ":couple_with_heart_mm:": {
+        "style": "github", 
+        "image": "1f468-2764-1f468.png", 
+        "unicode": "👨❤👨", 
+        "name": "Couple (man,man)"
+    }, 
+    ":man_in_tuxedo_tone2:": {
+        "style": "github", 
+        "image": "1f935-1f3fc.png", 
+        "unicode": "🤵🏼", 
+        "name": "Man In Tuxedo - Tone 2"
+    }, 
+    ":flag_mq:": {
+        "style": "github", 
+        "image": "1f1f2-1f1f6.png", 
+        "unicode": "🇲🇶", 
+        "name": "Martinique"
+    }, 
+    ":raised_back_of_hand:": {
+        "style": "github", 
+        "image": "1f91a.png", 
+        "unicode": "🤚", 
+        "name": "Raised Back Of Hand"
+    }, 
+    ":bo:": {
+        "style": "github", 
+        "image": "1f1e7-1f1f4.png", 
+        "unicode": "🇧🇴", 
+        "name": "Bolivia"
+    }, 
+    "📥": {
+        "style": "unicode", 
+        "image": "1f4e5.png", 
+        "name": "Inbox Tray"
+    }, 
+    "💤": {
+        "style": "unicode", 
+        "image": "1f4a4.png", 
+        "name": "Sleeping Symbol"
+    }, 
+    "👺": {
+        "style": "unicode", 
+        "image": "1f47a.png", 
+        "name": "Japanese Goblin"
+    }, 
+    ":flag-cg:": {
+        "style": "github", 
+        "image": "1f1e8-1f1ec.png", 
+        "unicode": "🇨🇬", 
+        "name": "The Republic Of The Congo"
+    }, 
+    ":shrug_tone2:": {
+        "style": "github", 
+        "image": "1f937-1f3fc.png", 
+        "unicode": "🤷🏼", 
+        "name": "Shrug - Tone 2"
+    }, 
+    ":cancer:": {
+        "style": "github", 
+        "image": "264b.png", 
+        "unicode": "♋", 
+        "name": "Cancer"
+    }, 
+    "🌋": {
+        "style": "unicode", 
+        "image": "1f30b.png", 
+        "name": "Volcano"
+    }, 
+    "🔏": {
+        "style": "unicode", 
+        "image": "1f50f.png", 
+        "name": "Lock With Ink Pen"
+    }, 
+    ":jo:": {
+        "style": "github", 
+        "image": "1f1ef-1f1f4.png", 
+        "unicode": "🇯🇴", 
+        "name": "Jordan"
+    }, 
+    ":video-camera:": {
+        "style": "github", 
+        "image": "1f4f9.png", 
+        "unicode": "📹", 
+        "name": "Video Camera"
+    }, 
+    ":man-tone3:": {
+        "style": "github", 
+        "image": "1f468-1f3fd.png", 
+        "unicode": "👨🏽", 
+        "name": "Man - Tone 3"
+    }, 
+    "🎠": {
+        "style": "unicode", 
+        "image": "1f3a0.png", 
+        "name": "Carousel Horse"
+    }, 
+    "🖤": {
+        "style": "unicode", 
+        "image": "1f5a4.png", 
+        "name": "Black Heart"
+    }, 
+    ":baby-tone4:": {
+        "style": "github", 
+        "image": "1f476-1f3fe.png", 
+        "unicode": "👶🏾", 
+        "name": "Baby - Tone 4"
+    }, 
+    ":angel_tone3:": {
+        "style": "github", 
+        "image": "1f47c-1f3fd.png", 
+        "unicode": "👼🏽", 
+        "name": "Baby Angel - Tone 3"
+    }, 
+    ":loudspeaker:": {
+        "style": "github", 
+        "image": "1f4e2.png", 
+        "unicode": "📢", 
+        "name": "Public Address Loudspeaker"
+    }, 
+    "😹": {
+        "style": "unicode", 
+        "image": "1f639.png", 
+        "name": "Cat Face With Tears Of Joy"
+    }, 
+    ":dancer_tone3:": {
+        "style": "github", 
+        "image": "1f483-1f3fd.png", 
+        "unicode": "💃🏽", 
+        "name": "Dancer - Tone 3"
+    }, 
+    "🇲🇴": {
+        "style": "unicode", 
+        "image": "1f1f2-1f1f4.png", 
+        "name": "Macau"
+    }, 
+    ":raised-hands:": {
+        "style": "github", 
+        "image": "1f64c.png", 
+        "unicode": "🙌", 
+        "name": "Person Raising Both Hands In Celebration"
+    }, 
+    ":monkey:": {
+        "style": "github", 
+        "image": "1f412.png", 
+        "unicode": "🐒", 
+        "name": "Monkey"
+    }, 
+    "🛎": {
+        "style": "unicode", 
+        "image": "1f6ce.png", 
+        "name": "Bellhop Bell"
+    }, 
+    "🇲🇷": {
+        "style": "unicode", 
+        "image": "1f1f2-1f1f7.png", 
+        "name": "Mauritania"
+    }, 
+    ":flag_tf:": {
+        "style": "github", 
+        "image": "1f1f9-1f1eb.png", 
+        "unicode": "🇹🇫", 
+        "name": "French Southern Territories"
+    }, 
+    ":flag_bt:": {
+        "style": "github", 
+        "image": "1f1e7-1f1f9.png", 
+        "unicode": "🇧🇹", 
+        "name": "Bhutan"
+    }, 
+    ":bath_tone4:": {
+        "style": "github", 
+        "image": "1f6c0-1f3fe.png", 
+        "unicode": "🛀🏾", 
+        "name": "Bath - Tone 4"
+    }, 
+    ":robot:": {
+        "style": "github", 
+        "image": "1f916.png", 
+        "unicode": "🤖", 
+        "name": "Robot Face"
+    }, 
+    ":muscle-tone2:": {
+        "style": "github", 
+        "image": "1f4aa-1f3fc.png", 
+        "unicode": "💪🏼", 
+        "name": "Flexed Biceps - Tone 2"
+    }, 
+    ":construction-worker-tone1:": {
+        "style": "github", 
+        "image": "1f477-1f3fb.png", 
+        "unicode": "👷🏻", 
+        "name": "Construction Worker - Tone 1"
+    }, 
+    ":eye_in_speech_bubble:": {
+        "style": "github", 
+        "image": "1f441-1f5e8.png", 
+        "unicode": "👁🗨", 
+        "name": "Eye In Speech Bubble"
+    }, 
+    "🇲🇼": {
+        "style": "unicode", 
+        "image": "1f1f2-1f1fc.png", 
+        "name": "Malawi"
+    }, 
+    ":stuck_out_tongue:": {
+        "style": "github", 
+        "ascii": ":P", 
+        "image": "1f61b.png", 
+        "unicode": "😛", 
+        "name": "Face With Stuck-out Tongue"
+    }, 
+    ":family_mmg:": {
+        "style": "github", 
+        "image": "1f468-1f468-1f467.png", 
+        "unicode": "👨👨👧", 
+        "name": "Family (man,man,girl)"
+    }, 
+    ":gift:": {
+        "style": "github", 
+        "image": "1f381.png", 
+        "unicode": "🎁", 
+        "name": "Wrapped Present"
+    }, 
+    ":arrow-upper-left:": {
+        "style": "github", 
+        "image": "2196.png", 
+        "unicode": "↖", 
+        "name": "North West Arrow"
+    }, 
+    ":gl:": {
+        "style": "github", 
+        "image": "1f1ec-1f1f1.png", 
+        "unicode": "🇬🇱", 
+        "name": "Greenland"
+    }, 
+    ":white-check-mark:": {
+        "style": "github", 
+        "image": "2705.png", 
+        "unicode": "✅", 
+        "name": "White Heavy Check Mark"
+    }, 
+    ":fox:": {
+        "style": "github", 
+        "image": "1f98a.png", 
+        "unicode": "🦊", 
+        "name": "Fox Face"
+    }, 
+    "🚷": {
+        "style": "unicode", 
+        "image": "1f6b7.png", 
+        "name": "No Pedestrians"
+    }, 
+    ":whale2:": {
+        "style": "github", 
+        "image": "1f40b.png", 
+        "unicode": "🐋", 
+        "name": "Whale"
+    }, 
+    "🙌": {
+        "style": "unicode", 
+        "image": "1f64c.png", 
+        "name": "Person Raising Both Hands In Celebration"
+    }, 
+    "🇲🇬": {
+        "style": "unicode", 
+        "image": "1f1f2-1f1ec.png", 
+        "name": "Madagascar"
+    }, 
+    ":smile:": {
+        "style": "github", 
+        "image": "1f604.png", 
+        "unicode": "😄", 
+        "name": "Smiling Face With Open Mouth And Smiling Eyes"
+    }, 
+    ":male_dancer_tone4:": {
+        "style": "github", 
+        "image": "1f57a-1f3fe.png", 
+        "unicode": "🕺🏾", 
+        "name": "Man Dancing - Tone 4"
+    }, 
+    ":bath-tone3:": {
+        "style": "github", 
+        "image": "1f6c0-1f3fd.png", 
+        "unicode": "🛀🏽", 
+        "name": "Bath - Tone 3"
+    }, 
+    "🗡": {
+        "style": "unicode", 
+        "image": "1f5e1.png", 
+        "name": "Dagger Knife"
+    }, 
+    "🏥": {
+        "style": "unicode", 
+        "image": "1f3e5.png", 
+        "name": "Hospital"
+    }, 
+    "*\\0/*": {
+        "style": "ascii", 
+        "ascii": "*\\0/*", 
+        "image": "1f646.png", 
+        "unicode": "🙆", 
+        "name": "Face With Ok Gesture"
+    }, 
+    ":dvd:": {
+        "style": "github", 
+        "image": "1f4c0.png", 
+        "unicode": "📀", 
+        "name": "Dvd"
+    }, 
+    ":cherries:": {
+        "style": "github", 
+        "image": "1f352.png", 
+        "unicode": "🍒", 
+        "name": "Cherries"
+    }, 
+    "🕶": {
+        "style": "unicode", 
+        "image": "1f576.png", 
+        "name": "Dark Sunglasses"
+    }, 
+    "🍺": {
+        "style": "unicode", 
+        "image": "1f37a.png", 
+        "name": "Beer Mug"
+    }, 
+    ":man-with-gua-pi-mao-tone1:": {
+        "style": "github", 
+        "image": "1f472-1f3fb.png", 
+        "unicode": "👲🏻", 
+        "name": "Man With Gua Pi Mao - Tone 1"
+    }, 
+    ":man-in-tuxedo-tone5:": {
+        "style": "github", 
+        "image": "1f935-1f3ff.png", 
+        "unicode": "🤵🏿", 
+        "name": "Man In Tuxedo - Tone 5"
+    }, 
+    "🐋": {
+        "style": "unicode", 
+        "image": "1f40b.png", 
+        "name": "Whale"
+    }, 
+    ":flag_lv:": {
+        "style": "github", 
+        "image": "1f1f1-1f1fb.png", 
+        "unicode": "🇱🇻", 
+        "name": "Latvia"
+    }, 
+    ":mr:": {
+        "style": "github", 
+        "image": "1f1f2-1f1f7.png", 
+        "unicode": "🇲🇷", 
+        "name": "Mauritania"
+    }, 
+    ":ch:": {
+        "style": "github", 
+        "image": "1f1e8-1f1ed.png", 
+        "unicode": "🇨🇭", 
+        "name": "Switzerland"
+    }, 
+    ":currency-exchange:": {
+        "style": "github", 
+        "image": "1f4b1.png", 
+        "unicode": "💱", 
+        "name": "Currency Exchange"
+    }, 
+    ":point-up-tone4:": {
+        "style": "github", 
+        "image": "261d-1f3fe.png", 
+        "unicode": "☝🏾", 
+        "name": "White Up Pointing Index - Tone 4"
+    }, 
+    "💠": {
+        "style": "unicode", 
+        "image": "1f4a0.png", 
+        "name": "Diamond Shape With A Dot Inside"
+    }, 
+    ":walking:": {
+        "style": "github", 
+        "image": "1f6b6.png", 
+        "unicode": "🚶", 
+        "name": "Pedestrian"
+    }, 
+    ":back_of_hand_tone5:": {
+        "style": "github", 
+        "image": "1f91a-1f3ff.png", 
+        "unicode": "🤚🏿", 
+        "name": "Raised Back Of Hand - Tone 5"
+    }, 
+    ":airplane-small:": {
+        "style": "github", 
+        "image": "1f6e9.png", 
+        "unicode": "🛩", 
+        "name": "Small Airplane"
+    }, 
+    ":haircut-tone4:": {
+        "style": "github", 
+        "image": "1f487-1f3fe.png", 
+        "unicode": "💇🏾", 
+        "name": "Haircut - Tone 4"
+    }, 
+    ":kh:": {
+        "style": "github", 
+        "image": "1f1f0-1f1ed.png", 
+        "unicode": "🇰🇭", 
+        "name": "Cambodia"
+    }, 
+    "👋🏻": {
+        "style": "unicode", 
+        "image": "1f44b-1f3fb.png", 
+        "name": "Waving Hand Sign - Tone 1"
+    }, 
+    "👋🏿": {
+        "style": "unicode", 
+        "image": "1f44b-1f3ff.png", 
+        "name": "Waving Hand Sign - Tone 5"
+    }, 
+    "🏻": {
+        "style": "unicode", 
+        "image": "1f3fb.png", 
+        "name": "Emoji Modifier Fitzpatrick Type-1-2"
+    }, 
+    "👋🏽": {
+        "style": "unicode", 
+        "image": "1f44b-1f3fd.png", 
+        "name": "Waving Hand Sign - Tone 3"
+    }, 
+    "👋🏼": {
+        "style": "unicode", 
+        "image": "1f44b-1f3fc.png", 
+        "name": "Waving Hand Sign - Tone 2"
+    }, 
+    ":older_woman:": {
+        "style": "github", 
+        "image": "1f475.png", 
+        "unicode": "👵", 
+        "name": "Older Woman"
+    }, 
+    ":raised_hands_tone5:": {
+        "style": "github", 
+        "image": "1f64c-1f3ff.png", 
+        "unicode": "🙌🏿", 
+        "name": "Person Raising Both Hands In Celebration - Tone 5"
+    }, 
+    ":suspension-railway:": {
+        "style": "github", 
+        "image": "1f69f.png", 
+        "unicode": "🚟", 
+        "name": "Suspension Railway"
+    }, 
+    ":ping-pong:": {
+        "style": "github", 
+        "image": "1f3d3.png", 
+        "unicode": "🏓", 
+        "name": "Table Tennis Paddle And Ball"
+    }, 
+    "🚍": {
+        "style": "unicode", 
+        "image": "1f68d.png", 
+        "name": "Oncoming Bus"
+    }, 
+    ":black_circle:": {
+        "style": "github", 
+        "image": "26ab.png", 
+        "unicode": "⚫", 
+        "name": "Medium Black Circle"
+    }, 
+    ":seat:": {
+        "style": "github", 
+        "image": "1f4ba.png", 
+        "unicode": "💺", 
+        "name": "Seat"
+    }, 
+    "😢": {
+        "style": "unicode", 
+        "ascii": ":'(", 
+        "image": "1f622.png", 
+        "name": "Crying Face"
+    }, 
+    ":lemon:": {
+        "style": "github", 
+        "image": "1f34b.png", 
+        "unicode": "🍋", 
+        "name": "Lemon"
+    }, 
+    ":flag-lu:": {
+        "style": "github", 
+        "image": "1f1f1-1f1fa.png", 
+        "unicode": "🇱🇺", 
+        "name": "Luxembourg"
+    }, 
+    ":py:": {
+        "style": "github", 
+        "image": "1f1f5-1f1fe.png", 
+        "unicode": "🇵🇾", 
+        "name": "Paraguay"
+    }, 
+    ":swimmer-tone1:": {
+        "style": "github", 
+        "image": "1f3ca-1f3fb.png", 
+        "unicode": "🏊🏻", 
+        "name": "Swimmer - Tone 1"
+    }, 
+    "📡": {
+        "style": "unicode", 
+        "image": "1f4e1.png", 
+        "name": "Satellite Antenna"
+    }, 
+    ":classical_building:": {
+        "style": "github", 
+        "image": "1f3db.png", 
+        "unicode": "🏛", 
+        "name": "Classical Building"
+    }, 
+    "👶": {
+        "style": "unicode", 
+        "image": "1f476.png", 
+        "name": "Baby"
+    }, 
+    ":mother_christmas_tone2:": {
+        "style": "github", 
+        "image": "1f936-1f3fc.png", 
+        "unicode": "🤶🏼", 
+        "name": "Mother Christmas - Tone 2"
+    }, 
+    ":man_dancing_tone1:": {
+        "style": "github", 
+        "image": "1f57a-1f3fb.png", 
+        "unicode": "🕺🏻", 
+        "name": "Man Dancing - Tone 1"
+    }, 
+    ":relieved:": {
+        "style": "github", 
+        "image": "1f60c.png", 
+        "unicode": "😌", 
+        "name": "Relieved Face"
+    }, 
+    "🔋": {
+        "style": "unicode", 
+        "image": "1f50b.png", 
+        "name": "Battery"
+    }, 
+    "🌏": {
+        "style": "unicode", 
+        "image": "1f30f.png", 
+        "name": "Earth Globe Asia-australia"
+    }, 
+    ":raised_back_of_hand_tone1:": {
+        "style": "github", 
+        "image": "1f91a-1f3fb.png", 
+        "unicode": "🤚🏻", 
+        "name": "Raised Back Of Hand - Tone 1"
+    }, 
+    "🤓": {
+        "style": "unicode", 
+        "image": "1f913.png", 
+        "name": "Nerd Face"
+    }, 
+    ":100:": {
+        "style": "github", 
+        "image": "1f4af.png", 
+        "unicode": "💯", 
+        "name": "Hundred Points Symbol"
+    }, 
+    "🎤": {
+        "style": "unicode", 
+        "image": "1f3a4.png", 
+        "name": "Microphone"
+    }, 
+    ":shower:": {
+        "style": "github", 
+        "image": "1f6bf.png", 
+        "unicode": "🚿", 
+        "name": "Shower"
+    }, 
+    ":postal_horn:": {
+        "style": "github", 
+        "image": "1f4ef.png", 
+        "unicode": "📯", 
+        "name": "Postal Horn"
+    }, 
+    ":last-quarter-moon-with-face:": {
+        "style": "github", 
+        "image": "1f31c.png", 
+        "unicode": "🌜", 
+        "name": "Last Quarter Moon With Face"
+    }, 
+    "◀": {
+        "style": "unicode", 
+        "image": "25c0.png", 
+        "name": "Black Left-pointing Triangle"
+    }, 
+    ":+1:": {
+        "style": "github", 
+        "image": "1f44d.png", 
+        "unicode": "👍", 
+        "name": "Thumbs Up Sign"
+    }, 
+    ":bat:": {
+        "style": "github", 
+        "image": "1f987.png", 
+        "unicode": "🦇", 
+        "name": "Bat"
+    }, 
+    ":thumbdown:": {
+        "style": "github", 
+        "image": "1f44e.png", 
+        "unicode": "👎", 
+        "name": "Thumbs Down Sign"
+    }, 
+    ":flag_vg:": {
+        "style": "github", 
+        "image": "1f1fb-1f1ec.png", 
+        "unicode": "🇻🇬", 
+        "name": "British Virgin Islands"
+    }, 
+    "🇸": {
+        "style": "unicode", 
+        "image": "1f1f8.png", 
+        "name": "Regional Indicator Symbol Letter S"
+    }, 
+    ":middle_finger_tone1:": {
+        "style": "github", 
+        "image": "1f595-1f3fb.png", 
+        "unicode": "🖕🏻", 
+        "name": "Reversed Hand With Middle Finger Extended - Tone 1"
+    }, 
+    ":point_up_tone1:": {
+        "style": "github", 
+        "image": "261d-1f3fb.png", 
+        "unicode": "☝🏻", 
+        "name": "White Up Pointing Index - Tone 1"
+    }, 
+    ":kissing-closed-eyes:": {
+        "style": "github", 
+        "image": "1f61a.png", 
+        "unicode": "😚", 
+        "name": "Kissing Face With Closed Eyes"
+    }, 
+    ":face_with_rolling_eyes:": {
+        "style": "github", 
+        "image": "1f644.png", 
+        "unicode": "🙄", 
+        "name": "Face With Rolling Eyes"
+    }, 
+    "🖍": {
+        "style": "unicode", 
+        "image": "1f58d.png", 
+        "name": "Lower Left Crayon"
+    }, 
+    "🔢": {
+        "style": "unicode", 
+        "image": "1f522.png", 
+        "name": "Input Symbol For Numbers"
+    }, 
+    ":flag-mr:": {
+        "style": "github", 
+        "image": "1f1f2-1f1f7.png", 
+        "unicode": "🇲🇷", 
+        "name": "Mauritania"
+    }, 
+    ":np:": {
+        "style": "github", 
+        "image": "1f1f3-1f1f5.png", 
+        "unicode": "🇳🇵", 
+        "name": "Nepal"
+    }, 
+    ":flag_ai:": {
+        "style": "github", 
+        "image": "1f1e6-1f1ee.png", 
+        "unicode": "🇦🇮", 
+        "name": "Anguilla"
+    }, 
+    "💷": {
+        "style": "unicode", 
+        "image": "1f4b7.png", 
+        "name": "Banknote With Pound Sign"
+    }, 
+    ":prince_tone5:": {
+        "style": "github", 
+        "image": "1f934-1f3ff.png", 
+        "unicode": "🤴🏿", 
+        "name": "Prince - Tone 5"
+    }, 
+    ":man_with_turban_tone2:": {
+        "style": "github", 
+        "image": "1f473-1f3fc.png", 
+        "unicode": "👳🏼", 
+        "name": "Man With Turban - Tone 2"
+    }, 
+    "👌": {
+        "style": "unicode", 
+        "image": "1f44c.png", 
+        "name": "Ok Hand Sign"
+    }, 
+    ":rabbit:": {
+        "style": "github", 
+        "image": "1f430.png", 
+        "unicode": "🐰", 
+        "name": "Rabbit Face"
+    }, 
+    ":gear:": {
+        "style": "github", 
+        "image": "2699.png", 
+        "unicode": "⚙", 
+        "name": "Gear"
+    }, 
+    ":truck:": {
+        "style": "github", 
+        "image": "1f69a.png", 
+        "unicode": "🚚", 
+        "name": "Delivery Truck"
+    }, 
+    ":mega:": {
+        "style": "github", 
+        "image": "1f4e3.png", 
+        "unicode": "📣", 
+        "name": "Cheering Megaphone"
+    }, 
+    ":bow_tone1:": {
+        "style": "github", 
+        "image": "1f647-1f3fb.png", 
+        "unicode": "🙇🏻", 
+        "name": "Person Bowing Deeply - Tone 1"
+    }, 
+    ":person_with_blond_hair_tone5:": {
+        "style": "github", 
+        "image": "1f471-1f3ff.png", 
+        "unicode": "👱🏿", 
+        "name": "Person With Blond Hair - Tone 5"
+    }, 
+    "😋": {
+        "style": "unicode", 
+        "image": "1f60b.png", 
+        "name": "Face Savouring Delicious Food"
+    }, 
+    "➖": {
+        "style": "unicode", 
+        "image": "2796.png", 
+        "name": "Heavy Minus Sign"
+    }, 
+    ":water_polo:": {
+        "style": "github", 
+        "image": "1f93d.png", 
+        "unicode": "🤽", 
+        "name": "Water Polo"
+    }, 
+    ":seedling:": {
+        "style": "github", 
+        "image": "1f331.png", 
+        "unicode": "🌱", 
+        "name": "Seedling"
+    }, 
+    "🚠": {
+        "style": "unicode", 
+        "image": "1f6a0.png", 
+        "name": "Mountain Cableway"
+    }, 
+    ":right-facing-fist:": {
+        "style": "github", 
+        "image": "1f91c.png", 
+        "unicode": "🤜", 
+        "name": "Right-facing Fist"
+    }, 
+    "👆🏻": {
+        "style": "unicode", 
+        "image": "1f446-1f3fb.png", 
+        "name": "White Up Pointing Backhand Index - Tone 1"
+    }, 
+    "👆🏼": {
+        "style": "unicode", 
+        "image": "1f446-1f3fc.png", 
+        "name": "White Up Pointing Backhand Index - Tone 2"
+    }, 
+    "👆🏽": {
+        "style": "unicode", 
+        "image": "1f446-1f3fd.png", 
+        "name": "White Up Pointing Backhand Index - Tone 3"
+    }, 
+    ":flag_ga:": {
+        "style": "github", 
+        "image": "1f1ec-1f1e6.png", 
+        "unicode": "🇬🇦", 
+        "name": "Gabon"
+    }, 
+    "👆🏿": {
+        "style": "unicode", 
+        "image": "1f446-1f3ff.png", 
+        "name": "White Up Pointing Backhand Index - Tone 5"
+    }, 
+    ":admission_tickets:": {
+        "style": "github", 
+        "image": "1f39f.png", 
+        "unicode": "🎟", 
+        "name": "Admission Tickets"
+    }, 
+    ":au:": {
+        "style": "github", 
+        "image": "1f1e6-1f1fa.png", 
+        "unicode": "🇦🇺", 
+        "name": "Australia"
+    }, 
+    "🌹": {
+        "style": "unicode", 
+        "image": "1f339.png", 
+        "name": "Rose"
+    }, 
+    "🏎": {
+        "style": "unicode", 
+        "image": "1f3ce.png", 
+        "name": "Racing Car"
+    }, 
+    "🚣🏻": {
+        "style": "unicode", 
+        "image": "1f6a3-1f3fb.png", 
+        "name": "Rowboat - Tone 1"
+    }, 
+    "🚣🏿": {
+        "style": "unicode", 
+        "image": "1f6a3-1f3ff.png", 
+        "name": "Rowboat - Tone 5"
+    }, 
+    "🚣🏾": {
+        "style": "unicode", 
+        "image": "1f6a3-1f3fe.png", 
+        "name": "Rowboat - Tone 4"
+    }, 
+    "🚣🏽": {
+        "style": "unicode", 
+        "image": "1f6a3-1f3fd.png", 
+        "name": "Rowboat - Tone 3"
+    }, 
+    "🚣🏼": {
+        "style": "unicode", 
+        "image": "1f6a3-1f3fc.png", 
+        "name": "Rowboat - Tone 2"
+    }, 
+    ":burrito:": {
+        "style": "github", 
+        "image": "1f32f.png", 
+        "unicode": "🌯", 
+        "name": "Burrito"
+    }, 
+    ":ie:": {
+        "style": "github", 
+        "image": "1f1ee-1f1ea.png", 
+        "unicode": "🇮🇪", 
+        "name": "Ireland"
+    }, 
+    "⏮": {
+        "style": "unicode", 
+        "image": "23ee.png", 
+        "name": "Black Left-pointing Double Triangle With Vertical Bar"
+    }, 
+    ":speak-no-evil:": {
+        "style": "github", 
+        "image": "1f64a.png", 
+        "unicode": "🙊", 
+        "name": "Speak-no-evil Monkey"
+    }, 
+    ":man_with_gua_pi_mao_tone1:": {
+        "style": "github", 
+        "image": "1f472-1f3fb.png", 
+        "unicode": "👲🏻", 
+        "name": "Man With Gua Pi Mao - Tone 1"
+    }, 
+    ":regional-indicator-e:": {
+        "style": "github", 
+        "image": "1f1ea.png", 
+        "unicode": "🇪", 
+        "name": "Regional Indicator Symbol Letter E"
+    }, 
+    "💍": {
+        "style": "unicode", 
+        "image": "1f48d.png", 
+        "name": "Ring"
+    }, 
+    ":horse:": {
+        "style": "github", 
+        "image": "1f434.png", 
+        "unicode": "🐴", 
+        "name": "Horse Face"
+    }, 
+    ":dragon:": {
+        "style": "github", 
+        "image": "1f409.png", 
+        "unicode": "🐉", 
+        "name": "Dragon"
+    }, 
+    ":flag-bz:": {
+        "style": "github", 
+        "image": "1f1e7-1f1ff.png", 
+        "unicode": "🇧🇿", 
+        "name": "Belize"
+    }, 
+    "🐢": {
+        "style": "unicode", 
+        "image": "1f422.png", 
+        "name": "Turtle"
+    }, 
+    ":fog:": {
+        "style": "github", 
+        "image": "1f32b.png", 
+        "unicode": "🌫", 
+        "name": "Fog"
+    }, 
+    ":house-with-garden:": {
+        "style": "github", 
+        "image": "1f3e1.png", 
+        "unicode": "🏡", 
+        "name": "House With Garden"
+    }, 
+    "🕌": {
+        "style": "unicode", 
+        "image": "1f54c.png", 
+        "name": "Mosque"
+    }, 
+    "🥔": {
+        "style": "unicode", 
+        "image": "1f954.png", 
+        "name": "Potato"
+    }, 
+    "🛡": {
+        "style": "unicode", 
+        "image": "1f6e1.png", 
+        "name": "Shield"
+    }, 
+    ":fm:": {
+        "style": "github", 
+        "image": "1f1eb-1f1f2.png", 
+        "unicode": "🇫🇲", 
+        "name": "Micronesia"
+    }, 
+    ":hear-no-evil:": {
+        "style": "github", 
+        "image": "1f649.png", 
+        "unicode": "🙉", 
+        "name": "Hear-no-evil Monkey"
+    }, 
+    ":poo:": {
+        "style": "github", 
+        "image": "1f4a9.png", 
+        "unicode": "💩", 
+        "name": "Pile Of Poo"
+    }, 
+    ":family_wwb:": {
+        "style": "github", 
+        "image": "1f469-1f469-1f466.png", 
+        "unicode": "👩👩👦", 
+        "name": "Family (woman,woman,boy)"
+    }, 
+    "☁": {
+        "style": "unicode", 
+        "image": "2601.png", 
+        "name": "Cloud"
+    }, 
+    "👧🏿": {
+        "style": "unicode", 
+        "image": "1f467-1f3ff.png", 
+        "name": "Girl - Tone 5"
+    }, 
+    "👧🏾": {
+        "style": "unicode", 
+        "image": "1f467-1f3fe.png", 
+        "name": "Girl - Tone 4"
+    }, 
+    ":family-mmgg:": {
+        "style": "github", 
+        "image": "1f468-1f468-1f467-1f467.png", 
+        "unicode": "👨👨👧👧", 
+        "name": "Family (man,man,girl,girl)"
+    }, 
+    "👧🏼": {
+        "style": "unicode", 
+        "image": "1f467-1f3fc.png", 
+        "name": "Girl - Tone 2"
+    }, 
+    "👧🏻": {
+        "style": "unicode", 
+        "image": "1f467-1f3fb.png", 
+        "name": "Girl - Tone 1"
+    }, 
+    ":flag_li:": {
+        "style": "github", 
+        "image": "1f1f1-1f1ee.png", 
+        "unicode": "🇱🇮", 
+        "name": "Liechtenstein"
+    }, 
+    ":clock1:": {
+        "style": "github", 
+        "image": "1f550.png", 
+        "unicode": "🕐", 
+        "name": "Clock Face One Oclock"
+    }, 
+    ":arrows-counterclockwise:": {
+        "style": "github", 
+        "image": "1f504.png", 
+        "unicode": "🔄", 
+        "name": "Anticlockwise Downwards And Upwards Open Circle Arrows"
+    }, 
+    ":my:": {
+        "style": "github", 
+        "image": "1f1f2-1f1fe.png", 
+        "unicode": "🇲🇾", 
+        "name": "Malaysia"
+    }, 
+    ":mouse2:": {
+        "style": "github", 
+        "image": "1f401.png", 
+        "unicode": "🐁", 
+        "name": "Mouse"
+    }, 
+    ":musical-keyboard:": {
+        "style": "github", 
+        "image": "1f3b9.png", 
+        "unicode": "🎹", 
+        "name": "Musical Keyboard"
+    }, 
+    ":santa_tone2:": {
+        "style": "github", 
+        "image": "1f385-1f3fc.png", 
+        "unicode": "🎅🏼", 
+        "name": "Father Christmas - Tone 2"
+    }, 
+    ":warning:": {
+        "style": "github", 
+        "image": "26a0.png", 
+        "unicode": "⚠", 
+        "name": "Warning Sign"
+    }, 
+    ":flag_ph:": {
+        "style": "github", 
+        "image": "1f1f5-1f1ed.png", 
+        "unicode": "🇵🇭", 
+        "name": "The Philippines"
+    }, 
+    ":kayak:": {
+        "style": "github", 
+        "image": "1f6f6.png", 
+        "unicode": "🛶", 
+        "name": "Canoe"
+    }, 
+    "🈹": {
+        "style": "unicode", 
+        "image": "1f239.png", 
+        "name": "Squared Cjk Unified Ideograph-5272"
+    }, 
+    ":japanese-ogre:": {
+        "style": "github", 
+        "image": "1f479.png", 
+        "unicode": "👹", 
+        "name": "Japanese Ogre"
+    }, 
+    ":partly-sunny:": {
+        "style": "github", 
+        "image": "26c5.png", 
+        "unicode": "⛅", 
+        "name": "Sun Behind Cloud"
+    }, 
+    ":flag_ms:": {
+        "style": "github", 
+        "image": "1f1f2-1f1f8.png", 
+        "unicode": "🇲🇸", 
+        "name": "Montserrat"
+    }, 
+    "🇷🇪": {
+        "style": "unicode", 
+        "image": "1f1f7-1f1ea.png", 
+        "name": "Réunion"
+    }, 
+    "🙏🏿": {
+        "style": "unicode", 
+        "image": "1f64f-1f3ff.png", 
+        "name": "Person With Folded Hands - Tone 5"
+    }, 
+    "🙏🏾": {
+        "style": "unicode", 
+        "image": "1f64f-1f3fe.png", 
+        "name": "Person With Folded Hands - Tone 4"
+    }, 
+    "🙏🏽": {
+        "style": "unicode", 
+        "image": "1f64f-1f3fd.png", 
+        "name": "Person With Folded Hands - Tone 3"
+    }, 
+    "🇷🇴": {
+        "style": "unicode", 
+        "image": "1f1f7-1f1f4.png", 
+        "name": "Romania"
+    }, 
+    "🙏🏻": {
+        "style": "unicode", 
+        "image": "1f64f-1f3fb.png", 
+        "name": "Person With Folded Hands - Tone 1"
+    }, 
+    ":bi:": {
+        "style": "github", 
+        "image": "1f1e7-1f1ee.png", 
+        "unicode": "🇧🇮", 
+        "name": "Burundi"
+    }, 
+    "🇷🇼": {
+        "style": "unicode", 
+        "image": "1f1f7-1f1fc.png", 
+        "name": "Rwanda"
+    }, 
+    "🇷🇺": {
+        "style": "unicode", 
+        "image": "1f1f7-1f1fa.png", 
+        "name": "Russia"
+    }, 
+    "🇷🇸": {
+        "style": "unicode", 
+        "image": "1f1f7-1f1f8.png", 
+        "name": "Serbia"
+    }, 
+    "🍣": {
+        "style": "unicode", 
+        "image": "1f363.png", 
+        "name": "Sushi"
+    }, 
+    ":family-wwb:": {
+        "style": "github", 
+        "image": "1f469-1f469-1f466.png", 
+        "unicode": "👩👩👦", 
+        "name": "Family (woman,woman,boy)"
+    }, 
+    "🏸": {
+        "style": "unicode", 
+        "image": "1f3f8.png", 
+        "name": "Badminton Racquet"
+    }, 
+    ":fork-and-knife:": {
+        "style": "github", 
+        "image": "1f374.png", 
+        "unicode": "🍴", 
+        "name": "Fork And Knife"
+    }, 
+    ":basketball_player:": {
+        "style": "github", 
+        "image": "26f9.png", 
+        "unicode": "⛹", 
+        "name": "Person With Ball"
+    }, 
+    ":/": {
+        "style": "ascii", 
+        "ascii": ">:\\", 
+        "image": "1f615.png", 
+        "unicode": "😕", 
+        "name": "Confused Face"
+    }, 
+    ":flag-ca:": {
+        "style": "github", 
+        "image": "1f1e8-1f1e6.png", 
+        "unicode": "🇨🇦", 
+        "name": "Canada"
+    }, 
+    ":man-tone5:": {
+        "style": "github", 
+        "image": "1f468-1f3ff.png", 
+        "unicode": "👨🏿", 
+        "name": "Man - Tone 5"
+    }, 
+    ":*": {
+        "style": "ascii", 
+        "ascii": ":*", 
+        "image": "1f618.png", 
+        "unicode": "😘", 
+        "name": "Face Throwing A Kiss"
+    }, 
+    ":$": {
+        "style": "ascii", 
+        "ascii": ":$", 
+        "image": "1f633.png", 
+        "unicode": "😳", 
+        "name": "Flushed Face"
+    }, 
+    ":#": {
+        "style": "ascii", 
+        "ascii": ":-X", 
+        "image": "1f636.png", 
+        "unicode": "😶", 
+        "name": "Face Without Mouth"
+    }, 
+    "🆑": {
+        "style": "unicode", 
+        "image": "1f191.png", 
+        "name": "Squared Cl"
+    }, 
+    ":dancer_tone1:": {
+        "style": "github", 
+        "image": "1f483-1f3fb.png", 
+        "unicode": "💃🏻", 
+        "name": "Dancer - Tone 1"
+    }, 
+    ":flag-pt:": {
+        "style": "github", 
+        "image": "1f1f5-1f1f9.png", 
+        "unicode": "🇵🇹", 
+        "name": "Portugal"
+    }, 
+    "🚿": {
+        "style": "unicode", 
+        "image": "1f6bf.png", 
+        "name": "Shower"
+    }, 
+    ":flag_bv:": {
+        "style": "github", 
+        "image": "1f1e7-1f1fb.png", 
+        "unicode": "🇧🇻", 
+        "name": "Bouvet Island"
+    }, 
+    ":o": {
+        "style": "ascii", 
+        "ascii": ":-O", 
+        "image": "1f62e.png", 
+        "unicode": "😮", 
+        "name": "Face With Open Mouth"
+    }, 
+    ":b": {
+        "style": "ascii", 
+        "ascii": ":P", 
+        "image": "1f61b.png", 
+        "unicode": "😛", 
+        "name": "Face With Stuck-out Tongue"
+    }, 
+    ":x": {
+        "style": "ascii", 
+        "ascii": ":-X", 
+        "image": "1f636.png", 
+        "unicode": "😶", 
+        "name": "Face Without Mouth"
+    }, 
+    ":p": {
+        "style": "ascii", 
+        "ascii": ":P", 
+        "image": "1f61b.png", 
+        "unicode": "😛", 
+        "name": "Face With Stuck-out Tongue"
+    }, 
+    ":flag_td:": {
+        "style": "github", 
+        "image": "1f1f9-1f1e9.png", 
+        "unicode": "🇹🇩", 
+        "name": "Chad"
+    }, 
+    ":L": {
+        "style": "ascii", 
+        "ascii": ">:\\", 
+        "image": "1f615.png", 
+        "unicode": "😕", 
+        "name": "Confused Face"
+    }, 
+    ":face_with_thermometer:": {
+        "style": "github", 
+        "image": "1f912.png", 
+        "unicode": "🤒", 
+        "name": "Face With Thermometer"
+    }, 
+    ":O": {
+        "style": "ascii", 
+        "ascii": ":-O", 
+        "image": "1f62e.png", 
+        "unicode": "😮", 
+        "name": "Face With Open Mouth"
+    }, 
+    ":cartwheel_tone1:": {
+        "style": "github", 
+        "image": "1f938-1f3fb.png", 
+        "unicode": "🤸🏻", 
+        "name": "Person Doing Cartwheel - Tone 1"
+    }, 
+    ":muscle-tone4:": {
+        "style": "github", 
+        "image": "1f4aa-1f3fe.png", 
+        "unicode": "💪🏾", 
+        "name": "Flexed Biceps - Tone 4"
+    }, 
+    ":@": {
+        "style": "ascii", 
+        "ascii": ">:(", 
+        "image": "1f620.png", 
+        "unicode": "😠", 
+        "name": "Angry Face"
+    }, 
+    ":\\": {
+        "style": "ascii", 
+        "ascii": ">:\\", 
+        "image": "1f615.png", 
+        "unicode": "😕", 
+        "name": "Confused Face"
+    }, 
+    ":]": {
+        "style": "ascii", 
+        "ascii": ":)", 
+        "image": "1f642.png", 
+        "unicode": "🙂", 
+        "name": "Slightly Smiling Face"
+    }, 
+    ":X": {
+        "style": "ascii", 
+        "ascii": ":-X", 
+        "image": "1f636.png", 
+        "unicode": "😶", 
+        "name": "Face Without Mouth"
+    }, 
+    ":[": {
+        "style": "ascii", 
+        "ascii": ">:[", 
+        "image": "1f61e.png", 
+        "unicode": "😞", 
+        "name": "Disappointed Face"
+    }, 
+    ":P": {
+        "style": "ascii", 
+        "ascii": ":P", 
+        "image": "1f61b.png", 
+        "unicode": "😛", 
+        "name": "Face With Stuck-out Tongue"
+    }, 
+    ":maple-leaf:": {
+        "style": "github", 
+        "image": "1f341.png", 
+        "unicode": "🍁", 
+        "name": "Maple Leaf"
+    }, 
+    ":tokyo_tower:": {
+        "style": "github", 
+        "image": "1f5fc.png", 
+        "unicode": "🗼", 
+        "name": "Tokyo Tower"
+    }, 
+    "🛀": {
+        "style": "unicode", 
+        "image": "1f6c0.png", 
+        "name": "Bath"
+    }, 
+    "🐓": {
+        "style": "unicode", 
+        "image": "1f413.png", 
+        "name": "Rooster"
+    }, 
+    ":gb:": {
+        "style": "github", 
+        "image": "1f1ec-1f1e7.png", 
+        "unicode": "🇬🇧", 
+        "name": "Great Britain"
+    }, 
+    ":sv:": {
+        "style": "github", 
+        "image": "1f1f8-1f1fb.png", 
+        "unicode": "🇸🇻", 
+        "name": "El Salvador"
+    }, 
+    "💨": {
+        "style": "unicode", 
+        "image": "1f4a8.png", 
+        "name": "Dash Symbol"
+    }, 
+    "🙆🏻": {
+        "style": "unicode", 
+        "image": "1f646-1f3fb.png", 
+        "name": "Face With Ok Gesture Tone1"
+    }, 
+    "🙆🏼": {
+        "style": "unicode", 
+        "image": "1f646-1f3fc.png", 
+        "name": "Face With Ok Gesture Tone2"
+    }, 
+    "🙆🏽": {
+        "style": "unicode", 
+        "image": "1f646-1f3fd.png", 
+        "name": "Face With Ok Gesture Tone3"
+    }, 
+    "🙆🏾": {
+        "style": "unicode", 
+        "image": "1f646-1f3fe.png", 
+        "name": "Face With Ok Gesture Tone4"
+    }, 
+    "🙆🏿": {
+        "style": "unicode", 
+        "image": "1f646-1f3ff.png", 
+        "name": "Face With Ok Gesture Tone5"
+    }, 
+    "'=)": {
+        "style": "ascii", 
+        "ascii": "':)", 
+        "image": "1f605.png", 
+        "unicode": "😅", 
+        "name": "Smiling Face With Open Mouth And Cold Sweat"
+    }, 
+    "'=(": {
+        "style": "ascii", 
+        "ascii": "':(", 
+        "image": "1f613.png", 
+        "unicode": "😓", 
+        "name": "Face With Cold Sweat"
+    }, 
+    "🌽": {
+        "style": "unicode", 
+        "image": "1f33d.png", 
+        "name": "Ear Of Maize"
+    }, 
+    ":first_place_medal:": {
+        "style": "github", 
+        "image": "1f947.png", 
+        "unicode": "🥇", 
+        "name": "First Place Medal"
+    }, 
+    ":green-heart:": {
+        "style": "github", 
+        "image": "1f49a.png", 
+        "unicode": "💚", 
+        "name": "Green Heart"
+    }, 
+    ":right_fist_tone2:": {
+        "style": "github", 
+        "image": "1f91c-1f3fc.png", 
+        "unicode": "🤜🏼", 
+        "name": "Right Facing Fist - Tone 2"
+    }, 
+    ":þ": {
+        "style": "ascii", 
+        "ascii": ":P", 
+        "image": "1f61b.png", 
+        "unicode": "😛", 
+        "name": "Face With Stuck-out Tongue"
+    }, 
+    "🏒": {
+        "style": "unicode", 
+        "image": "1f3d2.png", 
+        "name": "Ice Hockey Stick And Puck"
+    }, 
+    ":cop_tone3:": {
+        "style": "github", 
+        "image": "1f46e-1f3fd.png", 
+        "unicode": "👮🏽", 
+        "name": "Police Officer - Tone 3"
+    }, 
+    ":bride_with_veil_tone4:": {
+        "style": "github", 
+        "image": "1f470-1f3fe.png", 
+        "unicode": "👰🏾", 
+        "name": "Bride With Veil - Tone 4"
+    }, 
+    "'=D": {
+        "style": "ascii", 
+        "ascii": "':)", 
+        "image": "1f605.png", 
+        "unicode": "😅", 
+        "name": "Smiling Face With Open Mouth And Cold Sweat"
+    }, 
+    "👨👨👧👧": {
+        "style": "unicode", 
+        "image": "1f468-1f468-1f467-1f467.png", 
+        "name": "Family (man,man,girl,girl)"
+    }, 
+    "👨👨👧👦": {
+        "style": "unicode", 
+        "image": "1f468-1f468-1f467-1f466.png", 
+        "name": "Family (man,man,girl,boy)"
+    }, 
+    ":flag-hk:": {
+        "style": "github", 
+        "image": "1f1ed-1f1f0.png", 
+        "unicode": "🇭🇰", 
+        "name": "Hong Kong"
+    }, 
+    ":Þ": {
+        "style": "ascii", 
+        "ascii": ":P", 
+        "image": "1f61b.png", 
+        "unicode": "😛", 
+        "name": "Face With Stuck-out Tongue"
+    }, 
+    "⏲": {
+        "style": "unicode", 
+        "image": "23f2.png", 
+        "name": "Timer Clock"
+    }, 
+    ":man-in-tuxedo-tone3:": {
+        "style": "github", 
+        "image": "1f935-1f3fd.png", 
+        "unicode": "🤵🏽", 
+        "name": "Man In Tuxedo - Tone 3"
+    }, 
+    ":mt:": {
+        "style": "github", 
+        "image": "1f1f2-1f1f9.png", 
+        "unicode": "🇲🇹", 
+        "name": "Malta"
+    }, 
+    ":cv:": {
+        "style": "github", 
+        "image": "1f1e8-1f1fb.png", 
+        "unicode": "🇨🇻", 
+        "name": "Cape Verde"
+    }, 
+    ":handbag:": {
+        "style": "github", 
+        "image": "1f45c.png", 
+        "unicode": "👜", 
+        "name": "Handbag"
+    }, 
+    "🚕": {
+        "style": "unicode", 
+        "image": "1f695.png", 
+        "name": "Taxi"
+    }, 
+    ":rabbit2:": {
+        "style": "github", 
+        "image": "1f407.png", 
+        "unicode": "🐇", 
+        "name": "Rabbit"
+    }, 
+    "😪": {
+        "style": "unicode", 
+        "image": "1f62a.png", 
+        "name": "Sleepy Face"
+    }, 
+    ":mailbox-closed:": {
+        "style": "github", 
+        "image": "1f4ea.png", 
+        "unicode": "📪", 
+        "name": "Closed Mailbox With Lowered Flag"
+    }, 
+    ":flag-mo:": {
+        "style": "github", 
+        "image": "1f1f2-1f1f4.png", 
+        "unicode": "🇲🇴", 
+        "name": "Macau"
+    }, 
+    ":star-of-david:": {
+        "style": "github", 
+        "image": "2721.png", 
+        "unicode": "✡", 
+        "name": "Star Of David"
+    }, 
+    "♊": {
+        "style": "unicode", 
+        "image": "264a.png", 
+        "name": "Gemini"
+    }, 
+    ":+1_tone2:": {
+        "style": "github", 
+        "image": "1f44d-1f3fc.png", 
+        "unicode": "👍🏼", 
+        "name": "Thumbs Up Sign - Tone 2"
+    }, 
+    ":dove:": {
+        "style": "github", 
+        "image": "1f54a.png", 
+        "unicode": "🕊", 
+        "name": "Dove Of Peace"
+    }, 
+    "📩": {
+        "style": "unicode", 
+        "image": "1f4e9.png", 
+        "name": "Envelope With Downwards Arrow Above"
+    }, 
+    "😼": {
+        "style": "unicode", 
+        "image": "1f63c.png", 
+        "name": "Cat Face With Wry Smile"
+    }, 
+    ":flag_fj:": {
+        "style": "github", 
+        "image": "1f1eb-1f1ef.png", 
+        "unicode": "🇫🇯", 
+        "name": "Fiji"
+    }, 
+    ":flag_lt:": {
+        "style": "github", 
+        "image": "1f1f1-1f1f9.png", 
+        "unicode": "🇱🇹", 
+        "name": "Lithuania"
+    }, 
+    ":levitate:": {
+        "style": "github", 
+        "image": "1f574.png", 
+        "unicode": "🕴", 
+        "name": "Man In Business Suit Levitating"
+    }, 
+    ":man-with-gua-pi-mao:": {
+        "style": "github", 
+        "image": "1f472.png", 
+        "unicode": "👲", 
+        "name": "Man With Gua Pi Mao"
+    }, 
+    "👾": {
+        "style": "unicode", 
+        "image": "1f47e.png", 
+        "name": "Alien Monster"
+    }, 
+    "🔓": {
+        "style": "unicode", 
+        "image": "1f513.png", 
+        "name": "Open Lock"
+    }, 
+    ":envelope_with_arrow:": {
+        "style": "github", 
+        "image": "1f4e9.png", 
+        "unicode": "📩", 
+        "name": "Envelope With Downwards Arrow Above"
+    }, 
+    ":tiger:": {
+        "style": "github", 
+        "image": "1f42f.png", 
+        "unicode": "🐯", 
+        "name": "Tiger Face"
+    }, 
+    ":thumbup_tone2:": {
+        "style": "github", 
+        "image": "1f44d-1f3fc.png", 
+        "unicode": "👍🏼", 
+        "name": "Thumbs Up Sign - Tone 2"
+    }, 
+    "🖨": {
+        "style": "unicode", 
+        "image": "1f5a8.png", 
+        "name": "Printer"
+    }, 
+    "🏄🏾": {
+        "style": "unicode", 
+        "image": "1f3c4-1f3fe.png", 
+        "name": "Surfer - Tone 4"
+    }, 
+    "🏄🏿": {
+        "style": "unicode", 
+        "image": "1f3c4-1f3ff.png", 
+        "name": "Surfer - Tone 5"
+    }, 
+    "🏄🏼": {
+        "style": "unicode", 
+        "image": "1f3c4-1f3fc.png", 
+        "name": "Surfer - Tone 2"
+    }, 
+    "🏄🏽": {
+        "style": "unicode", 
+        "image": "1f3c4-1f3fd.png", 
+        "name": "Surfer - Tone 3"
+    }, 
+    "🏄🏻": {
+        "style": "unicode", 
+        "image": "1f3c4-1f3fb.png", 
+        "name": "Surfer - Tone 1"
+    }, 
+    ":construction-worker:": {
+        "style": "github", 
+        "image": "1f477.png", 
+        "unicode": "👷", 
+        "name": "Construction Worker"
+    }, 
+    ":pouch:": {
+        "style": "github", 
+        "image": "1f45d.png", 
+        "unicode": "👝", 
+        "name": "Pouch"
+    }, 
+    ":person-with-pouting-face-tone3:": {
+        "style": "github", 
+        "image": "1f64e-1f3fd.png", 
+        "unicode": "🙎🏽", 
+        "name": "Person With Pouting Face Tone3"
+    }, 
+    "👏🏿": {
+        "style": "unicode", 
+        "image": "1f44f-1f3ff.png", 
+        "name": "Clapping Hands Sign - Tone 5"
+    }, 
+    "👏🏾": {
+        "style": "unicode", 
+        "image": "1f44f-1f3fe.png", 
+        "name": "Clapping Hands Sign - Tone 4"
+    }, 
+    "👏🏽": {
+        "style": "unicode", 
+        "image": "1f44f-1f3fd.png", 
+        "name": "Clapping Hands Sign - Tone 3"
+    }, 
+    "👏🏼": {
+        "style": "unicode", 
+        "image": "1f44f-1f3fc.png", 
+        "name": "Clapping Hands Sign - Tone 2"
+    }, 
+    "👏🏻": {
+        "style": "unicode", 
+        "image": "1f44f-1f3fb.png", 
+        "name": "Clapping Hands Sign - Tone 1"
+    }, 
+    "✌🏾": {
+        "style": "unicode", 
+        "image": "270c-1f3fe.png", 
+        "name": "Victory Hand - Tone 4"
+    }, 
+    "✌🏿": {
+        "style": "unicode", 
+        "image": "270c-1f3ff.png", 
+        "name": "Victory Hand - Tone 5"
+    }, 
+    "✌🏼": {
+        "style": "unicode", 
+        "image": "270c-1f3fc.png", 
+        "name": "Victory Hand - Tone 2"
+    }, 
+    "✌🏽": {
+        "style": "unicode", 
+        "image": "270c-1f3fd.png", 
+        "name": "Victory Hand - Tone 3"
+    }, 
+    "✌🏻": {
+        "style": "unicode", 
+        "image": "270c-1f3fb.png", 
+        "name": "Victory Hand - Tone 1"
+    }, 
+    ":left_luggage:": {
+        "style": "github", 
+        "image": "1f6c5.png", 
+        "unicode": "🛅", 
+        "name": "Left Luggage"
+    }, 
+    ":dango:": {
+        "style": "github", 
+        "image": "1f361.png", 
+        "unicode": "🍡", 
+        "name": "Dango"
+    }, 
+    ":japanese-castle:": {
+        "style": "github", 
+        "image": "1f3ef.png", 
+        "unicode": "🏯", 
+        "name": "Japanese Castle"
+    }, 
+    "🍧": {
+        "style": "unicode", 
+        "image": "1f367.png", 
+        "name": "Shaved Ice"
+    }, 
+    ":tangerine:": {
+        "style": "github", 
+        "image": "1f34a.png", 
+        "unicode": "🍊", 
+        "name": "Tangerine"
+    }, 
+    ":muscle-tone1:": {
+        "style": "github", 
+        "image": "1f4aa-1f3fb.png", 
+        "unicode": "💪🏻", 
+        "name": "Flexed Biceps - Tone 1"
+    }, 
+    ":japanese_ogre:": {
+        "style": "github", 
+        "image": "1f479.png", 
+        "unicode": "👹", 
+        "name": "Japanese Ogre"
+    }, 
+    ":basketball-player-tone1:": {
+        "style": "github", 
+        "image": "26f9-1f3fb.png", 
+        "unicode": "⛹🏻", 
+        "name": "Person With Ball - Tone 1"
+    }, 
+    "🏼": {
+        "style": "unicode", 
+        "image": "1f3fc.png", 
+        "name": "Emoji Modifier Fitzpatrick Type-3"
+    }, 
+    ":si:": {
+        "style": "github", 
+        "image": "1f1f8-1f1ee.png", 
+        "unicode": "🇸🇮", 
+        "name": "Slovenia"
+    }, 
+    "🦍": {
+        "style": "unicode", 
+        "image": "1f98d.png", 
+        "name": "Gorilla"
+    }, 
+    "🎑": {
+        "style": "unicode", 
+        "image": "1f391.png", 
+        "name": "Moon Viewing Ceremony"
+    }, 
+    "🖕": {
+        "style": "unicode", 
+        "image": "1f595.png", 
+        "name": "Reversed Hand With Middle Finger Extended"
+    }, 
+    ":raised_back_of_hand_tone3:": {
+        "style": "github", 
+        "image": "1f91a-1f3fd.png", 
+        "unicode": "🤚🏽", 
+        "name": "Raised Back Of Hand - Tone 3"
+    }, 
+    ":calendar:": {
+        "style": "github", 
+        "image": "1f4c6.png", 
+        "unicode": "📆", 
+        "name": "Tear-off Calendar"
+    }, 
+    "🤢": {
+        "style": "unicode", 
+        "image": "1f922.png", 
+        "name": "Nauseated Face"
+    }, 
+    ":girl-tone2:": {
+        "style": "github", 
+        "image": "1f467-1f3fc.png", 
+        "unicode": "👧🏼", 
+        "name": "Girl - Tone 2"
+    }, 
+    "🌦": {
+        "style": "unicode", 
+        "image": "1f326.png", 
+        "name": "White Sun Behind Cloud With Rain"
+    }, 
+    "🔪": {
+        "style": "unicode", 
+        "image": "1f52a.png", 
+        "name": "Hocho"
+    }, 
+    "🤜🏿": {
+        "style": "unicode", 
+        "image": "1f91c-1f3ff.png", 
+        "name": "Right Facing Fist - Tone 5"
+    }, 
+    ":bicyclist-tone5:": {
+        "style": "github", 
+        "image": "1f6b4-1f3ff.png", 
+        "unicode": "🚴🏿", 
+        "name": "Bicyclist - Tone 5"
+    }, 
+    ":blossom:": {
+        "style": "github", 
+        "image": "1f33c.png", 
+        "unicode": "🌼", 
+        "name": "Blossom"
+    }, 
+    "💿": {
+        "style": "unicode", 
+        "image": "1f4bf.png", 
+        "name": "Optical Disc"
+    }, 
+    ":regional_indicator_f:": {
+        "style": "github", 
+        "image": "1f1eb.png", 
+        "unicode": "🇫", 
+        "name": "Regional Indicator Symbol Letter F"
+    }, 
+    ":va:": {
+        "style": "github", 
+        "image": "1f1fb-1f1e6.png", 
+        "unicode": "🇻🇦", 
+        "name": "The Vatican City"
+    }, 
+    "🉐": {
+        "style": "unicode", 
+        "image": "1f250.png", 
+        "name": "Circled Ideograph Advantage"
+    }, 
+    "👔": {
+        "style": "unicode", 
+        "image": "1f454.png", 
+        "name": "Necktie"
+    }, 
+    ":flag-tg:": {
+        "style": "github", 
+        "image": "1f1f9-1f1ec.png", 
+        "unicode": "🇹🇬", 
+        "name": "Togo"
+    }, 
+    ":speech_balloon:": {
+        "style": "github", 
+        "image": "1f4ac.png", 
+        "unicode": "💬", 
+        "name": "Speech Balloon"
+    }, 
+    ":drum_with_drumsticks:": {
+        "style": "github", 
+        "image": "1f941.png", 
+        "unicode": "🥁", 
+        "name": "Drum With Drumsticks"
+    }, 
+    ":flag_vi:": {
+        "style": "github", 
+        "image": "1f1fb-1f1ee.png", 
+        "unicode": "🇻🇮", 
+        "name": "U.s. Virgin Islands"
+    }, 
+    ":children-crossing:": {
+        "style": "github", 
+        "image": "1f6b8.png", 
+        "unicode": "🚸", 
+        "name": "Children Crossing"
+    }, 
+    "✉": {
+        "style": "unicode", 
+        "image": "2709.png", 
+        "name": "Envelope"
+    }, 
+    ":night-with-stars:": {
+        "style": "github", 
+        "image": "1f303.png", 
+        "unicode": "🌃", 
+        "name": "Night With Stars"
+    }, 
+    "😓": {
+        "style": "unicode", 
+        "ascii": "':(", 
+        "image": "1f613.png", 
+        "name": "Face With Cold Sweat"
+    }, 
+    ":a:": {
+        "style": "github", 
+        "image": "1f170.png", 
+        "unicode": "🅰", 
+        "name": "Negative Squared Latin Capital Letter A"
+    }, 
+    ":shaking_hands_tone3:": {
+        "style": "github", 
+        "image": "1f91d-1f3fd.png", 
+        "unicode": "🤝🏽", 
+        "name": "Handshake - Tone 3"
+    }, 
+    ":flag_dg:": {
+        "style": "github", 
+        "image": "1f1e9-1f1ec.png", 
+        "unicode": "🇩🇬", 
+        "name": "Diego Garcia"
+    }, 
+    ":nr:": {
+        "style": "github", 
+        "image": "1f1f3-1f1f7.png", 
+        "unicode": "🇳🇷", 
+        "name": "Nauru"
+    }, 
+    "🚨": {
+        "style": "unicode", 
+        "image": "1f6a8.png", 
+        "name": "Police Cars Revolving Light"
+    }, 
+    ":mag_right:": {
+        "style": "github", 
+        "image": "1f50e.png", 
+        "unicode": "🔎", 
+        "name": "Right-pointing Magnifying Glass"
+    }, 
+    ":muscle_tone4:": {
+        "style": "github", 
+        "image": "1f4aa-1f3fe.png", 
+        "unicode": "💪🏾", 
+        "name": "Flexed Biceps - Tone 4"
+    }, 
+    ":flag_ps:": {
+        "style": "github", 
+        "image": "1f1f5-1f1f8.png", 
+        "unicode": "🇵🇸", 
+        "name": "Palestinian Authority"
+    }, 
+    ":frame-photo:": {
+        "style": "github", 
+        "image": "1f5bc.png", 
+        "unicode": "🖼", 
+        "name": "Frame With Picture"
+    }, 
+    ":man_with_turban_tone4:": {
+        "style": "github", 
+        "image": "1f473-1f3fe.png", 
+        "unicode": "👳🏾", 
+        "name": "Man With Turban - Tone 4"
+    }, 
+    ":rugby-football:": {
+        "style": "github", 
+        "image": "1f3c9.png", 
+        "unicode": "🏉", 
+        "name": "Rugby Football"
+    }, 
+    ":water_polo_tone1:": {
+        "style": "github", 
+        "image": "1f93d-1f3fb.png", 
+        "unicode": "🤽🏻", 
+        "name": "Water Polo - Tone 1"
+    }, 
+    ":trophy:": {
+        "style": "github", 
+        "image": "1f3c6.png", 
+        "unicode": "🏆", 
+        "name": "Trophy"
+    }, 
+    ":foggy:": {
+        "style": "github", 
+        "image": "1f301.png", 
+        "unicode": "🌁", 
+        "name": "Foggy"
+    }, 
+    ":notes:": {
+        "style": "github", 
+        "image": "1f3b6.png", 
+        "unicode": "🎶", 
+        "name": "Multiple Musical Notes"
+    }, 
+    "💕": {
+        "style": "unicode", 
+        "image": "1f495.png", 
+        "name": "Two Hearts"
+    }, 
+    ":fencer:": {
+        "style": "github", 
+        "image": "1f93a.png", 
+        "unicode": "🤺", 
+        "name": "Fencer"
+    }, 
+    ":fox_face:": {
+        "style": "github", 
+        "image": "1f98a.png", 
+        "unicode": "🦊", 
+        "name": "Fox Face"
+    }, 
+    ":flag_zm:": {
+        "style": "github", 
+        "image": "1f1ff-1f1f2.png", 
+        "unicode": "🇿🇲", 
+        "name": "Zambia"
+    }, 
+    ":aw:": {
+        "style": "github", 
+        "image": "1f1e6-1f1fc.png", 
+        "unicode": "🇦🇼", 
+        "name": "Aruba"
+    }, 
+    ":electric_plug:": {
+        "style": "github", 
+        "image": "1f50c.png", 
+        "unicode": "🔌", 
+        "name": "Electric Plug"
+    }, 
+    "🎻": {
+        "style": "unicode", 
+        "image": "1f3bb.png", 
+        "name": "Violin"
+    }, 
+    ":family_wwgg:": {
+        "style": "github", 
+        "image": "1f469-1f469-1f467-1f467.png", 
+        "unicode": "👩👩👧👧", 
+        "name": "Family (woman,woman,girl,girl)"
+    }, 
+    ":man_with_gua_pi_mao_tone3:": {
+        "style": "github", 
+        "image": "1f472-1f3fd.png", 
+        "unicode": "👲🏽", 
+        "name": "Man With Gua Pi Mao - Tone 3"
+    }, 
+    "🍐": {
+        "style": "unicode", 
+        "image": "1f350.png", 
+        "name": "Pear"
+    }, 
+    ":flag_bm:": {
+        "style": "github", 
+        "image": "1f1e7-1f1f2.png", 
+        "unicode": "🇧🇲", 
+        "name": "Bermuda"
+    }, 
+    ":stop_button:": {
+        "style": "github", 
+        "image": "23f9.png", 
+        "unicode": "⏹", 
+        "name": "Black Square For Stop"
+    }, 
+    "🕔": {
+        "style": "unicode", 
+        "image": "1f554.png", 
+        "name": "Clock Face Five Oclock"
+    }, 
+    ":spaghetti:": {
+        "style": "github", 
+        "image": "1f35d.png", 
+        "unicode": "🍝", 
+        "name": "Spaghetti"
+    }, 
+    ":flag-al:": {
+        "style": "github", 
+        "image": "1f1e6-1f1f1.png", 
+        "unicode": "🇦🇱", 
+        "name": "Albania"
+    }, 
+    "🛩": {
+        "style": "unicode", 
+        "image": "1f6e9.png", 
+        "name": "Small Airplane"
+    }, 
+    ":crossed-flags:": {
+        "style": "github", 
+        "image": "1f38c.png", 
+        "unicode": "🎌", 
+        "name": "Crossed Flags"
+    }, 
+    ":runner_tone2:": {
+        "style": "github", 
+        "image": "1f3c3-1f3fc.png", 
+        "unicode": "🏃🏼", 
+        "name": "Runner - Tone 2"
+    }, 
+    ":regional-indicator-k:": {
+        "style": "github", 
+        "image": "1f1f0.png", 
+        "unicode": "🇰", 
+        "name": "Regional Indicator Symbol Letter K"
+    }, 
+    ":do_not_litter:": {
+        "style": "github", 
+        "image": "1f6af.png", 
+        "unicode": "🚯", 
+        "name": "Do Not Litter Symbol"
+    }, 
+    ":bride-with-veil-tone2:": {
+        "style": "github", 
+        "image": "1f470-1f3fc.png", 
+        "unicode": "👰🏼", 
+        "name": "Bride With Veil - Tone 2"
+    }, 
+    ":sign_of_the_horns_tone2:": {
+        "style": "github", 
+        "image": "1f918-1f3fc.png", 
+        "unicode": "🤘🏼", 
+        "name": "Sign Of The Horns - Tone 2"
+    }, 
+    ":camera:": {
+        "style": "github", 
+        "image": "1f4f7.png", 
+        "unicode": "📷", 
+        "name": "Camera"
+    }, 
+    "👊🏼": {
+        "style": "unicode", 
+        "image": "1f44a-1f3fc.png", 
+        "name": "Fisted Hand Sign - Tone 2"
+    }, 
+    "👊🏽": {
+        "style": "unicode", 
+        "image": "1f44a-1f3fd.png", 
+        "name": "Fisted Hand Sign - Tone 3"
+    }, 
+    "👊🏾": {
+        "style": "unicode", 
+        "image": "1f44a-1f3fe.png", 
+        "name": "Fisted Hand Sign - Tone 4"
+    }, 
+    "👊🏿": {
+        "style": "unicode", 
+        "image": "1f44a-1f3ff.png", 
+        "name": "Fisted Hand Sign - Tone 5"
+    }, 
+    "👊🏻": {
+        "style": "unicode", 
+        "image": "1f44a-1f3fb.png", 
+        "name": "Fisted Hand Sign - Tone 1"
+    }, 
+    "🤜🏾": {
+        "style": "unicode", 
+        "image": "1f91c-1f3fe.png", 
+        "name": "Right Facing Fist - Tone 4"
+    }, 
+    ":prince-tone5:": {
+        "style": "github", 
+        "image": "1f934-1f3ff.png", 
+        "unicode": "🤴🏿", 
+        "name": "Prince - Tone 5"
+    }, 
+    "🤜🏼": {
+        "style": "unicode", 
+        "image": "1f91c-1f3fc.png", 
+        "name": "Right Facing Fist - Tone 2"
+    }, 
+    "🤜🏽": {
+        "style": "unicode", 
+        "image": "1f91c-1f3fd.png", 
+        "name": "Right Facing Fist - Tone 3"
+    }, 
+    "🤜🏻": {
+        "style": "unicode", 
+        "image": "1f91c-1f3fb.png", 
+        "name": "Right Facing Fist - Tone 1"
+    }, 
+    "✳": {
+        "style": "unicode", 
+        "image": "2733.png", 
+        "name": "Eight Spoked Asterisk"
+    }, 
+    ":princess-tone4:": {
+        "style": "github", 
+        "image": "1f478-1f3fe.png", 
+        "unicode": "👸🏾", 
+        "name": "Princess - Tone 4"
+    }, 
+    ":dancer-tone5:": {
+        "style": "github", 
+        "image": "1f483-1f3ff.png", 
+        "unicode": "💃🏿", 
+        "name": "Dancer - Tone 5"
+    }, 
+    ":ok-hand-tone1:": {
+        "style": "github", 
+        "image": "1f44c-1f3fb.png", 
+        "unicode": "👌🏻", 
+        "name": "Ok Hand Sign - Tone 1"
+    }, 
+    ":fo:": {
+        "style": "github", 
+        "image": "1f1eb-1f1f4.png", 
+        "unicode": "🇫🇴", 
+        "name": "Faroe Islands"
+    }, 
+    ":cartwheel-tone5:": {
+        "style": "github", 
+        "image": "1f938-1f3ff.png", 
+        "unicode": "🤸🏿", 
+        "name": "Person Doing Cartwheel - Tone 5"
+    }, 
+    ":pn:": {
+        "style": "github", 
+        "image": "1f1f5-1f1f3.png", 
+        "unicode": "🇵🇳", 
+        "name": "Pitcairn"
+    }, 
+    ":flag_sr:": {
+        "style": "github", 
+        "image": "1f1f8-1f1f7.png", 
+        "unicode": "🇸🇷", 
+        "name": "Suriname"
+    }, 
+    ":weight_lifter:": {
+        "style": "github", 
+        "image": "1f3cb.png", 
+        "unicode": "🏋", 
+        "name": "Weight Lifter"
+    }, 
+    ":neutral_face:": {
+        "style": "github", 
+        "image": "1f610.png", 
+        "unicode": "😐", 
+        "name": "Neutral Face"
+    }, 
+    "🇼": {
+        "style": "unicode", 
+        "image": "1f1fc.png", 
+        "name": "Regional Indicator Symbol Letter W"
+    }, 
+    ":rose:": {
+        "style": "github", 
+        "image": "1f339.png", 
+        "unicode": "🌹", 
+        "name": "Rose"
+    }, 
+    ":mk:": {
+        "style": "github", 
+        "image": "1f1f2-1f1f0.png", 
+        "unicode": "🇲🇰", 
+        "name": "Macedonia"
+    }, 
+    ":clock3:": {
+        "style": "github", 
+        "image": "1f552.png", 
+        "unicode": "🕒", 
+        "name": "Clock Face Three Oclock"
+    }, 
+    "🤞🏻": {
+        "style": "unicode", 
+        "image": "1f91e-1f3fb.png", 
+        "name": "Hand With Index And Middle Fingers Crossed - Tone 1"
+    }, 
+    "🤞🏼": {
+        "style": "unicode", 
+        "image": "1f91e-1f3fc.png", 
+        "name": "Hand With Index And Middle Fingers Crossed - Tone 2"
+    }, 
+    "🤞🏽": {
+        "style": "unicode", 
+        "image": "1f91e-1f3fd.png", 
+        "name": "Hand With Index And Middle Fingers Crossed - Tone 3"
+    }, 
+    "🤞🏾": {
+        "style": "unicode", 
+        "image": "1f91e-1f3fe.png", 
+        "name": "Hand With Index And Middle Fingers Crossed - Tone 4"
+    }, 
+    "🤞🏿": {
+        "style": "unicode", 
+        "image": "1f91e-1f3ff.png", 
+        "name": "Hand With Index And Middle Fingers Crossed - Tone 5"
+    }, 
+    "🌪": {
+        "style": "unicode", 
+        "image": "1f32a.png", 
+        "name": "Cloud With Tornado"
+    }, 
+    ":disappointed_relieved:": {
+        "style": "github", 
+        "image": "1f625.png", 
+        "unicode": "😥", 
+        "name": "Disappointed But Relieved Face"
+    }, 
+    "💻": {
+        "style": "unicode", 
+        "image": "1f4bb.png", 
+        "name": "Personal Computer"
+    }, 
+    "🇹🇩": {
+        "style": "unicode", 
+        "image": "1f1f9-1f1e9.png", 
+        "name": "Chad"
+    }, 
+    "🇹🇨": {
+        "style": "unicode", 
+        "image": "1f1f9-1f1e8.png", 
+        "name": "Turks And Caicos Islands"
+    }, 
+    "🇹🇫": {
+        "style": "unicode", 
+        "image": "1f1f9-1f1eb.png", 
+        "name": "French Southern Territories"
+    }, 
+    "🇹🇭": {
+        "style": "unicode", 
+        "image": "1f1f9-1f1ed.png", 
+        "name": "Thailand"
+    }, 
+    "🇹🇬": {
+        "style": "unicode", 
+        "image": "1f1f9-1f1ec.png", 
+        "name": "Togo"
+    }, 
+    "🇹🇯": {
+        "style": "unicode", 
+        "image": "1f1f9-1f1ef.png", 
+        "name": "Tajikistan"
+    }, 
+    ":flag_mu:": {
+        "style": "github", 
+        "image": "1f1f2-1f1fa.png", 
+        "unicode": "🇲🇺", 
+        "name": "Mauritius"
+    }, 
+    "🇹🇦": {
+        "style": "unicode", 
+        "image": "1f1f9-1f1e6.png", 
+        "name": "Tristan Da Cunha"
+    }, 
+    "🇹🇹": {
+        "style": "unicode", 
+        "image": "1f1f9-1f1f9.png", 
+        "name": "Trinidad And Tobago"
+    }, 
+    "👐": {
+        "style": "unicode", 
+        "image": "1f450.png", 
+        "name": "Open Hands Sign"
+    }, 
+    "🇹🇻": {
+        "style": "unicode", 
+        "image": "1f1f9-1f1fb.png", 
+        "name": "Tuvalu"
+    }, 
+    "🇹🇼": {
+        "style": "unicode", 
+        "image": "1f1f9-1f1fc.png", 
+        "name": "The Republic Of China"
+    }, 
+    "🇹🇿": {
+        "style": "unicode", 
+        "image": "1f1f9-1f1ff.png", 
+        "name": "Tanzania"
+    }, 
+    "🇹🇱": {
+        "style": "unicode", 
+        "image": "1f1f9-1f1f1.png", 
+        "name": "Timor-leste"
+    }, 
+    "🇹🇰": {
+        "style": "unicode", 
+        "image": "1f1f9-1f1f0.png", 
+        "name": "Tokelau"
+    }, 
+    "🇹🇳": {
+        "style": "unicode", 
+        "image": "1f1f9-1f1f3.png", 
+        "name": "Tunisia"
+    }, 
+    ":flag_cr:": {
+        "style": "github", 
+        "image": "1f1e8-1f1f7.png", 
+        "unicode": "🇨🇷", 
+        "name": "Costa Rica"
+    }, 
+    "🇹🇴": {
+        "style": "unicode", 
+        "image": "1f1f9-1f1f4.png", 
+        "name": "Tonga"
+    }, 
+    "🇹🇷": {
+        "style": "unicode", 
+        "image": "1f1f9-1f1f7.png", 
+        "name": "Turkey"
+    }, 
+    "🇩": {
+        "style": "unicode", 
+        "image": "1f1e9.png", 
+        "name": "Regional Indicator Symbol Letter D"
+    }, 
+    ":stuffed-flatbread:": {
+        "style": "github", 
+        "image": "1f959.png", 
+        "unicode": "🥙", 
+        "name": "Stuffed Flatbread"
+    }, 
+    ":family_mmgg:": {
+        "style": "github", 
+        "image": "1f468-1f468-1f467-1f467.png", 
+        "unicode": "👨👨👧👧", 
+        "name": "Family (man,man,girl,girl)"
+    }, 
+    ":woman-tone4:": {
+        "style": "github", 
+        "image": "1f469-1f3fe.png", 
+        "unicode": "👩🏾", 
+        "name": "Woman - Tone 4"
+    }, 
+    "🅾": {
+        "style": "unicode", 
+        "image": "1f17e.png", 
+        "name": "Negative Squared Latin Capital Letter O"
+    }, 
+    ":waning-crescent-moon:": {
+        "style": "github", 
+        "image": "1f318.png", 
+        "unicode": "🌘", 
+        "name": "Waning Crescent Moon Symbol"
+    }, 
+    "⬅": {
+        "style": "unicode", 
+        "image": "2b05.png", 
+        "name": "Leftwards Black Arrow"
+    }, 
+    ":guardsman:": {
+        "style": "github", 
+        "image": "1f482.png", 
+        "unicode": "💂", 
+        "name": "Guardsman"
+    }, 
+    ":flag-cc:": {
+        "style": "github", 
+        "image": "1f1e8-1f1e8.png", 
+        "unicode": "🇨🇨", 
+        "name": "Cocos (keeling) Islands"
+    }, 
+    ":clap-tone3:": {
+        "style": "github", 
+        "image": "1f44f-1f3fd.png", 
+        "unicode": "👏🏽", 
+        "name": "Clapping Hands Sign - Tone 3"
+    }, 
+    ":rotating-light:": {
+        "style": "github", 
+        "image": "1f6a8.png", 
+        "unicode": "🚨", 
+        "name": "Police Cars Revolving Light"
+    }, 
+    ":heavy_plus_sign:": {
+        "style": "github", 
+        "image": "2795.png", 
+        "unicode": "➕", 
+        "name": "Heavy Plus Sign"
+    }, 
+    ":desktop_computer:": {
+        "style": "github", 
+        "image": "1f5a5.png", 
+        "unicode": "🖥", 
+        "name": "Desktop Computer"
+    }, 
+    "🤹": {
+        "style": "unicode", 
+        "image": "1f939.png", 
+        "name": "Juggling"
+    }, 
+    ":flag_tz:": {
+        "style": "github", 
+        "image": "1f1f9-1f1ff.png", 
+        "unicode": "🇹🇿", 
+        "name": "Tanzania"
+    }, 
+    ":muscle:": {
+        "style": "github", 
+        "image": "1f4aa.png", 
+        "unicode": "💪", 
+        "name": "Flexed Biceps"
+    }, 
+    "🚴🏾": {
+        "style": "unicode", 
+        "image": "1f6b4-1f3fe.png", 
+        "name": "Bicyclist - Tone 4"
+    }, 
+    "🚴🏿": {
+        "style": "unicode", 
+        "image": "1f6b4-1f3ff.png", 
+        "name": "Bicyclist - Tone 5"
+    }, 
+    "🚴🏼": {
+        "style": "unicode", 
+        "image": "1f6b4-1f3fc.png", 
+        "name": "Bicyclist - Tone 2"
+    }, 
+    "🚴🏽": {
+        "style": "unicode", 
+        "image": "1f6b4-1f3fd.png", 
+        "name": "Bicyclist - Tone 3"
+    }, 
+    "🚴🏻": {
+        "style": "unicode", 
+        "image": "1f6b4-1f3fb.png", 
+        "name": "Bicyclist - Tone 1"
+    }, 
+    ":vibration_mode:": {
+        "style": "github", 
+        "image": "1f4f3.png", 
+        "unicode": "📳", 
+        "name": "Vibration Mode"
+    }, 
+    ":runner:": {
+        "style": "github", 
+        "image": "1f3c3.png", 
+        "unicode": "🏃", 
+        "name": "Runner"
+    }, 
+    ":shaking_hands:": {
+        "style": "github", 
+        "image": "1f91d.png", 
+        "unicode": "🤝", 
+        "name": "Handshake"
+    }, 
+    ":cartwheel_tone3:": {
+        "style": "github", 
+        "image": "1f938-1f3fd.png", 
+        "unicode": "🤸🏽", 
+        "name": "Person Doing Cartwheel - Tone 3"
+    }, 
+    ":flag_uy:": {
+        "style": "github", 
+        "image": "1f1fa-1f1fe.png", 
+        "unicode": "🇺🇾", 
+        "name": "Uruguay"
+    }, 
+    "💑": {
+        "style": "unicode", 
+        "image": "1f491.png", 
+        "name": "Couple With Heart"
+    }, 
+    ":eye-in-speech-bubble:": {
+        "style": "github", 
+        "image": "1f441-1f5e8.png", 
+        "unicode": "👁🗨", 
+        "name": "Eye In Speech Bubble"
+    }, 
+    ":ok_hand_tone2:": {
+        "style": "github", 
+        "image": "1f44c-1f3fc.png", 
+        "unicode": "👌🏼", 
+        "name": "Ok Hand Sign - Tone 2"
+    }, 
+    ":st:": {
+        "style": "github", 
+        "image": "1f1f8-1f1f9.png", 
+        "unicode": "🇸🇹", 
+        "name": "São Tomé And Príncipe"
+    }, 
+    "🤷🏿": {
+        "style": "unicode", 
+        "image": "1f937-1f3ff.png", 
+        "name": "Shrug - Tone 5"
+    }, 
+    "🤷🏾": {
+        "style": "unicode", 
+        "image": "1f937-1f3fe.png", 
+        "name": "Shrug - Tone 4"
+    }, 
+    "🤷🏽": {
+        "style": "unicode", 
+        "image": "1f937-1f3fd.png", 
+        "name": "Shrug - Tone 3"
+    }, 
+    "🤷🏼": {
+        "style": "unicode", 
+        "image": "1f937-1f3fc.png", 
+        "name": "Shrug - Tone 2"
+    }, 
+    "🤷🏻": {
+        "style": "unicode", 
+        "image": "1f937-1f3fb.png", 
+        "name": "Shrug - Tone 1"
+    }, 
+    "🐦": {
+        "style": "unicode", 
+        "image": "1f426.png", 
+        "name": "Bird"
+    }, 
+    ":fried_shrimp:": {
+        "style": "github", 
+        "image": "1f364.png", 
+        "unicode": "🍤", 
+        "name": "Fried Shrimp"
+    }, 
+    "🎿": {
+        "style": "unicode", 
+        "image": "1f3bf.png", 
+        "name": "Ski And Ski Boot"
+    }, 
+    ":raised-hand-tone3:": {
+        "style": "github", 
+        "image": "270b-1f3fd.png", 
+        "unicode": "✋🏽", 
+        "name": "Raised Hand - Tone 3"
+    }, 
+    "🕐": {
+        "style": "unicode", 
+        "image": "1f550.png", 
+        "name": "Clock Face One Oclock"
+    }, 
+    "🍔": {
+        "style": "unicode", 
+        "image": "1f354.png", 
+        "name": "Hamburger"
+    }, 
+    "🙍🏽": {
+        "style": "unicode", 
+        "image": "1f64d-1f3fd.png", 
+        "name": "Person Frowning - Tone 3"
+    }, 
+    "🙍🏼": {
+        "style": "unicode", 
+        "image": "1f64d-1f3fc.png", 
+        "name": "Person Frowning - Tone 2"
+    }, 
+    "🙍🏿": {
+        "style": "unicode", 
+        "image": "1f64d-1f3ff.png", 
+        "name": "Person Frowning - Tone 5"
+    }, 
+    "🙍🏾": {
+        "style": "unicode", 
+        "image": "1f64d-1f3fe.png", 
+        "name": "Person Frowning - Tone 4"
+    }, 
+    ":cop_tone5:": {
+        "style": "github", 
+        "image": "1f46e-1f3ff.png", 
+        "unicode": "👮🏿", 
+        "name": "Police Officer - Tone 5"
+    }, 
+    "🙍🏻": {
+        "style": "unicode", 
+        "image": "1f64d-1f3fb.png", 
+        "name": "Person Frowning - Tone 1"
+    }, 
+    ":u6709:": {
+        "style": "github", 
+        "image": "1f236.png", 
+        "unicode": "🈶", 
+        "name": "Squared Cjk Unified Ideograph-6709"
+    }, 
+    ":girl-tone4:": {
+        "style": "github", 
+        "image": "1f467-1f3fe.png", 
+        "unicode": "👧🏾", 
+        "name": "Girl - Tone 4"
+    }, 
+    ":selfie_tone3:": {
+        "style": "github", 
+        "image": "1f933-1f3fd.png", 
+        "unicode": "🤳🏽", 
+        "name": "Selfie - Tone 3"
+    }, 
+    ":mv:": {
+        "style": "github", 
+        "image": "1f1f2-1f1fb.png", 
+        "unicode": "🇲🇻", 
+        "name": "Maldives"
+    }, 
+    "👨👨👧": {
+        "style": "unicode", 
+        "image": "1f468-1f468-1f467.png", 
+        "name": "Family (man,man,girl)"
+    }, 
+    "👨👨👦": {
+        "style": "unicode", 
+        "image": "1f468-1f468-1f466.png", 
+        "name": "Family (man,man,boy)"
+    }, 
+    ":card_index_dividers:": {
+        "style": "github", 
+        "image": "1f5c2.png", 
+        "unicode": "🗂", 
+        "name": "Card Index Dividers"
+    }, 
+    ":man-in-tuxedo-tone1:": {
+        "style": "github", 
+        "image": "1f935-1f3fb.png", 
+        "unicode": "🤵🏻", 
+        "name": "Man In Tuxedo - Tone 1"
+    }, 
+    ":control_knobs:": {
+        "style": "github", 
+        "image": "1f39b.png", 
+        "unicode": "🎛", 
+        "name": "Control Knobs"
+    }, 
+    ":bird:": {
+        "style": "github", 
+        "image": "1f426.png", 
+        "unicode": "🐦", 
+        "name": "Bird"
+    }, 
+    ":flag_dz:": {
+        "style": "github", 
+        "image": "1f1e9-1f1ff.png", 
+        "unicode": "🇩🇿", 
+        "name": "Algeria"
+    }, 
+    ":black-circle:": {
+        "style": "github", 
+        "image": "26ab.png", 
+        "unicode": "⚫", 
+        "name": "Medium Black Circle"
+    }, 
+    ":slightly_frowning_face:": {
+        "style": "github", 
+        "image": "1f641.png", 
+        "unicode": "🙁", 
+        "name": "Slightly Frowning Face"
+    }, 
+    ":flag-mm:": {
+        "style": "github", 
+        "image": "1f1f2-1f1f2.png", 
+        "unicode": "🇲🇲", 
+        "name": "Myanmar"
+    }, 
+    "😽": {
+        "style": "unicode", 
+        "image": "1f63d.png", 
+        "name": "Kissing Cat Face With Closed Eyes"
+    }, 
+    ":stop-button:": {
+        "style": "github", 
+        "image": "23f9.png", 
+        "unicode": "⏹", 
+        "name": "Black Square For Stop"
+    }, 
+    "🛒": {
+        "style": "unicode", 
+        "image": "1f6d2.png", 
+        "name": "Shopping Trolley"
+    }, 
+    ":curly-loop:": {
+        "style": "github", 
+        "image": "27b0.png", 
+        "unicode": "➰", 
+        "name": "Curly Loop"
+    }, 
+    ":lock-with-ink-pen:": {
+        "style": "github", 
+        "image": "1f50f.png", 
+        "unicode": "🔏", 
+        "name": "Lock With Ink Pen"
+    }, 
+    "⛲": {
+        "style": "unicode", 
+        "image": "26f2.png", 
+        "name": "Fountain"
+    }, 
+    ":cloud_tornado:": {
+        "style": "github", 
+        "image": "1f32a.png", 
+        "unicode": "🌪", 
+        "name": "Cloud With Tornado"
+    }, 
+    "🇸🇪": {
+        "style": "unicode", 
+        "image": "1f1f8-1f1ea.png", 
+        "name": "Sweden"
+    }, 
+    "🇸🇨": {
+        "style": "unicode", 
+        "image": "1f1f8-1f1e8.png", 
+        "name": "The Seychelles"
+    }, 
+    "🇸🇩": {
+        "style": "unicode", 
+        "image": "1f1f8-1f1e9.png", 
+        "name": "Sudan"
+    }, 
+    "🇸🇮": {
+        "style": "unicode", 
+        "image": "1f1f8-1f1ee.png", 
+        "name": "Slovenia"
+    }, 
+    "🇸🇯": {
+        "style": "unicode", 
+        "image": "1f1f8-1f1ef.png", 
+        "name": "Svalbard And Jan Mayen"
+    }, 
+    "🇸🇬": {
+        "style": "unicode", 
+        "image": "1f1f8-1f1ec.png", 
+        "name": "Singapore"
+    }, 
+    "🇸🇭": {
+        "style": "unicode", 
+        "image": "1f1f8-1f1ed.png", 
+        "name": "Saint Helena"
+    }, 
+    "🇸🇦": {
+        "style": "unicode", 
+        "image": "1f1f8-1f1e6.png", 
+        "name": "Saudi Arabia"
+    }, 
+    "🇸🇧": {
+        "style": "unicode", 
+        "image": "1f1f8-1f1e7.png", 
+        "name": "The Solomon Islands"
+    }, 
+    ":ro:": {
+        "style": "github", 
+        "image": "1f1f7-1f1f4.png", 
+        "unicode": "🇷🇴", 
+        "name": "Romania"
+    }, 
+    "🇸🇻": {
+        "style": "unicode", 
+        "image": "1f1f8-1f1fb.png", 
+        "name": "El Salvador"
+    }, 
+    "🇸🇸": {
+        "style": "unicode", 
+        "image": "1f1f8-1f1f8.png", 
+        "name": "South Sudan"
+    }, 
+    "🇸🇹": {
+        "style": "unicode", 
+        "image": "1f1f8-1f1f9.png", 
+        "name": "São Tomé And Príncipe"
+    }, 
+    "🆕": {
+        "style": "unicode", 
+        "image": "1f195.png", 
+        "name": "Squared New"
+    }, 
+    "🇸🇿": {
+        "style": "unicode", 
+        "image": "1f1f8-1f1ff.png", 
+        "name": "Swaziland"
+    }, 
+    "🇸🇽": {
+        "style": "unicode", 
+        "image": "1f1f8-1f1fd.png", 
+        "name": "Sint Maarten"
+    }, 
+    "🇸🇲": {
+        "style": "unicode", 
+        "image": "1f1f8-1f1f2.png", 
+        "name": "San Marino"
+    }, 
+    "🇸🇳": {
+        "style": "unicode", 
+        "image": "1f1f8-1f1f3.png", 
+        "name": "Senegal"
+    }, 
+    "🇸🇰": {
+        "style": "unicode", 
+        "image": "1f1f8-1f1f0.png", 
+        "name": "Slovakia"
+    }, 
+    "🇸🇱": {
+        "style": "unicode", 
+        "image": "1f1f8-1f1f1.png", 
+        "name": "Sierra Leone"
+    }, 
+    "🇸🇷": {
+        "style": "unicode", 
+        "image": "1f1f8-1f1f7.png", 
+        "name": "Suriname"
+    }, 
+    "🇸🇴": {
+        "style": "unicode", 
+        "image": "1f1f8-1f1f4.png", 
+        "name": "Somalia"
+    }, 
+    ":lollipop:": {
+        "style": "github", 
+        "image": "1f36d.png", 
+        "unicode": "🍭", 
+        "name": "Lollipop"
+    }, 
+    ":snail:": {
+        "style": "github", 
+        "image": "1f40c.png", 
+        "unicode": "🐌", 
+        "name": "Snail"
+    }, 
+    ":flag-ly:": {
+        "style": "github", 
+        "image": "1f1f1-1f1fe.png", 
+        "unicode": "🇱🇾", 
+        "name": "Libya"
+    }, 
+    ":station:": {
+        "style": "github", 
+        "image": "1f689.png", 
+        "unicode": "🚉", 
+        "name": "Station"
+    }, 
+    ":repeat-one:": {
+        "style": "github", 
+        "image": "1f502.png", 
+        "unicode": "🔂", 
+        "name": "Clockwise Rightwards And Leftwards Open Circle Arrows With Circled One Overlay"
+    }, 
+    ":unicorn_face:": {
+        "style": "github", 
+        "image": "1f984.png", 
+        "unicode": "🦄", 
+        "name": "Unicorn Face"
+    }, 
+    ":new:": {
+        "style": "github", 
+        "image": "1f195.png", 
+        "unicode": "🆕", 
+        "name": "Squared New"
+    }, 
+    "🚻": {
+        "style": "unicode", 
+        "image": "1f6bb.png", 
+        "name": "Restroom"
+    }, 
+    ":flag_nl:": {
+        "style": "github", 
+        "image": "1f1f3-1f1f1.png", 
+        "unicode": "🇳🇱", 
+        "name": "The Netherlands"
+    }, 
+    ":basketball-player-tone3:": {
+        "style": "github", 
+        "image": "26f9-1f3fd.png", 
+        "unicode": "⛹🏽", 
+        "name": "Person With Ball - Tone 3"
+    }, 
+    ":reversed_hand_with_middle_finger_extended:": {
+        "style": "github", 
+        "image": "1f595.png", 
+        "unicode": "🖕", 
+        "name": "Reversed Hand With Middle Finger Extended"
+    }, 
+    ":back_of_hand_tone4:": {
+        "style": "github", 
+        "image": "1f91a-1f3fe.png", 
+        "unicode": "🤚🏾", 
+        "name": "Raised Back Of Hand - Tone 4"
+    }, 
+    ":hand_splayed_tone4:": {
+        "style": "github", 
+        "image": "1f590-1f3fe.png", 
+        "unicode": "🖐🏾", 
+        "name": "Raised Hand With Fingers Splayed - Tone 4"
+    }, 
+    ":liar:": {
+        "style": "github", 
+        "image": "1f925.png", 
+        "unicode": "🤥", 
+        "name": "Lying Face"
+    }, 
+    ":man_tone4:": {
+        "style": "github", 
+        "image": "1f468-1f3fe.png", 
+        "unicode": "👨🏾", 
+        "name": "Man - Tone 4"
+    }, 
+    "👉🏿": {
+        "style": "unicode", 
+        "image": "1f449-1f3ff.png", 
+        "name": "White Right Pointing Backhand Index - Tone 5"
+    }, 
+    "🏩": {
+        "style": "unicode", 
+        "image": "1f3e9.png", 
+        "name": "Love Hotel"
+    }, 
+    "👉🏾": {
+        "style": "unicode", 
+        "image": "1f449-1f3fe.png", 
+        "name": "White Right Pointing Backhand Index - Tone 4"
+    }, 
+    ":person-with-blond-hair-tone4:": {
+        "style": "github", 
+        "image": "1f471-1f3fe.png", 
+        "unicode": "👱🏾", 
+        "name": "Person With Blond Hair - Tone 4"
+    }, 
+    "🍾": {
+        "style": "unicode", 
+        "image": "1f37e.png", 
+        "name": "Bottle With Popping Cork"
+    }, 
+    ":first-quarter-moon:": {
+        "style": "github", 
+        "image": "1f313.png", 
+        "unicode": "🌓", 
+        "name": "First Quarter Moon Symbol"
+    }, 
+    ":electric-plug:": {
+        "style": "github", 
+        "image": "1f50c.png", 
+        "unicode": "🔌", 
+        "name": "Electric Plug"
+    }, 
+    ":bicyclist-tone3:": {
+        "style": "github", 
+        "image": "1f6b4-1f3fd.png", 
+        "unicode": "🚴🏽", 
+        "name": "Bicyclist - Tone 3"
+    }, 
+    ":person_with_ball_tone1:": {
+        "style": "github", 
+        "image": "26f9-1f3fb.png", 
+        "unicode": "⛹🏻", 
+        "name": "Person With Ball - Tone 1"
+    }, 
+    ":name-badge:": {
+        "style": "github", 
+        "image": "1f4db.png", 
+        "unicode": "📛", 
+        "name": "Name Badge"
+    }, 
+    ":raised_hand_with_fingers_splayed_tone1:": {
+        "style": "github", 
+        "image": "1f590-1f3fb.png", 
+        "unicode": "🖐🏻", 
+        "name": "Raised Hand With Fingers Splayed - Tone 1"
+    }, 
+    ";]": {
+        "style": "ascii", 
+        "ascii": ";)", 
+        "image": "1f609.png", 
+        "unicode": "😉", 
+        "name": "Winking Face"
+    }, 
+    ":point_up_2_tone5:": {
+        "style": "github", 
+        "image": "1f446-1f3ff.png", 
+        "unicode": "👆🏿", 
+        "name": "White Up Pointing Backhand Index - Tone 5"
+    }, 
+    ";D": {
+        "style": "ascii", 
+        "ascii": ";)", 
+        "image": "1f609.png", 
+        "unicode": "😉", 
+        "name": "Winking Face"
+    }, 
+    "🔽": {
+        "style": "unicode", 
+        "image": "1f53d.png", 
+        "name": "Down-pointing Small Red Triangle"
+    }, 
+    ":nose-tone3:": {
+        "style": "github", 
+        "image": "1f443-1f3fd.png", 
+        "unicode": "👃🏽", 
+        "name": "Nose - Tone 3"
+    }, 
+    ":small_airplane:": {
+        "style": "github", 
+        "image": "1f6e9.png", 
+        "unicode": "🛩", 
+        "name": "Small Airplane"
+    }, 
+    "🗒": {
+        "style": "unicode", 
+        "image": "1f5d2.png", 
+        "name": "Spiral Note Pad"
+    }, 
+    "🙋🏻": {
+        "style": "unicode", 
+        "image": "1f64b-1f3fb.png", 
+        "name": "Happy Person Raising One Hand Tone1"
+    }, 
+    ";)": {
+        "style": "ascii", 
+        "ascii": ";)", 
+        "image": "1f609.png", 
+        "unicode": "😉", 
+        "name": "Winking Face"
+    }, 
+    ":rage:": {
+        "style": "github", 
+        "image": "1f621.png", 
+        "unicode": "😡", 
+        "name": "Pouting Face"
+    }, 
+    "🙋🏿": {
+        "style": "unicode", 
+        "image": "1f64b-1f3ff.png", 
+        "name": "Happy Person Raising One Hand Tone5"
+    }, 
+    "🙋🏾": {
+        "style": "unicode", 
+        "image": "1f64b-1f3fe.png", 
+        "name": "Happy Person Raising One Hand Tone4"
+    }, 
+    ":regional_indicator_d:": {
+        "style": "github", 
+        "image": "1f1e9.png", 
+        "unicode": "🇩", 
+        "name": "Regional Indicator Symbol Letter D"
+    }, 
+    "🙋🏼": {
+        "style": "unicode", 
+        "image": "1f64b-1f3fc.png", 
+        "name": "Happy Person Raising One Hand Tone2"
+    }, 
+    ":rice-scene:": {
+        "style": "github", 
+        "image": "1f391.png", 
+        "unicode": "🎑", 
+        "name": "Moon Viewing Ceremony"
+    }, 
+    "👧": {
+        "style": "unicode", 
+        "image": "1f467.png", 
+        "name": "Girl"
+    }, 
+    ":ideograph-advantage:": {
+        "style": "github", 
+        "image": "1f250.png", 
+        "unicode": "🉐", 
+        "name": "Circled Ideograph Advantage"
+    }, 
+    ":heartpulse:": {
+        "style": "github", 
+        "image": "1f497.png", 
+        "unicode": "💗", 
+        "name": "Growing Heart"
+    }, 
+    ":wastebasket:": {
+        "style": "github", 
+        "image": "1f5d1.png", 
+        "unicode": "🗑", 
+        "name": "Wastebasket"
+    }, 
+    ":raised_hand_tone4:": {
+        "style": "github", 
+        "image": "270b-1f3fe.png", 
+        "unicode": "✋🏾", 
+        "name": "Raised Hand - Tone 4"
+    }, 
+    "📼": {
+        "style": "unicode", 
+        "image": "1f4fc.png", 
+        "name": "Videocassette"
+    }, 
+    ":person_with_pouting_face_tone4:": {
+        "style": "github", 
+        "image": "1f64e-1f3fe.png", 
+        "unicode": "🙎🏾", 
+        "name": "Person With Pouting Face Tone4"
+    }, 
+    "🚑": {
+        "style": "unicode", 
+        "image": "1f691.png", 
+        "name": "Ambulance"
+    }, 
+    ":surfer_tone4:": {
+        "style": "github", 
+        "image": "1f3c4-1f3fe.png", 
+        "unicode": "🏄🏾", 
+        "name": "Surfer - Tone 4"
+    }, 
+    ":shaking_hands_tone1:": {
+        "style": "github", 
+        "image": "1f91d-1f3fb.png", 
+        "unicode": "🤝🏻", 
+        "name": "Handshake - Tone 1"
+    }, 
+    ":white_medium_small_square:": {
+        "style": "github", 
+        "image": "25fd.png", 
+        "unicode": "◽", 
+        "name": "White Medium Small Square"
+    }, 
+    ":cherry_blossom:": {
+        "style": "github", 
+        "image": "1f338.png", 
+        "unicode": "🌸", 
+        "name": "Cherry Blossom"
+    }, 
+    ":flag_au:": {
+        "style": "github", 
+        "image": "1f1e6-1f1fa.png", 
+        "unicode": "🇦🇺", 
+        "name": "Australia"
+    }, 
+    ":mrs-claus:": {
+        "style": "github", 
+        "image": "1f936.png", 
+        "unicode": "🤶", 
+        "name": "Mother Christmas"
+    }, 
+    ":prince_tone1:": {
+        "style": "github", 
+        "image": "1f934-1f3fb.png", 
+        "unicode": "🤴🏻", 
+        "name": "Prince - Tone 1"
+    }, 
+    "😦": {
+        "style": "unicode", 
+        "image": "1f626.png", 
+        "name": "Frowning Face With Open Mouth"
+    }, 
+    ":flag_de:": {
+        "style": "github", 
+        "image": "1f1e9-1f1ea.png", 
+        "unicode": "🇩🇪", 
+        "name": "Germany"
+    }, 
+    "⚱": {
+        "style": "unicode", 
+        "image": "26b1.png", 
+        "name": "Funeral Urn"
+    }, 
+    ":aries:": {
+        "style": "github", 
+        "image": "2648.png", 
+        "unicode": "♈", 
+        "name": "Aries"
+    }, 
+    ":vc:": {
+        "style": "github", 
+        "image": "1f1fb-1f1e8.png", 
+        "unicode": "🇻🇨", 
+        "name": "Saint Vincent And The Grenadines"
+    }, 
+    ":flag-sy:": {
+        "style": "github", 
+        "image": "1f1f8-1f1fe.png", 
+        "unicode": "🇸🇾", 
+        "name": "Syria"
+    }, 
+    ":crying-cat-face:": {
+        "style": "github", 
+        "image": "1f63f.png", 
+        "unicode": "😿", 
+        "name": "Crying Cat Face"
+    }, 
+    ":snake:": {
+        "style": "github", 
+        "image": "1f40d.png", 
+        "unicode": "🐍", 
+        "name": "Snake"
+    }, 
+    ":thermometer:": {
+        "style": "github", 
+        "image": "1f321.png", 
+        "unicode": "🌡", 
+        "name": "Thermometer"
+    }, 
+    ":mens:": {
+        "style": "github", 
+        "image": "1f6b9.png", 
+        "unicode": "🚹", 
+        "name": "Mens Symbol"
+    }, 
+    ":sneezing-face:": {
+        "style": "github", 
+        "image": "1f927.png", 
+        "unicode": "🤧", 
+        "name": "Sneezing Face"
+    }, 
+    ":timer:": {
+        "style": "github", 
+        "image": "23f2.png", 
+        "unicode": "⏲", 
+        "name": "Timer Clock"
+    }, 
+    ":bow_tone5:": {
+        "style": "github", 
+        "image": "1f647-1f3ff.png", 
+        "unicode": "🙇🏿", 
+        "name": "Person Bowing Deeply - Tone 5"
+    }, 
+    ":zero:": {
+        "style": "github", 
+        "image": "0030-20e3.png", 
+        "unicode": "0⃣", 
+        "name": "Keycap Digit Zero"
+    }, 
+    "🏃🏿": {
+        "style": "unicode", 
+        "image": "1f3c3-1f3ff.png", 
+        "name": "Runner - Tone 5"
+    }, 
+    "🏃🏾": {
+        "style": "unicode", 
+        "image": "1f3c3-1f3fe.png", 
+        "name": "Runner - Tone 4"
+    }, 
+    "🏃🏽": {
+        "style": "unicode", 
+        "image": "1f3c3-1f3fd.png", 
+        "name": "Runner - Tone 3"
+    }, 
+    "🏃🏼": {
+        "style": "unicode", 
+        "image": "1f3c3-1f3fc.png", 
+        "name": "Runner - Tone 2"
+    }, 
+    ":archery:": {
+        "style": "github", 
+        "image": "1f3f9.png", 
+        "unicode": "🏹", 
+        "name": "Bow And Arrow"
+    }, 
+    ":ballot_box_with_ballot:": {
+        "style": "github", 
+        "image": "1f5f3.png", 
+        "unicode": "🗳", 
+        "name": "Ballot Box With Ballot"
+    }, 
+    ":dagger:": {
+        "style": "github", 
+        "image": "1f5e1.png", 
+        "unicode": "🗡", 
+        "name": "Dagger Knife"
+    }, 
+    "🌓": {
+        "style": "unicode", 
+        "image": "1f313.png", 
+        "name": "First Quarter Moon Symbol"
+    }, 
+    ":frame_photo:": {
+        "style": "github", 
+        "image": "1f5bc.png", 
+        "unicode": "🖼", 
+        "name": "Frame With Picture"
+    }, 
+    ":flag-cx:": {
+        "style": "github", 
+        "image": "1f1e8-1f1fd.png", 
+        "unicode": "🇨🇽", 
+        "name": "Christmas Island"
+    }, 
+    ":person_with_blond_hair_tone2:": {
+        "style": "github", 
+        "image": "1f471-1f3fc.png", 
+        "unicode": "👱🏼", 
+        "name": "Person With Blond Hair - Tone 2"
+    }, 
+    ":walking_tone3:": {
+        "style": "github", 
+        "image": "1f6b6-1f3fd.png", 
+        "unicode": "🚶🏽", 
+        "name": "Pedestrian - Tone 3"
+    }, 
+    ":telephone:": {
+        "style": "github", 
+        "image": "260e.png", 
+        "unicode": "☎", 
+        "name": "Black Telephone"
+    }, 
+    "🎨": {
+        "style": "unicode", 
+        "image": "1f3a8.png", 
+        "name": "Artist Palette"
+    }, 
+    ":aq:": {
+        "style": "github", 
+        "image": "1f1e6-1f1f6.png", 
+        "unicode": "🇦🇶", 
+        "name": "Antarctica"
+    }, 
+    ":dizzy_face:": {
+        "style": "github", 
+        "ascii": "#-)", 
+        "image": "1f635.png", 
+        "unicode": "😵", 
+        "name": "Dizzy Face"
+    }, 
+    ":pig_nose:": {
+        "style": "github", 
+        "image": "1f43d.png", 
+        "unicode": "🐽", 
+        "name": "Pig Nose"
+    }, 
+    ":waxing-crescent-moon:": {
+        "style": "github", 
+        "image": "1f312.png", 
+        "unicode": "🌒", 
+        "name": "Waxing Crescent Moon Symbol"
+    }, 
+    "🐽": {
+        "style": "unicode", 
+        "image": "1f43d.png", 
+        "name": "Pig Nose"
+    }, 
+    ":flag-ar:": {
+        "style": "github", 
+        "image": "1f1e6-1f1f7.png", 
+        "unicode": "🇦🇷", 
+        "name": "Argentina"
+    }, 
+    ":man_with_gua_pi_mao_tone5:": {
+        "style": "github", 
+        "image": "1f472-1f3ff.png", 
+        "unicode": "👲🏿", 
+        "name": "Man With Gua Pi Mao - Tone 5"
+    }, 
+    ":dancers:": {
+        "style": "github", 
+        "image": "1f46f.png", 
+        "unicode": "👯", 
+        "name": "Woman With Bunny Ears"
+    }, 
+    ":upside_down_face:": {
+        "style": "github", 
+        "image": "1f643.png", 
+        "unicode": "🙃", 
+        "name": "Upside-down Face"
+    }, 
+    "📒": {
+        "style": "unicode", 
+        "image": "1f4d2.png", 
+        "name": "Ledger"
+    }, 
+    ":flag_bo:": {
+        "style": "github", 
+        "image": "1f1e7-1f1f4.png", 
+        "unicode": "🇧🇴", 
+        "name": "Bolivia"
+    }, 
+    ":ballot_box:": {
+        "style": "github", 
+        "image": "1f5f3.png", 
+        "unicode": "🗳", 
+        "name": "Ballot Box With Ballot"
+    }, 
+    ":moneybag:": {
+        "style": "github", 
+        "image": "1f4b0.png", 
+        "unicode": "💰", 
+        "name": "Money Bag"
+    }, 
+    ":prince-tone1:": {
+        "style": "github", 
+        "image": "1f934-1f3fb.png", 
+        "unicode": "🤴🏻", 
+        "name": "Prince - Tone 1"
+    }, 
+    ":alarm_clock:": {
+        "style": "github", 
+        "image": "23f0.png", 
+        "unicode": "⏰", 
+        "name": "Alarm Clock"
+    }, 
+    "🕧": {
+        "style": "unicode", 
+        "image": "1f567.png", 
+        "name": "Clock Face Twelve-thirty"
+    }, 
+    ":footprints:": {
+        "style": "github", 
+        "image": "1f463.png", 
+        "unicode": "👣", 
+        "name": "Footprints"
+    }, 
+    "\\O/": {
+        "style": "ascii", 
+        "ascii": "*\\0/*", 
+        "image": "1f646.png", 
+        "unicode": "🙆", 
+        "name": "Face With Ok Gesture"
+    }, 
+    ":feet:": {
+        "style": "github", 
+        "image": "1f43e.png", 
+        "unicode": "🐾", 
+        "name": "Paw Prints"
+    }, 
+    ":runner_tone4:": {
+        "style": "github", 
+        "image": "1f3c3-1f3fe.png", 
+        "unicode": "🏃🏾", 
+        "name": "Runner - Tone 4"
+    }, 
+    "🗼": {
+        "style": "unicode", 
+        "image": "1f5fc.png", 
+        "name": "Tokyo Tower"
+    }, 
+    ":bullettrain-front:": {
+        "style": "github", 
+        "image": "1f685.png", 
+        "unicode": "🚅", 
+        "name": "High-speed Train With Bullet Nose"
+    }, 
+    ":point_left_tone1:": {
+        "style": "github", 
+        "image": "1f448-1f3fb.png", 
+        "unicode": "👈🏻", 
+        "name": "White Left Pointing Backhand Index - Tone 1"
+    }, 
+    ":white_sun_behind_cloud_with_rain:": {
+        "style": "github", 
+        "image": "1f326.png", 
+        "unicode": "🌦", 
+        "name": "White Sun Behind Cloud With Rain"
+    }, 
+    ":arrow_backward:": {
+        "style": "github", 
+        "image": "25c0.png", 
+        "unicode": "◀", 
+        "name": "Black Left-pointing Triangle"
+    }, 
+    ":right_facing_fist_tone2:": {
+        "style": "github", 
+        "image": "1f91c-1f3fc.png", 
+        "unicode": "🤜🏼", 
+        "name": "Right Facing Fist - Tone 2"
+    }, 
+    ":sign_of_the_horns_tone4:": {
+        "style": "github", 
+        "image": "1f918-1f3fe.png", 
+        "unicode": "🤘🏾", 
+        "name": "Sign Of The Horns - Tone 4"
+    }, 
+    ":regional-indicator-i:": {
+        "style": "github", 
+        "image": "1f1ee.png", 
+        "unicode": "🇮", 
+        "name": "Regional Indicator Symbol Letter I"
+    }, 
+    ":ear:": {
+        "style": "github", 
+        "image": "1f442.png", 
+        "unicode": "👂", 
+        "name": "Ear"
+    }, 
+    "🚯": {
+        "style": "unicode", 
+        "image": "1f6af.png", 
+        "name": "Do Not Litter Symbol"
+    }, 
+    ":cowboy:": {
+        "style": "github", 
+        "image": "1f920.png", 
+        "unicode": "🤠", 
+        "name": "Face With Cowboy Hat"
+    }, 
+    ":purple-heart:": {
+        "style": "github", 
+        "image": "1f49c.png", 
+        "unicode": "💜", 
+        "name": "Purple Heart"
+    }, 
+    ":thumbsup_tone2:": {
+        "style": "github", 
+        "image": "1f44d-1f3fc.png", 
+        "unicode": "👍🏼", 
+        "name": "Thumbs Up Sign - Tone 2"
+    }, 
+    ":monkey-face:": {
+        "style": "github", 
+        "image": "1f435.png", 
+        "unicode": "🐵", 
+        "name": "Monkey Face"
+    }, 
+    "🙄": {
+        "style": "unicode", 
+        "image": "1f644.png", 
+        "name": "Face With Rolling Eyes"
+    }, 
+    ":night_with_stars:": {
+        "style": "github", 
+        "image": "1f303.png", 
+        "unicode": "🌃", 
+        "name": "Night With Stars"
+    }, 
+    ":ok-hand-tone3:": {
+        "style": "github", 
+        "image": "1f44c-1f3fd.png", 
+        "unicode": "👌🏽", 
+        "name": "Ok Hand Sign - Tone 3"
+    }, 
+    ":jack_o_lantern:": {
+        "style": "github", 
+        "image": "1f383.png", 
+        "unicode": "🎃", 
+        "name": "Jack-o-lantern"
+    }, 
+    ":cheese_wedge:": {
+        "style": "github", 
+        "image": "1f9c0.png", 
+        "unicode": "🧀", 
+        "name": "Cheese Wedge"
+    }, 
+    ":unlock:": {
+        "style": "github", 
+        "image": "1f513.png", 
+        "unicode": "🔓", 
+        "name": "Open Lock"
+    }, 
+    ":juggler:": {
+        "style": "github", 
+        "image": "1f939.png", 
+        "unicode": "🤹", 
+        "name": "Juggling"
+    }, 
+    ":large-blue-diamond:": {
+        "style": "github", 
+        "image": "1f537.png", 
+        "unicode": "🔷", 
+        "name": "Large Blue Diamond"
+    }, 
+    "🐃": {
+        "style": "unicode", 
+        "image": "1f403.png", 
+        "name": "Water Buffalo"
+    }, 
+    ":boy-tone4:": {
+        "style": "github", 
+        "image": "1f466-1f3fe.png", 
+        "unicode": "👦🏾", 
+        "name": "Boy - Tone 4"
+    }, 
+    ":mm:": {
+        "style": "github", 
+        "image": "1f1f2-1f1f2.png", 
+        "unicode": "🇲🇲", 
+        "name": "Myanmar"
+    }, 
+    "💘": {
+        "style": "unicode", 
+        "image": "1f498.png", 
+        "name": "Heart With Arrow"
+    }, 
+    ":clock5:": {
+        "style": "github", 
+        "image": "1f554.png", 
+        "unicode": "🕔", 
+        "name": "Clock Face Five Oclock"
+    }, 
+    ":face_with_cowboy_hat:": {
+        "style": "github", 
+        "image": "1f920.png", 
+        "unicode": "🤠", 
+        "name": "Face With Cowboy Hat"
+    }, 
+    ":lion:": {
+        "style": "github", 
+        "image": "1f981.png", 
+        "unicode": "🦁", 
+        "name": "Lion Face"
+    }, 
+    ":basketball_player_tone5:": {
+        "style": "github", 
+        "image": "26f9-1f3ff.png", 
+        "unicode": "⛹🏿", 
+        "name": "Person With Ball - Tone 5"
+    }, 
+    ":running-shirt-with-sash:": {
+        "style": "github", 
+        "image": "1f3bd.png", 
+        "unicode": "🎽", 
+        "name": "Running Shirt With Sash"
+    }, 
+    "🌭": {
+        "style": "unicode", 
+        "image": "1f32d.png", 
+        "name": "Hot Dog"
+    }, 
+    ":arrow-upper-right:": {
+        "style": "github", 
+        "image": "2197.png", 
+        "unicode": "↗", 
+        "name": "North East Arrow"
+    }, 
+    "🏂": {
+        "style": "unicode", 
+        "image": "1f3c2.png", 
+        "name": "Snowboarder"
+    }, 
+    ":roller_coaster:": {
+        "style": "github", 
+        "image": "1f3a2.png", 
+        "unicode": "🎢", 
+        "name": "Roller Coaster"
+    }, 
+    ":flag_white:": {
+        "style": "github", 
+        "image": "1f3f3.png", 
+        "unicode": "🏳", 
+        "name": "Waving White Flag"
+    }, 
+    ":swimmer:": {
+        "style": "github", 
+        "image": "1f3ca.png", 
+        "unicode": "🏊", 
+        "name": "Swimmer"
+    }, 
+    ":call_me_tone2:": {
+        "style": "github", 
+        "image": "1f919-1f3fc.png", 
+        "unicode": "🤙🏼", 
+        "name": "Call Me Hand - Tone 2"
+    }, 
+    ":flag_cp:": {
+        "style": "github", 
+        "image": "1f1e8-1f1f5.png", 
+        "unicode": "🇨🇵", 
+        "name": "Clipperton Island"
+    }, 
+    ":tz:": {
+        "style": "github", 
+        "image": "1f1f9-1f1ff.png", 
+        "unicode": "🇹🇿", 
+        "name": "Tanzania"
+    }, 
+    ":upside-down:": {
+        "style": "github", 
+        "image": "1f643.png", 
+        "unicode": "🙃", 
+        "name": "Upside-down Face"
+    }, 
+    ":arrow-left:": {
+        "style": "github", 
+        "image": "2b05.png", 
+        "unicode": "⬅", 
+        "name": "Leftwards Black Arrow"
+    }, 
+    "🚅": {
+        "style": "unicode", 
+        "image": "1f685.png", 
+        "name": "High-speed Train With Bullet Nose"
+    }, 
+    ":je:": {
+        "style": "github", 
+        "image": "1f1ef-1f1ea.png", 
+        "unicode": "🇯🇪", 
+        "name": "Jersey"
+    }, 
+    ":sparkle:": {
+        "style": "github", 
+        "image": "2747.png", 
+        "unicode": "❇", 
+        "name": "Sparkle"
+    }, 
+    ":flag-io:": {
+        "style": "github", 
+        "image": "1f1ee-1f1f4.png", 
+        "unicode": "🇮🇴", 
+        "name": "British Indian Ocean Territory"
+    }, 
+    ":kiwi:": {
+        "style": "github", 
+        "image": "1f95d.png", 
+        "unicode": "🥝", 
+        "name": "Kiwifruit"
+    }, 
+    ":clap-tone1:": {
+        "style": "github", 
+        "image": "1f44f-1f3fb.png", 
+        "unicode": "👏🏻", 
+        "name": "Clapping Hands Sign - Tone 1"
+    }, 
+    "😚": {
+        "style": "unicode", 
+        "image": "1f61a.png", 
+        "name": "Kissing Face With Closed Eyes"
+    }, 
+    ":dancer_tone5:": {
+        "style": "github", 
+        "image": "1f483-1f3ff.png", 
+        "unicode": "💃🏿", 
+        "name": "Dancer - Tone 5"
+    }, 
+    ":lifter_tone4:": {
+        "style": "github", 
+        "image": "1f3cb-1f3fe.png", 
+        "unicode": "🏋🏾", 
+        "name": "Weight Lifter - Tone 4"
+    }, 
+    "👮🏻": {
+        "style": "unicode", 
+        "image": "1f46e-1f3fb.png", 
+        "name": "Police Officer - Tone 1"
+    }, 
+    ":flag_mw:": {
+        "style": "github", 
+        "image": "1f1f2-1f1fc.png", 
+        "unicode": "🇲🇼", 
+        "name": "Malawi"
+    }, 
+    ":police_car:": {
+        "style": "github", 
+        "image": "1f693.png", 
+        "unicode": "🚓", 
+        "name": "Police Car"
+    }, 
+    ":credit-card:": {
+        "style": "github", 
+        "image": "1f4b3.png", 
+        "unicode": "💳", 
+        "name": "Credit Card"
+    }, 
+    ":bath_tone2:": {
+        "style": "github", 
+        "image": "1f6c0-1f3fc.png", 
+        "unicode": "🛀🏼", 
+        "name": "Bath - Tone 2"
+    }, 
+    ":flag_br:": {
+        "style": "github", 
+        "image": "1f1e7-1f1f7.png", 
+        "unicode": "🇧🇷", 
+        "name": "Brazil"
+    }, 
+    "📙": {
+        "style": "unicode", 
+        "image": "1f4d9.png", 
+        "name": "Orange Book"
+    }, 
+    ":rolling-eyes:": {
+        "style": "github", 
+        "image": "1f644.png", 
+        "unicode": "🙄", 
+        "name": "Face With Rolling Eyes"
+    }, 
+    "👮": {
+        "style": "unicode", 
+        "image": "1f46e.png", 
+        "name": "Police Officer"
+    }, 
+    ":ski:": {
+        "style": "github", 
+        "image": "1f3bf.png", 
+        "unicode": "🎿", 
+        "name": "Ski And Ski Boot"
+    }, 
+    ":metal:": {
+        "style": "github", 
+        "image": "1f918.png", 
+        "unicode": "🤘", 
+        "name": "Sign Of The Horns"
+    }, 
+    "🔃": {
+        "style": "unicode", 
+        "image": "1f503.png", 
+        "name": "Clockwise Downwards And Upwards Open Circle Arrows"
+    }, 
+    ":gf:": {
+        "style": "github", 
+        "image": "1f1ec-1f1eb.png", 
+        "unicode": "🇬🇫", 
+        "name": "French Guiana"
+    }, 
+    ":sr:": {
+        "style": "github", 
+        "image": "1f1f8-1f1f7.png", 
+        "unicode": "🇸🇷", 
+        "name": "Suriname"
+    }, 
+    ":ok_hand_tone4:": {
+        "style": "github", 
+        "image": "1f44c-1f3fe.png", 
+        "unicode": "👌🏾", 
+        "name": "Ok Hand Sign - Tone 4"
+    }, 
+    ":canoe:": {
+        "style": "github", 
+        "image": "1f6f6.png", 
+        "unicode": "🛶", 
+        "name": "Canoe"
+    }, 
+    ":older_woman_tone1:": {
+        "style": "github", 
+        "image": "1f475-1f3fb.png", 
+        "unicode": "👵🏻", 
+        "name": "Older Woman - Tone 1"
+    }, 
+    ":black-nib:": {
+        "style": "github", 
+        "image": "2712.png", 
+        "unicode": "✒", 
+        "name": "Black Nib"
+    }, 
+    ":clock830:": {
+        "style": "github", 
+        "image": "1f563.png", 
+        "unicode": "🕣", 
+        "name": "Clock Face Eight-thirty"
+    }, 
+    ":hourglass_flowing_sand:": {
+        "style": "github", 
+        "image": "23f3.png", 
+        "unicode": "⏳", 
+        "name": "Hourglass With Flowing Sand"
+    }, 
+    ":flag-sj:": {
+        "style": "github", 
+        "image": "1f1f8-1f1ef.png", 
+        "unicode": "🇸🇯", 
+        "name": "Svalbard And Jan Mayen"
+    }, 
+    ":bath-tone5:": {
+        "style": "github", 
+        "image": "1f6c0-1f3ff.png", 
+        "unicode": "🛀🏿", 
+        "name": "Bath - Tone 5"
+    }, 
+    "🍗": {
+        "style": "unicode", 
+        "image": "1f357.png", 
+        "name": "Poultry Leg"
+    }, 
+    "🥛": {
+        "style": "unicode", 
+        "image": "1f95b.png", 
+        "name": "Glass Of Milk"
+    }, 
+    "♥": {
+        "style": "unicode", 
+        "image": "2665.png", 
+        "name": "Black Heart Suit"
+    }, 
+    "🏬": {
+        "style": "unicode", 
+        "image": "1f3ec.png", 
+        "name": "Department Store"
+    }, 
+    "⛺": {
+        "style": "unicode", 
+        "image": "26fa.png", 
+        "name": "Tent"
+    }, 
+    "🎁": {
+        "style": "unicode", 
+        "image": "1f381.png", 
+        "name": "Wrapped Present"
+    }, 
+    ":cr:": {
+        "style": "github", 
+        "image": "1f1e8-1f1f7.png", 
+        "unicode": "🇨🇷", 
+        "name": "Costa Rica"
+    }, 
+    ":mountain_bicyclist_tone5:": {
+        "style": "github", 
+        "image": "1f6b5-1f3ff.png", 
+        "unicode": "🚵🏿", 
+        "name": "Mountain Bicyclist - Tone 5"
+    }, 
+    ":worship_symbol:": {
+        "style": "github", 
+        "image": "1f6d0.png", 
+        "unicode": "🛐", 
+        "name": "Place Of Worship"
+    }, 
+    ":poultry-leg:": {
+        "style": "github", 
+        "image": "1f357.png", 
+        "unicode": "🍗", 
+        "name": "Poultry Leg"
+    }, 
+    "🌖": {
+        "style": "unicode", 
+        "image": "1f316.png", 
+        "name": "Waning Gibbous Moon Symbol"
+    }, 
+    "🔚": {
+        "style": "unicode", 
+        "image": "1f51a.png", 
+        "name": "End With Leftwards Arrow Above"
+    }, 
+    ":no-good-tone1:": {
+        "style": "github", 
+        "image": "1f645-1f3fb.png", 
+        "unicode": "🙅🏻", 
+        "name": "Face With No Good Gesture - Tone 1"
+    }, 
+    ":flag-ga:": {
+        "style": "github", 
+        "image": "1f1ec-1f1e6.png", 
+        "unicode": "🇬🇦", 
+        "name": "Gabon"
+    }, 
+    ":point-right-tone2:": {
+        "style": "github", 
+        "image": "1f449-1f3fc.png", 
+        "unicode": "👉🏼", 
+        "name": "White Right Pointing Backhand Index - Tone 2"
+    }, 
+    ":male_dancer_tone2:": {
+        "style": "github", 
+        "image": "1f57a-1f3fc.png", 
+        "unicode": "🕺🏼", 
+        "name": "Man Dancing - Tone 2"
+    }, 
+    "💯": {
+        "style": "unicode", 
+        "image": "1f4af.png", 
+        "name": "Hundred Points Symbol"
+    }, 
+    ":right_fist:": {
+        "style": "github", 
+        "image": "1f91c.png", 
+        "unicode": "🤜", 
+        "name": "Right-facing Fist"
+    }, 
+    ":flag-mk:": {
+        "style": "github", 
+        "image": "1f1f2-1f1f0.png", 
+        "unicode": "🇲🇰", 
+        "name": "Macedonia"
+    }, 
+    ":oncoming-taxi:": {
+        "style": "github", 
+        "image": "1f696.png", 
+        "unicode": "🚖", 
+        "name": "Oncoming Taxi"
+    }, 
+    ":anguished:": {
+        "style": "github", 
+        "image": "1f627.png", 
+        "unicode": "😧", 
+        "name": "Anguished Face"
+    }, 
+    ":zm:": {
+        "style": "github", 
+        "image": "1f1ff-1f1f2.png", 
+        "unicode": "🇿🇲", 
+        "name": "Zambia"
+    }, 
+    "👄": {
+        "style": "unicode", 
+        "image": "1f444.png", 
+        "name": "Mouth"
+    }, 
+    ":crown:": {
+        "style": "github", 
+        "image": "1f451.png", 
+        "unicode": "👑", 
+        "name": "Crown"
+    }, 
+    "❎": {
+        "style": "unicode", 
+        "image": "274e.png", 
+        "name": "Negative Squared Cross Mark"
+    }, 
+    ":clock730:": {
+        "style": "github", 
+        "image": "1f562.png", 
+        "unicode": "🕢", 
+        "name": "Clock Face Seven-thirty"
+    }, 
+    ":second_place_medal:": {
+        "style": "github", 
+        "image": "1f948.png", 
+        "unicode": "🥈", 
+        "name": "Second Place Medal"
+    }, 
+    ":raising_hand_tone5:": {
+        "style": "github", 
+        "image": "1f64b-1f3ff.png", 
+        "unicode": "🙋🏿", 
+        "name": "Happy Person Raising One Hand Tone5"
+    }, 
+    ":flag-nu:": {
+        "style": "github", 
+        "image": "1f1f3-1f1fa.png", 
+        "unicode": "🇳🇺", 
+        "name": "Niue"
+    }, 
+    ":statue_of_liberty:": {
+        "style": "github", 
+        "image": "1f5fd.png", 
+        "unicode": "🗽", 
+        "name": "Statue Of Liberty"
+    }, 
+    "😃": {
+        "style": "unicode", 
+        "ascii": ":D", 
+        "image": "1f603.png", 
+        "name": "Smiling Face With Open Mouth"
+    }, 
+    ":juggler_tone1:": {
+        "style": "github", 
+        "image": "1f939-1f3fb.png", 
+        "unicode": "🤹🏻", 
+        "name": "Juggling - Tone 1"
+    }, 
+    ":shaking_hands_tone5:": {
+        "style": "github", 
+        "image": "1f91d-1f3ff.png", 
+        "unicode": "🤝🏿", 
+        "name": "Handshake - Tone 5"
+    }, 
+    "🚘": {
+        "style": "unicode", 
+        "image": "1f698.png", 
+        "name": "Oncoming Automobile"
+    }, 
+    ":japan:": {
+        "style": "github", 
+        "image": "1f5fe.png", 
+        "unicode": "🗾", 
+        "name": "Silhouette Of Japan"
+    }, 
+    ":haircut-tone2:": {
+        "style": "github", 
+        "image": "1f487-1f3fc.png", 
+        "unicode": "💇🏼", 
+        "name": "Haircut - Tone 2"
+    }, 
+    ":flag-ro:": {
+        "style": "github", 
+        "image": "1f1f7-1f1f4.png", 
+        "unicode": "🇷🇴", 
+        "name": "Romania"
+    }, 
+    ":al:": {
+        "style": "github", 
+        "image": "1f1e6-1f1f1.png", 
+        "unicode": "🇦🇱", 
+        "name": "Albania"
+    }, 
+    ":flushed:": {
+        "style": "github", 
+        "ascii": ":$", 
+        "image": "1f633.png", 
+        "unicode": "😳", 
+        "name": "Flushed Face"
+    }, 
+    ":ps:": {
+        "style": "github", 
+        "image": "1f1f5-1f1f8.png", 
+        "unicode": "🇵🇸", 
+        "name": "Palestinian Authority"
+    }, 
+    ":mother_christmas_tone4:": {
+        "style": "github", 
+        "image": "1f936-1f3fe.png", 
+        "unicode": "🤶🏾", 
+        "name": "Mother Christmas - Tone 4"
+    }, 
+    ":mrs_claus_tone1:": {
+        "style": "github", 
+        "image": "1f936-1f3fb.png", 
+        "unicode": "🤶🏻", 
+        "name": "Mother Christmas - Tone 1"
+    }, 
+    "👑": {
+        "style": "unicode", 
+        "image": "1f451.png", 
+        "name": "Crown"
+    }, 
+    ":couplekiss_ww:": {
+        "style": "github", 
+        "image": "1f469-2764-1f48b-1f469.png", 
+        "unicode": "👩❤💋👩", 
+        "name": "Kiss (woman,woman)"
+    }, 
+    ":clock630:": {
+        "style": "github", 
+        "image": "1f561.png", 
+        "unicode": "🕡", 
+        "name": "Clock Face Six-thirty"
+    }, 
+    ":fish_cake:": {
+        "style": "github", 
+        "image": "1f365.png", 
+        "unicode": "🍥", 
+        "name": "Fish Cake With Swirl Design"
+    }, 
+    ":bicyclist-tone1:": {
+        "style": "github", 
+        "image": "1f6b4-1f3fb.png", 
+        "unicode": "🚴🏻", 
+        "name": "Bicyclist - Tone 1"
+    }, 
+    "💅": {
+        "style": "unicode", 
+        "image": "1f485.png", 
+        "name": "Nail Polish"
+    }, 
+    ":mrs-claus-tone4:": {
+        "style": "github", 
+        "image": "1f936-1f3fe.png", 
+        "unicode": "🤶🏾", 
+        "name": "Mother Christmas - Tone 4"
+    }, 
+    "🤐": {
+        "style": "unicode", 
+        "image": "1f910.png", 
+        "name": "Zipper-mouth Face"
+    }, 
+    ":person_with_ball_tone3:": {
+        "style": "github", 
+        "image": "26f9-1f3fd.png", 
+        "unicode": "⛹🏽", 
+        "name": "Person With Ball - Tone 3"
+    }, 
+    ":confused:": {
+        "style": "github", 
+        "ascii": ">:\\", 
+        "image": "1f615.png", 
+        "unicode": "😕", 
+        "name": "Confused Face"
+    }, 
+    "🐚": {
+        "style": "unicode", 
+        "image": "1f41a.png", 
+        "name": "Spiral Shell"
+    }, 
+    "🎫": {
+        "style": "unicode", 
+        "image": "1f3ab.png", 
+        "name": "Ticket"
+    }, 
+    ":point_up_2_tone3:": {
+        "style": "github", 
+        "image": "1f446-1f3fd.png", 
+        "unicode": "👆🏽", 
+        "name": "White Up Pointing Backhand Index - Tone 3"
+    }, 
+    ":speak_no_evil:": {
+        "style": "github", 
+        "image": "1f64a.png", 
+        "unicode": "🙊", 
+        "name": "Speak-no-evil Monkey"
+    }, 
+    ":nose-tone5:": {
+        "style": "github", 
+        "image": "1f443-1f3ff.png", 
+        "unicode": "👃🏿", 
+        "name": "Nose - Tone 5"
+    }, 
+    ":fish-cake:": {
+        "style": "github", 
+        "image": "1f365.png", 
+        "unicode": "🍥", 
+        "name": "Fish Cake With Swirl Design"
+    }, 
+    ":flag-za:": {
+        "style": "github", 
+        "image": "1f1ff-1f1e6.png", 
+        "unicode": "🇿🇦", 
+        "name": "South Africa"
+    }, 
+    ":right_facing_fist:": {
+        "style": "github", 
+        "image": "1f91c.png", 
+        "unicode": "🤜", 
+        "name": "Right-facing Fist"
+    }, 
+    ":capital-abcd:": {
+        "style": "github", 
+        "image": "1f520.png", 
+        "unicode": "🔠", 
+        "name": "Input Symbol For Latin Capital Letters"
+    }, 
+    "♎": {
+        "style": "unicode", 
+        "image": "264e.png", 
+        "name": "Libra"
+    }, 
+    ":raised_hand_with_fingers_splayed_tone3:": {
+        "style": "github", 
+        "image": "1f590-1f3fd.png", 
+        "unicode": "🖐🏽", 
+        "name": "Raised Hand With Fingers Splayed - Tone 3"
+    }, 
+    ":regional_indicator_j:": {
+        "style": "github", 
+        "image": "1f1ef.png", 
+        "unicode": "🇯", 
+        "name": "Regional Indicator Symbol Letter J"
+    }, 
+    ":raised_hand_with_part_between_middle_and_ring_fingers_tone2:": {
+        "style": "github", 
+        "image": "1f596-1f3fc.png", 
+        "unicode": "🖖🏼", 
+        "name": "Raised Hand With Part Between Middle And Ring Fingers - Tone 2"
+    }, 
+    ":raised_hand_tone2:": {
+        "style": "github", 
+        "image": "270b-1f3fc.png", 
+        "unicode": "✋🏼", 
+        "name": "Raised Hand - Tone 2"
+    }, 
+    ":prince_tone3:": {
+        "style": "github", 
+        "image": "1f934-1f3fd.png", 
+        "unicode": "🤴🏽", 
+        "name": "Prince - Tone 3"
+    }, 
+    ":flag_aw:": {
+        "style": "github", 
+        "image": "1f1e6-1f1fc.png", 
+        "unicode": "🇦🇼", 
+        "name": "Aruba"
+    }, 
+    ":football:": {
+        "style": "github", 
+        "image": "1f3c8.png", 
+        "unicode": "🏈", 
+        "name": "American Football"
+    }, 
+    ":film_projector:": {
+        "style": "github", 
+        "image": "1f4fd.png", 
+        "unicode": "📽", 
+        "name": "Film Projector"
+    }, 
+    ":ve:": {
+        "style": "github", 
+        "image": "1f1fb-1f1ea.png", 
+        "unicode": "🇻🇪", 
+        "name": "Venezuela"
+    }, 
+    ":camera_with_flash:": {
+        "style": "github", 
+        "image": "1f4f8.png", 
+        "unicode": "📸", 
+        "name": "Camera With Flash"
+    }, 
+    ":bicyclist_tone5:": {
+        "style": "github", 
+        "image": "1f6b4-1f3ff.png", 
+        "unicode": "🚴🏿", 
+        "name": "Bicyclist - Tone 5"
+    }, 
+    ":flag-kz:": {
+        "style": "github", 
+        "image": "1f1f0-1f1ff.png", 
+        "unicode": "🇰🇿", 
+        "name": "Kazakhstan"
+    }, 
+    ":first_place:": {
+        "style": "github", 
+        "image": "1f947.png", 
+        "unicode": "🥇", 
+        "name": "First Place Medal"
+    }, 
+    ":potable-water:": {
+        "style": "github", 
+        "image": "1f6b0.png", 
+        "unicode": "🚰", 
+        "name": "Potable Water Symbol"
+    }, 
+    ":tuxedo_tone1:": {
+        "style": "github", 
+        "image": "1f935-1f3fb.png", 
+        "unicode": "🤵🏻", 
+        "name": "Man In Tuxedo - Tone 1"
+    }, 
+    ":post-office:": {
+        "style": "github", 
+        "image": "1f3e3.png", 
+        "unicode": "🏣", 
+        "name": "Japanese Post Office"
+    }, 
+    "🇬": {
+        "style": "unicode", 
+        "image": "1f1ec.png", 
+        "name": "Regional Indicator Symbol Letter G"
+    }, 
+    ":flag-cz:": {
+        "style": "github", 
+        "image": "1f1e8-1f1ff.png", 
+        "unicode": "🇨🇿", 
+        "name": "The Czech Republic"
+    }, 
+    ":musical-note:": {
+        "style": "github", 
+        "image": "1f3b5.png", 
+        "unicode": "🎵", 
+        "name": "Musical Note"
+    }, 
+    "🎅": {
+        "style": "unicode", 
+        "image": "1f385.png", 
+        "name": "Father Christmas"
+    }, 
+    "🦉": {
+        "style": "unicode", 
+        "image": "1f989.png", 
+        "name": "Owl"
+    }, 
+    ":field-hockey:": {
+        "style": "github", 
+        "image": "1f3d1.png", 
+        "unicode": "🏑", 
+        "name": "Field Hockey Stick And Ball"
+    }, 
+    ":call_me:": {
+        "style": "github", 
+        "image": "1f919.png", 
+        "unicode": "🤙", 
+        "name": "Call Me Hand"
+    }, 
+    "🔖": {
+        "style": "unicode", 
+        "image": "1f516.png", 
+        "name": "Bookmark"
+    }, 
+    ":hatching-chick:": {
+        "style": "github", 
+        "image": "1f423.png", 
+        "unicode": "🐣", 
+        "name": "Hatching Chick"
+    }, 
+    "🤞": {
+        "style": "unicode", 
+        "image": "1f91e.png", 
+        "name": "Hand With First And Index Finger Crossed"
+    }, 
+    ":as:": {
+        "style": "github", 
+        "image": "1f1e6-1f1f8.png", 
+        "unicode": "🇦🇸", 
+        "name": "American Samoa"
+    }, 
+    ":person_with_blond_hair_tone4:": {
+        "style": "github", 
+        "image": "1f471-1f3fe.png", 
+        "unicode": "👱🏾", 
+        "name": "Person With Blond Hair - Tone 4"
+    }, 
+    "💫": {
+        "style": "unicode", 
+        "image": "1f4ab.png", 
+        "name": "Dizzy Symbol"
+    }, 
+    ":notebook:": {
+        "style": "github", 
+        "image": "1f4d3.png", 
+        "unicode": "📓", 
+        "name": "Notebook"
+    }, 
+    ":shark:": {
+        "style": "github", 
+        "image": "1f988.png", 
+        "unicode": "🦈", 
+        "name": "Shark"
+    }, 
+    "👀": {
+        "style": "unicode", 
+        "image": "1f440.png", 
+        "name": "Eyes"
+    }, 
+    ":punch_tone2:": {
+        "style": "github", 
+        "image": "1f44a-1f3fc.png", 
+        "unicode": "👊🏼", 
+        "name": "Fisted Hand Sign - Tone 2"
+    }, 
+    ":ic:": {
+        "style": "github", 
+        "image": "1f1ee-1f1e8.png", 
+        "unicode": "🇮🇨", 
+        "name": "Canary Islands"
+    }, 
+    ":flag_bi:": {
+        "style": "github", 
+        "image": "1f1e7-1f1ee.png", 
+        "unicode": "🇧🇮", 
+        "name": "Burundi"
+    }, 
+    ":bar_chart:": {
+        "style": "github", 
+        "image": "1f4ca.png", 
+        "unicode": "📊", 
+        "name": "Bar Chart"
+    }, 
+    ":cloud_with_snow:": {
+        "style": "github", 
+        "image": "1f328.png", 
+        "unicode": "🌨", 
+        "name": "Cloud With Snow"
+    }, 
+    "*-)": {
+        "style": "ascii", 
+        "ascii": ";)", 
+        "image": "1f609.png", 
+        "unicode": "😉", 
+        "name": "Winking Face"
+    }, 
+    ":octagonal-sign:": {
+        "style": "github", 
+        "image": "1f6d1.png", 
+        "unicode": "🛑", 
+        "name": "Octagonal Sign"
+    }, 
+    ":fist_tone5:": {
+        "style": "github", 
+        "image": "270a-1f3ff.png", 
+        "unicode": "✊🏿", 
+        "name": "Raised Fist - Tone 5"
+    }, 
+    "✍": {
+        "style": "unicode", 
+        "image": "270d.png", 
+        "name": "Writing Hand"
+    }, 
+    ":point_left_tone3:": {
+        "style": "github", 
+        "image": "1f448-1f3fd.png", 
+        "unicode": "👈🏽", 
+        "name": "White Left Pointing Backhand Index - Tone 3"
+    }, 
+    ":gy:": {
+        "style": "github", 
+        "image": "1f1ec-1f1fe.png", 
+        "unicode": "🇬🇾", 
+        "name": "Guyana"
+    }, 
+    ":regional-indicator-o:": {
+        "style": "github", 
+        "image": "1f1f4.png", 
+        "unicode": "🇴", 
+        "name": "Regional Indicator Symbol Letter O"
+    }, 
+    ":dancer-tone1:": {
+        "style": "github", 
+        "image": "1f483-1f3fb.png", 
+        "unicode": "💃🏻", 
+        "name": "Dancer - Tone 1"
+    }, 
+    ":city_sunrise:": {
+        "style": "github", 
+        "image": "1f307.png", 
+        "unicode": "🌇", 
+        "name": "Sunset Over Buildings"
+    }, 
+    ":thumbsdown_tone4:": {
+        "style": "github", 
+        "image": "1f44e-1f3fe.png", 
+        "unicode": "👎🏾", 
+        "name": "Thumbs Down Sign - Tone 4"
+    }, 
+    ":video_camera:": {
+        "style": "github", 
+        "image": "1f4f9.png", 
+        "unicode": "📹", 
+        "name": "Video Camera"
+    }, 
+    ":christmas_tree:": {
+        "style": "github", 
+        "image": "1f384.png", 
+        "unicode": "🎄", 
+        "name": "Christmas Tree"
+    }, 
+    ":flag_kg:": {
+        "style": "github", 
+        "image": "1f1f0-1f1ec.png", 
+        "unicode": "🇰🇬", 
+        "name": "Kyrgyzstan"
+    }, 
+    ":ocean:": {
+        "style": "github", 
+        "image": "1f30a.png", 
+        "unicode": "🌊", 
+        "name": "Water Wave"
+    }, 
+    ":stuck_out_tongue_closed_eyes:": {
+        "style": "github", 
+        "image": "1f61d.png", 
+        "unicode": "😝", 
+        "name": "Face With Stuck-out Tongue And Tightly-closed Eyes"
+    }, 
+    ":flag_sv:": {
+        "style": "github", 
+        "image": "1f1f8-1f1fb.png", 
+        "unicode": "🇸🇻", 
+        "name": "El Salvador"
+    }, 
+    "💧": {
+        "style": "unicode", 
+        "image": "1f4a7.png", 
+        "name": "Droplet"
+    }, 
+    ":ear-of-rice:": {
+        "style": "github", 
+        "image": "1f33e.png", 
+        "unicode": "🌾", 
+        "name": "Ear Of Rice"
+    }, 
+    "🛬": {
+        "style": "unicode", 
+        "image": "1f6ec.png", 
+        "name": "Airplane Arriving"
+    }, 
+    ":flag-bt:": {
+        "style": "github", 
+        "image": "1f1e7-1f1f9.png", 
+        "unicode": "🇧🇹", 
+        "name": "Bhutan"
+    }, 
+    ":waning_gibbous_moon:": {
+        "style": "github", 
+        "image": "1f316.png", 
+        "unicode": "🌖", 
+        "name": "Waning Gibbous Moon Symbol"
+    }, 
+    ":family-mmbb:": {
+        "style": "github", 
+        "image": "1f468-1f468-1f466-1f466.png", 
+        "unicode": "👨👨👦👦", 
+        "name": "Family (man,man,boy,boy)"
+    }, 
+    "⏺": {
+        "style": "unicode", 
+        "image": "23fa.png", 
+        "name": "Black Circle For Record"
+    }, 
+    "💁": {
+        "style": "unicode", 
+        "image": "1f481.png", 
+        "name": "Information Desk Person"
+    }, 
+    ":eight-spoked-asterisk:": {
+        "style": "github", 
+        "image": "2733.png", 
+        "unicode": "✳", 
+        "name": "Eight Spoked Asterisk"
+    }, 
+    ":mo:": {
+        "style": "github", 
+        "image": "1f1f2-1f1f4.png", 
+        "unicode": "🇲🇴", 
+        "name": "Macau"
+    }, 
+    ":santa_tone3:": {
+        "style": "github", 
+        "image": "1f385-1f3fd.png", 
+        "unicode": "🎅🏽", 
+        "name": "Father Christmas - Tone 3"
+    }, 
+    ":japanese_goblin:": {
+        "style": "github", 
+        "image": "1f47a.png", 
+        "unicode": "👺", 
+        "name": "Japanese Goblin"
+    }, 
+    "🐖": {
+        "style": "unicode", 
+        "image": "1f416.png", 
+        "name": "Pig"
+    }, 
+    "🈚": {
+        "style": "unicode", 
+        "image": "1f21a.png", 
+        "name": "Squared Cjk Unified Ideograph-7121"
+    }, 
+    ":grey_question:": {
+        "style": "github", 
+        "image": "2754.png", 
+        "unicode": "❔", 
+        "name": "White Question Mark Ornament"
+    }, 
+    "🎯": {
+        "style": "unicode", 
+        "image": "1f3af.png", 
+        "name": "Direct Hit"
+    }, 
+    ":bacon:": {
+        "style": "github", 
+        "image": "1f953.png", 
+        "unicode": "🥓", 
+        "name": "Bacon"
+    }, 
+    ":thumbsdown-tone4:": {
+        "style": "github", 
+        "image": "1f44e-1f3fe.png", 
+        "unicode": "👎🏾", 
+        "name": "Thumbs Down Sign - Tone 4"
+    }, 
+    ":ly:": {
+        "style": "github", 
+        "image": "1f1f1-1f1fe.png", 
+        "unicode": "🇱🇾", 
+        "name": "Libya"
+    }, 
+    "🍄": {
+        "style": "unicode", 
+        "image": "1f344.png", 
+        "name": "Mushroom"
+    }, 
+    ":flag_cv:": {
+        "style": "github", 
+        "image": "1f1e8-1f1fb.png", 
+        "unicode": "🇨🇻", 
+        "name": "Cape Verde"
+    }, 
+    "🥈": {
+        "style": "unicode", 
+        "image": "1f948.png", 
+        "name": "Second Place Medal"
+    }, 
+    "👩👩👧": {
+        "style": "unicode", 
+        "image": "1f469-1f469-1f467.png", 
+        "name": "Family (woman,woman,girl)"
+    }, 
+    "👩👩👦": {
+        "style": "unicode", 
+        "image": "1f469-1f469-1f466.png", 
+        "name": "Family (woman,woman,boy)"
+    }, 
+    ":golf:": {
+        "style": "github", 
+        "image": "26f3.png", 
+        "unicode": "⛳", 
+        "name": "Flag In Hole"
+    }, 
+    ":railway_car:": {
+        "style": "github", 
+        "image": "1f683.png", 
+        "unicode": "🚃", 
+        "name": "Railway Car"
+    }, 
+    ":wind_blowing_face:": {
+        "style": "github", 
+        "image": "1f32c.png", 
+        "unicode": "🌬", 
+        "name": "Wind Blowing Face"
+    }, 
+    ":flag_lc:": {
+        "style": "github", 
+        "image": "1f1f1-1f1e8.png", 
+        "unicode": "🇱🇨", 
+        "name": "Saint Lucia"
+    }, 
+    ":^*": {
+        "style": "ascii", 
+        "ascii": ":*", 
+        "image": "1f618.png", 
+        "unicode": "😘", 
+        "name": "Face Throwing A Kiss"
+    }, 
+    ":shelled_peanut:": {
+        "style": "github", 
+        "image": "1f95c.png", 
+        "unicode": "🥜", 
+        "name": "Peanuts"
+    }, 
+    ":non-potable-water:": {
+        "style": "github", 
+        "image": "1f6b1.png", 
+        "unicode": "🚱", 
+        "name": "Non-potable Water Symbol"
+    }, 
+    "<3": {
+        "style": "ascii", 
+        "ascii": "<3", 
+        "image": "2764.png", 
+        "unicode": "❤", 
+        "name": "Heavy Black Heart"
+    }, 
+    "🆘": {
+        "style": "unicode", 
+        "image": "1f198.png", 
+        "name": "Squared Sos"
+    }, 
+    ":swimmer-tone3:": {
+        "style": "github", 
+        "image": "1f3ca-1f3fd.png", 
+        "unicode": "🏊🏽", 
+        "name": "Swimmer - Tone 3"
+    }, 
+    "😭": {
+        "style": "unicode", 
+        "image": "1f62d.png", 
+        "name": "Loudly Crying Face"
+    }, 
+    ":guardsman-tone3:": {
+        "style": "github", 
+        "image": "1f482-1f3fd.png", 
+        "unicode": "💂🏽", 
+        "name": "Guardsman - Tone 3"
+    }, 
+    ":flag_my:": {
+        "style": "github", 
+        "image": "1f1f2-1f1fe.png", 
+        "unicode": "🇲🇾", 
+        "name": "Malaysia"
+    }, 
+    ":closed_umbrella:": {
+        "style": "github", 
+        "image": "1f302.png", 
+        "unicode": "🌂", 
+        "name": "Closed Umbrella"
+    }, 
+    "🛂": {
+        "style": "unicode", 
+        "image": "1f6c2.png", 
+        "name": "Passport Control"
+    }, 
+    ":point_right_tone5:": {
+        "style": "github", 
+        "image": "1f449-1f3ff.png", 
+        "unicode": "👉🏿", 
+        "name": "White Right Pointing Backhand Index - Tone 5"
+    }, 
+    ":white_check_mark:": {
+        "style": "github", 
+        "image": "2705.png", 
+        "unicode": "✅", 
+        "name": "White Heavy Check Mark"
+    }, 
+    ":shit:": {
+        "style": "github", 
+        "image": "1f4a9.png", 
+        "unicode": "💩", 
+        "name": "Pile Of Poo"
+    }, 
+    "💆🏻": {
+        "style": "unicode", 
+        "image": "1f486-1f3fb.png", 
+        "name": "Face Massage - Tone 1"
+    }, 
+    "💆🏼": {
+        "style": "unicode", 
+        "image": "1f486-1f3fc.png", 
+        "name": "Face Massage - Tone 2"
+    }, 
+    "💆🏽": {
+        "style": "unicode", 
+        "image": "1f486-1f3fd.png", 
+        "name": "Face Massage - Tone 3"
+    }, 
+    "💆🏾": {
+        "style": "unicode", 
+        "image": "1f486-1f3fe.png", 
+        "name": "Face Massage - Tone 4"
+    }, 
+    "💆🏿": {
+        "style": "unicode", 
+        "image": "1f486-1f3ff.png", 
+        "name": "Face Massage - Tone 5"
+    }, 
+    ":sleeping-accommodation:": {
+        "style": "github", 
+        "image": "1f6cc.png", 
+        "unicode": "🛌", 
+        "name": "Sleeping Accommodation"
+    }, 
+    ":flag-im:": {
+        "style": "github", 
+        "image": "1f1ee-1f1f2.png", 
+        "unicode": "🇮🇲", 
+        "name": "Isle Of Man"
+    }, 
+    ":fireworks:": {
+        "style": "github", 
+        "image": "1f386.png", 
+        "unicode": "🎆", 
+        "name": "Fireworks"
+    }, 
+    ":gd:": {
+        "style": "github", 
+        "image": "1f1ec-1f1e9.png", 
+        "unicode": "🇬🇩", 
+        "name": "Grenada"
+    }, 
+    ":walking-tone5:": {
+        "style": "github", 
+        "image": "1f6b6-1f3ff.png", 
+        "unicode": "🚶🏿", 
+        "name": "Pedestrian - Tone 5"
+    }, 
+    ":white-circle:": {
+        "style": "github", 
+        "image": "26aa.png", 
+        "unicode": "⚪", 
+        "name": "Medium White Circle"
+    }, 
+    ":tanabata_tree:": {
+        "style": "github", 
+        "image": "1f38b.png", 
+        "unicode": "🎋", 
+        "name": "Tanabata Tree"
+    }, 
+    ":smirk_cat:": {
+        "style": "github", 
+        "image": "1f63c.png", 
+        "unicode": "😼", 
+        "name": "Cat Face With Wry Smile"
+    }, 
+    "☠": {
+        "style": "unicode", 
+        "image": "2620.png", 
+        "name": "Skull And Crossbones"
+    }, 
+    ":older-woman-tone5:": {
+        "style": "github", 
+        "image": "1f475-1f3ff.png", 
+        "unicode": "👵🏿", 
+        "name": "Older Woman - Tone 5"
+    }, 
+    "🚫": {
+        "style": "unicode", 
+        "image": "1f6ab.png", 
+        "name": "No Entry Sign"
+    }, 
+    "💉": {
+        "style": "unicode", 
+        "image": "1f489.png", 
+        "name": "Syringe"
+    }, 
+    ":beach-umbrella:": {
+        "style": "github", 
+        "image": "26f1.png", 
+        "unicode": "⛱", 
+        "name": "Umbrella On Ground"
+    }, 
+    ":basketball:": {
+        "style": "github", 
+        "image": "1f3c0.png", 
+        "unicode": "🏀", 
+        "name": "Basketball And Hoop"
+    }, 
+    "🙀": {
+        "style": "unicode", 
+        "image": "1f640.png", 
+        "name": "Weary Cat Face"
+    }, 
+    ":handball_tone4:": {
+        "style": "github", 
+        "image": "1f93e-1f3fe.png", 
+        "unicode": "🤾🏾", 
+        "name": "Handball - Tone 4"
+    }, 
+    ":purse:": {
+        "style": "github", 
+        "image": "1f45b.png", 
+        "unicode": "👛", 
+        "name": "Purse"
+    }, 
+    "🏙": {
+        "style": "unicode", 
+        "image": "1f3d9.png", 
+        "name": "Cityscape"
+    }, 
+    "🇨🇵": {
+        "style": "unicode", 
+        "image": "1f1e8-1f1f5.png", 
+        "name": "Clipperton Island"
+    }, 
+    "🍮": {
+        "style": "unicode", 
+        "image": "1f36e.png", 
+        "name": "Custard"
+    }, 
+    ":wheel-of-dharma:": {
+        "style": "github", 
+        "image": "2638.png", 
+        "unicode": "☸", 
+        "name": "Wheel Of Dharma"
+    }, 
+    ":no-good-tone3:": {
+        "style": "github", 
+        "image": "1f645-1f3fd.png", 
+        "unicode": "🙅🏽", 
+        "name": "Face With No Good Gesture - Tone 3"
+    }, 
+    ":love_letter:": {
+        "style": "github", 
+        "image": "1f48c.png", 
+        "unicode": "💌", 
+        "name": "Love Letter"
+    }, 
+    ":sweat_drops:": {
+        "style": "github", 
+        "image": "1f4a6.png", 
+        "unicode": "💦", 
+        "name": "Splashing Sweat Symbol"
+    }, 
+    ":bride_with_veil_tone2:": {
+        "style": "github", 
+        "image": "1f470-1f3fc.png", 
+        "unicode": "👰🏼", 
+        "name": "Bride With Veil - Tone 2"
+    }, 
+    "🔭": {
+        "style": "unicode", 
+        "image": "1f52d.png", 
+        "name": "Telescope"
+    }, 
+    "🌜": {
+        "style": "unicode", 
+        "image": "1f31c.png", 
+        "name": "Last Quarter Moon With Face"
+    }, 
+    "🤵": {
+        "style": "unicode", 
+        "image": "1f935.png", 
+        "name": "Man In Tuxedo"
+    }, 
+    "🐞": {
+        "style": "unicode", 
+        "image": "1f41e.png", 
+        "name": "Lady Beetle"
+    }, 
+    "🗂": {
+        "style": "unicode", 
+        "image": "1f5c2.png", 
+        "name": "Card Index Dividers"
+    }, 
+    ":+1_tone4:": {
+        "style": "github", 
+        "image": "1f44d-1f3fe.png", 
+        "unicode": "👍🏾", 
+        "name": "Thumbs Up Sign - Tone 4"
+    }, 
+    "👗": {
+        "style": "unicode", 
+        "image": "1f457.png", 
+        "name": "Dress"
+    }, 
+    ":school:": {
+        "style": "github", 
+        "image": "1f3eb.png", 
+        "unicode": "🏫", 
+        "name": "School"
+    }, 
+    ":put_litter_in_its_place:": {
+        "style": "github", 
+        "image": "1f6ae.png", 
+        "unicode": "🚮", 
+        "name": "Put Litter In Its Place Symbol"
+    }, 
+    "📬": {
+        "style": "unicode", 
+        "image": "1f4ec.png", 
+        "name": "Open Mailbox With Raised Flag"
+    }, 
+    ":cp:": {
+        "style": "github", 
+        "image": "1f1e8-1f1f5.png", 
+        "unicode": "🇨🇵", 
+        "name": "Clipperton Island"
+    }, 
+    "🚁": {
+        "style": "unicode", 
+        "image": "1f681.png", 
+        "name": "Helicopter"
+    }, 
+    "☪": {
+        "style": "unicode", 
+        "image": "262a.png", 
+        "name": "Star And Crescent"
+    }, 
+    ":clock1130:": {
+        "style": "github", 
+        "image": "1f566.png", 
+        "unicode": "🕦", 
+        "name": "Clock Face Eleven-thirty"
+    }, 
+    "😖": {
+        "style": "unicode", 
+        "image": "1f616.png", 
+        "name": "Confounded Face"
+    }, 
+    ":flag-fk:": {
+        "style": "github", 
+        "image": "1f1eb-1f1f0.png", 
+        "unicode": "🇫🇰", 
+        "name": "Falkland Islands"
+    }, 
+    ":flag_gt:": {
+        "style": "github", 
+        "image": "1f1ec-1f1f9.png", 
+        "unicode": "🇬🇹", 
+        "name": "Guatemala"
+    }, 
+    ":city-dusk:": {
+        "style": "github", 
+        "image": "1f306.png", 
+        "unicode": "🌆", 
+        "name": "Cityscape At Dusk"
+    }, 
+    ":call_me_hand_tone4:": {
+        "style": "github", 
+        "image": "1f919-1f3fe.png", 
+        "unicode": "🤙🏾", 
+        "name": "Call Me Hand - Tone 4"
+    }, 
+    ":mrs_claus_tone3:": {
+        "style": "github", 
+        "image": "1f936-1f3fd.png", 
+        "unicode": "🤶🏽", 
+        "name": "Mother Christmas - Tone 3"
+    }, 
+    ":bank:": {
+        "style": "github", 
+        "image": "1f3e6.png", 
+        "unicode": "🏦", 
+        "name": "Bank"
+    }, 
+    ":office:": {
+        "style": "github", 
+        "image": "1f3e2.png", 
+        "unicode": "🏢", 
+        "name": "Office Building"
+    }, 
+    ":punch:": {
+        "style": "github", 
+        "image": "1f44a.png", 
+        "unicode": "👊", 
+        "name": "Fisted Hand Sign"
+    }, 
+    ":open-hands:": {
+        "style": "github", 
+        "image": "1f450.png", 
+        "unicode": "👐", 
+        "name": "Open Hands Sign"
+    }, 
+    "🌃": {
+        "style": "unicode", 
+        "image": "1f303.png", 
+        "name": "Night With Stars"
+    }, 
+    ":fingers_crossed:": {
+        "style": "github", 
+        "image": "1f91e.png", 
+        "unicode": "🤞", 
+        "name": "Hand With First And Index Finger Crossed"
+    }, 
+    ":regional-indicator-p:": {
+        "style": "github", 
+        "image": "1f1f5.png", 
+        "unicode": "🇵", 
+        "name": "Regional Indicator Symbol Letter P"
+    }, 
+    ":point_up_2_tone1:": {
+        "style": "github", 
+        "image": "1f446-1f3fb.png", 
+        "unicode": "👆🏻", 
+        "name": "White Up Pointing Backhand Index - Tone 1"
+    }, 
+    ":heartbeat:": {
+        "style": "github", 
+        "image": "1f493.png", 
+        "unicode": "💓", 
+        "name": "Beating Heart"
+    }, 
+    ":person_with_ball_tone5:": {
+        "style": "github", 
+        "image": "26f9-1f3ff.png", 
+        "unicode": "⛹🏿", 
+        "name": "Person With Ball - Tone 5"
+    }, 
+    "🐭": {
+        "style": "unicode", 
+        "image": "1f42d.png", 
+        "name": "Mouse Face"
+    }, 
+    ":wrestlers-tone5:": {
+        "style": "github", 
+        "image": "1f93c-1f3ff.png", 
+        "unicode": "🤼🏿", 
+        "name": "Wrestlers - Tone 5"
+    }, 
+    ":tea:": {
+        "style": "github", 
+        "image": "1f375.png", 
+        "unicode": "🍵", 
+        "name": "Teacup Without Handle"
+    }, 
+    ":point_up_tone3:": {
+        "style": "github", 
+        "image": "261d-1f3fd.png", 
+        "unicode": "☝🏽", 
+        "name": "White Up Pointing Index - Tone 3"
+    }, 
+    ":hushed:": {
+        "style": "github", 
+        "image": "1f62f.png", 
+        "unicode": "😯", 
+        "name": "Hushed Face"
+    }, 
+    "📂": {
+        "style": "unicode", 
+        "image": "1f4c2.png", 
+        "name": "Open File Folder"
+    }, 
+    ":cop:": {
+        "style": "github", 
+        "image": "1f46e.png", 
+        "unicode": "👮", 
+        "name": "Police Officer"
+    }, 
+    ":spider_web:": {
+        "style": "github", 
+        "image": "1f578.png", 
+        "unicode": "🕸", 
+        "name": "Spider Web"
+    }, 
+    ":regional_indicator_h:": {
+        "style": "github", 
+        "image": "1f1ed.png", 
+        "unicode": "🇭", 
+        "name": "Regional Indicator Symbol Letter H"
+    }, 
+    ":raised_hand_with_fingers_splayed_tone5:": {
+        "style": "github", 
+        "image": "1f590-1f3ff.png", 
+        "unicode": "🖐🏿", 
+        "name": "Raised Hand With Fingers Splayed - Tone 5"
+    }, 
+    "🕗": {
+        "style": "unicode", 
+        "image": "1f557.png", 
+        "name": "Clock Face Eight Oclock"
+    }, 
+    "🐧": {
+        "style": "unicode", 
+        "image": "1f427.png", 
+        "name": "Penguin"
+    }, 
+    ":flag_gu:": {
+        "style": "github", 
+        "image": "1f1ec-1f1fa.png", 
+        "unicode": "🇬🇺", 
+        "name": "Guam"
+    }, 
+    ":milky_way:": {
+        "style": "github", 
+        "image": "1f30c.png", 
+        "unicode": "🌌", 
+        "name": "Milky Way"
+    }, 
+    ":gift_heart:": {
+        "style": "github", 
+        "image": "1f49d.png", 
+        "unicode": "💝", 
+        "name": "Heart With Ribbon"
+    }, 
+    ":expecting_woman_tone1:": {
+        "style": "github", 
+        "image": "1f930-1f3fb.png", 
+        "unicode": "🤰🏻", 
+        "name": "Pregnant Woman - Tone 1"
+    }, 
+    "🦁": {
+        "style": "unicode", 
+        "image": "1f981.png", 
+        "name": "Lion Face"
+    }, 
+    ":person-frowning-tone4:": {
+        "style": "github", 
+        "image": "1f64d-1f3fe.png", 
+        "unicode": "🙍🏾", 
+        "name": "Person Frowning - Tone 4"
+    }, 
+    "🤖": {
+        "style": "unicode", 
+        "image": "1f916.png", 
+        "name": "Robot Face"
+    }, 
+    "🔞": {
+        "style": "unicode", 
+        "image": "1f51e.png", 
+        "name": "No One Under Eighteen Symbol"
+    }, 
+    ":boy_tone2:": {
+        "style": "github", 
+        "image": "1f466-1f3fc.png", 
+        "unicode": "👦🏼", 
+        "name": "Boy - Tone 2"
+    }, 
+    ":flag_aq:": {
+        "style": "github", 
+        "image": "1f1e6-1f1f6.png", 
+        "unicode": "🇦🇶", 
+        "name": "Antarctica"
+    }, 
+    ":cloud_lightning:": {
+        "style": "github", 
+        "image": "1f329.png", 
+        "unicode": "🌩", 
+        "name": "Cloud With Lightning"
+    }, 
+    "💳": {
+        "style": "unicode", 
+        "image": "1f4b3.png", 
+        "name": "Credit Card"
+    }, 
+    ":vg:": {
+        "style": "github", 
+        "image": "1f1fb-1f1ec.png", 
+        "unicode": "🇻🇬", 
+        "name": "British Virgin Islands"
+    }, 
+    "👮🏼": {
+        "style": "unicode", 
+        "image": "1f46e-1f3fc.png", 
+        "name": "Police Officer - Tone 2"
+    }, 
+    "👮🏽": {
+        "style": "unicode", 
+        "image": "1f46e-1f3fd.png", 
+        "name": "Police Officer - Tone 3"
+    }, 
+    "👮🏾": {
+        "style": "unicode", 
+        "image": "1f46e-1f3fe.png", 
+        "name": "Police Officer - Tone 4"
+    }, 
+    "👮🏿": {
+        "style": "unicode", 
+        "image": "1f46e-1f3ff.png", 
+        "name": "Police Officer - Tone 5"
+    }, 
+    ":family-mwg:": {
+        "style": "github", 
+        "image": "1f468-1f469-1f467.png", 
+        "unicode": "👨👩👧", 
+        "name": "Family (man,woman,girl)"
+    }, 
+    ":watch:": {
+        "style": "github", 
+        "image": "231a.png", 
+        "unicode": "⌚", 
+        "name": "Watch"
+    }, 
+    "👈": {
+        "style": "unicode", 
+        "image": "1f448.png", 
+        "name": "White Left Pointing Backhand Index"
+    }, 
+    ":flag_ck:": {
+        "style": "github", 
+        "image": "1f1e8-1f1f0.png", 
+        "unicode": "🇨🇰", 
+        "name": "Cook Islands"
+    }, 
+    ":lb:": {
+        "style": "github", 
+        "image": "1f1f1-1f1e7.png", 
+        "unicode": "🇱🇧", 
+        "name": "Lebanon"
+    }, 
+    "🏝": {
+        "style": "unicode", 
+        "image": "1f3dd.png", 
+        "name": "Desert Island"
+    }, 
+    ":water-polo-tone2:": {
+        "style": "github", 
+        "image": "1f93d-1f3fc.png", 
+        "unicode": "🤽🏼", 
+        "name": "Water Polo - Tone 2"
+    }, 
+    ":tuxedo_tone3:": {
+        "style": "github", 
+        "image": "1f935-1f3fd.png", 
+        "unicode": "🤵🏽", 
+        "name": "Man In Tuxedo - Tone 3"
+    }, 
+    "🍲": {
+        "style": "unicode", 
+        "image": "1f372.png", 
+        "name": "Pot Of Food"
+    }, 
+    ":santa-tone2:": {
+        "style": "github", 
+        "image": "1f385-1f3fc.png", 
+        "unicode": "🎅🏼", 
+        "name": "Father Christmas - Tone 2"
+    }, 
+    "':-D": {
+        "style": "ascii", 
+        "ascii": "':)", 
+        "image": "1f605.png", 
+        "unicode": "😅", 
+        "name": "Smiling Face With Open Mouth And Cold Sweat"
+    }, 
+    ":two_men_holding_hands:": {
+        "style": "github", 
+        "image": "1f46c.png", 
+        "unicode": "👬", 
+        "name": "Two Men Holding Hands"
+    }, 
+    ":eggplant:": {
+        "style": "github", 
+        "image": "1f346.png", 
+        "unicode": "🍆", 
+        "name": "Aubergine"
+    }, 
+    ":water_polo_tone4:": {
+        "style": "github", 
+        "image": "1f93d-1f3fe.png", 
+        "unicode": "🤽🏾", 
+        "name": "Water Polo - Tone 4"
+    }, 
+    "🙌🏽": {
+        "style": "unicode", 
+        "image": "1f64c-1f3fd.png", 
+        "name": "Person Raising Both Hands In Celebration - Tone 3"
+    }, 
+    ":horse_racing_tone2:": {
+        "style": "github", 
+        "image": "1f3c7-1f3fc.png", 
+        "unicode": "🏇🏼", 
+        "name": "Horse Racing - Tone 2"
+    }, 
+    ":raising_hand_tone4:": {
+        "style": "github", 
+        "image": "1f64b-1f3fe.png", 
+        "unicode": "🙋🏾", 
+        "name": "Happy Person Raising One Hand Tone4"
+    }, 
+    ":selfie:": {
+        "style": "github", 
+        "image": "1f933.png", 
+        "unicode": "🤳", 
+        "name": "Selfie"
+    }, 
+    "⛔": {
+        "style": "unicode", 
+        "image": "26d4.png", 
+        "name": "No Entry"
+    }, 
+    ":im:": {
+        "style": "github", 
+        "image": "1f1ee-1f1f2.png", 
+        "unicode": "🇮🇲", 
+        "name": "Isle Of Man"
+    }, 
+    "':-(": {
+        "style": "ascii", 
+        "ascii": "':(", 
+        "image": "1f613.png", 
+        "unicode": "😓", 
+        "name": "Face With Cold Sweat"
+    }, 
+    "':-)": {
+        "style": "ascii", 
+        "ascii": "':)", 
+        "image": "1f605.png", 
+        "unicode": "😅", 
+        "name": "Smiling Face With Open Mouth And Cold Sweat"
+    }, 
+    ":small-red-triangle:": {
+        "style": "github", 
+        "image": "1f53a.png", 
+        "unicode": "🔺", 
+        "name": "Up-pointing Red Triangle"
+    }, 
+    "🛴": {
+        "style": "unicode", 
+        "image": "1f6f4.png", 
+        "name": "Scooter"
+    }, 
+    "◾": {
+        "style": "unicode", 
+        "image": "25fe.png", 
+        "name": "Black Medium Small Square"
+    }, 
+    ":point_left_tone5:": {
+        "style": "github", 
+        "image": "1f448-1f3ff.png", 
+        "unicode": "👈🏿", 
+        "name": "White Left Pointing Backhand Index - Tone 5"
+    }, 
+    ":level-slider:": {
+        "style": "github", 
+        "image": "1f39a.png", 
+        "unicode": "🎚", 
+        "name": "Level Slider"
+    }, 
+    ":princess-tone2:": {
+        "style": "github", 
+        "image": "1f478-1f3fc.png", 
+        "unicode": "👸🏼", 
+        "name": "Princess - Tone 2"
+    }, 
+    ":regional-indicator-m:": {
+        "style": "github", 
+        "image": "1f1f2.png", 
+        "unicode": "🇲", 
+        "name": "Regional Indicator Symbol Letter M"
+    }, 
+    ":cloud-lightning:": {
+        "style": "github", 
+        "image": "1f329.png", 
+        "unicode": "🌩", 
+        "name": "Cloud With Lightning"
+    }, 
+    ":bell:": {
+        "style": "github", 
+        "image": "1f514.png", 
+        "unicode": "🔔", 
+        "name": "Bell"
+    }, 
+    "👈🏻": {
+        "style": "unicode", 
+        "image": "1f448-1f3fb.png", 
+        "name": "White Left Pointing Backhand Index - Tone 1"
+    }, 
+    "👈🏾": {
+        "style": "unicode", 
+        "image": "1f448-1f3fe.png", 
+        "name": "White Left Pointing Backhand Index - Tone 4"
+    }, 
+    "👈🏿": {
+        "style": "unicode", 
+        "image": "1f448-1f3ff.png", 
+        "name": "White Left Pointing Backhand Index - Tone 5"
+    }, 
+    "👈🏼": {
+        "style": "unicode", 
+        "image": "1f448-1f3fc.png", 
+        "name": "White Left Pointing Backhand Index - Tone 2"
+    }, 
+    "👈🏽": {
+        "style": "unicode", 
+        "image": "1f448-1f3fd.png", 
+        "name": "White Left Pointing Backhand Index - Tone 3"
+    }, 
+    ":dancer-tone3:": {
+        "style": "github", 
+        "image": "1f483-1f3fd.png", 
+        "unicode": "💃🏽", 
+        "name": "Dancer - Tone 3"
+    }, 
+    ":smiley-cat:": {
+        "style": "github", 
+        "image": "1f63a.png", 
+        "unicode": "😺", 
+        "name": "Smiling Cat Face With Open Mouth"
+    }, 
+    ":eye:": {
+        "style": "github", 
+        "image": "1f441.png", 
+        "unicode": "👁", 
+        "name": "Eye"
+    }, 
+    "🥀": {
+        "style": "unicode", 
+        "image": "1f940.png", 
+        "name": "Wilted Flower"
+    }, 
+    ":rowboat-tone1:": {
+        "style": "github", 
+        "image": "1f6a3-1f3fb.png", 
+        "unicode": "🚣🏻", 
+        "name": "Rowboat - Tone 1"
+    }, 
+    ":flag_st:": {
+        "style": "github", 
+        "image": "1f1f8-1f1f9.png", 
+        "unicode": "🇸🇹", 
+        "name": "São Tomé And Príncipe"
+    }, 
+    ":new_moon_with_face:": {
+        "style": "github", 
+        "image": "1f31a.png", 
+        "unicode": "🌚", 
+        "name": "New Moon With Face"
+    }, 
+    ":bride-with-veil-tone4:": {
+        "style": "github", 
+        "image": "1f470-1f3fe.png", 
+        "unicode": "👰🏾", 
+        "name": "Bride With Veil - Tone 4"
+    }, 
+    ":cricket_bat_ball:": {
+        "style": "github", 
+        "image": "1f3cf.png", 
+        "unicode": "🏏", 
+        "name": "Cricket Bat And Ball"
+    }, 
+    ":flag-br:": {
+        "style": "github", 
+        "image": "1f1e7-1f1f7.png", 
+        "unicode": "🇧🇷", 
+        "name": "Brazil"
+    }, 
+    ":six_pointed_star:": {
+        "style": "github", 
+        "image": "1f52f.png", 
+        "unicode": "🔯", 
+        "name": "Six Pointed Star With Middle Dot"
+    }, 
+    ":ma:": {
+        "style": "github", 
+        "image": "1f1f2-1f1e6.png", 
+        "unicode": "🇲🇦", 
+        "name": "Morocco"
+    }, 
+    ":clock9:": {
+        "style": "github", 
+        "image": "1f558.png", 
+        "unicode": "🕘", 
+        "name": "Clock Face Nine Oclock"
+    }, 
+    ":wave-tone2:": {
+        "style": "github", 
+        "image": "1f44b-1f3fc.png", 
+        "unicode": "👋🏼", 
+        "name": "Waving Hand Sign - Tone 2"
+    }, 
+    "*\\O/*": {
+        "style": "ascii", 
+        "ascii": "*\\0/*", 
+        "image": "1f646.png", 
+        "unicode": "🙆", 
+        "name": "Face With Ok Gesture"
+    }, 
+    "☕": {
+        "style": "unicode", 
+        "image": "2615.png", 
+        "name": "Hot Beverage"
+    }, 
+    "⚪": {
+        "style": "unicode", 
+        "image": "26aa.png", 
+        "name": "Medium White Circle"
+    }, 
+    ":basketball_player_tone1:": {
+        "style": "github", 
+        "image": "26f9-1f3fb.png", 
+        "unicode": "⛹🏻", 
+        "name": "Person With Ball - Tone 1"
+    }, 
+    ":flag_ke:": {
+        "style": "github", 
+        "image": "1f1f0-1f1ea.png", 
+        "unicode": "🇰🇪", 
+        "name": "Kenya"
+    }, 
+    ":bq:": {
+        "style": "github", 
+        "image": "1f1e7-1f1f6.png", 
+        "unicode": "🇧🇶", 
+        "name": "Caribbean Netherlands"
+    }, 
+    ":flag_uz:": {
+        "style": "github", 
+        "image": "1f1fa-1f1ff.png", 
+        "unicode": "🇺🇿", 
+        "name": "Uzbekistan"
+    }, 
+    ":articulated_lorry:": {
+        "style": "github", 
+        "image": "1f69b.png", 
+        "unicode": "🚛", 
+        "name": "Articulated Lorry"
+    }, 
+    ":left_fist_tone4:": {
+        "style": "github", 
+        "image": "1f91b-1f3fe.png", 
+        "unicode": "🤛🏾", 
+        "name": "Left Facing Fist - Tone 4"
+    }, 
+    ":tv:": {
+        "style": "github", 
+        "image": "1f4fa.png", 
+        "unicode": "📺", 
+        "name": "Television"
+    }, 
+    ":selfie_tone2:": {
+        "style": "github", 
+        "image": "1f933-1f3fc.png", 
+        "unicode": "🤳🏼", 
+        "name": "Selfie - Tone 2"
+    }, 
+    ":keycap_ten:": {
+        "style": "github", 
+        "image": "1f51f.png", 
+        "unicode": "🔟", 
+        "name": "Keycap Ten"
+    }, 
+    ":cop_tone1:": {
+        "style": "github", 
+        "image": "1f46e-1f3fb.png", 
+        "unicode": "👮🏻", 
+        "name": "Police Officer - Tone 1"
+    }, 
+    "👓": {
+        "style": "unicode", 
+        "image": "1f453.png", 
+        "name": "Eyeglasses"
+    }, 
+    "🇰": {
+        "style": "unicode", 
+        "image": "1f1f0.png", 
+        "name": "Regional Indicator Symbol Letter K"
+    }, 
+    ":flag_la:": {
+        "style": "github", 
+        "image": "1f1f1-1f1e6.png", 
+        "unicode": "🇱🇦", 
+        "name": "Laos"
+    }, 
+    ":baby-symbol:": {
+        "style": "github", 
+        "image": "1f6bc.png", 
+        "unicode": "🚼", 
+        "name": "Baby Symbol"
+    }, 
+    "👩🏻": {
+        "style": "unicode", 
+        "image": "1f469-1f3fb.png", 
+        "name": "Woman - Tone 1"
+    }, 
+    "👩🏽": {
+        "style": "unicode", 
+        "image": "1f469-1f3fd.png", 
+        "name": "Woman - Tone 3"
+    }, 
+    "👩🏼": {
+        "style": "unicode", 
+        "image": "1f469-1f3fc.png", 
+        "name": "Woman - Tone 2"
+    }, 
+    "👩🏿": {
+        "style": "unicode", 
+        "image": "1f469-1f3ff.png", 
+        "name": "Woman - Tone 5"
+    }, 
+    "👩🏾": {
+        "style": "unicode", 
+        "image": "1f469-1f3fe.png", 
+        "name": "Woman - Tone 4"
+    }, 
+    ":nigeria:": {
+        "style": "github", 
+        "image": "1f1f3-1f1ec.png", 
+        "unicode": "🇳🇬", 
+        "name": "Nigeria"
+    }, 
+    "⚓": {
+        "style": "unicode", 
+        "image": "2693.png", 
+        "name": "Anchor"
+    }, 
+    ":flag-pk:": {
+        "style": "github", 
+        "image": "1f1f5-1f1f0.png", 
+        "unicode": "🇵🇰", 
+        "name": "Pakistan"
+    }, 
+    ":spiral_note_pad:": {
+        "style": "github", 
+        "image": "1f5d2.png", 
+        "unicode": "🗒", 
+        "name": "Spiral Note Pad"
+    }, 
+    "💇🏿": {
+        "style": "unicode", 
+        "image": "1f487-1f3ff.png", 
+        "name": "Haircut - Tone 5"
+    }, 
+    "💇🏾": {
+        "style": "unicode", 
+        "image": "1f487-1f3fe.png", 
+        "name": "Haircut - Tone 4"
+    }, 
+    ":cop-tone2:": {
+        "style": "github", 
+        "image": "1f46e-1f3fc.png", 
+        "unicode": "👮🏼", 
+        "name": "Police Officer - Tone 2"
+    }, 
+    "💇🏼": {
+        "style": "unicode", 
+        "image": "1f487-1f3fc.png", 
+        "name": "Haircut - Tone 2"
+    }, 
+    ":sunny:": {
+        "style": "github", 
+        "image": "2600.png", 
+        "unicode": "☀", 
+        "name": "Black Sun With Rays"
+    }, 
+    "🚳": {
+        "style": "unicode", 
+        "image": "1f6b3.png", 
+        "name": "No Bicycles"
+    }, 
+    ":guardsman-tone1:": {
+        "style": "github", 
+        "image": "1f482-1f3fb.png", 
+        "unicode": "💂🏻", 
+        "name": "Guardsman - Tone 1"
+    }, 
+    "😵": {
+        "style": "unicode", 
+        "ascii": "#-)", 
+        "image": "1f635.png", 
+        "name": "Dizzy Face"
+    }, 
+    ":black_large_square:": {
+        "style": "github", 
+        "image": "2b1b.png", 
+        "unicode": "⬛", 
+        "name": "Black Large Square"
+    }, 
+    ":video-game:": {
+        "style": "github", 
+        "image": "1f3ae.png", 
+        "unicode": "🎮", 
+        "name": "Video Game"
+    }, 
+    ":old_key:": {
+        "style": "github", 
+        "image": "1f5dd.png", 
+        "unicode": "🗝", 
+        "name": "Old Key"
+    }, 
+    "🙈": {
+        "style": "unicode", 
+        "image": "1f648.png", 
+        "name": "See-no-evil Monkey"
+    }, 
+    ":point_right_tone3:": {
+        "style": "github", 
+        "image": "1f449-1f3fd.png", 
+        "unicode": "👉🏽", 
+        "name": "White Right Pointing Backhand Index - Tone 3"
+    }, 
+    ":ok-woman-tone4:": {
+        "style": "github", 
+        "image": "1f646-1f3fe.png", 
+        "unicode": "🙆🏾", 
+        "name": "Face With Ok Gesture Tone4"
+    }, 
+    ":sparkler:": {
+        "style": "github", 
+        "image": "1f387.png", 
+        "unicode": "🎇", 
+        "name": "Firework Sparkler"
+    }, 
+    ":flag-ic:": {
+        "style": "github", 
+        "image": "1f1ee-1f1e8.png", 
+        "unicode": "🇮🇨", 
+        "name": "Canary Islands"
+    }, 
+    "☺": {
+        "style": "unicode", 
+        "image": "263a.png", 
+        "name": "White Smiling Face"
+    }, 
+    ":waving_white_flag:": {
+        "style": "github", 
+        "image": "1f3f3.png", 
+        "unicode": "🏳", 
+        "name": "Waving White Flag"
+    }, 
+    ":level_slider:": {
+        "style": "github", 
+        "image": "1f39a.png", 
+        "unicode": "🎚", 
+        "name": "Level Slider"
+    }, 
+    ":convenience-store:": {
+        "style": "github", 
+        "image": "1f3ea.png", 
+        "unicode": "🏪", 
+        "name": "Convenience Store"
+    }, 
+    ":arrows-clockwise:": {
+        "style": "github", 
+        "image": "1f503.png", 
+        "unicode": "🔃", 
+        "name": "Clockwise Downwards And Upwards Open Circle Arrows"
+    }, 
+    ":older-woman-tone3:": {
+        "style": "github", 
+        "image": "1f475-1f3fd.png", 
+        "unicode": "👵🏽", 
+        "name": "Older Woman - Tone 3"
+    }, 
+    "🌱": {
+        "style": "unicode", 
+        "image": "1f331.png", 
+        "name": "Seedling"
+    }, 
+    "🔵": {
+        "style": "unicode", 
+        "image": "1f535.png", 
+        "name": "Large Blue Circle"
+    }, 
+    "🏊🏼": {
+        "style": "unicode", 
+        "image": "1f3ca-1f3fc.png", 
+        "name": "Swimmer - Tone 2"
+    }, 
+    ":handball_tone2:": {
+        "style": "github", 
+        "image": "1f93e-1f3fc.png", 
+        "unicode": "🤾🏼", 
+        "name": "Handball - Tone 2"
+    }, 
+    ":fax:": {
+        "style": "github", 
+        "image": "1f4e0.png", 
+        "unicode": "📠", 
+        "name": "Fax Machine"
+    }, 
+    "🏆": {
+        "style": "unicode", 
+        "image": "1f3c6.png", 
+        "name": "Trophy"
+    }, 
+    ":raised-hand-tone5:": {
+        "style": "github", 
+        "image": "270b-1f3ff.png", 
+        "unicode": "✋🏿", 
+        "name": "Raised Hand - Tone 5"
+    }, 
+    "👟": {
+        "style": "unicode", 
+        "image": "1f45f.png", 
+        "name": "Athletic Shoe"
+    }, 
+    "📴": {
+        "style": "unicode", 
+        "image": "1f4f4.png", 
+        "name": "Mobile Phone Off"
+    }, 
+    ":shield:": {
+        "style": "github", 
+        "image": "1f6e1.png", 
+        "unicode": "🛡", 
+        "name": "Shield"
+    }, 
+    ":no-good-tone5:": {
+        "style": "github", 
+        "image": "1f645-1f3ff.png", 
+        "unicode": "🙅🏿", 
+        "name": "Face With No Good Gesture - Tone 5"
+    }, 
+    "🚉": {
+        "style": "unicode", 
+        "image": "1f689.png", 
+        "name": "Station"
+    }, 
+    ":mountain_bicyclist_tone1:": {
+        "style": "github", 
+        "image": "1f6b5-1f3fb.png", 
+        "unicode": "🚵🏻", 
+        "name": "Mountain Bicyclist - Tone 1"
+    }, 
+    ":hammer-pick:": {
+        "style": "github", 
+        "image": "2692.png", 
+        "unicode": "⚒", 
+        "name": "Hammer And Pick"
+    }, 
+    "😞": {
+        "style": "unicode", 
+        "ascii": ">:[", 
+        "image": "1f61e.png", 
+        "name": "Disappointed Face"
+    }, 
+    ":flag-mg:": {
+        "style": "github", 
+        "image": "1f1f2-1f1ec.png", 
+        "unicode": "🇲🇬", 
+        "name": "Madagascar"
+    }, 
+    "✨": {
+        "style": "unicode", 
+        "image": "2728.png", 
+        "name": "Sparkles"
+    }, 
+    ":flag-ge:": {
+        "style": "github", 
+        "image": "1f1ec-1f1ea.png", 
+        "unicode": "🇬🇪", 
+        "name": "Georgia"
+    }, 
+    ":heavy_check_mark:": {
+        "style": "github", 
+        "image": "2714.png", 
+        "unicode": "✔", 
+        "name": "Heavy Check Mark"
+    }, 
+    ":surfer-tone4:": {
+        "style": "github", 
+        "image": "1f3c4-1f3fe.png", 
+        "unicode": "🏄🏾", 
+        "name": "Surfer - Tone 4"
+    }, 
+    ":clap_tone1:": {
+        "style": "github", 
+        "image": "1f44f-1f3fb.png", 
+        "unicode": "👏🏻", 
+        "name": "Clapping Hands Sign - Tone 1"
+    }, 
+    "\\0/": {
+        "style": "ascii", 
+        "ascii": "*\\0/*", 
+        "image": "1f646.png", 
+        "unicode": "🙆", 
+        "name": "Face With Ok Gesture"
+    }, 
+    ":green-apple:": {
+        "style": "github", 
+        "image": "1f34f.png", 
+        "unicode": "🍏", 
+        "name": "Green Apple"
+    }, 
+    ":ideograph_advantage:": {
+        "style": "github", 
+        "image": "1f250.png", 
+        "unicode": "🉐", 
+        "name": "Circled Ideograph Advantage"
+    }, 
+    ":revolving-hearts:": {
+        "style": "github", 
+        "image": "1f49e.png", 
+        "unicode": "💞", 
+        "name": "Revolving Hearts"
+    }, 
+    ":scroll:": {
+        "style": "github", 
+        "image": "1f4dc.png", 
+        "unicode": "📜", 
+        "name": "Scroll"
+    }, 
+    ":flag_fr:": {
+        "style": "github", 
+        "image": "1f1eb-1f1f7.png", 
+        "unicode": "🇫🇷", 
+        "name": "France"
+    }, 
+    "🔼": {
+        "style": "unicode", 
+        "image": "1f53c.png", 
+        "name": "Up-pointing Small Red Triangle"
+    }, 
+    ":pray_tone5:": {
+        "style": "github", 
+        "image": "1f64f-1f3ff.png", 
+        "unicode": "🙏🏿", 
+        "name": "Person With Folded Hands - Tone 5"
+    }, 
+    ":pick:": {
+        "style": "github", 
+        "image": "26cf.png", 
+        "unicode": "⛏", 
+        "name": "Pick"
+    }, 
+    ":motorboat:": {
+        "style": "github", 
+        "image": "1f6e5.png", 
+        "unicode": "🛥", 
+        "name": "Motorboat"
+    }, 
+    ":nut-and-bolt:": {
+        "style": "github", 
+        "image": "1f529.png", 
+        "unicode": "🔩", 
+        "name": "Nut And Bolt"
+    }, 
+    "☝🏻": {
+        "style": "unicode", 
+        "image": "261d-1f3fb.png", 
+        "name": "White Up Pointing Index - Tone 1"
+    }, 
+    ":flag_gr:": {
+        "style": "github", 
+        "image": "1f1ec-1f1f7.png", 
+        "unicode": "🇬🇷", 
+        "name": "Greece"
+    }, 
+    ":park:": {
+        "style": "github", 
+        "image": "1f3de.png", 
+        "unicode": "🏞", 
+        "name": "National Park"
+    }, 
+    ":flag-fi:": {
+        "style": "github", 
+        "image": "1f1eb-1f1ee.png", 
+        "unicode": "🇫🇮", 
+        "name": "Finland"
+    }, 
+    "🐵": {
+        "style": "unicode", 
+        "image": "1f435.png", 
+        "name": "Monkey Face"
+    }, 
+    ";-)": {
+        "style": "ascii", 
+        "ascii": ";)", 
+        "image": "1f609.png", 
+        "unicode": "😉", 
+        "name": "Winking Face"
+    }, 
+    ";-(": {
+        "style": "ascii", 
+        "ascii": ":'(", 
+        "image": "1f622.png", 
+        "unicode": "😢", 
+        "name": "Crying Face"
+    }, 
+    ";-]": {
+        "style": "ascii", 
+        "ascii": ";)", 
+        "image": "1f609.png", 
+        "unicode": "😉", 
+        "name": "Winking Face"
+    }, 
+    "📊": {
+        "style": "unicode", 
+        "image": "1f4ca.png", 
+        "name": "Bar Chart"
+    }, 
+    ":first-quarter-moon-with-face:": {
+        "style": "github", 
+        "image": "1f31b.png", 
+        "unicode": "🌛", 
+        "name": "First Quarter Moon With Face"
+    }, 
+    ":person-with-blond-hair-tone2:": {
+        "style": "github", 
+        "image": "1f471-1f3fc.png", 
+        "unicode": "👱🏼", 
+        "name": "Person With Blond Hair - Tone 2"
+    }, 
+    ":mrs_claus_tone5:": {
+        "style": "github", 
+        "image": "1f936-1f3ff.png", 
+        "unicode": "🤶🏿", 
+        "name": "Mother Christmas - Tone 5"
+    }, 
+    ":icecream:": {
+        "style": "github", 
+        "image": "1f366.png", 
+        "unicode": "🍦", 
+        "name": "Soft Ice Cream"
+    }, 
+    "🥗": {
+        "style": "unicode", 
+        "image": "1f957.png", 
+        "name": "Green Salad"
+    }, 
+    "🍛": {
+        "style": "unicode", 
+        "image": "1f35b.png", 
+        "name": "Curry And Rice"
+    }, 
+    "🕟": {
+        "style": "unicode", 
+        "image": "1f55f.png", 
+        "name": "Clock Face Four-thirty"
+    }, 
+    ":wrestlers_tone4:": {
+        "style": "github", 
+        "image": "1f93c-1f3fe.png", 
+        "unicode": "🤼🏾", 
+        "name": "Wrestlers - Tone 4"
+    }, 
+    "🏰": {
+        "style": "unicode", 
+        "image": "1f3f0.png", 
+        "name": "European Castle"
+    }, 
+    ":regional-indicator-v:": {
+        "style": "github", 
+        "image": "1f1fb.png", 
+        "unicode": "🇻", 
+        "name": "Regional Indicator Symbol Letter V"
+    }, 
+    "=p": {
+        "style": "ascii", 
+        "ascii": ":P", 
+        "image": "1f61b.png", 
+        "unicode": "😛", 
+        "name": "Face With Stuck-out Tongue"
+    }, 
+    "=x": {
+        "style": "ascii", 
+        "ascii": ":-X", 
+        "image": "1f636.png", 
+        "unicode": "😶", 
+        "name": "Face Without Mouth"
+    }, 
+    ":arrow-up-down:": {
+        "style": "github", 
+        "image": "2195.png", 
+        "unicode": "↕", 
+        "name": "Up Down Arrow"
+    }, 
+    ":clap-tone5:": {
+        "style": "github", 
+        "image": "1f44f-1f3ff.png", 
+        "unicode": "👏🏿", 
+        "name": "Clapping Hands Sign - Tone 5"
+    }, 
+    ":flag_ag:": {
+        "style": "github", 
+        "image": "1f1e6-1f1ec.png", 
+        "unicode": "🇦🇬", 
+        "name": "Antigua And Barbuda"
+    }, 
+    "=P": {
+        "style": "ascii", 
+        "ascii": ":P", 
+        "image": "1f61b.png", 
+        "unicode": "😛", 
+        "name": "Face With Stuck-out Tongue"
+    }, 
+    ":point_down_tone4:": {
+        "style": "github", 
+        "image": "1f447-1f3fe.png", 
+        "unicode": "👇🏾", 
+        "name": "White Down Pointing Backhand Index - Tone 4"
+    }, 
+    "=]": {
+        "style": "ascii", 
+        "ascii": ":)", 
+        "image": "1f642.png", 
+        "unicode": "🙂", 
+        "name": "Slightly Smiling Face"
+    }, 
+    "=\\": {
+        "style": "ascii", 
+        "ascii": ">:\\", 
+        "image": "1f615.png", 
+        "unicode": "😕", 
+        "name": "Confused Face"
+    }, 
+    "=X": {
+        "style": "ascii", 
+        "ascii": ":-X", 
+        "image": "1f636.png", 
+        "unicode": "😶", 
+        "name": "Face Without Mouth"
+    }, 
+    "=D": {
+        "style": "ascii", 
+        "ascii": ":D", 
+        "image": "1f603.png", 
+        "unicode": "😃", 
+        "name": "Smiling Face With Open Mouth"
+    }, 
+    ":point_up_tone5:": {
+        "style": "github", 
+        "image": "261d-1f3ff.png", 
+        "unicode": "☝🏿", 
+        "name": "White Up Pointing Index - Tone 5"
+    }, 
+    ":pw:": {
+        "style": "github", 
+        "image": "1f1f5-1f1fc.png", 
+        "unicode": "🇵🇼", 
+        "name": "Palau"
+    }, 
+    ":juggling-tone4:": {
+        "style": "github", 
+        "image": "1f939-1f3fe.png", 
+        "unicode": "🤹🏾", 
+        "name": "Juggling - Tone 4"
+    }, 
+    ":flag-zm:": {
+        "style": "github", 
+        "image": "1f1ff-1f1f2.png", 
+        "unicode": "🇿🇲", 
+        "name": "Zambia"
+    }, 
+    "=$": {
+        "style": "ascii", 
+        "ascii": ":$", 
+        "image": "1f633.png", 
+        "unicode": "😳", 
+        "name": "Flushed Face"
+    }, 
+    ":person_with_pouting_face_tone5:": {
+        "style": "github", 
+        "image": "1f64e-1f3ff.png", 
+        "unicode": "🙎🏿", 
+        "name": "Person With Pouting Face Tone5"
+    }, 
+    "=#": {
+        "style": "ascii", 
+        "ascii": ":-X", 
+        "image": "1f636.png", 
+        "unicode": "😶", 
+        "name": "Face Without Mouth"
+    }, 
+    "=/": {
+        "style": "ascii", 
+        "ascii": ">:\\", 
+        "image": "1f615.png", 
+        "unicode": "😕", 
+        "name": "Confused Face"
+    }, 
+    "=)": {
+        "style": "ascii", 
+        "ascii": ":)", 
+        "image": "1f642.png", 
+        "unicode": "🙂", 
+        "name": "Slightly Smiling Face"
+    }, 
+    "=(": {
+        "style": "ascii", 
+        "ascii": ">:[", 
+        "image": "1f61e.png", 
+        "unicode": "😞", 
+        "name": "Disappointed Face"
+    }, 
+    "=*": {
+        "style": "ascii", 
+        "ascii": ":*", 
+        "image": "1f618.png", 
+        "unicode": "😘", 
+        "name": "Face Throwing A Kiss"
+    }, 
+    ":battery:": {
+        "style": "github", 
+        "image": "1f50b.png", 
+        "unicode": "🔋", 
+        "name": "Battery"
+    }, 
+    "🍨": {
+        "style": "unicode", 
+        "image": "1f368.png", 
+        "name": "Ice Cream"
+    }, 
+    ":butterfly:": {
+        "style": "github", 
+        "image": "1f98b.png", 
+        "unicode": "🦋", 
+        "name": "Butterfly"
+    }, 
+    ":angel-tone3:": {
+        "style": "github", 
+        "image": "1f47c-1f3fd.png", 
+        "unicode": "👼🏽", 
+        "name": "Baby Angel - Tone 3"
+    }, 
+    "😇": {
+        "style": "unicode", 
+        "ascii": "O:-)", 
+        "image": "1f607.png", 
+        "name": "Smiling Face With Halo"
+    }, 
+    ":saudiarabia:": {
+        "style": "github", 
+        "image": "1f1f8-1f1e6.png", 
+        "unicode": "🇸🇦", 
+        "name": "Saudi Arabia"
+    }, 
+    ":nz:": {
+        "style": "github", 
+        "image": "1f1f3-1f1ff.png", 
+        "unicode": "🇳🇿", 
+        "name": "New Zealand"
+    }, 
+    ":flag_as:": {
+        "style": "github", 
+        "image": "1f1e6-1f1f8.png", 
+        "unicode": "🇦🇸", 
+        "name": "American Samoa"
+    }, 
+    "🚜": {
+        "style": "unicode", 
+        "image": "1f69c.png", 
+        "name": "Tractor"
+    }, 
+    ":regional_indicator_n:": {
+        "style": "github", 
+        "image": "1f1f3.png", 
+        "unicode": "🇳", 
+        "name": "Regional Indicator Symbol Letter N"
+    }, 
+    ":boy_tone4:": {
+        "style": "github", 
+        "image": "1f466-1f3fe.png", 
+        "unicode": "👦🏾", 
+        "name": "Boy - Tone 4"
+    }, 
+    "🔱": {
+        "style": "unicode", 
+        "image": "1f531.png", 
+        "name": "Trident Emblem"
+    }, 
+    "🌵": {
+        "style": "unicode", 
+        "image": "1f335.png", 
+        "name": "Cactus"
+    }, 
+    ":juggling_tone3:": {
+        "style": "github", 
+        "image": "1f939-1f3fd.png", 
+        "unicode": "🤹🏽", 
+        "name": "Juggling - Tone 3"
+    }, 
+    ":bicyclist_tone1:": {
+        "style": "github", 
+        "image": "1f6b4-1f3fb.png", 
+        "unicode": "🚴🏻", 
+        "name": "Bicyclist - Tone 1"
+    }, 
+    ":flag-eh:": {
+        "style": "github", 
+        "image": "1f1ea-1f1ed.png", 
+        "unicode": "🇪🇭", 
+        "name": "Western Sahara"
+    }, 
+    "🏊": {
+        "style": "unicode", 
+        "image": "1f3ca.png", 
+        "name": "Swimmer"
+    }, 
+    ":ok-hand:": {
+        "style": "github", 
+        "image": "1f44c.png", 
+        "unicode": "👌", 
+        "name": "Ok Hand Sign"
+    }, 
+    "👛": {
+        "style": "unicode", 
+        "image": "1f45b.png", 
+        "name": "Purse"
+    }, 
+    ":boar:": {
+        "style": "github", 
+        "image": "1f417.png", 
+        "unicode": "🐗", 
+        "name": "Boar"
+    }, 
+    ":tuxedo_tone5:": {
+        "style": "github", 
+        "image": "1f935-1f3ff.png", 
+        "unicode": "🤵🏿", 
+        "name": "Man In Tuxedo - Tone 5"
+    }, 
+    "📰": {
+        "style": "unicode", 
+        "image": "1f4f0.png", 
+        "name": "Newspaper"
+    }, 
+    "💇🏽": {
+        "style": "unicode", 
+        "image": "1f487-1f3fd.png", 
+        "name": "Haircut - Tone 3"
+    }, 
+    ":bellhop_bell:": {
+        "style": "github", 
+        "image": "1f6ce.png", 
+        "unicode": "🛎", 
+        "name": "Bellhop Bell"
+    }, 
+    "💇🏻": {
+        "style": "unicode", 
+        "image": "1f487-1f3fb.png", 
+        "name": "Haircut - Tone 1"
+    }, 
+    ":flag-cv:": {
+        "style": "github", 
+        "image": "1f1e8-1f1fb.png", 
+        "unicode": "🇨🇻", 
+        "name": "Cape Verde"
+    }, 
+    ":bangbang:": {
+        "style": "github", 
+        "image": "203c.png", 
+        "unicode": "‼", 
+        "name": "Double Exclamation Mark"
+    }, 
+    ":bookmark:": {
+        "style": "github", 
+        "image": "1f516.png", 
+        "unicode": "🔖", 
+        "name": "Bookmark"
+    }, 
+    "©": {
+        "style": "unicode", 
+        "image": "00a9.png", 
+        "name": "Copyright Sign"
+    }, 
+    "👋🏾": {
+        "style": "unicode", 
+        "image": "1f44b-1f3fe.png", 
+        "name": "Waving Hand Sign - Tone 4"
+    }, 
+    ":massage:": {
+        "style": "github", 
+        "image": "1f486.png", 
+        "unicode": "💆", 
+        "name": "Face Massage"
+    }, 
+    "⚽": {
+        "style": "unicode", 
+        "image": "26bd.png", 
+        "name": "Soccer Ball"
+    }, 
+    ":shell:": {
+        "style": "github", 
+        "image": "1f41a.png", 
+        "unicode": "🐚", 
+        "name": "Spiral Shell"
+    }, 
+    ":hole:": {
+        "style": "github", 
+        "image": "1f573.png", 
+        "unicode": "🕳", 
+        "name": "Hole"
+    }, 
+    ":headphones:": {
+        "style": "github", 
+        "image": "1f3a7.png", 
+        "unicode": "🎧", 
+        "name": "Headphone"
+    }, 
+    ":black-square-button:": {
+        "style": "github", 
+        "image": "1f532.png", 
+        "unicode": "🔲", 
+        "name": "Black Square Button"
+    }, 
+    ":flag_be:": {
+        "style": "github", 
+        "image": "1f1e7-1f1ea.png", 
+        "unicode": "🇧🇪", 
+        "name": "Belgium"
+    }, 
+    ":mailbox-with-no-mail:": {
+        "style": "github", 
+        "image": "1f4ed.png", 
+        "unicode": "📭", 
+        "name": "Open Mailbox With Lowered Flag"
+    }, 
+    ":open_hands_tone4:": {
+        "style": "github", 
+        "image": "1f450-1f3fe.png", 
+        "unicode": "👐🏾", 
+        "name": "Open Hands Sign - Tone 4"
+    }, 
+    "🐑": {
+        "style": "unicode", 
+        "image": "1f411.png", 
+        "name": "Sheep"
+    }, 
+    "♒": {
+        "style": "unicode", 
+        "image": "2652.png", 
+        "name": "Aquarius"
+    }, 
+    ":movie-camera:": {
+        "style": "github", 
+        "image": "1f3a5.png", 
+        "unicode": "🎥", 
+        "name": "Movie Camera"
+    }, 
+    ":us:": {
+        "style": "github", 
+        "image": "1f1fa-1f1f8.png", 
+        "unicode": "🇺🇸", 
+        "name": "United States"
+    }, 
+    ":poop:": {
+        "style": "github", 
+        "image": "1f4a9.png", 
+        "unicode": "💩", 
+        "name": "Pile Of Poo"
+    }, 
+    ":no-mouth:": {
+        "style": "github", 
+        "ascii": ":-X", 
+        "image": "1f636.png", 
+        "unicode": "😶", 
+        "name": "Face Without Mouth"
+    }, 
+    ":thunder-cloud-rain:": {
+        "style": "github", 
+        "image": "26c8.png", 
+        "unicode": "⛈", 
+        "name": "Thunder Cloud And Rain"
+    }, 
+    ":metal_tone5:": {
+        "style": "github", 
+        "image": "1f918-1f3ff.png", 
+        "unicode": "🤘🏿", 
+        "name": "Sign Of The Horns - Tone 5"
+    }, 
+    "x-p": {
+        "style": "ascii", 
+        "ascii": ">:P", 
+        "image": "1f61c.png", 
+        "unicode": "😜", 
+        "name": "Face With Stuck-out Tongue And Winking Eye"
+    }, 
+    ":ferris-wheel:": {
+        "style": "github", 
+        "image": "1f3a1.png", 
+        "unicode": "🎡", 
+        "name": "Ferris Wheel"
+    }, 
+    ":vhs:": {
+        "style": "github", 
+        "image": "1f4fc.png", 
+        "unicode": "📼", 
+        "name": "Videocassette"
+    }, 
+    ":fist_tone1:": {
+        "style": "github", 
+        "image": "270a-1f3fb.png", 
+        "unicode": "✊🏻", 
+        "name": "Raised Fist - Tone 1"
+    }, 
+    ":construction-worker-tone5:": {
+        "style": "github", 
+        "image": "1f477-1f3ff.png", 
+        "unicode": "👷🏿", 
+        "name": "Construction Worker - Tone 5"
+    }, 
+    ":thumbsup_tone4:": {
+        "style": "github", 
+        "image": "1f44d-1f3fe.png", 
+        "unicode": "👍🏾", 
+        "name": "Thumbs Up Sign - Tone 4"
+    }, 
+    "</3": {
+        "style": "ascii", 
+        "ascii": "</3", 
+        "image": "1f494.png", 
+        "unicode": "💔", 
+        "name": "Broken Heart"
+    }, 
+    "-___-": {
+        "style": "ascii", 
+        "ascii": "-_-", 
+        "image": "1f611.png", 
+        "unicode": "😑", 
+        "name": "Expressionless Face"
+    }, 
+    ":angel-tone2:": {
+        "style": "github", 
+        "image": "1f47c-1f3fc.png", 
+        "unicode": "👼🏼", 
+        "name": "Baby Angel - Tone 2"
+    }, 
+    "🐱": {
+        "style": "unicode", 
+        "image": "1f431.png", 
+        "name": "Cat Face"
+    }, 
+    ":flag-at:": {
+        "style": "github", 
+        "image": "1f1e6-1f1f9.png", 
+        "unicode": "🇦🇹", 
+        "name": "Austria"
+    }, 
+    "🈵": {
+        "style": "unicode", 
+        "image": "1f235.png", 
+        "name": "Squared Cjk Unified Ideograph-6e80"
+    }, 
+    ":page-facing-up:": {
+        "style": "github", 
+        "image": "1f4c4.png", 
+        "unicode": "📄", 
+        "name": "Page Facing Up"
+    }, 
+    "🕊": {
+        "style": "unicode", 
+        "image": "1f54a.png", 
+        "name": "Dove Of Peace"
+    }, 
+    "📆": {
+        "style": "unicode", 
+        "image": "1f4c6.png", 
+        "name": "Tear-off Calendar"
+    }, 
+    ":fearful:": {
+        "style": "github", 
+        "ascii": "D:", 
+        "image": "1f628.png", 
+        "unicode": "😨", 
+        "name": "Fearful Face"
+    }, 
+    ":carrot:": {
+        "style": "github", 
+        "image": "1f955.png", 
+        "unicode": "🥕", 
+        "name": "Carrot"
+    }, 
+    "🕛": {
+        "style": "unicode", 
+        "image": "1f55b.png", 
+        "name": "Clock Face Twelve Oclock"
+    }, 
+    "🍟": {
+        "style": "unicode", 
+        "image": "1f35f.png", 
+        "name": "French Fries"
+    }, 
+    ":right_facing_fist_tone4:": {
+        "style": "github", 
+        "image": "1f91c-1f3fe.png", 
+        "unicode": "🤜🏾", 
+        "name": "Right Facing Fist - Tone 4"
+    }, 
+    "🏴": {
+        "style": "unicode", 
+        "image": "1f3f4.png", 
+        "name": "Waving Black Flag"
+    }, 
+    ":mc:": {
+        "style": "github", 
+        "image": "1f1f2-1f1e8.png", 
+        "unicode": "🇲🇨", 
+        "name": "Monaco"
+    }, 
+    "🦅": {
+        "style": "unicode", 
+        "image": "1f985.png", 
+        "name": "Eagle"
+    }, 
+    "🎉": {
+        "style": "unicode", 
+        "image": "1f389.png", 
+        "name": "Party Popper"
+    }, 
+    "🤚": {
+        "style": "unicode", 
+        "image": "1f91a.png", 
+        "name": "Raised Back Of Hand"
+    }, 
+    ":no_pedestrians:": {
+        "style": "github", 
+        "image": "1f6b7.png", 
+        "unicode": "🚷", 
+        "name": "No Pedestrians"
+    }, 
+    "🌞": {
+        "style": "unicode", 
+        "image": "1f31e.png", 
+        "name": "Sun With Face"
+    }, 
+    ":m:": {
+        "style": "github", 
+        "image": "24c2.png", 
+        "unicode": "Ⓜ", 
+        "name": "Circled Latin Capital Letter M"
+    }, 
+    ":stopwatch:": {
+        "style": "github", 
+        "image": "23f1.png", 
+        "unicode": "⏱", 
+        "name": "Stopwatch"
+    }, 
+    ":heavy-minus-sign:": {
+        "style": "github", 
+        "image": "2796.png", 
+        "unicode": "➖", 
+        "name": "Heavy Minus Sign"
+    }, 
+    ":sagittarius:": {
+        "style": "github", 
+        "image": "2650.png", 
+        "unicode": "♐", 
+        "name": "Sagittarius"
+    }, 
+    ":call_me_tone4:": {
+        "style": "github", 
+        "image": "1f919-1f3fe.png", 
+        "unicode": "🤙🏾", 
+        "name": "Call Me Hand - Tone 4"
+    }, 
+    ":tt:": {
+        "style": "github", 
+        "image": "1f1f9-1f1f9.png", 
+        "unicode": "🇹🇹", 
+        "name": "Trinidad And Tobago"
+    }, 
+    ":lipstick:": {
+        "style": "github", 
+        "image": "1f484.png", 
+        "unicode": "💄", 
+        "name": "Lipstick"
+    }, 
+    ":eject:": {
+        "style": "github", 
+        "image": "23cf.png", 
+        "unicode": "⏏", 
+        "name": "Eject Symbol"
+    }, 
+    "🗝": {
+        "style": "unicode", 
+        "image": "1f5dd.png", 
+        "name": "Old Key"
+    }, 
+    ":open-hands-tone1:": {
+        "style": "github", 
+        "image": "1f450-1f3fb.png", 
+        "unicode": "👐🏻", 
+        "name": "Open Hands Sign - Tone 1"
+    }, 
+    ":flag-nl:": {
+        "style": "github", 
+        "image": "1f1f3-1f1f1.png", 
+        "unicode": "🇳🇱", 
+        "name": "The Netherlands"
+    }, 
+    ":arrow_lower_right:": {
+        "style": "github", 
+        "image": "2198.png", 
+        "unicode": "↘", 
+        "name": "South East Arrow"
+    }, 
+    ":shopping-bags:": {
+        "style": "github", 
+        "image": "1f6cd.png", 
+        "unicode": "🛍", 
+        "name": "Shopping Bags"
+    }, 
+    ":art:": {
+        "style": "github", 
+        "image": "1f3a8.png", 
+        "unicode": "🎨", 
+        "name": "Artist Palette"
+    }, 
+    "🐇": {
+        "style": "unicode", 
+        "image": "1f407.png", 
+        "name": "Rabbit"
+    }, 
+    ":regional_indicator_i:": {
+        "style": "github", 
+        "image": "1f1ee.png", 
+        "unicode": "🇮", 
+        "name": "Regional Indicator Symbol Letter I"
+    }, 
+    ":nose_tone5:": {
+        "style": "github", 
+        "image": "1f443-1f3ff.png", 
+        "unicode": "👃🏿", 
+        "name": "Nose - Tone 5"
+    }, 
+    ":lifter_tone2:": {
+        "style": "github", 
+        "image": "1f3cb-1f3fc.png", 
+        "unicode": "🏋🏼", 
+        "name": "Weight Lifter - Tone 2"
+    }, 
+    ":purple_heart:": {
+        "style": "github", 
+        "image": "1f49c.png", 
+        "unicode": "💜", 
+        "name": "Purple Heart"
+    }, 
+    "💜": {
+        "style": "unicode", 
+        "image": "1f49c.png", 
+        "name": "Purple Heart"
+    }, 
+    "↪": {
+        "style": "unicode", 
+        "image": "21aa.png", 
+        "name": "Rightwards Arrow With Hook"
+    }, 
+    ":sleuth_or_spy_tone5:": {
+        "style": "github", 
+        "image": "1f575-1f3ff.png", 
+        "unicode": "🕵🏿", 
+        "name": "Sleuth Or Spy - Tone 5"
+    }, 
+    ":white_circle:": {
+        "style": "github", 
+        "image": "26aa.png", 
+        "unicode": "⚪", 
+        "name": "Medium White Circle"
+    }, 
+    ":bs:": {
+        "style": "github", 
+        "image": "1f1e7-1f1f8.png", 
+        "unicode": "🇧🇸", 
+        "name": "The Bahamas"
+    }, 
+    ":point_right_tone1:": {
+        "style": "github", 
+        "image": "1f449-1f3fb.png", 
+        "unicode": "👉🏻", 
+        "name": "White Right Pointing Backhand Index - Tone 1"
+    }, 
+    ":metal-tone1:": {
+        "style": "github", 
+        "image": "1f918-1f3fb.png", 
+        "unicode": "🤘🏻", 
+        "name": "Sign Of The Horns - Tone 1"
+    }, 
+    ":ship:": {
+        "style": "github", 
+        "image": "1f6a2.png", 
+        "unicode": "🚢", 
+        "name": "Ship"
+    }, 
+    "🛰": {
+        "style": "unicode", 
+        "image": "1f6f0.png", 
+        "name": "Satellite"
+    }, 
+    ":ear_tone5:": {
+        "style": "github", 
+        "image": "1f442-1f3ff.png", 
+        "unicode": "👂🏿", 
+        "name": "Ear - Tone 5"
+    }, 
+    ":repeat:": {
+        "style": "github", 
+        "image": "1f501.png", 
+        "unicode": "🔁", 
+        "name": "Clockwise Rightwards And Leftwards Open Circle Arrows"
+    }, 
+    ":clock11:": {
+        "style": "github", 
+        "image": "1f55a.png", 
+        "unicode": "🕚", 
+        "name": "Clock Face Eleven Oclock"
+    }, 
+    ":walking-tone1:": {
+        "style": "github", 
+        "image": "1f6b6-1f3fb.png", 
+        "unicode": "🚶🏻", 
+        "name": "Pedestrian - Tone 1"
+    }, 
+    ":rice-cracker:": {
+        "style": "github", 
+        "image": "1f358.png", 
+        "unicode": "🍘", 
+        "name": "Rice Cracker"
+    }, 
+    ":put-litter-in-its-place:": {
+        "style": "github", 
+        "image": "1f6ae.png", 
+        "unicode": "🚮", 
+        "name": "Put Litter In Its Place Symbol"
+    }, 
+    ":older-woman-tone1:": {
+        "style": "github", 
+        "image": "1f475-1f3fb.png", 
+        "unicode": "👵🏻", 
+        "name": "Older Woman - Tone 1"
+    }, 
+    "⌨": {
+        "style": "unicode", 
+        "image": "2328.png", 
+        "name": "Keyboard"
+    }, 
+    ":ok-woman-tone2:": {
+        "style": "github", 
+        "image": "1f646-1f3fc.png", 
+        "unicode": "🙆🏼", 
+        "name": "Face With Ok Gesture Tone2"
+    }, 
+    "🎳": {
+        "style": "unicode", 
+        "image": "1f3b3.png", 
+        "name": "Bowling"
+    }, 
+    ":flag_tr:": {
+        "style": "github", 
+        "image": "1f1f9-1f1f7.png", 
+        "unicode": "🇹🇷", 
+        "name": "Turkey"
+    }, 
+    "🥄": {
+        "style": "unicode", 
+        "image": "1f944.png", 
+        "name": "Spoon"
+    }, 
+    "🍈": {
+        "style": "unicode", 
+        "image": "1f348.png", 
+        "name": "Melon"
+    }, 
+    ":joy:": {
+        "style": "github", 
+        "ascii": ":')", 
+        "image": "1f602.png", 
+        "unicode": "😂", 
+        "name": "Face With Tears Of Joy"
+    }, 
+    ":aquarius:": {
+        "style": "github", 
+        "image": "2652.png", 
+        "unicode": "♒", 
+        "name": "Aquarius"
+    }, 
+    "📝": {
+        "style": "unicode", 
+        "image": "1f4dd.png", 
+        "name": "Memo"
+    }, 
+    ":flag-sk:": {
+        "style": "github", 
+        "image": "1f1f8-1f1f0.png", 
+        "unicode": "🇸🇰", 
+        "name": "Slovakia"
+    }, 
+    ":lizard:": {
+        "style": "github", 
+        "image": "1f98e.png", 
+        "unicode": "🦎", 
+        "name": "Lizard"
+    }, 
+    "👲": {
+        "style": "unicode", 
+        "image": "1f472.png", 
+        "name": "Man With Gua Pi Mao"
+    }, 
+    ":flag-vn:": {
+        "style": "github", 
+        "image": "1f1fb-1f1f3.png", 
+        "unicode": "🇻🇳", 
+        "name": "Vietnam"
+    }, 
+    ":hatching_chick:": {
+        "style": "github", 
+        "image": "1f423.png", 
+        "unicode": "🐣", 
+        "name": "Hatching Chick"
+    }, 
+    "🔇": {
+        "style": "unicode", 
+        "image": "1f507.png", 
+        "name": "Speaker With Cancellation Stroke"
+    }, 
+    "☑": {
+        "style": "unicode", 
+        "image": "2611.png", 
+        "name": "Ballot Box With Check"
+    }, 
+    ":flag-me:": {
+        "style": "github", 
+        "image": "1f1f2-1f1ea.png", 
+        "unicode": "🇲🇪", 
+        "name": "Montenegro"
+    }, 
+    ":pregnant_woman_tone4:": {
+        "style": "github", 
+        "image": "1f930-1f3fe.png", 
+        "unicode": "🤰🏾", 
+        "name": "Pregnant Woman - Tone 4"
+    }, 
+    ":flag-gg:": {
+        "style": "github", 
+        "image": "1f1ec-1f1ec.png", 
+        "unicode": "🇬🇬", 
+        "name": "Guernsey"
+    }, 
+    ":kissing_cat:": {
+        "style": "github", 
+        "image": "1f63d.png", 
+        "unicode": "😽", 
+        "name": "Kissing Cat Face With Closed Eyes"
+    }, 
+    ":haircut_tone4:": {
+        "style": "github", 
+        "image": "1f487-1f3fe.png", 
+        "unicode": "💇🏾", 
+        "name": "Haircut - Tone 4"
+    }, 
+    ":cloud_with_lightning:": {
+        "style": "github", 
+        "image": "1f329.png", 
+        "unicode": "🌩", 
+        "name": "Cloud With Lightning"
+    }, 
+    "😱": {
+        "style": "unicode", 
+        "image": "1f631.png", 
+        "name": "Face Screaming In Fear"
+    }, 
+    ":clap_tone3:": {
+        "style": "github", 
+        "image": "1f44f-1f3fd.png", 
+        "unicode": "👏🏽", 
+        "name": "Clapping Hands Sign - Tone 3"
+    }, 
+    ":point-right-tone4:": {
+        "style": "github", 
+        "image": "1f449-1f3fe.png", 
+        "unicode": "👉🏾", 
+        "name": "White Right Pointing Backhand Index - Tone 4"
+    }, 
+    ":surfer_tone2:": {
+        "style": "github", 
+        "image": "1f3c4-1f3fc.png", 
+        "unicode": "🏄🏼", 
+        "name": "Surfer - Tone 2"
+    }, 
+    ":frame_with_picture:": {
+        "style": "github", 
+        "image": "1f5bc.png", 
+        "unicode": "🖼", 
+        "name": "Frame With Picture"
+    }, 
+    ":timer_clock:": {
+        "style": "github", 
+        "image": "23f2.png", 
+        "unicode": "⏲", 
+        "name": "Timer Clock"
+    }, 
+    ":right-facing-fist-tone5:": {
+        "style": "github", 
+        "image": "1f91c-1f3ff.png", 
+        "unicode": "🤜🏿", 
+        "name": "Right Facing Fist - Tone 5"
+    }, 
+    ":flag-eu:": {
+        "style": "github", 
+        "image": "1f1ea-1f1fa.png", 
+        "unicode": "🇪🇺", 
+        "name": "European Union"
+    }, 
+    ":mountain_bicyclist_tone3:": {
+        "style": "github", 
+        "image": "1f6b5-1f3fd.png", 
+        "unicode": "🚵🏽", 
+        "name": "Mountain Bicyclist - Tone 3"
+    }, 
+    ":compression:": {
+        "style": "github", 
+        "image": "1f5dc.png", 
+        "unicode": "🗜", 
+        "name": "Compression"
+    }, 
+    "🇴": {
+        "style": "unicode", 
+        "image": "1f1f4.png", 
+        "name": "Regional Indicator Symbol Letter O"
+    }, 
+    ":imp:": {
+        "style": "github", 
+        "image": "1f47f.png", 
+        "unicode": "👿", 
+        "name": "Imp"
+    }, 
+    ":pray_tone3:": {
+        "style": "github", 
+        "image": "1f64f-1f3fd.png", 
+        "unicode": "🙏🏽", 
+        "name": "Person With Folded Hands - Tone 3"
+    }, 
+    ":large_blue_diamond:": {
+        "style": "github", 
+        "image": "1f537.png", 
+        "unicode": "🔷", 
+        "name": "Large Blue Diamond"
+    }, 
+    ":raised-hand:": {
+        "style": "github", 
+        "image": "270b.png", 
+        "unicode": "✋", 
+        "name": "Raised Hand"
+    }, 
+    ":flag-la:": {
+        "style": "github", 
+        "image": "1f1f1-1f1e6.png", 
+        "unicode": "🇱🇦", 
+        "name": "Laos"
+    }, 
+    "☄": {
+        "style": "unicode", 
+        "image": "2604.png", 
+        "name": "Comet"
+    }, 
+    ":flag-fo:": {
+        "style": "github", 
+        "image": "1f1eb-1f1f4.png", 
+        "unicode": "🇫🇴", 
+        "name": "Faroe Islands"
+    }, 
+    "🔎": {
+        "style": "unicode", 
+        "image": "1f50e.png", 
+        "name": "Right-pointing Magnifying Glass"
+    }, 
+    ":flag_gp:": {
+        "style": "github", 
+        "image": "1f1ec-1f1f5.png", 
+        "unicode": "🇬🇵", 
+        "name": "Guadeloupe"
+    }, 
+    "💣": {
+        "style": "unicode", 
+        "image": "1f4a3.png", 
+        "name": "Bomb"
+    }, 
+    ":flag-sl:": {
+        "style": "github", 
+        "image": "1f1f8-1f1f1.png", 
+        "unicode": "🇸🇱", 
+        "name": "Sierra Leone"
+    }, 
+    ":dart:": {
+        "style": "github", 
+        "image": "1f3af.png", 
+        "unicode": "🎯", 
+        "name": "Direct Hit"
+    }, 
+    "🐸": {
+        "style": "unicode", 
+        "image": "1f438.png", 
+        "name": "Frog Face"
+    }, 
+    "🏍": {
+        "style": "unicode", 
+        "image": "1f3cd.png", 
+        "name": "Racing Motorcycle"
+    }, 
+    ":black_heart:": {
+        "style": "github", 
+        "image": "1f5a4.png", 
+        "unicode": "🖤", 
+        "name": "Black Heart"
+    }, 
+    ":scream-cat:": {
+        "style": "github", 
+        "image": "1f640.png", 
+        "unicode": "🙀", 
+        "name": "Weary Cat Face"
+    }, 
+    "🍢": {
+        "style": "unicode", 
+        "image": "1f362.png", 
+        "name": "Oden"
+    }, 
+    ":flag_ws:": {
+        "style": "github", 
+        "image": "1f1fc-1f1f8.png", 
+        "unicode": "🇼🇸", 
+        "name": "Samoa"
+    }, 
+    ":thought_balloon:": {
+        "style": "github", 
+        "image": "1f4ad.png", 
+        "unicode": "💭", 
+        "name": "Thought Balloon"
+    }, 
+    ":leo:": {
+        "style": "github", 
+        "image": "264c.png", 
+        "unicode": "♌", 
+        "name": "Leo"
+    }, 
+    ":question:": {
+        "style": "github", 
+        "image": "2753.png", 
+        "unicode": "❓", 
+        "name": "Black Question Mark Ornament"
+    }, 
+    ":spy-tone5:": {
+        "style": "github", 
+        "image": "1f575-1f3ff.png", 
+        "unicode": "🕵🏿", 
+        "name": "Sleuth Or Spy - Tone 5"
+    }, 
+    ":information_desk_person_tone1:": {
+        "style": "github", 
+        "image": "1f481-1f3fb.png", 
+        "unicode": "💁🏻", 
+        "name": "Information Desk Person - Tone 1"
+    }, 
+    "🇩🇿": {
+        "style": "unicode", 
+        "image": "1f1e9-1f1ff.png", 
+        "name": "Algeria"
+    }, 
+    "🇩🇰": {
+        "style": "unicode", 
+        "image": "1f1e9-1f1f0.png", 
+        "name": "Denmark"
+    }, 
+    "🇩🇲": {
+        "style": "unicode", 
+        "image": "1f1e9-1f1f2.png", 
+        "name": "Dominica"
+    }, 
+    ":wrestlers-tone1:": {
+        "style": "github", 
+        "image": "1f93c-1f3fb.png", 
+        "unicode": "🤼🏻", 
+        "name": "Wrestlers - Tone 1"
+    }, 
+    "🇩🇴": {
+        "style": "unicode", 
+        "image": "1f1e9-1f1f4.png", 
+        "name": "The Dominican Republic"
+    }, 
+    "🇩🇪": {
+        "style": "unicode", 
+        "image": "1f1e9-1f1ea.png", 
+        "name": "Germany"
+    }, 
+    "🇩🇬": {
+        "style": "unicode", 
+        "image": "1f1e9-1f1ec.png", 
+        "name": "Diego Garcia"
+    }, 
+    "🇩🇯": {
+        "style": "unicode", 
+        "image": "1f1e9-1f1ef.png", 
+        "name": "Djibouti"
+    }, 
+    ":label:": {
+        "style": "github", 
+        "image": "1f3f7.png", 
+        "unicode": "🏷", 
+        "name": "Label"
+    }, 
+    ":congo:": {
+        "style": "github", 
+        "image": "1f1e8-1f1e9.png", 
+        "unicode": "🇨🇩", 
+        "name": "The Democratic Republic Of The Congo"
+    }, 
+    ":regional-indicator-t:": {
+        "style": "github", 
+        "image": "1f1f9.png", 
+        "unicode": "🇹", 
+        "name": "Regional Indicator Symbol Letter T"
+    }, 
+    ":articulated-lorry:": {
+        "style": "github", 
+        "image": "1f69b.png", 
+        "unicode": "🚛", 
+        "name": "Articulated Lorry"
+    }, 
+    ":spiral_calendar_pad:": {
+        "style": "github", 
+        "image": "1f5d3.png", 
+        "unicode": "🗓", 
+        "name": "Spiral Calendar Pad"
+    }, 
+    ":congratulations:": {
+        "style": "github", 
+        "image": "3297.png", 
+        "unicode": "㊗", 
+        "name": "Circled Ideograph Congratulation"
+    }, 
+    ":left-facing-fist-tone3:": {
+        "style": "github", 
+        "image": "1f91b-1f3fd.png", 
+        "unicode": "🤛🏽", 
+        "name": "Left Facing Fist - Tone 3"
+    }, 
+    ":point_down_tone2:": {
+        "style": "github", 
+        "image": "1f447-1f3fc.png", 
+        "unicode": "👇🏼", 
+        "name": "White Down Pointing Backhand Index - Tone 2"
+    }, 
+    ":curly_loop:": {
+        "style": "github", 
+        "image": "27b0.png", 
+        "unicode": "➰", 
+        "name": "Curly Loop"
+    }, 
+    ":information-desk-person-tone3:": {
+        "style": "github", 
+        "image": "1f481-1f3fd.png", 
+        "unicode": "💁🏽", 
+        "name": "Information Desk Person - Tone 3"
+    }, 
+    ":rowboat_tone1:": {
+        "style": "github", 
+        "image": "1f6a3-1f3fb.png", 
+        "unicode": "🚣🏻", 
+        "name": "Rowboat - Tone 1"
+    }, 
+    "🙏": {
+        "style": "unicode", 
+        "image": "1f64f.png", 
+        "name": "Person With Folded Hands"
+    }, 
+    ":eight:": {
+        "style": "github", 
+        "image": "0038-20e3.png", 
+        "unicode": "8⃣", 
+        "name": "Keycap Digit Eight"
+    }, 
+    "🛤": {
+        "style": "unicode", 
+        "image": "1f6e4.png", 
+        "name": "Railway Track"
+    }, 
+    ":cool:": {
+        "style": "github", 
+        "image": "1f192.png", 
+        "unicode": "🆒", 
+        "name": "Squared Cool"
+    }, 
+    "🕹": {
+        "style": "unicode", 
+        "image": "1f579.png", 
+        "name": "Joystick"
+    }, 
+    ":construction_worker_tone2:": {
+        "style": "github", 
+        "image": "1f477-1f3fc.png", 
+        "unicode": "👷🏼", 
+        "name": "Construction Worker - Tone 2"
+    }, 
+    ":person_doing_cartwheel_tone2:": {
+        "style": "github", 
+        "image": "1f938-1f3fc.png", 
+        "unicode": "🤸🏼", 
+        "name": "Person Doing Cartwheel - Tone 2"
+    }, 
+    ":wheel_of_dharma:": {
+        "style": "github", 
+        "image": "2638.png", 
+        "unicode": "☸", 
+        "name": "Wheel Of Dharma"
+    }, 
+    ":raised_hand_with_part_between_middle_and_ring_fingers_tone4:": {
+        "style": "github", 
+        "image": "1f596-1f3fe.png", 
+        "unicode": "🖖🏾", 
+        "name": "Raised Hand With Part Between Middle And Ring Fingers - Tone 4"
+    }, 
+    ":angel-tone1:": {
+        "style": "github", 
+        "image": "1f47c-1f3fb.png", 
+        "unicode": "👼🏻", 
+        "name": "Baby Angel - Tone 1"
+    }, 
+    "🐎": {
+        "style": "unicode", 
+        "image": "1f40e.png", 
+        "name": "Horse"
+    }, 
+    ":snowman2:": {
+        "style": "github", 
+        "image": "2603.png", 
+        "unicode": "☃", 
+        "name": "Snowman"
+    }, 
+    ":flag_py:": {
+        "style": "github", 
+        "image": "1f1f5-1f1fe.png", 
+        "unicode": "🇵🇾", 
+        "name": "Paraguay"
+    }, 
+    ":regional_indicator_l:": {
+        "style": "github", 
+        "image": "1f1f1.png", 
+        "unicode": "🇱", 
+        "name": "Regional Indicator Symbol Letter L"
+    }, 
+    ":high_brightness:": {
+        "style": "github", 
+        "image": "1f506.png", 
+        "unicode": "🔆", 
+        "name": "High Brightness Symbol"
+    }, 
+    ":mountain_cableway:": {
+        "style": "github", 
+        "image": "1f6a0.png", 
+        "unicode": "🚠", 
+        "name": "Mountain Cableway"
+    }, 
+    ":dividers:": {
+        "style": "github", 
+        "image": "1f5c2.png", 
+        "unicode": "🗂", 
+        "name": "Card Index Dividers"
+    }, 
+    "🔸": {
+        "style": "unicode", 
+        "image": "1f538.png", 
+        "name": "Small Orange Diamond"
+    }, 
+    ":sk:": {
+        "style": "github", 
+        "image": "1f1f8-1f1f0.png", 
+        "unicode": "🇸🇰", 
+        "name": "Slovakia"
+    }, 
+    ":guitar:": {
+        "style": "github", 
+        "image": "1f3b8.png", 
+        "unicode": "🎸", 
+        "name": "Guitar"
+    }, 
+    "🏋🏻": {
+        "style": "unicode", 
+        "image": "1f3cb-1f3fb.png", 
+        "name": "Weight Lifter - Tone 1"
+    }, 
+    ":bicyclist_tone3:": {
+        "style": "github", 
+        "image": "1f6b4-1f3fd.png", 
+        "unicode": "🚴🏽", 
+        "name": "Bicyclist - Tone 3"
+    }, 
+    ":juggling_tone1:": {
+        "style": "github", 
+        "image": "1f939-1f3fb.png", 
+        "unicode": "🤹🏻", 
+        "name": "Juggling - Tone 1"
+    }, 
+    ":flag_co:": {
+        "style": "github", 
+        "image": "1f1e8-1f1f4.png", 
+        "unicode": "🇨🇴", 
+        "name": "Colombia"
+    }, 
+    "🏋🏾": {
+        "style": "unicode", 
+        "image": "1f3cb-1f3fe.png", 
+        "name": "Weight Lifter - Tone 4"
+    }, 
+    "🏋🏽": {
+        "style": "unicode", 
+        "image": "1f3cb-1f3fd.png", 
+        "name": "Weight Lifter - Tone 3"
+    }, 
+    "🏋🏼": {
+        "style": "unicode", 
+        "image": "1f3cb-1f3fc.png", 
+        "name": "Weight Lifter - Tone 2"
+    }, 
+    "🏷": {
+        "style": "unicode", 
+        "image": "1f3f7.png", 
+        "name": "Label"
+    }, 
+    ":point-left-tone5:": {
+        "style": "github", 
+        "image": "1f448-1f3ff.png", 
+        "unicode": "👈🏿", 
+        "name": "White Left Pointing Backhand Index - Tone 5"
+    }, 
+    ":arrow-heading-down:": {
+        "style": "github", 
+        "image": "2935.png", 
+        "unicode": "⤵", 
+        "name": "Arrow Pointing Rightwards Then Curving Downwards"
+    }, 
+    ":cat2:": {
+        "style": "github", 
+        "image": "1f408.png", 
+        "unicode": "🐈", 
+        "name": "Cat"
+    }, 
+    ":peace:": {
+        "style": "github", 
+        "image": "262e.png", 
+        "unicode": "☮", 
+        "name": "Peace Symbol"
+    }, 
+    ":flag_zw:": {
+        "style": "github", 
+        "image": "1f1ff-1f1fc.png", 
+        "unicode": "🇿🇼", 
+        "name": "Zimbabwe"
+    }, 
+    "9⃣": {
+        "style": "unicode", 
+        "image": "0039-20e3.png", 
+        "name": "Keycap Digit Nine"
+    }, 
+    "🎌": {
+        "style": "unicode", 
+        "image": "1f38c.png", 
+        "name": "Crossed Flags"
+    }, 
+    "🦐": {
+        "style": "unicode", 
+        "image": "1f990.png", 
+        "name": "Shrimp"
+    }, 
+    ":ws:": {
+        "style": "github", 
+        "image": "1f1fc-1f1f8.png", 
+        "unicode": "🇼🇸", 
+        "name": "Samoa"
+    }, 
+    ":wilted_flower:": {
+        "style": "github", 
+        "image": "1f940.png", 
+        "unicode": "🥀", 
+        "name": "Wilted Flower"
+    }, 
+    "😥": {
+        "style": "unicode", 
+        "image": "1f625.png", 
+        "name": "Disappointed But Relieved Face"
+    }, 
+    ":mountain_railway:": {
+        "style": "github", 
+        "image": "1f69e.png", 
+        "unicode": "🚞", 
+        "name": "Mountain Railway"
+    }, 
+    ":partly_sunny:": {
+        "style": "github", 
+        "image": "26c5.png", 
+        "unicode": "⛅", 
+        "name": "Sun Behind Cloud"
+    }, 
+    "🚺": {
+        "style": "unicode", 
+        "image": "1f6ba.png", 
+        "name": "Womens Symbol"
+    }, 
+    ":two-men-holding-hands:": {
+        "style": "github", 
+        "image": "1f46c.png", 
+        "unicode": "👬", 
+        "name": "Two Men Holding Hands"
+    }, 
+    ":punch_tone4:": {
+        "style": "github", 
+        "image": "1f44a-1f3fe.png", 
+        "unicode": "👊🏾", 
+        "name": "Fisted Hand Sign - Tone 4"
+    }, 
+    ":flag_bg:": {
+        "style": "github", 
+        "image": "1f1e7-1f1ec.png", 
+        "unicode": "🇧🇬", 
+        "name": "Bulgaria"
+    }, 
+    ":man-dancing:": {
+        "style": "github", 
+        "image": "1f57a.png", 
+        "unicode": "🕺", 
+        "name": "Man Dancing"
+    }, 
+    ":stuck-out-tongue-winking-eye:": {
+        "style": "github", 
+        "ascii": ">:P", 
+        "image": "1f61c.png", 
+        "unicode": "😜", 
+        "name": "Face With Stuck-out Tongue And Winking Eye"
+    }, 
+    ":om_symbol:": {
+        "style": "github", 
+        "image": "1f549.png", 
+        "unicode": "🕉", 
+        "name": "Om Symbol"
+    }, 
+    ":knife:": {
+        "style": "github", 
+        "image": "1f52a.png", 
+        "unicode": "🔪", 
+        "name": "Hocho"
+    }, 
+    ":roller-coaster:": {
+        "style": "github", 
+        "image": "1f3a2.png", 
+        "unicode": "🎢", 
+        "name": "Roller Coaster"
+    }, 
+    ":triangular_ruler:": {
+        "style": "github", 
+        "image": "1f4d0.png", 
+        "unicode": "📐", 
+        "name": "Triangular Ruler"
+    }, 
+    ":metal_tone3:": {
+        "style": "github", 
+        "image": "1f918-1f3fd.png", 
+        "unicode": "🤘🏽", 
+        "name": "Sign Of The Horns - Tone 3"
+    }, 
+    ":thumbsdown:": {
+        "style": "github", 
+        "image": "1f44e.png", 
+        "unicode": "👎", 
+        "name": "Thumbs Down Sign"
+    }, 
+    ":flag-cp:": {
+        "style": "github", 
+        "image": "1f1e8-1f1f5.png", 
+        "unicode": "🇨🇵", 
+        "name": "Clipperton Island"
+    }, 
+    "👹": {
+        "style": "unicode", 
+        "image": "1f479.png", 
+        "name": "Japanese Ogre"
+    }, 
+    ":broken_heart:": {
+        "style": "github", 
+        "ascii": "</3", 
+        "image": "1f494.png", 
+        "unicode": "💔", 
+        "name": "Broken Heart"
+    }, 
+    ":chocolate_bar:": {
+        "style": "github", 
+        "image": "1f36b.png", 
+        "unicode": "🍫", 
+        "name": "Chocolate Bar"
+    }, 
+    ":gs:": {
+        "style": "github", 
+        "image": "1f1ec-1f1f8.png", 
+        "unicode": "🇬🇸", 
+        "name": "South Georgia"
+    }, 
+    ":thumbsdown_tone2:": {
+        "style": "github", 
+        "image": "1f44e-1f3fc.png", 
+        "unicode": "👎🏼", 
+        "name": "Thumbs Down Sign - Tone 2"
+    }, 
+    "🤒": {
+        "style": "unicode", 
+        "image": "1f912.png", 
+        "name": "Face With Thermometer"
+    }, 
+    "🚣": {
+        "style": "unicode", 
+        "image": "1f6a3.png", 
+        "name": "Rowboat"
+    }, 
+    "😸": {
+        "style": "unicode", 
+        "image": "1f638.png", 
+        "name": "Grinning Cat Face With Smiling Eyes"
+    }, 
+    ":flag-az:": {
+        "style": "github", 
+        "image": "1f1e6-1f1ff.png", 
+        "unicode": "🇦🇿", 
+        "name": "Azerbaijan"
+    }, 
+    "🇨🇺": {
+        "style": "unicode", 
+        "image": "1f1e8-1f1fa.png", 
+        "name": "Cuba"
+    }, 
+    "🇨🇻": {
+        "style": "unicode", 
+        "image": "1f1e8-1f1fb.png", 
+        "name": "Cape Verde"
+    }, 
+    ":eu:": {
+        "style": "github", 
+        "image": "1f1ea-1f1fa.png", 
+        "unicode": "🇪🇺", 
+        "name": "European Union"
+    }, 
+    "🇨🇾": {
+        "style": "unicode", 
+        "image": "1f1e8-1f1fe.png", 
+        "name": "Cyprus"
+    }, 
+    ":flag_sh:": {
+        "style": "github", 
+        "image": "1f1f8-1f1ed.png", 
+        "unicode": "🇸🇭", 
+        "name": "Saint Helena"
+    }, 
+    "🇨🇼": {
+        "style": "unicode", 
+        "image": "1f1e8-1f1fc.png", 
+        "name": "Curaçao"
+    }, 
+    "🇨🇽": {
+        "style": "unicode", 
+        "image": "1f1e8-1f1fd.png", 
+        "name": "Christmas Island"
+    }, 
+    "🇨🇲": {
+        "style": "unicode", 
+        "image": "1f1e8-1f1f2.png", 
+        "name": "Cameroon"
+    }, 
+    "🇨🇳": {
+        "style": "unicode", 
+        "image": "1f1e8-1f1f3.png", 
+        "name": "China"
+    }, 
+    "🇨🇰": {
+        "style": "unicode", 
+        "image": "1f1e8-1f1f0.png", 
+        "name": "Cook Islands"
+    }, 
+    "🇨🇱": {
+        "style": "unicode", 
+        "image": "1f1e8-1f1f1.png", 
+        "name": "Chile"
+    }, 
+    ":peace_symbol:": {
+        "style": "github", 
+        "image": "262e.png", 
+        "unicode": "☮", 
+        "name": "Peace Symbol"
+    }, 
+    "🇨🇴": {
+        "style": "unicode", 
+        "image": "1f1e8-1f1f4.png", 
+        "name": "Colombia"
+    }, 
+    ":older_woman_tone4:": {
+        "style": "github", 
+        "image": "1f475-1f3fe.png", 
+        "unicode": "👵🏾", 
+        "name": "Older Woman - Tone 4"
+    }, 
+    "🇨🇫": {
+        "style": "unicode", 
+        "image": "1f1e8-1f1eb.png", 
+        "name": "Central African Republic"
+    }, 
+    "🇨🇨": {
+        "style": "unicode", 
+        "image": "1f1e8-1f1e8.png", 
+        "name": "Cocos (keeling) Islands"
+    }, 
+    "🇨🇩": {
+        "style": "unicode", 
+        "image": "1f1e8-1f1e9.png", 
+        "name": "The Democratic Republic Of The Congo"
+    }, 
+    "🇨🇮": {
+        "style": "unicode", 
+        "image": "1f1e8-1f1ee.png", 
+        "name": "Côte D’ivoire"
+    }, 
+    ":signal_strength:": {
+        "style": "github", 
+        "image": "1f4f6.png", 
+        "unicode": "📶", 
+        "name": "Antenna With Bars"
+    }, 
+    "🇨🇬": {
+        "style": "unicode", 
+        "image": "1f1e8-1f1ec.png", 
+        "name": "The Republic Of The Congo"
+    }, 
+    "🇨🇭": {
+        "style": "unicode", 
+        "image": "1f1e8-1f1ed.png", 
+        "name": "Switzerland"
+    }, 
+    "🇨🇦": {
+        "style": "unicode", 
+        "image": "1f1e8-1f1e6.png", 
+        "name": "Canada"
+    }, 
+    ":flag-bn:": {
+        "style": "github", 
+        "image": "1f1e7-1f1f3.png", 
+        "unicode": "🇧🇳", 
+        "name": "Brunei"
+    }, 
+    ":snowboarder:": {
+        "style": "github", 
+        "image": "1f3c2.png", 
+        "unicode": "🏂", 
+        "name": "Snowboarder"
+    }, 
+    ":reversed_hand_with_middle_finger_extended_tone5:": {
+        "style": "github", 
+        "image": "1f595-1f3ff.png", 
+        "unicode": "🖕🏿", 
+        "name": "Reversed Hand With Middle Finger Extended - Tone 5"
+    }, 
+    ":massage_tone3:": {
+        "style": "github", 
+        "image": "1f486-1f3fd.png", 
+        "unicode": "💆🏽", 
+        "name": "Face Massage - Tone 3"
+    }, 
+    ":chile:": {
+        "style": "github", 
+        "image": "1f1e8-1f1f1.png", 
+        "unicode": "🇨🇱", 
+        "name": "Chile"
+    }, 
+    ":fist_tone3:": {
+        "style": "github", 
+        "image": "270a-1f3fd.png", 
+        "unicode": "✊🏽", 
+        "name": "Raised Fist - Tone 3"
+    }, 
+    ":shrug_tone3:": {
+        "style": "github", 
+        "image": "1f937-1f3fd.png", 
+        "unicode": "🤷🏽", 
+        "name": "Shrug - Tone 3"
+    }, 
+    ":mailbox_with_no_mail:": {
+        "style": "github", 
+        "image": "1f4ed.png", 
+        "unicode": "📭", 
+        "name": "Open Mailbox With Lowered Flag"
+    }, 
+    ":man-dancing-tone4:": {
+        "style": "github", 
+        "image": "1f57a-1f3fe.png", 
+        "unicode": "🕺🏾", 
+        "name": "Man Dancing - Tone 4"
+    }, 
+    ":railway-track:": {
+        "style": "github", 
+        "image": "1f6e4.png", 
+        "unicode": "🛤", 
+        "name": "Railway Track"
+    }, 
+    "🌡": {
+        "style": "unicode", 
+        "image": "1f321.png", 
+        "name": "Thermometer"
+    }, 
+    ":flag_ki:": {
+        "style": "github", 
+        "image": "1f1f0-1f1ee.png", 
+        "unicode": "🇰🇮", 
+        "name": "Kiribati"
+    }, 
+    "🔥": {
+        "style": "unicode", 
+        "image": "1f525.png", 
+        "name": "Fire"
+    }, 
+    "🎶": {
+        "style": "unicode", 
+        "image": "1f3b6.png", 
+        "name": "Multiple Musical Notes"
+    }, 
+    ":older-woman:": {
+        "style": "github", 
+        "image": "1f475.png", 
+        "unicode": "👵", 
+        "name": "Older Woman"
+    }, 
+    ":cloud-snow:": {
+        "style": "github", 
+        "image": "1f328.png", 
+        "unicode": "🌨", 
+        "name": "Cloud With Snow"
+    }, 
+    ":minibus:": {
+        "style": "github", 
+        "image": "1f690.png", 
+        "unicode": "🚐", 
+        "name": "Minibus"
+    }, 
+    ":money-mouth:": {
+        "style": "github", 
+        "image": "1f911.png", 
+        "unicode": "🤑", 
+        "name": "Money-mouth Face"
+    }, 
+    ":tr:": {
+        "style": "github", 
+        "image": "1f1f9-1f1f7.png", 
+        "unicode": "🇹🇷", 
+        "name": "Turkey"
+    }, 
+    "👏": {
+        "style": "unicode", 
+        "image": "1f44f.png", 
+        "name": "Clapping Hands Sign"
+    }, 
+    ":thinking:": {
+        "style": "github", 
+        "image": "1f914.png", 
+        "unicode": "🤔", 
+        "name": "Thinking Face"
+    }, 
+    "📤": {
+        "style": "unicode", 
+        "image": "1f4e4.png", 
+        "name": "Outbox Tray"
+    }, 
+    ":bust-in-silhouette:": {
+        "style": "github", 
+        "image": "1f464.png", 
+        "unicode": "👤", 
+        "name": "Bust In Silhouette"
+    }, 
+    ":hospital:": {
+        "style": "github", 
+        "image": "1f3e5.png", 
+        "unicode": "🏥", 
+        "name": "Hospital"
+    }, 
+    ":books:": {
+        "style": "github", 
+        "image": "1f4da.png", 
+        "unicode": "📚", 
+        "name": "Books"
+    }, 
+    ":open-hands-tone3:": {
+        "style": "github", 
+        "image": "1f450-1f3fd.png", 
+        "unicode": "👐🏽", 
+        "name": "Open Hands Sign - Tone 3"
+    }, 
+    ":me:": {
+        "style": "github", 
+        "image": "1f1f2-1f1ea.png", 
+        "unicode": "🇲🇪", 
+        "name": "Montenegro"
+    }, 
+    ":cg:": {
+        "style": "github", 
+        "image": "1f1e8-1f1ec.png", 
+        "unicode": "🇨🇬", 
+        "name": "The Republic Of The Congo"
+    }, 
+    ":guardsman-tone5:": {
+        "style": "github", 
+        "image": "1f482-1f3ff.png", 
+        "unicode": "💂🏿", 
+        "name": "Guardsman - Tone 5"
+    }, 
+    ":green-book:": {
+        "style": "github", 
+        "image": "1f4d7.png", 
+        "unicode": "📗", 
+        "name": "Green Book"
+    }, 
+    ":pregnant-woman:": {
+        "style": "github", 
+        "image": "1f930.png", 
+        "unicode": "🤰", 
+        "name": "Pregnant Woman"
+    }, 
+    "😎": {
+        "style": "unicode", 
+        "ascii": "B-)", 
+        "image": "1f60e.png", 
+        "name": "Smiling Face With Sunglasses"
+    }, 
+    ":flag-fr:": {
+        "style": "github", 
+        "image": "1f1eb-1f1f7.png", 
+        "unicode": "🇫🇷", 
+        "name": "France"
+    }, 
+    ":nose_tone3:": {
+        "style": "github", 
+        "image": "1f443-1f3fd.png", 
+        "unicode": "👃🏽", 
+        "name": "Nose - Tone 3"
+    }, 
+    ":tent:": {
+        "style": "github", 
+        "image": "26fa.png", 
+        "unicode": "⛺", 
+        "name": "Tent"
+    }, 
+    "⚙": {
+        "style": "unicode", 
+        "image": "2699.png", 
+        "name": "Gear"
+    }, 
+    ":sunrise:": {
+        "style": "github", 
+        "image": "1f305.png", 
+        "unicode": "🌅", 
+        "name": "Sunrise"
+    }, 
+    ":key:": {
+        "style": "github", 
+        "image": "1f511.png", 
+        "unicode": "🔑", 
+        "name": "Key"
+    }, 
+    ":black_nib:": {
+        "style": "github", 
+        "image": "2712.png", 
+        "unicode": "✒", 
+        "name": "Black Nib"
+    }, 
+    "☮": {
+        "style": "unicode", 
+        "image": "262e.png", 
+        "name": "Peace Symbol"
+    }, 
+    ":ambulance:": {
+        "style": "github", 
+        "image": "1f691.png", 
+        "unicode": "🚑", 
+        "name": "Ambulance"
+    }, 
+    "🤼": {
+        "style": "unicode", 
+        "image": "1f93c.png", 
+        "name": "Wrestlers"
+    }, 
+    ":no_good_tone1:": {
+        "style": "github", 
+        "image": "1f645-1f3fb.png", 
+        "unicode": "🙅🏻", 
+        "name": "Face With No Good Gesture - Tone 1"
+    }, 
+    ":accept:": {
+        "style": "github", 
+        "image": "1f251.png", 
+        "unicode": "🉑", 
+        "name": "Circled Ideograph Accept"
+    }, 
+    ":flag_om:": {
+        "style": "github", 
+        "image": "1f1f4-1f1f2.png", 
+        "unicode": "🇴🇲", 
+        "name": "Oman"
+    }, 
+    ":pen-ballpoint:": {
+        "style": "github", 
+        "image": "1f58a.png", 
+        "unicode": "🖊", 
+        "name": "Lower Left Ballpoint Pen"
+    }, 
+    "🚶🏻": {
+        "style": "unicode", 
+        "image": "1f6b6-1f3fb.png", 
+        "name": "Pedestrian - Tone 1"
+    }, 
+    "🚶🏼": {
+        "style": "unicode", 
+        "image": "1f6b6-1f3fc.png", 
+        "name": "Pedestrian - Tone 2"
+    }, 
+    "🚶🏽": {
+        "style": "unicode", 
+        "image": "1f6b6-1f3fd.png", 
+        "name": "Pedestrian - Tone 3"
+    }, 
+    ":metal-tone3:": {
+        "style": "github", 
+        "image": "1f918-1f3fd.png", 
+        "unicode": "🤘🏽", 
+        "name": "Sign Of The Horns - Tone 3"
+    }, 
+    "🚶🏿": {
+        "style": "unicode", 
+        "image": "1f6b6-1f3ff.png", 
+        "name": "Pedestrian - Tone 5"
+    }, 
+    ":ram:": {
+        "style": "github", 
+        "image": "1f40f.png", 
+        "unicode": "🐏", 
+        "name": "Ram"
+    }, 
+    ":sos:": {
+        "style": "github", 
+        "image": "1f198.png", 
+        "unicode": "🆘", 
+        "name": "Squared Sos"
+    }, 
+    "🇷": {
+        "style": "unicode", 
+        "image": "1f1f7.png", 
+        "name": "Regional Indicator Symbol Letter R"
+    }, 
+    "🙇🏽": {
+        "style": "unicode", 
+        "image": "1f647-1f3fd.png", 
+        "name": "Person Bowing Deeply - Tone 3"
+    }, 
+    ":family_mmbb:": {
+        "style": "github", 
+        "image": "1f468-1f468-1f466-1f466.png", 
+        "unicode": "👨👨👦👦", 
+        "name": "Family (man,man,boy,boy)"
+    }, 
+    ":golfer:": {
+        "style": "github", 
+        "image": "1f3cc.png", 
+        "unicode": "🏌", 
+        "name": "Golfer"
+    }, 
+    ":restroom:": {
+        "style": "github", 
+        "image": "1f6bb.png", 
+        "unicode": "🚻", 
+        "name": "Restroom"
+    }, 
+    "⬛": {
+        "style": "unicode", 
+        "image": "2b1b.png", 
+        "name": "Black Large Square"
+    }, 
+    "🐥": {
+        "style": "unicode", 
+        "image": "1f425.png", 
+        "name": "Front-facing Baby Chick"
+    }, 
+    ":pause_button:": {
+        "style": "github", 
+        "image": "23f8.png", 
+        "unicode": "⏸", 
+        "name": "Double Vertical Bar"
+    }, 
+    "💺": {
+        "style": "unicode", 
+        "image": "1f4ba.png", 
+        "name": "Seat"
+    }, 
+    "🍋": {
+        "style": "unicode", 
+        "image": "1f34b.png", 
+        "name": "Lemon"
+    }, 
+    ":lifter-tone4:": {
+        "style": "github", 
+        "image": "1f3cb-1f3fe.png", 
+        "unicode": "🏋🏾", 
+        "name": "Weight Lifter - Tone 4"
+    }, 
+    "🏠": {
+        "style": "unicode", 
+        "image": "1f3e0.png", 
+        "name": "House Building"
+    }, 
+    ":part-alternation-mark:": {
+        "style": "github", 
+        "image": "303d.png", 
+        "unicode": "〽", 
+        "name": "Part Alternation Mark"
+    }, 
+    ":walking-tone3:": {
+        "style": "github", 
+        "image": "1f6b6-1f3fd.png", 
+        "unicode": "🚶🏽", 
+        "name": "Pedestrian - Tone 3"
+    }, 
+    ":sz:": {
+        "style": "github", 
+        "image": "1f1f8-1f1ff.png", 
+        "unicode": "🇸🇿", 
+        "name": "Swaziland"
+    }, 
+    ":white_sun_small_cloud:": {
+        "style": "github", 
+        "image": "1f324.png", 
+        "unicode": "🌤", 
+        "name": "White Sun With Small Cloud"
+    }, 
+    ":pregnant_woman_tone2:": {
+        "style": "github", 
+        "image": "1f930-1f3fc.png", 
+        "unicode": "🤰🏼", 
+        "name": "Pregnant Woman - Tone 2"
+    }, 
+    "d:": {
+        "style": "ascii", 
+        "ascii": ":P", 
+        "image": "1f61b.png", 
+        "unicode": "😛", 
+        "name": "Face With Stuck-out Tongue"
+    }, 
+    ":world_map:": {
+        "style": "github", 
+        "image": "1f5fa.png", 
+        "unicode": "🗺", 
+        "name": "World Map"
+    }, 
+    ":flag-gi:": {
+        "style": "github", 
+        "image": "1f1ec-1f1ee.png", 
+        "unicode": "🇬🇮", 
+        "name": "Gibraltar"
+    }, 
+    ":na:": {
+        "style": "github", 
+        "image": "1f1f3-1f1e6.png", 
+        "unicode": "🇳🇦", 
+        "name": "Namibia"
+    }, 
+    ":clap_tone5:": {
+        "style": "github", 
+        "image": "1f44f-1f3ff.png", 
+        "unicode": "👏🏿", 
+        "name": "Clapping Hands Sign - Tone 5"
+    }, 
+    ":drooling-face:": {
+        "style": "github", 
+        "image": "1f924.png", 
+        "unicode": "🤤", 
+        "name": "Drooling Face"
+    }, 
+    ":sleepy:": {
+        "style": "github", 
+        "image": "1f62a.png", 
+        "unicode": "😪", 
+        "name": "Sleepy Face"
+    }, 
+    ":yin-yang:": {
+        "style": "github", 
+        "image": "262f.png", 
+        "unicode": "☯", 
+        "name": "Yin Yang"
+    }, 
+    ":steam_locomotive:": {
+        "style": "github", 
+        "image": "1f682.png", 
+        "unicode": "🚂", 
+        "name": "Steam Locomotive"
+    }, 
+    ":flag-es:": {
+        "style": "github", 
+        "image": "1f1ea-1f1f8.png", 
+        "unicode": "🇪🇸", 
+        "name": "Spain"
+    }, 
+    ":asterisk:": {
+        "style": "github", 
+        "image": "002a-20e3.png", 
+        "unicode": "*⃣", 
+        "name": "Keycap Asterisk"
+    }, 
+    ":pray_tone1:": {
+        "style": "github", 
+        "image": "1f64f-1f3fb.png", 
+        "unicode": "🙏🏻", 
+        "name": "Person With Folded Hands - Tone 1"
+    }, 
+    ":cz:": {
+        "style": "github", 
+        "image": "1f1e8-1f1ff.png", 
+        "unicode": "🇨🇿", 
+        "name": "The Czech Republic"
+    }, 
+    ":yt:": {
+        "style": "github", 
+        "image": "1f1fe-1f1f9.png", 
+        "unicode": "🇾🇹", 
+        "name": "Mayotte"
+    }, 
+    ":man-in-tuxedo:": {
+        "style": "github", 
+        "image": "1f935.png", 
+        "unicode": "🤵", 
+        "name": "Man In Tuxedo"
+    }, 
+    ":flag_gn:": {
+        "style": "github", 
+        "image": "1f1ec-1f1f3.png", 
+        "unicode": "🇬🇳", 
+        "name": "Guinea"
+    }, 
+    ":flag-lc:": {
+        "style": "github", 
+        "image": "1f1f1-1f1e8.png", 
+        "unicode": "🇱🇨", 
+        "name": "Saint Lucia"
+    }, 
+    ":rolling_eyes:": {
+        "style": "github", 
+        "image": "1f644.png", 
+        "unicode": "🙄", 
+        "name": "Face With Rolling Eyes"
+    }, 
+    ":flag-fm:": {
+        "style": "github", 
+        "image": "1f1eb-1f1f2.png", 
+        "unicode": "🇫🇲", 
+        "name": "Micronesia"
+    }, 
+    "🚌": {
+        "style": "unicode", 
+        "image": "1f68c.png", 
+        "name": "Bus"
+    }, 
+    ":flag_nf:": {
+        "style": "github", 
+        "image": "1f1f3-1f1eb.png", 
+        "unicode": "🇳🇫", 
+        "name": "Norfolk Island"
+    }, 
+    "🔡": {
+        "style": "unicode", 
+        "image": "1f521.png", 
+        "name": "Input Symbol For Latin Small Letters"
+    }, 
+    ":kz:": {
+        "style": "github", 
+        "image": "1f1f0-1f1ff.png", 
+        "unicode": "🇰🇿", 
+        "name": "Kazakhstan"
+    }, 
+    "🌥": {
+        "style": "unicode", 
+        "image": "1f325.png", 
+        "name": "White Sun Behind Cloud"
+    }, 
+    ":ad:": {
+        "style": "github", 
+        "image": "1f1e6-1f1e9.png", 
+        "unicode": "🇦🇩", 
+        "name": "Andorra"
+    }, 
+    ":bath_tone5:": {
+        "style": "github", 
+        "image": "1f6c0-1f3ff.png", 
+        "unicode": "🛀🏿", 
+        "name": "Bath - Tone 5"
+    }, 
+    ":triangular-flag-on-post:": {
+        "style": "github", 
+        "image": "1f6a9.png", 
+        "unicode": "🚩", 
+        "name": "Triangular Flag On Post"
+    }, 
+    ":flag-sn:": {
+        "style": "github", 
+        "image": "1f1f8-1f1f3.png", 
+        "unicode": "🇸🇳", 
+        "name": "Senegal"
+    }, 
+    "🎺": {
+        "style": "unicode", 
+        "image": "1f3ba.png", 
+        "name": "Trumpet"
+    }, 
+    "🤽🏻": {
+        "style": "unicode", 
+        "image": "1f93d-1f3fb.png", 
+        "name": "Water Polo - Tone 1"
+    }, 
+    ":capricorn:": {
+        "style": "github", 
+        "image": "2651.png", 
+        "unicode": "♑", 
+        "name": "Capricorn"
+    }, 
+    ":call_me_hand_tone5:": {
+        "style": "github", 
+        "image": "1f919-1f3ff.png", 
+        "unicode": "🤙🏿", 
+        "name": "Call Me Hand - Tone 5"
+    }, 
+    "👋": {
+        "style": "unicode", 
+        "image": "1f44b.png", 
+        "name": "Waving Hand Sign"
+    }, 
+    ":wrestling_tone4:": {
+        "style": "github", 
+        "image": "1f93c-1f3fe.png", 
+        "unicode": "🤼🏾", 
+        "name": "Wrestlers - Tone 4"
+    }, 
+    ":it:": {
+        "style": "github", 
+        "image": "1f1ee-1f1f9.png", 
+        "unicode": "🇮🇹", 
+        "name": "Italy"
+    }, 
+    "📠": {
+        "style": "unicode", 
+        "image": "1f4e0.png", 
+        "name": "Fax Machine"
+    }, 
+    ":expecting_woman_tone4:": {
+        "style": "github", 
+        "image": "1f930-1f3fe.png", 
+        "unicode": "🤰🏾", 
+        "name": "Pregnant Woman - Tone 4"
+    }, 
+    ":spy-tone3:": {
+        "style": "github", 
+        "image": "1f575-1f3fd.png", 
+        "unicode": "🕵🏽", 
+        "name": "Sleuth Or Spy - Tone 3"
+    }, 
+    ":heavy-plus-sign:": {
+        "style": "github", 
+        "image": "2795.png", 
+        "unicode": "➕", 
+        "name": "Heavy Plus Sign"
+    }, 
+    ":information_desk_person_tone3:": {
+        "style": "github", 
+        "image": "1f481-1f3fd.png", 
+        "unicode": "💁🏽", 
+        "name": "Information Desk Person - Tone 3"
+    }, 
+    ":wrestlers-tone3:": {
+        "style": "github", 
+        "image": "1f93c-1f3fd.png", 
+        "unicode": "🤼🏽", 
+        "name": "Wrestlers - Tone 3"
+    }, 
+    ":shopping_cart:": {
+        "style": "github", 
+        "image": "1f6d2.png", 
+        "unicode": "🛒", 
+        "name": "Shopping Trolley"
+    }, 
+    ":heart-exclamation:": {
+        "style": "github", 
+        "image": "2763.png", 
+        "unicode": "❣", 
+        "name": "Heavy Heart Exclamation Mark Ornament"
+    }, 
+    ":regional-indicator-z:": {
+        "style": "github", 
+        "image": "1f1ff.png", 
+        "unicode": "🇿", 
+        "name": "Regional Indicator Symbol Letter Z"
+    }, 
+    ":face-palm-tone2:": {
+        "style": "github", 
+        "image": "1f926-1f3fc.png", 
+        "unicode": "🤦🏼", 
+        "name": "Face Palm - Tone 2"
+    }, 
+    ":wrench:": {
+        "style": "github", 
+        "image": "1f527.png", 
+        "unicode": "🔧", 
+        "name": "Wrench"
+    }, 
+    ":pen_fountain:": {
+        "style": "github", 
+        "image": "1f58b.png", 
+        "unicode": "🖋", 
+        "name": "Lower Left Fountain Pen"
+    }, 
+    ":incoming_envelope:": {
+        "style": "github", 
+        "image": "1f4e8.png", 
+        "unicode": "📨", 
+        "name": "Incoming Envelope"
+    }, 
+    ":record_button:": {
+        "style": "github", 
+        "image": "23fa.png", 
+        "unicode": "⏺", 
+        "name": "Black Circle For Record"
+    }, 
+    ":left-facing-fist-tone5:": {
+        "style": "github", 
+        "image": "1f91b-1f3ff.png", 
+        "unicode": "🤛🏿", 
+        "name": "Left Facing Fist - Tone 5"
+    }, 
+    ":ring:": {
+        "style": "github", 
+        "image": "1f48d.png", 
+        "unicode": "💍", 
+        "name": "Ring"
+    }, 
+    ":information-desk-person-tone1:": {
+        "style": "github", 
+        "image": "1f481-1f3fb.png", 
+        "unicode": "💁🏻", 
+        "name": "Information Desk Person - Tone 1"
+    }, 
+    ":money_with_wings:": {
+        "style": "github", 
+        "image": "1f4b8.png", 
+        "unicode": "💸", 
+        "name": "Money With Wings"
+    }, 
+    ":rowboat_tone3:": {
+        "style": "github", 
+        "image": "1f6a3-1f3fd.png", 
+        "unicode": "🚣🏽", 
+        "name": "Rowboat - Tone 3"
+    }, 
+    "🛍": {
+        "style": "unicode", 
+        "image": "1f6cd.png", 
+        "name": "Shopping Bags"
+    }, 
+    ":squid:": {
+        "style": "github", 
+        "image": "1f991.png", 
+        "unicode": "🦑", 
+        "name": "Squid"
+    }, 
+    ":broken-heart:": {
+        "style": "github", 
+        "ascii": "</3", 
+        "image": "1f494.png", 
+        "unicode": "💔", 
+        "name": "Broken Heart"
+    }, 
+    ":radioactive:": {
+        "style": "github", 
+        "image": "2622.png", 
+        "unicode": "☢", 
+        "name": "Radioactive Sign"
+    }, 
+    ":middle-finger-tone3:": {
+        "style": "github", 
+        "image": "1f595-1f3fd.png", 
+        "unicode": "🖕🏽", 
+        "name": "Reversed Hand With Middle Finger Extended - Tone 3"
+    }, 
+    ":candy:": {
+        "style": "github", 
+        "image": "1f36c.png", 
+        "unicode": "🍬", 
+        "name": "Candy"
+    }, 
+    ":womans-hat:": {
+        "style": "github", 
+        "image": "1f452.png", 
+        "unicode": "👒", 
+        "name": "Womans Hat"
+    }, 
+    ":clubs:": {
+        "style": "github", 
+        "image": "2663.png", 
+        "unicode": "♣", 
+        "name": "Black Club Suit"
+    }, 
+    ":water-buffalo:": {
+        "style": "github", 
+        "image": "1f403.png", 
+        "unicode": "🐃", 
+        "name": "Water Buffalo"
+    }, 
+    ":outbox_tray:": {
+        "style": "github", 
+        "image": "1f4e4.png", 
+        "unicode": "📤", 
+        "name": "Outbox Tray"
+    }, 
+    ":flag_pg:": {
+        "style": "github", 
+        "image": "1f1f5-1f1ec.png", 
+        "unicode": "🇵🇬", 
+        "name": "Papua New Guinea"
+    }, 
+    ":person-frowning-tone2:": {
+        "style": "github", 
+        "image": "1f64d-1f3fc.png", 
+        "unicode": "🙍🏼", 
+        "name": "Person Frowning - Tone 2"
+    }, 
+    ":vulcan:": {
+        "style": "github", 
+        "image": "1f596.png", 
+        "unicode": "🖖", 
+        "name": "Raised Hand With Part Between Middle And Ring Fingers"
+    }, 
+    ":thunder_cloud_rain:": {
+        "style": "github", 
+        "image": "26c8.png", 
+        "unicode": "⛈", 
+        "name": "Thunder Cloud And Rain"
+    }, 
+    "🐡": {
+        "style": "unicode", 
+        "image": "1f421.png", 
+        "name": "Blowfish"
+    }, 
+    ":straight_ruler:": {
+        "style": "github", 
+        "image": "1f4cf.png", 
+        "unicode": "📏", 
+        "name": "Straight Ruler"
+    }, 
+    ":woman:": {
+        "style": "github", 
+        "image": "1f469.png", 
+        "unicode": "👩", 
+        "name": "Woman"
+    }, 
+    ":flag_kr:": {
+        "style": "github", 
+        "image": "1f1f0-1f1f7.png", 
+        "unicode": "🇰🇷", 
+        "name": "Korea"
+    }, 
+    ":envelope:": {
+        "style": "github", 
+        "image": "2709.png", 
+        "unicode": "✉", 
+        "name": "Envelope"
+    }, 
+    "💶": {
+        "style": "unicode", 
+        "image": "1f4b6.png", 
+        "name": "Banknote With Euro Sign"
+    }, 
+    ":mortar_board:": {
+        "style": "github", 
+        "image": "1f393.png", 
+        "unicode": "🎓", 
+        "name": "Graduation Cap"
+    }, 
+    ":regional_indicator_r:": {
+        "style": "github", 
+        "image": "1f1f7.png", 
+        "unicode": "🇷", 
+        "name": "Regional Indicator Symbol Letter R"
+    }, 
+    ":newspaper2:": {
+        "style": "github", 
+        "image": "1f5de.png", 
+        "unicode": "🗞", 
+        "name": "Rolled-up Newspaper"
+    }, 
+    ":flag_cm:": {
+        "style": "github", 
+        "image": "1f1e8-1f1f2.png", 
+        "unicode": "🇨🇲", 
+        "name": "Cameroon"
+    }, 
+    "🕋": {
+        "style": "unicode", 
+        "image": "1f54b.png", 
+        "name": "Kaaba"
+    }, 
+    "🍏": {
+        "style": "unicode", 
+        "image": "1f34f.png", 
+        "name": "Green Apple"
+    }, 
+    "🥓": {
+        "style": "unicode", 
+        "image": "1f953.png", 
+        "name": "Bacon"
+    }, 
+    ":checkered_flag:": {
+        "style": "github", 
+        "image": "1f3c1.png", 
+        "unicode": "🏁", 
+        "name": "Chequered Flag"
+    }, 
+    ":clipboard:": {
+        "style": "github", 
+        "image": "1f4cb.png", 
+        "unicode": "📋", 
+        "name": "Clipboard"
+    }, 
+    ":to:": {
+        "style": "github", 
+        "image": "1f1f9-1f1f4.png", 
+        "unicode": "🇹🇴", 
+        "name": "Tonga"
+    }, 
+    ":money-with-wings:": {
+        "style": "github", 
+        "image": "1f4b8.png", 
+        "unicode": "💸", 
+        "name": "Money With Wings"
+    }, 
+    ":santa-tone4:": {
+        "style": "github", 
+        "image": "1f385-1f3fe.png", 
+        "unicode": "🎅🏾", 
+        "name": "Father Christmas - Tone 4"
+    }, 
+    ":arrow-lower-left:": {
+        "style": "github", 
+        "image": "2199.png", 
+        "unicode": "↙", 
+        "name": "South West Arrow"
+    }, 
+    ":water-polo-tone4:": {
+        "style": "github", 
+        "image": "1f93d-1f3fe.png", 
+        "unicode": "🤽🏾", 
+        "name": "Water Polo - Tone 4"
+    }, 
+    ":hammer_pick:": {
+        "style": "github", 
+        "image": "2692.png", 
+        "unicode": "⚒", 
+        "name": "Hammer And Pick"
+    }, 
+    "☀": {
+        "style": "unicode", 
+        "image": "2600.png", 
+        "name": "Black Sun With Rays"
+    }, 
+    ":flag-white:": {
+        "style": "github", 
+        "image": "1f3f3.png", 
+        "unicode": "🏳", 
+        "name": "Waving White Flag"
+    }, 
+    "🤦🏻": {
+        "style": "unicode", 
+        "image": "1f926-1f3fb.png", 
+        "name": "Face Palm - Tone 1"
+    }, 
+    "🤦🏼": {
+        "style": "unicode", 
+        "image": "1f926-1f3fc.png", 
+        "name": "Face Palm - Tone 2"
+    }, 
+    "🤦🏽": {
+        "style": "unicode", 
+        "image": "1f926-1f3fd.png", 
+        "name": "Face Palm - Tone 3"
+    }, 
+    "🤦🏾": {
+        "style": "unicode", 
+        "image": "1f926-1f3fe.png", 
+        "name": "Face Palm - Tone 4"
+    }, 
+    "🌎": {
+        "style": "unicode", 
+        "image": "1f30e.png", 
+        "name": "Earth Globe Americas"
+    }, 
+    ":arrows_clockwise:": {
+        "style": "github", 
+        "image": "1f503.png", 
+        "unicode": "🔃", 
+        "name": "Clockwise Downwards And Upwards Open Circle Arrows"
+    }, 
+    ":man-with-turban-tone4:": {
+        "style": "github", 
+        "image": "1f473-1f3fe.png", 
+        "unicode": "👳🏾", 
+        "name": "Man With Turban - Tone 4"
+    }, 
+    ":water_polo_tone3:": {
+        "style": "github", 
+        "image": "1f93d-1f3fd.png", 
+        "unicode": "🤽🏽", 
+        "name": "Water Polo - Tone 3"
+    }, 
+    ":nail_care:": {
+        "style": "github", 
+        "image": "1f485.png", 
+        "unicode": "💅", 
+        "name": "Nail Polish"
+    }, 
+    ":flag-ss:": {
+        "style": "github", 
+        "image": "1f1f8-1f1f8.png", 
+        "unicode": "🇸🇸", 
+        "name": "South Sudan"
+    }, 
+    "🈸": {
+        "style": "unicode", 
+        "image": "1f238.png", 
+        "name": "Squared Cjk Unified Ideograph-7533"
+    }, 
+    ":flag_md:": {
+        "style": "github", 
+        "image": "1f1f2-1f1e9.png", 
+        "unicode": "🇲🇩", 
+        "name": "Moldova"
+    }, 
+    ":waning_crescent_moon:": {
+        "style": "github", 
+        "image": "1f318.png", 
+        "unicode": "🌘", 
+        "name": "Waning Crescent Moon Symbol"
+    }, 
+    ":reminder-ribbon:": {
+        "style": "github", 
+        "image": "1f397.png", 
+        "unicode": "🎗", 
+        "name": "Reminder Ribbon"
+    }, 
+    ":zipper_mouth:": {
+        "style": "github", 
+        "image": "1f910.png", 
+        "unicode": "🤐", 
+        "name": "Zipper-mouth Face"
+    }, 
+    ":dagger_knife:": {
+        "style": "github", 
+        "image": "1f5e1.png", 
+        "unicode": "🗡", 
+        "name": "Dagger Knife"
+    }, 
+    "🕢": {
+        "style": "unicode", 
+        "image": "1f562.png", 
+        "name": "Clock Face Seven-thirty"
+    }, 
+    ":baguette_bread:": {
+        "style": "github", 
+        "image": "1f956.png", 
+        "unicode": "🥖", 
+        "name": "Baguette Bread"
+    }, 
+    ":flashlight:": {
+        "style": "github", 
+        "image": "1f526.png", 
+        "unicode": "🔦", 
+        "name": "Electric Torch"
+    }, 
+    ":flag-cr:": {
+        "style": "github", 
+        "image": "1f1e8-1f1f7.png", 
+        "unicode": "🇨🇷", 
+        "name": "Costa Rica"
+    }, 
+    ":metal_tone1:": {
+        "style": "github", 
+        "image": "1f918-1f3fb.png", 
+        "unicode": "🤘🏻", 
+        "name": "Sign Of The Horns - Tone 1"
+    }, 
+    ":gq:": {
+        "style": "github", 
+        "image": "1f1ec-1f1f6.png", 
+        "unicode": "🇬🇶", 
+        "name": "Equatorial Guinea"
+    }, 
+    ":hotel:": {
+        "style": "github", 
+        "image": "1f3e8.png", 
+        "unicode": "🏨", 
+        "name": "Hotel"
+    }, 
+    "💌": {
+        "style": "unicode", 
+        "image": "1f48c.png", 
+        "name": "Love Letter"
+    }, 
+    ":saxophone:": {
+        "style": "github", 
+        "image": "1f3b7.png", 
+        "unicode": "🎷", 
+        "name": "Saxophone"
+    }, 
+    ":arrow-double-up:": {
+        "style": "github", 
+        "image": "23eb.png", 
+        "unicode": "⏫", 
+        "name": "Black Up-pointing Double Triangle"
+    }, 
+    ":globe_with_meridians:": {
+        "style": "github", 
+        "image": "1f310.png", 
+        "unicode": "🌐", 
+        "name": "Globe With Meridians"
+    }, 
+    ":flag_tk:": {
+        "style": "github", 
+        "image": "1f1f9-1f1f0.png", 
+        "unicode": "🇹🇰", 
+        "name": "Tokelau"
+    }, 
+    ":flag_ba:": {
+        "style": "github", 
+        "image": "1f1e7-1f1e6.png", 
+        "unicode": "🇧🇦", 
+        "name": "Bosnia And Herzegovina"
+    }, 
+    ":flag-ax:": {
+        "style": "github", 
+        "image": "1f1e6-1f1fd.png", 
+        "unicode": "🇦🇽", 
+        "name": "Åland Islands"
+    }, 
+    ":older_woman_tone2:": {
+        "style": "github", 
+        "image": "1f475-1f3fc.png", 
+        "unicode": "👵🏼", 
+        "name": "Older Woman - Tone 2"
+    }, 
+    "🙋": {
+        "style": "unicode", 
+        "image": "1f64b.png", 
+        "name": "Happy Person Raising One Hand"
+    }, 
+    ":horse-racing-tone2:": {
+        "style": "github", 
+        "image": "1f3c7-1f3fc.png", 
+        "unicode": "🏇🏼", 
+        "name": "Horse Racing - Tone 2"
+    }, 
+    ":flag_sn:": {
+        "style": "github", 
+        "image": "1f1f8-1f1f3.png", 
+        "unicode": "🇸🇳", 
+        "name": "Senegal"
+    }, 
+    ":massage_tone1:": {
+        "style": "github", 
+        "image": "1f486-1f3fb.png", 
+        "unicode": "💆🏻", 
+        "name": "Face Massage - Tone 1"
+    }, 
+    ":v-tone2:": {
+        "style": "github", 
+        "image": "270c-1f3fc.png", 
+        "unicode": "✌🏼", 
+        "name": "Victory Hand - Tone 2"
+    }, 
+    "🛠": {
+        "style": "unicode", 
+        "image": "1f6e0.png", 
+        "name": "Hammer And Wrench"
+    }, 
+    ":flag-bl:": {
+        "style": "github", 
+        "image": "1f1e7-1f1f1.png", 
+        "unicode": "🇧🇱", 
+        "name": "Saint Barthélemy"
+    }, 
+    ":arrow_lower_left:": {
+        "style": "github", 
+        "image": "2199.png", 
+        "unicode": "↙", 
+        "name": "South West Arrow"
+    }, 
+    ":waxing_crescent_moon:": {
+        "style": "github", 
+        "image": "1f312.png", 
+        "unicode": "🌒", 
+        "name": "Waxing Crescent Moon Symbol"
+    }, 
+    ":cookie:": {
+        "style": "github", 
+        "image": "1f36a.png", 
+        "unicode": "🍪", 
+        "name": "Cookie"
+    }, 
+    "🍹": {
+        "style": "unicode", 
+        "image": "1f379.png", 
+        "name": "Tropical Drink"
+    }, 
+    "*)": {
+        "style": "ascii", 
+        "ascii": ";)", 
+        "image": "1f609.png", 
+        "unicode": "😉", 
+        "name": "Winking Face"
+    }, 
+    ":man-dancing-tone2:": {
+        "style": "github", 
+        "image": "1f57a-1f3fc.png", 
+        "unicode": "🕺🏼", 
+        "name": "Man Dancing - Tone 2"
+    }, 
+    ":juggler_tone4:": {
+        "style": "github", 
+        "image": "1f939-1f3fe.png", 
+        "unicode": "🤹🏾", 
+        "name": "Juggling - Tone 4"
+    }, 
+    "🎣": {
+        "style": "unicode", 
+        "image": "1f3a3.png", 
+        "name": "Fishing Pole And Fish"
+    }, 
+    ":back:": {
+        "style": "github", 
+        "image": "1f519.png", 
+        "unicode": "🔙", 
+        "name": "Back With Leftwards Arrow Above"
+    }, 
+    "🌸": {
+        "style": "unicode", 
+        "image": "1f338.png", 
+        "name": "Cherry Blossom"
+    }, 
+    ":selfie_tone4:": {
+        "style": "github", 
+        "image": "1f933-1f3fe.png", 
+        "unicode": "🤳🏾", 
+        "name": "Selfie - Tone 4"
+    }, 
+    "📍": {
+        "style": "unicode", 
+        "image": "1f4cd.png", 
+        "name": "Round Pushpin"
+    }, 
+    "👢": {
+        "style": "unicode", 
+        "image": "1f462.png", 
+        "name": "Womans Boots"
+    }, 
+    ":punch-tone2:": {
+        "style": "github", 
+        "image": "1f44a-1f3fc.png", 
+        "unicode": "👊🏼", 
+        "name": "Fisted Hand Sign - Tone 2"
+    }, 
+    ":flag_lk:": {
+        "style": "github", 
+        "image": "1f1f1-1f1f0.png", 
+        "unicode": "🇱🇰", 
+        "name": "Sri Lanka"
+    }, 
+    ":checkered-flag:": {
+        "style": "github", 
+        "image": "1f3c1.png", 
+        "unicode": "🏁", 
+        "name": "Chequered Flag"
+    }, 
+    ":mg:": {
+        "style": "github", 
+        "image": "1f1f2-1f1ec.png", 
+        "unicode": "🇲🇬", 
+        "name": "Madagascar"
+    }, 
+    ":bow-and-arrow:": {
+        "style": "github", 
+        "image": "1f3f9.png", 
+        "unicode": "🏹", 
+        "name": "Bow And Arrow"
+    }, 
+    ":koala:": {
+        "style": "github", 
+        "image": "1f428.png", 
+        "unicode": "🐨", 
+        "name": "Koala"
+    }, 
+    ":nerd_face:": {
+        "style": "github", 
+        "image": "1f913.png", 
+        "unicode": "🤓", 
+        "name": "Nerd Face"
+    }, 
+    ":open-hands-tone5:": {
+        "style": "github", 
+        "image": "1f450-1f3ff.png", 
+        "unicode": "👐🏿", 
+        "name": "Open Hands Sign - Tone 5"
+    }, 
+    "🖌": {
+        "style": "unicode", 
+        "image": "1f58c.png", 
+        "name": "Lower Left Paintbrush"
+    }, 
+    ":nauseated-face:": {
+        "style": "github", 
+        "image": "1f922.png", 
+        "unicode": "🤢", 
+        "name": "Nauseated Face"
+    }, 
+    ":nose_tone1:": {
+        "style": "github", 
+        "image": "1f443-1f3fb.png", 
+        "unicode": "👃🏻", 
+        "name": "Nose - Tone 1"
+    }, 
+    ":cop-tone4:": {
+        "style": "github", 
+        "image": "1f46e-1f3fe.png", 
+        "unicode": "👮🏾", 
+        "name": "Police Officer - Tone 4"
+    }, 
+    ":expressionless:": {
+        "style": "github", 
+        "ascii": "-_-", 
+        "image": "1f611.png", 
+        "unicode": "😑", 
+        "name": "Expressionless Face"
+    }, 
+    "😡": {
+        "style": "unicode", 
+        "image": "1f621.png", 
+        "name": "Pouting Face"
+    }, 
+    ":sleuth_or_spy_tone1:": {
+        "style": "github", 
+        "image": "1f575-1f3fb.png", 
+        "unicode": "🕵🏻", 
+        "name": "Sleuth Or Spy - Tone 1"
+    }, 
+    ":radio:": {
+        "style": "github", 
+        "image": "1f4fb.png", 
+        "unicode": "📻", 
+        "name": "Radio"
+    }, 
+    ":white_frowning_face:": {
+        "style": "github", 
+        "image": "2639.png", 
+        "unicode": "☹", 
+        "name": "White Frowning Face"
+    }, 
+    ":track-next:": {
+        "style": "github", 
+        "image": "23ed.png", 
+        "unicode": "⏭", 
+        "name": "Black Right-pointing Double Triangle With Vertical Bar"
+    }, 
+    ":-1_tone2:": {
+        "style": "github", 
+        "image": "1f44e-1f3fc.png", 
+        "unicode": "👎🏼", 
+        "name": "Thumbs Down Sign - Tone 2"
+    }, 
+    ":no_good_tone3:": {
+        "style": "github", 
+        "image": "1f645-1f3fd.png", 
+        "unicode": "🙅🏽", 
+        "name": "Face With No Good Gesture - Tone 3"
+    }, 
+    "🤘🏻": {
+        "style": "unicode", 
+        "image": "1f918-1f3fb.png", 
+        "name": "Sign Of The Horns - Tone 1"
+    }, 
+    ":metal-tone5:": {
+        "style": "github", 
+        "image": "1f918-1f3ff.png", 
+        "unicode": "🤘🏿", 
+        "name": "Sign Of The Horns - Tone 5"
+    }, 
+    ":spoon:": {
+        "style": "github", 
+        "image": "1f944.png", 
+        "unicode": "🥄", 
+        "name": "Spoon"
+    }, 
+    ":baby_tone3:": {
+        "style": "github", 
+        "image": "1f476-1f3fd.png", 
+        "unicode": "👶🏽", 
+        "name": "Baby - Tone 3"
+    }, 
+    ":ear_tone1:": {
+        "style": "github", 
+        "image": "1f442-1f3fb.png", 
+        "unicode": "👂🏻", 
+        "name": "Ear - Tone 1"
+    }, 
+    ":point-down-tone2:": {
+        "style": "github", 
+        "image": "1f447-1f3fc.png", 
+        "unicode": "👇🏼", 
+        "name": "White Down Pointing Backhand Index - Tone 2"
+    }, 
+    ":flag-ie:": {
+        "style": "github", 
+        "image": "1f1ee-1f1ea.png", 
+        "unicode": "🇮🇪", 
+        "name": "Ireland"
+    }, 
+    ":tired-face:": {
+        "style": "github", 
+        "image": "1f62b.png", 
+        "unicode": "😫", 
+        "name": "Tired Face"
+    }, 
+    ":pray-tone5:": {
+        "style": "github", 
+        "image": "1f64f-1f3ff.png", 
+        "unicode": "🙏🏿", 
+        "name": "Person With Folded Hands - Tone 5"
+    }, 
+    ":confounded:": {
+        "style": "github", 
+        "image": "1f616.png", 
+        "unicode": "😖", 
+        "name": "Confounded Face"
+    }, 
+    "🌒": {
+        "style": "unicode", 
+        "image": "1f312.png", 
+        "name": "Waxing Crescent Moon Symbol"
+    }, 
+    "👆🏾": {
+        "style": "unicode", 
+        "image": "1f446-1f3fe.png", 
+        "name": "White Up Pointing Backhand Index - Tone 4"
+    }, 
+    ":flag_tv:": {
+        "style": "github", 
+        "image": "1f1f9-1f1fb.png", 
+        "unicode": "🇹🇻", 
+        "name": "Tuvalu"
+    }, 
+    ":scooter:": {
+        "style": "github", 
+        "image": "1f6f4.png", 
+        "unicode": "🛴", 
+        "name": "Scooter"
+    }, 
+    ":vulcan-tone5:": {
+        "style": "github", 
+        "image": "1f596-1f3ff.png", 
+        "unicode": "🖖🏿", 
+        "name": "Raised Hand With Part Between Middle And Ring Fingers - Tone 5"
+    }, 
+    ":left-facing-fist:": {
+        "style": "github", 
+        "image": "1f91b.png", 
+        "unicode": "🤛", 
+        "name": "Left-facing Fist"
+    }, 
+    ":handball-tone5:": {
+        "style": "github", 
+        "image": "1f93e-1f3ff.png", 
+        "unicode": "🤾🏿", 
+        "name": "Handball - Tone 5"
+    }, 
+    ":lifter-tone2:": {
+        "style": "github", 
+        "image": "1f3cb-1f3fc.png", 
+        "unicode": "🏋🏼", 
+        "name": "Weight Lifter - Tone 2"
+    }, 
+    ":family-wwgb:": {
+        "style": "github", 
+        "image": "1f469-1f469-1f467-1f466.png", 
+        "unicode": "👩👩👧👦", 
+        "name": "Family (woman,woman,girl,boy)"
+    }, 
+    "✈": {
+        "style": "unicode", 
+        "image": "2708.png", 
+        "name": "Airplane"
+    }, 
+    ":selfie_tone1:": {
+        "style": "github", 
+        "image": "1f933-1f3fb.png", 
+        "unicode": "🤳🏻", 
+        "name": "Selfie - Tone 1"
+    }, 
+    ":sx:": {
+        "style": "github", 
+        "image": "1f1f8-1f1fd.png", 
+        "unicode": "🇸🇽", 
+        "name": "Sint Maarten"
+    }, 
+    ":goat:": {
+        "style": "github", 
+        "image": "1f410.png", 
+        "unicode": "🐐", 
+        "name": "Goat"
+    }, 
+    "👨❤👨": {
+        "style": "unicode", 
+        "image": "1f468-2764-1f468.png", 
+        "name": "Couple (man,man)"
+    }, 
+    ":left_facing_fist:": {
+        "style": "github", 
+        "image": "1f91b.png", 
+        "unicode": "🤛", 
+        "name": "Left-facing Fist"
+    }, 
+    ":flag_ad:": {
+        "style": "github", 
+        "image": "1f1e6-1f1e9.png", 
+        "unicode": "🇦🇩", 
+        "name": "Andorra"
+    }, 
+    "🚔": {
+        "style": "unicode", 
+        "image": "1f694.png", 
+        "name": "Oncoming Police Car"
+    }, 
+    ":nc:": {
+        "style": "github", 
+        "image": "1f1f3-1f1e8.png", 
+        "unicode": "🇳🇨", 
+        "name": "New Caledonia"
+    }, 
+    ":small-red-triangle-down:": {
+        "style": "github", 
+        "image": "1f53b.png", 
+        "unicode": "🔻", 
+        "name": "Down-pointing Red Triangle"
+    }, 
+    ":flag-ma:": {
+        "style": "github", 
+        "image": "1f1f2-1f1e6.png", 
+        "unicode": "🇲🇦", 
+        "name": "Morocco"
+    }, 
+    "🤡": {
+        "style": "unicode", 
+        "image": "1f921.png", 
+        "name": "Clown Face"
+    }, 
+    "🔩": {
+        "style": "unicode", 
+        "image": "1f529.png", 
+        "name": "Nut And Bolt"
+    }, 
+    ":surfer-tone2:": {
+        "style": "github", 
+        "image": "1f3c4-1f3fc.png", 
+        "unicode": "🏄🏼", 
+        "name": "Surfer - Tone 2"
+    }, 
+    ":traffic_light:": {
+        "style": "github", 
+        "image": "1f6a5.png", 
+        "unicode": "🚥", 
+        "name": "Horizontal Traffic Light"
+    }, 
+    ":copyright:": {
+        "style": "github", 
+        "image": "00a9.png", 
+        "unicode": "©", 
+        "name": "Copyright Sign"
+    }, 
+    ":chart-with-upwards-trend:": {
+        "style": "github", 
+        "image": "1f4c8.png", 
+        "unicode": "📈", 
+        "name": "Chart With Upwards Trend"
+    }, 
+    ":flag_cf:": {
+        "style": "github", 
+        "image": "1f1e8-1f1eb.png", 
+        "unicode": "🇨🇫", 
+        "name": "Central African Republic"
+    }, 
+    ":point-up-2-tone2:": {
+        "style": "github", 
+        "image": "1f446-1f3fc.png", 
+        "unicode": "👆🏼", 
+        "name": "White Up Pointing Backhand Index - Tone 2"
+    }, 
+    ":flag_fk:": {
+        "style": "github", 
+        "image": "1f1eb-1f1f0.png", 
+        "unicode": "🇫🇰", 
+        "name": "Falkland Islands"
+    }, 
+    ":izakaya_lantern:": {
+        "style": "github", 
+        "image": "1f3ee.png", 
+        "unicode": "🏮", 
+        "name": "Izakaya Lantern"
+    }, 
+    ":right-facing-fist-tone1:": {
+        "style": "github", 
+        "image": "1f91c-1f3fb.png", 
+        "unicode": "🤜🏻", 
+        "name": "Right Facing Fist - Tone 1"
+    }, 
+    "👵🏽": {
+        "style": "unicode", 
+        "image": "1f475-1f3fd.png", 
+        "name": "Older Woman - Tone 3"
+    }, 
+    "👵🏼": {
+        "style": "unicode", 
+        "image": "1f475-1f3fc.png", 
+        "name": "Older Woman - Tone 2"
+    }, 
+    "👵🏿": {
+        "style": "unicode", 
+        "image": "1f475-1f3ff.png", 
+        "name": "Older Woman - Tone 5"
+    }, 
+    "👵🏾": {
+        "style": "unicode", 
+        "image": "1f475-1f3fe.png", 
+        "name": "Older Woman - Tone 4"
+    }, 
+    "👵🏻": {
+        "style": "unicode", 
+        "image": "1f475-1f3fb.png", 
+        "name": "Older Woman - Tone 1"
+    }, 
+    "📨": {
+        "style": "unicode", 
+        "image": "1f4e8.png", 
+        "name": "Incoming Envelope"
+    }, 
+    ":left_facing_fist_tone4:": {
+        "style": "github", 
+        "image": "1f91b-1f3fe.png", 
+        "unicode": "🤛🏾", 
+        "name": "Left Facing Fist - Tone 4"
+    }, 
+    ":hand_with_index_and_middle_fingers_crossed_tone4:": {
+        "style": "github", 
+        "image": "1f91e-1f3fe.png", 
+        "unicode": "🤞🏾", 
+        "name": "Hand With Index And Middle Fingers Crossed - Tone 4"
+    }, 
+    ":left-facing-fist-tone1:": {
+        "style": "github", 
+        "image": "1f91b-1f3fb.png", 
+        "unicode": "🤛🏻", 
+        "name": "Left Facing Fist - Tone 1"
+    }, 
+    ":four:": {
+        "style": "github", 
+        "image": "0034-20e3.png", 
+        "unicode": "4⃣", 
+        "name": "Keycap Digit Four"
+    }, 
+    "🍽": {
+        "style": "unicode", 
+        "image": "1f37d.png", 
+        "name": "Fork And Knife With Plate"
+    }, 
+    ":flag_gl:": {
+        "style": "github", 
+        "image": "1f1ec-1f1f1.png", 
+        "unicode": "🇬🇱", 
+        "name": "Greenland"
+    }, 
+    ":af:": {
+        "style": "github", 
+        "image": "1f1e6-1f1eb.png", 
+        "unicode": "🇦🇫", 
+        "name": "Afghanistan"
+    }, 
+    "🎧": {
+        "style": "unicode", 
+        "image": "1f3a7.png", 
+        "name": "Headphone"
+    }, 
+    ">:)": {
+        "style": "ascii", 
+        "ascii": ">:)", 
+        "image": "1f606.png", 
+        "unicode": "😆", 
+        "name": "Smiling Face With Open Mouth And Tightly-closed Eyes"
+    }, 
+    ">:(": {
+        "style": "ascii", 
+        "ascii": ">:(", 
+        "image": "1f620.png", 
+        "unicode": "😠", 
+        "name": "Angry Face"
+    }, 
+    ">:/": {
+        "style": "ascii", 
+        "ascii": ">:\\", 
+        "image": "1f615.png", 
+        "unicode": "😕", 
+        "name": "Confused Face"
+    }, 
+    "🌼": {
+        "style": "unicode", 
+        "image": "1f33c.png", 
+        "name": "Blossom"
+    }, 
+    ":flag-sh:": {
+        "style": "github", 
+        "image": "1f1f8-1f1ed.png", 
+        "unicode": "🇸🇭", 
+        "name": "Saint Helena"
+    }, 
+    ":wrestling_tone2:": {
+        "style": "github", 
+        "image": "1f93c-1f3fc.png", 
+        "unicode": "🤼🏼", 
+        "name": "Wrestlers - Tone 2"
+    }, 
+    ">:O": {
+        "style": "ascii", 
+        "ascii": ":-O", 
+        "image": "1f62e.png", 
+        "unicode": "😮", 
+        "name": "Face With Open Mouth"
+    }, 
+    ">:P": {
+        "style": "ascii", 
+        "ascii": ">:P", 
+        "image": "1f61c.png", 
+        "unicode": "😜", 
+        "name": "Face With Stuck-out Tongue And Winking Eye"
+    }, 
+    ":male_dancer:": {
+        "style": "github", 
+        "image": "1f57a.png", 
+        "unicode": "🕺", 
+        "name": "Man Dancing"
+    }, 
+    "=L": {
+        "style": "ascii", 
+        "ascii": ">:\\", 
+        "image": "1f615.png", 
+        "unicode": "😕", 
+        "name": "Confused Face"
+    }, 
+    ">:[": {
+        "style": "ascii", 
+        "ascii": ">:[", 
+        "image": "1f61e.png", 
+        "unicode": "😞", 
+        "name": "Disappointed Face"
+    }, 
+    ":face_palm_tone1:": {
+        "style": "github", 
+        "image": "1f926-1f3fb.png", 
+        "unicode": "🤦🏻", 
+        "name": "Face Palm - Tone 1"
+    }, 
+    ">:\\": {
+        "style": "ascii", 
+        "ascii": ">:\\", 
+        "image": "1f615.png", 
+        "unicode": "😕", 
+        "name": "Confused Face"
+    }, 
+    "🤴🏾": {
+        "style": "unicode", 
+        "image": "1f934-1f3fe.png", 
+        "name": "Prince - Tone 4"
+    }, 
+    "🤴🏿": {
+        "style": "unicode", 
+        "image": "1f934-1f3ff.png", 
+        "name": "Prince - Tone 5"
+    }, 
+    "🤴🏼": {
+        "style": "unicode", 
+        "image": "1f934-1f3fc.png", 
+        "name": "Prince - Tone 2"
+    }, 
+    "🤴🏽": {
+        "style": "unicode", 
+        "image": "1f934-1f3fd.png", 
+        "name": "Prince - Tone 3"
+    }, 
+    "🤴🏻": {
+        "style": "unicode", 
+        "image": "1f934-1f3fb.png", 
+        "name": "Prince - Tone 1"
+    }, 
+    "⛵": {
+        "style": "unicode", 
+        "image": "26f5.png", 
+        "name": "Sailboat"
+    }, 
+    "🇻": {
+        "style": "unicode", 
+        "image": "1f1fb.png", 
+        "name": "Regional Indicator Symbol Letter V"
+    }, 
+    ":classical-building:": {
+        "style": "github", 
+        "image": "1f3db.png", 
+        "unicode": "🏛", 
+        "name": "Classical Building"
+    }, 
+    "🌗": {
+        "style": "unicode", 
+        "image": "1f317.png", 
+        "name": "Last Quarter Moon Symbol"
+    }, 
+    ":floppy-disk:": {
+        "style": "github", 
+        "image": "1f4be.png", 
+        "unicode": "💾", 
+        "name": "Floppy Disk"
+    }, 
+    ":hn:": {
+        "style": "github", 
+        "image": "1f1ed-1f1f3.png", 
+        "unicode": "🇭🇳", 
+        "name": "Honduras"
+    }, 
+    "🐙": {
+        "style": "unicode", 
+        "image": "1f419.png", 
+        "name": "Octopus"
+    }, 
+    ":regional-indicator-x:": {
+        "style": "github", 
+        "image": "1f1fd.png", 
+        "unicode": "🇽", 
+        "name": "Regional Indicator Symbol Letter X"
+    }, 
+    ":face_palm:": {
+        "style": "github", 
+        "image": "1f926.png", 
+        "unicode": "🤦", 
+        "name": "Face Palm"
+    }, 
+    ":love-letter:": {
+        "style": "github", 
+        "image": "1f48c.png", 
+        "unicode": "💌", 
+        "name": "Love Letter"
+    }, 
+    "🐩": {
+        "style": "unicode", 
+        "image": "1f429.png", 
+        "name": "Poodle"
+    }, 
+    ":handshake_tone1:": {
+        "style": "github", 
+        "image": "1f91d-1f3fb.png", 
+        "unicode": "🤝🏻", 
+        "name": "Handshake - Tone 1"
+    }, 
+    "👂🏽": {
+        "style": "unicode", 
+        "image": "1f442-1f3fd.png", 
+        "name": "Ear - Tone 3"
+    }, 
+    "👂🏾": {
+        "style": "unicode", 
+        "image": "1f442-1f3fe.png", 
+        "name": "Ear - Tone 4"
+    }, 
+    "👂🏿": {
+        "style": "unicode", 
+        "image": "1f442-1f3ff.png", 
+        "name": "Ear - Tone 5"
+    }, 
+    "💾": {
+        "style": "unicode", 
+        "image": "1f4be.png", 
+        "name": "Floppy Disk"
+    }, 
+    "🥋": {
+        "style": "unicode", 
+        "image": "1f94b.png", 
+        "name": "Martial Arts Uniform"
+    }, 
+    ":juggling-tone2:": {
+        "style": "github", 
+        "image": "1f939-1f3fc.png", 
+        "unicode": "🤹🏼", 
+        "name": "Juggling - Tone 2"
+    }, 
+    "🕓": {
+        "style": "unicode", 
+        "image": "1f553.png", 
+        "name": "Clock Face Four Oclock"
+    }, 
+    ":koko:": {
+        "style": "github", 
+        "image": "1f201.png", 
+        "unicode": "🈁", 
+        "name": "Squared Katakana Koko"
+    }, 
+    ":person_with_pouting_face_tone2:": {
+        "style": "github", 
+        "image": "1f64e-1f3fc.png", 
+        "unicode": "🙎🏼", 
+        "name": "Person With Pouting Face Tone2"
+    }, 
+    "🗨": {
+        "style": "unicode", 
+        "image": "1f5e8.png", 
+        "name": "Left Speech Bubble"
+    }, 
+    ":satellite_orbital:": {
+        "style": "github", 
+        "image": "1f6f0.png", 
+        "unicode": "🛰", 
+        "name": "Satellite"
+    }, 
+    ":middle-finger-tone1:": {
+        "style": "github", 
+        "image": "1f595-1f3fb.png", 
+        "unicode": "🖕🏻", 
+        "name": "Reversed Hand With Middle Finger Extended - Tone 1"
+    }, 
+    ":rice_ball:": {
+        "style": "github", 
+        "image": "1f359.png", 
+        "unicode": "🍙", 
+        "name": "Rice Ball"
+    }, 
+    ":flag_pe:": {
+        "style": "github", 
+        "image": "1f1f5-1f1ea.png", 
+        "unicode": "🇵🇪", 
+        "name": "Peru"
+    }, 
+    "👶🏻": {
+        "style": "unicode", 
+        "image": "1f476-1f3fb.png", 
+        "name": "Baby - Tone 1"
+    }, 
+    "👶🏼": {
+        "style": "unicode", 
+        "image": "1f476-1f3fc.png", 
+        "name": "Baby - Tone 2"
+    }, 
+    "👶🏽": {
+        "style": "unicode", 
+        "image": "1f476-1f3fd.png", 
+        "name": "Baby - Tone 3"
+    }, 
+    "👶🏾": {
+        "style": "unicode", 
+        "image": "1f476-1f3fe.png", 
+        "name": "Baby - Tone 4"
+    }, 
+    "👶🏿": {
+        "style": "unicode", 
+        "image": "1f476-1f3ff.png", 
+        "name": "Baby - Tone 5"
+    }, 
+    ":flag-zw:": {
+        "style": "github", 
+        "image": "1f1ff-1f1fc.png", 
+        "unicode": "🇿🇼", 
+        "name": "Zimbabwe"
+    }, 
+    ":end:": {
+        "style": "github", 
+        "image": "1f51a.png", 
+        "unicode": "🔚", 
+        "name": "End With Leftwards Arrow Above"
+    }, 
+    ":rowboat_tone5:": {
+        "style": "github", 
+        "image": "1f6a3-1f3ff.png", 
+        "unicode": "🚣🏿", 
+        "name": "Rowboat - Tone 5"
+    }, 
+    ":mouse_three_button:": {
+        "style": "github", 
+        "image": "1f5b1.png", 
+        "unicode": "🖱", 
+        "name": "Three Button Mouse"
+    }, 
+    ":regional_indicator_p:": {
+        "style": "github", 
+        "image": "1f1f5.png", 
+        "unicode": "🇵", 
+        "name": "Regional Indicator Symbol Letter P"
+    }, 
+    ":track-previous:": {
+        "style": "github", 
+        "image": "23ee.png", 
+        "unicode": "⏮", 
+        "name": "Black Left-pointing Double Triangle With Vertical Bar"
+    }, 
+    ":flag_cc:": {
+        "style": "github", 
+        "image": "1f1e8-1f1e8.png", 
+        "unicode": "🇨🇨", 
+        "name": "Cocos (keeling) Islands"
+    }, 
+    ":massage-tone4:": {
+        "style": "github", 
+        "image": "1f486-1f3fe.png", 
+        "unicode": "💆🏾", 
+        "name": "Face Massage - Tone 4"
+    }, 
+    "🏑": {
+        "style": "unicode", 
+        "image": "1f3d1.png", 
+        "name": "Field Hockey Stick And Ball"
+    }, 
+    ":tm:": {
+        "style": "github", 
+        "image": "2122.png", 
+        "unicode": "™", 
+        "name": "Trade Mark Sign"
+    }, 
+    ":nail_care_tone2:": {
+        "style": "github", 
+        "image": "1f485-1f3fc.png", 
+        "unicode": "💅🏼", 
+        "name": "Nail Polish - Tone 2"
+    }, 
+    "🍦": {
+        "style": "unicode", 
+        "image": "1f366.png", 
+        "name": "Soft Ice Cream"
+    }, 
+    ":orthodox-cross:": {
+        "style": "github", 
+        "image": "2626.png", 
+        "unicode": "☦", 
+        "name": "Orthodox Cross"
+    }, 
+    ":mountain-bicyclist-tone5:": {
+        "style": "github", 
+        "image": "1f6b5-1f3ff.png", 
+        "unicode": "🚵🏿", 
+        "name": "Mountain Bicyclist - Tone 5"
+    }, 
+    "⏱": {
+        "style": "unicode", 
+        "image": "23f1.png", 
+        "name": "Stopwatch"
+    }, 
+    ":angel-tone5:": {
+        "style": "github", 
+        "image": "1f47c-1f3ff.png", 
+        "unicode": "👼🏿", 
+        "name": "Baby Angel - Tone 5"
+    }, 
+    ":point-left-tone1:": {
+        "style": "github", 
+        "image": "1f448-1f3fb.png", 
+        "unicode": "👈🏻", 
+        "name": "White Left Pointing Backhand Index - Tone 1"
+    }, 
+    "📿": {
+        "style": "unicode", 
+        "image": "1f4ff.png", 
+        "name": "Prayer Beads"
+    }, 
+    "🌇": {
+        "style": "unicode", 
+        "image": "1f307.png", 
+        "name": "Sunset Over Buildings"
+    }, 
+    "💔": {
+        "style": "unicode", 
+        "ascii": "</3", 
+        "image": "1f494.png", 
+        "name": "Broken Heart"
+    }, 
+    ":man-with-turban-tone2:": {
+        "style": "github", 
+        "image": "1f473-1f3fc.png", 
+        "unicode": "👳🏼", 
+        "name": "Man With Turban - Tone 2"
+    }, 
+    ":arrow-right:": {
+        "style": "github", 
+        "image": "27a1.png", 
+        "unicode": "➡", 
+        "name": "Black Rightwards Arrow"
+    }, 
+    ":couch_and_lamp:": {
+        "style": "github", 
+        "image": "1f6cb.png", 
+        "unicode": "🛋", 
+        "name": "Couch And Lamp"
+    }, 
+    ":flag_mf:": {
+        "style": "github", 
+        "image": "1f1f2-1f1eb.png", 
+        "unicode": "🇲🇫", 
+        "name": "Saint Martin"
+    }, 
+    ":third_place_medal:": {
+        "style": "github", 
+        "image": "1f949.png", 
+        "unicode": "🥉", 
+        "name": "Third Place Medal"
+    }, 
+    ":registered:": {
+        "style": "github", 
+        "image": "00ae.png", 
+        "unicode": "®", 
+        "name": "Registered Sign"
+    }, 
+    ":bd:": {
+        "style": "github", 
+        "image": "1f1e7-1f1e9.png", 
+        "unicode": "🇧🇩", 
+        "name": "Bangladesh"
+    }, 
+    "🇪🇸": {
+        "style": "unicode", 
+        "image": "1f1ea-1f1f8.png", 
+        "name": "Spain"
+    }, 
+    "🇪🇹": {
+        "style": "unicode", 
+        "image": "1f1ea-1f1f9.png", 
+        "name": "Ethiopia"
+    }, 
+    "🇪🇺": {
+        "style": "unicode", 
+        "image": "1f1ea-1f1fa.png", 
+        "name": "European Union"
+    }, 
+    ":oil:": {
+        "style": "github", 
+        "image": "1f6e2.png", 
+        "unicode": "🛢", 
+        "name": "Oil Drum"
+    }, 
+    "🇪🇷": {
+        "style": "unicode", 
+        "image": "1f1ea-1f1f7.png", 
+        "name": "Eritrea"
+    }, 
+    ":amphora:": {
+        "style": "github", 
+        "image": "1f3fa.png", 
+        "unicode": "🏺", 
+        "name": "Amphora"
+    }, 
+    "🇪🇬": {
+        "style": "unicode", 
+        "image": "1f1ea-1f1ec.png", 
+        "name": "Egypt"
+    }, 
+    "🇪🇭": {
+        "style": "unicode", 
+        "image": "1f1ea-1f1ed.png", 
+        "name": "Western Sahara"
+    }, 
+    "🇪🇨": {
+        "style": "unicode", 
+        "image": "1f1ea-1f1e8.png", 
+        "name": "Ecuador"
+    }, 
+    "🇪🇪": {
+        "style": "unicode", 
+        "image": "1f1ea-1f1ea.png", 
+        "name": "Estonia"
+    }, 
+    "🇪🇦": {
+        "style": "unicode", 
+        "image": "1f1ea-1f1e6.png", 
+        "name": "Ceuta, Melilla"
+    }, 
+    ":flag-cl:": {
+        "style": "github", 
+        "image": "1f1e8-1f1f1.png", 
+        "unicode": "🇨🇱", 
+        "name": "Chile"
+    }, 
+    ":second_place:": {
+        "style": "github", 
+        "image": "1f948.png", 
+        "unicode": "🥈", 
+        "name": "Second Place Medal"
+    }, 
+    ":card-box:": {
+        "style": "github", 
+        "image": "1f5c3.png", 
+        "unicode": "🗃", 
+        "name": "Card File Box"
+    }, 
+    ":black_medium_square:": {
+        "style": "github", 
+        "image": "25fc.png", 
+        "unicode": "◼", 
+        "name": "Black Medium Square"
+    }, 
+    "👐🏻": {
+        "style": "unicode", 
+        "image": "1f450-1f3fb.png", 
+        "name": "Open Hands Sign - Tone 1"
+    }, 
+    "👐🏾": {
+        "style": "unicode", 
+        "image": "1f450-1f3fe.png", 
+        "name": "Open Hands Sign - Tone 4"
+    }, 
+    "👐🏿": {
+        "style": "unicode", 
+        "image": "1f450-1f3ff.png", 
+        "name": "Open Hands Sign - Tone 5"
+    }, 
+    "👐🏼": {
+        "style": "unicode", 
+        "image": "1f450-1f3fc.png", 
+        "name": "Open Hands Sign - Tone 2"
+    }, 
+    "👐🏽": {
+        "style": "unicode", 
+        "image": "1f450-1f3fd.png", 
+        "name": "Open Hands Sign - Tone 3"
+    }, 
+    ":open_hands_tone2:": {
+        "style": "github", 
+        "image": "1f450-1f3fc.png", 
+        "unicode": "👐🏼", 
+        "name": "Open Hands Sign - Tone 2"
+    }, 
+    ":do-not-litter:": {
+        "style": "github", 
+        "image": "1f6af.png", 
+        "unicode": "🚯", 
+        "name": "Do Not Litter Symbol"
+    }, 
+    ":flag_hu:": {
+        "style": "github", 
+        "image": "1f1ed-1f1fa.png", 
+        "unicode": "🇭🇺", 
+        "name": "Hungary"
+    }, 
+    ":card-index:": {
+        "style": "github", 
+        "image": "1f4c7.png", 
+        "unicode": "📇", 
+        "name": "Card Index"
+    }, 
+    "📕": {
+        "style": "unicode", 
+        "image": "1f4d5.png", 
+        "name": "Closed Book"
+    }, 
+    ":japanese-goblin:": {
+        "style": "github", 
+        "image": "1f47a.png", 
+        "unicode": "👺", 
+        "name": "Japanese Goblin"
+    }, 
+    ":red_circle:": {
+        "style": "github", 
+        "image": "1f534.png", 
+        "unicode": "🔴", 
+        "name": "Large Red Circle"
+    }, 
+    ":reversed_hand_with_middle_finger_extended_tone1:": {
+        "style": "github", 
+        "image": "1f595-1f3fb.png", 
+        "unicode": "🖕🏻", 
+        "name": "Reversed Hand With Middle Finger Extended - Tone 1"
+    }, 
+    ":flag-ht:": {
+        "style": "github", 
+        "image": "1f1ed-1f1f9.png", 
+        "unicode": "🇭🇹", 
+        "name": "Haiti"
+    }, 
+    "👪": {
+        "style": "unicode", 
+        "image": "1f46a.png", 
+        "name": "Family"
+    }, 
+    ":flag-bj:": {
+        "style": "github", 
+        "image": "1f1e7-1f1ef.png", 
+        "unicode": "🇧🇯", 
+        "name": "Benin"
+    }, 
+    ":yellow_heart:": {
+        "style": "github", 
+        "image": "1f49b.png", 
+        "unicode": "💛", 
+        "name": "Yellow Heart"
+    }, 
+    ":ear-tone5:": {
+        "style": "github", 
+        "image": "1f442-1f3ff.png", 
+        "unicode": "👂🏿", 
+        "name": "Ear - Tone 5"
+    }, 
+    ":gw:": {
+        "style": "github", 
+        "image": "1f1ec-1f1fc.png", 
+        "unicode": "🇬🇼", 
+        "name": "Guinea-bissau"
+    }, 
+    "🗿": {
+        "style": "unicode", 
+        "image": "1f5ff.png", 
+        "name": "Moyai"
+    }, 
+    ":bow-tone2:": {
+        "style": "github", 
+        "image": "1f647-1f3fc.png", 
+        "unicode": "🙇🏼", 
+        "name": "Person Bowing Deeply - Tone 2"
+    }, 
+    ":arrow_forward:": {
+        "style": "github", 
+        "image": "25b6.png", 
+        "unicode": "▶", 
+        "name": "Black Right-pointing Triangle"
+    }, 
+    "🦌": {
+        "style": "unicode", 
+        "image": "1f98c.png", 
+        "name": "Deer"
+    }, 
+    ":microphone2:": {
+        "style": "github", 
+        "image": "1f399.png", 
+        "unicode": "🎙", 
+        "name": "Studio Microphone"
+    }, 
+    ":smile_cat:": {
+        "style": "github", 
+        "image": "1f638.png", 
+        "unicode": "😸", 
+        "name": "Grinning Cat Face With Smiling Eyes"
+    }, 
+    "🎐": {
+        "style": "unicode", 
+        "image": "1f390.png", 
+        "name": "Wind Chime"
+    }, 
+    ":flag-gp:": {
+        "style": "github", 
+        "image": "1f1ec-1f1f5.png", 
+        "unicode": "🇬🇵", 
+        "name": "Guadeloupe"
+    }, 
+    "⌛": {
+        "style": "unicode", 
+        "image": "231b.png", 
+        "name": "Hourglass"
+    }, 
+    ":athletic_shoe:": {
+        "style": "github", 
+        "image": "1f45f.png", 
+        "unicode": "👟", 
+        "name": "Athletic Shoe"
+    }, 
+    "😩": {
+        "style": "unicode", 
+        "image": "1f629.png", 
+        "name": "Weary Face"
+    }, 
+    ":weight_lifter_tone3:": {
+        "style": "github", 
+        "image": "1f3cb-1f3fd.png", 
+        "unicode": "🏋🏽", 
+        "name": "Weight Lifter - Tone 3"
+    }, 
+    ":flag_km:": {
+        "style": "github", 
+        "image": "1f1f0-1f1f2.png", 
+        "unicode": "🇰🇲", 
+        "name": "The Comoros"
+    }, 
+    ":flag_sl:": {
+        "style": "github", 
+        "image": "1f1f8-1f1f1.png", 
+        "unicode": "🇸🇱", 
+        "name": "Sierra Leone"
+    }, 
+    "🚾": {
+        "style": "unicode", 
+        "image": "1f6be.png", 
+        "name": "Water Closet"
+    }, 
+    ":new_moon:": {
+        "style": "github", 
+        "image": "1f311.png", 
+        "unicode": "🌑", 
+        "name": "New Moon Symbol"
+    }, 
+    "♉": {
+        "style": "unicode", 
+        "image": "2649.png", 
+        "name": "Taurus"
+    }, 
+    ":flag_es:": {
+        "style": "github", 
+        "image": "1f1ea-1f1f8.png", 
+        "unicode": "🇪🇸", 
+        "name": "Spain"
+    }, 
+    ":white-sun-small-cloud:": {
+        "style": "github", 
+        "image": "1f324.png", 
+        "unicode": "🌤", 
+        "name": "White Sun With Small Cloud"
+    }, 
+    ":flag-nf:": {
+        "style": "github", 
+        "image": "1f1f3-1f1eb.png", 
+        "unicode": "🇳🇫", 
+        "name": "Norfolk Island"
+    }, 
+    ":fishing-pole-and-fish:": {
+        "style": "github", 
+        "image": "1f3a3.png", 
+        "unicode": "🎣", 
+        "name": "Fishing Pole And Fish"
+    }, 
+    ":skull:": {
+        "style": "github", 
+        "image": "1f480.png", 
+        "unicode": "💀", 
+        "name": "Skull"
+    }, 
+    ":punch-tone4:": {
+        "style": "github", 
+        "image": "1f44a-1f3fe.png", 
+        "unicode": "👊🏾", 
+        "name": "Fisted Hand Sign - Tone 4"
+    }, 
+    "👱🏻": {
+        "style": "unicode", 
+        "image": "1f471-1f3fb.png", 
+        "name": "Person With Blond Hair - Tone 1"
+    }, 
+    "👱🏽": {
+        "style": "unicode", 
+        "image": "1f471-1f3fd.png", 
+        "name": "Person With Blond Hair - Tone 3"
+    }, 
+    ":do:": {
+        "style": "github", 
+        "image": "1f1e9-1f1f4.png", 
+        "unicode": "🇩🇴", 
+        "name": "The Dominican Republic"
+    }, 
+    "👱🏿": {
+        "style": "unicode", 
+        "image": "1f471-1f3ff.png", 
+        "name": "Person With Blond Hair - Tone 5"
+    }, 
+    "👱🏾": {
+        "style": "unicode", 
+        "image": "1f471-1f3fe.png", 
+        "name": "Person With Blond Hair - Tone 4"
+    }, 
+    ":rhino:": {
+        "style": "github", 
+        "image": "1f98f.png", 
+        "unicode": "🦏", 
+        "name": "Rhinoceros"
+    }, 
+    ":cc:": {
+        "style": "github", 
+        "image": "1f1e8-1f1e8.png", 
+        "unicode": "🇨🇨", 
+        "name": "Cocos (keeling) Islands"
+    }, 
+    ":tram:": {
+        "style": "github", 
+        "image": "1f68a.png", 
+        "unicode": "🚊", 
+        "name": "Tram"
+    }, 
+    ":confetti-ball:": {
+        "style": "github", 
+        "image": "1f38a.png", 
+        "unicode": "🎊", 
+        "name": "Confetti Ball"
+    }, 
+    ":chestnut:": {
+        "style": "github", 
+        "image": "1f330.png", 
+        "unicode": "🌰", 
+        "name": "Chestnut"
+    }, 
+    "🚧": {
+        "style": "unicode", 
+        "image": "1f6a7.png", 
+        "name": "Construction Sign"
+    }, 
+    ":by:": {
+        "style": "github", 
+        "image": "1f1e7-1f1fe.png", 
+        "unicode": "🇧🇾", 
+        "name": "Belarus"
+    }, 
+    ":sleuth_or_spy_tone3:": {
+        "style": "github", 
+        "image": "1f575-1f3fd.png", 
+        "unicode": "🕵🏽", 
+        "name": "Sleuth Or Spy - Tone 3"
+    }, 
+    ":scales:": {
+        "style": "github", 
+        "image": "2696.png", 
+        "unicode": "⚖", 
+        "name": "Scales"
+    }, 
+    ":file_cabinet:": {
+        "style": "github", 
+        "image": "1f5c4.png", 
+        "unicode": "🗄", 
+        "name": "File Cabinet"
+    }, 
+    ":no_good_tone5:": {
+        "style": "github", 
+        "image": "1f645-1f3ff.png", 
+        "unicode": "🙅🏿", 
+        "name": "Face With No Good Gesture - Tone 5"
+    }, 
+    ":-1_tone4:": {
+        "style": "github", 
+        "image": "1f44e-1f3fe.png", 
+        "unicode": "👎🏾", 
+        "name": "Thumbs Down Sign - Tone 4"
+    }, 
+    "🗑": {
+        "style": "unicode", 
+        "image": "1f5d1.png", 
+        "name": "Wastebasket"
+    }, 
+    "🏕": {
+        "style": "unicode", 
+        "image": "1f3d5.png", 
+        "name": "Camping"
+    }, 
+    ":baby_tone1:": {
+        "style": "github", 
+        "image": "1f476-1f3fb.png", 
+        "unicode": "👶🏻", 
+        "name": "Baby - Tone 1"
+    }, 
+    ":bikini:": {
+        "style": "github", 
+        "image": "1f459.png", 
+        "unicode": "👙", 
+        "name": "Bikini"
+    }, 
+    "👨👩👦👦": {
+        "style": "unicode", 
+        "image": "1f468-1f469-1f466-1f466.png", 
+        "name": "Family (man,woman,boy,boy)"
+    }, 
+    "🕦": {
+        "style": "unicode", 
+        "image": "1f566.png", 
+        "name": "Clock Face Eleven-thirty"
+    }, 
+    "🍪": {
+        "style": "unicode", 
+        "image": "1f36a.png", 
+        "name": "Cookie"
+    }, 
+    "🏳🌈": {
+        "style": "unicode", 
+        "image": "1f3f3-1f308.png", 
+        "name": "Gay_pride_flag"
+    }, 
+    ":parking:": {
+        "style": "github", 
+        "image": "1f17f.png", 
+        "unicode": "🅿", 
+        "name": "Negative Squared Latin Capital Letter P"
+    }, 
+    "📻": {
+        "style": "unicode", 
+        "image": "1f4fb.png", 
+        "name": "Radio"
+    }, 
+    ":arrow-right-hook:": {
+        "style": "github", 
+        "image": "21aa.png", 
+        "unicode": "↪", 
+        "name": "Rightwards Arrow With Hook"
+    }, 
+    "💐": {
+        "style": "unicode", 
+        "image": "1f490.png", 
+        "name": "Bouquet"
+    }, 
+    ":mountain_bicyclist:": {
+        "style": "github", 
+        "image": "1f6b5.png", 
+        "unicode": "🚵", 
+        "name": "Mountain Bicyclist"
+    }, 
+    ":fingers-crossed-tone3:": {
+        "style": "github", 
+        "image": "1f91e-1f3fd.png", 
+        "unicode": "🤞🏽", 
+        "name": "Hand With Index And Middle Fingers Crossed - Tone 3"
+    }, 
+    ":flag_tt:": {
+        "style": "github", 
+        "image": "1f1f9-1f1f9.png", 
+        "unicode": "🇹🇹", 
+        "name": "Trinidad And Tobago"
+    }, 
+    ":vertical_traffic_light:": {
+        "style": "github", 
+        "image": "1f6a6.png", 
+        "unicode": "🚦", 
+        "name": "Vertical Traffic Light"
+    }, 
+    ":trolleybus:": {
+        "style": "github", 
+        "image": "1f68e.png", 
+        "unicode": "🚎", 
+        "name": "Trolleybus"
+    }, 
+    ":woman_tone2:": {
+        "style": "github", 
+        "image": "1f469-1f3fc.png", 
+        "unicode": "👩🏼", 
+        "name": "Woman - Tone 2"
+    }, 
+    ":book:": {
+        "style": "github", 
+        "image": "1f4d6.png", 
+        "unicode": "📖", 
+        "name": "Open Book"
+    }, 
+    ":person_with_blond_hair:": {
+        "style": "github", 
+        "image": "1f471.png", 
+        "unicode": "👱", 
+        "name": "Person With Blond Hair"
+    }, 
+    ":stop_sign:": {
+        "style": "github", 
+        "image": "1f6d1.png", 
+        "unicode": "🛑", 
+        "name": "Octagonal Sign"
+    }, 
+    ":chocolate-bar:": {
+        "style": "github", 
+        "image": "1f36b.png", 
+        "unicode": "🍫", 
+        "name": "Chocolate Bar"
+    }, 
+    ":clown_face:": {
+        "style": "github", 
+        "image": "1f921.png", 
+        "unicode": "🤡", 
+        "name": "Clown Face"
+    }, 
+    ":selfie-tone2:": {
+        "style": "github", 
+        "image": "1f933-1f3fc.png", 
+        "unicode": "🤳🏼", 
+        "name": "Selfie - Tone 2"
+    }, 
+    ":grimacing:": {
+        "style": "github", 
+        "image": "1f62c.png", 
+        "unicode": "😬", 
+        "name": "Grimacing Face"
+    }, 
+    ":paperclips:": {
+        "style": "github", 
+        "image": "1f587.png", 
+        "unicode": "🖇", 
+        "name": "Linked Paperclips"
+    }, 
+    ":white_sun_cloud:": {
+        "style": "github", 
+        "image": "1f325.png", 
+        "unicode": "🌥", 
+        "name": "White Sun Behind Cloud"
+    }, 
+    ":pen-fountain:": {
+        "style": "github", 
+        "image": "1f58b.png", 
+        "unicode": "🖋", 
+        "name": "Lower Left Fountain Pen"
+    }, 
+    ":spy_tone5:": {
+        "style": "github", 
+        "image": "1f575-1f3ff.png", 
+        "unicode": "🕵🏿", 
+        "name": "Sleuth Or Spy - Tone 5"
+    }, 
+    ":flag-gm:": {
+        "style": "github", 
+        "image": "1f1ec-1f1f2.png", 
+        "unicode": "🇬🇲", 
+        "name": "The Gambia"
+    }, 
+    ":ne:": {
+        "style": "github", 
+        "image": "1f1f3-1f1ea.png", 
+        "unicode": "🇳🇪", 
+        "name": "Niger"
+    }, 
+    "😒": {
+        "style": "unicode", 
+        "image": "1f612.png", 
+        "name": "Unamused Face"
+    }, 
+    ":flag_af:": {
+        "style": "github", 
+        "image": "1f1e6-1f1eb.png", 
+        "unicode": "🇦🇫", 
+        "name": "Afghanistan"
+    }, 
+    ":fingers_crossed_tone4:": {
+        "style": "github", 
+        "image": "1f91e-1f3fe.png", 
+        "unicode": "🤞🏾", 
+        "name": "Hand With Index And Middle Fingers Crossed - Tone 4"
+    }, 
+    ":flag_ci:": {
+        "style": "github", 
+        "image": "1f1e8-1f1ee.png", 
+        "unicode": "🇨🇮", 
+        "name": "Côte D’ivoire"
+    }, 
+    ":tokyo-tower:": {
+        "style": "github", 
+        "image": "1f5fc.png", 
+        "unicode": "🗼", 
+        "name": "Tokyo Tower"
+    }, 
+    ":writing-hand-tone3:": {
+        "style": "github", 
+        "image": "270d-1f3fd.png", 
+        "unicode": "✍🏽", 
+        "name": "Writing Hand - Tone 3"
+    }, 
+    ":flag-th:": {
+        "style": "github", 
+        "image": "1f1f9-1f1ed.png", 
+        "unicode": "🇹🇭", 
+        "name": "Thailand"
+    }, 
+    "🤸": {
+        "style": "unicode", 
+        "image": "1f938.png", 
+        "name": "Person Doing Cartwheel"
+    }, 
+    "👧🏽": {
+        "style": "unicode", 
+        "image": "1f467-1f3fd.png", 
+        "name": "Girl - Tone 3"
+    }, 
+    ":oil_drum:": {
+        "style": "github", 
+        "image": "1f6e2.png", 
+        "unicode": "🛢", 
+        "name": "Oil Drum"
+    }, 
+    ":point-up-2-tone4:": {
+        "style": "github", 
+        "image": "1f446-1f3fe.png", 
+        "unicode": "👆🏾", 
+        "name": "White Up Pointing Backhand Index - Tone 4"
+    }, 
+    ":smile-cat:": {
+        "style": "github", 
+        "image": "1f638.png", 
+        "unicode": "😸", 
+        "name": "Grinning Cat Face With Smiling Eyes"
+    }, 
+    "📑": {
+        "style": "unicode", 
+        "image": "1f4d1.png", 
+        "name": "Bookmark Tabs"
+    }, 
+    "👦": {
+        "style": "unicode", 
+        "image": "1f466.png", 
+        "name": "Boy"
+    }, 
+    ":eject_symbol:": {
+        "style": "github", 
+        "image": "23cf.png", 
+        "unicode": "⏏", 
+        "name": "Eject Symbol"
+    }, 
+    ":triangular-ruler:": {
+        "style": "github", 
+        "image": "1f4d0.png", 
+        "unicode": "📐", 
+        "name": "Triangular Ruler"
+    }, 
+    ":left_facing_fist_tone2:": {
+        "style": "github", 
+        "image": "1f91b-1f3fc.png", 
+        "unicode": "🤛🏼", 
+        "name": "Left Facing Fist - Tone 2"
+    }, 
+    "🗻": {
+        "style": "unicode", 
+        "image": "1f5fb.png", 
+        "name": "Mount Fuji"
+    }, 
+    "🏿": {
+        "style": "unicode", 
+        "image": "1f3ff.png", 
+        "name": "Emoji Modifier Fitzpatrick Type-6"
+    }, 
+    ":flag_nz:": {
+        "style": "github", 
+        "image": "1f1f3-1f1ff.png", 
+        "unicode": "🇳🇿", 
+        "name": "New Zealand"
+    }, 
+    "⚖": {
+        "style": "unicode", 
+        "image": "2696.png", 
+        "name": "Scales"
+    }, 
+    "🛃": {
+        "style": "unicode", 
+        "image": "1f6c3.png", 
+        "name": "Customs"
+    }, 
+    "🖐": {
+        "style": "unicode", 
+        "image": "1f590.png", 
+        "name": "Raised Hand With Fingers Splayed"
+    }, 
+    ":dizzy:": {
+        "style": "github", 
+        "image": "1f4ab.png", 
+        "unicode": "💫", 
+        "name": "Dizzy Symbol"
+    }, 
+    ":cinema:": {
+        "style": "github", 
+        "image": "1f3a6.png", 
+        "unicode": "🎦", 
+        "name": "Cinema"
+    }, 
+    ":right-facing-fist-tone3:": {
+        "style": "github", 
+        "image": "1f91c-1f3fd.png", 
+        "unicode": "🤜🏽", 
+        "name": "Right Facing Fist - Tone 3"
+    }, 
+    "⁉": {
+        "style": "unicode", 
+        "image": "2049.png", 
+        "name": "Exclamation Question Mark"
+    }, 
+    ":full-moon:": {
+        "style": "github", 
+        "image": "1f315.png", 
+        "unicode": "🌕", 
+        "name": "Full Moon Symbol"
+    }, 
+    ":performing-arts:": {
+        "style": "github", 
+        "image": "1f3ad.png", 
+        "unicode": "🎭", 
+        "name": "Performing Arts"
+    }, 
+    ":hear_no_evil:": {
+        "style": "github", 
+        "image": "1f649.png", 
+        "unicode": "🙉", 
+        "name": "Hear-no-evil Monkey"
+    }, 
+    ":bouquet:": {
+        "style": "github", 
+        "image": "1f490.png", 
+        "unicode": "💐", 
+        "name": "Bouquet"
+    }, 
+    ":face_palm_tone3:": {
+        "style": "github", 
+        "image": "1f926-1f3fd.png", 
+        "unicode": "🤦🏽", 
+        "name": "Face Palm - Tone 3"
+    }, 
+    ":minidisc:": {
+        "style": "github", 
+        "image": "1f4bd.png", 
+        "unicode": "💽", 
+        "name": "Minidisc"
+    }, 
+    "🇨": {
+        "style": "unicode", 
+        "image": "1f1e8.png", 
+        "name": "Regional Indicator Symbol Letter C"
+    }, 
+    ":two:": {
+        "style": "github", 
+        "image": "0032-20e3.png", 
+        "unicode": "2⃣", 
+        "name": "Keycap Digit Two"
+    }, 
+    ":face_palm_tone5:": {
+        "style": "github", 
+        "image": "1f926-1f3ff.png", 
+        "unicode": "🤦🏿", 
+        "name": "Face Palm - Tone 5"
+    }, 
+    "🔒": {
+        "style": "unicode", 
+        "image": "1f512.png", 
+        "name": "Lock"
+    }, 
+    ":raised-back-of-hand-tone4:": {
+        "style": "github", 
+        "image": "1f91a-1f3fe.png", 
+        "unicode": "🤚🏾", 
+        "name": "Raised Back Of Hand - Tone 4"
+    }, 
+    ":four_leaf_clover:": {
+        "style": "github", 
+        "image": "1f340.png", 
+        "unicode": "🍀", 
+        "name": "Four Leaf Clover"
+    }, 
+    ":upside_down:": {
+        "style": "github", 
+        "image": "1f643.png", 
+        "unicode": "🙃", 
+        "name": "Upside-down Face"
+    }, 
+    ":boot:": {
+        "style": "github", 
+        "image": "1f462.png", 
+        "unicode": "👢", 
+        "name": "Womans Boots"
+    }, 
+    ":beetle:": {
+        "style": "github", 
+        "image": "1f41e.png", 
+        "unicode": "🐞", 
+        "name": "Lady Beetle"
+    }, 
+    ":flag-ac:": {
+        "style": "github", 
+        "image": "1f1e6-1f1e8.png", 
+        "unicode": "🇦🇨", 
+        "name": "Ascension"
+    }, 
+    ":handshake_tone3:": {
+        "style": "github", 
+        "image": "1f91d-1f3fd.png", 
+        "unicode": "🤝🏽", 
+        "name": "Handshake - Tone 3"
+    }, 
+    ":robot_face:": {
+        "style": "github", 
+        "image": "1f916.png", 
+        "unicode": "🤖", 
+        "name": "Robot Face"
+    }, 
+    "🐼": {
+        "style": "unicode", 
+        "image": "1f43c.png", 
+        "name": "Panda Face"
+    }, 
+    ":fr:": {
+        "style": "github", 
+        "image": "1f1eb-1f1f7.png", 
+        "unicode": "🇫🇷", 
+        "name": "France"
+    }, 
+    ":money_mouth:": {
+        "style": "github", 
+        "image": "1f911.png", 
+        "unicode": "🤑", 
+        "name": "Money-mouth Face"
+    }, 
+    ":construction_worker_tone4:": {
+        "style": "github", 
+        "image": "1f477-1f3fe.png", 
+        "unicode": "👷🏾", 
+        "name": "Construction Worker - Tone 4"
+    }, 
+    ":information-desk-person-tone5:": {
+        "style": "github", 
+        "image": "1f481-1f3ff.png", 
+        "unicode": "💁🏿", 
+        "name": "Information Desk Person - Tone 5"
+    }, 
+    ":stars:": {
+        "style": "github", 
+        "image": "1f320.png", 
+        "unicode": "🌠", 
+        "name": "Shooting Star"
+    }, 
+    ":exclamation:": {
+        "style": "github", 
+        "image": "2757.png", 
+        "unicode": "❗", 
+        "name": "Heavy Exclamation Mark Symbol"
+    }, 
+    ":honey_pot:": {
+        "style": "github", 
+        "image": "1f36f.png", 
+        "unicode": "🍯", 
+        "name": "Honey Pot"
+    }, 
+    ":flag_it:": {
+        "style": "github", 
+        "image": "1f1ee-1f1f9.png", 
+        "unicode": "🇮🇹", 
+        "name": "Italy"
+    }, 
+    ":u7533:": {
+        "style": "github", 
+        "image": "1f238.png", 
+        "unicode": "🈸", 
+        "name": "Squared Cjk Unified Ideograph-7533"
+    }, 
+    ":hatched_chick:": {
+        "style": "github", 
+        "image": "1f425.png", 
+        "unicode": "🐥", 
+        "name": "Front-facing Baby Chick"
+    }, 
+    ":older-man-tone4:": {
+        "style": "github", 
+        "image": "1f474-1f3fe.png", 
+        "unicode": "👴🏾", 
+        "name": "Older Man - Tone 4"
+    }, 
+    "🚐": {
+        "style": "unicode", 
+        "image": "1f690.png", 
+        "name": "Minibus"
+    }, 
+    ":person_doing_cartwheel_tone4:": {
+        "style": "github", 
+        "image": "1f938-1f3fe.png", 
+        "unicode": "🤸🏾", 
+        "name": "Person Doing Cartwheel - Tone 4"
+    }, 
+    ":signal-strength:": {
+        "style": "github", 
+        "image": "1f4f6.png", 
+        "unicode": "📶", 
+        "name": "Antenna With Bars"
+    }, 
+    ":loud_sound:": {
+        "style": "github", 
+        "image": "1f50a.png", 
+        "unicode": "🔊", 
+        "name": "Speaker With Three Sound Waves"
+    }, 
+    "🤥": {
+        "style": "unicode", 
+        "image": "1f925.png", 
+        "name": "Lying Face"
+    }, 
+    ":flag_gh:": {
+        "style": "github", 
+        "image": "1f1ec-1f1ed.png", 
+        "unicode": "🇬🇭", 
+        "name": "Ghana"
+    }, 
+    "🌩": {
+        "style": "unicode", 
+        "image": "1f329.png", 
+        "name": "Cloud With Lightning"
+    }, 
+    ":flag-tw:": {
+        "style": "github", 
+        "image": "1f1f9-1f1fc.png", 
+        "unicode": "🇹🇼", 
+        "name": "The Republic Of China"
+    }, 
+    ":regional_indicator_v:": {
+        "style": "github", 
+        "image": "1f1fb.png", 
+        "unicode": "🇻", 
+        "name": "Regional Indicator Symbol Letter V"
+    }, 
+    "⚰": {
+        "style": "unicode", 
+        "image": "26b0.png", 
+        "name": "Coffin"
+    }, 
+    "🎾": {
+        "style": "unicode", 
+        "image": "1f3be.png", 
+        "name": "Tennis Racquet And Ball"
+    }, 
+    ":point-left-tone3:": {
+        "style": "github", 
+        "image": "1f448-1f3fd.png", 
+        "unicode": "👈🏽", 
+        "name": "White Left Pointing Backhand Index - Tone 3"
+    }, 
+    ":drool:": {
+        "style": "github", 
+        "image": "1f924.png", 
+        "unicode": "🤤", 
+        "name": "Drooling Face"
+    }, 
+    ":tk:": {
+        "style": "github", 
+        "image": "1f1f9-1f1f0.png", 
+        "unicode": "🇹🇰", 
+        "name": "Tokelau"
+    }, 
+    ":watermelon:": {
+        "style": "github", 
+        "image": "1f349.png", 
+        "unicode": "🍉", 
+        "name": "Watermelon"
+    }, 
+    ":speaker:": {
+        "style": "github", 
+        "image": "1f508.png", 
+        "unicode": "🔈", 
+        "name": "Speaker"
+    }, 
+    ":flag-re:": {
+        "style": "github", 
+        "image": "1f1f7-1f1ea.png", 
+        "unicode": "🇷🇪", 
+        "name": "Réunion"
+    }, 
+    "🙏🏼": {
+        "style": "unicode", 
+        "image": "1f64f-1f3fc.png", 
+        "name": "Person With Folded Hands - Tone 2"
+    }, 
+    ":airplane_small:": {
+        "style": "github", 
+        "image": "1f6e9.png", 
+        "unicode": "🛩", 
+        "name": "Small Airplane"
+    }, 
+    "🐒": {
+        "style": "unicode", 
+        "image": "1f412.png", 
+        "name": "Monkey"
+    }, 
+    "💱": {
+        "style": "unicode", 
+        "image": "1f4b1.png", 
+        "name": "Currency Exchange"
+    }, 
+    ":flag_mh:": {
+        "style": "github", 
+        "image": "1f1f2-1f1ed.png", 
+        "unicode": "🇲🇭", 
+        "name": "The Marshall Islands"
+    }, 
+    ":hourglass:": {
+        "style": "github", 
+        "image": "231b.png", 
+        "unicode": "⌛", 
+        "name": "Hourglass"
+    }, 
+    ":flag_ca:": {
+        "style": "github", 
+        "image": "1f1e8-1f1e6.png", 
+        "unicode": "🇨🇦", 
+        "name": "Canada"
+    }, 
+    ":bf:": {
+        "style": "github", 
+        "image": "1f1e7-1f1eb.png", 
+        "unicode": "🇧🇫", 
+        "name": "Burkina Faso"
+    }, 
+    ":flag-kn:": {
+        "style": "github", 
+        "image": "1f1f0-1f1f3.png", 
+        "unicode": "🇰🇳", 
+        "name": "Saint Kitts And Nevis"
+    }, 
+    ":underage:": {
+        "style": "github", 
+        "image": "1f51e.png", 
+        "unicode": "🔞", 
+        "name": "No One Under Eighteen Symbol"
+    }, 
+    "🛑": {
+        "style": "unicode", 
+        "image": "1f6d1.png", 
+        "name": "Octagonal Sign"
+    }, 
+    ":kiss_ww:": {
+        "style": "github", 
+        "image": "1f469-2764-1f48b-1f469.png", 
+        "unicode": "👩❤💋👩", 
+        "name": "Kiss (woman,woman)"
+    }, 
+    ":no_bicycles:": {
+        "style": "github", 
+        "image": "1f6b3.png", 
+        "unicode": "🚳", 
+        "name": "No Bicycles"
+    }, 
+    ":flag-cn:": {
+        "style": "github", 
+        "image": "1f1e8-1f1f3.png", 
+        "unicode": "🇨🇳", 
+        "name": "China"
+    }, 
+    ":sweat-drops:": {
+        "style": "github", 
+        "image": "1f4a6.png", 
+        "unicode": "💦", 
+        "name": "Splashing Sweat Symbol"
+    }, 
+    "⛱": {
+        "style": "unicode", 
+        "image": "26f1.png", 
+        "name": "Umbrella On Ground"
+    }, 
+    ":fist-tone5:": {
+        "style": "github", 
+        "image": "270a-1f3ff.png", 
+        "unicode": "✊🏿", 
+        "name": "Raised Fist - Tone 5"
+    }, 
+    ":princess_tone3:": {
+        "style": "github", 
+        "image": "1f478-1f3fd.png", 
+        "unicode": "👸🏽", 
+        "name": "Princess - Tone 3"
+    }, 
+    "🇿": {
+        "style": "unicode", 
+        "image": "1f1ff.png", 
+        "name": "Regional Indicator Symbol Letter Z"
+    }, 
+    ":monkey_face:": {
+        "style": "github", 
+        "image": "1f435.png", 
+        "unicode": "🐵", 
+        "name": "Monkey Face"
+    }, 
+    "🆔": {
+        "style": "unicode", 
+        "image": "1f194.png", 
+        "name": "Squared Id"
+    }, 
+    ":trident:": {
+        "style": "github", 
+        "image": "1f531.png", 
+        "unicode": "🔱", 
+        "name": "Trident Emblem"
+    }, 
+    ":heart_eyes_cat:": {
+        "style": "github", 
+        "image": "1f63b.png", 
+        "unicode": "😻", 
+        "name": "Smiling Cat Face With Heart-shaped Eyes"
+    }, 
+    "➰": {
+        "style": "unicode", 
+        "image": "27b0.png", 
+        "name": "Curly Loop"
+    }, 
+    ":flag_to:": {
+        "style": "github", 
+        "image": "1f1f9-1f1f4.png", 
+        "unicode": "🇹🇴", 
+        "name": "Tonga"
+    }, 
+    ":flag-ws:": {
+        "style": "github", 
+        "image": "1f1fc-1f1f8.png", 
+        "unicode": "🇼🇸", 
+        "name": "Samoa"
+    }, 
+    "🍓": {
+        "style": "unicode", 
+        "image": "1f353.png", 
+        "name": "Strawberry"
+    }, 
+    ":rocket:": {
+        "style": "github", 
+        "image": "1f680.png", 
+        "unicode": "🚀", 
+        "name": "Rocket"
+    }, 
+    ":flag-bh:": {
+        "style": "github", 
+        "image": "1f1e7-1f1ed.png", 
+        "unicode": "🇧🇭", 
+        "name": "Bahrain"
+    }, 
+    ":massage_tone5:": {
+        "style": "github", 
+        "image": "1f486-1f3ff.png", 
+        "unicode": "💆🏿", 
+        "name": "Face Massage - Tone 5"
+    }, 
+    ":io:": {
+        "style": "github", 
+        "image": "1f1ee-1f1f4.png", 
+        "unicode": "🇮🇴", 
+        "name": "British Indian Ocean Territory"
+    }, 
+    ":five:": {
+        "style": "github", 
+        "image": "0035-20e3.png", 
+        "unicode": "5⃣", 
+        "name": "Keycap Digit Five"
+    }, 
+    ":green_apple:": {
+        "style": "github", 
+        "image": "1f34f.png", 
+        "unicode": "🍏", 
+        "name": "Green Apple"
+    }, 
+    "🏨": {
+        "style": "unicode", 
+        "image": "1f3e8.png", 
+        "name": "Hotel"
+    }, 
+    ":o2:": {
+        "style": "github", 
+        "image": "1f17e.png", 
+        "unicode": "🅾", 
+        "name": "Negative Squared Latin Capital Letter O"
+    }, 
+    ":information-desk-person:": {
+        "style": "github", 
+        "image": "1f481.png", 
+        "unicode": "💁", 
+        "name": "Information Desk Person"
+    }, 
+    ":gu:": {
+        "style": "github", 
+        "image": "1f1ec-1f1fa.png", 
+        "unicode": "🇬🇺", 
+        "name": "Guam"
+    }, 
+    "👽": {
+        "style": "unicode", 
+        "image": "1f47d.png", 
+        "name": "Extraterrestrial Alien"
+    }, 
+    ":reversed_hand_with_middle_finger_extended_tone3:": {
+        "style": "github", 
+        "image": "1f595-1f3fd.png", 
+        "unicode": "🖕🏽", 
+        "name": "Reversed Hand With Middle Finger Extended - Tone 3"
+    }, 
+    "🌂": {
+        "style": "unicode", 
+        "image": "1f302.png", 
+        "name": "Closed Umbrella"
+    }, 
+    ":bow-tone4:": {
+        "style": "github", 
+        "image": "1f647-1f3fe.png", 
+        "unicode": "🙇🏾", 
+        "name": "Person Bowing Deeply - Tone 4"
+    }, 
+    ":flag-gr:": {
+        "style": "github", 
+        "image": "1f1ec-1f1f7.png", 
+        "unicode": "🇬🇷", 
+        "name": "Greece"
+    }, 
+    ":(": {
+        "style": "ascii", 
+        "ascii": ">:[", 
+        "image": "1f61e.png", 
+        "unicode": "😞", 
+        "name": "Disappointed Face"
+    }, 
+    ":city_dusk:": {
+        "style": "github", 
+        "image": "1f306.png", 
+        "unicode": "🌆", 
+        "name": "Cityscape At Dusk"
+    }, 
+    ":)": {
+        "style": "ascii", 
+        "ascii": ":)", 
+        "image": "1f642.png", 
+        "unicode": "🙂", 
+        "name": "Slightly Smiling Face"
+    }, 
+    ":weight_lifter_tone1:": {
+        "style": "github", 
+        "image": "1f3cb-1f3fb.png", 
+        "unicode": "🏋🏻", 
+        "name": "Weight Lifter - Tone 1"
+    }, 
+    ":arrows_counterclockwise:": {
+        "style": "github", 
+        "image": "1f504.png", 
+        "unicode": "🔄", 
+        "name": "Anticlockwise Downwards And Upwards Open Circle Arrows"
+    }, 
+    ":chipmunk:": {
+        "style": "github", 
+        "image": "1f43f.png", 
+        "unicode": "🐿", 
+        "name": "Chipmunk"
+    }, 
+    ":flag_sb:": {
+        "style": "github", 
+        "image": "1f1f8-1f1e7.png", 
+        "unicode": "🇸🇧", 
+        "name": "The Solomon Islands"
+    }, 
+    ":person_frowning_tone5:": {
+        "style": "github", 
+        "image": "1f64d-1f3ff.png", 
+        "unicode": "🙍🏿", 
+        "name": "Person Frowning - Tone 5"
+    }, 
+    "⛏": {
+        "style": "unicode", 
+        "image": "26cf.png", 
+        "name": "Pick"
+    }, 
+    ":flag_eu:": {
+        "style": "github", 
+        "image": "1f1ea-1f1fa.png", 
+        "unicode": "🇪🇺", 
+        "name": "European Union"
+    }, 
+    ":frowning2:": {
+        "style": "github", 
+        "image": "2639.png", 
+        "unicode": "☹", 
+        "name": "White Frowning Face"
+    }, 
+    ":dm:": {
+        "style": "github", 
+        "image": "1f1e9-1f1f2.png", 
+        "unicode": "🇩🇲", 
+        "name": "Dominica"
+    }, 
+    ":ca:": {
+        "style": "github", 
+        "image": "1f1e8-1f1e6.png", 
+        "unicode": "🇨🇦", 
+        "name": "Canada"
+    }, 
+    ":call-me-tone5:": {
+        "style": "github", 
+        "image": "1f919-1f3ff.png", 
+        "unicode": "🤙🏿", 
+        "name": "Call Me Hand - Tone 5"
+    }, 
+    ":smirk-cat:": {
+        "style": "github", 
+        "image": "1f63c.png", 
+        "unicode": "😼", 
+        "name": "Cat Face With Wry Smile"
+    }, 
+    ":tools:": {
+        "style": "github", 
+        "image": "1f6e0.png", 
+        "unicode": "🛠", 
+        "name": "Hammer And Wrench"
+    }, 
+    "🚄": {
+        "style": "unicode", 
+        "image": "1f684.png", 
+        "name": "High-speed Train"
+    }, 
+    ":flag-pf:": {
+        "style": "github", 
+        "image": "1f1f5-1f1eb.png", 
+        "unicode": "🇵🇫", 
+        "name": "French Polynesia"
+    }, 
+    ":skeleton:": {
+        "style": "github", 
+        "image": "1f480.png", 
+        "unicode": "💀", 
+        "name": "Skull"
+    }, 
+    ":double_vertical_bar:": {
+        "style": "github", 
+        "image": "23f8.png", 
+        "unicode": "⏸", 
+        "name": "Double Vertical Bar"
+    }, 
+    ":motorway:": {
+        "style": "github", 
+        "image": "1f6e3.png", 
+        "unicode": "🛣", 
+        "name": "Motorway"
+    }, 
+    "🔙": {
+        "style": "unicode", 
+        "image": "1f519.png", 
+        "name": "Back With Leftwards Arrow Above"
+    }, 
+    ":european-castle:": {
+        "style": "github", 
+        "image": "1f3f0.png", 
+        "unicode": "🏰", 
+        "name": "European Castle"
+    }, 
+    ":radio-button:": {
+        "style": "github", 
+        "image": "1f518.png", 
+        "unicode": "🔘", 
+        "name": "Radio Button"
+    }, 
+    "👃": {
+        "style": "unicode", 
+        "image": "1f443.png", 
+        "name": "Nose"
+    }, 
+    "📘": {
+        "style": "unicode", 
+        "image": "1f4d8.png", 
+        "name": "Blue Book"
+    }, 
+    ":pray-tone1:": {
+        "style": "github", 
+        "image": "1f64f-1f3fb.png", 
+        "unicode": "🙏🏻", 
+        "name": "Person With Folded Hands - Tone 1"
+    }, 
+    ":flag_wf:": {
+        "style": "github", 
+        "image": "1f1fc-1f1eb.png", 
+        "unicode": "🇼🇫", 
+        "name": "Wallis And Futuna"
+    }, 
+    "🍭": {
+        "style": "unicode", 
+        "image": "1f36d.png", 
+        "name": "Lollipop"
+    }, 
+    ":bullettrain-side:": {
+        "style": "github", 
+        "image": "1f684.png", 
+        "unicode": "🚄", 
+        "name": "High-speed Train"
+    }, 
+    "🐨": {
+        "style": "unicode", 
+        "image": "1f428.png", 
+        "name": "Koala"
+    }, 
+    ":ok-woman:": {
+        "style": "github", 
+        "ascii": "*\\0/*", 
+        "image": "1f646.png", 
+        "unicode": "🙆", 
+        "name": "Face With Ok Gesture"
+    }, 
+    ":sign_of_the_horns:": {
+        "style": "github", 
+        "image": "1f918.png", 
+        "unicode": "🤘", 
+        "name": "Sign Of The Horns"
+    }, 
+    ":motor_scooter:": {
+        "style": "github", 
+        "image": "1f6f5.png", 
+        "unicode": "🛵", 
+        "name": "Motor Scooter"
+    }, 
+    "🈂": {
+        "style": "unicode", 
+        "image": "1f202.png", 
+        "name": "Squared Katakana Sa"
+    }, 
+    ":ok_woman_tone4:": {
+        "style": "github", 
+        "image": "1f646-1f3fe.png", 
+        "unicode": "🙆🏾", 
+        "name": "Face With Ok Gesture Tone4"
+    }, 
+    ":fingers-crossed-tone1:": {
+        "style": "github", 
+        "image": "1f91e-1f3fb.png", 
+        "unicode": "🤞🏻", 
+        "name": "Hand With Index And Middle Fingers Crossed - Tone 1"
+    }, 
+    "🎗": {
+        "style": "unicode", 
+        "image": "1f397.png", 
+        "name": "Reminder Ribbon"
+    }, 
+    "🇶🇦": {
+        "style": "unicode", 
+        "image": "1f1f6-1f1e6.png", 
+        "name": "Qatar"
+    }, 
+    "🌬": {
+        "style": "unicode", 
+        "image": "1f32c.png", 
+        "name": "Wind Blowing Face"
+    }, 
+    ":sun_with_face:": {
+        "style": "github", 
+        "image": "1f31e.png", 
+        "unicode": "🌞", 
+        "name": "Sun With Face"
+    }, 
+    ":athletic-shoe:": {
+        "style": "github", 
+        "image": "1f45f.png", 
+        "unicode": "👟", 
+        "name": "Athletic Shoe"
+    }, 
+    "🤰": {
+        "style": "unicode", 
+        "image": "1f930.png", 
+        "name": "Pregnant Woman"
+    }, 
+    ":woman_tone4:": {
+        "style": "github", 
+        "image": "1f469-1f3fe.png", 
+        "unicode": "👩🏾", 
+        "name": "Woman - Tone 4"
+    }, 
+    ":vulcan-tone1:": {
+        "style": "github", 
+        "image": "1f596-1f3fb.png", 
+        "unicode": "🖖🏻", 
+        "name": "Raised Hand With Part Between Middle And Ring Fingers - Tone 1"
+    }, 
+    "🛅": {
+        "style": "unicode", 
+        "image": "1f6c5.png", 
+        "name": "Left Luggage"
+    }, 
+    ":doughnut:": {
+        "style": "github", 
+        "image": "1f369.png", 
+        "unicode": "🍩", 
+        "name": "Doughnut"
+    }, 
+    ":handball-tone1:": {
+        "style": "github", 
+        "image": "1f93e-1f3fb.png", 
+        "unicode": "🤾🏻", 
+        "name": "Handball - Tone 1"
+    }, 
+    ":selfie-tone4:": {
+        "style": "github", 
+        "image": "1f933-1f3fe.png", 
+        "unicode": "🤳🏾", 
+        "name": "Selfie - Tone 4"
+    }, 
+    "❤": {
+        "style": "unicode", 
+        "ascii": "<3", 
+        "image": "2764.png", 
+        "name": "Heavy Black Heart"
+    }, 
+    ":sd:": {
+        "style": "github", 
+        "image": "1f1f8-1f1e9.png", 
+        "unicode": "🇸🇩", 
+        "name": "Sudan"
+    }, 
+    "🇫": {
+        "style": "unicode", 
+        "image": "1f1eb.png", 
+        "name": "Regional Indicator Symbol Letter F"
+    }, 
+    ":speaking_head:": {
+        "style": "github", 
+        "image": "1f5e3.png", 
+        "unicode": "🗣", 
+        "name": "Speaking Head In Silhouette"
+    }, 
+    ":flag_dj:": {
+        "style": "github", 
+        "image": "1f1e9-1f1ef.png", 
+        "unicode": "🇩🇯", 
+        "name": "Djibouti"
+    }, 
+    ":ng:": {
+        "style": "github", 
+        "image": "1f196.png", 
+        "unicode": "🆖", 
+        "name": "Squared Ng"
+    }, 
+    ":older_man_tone1:": {
+        "style": "github", 
+        "image": "1f474-1f3fb.png", 
+        "unicode": "👴🏻", 
+        "name": "Older Man - Tone 1"
+    }, 
+    ":fingers_crossed_tone2:": {
+        "style": "github", 
+        "image": "1f91e-1f3fc.png", 
+        "unicode": "🤞🏼", 
+        "name": "Hand With Index And Middle Fingers Crossed - Tone 2"
+    }, 
+    ":writing-hand-tone1:": {
+        "style": "github", 
+        "image": "270d-1f3fb.png", 
+        "unicode": "✍🏻", 
+        "name": "Writing Hand - Tone 1"
+    }, 
+    "💮": {
+        "style": "unicode", 
+        "image": "1f4ae.png", 
+        "name": "White Flower"
+    }, 
+    ":nine:": {
+        "style": "github", 
+        "image": "0039-20e3.png", 
+        "unicode": "9⃣", 
+        "name": "Keycap Digit Nine"
+    }, 
+    ":comet:": {
+        "style": "github", 
+        "image": "2604.png", 
+        "unicode": "☄", 
+        "name": "Comet"
+    }, 
+    ":flag-tj:": {
+        "style": "github", 
+        "image": "1f1f9-1f1ef.png", 
+        "unicode": "🇹🇯", 
+        "name": "Tajikistan"
+    }, 
+    ":skull_crossbones:": {
+        "style": "github", 
+        "image": "2620.png", 
+        "unicode": "☠", 
+        "name": "Skull And Crossbones"
+    }, 
+    "🇦🇱": {
+        "style": "unicode", 
+        "image": "1f1e6-1f1f1.png", 
+        "name": "Albania"
+    }, 
+    "🇦🇲": {
+        "style": "unicode", 
+        "image": "1f1e6-1f1f2.png", 
+        "name": "Armenia"
+    }, 
+    "🇦🇴": {
+        "style": "unicode", 
+        "image": "1f1e6-1f1f4.png", 
+        "name": "Angola"
+    }, 
+    "🇦🇶": {
+        "style": "unicode", 
+        "image": "1f1e6-1f1f6.png", 
+        "name": "Antarctica"
+    }, 
+    "🇦🇷": {
+        "style": "unicode", 
+        "image": "1f1e6-1f1f7.png", 
+        "name": "Argentina"
+    }, 
+    "🇦🇸": {
+        "style": "unicode", 
+        "image": "1f1e6-1f1f8.png", 
+        "name": "American Samoa"
+    }, 
+    "🇦🇹": {
+        "style": "unicode", 
+        "image": "1f1e6-1f1f9.png", 
+        "name": "Austria"
+    }, 
+    "🇦🇺": {
+        "style": "unicode", 
+        "image": "1f1e6-1f1fa.png", 
+        "name": "Australia"
+    }, 
+    "🇦🇼": {
+        "style": "unicode", 
+        "image": "1f1e6-1f1fc.png", 
+        "name": "Aruba"
+    }, 
+    "🇦🇽": {
+        "style": "unicode", 
+        "image": "1f1e6-1f1fd.png", 
+        "name": "Åland Islands"
+    }, 
+    "🇦🇿": {
+        "style": "unicode", 
+        "image": "1f1e6-1f1ff.png", 
+        "name": "Azerbaijan"
+    }, 
+    "🇦🇨": {
+        "style": "unicode", 
+        "image": "1f1e6-1f1e8.png", 
+        "name": "Ascension"
+    }, 
+    "🇦🇩": {
+        "style": "unicode", 
+        "image": "1f1e6-1f1e9.png", 
+        "name": "Andorra"
+    }, 
+    "🇦🇪": {
+        "style": "unicode", 
+        "image": "1f1e6-1f1ea.png", 
+        "name": "The United Arab Emirates"
+    }, 
+    "🇦🇫": {
+        "style": "unicode", 
+        "image": "1f1e6-1f1eb.png", 
+        "name": "Afghanistan"
+    }, 
+    "🇦🇬": {
+        "style": "unicode", 
+        "image": "1f1e6-1f1ec.png", 
+        "name": "Antigua And Barbuda"
+    }, 
+    "🇦🇮": {
+        "style": "unicode", 
+        "image": "1f1e6-1f1ee.png", 
+        "name": "Anguilla"
+    }, 
+    ":flag-uz:": {
+        "style": "github", 
+        "image": "1f1fa-1f1ff.png", 
+        "unicode": "🇺🇿", 
+        "name": "Uzbekistan"
+    }, 
+    ":low-brightness:": {
+        "style": "github", 
+        "image": "1f505.png", 
+        "unicode": "🔅", 
+        "name": "Low Brightness Symbol"
+    }, 
+    ":blowfish:": {
+        "style": "github", 
+        "image": "1f421.png", 
+        "unicode": "🐡", 
+        "name": "Blowfish"
+    }, 
+    ":printer:": {
+        "style": "github", 
+        "image": "1f5a8.png", 
+        "unicode": "🖨", 
+        "name": "Printer"
+    }, 
+    ":white_square_button:": {
+        "style": "github", 
+        "image": "1f533.png", 
+        "unicode": "🔳", 
+        "name": "White Square Button"
+    }, 
+    ":ab:": {
+        "style": "github", 
+        "image": "1f18e.png", 
+        "unicode": "🆎", 
+        "name": "Negative Squared Ab"
+    }, 
+    ":angel:": {
+        "style": "github", 
+        "image": "1f47c.png", 
+        "unicode": "👼", 
+        "name": "Baby Angel"
+    }, 
+    ":flag-sd:": {
+        "style": "github", 
+        "image": "1f1f8-1f1e9.png", 
+        "unicode": "🇸🇩", 
+        "name": "Sudan"
+    }, 
+    ":eagle:": {
+        "style": "github", 
+        "image": "1f985.png", 
+        "unicode": "🦅", 
+        "name": "Eagle"
+    }, 
+    ":no-mobile-phones:": {
+        "style": "github", 
+        "image": "1f4f5.png", 
+        "unicode": "📵", 
+        "name": "No Mobile Phones"
+    }, 
+    ":bridge-at-night:": {
+        "style": "github", 
+        "image": "1f309.png", 
+        "unicode": "🌉", 
+        "name": "Bridge At Night"
+    }, 
+    "🏁": {
+        "style": "unicode", 
+        "image": "1f3c1.png", 
+        "name": "Chequered Flag"
+    }, 
+    ":ir:": {
+        "style": "github", 
+        "image": "1f1ee-1f1f7.png", 
+        "unicode": "🇮🇷", 
+        "name": "Iran"
+    }, 
+    "🍖": {
+        "style": "unicode", 
+        "image": "1f356.png", 
+        "name": "Meat On Bone"
+    }, 
+    "🕚": {
+        "style": "unicode", 
+        "image": "1f55a.png", 
+        "name": "Clock Face Eleven Oclock"
+    }, 
+    ":joy-cat:": {
+        "style": "github", 
+        "image": "1f639.png", 
+        "unicode": "😹", 
+        "name": "Cat Face With Tears Of Joy"
+    }, 
+    "📯": {
+        "style": "unicode", 
+        "image": "1f4ef.png", 
+        "name": "Postal Horn"
+    }, 
+    ":D": {
+        "style": "ascii", 
+        "ascii": ":D", 
+        "image": "1f603.png", 
+        "unicode": "😃", 
+        "name": "Smiling Face With Open Mouth"
+    }, 
+    ":fallen_leaf:": {
+        "style": "github", 
+        "image": "1f342.png", 
+        "unicode": "🍂", 
+        "name": "Fallen Leaf"
+    }, 
+    ":flag-li:": {
+        "style": "github", 
+        "image": "1f1f1-1f1ee.png", 
+        "unicode": "🇱🇮", 
+        "name": "Liechtenstein"
+    }, 
+    ":track_next:": {
+        "style": "github", 
+        "image": "23ed.png", 
+        "unicode": "⏭", 
+        "name": "Black Right-pointing Double Triangle With Vertical Bar"
+    }, 
+    "💄": {
+        "style": "unicode", 
+        "image": "1f484.png", 
+        "name": "Lipstick"
+    }, 
+    ":indonesia:": {
+        "style": "github", 
+        "image": "1f1ee-1f1e9.png", 
+        "unicode": "🇮🇩", 
+        "name": "Indonesia"
+    }, 
+    "🚙": {
+        "style": "unicode", 
+        "image": "1f699.png", 
+        "name": "Recreational Vehicle"
+    }, 
+    ":flag_sj:": {
+        "style": "github", 
+        "image": "1f1f8-1f1ef.png", 
+        "unicode": "🇸🇯", 
+        "name": "Svalbard And Jan Mayen"
+    }, 
+    ":pm:": {
+        "style": "github", 
+        "image": "1f1f5-1f1f2.png", 
+        "unicode": "🇵🇲", 
+        "name": "Saint Pierre And Miquelon"
+    }, 
+    "🤝": {
+        "style": "unicode", 
+        "image": "1f91d.png", 
+        "name": "Handshake"
+    }, 
+    "☣": {
+        "style": "unicode", 
+        "image": "2623.png", 
+        "name": "Biohazard Sign"
+    }, 
+    ":flag_hn:": {
+        "style": "github", 
+        "image": "1f1ed-1f1f3.png", 
+        "unicode": "🇭🇳", 
+        "name": "Honduras"
+    }, 
+    ":es:": {
+        "style": "github", 
+        "image": "1f1ea-1f1f8.png", 
+        "unicode": "🇪🇸", 
+        "name": "Spain"
+    }, 
+    ":handshake_tone5:": {
+        "style": "github", 
+        "image": "1f91d-1f3ff.png", 
+        "unicode": "🤝🏿", 
+        "name": "Handshake - Tone 5"
+    }, 
+    "💁🏻": {
+        "style": "unicode", 
+        "image": "1f481-1f3fb.png", 
+        "name": "Information Desk Person - Tone 1"
+    }, 
+    "💁🏽": {
+        "style": "unicode", 
+        "image": "1f481-1f3fd.png", 
+        "name": "Information Desk Person - Tone 3"
+    }, 
+    "💁🏼": {
+        "style": "unicode", 
+        "image": "1f481-1f3fc.png", 
+        "name": "Information Desk Person - Tone 2"
+    }, 
+    "💁🏿": {
+        "style": "unicode", 
+        "image": "1f481-1f3ff.png", 
+        "name": "Information Desk Person - Tone 5"
+    }, 
+    "💁🏾": {
+        "style": "unicode", 
+        "image": "1f481-1f3fe.png", 
+        "name": "Information Desk Person - Tone 4"
+    }, 
+    "🙃": {
+        "style": "unicode", 
+        "image": "1f643.png", 
+        "name": "Upside-down Face"
+    }, 
+    ":shrug-tone1:": {
+        "style": "github", 
+        "image": "1f937-1f3fb.png", 
+        "unicode": "🤷🏻", 
+        "name": "Shrug - Tone 1"
+    }, 
+    ":lying_face:": {
+        "style": "github", 
+        "image": "1f925.png", 
+        "unicode": "🤥", 
+        "name": "Lying Face"
+    }, 
+    ":projector:": {
+        "style": "github", 
+        "image": "1f4fd.png", 
+        "unicode": "📽", 
+        "name": "Film Projector"
+    }, 
+    ":middle-finger-tone5:": {
+        "style": "github", 
+        "image": "1f595-1f3ff.png", 
+        "unicode": "🖕🏿", 
+        "name": "Reversed Hand With Middle Finger Extended - Tone 5"
+    }, 
+    ":snow_capped_mountain:": {
+        "style": "github", 
+        "image": "1f3d4.png", 
+        "unicode": "🏔", 
+        "name": "Snow Capped Mountain"
+    }, 
+    ":qa:": {
+        "style": "github", 
+        "image": "1f1f6-1f1e6.png", 
+        "unicode": "🇶🇦", 
+        "name": "Qatar"
+    }, 
+    ":regional_indicator_t:": {
+        "style": "github", 
+        "image": "1f1f9.png", 
+        "unicode": "🇹", 
+        "name": "Regional Indicator Symbol Letter T"
+    }, 
+    ":vs:": {
+        "style": "github", 
+        "image": "1f19a.png", 
+        "unicode": "🆚", 
+        "name": "Squared Vs"
+    }, 
+    "🆗": {
+        "style": "unicode", 
+        "image": "1f197.png", 
+        "name": "Squared Ok"
+    }, 
+    ":sweet-potato:": {
+        "style": "github", 
+        "image": "1f360.png", 
+        "unicode": "🍠", 
+        "name": "Roasted Sweet Potato"
+    }, 
+    ":speech_left:": {
+        "style": "github", 
+        "image": "1f5e8.png", 
+        "unicode": "🗨", 
+        "name": "Left Speech Bubble"
+    }, 
+    ":panda-face:": {
+        "style": "github", 
+        "image": "1f43c.png", 
+        "unicode": "🐼", 
+        "name": "Panda Face"
+    }, 
+    ":raised-hands-tone5:": {
+        "style": "github", 
+        "image": "1f64c-1f3ff.png", 
+        "unicode": "🙌🏿", 
+        "name": "Person Raising Both Hands In Celebration - Tone 5"
+    }, 
+    "📅": {
+        "style": "unicode", 
+        "image": "1f4c5.png", 
+        "name": "Calendar"
+    }, 
+    ":boxing-glove:": {
+        "style": "github", 
+        "image": "1f94a.png", 
+        "unicode": "🥊", 
+        "name": "Boxing Glove"
+    }, 
+    "👚": {
+        "style": "unicode", 
+        "image": "1f45a.png", 
+        "name": "Womans Clothes"
+    }, 
+    "🇵🇼": {
+        "style": "unicode", 
+        "image": "1f1f5-1f1fc.png", 
+        "name": "Palau"
+    }, 
+    "🇵🇾": {
+        "style": "unicode", 
+        "image": "1f1f5-1f1fe.png", 
+        "name": "Paraguay"
+    }, 
+    "🇵🇹": {
+        "style": "unicode", 
+        "image": "1f1f5-1f1f9.png", 
+        "name": "Portugal"
+    }, 
+    "🇵🇸": {
+        "style": "unicode", 
+        "image": "1f1f5-1f1f8.png", 
+        "name": "Palestinian Authority"
+    }, 
+    "🏫": {
+        "style": "unicode", 
+        "image": "1f3eb.png", 
+        "name": "School"
+    }, 
+    ":space_invader:": {
+        "style": "github", 
+        "image": "1f47e.png", 
+        "unicode": "👾", 
+        "name": "Alien Monster"
+    }, 
+    "🇵🇱": {
+        "style": "unicode", 
+        "image": "1f1f5-1f1f1.png", 
+        "name": "Poland"
+    }, 
+    "🇵🇰": {
+        "style": "unicode", 
+        "image": "1f1f5-1f1f0.png", 
+        "name": "Pakistan"
+    }, 
+    "🗯": {
+        "style": "unicode", 
+        "image": "1f5ef.png", 
+        "name": "Right Anger Bubble"
+    }, 
+    ":man_in_tuxedo_tone5:": {
+        "style": "github", 
+        "image": "1f935-1f3ff.png", 
+        "unicode": "🤵🏿", 
+        "name": "Man In Tuxedo - Tone 5"
+    }, 
+    "🇵🇭": {
+        "style": "unicode", 
+        "image": "1f1f5-1f1ed.png", 
+        "name": "The Philippines"
+    }, 
+    ":flag_pa:": {
+        "style": "github", 
+        "image": "1f1f5-1f1e6.png", 
+        "unicode": "🇵🇦", 
+        "name": "Panama"
+    }, 
+    ":tada:": {
+        "style": "github", 
+        "image": "1f389.png", 
+        "unicode": "🎉", 
+        "name": "Party Popper"
+    }, 
+    "🇵🇫": {
+        "style": "unicode", 
+        "image": "1f1f5-1f1eb.png", 
+        "name": "French Polynesia"
+    }, 
+    "🇵🇪": {
+        "style": "unicode", 
+        "image": "1f1f5-1f1ea.png", 
+        "name": "Peru"
+    }, 
+    "⛹": {
+        "style": "unicode", 
+        "image": "26f9.png", 
+        "name": "Person With Ball"
+    }, 
+    ":six:": {
+        "style": "github", 
+        "image": "0036-20e3.png", 
+        "unicode": "6⃣", 
+        "name": "Keycap Digit Six"
+    }, 
+    "🇵🇦": {
+        "style": "unicode", 
+        "image": "1f1f5-1f1e6.png", 
+        "name": "Panama"
+    }, 
+    "🎀": {
+        "style": "unicode", 
+        "image": "1f380.png", 
+        "name": "Ribbon"
+    }, 
+    ":angel_tone4:": {
+        "style": "github", 
+        "image": "1f47c-1f3fe.png", 
+        "unicode": "👼🏾", 
+        "name": "Baby Angel - Tone 4"
+    }, 
+    "😙": {
+        "style": "unicode", 
+        "image": "1f619.png", 
+        "name": "Kissing Face With Smiling Eyes"
+    }, 
+    ":izakaya-lantern:": {
+        "style": "github", 
+        "image": "1f3ee.png", 
+        "unicode": "🏮", 
+        "name": "Izakaya Lantern"
+    }, 
+    ":flag-kh:": {
+        "style": "github", 
+        "image": "1f1f0-1f1ed.png", 
+        "unicode": "🇰🇭", 
+        "name": "Cambodia"
+    }, 
+    ":lv:": {
+        "style": "github", 
+        "image": "1f1f1-1f1fb.png", 
+        "unicode": "🇱🇻", 
+        "name": "Latvia"
+    }, 
+    "🚮": {
+        "style": "unicode", 
+        "image": "1f6ae.png", 
+        "name": "Put Litter In Its Place Symbol"
+    }, 
+    ":flag_cg:": {
+        "style": "github", 
+        "image": "1f1e8-1f1ec.png", 
+        "unicode": "🇨🇬", 
+        "name": "The Republic Of The Congo"
+    }, 
+    ":nail-care-tone2:": {
+        "style": "github", 
+        "image": "1f485-1f3fc.png", 
+        "unicode": "💅🏼", 
+        "name": "Nail Polish - Tone 2"
+    }, 
+    "🥇": {
+        "style": "unicode", 
+        "image": "1f947.png", 
+        "name": "First Place Medal"
+    }, 
+    ":runner-tone2:": {
+        "style": "github", 
+        "image": "1f3c3-1f3fc.png", 
+        "unicode": "🏃🏼", 
+        "name": "Runner - Tone 2"
+    }, 
+    ":santa_tone4:": {
+        "style": "github", 
+        "image": "1f385-1f3fe.png", 
+        "unicode": "🎅🏾", 
+        "name": "Father Christmas - Tone 4"
+    }, 
+    ":fist-tone3:": {
+        "style": "github", 
+        "image": "270a-1f3fd.png", 
+        "unicode": "✊🏽", 
+        "name": "Raised Fist - Tone 3"
+    }, 
+    ":stuffed_flatbread:": {
+        "style": "github", 
+        "image": "1f959.png", 
+        "unicode": "🥙", 
+        "name": "Stuffed Flatbread"
+    }, 
+    ":person_with_pouting_face_tone3:": {
+        "style": "github", 
+        "image": "1f64e-1f3fd.png", 
+        "unicode": "🙎🏽", 
+        "name": "Person With Pouting Face Tone3"
+    }, 
+    ":flag-ir:": {
+        "style": "github", 
+        "image": "1f1ee-1f1f7.png", 
+        "unicode": "🇮🇷", 
+        "name": "Iran"
+    }, 
+    ":flag-ch:": {
+        "style": "github", 
+        "image": "1f1e8-1f1ed.png", 
+        "unicode": "🇨🇭", 
+        "name": "Switzerland"
+    }, 
+    ":princess_tone1:": {
+        "style": "github", 
+        "image": "1f478-1f3fb.png", 
+        "unicode": "👸🏻", 
+        "name": "Princess - Tone 1"
+    }, 
+    ":clapper:": {
+        "style": "github", 
+        "image": "1f3ac.png", 
+        "unicode": "🎬", 
+        "name": "Clapper Board"
+    }, 
+    ":hand-splayed-tone4:": {
+        "style": "github", 
+        "image": "1f590-1f3fe.png", 
+        "unicode": "🖐🏾", 
+        "name": "Raised Hand With Fingers Splayed - Tone 4"
+    }, 
+    "🚗": {
+        "style": "unicode", 
+        "image": "1f697.png", 
+        "name": "Automobile"
+    }, 
+    ":8ball:": {
+        "style": "github", 
+        "image": "1f3b1.png", 
+        "unicode": "🎱", 
+        "name": "Billiards"
+    }, 
+    ":flag_tm:": {
+        "style": "github", 
+        "image": "1f1f9-1f1f2.png", 
+        "unicode": "🇹🇲", 
+        "name": "Turkmenistan"
+    }, 
+    "😬": {
+        "style": "unicode", 
+        "image": "1f62c.png", 
+        "name": "Grimacing Face"
+    }, 
+    "🥜": {
+        "style": "unicode", 
+        "image": "1f95c.png", 
+        "name": "Peanuts"
+    }, 
+    ":kissing_closed_eyes:": {
+        "style": "github", 
+        "image": "1f61a.png", 
+        "unicode": "😚", 
+        "name": "Kissing Face With Closed Eyes"
+    }, 
+    ":person_with_ball:": {
+        "style": "github", 
+        "image": "26f9.png", 
+        "unicode": "⛹", 
+        "name": "Person With Ball"
+    }, 
+    "🏅": {
+        "style": "unicode", 
+        "image": "1f3c5.png", 
+        "name": "Sports Medal"
+    }, 
+    ":v-tone4:": {
+        "style": "github", 
+        "image": "270c-1f3fe.png", 
+        "unicode": "✌🏾", 
+        "name": "Victory Hand - Tone 4"
+    }, 
+    "🕖": {
+        "style": "unicode", 
+        "image": "1f556.png", 
+        "name": "Clock Face Seven Oclock"
+    }, 
+    ":flag-bf:": {
+        "style": "github", 
+        "image": "1f1e7-1f1eb.png", 
+        "unicode": "🇧🇫", 
+        "name": "Burkina Faso"
+    }, 
+    ":shopping-cart:": {
+        "style": "github", 
+        "image": "1f6d2.png", 
+        "unicode": "🛒", 
+        "name": "Shopping Trolley"
+    }, 
+    "🍚": {
+        "style": "unicode", 
+        "image": "1f35a.png", 
+        "name": "Cooked Rice"
+    }, 
+    "🥞": {
+        "style": "unicode", 
+        "image": "1f95e.png", 
+        "name": "Pancakes"
+    }, 
+    ":ear-tone1:": {
+        "style": "github", 
+        "image": "1f442-1f3fb.png", 
+        "unicode": "👂🏻", 
+        "name": "Ear - Tone 1"
+    }, 
+    ":peanuts:": {
+        "style": "github", 
+        "image": "1f95c.png", 
+        "unicode": "🥜", 
+        "name": "Peanuts"
+    }, 
+    "📫": {
+        "style": "unicode", 
+        "image": "1f4eb.png", 
+        "name": "Closed Mailbox With Raised Flag"
+    }, 
+    ":gorilla:": {
+        "style": "github", 
+        "image": "1f98d.png", 
+        "unicode": "🦍", 
+        "name": "Gorilla"
+    }, 
+    ":-Þ": {
+        "style": "ascii", 
+        "ascii": ":P", 
+        "image": "1f61b.png", 
+        "unicode": "😛", 
+        "name": "Face With Stuck-out Tongue"
+    }, 
+    ":whisky:": {
+        "style": "github", 
+        "image": "1f943.png", 
+        "unicode": "🥃", 
+        "name": "Tumbler Glass"
+    }, 
+    "🇵🇷": {
+        "style": "unicode", 
+        "image": "1f1f5-1f1f7.png", 
+        "name": "Puerto Rico"
+    }, 
+    "💀": {
+        "style": "unicode", 
+        "image": "1f480.png", 
+        "name": "Skull"
+    }, 
+    ":fries:": {
+        "style": "github", 
+        "image": "1f35f.png", 
+        "unicode": "🍟", 
+        "name": "French Fries"
+    }, 
+    ":juggler_tone2:": {
+        "style": "github", 
+        "image": "1f939-1f3fc.png", 
+        "unicode": "🤹🏼", 
+        "name": "Juggling - Tone 2"
+    }, 
+    "🇵🇳": {
+        "style": "unicode", 
+        "image": "1f1f5-1f1f3.png", 
+        "name": "Pitcairn"
+    }, 
+    ":back_of_hand_tone2:": {
+        "style": "github", 
+        "image": "1f91a-1f3fc.png", 
+        "unicode": "🤚🏼", 
+        "name": "Raised Back Of Hand - Tone 2"
+    }, 
+    "🇵🇲": {
+        "style": "unicode", 
+        "image": "1f1f5-1f1f2.png", 
+        "name": "Saint Pierre And Miquelon"
+    }, 
+    ":bathtub:": {
+        "style": "github", 
+        "image": "1f6c1.png", 
+        "unicode": "🛁", 
+        "name": "Bathtub"
+    }, 
+    ":flag-gt:": {
+        "style": "github", 
+        "image": "1f1ec-1f1f9.png", 
+        "unicode": "🇬🇹", 
+        "name": "Guatemala"
+    }, 
+    "🇵🇬": {
+        "style": "unicode", 
+        "image": "1f1f5-1f1ec.png", 
+        "name": "Papua New Guinea"
+    }, 
+    ":bath-tone1:": {
+        "style": "github", 
+        "image": "1f6c0-1f3fb.png", 
+        "unicode": "🛀🏻", 
+        "name": "Bath - Tone 1"
+    }, 
+    ":handshake:": {
+        "style": "github", 
+        "image": "1f91d.png", 
+        "unicode": "🤝", 
+        "name": "Handshake"
+    }, 
+    ":older-man:": {
+        "style": "github", 
+        "image": "1f474.png", 
+        "unicode": "👴", 
+        "name": "Older Man"
+    }, 
+    ":chicken:": {
+        "style": "github", 
+        "image": "1f414.png", 
+        "unicode": "🐔", 
+        "name": "Chicken"
+    }, 
+    ":taurus:": {
+        "style": "github", 
+        "image": "2649.png", 
+        "unicode": "♉", 
+        "name": "Taurus"
+    }, 
+    ":flag-nz:": {
+        "style": "github", 
+        "image": "1f1f3-1f1ff.png", 
+        "unicode": "🇳🇿", 
+        "name": "New Zealand"
+    }, 
+    ":scorpion:": {
+        "style": "github", 
+        "image": "1f982.png", 
+        "unicode": "🦂", 
+        "name": "Scorpion"
+    }, 
+    "⭕": {
+        "style": "unicode", 
+        "image": "2b55.png", 
+        "name": "Heavy Large Circle"
+    }, 
+    ":arrow-double-down:": {
+        "style": "github", 
+        "image": "23ec.png", 
+        "unicode": "⏬", 
+        "name": "Black Down-pointing Double Triangle"
+    }, 
+    ":dk:": {
+        "style": "github", 
+        "image": "1f1e9-1f1f0.png", 
+        "unicode": "🇩🇰", 
+        "name": "Denmark"
+    }, 
+    ":hot_dog:": {
+        "style": "github", 
+        "image": "1f32d.png", 
+        "unicode": "🌭", 
+        "name": "Hot Dog"
+    }, 
+    ":co:": {
+        "style": "github", 
+        "image": "1f1e8-1f1f4.png", 
+        "unicode": "🇨🇴", 
+        "name": "Colombia"
+    }, 
+    ":flag-ug:": {
+        "style": "github", 
+        "image": "1f1fa-1f1ec.png", 
+        "unicode": "🇺🇬", 
+        "name": "Uganda"
+    }, 
+    ":call-me-tone3:": {
+        "style": "github", 
+        "image": "1f919-1f3fd.png", 
+        "unicode": "🤙🏽", 
+        "name": "Call Me Hand - Tone 3"
+    }, 
+    ":handshake-tone5:": {
+        "style": "github", 
+        "image": "1f91d-1f3ff.png", 
+        "unicode": "🤝🏿", 
+        "name": "Handshake - Tone 5"
+    }, 
+    "😂": {
+        "style": "unicode", 
+        "ascii": ":')", 
+        "image": "1f602.png", 
+        "name": "Face With Tears Of Joy"
+    }, 
+    ":space-invader:": {
+        "style": "github", 
+        "image": "1f47e.png", 
+        "unicode": "👾", 
+        "name": "Alien Monster"
+    }, 
+    ":zzz:": {
+        "style": "github", 
+        "image": "1f4a4.png", 
+        "unicode": "💤", 
+        "name": "Sleeping Symbol"
+    }, 
+    "✌": {
+        "style": "unicode", 
+        "image": "270c.png", 
+        "name": "Victory Hand"
+    }, 
+    ":nauseated_face:": {
+        "style": "github", 
+        "image": "1f922.png", 
+        "unicode": "🤢", 
+        "name": "Nauseated Face"
+    }, 
+    ":small_red_triangle:": {
+        "style": "github", 
+        "image": "1f53a.png", 
+        "unicode": "🔺", 
+        "name": "Up-pointing Red Triangle"
+    }, 
+    "🇴🇲": {
+        "style": "unicode", 
+        "image": "1f1f4-1f1f2.png", 
+        "name": "Oman"
+    }, 
+    ":nail-care:": {
+        "style": "github", 
+        "image": "1f485.png", 
+        "unicode": "💅", 
+        "name": "Nail Polish"
+    }, 
+    "📁": {
+        "style": "unicode", 
+        "image": "1f4c1.png", 
+        "name": "File Folder"
+    }, 
+    ":baby_tone5:": {
+        "style": "github", 
+        "image": "1f476-1f3ff.png", 
+        "unicode": "👶🏿", 
+        "name": "Baby - Tone 5"
+    }, 
+    ":post_office:": {
+        "style": "github", 
+        "image": "1f3e3.png", 
+        "unicode": "🏣", 
+        "name": "Japanese Post Office"
+    }, 
+    "👖": {
+        "style": "unicode", 
+        "image": "1f456.png", 
+        "name": "Jeans"
+    }, 
+    ":white-large-square:": {
+        "style": "github", 
+        "image": "2b1c.png", 
+        "unicode": "⬜", 
+        "name": "White Large Square"
+    }, 
+    ":pray-tone3:": {
+        "style": "github", 
+        "image": "1f64f-1f3fd.png", 
+        "unicode": "🙏🏽", 
+        "name": "Person With Folded Hands - Tone 3"
+    }, 
+    "🏯": {
+        "style": "unicode", 
+        "image": "1f3ef.png", 
+        "name": "Japanese Castle"
+    }, 
+    ":basketball_player_tone3:": {
+        "style": "github", 
+        "image": "26f9-1f3fd.png", 
+        "unicode": "⛹🏽", 
+        "name": "Person With Ball - Tone 3"
+    }, 
+    ":point-down-tone4:": {
+        "style": "github", 
+        "image": "1f447-1f3fe.png", 
+        "unicode": "👇🏾", 
+        "name": "White Down Pointing Backhand Index - Tone 4"
+    }, 
+    "🎄": {
+        "style": "unicode", 
+        "image": "1f384.png", 
+        "name": "Christmas Tree"
+    }, 
+    ":ok_woman_tone2:": {
+        "style": "github", 
+        "image": "1f646-1f3fc.png", 
+        "unicode": "🙆🏼", 
+        "name": "Face With Ok Gesture Tone2"
+    }, 
+    "🦈": {
+        "style": "unicode", 
+        "image": "1f988.png", 
+        "name": "Shark"
+    }, 
+    ":vulcan-tone3:": {
+        "style": "github", 
+        "image": "1f596-1f3fd.png", 
+        "unicode": "🖖🏽", 
+        "name": "Raised Hand With Part Between Middle And Ring Fingers - Tone 3"
+    }, 
+    ":clock530:": {
+        "style": "github", 
+        "image": "1f560.png", 
+        "unicode": "🕠", 
+        "name": "Clock Face Five-thirty"
+    }, 
+    ":at:": {
+        "style": "github", 
+        "image": "1f1e6-1f1f9.png", 
+        "unicode": "🇦🇹", 
+        "name": "Austria"
+    }, 
+    ":clock930:": {
+        "style": "github", 
+        "image": "1f564.png", 
+        "unicode": "🕤", 
+        "name": "Clock Face Nine-thirty"
+    }, 
+    ":juggling:": {
+        "style": "github", 
+        "image": "1f939.png", 
+        "unicode": "🤹", 
+        "name": "Juggling"
+    }, 
+    "♍": {
+        "style": "unicode", 
+        "image": "264d.png", 
+        "name": "Virgo"
+    }, 
+    ":handball-tone3:": {
+        "style": "github", 
+        "image": "1f93e-1f3fd.png", 
+        "unicode": "🤾🏽", 
+        "name": "Handball - Tone 3"
+    }, 
+    ":wf:": {
+        "style": "github", 
+        "image": "1f1fc-1f1eb.png", 
+        "unicode": "🇼🇫", 
+        "name": "Wallis And Futuna"
+    }, 
+    "👦🏿": {
+        "style": "unicode", 
+        "image": "1f466-1f3ff.png", 
+        "name": "Boy - Tone 5"
+    }, 
+    ":taxi:": {
+        "style": "github", 
+        "image": "1f695.png", 
+        "unicode": "🚕", 
+        "name": "Taxi"
+    }, 
+    ":two-hearts:": {
+        "style": "github", 
+        "image": "1f495.png", 
+        "unicode": "💕", 
+        "name": "Two Hearts"
+    }, 
+    ":sb:": {
+        "style": "github", 
+        "image": "1f1f8-1f1e7.png", 
+        "unicode": "🇸🇧", 
+        "name": "The Solomon Islands"
+    }, 
+    ":spy_tone1:": {
+        "style": "github", 
+        "image": "1f575-1f3fb.png", 
+        "unicode": "🕵🏻", 
+        "name": "Sleuth Or Spy - Tone 1"
+    }, 
+    ":mahjong:": {
+        "style": "github", 
+        "image": "1f004.png", 
+        "unicode": "🀄", 
+        "name": "Mahjong Tile Red Dragon"
+    }, 
+    ":file-folder:": {
+        "style": "github", 
+        "image": "1f4c1.png", 
+        "unicode": "📁", 
+        "name": "File Folder"
+    }, 
+    "🔂": {
+        "style": "unicode", 
+        "image": "1f502.png", 
+        "name": "Clockwise Rightwards And Leftwards Open Circle Arrows With Circled One Overlay"
+    }, 
+    ":ni:": {
+        "style": "github", 
+        "image": "1f1f3-1f1ee.png", 
+        "unicode": "🇳🇮", 
+        "name": "Nicaragua"
+    }, 
+    ":facepalm_tone1:": {
+        "style": "github", 
+        "image": "1f926-1f3fb.png", 
+        "unicode": "🤦🏻", 
+        "name": "Face Palm - Tone 1"
+    }, 
+    ":older_man_tone3:": {
+        "style": "github", 
+        "image": "1f474-1f3fd.png", 
+        "unicode": "👴🏽", 
+        "name": "Older Man - Tone 3"
+    }, 
+    ":fire-engine:": {
+        "style": "github", 
+        "image": "1f692.png", 
+        "unicode": "🚒", 
+        "name": "Fire Engine"
+    }, 
+    "💗": {
+        "style": "unicode", 
+        "image": "1f497.png", 
+        "name": "Growing Heart"
+    }, 
+    ":cityscape:": {
+        "style": "github", 
+        "image": "1f3d9.png", 
+        "unicode": "🏙", 
+        "name": "Cityscape"
+    }, 
+    ":face-palm-tone5:": {
+        "style": "github", 
+        "image": "1f926-1f3ff.png", 
+        "unicode": "🤦🏿", 
+        "name": "Face Palm - Tone 5"
+    }, 
+    ":bento:": {
+        "style": "github", 
+        "image": "1f371.png", 
+        "unicode": "🍱", 
+        "name": "Bento Box"
+    }, 
+    "➡": {
+        "style": "unicode", 
+        "image": "27a1.png", 
+        "name": "Black Rightwards Arrow"
+    }, 
+    "🐬": {
+        "style": "unicode", 
+        "image": "1f42c.png", 
+        "name": "Dolphin"
+    }, 
+    "O:)": {
+        "style": "ascii", 
+        "ascii": "O:-)", 
+        "image": "1f607.png", 
+        "unicode": "😇", 
+        "name": "Smiling Face With Halo"
+    }, 
+    "O:3": {
+        "style": "ascii", 
+        "ascii": "O:-)", 
+        "image": "1f607.png", 
+        "unicode": "😇", 
+        "name": "Smiling Face With Halo"
+    }, 
+    ":flag-tl:": {
+        "style": "github", 
+        "image": "1f1f9-1f1f1.png", 
+        "unicode": "🇹🇱", 
+        "name": "Timor-leste"
+    }, 
+    "🤸🏻": {
+        "style": "unicode", 
+        "image": "1f938-1f3fb.png", 
+        "name": "Person Doing Cartwheel - Tone 1"
+    }, 
+    "🤸🏾": {
+        "style": "unicode", 
+        "image": "1f938-1f3fe.png", 
+        "name": "Person Doing Cartwheel - Tone 4"
+    }, 
+    "🤸🏿": {
+        "style": "unicode", 
+        "image": "1f938-1f3ff.png", 
+        "name": "Person Doing Cartwheel - Tone 5"
+    }, 
+    "🤸🏼": {
+        "style": "unicode", 
+        "image": "1f938-1f3fc.png", 
+        "name": "Person Doing Cartwheel - Tone 2"
+    }, 
+    "🤸🏽": {
+        "style": "unicode", 
+        "image": "1f938-1f3fd.png", 
+        "name": "Person Doing Cartwheel - Tone 3"
+    }, 
+    ":ribbon:": {
+        "style": "github", 
+        "image": "1f380.png", 
+        "unicode": "🎀", 
+        "name": "Ribbon"
+    }, 
+    "♠": {
+        "style": "unicode", 
+        "image": "2660.png", 
+        "name": "Black Spade Suit"
+    }, 
+    "🛫": {
+        "style": "unicode", 
+        "image": "1f6eb.png", 
+        "name": "Airplane Departure"
+    }, 
+    ":curry:": {
+        "style": "github", 
+        "image": "1f35b.png", 
+        "unicode": "🍛", 
+        "name": "Curry And Rice"
+    }, 
+    "⏹": {
+        "style": "unicode", 
+        "image": "23f9.png", 
+        "name": "Black Square For Stop"
+    }, 
+    "🚀": {
+        "style": "unicode", 
+        "image": "1f680.png", 
+        "name": "Rocket"
+    }, 
+    ":kr:": {
+        "style": "github", 
+        "image": "1f1f0-1f1f7.png", 
+        "unicode": "🇰🇷", 
+        "name": "Korea"
+    }, 
+    "🌙": {
+        "style": "unicode", 
+        "image": "1f319.png", 
+        "name": "Crescent Moon"
+    }, 
+    ":arrow_down_small:": {
+        "style": "github", 
+        "image": "1f53d.png", 
+        "unicode": "🔽", 
+        "name": "Down-pointing Small Red Triangle"
+    }, 
+    ":vulcan_tone4:": {
+        "style": "github", 
+        "image": "1f596-1f3fe.png", 
+        "unicode": "🖖🏾", 
+        "name": "Raised Hand With Part Between Middle And Ring Fingers - Tone 4"
+    }, 
+    ":helmet-with-cross:": {
+        "style": "github", 
+        "image": "26d1.png", 
+        "unicode": "⛑", 
+        "name": "Helmet With White Cross"
+    }, 
+    "🎮": {
+        "style": "unicode", 
+        "image": "1f3ae.png", 
+        "name": "Video Game"
+    }, 
+    ":writing_hand_tone5:": {
+        "style": "github", 
+        "image": "270d-1f3ff.png", 
+        "unicode": "✍🏿", 
+        "name": "Writing Hand - Tone 5"
+    }, 
+    ":tickets:": {
+        "style": "github", 
+        "image": "1f39f.png", 
+        "unicode": "🎟", 
+        "name": "Admission Tickets"
+    }, 
+    ":fleur-de-lis:": {
+        "style": "github", 
+        "image": "269c.png", 
+        "unicode": "⚜", 
+        "name": "Fleur-de-lis"
+    }, 
+    ":black-large-square:": {
+        "style": "github", 
+        "image": "2b1b.png", 
+        "unicode": "⬛", 
+        "name": "Black Large Square"
+    }, 
+    ":basketball-player-tone4:": {
+        "style": "github", 
+        "image": "26f9-1f3fe.png", 
+        "unicode": "⛹🏾", 
+        "name": "Person With Ball - Tone 4"
+    }, 
+    ":flag_gf:": {
+        "style": "github", 
+        "image": "1f1ec-1f1eb.png", 
+        "unicode": "🇬🇫", 
+        "name": "French Guiana"
+    }, 
+    ":flag-lk:": {
+        "style": "github", 
+        "image": "1f1f1-1f1f0.png", 
+        "unicode": "🇱🇰", 
+        "name": "Sri Lanka"
+    }, 
+    ":open_file_folder:": {
+        "style": "github", 
+        "image": "1f4c2.png", 
+        "unicode": "📂", 
+        "name": "Open File Folder"
+    }, 
+    ":construction-site:": {
+        "style": "github", 
+        "image": "1f3d7.png", 
+        "unicode": "🏗", 
+        "name": "Building Construction"
+    }, 
+    "🐂": {
+        "style": "unicode", 
+        "image": "1f402.png", 
+        "name": "Ox"
+    }, 
+    ":bullettrain_side:": {
+        "style": "github", 
+        "image": "1f684.png", 
+        "unicode": "🚄", 
+        "name": "High-speed Train"
+    }, 
+    "㊙": {
+        "style": "unicode", 
+        "image": "3299.png", 
+        "name": "Circled Ideograph Secret"
+    }, 
+    ":man_in_tuxedo:": {
+        "style": "github", 
+        "image": "1f935.png", 
+        "unicode": "🤵", 
+        "name": "Man In Tuxedo"
+    }, 
+    ":slot-machine:": {
+        "style": "github", 
+        "image": "1f3b0.png", 
+        "unicode": "🎰", 
+        "name": "Slot Machine"
+    }, 
+    "⚡": {
+        "style": "unicode", 
+        "image": "26a1.png", 
+        "name": "High Voltage Sign"
+    }, 
+    ":grandma_tone5:": {
+        "style": "github", 
+        "image": "1f475-1f3ff.png", 
+        "unicode": "👵🏿", 
+        "name": "Older Woman - Tone 5"
+    }, 
+    ":flag-dk:": {
+        "style": "github", 
+        "image": "1f1e9-1f1f0.png", 
+        "unicode": "🇩🇰", 
+        "name": "Denmark"
+    }, 
+    ":thumbdown_tone5:": {
+        "style": "github", 
+        "image": "1f44e-1f3ff.png", 
+        "unicode": "👎🏿", 
+        "name": "Thumbs Down Sign - Tone 5"
+    }, 
+    ":couch:": {
+        "style": "github", 
+        "image": "1f6cb.png", 
+        "unicode": "🛋", 
+        "name": "Couch And Lamp"
+    }, 
+    "🤴": {
+        "style": "unicode", 
+        "image": "1f934.png", 
+        "name": "Prince"
+    }, 
+    ":flag-ag:": {
+        "style": "github", 
+        "image": "1f1e6-1f1ec.png", 
+        "unicode": "🇦🇬", 
+        "name": "Antigua And Barbuda"
+    }, 
+    "🛁": {
+        "style": "unicode", 
+        "image": "1f6c1.png", 
+        "name": "Bathtub"
+    }, 
+    ":family-mwbb:": {
+        "style": "github", 
+        "image": "1f468-1f469-1f466-1f466.png", 
+        "unicode": "👨👩👦👦", 
+        "name": "Family (man,woman,boy,boy)"
+    }, 
+    ":maple_leaf:": {
+        "style": "github", 
+        "image": "1f341.png", 
+        "unicode": "🍁", 
+        "name": "Maple Leaf"
+    }, 
+    ":shrug-tone3:": {
+        "style": "github", 
+        "image": "1f937-1f3fd.png", 
+        "unicode": "🤷🏽", 
+        "name": "Shrug - Tone 3"
+    }, 
+    ":clock230:": {
+        "style": "github", 
+        "image": "1f55d.png", 
+        "unicode": "🕝", 
+        "name": "Clock Face Two-thirty"
+    }, 
+    ":wine_glass:": {
+        "style": "github", 
+        "image": "1f377.png", 
+        "unicode": "🍷", 
+        "name": "Wine Glass"
+    }, 
+    ":speech-balloon:": {
+        "style": "github", 
+        "image": "1f4ac.png", 
+        "unicode": "💬", 
+        "name": "Speech Balloon"
+    }, 
+    ":heavy-check-mark:": {
+        "style": "github", 
+        "image": "2714.png", 
+        "unicode": "✔", 
+        "name": "Heavy Check Mark"
+    }, 
+    "🇯": {
+        "style": "unicode", 
+        "image": "1f1ef.png", 
+        "name": "Regional Indicator Symbol Letter J"
+    }, 
+    ":regional-indicator-b:": {
+        "style": "github", 
+        "image": "1f1e7.png", 
+        "unicode": "🇧", 
+        "name": "Regional Indicator Symbol Letter B"
+    }, 
+    ":regional_indicator_z:": {
+        "style": "github", 
+        "image": "1f1ff.png", 
+        "unicode": "🇿", 
+        "name": "Regional Indicator Symbol Letter Z"
+    }, 
+    ":vu:": {
+        "style": "github", 
+        "image": "1f1fb-1f1fa.png", 
+        "unicode": "🇻🇺", 
+        "name": "Vanuatu"
+    }, 
+    ":atom_symbol:": {
+        "style": "github", 
+        "image": "269b.png", 
+        "unicode": "⚛", 
+        "name": "Atom Symbol"
+    }, 
+    ":baby_symbol:": {
+        "style": "github", 
+        "image": "1f6bc.png", 
+        "unicode": "🚼", 
+        "name": "Baby Symbol"
+    }, 
+    ":earth-africa:": {
+        "style": "github", 
+        "image": "1f30d.png", 
+        "unicode": "🌍", 
+        "name": "Earth Globe Europe-africa"
+    }, 
+    ":flag_kz:": {
+        "style": "github", 
+        "image": "1f1f0-1f1ff.png", 
+        "unicode": "🇰🇿", 
+        "name": "Kazakhstan"
+    }, 
+    "💅🏽": {
+        "style": "unicode", 
+        "image": "1f485-1f3fd.png", 
+        "name": "Nail Polish - Tone 3"
+    }, 
+    "💅🏼": {
+        "style": "unicode", 
+        "image": "1f485-1f3fc.png", 
+        "name": "Nail Polish - Tone 2"
+    }, 
+    "💅🏿": {
+        "style": "unicode", 
+        "image": "1f485-1f3ff.png", 
+        "name": "Nail Polish - Tone 5"
+    }, 
+    "💅🏾": {
+        "style": "unicode", 
+        "image": "1f485-1f3fe.png", 
+        "name": "Nail Polish - Tone 4"
+    }, 
+    "💅🏻": {
+        "style": "unicode", 
+        "image": "1f485-1f3fb.png", 
+        "name": "Nail Polish - Tone 1"
+    }, 
+    ":on:": {
+        "style": "github", 
+        "image": "1f51b.png", 
+        "unicode": "🔛", 
+        "name": "On With Exclamation Mark With Left Right Arrow Abo"
+    }, 
+    ":red-circle:": {
+        "style": "github", 
+        "image": "1f534.png", 
+        "unicode": "🔴", 
+        "name": "Large Red Circle"
+    }, 
+    ":postbox:": {
+        "style": "github", 
+        "image": "1f4ee.png", 
+        "unicode": "📮", 
+        "name": "Postbox"
+    }, 
+    "🍃": {
+        "style": "unicode", 
+        "image": "1f343.png", 
+        "name": "Leaf Fluttering In Wind"
+    }, 
+    ":tg:": {
+        "style": "github", 
+        "image": "1f1f9-1f1ec.png", 
+        "unicode": "🇹🇬", 
+        "name": "Togo"
+    }, 
+    ":girl_tone2:": {
+        "style": "github", 
+        "image": "1f467-1f3fc.png", 
+        "unicode": "👧🏼", 
+        "name": "Girl - Tone 2"
+    }, 
+    "🏘": {
+        "style": "unicode", 
+        "image": "1f3d8.png", 
+        "name": "House Buildings"
+    }, 
+    ":arrow_up_small:": {
+        "style": "github", 
+        "image": "1f53c.png", 
+        "unicode": "🔼", 
+        "name": "Up-pointing Small Red Triangle"
+    }, 
+    ":blue-heart:": {
+        "style": "github", 
+        "image": "1f499.png", 
+        "unicode": "💙", 
+        "name": "Blue Heart"
+    }, 
+    "👭": {
+        "style": "unicode", 
+        "image": "1f46d.png", 
+        "name": "Two Women Holding Hands"
+    }, 
+    ":flag_pr:": {
+        "style": "github", 
+        "image": "1f1f5-1f1f7.png", 
+        "unicode": "🇵🇷", 
+        "name": "Puerto Rico"
+    }, 
+    ":nail_care_tone4:": {
+        "style": "github", 
+        "image": "1f485-1f3fe.png", 
+        "unicode": "💅🏾", 
+        "name": "Nail Polish - Tone 4"
+    }, 
+    ":bride-with-veil-tone3:": {
+        "style": "github", 
+        "image": "1f470-1f3fd.png", 
+        "unicode": "👰🏽", 
+        "name": "Bride With Veil - Tone 3"
+    }, 
+    "🇧🇷": {
+        "style": "unicode", 
+        "image": "1f1e7-1f1f7.png", 
+        "name": "Brazil"
+    }, 
+    "🇧🇶": {
+        "style": "unicode", 
+        "image": "1f1e7-1f1f6.png", 
+        "name": "Caribbean Netherlands"
+    }, 
+    "🇧🇴": {
+        "style": "unicode", 
+        "image": "1f1e7-1f1f4.png", 
+        "name": "Bolivia"
+    }, 
+    "🇧🇳": {
+        "style": "unicode", 
+        "image": "1f1e7-1f1f3.png", 
+        "name": "Brunei"
+    }, 
+    "🇧🇲": {
+        "style": "unicode", 
+        "image": "1f1e7-1f1f2.png", 
+        "name": "Bermuda"
+    }, 
+    "🇧🇱": {
+        "style": "unicode", 
+        "image": "1f1e7-1f1f1.png", 
+        "name": "Saint Barthélemy"
+    }, 
+    "🇧🇿": {
+        "style": "unicode", 
+        "image": "1f1e7-1f1ff.png", 
+        "name": "Belize"
+    }, 
+    "🇧🇾": {
+        "style": "unicode", 
+        "image": "1f1e7-1f1fe.png", 
+        "name": "Belarus"
+    }, 
+    "🇧🇼": {
+        "style": "unicode", 
+        "image": "1f1e7-1f1fc.png", 
+        "name": "Botswana"
+    }, 
+    "🇧🇻": {
+        "style": "unicode", 
+        "image": "1f1e7-1f1fb.png", 
+        "name": "Bouvet Island"
+    }, 
+    ":soon:": {
+        "style": "github", 
+        "image": "1f51c.png", 
+        "unicode": "🔜", 
+        "name": "Soon With Rightwards Arrow Above"
+    }, 
+    "🇧🇹": {
+        "style": "unicode", 
+        "image": "1f1e7-1f1f9.png", 
+        "name": "Bhutan"
+    }, 
+    "🇧🇸": {
+        "style": "unicode", 
+        "image": "1f1e7-1f1f8.png", 
+        "name": "The Bahamas"
+    }, 
+    "🇧🇧": {
+        "style": "unicode", 
+        "image": "1f1e7-1f1e7.png", 
+        "name": "Barbados"
+    }, 
+    "🇧🇦": {
+        "style": "unicode", 
+        "image": "1f1e7-1f1e6.png", 
+        "name": "Bosnia And Herzegovina"
+    }, 
+    ":yen:": {
+        "style": "github", 
+        "image": "1f4b4.png", 
+        "unicode": "💴", 
+        "name": "Banknote With Yen Sign"
+    }, 
+    ":flag_ml:": {
+        "style": "github", 
+        "image": "1f1f2-1f1f1.png", 
+        "unicode": "🇲🇱", 
+        "name": "Mali"
+    }, 
+    "🇧🇯": {
+        "style": "unicode", 
+        "image": "1f1e7-1f1ef.png", 
+        "name": "Benin"
+    }, 
+    "🇧🇮": {
+        "style": "unicode", 
+        "image": "1f1e7-1f1ee.png", 
+        "name": "Burundi"
+    }, 
+    "🇧🇭": {
+        "style": "unicode", 
+        "image": "1f1e7-1f1ed.png", 
+        "name": "Bahrain"
+    }, 
+    "🇧🇬": {
+        "style": "unicode", 
+        "image": "1f1e7-1f1ec.png", 
+        "name": "Bulgaria"
+    }, 
+    "🇧🇫": {
+        "style": "unicode", 
+        "image": "1f1e7-1f1eb.png", 
+        "name": "Burkina Faso"
+    }, 
+    "🇧🇪": {
+        "style": "unicode", 
+        "image": "1f1e7-1f1ea.png", 
+        "name": "Belgium"
+    }, 
+    "🇧🇩": {
+        "style": "unicode", 
+        "image": "1f1e7-1f1e9.png", 
+        "name": "Bangladesh"
+    }, 
+    ":lt:": {
+        "style": "github", 
+        "image": "1f1f1-1f1f9.png", 
+        "unicode": "🇱🇹", 
+        "name": "Lithuania"
+    }, 
+    ":bb:": {
+        "style": "github", 
+        "image": "1f1e7-1f1e7.png", 
+        "unicode": "🇧🇧", 
+        "name": "Barbados"
+    }, 
+    "🈳": {
+        "style": "unicode", 
+        "image": "1f233.png", 
+        "name": "Squared Cjk Unified Ideograph-7a7a"
+    }, 
+    "😴": {
+        "style": "unicode", 
+        "image": "1f634.png", 
+        "name": "Sleeping Face"
+    }, 
+    ":massage-tone2:": {
+        "style": "github", 
+        "image": "1f486-1f3fc.png", 
+        "unicode": "💆🏼", 
+        "name": "Face Massage - Tone 2"
+    }, 
+    ":flag-qa:": {
+        "style": "github", 
+        "image": "1f1f6-1f1e6.png", 
+        "unicode": "🇶🇦", 
+        "name": "Qatar"
+    }, 
+    "🥖": {
+        "style": "unicode", 
+        "image": "1f956.png", 
+        "name": "Baguette Bread"
+    }, 
+    ":arrow_up:": {
+        "style": "github", 
+        "image": "2b06.png", 
+        "unicode": "⬆", 
+        "name": "Upwards Black Arrow"
+    }, 
+    "🕞": {
+        "style": "unicode", 
+        "image": "1f55e.png", 
+        "name": "Clock Face Three-thirty"
+    }, 
+    ":baby-tone1:": {
+        "style": "github", 
+        "image": "1f476-1f3fb.png", 
+        "unicode": "👶🏻", 
+        "name": "Baby - Tone 1"
+    }, 
+    ":fist-tone1:": {
+        "style": "github", 
+        "image": "270a-1f3fb.png", 
+        "unicode": "✊🏻", 
+        "name": "Raised Fist - Tone 1"
+    }, 
+    ":customs:": {
+        "style": "github", 
+        "image": "1f6c3.png", 
+        "unicode": "🛃", 
+        "name": "Customs"
+    }, 
+    "📳": {
+        "style": "unicode", 
+        "image": "1f4f3.png", 
+        "name": "Vibration Mode"
+    }, 
+    ":thumbsdown-tone3:": {
+        "style": "github", 
+        "image": "1f44e-1f3fd.png", 
+        "unicode": "👎🏽", 
+        "name": "Thumbs Down Sign - Tone 3"
+    }, 
+    ":arrow_left:": {
+        "style": "github", 
+        "image": "2b05.png", 
+        "unicode": "⬅", 
+        "name": "Leftwards Black Arrow"
+    }, 
+    "💈": {
+        "style": "unicode", 
+        "image": "1f488.png", 
+        "name": "Barber Pole"
+    }, 
+    ":cucumber:": {
+        "style": "github", 
+        "image": "1f952.png", 
+        "unicode": "🥒", 
+        "name": "Cucumber"
+    }, 
+    "🌝": {
+        "style": "unicode", 
+        "image": "1f31d.png", 
+        "name": "Full Moon With Face"
+    }, 
+    ":person_with_pouting_face_tone1:": {
+        "style": "github", 
+        "image": "1f64e-1f3fb.png", 
+        "unicode": "🙎🏻", 
+        "name": "Person With Pouting Face Tone1"
+    }, 
+    ":flag_tc:": {
+        "style": "github", 
+        "image": "1f1f9-1f1e8.png", 
+        "unicode": "🇹🇨", 
+        "name": "Turks And Caicos Islands"
+    }, 
+    ":flag_by:": {
+        "style": "github", 
+        "image": "1f1e7-1f1fe.png", 
+        "unicode": "🇧🇾", 
+        "name": "Belarus"
+    }, 
+    "🎲": {
+        "style": "unicode", 
+        "image": "1f3b2.png", 
+        "name": "Game Die"
+    }, 
+    ":flag-bd:": {
+        "style": "github", 
+        "image": "1f1e7-1f1e9.png", 
+        "unicode": "🇧🇩", 
+        "name": "Bangladesh"
+    }, 
+    ":person-with-blond-hair:": {
+        "style": "github", 
+        "image": "1f471.png", 
+        "unicode": "👱", 
+        "name": "Person With Blond Hair"
+    }, 
+    ":family-mmb:": {
+        "style": "github", 
+        "image": "1f468-1f468-1f466.png", 
+        "unicode": "👨👨👦", 
+        "name": "Family (man,man,boy)"
+    }, 
+    "❕": {
+        "style": "unicode", 
+        "image": "2755.png", 
+        "name": "White Exclamation Mark Ornament"
+    }, 
+    ":flag-hr:": {
+        "style": "github", 
+        "image": "1f1ed-1f1f7.png", 
+        "unicode": "🇭🇷", 
+        "name": "Croatia"
+    }, 
+    ":gi:": {
+        "style": "github", 
+        "image": "1f1ec-1f1ee.png", 
+        "unicode": "🇬🇮", 
+        "name": "Gibraltar"
+    }, 
+    ":ear-tone3:": {
+        "style": "github", 
+        "image": "1f442-1f3fd.png", 
+        "unicode": "👂🏽", 
+        "name": "Ear - Tone 3"
+    }, 
+    ":orange-book:": {
+        "style": "github", 
+        "image": "1f4d9.png", 
+        "unicode": "📙", 
+        "name": "Orange Book"
+    }, 
+    "🅱": {
+        "style": "unicode", 
+        "image": "1f171.png", 
+        "name": "Negative Squared Latin Capital Letter B"
+    }, 
+    ":man-with-turban:": {
+        "style": "github", 
+        "image": "1f473.png", 
+        "unicode": "👳", 
+        "name": "Man With Turban"
+    }, 
+    "💂🏼": {
+        "style": "unicode", 
+        "image": "1f482-1f3fc.png", 
+        "name": "Guardsman - Tone 2"
+    }, 
+    "💂🏽": {
+        "style": "unicode", 
+        "image": "1f482-1f3fd.png", 
+        "name": "Guardsman - Tone 3"
+    }, 
+    "💂🏾": {
+        "style": "unicode", 
+        "image": "1f482-1f3fe.png", 
+        "name": "Guardsman - Tone 4"
+    }, 
+    "💂🏿": {
+        "style": "unicode", 
+        "image": "1f482-1f3ff.png", 
+        "name": "Guardsman - Tone 5"
+    }, 
+    "♿": {
+        "style": "unicode", 
+        "image": "267f.png", 
+        "name": "Wheelchair Symbol"
+    }, 
+    "💂🏻": {
+        "style": "unicode", 
+        "image": "1f482-1f3fb.png", 
+        "name": "Guardsman - Tone 1"
+    }, 
+    ":jeans:": {
+        "style": "github", 
+        "image": "1f456.png", 
+        "unicode": "👖", 
+        "name": "Jeans"
+    }, 
+    "😊": {
+        "style": "unicode", 
+        "image": "1f60a.png", 
+        "name": "Smiling Face With Smiling Eyes"
+    }, 
+    ":orthodox_cross:": {
+        "style": "github", 
+        "image": "2626.png", 
+        "unicode": "☦", 
+        "name": "Orthodox Cross"
+    }, 
+    "✔": {
+        "style": "unicode", 
+        "image": "2714.png", 
+        "name": "Heavy Check Mark"
+    }, 
+    ":weight_lifter_tone5:": {
+        "style": "github", 
+        "image": "1f3cb-1f3ff.png", 
+        "unicode": "🏋🏿", 
+        "name": "Weight Lifter - Tone 5"
+    }, 
+    ":person_frowning_tone1:": {
+        "style": "github", 
+        "image": "1f64d-1f3fb.png", 
+        "unicode": "🙍🏻", 
+        "name": "Person Frowning - Tone 1"
+    }, 
+    ":point-up-tone1:": {
+        "style": "github", 
+        "image": "261d-1f3fb.png", 
+        "unicode": "☝🏻", 
+        "name": "White Up Pointing Index - Tone 1"
+    }, 
+    ":flag_ls:": {
+        "style": "github", 
+        "image": "1f1f1-1f1f8.png", 
+        "unicode": "🇱🇸", 
+        "name": "Lesotho"
+    }, 
+    "📉": {
+        "style": "unicode", 
+        "image": "1f4c9.png", 
+        "name": "Chart With Downwards Trend"
+    }, 
+    ":swimmer_tone2:": {
+        "style": "github", 
+        "image": "1f3ca-1f3fc.png", 
+        "unicode": "🏊🏼", 
+        "name": "Swimmer - Tone 2"
+    }, 
+    ":camera-with-flash:": {
+        "style": "github", 
+        "image": "1f4f8.png", 
+        "unicode": "📸", 
+        "name": "Camera With Flash"
+    }, 
+    ":zw:": {
+        "style": "github", 
+        "image": "1f1ff-1f1fc.png", 
+        "unicode": "🇿🇼", 
+        "name": "Zimbabwe"
+    }, 
+    ":cm:": {
+        "style": "github", 
+        "image": "1f1e8-1f1f2.png", 
+        "unicode": "🇨🇲", 
+        "name": "Cameroon"
+    }, 
+    ":slot_machine:": {
+        "style": "github", 
+        "image": "1f3b0.png", 
+        "unicode": "🎰", 
+        "name": "Slot Machine"
+    }, 
+    "🗳": {
+        "style": "unicode", 
+        "image": "1f5f3.png", 
+        "name": "Ballot Box With Ballot"
+    }, 
+    ":couple_with_heart_ww:": {
+        "style": "github", 
+        "image": "1f469-2764-1f469.png", 
+        "unicode": "👩❤👩", 
+        "name": "Couple (woman,woman)"
+    }, 
+    ":call-me-tone1:": {
+        "style": "github", 
+        "image": "1f919-1f3fb.png", 
+        "unicode": "🤙🏻", 
+        "name": "Call Me Hand - Tone 1"
+    }, 
+    ":handshake-tone3:": {
+        "style": "github", 
+        "image": "1f91d-1f3fd.png", 
+        "unicode": "🤝🏽", 
+        "name": "Handshake - Tone 3"
+    }, 
+    "🦀": {
+        "style": "unicode", 
+        "image": "1f980.png", 
+        "name": "Crab"
+    }, 
+    ":rowboat:": {
+        "style": "github", 
+        "image": "1f6a3.png", 
+        "unicode": "🚣", 
+        "name": "Rowboat"
+    }, 
+    ":km:": {
+        "style": "github", 
+        "image": "1f1f0-1f1f2.png", 
+        "unicode": "🇰🇲", 
+        "name": "The Comoros"
+    }, 
+    ":revolving_hearts:": {
+        "style": "github", 
+        "image": "1f49e.png", 
+        "unicode": "💞", 
+        "name": "Revolving Hearts"
+    }, 
+    ":mountain-railway:": {
+        "style": "github", 
+        "image": "1f69e.png", 
+        "unicode": "🚞", 
+        "name": "Mountain Railway"
+    }, 
+    ":man_with_gua_pi_mao:": {
+        "style": "github", 
+        "image": "1f472.png", 
+        "unicode": "👲", 
+        "name": "Man With Gua Pi Mao"
+    }, 
+    "🍇": {
+        "style": "unicode", 
+        "image": "1f347.png", 
+        "name": "Grapes"
+    }, 
+    ":mount-fuji:": {
+        "style": "github", 
+        "image": "1f5fb.png", 
+        "unicode": "🗻", 
+        "name": "Mount Fuji"
+    }, 
+    "🏜": {
+        "style": "unicode", 
+        "image": "1f3dc.png", 
+        "name": "Desert"
+    }, 
+    ":lower_left_paintbrush:": {
+        "style": "github", 
+        "image": "1f58c.png", 
+        "unicode": "🖌", 
+        "name": "Lower Left Paintbrush"
+    }, 
+    ":sunrise_over_mountains:": {
+        "style": "github", 
+        "image": "1f304.png", 
+        "unicode": "🌄", 
+        "name": "Sunrise Over Mountains"
+    }, 
+    "⛪": {
+        "style": "unicode", 
+        "image": "26ea.png", 
+        "name": "Church"
+    }, 
+    ":black_small_square:": {
+        "style": "github", 
+        "image": "25aa.png", 
+        "unicode": "▪", 
+        "name": "Black Small Square"
+    }, 
+    ":couple_with_heart:": {
+        "style": "github", 
+        "image": "1f491.png", 
+        "unicode": "💑", 
+        "name": "Couple With Heart"
+    }, 
+    "🌆": {
+        "style": "unicode", 
+        "image": "1f306.png", 
+        "name": "Cityscape At Dusk"
+    }, 
+    ":motorcycle:": {
+        "style": "github", 
+        "image": "1f3cd.png", 
+        "unicode": "🏍", 
+        "name": "Racing Motorcycle"
+    }, 
+    "🔊": {
+        "style": "unicode", 
+        "image": "1f50a.png", 
+        "name": "Speaker With Three Sound Waves"
+    }, 
+    ":small_blue_diamond:": {
+        "style": "github", 
+        "image": "1f539.png", 
+        "unicode": "🔹", 
+        "name": "Small Blue Diamond"
+    }, 
+    ":couple-ww:": {
+        "style": "github", 
+        "image": "1f469-2764-1f469.png", 
+        "unicode": "👩❤👩", 
+        "name": "Couple (woman,woman)"
+    }, 
+    ":cloud:": {
+        "style": "github", 
+        "image": "2601.png", 
+        "unicode": "☁", 
+        "name": "Cloud"
+    }, 
+    "💟": {
+        "style": "unicode", 
+        "image": "1f49f.png", 
+        "name": "Heart Decoration"
+    }, 
+    ":sparkling_heart:": {
+        "style": "github", 
+        "image": "1f496.png", 
+        "unicode": "💖", 
+        "name": "Sparkling Heart"
+    }, 
+    ":boom:": {
+        "style": "github", 
+        "image": "1f4a5.png", 
+        "unicode": "💥", 
+        "name": "Collision Symbol"
+    }, 
+    ":point_right:": {
+        "style": "github", 
+        "image": "1f449.png", 
+        "unicode": "👉", 
+        "name": "White Right Pointing Backhand Index"
+    }, 
+    ":man_dancing_tone4:": {
+        "style": "github", 
+        "image": "1f57a-1f3fe.png", 
+        "unicode": "🕺🏾", 
+        "name": "Man Dancing - Tone 4"
+    }, 
+    ":race-car:": {
+        "style": "github", 
+        "image": "1f3ce.png", 
+        "unicode": "🏎", 
+        "name": "Racing Car"
+    }, 
+    "🐴": {
+        "style": "unicode", 
+        "image": "1f434.png", 
+        "name": "Horse Face"
+    }, 
+    ":orange_book:": {
+        "style": "github", 
+        "image": "1f4d9.png", 
+        "unicode": "📙", 
+        "name": "Orange Book"
+    }, 
+    ":wave_tone2:": {
+        "style": "github", 
+        "image": "1f44b-1f3fc.png", 
+        "unicode": "👋🏼", 
+        "name": "Waving Hand Sign - Tone 2"
+    }, 
+    ":point-up-2:": {
+        "style": "github", 
+        "image": "1f446.png", 
+        "unicode": "👆", 
+        "name": "White Up Pointing Backhand Index"
+    }, 
+    "⛓": {
+        "style": "unicode", 
+        "image": "26d3.png", 
+        "name": "Chains"
+    }, 
+    ":musical_score:": {
+        "style": "github", 
+        "image": "1f3bc.png", 
+        "unicode": "🎼", 
+        "name": "Musical Score"
+    }, 
+    ":tone5:": {
+        "style": "github", 
+        "image": "1f3ff.png", 
+        "unicode": "🏿", 
+        "name": "Emoji Modifier Fitzpatrick Type-6"
+    }, 
+    ":fingers-crossed-tone5:": {
+        "style": "github", 
+        "image": "1f91e-1f3ff.png", 
+        "unicode": "🤞🏿", 
+        "name": "Hand With Index And Middle Fingers Crossed - Tone 5"
+    }, 
+    "♨": {
+        "style": "unicode", 
+        "image": "2668.png", 
+        "name": "Hot Springs"
+    }, 
+    ":spy_tone3:": {
+        "style": "github", 
+        "image": "1f575-1f3fd.png", 
+        "unicode": "🕵🏽", 
+        "name": "Sleuth Or Spy - Tone 3"
+    }, 
+    ":synagogue:": {
+        "style": "github", 
+        "image": "1f54d.png", 
+        "unicode": "🕍", 
+        "name": "Synagogue"
+    }, 
+    ":flag_im:": {
+        "style": "github", 
+        "image": "1f1ee-1f1f2.png", 
+        "unicode": "🇮🇲", 
+        "name": "Isle Of Man"
+    }, 
+    "🛳": {
+        "style": "unicode", 
+        "image": "1f6f3.png", 
+        "name": "Passenger Ship"
+    }, 
+    ":arrow_up_down:": {
+        "style": "github", 
+        "image": "2195.png", 
+        "unicode": "↕", 
+        "name": "Up Down Arrow"
+    }, 
+    ":left_fist:": {
+        "style": "github", 
+        "image": "1f91b.png", 
+        "unicode": "🤛", 
+        "name": "Left-facing Fist"
+    }, 
+    "🚈": {
+        "style": "unicode", 
+        "image": "1f688.png", 
+        "name": "Light Rail"
+    }, 
+    ":flag_al:": {
+        "style": "github", 
+        "image": "1f1e6-1f1f1.png", 
+        "unicode": "🇦🇱", 
+        "name": "Albania"
+    }, 
+    ":older_man_tone5:": {
+        "style": "github", 
+        "image": "1f474-1f3ff.png", 
+        "unicode": "👴🏿", 
+        "name": "Older Man - Tone 5"
+    }, 
+    ":gay_pride_flag:": {
+        "style": "github", 
+        "image": "1f3f3-1f308.png", 
+        "unicode": "🏳🌈", 
+        "name": "Gay_pride_flag"
+    }, 
+    ":flag-tn:": {
+        "style": "github", 
+        "image": "1f1f9-1f1f3.png", 
+        "unicode": "🇹🇳", 
+        "name": "Tunisia"
+    }, 
+    ":middle_finger_tone4:": {
+        "style": "github", 
+        "image": "1f595-1f3fe.png", 
+        "unicode": "🖕🏾", 
+        "name": "Reversed Hand With Middle Finger Extended - Tone 4"
+    }, 
+    ":ophiuchus:": {
+        "style": "github", 
+        "image": "26ce.png", 
+        "unicode": "⛎", 
+        "name": "Ophiuchus"
+    }, 
+    ":writing-hand-tone5:": {
+        "style": "github", 
+        "image": "270d-1f3ff.png", 
+        "unicode": "✍🏿", 
+        "name": "Writing Hand - Tone 5"
+    }, 
+    ":second-place:": {
+        "style": "github", 
+        "image": "1f948.png", 
+        "unicode": "🥈", 
+        "name": "Second Place Medal"
+    }, 
+    ":pregnant-woman-tone4:": {
+        "style": "github", 
+        "image": "1f930-1f3fe.png", 
+        "unicode": "🤰🏾", 
+        "name": "Pregnant Woman - Tone 4"
+    }, 
+    ":facepalm_tone3:": {
+        "style": "github", 
+        "image": "1f926-1f3fd.png", 
+        "unicode": "🤦🏽", 
+        "name": "Face Palm - Tone 3"
+    }, 
+    "🍱": {
+        "style": "unicode", 
+        "image": "1f371.png", 
+        "name": "Bento Box"
+    }, 
+    "🕵": {
+        "style": "unicode", 
+        "image": "1f575.png", 
+        "name": "Sleuth Or Spy"
+    }, 
+    ":flag-my:": {
+        "style": "github", 
+        "image": "1f1f2-1f1fe.png", 
+        "unicode": "🇲🇾", 
+        "name": "Malaysia"
+    }, 
+    ":kp:": {
+        "style": "github", 
+        "image": "1f1f0-1f1f5.png", 
+        "unicode": "🇰🇵", 
+        "name": "North Korea"
+    }, 
+    "🐊": {
+        "style": "unicode", 
+        "image": "1f40a.png", 
+        "name": "Crocodile"
+    }, 
+    "🎛": {
+        "style": "unicode", 
+        "image": "1f39b.png", 
+        "name": "Control Knobs"
+    }, 
+    "*⃣": {
+        "style": "unicode", 
+        "image": "002a-20e3.png", 
+        "name": "Keycap Asterisk"
+    }, 
+    ":mobile-phone-off:": {
+        "style": "github", 
+        "image": "1f4f4.png", 
+        "unicode": "📴", 
+        "name": "Mobile Phone Off"
+    }, 
+    ":walking_tone5:": {
+        "style": "github", 
+        "image": "1f6b6-1f3ff.png", 
+        "unicode": "🚶🏿", 
+        "name": "Pedestrian - Tone 5"
+    }, 
+    "🌰": {
+        "style": "unicode", 
+        "image": "1f330.png", 
+        "name": "Chestnut"
+    }, 
+    "🔴": {
+        "style": "unicode", 
+        "image": "1f534.png", 
+        "name": "Large Red Circle"
+    }, 
+    ":flag-kw:": {
+        "style": "github", 
+        "image": "1f1f0-1f1fc.png", 
+        "unicode": "🇰🇼", 
+        "name": "Kuwait"
+    }, 
+    ":writing_hand_tone3:": {
+        "style": "github", 
+        "image": "270d-1f3fd.png", 
+        "unicode": "✍🏽", 
+        "name": "Writing Hand - Tone 3"
+    }, 
+    ":top:": {
+        "style": "github", 
+        "image": "1f51d.png", 
+        "unicode": "🔝", 
+        "name": "Top With Upwards Arrow Above"
+    }, 
+    ":construction:": {
+        "style": "github", 
+        "image": "1f6a7.png", 
+        "unicode": "🚧", 
+        "name": "Construction Sign"
+    }, 
+    ":bee:": {
+        "style": "github", 
+        "image": "1f41d.png", 
+        "unicode": "🐝", 
+        "name": "Honeybee"
+    }, 
+    ":flag_np:": {
+        "style": "github", 
+        "image": "1f1f3-1f1f5.png", 
+        "unicode": "🇳🇵", 
+        "name": "Nepal"
+    }, 
+    ":heavy_multiplication_x:": {
+        "style": "github", 
+        "image": "2716.png", 
+        "unicode": "✖", 
+        "name": "Heavy Multiplication X"
+    }, 
+    ":flag_gd:": {
+        "style": "github", 
+        "image": "1f1ec-1f1e9.png", 
+        "unicode": "🇬🇩", 
+        "name": "Grenada"
+    }, 
+    "😗": {
+        "style": "unicode", 
+        "image": "1f617.png", 
+        "name": "Kissing Face"
+    }, 
+    ":badminton:": {
+        "style": "github", 
+        "image": "1f3f8.png", 
+        "unicode": "🏸", 
+        "name": "Badminton Racquet"
+    }, 
+    ":flag_qa:": {
+        "style": "github", 
+        "image": "1f1f6-1f1e6.png", 
+        "unicode": "🇶🇦", 
+        "name": "Qatar"
+    }, 
+    ":pa:": {
+        "style": "github", 
+        "image": "1f1f5-1f1e6.png", 
+        "unicode": "🇵🇦", 
+        "name": "Panama"
+    }, 
+    ":flag-ae:": {
+        "style": "github", 
+        "image": "1f1e6-1f1ea.png", 
+        "unicode": "🇦🇪", 
+        "name": "The United Arab Emirates"
+    }, 
+    ":thumbdown_tone3:": {
+        "style": "github", 
+        "image": "1f44e-1f3fd.png", 
+        "unicode": "👎🏽", 
+        "name": "Thumbs Down Sign - Tone 3"
+    }, 
+    ":grandma_tone3:": {
+        "style": "github", 
+        "image": "1f475-1f3fd.png", 
+        "unicode": "👵🏽", 
+        "name": "Older Woman - Tone 3"
+    }, 
+    ":flag-dm:": {
+        "style": "github", 
+        "image": "1f1e9-1f1f2.png", 
+        "unicode": "🇩🇲", 
+        "name": "Dominica"
+    }, 
+    ":hugging_face:": {
+        "style": "github", 
+        "image": "1f917.png", 
+        "unicode": "🤗", 
+        "name": "Hugging Face"
+    }, 
+    ":hockey:": {
+        "style": "github", 
+        "image": "1f3d2.png", 
+        "unicode": "🏒", 
+        "name": "Ice Hockey Stick And Puck"
+    }, 
+    ":melon:": {
+        "style": "github", 
+        "image": "1f348.png", 
+        "unicode": "🍈", 
+        "name": "Melon"
+    }, 
+    ":family_wwg:": {
+        "style": "github", 
+        "image": "1f469-1f469-1f467.png", 
+        "unicode": "👩👩👧", 
+        "name": "Family (woman,woman,girl)"
+    }, 
+    ":flag_ir:": {
+        "style": "github", 
+        "image": "1f1ee-1f1f7.png", 
+        "unicode": "🇮🇷", 
+        "name": "Iran"
+    }, 
+    ":raised-back-of-hand-tone2:": {
+        "style": "github", 
+        "image": "1f91a-1f3fc.png", 
+        "unicode": "🤚🏼", 
+        "name": "Raised Back Of Hand - Tone 2"
+    }, 
+    "👵": {
+        "style": "unicode", 
+        "image": "1f475.png", 
+        "name": "Older Woman"
+    }, 
+    ":prince-tone2:": {
+        "style": "github", 
+        "image": "1f934-1f3fc.png", 
+        "unicode": "🤴🏼", 
+        "name": "Prince - Tone 2"
+    }, 
+    ":regional_indicator_x:": {
+        "style": "github", 
+        "image": "1f1fd.png", 
+        "unicode": "🇽", 
+        "name": "Regional Indicator Symbol Letter X"
+    }, 
+    "🔆": {
+        "style": "unicode", 
+        "image": "1f506.png", 
+        "name": "High Brightness Symbol"
+    }, 
+    ":cartwheel-tone2:": {
+        "style": "github", 
+        "image": "1f938-1f3fc.png", 
+        "unicode": "🤸🏼", 
+        "name": "Person Doing Cartwheel - Tone 2"
+    }, 
+    ":angry:": {
+        "style": "github", 
+        "ascii": ">:(", 
+        "image": "1f620.png", 
+        "unicode": "😠", 
+        "name": "Angry Face"
+    }, 
+    ":older-man-tone2:": {
+        "style": "github", 
+        "image": "1f474-1f3fc.png", 
+        "unicode": "👴🏼", 
+        "name": "Older Man - Tone 2"
+    }, 
+    "💛": {
+        "style": "unicode", 
+        "image": "1f49b.png", 
+        "name": "Yellow Heart"
+    }, 
+    ":bamboo:": {
+        "style": "github", 
+        "image": "1f38d.png", 
+        "unicode": "🎍", 
+        "name": "Pine Decoration"
+    }, 
+    "↩": {
+        "style": "unicode", 
+        "image": "21a9.png", 
+        "name": "Leftwards Arrow With Hook"
+    }, 
+    "🐰": {
+        "style": "unicode", 
+        "image": "1f430.png", 
+        "name": "Rabbit Face"
+    }, 
+    "🈴": {
+        "style": "unicode", 
+        "image": "1f234.png", 
+        "name": "Squared Cjk Unified Ideograph-5408"
+    }, 
+    ":mountain-bicyclist-tone4:": {
+        "style": "github", 
+        "image": "1f6b5-1f3fe.png", 
+        "unicode": "🚵🏾", 
+        "name": "Mountain Bicyclist - Tone 4"
+    }, 
+    ":heart-eyes-cat:": {
+        "style": "github", 
+        "image": "1f63b.png", 
+        "unicode": "😻", 
+        "name": "Smiling Cat Face With Heart-shaped Eyes"
+    }, 
+    "🎅🏻": {
+        "style": "unicode", 
+        "image": "1f385-1f3fb.png", 
+        "name": "Father Christmas - Tone 1"
+    }, 
+    ":woman-tone3:": {
+        "style": "github", 
+        "image": "1f469-1f3fd.png", 
+        "unicode": "👩🏽", 
+        "name": "Woman - Tone 3"
+    }, 
+    ":girl_tone4:": {
+        "style": "github", 
+        "image": "1f467-1f3fe.png", 
+        "unicode": "👧🏾", 
+        "name": "Girl - Tone 4"
+    }, 
+    ":family-mmgb:": {
+        "style": "github", 
+        "image": "1f468-1f468-1f467-1f466.png", 
+        "unicode": "👨👨👧👦", 
+        "name": "Family (man,man,girl,boy)"
+    }, 
+    ":man_in_tuxedo_tone1:": {
+        "style": "github", 
+        "image": "1f935-1f3fb.png", 
+        "unicode": "🤵🏻", 
+        "name": "Man In Tuxedo - Tone 1"
+    }, 
+    ":family-mwgb:": {
+        "style": "github", 
+        "image": "1f468-1f469-1f467-1f466.png", 
+        "unicode": "👨👩👧👦", 
+        "name": "Family (man,woman,girl,boy)"
+    }, 
+    ":flag_pm:": {
+        "style": "github", 
+        "image": "1f1f5-1f1f2.png", 
+        "unicode": "🇵🇲", 
+        "name": "Saint Pierre And Miquelon"
+    }, 
+    ":umbrella:": {
+        "style": "github", 
+        "image": "2614.png", 
+        "unicode": "☔", 
+        "name": "Umbrella With Rain Drops"
+    }, 
+    "👸🏻": {
+        "style": "unicode", 
+        "image": "1f478-1f3fb.png", 
+        "name": "Princess - Tone 1"
+    }, 
+    "👸🏾": {
+        "style": "unicode", 
+        "image": "1f478-1f3fe.png", 
+        "name": "Princess - Tone 4"
+    }, 
+    "👸🏿": {
+        "style": "unicode", 
+        "image": "1f478-1f3ff.png", 
+        "name": "Princess - Tone 5"
+    }, 
+    "👸🏼": {
+        "style": "unicode", 
+        "image": "1f478-1f3fc.png", 
+        "name": "Princess - Tone 2"
+    }, 
+    "👸🏽": {
+        "style": "unicode", 
+        "image": "1f478-1f3fd.png", 
+        "name": "Princess - Tone 3"
+    }, 
+    "🤙": {
+        "style": "unicode", 
+        "image": "1f919.png", 
+        "name": "Call Me Hand"
+    }, 
+    ":flag_mn:": {
+        "style": "github", 
+        "image": "1f1f2-1f1f3.png", 
+        "unicode": "🇲🇳", 
+        "name": "Mongolia"
+    }, 
+    ":leftwards_arrow_with_hook:": {
+        "style": "github", 
+        "image": "21a9.png", 
+        "unicode": "↩", 
+        "name": "Leftwards Arrow With Hook"
+    }, 
+    ":lr:": {
+        "style": "github", 
+        "image": "1f1f1-1f1f7.png", 
+        "unicode": "🇱🇷", 
+        "name": "Liberia"
+    }, 
+    ":bl:": {
+        "style": "github", 
+        "image": "1f1e7-1f1f1.png", 
+        "unicode": "🇧🇱", 
+        "name": "Saint Barthélemy"
+    }, 
+    ":kissing-cat:": {
+        "style": "github", 
+        "image": "1f63d.png", 
+        "unicode": "😽", 
+        "name": "Kissing Cat Face With Closed Eyes"
+    }, 
+    ":radioactive_sign:": {
+        "style": "github", 
+        "image": "2622.png", 
+        "unicode": "☢", 
+        "name": "Radioactive Sign"
+    }, 
+    "🖖🏻": {
+        "style": "unicode", 
+        "image": "1f596-1f3fb.png", 
+        "name": "Raised Hand With Part Between Middle And Ring Fingers - Tone 1"
+    }, 
+    "🖖🏼": {
+        "style": "unicode", 
+        "image": "1f596-1f3fc.png", 
+        "name": "Raised Hand With Part Between Middle And Ring Fingers - Tone 2"
+    }, 
+    "🖖🏽": {
+        "style": "unicode", 
+        "image": "1f596-1f3fd.png", 
+        "name": "Raised Hand With Part Between Middle And Ring Fingers - Tone 3"
+    }, 
+    "🖖🏾": {
+        "style": "unicode", 
+        "image": "1f596-1f3fe.png", 
+        "name": "Raised Hand With Part Between Middle And Ring Fingers - Tone 4"
+    }, 
+    "🖖🏿": {
+        "style": "unicode", 
+        "image": "1f596-1f3ff.png", 
+        "name": "Raised Hand With Part Between Middle And Ring Fingers - Tone 5"
+    }, 
+    ":crossed_swords:": {
+        "style": "github", 
+        "image": "2694.png", 
+        "unicode": "⚔", 
+        "name": "Crossed Swords"
+    }, 
+    "🙇": {
+        "style": "unicode", 
+        "image": "1f647.png", 
+        "name": "Person Bowing Deeply"
+    }, 
+    ":princess_tone5:": {
+        "style": "github", 
+        "image": "1f478-1f3ff.png", 
+        "unicode": "👸🏿", 
+        "name": "Princess - Tone 5"
+    }, 
+    ":construction-worker-tone4:": {
+        "style": "github", 
+        "image": "1f477-1f3fe.png", 
+        "unicode": "👷🏾", 
+        "name": "Construction Worker - Tone 4"
+    }, 
+    ":flag-cd:": {
+        "style": "github", 
+        "image": "1f1e8-1f1e9.png", 
+        "unicode": "🇨🇩", 
+        "name": "The Democratic Republic Of The Congo"
+    }, 
+    ":baby-tone3:": {
+        "style": "github", 
+        "image": "1f476-1f3fd.png", 
+        "unicode": "👶🏽", 
+        "name": "Baby - Tone 3"
+    }, 
+    ":sob:": {
+        "style": "github", 
+        "image": "1f62d.png", 
+        "unicode": "😭", 
+        "name": "Loudly Crying Face"
+    }, 
+    "⏪": {
+        "style": "unicode", 
+        "image": "23ea.png", 
+        "name": "Black Left-pointing Double Triangle"
+    }, 
+    ":thumbsdown-tone1:": {
+        "style": "github", 
+        "image": "1f44e-1f3fb.png", 
+        "unicode": "👎🏻", 
+        "name": "Thumbs Down Sign - Tone 1"
+    }, 
+    "🍵": {
+        "style": "unicode", 
+        "image": "1f375.png", 
+        "name": "Teacup Without Handle"
+    }, 
+    ":right_anger_bubble:": {
+        "style": "github", 
+        "image": "1f5ef.png", 
+        "unicode": "🗯", 
+        "name": "Right Anger Bubble"
+    }, 
+    ":swimmer_tone4:": {
+        "style": "github", 
+        "image": "1f3ca-1f3fe.png", 
+        "unicode": "🏊🏾", 
+        "name": "Swimmer - Tone 4"
+    }, 
+    ":flag_id:": {
+        "style": "github", 
+        "image": "1f1ee-1f1e9.png", 
+        "unicode": "🇮🇩", 
+        "name": "Indonesia"
+    }, 
+    "🐆": {
+        "style": "unicode", 
+        "image": "1f406.png", 
+        "name": "Leopard"
+    }, 
+    "🎟": {
+        "style": "unicode", 
+        "image": "1f39f.png", 
+        "name": "Admission Tickets"
+    }, 
+    ":cartwheel_tone4:": {
+        "style": "github", 
+        "image": "1f938-1f3fe.png", 
+        "unicode": "🤸🏾", 
+        "name": "Person Doing Cartwheel - Tone 4"
+    }, 
+    ":call_me_hand_tone1:": {
+        "style": "github", 
+        "image": "1f919-1f3fb.png", 
+        "unicode": "🤙🏻", 
+        "name": "Call Me Hand - Tone 1"
+    }, 
+    ":ua:": {
+        "style": "github", 
+        "image": "1f1fa-1f1e6.png", 
+        "unicode": "🇺🇦", 
+        "name": "Ukraine"
+    }, 
+    "🔰": {
+        "style": "unicode", 
+        "image": "1f530.png", 
+        "name": "Japanese Symbol For Beginner"
+    }, 
+    "🌴": {
+        "style": "unicode", 
+        "image": "1f334.png", 
+        "name": "Palm Tree"
+    }, 
+    ":nose-tone1:": {
+        "style": "github", 
+        "image": "1f443-1f3fb.png", 
+        "unicode": "👃🏻", 
+        "name": "Nose - Tone 1"
+    }, 
+    ":flag-bb:": {
+        "style": "github", 
+        "image": "1f1e7-1f1e7.png", 
+        "unicode": "🇧🇧", 
+        "name": "Barbados"
+    }, 
+    ":e-mail:": {
+        "style": "github", 
+        "image": "1f4e7.png", 
+        "unicode": "📧", 
+        "name": "E-mail Symbol"
+    }, 
+    "✊🏼": {
+        "style": "unicode", 
+        "image": "270a-1f3fc.png", 
+        "name": "Raised Fist - Tone 2"
+    }, 
+    "✊🏽": {
+        "style": "unicode", 
+        "image": "270a-1f3fd.png", 
+        "name": "Raised Fist - Tone 3"
+    }, 
+    "✊🏾": {
+        "style": "unicode", 
+        "image": "270a-1f3fe.png", 
+        "name": "Raised Fist - Tone 4"
+    }, 
+    ":left_fist_tone3:": {
+        "style": "github", 
+        "image": "1f91b-1f3fd.png", 
+        "unicode": "🤛🏽", 
+        "name": "Left Facing Fist - Tone 3"
+    }, 
+    "✊🏻": {
+        "style": "unicode", 
+        "image": "270a-1f3fb.png", 
+        "name": "Raised Fist - Tone 1"
+    }, 
+    "🇳": {
+        "style": "unicode", 
+        "image": "1f1f3.png", 
+        "name": "Regional Indicator Symbol Letter N"
+    }, 
+    ":flag-vc:": {
+        "style": "github", 
+        "image": "1f1fb-1f1e8.png", 
+        "unicode": "🇻🇨", 
+        "name": "Saint Vincent And The Grenadines"
+    }, 
+    "⛽": {
+        "style": "unicode", 
+        "image": "26fd.png", 
+        "name": "Fuel Pump"
+    }, 
+    "⚒": {
+        "style": "unicode", 
+        "image": "2692.png", 
+        "name": "Hammer And Pick"
+    }, 
+    "😝": {
+        "style": "unicode", 
+        "image": "1f61d.png", 
+        "name": "Face With Stuck-out Tongue And Tightly-closed Eyes"
+    }, 
+    ":pineapple:": {
+        "style": "github", 
+        "image": "1f34d.png", 
+        "unicode": "🍍", 
+        "name": "Pineapple"
+    }, 
+    ":flag_sd:": {
+        "style": "github", 
+        "image": "1f1f8-1f1e9.png", 
+        "unicode": "🇸🇩", 
+        "name": "Sudan"
+    }, 
+    ":kissing-smiling-eyes:": {
+        "style": "github", 
+        "image": "1f619.png", 
+        "unicode": "😙", 
+        "name": "Kissing Face With Smiling Eyes"
+    }, 
+    "🚲": {
+        "style": "unicode", 
+        "image": "1f6b2.png", 
+        "name": "Bicycle"
+    }, 
+    ":right_fist_tone5:": {
+        "style": "github", 
+        "image": "1f91c-1f3ff.png", 
+        "unicode": "🤜🏿", 
+        "name": "Right Facing Fist - Tone 5"
+    }, 
+    ":man-with-gua-pi-mao-tone2:": {
+        "style": "github", 
+        "image": "1f472-1f3fc.png", 
+        "unicode": "👲🏼", 
+        "name": "Man With Gua Pi Mao - Tone 2"
+    }, 
+    "🥃": {
+        "style": "unicode", 
+        "image": "1f943.png", 
+        "name": "Tumbler Glass"
+    }, 
+    ":point-up-tone3:": {
+        "style": "github", 
+        "image": "261d-1f3fd.png", 
+        "unicode": "☝🏽", 
+        "name": "White Up Pointing Index - Tone 3"
+    }, 
+    ":thumbsup-tone2:": {
+        "style": "github", 
+        "image": "1f44d-1f3fc.png", 
+        "unicode": "👍🏼", 
+        "name": "Thumbs Up Sign - Tone 2"
+    }, 
+    ":raised_hands_tone2:": {
+        "style": "github", 
+        "image": "1f64c-1f3fc.png", 
+        "unicode": "🙌🏼", 
+        "name": "Person Raising Both Hands In Celebration - Tone 2"
+    }, 
+    ":dg:": {
+        "style": "github", 
+        "image": "1f1e9-1f1ec.png", 
+        "unicode": "🇩🇬", 
+        "name": "Diego Garcia"
+    }, 
+    ":mq:": {
+        "style": "github", 
+        "image": "1f1f2-1f1f6.png", 
+        "unicode": "🇲🇶", 
+        "name": "Martinique"
+    }, 
+    ":ck:": {
+        "style": "github", 
+        "image": "1f1e8-1f1f0.png", 
+        "unicode": "🇨🇰", 
+        "name": "Cook Islands"
+    }, 
+    ":ye:": {
+        "style": "github", 
+        "image": "1f1fe-1f1ea.png", 
+        "unicode": "🇾🇪", 
+        "name": "Yemen"
+    }, 
+    ":person_frowning_tone3:": {
+        "style": "github", 
+        "image": "1f64d-1f3fd.png", 
+        "unicode": "🙍🏽", 
+        "name": "Person Frowning - Tone 3"
+    }, 
+    "👱": {
+        "style": "unicode", 
+        "image": "1f471.png", 
+        "name": "Person With Blond Hair"
+    }, 
+    "🤙🏻": {
+        "style": "unicode", 
+        "image": "1f919-1f3fb.png", 
+        "name": "Call Me Hand - Tone 1"
+    }, 
+    "🤙🏽": {
+        "style": "unicode", 
+        "image": "1f919-1f3fd.png", 
+        "name": "Call Me Hand - Tone 3"
+    }, 
+    "🤙🏼": {
+        "style": "unicode", 
+        "image": "1f919-1f3fc.png", 
+        "name": "Call Me Hand - Tone 2"
+    }, 
+    "🤙🏿": {
+        "style": "unicode", 
+        "image": "1f919-1f3ff.png", 
+        "name": "Call Me Hand - Tone 5"
+    }, 
+    "🤙🏾": {
+        "style": "unicode", 
+        "image": "1f919-1f3fe.png", 
+        "name": "Call Me Hand - Tone 4"
+    }, 
+    ":flag_black:": {
+        "style": "github", 
+        "image": "1f3f4.png", 
+        "unicode": "🏴", 
+        "name": "Waving Black Flag"
+    }, 
+    ":baby:": {
+        "style": "github", 
+        "image": "1f476.png", 
+        "unicode": "👶", 
+        "name": "Baby"
+    }, 
+    "🔀": {
+        "style": "unicode", 
+        "image": "1f500.png", 
+        "name": "Twisted Rightwards Arrows"
+    }, 
+    "🚛": {
+        "style": "unicode", 
+        "image": "1f69b.png", 
+        "name": "Articulated Lorry"
+    }, 
+    ":cake:": {
+        "style": "github", 
+        "image": "1f370.png", 
+        "unicode": "🍰", 
+        "name": "Shortcake"
+    }, 
+    ":baggage_claim:": {
+        "style": "github", 
+        "image": "1f6c4.png", 
+        "unicode": "🛄", 
+        "name": "Baggage Claim"
+    }, 
+    ":grey-exclamation:": {
+        "style": "github", 
+        "image": "2755.png", 
+        "unicode": "❕", 
+        "name": "White Exclamation Mark Ornament"
+    }, 
+    "😰": {
+        "style": "unicode", 
+        "image": "1f630.png", 
+        "name": "Face With Open Mouth And Cold Sweat"
+    }, 
+    ":star_of_david:": {
+        "style": "github", 
+        "image": "2721.png", 
+        "unicode": "✡", 
+        "name": "Star Of David"
+    }, 
+    ":guardsman_tone2:": {
+        "style": "github", 
+        "image": "1f482-1f3fc.png", 
+        "unicode": "💂🏼", 
+        "name": "Guardsman - Tone 2"
+    }, 
+    ":disappointed:": {
+        "style": "github", 
+        "ascii": ">:[", 
+        "image": "1f61e.png", 
+        "unicode": "😞", 
+        "name": "Disappointed Face"
+    }, 
+    "🏉": {
+        "style": "unicode", 
+        "image": "1f3c9.png", 
+        "name": "Rugby Football"
+    }, 
+    ":chains:": {
+        "style": "github", 
+        "image": "26d3.png", 
+        "unicode": "⛓", 
+        "name": "Chains"
+    }, 
+    ":heavy_heart_exclamation_mark_ornament:": {
+        "style": "github", 
+        "image": "2763.png", 
+        "unicode": "❣", 
+        "name": "Heavy Heart Exclamation Mark Ornament"
+    }, 
+    "🥚": {
+        "style": "unicode", 
+        "image": "1f95a.png", 
+        "name": "Egg"
+    }, 
+    "🍞": {
+        "style": "unicode", 
+        "image": "1f35e.png", 
+        "name": "Bread"
+    }, 
+    "👳🏻": {
+        "style": "unicode", 
+        "image": "1f473-1f3fb.png", 
+        "name": "Man With Turban - Tone 1"
+    }, 
+    "👳🏿": {
+        "style": "unicode", 
+        "image": "1f473-1f3ff.png", 
+        "name": "Man With Turban - Tone 5"
+    }, 
+    "👳🏾": {
+        "style": "unicode", 
+        "image": "1f473-1f3fe.png", 
+        "name": "Man With Turban - Tone 4"
+    }, 
+    "👳🏽": {
+        "style": "unicode", 
+        "image": "1f473-1f3fd.png", 
+        "name": "Man With Turban - Tone 3"
+    }, 
+    "👳🏼": {
+        "style": "unicode", 
+        "image": "1f473-1f3fc.png", 
+        "name": "Man With Turban - Tone 2"
+    }, 
+    ":v_tone2:": {
+        "style": "github", 
+        "image": "270c-1f3fc.png", 
+        "unicode": "✌🏼", 
+        "name": "Victory Hand - Tone 2"
+    }, 
+    "B)": {
+        "style": "ascii", 
+        "ascii": "B-)", 
+        "image": "1f60e.png", 
+        "unicode": "😎", 
+        "name": "Smiling Face With Sunglasses"
+    }, 
+    ":meat_on_bone:": {
+        "style": "github", 
+        "image": "1f356.png", 
+        "unicode": "🍖", 
+        "name": "Meat On Bone"
+    }, 
+    ":volcano:": {
+        "style": "github", 
+        "image": "1f30b.png", 
+        "unicode": "🌋", 
+        "name": "Volcano"
+    }, 
+    ":thumbup_tone5:": {
+        "style": "github", 
+        "image": "1f44d-1f3ff.png", 
+        "unicode": "👍🏿", 
+        "name": "Thumbs Up Sign - Tone 5"
+    }, 
+    ":flag-pl:": {
+        "style": "github", 
+        "image": "1f1f5-1f1f1.png", 
+        "unicode": "🇵🇱", 
+        "name": "Poland"
+    }, 
+    ":video_game:": {
+        "style": "github", 
+        "image": "1f3ae.png", 
+        "unicode": "🎮", 
+        "name": "Video Game"
+    }, 
+    "◽": {
+        "style": "unicode", 
+        "image": "25fd.png", 
+        "name": "White Medium Small Square"
+    }, 
+    ":arrow-up:": {
+        "style": "github", 
+        "image": "2b06.png", 
+        "unicode": "⬆", 
+        "name": "Upwards Black Arrow"
+    }, 
+    ":hand_splayed_tone3:": {
+        "style": "github", 
+        "image": "1f590-1f3fd.png", 
+        "unicode": "🖐🏽", 
+        "name": "Raised Hand With Fingers Splayed - Tone 3"
+    }, 
+    ":oncoming-police-car:": {
+        "style": "github", 
+        "image": "1f694.png", 
+        "unicode": "🚔", 
+        "name": "Oncoming Police Car"
+    }, 
+    ":swimmer-tone4:": {
+        "style": "github", 
+        "image": "1f3ca-1f3fe.png", 
+        "unicode": "🏊🏾", 
+        "name": "Swimmer - Tone 4"
+    }, 
+    "🔝": {
+        "style": "unicode", 
+        "image": "1f51d.png", 
+        "name": "Top With Upwards Arrow Above"
+    }, 
+    ":man_dancing_tone2:": {
+        "style": "github", 
+        "image": "1f57a-1f3fc.png", 
+        "unicode": "🕺🏼", 
+        "name": "Man Dancing - Tone 2"
+    }, 
+    ":meat-on-bone:": {
+        "style": "github", 
+        "image": "1f356.png", 
+        "unicode": "🍖", 
+        "name": "Meat On Bone"
+    }, 
+    ":spades:": {
+        "style": "github", 
+        "image": "2660.png", 
+        "unicode": "♠", 
+        "name": "Black Spade Suit"
+    }, 
+    ":lips:": {
+        "style": "github", 
+        "image": "1f444.png", 
+        "unicode": "👄", 
+        "name": "Mouth"
+    }, 
+    ":man_tone3:": {
+        "style": "github", 
+        "image": "1f468-1f3fd.png", 
+        "unicode": "👨🏽", 
+        "name": "Man - Tone 3"
+    }, 
+    ":eight_pointed_black_star:": {
+        "style": "github", 
+        "image": "2734.png", 
+        "unicode": "✴", 
+        "name": "Eight Pointed Black Star"
+    }, 
+    "🖲": {
+        "style": "unicode", 
+        "image": "1f5b2.png", 
+        "name": "Trackball"
+    }, 
+    ":carousel_horse:": {
+        "style": "github", 
+        "image": "1f3a0.png", 
+        "unicode": "🎠", 
+        "name": "Carousel Horse"
+    }, 
+    "👇": {
+        "style": "unicode", 
+        "image": "1f447.png", 
+        "name": "White Down Pointing Backhand Index"
+    }, 
+    ":third_place:": {
+        "style": "github", 
+        "image": "1f949.png", 
+        "unicode": "🥉", 
+        "name": "Third Place Medal"
+    }, 
+    ":sn:": {
+        "style": "github", 
+        "image": "1f1f8-1f1f3.png", 
+        "unicode": "🇸🇳", 
+        "name": "Senegal"
+    }, 
+    "📜": {
+        "style": "unicode", 
+        "image": "1f4dc.png", 
+        "name": "Scroll"
+    }, 
+    ":tone3:": {
+        "style": "github", 
+        "image": "1f3fd.png", 
+        "unicode": "🏽", 
+        "name": "Emoji Modifier Fitzpatrick Type-4"
+    }, 
+    "♻": {
+        "style": "unicode", 
+        "image": "267b.png", 
+        "name": "Black Universal Recycling Symbol"
+    }, 
+    ":derelict_house_building:": {
+        "style": "github", 
+        "image": "1f3da.png", 
+        "unicode": "🏚", 
+        "name": "Derelict House Building"
+    }, 
+    "😆": {
+        "style": "unicode", 
+        "ascii": ">:)", 
+        "image": "1f606.png", 
+        "name": "Smiling Face With Open Mouth And Tightly-closed Eyes"
+    }, 
+    ":face-palm-tone1:": {
+        "style": "github", 
+        "image": "1f926-1f3fb.png", 
+        "unicode": "🤦🏻", 
+        "name": "Face Palm - Tone 1"
+    }, 
+    ":middle_finger_tone2:": {
+        "style": "github", 
+        "image": "1f595-1f3fc.png", 
+        "unicode": "🖕🏼", 
+        "name": "Reversed Hand With Middle Finger Extended - Tone 2"
+    }, 
+    ":clock:": {
+        "style": "github", 
+        "image": "1f570.png", 
+        "unicode": "🕰", 
+        "name": "Mantlepiece Clock"
+    }, 
+    ":flower_playing_cards:": {
+        "style": "github", 
+        "image": "1f3b4.png", 
+        "unicode": "🎴", 
+        "name": "Flower Playing Cards"
+    }, 
+    ":wave_tone4:": {
+        "style": "github", 
+        "image": "1f44b-1f3fe.png", 
+        "unicode": "👋🏾", 
+        "name": "Waving Hand Sign - Tone 4"
+    }, 
+    ":high-heel:": {
+        "style": "github", 
+        "image": "1f460.png", 
+        "unicode": "👠", 
+        "name": "High-heeled Shoe"
+    }, 
+    ":yellow-heart:": {
+        "style": "github", 
+        "image": "1f49b.png", 
+        "unicode": "💛", 
+        "name": "Yellow Heart"
+    }, 
+    ":first-place:": {
+        "style": "github", 
+        "image": "1f947.png", 
+        "unicode": "🥇", 
+        "name": "First Place Medal"
+    }, 
+    ":pregnant-woman-tone2:": {
+        "style": "github", 
+        "image": "1f930-1f3fc.png", 
+        "unicode": "🤰🏼", 
+        "name": "Pregnant Woman - Tone 2"
+    }, 
+    ":newspaper:": {
+        "style": "github", 
+        "image": "1f4f0.png", 
+        "unicode": "📰", 
+        "name": "Newspaper"
+    }, 
+    ":facepalm_tone5:": {
+        "style": "github", 
+        "image": "1f926-1f3ff.png", 
+        "unicode": "🤦🏿", 
+        "name": "Face Palm - Tone 5"
+    }, 
+    "🏳": {
+        "style": "unicode", 
+        "image": "1f3f3.png", 
+        "name": "Waving White Flag"
+    }, 
+    ":flag-mw:": {
+        "style": "github", 
+        "image": "1f1f2-1f1fc.png", 
+        "unicode": "🇲🇼", 
+        "name": "Malawi"
+    }, 
+    "🙎🏼": {
+        "style": "unicode", 
+        "image": "1f64e-1f3fc.png", 
+        "name": "Person With Pouting Face Tone2"
+    }, 
+    ":ax:": {
+        "style": "github", 
+        "image": "1f1e6-1f1fd.png", 
+        "unicode": "🇦🇽", 
+        "name": "Åland Islands"
+    }, 
+    "🦄": {
+        "style": "unicode", 
+        "image": "1f984.png", 
+        "name": "Unicorn Face"
+    }, 
+    ":raising_hand:": {
+        "style": "github", 
+        "image": "1f64b.png", 
+        "unicode": "🙋", 
+        "name": "Happy Person Raising One Hand"
+    }, 
+    "🎈": {
+        "style": "unicode", 
+        "image": "1f388.png", 
+        "name": "Balloon"
+    }, 
+    ":last_quarter_moon:": {
+        "style": "github", 
+        "image": "1f317.png", 
+        "unicode": "🌗", 
+        "name": "Last Quarter Moon Symbol"
+    }, 
+    ":vertical-traffic-light:": {
+        "style": "github", 
+        "image": "1f6a6.png", 
+        "unicode": "🚦", 
+        "name": "Vertical Traffic Light"
+    }, 
+    ":flag-sb:": {
+        "style": "github", 
+        "image": "1f1f8-1f1e7.png", 
+        "unicode": "🇸🇧", 
+        "name": "The Solomon Islands"
+    }, 
+    "🐝": {
+        "style": "unicode", 
+        "image": "1f41d.png", 
+        "name": "Honeybee"
+    }, 
+    ":flag-eg:": {
+        "style": "github", 
+        "image": "1f1ea-1f1ec.png", 
+        "unicode": "🇪🇬", 
+        "name": "Egypt"
+    }, 
+    ":raising-hand-tone1:": {
+        "style": "github", 
+        "image": "1f64b-1f3fb.png", 
+        "unicode": "🙋🏻", 
+        "name": "Happy Person Raising One Hand Tone1"
+    }, 
+    "💲": {
+        "style": "unicode", 
+        "image": "1f4b2.png", 
+        "name": "Heavy Dollar Sign"
+    }, 
+    ":man_with_turban_tone1:": {
+        "style": "github", 
+        "image": "1f473-1f3fb.png", 
+        "unicode": "👳🏻", 
+        "name": "Man With Turban - Tone 1"
+    }, 
+    "♑": {
+        "style": "unicode", 
+        "image": "2651.png", 
+        "name": "Capricorn"
+    }, 
+    ":gun:": {
+        "style": "github", 
+        "image": "1f52b.png", 
+        "unicode": "🔫", 
+        "name": "Pistol"
+    }, 
+    "⏏": {
+        "style": "unicode", 
+        "image": "23cf.png", 
+        "name": "Eject Symbol"
+    }, 
+    ":writing_hand_tone1:": {
+        "style": "github", 
+        "image": "270d-1f3fb.png", 
+        "unicode": "✍🏻", 
+        "name": "Writing Hand - Tone 1"
+    }, 
+    "🗜": {
+        "style": "unicode", 
+        "image": "1f5dc.png", 
+        "name": "Compression"
+    }, 
+    ":flag_nr:": {
+        "style": "github", 
+        "image": "1f1f3-1f1f7.png", 
+        "unicode": "🇳🇷", 
+        "name": "Nauru"
+    }, 
+    ":flag_gb:": {
+        "style": "github", 
+        "image": "1f1ec-1f1e7.png", 
+        "unicode": "🇬🇧", 
+        "name": "Great Britain"
+    }, 
+    "0;-)": {
+        "style": "ascii", 
+        "ascii": "O:-)", 
+        "image": "1f607.png", 
+        "unicode": "😇", 
+        "name": "Smiling Face With Halo"
+    }, 
+    ":fingers-crossed:": {
+        "style": "github", 
+        "image": "1f91e.png", 
+        "unicode": "🤞", 
+        "name": "Hand With First And Index Finger Crossed"
+    }, 
+    ":flag-mp:": {
+        "style": "github", 
+        "image": "1f1f2-1f1f5.png", 
+        "unicode": "🇲🇵", 
+        "name": "Northern Mariana Islands"
+    }, 
+    ":muscle-tone5:": {
+        "style": "github", 
+        "image": "1f4aa-1f3ff.png", 
+        "unicode": "💪🏿", 
+        "name": "Flexed Biceps - Tone 5"
+    }, 
+    ":pg:": {
+        "style": "github", 
+        "image": "1f1f5-1f1ec.png", 
+        "unicode": "🇵🇬", 
+        "name": "Papua New Guinea"
+    }, 
+    ":pregnant_woman:": {
+        "style": "github", 
+        "image": "1f930.png", 
+        "unicode": "🤰", 
+        "name": "Pregnant Woman"
+    }, 
+    "🚏": {
+        "style": "unicode", 
+        "image": "1f68f.png", 
+        "name": "Bus Stop"
+    }, 
+    ":flag-do:": {
+        "style": "github", 
+        "image": "1f1e9-1f1f4.png", 
+        "unicode": "🇩🇴", 
+        "name": "The Dominican Republic"
+    }, 
+    ":grandma_tone1:": {
+        "style": "github", 
+        "image": "1f475-1f3fb.png", 
+        "unicode": "👵🏻", 
+        "name": "Older Woman - Tone 1"
+    }, 
+    ":arrow_heading_up:": {
+        "style": "github", 
+        "image": "2934.png", 
+        "unicode": "⤴", 
+        "name": "Arrow Pointing Rightwards Then Curving Upwards"
+    }, 
+    "😤": {
+        "style": "unicode", 
+        "image": "1f624.png", 
+        "name": "Face With Look Of Triumph"
+    }, 
+    ":palm_tree:": {
+        "style": "github", 
+        "image": "1f334.png", 
+        "unicode": "🌴", 
+        "name": "Palm Tree"
+    }, 
+    ":crescent_moon:": {
+        "style": "github", 
+        "image": "1f319.png", 
+        "unicode": "🌙", 
+        "name": "Crescent Moon"
+    }, 
+    ":thumbdown_tone1:": {
+        "style": "github", 
+        "image": "1f44e-1f3fb.png", 
+        "unicode": "👎🏻", 
+        "name": "Thumbs Down Sign - Tone 1"
+    }, 
+    "🕎": {
+        "style": "unicode", 
+        "image": "1f54e.png", 
+        "name": "Menorah With Nine Branches"
+    }, 
+    "📣": {
+        "style": "unicode", 
+        "image": "1f4e3.png", 
+        "name": "Cheering Megaphone"
+    }, 
+    ":regional-indicator-f:": {
+        "style": "github", 
+        "image": "1f1eb.png", 
+        "unicode": "🇫", 
+        "name": "Regional Indicator Symbol Letter F"
+    }, 
+    "👸": {
+        "style": "unicode", 
+        "image": "1f478.png", 
+        "name": "Princess"
+    }, 
+    ":symbols:": {
+        "style": "github", 
+        "image": "1f523.png", 
+        "unicode": "🔣", 
+        "name": "Input Symbol For Symbols"
+    }, 
+    ":raised-hands-tone3:": {
+        "style": "github", 
+        "image": "1f64c-1f3fd.png", 
+        "unicode": "🙌🏽", 
+        "name": "Person Raising Both Hands In Celebration - Tone 3"
+    }, 
+    "🌍": {
+        "style": "unicode", 
+        "image": "1f30d.png", 
+        "name": "Earth Globe Europe-africa"
+    }, 
+    "🤑": {
+        "style": "unicode", 
+        "image": "1f911.png", 
+        "name": "Money-mouth Face"
+    }, 
+    "👎🏻": {
+        "style": "unicode", 
+        "image": "1f44e-1f3fb.png", 
+        "name": "Thumbs Down Sign - Tone 1"
+    }, 
+    "👎🏼": {
+        "style": "unicode", 
+        "image": "1f44e-1f3fc.png", 
+        "name": "Thumbs Down Sign - Tone 2"
+    }, 
+    "👎🏽": {
+        "style": "unicode", 
+        "image": "1f44e-1f3fd.png", 
+        "name": "Thumbs Down Sign - Tone 3"
+    }, 
+    "👎🏾": {
+        "style": "unicode", 
+        "image": "1f44e-1f3fe.png", 
+        "name": "Thumbs Down Sign - Tone 4"
+    }, 
+    "👎🏿": {
+        "style": "unicode", 
+        "image": "1f44e-1f3ff.png", 
+        "name": "Thumbs Down Sign - Tone 5"
+    }, 
+    ":fast_forward:": {
+        "style": "github", 
+        "image": "23e9.png", 
+        "unicode": "⏩", 
+        "name": "Black Right-pointing Double Triangle"
+    }, 
+    ":thumbup:": {
+        "style": "github", 
+        "image": "1f44d.png", 
+        "unicode": "👍", 
+        "name": "Thumbs Up Sign"
+    }, 
+    "🇲🇵": {
+        "style": "unicode", 
+        "image": "1f1f2-1f1f5.png", 
+        "name": "Northern Mariana Islands"
+    }, 
+    "🇲🇶": {
+        "style": "unicode", 
+        "image": "1f1f2-1f1f6.png", 
+        "name": "Martinique"
+    }, 
+    "🎢": {
+        "style": "unicode", 
+        "image": "1f3a2.png", 
+        "name": "Roller Coaster"
+    }, 
+    "🇲🇰": {
+        "style": "unicode", 
+        "image": "1f1f2-1f1f0.png", 
+        "name": "Macedonia"
+    }, 
+    "🇲🇱": {
+        "style": "unicode", 
+        "image": "1f1f2-1f1f1.png", 
+        "name": "Mali"
+    }, 
+    "🇲🇲": {
+        "style": "unicode", 
+        "image": "1f1f2-1f1f2.png", 
+        "name": "Myanmar"
+    }, 
+    "🇲🇳": {
+        "style": "unicode", 
+        "image": "1f1f2-1f1f3.png", 
+        "name": "Mongolia"
+    }, 
+    ":fj:": {
+        "style": "github", 
+        "image": "1f1eb-1f1ef.png", 
+        "unicode": "🇫🇯", 
+        "name": "Fiji"
+    }, 
+    "🇲🇽": {
+        "style": "unicode", 
+        "image": "1f1f2-1f1fd.png", 
+        "name": "Mexico"
+    }, 
+    "🇲🇾": {
+        "style": "unicode", 
+        "image": "1f1f2-1f1fe.png", 
+        "name": "Malaysia"
+    }, 
+    "🇲🇿": {
+        "style": "unicode", 
+        "image": "1f1f2-1f1ff.png", 
+        "name": "Mozambique"
+    }, 
+    "🇲🇸": {
+        "style": "unicode", 
+        "image": "1f1f2-1f1f8.png", 
+        "name": "Montserrat"
+    }, 
+    "🇲🇹": {
+        "style": "unicode", 
+        "image": "1f1f2-1f1f9.png", 
+        "name": "Malta"
+    }, 
+    "🇲🇺": {
+        "style": "unicode", 
+        "image": "1f1f2-1f1fa.png", 
+        "name": "Mauritius"
+    }, 
+    "🇲🇻": {
+        "style": "unicode", 
+        "image": "1f1f2-1f1fb.png", 
+        "name": "Maldives"
+    }, 
+    "🇲🇦": {
+        "style": "unicode", 
+        "image": "1f1f2-1f1e6.png", 
+        "name": "Morocco"
+    }, 
+    "🈷": {
+        "style": "unicode", 
+        "image": "1f237.png", 
+        "name": "Squared Cjk Unified Ideograph-6708"
+    }, 
+    "⛈": {
+        "style": "unicode", 
+        "image": "26c8.png", 
+        "name": "Thunder Cloud And Rain"
+    }, 
+    ":family:": {
+        "style": "github", 
+        "image": "1f46a.png", 
+        "unicode": "👪", 
+        "name": "Family"
+    }, 
+    "🇲🇭": {
+        "style": "unicode", 
+        "image": "1f1f2-1f1ed.png", 
+        "name": "The Marshall Islands"
+    }, 
+    ":flag_sy:": {
+        "style": "github", 
+        "image": "1f1f8-1f1fe.png", 
+        "unicode": "🇸🇾", 
+        "name": "Syria"
+    }, 
+    ":heart-decoration:": {
+        "style": "github", 
+        "image": "1f49f.png", 
+        "unicode": "💟", 
+        "name": "Heart Decoration"
+    }, 
+    "🇲🇨": {
+        "style": "unicode", 
+        "image": "1f1f2-1f1e8.png", 
+        "name": "Monaco"
+    }, 
+    "🇲🇩": {
+        "style": "unicode", 
+        "image": "1f1f2-1f1e9.png", 
+        "name": "Moldova"
+    }, 
+    "🇲🇪": {
+        "style": "unicode", 
+        "image": "1f1f2-1f1ea.png", 
+        "name": "Montenegro"
+    }, 
+    "🇲🇫": {
+        "style": "unicode", 
+        "image": "1f1f2-1f1eb.png", 
+        "name": "Saint Martin"
+    }, 
+    ":flag-xk:": {
+        "style": "github", 
+        "image": "1f1fd-1f1f0.png", 
+        "unicode": "🇽🇰", 
+        "name": "Kosovo"
+    }, 
+    ":woman-tone1:": {
+        "style": "github", 
+        "image": "1f469-1f3fb.png", 
+        "unicode": "👩🏻", 
+        "name": "Woman - Tone 1"
+    }, 
+    ":boy-tone3:": {
+        "style": "github", 
+        "image": "1f466-1f3fd.png", 
+        "unicode": "👦🏽", 
+        "name": "Boy - Tone 3"
+    }, 
+    ":small-blue-diamond:": {
+        "style": "github", 
+        "image": "1f539.png", 
+        "unicode": "🔹", 
+        "name": "Small Blue Diamond"
+    }, 
+    ":flag_pk:": {
+        "style": "github", 
+        "image": "1f1f5-1f1f0.png", 
+        "unicode": "🇵🇰", 
+        "name": "Pakistan"
+    }, 
+    "🇶": {
+        "style": "unicode", 
+        "image": "1f1f6.png", 
+        "name": "Regional Indicator Symbol Letter Q"
+    }, 
+    ":no-bicycles:": {
+        "style": "github", 
+        "image": "1f6b3.png", 
+        "unicode": "🚳", 
+        "name": "No Bicycles"
+    }, 
+    ":man_in_tuxedo_tone3:": {
+        "style": "github", 
+        "image": "1f935-1f3fd.png", 
+        "unicode": "🤵🏽", 
+        "name": "Man In Tuxedo - Tone 3"
+    }, 
+    ":flag_mp:": {
+        "style": "github", 
+        "image": "1f1f2-1f1f5.png", 
+        "unicode": "🇲🇵", 
+        "name": "Northern Mariana Islands"
+    }, 
+    ":key2:": {
+        "style": "github", 
+        "image": "1f5dd.png", 
+        "unicode": "🗝", 
+        "name": "Old Key"
+    }, 
+    ":nail-care-tone4:": {
+        "style": "github", 
+        "image": "1f485-1f3fe.png", 
+        "unicode": "💅🏾", 
+        "name": "Nail Polish - Tone 4"
+    }, 
+    ":family_mwgb:": {
+        "style": "github", 
+        "image": "1f468-1f469-1f467-1f466.png", 
+        "unicode": "👨👩👧👦", 
+        "name": "Family (man,woman,girl,boy)"
+    }, 
+    ":bn:": {
+        "style": "github", 
+        "image": "1f1e7-1f1f3.png", 
+        "unicode": "🇧🇳", 
+        "name": "Brunei"
+    }, 
+    ":flag_cy:": {
+        "style": "github", 
+        "image": "1f1e8-1f1fe.png", 
+        "unicode": "🇨🇾", 
+        "name": "Cyprus"
+    }, 
+    ":flag_ru:": {
+        "style": "github", 
+        "image": "1f1f7-1f1fa.png", 
+        "unicode": "🇷🇺", 
+        "name": "Russia"
+    }, 
+    ":flag_xk:": {
+        "style": "github", 
+        "image": "1f1fd-1f1f0.png", 
+        "unicode": "🇽🇰", 
+        "name": "Kosovo"
+    }, 
+    ":statue-of-liberty:": {
+        "style": "github", 
+        "image": "1f5fd.png", 
+        "unicode": "🗽", 
+        "name": "Statue Of Liberty"
+    }, 
+    ":family_mmgb:": {
+        "style": "github", 
+        "image": "1f468-1f468-1f467-1f466.png", 
+        "unicode": "👨👨👧👦", 
+        "name": "Family (man,man,girl,boy)"
+    }, 
+    "💹": {
+        "style": "unicode", 
+        "image": "1f4b9.png", 
+        "name": "Chart With Upwards Trend And Yen Sign"
+    }, 
+    ":tc:": {
+        "style": "github", 
+        "image": "1f1f9-1f1e8.png", 
+        "unicode": "🇹🇨", 
+        "name": "Turks And Caicos Islands"
+    }, 
+    "❄": {
+        "style": "unicode", 
+        "image": "2744.png", 
+        "name": "Snowflake"
+    }, 
+    ":shrug_tone5:": {
+        "style": "github", 
+        "image": "1f937-1f3ff.png", 
+        "unicode": "🤷🏿", 
+        "name": "Shrug - Tone 5"
+    }, 
+    "🇳🇺": {
+        "style": "unicode", 
+        "image": "1f1f3-1f1fa.png", 
+        "name": "Niue"
+    }, 
+    ":shrimp:": {
+        "style": "github", 
+        "image": "1f990.png", 
+        "unicode": "🦐", 
+        "name": "Shrimp"
+    }, 
+    "👎": {
+        "style": "unicode", 
+        "image": "1f44e.png", 
+        "name": "Thumbs Down Sign"
+    }, 
+    ":camel:": {
+        "style": "github", 
+        "image": "1f42b.png", 
+        "unicode": "🐫", 
+        "name": "Bactrian Camel"
+    }, 
+    ":flag-it:": {
+        "style": "github", 
+        "image": "1f1ee-1f1f9.png", 
+        "unicode": "🇮🇹", 
+        "name": "Italy"
+    }, 
+    ":flag-cf:": {
+        "style": "github", 
+        "image": "1f1e8-1f1eb.png", 
+        "unicode": "🇨🇫", 
+        "name": "Central African Republic"
+    }, 
+    ":construction-worker-tone2:": {
+        "style": "github", 
+        "image": "1f477-1f3fc.png", 
+        "unicode": "👷🏼", 
+        "name": "Construction Worker - Tone 2"
+    }, 
+    "🗣": {
+        "style": "unicode", 
+        "image": "1f5e3.png", 
+        "name": "Speaking Head In Silhouette"
+    }, 
+    ":three:": {
+        "style": "github", 
+        "image": "0033-20e3.png", 
+        "unicode": "3⃣", 
+        "name": "Keycap Digit Three"
+    }, 
+    ":baby-tone5:": {
+        "style": "github", 
+        "image": "1f476-1f3ff.png", 
+        "unicode": "👶🏿", 
+        "name": "Baby - Tone 5"
+    }, 
+    ":stuck-out-tongue-closed-eyes:": {
+        "style": "github", 
+        "image": "1f61d.png", 
+        "unicode": "😝", 
+        "name": "Face With Stuck-out Tongue And Tightly-closed Eyes"
+    }, 
+    ":angel_tone2:": {
+        "style": "github", 
+        "image": "1f47c-1f3fc.png", 
+        "unicode": "👼🏼", 
+        "name": "Baby Angel - Tone 2"
+    }, 
+    "🕸": {
+        "style": "unicode", 
+        "image": "1f578.png", 
+        "name": "Spider Web"
+    }, 
+    ":dancer_tone2:": {
+        "style": "github", 
+        "image": "1f483-1f3fc.png", 
+        "unicode": "💃🏼", 
+        "name": "Dancer - Tone 2"
+    }, 
+    "🤝🏿": {
+        "style": "unicode", 
+        "image": "1f91d-1f3ff.png", 
+        "name": "Handshake - Tone 5"
+    }, 
+    ":ok_hand_tone3:": {
+        "style": "github", 
+        "image": "1f44c-1f3fd.png", 
+        "unicode": "👌🏽", 
+        "name": "Ok Hand Sign - Tone 3"
+    }, 
+    "⬇": {
+        "style": "unicode", 
+        "image": "2b07.png", 
+        "name": "Downwards Black Arrow"
+    }, 
+    "🤝🏻": {
+        "style": "unicode", 
+        "image": "1f91d-1f3fb.png", 
+        "name": "Handshake - Tone 1"
+    }, 
+    ":flag_tg:": {
+        "style": "github", 
+        "image": "1f1f9-1f1ec.png", 
+        "unicode": "🇹🇬", 
+        "name": "Togo"
+    }, 
+    ":card_index:": {
+        "style": "github", 
+        "image": "1f4c7.png", 
+        "unicode": "📇", 
+        "name": "Card Index"
+    }, 
+    ":straight-ruler:": {
+        "style": "github", 
+        "image": "1f4cf.png", 
+        "unicode": "📏", 
+        "name": "Straight Ruler"
+    }, 
+    ":chart_with_downwards_trend:": {
+        "style": "github", 
+        "image": "1f4c9.png", 
+        "unicode": "📉", 
+        "name": "Chart With Downwards Trend"
+    }, 
+    ":call_me_hand_tone3:": {
+        "style": "github", 
+        "image": "1f919-1f3fd.png", 
+        "unicode": "🤙🏽", 
+        "name": "Call Me Hand - Tone 3"
+    }, 
+    ":owl:": {
+        "style": "github", 
+        "image": "1f989.png", 
+        "unicode": "🦉", 
+        "name": "Owl"
+    }, 
+    "🇳🇨": {
+        "style": "unicode", 
+        "image": "1f1f3-1f1e8.png", 
+        "name": "New Caledonia"
+    }, 
+    "🌷": {
+        "style": "unicode", 
+        "image": "1f337.png", 
+        "name": "Tulip"
+    }, 
+    ":runner-tone4:": {
+        "style": "github", 
+        "image": "1f3c3-1f3fe.png", 
+        "unicode": "🏃🏾", 
+        "name": "Runner - Tone 4"
+    }, 
+    ":first_quarter_moon_with_face:": {
+        "style": "github", 
+        "image": "1f31b.png", 
+        "unicode": "🌛", 
+        "name": "First Quarter Moon With Face"
+    }, 
+    ":flag_je:": {
+        "style": "github", 
+        "image": "1f1ef-1f1ea.png", 
+        "unicode": "🇯🇪", 
+        "name": "Jersey"
+    }, 
+    ":military_medal:": {
+        "style": "github", 
+        "image": "1f396.png", 
+        "unicode": "🎖", 
+        "name": "Military Medal"
+    }, 
+    ":flag-yt:": {
+        "style": "github", 
+        "image": "1f1fe-1f1f9.png", 
+        "unicode": "🇾🇹", 
+        "name": "Mayotte"
+    }, 
+    ":flag-hn:": {
+        "style": "github", 
+        "image": "1f1ed-1f1f3.png", 
+        "unicode": "🇭🇳", 
+        "name": "Honduras"
+    }, 
+    ":trumpet:": {
+        "style": "github", 
+        "image": "1f3ba.png", 
+        "unicode": "🎺", 
+        "name": "Trumpet"
+    }, 
+    "🏌": {
+        "style": "unicode", 
+        "image": "1f3cc.png", 
+        "name": "Golfer"
+    }, 
+    "🤶🏻": {
+        "style": "unicode", 
+        "image": "1f936-1f3fb.png", 
+        "name": "Mother Christmas - Tone 1"
+    }, 
+    "🤶🏼": {
+        "style": "unicode", 
+        "image": "1f936-1f3fc.png", 
+        "name": "Mother Christmas - Tone 2"
+    }, 
+    "🤶🏽": {
+        "style": "unicode", 
+        "image": "1f936-1f3fd.png", 
+        "name": "Mother Christmas - Tone 3"
+    }, 
+    "🤶🏾": {
+        "style": "unicode", 
+        "image": "1f936-1f3fe.png", 
+        "name": "Mother Christmas - Tone 4"
+    }, 
+    "🤶🏿": {
+        "style": "unicode", 
+        "image": "1f936-1f3ff.png", 
+        "name": "Mother Christmas - Tone 5"
+    }, 
+    "⏬": {
+        "style": "unicode", 
+        "image": "23ec.png", 
+        "name": "Black Down-pointing Double Triangle"
+    }, 
+    ":flag-va:": {
+        "style": "github", 
+        "image": "1f1fb-1f1e6.png", 
+        "unicode": "🇻🇦", 
+        "name": "The Vatican City"
+    }, 
+    ":atom:": {
+        "style": "github", 
+        "image": "269b.png", 
+        "unicode": "⚛", 
+        "name": "Atom Symbol"
+    }, 
+    ":middle_finger:": {
+        "style": "github", 
+        "image": "1f595.png", 
+        "unicode": "🖕", 
+        "name": "Reversed Hand With Middle Finger Extended"
+    }, 
+    ":smiling_imp:": {
+        "style": "github", 
+        "image": "1f608.png", 
+        "unicode": "😈", 
+        "name": "Smiling Face With Horns"
+    }, 
+    "💏": {
+        "style": "unicode", 
+        "image": "1f48f.png", 
+        "name": "Kiss"
+    }, 
+    ":bath-tone2:": {
+        "style": "github", 
+        "image": "1f6c0-1f3fc.png", 
+        "unicode": "🛀🏼", 
+        "name": "Bath - Tone 2"
+    }, 
+    "🐤": {
+        "style": "unicode", 
+        "image": "1f424.png", 
+        "name": "Baby Chick"
+    }, 
+    ":woman_tone1:": {
+        "style": "github", 
+        "image": "1f469-1f3fb.png", 
+        "unicode": "👩🏻", 
+        "name": "Woman - Tone 1"
+    }, 
+    ":stew:": {
+        "style": "github", 
+        "image": "1f372.png", 
+        "unicode": "🍲", 
+        "name": "Pot Of Food"
+    }, 
+    ":womans_clothes:": {
+        "style": "github", 
+        "image": "1f45a.png", 
+        "unicode": "👚", 
+        "name": "Womans Clothes"
+    }, 
+    ":flag_fi:": {
+        "style": "github", 
+        "image": "1f1eb-1f1ee.png", 
+        "unicode": "🇫🇮", 
+        "name": "Finland"
+    }, 
+    ":thumbsup-tone4:": {
+        "style": "github", 
+        "image": "1f44d-1f3fe.png", 
+        "unicode": "👍🏾", 
+        "name": "Thumbs Up Sign - Tone 4"
+    }, 
+    ":de:": {
+        "style": "github", 
+        "image": "1f1e9-1f1ea.png", 
+        "unicode": "🇩🇪", 
+        "name": "Germany"
+    }, 
+    ":ms:": {
+        "style": "github", 
+        "image": "1f1f2-1f1f8.png", 
+        "unicode": "🇲🇸", 
+        "name": "Montserrat"
+    }, 
+    "🥒": {
+        "style": "unicode", 
+        "image": "1f952.png", 
+        "name": "Cucumber"
+    }, 
+    ":ci:": {
+        "style": "github", 
+        "image": "1f1e8-1f1ee.png", 
+        "unicode": "🇨🇮", 
+        "name": "Côte D’ivoire"
+    }, 
+    ":kiss-mm:": {
+        "style": "github", 
+        "image": "1f468-2764-1f48b-1f468.png", 
+        "unicode": "👨❤💋👨", 
+        "name": "Kiss (man,man)"
+    }, 
+    ":point-up-tone5:": {
+        "style": "github", 
+        "image": "261d-1f3ff.png", 
+        "unicode": "☝🏿", 
+        "name": "White Up Pointing Index - Tone 5"
+    }, 
+    "👉🏻": {
+        "style": "unicode", 
+        "image": "1f449-1f3fb.png", 
+        "name": "White Right Pointing Backhand Index - Tone 1"
+    }, 
+    "👉🏽": {
+        "style": "unicode", 
+        "image": "1f449-1f3fd.png", 
+        "name": "White Right Pointing Backhand Index - Tone 3"
+    }, 
+    "👉🏼": {
+        "style": "unicode", 
+        "image": "1f449-1f3fc.png", 
+        "name": "White Right Pointing Backhand Index - Tone 2"
+    }, 
+    ":flag-ua:": {
+        "style": "github", 
+        "image": "1f1fa-1f1e6.png", 
+        "unicode": "🇺🇦", 
+        "name": "Ukraine"
+    }, 
+    ":rewind:": {
+        "style": "github", 
+        "image": "23ea.png", 
+        "unicode": "⏪", 
+        "name": "Black Left-pointing Double Triangle"
+    }, 
+    "🤛🏻": {
+        "style": "unicode", 
+        "image": "1f91b-1f3fb.png", 
+        "name": "Left Facing Fist - Tone 1"
+    }, 
+    "🤛🏿": {
+        "style": "unicode", 
+        "image": "1f91b-1f3ff.png", 
+        "name": "Left Facing Fist - Tone 5"
+    }, 
+    "🤛🏾": {
+        "style": "unicode", 
+        "image": "1f91b-1f3fe.png", 
+        "name": "Left Facing Fist - Tone 4"
+    }, 
+    "🤛🏽": {
+        "style": "unicode", 
+        "image": "1f91b-1f3fd.png", 
+        "name": "Left Facing Fist - Tone 3"
+    }, 
+    "🤛🏼": {
+        "style": "unicode", 
+        "image": "1f91b-1f3fc.png", 
+        "name": "Left Facing Fist - Tone 2"
+    }, 
+    ":airplane:": {
+        "style": "github", 
+        "image": "2708.png", 
+        "unicode": "✈", 
+        "name": "Airplane"
+    }, 
+    ":spider-web:": {
+        "style": "github", 
+        "image": "1f578.png", 
+        "unicode": "🕸", 
+        "name": "Spider Web"
+    }, 
+    ":anger:": {
+        "style": "github", 
+        "image": "1f4a2.png", 
+        "unicode": "💢", 
+        "name": "Anger Symbol"
+    }, 
+    "☃": {
+        "style": "unicode", 
+        "image": "2603.png", 
+        "name": "Snowman"
+    }, 
+    ":haircut-tone5:": {
+        "style": "github", 
+        "image": "1f487-1f3ff.png", 
+        "unicode": "💇🏿", 
+        "name": "Haircut - Tone 5"
+    }, 
+    "⏭": {
+        "style": "unicode", 
+        "image": "23ed.png", 
+        "name": "Black Right-pointing Double Triangle With Vertical Bar"
+    }, 
+    ":dark_sunglasses:": {
+        "style": "github", 
+        "image": "1f576.png", 
+        "unicode": "🕶", 
+        "name": "Dark Sunglasses"
+    }, 
+    ":ki:": {
+        "style": "github", 
+        "image": "1f1f0-1f1ee.png", 
+        "unicode": "🇰🇮", 
+        "name": "Kiribati"
+    }, 
+    ":avocado:": {
+        "style": "github", 
+        "image": "1f951.png", 
+        "unicode": "🥑", 
+        "name": "Avocado"
+    }, 
+    ":raised_hands_tone4:": {
+        "style": "github", 
+        "image": "1f64c-1f3fe.png", 
+        "unicode": "🙌🏾", 
+        "name": "Person Raising Both Hands In Celebration - Tone 4"
+    }, 
+    ":train:": {
+        "style": "github", 
+        "image": "1f68b.png", 
+        "unicode": "🚋", 
+        "name": "Tram Car"
+    }, 
+    ":airplane-arriving:": {
+        "style": "github", 
+        "image": "1f6ec.png", 
+        "unicode": "🛬", 
+        "name": "Airplane Arriving"
+    }, 
+    ":guardsman_tone4:": {
+        "style": "github", 
+        "image": "1f482-1f3fe.png", 
+        "unicode": "💂🏾", 
+        "name": "Guardsman - Tone 4"
+    }, 
+    ":earth_asia:": {
+        "style": "github", 
+        "image": "1f30f.png", 
+        "unicode": "🌏", 
+        "name": "Earth Globe Asia-australia"
+    }, 
+    ":custard:": {
+        "style": "github", 
+        "image": "1f36e.png", 
+        "unicode": "🍮", 
+        "name": "Custard"
+    }, 
+    ":middle-finger:": {
+        "style": "github", 
+        "image": "1f595.png", 
+        "unicode": "🖕", 
+        "name": "Reversed Hand With Middle Finger Extended"
+    }, 
+    "🍡": {
+        "style": "unicode", 
+        "image": "1f361.png", 
+        "name": "Dango"
+    }, 
+    ":flag-pn:": {
+        "style": "github", 
+        "image": "1f1f5-1f1f3.png", 
+        "unicode": "🇵🇳", 
+        "name": "Pitcairn"
+    }, 
+    "🕥": {
+        "style": "unicode", 
+        "image": "1f565.png", 
+        "name": "Clock Face Ten-thirty"
+    }, 
+    ":v_tone4:": {
+        "style": "github", 
+        "image": "270c-1f3fe.png", 
+        "unicode": "✌🏾", 
+        "name": "Victory Hand - Tone 4"
+    }, 
+    ":flag_ni:": {
+        "style": "github", 
+        "image": "1f1f3-1f1ee.png", 
+        "unicode": "🇳🇮", 
+        "name": "Nicaragua"
+    }, 
+    ":flag-lr:": {
+        "style": "github", 
+        "image": "1f1f1-1f1f7.png", 
+        "unicode": "🇱🇷", 
+        "name": "Liberia"
+    }, 
+    "🗺": {
+        "style": "unicode", 
+        "image": "1f5fa.png", 
+        "name": "World Map"
+    }, 
+    ":bear:": {
+        "style": "github", 
+        "image": "1f43b.png", 
+        "unicode": "🐻", 
+        "name": "Bear Face"
+    }, 
+    "🐪": {
+        "style": "unicode", 
+        "image": "1f42a.png", 
+        "name": "Dromedary Camel"
+    }, 
+    ":hand_splayed_tone1:": {
+        "style": "github", 
+        "image": "1f590-1f3fb.png", 
+        "unicode": "🖐🏻", 
+        "name": "Raised Hand With Fingers Splayed - Tone 1"
+    }, 
+    "🎋": {
+        "style": "unicode", 
+        "image": "1f38b.png", 
+        "name": "Tanabata Tree"
+    }, 
+    ":vibration-mode:": {
+        "style": "github", 
+        "image": "1f4f3.png", 
+        "unicode": "📳", 
+        "name": "Vibration Mode"
+    }, 
+    ":no_mouth:": {
+        "style": "github", 
+        "ascii": ":-X", 
+        "image": "1f636.png", 
+        "unicode": "😶", 
+        "name": "Face Without Mouth"
+    }, 
+    ":outbox-tray:": {
+        "style": "github", 
+        "image": "1f4e4.png", 
+        "unicode": "📤", 
+        "name": "Outbox Tray"
+    }, 
+    "🌠": {
+        "style": "unicode", 
+        "image": "1f320.png", 
+        "name": "Shooting Star"
+    }, 
+    "🔤": {
+        "style": "unicode", 
+        "image": "1f524.png", 
+        "name": "Input Symbol For Latin Letters"
+    }, 
+    ":raised-back-of-hand:": {
+        "style": "github", 
+        "image": "1f91a.png", 
+        "unicode": "🤚", 
+        "name": "Raised Back Of Hand"
+    }, 
+    ":man_tone1:": {
+        "style": "github", 
+        "image": "1f468-1f3fb.png", 
+        "unicode": "👨🏻", 
+        "name": "Man - Tone 1"
+    }, 
+    "🚹": {
+        "style": "unicode", 
+        "image": "1f6b9.png", 
+        "name": "Mens Symbol"
+    }, 
+    ":mother_christmas_tone3:": {
+        "style": "github", 
+        "image": "1f936-1f3fd.png", 
+        "unicode": "🤶🏽", 
+        "name": "Mother Christmas - Tone 3"
+    }, 
+    "🤼🏾": {
+        "style": "unicode", 
+        "image": "1f93c-1f3fe.png", 
+        "name": "Wrestlers - Tone 4"
+    }, 
+    "🤼🏿": {
+        "style": "unicode", 
+        "image": "1f93c-1f3ff.png", 
+        "name": "Wrestlers - Tone 5"
+    }, 
+    "🤼🏼": {
+        "style": "unicode", 
+        "image": "1f93c-1f3fc.png", 
+        "name": "Wrestlers - Tone 2"
+    }, 
+    "🤼🏽": {
+        "style": "unicode", 
+        "image": "1f93c-1f3fd.png", 
+        "name": "Wrestlers - Tone 3"
+    }, 
+    "🤼🏻": {
+        "style": "unicode", 
+        "image": "1f93c-1f3fb.png", 
+        "name": "Wrestlers - Tone 1"
+    }, 
+    "🙎": {
+        "style": "unicode", 
+        "image": "1f64e.png", 
+        "name": "Person With Pouting Face"
+    }, 
+    ":tone1:": {
+        "style": "github", 
+        "image": "1f3fb.png", 
+        "unicode": "🏻", 
+        "name": "Emoji Modifier Fitzpatrick Type-1-2"
+    }, 
+    ":satellite-orbital:": {
+        "style": "github", 
+        "image": "1f6f0.png", 
+        "unicode": "🛰", 
+        "name": "Satellite"
+    }, 
+    ":mag:": {
+        "style": "github", 
+        "image": "1f50d.png", 
+        "unicode": "🔍", 
+        "name": "Left-pointing Magnifying Glass"
+    }, 
+    ":third-place:": {
+        "style": "github", 
+        "image": "1f949.png", 
+        "unicode": "🥉", 
+        "name": "Third Place Medal"
+    }, 
+    ":couple-with-heart:": {
+        "style": "github", 
+        "image": "1f491.png", 
+        "unicode": "💑", 
+        "name": "Couple With Heart"
+    }, 
+    ":vn:": {
+        "style": "github", 
+        "image": "1f1fb-1f1f3.png", 
+        "unicode": "🇻🇳", 
+        "name": "Vietnam"
+    }, 
+    ":regional_indicator_c:": {
+        "style": "github", 
+        "image": "1f1e8.png", 
+        "unicode": "🇨", 
+        "name": "Regional Indicator Symbol Letter C"
+    }, 
+    ":glass_of_milk:": {
+        "style": "github", 
+        "image": "1f95b.png", 
+        "unicode": "🥛", 
+        "name": "Glass Of Milk"
+    }, 
+    ":mrs-claus-tone2:": {
+        "style": "github", 
+        "image": "1f936-1f3fc.png", 
+        "unicode": "🤶🏼", 
+        "name": "Mother Christmas - Tone 2"
+    }, 
+    "O_O": {
+        "style": "ascii", 
+        "ascii": ":-O", 
+        "image": "1f62e.png", 
+        "unicode": "😮", 
+        "name": "Face With Open Mouth"
+    }, 
+    ":joy_cat:": {
+        "style": "github", 
+        "image": "1f639.png", 
+        "unicode": "😹", 
+        "name": "Cat Face With Tears Of Joy"
+    }, 
+    ":sake:": {
+        "style": "github", 
+        "image": "1f376.png", 
+        "unicode": "🍶", 
+        "name": "Sake Bottle And Cup"
+    }, 
+    ":ballot-box-with-check:": {
+        "style": "github", 
+        "image": "2611.png", 
+        "unicode": "☑", 
+        "name": "Ballot Box With Check"
+    }, 
+    ":scissors:": {
+        "style": "github", 
+        "image": "2702.png", 
+        "unicode": "✂", 
+        "name": "Black Scissors"
+    }, 
+    ":b:": {
+        "style": "github", 
+        "image": "1f171.png", 
+        "unicode": "🅱", 
+        "name": "Negative Squared Latin Capital Letter B"
+    }, 
+    ":flag-mu:": {
+        "style": "github", 
+        "image": "1f1f2-1f1fa.png", 
+        "unicode": "🇲🇺", 
+        "name": "Mauritius"
+    }, 
+    "👥": {
+        "style": "unicode", 
+        "image": "1f465.png", 
+        "name": "Busts In Silhouette"
+    }, 
+    ":railroad_track:": {
+        "style": "github", 
+        "image": "1f6e4.png", 
+        "unicode": "🛤", 
+        "name": "Railway Track"
+    }, 
+    ":face-palm-tone3:": {
+        "style": "github", 
+        "image": "1f926-1f3fd.png", 
+        "unicode": "🤦🏽", 
+        "name": "Face Palm - Tone 3"
+    }, 
+    ":busstop:": {
+        "style": "github", 
+        "image": "1f68f.png", 
+        "unicode": "🚏", 
+        "name": "Bus Stop"
+    }, 
+    ":no:": {
+        "style": "github", 
+        "image": "1f1f3-1f1f4.png", 
+        "unicode": "🇳🇴", 
+        "name": "Norway"
+    }, 
+    "📺": {
+        "style": "unicode", 
+        "image": "1f4fa.png", 
+        "name": "Television"
+    }, 
+    ":prince_tone4:": {
+        "style": "github", 
+        "image": "1f934-1f3fe.png", 
+        "unicode": "🤴🏾", 
+        "name": "Prince - Tone 4"
+    }, 
+    ":vulcan_tone5:": {
+        "style": "github", 
+        "image": "1f596-1f3ff.png", 
+        "unicode": "🖖🏿", 
+        "name": "Raised Hand With Part Between Middle And Ring Fingers - Tone 5"
+    }, 
+    "💋": {
+        "style": "unicode", 
+        "image": "1f48b.png", 
+        "name": "Kiss Mark"
+    }, 
+    "🙌🏾": {
+        "style": "unicode", 
+        "image": "1f64c-1f3fe.png", 
+        "name": "Person Raising Both Hands In Celebration - Tone 4"
+    }, 
+    "🙌🏿": {
+        "style": "unicode", 
+        "image": "1f64c-1f3ff.png", 
+        "name": "Person Raising Both Hands In Celebration - Tone 5"
+    }, 
+    "🙌🏼": {
+        "style": "unicode", 
+        "image": "1f64c-1f3fc.png", 
+        "name": "Person Raising Both Hands In Celebration - Tone 2"
+    }, 
+    "⌚": {
+        "style": "unicode", 
+        "image": "231a.png", 
+        "name": "Watch"
+    }, 
+    "🙌🏻": {
+        "style": "unicode", 
+        "image": "1f64c-1f3fb.png", 
+        "name": "Person Raising Both Hands In Celebration - Tone 1"
+    }, 
+    "🐠": {
+        "style": "unicode", 
+        "image": "1f420.png", 
+        "name": "Tropical Fish"
+    }, 
+    ":raising-hand-tone3:": {
+        "style": "github", 
+        "image": "1f64b-1f3fd.png", 
+        "unicode": "🙋🏽", 
+        "name": "Happy Person Raising One Hand Tone3"
+    }, 
+    ":flag-ee:": {
+        "style": "github", 
+        "image": "1f1ea-1f1ea.png", 
+        "unicode": "🇪🇪", 
+        "name": "Estonia"
+    }, 
+    ":bow_tone2:": {
+        "style": "github", 
+        "image": "1f647-1f3fc.png", 
+        "unicode": "🙇🏼", 
+        "name": "Person Bowing Deeply - Tone 2"
+    }, 
+    ":man_with_turban_tone3:": {
+        "style": "github", 
+        "image": "1f473-1f3fd.png", 
+        "unicode": "👳🏽", 
+        "name": "Man With Turban - Tone 3"
+    }, 
+    ":dress:": {
+        "style": "github", 
+        "image": "1f457.png", 
+        "unicode": "👗", 
+        "name": "Dress"
+    }, 
+    ":white_large_square:": {
+        "style": "github", 
+        "image": "2b1c.png", 
+        "unicode": "⬜", 
+        "name": "White Large Square"
+    }, 
+    ":baby_chick:": {
+        "style": "github", 
+        "image": "1f424.png", 
+        "unicode": "🐤", 
+        "name": "Baby Chick"
+    }, 
+    ":sunrise-over-mountains:": {
+        "style": "github", 
+        "image": "1f304.png", 
+        "unicode": "🌄", 
+        "name": "Sunrise Over Mountains"
+    }, 
+    ":water-polo:": {
+        "style": "github", 
+        "image": "1f93d.png", 
+        "unicode": "🤽", 
+        "name": "Water Polo"
+    }, 
+    ":unicorn:": {
+        "style": "github", 
+        "image": "1f984.png", 
+        "unicode": "🦄", 
+        "name": "Unicorn Face"
+    }, 
+    ":az:": {
+        "style": "github", 
+        "image": "1f1e6-1f1ff.png", 
+        "unicode": "🇦🇿", 
+        "name": "Azerbaijan"
+    }, 
+    ":star_and_crescent:": {
+        "style": "github", 
+        "image": "262a.png", 
+        "unicode": "☪", 
+        "name": "Star And Crescent"
+    }, 
+    ":pe:": {
+        "style": "github", 
+        "image": "1f1f5-1f1ea.png", 
+        "unicode": "🇵🇪", 
+        "name": "Peru"
+    }, 
+    ":love_hotel:": {
+        "style": "github", 
+        "image": "1f3e9.png", 
+        "unicode": "🏩", 
+        "name": "Love Hotel"
+    }, 
+    ":flag-ai:": {
+        "style": "github", 
+        "image": "1f1e6-1f1ee.png", 
+        "unicode": "🇦🇮", 
+        "name": "Anguilla"
+    }, 
+    ":head_bandage:": {
+        "style": "github", 
+        "image": "1f915.png", 
+        "unicode": "🤕", 
+        "name": "Face With Head-bandage"
+    }, 
+    ":runner_tone1:": {
+        "style": "github", 
+        "image": "1f3c3-1f3fb.png", 
+        "unicode": "🏃🏻", 
+        "name": "Runner - Tone 1"
+    }, 
+    "😷": {
+        "style": "unicode", 
+        "image": "1f637.png", 
+        "name": "Face With Medical Mask"
+    }, 
+    ":european_post_office:": {
+        "style": "github", 
+        "image": "1f3e4.png", 
+        "unicode": "🏤", 
+        "name": "European Post Office"
+    }, 
+    ":cloud-rain:": {
+        "style": "github", 
+        "image": "1f327.png", 
+        "unicode": "🌧", 
+        "name": "Cloud With Rain"
+    }, 
+    ":black-medium-small-square:": {
+        "style": "github", 
+        "image": "25fe.png", 
+        "unicode": "◾", 
+        "name": "Black Medium Small Square"
+    }, 
+    "🛌": {
+        "style": "unicode", 
+        "image": "1f6cc.png", 
+        "name": "Sleeping Accommodation"
+    }, 
+    ":regional-indicator-d:": {
+        "style": "github", 
+        "image": "1f1e9.png", 
+        "unicode": "🇩", 
+        "name": "Regional Indicator Symbol Letter D"
+    }, 
+    ":sign_of_the_horns_tone1:": {
+        "style": "github", 
+        "image": "1f918-1f3fb.png", 
+        "unicode": "🤘🏻", 
+        "name": "Sign Of The Horns - Tone 1"
+    }, 
+    ":mountain_snow:": {
+        "style": "github", 
+        "image": "1f3d4.png", 
+        "unicode": "🏔", 
+        "name": "Snow Capped Mountain"
+    }, 
+    "🕡": {
+        "style": "unicode", 
+        "image": "1f561.png", 
+        "name": "Clock Face Six-thirty"
+    }, 
+    "🍥": {
+        "style": "unicode", 
+        "image": "1f365.png", 
+        "name": "Fish Cake With Swirl Design"
+    }, 
+    ":menorah:": {
+        "style": "github", 
+        "image": "1f54e.png", 
+        "unicode": "🕎", 
+        "name": "Menorah With Nine Branches"
+    }, 
+    ":white-sun-rain-cloud:": {
+        "style": "github", 
+        "image": "1f326.png", 
+        "unicode": "🌦", 
+        "name": "White Sun Behind Cloud With Rain"
+    }, 
+    ":zipper_mouth_face:": {
+        "style": "github", 
+        "image": "1f910.png", 
+        "unicode": "🤐", 
+        "name": "Zipper-mouth Face"
+    }, 
+    "🏺": {
+        "style": "unicode", 
+        "image": "1f3fa.png", 
+        "name": "Amphora"
+    }, 
+    "🖋": {
+        "style": "unicode", 
+        "image": "1f58b.png", 
+        "name": "Lower Left Fountain Pen"
+    }, 
+    ":heart-eyes:": {
+        "style": "github", 
+        "image": "1f60d.png", 
+        "unicode": "😍", 
+        "name": "Smiling Face With Heart-shaped Eyes"
+    }, 
+    "🎏": {
+        "style": "unicode", 
+        "image": "1f38f.png", 
+        "name": "Carp Streamer"
+    }, 
+    ":call_me_hand:": {
+        "style": "github", 
+        "image": "1f919.png", 
+        "unicode": "🤙", 
+        "name": "Call Me Hand"
+    }, 
+    "🔠": {
+        "style": "unicode", 
+        "image": "1f520.png", 
+        "name": "Input Symbol For Latin Capital Letters"
+    }, 
+    "🌤": {
+        "style": "unicode", 
+        "image": "1f324.png", 
+        "name": "White Sun With Small Cloud"
+    }, 
+    "▫": {
+        "style": "unicode", 
+        "image": "25ab.png", 
+        "name": "White Small Square"
+    }, 
+    ":ok-hand-tone4:": {
+        "style": "github", 
+        "image": "1f44c-1f3fe.png", 
+        "unicode": "👌🏾", 
+        "name": "Ok Hand Sign - Tone 4"
+    }, 
+    "💃🏻": {
+        "style": "unicode", 
+        "image": "1f483-1f3fb.png", 
+        "name": "Dancer - Tone 1"
+    }, 
+    ":small_orange_diamond:": {
+        "style": "github", 
+        "image": "1f538.png", 
+        "unicode": "🔸", 
+        "name": "Small Orange Diamond"
+    }, 
+    "💃🏿": {
+        "style": "unicode", 
+        "image": "1f483-1f3ff.png", 
+        "name": "Dancer - Tone 5"
+    }, 
+    "💃🏾": {
+        "style": "unicode", 
+        "image": "1f483-1f3fe.png", 
+        "name": "Dancer - Tone 4"
+    }, 
+    "💃🏽": {
+        "style": "unicode", 
+        "image": "1f483-1f3fd.png", 
+        "name": "Dancer - Tone 3"
+    }, 
+    "💃🏼": {
+        "style": "unicode", 
+        "image": "1f483-1f3fc.png", 
+        "name": "Dancer - Tone 2"
+    }, 
+    ":small-orange-diamond:": {
+        "style": "github", 
+        "image": "1f538.png", 
+        "unicode": "🔸", 
+        "name": "Small Orange Diamond"
+    }, 
+    ":musical-score:": {
+        "style": "github", 
+        "image": "1f3bc.png", 
+        "unicode": "🎼", 
+        "name": "Musical Score"
+    }, 
+    ":bridge_at_night:": {
+        "style": "github", 
+        "image": "1f309.png", 
+        "unicode": "🌉", 
+        "name": "Bridge At Night"
+    }, 
+    ":seven:": {
+        "style": "github", 
+        "image": "0037-20e3.png", 
+        "unicode": "7⃣", 
+        "name": "Keycap Digit Seven"
+    }, 
+    ":boy-tone1:": {
+        "style": "github", 
+        "image": "1f466-1f3fb.png", 
+        "unicode": "👦🏻", 
+        "name": "Boy - Tone 1"
+    }, 
+    ":cherry-blossom:": {
+        "style": "github", 
+        "image": "1f338.png", 
+        "unicode": "🌸", 
+        "name": "Cherry Blossom"
+    }, 
+    ":wine-glass:": {
+        "style": "github", 
+        "image": "1f377.png", 
+        "unicode": "🍷", 
+        "name": "Wine Glass"
+    }, 
+    ":bulb:": {
+        "style": "github", 
+        "image": "1f4a1.png", 
+        "unicode": "💡", 
+        "name": "Electric Light Bulb"
+    }, 
+    ":flag_mr:": {
+        "style": "github", 
+        "image": "1f1f2-1f1f7.png", 
+        "unicode": "🇲🇷", 
+        "name": "Mauritania"
+    }, 
+    "😍": {
+        "style": "unicode", 
+        "image": "1f60d.png", 
+        "name": "Smiling Face With Heart-shaped Eyes"
+    }, 
+    "↘": {
+        "style": "unicode", 
+        "image": "2198.png", 
+        "name": "South East Arrow"
+    }, 
+    ":bh:": {
+        "style": "github", 
+        "image": "1f1e7-1f1ed.png", 
+        "unicode": "🇧🇭", 
+        "name": "Bahrain"
+    }, 
+    "🚢": {
+        "style": "unicode", 
+        "image": "1f6a2.png", 
+        "name": "Ship"
+    }, 
+    ":flag_ua:": {
+        "style": "github", 
+        "image": "1f1fa-1f1e6.png", 
+        "unicode": "🇺🇦", 
+        "name": "Ukraine"
+    }, 
+    ":flag_rw:": {
+        "style": "github", 
+        "image": "1f1f7-1f1fc.png", 
+        "unicode": "🇷🇼", 
+        "name": "Rwanda"
+    }, 
+    "®": {
+        "style": "unicode", 
+        "image": "00ae.png", 
+        "name": "Registered Sign"
+    }, 
+    ":ta:": {
+        "style": "github", 
+        "image": "1f1f9-1f1e6.png", 
+        "unicode": "🇹🇦", 
+        "name": "Tristan Da Cunha"
+    }, 
+    ":man-tone2:": {
+        "style": "github", 
+        "image": "1f468-1f3fc.png", 
+        "unicode": "👨🏼", 
+        "name": "Man - Tone 2"
+    }, 
+    ":thumbsdown-tone5:": {
+        "style": "github", 
+        "image": "1f44e-1f3ff.png", 
+        "unicode": "👎🏿", 
+        "name": "Thumbs Down Sign - Tone 5"
+    }, 
+    "❗": {
+        "style": "unicode", 
+        "image": "2757.png", 
+        "name": "Heavy Exclamation Mark Symbol"
+    }, 
+    "👡": {
+        "style": "unicode", 
+        "image": "1f461.png", 
+        "name": "Womans Sandal"
+    }, 
+    "🙇🏿": {
+        "style": "unicode", 
+        "image": "1f647-1f3ff.png", 
+        "name": "Person Bowing Deeply - Tone 5"
+    }, 
+    "🙇🏾": {
+        "style": "unicode", 
+        "image": "1f647-1f3fe.png", 
+        "name": "Person Bowing Deeply - Tone 4"
+    }, 
+    ":reminder_ribbon:": {
+        "style": "github", 
+        "image": "1f397.png", 
+        "unicode": "🎗", 
+        "name": "Reminder Ribbon"
+    }, 
+    "🙇🏼": {
+        "style": "unicode", 
+        "image": "1f647-1f3fc.png", 
+        "name": "Person Bowing Deeply - Tone 2"
+    }, 
+    "🙇🏻": {
+        "style": "unicode", 
+        "image": "1f647-1f3fb.png", 
+        "name": "Person Bowing Deeply - Tone 1"
+    }, 
+    "📶": {
+        "style": "unicode", 
+        "image": "1f4f6.png", 
+        "name": "Antenna With Bars"
+    }, 
+    ":raising-hand-tone5:": {
+        "style": "github", 
+        "image": "1f64b-1f3ff.png", 
+        "unicode": "🙋🏿", 
+        "name": "Happy Person Raising One Hand Tone5"
+    }, 
+    ":play-pause:": {
+        "style": "github", 
+        "image": "23ef.png", 
+        "unicode": "⏯", 
+        "name": "Black Right-pointing Double Triangle With Double Vertical Bar"
+    }, 
+    "🚋": {
+        "style": "unicode", 
+        "image": "1f68b.png", 
+        "name": "Tram Car"
+    }, 
+    ":head-bandage:": {
+        "style": "github", 
+        "image": "1f915.png", 
+        "unicode": "🤕", 
+        "name": "Face With Head-bandage"
+    }, 
+    "✖": {
+        "style": "unicode", 
+        "image": "2716.png", 
+        "name": "Heavy Multiplication X"
+    }, 
+    ":white-sun-cloud:": {
+        "style": "github", 
+        "image": "1f325.png", 
+        "unicode": "🌥", 
+        "name": "White Sun Behind Cloud"
+    }, 
+    ":flag_bw:": {
+        "style": "github", 
+        "image": "1f1e7-1f1fc.png", 
+        "unicode": "🇧🇼", 
+        "name": "Botswana"
+    }, 
+    "😠": {
+        "style": "unicode", 
+        "ascii": ">:(", 
+        "image": "1f620.png", 
+        "name": "Angry Face"
+    }, 
+    "⚫": {
+        "style": "unicode", 
+        "image": "26ab.png", 
+        "name": "Medium Black Circle"
+    }, 
+    "-__-": {
+        "style": "ascii", 
+        "ascii": "-_-", 
+        "image": "1f611.png", 
+        "unicode": "😑", 
+        "name": "Expressionless Face"
+    }, 
+    ":muscle-tone3:": {
+        "style": "github", 
+        "image": "1f4aa-1f3fd.png", 
+        "unicode": "💪🏽", 
+        "name": "Flexed Biceps - Tone 3"
+    }, 
+    "🎹": {
+        "style": "unicode", 
+        "image": "1f3b9.png", 
+        "name": "Musical Keyboard"
+    }, 
+    ":hibiscus:": {
+        "style": "github", 
+        "image": "1f33a.png", 
+        "unicode": "🌺", 
+        "name": "Hibiscus"
+    }, 
+    "🍎": {
+        "style": "unicode", 
+        "image": "1f34e.png", 
+        "name": "Red Apple"
+    }, 
+    ":abc:": {
+        "style": "github", 
+        "image": "1f524.png", 
+        "unicode": "🔤", 
+        "name": "Input Symbol For Latin Letters"
+    }, 
+    ":pencil2:": {
+        "style": "github", 
+        "image": "270f.png", 
+        "unicode": "✏", 
+        "name": "Pencil"
+    }, 
+    ":person-with-pouting-face-tone1:": {
+        "style": "github", 
+        "image": "1f64e-1f3fb.png", 
+        "unicode": "🙎🏻", 
+        "name": "Person With Pouting Face Tone1"
+    }, 
+    ":balloon:": {
+        "style": "github", 
+        "image": "1f388.png", 
+        "unicode": "🎈", 
+        "name": "Balloon"
+    }, 
+    "-_-": {
+        "style": "ascii", 
+        "ascii": "-_-", 
+        "image": "1f611.png", 
+        "unicode": "😑", 
+        "name": "Expressionless Face"
+    }, 
+    ":metal-tone2:": {
+        "style": "github", 
+        "image": "1f918-1f3fc.png", 
+        "unicode": "🤘🏼", 
+        "name": "Sign Of The Horns - Tone 2"
+    }, 
+    ":ok_hand_tone1:": {
+        "style": "github", 
+        "image": "1f44c-1f3fb.png", 
+        "unicode": "👌🏻", 
+        "name": "Ok Hand Sign - Tone 1"
+    }, 
+    ":flag-vg:": {
+        "style": "github", 
+        "image": "1f1fb-1f1ec.png", 
+        "unicode": "🇻🇬", 
+        "name": "British Virgin Islands"
+    }, 
+    ":fast-forward:": {
+        "style": "github", 
+        "image": "23e9.png", 
+        "unicode": "⏩", 
+        "name": "Black Right-pointing Double Triangle"
+    }, 
+    "🔍": {
+        "style": "unicode", 
+        "image": "1f50d.png", 
+        "name": "Left-pointing Magnifying Glass"
+    }, 
+    "🤕": {
+        "style": "unicode", 
+        "image": "1f915.png", 
+        "name": "Face With Head-bandage"
+    }, 
+    ":male_dancer_tone5:": {
+        "style": "github", 
+        "image": "1f57a-1f3ff.png", 
+        "unicode": "🕺🏿", 
+        "name": "Man Dancing - Tone 5"
+    }, 
+    ":bride_with_veil_tone5:": {
+        "style": "github", 
+        "image": "1f470-1f3ff.png", 
+        "unicode": "👰🏿", 
+        "name": "Bride With Veil - Tone 5"
+    }, 
+    ":evergreen_tree:": {
+        "style": "github", 
+        "image": "1f332.png", 
+        "unicode": "🌲", 
+        "name": "Evergreen Tree"
+    }, 
+    ":pushpin:": {
+        "style": "github", 
+        "image": "1f4cc.png", 
+        "unicode": "📌", 
+        "name": "Pushpin"
+    }, 
+    "⤵": {
+        "style": "unicode", 
+        "image": "2935.png", 
+        "name": "Arrow Pointing Rightwards Then Curving Downwards"
+    }, 
+    "🐷": {
+        "style": "unicode", 
+        "image": "1f437.png", 
+        "name": "Pig Face"
+    }, 
+    ":right_fist_tone1:": {
+        "style": "github", 
+        "image": "1f91c-1f3fb.png", 
+        "unicode": "🤜🏻", 
+        "name": "Right Facing Fist - Tone 1"
+    }, 
+    "5⃣": {
+        "style": "unicode", 
+        "image": "0035-20e3.png", 
+        "name": "Keycap Digit Five"
+    }, 
+    ":keycap_asterisk:": {
+        "style": "github", 
+        "image": "002a-20e3.png", 
+        "unicode": "*⃣", 
+        "name": "Keycap Asterisk"
+    }, 
+    ":man-in-tuxedo-tone4:": {
+        "style": "github", 
+        "image": "1f935-1f3fe.png", 
+        "unicode": "🤵🏾", 
+        "name": "Man In Tuxedo - Tone 4"
+    }, 
+    ":mu:": {
+        "style": "github", 
+        "image": "1f1f2-1f1fa.png", 
+        "unicode": "🇲🇺", 
+        "name": "Mauritius"
+    }, 
+    "📌": {
+        "style": "unicode", 
+        "image": "1f4cc.png", 
+        "name": "Pushpin"
+    }, 
+    ":cw:": {
+        "style": "github", 
+        "image": "1f1e8-1f1fc.png", 
+        "unicode": "🇨🇼", 
+        "name": "Curaçao"
+    }, 
+    ":file_folder:": {
+        "style": "github", 
+        "image": "1f4c1.png", 
+        "unicode": "📁", 
+        "name": "File Folder"
+    }, 
+    ":flag-mn:": {
+        "style": "github", 
+        "image": "1f1f2-1f1f3.png", 
+        "unicode": "🇲🇳", 
+        "name": "Mongolia"
+    }, 
+    "🇺": {
+        "style": "unicode", 
+        "image": "1f1fa.png", 
+        "name": "Regional Indicator Symbol Letter U"
+    }, 
+    ":dollar:": {
+        "style": "github", 
+        "image": "1f4b5.png", 
+        "unicode": "💵", 
+        "name": "Banknote With Dollar Sign"
+    }, 
+    ":biohazard:": {
+        "style": "github", 
+        "image": "2623.png", 
+        "unicode": "☣", 
+        "name": "Biohazard Sign"
+    }, 
+    ":kg:": {
+        "style": "github", 
+        "image": "1f1f0-1f1ec.png", 
+        "unicode": "🇰🇬", 
+        "name": "Kyrgyzstan"
+    }, 
+    ":+1_tone3:": {
+        "style": "github", 
+        "image": "1f44d-1f3fd.png", 
+        "unicode": "👍🏽", 
+        "name": "Thumbs Up Sign - Tone 3"
+    }, 
+    ":rice_cracker:": {
+        "style": "github", 
+        "image": "1f358.png", 
+        "unicode": "🍘", 
+        "name": "Rice Cracker"
+    }, 
+    ":ice-cream:": {
+        "style": "github", 
+        "image": "1f368.png", 
+        "unicode": "🍨", 
+        "name": "Ice Cream"
+    }, 
+    ":recycle:": {
+        "style": "github", 
+        "image": "267b.png", 
+        "unicode": "♻", 
+        "name": "Black Universal Recycling Symbol"
+    }, 
+    ":flag_lu:": {
+        "style": "github", 
+        "image": "1f1f1-1f1fa.png", 
+        "unicode": "🇱🇺", 
+        "name": "Luxembourg"
+    }, 
+    ":flag-nr:": {
+        "style": "github", 
+        "image": "1f1f3-1f1f7.png", 
+        "unicode": "🇳🇷", 
+        "name": "Nauru"
+    }, 
+    ":point-right:": {
+        "style": "github", 
+        "image": "1f449.png", 
+        "unicode": "👉", 
+        "name": "White Right Pointing Backhand Index"
+    }, 
+    "🏣": {
+        "style": "unicode", 
+        "image": "1f3e3.png", 
+        "name": "Japanese Post Office"
+    }, 
+    ":flag-ph:": {
+        "style": "github", 
+        "image": "1f1f5-1f1ed.png", 
+        "unicode": "🇵🇭", 
+        "name": "The Philippines"
+    }, 
+    "🍸": {
+        "style": "unicode", 
+        "image": "1f378.png", 
+        "name": "Cocktail Glass"
+    }, 
+    ":thumbup_tone1:": {
+        "style": "github", 
+        "image": "1f44d-1f3fb.png", 
+        "unicode": "👍🏻", 
+        "name": "Thumbs Up Sign - Tone 1"
+    }, 
+    ":flag-lt:": {
+        "style": "github", 
+        "image": "1f1f1-1f1f9.png", 
+        "unicode": "🇱🇹", 
+        "name": "Lithuania"
+    }, 
+    "🐍": {
+        "style": "unicode", 
+        "image": "1f40d.png", 
+        "name": "Snake"
+    }, 
+    ":baggage-claim:": {
+        "style": "github", 
+        "image": "1f6c4.png", 
+        "unicode": "🛄", 
+        "name": "Baggage Claim"
+    }, 
+    "👩👩👦👦": {
+        "style": "unicode", 
+        "image": "1f469-1f469-1f466-1f466.png", 
+        "name": "Family (woman,woman,boy,boy)"
+    }, 
+    ":inbox_tray:": {
+        "style": "github", 
+        "image": "1f4e5.png", 
+        "unicode": "📥", 
+        "name": "Inbox Tray"
+    }, 
+    "💢": {
+        "style": "unicode", 
+        "image": "1f4a2.png", 
+        "name": "Anger Symbol"
+    }, 
+    ":honey-pot:": {
+        "style": "github", 
+        "image": "1f36f.png", 
+        "unicode": "🍯", 
+        "name": "Honey Pot"
+    }, 
+    "🔷": {
+        "style": "unicode", 
+        "image": "1f537.png", 
+        "name": "Large Blue Diamond"
+    }, 
+    "🛀🏻": {
+        "style": "unicode", 
+        "image": "1f6c0-1f3fb.png", 
+        "name": "Bath - Tone 1"
+    }, 
+    ":mother_christmas_tone1:": {
+        "style": "github", 
+        "image": "1f936-1f3fb.png", 
+        "unicode": "🤶🏻", 
+        "name": "Mother Christmas - Tone 1"
+    }, 
+    "🛀🏿": {
+        "style": "unicode", 
+        "image": "1f6c0-1f3ff.png", 
+        "name": "Bath - Tone 5"
+    }, 
+    "🛀🏼": {
+        "style": "unicode", 
+        "image": "1f6c0-1f3fc.png", 
+        "name": "Bath - Tone 2"
+    }, 
+    "🛀🏽": {
+        "style": "unicode", 
+        "image": "1f6c0-1f3fd.png", 
+        "name": "Bath - Tone 3"
+    }, 
+    "Ⓜ": {
+        "style": "unicode", 
+        "image": "24c2.png", 
+        "name": "Circled Latin Capital Letter M"
+    }, 
+    ":sj:": {
+        "style": "github", 
+        "image": "1f1f8-1f1ef.png", 
+        "unicode": "🇸🇯", 
+        "name": "Svalbard And Jan Mayen"
+    }, 
+    ":milk:": {
+        "style": "github", 
+        "image": "1f95b.png", 
+        "unicode": "🥛", 
+        "name": "Glass Of Milk"
+    }, 
+    ":three_button_mouse:": {
+        "style": "github", 
+        "image": "1f5b1.png", 
+        "unicode": "🖱", 
+        "name": "Three Button Mouse"
+    }, 
+    ":girl-tone3:": {
+        "style": "github", 
+        "image": "1f467-1f3fd.png", 
+        "unicode": "👧🏽", 
+        "name": "Girl - Tone 3"
+    }, 
+    ":sunglasses:": {
+        "style": "github", 
+        "ascii": "B-)", 
+        "image": "1f60e.png", 
+        "unicode": "😎", 
+        "name": "Smiling Face With Sunglasses"
+    }, 
+    "🛶": {
+        "style": "unicode", 
+        "image": "1f6f6.png", 
+        "name": "Canoe"
+    }, 
+    ":calendar-spiral:": {
+        "style": "github", 
+        "image": "1f5d3.png", 
+        "unicode": "🗓", 
+        "name": "Spiral Calendar Pad"
+    }, 
+    ":regional_indicator_a:": {
+        "style": "github", 
+        "image": "1f1e6.png", 
+        "unicode": "🇦", 
+        "name": "Regional Indicator Symbol Letter A"
+    }, 
+    ":rofl:": {
+        "style": "github", 
+        "image": "1f923.png", 
+        "unicode": "🤣", 
+        "name": "Rolling On The Floor Laughing"
+    }, 
+    "💓": {
+        "style": "unicode", 
+        "image": "1f493.png", 
+        "name": "Beating Heart"
+    }, 
+    ":flag-td:": {
+        "style": "github", 
+        "image": "1f1f9-1f1e9.png", 
+        "unicode": "🇹🇩", 
+        "name": "Chad"
+    }, 
+    "🏋🏿": {
+        "style": "unicode", 
+        "image": "1f3cb-1f3ff.png", 
+        "name": "Weight Lifter - Tone 5"
+    }, 
+    ":sandal:": {
+        "style": "github", 
+        "image": "1f461.png", 
+        "unicode": "👡", 
+        "name": "Womans Sandal"
+    }, 
+    "🎽": {
+        "style": "unicode", 
+        "image": "1f3bd.png", 
+        "name": "Running Shirt With Sash"
+    }, 
+    ":open_hands:": {
+        "style": "github", 
+        "image": "1f450.png", 
+        "unicode": "👐", 
+        "name": "Open Hands Sign"
+    }, 
+    "🍒": {
+        "style": "unicode", 
+        "image": "1f352.png", 
+        "name": "Cherries"
+    }, 
+    "👨👩👧": {
+        "style": "unicode", 
+        "image": "1f468-1f469-1f467.png", 
+        "name": "Family (man,woman,girl)"
+    }, 
+    ":flag-ms:": {
+        "style": "github", 
+        "image": "1f1f2-1f1f8.png", 
+        "unicode": "🇲🇸", 
+        "name": "Montserrat"
+    }, 
+    ":flag_pt:": {
+        "style": "github", 
+        "image": "1f1f5-1f1f9.png", 
+        "unicode": "🇵🇹", 
+        "name": "Portugal"
+    }, 
+    ":hammer:": {
+        "style": "github", 
+        "image": "1f528.png", 
+        "unicode": "🔨", 
+        "name": "Hammer"
+    }, 
+    ":man_with_turban_tone5:": {
+        "style": "github", 
+        "image": "1f473-1f3ff.png", 
+        "unicode": "👳🏿", 
+        "name": "Man With Turban - Tone 5"
+    }, 
+    ":water_polo_tone2:": {
+        "style": "github", 
+        "image": "1f93d-1f3fc.png", 
+        "unicode": "🤽🏼", 
+        "name": "Water Polo - Tone 2"
+    }, 
+    ":lifter:": {
+        "style": "github", 
+        "image": "1f3cb.png", 
+        "unicode": "🏋", 
+        "name": "Weight Lifter"
+    }, 
+    ":flag-ec:": {
+        "style": "github", 
+        "image": "1f1ea-1f1e8.png", 
+        "unicode": "🇪🇨", 
+        "name": "Ecuador"
+    }, 
+    "😿": {
+        "style": "unicode", 
+        "image": "1f63f.png", 
+        "name": "Crying Cat Face"
+    }, 
+    ":cold-sweat:": {
+        "style": "github", 
+        "image": "1f630.png", 
+        "unicode": "😰", 
+        "name": "Face With Open Mouth And Cold Sweat"
+    }, 
+    ":twisted-rightwards-arrows:": {
+        "style": "github", 
+        "image": "1f500.png", 
+        "unicode": "🔀", 
+        "name": "Twisted Rightwards Arrows"
+    }, 
+    "⛴": {
+        "style": "unicode", 
+        "image": "26f4.png", 
+        "name": "Ferry"
+    }, 
+    "🔦": {
+        "style": "unicode", 
+        "image": "1f526.png", 
+        "name": "Electric Torch"
+    }, 
+    "🗾": {
+        "style": "unicode", 
+        "image": "1f5fe.png", 
+        "name": "Silhouette Of Japan"
+    }, 
+    ":gay-pride-flag:": {
+        "style": "github", 
+        "image": "1f3f3-1f308.png", 
+        "unicode": "🏳🌈", 
+        "name": "Gay_pride_flag"
+    }, 
+    "🦋": {
+        "style": "unicode", 
+        "image": "1f98b.png", 
+        "name": "Butterfly"
+    }, 
+    ":volleyball:": {
+        "style": "github", 
+        "image": "1f3d0.png", 
+        "unicode": "🏐", 
+        "name": "Volleyball"
+    }, 
+    ":flag-ao:": {
+        "style": "github", 
+        "image": "1f1e6-1f1f4.png", 
+        "unicode": "🇦🇴", 
+        "name": "Angola"
+    }, 
+    "✍🏽": {
+        "style": "unicode", 
+        "image": "270d-1f3fd.png", 
+        "name": "Writing Hand - Tone 3"
+    }, 
+    "✍🏼": {
+        "style": "unicode", 
+        "image": "270d-1f3fc.png", 
+        "name": "Writing Hand - Tone 2"
+    }, 
+    "✍🏿": {
+        "style": "unicode", 
+        "image": "270d-1f3ff.png", 
+        "name": "Writing Hand - Tone 5"
+    }, 
+    "✍🏾": {
+        "style": "unicode", 
+        "image": "270d-1f3fe.png", 
+        "name": "Writing Hand - Tone 4"
+    }, 
+    "✍🏻": {
+        "style": "unicode", 
+        "image": "270d-1f3fb.png", 
+        "name": "Writing Hand - Tone 1"
+    }, 
+    "🤠": {
+        "style": "unicode", 
+        "image": "1f920.png", 
+        "name": "Face With Cowboy Hat"
+    }, 
+    ":see-no-evil:": {
+        "style": "github", 
+        "image": "1f648.png", 
+        "unicode": "🙈", 
+        "name": "See-no-evil Monkey"
+    }, 
+    "🔨": {
+        "style": "unicode", 
+        "image": "1f528.png", 
+        "name": "Hammer"
+    }, 
+    ":id:": {
+        "style": "github", 
+        "image": "1f194.png", 
+        "unicode": "🆔", 
+        "name": "Squared Id"
+    }, 
+    ":runner_tone3:": {
+        "style": "github", 
+        "image": "1f3c3-1f3fd.png", 
+        "unicode": "🏃🏽", 
+        "name": "Runner - Tone 3"
+    }, 
+    ":man_with_gua_pi_mao_tone2:": {
+        "style": "github", 
+        "image": "1f472-1f3fc.png", 
+        "unicode": "👲🏼", 
+        "name": "Man With Gua Pi Mao - Tone 2"
+    }, 
+    ":flag-by:": {
+        "style": "github", 
+        "image": "1f1e7-1f1fe.png", 
+        "unicode": "🇧🇾", 
+        "name": "Belarus"
+    }, 
+    ":regional-indicator-j:": {
+        "style": "github", 
+        "image": "1f1ef.png", 
+        "unicode": "🇯", 
+        "name": "Regional Indicator Symbol Letter J"
+    }, 
+    ":oncoming-bus:": {
+        "style": "github", 
+        "image": "1f68d.png", 
+        "unicode": "🚍", 
+        "name": "Oncoming Bus"
+    }, 
+    ":unamused:": {
+        "style": "github", 
+        "image": "1f612.png", 
+        "unicode": "😒", 
+        "name": "Unamused Face"
+    }, 
+    ":sign_of_the_horns_tone3:": {
+        "style": "github", 
+        "image": "1f918-1f3fd.png", 
+        "unicode": "🤘🏽", 
+        "name": "Sign Of The Horns - Tone 3"
+    }, 
+    ":deer:": {
+        "style": "github", 
+        "image": "1f98c.png", 
+        "unicode": "🦌", 
+        "name": "Deer"
+    }, 
+    "🏧": {
+        "style": "unicode", 
+        "image": "1f3e7.png", 
+        "name": "Automated Teller Machine"
+    }, 
+    ":prince-tone4:": {
+        "style": "github", 
+        "image": "1f934-1f3fe.png", 
+        "unicode": "🤴🏾", 
+        "name": "Prince - Tone 4"
+    }, 
+    ":film_frames:": {
+        "style": "github", 
+        "image": "1f39e.png", 
+        "unicode": "🎞", 
+        "name": "Film Frames"
+    }, 
+    ":black_joker:": {
+        "style": "github", 
+        "image": "1f0cf.png", 
+        "unicode": "🃏", 
+        "name": "Playing Card Black Joker"
+    }, 
+    ":dancer-tone4:": {
+        "style": "github", 
+        "image": "1f483-1f3fe.png", 
+        "unicode": "💃🏾", 
+        "name": "Dancer - Tone 4"
+    }, 
+    "🍼": {
+        "style": "unicode", 
+        "image": "1f37c.png", 
+        "name": "Baby Bottle"
+    }, 
+    "😕": {
+        "style": "unicode", 
+        "ascii": ">:\\", 
+        "image": "1f615.png", 
+        "name": "Confused Face"
+    }, 
+    "🛣": {
+        "style": "unicode", 
+        "image": "1f6e3.png", 
+        "name": "Motorway"
+    }, 
+    ":cartwheel-tone4:": {
+        "style": "github", 
+        "image": "1f938-1f3fe.png", 
+        "unicode": "🤸🏾", 
+        "name": "Person Doing Cartwheel - Tone 4"
+    }, 
+    ":eh:": {
+        "style": "github", 
+        "image": "1f1ea-1f1ed.png", 
+        "unicode": "🇪🇭", 
+        "name": "Western Sahara"
+    }, 
+    "🚪": {
+        "style": "unicode", 
+        "image": "1f6aa.png", 
+        "name": "Door"
+    }, 
+    ":ferris_wheel:": {
+        "style": "github", 
+        "image": "1f3a1.png", 
+        "unicode": "🎡", 
+        "name": "Ferris Wheel"
+    }, 
+    ":u7121:": {
+        "style": "github", 
+        "image": "1f21a.png", 
+        "unicode": "🈚", 
+        "name": "Squared Cjk Unified Ideograph-7121"
+    }, 
+    ":hankey:": {
+        "style": "github", 
+        "image": "1f4a9.png", 
+        "unicode": "💩", 
+        "name": "Pile Of Poo"
+    }, 
+    ":clock2:": {
+        "style": "github", 
+        "image": "1f551.png", 
+        "unicode": "🕑", 
+        "name": "Clock Face Two Oclock"
+    }, 
+    ":1234:": {
+        "style": "github", 
+        "image": "1f522.png", 
+        "unicode": "🔢", 
+        "name": "Input Symbol For Numbers"
+    }, 
+    ":mh:": {
+        "style": "github", 
+        "image": "1f1f2-1f1ed.png", 
+        "unicode": "🇲🇭", 
+        "name": "The Marshall Islands"
+    }, 
+    "👩": {
+        "style": "unicode", 
+        "image": "1f469.png", 
+        "name": "Woman"
+    }, 
+    ":keyboard:": {
+        "style": "github", 
+        "image": "2328.png", 
+        "unicode": "⌨", 
+        "name": "Keyboard"
+    }, 
+    ":heart_decoration:": {
+        "style": "github", 
+        "image": "1f49f.png", 
+        "unicode": "💟", 
+        "name": "Heart Decoration"
+    }, 
+    ":mosque:": {
+        "style": "github", 
+        "image": "1f54c.png", 
+        "unicode": "🕌", 
+        "name": "Mosque"
+    }, 
+    ":flag_mt:": {
+        "style": "github", 
+        "image": "1f1f2-1f1f9.png", 
+        "unicode": "🇲🇹", 
+        "name": "Malta"
+    }, 
+    "🚓": {
+        "style": "unicode", 
+        "image": "1f693.png", 
+        "name": "Police Car"
+    }, 
+    ":bj:": {
+        "style": "github", 
+        "image": "1f1e7-1f1ef.png", 
+        "unicode": "🇧🇯", 
+        "name": "Benin"
+    }, 
+    "🇹🇲": {
+        "style": "unicode", 
+        "image": "1f1f9-1f1f2.png", 
+        "name": "Turkmenistan"
+    }, 
+    "😨": {
+        "style": "unicode", 
+        "ascii": "D:", 
+        "image": "1f628.png", 
+        "name": "Fearful Face"
+    }, 
+    ":hammer_and_wrench:": {
+        "style": "github", 
+        "image": "1f6e0.png", 
+        "unicode": "🛠", 
+        "name": "Hammer And Wrench"
+    }, 
+    ":woman-tone5:": {
+        "style": "github", 
+        "image": "1f469-1f3ff.png", 
+        "unicode": "👩🏿", 
+        "name": "Woman - Tone 5"
+    }, 
+    ":man-tone4:": {
+        "style": "github", 
+        "image": "1f468-1f3fe.png", 
+        "unicode": "👨🏾", 
+        "name": "Man - Tone 4"
+    }, 
+    "♈": {
+        "style": "unicode", 
+        "image": "2648.png", 
+        "name": "Aries"
+    }, 
+    ":shrug_tone1:": {
+        "style": "github", 
+        "image": "1f937-1f3fb.png", 
+        "unicode": "🤷🏻", 
+        "name": "Shrug - Tone 1"
+    }, 
+    ":package:": {
+        "style": "github", 
+        "image": "1f4e6.png", 
+        "unicode": "📦", 
+        "name": "Package"
+    }, 
+    ":helicopter:": {
+        "style": "github", 
+        "image": "1f681.png", 
+        "unicode": "🚁", 
+        "name": "Helicopter"
+    }, 
+    ":bomb:": {
+        "style": "github", 
+        "image": "1f4a3.png", 
+        "unicode": "💣", 
+        "name": "Bomb"
+    }, 
+    ":flag-pw:": {
+        "style": "github", 
+        "image": "1f1f5-1f1fc.png", 
+        "unicode": "🇵🇼", 
+        "name": "Palau"
+    }, 
+    ":negative_squared_cross_mark:": {
+        "style": "github", 
+        "image": "274e.png", 
+        "unicode": "❎", 
+        "name": "Negative Squared Cross Mark"
+    }, 
+    ":flag_bq:": {
+        "style": "github", 
+        "image": "1f1e7-1f1f6.png", 
+        "unicode": "🇧🇶", 
+        "name": "Caribbean Netherlands"
+    }, 
+    "🤰🏿": {
+        "style": "unicode", 
+        "image": "1f930-1f3ff.png", 
+        "name": "Pregnant Woman - Tone 5"
+    }, 
+    "🌑": {
+        "style": "unicode", 
+        "image": "1f311.png", 
+        "name": "New Moon Symbol"
+    }, 
+    "🙎🏻": {
+        "style": "unicode", 
+        "image": "1f64e-1f3fb.png", 
+        "name": "Person With Pouting Face Tone1"
+    }, 
+    "🔕": {
+        "style": "unicode", 
+        "image": "1f515.png", 
+        "name": "Bell With Cancellation Stroke"
+    }, 
+    "🙎🏽": {
+        "style": "unicode", 
+        "image": "1f64e-1f3fd.png", 
+        "name": "Person With Pouting Face Tone3"
+    }, 
+    "🙎🏾": {
+        "style": "unicode", 
+        "image": "1f64e-1f3fe.png", 
+        "name": "Person With Pouting Face Tone4"
+    }, 
+    "🙎🏿": {
+        "style": "unicode", 
+        "image": "1f64e-1f3ff.png", 
+        "name": "Person With Pouting Face Tone5"
+    }, 
+    ":sweet_potato:": {
+        "style": "github", 
+        "image": "1f360.png", 
+        "unicode": "🍠", 
+        "name": "Roasted Sweet Potato"
+    }, 
+    ":eight_spoked_asterisk:": {
+        "style": "github", 
+        "image": "2733.png", 
+        "unicode": "✳", 
+        "name": "Eight Spoked Asterisk"
+    }, 
+    "🎦": {
+        "style": "unicode", 
+        "image": "1f3a6.png", 
+        "name": "Cinema"
+    }, 
+    ":christmas-tree:": {
+        "style": "github", 
+        "image": "1f384.png", 
+        "unicode": "🎄", 
+        "name": "Christmas Tree"
+    }, 
+    ":snowflake:": {
+        "style": "github", 
+        "image": "2744.png", 
+        "unicode": "❄", 
+        "name": "Snowflake"
+    }, 
+    ":cartwheel_tone2:": {
+        "style": "github", 
+        "image": "1f938-1f3fc.png", 
+        "unicode": "🤸🏼", 
+        "name": "Person Doing Cartwheel - Tone 2"
+    }, 
+    ":cloud_with_rain:": {
+        "style": "github", 
+        "image": "1f327.png", 
+        "unicode": "🌧", 
+        "name": "Cloud With Rain"
+    }, 
+    "🐿": {
+        "style": "unicode", 
+        "image": "1f43f.png", 
+        "name": "Chipmunk"
+    }, 
+    ":field_hockey:": {
+        "style": "github", 
+        "image": "1f3d1.png", 
+        "unicode": "🏑", 
+        "name": "Field Hockey Stick And Ball"
+    }, 
+    ":ga:": {
+        "style": "github", 
+        "image": "1f1ec-1f1e6.png", 
+        "unicode": "🇬🇦", 
+        "name": "Gabon"
+    }, 
+    ":left_fist_tone2:": {
+        "style": "github", 
+        "image": "1f91b-1f3fc.png", 
+        "unicode": "🤛🏼", 
+        "name": "Left Facing Fist - Tone 2"
+    }, 
+    "📔": {
+        "style": "unicode", 
+        "image": "1f4d4.png", 
+        "name": "Notebook With Decorative Cover"
+    }, 
+    ":-1:": {
+        "style": "github", 
+        "image": "1f44e.png", 
+        "unicode": "👎", 
+        "name": "Thumbs Down Sign"
+    }, 
+    ":flag-ve:": {
+        "style": "github", 
+        "image": "1f1fb-1f1ea.png", 
+        "unicode": "🇻🇪", 
+        "name": "Venezuela"
+    }, 
+    "🇳🇿": {
+        "style": "unicode", 
+        "image": "1f1f3-1f1ff.png", 
+        "name": "New Zealand"
+    }, 
+    "🤝🏽": {
+        "style": "unicode", 
+        "image": "1f91d-1f3fd.png", 
+        "name": "Handshake - Tone 3"
+    }, 
+    "🤝🏼": {
+        "style": "unicode", 
+        "image": "1f91d-1f3fc.png", 
+        "name": "Handshake - Tone 2"
+    }, 
+    "🇳🇱": {
+        "style": "unicode", 
+        "image": "1f1f3-1f1f1.png", 
+        "name": "The Netherlands"
+    }, 
+    "🤝🏾": {
+        "style": "unicode", 
+        "image": "1f91d-1f3fe.png", 
+        "name": "Handshake - Tone 4"
+    }, 
+    "🇳🇷": {
+        "style": "unicode", 
+        "image": "1f1f3-1f1f7.png", 
+        "name": "Nauru"
+    }, 
+    "🇳🇵": {
+        "style": "unicode", 
+        "image": "1f1f3-1f1f5.png", 
+        "name": "Nepal"
+    }, 
+    "🇳🇴": {
+        "style": "unicode", 
+        "image": "1f1f3-1f1f4.png", 
+        "name": "Norway"
+    }, 
+    "🇳🇫": {
+        "style": "unicode", 
+        "image": "1f1f3-1f1eb.png", 
+        "name": "Norfolk Island"
+    }, 
+    "🇳🇪": {
+        "style": "unicode", 
+        "image": "1f1f3-1f1ea.png", 
+        "name": "Niger"
+    }, 
+    ":mag-right:": {
+        "style": "github", 
+        "image": "1f50e.png", 
+        "unicode": "🔎", 
+        "name": "Right-pointing Magnifying Glass"
+    }, 
+    "🇳🇮": {
+        "style": "unicode", 
+        "image": "1f1f3-1f1ee.png", 
+        "name": "Nicaragua"
+    }, 
+    "🇳🇬": {
+        "style": "unicode", 
+        "image": "1f1f3-1f1ec.png", 
+        "name": "Nigeria"
+    }, 
+    "🇳🇦": {
+        "style": "unicode", 
+        "image": "1f1f3-1f1e6.png", 
+        "name": "Namibia"
+    }, 
+    ":right_fist_tone3:": {
+        "style": "github", 
+        "image": "1f91c-1f3fd.png", 
+        "unicode": "🤜🏽", 
+        "name": "Right Facing Fist - Tone 3"
+    }, 
+    "🔬": {
+        "style": "unicode", 
+        "image": "1f52c.png", 
+        "name": "Microscope"
+    }, 
+    ":cop_tone2:": {
+        "style": "github", 
+        "image": "1f46e-1f3fc.png", 
+        "unicode": "👮🏼", 
+        "name": "Police Officer - Tone 2"
+    }, 
+    ":u6708:": {
+        "style": "github", 
+        "image": "1f237.png", 
+        "unicode": "🈷", 
+        "name": "Squared Cjk Unified Ideograph-6708"
+    }, 
+    ":man-in-tuxedo-tone2:": {
+        "style": "github", 
+        "image": "1f935-1f3fc.png", 
+        "unicode": "🤵🏼", 
+        "name": "Man In Tuxedo - Tone 2"
+    }, 
+    ":mw:": {
+        "style": "github", 
+        "image": "1f1f2-1f1fc.png", 
+        "unicode": "🇲🇼", 
+        "name": "Malawi"
+    }, 
+    ":cu:": {
+        "style": "github", 
+        "image": "1f1e8-1f1fa.png", 
+        "unicode": "🇨🇺", 
+        "name": "Cuba"
+    }, 
+    ":flag-um:": {
+        "style": "github", 
+        "image": "1f1fa-1f1f2.png", 
+        "unicode": "🇺🇲", 
+        "name": "United States Minor Outlying Islands"
+    }, 
+    ":man-with-gua-pi-mao-tone4:": {
+        "style": "github", 
+        "image": "1f472-1f3fe.png", 
+        "unicode": "👲🏾", 
+        "name": "Man With Gua Pi Mao - Tone 4"
+    }, 
+    ":carousel-horse:": {
+        "style": "github", 
+        "image": "1f3a0.png", 
+        "unicode": "🎠", 
+        "name": "Carousel Horse"
+    }, 
+    ":wrestling:": {
+        "style": "github", 
+        "image": "1f93c.png", 
+        "unicode": "🤼", 
+        "name": "Wrestlers"
+    }, 
+    "🇧": {
+        "style": "unicode", 
+        "image": "1f1e7.png", 
+        "name": "Regional Indicator Symbol Letter B"
+    }, 
+    ":flag-ml:": {
+        "style": "github", 
+        "image": "1f1f2-1f1f1.png", 
+        "unicode": "🇲🇱", 
+        "name": "Mali"
+    }, 
+    ":frowning:": {
+        "style": "github", 
+        "image": "1f626.png", 
+        "unicode": "😦", 
+        "name": "Frowning Face With Open Mouth"
+    }, 
+    ":ke:": {
+        "style": "github", 
+        "image": "1f1f0-1f1ea.png", 
+        "unicode": "🇰🇪", 
+        "name": "Kenya"
+    }, 
+    ":clown:": {
+        "style": "github", 
+        "image": "1f921.png", 
+        "unicode": "🤡", 
+        "name": "Clown Face"
+    }, 
+    ":haircut-tone1:": {
+        "style": "github", 
+        "image": "1f487-1f3fb.png", 
+        "unicode": "💇🏻", 
+        "name": "Haircut - Tone 1"
+    }, 
+    ":skier:": {
+        "style": "github", 
+        "image": "26f7.png", 
+        "unicode": "⛷", 
+        "name": "Skier"
+    }, 
+    "🐕": {
+        "style": "unicode", 
+        "image": "1f415.png", 
+        "name": "Dog"
+    }, 
+    ":+1_tone1:": {
+        "style": "github", 
+        "image": "1f44d-1f3fb.png", 
+        "unicode": "👍🏻", 
+        "name": "Thumbs Up Sign - Tone 1"
+    }, 
+    ":potable_water:": {
+        "style": "github", 
+        "image": "1f6b0.png", 
+        "unicode": "🚰", 
+        "name": "Potable Water Symbol"
+    }, 
+    ":flag-np:": {
+        "style": "github", 
+        "image": "1f1f3-1f1f5.png", 
+        "unicode": "🇳🇵", 
+        "name": "Nepal"
+    }, 
+    ":u7a7a:": {
+        "style": "github", 
+        "image": "1f233.png", 
+        "unicode": "🈳", 
+        "name": "Squared Cjk Unified Ideograph-7a7a"
+    }, 
+    "💪": {
+        "style": "unicode", 
+        "image": "1f4aa.png", 
+        "name": "Flexed Biceps"
+    }, 
+    "✋🏾": {
+        "style": "unicode", 
+        "image": "270b-1f3fe.png", 
+        "name": "Raised Hand - Tone 4"
+    }, 
+    ":flag-tf:": {
+        "style": "github", 
+        "image": "1f1f9-1f1eb.png", 
+        "unicode": "🇹🇫", 
+        "name": "French Southern Territories"
+    }, 
+    "🤷": {
+        "style": "unicode", 
+        "image": "1f937.png", 
+        "name": "Shrug"
+    }, 
+    ":flag_fm:": {
+        "style": "github", 
+        "image": "1f1eb-1f1f2.png", 
+        "unicode": "🇫🇲", 
+        "name": "Micronesia"
+    }, 
+    ":flag_ea:": {
+        "style": "github", 
+        "image": "1f1ea-1f1e6.png", 
+        "unicode": "🇪🇦", 
+        "name": "Ceuta, Melilla"
+    }, 
+    ":karate_uniform:": {
+        "style": "github", 
+        "image": "1f94b.png", 
+        "unicode": "🥋", 
+        "name": "Martial Arts Uniform"
+    }, 
+    "🌻": {
+        "style": "unicode", 
+        "image": "1f33b.png", 
+        "name": "Sunflower"
+    }, 
+    "〽": {
+        "style": "unicode", 
+        "image": "303d.png", 
+        "name": "Part Alternation Mark"
+    }, 
+    ":white-medium-small-square:": {
+        "style": "github", 
+        "image": "25fd.png", 
+        "unicode": "◽", 
+        "name": "White Medium Small Square"
+    }, 
+    "🤾🏻": {
+        "style": "unicode", 
+        "image": "1f93e-1f3fb.png", 
+        "name": "Handball - Tone 1"
+    }, 
+    "🤾🏼": {
+        "style": "unicode", 
+        "image": "1f93e-1f3fc.png", 
+        "name": "Handball - Tone 2"
+    }, 
+    "🤾🏽": {
+        "style": "unicode", 
+        "image": "1f93e-1f3fd.png", 
+        "name": "Handball - Tone 3"
+    }, 
+    "🤾🏾": {
+        "style": "unicode", 
+        "image": "1f93e-1f3fe.png", 
+        "name": "Handball - Tone 4"
+    }, 
+    "🤾🏿": {
+        "style": "unicode", 
+        "image": "1f93e-1f3ff.png", 
+        "name": "Handball - Tone 5"
+    }, 
+    "🏐": {
+        "style": "unicode", 
+        "image": "1f3d0.png", 
+        "name": "Volleyball"
+    }, 
+    ":tumbler-glass:": {
+        "style": "github", 
+        "image": "1f943.png", 
+        "unicode": "🥃", 
+        "name": "Tumbler Glass"
+    }, 
+    ":police-car:": {
+        "style": "github", 
+        "image": "1f693.png", 
+        "unicode": "🚓", 
+        "name": "Police Car"
+    }, 
+    ":thumbup_tone3:": {
+        "style": "github", 
+        "image": "1f44d-1f3fd.png", 
+        "unicode": "👍🏽", 
+        "name": "Thumbs Up Sign - Tone 3"
+    }, 
+    ":flag-lv:": {
+        "style": "github", 
+        "image": "1f1f1-1f1fb.png", 
+        "unicode": "🇱🇻", 
+        "name": "Latvia"
+    }, 
+    ":fire:": {
+        "style": "github", 
+        "image": "1f525.png", 
+        "unicode": "🔥", 
+        "name": "Fire"
+    }, 
+    "⏰": {
+        "style": "unicode", 
+        "image": "23f0.png", 
+        "name": "Alarm Clock"
+    }, 
+    "D:": {
+        "style": "ascii", 
+        "ascii": "D:", 
+        "image": "1f628.png", 
+        "unicode": "😨", 
+        "name": "Fearful Face"
+    }, 
+    ":swimmer-tone2:": {
+        "style": "github", 
+        "image": "1f3ca-1f3fc.png", 
+        "unicode": "🏊🏼", 
+        "name": "Swimmer - Tone 2"
+    }, 
+    ":basketball-player-tone2:": {
+        "style": "github", 
+        "image": "26f9-1f3fc.png", 
+        "unicode": "⛹🏼", 
+        "name": "Person With Ball - Tone 2"
+    }, 
+    ":barber:": {
+        "style": "github", 
+        "image": "1f488.png", 
+        "unicode": "💈", 
+        "name": "Barber Pole"
+    }, 
+    ":facepalm:": {
+        "style": "github", 
+        "image": "1f926.png", 
+        "unicode": "🤦", 
+        "name": "Face Palm"
+    }, 
+    ":couple-mm:": {
+        "style": "github", 
+        "image": "1f468-2764-1f468.png", 
+        "unicode": "👨❤👨", 
+        "name": "Couple (man,man)"
+    }, 
+    "👍🏼": {
+        "style": "unicode", 
+        "image": "1f44d-1f3fc.png", 
+        "name": "Thumbs Up Sign - Tone 2"
+    }, 
+    ":hand_splayed_tone5:": {
+        "style": "github", 
+        "image": "1f590-1f3ff.png", 
+        "unicode": "🖐🏿", 
+        "name": "Raised Hand With Fingers Splayed - Tone 5"
+    }, 
+    ":man_tone5:": {
+        "style": "github", 
+        "image": "1f468-1f3ff.png", 
+        "unicode": "👨🏿", 
+        "name": "Man - Tone 5"
+    }, 
+    ":anchor:": {
+        "style": "github", 
+        "image": "2693.png", 
+        "unicode": "⚓", 
+        "name": "Anchor"
+    }, 
+    ":sh:": {
+        "style": "github", 
+        "image": "1f1f8-1f1ed.png", 
+        "unicode": "🇸🇭", 
+        "name": "Saint Helena"
+    }, 
+    "#⃣": {
+        "style": "unicode", 
+        "image": "0023-20e3.png", 
+        "name": "Keycap Number Sign"
+    }, 
+    ":bicyclist-tone4:": {
+        "style": "github", 
+        "image": "1f6b4-1f3fe.png", 
+        "unicode": "🚴🏾", 
+        "name": "Bicyclist - Tone 4"
+    }, 
+    "0:3": {
+        "style": "ascii", 
+        "ascii": "O:-)", 
+        "image": "1f607.png", 
+        "unicode": "😇", 
+        "name": "Smiling Face With Halo"
+    }, 
+    ":horse-racing-tone4:": {
+        "style": "github", 
+        "image": "1f3c7-1f3fe.png", 
+        "unicode": "🏇🏾", 
+        "name": "Horse Racing - Tone 4"
+    }, 
+    "0:)": {
+        "style": "ascii", 
+        "ascii": "O:-)", 
+        "image": "1f607.png", 
+        "unicode": "😇", 
+        "name": "Smiling Face With Halo"
+    }, 
+    ":raised_back_of_hand_tone2:": {
+        "style": "github", 
+        "image": "1f91a-1f3fc.png", 
+        "unicode": "🤚🏼", 
+        "name": "Raised Back Of Hand - Tone 2"
+    }, 
+    ":girl-tone1:": {
+        "style": "github", 
+        "image": "1f467-1f3fb.png", 
+        "unicode": "👧🏻", 
+        "name": "Girl - Tone 1"
+    }, 
+    ":flag_ie:": {
+        "style": "github", 
+        "image": "1f1ee-1f1ea.png", 
+        "unicode": "🇮🇪", 
+        "name": "Ireland"
+    }, 
+    "🤰🏻": {
+        "style": "unicode", 
+        "image": "1f930-1f3fb.png", 
+        "name": "Pregnant Woman - Tone 1"
+    }, 
+    "🤰🏾": {
+        "style": "unicode", 
+        "image": "1f930-1f3fe.png", 
+        "name": "Pregnant Woman - Tone 4"
+    }, 
+    ":monorail:": {
+        "style": "github", 
+        "image": "1f69d.png", 
+        "unicode": "🚝", 
+        "name": "Monorail"
+    }, 
+    "🤰🏼": {
+        "style": "unicode", 
+        "image": "1f930-1f3fc.png", 
+        "name": "Pregnant Woman - Tone 2"
+    }, 
+    "🤰🏽": {
+        "style": "unicode", 
+        "image": "1f930-1f3fd.png", 
+        "name": "Pregnant Woman - Tone 3"
+    }, 
+    ":nose-tone2:": {
+        "style": "github", 
+        "image": "1f443-1f3fc.png", 
+        "unicode": "👃🏼", 
+        "name": "Nose - Tone 2"
+    }, 
+    ":point_up_2_tone4:": {
+        "style": "github", 
+        "image": "1f446-1f3fe.png", 
+        "unicode": "👆🏾", 
+        "name": "White Up Pointing Backhand Index - Tone 4"
+    }, 
+    ":regional_indicator_g:": {
+        "style": "github", 
+        "image": "1f1ec.png", 
+        "unicode": "🇬", 
+        "name": "Regional Indicator Symbol Letter G"
+    }, 
+    "X-)": {
+        "style": "ascii", 
+        "ascii": "#-)", 
+        "image": "1f635.png", 
+        "unicode": "😵", 
+        "name": "Dizzy Face"
+    }, 
+    ":ferry:": {
+        "style": "github", 
+        "image": "26f4.png", 
+        "unicode": "⛴", 
+        "name": "Ferry"
+    }, 
+    "🔑": {
+        "style": "unicode", 
+        "image": "1f511.png", 
+        "name": "Key"
+    }, 
+    "🌕": {
+        "style": "unicode", 
+        "image": "1f315.png", 
+        "name": "Full Moon Symbol"
+    }, 
+    "✋🏻": {
+        "style": "unicode", 
+        "image": "270b-1f3fb.png", 
+        "name": "Raised Hand - Tone 1"
+    }, 
+    "✋🏿": {
+        "style": "unicode", 
+        "image": "270b-1f3ff.png", 
+        "name": "Raised Hand - Tone 5"
+    }, 
+    "⚜": {
+        "style": "unicode", 
+        "image": "269c.png", 
+        "name": "Fleur-de-lis"
+    }, 
+    "✋🏽": {
+        "style": "unicode", 
+        "image": "270b-1f3fd.png", 
+        "name": "Raised Hand - Tone 3"
+    }, 
+    "✋🏼": {
+        "style": "unicode", 
+        "image": "270b-1f3fc.png", 
+        "name": "Raised Hand - Tone 2"
+    }, 
+    ":ug:": {
+        "style": "github", 
+        "image": "1f1fa-1f1ec.png", 
+        "unicode": "🇺🇬", 
+        "name": "Uganda"
+    }, 
+    ":raised_hand_tone5:": {
+        "style": "github", 
+        "image": "270b-1f3ff.png", 
+        "unicode": "✋🏿", 
+        "name": "Raised Hand - Tone 5"
+    }, 
+    "🎪": {
+        "style": "unicode", 
+        "image": "1f3aa.png", 
+        "name": "Circus Tent"
+    }, 
+    ":euro:": {
+        "style": "github", 
+        "image": "1f4b6.png", 
+        "unicode": "💶", 
+        "name": "Banknote With Euro Sign"
+    }, 
+    ":pencil:": {
+        "style": "github", 
+        "image": "1f4dd.png", 
+        "unicode": "📝", 
+        "name": "Memo"
+    }, 
+    "🐻": {
+        "style": "unicode", 
+        "image": "1f43b.png", 
+        "name": "Bear Face"
+    }, 
+    ":flag-er:": {
+        "style": "github", 
+        "image": "1f1ea-1f1f7.png", 
+        "unicode": "🇪🇷", 
+        "name": "Eritrea"
+    }, 
+    "📐": {
+        "style": "unicode", 
+        "image": "1f4d0.png", 
+        "name": "Triangular Ruler"
+    }, 
+    ":shaking_hands_tone2:": {
+        "style": "github", 
+        "image": "1f91d-1f3fc.png", 
+        "unicode": "🤝🏼", 
+        "name": "Handshake - Tone 2"
+    }, 
+    ":flag_at:": {
+        "style": "github", 
+        "image": "1f1e6-1f1f9.png", 
+        "unicode": "🇦🇹", 
+        "name": "Austria"
+    }, 
+    ":muscle_tone5:": {
+        "style": "github", 
+        "image": "1f4aa-1f3ff.png", 
+        "unicode": "💪🏿", 
+        "name": "Flexed Biceps - Tone 5"
+    }, 
+    ":kiss:": {
+        "style": "github", 
+        "image": "1f48b.png", 
+        "unicode": "💋", 
+        "name": "Kiss Mark"
+    }, 
+    ":flag-mq:": {
+        "style": "github", 
+        "image": "1f1f2-1f1f6.png", 
+        "unicode": "🇲🇶", 
+        "name": "Martinique"
+    }, 
+    ":salad:": {
+        "style": "github", 
+        "image": "1f957.png", 
+        "unicode": "🥗", 
+        "name": "Green Salad"
+    }, 
+    "X-P": {
+        "style": "ascii", 
+        "ascii": ">:P", 
+        "image": "1f61c.png", 
+        "unicode": "😜", 
+        "name": "Face With Stuck-out Tongue And Winking Eye"
+    }, 
+    "🇾": {
+        "style": "unicode", 
+        "image": "1f1fe.png", 
+        "name": "Regional Indicator Symbol Letter Y"
+    }, 
+    ":flag-sx:": {
+        "style": "github", 
+        "image": "1f1f8-1f1fd.png", 
+        "unicode": "🇸🇽", 
+        "name": "Sint Maarten"
+    }, 
+    "🆓": {
+        "style": "unicode", 
+        "image": "1f193.png", 
+        "name": "Squared Free"
+    }, 
+    ":flag-ea:": {
+        "style": "github", 
+        "image": "1f1ea-1f1e6.png", 
+        "unicode": "🇪🇦", 
+        "name": "Ceuta, Melilla"
+    }, 
+    ":ice_cream:": {
+        "style": "github", 
+        "image": "1f368.png", 
+        "unicode": "🍨", 
+        "name": "Ice Cream"
+    }, 
+    ":turkmenistan:": {
+        "style": "github", 
+        "image": "1f1f9-1f1f2.png", 
+        "unicode": "🇹🇲", 
+        "name": "Turkmenistan"
+    }, 
+    "🚽": {
+        "style": "unicode", 
+        "image": "1f6bd.png", 
+        "name": "Toilet"
+    }, 
+    ":baby_tone4:": {
+        "style": "github", 
+        "image": "1f476-1f3fe.png", 
+        "unicode": "👶🏾", 
+        "name": "Baby - Tone 4"
+    }, 
+    ":no-bell:": {
+        "style": "github", 
+        "image": "1f515.png", 
+        "unicode": "🔕", 
+        "name": "Bell With Cancellation Stroke"
+    }, 
+    ":person_with_blond_hair_tone1:": {
+        "style": "github", 
+        "image": "1f471-1f3fb.png", 
+        "unicode": "👱🏻", 
+        "name": "Person With Blond Hair - Tone 1"
+    }, 
+    ":poodle:": {
+        "style": "github", 
+        "image": "1f429.png", 
+        "unicode": "🐩", 
+        "name": "Poodle"
+    }, 
+    ":pouting-cat:": {
+        "style": "github", 
+        "image": "1f63e.png", 
+        "unicode": "😾", 
+        "name": "Pouting Cat Face"
+    }, 
+    ":envelope-with-arrow:": {
+        "style": "github", 
+        "image": "1f4e9.png", 
+        "unicode": "📩", 
+        "name": "Envelope With Downwards Arrow Above"
+    }, 
+    ":man_dancing:": {
+        "style": "github", 
+        "image": "1f57a.png", 
+        "unicode": "🕺", 
+        "name": "Man Dancing"
+    }, 
+    ":man_with_gua_pi_mao_tone4:": {
+        "style": "github", 
+        "image": "1f472-1f3fe.png", 
+        "unicode": "👲🏾", 
+        "name": "Man With Gua Pi Mao - Tone 4"
+    }, 
+    ":flag-de:": {
+        "style": "github", 
+        "image": "1f1e9-1f1ea.png", 
+        "unicode": "🇩🇪", 
+        "name": "Germany"
+    }, 
+    ":heavy-dollar-sign:": {
+        "style": "github", 
+        "image": "1f4b2.png", 
+        "unicode": "💲", 
+        "name": "Heavy Dollar Sign"
+    }, 
+    ":flag_bl:": {
+        "style": "github", 
+        "image": "1f1e7-1f1f1.png", 
+        "unicode": "🇧🇱", 
+        "name": "Saint Barthélemy"
+    }, 
+    ":dolphin:": {
+        "style": "github", 
+        "image": "1f42c.png", 
+        "unicode": "🐬", 
+        "name": "Dolphin"
+    }, 
+    ":flag-am:": {
+        "style": "github", 
+        "image": "1f1e6-1f1f2.png", 
+        "unicode": "🇦🇲", 
+        "name": "Armenia"
+    }, 
+    "🇨🇿": {
+        "style": "unicode", 
+        "image": "1f1e8-1f1ff.png", 
+        "name": "The Czech Republic"
+    }, 
+    ":horse_racing:": {
+        "style": "github", 
+        "image": "1f3c7.png", 
+        "unicode": "🏇", 
+        "name": "Horse Racing"
+    }, 
+    "💦": {
+        "style": "unicode", 
+        "image": "1f4a6.png", 
+        "name": "Splashing Sweat Symbol"
+    }, 
+    ":runner_tone5:": {
+        "style": "github", 
+        "image": "1f3c3-1f3ff.png", 
+        "unicode": "🏃🏿", 
+        "name": "Runner - Tone 5"
+    }, 
+    "🔻": {
+        "style": "unicode", 
+        "image": "1f53b.png", 
+        "name": "Down-pointing Red Triangle"
+    }, 
+    ":bow_and_arrow:": {
+        "style": "github", 
+        "image": "1f3f9.png", 
+        "unicode": "🏹", 
+        "name": "Bow And Arrow"
+    }, 
+    "🌿": {
+        "style": "unicode", 
+        "image": "1f33f.png", 
+        "name": "Herb"
+    }, 
+    ":regional-indicator-h:": {
+        "style": "github", 
+        "image": "1f1ed.png", 
+        "unicode": "🇭", 
+        "name": "Regional Indicator Symbol Letter H"
+    }, 
+    "6⃣": {
+        "style": "unicode", 
+        "image": "0036-20e3.png", 
+        "name": "Keycap Digit Six"
+    }, 
+    ":cheese:": {
+        "style": "github", 
+        "image": "1f9c0.png", 
+        "unicode": "🧀", 
+        "name": "Cheese Wedge"
+    }, 
+    ":flag-bw:": {
+        "style": "github", 
+        "image": "1f1e7-1f1fc.png", 
+        "unicode": "🇧🇼", 
+        "name": "Botswana"
+    }, 
+    "🇨🇷": {
+        "style": "unicode", 
+        "image": "1f1e8-1f1f7.png", 
+        "name": "Costa Rica"
+    }, 
+    ":bride-with-veil-tone1:": {
+        "style": "github", 
+        "image": "1f470-1f3fb.png", 
+        "unicode": "👰🏻", 
+        "name": "Bride With Veil - Tone 1"
+    }, 
+    "🏔": {
+        "style": "unicode", 
+        "image": "1f3d4.png", 
+        "name": "Snow Capped Mountain"
+    }, 
+    ":right_facing_fist_tone3:": {
+        "style": "github", 
+        "image": "1f91c-1f3fd.png", 
+        "unicode": "🤜🏽", 
+        "name": "Right Facing Fist - Tone 3"
+    }, 
+    ":sign_of_the_horns_tone5:": {
+        "style": "github", 
+        "image": "1f918-1f3ff.png", 
+        "unicode": "🤘🏿", 
+        "name": "Sign Of The Horns - Tone 5"
+    }, 
+    ":pig2:": {
+        "style": "github", 
+        "image": "1f416.png", 
+        "unicode": "🐖", 
+        "name": "Pig"
+    }, 
+    ":green_salad:": {
+        "style": "github", 
+        "image": "1f957.png", 
+        "unicode": "🥗", 
+        "name": "Green Salad"
+    }, 
+    ":princess-tone5:": {
+        "style": "github", 
+        "image": "1f478-1f3ff.png", 
+        "unicode": "👸🏿", 
+        "name": "Princess - Tone 5"
+    }, 
+    ":thumbsup_tone3:": {
+        "style": "github", 
+        "image": "1f44d-1f3fd.png", 
+        "unicode": "👍🏽", 
+        "name": "Thumbs Up Sign - Tone 3"
+    }, 
+    ":person-with-pouting-face:": {
+        "style": "github", 
+        "image": "1f64e.png", 
+        "unicode": "🙎", 
+        "name": "Person With Pouting Face"
+    }, 
+    ":house_with_garden:": {
+        "style": "github", 
+        "image": "1f3e1.png", 
+        "unicode": "🏡", 
+        "name": "House With Garden"
+    }, 
+    "👌🏾": {
+        "style": "unicode", 
+        "image": "1f44c-1f3fe.png", 
+        "name": "Ok Hand Sign - Tone 4"
+    }, 
+    "👌🏿": {
+        "style": "unicode", 
+        "image": "1f44c-1f3ff.png", 
+        "name": "Ok Hand Sign - Tone 5"
+    }, 
+    "👌🏼": {
+        "style": "unicode", 
+        "image": "1f44c-1f3fc.png", 
+        "name": "Ok Hand Sign - Tone 2"
+    }, 
+    "👌🏽": {
+        "style": "unicode", 
+        "image": "1f44c-1f3fd.png", 
+        "name": "Ok Hand Sign - Tone 3"
+    }, 
+    "👌🏻": {
+        "style": "unicode", 
+        "image": "1f44c-1f3fb.png", 
+        "name": "Ok Hand Sign - Tone 1"
+    }, 
+    "👨👨👦👦": {
+        "style": "unicode", 
+        "image": "1f468-1f468-1f466-1f466.png", 
+        "name": "Family (man,man,boy,boy)"
+    }, 
+    ":mountain-bicyclist-tone2:": {
+        "style": "github", 
+        "image": "1f6b5-1f3fc.png", 
+        "unicode": "🚵🏼", 
+        "name": "Mountain Bicyclist - Tone 2"
+    }, 
+    ":flag_ss:": {
+        "style": "github", 
+        "image": "1f1f8-1f1f8.png", 
+        "unicode": "🇸🇸", 
+        "name": "South Sudan"
+    }, 
+    ":airplane_arriving:": {
+        "style": "github", 
+        "image": "1f6ec.png", 
+        "unicode": "🛬", 
+        "name": "Airplane Arriving"
+    }, 
+    ":fried-shrimp:": {
+        "style": "github", 
+        "image": "1f364.png", 
+        "unicode": "🍤", 
+        "name": "Fried Shrimp"
+    }, 
+    ":boy-tone5:": {
+        "style": "github", 
+        "image": "1f466-1f3ff.png", 
+        "unicode": "👦🏿", 
+        "name": "Boy - Tone 5"
+    }, 
+    ":cocktail:": {
+        "style": "github", 
+        "image": "1f378.png", 
+        "unicode": "🍸", 
+        "name": "Cocktail Glass"
+    }, 
+    ":dz:": {
+        "style": "github", 
+        "image": "1f1e9-1f1ff.png", 
+        "unicode": "🇩🇿", 
+        "name": "Algeria"
+    }, 
+    "🕒": {
+        "style": "unicode", 
+        "image": "1f552.png", 
+        "name": "Clock Face Three Oclock"
+    }, 
+    ":clock4:": {
+        "style": "github", 
+        "image": "1f553.png", 
+        "unicode": "🕓", 
+        "name": "Clock Face Four Oclock"
+    }, 
+    ":person-with-pouting-face-tone4:": {
+        "style": "github", 
+        "image": "1f64e-1f3fe.png", 
+        "unicode": "🙎🏾", 
+        "name": "Person With Pouting Face Tone4"
+    }, 
+    ":u5272:": {
+        "style": "github", 
+        "image": "1f239.png", 
+        "unicode": "🈹", 
+        "name": "Squared Cjk Unified Ideograph-5272"
+    }, 
+    "📧": {
+        "style": "unicode", 
+        "image": "1f4e7.png", 
+        "name": "E-mail Symbol"
+    }, 
+    ":libra:": {
+        "style": "github", 
+        "image": "264e.png", 
+        "unicode": "♎", 
+        "name": "Libra"
+    }, 
+    ":basketball_player_tone4:": {
+        "style": "github", 
+        "image": "26f9-1f3fe.png", 
+        "unicode": "⛹🏾", 
+        "name": "Person With Ball - Tone 4"
+    }, 
+    ":lion_face:": {
+        "style": "github", 
+        "image": "1f981.png", 
+        "unicode": "🦁", 
+        "name": "Lion Face"
+    }, 
+    ":sleeping_accommodation:": {
+        "style": "github", 
+        "image": "1f6cc.png", 
+        "unicode": "🛌", 
+        "name": "Sleeping Accommodation"
+    }, 
+    ":tanabata-tree:": {
+        "style": "github", 
+        "image": "1f38b.png", 
+        "unicode": "🎋", 
+        "name": "Tanabata Tree"
+    }, 
+    "👼": {
+        "style": "unicode", 
+        "image": "1f47c.png", 
+        "name": "Baby Angel"
+    }, 
+    ":bt:": {
+        "style": "github", 
+        "image": "1f1e7-1f1f9.png", 
+        "unicode": "🇧🇹", 
+        "name": "Bhutan"
+    }, 
+    ":taco:": {
+        "style": "github", 
+        "image": "1f32e.png", 
+        "unicode": "🌮", 
+        "name": "Taco"
+    }, 
+    ":whale:": {
+        "style": "github", 
+        "image": "1f433.png", 
+        "unicode": "🐳", 
+        "name": "Spouting Whale"
+    }, 
+    ":flag_rs:": {
+        "style": "github", 
+        "image": "1f1f7-1f1f8.png", 
+        "unicode": "🇷🇸", 
+        "name": "Serbia"
+    }, 
+    ":family-wwg:": {
+        "style": "github", 
+        "image": "1f469-1f469-1f467.png", 
+        "unicode": "👩👩👧", 
+        "name": "Family (woman,woman,girl)"
+    }, 
+    "😻": {
+        "style": "unicode", 
+        "image": "1f63b.png", 
+        "name": "Smiling Cat Face With Heart-shaped Eyes"
+    }, 
+    ":flag-rw:": {
+        "style": "github", 
+        "image": "1f1f7-1f1fc.png", 
+        "unicode": "🇷🇼", 
+        "name": "Rwanda"
+    }, 
+    ":left_fist_tone1:": {
+        "style": "github", 
+        "image": "1f91b-1f3fb.png", 
+        "unicode": "🤛🏻", 
+        "name": "Left Facing Fist - Tone 1"
+    }, 
+    ":zap:": {
+        "style": "github", 
+        "image": "26a1.png", 
+        "unicode": "⚡", 
+        "name": "High Voltage Sign"
+    }, 
+    ":'-(": {
+        "style": "ascii", 
+        "ascii": ":'(", 
+        "image": "1f622.png", 
+        "unicode": "😢", 
+        "name": "Crying Face"
+    }, 
+    ":flag-in:": {
+        "style": "github", 
+        "image": "1f1ee-1f1f3.png", 
+        "unicode": "🇮🇳", 
+        "name": "India"
+    }, 
+    "🛐": {
+        "style": "unicode", 
+        "image": "1f6d0.png", 
+        "name": "Place Of Worship"
+    }, 
+    ":house_abandoned:": {
+        "style": "github", 
+        "image": "1f3da.png", 
+        "unicode": "🏚", 
+        "name": "Derelict House Building"
+    }, 
+    ":crab:": {
+        "style": "github", 
+        "image": "1f980.png", 
+        "unicode": "🦀", 
+        "name": "Crab"
+    }, 
+    ":clap-tone2:": {
+        "style": "github", 
+        "image": "1f44f-1f3fc.png", 
+        "unicode": "👏🏼", 
+        "name": "Clapping Hands Sign - Tone 2"
+    }, 
+    "🍩": {
+        "style": "unicode", 
+        "image": "1f369.png", 
+        "name": "Doughnut"
+    }, 
+    ":lifter_tone5:": {
+        "style": "github", 
+        "image": "1f3cb-1f3ff.png", 
+        "unicode": "🏋🏿", 
+        "name": "Weight Lifter - Tone 5"
+    }, 
+    ":dancer_tone4:": {
+        "style": "github", 
+        "image": "1f483-1f3fe.png", 
+        "unicode": "💃🏾", 
+        "name": "Dancer - Tone 4"
+    }, 
+    ":flag_mv:": {
+        "style": "github", 
+        "image": "1f1f2-1f1fb.png", 
+        "unicode": "🇲🇻", 
+        "name": "Maldives"
+    }, 
+    ":hand-splayed:": {
+        "style": "github", 
+        "image": "1f590.png", 
+        "unicode": "🖐", 
+        "name": "Raised Hand With Fingers Splayed"
+    }, 
+    ":left-luggage:": {
+        "style": "github", 
+        "image": "1f6c5.png", 
+        "unicode": "🛅", 
+        "name": "Left Luggage"
+    }, 
+    "🏾": {
+        "style": "unicode", 
+        "image": "1f3fe.png", 
+        "name": "Emoji Modifier Fitzpatrick Type-5"
+    }, 
+    ":bath_tone1:": {
+        "style": "github", 
+        "image": "1f6c0-1f3fb.png", 
+        "unicode": "🛀🏻", 
+        "name": "Bath - Tone 1"
+    }, 
+    ":flag_bs:": {
+        "style": "github", 
+        "image": "1f1e7-1f1f8.png", 
+        "unicode": "🇧🇸", 
+        "name": "The Bahamas"
+    }, 
+    "🦏": {
+        "style": "unicode", 
+        "image": "1f98f.png", 
+        "name": "Rhinoceros"
+    }, 
+    "🎓": {
+        "style": "unicode", 
+        "image": "1f393.png", 
+        "name": "Graduation Cap"
+    }, 
+    ":construction_site:": {
+        "style": "github", 
+        "image": "1f3d7.png", 
+        "unicode": "🏗", 
+        "name": "Building Construction"
+    }, 
+    "🤤": {
+        "style": "unicode", 
+        "image": "1f924.png", 
+        "name": "Drooling Face"
+    }, 
+    "🌨": {
+        "style": "unicode", 
+        "image": "1f328.png", 
+        "name": "Cloud With Snow"
+    }, 
+    "💽": {
+        "style": "unicode", 
+        "image": "1f4bd.png", 
+        "name": "Minidisc"
+    }, 
+    ":dragon-face:": {
+        "style": "github", 
+        "image": "1f432.png", 
+        "unicode": "🐲", 
+        "name": "Dragon Face"
+    }, 
+    ":gg:": {
+        "style": "github", 
+        "image": "1f1ec-1f1ec.png", 
+        "unicode": "🇬🇬", 
+        "name": "Guernsey"
+    }, 
+    ":atm:": {
+        "style": "github", 
+        "image": "1f3e7.png", 
+        "unicode": "🏧", 
+        "name": "Automated Teller Machine"
+    }, 
+    ":ok_hand_tone5:": {
+        "style": "github", 
+        "image": "1f44c-1f3ff.png", 
+        "unicode": "👌🏿", 
+        "name": "Ok Hand Sign - Tone 5"
+    }, 
+    ":ss:": {
+        "style": "github", 
+        "image": "1f1f8-1f1f8.png", 
+        "unicode": "🇸🇸", 
+        "name": "South Sudan"
+    }, 
+    "👒": {
+        "style": "unicode", 
+        "image": "1f452.png", 
+        "name": "Womans Hat"
+    }, 
+    ":elephant:": {
+        "style": "github", 
+        "image": "1f418.png", 
+        "unicode": "🐘", 
+        "name": "Elephant"
+    }, 
+    ":clock1230:": {
+        "style": "github", 
+        "image": "1f567.png", 
+        "unicode": "🕧", 
+        "name": "Clock Face Twelve-thirty"
+    }, 
+    ":hugging:": {
+        "style": "github", 
+        "image": "1f917.png", 
+        "unicode": "🤗", 
+        "name": "Hugging Face"
+    }, 
+    ":map:": {
+        "style": "github", 
+        "image": "1f5fa.png", 
+        "unicode": "🗺", 
+        "name": "World Map"
+    }, 
+    ":no-pedestrians:": {
+        "style": "github", 
+        "image": "1f6b7.png", 
+        "unicode": "🚷", 
+        "name": "No Pedestrians"
+    }, 
+    ":octagonal_sign:": {
+        "style": "github", 
+        "image": "1f6d1.png", 
+        "unicode": "🛑", 
+        "name": "Octagonal Sign"
+    }, 
+    ":raised-hand-tone2:": {
+        "style": "github", 
+        "image": "270b-1f3fc.png", 
+        "unicode": "✋🏼", 
+        "name": "Raised Hand - Tone 2"
+    }, 
+    ":bath-tone4:": {
+        "style": "github", 
+        "image": "1f6c0-1f3fe.png", 
+        "unicode": "🛀🏾", 
+        "name": "Bath - Tone 4"
+    }, 
+    "😑": {
+        "style": "unicode", 
+        "ascii": "-_-", 
+        "image": "1f611.png", 
+        "name": "Expressionless Face"
+    }, 
+    ":bride_with_veil_tone1:": {
+        "style": "github", 
+        "image": "1f470-1f3fb.png", 
+        "unicode": "👰🏻", 
+        "name": "Bride With Veil - Tone 1"
+    }, 
+    ":negative-squared-cross-mark:": {
+        "style": "github", 
+        "image": "274e.png", 
+        "unicode": "❎", 
+        "name": "Negative Squared Cross Mark"
+    }, 
+    ":male_dancer_tone1:": {
+        "style": "github", 
+        "image": "1f57a-1f3fb.png", 
+        "unicode": "🕺🏻", 
+        "name": "Man Dancing - Tone 1"
+    }, 
+    ":cop_tone4:": {
+        "style": "github", 
+        "image": "1f46e-1f3fe.png", 
+        "unicode": "👮🏾", 
+        "name": "Police Officer - Tone 4"
+    }, 
+    ":two_hearts:": {
+        "style": "github", 
+        "image": "1f495.png", 
+        "unicode": "💕", 
+        "name": "Two Hearts"
+    }, 
+    ":motorbike:": {
+        "style": "github", 
+        "image": "1f6f5.png", 
+        "unicode": "🛵", 
+        "name": "Motor Scooter"
+    }, 
+    "🚦": {
+        "style": "unicode", 
+        "image": "1f6a6.png", 
+        "name": "Vertical Traffic Light"
+    }, 
+    ":turtle:": {
+        "style": "github", 
+        "image": "1f422.png", 
+        "unicode": "🐢", 
+        "name": "Turtle"
+    }, 
+    ":rainbow:": {
+        "style": "github", 
+        "image": "1f308.png", 
+        "unicode": "🌈", 
+        "name": "Rainbow"
+    }, 
+    ":skull-crossbones:": {
+        "style": "github", 
+        "image": "2620.png", 
+        "unicode": "☠", 
+        "name": "Skull And Crossbones"
+    }, 
+    ":white_sun_behind_cloud:": {
+        "style": "github", 
+        "image": "1f325.png", 
+        "unicode": "🌥", 
+        "name": "White Sun Behind Cloud"
+    }, 
+    "👇🏿": {
+        "style": "unicode", 
+        "image": "1f447-1f3ff.png", 
+        "name": "White Down Pointing Backhand Index - Tone 5"
+    }, 
+    "👇🏾": {
+        "style": "unicode", 
+        "image": "1f447-1f3fe.png", 
+        "name": "White Down Pointing Backhand Index - Tone 4"
+    }, 
+    "👇🏽": {
+        "style": "unicode", 
+        "image": "1f447-1f3fd.png", 
+        "name": "White Down Pointing Backhand Index - Tone 3"
+    }, 
+    "👇🏼": {
+        "style": "unicode", 
+        "image": "1f447-1f3fc.png", 
+        "name": "White Down Pointing Backhand Index - Tone 2"
+    }, 
+    "👇🏻": {
+        "style": "unicode", 
+        "image": "1f447-1f3fb.png", 
+        "name": "White Down Pointing Backhand Index - Tone 1"
+    }, 
+    "👰🏻": {
+        "style": "unicode", 
+        "image": "1f470-1f3fb.png", 
+        "name": "Bride With Veil - Tone 1"
+    }, 
+    "💃": {
+        "style": "unicode", 
+        "image": "1f483.png", 
+        "name": "Dancer"
+    }, 
+    ":heart:": {
+        "style": "github", 
+        "ascii": "<3", 
+        "image": "2764.png", 
+        "unicode": "❤", 
+        "name": "Heavy Black Heart"
+    }, 
+    "🐘": {
+        "style": "unicode", 
+        "image": "1f418.png", 
+        "name": "Elephant"
+    }, 
+    ":weary:": {
+        "style": "github", 
+        "image": "1f629.png", 
+        "unicode": "😩", 
+        "name": "Weary Face"
+    }, 
+    ":laughing:": {
+        "style": "github", 
+        "ascii": ">:)", 
+        "image": "1f606.png", 
+        "unicode": "😆", 
+        "name": "Smiling Face With Open Mouth And Tightly-closed Eyes"
+    }, 
+    ":flag_ec:": {
+        "style": "github", 
+        "image": "1f1ea-1f1e8.png", 
+        "unicode": "🇪🇨", 
+        "name": "Ecuador"
+    }, 
+    "🎭": {
+        "style": "unicode", 
+        "image": "1f3ad.png", 
+        "name": "Performing Arts"
+    }, 
+    ":mushroom:": {
+        "style": "github", 
+        "image": "1f344.png", 
+        "unicode": "🍄", 
+        "name": "Mushroom"
+    }, 
+    ":biohazard_sign:": {
+        "style": "github", 
+        "image": "2623.png", 
+        "unicode": "☣", 
+        "name": "Biohazard Sign"
+    }, 
+    ":flag_fo:": {
+        "style": "github", 
+        "image": "1f1eb-1f1f4.png", 
+        "unicode": "🇫🇴", 
+        "name": "Faroe Islands"
+    }, 
+    ":flag_ly:": {
+        "style": "github", 
+        "image": "1f1f1-1f1fe.png", 
+        "unicode": "🇱🇾", 
+        "name": "Libya"
+    }, 
+    "🍂": {
+        "style": "unicode", 
+        "image": "1f342.png", 
+        "name": "Fallen Leaf"
+    }, 
+    ":mountain-cableway:": {
+        "style": "github", 
+        "image": "1f6a0.png", 
+        "unicode": "🚠", 
+        "name": "Mountain Cableway"
+    }, 
+    ":rowboat-tone5:": {
+        "style": "github", 
+        "image": "1f6a3-1f3ff.png", 
+        "unicode": "🚣🏿", 
+        "name": "Rowboat - Tone 5"
+    }, 
+    ":wrestlers_tone3:": {
+        "style": "github", 
+        "image": "1f93c-1f3fd.png", 
+        "unicode": "🤼🏽", 
+        "name": "Wrestlers - Tone 3"
+    }, 
+    ":rolling_on_the_floor_laughing:": {
+        "style": "github", 
+        "image": "1f923.png", 
+        "unicode": "🤣", 
+        "name": "Rolling On The Floor Laughing"
+    }, 
+    ":ramen:": {
+        "style": "github", 
+        "image": "1f35c.png", 
+        "unicode": "🍜", 
+        "name": "Steaming Bowl"
+    }, 
+    ":flag_no:": {
+        "style": "github", 
+        "image": "1f1f3-1f1f4.png", 
+        "unicode": "🇳🇴", 
+        "name": "Norway"
+    }, 
+    ":turkey:": {
+        "style": "github", 
+        "image": "1f983.png", 
+        "unicode": "🦃", 
+        "name": "Turkey"
+    }, 
+    ":flag_gy:": {
+        "style": "github", 
+        "image": "1f1ec-1f1fe.png", 
+        "unicode": "🇬🇾", 
+        "name": "Guyana"
+    }, 
+    ":haircut-tone3:": {
+        "style": "github", 
+        "image": "1f487-1f3fd.png", 
+        "unicode": "💇🏽", 
+        "name": "Haircut - Tone 3"
+    }, 
+    ":am:": {
+        "style": "github", 
+        "image": "1f1e6-1f1f2.png", 
+        "unicode": "🇦🇲", 
+        "name": "Armenia"
+    }, 
+    "☔": {
+        "style": "unicode", 
+        "image": "2614.png", 
+        "name": "Umbrella With Rain Drops"
+    }, 
+    ":pr:": {
+        "style": "github", 
+        "image": "1f1f5-1f1f7.png", 
+        "unicode": "🇵🇷", 
+        "name": "Puerto Rico"
+    }, 
+    ":mother_christmas_tone5:": {
+        "style": "github", 
+        "image": "1f936-1f3ff.png", 
+        "unicode": "🤶🏿", 
+        "name": "Mother Christmas - Tone 5"
+    }, 
+    "🆖": {
+        "style": "unicode", 
+        "image": "1f196.png", 
+        "name": "Squared Ng"
+    }, 
+    ":smoking:": {
+        "style": "github", 
+        "image": "1f6ac.png", 
+        "unicode": "🚬", 
+        "name": "Smoking Symbol"
+    }, 
+    "😯": {
+        "style": "unicode", 
+        "image": "1f62f.png", 
+        "name": "Hushed Face"
+    }, 
+    "🚟": {
+        "style": "unicode", 
+        "image": "1f69f.png", 
+        "name": "Suspension Railway"
+    }, 
+    ":person-with-blond-hair-tone5:": {
+        "style": "github", 
+        "image": "1f471-1f3ff.png", 
+        "unicode": "👱🏿", 
+        "name": "Person With Blond Hair - Tone 5"
+    }, 
+    "👨🏻": {
+        "style": "unicode", 
+        "image": "1f468-1f3fb.png", 
+        "name": "Man - Tone 1"
+    }, 
+    ":writing_hand:": {
+        "style": "github", 
+        "image": "270d.png", 
+        "unicode": "✍", 
+        "name": "Writing Hand"
+    }, 
+    "👨🏾": {
+        "style": "unicode", 
+        "image": "1f468-1f3fe.png", 
+        "name": "Man - Tone 4"
+    }, 
+    "👨🏿": {
+        "style": "unicode", 
+        "image": "1f468-1f3ff.png", 
+        "name": "Man - Tone 5"
+    }, 
+    "👨🏼": {
+        "style": "unicode", 
+        "image": "1f468-1f3fc.png", 
+        "name": "Man - Tone 2"
+    }, 
+    "👨🏽": {
+        "style": "unicode", 
+        "image": "1f468-1f3fd.png", 
+        "name": "Man - Tone 3"
+    }, 
+    ":bicyclist-tone2:": {
+        "style": "github", 
+        "image": "1f6b4-1f3fc.png", 
+        "unicode": "🚴🏼", 
+        "name": "Bicyclist - Tone 2"
+    }, 
+    "🕙": {
+        "style": "unicode", 
+        "image": "1f559.png", 
+        "name": "Clock Face Ten Oclock"
+    }, 
+    ":raised_back_of_hand_tone4:": {
+        "style": "github", 
+        "image": "1f91a-1f3fe.png", 
+        "unicode": "🤚🏾", 
+        "name": "Raised Back Of Hand - Tone 4"
+    }, 
+    ":japanese_castle:": {
+        "style": "github", 
+        "image": "1f3ef.png", 
+        "unicode": "🏯", 
+        "name": "Japanese Castle"
+    }, 
+    ":pensive:": {
+        "style": "github", 
+        "image": "1f614.png", 
+        "unicode": "😔", 
+        "name": "Pensive Face"
+    }, 
+    ":raised_hand_with_fingers_splayed_tone2:": {
+        "style": "github", 
+        "image": "1f590-1f3fc.png", 
+        "unicode": "🖐🏼", 
+        "name": "Raised Hand With Fingers Splayed - Tone 2"
+    }, 
+    ":point_up_2_tone2:": {
+        "style": "github", 
+        "image": "1f446-1f3fc.png", 
+        "unicode": "👆🏼", 
+        "name": "White Up Pointing Backhand Index - Tone 2"
+    }, 
+    ":round-pushpin:": {
+        "style": "github", 
+        "image": "1f4cd.png", 
+        "unicode": "📍", 
+        "name": "Round Pushpin"
+    }, 
+    ":nose-tone4:": {
+        "style": "github", 
+        "image": "1f443-1f3fe.png", 
+        "unicode": "👃🏾", 
+        "name": "Nose - Tone 4"
+    }, 
+    ":capital_abcd:": {
+        "style": "github", 
+        "image": "1f520.png", 
+        "unicode": "🔠", 
+        "name": "Input Symbol For Latin Capital Letters"
+    }, 
+    ":raised_hands:": {
+        "style": "github", 
+        "image": "1f64c.png", 
+        "unicode": "🙌", 
+        "name": "Person Raising Both Hands In Celebration"
+    }, 
+    "🔘": {
+        "style": "unicode", 
+        "image": "1f518.png", 
+        "name": "Radio Button"
+    }, 
+    ":house_buildings:": {
+        "style": "github", 
+        "image": "1f3d8.png", 
+        "unicode": "🏘", 
+        "name": "House Buildings"
+    }, 
+    ":flag_il:": {
+        "style": "github", 
+        "image": "1f1ee-1f1f1.png", 
+        "unicode": "🇮🇱", 
+        "name": "Israel"
+    }, 
+    ":raised_hand:": {
+        "style": "github", 
+        "image": "270b.png", 
+        "unicode": "✋", 
+        "name": "Raised Hand"
+    }, 
+    ":raised_hand_tone3:": {
+        "style": "github", 
+        "image": "270b-1f3fd.png", 
+        "unicode": "✋🏽", 
+        "name": "Raised Hand - Tone 3"
+    }, 
+    ":raised_hand_with_part_between_middle_and_ring_fingers_tone3:": {
+        "style": "github", 
+        "image": "1f596-1f3fd.png", 
+        "unicode": "🖖🏽", 
+        "name": "Raised Hand With Part Between Middle And Ring Fingers - Tone 3"
+    }, 
+    ":no_smoking:": {
+        "style": "github", 
+        "image": "1f6ad.png", 
+        "unicode": "🚭", 
+        "name": "No Smoking Symbol"
+    }, 
+    "🏗": {
+        "style": "unicode", 
+        "image": "1f3d7.png", 
+        "name": "Building Construction"
+    }, 
+    ":nu:": {
+        "style": "github", 
+        "image": "1f1f3-1f1fa.png", 
+        "unicode": "🇳🇺", 
+        "name": "Niue"
+    }, 
+    ":muscle_tone3:": {
+        "style": "github", 
+        "image": "1f4aa-1f3fd.png", 
+        "unicode": "💪🏽", 
+        "name": "Flexed Biceps - Tone 3"
+    }, 
+    ":ledger:": {
+        "style": "github", 
+        "image": "1f4d2.png", 
+        "unicode": "📒", 
+        "name": "Ledger"
+    }, 
+    "🍬": {
+        "style": "unicode", 
+        "image": "1f36c.png", 
+        "name": "Candy"
+    }, 
+    ":prince_tone2:": {
+        "style": "github", 
+        "image": "1f934-1f3fc.png", 
+        "unicode": "🤴🏼", 
+        "name": "Prince - Tone 2"
+    }, 
+    ":man-with-gua-pi-mao-tone5:": {
+        "style": "github", 
+        "image": "1f472-1f3ff.png", 
+        "unicode": "👲🏿", 
+        "name": "Man With Gua Pi Mao - Tone 5"
+    }, 
+    ":haircut:": {
+        "style": "github", 
+        "image": "1f487.png", 
+        "unicode": "💇", 
+        "name": "Haircut"
+    }, 
+    ":green_book:": {
+        "style": "github", 
+        "image": "1f4d7.png", 
+        "unicode": "📗", 
+        "name": "Green Book"
+    }, 
+    "😅": {
+        "style": "unicode", 
+        "ascii": "':)", 
+        "image": "1f605.png", 
+        "name": "Smiling Face With Open Mouth And Cold Sweat"
+    }, 
+    "✏": {
+        "style": "unicode", 
+        "image": "270f.png", 
+        "name": "Pencil"
+    }, 
+    ":flag-ky:": {
+        "style": "github", 
+        "image": "1f1f0-1f1fe.png", 
+        "unicode": "🇰🇾", 
+        "name": "Cayman Islands"
+    }, 
+    "🚚": {
+        "style": "unicode", 
+        "image": "1f69a.png", 
+        "name": "Delivery Truck"
+    }, 
+    ":bow_tone4:": {
+        "style": "github", 
+        "image": "1f647-1f3fe.png", 
+        "unicode": "🙇🏾", 
+        "name": "Person Bowing Deeply - Tone 4"
+    }, 
+    "0;^)": {
+        "style": "ascii", 
+        "ascii": "O:-)", 
+        "image": "1f607.png", 
+        "unicode": "😇", 
+        "name": "Smiling Face With Halo"
+    }, 
+    ":bus:": {
+        "style": "github", 
+        "image": "1f68c.png", 
+        "unicode": "🚌", 
+        "name": "Bus"
+    }, 
+    "👙": {
+        "style": "unicode", 
+        "image": "1f459.png", 
+        "name": "Bikini"
+    }, 
+    ":flag-cy:": {
+        "style": "github", 
+        "image": "1f1e8-1f1fe.png", 
+        "unicode": "🇨🇾", 
+        "name": "Cyprus"
+    }, 
+    ":church:": {
+        "style": "github", 
+        "image": "26ea.png", 
+        "unicode": "⛪", 
+        "name": "Church"
+    }, 
+    ":family_wwgb:": {
+        "style": "github", 
+        "image": "1f469-1f469-1f467-1f466.png", 
+        "unicode": "👩👩👧👦", 
+        "name": "Family (woman,woman,girl,boy)"
+    }, 
+    "🇯🇪": {
+        "style": "unicode", 
+        "image": "1f1ef-1f1ea.png", 
+        "name": "Jersey"
+    }, 
+    ":wind-blowing-face:": {
+        "style": "github", 
+        "image": "1f32c.png", 
+        "unicode": "🌬", 
+        "name": "Wind Blowing Face"
+    }, 
+    ":person_with_blond_hair_tone3:": {
+        "style": "github", 
+        "image": "1f471-1f3fd.png", 
+        "unicode": "👱🏽", 
+        "name": "Person With Blond Hair - Tone 3"
+    }, 
+    "📮": {
+        "style": "unicode", 
+        "image": "1f4ee.png", 
+        "name": "Postbox"
+    }, 
+    ":flag-sz:": {
+        "style": "github", 
+        "image": "1f1f8-1f1ff.png", 
+        "unicode": "🇸🇿", 
+        "name": "Swaziland"
+    }, 
+    "🇯🇵": {
+        "style": "unicode", 
+        "image": "1f1ef-1f1f5.png", 
+        "name": "Japan"
+    }, 
+    "🇯🇴": {
+        "style": "unicode", 
+        "image": "1f1ef-1f1f4.png", 
+        "name": "Jordan"
+    }, 
+    "🇯🇲": {
+        "style": "unicode", 
+        "image": "1f1ef-1f1f2.png", 
+        "name": "Jamaica"
+    }, 
+    ":flag-as:": {
+        "style": "github", 
+        "image": "1f1e6-1f1f8.png", 
+        "unicode": "🇦🇸", 
+        "name": "American Samoa"
+    }, 
+    "🚃": {
+        "style": "unicode", 
+        "image": "1f683.png", 
+        "name": "Railway Car"
+    }, 
+    ":flag-je:": {
+        "style": "github", 
+        "image": "1f1ef-1f1ea.png", 
+        "unicode": "🇯🇪", 
+        "name": "Jersey"
+    }, 
+    ":light-rail:": {
+        "style": "github", 
+        "image": "1f688.png", 
+        "unicode": "🚈", 
+        "name": "Light Rail"
+    }, 
+    ":flag-dg:": {
+        "style": "github", 
+        "image": "1f1e9-1f1ec.png", 
+        "unicode": "🇩🇬", 
+        "name": "Diego Garcia"
+    }, 
+    ":punch_tone3:": {
+        "style": "github", 
+        "image": "1f44a-1f3fd.png", 
+        "unicode": "👊🏽", 
+        "name": "Fisted Hand Sign - Tone 3"
+    }, 
+    "😘": {
+        "style": "unicode", 
+        "ascii": ":*", 
+        "image": "1f618.png", 
+        "name": "Face Throwing A Kiss"
+    }, 
+    ":flag_bn:": {
+        "style": "github", 
+        "image": "1f1e7-1f1f3.png", 
+        "unicode": "🇧🇳", 
+        "name": "Brunei"
+    }, 
+    "™": {
+        "style": "unicode", 
+        "image": "2122.png", 
+        "name": "Trade Mark Sign"
+    }, 
+    ":table_tennis:": {
+        "style": "github", 
+        "image": "1f3d3.png", 
+        "unicode": "🏓", 
+        "name": "Table Tennis Paddle And Ball"
+    }, 
+    ":anger-right:": {
+        "style": "github", 
+        "image": "1f5ef.png", 
+        "unicode": "🗯", 
+        "name": "Right Anger Bubble"
+    }, 
+    ":regional-indicator-n:": {
+        "style": "github", 
+        "image": "1f1f3.png", 
+        "unicode": "🇳", 
+        "name": "Regional Indicator Symbol Letter N"
+    }, 
+    ":right_facing_fist_tone1:": {
+        "style": "github", 
+        "image": "1f91c-1f3fb.png", 
+        "unicode": "🤜🏻", 
+        "name": "Right Facing Fist - Tone 1"
+    }, 
+    ":ballot_box_with_check:": {
+        "style": "github", 
+        "image": "2611.png", 
+        "unicode": "☑", 
+        "name": "Ballot Box With Check"
+    }, 
+    ":ticket:": {
+        "style": "github", 
+        "image": "1f3ab.png", 
+        "unicode": "🎫", 
+        "name": "Ticket"
+    }, 
+    ":thumbsup_tone1:": {
+        "style": "github", 
+        "image": "1f44d-1f3fb.png", 
+        "unicode": "👍🏻", 
+        "name": "Thumbs Up Sign - Tone 1"
+    }, 
+    "💪🏼": {
+        "style": "unicode", 
+        "image": "1f4aa-1f3fc.png", 
+        "name": "Flexed Biceps - Tone 2"
+    }, 
+    "💪🏽": {
+        "style": "unicode", 
+        "image": "1f4aa-1f3fd.png", 
+        "name": "Flexed Biceps - Tone 3"
+    }, 
+    "💪🏾": {
+        "style": "unicode", 
+        "image": "1f4aa-1f3fe.png", 
+        "name": "Flexed Biceps - Tone 4"
+    }, 
+    "💪🏿": {
+        "style": "unicode", 
+        "image": "1f4aa-1f3ff.png", 
+        "name": "Flexed Biceps - Tone 5"
+    }, 
+    "🔅": {
+        "style": "unicode", 
+        "image": "1f505.png", 
+        "name": "Low Brightness Symbol"
+    }, 
+    "💪🏻": {
+        "style": "unicode", 
+        "image": "1f4aa-1f3fb.png", 
+        "name": "Flexed Biceps - Tone 1"
+    }, 
+    ":santa:": {
+        "style": "github", 
+        "image": "1f385.png", 
+        "unicode": "🎅", 
+        "name": "Father Christmas"
+    }, 
+    ":two-women-holding-hands:": {
+        "style": "github", 
+        "image": "1f46d.png", 
+        "unicode": "👭", 
+        "name": "Two Women Holding Hands"
+    }, 
+    "🎖": {
+        "style": "unicode", 
+        "image": "1f396.png", 
+        "name": "Military Medal"
+    }, 
+    ":ok-hand-tone2:": {
+        "style": "github", 
+        "image": "1f44c-1f3fc.png", 
+        "unicode": "👌🏼", 
+        "name": "Ok Hand Sign - Tone 2"
+    }, 
+    ":flag-wf:": {
+        "style": "github", 
+        "image": "1f1fc-1f1eb.png", 
+        "unicode": "🇼🇫", 
+        "name": "Wallis And Futuna"
+    }, 
+    ":railway-car:": {
+        "style": "github", 
+        "image": "1f683.png", 
+        "unicode": "🚃", 
+        "name": "Railway Car"
+    }, 
+    "🐯": {
+        "style": "unicode", 
+        "image": "1f42f.png", 
+        "name": "Tiger Face"
+    }, 
+    ":clock6:": {
+        "style": "github", 
+        "image": "1f555.png", 
+        "unicode": "🕕", 
+        "name": "Clock Face Six Oclock"
+    }, 
+    "📄": {
+        "style": "unicode", 
+        "image": "1f4c4.png", 
+        "name": "Page Facing Up"
+    }, 
+    ":herb:": {
+        "style": "github", 
+        "image": "1f33f.png", 
+        "unicode": "🌿", 
+        "name": "Herb"
+    }, 
+    ":hot_pepper:": {
+        "style": "github", 
+        "image": "1f336.png", 
+        "unicode": "🌶", 
+        "name": "Hot Pepper"
+    }, 
+    ":ml:": {
+        "style": "github", 
+        "image": "1f1f2-1f1f1.png", 
+        "unicode": "🇲🇱", 
+        "name": "Mali"
+    }, 
+    "🥝": {
+        "style": "unicode", 
+        "image": "1f95d.png", 
+        "name": "Kiwifruit"
+    }, 
+    "♣": {
+        "style": "unicode", 
+        "image": "2663.png", 
+        "name": "Black Club Suit"
+    }, 
+    ":inbox-tray:": {
+        "style": "github", 
+        "image": "1f4e5.png", 
+        "unicode": "📥", 
+        "name": "Inbox Tray"
+    }, 
+    "⛸": {
+        "style": "unicode", 
+        "image": "26f8.png", 
+        "name": "Ice Skate"
+    }, 
+    "7⃣": {
+        "style": "unicode", 
+        "image": "0037-20e3.png", 
+        "name": "Keycap Digit Seven"
+    }, 
+    "🦇": {
+        "style": "unicode", 
+        "image": "1f987.png", 
+        "name": "Bat"
+    }, 
+    ":bv:": {
+        "style": "github", 
+        "image": "1f1e7-1f1fb.png", 
+        "unicode": "🇧🇻", 
+        "name": "Bouvet Island"
+    }, 
+    ":call_me_tone3:": {
+        "style": "github", 
+        "image": "1f919-1f3fd.png", 
+        "unicode": "🤙🏽", 
+        "name": "Call Me Hand - Tone 3"
+    }, 
+    "🤜": {
+        "style": "unicode", 
+        "image": "1f91c.png", 
+        "name": "Right-facing Fist"
+    }, 
+    ":flag_ug:": {
+        "style": "github", 
+        "image": "1f1fa-1f1ec.png", 
+        "unicode": "🇺🇬", 
+        "name": "Uganda"
+    }, 
+    ":hu:": {
+        "style": "github", 
+        "image": "1f1ed-1f1fa.png", 
+        "unicode": "🇭🇺", 
+        "name": "Hungary"
+    }, 
+    "X)": {
+        "style": "ascii", 
+        "ascii": "#-)", 
+        "image": "1f635.png", 
+        "unicode": "😵", 
+        "name": "Dizzy Face"
+    }, 
+    ":surfer:": {
+        "style": "github", 
+        "image": "1f3c4.png", 
+        "unicode": "🏄", 
+        "name": "Surfer"
+    }, 
+    ":flag-ni:": {
+        "style": "github", 
+        "image": "1f1f3-1f1ee.png", 
+        "unicode": "🇳🇮", 
+        "name": "Nicaragua"
+    }, 
+    ":mount_fuji:": {
+        "style": "github", 
+        "image": "1f5fb.png", 
+        "unicode": "🗻", 
+        "name": "Mount Fuji"
+    }, 
+    ":flag-ru:": {
+        "style": "github", 
+        "image": "1f1f7-1f1fa.png", 
+        "unicode": "🇷🇺", 
+        "name": "Russia"
+    }, 
+    ":flower-playing-cards:": {
+        "style": "github", 
+        "image": "1f3b4.png", 
+        "unicode": "🎴", 
+        "name": "Flower Playing Cards"
+    }, 
+    "⭐": {
+        "style": "unicode", 
+        "image": "2b50.png", 
+        "name": "White Medium Star"
+    }, 
+    ":round_pushpin:": {
+        "style": "github", 
+        "image": "1f4cd.png", 
+        "unicode": "📍", 
+        "name": "Round Pushpin"
+    }, 
+    "👷🏿": {
+        "style": "unicode", 
+        "image": "1f477-1f3ff.png", 
+        "name": "Construction Worker - Tone 5"
+    }, 
+    "👷🏾": {
+        "style": "unicode", 
+        "image": "1f477-1f3fe.png", 
+        "name": "Construction Worker - Tone 4"
+    }, 
+    "👷🏽": {
+        "style": "unicode", 
+        "image": "1f477-1f3fd.png", 
+        "name": "Construction Worker - Tone 3"
+    }, 
+    "👷🏼": {
+        "style": "unicode", 
+        "image": "1f477-1f3fc.png", 
+        "name": "Construction Worker - Tone 2"
+    }, 
+    "👷🏻": {
+        "style": "unicode", 
+        "image": "1f477-1f3fb.png", 
+        "name": "Construction Worker - Tone 1"
+    }, 
+    ":ru:": {
+        "style": "github", 
+        "image": "1f1f7-1f1fa.png", 
+        "unicode": "🇷🇺", 
+        "name": "Russia"
+    }, 
+    ":drooling_face:": {
+        "style": "github", 
+        "image": "1f924.png", 
+        "unicode": "🤤", 
+        "name": "Drooling Face"
+    }, 
+    ":flag-ps:": {
+        "style": "github", 
+        "image": "1f1f5-1f1f8.png", 
+        "unicode": "🇵🇸", 
+        "name": "Palestinian Authority"
+    }, 
+    "🍉": {
+        "style": "unicode", 
+        "image": "1f349.png", 
+        "name": "Watermelon"
+    }, 
+    ":flag_mx:": {
+        "style": "github", 
+        "image": "1f1f2-1f1fd.png", 
+        "unicode": "🇲🇽", 
+        "name": "Mexico"
+    }, 
+    "🈁": {
+        "style": "unicode", 
+        "image": "1f201.png", 
+        "name": "Squared Katakana Koko"
+    }, 
+    "🇾🇹": {
+        "style": "unicode", 
+        "image": "1f1fe-1f1f9.png", 
+        "name": "Mayotte"
+    }, 
+    "🐅": {
+        "style": "unicode", 
+        "image": "1f405.png", 
+        "name": "Tiger"
+    }, 
+    ":bath_tone3:": {
+        "style": "github", 
+        "image": "1f6c0-1f3fd.png", 
+        "unicode": "🛀🏽", 
+        "name": "Bath - Tone 3"
+    }, 
+    ":record-button:": {
+        "style": "github", 
+        "image": "23fa.png", 
+        "unicode": "⏺", 
+        "name": "Black Circle For Record"
+    }, 
+    "🇾🇪": {
+        "style": "unicode", 
+        "image": "1f1fe-1f1ea.png", 
+        "name": "Yemen"
+    }, 
+    ":older-woman-tone4:": {
+        "style": "github", 
+        "image": "1f475-1f3fe.png", 
+        "unicode": "👵🏾", 
+        "name": "Older Woman - Tone 4"
+    }, 
+    "💚": {
+        "style": "unicode", 
+        "image": "1f49a.png", 
+        "name": "Green Heart"
+    }, 
+    ":hot-pepper:": {
+        "style": "github", 
+        "image": "1f336.png", 
+        "unicode": "🌶", 
+        "name": "Hot Pepper"
+    }, 
+    "🌫": {
+        "style": "unicode", 
+        "image": "1f32b.png", 
+        "name": "Fog"
+    }, 
+    "🔯": {
+        "style": "unicode", 
+        "image": "1f52f.png", 
+        "name": "Six Pointed Star With Middle Dot"
+    }, 
+    ":flag-il:": {
+        "style": "github", 
+        "image": "1f1ee-1f1f1.png", 
+        "unicode": "🇮🇱", 
+        "name": "Israel"
+    }, 
+    ":apple:": {
+        "style": "github", 
+        "image": "1f34e.png", 
+        "unicode": "🍎", 
+        "name": "Red Apple"
+    }, 
+    "☹": {
+        "style": "unicode", 
+        "image": "2639.png", 
+        "name": "White Frowning Face"
+    }, 
+    ":rat:": {
+        "style": "github", 
+        "image": "1f400.png", 
+        "unicode": "🐀", 
+        "name": "Rat"
+    }, 
+    "🏀": {
+        "style": "unicode", 
+        "image": "1f3c0.png", 
+        "name": "Basketball And Hoop"
+    }, 
+    ":ge:": {
+        "style": "github", 
+        "image": "1f1ec-1f1ea.png", 
+        "unicode": "🇬🇪", 
+        "name": "Georgia"
+    }, 
+    "🗄": {
+        "style": "unicode", 
+        "image": "1f5c4.png", 
+        "name": "File Cabinet"
+    }, 
+    "⛎": {
+        "style": "unicode", 
+        "image": "26ce.png", 
+        "name": "Ophiuchus"
+    }, 
+    ":shopping_trolley:": {
+        "style": "github", 
+        "image": "1f6d2.png", 
+        "unicode": "🛒", 
+        "name": "Shopping Trolley"
+    }, 
+    "❣": {
+        "style": "unicode", 
+        "image": "2763.png", 
+        "name": "Heavy Heart Exclamation Mark Ornament"
+    }, 
+    ":flag-vi:": {
+        "style": "github", 
+        "image": "1f1fb-1f1ee.png", 
+        "unicode": "🇻🇮", 
+        "name": "U.s. Virgin Islands"
+    }, 
+    ":desert_island:": {
+        "style": "github", 
+        "image": "1f3dd.png", 
+        "unicode": "🏝", 
+        "name": "Desert Island"
+    }, 
+    ":handball_tone5:": {
+        "style": "github", 
+        "image": "1f93e-1f3ff.png", 
+        "unicode": "🤾🏿", 
+        "name": "Handball - Tone 5"
+    }, 
+    ":palm-tree:": {
+        "style": "github", 
+        "image": "1f334.png", 
+        "unicode": "🌴", 
+        "name": "Palm Tree"
+    }, 
+    ":ok_woman:": {
+        "style": "github", 
+        "ascii": "*\\0/*", 
+        "image": "1f646.png", 
+        "unicode": "🙆", 
+        "name": "Face With Ok Gesture"
+    }, 
+    ":track_previous:": {
+        "style": "github", 
+        "image": "23ee.png", 
+        "unicode": "⏮", 
+        "name": "Black Left-pointing Double Triangle With Vertical Bar"
+    }, 
+    "🚶🏾": {
+        "style": "unicode", 
+        "image": "1f6b6-1f3fe.png", 
+        "name": "Pedestrian - Tone 4"
+    }, 
+    ":flag_jm:": {
+        "style": "github", 
+        "image": "1f1ef-1f1f2.png", 
+        "unicode": "🇯🇲", 
+        "name": "Jamaica"
+    }, 
+    ":regional_indicator_m:": {
+        "style": "github", 
+        "image": "1f1f2.png", 
+        "unicode": "🇲", 
+        "name": "Regional Indicator Symbol Letter M"
+    }, 
+    "♌": {
+        "style": "unicode", 
+        "image": "264c.png", 
+        "name": "Leo"
+    }, 
+    ":mountain_bicyclist_tone4:": {
+        "style": "github", 
+        "image": "1f6b5-1f3fe.png", 
+        "unicode": "🚵🏾", 
+        "name": "Mountain Bicyclist - Tone 4"
+    }, 
+    ":no-good-tone2:": {
+        "style": "github", 
+        "image": "1f645-1f3fc.png", 
+        "unicode": "🙅🏼", 
+        "name": "Face With No Good Gesture - Tone 2"
+    }, 
+    ":flag-mh:": {
+        "style": "github", 
+        "image": "1f1f2-1f1ed.png", 
+        "unicode": "🇲🇭", 
+        "name": "The Marshall Islands"
+    }, 
+    ":flag-gb:": {
+        "style": "github", 
+        "image": "1f1ec-1f1e7.png", 
+        "unicode": "🇬🇧", 
+        "name": "Great Britain"
+    }, 
+    ":point-right-tone3:": {
+        "style": "github", 
+        "image": "1f449-1f3fd.png", 
+        "unicode": "👉🏽", 
+        "name": "White Right Pointing Backhand Index - Tone 3"
+    }, 
+    ":cactus:": {
+        "style": "github", 
+        "image": "1f335.png", 
+        "unicode": "🌵", 
+        "name": "Cactus"
+    }, 
+    ":male_dancer_tone3:": {
+        "style": "github", 
+        "image": "1f57a-1f3fd.png", 
+        "unicode": "🕺🏽", 
+        "name": "Man Dancing - Tone 3"
+    }, 
+    ":cry:": {
+        "style": "github", 
+        "ascii": ":'(", 
+        "image": "1f622.png", 
+        "unicode": "😢", 
+        "name": "Crying Face"
+    }, 
+    ":bride_with_veil_tone3:": {
+        "style": "github", 
+        "image": "1f470-1f3fd.png", 
+        "unicode": "👰🏽", 
+        "name": "Bride With Veil - Tone 3"
+    }, 
+    ":wrestlers_tone2:": {
+        "style": "github", 
+        "image": "1f93c-1f3fc.png", 
+        "unicode": "🤼🏼", 
+        "name": "Wrestlers - Tone 2"
+    }, 
+    "🇸🇾": {
+        "style": "unicode", 
+        "image": "1f1f8-1f1fe.png", 
+        "name": "Syria"
+    }, 
+    ":tropical-drink:": {
+        "style": "github", 
+        "image": "1f379.png", 
+        "unicode": "🍹", 
+        "name": "Tropical Drink"
+    }, 
+    ":man_in_business_suit_levitating:": {
+        "style": "github", 
+        "image": "1f574.png", 
+        "unicode": "🕴", 
+        "name": "Man In Business Suit Levitating"
+    }, 
+    ":film-frames:": {
+        "style": "github", 
+        "image": "1f39e.png", 
+        "unicode": "🎞", 
+        "name": "Film Frames"
+    }, 
+    "🔁": {
+        "style": "unicode", 
+        "image": "1f501.png", 
+        "name": "Clockwise Rightwards And Leftwards Open Circle Arrows"
+    }, 
+    "🌅": {
+        "style": "unicode", 
+        "image": "1f305.png", 
+        "name": "Sunrise"
+    }, 
+    ":+1_tone5:": {
+        "style": "github", 
+        "image": "1f44d-1f3ff.png", 
+        "unicode": "👍🏿", 
+        "name": "Thumbs Up Sign - Tone 5"
+    }, 
+    "🖖": {
+        "style": "unicode", 
+        "image": "1f596.png", 
+        "name": "Raised Hand With Part Between Middle And Ring Fingers"
+    }, 
+    "🎚": {
+        "style": "unicode", 
+        "image": "1f39a.png", 
+        "name": "Level Slider"
+    }, 
+    ":flag_ee:": {
+        "style": "github", 
+        "image": "1f1ea-1f1ea.png", 
+        "unicode": "🇪🇪", 
+        "name": "Estonia"
+    }, 
+    ":notepad-spiral:": {
+        "style": "github", 
+        "image": "1f5d2.png", 
+        "unicode": "🗒", 
+        "name": "Spiral Note Pad"
+    }, 
+    "🐫": {
+        "style": "unicode", 
+        "image": "1f42b.png", 
+        "name": "Bactrian Camel"
+    }, 
+    ":point-up:": {
+        "style": "github", 
+        "image": "261d.png", 
+        "unicode": "☝", 
+        "name": "White Up Pointing Index"
+    }, 
+    "🈯": {
+        "style": "unicode", 
+        "image": "1f22f.png", 
+        "name": "Squared Cjk Unified Ideograph-6307"
+    }, 
+    "👩❤💋👩": {
+        "style": "unicode", 
+        "image": "1f469-2764-1f48b-1f469.png", 
+        "name": "Kiss (woman,woman)"
+    }, 
+    "ℹ": {
+        "style": "unicode", 
+        "image": "2139.png", 
+        "name": "Information Source"
+    }, 
+    "📀": {
+        "style": "unicode", 
+        "image": "1f4c0.png", 
+        "name": "Dvd"
+    }, 
+    ":flag_gw:": {
+        "style": "github", 
+        "image": "1f1ec-1f1fc.png", 
+        "unicode": "🇬🇼", 
+        "name": "Guinea-bissau"
+    }, 
+    ":flag_na:": {
+        "style": "github", 
+        "image": "1f1f3-1f1e6.png", 
+        "unicode": "🇳🇦", 
+        "name": "Namibia"
+    }, 
+    "🇮": {
+        "style": "unicode", 
+        "image": "1f1ee.png", 
+        "name": "Regional Indicator Symbol Letter I"
+    }, 
+    ":busts-in-silhouette:": {
+        "style": "github", 
+        "image": "1f465.png", 
+        "unicode": "👥", 
+        "name": "Busts In Silhouette"
+    }, 
+    ":ao:": {
+        "style": "github", 
+        "image": "1f1e6-1f1f4.png", 
+        "unicode": "🇦🇴", 
+        "name": "Angola"
+    }, 
+    ":couple:": {
+        "style": "github", 
+        "image": "1f46b.png", 
+        "unicode": "👫", 
+        "name": "Man And Woman Holding Hands"
+    }, 
+    ":point_up_2:": {
+        "style": "github", 
+        "image": "1f446.png", 
+        "unicode": "👆", 
+        "name": "White Up Pointing Backhand Index"
+    }, 
+    ":flag-dz:": {
+        "style": "github", 
+        "image": "1f1e9-1f1ff.png", 
+        "unicode": "🇩🇿", 
+        "name": "Algeria"
+    }, 
+    ":mrs_claus_tone2:": {
+        "style": "github", 
+        "image": "1f936-1f3fc.png", 
+        "unicode": "🤶🏼", 
+        "name": "Mother Christmas - Tone 2"
+    }, 
+    "☢": {
+        "style": "unicode", 
+        "image": "2622.png", 
+        "name": "Radioactive Sign"
+    }, 
+    ":wrestlers_tone1:": {
+        "style": "github", 
+        "image": "1f93c-1f3fb.png", 
+        "unicode": "🤼🏻", 
+        "name": "Wrestlers - Tone 1"
+    }, 
+    "🚭": {
+        "style": "unicode", 
+        "image": "1f6ad.png", 
+        "name": "No Smoking Symbol"
+    }, 
+    ":keycap-ten:": {
+        "style": "github", 
+        "image": "1f51f.png", 
+        "unicode": "🔟", 
+        "name": "Keycap Ten"
+    }, 
+    "🙂": {
+        "style": "unicode", 
+        "ascii": ":)", 
+        "image": "1f642.png", 
+        "name": "Slightly Smiling Face"
+    }, 
+    ":mrs-claus-tone5:": {
+        "style": "github", 
+        "image": "1f936-1f3ff.png", 
+        "unicode": "🤶🏿", 
+        "name": "Mother Christmas - Tone 5"
+    }, 
+    "❌": {
+        "style": "unicode", 
+        "image": "274c.png", 
+        "name": "Cross Mark"
+    }, 
+    ":regional-indicator-s:": {
+        "style": "github", 
+        "image": "1f1f8.png", 
+        "unicode": "🇸", 
+        "name": "Regional Indicator Symbol Letter S"
+    }, 
+    ":girl-tone5:": {
+        "style": "github", 
+        "image": "1f467-1f3ff.png", 
+        "unicode": "👧🏿", 
+        "name": "Girl - Tone 5"
+    }, 
+    ":yin_yang:": {
+        "style": "github", 
+        "image": "262f.png", 
+        "unicode": "☯", 
+        "name": "Yin Yang"
+    }, 
+    ":person_with_ball_tone2:": {
+        "style": "github", 
+        "image": "26f9-1f3fc.png", 
+        "unicode": "⛹🏼", 
+        "name": "Person With Ball - Tone 2"
+    }, 
+    ":sunflower:": {
+        "style": "github", 
+        "image": "1f33b.png", 
+        "unicode": "🌻", 
+        "name": "Sunflower"
+    }, 
+    ":wrestlers-tone4:": {
+        "style": "github", 
+        "image": "1f93c-1f3fe.png", 
+        "unicode": "🤼🏾", 
+        "name": "Wrestlers - Tone 4"
+    }, 
+    "🐁": {
+        "style": "unicode", 
+        "image": "1f401.png", 
+        "name": "Mouse"
+    }, 
+    ":flag-tz:": {
+        "style": "github", 
+        "image": "1f1f9-1f1ff.png", 
+        "unicode": "🇹🇿", 
+        "name": "Tanzania"
+    }, 
+    ":raised_hand_with_fingers_splayed_tone4:": {
+        "style": "github", 
+        "image": "1f590-1f3fe.png", 
+        "unicode": "🖐🏾", 
+        "name": "Raised Hand With Fingers Splayed - Tone 4"
+    }, 
+    ":regional_indicator_k:": {
+        "style": "github", 
+        "image": "1f1f0.png", 
+        "unicode": "🇰", 
+        "name": "Regional Indicator Symbol Letter K"
+    }, 
+    ":bowling:": {
+        "style": "github", 
+        "image": "1f3b3.png", 
+        "unicode": "🎳", 
+        "name": "Bowling"
+    }, 
+    ":mailbox_closed:": {
+        "style": "github", 
+        "image": "1f4ea.png", 
+        "unicode": "📪", 
+        "name": "Closed Mailbox With Lowered Flag"
+    }, 
+    "🔫": {
+        "style": "unicode", 
+        "image": "1f52b.png", 
+        "name": "Pistol"
+    }, 
+    ":fork-knife-plate:": {
+        "style": "github", 
+        "image": "1f37d.png", 
+        "unicode": "🍽", 
+        "name": "Fork And Knife With Plate"
+    }, 
+    ":clap:": {
+        "style": "github", 
+        "image": "1f44f.png", 
+        "unicode": "👏", 
+        "name": "Clapping Hands Sign"
+    }, 
+    "🌯": {
+        "style": "unicode", 
+        "image": "1f32f.png", 
+        "name": "Burrito"
+    }, 
+    "🤳": {
+        "style": "unicode", 
+        "image": "1f933.png", 
+        "name": "Selfie"
+    }, 
+    ":raised_hand_tone1:": {
+        "style": "github", 
+        "image": "270b-1f3fb.png", 
+        "unicode": "✋🏻", 
+        "name": "Raised Hand - Tone 1"
+    }, 
+    ":kiss_mm:": {
+        "style": "github", 
+        "image": "1f468-2764-1f48b-1f468.png", 
+        "unicode": "👨❤💋👨", 
+        "name": "Kiss (man,man)"
+    }, 
+    ":bicyclist_tone2:": {
+        "style": "github", 
+        "image": "1f6b4-1f3fc.png", 
+        "unicode": "🚴🏼", 
+        "name": "Bicyclist - Tone 2"
+    }, 
+    ":raised_hand_with_part_between_middle_and_ring_fingers_tone1:": {
+        "style": "github", 
+        "image": "1f596-1f3fb.png", 
+        "unicode": "🖖🏻", 
+        "name": "Raised Hand With Part Between Middle And Ring Fingers - Tone 1"
+    }, 
+    ":alien:": {
+        "style": "github", 
+        "image": "1f47d.png", 
+        "unicode": "👽", 
+        "name": "Extraterrestrial Alien"
+    }, 
+    ":worried:": {
+        "style": "github", 
+        "image": "1f61f.png", 
+        "unicode": "😟", 
+        "name": "Worried Face"
+    }, 
+    "🏄": {
+        "style": "unicode", 
+        "image": "1f3c4.png", 
+        "name": "Surfer"
+    }, 
+    ":tuvalu:": {
+        "style": "github", 
+        "image": "1f1f9-1f1fb.png", 
+        "unicode": "🇹🇻", 
+        "name": "Tuvalu"
+    }, 
+    ":boy_tone3:": {
+        "style": "github", 
+        "image": "1f466-1f3fd.png", 
+        "unicode": "👦🏽", 
+        "name": "Boy - Tone 3"
+    }, 
+    ":muscle_tone1:": {
+        "style": "github", 
+        "image": "1f4aa-1f3fb.png", 
+        "unicode": "💪🏻", 
+        "name": "Flexed Biceps - Tone 1"
+    }, 
+    ":crystal_ball:": {
+        "style": "github", 
+        "image": "1f52e.png", 
+        "unicode": "🔮", 
+        "name": "Crystal Ball"
+    }, 
+    ">.<": {
+        "style": "ascii", 
+        "ascii": ">.<", 
+        "image": "1f623.png", 
+        "unicode": "😣", 
+        "name": "Persevering Face"
+    }, 
+    ":bicyclist_tone4:": {
+        "style": "github", 
+        "image": "1f6b4-1f3fe.png", 
+        "unicode": "🚴🏾", 
+        "name": "Bicyclist - Tone 4"
+    }, 
+    ":earth_africa:": {
+        "style": "github", 
+        "image": "1f30d.png", 
+        "unicode": "🌍", 
+        "name": "Earth Globe Europe-africa"
+    }, 
+    ":water-polo-tone3:": {
+        "style": "github", 
+        "image": "1f93d-1f3fd.png", 
+        "unicode": "🤽🏽", 
+        "name": "Water Polo - Tone 3"
+    }, 
+    ":tuxedo_tone2:": {
+        "style": "github", 
+        "image": "1f935-1f3fc.png", 
+        "unicode": "🤵🏼", 
+        "name": "Man In Tuxedo - Tone 2"
+    }, 
+    ":oncoming_bus:": {
+        "style": "github", 
+        "image": "1f68d.png", 
+        "unicode": "🚍", 
+        "name": "Oncoming Bus"
+    }, 
+    ":department_store:": {
+        "style": "github", 
+        "image": "1f3ec.png", 
+        "unicode": "🏬", 
+        "name": "Department Store"
+    }, 
+    ":wind_chime:": {
+        "style": "github", 
+        "image": "1f390.png", 
+        "unicode": "🎐", 
+        "name": "Wind Chime"
+    }, 
+    "🥊": {
+        "style": "unicode", 
+        "image": "1f94a.png", 
+        "name": "Boxing Glove"
+    }, 
+    ":city-sunset:": {
+        "style": "github", 
+        "image": "1f307.png", 
+        "unicode": "🌇", 
+        "name": "Sunset Over Buildings"
+    }, 
+    "📗": {
+        "style": "unicode", 
+        "image": "1f4d7.png", 
+        "name": "Green Book"
+    }, 
+    ":cyclone:": {
+        "style": "github", 
+        "image": "1f300.png", 
+        "unicode": "🌀", 
+        "name": "Cyclone"
+    }, 
+    "🇱🇰": {
+        "style": "unicode", 
+        "image": "1f1f1-1f1f0.png", 
+        "name": "Sri Lanka"
+    }, 
+    ":ar:": {
+        "style": "github", 
+        "image": "1f1e6-1f1f7.png", 
+        "unicode": "🇦🇷", 
+        "name": "Argentina"
+    }, 
+    "🇱🇷": {
+        "style": "unicode", 
+        "image": "1f1f1-1f1f7.png", 
+        "name": "Liberia"
+    }, 
+    "🇱🇹": {
+        "style": "unicode", 
+        "image": "1f1f1-1f1f9.png", 
+        "name": "Lithuania"
+    }, 
+    "🇱🇸": {
+        "style": "unicode", 
+        "image": "1f1f1-1f1f8.png", 
+        "name": "Lesotho"
+    }, 
+    "🇱🇻": {
+        "style": "unicode", 
+        "image": "1f1f1-1f1fb.png", 
+        "name": "Latvia"
+    }, 
+    "🇱🇺": {
+        "style": "unicode", 
+        "image": "1f1f1-1f1fa.png", 
+        "name": "Luxembourg"
+    }, 
+    "👬": {
+        "style": "unicode", 
+        "image": "1f46c.png", 
+        "name": "Two Men Holding Hands"
+    }, 
+    "🇱🇾": {
+        "style": "unicode", 
+        "image": "1f1f1-1f1fe.png", 
+        "name": "Libya"
+    }, 
+    ":left_speech_bubble:": {
+        "style": "github", 
+        "image": "1f5e8.png", 
+        "unicode": "🗨", 
+        "name": "Left Speech Bubble"
+    }, 
+    ":grey-question:": {
+        "style": "github", 
+        "image": "2754.png", 
+        "unicode": "❔", 
+        "name": "White Question Mark Ornament"
+    }, 
+    "🇱🇧": {
+        "style": "unicode", 
+        "image": "1f1f1-1f1e7.png", 
+        "name": "Lebanon"
+    }, 
+    "🇱🇦": {
+        "style": "unicode", 
+        "image": "1f1f1-1f1e6.png", 
+        "name": "Laos"
+    }, 
+    "🇱🇨": {
+        "style": "unicode", 
+        "image": "1f1f1-1f1e8.png", 
+        "name": "Saint Lucia"
+    }, 
+    ":flag-st:": {
+        "style": "github", 
+        "image": "1f1f8-1f1f9.png", 
+        "unicode": "🇸🇹", 
+        "name": "São Tomé And Príncipe"
+    }, 
+    ":horse_racing_tone3:": {
+        "style": "github", 
+        "image": "1f3c7-1f3fd.png", 
+        "unicode": "🏇🏽", 
+        "name": "Horse Racing - Tone 3"
+    }, 
+    "🇱🇮": {
+        "style": "unicode", 
+        "image": "1f1f1-1f1ee.png", 
+        "name": "Liechtenstein"
+    }, 
+    ":flag-aq:": {
+        "style": "github", 
+        "image": "1f1e6-1f1f6.png", 
+        "unicode": "🇦🇶", 
+        "name": "Antarctica"
+    }, 
+    ":punch_tone1:": {
+        "style": "github", 
+        "image": "1f44a-1f3fb.png", 
+        "unicode": "👊🏻", 
+        "name": "Fisted Hand Sign - Tone 1"
+    }, 
+    ":cloud_snow:": {
+        "style": "github", 
+        "image": "1f328.png", 
+        "unicode": "🌨", 
+        "name": "Cloud With Snow"
+    }, 
+    "🆚": {
+        "style": "unicode", 
+        "image": "1f19a.png", 
+        "name": "Squared Vs"
+    }, 
+    ":flag_bh:": {
+        "style": "github", 
+        "image": "1f1e7-1f1ed.png", 
+        "unicode": "🇧🇭", 
+        "name": "Bahrain"
+    }, 
+    "⚠": {
+        "style": "unicode", 
+        "image": "26a0.png", 
+        "name": "Warning Sign"
+    }, 
+    "😫": {
+        "style": "unicode", 
+        "image": "1f62b.png", 
+        "name": "Tired Face"
+    }, 
+    ":point_left_tone2:": {
+        "style": "github", 
+        "image": "1f448-1f3fc.png", 
+        "unicode": "👈🏼", 
+        "name": "White Left Pointing Backhand Index - Tone 2"
+    }, 
+    ":person_doing_cartwheel:": {
+        "style": "github", 
+        "image": "1f938.png", 
+        "unicode": "🤸", 
+        "name": "Person Doing Cartwheel"
+    }, 
+    ":fist_tone4:": {
+        "style": "github", 
+        "image": "270a-1f3fe.png", 
+        "unicode": "✊🏾", 
+        "name": "Raised Fist - Tone 4"
+    }, 
+    ":regional-indicator-l:": {
+        "style": "github", 
+        "image": "1f1f1.png", 
+        "unicode": "🇱", 
+        "name": "Regional Indicator Symbol Letter L"
+    }, 
+    "🍙": {
+        "style": "unicode", 
+        "image": "1f359.png", 
+        "name": "Rice Ball"
+    }, 
+    ":dancer-tone2:": {
+        "style": "github", 
+        "image": "1f483-1f3fc.png", 
+        "unicode": "💃🏼", 
+        "name": "Dancer - Tone 2"
+    }, 
+    "🏮": {
+        "style": "unicode", 
+        "image": "1f3ee.png", 
+        "name": "Izakaya Lantern"
+    }, 
+    ":princess-tone1:": {
+        "style": "github", 
+        "image": "1f478-1f3fb.png", 
+        "unicode": "👸🏻", 
+        "name": "Princess - Tone 1"
+    }, 
+    ":thumbsdown_tone5:": {
+        "style": "github", 
+        "image": "1f44e-1f3ff.png", 
+        "unicode": "👎🏿", 
+        "name": "Thumbs Down Sign - Tone 5"
+    }, 
+    "🎃": {
+        "style": "unicode", 
+        "image": "1f383.png", 
+        "name": "Jack-o-lantern"
+    }, 
+    ":rowboat-tone2:": {
+        "style": "github", 
+        "image": "1f6a3-1f3fc.png", 
+        "unicode": "🚣🏼", 
+        "name": "Rowboat - Tone 2"
+    }, 
+    ":ox:": {
+        "style": "github", 
+        "image": "1f402.png", 
+        "unicode": "🐂", 
+        "name": "Ox"
+    }, 
+    ":neutral-face:": {
+        "style": "github", 
+        "image": "1f610.png", 
+        "unicode": "😐", 
+        "name": "Neutral Face"
+    }, 
+    ":flag_ye:": {
+        "style": "github", 
+        "image": "1f1fe-1f1ea.png", 
+        "unicode": "🇾🇪", 
+        "name": "Yemen"
+    }, 
+    "🌘": {
+        "style": "unicode", 
+        "image": "1f318.png", 
+        "name": "Waning Crescent Moon Symbol"
+    }, 
+    ":beers:": {
+        "style": "github", 
+        "image": "1f37b.png", 
+        "unicode": "🍻", 
+        "name": "Clinking Beer Mugs"
+    }, 
+    ":bride-with-veil-tone5:": {
+        "style": "github", 
+        "image": "1f470-1f3ff.png", 
+        "unicode": "👰🏿", 
+        "name": "Bride With Veil - Tone 5"
+    }, 
+    "💭": {
+        "style": "unicode", 
+        "image": "1f4ad.png", 
+        "name": "Thought Balloon"
+    }, 
+    ":flag-bs:": {
+        "style": "github", 
+        "image": "1f1e7-1f1f8.png", 
+        "unicode": "🇧🇸", 
+        "name": "The Bahamas"
+    }, 
+    "👂": {
+        "style": "unicode", 
+        "image": "1f442.png", 
+        "name": "Ear"
+    }, 
+    ":u6e80:": {
+        "style": "github", 
+        "image": "1f235.png", 
+        "unicode": "🈵", 
+        "name": "Squared Cjk Unified Ideograph-6e80"
+    }, 
+    ":clock8:": {
+        "style": "github", 
+        "image": "1f557.png", 
+        "unicode": "🕗", 
+        "name": "Clock Face Eight Oclock"
+    }, 
+    ":mn:": {
+        "style": "github", 
+        "image": "1f1f2-1f1f3.png", 
+        "unicode": "🇲🇳", 
+        "name": "Mongolia"
+    }, 
+    ":wave-tone5:": {
+        "style": "github", 
+        "image": "1f44b-1f3ff.png", 
+        "unicode": "👋🏿", 
+        "name": "Waving Hand Sign - Tone 5"
+    }, 
+    ":fork_and_knife:": {
+        "style": "github", 
+        "image": "1f374.png", 
+        "unicode": "🍴", 
+        "name": "Fork And Knife"
+    }, 
+    ":ballot-box:": {
+        "style": "github", 
+        "image": "1f5f3.png", 
+        "unicode": "🗳", 
+        "name": "Ballot Box With Ballot"
+    }, 
+    ":military-medal:": {
+        "style": "github", 
+        "image": "1f396.png", 
+        "unicode": "🎖", 
+        "name": "Military Medal"
+    }, 
+    "😁": {
+        "style": "unicode", 
+        "image": "1f601.png", 
+        "name": "Grinning Face With Smiling Eyes"
+    }, 
+    ":flag_cw:": {
+        "style": "github", 
+        "image": "1f1e8-1f1fc.png", 
+        "unicode": "🇨🇼", 
+        "name": "Curaçao"
+    }, 
+    ":flag_ro:": {
+        "style": "github", 
+        "image": "1f1f7-1f1f4.png", 
+        "unicode": "🇷🇴", 
+        "name": "Romania"
+    }, 
+    ":left_fist_tone5:": {
+        "style": "github", 
+        "image": "1f91b-1f3ff.png", 
+        "unicode": "🤛🏿", 
+        "name": "Left Facing Fist - Tone 5"
+    }, 
+    "✋": {
+        "style": "unicode", 
+        "image": "270b.png", 
+        "name": "Raised Hand"
+    }, 
+    ":bookmark-tabs:": {
+        "style": "github", 
+        "image": "1f4d1.png", 
+        "unicode": "📑", 
+        "name": "Bookmark Tabs"
+    }, 
+    "🚖": {
+        "style": "unicode", 
+        "image": "1f696.png", 
+        "name": "Oncoming Taxi"
+    }, 
+    ":dromedary_camel:": {
+        "style": "github", 
+        "image": "1f42a.png", 
+        "unicode": "🐪", 
+        "name": "Dromedary Camel"
+    }, 
+    ":call_me_tone1:": {
+        "style": "github", 
+        "image": "1f919-1f3fb.png", 
+        "unicode": "🤙🏻", 
+        "name": "Call Me Hand - Tone 1"
+    }, 
+    ":flag-rs:": {
+        "style": "github", 
+        "image": "1f1f7-1f1f8.png", 
+        "unicode": "🇷🇸", 
+        "name": "Serbia"
+    }, 
+    ":raised_back_of_hand_tone5:": {
+        "style": "github", 
+        "image": "1f91a-1f3ff.png", 
+        "unicode": "🤚🏿", 
+        "name": "Raised Back Of Hand - Tone 5"
+    }, 
+    ":flag_lb:": {
+        "style": "github", 
+        "image": "1f1f1-1f1e7.png", 
+        "unicode": "🇱🇧", 
+        "name": "Lebanon"
+    }, 
+    ":arrow-heading-up:": {
+        "style": "github", 
+        "image": "2934.png", 
+        "unicode": "⤴", 
+        "name": "Arrow Pointing Rightwards Then Curving Upwards"
+    }, 
+    ":national_park:": {
+        "style": "github", 
+        "image": "1f3de.png", 
+        "unicode": "🏞", 
+        "name": "National Park"
+    }, 
+    ":flag-no:": {
+        "style": "github", 
+        "image": "1f1f3-1f1f4.png", 
+        "unicode": "🇳🇴", 
+        "name": "Norway"
+    }, 
+    ":sleeping:": {
+        "style": "github", 
+        "image": "1f634.png", 
+        "unicode": "😴", 
+        "name": "Sleeping Face"
+    }, 
+    ":lifter_tone1:": {
+        "style": "github", 
+        "image": "1f3cb-1f3fb.png", 
+        "unicode": "🏋🏻", 
+        "name": "Weight Lifter - Tone 1"
+    }, 
+    ":hand_splayed:": {
+        "style": "github", 
+        "image": "1f590.png", 
+        "unicode": "🖐", 
+        "name": "Raised Hand With Fingers Splayed"
+    }, 
+    ":rw:": {
+        "style": "github", 
+        "image": "1f1f7-1f1fc.png", 
+        "unicode": "🇷🇼", 
+        "name": "Rwanda"
+    }, 
+    ":wrestlers:": {
+        "style": "github", 
+        "image": "1f93c.png", 
+        "unicode": "🤼", 
+        "name": "Wrestlers"
+    }, 
+    ":cop-tone3:": {
+        "style": "github", 
+        "image": "1f46e-1f3fd.png", 
+        "unicode": "👮🏽", 
+        "name": "Police Officer - Tone 3"
+    }, 
+    ":guardsman-tone2:": {
+        "style": "github", 
+        "image": "1f482-1f3fc.png", 
+        "unicode": "💂🏼", 
+        "name": "Guardsman - Tone 2"
+    }, 
+    "⏸": {
+        "style": "unicode", 
+        "image": "23f8.png", 
+        "name": "Double Vertical Bar"
+    }, 
+    ":flag_mz:": {
+        "style": "github", 
+        "image": "1f1f2-1f1ff.png", 
+        "unicode": "🇲🇿", 
+        "name": "Mozambique"
+    }, 
+    ":um:": {
+        "style": "github", 
+        "image": "1f1fa-1f1f2.png", 
+        "unicode": "🇺🇲", 
+        "name": "United States Minor Outlying Islands"
+    }, 
+    ":point_right_tone2:": {
+        "style": "github", 
+        "image": "1f449-1f3fc.png", 
+        "unicode": "👉🏼", 
+        "name": "White Right Pointing Backhand Index - Tone 2"
+    }, 
+    "➕": {
+        "style": "unicode", 
+        "image": "2795.png", 
+        "name": "Heavy Plus Sign"
+    }, 
+    ":racehorse:": {
+        "style": "github", 
+        "image": "1f40e.png", 
+        "unicode": "🐎", 
+        "name": "Horse"
+    }, 
+    "🇰🇲": {
+        "style": "unicode", 
+        "image": "1f1f0-1f1f2.png", 
+        "name": "The Comoros"
+    }, 
+    "🇰🇳": {
+        "style": "unicode", 
+        "image": "1f1f0-1f1f3.png", 
+        "name": "Saint Kitts And Nevis"
+    }, 
+    ":dog:": {
+        "style": "github", 
+        "image": "1f436.png", 
+        "unicode": "🐶", 
+        "name": "Dog Face"
+    }, 
+    ":fish:": {
+        "style": "github", 
+        "image": "1f41f.png", 
+        "unicode": "🐟", 
+        "name": "Fish"
+    }, 
+    "🇰🇷": {
+        "style": "unicode", 
+        "image": "1f1f0-1f1f7.png", 
+        "name": "Korea"
+    }, 
+    "🇰🇵": {
+        "style": "unicode", 
+        "image": "1f1f0-1f1f5.png", 
+        "name": "North Korea"
+    }, 
+    "':D": {
+        "style": "ascii", 
+        "ascii": "':)", 
+        "image": "1f605.png", 
+        "unicode": "😅", 
+        "name": "Smiling Face With Open Mouth And Cold Sweat"
+    }, 
+    "🇰🇾": {
+        "style": "unicode", 
+        "image": "1f1f0-1f1fe.png", 
+        "name": "Cayman Islands"
+    }, 
+    "🇰🇿": {
+        "style": "unicode", 
+        "image": "1f1f0-1f1ff.png", 
+        "name": "Kazakhstan"
+    }, 
+    "🇰🇼": {
+        "style": "unicode", 
+        "image": "1f1f0-1f1fc.png", 
+        "name": "Kuwait"
+    }, 
+    ":clock430:": {
+        "style": "github", 
+        "image": "1f55f.png", 
+        "unicode": "🕟", 
+        "name": "Clock Face Four-thirty"
+    }, 
+    "🇰🇪": {
+        "style": "unicode", 
+        "image": "1f1f0-1f1ea.png", 
+        "name": "Kenya"
+    }, 
+    "👞": {
+        "style": "unicode", 
+        "image": "1f45e.png", 
+        "name": "Mans Shoe"
+    }, 
+    "🇰🇮": {
+        "style": "unicode", 
+        "image": "1f1f0-1f1ee.png", 
+        "name": "Kiribati"
+    }, 
+    "🇰🇬": {
+        "style": "unicode", 
+        "image": "1f1f0-1f1ec.png", 
+        "name": "Kyrgyzstan"
+    }, 
+    "🇰🇭": {
+        "style": "unicode", 
+        "image": "1f1f0-1f1ed.png", 
+        "name": "Cambodia"
+    }, 
+    "':(": {
+        "style": "ascii", 
+        "ascii": "':(", 
+        "image": "1f613.png", 
+        "unicode": "😓", 
+        "name": "Face With Cold Sweat"
+    }, 
+    "':)": {
+        "style": "ascii", 
+        "ascii": "':)", 
+        "image": "1f605.png", 
+        "unicode": "😅", 
+        "name": "Smiling Face With Open Mouth And Cold Sweat"
+    }, 
+    ":clock330:": {
+        "style": "github", 
+        "image": "1f55e.png", 
+        "unicode": "🕞", 
+        "name": "Clock Face Three-thirty"
+    }, 
+    ":u7981:": {
+        "style": "github", 
+        "image": "1f232.png", 
+        "unicode": "🈲", 
+        "name": "Squared Cjk Unified Ideograph-7981"
+    }, 
+    ":gem:": {
+        "style": "github", 
+        "image": "1f48e.png", 
+        "unicode": "💎", 
+        "name": "Gem Stone"
+    }, 
+    ":racing_motorcycle:": {
+        "style": "github", 
+        "image": "1f3cd.png", 
+        "unicode": "🏍", 
+        "name": "Racing Motorcycle"
+    }, 
+    ":older-woman-tone2:": {
+        "style": "github", 
+        "image": "1f475-1f3fc.png", 
+        "unicode": "👵🏼", 
+        "name": "Older Woman - Tone 2"
+    }, 
+    ":flag-mc:": {
+        "style": "github", 
+        "image": "1f1f2-1f1e8.png", 
+        "unicode": "🇲🇨", 
+        "name": "Monaco"
+    }, 
+    ":handball_tone3:": {
+        "style": "github", 
+        "image": "1f93e-1f3fd.png", 
+        "unicode": "🤾🏽", 
+        "name": "Handball - Tone 3"
+    }, 
+    "🔉": {
+        "style": "unicode", 
+        "image": "1f509.png", 
+        "name": "Speaker With One Sound Wave"
+    }, 
+    ":rooster:": {
+        "style": "github", 
+        "image": "1f413.png", 
+        "unicode": "🐓", 
+        "name": "Rooster"
+    }, 
+    "↙": {
+        "style": "unicode", 
+        "image": "2199.png", 
+        "name": "South West Arrow"
+    }, 
+    ":circus_tent:": {
+        "style": "github", 
+        "image": "1f3aa.png", 
+        "unicode": "🎪", 
+        "name": "Circus Tent"
+    }, 
+    ":rice_scene:": {
+        "style": "github", 
+        "image": "1f391.png", 
+        "unicode": "🎑", 
+        "name": "Moon Viewing Ceremony"
+    }, 
+    ":raised_hand_with_fingers_splayed:": {
+        "style": "github", 
+        "image": "1f590.png", 
+        "unicode": "🖐", 
+        "name": "Raised Hand With Fingers Splayed"
+    }, 
+    "🐳": {
+        "style": "unicode", 
+        "image": "1f433.png", 
+        "name": "Spouting Whale"
+    }, 
+    ":flag_jo:": {
+        "style": "github", 
+        "image": "1f1ef-1f1f4.png", 
+        "unicode": "🇯🇴", 
+        "name": "Jordan"
+    }, 
+    ":no-good-tone4:": {
+        "style": "github", 
+        "image": "1f645-1f3fe.png", 
+        "unicode": "🙅🏾", 
+        "name": "Face With No Good Gesture - Tone 4"
+    }, 
+    ":scream_cat:": {
+        "style": "github", 
+        "image": "1f640.png", 
+        "unicode": "🙀", 
+        "name": "Weary Cat Face"
+    }, 
+    "📈": {
+        "style": "unicode", 
+        "image": "1f4c8.png", 
+        "name": "Chart With Upwards Trend"
+    }, 
+    ":haircut_tone2:": {
+        "style": "github", 
+        "image": "1f487-1f3fc.png", 
+        "unicode": "💇🏼", 
+        "name": "Haircut - Tone 2"
+    }, 
+    ":school-satchel:": {
+        "style": "github", 
+        "image": "1f392.png", 
+        "unicode": "🎒", 
+        "name": "School Satchel"
+    }, 
+    ":'-)": {
+        "style": "ascii", 
+        "ascii": ":')", 
+        "image": "1f602.png", 
+        "unicode": "😂", 
+        "name": "Face With Tears Of Joy"
+    }, 
+    "🍝": {
+        "style": "unicode", 
+        "image": "1f35d.png", 
+        "name": "Spaghetti"
+    }, 
+    ":point-right-tone1:": {
+        "style": "github", 
+        "image": "1f449-1f3fb.png", 
+        "unicode": "👉🏻", 
+        "name": "White Right Pointing Backhand Index - Tone 1"
+    }, 
+    ":flag-mf:": {
+        "style": "github", 
+        "image": "1f1f2-1f1eb.png", 
+        "unicode": "🇲🇫", 
+        "name": "Saint Martin"
+    }, 
+    ":flag-gd:": {
+        "style": "github", 
+        "image": "1f1ec-1f1e9.png", 
+        "unicode": "🇬🇩", 
+        "name": "Grenada"
+    }, 
+    "🎇": {
+        "style": "unicode", 
+        "image": "1f387.png", 
+        "name": "Firework Sparkler"
+    }, 
+    ":point_left:": {
+        "style": "github", 
+        "image": "1f448.png", 
+        "unicode": "👈", 
+        "name": "White Left Pointing Backhand Index"
+    }, 
+    ":busts_in_silhouette:": {
+        "style": "github", 
+        "image": "1f465.png", 
+        "unicode": "👥", 
+        "name": "Busts In Silhouette"
+    }, 
+    ":full_moon_with_face:": {
+        "style": "github", 
+        "image": "1f31d.png", 
+        "unicode": "🌝", 
+        "name": "Full Moon With Face"
+    }, 
+    ":gm:": {
+        "style": "github", 
+        "image": "1f1ec-1f1f2.png", 
+        "unicode": "🇬🇲", 
+        "name": "The Gambia"
+    }, 
+    ";(": {
+        "style": "ascii", 
+        "ascii": ":'(", 
+        "image": "1f622.png", 
+        "unicode": "😢", 
+        "name": "Crying Face"
+    }, 
+    ":homes:": {
+        "style": "github", 
+        "image": "1f3d8.png", 
+        "unicode": "🏘", 
+        "name": "House Buildings"
+    }, 
+    ":flag_eg:": {
+        "style": "github", 
+        "image": "1f1ea-1f1ec.png", 
+        "unicode": "🇪🇬", 
+        "name": "Egypt"
+    }, 
+    "🚵": {
+        "style": "unicode", 
+        "image": "1f6b5.png", 
+        "name": "Mountain Bicyclist"
+    }, 
+    "🙋🏽": {
+        "style": "unicode", 
+        "image": "1f64b-1f3fd.png", 
+        "name": "Happy Person Raising One Hand Tone3"
+    }, 
+    "➿": {
+        "style": "unicode", 
+        "image": "27bf.png", 
+        "name": "Double Curly Loop"
+    }, 
+    ":passenger_ship:": {
+        "style": "github", 
+        "image": "1f6f3.png", 
+        "unicode": "🛳", 
+        "name": "Passenger Ship"
+    }, 
+    "🙊": {
+        "style": "unicode", 
+        "image": "1f64a.png", 
+        "name": "Speak-no-evil Monkey"
+    }, 
+    ":arrow-backward:": {
+        "style": "github", 
+        "image": "25c0.png", 
+        "unicode": "◀", 
+        "name": "Black Left-pointing Triangle"
+    }, 
+    "⛹🏻": {
+        "style": "unicode", 
+        "image": "26f9-1f3fb.png", 
+        "name": "Person With Ball - Tone 1"
+    }, 
+    "⛹🏽": {
+        "style": "unicode", 
+        "image": "26f9-1f3fd.png", 
+        "name": "Person With Ball - Tone 3"
+    }, 
+    "❔": {
+        "style": "unicode", 
+        "image": "2754.png", 
+        "name": "White Question Mark Ornament"
+    }, 
+    "⛹🏿": {
+        "style": "unicode", 
+        "image": "26f9-1f3ff.png", 
+        "name": "Person With Ball - Tone 5"
+    }, 
+    "⛹🏾": {
+        "style": "unicode", 
+        "image": "26f9-1f3fe.png", 
+        "name": "Person With Ball - Tone 4"
+    }, 
+    ":flag-fj:": {
+        "style": "github", 
+        "image": "1f1eb-1f1ef.png", 
+        "unicode": "🇫🇯", 
+        "name": "Fiji"
+    }, 
+    ":ghost:": {
+        "style": "github", 
+        "image": "1f47b.png", 
+        "unicode": "👻", 
+        "name": "Ghost"
+    }, 
+    ":flag_nc:": {
+        "style": "github", 
+        "image": "1f1f3-1f1e8.png", 
+        "unicode": "🇳🇨", 
+        "name": "New Caledonia"
+    }, 
+    ":fuelpump:": {
+        "style": "github", 
+        "image": "26fd.png", 
+        "unicode": "⛽", 
+        "name": "Fuel Pump"
+    }, 
+    "🅰": {
+        "style": "unicode", 
+        "image": "1f170.png", 
+        "name": "Negative Squared Latin Capital Letter A"
+    }, 
+    ":ai:": {
+        "style": "github", 
+        "image": "1f1e6-1f1ee.png", 
+        "unicode": "🇦🇮", 
+        "name": "Anguilla"
+    }, 
+    ":sweat-smile:": {
+        "style": "github", 
+        "ascii": "':)", 
+        "image": "1f605.png", 
+        "unicode": "😅", 
+        "name": "Smiling Face With Open Mouth And Cold Sweat"
+    }, 
+    ":person-with-blond-hair-tone1:": {
+        "style": "github", 
+        "image": "1f471-1f3fb.png", 
+        "unicode": "👱🏻", 
+        "name": "Person With Blond Hair - Tone 1"
+    }, 
+    "🐉": {
+        "style": "unicode", 
+        "image": "1f409.png", 
+        "name": "Dragon"
+    }, 
+    ":mrs_claus_tone4:": {
+        "style": "github", 
+        "image": "1f936-1f3fe.png", 
+        "unicode": "🤶🏾", 
+        "name": "Mother Christmas - Tone 4"
+    }, 
+    "💞": {
+        "style": "unicode", 
+        "image": "1f49e.png", 
+        "name": "Revolving Hearts"
+    }, 
+    ":speedboat:": {
+        "style": "github", 
+        "image": "1f6a4.png", 
+        "unicode": "🚤", 
+        "name": "Speedboat"
+    }, 
+    "⛰": {
+        "style": "unicode", 
+        "image": "26f0.png", 
+        "name": "Mountain"
+    }, 
+    "🔳": {
+        "style": "unicode", 
+        "image": "1f533.png", 
+        "name": "White Square Button"
+    }, 
+    ":first_quarter_moon:": {
+        "style": "github", 
+        "image": "1f313.png", 
+        "unicode": "🌓", 
+        "name": "First Quarter Moon Symbol"
+    }, 
+    ":aerial-tramway:": {
+        "style": "github", 
+        "image": "1f6a1.png", 
+        "unicode": "🚡", 
+        "name": "Aerial Tramway"
+    }, 
+    ":red-car:": {
+        "style": "github", 
+        "image": "1f697.png", 
+        "unicode": "🚗", 
+        "name": "Automobile"
+    }, 
+    "🧀": {
+        "style": "unicode", 
+        "image": "1f9c0.png", 
+        "name": "Cheese Wedge"
+    }, 
+    ":regional-indicator-q:": {
+        "style": "github", 
+        "image": "1f1f6.png", 
+        "unicode": "🇶", 
+        "name": "Regional Indicator Symbol Letter Q"
+    }, 
+    ":sweat:": {
+        "style": "github", 
+        "ascii": "':(", 
+        "image": "1f613.png", 
+        "unicode": "😓", 
+        "name": "Face With Cold Sweat"
+    }, 
+    ":coffee:": {
+        "style": "github", 
+        "image": "2615.png", 
+        "unicode": "☕", 
+        "name": "Hot Beverage"
+    }, 
+    ":briefcase:": {
+        "style": "github", 
+        "image": "1f4bc.png", 
+        "unicode": "💼", 
+        "name": "Briefcase"
+    }, 
+    ":person_with_ball_tone4:": {
+        "style": "github", 
+        "image": "26f9-1f3fe.png", 
+        "unicode": "⛹🏾", 
+        "name": "Person With Ball - Tone 4"
+    }, 
+    ":flag_ic:": {
+        "style": "github", 
+        "image": "1f1ee-1f1e8.png", 
+        "unicode": "🇮🇨", 
+        "name": "Canary Islands"
+    }, 
+    "☝🏽": {
+        "style": "unicode", 
+        "image": "261d-1f3fd.png", 
+        "name": "White Up Pointing Index - Tone 3"
+    }, 
+    "☝🏼": {
+        "style": "unicode", 
+        "image": "261d-1f3fc.png", 
+        "name": "White Up Pointing Index - Tone 2"
+    }, 
+    "☝🏿": {
+        "style": "unicode", 
+        "image": "261d-1f3ff.png", 
+        "name": "White Up Pointing Index - Tone 5"
+    }, 
+    "☝🏾": {
+        "style": "unicode", 
+        "image": "261d-1f3fe.png", 
+        "name": "White Up Pointing Index - Tone 4"
+    }, 
+    ":stuck-out-tongue:": {
+        "style": "github", 
+        "ascii": ":P", 
+        "image": "1f61b.png", 
+        "unicode": "😛", 
+        "name": "Face With Stuck-out Tongue"
+    }, 
+    ":point_up_tone2:": {
+        "style": "github", 
+        "image": "261d-1f3fc.png", 
+        "unicode": "☝🏼", 
+        "name": "White Up Pointing Index - Tone 2"
+    }, 
+    ":flag_vn:": {
+        "style": "github", 
+        "image": "1f1fb-1f1f3.png", 
+        "unicode": "🇻🇳", 
+        "name": "Vietnam"
+    }, 
+    "🎱": {
+        "style": "unicode", 
+        "image": "1f3b1.png", 
+        "name": "Billiards"
+    }, 
+    ":prayer-beads:": {
+        "style": "github", 
+        "image": "1f4ff.png", 
+        "unicode": "📿", 
+        "name": "Prayer Beads"
+    }, 
+    ":interrobang:": {
+        "style": "github", 
+        "image": "2049.png", 
+        "unicode": "⁉", 
+        "name": "Exclamation Question Mark"
+    }, 
+    "🥂": {
+        "style": "unicode", 
+        "image": "1f942.png", 
+        "name": "Clinking Glasses"
+    }, 
+    "🍆": {
+        "style": "unicode", 
+        "image": "1f346.png", 
+        "name": "Aubergine"
+    }, 
+    "8⃣": {
+        "style": "unicode", 
+        "image": "0038-20e3.png", 
+        "name": "Keycap Digit Eight"
+    }, 
+    ":name_badge:": {
+        "style": "github", 
+        "image": "1f4db.png", 
+        "unicode": "📛", 
+        "name": "Name Badge"
+    }, 
+    ":flag_ar:": {
+        "style": "github", 
+        "image": "1f1e6-1f1f7.png", 
+        "unicode": "🇦🇷", 
+        "name": "Argentina"
+    }, 
+    ":computer:": {
+        "style": "github", 
+        "image": "1f4bb.png", 
+        "unicode": "💻", 
+        "name": "Personal Computer"
+    }, 
+    "📟": {
+        "style": "unicode", 
+        "image": "1f4df.png", 
+        "name": "Pager"
+    }, 
+    ":nose:": {
+        "style": "github", 
+        "image": "1f443.png", 
+        "unicode": "👃", 
+        "name": "Nose"
+    }, 
+    ":wavy-dash:": {
+        "style": "github", 
+        "image": "3030.png", 
+        "unicode": "〰", 
+        "name": "Wavy Dash"
+    }, 
+    ":boy_tone5:": {
+        "style": "github", 
+        "image": "1f466-1f3ff.png", 
+        "unicode": "👦🏿", 
+        "name": "Boy - Tone 5"
+    }, 
+    "👴": {
+        "style": "unicode", 
+        "image": "1f474.png", 
+        "name": "Older Man"
+    }, 
+    ":hand_with_index_and_middle_fingers_crossed_tone2:": {
+        "style": "github", 
+        "image": "1f91e-1f3fc.png", 
+        "unicode": "🤞🏼", 
+        "name": "Hand With Index And Middle Fingers Crossed - Tone 2"
+    }, 
+    ":regional-indicator-c:": {
+        "style": "github", 
+        "image": "1f1e8.png", 
+        "unicode": "🇨", 
+        "name": "Regional Indicator Symbol Letter C"
+    }, 
+    ":grinning:": {
+        "style": "github", 
+        "image": "1f600.png", 
+        "unicode": "😀", 
+        "name": "Grinning Face"
+    }, 
+    ":flag-ke:": {
+        "style": "github", 
+        "image": "1f1f0-1f1ea.png", 
+        "unicode": "🇰🇪", 
+        "name": "Kenya"
+    }, 
+    ":juggling_tone2:": {
+        "style": "github", 
+        "image": "1f939-1f3fc.png", 
+        "unicode": "🤹🏼", 
+        "name": "Juggling - Tone 2"
+    }, 
+    ":arrow_down:": {
+        "style": "github", 
+        "image": "2b07.png", 
+        "unicode": "⬇", 
+        "name": "Downwards Black Arrow"
+    }, 
+    ":moyai:": {
+        "style": "github", 
+        "image": "1f5ff.png", 
+        "unicode": "🗿", 
+        "name": "Moyai"
+    }, 
+    "8-D": {
+        "style": "ascii", 
+        "ascii": "B-)", 
+        "image": "1f60e.png", 
+        "unicode": "😎", 
+        "name": "Smiling Face With Sunglasses"
+    }, 
+    ":lc:": {
+        "style": "github", 
+        "image": "1f1f1-1f1e8.png", 
+        "unicode": "🇱🇨", 
+        "name": "Saint Lucia"
+    }, 
+    ":flag_ch:": {
+        "style": "github", 
+        "image": "1f1e8-1f1ed.png", 
+        "unicode": "🇨🇭", 
+        "name": "Switzerland"
+    }, 
+    ":water-polo-tone1:": {
+        "style": "github", 
+        "image": "1f93d-1f3fb.png", 
+        "unicode": "🤽🏻", 
+        "name": "Water Polo - Tone 1"
+    }, 
+    ":tuxedo_tone4:": {
+        "style": "github", 
+        "image": "1f935-1f3fe.png", 
+        "unicode": "🤵🏾", 
+        "name": "Man In Tuxedo - Tone 4"
+    }, 
+    ":shaking_hands_tone4:": {
+        "style": "github", 
+        "image": "1f91d-1f3fe.png", 
+        "unicode": "🤝🏾", 
+        "name": "Handshake - Tone 4"
+    }, 
+    ":flag_bf:": {
+        "style": "github", 
+        "image": "1f1e7-1f1eb.png", 
+        "unicode": "🇧🇫", 
+        "name": "Burkina Faso"
+    }, 
+    ":couple_mm:": {
+        "style": "github", 
+        "image": "1f468-2764-1f468.png", 
+        "unicode": "👨❤👨", 
+        "name": "Couple (man,man)"
+    }, 
+    "😳": {
+        "style": "unicode", 
+        "ascii": ":$", 
+        "image": "1f633.png", 
+        "name": "Flushed Face"
+    }, 
+    ":santa-tone3:": {
+        "style": "github", 
+        "image": "1f385-1f3fd.png", 
+        "unicode": "🎅🏽", 
+        "name": "Father Christmas - Tone 3"
+    }, 
+    ":x:": {
+        "style": "github", 
+        "image": "274c.png", 
+        "unicode": "❌", 
+        "name": "Cross Mark"
+    }, 
+    ":baby-bottle:": {
+        "style": "github", 
+        "image": "1f37c.png", 
+        "unicode": "🍼", 
+        "name": "Baby Bottle"
+    }, 
+    ":muscle_tone2:": {
+        "style": "github", 
+        "image": "1f4aa-1f3fc.png", 
+        "unicode": "💪🏼", 
+        "name": "Flexed Biceps - Tone 2"
+    }, 
+    ":blue-book:": {
+        "style": "github", 
+        "image": "1f4d8.png", 
+        "unicode": "📘", 
+        "name": "Blue Book"
+    }, 
+    ":flag-cu:": {
+        "style": "github", 
+        "image": "1f1e8-1f1fa.png", 
+        "unicode": "🇨🇺", 
+        "name": "Cuba"
+    }, 
+    ":metal_tone4:": {
+        "style": "github", 
+        "image": "1f918-1f3fe.png", 
+        "unicode": "🤘🏾", 
+        "name": "Sign Of The Horns - Tone 4"
+    }, 
+    "🇹": {
+        "style": "unicode", 
+        "image": "1f1f9.png", 
+        "name": "Regional Indicator Symbol Letter T"
+    }, 
+    ":trackball:": {
+        "style": "github", 
+        "image": "1f5b2.png", 
+        "unicode": "🖲", 
+        "name": "Trackball"
+    }, 
+    "8-)": {
+        "style": "ascii", 
+        "ascii": "B-)", 
+        "image": "1f60e.png", 
+        "unicode": "😎", 
+        "name": "Smiling Face With Sunglasses"
+    }, 
+    "🇲": {
+        "style": "unicode", 
+        "image": "1f1f2.png", 
+        "name": "Regional Indicator Symbol Letter M"
+    }, 
+    ":bread:": {
+        "style": "github", 
+        "image": "1f35e.png", 
+        "unicode": "🍞", 
+        "name": "Bread"
+    }, 
+    ":airplane-departure:": {
+        "style": "github", 
+        "image": "1f6eb.png", 
+        "unicode": "🛫", 
+        "name": "Airplane Departure"
+    }, 
+    ":horse_racing_tone1:": {
+        "style": "github", 
+        "image": "1f3c7-1f3fb.png", 
+        "unicode": "🏇🏻", 
+        "name": "Horse Racing - Tone 1"
+    }, 
+    ":flag-sv:": {
+        "style": "github", 
+        "image": "1f1f8-1f1fb.png", 
+        "unicode": "🇸🇻", 
+        "name": "El Salvador"
+    }, 
+    ":eight-pointed-black-star:": {
+        "style": "github", 
+        "image": "2734.png", 
+        "unicode": "✴", 
+        "name": "Eight Pointed Black Star"
+    }, 
+    ":flag_bj:": {
+        "style": "github", 
+        "image": "1f1e7-1f1ef.png", 
+        "unicode": "🇧🇯", 
+        "name": "Benin"
+    }, 
+    ":arrow-up-small:": {
+        "style": "github", 
+        "image": "1f53c.png", 
+        "unicode": "🔼", 
+        "name": "Up-pointing Small Red Triangle"
+    }, 
+    ":flag-aw:": {
+        "style": "github", 
+        "image": "1f1e6-1f1fc.png", 
+        "unicode": "🇦🇼", 
+        "name": "Aruba"
+    }, 
+    ":airplane_departure:": {
+        "style": "github", 
+        "image": "1f6eb.png", 
+        "unicode": "🛫", 
+        "name": "Airplane Departure"
+    }, 
+    ":il:": {
+        "style": "github", 
+        "image": "1f1ee-1f1f1.png", 
+        "unicode": "🇮🇱", 
+        "name": "Israel"
+    }, 
+    ":up:": {
+        "style": "github", 
+        "image": "1f199.png", 
+        "unicode": "🆙", 
+        "name": "Squared Up With Exclamation Mark"
+    }, 
+    "💵": {
+        "style": "unicode", 
+        "image": "1f4b5.png", 
+        "name": "Banknote With Dollar Sign"
+    }, 
+    ":convenience_store:": {
+        "style": "github", 
+        "image": "1f3ea.png", 
+        "unicode": "🏪", 
+        "name": "Convenience Store"
+    }, 
+    ":star:": {
+        "style": "github", 
+        "image": "2b50.png", 
+        "unicode": "⭐", 
+        "name": "White Medium Star"
+    }, 
+    ":point_left_tone4:": {
+        "style": "github", 
+        "image": "1f448-1f3fe.png", 
+        "unicode": "👈🏾", 
+        "name": "White Left Pointing Backhand Index - Tone 4"
+    }, 
+    ":thumbsup_tone5:": {
+        "style": "github", 
+        "image": "1f44d-1f3ff.png", 
+        "unicode": "👍🏿", 
+        "name": "Thumbs Up Sign - Tone 5"
+    }, 
+    "👊": {
+        "style": "unicode", 
+        "image": "1f44a.png", 
+        "name": "Fisted Hand Sign"
+    }, 
+    ":princess-tone3:": {
+        "style": "github", 
+        "image": "1f478-1f3fd.png", 
+        "unicode": "👸🏽", 
+        "name": "Princess - Tone 3"
+    }, 
+    "🏛": {
+        "style": "unicode", 
+        "image": "1f3db.png", 
+        "name": "Classical Building"
+    }, 
+    ":no_entry_sign:": {
+        "style": "github", 
+        "image": "1f6ab.png", 
+        "unicode": "🚫", 
+        "name": "No Entry Sign"
+    }, 
+    ":womans-clothes:": {
+        "style": "github", 
+        "image": "1f45a.png", 
+        "unicode": "👚", 
+        "name": "Womans Clothes"
+    }, 
+    ":free:": {
+        "style": "github", 
+        "image": "1f193.png", 
+        "unicode": "🆓", 
+        "name": "Squared Free"
+    }, 
+    "⛩": {
+        "style": "unicode", 
+        "image": "26e9.png", 
+        "name": "Shinto Shrine"
+    }, 
+    "🍰": {
+        "style": "unicode", 
+        "image": "1f370.png", 
+        "name": "Shortcake"
+    }, 
+    "🕴": {
+        "style": "unicode", 
+        "image": "1f574.png", 
+        "name": "Man In Business Suit Levitating"
+    }, 
+    ":walking_tone1:": {
+        "style": "github", 
+        "image": "1f6b6-1f3fb.png", 
+        "unicode": "🚶🏻", 
+        "name": "Pedestrian - Tone 1"
+    }, 
+    "😉": {
+        "style": "unicode", 
+        "ascii": ";)", 
+        "image": "1f609.png", 
+        "name": "Winking Face"
+    }, 
+    ":basketball-player:": {
+        "style": "github", 
+        "image": "26f9.png", 
+        "unicode": "⛹", 
+        "name": "Person With Ball"
+    }, 
+    "🚞": {
+        "style": "unicode", 
+        "image": "1f69e.png", 
+        "name": "Mountain Railway"
+    }, 
+    ":right_facing_fist_tone5:": {
+        "style": "github", 
+        "image": "1f91c-1f3ff.png", 
+        "unicode": "🤜🏿", 
+        "name": "Right Facing Fist - Tone 5"
+    }, 
+    ":flag-bq:": {
+        "style": "github", 
+        "image": "1f1e7-1f1f6.png", 
+        "unicode": "🇧🇶", 
+        "name": "Caribbean Netherlands"
+    }, 
+    ":wave-tone3:": {
+        "style": "github", 
+        "image": "1f44b-1f3fd.png", 
+        "unicode": "👋🏽", 
+        "name": "Waving Hand Sign - Tone 3"
+    }, 
+    ":person-frowning-tone5:": {
+        "style": "github", 
+        "image": "1f64d-1f3ff.png", 
+        "unicode": "🙍🏿", 
+        "name": "Person Frowning - Tone 5"
+    }, 
+    ":anger_right:": {
+        "style": "github", 
+        "image": "1f5ef.png", 
+        "unicode": "🗯", 
+        "name": "Right Anger Bubble"
+    }, 
+    ":clinking_glass:": {
+        "style": "github", 
+        "image": "1f942.png", 
+        "unicode": "🥂", 
+        "name": "Clinking Glasses"
+    }, 
+    ":flag-bm:": {
+        "style": "github", 
+        "image": "1f1e7-1f1f2.png", 
+        "unicode": "🇧🇲", 
+        "name": "Bermuda"
+    }, 
+    ":basketball_player_tone2:": {
+        "style": "github", 
+        "image": "26f9-1f3fc.png", 
+        "unicode": "⛹🏼", 
+        "name": "Person With Ball - Tone 2"
+    }, 
+    ":cold_sweat:": {
+        "style": "github", 
+        "image": "1f630.png", 
+        "unicode": "😰", 
+        "name": "Face With Open Mouth And Cold Sweat"
+    }, 
+    ":leopard:": {
+        "style": "github", 
+        "image": "1f406.png", 
+        "unicode": "🐆", 
+        "name": "Leopard"
+    }, 
+    ":td:": {
+        "style": "github", 
+        "image": "1f1f9-1f1e9.png", 
+        "unicode": "🇹🇩", 
+        "name": "Chad"
+    }, 
+    ":loud-sound:": {
+        "style": "github", 
+        "image": "1f50a.png", 
+        "unicode": "🔊", 
+        "name": "Speaker With Three Sound Waves"
+    }, 
+    "👴🏾": {
+        "style": "unicode", 
+        "image": "1f474-1f3fe.png", 
+        "name": "Older Man - Tone 4"
+    }, 
+    "🚇": {
+        "style": "unicode", 
+        "image": "1f687.png", 
+        "name": "Metro"
+    }, 
+    ":person-with-pouting-face-tone5:": {
+        "style": "github", 
+        "image": "1f64e-1f3ff.png", 
+        "unicode": "🙎🏿", 
+        "name": "Person With Pouting Face Tone5"
+    }, 
+    ":flag_cu:": {
+        "style": "github", 
+        "image": "1f1e8-1f1fa.png", 
+        "unicode": "🇨🇺", 
+        "name": "Cuba"
+    }, 
+    ":control-knobs:": {
+        "style": "github", 
+        "image": "1f39b.png", 
+        "unicode": "🎛", 
+        "name": "Control Knobs"
+    }, 
+    ":tw:": {
+        "style": "github", 
+        "image": "1f1f9-1f1fc.png", 
+        "unicode": "🇹🇼", 
+        "name": "The Republic Of China"
+    }, 
+    ":scorpius:": {
+        "style": "github", 
+        "image": "264f.png", 
+        "unicode": "♏", 
+        "name": "Scorpius"
+    }, 
+    "😜": {
+        "style": "unicode", 
+        "ascii": ">:P", 
+        "image": "1f61c.png", 
+        "name": "Face With Stuck-out Tongue And Winking Eye"
+    }, 
+    "🖱": {
+        "style": "unicode", 
+        "image": "1f5b1.png", 
+        "name": "Three Button Mouse"
+    }, 
+    "🎵": {
+        "style": "unicode", 
+        "image": "1f3b5.png", 
+        "name": "Musical Note"
+    }, 
+    ":dromedary-camel:": {
+        "style": "github", 
+        "image": "1f42a.png", 
+        "unicode": "🐪", 
+        "name": "Dromedary Camel"
+    }, 
+    ":clap-tone4:": {
+        "style": "github", 
+        "image": "1f44f-1f3fe.png", 
+        "unicode": "👏🏾", 
+        "name": "Clapping Hands Sign - Tone 4"
+    }, 
+    ":mantlepiece_clock:": {
+        "style": "github", 
+        "image": "1f570.png", 
+        "unicode": "🕰", 
+        "name": "Mantlepiece Clock"
+    }, 
+    "🍊": {
+        "style": "unicode", 
+        "image": "1f34a.png", 
+        "name": "Tangerine"
+    }, 
+    "📛": {
+        "style": "unicode", 
+        "image": "1f4db.png", 
+        "name": "Name Badge"
+    }, 
+    ":lifter_tone3:": {
+        "style": "github", 
+        "image": "1f3cb-1f3fd.png", 
+        "unicode": "🏋🏽", 
+        "name": "Weight Lifter - Tone 3"
+    }, 
+    ":black-heart:": {
+        "style": "github", 
+        "image": "1f5a4.png", 
+        "unicode": "🖤", 
+        "name": "Black Heart"
+    }, 
+    ":nose_tone4:": {
+        "style": "github", 
+        "image": "1f443-1f3fe.png", 
+        "unicode": "👃🏾", 
+        "name": "Nose - Tone 4"
+    }, 
+    ":door:": {
+        "style": "github", 
+        "image": "1f6aa.png", 
+        "unicode": "🚪", 
+        "name": "Door"
+    }, 
+    ":cop-tone1:": {
+        "style": "github", 
+        "image": "1f46e-1f3fb.png", 
+        "unicode": "👮🏻", 
+        "name": "Police Officer - Tone 1"
+    }, 
+    "👰": {
+        "style": "unicode", 
+        "image": "1f470.png", 
+        "name": "Bride With Veil"
+    }, 
+    ":br:": {
+        "style": "github", 
+        "image": "1f1e7-1f1f7.png", 
+        "unicode": "🇧🇷", 
+        "name": "Brazil"
+    }, 
+    ":sparkles:": {
+        "style": "github", 
+        "image": "2728.png", 
+        "unicode": "✨", 
+        "name": "Sparkles"
+    }, 
+    ":chart_with_upwards_trend:": {
+        "style": "github", 
+        "image": "1f4c8.png", 
+        "unicode": "📈", 
+        "name": "Chart With Upwards Trend"
+    }, 
+    "🏃🏻": {
+        "style": "unicode", 
+        "image": "1f3c3-1f3fb.png", 
+        "name": "Runner - Tone 1"
+    }, 
+    ":clock12:": {
+        "style": "github", 
+        "image": "1f55b.png", 
+        "unicode": "🕛", 
+        "name": "Clock Face Twelve Oclock"
+    }, 
+    ":xk:": {
+        "style": "github", 
+        "image": "1f1fd-1f1f0.png", 
+        "unicode": "🇽🇰", 
+        "name": "Kosovo"
+    }, 
+    "🥙": {
+        "style": "unicode", 
+        "image": "1f959.png", 
+        "name": "Stuffed Flatbread"
+    }, 
+    ":soccer:": {
+        "style": "github", 
+        "image": "26bd.png", 
+        "unicode": "⚽", 
+        "name": "Soccer Ball"
+    }, 
+    "▪": {
+        "style": "unicode", 
+        "image": "25aa.png", 
+        "name": "Black Small Square"
+    }, 
+    ":smirk:": {
+        "style": "github", 
+        "image": "1f60f.png", 
+        "unicode": "😏", 
+        "name": "Smirking Face"
+    }, 
+    ":ok-woman-tone5:": {
+        "style": "github", 
+        "image": "1f646-1f3ff.png", 
+        "unicode": "🙆🏿", 
+        "name": "Face With Ok Gesture Tone5"
+    }, 
+    ":pouting_cat:": {
+        "style": "github", 
+        "image": "1f63e.png", 
+        "unicode": "😾", 
+        "name": "Pouting Cat Face"
+    }, 
+    ":call-me:": {
+        "style": "github", 
+        "image": "1f919.png", 
+        "unicode": "🤙", 
+        "name": "Call Me Hand"
+    }, 
+    "🦃": {
+        "style": "unicode", 
+        "image": "1f983.png", 
+        "name": "Turkey"
+    }, 
+    ":slight-smile:": {
+        "style": "github", 
+        "ascii": ":)", 
+        "image": "1f642.png", 
+        "unicode": "🙂", 
+        "name": "Slightly Smiling Face"
+    }, 
+    ":raised-hand-tone4:": {
+        "style": "github", 
+        "image": "270b-1f3fe.png", 
+        "unicode": "✋🏾", 
+        "name": "Raised Hand - Tone 4"
+    }, 
+    ":handball_tone1:": {
+        "style": "github", 
+        "image": "1f93e-1f3fb.png", 
+        "unicode": "🤾🏻", 
+        "name": "Handball - Tone 1"
+    }, 
+    "🤘": {
+        "style": "unicode", 
+        "image": "1f918.png", 
+        "name": "Sign Of The Horns"
+    }, 
+    ":joystick:": {
+        "style": "github", 
+        "image": "1f579.png", 
+        "unicode": "🕹", 
+        "name": "Joystick"
+    }, 
+    ":flag_vu:": {
+        "style": "github", 
+        "image": "1f1fb-1f1fa.png", 
+        "unicode": "🇻🇺", 
+        "name": "Vanuatu"
+    }, 
+    "👆": {
+        "style": "unicode", 
+        "image": "1f446.png", 
+        "name": "White Up Pointing Backhand Index"
+    }, 
+    ":flag-gf:": {
+        "style": "github", 
+        "image": "1f1ec-1f1eb.png", 
+        "unicode": "🇬🇫", 
+        "name": "French Guiana"
+    }, 
+    ":pregnant_woman_tone5:": {
+        "style": "github", 
+        "image": "1f930-1f3ff.png", 
+        "unicode": "🤰🏿", 
+        "name": "Pregnant Woman - Tone 5"
+    }, 
+    ":pisces:": {
+        "style": "github", 
+        "image": "2653.png", 
+        "unicode": "♓", 
+        "name": "Pisces"
+    }, 
+    "🏟": {
+        "style": "unicode", 
+        "image": "1f3df.png", 
+        "name": "Stadium"
+    }, 
+    ":flag-md:": {
+        "style": "github", 
+        "image": "1f1f2-1f1e9.png", 
+        "unicode": "🇲🇩", 
+        "name": "Moldova"
+    }, 
+    "🕰": {
+        "style": "unicode", 
+        "image": "1f570.png", 
+        "name": "Mantlepiece Clock"
+    }, 
+    ":ok_hand:": {
+        "style": "github", 
+        "image": "1f44c.png", 
+        "unicode": "👌", 
+        "name": "Ok Hand Sign"
+    }, 
+    "🍴": {
+        "style": "unicode", 
+        "image": "1f374.png", 
+        "name": "Fork And Knife"
+    }, 
+    ":haircut_tone5:": {
+        "style": "github", 
+        "image": "1f487-1f3ff.png", 
+        "unicode": "💇🏿", 
+        "name": "Haircut - Tone 5"
+    }, 
+    ":surfer-tone5:": {
+        "style": "github", 
+        "image": "1f3c4-1f3ff.png", 
+        "unicode": "🏄🏿", 
+        "name": "Surfer - Tone 5"
+    }, 
+    ":wavy_dash:": {
+        "style": "github", 
+        "image": "3030.png", 
+        "unicode": "〰", 
+        "name": "Wavy Dash"
+    }, 
+    ":next_track:": {
+        "style": "github", 
+        "image": "23ed.png", 
+        "unicode": "⏭", 
+        "name": "Black Right-pointing Double Triangle With Vertical Bar"
+    }, 
+    ":mrs_claus:": {
+        "style": "github", 
+        "image": "1f936.png", 
+        "unicode": "🤶", 
+        "name": "Mother Christmas"
+    }, 
+    ":hand_with_index_and_middle_fingers_crossed_tone1:": {
+        "style": "github", 
+        "image": "1f91e-1f3fb.png", 
+        "unicode": "🤞🏻", 
+        "name": "Hand With Index And Middle Fingers Crossed - Tone 1"
+    }, 
+    ":alarm-clock:": {
+        "style": "github", 
+        "image": "23f0.png", 
+        "unicode": "⏰", 
+        "name": "Alarm Clock"
+    }, 
+    ":flag-et:": {
+        "style": "github", 
+        "image": "1f1ea-1f1f9.png", 
+        "unicode": "🇪🇹", 
+        "name": "Ethiopia"
+    }, 
+    ":information_desk_person:": {
+        "style": "github", 
+        "image": "1f481.png", 
+        "unicode": "💁", 
+        "name": "Information Desk Person"
+    }, 
+    ":chart:": {
+        "style": "github", 
+        "image": "1f4b9.png", 
+        "unicode": "💹", 
+        "name": "Chart With Upwards Trend And Yen Sign"
+    }, 
+    ":pray_tone4:": {
+        "style": "github", 
+        "image": "1f64f-1f3fe.png", 
+        "unicode": "🙏🏾", 
+        "name": "Person With Folded Hands - Tone 4"
+    }, 
+    "🇿🇼": {
+        "style": "unicode", 
+        "image": "1f1ff-1f1fc.png", 
+        "name": "Zimbabwe"
+    }, 
+    "🇿🇲": {
+        "style": "unicode", 
+        "image": "1f1ff-1f1f2.png", 
+        "name": "Zambia"
+    }, 
+    ":expecting_woman_tone3:": {
+        "style": "github", 
+        "image": "1f930-1f3fd.png", 
+        "unicode": "🤰🏽", 
+        "name": "Pregnant Woman - Tone 3"
+    }, 
+    ":flag_gs:": {
+        "style": "github", 
+        "image": "1f1ec-1f1f8.png", 
+        "unicode": "🇬🇸", 
+        "name": "South Georgia"
+    }, 
+    ":currency_exchange:": {
+        "style": "github", 
+        "image": "1f4b1.png", 
+        "unicode": "💱", 
+        "name": "Currency Exchange"
+    }, 
+    ":flag_ne:": {
+        "style": "github", 
+        "image": "1f1f3-1f1ea.png", 
+        "unicode": "🇳🇪", 
+        "name": "Niger"
+    }, 
+    "🇿🇦": {
+        "style": "unicode", 
+        "image": "1f1ff-1f1e6.png", 
+        "name": "South Africa"
+    }, 
+    ":closed-lock-with-key:": {
+        "style": "github", 
+        "image": "1f510.png", 
+        "unicode": "🔐", 
+        "name": "Closed Lock With Key"
+    }, 
+    ":martial-arts-uniform:": {
+        "style": "github", 
+        "image": "1f94b.png", 
+        "unicode": "🥋", 
+        "name": "Martial Arts Uniform"
+    }, 
+    ":cloud_with_tornado:": {
+        "style": "github", 
+        "image": "1f32a.png", 
+        "unicode": "🌪", 
+        "name": "Cloud With Tornado"
+    }, 
+    "💇": {
+        "style": "unicode", 
+        "image": "1f487.png", 
+        "name": "Haircut"
+    }, 
+    ":person-with-blond-hair-tone3:": {
+        "style": "github", 
+        "image": "1f471-1f3fd.png", 
+        "unicode": "👱🏽", 
+        "name": "Person With Blond Hair - Tone 3"
+    }, 
+    ":wave:": {
+        "style": "github", 
+        "image": "1f44b.png", 
+        "unicode": "👋", 
+        "name": "Waving Hand Sign"
+    }, 
+    "↕": {
+        "style": "unicode", 
+        "image": "2195.png", 
+        "name": "Up Down Arrow"
+    }, 
+    ":tumbler_glass:": {
+        "style": "github", 
+        "image": "1f943.png", 
+        "unicode": "🥃", 
+        "name": "Tumbler Glass"
+    }, 
+    "🐜": {
+        "style": "unicode", 
+        "image": "1f41c.png", 
+        "name": "Ant"
+    }, 
+    ":wrestlers_tone5:": {
+        "style": "github", 
+        "image": "1f93c-1f3ff.png", 
+        "unicode": "🤼🏿", 
+        "name": "Wrestlers - Tone 5"
+    }, 
+    ":-þ": {
+        "style": "ascii", 
+        "ascii": ":P", 
+        "image": "1f61b.png", 
+        "unicode": "😛", 
+        "name": "Face With Stuck-out Tongue"
+    }, 
+    ":shopping_bags:": {
+        "style": "github", 
+        "image": "1f6cd.png", 
+        "unicode": "🛍", 
+        "name": "Shopping Bags"
+    }, 
+    ":regional-indicator-w:": {
+        "style": "github", 
+        "image": "1f1fc.png", 
+        "unicode": "🇼", 
+        "name": "Regional Indicator Symbol Letter W"
+    }, 
+    ":mrs-claus-tone1:": {
+        "style": "github", 
+        "image": "1f936-1f3fb.png", 
+        "unicode": "🤶🏻", 
+        "name": "Mother Christmas - Tone 1"
+    }, 
+    "👦🏻": {
+        "style": "unicode", 
+        "image": "1f466-1f3fb.png", 
+        "name": "Boy - Tone 1"
+    }, 
+    "👦🏼": {
+        "style": "unicode", 
+        "image": "1f466-1f3fc.png", 
+        "name": "Boy - Tone 2"
+    }, 
+    "👦🏽": {
+        "style": "unicode", 
+        "image": "1f466-1f3fd.png", 
+        "name": "Boy - Tone 3"
+    }, 
+    "👦🏾": {
+        "style": "unicode", 
+        "image": "1f466-1f3fe.png", 
+        "name": "Boy - Tone 4"
+    }, 
+    ":white-square-button:": {
+        "style": "github", 
+        "image": "1f533.png", 
+        "unicode": "🔳", 
+        "name": "White Square Button"
+    }, 
+    "♐": {
+        "style": "unicode", 
+        "image": "2650.png", 
+        "name": "Sagittarius"
+    }, 
+    ":lying-face:": {
+        "style": "github", 
+        "image": "1f925.png", 
+        "unicode": "🤥", 
+        "name": "Lying Face"
+    }, 
+    "⏩": {
+        "style": "unicode", 
+        "image": "23e9.png", 
+        "name": "Black Right-pointing Double Triangle"
+    }, 
+    ":diamonds:": {
+        "style": "github", 
+        "image": "2666.png", 
+        "unicode": "♦", 
+        "name": "Black Diamond Suit"
+    }, 
+    ":left-facing-fist-tone2:": {
+        "style": "github", 
+        "image": "1f91b-1f3fc.png", 
+        "unicode": "🤛🏼", 
+        "name": "Left Facing Fist - Tone 2"
+    }, 
+    ":pt:": {
+        "style": "github", 
+        "image": "1f1f5-1f1f9.png", 
+        "unicode": "🇵🇹", 
+        "name": "Portugal"
+    }, 
+    ":point_up_tone4:": {
+        "style": "github", 
+        "image": "261d-1f3fe.png", 
+        "unicode": "☝🏾", 
+        "name": "White Up Pointing Index - Tone 4"
+    }, 
+    ":point_down_tone5:": {
+        "style": "github", 
+        "image": "1f447-1f3ff.png", 
+        "unicode": "👇🏿", 
+        "name": "White Down Pointing Backhand Index - Tone 5"
+    }, 
+    ":juggling-tone5:": {
+        "style": "github", 
+        "image": "1f939-1f3ff.png", 
+        "unicode": "🤹🏿", 
+        "name": "Juggling - Tone 5"
+    }, 
+    ":-O": {
+        "style": "ascii", 
+        "ascii": ":-O", 
+        "image": "1f62e.png", 
+        "unicode": "😮", 
+        "name": "Face With Open Mouth"
+    }, 
+    "🌉": {
+        "style": "unicode", 
+        "image": "1f309.png", 
+        "name": "Bridge At Night"
+    }, 
+    ":-D": {
+        "style": "ascii", 
+        "ascii": ":D", 
+        "image": "1f603.png", 
+        "unicode": "😃", 
+        "name": "Smiling Face With Open Mouth"
+    }, 
+    ":-[": {
+        "style": "ascii", 
+        "ascii": ">:[", 
+        "image": "1f61e.png", 
+        "unicode": "😞", 
+        "name": "Disappointed Face"
+    }, 
+    ":-X": {
+        "style": "ascii", 
+        "ascii": ":-X", 
+        "image": "1f636.png", 
+        "unicode": "😶", 
+        "name": "Face Without Mouth"
+    }, 
+    ":full_moon:": {
+        "style": "github", 
+        "image": "1f315.png", 
+        "unicode": "🌕", 
+        "name": "Full Moon Symbol"
+    }, 
+    ":-P": {
+        "style": "ascii", 
+        "ascii": ":P", 
+        "image": "1f61b.png", 
+        "unicode": "😛", 
+        "name": "Face With Stuck-out Tongue"
+    }, 
+    "🎞": {
+        "style": "unicode", 
+        "image": "1f39e.png", 
+        "name": "Film Frames"
+    }, 
+    ":-o": {
+        "style": "ascii", 
+        "ascii": ":-O", 
+        "image": "1f62e.png", 
+        "unicode": "😮", 
+        "name": "Face With Open Mouth"
+    }, 
+    ":-b": {
+        "style": "ascii", 
+        "ascii": ":P", 
+        "image": "1f61b.png", 
+        "unicode": "😛", 
+        "name": "Face With Stuck-out Tongue"
+    }, 
+    ":goal:": {
+        "style": "github", 
+        "image": "1f945.png", 
+        "unicode": "🥅", 
+        "name": "Goal Net"
+    }, 
+    ":-x": {
+        "style": "ascii", 
+        "ascii": ":-X", 
+        "image": "1f636.png", 
+        "unicode": "😶", 
+        "name": "Face Without Mouth"
+    }, 
+    ":sparkling-heart:": {
+        "style": "github", 
+        "image": "1f496.png", 
+        "unicode": "💖", 
+        "name": "Sparkling Heart"
+    }, 
+    ":construction_worker_tone3:": {
+        "style": "github", 
+        "image": "1f477-1f3fd.png", 
+        "unicode": "👷🏽", 
+        "name": "Construction Worker - Tone 3"
+    }, 
+    ":-p": {
+        "style": "ascii", 
+        "ascii": ":P", 
+        "image": "1f61b.png", 
+        "unicode": "😛", 
+        "name": "Face With Stuck-out Tongue"
+    }, 
+    ":ping_pong:": {
+        "style": "github", 
+        "image": "1f3d3.png", 
+        "unicode": "🏓", 
+        "name": "Table Tennis Paddle And Ball"
+    }, 
+    ":earth_americas:": {
+        "style": "github", 
+        "image": "1f30e.png", 
+        "unicode": "🌎", 
+        "name": "Earth Globe Americas"
+    }, 
+    ":raised_hand_with_part_between_middle_and_ring_fingers_tone5:": {
+        "style": "github", 
+        "image": "1f596-1f3ff.png", 
+        "unicode": "🖖🏿", 
+        "name": "Raised Hand With Part Between Middle And Ring Fingers - Tone 5"
+    }, 
+    ":mute:": {
+        "style": "github", 
+        "image": "1f507.png", 
+        "unicode": "🔇", 
+        "name": "Speaker With Cancellation Stroke"
+    }, 
+    ":person-frowning-tone1:": {
+        "style": "github", 
+        "image": "1f64d-1f3fb.png", 
+        "unicode": "🙍🏻", 
+        "name": "Person Frowning - Tone 1"
+    }, 
+    "🕝": {
+        "style": "unicode", 
+        "image": "1f55d.png", 
+        "name": "Clock Face Two-thirty"
+    }, 
+    ":-*": {
+        "style": "ascii", 
+        "ascii": ":*", 
+        "image": "1f618.png", 
+        "unicode": "😘", 
+        "name": "Face Throwing A Kiss"
+    }, 
+    ":candle:": {
+        "style": "github", 
+        "image": "1f56f.png", 
+        "unicode": "🕯", 
+        "name": "Candle"
+    }, 
+    ":-(": {
+        "style": "ascii", 
+        "ascii": ">:[", 
+        "image": "1f61e.png", 
+        "unicode": "😞", 
+        "name": "Disappointed Face"
+    }, 
+    ":-)": {
+        "style": "ascii", 
+        "ascii": ":)", 
+        "image": "1f642.png", 
+        "unicode": "🙂", 
+        "name": "Slightly Smiling Face"
+    }, 
+    ":-.": {
+        "style": "ascii", 
+        "ascii": ">:\\", 
+        "image": "1f615.png", 
+        "unicode": "😕", 
+        "name": "Confused Face"
+    }, 
+    ":-/": {
+        "style": "ascii", 
+        "ascii": ">:\\", 
+        "image": "1f615.png", 
+        "unicode": "😕", 
+        "name": "Confused Face"
+    }, 
+    ":-#": {
+        "style": "ascii", 
+        "ascii": ":-X", 
+        "image": "1f636.png", 
+        "unicode": "😶", 
+        "name": "Face Without Mouth"
+    }, 
+    ":regional_indicator_o:": {
+        "style": "github", 
+        "image": "1f1f4.png", 
+        "unicode": "🇴", 
+        "name": "Regional Indicator Symbol Letter O"
+    }, 
+    "🖇": {
+        "style": "unicode", 
+        "image": "1f587.png", 
+        "name": "Linked Paperclips"
+    }, 
+    ":flag-kg:": {
+        "style": "github", 
+        "image": "1f1f0-1f1ec.png", 
+        "unicode": "🇰🇬", 
+        "name": "Kyrgyzstan"
+    }, 
+    ":la:": {
+        "style": "github", 
+        "image": "1f1f1-1f1e6.png", 
+        "unicode": "🇱🇦", 
+        "name": "Laos"
+    }, 
+    ":pk:": {
+        "style": "github", 
+        "image": "1f1f5-1f1f0.png", 
+        "unicode": "🇵🇰", 
+        "name": "Pakistan"
+    }, 
+    ":black_medium_small_square:": {
+        "style": "github", 
+        "image": "25fe.png", 
+        "unicode": "◾", 
+        "name": "Black Medium Small Square"
+    }, 
+    ":diamond_shape_with_a_dot_inside:": {
+        "style": "github", 
+        "image": "1f4a0.png", 
+        "unicode": "💠", 
+        "name": "Diamond Shape With A Dot Inside"
+    }, 
+    "8)": {
+        "style": "ascii", 
+        "ascii": "B-)", 
+        "image": "1f60e.png", 
+        "unicode": "😎", 
+        "name": "Smiling Face With Sunglasses"
+    }, 
+    "🔜": {
+        "style": "unicode", 
+        "image": "1f51c.png", 
+        "name": "Soon With Rightwards Arrow Above"
+    }, 
+    ":flag_cn:": {
+        "style": "github", 
+        "image": "1f1e8-1f1f3.png", 
+        "unicode": "🇨🇳", 
+        "name": "China"
+    }, 
+    ":wheelchair:": {
+        "style": "github", 
+        "image": "267f.png", 
+        "unicode": "♿", 
+        "name": "Wheelchair Symbol"
+    }, 
+    "☦": {
+        "style": "unicode", 
+        "image": "2626.png", 
+        "name": "Orthodox Cross"
+    }, 
+    ":urn:": {
+        "style": "github", 
+        "image": "26b1.png", 
+        "unicode": "⚱", 
+        "name": "Funeral Urn"
+    }, 
+    "🚱": {
+        "style": "unicode", 
+        "image": "1f6b1.png", 
+        "name": "Non-potable Water Symbol"
+    }, 
+    ":v:": {
+        "style": "github", 
+        "image": "270c.png", 
+        "unicode": "✌", 
+        "name": "Victory Hand"
+    }, 
+    ":santa-tone1:": {
+        "style": "github", 
+        "image": "1f385-1f3fb.png", 
+        "unicode": "🎅🏻", 
+        "name": "Father Christmas - Tone 1"
+    }, 
+    "🙆": {
+        "style": "unicode", 
+        "ascii": "*\\0/*", 
+        "image": "1f646.png", 
+        "name": "Face With Ok Gesture"
+    }, 
+    ":lower_left_crayon:": {
+        "style": "github", 
+        "image": "1f58d.png", 
+        "unicode": "🖍", 
+        "name": "Lower Left Crayon"
+    }, 
+    ":md:": {
+        "style": "github", 
+        "image": "1f1f2-1f1e9.png", 
+        "unicode": "🇲🇩", 
+        "name": "Moldova"
+    }, 
+    ":egg:": {
+        "style": "github", 
+        "image": "1f95a.png", 
+        "unicode": "🥚", 
+        "name": "Egg"
+    }, 
+    ":flag_ma:": {
+        "style": "github", 
+        "image": "1f1f2-1f1e6.png", 
+        "unicode": "🇲🇦", 
+        "name": "Morocco"
+    }, 
+    ":punch_tone5:": {
+        "style": "github", 
+        "image": "1f44a-1f3ff.png", 
+        "unicode": "👊🏿", 
+        "name": "Fisted Hand Sign - Tone 5"
+    }, 
+    ":flag_bd:": {
+        "style": "github", 
+        "image": "1f1e7-1f1e9.png", 
+        "unicode": "🇧🇩", 
+        "name": "Bangladesh"
+    }, 
+    "✊🏿": {
+        "style": "unicode", 
+        "image": "270a-1f3ff.png", 
+        "name": "Raised Fist - Tone 5"
+    }, 
+    "0:-3": {
+        "style": "ascii", 
+        "ascii": "O:-)", 
+        "image": "1f607.png", 
+        "unicode": "😇", 
+        "name": "Smiling Face With Halo"
+    }, 
+    ":in:": {
+        "style": "github", 
+        "image": "1f1ee-1f1f3.png", 
+        "unicode": "🇮🇳", 
+        "name": "India"
+    }, 
+    ":open_hands_tone5:": {
+        "style": "github", 
+        "image": "1f450-1f3ff.png", 
+        "unicode": "👐🏿", 
+        "name": "Open Hands Sign - Tone 5"
+    }, 
+    "0:-)": {
+        "style": "ascii", 
+        "ascii": "O:-)", 
+        "image": "1f607.png", 
+        "unicode": "😇", 
+        "name": "Smiling Face With Halo"
+    }, 
+    ":flag-cw:": {
+        "style": "github", 
+        "image": "1f1e8-1f1fc.png", 
+        "unicode": "🇨🇼", 
+        "name": "Curaçao"
+    }, 
+    ":metal_tone2:": {
+        "style": "github", 
+        "image": "1f918-1f3fc.png", 
+        "unicode": "🤘🏼", 
+        "name": "Sign Of The Horns - Tone 2"
+    }, 
+    ":drum:": {
+        "style": "github", 
+        "image": "1f941.png", 
+        "unicode": "🥁", 
+        "name": "Drum With Drumsticks"
+    }, 
+    "🏈": {
+        "style": "unicode", 
+        "image": "1f3c8.png", 
+        "name": "American Football"
+    }, 
+    ":poultry_leg:": {
+        "style": "github", 
+        "image": "1f357.png", 
+        "unicode": "🍗", 
+        "name": "Poultry Leg"
+    }, 
+    ":slight_frown:": {
+        "style": "github", 
+        "image": "1f641.png", 
+        "unicode": "🙁", 
+        "name": "Slightly Frowning Face"
+    }, 
+    "👝": {
+        "style": "unicode", 
+        "image": "1f45d.png", 
+        "name": "Pouch"
+    }, 
+    ":mountain:": {
+        "style": "github", 
+        "image": "26f0.png", 
+        "unicode": "⛰", 
+        "name": "Mountain"
+    }, 
+    ":notebook_with_decorative_cover:": {
+        "style": "github", 
+        "image": "1f4d4.png", 
+        "unicode": "📔", 
+        "name": "Notebook With Decorative Cover"
+    }, 
+    ":information_source:": {
+        "style": "github", 
+        "image": "2139.png", 
+        "unicode": "ℹ", 
+        "name": "Information Source"
+    }, 
+    "📲": {
+        "style": "unicode", 
+        "image": "1f4f2.png", 
+        "name": "Mobile Phone With Rightwards Arrow At Left"
+    }, 
+    ":flag-au:": {
+        "style": "github", 
+        "image": "1f1e6-1f1fa.png", 
+        "unicode": "🇦🇺", 
+        "name": "Australia"
+    }, 
+    ":thumbsdown_tone1:": {
+        "style": "github", 
+        "image": "1f44e-1f3fb.png", 
+        "unicode": "👎🏻", 
+        "name": "Thumbs Down Sign - Tone 1"
+    }, 
+    ":flag-jo:": {
+        "style": "github", 
+        "image": "1f1ef-1f1f4.png", 
+        "unicode": "🇯🇴", 
+        "name": "Jordan"
+    }, 
+    "◼": {
+        "style": "unicode", 
+        "image": "25fc.png", 
+        "name": "Black Medium Square"
+    }, 
+    ":flag_sk:": {
+        "style": "github", 
+        "image": "1f1f8-1f1f0.png", 
+        "unicode": "🇸🇰", 
+        "name": "Slovakia"
+    }, 
+    ":er:": {
+        "style": "github", 
+        "image": "1f1ea-1f1f7.png", 
+        "unicode": "🇪🇷", 
+        "name": "Eritrea"
+    }, 
+    ":microscope:": {
+        "style": "github", 
+        "image": "1f52c.png", 
+        "unicode": "🔬", 
+        "name": "Microscope"
+    }, 
+    "🤳🏻": {
+        "style": "unicode", 
+        "image": "1f933-1f3fb.png", 
+        "name": "Selfie - Tone 1"
+    }, 
+    ":flag-bo:": {
+        "style": "github", 
+        "image": "1f1e7-1f1f4.png", 
+        "unicode": "🇧🇴", 
+        "name": "Bolivia"
+    }, 
+    "🤳🏿": {
+        "style": "unicode", 
+        "image": "1f933-1f3ff.png", 
+        "name": "Selfie - Tone 5"
+    }, 
+    "🤳🏾": {
+        "style": "unicode", 
+        "image": "1f933-1f3fe.png", 
+        "name": "Selfie - Tone 4"
+    }, 
+    "🤳🏽": {
+        "style": "unicode", 
+        "image": "1f933-1f3fd.png", 
+        "name": "Selfie - Tone 3"
+    }, 
+    "🤳🏼": {
+        "style": "unicode", 
+        "image": "1f933-1f3fc.png", 
+        "name": "Selfie - Tone 2"
+    }, 
+    ":reversed_hand_with_middle_finger_extended_tone4:": {
+        "style": "github", 
+        "image": "1f595-1f3fe.png", 
+        "unicode": "🖕🏾", 
+        "name": "Reversed Hand With Middle Finger Extended - Tone 4"
+    }, 
+    ":massage_tone2:": {
+        "style": "github", 
+        "image": "1f486-1f3fc.png", 
+        "unicode": "💆🏼", 
+        "name": "Face Massage - Tone 2"
+    }, 
+    ":flag-bv:": {
+        "style": "github", 
+        "image": "1f1e7-1f1fb.png", 
+        "unicode": "🇧🇻", 
+        "name": "Bouvet Island"
+    }, 
+    ":light_rail:": {
+        "style": "github", 
+        "image": "1f688.png", 
+        "unicode": "🚈", 
+        "name": "Light Rail"
+    }, 
+    ":pause-button:": {
+        "style": "github", 
+        "image": "23f8.png", 
+        "unicode": "⏸", 
+        "name": "Double Vertical Bar"
+    }, 
+    ":flag-ye:": {
+        "style": "github", 
+        "image": "1f1fe-1f1ea.png", 
+        "unicode": "🇾🇪", 
+        "name": "Yemen"
+    }, 
+    ":hammer_and_pick:": {
+        "style": "github", 
+        "image": "2692.png", 
+        "unicode": "⚒", 
+        "name": "Hammer And Pick"
+    }, 
+    "🛏": {
+        "style": "unicode", 
+        "image": "1f6cf.png", 
+        "name": "Bed"
+    }, 
+    ":family-wwbb:": {
+        "style": "github", 
+        "image": "1f469-1f469-1f466-1f466.png", 
+        "unicode": "👩👩👦👦", 
+        "name": "Family (woman,woman,boy,boy)"
+    }, 
+    ":dizzy-face:": {
+        "style": "github", 
+        "ascii": "#-)", 
+        "image": "1f635.png", 
+        "unicode": "😵", 
+        "name": "Dizzy Face"
+    }, 
+    ":mailbox_with_mail:": {
+        "style": "github", 
+        "image": "1f4ec.png", 
+        "unicode": "📬", 
+        "name": "Open Mailbox With Raised Flag"
+    }, 
+    ":flag_kh:": {
+        "style": "github", 
+        "image": "1f1f0-1f1ed.png", 
+        "unicode": "🇰🇭", 
+        "name": "Cambodia"
+    }, 
+    ":call_me_tone5:": {
+        "style": "github", 
+        "image": "1f919-1f3ff.png", 
+        "unicode": "🤙🏿", 
+        "name": "Call Me Hand - Tone 5"
+    }, 
+    ":bottle_with_popping_cork:": {
+        "style": "github", 
+        "image": "1f37e.png", 
+        "unicode": "🍾", 
+        "name": "Bottle With Popping Cork"
+    }, 
+    "🐣": {
+        "style": "unicode", 
+        "image": "1f423.png", 
+        "name": "Hatching Chick"
+    }, 
+    ":open-hands-tone2:": {
+        "style": "github", 
+        "image": "1f450-1f3fc.png", 
+        "unicode": "👐🏼", 
+        "name": "Open Hands Sign - Tone 2"
+    }, 
+    ":pray:": {
+        "style": "github", 
+        "image": "1f64f.png", 
+        "unicode": "🙏", 
+        "name": "Person With Folded Hands"
+    }, 
+    ":flag-nc:": {
+        "style": "github", 
+        "image": "1f1f3-1f1e8.png", 
+        "unicode": "🇳🇨", 
+        "name": "New Caledonia"
+    }, 
+    ":wave-tone1:": {
+        "style": "github", 
+        "image": "1f44b-1f3fb.png", 
+        "unicode": "👋🏻", 
+        "name": "Waving Hand Sign - Tone 1"
+    }, 
+    "💸": {
+        "style": "unicode", 
+        "image": "1f4b8.png", 
+        "name": "Money With Wings"
+    }, 
+    ":punch-tone1:": {
+        "style": "github", 
+        "image": "1f44a-1f3fb.png", 
+        "unicode": "👊🏻", 
+        "name": "Fisted Hand Sign - Tone 1"
+    }, 
+    "🇻🇳": {
+        "style": "unicode", 
+        "image": "1f1fb-1f1f3.png", 
+        "name": "Vietnam"
+    }, 
+    "🇻🇺": {
+        "style": "unicode", 
+        "image": "1f1fb-1f1fa.png", 
+        "name": "Vanuatu"
+    }, 
+    ":rs:": {
+        "style": "github", 
+        "image": "1f1f7-1f1f8.png", 
+        "unicode": "🇷🇸", 
+        "name": "Serbia"
+    }, 
+    "🍍": {
+        "style": "unicode", 
+        "image": "1f34d.png", 
+        "name": "Pineapple"
+    }, 
+    "🥑": {
+        "style": "unicode", 
+        "image": "1f951.png", 
+        "name": "Avocado"
+    }, 
+    ":nose_tone2:": {
+        "style": "github", 
+        "image": "1f443-1f3fc.png", 
+        "unicode": "👃🏼", 
+        "name": "Nose - Tone 2"
+    }, 
+    "🇻🇦": {
+        "style": "unicode", 
+        "image": "1f1fb-1f1e6.png", 
+        "name": "The Vatican City"
+    }, 
+    ":flag-py:": {
+        "style": "github", 
+        "image": "1f1f5-1f1fe.png", 
+        "unicode": "🇵🇾", 
+        "name": "Paraguay"
+    }, 
+    "🇻🇪": {
+        "style": "unicode", 
+        "image": "1f1fb-1f1ea.png", 
+        "name": "Venezuela"
+    }, 
+    "🇻🇨": {
+        "style": "unicode", 
+        "image": "1f1fb-1f1e8.png", 
+        "name": "Saint Vincent And The Grenadines"
+    }, 
+    "🇻🇮": {
+        "style": "unicode", 
+        "image": "1f1fb-1f1ee.png", 
+        "name": "U.s. Virgin Islands"
+    }, 
+    ":closed-umbrella:": {
+        "style": "github", 
+        "image": "1f302.png", 
+        "unicode": "🌂", 
+        "name": "Closed Umbrella"
+    }, 
+    "🇻🇬": {
+        "style": "unicode", 
+        "image": "1f1fb-1f1ec.png", 
+        "name": "British Virgin Islands"
+    }, 
+    "🏢": {
+        "style": "unicode", 
+        "image": "1f3e2.png", 
+        "name": "Office Building"
+    }, 
+    ">:-)": {
+        "style": "ascii", 
+        "ascii": ">:)", 
+        "image": "1f606.png", 
+        "unicode": "😆", 
+        "name": "Smiling Face With Open Mouth And Tightly-closed Eyes"
+    }, 
+    ">:-(": {
+        "style": "ascii", 
+        "ascii": ">:(", 
+        "image": "1f620.png", 
+        "unicode": "😠", 
+        "name": "Angry Face"
+    }, 
+    ":sleuth_or_spy_tone4:": {
+        "style": "github", 
+        "image": "1f575-1f3fe.png", 
+        "unicode": "🕵🏾", 
+        "name": "Sleuth Or Spy - Tone 4"
+    }, 
+    ":see_no_evil:": {
+        "style": "github", 
+        "image": "1f648.png", 
+        "unicode": "🙈", 
+        "name": "See-no-evil Monkey"
+    }, 
+    ":sports_medal:": {
+        "style": "github", 
+        "image": "1f3c5.png", 
+        "unicode": "🏅", 
+        "name": "Sports Medal"
+    }, 
+    ":-1_tone1:": {
+        "style": "github", 
+        "image": "1f44e-1f3fb.png", 
+        "unicode": "👎🏻", 
+        "name": "Thumbs Down Sign - Tone 1"
+    }, 
+    "🌌": {
+        "style": "unicode", 
+        "image": "1f30c.png", 
+        "name": "Milky Way"
+    }, 
+    ":paw_prints:": {
+        "style": "github", 
+        "image": "1f43e.png", 
+        "unicode": "🐾", 
+        "name": "Paw Prints"
+    }, 
+    ":pudding:": {
+        "style": "github", 
+        "image": "1f36e.png", 
+        "unicode": "🍮", 
+        "name": "Custard"
+    }, 
+    "🚥": {
+        "style": "unicode", 
+        "image": "1f6a5.png", 
+        "name": "Horizontal Traffic Light"
+    }, 
+    ":ear_tone4:": {
+        "style": "github", 
+        "image": "1f442-1f3fe.png", 
+        "unicode": "👂🏾", 
+        "name": "Ear - Tone 4"
+    }, 
+    "😺": {
+        "style": "unicode", 
+        "image": "1f63a.png", 
+        "name": "Smiling Cat Face With Open Mouth"
+    }, 
+    "⛅": {
+        "style": "unicode", 
+        "image": "26c5.png", 
+        "name": "Sun Behind Cloud"
+    }, 
+    ":new-moon-with-face:": {
+        "style": "github", 
+        "image": "1f31a.png", 
+        "unicode": "🌚", 
+        "name": "New Moon With Face"
+    }, 
+    ":clock10:": {
+        "style": "github", 
+        "image": "1f559.png", 
+        "unicode": "🕙", 
+        "name": "Clock Face Ten Oclock"
+    }, 
+    ":panda_face:": {
+        "style": "github", 
+        "image": "1f43c.png", 
+        "unicode": "🐼", 
+        "name": "Panda Face"
+    }, 
+    ":tulip:": {
+        "style": "github", 
+        "image": "1f337.png", 
+        "unicode": "🌷", 
+        "name": "Tulip"
+    }, 
+    ":ok-woman-tone3:": {
+        "style": "github", 
+        "image": "1f646-1f3fd.png", 
+        "unicode": "🙆🏽", 
+        "name": "Face With Ok Gesture Tone3"
+    }, 
+    "📹": {
+        "style": "unicode", 
+        "image": "1f4f9.png", 
+        "name": "Video Camera"
+    }, 
+    ":lifter-tone5:": {
+        "style": "github", 
+        "image": "1f3cb-1f3ff.png", 
+        "unicode": "🏋🏿", 
+        "name": "Weight Lifter - Tone 5"
+    }, 
+    ":family-wwgg:": {
+        "style": "github", 
+        "image": "1f469-1f469-1f467-1f467.png", 
+        "unicode": "👩👩👧👧", 
+        "name": "Family (woman,woman,girl,girl)"
+    }, 
+    "💎": {
+        "style": "unicode", 
+        "image": "1f48e.png", 
+        "name": "Gem Stone"
+    }, 
+    ":train2:": {
+        "style": "github", 
+        "image": "1f686.png", 
+        "unicode": "🚆", 
+        "name": "Train"
+    }, 
+    "👨👩👧👦": {
+        "style": "unicode", 
+        "image": "1f468-1f469-1f467-1f466.png", 
+        "name": "Family (man,woman,girl,boy)"
+    }, 
+    "👨👩👧👧": {
+        "style": "unicode", 
+        "image": "1f468-1f469-1f467-1f467.png", 
+        "name": "Family (man,woman,girl,girl)"
+    }, 
+    "🔣": {
+        "style": "unicode", 
+        "image": "1f523.png", 
+        "name": "Input Symbol For Symbols"
+    }, 
+    ":walking-tone2:": {
+        "style": "github", 
+        "image": "1f6b6-1f3fc.png", 
+        "unicode": "🚶🏼", 
+        "name": "Pedestrian - Tone 2"
+    }, 
+    ":baby_bottle:": {
+        "style": "github", 
+        "image": "1f37c.png", 
+        "unicode": "🍼", 
+        "name": "Baby Bottle"
+    }, 
+    ":bellhop:": {
+        "style": "github", 
+        "image": "1f6ce.png", 
+        "unicode": "🛎", 
+        "name": "Bellhop Bell"
+    }, 
+    "🚊": {
+        "style": "unicode", 
+        "image": "1f68a.png", 
+        "name": "Tram"
+    }, 
+    ":flag-us:": {
+        "style": "github", 
+        "image": "1f1fa-1f1f8.png", 
+        "unicode": "🇺🇸", 
+        "name": "United States"
+    }, 
+    ":pregnant_woman_tone3:": {
+        "style": "github", 
+        "image": "1f930-1f3fd.png", 
+        "unicode": "🤰🏽", 
+        "name": "Pregnant Woman - Tone 3"
+    }, 
+    ":flag-gh:": {
+        "style": "github", 
+        "image": "1f1ec-1f1ed.png", 
+        "unicode": "🇬🇭", 
+        "name": "Ghana"
+    }, 
+    ":wink:": {
+        "style": "github", 
+        "ascii": ";)", 
+        "image": "1f609.png", 
+        "unicode": "😉", 
+        "name": "Winking Face"
+    }, 
+    ":haircut_tone3:": {
+        "style": "github", 
+        "image": "1f487-1f3fd.png", 
+        "unicode": "💇🏽", 
+        "name": "Haircut - Tone 3"
+    }, 
+    ":clap_tone2:": {
+        "style": "github", 
+        "image": "1f44f-1f3fc.png", 
+        "unicode": "👏🏼", 
+        "name": "Clapping Hands Sign - Tone 2"
+    }, 
+    "🍷": {
+        "style": "unicode", 
+        "image": "1f377.png", 
+        "name": "Wine Glass"
+    }, 
+    ":point-right-tone5:": {
+        "style": "github", 
+        "image": "1f449-1f3ff.png", 
+        "unicode": "👉🏿", 
+        "name": "White Right Pointing Backhand Index - Tone 5"
+    }, 
+    ":surfer_tone3:": {
+        "style": "github", 
+        "image": "1f3c4-1f3fd.png", 
+        "unicode": "🏄🏽", 
+        "name": "Surfer - Tone 3"
+    }, 
+    ":telescope:": {
+        "style": "github", 
+        "image": "1f52d.png", 
+        "unicode": "🔭", 
+        "name": "Telescope"
+    }, 
+    "⬆": {
+        "style": "unicode", 
+        "image": "2b06.png", 
+        "name": "Upwards Black Arrow"
+    }, 
+    ":no_good:": {
+        "style": "github", 
+        "image": "1f645.png", 
+        "unicode": "🙅", 
+        "name": "Face With No Good Gesture"
+    }, 
+    ":calling:": {
+        "style": "github", 
+        "image": "1f4f2.png", 
+        "unicode": "📲", 
+        "name": "Mobile Phone With Rightwards Arrow At Left"
+    }, 
+    ":right-facing-fist-tone4:": {
+        "style": "github", 
+        "image": "1f91c-1f3fe.png", 
+        "unicode": "🤜🏾", 
+        "name": "Right Facing Fist - Tone 4"
+    }, 
+    ":hand_with_index_and_middle_fingers_crossed_tone3:": {
+        "style": "github", 
+        "image": "1f91e-1f3fd.png", 
+        "unicode": "🤞🏽", 
+        "name": "Hand With Index And Middle Fingers Crossed - Tone 3"
+    }, 
+    ":page_with_curl:": {
+        "style": "github", 
+        "image": "1f4c3.png", 
+        "unicode": "📃", 
+        "name": "Page With Curl"
+    }, 
+    ":blue_heart:": {
+        "style": "github", 
+        "image": "1f499.png", 
+        "unicode": "💙", 
+        "name": "Blue Heart"
+    }, 
+    "🎡": {
+        "style": "unicode", 
+        "image": "1f3a1.png", 
+        "name": "Ferris Wheel"
+    }, 
+    "🖥": {
+        "style": "unicode", 
+        "image": "1f5a5.png", 
+        "name": "Desktop Computer"
+    }, 
+    ":mountain_bicyclist_tone2:": {
+        "style": "github", 
+        "image": "1f6b5-1f3fc.png", 
+        "unicode": "🚵🏼", 
+        "name": "Mountain Bicyclist - Tone 2"
+    }, 
+    ":za:": {
+        "style": "github", 
+        "image": "1f1ff-1f1e6.png", 
+        "unicode": "🇿🇦", 
+        "name": "South Africa"
+    }, 
+    ":man_with_turban:": {
+        "style": "github", 
+        "image": "1f473.png", 
+        "unicode": "👳", 
+        "name": "Man With Turban"
+    }, 
+    ":triangular_flag_on_post:": {
+        "style": "github", 
+        "image": "1f6a9.png", 
+        "unicode": "🚩", 
+        "name": "Triangular Flag On Post"
+    }, 
+    ":oncoming_taxi:": {
+        "style": "github", 
+        "image": "1f696.png", 
+        "unicode": "🚖", 
+        "name": "Oncoming Taxi"
+    }, 
+    ":shaved-ice:": {
+        "style": "github", 
+        "image": "1f367.png", 
+        "unicode": "🍧", 
+        "name": "Shaved Ice"
+    }, 
+    "🌶": {
+        "style": "unicode", 
+        "image": "1f336.png", 
+        "name": "Hot Pepper"
+    }, 
+    ":pray_tone2:": {
+        "style": "github", 
+        "image": "1f64f-1f3fc.png", 
+        "unicode": "🙏🏼", 
+        "name": "Person With Folded Hands - Tone 2"
+    }, 
+    "🔺": {
+        "style": "unicode", 
+        "image": "1f53a.png", 
+        "name": "Up-pointing Red Triangle"
+    }, 
+    ":droplet:": {
+        "style": "github", 
+        "image": "1f4a7.png", 
+        "unicode": "💧", 
+        "name": "Droplet"
+    }, 
+    ":oncoming_police_car:": {
+        "style": "github", 
+        "image": "1f694.png", 
+        "unicode": "🚔", 
+        "name": "Oncoming Police Car"
+    }, 
+    "📏": {
+        "style": "unicode", 
+        "image": "1f4cf.png", 
+        "name": "Straight Ruler"
+    }, 
+    ":full-moon-with-face:": {
+        "style": "github", 
+        "image": "1f31d.png", 
+        "unicode": "🌝", 
+        "name": "Full Moon With Face"
+    }, 
+    ":flag_ng:": {
+        "style": "github", 
+        "image": "1f1f3-1f1ec.png", 
+        "unicode": "🇳🇬", 
+        "name": "Nigeria"
+    }, 
+    ":star-and-crescent:": {
+        "style": "github", 
+        "image": "262a.png", 
+        "unicode": "☪", 
+        "name": "Star And Crescent"
+    }, 
+    ":back_of_hand:": {
+        "style": "github", 
+        "image": "1f91a.png", 
+        "unicode": "🤚", 
+        "name": "Raised Back Of Hand"
+    }, 
+    ":flag_gq:": {
+        "style": "github", 
+        "image": "1f1ec-1f1f6.png", 
+        "unicode": "🇬🇶", 
+        "name": "Equatorial Guinea"
+    }, 
+    "👤": {
+        "style": "unicode", 
+        "image": "1f464.png", 
+        "name": "Bust In Silhouette"
+    }, 
+    ":ae:": {
+        "style": "github", 
+        "image": "1f1e6-1f1ea.png", 
+        "unicode": "🇦🇪", 
+        "name": "The United Arab Emirates"
+    }, 
+    ":white_small_square:": {
+        "style": "github", 
+        "image": "25ab.png", 
+        "unicode": "▫", 
+        "name": "White Small Square"
+    }, 
+    ":page-with-curl:": {
+        "style": "github", 
+        "image": "1f4c3.png", 
+        "unicode": "📃", 
+        "name": "Page With Curl"
+    }, 
+    ":flag-sm:": {
+        "style": "github", 
+        "image": "1f1f8-1f1f2.png", 
+        "unicode": "🇸🇲", 
+        "name": "San Marino"
+    }, 
+    ":lower_left_ballpoint_pen:": {
+        "style": "github", 
+        "image": "1f58a.png", 
+        "unicode": "🖊", 
+        "name": "Lower Left Ballpoint Pen"
+    }, 
+    "😣": {
+        "style": "unicode", 
+        "ascii": ">.<", 
+        "image": "1f623.png", 
+        "name": "Persevering Face"
+    }, 
+    ":black-small-square:": {
+        "style": "github", 
+        "image": "25aa.png", 
+        "unicode": "▪", 
+        "name": "Black Small Square"
+    }, 
+    ":expecting_woman_tone5:": {
+        "style": "github", 
+        "image": "1f930-1f3ff.png", 
+        "unicode": "🤰🏿", 
+        "name": "Pregnant Woman - Tone 5"
+    }, 
+    "👰🏾": {
+        "style": "unicode", 
+        "image": "1f470-1f3fe.png", 
+        "name": "Bride With Veil - Tone 4"
+    }, 
+    "👰🏿": {
+        "style": "unicode", 
+        "image": "1f470-1f3ff.png", 
+        "name": "Bride With Veil - Tone 5"
+    }, 
+    "👰🏼": {
+        "style": "unicode", 
+        "image": "1f470-1f3fc.png", 
+        "name": "Bride With Veil - Tone 2"
+    }, 
+    "👰🏽": {
+        "style": "unicode", 
+        "image": "1f470-1f3fd.png", 
+        "name": "Bride With Veil - Tone 3"
+    }, 
+    ":arrow_heading_down:": {
+        "style": "github", 
+        "image": "2935.png", 
+        "unicode": "⤵", 
+        "name": "Arrow Pointing Rightwards Then Curving Downwards"
+    }, 
+    ":spy-tone4:": {
+        "style": "github", 
+        "image": "1f575-1f3fe.png", 
+        "unicode": "🕵🏾", 
+        "name": "Sleuth Or Spy - Tone 4"
+    }, 
+    "🚸": {
+        "style": "unicode", 
+        "image": "1f6b8.png", 
+        "name": "Children Crossing"
+    }, 
+    ":cricket:": {
+        "style": "github", 
+        "image": "1f3cf.png", 
+        "unicode": "🏏", 
+        "name": "Cricket Bat And Ball"
+    }, 
+    ":wrestlers-tone2:": {
+        "style": "github", 
+        "image": "1f93c-1f3fc.png", 
+        "unicode": "🤼🏼", 
+        "name": "Wrestlers - Tone 2"
+    }, 
+    ":older_man:": {
+        "style": "github", 
+        "image": "1f474.png", 
+        "unicode": "👴", 
+        "name": "Older Man"
+    }, 
+    ":hk:": {
+        "style": "github", 
+        "image": "1f1ed-1f1f0.png", 
+        "unicode": "🇭🇰", 
+        "name": "Hong Kong"
+    }, 
+    ":regional-indicator-u:": {
+        "style": "github", 
+        "image": "1f1fa.png", 
+        "unicode": "🇺", 
+        "name": "Regional Indicator Symbol Letter U"
+    }, 
+    ":mrs-claus-tone3:": {
+        "style": "github", 
+        "image": "1f936-1f3fd.png", 
+        "unicode": "🤶🏽", 
+        "name": "Mother Christmas - Tone 3"
+    }, 
+    ":left-facing-fist-tone4:": {
+        "style": "github", 
+        "image": "1f91b-1f3fe.png", 
+        "unicode": "🤛🏾", 
+        "name": "Left Facing Fist - Tone 4"
+    }, 
+    ":couplekiss:": {
+        "style": "github", 
+        "image": "1f48f.png", 
+        "unicode": "💏", 
+        "name": "Kiss"
+    }, 
+    ":point_down_tone3:": {
+        "style": "github", 
+        "image": "1f447-1f3fd.png", 
+        "unicode": "👇🏽", 
+        "name": "White Down Pointing Backhand Index - Tone 3"
+    }, 
+    ":kissing-heart:": {
+        "style": "github", 
+        "ascii": ":*", 
+        "image": "1f618.png", 
+        "unicode": "😘", 
+        "name": "Face Throwing A Kiss"
+    }, 
+    ":information-desk-person-tone2:": {
+        "style": "github", 
+        "image": "1f481-1f3fc.png", 
+        "unicode": "💁🏼", 
+        "name": "Information Desk Person - Tone 2"
+    }, 
+    "↗": {
+        "style": "unicode", 
+        "image": "2197.png", 
+        "name": "North East Arrow"
+    }, 
+    "💥": {
+        "style": "unicode", 
+        "image": "1f4a5.png", 
+        "name": "Collision Symbol"
+    }, 
+    ":middle-finger-tone2:": {
+        "style": "github", 
+        "image": "1f595-1f3fc.png", 
+        "unicode": "🖕🏼", 
+        "name": "Reversed Hand With Middle Finger Extended - Tone 2"
+    }, 
+    ":ice_skate:": {
+        "style": "github", 
+        "image": "26f8.png", 
+        "unicode": "⛸", 
+        "name": "Ice Skate"
+    }, 
+    ":cruise-ship:": {
+        "style": "github", 
+        "image": "1f6f3.png", 
+        "unicode": "🛳", 
+        "name": "Passenger Ship"
+    }, 
+    "🈶": {
+        "style": "unicode", 
+        "image": "1f236.png", 
+        "name": "Squared Cjk Unified Ideograph-6709"
+    }, 
+    "🐺": {
+        "style": "unicode", 
+        "image": "1f43a.png", 
+        "name": "Wolf Face"
+    }, 
+    ":construction_worker_tone1:": {
+        "style": "github", 
+        "image": "1f477-1f3fb.png", 
+        "unicode": "👷🏻", 
+        "name": "Construction Worker - Tone 1"
+    }, 
+    ":person_doing_cartwheel_tone3:": {
+        "style": "github", 
+        "image": "1f938-1f3fd.png", 
+        "unicode": "🤸🏽", 
+        "name": "Person Doing Cartwheel - Tone 3"
+    }, 
+    "🏋": {
+        "style": "unicode", 
+        "image": "1f3cb.png", 
+        "name": "Weight Lifter"
+    }, 
+    ":person-frowning-tone3:": {
+        "style": "github", 
+        "image": "1f64d-1f3fd.png", 
+        "unicode": "🙍🏽", 
+        "name": "Person Frowning - Tone 3"
+    }, 
+    "🏤": {
+        "style": "unicode", 
+        "image": "1f3e4.png", 
+        "name": "European Post Office"
+    }, 
+    "🍠": {
+        "style": "unicode", 
+        "image": "1f360.png", 
+        "name": "Roasted Sweet Potato"
+    }, 
+    ":slightly_smiling_face:": {
+        "style": "github", 
+        "ascii": ":)", 
+        "image": "1f642.png", 
+        "unicode": "🙂", 
+        "name": "Slightly Smiling Face"
+    }, 
+    "🕤": {
+        "style": "unicode", 
+        "image": "1f564.png", 
+        "name": "Clock Face Nine-thirty"
+    }, 
+    "⏫": {
+        "style": "unicode", 
+        "image": "23eb.png", 
+        "name": "Black Up-pointing Double Triangle"
+    }, 
+    ":ok-woman-tone1:": {
+        "style": "github", 
+        "image": "1f646-1f3fb.png", 
+        "unicode": "🙆🏻", 
+        "name": "Face With Ok Gesture Tone1"
+    }, 
+    "🙅🏽": {
+        "style": "unicode", 
+        "image": "1f645-1f3fd.png", 
+        "name": "Face With No Good Gesture - Tone 3"
+    }, 
+    "🙅🏼": {
+        "style": "unicode", 
+        "image": "1f645-1f3fc.png", 
+        "name": "Face With No Good Gesture - Tone 2"
+    }, 
+    "🙅🏿": {
+        "style": "unicode", 
+        "image": "1f645-1f3ff.png", 
+        "name": "Face With No Good Gesture - Tone 5"
+    }, 
+    "🙅🏾": {
+        "style": "unicode", 
+        "image": "1f645-1f3fe.png", 
+        "name": "Face With No Good Gesture - Tone 4"
+    }, 
+    "🙅🏻": {
+        "style": "unicode", 
+        "image": "1f645-1f3fb.png", 
+        "name": "Face With No Good Gesture - Tone 1"
+    }, 
+    ":flag_cl:": {
+        "style": "github", 
+        "image": "1f1e8-1f1f1.png", 
+        "unicode": "🇨🇱", 
+        "name": "Chile"
+    }, 
+    "🚎": {
+        "style": "unicode", 
+        "image": "1f68e.png", 
+        "name": "Trolleybus"
+    }, 
+    ":nut_and_bolt:": {
+        "style": "github", 
+        "image": "1f529.png", 
+        "unicode": "🔩", 
+        "name": "Nut And Bolt"
+    }, 
+    ":tn:": {
+        "style": "github", 
+        "image": "1f1f9-1f1f3.png", 
+        "unicode": "🇹🇳", 
+        "name": "Tunisia"
+    }, 
+    ":globe-with-meridians:": {
+        "style": "github", 
+        "image": "1f310.png", 
+        "unicode": "🌐", 
+        "name": "Globe With Meridians"
+    }, 
+    "🤧": {
+        "style": "unicode", 
+        "image": "1f927.png", 
+        "name": "Sneezing Face"
+    }, 
+    ":water-polo-tone5:": {
+        "style": "github", 
+        "image": "1f93d-1f3ff.png", 
+        "unicode": "🤽🏿", 
+        "name": "Water Polo - Tone 5"
+    }, 
+    ":point-left-tone4:": {
+        "style": "github", 
+        "image": "1f448-1f3fe.png", 
+        "unicode": "👈🏾", 
+        "name": "White Left Pointing Backhand Index - Tone 4"
+    }, 
+    ":low_brightness:": {
+        "style": "github", 
+        "image": "1f505.png", 
+        "unicode": "🔅", 
+        "name": "Low Brightness Symbol"
+    }, 
+    ":no_entry:": {
+        "style": "github", 
+        "image": "26d4.png", 
+        "unicode": "⛔", 
+        "name": "No Entry"
+    }, 
+    ":man-with-turban-tone5:": {
+        "style": "github", 
+        "image": "1f473-1f3ff.png", 
+        "unicode": "👳🏿", 
+        "name": "Man With Turban - Tone 5"
+    }, 
+    ":flan:": {
+        "style": "github", 
+        "image": "1f36e.png", 
+        "unicode": "🍮", 
+        "name": "Custard"
+    }, 
+    ":horse_racing_tone5:": {
+        "style": "github", 
+        "image": "1f3c7-1f3ff.png", 
+        "unicode": "🏇🏿", 
+        "name": "Horse Racing - Tone 5"
+    }, 
+    ":u5408:": {
+        "style": "github", 
+        "image": "1f234.png", 
+        "unicode": "🈴", 
+        "name": "Squared Cjk Unified Ideograph-5408"
+    }, 
+    ":island:": {
+        "style": "github", 
+        "image": "1f3dd.png", 
+        "unicode": "🏝", 
+        "name": "Desert Island"
+    }, 
+    ":mans-shoe:": {
+        "style": "github", 
+        "image": "1f45e.png", 
+        "unicode": "👞", 
+        "name": "Mans Shoe"
+    }, 
+    ":flag-sr:": {
+        "style": "github", 
+        "image": "1f1f8-1f1f7.png", 
+        "unicode": "🇸🇷", 
+        "name": "Suriname"
+    }, 
+    ":flag_mc:": {
+        "style": "github", 
+        "image": "1f1f2-1f1e8.png", 
+        "unicode": "🇲🇨", 
+        "name": "Monaco"
+    }, 
+    ":raising_hand_tone1:": {
+        "style": "github", 
+        "image": "1f64b-1f3fb.png", 
+        "unicode": "🙋🏻", 
+        "name": "Happy Person Raising One Hand Tone1"
+    }, 
+    "✂": {
+        "style": "unicode", 
+        "image": "2702.png", 
+        "name": "Black Scissors"
+    }, 
+    ":running_shirt_with_sash:": {
+        "style": "github", 
+        "image": "1f3bd.png", 
+        "unicode": "🎽", 
+        "name": "Running Shirt With Sash"
+    }, 
+    "😌": {
+        "style": "unicode", 
+        "image": "1f60c.png", 
+        "name": "Relieved Face"
+    }, 
+    "⚗": {
+        "style": "unicode", 
+        "image": "2697.png", 
+        "name": "Alembic"
+    }, 
+    ":one:": {
+        "style": "github", 
+        "image": "0031-20e3.png", 
+        "unicode": "1⃣", 
+        "name": "Keycap Digit One"
+    }, 
+    "🎥": {
+        "style": "unicode", 
+        "image": "1f3a5.png", 
+        "name": "Movie Camera"
+    }, 
+    "🔶": {
+        "style": "unicode", 
+        "image": "1f536.png", 
+        "name": "Large Orange Diamond"
+    }, 
+    "🌺": {
+        "style": "unicode", 
+        "image": "1f33a.png", 
+        "name": "Hibiscus"
+    }, 
+    "🤾": {
+        "style": "unicode", 
+        "image": "1f93e.png", 
+        "name": "Handball"
+    }, 
+    ":waxing_gibbous_moon:": {
+        "style": "github", 
+        "image": "1f314.png", 
+        "unicode": "🌔", 
+        "name": "Waxing Gibbous Moon Symbol"
+    }, 
+    ":gr:": {
+        "style": "github", 
+        "image": "1f1ec-1f1f7.png", 
+        "unicode": "🇬🇷", 
+        "name": "Greece"
+    }, 
+    ":hand-splayed-tone3:": {
+        "style": "github", 
+        "image": "1f590-1f3fd.png", 
+        "unicode": "🖐🏽", 
+        "name": "Raised Hand With Fingers Splayed - Tone 3"
+    }, 
+    "📋": {
+        "style": "unicode", 
+        "image": "1f4cb.png", 
+        "name": "Clipboard"
+    }, 
+    ":thumbsdown_tone3:": {
+        "style": "github", 
+        "image": "1f44e-1f3fd.png", 
+        "unicode": "👎🏽", 
+        "name": "Thumbs Down Sign - Tone 3"
+    }, 
+    "🤦🏿": {
+        "style": "unicode", 
+        "image": "1f926-1f3ff.png", 
+        "name": "Face Palm - Tone 5"
+    }, 
+    "👠": {
+        "style": "unicode", 
+        "image": "1f460.png", 
+        "name": "High-heeled Shoe"
+    }, 
+    ":wilted_rose:": {
+        "style": "github", 
+        "image": "1f940.png", 
+        "unicode": "🥀", 
+        "name": "Wilted Flower"
+    }, 
+    "0⃣": {
+        "style": "unicode", 
+        "image": "0030-20e3.png", 
+        "name": "Keycap Digit Zero"
+    }, 
+    ":arrow-forward:": {
+        "style": "github", 
+        "image": "25b6.png", 
+        "unicode": "▶", 
+        "name": "Black Right-pointing Triangle"
+    }, 
+    ":latin_cross:": {
+        "style": "github", 
+        "image": "271d.png", 
+        "unicode": "✝", 
+        "name": "Latin Cross"
+    }, 
+    ":house-abandoned:": {
+        "style": "github", 
+        "image": "1f3da.png", 
+        "unicode": "🏚", 
+        "name": "Derelict House Building"
+    }, 
+    ":file-cabinet:": {
+        "style": "github", 
+        "image": "1f5c4.png", 
+        "unicode": "🗄", 
+        "name": "File Cabinet"
+    }, 
+    ":flag-jm:": {
+        "style": "github", 
+        "image": "1f1ef-1f1f2.png", 
+        "unicode": "🇯🇲", 
+        "name": "Jamaica"
+    }, 
+    ":older_woman_tone5:": {
+        "style": "github", 
+        "image": "1f475-1f3ff.png", 
+        "unicode": "👵🏿", 
+        "name": "Older Woman - Tone 5"
+    }, 
+    ":et:": {
+        "style": "github", 
+        "image": "1f1ea-1f1f9.png", 
+        "unicode": "🇪🇹", 
+        "name": "Ethiopia"
+    }, 
+    ":cupid:": {
+        "style": "github", 
+        "image": "1f498.png", 
+        "unicode": "💘", 
+        "name": "Heart With Arrow"
+    }, 
+    ":flag_si:": {
+        "style": "github", 
+        "image": "1f1f8-1f1ee.png", 
+        "unicode": "🇸🇮", 
+        "name": "Slovenia"
+    }, 
+    ":horse-racing-tone3:": {
+        "style": "github", 
+        "image": "1f3c7-1f3fd.png", 
+        "unicode": "🏇🏽", 
+        "name": "Horse Racing - Tone 3"
+    }, 
+    "🆎": {
+        "style": "unicode", 
+        "image": "1f18e.png", 
+        "name": "Negative Squared Ab"
+    }, 
+    ":uy:": {
+        "style": "github", 
+        "image": "1f1fa-1f1fe.png", 
+        "unicode": "🇺🇾", 
+        "name": "Uruguay"
+    }, 
+    ":v-tone3:": {
+        "style": "github", 
+        "image": "270c-1f3fd.png", 
+        "unicode": "✌🏽", 
+        "name": "Victory Hand - Tone 3"
+    }, 
+    "🛄": {
+        "style": "unicode", 
+        "image": "1f6c4.png", 
+        "name": "Baggage Claim"
+    }, 
+    ":wedding:": {
+        "style": "github", 
+        "image": "1f492.png", 
+        "unicode": "💒", 
+        "name": "Wedding"
+    }, 
+    ":person_frowning:": {
+        "style": "github", 
+        "image": "1f64d.png", 
+        "unicode": "🙍", 
+        "name": "Person Frowning"
+    }, 
+    ":beginner:": {
+        "style": "github", 
+        "image": "1f530.png", 
+        "unicode": "🔰", 
+        "name": "Japanese Symbol For Beginner"
+    }, 
+    ":family_mmb:": {
+        "style": "github", 
+        "image": "1f468-1f468-1f466.png", 
+        "unicode": "👨👨👦", 
+        "name": "Family (man,man,boy)"
+    }, 
+    ":fist_tone2:": {
+        "style": "github", 
+        "image": "270a-1f3fc.png", 
+        "unicode": "✊🏼", 
+        "name": "Raised Fist - Tone 2"
+    }, 
+    ":grin:": {
+        "style": "github", 
+        "image": "1f601.png", 
+        "unicode": "😁", 
+        "name": "Grinning Face With Smiling Eyes"
+    }, 
+    ":mouse-three-button:": {
+        "style": "github", 
+        "image": "1f5b1.png", 
+        "unicode": "🖱", 
+        "name": "Three Button Mouse"
+    }, 
+    ":flag-om:": {
+        "style": "github", 
+        "image": "1f1f4-1f1f2.png", 
+        "unicode": "🇴🇲", 
+        "name": "Oman"
+    }, 
+    ":man-dancing-tone5:": {
+        "style": "github", 
+        "image": "1f57a-1f3ff.png", 
+        "unicode": "🕺🏿", 
+        "name": "Man Dancing - Tone 5"
+    }, 
+    ":right_fist_tone4:": {
+        "style": "github", 
+        "image": "1f91c-1f3fe.png", 
+        "unicode": "🤜🏾", 
+        "name": "Right Facing Fist - Tone 4"
+    }, 
+    ":bow-tone1:": {
+        "style": "github", 
+        "image": "1f647-1f3fb.png", 
+        "unicode": "🙇🏻", 
+        "name": "Person Bowing Deeply - Tone 1"
+    }, 
+    ":juggler_tone5:": {
+        "style": "github", 
+        "image": "1f939-1f3ff.png", 
+        "unicode": "🤹🏿", 
+        "name": "Juggling - Tone 5"
+    }, 
+    ":flag_kn:": {
+        "style": "github", 
+        "image": "1f1f0-1f1f3.png", 
+        "unicode": "🇰🇳", 
+        "name": "Saint Kitts And Nevis"
+    }, 
+    ":white-flower:": {
+        "style": "github", 
+        "image": "1f4ae.png", 
+        "unicode": "💮", 
+        "name": "White Flower"
+    }, 
+    ":rowboat-tone4:": {
+        "style": "github", 
+        "image": "1f6a3-1f3fe.png", 
+        "unicode": "🚣🏾", 
+        "name": "Rowboat - Tone 4"
+    }, 
+    "☂": {
+        "style": "unicode", 
+        "image": "2602.png", 
+        "name": "Umbrella"
+    }, 
+    ":selfie_tone5:": {
+        "style": "github", 
+        "image": "1f933-1f3ff.png", 
+        "unicode": "🤳🏿", 
+        "name": "Selfie - Tone 5"
+    }, 
+    ":popcorn:": {
+        "style": "github", 
+        "image": "1f37f.png", 
+        "unicode": "🍿", 
+        "name": "Popcorn"
+    }, 
+    ":building_construction:": {
+        "style": "github", 
+        "image": "1f3d7.png", 
+        "unicode": "🏗", 
+        "name": "Building Construction"
+    }, 
+    ":arrow_right_hook:": {
+        "style": "github", 
+        "image": "21aa.png", 
+        "unicode": "↪", 
+        "name": "Rightwards Arrow With Hook"
+    }, 
+    "➗": {
+        "style": "unicode", 
+        "image": "2797.png", 
+        "name": "Heavy Division Sign"
+    }, 
+    ":u55b6:": {
+        "style": "github", 
+        "image": "1f23a.png", 
+        "unicode": "🈺", 
+        "name": "Squared Cjk Unified Ideograph-55b6"
+    }, 
+    "💡": {
+        "style": "unicode", 
+        "image": "1f4a1.png", 
+        "name": "Electric Light Bulb"
+    }, 
+    ":flag-na:": {
+        "style": "github", 
+        "image": "1f1f3-1f1e6.png", 
+        "unicode": "🇳🇦", 
+        "name": "Namibia"
+    }, 
+    ":mountain-snow:": {
+        "style": "github", 
+        "image": "1f3d4.png", 
+        "unicode": "🏔", 
+        "name": "Snow Capped Mountain"
+    }, 
+    "🐶": {
+        "style": "unicode", 
+        "image": "1f436.png", 
+        "name": "Dog Face"
+    }, 
+    ":punch-tone3:": {
+        "style": "github", 
+        "image": "1f44a-1f3fd.png", 
+        "unicode": "👊🏽", 
+        "name": "Fisted Hand Sign - Tone 3"
+    }, 
+    "🈺": {
+        "style": "unicode", 
+        "image": "1f23a.png", 
+        "name": "Squared Cjk Unified Ideograph-55b6"
+    }, 
+    ":open-hands-tone4:": {
+        "style": "github", 
+        "image": "1f450-1f3fe.png", 
+        "unicode": "👐🏾", 
+        "name": "Open Hands Sign - Tone 4"
+    }, 
+    ":cf:": {
+        "style": "github", 
+        "image": "1f1e8-1f1eb.png", 
+        "unicode": "🇨🇫", 
+        "name": "Central African Republic"
+    }, 
+    ":guardsman-tone4:": {
+        "style": "github", 
+        "image": "1f482-1f3fe.png", 
+        "unicode": "💂🏾", 
+        "name": "Guardsman - Tone 4"
+    }, 
+    ":thermometer-face:": {
+        "style": "github", 
+        "image": "1f912.png", 
+        "unicode": "🤒", 
+        "name": "Face With Thermometer"
+    }, 
+    "🏏": {
+        "style": "unicode", 
+        "image": "1f3cf.png", 
+        "name": "Cricket Bat And Ball"
+    }, 
+    ":tropical-fish:": {
+        "style": "github", 
+        "image": "1f420.png", 
+        "unicode": "🐠", 
+        "name": "Tropical Fish"
+    }, 
+    ":cop-tone5:": {
+        "style": "github", 
+        "image": "1f46e-1f3ff.png", 
+        "unicode": "👮🏿", 
+        "name": "Police Officer - Tone 5"
+    }, 
+    "🕠": {
+        "style": "unicode", 
+        "image": "1f560.png", 
+        "name": "Clock Face Five-thirty"
+    }, 
+    "🍤": {
+        "style": "unicode", 
+        "image": "1f364.png", 
+        "name": "Fried Shrimp"
+    }, 
+    ":persevere:": {
+        "style": "github", 
+        "ascii": ">.<", 
+        "image": "1f623.png", 
+        "unicode": "😣", 
+        "name": "Persevering Face"
+    }, 
+    "⏯": {
+        "style": "unicode", 
+        "image": "23ef.png", 
+        "name": "Black Right-pointing Double Triangle With Double Vertical Bar"
+    }, 
+    ":flag_re:": {
+        "style": "github", 
+        "image": "1f1f7-1f1ea.png", 
+        "unicode": "🇷🇪", 
+        "name": "Réunion"
+    }, 
+    ":no_good_tone2:": {
+        "style": "github", 
+        "image": "1f645-1f3fc.png", 
+        "unicode": "🙅🏼", 
+        "name": "Face With No Good Gesture - Tone 2"
+    }, 
+    ":-1_tone3:": {
+        "style": "github", 
+        "image": "1f44e-1f3fd.png", 
+        "unicode": "👎🏽", 
+        "name": "Thumbs Down Sign - Tone 3"
+    }, 
+    ":diamond-shape-with-a-dot-inside:": {
+        "style": "github", 
+        "image": "1f4a0.png", 
+        "unicode": "💠", 
+        "name": "Diamond Shape With A Dot Inside"
+    }, 
+    ":boxing_glove:": {
+        "style": "github", 
+        "image": "1f94a.png", 
+        "unicode": "🥊", 
+        "name": "Boxing Glove"
+    }, 
+    ":sailboat:": {
+        "style": "github", 
+        "image": "26f5.png", 
+        "unicode": "⛵", 
+        "name": "Sailboat"
+    }, 
+    ":metal-tone4:": {
+        "style": "github", 
+        "image": "1f918-1f3fe.png", 
+        "unicode": "🤘🏾", 
+        "name": "Sign Of The Horns - Tone 4"
+    }, 
+    ":flag-id:": {
+        "style": "github", 
+        "image": "1f1ee-1f1e9.png", 
+        "unicode": "🇮🇩", 
+        "name": "Indonesia"
+    }, 
+    ":thinking_face:": {
+        "style": "github", 
+        "image": "1f914.png", 
+        "unicode": "🤔", 
+        "name": "Thinking Face"
+    }, 
+    ":swimmer_tone1:": {
+        "style": "github", 
+        "image": "1f3ca-1f3fb.png", 
+        "unicode": "🏊🏻", 
+        "name": "Swimmer - Tone 1"
+    }, 
+    ":ear_tone2:": {
+        "style": "github", 
+        "image": "1f442-1f3fc.png", 
+        "unicode": "👂🏼", 
+        "name": "Ear - Tone 2"
+    }, 
+    ":penguin:": {
+        "style": "github", 
+        "image": "1f427.png", 
+        "unicode": "🐧", 
+        "name": "Penguin"
+    }, 
+    ":thumbsup:": {
+        "style": "github", 
+        "image": "1f44d.png", 
+        "unicode": "👍", 
+        "name": "Thumbs Up Sign"
+    }, 
+    "🙍": {
+        "style": "unicode", 
+        "image": "1f64d.png", 
+        "name": "Person Frowning"
+    }, 
+    ":cat:": {
+        "style": "github", 
+        "image": "1f431.png", 
+        "unicode": "🐱", 
+        "name": "Cat Face"
+    }, 
+    "🛢": {
+        "style": "unicode", 
+        "image": "1f6e2.png", 
+        "name": "Oil Drum"
+    }, 
+    ":flag_tw:": {
+        "style": "github", 
+        "image": "1f1f9-1f1fc.png", 
+        "unicode": "🇹🇼", 
+        "name": "The Republic Of China"
+    }, 
+    ":flag-black:": {
+        "style": "github", 
+        "image": "1f3f4.png", 
+        "unicode": "🏴", 
+        "name": "Waving Black Flag"
+    }, 
+    ":vulcan-tone4:": {
+        "style": "github", 
+        "image": "1f596-1f3fe.png", 
+        "unicode": "🖖🏾", 
+        "name": "Raised Hand With Part Between Middle And Ring Fingers - Tone 4"
+    }, 
+    "👩❤👩": {
+        "style": "unicode", 
+        "image": "1f469-2764-1f469.png", 
+        "name": "Couple (woman,woman)"
+    }, 
+    ":vulcan_tone2:": {
+        "style": "github", 
+        "image": "1f596-1f3fc.png", 
+        "unicode": "🖖🏼", 
+        "name": "Raised Hand With Part Between Middle And Ring Fingers - Tone 2"
+    }, 
+    ":lifter-tone3:": {
+        "style": "github", 
+        "image": "1f3cb-1f3fd.png", 
+        "unicode": "🏋🏽", 
+        "name": "Weight Lifter - Tone 3"
+    }, 
+    "🐌": {
+        "style": "unicode", 
+        "image": "1f40c.png", 
+        "name": "Snail"
+    }, 
+    "O=)": {
+        "style": "ascii", 
+        "ascii": "O:-)", 
+        "image": "1f607.png", 
+        "unicode": "😇", 
+        "name": "Smiling Face With Halo"
+    }, 
+    ":raising_hand_tone2:": {
+        "style": "github", 
+        "image": "1f64b-1f3fc.png", 
+        "unicode": "🙋🏼", 
+        "name": "Happy Person Raising One Hand Tone2"
+    }, 
+    ":sy:": {
+        "style": "github", 
+        "image": "1f1f8-1f1fe.png", 
+        "unicode": "🇸🇾", 
+        "name": "Syria"
+    }, 
+    ":selfie-tone1:": {
+        "style": "github", 
+        "image": "1f933-1f3fb.png", 
+        "unicode": "🤳🏻", 
+        "name": "Selfie - Tone 1"
+    }, 
+    "🛋": {
+        "style": "unicode", 
+        "image": "1f6cb.png", 
+        "name": "Couch And Lamp"
+    }, 
+    "🃏": {
+        "style": "unicode", 
+        "image": "1f0cf.png", 
+        "name": "Playing Card Black Joker"
+    }, 
+    ":clap_tone4:": {
+        "style": "github", 
+        "image": "1f44f-1f3fe.png", 
+        "unicode": "👏🏾", 
+        "name": "Clapping Hands Sign - Tone 4"
+    }, 
+    ":surfer-tone1:": {
+        "style": "github", 
+        "image": "1f3c4-1f3fb.png", 
+        "unicode": "🏄🏻", 
+        "name": "Surfer - Tone 1"
+    }, 
+    ":surfer_tone1:": {
+        "style": "github", 
+        "image": "1f3c4-1f3fb.png", 
+        "unicode": "🏄🏻", 
+        "name": "Surfer - Tone 1"
+    }, 
+    ":pager:": {
+        "style": "github", 
+        "image": "1f4df.png", 
+        "unicode": "📟", 
+        "name": "Pager"
+    }, 
+    "👁🗨": {
+        "style": "unicode", 
+        "image": "1f441-1f5e8.png", 
+        "name": "Eye In Speech Bubble"
+    }, 
+    ":haircut_tone1:": {
+        "style": "github", 
+        "image": "1f487-1f3fb.png", 
+        "unicode": "💇🏻", 
+        "name": "Haircut - Tone 1"
+    }, 
+    ":fountain:": {
+        "style": "github", 
+        "image": "26f2.png", 
+        "unicode": "⛲", 
+        "name": "Fountain"
+    }, 
+    "🏹": {
+        "style": "unicode", 
+        "image": "1f3f9.png", 
+        "name": "Bow And Arrow"
+    }, 
+    ":thought-balloon:": {
+        "style": "github", 
+        "image": "1f4ad.png", 
+        "unicode": "💭", 
+        "name": "Thought Balloon"
+    }, 
+    ":information-source:": {
+        "style": "github", 
+        "image": "2139.png", 
+        "unicode": "ℹ", 
+        "name": "Information Source"
+    }, 
+    ":point-up-2-tone1:": {
+        "style": "github", 
+        "image": "1f446-1f3fb.png", 
+        "unicode": "👆🏻", 
+        "name": "White Up Pointing Backhand Index - Tone 1"
+    }, 
+    "🎎": {
+        "style": "unicode", 
+        "image": "1f38e.png", 
+        "name": "Japanese Dolls"
+    }, 
+    ":regional_indicator_e:": {
+        "style": "github", 
+        "image": "1f1ea.png", 
+        "unicode": "🇪", 
+        "name": "Regional Indicator Symbol Letter E"
+    }, 
+    ":play_pause:": {
+        "style": "github", 
+        "image": "23ef.png", 
+        "unicode": "⏯", 
+        "name": "Black Right-pointing Double Triangle With Double Vertical Bar"
+    }, 
+    ":cy:": {
+        "style": "github", 
+        "image": "1f1e8-1f1fe.png", 
+        "unicode": "🇨🇾", 
+        "name": "Cyprus"
+    }, 
+    ":lower_left_fountain_pen:": {
+        "style": "github", 
+        "image": "1f58b.png", 
+        "unicode": "🖋", 
+        "name": "Lower Left Fountain Pen"
+    }, 
+    ":hand_with_index_and_middle_fingers_crossed_tone5:": {
+        "style": "github", 
+        "image": "1f91e-1f3ff.png", 
+        "unicode": "🤞🏿", 
+        "name": "Hand With Index And Middle Fingers Crossed - Tone 5"
+    }, 
+    ":pregnant_woman_tone1:": {
+        "style": "github", 
+        "image": "1f930-1f3fb.png", 
+        "unicode": "🤰🏻", 
+        "name": "Pregnant Woman - Tone 1"
+    }, 
+    ":shrug-tone5:": {
+        "style": "github", 
+        "image": "1f937-1f3ff.png", 
+        "unicode": "🤷🏿", 
+        "name": "Shrug - Tone 5"
+    }, 
+    ":point_up:": {
+        "style": "github", 
+        "image": "261d.png", 
+        "unicode": "☝", 
+        "name": "White Up Pointing Index"
+    }, 
+    "📷": {
+        "style": "unicode", 
+        "image": "1f4f7.png", 
+        "name": "Camera"
+    }, 
+    ":flag-lb:": {
+        "style": "github", 
+        "image": "1f1f1-1f1e7.png", 
+        "unicode": "🇱🇧", 
+        "name": "Lebanon"
+    }, 
+    "🕍": {
+        "style": "unicode", 
+        "image": "1f54d.png", 
+        "name": "Synagogue"
+    }, 
+    ":sound:": {
+        "style": "github", 
+        "image": "1f509.png", 
+        "unicode": "🔉", 
+        "name": "Speaker With One Sound Wave"
+    }, 
+    "🥕": {
+        "style": "unicode", 
+        "image": "1f955.png", 
+        "name": "Carrot"
+    }, 
+    ":ky:": {
+        "style": "github", 
+        "image": "1f1f0-1f1fe.png", 
+        "unicode": "🇰🇾", 
+        "name": "Cayman Islands"
+    }, 
+    ":ag:": {
+        "style": "github", 
+        "image": "1f1e6-1f1ec.png", 
+        "unicode": "🇦🇬", 
+        "name": "Antigua And Barbuda"
+    }, 
+    "👷": {
+        "style": "unicode", 
+        "image": "1f477.png", 
+        "name": "Construction Worker"
+    }, 
+    ":flag-so:": {
+        "style": "github", 
+        "image": "1f1f8-1f1f4.png", 
+        "unicode": "🇸🇴", 
+        "name": "Somalia"
+    }, 
+    ":wrestling_tone5:": {
+        "style": "github", 
+        "image": "1f93c-1f3ff.png", 
+        "unicode": "🤼🏿", 
+        "name": "Wrestlers - Tone 5"
+    }, 
+    "🔌": {
+        "style": "unicode", 
+        "image": "1f50c.png", 
+        "name": "Electric Plug"
+    }, 
+    "🤔": {
+        "style": "unicode", 
+        "image": "1f914.png", 
+        "name": "Thinking Face"
+    }, 
+    ":hand-splayed-tone2:": {
+        "style": "github", 
+        "image": "1f590-1f3fc.png", 
+        "unicode": "🖐🏼", 
+        "name": "Raised Hand With Fingers Splayed - Tone 2"
+    }, 
+    "🚡": {
+        "style": "unicode", 
+        "image": "1f6a1.png", 
+        "name": "Aerial Tramway"
+    }, 
+    ":strawberry:": {
+        "style": "github", 
+        "image": "1f353.png", 
+        "unicode": "🍓", 
+        "name": "Strawberry"
+    }, 
+    "🤚🏼": {
+        "style": "unicode", 
+        "image": "1f91a-1f3fc.png", 
+        "name": "Raised Back Of Hand - Tone 2"
+    }, 
+    "🤚🏽": {
+        "style": "unicode", 
+        "image": "1f91a-1f3fd.png", 
+        "name": "Raised Back Of Hand - Tone 3"
+    }, 
+    "🤚🏾": {
+        "style": "unicode", 
+        "image": "1f91a-1f3fe.png", 
+        "name": "Raised Back Of Hand - Tone 4"
+    }, 
+    "🤚🏿": {
+        "style": "unicode", 
+        "image": "1f91a-1f3ff.png", 
+        "name": "Raised Back Of Hand - Tone 5"
+    }, 
+    "⤴": {
+        "style": "unicode", 
+        "image": "2934.png", 
+        "name": "Arrow Pointing Rightwards Then Curving Upwards"
+    }, 
+    "🤚🏻": {
+        "style": "unicode", 
+        "image": "1f91a-1f3fb.png", 
+        "name": "Raised Back Of Hand - Tone 1"
+    }, 
+    ":grapes:": {
+        "style": "github", 
+        "image": "1f347.png", 
+        "unicode": "🍇", 
+        "name": "Grapes"
+    }, 
+    ":spy-tone2:": {
+        "style": "github", 
+        "image": "1f575-1f3fc.png", 
+        "unicode": "🕵🏼", 
+        "name": "Sleuth Or Spy - Tone 2"
+    }, 
+    ":arrow_upper_left:": {
+        "style": "github", 
+        "image": "2196.png", 
+        "unicode": "↖", 
+        "name": "North West Arrow"
+    }, 
+    ":tiger2:": {
+        "style": "github", 
+        "image": "1f405.png", 
+        "unicode": "🐅", 
+        "name": "Tiger"
+    }, 
+    ":information_desk_person_tone2:": {
+        "style": "github", 
+        "image": "1f481-1f3fc.png", 
+        "unicode": "💁🏼", 
+        "name": "Information Desk Person - Tone 2"
+    }, 
+    ":ph:": {
+        "style": "github", 
+        "image": "1f1f5-1f1ed.png", 
+        "unicode": "🇵🇭", 
+        "name": "The Philippines"
+    }, 
+    ":linked_paperclips:": {
+        "style": "github", 
+        "image": "1f587.png", 
+        "unicode": "🖇", 
+        "name": "Linked Paperclips"
+    }, 
+    ":point_down_tone1:": {
+        "style": "github", 
+        "image": "1f447-1f3fb.png", 
+        "unicode": "👇🏻", 
+        "name": "White Down Pointing Backhand Index - Tone 1"
+    }, 
+    ":paperclip:": {
+        "style": "github", 
+        "image": "1f4ce.png", 
+        "unicode": "📎", 
+        "name": "Paperclip"
+    }, 
+    ":om-symbol:": {
+        "style": "github", 
+        "image": "1f549.png", 
+        "unicode": "🕉", 
+        "name": "Om Symbol"
+    }, 
+    ":juggling-tone1:": {
+        "style": "github", 
+        "image": "1f939-1f3fb.png", 
+        "unicode": "🤹🏻", 
+        "name": "Juggling - Tone 1"
+    }, 
+    ":snowman:": {
+        "style": "github", 
+        "image": "26c4.png", 
+        "unicode": "⛄", 
+        "name": "Snowman Without Snow"
+    }, 
+    "🇮🇩": {
+        "style": "unicode", 
+        "image": "1f1ee-1f1e9.png", 
+        "name": "Indonesia"
+    }, 
+    "🇮🇪": {
+        "style": "unicode", 
+        "image": "1f1ee-1f1ea.png", 
+        "name": "Ireland"
+    }, 
+    "👴🏽": {
+        "style": "unicode", 
+        "image": "1f474-1f3fd.png", 
+        "name": "Older Man - Tone 3"
+    }, 
+    "👴🏻": {
+        "style": "unicode", 
+        "image": "1f474-1f3fb.png", 
+        "name": "Older Man - Tone 1"
+    }, 
+    ":umbrella2:": {
+        "style": "github", 
+        "image": "2602.png", 
+        "unicode": "☂", 
+        "name": "Umbrella"
+    }, 
+    "🇮🇸": {
+        "style": "unicode", 
+        "image": "1f1ee-1f1f8.png", 
+        "name": "Iceland"
+    }, 
+    "🇮🇹": {
+        "style": "unicode", 
+        "image": "1f1ee-1f1f9.png", 
+        "name": "Italy"
+    }, 
+    "🇮🇱": {
+        "style": "unicode", 
+        "image": "1f1ee-1f1f1.png", 
+        "name": "Israel"
+    }, 
+    "🇮🇲": {
+        "style": "unicode", 
+        "image": "1f1ee-1f1f2.png", 
+        "name": "Isle Of Man"
+    }, 
+    "🇮🇳": {
+        "style": "unicode", 
+        "image": "1f1ee-1f1f3.png", 
+        "name": "India"
+    }, 
+    "🇮🇴": {
+        "style": "unicode", 
+        "image": "1f1ee-1f1f4.png", 
+        "name": "British Indian Ocean Territory"
+    }, 
+    "🇮🇶": {
+        "style": "unicode", 
+        "image": "1f1ee-1f1f6.png", 
+        "name": "Iraq"
+    }, 
+    "🇮🇷": {
+        "style": "unicode", 
+        "image": "1f1ee-1f1f7.png", 
+        "name": "Iran"
+    }, 
+    ":flag_pf:": {
+        "style": "github", 
+        "image": "1f1f5-1f1eb.png", 
+        "unicode": "🇵🇫", 
+        "name": "French Polynesia"
+    }, 
+    ":flag_ax:": {
+        "style": "github", 
+        "image": "1f1e6-1f1fd.png", 
+        "unicode": "🇦🇽", 
+        "name": "Åland Islands"
+    }, 
+    "👍": {
+        "style": "unicode", 
+        "image": "1f44d.png", 
+        "name": "Thumbs Up Sign"
+    }, 
+    ":person_doing_cartwheel_tone1:": {
+        "style": "github", 
+        "image": "1f938-1f3fb.png", 
+        "unicode": "🤸🏻", 
+        "name": "Person Doing Cartwheel - Tone 1"
+    }, 
+    ":flag-tr:": {
+        "style": "github", 
+        "image": "1f1f9-1f1f7.png", 
+        "unicode": "🇹🇷", 
+        "name": "Turkey"
+    }, 
+    "📢": {
+        "style": "unicode", 
+        "image": "1f4e2.png", 
+        "name": "Public Address Loudspeaker"
+    }, 
+    ":syringe:": {
+        "style": "github", 
+        "image": "1f489.png", 
+        "unicode": "💉", 
+        "name": "Syringe"
+    }, 
+    ":smiley_cat:": {
+        "style": "github", 
+        "image": "1f63a.png", 
+        "unicode": "😺", 
+        "name": "Smiling Cat Face With Open Mouth"
+    }, 
+    ":cow:": {
+        "style": "github", 
+        "image": "1f42e.png", 
+        "unicode": "🐮", 
+        "name": "Cow Face"
+    }, 
+    ":rowboat_tone2:": {
+        "style": "github", 
+        "image": "1f6a3-1f3fc.png", 
+        "unicode": "🚣🏼", 
+        "name": "Rowboat - Tone 2"
+    }, 
+    "🕷": {
+        "style": "unicode", 
+        "image": "1f577.png", 
+        "name": "Spider"
+    }, 
+    ":ice-skate:": {
+        "style": "github", 
+        "image": "26f8.png", 
+        "unicode": "⛸", 
+        "name": "Ice Skate"
+    }, 
+    ":regional_indicator_s:": {
+        "style": "github", 
+        "image": "1f1f8.png", 
+        "unicode": "🇸", 
+        "name": "Regional Indicator Symbol Letter S"
+    }, 
+    "✊": {
+        "style": "unicode", 
+        "image": "270a.png", 
+        "name": "Raised Fist"
+    }, 
+    ":juggling_tone4:": {
+        "style": "github", 
+        "image": "1f939-1f3fe.png", 
+        "unicode": "🤹🏾", 
+        "name": "Juggling - Tone 4"
+    }, 
+    "😔": {
+        "style": "unicode", 
+        "image": "1f614.png", 
+        "name": "Pensive Face"
+    }, 
+    ":tl:": {
+        "style": "github", 
+        "image": "1f1f9-1f1f1.png", 
+        "unicode": "🇹🇱", 
+        "name": "Timor-leste"
+    }, 
+    ":french_bread:": {
+        "style": "github", 
+        "image": "1f956.png", 
+        "unicode": "🥖", 
+        "name": "Baguette Bread"
+    }, 
+    ":iphone:": {
+        "style": "github", 
+        "image": "1f4f1.png", 
+        "unicode": "📱", 
+        "name": "Mobile Phone"
+    }, 
+    ":santa-tone5:": {
+        "style": "github", 
+        "image": "1f385-1f3ff.png", 
+        "unicode": "🎅🏿", 
+        "name": "Father Christmas - Tone 5"
+    }, 
+    ":nail_care_tone3:": {
+        "style": "github", 
+        "image": "1f485-1f3fd.png", 
+        "unicode": "💅🏽", 
+        "name": "Nail Polish - Tone 3"
+    }, 
+    ":angel-tone4:": {
+        "style": "github", 
+        "image": "1f47c-1f3fe.png", 
+        "unicode": "👼🏾", 
+        "name": "Baby Angel - Tone 4"
+    }, 
+    "🤶": {
+        "style": "unicode", 
+        "image": "1f936.png", 
+        "name": "Mother Christmas"
+    }, 
+    ":eyes:": {
+        "style": "github", 
+        "image": "1f440.png", 
+        "unicode": "👀", 
+        "name": "Eyes"
+    }, 
+    "🌊": {
+        "style": "unicode", 
+        "image": "1f30a.png", 
+        "name": "Water Wave"
+    }, 
+    ":boy_tone1:": {
+        "style": "github", 
+        "image": "1f466-1f3fb.png", 
+        "unicode": "👦🏻", 
+        "name": "Boy - Tone 1"
+    }, 
+    ":part_alternation_mark:": {
+        "style": "github", 
+        "image": "303d.png", 
+        "unicode": "〽", 
+        "name": "Part Alternation Mark"
+    }, 
+    "📓": {
+        "style": "unicode", 
+        "image": "1f4d3.png", 
+        "name": "Notebook"
+    }, 
+    ":factory:": {
+        "style": "github", 
+        "image": "1f3ed.png", 
+        "unicode": "🏭", 
+        "name": "Factory"
+    }, 
+    ":man-with-turban-tone3:": {
+        "style": "github", 
+        "image": "1f473-1f3fd.png", 
+        "unicode": "👳🏽", 
+        "name": "Man With Turban - Tone 3"
+    }, 
+    "👨": {
+        "style": "unicode", 
+        "image": "1f468.png", 
+        "name": "Man"
+    }, 
+    ":dolls:": {
+        "style": "github", 
+        "image": "1f38e.png", 
+        "unicode": "🎎", 
+        "name": "Japanese Dolls"
+    }, 
+    "🏽": {
+        "style": "unicode", 
+        "image": "1f3fd.png", 
+        "name": "Emoji Modifier Fitzpatrick Type-4"
+    }, 
+    ":european_castle:": {
+        "style": "github", 
+        "image": "1f3f0.png", 
+        "unicode": "🏰", 
+        "name": "European Castle"
+    }, 
+    "🎒": {
+        "style": "unicode", 
+        "image": "1f392.png", 
+        "name": "School Satchel"
+    }, 
+    ":vulcan_tone3:": {
+        "style": "github", 
+        "image": "1f596-1f3fd.png", 
+        "unicode": "🖖🏽", 
+        "name": "Raised Hand With Part Between Middle And Ring Fingers - Tone 3"
+    }, 
+    ":raising_hand_tone3:": {
+        "style": "github", 
+        "image": "1f64b-1f3fd.png", 
+        "unicode": "🙋🏽", 
+        "name": "Happy Person Raising One Hand Tone3"
+    }, 
+    "🤵🏽": {
+        "style": "unicode", 
+        "image": "1f935-1f3fd.png", 
+        "name": "Man In Tuxedo - Tone 3"
+    }, 
+    "🤵🏼": {
+        "style": "unicode", 
+        "image": "1f935-1f3fc.png", 
+        "name": "Man In Tuxedo - Tone 2"
+    }, 
+    "🤵🏿": {
+        "style": "unicode", 
+        "image": "1f935-1f3ff.png", 
+        "name": "Man In Tuxedo - Tone 5"
+    }, 
+    "🤵🏾": {
+        "style": "unicode", 
+        "image": "1f935-1f3fe.png", 
+        "name": "Man In Tuxedo - Tone 4"
+    }, 
+    "🤵🏻": {
+        "style": "unicode", 
+        "image": "1f935-1f3fb.png", 
+        "name": "Man In Tuxedo - Tone 1"
+    }, 
+    ":hand-splayed-tone1:": {
+        "style": "github", 
+        "image": "1f590-1f3fb.png", 
+        "unicode": "🖐🏻", 
+        "name": "Raised Hand With Fingers Splayed - Tone 1"
+    }, 
+    ":rugby_football:": {
+        "style": "github", 
+        "image": "1f3c9.png", 
+        "unicode": "🏉", 
+        "name": "Rugby Football"
+    }, 
+    ":rolled_up_newspaper:": {
+        "style": "github", 
+        "image": "1f5de.png", 
+        "unicode": "🗞", 
+        "name": "Rolled-up Newspaper"
+    }, 
+    ":sleuth_or_spy:": {
+        "style": "github", 
+        "image": "1f575.png", 
+        "unicode": "🕵", 
+        "name": "Sleuth Or Spy"
+    }, 
+    ":game_die:": {
+        "style": "github", 
+        "image": "1f3b2.png", 
+        "unicode": "🎲", 
+        "name": "Game Die"
+    }, 
+    "🇦": {
+        "style": "unicode", 
+        "image": "1f1e6.png", 
+        "name": "Regional Indicator Symbol Letter A"
+    }, 
+    ":open_hands_tone1:": {
+        "style": "github", 
+        "image": "1f450-1f3fb.png", 
+        "unicode": "👐🏻", 
+        "name": "Open Hands Sign - Tone 1"
+    }, 
+    ":flag_tj:": {
+        "style": "github", 
+        "image": "1f1f9-1f1ef.png", 
+        "unicode": "🇹🇯", 
+        "name": "Tajikistan"
+    }, 
+    ":high_heel:": {
+        "style": "github", 
+        "image": "1f460.png", 
+        "unicode": "👠", 
+        "name": "High-heeled Shoe"
+    }, 
+    ":last-quarter-moon:": {
+        "style": "github", 
+        "image": "1f317.png", 
+        "unicode": "🌗", 
+        "name": "Last Quarter Moon Symbol"
+    }, 
+    ":closed-book:": {
+        "style": "github", 
+        "image": "1f4d5.png", 
+        "unicode": "📕", 
+        "name": "Closed Book"
+    }, 
+    ":astonished:": {
+        "style": "github", 
+        "image": "1f632.png", 
+        "unicode": "😲", 
+        "name": "Astonished Face"
+    }, 
+    ":older_woman_tone3:": {
+        "style": "github", 
+        "image": "1f475-1f3fd.png", 
+        "unicode": "👵🏽", 
+        "name": "Older Woman - Tone 3"
+    }, 
+    ":horse-racing-tone1:": {
+        "style": "github", 
+        "image": "1f3c7-1f3fb.png", 
+        "unicode": "🏇🏻", 
+        "name": "Horse Racing - Tone 1"
+    }, 
+    ":stuck_out_tongue_winking_eye:": {
+        "style": "github", 
+        "ascii": ">:P", 
+        "image": "1f61c.png", 
+        "unicode": "😜", 
+        "name": "Face With Stuck-out Tongue And Winking Eye"
+    }, 
+    ":flag_so:": {
+        "style": "github", 
+        "image": "1f1f8-1f1f4.png", 
+        "unicode": "🇸🇴", 
+        "name": "Somalia"
+    }, 
+    ":large_blue_circle:": {
+        "style": "github", 
+        "image": "1f535.png", 
+        "unicode": "🔵", 
+        "name": "Large Blue Circle"
+    }, 
+    ":v-tone1:": {
+        "style": "github", 
+        "image": "270c-1f3fb.png", 
+        "unicode": "✌🏻", 
+        "name": "Victory Hand - Tone 1"
+    }, 
+    ":raised-hands-tone1:": {
+        "style": "github", 
+        "image": "1f64c-1f3fb.png", 
+        "unicode": "🙌🏻", 
+        "name": "Person Raising Both Hands In Celebration - Tone 1"
+    }, 
+    "💩": {
+        "style": "unicode", 
+        "image": "1f4a9.png", 
+        "name": "Pile Of Poo"
+    }, 
+    ":flag-hu:": {
+        "style": "github", 
+        "image": "1f1ed-1f1fa.png", 
+        "unicode": "🇭🇺", 
+        "name": "Hungary"
+    }, 
+    ":helmet_with_white_cross:": {
+        "style": "github", 
+        "image": "26d1.png", 
+        "unicode": "⛑", 
+        "name": "Helmet With White Cross"
+    }, 
+    "✴": {
+        "style": "unicode", 
+        "image": "2734.png", 
+        "name": "Eight Pointed Black Star"
+    }, 
+    ":children_crossing:": {
+        "style": "github", 
+        "image": "1f6b8.png", 
+        "unicode": "🚸", 
+        "name": "Children Crossing"
+    }, 
+    ":flag_jp:": {
+        "style": "github", 
+        "image": "1f1ef-1f1f5.png", 
+        "unicode": "🇯🇵", 
+        "name": "Japan"
+    }, 
+    "🐾": {
+        "style": "unicode", 
+        "image": "1f43e.png", 
+        "name": "Paw Prints"
+    }, 
+    "🇽🇰": {
+        "style": "unicode", 
+        "image": "1f1fd-1f1f0.png", 
+        "name": "Kosovo"
+    }, 
+    ":man-dancing-tone3:": {
+        "style": "github", 
+        "image": "1f57a-1f3fd.png", 
+        "unicode": "🕺🏽", 
+        "name": "Man Dancing - Tone 3"
+    }, 
+    ":oncoming-automobile:": {
+        "style": "github", 
+        "image": "1f698.png", 
+        "unicode": "🚘", 
+        "name": "Oncoming Automobile"
+    }, 
+    "🗓": {
+        "style": "unicode", 
+        "image": "1f5d3.png", 
+        "name": "Spiral Calendar Pad"
+    }, 
+    ":baseball:": {
+        "style": "github", 
+        "image": "26be.png", 
+        "unicode": "⚾", 
+        "name": "Baseball"
+    }, 
+    ":bow-tone3:": {
+        "style": "github", 
+        "image": "1f647-1f3fd.png", 
+        "unicode": "🙇🏽", 
+        "name": "Person Bowing Deeply - Tone 3"
+    }, 
+    ":rice-ball:": {
+        "style": "github", 
+        "image": "1f359.png", 
+        "unicode": "🍙", 
+        "name": "Rice Ball"
+    }, 
+    ":weight_lifter_tone2:": {
+        "style": "github", 
+        "image": "1f3cb-1f3fc.png", 
+        "unicode": "🏋🏼", 
+        "name": "Weight Lifter - Tone 2"
+    }, 
+    ":toilet:": {
+        "style": "github", 
+        "image": "1f6bd.png", 
+        "unicode": "🚽", 
+        "name": "Toilet"
+    }, 
+    ":coffin:": {
+        "style": "github", 
+        "image": "26b0.png", 
+        "unicode": "⚰", 
+        "name": "Coffin"
+    }, 
+    ":mountain-bicyclist:": {
+        "style": "github", 
+        "image": "1f6b5.png", 
+        "unicode": "🚵", 
+        "name": "Mountain Bicyclist"
+    }, 
+    ":heart_eyes:": {
+        "style": "github", 
+        "image": "1f60d.png", 
+        "unicode": "😍", 
+        "name": "Smiling Face With Heart-shaped Eyes"
+    }, 
+    ":mobile_phone_off:": {
+        "style": "github", 
+        "image": "1f4f4.png", 
+        "unicode": "📴", 
+        "name": "Mobile Phone Off"
+    }, 
+    ":flag-ng:": {
+        "style": "github", 
+        "image": "1f1f3-1f1ec.png", 
+        "unicode": "🇳🇬", 
+        "name": "Nigeria"
+    }, 
+    ":four-leaf-clover:": {
+        "style": "github", 
+        "image": "1f340.png", 
+        "unicode": "🍀", 
+        "name": "Four Leaf Clover"
+    }, 
+    ":cartwheel:": {
+        "style": "github", 
+        "image": "1f938.png", 
+        "unicode": "🤸", 
+        "name": "Person Doing Cartwheel"
+    }, 
+    ":punch-tone5:": {
+        "style": "github", 
+        "image": "1f44a-1f3ff.png", 
+        "unicode": "👊🏿", 
+        "name": "Fisted Hand Sign - Tone 5"
+    }, 
+    "🌧": {
+        "style": "unicode", 
+        "image": "1f327.png", 
+        "name": "Cloud With Rain"
+    }, 
+    ":flag_er:": {
+        "style": "github", 
+        "image": "1f1ea-1f1f7.png", 
+        "unicode": "🇪🇷", 
+        "name": "Eritrea"
+    }, 
+    ":mf:": {
+        "style": "github", 
+        "image": "1f1f2-1f1eb.png", 
+        "unicode": "🇲🇫", 
+        "name": "Saint Martin"
+    }, 
+    ":cd:": {
+        "style": "github", 
+        "image": "1f4bf.png", 
+        "unicode": "💿", 
+        "name": "Optical Disc"
+    }, 
+    "🎼": {
+        "style": "unicode", 
+        "image": "1f3bc.png", 
+        "name": "Musical Score"
+    }, 
+    ":flag-pe:": {
+        "style": "github", 
+        "image": "1f1f5-1f1ea.png", 
+        "unicode": "🇵🇪", 
+        "name": "Peru"
+    }, 
+    "O:-3": {
+        "style": "ascii", 
+        "ascii": "O:-)", 
+        "image": "1f607.png", 
+        "unicode": "😇", 
+        "name": "Smiling Face With Halo"
+    }, 
+    ":boxing_gloves:": {
+        "style": "github", 
+        "image": "1f94a.png", 
+        "unicode": "🥊", 
+        "name": "Boxing Glove"
+    }, 
+    "O:-)": {
+        "style": "ascii", 
+        "ascii": "O:-)", 
+        "image": "1f607.png", 
+        "unicode": "😇", 
+        "name": "Smiling Face With Halo"
+    }, 
+    ":no_good_tone4:": {
+        "style": "github", 
+        "image": "1f645-1f3fe.png", 
+        "unicode": "🙅🏾", 
+        "name": "Face With No Good Gesture - Tone 4"
+    }, 
+    ":-1_tone5:": {
+        "style": "github", 
+        "image": "1f44e-1f3ff.png", 
+        "unicode": "👎🏿", 
+        "name": "Thumbs Down Sign - Tone 5"
+    }, 
+    "🕺🏼": {
+        "style": "unicode", 
+        "image": "1f57a-1f3fc.png", 
+        "name": "Man Dancing - Tone 2"
+    }, 
+    "🕺🏽": {
+        "style": "unicode", 
+        "image": "1f57a-1f3fd.png", 
+        "name": "Man Dancing - Tone 3"
+    }, 
+    "🕺🏾": {
+        "style": "unicode", 
+        "image": "1f57a-1f3fe.png", 
+        "name": "Man Dancing - Tone 4"
+    }, 
+    "🕺🏿": {
+        "style": "unicode", 
+        "image": "1f57a-1f3ff.png", 
+        "name": "Man Dancing - Tone 5"
+    }, 
+    "🐔": {
+        "style": "unicode", 
+        "image": "1f414.png", 
+        "name": "Chicken"
+    }, 
+    "🕺🏻": {
+        "style": "unicode", 
+        "image": "1f57a-1f3fb.png", 
+        "name": "Man Dancing - Tone 1"
+    }, 
+    ":baby_tone2:": {
+        "style": "github", 
+        "image": "1f476-1f3fc.png", 
+        "unicode": "👶🏼", 
+        "name": "Baby - Tone 2"
+    }, 
+    ":point-down-tone3:": {
+        "style": "github", 
+        "image": "1f447-1f3fd.png", 
+        "unicode": "👇🏽", 
+        "name": "White Down Pointing Backhand Index - Tone 3"
+    }, 
+    ":flame:": {
+        "style": "github", 
+        "image": "1f525.png", 
+        "unicode": "🔥", 
+        "name": "Fire"
+    }, 
+    ":pray-tone4:": {
+        "style": "github", 
+        "image": "1f64f-1f3fe.png", 
+        "unicode": "🙏🏾", 
+        "name": "Person With Folded Hands - Tone 4"
+    }, 
+    ":arrow_double_down:": {
+        "style": "github", 
+        "image": "23ec.png", 
+        "unicode": "⏬", 
+        "name": "Black Down-pointing Double Triangle"
+    }, 
+    ":hr:": {
+        "style": "github", 
+        "image": "1f1ed-1f1f7.png", 
+        "unicode": "🇭🇷", 
+        "name": "Croatia"
+    }, 
+    ":woman_tone3:": {
+        "style": "github", 
+        "image": "1f469-1f3fd.png", 
+        "unicode": "👩🏽", 
+        "name": "Woman - Tone 3"
+    }, 
+    "⛳": {
+        "style": "unicode", 
+        "image": "26f3.png", 
+        "name": "Flag In Hole"
+    }, 
+    "🇽": {
+        "style": "unicode", 
+        "image": "1f1fd.png", 
+        "name": "Regional Indicator Symbol Letter X"
+    }, 
+    ":hash:": {
+        "style": "github", 
+        "image": "0023-20e3.png", 
+        "unicode": "#⃣", 
+        "name": "Keycap Number Sign"
+    }, 
+    ":expecting_woman:": {
+        "style": "github", 
+        "image": "1f930.png", 
+        "unicode": "🤰", 
+        "name": "Pregnant Woman"
+    }, 
+    ":handball-tone4:": {
+        "style": "github", 
+        "image": "1f93e-1f3fe.png", 
+        "unicode": "🤾🏾", 
+        "name": "Handball - Tone 4"
+    }, 
+    ":cruise_ship:": {
+        "style": "github", 
+        "image": "1f6f3.png", 
+        "unicode": "🛳", 
+        "name": "Passenger Ship"
+    }, 
+    ":open-file-folder:": {
+        "style": "github", 
+        "image": "1f4c2.png", 
+        "unicode": "📂", 
+        "name": "Open File Folder"
+    }, 
+    "🆒": {
+        "style": "unicode", 
+        "image": "1f192.png", 
+        "name": "Squared Cool"
+    }, 
+    ":steam-locomotive:": {
+        "style": "github", 
+        "image": "1f682.png", 
+        "unicode": "🚂", 
+        "name": "Steam Locomotive"
+    }, 
+    ":beach_umbrella:": {
+        "style": "github", 
+        "image": "26f1.png", 
+        "unicode": "⛱", 
+        "name": "Umbrella On Ground"
+    }, 
+    ":waning-gibbous-moon:": {
+        "style": "github", 
+        "image": "1f316.png", 
+        "unicode": "🌖", 
+        "name": "Waning Gibbous Moon Symbol"
+    }, 
+    ":raised-hand-tone1:": {
+        "style": "github", 
+        "image": "270b-1f3fb.png", 
+        "unicode": "✋🏻", 
+        "name": "Raised Hand - Tone 1"
+    }, 
+    ":sg:": {
+        "style": "github", 
+        "image": "1f1f8-1f1ec.png", 
+        "unicode": "🇸🇬", 
+        "name": "Singapore"
+    }, 
+    ":selfie-tone3:": {
+        "style": "github", 
+        "image": "1f933-1f3fd.png", 
+        "unicode": "🤳🏽", 
+        "name": "Selfie - Tone 3"
+    }, 
+    ":fingers_crossed_tone5:": {
+        "style": "github", 
+        "image": "1f91e-1f3ff.png", 
+        "unicode": "🤞🏿", 
+        "name": "Hand With Index And Middle Fingers Crossed - Tone 5"
+    }, 
+    ":flag-gl:": {
+        "style": "github", 
+        "image": "1f1ec-1f1f1.png", 
+        "unicode": "🇬🇱", 
+        "name": "Greenland"
+    }, 
+    "🍑": {
+        "style": "unicode", 
+        "image": "1f351.png", 
+        "name": "Peach"
+    }, 
+    ":smiling-imp:": {
+        "style": "github", 
+        "image": "1f608.png", 
+        "unicode": "😈", 
+        "name": "Smiling Face With Horns"
+    }, 
+    "🕕": {
+        "style": "unicode", 
+        "image": "1f555.png", 
+        "name": "Clock Face Six Oclock"
+    }, 
+    ":hourglass-flowing-sand:": {
+        "style": "github", 
+        "image": "23f3.png", 
+        "unicode": "⏳", 
+        "name": "Hourglass With Flowing Sand"
+    }, 
+    ":disappointed-relieved:": {
+        "style": "github", 
+        "image": "1f625.png", 
+        "unicode": "😥", 
+        "name": "Disappointed But Relieved Face"
+    }, 
+    "🏦": {
+        "style": "unicode", 
+        "image": "1f3e6.png", 
+        "name": "Bank"
+    }, 
+    ":surfer-tone3:": {
+        "style": "github", 
+        "image": "1f3c4-1f3fd.png", 
+        "unicode": "🏄🏽", 
+        "name": "Surfer - Tone 3"
+    }, 
+    ":lifter-tone1:": {
+        "style": "github", 
+        "image": "1f3cb-1f3fb.png", 
+        "unicode": "🏋🏻", 
+        "name": "Weight Lifter - Tone 1"
+    }, 
+    "👿": {
+        "style": "unicode", 
+        "image": "1f47f.png", 
+        "name": "Imp"
+    }, 
+    ":point-up-2-tone3:": {
+        "style": "github", 
+        "image": "1f446-1f3fd.png", 
+        "unicode": "👆🏽", 
+        "name": "White Up Pointing Backhand Index - Tone 3"
+    }, 
+    ":walking_tone2:": {
+        "style": "github", 
+        "image": "1f6b6-1f3fc.png", 
+        "unicode": "🚶🏼", 
+        "name": "Pedestrian - Tone 2"
+    }, 
+    "🇼🇸": {
+        "style": "unicode", 
+        "image": "1f1fc-1f1f8.png", 
+        "name": "Samoa"
+    }, 
+    "🌐": {
+        "style": "unicode", 
+        "image": "1f310.png", 
+        "name": "Globe With Meridians"
+    }, 
+    "🔔": {
+        "style": "unicode", 
+        "image": "1f514.png", 
+        "name": "Bell"
+    }, 
+    "🇼🇫": {
+        "style": "unicode", 
+        "image": "1f1fc-1f1eb.png", 
+        "name": "Wallis And Futuna"
+    }, 
+    ":previous_track:": {
+        "style": "github", 
+        "image": "23ee.png", 
+        "unicode": "⏮", 
+        "name": "Black Left-pointing Double Triangle With Vertical Bar"
+    }, 
+    "🚩": {
+        "style": "unicode", 
+        "image": "1f6a9.png", 
+        "name": "Triangular Flag On Post"
+    }, 
+    ":left_facing_fist_tone5:": {
+        "style": "github", 
+        "image": "1f91b-1f3ff.png", 
+        "unicode": "🤛🏿", 
+        "name": "Left Facing Fist - Tone 5"
+    }, 
+    ":gemini:": {
+        "style": "github", 
+        "image": "264a.png", 
+        "unicode": "♊", 
+        "name": "Gemini"
+    }, 
+    ":o:": {
+        "style": "github", 
+        "image": "2b55.png", 
+        "unicode": "⭕", 
+        "name": "Heavy Large Circle"
+    }, 
+    ":dove_of_peace:": {
+        "style": "github", 
+        "image": "1f54a.png", 
+        "unicode": "🕊", 
+        "name": "Dove Of Peace"
+    }, 
+    "😾": {
+        "style": "unicode", 
+        "image": "1f63e.png", 
+        "name": "Pouting Cat Face"
+    }, 
+    ":helmet_with_cross:": {
+        "style": "github", 
+        "image": "26d1.png", 
+        "unicode": "⛑", 
+        "name": "Helmet With White Cross"
+    }, 
+    ":flag_gm:": {
+        "style": "github", 
+        "image": "1f1ec-1f1f2.png", 
+        "unicode": "🇬🇲", 
+        "name": "The Gambia"
+    }, 
+    "😶": {
+        "style": "unicode", 
+        "ascii": ":-X", 
+        "image": "1f636.png", 
+        "name": "Face Without Mouth"
+    }, 
+    ":couple_ww:": {
+        "style": "github", 
+        "image": "1f469-2764-1f469.png", 
+        "unicode": "👩❤👩", 
+        "name": "Couple (woman,woman)"
+    }, 
+    ":kw:": {
+        "style": "github", 
+        "image": "1f1f0-1f1fc.png", 
+        "unicode": "🇰🇼", 
+        "name": "Kuwait"
+    }, 
+    ":notebook-with-decorative-cover:": {
+        "style": "github", 
+        "image": "1f4d4.png", 
+        "unicode": "📔", 
+        "name": "Notebook With Decorative Cover"
+    }, 
+    ">;)": {
+        "style": "ascii", 
+        "ascii": ">:)", 
+        "image": "1f606.png", 
+        "unicode": "😆", 
+        "name": "Smiling Face With Open Mouth And Tightly-closed Eyes"
+    }, 
+    ":innocent:": {
+        "style": "github", 
+        "ascii": "O:-)", 
+        "image": "1f607.png", 
+        "unicode": "😇", 
+        "name": "Smiling Face With Halo"
+    }, 
+    ":flag-si:": {
+        "style": "github", 
+        "image": "1f1f8-1f1ee.png", 
+        "unicode": "🇸🇮", 
+        "name": "Slovenia"
+    }, 
+    ":wrestling_tone3:": {
+        "style": "github", 
+        "image": "1f93c-1f3fd.png", 
+        "unicode": "🤼🏽", 
+        "name": "Wrestlers - Tone 3"
+    }, 
+    ":white-medium-square:": {
+        "style": "github", 
+        "image": "25fb.png", 
+        "unicode": "◻", 
+        "name": "White Medium Square"
+    }, 
+    ":iq:": {
+        "style": "github", 
+        "image": "1f1ee-1f1f6.png", 
+        "unicode": "🇮🇶", 
+        "name": "Iraq"
+    }, 
+    ":game-die:": {
+        "style": "github", 
+        "image": "1f3b2.png", 
+        "unicode": "🎲", 
+        "name": "Game Die"
+    }, 
+    "1⃣": {
+        "style": "unicode", 
+        "image": "0031-20e3.png", 
+        "name": "Keycap Digit One"
+    }, 
+    ":information_desk_person_tone4:": {
+        "style": "github", 
+        "image": "1f481-1f3fe.png", 
+        "unicode": "💁🏾", 
+        "name": "Information Desk Person - Tone 4"
+    }, 
+    "🉑": {
+        "style": "unicode", 
+        "image": "1f251.png", 
+        "name": "Circled Ideograph Accept"
+    }, 
+    "👕": {
+        "style": "unicode", 
+        "image": "1f455.png", 
+        "name": "T-shirt"
+    }, 
+    ":raised-back-of-hand-tone5:": {
+        "style": "github", 
+        "image": "1f91a-1f3ff.png", 
+        "unicode": "🤚🏿", 
+        "name": "Raised Back Of Hand - Tone 5"
+    }, 
+    "🕵🏽": {
+        "style": "unicode", 
+        "image": "1f575-1f3fd.png", 
+        "name": "Sleuth Or Spy - Tone 3"
+    }, 
+    "🕵🏼": {
+        "style": "unicode", 
+        "image": "1f575-1f3fc.png", 
+        "name": "Sleuth Or Spy - Tone 2"
+    }, 
+    "🕵🏿": {
+        "style": "unicode", 
+        "image": "1f575-1f3ff.png", 
+        "name": "Sleuth Or Spy - Tone 5"
+    }, 
+    "🕵🏾": {
+        "style": "unicode", 
+        "image": "1f575-1f3fe.png", 
+        "name": "Sleuth Or Spy - Tone 4"
+    }, 
+    "🕵🏻": {
+        "style": "unicode", 
+        "image": "1f575-1f3fb.png", 
+        "name": "Sleuth Or Spy - Tone 1"
+    }, 
+    "📪": {
+        "style": "unicode", 
+        "image": "1f4ea.png", 
+        "name": "Closed Mailbox With Lowered Flag"
+    }, 
+    ":ear_tone3:": {
+        "style": "github", 
+        "image": "1f442-1f3fd.png", 
+        "unicode": "👂🏽", 
+        "name": "Ear - Tone 3"
+    }, 
+    "👨❤💋👨": {
+        "style": "unicode", 
+        "image": "1f468-2764-1f48b-1f468.png", 
+        "name": "Kiss (man,man)"
+    }, 
+    ":bookmark_tabs:": {
+        "style": "github", 
+        "image": "1f4d1.png", 
+        "unicode": "📑", 
+        "name": "Bookmark Tabs"
+    }, 
+    "🍻": {
+        "style": "unicode", 
+        "image": "1f37b.png", 
+        "name": "Clinking Beer Mugs"
+    }, 
+    ":handshake_tone2:": {
+        "style": "github", 
+        "image": "1f91d-1f3fc.png", 
+        "unicode": "🤝🏼", 
+        "name": "Handshake - Tone 2"
+    }, 
+    ":ok:": {
+        "style": "github", 
+        "image": "1f197.png", 
+        "unicode": "🆗", 
+        "name": "Squared Ok"
+    }, 
+    ":construction_worker_tone5:": {
+        "style": "github", 
+        "image": "1f477-1f3ff.png", 
+        "unicode": "👷🏿", 
+        "name": "Construction Worker - Tone 5"
+    }, 
+    "🐐": {
+        "style": "unicode", 
+        "image": "1f410.png", 
+        "name": "Goat"
+    }, 
+    ":juggling-tone3:": {
+        "style": "github", 
+        "image": "1f939-1f3fd.png", 
+        "unicode": "🤹🏽", 
+        "name": "Juggling - Tone 3"
+    }, 
+    "B-)": {
+        "style": "ascii", 
+        "ascii": "B-)", 
+        "image": "1f60e.png", 
+        "unicode": "😎", 
+        "name": "Smiling Face With Sunglasses"
+    }, 
+    ":regional-indicator-y:": {
+        "style": "github", 
+        "image": "1f1fe.png", 
+        "unicode": "🇾", 
+        "name": "Regional Indicator Symbol Letter Y"
+    }, 
+    ":shallow_pan_of_food:": {
+        "style": "github", 
+        "image": "1f958.png", 
+        "unicode": "🥘", 
+        "name": "Shallow Pan Of Food"
+    }, 
+    "B-D": {
+        "style": "ascii", 
+        "ascii": "B-)", 
+        "image": "1f60e.png", 
+        "unicode": "😎", 
+        "name": "Smiling Face With Sunglasses"
+    }, 
+    ":flag_az:": {
+        "style": "github", 
+        "image": "1f1e6-1f1ff.png", 
+        "unicode": "🇦🇿", 
+        "name": "Azerbaijan"
+    }, 
+    ":stadium:": {
+        "style": "github", 
+        "image": "1f3df.png", 
+        "unicode": "🏟", 
+        "name": "Stadium"
+    }, 
+    ":house:": {
+        "style": "github", 
+        "image": "1f3e0.png", 
+        "unicode": "🏠", 
+        "name": "House Building"
+    }, 
+    ":open_mouth:": {
+        "style": "github", 
+        "ascii": ":-O", 
+        "image": "1f62e.png", 
+        "unicode": "😮", 
+        "name": "Face With Open Mouth"
+    }, 
+    ":flag-tt:": {
+        "style": "github", 
+        "image": "1f1f9-1f1f9.png", 
+        "unicode": "🇹🇹", 
+        "name": "Trinidad And Tobago"
+    }, 
+    ":flag_um:": {
+        "style": "github", 
+        "image": "1f1fa-1f1f2.png", 
+        "unicode": "🇺🇲", 
+        "name": "United States Minor Outlying Islands"
+    }, 
+    ":'(": {
+        "style": "ascii", 
+        "ascii": ":'(", 
+        "image": "1f622.png", 
+        "unicode": "😢", 
+        "name": "Crying Face"
+    }, 
+    ":')": {
+        "style": "ascii", 
+        "ascii": ":')", 
+        "image": "1f602.png", 
+        "unicode": "😂", 
+        "name": "Face With Tears Of Joy"
+    }, 
+    ":rowboat_tone4:": {
+        "style": "github", 
+        "image": "1f6a3-1f3fe.png", 
+        "unicode": "🚣🏾", 
+        "name": "Rowboat - Tone 4"
+    }, 
+    ":regional_indicator_q:": {
+        "style": "github", 
+        "image": "1f1f6.png", 
+        "unicode": "🇶", 
+        "name": "Regional Indicator Symbol Letter Q"
+    }, 
+    "#)": {
+        "style": "ascii", 
+        "ascii": "#-)", 
+        "image": "1f635.png", 
+        "unicode": "😵", 
+        "name": "Dizzy Face"
+    }, 
+    ":baby-chick:": {
+        "style": "github", 
+        "image": "1f424.png", 
+        "unicode": "🐤", 
+        "name": "Baby Chick"
+    }, 
+    ":massage-tone5:": {
+        "style": "github", 
+        "image": "1f486-1f3ff.png", 
+        "unicode": "💆🏿", 
+        "name": "Face Massage - Tone 5"
+    }, 
+    "🦎": {
+        "style": "unicode", 
+        "image": "1f98e.png", 
+        "name": "Lizard"
+    }, 
+    ":tj:": {
+        "style": "github", 
+        "image": "1f1f9-1f1ef.png", 
+        "unicode": "🇹🇯", 
+        "name": "Tajikistan"
+    }, 
+    ":paintbrush:": {
+        "style": "github", 
+        "image": "1f58c.png", 
+        "unicode": "🖌", 
+        "name": "Lower Left Paintbrush"
+    }, 
+    "✝": {
+        "style": "unicode", 
+        "image": "271d.png", 
+        "name": "Latin Cross"
+    }, 
+    ":nail_care_tone1:": {
+        "style": "github", 
+        "image": "1f485-1f3fb.png", 
+        "unicode": "💅🏻", 
+        "name": "Nail Polish - Tone 1"
+    }, 
+    "😧": {
+        "style": "unicode", 
+        "image": "1f627.png", 
+        "name": "Anguished Face"
+    }, 
+    ":paella:": {
+        "style": "github", 
+        "image": "1f958.png", 
+        "unicode": "🥘", 
+        "name": "Shallow Pan Of Food"
+    }, 
+    ":banana:": {
+        "style": "github", 
+        "image": "1f34c.png", 
+        "unicode": "🍌", 
+        "name": "Banana"
+    }, 
+    "🚼": {
+        "style": "unicode", 
+        "image": "1f6bc.png", 
+        "name": "Baby Symbol"
+    }, 
+    "🕑": {
+        "style": "unicode", 
+        "image": "1f551.png", 
+        "name": "Clock Face Two Oclock"
+    }, 
+    "🍕": {
+        "style": "unicode", 
+        "image": "1f355.png", 
+        "name": "Slice Of Pizza"
+    }, 
+    ":man-with-turban-tone1:": {
+        "style": "github", 
+        "image": "1f473-1f3fb.png", 
+        "unicode": "👳🏻", 
+        "name": "Man With Turban - Tone 1"
+    }, 
+    ":flag_mg:": {
+        "style": "github", 
+        "image": "1f1f2-1f1ec.png", 
+        "unicode": "🇲🇬", 
+        "name": "Madagascar"
+    }, 
+    ":shirt:": {
+        "style": "github", 
+        "image": "1f455.png", 
+        "unicode": "👕", 
+        "name": "T-shirt"
+    }, 
+    "🏪": {
+        "style": "unicode", 
+        "image": "1f3ea.png", 
+        "name": "Convenience Store"
+    }, 
+    ":fire_engine:": {
+        "style": "github", 
+        "image": "1f692.png", 
+        "unicode": "🚒", 
+        "name": "Fire Engine"
+    }, 
+    ":flag-km:": {
+        "style": "github", 
+        "image": "1f1f0-1f1f2.png", 
+        "unicode": "🇰🇲", 
+        "name": "The Comoros"
+    }, 
+    ":lk:": {
+        "style": "github", 
+        "image": "1f1f1-1f1f0.png", 
+        "unicode": "🇱🇰", 
+        "name": "Sri Lanka"
+    }, 
+    "👻": {
+        "style": "unicode", 
+        "image": "1f47b.png", 
+        "name": "Ghost"
+    }, 
+    ":be:": {
+        "style": "github", 
+        "image": "1f1e7-1f1ea.png", 
+        "unicode": "🇧🇪", 
+        "name": "Belgium"
+    }, 
+    "🔐": {
+        "style": "unicode", 
+        "image": "1f510.png", 
+        "name": "Closed Lock With Key"
+    }, 
+    "🌔": {
+        "style": "unicode", 
+        "image": "1f314.png", 
+        "name": "Waxing Gibbous Moon Symbol"
+    }, 
+    ":vulcan_tone1:": {
+        "style": "github", 
+        "image": "1f596-1f3fb.png", 
+        "unicode": "🖖🏻", 
+        "name": "Raised Hand With Part Between Middle And Ring Fingers - Tone 1"
+    }, 
+    ":flag-cm:": {
+        "style": "github", 
+        "image": "1f1e8-1f1f2.png", 
+        "unicode": "🇨🇲", 
+        "name": "Cameroon"
+    }, 
+    "👲🏼": {
+        "style": "unicode", 
+        "image": "1f472-1f3fc.png", 
+        "name": "Man With Gua Pi Mao - Tone 2"
+    }, 
+    "👲🏽": {
+        "style": "unicode", 
+        "image": "1f472-1f3fd.png", 
+        "name": "Man With Gua Pi Mao - Tone 3"
+    }, 
+    "👲🏾": {
+        "style": "unicode", 
+        "image": "1f472-1f3fe.png", 
+        "name": "Man With Gua Pi Mao - Tone 4"
+    }, 
+    "👲🏿": {
+        "style": "unicode", 
+        "image": "1f472-1f3ff.png", 
+        "name": "Man With Gua Pi Mao - Tone 5"
+    }, 
+    ":crying_cat_face:": {
+        "style": "github", 
+        "image": "1f63f.png", 
+        "unicode": "😿", 
+        "name": "Crying Cat Face"
+    }, 
+    "👲🏻": {
+        "style": "unicode", 
+        "image": "1f472-1f3fb.png", 
+        "name": "Man With Gua Pi Mao - Tone 1"
+    }, 
+    ":grandma:": {
+        "style": "github", 
+        "image": "1f475.png", 
+        "unicode": "👵", 
+        "name": "Older Woman"
+    }, 
+    ":princess_tone2:": {
+        "style": "github", 
+        "image": "1f478-1f3fc.png", 
+        "unicode": "👸🏼", 
+        "name": "Princess - Tone 2"
+    }, 
+    ":hamburger:": {
+        "style": "github", 
+        "image": "1f354.png", 
+        "unicode": "🍔", 
+        "name": "Hamburger"
+    }, 
+    ":champagne_glass:": {
+        "style": "github", 
+        "image": "1f942.png", 
+        "unicode": "🥂", 
+        "name": "Clinking Glasses"
+    }, 
+    ":speech-left:": {
+        "style": "github", 
+        "image": "1f5e8.png", 
+        "unicode": "🗨", 
+        "name": "Left Speech Bubble"
+    }, 
+    ":flag_ht:": {
+        "style": "github", 
+        "image": "1f1ed-1f1f9.png", 
+        "unicode": "🇭🇹", 
+        "name": "Haiti"
+    }, 
+    ":open_hands_tone3:": {
+        "style": "github", 
+        "image": "1f450-1f3fd.png", 
+        "unicode": "👐🏽", 
+        "name": "Open Hands Sign - Tone 3"
+    }, 
+    ":flag_th:": {
+        "style": "github", 
+        "image": "1f1f9-1f1ed.png", 
+        "unicode": "🇹🇭", 
+        "name": "Thailand"
+    }, 
+    ":flag_bb:": {
+        "style": "github", 
+        "image": "1f1e7-1f1e7.png", 
+        "unicode": "🇧🇧", 
+        "name": "Barbados"
+    }, 
+    ":flag-bi:": {
+        "style": "github", 
+        "image": "1f1e7-1f1ee.png", 
+        "unicode": "🇧🇮", 
+        "name": "Burundi"
+    }, 
+    "🚒": {
+        "style": "unicode", 
+        "image": "1f692.png", 
+        "name": "Fire Engine"
+    }, 
+    "☝": {
+        "style": "unicode", 
+        "image": "261d.png", 
+        "name": "White Up Pointing Index"
+    }, 
+    ":massage_tone4:": {
+        "style": "github", 
+        "image": "1f486-1f3fe.png", 
+        "unicode": "💆🏾", 
+        "name": "Face Massage - Tone 4"
+    }, 
+    "🤣": {
+        "style": "unicode", 
+        "image": "1f923.png", 
+        "name": "Rolling On The Floor Laughing"
+    }, 
+    ":horse-racing:": {
+        "style": "github", 
+        "image": "1f3c7.png", 
+        "unicode": "🏇", 
+        "name": "Horse Racing"
+    }, 
+    ":family-mmg:": {
+        "style": "github", 
+        "image": "1f468-1f468-1f467.png", 
+        "unicode": "👨👨👧", 
+        "name": "Family (man,man,girl)"
+    }, 
+    ":reversed_hand_with_middle_finger_extended_tone2:": {
+        "style": "github", 
+        "image": "1f595-1f3fc.png", 
+        "unicode": "🖕🏼", 
+        "name": "Reversed Hand With Middle Finger Extended - Tone 2"
+    }, 
+    ":ear-tone4:": {
+        "style": "github", 
+        "image": "1f442-1f3fe.png", 
+        "unicode": "👂🏾", 
+        "name": "Ear - Tone 4"
+    }, 
+    "🇮🇨": {
+        "style": "unicode", 
+        "image": "1f1ee-1f1e8.png", 
+        "name": "Canary Islands"
+    }, 
+    ":bow-tone5:": {
+        "style": "github", 
+        "image": "1f647-1f3ff.png", 
+        "unicode": "🙇🏿", 
+        "name": "Person Bowing Deeply - Tone 5"
+    }, 
+    "❇": {
+        "style": "unicode", 
+        "image": "2747.png", 
+        "name": "Sparkle"
+    }, 
+    "👴🏿": {
+        "style": "unicode", 
+        "image": "1f474-1f3ff.png", 
+        "name": "Older Man - Tone 5"
+    }, 
+    ":call-me-tone4:": {
+        "style": "github", 
+        "image": "1f919-1f3fe.png", 
+        "unicode": "🤙🏾", 
+        "name": "Call Me Hand - Tone 4"
+    }, 
+    "👴🏼": {
+        "style": "unicode", 
+        "image": "1f474-1f3fc.png", 
+        "name": "Older Man - Tone 2"
+    }, 
+    ":flag-gq:": {
+        "style": "github", 
+        "image": "1f1ec-1f1f6.png", 
+        "unicode": "🇬🇶", 
+        "name": "Equatorial Guinea"
+    }, 
+    ":kiss-ww:": {
+        "style": "github", 
+        "image": "1f469-2764-1f48b-1f469.png", 
+        "unicode": "👩❤💋👩", 
+        "name": "Kiss (woman,woman)"
+    }, 
+    ":thunder_cloud_and_rain:": {
+        "style": "github", 
+        "image": "26c8.png", 
+        "unicode": "⛈", 
+        "name": "Thunder Cloud And Rain"
+    }, 
+    ":spy:": {
+        "style": "github", 
+        "image": "1f575.png", 
+        "unicode": "🕵", 
+        "name": "Sleuth Or Spy"
+    }, 
+    ":man-dancing-tone1:": {
+        "style": "github", 
+        "image": "1f57a-1f3fb.png", 
+        "unicode": "🕺🏻", 
+        "name": "Man Dancing - Tone 1"
+    }, 
+    "📦": {
+        "style": "unicode", 
+        "image": "1f4e6.png", 
+        "name": "Package"
+    }, 
+    ":flag_sm:": {
+        "style": "github", 
+        "image": "1f1f8-1f1f2.png", 
+        "unicode": "🇸🇲", 
+        "name": "San Marino"
+    }, 
+    "🍿": {
+        "style": "unicode", 
+        "image": "1f37f.png", 
+        "name": "Popcorn"
+    }, 
+    ":point-down:": {
+        "style": "github", 
+        "image": "1f447.png", 
+        "unicode": "👇", 
+        "name": "White Down Pointing Backhand Index"
+    }, 
+    ":new-moon:": {
+        "style": "github", 
+        "image": "1f311.png", 
+        "unicode": "🌑", 
+        "name": "New Moon Symbol"
+    }, 
+    "😐": {
+        "style": "unicode", 
+        "image": "1f610.png", 
+        "name": "Neutral Face"
+    }, 
+    ":flag_et:": {
+        "style": "github", 
+        "image": "1f1ea-1f1f9.png", 
+        "unicode": "🇪🇹", 
+        "name": "Ethiopia"
+    }, 
+    ":flag-ne:": {
+        "style": "github", 
+        "image": "1f1f3-1f1ea.png", 
+        "unicode": "🇳🇪", 
+        "name": "Niger"
+    }, 
+    "⚛": {
+        "style": "unicode", 
+        "image": "269b.png", 
+        "name": "Atom Symbol"
+    }, 
+    ":movie_camera:": {
+        "style": "github", 
+        "image": "1f3a5.png", 
+        "unicode": "🎥", 
+        "name": "Movie Camera"
+    }, 
+    "🎩": {
+        "style": "unicode", 
+        "image": "1f3a9.png", 
+        "name": "Top Hat"
+    }, 
+    ":mx:": {
+        "style": "github", 
+        "image": "1f1f2-1f1fd.png", 
+        "unicode": "🇲🇽", 
+        "name": "Mexico"
+    }, 
+    ":no_bell:": {
+        "style": "github", 
+        "image": "1f515.png", 
+        "unicode": "🔕", 
+        "name": "Bell With Cancellation Stroke"
+    }, 
+    "🤺": {
+        "style": "unicode", 
+        "image": "1f93a.png", 
+        "name": "Fencer"
+    }, 
+    "🌾": {
+        "style": "unicode", 
+        "image": "1f33e.png", 
+        "name": "Ear Of Rice"
+    }, 
+    ":flag-pg:": {
+        "style": "github", 
+        "image": "1f1f5-1f1ec.png", 
+        "unicode": "🇵🇬", 
+        "name": "Papua New Guinea"
+    }, 
+    "🚶": {
+        "style": "unicode", 
+        "image": "1f6b6.png", 
+        "name": "Pedestrian"
+    }, 
+    "🎸": {
+        "style": "unicode", 
+        "image": "1f3b8.png", 
+        "name": "Guitar"
+    }, 
+    ":flag_us:": {
+        "style": "github", 
+        "image": "1f1fa-1f1f8.png", 
+        "unicode": "🇺🇸", 
+        "name": "United States"
+    }, 
+    ":bz:": {
+        "style": "github", 
+        "image": "1f1e7-1f1ff.png", 
+        "unicode": "🇧🇿", 
+        "name": "Belize"
+    }, 
+    ":twisted_rightwards_arrows:": {
+        "style": "github", 
+        "image": "1f500.png", 
+        "unicode": "🔀", 
+        "name": "Twisted Rightwards Arrows"
+    }, 
+    ":sleuth_or_spy_tone2:": {
+        "style": "github", 
+        "image": "1f575-1f3fc.png", 
+        "unicode": "🕵🏼", 
+        "name": "Sleuth Or Spy - Tone 2"
+    }, 
+    ":bike:": {
+        "style": "github", 
+        "image": "1f6b2.png", 
+        "unicode": "🚲", 
+        "name": "Bicycle"
+    }, 
+    "🗽": {
+        "style": "unicode", 
+        "image": "1f5fd.png", 
+        "name": "Statue Of Liberty"
+    }, 
+    ":notepad_spiral:": {
+        "style": "github", 
+        "image": "1f5d2.png", 
+        "unicode": "🗒", 
+        "name": "Spiral Note Pad"
+    }, 
+    ":large-blue-circle:": {
+        "style": "github", 
+        "image": "1f535.png", 
+        "unicode": "🔵", 
+        "name": "Large Blue Circle"
+    }, 
+    ":point-down-tone1:": {
+        "style": "github", 
+        "image": "1f447-1f3fb.png", 
+        "unicode": "👇🏻", 
+        "name": "White Down Pointing Backhand Index - Tone 1"
+    }, 
+    "#-)": {
+        "style": "ascii", 
+        "ascii": "#-)", 
+        "image": "1f635.png", 
+        "unicode": "😵", 
+        "name": "Dizzy Face"
+    }, 
+    ":white_medium_square:": {
+        "style": "github", 
+        "image": "25fb.png", 
+        "unicode": "◻", 
+        "name": "White Medium Square"
+    }, 
+    ":heavy-multiplication-x:": {
+        "style": "github", 
+        "image": "2716.png", 
+        "unicode": "✖", 
+        "name": "Heavy Multiplication X"
+    }, 
+    "💼": {
+        "style": "unicode", 
+        "image": "1f4bc.png", 
+        "name": "Briefcase"
+    }, 
+    ":milky-way:": {
+        "style": "github", 
+        "image": "1f30c.png", 
+        "unicode": "🌌", 
+        "name": "Milky Way"
+    }, 
+    ":fingers-crossed-tone2:": {
+        "style": "github", 
+        "image": "1f91e-1f3fc.png", 
+        "unicode": "🤞🏼", 
+        "name": "Hand With Index And Middle Fingers Crossed - Tone 2"
+    }, 
+    "🇪": {
+        "style": "unicode", 
+        "image": "1f1ea.png", 
+        "name": "Regional Indicator Symbol Letter E"
+    }, 
+    ":woman_tone5:": {
+        "style": "github", 
+        "image": "1f469-1f3ff.png", 
+        "unicode": "👩🏿", 
+        "name": "Woman - Tone 5"
+    }, 
+    "🌁": {
+        "style": "unicode", 
+        "image": "1f301.png", 
+        "name": "Foggy"
+    }, 
+    ":tennis:": {
+        "style": "github", 
+        "image": "1f3be.png", 
+        "unicode": "🎾", 
+        "name": "Tennis Racquet And Ball"
+    }, 
+    ":flag_ta:": {
+        "style": "github", 
+        "image": "1f1f9-1f1e6.png", 
+        "unicode": "🇹🇦", 
+        "name": "Tristan Da Cunha"
+    }, 
+    ":hatched-chick:": {
+        "style": "github", 
+        "image": "1f425.png", 
+        "unicode": "🐥", 
+        "name": "Front-facing Baby Chick"
+    }, 
+    ":selfie-tone5:": {
+        "style": "github", 
+        "image": "1f933-1f3ff.png", 
+        "unicode": "🤳🏿", 
+        "name": "Selfie - Tone 5"
+    }, 
+    "🏊🏽": {
+        "style": "unicode", 
+        "image": "1f3ca-1f3fd.png", 
+        "name": "Swimmer - Tone 3"
+    }, 
+    "🏊🏾": {
+        "style": "unicode", 
+        "image": "1f3ca-1f3fe.png", 
+        "name": "Swimmer - Tone 4"
+    }, 
+    "🏊🏿": {
+        "style": "unicode", 
+        "image": "1f3ca-1f3ff.png", 
+        "name": "Swimmer - Tone 5"
+    }, 
+    "🏊🏻": {
+        "style": "unicode", 
+        "image": "1f3ca-1f3fb.png", 
+        "name": "Swimmer - Tone 1"
+    }, 
+    ":se:": {
+        "style": "github", 
+        "image": "1f1f8-1f1ea.png", 
+        "unicode": "🇸🇪", 
+        "name": "Sweden"
+    }, 
+    ":flag-vu:": {
+        "style": "github", 
+        "image": "1f1fb-1f1fa.png", 
+        "unicode": "🇻🇺", 
+        "name": "Vanuatu"
+    }, 
+    ":spy_tone4:": {
+        "style": "github", 
+        "image": "1f575-1f3fe.png", 
+        "unicode": "🕵🏾", 
+        "name": "Sleuth Or Spy - Tone 4"
+    }, 
+    ":man:": {
+        "style": "github", 
+        "image": "1f468.png", 
+        "unicode": "👨", 
+        "name": "Man"
+    }, 
+    ":flag_dk:": {
+        "style": "github", 
+        "image": "1f1e9-1f1f0.png", 
+        "unicode": "🇩🇰", 
+        "name": "Denmark"
+    }, 
+    ":leaves:": {
+        "style": "github", 
+        "image": "1f343.png", 
+        "unicode": "🍃", 
+        "name": "Leaf Fluttering In Wind"
+    }, 
+    ":flag-gn:": {
+        "style": "github", 
+        "image": "1f1ec-1f1f3.png", 
+        "unicode": "🇬🇳", 
+        "name": "Guinea"
+    }, 
+    ":nf:": {
+        "style": "github", 
+        "image": "1f1f3-1f1eb.png", 
+        "unicode": "🇳🇫", 
+        "name": "Norfolk Island"
+    }, 
+    "🏓": {
+        "style": "unicode", 
+        "image": "1f3d3.png", 
+        "name": "Table Tennis Paddle And Ball"
+    }, 
+    ":bust_in_silhouette:": {
+        "style": "github", 
+        "image": "1f464.png", 
+        "unicode": "👤", 
+        "name": "Bust In Silhouette"
+    }, 
+    ":fingers_crossed_tone3:": {
+        "style": "github", 
+        "image": "1f91e-1f3fd.png", 
+        "unicode": "🤞🏽", 
+        "name": "Hand With Index And Middle Fingers Crossed - Tone 3"
+    }, 
+    ":pig-nose:": {
+        "style": "github", 
+        "image": "1f43d.png", 
+        "unicode": "🐽", 
+        "name": "Pig Nose"
+    }, 
+    ":croissant:": {
+        "style": "github", 
+        "image": "1f950.png", 
+        "unicode": "🥐", 
+        "name": "Croissant"
+    }, 
+    ":surfer_tone5:": {
+        "style": "github", 
+        "image": "1f3c4-1f3ff.png", 
+        "unicode": "🏄🏿", 
+        "name": "Surfer - Tone 5"
+    }, 
+    ":writing-hand-tone2:": {
+        "style": "github", 
+        "image": "270d-1f3fc.png", 
+        "unicode": "✍🏼", 
+        "name": "Writing Hand - Tone 2"
+    }, 
+    ":suspension_railway:": {
+        "style": "github", 
+        "image": "1f69f.png", 
+        "unicode": "🚟", 
+        "name": "Suspension Railway"
+    }, 
+    "⏳": {
+        "style": "unicode", 
+        "image": "23f3.png", 
+        "name": "Hourglass With Flowing Sand"
+    }, 
+    ":flag-tk:": {
+        "style": "github", 
+        "image": "1f1f9-1f1f0.png", 
+        "unicode": "🇹🇰", 
+        "name": "Tokelau"
+    }, 
+    "📽": {
+        "style": "unicode", 
+        "image": "1f4fd.png", 
+        "name": "Film Projector"
+    }, 
+    ":credit_card:": {
+        "style": "github", 
+        "image": "1f4b3.png", 
+        "unicode": "💳", 
+        "name": "Credit Card"
+    }, 
+    ":dragon_face:": {
+        "style": "github", 
+        "image": "1f432.png", 
+        "unicode": "🐲", 
+        "name": "Dragon Face"
+    }, 
+    ":point-up-2-tone5:": {
+        "style": "github", 
+        "image": "1f446-1f3ff.png", 
+        "unicode": "👆🏿", 
+        "name": "White Up Pointing Backhand Index - Tone 5"
+    }, 
+    "💒": {
+        "style": "unicode", 
+        "image": "1f492.png", 
+        "name": "Wedding"
+    }, 
+    "🔧": {
+        "style": "unicode", 
+        "image": "1f527.png", 
+        "name": "Wrench"
+    }, 
+    ":clock130:": {
+        "style": "github", 
+        "image": "1f55c.png", 
+        "unicode": "🕜", 
+        "name": "Clock Face One-thirty"
+    }, 
+    ":left_facing_fist_tone3:": {
+        "style": "github", 
+        "image": "1f91b-1f3fd.png", 
+        "unicode": "🤛🏽", 
+        "name": "Left Facing Fist - Tone 3"
+    }, 
+    ":necktie:": {
+        "style": "github", 
+        "image": "1f454.png", 
+        "unicode": "👔", 
+        "name": "Necktie"
+    }, 
+    ":girl:": {
+        "style": "github", 
+        "image": "1f467.png", 
+        "unicode": "👧", 
+        "name": "Girl"
+    }, 
+    "🖼": {
+        "style": "unicode", 
+        "image": "1f5bc.png", 
+        "name": "Frame With Picture"
+    }, 
+    ":u6307:": {
+        "style": "github", 
+        "image": "1f22f.png", 
+        "unicode": "🈯", 
+        "name": "Squared Cjk Unified Ideograph-6307"
+    }, 
+    ":ac:": {
+        "style": "github", 
+        "image": "1f1e6-1f1e8.png", 
+        "unicode": "🇦🇨", 
+        "name": "Ascension"
+    }, 
+    ":shinto-shrine:": {
+        "style": "github", 
+        "image": "26e9.png", 
+        "unicode": "⛩", 
+        "name": "Shinto Shrine"
+    }, 
+    ":crossed-swords:": {
+        "style": "github", 
+        "image": "2694.png", 
+        "unicode": "⚔", 
+        "name": "Crossed Swords"
+    }, 
+    ":right-facing-fist-tone2:": {
+        "style": "github", 
+        "image": "1f91c-1f3fc.png", 
+        "unicode": "🤜🏼", 
+        "name": "Right Facing Fist - Tone 2"
+    }, 
+    "🅿": {
+        "style": "unicode", 
+        "image": "1f17f.png", 
+        "name": "Negative Squared Latin Capital Letter P"
+    }, 
+    ":pound:": {
+        "style": "github", 
+        "image": "1f4b7.png", 
+        "unicode": "💷", 
+        "name": "Banknote With Pound Sign"
+    }, 
+    ":arrow_double_up:": {
+        "style": "github", 
+        "image": "23eb.png", 
+        "unicode": "⏫", 
+        "name": "Black Up-pointing Double Triangle"
+    }, 
+    "😄": {
+        "style": "unicode", 
+        "image": "1f604.png", 
+        "name": "Smiling Face With Open Mouth And Smiling Eyes"
+    }, 
+    ":is:": {
+        "style": "github", 
+        "image": "1f1ee-1f1f8.png", 
+        "unicode": "🇮🇸", 
+        "name": "Iceland"
+    }, 
+    ":face_palm_tone2:": {
+        "style": "github", 
+        "image": "1f926-1f3fc.png", 
+        "unicode": "🤦🏼", 
+        "name": "Face Palm - Tone 2"
+    }, 
+    "㊗": {
+        "style": "unicode", 
+        "image": "3297.png", 
+        "name": "Circled Ideograph Congratulation"
+    }, 
+    ":wrestling_tone1:": {
+        "style": "github", 
+        "image": "1f93c-1f3fb.png", 
+        "unicode": "🤼🏻", 
+        "name": "Wrestlers - Tone 1"
+    }, 
+    "🔮": {
+        "style": "unicode", 
+        "image": "1f52e.png", 
+        "name": "Crystal Ball"
+    }, 
+    ":dog2:": {
+        "style": "github", 
+        "image": "1f415.png", 
+        "unicode": "🐕", 
+        "name": "Dog"
+    }, 
+    "📃": {
+        "style": "unicode", 
+        "image": "1f4c3.png", 
+        "name": "Page With Curl"
+    }, 
+    ":hm:": {
+        "style": "github", 
+        "image": "1f1ed-1f1f2.png", 
+        "unicode": "🇭🇲", 
+        "name": "Heard Island And Mcdonald Islands"
+    }, 
+    ":grey_exclamation:": {
+        "style": "github", 
+        "image": "2755.png", 
+        "unicode": "❕", 
+        "name": "White Exclamation Mark Ornament"
+    }, 
+    "👘": {
+        "style": "unicode", 
+        "image": "1f458.png", 
+        "name": "Kimono"
+    }, 
+    ":pl:": {
+        "style": "github", 
+        "image": "1f1f5-1f1f1.png", 
+        "unicode": "🇵🇱", 
+        "name": "Poland"
+    }, 
+    ":goal_net:": {
+        "style": "github", 
+        "image": "1f945.png", 
+        "unicode": "🥅", 
+        "name": "Goal Net"
+    }, 
+    ":black-medium-square:": {
+        "style": "github", 
+        "image": "25fc.png", 
+        "unicode": "◼", 
+        "name": "Black Medium Square"
+    }, 
+    "🏭": {
+        "style": "unicode", 
+        "image": "1f3ed.png", 
+        "name": "Factory"
+    }, 
+    ":handshake_tone4:": {
+        "style": "github", 
+        "image": "1f91d-1f3fe.png", 
+        "unicode": "🤝🏾", 
+        "name": "Handshake - Tone 4"
+    }, 
+    ":princess:": {
+        "style": "github", 
+        "image": "1f478.png", 
+        "unicode": "👸", 
+        "name": "Princess"
+    }, 
+    "🎂": {
+        "style": "unicode", 
+        "image": "1f382.png", 
+        "name": "Birthday Cake"
+    }, 
+    "🦆": {
+        "style": "unicode", 
+        "image": "1f986.png", 
+        "name": "Duck"
+    }, 
+    ":flag_yt:": {
+        "style": "github", 
+        "image": "1f1fe-1f1f9.png", 
+        "unicode": "🇾🇹", 
+        "name": "Mayotte"
+    }, 
+    ":information-desk-person-tone4:": {
+        "style": "github", 
+        "image": "1f481-1f3fe.png", 
+        "unicode": "💁🏾", 
+        "name": "Information Desk Person - Tone 4"
+    }, 
+    ":middle-finger-tone4:": {
+        "style": "github", 
+        "image": "1f595-1f3fe.png", 
+        "unicode": "🖕🏾", 
+        "name": "Reversed Hand With Middle Finger Extended - Tone 4"
+    }, 
+    ":scream:": {
+        "style": "github", 
+        "image": "1f631.png", 
+        "unicode": "😱", 
+        "name": "Face Screaming In Fear"
+    }, 
+    ":rotating_light:": {
+        "style": "github", 
+        "image": "1f6a8.png", 
+        "unicode": "🚨", 
+        "name": "Police Cars Revolving Light"
+    }, 
+    ":older-man-tone5:": {
+        "style": "github", 
+        "image": "1f474-1f3ff.png", 
+        "unicode": "👴🏿", 
+        "name": "Older Man - Tone 5"
+    }, 
+    "♏": {
+        "style": "unicode", 
+        "image": "264f.png", 
+        "name": "Scorpius"
+    }, 
+    ":person_doing_cartwheel_tone5:": {
+        "style": "github", 
+        "image": "1f938-1f3ff.png", 
+        "unicode": "🤸🏿", 
+        "name": "Person Doing Cartwheel - Tone 5"
+    }, 
+    ":fork_and_knife_with_plate:": {
+        "style": "github", 
+        "image": "1f37d.png", 
+        "unicode": "🍽", 
+        "name": "Fork And Knife With Plate"
+    }, 
+    ":gift-heart:": {
+        "style": "github", 
+        "image": "1f49d.png", 
+        "unicode": "💝", 
+        "name": "Heart With Ribbon"
+    }, 
+    ":duck:": {
+        "style": "github", 
+        "image": "1f986.png", 
+        "unicode": "🦆", 
+        "name": "Duck"
+    }, 
+    ":mountain-bicyclist-tone1:": {
+        "style": "github", 
+        "image": "1f6b5-1f3fb.png", 
+        "unicode": "🚵🏻", 
+        "name": "Mountain Bicyclist - Tone 1"
+    }, 
+    ":flag-tv:": {
+        "style": "github", 
+        "image": "1f1f9-1f1fb.png", 
+        "unicode": "🇹🇻", 
+        "name": "Tuvalu"
+    }, 
+    ":regional_indicator_w:": {
+        "style": "github", 
+        "image": "1f1fc.png", 
+        "unicode": "🇼", 
+        "name": "Regional Indicator Symbol Letter W"
+    }, 
+    "🇭🇺": {
+        "style": "unicode", 
+        "image": "1f1ed-1f1fa.png", 
+        "name": "Hungary"
+    }, 
+    ":flag_kw:": {
+        "style": "github", 
+        "image": "1f1f0-1f1fc.png", 
+        "unicode": "🇰🇼", 
+        "name": "Kuwait"
+    }, 
+    ":raised-hands-tone4:": {
+        "style": "github", 
+        "image": "1f64c-1f3fe.png", 
+        "unicode": "🙌🏾", 
+        "name": "Person Raising Both Hands In Celebration - Tone 4"
+    }, 
+    ":face-palm:": {
+        "style": "github", 
+        "image": "1f926.png", 
+        "unicode": "🤦", 
+        "name": "Face Palm"
+    }, 
+    ":th:": {
+        "style": "github", 
+        "image": "1f1f9-1f1ed.png", 
+        "unicode": "🇹🇭", 
+        "name": "Thailand"
+    }, 
+    ":point-left-tone2:": {
+        "style": "github", 
+        "image": "1f448-1f3fc.png", 
+        "unicode": "👈🏼", 
+        "name": "White Left Pointing Backhand Index - Tone 2"
+    }, 
+    "💙": {
+        "style": "unicode", 
+        "image": "1f499.png", 
+        "name": "Blue Heart"
+    }, 
+    "🚵🏽": {
+        "style": "unicode", 
+        "image": "1f6b5-1f3fd.png", 
+        "name": "Mountain Bicyclist - Tone 3"
+    }, 
+    "🚵🏼": {
+        "style": "unicode", 
+        "image": "1f6b5-1f3fc.png", 
+        "name": "Mountain Bicyclist - Tone 2"
+    }, 
+    "🚵🏿": {
+        "style": "unicode", 
+        "image": "1f6b5-1f3ff.png", 
+        "name": "Mountain Bicyclist - Tone 5"
+    }, 
+    "🚵🏾": {
+        "style": "unicode", 
+        "image": "1f6b5-1f3fe.png", 
+        "name": "Mountain Bicyclist - Tone 4"
+    }, 
+    "🚵🏻": {
+        "style": "unicode", 
+        "image": "1f6b5-1f3fb.png", 
+        "name": "Mountain Bicyclist - Tone 1"
+    }, 
+    ":bullettrain_front:": {
+        "style": "github", 
+        "image": "1f685.png", 
+        "unicode": "🚅", 
+        "name": "High-speed Train With Bullet Nose"
+    }, 
+    ":girl_tone1:": {
+        "style": "github", 
+        "image": "1f467-1f3fb.png", 
+        "unicode": "👧🏻", 
+        "name": "Girl - Tone 1"
+    }, 
+    "🐮": {
+        "style": "unicode", 
+        "image": "1f42e.png", 
+        "name": "Cow Face"
+    }, 
+    ":beer:": {
+        "style": "github", 
+        "image": "1f37a.png", 
+        "unicode": "🍺", 
+        "name": "Beer Mug"
+    }, 
+    "🗃": {
+        "style": "unicode", 
+        "image": "1f5c3.png", 
+        "name": "Card File Box"
+    }, 
+    ":kissing:": {
+        "style": "github", 
+        "image": "1f617.png", 
+        "unicode": "😗", 
+        "name": "Kissing Face"
+    }, 
+    "🕘": {
+        "style": "unicode", 
+        "image": "1f558.png", 
+        "name": "Clock Face Nine Oclock"
+    }, 
+    ":li:": {
+        "style": "github", 
+        "image": "1f1f1-1f1ee.png", 
+        "unicode": "🇱🇮", 
+        "name": "Liechtenstein"
+    }, 
+    ":bg:": {
+        "style": "github", 
+        "image": "1f1e7-1f1ec.png", 
+        "unicode": "🇧🇬", 
+        "name": "Bulgaria"
+    }, 
+    ":nail-care-tone3:": {
+        "style": "github", 
+        "image": "1f485-1f3fd.png", 
+        "unicode": "💅🏽", 
+        "name": "Nail Polish - Tone 3"
+    }, 
+    "👼🏾": {
+        "style": "unicode", 
+        "image": "1f47c-1f3fe.png", 
+        "name": "Baby Angel - Tone 4"
+    }, 
+    "👼🏿": {
+        "style": "unicode", 
+        "image": "1f47c-1f3ff.png", 
+        "name": "Baby Angel - Tone 5"
+    }, 
+    "👼🏼": {
+        "style": "unicode", 
+        "image": "1f47c-1f3fc.png", 
+        "name": "Baby Angel - Tone 2"
+    }, 
+    "👼🏽": {
+        "style": "unicode", 
+        "image": "1f47c-1f3fd.png", 
+        "name": "Baby Angel - Tone 3"
+    }, 
+    ":runner-tone3:": {
+        "style": "github", 
+        "image": "1f3c3-1f3fd.png", 
+        "unicode": "🏃🏽", 
+        "name": "Runner - Tone 3"
+    }, 
+    "👼🏻": {
+        "style": "unicode", 
+        "image": "1f47c-1f3fb.png", 
+        "name": "Baby Angel - Tone 1"
+    }, 
+    ":abcd:": {
+        "style": "github", 
+        "image": "1f521.png", 
+        "unicode": "🔡", 
+        "name": "Input Symbol For Latin Small Letters"
+    }, 
+    "🤛": {
+        "style": "unicode", 
+        "image": "1f91b.png", 
+        "name": "Left-facing Fist"
+    }, 
+    ":metro:": {
+        "style": "github", 
+        "image": "1f687.png", 
+        "unicode": "🚇", 
+        "name": "Metro"
+    }, 
+    ":fist-tone4:": {
+        "style": "github", 
+        "image": "270a-1f3fe.png", 
+        "unicode": "✊🏾", 
+        "name": "Raised Fist - Tone 4"
+    }, 
+    ":flag-co:": {
+        "style": "github", 
+        "image": "1f1e8-1f1f4.png", 
+        "unicode": "🇨🇴", 
+        "name": "Colombia"
+    }, 
+    "🎬": {
+        "style": "unicode", 
+        "image": "1f3ac.png", 
+        "name": "Clapper Board"
+    }, 
+    ":cloud_rain:": {
+        "style": "github", 
+        "image": "1f327.png", 
+        "unicode": "🌧", 
+        "name": "Cloud With Rain"
+    }, 
+    "🙅": {
+        "style": "unicode", 
+        "image": "1f645.png", 
+        "name": "Face With No Good Gesture"
+    }, 
+    ":railway_track:": {
+        "style": "github", 
+        "image": "1f6e4.png", 
+        "unicode": "🛤", 
+        "name": "Railway Track"
+    }, 
+    ":hand-splayed-tone5:": {
+        "style": "github", 
+        "image": "1f590-1f3ff.png", 
+        "unicode": "🖐🏿", 
+        "name": "Raised Hand With Fingers Splayed - Tone 5"
+    }, 
+    ":flag_hr:": {
+        "style": "github", 
+        "image": "1f1ed-1f1f7.png", 
+        "unicode": "🇭🇷", 
+        "name": "Croatia"
+    }, 
+    ":pizza:": {
+        "style": "github", 
+        "image": "1f355.png", 
+        "unicode": "🍕", 
+        "name": "Slice Of Pizza"
+    }, 
+    ":flag_tn:": {
+        "style": "github", 
+        "image": "1f1f9-1f1f3.png", 
+        "unicode": "🇹🇳", 
+        "name": "Tunisia"
+    }, 
+    ":uz:": {
+        "style": "github", 
+        "image": "1f1fa-1f1ff.png", 
+        "unicode": "🇺🇿", 
+        "name": "Uzbekistan"
+    }, 
+    "🐄": {
+        "style": "unicode", 
+        "image": "1f404.png", 
+        "name": "Cow"
+    }, 
+    ":v-tone5:": {
+        "style": "github", 
+        "image": "270c-1f3ff.png", 
+        "unicode": "✌🏿", 
+        "name": "Victory Hand - Tone 5"
+    }, 
+    ":flag-bg:": {
+        "style": "github", 
+        "image": "1f1e7-1f1ec.png", 
+        "unicode": "🇧🇬", 
+        "name": "Bulgaria"
+    }, 
+    ":horse-racing-tone5:": {
+        "style": "github", 
+        "image": "1f3c7-1f3ff.png", 
+        "unicode": "🏇🏿", 
+        "name": "Horse Racing - Tone 5"
+    }, 
+    ":gt:": {
+        "style": "github", 
+        "image": "1f1ec-1f1f9.png", 
+        "unicode": "🇬🇹", 
+        "name": "Guatemala"
+    }, 
+    "☸": {
+        "style": "unicode", 
+        "image": "2638.png", 
+        "name": "Wheel Of Dharma"
+    }, 
+    ":non-potable_water:": {
+        "style": "github", 
+        "image": "1f6b1.png", 
+        "unicode": "🚱", 
+        "name": "Non-potable Water Symbol"
+    }, 
+    ":regional-indicator-r:": {
+        "style": "github", 
+        "image": "1f1f7.png", 
+        "unicode": "🇷", 
+        "name": "Regional Indicator Symbol Letter R"
+    }, 
+    ":crystal-ball:": {
+        "style": "github", 
+        "image": "1f52e.png", 
+        "unicode": "🔮", 
+        "name": "Crystal Ball"
+    }, 
+    ":juggler_tone3:": {
+        "style": "github", 
+        "image": "1f939-1f3fd.png", 
+        "unicode": "🤹🏽", 
+        "name": "Juggling - Tone 3"
+    }, 
+    ":flag-gs:": {
+        "style": "github", 
+        "image": "1f1ec-1f1f8.png", 
+        "unicode": "🇬🇸", 
+        "name": "South Georgia"
+    }, 
+    ":desert:": {
+        "style": "github", 
+        "image": "1f3dc.png", 
+        "unicode": "🏜", 
+        "name": "Desert"
+    }, 
+    ":waxing-gibbous-moon:": {
+        "style": "github", 
+        "image": "1f314.png", 
+        "unicode": "🌔", 
+        "name": "Waxing Gibbous Moon Symbol"
+    }, 
+    "🇭": {
+        "style": "unicode", 
+        "image": "1f1ed.png", 
+        "name": "Regional Indicator Symbol Letter H"
+    }, 
+    ":funeral_urn:": {
+        "style": "github", 
+        "image": "26b1.png", 
+        "unicode": "⚱", 
+        "name": "Funeral Urn"
+    }, 
+    ":flag_sc:": {
+        "style": "github", 
+        "image": "1f1f8-1f1e8.png", 
+        "unicode": "🇸🇨", 
+        "name": "The Seychelles"
+    }, 
+    ":person_frowning_tone4:": {
+        "style": "github", 
+        "image": "1f64d-1f3fe.png", 
+        "unicode": "🙍🏾", 
+        "name": "Person Frowning - Tone 4"
+    }, 
+    ":dj:": {
+        "style": "github", 
+        "image": "1f1e9-1f1ef.png", 
+        "unicode": "🇩🇯", 
+        "name": "Djibouti"
+    }, 
+    ":no-entry:": {
+        "style": "github", 
+        "image": "26d4.png", 
+        "unicode": "⛔", 
+        "name": "No Entry"
+    }, 
+    ":handshake-tone4:": {
+        "style": "github", 
+        "image": "1f91d-1f3fe.png", 
+        "unicode": "🤝🏾", 
+        "name": "Handshake - Tone 4"
+    }, 
+    ":mz:": {
+        "style": "github", 
+        "image": "1f1f2-1f1ff.png", 
+        "unicode": "🇲🇿", 
+        "name": "Mozambique"
+    }, 
+    ":swimmer_tone5:": {
+        "style": "github", 
+        "image": "1f3ca-1f3ff.png", 
+        "unicode": "🏊🏿", 
+        "name": "Swimmer - Tone 5"
+    }, 
+    "%-)": {
+        "style": "ascii", 
+        "ascii": "#-)", 
+        "image": "1f635.png", 
+        "unicode": "😵", 
+        "name": "Dizzy Face"
+    }, 
+    ":call-me-tone2:": {
+        "style": "github", 
+        "image": "1f919-1f3fc.png", 
+        "unicode": "🤙🏼", 
+        "name": "Call Me Hand - Tone 2"
+    }, 
+    "🍁": {
+        "style": "unicode", 
+        "image": "1f341.png", 
+        "name": "Maple Leaf"
+    }, 
+    ":flag-pa:": {
+        "style": "github", 
+        "image": "1f1f5-1f1e6.png", 
+        "unicode": "🇵🇦", 
+        "name": "Panama"
+    }, 
+    "🏖": {
+        "style": "unicode", 
+        "image": "1f3d6.png", 
+        "name": "Beach With Umbrella"
+    }, 
+    ":hotsprings:": {
+        "style": "github", 
+        "image": "2668.png", 
+        "unicode": "♨", 
+        "name": "Hot Springs"
+    }, 
+    ":flag_me:": {
+        "style": "github", 
+        "image": "1f1f2-1f1ea.png", 
+        "unicode": "🇲🇪", 
+        "name": "Montenegro"
+    }, 
+    "👯": {
+        "style": "unicode", 
+        "image": "1f46f.png", 
+        "name": "Woman With Bunny Ears"
+    }, 
+    "2⃣": {
+        "style": "unicode", 
+        "image": "0032-20e3.png", 
+        "name": "Keycap Digit Two"
+    }, 
+    ":sushi:": {
+        "style": "github", 
+        "image": "1f363.png", 
+        "unicode": "🍣", 
+        "name": "Sushi"
+    }, 
+    ":fist:": {
+        "style": "github", 
+        "image": "270a.png", 
+        "unicode": "✊", 
+        "name": "Raised Fist"
+    }, 
+    "🌀": {
+        "style": "unicode", 
+        "image": "1f300.png", 
+        "name": "Cyclone"
+    }, 
+    ":earth-americas:": {
+        "style": "github", 
+        "image": "1f30e.png", 
+        "unicode": "🌎", 
+        "name": "Earth Globe Americas"
+    }, 
+    "🔄": {
+        "style": "unicode", 
+        "image": "1f504.png", 
+        "name": "Anticlockwise Downwards And Upwards Open Circle Arrows"
+    }, 
+    "☎": {
+        "style": "unicode", 
+        "image": "260e.png", 
+        "name": "Black Telephone"
+    }, 
+    ":loop:": {
+        "style": "github", 
+        "image": "27bf.png", 
+        "unicode": "➿", 
+        "name": "Double Curly Loop"
+    }, 
+    ":traffic-light:": {
+        "style": "github", 
+        "image": "1f6a5.png", 
+        "unicode": "🚥", 
+        "name": "Horizontal Traffic Light"
+    }, 
+    ":pill:": {
+        "style": "github", 
+        "image": "1f48a.png", 
+        "unicode": "💊", 
+        "name": "Pill"
+    }, 
+    "😮": {
+        "style": "unicode", 
+        "ascii": ":-O", 
+        "image": "1f62e.png", 
+        "name": "Face With Open Mouth"
+    }, 
+    ":ok_woman_tone5:": {
+        "style": "github", 
+        "image": "1f646-1f3ff.png", 
+        "unicode": "🙆🏿", 
+        "name": "Face With Ok Gesture Tone5"
+    }, 
+    ":closed_book:": {
+        "style": "github", 
+        "image": "1f4d5.png", 
+        "unicode": "📕", 
+        "name": "Closed Book"
+    }, 
+    ":radio_button:": {
+        "style": "github", 
+        "image": "1f518.png", 
+        "unicode": "🔘", 
+        "name": "Radio Button"
+    }, 
+    ":vulcan-tone2:": {
+        "style": "github", 
+        "image": "1f596-1f3fc.png", 
+        "unicode": "🖖🏼", 
+        "name": "Raised Hand With Part Between Middle And Ring Fingers - Tone 2"
+    }, 
+    ":repeat_one:": {
+        "style": "github", 
+        "image": "1f502.png", 
+        "unicode": "🔂", 
+        "name": "Clockwise Rightwards And Leftwards Open Circle Arrows With Circled One Overlay"
+    }, 
+    "🍀": {
+        "style": "unicode", 
+        "image": "1f340.png", 
+        "name": "Four Leaf Clover"
+    }, 
+    ":blush:": {
+        "style": "github", 
+        "image": "1f60a.png", 
+        "unicode": "😊", 
+        "name": "Smiling Face With Smiling Eyes"
+    }, 
+    ":sc:": {
+        "style": "github", 
+        "image": "1f1f8-1f1e8.png", 
+        "unicode": "🇸🇨", 
+        "name": "The Seychelles"
+    }, 
+    ":tophat:": {
+        "style": "github", 
+        "image": "1f3a9.png", 
+        "unicode": "🎩", 
+        "name": "Top Hat"
+    }, 
+    "👅": {
+        "style": "unicode", 
+        "image": "1f445.png", 
+        "name": "Tongue"
+    }, 
+    ":handshake-tone1:": {
+        "style": "github", 
+        "image": "1f91d-1f3fb.png", 
+        "unicode": "🤝🏻", 
+        "name": "Handshake - Tone 1"
+    }, 
+    ":confetti_ball:": {
+        "style": "github", 
+        "image": "1f38a.png", 
+        "unicode": "🎊", 
+        "name": "Confetti Ball"
+    }, 
+    ":flag-mz:": {
+        "style": "github", 
+        "image": "1f1f2-1f1ff.png", 
+        "unicode": "🇲🇿", 
+        "name": "Mozambique"
+    }, 
+    ":fingers_crossed_tone1:": {
+        "style": "github", 
+        "image": "1f91e-1f3fb.png", 
+        "unicode": "🤞🏻", 
+        "name": "Hand With Index And Middle Fingers Crossed - Tone 1"
+    }, 
+    "📚": {
+        "style": "unicode", 
+        "image": "1f4da.png", 
+        "name": "Books"
+    }, 
+    ":older_man_tone2:": {
+        "style": "github", 
+        "image": "1f474-1f3fc.png", 
+        "unicode": "👴🏼", 
+        "name": "Older Man - Tone 2"
+    }, 
+    ":telephone-receiver:": {
+        "style": "github", 
+        "image": "1f4de.png", 
+        "unicode": "📞", 
+        "name": "Telephone Receiver"
+    }, 
+    "🍫": {
+        "style": "unicode", 
+        "image": "1f36b.png", 
+        "name": "Chocolate Bar"
+    }, 
+    "🕯": {
+        "style": "unicode", 
+        "image": "1f56f.png", 
+        "name": "Candle"
+    }, 
+    ":mouse:": {
+        "style": "github", 
+        "image": "1f42d.png", 
+        "unicode": "🐭", 
+        "name": "Mouse Face"
+    }, 
+    ":flag-tm:": {
+        "style": "github", 
+        "image": "1f1f9-1f1f2.png", 
+        "unicode": "🇹🇲", 
+        "name": "Turkmenistan"
+    }, 
+    "🐀": {
+        "style": "unicode", 
+        "image": "1f400.png", 
+        "name": "Rat"
+    }, 
+    ":raising-hand-tone4:": {
+        "style": "github", 
+        "image": "1f64b-1f3fe.png", 
+        "unicode": "🙋🏾", 
+        "name": "Happy Person Raising One Hand Tone4"
+    }, 
+    "🆙": {
+        "style": "unicode", 
+        "image": "1f199.png", 
+        "name": "Squared Up With Exclamation Mark"
+    }, 
+    ":crocodile:": {
+        "style": "github", 
+        "image": "1f40a.png", 
+        "unicode": "🐊", 
+        "name": "Crocodile"
+    }, 
+    ":heavy_dollar_sign:": {
+        "style": "github", 
+        "image": "1f4b2.png", 
+        "unicode": "💲", 
+        "name": "Heavy Dollar Sign"
+    }, 
+    ":champagne-glass:": {
+        "style": "github", 
+        "image": "1f942.png", 
+        "unicode": "🥂", 
+        "name": "Clinking Glasses"
+    }, 
+    ":wind-chime:": {
+        "style": "github", 
+        "image": "1f390.png", 
+        "unicode": "🎐", 
+        "name": "Wind Chime"
+    }, 
+    ":bicyclist:": {
+        "style": "github", 
+        "image": "1f6b4.png", 
+        "unicode": "🚴", 
+        "name": "Bicyclist"
+    }, 
+    ":left_facing_fist_tone1:": {
+        "style": "github", 
+        "image": "1f91b-1f3fb.png", 
+        "unicode": "🤛🏻", 
+        "name": "Left Facing Fist - Tone 1"
+    }, 
+    ":pancakes:": {
+        "style": "github", 
+        "image": "1f95e.png", 
+        "unicode": "🥞", 
+        "name": "Pancakes"
+    }, 
+    ":lock:": {
+        "style": "github", 
+        "image": "1f512.png", 
+        "unicode": "🔒", 
+        "name": "Lock"
+    }, 
+    ":mortar-board:": {
+        "style": "github", 
+        "image": "1f393.png", 
+        "unicode": "🎓", 
+        "name": "Graduation Cap"
+    }, 
+    ":flag-se:": {
+        "style": "github", 
+        "image": "1f1f8-1f1ea.png", 
+        "unicode": "🇸🇪", 
+        "name": "Sweden"
+    }, 
+    "⛷": {
+        "style": "unicode", 
+        "image": "26f7.png", 
+        "name": "Skier"
+    }, 
+    ":skull_and_crossbones:": {
+        "style": "github", 
+        "image": "2620.png", 
+        "unicode": "☠", 
+        "name": "Skull And Crossbones"
+    }, 
+    ":face_palm_tone4:": {
+        "style": "github", 
+        "image": "1f926-1f3fe.png", 
+        "unicode": "🤦🏾", 
+        "name": "Face Palm - Tone 4"
+    }, 
+    ":rhinoceros:": {
+        "style": "github", 
+        "image": "1f98f.png", 
+        "unicode": "🦏", 
+        "name": "Rhinoceros"
+    }, 
+    "🚬": {
+        "style": "unicode", 
+        "image": "1f6ac.png", 
+        "name": "Smoking Symbol"
+    }, 
+    "🎅🏽": {
+        "style": "unicode", 
+        "image": "1f385-1f3fd.png", 
+        "name": "Father Christmas - Tone 3"
+    }, 
+    "🎅🏼": {
+        "style": "unicode", 
+        "image": "1f385-1f3fc.png", 
+        "name": "Father Christmas - Tone 2"
+    }, 
+    "🎅🏿": {
+        "style": "unicode", 
+        "image": "1f385-1f3ff.png", 
+        "name": "Father Christmas - Tone 5"
+    }, 
+    "🎅🏾": {
+        "style": "unicode", 
+        "image": "1f385-1f3fe.png", 
+        "name": "Father Christmas - Tone 4"
+    }, 
+    ":flag_gi:": {
+        "style": "github", 
+        "image": "1f1ec-1f1ee.png", 
+        "unicode": "🇬🇮", 
+        "name": "Gibraltar"
+    }, 
+    "▶": {
+        "style": "unicode", 
+        "image": "25b6.png", 
+        "name": "Black Right-pointing Triangle"
+    }, 
+    ":musical_note:": {
+        "style": "github", 
+        "image": "1f3b5.png", 
+        "unicode": "🎵", 
+        "name": "Musical Note"
+    }, 
+    "🍅": {
+        "style": "unicode", 
+        "image": "1f345.png", 
+        "name": "Tomato"
+    }, 
+    "🥉": {
+        "style": "unicode", 
+        "image": "1f949.png", 
+        "name": "Third Place Medal"
+    }, 
+    "🏚": {
+        "style": "unicode", 
+        "image": "1f3da.png", 
+        "name": "Derelict House Building"
+    }, 
+    "👫": {
+        "style": "unicode", 
+        "image": "1f46b.png", 
+        "name": "Man And Woman Holding Hands"
+    }, 
+    "🇫🇯": {
+        "style": "unicode", 
+        "image": "1f1eb-1f1ef.png", 
+        "name": "Fiji"
+    }, 
+    "🇫🇮": {
+        "style": "unicode", 
+        "image": "1f1eb-1f1ee.png", 
+        "name": "Finland"
+    }, 
+    "🇫🇲": {
+        "style": "unicode", 
+        "image": "1f1eb-1f1f2.png", 
+        "name": "Micronesia"
+    }, 
+    "🇫🇰": {
+        "style": "unicode", 
+        "image": "1f1eb-1f1f0.png", 
+        "name": "Falkland Islands"
+    }, 
+    "🇫🇷": {
+        "style": "unicode", 
+        "image": "1f1eb-1f1f7.png", 
+        "name": "France"
+    }, 
+    ":flag_hm:": {
+        "style": "github", 
+        "image": "1f1ed-1f1f2.png", 
+        "unicode": "🇭🇲", 
+        "name": "Heard Island And Mcdonald Islands"
+    }, 
+    "🇫🇴": {
+        "style": "unicode", 
+        "image": "1f1eb-1f1f4.png", 
+        "name": "Faroe Islands"
+    }, 
+    ":arrow_right:": {
+        "style": "github", 
+        "image": "27a1.png", 
+        "unicode": "➡", 
+        "name": "Black Rightwards Arrow"
+    }, 
+    ":flag-af:": {
+        "style": "github", 
+        "image": "1f1e6-1f1eb.png", 
+        "unicode": "🇦🇫", 
+        "name": "Afghanistan"
+    }, 
+    ":shrug-tone2:": {
+        "style": "github", 
+        "image": "1f937-1f3fc.png", 
+        "unicode": "🤷🏼", 
+        "name": "Shrug - Tone 2"
+    }, 
+    "🌄": {
+        "style": "unicode", 
+        "image": "1f304.png", 
+        "name": "Sunrise Over Mountains"
+    }, 
+    ":fallen-leaf:": {
+        "style": "github", 
+        "image": "1f342.png", 
+        "unicode": "🍂", 
+        "name": "Fallen Leaf"
+    }, 
+    ":cross:": {
+        "style": "github", 
+        "image": "271d.png", 
+        "unicode": "✝", 
+        "name": "Latin Cross"
+    }, 
+    ":bride_with_veil:": {
+        "style": "github", 
+        "image": "1f470.png", 
+        "unicode": "👰", 
+        "name": "Bride With Veil"
+    }, 
+    ":sun-with-face:": {
+        "style": "github", 
+        "image": "1f31e.png", 
+        "unicode": "🌞", 
+        "name": "Sun With Face"
+    }, 
+    ":raised-back-of-hand-tone1:": {
+        "style": "github", 
+        "image": "1f91a-1f3fb.png", 
+        "unicode": "🤚🏻", 
+        "name": "Raised Back Of Hand - Tone 1"
+    }, 
+    ":telephone_receiver:": {
+        "style": "github", 
+        "image": "1f4de.png", 
+        "unicode": "📞", 
+        "name": "Telephone Receiver"
+    }, 
+    ":regional_indicator_u:": {
+        "style": "github", 
+        "image": "1f1fa.png", 
+        "unicode": "🇺", 
+        "name": "Regional Indicator Symbol Letter U"
+    }, 
+    ":family-mwgg:": {
+        "style": "github", 
+        "image": "1f468-1f469-1f467-1f467.png", 
+        "unicode": "👨👩👧👧", 
+        "name": "Family (man,woman,girl,girl)"
+    }, 
+    ":sneeze:": {
+        "style": "github", 
+        "image": "1f927.png", 
+        "unicode": "🤧", 
+        "name": "Sneezing Face"
+    }, 
+    ":cx:": {
+        "style": "github", 
+        "image": "1f1e8-1f1fd.png", 
+        "unicode": "🇨🇽", 
+        "name": "Christmas Island"
+    }, 
+    ":lock_with_ink_pen:": {
+        "style": "github", 
+        "image": "1f50f.png", 
+        "unicode": "🔏", 
+        "name": "Lock With Ink Pen"
+    }, 
+    ":mountain-bicyclist-tone3:": {
+        "style": "github", 
+        "image": "1f6b5-1f3fd.png", 
+        "unicode": "🚵🏽", 
+        "name": "Mountain Bicyclist - Tone 3"
+    }, 
+    ":ea:": {
+        "style": "github", 
+        "image": "1f1ea-1f1e6.png", 
+        "unicode": "🇪🇦", 
+        "name": "Ceuta, Melilla"
+    }, 
+    ":cow2:": {
+        "style": "github", 
+        "image": "1f404.png", 
+        "unicode": "🐄", 
+        "name": "Cow"
+    }, 
+    "🚂": {
+        "style": "unicode", 
+        "image": "1f682.png", 
+        "name": "Steam Locomotive"
+    }, 
+    ":tf:": {
+        "style": "github", 
+        "image": "1f1f9-1f1eb.png", 
+        "unicode": "🇹🇫", 
+        "name": "French Southern Territories"
+    }, 
+    "🤹🏻": {
+        "style": "unicode", 
+        "image": "1f939-1f3fb.png", 
+        "name": "Juggling - Tone 1"
+    }, 
+    "🤹🏽": {
+        "style": "unicode", 
+        "image": "1f939-1f3fd.png", 
+        "name": "Juggling - Tone 3"
+    }, 
+    "🤹🏼": {
+        "style": "unicode", 
+        "image": "1f939-1f3fc.png", 
+        "name": "Juggling - Tone 2"
+    }, 
+    "🤹🏿": {
+        "style": "unicode", 
+        "image": "1f939-1f3ff.png", 
+        "name": "Juggling - Tone 5"
+    }, 
+    "🤹🏾": {
+        "style": "unicode", 
+        "image": "1f939-1f3fe.png", 
+        "name": "Juggling - Tone 4"
+    }, 
+    "O;-)": {
+        "style": "ascii", 
+        "ascii": "O:-)", 
+        "image": "1f607.png", 
+        "unicode": "😇", 
+        "name": "Smiling Face With Halo"
+    }, 
+    ":girl_tone3:": {
+        "style": "github", 
+        "image": "1f467-1f3fd.png", 
+        "unicode": "👧🏽", 
+        "name": "Girl - Tone 3"
+    }, 
+    ":man_in_tuxedo_tone4:": {
+        "style": "github", 
+        "image": "1f935-1f3fe.png", 
+        "unicode": "🤵🏾", 
+        "name": "Man In Tuxedo - Tone 4"
+    }, 
+    ":nail_care_tone5:": {
+        "style": "github", 
+        "image": "1f485-1f3ff.png", 
+        "unicode": "💅🏿", 
+        "name": "Nail Polish - Tone 5"
+    }, 
+    "👁": {
+        "style": "unicode", 
+        "image": "1f441.png", 
+        "name": "Eye"
+    }, 
+    ":angel_tone5:": {
+        "style": "github", 
+        "image": "1f47c-1f3ff.png", 
+        "unicode": "👼🏿", 
+        "name": "Baby Angel - Tone 5"
+    }, 
+    ":mailbox-with-mail:": {
+        "style": "github", 
+        "image": "1f4ec.png", 
+        "unicode": "📬", 
+        "name": "Open Mailbox With Raised Flag"
+    }, 
+    ":flag_mk:": {
+        "style": "github", 
+        "image": "1f1f2-1f1f0.png", 
+        "unicode": "🇲🇰", 
+        "name": "Macedonia"
+    }, 
+    "📖": {
+        "style": "unicode", 
+        "image": "1f4d6.png", 
+        "name": "Open Book"
+    }, 
+    "🌳": {
+        "style": "unicode", 
+        "image": "1f333.png", 
+        "name": "Deciduous Tree"
+    }, 
+    ":flag-ki:": {
+        "style": "github", 
+        "image": "1f1f0-1f1ee.png", 
+        "unicode": "🇰🇮", 
+        "name": "Kiribati"
+    }, 
+    ";^)": {
+        "style": "ascii", 
+        "ascii": ";)", 
+        "image": "1f609.png", 
+        "unicode": "😉", 
+        "name": "Winking Face"
+    }, 
+    ":microphone:": {
+        "style": "github", 
+        "image": "1f3a4.png", 
+        "unicode": "🎤", 
+        "name": "Microphone"
+    }, 
+    "🍯": {
+        "style": "unicode", 
+        "image": "1f36f.png", 
+        "name": "Honey Pot"
+    }, 
+    ":ba:": {
+        "style": "github", 
+        "image": "1f1e7-1f1e6.png", 
+        "unicode": "🇧🇦", 
+        "name": "Bosnia And Herzegovina"
+    }, 
+    ":massage-tone1:": {
+        "style": "github", 
+        "image": "1f486-1f3fb.png", 
+        "unicode": "💆🏻", 
+        "name": "Face Massage - Tone 1"
+    }, 
+    ":birthday:": {
+        "style": "github", 
+        "image": "1f382.png", 
+        "unicode": "🎂", 
+        "name": "Birthday Cake"
+    }, 
+    ":flag_cd:": {
+        "style": "github", 
+        "image": "1f1e8-1f1e9.png", 
+        "unicode": "🇨🇩", 
+        "name": "The Democratic Republic Of The Congo"
+    }, 
+    ":nail-care-tone1:": {
+        "style": "github", 
+        "image": "1f485-1f3fb.png", 
+        "unicode": "💅🏻", 
+        "name": "Nail Polish - Tone 1"
+    }, 
+    "😀": {
+        "style": "unicode", 
+        "image": "1f600.png", 
+        "name": "Grinning Face"
+    }, 
+    "🀄": {
+        "style": "unicode", 
+        "image": "1f004.png", 
+        "name": "Mahjong Tile Red Dragon"
+    }, 
+    ":runner-tone1:": {
+        "style": "github", 
+        "image": "1f3c3-1f3fb.png", 
+        "unicode": "🏃🏻", 
+        "name": "Runner - Tone 1"
+    }, 
+    ":santa_tone5:": {
+        "style": "github", 
+        "image": "1f385-1f3ff.png", 
+        "unicode": "🎅🏿", 
+        "name": "Father Christmas - Tone 5"
+    }, 
+    "🎙": {
+        "style": "unicode", 
+        "image": "1f399.png", 
+        "name": "Studio Microphone"
+    }, 
+    ":french-bread:": {
+        "style": "github", 
+        "image": "1f956.png", 
+        "unicode": "🥖", 
+        "name": "Baguette Bread"
+    }, 
+    ":fist-tone2:": {
+        "style": "github", 
+        "image": "270a-1f3fc.png", 
+        "unicode": "✊🏼", 
+        "name": "Raised Fist - Tone 2"
+    }, 
+    ":fencing:": {
+        "style": "github", 
+        "image": "1f93a.png", 
+        "unicode": "🤺", 
+        "name": "Fencer"
+    }, 
+    ":oden:": {
+        "style": "github", 
+        "image": "1f362.png", 
+        "unicode": "🍢", 
+        "name": "Oden"
+    }, 
+    ":flag-is:": {
+        "style": "github", 
+        "image": "1f1ee-1f1f8.png", 
+        "unicode": "🇮🇸", 
+        "name": "Iceland"
+    }, 
+    ":flag-ci:": {
+        "style": "github", 
+        "image": "1f1e8-1f1ee.png", 
+        "unicode": "🇨🇮", 
+        "name": "Côte D’ivoire"
+    }, 
+    ":tractor:": {
+        "style": "github", 
+        "image": "1f69c.png", 
+        "unicode": "🚜", 
+        "name": "Tractor"
+    }, 
+    "🌮": {
+        "style": "unicode", 
+        "image": "1f32e.png", 
+        "name": "Taco"
+    }, 
+    ":page_facing_up:": {
+        "style": "github", 
+        "image": "1f4c4.png", 
+        "unicode": "📄", 
+        "name": "Page Facing Up"
+    }, 
+    ":thumbsdown-tone2:": {
+        "style": "github", 
+        "image": "1f44e-1f3fc.png", 
+        "unicode": "👎🏼", 
+        "name": "Thumbs Down Sign - Tone 2"
+    }, 
+    ":point_right_tone4:": {
+        "style": "github", 
+        "image": "1f449-1f3fe.png", 
+        "unicode": "👉🏾", 
+        "name": "White Right Pointing Backhand Index - Tone 4"
+    }, 
+    ":earth-asia:": {
+        "style": "github", 
+        "image": "1f30f.png", 
+        "unicode": "🌏", 
+        "name": "Earth Globe Asia-australia"
+    }, 
+    ":musical_keyboard:": {
+        "style": "github", 
+        "image": "1f3b9.png", 
+        "unicode": "🎹", 
+        "name": "Musical Keyboard"
+    }, 
+    ":mother_christmas:": {
+        "style": "github", 
+        "image": "1f936.png", 
+        "unicode": "🤶", 
+        "name": "Mother Christmas"
+    }, 
+    ":person_with_pouting_face:": {
+        "style": "github", 
+        "image": "1f64e.png", 
+        "unicode": "🙎", 
+        "name": "Person With Pouting Face"
+    }, 
+    ":flag_tl:": {
+        "style": "github", 
+        "image": "1f1f9-1f1f1.png", 
+        "unicode": "🇹🇱", 
+        "name": "Timor-leste"
+    }, 
+    ":shinto_shrine:": {
+        "style": "github", 
+        "image": "26e9.png", 
+        "unicode": "⛩", 
+        "name": "Shinto Shrine"
+    }, 
+    ":tropical_fish:": {
+        "style": "github", 
+        "image": "1f420.png", 
+        "unicode": "🐠", 
+        "name": "Tropical Fish"
+    }, 
+    ":camping:": {
+        "style": "github", 
+        "image": "1f3d5.png", 
+        "unicode": "🏕", 
+        "name": "Camping"
+    }, 
+    "🇺🇬": {
+        "style": "unicode", 
+        "image": "1f1fa-1f1ec.png", 
+        "name": "Uganda"
+    }, 
+    ":no-good:": {
+        "style": "github", 
+        "image": "1f645.png", 
+        "unicode": "🙅", 
+        "name": "Face With No Good Gesture"
+    }, 
+    "🇺🇦": {
+        "style": "unicode", 
+        "image": "1f1fa-1f1e6.png", 
+        "name": "Ukraine"
+    }, 
+    "🦊": {
+        "style": "unicode", 
+        "image": "1f98a.png", 
+        "name": "Fox Face"
+    }, 
+    ":fi:": {
+        "style": "github", 
+        "image": "1f1eb-1f1ee.png", 
+        "unicode": "🇫🇮", 
+        "name": "Finland"
+    }, 
+    "🇺🇾": {
+        "style": "unicode", 
+        "image": "1f1fa-1f1fe.png", 
+        "name": "Uruguay"
+    }, 
+    "🇺🇿": {
+        "style": "unicode", 
+        "image": "1f1fa-1f1ff.png", 
+        "name": "Uzbekistan"
+    }, 
+    "🇺🇸": {
+        "style": "unicode", 
+        "image": "1f1fa-1f1f8.png", 
+        "name": "United States"
+    }, 
+    "🐗": {
+        "style": "unicode", 
+        "image": "1f417.png", 
+        "name": "Boar"
+    }, 
+    ":flag-be:": {
+        "style": "github", 
+        "image": "1f1e7-1f1ea.png", 
+        "unicode": "🇧🇪", 
+        "name": "Belgium"
+    }, 
+    "🇺🇲": {
+        "style": "unicode", 
+        "image": "1f1fa-1f1f2.png", 
+        "name": "United States Minor Outlying Islands"
+    }, 
+    ":walking-tone4:": {
+        "style": "github", 
+        "image": "1f6b6-1f3fe.png", 
+        "unicode": "🚶🏾", 
+        "name": "Pedestrian - Tone 4"
+    }, 
+    "✡": {
+        "style": "unicode", 
+        "image": "2721.png", 
+        "name": "Star Of David"
+    }, 
+    "💬": {
+        "style": "unicode", 
+        "image": "1f4ac.png", 
+        "name": "Speech Balloon"
+    }, 
+    ":open-mouth:": {
+        "style": "github", 
+        "ascii": ":-O", 
+        "image": "1f62e.png", 
+        "unicode": "😮", 
+        "name": "Face With Open Mouth"
+    }, 
+    ":person-frowning:": {
+        "style": "github", 
+        "image": "1f64d.png", 
+        "unicode": "🙍", 
+        "name": "Person Frowning"
+    }, 
+    "♋": {
+        "style": "unicode", 
+        "image": "264b.png", 
+        "name": "Cancer"
+    }, 
+    ":smiley:": {
+        "style": "github", 
+        "ascii": ":D", 
+        "image": "1f603.png", 
+        "unicode": "😃", 
+        "name": "Smiling Face With Open Mouth"
+    }, 
+    ":back_of_hand_tone3:": {
+        "style": "github", 
+        "image": "1f91a-1f3fd.png", 
+        "unicode": "🤚🏽", 
+        "name": "Raised Back Of Hand - Tone 3"
+    }, 
+    ":sheep:": {
+        "style": "github", 
+        "image": "1f411.png", 
+        "unicode": "🐑", 
+        "name": "Sheep"
+    }, 
+    ":flag-gu:": {
+        "style": "github", 
+        "image": "1f1ec-1f1fa.png", 
+        "unicode": "🇬🇺", 
+        "name": "Guam"
+    }, 
+    ":regional_indicator_y:": {
+        "style": "github", 
+        "image": "1f1fe.png", 
+        "unicode": "🇾", 
+        "name": "Regional Indicator Symbol Letter Y"
+    }, 
+    ":flag_sa:": {
+        "style": "github", 
+        "image": "1f1f8-1f1e6.png", 
+        "unicode": "🇸🇦", 
+        "name": "Saudi Arabia"
+    }, 
+    ":arrow-lower-right:": {
+        "style": "github", 
+        "image": "2198.png", 
+        "unicode": "↘", 
+        "name": "South East Arrow"
+    }, 
+    ":dash:": {
+        "style": "github", 
+        "image": "1f4a8.png", 
+        "unicode": "💨", 
+        "name": "Dash Symbol"
+    }, 
+    ":weight_lifter_tone4:": {
+        "style": "github", 
+        "image": "1f3cb-1f3fe.png", 
+        "unicode": "🏋🏾", 
+        "name": "Weight Lifter - Tone 4"
+    }, 
+    ":flag_eh:": {
+        "style": "github", 
+        "image": "1f1ea-1f1ed.png", 
+        "unicode": "🇪🇭", 
+        "name": "Western Sahara"
+    }, 
+    ":swimmer_tone3:": {
+        "style": "github", 
+        "image": "1f3ca-1f3fd.png", 
+        "unicode": "🏊🏽", 
+        "name": "Swimmer - Tone 3"
+    }, 
+    ":aerial_tramway:": {
+        "style": "github", 
+        "image": "1f6a1.png", 
+        "unicode": "🚡", 
+        "name": "Aerial Tramway"
+    }, 
+    ":bug:": {
+        "style": "github", 
+        "image": "1f41b.png", 
+        "unicode": "🐛", 
+        "name": "Bug"
+    }, 
+    ":cn:": {
+        "style": "github", 
+        "image": "1f1e8-1f1f3.png", 
+        "unicode": "🇨🇳", 
+        "name": "China"
+    }, 
+    ":thumbsup-tone1:": {
+        "style": "github", 
+        "image": "1f44d-1f3fb.png", 
+        "unicode": "👍🏻", 
+        "name": "Thumbs Up Sign - Tone 1"
+    }, 
+    ":handshake-tone2:": {
+        "style": "github", 
+        "image": "1f91d-1f3fc.png", 
+        "unicode": "🤝🏼", 
+        "name": "Handshake - Tone 2"
+    }, 
+    "🏃": {
+        "style": "unicode", 
+        "image": "1f3c3.png", 
+        "name": "Runner"
+    }, 
+    ":bath:": {
+        "style": "github", 
+        "image": "1f6c0.png", 
+        "unicode": "🛀", 
+        "name": "Bath"
+    }, 
+    ":heavy_division_sign:": {
+        "style": "github", 
+        "image": "2797.png", 
+        "unicode": "➗", 
+        "name": "Heavy Division Sign"
+    }, 
+    "👍🏽": {
+        "style": "unicode", 
+        "image": "1f44d-1f3fd.png", 
+        "name": "Thumbs Up Sign - Tone 3"
+    }, 
+    "🍘": {
+        "style": "unicode", 
+        "image": "1f358.png", 
+        "name": "Rice Cracker"
+    }, 
+    "👍🏿": {
+        "style": "unicode", 
+        "image": "1f44d-1f3ff.png", 
+        "name": "Thumbs Up Sign - Tone 5"
+    }, 
+    "👍🏾": {
+        "style": "unicode", 
+        "image": "1f44d-1f3fe.png", 
+        "name": "Thumbs Up Sign - Tone 4"
+    }, 
+    ":kn:": {
+        "style": "github", 
+        "image": "1f1f0-1f1f3.png", 
+        "unicode": "🇰🇳", 
+        "name": "Saint Kitts And Nevis"
+    }, 
+    "👍🏻": {
+        "style": "unicode", 
+        "image": "1f44d-1f3fb.png", 
+        "name": "Thumbs Up Sign - Tone 1"
+    }, 
+    ":saudi:": {
+        "style": "github", 
+        "image": "1f1f8-1f1e6.png", 
+        "unicode": "🇸🇦", 
+        "name": "Saudi Arabia"
+    }, 
+    ":email:": {
+        "style": "github", 
+        "image": "1f4e7.png", 
+        "unicode": "📧", 
+        "name": "E-mail Symbol"
+    }, 
+    "📭": {
+        "style": "unicode", 
+        "image": "1f4ed.png", 
+        "name": "Open Mailbox With Lowered Flag"
+    }, 
+    ":umbrella_on_ground:": {
+        "style": "github", 
+        "image": "26f1.png", 
+        "unicode": "⛱", 
+        "name": "Umbrella On Ground"
+    }, 
+    ":spider:": {
+        "style": "github", 
+        "image": "1f577.png", 
+        "unicode": "🕷", 
+        "name": "Spider"
+    }, 
+    ":gp:": {
+        "style": "github", 
+        "image": "1f1ec-1f1f5.png", 
+        "unicode": "🇬🇵", 
+        "name": "Guadeloupe"
+    }, 
+    "💂": {
+        "style": "unicode", 
+        "image": "1f482.png", 
+        "name": "Guardsman"
+    }, 
+    ":guardsman_tone1:": {
+        "style": "github", 
+        "image": "1f482-1f3fb.png", 
+        "unicode": "💂🏻", 
+        "name": "Guardsman - Tone 1"
+    }, 
+    ":arrow-down-small:": {
+        "style": "github", 
+        "image": "1f53d.png", 
+        "unicode": "🔽", 
+        "name": "Down-pointing Small Red Triangle"
+    }, 
+    "🔗": {
+        "style": "unicode", 
+        "image": "1f517.png", 
+        "name": "Link Symbol"
+    }, 
+    ":city_sunset:": {
+        "style": "github", 
+        "image": "1f307.png", 
+        "unicode": "🌇", 
+        "name": "Sunset Over Buildings"
+    }, 
+    "😛": {
+        "style": "unicode", 
+        "ascii": ":P", 
+        "image": "1f61b.png", 
+        "name": "Face With Stuck-out Tongue"
+    }, 
+    ":v_tone1:": {
+        "style": "github", 
+        "image": "270c-1f3fb.png", 
+        "unicode": "✌🏻", 
+        "name": "Victory Hand - Tone 1"
+    }, 
+    ":postal-horn:": {
+        "style": "github", 
+        "image": "1f4ef.png", 
+        "unicode": "📯", 
+        "name": "Postal Horn"
+    }, 
+    ":pray-tone2:": {
+        "style": "github", 
+        "image": "1f64f-1f3fc.png", 
+        "unicode": "🙏🏼", 
+        "name": "Person With Folded Hands - Tone 2"
+    }, 
+    ":re:": {
+        "style": "github", 
+        "image": "1f1f7-1f1ea.png", 
+        "unicode": "🇷🇪", 
+        "name": "Réunion"
+    }, 
+    ":rice:": {
+        "style": "github", 
+        "image": "1f35a.png", 
+        "unicode": "🍚", 
+        "name": "Cooked Rice"
+    }, 
+    ":point-down-tone5:": {
+        "style": "github", 
+        "image": "1f447-1f3ff.png", 
+        "unicode": "👇🏿", 
+        "name": "White Down Pointing Backhand Index - Tone 5"
+    }, 
+    "🙁": {
+        "style": "unicode", 
+        "image": "1f641.png", 
+        "name": "Slightly Frowning Face"
+    }, 
+    ":ok_woman_tone3:": {
+        "style": "github", 
+        "image": "1f646-1f3fd.png", 
+        "unicode": "🙆🏽", 
+        "name": "Face With Ok Gesture Tone3"
+    }, 
+    ":crayon:": {
+        "style": "github", 
+        "image": "1f58d.png", 
+        "unicode": "🖍", 
+        "name": "Lower Left Crayon"
+    }, 
+    ":ht:": {
+        "style": "github", 
+        "image": "1f1ed-1f1f9.png", 
+        "unicode": "🇭🇹", 
+        "name": "Haiti"
+    }, 
+    ":floppy_disk:": {
+        "style": "github", 
+        "image": "1f4be.png", 
+        "unicode": "💾", 
+        "name": "Floppy Disk"
+    }, 
+    ":flag_va:": {
+        "style": "github", 
+        "image": "1f1fb-1f1e6.png", 
+        "unicode": "🇻🇦", 
+        "name": "The Vatican City"
+    }, 
+    "🐈": {
+        "style": "unicode", 
+        "image": "1f408.png", 
+        "name": "Cat"
+    }, 
+    ":corn:": {
+        "style": "github", 
+        "image": "1f33d.png", 
+        "unicode": "🌽", 
+        "name": "Ear Of Maize"
+    }, 
+    ":wave_tone1:": {
+        "style": "github", 
+        "image": "1f44b-1f3fb.png", 
+        "unicode": "👋🏻", 
+        "name": "Waving Hand Sign - Tone 1"
+    }, 
+    ":handball-tone2:": {
+        "style": "github", 
+        "image": "1f93e-1f3fc.png", 
+        "unicode": "🤾🏼", 
+        "name": "Handball - Tone 2"
+    }, 
+    ":shaved_ice:": {
+        "style": "github", 
+        "image": "1f367.png", 
+        "unicode": "🍧", 
+        "name": "Shaved Ice"
+    }, 
+    ":sa:": {
+        "style": "github", 
+        "image": "1f202.png", 
+        "unicode": "🈂", 
+        "name": "Squared Katakana Sa"
+    }, 
+    ":raised_hand_with_part_between_middle_and_ring_fingers:": {
+        "style": "github", 
+        "image": "1f596.png", 
+        "unicode": "🖖", 
+        "name": "Raised Hand With Part Between Middle And Ring Fingers"
+    }, 
+    ":tone4:": {
+        "style": "github", 
+        "image": "1f3fe.png", 
+        "unicode": "🏾", 
+        "name": "Emoji Modifier Fitzpatrick Type-5"
+    }, 
+    "〰": {
+        "style": "unicode", 
+        "image": "3030.png", 
+        "name": "Wavy Dash"
+    }, 
+    "🌲": {
+        "style": "unicode", 
+        "image": "1f332.png", 
+        "name": "Evergreen Tree"
+    }, 
+    "3⃣": {
+        "style": "unicode", 
+        "image": "0033-20e3.png", 
+        "name": "Keycap Digit Three"
+    }, 
+    ":flag_ac:": {
+        "style": "github", 
+        "image": "1f1e6-1f1e8.png", 
+        "unicode": "🇦🇨", 
+        "name": "Ascension"
+    }, 
+    ":potato:": {
+        "style": "github", 
+        "image": "1f954.png", 
+        "unicode": "🥔", 
+        "name": "Potato"
+    }, 
+    ":arrow_upper_right:": {
+        "style": "github", 
+        "image": "2197.png", 
+        "unicode": "↗", 
+        "name": "North East Arrow"
+    }, 
+    ":mask:": {
+        "style": "github", 
+        "image": "1f637.png", 
+        "unicode": "😷", 
+        "name": "Face With Medical Mask"
+    }, 
+    ":flag_do:": {
+        "style": "github", 
+        "image": "1f1e9-1f1f4.png", 
+        "unicode": "🇩🇴", 
+        "name": "The Dominican Republic"
+    }, 
+    ":spy-tone1:": {
+        "style": "github", 
+        "image": "1f575-1f3fb.png", 
+        "unicode": "🕵🏻", 
+        "name": "Sleuth Or Spy - Tone 1"
+    }, 
+    ":facepalm_tone2:": {
+        "style": "github", 
+        "image": "1f926-1f3fc.png", 
+        "unicode": "🤦🏼", 
+        "name": "Face Palm - Tone 2"
+    }, 
+    ":older_man_tone4:": {
+        "style": "github", 
+        "image": "1f474-1f3fe.png", 
+        "unicode": "👴🏾", 
+        "name": "Older Man - Tone 4"
+    }, 
+    ":face-palm-tone4:": {
+        "style": "github", 
+        "image": "1f926-1f3fe.png", 
+        "unicode": "🤦🏾", 
+        "name": "Face Palm - Tone 4"
+    }, 
+    ":vi:": {
+        "style": "github", 
+        "image": "1f1fb-1f1ee.png", 
+        "unicode": "🇻🇮", 
+        "name": "U.s. Virgin Islands"
+    }, 
+    ":six-pointed-star:": {
+        "style": "github", 
+        "image": "1f52f.png", 
+        "unicode": "🔯", 
+        "name": "Six Pointed Star With Middle Dot"
+    }, 
+    ":flag-to:": {
+        "style": "github", 
+        "image": "1f1f9-1f1f4.png", 
+        "unicode": "🇹🇴", 
+        "name": "Tonga"
+    }, 
+    "🏇🏿": {
+        "style": "unicode", 
+        "image": "1f3c7-1f3ff.png", 
+        "name": "Horse Racing - Tone 5"
+    }, 
+    "🏇🏾": {
+        "style": "unicode", 
+        "image": "1f3c7-1f3fe.png", 
+        "name": "Horse Racing - Tone 4"
+    }, 
+    "🏇🏽": {
+        "style": "unicode", 
+        "image": "1f3c7-1f3fd.png", 
+        "name": "Horse Racing - Tone 3"
+    }, 
+    "🏇🏼": {
+        "style": "unicode", 
+        "image": "1f3c7-1f3fc.png", 
+        "name": "Horse Racing - Tone 2"
+    }, 
+    "🏇🏻": {
+        "style": "unicode", 
+        "image": "1f3c7-1f3fb.png", 
+        "name": "Horse Racing - Tone 1"
+    }, 
+    "🇱": {
+        "style": "unicode", 
+        "image": "1f1f1.png", 
+        "name": "Regional Indicator Symbol Letter L"
+    }, 
+    ":satellite:": {
+        "style": "github", 
+        "image": "1f4e1.png", 
+        "unicode": "📡", 
+        "name": "Satellite Antenna"
+    }, 
+    ":cloud-tornado:": {
+        "style": "github", 
+        "image": "1f32a.png", 
+        "unicode": "🌪", 
+        "name": "Cloud With Tornado"
+    }, 
+    "⚔": {
+        "style": "unicode", 
+        "image": "2694.png", 
+        "name": "Crossed Swords"
+    }, 
+    "😟": {
+        "style": "unicode", 
+        "image": "1f61f.png", 
+        "name": "Worried Face"
+    }, 
+    "🌚": {
+        "style": "unicode", 
+        "image": "1f31a.png", 
+        "name": "New Moon With Face"
+    }, 
+    ":thermometer_face:": {
+        "style": "github", 
+        "image": "1f912.png", 
+        "unicode": "🤒", 
+        "name": "Face With Thermometer"
+    }, 
+    ":pregnant-woman-tone5:": {
+        "style": "github", 
+        "image": "1f930-1f3ff.png", 
+        "unicode": "🤰🏿", 
+        "name": "Pregnant Woman - Tone 5"
+    }, 
+    ":flag-uy:": {
+        "style": "github", 
+        "image": "1f1fa-1f1fe.png", 
+        "unicode": "🇺🇾", 
+        "name": "Uruguay"
+    }, 
+    ":hotdog:": {
+        "style": "github", 
+        "image": "1f32d.png", 
+        "unicode": "🌭", 
+        "name": "Hot Dog"
+    }, 
+    ":flag-mx:": {
+        "style": "github", 
+        "image": "1f1f2-1f1fd.png", 
+        "unicode": "🇲🇽", 
+        "name": "Mexico"
+    }, 
+    "🚴": {
+        "style": "unicode", 
+        "image": "1f6b4.png", 
+        "name": "Bicyclist"
+    }, 
+    ":place_of_worship:": {
+        "style": "github", 
+        "image": "1f6d0.png", 
+        "unicode": "🛐", 
+        "name": "Place Of Worship"
+    }, 
+    "🥁": {
+        "style": "unicode", 
+        "image": "1f941.png", 
+        "name": "Drum With Drumsticks"
+    }, 
+    "🕉": {
+        "style": "unicode", 
+        "image": "1f549.png", 
+        "name": "Om Symbol"
+    }, 
+    ":heart_exclamation:": {
+        "style": "github", 
+        "image": "2763.png", 
+        "unicode": "❣", 
+        "name": "Heavy Heart Exclamation Mark Ornament"
+    }, 
+    ":flag-sg:": {
+        "style": "github", 
+        "image": "1f1f8-1f1ec.png", 
+        "unicode": "🇸🇬", 
+        "name": "Singapore"
+    }, 
+    ":kissing_smiling_eyes:": {
+        "style": "github", 
+        "image": "1f619.png", 
+        "unicode": "😙", 
+        "name": "Kissing Face With Smiling Eyes"
+    }, 
+    "🗞": {
+        "style": "unicode", 
+        "image": "1f5de.png", 
+        "name": "Rolled-up Newspaper"
+    }, 
+    "👳": {
+        "style": "unicode", 
+        "image": "1f473.png", 
+        "name": "Man With Turban"
+    }, 
+    ":walking_tone4:": {
+        "style": "github", 
+        "image": "1f6b6-1f3fe.png", 
+        "unicode": "🚶🏾", 
+        "name": "Pedestrian - Tone 4"
+    }, 
+    ">=)": {
+        "style": "ascii", 
+        "ascii": ">:)", 
+        "image": "1f606.png", 
+        "unicode": "😆", 
+        "name": "Smiling Face With Open Mouth And Tightly-closed Eyes"
+    }, 
+    ":writing_hand_tone4:": {
+        "style": "github", 
+        "image": "270d-1f3fe.png", 
+        "unicode": "✍🏾", 
+        "name": "Writing Hand - Tone 4"
+    }, 
+    "🔈": {
+        "style": "unicode", 
+        "image": "1f508.png", 
+        "name": "Speaker"
+    }, 
+    "🈲": {
+        "style": "unicode", 
+        "image": "1f232.png", 
+        "name": "Squared Cjk Unified Ideograph-7981"
+    }, 
+    ":crossed_flags:": {
+        "style": "github", 
+        "image": "1f38c.png", 
+        "unicode": "🎌", 
+        "name": "Crossed Flags"
+    }, 
+    ":information_desk_person_tone5:": {
+        "style": "github", 
+        "image": "1f481-1f3ff.png", 
+        "unicode": "💁🏿", 
+        "name": "Information Desk Person - Tone 5"
+    }, 
+    ":flag_gg:": {
+        "style": "github", 
+        "image": "1f1ec-1f1ec.png", 
+        "unicode": "🇬🇬", 
+        "name": "Guernsey"
+    }, 
+    ":pig:": {
+        "style": "github", 
+        "image": "1f437.png", 
+        "unicode": "🐷", 
+        "name": "Pig Face"
+    }, 
+    "🏇": {
+        "style": "unicode", 
+        "image": "1f3c7.png", 
+        "name": "Horse Racing"
+    }, 
+    ":motor-scooter:": {
+        "style": "github", 
+        "image": "1f6f5.png", 
+        "unicode": "🛵", 
+        "name": "Motor Scooter"
+    }, 
+    "🛀🏾": {
+        "style": "unicode", 
+        "image": "1f6c0-1f3fe.png", 
+        "name": "Bath - Tone 4"
+    }, 
+    ":passport-control:": {
+        "style": "github", 
+        "image": "1f6c2.png", 
+        "unicode": "🛂", 
+        "name": "Passport Control"
+    }, 
+    ":jack-o-lantern:": {
+        "style": "github", 
+        "image": "1f383.png", 
+        "unicode": "🎃", 
+        "name": "Jack-o-lantern"
+    }, 
+    "🍜": {
+        "style": "unicode", 
+        "image": "1f35c.png", 
+        "name": "Steaming Bowl"
+    }, 
+    ":bm:": {
+        "style": "github", 
+        "image": "1f1e7-1f1f2.png", 
+        "unicode": "🇧🇲", 
+        "name": "Bermuda"
+    }, 
+    ":flag-ad:": {
+        "style": "github", 
+        "image": "1f1e6-1f1e9.png", 
+        "unicode": "🇦🇩", 
+        "name": "Andorra"
+    }, 
+    ":thumbdown_tone4:": {
+        "style": "github", 
+        "image": "1f44e-1f3fe.png", 
+        "unicode": "👎🏾", 
+        "name": "Thumbs Down Sign - Tone 4"
+    }, 
+    ":flag-jp:": {
+        "style": "github", 
+        "image": "1f1ef-1f1f5.png", 
+        "unicode": "🇯🇵", 
+        "name": "Japan"
+    }, 
+    ":flag-dj:": {
+        "style": "github", 
+        "image": "1f1e9-1f1ef.png", 
+        "unicode": "🇩🇯", 
+        "name": "Djibouti"
+    }, 
+    ":grandma_tone4:": {
+        "style": "github", 
+        "image": "1f475-1f3fe.png", 
+        "unicode": "👵🏾", 
+        "name": "Older Woman - Tone 4"
+    }, 
+    ":alembic:": {
+        "style": "github", 
+        "image": "2697.png", 
+        "unicode": "⚗", 
+        "name": "Alembic"
+    }, 
+    "🛵": {
+        "style": "unicode", 
+        "image": "1f6f5.png", 
+        "name": "Motor Scooter"
+    }, 
+    ":hearts:": {
+        "style": "github", 
+        "image": "2665.png", 
+        "unicode": "♥", 
+        "name": "Black Heart Suit"
+    }, 
+    ":hamster:": {
+        "style": "github", 
+        "image": "1f439.png", 
+        "unicode": "🐹", 
+        "name": "Hamster Face"
+    }, 
+    ":flag_hk:": {
+        "style": "github", 
+        "image": "1f1ed-1f1f0.png", 
+        "unicode": "🇭🇰", 
+        "name": "Hong Kong"
+    }, 
+    ":cooking:": {
+        "style": "github", 
+        "image": "1f373.png", 
+        "unicode": "🍳", 
+        "name": "Cooking"
+    }, 
+    ":shrug-tone4:": {
+        "style": "github", 
+        "image": "1f937-1f3fe.png", 
+        "unicode": "🤷🏾", 
+        "name": "Shrug - Tone 4"
+    }, 
+    ":prince:": {
+        "style": "github", 
+        "image": "1f934.png", 
+        "unicode": "🤴", 
+        "name": "Prince"
+    }, 
+    ":flag_iq:": {
+        "style": "github", 
+        "image": "1f1ee-1f1f6.png", 
+        "unicode": "🇮🇶", 
+        "name": "Iraq"
+    }, 
+    ":raised-back-of-hand-tone3:": {
+        "style": "github", 
+        "image": "1f91a-1f3fd.png", 
+        "unicode": "🤚🏽", 
+        "name": "Raised Back Of Hand - Tone 3"
+    }, 
+    ":white_sun_with_small_cloud:": {
+        "style": "github", 
+        "image": "1f324.png", 
+        "unicode": "🌤", 
+        "name": "White Sun With Small Cloud"
+    }, 
+    ":ear_of_rice:": {
+        "style": "github", 
+        "image": "1f33e.png", 
+        "unicode": "🌾", 
+        "name": "Ear Of Rice"
+    }, 
+    ":older-man-tone1:": {
+        "style": "github", 
+        "image": "1f474-1f3fb.png", 
+        "unicode": "👴🏻", 
+        "name": "Older Man - Tone 1"
+    }, 
+    ":lion-face:": {
+        "style": "github", 
+        "image": "1f981.png", 
+        "unicode": "🦁", 
+        "name": "Lion Face"
+    }, 
+    "👉": {
+        "style": "unicode", 
+        "image": "1f449.png", 
+        "name": "White Right Pointing Backhand Index"
+    }, 
+    ":tongue:": {
+        "style": "github", 
+        "image": "1f445.png", 
+        "unicode": "👅", 
+        "name": "Tongue"
+    }, 
+    ":flag_io:": {
+        "style": "github", 
+        "image": "1f1ee-1f1f4.png", 
+        "unicode": "🇮🇴", 
+        "name": "British Indian Ocean Territory"
+    }, 
+    "📞": {
+        "style": "unicode", 
+        "image": "1f4de.png", 
+        "name": "Telephone Receiver"
+    }, 
+    "🕳": {
+        "style": "unicode", 
+        "image": "1f573.png", 
+        "name": "Hole"
+    }, 
+    ":flag_sz:": {
+        "style": "github", 
+        "image": "1f1f8-1f1ff.png", 
+        "unicode": "🇸🇿", 
+        "name": "Swaziland"
+    }, 
+    ":om:": {
+        "style": "github", 
+        "image": "1f1f4-1f1f2.png", 
+        "unicode": "🇴🇲", 
+        "name": "Oman"
+    }, 
+    ":ec:": {
+        "style": "github", 
+        "image": "1f1ea-1f1e8.png", 
+        "unicode": "🇪🇨", 
+        "name": "Ecuador"
+    }, 
+    ":arrow-down:": {
+        "style": "github", 
+        "image": "2b07.png", 
+        "unicode": "⬇", 
+        "name": "Downwards Black Arrow"
+    }, 
+    ":crescent-moon:": {
+        "style": "github", 
+        "image": "1f319.png", 
+        "unicode": "🌙", 
+        "name": "Crescent Moon"
+    }, 
+    "%)": {
+        "style": "ascii", 
+        "ascii": "#-)", 
+        "image": "1f635.png", 
+        "unicode": "😵", 
+        "name": "Dizzy Face"
+    }, 
+    "😈": {
+        "style": "unicode", 
+        "image": "1f608.png", 
+        "name": "Smiling Face With Horns"
+    }, 
+    ":shallow-pan-of-food:": {
+        "style": "github", 
+        "image": "1f958.png", 
+        "unicode": "🥘", 
+        "name": "Shallow Pan Of Food"
+    }, 
+    ":girl_tone5:": {
+        "style": "github", 
+        "image": "1f467-1f3ff.png", 
+        "unicode": "👧🏿", 
+        "name": "Girl - Tone 5"
+    }, 
+    ":small_red_triangle_down:": {
+        "style": "github", 
+        "image": "1f53b.png", 
+        "unicode": "🔻", 
+        "name": "Down-pointing Red Triangle"
+    }, 
+    ":flag_pn:": {
+        "style": "github", 
+        "image": "1f1f5-1f1f3.png", 
+        "unicode": "🇵🇳", 
+        "name": "Pitcairn"
+    }, 
+    ":no_mobile_phones:": {
+        "style": "github", 
+        "image": "1f4f5.png", 
+        "unicode": "📵", 
+        "name": "No Mobile Phones"
+    }, 
+    "‼": {
+        "style": "unicode", 
+        "image": "203c.png", 
+        "name": "Double Exclamation Mark"
+    }, 
+    ":tomato:": {
+        "style": "github", 
+        "image": "1f345.png", 
+        "unicode": "🍅", 
+        "name": "Tomato"
+    }, 
+    "👂🏼": {
+        "style": "unicode", 
+        "image": "1f442-1f3fc.png", 
+        "name": "Ear - Tone 2"
+    }, 
+    ":flag_mm:": {
+        "style": "github", 
+        "image": "1f1f2-1f1f2.png", 
+        "unicode": "🇲🇲", 
+        "name": "Myanmar"
+    }, 
+    ":family_mwgg:": {
+        "style": "github", 
+        "image": "1f468-1f469-1f467-1f467.png", 
+        "unicode": "👨👩👧👧", 
+        "name": "Family (man,woman,girl,girl)"
+    }, 
+    ":point_down:": {
+        "style": "github", 
+        "image": "1f447.png", 
+        "unicode": "👇", 
+        "name": "White Down Pointing Backhand Index"
+    }, 
+    ":flag_cz:": {
+        "style": "github", 
+        "image": "1f1e8-1f1ff.png", 
+        "unicode": "🇨🇿", 
+        "name": "The Czech Republic"
+    }, 
+    ":lu:": {
+        "style": "github", 
+        "image": "1f1f1-1f1fa.png", 
+        "unicode": "🇱🇺", 
+        "name": "Luxembourg"
+    }, 
+    ":water_buffalo:": {
+        "style": "github", 
+        "image": "1f403.png", 
+        "unicode": "🐃", 
+        "name": "Water Buffalo"
+    }, 
+    ":evergreen-tree:": {
+        "style": "github", 
+        "image": "1f332.png", 
+        "unicode": "🌲", 
+        "name": "Evergreen Tree"
+    }, 
+    ":card_box:": {
+        "style": "github", 
+        "image": "1f5c3.png", 
+        "unicode": "🗃", 
+        "name": "Card File Box"
+    }, 
+    ":massage-tone3:": {
+        "style": "github", 
+        "image": "1f486-1f3fd.png", 
+        "unicode": "💆🏽", 
+        "name": "Face Massage - Tone 3"
+    }, 
+    "👂🏻": {
+        "style": "unicode", 
+        "image": "1f442-1f3fb.png", 
+        "name": "Ear - Tone 1"
+    }, 
+    ":horse_racing_tone4:": {
+        "style": "github", 
+        "image": "1f3c7-1f3fe.png", 
+        "unicode": "🏇🏾", 
+        "name": "Horse Racing - Tone 4"
+    }, 
+    "🦂": {
+        "style": "unicode", 
+        "image": "1f982.png", 
+        "name": "Scorpion"
+    }, 
+    "🎆": {
+        "style": "unicode", 
+        "image": "1f386.png", 
+        "name": "Fireworks"
+    }, 
+    ":princess_tone4:": {
+        "style": "github", 
+        "image": "1f478-1f3fe.png", 
+        "unicode": "👸🏾", 
+        "name": "Princess - Tone 4"
+    }, 
+    "🖊": {
+        "style": "unicode", 
+        "image": "1f58a.png", 
+        "name": "Lower Left Ballpoint Pen"
+    }, 
+    ":wolf:": {
+        "style": "github", 
+        "image": "1f43a.png", 
+        "unicode": "🐺", 
+        "name": "Wolf Face"
+    }, 
+    ":flag-iq:": {
+        "style": "github", 
+        "image": "1f1ee-1f1f6.png", 
+        "unicode": "🇮🇶", 
+        "name": "Iraq"
+    }, 
+    ":flag-ck:": {
+        "style": "github", 
+        "image": "1f1e8-1f1f0.png", 
+        "unicode": "🇨🇰", 
+        "name": "Cook Islands"
+    }, 
+    ":man-tone1:": {
+        "style": "github", 
+        "image": "1f468-1f3fb.png", 
+        "unicode": "👨🏻", 
+        "name": "Man - Tone 1"
+    }, 
+    "🐟": {
+        "style": "unicode", 
+        "image": "1f41f.png", 
+        "name": "Fish"
+    }, 
+    ":jm:": {
+        "style": "github", 
+        "image": "1f1ef-1f1f2.png", 
+        "unicode": "🇯🇲", 
+        "name": "Jamaica"
+    }, 
+    ":bride-with-veil:": {
+        "style": "github", 
+        "image": "1f470.png", 
+        "unicode": "👰", 
+        "name": "Bride With Veil"
+    }, 
+    "💴": {
+        "style": "unicode", 
+        "image": "1f4b4.png", 
+        "name": "Banknote With Yen Sign"
+    }, 
+    "♓": {
+        "style": "unicode", 
+        "image": "2653.png", 
+        "name": "Pisces"
+    }, 
+    ":rainbow_flag:": {
+        "style": "github", 
+        "image": "1f3f3-1f308.png", 
+        "unicode": "🏳🌈", 
+        "name": "Gay_pride_flag"
+    }, 
+    ":mans_shoe:": {
+        "style": "github", 
+        "image": "1f45e.png", 
+        "unicode": "👞", 
+        "name": "Mans Shoe"
+    }, 
+    ":left-right-arrow:": {
+        "style": "github", 
+        "image": "2194.png", 
+        "unicode": "↔", 
+        "name": "Left Right Arrow"
+    }, 
+    "👃🏻": {
+        "style": "unicode", 
+        "image": "1f443-1f3fb.png", 
+        "name": "Nose - Tone 1"
+    }, 
+    "👃🏿": {
+        "style": "unicode", 
+        "image": "1f443-1f3ff.png", 
+        "name": "Nose - Tone 5"
+    }, 
+    "👃🏾": {
+        "style": "unicode", 
+        "image": "1f443-1f3fe.png", 
+        "name": "Nose - Tone 4"
+    }, 
+    "👃🏽": {
+        "style": "unicode", 
+        "image": "1f443-1f3fd.png", 
+        "name": "Nose - Tone 3"
+    }, 
+    "👃🏼": {
+        "style": "unicode", 
+        "image": "1f443-1f3fc.png", 
+        "name": "Nose - Tone 2"
+    }, 
+    ":bow:": {
+        "style": "github", 
+        "image": "1f647.png", 
+        "unicode": "🙇", 
+        "name": "Person Bowing Deeply"
+    }, 
+    ":flag-hm:": {
+        "style": "github", 
+        "image": "1f1ed-1f1f2.png", 
+        "unicode": "🇭🇲", 
+        "name": "Heard Island And Mcdonald Islands"
+    }, 
+    ":beach:": {
+        "style": "github", 
+        "image": "1f3d6.png", 
+        "unicode": "🏖", 
+        "name": "Beach With Umbrella"
+    }, 
+    "🇬🇩": {
+        "style": "unicode", 
+        "image": "1f1ec-1f1e9.png", 
+        "name": "Grenada"
+    }, 
+    ":gh:": {
+        "style": "github", 
+        "image": "1f1ec-1f1ed.png", 
+        "unicode": "🇬🇭", 
+        "name": "Ghana"
+    }, 
+    "👱🏼": {
+        "style": "unicode", 
+        "image": "1f471-1f3fc.png", 
+        "name": "Person With Blond Hair - Tone 2"
+    }, 
+    ":ear-tone2:": {
+        "style": "github", 
+        "image": "1f442-1f3fc.png", 
+        "unicode": "👂🏼", 
+        "name": "Ear - Tone 2"
+    }, 
+    "🇬🇵": {
+        "style": "unicode", 
+        "image": "1f1ec-1f1f5.png", 
+        "name": "Guadeloupe"
+    }, 
+    ":flag-gw:": {
+        "style": "github", 
+        "image": "1f1ec-1f1fc.png", 
+        "unicode": "🇬🇼", 
+        "name": "Guinea-bissau"
+    }, 
+    ":racing_car:": {
+        "style": "github", 
+        "image": "1f3ce.png", 
+        "unicode": "🏎", 
+        "name": "Racing Car"
+    }, 
+    ":flag_sg:": {
+        "style": "github", 
+        "image": "1f1f8-1f1ec.png", 
+        "unicode": "🇸🇬", 
+        "name": "Singapore"
+    }, 
+    ":white_flower:": {
+        "style": "github", 
+        "image": "1f4ae.png", 
+        "unicode": "💮", 
+        "name": "White Flower"
+    }, 
+    ":dancer:": {
+        "style": "github", 
+        "image": "1f483.png", 
+        "unicode": "💃", 
+        "name": "Dancer"
+    }, 
+    "📵": {
+        "style": "unicode", 
+        "image": "1f4f5.png", 
+        "name": "No Mobile Phones"
+    }, 
+    ":incoming-envelope:": {
+        "style": "github", 
+        "image": "1f4e8.png", 
+        "unicode": "📨", 
+        "name": "Incoming Envelope"
+    }, 
+    ":link:": {
+        "style": "github", 
+        "image": "1f517.png", 
+        "unicode": "🔗", 
+        "name": "Link Symbol"
+    }, 
+    ":flag_lr:": {
+        "style": "github", 
+        "image": "1f1f1-1f1f7.png", 
+        "unicode": "🇱🇷", 
+        "name": "Liberia"
+    }, 
+    ":leftwards-arrow-with-hook:": {
+        "style": "github", 
+        "image": "21a9.png", 
+        "unicode": "↩", 
+        "name": "Leftwards Arrow With Hook"
+    }, 
+    ":white_sun_rain_cloud:": {
+        "style": "github", 
+        "image": "1f326.png", 
+        "unicode": "🌦", 
+        "name": "White Sun Behind Cloud With Rain"
+    }, 
+    "💊": {
+        "style": "unicode", 
+        "image": "1f48a.png", 
+        "name": "Pill"
+    }, 
+    ":raised_hands_tone1:": {
+        "style": "github", 
+        "image": "1f64c-1f3fb.png", 
+        "unicode": "🙌🏻", 
+        "name": "Person Raising Both Hands In Celebration - Tone 1"
+    }, 
+    "🤗": {
+        "style": "unicode", 
+        "image": "1f917.png", 
+        "name": "Hugging Face"
+    }, 
+    "🌛": {
+        "style": "unicode", 
+        "image": "1f31b.png", 
+        "name": "First Quarter Moon With Face"
+    }, 
+    ":white-small-square:": {
+        "style": "github", 
+        "image": "25ab.png", 
+        "unicode": "▫", 
+        "name": "White Small Square"
+    }, 
+    "🔟": {
+        "style": "unicode", 
+        "image": "1f51f.png", 
+        "name": "Keycap Ten"
+    }, 
+    ":cl:": {
+        "style": "github", 
+        "image": "1f191.png", 
+        "unicode": "🆑", 
+        "name": "Squared Cl"
+    }, 
+    ":satisfied:": {
+        "style": "github", 
+        "ascii": ">:)", 
+        "image": "1f606.png", 
+        "unicode": "😆", 
+        "name": "Smiling Face With Open Mouth And Tightly-closed Eyes"
+    }, 
+    ":heavy-division-sign:": {
+        "style": "github", 
+        "image": "2797.png", 
+        "unicode": "➗", 
+        "name": "Heavy Division Sign"
+    }, 
+    ":back_of_hand_tone1:": {
+        "style": "github", 
+        "image": "1f91a-1f3fb.png", 
+        "unicode": "🤚🏻", 
+        "name": "Raised Back Of Hand - Tone 1"
+    }, 
+    "🎰": {
+        "style": "unicode", 
+        "image": "1f3b0.png", 
+        "name": "Slot Machine"
+    }, 
+    ":thumbsup-tone3:": {
+        "style": "github", 
+        "image": "1f44d-1f3fd.png", 
+        "unicode": "👍🏽", 
+        "name": "Thumbs Up Sign - Tone 3"
+    }, 
+    "⚾": {
+        "style": "unicode", 
+        "image": "26be.png", 
+        "name": "Baseball"
+    }, 
+    ":womans_hat:": {
+        "style": "github", 
+        "image": "1f452.png", 
+        "unicode": "👒", 
+        "name": "Womans Hat"
+    }, 
+    "🙉": {
+        "style": "unicode", 
+        "image": "1f649.png", 
+        "name": "Hear-no-evil Monkey"
+    }, 
+    "❓": {
+        "style": "unicode", 
+        "image": "2753.png", 
+        "name": "Black Question Mark Ornament"
+    }, 
+    ":dark-sunglasses:": {
+        "style": "github", 
+        "image": "1f576.png", 
+        "unicode": "🕶", 
+        "name": "Dark Sunglasses"
+    }, 
+    ":medal:": {
+        "style": "github", 
+        "image": "1f3c5.png", 
+        "unicode": "🏅", 
+        "name": "Sports Medal"
+    }, 
+    ":raising-hand:": {
+        "style": "github", 
+        "image": "1f64b.png", 
+        "unicode": "🙋", 
+        "name": "Happy Person Raising One Hand"
+    }, 
+    ":jp:": {
+        "style": "github", 
+        "image": "1f1ef-1f1f5.png", 
+        "unicode": "🇯🇵", 
+        "name": "Japan"
+    }, 
+    ":guardsman_tone3:": {
+        "style": "github", 
+        "image": "1f482-1f3fd.png", 
+        "unicode": "💂🏽", 
+        "name": "Guardsman - Tone 3"
+    }, 
+    "✒": {
+        "style": "unicode", 
+        "image": "2712.png", 
+        "name": "Black Nib"
+    }, 
+    ":deciduous-tree:": {
+        "style": "github", 
+        "image": "1f333.png", 
+        "unicode": "🌳", 
+        "name": "Deciduous Tree"
+    }, 
+    ":v_tone3:": {
+        "style": "github", 
+        "image": "270c-1f3fd.png", 
+        "unicode": "✌🏽", 
+        "name": "Victory Hand - Tone 3"
+    }, 
+    ":thumbup_tone4:": {
+        "style": "github", 
+        "image": "1f44d-1f3fe.png", 
+        "unicode": "👍🏾", 
+        "name": "Thumbs Up Sign - Tone 4"
+    }, 
+    ":flag-pm:": {
+        "style": "github", 
+        "image": "1f1f5-1f1f2.png", 
+        "unicode": "🇵🇲", 
+        "name": "Saint Pierre And Miquelon"
+    }, 
+    ":performing_arts:": {
+        "style": "github", 
+        "image": "1f3ad.png", 
+        "unicode": "🎭", 
+        "name": "Performing Arts"
+    }, 
+    ":swimmer-tone5:": {
+        "style": "github", 
+        "image": "1f3ca-1f3ff.png", 
+        "unicode": "🏊🏿", 
+        "name": "Swimmer - Tone 5"
+    }, 
+    ":beach_with_umbrella:": {
+        "style": "github", 
+        "image": "1f3d6.png", 
+        "unicode": "🏖", 
+        "name": "Beach With Umbrella"
+    }, 
+    ":ok_woman_tone1:": {
+        "style": "github", 
+        "image": "1f646-1f3fb.png", 
+        "unicode": "🙆🏻", 
+        "name": "Face With Ok Gesture Tone1"
+    }, 
+    ":man_dancing_tone5:": {
+        "style": "github", 
+        "image": "1f57a-1f3ff.png", 
+        "unicode": "🕺🏿", 
+        "name": "Man Dancing - Tone 5"
+    }, 
+    ":kissing_heart:": {
+        "style": "github", 
+        "ascii": ":*", 
+        "image": "1f618.png", 
+        "unicode": "😘", 
+        "name": "Face Throwing A Kiss"
+    }, 
+    ":cartwheel_tone5:": {
+        "style": "github", 
+        "image": "1f938-1f3ff.png", 
+        "unicode": "🤸🏿", 
+        "name": "Person Doing Cartwheel - Tone 5"
+    }, 
+    "🏵": {
+        "style": "unicode", 
+        "image": "1f3f5.png", 
+        "name": "Rosette"
+    }, 
+    ":flag_vc:": {
+        "style": "github", 
+        "image": "1f1fb-1f1e8.png", 
+        "unicode": "🇻🇨", 
+        "name": "Saint Vincent And The Grenadines"
+    }, 
+    "🎊": {
+        "style": "unicode", 
+        "image": "1f38a.png", 
+        "name": "Confetti Ball"
+    }, 
+    ":so:": {
+        "style": "github", 
+        "image": "1f1f8-1f1f4.png", 
+        "unicode": "🇸🇴", 
+        "name": "Somalia"
+    }, 
+    ":octopus:": {
+        "style": "github", 
+        "image": "1f419.png", 
+        "unicode": "🐙", 
+        "name": "Octopus"
+    }, 
+    "🐛": {
+        "style": "unicode", 
+        "image": "1f41b.png", 
+        "name": "Bug"
+    }, 
+    ":fishing_pole_and_fish:": {
+        "style": "github", 
+        "image": "1f3a3.png", 
+        "unicode": "🎣", 
+        "name": "Fishing Pole And Fish"
+    }, 
+    ":rowboat-tone3:": {
+        "style": "github", 
+        "image": "1f6a3-1f3fd.png", 
+        "unicode": "🚣🏽", 
+        "name": "Rowboat - Tone 3"
+    }, 
+    ":fingers-crossed-tone4:": {
+        "style": "github", 
+        "image": "1f91e-1f3fe.png", 
+        "unicode": "🤞🏾", 
+        "name": "Hand With Index And Middle Fingers Crossed - Tone 4"
+    }, 
+    ":tone2:": {
+        "style": "github", 
+        "image": "1f3fc.png", 
+        "unicode": "🏼", 
+        "name": "Emoji Modifier Fitzpatrick Type-3"
+    }, 
+    ":love-hotel:": {
+        "style": "github", 
+        "image": "1f3e9.png", 
+        "unicode": "🏩", 
+        "name": "Love Hotel"
+    }, 
+    ":spy_tone2:": {
+        "style": "github", 
+        "image": "1f575-1f3fc.png", 
+        "unicode": "🕵🏼", 
+        "name": "Sleuth Or Spy - Tone 2"
+    }, 
+    "💰": {
+        "style": "unicode", 
+        "image": "1f4b0.png", 
+        "name": "Money Bag"
+    }, 
+    ":flag_in:": {
+        "style": "github", 
+        "image": "1f1ee-1f1f3.png", 
+        "unicode": "🇮🇳", 
+        "name": "India"
+    }, 
+    ":last_quarter_moon_with_face:": {
+        "style": "github", 
+        "image": "1f31c.png", 
+        "unicode": "🌜", 
+        "name": "Last Quarter Moon With Face"
+    }, 
+    ":violin:": {
+        "style": "github", 
+        "image": "1f3bb.png", 
+        "unicode": "🎻", 
+        "name": "Violin"
+    }, 
+    ":flag_am:": {
+        "style": "github", 
+        "image": "1f1e6-1f1f2.png", 
+        "unicode": "🇦🇲", 
+        "name": "Armenia"
+    }, 
+    ":star2:": {
+        "style": "github", 
+        "image": "1f31f.png", 
+        "unicode": "🌟", 
+        "name": "Glowing Star"
+    }, 
+    ":race_car:": {
+        "style": "github", 
+        "image": "1f3ce.png", 
+        "unicode": "🏎", 
+        "name": "Racing Car"
+    }, 
+    ":middle_finger_tone5:": {
+        "style": "github", 
+        "image": "1f595-1f3ff.png", 
+        "unicode": "🖕🏿", 
+        "name": "Reversed Hand With Middle Finger Extended - Tone 5"
+    }, 
+    ":flag-ta:": {
+        "style": "github", 
+        "image": "1f1f9-1f1e6.png", 
+        "unicode": "🇹🇦", 
+        "name": "Tristan Da Cunha"
+    }, 
+    ":green_heart:": {
+        "style": "github", 
+        "image": "1f49a.png", 
+        "unicode": "💚", 
+        "name": "Green Heart"
+    }, 
+    ":ant:": {
+        "style": "github", 
+        "image": "1f41c.png", 
+        "unicode": "🐜", 
+        "name": "Ant"
+    }, 
+    ":wave_tone3:": {
+        "style": "github", 
+        "image": "1f44b-1f3fd.png", 
+        "unicode": "👋🏽", 
+        "name": "Waving Hand Sign - Tone 3"
+    }, 
+    ":writing-hand-tone4:": {
+        "style": "github", 
+        "image": "270d-1f3fe.png", 
+        "unicode": "✍🏾", 
+        "name": "Writing Hand - Tone 4"
+    }, 
+    ":frog:": {
+        "style": "github", 
+        "image": "1f438.png", 
+        "unicode": "🐸", 
+        "name": "Frog Face"
+    }, 
+    "🚝": {
+        "style": "unicode", 
+        "image": "1f69d.png", 
+        "name": "Monorail"
+    }, 
+    ":pregnant-woman-tone3:": {
+        "style": "github", 
+        "image": "1f930-1f3fd.png", 
+        "unicode": "🤰🏽", 
+        "name": "Pregnant Woman - Tone 3"
+    }, 
+    ":blue_book:": {
+        "style": "github", 
+        "image": "1f4d8.png", 
+        "unicode": "📘", 
+        "name": "Blue Book"
+    }, 
+    ":facepalm_tone4:": {
+        "style": "github", 
+        "image": "1f926-1f3fe.png", 
+        "unicode": "🤦🏾", 
+        "name": "Face Palm - Tone 4"
+    }, 
+    ":flag_dm:": {
+        "style": "github", 
+        "image": "1f1e9-1f1f2.png", 
+        "unicode": "🇩🇲", 
+        "name": "Dominica"
+    }, 
+    "😲": {
+        "style": "unicode", 
+        "image": "1f632.png", 
+        "name": "Astonished Face"
+    }, 
+    ":nl:": {
+        "style": "github", 
+        "image": "1f1f3-1f1f1.png", 
+        "unicode": "🇳🇱", 
+        "name": "The Netherlands"
+    }, 
+    ":flag-mv:": {
+        "style": "github", 
+        "image": "1f1f2-1f1fb.png", 
+        "unicode": "🇲🇻", 
+        "name": "Maldives"
+    }, 
+    ":flag_kp:": {
+        "style": "github", 
+        "image": "1f1f0-1f1f5.png", 
+        "unicode": "🇰🇵", 
+        "name": "North Korea"
+    }, 
+    ":wc:": {
+        "style": "github", 
+        "image": "1f6be.png", 
+        "unicode": "🚾", 
+        "name": "Water Closet"
+    }, 
+    ":flag-sa:": {
+        "style": "github", 
+        "image": "1f1f8-1f1e6.png", 
+        "unicode": "🇸🇦", 
+        "name": "Saudi Arabia"
+    }, 
+    "🥘": {
+        "style": "unicode", 
+        "image": "1f958.png", 
+        "name": "Shallow Pan Of Food"
+    }, 
+    ":sick:": {
+        "style": "github", 
+        "image": "1f922.png", 
+        "unicode": "🤢", 
+        "name": "Nauseated Face"
+    }, 
+    "📱": {
+        "style": "unicode", 
+        "image": "1f4f1.png", 
+        "name": "Mobile Phone"
+    }, 
+    "🇭🇷": {
+        "style": "unicode", 
+        "image": "1f1ed-1f1f7.png", 
+        "name": "Croatia"
+    }, 
+    "🇭🇰": {
+        "style": "unicode", 
+        "image": "1f1ed-1f1f0.png", 
+        "name": "Hong Kong"
+    }, 
+    "🇭🇳": {
+        "style": "unicode", 
+        "image": "1f1ed-1f1f3.png", 
+        "name": "Honduras"
+    }, 
+    "🇭🇲": {
+        "style": "unicode", 
+        "image": "1f1ed-1f1f2.png", 
+        "name": "Heard Island And Mcdonald Islands"
+    }, 
+    ":speaking-head:": {
+        "style": "github", 
+        "image": "1f5e3.png", 
+        "unicode": "🗣", 
+        "name": "Speaking Head In Silhouette"
+    }, 
+    "◻": {
+        "style": "unicode", 
+        "image": "25fb.png", 
+        "name": "White Medium Square"
+    }, 
+    "🇭🇹": {
+        "style": "unicode", 
+        "image": "1f1ed-1f1f9.png", 
+        "name": "Haiti"
+    }, 
+    ":flag-kp:": {
+        "style": "github", 
+        "image": "1f1f0-1f1f5.png", 
+        "unicode": "🇰🇵", 
+        "name": "North Korea"
+    }, 
+    ":writing_hand_tone2:": {
+        "style": "github", 
+        "image": "270d-1f3fc.png", 
+        "unicode": "✍🏼", 
+        "name": "Writing Hand - Tone 2"
+    }, 
+    "💆": {
+        "style": "unicode", 
+        "image": "1f486.png", 
+        "name": "Face Massage"
+    }, 
+    ":bed:": {
+        "style": "github", 
+        "image": "1f6cf.png", 
+        "unicode": "🛏", 
+        "name": "Bed"
+    }, 
+    ":champagne:": {
+        "style": "github", 
+        "image": "1f37e.png", 
+        "unicode": "🍾", 
+        "name": "Bottle With Popping Cork"
+    }, 
+    "🔛": {
+        "style": "unicode", 
+        "image": "1f51b.png", 
+        "name": "On With Exclamation Mark With Left Right Arrow Abo"
+    }, 
+    ":oncoming_automobile:": {
+        "style": "github", 
+        "image": "1f698.png", 
+        "unicode": "🚘", 
+        "name": "Oncoming Automobile"
+    }, 
+    "🌟": {
+        "style": "unicode", 
+        "image": "1f31f.png", 
+        "name": "Glowing Star"
+    }, 
+    ":flag_ge:": {
+        "style": "github", 
+        "image": "1f1ec-1f1ea.png", 
+        "unicode": "🇬🇪", 
+        "name": "Georgia"
+    }, 
+    ":expecting_woman_tone2:": {
+        "style": "github", 
+        "image": "1f930-1f3fc.png", 
+        "unicode": "🤰🏼", 
+        "name": "Pregnant Woman - Tone 2"
+    }, 
+    "🎴": {
+        "style": "unicode", 
+        "image": "1f3b4.png", 
+        "name": "Flower Playing Cards"
+    }, 
+    ":pf:": {
+        "style": "github", 
+        "image": "1f1f5-1f1eb.png", 
+        "unicode": "🇵🇫", 
+        "name": "French Polynesia"
+    }, 
+    ":triumph:": {
+        "style": "github", 
+        "image": "1f624.png", 
+        "unicode": "😤", 
+        "name": "Face With Look Of Triumph"
+    }, 
+    ":thumbdown_tone2:": {
+        "style": "github", 
+        "image": "1f44e-1f3fc.png", 
+        "unicode": "👎🏼", 
+        "name": "Thumbs Down Sign - Tone 2"
+    }, 
+    ":construction_worker:": {
+        "style": "github", 
+        "image": "1f477.png", 
+        "unicode": "👷", 
+        "name": "Construction Worker"
+    }, 
+    ":grandma_tone2:": {
+        "style": "github", 
+        "image": "1f475-1f3fc.png", 
+        "unicode": "👵🏼", 
+        "name": "Older Woman - Tone 2"
+    }, 
+    ":shrug:": {
+        "style": "github", 
+        "image": "1f937.png", 
+        "unicode": "🤷", 
+        "name": "Shrug"
+    }, 
+    ":waving_black_flag:": {
+        "style": "github", 
+        "image": "1f3f4.png", 
+        "unicode": "🏴", 
+        "name": "Waving Black Flag"
+    }, 
+    ":wave-tone4:": {
+        "style": "github", 
+        "image": "1f44b-1f3fe.png", 
+        "unicode": "👋🏾", 
+        "name": "Waving Hand Sign - Tone 4"
+    }, 
+    ":heavy_minus_sign:": {
+        "style": "github", 
+        "image": "2796.png", 
+        "unicode": "➖", 
+        "name": "Heavy Minus Sign"
+    }, 
+    ":desktop:": {
+        "style": "github", 
+        "image": "1f5a5.png", 
+        "unicode": "🖥", 
+        "name": "Desktop Computer"
+    }, 
+    ":juggling_tone5:": {
+        "style": "github", 
+        "image": "1f939-1f3ff.png", 
+        "unicode": "🤹🏿", 
+        "name": "Juggling - Tone 5"
+    }, 
+    ":no-smoking:": {
+        "style": "github", 
+        "image": "1f6ad.png", 
+        "unicode": "🚭", 
+        "name": "No Smoking Symbol"
+    }, 
+    ":black_square_button:": {
+        "style": "github", 
+        "image": "1f532.png", 
+        "unicode": "🔲", 
+        "name": "Black Square Button"
+    }, 
+    ":closed_lock_with_key:": {
+        "style": "github", 
+        "image": "1f510.png", 
+        "unicode": "🔐", 
+        "name": "Closed Lock With Key"
+    }, 
+    ":sweat_smile:": {
+        "style": "github", 
+        "ascii": "':)", 
+        "image": "1f605.png", 
+        "unicode": "😅", 
+        "name": "Smiling Face With Open Mouth And Cold Sweat"
+    }, 
+    ":clock1030:": {
+        "style": "github", 
+        "image": "1f565.png", 
+        "unicode": "🕥", 
+        "name": "Clock Face Ten-thirty"
+    }, 
+    ":clock7:": {
+        "style": "github", 
+        "image": "1f556.png", 
+        "unicode": "🕖", 
+        "name": "Clock Face Seven Oclock"
+    }, 
+    ":flag_is:": {
+        "style": "github", 
+        "image": "1f1ee-1f1f8.png", 
+        "unicode": "🇮🇸", 
+        "name": "Iceland"
+    }, 
+    "🔲": {
+        "style": "unicode", 
+        "image": "1f532.png", 
+        "name": "Black Square Button"
+    }, 
+    ":regional-indicator-a:": {
+        "style": "github", 
+        "image": "1f1e6.png", 
+        "unicode": "🇦", 
+        "name": "Regional Indicator Symbol Letter A"
+    }, 
+    ":prince-tone3:": {
+        "style": "github", 
+        "image": "1f934-1f3fd.png", 
+        "unicode": "🤴🏽", 
+        "name": "Prince - Tone 3"
+    }, 
+    "📇": {
+        "style": "unicode", 
+        "image": "1f4c7.png", 
+        "name": "Card Index"
+    }, 
+    ":cartwheel-tone3:": {
+        "style": "github", 
+        "image": "1f938-1f3fd.png", 
+        "unicode": "🤸🏽", 
+        "name": "Person Doing Cartwheel - Tone 3"
+    }, 
+    ":raised-hands-tone2:": {
+        "style": "github", 
+        "image": "1f64c-1f3fc.png", 
+        "unicode": "🙌🏼", 
+        "name": "Person Raising Both Hands In Celebration - Tone 2"
+    }, 
+    ":flag_ky:": {
+        "style": "github", 
+        "image": "1f1f0-1f1fe.png", 
+        "unicode": "🇰🇾", 
+        "name": "Cayman Islands"
+    }, 
+    ":point-left:": {
+        "style": "github", 
+        "image": "1f448.png", 
+        "unicode": "👈", 
+        "name": "White Left Pointing Backhand Index"
+    }, 
+    ":card_file_box:": {
+        "style": "github", 
+        "image": "1f5c3.png", 
+        "unicode": "🗃", 
+        "name": "Card File Box"
+    }, 
+    "👜": {
+        "style": "unicode", 
+        "image": "1f45c.png", 
+        "name": "Handbag"
+    }, 
+    ":older-man-tone3:": {
+        "style": "github", 
+        "image": "1f474-1f3fd.png", 
+        "unicode": "👴🏽", 
+        "name": "Older Man - Tone 3"
+    }, 
+    ":nerd:": {
+        "style": "github", 
+        "image": "1f913.png", 
+        "unicode": "🤓", 
+        "name": "Nerd Face"
+    }, 
+    ":flags:": {
+        "style": "github", 
+        "image": "1f38f.png", 
+        "unicode": "🎏", 
+        "name": "Carp Streamer"
+    }, 
+    ":ee:": {
+        "style": "github", 
+        "image": "1f1ea-1f1ea.png", 
+        "unicode": "🇪🇪", 
+        "name": "Estonia"
+    }, 
+    "🇵": {
+        "style": "unicode", 
+        "image": "1f1f5.png", 
+        "name": "Regional Indicator Symbol Letter P"
+    }, 
+    ":flag_sx:": {
+        "style": "github", 
+        "image": "1f1f8-1f1fd.png", 
+        "unicode": "🇸🇽", 
+        "name": "Sint Maarten"
+    }, 
+    ":sneezing_face:": {
+        "style": "github", 
+        "image": "1f927.png", 
+        "unicode": "🤧", 
+        "name": "Sneezing Face"
+    }, 
+    "🖕🏽": {
+        "style": "unicode", 
+        "image": "1f595-1f3fd.png", 
+        "name": "Reversed Hand With Middle Finger Extended - Tone 3"
+    }, 
+    "🖕🏼": {
+        "style": "unicode", 
+        "image": "1f595-1f3fc.png", 
+        "name": "Reversed Hand With Middle Finger Extended - Tone 2"
+    }, 
+    "🖕🏿": {
+        "style": "unicode", 
+        "image": "1f595-1f3ff.png", 
+        "name": "Reversed Hand With Middle Finger Extended - Tone 5"
+    }, 
+    "🖕🏾": {
+        "style": "unicode", 
+        "image": "1f595-1f3fe.png", 
+        "name": "Reversed Hand With Middle Finger Extended - Tone 4"
+    }, 
+    "🖕🏻": {
+        "style": "unicode", 
+        "image": "1f595-1f3fb.png", 
+        "name": "Reversed Hand With Middle Finger Extended - Tone 1"
+    }, 
+    ":woman-tone2:": {
+        "style": "github", 
+        "image": "1f469-1f3fc.png", 
+        "unicode": "👩🏼", 
+        "name": "Woman - Tone 2"
+    }, 
+    ":peach:": {
+        "style": "github", 
+        "image": "1f351.png", 
+        "unicode": "🍑", 
+        "name": "Peach"
+    }, 
+    ":eyeglasses:": {
+        "style": "github", 
+        "image": "1f453.png", 
+        "unicode": "👓", 
+        "name": "Eyeglasses"
+    }, 
+    ":flag_pl:": {
+        "style": "github", 
+        "image": "1f1f5-1f1f1.png", 
+        "unicode": "🇵🇱", 
+        "name": "Poland"
+    }, 
+    "🚰": {
+        "style": "unicode", 
+        "image": "1f6b0.png", 
+        "name": "Potable Water Symbol"
+    }, 
+    "🤘🏾": {
+        "style": "unicode", 
+        "image": "1f918-1f3fe.png", 
+        "name": "Sign Of The Horns - Tone 4"
+    }, 
+    "🤘🏿": {
+        "style": "unicode", 
+        "image": "1f918-1f3ff.png", 
+        "name": "Sign Of The Horns - Tone 5"
+    }, 
+    "🤘🏼": {
+        "style": "unicode", 
+        "image": "1f918-1f3fc.png", 
+        "name": "Sign Of The Horns - Tone 2"
+    }, 
+    "🤘🏽": {
+        "style": "unicode", 
+        "image": "1f918-1f3fd.png", 
+        "name": "Sign Of The Horns - Tone 3"
+    }, 
+    ":chart-with-downwards-trend:": {
+        "style": "github", 
+        "image": "1f4c9.png", 
+        "unicode": "📉", 
+        "name": "Chart With Downwards Trend"
+    }, 
+    "🥅": {
+        "style": "unicode", 
+        "image": "1f945.png", 
+        "name": "Goal Net"
+    }, 
+    "⛹🏼": {
+        "style": "unicode", 
+        "image": "26f9-1f3fc.png", 
+        "name": "Person With Ball - Tone 2"
+    }, 
+    ":angel_tone1:": {
+        "style": "github", 
+        "image": "1f47c-1f3fb.png", 
+        "unicode": "👼🏻", 
+        "name": "Baby Angel - Tone 1"
+    }, 
+    ":nail-care-tone5:": {
+        "style": "github", 
+        "image": "1f485-1f3ff.png", 
+        "unicode": "💅🏿", 
+        "name": "Nail Polish - Tone 5"
+    }, 
+    ":rosette:": {
+        "style": "github", 
+        "image": "1f3f5.png", 
+        "unicode": "🏵", 
+        "name": "Rosette"
+    }, 
+    ":flag_mo:": {
+        "style": "github", 
+        "image": "1f1f2-1f1f4.png", 
+        "unicode": "🇲🇴", 
+        "name": "Macau"
+    }, 
+    "🏞": {
+        "style": "unicode", 
+        "image": "1f3de.png", 
+        "name": "National Park"
+    }, 
+    ":ls:": {
+        "style": "github", 
+        "image": "1f1f1-1f1f8.png", 
+        "unicode": "🇱🇸", 
+        "name": "Lesotho"
+    }, 
+    ":shamrock:": {
+        "style": "github", 
+        "image": "2618.png", 
+        "unicode": "☘", 
+        "name": "Shamrock"
+    }, 
+    ":flag_cx:": {
+        "style": "github", 
+        "image": "1f1e8-1f1fd.png", 
+        "unicode": "🇨🇽", 
+        "name": "Christmas Island"
+    }, 
+    "🌈": {
+        "style": "unicode", 
+        "image": "1f308.png", 
+        "name": "Rainbow"
+    }, 
+    ":pear:": {
+        "style": "github", 
+        "image": "1f350.png", 
+        "unicode": "🍐", 
+        "name": "Pear"
+    }, 
+    ":santa_tone1:": {
+        "style": "github", 
+        "image": "1f385-1f3fb.png", 
+        "unicode": "🎅🏻", 
+        "name": "Father Christmas - Tone 1"
+    }, 
+    ":shrug_tone4:": {
+        "style": "github", 
+        "image": "1f937-1f3fe.png", 
+        "unicode": "🤷🏾", 
+        "name": "Shrug - Tone 4"
+    }, 
+    "💝": {
+        "style": "unicode", 
+        "image": "1f49d.png", 
+        "name": "Heart With Ribbon"
+    }, 
+    ":construction-worker-tone3:": {
+        "style": "github", 
+        "image": "1f477-1f3fd.png", 
+        "unicode": "👷🏽", 
+        "name": "Construction Worker - Tone 3"
+    }, 
+    ":european-post-office:": {
+        "style": "github", 
+        "image": "1f3e4.png", 
+        "unicode": "🏤", 
+        "name": "European Post Office"
+    }, 
+    "🇬🇦": {
+        "style": "unicode", 
+        "image": "1f1ec-1f1e6.png", 
+        "name": "Gabon"
+    }, 
+    "🇬🇧": {
+        "style": "unicode", 
+        "image": "1f1ec-1f1e7.png", 
+        "name": "Great Britain"
+    }, 
+    "🇬🇮": {
+        "style": "unicode", 
+        "image": "1f1ec-1f1ee.png", 
+        "name": "Gibraltar"
+    }, 
+    "🇬🇬": {
+        "style": "unicode", 
+        "image": "1f1ec-1f1ec.png", 
+        "name": "Guernsey"
+    }, 
+    "🇬🇭": {
+        "style": "unicode", 
+        "image": "1f1ec-1f1ed.png", 
+        "name": "Ghana"
+    }, 
+    "🇬🇪": {
+        "style": "unicode", 
+        "image": "1f1ec-1f1ea.png", 
+        "name": "Georgia"
+    }, 
+    "🇬🇫": {
+        "style": "unicode", 
+        "image": "1f1ec-1f1eb.png", 
+        "name": "French Guiana"
+    }, 
+    ":baby-tone2:": {
+        "style": "github", 
+        "image": "1f476-1f3fc.png", 
+        "unicode": "👶🏼", 
+        "name": "Baby - Tone 2"
+    }, 
+    "🇬🇶": {
+        "style": "unicode", 
+        "image": "1f1ec-1f1f6.png", 
+        "name": "Equatorial Guinea"
+    }, 
+    "🇬🇷": {
+        "style": "unicode", 
+        "image": "1f1ec-1f1f7.png", 
+        "name": "Greece"
+    }, 
+    "🐲": {
+        "style": "unicode", 
+        "image": "1f432.png", 
+        "name": "Dragon Face"
+    }, 
+    "🇬🇲": {
+        "style": "unicode", 
+        "image": "1f1ec-1f1f2.png", 
+        "name": "The Gambia"
+    }, 
+    "🇬🇳": {
+        "style": "unicode", 
+        "image": "1f1ec-1f1f3.png", 
+        "name": "Guinea"
+    }, 
+    "🇬🇱": {
+        "style": "unicode", 
+        "image": "1f1ec-1f1f1.png", 
+        "name": "Greenland"
+    }, 
+    "🇬🇾": {
+        "style": "unicode", 
+        "image": "1f1ec-1f1fe.png", 
+        "name": "Guyana"
+    }, 
+    "🇬🇼": {
+        "style": "unicode", 
+        "image": "1f1ec-1f1fc.png", 
+        "name": "Guinea-bissau"
+    }, 
+    "🇬🇺": {
+        "style": "unicode", 
+        "image": "1f1ec-1f1fa.png", 
+        "name": "Guam"
+    }, 
+    "🇬🇸": {
+        "style": "unicode", 
+        "image": "1f1ec-1f1f8.png", 
+        "name": "South Georgia"
+    }, 
+    "🇬🇹": {
+        "style": "unicode", 
+        "image": "1f1ec-1f1f9.png", 
+        "name": "Guatemala"
+    }, 
+    "🖐🏻": {
+        "style": "unicode", 
+        "image": "1f590-1f3fb.png", 
+        "name": "Raised Hand With Fingers Splayed - Tone 1"
+    }, 
+    ":hand_with_index_and_middle_finger_crossed:": {
+        "style": "github", 
+        "image": "1f91e.png", 
+        "unicode": "🤞", 
+        "name": "Hand With First And Index Finger Crossed"
+    }, 
+    "🖐🏾": {
+        "style": "unicode", 
+        "image": "1f590-1f3fe.png", 
+        "name": "Raised Hand With Fingers Splayed - Tone 4"
+    }, 
+    "🖐🏿": {
+        "style": "unicode", 
+        "image": "1f590-1f3ff.png", 
+        "name": "Raised Hand With Fingers Splayed - Tone 5"
+    }, 
+    "🖐🏼": {
+        "style": "unicode", 
+        "image": "1f590-1f3fc.png", 
+        "name": "Raised Hand With Fingers Splayed - Tone 2"
+    }, 
+    "🖐🏽": {
+        "style": "unicode", 
+        "image": "1f590-1f3fd.png", 
+        "name": "Raised Hand With Fingers Splayed - Tone 3"
+    }, 
+    "⛑": {
+        "style": "unicode", 
+        "image": "26d1.png", 
+        "name": "Helmet With White Cross"
+    }, 
+    ":flag_bz:": {
+        "style": "github", 
+        "image": "1f1e7-1f1ff.png", 
+        "unicode": "🇧🇿", 
+        "name": "Belize"
+    }, 
+    "🕜": {
+        "style": "unicode", 
+        "image": "1f55c.png", 
+        "name": "Clock Face One-thirty"
+    }, 
+    ":person-with-pouting-face-tone2:": {
+        "style": "github", 
+        "image": "1f64e-1f3fc.png", 
+        "unicode": "🙎🏼", 
+        "name": "Person With Pouting Face Tone2"
+    }, 
+    ":passport_control:": {
+        "style": "github", 
+        "image": "1f6c2.png", 
+        "unicode": "🛂", 
+        "name": "Passport Control"
+    }, 
+    "♦": {
+        "style": "unicode", 
+        "image": "2666.png", 
+        "name": "Black Diamond Suit"
+    }, 
+    ":call_me_hand_tone2:": {
+        "style": "github", 
+        "image": "1f919-1f3fc.png", 
+        "unicode": "🤙🏼", 
+        "name": "Call Me Hand - Tone 2"
+    }, 
+    ":large-orange-diamond:": {
+        "style": "github", 
+        "image": "1f536.png", 
+        "unicode": "🔶", 
+        "name": "Large Orange Diamond"
+    }, 
+    ":boy:": {
+        "style": "github", 
+        "image": "1f466.png", 
+        "unicode": "👦", 
+        "name": "Boy"
+    }, 
+    ":family_wwbb:": {
+        "style": "github", 
+        "image": "1f469-1f469-1f466-1f466.png", 
+        "unicode": "👩👩👦👦", 
+        "name": "Family (woman,woman,boy,boy)"
+    }, 
+    "4⃣": {
+        "style": "unicode", 
+        "image": "0034-20e3.png", 
+        "name": "Keycap Digit Four"
+    }, 
+    ":runner-tone5:": {
+        "style": "github", 
+        "image": "1f3c3-1f3ff.png", 
+        "unicode": "🏃🏿", 
+        "name": "Runner - Tone 5"
+    }, 
+    ":handball:": {
+        "style": "github", 
+        "image": "1f93e.png", 
+        "unicode": "🤾", 
+        "name": "Handball"
+    }, 
+    "🚆": {
+        "style": "unicode", 
+        "image": "1f686.png", 
+        "name": "Train"
+    }, 
+    ":flag-ba:": {
+        "style": "github", 
+        "image": "1f1e7-1f1e6.png", 
+        "unicode": "🇧🇦", 
+        "name": "Bosnia And Herzegovina"
+    }, 
+    ":martial_arts_uniform:": {
+        "style": "github", 
+        "image": "1f94b.png", 
+        "unicode": "🥋", 
+        "name": "Martial Arts Uniform"
+    }, 
+    "↔": {
+        "style": "unicode", 
+        "image": "2194.png", 
+        "name": "Left Right Arrow"
+    }, 
+    ":gn:": {
+        "style": "github", 
+        "image": "1f1ec-1f1f3.png", 
+        "unicode": "🇬🇳", 
+        "name": "Guinea"
+    }, 
+    ":bw:": {
+        "style": "github", 
+        "image": "1f1e7-1f1fc.png", 
+        "unicode": "🇧🇼", 
+        "name": "Botswana"
+    }, 
+    ":flag-gy:": {
+        "style": "github", 
+        "image": "1f1ec-1f1fe.png", 
+        "unicode": "🇬🇾", 
+        "name": "Guyana"
+    }, 
+    ":black-joker:": {
+        "style": "github", 
+        "image": "1f0cf.png", 
+        "unicode": "🃏", 
+        "name": "Playing Card Black Joker"
+    }, 
+    ":kimono:": {
+        "style": "github", 
+        "image": "1f458.png", 
+        "unicode": "👘", 
+        "name": "Kimono"
+    }, 
+    ":flag_se:": {
+        "style": "github", 
+        "image": "1f1f8-1f1ea.png", 
+        "unicode": "🇸🇪", 
+        "name": "Sweden"
+    }, 
+    "🍳": {
+        "style": "unicode", 
+        "image": "1f373.png", 
+        "name": "Cooking"
+    }
+}
\ No newline at end of file
diff --git a/configs/shared/emacs/.emacs.d/elpa/emojify-20180611.838/emojify-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/emojify-20180611.838/emojify-autoloads.el
new file mode 100644
index 0000000000..ae187d4f69
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/emojify-20180611.838/emojify-autoloads.el
@@ -0,0 +1,95 @@
+;;; emojify-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "emojify" "emojify.el" (23377 61594 479878
+;;;;;;  475000))
+;;; Generated autoloads from emojify.el
+
+(autoload 'emojify-set-emoji-styles "emojify" "\
+Set the type of emojis that should be displayed.
+
+STYLES is the styles emoji styles that should be used, see `emojify-emoji-styles'
+
+\(fn STYLES)" nil nil)
+
+(autoload 'emojify-mode "emojify" "\
+Emojify mode
+
+\(fn &optional ARG)" t nil)
+
+(defvar global-emojify-mode nil "\
+Non-nil if Global Emojify mode is enabled.
+See the `global-emojify-mode' command
+for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `global-emojify-mode'.")
+
+(custom-autoload 'global-emojify-mode "emojify" nil)
+
+(autoload 'global-emojify-mode "emojify" "\
+Toggle Emojify mode in all buffers.
+With prefix ARG, enable Global Emojify mode if ARG is positive;
+otherwise, disable it.  If called from Lisp, enable the mode if
+ARG is omitted or nil.
+
+Emojify mode is enabled in all buffers where
+`emojify-mode' would do it.
+See `emojify-mode' for more information on Emojify mode.
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'emojify-mode-line-mode "emojify" "\
+Emojify mode line
+
+\(fn &optional ARG)" t nil)
+
+(defvar global-emojify-mode-line-mode nil "\
+Non-nil if Global Emojify-Mode-Line mode is enabled.
+See the `global-emojify-mode-line-mode' command
+for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `global-emojify-mode-line-mode'.")
+
+(custom-autoload 'global-emojify-mode-line-mode "emojify" nil)
+
+(autoload 'global-emojify-mode-line-mode "emojify" "\
+Toggle Emojify-Mode-Line mode in all buffers.
+With prefix ARG, enable Global Emojify-Mode-Line mode if ARG is positive;
+otherwise, disable it.  If called from Lisp, enable the mode if
+ARG is omitted or nil.
+
+Emojify-Mode-Line mode is enabled in all buffers where
+`emojify-mode-line-mode' would do it.
+See `emojify-mode-line-mode' for more information on Emojify-Mode-Line mode.
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'emojify-apropos-emoji "emojify" "\
+Show Emojis that match PATTERN.
+
+\(fn PATTERN)" t nil)
+
+(autoload 'emojify-insert-emoji "emojify" "\
+Interactively prompt for Emojis and insert them in the current buffer.
+
+This respects the `emojify-emoji-styles' variable.
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads nil nil ("emojify-pkg.el") (23377 61594 478542
+;;;;;;  309000))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; emojify-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/emojify-20180611.838/emojify-pkg.el b/configs/shared/emacs/.emacs.d/elpa/emojify-20180611.838/emojify-pkg.el
new file mode 100644
index 0000000000..94aae09d90
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/emojify-20180611.838/emojify-pkg.el
@@ -0,0 +1,10 @@
+(define-package "emojify" "20180611.838" "Display emojis in Emacs"
+  '((seq "1.11")
+    (ht "2.0")
+    (emacs "24.3"))
+  :keywords
+  '("multimedia" "convenience")
+  :url "https://github.com/iqbalansari/emacs-emojify")
+;; Local Variables:
+;; no-byte-compile: t
+;; End:
diff --git a/configs/shared/emacs/.emacs.d/elpa/emojify-20180611.838/emojify.el b/configs/shared/emacs/.emacs.d/elpa/emojify-20180611.838/emojify.el
new file mode 100644
index 0000000000..1e0ccea0e5
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/emojify-20180611.838/emojify.el
@@ -0,0 +1,2122 @@
+;;; emojify.el --- Display emojis in Emacs           -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2015-2018  Iqbal Ansari
+
+;; Author: Iqbal Ansari <iqbalansari02@yahoo.com>
+;; Keywords: multimedia, convenience
+;; URL: https://github.com/iqbalansari/emacs-emojify
+;; Version: 1.0
+;; Package-Requires: ((seq "1.11") (ht "2.0") (emacs "24.3"))
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This package displays emojis in Emacs similar to how Github, Slack etc do.  It
+;; can display plain ascii like ':)' as well as Github style emojis like ':smile:'
+;;
+;; It provides a minor mode `emojify-mode' to enable display of emojis in a buffer.
+;; To enable emojify mode globally use `global-emojify-mode'
+;;
+;; For detailed documentation see the projects README file at
+;; https://github.com/iqbalansari/emacs-emojify
+
+
+
+;;; Code:
+
+(require 'seq)
+(require 'ht)
+
+(require 'subr-x nil :no-error)
+(require 'cl-lib)
+(require 'json)
+(require 'regexp-opt)
+(require 'jit-lock)
+(require 'pcase)
+(require 'tar-mode)
+(require 'apropos)
+
+
+
+;; Satisfying the byte-compiler
+;; We do not "require" these functions but if `org-mode' is active we use them
+
+;; Required to determine point is in an org-list
+(declare-function org-list-get-item-begin "org-list")
+(declare-function org-at-heading-p "org")
+
+;; Required to determine point is in an org-src block
+(declare-function org-element-type "org-element")
+(declare-function org-element-at-point "org-element")
+
+;; Required for integration with company-mode
+(declare-function company-pseudo-tooltip-unhide "company")
+
+;; Shouldn't require 'jit-lock be enough :/
+(defvar jit-lock-start)
+(defvar jit-lock-end)
+
+;; Used while inserting emojis using helm
+(defvar helm-buffer)
+(defvar helm-after-initialize-hook)
+
+
+
+;; Compatibility functions
+
+(defun emojify-user-error (format &rest args)
+  "Signal a pilot error, making a message by passing FORMAT and ARGS to ‘format-message’."
+  (if (fboundp 'user-error)
+      (apply #'user-error format args)
+    (apply #'error format args)))
+
+(defun emojify-face-height (face)
+  "Get font height for the FACE."
+  (let ((face-font (face-font face)))
+    (cond
+     ((and (display-multi-font-p)
+           ;; Avoid calling font-info if the frame's default font was
+           ;; not changed since the frame was created.  That's because
+           ;; font-info is expensive for some fonts, see bug #14838.
+           (not (string= (frame-parameter nil 'font) face-font)))
+      (aref (font-info face-font) 3))
+     (t (frame-char-height)))))
+
+(defun emojify-default-font-height ()
+  "Return the height in pixels of the current buffer's default face font.
+
+`default-font-height' seems to be available only on Emacs versions after 24.3.
+This provides a compatibility version for previous versions."
+  (if (fboundp 'default-font-height)
+      (default-font-height)
+    (emojify-face-height 'default)))
+
+(defun emojify-overlays-at (pos &optional sorted)
+  "Return a list of the overlays that contain the character at POS.
+If SORTED is non-nil, then sort them by decreasing priority.
+
+The SORTED argument was introduced in Emacs 24.4, along with the incompatible
+change that overlay priorities can be any Lisp object (earlier they were
+restricted to integer and nil).  This version uses the SORTED argument of
+`overlays-at' on Emacs version 24.4 onwards and manually sorts the overlays by
+priority on lower versions."
+  (if (version< emacs-version "24.4")
+      (let ((overlays-at-pos (overlays-at pos)))
+        (if sorted
+            (seq-sort (lambda (overlay1 overlay2)
+                        (if (and (overlay-get overlay2 'priority)
+                                 (overlay-get overlay1 'priority))
+                            ;; If both overlays have priorities compare them
+                            (< (overlay-get overlay1 'priority)
+                               (overlay-get overlay2 'priority))
+                          ;; Otherwise overlay with nil priority is sorted below
+                          ;; the one with integer value otherwise preserve order
+                          (not (overlay-get overlay1 'priority))))
+                      overlays-at-pos)
+          overlays-at-pos))
+    (overlays-at pos sorted)))
+
+(defun emojify--string-join (strings &optional separator)
+  "Join all STRINGS using SEPARATOR.
+
+This function is available on Emacs v24.4 and higher, it has been
+backported here for compatibility with older Emacsen."
+  (if (fboundp 'string-join)
+      (apply #'string-join (list strings separator))
+    (mapconcat 'identity strings separator)))
+
+
+
+;; Debugging helpers
+
+(define-minor-mode emojify-debug-mode
+  "Enable debugging for emojify-mode.
+
+By default emojify silences any errors during emoji redisplay.  This is done
+since emojis are redisplayed using jit-lock (the same mechanism used for
+font-lock) as such any bugs in the code can cause other important things to
+fail. This also turns on jit-debug-mode so that (e)debugging emojify's redisplay
+functions work."
+  :init-value nil
+  (if emojify-debug-mode
+      (when (fboundp 'jit-lock-debug-mode)
+        (jit-lock-debug-mode +1))
+    (when (fboundp 'jit-lock-debug-mode)
+      (jit-lock-debug-mode -1))))
+
+(defmacro emojify-execute-ignoring-errors-unless-debug (&rest forms)
+  "Execute FORMS ignoring errors unless variable `emojify-debug-mode' is non-nil."
+  (declare (debug t) (indent 0))
+  `(if emojify-debug-mode
+       (progn
+         ,@forms)
+     (ignore-errors
+       ,@forms)))
+
+
+
+;; Utility functions
+
+;; These should be bound dynamically by functions calling
+;; `emojify--inside-rectangle-selection-p' and
+;; `emojify--inside-non-rectangle-selection-p' to region-beginning and
+;; region-end respectively. This is needed mark the original region which is
+;; impossible to get after point moves during processing.
+(defvar emojify-region-beg nil)
+(defvar emojify-region-end nil)
+
+;; This should be bound dynamically to the location of point before emojify's
+;; display loop, this since getting the point after point moves during
+;; processing is impossible
+(defvar emojify-current-point nil)
+
+(defmacro emojify-with-saved-buffer-state (&rest forms)
+  "Execute FORMS saving current buffer state.
+
+This saves point and mark, `match-data' and buffer modification state it also
+inhibits buffer change, point motion hooks."
+  (declare (debug t) (indent 0))
+  `(let ((inhibit-point-motion-hooks t)
+         (emojify-current-point (point))
+         (emojify-region-beg (when (region-active-p) (region-beginning)))
+         (emojify-region-end (when (region-active-p) (region-end))))
+     (with-silent-modifications
+       (save-match-data
+         (save-excursion
+           (save-restriction
+             (widen)
+             ,@forms))))))
+
+(defmacro emojify-do-for-emojis-in-region (beg end &rest forms)
+  "For all emojis between BEG and END, execute the given FORMS.
+
+During the execution `emoji-start' and `emoji-end' are bound to the start
+and end of the emoji for which the form is being executed."
+  (declare (debug t) (indent 2))
+  `(let ((--emojify-loop-current-pos ,beg)
+         (--emojify-loop-end ,end)
+         emoji-start)
+     (while (and (> --emojify-loop-end --emojify-loop-current-pos)
+                 (setq emoji-start (text-property-any --emojify-loop-current-pos --emojify-loop-end 'emojified t)))
+       (let ((emoji-end (+ emoji-start
+                           (length (get-text-property emoji-start 'emojify-text)))))
+         ,@forms
+         (setq --emojify-loop-current-pos emoji-end)))))
+
+(defun emojify-message (format-string &rest args)
+  "Log debugging messages to buffer named 'emojify-log'.
+
+This is a substitute to `message' since using it during redisplay causes errors.
+FORMAT-STRING and ARGS are same as the arguments to `message'."
+  (when emojify-debug-mode
+    (emojify-with-saved-buffer-state
+      (with-current-buffer (get-buffer-create "emojify-log")
+        (goto-char (point-max))
+        (insert (apply #'format format-string args))
+        (insert "\n")))))
+
+(defun emojify--get-relevant-region ()
+  "Try getting region in buffer that completely covers the current window.
+
+This is used instead of directly using `window-start' and `window-end', since
+they return the values corresponding buffer in currently selected window, which
+is incorrect if the buffer where there are called is not actually the buffer
+visible in the selected window."
+  (let* ((window-size (- (window-end) (window-start)))
+         (start (max (- (point) window-size) (point-min)))
+         (end (min (+ (point) window-size) (point-max))))
+    (cons start end)))
+
+(defun emojify-quit-buffer ()
+  "Hide the current buffer.
+There are windows other than the one the current buffer is displayed in quit the
+current window too."
+  (interactive)
+  (if (= (length (window-list)) 1)
+      (bury-buffer)
+    (quit-window)))
+
+(defvar emojify-common-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map "q" #'emojify-quit-buffer)
+    (define-key map "n" #'next-line)
+    (define-key map "p" #'previous-line)
+    (define-key map "r" #'isearch-backward)
+    (define-key map "s" #'isearch-forward)
+    (define-key map ">" #'end-of-buffer)
+    (define-key map "<" #'beginning-of-buffer)
+
+    (dolist (key '("?" "h" "H"))
+      (define-key map key #'describe-mode))
+
+    (dolist (number (number-sequence 0 9))
+      (define-key map (number-to-string number) #'digit-argument))
+
+    map)
+  "Common keybindings available in all special emojify buffers.")
+
+
+
+;; Customizations for control how emojis are displayed
+
+(defgroup emojify nil
+  "Customization options for emojify"
+  :group 'display
+  :prefix "emojify-")
+
+(defcustom emojify-emoji-json
+  (expand-file-name "data/emoji.json"
+                    (cond (load-file-name (file-name-directory load-file-name))
+                          ((locate-library "emojify") (file-name-directory (locate-library "emojify")))
+                          (t default-directory)))
+  "The path to JSON file containing the configuration for displaying emojis."
+  :type 'file
+  :group 'emojify)
+
+(defvar emojify-emoji-set-json
+  (let ((json-array-type 'list)
+        (json-object-type 'hash-table))
+    (json-read-file (expand-file-name "data/emoji-sets.json"
+                                      (cond (load-file-name (file-name-directory load-file-name))
+                                            ((locate-library "emojify") (file-name-directory (locate-library "emojify")))
+                                            (t default-directory))))))
+
+(defcustom emojify-emoji-set "emojione-v2.2.6-22"
+  "The emoji set used to display emojis."
+  :type (append '(radio :tag "Emoji set")
+                (mapcar (lambda (set) (list 'const set))
+                        (ht-keys emojify-emoji-set-json)))
+  :group 'emojify)
+
+(defcustom emojify-emojis-dir
+  (locate-user-emacs-file "emojis")
+  "Path to the directory containing the emoji images."
+  :type 'directory
+  :group 'emojify)
+
+(defcustom emojify-display-style
+  'image
+  "How the emoji's be displayed.
+
+Possible values are
+`image'   - Display emojis using images, this requires images are supported by
+            user's Emacs installation
+`unicode' - Display emojis using unicode characters, this works well on
+            platforms with good emoji fonts.  In this case the emoji text
+            ':wink:' will be substituted with 😉.
+`ascii'   - Display emojis as ascii characters, this is simplest and does not
+            require any external dependencies.  In this cases emoji text like
+            ':wink:' are substituted with ascii equivalents like ';)'"
+  :type '(radio :tag "Emoji display style"
+                (const :tag "Display emojis as images" image)
+                (const :tag "Display emojis as unicode characters" unicode)
+                (const :tag "Display emojis as ascii string" ascii))
+  :group 'emojify)
+
+
+
+;; Customizations to control the enabling of emojify-mode
+
+(defcustom emojify-inhibit-major-modes
+  '(dired-mode
+    doc-view-mode
+    debugger-mode
+    pdf-view-mode
+    image-mode
+    help-mode
+    ibuffer-mode
+    magit-popup-mode
+    magit-diff-mode
+    ert-results-mode
+    compilation-mode
+    proced-mode
+    mu4e-headers-mode)
+  "Major modes where emojify mode should not be enabled."
+  :type '(repeat symbol)
+  :group 'emojify)
+
+(defcustom emojify-inhibit-in-buffer-functions
+  '(emojify-minibuffer-p emojify-helm-buffer-p)
+  "Functions used inhibit emojify-mode in a buffer.
+
+These functions are called with one argument, the buffer where command
+‘emojify-mode’ is about to be enabled, emojify is not enabled if any of the
+functions return a non-nil value."
+  :type 'hook
+  :group 'emojify)
+
+(defvar emojify-inhibit-emojify-in-current-buffer-p nil
+  "Should emojify be inhibited in current buffer.
+
+This is a buffer local variable that can be set to inhibit enabling of
+emojify in a buffer.")
+(make-variable-buffer-local 'emojify-inhibit-emojify-in-current-buffer-p)
+
+(defvar emojify-minibuffer-reading-emojis-p nil
+  "Are we currently reading emojis using minibuffer?")
+
+(defun emojify-ephemeral-buffer-p (buffer)
+  "Determine if BUFFER is an ephemeral/temporary buffer."
+  (and (not (minibufferp))
+       (string-match-p "^ " (buffer-name buffer))))
+
+(defun emojify-inhibit-major-mode-p (buffer)
+  "Determine if user has disabled the `major-mode' enabled for the BUFFER.
+
+Returns non-nil if the buffer's major mode is part of `emojify-inhibit-major-modes'"
+  (with-current-buffer buffer
+    (apply #'derived-mode-p emojify-inhibit-major-modes)))
+
+(defun emojify-helm-buffer-p (buffer)
+  "Determine if the current BUFFER is a helm buffer."
+  (unless emojify-minibuffer-reading-emojis-p
+    (string-match-p "\\*helm" (buffer-name buffer))))
+
+(defun emojify-minibuffer-p (buffer)
+  "Determine if the current BUFFER is a minibuffer."
+  (unless emojify-minibuffer-reading-emojis-p
+    (minibufferp buffer)))
+
+(defun emojify-buffer-p (buffer)
+  "Determine if `emojify-mode' should be enabled for given BUFFER.
+
+`emojify-mode' mode is not enabled in temporary buffers.  Additionally user
+can customize `emojify-inhibit-major-modes' and
+`emojify-inhibit-in-buffer-functions' to disabled emojify in additional buffers."
+  (not (or emojify-inhibit-emojify-in-current-buffer-p
+           (emojify-ephemeral-buffer-p (current-buffer))
+           (emojify-inhibit-major-mode-p (current-buffer))
+           (buffer-base-buffer buffer)
+           (run-hook-with-args-until-success 'emojify-inhibit-in-buffer-functions buffer))))
+
+
+
+;; Customizations to control display of emojis
+
+(defvar emojify-emoji-style-change-hook nil
+  "Hooks run when emoji style changes.")
+
+;;;###autoload
+(defun emojify-set-emoji-styles (styles)
+  "Set the type of emojis that should be displayed.
+
+STYLES is the styles emoji styles that should be used, see `emojify-emoji-styles'"
+  (when (not (listp styles))
+    (setq styles (list styles))
+    (warn "`emojify-emoji-style' has been deprecated use `emojify-emoji-styles' instead!"))
+
+  (setq-default emojify-emoji-styles styles)
+
+  (run-hooks 'emojify-emoji-style-change-hook))
+
+(defcustom emojify-emoji-styles
+  '(ascii unicode github)
+  "The type of emojis that should be displayed.
+
+These can have one of the following values
+
+`ascii'           - Display only ascii emojis for example ';)'
+`unicode'         - Display only unicode emojis for example '😉'
+`github'          - Display only github style emojis for example ':wink:'"
+  :type '(set
+          (const :tag "Display only ascii emojis" ascii)
+          (const :tag "Display only github emojis" github)
+          (const :tag "Display only unicode codepoints" unicode))
+  :set (lambda (_ value) (emojify-set-emoji-styles value))
+  :group 'emojify)
+
+(defcustom emojify-program-contexts
+  '(comments string code)
+  "Contexts where emojis can be displayed in programming modes.
+
+Possible values are
+`comments' - Display emojis in comments
+`string'   - Display emojis in strings
+`code'     - Display emojis in code (this is applicable only for unicode emojis)"
+  :type '(set :tag "Contexts where emojis should be displayed in programming modes"
+              (const :tag "Display emojis in comments" comments)
+              (const :tag "Display emojis in string" string)
+              (const :tag "Display emojis in code" code))
+  :group 'emojify)
+
+(defcustom emojify-inhibit-functions
+  '(emojify-in-org-tags-p emojify-in-org-list-p)
+  "Functions used to determine given emoji should displayed at current point.
+
+These functions are called with 3 arguments, the text to be emojified, the start
+of emoji text and the end of emoji text.  These functions are called with the
+buffer where emojis are going to be displayed selected."
+  :type 'hook
+  :group 'emojify)
+
+(defcustom emojify-composed-text-p t
+  "Should composed text be emojified."
+  :type 'boolean
+  :group 'emojify)
+
+(defcustom emojify-company-tooltips-p t
+  "Should company mode tooltips be emojified."
+  :type 'boolean
+  :group 'emojify)
+
+(defun emojify-in-org-tags-p (match beg _end)
+  "Determine whether the point is on `org-mode' tag.
+
+MATCH, BEG and _END are the text currently matched emoji and the start position
+and end position of emoji text respectively.
+
+Easiest would have to inspect face at point but unfortunately, there is no
+way to guarantee that we run after font-lock"
+  (and (memq major-mode '(org-mode org-agenda-mode))
+       (string-match-p ":[^:]+[:]?" match)
+       (org-at-heading-p)
+       (save-excursion
+         (save-match-data
+           (goto-char beg)
+           (looking-at ":[^:]+:[\s-]*$")))))
+
+(defun emojify-in-org-list-p (text beg &rest ignored)
+  "Determine whether the point is in `org-mode' list.
+
+TEXT is the text which is supposed to rendered a an emoji.  BEG is the beginning
+of the emoji text in the buffer.  The arguments IGNORED are ignored."
+  (and (eq major-mode 'org-mode)
+       (equal text "8)")
+       (equal (org-list-get-item-begin) beg)))
+
+(defun emojify-valid-program-context-p (emoji beg end)
+  "Determine if EMOJI should be displayed for text between BEG and END.
+
+This returns non-nil if the region is valid according to `emojify-program-contexts'"
+  (when emojify-program-contexts
+    (let* ((syntax-beg (syntax-ppss beg))
+           (syntax-end (syntax-ppss end))
+           (context (cond ((and (nth 3 syntax-beg)
+                                (nth 3 syntax-end))
+                           'string)
+                          ((and (nth 4 syntax-beg)
+                                (nth 4 syntax-end))
+                           'comments)
+                          (t 'code))))
+      (and (memql context emojify-program-contexts)
+           (if (equal context 'code)
+               (and (string= (ht-get emoji "style") "unicode")
+                    (memql 'unicode emojify-emoji-styles))
+             t)))))
+
+(defun emojify-inside-org-src-p (point)
+  "Return non-nil if POINT is inside `org-mode' src block.
+
+This is used to inhibit display of emoji's in `org-mode' src blocks
+since our mechanisms do not work in it."
+  (when (eq major-mode 'org-mode)
+    (save-excursion
+      (goto-char point)
+      (eq (org-element-type (org-element-at-point)) 'src-block))))
+
+(defun emojify-looking-at-end-of-list-maybe (point)
+  "Determine if POINT is end of a list.
+
+This is not accurate since it restricts the region to scan to
+the visible area."
+  (let* ((area (emojify--get-relevant-region))
+         (beg (car area))
+         (end (cdr area)))
+    (save-restriction
+      (narrow-to-region beg end)
+      (let ((list-start (ignore-errors (scan-sexps point -1))))
+        (when (and list-start
+                   ;; Ignore the starting brace if it is an emoji
+                   (not (get-text-property list-start 'emojified)))
+          ;; If we got a list start make sure both start and end
+          ;; belong to same string/comment
+          (let ((syntax-beg (syntax-ppss list-start))
+                (syntax-end (syntax-ppss point)))
+            (and list-start
+                 (eq (nth 8 syntax-beg)
+                     (nth 8 syntax-end)))))))))
+
+(defun emojify-valid-ascii-emoji-context-p (beg end)
+  "Determine if the okay to display ascii emoji between BEG and END."
+  ;; The text is at the start of the buffer
+  (and (or (not (char-before beg))
+           ;; 32 space since ?  (? followed by a space) is not readable
+           ;; 34 is "  since?" confuses font-lock
+           ;; 41 is )  since?) (extra paren) confuses most packages
+           (memq (char-syntax (char-before beg))
+                 ;; space
+                 '(32
+                   ;; start/end of string
+                   34
+                   ;; whitespace syntax
+                   ?-
+                   ;; comment start
+                   ?<
+                   ;; comment end, this handles text at start of line immediately
+                   ;; after comment line in a multiline comment
+                   ?>)))
+       ;; The text is at the end of the buffer
+       (or (not (char-after end))
+           (memq (char-syntax (char-after end))
+                 ;; space
+                 '(32
+                   ;; start/end of string
+                   34
+                   ;; whitespace syntax
+                   ?-
+                   ;; punctuation
+                   ?.
+                   ;; closing braces
+                   41
+                   ;; comment end
+                   ?>)))))
+
+
+
+;; Obsolete vars
+
+(define-obsolete-variable-alias 'emojify-emoji-style 'emojify-emoji-styles "0.2")
+(define-obsolete-function-alias 'emojify-set-emoji-style 'emojify-set-emoji-styles "0.2")
+
+
+
+;; Customizations to control the behaviour when point enters emojified text
+
+(defcustom emojify-point-entered-behaviour 'echo
+  "The behaviour when point enters, an emojified text.
+
+It can be one of the following
+`echo'    - Echo the underlying text in the minibuffer
+`uncover' - Display the underlying text while point is on it
+function  - It is called with 2 arguments (the buffer where emoji appears is
+            current during execution)
+            1) starting position of emoji text
+            2) ending position of emoji text
+
+Does nothing if the value is anything else."
+  ;; TODO: Mention custom function
+  :type '(radio :tag "Behaviour when point enters an emoji"
+                (const :tag "Echo the underlying emoji text in the minibuffer" echo)
+                (const :tag "Uncover (undisplay) the underlying emoji text" uncover))
+  :group 'emojify)
+
+(defcustom emojify-reveal-on-isearch t
+  "Should underlying emoji be displayed when point enters emoji while in isearch mode.")
+
+(defcustom emojify-show-help t
+  "If non-nil the underlying text is displayed in a popup when mouse moves over it."
+  :type 'boolean
+  :group 'emojify)
+
+(defun emojify-on-emoji-enter (beginning end)
+  "Executed when point enters emojified text between BEGINNING and END."
+  (cond ((and (eq emojify-point-entered-behaviour 'echo)
+              ;; Do not echo in isearch-mode
+              (not isearch-mode)
+              (not (active-minibuffer-window))
+              (not (current-message)))
+         (message (substring-no-properties (get-text-property beginning 'emojify-text))))
+        ((eq emojify-point-entered-behaviour 'uncover)
+         (put-text-property beginning end 'display nil))
+        ((functionp 'emojify-point-entered-behaviour)
+         (funcall emojify-point-entered-behaviour beginning end)))
+
+  (when (and isearch-mode emojify-reveal-on-isearch)
+    (put-text-property beginning end 'display nil)))
+
+(defun emojify-on-emoji-exit (beginning end)
+  "Executed when point exits emojified text between BEGINNING and END."
+  (put-text-property beginning
+                     end
+                     'display
+                     (get-text-property beginning 'emojify-display)))
+
+(defvar-local emojify--last-emoji-pos nil)
+
+(defun emojify-detect-emoji-entry/exit ()
+  "Detect emoji entry and exit and run appropriate handlers.
+
+This is inspired by `prettify-symbol-mode's logic for
+`prettify-symbols-unprettify-at-point'."
+  (while-no-input
+    (emojify-with-saved-buffer-state
+      (when emojify--last-emoji-pos
+        (emojify-on-emoji-exit (car emojify--last-emoji-pos) (cdr emojify--last-emoji-pos)))
+
+      (when (get-text-property (point) 'emojified)
+        (let* ((text-props (text-properties-at (point)))
+               (buffer (plist-get text-props 'emojify-buffer))
+               (match-beginning (plist-get text-props 'emojify-beginning))
+               (match-end (plist-get text-props 'emojify-end)))
+          (when (eq buffer (current-buffer))
+            (emojify-on-emoji-enter match-beginning match-end)
+            (setq emojify--last-emoji-pos (cons match-beginning match-end))))))))
+
+(defun emojify-help-function (_window _string pos)
+  "Function to get help string to be echoed when point/mouse into the point.
+
+To understand WINDOW, STRING and POS see the function documentation for
+`help-echo' text-property."
+  (when (and emojify-show-help
+             (not isearch-mode)
+             (not (active-minibuffer-window))
+             (not (current-message)))
+    (plist-get (text-properties-at pos) 'emojify-text)))
+
+
+
+;; Core functions and macros
+
+;; Variables related to user emojis
+
+(defcustom emojify-user-emojis nil
+  "User specified custom emojis.
+
+This is an alist where first element of cons is the text to be displayed as
+emoji, while the second element of the cons is an alist containing data about
+the emoji.
+
+The inner alist should have atleast (not all keys are strings)
+
+`name'  - The name of the emoji
+`style' - This should be one of \"github\", \"ascii\" or \"github\"
+          (see `emojify-emoji-styles')
+
+The alist should contain one of (see `emojify-display-style')
+`unicode' - The replacement for the provided emoji for \"unicode\" display style
+`image'   - The replacement for the provided emoji for \"image\" display style.
+            This should be the absolute path to the image
+`ascii'   - The replacement for the provided emoji for \"ascii\" display style
+
+Example -
+The following assumes that custom images are at ~/.emacs.d/emojis/trollface.png and
+~/.emacs.d/emojis/neckbeard.png
+
+'((\":troll:\"     . ((\"name\" . \"Troll\")
+                    (\"image\" . \"~/.emacs.d/emojis/trollface.png\")
+                    (\"style\" . \"github\")))
+  (\":neckbeard:\" . ((\"name\" . \"Neckbeard\")
+                    (\"image\" . \"~/.emacs.d/emojis/neckbeard.png\")
+                    (\"style\" . \"github\"))))")
+
+(defvar emojify--user-emojis nil
+  "User specified custom emojis.")
+
+(defvar emojify--user-emojis-regexp nil
+  "Regexp to match user specified custom emojis.")
+
+;; Variables related to default emojis
+(defvar emojify-emojis nil
+  "Data about the emojis, this contains only the emojis that come with emojify.")
+
+(defvar emojify-regexps nil
+  "List of regexps to match text to be emojified.")
+
+(defvar emojify--completing-candidates-cache nil
+  "Cached values for completing read candidates calculated for `emojify-completing-read'.")
+
+;; Cache for emoji completing read candidates
+(defun emojify--get-completing-read-candidates ()
+  "Get the candidates to be used for `emojify-completing-read'.
+
+The candidates are calculated according to currently active
+`emojify-emoji-styles' and cached"
+  (let ((styles (mapcar #'symbol-name emojify-emoji-styles)))
+    (unless (and emojify--completing-candidates-cache
+                 (equal styles (car emojify--completing-candidates-cache)))
+      (setq emojify--completing-candidates-cache
+            (cons styles
+                  (let ((emojis (ht-create #'equal)))
+                    (emojify-emojis-each (lambda (key value)
+                                           (when (seq-position styles (ht-get value "style"))
+                                             (ht-set! emojis
+                                                      (format "%s - %s (%s)"
+                                                              key
+                                                              (ht-get value "name")
+                                                              (ht-get value "style"))
+                                                      value))))
+                    emojis))))
+    (cdr emojify--completing-candidates-cache)))
+
+(defun emojify-create-emojify-emojis (&optional force)
+  "Create `emojify-emojis' if needed.
+
+The function avoids reading emoji data if it has already been read unless FORCE
+in which case emoji data is re-read."
+  (when (or force (not emojify-emojis))
+    (emojify-set-emoji-data)))
+
+(defun emojify-get-emoji (emoji)
+  "Get data for given EMOJI.
+
+This first looks for the emoji in `emojify--user-emojis',
+and then in `emojify-emojis'."
+  (or (when emojify--user-emojis
+        (ht-get emojify--user-emojis emoji))
+      (ht-get emojify-emojis emoji)))
+
+(defun emojify-emojis-each (function)
+  "Execute FUNCTION for each emoji.
+
+This first runs function for `emojify--user-emojis',
+and then `emojify-emojis'."
+  (when emojify--user-emojis
+    (ht-each function emojify--user-emojis))
+  (ht-each function emojify-emojis))
+
+(defun emojify--verify-user-emojis (emojis)
+  "Verify the EMOJIS in correct user format."
+  (seq-every-p (lambda (emoji)
+                 (and (assoc "name" (cdr emoji))
+                      ;; Make sure style is present is only one of
+                      ;; "unicode", "ascii" and "github".
+                      (assoc "style" (cdr emoji))
+                      (seq-position '("unicode" "ascii" "github")
+                                    (cdr (assoc "style" (cdr emoji))))
+                      (or (assoc "unicode" (cdr emoji))
+                          (assoc "image" (cdr emoji))
+                          (assoc "ascii" (cdr emoji)))))
+               emojis))
+
+(defun emojify-set-emoji-data ()
+  "Read the emoji data for STYLES and set the regexp required to search them."
+  (setq-default emojify-emojis (let ((json-array-type 'list)
+                                     (json-object-type 'hash-table))
+                                 (json-read-file emojify-emoji-json)))
+
+  (let (unicode-emojis ascii-emojis)
+    (ht-each (lambda (emoji data)
+               (when (string= (ht-get data "style") "unicode")
+                 (push emoji unicode-emojis))
+
+               (when (string= (ht-get data "style") "ascii")
+                 (push emoji ascii-emojis)))
+             emojify-emojis)
+
+    ;; Construct emojify-regexps such that github style are searched first
+    ;; followed by unicode and then ascii emojis.
+    (setq emojify-regexps (list ":[[:alnum:]+_-]+:"
+                                (regexp-opt unicode-emojis)
+                                (regexp-opt ascii-emojis))))
+
+  (when emojify-user-emojis
+    (if (emojify--verify-user-emojis emojify-user-emojis)
+        ;; Create entries for user emojis
+        (let ((emoji-pairs (mapcar (lambda (user-emoji)
+                                     (cons (car user-emoji)
+                                           (ht-from-alist (cdr user-emoji))))
+                                   emojify-user-emojis)))
+          (setq emojify--user-emojis (ht-from-alist emoji-pairs))
+          (setq emojify--user-emojis-regexp (regexp-opt (mapcar #'car emoji-pairs))))
+      (message "[emojify] User emojis are not in correct format ignoring them.")))
+
+  (emojify-emojis-each (lambda (emoji data)
+                         ;; Add the emoji text to data, this makes the values
+                         ;; of the `emojify-emojis' standalone containing all
+                         ;; data about the emoji
+                         (ht-set! data "emoji" emoji)
+                         (ht-set! data "custom" (and emojify--user-emojis
+                                                     (ht-get emojify--user-emojis emoji)))))
+
+  ;; Clear completion candidates cache
+  (setq emojify--completing-candidates-cache nil))
+
+(defvar emojify-emoji-keymap
+  (let ((map (make-sparse-keymap)))
+    (define-key map [remap delete-char] #'emojify-delete-emoji-forward)
+    (define-key map [remap delete-forward-char] #'emojify-delete-emoji-forward)
+    (define-key map [remap backward-delete-char] #'emojify-delete-emoji-backward)
+    (define-key map [remap org-delete-backward-char] #'emojify-delete-emoji-backward)
+    (define-key map [remap delete-backward-char] #'emojify-delete-emoji-backward)
+    (define-key map [remap backward-delete-char-untabify] #'emojify-delete-emoji-backward)
+    map))
+
+(defun emojify-image-dir ()
+  "Get the path to directory containing images for currently selected emoji set."
+  (expand-file-name emojify-emoji-set
+                    emojify-emojis-dir))
+
+(defun emojify--get-point-col-and-line (point)
+  "Return a cons of containing the column number and line at POINT."
+  (save-excursion
+    (goto-char point)
+    (cons (current-column) (line-number-at-pos))))
+
+(defun emojify--get-composed-text (point)
+  "Get the text used as composition property at POINT.
+
+This does not check if there is composition property at point the callers should
+make sure the point has a composition property otherwise this function will
+fail."
+  (emojify--string-join (mapcar #'char-to-string
+                                (decode-composition-components (nth 2
+                                                                    (find-composition point
+                                                                                      nil
+                                                                                      nil
+                                                                                      t))))))
+
+(defun emojify--inside-rectangle-selection-p (beg end)
+  "Check if region marked by BEG and END is inside a rectangular selection.
+
+In addition to explicit the parameters BEG and END, calling functions should
+also dynamically bind `emojify-region-beg' and `emojify-region-end' to beginning
+and end of region respectively."
+  (when (and emojify-region-beg
+             (bound-and-true-p rectangle-mark-mode))
+    (let ((rect-beg (emojify--get-point-col-and-line emojify-region-beg))
+          (rect-end (emojify--get-point-col-and-line emojify-region-end))
+          (emoji-start-pos (emojify--get-point-col-and-line beg))
+          (emoji-end-pos (emojify--get-point-col-and-line end)))
+      (or (and (<= (car rect-beg) (car emoji-start-pos))
+               (<= (car emoji-start-pos) (car rect-end))
+               (<= (cdr rect-beg) (cdr emoji-start-pos))
+               (<= (cdr emoji-start-pos) (cdr rect-end)))
+          (and (<= (car rect-beg) (car emoji-end-pos))
+               (<= (car emoji-end-pos) (car rect-end))
+               (<= (cdr rect-beg) (cdr emoji-end-pos))
+               (<= (cdr emoji-end-pos) (cdr rect-end)))))))
+
+(defun emojify--inside-non-rectangle-selection-p (beg end)
+  "Check if region marked by BEG and END is inside a non-regular selection.
+
+In addition to the explicit parameters BEG and END, calling functions should
+also dynamically bind `emojify-region-beg' and `emojify-region-end' to beginning
+and end of region respectively."
+  (when (and emojify-region-beg
+             (region-active-p)
+             (not (bound-and-true-p rectangle-mark-mode)))
+    (or (and (<  emojify-region-beg beg)
+             (<= beg emojify-region-end))
+        (and (<  emojify-region-beg end)
+             (<= end emojify-region-end)))))
+
+(defun emojify--region-background-maybe (beg end)
+  "If the BEG and END falls inside an active region return the region face.
+
+This returns nil if the emojis between BEG and END do not fall in region."
+  ;; `redisplay-highlight-region-function' was not defined in Emacs 24.3
+  (when (and (or (not (boundp 'redisplay-highlight-region-function))
+                 (equal (default-value 'redisplay-highlight-region-function) redisplay-highlight-region-function))
+             (or (emojify--inside-non-rectangle-selection-p beg end)
+                 (emojify--inside-rectangle-selection-p beg end)))
+    (face-background 'region)))
+
+(defun emojify--get-image-background (beg end)
+  "Get the color to be used as background for emoji between BEG and END."
+  ;; We do a separate check for region since `background-color-at-point'
+  ;; does not always detect background color inside regions properly
+  (or (emojify--region-background-maybe beg end)
+      (save-excursion
+        (goto-char beg)
+        (background-color-at-point))))
+
+(defvar emojify--imagemagick-support-cache (ht-create))
+
+(defun emojify--imagemagick-supports-p (format)
+  "Check if imagemagick support given FORMAT.
+
+This function caches the result of the check since the naive check
+
+    (memq format (imagemagick-types))
+
+can be expensive if imagemagick-types returns a large list, this is
+especially problematic since this check is potentially called during
+very redisplay. See https://github.com/iqbalansari/emacs-emojify/issues/41"
+  (when (fboundp 'imagemagick-types)
+    (when (equal (ht-get emojify--imagemagick-support-cache format 'unset) 'unset)
+      (ht-set emojify--imagemagick-support-cache format (memq format (imagemagick-types))))
+    (ht-get emojify--imagemagick-support-cache format)))
+
+(defun emojify--get-image-display (data buffer beg end &optional target)
+  "Get the display text property to display the emoji as an image.
+
+DATA holds the emoji data, _BUFFER is the target buffer where the emoji is to be
+displayed, BEG and END delimit the region where emoji will be displayed.  For
+explanation of TARGET see the documentation of `emojify--get-text-display-props'.
+
+TODO: Perhaps TARGET should be generalized to work with overlays, buffers and
+other different display constructs, for now this works."
+  (when (ht-get data "image")
+    (let* ((image-file (expand-file-name (ht-get data "image")
+                                         (emojify-image-dir)))
+           (image-type (intern (upcase (file-name-extension image-file)))))
+      (when (file-exists-p image-file)
+        (create-image image-file
+                      ;; use imagemagick if available and supports PNG images
+                      ;; (allows resizing images)
+                      (when (emojify--imagemagick-supports-p image-type)
+			'imagemagick)
+                      nil
+                      :ascent 'center
+                      :heuristic-mask t
+                      :background (cond ((equal target 'mode-line)
+                                         (face-background 'mode-line nil 'default))
+                                        (t (emojify--get-image-background beg end)))
+                      ;; no-op if imagemagick is  not available
+                      :height (cond ((bufferp target)
+                                     (with-current-buffer target
+                                       (emojify-default-font-height)))
+                                    ((equal target 'mode-line)
+                                     (emojify-face-height 'mode-line))
+                                    (t (with-current-buffer buffer
+                                         (emojify-default-font-height)))))))))
+
+(defun emojify--get-unicode-display (data &rest ignored)
+  "Get the display text property to display the emoji as an unicode character.
+
+DATA holds the emoji data, rest of the arguments IGNORED are ignored"
+  (let* ((unicode (ht-get data "unicode"))
+         (characters (when unicode
+                       (string-to-vector unicode))))
+    (when (seq-every-p #'char-displayable-p characters)
+      unicode)))
+
+(defun emojify--get-ascii-display (data &rest ignored)
+  "Get the display text property to display the emoji as an ascii characters.
+
+DATA holds the emoji data, rest of the arguments IGNORED are ignored."
+  (ht-get data "ascii"))
+
+(defun emojify--get-text-display-props (emoji buffer beg end &optional target)
+  "Get the display property for an EMOJI.
+
+BUFFER is the buffer currently holding the EMOJI, BEG and END delimit the region
+containing the emoji.  TARGET can either be a buffer object or a special value
+mode-line.  It is used to indicate where EMOJI would be displayed, properties
+like font-height are inherited from TARGET if provided."
+  (funcall (pcase emojify-display-style
+             (`image #'emojify--get-image-display)
+             (`unicode #'emojify--get-unicode-display)
+             (`ascii #'emojify--get-ascii-display))
+           emoji
+           buffer
+           beg
+           end
+           target))
+
+(defun emojify--propertize-text-for-emoji (emoji text buffer start end &optional target)
+  "Display EMOJI for TEXT in BUFFER between START and END.
+
+For explanation of TARGET see the documentation of
+`emojify--get-text-display-props'."
+  (let ((display-prop
+         (emojify--get-text-display-props emoji buffer start end target))
+        (buffer-props (unless target
+                        (list 'emojify-buffer buffer
+                              'emojify-beginning (copy-marker start)
+                              'emojify-end (copy-marker end)
+                              'yank-handler (list nil text)
+                              'keymap emojify-emoji-keymap
+                              'help-echo #'emojify-help-function))))
+    (when display-prop
+      (add-text-properties start
+                           end
+                           (append (list 'emojified t
+                                         'emojify-display display-prop
+                                         'display display-prop
+                                         'emojify-text text)
+                                   buffer-props)))))
+
+(defun emojify-display-emojis-in-region (beg end)
+  "Display emojis in region.
+
+BEG and END are the beginning and end of the region respectively.
+
+Displaying happens in two phases, first search based phase displays actual text
+appearing in buffer as emojis.  In the next phase composed text is searched for
+emojis and displayed.
+
+A minor problem here is that if the text is composed after this display loop it
+would not be displayed as emoji, although in practice the two packages that use
+the composition property `prettify-symbol-mode' and `org-bullets' use the
+font-lock machinery which runs before emojify's display loop, so hopefully this
+should not be a problem 🤞."
+  (emojify-with-saved-buffer-state
+    ;; Make sure we halt if displaying emojis takes more than a second (this
+    ;; might be too large duration)
+    (with-timeout (1 (emojify-message "Failed to display emojis under 1 second"))
+      (seq-doseq (regexp (apply #'append
+                                (when emojify--user-emojis-regexp
+                                  (list emojify--user-emojis-regexp))
+                                (list emojify-regexps)))
+        (let (case-fold-search)
+          (goto-char beg)
+          (while (and (> end (point))
+                      (search-forward-regexp regexp end t))
+            (let* ((match-beginning (match-beginning 0))
+                   (match-end (match-end 0))
+                   (match (match-string-no-properties 0))
+                   (buffer (current-buffer))
+                   (emoji (emojify-get-emoji match))
+                   (force-display (get-text-property match-beginning 'emojify-force-display)))
+              (when (and emoji
+                         (not (or (get-text-property match-beginning 'emojify-inhibit)
+                                  (get-text-property match-end 'emojify-inhibit)))
+                         (memql (intern (ht-get emoji "style"))
+                                emojify-emoji-styles)
+                         ;; Skip displaying this emoji if the its bounds are
+                         ;; already part of an existing emoji. Since the emojis
+                         ;; are searched in descending order of length (see
+                         ;; construction of emojify-regexp in `emojify-set-emoji-data'),
+                         ;; this means larger emojis get precedence over smaller
+                         ;; ones
+                         (not (or (get-text-property match-beginning 'emojified)
+                                  (get-text-property (1- match-end) 'emojified)))
+                         ;; Display unconditionally in non-prog mode
+                         (or (not (derived-mode-p 'prog-mode 'tuareg--prog-mode 'comint-mode 'smalltalk-mode))
+                             ;; In prog mode enable respecting `emojify-program-contexts'
+                             (emojify-valid-program-context-p emoji match-beginning match-end))
+
+                         ;; Display ascii emojis conservatively, since they have potential
+                         ;; to be annoying consider d: in head:, except while executing apropos
+                         ;; emoji
+                         (or (not (string= (ht-get emoji "style") "ascii"))
+                             force-display
+                             (emojify-valid-ascii-emoji-context-p match-beginning match-end))
+
+                         (or force-display
+                             (not (emojify-inside-org-src-p match-beginning)))
+
+                         ;; Inhibit possibly inside a list
+                         ;; 41 is ?) but packages get confused by the extra closing paren :)
+                         ;; TODO Report bugs to such packages
+                         (or force-display
+                             (not (and (eq (char-syntax (char-before match-end)) 41)
+                                       (emojify-looking-at-end-of-list-maybe match-end))))
+
+                         (not (run-hook-with-args-until-success 'emojify-inhibit-functions match match-beginning match-end)))
+                (emojify--propertize-text-for-emoji emoji match buffer match-beginning match-end)))
+            ;; Stop a bit to let `with-timeout' kick in
+            (sit-for 0 t))))
+
+      ;; Loop to emojify composed text
+      (when (and emojify-composed-text-p
+                 ;; Skip this if user has disabled unicode style emojis, since
+                 ;; we display only composed text that are unicode emojis
+                 (memql 'unicode emojify-emoji-styles))
+        (goto-char beg)
+        (let ((compose-start (if (get-text-property beg 'composition)
+                                 ;; Check `beg' first for composition property
+                                 ;; since `next-single-property-change' will
+                                 ;; search for region after `beg' for property
+                                 ;; change thus skipping any composed text at
+                                 ;; `beg'
+                                 beg
+                               (next-single-property-change beg
+                                                            'composition
+                                                            nil
+                                                            end))))
+          (while (and (> end (point))
+                      ;; `end' would be equal to `compose-start' if there was no
+                      ;; text with composition found within `end', this happens
+                      ;; because `next-single-property-change' returns the limit
+                      ;; (and we use `end' as the limit) if no match is found
+                      (> end compose-start)
+                      compose-start)
+            (let* ((match (emojify--get-composed-text compose-start))
+                   (emoji (emojify-get-emoji match))
+                   (compose-end (next-single-property-change compose-start 'composition nil end)))
+              ;; Display only composed text that is unicode char
+              (when (and emoji
+                         (string= (ht-get emoji "style") "unicode"))
+                (emojify--propertize-text-for-emoji emoji match (current-buffer) compose-start compose-end))
+              ;; Setup the next loop
+              (setq compose-start (and compose-end (next-single-property-change compose-end
+                                                                                'composition
+                                                                                nil
+                                                                                end)))
+              (goto-char compose-end))
+            ;; Stop a bit to let `with-timeout' kick in
+            (sit-for 0 t)))))))
+
+(defun emojify-undisplay-emojis-in-region (beg end)
+  "Undisplay the emojis in region.
+
+BEG and END are the beginning and end of the region respectively"
+  (emojify-with-saved-buffer-state
+    (while (< beg end)
+      ;; Get the start of emojified region in the region, the region is marked
+      ;; with text-property `emojified' whose value is `t'. The region is marked
+      ;; so that we do not inadvertently remove display or other properties
+      ;; inserted by other packages.  This might fail too if a package adds any
+      ;; of these properties between an emojified text, but that situation is
+      ;; hopefully very rare and this is better than blindly removing all text
+      ;; properties
+      (let* ((emoji-start (text-property-any beg end 'emojified t))
+             ;; Get the end emojified text, if we could not find the start set
+             ;; emoji-end to region `end', this merely to make looping easier.
+             (emoji-end (or (and emoji-start
+                                 (text-property-not-all emoji-start end 'emojified t))
+                            ;; If the emojified text is at the end of the region
+                            ;; assume that end is the emojified text.
+                            end)))
+        ;; Proceed only if we got start of emojified text
+        (when emoji-start
+          ;; Remove the properties
+          (remove-text-properties emoji-start emoji-end (append (list 'emojified t
+                                                                      'display t
+                                                                      'emojify-display t
+                                                                      'emojify-buffer t
+                                                                      'emojify-text t
+                                                                      'emojify-beginning t
+                                                                      'emojify-end t
+                                                                      'yank-handler t
+                                                                      'keymap t
+                                                                      'help-echo t
+                                                                      'rear-nonsticky t))))
+        ;; Setup the next iteration
+        (setq beg emoji-end)))))
+
+(defun emojify-redisplay-emojis-in-region (&optional beg end)
+  "Redisplay emojis in region between BEG and END.
+
+Redisplay emojis in the visible region if BEG and END are not specified"
+  (let* ((area (emojify--get-relevant-region))
+         (beg (save-excursion
+                (goto-char (or beg (car area)))
+                (line-beginning-position)))
+         (end (save-excursion
+                (goto-char (or end (cdr area)))
+                (line-end-position))))
+    (unless (> (- end beg) 5000)
+      (emojify-execute-ignoring-errors-unless-debug
+        (emojify-undisplay-emojis-in-region beg end)
+        (emojify-display-emojis-in-region beg end)))))
+
+(defun emojify-after-change-extend-region-function (beg end _len)
+  "Extend the region to be emojified.
+
+This simply extends the region to be fontified to the start of line at BEG and
+end of line at END.  _LEN is ignored.
+
+The idea is since an emoji cannot span multiple lines, redisplaying complete
+lines ensures that all the possibly affected emojis are redisplayed."
+  (let ((emojify-jit-lock-start (save-excursion
+                                  (goto-char beg)
+                                  (line-beginning-position)))
+        (emojify-jit-lock-end (save-excursion
+                                (goto-char end)
+                                (line-end-position))))
+    (setq jit-lock-start (if jit-lock-start
+                             (min jit-lock-start emojify-jit-lock-start)
+                           emojify-jit-lock-start))
+    (setq jit-lock-end (if jit-lock-end
+                           (max jit-lock-end emojify-jit-lock-end)
+                         emojify-jit-lock-end))))
+
+
+
+;; Emojify standalone strings
+
+(defun emojify-string (string &optional styles target)
+  "Create a propertized version of STRING, to display emojis belonging STYLES.
+
+TARGET can either be a buffer object or a special value mode-line.  It is used
+to indicate where EMOJI would be displayed, properties like font-height are
+inherited from TARGET if provided.  See also `emojify--get-text-display-props'."
+  (emojify-create-emojify-emojis)
+  (let ((target (or target (current-buffer))))
+    (with-temp-buffer
+      (insert string)
+      (let ((beg (point-min))
+            (end (point-max))
+            (styles (or styles '(unicode))))
+        (seq-doseq (regexp (apply #'append
+                                  (when emojify--user-emojis-regexp
+                                    (list emojify--user-emojis-regexp))
+                                  (list emojify-regexps)))
+          (goto-char beg)
+          (while (and (> end (point))
+                      (search-forward-regexp regexp end t))
+            (let* ((match-beginning (match-beginning 0))
+                   (match-end (match-end 0))
+                   (match (match-string-no-properties 0))
+                   (buffer (current-buffer))
+                   (emoji (emojify-get-emoji match)))
+              (when (and emoji
+                         (not (or (get-text-property match-beginning 'emojify-inhibit)
+                                  (get-text-property match-end 'emojify-inhibit)))
+                         (memql (intern (ht-get emoji "style")) styles)
+                         ;; Skip displaying this emoji if the its bounds are
+                         ;; already part of an existing emoji. Since the emojis
+                         ;; are searched in descending order of length (see
+                         ;; construction of emojify-regexp in `emojify-set-emoji-data'),
+                         ;; this means larger emojis get precedence over smaller
+                         ;; ones
+                         (not (or (get-text-property match-beginning 'emojified)
+                                  (get-text-property (1- match-end) 'emojified))))
+                (emojify--propertize-text-for-emoji emoji match buffer match-beginning match-end target))))))
+      (buffer-string))))
+
+
+
+;; Electric delete functionality
+
+(defun emojify--find-key-binding-ignoring-emojify-keymap (key)
+  "Find the binding for given KEY ignoring the text properties at point.
+
+This is needed since `key-binding' looks up in keymap text property as well
+which is not what we want when falling back in `emojify-delete-emoji'"
+  (let* ((key-binding (or (minor-mode-key-binding key)
+                          (local-key-binding key)
+                          (global-key-binding key))))
+    (when key-binding
+      (or (command-remapping key-binding
+                             nil
+                             (seq-filter (lambda (keymap)
+                                           (not (equal keymap emojify-emoji-keymap)))
+                                         (current-active-maps)))
+          key-binding))))
+
+(defun emojify-delete-emoji (point)
+  "Delete emoji at POINT."
+  (if (get-text-property point 'emojified)
+      (delete-region (get-text-property point 'emojify-beginning)
+                     (get-text-property point 'emojify-end))
+    (call-interactively (emojify--find-key-binding-ignoring-emojify-keymap (this-command-keys)))))
+
+(defun emojify-delete-emoji-forward ()
+  "Delete emoji after point."
+  (interactive)
+  (emojify-delete-emoji (point)))
+
+(defun emojify-delete-emoji-backward ()
+  "Delete emoji before point."
+  (interactive)
+  (emojify-delete-emoji (1- (point))))
+
+;; Integrate with delete-selection-mode
+;; Basically instruct delete-selection mode to override our commands
+;; if the region is active.
+(put 'emojify-delete-emoji-forward 'delete-selection 'supersede)
+(put 'emojify-delete-emoji-backward 'delete-selection 'supersede)
+
+
+
+;; Updating background color on selection
+
+(defun emojify--update-emojis-background-in-region (&optional beg end)
+  "Update the background color for emojis between BEG and END."
+  (when (equal emojify-display-style 'image)
+    (emojify-with-saved-buffer-state
+      (emojify-do-for-emojis-in-region beg end
+        (plist-put (cdr (get-text-property emoji-start 'display))
+                   :background
+                   (emojify--get-image-background emoji-start
+                                                  emoji-end))))))
+
+(defun emojify--update-emojis-background-in-region-starting-at (point)
+  "Update background color for emojis in buffer starting at POINT.
+
+This updates the emojis in the region starting from POINT, the end of region is
+determined by product of `frame-height' and `frame-width' which roughly
+corresponds to the visible area.  POINT usually corresponds to the starting
+position of the window, see
+`emojify-update-visible-emojis-background-after-command' and
+`emojify-update-visible-emojis-background-after-window-scroll'
+
+NOTE: `window-text-height' and `window-text-width' would have been more
+appropriate here however they were not defined in Emacs v24.3 and below."
+  (let* ((region-beginning point)
+         (region-end (min (+ region-beginning (* (frame-height)
+                                                 (frame-width)))
+                          (point-max))))
+    (emojify--update-emojis-background-in-region region-beginning
+                                                 region-end)))
+
+(defun emojify-update-visible-emojis-background-after-command ()
+  "Function added to `post-command-hook' when region is active.
+
+This function updates the backgrounds of the emojis in the region changed after
+the command.
+
+Ideally this would have been good enough to update emoji backgounds after region
+changes, unfortunately this does not work well with commands that scroll the
+window specifically `window-start' and `window-end' (sometimes only `window-end')
+report incorrect values.
+
+To work around this
+`emojify-update-visible-emojis-background-after-window-scroll' is added to
+`window-scroll-functions' to update emojis on window scroll."
+  (while-no-input (emojify--update-emojis-background-in-region-starting-at (window-start))))
+
+(defun emojify-update-visible-emojis-background-after-window-scroll (_window display-start)
+  "Function added to `window-scroll-functions' when region is active.
+
+This function updates the backgrounds of the emojis in the newly displayed area
+of the window.  DISPLAY-START corresponds to the new start of the window."
+  (while-no-input (emojify--update-emojis-background-in-region-starting-at display-start)))
+
+
+
+;; Lazy image downloading
+
+(defcustom emojify-download-emojis-p 'ask
+  "Should emojify download images, if the selected emoji sets are not available.
+
+Emojify can automatically download the images required to display the selected
+emoji set.  By default the user will be asked for confirmation before downloading
+the image.  Set this variable to t to download the images without asking for
+confirmation.  Setting it to nil will disable automatic download of the images.
+
+Please note that emojify will not download the images if Emacs is running in
+non-interactive mode and `emojify-download-emojis-p' is set to `ask'."
+  :type '(radio :tag "Automatically download required images"
+                (const :tag "Ask before downloading" ask)
+                (const :tag "Download without asking" t)
+                (const :tag "Disable automatic downloads" nil))
+  :group 'emojify)
+
+(defvar emojify--refused-image-download-p nil
+  "Used to remember that user has refused to download images in this session.")
+(defvar emojify--download-in-progress-p nil
+  "Is emoji download in progress used to avoid multiple emoji download prompts.")
+
+(defun emojify--emoji-download-emoji-set (data)
+  "Download the emoji images according to DATA."
+  (let ((destination (expand-file-name (make-temp-name "emojify")
+                                       temporary-file-directory)))
+    (url-copy-file (ht-get data "url")
+                   destination)
+    (let ((downloaded-sha (with-temp-buffer
+                            (insert-file-contents-literally destination)
+                            (secure-hash 'sha256 (current-buffer)))))
+      (when (string= downloaded-sha (ht-get data "sha256"))
+        destination))))
+
+(defun emojify--extract-emojis (file)
+  "Extract the tar FILE in emoji directory."
+  (let* ((default-directory emojify-emojis-dir))
+    (with-temp-buffer
+      (insert-file-contents-literally file)
+      (let ((emojify-inhibit-emojify-in-current-buffer-p t))
+        (tar-mode))
+      (tar-untar-buffer))))
+
+(defun emojify-download-emoji (emoji-set)
+  "Download the provided EMOJI-SET."
+  (interactive (list (completing-read "Select the emoji set you want to download: "
+                                      (ht-keys emojify-emoji-set-json))))
+  (let ((emoji-data (ht-get emojify-emoji-set-json emoji-set)))
+    (cond ((not emoji-data)
+           (error "No emoji set named %s found" emoji-set))
+          ((and (file-exists-p (expand-file-name emoji-set emojify-emojis-dir))
+                (called-interactively-p 'any))
+           (message "%s emoji-set already downloaded, not downloading again!" emoji-set))
+          (t
+           (emojify--extract-emojis (emojify--emoji-download-emoji-set (ht-get emojify-emoji-set-json emoji-set)))))))
+
+(defun emojify--confirm-emoji-download ()
+  "Confirm download of emojis.
+
+This takes care of respecting the `emojify-download-emojis-p' and making sure we
+do not prompt the user to download emojis multiple times."
+  (if (not (equal emojify-download-emojis-p 'ask))
+      emojify-download-emojis-p
+    ;; Skip the prompt if we are in noninteractive mode or the user has already
+    ;; denied us permission to download once
+    (unless (or noninteractive emojify--refused-image-download-p)
+      (let ((download-confirmed-p (yes-or-no-p "[emojify] Emoji images not available should I download them now?")))
+        (setq emojify--refused-image-download-p (not download-confirmed-p))
+        download-confirmed-p))))
+
+(defun emojify-download-emoji-maybe ()
+  "Download emoji images if needed."
+  (when (and (equal emojify-display-style 'image)
+             (not (file-exists-p (emojify-image-dir)))
+             (not emojify--refused-image-download-p))
+    (unwind-protect
+        ;; Do not prompt for download if download is in progress
+        (unless emojify--download-in-progress-p
+          (setq emojify--download-in-progress-p t)
+          (if (emojify--confirm-emoji-download)
+              (emojify-download-emoji emojify-emoji-set)
+            (warn "[emojify] Not downloading emoji images for now. Emojis would
+not be displayed since images are not available. If you wish to download emojis,
+run the command `emojify-download-emoji'")))
+      (setq emojify--download-in-progress-p nil))))
+
+(defun emojify-ensure-images ()
+  "Ensure that emoji images are downloaded."
+  (if after-init-time
+      (emojify-download-emoji-maybe)
+    (add-hook 'after-init-hook #'emojify-download-emoji-maybe t)))
+
+
+
+;; Minor mode definitions
+
+(defun emojify-turn-on-emojify-mode ()
+  "Turn on `emojify-mode' in current buffer."
+
+  ;; Calculate emoji data if needed
+  (emojify-create-emojify-emojis)
+
+  (when (emojify-buffer-p (current-buffer))
+    ;; Download images if not available
+    (emojify-ensure-images)
+
+    ;; Install our jit-lock function
+    (jit-lock-register #'emojify-redisplay-emojis-in-region)
+    (add-hook 'jit-lock-after-change-extend-region-functions #'emojify-after-change-extend-region-function t t)
+
+    ;; Handle point entered behaviour
+    (add-hook 'post-command-hook #'emojify-detect-emoji-entry/exit t t)
+
+    ;; Update emoji backgrounds after each command
+    (add-hook 'post-command-hook #'emojify-update-visible-emojis-background-after-command t t)
+
+    ;; Update emoji backgrounds after mark is deactivated, this is needed since
+    ;; deactivation can happen outside the command loop
+    (add-hook 'deactivate-mark-hook #'emojify-update-visible-emojis-background-after-command t t)
+
+    ;; Update emoji backgrounds after when window scrolls
+    (add-hook 'window-scroll-functions #'emojify-update-visible-emojis-background-after-window-scroll t t)
+
+    ;; Redisplay emojis after enabling `prettify-symbol-mode'
+    (add-hook 'prettify-symbols-mode-hook #'emojify-redisplay-emojis-in-region)
+
+    ;; Redisplay visible emojis when emoji style changes
+    (add-hook 'emojify-emoji-style-change-hook #'emojify-redisplay-emojis-in-region)))
+
+(defun emojify-turn-off-emojify-mode ()
+  "Turn off `emojify-mode' in current buffer."
+  ;; Remove currently displayed emojis
+  (save-restriction
+    (widen)
+    (emojify-undisplay-emojis-in-region (point-min) (point-max)))
+
+  ;; Uninstall our jit-lock function
+  (jit-lock-unregister #'emojify-redisplay-emojis-in-region)
+  (remove-hook 'jit-lock-after-change-extend-region-functions #'emojify-after-change-extend-region-function t)
+
+  (remove-hook 'post-command-hook #'emojify-detect-emoji-entry/exit t)
+
+  ;; Disable hooks to update emoji backgrounds
+  (remove-hook 'post-command-hook #'emojify-update-visible-emojis-background-after-command t)
+  (remove-hook 'deactivate-mark-hook #'emojify-update-visible-emojis-background-after-command t)
+  (remove-hook 'window-scroll-functions #'emojify-update-visible-emojis-background-after-window-scroll t)
+
+  ;; Remove hook to redisplay emojis after enabling `prettify-symbol-mode'
+  (remove-hook 'prettify-symbols-mode-hook #'emojify-redisplay-emojis-in-region)
+
+  ;; Remove style change hooks
+  (remove-hook 'emojify-emoji-style-change-hook #'emojify-redisplay-emojis-in-region))
+
+;;;###autoload
+(define-minor-mode emojify-mode
+  "Emojify mode"
+  :init-value nil
+  (if emojify-mode
+      ;; Turn on
+      (emojify-turn-on-emojify-mode)
+    ;; Turn off
+    (emojify-turn-off-emojify-mode)))
+
+;;;###autoload
+(define-globalized-minor-mode global-emojify-mode
+  emojify-mode emojify-mode
+  :init-value nil)
+
+(defadvice set-buffer-multibyte (after emojify-disable-for-unibyte-buffers (&rest ignored))
+  "Disable emojify when unibyte encoding is enabled for a buffer.
+Re-enable it when buffer changes back to multibyte encoding."
+  (ignore-errors
+    (if enable-multibyte-characters
+        (when global-emojify-mode
+          (emojify-mode +1))
+      (emojify-mode -1))))
+
+(ad-activate #'set-buffer-multibyte)
+
+
+
+;; Displaying emojis in mode-line
+
+(defun emojify--emojied-mode-line (format)
+  "Return an emojified version of mode-line FORMAT.
+
+The format is converted to the actual string to be displayed using
+`format-mode-line' and the unicode characters are replaced by images."
+  (if emojify-mode
+      ;; Remove "%e" from format since we keep it as first part of the
+      ;; emojified mode-line, see `emojify-emojify-mode-line'
+      (emojify-string (format-mode-line (delq "%e" format)) nil 'mode-line)
+    (format-mode-line format)))
+
+(defun emojify-mode-line-emojified-p ()
+  "Check if the mode-line is already emojified.
+
+If the `mode-line-format' is of following format
+
+\(\"%e\" (:eval (emojify-emojied-mode-line ... )))
+
+We can assume the mode-line is already emojified."
+  (and (consp mode-line-format)
+       (equal (ignore-errors (cl-caadr mode-line-format))
+              :eval)
+       (equal (ignore-errors (car (cl-cadadr mode-line-format)))
+              'emojify--emojied-mode-line)))
+
+(defun emojify-emojify-mode-line ()
+  "Emojify unicode characters in the mode-line.
+
+This updates `mode-line-format' to a modified version which emojifies the
+mode-line before it is displayed."
+  (unless (emojify-mode-line-emojified-p)
+    (setq mode-line-format `("%e" (:eval
+                                   (emojify--emojied-mode-line ',mode-line-format))))))
+
+(defun emojify-unemojify-mode-line ()
+  "Restore `mode-line-format' to unemojified version.
+
+This basically reverses the effect of `emojify-emojify-mode-line'."
+  (when (emojify-mode-line-emojified-p)
+    (setq mode-line-format (cl-cadadr (cl-cadadr mode-line-format)))))
+
+;;;###autoload
+(define-minor-mode emojify-mode-line-mode
+  "Emojify mode line"
+  :init-value nil
+  (if emojify-mode-line-mode
+      ;; Turn on
+      (emojify-emojify-mode-line)
+    ;; Turn off
+    (emojify-unemojify-mode-line)))
+
+;;;###autoload
+(define-globalized-minor-mode global-emojify-mode-line-mode
+  emojify-mode-line-mode emojify-mode-line-mode
+  :init-value nil)
+
+
+
+;; Searching emojis
+
+(defvar emojify-apropos-buffer-name "*Apropos Emojis*")
+
+(defun emojify-apropos-quit ()
+  "Delete the window displaying Emoji search results."
+  (interactive)
+  (if (= (length (window-list)) 1)
+      (bury-buffer)
+    (quit-window)))
+
+(defun emojify-apropos-copy-emoji ()
+  "Copy the emoji being displayed at current line in apropos results."
+  (interactive)
+  (save-excursion
+    (goto-char (line-beginning-position))
+    (if (not (get-text-property (point) 'emojified))
+        (emojify-user-error "No emoji at point")
+      (kill-new (get-text-property (point) 'emojify-text))
+      (message "Copied emoji (%s) to kill ring!"
+               (get-text-property (point) 'emojify-text)))))
+
+(defun emojify-apropos-describe-emoji ()
+  "Copy the emoji being displayed at current line in apropos results."
+  (interactive)
+  (save-excursion
+    (goto-char (line-beginning-position))
+    (if (not (get-text-property (point) 'emojified))
+        (emojify-user-error "No emoji at point")
+      (emojify-describe-emoji (get-text-property (point) 'emojify-text)))))
+
+(defvar emojify-apropos-mode-map
+  (let ((map (make-sparse-keymap)))
+    (set-keymap-parent map emojify-common-mode-map)
+    (define-key map "c" #'emojify-apropos-copy-emoji)
+    (define-key map "w" #'emojify-apropos-copy-emoji)
+    (define-key map "d" #'emojify-apropos-describe-emoji)
+    (define-key map (kbd "RET") #'emojify-apropos-describe-emoji)
+    (define-key map "g" #'emojify-apropos-emoji)
+    map)
+  "Keymap used in `emojify-apropos-mode'.")
+
+(define-derived-mode emojify-apropos-mode fundamental-mode "Apropos Emojis"
+  "Mode used to display results of `emojify-apropos-emoji'
+
+\\{emojify-apropos-mode-map}"
+  (emojify-mode +1)
+  ;; view mode being a minor mode eats up our bindings avoid it
+  (let (view-read-only)
+    (read-only-mode +1)))
+
+(put 'emojify-apropos-mode 'mode-class 'special)
+
+(defvar emojify--apropos-last-query nil)
+(make-variable-buffer-local 'emojify--apropos-last-query)
+
+(defun emojify-apropos-read-pattern ()
+  "Read apropos pattern with INITIAL-INPUT as the initial input.
+
+Borrowed from apropos.el"
+  (let ((pattern (read-string (concat "Search for emoji (word list or regexp): ")
+                              emojify--apropos-last-query)))
+    (if (string-equal (regexp-quote pattern) pattern)
+        (or (split-string pattern "[ \t]+" t)
+            (emojify-user-error "No word list given"))
+      pattern)))
+
+;;;###autoload
+(defun emojify-apropos-emoji (pattern)
+  "Show Emojis that match PATTERN."
+  (interactive (list (emojify-apropos-read-pattern)))
+
+  (emojify-create-emojify-emojis)
+
+  (let ((in-apropos-buffer-p (equal major-mode 'emojify-apropos-mode))
+        matching-emojis
+        sorted-emojis)
+
+    (unless (listp pattern)
+      (setq pattern (list pattern)))
+
+    ;; Convert the user entered text to a regex to match the emoji name or
+    ;; description
+    (apropos-parse-pattern pattern)
+
+    ;; Collect matching emojis in a list of (list score emoji emoji-data)
+    ;; elements, where score is the proximity of the emoji to given pattern
+    ;; calculated using `apropos-score-str'
+    (emojify-emojis-each (lambda (key value)
+                           (when (or (string-match apropos-regexp key)
+                                     (string-match apropos-regexp (ht-get value "name")))
+                             (push (list (max (apropos-score-str key)
+                                              (apropos-score-str (ht-get value "name")))
+                                         key
+                                         value)
+                                   matching-emojis))))
+
+    ;; Sort the emojis by the proximity score
+    (setq sorted-emojis (mapcar #'cdr
+                                (sort matching-emojis
+                                      (lambda (emoji1 emoji2)
+                                        (> (car emoji1) (car emoji2))))))
+
+    ;; Insert result in apropos buffer and display it
+    (with-current-buffer (get-buffer-create emojify-apropos-buffer-name)
+      (let ((inhibit-read-only t)
+            (query (mapconcat 'identity pattern " ")))
+        (erase-buffer)
+        (insert (propertize "Emojis matching" 'face 'apropos-symbol))
+        (insert (format " - \"%s\"" query))
+        (insert "\n\nUse `c' or `w' to copy emoji on current line\nUse `g' to rerun apropos\n\n")
+        (dolist (emoji sorted-emojis)
+          (insert (format "%s - %s (%s)"
+                          (car emoji)
+                          (ht-get (cadr emoji) "name")
+                          (ht-get (cadr emoji) "style")))
+          (insert "\n"))
+        (goto-char (point-min))
+        (forward-line (1- 6))
+        (emojify-apropos-mode)
+        (setq emojify--apropos-last-query (concat query " "))
+        (setq-local line-spacing 7)))
+
+    (pop-to-buffer (get-buffer emojify-apropos-buffer-name)
+                   (when in-apropos-buffer-p
+                     (cons #'display-buffer-same-window nil)))))
+
+
+
+;; Inserting emojis
+
+(defun emojify--completing-read-minibuffer-setup-hook ()
+  "Enables `emojify-mode' in minbuffer while inserting emojis.
+
+This ensures `emojify' is enabled even when `global-emojify-mode' is not on."
+  (emojify-mode +1))
+
+(defun emojify--completing-read-helm-hook ()
+  "Enables `emojify-mode' in helm buffer.
+
+This ensures `emojify' is enabled in helm buffer displaying completion even when
+`global-emojify-mode' is not on."
+  (with-current-buffer helm-buffer
+    (emojify-mode +1)))
+
+(defun emojify-completing-read (prompt &optional predicate require-match initial-input hist def inherit-input-method)
+  "Read emoji from the user and return the selected emoji.
+
+PROMPT is a string to prompt with, PREDICATE, REQUIRE-MATCH, INITIAL-INPUT,
+HIST, DEF, INHERIT-INPUT-METHOD correspond to the arguments for
+`completing-read' and are passed to ‘completing-read’ without any
+interpretation.
+
+For each possible emoji PREDICATE is called with emoji text and data about the
+emoji as a hash-table, the predate should return nil if it the emoji should
+not be displayed for selection.
+
+For example the following can be used to display only github style emojis for
+selection
+
+\(emojify-completing-read \"Select a Github style emoji: \"
+                         (lambda (emoji data)
+                           (equal (gethash \"style\" data) \"github\")))
+
+This function sets up `ido', `icicles', `helm', `ivy' and vanilla Emacs
+completion UI to display properly emojis."
+  (emojify-create-emojify-emojis)
+  (let* ((emojify-minibuffer-reading-emojis-p t)
+         (line-spacing 7)
+         (completion-ignore-case t)
+         (candidates (emojify--get-completing-read-candidates))
+         ;; Vanilla Emacs completion and Icicles use the completion list mode to display candidates
+         ;; the following makes sure emojify is enabled in the completion list
+         (completion-list-mode-hook (cons #'emojify--completing-read-minibuffer-setup-hook
+                                          completion-list-mode-hook))
+         ;; (Vertical) Ido and Ivy displays candidates in minibuffer this makes sure candidates are emojified
+         ;; when Ido or Ivy are used
+         (minibuffer-setup-hook (cons #'emojify--completing-read-minibuffer-setup-hook
+                                      minibuffer-setup-hook))
+         (helm-after-initialize-hook (cons #'emojify--completing-read-helm-hook
+                                           (bound-and-true-p helm-after-initialize-hook))))
+    (car (split-string (completing-read prompt
+                                        candidates
+                                        predicate
+                                        require-match
+                                        initial-input
+                                        hist
+                                        def
+                                        inherit-input-method)
+                       " "))))
+
+;;;###autoload
+(defun emojify-insert-emoji ()
+  "Interactively prompt for Emojis and insert them in the current buffer.
+
+This respects the `emojify-emoji-styles' variable."
+  (interactive)
+  (insert (emojify-completing-read "Insert Emoji: ")))
+
+
+
+;; Describing emojis
+
+(defvar emojify-help-buffer-name "*Emoji Help*")
+
+(defvar-local emojify-described-emoji nil)
+
+(defun emojify-description-copy-emoji ()
+  "Copy the emoji being displayed at current line in apropos results."
+  (interactive)
+  (save-excursion
+    (kill-new emojify-described-emoji)
+    (message "Copied emoji (%s) to kill ring!" emojify-described-emoji)))
+
+(defvar emojify-description-mode-map
+  (let ((map (make-sparse-keymap)))
+    (set-keymap-parent map emojify-common-mode-map)
+    (define-key map "c" #'emojify-description-copy-emoji)
+    (define-key map "w" #'emojify-description-copy-emoji)
+    map)
+  "Keymap used in `emojify-description-mode'.")
+
+(define-derived-mode emojify-description-mode fundamental-mode "Describe Emoji"
+  "Mode used to display results of description for emojis.
+
+\\{emojify-description-mode-map}"
+  (emojify-mode +1)
+  ;; view mode being a minor mode eats up our bindings avoid it
+  (let (view-read-only)
+    (read-only-mode +1))
+  (goto-address-mode +1))
+
+(put 'emojify-description-mode 'mode-class 'special)
+
+(defun emojify--display-emoji-description-buffer (emoji)
+  "Display description for EMOJI."
+  (with-current-buffer (get-buffer-create emojify-help-buffer-name)
+    (let ((inhibit-read-only t))
+      (erase-buffer)
+      (save-excursion
+        (insert (propertize (ht-get emoji "emoji") 'emojify-inhibit t)
+                " - Displayed as "
+                (propertize (ht-get emoji "emoji") 'emojify-force-display t)
+                "\n\n")
+        (insert (propertize "Name" 'face 'font-lock-keyword-face)
+                ": "
+                (ht-get emoji "name") "\n")
+        (insert (propertize "Style" 'face 'font-lock-keyword-face)
+                ": "
+                (ht-get emoji "style") "\n")
+        (insert (propertize "Image used" 'face 'font-lock-keyword-face)
+                ": "
+                (expand-file-name (ht-get emoji "image")
+                                  (emojify-image-dir))
+                "\n")
+        (when (and (not (string= (ht-get emoji "style") "unicode"))
+                   (ht-get emoji "unicode"))
+          (insert (propertize "Unicode representation"
+                              'face 'font-lock-keyword-face)
+                  ": "
+                  (propertize (ht-get emoji "unicode") 'emojify-inhibit t)
+                  "\n"))
+        (when (and (not (string= (ht-get emoji "style") "ascii"))
+                   (ht-get emoji "ascii"))
+          (insert (propertize "Ascii representation"
+                              'face 'font-lock-keyword-face)
+                  ": "
+                  (propertize (ht-get emoji "ascii") 'emojify-inhibit t)
+                  "\n"))
+        (insert (propertize "User defined"
+                            'face 'font-lock-keyword-face)
+                ": "
+                (if (ht-get emoji "custom") "Yes" "No")
+                "\n")
+        (unless (ht-get emoji "custom")
+          (when (or (ht-get emoji "unicode")
+                    (string= (ht-get emoji "style") "unicode"))
+            (insert (propertize "Unicode Consortium" 'face 'font-lock-keyword-face)
+                    ": "
+                    (concat "http://www.unicode.org/emoji/charts-beta/full-emoji-list.html#"
+                            (string-join (mapcar (apply-partially #'format "%x")
+                                                 (string-to-list (or (ht-get emoji "unicode")
+                                                                     (ht-get emoji "emoji"))))
+                                         "_"))
+                    "\n"))
+          (insert (propertize "Emojipedia" 'face 'font-lock-keyword-face)
+                  ": "
+                  (let* ((tone-stripped (replace-regexp-in-string "- *[Tt]one *\\([0-9]+\\)$"
+                                                                  "- type \\1"
+                                                                  (ht-get emoji "name")))
+                         (non-alphanumeric-stripped (replace-regexp-in-string "[^0-9a-zA-Z]"
+                                                                              " "
+                                                                              tone-stripped))
+                         (words (split-string non-alphanumeric-stripped " " t " ")))
+                    (concat "http://emojipedia.org/"
+                            (downcase (emojify--string-join words "-"))))
+                  "\n"))))
+    (emojify-description-mode)
+    (setq emojify-described-emoji (ht-get emoji "emoji")))
+  (display-buffer (get-buffer emojify-help-buffer-name))
+  (get-buffer emojify-help-buffer-name))
+
+(defun emojify-describe-emoji (emoji-text)
+  "Display description for EMOJI-TEXT."
+  (interactive (list (emojify-completing-read "Describe Emoji: ")))
+  (if (emojify-get-emoji emoji-text)
+      (emojify--display-emoji-description-buffer (emojify-get-emoji emoji-text))
+    (emojify-user-error "No emoji found for '%s'" emoji-text)))
+
+(defun emojify-describe-emoji-at-point ()
+  "Display help for EMOJI displayed at point."
+  (interactive)
+  (if (not (get-text-property (point) 'emojified))
+      (emojify-user-error "No emoji at point!")
+    (emojify--display-emoji-description-buffer (emojify-get-emoji (get-text-property (point) 'emojify-text)))))
+
+
+
+;; Listing emojis
+
+(defun emojify-list-copy-emoji ()
+  "Copy the emoji being displayed at current line in apropos results."
+  (interactive)
+  (save-excursion
+    (let ((emoji (get-text-property (point) 'tabulated-list-id)))
+      (if (not emoji)
+          (emojify-user-error "No emoji at point")
+        (kill-new emoji)
+        (message "Copied emoji (%s) to kill ring!" emoji)))))
+
+(defun emojify-list-describe-emoji ()
+  "Copy the emoji being displayed at current line in apropos results."
+  (interactive)
+  (save-excursion
+    (let ((emoji (get-text-property (point) 'tabulated-list-id)))
+      (if (not emoji)
+          (emojify-user-error "No emoji at point")
+        (emojify-describe-emoji emoji)))))
+
+(defvar-local emojify-list--emojis-displayed nil
+  "Record that emojis have been successfully displayed in the current buffer.
+
+`emojify-list-emojis' checks to this decide if it should print the entries
+again.")
+
+(defun emojify-list-force-refresh ()
+  "Force emoji list to be refreshed."
+  (interactive)
+  (setq emojify-list--emojis-displayed nil)
+  (emojify-list-emojis))
+
+(defvar emojify-list-mode-map
+  (let ((map (make-sparse-keymap)))
+    (set-keymap-parent map emojify-common-mode-map)
+    (define-key map "c" #'emojify-list-copy-emoji)
+    (define-key map "w" #'emojify-list-copy-emoji)
+    (define-key map "d" #'emojify-list-describe-emoji)
+    (define-key map "g" #'emojify-list-force-refresh)
+    (define-key map (kbd "RET") #'emojify-list-describe-emoji)
+    map)
+  "Keymap used in `emojify-list-mode'.")
+
+(defun emojify-list-printer (id cols)
+  "Printer used to print the emoji rows in tabulated list.
+
+See `tabulated-list-print-entry' to understand the arguments ID and COLS."
+  (let ((beg (point))
+        (padding (max tabulated-list-padding 0))
+        (inhibit-read-only t))
+    (when (> tabulated-list-padding 0)
+      (insert (make-string padding ?\s)))
+
+    (tabulated-list-print-col 0
+                              (propertize (aref cols 0) 'emojify-inhibit t)
+                              (current-column))
+
+    ;; Inhibit display of second column ("Text") as emoji
+    (tabulated-list-print-col 1
+                              (propertize (aref cols 1) 'emojify-inhibit t)
+                              (current-column))
+
+    ;; The type of this emoji
+    (tabulated-list-print-col 2
+                              (aref cols 2)
+                              (current-column))
+
+    ;; Is this a custom emoji
+    (tabulated-list-print-col 3
+                              (aref cols 3)
+                              (current-column))
+
+    ;; Force display of last column ("Display") as emoji
+    (tabulated-list-print-col 4
+                              (propertize (aref cols 4) 'emojify-force-display t)
+                              (current-column))
+
+    (insert ?\n)
+    (add-text-properties beg
+                         (point)
+                         `(tabulated-list-id ,id tabulated-list-entry ,cols))
+
+    (message "Listing emojis (%d of %d) ..." (1- (line-number-at-pos)) (aref cols 5))))
+
+(defun emojify-list-entries ()
+  "Return entries to display in tabulated list."
+  (emojify-create-emojify-emojis)
+
+  (let (entries count)
+    (emojify-emojis-each (lambda (emoji data)
+                           (push (list emoji (vector (ht-get data "name")
+                                                     emoji
+                                                     (ht-get data "style")
+                                                     (if (ht-get data "custom") "Yes" "No")
+                                                     emoji))
+                                 entries)))
+
+    (setq count (length entries))
+
+    (mapcar (lambda (entry)
+              (list (car entry) (vconcat (cadr entry) (vector count))))
+            entries)))
+
+(define-derived-mode emojify-list-mode tabulated-list-mode "Emoji-List"
+  "Major mode for listing emojis.
+\\{emojify-list-mode-map}"
+  (setq line-spacing 7
+        tabulated-list-format [("Name" 30 t)
+                               ("Text" 20 t)
+                               ("Style" 10 t)
+                               ("Custom" 10 t)
+                               ("Display" 20 nil)]
+        tabulated-list-sort-key (cons "Name" nil)
+        tabulated-list-padding 2
+        tabulated-list-entries #'emojify-list-entries
+        tabulated-list-printer #'emojify-list-printer)
+  (tabulated-list-init-header))
+
+(defun emojify-list-emojis ()
+  "List emojis in a tabulated view."
+  (interactive)
+  (let ((buffer (get-buffer-create "*Emojis*")))
+    (with-current-buffer buffer
+      (unless emojify-list--emojis-displayed
+        (emojify-list-mode)
+        (tabulated-list-print)
+        (setq emojify-list--emojis-displayed t))
+      (pop-to-buffer buffer))))
+
+
+
+;; Integration with company mode
+
+(defadvice company-pseudo-tooltip-unhide (after emojify-display-emojis-in-company-tooltip (&rest ignored))
+  "Advice to display emojis in company mode tooltips.
+
+This function does two things, first it adds text properties to the completion
+tooltip to make it display the emojis, secondly it makes company always render
+the completion tooltip using `after-string' overlay property rather than
+`display' text property.
+
+The second step is needed because emojify displays the emojis using `display'
+text property, similarly company-mode in some cases uses `display' overlay
+property to render its pop, this results into a `display' property inside
+`display' property, however Emacs ignores recursive display text property.
+Using `after-string' works as well as `display' while allowing the emojis to be
+displayed."
+  (when (and emojify-mode
+             emojify-company-tooltips-p
+             (overlayp (bound-and-true-p company-pseudo-tooltip-overlay)))
+    (let* ((ov company-pseudo-tooltip-overlay)
+           (disp (or (overlay-get ov 'display)
+                     (overlay-get ov 'after-string)))
+           (emojified-display (when disp
+                                (emojify-string disp)))
+           (emojified-p (when emojified-display
+                          (text-property-any 0 (1- (length emojified-display))
+                                             'emojified t
+                                             emojified-display))))
+      ;; Do not switch to after-string if menu is not emojified
+      (when (and disp emojified-p)
+        (overlay-put ov 'after-string nil)
+        (overlay-put ov 'display (propertize " " 'invisible t))
+        (overlay-put ov 'after-string emojified-display)))))
+
+(ad-activate #'company-pseudo-tooltip-unhide)
+
+
+
+;; Integration with some miscellaneous functionality
+
+(defadvice mouse--drag-set-mark-and-point (after emojify-update-emoji-background (&rest ignored))
+  "Advice to update emoji backgrounds after selection is changed using mouse.
+
+Currently there are no hooks run after mouse movements, as such the emoji
+backgrounds are updated only after the mouse button is released.  This advices
+`mouse--drag-set-mark-and-point' which is run after selection changes to trigger
+an update of emoji backgrounds.  Not the cleanest but the only way I can think of."
+  (when emojify-mode
+    (emojify-update-visible-emojis-background-after-command)))
+
+(ad-activate #'mouse--drag-set-mark-and-point)
+
+(defadvice text-scale-increase (after emojify-resize-emojis (&rest ignored))
+  "Advice `text-scale-increase' to resize emojis on text resize."
+  (when emojify-mode
+    (let ((new-font-height (emojify-default-font-height)))
+      (emojify-do-for-emojis-in-region (point-min) (point-max)
+        (plist-put (cdr (get-text-property emoji-start 'display))
+                   :height
+                   new-font-height)))))
+
+(ad-activate #'text-scale-increase)
+
+
+
+(provide 'emojify)
+;;; emojify.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/emojify-20180611.838/emojify.elc b/configs/shared/emacs/.emacs.d/elpa/emojify-20180611.838/emojify.elc
new file mode 100644
index 0000000000..800c145251
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/emojify-20180611.838/emojify.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/engine-mode-20180401.946/engine-mode-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/engine-mode-20180401.946/engine-mode-autoloads.el
new file mode 100644
index 0000000000..19e2417cce
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/engine-mode-20180401.946/engine-mode-autoloads.el
@@ -0,0 +1,71 @@
+;;; engine-mode-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "engine-mode" "engine-mode.el" (23377 60993
+;;;;;;  371469 298000))
+;;; Generated autoloads from engine-mode.el
+
+(defvar engine-mode nil "\
+Non-nil if Engine mode is enabled.
+See the `engine-mode' command
+for a description of this minor mode.")
+
+(custom-autoload 'engine-mode "engine-mode" nil)
+
+(autoload 'engine-mode "engine-mode" "\
+Minor mode for defining and querying search engines through Emacs.
+
+\\{engine-mode-map}
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'defengine "engine-mode" "\
+Define a custom search engine.
+
+`engine-name' is a symbol naming the engine.
+`search-engine-url' is the url to be queried, with a \"%s\"
+standing in for the search term.
+The optional keyword argument `docstring' assigns a docstring to
+the generated function. A reasonably sensible docstring will be
+generated if a custom one isn't provided.
+The optional keyword argument `browser` assigns the browser
+function to be used when opening the URL.
+The optional keyword argument `term-transformation-hook' is a
+function that will be applied to the search term before it's
+substituted into `search-engine-url'. For example, if we wanted
+to always upcase our search terms, we might use:
+
+\(defengine duckduckgo
+  \"https://duckduckgo.com/?q=%s\"
+  :term-transformation-hook 'upcase)
+
+In this case, searching for \"foobar\" will hit the url
+\"https://duckduckgo.com/?q=FOOBAR\".
+
+The optional keyword argument `keybinding' is a string describing
+the key to bind the new function.
+
+Keybindings are in the `engine-mode-map', so they're prefixed.
+
+For example, to search Wikipedia, use:
+
+  (defengine wikipedia
+    \"http://www.wikipedia.org/search-redirect.php?language=en&go=Go&search=%s\"
+    :keybinding \"w\"
+    :docstring \"Search Wikipedia!\")
+
+Hitting \"C-x / w\" will be bound to the newly-defined
+`engine/search-wikipedia' function.
+
+\(fn ENGINE-NAME SEARCH-ENGINE-URL &key KEYBINDING DOCSTRING (BROWSER \\='engine/browser-function) (TERM-TRANSFORMATION-HOOK \\='identity))" nil t)
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; engine-mode-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/engine-mode-20180401.946/engine-mode-pkg.el b/configs/shared/emacs/.emacs.d/elpa/engine-mode-20180401.946/engine-mode-pkg.el
new file mode 100644
index 0000000000..62733bca4d
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/engine-mode-20180401.946/engine-mode-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "engine-mode" "20180401.946" "Define and query search engines from within Emacs." '((cl-lib "0.5")))
diff --git a/configs/shared/emacs/.emacs.d/elpa/engine-mode-20180401.946/engine-mode.el b/configs/shared/emacs/.emacs.d/elpa/engine-mode-20180401.946/engine-mode.el
new file mode 100644
index 0000000000..caf724cf0d
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/engine-mode-20180401.946/engine-mode.el
@@ -0,0 +1,178 @@
+;;; engine-mode.el --- Define and query search engines from within Emacs.
+
+;; Author: Harry R. Schwartz <hello@harryrschwartz.com>
+;; Version: 2.1.0
+;; Package-Version: 20180401.946
+;; URL: https://github.com/hrs/engine-mode
+;; Package-Requires: ((cl-lib "0.5"))
+
+;; This file is NOT part of GNU Emacs.
+
+;;; Commentary:
+
+;; `engine-mode' is a global minor mode for Emacs. It enables you to
+;; easily define search engines, bind them to keybindings, and query
+;; them from the comfort of your editor.
+
+;; For example, suppose we want to be able to easily search GitHub:
+
+;; (defengine github
+;;   "https://github.com/search?ref=simplesearch&q=%s")
+
+;; This defines an interactive function `engine/search-github'. When
+;; executed it will take the selected region (or prompt for input, if
+;; no region is selected) and search GitHub for it, displaying the
+;; results in your default browser.
+
+;; The `defengine' macro can also take an optional key combination,
+;; prefixed with "C-x /":
+
+;; (defengine duckduckgo
+;;   "https://duckduckgo.com/?q=%s"
+;;   :keybinding "d")
+
+;; `C-x / d' is now bound to the new function
+;; engine/search-duckduckgo'! Nifty.
+
+;;; License:
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Code:
+(eval-when-compile (require 'cl-macs))
+
+(defcustom engine/keybinding-prefix "C-x /"
+  "The default engine-mode keybindings prefix."
+  :group 'engine-mode
+  :type 'string)
+
+(define-prefix-command 'engine-mode-prefixed-map)
+(defvar engine-mode-prefixed-map)
+
+(defvar engine-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd engine/keybinding-prefix) engine-mode-prefixed-map)
+    map)
+  "Keymap for `engine-mode'.")
+
+;;;###autoload
+(define-minor-mode engine-mode
+  "Minor mode for defining and querying search engines through Emacs.
+
+\\{engine-mode-map}"
+  :global t
+  :keymap engine-mode-map)
+
+(defun engine/set-keymap-prefix (prefix-key)
+  "Bind the engine-mode keymap to a new prefix.
+For example, to use \"C-c s\" instead of the default \"C-x /\":
+
+\(engine/set-keymap-prefix (kbd \"C-c s\"))"
+  (define-key engine-mode-map (kbd engine/keybinding-prefix) nil)
+  (define-key engine-mode-map prefix-key engine-mode-prefixed-map))
+
+(defcustom engine/browser-function nil
+  "The default browser function used when opening a URL in an engine.
+Defaults to `nil' which means to go with `browse-url-browser-function'."
+  :group 'engine-mode
+  :type 'symbol)
+
+(defun engine/search-prompt (engine-name default-word)
+  (if (string= default-word "")
+      (format "Search %s: " (capitalize engine-name))
+    (format "Search %s (%s): " (capitalize engine-name) default-word)))
+
+(defun engine/prompted-search-term (engine-name)
+  (let ((current-word (or (thing-at-point 'symbol) "")))
+    (read-string (engine/search-prompt engine-name current-word)
+     nil nil current-word)))
+
+(defun engine/get-query (engine-name)
+  "Return the selected region (if any) or prompt the user for a query."
+  (if (use-region-p)
+      (buffer-substring (region-beginning) (region-end))
+    (engine/prompted-search-term engine-name)))
+
+(defun engine/execute-search (search-engine-url browser-function search-term)
+  "Display the results of the query."
+  (interactive)
+  (let ((browse-url-browser-function (or browser-function
+                                         browse-url-browser-function)))
+    (browse-url
+     (format-spec search-engine-url
+                  (format-spec-make ?s (url-hexify-string search-term))))))
+
+(defun engine/function-name (engine-name)
+  (intern (concat "engine/search-" (downcase (symbol-name engine-name)))))
+
+(defun engine/docstring (engine-name)
+  (concat "Search "
+          (capitalize (symbol-name engine-name))
+          " for the selected text. Prompt for input if none is selected."))
+
+(defun engine/bind-key (engine-name keybinding)
+  (when keybinding
+    `(define-key engine-mode-prefixed-map ,keybinding
+       (quote ,(engine/function-name engine-name)))))
+
+;;;###autoload
+(cl-defmacro defengine (engine-name search-engine-url &key keybinding docstring (browser 'engine/browser-function) (term-transformation-hook 'identity))
+  "Define a custom search engine.
+
+`engine-name' is a symbol naming the engine.
+`search-engine-url' is the url to be queried, with a \"%s\"
+standing in for the search term.
+The optional keyword argument `docstring' assigns a docstring to
+the generated function. A reasonably sensible docstring will be
+generated if a custom one isn't provided.
+The optional keyword argument `browser` assigns the browser
+function to be used when opening the URL.
+The optional keyword argument `term-transformation-hook' is a
+function that will be applied to the search term before it's
+substituted into `search-engine-url'. For example, if we wanted
+to always upcase our search terms, we might use:
+
+\(defengine duckduckgo
+  \"https://duckduckgo.com/?q=%s\"
+  :term-transformation-hook 'upcase)
+
+In this case, searching for \"foobar\" will hit the url
+\"https://duckduckgo.com/?q=FOOBAR\".
+
+The optional keyword argument `keybinding' is a string describing
+the key to bind the new function.
+
+Keybindings are in the `engine-mode-map', so they're prefixed.
+
+For example, to search Wikipedia, use:
+
+  (defengine wikipedia
+    \"http://www.wikipedia.org/search-redirect.php?language=en&go=Go&search=%s\"
+    :keybinding \"w\"
+    :docstring \"Search Wikipedia!\")
+
+Hitting \"C-x / w\" will be bound to the newly-defined
+`engine/search-wikipedia' function."
+
+  (cl-assert (symbolp engine-name))
+  `(prog1
+     (defun ,(engine/function-name engine-name) (search-term)
+       ,(or docstring (engine/docstring engine-name))
+       (interactive
+        (list (engine/get-query ,(symbol-name engine-name))))
+       (engine/execute-search ,search-engine-url ,browser (,term-transformation-hook search-term)))
+     ,(engine/bind-key engine-name keybinding)))
+
+(provide 'engine-mode)
+;;; engine-mode.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/engine-mode-20180401.946/engine-mode.elc b/configs/shared/emacs/.emacs.d/elpa/engine-mode-20180401.946/engine-mode.elc
new file mode 100644
index 0000000000..229b2d317f
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/engine-mode-20180401.946/engine-mode.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/epl-20180205.1249/epl-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/epl-20180205.1249/epl-autoloads.el
new file mode 100644
index 0000000000..15482bbcf7
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/epl-20180205.1249/epl-autoloads.el
@@ -0,0 +1,15 @@
+;;; epl-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil nil ("epl.el") (23377 60991 659708 774000))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; epl-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/epl-20180205.1249/epl-pkg.el b/configs/shared/emacs/.emacs.d/elpa/epl-20180205.1249/epl-pkg.el
new file mode 100644
index 0000000000..2684556723
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/epl-20180205.1249/epl-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "epl" "20180205.1249" "Emacs Package Library" '((cl-lib "0.3")))
diff --git a/configs/shared/emacs/.emacs.d/elpa/epl-20180205.1249/epl.el b/configs/shared/emacs/.emacs.d/elpa/epl-20180205.1249/epl.el
new file mode 100644
index 0000000000..918ec466ab
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/epl-20180205.1249/epl.el
@@ -0,0 +1,711 @@
+;;; epl.el --- Emacs Package Library -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2013-2015 Sebastian Wiesner
+;; Copyright (C) 1985-1986, 1992, 1994-1995, 1999-2015 Free Software
+
+;; Author: Sebastian Wiesner <swiesner@lunaryorn.com>
+;; Maintainer: Johan Andersson <johan.rejeep@gmail.com>
+;;     Sebastian Wiesner <swiesner@lunaryorn.com>
+;; Version: 0.10-cvs
+;; Package-Version: 20180205.1249
+;; Package-Requires: ((cl-lib "0.3"))
+;; Keywords: convenience
+;; URL: http://github.com/cask/epl
+
+;; This file is NOT part of GNU Emacs.
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; A package management library for Emacs, based on package.el.
+
+;; The purpose of this library is to wrap all the quirks and hassle of
+;; package.el into a sane API.
+
+;; The following functions comprise the public interface of this library:
+
+;;; Package directory selection
+
+;; `epl-package-dir' gets the directory of packages.
+
+;; `epl-default-package-dir' gets the default package directory.
+
+;; `epl-change-package-dir' changes the directory of packages.
+
+;;; Package system management
+
+;; `epl-initialize' initializes the package system and activates all
+;; packages.
+
+;; `epl-reset' resets the package system.
+
+;; `epl-refresh' refreshes all package archives.
+
+;; `epl-add-archive' adds a new package archive.
+
+;;; Package objects
+
+;; Struct `epl-requirement' describes a requirement of a package with `name' and
+;; `version' slots.
+
+;; `epl-requirement-version-string' gets a requirement version as string.
+
+;; Struct `epl-package' describes an installed or installable package with a
+;; `name' and some internal `description'.
+
+;; `epl-package-version' gets the version of a package.
+
+;; `epl-package-version-string' gets the version of a package as string.
+
+;; `epl-package-summary' gets the summary of a package.
+
+;; `epl-package-requirements' gets the requirements of a package.
+
+;; `epl-package-directory' gets the installation directory of a package.
+
+;; `epl-package-from-buffer' creates a package object for the package contained
+;; in the current buffer.
+
+;; `epl-package-from-file' creates a package object for a package file, either
+;; plain lisp or tarball.
+
+;; `epl-package-from-descriptor-file' creates a package object for a package
+;; description (i.e. *-pkg.el) file.
+
+;;; Package database access
+
+;; `epl-package-installed-p' determines whether a package is installed, either
+;; built-in or explicitly installed.
+
+;; `epl-package-outdated-p' determines whether a package is outdated, that is,
+;; whether a package with a higher version number is available.
+
+;; `epl-built-in-packages', `epl-installed-packages', `epl-outdated-packages'
+;; and `epl-available-packages' get all packages built-in, installed, outdated,
+;; or available for installation respectively.
+
+;; `epl-find-built-in-package', `epl-find-installed-packages' and
+;; `epl-find-available-packages' find built-in, installed and available packages
+;; by name.
+
+;; `epl-find-upgrades' finds all upgradable packages.
+
+;; `epl-built-in-p' return true if package is built-in to Emacs.
+
+;;; Package operations
+
+;; `epl-install-file' installs a package file.
+
+;; `epl-package-install' installs a package.
+
+;; `epl-package-delete' deletes a package.
+
+;; `epl-upgrade' upgrades packages.
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'package)
+
+
+(unless (fboundp #'define-error)
+  ;; `define-error' for 24.3 and earlier, copied from subr.el
+  (defun define-error (name message &optional parent)
+    "Define NAME as a new error signal.
+MESSAGE is a string that will be output to the echo area if such an error
+is signaled without being caught by a `condition-case'.
+PARENT is either a signal or a list of signals from which it inherits.
+Defaults to `error'."
+    (unless parent (setq parent 'error))
+    (let ((conditions
+           (if (consp parent)
+               (apply #'append
+                      (mapcar (lambda (parent)
+                                (cons parent
+                                      (or (get parent 'error-conditions)
+                                          (error "Unknown signal `%s'" parent))))
+                              parent))
+             (cons parent (get parent 'error-conditions)))))
+      (put name 'error-conditions
+           (delete-dups (copy-sequence (cons name conditions))))
+      (when message (put name 'error-message message)))))
+
+(defsubst epl--package-desc-p (package)
+  "Whether PACKAGE is a `package-desc' object.
+
+Like `package-desc-p', but return nil, if `package-desc-p' is not
+defined as function."
+  (and (fboundp 'package-desc-p) (package-desc-p package)))
+
+
+;;; EPL errors
+(define-error 'epl-error "EPL error")
+
+(define-error 'epl-invalid-package "Invalid EPL package" 'epl-error)
+
+(define-error 'epl-invalid-package-file "Invalid EPL package file"
+  'epl-invalid-package)
+
+
+;;; Package directory
+(defun epl-package-dir ()
+  "Get the directory of packages."
+  package-user-dir)
+
+(defun epl-default-package-dir ()
+  "Get the default directory of packages."
+  (eval (car (get 'package-user-dir 'standard-value))))
+
+(defun epl-change-package-dir (directory)
+  "Change the directory of packages to DIRECTORY."
+  (setq package-user-dir directory)
+  (epl-initialize))
+
+
+;;; Package system management
+(defvar epl--load-path-before-initialize nil
+  "Remember the load path for `epl-reset'.")
+
+(defun epl-initialize (&optional no-activate)
+  "Load Emacs Lisp packages and activate them.
+
+With NO-ACTIVATE non-nil, do not activate packages."
+  (setq epl--load-path-before-initialize load-path)
+  (package-initialize no-activate))
+
+(defalias 'epl-refresh 'package-refresh-contents)
+
+(defun epl-add-archive (name url)
+  "Add a package archive with NAME and URL."
+  (add-to-list 'package-archives (cons name url)))
+
+(defun epl-reset ()
+  "Reset the package system.
+
+Clear the list of installed and available packages, the list of
+package archives and reset the package directory."
+  (setq package-alist nil
+        package-archives nil
+        package-archive-contents nil
+        load-path epl--load-path-before-initialize)
+  (when (boundp 'package-obsolete-alist) ; Legacy package.el
+    (setq package-obsolete-alist nil))
+  (epl-change-package-dir (epl-default-package-dir)))
+
+
+;;; Package structures
+(cl-defstruct (epl-requirement
+               (:constructor epl-requirement-create))
+  "Structure describing a requirement.
+
+Slots:
+
+`name' The name of the required package, as symbol.
+
+`version' The version of the required package, as version list."
+  name
+  version)
+
+(defun epl-requirement-version-string (requirement)
+  "The version of a REQUIREMENT, as string."
+  (package-version-join (epl-requirement-version requirement)))
+
+(cl-defstruct (epl-package (:constructor epl-package-create))
+  "Structure representing a package.
+
+Slots:
+
+`name' The package name, as symbol.
+
+`description' The package description.
+
+The format package description varies between package.el
+variants.  For `package-desc' variants, it is simply the
+corresponding `package-desc' object.  For legacy variants, it is
+a vector `[VERSION REQS DOCSTRING]'.
+
+Do not access `description' directly, but instead use the
+`epl-package' accessors."
+  name
+  description)
+
+(defmacro epl-package-as-description (var &rest body)
+  "Cast VAR to a package description in BODY.
+
+VAR is a symbol, bound to an `epl-package' object.  This macro
+casts this object to the `description' object, and binds the
+description to VAR in BODY."
+  (declare (indent 1))
+  (unless (symbolp var)
+    (signal 'wrong-type-argument (list #'symbolp var)))
+  `(if (epl-package-p ,var)
+       (let ((,var (epl-package-description ,var)))
+         ,@body)
+     (signal 'wrong-type-argument (list #'epl-package-p ,var))))
+
+(defsubst epl-package--package-desc-p (package)
+  "Whether the description of PACKAGE is a `package-desc'."
+  (epl--package-desc-p (epl-package-description package)))
+
+(defun epl-package-version (package)
+  "Get the version of PACKAGE, as version list."
+  (epl-package-as-description package
+    (cond
+     ((fboundp 'package-desc-version) (package-desc-version package))
+     ;; Legacy
+     ((fboundp 'package-desc-vers)
+      (let ((version (package-desc-vers package)))
+        (if (listp version) version (version-to-list version))))
+     (:else (error "Cannot get version from %S" package)))))
+
+(defun epl-package-version-string (package)
+  "Get the version from a PACKAGE, as string."
+  (package-version-join (epl-package-version package)))
+
+(defun epl-package-summary (package)
+  "Get the summary of PACKAGE, as string."
+  (epl-package-as-description package
+    (cond
+     ((fboundp 'package-desc-summary) (package-desc-summary package))
+     ((fboundp 'package-desc-doc) (package-desc-doc package)) ; Legacy
+     (:else (error "Cannot get summary from %S" package)))))
+
+(defsubst epl-requirement--from-req (req)
+  "Create a `epl-requirement' from a `package-desc' REQ."
+  (let  ((version (cadr req)))
+    (epl-requirement-create :name (car req)
+                            :version (if (listp version) version
+                                       (version-to-list version)))))
+
+(defun epl-package-requirements (package)
+  "Get the requirements of PACKAGE.
+
+The requirements are a list of `epl-requirement' objects."
+  (epl-package-as-description package
+    (mapcar #'epl-requirement--from-req (package-desc-reqs package))))
+
+(defun epl-package-directory (package)
+  "Get the directory PACKAGE is installed to.
+
+Return the absolute path of the installation directory of
+PACKAGE, or nil, if PACKAGE is not installed."
+  (cond
+   ((fboundp 'package-desc-dir)
+    (package-desc-dir (epl-package-description package)))
+   ((fboundp 'package--dir)
+    (package--dir (symbol-name (epl-package-name package))
+                  (epl-package-version-string package)))
+   (:else (error "Cannot get package directory from %S" package))))
+
+(defun epl-package-->= (pkg1 pkg2)
+  "Determine whether PKG1 is before PKG2 by version."
+  (not (version-list-< (epl-package-version pkg1)
+                       (epl-package-version pkg2))))
+
+(defun epl-package--from-package-desc (package-desc)
+  "Create an `epl-package' from a PACKAGE-DESC.
+
+PACKAGE-DESC is a `package-desc' object, from recent package.el
+variants."
+  (if (and (fboundp 'package-desc-name)
+           (epl--package-desc-p package-desc))
+      (epl-package-create :name (package-desc-name package-desc)
+                          :description package-desc)
+    (signal 'wrong-type-argument (list 'epl--package-desc-p package-desc))))
+
+(defun epl-package--parse-info (info)
+  "Parse a package.el INFO."
+  (if (epl--package-desc-p info)
+      (epl-package--from-package-desc info)
+    ;; For legacy package.el, info is a vector [NAME REQUIRES DESCRIPTION
+    ;; VERSION COMMENTARY].  We need to re-shape this vector into the
+    ;; `package-alist' format [VERSION REQUIRES DESCRIPTION] to attach it to the
+    ;; new `epl-package'.
+    (let ((name (intern (aref info 0)))
+          (info (vector (aref info 3) (aref info 1) (aref info 2))))
+      (epl-package-create :name name :description info))))
+
+(defun epl-package-from-buffer (&optional buffer)
+  "Create an `epl-package' object from BUFFER.
+
+BUFFER defaults to the current buffer.
+
+Signal `epl-invalid-package' if the buffer does not contain a
+valid package file."
+  (let ((info (with-current-buffer (or buffer (current-buffer))
+                (condition-case err
+                    (package-buffer-info)
+                  (error (signal 'epl-invalid-package (cdr err)))))))
+    (epl-package--parse-info info)))
+
+(defun epl-package-from-lisp-file (file-name)
+  "Parse the package headers the file at FILE-NAME.
+
+Return an `epl-package' object with the header metadata."
+  (with-temp-buffer
+    (insert-file-contents file-name)
+    (condition-case err
+        (epl-package-from-buffer (current-buffer))
+      ;; Attach file names to invalid package errors
+      (epl-invalid-package
+       (signal 'epl-invalid-package-file (cons file-name (cdr err))))
+      ;; Forward other errors
+      (error (signal (car err) (cdr err))))))
+
+(defun epl-package-from-tar-file (file-name)
+  "Parse the package tarball at FILE-NAME.
+
+Return a `epl-package' object with the meta data of the tarball
+package in FILE-NAME."
+  (condition-case nil
+      ;; In legacy package.el, `package-tar-file-info' takes the name of the tar
+      ;; file to parse as argument.  In modern package.el, it has no arguments
+      ;; and works on the current buffer.  Hence, we just try to call the legacy
+      ;; version, and if that fails because of a mismatch between formal and
+      ;; actual arguments, we use the modern approach.  To avoid spurious
+      ;; signature warnings by the byte compiler, we suppress warnings when
+      ;; calling the function.
+      (epl-package--parse-info (with-no-warnings
+                                 (package-tar-file-info file-name)))
+    (wrong-number-of-arguments
+     (with-temp-buffer
+       (insert-file-contents-literally file-name)
+       ;; Switch to `tar-mode' to enable extraction of the file.  Modern
+       ;; `package-tar-file-info' relies on `tar-mode', and signals an error if
+       ;; called in a buffer with a different mode.
+       (tar-mode)
+       (epl-package--parse-info (with-no-warnings
+                                  (package-tar-file-info)))))))
+
+(defun epl-package-from-file (file-name)
+  "Parse the package at FILE-NAME.
+
+Return an `epl-package' object with the meta data of the package
+at FILE-NAME."
+  (if (string-match-p (rx ".tar" string-end) file-name)
+      (epl-package-from-tar-file file-name)
+    (epl-package-from-lisp-file file-name)))
+
+(defun epl-package--parse-descriptor-requirement (requirement)
+  "Parse a REQUIREMENT in a package descriptor."
+  ;; This function is only called on legacy package.el.  On package-desc
+  ;; package.el, we just let package.el do the work.
+  (cl-destructuring-bind (name version-string) requirement
+    (list name (version-to-list version-string))))
+
+(defun epl-package-from-descriptor-file (descriptor-file)
+  "Load a `epl-package' from a package DESCRIPTOR-FILE.
+
+A package descriptor is a file defining a new package.  Its name
+typically ends with -pkg.el."
+  (with-temp-buffer
+    (insert-file-contents descriptor-file)
+    (goto-char (point-min))
+    (let ((sexp (read (current-buffer))))
+      (unless (eq (car sexp) 'define-package)
+        (error "%S is no valid package descriptor" descriptor-file))
+      (if (and (fboundp 'package-desc-from-define)
+               (fboundp 'package-desc-name))
+          ;; In Emacs snapshot, we can conveniently call a function to parse the
+          ;; descriptor
+          (let ((desc (apply #'package-desc-from-define (cdr sexp))))
+            (epl-package-create :name (package-desc-name desc)
+                                :description desc))
+        ;; In legacy package.el, we must manually deconstruct the descriptor,
+        ;; because the load function has eval's the descriptor and has a lot of
+        ;; global side-effects.
+        (cl-destructuring-bind
+            (name version-string summary requirements) (cdr sexp)
+          (epl-package-create
+           :name (intern name)
+           :description
+           (vector (version-to-list version-string)
+                   (mapcar #'epl-package--parse-descriptor-requirement
+                           ;; Strip the leading `quote' from the package list
+                           (cadr requirements))
+                   summary)))))))
+
+
+;;; Package database access
+(defun epl-package-installed-p (package &optional min-version)
+  "Determine whether a PACKAGE, of MIN-VERSION or newer, is installed.
+
+PACKAGE is either a package name as symbol, or a package object.
+When a explicit MIN-VERSION is provided it overwrites the version of the PACKAGE object."
+  (let ((name (if (epl-package-p package)
+                  (epl-package-name package)
+                package))
+        (min-version (or min-version (and (epl-package-p package)
+                                          (epl-package-version package)))))
+    (package-installed-p name min-version)))
+
+(defun epl--parse-built-in-entry (entry)
+  "Parse an ENTRY from the list of built-in packages.
+
+Return the corresponding `epl-package' object."
+  (if (fboundp 'package--from-builtin)
+      ;; In package-desc package.el, convert the built-in package to a
+      ;; `package-desc' and convert that to an `epl-package'
+      (epl-package--from-package-desc (package--from-builtin entry))
+    (epl-package-create :name (car entry) :description (cdr entry))))
+
+(defun epl-built-in-packages ()
+  "Get all built-in packages.
+
+Return a list of `epl-package' objects."
+  ;; This looks mighty strange, but it's the only way to force package.el to
+  ;; build the list of built-in packages.  Without this, `package--builtins'
+  ;; might be empty.
+  (package-built-in-p 'foo)
+  (mapcar #'epl--parse-built-in-entry package--builtins))
+
+(defun epl-find-built-in-package (name)
+  "Find a built-in package with NAME.
+
+NAME is a package name, as symbol.
+
+Return the built-in package as `epl-package' object, or nil if
+there is no built-in package with NAME."
+  (when (package-built-in-p name)
+    ;; We must call `package-built-in-p' *before* inspecting
+    ;; `package--builtins', because otherwise `package--builtins' might be
+    ;; empty.
+    (epl--parse-built-in-entry (assq name package--builtins))))
+
+(defun epl-package-outdated-p (package)
+  "Determine whether a PACKAGE is outdated.
+
+A package is outdated, if there is an available package with a
+higher version.
+
+PACKAGE is either a package name as symbol, or a package object.
+In the former case, test the installed or built-in package with
+the highest version number, in the later case, test the package
+object itself.
+
+Return t, if the package is outdated, or nil otherwise."
+  (let* ((package (if (epl-package-p package)
+                      package
+                    (or (car (epl-find-installed-packages package))
+                        (epl-find-built-in-package package))))
+         (available (car (epl-find-available-packages
+                          (epl-package-name package)))))
+    (and package available (version-list-< (epl-package-version package)
+                                           (epl-package-version available)))))
+
+(defun epl--parse-package-list-entry (entry)
+  "Parse a list of packages from ENTRY.
+
+ENTRY is a single entry in a package list, e.g. `package-alist',
+`package-archive-contents', etc.  Typically it is a cons cell,
+but the exact format varies between package.el versions.  This
+function tries to parse all known variants.
+
+Return a list of `epl-package' objects parsed from ENTRY."
+  (let ((descriptions (cdr entry)))
+    (cond
+     ((listp descriptions)
+      (sort (mapcar #'epl-package--from-package-desc descriptions)
+            #'epl-package-->=))
+     ;; Legacy package.el has just a single package in an entry, which is a
+     ;; standard description vector
+     ((vectorp descriptions)
+      (list (epl-package-create :name (car entry)
+                                :description descriptions)))
+     (:else (error "Cannot parse entry %S" entry)))))
+
+(defun epl-installed-packages ()
+  "Get all installed packages.
+
+Return a list of package objects."
+  (apply #'append (mapcar #'epl--parse-package-list-entry package-alist)))
+
+(defsubst epl--filter-outdated-packages (packages)
+  "Filter outdated packages from PACKAGES."
+  (let (res)
+    (dolist (package packages)
+      (when (epl-package-outdated-p package)
+        (push package res)))
+    (nreverse res)))
+
+(defun epl-outdated-packages ()
+  "Get all outdated packages, as in `epl-package-outdated-p'.
+
+Return a list of package objects."
+  (epl--filter-outdated-packages (epl-installed-packages)))
+
+(defsubst epl--find-package-in-list (name list)
+  "Find a package by NAME in a package LIST.
+
+Return a list of corresponding `epl-package' objects."
+  (let ((entry (assq name list)))
+    (when entry
+      (epl--parse-package-list-entry entry))))
+
+(defun epl-find-installed-package (name)
+  "Find the latest installed package by NAME.
+
+NAME is a package name, as symbol.
+
+Return the installed package with the highest version number as
+`epl-package' object, or nil, if no package with NAME is
+installed."
+  (car (epl-find-installed-packages name)))
+(make-obsolete 'epl-find-installed-package 'epl-find-installed-packages "0.7")
+
+(defun epl-find-installed-packages (name)
+  "Find all installed packages by NAME.
+
+NAME is a package name, as symbol.
+
+Return a list of all installed packages with NAME, sorted by
+version number in descending order.  Return nil, if there are no
+packages with NAME."
+  (epl--find-package-in-list name package-alist))
+
+(defun epl-available-packages ()
+  "Get all packages available for installation.
+
+Return a list of package objects."
+  (apply #'append (mapcar #'epl--parse-package-list-entry
+                          package-archive-contents)))
+
+(defun epl-find-available-packages (name)
+  "Find available packages for NAME.
+
+NAME is a package name, as symbol.
+
+Return a list of available packages for NAME, sorted by version
+number in descending order.  Return nil, if there are no packages
+for NAME."
+  (epl--find-package-in-list name package-archive-contents))
+
+(cl-defstruct (epl-upgrade
+               (:constructor epl-upgrade-create))
+  "Structure describing an upgradable package.
+Slots:
+
+`installed' The installed package
+
+`available' The package available for installation."
+  installed
+  available)
+
+(defun epl-find-upgrades (&optional packages)
+  "Find all upgradable PACKAGES.
+
+PACKAGES is a list of package objects to upgrade, defaulting to
+all installed packages.
+
+Return a list of `epl-upgrade' objects describing all upgradable
+packages."
+  (let ((packages (or packages (epl-installed-packages)))
+        upgrades)
+    (dolist (pkg packages)
+      (let* ((version (epl-package-version pkg))
+             (name (epl-package-name pkg))
+             ;; Find the latest available package for NAME
+             (available-pkg (car (epl-find-available-packages name)))
+             (available-version (when available-pkg
+                                  (epl-package-version available-pkg))))
+        (when (and available-version (version-list-< version available-version))
+          (push (epl-upgrade-create :installed pkg
+                                    :available available-pkg)
+                upgrades))))
+    (nreverse upgrades)))
+
+(defalias 'epl-built-in-p 'package-built-in-p)
+
+
+;;; Package operations
+
+(defun epl-install-file (file)
+    "Install a package from FILE, like `package-install-file'."
+    (interactive (advice-eval-interactive-spec
+                  (cadr (interactive-form #'package-install-file))))
+    (apply #'package-install-file (list file))
+    (let ((package (epl-package-from-file file)))
+      (unless (epl-package--package-desc-p package)
+        (epl--kill-autoload-buffer package))))
+
+(defun epl--kill-autoload-buffer (package)
+  "Kill the buffer associated with autoloads for PACKAGE."
+  (let* ((auto-name (format "%s-autoloads.el" (epl-package-name package)))
+         (generated-autoload-file (expand-file-name auto-name (epl-package-directory package)))
+         (buf (find-buffer-visiting generated-autoload-file)))
+    (when buf (kill-buffer buf))))
+
+(defun epl-package-install (package &optional force)
+  "Install a PACKAGE.
+
+PACKAGE is a `epl-package' object.  If FORCE is given and
+non-nil, install PACKAGE, even if it is already installed."
+  (when (or force (not (epl-package-installed-p package)))
+    (if (epl-package--package-desc-p package)
+        (package-install (epl-package-description package))
+      ;; The legacy API installs by name.  We have no control over versioning,
+      ;; etc.
+      (package-install (epl-package-name package))
+      (epl--kill-autoload-buffer package))))
+
+(defun epl-package-delete (package)
+  "Delete a PACKAGE.
+
+PACKAGE is a `epl-package' object to delete."
+  ;; package-delete allows for packages being trashed instead of fully deleted.
+  ;; Let's prevent his silly behavior
+  (let ((delete-by-moving-to-trash nil))
+    ;; The byte compiler will warn us that we are calling `package-delete' with
+    ;; the wrong number of arguments, since it can't infer that we guarantee to
+    ;; always call the correct version.  Thus we suppress all warnings when
+    ;; calling `package-delete'.  I wish there was a more granular way to
+    ;; disable just that specific warning, but it is what it is.
+    (if (epl-package--package-desc-p package)
+        (with-no-warnings
+          (package-delete (epl-package-description package)))
+      ;; The legacy API deletes by name (as string!) and version instead by
+      ;; descriptor.  Hence `package-delete' takes two arguments.  For some
+      ;; insane reason, the arguments are strings here!
+      (let ((name (symbol-name (epl-package-name package)))
+            (version (epl-package-version-string package)))
+        (with-no-warnings
+          (package-delete name version))
+        ;; Legacy package.el does not remove the deleted package
+        ;; from the `package-alist', so we do it manually here.
+        (let ((pkg (assq (epl-package-name package) package-alist)))
+          (when pkg
+            (setq package-alist (delq pkg package-alist))))))))
+
+(defun epl-upgrade (&optional packages preserve-obsolete)
+  "Upgrade PACKAGES.
+
+PACKAGES is a list of package objects to upgrade, defaulting to
+all installed packages.
+
+The old versions of the updated packages are deleted, unless
+PRESERVE-OBSOLETE is non-nil.
+
+Return a list of all performed upgrades, as a list of
+`epl-upgrade' objects."
+  (let ((upgrades (epl-find-upgrades packages)))
+    (dolist (upgrade upgrades)
+      (epl-package-install (epl-upgrade-available upgrade) 'force)
+      (unless preserve-obsolete
+        (epl-package-delete (epl-upgrade-installed upgrade))))
+    upgrades))
+
+(provide 'epl)
+
+;;; epl.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/epl-20180205.1249/epl.elc b/configs/shared/emacs/.emacs.d/elpa/epl-20180205.1249/epl.elc
new file mode 100644
index 0000000000..2250873858
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/epl-20180205.1249/epl.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/dir b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/dir
new file mode 100644
index 0000000000..b0c316ec5a
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/dir
@@ -0,0 +1,18 @@
+This is the file .../info/dir, which contains the
+topmost node of the Info hierarchy, called (dir)Top.
+The first time you invoke Info you start off looking at this node.
+
+File: dir,	Node: Top	This is the top of the INFO tree
+
+  This (the Directory node) gives a menu of major topics.
+  Typing "q" exits, "?" lists all Info commands, "d" returns here,
+  "h" gives a primer for first-timers,
+  "mEmacs<Return>" visits the Emacs manual, etc.
+
+  In Emacs, you can click mouse button 2 on a menu item or cross reference
+  to select it.
+
+* Menu:
+
+Emacs
+* Evil: (evil).                 Extensible vi layer for Emacs.
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-autoloads.el
new file mode 100644
index 0000000000..b13274e8c1
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-autoloads.el
@@ -0,0 +1,27 @@
+;;; evil-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "evil-core" "evil-core.el" (23377 61206 498047
+;;;;;;  559000))
+;;; Generated autoloads from evil-core.el
+ (autoload 'evil-mode "evil" nil t)
+
+;;;***
+
+;;;### (autoloads nil nil ("evil-command-window.el" "evil-commands.el"
+;;;;;;  "evil-common.el" "evil-development.el" "evil-digraphs.el"
+;;;;;;  "evil-ex.el" "evil-integration.el" "evil-jumps.el" "evil-macros.el"
+;;;;;;  "evil-maps.el" "evil-pkg.el" "evil-repeat.el" "evil-search.el"
+;;;;;;  "evil-states.el" "evil-types.el" "evil-vars.el" "evil.el")
+;;;;;;  (23377 61206 504105 539000))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; evil-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-command-window.el b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-command-window.el
new file mode 100644
index 0000000000..62ed189763
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-command-window.el
@@ -0,0 +1,168 @@
+;;; evil-command-window.el --- Evil command line window implementation
+;; Author: Emanuel Evans <emanuel.evans at gmail.com>
+;; Maintainer: Vegard Øye <vegard_oye at hotmail.com>
+
+;; Version: 1.2.13
+
+;;
+;; This file is NOT part of GNU Emacs.
+
+;;; License:
+
+;; This file is part of Evil.
+;;
+;; Evil 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.
+;;
+;; Evil 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 Evil.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This provides an implementation of the vim command line window for
+;; editing and repeating past ex commands and searches.
+
+;;; Code:
+
+(require 'evil-vars)
+(require 'evil-common)
+(require 'evil-search)
+(require 'evil-ex)
+
+(defvar evil-search-module)
+
+(define-derived-mode evil-command-window-mode fundamental-mode "Evil-cmd"
+  "Major mode for the Evil command line window."
+  (auto-fill-mode 0)
+  (setq-local after-change-functions (cons 'evil-command-window-draw-prefix
+                                           after-change-functions)))
+
+(defun evil-command-window (hist cmd-key execute-fn)
+  "Open a command line window for HIST with CMD-KEY and EXECUTE-FN.
+HIST should be a list of commands.  CMD-KEY should be the string of
+the key whose history is being shown (one of \":\", \"/\", or
+\"?\").  EXECUTE-FN should be a function of one argument to
+execute on the result that the user selects."
+  (when (eq major-mode 'evil-command-window-mode)
+    (user-error "Cannot recursively open command line window"))
+  (dolist (win (window-list))
+    (when (equal (buffer-name (window-buffer win))
+                 "*Command Line*")
+      (kill-buffer (window-buffer win))
+      (delete-window win)))
+  (split-window nil
+                (unless (zerop evil-command-window-height)
+                  evil-command-window-height)
+                'above)
+  (setq evil-command-window-current-buffer (current-buffer))
+  (ignore-errors (kill-buffer "*Command Line*"))
+  (switch-to-buffer "*Command Line*")
+  (setq-local evil-command-window-execute-fn execute-fn)
+  (setq-local evil-command-window-cmd-key cmd-key)
+  (evil-command-window-mode)
+  (evil-command-window-insert-commands hist))
+
+(defun evil-command-window-ex (&optional current-command)
+  "Open a command line window for editing and executing ex commands.
+If CURRENT-COMMAND is present, it will be inserted under the
+cursor as the current command to be edited."
+  (interactive)
+  (evil-command-window (cons (or current-command "") evil-ex-history)
+                       ":"
+                       'evil-command-window-ex-execute))
+
+(defun evil-command-window-execute ()
+  "Execute the command under the cursor in the appropriate buffer.
+The local var `evil-command-window-execute-fn' determines which
+function to execute."
+  (interactive)
+  (let ((result (buffer-substring (line-beginning-position)
+                                  (line-end-position)))
+        (execute-fn evil-command-window-execute-fn)
+        (command-window (get-buffer-window)))
+    (select-window (previous-window))
+    (unless (equal evil-command-window-current-buffer (current-buffer))
+      (user-error "Originating buffer is no longer active"))
+    (kill-buffer "*Command Line*")
+    (delete-window command-window)
+    (funcall execute-fn result)
+    (setq evil-command-window-current-buffer nil)))
+
+(defun evil-command-window-ex-execute (result)
+  "Execute RESULT as an ex command in the appropriate buffer."
+  (unless (string-match-p "^ *$" result)
+    (unless (equal result (car evil-ex-history))
+      (setq evil-ex-history (cons result evil-ex-history)))
+    (let ((evil-ex-current-buffer evil-command-window-current-buffer))
+      (evil-ex-execute result))))
+
+(defun evil-command-window-search-forward ()
+  "Open a command line window for forward searches."
+  (interactive)
+  (evil-command-window (cons ""
+                             (if (eq evil-search-module 'evil-search)
+                                 evil-ex-search-history
+                               evil-search-forward-history))
+                       "/"
+                       (lambda (result)
+                         (evil-command-window-search-execute result t))))
+
+(defun evil-command-window-search-backward ()
+  "Open a command line window for backward searches."
+  (interactive)
+  (evil-command-window (cons ""
+                             (if (eq evil-search-module 'evil-search)
+                                 evil-ex-search-history
+                               evil-search-backward-history))
+                       "?"
+                       (lambda (result)
+                         (evil-command-window-search-execute result nil))))
+
+(defun evil-command-window-search-execute (result forward)
+  "Search for RESULT using FORWARD to determine direction."
+  (unless (zerop (length result))
+
+    (if (eq evil-search-module 'evil-search)
+        (progn
+          (setq evil-ex-search-pattern (evil-ex-make-search-pattern result)
+                evil-ex-search-direction (if forward 'forward 'backward))
+          (unless (equal result (car-safe evil-ex-search-history))
+            (push result evil-ex-search-history))
+          (evil-ex-search))
+      (if forward
+          (unless (equal result (car-safe evil-search-forward-history))
+            (push result evil-search-forward-history))
+        (unless (equal result (car-safe evil-search-backward-history))
+          (push result evil-search-backward-history)))
+      (evil-search result forward evil-regexp-search))))
+
+(defun evil-command-window-draw-prefix (&rest ignored)
+  "Display `evil-command-window-cmd-key' as a prefix to the current line.
+Parameters passed in through IGNORED are ignored."
+  (let ((prefix (propertize evil-command-window-cmd-key
+                            'font-lock-face 'minibuffer-prompt)))
+    (set-text-properties (line-beginning-position) (line-beginning-position 2)
+                         (list 'line-prefix prefix))))
+
+(defun evil-command-window-insert-commands (hist)
+  "Insert the commands in HIST."
+  (let ((inhibit-modification-hooks t))
+    (mapc #'(lambda (cmd) (insert cmd) (newline)) hist)
+    (reverse-region (point-min) (point-max)))
+  (let ((prefix (propertize evil-command-window-cmd-key
+                            'font-lock-face 'minibuffer-prompt)))
+    (set-text-properties (point-min) (point-max) (list 'line-prefix prefix)))
+  (goto-char (point-max))
+  (when (and (bolp) (not (bobp))) (backward-char))
+  (evil-adjust-cursor))
+
+(provide 'evil-command-window)
+
+;;; evil-command-window.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-command-window.elc b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-command-window.elc
new file mode 100644
index 0000000000..ce53b7df8f
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-command-window.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-commands.el b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-commands.el
new file mode 100644
index 0000000000..6ae1a45b79
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-commands.el
@@ -0,0 +1,4496 @@
+;;; evil-commands.el --- Evil commands and operators
+;; Author: Vegard Øye <vegard_oye at hotmail.com>
+;; Maintainer: Vegard Øye <vegard_oye at hotmail.com>
+
+;; Version: 1.2.13
+
+;;
+;; This file is NOT part of GNU Emacs.
+
+;;; License:
+
+;; This file is part of Evil.
+;;
+;; Evil 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.
+;;
+;; Evil 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 Evil.  If not, see <http://www.gnu.org/licenses/>.
+
+(require 'evil-common)
+(require 'evil-digraphs)
+(require 'evil-search)
+(require 'evil-ex)
+(require 'evil-types)
+(require 'evil-command-window)
+(require 'evil-jumps)
+(require 'flyspell)
+(require 'cl-lib)
+(require 'reveal)
+
+;;; Motions
+
+;; Movement commands, or motions, are defined with the macro
+;; `evil-define-motion'. A motion is a command with an optional
+;; argument COUNT (interactively accessed by the code "<c>").
+;; It may specify the :type command property (e.g., :type line),
+;; which determines how it is handled by an operator command.
+;; Furthermore, the command must have the command properties
+;; :keep-visual t and :repeat motion; these are automatically
+;; set by the `evil-define-motion' macro.
+
+;;; Code:
+
+(evil-define-motion evil-forward-char (count &optional crosslines noerror)
+  "Move cursor to the right by COUNT characters.
+Movement is restricted to the current line unless CROSSLINES is non-nil.
+If NOERROR is non-nil, don't signal an error upon reaching the end
+of the line or the buffer; just return nil."
+  :type exclusive
+  (interactive "<c>" (list evil-cross-lines
+                           (evil-kbd-macro-suppress-motion-error)))
+  (cond
+   (noerror
+    (condition-case nil
+        (evil-forward-char count crosslines nil)
+      (error nil)))
+   ((not crosslines)
+    ;; for efficiency, narrow the buffer to the projected
+    ;; movement before determining the current line
+    (evil-with-restriction
+        (point)
+        (save-excursion
+          (evil-forward-char (1+ (or count 1)) t t)
+          (point))
+      (condition-case err
+          (evil-narrow-to-line
+            (evil-forward-char count t noerror))
+        (error
+         ;; Restore the previous command (this one never happend).
+         ;; Actually, this preserves the current column if the
+         ;; previous command was `evil-next-line' or
+         ;; `evil-previous-line'.
+         (setq this-command last-command)
+         (signal (car err) (cdr err))))))
+   (t
+    (evil-motion-loop (nil (or count 1))
+      (forward-char)
+      ;; don't put the cursor on a newline
+      (when (and evil-move-cursor-back
+                 (not evil-move-beyond-eol)
+                 (not (evil-visual-state-p))
+                 (not (evil-operator-state-p))
+                 (eolp) (not (eobp)) (not (bolp)))
+        (forward-char))))))
+
+(evil-define-motion evil-backward-char (count &optional crosslines noerror)
+  "Move cursor to the left by COUNT characters.
+Movement is restricted to the current line unless CROSSLINES is non-nil.
+If NOERROR is non-nil, don't signal an error upon reaching the beginning
+of the line or the buffer; just return nil."
+  :type exclusive
+  (interactive "<c>" (list evil-cross-lines
+                           (evil-kbd-macro-suppress-motion-error)))
+  (cond
+   (noerror
+    (condition-case nil
+        (evil-backward-char count crosslines nil)
+      (error nil)))
+   ((not crosslines)
+    ;; restrict movement to the current line
+    (evil-with-restriction
+        (save-excursion
+          (evil-backward-char (1+ (or count 1)) t t)
+          (point))
+        (1+ (point))
+      (condition-case err
+          (evil-narrow-to-line
+            (evil-backward-char count t noerror))
+        (error
+         ;; Restore the previous command (this one never happened).
+         ;; Actually, this preserves the current column if the
+         ;; previous command was `evil-next-line' or
+         ;; `evil-previous-line'.
+         (setq this-command last-command)
+         (signal (car err) (cdr err))))))
+   (t
+    (evil-motion-loop (nil (or count 1))
+      (backward-char)
+      ;; don't put the cursor on a newline
+      (unless (or (evil-visual-state-p) (evil-operator-state-p))
+        (evil-adjust-cursor))))))
+
+(evil-define-motion evil-next-line (count)
+  "Move the cursor COUNT lines down."
+  :type line
+  (let (line-move-visual)
+    (evil-line-move (or count 1))))
+
+(evil-define-motion evil-previous-line (count)
+  "Move the cursor COUNT lines up."
+  :type line
+  (let (line-move-visual)
+    (evil-line-move (- (or count 1)))))
+
+(evil-define-motion evil-next-visual-line (count)
+  "Move the cursor COUNT screen lines down."
+  :type exclusive
+  (let ((line-move-visual t))
+    (evil-line-move (or count 1))))
+
+(evil-define-motion evil-previous-visual-line (count)
+  "Move the cursor COUNT screen lines up."
+  :type exclusive
+  (let ((line-move-visual t))
+    (evil-line-move (- (or count 1)))))
+
+;; used for repeated commands like "dd"
+(evil-define-motion evil-line (count)
+  "Move COUNT - 1 lines down."
+  :type line
+  (let (line-move-visual)
+    ;; Catch bob and eob errors. These are caused when not moving
+    ;; point starting in the first or last line, respectively. In this
+    ;; case the current line should be selected.
+    (condition-case err
+        (evil-line-move (1- (or count 1)))
+      ((beginning-of-buffer end-of-buffer)))))
+
+(evil-define-motion evil-beginning-of-line ()
+  "Move the cursor to the beginning of the current line."
+  :type exclusive
+  (move-beginning-of-line nil))
+
+(evil-define-motion evil-end-of-line (count)
+  "Move the cursor to the end of the current line.
+If COUNT is given, move COUNT - 1 lines downward first."
+  :type inclusive
+  (move-end-of-line count)
+  (when evil-track-eol
+    (setq temporary-goal-column most-positive-fixnum
+          this-command 'next-line))
+  (unless (evil-visual-state-p)
+    (evil-adjust-cursor)
+    (when (eolp)
+      ;; prevent "c$" and "d$" from deleting blank lines
+      (setq evil-this-type 'exclusive))))
+
+(evil-define-motion evil-beginning-of-visual-line ()
+  "Move the cursor to the first character of the current screen line."
+  :type exclusive
+  (if (fboundp 'beginning-of-visual-line)
+      (beginning-of-visual-line)
+    (beginning-of-line)))
+
+(evil-define-motion evil-end-of-visual-line (count)
+  "Move the cursor to the last character of the current screen line.
+If COUNT is given, move COUNT - 1 screen lines downward first."
+  :type inclusive
+  (if (fboundp 'end-of-visual-line)
+      (end-of-visual-line count)
+    (end-of-line count)))
+
+(evil-define-motion evil-middle-of-visual-line ()
+  "Move the cursor to the middle of the current visual line."
+  :type exclusive
+  (beginning-of-visual-line)
+  (evil-with-restriction
+      nil
+      (save-excursion (end-of-visual-line) (point))
+    (move-to-column (+ (current-column)
+                       -1
+                       (/ (with-no-warnings (window-body-width)) 2)))))
+
+(evil-define-motion evil-beginning-of-line-or-digit-argument ()
+  "Move the cursor to the beginning of the current line.
+This function passes its command to `digit-argument' (usually a 0)
+if it is not the first event."
+  :type exclusive
+  (cond
+   (current-prefix-arg
+    (setq this-command #'digit-argument)
+    (call-interactively #'digit-argument))
+   (t
+    (setq this-command #'evil-beginning-of-line)
+    (call-interactively #'evil-beginning-of-line))))
+
+(evil-define-motion evil-first-non-blank ()
+  "Move the cursor to the first non-blank character of the current line."
+  :type exclusive
+  (evil-narrow-to-line (back-to-indentation)))
+
+(evil-define-motion evil-last-non-blank (count)
+  "Move the cursor to the last non-blank character of the current line.
+If COUNT is given, move COUNT - 1 lines downward first."
+  :type inclusive
+  (goto-char
+   (save-excursion
+     (evil-move-beginning-of-line count)
+     (if (re-search-forward "[ \t]*$")
+         (max (line-beginning-position)
+              (1- (match-beginning 0)))
+       (line-beginning-position)))))
+
+(evil-define-motion evil-first-non-blank-of-visual-line ()
+  "Move the cursor to the first non blank character
+of the current screen line."
+  :type exclusive
+  (evil-beginning-of-visual-line)
+  (skip-chars-forward " \t\r"))
+
+(evil-define-motion evil-next-line-first-non-blank (count)
+  "Move the cursor COUNT lines down on the first non-blank character."
+  :type line
+  (let ((this-command this-command))
+    (evil-next-line (or count 1)))
+  (evil-first-non-blank))
+
+(evil-define-motion evil-next-line-1-first-non-blank (count)
+  "Move the cursor COUNT-1 lines down on the first non-blank character."
+  :type line
+  (let ((this-command this-command))
+    (evil-next-line (1- (or count 1))))
+  (evil-first-non-blank))
+
+(evil-define-motion evil-previous-line-first-non-blank (count)
+  "Move the cursor COUNT lines up on the first non-blank character."
+  :type line
+  (let ((this-command this-command))
+    (evil-previous-line (or count 1)))
+  (evil-first-non-blank))
+
+(evil-define-motion evil-goto-line (count)
+  "Go to the first non-blank character of line COUNT.
+By default the last line."
+  :jump t
+  :type line
+  (if (null count)
+      (with-no-warnings (end-of-buffer))
+    (goto-char (point-min))
+    (forward-line (1- count)))
+  (evil-first-non-blank))
+
+(evil-define-motion evil-goto-first-line (count)
+  "Go to the first non-blank character of line COUNT.
+By default the first line."
+  :jump t
+  :type line
+  (evil-goto-line (or count 1)))
+
+(evil-define-motion evil-forward-word-begin (count &optional bigword)
+  "Move the cursor to the beginning of the COUNT-th next word.
+If BIGWORD is non-nil, move by WORDS.
+
+If this command is called in operator-pending state it behaves
+differently. If point reaches the beginning of a word on a new
+line point is moved back to the end of the previous line.
+
+If called after a change operator, i.e. cw or cW,
+`evil-want-change-word-to-end' is non-nil and point is on a word,
+then both behave like ce or cE.
+
+If point is at the end of the buffer and cannot be moved signal
+'end-of-buffer is raised.
+"
+  :type exclusive
+  (let ((thing (if bigword 'evil-WORD 'evil-word))
+        (orig (point))
+        (count (or count 1)))
+    (evil-signal-at-bob-or-eob count)
+    (cond
+     ;; default motion, beginning of next word
+     ((not (evil-operator-state-p))
+      (evil-forward-beginning thing count))
+     ;; the evil-change operator, maybe behave like ce or cE
+     ((and evil-want-change-word-to-end
+           (memq evil-this-operator evil-change-commands)
+           (< orig (or (cdr-safe (bounds-of-thing-at-point thing)) orig)))
+      ;; forward-thing moves point to the correct position because
+      ;; this is an exclusive motion
+      (forward-thing thing count))
+     ;; operator state
+     (t
+      (prog1 (evil-forward-beginning thing count)
+        ;; if we reached the beginning of a word on a new line in
+        ;; Operator-Pending state, go back to the end of the previous
+        ;; line
+        (when (and (> (line-beginning-position) orig)
+                   (looking-back "^[[:space:]]*" (line-beginning-position)))
+          ;; move cursor back as long as the line contains only
+          ;; whitespaces and is non-empty
+          (evil-move-end-of-line 0)
+          ;; skip non-empty lines containing only spaces
+          (while (and (looking-back "^[[:space:]]+$" (line-beginning-position))
+                      (not (<= (line-beginning-position) orig)))
+            (evil-move-end-of-line 0))
+          ;; but if the previous line is empty, delete this line
+          (when (bolp) (forward-char))))))))
+
+(evil-define-motion evil-forward-word-end (count &optional bigword)
+  "Move the cursor to the end of the COUNT-th next word.
+If BIGWORD is non-nil, move by WORDS."
+  :type inclusive
+  (let ((thing (if bigword 'evil-WORD 'evil-word))
+        (count (or count 1)))
+    (evil-signal-at-bob-or-eob count)
+    ;; Evil special behaviour: e or E on a one-character word in
+    ;; operator state does not move point
+    (unless (and (evil-operator-state-p)
+                 (= 1 count)
+                 (let ((bnd (bounds-of-thing-at-point thing)))
+                   (and bnd
+                        (= (car bnd) (point))
+                        (= (cdr bnd) (1+ (point)))))
+                 (looking-at "[[:word:]]"))
+      (evil-forward-end thing count))))
+
+(evil-define-motion evil-backward-word-begin (count &optional bigword)
+  "Move the cursor to the beginning of the COUNT-th previous word.
+If BIGWORD is non-nil, move by WORDS."
+  :type exclusive
+  (let ((thing (if bigword 'evil-WORD 'evil-word)))
+    (evil-signal-at-bob-or-eob (- (or count 1)))
+    (evil-backward-beginning thing count)))
+
+(evil-define-motion evil-backward-word-end (count &optional bigword)
+  "Move the cursor to the end of the COUNT-th previous word.
+If BIGWORD is non-nil, move by WORDS."
+  :type inclusive
+  (let ((thing (if bigword 'evil-WORD 'evil-word)))
+    (evil-signal-at-bob-or-eob (- (or count 1)))
+    (evil-backward-end thing count)))
+
+(evil-define-motion evil-forward-WORD-begin (count)
+  "Move the cursor to the beginning of the COUNT-th next WORD."
+  :type exclusive
+  (evil-forward-word-begin count t))
+
+(evil-define-motion evil-forward-WORD-end (count)
+  "Move the cursor to the end of the COUNT-th next WORD."
+  :type inclusive
+  (evil-forward-word-end count t))
+
+(evil-define-motion evil-backward-WORD-begin (count)
+  "Move the cursor to the beginning of the COUNT-th previous WORD."
+  :type exclusive
+  (evil-backward-word-begin count t))
+
+(evil-define-motion evil-backward-WORD-end (count)
+  "Move the cursor to the end of the COUNT-th previous WORD."
+  :type inclusive
+  (evil-backward-word-end count t))
+
+;; section movement
+(evil-define-motion evil-forward-section-begin (count)
+  "Move the cursor to the beginning of the COUNT-th next section."
+  :jump t
+  :type exclusive
+  (evil-signal-at-bob-or-eob count)
+  (evil-forward-beginning 'evil-defun count))
+
+(evil-define-motion evil-forward-section-end (count)
+  "Move the cursor to the end of the COUNT-th next section."
+  :jump t
+  :type inclusive
+  (evil-signal-at-bob-or-eob count)
+  (evil-forward-end 'evil-defun count)
+  (unless (eobp) (forward-line)))
+
+(evil-define-motion evil-backward-section-begin (count)
+  "Move the cursor to the beginning of the COUNT-th previous section."
+  :jump t
+  :type exclusive
+  (evil-signal-at-bob-or-eob (- (or count 1)))
+  (evil-backward-beginning 'evil-defun count))
+
+(evil-define-motion evil-backward-section-end (count)
+  "Move the cursor to the end of the COUNT-th previous section."
+  :jump t
+  :type inclusive
+  (evil-signal-at-bob-or-eob (- (or count 1)))
+  (end-of-line -1)
+  (evil-backward-end 'evil-defun count)
+  (unless (eobp) (forward-line)))
+
+(evil-define-motion evil-forward-sentence-begin (count)
+  "Move to the next COUNT-th beginning of a sentence or end of a paragraph."
+  :jump t
+  :type exclusive
+  (evil-signal-at-bob-or-eob count)
+  (evil-forward-nearest count
+                        #'(lambda (cnt)
+                            (evil-forward-beginning 'evil-sentence))
+                        #'evil-forward-paragraph))
+
+(evil-define-motion evil-backward-sentence-begin (count)
+  "Move to the previous COUNT-th beginning of a sentence or paragraph."
+  :jump t
+  :type exclusive
+  (evil-signal-at-bob-or-eob (- (or count 1)))
+  (evil-forward-nearest (- (or count 1))
+                        #'(lambda (cnt)
+                            (evil-backward-beginning 'evil-sentence))
+                        #'(lambda (cnt)
+                            (evil-backward-paragraph))))
+
+(evil-define-motion evil-forward-paragraph (count)
+  "Move to the end of the COUNT-th next paragraph."
+  :jump t
+  :type exclusive
+  (evil-signal-at-bob-or-eob count)
+  (evil-forward-end 'evil-paragraph count)
+  (unless (eobp) (forward-line)))
+
+(evil-define-motion evil-backward-paragraph (count)
+  "Move to the beginning of the COUNT-th previous paragraph."
+  :jump t
+  :type exclusive
+  (evil-signal-at-bob-or-eob (- (or count 1)))
+  (unless (eobp) (forward-line))
+  (evil-backward-beginning 'evil-paragraph count)
+  (unless (bobp) (forward-line -1)))
+
+(evil-define-motion evil-jump-item (count)
+  "Find the next item in this line after or under the cursor
+and jump to the corresponding one."
+  :jump t
+  :type inclusive
+  (cond
+   ;; COUNT% jumps to a line COUNT percentage down the file
+   (count
+    (goto-char
+     (evil-normalize-position
+      (let ((size (- (point-max) (point-min))))
+        (+ (point-min)
+           (if (> size 80000)
+               (* count (/ size 100))
+             (/ (* count size) 100))))))
+    (back-to-indentation)
+    (setq evil-this-type 'line))
+   ((and (evil-looking-at-start-comment t)
+         (let ((pnt (point)))
+           (forward-comment 1)
+           (or (not (bolp))
+               (prog1 nil (goto-char pnt)))))
+    (backward-char))
+   ((and (not (eolp)) (evil-looking-at-end-comment t))
+    (forward-comment -1))
+   ((and
+     (memq major-mode '(c-mode c++-mode))
+     (require 'hideif nil t)
+     (with-no-warnings
+       (let* ((hif-else-regexp (concat hif-cpp-prefix "\\(?:else\\|elif[ \t]+\\)"))
+              (hif-ifx-else-endif-regexp
+               (concat hif-ifx-regexp "\\|" hif-else-regexp "\\|" hif-endif-regexp)))
+         (cond
+          ((save-excursion (beginning-of-line) (or (hif-looking-at-ifX) (hif-looking-at-else)))
+           (hif-find-next-relevant)
+           (while (hif-looking-at-ifX)
+             (hif-ifdef-to-endif)
+             (hif-find-next-relevant))
+           t)
+          ((save-excursion (beginning-of-line) (hif-looking-at-endif))
+           (hif-endif-to-ifdef)
+           t))))))
+   (t
+    (let* ((open (point-max))
+           (close (point-max))
+           (open-pair (condition-case nil
+                          (save-excursion
+                            ;; consider the character right before eol given that
+                            ;; point may be placed there, e.g. in visual state
+                            (when (and (eolp) (not (bolp)))
+                              (backward-char))
+                            (setq open (1- (scan-lists (point) 1 -1)))
+                            (when (< open (line-end-position))
+                              (goto-char open)
+                              (forward-list)
+                              (1- (point))))
+                        (error nil)))
+           (close-pair (condition-case nil
+                           (save-excursion
+                             ;; consider the character right before eol given that
+                             ;; point may be placed there, e.g. in visual state
+                             (when (and (eolp) (not (bolp)))
+                               (backward-char))
+                             (setq close (1- (scan-lists (point) 1 1)))
+                             (when (< close (line-end-position))
+                               (goto-char (1+ close))
+                               (backward-list)
+                               (point)))
+                         (error nil))))
+      (cond
+       ((not (or open-pair close-pair))
+        ;; nothing found, check if we are inside a string
+        (let ((pnt (point))
+              (state (syntax-ppss (point)))
+              (bnd (bounds-of-thing-at-point 'evil-string)))
+          (if (not (and bnd (< (point) (cdr bnd))))
+              ;; no, then we really failed
+              (user-error "No matching item found on the current line")
+            ;; yes, go to the end of the string and try again
+            (let ((endstr (cdr bnd)))
+              (when (or (save-excursion
+                          (goto-char endstr)
+                          (let ((b (bounds-of-thing-at-point 'evil-string)))
+                            (and b (< (point) (cdr b))))) ; not at end of string
+                        (condition-case nil
+                            (progn
+                              (goto-char endstr)
+                              (evil-jump-item)
+                              nil)
+                          (error t)))
+                ;; failed again, go back to original point
+                (goto-char pnt)
+                (user-error "No matching item found on the current line"))))))
+       ((< open close) (goto-char open-pair))
+       (t (goto-char close-pair)))))))
+
+(defun evil--flyspell-overlays-in-p (beg end)
+  (let ((ovs (overlays-in beg end))
+        done)
+    (while (and ovs (not done))
+      (when (flyspell-overlay-p (car ovs))
+        (setq done t))
+      (setq ovs (cdr ovs)))
+    done))
+
+(defun evil--flyspell-overlay-at (pos forwardp)
+  (when (not forwardp)
+    (setq pos (max (1- pos) (point-min))))
+  (let ((ovs (overlays-at pos))
+        done)
+    (while (and ovs (not done))
+      (if (flyspell-overlay-p (car ovs))
+          (setq done t)
+        (setq ovs (cdr ovs))))
+    (when done
+      (car ovs))))
+
+(defun evil--flyspell-overlay-after (pos limit forwardp)
+  (let (done)
+    (while (and (if forwardp
+                    (< pos limit)
+                  (> pos limit))
+                (not done))
+      (let ((ov (evil--flyspell-overlay-at pos forwardp)))
+        (when ov
+          (setq done ov)))
+      (setq pos (if forwardp
+                    (next-overlay-change pos)
+                  (previous-overlay-change pos))))
+    done))
+
+(defun evil--next-flyspell-error (forwardp)
+  (when (evil--flyspell-overlays-in-p (point-min) (point-max))
+    (let ((pos (point))
+          limit
+          ov)
+      (when (evil--flyspell-overlay-at pos forwardp)
+        (if (/= pos (point-min))
+            (setq pos (save-excursion (goto-char pos)
+                                      (forward-word (if forwardp 1 -1))
+                                      (point)))
+          (setq pos (point-max))))
+      (setq limit (if forwardp (point-max) (point-min))
+            ov (evil--flyspell-overlay-after pos limit forwardp))
+      (if ov
+          (goto-char (overlay-start ov))
+        (when evil-search-wrap
+          (setq limit pos
+                pos (if forwardp (point-min) (point-max))
+                ov (evil--flyspell-overlay-after pos limit forwardp))
+          (when ov
+            (goto-char (overlay-start ov))))))))
+
+(evil-define-motion evil-next-flyspell-error (count)
+  "Go to the COUNT'th spelling mistake after point."
+  (interactive "p")
+  (dotimes (_ count)
+    (evil--next-flyspell-error t)))
+
+(evil-define-motion evil-prev-flyspell-error (count)
+  "Go to the COUNT'th spelling mistake preceding point."
+  (interactive "p")
+  (dotimes (_ count)
+    (evil--next-flyspell-error nil)))
+
+(evil-define-motion evil-previous-open-paren (count)
+  "Go to [count] previous unmatched '('."
+  :type exclusive
+  (evil-up-paren ?\( ?\) (- (or count 1))))
+
+(evil-define-motion evil-next-close-paren (count)
+  "Go to [count] next unmatched ')'."
+  :type exclusive
+  (forward-char)
+  (evil-up-paren ?\( ?\) (or count 1))
+  (backward-char))
+
+(evil-define-motion evil-previous-open-brace (count)
+  "Go to [count] previous unmatched '{'."
+  :type exclusive
+  (evil-up-paren ?{ ?} (- (or count 1))))
+
+(evil-define-motion evil-next-close-brace (count)
+  "Go to [count] next unmatched '}'."
+  :type exclusive
+  (forward-char)
+  (evil-up-paren ?{ ?} (or count 1))
+  (backward-char))
+
+(evil-define-motion evil-find-char (count char)
+  "Move to the next COUNT'th occurrence of CHAR.
+Movement is restricted to the current line unless `evil-cross-lines' is non-nil."
+  :type inclusive
+  (interactive "<c><C>")
+  (setq count (or count 1))
+  (let ((fwd (> count 0)))
+    (setq evil-last-find (list #'evil-find-char char fwd))
+    (when fwd (forward-char))
+    (let ((case-fold-search nil))
+      (unless (prog1
+                  (search-forward (char-to-string char)
+                                  (unless evil-cross-lines
+                                    (if fwd
+                                        (line-end-position)
+                                      (line-beginning-position)))
+                                  t count)
+                (when fwd (backward-char)))
+        (user-error "Can't find %c" char)))))
+
+(evil-define-motion evil-find-char-backward (count char)
+  "Move to the previous COUNT'th occurrence of CHAR."
+  :type exclusive
+  (interactive "<c><C>")
+  (evil-find-char (- (or count 1)) char))
+
+(evil-define-motion evil-find-char-to (count char)
+  "Move before the next COUNT'th occurrence of CHAR."
+  :type inclusive
+  (interactive "<c><C>")
+  (unwind-protect
+      (progn
+        (evil-find-char count char)
+        (if (> (or count 1) 0)
+            (backward-char)
+          (forward-char)))
+    (setcar evil-last-find #'evil-find-char-to)))
+
+(evil-define-motion evil-find-char-to-backward (count char)
+  "Move before the previous COUNT'th occurrence of CHAR."
+  :type exclusive
+  (interactive "<c><C>")
+  (evil-find-char-to (- (or count 1)) char))
+
+(evil-define-motion evil-repeat-find-char (count)
+  "Repeat the last find COUNT times."
+  :type inclusive
+  (setq count (or count 1))
+  (if evil-last-find
+      (let ((cmd (car evil-last-find))
+            (char (nth 1 evil-last-find))
+            (fwd (nth 2 evil-last-find))
+            evil-last-find)
+        ;; ensure count is non-negative
+        (when (< count 0)
+          (setq count (- count)
+                fwd (not fwd)))
+        ;; skip next character when repeating t or T
+        (and (eq cmd #'evil-find-char-to)
+             evil-repeat-find-to-skip-next
+             (= count 1)
+             (or (and fwd (= (char-after (1+ (point))) char))
+                 (and (not fwd) (= (char-before) char)))
+             (setq count (1+ count)))
+        (funcall cmd (if fwd count (- count)) char)
+        (unless (nth 2 evil-last-find)
+          (setq evil-this-type 'exclusive)))
+    (user-error "No previous search")))
+
+(evil-define-motion evil-repeat-find-char-reverse (count)
+  "Repeat the last find COUNT times in the opposite direction."
+  :type inclusive
+  (evil-repeat-find-char (- (or count 1))))
+
+;; ceci n'est pas une pipe
+(evil-define-motion evil-goto-column (count)
+  "Go to column COUNT on the current line.
+Columns are counted from zero."
+  :type exclusive
+  (move-to-column (or count 0)))
+
+(evil-define-command evil-goto-mark (char &optional noerror)
+  "Go to the marker specified by CHAR."
+  :keep-visual t
+  :repeat nil
+  :type exclusive
+  :jump t
+  (interactive (list (read-char)))
+  (let ((marker (evil-get-marker char)))
+    (cond
+     ((markerp marker)
+      (switch-to-buffer (marker-buffer marker))
+      (goto-char (marker-position marker)))
+     ((numberp marker)
+      (goto-char marker))
+     ((consp marker)
+      (when (or (find-buffer-visiting (car marker))
+                (and (y-or-n-p (format "Visit file %s again? "
+                                       (car marker)))
+                     (find-file (car marker))))
+        (goto-char (cdr marker))))
+     ((not noerror)
+      (user-error "Marker `%c' is not set%s" char
+                  (if (evil-global-marker-p char) ""
+                    " in this buffer"))))))
+
+(evil-define-command evil-goto-mark-line (char &optional noerror)
+  "Go to the line of the marker specified by CHAR."
+  :keep-visual t
+  :repeat nil
+  :type line
+  :jump t
+  (interactive (list (read-char)))
+  (evil-goto-mark char noerror)
+  (evil-first-non-blank))
+
+(evil-define-motion evil-jump-backward (count)
+  "Go to older position in jump list.
+To go the other way, press \
+\\<evil-motion-state-map>\\[evil-jump-forward]."
+  (evil--jump-backward count))
+
+(evil-define-motion evil-jump-forward (count)
+  "Go to newer position in jump list.
+To go the other way, press \
+\\<evil-motion-state-map>\\[evil-jump-backward]."
+  (evil--jump-forward count))
+
+(evil-define-motion evil-jump-backward-swap (count)
+  "Go to the previous position in jump list.
+The current position is placed in the jump list."
+  (let ((pnt (point)))
+    (evil--jump-backward 1)
+    (evil-set-jump pnt)))
+
+(evil-define-motion evil-jump-to-tag (arg)
+  "Jump to tag under point.
+If called with a prefix argument, provide a prompt
+for specifying the tag."
+  :jump t
+  (interactive "P")
+  (cond
+   ((fboundp 'xref-find-definitions)
+    (let ((xref-prompt-for-identifier arg))
+      (call-interactively #'xref-find-definitions)))
+   ((fboundp 'find-tag)
+    (if arg (call-interactively #'find-tag)
+      (let ((tag (funcall (or find-tag-default-function
+                              (get major-mode 'find-tag-default-function)
+                              #'find-tag-default))))
+        (unless tag (user-error "No tag candidate found around point"))
+        (find-tag tag))))))
+
+(evil-define-motion evil-lookup ()
+  "Look up the keyword at point.
+Calls `evil-lookup-func'."
+  (funcall evil-lookup-func))
+
+(defun evil-ret-gen (count indent?)
+  (let* ((field  (get-char-property (point) 'field))
+         (button (get-char-property (point) 'button))
+         (doc    (get-char-property (point) 'widget-doc))
+         (widget (or field button doc)))
+    (cond
+     ((and widget
+           (fboundp 'widget-type)
+           (fboundp 'widget-button-press)
+           (or (and (symbolp widget)
+                    (get widget 'widget-type))
+               (and (consp widget)
+                    (get (widget-type widget) 'widget-type))))
+      (when (evil-operator-state-p)
+        (setq evil-inhibit-operator t))
+      (when (fboundp 'widget-button-press)
+        (widget-button-press (point))))
+     ((and (fboundp 'button-at)
+           (fboundp 'push-button)
+           (button-at (point)))
+      (when (evil-operator-state-p)
+        (setq evil-inhibit-operator t))
+      (push-button))
+     ((or (evil-emacs-state-p)
+          (and (evil-insert-state-p)
+               (not buffer-read-only)))
+      (if (not indent?)
+          (newline count)
+        (delete-horizontal-space t)
+        (newline count)
+        (indent-according-to-mode)))
+     (t
+      (evil-next-line-first-non-blank count)))))
+
+(evil-define-motion evil-ret (count)
+  "Move the cursor COUNT lines down.
+If point is on a widget or a button, click on it.
+In Insert state, insert a newline."
+  :type line
+  (evil-ret-gen count nil))
+
+(evil-define-motion evil-ret-and-indent (count)
+  "Move the cursor COUNT lines down.
+If point is on a widget or a button, click on it.
+In Insert state, insert a newline and indent."
+  :type line
+  (evil-ret-gen count t))
+
+(evil-define-motion evil-window-top (count)
+  "Move the cursor to line COUNT from the top of the window
+on the first non-blank character."
+  :jump t
+  :type line
+  (move-to-window-line (max (or count 0)
+                            (if (= (point-min) (window-start))
+                                0
+                              scroll-margin)))
+  (back-to-indentation))
+
+(evil-define-motion evil-window-middle ()
+  "Move the cursor to the middle line in the window
+on the first non-blank character."
+  :jump t
+  :type line
+  (move-to-window-line
+   (/ (1+ (save-excursion (move-to-window-line -1))) 2))
+  (back-to-indentation))
+
+(evil-define-motion evil-window-bottom (count)
+  "Move the cursor to line COUNT from the bottom of the window
+on the first non-blank character."
+  :jump t
+  :type line
+  (move-to-window-line (- (max (or count 1) (1+ scroll-margin))))
+  (back-to-indentation))
+
+;; scrolling
+(evil-define-command evil-scroll-line-up (count)
+  "Scrolls the window COUNT lines upwards."
+  :repeat nil
+  :keep-visual t
+  (interactive "p")
+  (let ((scroll-preserve-screen-position nil))
+    (scroll-down count)))
+
+(evil-define-command evil-scroll-line-down (count)
+  "Scrolls the window COUNT lines downwards."
+  :repeat nil
+  :keep-visual t
+  (interactive "p")
+  (let ((scroll-preserve-screen-position nil))
+    (scroll-up count)))
+
+(evil-define-command evil-scroll-count-reset ()
+  "Sets `evil-scroll-count' to 0.
+`evil-scroll-up' and `evil-scroll-down' will scroll
+for a half of the screen(default)."
+  :repeat nil
+  :keep-visual t
+  (interactive)
+  (setq evil-scroll-count 0))
+
+(evil-define-command evil-scroll-up (count)
+  "Scrolls the window and the cursor COUNT lines upwards.
+If COUNT is not specified the function scrolls down
+`evil-scroll-count', which is the last used count.
+If the scroll count is zero the command scrolls half the screen."
+  :repeat nil
+  :keep-visual t
+  (interactive "<c>")
+  (evil-save-column
+    (setq count (or count (max 0 evil-scroll-count)))
+    (setq evil-scroll-count count)
+    (when (= (point-min) (line-beginning-position))
+      (signal 'beginning-of-buffer nil))
+    (when (zerop count)
+      (setq count (/ (1- (window-height)) 2)))
+    (let ((xy (posn-x-y (posn-at-point))))
+      (condition-case nil
+          (progn
+            (scroll-down count)
+            (goto-char (posn-point (posn-at-x-y (car xy) (cdr xy)))))
+        (beginning-of-buffer
+         (condition-case nil
+             (with-no-warnings (previous-line count))
+           (beginning-of-buffer)))))))
+
+(evil-define-command evil-scroll-down (count)
+  "Scrolls the window and the cursor COUNT lines downwards.
+If COUNT is not specified the function scrolls down
+`evil-scroll-count', which is the last used count.
+If the scroll count is zero the command scrolls half the screen."
+  :repeat nil
+  :keep-visual t
+  (interactive "<c>")
+  (evil-save-column
+    (setq count (or count (max 0 evil-scroll-count)))
+    (setq evil-scroll-count count)
+    (when (eobp) (signal 'end-of-buffer nil))
+    (when (zerop count)
+      (setq count (/ (1- (window-height)) 2)))
+    ;; BUG #660: First check whether the eob is visible.
+    ;; In that case we do not scroll but merely move point.
+    (if (<= (point-max) (window-end))
+        (with-no-warnings (next-line count nil))
+      (let ((xy (posn-x-y (posn-at-point))))
+        (condition-case nil
+            (progn
+              (scroll-up count)
+              (let* ((wend (window-end nil t))
+                     (p (posn-at-x-y (car xy) (cdr xy)))
+                     (margin (max 0 (- scroll-margin
+                                       (cdr (posn-col-row p))))))
+                (goto-char (posn-point p))
+                ;; ensure point is not within the scroll-margin
+                (when (> margin 0)
+                  (with-no-warnings (next-line margin))
+                  (recenter scroll-margin))
+                (when (<= (point-max) wend)
+                  (save-excursion
+                    (goto-char (point-max))
+                    (recenter (- (max 1 scroll-margin)))))))
+          (end-of-buffer
+           (goto-char (point-max))
+           (recenter (- (max 1 scroll-margin)))))))))
+
+(evil-define-command evil-scroll-page-up (count)
+  "Scrolls the window COUNT pages upwards."
+  :repeat nil
+  :keep-visual t
+  (interactive "p")
+  (evil-save-column
+    (dotimes (i count)
+      (condition-case err
+          (scroll-down nil)
+        (beginning-of-buffer
+         (if (and (bobp) (zerop i))
+             (signal (car err) (cdr err))
+           (goto-char (point-min))))))))
+
+(evil-define-command evil-scroll-page-down (count)
+  "Scrolls the window COUNT pages downwards."
+  :repeat nil
+  :keep-visual t
+  (interactive "p")
+  (evil-save-column
+    (dotimes (i count)
+      (condition-case err
+          (scroll-up nil)
+        (end-of-buffer
+         (if (and (eobp) (zerop i))
+             (signal (car err) (cdr err))
+           (goto-char (point-max))))))))
+
+(evil-define-command evil-scroll-line-to-top (count)
+  "Scrolls line number COUNT (or the cursor line) to the top of the window."
+  :repeat nil
+  :keep-visual t
+  (interactive "<c>")
+  (evil-save-column
+    (let ((line (or count (line-number-at-pos (point)))))
+      (goto-char (point-min))
+      (forward-line (1- line)))
+    (recenter (1- (max 1 scroll-margin)))))
+
+(evil-define-command evil-scroll-line-to-center (count)
+  "Scrolls line number COUNT (or the cursor line) to the center of the window."
+  :repeat nil
+  :keep-visual t
+  (interactive "<c>")
+  (evil-save-column
+    (when count
+      (goto-char (point-min))
+      (forward-line (1- count)))
+    (recenter nil)))
+
+(evil-define-command evil-scroll-line-to-bottom (count)
+  "Scrolls line number COUNT (or the cursor line) to the bottom of the window."
+  :repeat nil
+  :keep-visual t
+  (interactive "<c>")
+  (evil-save-column
+    (let ((line (or count (line-number-at-pos (point)))))
+      (goto-char (point-min))
+      (forward-line (1- line)))
+    (recenter (- (max 1 scroll-margin)))))
+
+(evil-define-command evil-scroll-bottom-line-to-top (count)
+  "Scrolls the line right below the window,
+or line COUNT to the top of the window."
+  :repeat nil
+  :keep-visual t
+  (interactive "<c>")
+  (if count
+      (progn
+        (goto-char (point-min))
+        (forward-line (1- count)))
+    (goto-char (window-end))
+    (evil-move-cursor-back))
+  (recenter (1- (max 0 scroll-margin)))
+  (evil-first-non-blank))
+
+(evil-define-command evil-scroll-top-line-to-bottom (count)
+  "Scrolls the line right below the window,
+or line COUNT to the top of the window."
+  :repeat nil
+  :keep-visual t
+  (interactive "<c>")
+  (if count
+      (progn
+        (goto-char (point-min))
+        (forward-line (1- count)))
+    (goto-char (window-start)))
+  (recenter (- (max 1 scroll-margin)))
+  (evil-first-non-blank))
+
+(evil-define-command evil-scroll-left (count)
+  "Scrolls the window COUNT half-screenwidths to the left."
+  :repeat nil
+  :keep-visual t
+  (interactive "p")
+  (evil-with-hproject-point-on-window
+    (scroll-right (* count (/ (window-width) 2)))))
+
+(evil-define-command evil-scroll-right (count)
+  "Scrolls the window COUNT half-screenwidths to the right."
+  :repeat nil
+  :keep-visual t
+  (interactive "p")
+  (evil-with-hproject-point-on-window
+    (scroll-left (* count (/ (window-width) 2)))))
+
+(evil-define-command evil-scroll-column-left (count)
+  "Scrolls the window COUNT columns to the left."
+  :repeat nil
+  :keep-visual t
+  (interactive "p")
+  (evil-with-hproject-point-on-window
+    (scroll-right count)))
+
+(evil-define-command evil-scroll-column-right (count)
+  "Scrolls the window COUNT columns to the right."
+  :repeat nil
+  :keep-visual t
+  (interactive "p")
+  (evil-with-hproject-point-on-window
+    (scroll-left count)))
+
+;;; Text objects
+
+;; Text objects are defined with `evil-define-text-object'. In Visual
+;; state, they modify the current selection; in Operator-Pending
+;; state, they return a pair of buffer positions. Outer text objects
+;; are bound in the keymap `evil-outer-text-objects-map', and inner
+;; text objects are bound in `evil-inner-text-objects-map'.
+;;
+;; Common text objects like words, WORDS, paragraphs and sentences are
+;; defined via a corresponding move-function. This function must have
+;; the following properties:
+;;
+;;   1. Take exactly one argument, the count.
+;;   2. When the count is positive, move point forward to the first
+;;      character after the end of the next count-th object.
+;;   3. When the count is negative, move point backward to the first
+;;      character of the count-th previous object.
+;;   4. If point is placed on the first character of an object, the
+;;      backward motion does NOT count that object.
+;;   5. If point is placed on the last character of an object, the
+;;      forward motion DOES count that object.
+;;   6. The return value is "count left", i.e., in forward direction
+;;      count is decreased by one for each successful move and in
+;;      backward direction count is increased by one for each
+;;      successful move, returning the final value of count.
+;;      Therefore, if the complete move is successful, the return
+;;      value is 0.
+;;
+;; A useful macro in this regard is `evil-motion-loop', which quits
+;; when point does not move further and returns the count difference.
+;; It also provides a "unit value" of 1 or -1 for use in each
+;; iteration. For example, a hypothetical "foo-bar" move could be
+;; written as such:
+;;
+;;     (defun foo-bar (count)
+;;       (evil-motion-loop (var count)
+;;         (forward-foo var) ; `var' is 1 or -1 depending on COUNT
+;;         (forward-bar var)))
+;;
+;; If "forward-foo" and "-bar" didn't accept negative arguments,
+;; we could choose their backward equivalents by inspecting `var':
+;;
+;;     (defun foo-bar (count)
+;;       (evil-motion-loop (var count)
+;;         (cond
+;;          ((< var 0)
+;;           (backward-foo 1)
+;;           (backward-bar 1))
+;;          (t
+;;           (forward-foo 1)
+;;           (forward-bar 1)))))
+;;
+;; After a forward motion, point has to be placed on the first
+;; character after some object, unless no motion was possible at all.
+;; Similarly, after a backward motion, point has to be placed on the
+;; first character of some object. This implies that point should
+;; NEVER be moved to eob or bob, unless an object ends or begins at
+;; eob or bob. (Usually, Emacs motions always move as far as possible.
+;; But we want to use the motion-function to identify certain objects
+;; in the buffer, and thus exact movement to object boundaries is
+;; required.)
+
+(evil-define-text-object evil-a-word (count &optional beg end type)
+  "Select a word."
+  (evil-select-an-object 'evil-word beg end type count))
+
+(evil-define-text-object evil-inner-word (count &optional beg end type)
+  "Select inner word."
+  (evil-select-inner-object 'evil-word beg end type count))
+
+(evil-define-text-object evil-a-WORD (count &optional beg end type)
+  "Select a WORD."
+  (evil-select-an-object 'evil-WORD beg end type count))
+
+(evil-define-text-object evil-inner-WORD (count &optional beg end type)
+  "Select inner WORD."
+  (evil-select-inner-object 'evil-WORD beg end type count))
+
+(evil-define-text-object evil-a-symbol (count &optional beg end type)
+  "Select a symbol."
+  (evil-select-an-object 'evil-symbol beg end type count))
+
+(evil-define-text-object evil-inner-symbol (count &optional beg end type)
+  "Select inner symbol."
+  (evil-select-inner-object 'evil-symbol beg end type count))
+
+(evil-define-text-object evil-a-sentence (count &optional beg end type)
+  "Select a sentence."
+  (evil-select-an-object 'evil-sentence beg end type count))
+
+(evil-define-text-object evil-inner-sentence (count &optional beg end type)
+  "Select inner sentence."
+  (evil-select-inner-object 'evil-sentence beg end type count))
+
+(evil-define-text-object evil-a-paragraph (count &optional beg end type)
+  "Select a paragraph."
+  :type line
+  (evil-select-an-object 'evil-paragraph beg end type count t))
+
+(evil-define-text-object evil-inner-paragraph (count &optional beg end type)
+  "Select inner paragraph."
+  :type line
+  (evil-select-inner-object 'evil-paragraph beg end type count t))
+
+(evil-define-text-object evil-a-paren (count &optional beg end type)
+  "Select a parenthesis."
+  :extend-selection nil
+  (evil-select-paren ?\( ?\) beg end type count t))
+
+(evil-define-text-object evil-inner-paren (count &optional beg end type)
+  "Select inner parenthesis."
+  :extend-selection nil
+  (evil-select-paren ?\( ?\) beg end type count))
+
+(evil-define-text-object evil-a-bracket (count &optional beg end type)
+  "Select a square bracket."
+  :extend-selection nil
+  (evil-select-paren ?\[ ?\] beg end type count t))
+
+(evil-define-text-object evil-inner-bracket (count &optional beg end type)
+  "Select inner square bracket."
+  :extend-selection nil
+  (evil-select-paren ?\[ ?\] beg end type count))
+
+(evil-define-text-object evil-a-curly (count &optional beg end type)
+  "Select a curly bracket (\"brace\")."
+  :extend-selection nil
+  (evil-select-paren ?{ ?} beg end type count t))
+
+(evil-define-text-object evil-inner-curly (count &optional beg end type)
+  "Select inner curly bracket (\"brace\")."
+  :extend-selection nil
+  (evil-select-paren ?{ ?} beg end type count))
+
+(evil-define-text-object evil-an-angle (count &optional beg end type)
+  "Select an angle bracket."
+  :extend-selection nil
+  (evil-select-paren ?< ?> beg end type count t))
+
+(evil-define-text-object evil-inner-angle (count &optional beg end type)
+  "Select inner angle bracket."
+  :extend-selection nil
+  (evil-select-paren ?< ?> beg end type count))
+
+(evil-define-text-object evil-a-single-quote (count &optional beg end type)
+  "Select a single-quoted expression."
+  :extend-selection t
+  (evil-select-quote ?' beg end type count t))
+
+(evil-define-text-object evil-inner-single-quote (count &optional beg end type)
+  "Select inner single-quoted expression."
+  :extend-selection nil
+  (evil-select-quote ?' beg end type count))
+
+(evil-define-text-object evil-a-double-quote (count &optional beg end type)
+  "Select a double-quoted expression."
+  :extend-selection t
+  (evil-select-quote ?\" beg end type count t))
+
+(evil-define-text-object evil-inner-double-quote (count &optional beg end type)
+  "Select inner double-quoted expression."
+  :extend-selection nil
+  (evil-select-quote ?\" beg end type count))
+
+(evil-define-text-object evil-a-back-quote (count &optional beg end type)
+  "Select a back-quoted expression."
+  :extend-selection t
+  (evil-select-quote ?\` beg end type count t))
+
+(evil-define-text-object evil-inner-back-quote (count &optional beg end type)
+  "Select inner back-quoted expression."
+  :extend-selection nil
+  (evil-select-quote ?\` beg end type count))
+
+(evil-define-text-object evil-a-tag (count &optional beg end type)
+  "Select a tag block."
+  :extend-selection nil
+  (evil-select-xml-tag beg end type count t))
+
+(evil-define-text-object evil-inner-tag (count &optional beg end type)
+  "Select inner tag block."
+  :extend-selection nil
+  (evil-select-xml-tag beg end type count))
+
+(evil-define-text-object evil-next-match (count &optional beg end type)
+  "Select next match."
+  (unless (and (boundp 'evil-search-module)
+               (eq evil-search-module 'evil-search))
+    (user-error "next-match text objects only work with Evil search module."))
+  (let ((pnt (point)))
+    (cond
+     ((eq evil-ex-search-direction 'forward)
+      (unless (eobp) (forward-char))
+      (evil-ex-search-previous 1)
+      (when (and (<= evil-ex-search-match-beg pnt)
+                 (> evil-ex-search-match-end pnt)
+                 (not (evil-visual-state-p)))
+        (setq count (1- count)))
+      (if (> count 0) (evil-ex-search-next count)))
+     (t
+      (unless (eobp) (forward-char))
+      (evil-ex-search-next count))))
+  ;; active visual state if command is executed in normal state
+  (when (evil-normal-state-p)
+    (evil-visual-select evil-ex-search-match-beg evil-ex-search-match-end 'inclusive +1 t))
+  (list evil-ex-search-match-beg evil-ex-search-match-end))
+
+(evil-define-text-object evil-previous-match (count &optional beg end type)
+  "Select next match."
+  (unless (and (boundp 'evil-search-module)
+               (eq evil-search-module 'evil-search))
+    (user-error "previous-match text objects only work with Evil search module."))
+  (let ((evil-ex-search-direction
+         (if (eq evil-ex-search-direction 'backward)
+             'forward
+           'backward)))
+    (evil-next-match count beg end type)))
+
+;;; Operator commands
+
+(evil-define-operator evil-yank (beg end type register yank-handler)
+  "Saves the characters in motion into the kill-ring."
+  :move-point nil
+  :repeat nil
+  (interactive "<R><x><y>")
+  (let ((evil-was-yanked-without-register
+         (and evil-was-yanked-without-register (not register))))
+    (cond
+     ((and (fboundp 'cua--global-mark-active)
+           (fboundp 'cua-copy-region-to-global-mark)
+           (cua--global-mark-active))
+      (cua-copy-region-to-global-mark beg end))
+     ((eq type 'block)
+      (evil-yank-rectangle beg end register yank-handler))
+     ((eq type 'line)
+      (evil-yank-lines beg end register yank-handler))
+     (t
+      (evil-yank-characters beg end register yank-handler)))))
+
+(evil-define-operator evil-yank-line (beg end type register)
+  "Saves whole lines into the kill-ring."
+  :motion evil-line
+  :move-point nil
+  (interactive "<R><x>")
+  (when (evil-visual-state-p)
+    (unless (memq type '(line block))
+      (let ((range (evil-expand beg end 'line)))
+        (setq beg (evil-range-beginning range)
+              end (evil-range-end range)
+              type (evil-type range))))
+    (evil-exit-visual-state))
+  (evil-yank beg end type register))
+
+(evil-define-operator evil-delete (beg end type register yank-handler)
+  "Delete text from BEG to END with TYPE.
+Save in REGISTER or in the kill-ring with YANK-HANDLER."
+  (interactive "<R><x><y>")
+  (unless register
+    (let ((text (filter-buffer-substring beg end)))
+      (unless (string-match-p "\n" text)
+        ;; set the small delete register
+        (evil-set-register ?- text))))
+  (let ((evil-was-yanked-without-register nil))
+    (evil-yank beg end type register yank-handler))
+  (cond
+   ((eq type 'block)
+    (evil-apply-on-block #'delete-region beg end nil))
+   ((and (eq type 'line)
+         (= end (point-max))
+         (or (= beg end)
+             (/= (char-before end) ?\n))
+         (/= beg (point-min))
+         (=  (char-before beg) ?\n))
+    (delete-region (1- beg) end))
+   (t
+    (delete-region beg end)))
+  ;; place cursor on beginning of line
+  (when (and (called-interactively-p 'any)
+             (eq type 'line))
+    (evil-first-non-blank)))
+
+(evil-define-operator evil-delete-line (beg end type register yank-handler)
+  "Delete to end of line."
+  :motion nil
+  :keep-visual t
+  (interactive "<R><x>")
+  ;; act linewise in Visual state
+  (let* ((beg (or beg (point)))
+         (end (or end beg)))
+    (when (evil-visual-state-p)
+      (unless (memq type '(line block))
+        (let ((range (evil-expand beg end 'line)))
+          (setq beg (evil-range-beginning range)
+                end (evil-range-end range)
+                type (evil-type range))))
+      (evil-exit-visual-state))
+    (cond
+     ((eq type 'block)
+      ;; equivalent to $d, i.e., we use the block-to-eol selection and
+      ;; call `evil-delete'. In this case we fake the call to
+      ;; `evil-end-of-line' by setting `temporary-goal-column' and
+      ;; `last-command' appropriately as `evil-end-of-line' would do.
+      (let ((temporary-goal-column most-positive-fixnum)
+            (last-command 'next-line))
+        (evil-delete beg end 'block register yank-handler)))
+     ((eq type 'line)
+      (evil-delete beg end type register yank-handler))
+     (t
+      (evil-delete beg (line-end-position) type register yank-handler)))))
+
+(evil-define-operator evil-delete-whole-line
+  (beg end type register yank-handler)
+  "Delete whole line."
+  :motion evil-line
+  (interactive "<R><x>")
+  (evil-delete beg end type register yank-handler))
+
+(evil-define-operator evil-delete-char (beg end type register)
+  "Delete next character."
+  :motion evil-forward-char
+  (interactive "<R><x>")
+  (evil-delete beg end type register))
+
+(evil-define-operator evil-delete-backward-char (beg end type register)
+  "Delete previous character."
+  :motion evil-backward-char
+  (interactive "<R><x>")
+  (evil-delete beg end type register))
+
+(evil-define-command evil-delete-backward-char-and-join (count)
+  "Delete previous character and join lines.
+If point is at the beginning of a line then the current line will
+be joined with the previous line if and only if
+`evil-backspace-join-lines'."
+  (interactive "p")
+  (if (or evil-backspace-join-lines (not (bolp)))
+      (call-interactively 'delete-backward-char)
+    (user-error "Beginning of line")))
+
+(evil-define-command evil-delete-backward-word ()
+  "Delete previous word."
+  (if (and (bolp) (not (bobp)))
+      (progn
+        (unless evil-backspace-join-lines (user-error "Beginning of line"))
+        (delete-char -1))
+    (delete-region (max
+                    (save-excursion
+                      (evil-backward-word-begin)
+                      (point))
+                    (line-beginning-position))
+                   (point))))
+
+(defun evil-ex-delete-or-yank (should-delete beg end type register count yank-handler)
+  "Execute evil-delete or evil-yank on the given region.
+If SHOULD-DELETE is t, evil-delete will be executed, otherwise
+evil-yank.
+The region specified by BEG and END will be adjusted if COUNT is
+given."
+  (when count
+    ;; with COUNT, the command should go the end of the region and delete/yank
+    ;; COUNT lines from there
+    (setq beg (save-excursion
+                (goto-char end)
+                (forward-line -1)
+                (point))
+          end (save-excursion
+                (goto-char end)
+                (point-at-bol count))
+          type 'line))
+  (funcall (if should-delete 'evil-delete 'evil-yank) beg end type register yank-handler))
+
+(evil-define-operator evil-ex-delete (beg end type register count yank-handler)
+  "The Ex delete command.
+\[BEG,END]delete [REGISTER] [COUNT]"
+  (interactive "<R><xc/><y>")
+  (evil-ex-delete-or-yank t beg end type register count yank-handler))
+
+(evil-define-operator evil-ex-yank (beg end type register count yank-handler)
+  "The Ex yank command.
+\[BEG,END]yank [REGISTER] [COUNT]"
+  (interactive "<R><xc/><y>")
+  (evil-ex-delete-or-yank nil beg end type register count yank-handler))
+
+(evil-define-operator evil-change
+  (beg end type register yank-handler delete-func)
+  "Change text from BEG to END with TYPE.
+Save in REGISTER or the kill-ring with YANK-HANDLER.
+DELETE-FUNC is a function for deleting text, default `evil-delete'.
+If TYPE is `line', insertion starts on an empty line.
+If TYPE is `block', the inserted text in inserted at each line
+of the block."
+  (interactive "<R><x><y>")
+  (let ((delete-func (or delete-func #'evil-delete))
+        (nlines (1+ (evil-count-lines beg end)))
+        (opoint (save-excursion
+                  (goto-char beg)
+                  (line-beginning-position))))
+    (unless (eq evil-want-fine-undo t)
+      (evil-start-undo-step))
+    (funcall delete-func beg end type register yank-handler)
+    (cond
+     ((eq type 'line)
+      (if ( = opoint (point))
+          (evil-open-above 1)
+        (evil-open-below 1)))
+     ((eq type 'block)
+      (evil-insert 1 nlines))
+     (t
+      (evil-insert 1)))))
+
+(evil-define-operator evil-change-line (beg end type register yank-handler)
+  "Change to end of line."
+  :motion evil-end-of-line
+  (interactive "<R><x><y>")
+  (evil-change beg end type register yank-handler #'evil-delete-line))
+
+(evil-define-operator evil-change-whole-line
+  (beg end type register yank-handler)
+  "Change whole line."
+  :motion evil-line
+  (interactive "<R><x>")
+  (evil-change beg end type register yank-handler #'evil-delete-whole-line))
+
+(evil-define-command evil-copy (beg end address)
+  "Copy lines in BEG END below line given by ADDRESS."
+  :motion evil-line
+  (interactive "<r><addr>")
+  (goto-char (point-min))
+  (forward-line address)
+  (let* ((txt (buffer-substring-no-properties beg end))
+         (len (length txt)))
+    ;; ensure text consists of complete lines
+    (when (or (zerop len) (/= (aref txt (1- len)) ?\n))
+      (setq txt (concat txt "\n")))
+    (when (and (eobp) (not (bolp))) (newline)) ; incomplete last line
+    (insert txt)
+    (forward-line -1)))
+
+(evil-define-command evil-move (beg end address)
+  "Move lines in BEG END below line given by ADDRESS."
+  :motion evil-line
+  (interactive "<r><addr>")
+  (goto-char (point-min))
+  (forward-line address)
+  (let* ((m (set-marker (make-marker) (point)))
+         (txt (buffer-substring-no-properties beg end))
+         (len (length txt)))
+    (delete-region beg end)
+    (goto-char m)
+    (set-marker m nil)
+    ;; ensure text consists of complete lines
+    (when (or (zerop len) (/= (aref txt (1- len)) ?\n))
+      (setq txt (concat txt "\n")))
+    (when (and (eobp) (not (bolp))) (newline)) ; incomplete last line
+    (when (evil-visual-state-p)
+      (move-marker evil-visual-mark (point)))
+    (insert txt)
+    (forward-line -1)
+    (when (evil-visual-state-p)
+      (move-marker evil-visual-point (point)))))
+
+(evil-define-operator evil-substitute (beg end type register)
+  "Change a character."
+  :motion evil-forward-char
+  (interactive "<R><x>")
+  (evil-change beg end type register))
+
+(evil-define-operator evil-upcase (beg end type)
+  "Convert text to upper case."
+  (if (eq type 'block)
+      (evil-apply-on-block #'evil-upcase beg end nil)
+    (upcase-region beg end)))
+
+(evil-define-operator evil-downcase (beg end type)
+  "Convert text to lower case."
+  (if (eq type 'block)
+      (evil-apply-on-block #'evil-downcase beg end nil)
+    (downcase-region beg end)))
+
+(evil-define-operator evil-invert-case (beg end type)
+  "Invert case of text."
+  (let (char)
+    (if (eq type 'block)
+        (evil-apply-on-block #'evil-invert-case beg end nil)
+      (save-excursion
+        (goto-char beg)
+        (while (< beg end)
+          (setq char (following-char))
+          (delete-char 1 nil)
+          (if (eq (upcase char) char)
+              (insert-char (downcase char) 1)
+            (insert-char (upcase char) 1))
+          (setq beg (1+ beg)))))))
+
+(evil-define-operator evil-invert-char (beg end type)
+  "Invert case of character."
+  :motion evil-forward-char
+  (if (eq type 'block)
+      (evil-apply-on-block #'evil-invert-case beg end nil)
+    (evil-invert-case beg end)
+    (when evil-this-motion
+      (goto-char end)
+      (when (and evil-cross-lines
+                 evil-move-cursor-back
+                 (not evil-move-beyond-eol)
+                 (not (evil-visual-state-p))
+                 (not (evil-operator-state-p))
+                 (eolp) (not (eobp)) (not (bolp)))
+        (forward-char)))))
+
+(evil-define-operator evil-rot13 (beg end type)
+  "ROT13 encrypt text."
+  (if (eq type 'block)
+      (evil-apply-on-block #'evil-rot13 beg end nil)
+    (rot13-region beg end)))
+
+(evil-define-operator evil-join (beg end)
+  "Join the selected lines."
+  :motion evil-line
+  (let ((count (count-lines beg end)))
+    (when (> count 1)
+      (setq count (1- count)))
+    (goto-char beg)
+    (dotimes (var count)
+      (join-line 1))))
+
+(evil-define-operator evil-join-whitespace (beg end)
+  "Join the selected lines without changing whitespace.
+\\<evil-normal-state-map>Like \\[evil-join], \
+but doesn't insert or remove any spaces."
+  :motion evil-line
+  (let ((count (count-lines beg end)))
+    (when (> count 1)
+      (setq count (1- count)))
+    (goto-char beg)
+    (dotimes (var count)
+      (evil-move-end-of-line 1)
+      (unless (eobp)
+        (delete-char 1)))))
+
+(evil-define-operator evil-ex-join (beg end &optional count bang)
+  "Join the selected lines with optional COUNT and BANG."
+  (interactive "<r><a><!>")
+  (if (and count (not (string-match-p "^[1-9][0-9]*$" count)))
+      (user-error "Invalid count")
+    (let ((join-fn (if bang 'evil-join-whitespace 'evil-join)))
+      (cond
+       ((not count)
+        ;; without count - just join the given region
+        (funcall join-fn beg end))
+       (t
+        ;; emulate vim's :join when count is given - start from the
+        ;; end of the region and join COUNT lines from there
+        (let* ((count-num (string-to-number count))
+               (beg-adjusted (save-excursion
+                               (goto-char end)
+                               (forward-line -1)
+                               (point)))
+               (end-adjusted (save-excursion
+                               (goto-char end)
+                               (point-at-bol count-num))))
+          (funcall join-fn beg-adjusted end-adjusted)))))))
+
+(evil-define-operator evil-fill (beg end)
+  "Fill text."
+  :move-point nil
+  :type line
+  (save-excursion
+    (condition-case nil
+        (fill-region beg end)
+      (error nil))))
+
+(evil-define-operator evil-fill-and-move (beg end)
+  "Fill text and move point to the end of the filled region."
+  :move-point nil
+  :type line
+  (let ((marker (make-marker)))
+    (move-marker marker (1- end))
+    (condition-case nil
+        (progn
+          (fill-region beg end)
+          (goto-char marker)
+          (evil-first-non-blank))
+      (error nil))))
+
+(evil-define-operator evil-indent (beg end)
+  "Indent text."
+  :move-point nil
+  :type line
+  (if (and (= beg (line-beginning-position))
+           (= end (line-beginning-position 2)))
+      ;; since some Emacs modes can only indent one line at a time,
+      ;; implement "==" as a call to `indent-according-to-mode'
+      (indent-according-to-mode)
+    (goto-char beg)
+    (indent-region beg end))
+  ;; We also need to tabify or untabify the leading white characters
+  (when evil-indent-convert-tabs
+    (let* ((beg-line (line-number-at-pos beg))
+           (end-line (line-number-at-pos end))
+           (ln beg-line)
+           (convert-white (if indent-tabs-mode 'tabify 'untabify)))
+      (save-excursion
+        (while (<= ln end-line)
+          (goto-char (point-min))
+          (forward-line (- ln 1))
+          (back-to-indentation)
+          ;; Whether tab or space should be used is determined by indent-tabs-mode
+          (funcall convert-white (line-beginning-position) (point))
+          (setq ln (1+ ln)))))
+    (back-to-indentation)))
+
+(evil-define-operator evil-indent-line (beg end)
+  "Indent the line."
+  :motion evil-line
+  (evil-indent beg end))
+
+(evil-define-operator evil-shift-left (beg end &optional count preserve-empty)
+  "Shift text from BEG to END to the left.
+The text is shifted to the nearest multiple of `evil-shift-width'
+\(the rounding can be disabled by setting `evil-shift-round').
+If PRESERVE-EMPTY is non-nil, lines that contain only spaces are
+indented, too, otherwise they are ignored.  The relative column
+of point is preserved if this function is not called
+interactively. Otherwise, if the function is called as an
+operator, point is moved to the first non-blank character.
+See also `evil-shift-right'."
+  :type line
+  (interactive "<r><vc>")
+  (evil-shift-right beg end (- (or count 1)) preserve-empty))
+
+(evil-define-operator evil-shift-right (beg end &optional count preserve-empty)
+  "Shift text from BEG to END to the right.
+The text is shifted to the nearest multiple of `evil-shift-width'
+\(the rounding can be disabled by setting `evil-shift-round').
+If PRESERVE-EMPTY is non-nil, lines that contain only spaces are
+indented, too, otherwise they are ignored.  The relative column
+of point is preserved if this function is not called
+interactively. Otherwise, if the function is called as an
+operator, point is moved to the first non-blank character.
+See also `evil-shift-left'."
+  :type line
+  (interactive "<r><vc>")
+  (setq count (or count 1))
+  (let ((beg (set-marker (make-marker) beg))
+        (end (set-marker (make-marker) end))
+        (pnt-indent (current-column))
+        first-shift) ; shift of first line
+    (save-excursion
+      (goto-char beg)
+      (while (< (point) end)
+        (let* ((indent (current-indentation))
+               (new-indent
+                (max 0
+                     (if (not evil-shift-round)
+                         (+ indent (* count evil-shift-width))
+                       (* (+ (/ indent evil-shift-width)
+                             count
+                             (cond
+                              ((> count 0) 0)
+                              ((zerop (mod indent evil-shift-width)) 0)
+                              (t 1)))
+                          evil-shift-width)))))
+          (unless first-shift
+            (setq first-shift (- new-indent indent)))
+          (when (or preserve-empty
+                    (save-excursion
+                      (skip-chars-forward " \t")
+                      (not (eolp))))
+            (indent-to new-indent 0))
+          (delete-region (point) (progn (skip-chars-forward " \t") (point)))
+          (forward-line 1))))
+    ;; assuming that point is in the first line, adjust its position
+    (if (called-interactively-p 'any)
+        (evil-first-non-blank)
+      (move-to-column (max 0 (+ pnt-indent first-shift))))))
+
+(evil-define-command evil-shift-right-line (count)
+  "Shift the current line COUNT times to the right.
+The text is shifted to the nearest multiple of
+`evil-shift-width'. Like `evil-shift-right' but always works on
+the current line."
+  (interactive "<c>")
+  (evil-shift-right (line-beginning-position) (line-beginning-position 2) count t))
+
+(evil-define-command evil-shift-left-line (count)
+  "Shift the current line COUNT times to the left.
+The text is shifted to the nearest multiple of
+`evil-shift-width'. Like `evil-shift-left' but always works on
+the current line."
+  (interactive "<c>")
+  (evil-shift-left (line-beginning-position) (line-beginning-position 2) count t))
+
+(evil-define-operator evil-align-left (beg end type &optional width)
+  "Right-align lines in the region at WIDTH columns.
+The default for width is the value of `fill-column'."
+  :motion evil-line
+  :type line
+  (interactive "<R><a>")
+  (evil-justify-lines beg end 'left (if width
+                                        (string-to-number width)
+                                      0)))
+
+(evil-define-operator evil-align-right (beg end type &optional width)
+  "Right-align lines in the region at WIDTH columns.
+The default for width is the value of `fill-column'."
+  :motion evil-line
+  :type line
+  (interactive "<R><a>")
+  (evil-justify-lines beg end 'right (if width
+                                         (string-to-number width)
+                                       fill-column)))
+
+(evil-define-operator evil-align-center (beg end type &optional width)
+  "Centers lines in the region between WIDTH columns.
+The default for width is the value of `fill-column'."
+  :motion evil-line
+  :type line
+  (interactive "<R><a>")
+  (evil-justify-lines beg end 'center (if width
+                                          (string-to-number width)
+                                        fill-column)))
+
+(evil-define-operator evil-replace (beg end type char)
+  "Replace text from BEG to END with CHAR."
+  :motion evil-forward-char
+  (interactive "<R>"
+               (unwind-protect
+                   (let ((evil-force-cursor 'replace))
+                     (evil-refresh-cursor)
+                     (list (evil-read-key)))
+                 (evil-refresh-cursor)))
+  (when char
+    (if (eq type 'block)
+        (save-excursion
+          (evil-apply-on-rectangle
+           #'(lambda (begcol endcol char)
+               (let ((maxcol (evil-column (line-end-position))))
+                 (when (< begcol maxcol)
+                   (setq endcol (min endcol maxcol))
+                   (let ((beg (evil-move-to-column begcol nil t))
+                         (end (evil-move-to-column endcol nil t)))
+                     (delete-region beg end)
+                     (insert (make-string (- endcol begcol) char))))))
+           beg end char))
+      (goto-char beg)
+      (cond
+       ((eq char ?\n)
+        (delete-region beg end)
+        (newline)
+        (when evil-auto-indent
+          (indent-according-to-mode)))
+       (t
+        (while (< (point) end)
+          (if (eq (char-after) ?\n)
+              (forward-char)
+            (delete-char 1)
+            (insert-char char 1)))
+        (goto-char (max beg (1- end))))))))
+
+(evil-define-command evil-paste-before
+  (count &optional register yank-handler)
+  "Pastes the latest yanked text before the cursor position.
+The return value is the yanked text."
+  :suppress-operator t
+  (interactive "P<x>")
+  (if (evil-visual-state-p)
+      (evil-visual-paste count register)
+    (evil-with-undo
+      (let* ((text (if register
+                       (evil-get-register register)
+                     (current-kill 0)))
+             (yank-handler (or yank-handler
+                               (when (stringp text)
+                                 (car-safe (get-text-property
+                                            0 'yank-handler text)))))
+             (opoint (point)))
+        (when text
+          (if (functionp yank-handler)
+              (let ((evil-paste-count count)
+                    ;; for non-interactive use
+                    (this-command #'evil-paste-before))
+                (push-mark opoint t)
+                (insert-for-yank text))
+            ;; no yank-handler, default
+            (when (vectorp text)
+              (setq text (evil-vector-to-string text)))
+            (set-text-properties 0 (length text) nil text)
+            (push-mark opoint t)
+            (dotimes (i (or count 1))
+              (insert-for-yank text))
+            (setq evil-last-paste
+                  (list #'evil-paste-before
+                        count
+                        opoint
+                        opoint    ; beg
+                        (point))) ; end
+            (evil-set-marker ?\[ opoint)
+            (evil-set-marker ?\] (1- (point)))
+            (when (and evil-move-cursor-back
+                       (> (length text) 0))
+              (backward-char))))
+        ;; no paste-pop after pasting from a register
+        (when register
+          (setq evil-last-paste nil))
+        (and (> (length text) 0) text)))))
+
+(evil-define-command evil-paste-after
+  (count &optional register yank-handler)
+  "Pastes the latest yanked text behind point.
+The return value is the yanked text."
+  :suppress-operator t
+  (interactive "P<x>")
+  (if (evil-visual-state-p)
+      (evil-visual-paste count register)
+    (evil-with-undo
+      (let* ((text (if register
+                       (evil-get-register register)
+                     (current-kill 0)))
+             (yank-handler (or yank-handler
+                               (when (stringp text)
+                                 (car-safe (get-text-property
+                                            0 'yank-handler text)))))
+             (opoint (point)))
+        (when text
+          (if (functionp yank-handler)
+              (let ((evil-paste-count count)
+                    ;; for non-interactive use
+                    (this-command #'evil-paste-after))
+                (insert-for-yank text))
+            ;; no yank-handler, default
+            (when (vectorp text)
+              (setq text (evil-vector-to-string text)))
+            (set-text-properties 0 (length text) nil text)
+            (unless (eolp) (forward-char))
+            (push-mark (point) t)
+            ;; TODO: Perhaps it is better to collect a list of all
+            ;; (point . mark) pairs to undo the yanking for COUNT > 1.
+            ;; The reason is that this yanking could very well use
+            ;; `yank-handler'.
+            (let ((beg (point)))
+              (dotimes (i (or count 1))
+                (insert-for-yank text))
+              (setq evil-last-paste
+                    (list #'evil-paste-after
+                          count
+                          opoint
+                          beg       ; beg
+                          (point))) ; end
+              (evil-set-marker ?\[ beg)
+              (evil-set-marker ?\] (1- (point)))
+              (when (evil-normal-state-p)
+                (evil-move-cursor-back)))))
+        (when register
+          (setq evil-last-paste nil))
+        (and (> (length text) 0) text)))))
+
+(evil-define-command evil-visual-paste (count &optional register)
+  "Paste over Visual selection."
+  :suppress-operator t
+  (interactive "P<x>")
+  ;; evil-visual-paste is typically called from evil-paste-before or
+  ;; evil-paste-after, but we have to mark that the paste was from
+  ;; visual state
+  (setq this-command 'evil-visual-paste)
+  (let* ((text (if register
+                   (evil-get-register register)
+                 (current-kill 0)))
+         (yank-handler (car-safe (get-text-property
+                                  0 'yank-handler text)))
+         new-kill
+         paste-eob)
+    (evil-with-undo
+      (let* ((kill-ring (list (current-kill 0)))
+             (kill-ring-yank-pointer kill-ring))
+        (when (evil-visual-state-p)
+          (evil-visual-rotate 'upper-left)
+          ;; if we replace the last buffer line that does not end in a
+          ;; newline, we use `evil-paste-after' because `evil-delete'
+          ;; will move point to the line above
+          (when (and (= evil-visual-end (point-max))
+                     (/= (char-before (point-max)) ?\n))
+            (setq paste-eob t))
+          (evil-delete evil-visual-beginning evil-visual-end
+                       (evil-visual-type))
+          (when (and (eq yank-handler #'evil-yank-line-handler)
+                     (not (eq (evil-visual-type) 'line))
+                     (not (= evil-visual-end (point-max))))
+            (insert "\n"))
+          (evil-normal-state)
+          (setq new-kill (current-kill 0))
+          (current-kill 1))
+        (if paste-eob
+            (evil-paste-after count register)
+          (evil-paste-before count register)))
+      (when evil-kill-on-visual-paste
+        (kill-new new-kill))
+      ;; mark the last paste as visual-paste
+      (setq evil-last-paste
+            (list (nth 0 evil-last-paste)
+                  (nth 1 evil-last-paste)
+                  (nth 2 evil-last-paste)
+                  (nth 3 evil-last-paste)
+                  (nth 4 evil-last-paste)
+                  t)))))
+
+(defun evil-paste-from-register (register)
+  "Paste from REGISTER."
+  (interactive
+   (let ((overlay (make-overlay (point) (point)))
+         (string "\""))
+     (unwind-protect
+         (progn
+           ;; display " in the buffer while reading register
+           (put-text-property 0 1 'face 'minibuffer-prompt string)
+           (put-text-property 0 1 'cursor t string)
+           (overlay-put overlay 'after-string string)
+           (list (or evil-this-register (read-char))))
+       (delete-overlay overlay))))
+  (when (evil-paste-before nil register t)
+    ;; go to end of pasted text
+    (unless (eobp)
+      (forward-char))))
+
+(defun evil-paste-last-insertion ()
+  "Paste last insertion."
+  (interactive)
+  (evil-paste-from-register ?.))
+
+(evil-define-command evil-use-register (register)
+  "Use REGISTER for the next command."
+  :keep-visual t
+  :repeat ignore
+  (interactive "<C>")
+  (setq evil-this-register register))
+
+(defvar evil-macro-buffer nil
+  "The buffer that has been active on macro recording.")
+
+(evil-define-command evil-record-macro (register)
+  "Record a keyboard macro into REGISTER.
+If REGISTER is :, /, or ?, the corresponding command line window
+will be opened instead."
+  :keep-visual t
+  :suppress-operator t
+  (interactive
+   (list (unless (and evil-this-macro defining-kbd-macro)
+           (or evil-this-register (evil-read-key)))))
+  (cond
+   ((eq register ?\C-g)
+    (keyboard-quit))
+   ((and evil-this-macro defining-kbd-macro)
+    (setq evil-macro-buffer nil)
+    (condition-case nil
+        (end-kbd-macro)
+      (error nil))
+    (when last-kbd-macro
+      (when (member last-kbd-macro '("" []))
+        (setq last-kbd-macro nil))
+      (evil-set-register evil-this-macro last-kbd-macro))
+    (setq evil-this-macro nil))
+   ((eq register ?:)
+    (evil-command-window-ex))
+   ((eq register ?/)
+    (evil-command-window-search-forward))
+   ((eq register ??)
+    (evil-command-window-search-backward))
+   ((or (and (>= register ?0) (<= register ?9))
+        (and (>= register ?a) (<= register ?z))
+        (and (>= register ?A) (<= register ?Z)))
+    (when defining-kbd-macro (end-kbd-macro))
+    (setq evil-this-macro register)
+    (evil-set-register evil-this-macro nil)
+    (start-kbd-macro nil)
+    (setq evil-macro-buffer (current-buffer)))
+   (t (error "Invalid register"))))
+
+(evil-define-command evil-execute-macro (count macro)
+  "Execute keyboard macro MACRO, COUNT times.
+When called with a non-numerical prefix \
+\(such as \\[universal-argument]),
+COUNT is infinite. MACRO is read from a register
+when called interactively."
+  :keep-visual t
+  :suppress-operator t
+  (interactive
+   (let (count macro register)
+     (setq count (if current-prefix-arg
+                     (if (numberp current-prefix-arg)
+                         current-prefix-arg
+                       0) 1)
+           register (or evil-this-register (read-char)))
+     (cond
+      ((or (and (eq register ?@) (eq evil-last-register ?:))
+           (eq register ?:))
+       (setq macro (lambda () (evil-ex-repeat nil))
+             evil-last-register ?:))
+      ((eq register ?@)
+       (unless evil-last-register
+         (user-error "No previously executed keyboard macro."))
+       (setq macro (evil-get-register evil-last-register t)))
+      (t
+       (setq macro (evil-get-register register t)
+             evil-last-register register)))
+     (list count macro)))
+  (cond
+   ((functionp macro)
+    (evil-repeat-abort)
+    (dotimes (i (or count 1))
+      (funcall macro)))
+   ((or (and (not (stringp macro))
+             (not (vectorp macro)))
+        (member macro '("" [])))
+    ;; allow references to currently empty registers
+    ;; when defining macro
+    (unless evil-this-macro
+      (user-error "No previous macro")))
+   (t
+    (condition-case err
+        (evil-with-single-undo
+          (execute-kbd-macro macro count))
+      ;; enter Normal state if the macro fails
+      (error
+       (evil-normal-state)
+       (evil-normalize-keymaps)
+       (signal (car err) (cdr err)))))))
+
+;;; Visual commands
+
+(evil-define-motion evil-visual-restore ()
+  "Restore previous selection."
+  (let* ((point (point))
+         (mark (or (mark t) point))
+         (dir evil-visual-direction)
+         (type (evil-visual-type))
+         range)
+    (unless (evil-visual-state-p)
+      (cond
+       ;; No previous selection.
+       ((or (null evil-visual-selection)
+            (null evil-visual-mark)
+            (null evil-visual-point)))
+       ;; If the type was one-to-one, it is preferable to infer
+       ;; point and mark from the selection's boundaries. The reason
+       ;; is that a destructive operation may displace the markers
+       ;; inside the selection.
+       ((evil-type-property type :one-to-one)
+        (setq range (evil-contract-range (evil-visual-range))
+              mark (evil-range-beginning range)
+              point (evil-range-end range))
+        (when (< dir 0)
+          (evil-swap mark point)))
+       ;; If the type wasn't one-to-one, we have to restore the
+       ;; selection on the basis of the previous point and mark.
+       (t
+        (setq mark evil-visual-mark
+              point evil-visual-point)))
+      (evil-visual-make-selection mark point type t))))
+
+(evil-define-motion evil-visual-exchange-corners ()
+  "Rearrange corners in Visual Block mode.
+
+        M---+           +---M
+        |   |    <=>    |   |
+        +---P           P---+
+
+For example, if mark is in the upper left corner and point
+in the lower right, this function puts mark in the upper right
+corner and point in the lower left."
+  (cond
+   ((eq evil-visual-selection 'block)
+    (let* ((point (point))
+           (mark (or (mark t) point))
+           (point-col (evil-column point))
+           (mark-col (evil-column mark))
+           (mark (save-excursion
+                   (goto-char mark)
+                   (evil-move-to-column point-col)
+                   (point)))
+           (point (save-excursion
+                    (goto-char point)
+                    (evil-move-to-column mark-col)
+                    (point))))
+      (evil-visual-refresh mark point)))
+   (t
+    (evil-exchange-point-and-mark)
+    (evil-visual-refresh))))
+
+(evil-define-command evil-visual-rotate (corner &optional beg end type)
+  "In Visual Block selection, put point in CORNER.
+Corner may be one of `upper-left', `upper-right', `lower-left'
+and `lower-right':
+
+        upper-left +---+ upper-right
+                   |   |
+        lower-left +---+ lower-right
+
+When called interactively, the selection is rotated blockwise."
+  :keep-visual t
+  (interactive
+   (let ((corners '(upper-left upper-right lower-right lower-left)))
+     (list (or (cadr (memq (evil-visual-block-corner) corners))
+               'upper-left))))
+  (let* ((beg (or beg (point)))
+         (end (or end (mark t) beg))
+         (type (or type evil-this-type))
+         range)
+    (cond
+     ((memq type '(rectangle block))
+      (setq range (evil-block-rotate beg end :corner corner)
+            beg (pop range)
+            end (pop range))
+      (unless (eq corner (evil-visual-block-corner corner beg end))
+        (evil-swap beg end))
+      (goto-char beg)
+      (when (evil-visual-state-p)
+        (evil-move-mark end)
+        (evil-visual-refresh nil nil nil :corner corner)))
+     ((memq corner '(upper-right lower-right))
+      (goto-char (max beg end))
+      (when (evil-visual-state-p)
+        (evil-move-mark (min beg end))))
+     (t
+      (goto-char (min beg end))
+      (when (evil-visual-state-p)
+        (evil-move-mark (max beg end)))))))
+
+;;; Insertion commands
+
+(defun evil-insert (count &optional vcount skip-empty-lines)
+  "Switch to Insert state just before point.
+The insertion will be repeated COUNT times and repeated once for
+the next VCOUNT - 1 lines starting at the same column.
+If SKIP-EMPTY-LINES is non-nil, the insertion will not be performed
+on lines on which the insertion point would be after the end of the
+lines.  This is the default behaviour for Visual-state insertion."
+  (interactive
+   (list (prefix-numeric-value current-prefix-arg)
+         (and (evil-visual-state-p)
+              (memq (evil-visual-type) '(line block))
+              (save-excursion
+                (let ((m (mark)))
+                  ;; go to upper-left corner temporarily so
+                  ;; `count-lines' yields accurate results
+                  (evil-visual-rotate 'upper-left)
+                  (prog1 (count-lines evil-visual-beginning evil-visual-end)
+                    (set-mark m)))))
+         (evil-visual-state-p)))
+  (if (and (called-interactively-p 'any)
+           (evil-visual-state-p))
+      (cond
+       ((eq (evil-visual-type) 'line)
+        (evil-visual-rotate 'upper-left)
+        (evil-insert-line count vcount))
+       ((eq (evil-visual-type) 'block)
+        (let ((column (min (evil-column evil-visual-beginning)
+                           (evil-column evil-visual-end))))
+          (evil-visual-rotate 'upper-left)
+          (move-to-column column t)
+          (evil-insert count vcount skip-empty-lines)))
+       (t
+        (evil-visual-rotate 'upper-left)
+        (evil-insert count vcount skip-empty-lines)))
+    (setq evil-insert-count count
+          evil-insert-lines nil
+          evil-insert-vcount (and vcount
+                                  (> vcount 1)
+                                  (list (line-number-at-pos)
+                                        (current-column)
+                                        vcount))
+          evil-insert-skip-empty-lines skip-empty-lines)
+    (evil-insert-state 1)))
+
+(defun evil-append (count &optional vcount skip-empty-lines)
+  "Switch to Insert state just after point.
+The insertion will be repeated COUNT times and repeated once for
+the next VCOUNT - 1 lines starting at the same column.  If
+SKIP-EMPTY-LINES is non-nil, the insertion will not be performed
+on lines on which the insertion point would be after the end of
+the lines."
+  (interactive
+   (list (prefix-numeric-value current-prefix-arg)
+         (and (evil-visual-state-p)
+              (memq (evil-visual-type) '(line block))
+              (save-excursion
+                (let ((m (mark)))
+                  ;; go to upper-left corner temporarily so
+                  ;; `count-lines' yields accurate results
+                  (evil-visual-rotate 'upper-left)
+                  (prog1 (count-lines evil-visual-beginning evil-visual-end)
+                    (set-mark m)))))))
+  (if (and (called-interactively-p 'any)
+           (evil-visual-state-p))
+      (cond
+       ((or (eq (evil-visual-type) 'line)
+            (and (eq (evil-visual-type) 'block)
+                 (memq last-command '(next-line previous-line))
+                 (numberp temporary-goal-column)
+                 (= temporary-goal-column most-positive-fixnum)))
+        (evil-visual-rotate 'upper-left)
+        (evil-append-line count vcount))
+       ((eq (evil-visual-type) 'block)
+        (let ((column (max (evil-column evil-visual-beginning)
+                           (evil-column evil-visual-end))))
+          (evil-visual-rotate 'upper-left)
+          (move-to-column column t)
+          (evil-insert count vcount skip-empty-lines)))
+       (t
+        (evil-visual-rotate 'lower-right)
+        (evil-append count)))
+    (unless (eolp) (forward-char))
+    (evil-insert count vcount skip-empty-lines)
+    (add-hook 'post-command-hook #'evil-maybe-remove-spaces)))
+
+(defun evil-insert-resume (count)
+  "Switch to Insert state at previous insertion point.
+The insertion will be repeated COUNT times. If called from visual
+state, only place point at the previous insertion position but do not
+switch to insert state."
+  (interactive "p")
+  (evil-goto-mark ?^ t)
+  (unless (evil-visual-state-p)
+    (evil-insert count)))
+
+(defun evil-open-above (count)
+  "Insert a new line above point and switch to Insert state.
+The insertion will be repeated COUNT times."
+  (interactive "p")
+  (unless (eq evil-want-fine-undo t)
+    (evil-start-undo-step))
+  (evil-insert-newline-above)
+  (setq evil-insert-count count
+        evil-insert-lines t
+        evil-insert-vcount nil)
+  (evil-insert-state 1)
+  (when evil-auto-indent
+    (indent-according-to-mode)))
+
+(defun evil-open-below (count)
+  "Insert a new line below point and switch to Insert state.
+The insertion will be repeated COUNT times."
+  (interactive "p")
+  (unless (eq evil-want-fine-undo t)
+    (evil-start-undo-step))
+  (push (point) buffer-undo-list)
+  (evil-insert-newline-below)
+  (setq evil-insert-count count
+        evil-insert-lines t
+        evil-insert-vcount nil)
+  (evil-insert-state 1)
+  (when evil-auto-indent
+    (indent-according-to-mode)))
+
+(defun evil-insert-line (count &optional vcount)
+  "Switch to insert state at beginning of current line.
+Point is placed at the first non-blank character on the current
+line.  The insertion will be repeated COUNT times.  If VCOUNT is
+non nil it should be number > 0. The insertion will be repeated
+in the next VCOUNT - 1 lines below the current one."
+  (interactive "p")
+  (push (point) buffer-undo-list)
+  (back-to-indentation)
+  (setq evil-insert-count count
+        evil-insert-lines nil
+        evil-insert-vcount
+        (and vcount
+             (> vcount 1)
+             (list (line-number-at-pos)
+                   #'evil-first-non-blank
+                   vcount)))
+  (evil-insert-state 1))
+
+(defun evil-append-line (count &optional vcount)
+  "Switch to Insert state at the end of the current line.
+The insertion will be repeated COUNT times.  If VCOUNT is non nil
+it should be number > 0. The insertion will be repeated in the
+next VCOUNT - 1 lines below the current one."
+  (interactive "p")
+  (evil-move-end-of-line)
+  (setq evil-insert-count count
+        evil-insert-lines nil
+        evil-insert-vcount
+        (and vcount
+             (> vcount 1)
+             (list (line-number-at-pos)
+                   #'end-of-line
+                   vcount)))
+  (evil-insert-state 1))
+
+(evil-define-command evil-insert-digraph (count)
+  "Insert COUNT digraphs."
+  :repeat change
+  (interactive "p")
+  (let ((digraph (evil-read-digraph-char 0)))
+    (insert-char digraph count)))
+
+(evil-define-command evil-ex-show-digraphs ()
+  "Shows a list of all available digraphs."
+  :repeat nil
+  (let ((columns 3))
+    (evil-with-view-list
+      :name "evil-digraphs"
+      :mode-name "Evil Digraphs"
+      :format
+      (cl-loop repeat columns
+               vconcat [("Digraph" 8 nil)
+                        ("Sequence" 16 nil)])
+      :entries
+      (let* ((digraphs (mapcar #'(lambda (digraph)
+                                   (cons (cdr digraph)
+                                         (car digraph)))
+                               (append evil-digraphs-table
+                                       evil-digraphs-table-user)))
+             (entries (cl-loop for digraph in digraphs
+                               collect `(,(concat (char-to-string (nth 1 digraph))
+                                                  (char-to-string (nth 2 digraph)))
+                                         ,(char-to-string (nth 0 digraph)))))
+             (row)
+             (rows)
+             (clength (* columns 2)))
+        (cl-loop for e in entries
+                 do
+                 (push (nth 0 e) row)
+                 (push (nth 1 e) row)
+                 (when (eq (length row) clength)
+                   (push `(nil ,(apply #'vector row)) rows)
+                   (setq row nil)))
+        rows))))
+
+(defun evil--self-insert-string (string)
+  "Insert STRING as if typed interactively."
+  (let ((chars (append string nil)))
+    (dolist (char chars)
+      (let ((last-command-event char))
+        (self-insert-command 1)))))
+
+(defun evil-copy-from-above (arg)
+  "Copy characters from preceding non-blank line.
+The copied text is inserted before point.
+ARG is the number of lines to move backward.
+See also \\<evil-insert-state-map>\\[evil-copy-from-below]."
+  (interactive
+   (cond
+    ;; if a prefix argument was given, repeat it for subsequent calls
+    ((and (null current-prefix-arg)
+          (eq last-command #'evil-copy-from-above))
+     (setq current-prefix-arg last-prefix-arg)
+     (list (prefix-numeric-value current-prefix-arg)))
+    (t
+     (list (prefix-numeric-value current-prefix-arg)))))
+  (evil--self-insert-string (evil-copy-chars-from-line arg -1)))
+
+(defun evil-copy-from-below (arg)
+  "Copy characters from following non-blank line.
+The copied text is inserted before point.
+ARG is the number of lines to move forward.
+See also \\<evil-insert-state-map>\\[evil-copy-from-above]."
+  (interactive
+   (cond
+    ((and (null current-prefix-arg)
+          (eq last-command #'evil-copy-from-below))
+     (setq current-prefix-arg last-prefix-arg)
+     (list (prefix-numeric-value current-prefix-arg)))
+    (t
+     (list (prefix-numeric-value current-prefix-arg)))))
+  (evil--self-insert-string (evil-copy-chars-from-line arg 1)))
+
+;; adapted from `copy-from-above-command' in misc.el
+(defun evil-copy-chars-from-line (n num &optional col)
+  "Return N characters from line NUM, starting at column COL.
+NUM is relative to the current line and can be negative.
+COL defaults to the current column."
+  (interactive "p")
+  (let ((col (or col (current-column))) prefix)
+    (save-excursion
+      (forward-line num)
+      (when (looking-at "[[:space:]]*$")
+        (if (< num 0)
+            (skip-chars-backward " \t\n")
+          (skip-chars-forward " \t\n")))
+      (evil-move-beginning-of-line)
+      (move-to-column col)
+      ;; if the column winds up in middle of a tab,
+      ;; return the appropriate number of spaces
+      (when (< col (current-column))
+        (if (eq (preceding-char) ?\t)
+            (let ((len (min n (- (current-column) col))))
+              (setq prefix (make-string len ?\s)
+                    n (- n len)))
+          ;; if in middle of a control char, return the whole char
+          (backward-char 1)))
+      (concat prefix
+              (buffer-substring (point)
+                                (min (line-end-position)
+                                     (+ n (point))))))))
+
+;; completion
+(evil-define-command evil-complete-next (&optional arg)
+  "Complete to the nearest following word.
+Search backward if a match isn't found.
+Calls `evil-complete-next-func'."
+  :repeat change
+  (interactive "P")
+  (if (minibufferp)
+      (funcall evil-complete-next-minibuffer-func)
+    (funcall evil-complete-next-func arg)))
+
+(evil-define-command evil-complete-previous (&optional arg)
+  "Complete to the nearest preceding word.
+Search forward if a match isn't found.
+Calls `evil-complete-previous-func'."
+  :repeat change
+  (interactive "P")
+  (if (minibufferp)
+      (funcall evil-complete-previous-minibuffer-func)
+    (funcall evil-complete-previous-func arg)))
+
+(evil-define-command evil-complete-next-line (&optional arg)
+  "Complete a whole line.
+Calls `evil-complete-next-line-func'."
+  :repeat change
+  (interactive "P")
+  (if (minibufferp)
+      (funcall evil-complete-next-minibuffer-func)
+    (funcall evil-complete-next-line-func arg)))
+
+(evil-define-command evil-complete-previous-line (&optional arg)
+  "Complete a whole line.
+Calls `evil-complete-previous-line-func'."
+  :repeat change
+  (interactive "P")
+  (if (minibufferp)
+      (funcall evil-complete-previous-minibuffer-func)
+    (funcall evil-complete-previous-line-func arg)))
+
+;;; Search
+
+(defun evil-repeat-search (flag)
+  "Called to record a search command.
+FLAG is either 'pre or 'post if the function is called before resp.
+after executing the command."
+  (cond
+   ((and (evil-operator-state-p) (eq flag 'pre))
+    (evil-repeat-record (this-command-keys))
+    (evil-clear-command-keys))
+   ((and (evil-operator-state-p) (eq flag 'post))
+    ;; The value of (this-command-keys) at this point should be the
+    ;; key-sequence that called the last command that finished the
+    ;; search, usually RET. Therefore this key-sequence will be
+    ;; recorded in the post-command of the operator. Alternatively we
+    ;; could do it here.
+    (evil-repeat-record (if evil-regexp-search
+                            (car-safe regexp-search-ring)
+                          (car-safe search-ring))))
+   (t (evil-repeat-motion flag))))
+
+(evil-define-motion evil-search-forward ()
+  (format "Search forward for user-entered text.
+Searches for regular expression if `evil-regexp-search' is t.%s"
+          (if (and (fboundp 'isearch-forward)
+                   (documentation 'isearch-forward))
+              (format "\n\nBelow is the documentation string \
+for `isearch-forward',\nwhich lists available keys:\n\n%s"
+                      (documentation 'isearch-forward)) ""))
+  :jump t
+  :type exclusive
+  :repeat evil-repeat-search
+  (evil-search-incrementally t evil-regexp-search))
+
+(evil-define-motion evil-search-backward ()
+  (format "Search backward for user-entered text.
+Searches for regular expression if `evil-regexp-search' is t.%s"
+          (if (and (fboundp 'isearch-forward)
+                   (documentation 'isearch-forward))
+              (format "\n\nBelow is the documentation string \
+for `isearch-forward',\nwhich lists available keys:\n\n%s"
+                      (documentation 'isearch-forward)) ""))
+  :jump t
+  :type exclusive
+  :repeat evil-repeat-search
+  (evil-search-incrementally nil evil-regexp-search))
+
+(evil-define-motion evil-search-next (count)
+  "Repeat the last search."
+  :jump t
+  :type exclusive
+  (let ((orig (point))
+        (search-string (if evil-regexp-search
+                           (car-safe regexp-search-ring)
+                         (car-safe search-ring))))
+    (goto-char
+     ;; Wrap in `save-excursion' so that multiple searches have no visual effect.
+     (save-excursion
+       (evil-search search-string isearch-forward evil-regexp-search)
+       (when (and (> (point) orig)
+                  (save-excursion
+                    (evil-adjust-cursor)
+                    (= (point) orig)))
+         ;; Point won't move after first attempt and `evil-adjust-cursor' takes
+         ;; effect, so start again.
+         (evil-search search-string isearch-forward evil-regexp-search))
+       (point)))
+    (when (and count (> count 1))
+      (dotimes (var (1- count))
+        (evil-search search-string isearch-forward evil-regexp-search)))))
+
+(evil-define-motion evil-search-previous (count)
+  "Repeat the last search in the opposite direction."
+  :jump t
+  :type exclusive
+  (dotimes (var (or count 1))
+    (evil-search (if evil-regexp-search
+                     (car-safe regexp-search-ring)
+                   (car-safe search-ring))
+                 (not isearch-forward) evil-regexp-search)))
+
+(evil-define-motion evil-search-word-backward (count &optional symbol)
+  "Search backward for symbol under point."
+  :jump t
+  :type exclusive
+  (interactive (list (prefix-numeric-value current-prefix-arg)
+                     evil-symbol-word-search))
+  (dotimes (var (or count 1))
+    (evil-search-word nil nil symbol)))
+
+(evil-define-motion evil-search-word-forward (count &optional symbol)
+  "Search forward for symbol under point."
+  :jump t
+  :type exclusive
+  (interactive (list (prefix-numeric-value current-prefix-arg)
+                     evil-symbol-word-search))
+  (dotimes (var (or count 1))
+    (evil-search-word t nil symbol)))
+
+(evil-define-motion evil-search-unbounded-word-backward (count &optional symbol)
+  "Search backward for symbol under point.
+The search is unbounded, i.e., the pattern is not wrapped in
+\\<...\\>."
+  :jump t
+  :type exclusive
+  (interactive (list (prefix-numeric-value current-prefix-arg)
+                     evil-symbol-word-search))
+  (dotimes (var (or count 1))
+    (evil-search-word nil t symbol)))
+
+(evil-define-motion evil-search-unbounded-word-forward (count &optional symbol)
+  "Search forward for symbol under point.
+The search is unbounded, i.e., the pattern is not wrapped in
+\\<...\\>."
+  :jump t
+  :type exclusive
+  (interactive (list (prefix-numeric-value current-prefix-arg)
+                     evil-symbol-word-search))
+  (dotimes (var (or count 1))
+    (evil-search-word t t symbol)))
+
+(evil-define-motion evil-goto-definition ()
+  "Go to definition or first occurrence of symbol under point."
+  :jump t
+  :type exclusive
+  (let* ((string (evil-find-symbol t))
+         (search (format "\\_<%s\\_>" (regexp-quote string)))
+         ientry ipos)
+    ;; load imenu if available
+    (unless (featurep 'imenu)
+      (condition-case nil
+          (require 'imenu)
+        (error nil)))
+    (if (null string)
+        (user-error "No symbol under cursor")
+      (setq isearch-forward t)
+      ;; if imenu is available, try it
+      (cond
+       ((fboundp 'imenu--make-index-alist)
+        (condition-case nil
+            (setq ientry (imenu--make-index-alist))
+          (error nil))
+        (setq ientry (assoc string ientry))
+        (setq ipos (cdr ientry))
+        (when (and (markerp ipos)
+                   (eq (marker-buffer ipos) (current-buffer)))
+          (setq ipos (marker-position ipos)))
+        (cond
+         ;; imenu found a position, so go there and
+         ;; highlight the occurrence
+         ((numberp ipos)
+          (evil-search search t t ipos))
+         ;; imenu failed, try semantic
+         ((and (fboundp 'semantic-ia-fast-jump)
+               (ignore-errors (semantic-ia-fast-jump ipos)))
+          ()) ;; noop, already jumped
+         ((fboundp 'xref-find-definitions) ;; semantic failed, try the generic func
+          (xref-find-definitions string))))
+       ;; otherwise just go to first occurrence in buffer
+       (t
+        (evil-search search t t (point-min)))))))
+
+;;; Folding
+(defun evil-fold-action (list action)
+  "Perform fold ACTION for each matching major or minor mode in LIST.
+
+ACTION will be performed for the first matching handler in LIST.  For more
+information on its features and format, see the documentation for
+`evil-fold-list'.
+
+If no matching ACTION is found in LIST, an error will signaled.
+
+Handler errors will be demoted, so a problem in one handler will (hopefully)
+not interfere with another."
+  (if (null list)
+      (user-error
+       "Enable one of the following modes for folding to work: %s"
+       (mapconcat 'symbol-name (mapcar 'caar evil-fold-list) ", "))
+    (let* ((modes (caar list)))
+      (if (evil--mode-p modes)
+          (let* ((actions (cdar list))
+                 (fn      (plist-get actions action)))
+            (when fn
+              (with-demoted-errors (funcall fn))))
+        (evil-fold-action (cdr list) action)))))
+
+(defun evil--mode-p (modes)
+  "Determines whether any symbol in MODES represents the current
+buffer's major mode or any of its minors."
+  (unless (eq modes '())
+    (let ((mode (car modes)))
+      (or (eq major-mode mode)
+          (and (boundp mode) (symbol-value mode))
+          (evil--mode-p (cdr modes))))))
+
+(evil-define-command evil-toggle-fold ()
+  "Open or close a fold under point.
+See also `evil-open-fold' and `evil-close-fold'."
+  (evil-fold-action evil-fold-list :toggle))
+
+(evil-define-command evil-open-folds ()
+  "Open all folds.
+See also `evil-close-folds'."
+  (evil-fold-action evil-fold-list :open-all))
+
+(evil-define-command evil-close-folds ()
+  "Close all folds.
+See also `evil-open-folds'."
+  (evil-fold-action evil-fold-list :close-all))
+
+(evil-define-command evil-open-fold ()
+  "Open fold at point.
+See also `evil-close-fold'."
+  (evil-fold-action evil-fold-list :open))
+
+(evil-define-command evil-open-fold-rec ()
+  "Open fold at point recursively.
+See also `evil-open-fold' and `evil-close-fold'."
+  (evil-fold-action evil-fold-list :open-rec))
+
+(evil-define-command evil-close-fold ()
+  "Close fold at point.
+See also `evil-open-fold'."
+  (evil-fold-action evil-fold-list :close))
+
+;;; Ex
+
+(evil-define-operator evil-write (beg end type file-or-append &optional bang)
+  "Save the current buffer, from BEG to END, to FILE-OR-APPEND.
+If FILE-OR-APPEND is of the form \">> FILE\", append to FILE
+instead of overwriting.  The current buffer's filename is not
+changed unless it has no associated file and no region is
+specified.  If the file already exists and the BANG argument is
+non-nil, it is overwritten without confirmation."
+  :motion nil
+  :move-point nil
+  :type line
+  :repeat nil
+  (interactive "<R><fsh><!>")
+  (let* ((append-and-filename (evil-extract-append file-or-append))
+         (append (car append-and-filename))
+         (filename (cdr append-and-filename))
+         (bufname (buffer-file-name (buffer-base-buffer))))
+    (when (zerop (length filename))
+      (setq filename bufname))
+    (cond
+     ((zerop (length filename))
+      (user-error "Please specify a file name for the buffer"))
+     ;; execute command on region
+     ((eq (aref filename 0) ?!)
+      (shell-command-on-region beg end (substring filename 1)))
+     ;; with region or append, always save to file without resetting
+     ;; modified flag
+     ((or append (and beg end))
+      (write-region beg end filename append nil nil (not (or append bang))))
+     ;; no current file
+     ((null bufname)
+      (write-file filename (not bang)))
+     ;; save current buffer to its file
+     ((string= filename bufname)
+      (if (not bang) (save-buffer) (write-file filename)))
+     ;; save to another file
+     (t
+      (write-region nil nil filename
+                    nil (not bufname) nil
+                    (not bang))))))
+
+(evil-define-command evil-write-all (bang)
+  "Saves all buffers visiting a file.
+If BANG is non nil then read-only buffers are saved, too,
+otherwise they are skipped. "
+  :repeat nil
+  :move-point nil
+  (interactive "<!>")
+  (if bang
+      (save-some-buffers t)
+    ;; save only buffer that are not read-only and
+    ;; that are visiting a file
+    (save-some-buffers t
+                       #'(lambda ()
+                           (and (not buffer-read-only)
+                                (buffer-file-name))))))
+
+(evil-define-command evil-save (filename &optional bang)
+  "Save the current buffer to FILENAME.
+Changes the file name of the current buffer to FILENAME.  If no
+FILENAME is given, the current file name is used."
+  :repeat nil
+  :move-point nil
+  (interactive "<f><!>")
+  (when (zerop (length filename))
+    (setq filename (buffer-file-name (buffer-base-buffer))))
+  (write-file filename (not bang)))
+
+(evil-define-command evil-edit (file &optional bang)
+  "Open FILE.
+If no FILE is specified, reload the current buffer from disk."
+  :repeat nil
+  (interactive "<f><!>")
+  (if file
+      (find-file file)
+    (revert-buffer bang (or bang (not (buffer-modified-p))) t)))
+
+(evil-define-command evil-read (count file)
+  "Inserts the contents of FILE below the current line or line COUNT."
+  :repeat nil
+  :move-point nil
+  (interactive "P<fsh>")
+  (when (and file (not (zerop (length file))))
+    (when count (goto-char (point-min)))
+    (when (or (not (zerop (forward-line (or count 1))))
+              (not (bolp)))
+      (insert "\n"))
+    (if (/= (aref file 0) ?!)
+        (let ((result (insert-file-contents file)))
+          (save-excursion
+            (forward-char (cadr result))
+            (unless (bolp) (insert "\n"))))
+      (shell-command (substring file 1) t)
+      (save-excursion
+        (goto-char (mark))
+        (unless (bolp) (insert "\n"))))))
+
+(evil-define-command evil-show-files ()
+  "Shows the file-list.
+The same as `buffer-menu', but shows only buffers visiting
+files."
+  :repeat nil
+  (buffer-menu 1))
+
+(evil-define-command evil-goto-error (count)
+  "Go to error number COUNT.
+
+If no COUNT supplied, move to the current error.
+
+Acts like `first-error' other than when given no counts, goes
+to the current error instead of the first, like in Vim's :cc
+command."
+  :repeat nil
+  (interactive "<c>")
+  (if count
+      (first-error (if (eql 0 count) 1 count))
+    (next-error 0)))
+
+(evil-define-command evil-buffer (buffer)
+  "Switches to another buffer."
+  :repeat nil
+  (interactive "<b>")
+  (cond
+   ;; no buffer given, switch to "other" buffer
+   ((null buffer) (switch-to-buffer (other-buffer)))
+   ;; we are given the name of an existing buffer
+   ((get-buffer buffer) (switch-to-buffer buffer))
+   ;; try to complete the buffer
+   ((let ((all-buffers (internal-complete-buffer buffer nil t)))
+      (when (= (length all-buffers) 1)
+        (switch-to-buffer (car all-buffers)))))
+   (t
+    (when (y-or-n-p
+           (format "No buffer with name \"%s\" exists. Create new buffer? "
+                   buffer))
+      (switch-to-buffer buffer)))))
+
+(evil-define-command evil-next-buffer (&optional count)
+  "Goes to the `count'-th next buffer in the buffer list."
+  :repeat nil
+  (interactive "p")
+  (dotimes (i (or count 1))
+    (next-buffer)))
+
+(evil-define-command evil-prev-buffer (&optional count)
+  "Goes to the `count'-th prev buffer in the buffer list."
+  :repeat nil
+  (interactive "p")
+  (dotimes (i (or count 1))
+    (previous-buffer)))
+
+(evil-define-command evil-delete-buffer (buffer &optional bang)
+  "Deletes a buffer.
+All windows currently showing this buffer will be closed except
+for the last window in each frame."
+  (interactive "<b><!>")
+  (with-current-buffer (or buffer (current-buffer))
+    (when bang
+      (set-buffer-modified-p nil)
+      (dolist (process (process-list))
+        (when (eq (process-buffer process) (current-buffer))
+          (set-process-query-on-exit-flag process nil))))
+    ;; get all windows that show this buffer
+    (let ((wins (get-buffer-window-list (current-buffer) nil t)))
+      ;; if the buffer which was initiated by emacsclient,
+      ;; call `server-edit' from server.el to avoid
+      ;; "Buffer still has clients" message
+      (if (and (fboundp 'server-edit)
+               (boundp 'server-buffer-clients)
+               server-buffer-clients)
+          (server-edit)
+        (kill-buffer nil))
+      ;; close all windows that showed this buffer
+      (mapc #'(lambda (w)
+                (condition-case nil
+                    (delete-window w)
+                  (error nil)))
+            wins))))
+
+(evil-define-command evil-quit (&optional force)
+  "Closes the current window, current frame, Emacs.
+If the current frame belongs to some client the client connection
+is closed."
+  :repeat nil
+  (interactive "<!>")
+  (condition-case nil
+      (delete-window)
+    (error
+     (if (and (boundp 'server-buffer-clients)
+              (fboundp 'server-edit)
+              (fboundp 'server-buffer-done)
+              server-buffer-clients)
+         (if force
+             (server-buffer-done (current-buffer))
+           (server-edit))
+       (condition-case nil
+           (delete-frame)
+         (error
+          (if force
+              (kill-emacs)
+            (save-buffers-kill-emacs))))))))
+
+(evil-define-command evil-quit-all (&optional bang)
+  "Exits Emacs, asking for saving."
+  :repeat nil
+  (interactive "<!>")
+  (if (null bang)
+      (save-buffers-kill-terminal)
+    (let ((proc (frame-parameter (selected-frame) 'client)))
+      (if proc
+          (with-no-warnings
+            (server-delete-client proc))
+        (dolist (process (process-list))
+          (set-process-query-on-exit-flag process nil))
+        (kill-emacs)))))
+
+(evil-define-command evil-quit-all-with-error-code (&optional force)
+  "Exits Emacs without saving, returning an non-zero error code.
+The FORCE argument is only there for compatibility and is ignored.
+This function fails with an error if Emacs is run in server mode."
+  :repeat nil
+  (interactive "<!>")
+  (if (and (boundp 'server-buffer-clients)
+           (fboundp 'server-edit)
+           (fboundp 'server-buffer-done)
+           server-buffer-clients)
+      (user-error "Cannot exit client process with error code.")
+    (kill-emacs 1)))
+
+(evil-define-command evil-save-and-quit ()
+  "Save all buffers and exit Emacs."
+  (save-buffers-kill-terminal t))
+
+(evil-define-command evil-save-and-close (file &optional bang)
+  "Saves the current buffer and closes the window."
+  :repeat nil
+  (interactive "<f><!>")
+  (evil-write nil nil nil file bang)
+  (evil-quit))
+
+(evil-define-command evil-save-modified-and-close (file &optional bang)
+  "Saves the current buffer and closes the window."
+  :repeat nil
+  (interactive "<f><!>")
+  (when (buffer-modified-p)
+    (evil-write nil nil nil file bang))
+  (evil-quit))
+
+(evil-define-operator evil-shell-command
+  (beg end type command &optional previous)
+  "Execute a shell command.
+If BEG, END and TYPE is specified, COMMAND is executed on the region,
+which is replaced with the command's output. Otherwise, the
+output is displayed in its own buffer. If PREVIOUS is non-nil,
+the previous shell command is executed instead."
+  (interactive "<R><sh><!>")
+  (if (not (evil-ex-p))
+      (let ((evil-ex-initial-input
+             (if (and beg
+                      (not (evil-visual-state-p))
+                      (not current-prefix-arg))
+                 (let ((range (evil-range beg end type)))
+                   (evil-contract-range range)
+                   ;; TODO: this is not exactly the same as Vim, which
+                   ;; uses .,+count as range. However, this is easier
+                   ;; to achieve with the current implementation and
+                   ;; the very inconvenient range interface.
+                   ;;
+                   ;; TODO: the range interface really needs some
+                   ;; rework!
+                   (format
+                    "%d,%d!"
+                    (line-number-at-pos (evil-range-beginning range))
+                    (line-number-at-pos (evil-range-end range))))
+               "!")))
+        (call-interactively 'evil-ex))
+    (when command
+      (setq command (evil-ex-replace-special-filenames command)))
+    (if (zerop (length command))
+        (when previous (setq command evil-previous-shell-command))
+      (setq evil-previous-shell-command command))
+    (cond
+     ((zerop (length command))
+      (if previous (user-error "No previous shell command")
+        (user-error "No shell command")))
+     (evil-ex-range
+      (if (not evil-display-shell-error-in-message)
+          (shell-command-on-region beg end command nil t)
+        (let ((output-buffer (generate-new-buffer " *temp*"))
+              (error-buffer (generate-new-buffer " *temp*")))
+          (unwind-protect
+              (if (zerop (shell-command-on-region beg end
+                                                  command
+                                                  output-buffer nil
+                                                  error-buffer))
+                  (progn
+                    (delete-region beg end)
+                    (insert-buffer-substring output-buffer)
+                    (goto-char beg)
+                    (evil-first-non-blank))
+                (display-message-or-buffer error-buffer))
+            (kill-buffer output-buffer)
+            (kill-buffer error-buffer)))))
+     (t
+      (shell-command command)))))
+
+(evil-define-command evil-make (arg)
+  "Call a build command in the current directory.
+If ARG is nil this function calls `recompile', otherwise it calls
+`compile' passing ARG as build command."
+  (interactive "<sh>")
+  (if (and (fboundp 'recompile)
+           (not arg))
+      (recompile)
+    (compile arg)))
+
+;; TODO: escape special characters (currently only \n) ... perhaps
+;; there is some Emacs function doing this?
+(evil-define-command evil-show-registers ()
+  "Shows the contents of all registers."
+  :repeat nil
+  (evil-with-view-list
+    :name "evil-registers"
+    :mode-name "Evil Registers"
+    :format
+    [("Register" 10 nil)
+     ("Value" 1000 nil)]
+    :entries
+    (cl-loop for (key . val) in (evil-register-list)
+             collect `(nil [,(char-to-string key)
+                            ,(or (and val
+                                      (stringp val)
+                                      (replace-regexp-in-string "\n" "^J" val))
+                                 "")]))))
+
+(evil-define-command evil-show-marks (mrks)
+  "Shows all marks.
+If MRKS is non-nil it should be a string and only registers
+corresponding to the characters of this string are shown."
+  :repeat nil
+  (interactive "<a>")
+  ;; To get markers and positions, we can't rely on 'global-mark-ring'
+  ;; provided by Emacs (although it will be much simpler and faster),
+  ;; because 'global-mark-ring' does not store mark characters, but
+  ;; only buffer name and position. Instead, 'evil-markers-alist' is
+  ;; used; this is list maintained by Evil for each buffer.
+  (let ((all-markers
+         ;; get global and local marks
+         (append (cl-remove-if (lambda (m)
+                                 (or (evil-global-marker-p (car m))
+                                     (not (markerp (cdr m)))))
+                               evil-markers-alist)
+                 (cl-remove-if (lambda (m)
+                                 (or (not (evil-global-marker-p (car m)))
+                                     (not (markerp (cdr m)))))
+                               (default-value 'evil-markers-alist)))))
+    (when mrks
+      (setq mrks (string-to-list mrks))
+      (setq all-markers (cl-delete-if (lambda (m)
+                                        (not (member (car m) mrks)))
+                                      all-markers)))
+    ;; map marks to list of 4-tuples (char row col file)
+    (setq all-markers
+          (mapcar (lambda (m)
+                    (with-current-buffer (marker-buffer (cdr m))
+                      (save-excursion
+                        (goto-char (cdr m))
+                        (list (car m)
+                              (line-number-at-pos (point))
+                              (current-column)
+                              (buffer-name)))))
+                  all-markers))
+    (evil-with-view-list
+      :name "evil-marks"
+      :mode-name "Evil Marks"
+      :format [("Mark" 8 nil)
+               ("Line" 8 nil)
+               ("Column" 8 nil)
+               ("Buffer" 1000 nil)]
+      :entries (cl-loop for m in (sort all-markers (lambda (a b) (< (car a) (car b))))
+                        collect `(nil [,(char-to-string (nth 0 m))
+                                       ,(number-to-string (nth 1 m))
+                                       ,(number-to-string (nth 2 m))
+                                       (,(nth 3 m))]))
+      :select-action #'evil--show-marks-select-action)))
+
+(defun evil--show-marks-select-action (entry)
+  (kill-buffer)
+  (switch-to-buffer (car (elt entry 3)))
+  (evil-goto-mark (string-to-char (elt entry 0))))
+
+(evil-define-command evil-delete-marks (marks &optional force)
+  "Delete all marks.
+MARKS is a string denoting all marks to be deleted. Mark names are
+either single characters or a range of characters in the form A-Z.
+
+If FORCE is non-nil all local marks except 0-9 are removed.
+"
+  (interactive "<a><!>")
+  (cond
+   ;; delete local marks except 0-9
+   (force
+    (setq evil-markers-alist
+          (cl-delete-if (lambda (m)
+                          (not (and (>= (car m) ?0) (<= (car m) ?9))))
+                        evil-markers-alist)))
+   (t
+    (let ((i 0)
+          (n (length marks))
+          delmarks)
+      (while (< i n)
+        (cond
+         ;; skip spaces
+         ((= (aref marks i) ?\s) (cl-incf i))
+         ;; ranges of marks
+         ((and (< (+ i 2) n)
+               (= (aref marks (1+ i)) ?-)
+               (or (and (>= (aref marks i) ?a)
+                        (<= (aref marks i) ?z)
+                        (>= (aref marks (+ 2 i)) ?a)
+                        (<= (aref marks (+ 2 i)) ?z))
+                   (and (>= (aref marks i) ?A)
+                        (<= (aref marks i) ?Z)
+                        (>= (aref marks (+ 2 i)) ?A)
+                        (<= (aref marks (+ 2 i)) ?Z))))
+          (let ((m (aref marks i)))
+            (while (<= m (aref marks (+ 2 i)))
+              (push m delmarks)
+              (cl-incf m)))
+          (cl-incf i 2))
+         ;; single marks
+         (t
+          (push (aref marks i) delmarks)
+          (cl-incf i))))
+      ;; now remove all marks
+      (setq evil-markers-alist
+            (cl-delete-if (lambda (m) (member (car m) delmarks))
+                          evil-markers-alist))
+      (set-default 'evil-markers-alist
+                   (cl-delete-if (lambda (m) (member (car m) delmarks))
+                                 (default-value 'evil-markers-alist)))))))
+
+(eval-when-compile (require 'ffap))
+(evil-define-command evil-find-file-at-point-with-line ()
+  "Opens the file at point and goes to line-number."
+  (require 'ffap)
+  (let ((fname (with-no-warnings (ffap-file-at-point))))
+    (if fname
+        (let ((line
+               (save-excursion
+                 (goto-char (cadr ffap-string-at-point-region))
+                 (and (re-search-backward ":\\([0-9]+\\)\\="
+                                          (line-beginning-position) t)
+                      (string-to-number (match-string 1))))))
+          (with-no-warnings (ffap-other-window))
+          (when line
+            (goto-char (point-min))
+            (forward-line (1- line))))
+      (user-error "File does not exist."))))
+
+(evil-ex-define-argument-type state
+  "Defines an argument type which can take state names."
+  :collection
+  (lambda (arg predicate flag)
+    (let ((completions
+           (append '("nil")
+                   (mapcar #'(lambda (state)
+                               (format "%s" (car state)))
+                           evil-state-properties))))
+      (when arg
+        (cond
+         ((eq flag nil)
+          (try-completion arg completions predicate))
+         ((eq flag t)
+          (all-completions arg completions predicate))
+         ((eq flag 'lambda)
+          (test-completion arg completions predicate))
+         ((eq (car-safe flag) 'boundaries)
+          (cons 'boundaries
+                (completion-boundaries arg
+                                       completions
+                                       predicate
+                                       (cdr flag)))))))))
+
+(evil-define-interactive-code "<state>"
+  "A valid evil state."
+  :ex-arg state
+  (list (when (and (evil-ex-p) evil-ex-argument)
+          (intern evil-ex-argument))))
+
+;; TODO: should we merge this command with `evil-set-initial-state'?
+(evil-define-command evil-ex-set-initial-state (state)
+  "Set the initial state for the current major mode to STATE.
+This is the state the buffer comes up in. See `evil-set-initial-state'."
+  :repeat nil
+  (interactive "<state>")
+  (if (not (or (assq state evil-state-properties)
+               (null state)))
+      (user-error "State %s cannot be set as initial Evil state" state)
+    (let ((current-initial-state (evil-initial-state major-mode)))
+      (unless (eq current-initial-state state)
+        ;; only if we selected a new mode
+        (when (y-or-n-p (format "Major-mode `%s' has initial mode `%s'. \
+Change to `%s'? "
+                                major-mode
+                                (or current-initial-state "DEFAULT")
+                                (or state "DEFAULT")))
+          (evil-set-initial-state major-mode state)
+          (when (y-or-n-p "Save setting in customization file? ")
+            (dolist (s (list current-initial-state state))
+              (when s
+                (let ((var (intern (format "evil-%s-state-modes" s))))
+                  (customize-save-variable var (symbol-value var)))))))))))
+
+(evil-define-command evil-force-normal-state ()
+  "Switch to normal state without recording current command."
+  :repeat abort
+  :suppress-operator t
+  (evil-normal-state))
+
+(evil-define-motion evil-ex-search-next (count)
+  "Goes to the next occurrence."
+  :jump t
+  :type exclusive
+  (evil-ex-search count))
+
+(evil-define-motion evil-ex-search-previous (count)
+  "Goes the the previous occurrence."
+  :jump t
+  :type exclusive
+  (let ((evil-ex-search-direction
+         (if (eq evil-ex-search-direction 'backward) 'forward 'backward)))
+    (evil-ex-search count)))
+
+(defun evil-repeat-ex-search (flag)
+  "Called to record a search command.
+FLAG is either 'pre or 'post if the function is called before
+resp.  after executing the command."
+  (cond
+   ((and (evil-operator-state-p) (eq flag 'pre))
+    (evil-repeat-record (this-command-keys))
+    (evil-clear-command-keys))
+   ((and (evil-operator-state-p) (eq flag 'post))
+    ;; The value of (this-command-keys) at this point should be the
+    ;; key-sequence that called the last command that finished the
+    ;; search, usually RET. Therefore this key-sequence will be
+    ;; recorded in the post-command of the operator. Alternatively we
+    ;; could do it here.
+    (evil-repeat-record (evil-ex-pattern-regex evil-ex-search-pattern)))
+   (t (evil-repeat-motion flag))))
+
+(evil-define-motion evil-ex-search-forward (count)
+  "Starts a forward search."
+  :jump t
+  :type exclusive
+  :repeat evil-repeat-ex-search
+  (evil-ex-start-search 'forward count))
+
+(evil-define-motion evil-ex-search-backward (count)
+  "Starts a forward search."
+  :jump t
+  :repeat evil-repeat-ex-search
+  (evil-ex-start-search 'backward count))
+
+(evil-define-motion evil-ex-search-word-forward (count &optional symbol)
+  "Search for the next occurrence of word under the cursor."
+  :jump t
+  :type exclusive
+  (interactive (list (prefix-numeric-value current-prefix-arg)
+                     evil-symbol-word-search))
+  (evil-ex-start-word-search nil 'forward count symbol))
+
+(evil-define-motion evil-ex-search-word-backward (count &optional symbol)
+  "Search for the next occurrence of word under the cursor."
+  :jump t
+  :type exclusive
+  (interactive (list (prefix-numeric-value current-prefix-arg)
+                     evil-symbol-word-search))
+  (evil-ex-start-word-search nil 'backward count symbol))
+
+(evil-define-motion evil-ex-search-unbounded-word-forward (count &optional symbol)
+  "Search for the next occurrence of word under the cursor."
+  :jump t
+  :type exclusive
+  (interactive (list (prefix-numeric-value current-prefix-arg)
+                     evil-symbol-word-search))
+  (evil-ex-start-word-search t 'forward count symbol))
+
+(evil-define-motion evil-ex-search-unbounded-word-backward (count &optional symbol)
+  "Search for the next occurrence of word under the cursor."
+  :jump t
+  :type exclusive
+  (interactive (list (prefix-numeric-value current-prefix-arg)
+                     evil-symbol-word-search))
+  (evil-ex-start-word-search t 'backward count symbol))
+
+(defun evil-revert-reveal (open-spots)
+  "Unconditionally close overlays in OPEN-SPOTS in current window.
+Modified version of `reveal-close-old-overlays' from
+reveal.el. OPEN-SPOTS is a local version of `reveal-open-spots'."
+  (dolist (spot open-spots)
+    (let ((window (car spot))
+          (ol (cdr spot)))
+      (unless (eq window (selected-window))
+        (error "evil-revert-reveal: slot with wrong window"))
+      (let* ((inv (overlay-get ol 'reveal-invisible))
+             (open (or (overlay-get ol 'reveal-toggle-invisible)
+                       (get inv 'reveal-toggle-invisible)
+                       (overlay-get ol 'isearch-open-invisible-temporary))))
+        (if (and (overlay-start ol) ;Check it's still live.
+                 open)
+            (condition-case err
+                (funcall open ol t)
+              (error (message "!!Reveal-hide (funcall %s %s t): %s !!"
+                              open ol err)))
+          (overlay-put ol 'invisible inv))
+        ;; Remove the overlay from the list of open spots.
+        (overlay-put ol 'reveal-invisible nil)))))
+
+(evil-define-operator evil-ex-substitute
+  (beg end pattern replacement flags)
+  "The Ex substitute command.
+\[BEG,END]substitute/PATTERN/REPLACEMENT/FLAGS"
+  :repeat nil
+  :jump t
+  :move-point nil
+  :motion evil-line
+  (interactive "<r><s/>")
+  (evil-ex-nohighlight)
+  (unless pattern
+    (user-error "No pattern given"))
+  (setq replacement (or replacement ""))
+  (setq evil-ex-last-was-search nil)
+  (let* ((flags (append flags nil))
+         (count-only (memq ?n flags))
+         (confirm (and (memq ?c flags) (not count-only)))
+         (case-fold-search (evil-ex-pattern-ignore-case pattern))
+         (case-replace case-fold-search)
+         (evil-ex-substitute-regex (evil-ex-pattern-regex pattern))
+         (evil-ex-substitute-nreplaced 0)
+         (evil-ex-substitute-last-point (point))
+         (whole-line (evil-ex-pattern-whole-line pattern))
+         (evil-ex-substitute-overlay (make-overlay (point) (point)))
+         (evil-ex-substitute-hl (evil-ex-make-hl 'evil-ex-substitute))
+         (orig-point-marker (move-marker (make-marker) (point)))
+         (end-marker (move-marker (make-marker) end))
+         (use-reveal confirm)
+         reveal-open-spots
+         zero-length-match
+         match-contains-newline
+         transient-mark-mode)
+    (setq evil-ex-substitute-pattern pattern
+          evil-ex-substitute-replacement replacement
+          evil-ex-substitute-flags flags
+          isearch-string evil-ex-substitute-regex)
+    (isearch-update-ring evil-ex-substitute-regex t)
+    (unwind-protect
+        (progn
+          (evil-ex-hl-change 'evil-ex-substitute pattern)
+          (overlay-put evil-ex-substitute-overlay 'face 'isearch)
+          (overlay-put evil-ex-substitute-overlay 'priority 1001)
+          (goto-char beg)
+          (catch 'exit-search
+            (while (re-search-forward evil-ex-substitute-regex end-marker t)
+              (when (not (and query-replace-skip-read-only
+                              (text-property-any (match-beginning 0) (match-end 0) 'read-only t)))
+                (let ((match-str (match-string 0))
+                      (match-beg (move-marker (make-marker) (match-beginning 0)))
+                      (match-end (move-marker (make-marker) (match-end 0)))
+                      (match-data (match-data)))
+                  (goto-char match-beg)
+                  (setq match-contains-newline
+                        (string-match-p "\n" (buffer-substring-no-properties
+                                              match-beg match-end)))
+                  (setq zero-length-match (= match-beg match-end))
+                  (when (and (string= "^" evil-ex-substitute-regex)
+                             (= (point) end-marker))
+                    ;; The range (beg end) includes the final newline which means
+                    ;; end-marker is on one line down. With the regex "^" the
+                    ;; beginning of this last line will be matched which we don't
+                    ;; want, so we abort here.
+                    (throw 'exit-search t))
+                  (setq evil-ex-substitute-last-point match-beg)
+                  (if confirm
+                      (let ((prompt
+                             (format "Replace %s with %s (y/n/a/q/l/^E/^Y)? "
+                                     match-str
+                                     (evil-match-substitute-replacement
+                                      evil-ex-substitute-replacement
+                                      (not case-replace))))
+                            (search-invisible t)
+                            response)
+                        (move-overlay evil-ex-substitute-overlay match-beg match-end)
+                        ;; Simulate `reveal-mode'. `reveal-mode' uses
+                        ;; `post-command-hook' but that won't work here.
+                        (when use-reveal
+                          (reveal-post-command))
+                        (catch 'exit-read-char
+                          (while (setq response (read-char prompt))
+                            (when (member response '(?y ?a ?l))
+                              (unless count-only
+                                (set-match-data match-data)
+                                (evil-replace-match evil-ex-substitute-replacement
+                                                    (not case-replace)))
+                              (setq evil-ex-substitute-nreplaced
+                                    (1+ evil-ex-substitute-nreplaced))
+                              (evil-ex-hl-set-region 'evil-ex-substitute
+                                                     (save-excursion
+                                                       (forward-line)
+                                                       (point))
+                                                     (evil-ex-hl-get-max
+                                                      'evil-ex-substitute)))
+                            (cl-case response
+                              ((?y ?n) (throw 'exit-read-char t))
+                              (?a (setq confirm nil)
+                                  (throw 'exit-read-char t))
+                              ((?q ?l ?\C-\[) (throw 'exit-search t))
+                              (?\C-e (evil-scroll-line-down 1))
+                              (?\C-y (evil-scroll-line-up 1))))))
+                    (setq evil-ex-substitute-nreplaced
+                          (1+ evil-ex-substitute-nreplaced))
+                    (unless count-only
+                      (set-match-data match-data)
+                      (evil-replace-match evil-ex-substitute-replacement
+                                          (not case-replace))))
+                  (goto-char match-end)
+                  (cond ((>= (point) end-marker)
+                         ;; Don't want to perform multiple replacements at the end
+                         ;; of the search region.
+                         (throw 'exit-search t))
+                        ((and (not whole-line)
+                              (not match-contains-newline))
+                         (forward-line)
+                         ;; forward-line just moves to the end of the line on the
+                         ;; last line of the buffer.
+                         (when (or (eobp)
+                                   (> (point) end-marker))
+                           (throw 'exit-search t)))
+                        ;; For zero-length matches check to see if point won't
+                        ;; move next time. This is a problem when matching the
+                        ;; regexp "$" because we can enter an infinite loop,
+                        ;; repeatedly matching the same character
+                        ((and zero-length-match
+                              (let ((pnt (point)))
+                                (save-excursion
+                                  (and
+                                   (re-search-forward
+                                    evil-ex-substitute-regex end-marker t)
+                                   (= pnt (point))))))
+                         (if (or (eobp)
+                                 (>= (point) end-marker))
+                             (throw 'exit-search t)
+                           (forward-char)))))))))
+      (evil-ex-delete-hl 'evil-ex-substitute)
+      (delete-overlay evil-ex-substitute-overlay)
+
+      (if count-only
+          (goto-char orig-point-marker)
+        (goto-char evil-ex-substitute-last-point))
+
+      (move-marker orig-point-marker nil)
+      (move-marker end-marker nil)
+
+      (when use-reveal
+        (evil-revert-reveal reveal-open-spots)))
+
+    (message "%s %d occurrence%s"
+             (if count-only "Found" "Replaced")
+             evil-ex-substitute-nreplaced
+             (if (/= evil-ex-substitute-nreplaced 1) "s" ""))
+    (evil-first-non-blank)))
+
+(evil-define-operator evil-ex-repeat-substitute
+  (beg end flags)
+  "Repeat last substitute command.
+This is the same as :s//~/"
+  :repeat nil
+  :jump t
+  :move-point nil
+  :motion evil-line
+  (interactive "<r><a>")
+  (apply #'evil-ex-substitute beg end
+         (evil-ex-get-substitute-info (concat "//~/" flags))))
+
+(evil-define-operator evil-ex-repeat-substitute-with-flags
+  (beg end flags)
+  "Repeat last substitute command with last flags.
+This is the same as :s//~/&"
+  :repeat nil
+  :jump t
+  :move-point nil
+  :motion evil-line
+  (interactive "<r><a>")
+  (apply #'evil-ex-substitute beg end
+         (evil-ex-get-substitute-info (concat "//~/&" flags))))
+
+(evil-define-operator evil-ex-repeat-substitute-with-search
+  (beg end flags)
+  "Repeat last substitute command with last search pattern.
+This is the same as :s//~/r"
+  :repeat nil
+  :jump t
+  :move-point nil
+  :motion evil-line
+  (interactive "<r><a>")
+  (apply #'evil-ex-substitute beg end
+         (evil-ex-get-substitute-info (concat "//~/r" flags))))
+
+(evil-define-operator evil-ex-repeat-substitute-with-search-and-flags
+  (beg end flags)
+  "Repeat last substitute command with last search pattern and last flags.
+This is the same as :s//~/&r"
+  :repeat nil
+  :jump t
+  :move-point nil
+  :motion evil-line
+  (interactive "<r><a>")
+  (apply #'evil-ex-substitute beg end
+         (evil-ex-get-substitute-info (concat "//~/&r" flags))))
+
+(evil-define-operator evil-ex-repeat-global-substitute ()
+  "Repeat last substitute command on the whole buffer.
+This is the same as :%s//~/&"
+  :repeat nil
+  :jump t
+  :move-point nil
+  :motion evil-line
+  (interactive)
+  (apply #'evil-ex-substitute (point-min) (point-max)
+         (evil-ex-get-substitute-info (concat "//~/&"))))
+
+(evil-define-operator evil-ex-global
+  (beg end pattern command &optional invert)
+  "The Ex global command.
+\[BEG,END]global[!]/PATTERN/COMMAND"
+  :motion mark-whole-buffer
+  :move-point nil
+  (interactive "<r><g/><!>")
+  (unless pattern
+    (user-error "No pattern given"))
+  (unless command
+    (user-error "No command given"))
+  ;; TODO: `evil-ex-make-substitute-pattern' should be executed so
+  ;; :substitute can re-use :global's pattern depending on its `r'
+  ;; flag. This isn't supported currently but should be simple to add
+  (evil-with-single-undo
+    (let ((case-fold-search
+           (eq (evil-ex-regex-case pattern evil-ex-search-case) 'insensitive))
+          (command-form (evil-ex-parse command))
+          (transient-mark-mode transient-mark-mode)
+          (deactivate-mark deactivate-mark)
+          match markers)
+      (when (and pattern command)
+        (setq isearch-string pattern)
+        (isearch-update-ring pattern t)
+        (goto-char beg)
+        (evil-move-beginning-of-line)
+        (while (< (point) end)
+          (setq match (re-search-forward pattern (line-end-position) t))
+          (when (or (and match (not invert))
+                    (and invert (not match)))
+            (push (move-marker (make-marker)
+                               (or (and match (match-beginning 0))
+                                   (line-beginning-position)))
+                  markers))
+          (forward-line))
+        (setq markers (nreverse markers))
+        (unwind-protect
+            (dolist (marker markers)
+              (goto-char marker)
+              (eval command-form))
+          ;; ensure that all markers are deleted afterwards,
+          ;; even in the event of failure
+          (dolist (marker markers)
+            (set-marker marker nil)))))))
+
+(evil-define-operator evil-ex-global-inverted
+  (beg end pattern command &optional invert)
+  "The Ex vglobal command.
+\[BEG,END]vglobal/PATTERN/COMMAND"
+  :motion mark-whole-buffer
+  :move-point nil
+  (interactive "<r><g/><!>")
+  (evil-ex-global beg end pattern command (not invert)))
+
+(evil-define-operator evil-ex-normal (beg end commands)
+  "The Ex normal command.
+Execute the argument as normal command on each line in the
+range. The given argument is passed straight to
+`execute-kbd-macro'.  The default is the current line."
+  :motion evil-line
+  (interactive "<r><a>")
+  (evil-with-single-undo
+    (let (markers evil-ex-current-buffer prefix-arg current-prefix-arg)
+      (goto-char beg)
+      (while
+          (and (< (point) end)
+               (progn
+                 (push (move-marker (make-marker) (line-beginning-position))
+                       markers)
+                 (and (= (forward-line) 0) (bolp)))))
+      (setq markers (nreverse markers))
+      (deactivate-mark)
+      (evil-force-normal-state)
+      ;; replace ^[ by escape
+      (setq commands
+            (vconcat
+             (mapcar #'(lambda (ch) (if (equal ch ?) 'escape ch))
+                     (append commands nil))))
+      (dolist (marker markers)
+        (goto-char marker)
+        (condition-case nil
+            (execute-kbd-macro commands)
+          (error nil))
+        (evil-force-normal-state)
+        (set-marker marker nil)))))
+
+(evil-define-command evil-goto-char (position)
+  "Go to POSITION in the buffer.
+Default position is the beginning of the buffer."
+  (interactive "p")
+  (let ((position (evil-normalize-position
+                   (or position (point-min)))))
+    (goto-char position)))
+
+(evil-define-operator evil-ex-line-number (beg end)
+  "Print the last line number."
+  :motion mark-whole-buffer
+  :move-point nil
+  (interactive "<r>")
+  (message "%d" (count-lines (point-min) end)))
+
+(evil-define-command evil-show-file-info ()
+  "Shows basic file information."
+  (let* ((nlines   (count-lines (point-min) (point-max)))
+         (curr     (line-number-at-pos (point)))
+         (perc     (if (> nlines 0)
+                       (format "%d%%" (* (/ (float curr) (float nlines)) 100.0))
+                     "No lines in buffer"))
+         (file     (buffer-file-name (buffer-base-buffer)))
+         (writable (and file (file-writable-p file)))
+         (readonly (if (and file (not writable)) "[readonly] " "")))
+    (if file
+        (message "\"%s\" %d %slines --%s--" file nlines readonly perc)
+      (message "%d lines --%s--" nlines perc))))
+
+(evil-define-operator evil-ex-sort (beg end &optional options reverse)
+  "The Ex sort command.
+\[BEG,END]sort[!] [i][u]
+The following additional options are supported:
+
+  * i   ignore case
+  * u   remove duplicate lines
+
+The 'bang' argument means to sort in reverse order."
+  :motion mark-whole-buffer
+  :move-point nil
+  (interactive "<r><a><!>")
+  (let ((beg (copy-marker beg))
+        (end (copy-marker end))
+        sort-fold-case uniq)
+    (dolist (opt (append options nil))
+      (cond
+       ((eq opt ?i) (setq sort-fold-case t))
+       ((eq opt ?u) (setq uniq t))
+       (t (user-error "Unsupported sort option: %c" opt))))
+    (sort-lines reverse beg end)
+    (when uniq
+      (let (line prev-line)
+        (goto-char beg)
+        (while (and (< (point) end) (not (eobp)))
+          (setq line (buffer-substring-no-properties
+                      (line-beginning-position)
+                      (line-end-position)))
+          (if (and (stringp prev-line)
+                   (eq t (compare-strings line nil nil
+                                          prev-line nil nil
+                                          sort-fold-case)))
+              (delete-region (progn (forward-line 0) (point))
+                             (progn (forward-line 1) (point)))
+            (setq prev-line line)
+            (forward-line 1)))))
+    (goto-char beg)
+    (set-marker beg nil)
+    (set-marker end nil)))
+
+;;; Window navigation
+
+(defun evil-resize-window (new-size &optional horizontal)
+  "Set the current window's width or height to NEW-SIZE.
+If HORIZONTAL is non-nil the width of the window is changed,
+otherwise its height is changed."
+  (let ((count (- new-size (if horizontal (window-width) (window-height)))))
+    (if (>= emacs-major-version 24)
+        (enlarge-window count horizontal)
+      (let ((wincfg (current-window-configuration))
+            (nwins (length (window-list)))
+            (inhibit-redisplay t))
+        (catch 'done
+          (save-window-excursion
+            (while (not (zerop count))
+              (if (> count 0)
+                  (progn
+                    (enlarge-window 1 horizontal)
+                    (setq count (1- count)))
+                (progn
+                  (shrink-window 1 horizontal)
+                  (setq count (1+ count))))
+              (if (= nwins (length (window-list)))
+                  (setq wincfg (current-window-configuration))
+                (throw 'done t)))))
+        (set-window-configuration wincfg)))))
+
+(defun evil-get-buffer-tree (wintree)
+  "Extracts the buffer tree from a given window tree WINTREE."
+  (if (consp wintree)
+      (cons (car wintree) (mapcar #'evil-get-buffer-tree (cddr wintree)))
+    (window-buffer wintree)))
+
+(defun evil-restore-window-tree (win tree)
+  "Restore the given buffer-tree layout as subwindows of WIN.
+TREE is the tree layout to be restored.
+A tree layout is either a buffer or a list of the form (DIR TREE ...),
+where DIR is t for horizontal split and nil otherwise. All other
+elements of the list are tree layouts itself."
+  (if (bufferp tree)
+      (set-window-buffer win tree)
+    ;; if tree is buffer list with one buffer only, do not split
+    ;; anymore
+    (if (not (cddr tree))
+        (evil-restore-window-tree win (cadr tree))
+      ;; tree is a regular list, split recursively
+      (let ((newwin (split-window win nil (not (car tree)))))
+        (evil-restore-window-tree win (cadr tree))
+        (evil-restore-window-tree newwin (cons (car tree) (cddr tree)))))))
+
+(defun evil-alternate-buffer (&optional window)
+  "Return the last buffer WINDOW has displayed other than the
+current one (equivalent to Vim's alternate buffer).
+
+Returns the first item in `window-prev-buffers' that isn't
+`window-buffer' of WINDOW."
+  ;; If the last buffer visited has been killed, then `window-prev-buffers'
+  ;; returns a list with `current-buffer' at the head, we account for this
+  ;; possibility.
+  (let* ((prev-buffers (window-prev-buffers))
+         (head (car prev-buffers)))
+    (if (eq (car head) (window-buffer window))
+        (cadr prev-buffers)
+      head)))
+
+(evil-define-command evil-switch-to-windows-last-buffer ()
+  "Switch to current windows last open buffer."
+  :repeat nil
+  (let ((previous-place (evil-alternate-buffer)))
+    (when previous-place
+      (switch-to-buffer (car previous-place))
+      (goto-char (car (last previous-place))))))
+
+(evil-define-command evil-window-delete ()
+  "Deletes the current window.
+If `evil-auto-balance-windows' is non-nil then all children of
+the deleted window's parent window are rebalanced."
+  (let ((p (window-parent)))
+    (delete-window)
+    (when evil-auto-balance-windows
+      ;; balance-windows raises an error if the parent does not have
+      ;; any further children (then rebalancing is not necessary anyway)
+      (condition-case nil
+          (balance-windows p)
+        (error)))))
+
+(evil-define-command evil-window-split (&optional count file)
+  "Splits the current window horizontally, COUNT lines height,
+editing a certain FILE. The new window will be created below
+when `evil-split-window-below' is non-nil. If COUNT and
+`evil-auto-balance-windows' are both non-nil then all children
+of the parent of the splitted window are rebalanced."
+  :repeat nil
+  (interactive "P<f>")
+  (split-window (selected-window) count
+                (if evil-split-window-below 'above 'below))
+  (when (and (not count) evil-auto-balance-windows)
+    (balance-windows (window-parent)))
+  (when file
+    (evil-edit file)))
+
+(evil-define-command evil-window-vsplit (&optional count file)
+  "Splits the current window vertically, COUNT columns width,
+editing a certain FILE. The new window will be created to the
+right when `evil-vsplit-window-right' is non-nil. If COUNT and
+`evil-auto-balance-windows'are both non-nil then all children
+of the parent of the splitted window are rebalanced."
+  :repeat nil
+  (interactive "P<f>")
+  (split-window (selected-window) count
+                (if evil-vsplit-window-right 'left 'right))
+  (when (and (not count) evil-auto-balance-windows)
+    (balance-windows (window-parent)))
+  (when file
+    (evil-edit file)))
+
+(evil-define-command evil-split-buffer (buffer)
+  "Splits window and switches to another buffer."
+  :repeat nil
+  (interactive "<b>")
+  (evil-window-split)
+  (evil-buffer buffer))
+
+(evil-define-command evil-split-next-buffer (&optional count)
+  "Splits the window and goes to the COUNT-th next buffer in the buffer list."
+  :repeat nil
+  (interactive "p")
+  (evil-window-split)
+  (evil-next-buffer count))
+
+(evil-define-command evil-split-prev-buffer (&optional count)
+  "Splits window and goes to the COUNT-th prev buffer in the buffer list."
+  :repeat nil
+  (interactive "p")
+  (evil-window-split)
+  (evil-prev-buffer count))
+
+(evil-define-command evil-window-left (count)
+  "Move the cursor to new COUNT-th window left of the current one."
+  :repeat nil
+  (interactive "p")
+  (dotimes (i count)
+    (windmove-left)))
+
+(evil-define-command evil-window-right (count)
+  "Move the cursor to new COUNT-th window right of the current one."
+  :repeat nil
+  (interactive "p")
+  (dotimes (i count)
+    (windmove-right)))
+
+(evil-define-command evil-window-up (count)
+  "Move the cursor to new COUNT-th window above the current one."
+  :repeat nil
+  (interactive "p")
+  (dotimes (i (or count 1))
+    (windmove-up)))
+
+(evil-define-command evil-window-down (count)
+  "Move the cursor to new COUNT-th window below the current one."
+  :repeat nil
+  (interactive "p")
+  (dotimes (i (or count 1))
+    (windmove-down)))
+
+(evil-define-command evil-window-bottom-right ()
+  "Move the cursor to bottom-right window."
+  :repeat nil
+  (let ((last-sibling (frame-root-window)))
+    (while (and last-sibling (not (window-live-p last-sibling)))
+      (setq last-sibling (window-last-child last-sibling)))
+    (when last-sibling
+      (select-window last-sibling))))
+
+(evil-define-command evil-window-top-left ()
+  "Move the cursor to top-left window."
+  :repeat nil
+  (let ((first-child (window-child (frame-root-window))))
+    (while (and first-child (not (window-live-p first-child)))
+      (setq first-child (window-child first-child)))
+    (when first-child
+      (select-window
+       first-child))))
+
+(evil-define-command evil-window-mru ()
+  "Move the cursor to the previous (last accessed) buffer in another window.
+More precisely, it selects the most recently used buffer that is
+shown in some other window, preferably of the current frame, and
+is different from the current one."
+  :repeat nil
+  (catch 'done
+    (dolist (buf (buffer-list (selected-frame)))
+      (let ((win (get-buffer-window buf)))
+        (when (and (not (eq buf (current-buffer)))
+                   win
+                   (not (eq win (selected-window))))
+          (select-window win)
+          (throw 'done nil))))))
+
+(evil-define-command evil-window-next (count)
+  "Move the cursor to the next window in the cyclic order.
+With COUNT go to the count-th window in the order starting from
+top-left."
+  :repeat nil
+  (interactive "<c>")
+  (if (not count)
+      (select-window (next-window))
+    (evil-window-top-left)
+    (other-window (1- count))))
+
+(evil-define-command evil-window-prev (count)
+  "Move the cursor to the previous window in the cyclic order.
+With COUNT go to the count-th window in the order starting from
+top-left."
+  :repeat nil
+  (interactive "<c>")
+  (if (not count)
+      (select-window (previous-window))
+    (evil-window-top-left)
+    (other-window (1- count))))
+
+(evil-define-command evil-window-new (count file)
+  "Splits the current window horizontally
+and opens a new buffer or edits a certain FILE."
+  :repeat nil
+  (interactive "P<f>")
+  (let ((new-window (split-window (selected-window) count
+                                  (if evil-split-window-below 'below 'above))))
+    (when (and (not count) evil-auto-balance-windows)
+      (balance-windows (window-parent)))
+    (if file
+        (evil-edit file)
+      (let ((buffer (generate-new-buffer "*new*")))
+        (set-window-buffer new-window buffer)
+        (select-window new-window)
+        (with-current-buffer buffer
+          (funcall (default-value 'major-mode)))))))
+
+(evil-define-command evil-window-vnew (count file)
+  "Splits the current window vertically
+and opens a new buffer name or edits a certain FILE."
+  :repeat nil
+  (interactive "P<f>")
+  (let ((new-window (split-window (selected-window) count
+                                  (if evil-vsplit-window-right 'right 'left))))
+    (when (and (not count) evil-auto-balance-windows)
+      (balance-windows (window-parent)))
+    (if file
+        (evil-edit file)
+      (let ((buffer (generate-new-buffer "*new*")))
+        (set-window-buffer new-window buffer)
+        (select-window new-window)
+        (with-current-buffer buffer
+          (funcall (default-value 'major-mode)))))))
+
+(evil-define-command evil-buffer-new (count file)
+  "Creates a new buffer replacing the current window, optionally
+   editing a certain FILE"
+  :repeat nil
+  (interactive "P<f>")
+  (if file
+      (evil-edit file)
+    (let ((buffer (generate-new-buffer "*new*")))
+      (set-window-buffer nil buffer)
+      (with-current-buffer buffer
+        (funcall (default-value 'major-mode))))))
+
+(evil-define-command evil-window-increase-height (count)
+  "Increase current window height by COUNT."
+  :repeat nil
+  (interactive "p")
+  (evil-resize-window (+ (window-height) count)))
+
+(evil-define-command evil-window-decrease-height (count)
+  "Decrease current window height by COUNT."
+  :repeat nil
+  (interactive "p")
+  (evil-resize-window (- (window-height) count)))
+
+(evil-define-command evil-window-increase-width (count)
+  "Increase current window width by COUNT."
+  :repeat nil
+  (interactive "p")
+  (evil-resize-window (+ (window-width) count) t))
+
+(evil-define-command evil-window-decrease-width (count)
+  "Decrease current window width by COUNT."
+  :repeat nil
+  (interactive "p")
+  (evil-resize-window (- (window-width) count) t))
+
+(evil-define-command evil-window-set-height (count)
+  "Sets the height of the current window to COUNT."
+  :repeat nil
+  (interactive "<c>")
+  (evil-resize-window (or count (frame-height)) nil))
+
+(evil-define-command evil-window-set-width (count)
+  "Sets the width of the current window to COUNT."
+  :repeat nil
+  (interactive "<c>")
+  (evil-resize-window (or count (frame-width)) t))
+
+(evil-define-command evil-ex-resize (arg)
+  "The ex :resize command.
+
+If ARG is a signed positive integer, increase the current window
+height by ARG.
+
+If ARG is a signed negative integer, decrease the current window
+height by ARG.
+
+If ARG is a positive integer without explicit sign, set the current
+window height to ARG.
+
+If ARG is empty, maximize the current window height."
+  (interactive "<a>")
+  (if (or (not arg) (= 0 (length arg)))
+      (evil-window-set-height nil)
+    (let ((n (string-to-number arg)))
+      (if (> n 0)
+          (if (= ?+ (aref arg 0))
+              (evil-window-increase-height n)
+            (evil-window-set-height n))
+        (evil-window-decrease-height (- n))))))
+
+(evil-define-command evil-window-rotate-upwards ()
+  "Rotates the windows according to the currenty cyclic ordering."
+  :repeat nil
+  (let ((wlist (window-list))
+        (blist (mapcar #'(lambda (w) (window-buffer w))
+                       (window-list))))
+    (setq blist (append (cdr blist) (list (car blist))))
+    (while (and wlist blist)
+      (set-window-buffer (car wlist) (car blist))
+      (setq wlist (cdr wlist)
+            blist (cdr blist)))
+    (select-window (car (last (window-list))))))
+
+(evil-define-command evil-window-rotate-downwards ()
+  "Rotates the windows according to the currenty cyclic ordering."
+  :repeat nil
+  (let ((wlist (window-list))
+        (blist (mapcar #'(lambda (w) (window-buffer w))
+                       (window-list))))
+    (setq blist (append (last blist) blist))
+    (while (and wlist blist)
+      (set-window-buffer (car wlist) (car blist))
+      (setq wlist (cdr wlist)
+            blist (cdr blist)))
+    (select-window (cadr (window-list)))))
+
+(evil-define-command evil-window-move-very-top ()
+  "Closes the current window, splits the upper-left one horizontally
+and redisplays the current buffer there."
+  :repeat nil
+  (unless (one-window-p)
+    (save-excursion
+      (let ((b (current-buffer)))
+        (delete-window)
+        (let ((btree (evil-get-buffer-tree (car (window-tree)))))
+          (delete-other-windows)
+          (let ((newwin (selected-window))
+                (subwin (split-window)))
+            (evil-restore-window-tree subwin btree)
+            (set-window-buffer newwin b)
+            (select-window newwin)))))
+    (balance-windows)))
+
+(evil-define-command evil-window-move-far-left ()
+  "Closes the current window, splits the upper-left one vertically
+and redisplays the current buffer there."
+  :repeat nil
+  (unless (one-window-p)
+    (save-excursion
+      (let ((b (current-buffer)))
+        (delete-window)
+        (let ((btree (evil-get-buffer-tree (car (window-tree)))))
+          (delete-other-windows)
+          (let ((newwin (selected-window))
+                (subwin (split-window-horizontally)))
+            (evil-restore-window-tree subwin btree)
+            (set-window-buffer newwin b)
+            (select-window newwin)))))
+    (balance-windows)))
+
+(evil-define-command evil-window-move-far-right ()
+  "Closes the current window, splits the lower-right one vertically
+and redisplays the current buffer there."
+  :repeat nil
+  (unless (one-window-p)
+    (save-excursion
+      (let ((b (current-buffer)))
+        (delete-window)
+        (let ((btree (evil-get-buffer-tree (car (window-tree)))))
+          (delete-other-windows)
+          (let ((subwin (selected-window))
+                (newwin (split-window-horizontally)))
+            (evil-restore-window-tree subwin btree)
+            (set-window-buffer newwin b)
+            (select-window newwin)))))
+    (balance-windows)))
+
+(evil-define-command evil-window-move-very-bottom ()
+  "Closes the current window, splits the lower-right one horizontally
+and redisplays the current buffer there."
+  :repeat nil
+  (unless (one-window-p)
+    (save-excursion
+      (let ((b (current-buffer)))
+        (delete-window)
+        (let ((btree (evil-get-buffer-tree (car (window-tree)))))
+          (delete-other-windows)
+          (let ((subwin (selected-window))
+                (newwin (split-window)))
+            (evil-restore-window-tree subwin btree)
+            (set-window-buffer newwin b)
+            (select-window newwin)))))
+    (balance-windows)))
+
+;;; Mouse handling
+
+;; Large parts of this code are taken from mouse.el which is
+;; distributed with GNU Emacs
+(defun evil-mouse-drag-region (start-event)
+  "Set the region to the text that the mouse is dragged over.
+Highlight the drag area as you move the mouse.
+This must be bound to a button-down mouse event.
+
+If the click is in the echo area, display the `*Messages*' buffer.
+
+START-EVENT should be the event that started the drag."
+  (interactive "e")
+  ;; Give temporary modes such as isearch a chance to turn off.
+  (run-hooks 'mouse-leave-buffer-hook)
+  (evil-mouse-drag-track start-event t))
+(evil-set-command-property 'evil-mouse-drag-region :keep-visual t)
+
+(defun evil-mouse-drag-track (start-event &optional
+                                          do-mouse-drag-region-post-process)
+  "Track mouse drags by highlighting area between point and cursor.
+The region will be defined with mark and point.
+DO-MOUSE-DRAG-REGION-POST-PROCESS should only be used by
+`mouse-drag-region'."
+  (mouse-minibuffer-check start-event)
+  (setq mouse-selection-click-count-buffer (current-buffer))
+  (deactivate-mark)
+  (let* ((scroll-margin 0) ; Avoid margin scrolling (Bug#9541).
+         (original-window (selected-window))
+         ;; We've recorded what we needed from the current buffer and
+         ;; window, now let's jump to the place of the event, where things
+         ;; are happening.
+         (_ (mouse-set-point start-event))
+         (echo-keystrokes 0)
+         (start-posn (event-start start-event))
+         (start-point (posn-point start-posn))
+         (start-window (posn-window start-posn))
+         (start-window-start (window-start start-window))
+         (start-hscroll (window-hscroll start-window))
+         (bounds (window-edges start-window))
+         (make-cursor-line-fully-visible nil)
+         (top (nth 1 bounds))
+         (bottom (if (window-minibuffer-p start-window)
+                     (nth 3 bounds)
+                   ;; Don't count the mode line.
+                   (1- (nth 3 bounds))))
+         (on-link (and mouse-1-click-follows-link
+                       (or mouse-1-click-in-non-selected-windows
+                           (eq start-window original-window))
+                       ;; Use start-point before the intangibility
+                       ;; treatment, in case we click on a link inside an
+                       ;; intangible text.
+                       (mouse-on-link-p start-posn)))
+         (click-count (1- (event-click-count start-event)))
+         (remap-double-click (and on-link
+                                  (eq mouse-1-click-follows-link 'double)
+                                  (= click-count 1)))
+         ;; Suppress automatic hscrolling, because that is a nuisance
+         ;; when setting point near the right fringe (but see below).
+         (auto-hscroll-mode-saved auto-hscroll-mode)
+         (auto-hscroll-mode nil)
+         event end end-point)
+
+    (setq mouse-selection-click-count click-count)
+    ;; In case the down click is in the middle of some intangible text,
+    ;; use the end of that text, and put it in START-POINT.
+    (if (< (point) start-point)
+        (goto-char start-point))
+    (setq start-point (point))
+    (if remap-double-click
+        (setq click-count 0))
+
+    (setq click-count (mod click-count 4))
+
+    ;; activate correct visual state
+    (let ((range (evil-mouse-start-end start-point start-point click-count)))
+      (set-mark (nth 0 range))
+      (goto-char (nth 1 range)))
+
+    (cond
+     ((= click-count 0)
+      (when (evil-visual-state-p) (evil-exit-visual-state)))
+     ((= click-count 1)
+      (evil-visual-char)
+      (evil-visual-post-command))
+     ((= click-count 2)
+      (evil-visual-line)
+      (evil-visual-post-command))
+     ((= click-count 3)
+      (evil-visual-block)
+      (evil-visual-post-command)))
+
+    ;; Track the mouse until we get a non-movement event.
+    (track-mouse
+      (while (progn
+               (setq event (read-key))
+               (or (mouse-movement-p event)
+                   (memq (car-safe event) '(switch-frame select-window))))
+        (unless (evil-visual-state-p)
+          (cond
+           ((= click-count 0) (evil-visual-char))
+           ((= click-count 1) (evil-visual-char))
+           ((= click-count 2) (evil-visual-line))
+           ((= click-count 3) (evil-visual-block))))
+
+        (evil-visual-pre-command)
+        (unless (memq (car-safe event) '(switch-frame select-window))
+          ;; Automatic hscrolling did not occur during the call to
+          ;; `read-event'; but if the user subsequently drags the
+          ;; mouse, go ahead and hscroll.
+          (let ((auto-hscroll-mode auto-hscroll-mode-saved))
+            (redisplay))
+          (setq end (event-end event)
+                end-point (posn-point end))
+          (if (and (eq (posn-window end) start-window)
+                   (integer-or-marker-p end-point))
+              (evil-mouse--drag-set-mark-and-point start-point
+                                                   end-point click-count)
+            (let ((mouse-row (cdr (cdr (mouse-position)))))
+              (cond
+               ((null mouse-row))
+               ((< mouse-row top)
+                (mouse-scroll-subr start-window (- mouse-row top)
+                                   nil start-point))
+               ((>= mouse-row bottom)
+                (mouse-scroll-subr start-window (1+ (- mouse-row bottom))
+                                   nil start-point))))))
+        (evil-visual-post-command)))
+
+    ;; Handle the terminating event if possible.
+    (when (consp event)
+      ;; Ensure that point is on the end of the last event.
+      (when (and (setq end-point (posn-point (event-end event)))
+                 (eq (posn-window end) start-window)
+                 (integer-or-marker-p end-point)
+                 (/= start-point end-point))
+        (evil-mouse--drag-set-mark-and-point start-point
+                                             end-point click-count))
+
+      ;; Find its binding.
+      (let* ((fun (key-binding (vector (car event))))
+             (do-multi-click (and (> (event-click-count event) 0)
+                                  (functionp fun)
+                                  (not (memq fun '(mouse-set-point
+                                                   mouse-set-region))))))
+        (if (and (or (/= (mark) (point))
+                     (= click-count 1) ; word selection
+                     (and (memq (evil-visual-type) '(line block))))
+                 (not do-multi-click))
+
+            ;; If point has moved, finish the drag.
+            (let (last-command this-command)
+              (and mouse-drag-copy-region
+                   do-mouse-drag-region-post-process
+                   (let (deactivate-mark)
+                     (evil-visual-expand-region)
+                     (copy-region-as-kill (mark) (point))
+                     (evil-visual-contract-region))))
+
+          ;; If point hasn't moved, run the binding of the
+          ;; terminating up-event.
+          (if do-multi-click
+              (goto-char start-point)
+            (deactivate-mark))
+          (when (and (functionp fun)
+                     (= start-hscroll (window-hscroll start-window))
+                     ;; Don't run the up-event handler if the window
+                     ;; start changed in a redisplay after the
+                     ;; mouse-set-point for the down-mouse event at
+                     ;; the beginning of this function.  When the
+                     ;; window start has changed, the up-mouse event
+                     ;; contains a different position due to the new
+                     ;; window contents, and point is set again.
+                     (or end-point
+                         (= (window-start start-window)
+                            start-window-start)))
+            (when (and on-link
+                       (= start-point (point))
+                       (evil-mouse--remap-link-click-p start-event event))
+              ;; If we rebind to mouse-2, reselect previous selected
+              ;; window, so that the mouse-2 event runs in the same
+              ;; situation as if user had clicked it directly.  Fixes
+              ;; the bug reported by juri@jurta.org on 2005-12-27.
+              (if (or (vectorp on-link) (stringp on-link))
+                  (setq event (aref on-link 0))
+                (select-window original-window)
+                (setcar event 'mouse-2)
+                ;; If this mouse click has never been done by the
+                ;; user, it doesn't have the necessary property to be
+                ;; interpreted correctly.
+                (put 'mouse-2 'event-kind 'mouse-click)))
+            (push event unread-command-events)))))))
+
+;; This function is a plain copy of `mouse--drag-set-mark-and-point',
+;; which is only available in Emacs 24
+(defun evil-mouse--drag-set-mark-and-point (start click click-count)
+  (let* ((range (evil-mouse-start-end start click click-count))
+         (beg (nth 0 range))
+         (end (nth 1 range)))
+    (cond ((eq (mark) beg)
+           (goto-char end))
+          ((eq (mark) end)
+           (goto-char beg))
+          ((< click (mark))
+           (set-mark end)
+           (goto-char beg))
+          (t
+           (set-mark beg)
+           (goto-char end)))))
+
+;; This function is a plain copy of `mouse--remap-link-click-p',
+;; which is only available in Emacs 23
+(defun evil-mouse--remap-link-click-p (start-event end-event)
+  (or (and (eq mouse-1-click-follows-link 'double)
+           (= (event-click-count start-event) 2))
+      (and
+       (not (eq mouse-1-click-follows-link 'double))
+       (= (event-click-count start-event) 1)
+       (= (event-click-count end-event) 1)
+       (or (not (integerp mouse-1-click-follows-link))
+           (let ((t0 (posn-timestamp (event-start start-event)))
+                 (t1 (posn-timestamp (event-end   end-event))))
+             (and (integerp t0) (integerp t1)
+                  (if (> mouse-1-click-follows-link 0)
+                      (<= (- t1 t0) mouse-1-click-follows-link)
+                    (< (- t0 t1) mouse-1-click-follows-link))))))))
+
+(defun evil-mouse-start-end (start end mode)
+  "Return a list of region bounds based on START and END according to MODE.
+If MODE is not 1 then set point to (min START END), mark to (max
+START END).  If MODE is 1 then set point to start of word at (min
+START END), mark to end of word at (max START END)."
+  (evil-sort start end)
+  (setq mode (mod mode 4))
+  (if (/= mode 1) (list start end)
+    (list
+     (save-excursion
+       (goto-char (min (point-max) (1+ start)))
+       (if (zerop (forward-thing evil-mouse-word -1))
+           (let ((bpnt (point)))
+             (forward-thing evil-mouse-word +1)
+             (if (> (point) start) bpnt (point)))
+         (point-min)))
+     (save-excursion
+       (goto-char end)
+       (1-
+        (if (zerop (forward-thing evil-mouse-word +1))
+            (let ((epnt (point)))
+              (forward-thing evil-mouse-word -1)
+              (if (<= (point) end) epnt (point)))
+          (point-max)))))))
+
+;;; State switching
+
+(evil-define-command evil-exit-emacs-state (&optional buffer message)
+  "Exit Emacs state.
+Changes the state to the previous state, or to Normal state
+if the previous state was Emacs state."
+  :keep-visual t
+  :suppress-operator t
+  (interactive '(nil t))
+  (with-current-buffer (or buffer (current-buffer))
+    (when (evil-emacs-state-p)
+      (evil-change-to-previous-state buffer message)
+      (when (evil-emacs-state-p)
+        (evil-normal-state (and message 1))))))
+
+(defun evil-execute-in-normal-state ()
+  "Execute the next command in Normal state."
+  (interactive)
+  (evil-delay '(not (memq this-command
+                          '(evil-execute-in-normal-state
+                            evil-use-register
+                            digit-argument
+                            negative-argument
+                            universal-argument
+                            universal-argument-minus
+                            universal-argument-more
+                            universal-argument-other-key)))
+      `(progn
+         (with-current-buffer ,(current-buffer)
+           (evil-change-state ',evil-state)
+           (setq evil-move-cursor-back ',evil-move-cursor-back)))
+    'post-command-hook)
+  (setq evil-move-cursor-back nil)
+  (evil-normal-state)
+  (evil-echo "Switched to Normal state for the next command ..."))
+
+(defun evil-stop-execute-in-emacs-state ()
+  (when (and (not (eq this-command #'evil-execute-in-emacs-state))
+             (not (minibufferp)))
+    (remove-hook 'post-command-hook 'evil-stop-execute-in-emacs-state)
+    (when (buffer-live-p evil-execute-in-emacs-state-buffer)
+      (with-current-buffer evil-execute-in-emacs-state-buffer
+        (if (and (eq evil-previous-state 'visual)
+                 (not (use-region-p)))
+            (progn
+              (evil-change-to-previous-state)
+              (evil-exit-visual-state))
+          (evil-change-to-previous-state))))
+    (setq evil-execute-in-emacs-state-buffer nil)))
+
+(evil-define-command evil-execute-in-emacs-state ()
+  "Execute the next command in Emacs state."
+  (add-hook 'post-command-hook #'evil-stop-execute-in-emacs-state t)
+  (setq evil-execute-in-emacs-state-buffer (current-buffer))
+  (cond
+   ((evil-visual-state-p)
+    (let ((mrk (mark))
+          (pnt (point)))
+      (evil-emacs-state)
+      (set-mark mrk)
+      (goto-char pnt)))
+   (t
+    (evil-emacs-state)))
+  (evil-echo "Switched to Emacs state for the next command ..."))
+
+(defun evil-exit-visual-and-repeat (event)
+  "Exit insert state and repeat event.
+This special command should be used if some command called from
+visual state should actually be called in normal-state.  The main
+reason for doing this is that the repeat system should *not*
+record the visual state information for some command.  This
+command should be bound to exactly the same event in visual state
+as the original command is bound in normal state.  EVENT is the
+event that triggered the execution of this command."
+  (interactive "e")
+  (when (evil-visual-state-p)
+    (evil-exit-visual-state)
+    (push event unread-command-events)))
+(evil-declare-ignore-repeat 'evil-exit-visual-and-repeat)
+
+(provide 'evil-commands)
+
+;;; evil-commands.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-commands.elc b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-commands.elc
new file mode 100644
index 0000000000..b01ba6dd99
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-commands.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-common.el b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-common.el
new file mode 100644
index 0000000000..62eda5fffa
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-common.el
@@ -0,0 +1,3883 @@
+;;; evil-common.el --- Common functions and utilities
+;; Author: Vegard Øye <vegard_oye at hotmail.com>
+;; Maintainer: Vegard Øye <vegard_oye at hotmail.com>
+
+;; Version: 1.2.13
+
+;;
+;; This file is NOT part of GNU Emacs.
+
+;;; License:
+
+;; This file is part of Evil.
+;;
+;; Evil 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.
+;;
+;; Evil 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 Evil.  If not, see <http://www.gnu.org/licenses/>.
+
+(require 'evil-vars)
+(require 'evil-digraphs)
+(require 'rect)
+(require 'thingatpt)
+
+;;; Code:
+
+(declare-function evil-visual-state-p "evil-states")
+(declare-function evil-visual-restore "evil-states")
+(declare-function evil-motion-state "evil-states")
+(declare-function evil-ex-p "evil-ex")
+(declare-function evil-set-jump "evil-jumps")
+
+(condition-case nil
+    (require 'windmove)
+  (error
+   (message "evil: Could not load `windmove', \
+window commands not available.")
+   nil))
+
+;;; Compatibility with different Emacs versions
+
+;; x-set-selection and x-get-selection have been deprecated since 25.1
+;; by gui-set-selection and gui-get-selection
+(defalias 'evil-get-selection
+  (if (fboundp 'gui-get-selection) 'gui-get-selection 'x-get-selection))
+(defalias 'evil-set-selection
+  (if (fboundp 'gui-set-selection) 'gui-set-selection 'x-set-selection))
+
+(defmacro evil-called-interactively-p ()
+  "Wrapper for `called-interactively-p'.
+In older versions of Emacs, `called-interactively-p' takes
+no arguments.  In Emacs 23.2 and newer, it takes one argument."
+  (called-interactively-p 'any))
+(make-obsolete 'evil-called-interactively-p
+               "please use (called-interactively-p 'any) instead."
+               "Git commit 222b791")
+
+;; macro helper
+(eval-and-compile
+  (defun evil-unquote (exp)
+    "Return EXP unquoted."
+    (while (eq (car-safe exp) 'quote)
+      (setq exp (cadr exp)))
+    exp))
+
+(defun evil-delay (condition form hook &optional append local name)
+  "Execute FORM when CONDITION becomes true, checking with HOOK.
+NAME specifies the name of the entry added to HOOK. If APPEND is
+non-nil, the entry is appended to the hook. If LOCAL is non-nil,
+the buffer-local value of HOOK is modified."
+  (if (and (not (booleanp condition)) (eval condition))
+      (eval form)
+    (let* ((name (or name (format "evil-delay-form-in-%s" hook)))
+           (fun (make-symbol name))
+           (condition (or condition t)))
+      (fset fun `(lambda (&rest args)
+                   (when ,condition
+                     (remove-hook ',hook #',fun ',local)
+                     ,form)))
+      (put fun 'permanent-local-hook t)
+      (add-hook hook fun append local))))
+(put 'evil-delay 'lisp-indent-function 2)
+
+;;; List functions
+
+(defun evil-add-to-alist (list-var key val &rest elements)
+  "Add the assocation of KEY and VAL to the value of LIST-VAR.
+If the list already contains an entry for KEY, update that entry;
+otherwise add at the end of the list."
+  (let ((tail (symbol-value list-var)))
+    (while (and tail (not (equal (car-safe (car-safe tail)) key)))
+      (setq tail (cdr tail)))
+    (if tail
+        (setcar tail (cons key val))
+      (set list-var (append (symbol-value list-var)
+                            (list (cons key val)))))
+    (if elements
+        (apply #'evil-add-to-alist list-var elements)
+      (symbol-value list-var))))
+
+;; custom version of `delete-if'
+(defun evil-filter-list (predicate list &optional pointer)
+  "Delete by side-effect all items satisfying PREDICATE in LIST.
+Stop when reaching POINTER.  If the first item satisfies PREDICATE,
+there is no way to remove it by side-effect; therefore, write
+\(setq foo (evil-filter-list 'predicate foo)) to be sure of
+changing the value of `foo'."
+  (let ((tail list) elt head)
+    (while (and tail (not (eq tail pointer)))
+      (setq elt (car tail))
+      (cond
+       ((funcall predicate elt)
+        (setq tail (cdr tail))
+        (if head
+            (setcdr head tail)
+          (setq list tail)))
+       (t
+        (setq head tail
+              tail (cdr tail)))))
+    list))
+
+(defun evil-member-if (predicate list &optional pointer)
+  "Find the first item satisfying PREDICATE in LIST.
+Stop when reaching POINTER, which should point at a link
+in the list."
+  (let (elt)
+    (catch 'done
+      (while (and (consp list) (not (eq list pointer)))
+        (setq elt (car list))
+        (if (funcall predicate elt)
+            (throw 'done elt)
+          (setq list (cdr list)))))))
+
+(defun evil-member-recursive-if (predicate tree)
+  "Find the first item satisfying PREDICATE in TREE."
+  (cond
+   ((funcall predicate tree)
+    tree)
+   ((listp tree)
+    (catch 'done
+      (dolist (elt tree)
+        (when (setq elt (evil-member-recursive-if predicate elt))
+          (throw 'done elt)))))))
+
+(defun evil-concat-lists (&rest sequences)
+  "Concatenate lists, removing duplicates.
+Elements are compared with `eq'."
+  (let (result)
+    (dolist (sequence sequences)
+      (dolist (elt sequence)
+        (add-to-list 'result elt nil #'eq)))
+    (nreverse result)))
+
+(defun evil-concat-alists (&rest sequences)
+  "Concatenate association lists, removing duplicates.
+An alist is a list of cons cells (KEY . VALUE) where each key
+may occur only once. Later values overwrite earlier values."
+  (let (result)
+    (dolist (sequence sequences)
+      (dolist (elt sequence)
+        (setq result (assq-delete-all (car-safe elt) result))
+        (push elt result)))
+    (nreverse result)))
+
+(defun evil-concat-plists (&rest sequences)
+  "Concatenate property lists, removing duplicates.
+A property list is a list (:KEYWORD1 VALUE1 :KEYWORD2 VALUE2...)
+where each keyword may occur only once. Later values overwrite
+earlier values."
+  (let (result)
+    (dolist (sequence sequences result)
+      (while sequence
+        (setq result
+              (plist-put result (pop sequence) (pop sequence)))))))
+
+(defun evil-concat-keymap-alists (&rest sequences)
+  "Concatenate keymap association lists, removing duplicates.
+A keymap alist is a list of cons cells (VAR . MAP) where each keymap
+may occur only once, but where the variables may be repeated
+\(e.g., (VAR . MAP1) (VAR . MAP2) is allowed). The order matters,
+with the highest priority keymaps being listed first."
+  (let (result)
+    (dolist (sequence sequences)
+      (dolist (elt sequence)
+        (unless (rassq (cdr-safe elt) result)
+          (push elt result))))
+    (nreverse result)))
+
+(defun evil-plist-delete (prop plist)
+  "Delete by side effect the property PROP from PLIST.
+If PROP is the first property in PLIST, there is no way
+to remove it by side-effect; therefore, write
+\(setq foo (evil-plist-delete :prop foo)) to be sure of
+changing the value of `foo'."
+  (let ((tail plist) elt head)
+    (while tail
+      (setq elt (car tail))
+      (cond
+       ((eq elt prop)
+        (setq tail (cdr (cdr tail)))
+        (if head
+            (setcdr (cdr head) tail)
+          (setq plist tail)))
+       (t
+        (setq head tail
+              tail (cdr (cdr tail))))))
+    plist))
+
+(defun evil-get-property (alist key &optional prop)
+  "Return property PROP for KEY in ALIST.
+ALIST is an association list with entries of the form
+\(KEY . PLIST), where PLIST is a property list.
+If PROP is nil, return all properties for KEY.
+If KEY is t, return an association list of keys
+and their PROP values."
+  (cond
+   ((null prop)
+    (cdr (assq key alist)))
+   ((eq key t)
+    (let (result val)
+      (dolist (entry alist result)
+        (setq key (car entry)
+              val (cdr entry))
+        (when (plist-member val prop)
+          (setq val (plist-get val prop))
+          (push (cons key val) result)))))
+   (t
+    (plist-get (cdr (assq key alist)) prop))))
+
+(defun evil-put-property (alist-var key prop val &rest properties)
+  "Set PROP to VAL for KEY in ALIST-VAR.
+ALIST-VAR points to an association list with entries of the form
+\(KEY . PLIST), where PLIST is a property list storing PROP and VAL."
+  (set alist-var
+       (let* ((alist (symbol-value alist-var))
+              (plist (cdr (assq key alist))))
+         (setq plist (plist-put plist prop val))
+         (when properties
+           (setq plist (evil-concat-plists plist properties)
+                 val (car (last properties))))
+         (setq alist (assq-delete-all key alist))
+         (push (cons key plist) alist)))
+  val)
+
+(defun evil-state-property (state prop &optional value)
+  "Return the value of property PROP for STATE.
+PROP is a keyword as used by `evil-define-state'.
+STATE is the state's symbolic name.
+If VALUE is non-nil and the value is a variable,
+return the value of that variable."
+  (let ((val (evil-get-property evil-state-properties state prop)))
+    (if (and value (symbolp val) (boundp val))
+        (symbol-value val)
+      val)))
+
+(defmacro evil-swap (this that &rest vars)
+  "Swap the values of variables THIS and THAT.
+If three or more arguments are given, the values are rotated.
+E.g., (evil-swap A B C) sets A to B, B to C, and C to A."
+  `(progn
+     (setq ,this (prog1 ,that
+                   (setq ,that ,this)))
+     ,@(when vars
+         `((evil-swap ,that ,@vars)))))
+
+(defmacro evil-sort (min max &rest vars)
+  "Place the smallest value in MIN and the largest in MAX.
+If three or more arguments are given, place the smallest
+value in the first argument and the largest in the last,
+sorting in between."
+  (let ((sorted (make-symbol "sortvar")))
+    `(let ((,sorted (sort (list ,min ,max ,@vars) '<)))
+       (setq ,min (pop ,sorted)
+             ,max (pop ,sorted)
+             ,@(apply #'append
+                      (mapcar #'(lambda (var)
+                                  (list var `(pop ,sorted)))
+                              vars))))))
+
+(defun evil-vector-to-string (vector)
+  "Turns vector into a string, changing <escape> to '\\e'"
+  (mapconcat (lambda (c)
+               (if (equal c 'escape)
+                   "\e"
+                 (make-string 1 c)))
+             vector
+             ""))
+
+;;; Command properties
+
+(defmacro evil-define-command (command &rest body)
+  "Define a command COMMAND.
+
+\(fn COMMAND (ARGS...) DOC [[KEY VALUE]...] BODY...)"
+  (declare (indent defun)
+           (debug (&define name
+                           [&optional lambda-list]
+                           [&optional stringp]
+                           [&rest keywordp sexp]
+                           [&optional ("interactive" [&rest form])]
+                           def-body)))
+  (let ((interactive '(interactive))
+        arg args doc doc-form key keys)
+    ;; collect arguments
+    (when (listp (car-safe body))
+      (setq args (pop body)))
+    ;; collect docstring
+    (when (> (length body) 1)
+      (if (eq (car-safe (car-safe body)) 'format)
+          (setq doc-form (pop body))
+        (when (stringp (car-safe body))
+          (setq doc (pop body)))))
+    ;; collect keywords
+    (setq keys (plist-put keys :repeat t))
+    (while (keywordp (car-safe body))
+      (setq key (pop body)
+            arg (pop body))
+      (unless nil ; TODO: add keyword check
+        (setq keys (plist-put keys key arg))))
+    ;; collect `interactive' form
+    (when (and body (consp (car body))
+               (eq (car (car body)) 'interactive))
+      (let* ((iform (pop body))
+             (result (apply #'evil-interactive-form (cdr iform)))
+             (form (car result))
+             (attrs (cdr result)))
+        (setq interactive `(interactive ,form)
+              keys (evil-concat-plists keys attrs))))
+    `(progn
+       ;; the compiler does not recognize `defun' inside `let'
+       ,(when (and command body)
+          `(defun ,command ,args
+             ,@(when doc `(,doc))
+             ,interactive
+             ,@body))
+       ,(when (and command doc-form)
+          `(put ',command 'function-documentation ,doc-form))
+       ;; set command properties for symbol or lambda function
+       (let ((func ',(if (and (null command) body)
+                         `(lambda ,args
+                            ,interactive
+                            ,@body)
+                       command)))
+         (apply #'evil-set-command-properties func ',keys)
+         func))))
+
+;; If no Evil properties are defined for the command, several parts of
+;; Evil apply certain default rules; e.g., the repeat system decides
+;; whether the command is repeatable by monitoring buffer changes.
+(defun evil-has-command-property-p (command property)
+  "Whether COMMAND has Evil PROPERTY.
+See also `evil-has-command-properties-p'."
+  (plist-member (evil-get-command-properties command) property))
+
+(defun evil-has-command-properties-p (command)
+  "Whether Evil properties are defined for COMMAND.
+See also `evil-has-command-property-p'."
+  (and (evil-get-command-properties command) t))
+
+(defun evil-get-command-property (command property &optional default)
+  "Return the value of Evil PROPERTY of COMMAND.
+If the command does not have the property, return DEFAULT.
+See also `evil-get-command-properties'."
+  (if (evil-has-command-property-p command property)
+      (evil-get-property evil-command-properties command property)
+    default))
+
+(defun evil-get-command-properties (command)
+  "Return all Evil properties of COMMAND.
+See also `evil-get-command-property'."
+  (evil-get-property evil-command-properties command))
+
+(defun evil-set-command-property (command property value)
+  "Set PROPERTY to VALUE for COMMAND.
+To set multiple properties at once, see
+`evil-set-command-properties' and `evil-add-command-properties'."
+  (evil-put-property 'evil-command-properties command property value))
+(defalias 'evil-put-command-property 'evil-set-command-property)
+
+(defun evil-add-command-properties (command &rest properties)
+  "Add PROPERTIES to COMMAND.
+PROPERTIES should be a property list.
+To replace all properties at once, use `evil-set-command-properties'."
+  (apply #'evil-put-property
+         'evil-command-properties command properties))
+
+(defun evil-set-command-properties (command &rest properties)
+  "Replace all of COMMAND's properties with PROPERTIES.
+PROPERTIES should be a property list.
+This erases all previous properties; to only add properties,
+use `evil-set-command-property'."
+  (setq evil-command-properties
+        (assq-delete-all command evil-command-properties))
+  (when properties
+    (apply #'evil-add-command-properties command properties)))
+
+(defun evil-remove-command-properties (command &rest properties)
+  "Remove PROPERTIES from COMMAND.
+PROPERTIES should be a list of properties (:PROP1 :PROP2 ...).
+If PROPERTIES is the empty list, all properties are removed."
+  (let (plist)
+    (when properties
+      (setq plist (evil-get-command-properties command))
+      (dolist (property properties)
+        (setq plist (evil-plist-delete property plist))))
+    (apply #'evil-set-command-properties command plist)))
+
+(defun evil-yank-handler (&optional motion)
+  "Return the yank handler for MOTION.
+MOTION defaults to the current motion."
+  (setq motion (or motion evil-this-motion))
+  (evil-get-command-property motion :yank-handler))
+
+(defun evil-declare-motion (command)
+  "Declare COMMAND to be a movement function.
+This ensures that it behaves correctly in Visual state."
+  (evil-add-command-properties command :keep-visual t :repeat 'motion))
+
+(defun evil-declare-repeat (command)
+  "Declare COMMAND to be repeatable."
+  (evil-add-command-properties command :repeat t))
+
+(defun evil-declare-not-repeat (command)
+  "Declare COMMAND to be nonrepeatable."
+  (evil-add-command-properties command :repeat nil))
+
+(defun evil-declare-ignore-repeat (command)
+  "Declare COMMAND to be nonrepeatable."
+  (evil-add-command-properties command :repeat 'ignore))
+
+(defun evil-declare-change-repeat (command)
+  "Declare COMMAND to be repeatable by buffer changes."
+  (evil-add-command-properties command :repeat 'change))
+
+(defun evil-declare-insert-at-point-repeat (command)
+  "Declare COMMAND to be repeatable by buffer changes."
+  (evil-add-command-properties command :repeat 'insert-at-point))
+
+(defun evil-declare-abort-repeat (command)
+  "Declare COMMAND to be nonrepeatable."
+  (evil-add-command-properties command :repeat 'abort))
+
+(defun evil-delimited-arguments (string &optional num)
+  "Parse STRING as a sequence of delimited arguments.
+Returns a list of NUM strings, or as many arguments as
+the string contains. The first non-blank character is
+taken to be the delimiter. If some arguments are missing
+from STRING, the resulting list is padded with nil values.
+Two delimiters following directly after each other gives
+an empty string."
+  (save-match-data
+    (let ((string (or string ""))
+          (count (or num -1)) (idx 0)
+          argument delim match result)
+      (when (string-match "^[[:space:]]*\\([^[:space:]]\\)" string)
+        (setq delim (match-string 1 string)
+              argument (format "%s\\(\\(?:[\\].\\|[^%s]\\)*\\)"
+                               (regexp-quote delim)
+                               delim))
+        (while (and (/= count 0) (string-match argument string idx))
+          (setq match (match-string 1 string)
+                idx (match-end 1)
+                count (1- count))
+          (when (= count 0)
+            (unless (save-match-data
+                      (string-match
+                       (format "%s[[:space:]]*$" delim) string idx))
+              (setq match (substring string (match-beginning 1)))))
+          (unless (and (zerop (length match))
+                       (zerop (length (substring string idx))))
+            (push match result))))
+      (when (and num (< (length result) num))
+        (dotimes (i (- num (length result)))
+          (push nil result)))
+      (nreverse result))))
+
+(defun evil-concat-charsets (&rest sets)
+  "Concatenate character sets.
+A character set is the part between [ and ] in a regular expression.
+If any character set is complemented, the result is also complemented."
+  (let ((bracket "") (complement "") (hyphen "") result)
+    (save-match-data
+      (dolist (set sets)
+        (when (string-match-p "^\\^" set)
+          (setq set (substring set 1)
+                complement "^"))
+        (when (string-match-p "^]" set)
+          (setq set (substring set 1)
+                bracket "]"))
+        (when (string-match-p "^-" set)
+          (setq set (substring set 1)
+                hyphen "-"))
+        (setq result (concat result set)))
+      (format "%s%s%s%s" complement bracket hyphen result))))
+
+;;; Key sequences
+
+(defun evil-keypress-parser (&optional input)
+  "Read from keyboard or INPUT and build a command description.
+Returns (CMD COUNT), where COUNT is the numeric prefix argument.
+Both COUNT and CMD may be nil."
+  (let (count negative)
+    (when input (setq unread-command-events (append input unread-command-events)))
+    (catch 'done
+      (while t
+        (let ((seq (read-key-sequence "")))
+          (when seq
+            (let ((cmd (key-binding seq)))
+              (cond
+               ((null cmd) (throw 'done (list nil nil)))
+               ((arrayp cmd) ; keyboard macro, recursive call
+                (let ((cmd (evil-keypress-parser cmd)))
+                  (throw 'done
+                         (list (car cmd)
+                               (if (or count (cadr cmd))
+                                   (list (car cmd) (* (or count 1)
+                                                      (or (cadr cmd) 1))))))))
+               ((or (eq cmd #'digit-argument)
+                    (and (eq cmd 'evil-digit-argument-or-evil-beginning-of-line)
+                         count))
+                (let* ((event (aref seq (- (length seq) 1)))
+                       (char (or (when (characterp event) event)
+                                 (when (symbolp event)
+                                   (get event 'ascii-character))))
+                       (digit (if (or (characterp char) (integerp char))
+                                  (- (logand char ?\177) ?0))))
+                  (setq count (+ (* 10 (or count 0)) digit))))
+               ((eq cmd #'negative-argument)
+                (setq negative (not negative)))
+               (t
+                (throw 'done (list cmd
+                                   (and count
+                                        (* count
+                                           (if negative -1 1))))))))))))))
+
+(defun evil-read-key (&optional prompt)
+  "Read a key from the keyboard.
+Translates it according to the input method."
+  (let ((old-global-map (current-global-map))
+        (new-global-map (make-sparse-keymap))
+        (overriding-terminal-local-map nil)
+        (overriding-local-map evil-read-key-map)
+        seq char cmd)
+    (unwind-protect
+        (condition-case nil
+            (progn
+              (define-key new-global-map [menu-bar]
+                (lookup-key global-map [menu-bar]))
+              (define-key new-global-map [tool-bar]
+                (lookup-key global-map [tool-bar]))
+              (add-to-list 'new-global-map
+                           (make-char-table 'display-table
+                                            'self-insert-command) t)
+              (use-global-map new-global-map)
+              (setq seq (read-key-sequence prompt nil t)
+                    char (aref seq 0)
+                    cmd (key-binding seq))
+              (while (arrayp cmd)
+                (setq char (aref cmd 0)
+                      cmd (key-binding cmd)))
+              (cond
+               ((eq cmd 'self-insert-command)
+                char)
+               (cmd
+                (call-interactively cmd))
+               (t
+                (user-error "No replacement character typed"))))
+          (quit
+           (when (fboundp 'evil-repeat-abort)
+             (evil-repeat-abort))
+           (signal 'quit nil)))
+      (use-global-map old-global-map))))
+
+(defun evil-read-quoted-char ()
+  "Command that calls `read-quoted-char'.
+This command can be used wherever `read-quoted-char' is required
+as a command. Its main use is in the `evil-read-key-map'."
+  (interactive)
+  (read-quoted-char))
+
+(defun evil-read-digraph-char (&optional hide-chars)
+  "Read two keys from keyboard forming a digraph.
+This function creates an overlay at (point), hiding the next
+HIDE-CHARS characters. HIDE-CHARS defaults to 1."
+  (interactive)
+  (let (char1 char2 string overlay)
+    (unwind-protect
+        (progn
+          (setq overlay (make-overlay (point)
+                                      (min (point-max)
+                                           (+ (or hide-chars 1)
+                                              (point)))))
+          (overlay-put overlay 'invisible t)
+          ;; create overlay prompt
+          (setq string "?")
+          (put-text-property 0 1 'face 'minibuffer-prompt string)
+          ;; put cursor at (i.e., right before) the prompt
+          (put-text-property 0 1 'cursor t string)
+          (overlay-put overlay 'after-string string)
+          (setq char1 (read-key))
+          (setq string (string char1))
+          (put-text-property 0 1 'face 'minibuffer-prompt string)
+          (put-text-property 0 1 'cursor t string)
+          (overlay-put overlay 'after-string string)
+          (setq char2 (read-key)))
+      (delete-overlay overlay))
+    (or (evil-digraph (list char1 char2))
+        ;; use the last character if undefined
+        char2)))
+
+(defun evil-read-motion (&optional motion count type modifier)
+  "Read a MOTION, motion COUNT and motion TYPE from the keyboard.
+The type may be overridden with MODIFIER, which may be a type
+or a Visual selection as defined by `evil-define-visual-selection'.
+Return a list (MOTION COUNT [TYPE])."
+  (let ((modifiers '((evil-visual-char . char)
+                     (evil-visual-line . line)
+                     (evil-visual-block . block)))
+        command prefix)
+    (setq evil-this-type-modified nil)
+    (unless motion
+      (while (progn
+               (setq command (evil-keypress-parser)
+                     motion (pop command)
+                     prefix (pop command))
+               (when prefix
+                 (if count
+                     (setq count (string-to-number
+                                  (concat (number-to-string count)
+                                          (number-to-string prefix))))
+                   (setq count prefix)))
+               ;; if the command is a type modifier, read more
+               (when (rassq motion evil-visual-alist)
+                 (setq modifier
+                       (or modifier
+                           (car (rassq motion evil-visual-alist))))))))
+    (when modifier
+      (setq type (or type (evil-type motion 'exclusive)))
+      (cond
+       ((eq modifier 'char)
+        ;; TODO: this behavior could be less hard-coded
+        (if (eq type 'exclusive)
+            (setq type 'inclusive)
+          (setq type 'exclusive)))
+       (t
+        (setq type modifier)))
+      (setq evil-this-type-modified type))
+    (list motion count type)))
+
+(defun evil-mouse-events-p (keys)
+  "Returns non-nil iff KEYS contains a mouse event."
+  (catch 'done
+    (dotimes (i (length keys))
+      (when (or (and (fboundp 'mouse-event-p)
+                     (mouse-event-p (aref keys i)))
+                (mouse-movement-p (aref keys i)))
+        (throw 'done t)))
+    nil))
+
+(defun evil-extract-count (keys)
+  "Splits the key-sequence KEYS into prefix-argument and the rest.
+Returns the list (PREFIX CMD SEQ REST), where PREFIX is the
+prefix count, CMD the command to be executed, SEQ the subsequence
+calling CMD, and REST is all remaining events in the
+key-sequence. PREFIX and REST may be nil if they do not exist.
+If a command is bound to some keyboard macro, it is expanded
+recursively."
+  (catch 'done
+    (let* ((len (length keys))
+           (beg 0)
+           (end 1)
+           (found-prefix nil))
+      (while (and (<= end len))
+        (let ((cmd (key-binding (substring keys beg end))))
+          (cond
+           ((memq cmd '(undefined nil))
+            (user-error "No command bound to %s" (substring keys beg end)))
+           ((arrayp cmd) ; keyboard macro, replace command with macro
+            (setq keys (vconcat (substring keys 0 beg)
+                                cmd
+                                (substring keys end))
+                  end (1+ beg)
+                  len (length keys)))
+           ((functionp cmd)
+            (if (or (memq cmd '(digit-argument negative-argument))
+                    (and found-prefix
+                         (evil-get-command-property
+                          cmd :digit-argument-redirection)))
+                ;; skip those commands
+                (setq found-prefix t ; found at least one prefix argument
+                      beg end
+                      end (1+ end))
+              ;; a real command, finish
+              (throw 'done
+                     (list (unless (zerop beg)
+                             (string-to-number
+                              (concat (substring keys 0 beg))))
+                           cmd
+                           (substring keys beg end)
+                           (when (< end len)
+                             (substring keys end))))))
+           (t ; append a further event
+            (setq end (1+ end))))))
+      (user-error "Key sequence contains no complete binding"))))
+
+(defmacro evil-redirect-digit-argument (map keys target)
+  "Bind a wrapper function calling TARGET or `digit-argument'.
+MAP is a keymap for binding KEYS to the wrapper for TARGET.
+The wrapper only calls `digit-argument' if a prefix-argument
+has already been started; otherwise TARGET is called."
+  (let* ((target (eval target))
+         (wrapper (intern (format "evil-digit-argument-or-%s"
+                                  target))))
+    `(progn
+       (define-key ,map ,keys ',wrapper)
+       (evil-define-command ,wrapper ()
+         :digit-argument-redirection ,target
+         :keep-visual t
+         :repeat nil
+         (interactive)
+         (cond
+          (current-prefix-arg
+           (setq this-command #'digit-argument)
+           (call-interactively #'digit-argument))
+          (t
+           (let ((target (or (command-remapping #',target)
+                             #',target)))
+             (setq this-command target)
+             (call-interactively target))))))))
+
+(defun evil-extract-append (file-or-append)
+  "Return an (APPEND . FILENAME) pair based on FILE-OR-APPEND.
+FILE-OR-APPEND should either be a filename or a \">> FILE\"
+directive.  APPEND will be t if FILE-OR-APPEND is an append
+directive and nil otherwise.  FILENAME will be the extracted
+filename."
+  (if (and (stringp file-or-append)
+           (string-match "\\(>> *\\)" file-or-append))
+      (cons t (substring file-or-append(match-end 1)))
+    (cons nil file-or-append)))
+
+(defun evil-set-keymap-prompt (map prompt)
+  "Set the prompt-string of MAP to PROMPT."
+  (delq (keymap-prompt map) map)
+  (when prompt
+    (setcdr map (cons prompt (cdr map)))))
+
+(defun evil-lookup-key (map key)
+  "Returns non-nil value if KEY is bound in MAP."
+  (let ((definition (lookup-key map key)))
+    (if (numberp definition) ; in-band error
+        nil
+      definition)))
+
+;;; Display
+
+(defun evil-set-cursor (specs)
+  "Change the cursor's apperance according to SPECS.
+SPECS may be a cursor type as per `cursor-type', a color
+string as passed to `set-cursor-color', a zero-argument
+function for changing the cursor, or a list of the above."
+  (unless (and (listp specs)
+               (null (cdr-safe (last specs))))
+    (setq specs (list specs)))
+  (dolist (spec specs)
+    (cond
+     ((functionp spec)
+      (condition-case nil
+          (funcall spec)
+        (error nil)))
+     ((stringp spec)
+      (evil-set-cursor-color spec))
+     (t
+      (setq cursor-type spec)))))
+
+(defun evil-set-cursor-color (color)
+  "Set the cursor color to COLOR."
+  (unless (equal (frame-parameter nil 'cursor-color) color)
+    ;; `set-cursor-color' forces a redisplay, so only
+    ;; call it when the color actually changes
+    (set-cursor-color color)))
+
+(defun evil-refresh-cursor (&optional state buffer)
+  "Refresh the cursor for STATE in BUFFER.
+BUFFER defaults to the current buffer.  If STATE is nil the
+cursor type is either `evil-force-cursor' or the current state."
+  (when (and (boundp 'evil-local-mode) evil-local-mode)
+    (let* ((state (or state evil-force-cursor evil-state 'normal))
+           (default (or evil-default-cursor t))
+           (cursor (evil-state-property state :cursor t))
+           (color (or (and (stringp cursor) cursor)
+                      (and (listp cursor)
+                           (evil-member-if #'stringp cursor))
+                      (frame-parameter nil 'cursor-color))))
+      (with-current-buffer (or buffer (current-buffer))
+        ;; if both STATE and `evil-default-cursor'
+        ;; specify a color, don't set it twice
+        (when (and color (listp default))
+          (setq default (evil-filter-list #'stringp default)))
+        (evil-set-cursor default)
+        (evil-set-cursor cursor)))))
+
+(defmacro evil-save-cursor (&rest body)
+  "Save the current cursor; execute BODY; restore the cursor."
+  (declare (indent defun)
+           (debug t))
+  `(let ((cursor cursor-type)
+         (color (frame-parameter (selected-frame) 'cursor-color))
+         (inhibit-quit t))
+     (unwind-protect
+         (progn ,@body)
+       (evil-set-cursor cursor)
+       (evil-set-cursor color))))
+
+(defun evil-echo (string &rest args)
+  "Display an unlogged message in the echo area.
+That is, the message is not logged in the *Messages* buffer.
+\(To log the message, just use `message'.)"
+  (unless evil-no-display
+    (let (message-log-max)
+      (apply #'message string args))))
+
+(defun evil-echo-area-save ()
+  "Save the current echo area in `evil-echo-area-message'."
+  (setq evil-echo-area-message (current-message)))
+
+(defun evil-echo-area-restore ()
+  "Restore the echo area from `evil-echo-area-message'.
+Does not restore if `evil-write-echo-area' is non-nil."
+  (unless evil-write-echo-area
+    (if evil-echo-area-message
+        (message "%s" evil-echo-area-message)
+      (message nil)))
+  (setq evil-echo-area-message nil
+        evil-write-echo-area nil))
+
+;; toggleable version of `with-temp-message'
+(defmacro evil-save-echo-area (&rest body)
+  "Save the echo area; execute BODY; restore the echo area.
+Intermittent messages are not logged in the *Messages* buffer."
+  (declare (indent defun)
+           (debug t))
+  `(let ((inhibit-quit t)
+         evil-echo-area-message
+         evil-write-echo-area)
+     (unwind-protect
+         (progn
+           (evil-echo-area-save)
+           ,@body)
+       (evil-echo-area-restore))))
+
+(defmacro evil-without-display (&rest body)
+  "Execute BODY without Evil displays.
+Inhibits echo area messages, mode line updates and cursor changes."
+  (declare (indent defun)
+           (debug t))
+  `(let ((evil-no-display t))
+     ,@body))
+
+(defun evil-num-visible-lines ()
+  "Returns the number of currently visible lines."
+  (- (window-height) 1))
+
+(defun evil-count-lines (beg end)
+  "Return absolute line-number-difference betweeen `beg` and `end`.
+This should give the same results no matter where on the line `beg`
+and `end` are."
+  (if (= beg end)
+      0
+    (let* ((last (max beg end))
+           (end-at-bol (save-excursion (goto-char last)
+                                       (bolp))))
+      (if end-at-bol
+          (count-lines beg end)
+        (1- (count-lines beg end))))))
+
+;;; Movement
+
+(defun evil-normalize-position (pos)
+  "Return POS if it does not exceed the buffer boundaries.
+If POS is less than `point-min', return `point-min'.
+Is POS is more than `point-max', return `point-max'.
+If POS is a marker, return its position."
+  (cond
+   ((not (number-or-marker-p pos))
+    pos)
+   ((< pos (point-min))
+    (point-min))
+   ((> pos (point-max))
+    (point-max))
+   ((markerp pos)
+    (marker-position pos))
+   (t
+    pos)))
+
+(defmacro evil-save-goal-column (&rest body)
+  "Restores the goal column after execution of BODY.
+See also `evil-save-column'."
+  (declare (indent defun)
+           (debug t))
+  `(let ((goal-column goal-column)
+         (temporary-goal-column temporary-goal-column))
+     ,@body))
+
+(defmacro evil-save-column (&rest body)
+  "Restores the column after execution of BODY.
+See also `evil-save-goal-column'."
+  (declare (indent defun)
+           (debug t))
+  `(let ((col (current-column)))
+     (evil-save-goal-column
+       ,@body
+       (move-to-column col))))
+
+(defun evil-narrow (beg end)
+  "Restrict the buffer to BEG and END.
+BEG or END may be nil, specifying a one-sided restriction including
+`point-min' or `point-max'. See also `evil-with-restriction.'"
+  (setq beg (or (evil-normalize-position beg) (point-min)))
+  (setq end (or (evil-normalize-position end) (point-max)))
+  (narrow-to-region beg end))
+
+(defmacro evil-with-restriction (beg end &rest body)
+  "Execute BODY with the buffer narrowed to BEG and END.
+BEG or END may be nil as passed to `evil-narrow'; this creates
+a one-sided restriction."
+  (declare (indent 2)
+           (debug t))
+  `(save-restriction
+     (let ((evil-restriction-stack
+            (cons (cons (point-min) (point-max)) evil-restriction-stack)))
+       (evil-narrow ,beg ,end)
+       ,@body)))
+
+(defmacro evil-without-restriction (&rest body)
+  "Execute BODY with the top-most narrowing removed.
+This works only if the previous narrowing has been generated by
+`evil-with-restriction'."
+  (declare (indent defun)
+           (debug t))
+  `(save-restriction
+     (widen)
+     (narrow-to-region (car (car evil-restriction-stack))
+                       (cdr (car evil-restriction-stack)))
+     (let ((evil-restriction-stack (cdr evil-restriction-stack)))
+       ,@body)))
+
+(defmacro evil-narrow-to-field (&rest body)
+  "Narrow to the current field."
+  (declare (indent defun)
+           (debug t))
+  `(evil-with-restriction (field-beginning) (field-end)
+     ,@body))
+
+(defun evil-move-beginning-of-line (&optional arg)
+  "Move to the beginning of the line as displayed.
+Like `move-beginning-of-line', but retains the goal column."
+  (evil-save-goal-column
+    (move-beginning-of-line arg)
+    (beginning-of-line)))
+
+(defun evil-move-end-of-line (&optional arg)
+  "Move to the end of the line as displayed.
+Like `move-end-of-line', but retains the goal column."
+  (evil-save-goal-column
+    (move-end-of-line arg)
+    (end-of-line)))
+
+(defun evil-adjust-cursor (&optional force)
+  "Move point one character back if at the end of a non-empty line.
+This behavior is contingent on the variable `evil-move-cursor-back';
+use the FORCE parameter to override it."
+  (when (and (eolp)
+             (not evil-move-beyond-eol)
+             (not (bolp))
+             (= (point)
+                (save-excursion
+                  (evil-move-end-of-line)
+                  (point))))
+    (evil-move-cursor-back force)))
+
+(defun evil-move-cursor-back (&optional force)
+  "Move point one character back within the current line.
+Contingent on the variable `evil-move-cursor-back' or the FORCE
+argument. Honors field boundaries, i.e., constrains the movement
+to the current field as recognized by `line-beginning-position'."
+  (when (or evil-move-cursor-back force)
+    (unless (or (= (point) (line-beginning-position))
+                (and (boundp 'visual-line-mode)
+                     visual-line-mode
+                     (= (point) (save-excursion
+                                  (beginning-of-visual-line)
+                                  (point)))))
+      (backward-char))))
+
+(defun evil-line-position (line &optional column)
+  "Return the position of LINE.
+If COLUMN is specified, return its position on the line.
+A negative number means the end of the line."
+  (save-excursion
+    (when (fboundp 'evil-goto-line)
+      (evil-goto-line line))
+    (if (numberp column)
+        (if (< column 0)
+            (beginning-of-line 2)
+          (move-to-column column))
+      (beginning-of-line))
+    (point)))
+
+(defun evil-column (&optional pos)
+  "Return the horizontal position of POS.
+POS defaults to point."
+  (save-excursion
+    (when pos
+      (goto-char pos))
+    (current-column)))
+
+(defun evil-move-to-column (column &optional dir force)
+  "Move point to column COLUMN in the current line.
+Places point at left of the tab character (at the right if DIR
+is non-nil) and returns point."
+  (interactive "p")
+  (move-to-column column force)
+  (unless force
+    (when (or (not dir) (and (numberp dir) (< dir 1)))
+      (when (> (current-column) column)
+        (evil-move-cursor-back))))
+  (point))
+
+(defmacro evil-loop (spec &rest body)
+  "Loop with countdown variable.
+Evaluate BODY with VAR counting down from COUNT to 0.
+COUNT can be negative, in which case VAR counts up instead.
+The return value is the value of VAR when the loop
+terminates, which is 0 if the loop completes successfully.
+RESULT specifies a variable for storing this value.
+
+\(fn (VAR COUNT [RESULT]) BODY...)"
+  (declare (indent defun)
+           (debug dolist))
+  (let* ((i (make-symbol "loopvar"))
+         (var (pop spec))
+         (count (pop spec))
+         (result (pop spec)))
+    (setq var (or (unless (eq var result) var) i)
+          result (or result var))
+    `(let ((,var ,count))
+       (setq ,result ,var)
+       (while (/= ,var 0)
+         ,@body
+         (if (> ,var 0)
+             (setq ,var (1- ,var))
+           (setq ,var (1+ ,var)))
+         (setq ,result ,var))
+       ,var)))
+
+;;; Motions
+
+(defmacro evil-motion-loop (spec &rest body)
+  "Loop a certain number of times.
+Evaluate BODY repeatedly COUNT times with VAR bound to 1 or -1,
+depending on the sign of COUNT. RESULT, if specified, holds
+the number of unsuccessful iterations, which is 0 if the loop
+completes successfully. This is also the return value.
+
+Each iteration must move point; if point does not change,
+the loop immediately quits. See also `evil-loop'.
+
+\(fn (VAR COUNT [RESULT]) BODY...)"
+  (declare (indent defun)
+           (debug ((symbolp form &optional symbolp) body)))
+  (let* ((var (or (pop spec) (make-symbol "unitvar")))
+         (countval (or (pop spec) 0))
+         (result (pop spec))
+         (i (make-symbol "loopvar"))
+         (count (make-symbol "countvar"))
+         (done (make-symbol "donevar"))
+         (orig (make-symbol "origvar")))
+    `(let* ((,count ,countval)
+            (,var (if (< ,count 0) -1 1)))
+       (catch ',done
+         (evil-loop (,i ,count ,result)
+           (let ((,orig (point)))
+             ,@body
+             (when (= (point) ,orig)
+               (throw ',done ,i))))))))
+
+(defmacro evil-signal-without-movement (&rest body)
+  "Catches errors provided point moves within this scope."
+  (declare (indent defun)
+           (debug t))
+  `(let ((p (point)))
+     (condition-case err
+         (progn ,@body)
+       (error
+        (when (= p (point))
+          (signal (car err) (cdr err)))))))
+
+(defun evil-signal-at-bob-or-eob (&optional count)
+  "Signals error if `point' is at boundaries.
+If `point' is at bob and COUNT is negative this function signal
+'beginning-of-buffer. If `point' is at eob and COUNT is positive
+this function singal 'end-of-buffer. This function should be used
+in motions. COUNT defaults to 1."
+  (setq count (or count 1))
+  (cond
+   ((< count 0) (evil-signal-at-bob))
+   ((> count 0) (evil-signal-at-eob))))
+
+(defun evil-signal-at-bob ()
+  "Signals 'beginning-of-buffer if `point' is at bob.
+This function should be used in backward motions. If `point' is at
+bob so that no further backward motion is possible the error
+'beginning-of-buffer is raised."
+  (when (bobp) (signal 'beginning-of-buffer nil)))
+
+(defun evil-signal-at-eob ()
+  "Signals 'end-of-buffer if `point' is at eob.
+This function should be used in forward motions. If `point' is close
+to eob so that no further forward motion is possible the error
+'end-of-buffer is raised. This is the case if `point' is at
+`point-max' or if is one position before `point-max',
+`evil-move-cursor-back' is non-nil and `point' is not at the end
+of a line. The latter is necessary because `point' cannot be
+moved to `point-max' if `evil-move-cursor-back' is non-nil and
+the last line in the buffer is not empty."
+  (when (or (eobp)
+            (and (not (eolp))
+                 evil-move-cursor-back
+                 (save-excursion (forward-char) (eobp))))
+    (signal 'end-of-buffer nil)))
+
+(defmacro evil-with-hproject-point-on-window (&rest body)
+  "Project point after BODY to current window.
+If point is on a position left or right of the current window
+then it is moved to the left and right boundary of the window,
+respectively. If `auto-hscroll-mode' is non-nil then the left and
+right positions are increased or decreased, respectively, by
+`horizontal-margin' so that no automatic scrolling occurs."
+  (declare (indent defun)
+           (debug t))
+  (let ((diff (make-symbol "diff"))
+        (left (make-symbol "left"))
+        (right (make-symbol "right")))
+    `(let ((,diff (if auto-hscroll-mode (1+ hscroll-margin) 0))
+           auto-hscroll-mode)
+       ,@body
+       (let* ((,left (+ (window-hscroll) ,diff))
+              (,right (+ (window-hscroll) (window-width) (- ,diff) -1)))
+         (move-to-column (min (max (current-column) ,left) ,right))))))
+
+(defun evil-goto-min (&rest positions)
+  "Go to the smallest position in POSITIONS.
+Non-numerical elements are ignored.
+See also `evil-goto-max'."
+  (when (setq positions (evil-filter-list
+                         #'(lambda (elt)
+                             (not (number-or-marker-p elt)))
+                         positions))
+    (goto-char (apply #'min positions))))
+
+(defun evil-goto-max (&rest positions)
+  "Go to the largest position in POSITIONS.
+Non-numerical elements are ignored.
+See also `evil-goto-min'."
+  (when (setq positions (evil-filter-list
+                         #'(lambda (elt)
+                             (not (number-or-marker-p elt)))
+                         positions))
+    (goto-char (apply #'max positions))))
+
+(defun evil-forward-not-thing (thing &optional count)
+  "Move point to the end or beginning of the complement of THING."
+  (evil-motion-loop (dir (or count 1))
+    (let (bnd)
+      (cond
+       ((> dir 0)
+        (while (and (setq bnd (bounds-of-thing-at-point thing))
+                    (< (point) (cdr bnd)))
+          (goto-char (cdr bnd)))
+        ;; no thing at (point)
+        (if (zerop (forward-thing thing))
+            ;; now at the end of the next thing
+            (let ((bnd (bounds-of-thing-at-point thing)))
+              (if (or (< (car bnd) (point))    ; end of a thing
+                      (= (car bnd) (cdr bnd))) ; zero width thing
+                  (goto-char (car bnd))
+                ;; beginning of yet another thing, go back
+                (forward-thing thing -1)))
+          (goto-char (point-max))))
+       (t
+        (while (and (not (bobp))
+                    (or (backward-char) t)
+                    (setq bnd (bounds-of-thing-at-point thing))
+                    (< (point) (cdr bnd)))
+          (goto-char (car bnd)))
+        ;; either bob or no thing at point
+        (goto-char
+         (if (and (not (bobp))
+                  (zerop (forward-thing thing -1))
+                  (setq bnd (bounds-of-thing-at-point thing)))
+             (cdr bnd)
+           (point-min))))))))
+
+(defun evil-bounds-of-not-thing-at-point (thing &optional which)
+  "Returns the bounds of a complement of THING at point.
+If there is a THING at point nil is returned.  Otherwise if WHICH
+is nil or 0 a cons cell (BEG . END) is returned. If WHICH is
+negative the beginning is returned. If WHICH is positive the END
+is returned."
+  (let ((pnt (point)))
+    (let ((beg (save-excursion
+                 (and (zerop (forward-thing thing -1))
+                      (forward-thing thing))
+                 (if (> (point) pnt) (point-min) (point))))
+          (end (save-excursion
+                 (and (zerop (forward-thing thing))
+                      (forward-thing thing -1))
+                 (if (< (point) pnt) (point-max) (point)))))
+      (when (and (<= beg (point)) (<= (point) end) (< beg end))
+        (cond
+         ((or (not which) (zerop which)) (cons beg end))
+         ((< which 0) beg)
+         ((> which 0) end))))))
+
+(defun evil-forward-nearest (count &rest forwards)
+  "Moves point forward to the first of several motions.
+FORWARDS is a list of forward motion functions (i.e. each moves
+point forward to the next end of a text object (if passed a +1)
+or backward to the preceeding beginning of a text object (if
+passed a -1)). This function calls each of these functions once
+and moves point to the nearest of the resulting positions. If
+COUNT is positive point is moved forward COUNT times, if negative
+point is moved backward -COUNT times."
+  (evil-motion-loop (dir (or count 1))
+    (let ((pnt (point))
+          (nxt (if (> dir 0) (point-max) (point-min))))
+      (dolist (fwd forwards)
+        (goto-char pnt)
+        (condition-case nil
+            (evil-with-restriction
+                (and (< dir 0)
+                     (save-excursion
+                       (goto-char nxt)
+                       (line-beginning-position 0)))
+                (and (> dir 0)
+                     (save-excursion
+                       (goto-char nxt)
+                       (line-end-position 2)))
+              (if (and (zerop (funcall fwd dir))
+                       (/= (point) pnt)
+                       (or (and (> dir 0) (< (point) nxt))
+                           (and (< dir 0) (> (point) nxt))))
+                  (setq nxt (point))))
+          (error)))
+      (goto-char nxt))))
+
+(defun bounds-of-evil-string-at-point (&optional state)
+  "Return the bounds of a string at point.
+If STATE is given it used a parsing state at point."
+  (save-excursion
+    (let ((state (or state (syntax-ppss))))
+      (and (nth 3 state)
+           (cons (nth 8 state)
+                 (and (parse-partial-sexp (point)
+                                          (point-max)
+                                          nil
+                                          nil
+                                          state
+                                          'syntax-table)
+                      (point)))))))
+(put 'evil-string 'bounds-of-thing-at-point #'bounds-of-evil-string-at-point)
+
+(defun bounds-of-evil-comment-at-point ()
+  "Return the bounds of a string at point."
+  (save-excursion
+    (let ((state (syntax-ppss)))
+      (and (nth 4 state)
+           (cons (nth 8 state)
+                 (and (parse-partial-sexp (point)
+                                          (point-max)
+                                          nil
+                                          nil
+                                          state
+                                          'syntax-table)
+                      (point)))))))
+(put 'evil-comment 'bounds-of-thing-at-point #'bounds-of-evil-comment-at-point)
+
+;; The purpose of this function is the provide line motions which
+;; preserve the column. This is how `previous-line' and `next-line'
+;; work, but unfortunately the behaviour is hard-coded: if and only if
+;; the last command was `previous-line' or `next-line', the column is
+;; preserved. Furthermore, in contrast to Vim, when we cannot go
+;; further, those motions move point to the beginning resp. the end of
+;; the line (we never want point to leave its column). The code here
+;; comes from simple.el, and I hope it will work in future.
+(defun evil-line-move (count &optional noerror)
+  "A wrapper for line motions which conserves the column.
+Signals an error at buffer boundaries unless NOERROR is non-nil."
+  (cond
+   (noerror
+    (condition-case nil
+        (evil-line-move count)
+      (error nil)))
+   (t
+    (evil-signal-without-movement
+      (setq this-command (if (>= count 0)
+                             #'next-line
+                           #'previous-line))
+      (let ((opoint (point)))
+        (condition-case err
+            (with-no-warnings
+              (funcall this-command (abs count)))
+          ((beginning-of-buffer end-of-buffer)
+           (let ((col (or goal-column
+                          (if (consp temporary-goal-column)
+                              (car temporary-goal-column)
+                            temporary-goal-column))))
+             (if line-move-visual
+                 (vertical-motion (cons col 0))
+               (line-move-finish col opoint (< count 0)))
+             ;; Maybe we should just `ding'?
+             (signal (car err) (cdr err))))))))))
+
+(defun evil-forward-syntax (syntax &optional count)
+  "Move point to the end or beginning of a sequence of characters in
+SYNTAX.
+Stop on reaching a character not in SYNTAX."
+  (let ((notsyntax (if (= (aref syntax 0) ?^)
+                       (substring syntax 1)
+                     (concat "^" syntax))))
+    (evil-motion-loop (dir (or count 1))
+      (cond
+       ((< dir 0)
+        (skip-syntax-backward notsyntax)
+        (skip-syntax-backward syntax))
+       (t
+        (skip-syntax-forward notsyntax)
+        (skip-syntax-forward syntax))))))
+
+(defun evil-forward-chars (chars &optional count)
+  "Move point to the end or beginning of a sequence of CHARS.
+CHARS is a character set as inside [...] in a regular expression."
+  (let ((notchars (if (= (aref chars 0) ?^)
+                      (substring chars 1)
+                    (concat "^" chars))))
+    (evil-motion-loop (dir (or count 1))
+      (cond
+       ((< dir 0)
+        (skip-chars-backward notchars)
+        (skip-chars-backward chars))
+       (t
+        (skip-chars-forward notchars)
+        (skip-chars-forward chars))))))
+
+(defun evil-up-block (beg end &optional count)
+  "Move point to the end or beginning of text enclosed by BEG and END.
+BEG and END should be regular expressions matching the opening
+and closing delimiters, respectively. If COUNT is greater than
+zero point is moved forward otherwise it is moved
+backwards. Whenever an opening delimiter is found the COUNT is
+increased by one, if a closing delimiter is found the COUNT is
+decreased by one. The motion stops when COUNT reaches zero. The
+match-data reflects the last successful match (that caused COUNT
+to reach zero). The behaviour of this functions is similar to
+`up-list'."
+  (let* ((count (or count 1))
+         (forwardp (> count 0))
+         (dir (if forwardp +1 -1)))
+    (catch 'done
+      (while (not (zerop count))
+        (let* ((pnt (point))
+               (cl (save-excursion
+                     (and (re-search-forward (if forwardp end beg) nil t dir)
+                          (or (/= pnt (point))
+                              (progn
+                                ;; zero size match, repeat search from
+                                ;; the next position
+                                (forward-char dir)
+                                (re-search-forward (if forwardp end beg) nil t dir)))
+                          (point))))
+               (match (match-data t))
+               (op (save-excursion
+                     (and (not (equal beg end))
+                          (re-search-forward (if forwardp beg end) cl t dir)
+                          (or (/= pnt (point))
+                              (progn
+                                ;; zero size match, repeat search from
+                                ;; the next position
+                                (forward-char dir)
+                                (re-search-forward (if forwardp beg end) cl t dir)))
+                          (point)))))
+          (cond
+           ((not cl)
+            (goto-char (if forwardp (point-max) (point-min)))
+            (set-match-data nil)
+            (throw 'done count))
+           (t
+            (if op
+                (progn
+                  (setq count (if forwardp (1+ count) (1- count)))
+                  (goto-char op))
+              (setq count (if forwardp (1- count) (1+ count)))
+              (if (zerop count) (set-match-data match))
+              (goto-char cl))))))
+      0)))
+
+(defun evil-up-paren (open close &optional count)
+  "Move point to the end or beginning of balanced parentheses.
+OPEN and CLOSE should be characters identifying the opening and
+closing parenthesis, respectively. If COUNT is greater than zero
+point is moved forward otherwise it is moved backwards. Whenever
+an opening delimiter is found the COUNT is increased by one, if a
+closing delimiter is found the COUNT is decreased by one. The
+motion stops when COUNT reaches zero. The match-data reflects the
+last successful match (that caused COUNT to reach zero)."
+  ;; Always use the default `forward-sexp-function'. This is important
+  ;; for modes that use a custom one like `python-mode'.
+  ;; (addresses #364)
+  (let (forward-sexp-function)
+    (with-syntax-table (copy-syntax-table (syntax-table))
+      (modify-syntax-entry open (format "(%c" close))
+      (modify-syntax-entry close (format ")%c" open))
+      (let ((rest (evil-motion-loop (dir count)
+                    (let ((pnt (point)))
+                      (condition-case nil
+                          (cond
+                           ((> dir 0)
+                            (while (progn
+                                     (up-list dir)
+                                     (/= (char-before) close))))
+                           (t
+                            (while (progn
+                                     (up-list dir)
+                                     (/= (char-after) open)))))
+                        (error (goto-char pnt)))))))
+        (cond
+         ((= rest count) (set-match-data nil))
+         ((> count 0) (set-match-data (list (1- (point)) (point))))
+         (t (set-match-data (list (point) (1+ (point))))))
+        rest))))
+
+(defun evil-up-xml-tag (&optional count)
+  "Move point to the end or beginning of balanced xml tags.
+OPEN and CLOSE should be characters identifying the opening and
+closing parenthesis, respectively. If COUNT is greater than zero
+point is moved forward otherwise it is moved backwards. Whenever
+an opening delimiter is found the COUNT is increased by one, if a
+closing delimiter is found the COUNT is decreased by one. The
+motion stops when COUNT reaches zero. The match-data reflects the
+last successful match (that caused COUNT to reach zero)."
+  (let* ((dir (if (> (or count 1) 0) +1 -1))
+         (count (abs (or count 1)))
+         (match (> count 0))
+         (op (if (> dir 0) 1 2))
+         (cl (if (> dir 0) 2 1))
+         (orig (point))
+         pnt tags match)
+    (catch 'done
+      (while (> count 0)
+        ;; find the previous opening tag
+        (while
+            (and (setq match
+                       (re-search-forward
+                        "<\\([^/ >]+\\)\\(?:[^\"/>]\\|\"[^\"]*\"\\)*?>\\|</\\([^>]+?\\)>"
+                        nil t dir))
+                 (cond
+                  ((match-beginning op)
+                   (push (match-string op) tags))
+                  ((null tags) nil) ; free closing tag
+                  ((and (< dir 0)
+                        (string= (car tags) (match-string cl)))
+                   ;; in backward direction we only accept matching
+                   ;; tags. If the current tag is a free opener
+                   ;; without matching closing tag, the subsequents
+                   ;; test will make us ignore this tag
+                   (pop tags))
+                  ((and (> dir 0))
+                   ;; non matching openers are considered free openers
+                   (while (and tags
+                               (not (string= (car tags)
+                                             (match-string cl))))
+                     (pop tags))
+                   (pop tags)))))
+        (unless (setq match (and match (match-data t)))
+          (setq match nil)
+          (throw 'done count))
+        ;; found closing tag, look for corresponding opening tag
+        (cond
+         ((> dir 0)
+          (setq pnt (match-end 0))
+          (goto-char (match-beginning 0)))
+         (t
+          (setq pnt (match-beginning 0))
+          (goto-char (match-end 0))))
+        (let* ((tag (match-string cl))
+               (refwd (concat "<\\(/\\)?"
+                              (regexp-quote tag)
+                              "\\(?:>\\| \\(?:[^\"/>]\\|\"[^\"]*\"\\)*?>\\)"))
+               (cnt 1))
+          (while (and (> cnt 0) (re-search-backward refwd nil t dir))
+            (setq cnt (+ cnt (if (match-beginning 1) dir (- dir)))))
+          (if (zerop cnt) (setq count (1- count) tags nil))
+          (goto-char pnt)))
+      (if (> count 0)
+          (set-match-data nil)
+        (set-match-data match)
+        (goto-char (if (> dir 0) (match-end 0) (match-beginning 0)))))
+    ;; if not found, set to point-max/point-min
+    (unless (zerop count)
+      (set-match-data nil)
+      (goto-char (if (> dir 0) (point-max) (point-min)))
+      (if (/= (point) orig) (setq count (1- count))))
+    (* dir count)))
+
+(defun evil-forward-quote (quote &optional count)
+  "Move point to the end or beginning of a string.
+QUOTE is the character delimiting the string. If COUNT is greater
+than zero point is moved forward otherwise it is moved
+backwards."
+  (let (reset-parser)
+    (with-syntax-table (copy-syntax-table (syntax-table))
+      (unless (= (char-syntax quote) ?\")
+        (modify-syntax-entry quote "\"")
+        (setq reset-parser t))
+      ;; global parser state is out of state, use local one
+      (let* ((pnt (point))
+             (state (save-excursion
+                      (beginning-of-defun)
+                      (parse-partial-sexp (point) pnt nil nil (syntax-ppss))))
+             (bnd (bounds-of-evil-string-at-point state)))
+        (when (and bnd (< (point) (cdr bnd)))
+          ;; currently within a string
+          (if (> count 0)
+              (progn
+                (goto-char (cdr bnd))
+                (setq count (1- count)))
+            (goto-char (car bnd))
+            (setq count (1+ count))))
+        ;; forward motions work with local parser state
+        (cond
+         ((> count 0)
+          ;; no need to reset global parser state because we only use
+          ;; the local one
+          (setq reset-parser nil)
+          (catch 'done
+            (while (and (> count 0) (not (eobp)))
+              (setq state (parse-partial-sexp (point) (point-max)
+                                              nil
+                                              nil
+                                              state
+                                              'syntax-table))
+              (cond
+               ((nth 3 state)
+                (setq bnd (bounds-of-thing-at-point 'evil-string))
+                (goto-char (cdr bnd))
+                (setq count (1- count)))
+               ((eobp) (goto-char pnt) (throw 'done nil))))))
+         ((< count 0)
+          ;; need to update global cache because of backward motion
+          (setq reset-parser (and reset-parser (point)))
+          (save-excursion
+            (beginning-of-defun)
+            (syntax-ppss-flush-cache (point)))
+          (catch 'done
+            (while (and (< count 0) (not (bobp)))
+              (setq pnt (point))
+              (while (and (not (bobp))
+                          (or (eobp) (/= (char-after) quote)))
+                (backward-char))
+              (cond
+               ((setq bnd (bounds-of-thing-at-point 'evil-string))
+                (goto-char (car bnd))
+                (setq count (1+ count)))
+               ((bobp) (goto-char pnt) (throw 'done nil))
+               (t (backward-char))))))
+         (t (setq reset-parser nil)))))
+    (when reset-parser
+      ;; reset global cache
+      (save-excursion
+        (goto-char reset-parser)
+        (beginning-of-defun)
+        (syntax-ppss-flush-cache (point))))
+    count))
+
+;;; Thing-at-point motion functions for Evil text objects and motions
+(defun forward-evil-empty-line (&optional count)
+  "Move forward COUNT empty lines."
+  (setq count (or count 1))
+  (cond
+   ((> count 0)
+    (while (and (> count 0) (not (eobp)))
+      (when (and (bolp) (eolp))
+        (setq count (1- count)))
+      (forward-line 1)))
+   (t
+    (while (and (< count 0) (not (bobp))
+                (zerop (forward-line -1)))
+      (when (and (bolp) (eolp))
+        (setq count (1+ count))))))
+  count)
+
+(defun forward-evil-space (&optional count)
+  "Move forward COUNT whitespace sequences [[:space:]]+."
+  (evil-forward-chars "[:space:]" count))
+
+(defun forward-evil-word (&optional count)
+  "Move forward COUNT words.
+Moves point COUNT words forward or (- COUNT) words backward if
+COUNT is negative. Point is placed after the end of the word (if
+forward) or at the first character of the word (if backward). A
+word is a sequence of word characters matching
+\[[:word:]] (recognized by `forward-word'), a sequence of
+non-whitespace non-word characters '[^[:word:]\\n\\r\\t\\f ]', or
+an empty line matching ^$."
+  (evil-forward-nearest
+   count
+   #'(lambda (&optional cnt)
+       (let ((word-separating-categories evil-cjk-word-separating-categories)
+             (word-combining-categories evil-cjk-word-combining-categories)
+             (pnt (point)))
+         (forward-word cnt)
+         (if (= pnt (point)) cnt 0)))
+   #'(lambda (&optional cnt)
+       (evil-forward-chars "^[:word:]\n\r\t\f " cnt))
+   #'forward-evil-empty-line))
+
+(defun forward-evil-WORD (&optional count)
+  "Move forward COUNT \"WORDS\".
+Moves point COUNT WORDS forward or (- COUNT) WORDS backward if
+COUNT is negative. Point is placed after the end of the WORD (if
+forward) or at the first character of the WORD (if backward). A
+WORD is a sequence of non-whitespace characters
+'[^\\n\\r\\t\\f ]', or an empty line matching ^$."
+  (evil-forward-nearest count
+                        #'(lambda (&optional cnt)
+                            (evil-forward-chars "^\n\r\t\f " cnt))
+                        #'forward-evil-empty-line))
+
+(defun forward-evil-symbol (&optional count)
+  "Move forward COUNT symbols.
+Moves point COUNT symbols forward or (- COUNT) symbols backward
+if COUNT is negative. Point is placed after the end of the
+symbol (if forward) or at the first character of the symbol (if
+backward). A symbol is either determined by `forward-symbol', or
+is a sequence of characters not in the word, symbol or whitespace
+syntax classes."
+  (evil-forward-nearest
+   count
+   #'(lambda (&optional cnt)
+       (evil-forward-syntax "^w_->" cnt))
+   #'(lambda (&optional cnt)
+       (let ((pnt (point)))
+         (forward-symbol cnt)
+         (if (= pnt (point)) cnt 0)))
+   #'forward-evil-empty-line))
+
+(defun forward-evil-defun (&optional count)
+  "Move forward COUNT defuns.
+Moves point COUNT defuns forward or (- COUNT) defuns backward
+if COUNT is negative.  A defun is defined by
+`beginning-of-defun' and `end-of-defun' functions."
+  (evil-motion-loop (dir (or count 1))
+    (if (> dir 0) (end-of-defun) (beginning-of-defun))))
+
+(defun forward-evil-sentence (&optional count)
+  "Move forward COUNT sentences.
+Moves point COUNT sentences forward or (- COUNT) sentences
+backward if COUNT is negative.  This function is the same as
+`forward-sentence' but returns the number of sentences that could
+NOT be moved over."
+  (evil-motion-loop (dir (or count 1))
+    (condition-case nil
+        (forward-sentence dir)
+      (error))))
+
+(defun forward-evil-paragraph (&optional count)
+  "Move forward COUNT paragraphs.
+Moves point COUNT paragraphs forward or (- COUNT) paragraphs backward
+if COUNT is negative.  A paragraph is defined by
+`start-of-paragraph-text' and `forward-paragraph' functions."
+  (evil-motion-loop (dir (or count 1))
+    (cond
+     ((> dir 0) (forward-paragraph))
+     ((not (bobp)) (start-of-paragraph-text) (beginning-of-line)))))
+
+(defvar evil-forward-quote-char ?\"
+  "The character to be used by `forward-evil-quote'.")
+
+(defun forward-evil-quote (&optional count)
+  "Move forward COUNT strings.
+The quotation character is specified by the global variable
+`evil-forward-quote-char'. This character is passed to
+`evil-forward-quote'."
+  (evil-forward-quote evil-forward-quote-char count))
+
+(defun forward-evil-quote-simple (&optional count)
+  "Move forward COUNT strings.
+The quotation character is specified by the global variable
+`evil-forward-quote-char'. This functions uses Vim's rules
+parsing from the beginning of the current line for quotation
+characters. It should only be used when looking for strings
+within comments and buffer *must* be narrowed to the comment."
+  (let ((dir (if (> (or count 1) 0) 1 -1))
+        (ch evil-forward-quote-char)
+        (pnt (point))
+        (cnt 0))
+    (beginning-of-line)
+    ;; count number of quotes before pnt
+    (while (< (point) pnt)
+      (when (= (char-after) ch)
+        (setq cnt (1+ cnt)))
+      (forward-char))
+    (setq cnt (- (* 2 (abs count)) (mod cnt 2)))
+    (cond
+     ((> dir 0)
+      (while (and (not (eolp)) (not (zerop cnt)))
+        (when (= (char-after) ch) (setq cnt (1- cnt)))
+        (forward-char))
+      (when (not (zerop cnt)) (goto-char (point-max))))
+     (t
+      (while (and (not (bolp)) (not (zerop cnt)))
+        (when (= (char-before) ch) (setq cnt (1- cnt)))
+        (forward-char -1))
+      (when (not (zerop cnt)) (goto-char (point-min)))))
+    (/ cnt 2)))
+
+;;; Motion functions
+(defun evil-forward-beginning (thing &optional count)
+  "Move forward to beginning of THING.
+The motion is repeated COUNT times."
+  (setq count (or count 1))
+  (if (< count 0)
+      (forward-thing thing count)
+    (let ((bnd (bounds-of-thing-at-point thing))
+          rest)
+      (when (and bnd (< (point) (cdr bnd)))
+        (goto-char (cdr bnd)))
+      (condition-case nil
+          (when (zerop (setq rest (forward-thing thing count)))
+            (when (and (bounds-of-thing-at-point thing)
+                       (not (bobp))
+                       ;; handle final empty line
+                       (not (and (bolp) (eobp))))
+              (forward-char -1))
+            (beginning-of-thing thing))
+        (error))
+      rest)))
+
+(defun evil-backward-beginning (thing &optional count)
+  "Move backward to beginning of THING.
+The motion is repeated COUNT times. This is the same as calling
+`evil-backward-beginning' with -COUNT."
+  (evil-forward-beginning thing (- (or count 1))))
+
+(defun evil-forward-end (thing &optional count)
+  "Move forward to end of THING.
+The motion is repeated COUNT times."
+  (setq count (or count 1))
+  (cond
+   ((> count 0)
+    (unless (eobp) (forward-char))
+    (prog1 (forward-thing thing count)
+      (unless (bobp) (forward-char -1))))
+   (t
+    (let ((bnd (bounds-of-thing-at-point thing))
+          rest)
+      (when (and bnd (< (point) (cdr bnd) ))
+        (goto-char (car bnd)))
+      (condition-case nil
+          (when (zerop (setq rest (forward-thing thing count)))
+            (end-of-thing thing)
+            (forward-char -1))
+        (error))
+      rest))))
+
+(defun evil-backward-end (thing &optional count)
+  "Move backward to end of THING.
+The motion is repeated COUNT times. This is the same as calling
+`evil-backward-end' with -COUNT."
+  (evil-forward-end thing (- (or count 1))))
+
+(defun evil-forward-word (&optional count)
+  "Move by words.
+Moves point COUNT words forward or (- COUNT) words backward if
+COUNT is negative. This function is the same as `forward-word'
+but returns the number of words by which point could *not* be
+moved."
+  (setq count (or count 1))
+  (let* ((dir (if (>= count 0) +1 -1))
+         (count (abs count)))
+    (while (and (> count 0)
+                (forward-word dir))
+      (setq count (1- count)))
+    count))
+
+(defun evil-in-comment-p (&optional pos)
+  "Checks if POS is within a comment according to current syntax.
+If POS is nil, (point) is used. The return value is the beginning
+position of the comment."
+  (setq pos (or pos (point)))
+  (let ((chkpos
+         (cond
+          ((eobp) pos)
+          ((= (char-syntax (char-after)) ?<) (1+ pos))
+          ((and (not (zerop (logand (car (syntax-after (point)))
+                                    (lsh 1 16))))
+                (not (zerop (logand (or (car (syntax-after (1+ (point)))) 0)
+                                    (lsh 1 17)))))
+           (+ pos 2))
+          ((and (not (zerop (logand (car (syntax-after (point)))
+                                    (lsh 1 17))))
+                (not (zerop (logand (or (car (syntax-after (1- (point)))) 0)
+                                    (lsh 1 16)))))
+           (1+ pos))
+          (t pos))))
+    (let ((syn (save-excursion (syntax-ppss chkpos))))
+      (and (nth 4 syn) (nth 8 syn)))))
+
+(defun evil-looking-at-start-comment (&optional move)
+  "Returns t if point is at the start of a comment.
+point must be on one of the opening characters of a block comment
+according to the current syntax table. Futhermore these
+characters must been parsed as opening characters, i.e. they
+won't be considered as comment starters inside a string or
+possibly another comment. Point is moved to the first character
+of the comment opener if MOVE is non-nil."
+  (cond
+   ;; one character opener
+   ((= (char-syntax (char-after)) ?<)
+    (equal (point) (evil-in-comment-p (1+ (point)))))
+   ;; two character opener on first char
+   ((and (not (zerop (logand (car (syntax-after (point)))
+                             (lsh 1 16))))
+         (not (zerop (logand (or (car (syntax-after (1+ (point)))) 0)
+                             (lsh 1 17)))))
+    (equal (point) (evil-in-comment-p (+ 2 (point)))))
+   ;; two character opener on second char
+   ((and (not (zerop (logand (car (syntax-after (point)))
+                             (lsh 1 17))))
+         (not (zerop (logand (or (car (syntax-after (1- (point)))) 0)
+                             (lsh 1 16)))))
+    (and (equal (1- (point)) (evil-in-comment-p (1+ (point))))
+         (prog1 t (when move (backward-char)))))))
+
+(defun evil-looking-at-end-comment (&optional move)
+  "Returns t if point is at the end of a comment.
+point must be on one of the opening characters of a block comment
+according to the current syntax table. Futhermore these
+characters must been parsed as opening characters, i.e. they
+won't be considered as comment starters inside a string or
+possibly another comment. Point is moved right after the comment
+closer if MOVE is non-nil."
+  (cond
+   ;; one char closer
+   ((= (char-syntax (char-after)) ?>)
+    (and (evil-in-comment-p) ; in comment
+         (not (evil-in-comment-p (1+ (point))))
+         (prog1 t (when move (forward-char)))))
+   ;; two char closer on first char
+   ((and (not (zerop (logand (car (syntax-after (point)))
+                             (lsh 1 18))))
+         (not (zerop (logand (or (car (syntax-after (1+ (point)))) 0)
+                             (lsh 1 19)))))
+    (and (evil-in-comment-p)
+         (not (evil-in-comment-p (+ (point) 2)))
+         (prog1 t (when move (forward-char 2)))))
+   ;; two char closer on second char
+   ((and (not (zerop (logand (car (syntax-after (point)))
+                             (lsh 1 19))))
+         (not (zerop (logand (or (car (syntax-after (1- (point)))) 0)
+                             (lsh 1 18)))))
+    (and (evil-in-comment-p)
+         (not (evil-in-comment-p (1+ (point))))
+         (prog1 t (when move (forward-char)))))))
+
+(defun evil-insert-newline-above ()
+  "Inserts a new line above point and places point in that line
+with regard to indentation."
+  (evil-narrow-to-field
+    (evil-move-beginning-of-line)
+    (insert (if use-hard-newlines hard-newline "\n"))
+    (forward-line -1)
+    (back-to-indentation)))
+
+(defun evil-insert-newline-below ()
+  "Inserts a new line below point and places point in that line
+with regard to indentation."
+  (evil-narrow-to-field
+    (evil-move-end-of-line)
+    (insert (if use-hard-newlines hard-newline "\n"))
+    (back-to-indentation)))
+
+;;; Markers
+
+(defun evil-global-marker-p (char)
+  "Whether CHAR denotes a global marker."
+  (or (and (>= char ?A) (<= char ?Z))
+      (assq char (default-value 'evil-markers-alist))))
+
+(defun evil-set-marker (char &optional pos advance)
+  "Set the marker denoted by CHAR to position POS.
+POS defaults to the current position of point.
+If ADVANCE is t, the marker advances when inserting text at it;
+otherwise, it stays behind."
+  (interactive (list (read-char)))
+  (catch 'done
+    (let ((marker (evil-get-marker char t)) alist)
+      (unless (markerp marker)
+        (cond
+         ((and marker (symbolp marker) (boundp marker))
+          (set marker (or (symbol-value marker) (make-marker)))
+          (setq marker (symbol-value marker)))
+         ((eq marker 'evil-jump-backward-swap)
+          (evil-set-jump)
+          (throw 'done nil))
+         ((functionp marker)
+          (user-error "Cannot set special marker `%c'" char))
+         ((evil-global-marker-p char)
+          (setq alist (default-value 'evil-markers-alist)
+                marker (make-marker))
+          (evil-add-to-alist 'alist char marker)
+          (setq-default evil-markers-alist alist))
+         (t
+          (setq marker (make-marker))
+          (evil-add-to-alist 'evil-markers-alist char marker))))
+      (add-hook 'kill-buffer-hook #'evil-swap-out-markers nil t)
+      (set-marker-insertion-type marker advance)
+      (set-marker marker (or pos (point))))))
+
+(defun evil-get-marker (char &optional raw)
+  "Return the marker denoted by CHAR.
+This is either a marker object as returned by `make-marker',
+a number, a cons cell (FILE . POS) with FILE being a string
+and POS a number, or nil. If RAW is non-nil, then the
+return value may also be a variable, a movement function,
+or a marker object pointing nowhere."
+  (let ((marker (if (evil-global-marker-p char)
+                    (cdr-safe (assq char (default-value
+                                           'evil-markers-alist)))
+                  (cdr-safe (assq char evil-markers-alist)))))
+    (save-excursion
+      (if raw
+          marker
+        (when (and (symbolp marker) (boundp marker))
+          (setq marker (symbol-value marker)))
+        (when (functionp marker)
+          (funcall marker)
+          (setq marker (point)))
+        (when (markerp marker)
+          (if (eq (marker-buffer marker) (current-buffer))
+              (setq marker (marker-position marker))
+            (setq marker (and (marker-buffer marker) marker))))
+        (when (or (numberp marker)
+                  (markerp marker)
+                  (and (consp marker)
+                       (stringp (car marker))
+                       (numberp (cdr marker))))
+          marker)))))
+
+(defun evil-swap-out-markers ()
+  "Turn markers into file references when the buffer is killed."
+  (and buffer-file-name
+       (dolist (entry evil-markers-alist)
+         (and (markerp (cdr entry))
+              (eq (marker-buffer (cdr entry)) (current-buffer))
+              (setcdr entry (cons buffer-file-name
+                                  (marker-position (cdr entry))))))))
+(put 'evil-swap-out-markers 'permanent-local-hook t)
+
+(defun evil-get-register (register &optional noerror)
+  "Return contents of REGISTER.
+Signal an error if empty, unless NOERROR is non-nil.
+
+The following special registers are supported.
+  \"  the unnamed register
+  *  the clipboard contents
+  +  the clipboard contents
+  <C-w> the word at point (ex mode only)
+  <C-a> the WORD at point (ex mode only)
+  <C-o> the symbol at point (ex mode only)
+  <C-f> the current file at point (ex mode only)
+  %  the current file name (read only)
+  #  the alternate file name (read only)
+  /  the last search pattern (read only)
+  :  the last command line (read only)
+  .  the last inserted text (read only)
+  -  the last small (less than a line) delete
+  _  the black hole register
+  =  the expression register (read only)"
+  (condition-case err
+      (when (characterp register)
+        (or (cond
+             ((eq register ?\")
+              (current-kill 0))
+             ((and (<= ?1 register) (<= register ?9))
+              (let ((reg (- register ?1)))
+                (and (< reg (length kill-ring))
+                     (current-kill reg t))))
+             ((memq register '(?* ?+))
+              ;; the following code is modified from
+              ;; `x-selection-value-internal'
+              (let ((what (if (eq register ?*) 'PRIMARY 'CLIPBOARD))
+                    (request-type (or (and (boundp 'x-select-request-type)
+                                           x-select-request-type)
+                                      '(UTF8_STRING COMPOUNT_TEXT STRING)))
+                    text)
+                (unless (consp request-type)
+                  (setq request-type (list request-type)))
+                (while (and request-type (not text))
+                  (condition-case nil
+                      (setq text (evil-get-selection what (pop request-type)))
+                    (error nil)))
+                (when text
+                  (remove-text-properties 0 (length text) '(foreign-selection nil) text))
+                text))
+             ((eq register ?\C-W)
+              (unless (evil-ex-p)
+                (user-error "Register <C-w> only available in ex state"))
+              (with-current-buffer evil-ex-current-buffer
+                (thing-at-point 'evil-word)))
+             ((eq register ?\C-A)
+              (unless (evil-ex-p)
+                (user-error "Register <C-a> only available in ex state"))
+              (with-current-buffer evil-ex-current-buffer
+                (thing-at-point 'evil-WORD)))
+             ((eq register ?\C-O)
+              (unless (evil-ex-p)
+                (user-error "Register <C-o> only available in ex state"))
+              (with-current-buffer evil-ex-current-buffer
+                (thing-at-point 'evil-symbol)))
+             ((eq register ?\C-F)
+              (unless (evil-ex-p)
+                (user-error "Register <C-f> only available in ex state"))
+              (with-current-buffer evil-ex-current-buffer
+                (thing-at-point 'filename)))
+             ((eq register ?%)
+              (or (buffer-file-name (and (evil-ex-p)
+                                         (minibufferp)
+                                         evil-ex-current-buffer))
+                  (user-error "No file name")))
+             ((= register ?#)
+              (or (with-current-buffer (other-buffer) (buffer-file-name))
+                  (user-error "No file name")))
+             ((eq register ?/)
+              (or (car-safe
+                   (or (and (boundp 'evil-search-module)
+                            (eq evil-search-module 'evil-search)
+                            evil-ex-search-history)
+                       (and isearch-regexp regexp-search-ring)
+                       search-ring))
+                  (user-error "No previous regular expression")))
+             ((eq register ?:)
+              (or (car-safe evil-ex-history)
+                  (user-error "No previous command line")))
+             ((eq register ?.)
+              evil-last-insertion)
+             ((eq register ?-)
+              evil-last-small-deletion)
+             ((eq register ?=)
+              (let* ((enable-recursive-minibuffers t)
+                     (result (eval (car (read-from-string (read-string "="))))))
+                (cond
+                 ((or (stringp result)
+                      (numberp result)
+                      (symbolp result))
+                  (prin1-to-string result))
+                 ((sequencep result)
+                  (mapconcat #'prin1-to-string result "\n"))
+                 (t (user-error "Using %s as a string" (type-of result))))))
+             ((eq register ?_) ; the black hole register
+              "")
+             (t
+              (setq register (downcase register))
+              (get-register register)))
+            (user-error "Register `%c' is empty" register)))
+    (error (unless err (signal (car err) (cdr err))))))
+
+(defun evil-set-register (register text)
+  "Set the contents of register REGISTER to TEXT.
+If REGISTER is an upcase character then text is appended to that
+register instead of replacing its content."
+  (cond
+   ((not (characterp register))
+    (user-error "Invalid register"))
+   ;; don't allow modification of read-only registers
+   ((member register '(?: ?. ?%))
+    (user-error "Can't modify read-only register"))
+   ((eq register ?\")
+    (kill-new text))
+   ((and (<= ?1 register) (<= register ?9))
+    (if (null kill-ring)
+        (kill-new text)
+      (let ((kill-ring-yank-pointer kill-ring-yank-pointer)
+            interprogram-paste-function
+            interprogram-cut-function)
+        (current-kill (- register ?1))
+        (setcar kill-ring-yank-pointer text))))
+   ((eq register ?*)
+    (evil-set-selection 'PRIMARY text))
+   ((eq register ?+)
+    (evil-set-selection 'CLIPBOARD text))
+   ((eq register ?-)
+    (setq evil-last-small-deletion text))
+   ((eq register ?_) ; the black hole register
+    nil)
+   ((and (<= ?A register) (<= register ?Z))
+    (setq register (downcase register))
+    (let ((content (get-register register)))
+      (cond
+       ((not content)
+        (set-register register text))
+       ((or (text-property-not-all 0 (length content)
+                                   'yank-handler nil
+                                   content)
+            (text-property-not-all 0 (length text)
+                                   'yank-handler nil
+                                   text))
+        ;; some non-trivial yank-handler -> always switch to line handler
+        ;; ensure complete lines
+        (when (and (> (length content) 0)
+                   (/= (aref content (1- (length content))) ?\n))
+          (setq content (concat content "\n")))
+        (when (and (> (length text) 0)
+                   (/= (aref text (1- (length text))) ?\n))
+          (setq text (concat text "\n")))
+        (setq text (concat content text))
+        (remove-list-of-text-properties 0 (length text) '(yank-handler) text)
+        (setq text (propertize text 'yank-handler '(evil-yank-line-handler)))
+        (set-register register text))
+       (t
+        (set-register register (concat content text))))))
+   (t
+    (set-register register text))))
+
+(defun evil-register-list ()
+  "Returns an alist of all registers"
+  (sort (append (mapcar #'(lambda (reg)
+                            (cons reg (evil-get-register reg t)))
+                        '(?\" ?* ?+ ?% ?# ?/ ?: ?. ?-
+                              ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9))
+                register-alist nil)
+        #'(lambda (reg1 reg2) (< (car reg1) (car reg2)))))
+
+(defsubst evil-kbd-macro-suppress-motion-error ()
+  "Returns non-nil if a motion error should be suppressed.
+Whether the motion error should be suppressed depends on the
+variable `evil-kbd-macro-suppress-motion-error'."
+  (or (and defining-kbd-macro
+           (memq evil-kbd-macro-suppress-motion-error '(t record)))
+      (and executing-kbd-macro
+           (memq evil-kbd-macro-suppress-motion-error '(t replay)))))
+
+;;; Region
+
+;; `set-mark' does too much at once
+(defun evil-move-mark (pos)
+  "Set buffer's mark to POS.
+If POS is nil, delete the mark."
+  (when pos
+    (setq pos (evil-normalize-position pos)))
+  (set-marker (mark-marker) pos))
+
+(defun evil-save-transient-mark-mode ()
+  "Save Transient Mark mode and make it buffer-local.
+Any changes to Transient Mark mode are now local to the current
+buffer, until `evil-restore-transient-mark-mode' is called.
+
+Variables pertaining to Transient Mark mode are listed in
+`evil-transient-vars', and their values are stored in
+`evil-transient-vals'."
+  (dolist (var evil-transient-vars)
+    (when (and (boundp var)
+               (not (assq var evil-transient-vals)))
+      (push (list var (symbol-value var)
+                  (local-variable-p var))
+            evil-transient-vals)
+      (make-variable-buffer-local var)
+      (put var 'permanent-local t))))
+
+(defun evil-restore-transient-mark-mode ()
+  "Restore Transient Mark mode.
+This presupposes that `evil-save-transient-mark-mode' has been
+called earlier. If Transient Mark mode was disabled before but
+enabled in the meantime, this function disables it; if it was
+enabled before but disabled in the meantime, this function
+enables it.
+
+The earlier settings of Transient Mark mode are stored in
+`evil-transient-vals'."
+  (let (entry local var val)
+    (while (setq entry (pop evil-transient-vals))
+      (setq var (pop entry)
+            val (pop entry)
+            local (pop entry))
+      (unless local
+        (kill-local-variable var))
+      (unless (equal (symbol-value var) val)
+        (if (fboundp var)
+            (funcall var (if val 1 -1))
+          (setq var val))))))
+
+(defun evil-save-mark ()
+  "Save the current mark, including whether it is transient.
+See also `evil-restore-mark'."
+  (unless evil-visual-previous-mark
+    (setq evil-visual-previous-mark (mark t))
+    (evil-save-transient-mark-mode)))
+
+(defun evil-restore-mark ()
+  "Restore the mark, including whether it was transient.
+See also `evil-save-mark'."
+  (when evil-visual-previous-mark
+    (evil-restore-transient-mark-mode)
+    (evil-move-mark evil-visual-previous-mark)
+    (setq evil-visual-previous-mark nil)))
+
+;; In theory, an active region implies Transient Mark mode, and
+;; disabling Transient Mark mode implies deactivating the region.
+;; In practice, Emacs never clears `mark-active' except in Transient
+;; Mark mode, so we define our own toggle functions to make things
+;; more predictable.
+(defun evil-transient-mark (&optional arg)
+  "Toggle Transient Mark mode.
+Ensure that the region is properly deactivated.
+Enable with positive ARG, disable with negative ARG."
+  (unless (numberp arg)
+    (setq arg (if transient-mark-mode -1 1)))
+  (cond
+   ((< arg 1)
+    (evil-active-region -1)
+    ;; Transient Mark mode cannot be disabled
+    ;; while CUA mode is enabled
+    (when (fboundp 'cua-mode)
+      (cua-mode -1))
+    (when transient-mark-mode
+      (transient-mark-mode -1)))
+   (t
+    (unless transient-mark-mode
+      (evil-active-region -1)
+      (transient-mark-mode 1)))))
+
+(defun evil-active-region (&optional arg)
+  "Toggle active region.
+Ensure that Transient Mark mode is properly enabled.
+Enable with positive ARG, disable with negative ARG."
+  (unless (numberp arg)
+    (setq arg (if (region-active-p) -1 1)))
+  (cond
+   ((and (< arg 1))
+    (when (or transient-mark-mode mark-active)
+      (setq mark-active nil
+            deactivate-mark nil)
+      (when (boundp 'cua--explicit-region-start)
+        (setq cua--explicit-region-start nil))
+      (run-hooks 'deactivate-mark-hook)))
+   (t
+    (evil-transient-mark 1)
+    (when deactivate-mark
+      (setq deactivate-mark nil))
+    (unless (mark t)
+      (evil-move-mark (point)))
+    (unless (region-active-p)
+      (set-mark (mark t)))
+    (when (boundp 'cua--explicit-region-start)
+      (setq cua--explicit-region-start t)))))
+
+(defmacro evil-with-transient-mark-mode (&rest body)
+  "Execute BODY with Transient Mark mode.
+Then restore Transient Mark mode to its previous setting."
+  (declare (indent defun)
+           (debug t))
+  `(let ((inhibit-quit t)
+         evil-transient-vals)
+     (unwind-protect
+         (progn
+           (evil-save-transient-mark-mode)
+           (evil-transient-mark 1)
+           ,@body)
+       (evil-restore-transient-mark-mode))))
+
+(defmacro evil-with-active-region (beg end &rest body)
+  "Execute BODY with an active region from BEG to END."
+  (declare (indent 2)
+           (debug t))
+  `(let ((beg ,beg) (end ,end)
+         evil-transient-vals)
+     (evil-with-transient-mark-mode
+       (save-excursion
+         (evil-active-region 1)
+         (evil-move-mark beg)
+         (goto-char end)
+         ,@body))))
+
+(defun evil-exchange-point-and-mark ()
+  "Exchange point and mark without activating the region."
+  (let* ((point (point))
+         (mark  (or (mark t) point)))
+    (set-marker (mark-marker) point)
+    (goto-char mark)))
+
+(defun evil-apply-on-block (func beg end pass-columns &rest args)
+  "Call FUNC for each line of a block selection.
+The selection is specified by the region BEG and END.  FUNC must
+take at least two arguments, the beginning and end of each
+line. If PASS-COLUMNS is non-nil, these values are the columns,
+otherwise tey are buffer positions. Extra arguments to FUNC may
+be passed via ARGS."
+  (let ((eol-col (and (memq last-command '(next-line previous-line))
+                      (numberp temporary-goal-column)
+                      temporary-goal-column))
+        startcol startpt endcol endpt)
+    (save-excursion
+      (goto-char beg)
+      (setq startcol (current-column))
+      (beginning-of-line)
+      (setq startpt (point))
+      (goto-char end)
+      (setq endcol (current-column))
+      (forward-line 1)
+      (setq endpt (point-marker))
+      ;; ensure the start column is the left one.
+      (evil-sort startcol endcol)
+      ;; maybe find maximal column
+      (when eol-col
+        (setq eol-col 0)
+        (goto-char startpt)
+        (while (< (point) endpt)
+          (setq eol-col (max eol-col
+                             (evil-column (line-end-position))))
+          (forward-line 1))
+        (setq endcol (max endcol
+                          (min eol-col
+                               (1+ (min (1- most-positive-fixnum)
+                                        (truncate temporary-goal-column)))))))
+      ;; start looping over lines
+      (goto-char startpt)
+      (while (< (point) endpt)
+        (if pass-columns
+            (apply func startcol endcol args)
+          (apply func
+                 (save-excursion (evil-move-to-column startcol))
+                 (save-excursion (evil-move-to-column endcol t))
+                 args))
+        (forward-line 1)))))
+
+(defun evil-apply-on-rectangle (function start end &rest args)
+  "Like `apply-on-rectangle' but maybe extends to eol.
+If `temporary-goal-column' is set to a big number, then the
+region of each line is extended to the end of each line. The end
+column is set to the maximal column in all covered lines."
+  (apply #'evil-apply-on-block function start end t args))
+
+;;; Insertion
+
+(defun evil-concat-ranges (ranges)
+  "Concatenate RANGES.
+RANGES must be a list of ranges.  They must be ordered so that
+successive ranges share their boundaries.  The return value is a
+single range of disjoint union of the ranges or nil if the
+disjoint union is not a single range."
+  (let ((range (car-safe ranges)) (ranges (cdr ranges)) r)
+    (while (and range (setq r (car-safe ranges)))
+      (setq range
+            (cond ((and (= (cdr r) (car range))) (cons (car r) (cdr range)))
+                  ((and (= (cdr range) (car r))) (cons (car range) (cdr r)))))
+      (setq ranges (cdr ranges)))
+    range))
+
+(defun evil-track-last-insertion (beg end len)
+  "Track the last insertion range and its text.
+The insertion range is stored as a pair of buffer positions in
+`evil-current-insertion'. If a subsequent change is compatible,
+then the current range is modified, otherwise it is replaced by a
+new range. Compatible changes are changes that do not create a
+disjoin range."
+  ;; deletion
+  (when (> len 0)
+    (if (and evil-current-insertion
+             (>= beg (car evil-current-insertion))
+             (<= (+ beg len) (cdr evil-current-insertion)))
+        (setcdr evil-current-insertion
+                (- (cdr evil-current-insertion) len))
+      (setq evil-current-insertion nil)))
+  ;; insertion
+  (if (and evil-current-insertion
+           (>= beg (car evil-current-insertion))
+           (<= beg (cdr evil-current-insertion)))
+      (setcdr evil-current-insertion
+              (+ (- end beg)
+                 (cdr evil-current-insertion)))
+    (setq evil-current-insertion (cons beg end))))
+(put 'evil-track-last-insertion 'permanent-local-hook t)
+
+(defun evil-start-track-last-insertion ()
+  "Start tracking the last insertion."
+  (setq evil-current-insertion nil)
+  (add-hook 'after-change-functions #'evil-track-last-insertion nil t))
+
+(defun evil-stop-track-last-insertion ()
+  "Stop tracking the last insertion.
+The tracked insertion is set to `evil-last-insertion'."
+  (setq evil-last-insertion
+        (and evil-current-insertion
+             ;; Check whether the insertion range is a valid buffer
+             ;; range.  If a buffer modification is done from within
+             ;; another change hook or modification-hook (yasnippet
+             ;; does this using overlay modification-hooks), then the
+             ;; insertion information may be invalid. There is no way
+             ;; to detect this situation, but at least we should
+             ;; ensure that no error occurs (see bug #272).
+             (>= (car evil-current-insertion) (point-min))
+             (<= (cdr evil-current-insertion) (point-max))
+             (buffer-substring-no-properties (car evil-current-insertion)
+                                             (cdr evil-current-insertion))))
+  (remove-hook 'after-change-functions #'evil-track-last-insertion t))
+
+;;; Paste
+
+(defun evil-yank-characters (beg end &optional register yank-handler)
+  "Saves the characters defined by the region BEG and END in the kill-ring."
+  (let ((text (filter-buffer-substring beg end)))
+    (when yank-handler
+      (setq text (propertize text 'yank-handler (list yank-handler))))
+    (when register
+      (evil-set-register register text))
+    (when evil-was-yanked-without-register
+      (evil-set-register ?0 text)) ; "0 register contains last yanked text
+    (unless (eq register ?_)
+      (kill-new text))))
+
+(defun evil-yank-lines (beg end &optional register yank-handler)
+  "Saves the lines in the region BEG and END into the kill-ring."
+  (let* ((text (filter-buffer-substring beg end))
+         (yank-handler (list (or yank-handler
+                                 #'evil-yank-line-handler)
+                             nil
+                             t)))
+    ;; Ensure the text ends with a newline. This is required
+    ;; if the deleted lines were the last lines in the buffer.
+    (when (or (zerop (length text))
+              (/= (aref text (1- (length text))) ?\n))
+      (setq text (concat text "\n")))
+    (setq text (propertize text 'yank-handler yank-handler))
+    (when register
+      (evil-set-register register text))
+    (when evil-was-yanked-without-register
+      (evil-set-register ?0 text)) ; "0 register contains last yanked text
+    (unless (eq register ?_)
+      (kill-new text))))
+
+(defun evil-yank-rectangle (beg end &optional register yank-handler)
+  "Saves the rectangle defined by region BEG and END into the kill-ring."
+  (let ((lines (list nil)))
+    (evil-apply-on-rectangle #'extract-rectangle-line beg end lines)
+    ;; We remove spaces from the beginning and the end of the next.
+    ;; Spaces are inserted explicitly in the yank-handler in order to
+    ;; NOT insert lines full of spaces.
+    (setq lines (nreverse (cdr lines)))
+    ;; `text' is used as default insert text when pasting this rectangle
+    ;; in another program, e.g., using the X clipboard.
+    (let* ((yank-handler (list (or yank-handler
+                                   #'evil-yank-block-handler)
+                               lines
+                               t
+                               'evil-delete-yanked-rectangle))
+           (text (propertize (mapconcat #'identity lines "\n")
+                             'yank-handler yank-handler)))
+      (when register
+        (evil-set-register register text))
+      (when evil-was-yanked-without-register
+        (evil-set-register ?0 text)) ; "0 register contains last yanked text
+      (unless (eq register ?_)
+        (kill-new text)))))
+
+(defun evil-remove-yank-excluded-properties (text)
+  "Removes `yank-excluded-properties' from TEXT."
+  (if (eq yank-excluded-properties t)
+      (set-text-properties 0 (length text) nil text)
+    (remove-list-of-text-properties 0 (length text)
+                                    yank-excluded-properties text)))
+
+(defun evil-yank-line-handler (text)
+  "Inserts the current text linewise."
+  (let ((text (apply #'concat (make-list (or evil-paste-count 1) text)))
+        (opoint (point)))
+    (evil-remove-yank-excluded-properties text)
+    (cond
+     ((eq this-command 'evil-paste-before)
+      (evil-move-beginning-of-line)
+      (evil-move-mark (point))
+      (insert text)
+      (setq evil-last-paste
+            (list 'evil-paste-before
+                  evil-paste-count
+                  opoint
+                  (mark t)
+                  (point)))
+      (evil-set-marker ?\[ (mark))
+      (evil-set-marker ?\] (1- (point)))
+      (evil-exchange-point-and-mark)
+      (back-to-indentation))
+     ((eq this-command 'evil-paste-after)
+      (evil-move-end-of-line)
+      (evil-move-mark (point))
+      (insert "\n")
+      (insert text)
+      (evil-set-marker ?\[ (1+ (mark)))
+      (evil-set-marker ?\] (1- (point)))
+      (delete-char -1) ; delete the last newline
+      (setq evil-last-paste
+            (list 'evil-paste-after
+                  evil-paste-count
+                  opoint
+                  (mark t)
+                  (point)))
+      (evil-move-mark (1+ (mark t)))
+      (evil-exchange-point-and-mark)
+      (back-to-indentation))
+     (t
+      (insert text)))))
+
+(defun evil-yank-block-handler (lines)
+  "Inserts the current text as block."
+  (let ((count (or evil-paste-count 1))
+        (col (if (eq this-command 'evil-paste-after)
+                 (1+ (current-column))
+               (current-column)))
+        (current-line (line-number-at-pos (point)))
+        (opoint (point))
+        epoint)
+    (dolist (line lines)
+      ;; concat multiple copies according to count
+      (setq line (apply #'concat (make-list count line)))
+      ;; strip whitespaces at beginning and end
+      (string-match "^ *\\(.*?\\) *$" line)
+      (let ((text (match-string 1 line))
+            (begextra (match-beginning 1))
+            (endextra (- (match-end 0) (match-end 1))))
+        ;; maybe we have to insert a new line at eob
+        (while (< (line-number-at-pos (point))
+                  current-line)
+          (goto-char (point-max))
+          (insert "\n"))
+        (setq current-line (1+ current-line))
+        ;; insert text unless we insert an empty line behind eol
+        (unless (and (< (evil-column (line-end-position)) col)
+                     (zerop (length text)))
+          ;; if we paste behind eol, it may be sufficient to insert tabs
+          (if (< (evil-column (line-end-position)) col)
+              (move-to-column (+ col begextra) t)
+            (move-to-column col t)
+            (insert (make-string begextra ?\s)))
+          (evil-remove-yank-excluded-properties text)
+          (insert text)
+          (unless (eolp)
+            ;; text follows, so we have to insert spaces
+            (insert (make-string endextra ?\s)))
+          (setq epoint (point)))
+        (forward-line 1)))
+    (setq evil-last-paste
+          (list this-command
+                evil-paste-count
+                opoint
+                (length lines)                   ; number of rows
+                (* count (length (car lines))))) ; number of colums
+    (evil-set-marker ?\[ opoint)
+    (evil-set-marker ?\] (1- epoint))
+    (goto-char opoint)
+    (when (and (eq this-command 'evil-paste-after)
+               (not (eolp)))
+      (forward-char))))
+
+(defun evil-delete-yanked-rectangle (nrows ncols)
+  "Special function to delete the block yanked by a previous paste command."
+  (let ((opoint (point))
+        (col (if (eq last-command 'evil-paste-after)
+                 (1+ (current-column))
+               (current-column))))
+    (dotimes (i nrows)
+      (delete-region (save-excursion
+                       (move-to-column col)
+                       (point))
+                     (save-excursion
+                       (move-to-column (+ col ncols))
+                       (point)))
+      (unless (eobp) (forward-line)))
+    (goto-char opoint)))
+
+;; TODO: if undoing is disabled in the current buffer, paste-pop won't
+;; work. Although this is probably not a big problem, because usually
+;; buffers where `evil-paste-pop' may be useful have undoing enabled.
+;; A solution would be to temporarily enable undo when pasting and
+;; store the undo information in a special variable that does not
+;; interfere with `buffer-undo-list'.
+(defun evil-paste-pop (count)
+  "Replace the just-yanked stretch of killed text with a different stretch.
+This command is allowed only immediatly after a `yank',
+`evil-paste-before', `evil-paste-after' or `evil-paste-pop'.
+This command uses the same paste command as before, i.e., when
+used after `evil-paste-after' the new text is also yanked using
+`evil-paste-after', used with the same paste-count argument.
+
+The COUNT argument inserts the COUNTth previous kill.  If COUNT
+is negative this is a more recent kill."
+  (interactive "p")
+  (unless (memq last-command
+                '(evil-paste-after
+                  evil-paste-before
+                  evil-visual-paste))
+    (user-error "Previous command was not an evil-paste: %s" last-command))
+  (unless evil-last-paste
+    (user-error "Previous paste command used a register"))
+  (evil-undo-pop)
+  (goto-char (nth 2 evil-last-paste))
+  (setq this-command (nth 0 evil-last-paste))
+  ;; use temporary kill-ring, so the paste cannot modify it
+  (let ((kill-ring (list (current-kill
+                          (if (and (> count 0) (nth 5 evil-last-paste))
+                              ;; if was visual paste then skip the
+                              ;; text that has been replaced
+                              (1+ count)
+                            count))))
+        (kill-ring-yank-pointer kill-ring))
+    (when (eq last-command 'evil-visual-paste)
+      (let ((evil-no-display t))
+        (evil-visual-restore)))
+    (funcall (nth 0 evil-last-paste) (nth 1 evil-last-paste))
+    ;; if this was a visual paste, then mark the last paste as NOT
+    ;; being the first visual paste
+    (when (eq last-command 'evil-visual-paste)
+      (setcdr (nthcdr 4 evil-last-paste) nil))))
+
+(defun evil-paste-pop-next (count)
+  "Same as `evil-paste-pop' but with negative argument."
+  (interactive "p")
+  (evil-paste-pop (- count)))
+
+;;; Interactive forms
+
+(defun evil-match-interactive-code (interactive &optional pos)
+  "Match an interactive code at position POS in string INTERACTIVE.
+Returns the first matching entry in `evil-interactive-alist', or nil."
+  (let ((length (length interactive))
+        (pos (or pos 0)))
+    (catch 'done
+      (dolist (entry evil-interactive-alist)
+        (let* ((string (car entry))
+               (end (+ (length string) pos)))
+          (when (and (<= end length)
+                     (string= string
+                              (substring interactive pos end)))
+            (throw 'done entry)))))))
+
+(defun evil-concatenate-interactive-forms (&rest forms)
+  "Concatenate interactive list expressions FORMS.
+Returns a single expression where successive expressions
+are joined, if possible."
+  (let (result)
+    (when forms
+      (while (cdr forms)
+        (cond
+         ((null (car forms))
+          (pop forms))
+         ((and (eq (car (car forms)) 'list)
+               (eq (car (cadr forms)) 'list))
+          (setq forms (cons (append (car forms)
+                                    (cdr (cadr forms)))
+                            (cdr (cdr forms)))))
+         (t
+          (push (pop forms) result))))
+      (when (car forms)
+        (push (pop forms) result))
+      (setq result (nreverse result))
+      (cond
+       ((null result))
+       ((null (cdr result))
+        (car result))
+       (t
+        `(append ,@result))))))
+
+(defun evil-interactive-string (string)
+  "Evaluate the interactive string STRING.
+The string may contain extended interactive syntax.
+The return value is a cons cell (FORM . PROPERTIES),
+where FORM is a single list-expression to be passed to
+a standard `interactive' statement, and PROPERTIES is a
+list of command properties as passed to `evil-define-command'."
+  (let ((length (length string))
+        (pos 0)
+        code expr forms match plist prompt properties)
+    (while (< pos length)
+      (if (eq (aref string pos) ?\n)
+          (setq pos (1+ pos))
+        (setq match (evil-match-interactive-code string pos))
+        (if (null match)
+            (user-error "Unknown interactive code: `%s'"
+                        (substring string pos))
+          (setq code (car match)
+                expr (car (cdr match))
+                plist (cdr (cdr match))
+                pos (+ pos (length code)))
+          (when (functionp expr)
+            (setq prompt
+                  (substring string pos
+                             (or (string-match "\n" string pos)
+                                 length))
+                  pos (+ pos (length prompt))
+                  expr `(funcall ,expr ,prompt)))
+          (setq forms (append forms (list expr))
+                properties (append properties plist)))))
+    (cons `(append ,@forms) properties)))
+
+(defun evil-interactive-form (&rest args)
+  "Evaluate interactive forms ARGS.
+The return value is a cons cell (FORM . PROPERTIES),
+where FORM is a single list-expression to be passed to
+a standard `interactive' statement, and PROPERTIES is a
+list of command properties as passed to `evil-define-command'."
+  (let (forms properties)
+    (dolist (arg args)
+      (if (not (stringp arg))
+          (setq forms (append forms (list arg)))
+        (setq arg (evil-interactive-string arg)
+              forms (append forms (cdr (car arg)))
+              properties (append properties (cdr arg)))))
+    (cons (apply #'evil-concatenate-interactive-forms forms)
+          properties)))
+
+;;; Types
+
+(defun evil-type (object &optional default)
+  "Return the type of OBJECT, or DEFAULT if none."
+  (let (type)
+    (cond
+     ((overlayp object)
+      (setq type (overlay-get object :type)))
+     ((evil-range-p object)
+      (setq type (nth 2 object)))
+     ((listp object)
+      (setq type (plist-get object :type)))
+     ((commandp object)
+      (setq type (evil-get-command-property object :type)))
+     ((symbolp object)
+      (setq type (get object 'type))))
+    (setq type (or type default))
+    (and (evil-type-p type) type)))
+
+(defun evil-set-type (object type)
+  "Set the type of OBJECT to TYPE.
+For example, (evil-set-type 'next-line 'line)
+will make `line' the type of the `next-line' command."
+  (cond
+   ((overlayp object)
+    (overlay-put object :type type))
+   ((evil-range-p object)
+    (evil-set-range-type object type))
+   ((listp object)
+    (plist-put object :type type))
+   ((commandp object)
+    (evil-set-command-property object :type type))
+   ((symbolp object)
+    (put object 'type type)))
+  object)
+
+(defun evil-type-property (type prop)
+  "Return property PROP for TYPE."
+  (evil-get-property evil-type-properties type prop))
+
+(defun evil-type-p (sym)
+  "Whether SYM is the name of a type."
+  (assq sym evil-type-properties))
+
+(defun evil-expand (beg end type &rest properties)
+  "Expand BEG and END as TYPE with PROPERTIES.
+Returns a list (BEG END TYPE PROPERTIES ...), where the tail
+may contain a property list."
+  (apply #'evil-transform
+         ;; don't expand if already expanded
+         (unless (plist-get properties :expanded) :expand)
+         beg end type properties))
+
+(defun evil-contract (beg end type &rest properties)
+  "Contract BEG and END as TYPE with PROPERTIES.
+Returns a list (BEG END TYPE PROPERTIES ...), where the tail
+may contain a property list."
+  (apply #'evil-transform :contract beg end type properties))
+
+(defun evil-normalize (beg end type &rest properties)
+  "Normalize BEG and END as TYPE with PROPERTIES.
+Returns a list (BEG END TYPE PROPERTIES ...), where the tail
+may contain a property list."
+  (apply #'evil-transform :normalize beg end type properties))
+
+(defun evil-transform (transform beg end type &rest properties)
+  "Apply TRANSFORM on BEG and END with PROPERTIES.
+Returns a list (BEG END TYPE PROPERTIES ...), where the tail
+may contain a property list. If TRANSFORM is undefined,
+return positions unchanged."
+  (let* ((type (or type (evil-type properties)))
+         (transform (when (and type transform)
+                      (evil-type-property type transform))))
+    (if transform
+        (apply transform beg end properties)
+      (apply #'evil-range beg end type properties))))
+
+(defun evil-describe (beg end type &rest properties)
+  "Return description of BEG and END with PROPERTIES.
+If no description is available, return the empty string."
+  (let* ((type (or type (evil-type properties)))
+         (properties (plist-put properties :type type))
+         (describe (evil-type-property type :string)))
+    (or (when describe
+          (apply describe beg end properties))
+        "")))
+
+;;; Ranges
+
+(defun evil-range (beg end &optional type &rest properties)
+  "Return a list (BEG END [TYPE] PROPERTIES...).
+BEG and END are buffer positions (numbers or markers),
+TYPE is a type as per `evil-type-p', and PROPERTIES is
+a property list."
+  (let ((beg (evil-normalize-position beg))
+        (end (evil-normalize-position end)))
+    (when (and (numberp beg) (numberp end))
+      (append (list (min beg end) (max beg end))
+              (when (evil-type-p type)
+                (list type))
+              properties))))
+
+(defun evil-range-p (object)
+  "Whether OBJECT is a range."
+  (and (listp object)
+       (>= (length object) 2)
+       (numberp (nth 0 object))
+       (numberp (nth 1 object))))
+
+(defun evil-range-beginning (range)
+  "Return beginning of RANGE."
+  (when (evil-range-p range)
+    (let ((beg (evil-normalize-position (nth 0 range)))
+          (end (evil-normalize-position (nth 1 range))))
+      (min beg end))))
+
+(defun evil-range-end (range)
+  "Return end of RANGE."
+  (when (evil-range-p range)
+    (let ((beg (evil-normalize-position (nth 0 range)))
+          (end (evil-normalize-position (nth 1 range))))
+      (max beg end))))
+
+(defun evil-range-properties (range)
+  "Return properties of RANGE."
+  (when (evil-range-p range)
+    (if (evil-type range)
+        (nthcdr 3 range)
+      (nthcdr 2 range))))
+
+(defun evil-copy-range (range)
+  "Return a copy of RANGE."
+  (copy-sequence range))
+
+(defun evil-set-range (range &optional beg end type &rest properties)
+  "Set RANGE to have beginning BEG and end END.
+The TYPE and additional PROPERTIES may also be specified.
+If an argument is nil, it's not used; the previous value is retained.
+See also `evil-set-range-beginning', `evil-set-range-end',
+`evil-set-range-type' and `evil-set-range-properties'."
+  (when (evil-range-p range)
+    (let ((beg (or (evil-normalize-position beg)
+                   (evil-range-beginning range)))
+          (end (or (evil-normalize-position end)
+                   (evil-range-end range)))
+          (type (or type (evil-type range)))
+          (plist (evil-range-properties range)))
+      (evil-sort beg end)
+      (setq plist (evil-concat-plists plist properties))
+      (evil-set-range-beginning range beg)
+      (evil-set-range-end range end)
+      (evil-set-range-type range type)
+      (evil-set-range-properties range plist)
+      range)))
+
+(defun evil-set-range-beginning (range beg &optional copy)
+  "Set RANGE's beginning to BEG.
+If COPY is non-nil, return a copy of RANGE."
+  (when copy
+    (setq range (evil-copy-range range)))
+  (setcar range beg)
+  range)
+
+(defun evil-set-range-end (range end &optional copy)
+  "Set RANGE's end to END.
+If COPY is non-nil, return a copy of RANGE."
+  (when copy
+    (setq range (evil-copy-range range)))
+  (setcar (cdr range) end)
+  range)
+
+(defun evil-set-range-type (range type &optional copy)
+  "Set RANGE's type to TYPE.
+If COPY is non-nil, return a copy of RANGE."
+  (when copy
+    (setq range (evil-copy-range range)))
+  (if type
+      (setcdr (cdr range)
+              (cons type (evil-range-properties range)))
+    (setcdr (cdr range) (evil-range-properties range)))
+  range)
+
+(defun evil-set-range-properties (range properties &optional copy)
+  "Set RANGE's properties to PROPERTIES.
+If COPY is non-nil, return a copy of RANGE."
+  (when copy
+    (setq range (evil-copy-range range)))
+  (if (evil-type range)
+      (setcdr (cdr (cdr range)) properties)
+    (setcdr (cdr range) properties))
+  range)
+
+(defun evil-range-union (range1 range2 &optional type)
+  "Return the union of the ranges RANGE1 and RANGE2.
+If the ranges have conflicting types, use RANGE1's type.
+This can be overridden with TYPE."
+  (when (and (evil-range-p range1)
+             (evil-range-p range2))
+    (evil-range (min (evil-range-beginning range1)
+                     (evil-range-beginning range2))
+                (max (evil-range-end range1)
+                     (evil-range-end range2))
+                (or type
+                    (evil-type range1)
+                    (evil-type range2)))))
+
+(defun evil-subrange-p (range1 range2)
+  "Whether RANGE1 is contained within RANGE2."
+  (and (evil-range-p range1)
+       (evil-range-p range2)
+       (<= (evil-range-beginning range2)
+           (evil-range-beginning range1))
+       (>= (evil-range-end range2)
+           (evil-range-end range1))))
+
+(defun evil-select-inner-object (thing beg end type &optional count line)
+  "Return an inner text object range of COUNT objects.
+If COUNT is positive, return objects following point; if COUNT is
+negative, return objects preceding point.  If one is unspecified,
+the other is used with a negative argument.  THING is a symbol
+understood by thing-at-point.  BEG, END and TYPE specify the
+current selection.  If LINE is non-nil, the text object should be
+linewise, otherwise it is character wise."
+  (let* ((count (or count 1))
+         (bnd (or (let ((b (bounds-of-thing-at-point thing)))
+                    (and b (< (point) (cdr b)) b))
+                  (evil-bounds-of-not-thing-at-point thing))))
+    ;; check if current object is selected
+    (when (or (not beg) (not end)
+              (> beg (car bnd))
+              (< end (cdr bnd))
+              (and (eq type 'inclusive)
+                   (= (1+ beg) end))) ; empty region does not count
+      (when (or (not beg) (< (car bnd) beg)) (setq beg (car bnd)))
+      (when (or (not end) (> (cdr bnd) end)) (setq end (cdr bnd)))
+      (setq count (if (> count 0) (1- count) (1+ count))))
+    (goto-char (if (< count 0) beg end))
+    (evil-forward-nearest count
+                          #'(lambda (cnt) (forward-thing thing cnt))
+                          #'(lambda (cnt) (evil-forward-not-thing thing cnt)))
+    (evil-range (if (>= count 0) beg (point))
+                (if (< count 0) end (point))
+                (if line 'line type)
+                :expanded t)))
+
+(defun evil-select-an-object (thing beg end type count &optional line)
+  "Return an outer text object range of COUNT objects.
+If COUNT is positive, return objects following point; if COUNT is
+negative, return objects preceding point.  If one is unspecified,
+the other is used with a negative argument.  THING is a symbol
+understood by thing-at-point.  BEG, END and TYPE specify the
+current selection.  If LINE is non-nil, the text object should be
+linewise, otherwise it is character wise."
+  (let* ((dir (if (> (or count 1) 0) +1 -1))
+         (count (abs (or count 1)))
+         (objbnd (let ((b (bounds-of-thing-at-point thing)))
+                   (and b (< (point) (cdr b)) b)))
+         (bnd (or objbnd (evil-bounds-of-not-thing-at-point thing)))
+         addcurrent other)
+    ;; check if current object is not selected
+    (when (or (not beg) (not end)
+              (> beg (car bnd))
+              (< end (cdr bnd))
+              (and (eq type 'inclusive)
+                   (= (1+ beg) end))) ; empty region does not count
+      ;; if not, enlarge selection
+      (when (or (not beg) (< (car bnd) beg)) (setq beg (car bnd)))
+      (when (or (not end) (> (cdr bnd) end)) (setq end (cdr bnd)))
+      (if objbnd (setq addcurrent t)))
+    ;; make other and (point) reflect the selection
+    (cond
+     ((> dir 0) (goto-char end) (setq other beg))
+     (t (goto-char beg) (setq other end)))
+    (cond
+     ;; do nothing more than only current is selected
+     ((not (and (= beg (car bnd)) (= end (cdr bnd)))))
+     ;; current match is thing, add whitespace
+     (objbnd
+      (let ((wsend (evil-with-restriction
+                       ;; restrict to current line if we do non-line selection
+                       (and (not line) (line-beginning-position))
+                       (and (not line) (line-end-position))
+                     (evil-bounds-of-not-thing-at-point thing dir))))
+        (cond
+         (wsend
+          ;; add whitespace at end
+          (goto-char wsend)
+          (setq addcurrent t))
+         (t
+          ;; no whitespace at end, try beginning
+          (save-excursion
+            (goto-char other)
+            (setq wsend
+                  (evil-with-restriction
+                      ;; restrict to current line if we do non-line selection
+                      (and (not line) (line-beginning-position))
+                      (and (not line) (line-end-position))
+                    (evil-bounds-of-not-thing-at-point thing (- dir))))
+            (when wsend (setq other wsend addcurrent t)))))))
+     ;; current match is whitespace, add thing
+     (t
+      (forward-thing thing dir)
+      (setq addcurrent t)))
+    ;; possibly count current object as selection
+    (if addcurrent (setq count (1- count)))
+    ;; move
+    (dotimes (var count)
+      (let ((wsend (evil-bounds-of-not-thing-at-point thing dir)))
+        (if (and wsend (/= wsend (point)))
+            ;; start with whitespace
+            (forward-thing thing dir)
+          ;; start with thing
+          (forward-thing thing dir)
+          (setq wsend (evil-bounds-of-not-thing-at-point thing dir))
+          (when wsend (goto-char wsend)))))
+    ;; return range
+    (evil-range (if (> dir 0) other (point))
+                (if (< dir 0) other (point))
+                (if line 'line type)
+                :expanded t)))
+
+(defun evil--get-block-range (op cl selection-type)
+  "Return the exclusive range of a visual selection.
+OP and CL are pairs of buffer positions for the opening and
+closing delimiter of a range. SELECTION-TYPE is the desired type
+of selection.  It is a symbol that determines which parts of the
+block are selected.  If it is 'inclusive or t the returned range
+is \(cons (car OP) (cdr CL)). If it is 'exclusive or nil the
+returned range is (cons (cdr OP) (car CL)).  If it is
+'exclusive-line the returned range will skip whitespace at the
+end of the line of OP and at the beginning of the line of CL."
+  (cond
+   ((memq selection-type '(inclusive t)) (cons (car op) (cdr cl)))
+   ((memq selection-type '(exclusive nil)) (cons (cdr op) (car cl)))
+   ((eq selection-type 'exclusive-line)
+    (let ((beg (cdr op))
+          (end (car cl)))
+      (save-excursion
+        (goto-char beg)
+        (when (and (eolp) (not (eobp)))
+          (setq beg (line-beginning-position 2)))
+        (goto-char end)
+        (skip-chars-backward " \t")
+        (when (bolp)
+          (setq end (point))
+          (goto-char beg)
+          (when (and (not (bolp)) (< beg end))
+            (setq end (1- end)))))
+      (cons beg end)))
+   (t
+    (user-error "Unknown selection-type %s" selection-type))))
+
+(defun evil-select-block (thing beg end type count
+                                &optional
+                                selection-type
+                                countcurrent
+                                fixedscan)
+  "Return a range (BEG END) of COUNT delimited text objects.
+BEG END TYPE are the currently selected (visual) range.  The
+delimited object must be given by THING-up function (see
+`evil-up-block').
+
+SELECTION-TYPE is symbol that determines which parts of the block
+are selected.  If it is 'inclusive or t OPEN and CLOSE are
+included in the range. If it is 'exclusive or nil the delimiters
+are not contained. If it is 'exclusive-line the delimiters are
+not included as well as adjacent whitespace until the beginning
+of the next line or the end of the previous line. If the
+resulting selection consists of complete lines only and visual
+state is not active, the returned selection is linewise.
+
+If COUNTCURRENT is non-nil an objected is counted if the current
+selection matches that object exactly.
+
+Usually scanning for the surrounding block starts at (1+ beg)
+and (1- end). If this might fail due to the behavior of THING
+then FIXEDSCAN can be set to t. In this case the scan starts at
+BEG and END. One example where this might fail is if BEG and END
+are the delimiters of a string or comment."
+  (save-excursion
+    (save-match-data
+      (let* ((orig-beg beg)
+             (orig-end end)
+             (beg (or beg (point)))
+             (end (or end (point)))
+             (count (abs (or count 1)))
+             op cl op-end cl-end)
+        ;; We always assume at least one selected character.
+        (if (= beg end) (setq end (1+ end)))
+        ;; We scan twice: starting at (1+ beg) forward and at (1- end)
+        ;; backward. The resulting selection is the smaller one.
+        (goto-char (if fixedscan beg (1+ beg)))
+        (when (and (zerop (funcall thing +1)) (match-beginning 0))
+          (setq cl (cons (match-beginning 0) (match-end 0)))
+          (goto-char (car cl))
+          (when (and (zerop (funcall thing -1)) (match-beginning 0))
+            (setq op (cons (match-beginning 0) (match-end 0)))))
+        ;; start scanning from end
+        (goto-char (if fixedscan end (1- end)))
+        (when (and (zerop (funcall thing -1)) (match-beginning 0))
+          (setq op-end (cons (match-beginning 0) (match-end 0)))
+          (goto-char (cdr op-end))
+          (when (and (zerop (funcall thing +1)) (match-beginning 0))
+            (setq cl-end (cons (match-beginning 0) (match-end 0)))))
+        ;; Bug #607: use the tightest selection that contains the
+        ;; original selection. If non selection contains the original,
+        ;; use the larger one.
+        (cond
+         ((and (not op) (not cl-end))
+          (error "No surrounding delimiters found"))
+         ((or (not op) ; first not found
+              (and cl-end ; second found
+                   (>= (car op-end) (car op)) ; second smaller
+                   (<= (cdr cl-end) (cdr cl))
+                   (<= (car op-end) beg)      ; second contains orig
+                   (>= (cdr cl-end) end)))
+          (setq op op-end cl cl-end)))
+        (setq op-end op cl-end cl) ; store copy
+        ;; if the current selection contains the surrounding
+        ;; delimiters, they do not count as new selection
+        (let ((cnt (if (and orig-beg orig-end (not countcurrent))
+                       (let ((sel (evil--get-block-range op cl selection-type)))
+                         (if (and (<= orig-beg (car sel))
+                                  (>= orig-end (cdr sel)))
+                             count
+                           (1- count)))
+                     (1- count))))
+          ;; starting from the innermost surrounding delimiters
+          ;; increase selection
+          (when (> cnt 0)
+            (setq op (progn
+                       (goto-char (car op-end))
+                       (funcall thing (- cnt))
+                       (if (match-beginning 0)
+                           (cons (match-beginning 0) (match-end 0))
+                         op))
+                  cl (progn
+                       (goto-char (cdr cl-end))
+                       (funcall thing cnt)
+                       (if (match-beginning 0)
+                           (cons (match-beginning 0) (match-end 0))
+                         cl)))))
+        (let ((sel (evil--get-block-range op cl selection-type)))
+          (setq op (car sel)
+                cl (cdr sel)))
+        (cond
+         ((and (equal op orig-beg) (equal cl orig-end)
+               (or (not countcurrent)
+                   (and countcurrent (/= count 1))))
+          (error "No surrounding delimiters found"))
+         ((save-excursion
+            (and (not (evil-visual-state-p))
+                 (eq type 'inclusive)
+                 (progn (goto-char op) (bolp))
+                 (progn (goto-char cl) (bolp))))
+          (evil-range op cl 'line :expanded t))
+         (t
+          (evil-range op cl type :expanded t)))))))
+
+(defun evil-select-paren (open close beg end type count &optional inclusive)
+  "Return a range (BEG END) of COUNT delimited text objects.
+OPEN and CLOSE specify the opening and closing delimiter,
+respectively. BEG END TYPE are the currently selected (visual)
+range.  If INCLUSIVE is non-nil, OPEN and CLOSE are included in
+the range; otherwise they are excluded.
+
+The types of OPEN and CLOSE specify which kind of THING is used
+for parsing with `evil-select-block'. If OPEN and CLOSE are
+characters `evil-up-paren' is used. Otherwise OPEN and CLOSE
+must be regular expressions and `evil-up-block' is used.
+
+If the selection is exclusive, whitespace at the end or at the
+beginning of the selection until the end-of-line or beginning-of-line
+is ignored."
+  ;; we need special linewise exclusive selection
+  (unless inclusive (setq inclusive 'exclusive-line))
+  (cond
+   ((and (characterp open) (characterp close))
+    (let ((thing #'(lambda (&optional cnt)
+                     (evil-up-paren open close cnt)))
+          (bnd (or (bounds-of-thing-at-point 'evil-string)
+                   (bounds-of-thing-at-point 'evil-comment)
+                   ;; If point is at the opening quote of a string,
+                   ;; this must be handled as if point is within the
+                   ;; string, i.e. the selection must be extended
+                   ;; around the string. Otherwise
+                   ;; `evil-select-block' might do the wrong thing
+                   ;; because it accidentally moves point inside the
+                   ;; string (for inclusive selection) when looking
+                   ;; for the current surrounding block. (re #364)
+                   (and (= (point) (or beg (point)))
+                        (save-excursion
+                          (goto-char (1+ (or beg (point))))
+                          (or (bounds-of-thing-at-point 'evil-string)
+                              (bounds-of-thing-at-point 'evil-comment)))))))
+      (if (not bnd)
+          (evil-select-block thing beg end type count inclusive)
+        (or (evil-with-restriction (car bnd) (cdr bnd)
+              (condition-case nil
+                  (evil-select-block thing beg end type count inclusive)
+                (error nil)))
+            (save-excursion
+              (setq beg (or beg (point))
+                    end (or end (point)))
+              (goto-char (car bnd))
+              (let ((extbeg (min beg (car bnd)))
+                    (extend (max end (cdr bnd))))
+                (evil-select-block thing
+                                   extbeg extend
+                                   type
+                                   count
+                                   inclusive
+                                   (or (< extbeg beg) (> extend end))
+                                   t)))))))
+   (t
+    (evil-select-block #'(lambda (&optional cnt)
+                           (evil-up-block open close cnt))
+                       beg end type count inclusive))))
+
+(defun evil-select-quote-thing (thing beg end type count &optional inclusive)
+  "Selection THING as if it described a quoted object.
+THING is typically either 'evil-quote or 'evil-chars. This
+function is called from `evil-select-quote'."
+  (save-excursion
+    (let* ((count (or count 1))
+           (dir (if (> count 0) 1 -1))
+           (bnd (let ((b (bounds-of-thing-at-point thing)))
+                  (and b (< (point) (cdr b)) b)))
+           contains-string
+           addcurrent
+           wsboth)
+      (if inclusive (setq inclusive t)
+        (when (= (abs count) 2)
+          (setq count dir)
+          (setq inclusive 'quote-only))
+        ;; never extend with exclusive selection
+        (setq beg nil end nil))
+      ;; check if the previously selected range does not contain a
+      ;; string
+      (unless (and beg end
+                   (save-excursion
+                     (goto-char (if (> dir 0) beg end))
+                     (forward-thing thing dir)
+                     (and (<= beg (point)) (< (point) end))))
+        ;; if so forget the range
+        (setq beg nil end nil))
+      ;; check if there is a current object, if not fetch one
+      (when (not bnd)
+        (unless (and (zerop (forward-thing thing dir))
+                     (setq bnd (bounds-of-thing-at-point thing)))
+          (error "No quoted string found"))
+        (if (> dir 0)
+            (setq end (point))
+          (setq beg (point)))
+        (setq addcurrent t))
+      ;; check if current object is not selected
+      (when (or (not beg) (not end) (> beg (car bnd)) (< end (cdr bnd)))
+        ;; if not, enlarge selection
+        (when (or (not beg) (< (car bnd) beg)) (setq beg (car bnd)))
+        (when (or (not end) (> (cdr bnd) end)) (setq end (cdr bnd)))
+        (setq addcurrent t wsboth t))
+      ;; maybe count current element
+      (when addcurrent
+        (setq count (if (> dir 0) (1- count) (1+ count))))
+      ;; enlarge selection
+      (goto-char (if (> dir 0) end beg))
+      (when (and (not addcurrent)
+                 (= count (forward-thing thing count)))
+        (error "No quoted string found"))
+      (if (> dir 0) (setq end (point)) (setq beg (point)))
+      ;; add whitespace
+      (cond
+       ((not inclusive) (setq beg (1+ beg) end (1- end)))
+       ((not (eq inclusive 'quote-only))
+        ;; try to add whitespace in forward direction
+        (goto-char (if (> dir 0) end beg))
+        (if (setq bnd (bounds-of-thing-at-point 'evil-space))
+            (if (> dir 0) (setq end (cdr bnd)) (setq beg (car bnd)))
+          ;; if not found try backward direction
+          (goto-char (if (> dir 0) beg end))
+          (if (and wsboth (setq bnd (bounds-of-thing-at-point 'evil-space)))
+              (if (> dir 0) (setq beg (car bnd)) (setq end (cdr bnd)))))))
+      (evil-range beg end
+                  ;; HACK: fixes #583
+                  ;; When not in visual state, an empty range is
+                  ;; possible. However, this cannot be achieved with
+                  ;; inclusive ranges, hence we use exclusive ranges
+                  ;; in this case. In visual state the range must be
+                  ;; inclusive because otherwise the selection would
+                  ;; be wrong.
+                  (if (evil-visual-state-p) 'inclusive 'exclusive)
+                  :expanded t))))
+
+(defun evil-select-quote (quote beg end type count &optional inclusive)
+  "Return a range (BEG END) of COUNT quoted text objects.
+QUOTE specifies the quotation delimiter. BEG END TYPE are the
+currently selected (visual) range.
+
+If INCLUSIVE is nil the previous selection is ignore. If there is
+quoted string at point this object will be selected, otherwise
+the following (if (> COUNT 0)) or preceeding object (if (< COUNT
+0)) is selected. If (/= (abs COUNT) 2) the delimiting quotes are not
+contained in the range, otherwise they are contained in the range.
+
+If INCLUSIVE is non-nil the selection depends on the previous
+selection. If the currently selection contains at least one
+character that is contained in a quoted string then the selection
+is extended, otherwise it is thrown away. If there is a
+non-selected object at point then this object is added to the
+selection. Otherwise the selection is extended to the
+following (if (> COUNT 0)) or preceeding object (if (< COUNT
+0)). Any whitespace following (or preceeding if (< COUNT 0)) the
+new selection is added to the selection. If no such whitespace
+exists and the selection contains only one quoted string then the
+preceeding (or following) whitespace is added to the range. "
+  (let ((evil-forward-quote-char quote))
+    (or (let ((bnd (or (bounds-of-thing-at-point 'evil-comment)
+                       (bounds-of-thing-at-point 'evil-string))))
+          (when (and bnd (< (point) (cdr bnd))
+                     (/= (char-after (car bnd)) quote)
+                     (/= (char-before (cdr bnd)) quote))
+            (evil-with-restriction (car bnd) (cdr bnd)
+              (condition-case nil
+                  (evil-select-quote-thing 'evil-quote-simple
+                                           beg end type
+                                           count
+                                           inclusive)
+                (error nil)))))
+        (let ((evil-forward-quote-char quote))
+          (evil-select-quote-thing 'evil-quote
+                                   beg end type
+                                   count
+                                   inclusive)))))
+
+(defun evil-select-xml-tag (beg end type &optional count inclusive)
+  "Return a range (BEG END) of COUNT matching XML tags.
+If INCLUSIVE is non-nil, the tags themselves are included
+from the range."
+  (cond
+   ((and (not inclusive) (= (abs (or count 1)) 1))
+    (let ((rng (evil-select-block #'evil-up-xml-tag beg end type count nil t)))
+      (if (or (and beg (= beg (evil-range-beginning rng))
+                   end (= end (evil-range-end rng)))
+              (= (evil-range-beginning rng) (evil-range-end rng)))
+          (evil-select-block #'evil-up-xml-tag beg end type count t)
+        rng)))
+   (t
+    (evil-select-block #'evil-up-xml-tag beg end type count inclusive))))
+
+(defun evil-expand-range (range &optional copy)
+  "Expand RANGE according to its type.
+Return a new range if COPY is non-nil."
+  (when copy
+    (setq range (evil-copy-range range)))
+  (unless (plist-get (evil-range-properties range) :expanded)
+    (setq range (evil-transform-range :expand range)))
+  range)
+
+(defun evil-contract-range (range &optional copy)
+  "Contract RANGE according to its type.
+Return a new range if COPY is non-nil."
+  (evil-transform-range :contract range copy))
+
+(defun evil-normalize-range (range &optional copy)
+  "Normalize RANGE according to its type.
+Return a new range if COPY is non-nil."
+  (evil-transform-range :normalize range copy))
+
+(defun evil-transform-range (transform range &optional copy)
+  "Apply TRANSFORM to RANGE according to its type.
+Return a new range if COPY is non-nil."
+  (when copy
+    (setq range (evil-copy-range range)))
+  (when (evil-type range)
+    (apply #'evil-set-range range
+           (apply #'evil-transform transform range)))
+  range)
+
+(defun evil-describe-range (range)
+  "Return description of RANGE.
+If no description is available, return the empty string."
+  (apply #'evil-describe range))
+
+;;; Undo
+
+(defun evil-start-undo-step (&optional continue)
+  "Start a undo step.
+All following buffer modifications are grouped together as a
+single action. If CONTINUE is non-nil, preceding modifications
+are included. The step is terminated with `evil-end-undo-step'."
+  (when (and (listp buffer-undo-list)
+             (not evil-in-single-undo))
+    (if evil-undo-list-pointer
+        (evil-refresh-undo-step)
+      (unless (or continue (null (car-safe buffer-undo-list)))
+        (undo-boundary))
+      (setq evil-undo-list-pointer (or buffer-undo-list t)))))
+
+(defun evil-end-undo-step (&optional continue)
+  "End a undo step started with `evil-start-undo-step'.
+Adds an undo boundary unless CONTINUE is specified."
+  (when (and (listp buffer-undo-list)
+             evil-undo-list-pointer
+             (not evil-in-single-undo))
+    (evil-refresh-undo-step)
+    (unless (or continue (null (car-safe buffer-undo-list)))
+      (undo-boundary))
+    (setq evil-undo-list-pointer nil)))
+
+(defun evil-refresh-undo-step ()
+  "Refresh `buffer-undo-list' entries for current undo step.
+Undo boundaries until `evil-undo-list-pointer' are removed to
+make the entries undoable as a single action. See
+`evil-start-undo-step'."
+  (when evil-undo-list-pointer
+    (setq buffer-undo-list
+          (evil-filter-list #'null buffer-undo-list evil-undo-list-pointer))
+    (setq evil-undo-list-pointer (or buffer-undo-list t))))
+
+(defmacro evil-with-undo (&rest body)
+  "Execute BODY with enabled undo.
+If undo is disabled in the current buffer, the undo information
+is stored in `evil-temporary-undo' instead of `buffer-undo-list'."
+  (declare (indent defun)
+           (debug t))
+  `(unwind-protect
+       (let (buffer-undo-list)
+         (unwind-protect
+             (progn ,@body)
+           (setq evil-temporary-undo buffer-undo-list)
+           ;; ensure evil-temporary-undo starts with exactly one undo
+           ;; boundary marker, i.e. nil
+           (unless (null (car-safe evil-temporary-undo))
+             (push nil evil-temporary-undo))))
+     (unless (eq buffer-undo-list t)
+       ;; undo is enabled, so update the global buffer undo list
+       (setq buffer-undo-list
+             ;; prepend new undos (if there are any)
+             (if (cdr evil-temporary-undo)
+                 (nconc evil-temporary-undo buffer-undo-list)
+               buffer-undo-list)
+             evil-temporary-undo nil))))
+
+(defmacro evil-with-single-undo (&rest body)
+  "Execute BODY as a single undo step."
+  (declare (indent defun)
+           (debug t))
+  `(let (evil-undo-list-pointer)
+     (evil-with-undo
+       (unwind-protect
+           (progn
+             (evil-start-undo-step)
+             (let ((evil-in-single-undo t))
+               ,@body))
+         (evil-end-undo-step)))))
+
+(defun evil-undo-pop ()
+  "Undo the last buffer change.
+Removes the last undo information from `buffer-undo-list'.
+If undo is disabled in the current buffer, use the information
+in `evil-temporary-undo' instead."
+  (let ((paste-undo (list nil)))
+    (let ((undo-list (if (eq buffer-undo-list t)
+                         evil-temporary-undo
+                       buffer-undo-list)))
+      (when (or (not undo-list) (car undo-list))
+        (user-error "Can't undo previous change"))
+      (while (and undo-list (null (car undo-list)))
+        (pop undo-list)) ; remove nil
+      (while (and undo-list (car undo-list))
+        (push (pop undo-list) paste-undo))
+      (let ((buffer-undo-list (nreverse paste-undo)))
+        (evil-save-echo-area
+          (undo)))
+      (if (eq buffer-undo-list t)
+          (setq evil-temporary-undo nil)
+        (setq buffer-undo-list undo-list)))))
+
+;;; Search
+(defun evil-transform-regexp (regexp replacements-alist)
+  (let ((pos 0) result)
+    (replace-regexp-in-string
+     "\\\\+[^\\\\]"
+     #'(lambda (txt)
+         (let* ((b (match-beginning 0))
+                (e (match-end 0))
+                (ch (aref txt (1- e)))
+                (repl (assoc ch replacements-alist)))
+           (if (and repl (zerop (mod (length txt) 2)))
+               (concat (substring txt b (- e 2))
+                       (cdr repl))
+             txt)))
+     regexp nil t)))
+
+(defun evil-transform-magic (str magic quote transform &optional start)
+  "Transforms STR with magic characters.
+MAGIC is a regexp that matches all potential magic
+characters. Each occurence of CHAR as magic character within str
+is replaced by the result of calling the associated TRANSFORM
+function. TRANSFORM is a function taking two arguments, the
+character to be transformed and the rest of string after the
+character. The function should return a triple (REPLACEMENT REST
+. STOP) where REPLACEMENT is the replacement and REST is the rest
+of the string that has not been transformed. If STOP is non-nil
+then the substitution stops immediately.  The replacement starts
+at position START, everything before that position is returned
+literally.  The result is a pair (RESULT . REST). RESULT is a
+list containing the transformed parts in order. If two
+subsequents parts are both strings, they are concatenated. REST
+is the untransformed rest string (usually \"\" but may be more if
+TRANSFORM stopped the substitution). Which characters are
+considered as magic characters (i.e. the transformation happens
+if the character is NOT preceeded by a backslash) is determined
+by `evil-magic'. The special tokens \\v, \\V, \\m and \\M have
+always a special meaning (like in Vim) and should not be
+contained in TRANSFORMS, otherwise their meaning is overwritten.
+
+The parameter QUOTE is a quoting function applied to literal
+transformations, usually `regexp-quote' or `replace-quote'."
+  (save-match-data
+    (let ((regexp (concat "\\(?:\\`\\|[^\\]\\)\\(\\\\\\(?:\\(" magic "\\)\\|\\(.\\)\\)\\|\\(" magic "\\)\\)"))
+          (magic-chars (evil-get-magic evil-magic))
+          (evil-magic evil-magic)
+          (quote (or quote #'identity))
+          result stop)
+      (while (and (not stop) str (string-match regexp str))
+        (unless (zerop (match-beginning 1))
+          (push (substring str 0 (match-beginning 1)) result))
+        (let ((char (or (match-string 2 str)
+                        (match-string 3 str)
+                        (match-string 4 str)))
+              (rest (substring str (match-end 0))))
+          (cond
+           ((match-beginning 4)
+            ;; magic character without backslash
+            (if (string-match magic-chars char)
+                ;; magic, do transform
+                (let ((trans (funcall transform (aref char 0) rest)))
+                  (push (car trans) result)
+                  (setq str (cadr trans) stop (nthcdr 2 trans)))
+              ;; non-magic, literal transformation
+              (push (funcall quote char) result)
+              (setq str rest)))
+           ((match-beginning 2)
+            ;; magic character with backslash
+            (if (not (string-match magic-chars char))
+                ;; non-magic, do transform
+                (let ((trans (funcall transform (aref char 0) rest)))
+                  (push (car trans) result)
+                  (setq str (cadr trans) stop (nthcdr 2 trans)))
+              ;; magic, literal transformation
+              (push (funcall quote char) result)
+              (setq str rest)))
+           ((memq (aref char 0) '(?m ?M ?v ?V))
+            (setq evil-magic (cdr (assq (aref char 0)
+                                        '((?m . t)
+                                          (?M . nil)
+                                          (?v . very-magic)
+                                          (?V . very-nomagic)))))
+            (setq magic-chars (evil-get-magic evil-magic))
+            (setq str rest))
+           (t
+            ;; non-magic char with backslash, literal transformation
+            (push (funcall quote char) result)
+            (setq str rest)))))
+      (cond
+       ((and str (not stop))
+        (push str result)
+        (setq str ""))
+       ((not str)
+        (setq str "")))
+      ;; concatenate subsequent strings
+      ;; note that result is in reverse order
+      (let (repl)
+        (while result
+          (cond
+           ((and (stringp (car result))
+                 (zerop (length (car result))))
+            (pop result))
+           ((and (stringp (car result))
+                 (stringp (cadr result)))
+            (setq result (cons (concat (cadr result)
+                                       (car result))
+                               (nthcdr 2 result))))
+           (t
+            (push (pop result) repl))))
+        (cons repl str)))))
+
+(defconst evil-vim-regexp-replacements
+  '((?n  . "\n")           (?r  . "\r")
+    (?t  . "\t")           (?b  . "\b")
+    (?s  . "[[:space:]]")  (?S  . "[^[:space:]]")
+    (?d  . "[[:digit:]]")  (?D  . "[^[:digit:]]")
+    (?x  . "[[:xdigit:]]") (?X  . "[^[:xdigit:]]")
+    (?o  . "[0-7]")        (?O  . "[^0-7]")
+    (?a  . "[[:alpha:]]")  (?A  . "[^[:alpha:]]")
+    (?l  . "[a-z]")        (?L  . "[^a-z]")
+    (?u  . "[A-Z]")        (?U  . "[^A-Z]")
+    (?y  . "\\s")          (?Y  . "\\S")
+    (?\( . "\\(")          (?\) . "\\)")
+    (?{  . "\\{")          (?}  . "\\}")
+    (?\[ . "[")            (?\] . "]")
+    (?<  . "\\<")          (?>  . "\\>")
+    (?_  . "\\_")
+    (?*  . "*")            (?+  . "+")
+    (??  . "?")            (?=  . "?")
+    (?.  . ".")
+    (?`  . "`")            (?^  . "^")
+    (?$  . "$")            (?|  . "\\|")))
+
+(defconst evil-regexp-magic "[][(){}<>_dDsSxXoOaAlLuUwWyY.*+?=^$`|nrtb]")
+
+(defun evil-transform-vim-style-regexp (regexp)
+  "Transforms vim-style backslash codes to Emacs regexp.
+This includes the backslash codes \\d, \\D, \\s, \\S, \\x, \\X,
+\\o, \\O, \\a, \\A, \\l, \\L, \\u, \\U and \\w, \\W. The new
+codes \\y and \\Y can be used instead of the Emacs code \\s and
+\\S which have a different meaning in Vim-style."
+  (car
+   (car
+    (evil-transform-magic
+     regexp evil-regexp-magic #'regexp-quote
+     #'(lambda (char rest)
+         (let ((repl (assoc char evil-vim-regexp-replacements)))
+           (if repl
+               (list (cdr repl) rest)
+             (list (concat "\\" (char-to-string char)) rest))))))))
+
+;;; Substitute
+
+(defun evil-downcase-first (str)
+  "Return STR with the first letter downcased."
+  (if (zerop (length str))
+      str
+    (concat (downcase (substring str 0 1))
+            (substring str 1))))
+
+(defun evil-upcase-first (str)
+  "Return STR with the first letter upcased."
+  (if (zerop (length str))
+      str
+    (concat (upcase (substring str 0 1))
+            (substring str 1))))
+
+(defun evil-get-magic (magic)
+  "Returns a regexp matching the magic characters according to MAGIC.
+Depending on the value of MAGIC the following characters are
+considered magic.
+  t             [][{}*+?.&~$^
+  nil           [][{}*+?$^
+  'very-magic   not 0-9A-Za-z_
+  'very-nomagic empty."
+  (cond
+   ((eq magic t) "[][}{*+?.&~$^]")
+   ((eq magic 'very-magic) "[^0-9A-Za-z_]")
+   ((eq magic 'very-nomagic) "\\\\")
+   (t "[][}{*+?$^]")))
+
+;; TODO: support magic characters in patterns
+(defconst evil-replacement-magic "[eElLuU0-9&#,rnbt=]"
+  "All magic characters in a replacement string")
+
+(defun evil-compile-subreplacement (to &optional start)
+  "Convert a regexp replacement TO to Lisp from START until \\e or \\E.
+Returns a pair (RESULT . REST). RESULT is a list suitable for
+`perform-replace' if necessary, the original string if not.
+REST is the unparsed remainder of TO."
+  (let ((result
+         (evil-transform-magic
+          to evil-replacement-magic #'replace-quote
+          #'(lambda (char rest)
+              (cond
+               ((eq char ?#)
+                (list '(number-to-string replace-count) rest))
+               ((eq char ?r) (list "\r" rest))
+               ((eq char ?n) (list "\n" rest))
+               ((eq char ?b) (list "\b" rest))
+               ((eq char ?t) (list "\t" rest))
+               ((memq char '(?e ?E))
+                `("" ,rest . t))
+               ((memq char '(?l ?L ?u ?U))
+                (let ((result (evil-compile-subreplacement rest))
+                      (func (cdr (assoc char
+                                        '((?l . evil-downcase-first)
+                                          (?L . downcase)
+                                          (?u . evil-upcase-first)
+                                          (?U . upcase))))))
+                  (list `(,func
+                          (replace-quote
+                           (evil-match-substitute-replacement
+                            ,(car result)
+                            (not case-replace))))
+                        (cdr result))))
+               ((eq char ?=)
+                (when (or (zerop (length rest))
+                          (not (eq (aref rest 0) ?@)))
+                  (user-error "Expected @ after \\="))
+                (when (< (length rest) 2)
+                  (user-error "Expected register after \\=@"))
+                (list (evil-get-register (aref rest 1))
+                      (substring rest 2)))
+               ((eq char ?,)
+                (let* ((obj (read-from-string rest))
+                       (result `(replace-quote ,(car obj)))
+                       (end
+                        ;; swallow a space after a symbol
+                        (if (and (or (symbolp (car obj))
+                                     ;; swallow a space after 'foo,
+                                     ;; but not after (quote foo)
+                                     (and (eq (car-safe (car obj)) 'quote)
+                                          (not (= ?\( (aref rest 0)))))
+                                 (eq (string-match " " rest (cdr obj))
+                                     (cdr obj)))
+                            (1+ (cdr obj))
+                          (cdr obj))))
+                  (list result (substring rest end))))
+               ((eq char ?0)
+                (list "\\&" rest))
+               (t
+                (list (concat "\\" (char-to-string char)) rest))))
+          start)))
+    (let ((rest (cdr result))
+          (result (car result)))
+      (replace-match-string-symbols result)
+      (cons (if (cdr result)
+                (cons 'concat result)
+              (or (car result) ""))
+            rest))))
+
+(defun evil-compile-replacement (to)
+  "Maybe convert a regexp replacement TO to Lisp.
+Returns a list suitable for `perform-replace' if necessary, the
+original string if not. Currently the following magic characters
+in replacements are supported: 0-9&#lLuUrnbt,
+The magic character , (comma) start an Emacs-lisp expression."
+  (when (stringp to)
+    (save-match-data
+      (cons 'replace-eval-replacement
+            (car (evil-compile-subreplacement to))))))
+
+(defun evil-replace-match (replacement &optional fixedcase string)
+  "Replace text match by last search with REPLACEMENT.
+If REPLACEMENT is an expression it will be evaluated to compute
+the replacement text, otherwise the function behaves as
+`replace-match'."
+  (if (stringp replacement)
+      (replace-match replacement fixedcase nil string)
+    (replace-match (funcall (car replacement)
+                            (cdr replacement)
+                            0)
+                   fixedcase nil string)))
+
+(defun evil-match-substitute-replacement (replacement &optional fixedcase string)
+  "Return REPLACEMENT as it will be inserted by `evil-replace-match'."
+  (if (stringp replacement)
+      (match-substitute-replacement replacement fixedcase nil string)
+    (match-substitute-replacement (funcall (car replacement)
+                                           (cdr replacement)
+                                           0)
+                                  fixedcase nil string)))
+
+;;; Alignment
+
+(defun evil-justify-lines (beg end justify position)
+  "Justifes all lines in a range.
+BEG and END specify the range of those lines to be
+justified. JUSTIFY is either 'left, 'right or 'center according
+to the justification type. POSITION is the maximal text width for
+right and center justification or the column at which the lines
+should be left-aligned for left justification."
+  (let ((fill-column position)
+        adaptive-fill-mode fill-prefix)
+    (evil-with-restriction
+        (save-excursion
+          (goto-char beg)
+          (line-beginning-position))
+        (save-excursion
+          (goto-char end)
+          (if (bolp)
+              (line-end-position 0)
+            (line-end-position)))
+      (goto-char (point-min))
+      (while (progn
+               (if (eq justify 'left)
+                   (indent-line-to position)
+                 (when (re-search-forward "^[[:space:]]*" nil t)
+                   (delete-region (match-beginning 0)
+                                  (match-end 0)))
+                 (justify-current-line justify nil t))
+               (and (zerop (forward-line)) (bolp))))
+      (goto-char (point-min))
+      (back-to-indentation))))
+
+;;; View helper
+
+(defvar-local evil-list-view-select-action nil)
+(put 'evil-list-view-select-action 'permanent-local t)
+
+(define-derived-mode evil-list-view-mode tabulated-list-mode
+  "Evil List View"
+  (tabulated-list-init-header)
+  (tabulated-list-print))
+
+(defun evil-list-view-goto-entry ()
+  (interactive)
+  (when (and evil-list-view-select-action
+             (not (eobp)))
+    (let* ((line (line-number-at-pos (point)))
+           (entry (elt tabulated-list-entries (1- line))))
+      (funcall evil-list-view-select-action (nth 1 entry)))))
+
+(define-key evil-list-view-mode-map (kbd "q") #'kill-this-buffer)
+(define-key evil-list-view-mode-map [follow-link] nil) ;; allows mouse-1 to be activated
+(define-key evil-list-view-mode-map [mouse-1] #'evil-list-view-goto-entry)
+(define-key evil-list-view-mode-map [return] #'evil-list-view-goto-entry)
+
+(defmacro evil-with-view-list (&rest properties)
+  "Opens new list view buffer.
+
+PROPERTIES is a property-list which supports the following properties:
+
+:name           (required)   The name of the buffer.
+:mode-name      (required)   The name for the mode line.
+:format         (required)   The value for `tabulated-list-format'.
+:entries        (required)   The value for `tabulated-list-entries'.
+:select-action  (optional)   A function for row selection.
+                             It takes in a single parameter, which is the selected row's
+                             vector value that is passed into `:entries'.
+"
+  (declare (indent defun) (debug t))
+  `(let ((bufname (concat "*" ,(plist-get properties :name) "*"))
+         (inhibit-read-only t))
+     (and (get-buffer bufname)
+          (kill-buffer bufname))
+     (let ((buf (get-buffer-create bufname)))
+       (with-current-buffer buf
+         (setq tabulated-list-format ,(plist-get properties :format))
+         (setq tabulated-list-entries ,(plist-get properties :entries))
+         (setq evil-list-view-select-action ,(plist-get properties :select-action))
+         (evil-list-view-mode)
+         (setq mode-name ,(plist-get properties :mode-name))
+         (evil-motion-state))
+       (switch-to-buffer-other-window buf))))
+
+(provide 'evil-common)
+
+;;; evil-common.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-common.elc b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-common.elc
new file mode 100644
index 0000000000..bb53ef246a
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-common.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-core.el b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-core.el
new file mode 100644
index 0000000000..645a992961
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-core.el
@@ -0,0 +1,1363 @@
+;;; evil-core.el --- Core functionality
+;; Author: Vegard Øye <vegard_oye at hotmail.com>
+;; Maintainer: Vegard Øye <vegard_oye at hotmail.com>
+
+;; Version: 1.2.13
+
+;;
+;; This file is NOT part of GNU Emacs.
+
+;;; License:
+
+;; This file is part of Evil.
+;;
+;; Evil 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.
+;;
+;; Evil 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 Evil.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Evil is defined as a globalized minor mode, enabled with the toggle
+;; function `evil-mode'.  This in turn enables `evil-local-mode' in
+;; every buffer, which sets up the buffer's state.
+;;
+;; Each state has its own keymaps, and these keymaps have status as
+;; "emulation keymaps" with priority over regular keymaps.  Emacs
+;; maintains the following keymap hierarchy (highest priority first):
+;;
+;;     * Overriding keymaps/overlay keymaps...
+;;     * Emulation mode keymaps...
+;;       - Evil keymaps...
+;;     * Minor mode keymaps...
+;;     * Local keymap (`local-set-key')
+;;     * Global keymap (`global-set-key')
+;;
+;; Within this hierarchy, Evil arranges the keymaps for the current
+;; state as shown below:
+;;
+;;     * Intercept keymaps...
+;;     * Local state keymap
+;;     * Minor-mode keymaps...
+;;     * Auxiliary keymaps...
+;;     * Overriding keymaps...
+;;     * Global state keymap
+;;     * Keymaps for other states...
+;;
+;; These keymaps are listed in `evil-mode-map-alist', which is listed
+;; in `emulation-mode-map-alist'.
+;;
+;; Most of the key bindings for a state are stored in its global
+;; keymap, which has a name such as `evil-normal-state-map'. (See the
+;; file evil-maps.el, which contains all the default key bindings.) A
+;; state also has a local keymap (`evil-normal-state-local-map'),
+;; which may contain user customizations for the current buffer.
+;; Furthermore, any Emacs mode may be assigned state bindings of its
+;; own by passing the mode's keymap to the function `evil-define-key'
+;; or `evil-define-minor-mode-key'. The former uses a specific map to
+;; define the key in while the latter associates the key with a
+;; particular mode. These mode-specific bindings are ultimately stored
+;; in so-called auxiliary and minor-mode keymaps respectively, which
+;; are sandwiched between the local keymap and the global keymap.
+;; Finally, the state may also activate the keymaps of other states
+;; (e.g., Normal state inherits bindings from Motion state).
+;;
+;; For integration purposes, a regular Emacs keymap may be "elevated"
+;; to emulation status by passing it to `evil-make-intercept-map' or
+;; `evil-make-overriding-map'.  An "intercept" keymap has priority over
+;; all other Evil keymaps.  (Evil uses this facility when debugging and
+;; for handling the "ESC" key in the terminal.) More common is the
+;; "overriding" keymap, which only has priority over the global state
+;; keymap.  (This is useful for adapting key-heavy modes such as Dired,
+;; where all but a few keys should be left as-is and should not be
+;; shadowed by Evil's default bindings.)
+;;
+;; States are defined with the macro `evil-define-state', which
+;; creates a command for switching to the state.  This command,
+;; for example `evil-normal-state' for Normal state, performs
+;; the following tasks:
+;;
+;;     * Setting `evil-state' to the new state.
+;;     * Refreshing the keymaps in `evil-mode-map-alist'.
+;;     * Updating the mode line.
+;;       - Normal state depends on `evil-normal-state-tag'.
+;;     * Adjusting the cursor's appearance.
+;;       - Normal state depends on `evil-normal-state-cursor'.
+;;     * Displaying a message in the echo area.
+;;       - Normal state depends on `evil-normal-state-message'.
+;;     * Running hooks.
+;;       - Normal state runs `evil-normal-state-entry-hook' when
+;;         entering, and `evil-normal-state-exit-hook' when exiting.
+;;
+;; The various properties of a state can be accessed through their
+;; respective variables, or by passing a keyword and the state's name
+;; to the `evil-state-property' function.  Evil defines the states
+;; Normal state ("normal"), Insert state ("insert"), Visual state
+;; ("visual"), Replace state ("replace"), Operator-Pending state
+;; ("operator"), Motion state ("motion") and Emacs state ("emacs").
+
+(require 'evil-common)
+
+;;; Code:
+
+(declare-function evil-emacs-state-p "evil-states")
+(declare-function evil-ex-p "evil-ex")
+(defvar evil-mode-buffers)
+
+(define-minor-mode evil-local-mode
+  "Minor mode for setting up Evil in a single buffer."
+  :init-value nil
+  (cond
+   ((evil-disabled-buffer-p)
+    ;; Don't leave the mode variable on in buffers where evil disabled, because
+    ;; functions that check this variable will get an incorrect result (e.g.,
+    ;; evil-refresh-cursor).
+    (setq evil-local-mode nil))
+   (evil-local-mode
+    (setq emulation-mode-map-alists
+          (evil-concat-lists '(evil-mode-map-alist)
+                             emulation-mode-map-alists))
+    (evil-initialize-local-keymaps)
+    ;; restore the proper value of `major-mode' in Fundamental buffers
+    (when (eq major-mode 'turn-on-evil-mode)
+      (setq major-mode 'fundamental-mode))
+    ;; The initial state is usually setup by `evil-initialize' when
+    ;; the major-mode in a buffer changes. This preliminary
+    ;; initialization is only for the case when `evil-local-mode' is
+    ;; called directly for the first time in a buffer.
+    (unless evil-state (evil-initialize-state))
+    (add-hook 'input-method-activate-hook 'evil-activate-input-method t t)
+    (add-hook 'input-method-deactivate-hook 'evil-deactivate-input-method t t)
+    (add-hook 'activate-mark-hook 'evil-visual-activate-hook nil t)
+    (add-hook 'pre-command-hook 'evil-repeat-pre-hook)
+    (add-hook 'post-command-hook 'evil-repeat-post-hook))
+   (t
+    (evil-refresh-mode-line)
+    (remove-hook 'activate-mark-hook 'evil-visual-activate-hook t)
+    (remove-hook 'input-method-activate-hook 'evil-activate-input-method t)
+    (remove-hook 'input-method-deactivate-hook 'evil-deactivate-input-method t)
+    (evil-change-state nil))))
+
+;; Make the variable permanent local.  This is particular useful in
+;; conjunction with nXhtml/mumamo because mumamo does not touch these
+;; variables.
+(put 'evil-local-mode 'permanent-local t)
+
+(defun turn-on-evil-mode (&optional arg)
+  "Turn on Evil in the current buffer."
+  (interactive)
+  (evil-local-mode (or arg 1)))
+
+(defun turn-off-evil-mode (&optional arg)
+  "Turn off Evil in the current buffer."
+  (interactive)
+  (evil-local-mode (or arg -1)))
+
+;; The function `evil-initialize' should only be used to initialize
+;; `evil-local-mode' from the globalized minor-mode `evil-mode'. It is
+;; called whenever evil is enabled in a buffer for the first time or
+;; when evil is active and the major-mode of the buffer changes. In
+;; addition to enabling `evil-local-mode' it also sets the initial
+;; evil-state according to the major-mode.
+(defun evil-initialize ()
+  "Enable Evil in the current buffer, if appropriate.
+To enable Evil globally, do (evil-mode 1)."
+  ;; TODO: option for enabling vi keys in the minibuffer
+  (unless (minibufferp)
+    (evil-local-mode 1)
+    (evil-initialize-state)))
+
+;;;###autoload (autoload 'evil-mode "evil" nil t)
+(define-globalized-minor-mode evil-mode
+  evil-local-mode evil-initialize)
+
+;; No hooks are run in Fundamental buffers, so other measures are
+;; necessary to initialize Evil in these buffers. When Evil is
+;; enabled globally, the default value of `major-mode' is set to
+;; `turn-on-evil-mode', so that Evil is enabled in Fundamental
+;; buffers as well. Then, the buffer-local value of `major-mode' is
+;; changed back to `fundamental-mode'. (Since the `evil-mode' function
+;; is created by a macro, we use `defadvice' to augment it.)
+(defadvice evil-mode (after start-evil activate)
+  "Enable Evil in Fundamental mode."
+  (if evil-mode
+      (progn
+        (when (eq (default-value 'major-mode) 'fundamental-mode)
+          ;; changed back by `evil-local-mode'
+          (setq-default major-mode 'turn-on-evil-mode))
+        (ad-enable-regexp "^evil")
+        (ad-activate-regexp "^evil")
+        (with-no-warnings (evil-esc-mode 1)))
+    (when (eq (default-value 'major-mode) 'turn-on-evil-mode)
+      (setq-default major-mode 'fundamental-mode))
+    (ad-disable-regexp "^evil")
+    (ad-update-regexp "^evil")
+    (with-no-warnings (evil-esc-mode -1))))
+
+(defun evil-change-state (state &optional message)
+  "Change the state to STATE.
+If STATE is nil, disable all states."
+  (let ((func (evil-state-property (or state evil-state) :toggle)))
+    (when (and (functionp func)
+               (or message (not (eq state evil-state))))
+      (funcall func (if state (and message 1) -1)))))
+
+(defmacro evil-save-state (&rest body)
+  "Save the current state; execute BODY; restore the state."
+  (declare (indent defun)
+           (debug t))
+  `(let* ((evil-state evil-state)
+          (evil-previous-state evil-previous-state)
+          (evil-previous-state-alist (copy-tree evil-previous-state-alist))
+          (evil-next-state evil-next-state)
+          (old-state evil-state)
+          (inhibit-quit t)
+          (buf (current-buffer)))
+     (unwind-protect
+         (progn ,@body)
+       (when (buffer-live-p buf)
+         (with-current-buffer buf
+           (evil-change-state old-state))))))
+
+(defmacro evil-with-state (state &rest body)
+  "Change to STATE and execute BODY without refreshing the display.
+Restore the previous state afterwards."
+  (declare (indent defun)
+           (debug t))
+  `(evil-without-display
+     (evil-save-state
+       (evil-change-state ',state)
+       ,@body)))
+
+(defun evil-initializing-p (&optional buffer)
+  "Whether Evil is in the process of being initialized."
+  (memq (or buffer (current-buffer)) evil-mode-buffers))
+
+(defun evil-initialize-state (&optional state buffer)
+  "Set up the initial state for BUFFER.
+BUFFER defaults to the current buffer.
+Uses STATE if specified, or calls `evil-initial-state-for-buffer'.
+See also `evil-set-initial-state'."
+  (with-current-buffer (or buffer (current-buffer))
+    (if state (evil-change-state state)
+      (evil-change-to-initial-state buffer))))
+(put 'evil-initialize-state 'permanent-local-hook t)
+
+(defun evil-initial-state-for-buffer-name (&optional name default)
+  "Return the initial Evil state to use for a buffer with name NAME.
+Matches the name against the regular expressions in
+`evil-buffer-regexps'. If none matches, returns DEFAULT."
+  (let ((name (if (stringp name) name (buffer-name name)))
+        regexp state)
+    (when (stringp name)
+      (catch 'done
+        (dolist (entry evil-buffer-regexps default)
+          (setq regexp (car entry)
+                state (cdr entry))
+          (when (string-match regexp name)
+            (throw 'done state)))))))
+
+(defun evil-disabled-buffer-p (&optional buffer)
+  "Whether Evil should be disabled in BUFFER."
+  (null (evil-initial-state-for-buffer-name buffer 'undefined)))
+
+(defun evil-initial-state-for-buffer (&optional buffer default)
+  "Return the initial Evil state to use for BUFFER.
+BUFFER defaults to the current buffer. Returns DEFAULT
+if no initial state is associated with BUFFER.
+See also `evil-initial-state'."
+  (with-current-buffer (or buffer (current-buffer))
+    (or (evil-initial-state-for-buffer-name (buffer-name))
+        (catch 'done
+          (dolist (mode minor-mode-map-alist)
+            (setq mode (car-safe mode))
+            (when (and (boundp mode) (symbol-value mode))
+              (when (setq mode (evil-initial-state mode))
+                (throw 'done mode)))))
+        (evil-initial-state major-mode nil t)
+        default)))
+
+(defun evil-initial-state (mode &optional default follow-parent checked-modes)
+  "Return the Evil state to use for MODE or its alias.
+Returns DEFAULT if no initial state is associated with MODE.
+The initial state for a mode can be set with
+`evil-set-initial-state'.
+
+If FOLLOW-PARENT is non-nil, also check parent modes of MODE and
+its alias. CHECKED-MODES is used internally and should not be set
+initially."
+  (cond
+   ((and mode (symbolp mode) (memq mode checked-modes))
+    (error "Circular reference detected in ancestors of %s\n%s"
+           major-mode checked-modes))
+   ((and mode (symbolp mode))
+    (let ((mode-alias (let ((func (symbol-function mode)))
+                        (when (symbolp func)
+                          func)))
+          state modes)
+      (or
+       (catch 'done
+         (dolist (entry (evil-state-property t :modes) default)
+           (setq state (car entry)
+                 modes (symbol-value (cdr entry)))
+           (when (or (memq mode modes)
+                     (and mode-alias
+                          (memq mode-alias modes)))
+             (throw 'done state))))
+       (when follow-parent
+         (evil-initial-state (get mode 'derived-mode-parent)
+                             nil t (cons mode checked-modes)))
+       (when follow-parent
+         (evil-initial-state (get mode-alias 'derived-mode-parent)
+                             nil t (cons mode-alias checked-modes))))))))
+
+(defun evil-set-initial-state (mode state)
+  "Set the initial state for MODE to STATE.
+This is the state the buffer comes up in."
+  (dolist (modes (evil-state-property t :modes))
+    (setq modes (cdr-safe modes))
+    (set modes (delq mode (symbol-value modes))))
+  (when state
+    (add-to-list (evil-state-property state :modes) mode)))
+
+(evil-define-command evil-change-to-initial-state
+  (&optional buffer message)
+  "Change the state of BUFFER to its initial state.
+This is the state the buffer came up in. If Evil is not activated
+then this function does nothing."
+  :keep-visual t
+  :suppress-operator t
+  (with-current-buffer (or buffer (current-buffer))
+    (when evil-local-mode
+      (evil-change-state (evil-initial-state-for-buffer
+                          buffer (or evil-default-state 'normal))
+                         message))))
+
+(evil-define-command evil-change-to-previous-state
+  (&optional buffer message)
+  "Change the state of BUFFER to its previous state."
+  :keep-visual t
+  :repeat abort
+  :suppress-operator t
+  (with-current-buffer (or buffer (current-buffer))
+    (let ((prev-state evil-previous-state)
+          (prev-prev-state (cdr-safe (assoc evil-previous-state
+                                            evil-previous-state-alist))))
+      (evil-change-state nil)
+      (when prev-prev-state
+        (setq evil-previous-state prev-prev-state))
+      (evil-change-state (or prev-state evil-default-state 'normal)
+                         message))))
+
+;; When a buffer is created in a low-level way, it is invisible to
+;; Evil (as well as other globalized minor modes) because no hooks are
+;; run. This is appropriate since many buffers are used for throwaway
+;; purposes. Passing the buffer to `set-window-buffer' indicates
+;; otherwise, though, so advise this function to initialize Evil.
+(defadvice set-window-buffer (before evil)
+  "Initialize Evil in the displayed buffer."
+  (when evil-mode
+    (when (get-buffer (ad-get-arg 1))
+      (with-current-buffer (ad-get-arg 1)
+        (unless evil-local-mode
+          (evil-local-mode 1))))))
+
+;; Refresh cursor color.
+;; Cursor color can only be set for each frame but not for each buffer.
+(add-hook 'window-configuration-change-hook 'evil-refresh-cursor)
+(defadvice select-window (after evil activate)
+  (evil-refresh-cursor))
+
+(defun evil-generate-mode-line-tag (&optional state)
+  "Generate the evil mode-line tag for STATE."
+  (let ((tag (evil-state-property state :tag t)))
+    ;; prepare mode-line: add tooltip
+    (if (stringp tag)
+        (propertize tag
+                    'help-echo (evil-state-property state :name)
+                    'mouse-face 'mode-line-highlight)
+      tag)))
+
+(defun evil-refresh-mode-line (&optional state)
+  "Refresh mode line tag."
+  (when (listp mode-line-format)
+    (setq evil-mode-line-tag (evil-generate-mode-line-tag state))
+    ;; refresh mode line data structure
+    ;; first remove evil from mode-line
+    (setq mode-line-format (delq 'evil-mode-line-tag mode-line-format))
+    (let ((mlpos mode-line-format)
+          pred which where)
+      ;; determine before/after which symbol the tag should be placed
+      (cond
+       ((eq evil-mode-line-format 'before)
+        (setq where 'after which 'mode-line-position))
+       ((eq evil-mode-line-format 'after)
+        (setq where 'after which 'mode-line-modes))
+       ((consp evil-mode-line-format)
+        (setq where (car evil-mode-line-format)
+              which (cdr evil-mode-line-format))))
+      ;; find the cons-cell of the symbol before/after which the tag
+      ;; should be placed
+      (while (and mlpos
+                  (let ((sym (or (car-safe (car mlpos)) (car mlpos))))
+                    (not (eq which sym))))
+        (setq pred mlpos
+              mlpos (cdr mlpos)))
+      ;; put evil tag at the right position in the mode line
+      (cond
+       ((not mlpos)) ;; position not found, so do not add the tag
+       ((eq where 'before)
+        (if pred
+            (setcdr pred (cons 'evil-mode-line-tag mlpos))
+          (setq mode-line-format
+                (cons 'evil-mode-line-tag mode-line-format))))
+       ((eq where 'after)
+        (setcdr mlpos (cons 'evil-mode-line-tag (cdr mlpos)))))
+      (force-mode-line-update))))
+
+;; input methods should be disabled in non-insertion states
+(defun evil-activate-input-method ()
+  "Enable input method in states with :input-method non-nil."
+  (let (input-method-activate-hook
+        input-method-deactivate-hook)
+    (when (and evil-local-mode evil-state)
+      (setq evil-input-method current-input-method)
+      (unless (evil-state-property evil-state :input-method)
+        (deactivate-input-method)))))
+(put 'evil-activate-input-method 'permanent-local-hook t)
+
+(defun evil-deactivate-input-method ()
+  "Disable input method in all states."
+  (let (input-method-activate-hook
+        input-method-deactivate-hook)
+    (when (and evil-local-mode evil-state)
+      (setq evil-input-method nil))))
+(put 'evil-deactivate-input-method 'permanent-local-hook t)
+
+(defmacro evil-without-input-method-hooks (&rest body)
+  "Execute body with evil's activate/deactivate-input-method hooks deactivated.
+
+This allows input methods to be used in normal-state."
+  `(unwind-protect
+       (progn
+         (remove-hook 'input-method-activate-hook 'evil-activate-input-method t)
+         (remove-hook 'input-method-deactivate-hook
+                      'evil-deactivate-input-method t)
+         ,@body)
+     (progn
+       (add-hook 'input-method-activate-hook 'evil-activate-input-method nil t)
+       (add-hook 'input-method-deactivate-hook
+                 'evil-deactivate-input-method nil t))))
+
+(defadvice toggle-input-method (around evil)
+  "Refresh `evil-input-method'."
+  (cond
+   ((not evil-local-mode)
+    ad-do-it)
+   ((evil-state-property evil-state :input-method)
+    ad-do-it)
+   (t
+    (let ((current-input-method evil-input-method))
+      ad-do-it))))
+
+;; Local keymaps are implemented using buffer-local variables.
+;; However, unless a buffer-local value already exists,
+;; `define-key' acts on the variable's default (global) value.
+;; So we need to initialize the variable whenever we enter a
+;; new buffer or when the buffer-local values are reset.
+(defun evil-initialize-local-keymaps ()
+  "Initialize a buffer-local value for local keymaps as necessary.
+The initial value is that of `make-sparse-keymap'."
+  (dolist (entry evil-local-keymaps-alist)
+    (let ((mode (car entry))
+          (map  (cdr entry)))
+      (unless (and (keymapp (symbol-value map))
+                   (local-variable-p map))
+        (set map (make-sparse-keymap))))))
+
+(defun evil-make-overriding-map (keymap &optional state copy)
+  "Give KEYMAP precedence over the global keymap of STATE.
+The keymap will have lower precedence than custom STATE bindings.
+If STATE is nil, give it precedence over all states.
+If COPY is t, create a copy of KEYMAP and give that
+higher precedence. See also `evil-make-intercept-map'."
+  (let ((key [override-state]))
+    (if (not copy)
+        (define-key keymap key (or state 'all))
+      (unless (keymapp copy)
+        (setq copy (assq-delete-all 'menu-bar (copy-keymap keymap))))
+      (define-key copy key (or state 'all))
+      (define-key keymap key copy))))
+
+(defun evil-make-intercept-map (keymap &optional state aux)
+  "Give KEYMAP precedence over all Evil keymaps in STATE.
+If STATE is nil, give it precedence over all states. If AUX is non-nil, make the
+auxiliary keymap corresponding to KEYMAP in STATE an intercept keymap instead of
+KEYMAP itself. See also `evil-make-overriding-map'."
+  (let ((key [intercept-state])
+        (keymap (if aux
+                    (evil-get-auxiliary-keymap keymap state t t)
+                  keymap)))
+    (define-key keymap key (or state 'all))))
+
+(defmacro evil-define-keymap (keymap doc &rest body)
+  "Define a keymap KEYMAP listed in `evil-mode-map-alist'.
+That means it will have precedence over regular keymaps.
+
+DOC is the documentation for the variable. BODY, if specified,
+is executed after toggling the mode. Optional keyword arguments
+may be specified before the body code:
+
+:mode VAR       Mode variable. If unspecified, the variable
+                is based on the keymap name.
+:local BOOLEAN  Whether the keymap should be buffer-local, that is,
+                reinitialized for each buffer.
+:func BOOLEAN   Create a toggle function even if BODY is empty.
+
+\(fn KEYMAP DOC [[KEY VAL]...] BODY...)"
+  (declare (indent defun)
+           (debug (&define name
+                           [&optional stringp]
+                           [&rest [keywordp sexp]]
+                           def-body)))
+  (let ((func t)
+        arg intercept key local mode overriding)
+    (while (keywordp (car-safe body))
+      (setq key (pop body)
+            arg (pop body))
+      (cond
+       ((eq key :mode)
+        (setq mode arg))
+       ((eq key :local)
+        (setq local arg))
+       ((eq key :func)
+        (setq func arg))
+       ((eq key :intercept)
+        (setq intercept arg))
+       ((eq key :overriding)
+        (setq overriding arg))))
+    (setq mode (or mode
+                   (intern (replace-regexp-in-string
+                            "\\(?:-\\(?:mode-\\)?\\(?:key\\)?map\\)?$"
+                            "-mode"
+                            (symbol-name keymap)))))
+    `(progn
+       (defvar ,keymap ,(unless local '(make-sparse-keymap)))
+       (unless (get ',keymap 'variable-documentation)
+         (put ',keymap 'variable-documentation ,doc))
+       (defvar ,mode nil)
+       (unless (get ',mode 'variable-documentation)
+         (put ',mode 'variable-documentation ,doc))
+       (make-variable-buffer-local ',mode)
+       (put ',mode 'permanent-local t)
+       (when ,intercept
+         (evil-make-intercept-map ,keymap))
+       (when ,overriding
+         (evil-make-overriding-map ,keymap))
+       ,@(if local
+             `((make-variable-buffer-local ',keymap)
+               (put ',keymap 'permanent-local t)
+               (evil-add-to-alist 'evil-local-keymaps-alist
+                                  ',mode ',keymap))
+           `((evil-add-to-alist 'evil-global-keymaps-alist
+                                ',mode ',keymap)
+             (evil-add-to-alist 'evil-mode-map-alist
+                                ',mode ,keymap)))
+       ,(when (or body func)
+          `(defun ,mode (&optional arg)
+             ,@(when doc `(,doc))
+             (interactive)
+             (cond
+              ((numberp arg)
+               (setq ,mode (> arg 0)))
+              (t
+               (setq ,mode (not ,mode))))
+             ,@body))
+       ',keymap)))
+
+;; The ESC -> escape translation code has been provided by Stefan
+;; Monnier in the discussion of GNU Emacs bug #13793.
+(defun evil-esc-mode (&optional arg)
+  "Toggle interception of \\e (escape).
+Enable with positive ARG and disable with negative ARG.
+
+When enabled, `evil-esc-mode' modifies the entry of \\e in
+`input-decode-map'. If such an event arrives, it is translated to
+a plain 'escape event if no further event occurs within
+`evil-esc-delay' seconds. Otherwise no translation happens and
+the ESC prefix map (i.e. the map originally bound to \\e in
+`input-decode-map`) is returned."
+  (cond
+   ((or (null arg) (eq arg 0))
+    (evil-esc-mode (if evil-esc-mode -1 +1)))
+   ((> arg 0)
+    (unless evil-esc-mode
+      (setq evil-esc-mode t)
+      (add-hook 'after-make-frame-functions #'evil-init-esc)
+      (mapc #'evil-init-esc (frame-list))))
+   ((< arg 0)
+    (when evil-esc-mode
+      (remove-hook 'after-make-frame-functions #'evil-init-esc)
+      (mapc #'evil-deinit-esc (frame-list))
+      (setq evil-esc-mode nil)))))
+
+(defun evil-init-esc (frame)
+  "Update `input-decode-map' in terminal."
+  (with-selected-frame frame
+    (let ((term (frame-terminal frame)))
+      (when (and
+             (or (eq evil-intercept-esc 'always)
+                 (and evil-intercept-esc
+                      (eq (terminal-live-p term) t))) ; only patch tty
+             (not (terminal-parameter term 'evil-esc-map)))
+        (let ((evil-esc-map (lookup-key input-decode-map [?\e])))
+          (set-terminal-parameter term 'evil-esc-map evil-esc-map)
+          (define-key input-decode-map [?\e]
+            `(menu-item "" ,evil-esc-map :filter ,#'evil-esc)))))))
+
+(defun evil-deinit-esc (frame)
+  "Restore `input-decode-map' in terminal."
+  (with-selected-frame frame
+    (let ((term (frame-terminal frame)))
+      (when (terminal-live-p term)
+        (let ((evil-esc-map (terminal-parameter term 'evil-esc-map)))
+          (when evil-esc-map
+            (define-key input-decode-map [?\e] evil-esc-map)
+            (set-terminal-parameter term 'evil-esc-map nil)))))))
+
+(defun evil-esc (map)
+  "Translate \\e to 'escape if no further event arrives.
+This function is used to translate a \\e event either to 'escape
+or to the standard ESC prefix translation map. If \\e arrives,
+this function waits for `evil-esc-delay' seconds for another
+event. If no other event arrives, the event is translated to
+'escape, otherwise it is translated to the standard ESC prefix
+map stored in `input-decode-map'. If `evil-inhibit-esc' is
+non-nil or if evil is in emacs state, the event is always
+translated to the ESC prefix.
+
+The translation to 'escape happens only if the current command
+has indeed been triggered by \\e. In other words, this will only
+happen when the keymap is accessed from `read-key-sequence'. In
+particular, if it is access from `define-key' the returned
+mapping will always be the ESC prefix map."
+  (if (and (not evil-inhibit-esc)
+           (or evil-local-mode (evil-ex-p)
+               (active-minibuffer-window))
+           (not (evil-emacs-state-p))
+           (let ((keys (this-single-command-keys)))
+             (and (> (length keys) 0)
+                  (= (aref keys (1- (length keys))) ?\e)))
+           (sit-for evil-esc-delay))
+      (prog1 [escape]
+        (when defining-kbd-macro
+          (end-kbd-macro)
+          (setq last-kbd-macro (vconcat last-kbd-macro [escape]))
+          (start-kbd-macro t t)))
+    map))
+
+(defun evil-state-p (sym)
+  "Whether SYM is the name of a state."
+  (assq sym evil-state-properties))
+
+(defun evil-state-keymaps (state &rest excluded)
+  "Return a keymap alist of keymaps activated by STATE.
+If STATE references other states in its :enable property,
+these states are recursively processed and added to the list.
+\(The EXCLUDED argument is an internal safeguard against
+infinite recursion, keeping track of processed states.)"
+  (let* ((state (or state evil-state))
+         (enable (evil-state-property state :enable))
+         (map (cons
+               (evil-state-property state :mode)
+               (evil-state-property state :keymap t)))
+         (local-map (cons
+                     (evil-state-property state :local)
+                     (evil-state-property state :local-keymap t)))
+         (minor-mode-maps (evil-state-minor-mode-keymaps state))
+         (aux-maps (evil-state-auxiliary-keymaps state))
+         (overriding-maps
+          (evil-state-overriding-keymaps state))
+         (intercept-maps
+          (evil-state-intercept-keymaps state))
+         (result `(,intercept-maps))
+         (remove-duplicates (null excluded)))
+    (unless (memq state enable)
+      (setq enable (cons state enable)))
+    ;; process STATE's :enable property
+    (dolist (entry enable)
+      (cond
+       ((memq entry excluded))
+       ;; the keymaps for STATE
+       ((eq entry state)
+        (setq result `(,@result
+                       (,local-map)
+                       ,minor-mode-maps
+                       ,aux-maps
+                       ,overriding-maps
+                       (,map)))
+        (push state excluded))
+       ;; the keymaps for another state: call `evil-state-keymaps'
+       ;; recursively, but keep track of processed states
+       ((evil-state-p entry)
+        (setq result `(,@result
+                       ,(apply #'evil-state-keymaps entry excluded))))
+       ;; a single keymap
+       ((or (keymapp entry)
+            (and (keymapp (symbol-value entry))
+                 (setq entry (symbol-value entry)))
+            (setq entry (evil-keymap-for-mode entry)))
+        (setq result `(,@result
+                       ((,(evil-mode-for-keymap entry t) .
+                         ,entry)))))))
+    ;; postpone the expensive filtering of duplicates to the top level
+    (if remove-duplicates
+        (apply #'evil-concat-keymap-alists result)
+      (apply #'append result))))
+
+(defun evil-normalize-keymaps (&optional state)
+  "Create a buffer-local value for `evil-mode-map-alist'.
+This is a keymap alist, determined by the current state
+\(or by STATE if specified)."
+  (let ((state (or state evil-state))
+        (excluded '(nil t))
+        map mode temp)
+    ;; initialize buffer-local keymaps as necessary
+    (evil-initialize-local-keymaps)
+    ;; deactivate keymaps of previous state
+    (dolist (entry evil-mode-map-alist)
+      (setq mode (car-safe entry)
+            map (cdr-safe entry))
+      ;; don't deactivate overriding keymaps;
+      ;; they are toggled by their associated mode
+      (if (or (memq mode excluded)
+              (evil-intercept-keymap-p map)
+              (evil-overriding-keymap-p map)
+              (evil-auxiliary-keymap-p map)
+              (evil-minor-mode-keymap-p map))
+          (push mode excluded)
+        (when (and (fboundp mode) (symbol-value mode))
+          (funcall mode -1))
+        (set mode nil)))
+    (setq evil-mode-map-alist nil)
+    ;; activate keymaps of current state
+    (when state
+      (setq temp (evil-state-keymaps state))
+      (dolist (entry temp)
+        (setq mode (car entry)
+              map (cdr entry))
+        (unless (or (and (boundp mode) (symbol-value mode))
+                    ;; the minor-mode keymaps include modes that are not
+                    ;; necessarily active
+                    (evil-minor-mode-keymap-p map))
+          (when (fboundp mode)
+            (funcall mode 1))
+          (set mode t))
+        ;; refresh the keymap in case it has changed
+        ;; (e.g., `evil-operator-shortcut-map' is
+        ;; reset on toggling)
+        (if (or (memq mode excluded)
+                (evil-intercept-keymap-p map)
+                (evil-overriding-keymap-p map)
+                (evil-auxiliary-keymap-p map)
+                (evil-minor-mode-keymap-p map))
+            (push mode excluded)
+          (setcdr entry (or (evil-keymap-for-mode mode) map))))
+      ;; update `evil-mode-map-alist'
+      (setq evil-mode-map-alist temp))))
+
+(defun evil-mode-for-keymap (keymap &optional default)
+  "Return the minor mode associated with KEYMAP.
+Returns DEFAULT if no mode is found.
+See also `evil-keymap-for-mode'."
+  (let ((map (if (keymapp keymap) keymap (symbol-value keymap)))
+        (var (when (symbolp keymap) keymap)))
+    ;; Check Evil variables first for speed purposes.
+    ;; If all else fails, check `minor-mode-map-alist'.
+    (or (when var
+          (or (car (rassq var evil-global-keymaps-alist))
+              (car (rassq var evil-local-keymaps-alist))))
+        (car (rassq map (mapcar #'(lambda (e)
+                                    ;; from (MODE-VAR . MAP-VAR)
+                                    ;; to (MODE-VAR . MAP)
+                                    (cons (car-safe e)
+                                          (symbol-value (cdr-safe e))))
+                                (append evil-global-keymaps-alist
+                                        evil-local-keymaps-alist))))
+        (car (rassq map minor-mode-map-alist))
+        default)))
+
+(defun evil-keymap-for-mode (mode &optional variable)
+  "Return the keymap associated with MODE.
+Return the keymap variable if VARIABLE is non-nil.
+See also `evil-mode-for-keymap'."
+  (let* ((var (or (cdr (assq mode evil-global-keymaps-alist))
+                  (cdr (assq mode evil-local-keymaps-alist))))
+         (map (or (symbol-value var)
+                  (cdr (assq mode minor-mode-map-alist)))))
+    (if variable var map)))
+
+(defun evil-state-auxiliary-keymaps (state)
+  "Return a keymap alist of auxiliary keymaps for STATE."
+  (let ((state (or state evil-state))
+        aux result)
+    (dolist (map (current-active-maps) result)
+      (when (setq aux (evil-get-auxiliary-keymap map state))
+        (push (cons (evil-mode-for-keymap map t) aux) result)))
+    (nreverse result)))
+
+(defun evil-state-minor-mode-keymaps (state)
+  "Return a keymap alist of minor-mode keymaps for STATE."
+  (let* ((state (or state evil-state))
+         (state-entry (assq state evil-minor-mode-keymaps-alist)))
+    (when state-entry
+      (cdr state-entry))))
+
+(defun evil-state-overriding-keymaps (&optional state)
+  "Return a keymap alist of overriding keymaps for STATE."
+  (let* ((state (or state evil-state))
+         result)
+    (dolist (map (current-active-maps))
+      (when (setq map (evil-overriding-keymap-p map state))
+        (push (cons (evil-mode-for-keymap map t) map) result)))
+    (nreverse result)))
+
+(defun evil-state-intercept-keymaps (&optional state)
+  "Return a keymap alist of intercept keymaps for STATE."
+  (let* ((state (or state evil-state))
+         result)
+    (dolist (map (current-active-maps))
+      (when (setq map (or (evil-intercept-keymap-p map state)
+                          (evil-intercept-keymap-p
+                           (evil-get-auxiliary-keymap map state) state)))
+        (push (cons (evil-mode-for-keymap map t) map) result)))
+    (setq result (nreverse result))
+    result))
+
+(defun evil-set-auxiliary-keymap (map state &optional aux)
+  "Set the auxiliary keymap for MAP in STATE to AUX.
+If AUX is nil, create a new auxiliary keymap."
+  (unless (keymapp aux)
+    (setq aux (make-sparse-keymap)))
+  (unless (evil-auxiliary-keymap-p aux)
+    (evil-set-keymap-prompt
+     aux (format "Auxiliary keymap for %s"
+                 (or (evil-state-property state :name)
+                     (format "%s state" state)))))
+  (define-key map
+    (vconcat (list (intern (format "%s-state" state)))) aux)
+  aux)
+(put 'evil-set-auxiliary-keymap 'lisp-indent-function 'defun)
+
+(defun evil-get-auxiliary-keymap (map state &optional create ignore-parent)
+  "Get the auxiliary keymap for MAP in STATE.
+If CREATE is non-nil, create an auxiliary keymap
+if MAP does not have one. If CREATE and
+IGNORE-PARENT are non-nil then a new auxiliary
+keymap is created even if the parent of MAP has
+one already."
+  (when state
+    (let* ((key (vconcat (list (intern (format "%s-state" state)))))
+           (parent-aux (when (and ignore-parent
+                                  (keymap-parent map)
+                                  state)
+                         (lookup-key (keymap-parent map) key)))
+           (aux (if state (lookup-key map key) map)))
+      (cond
+       ((and ignore-parent
+             (equal parent-aux aux)
+             create)
+        (evil-set-auxiliary-keymap map state))
+       ((evil-auxiliary-keymap-p aux)
+        aux)
+       (create
+        (evil-set-auxiliary-keymap map state))))))
+
+(defun evil-get-minor-mode-keymap (state mode)
+  "Get the auxiliary keymap for MODE in STATE, creating one if it
+does not already exist."
+  (let ((state-entry (assq state evil-minor-mode-keymaps-alist)))
+    (if (and state-entry
+             (assq mode state-entry))
+        (cdr (assq mode state-entry))
+      (let ((map (make-sparse-keymap)))
+        (evil-set-keymap-prompt
+         map (format "Minor-mode keymap for %s in %s"
+                     (symbol-name mode)
+                     (or (evil-state-property state :name)
+                         (format "%s state" state))))
+        (if state-entry
+            (setcdr state-entry
+                    (append (list (cons mode map)) (cdr state-entry)))
+          (push (cons state (list (cons mode map)))
+                evil-minor-mode-keymaps-alist))
+        map))))
+
+(defun evil-auxiliary-keymap-p (map)
+  "Whether MAP is an auxiliary keymap."
+  (and (keymapp map)
+       (string-match-p "Auxiliary keymap"
+                       (or (keymap-prompt map) "")) t))
+
+(defun evil-minor-mode-keymap-p (map)
+  "Whether MAP is a minor-mode keymap."
+  (and (keymapp map)
+       (string-match-p "Minor-mode keymap"
+                       (or (keymap-prompt map) "")) t))
+
+(defun evil-intercept-keymap-p (map &optional state)
+  "Whether MAP is an intercept keymap for STATE.
+If STATE is nil, it means any state."
+  (let ((entry (and (keymapp map)
+                    (lookup-key map [intercept-state]))))
+    (cond
+     ((null entry)
+      nil)
+     ((null state)
+      map)
+     ((eq entry state)
+      map)
+     ((eq entry 'all)
+      map))))
+
+(defun evil-overriding-keymap-p (map &optional state)
+  "Whether MAP is an overriding keymap for STATE.
+If STATE is nil, it means any state."
+  (let ((entry (and (keymapp map)
+                    (lookup-key map [override-state]))))
+    (cond
+     ((null entry)
+      nil)
+     ((keymapp entry)
+      (evil-overriding-keymap-p entry state))
+     ((null state)
+      map)
+     ((eq entry state)
+      map)
+     ((eq entry 'all)
+      map))))
+
+(defun evil-intercept-keymap-state (map)
+  "Return the state for the intercept keymap MAP.
+A return value of t means all states."
+  (let ((state (lookup-key map [intercept-state] map)))
+    (cond
+     ((keymapp state)
+      (evil-intercept-keymap-state state))
+     ((eq state 'all)
+      t)
+     (t
+      state))))
+
+(defun evil-overriding-keymap-state (map)
+  "Return the state for the overriding keymap MAP.
+A return value of t means all states."
+  (let ((state (lookup-key map [override-state] map)))
+    (cond
+     ((keymapp state)
+      (evil-overriding-keymap-state state))
+     ((eq state 'all)
+      t)
+     (t
+      state))))
+
+(defmacro evil-define-key (state keymap key def &rest bindings)
+  "Create a STATE binding from KEY to DEF for KEYMAP.
+STATE is one of normal, insert, visual, replace, operator,
+motion, emacs, or a list of one or more of these. Omitting a
+state by using nil corresponds to a standard Emacs binding using
+`define-key'. The remaining arguments are like those of
+`define-key'. For example:
+
+    (evil-define-key 'normal foo-map \"a\" 'bar)
+
+This creates a binding from \"a\" to bar in Normal state, which
+is active whenever foo-map is active. Using nil for the state,
+the following lead to identical bindings:
+
+    (evil-define-key nil foo-map \"a\" 'bar)
+
+    (define-key foo-map \"a\" 'bar)
+
+It is possible to specify multiple states and/or bindings at
+once:
+
+    (evil-define-key '(normal visual) foo-map
+      \"a\" 'bar
+      \"b\" 'foo)
+
+If foo-map has not been initialized yet, this macro adds an entry
+to `after-load-functions', delaying execution as necessary.
+
+KEYMAP may also be a quoted symbol. If the symbol is global, the
+global evil keymap corresponding to the state(s) is used, meaning
+the following lead to identical bindings:
+
+    (evil-define-key 'normal 'global \"a\" 'bar)
+
+    (evil-global-set-key 'normal \"a\" 'bar)
+
+The symbol local may also be used, which corresponds to using
+`evil-local-set-key'. If a quoted symbol is used that is not
+global or local, it is assumed to be the name of a minor mode, in
+which case `evil-define-minor-mode-key' is used."
+  (declare (indent defun))
+  (cond ((member keymap '('global 'local))
+         `(evil-define-key* ,state ,keymap ,key ,def ,@bindings))
+        ((and (consp keymap) (eq (car keymap) 'quote))
+         `(evil-define-minor-mode-key ,state ,keymap ,key ,def ,@bindings))
+        (t
+         `(evil-delay ',(if (symbolp keymap)
+                            `(and (boundp ',keymap) (keymapp ,keymap))
+                          `(keymapp ,keymap))
+              '(condition-case-unless-debug err
+                   (evil-define-key* ,state ,keymap ,key ,def ,@bindings)
+                 (error
+                  (message "error in evil-define-key: %s"
+                           (error-message-string err))))
+            'after-load-functions t nil
+            (format "evil-define-key-in-%s"
+                    ',(if (symbolp keymap) keymap 'keymap))))))
+(defalias 'evil-declare-key 'evil-define-key)
+
+(defun evil-define-key* (state keymap key def &rest bindings)
+  "Create a STATE binding from KEY to DEF for KEYMAP.
+STATE is one of normal, insert, visual, replace, operator,
+motion, emacs, or a list of one or more of these. Omitting a
+state by using nil corresponds to a standard Emacs binding using
+`define-key' The remaining arguments are like those of
+`define-key'. For example:
+
+    (evil-define-key* 'normal foo-map \"a\" 'bar)
+
+This creates a binding from \"a\" to bar in Normal state, which
+is active whenever foo-map is active. Using nil for the state,
+the following are equivalent:
+
+    (evil-define-key* nil foo-map \"a\" 'bar)
+
+    (define-key foo-map \"a\" 'bar)
+
+ It is possible to specify multiple states and/or bindings at
+ once:
+
+    (evil-define-key* '(normal visual) foo-map
+      \"a\" 'bar
+      \"b\" 'foo)
+
+KEYMAP may also be a quoted symbol. If the symbol is global, the
+global evil keymap corresponding to the state(s) is used, meaning
+the following are equivalent:
+
+    (evil-define-key* 'normal 'global \"a\" 'bar)
+
+    (evil-global-set-key 'normal \"a\" 'bar)
+
+The symbol local may also be used, which corresponds to using
+`evil-local-set-key'.
+
+The use is nearly identical to `evil-define-key' with the
+exception that this is a function and not a macro (and so will
+not be expanded when compiled which can have unintended
+consequences). `evil-define-key*' also does not defer any
+bindings like `evil-define-key' does using `evil-delay'. This
+allows errors in the bindings to be caught immediately, and makes
+its behavior more predictable."
+  (let ((maps
+         (if state
+             (mapcar
+              (lambda (st)
+                (cond ((eq keymap 'global)
+                       (evil-state-property st :keymap t))
+                      ((eq keymap 'local)
+                       (evil-state-property st :local-keymap t))
+                      (t
+                       (evil-get-auxiliary-keymap keymap st t t))))
+              (if (listp state) state (list state)))
+           (list
+            (cond ((eq keymap 'global)
+                   global-map)
+                  ((eq keymap 'local)
+                   ;; see `local-set-key'
+                   (or (current-local-map)
+                       (let ((map (make-sparse-keymap)))
+                         (use-local-map map)
+                         map)))
+                  (t
+                   keymap))))))
+    (while key
+      (dolist (map maps)
+        (define-key map key def))
+      (setq key (pop bindings)
+            def (pop bindings)))
+    ;; ensure the prompt string comes first
+    (dolist (map maps)
+      (evil-set-keymap-prompt map (keymap-prompt map)))))
+
+(defun evil-define-minor-mode-key (state mode key def &rest bindings)
+  "Similar to `evil-define-key' but the bindings are associated
+with the minor-mode symbol MODE instead of a particular map.
+Associating bindings with a mode symbol instead of a map allows
+evil to use Emacs' built-in mechanisms to enable the bindings
+automatically when MODE is active without relying on calling
+`evil-normalize-keymaps'. Another less significant difference is
+that the bindings can be created immediately, because this
+function only uses the symbol MODE and does not rely on its
+value.
+
+See `evil-define-key' for the usage of STATE, KEY, DEF and
+BINDINGS."
+  (declare (indent defun))
+  (let ((maps (mapcar
+               (lambda (st)
+                 (evil-get-minor-mode-keymap st mode))
+               (if (listp state) state (list state)))))
+    (while key
+      (dolist (map maps)
+        (define-key map key def))
+      (setq key (pop bindings)
+            def (pop bindings)))))
+
+(defmacro evil-add-hjkl-bindings (keymap &optional state &rest bindings)
+  "Add \"h\", \"j\", \"k\", \"l\" bindings to KEYMAP in STATE.
+Add additional BINDINGS if specified."
+  (declare (indent defun))
+  `(evil-define-key ,state ,keymap
+     "h" (lookup-key evil-motion-state-map "h")
+     "j" (lookup-key evil-motion-state-map "j")
+     "k" (lookup-key evil-motion-state-map "k")
+     "l" (lookup-key evil-motion-state-map "l")
+     ":" (lookup-key evil-motion-state-map ":")
+     ,@bindings))
+
+;; may be useful for programmatic purposes
+(defun evil-global-set-key (state key def)
+  "Bind KEY to DEF in STATE."
+  (define-key (evil-state-property state :keymap t) key def))
+
+(defun evil-local-set-key (state key def)
+  "Bind KEY to DEF in STATE in the current buffer."
+  (define-key (evil-state-property state :local-keymap t) key def))
+
+;; Advise these functions as they may activate an overriding keymap or
+;; a keymap with state bindings; if so, refresh `evil-mode-map-alist'.
+(defadvice use-global-map (after evil activate)
+  "Refresh Evil keymaps."
+  (evil-normalize-keymaps))
+
+(defadvice use-local-map (after evil activate)
+  "Refresh Evil keymaps."
+  (evil-normalize-keymaps))
+
+(defmacro evil-define-state (state doc &rest body)
+  "Define an Evil state STATE.
+DOC is a general description and shows up in all docstrings;
+the first line of the string should be the full name of the state.
+Then follows one or more optional keywords:
+
+:tag STRING             Mode line indicator.
+:message STRING         Echo area message when changing to STATE.
+:cursor SPEC            Cursor to use in STATE.
+:entry-hook LIST        Hooks run when changing to STATE.
+:exit-hook LIST         Hooks run when changing from STATE.
+:enable LIST            List of other states and modes enabled by STATE.
+:suppress-keymap FLAG   If FLAG is non-nil, makes `evil-suppress-map'
+                        the parent of the global map of STATE,
+                        effectively disabling bindings to
+                        `self-insert-command'.
+
+Following the keywords is optional code to be executed each time
+the state is enabled or disabled. For example:
+
+    (evil-define-state test
+      \"Test state.\"
+      :tag \"<T> \"
+      (setq test-var t))
+
+The global keymap of this state will be `evil-test-state-map',
+the local keymap will be `evil-test-state-local-map', and so on.
+
+\(fn STATE DOC [[KEY VAL]...] BODY...)"
+  (declare (indent defun)
+           (debug (&define name
+                           [&optional stringp]
+                           [&rest [keywordp sexp]]
+                           def-body)))
+  (let* ((name (and (string-match "^\\(.+\\)\\(\\(?:.\\|\n\\)*\\)" doc)
+                    (match-string 1 doc)))
+         (doc (match-string 2 doc))
+         (name (and (string-match "^\\(.+?\\)\\.?$" name)
+                    (match-string 1 name)))
+         (doc (if (or (null doc) (string= doc "")) ""
+                (format "\n%s" doc)))
+         (toggle (intern (format "evil-%s-state" state)))
+         (mode (intern (format "%s-minor-mode" toggle)))
+         (keymap (intern (format "%s-map" toggle)))
+         (local (intern (format "%s-local-minor-mode" toggle)))
+         (local-keymap (intern (format "%s-local-map" toggle)))
+         (tag (intern (format "%s-tag" toggle)))
+         (message (intern (format "%s-message" toggle)))
+         (cursor (intern (format "%s-cursor" toggle)))
+         (entry-hook (intern (format "%s-entry-hook" toggle)))
+         (exit-hook (intern (format "%s-exit-hook" toggle)))
+         (modes (intern (format "%s-modes" toggle)))
+         (predicate (intern (format "%s-p" toggle)))
+         arg cursor-value enable entry-hook-value exit-hook-value
+         input-method key message-value suppress-keymap tag-value)
+    ;; collect keywords
+    (while (keywordp (car-safe body))
+      (setq key (pop body)
+            arg (pop body))
+      (cond
+       ((eq key :tag)
+        (setq tag-value arg))
+       ((eq key :message)
+        (setq message-value arg))
+       ((eq key :cursor)
+        (setq cursor-value arg))
+       ((eq key :entry-hook)
+        (setq entry-hook-value arg)
+        (unless (listp entry-hook-value)
+          (setq entry-hook-value (list entry-hook-value))))
+       ((eq key :exit-hook)
+        (setq exit-hook-value arg)
+        (unless (listp exit-hook-value)
+          (setq exit-hook-value (list entry-hook-value))))
+       ((eq key :enable)
+        (setq enable arg))
+       ((eq key :input-method)
+        (setq input-method arg))
+       ((eq key :suppress-keymap)
+        (setq suppress-keymap arg))))
+
+    ;; macro expansion
+    `(progn
+       ;; Save the state's properties in `evil-state-properties' for
+       ;; runtime lookup. Among other things, this information is used
+       ;; to determine what keymaps should be activated by the state
+       ;; (and, when processing :enable, what keymaps are activated by
+       ;; other states). We cannot know this at compile time because
+       ;; it depends on the current buffer and its active keymaps
+       ;; (to which we may have assigned state bindings), as well as
+       ;; states whose definitions may not have been processed yet.
+       (evil-put-property
+        'evil-state-properties ',state
+        :name ',name
+        :toggle ',toggle
+        :mode (defvar ,mode nil
+                ,(format "Non-nil if %s is enabled.
+Use the command `%s' to change this variable." name toggle))
+        :keymap (defvar ,keymap (make-sparse-keymap)
+                  ,(format "Keymap for %s." name))
+        :local (defvar ,local nil
+                 ,(format "Non-nil if %s is enabled.
+Use the command `%s' to change this variable." name toggle))
+        :local-keymap (defvar ,local-keymap nil
+                        ,(format "Buffer-local keymap for %s." name))
+        :tag (defvar ,tag ,tag-value
+               ,(format "Mode line tag for %s." name))
+        :message (defvar ,message ,message-value
+                   ,(format "Echo area message for %s." name))
+        :cursor (defvar ,cursor ',cursor-value
+                  ,(format "Cursor for %s.
+May be a cursor type as per `cursor-type', a color string as passed
+to `set-cursor-color', a zero-argument function for changing the
+cursor, or a list of the above." name))
+        :entry-hook (defvar ,entry-hook nil
+                      ,(format "Hooks to run when entering %s." name))
+        :exit-hook (defvar ,exit-hook nil
+                     ,(format "Hooks to run when exiting %s." name))
+        :modes (defvar ,modes nil
+                 ,(format "Modes that should come up in %s." name))
+        :input-method ',input-method
+        :predicate ',predicate
+        :enable ',enable)
+
+       ,@(when suppress-keymap
+           `((set-keymap-parent ,keymap evil-suppress-map)))
+
+       (dolist (func ',entry-hook-value)
+         (add-hook ',entry-hook func))
+
+       (dolist (func ',exit-hook-value)
+         (add-hook ',exit-hook func))
+
+       (defun ,predicate (&optional state)
+         ,(format "Whether the current state is %s.
+\(That is, whether `evil-state' is `%s'.)" name state)
+         (and evil-local-mode
+              (eq (or state evil-state) ',state)))
+
+       ;; define state function
+       (defun ,toggle (&optional arg)
+         ,(format "Enable %s. Disable with negative ARG.
+If ARG is nil, don't display a message in the echo area.%s" name doc)
+         (interactive)
+         (cond
+          ((and (numberp arg) (< arg 1))
+           (setq evil-previous-state evil-state
+                 evil-state nil)
+           (let ((evil-state ',state))
+             (run-hooks ',exit-hook)
+             (setq evil-state nil)
+             (evil-normalize-keymaps)
+             ,@body))
+          (t
+           (unless evil-local-mode
+             (evil-local-mode 1))
+           (let ((evil-next-state ',state)
+                 input-method-activate-hook
+                 input-method-deactivate-hook)
+             (evil-change-state nil)
+             (setq evil-state ',state)
+             (evil-add-to-alist 'evil-previous-state-alist
+                                ',state evil-previous-state)
+             (let ((evil-state ',state))
+               (evil-normalize-keymaps)
+               (if ',input-method
+                   (activate-input-method evil-input-method)
+                 ;; BUG #475: Deactivate the current input method only
+                 ;; if there is a function to deactivate it, otherwise
+                 ;; an error would be raised. This strange situation
+                 ;; should not arise in general and there should
+                 ;; probably be a better way to handle this situation.
+                 (if deactivate-current-input-method-function
+                     (deactivate-input-method)))
+               (unless evil-no-display
+                 (evil-refresh-cursor ',state)
+                 (evil-refresh-mode-line ',state)
+                 (when (called-interactively-p 'any)
+                   (redisplay)))
+               ,@body
+               (run-hooks ',entry-hook)
+               (when (and evil-echo-state
+                          arg (not evil-no-display) ,message)
+                 (if (functionp ,message)
+                     (funcall ,message)
+                   (evil-echo "%s" ,message))))))))
+
+       (evil-set-command-property ',toggle :keep-visual t)
+       (evil-set-command-property ',toggle :suppress-operator t)
+
+       (evil-define-keymap ,keymap nil
+         :mode ,mode
+         :func nil)
+
+       (evil-define-keymap ,local-keymap nil
+         :mode ,local
+         :local t
+         :func nil)
+
+       ',state)))
+
+(provide 'evil-core)
+
+;;; evil-core.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-core.elc b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-core.elc
new file mode 100644
index 0000000000..ca21f196c0
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-core.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-development.el b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-development.el
new file mode 100644
index 0000000000..1e8a8fe9fb
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-development.el
@@ -0,0 +1,50 @@
+;;; evil-development.el --- Useful features for Evil developers
+
+;; Author: Justin Burkett <justin at burkett dot cc>
+
+;; Version: 1.2.13
+
+;;
+;; This file is NOT part of GNU Emacs.
+
+;;; License:
+
+;; This file is part of Evil.
+;;
+;; Evil 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.
+;;
+;; Evil 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 Evil.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Code:
+
+;;; Teach imenu about evil macros
+
+(with-eval-after-load 'lisp-mode
+  (when (boundp 'lisp-imenu-generic-expression)
+    (dolist (macro '("interactive-code"
+                     "type"
+                     "text-object"
+                     "motion"
+                     "command"
+                     "operator"))
+      (let ((macro-name (format "evil-%s" macro)))
+        (unless (assoc macro-name lisp-imenu-generic-expression)
+          (push (list
+                 macro-name
+                 (format "^\\s-*(evil-define-%s\\s-+\\(\\(?:\\sw\\|\\s_\\|\\\\.\\)+\\)"
+                         macro)
+                 1)
+                lisp-imenu-generic-expression))))))
+
+(provide 'evil-development)
+
+;;; evil-development.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-development.elc b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-development.elc
new file mode 100644
index 0000000000..f056bfeb5f
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-development.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-digraphs.el b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-digraphs.el
new file mode 100644
index 0000000000..2046f746b4
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-digraphs.el
@@ -0,0 +1,1729 @@
+;;; evil-digraphs.el --- Digraphs
+
+;; Author: Vegard Øye <vegard_oye at hotmail.com>
+;; Maintainer: Vegard Øye <vegard_oye at hotmail.com>
+
+;; Version: 1.2.13
+
+;;
+;; This file is NOT part of GNU Emacs.
+
+;;; License:
+
+;; This file is part of Evil.
+;;
+;; Evil 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.
+;;
+;; Evil 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 Evil.  If not, see <http://www.gnu.org/licenses/>.
+
+(require 'evil-vars)
+
+;;; Code:
+
+(defgroup evil-digraphs nil
+  "Digraph support based on RFC 1345."
+  :group 'evil
+  :prefix "evil-digraph-")
+
+(defcustom evil-digraphs-table-user nil
+  "List of user-defined digraphs.
+Entries have the form ((?CHAR1 ?CHAR2) . ?DIGRAPH).  That is,
+a cons cell of the digraph and its character replacement,
+where the digraph is a list of two characters.
+See also `evil-digraphs-table'."
+  :type '(alist :key-type (list character character)
+                :value-type character)
+  :require 'evil-digraphs
+  :group 'evil-digraphs)
+
+(defconst evil-digraphs-table
+  '(((?N ?U) . ?\x00)
+    ((?S ?H) . ?\x01)
+    ((?S ?X) . ?\x02)
+    ((?E ?X) . ?\x03)
+    ((?E ?T) . ?\x04)
+    ((?E ?Q) . ?\x05)
+    ((?A ?K) . ?\x06)
+    ((?B ?L) . ?\x07)
+    ((?B ?S) . ?\x08)
+    ((?H ?T) . ?\x09)
+    ((?L ?F) . ?\x0a)
+    ((?V ?T) . ?\x0b)
+    ((?F ?F) . ?\x0c)
+    ((?C ?R) . ?\x0d)
+    ((?S ?O) . ?\x0e)
+    ((?S ?I) . ?\x0f)
+    ((?D ?L) . ?\x10)
+    ((?D ?1) . ?\x11)
+    ((?D ?2) . ?\x12)
+    ((?D ?3) . ?\x13)
+    ((?D ?4) . ?\x14)
+    ((?N ?K) . ?\x15)
+    ((?S ?Y) . ?\x16)
+    ((?E ?B) . ?\x17)
+    ((?C ?N) . ?\x18)
+    ((?E ?M) . ?\x19)
+    ((?S ?B) . ?\x1a)
+    ((?E ?C) . ?\x1b)
+    ((?F ?S) . ?\x1c)
+    ((?G ?S) . ?\x1d)
+    ((?R ?S) . ?\x1e)
+    ((?U ?S) . ?\x1f)
+    ((?S ?P) . ?\x20)
+    ((?N ?b) . ?\x23)
+    ((?D ?O) . ?\x24)
+    ((?A ?t) . ?\x40)
+    ((?< ?\() . ?\x5b)
+    ((?/ ?/) . ?\x5c)
+    ((?\) ?>) . ?\x5d)
+    ((?' ?>) . ?\x5e)
+    ((?' ?!) . ?\x60)
+    ((?\( ?!) . ?\x7b)
+    ((?! ?!) . ?\x7c)
+    ((?! ?\)) . ?\x7d)
+    ((?' ??) . ?\x7e)
+    ((?D ?T) . ?\x7f)
+    ((?P ?A) . ?\x80)
+    ((?H ?O) . ?\x81)
+    ((?B ?H) . ?\x82)
+    ((?N ?H) . ?\x83)
+    ((?I ?N) . ?\x84)
+    ((?N ?L) . ?\x85)
+    ((?S ?A) . ?\x86)
+    ((?E ?S) . ?\x87)
+    ((?H ?S) . ?\x88)
+    ((?H ?J) . ?\x89)
+    ((?V ?S) . ?\x8a)
+    ((?P ?D) . ?\x8b)
+    ((?P ?U) . ?\x8c)
+    ((?R ?I) . ?\x8d)
+    ((?S ?2) . ?\x8e)
+    ((?S ?3) . ?\x8f)
+    ((?D ?C) . ?\x90)
+    ((?P ?1) . ?\x91)
+    ((?P ?2) . ?\x92)
+    ((?T ?S) . ?\x93)
+    ((?C ?C) . ?\x94)
+    ((?M ?W) . ?\x95)
+    ((?S ?G) . ?\x96)
+    ((?E ?G) . ?\x97)
+    ((?S ?S) . ?\x98)
+    ((?G ?C) . ?\x99)
+    ((?S ?C) . ?\x9a)
+    ((?C ?I) . ?\x9b)
+    ((?S ?T) . ?\x9c)
+    ((?O ?C) . ?\x9d)
+    ((?P ?M) . ?\x9e)
+    ((?A ?C) . ?\x9f)
+    ((?N ?S) . ?\xa0)
+    ((?! ?I) . ?\xa1)
+    ((?C ?t) . ?\xa2)
+    ((?P ?d) . ?\xa3)
+    ((?C ?u) . ?\xa4)
+    ((?Y ?e) . ?\xa5)
+    ((?B ?B) . ?\xa6)
+    ((?S ?E) . ?\xa7)
+    ((?' ?:) . ?\xa8)
+    ((?C ?o) . ?\xa9)
+    ((?- ?a) . ?\xaa)
+    ((?< ?<) . ?\xab)
+    ((?N ?O) . ?\xac)
+    ((?- ?-) . ?\xad)
+    ((?R ?g) . ?\xae)
+    ((?' ?m) . ?\xaf)
+    ((?D ?G) . ?\xb0)
+    ((?+ ?-) . ?\xb1)
+    ((?2 ?S) . ?\xb2)
+    ((?3 ?S) . ?\xb3)
+    ((?' ?') . ?\xb4)
+    ((?M ?y) . ?\xb5)
+    ((?P ?I) . ?\xb6)
+    ((?. ?M) . ?\xb7)
+    ((?' ?,) . ?\xb8)
+    ((?1 ?S) . ?\xb9)
+    ((?- ?o) . ?\xba)
+    ((?> ?>) . ?\xbb)
+    ((?1 ?4) . ?\xbc)
+    ((?1 ?2) . ?\xbd)
+    ((?3 ?4) . ?\xbe)
+    ((?? ?I) . ?\xbf)
+    ((?A ?!) . ?\xc0)
+    ((?A ?') . ?\xc1)
+    ((?A ?>) . ?\xc2)
+    ((?A ??) . ?\xc3)
+    ((?A ?:) . ?\xc4)
+    ((?A ?A) . ?\xc5)
+    ((?A ?E) . ?\xc6)
+    ((?C ?,) . ?\xc7)
+    ((?E ?!) . ?\xc8)
+    ((?E ?') . ?\xc9)
+    ((?E ?>) . ?\xca)
+    ((?E ?:) . ?\xcb)
+    ((?I ?!) . ?\xcc)
+    ((?I ?') . ?\xcd)
+    ((?I ?>) . ?\xce)
+    ((?I ?:) . ?\xcf)
+    ((?D ?-) . ?\xd0)
+    ((?N ??) . ?\xd1)
+    ((?O ?!) . ?\xd2)
+    ((?O ?') . ?\xd3)
+    ((?O ?>) . ?\xd4)
+    ((?O ??) . ?\xd5)
+    ((?O ?:) . ?\xd6)
+    ((?* ?X) . ?\xd7)
+    ((?O ?/) . ?\xd8)
+    ((?U ?!) . ?\xd9)
+    ((?U ?') . ?\xda)
+    ((?U ?>) . ?\xdb)
+    ((?U ?:) . ?\xdc)
+    ((?Y ?') . ?\xdd)
+    ((?T ?H) . ?\xde)
+    ((?s ?s) . ?\xdf)
+    ((?a ?!) . ?\xe0)
+    ((?a ?') . ?\xe1)
+    ((?a ?>) . ?\xe2)
+    ((?a ??) . ?\xe3)
+    ((?a ?:) . ?\xe4)
+    ((?a ?a) . ?\xe5)
+    ((?a ?e) . ?\xe6)
+    ((?c ?,) . ?\xe7)
+    ((?e ?!) . ?\xe8)
+    ((?e ?') . ?\xe9)
+    ((?e ?>) . ?\xea)
+    ((?e ?:) . ?\xeb)
+    ((?i ?!) . ?\xec)
+    ((?i ?') . ?\xed)
+    ((?i ?>) . ?\xee)
+    ((?i ?:) . ?\xef)
+    ((?d ?-) . ?\xf0)
+    ((?n ??) . ?\xf1)
+    ((?o ?!) . ?\xf2)
+    ((?o ?') . ?\xf3)
+    ((?o ?>) . ?\xf4)
+    ((?o ??) . ?\xf5)
+    ((?o ?:) . ?\xf6)
+    ((?- ?:) . ?\xf7)
+    ((?o ?/) . ?\xf8)
+    ((?u ?!) . ?\xf9)
+    ((?u ?') . ?\xfa)
+    ((?u ?>) . ?\xfb)
+    ((?u ?:) . ?\xfc)
+    ((?y ?') . ?\xfd)
+    ((?t ?h) . ?\xfe)
+    ((?y ?:) . ?\xff)
+    ((?A ?-) . ?\x0100)
+    ((?a ?-) . ?\x0101)
+    ((?A ?\() . ?\x0102)
+    ((?a ?\() . ?\x0103)
+    ((?A ?\;) . ?\x0104)
+    ((?a ?\;) . ?\x0105)
+    ((?C ?') . ?\x0106)
+    ((?c ?') . ?\x0107)
+    ((?C ?>) . ?\x0108)
+    ((?c ?>) . ?\x0109)
+    ((?C ?.) . ?\x010a)
+    ((?c ?.) . ?\x010b)
+    ((?C ?<) . ?\x010c)
+    ((?c ?<) . ?\x010d)
+    ((?D ?<) . ?\x010e)
+    ((?d ?<) . ?\x010f)
+    ((?D ?/) . ?\x0110)
+    ((?d ?/) . ?\x0111)
+    ((?E ?-) . ?\x0112)
+    ((?e ?-) . ?\x0113)
+    ((?E ?\() . ?\x0114)
+    ((?e ?\() . ?\x0115)
+    ((?E ?.) . ?\x0116)
+    ((?e ?.) . ?\x0117)
+    ((?E ?\;) . ?\x0118)
+    ((?e ?\;) . ?\x0119)
+    ((?E ?<) . ?\x011a)
+    ((?e ?<) . ?\x011b)
+    ((?G ?>) . ?\x011c)
+    ((?g ?>) . ?\x011d)
+    ((?G ?\() . ?\x011e)
+    ((?g ?\() . ?\x011f)
+    ((?G ?.) . ?\x0120)
+    ((?g ?.) . ?\x0121)
+    ((?G ?,) . ?\x0122)
+    ((?g ?,) . ?\x0123)
+    ((?H ?>) . ?\x0124)
+    ((?h ?>) . ?\x0125)
+    ((?H ?/) . ?\x0126)
+    ((?h ?/) . ?\x0127)
+    ((?I ??) . ?\x0128)
+    ((?i ??) . ?\x0129)
+    ((?I ?-) . ?\x012a)
+    ((?i ?-) . ?\x012b)
+    ((?I ?\() . ?\x012c)
+    ((?i ?\() . ?\x012d)
+    ((?I ?\;) . ?\x012e)
+    ((?i ?\;) . ?\x012f)
+    ((?I ?.) . ?\x0130)
+    ((?i ?.) . ?\x0131)
+    ((?I ?J) . ?\x0132)
+    ((?i ?j) . ?\x0133)
+    ((?J ?>) . ?\x0134)
+    ((?j ?>) . ?\x0135)
+    ((?K ?,) . ?\x0136)
+    ((?k ?,) . ?\x0137)
+    ((?k ?k) . ?\x0138)
+    ((?L ?') . ?\x0139)
+    ((?l ?') . ?\x013a)
+    ((?L ?,) . ?\x013b)
+    ((?l ?,) . ?\x013c)
+    ((?L ?<) . ?\x013d)
+    ((?l ?<) . ?\x013e)
+    ((?L ?.) . ?\x013f)
+    ((?l ?.) . ?\x0140)
+    ((?L ?/) . ?\x0141)
+    ((?l ?/) . ?\x0142)
+    ((?N ?') . ?\x0143)
+    ((?n ?') . ?\x0144)
+    ((?N ?,) . ?\x0145)
+    ((?n ?,) . ?\x0146)
+    ((?N ?<) . ?\x0147)
+    ((?n ?<) . ?\x0148)
+    ((?' ?n) . ?\x0149)
+    ((?N ?G) . ?\x014a)
+    ((?n ?g) . ?\x014b)
+    ((?O ?-) . ?\x014c)
+    ((?o ?-) . ?\x014d)
+    ((?O ?\() . ?\x014e)
+    ((?o ?\() . ?\x014f)
+    ((?O ?\") . ?\x0150)
+    ((?o ?\") . ?\x0151)
+    ((?O ?E) . ?\x0152)
+    ((?o ?e) . ?\x0153)
+    ((?R ?') . ?\x0154)
+    ((?r ?') . ?\x0155)
+    ((?R ?,) . ?\x0156)
+    ((?r ?,) . ?\x0157)
+    ((?R ?<) . ?\x0158)
+    ((?r ?<) . ?\x0159)
+    ((?S ?') . ?\x015a)
+    ((?s ?') . ?\x015b)
+    ((?S ?>) . ?\x015c)
+    ((?s ?>) . ?\x015d)
+    ((?S ?,) . ?\x015e)
+    ((?s ?,) . ?\x015f)
+    ((?S ?<) . ?\x0160)
+    ((?s ?<) . ?\x0161)
+    ((?T ?,) . ?\x0162)
+    ((?t ?,) . ?\x0163)
+    ((?T ?<) . ?\x0164)
+    ((?t ?<) . ?\x0165)
+    ((?T ?/) . ?\x0166)
+    ((?t ?/) . ?\x0167)
+    ((?U ??) . ?\x0168)
+    ((?u ??) . ?\x0169)
+    ((?U ?-) . ?\x016a)
+    ((?u ?-) . ?\x016b)
+    ((?U ?\() . ?\x016c)
+    ((?u ?\() . ?\x016d)
+    ((?U ?0) . ?\x016e)
+    ((?u ?0) . ?\x016f)
+    ((?U ?\") . ?\x0170)
+    ((?u ?\") . ?\x0171)
+    ((?U ?\;) . ?\x0172)
+    ((?u ?\;) . ?\x0173)
+    ((?W ?>) . ?\x0174)
+    ((?w ?>) . ?\x0175)
+    ((?Y ?>) . ?\x0176)
+    ((?y ?>) . ?\x0177)
+    ((?Y ?:) . ?\x0178)
+    ((?Z ?') . ?\x0179)
+    ((?z ?') . ?\x017a)
+    ((?Z ?.) . ?\x017b)
+    ((?z ?.) . ?\x017c)
+    ((?Z ?<) . ?\x017d)
+    ((?z ?<) . ?\x017e)
+    ((?O ?9) . ?\x01a0)
+    ((?o ?9) . ?\x01a1)
+    ((?O ?I) . ?\x01a2)
+    ((?o ?i) . ?\x01a3)
+    ((?y ?r) . ?\x01a6)
+    ((?U ?9) . ?\x01af)
+    ((?u ?9) . ?\x01b0)
+    ((?Z ?/) . ?\x01b5)
+    ((?z ?/) . ?\x01b6)
+    ((?E ?D) . ?\x01b7)
+    ((?A ?<) . ?\x01cd)
+    ((?a ?<) . ?\x01ce)
+    ((?I ?<) . ?\x01cf)
+    ((?i ?<) . ?\x01d0)
+    ((?O ?<) . ?\x01d1)
+    ((?o ?<) . ?\x01d2)
+    ((?U ?<) . ?\x01d3)
+    ((?u ?<) . ?\x01d4)
+    ((?A ?1) . ?\x01de)
+    ((?a ?1) . ?\x01df)
+    ((?A ?7) . ?\x01e0)
+    ((?a ?7) . ?\x01e1)
+    ((?A ?3) . ?\x01e2)
+    ((?a ?3) . ?\x01e3)
+    ((?G ?/) . ?\x01e4)
+    ((?g ?/) . ?\x01e5)
+    ((?G ?<) . ?\x01e6)
+    ((?g ?<) . ?\x01e7)
+    ((?K ?<) . ?\x01e8)
+    ((?k ?<) . ?\x01e9)
+    ((?O ?\;) . ?\x01ea)
+    ((?o ?\;) . ?\x01eb)
+    ((?O ?1) . ?\x01ec)
+    ((?o ?1) . ?\x01ed)
+    ((?E ?Z) . ?\x01ee)
+    ((?e ?z) . ?\x01ef)
+    ((?j ?<) . ?\x01f0)
+    ((?G ?') . ?\x01f4)
+    ((?g ?') . ?\x01f5)
+    ((?\; ?S) . ?\x02bf)
+    ((?' ?<) . ?\x02c7)
+    ((?' ?\() . ?\x02d8)
+    ((?' ?.) . ?\x02d9)
+    ((?' ?0) . ?\x02da)
+    ((?' ?\;) . ?\x02db)
+    ((?' ?\") . ?\x02dd)
+    ((?A ?%) . ?\x0386)
+    ((?E ?%) . ?\x0388)
+    ((?Y ?%) . ?\x0389)
+    ((?I ?%) . ?\x038a)
+    ((?O ?%) . ?\x038c)
+    ((?U ?%) . ?\x038e)
+    ((?W ?%) . ?\x038f)
+    ((?i ?3) . ?\x0390)
+    ((?A ?*) . ?\x0391)
+    ((?B ?*) . ?\x0392)
+    ((?G ?*) . ?\x0393)
+    ((?D ?*) . ?\x0394)
+    ((?E ?*) . ?\x0395)
+    ((?Z ?*) . ?\x0396)
+    ((?Y ?*) . ?\x0397)
+    ((?H ?*) . ?\x0398)
+    ((?I ?*) . ?\x0399)
+    ((?K ?*) . ?\x039a)
+    ((?L ?*) . ?\x039b)
+    ((?M ?*) . ?\x039c)
+    ((?N ?*) . ?\x039d)
+    ((?C ?*) . ?\x039e)
+    ((?O ?*) . ?\x039f)
+    ((?P ?*) . ?\x03a0)
+    ((?R ?*) . ?\x03a1)
+    ((?S ?*) . ?\x03a3)
+    ((?T ?*) . ?\x03a4)
+    ((?U ?*) . ?\x03a5)
+    ((?F ?*) . ?\x03a6)
+    ((?X ?*) . ?\x03a7)
+    ((?Q ?*) . ?\x03a8)
+    ((?W ?*) . ?\x03a9)
+    ((?J ?*) . ?\x03aa)
+    ((?V ?*) . ?\x03ab)
+    ((?a ?%) . ?\x03ac)
+    ((?e ?%) . ?\x03ad)
+    ((?y ?%) . ?\x03ae)
+    ((?i ?%) . ?\x03af)
+    ((?u ?3) . ?\x03b0)
+    ((?a ?*) . ?\x03b1)
+    ((?b ?*) . ?\x03b2)
+    ((?g ?*) . ?\x03b3)
+    ((?d ?*) . ?\x03b4)
+    ((?e ?*) . ?\x03b5)
+    ((?z ?*) . ?\x03b6)
+    ((?y ?*) . ?\x03b7)
+    ((?h ?*) . ?\x03b8)
+    ((?i ?*) . ?\x03b9)
+    ((?k ?*) . ?\x03ba)
+    ((?l ?*) . ?\x03bb)
+    ((?m ?*) . ?\x03bc)
+    ((?n ?*) . ?\x03bd)
+    ((?c ?*) . ?\x03be)
+    ((?o ?*) . ?\x03bf)
+    ((?p ?*) . ?\x03c0)
+    ((?r ?*) . ?\x03c1)
+    ((?* ?s) . ?\x03c2)
+    ((?s ?*) . ?\x03c3)
+    ((?t ?*) . ?\x03c4)
+    ((?u ?*) . ?\x03c5)
+    ((?f ?*) . ?\x03c6)
+    ((?x ?*) . ?\x03c7)
+    ((?q ?*) . ?\x03c8)
+    ((?w ?*) . ?\x03c9)
+    ((?j ?*) . ?\x03ca)
+    ((?v ?*) . ?\x03cb)
+    ((?o ?%) . ?\x03cc)
+    ((?u ?%) . ?\x03cd)
+    ((?w ?%) . ?\x03ce)
+    ((?' ?G) . ?\x03d8)
+    ((?, ?G) . ?\x03d9)
+    ((?T ?3) . ?\x03da)
+    ((?t ?3) . ?\x03db)
+    ((?M ?3) . ?\x03dc)
+    ((?m ?3) . ?\x03dd)
+    ((?K ?3) . ?\x03de)
+    ((?k ?3) . ?\x03df)
+    ((?P ?3) . ?\x03e0)
+    ((?p ?3) . ?\x03e1)
+    ((?' ?%) . ?\x03f4)
+    ((?j ?3) . ?\x03f5)
+    ((?I ?O) . ?\x0401)
+    ((?D ?%) . ?\x0402)
+    ((?G ?%) . ?\x0403)
+    ((?I ?E) . ?\x0404)
+    ((?D ?S) . ?\x0405)
+    ((?I ?I) . ?\x0406)
+    ((?Y ?I) . ?\x0407)
+    ((?J ?%) . ?\x0408)
+    ((?L ?J) . ?\x0409)
+    ((?N ?J) . ?\x040a)
+    ((?T ?s) . ?\x040b)
+    ((?K ?J) . ?\x040c)
+    ((?V ?%) . ?\x040e)
+    ((?D ?Z) . ?\x040f)
+    ((?A ?=) . ?\x0410)
+    ((?B ?=) . ?\x0411)
+    ((?V ?=) . ?\x0412)
+    ((?G ?=) . ?\x0413)
+    ((?D ?=) . ?\x0414)
+    ((?E ?=) . ?\x0415)
+    ((?Z ?%) . ?\x0416)
+    ((?Z ?=) . ?\x0417)
+    ((?I ?=) . ?\x0418)
+    ((?J ?=) . ?\x0419)
+    ((?K ?=) . ?\x041a)
+    ((?L ?=) . ?\x041b)
+    ((?M ?=) . ?\x041c)
+    ((?N ?=) . ?\x041d)
+    ((?O ?=) . ?\x041e)
+    ((?P ?=) . ?\x041f)
+    ((?R ?=) . ?\x0420)
+    ((?S ?=) . ?\x0421)
+    ((?T ?=) . ?\x0422)
+    ((?U ?=) . ?\x0423)
+    ((?F ?=) . ?\x0424)
+    ((?H ?=) . ?\x0425)
+    ((?C ?=) . ?\x0426)
+    ((?C ?%) . ?\x0427)
+    ((?S ?%) . ?\x0428)
+    ((?S ?c) . ?\x0429)
+    ((?= ?\") . ?\x042a)
+    ((?Y ?=) . ?\x042b)
+    ((?% ?\") . ?\x042c)
+    ((?J ?E) . ?\x042d)
+    ((?J ?U) . ?\x042e)
+    ((?J ?A) . ?\x042f)
+    ((?a ?=) . ?\x0430)
+    ((?b ?=) . ?\x0431)
+    ((?v ?=) . ?\x0432)
+    ((?g ?=) . ?\x0433)
+    ((?d ?=) . ?\x0434)
+    ((?e ?=) . ?\x0435)
+    ((?z ?%) . ?\x0436)
+    ((?z ?=) . ?\x0437)
+    ((?i ?=) . ?\x0438)
+    ((?j ?=) . ?\x0439)
+    ((?k ?=) . ?\x043a)
+    ((?l ?=) . ?\x043b)
+    ((?m ?=) . ?\x043c)
+    ((?n ?=) . ?\x043d)
+    ((?o ?=) . ?\x043e)
+    ((?p ?=) . ?\x043f)
+    ((?r ?=) . ?\x0440)
+    ((?s ?=) . ?\x0441)
+    ((?t ?=) . ?\x0442)
+    ((?u ?=) . ?\x0443)
+    ((?f ?=) . ?\x0444)
+    ((?h ?=) . ?\x0445)
+    ((?c ?=) . ?\x0446)
+    ((?c ?%) . ?\x0447)
+    ((?s ?%) . ?\x0448)
+    ((?s ?c) . ?\x0449)
+    ((?= ?') . ?\x044a)
+    ((?y ?=) . ?\x044b)
+    ((?% ?') . ?\x044c)
+    ((?j ?e) . ?\x044d)
+    ((?j ?u) . ?\x044e)
+    ((?j ?a) . ?\x044f)
+    ((?i ?o) . ?\x0451)
+    ((?d ?%) . ?\x0452)
+    ((?g ?%) . ?\x0453)
+    ((?i ?e) . ?\x0454)
+    ((?d ?s) . ?\x0455)
+    ((?i ?i) . ?\x0456)
+    ((?y ?i) . ?\x0457)
+    ((?j ?%) . ?\x0458)
+    ((?l ?j) . ?\x0459)
+    ((?n ?j) . ?\x045a)
+    ((?t ?s) . ?\x045b)
+    ((?k ?j) . ?\x045c)
+    ((?v ?%) . ?\x045e)
+    ((?d ?z) . ?\x045f)
+    ((?Y ?3) . ?\x0462)
+    ((?y ?3) . ?\x0463)
+    ((?O ?3) . ?\x046a)
+    ((?o ?3) . ?\x046b)
+    ((?F ?3) . ?\x0472)
+    ((?f ?3) . ?\x0473)
+    ((?V ?3) . ?\x0474)
+    ((?v ?3) . ?\x0475)
+    ((?C ?3) . ?\x0480)
+    ((?c ?3) . ?\x0481)
+    ((?G ?3) . ?\x0490)
+    ((?g ?3) . ?\x0491)
+    ((?A ?+) . ?\x05d0)
+    ((?B ?+) . ?\x05d1)
+    ((?G ?+) . ?\x05d2)
+    ((?D ?+) . ?\x05d3)
+    ((?H ?+) . ?\x05d4)
+    ((?W ?+) . ?\x05d5)
+    ((?Z ?+) . ?\x05d6)
+    ((?X ?+) . ?\x05d7)
+    ((?T ?j) . ?\x05d8)
+    ((?J ?+) . ?\x05d9)
+    ((?K ?%) . ?\x05da)
+    ((?K ?+) . ?\x05db)
+    ((?L ?+) . ?\x05dc)
+    ((?M ?%) . ?\x05dd)
+    ((?M ?+) . ?\x05de)
+    ((?N ?%) . ?\x05df)
+    ((?N ?+) . ?\x05e0)
+    ((?S ?+) . ?\x05e1)
+    ((?E ?+) . ?\x05e2)
+    ((?P ?%) . ?\x05e3)
+    ((?P ?+) . ?\x05e4)
+    ((?Z ?j) . ?\x05e5)
+    ((?Z ?J) . ?\x05e6)
+    ((?Q ?+) . ?\x05e7)
+    ((?R ?+) . ?\x05e8)
+    ((?S ?h) . ?\x05e9)
+    ((?T ?+) . ?\x05ea)
+    ((?, ?+) . ?\x060c)
+    ((?\; ?+) . ?\x061b)
+    ((?? ?+) . ?\x061f)
+    ((?H ?') . ?\x0621)
+    ((?a ?M) . ?\x0622)
+    ((?a ?H) . ?\x0623)
+    ((?w ?H) . ?\x0624)
+    ((?a ?h) . ?\x0625)
+    ((?y ?H) . ?\x0626)
+    ((?a ?+) . ?\x0627)
+    ((?b ?+) . ?\x0628)
+    ((?t ?m) . ?\x0629)
+    ((?t ?+) . ?\x062a)
+    ((?t ?k) . ?\x062b)
+    ((?g ?+) . ?\x062c)
+    ((?h ?k) . ?\x062d)
+    ((?x ?+) . ?\x062e)
+    ((?d ?+) . ?\x062f)
+    ((?d ?k) . ?\x0630)
+    ((?r ?+) . ?\x0631)
+    ((?z ?+) . ?\x0632)
+    ((?s ?+) . ?\x0633)
+    ((?s ?n) . ?\x0634)
+    ((?c ?+) . ?\x0635)
+    ((?d ?d) . ?\x0636)
+    ((?t ?j) . ?\x0637)
+    ((?z ?H) . ?\x0638)
+    ((?e ?+) . ?\x0639)
+    ((?i ?+) . ?\x063a)
+    ((?+ ?+) . ?\x0640)
+    ((?f ?+) . ?\x0641)
+    ((?q ?+) . ?\x0642)
+    ((?k ?+) . ?\x0643)
+    ((?l ?+) . ?\x0644)
+    ((?m ?+) . ?\x0645)
+    ((?n ?+) . ?\x0646)
+    ((?h ?+) . ?\x0647)
+    ((?w ?+) . ?\x0648)
+    ((?j ?+) . ?\x0649)
+    ((?y ?+) . ?\x064a)
+    ((?: ?+) . ?\x064b)
+    ((?\" ?+) . ?\x064c)
+    ((?= ?+) . ?\x064d)
+    ((?/ ?+) . ?\x064e)
+    ((?' ?+) . ?\x064f)
+    ((?1 ?+) . ?\x0650)
+    ((?3 ?+) . ?\x0651)
+    ((?0 ?+) . ?\x0652)
+    ((?a ?S) . ?\x0670)
+    ((?p ?+) . ?\x067e)
+    ((?v ?+) . ?\x06a4)
+    ((?g ?f) . ?\x06af)
+    ((?0 ?a) . ?\x06f0)
+    ((?1 ?a) . ?\x06f1)
+    ((?2 ?a) . ?\x06f2)
+    ((?3 ?a) . ?\x06f3)
+    ((?4 ?a) . ?\x06f4)
+    ((?5 ?a) . ?\x06f5)
+    ((?6 ?a) . ?\x06f6)
+    ((?7 ?a) . ?\x06f7)
+    ((?8 ?a) . ?\x06f8)
+    ((?9 ?a) . ?\x06f9)
+    ((?B ?.) . ?\x1e02)
+    ((?b ?.) . ?\x1e03)
+    ((?B ?_) . ?\x1e06)
+    ((?b ?_) . ?\x1e07)
+    ((?D ?.) . ?\x1e0a)
+    ((?d ?.) . ?\x1e0b)
+    ((?D ?_) . ?\x1e0e)
+    ((?d ?_) . ?\x1e0f)
+    ((?D ?,) . ?\x1e10)
+    ((?d ?,) . ?\x1e11)
+    ((?F ?.) . ?\x1e1e)
+    ((?f ?.) . ?\x1e1f)
+    ((?G ?-) . ?\x1e20)
+    ((?g ?-) . ?\x1e21)
+    ((?H ?.) . ?\x1e22)
+    ((?h ?.) . ?\x1e23)
+    ((?H ?:) . ?\x1e26)
+    ((?h ?:) . ?\x1e27)
+    ((?H ?,) . ?\x1e28)
+    ((?h ?,) . ?\x1e29)
+    ((?K ?') . ?\x1e30)
+    ((?k ?') . ?\x1e31)
+    ((?K ?_) . ?\x1e34)
+    ((?k ?_) . ?\x1e35)
+    ((?L ?_) . ?\x1e3a)
+    ((?l ?_) . ?\x1e3b)
+    ((?M ?') . ?\x1e3e)
+    ((?m ?') . ?\x1e3f)
+    ((?M ?.) . ?\x1e40)
+    ((?m ?.) . ?\x1e41)
+    ((?N ?.) . ?\x1e44)
+    ((?n ?.) . ?\x1e45)
+    ((?N ?_) . ?\x1e48)
+    ((?n ?_) . ?\x1e49)
+    ((?P ?') . ?\x1e54)
+    ((?p ?') . ?\x1e55)
+    ((?P ?.) . ?\x1e56)
+    ((?p ?.) . ?\x1e57)
+    ((?R ?.) . ?\x1e58)
+    ((?r ?.) . ?\x1e59)
+    ((?R ?_) . ?\x1e5e)
+    ((?r ?_) . ?\x1e5f)
+    ((?S ?.) . ?\x1e60)
+    ((?s ?.) . ?\x1e61)
+    ((?T ?.) . ?\x1e6a)
+    ((?t ?.) . ?\x1e6b)
+    ((?T ?_) . ?\x1e6e)
+    ((?t ?_) . ?\x1e6f)
+    ((?V ??) . ?\x1e7c)
+    ((?v ??) . ?\x1e7d)
+    ((?W ?!) . ?\x1e80)
+    ((?w ?!) . ?\x1e81)
+    ((?W ?') . ?\x1e82)
+    ((?w ?') . ?\x1e83)
+    ((?W ?:) . ?\x1e84)
+    ((?w ?:) . ?\x1e85)
+    ((?W ?.) . ?\x1e86)
+    ((?w ?.) . ?\x1e87)
+    ((?X ?.) . ?\x1e8a)
+    ((?x ?.) . ?\x1e8b)
+    ((?X ?:) . ?\x1e8c)
+    ((?x ?:) . ?\x1e8d)
+    ((?Y ?.) . ?\x1e8e)
+    ((?y ?.) . ?\x1e8f)
+    ((?Z ?>) . ?\x1e90)
+    ((?z ?>) . ?\x1e91)
+    ((?Z ?_) . ?\x1e94)
+    ((?z ?_) . ?\x1e95)
+    ((?h ?_) . ?\x1e96)
+    ((?t ?:) . ?\x1e97)
+    ((?w ?0) . ?\x1e98)
+    ((?y ?0) . ?\x1e99)
+    ((?A ?2) . ?\x1ea2)
+    ((?a ?2) . ?\x1ea3)
+    ((?E ?2) . ?\x1eba)
+    ((?e ?2) . ?\x1ebb)
+    ((?E ??) . ?\x1ebc)
+    ((?e ??) . ?\x1ebd)
+    ((?I ?2) . ?\x1ec8)
+    ((?i ?2) . ?\x1ec9)
+    ((?O ?2) . ?\x1ece)
+    ((?o ?2) . ?\x1ecf)
+    ((?U ?2) . ?\x1ee6)
+    ((?u ?2) . ?\x1ee7)
+    ((?Y ?!) . ?\x1ef2)
+    ((?y ?!) . ?\x1ef3)
+    ((?Y ?2) . ?\x1ef6)
+    ((?y ?2) . ?\x1ef7)
+    ((?Y ??) . ?\x1ef8)
+    ((?y ??) . ?\x1ef9)
+    ((?\; ?') . ?\x1f00)
+    ((?, ?') . ?\x1f01)
+    ((?\; ?!) . ?\x1f02)
+    ((?, ?!) . ?\x1f03)
+    ((?? ?\;) . ?\x1f04)
+    ((?? ?,) . ?\x1f05)
+    ((?! ?:) . ?\x1f06)
+    ((?? ?:) . ?\x1f07)
+    ((?1 ?N) . ?\x2002)
+    ((?1 ?M) . ?\x2003)
+    ((?3 ?M) . ?\x2004)
+    ((?4 ?M) . ?\x2005)
+    ((?6 ?M) . ?\x2006)
+    ((?1 ?T) . ?\x2009)
+    ((?1 ?H) . ?\x200a)
+    ((?- ?1) . ?\x2010)
+    ((?- ?N) . ?\x2013)
+    ((?- ?M) . ?\x2014)
+    ((?- ?3) . ?\x2015)
+    ((?! ?2) . ?\x2016)
+    ((?= ?2) . ?\x2017)
+    ((?' ?6) . ?\x2018)
+    ((?' ?9) . ?\x2019)
+    ((?. ?9) . ?\x201a)
+    ((?9 ?') . ?\x201b)
+    ((?\" ?6) . ?\x201c)
+    ((?\" ?9) . ?\x201d)
+    ((?: ?9) . ?\x201e)
+    ((?9 ?\") . ?\x201f)
+    ((?/ ?-) . ?\x2020)
+    ((?/ ?=) . ?\x2021)
+    ((?. ?.) . ?\x2025)
+    ((?% ?0) . ?\x2030)
+    ((?1 ?') . ?\x2032)
+    ((?2 ?') . ?\x2033)
+    ((?3 ?') . ?\x2034)
+    ((?1 ?\") . ?\x2035)
+    ((?2 ?\") . ?\x2036)
+    ((?3 ?\") . ?\x2037)
+    ((?C ?a) . ?\x2038)
+    ((?< ?1) . ?\x2039)
+    ((?> ?1) . ?\x203a)
+    ((?: ?X) . ?\x203b)
+    ((?' ?-) . ?\x203e)
+    ((?/ ?f) . ?\x2044)
+    ((?0 ?S) . ?\x2070)
+    ((?4 ?S) . ?\x2074)
+    ((?5 ?S) . ?\x2075)
+    ((?6 ?S) . ?\x2076)
+    ((?7 ?S) . ?\x2077)
+    ((?8 ?S) . ?\x2078)
+    ((?9 ?S) . ?\x2079)
+    ((?+ ?S) . ?\x207a)
+    ((?- ?S) . ?\x207b)
+    ((?= ?S) . ?\x207c)
+    ((?\( ?S) . ?\x207d)
+    ((?\) ?S) . ?\x207e)
+    ((?n ?S) . ?\x207f)
+    ((?0 ?s) . ?\x2080)
+    ((?1 ?s) . ?\x2081)
+    ((?2 ?s) . ?\x2082)
+    ((?3 ?s) . ?\x2083)
+    ((?4 ?s) . ?\x2084)
+    ((?5 ?s) . ?\x2085)
+    ((?6 ?s) . ?\x2086)
+    ((?7 ?s) . ?\x2087)
+    ((?8 ?s) . ?\x2088)
+    ((?9 ?s) . ?\x2089)
+    ((?+ ?s) . ?\x208a)
+    ((?- ?s) . ?\x208b)
+    ((?= ?s) . ?\x208c)
+    ((?\( ?s) . ?\x208d)
+    ((?\) ?s) . ?\x208e)
+    ((?L ?i) . ?\x20a4)
+    ((?P ?t) . ?\x20a7)
+    ((?W ?=) . ?\x20a9)
+    ((?= ?e) . ?\x20ac)
+    ((?E ?u) . ?\x20ac)
+    ((?o ?C) . ?\x2103)
+    ((?c ?o) . ?\x2105)
+    ((?o ?F) . ?\x2109)
+    ((?N ?0) . ?\x2116)
+    ((?P ?O) . ?\x2117)
+    ((?R ?x) . ?\x211e)
+    ((?S ?M) . ?\x2120)
+    ((?T ?M) . ?\x2122)
+    ((?O ?m) . ?\x2126)
+    ((?A ?O) . ?\x212b)
+    ((?1 ?3) . ?\x2153)
+    ((?2 ?3) . ?\x2154)
+    ((?1 ?5) . ?\x2155)
+    ((?2 ?5) . ?\x2156)
+    ((?3 ?5) . ?\x2157)
+    ((?4 ?5) . ?\x2158)
+    ((?1 ?6) . ?\x2159)
+    ((?5 ?6) . ?\x215a)
+    ((?1 ?8) . ?\x215b)
+    ((?3 ?8) . ?\x215c)
+    ((?5 ?8) . ?\x215d)
+    ((?7 ?8) . ?\x215e)
+    ((?1 ?R) . ?\x2160)
+    ((?2 ?R) . ?\x2161)
+    ((?3 ?R) . ?\x2162)
+    ((?4 ?R) . ?\x2163)
+    ((?5 ?R) . ?\x2164)
+    ((?6 ?R) . ?\x2165)
+    ((?7 ?R) . ?\x2166)
+    ((?8 ?R) . ?\x2167)
+    ((?9 ?R) . ?\x2168)
+    ((?a ?R) . ?\x2169)
+    ((?b ?R) . ?\x216a)
+    ((?c ?R) . ?\x216b)
+    ((?1 ?r) . ?\x2170)
+    ((?2 ?r) . ?\x2171)
+    ((?3 ?r) . ?\x2172)
+    ((?4 ?r) . ?\x2173)
+    ((?5 ?r) . ?\x2174)
+    ((?6 ?r) . ?\x2175)
+    ((?7 ?r) . ?\x2176)
+    ((?8 ?r) . ?\x2177)
+    ((?9 ?r) . ?\x2178)
+    ((?a ?r) . ?\x2179)
+    ((?b ?r) . ?\x217a)
+    ((?c ?r) . ?\x217b)
+    ((?< ?-) . ?\x2190)
+    ((?- ?!) . ?\x2191)
+    ((?- ?>) . ?\x2192)
+    ((?- ?v) . ?\x2193)
+    ((?< ?>) . ?\x2194)
+    ((?U ?D) . ?\x2195)
+    ((?< ?=) . ?\x21d0)
+    ((?= ?>) . ?\x21d2)
+    ((?= ?=) . ?\x21d4)
+    ((?F ?A) . ?\x2200)
+    ((?d ?P) . ?\x2202)
+    ((?T ?E) . ?\x2203)
+    ((?/ ?0) . ?\x2205)
+    ((?D ?E) . ?\x2206)
+    ((?N ?B) . ?\x2207)
+    ((?\( ?-) . ?\x2208)
+    ((?- ?\)) . ?\x220b)
+    ((?* ?P) . ?\x220f)
+    ((?+ ?Z) . ?\x2211)
+    ((?- ?2) . ?\x2212)
+    ((?- ?+) . ?\x2213)
+    ((?* ?-) . ?\x2217)
+    ((?O ?b) . ?\x2218)
+    ((?S ?b) . ?\x2219)
+    ((?R ?T) . ?\x221a)
+    ((?0 ?\() . ?\x221d)
+    ((?0 ?0) . ?\x221e)
+    ((?- ?L) . ?\x221f)
+    ((?- ?V) . ?\x2220)
+    ((?P ?P) . ?\x2225)
+    ((?A ?N) . ?\x2227)
+    ((?O ?R) . ?\x2228)
+    ((?\( ?U) . ?\x2229)
+    ((?\) ?U) . ?\x222a)
+    ((?I ?n) . ?\x222b)
+    ((?D ?I) . ?\x222c)
+    ((?I ?o) . ?\x222e)
+    ((?. ?:) . ?\x2234)
+    ((?: ?.) . ?\x2235)
+    ((?: ?R) . ?\x2236)
+    ((?: ?:) . ?\x2237)
+    ((?? ?1) . ?\x223c)
+    ((?C ?G) . ?\x223e)
+    ((?? ?-) . ?\x2243)
+    ((?? ?=) . ?\x2245)
+    ((?? ?2) . ?\x2248)
+    ((?= ??) . ?\x224c)
+    ((?H ?I) . ?\x2253)
+    ((?! ?=) . ?\x2260)
+    ((?= ?3) . ?\x2261)
+    ((?= ?<) . ?\x2264)
+    ((?> ?=) . ?\x2265)
+    ((?< ?*) . ?\x226a)
+    ((?* ?>) . ?\x226b)
+    ((?! ?<) . ?\x226e)
+    ((?! ?>) . ?\x226f)
+    ((?\( ?C) . ?\x2282)
+    ((?\) ?C) . ?\x2283)
+    ((?\( ?_) . ?\x2286)
+    ((?\) ?_) . ?\x2287)
+    ((?0 ?.) . ?\x2299)
+    ((?0 ?2) . ?\x229a)
+    ((?- ?T) . ?\x22a5)
+    ((?. ?P) . ?\x22c5)
+    ((?: ?3) . ?\x22ee)
+    ((?. ?3) . ?\x22ef)
+    ((?E ?h) . ?\x2302)
+    ((?< ?7) . ?\x2308)
+    ((?> ?7) . ?\x2309)
+    ((?7 ?<) . ?\x230a)
+    ((?7 ?>) . ?\x230b)
+    ((?N ?I) . ?\x2310)
+    ((?\( ?A) . ?\x2312)
+    ((?T ?R) . ?\x2315)
+    ((?I ?u) . ?\x2320)
+    ((?I ?l) . ?\x2321)
+    ((?< ?/) . ?\x2329)
+    ((?/ ?>) . ?\x232a)
+    ((?V ?s) . ?\x2423)
+    ((?1 ?h) . ?\x2440)
+    ((?3 ?h) . ?\x2441)
+    ((?2 ?h) . ?\x2442)
+    ((?4 ?h) . ?\x2443)
+    ((?1 ?j) . ?\x2446)
+    ((?2 ?j) . ?\x2447)
+    ((?3 ?j) . ?\x2448)
+    ((?4 ?j) . ?\x2449)
+    ((?1 ?.) . ?\x2488)
+    ((?2 ?.) . ?\x2489)
+    ((?3 ?.) . ?\x248a)
+    ((?4 ?.) . ?\x248b)
+    ((?5 ?.) . ?\x248c)
+    ((?6 ?.) . ?\x248d)
+    ((?7 ?.) . ?\x248e)
+    ((?8 ?.) . ?\x248f)
+    ((?9 ?.) . ?\x2490)
+    ((?h ?h) . ?\x2500)
+    ((?H ?H) . ?\x2501)
+    ((?v ?v) . ?\x2502)
+    ((?V ?V) . ?\x2503)
+    ((?3 ?-) . ?\x2504)
+    ((?3 ?_) . ?\x2505)
+    ((?3 ?!) . ?\x2506)
+    ((?3 ?/) . ?\x2507)
+    ((?4 ?-) . ?\x2508)
+    ((?4 ?_) . ?\x2509)
+    ((?4 ?!) . ?\x250a)
+    ((?4 ?/) . ?\x250b)
+    ((?d ?r) . ?\x250c)
+    ((?d ?R) . ?\x250d)
+    ((?D ?r) . ?\x250e)
+    ((?D ?R) . ?\x250f)
+    ((?d ?l) . ?\x2510)
+    ((?d ?L) . ?\x2511)
+    ((?D ?l) . ?\x2512)
+    ((?L ?D) . ?\x2513)
+    ((?u ?r) . ?\x2514)
+    ((?u ?R) . ?\x2515)
+    ((?U ?r) . ?\x2516)
+    ((?U ?R) . ?\x2517)
+    ((?u ?l) . ?\x2518)
+    ((?u ?L) . ?\x2519)
+    ((?U ?l) . ?\x251a)
+    ((?U ?L) . ?\x251b)
+    ((?v ?r) . ?\x251c)
+    ((?v ?R) . ?\x251d)
+    ((?V ?r) . ?\x2520)
+    ((?V ?R) . ?\x2523)
+    ((?v ?l) . ?\x2524)
+    ((?v ?L) . ?\x2525)
+    ((?V ?l) . ?\x2528)
+    ((?V ?L) . ?\x252b)
+    ((?d ?h) . ?\x252c)
+    ((?d ?H) . ?\x252f)
+    ((?D ?h) . ?\x2530)
+    ((?D ?H) . ?\x2533)
+    ((?u ?h) . ?\x2534)
+    ((?u ?H) . ?\x2537)
+    ((?U ?h) . ?\x2538)
+    ((?U ?H) . ?\x253b)
+    ((?v ?h) . ?\x253c)
+    ((?v ?H) . ?\x253f)
+    ((?V ?h) . ?\x2542)
+    ((?V ?H) . ?\x254b)
+    ((?F ?D) . ?\x2571)
+    ((?B ?D) . ?\x2572)
+    ((?T ?B) . ?\x2580)
+    ((?L ?B) . ?\x2584)
+    ((?F ?B) . ?\x2588)
+    ((?l ?B) . ?\x258c)
+    ((?R ?B) . ?\x2590)
+    ((?. ?S) . ?\x2591)
+    ((?: ?S) . ?\x2592)
+    ((?? ?S) . ?\x2593)
+    ((?f ?S) . ?\x25a0)
+    ((?O ?S) . ?\x25a1)
+    ((?R ?O) . ?\x25a2)
+    ((?R ?r) . ?\x25a3)
+    ((?R ?F) . ?\x25a4)
+    ((?R ?Y) . ?\x25a5)
+    ((?R ?H) . ?\x25a6)
+    ((?R ?Z) . ?\x25a7)
+    ((?R ?K) . ?\x25a8)
+    ((?R ?X) . ?\x25a9)
+    ((?s ?B) . ?\x25aa)
+    ((?S ?R) . ?\x25ac)
+    ((?O ?r) . ?\x25ad)
+    ((?U ?T) . ?\x25b2)
+    ((?u ?T) . ?\x25b3)
+    ((?P ?R) . ?\x25b6)
+    ((?T ?r) . ?\x25b7)
+    ((?D ?t) . ?\x25bc)
+    ((?d ?T) . ?\x25bd)
+    ((?P ?L) . ?\x25c0)
+    ((?T ?l) . ?\x25c1)
+    ((?D ?b) . ?\x25c6)
+    ((?D ?w) . ?\x25c7)
+    ((?L ?Z) . ?\x25ca)
+    ((?0 ?m) . ?\x25cb)
+    ((?0 ?o) . ?\x25ce)
+    ((?0 ?M) . ?\x25cf)
+    ((?0 ?L) . ?\x25d0)
+    ((?0 ?R) . ?\x25d1)
+    ((?S ?n) . ?\x25d8)
+    ((?I ?c) . ?\x25d9)
+    ((?F ?d) . ?\x25e2)
+    ((?B ?d) . ?\x25e3)
+    ((?* ?2) . ?\x2605)
+    ((?* ?1) . ?\x2606)
+    ((?< ?H) . ?\x261c)
+    ((?> ?H) . ?\x261e)
+    ((?0 ?u) . ?\x263a)
+    ((?0 ?U) . ?\x263b)
+    ((?S ?U) . ?\x263c)
+    ((?F ?m) . ?\x2640)
+    ((?M ?l) . ?\x2642)
+    ((?c ?S) . ?\x2660)
+    ((?c ?H) . ?\x2661)
+    ((?c ?D) . ?\x2662)
+    ((?c ?C) . ?\x2663)
+    ((?M ?d) . ?\x2669)
+    ((?M ?8) . ?\x266a)
+    ((?M ?2) . ?\x266b)
+    ((?M ?b) . ?\x266d)
+    ((?M ?x) . ?\x266e)
+    ((?M ?X) . ?\x266f)
+    ((?O ?K) . ?\x2713)
+    ((?X ?X) . ?\x2717)
+    ((?- ?X) . ?\x2720)
+    ((?I ?S) . ?\x3000)
+    ((?, ?_) . ?\x3001)
+    ((?. ?_) . ?\x3002)
+    ((?+ ?\") . ?\x3003)
+    ((?+ ?_) . ?\x3004)
+    ((?* ?_) . ?\x3005)
+    ((?\; ?_) . ?\x3006)
+    ((?0 ?_) . ?\x3007)
+    ((?< ?+) . ?\x300a)
+    ((?> ?+) . ?\x300b)
+    ((?< ?') . ?\x300c)
+    ((?> ?') . ?\x300d)
+    ((?< ?\") . ?\x300e)
+    ((?> ?\") . ?\x300f)
+    ((?\( ?\") . ?\x3010)
+    ((?\) ?\") . ?\x3011)
+    ((?= ?T) . ?\x3012)
+    ((?= ?_) . ?\x3013)
+    ((?\( ?') . ?\x3014)
+    ((?\) ?') . ?\x3015)
+    ((?\( ?I) . ?\x3016)
+    ((?\) ?I) . ?\x3017)
+    ((?- ??) . ?\x301c)
+    ((?A ?5) . ?\x3041)
+    ((?a ?5) . ?\x3042)
+    ((?I ?5) . ?\x3043)
+    ((?i ?5) . ?\x3044)
+    ((?U ?5) . ?\x3045)
+    ((?u ?5) . ?\x3046)
+    ((?E ?5) . ?\x3047)
+    ((?e ?5) . ?\x3048)
+    ((?O ?5) . ?\x3049)
+    ((?o ?5) . ?\x304a)
+    ((?k ?a) . ?\x304b)
+    ((?g ?a) . ?\x304c)
+    ((?k ?i) . ?\x304d)
+    ((?g ?i) . ?\x304e)
+    ((?k ?u) . ?\x304f)
+    ((?g ?u) . ?\x3050)
+    ((?k ?e) . ?\x3051)
+    ((?g ?e) . ?\x3052)
+    ((?k ?o) . ?\x3053)
+    ((?g ?o) . ?\x3054)
+    ((?s ?a) . ?\x3055)
+    ((?z ?a) . ?\x3056)
+    ((?s ?i) . ?\x3057)
+    ((?z ?i) . ?\x3058)
+    ((?s ?u) . ?\x3059)
+    ((?z ?u) . ?\x305a)
+    ((?s ?e) . ?\x305b)
+    ((?z ?e) . ?\x305c)
+    ((?s ?o) . ?\x305d)
+    ((?z ?o) . ?\x305e)
+    ((?t ?a) . ?\x305f)
+    ((?d ?a) . ?\x3060)
+    ((?t ?i) . ?\x3061)
+    ((?d ?i) . ?\x3062)
+    ((?t ?U) . ?\x3063)
+    ((?t ?u) . ?\x3064)
+    ((?d ?u) . ?\x3065)
+    ((?t ?e) . ?\x3066)
+    ((?d ?e) . ?\x3067)
+    ((?t ?o) . ?\x3068)
+    ((?d ?o) . ?\x3069)
+    ((?n ?a) . ?\x306a)
+    ((?n ?i) . ?\x306b)
+    ((?n ?u) . ?\x306c)
+    ((?n ?e) . ?\x306d)
+    ((?n ?o) . ?\x306e)
+    ((?h ?a) . ?\x306f)
+    ((?b ?a) . ?\x3070)
+    ((?p ?a) . ?\x3071)
+    ((?h ?i) . ?\x3072)
+    ((?b ?i) . ?\x3073)
+    ((?p ?i) . ?\x3074)
+    ((?h ?u) . ?\x3075)
+    ((?b ?u) . ?\x3076)
+    ((?p ?u) . ?\x3077)
+    ((?h ?e) . ?\x3078)
+    ((?b ?e) . ?\x3079)
+    ((?p ?e) . ?\x307a)
+    ((?h ?o) . ?\x307b)
+    ((?b ?o) . ?\x307c)
+    ((?p ?o) . ?\x307d)
+    ((?m ?a) . ?\x307e)
+    ((?m ?i) . ?\x307f)
+    ((?m ?u) . ?\x3080)
+    ((?m ?e) . ?\x3081)
+    ((?m ?o) . ?\x3082)
+    ((?y ?A) . ?\x3083)
+    ((?y ?a) . ?\x3084)
+    ((?y ?U) . ?\x3085)
+    ((?y ?u) . ?\x3086)
+    ((?y ?O) . ?\x3087)
+    ((?y ?o) . ?\x3088)
+    ((?r ?a) . ?\x3089)
+    ((?r ?i) . ?\x308a)
+    ((?r ?u) . ?\x308b)
+    ((?r ?e) . ?\x308c)
+    ((?r ?o) . ?\x308d)
+    ((?w ?A) . ?\x308e)
+    ((?w ?a) . ?\x308f)
+    ((?w ?i) . ?\x3090)
+    ((?w ?e) . ?\x3091)
+    ((?w ?o) . ?\x3092)
+    ((?n ?5) . ?\x3093)
+    ((?v ?u) . ?\x3094)
+    ((?\" ?5) . ?\x309b)
+    ((?0 ?5) . ?\x309c)
+    ((?* ?5) . ?\x309d)
+    ((?+ ?5) . ?\x309e)
+    ((?a ?6) . ?\x30a1)
+    ((?A ?6) . ?\x30a2)
+    ((?i ?6) . ?\x30a3)
+    ((?I ?6) . ?\x30a4)
+    ((?u ?6) . ?\x30a5)
+    ((?U ?6) . ?\x30a6)
+    ((?e ?6) . ?\x30a7)
+    ((?E ?6) . ?\x30a8)
+    ((?o ?6) . ?\x30a9)
+    ((?O ?6) . ?\x30aa)
+    ((?K ?a) . ?\x30ab)
+    ((?G ?a) . ?\x30ac)
+    ((?K ?i) . ?\x30ad)
+    ((?G ?i) . ?\x30ae)
+    ((?K ?u) . ?\x30af)
+    ((?G ?u) . ?\x30b0)
+    ((?K ?e) . ?\x30b1)
+    ((?G ?e) . ?\x30b2)
+    ((?K ?o) . ?\x30b3)
+    ((?G ?o) . ?\x30b4)
+    ((?S ?a) . ?\x30b5)
+    ((?Z ?a) . ?\x30b6)
+    ((?S ?i) . ?\x30b7)
+    ((?Z ?i) . ?\x30b8)
+    ((?S ?u) . ?\x30b9)
+    ((?Z ?u) . ?\x30ba)
+    ((?S ?e) . ?\x30bb)
+    ((?Z ?e) . ?\x30bc)
+    ((?S ?o) . ?\x30bd)
+    ((?Z ?o) . ?\x30be)
+    ((?T ?a) . ?\x30bf)
+    ((?D ?a) . ?\x30c0)
+    ((?T ?i) . ?\x30c1)
+    ((?D ?i) . ?\x30c2)
+    ((?T ?U) . ?\x30c3)
+    ((?T ?u) . ?\x30c4)
+    ((?D ?u) . ?\x30c5)
+    ((?T ?e) . ?\x30c6)
+    ((?D ?e) . ?\x30c7)
+    ((?T ?o) . ?\x30c8)
+    ((?D ?o) . ?\x30c9)
+    ((?N ?a) . ?\x30ca)
+    ((?N ?i) . ?\x30cb)
+    ((?N ?u) . ?\x30cc)
+    ((?N ?e) . ?\x30cd)
+    ((?N ?o) . ?\x30ce)
+    ((?H ?a) . ?\x30cf)
+    ((?B ?a) . ?\x30d0)
+    ((?P ?a) . ?\x30d1)
+    ((?H ?i) . ?\x30d2)
+    ((?B ?i) . ?\x30d3)
+    ((?P ?i) . ?\x30d4)
+    ((?H ?u) . ?\x30d5)
+    ((?B ?u) . ?\x30d6)
+    ((?P ?u) . ?\x30d7)
+    ((?H ?e) . ?\x30d8)
+    ((?B ?e) . ?\x30d9)
+    ((?P ?e) . ?\x30da)
+    ((?H ?o) . ?\x30db)
+    ((?B ?o) . ?\x30dc)
+    ((?P ?o) . ?\x30dd)
+    ((?u ?R) . ?\x2515)
+    ((?U ?r) . ?\x2516)
+    ((?U ?R) . ?\x2517)
+    ((?u ?l) . ?\x2518)
+    ((?u ?L) . ?\x2519)
+    ((?U ?l) . ?\x251a)
+    ((?U ?L) . ?\x251b)
+    ((?v ?r) . ?\x251c)
+    ((?v ?R) . ?\x251d)
+    ((?V ?r) . ?\x2520)
+    ((?V ?R) . ?\x2523)
+    ((?v ?l) . ?\x2524)
+    ((?v ?L) . ?\x2525)
+    ((?V ?l) . ?\x2528)
+    ((?V ?L) . ?\x252b)
+    ((?d ?h) . ?\x252c)
+    ((?d ?H) . ?\x252f)
+    ((?D ?h) . ?\x2530)
+    ((?D ?H) . ?\x2533)
+    ((?u ?h) . ?\x2534)
+    ((?u ?H) . ?\x2537)
+    ((?U ?h) . ?\x2538)
+    ((?U ?H) . ?\x253b)
+    ((?v ?h) . ?\x253c)
+    ((?v ?H) . ?\x253f)
+    ((?V ?h) . ?\x2542)
+    ((?V ?H) . ?\x254b)
+    ((?F ?D) . ?\x2571)
+    ((?B ?D) . ?\x2572)
+    ((?T ?B) . ?\x2580)
+    ((?L ?B) . ?\x2584)
+    ((?F ?B) . ?\x2588)
+    ((?l ?B) . ?\x258c)
+    ((?R ?B) . ?\x2590)
+    ((?. ?S) . ?\x2591)
+    ((?: ?S) . ?\x2592)
+    ((?? ?S) . ?\x2593)
+    ((?f ?S) . ?\x25a0)
+    ((?O ?S) . ?\x25a1)
+    ((?R ?O) . ?\x25a2)
+    ((?R ?r) . ?\x25a3)
+    ((?R ?F) . ?\x25a4)
+    ((?R ?Y) . ?\x25a5)
+    ((?R ?H) . ?\x25a6)
+    ((?R ?Z) . ?\x25a7)
+    ((?R ?K) . ?\x25a8)
+    ((?R ?X) . ?\x25a9)
+    ((?s ?B) . ?\x25aa)
+    ((?S ?R) . ?\x25ac)
+    ((?O ?r) . ?\x25ad)
+    ((?U ?T) . ?\x25b2)
+    ((?u ?T) . ?\x25b3)
+    ((?P ?R) . ?\x25b6)
+    ((?T ?r) . ?\x25b7)
+    ((?D ?t) . ?\x25bc)
+    ((?d ?T) . ?\x25bd)
+    ((?P ?L) . ?\x25c0)
+    ((?T ?l) . ?\x25c1)
+    ((?D ?b) . ?\x25c6)
+    ((?D ?w) . ?\x25c7)
+    ((?L ?Z) . ?\x25ca)
+    ((?0 ?m) . ?\x25cb)
+    ((?0 ?o) . ?\x25ce)
+    ((?0 ?M) . ?\x25cf)
+    ((?0 ?L) . ?\x25d0)
+    ((?0 ?R) . ?\x25d1)
+    ((?S ?n) . ?\x25d8)
+    ((?I ?c) . ?\x25d9)
+    ((?F ?d) . ?\x25e2)
+    ((?B ?d) . ?\x25e3)
+    ((?* ?2) . ?\x2605)
+    ((?* ?1) . ?\x2606)
+    ((?< ?H) . ?\x261c)
+    ((?> ?H) . ?\x261e)
+    ((?0 ?u) . ?\x263a)
+    ((?0 ?U) . ?\x263b)
+    ((?S ?U) . ?\x263c)
+    ((?F ?m) . ?\x2640)
+    ((?M ?l) . ?\x2642)
+    ((?c ?S) . ?\x2660)
+    ((?c ?H) . ?\x2661)
+    ((?c ?D) . ?\x2662)
+    ((?c ?C) . ?\x2663)
+    ((?M ?d) . ?\x2669)
+    ((?M ?8) . ?\x266a)
+    ((?M ?2) . ?\x266b)
+    ((?M ?b) . ?\x266d)
+    ((?M ?x) . ?\x266e)
+    ((?M ?X) . ?\x266f)
+    ((?O ?K) . ?\x2713)
+    ((?X ?X) . ?\x2717)
+    ((?- ?X) . ?\x2720)
+    ((?I ?S) . ?\x3000)
+    ((?, ?_) . ?\x3001)
+    ((?. ?_) . ?\x3002)
+    ((?+ ?\") . ?\x3003)
+    ((?+ ?_) . ?\x3004)
+    ((?* ?_) . ?\x3005)
+    ((?\; ?_) . ?\x3006)
+    ((?0 ?_) . ?\x3007)
+    ((?< ?+) . ?\x300a)
+    ((?> ?+) . ?\x300b)
+    ((?< ?') . ?\x300c)
+    ((?> ?') . ?\x300d)
+    ((?< ?\") . ?\x300e)
+    ((?> ?\") . ?\x300f)
+    ((?\( ?\") . ?\x3010)
+    ((?\) ?\") . ?\x3011)
+    ((?= ?T) . ?\x3012)
+    ((?= ?_) . ?\x3013)
+    ((?\( ?') . ?\x3014)
+    ((?\) ?') . ?\x3015)
+    ((?\( ?I) . ?\x3016)
+    ((?\) ?I) . ?\x3017)
+    ((?- ??) . ?\x301c)
+    ((?A ?5) . ?\x3041)
+    ((?a ?5) . ?\x3042)
+    ((?I ?5) . ?\x3043)
+    ((?i ?5) . ?\x3044)
+    ((?U ?5) . ?\x3045)
+    ((?u ?5) . ?\x3046)
+    ((?E ?5) . ?\x3047)
+    ((?e ?5) . ?\x3048)
+    ((?O ?5) . ?\x3049)
+    ((?o ?5) . ?\x304a)
+    ((?k ?a) . ?\x304b)
+    ((?g ?a) . ?\x304c)
+    ((?k ?i) . ?\x304d)
+    ((?g ?i) . ?\x304e)
+    ((?k ?u) . ?\x304f)
+    ((?g ?u) . ?\x3050)
+    ((?k ?e) . ?\x3051)
+    ((?g ?e) . ?\x3052)
+    ((?k ?o) . ?\x3053)
+    ((?g ?o) . ?\x3054)
+    ((?s ?a) . ?\x3055)
+    ((?z ?a) . ?\x3056)
+    ((?s ?i) . ?\x3057)
+    ((?z ?i) . ?\x3058)
+    ((?s ?u) . ?\x3059)
+    ((?z ?u) . ?\x305a)
+    ((?s ?e) . ?\x305b)
+    ((?z ?e) . ?\x305c)
+    ((?s ?o) . ?\x305d)
+    ((?z ?o) . ?\x305e)
+    ((?t ?a) . ?\x305f)
+    ((?d ?a) . ?\x3060)
+    ((?t ?i) . ?\x3061)
+    ((?d ?i) . ?\x3062)
+    ((?t ?U) . ?\x3063)
+    ((?t ?u) . ?\x3064)
+    ((?d ?u) . ?\x3065)
+    ((?t ?e) . ?\x3066)
+    ((?d ?e) . ?\x3067)
+    ((?t ?o) . ?\x3068)
+    ((?d ?o) . ?\x3069)
+    ((?n ?a) . ?\x306a)
+    ((?n ?i) . ?\x306b)
+    ((?n ?u) . ?\x306c)
+    ((?n ?e) . ?\x306d)
+    ((?n ?o) . ?\x306e)
+    ((?h ?a) . ?\x306f)
+    ((?b ?a) . ?\x3070)
+    ((?p ?a) . ?\x3071)
+    ((?h ?i) . ?\x3072)
+    ((?b ?i) . ?\x3073)
+    ((?p ?i) . ?\x3074)
+    ((?h ?u) . ?\x3075)
+    ((?b ?u) . ?\x3076)
+    ((?p ?u) . ?\x3077)
+    ((?h ?e) . ?\x3078)
+    ((?b ?e) . ?\x3079)
+    ((?p ?e) . ?\x307a)
+    ((?h ?o) . ?\x307b)
+    ((?b ?o) . ?\x307c)
+    ((?p ?o) . ?\x307d)
+    ((?m ?a) . ?\x307e)
+    ((?m ?i) . ?\x307f)
+    ((?m ?u) . ?\x3080)
+    ((?m ?e) . ?\x3081)
+    ((?m ?o) . ?\x3082)
+    ((?y ?A) . ?\x3083)
+    ((?y ?a) . ?\x3084)
+    ((?y ?U) . ?\x3085)
+    ((?y ?u) . ?\x3086)
+    ((?y ?O) . ?\x3087)
+    ((?y ?o) . ?\x3088)
+    ((?r ?a) . ?\x3089)
+    ((?r ?i) . ?\x308a)
+    ((?r ?u) . ?\x308b)
+    ((?r ?e) . ?\x308c)
+    ((?r ?o) . ?\x308d)
+    ((?w ?A) . ?\x308e)
+    ((?w ?a) . ?\x308f)
+    ((?w ?i) . ?\x3090)
+    ((?w ?e) . ?\x3091)
+    ((?w ?o) . ?\x3092)
+    ((?n ?5) . ?\x3093)
+    ((?v ?u) . ?\x3094)
+    ((?\" ?5) . ?\x309b)
+    ((?0 ?5) . ?\x309c)
+    ((?* ?5) . ?\x309d)
+    ((?+ ?5) . ?\x309e)
+    ((?a ?6) . ?\x30a1)
+    ((?A ?6) . ?\x30a2)
+    ((?i ?6) . ?\x30a3)
+    ((?I ?6) . ?\x30a4)
+    ((?u ?6) . ?\x30a5)
+    ((?U ?6) . ?\x30a6)
+    ((?e ?6) . ?\x30a7)
+    ((?E ?6) . ?\x30a8)
+    ((?o ?6) . ?\x30a9)
+    ((?O ?6) . ?\x30aa)
+    ((?K ?a) . ?\x30ab)
+    ((?G ?a) . ?\x30ac)
+    ((?K ?i) . ?\x30ad)
+    ((?G ?i) . ?\x30ae)
+    ((?K ?u) . ?\x30af)
+    ((?G ?u) . ?\x30b0)
+    ((?K ?e) . ?\x30b1)
+    ((?G ?e) . ?\x30b2)
+    ((?K ?o) . ?\x30b3)
+    ((?G ?o) . ?\x30b4)
+    ((?S ?a) . ?\x30b5)
+    ((?Z ?a) . ?\x30b6)
+    ((?S ?i) . ?\x30b7)
+    ((?Z ?i) . ?\x30b8)
+    ((?S ?u) . ?\x30b9)
+    ((?Z ?u) . ?\x30ba)
+    ((?S ?e) . ?\x30bb)
+    ((?Z ?e) . ?\x30bc)
+    ((?S ?o) . ?\x30bd)
+    ((?Z ?o) . ?\x30be)
+    ((?T ?a) . ?\x30bf)
+    ((?D ?a) . ?\x30c0)
+    ((?T ?i) . ?\x30c1)
+    ((?D ?i) . ?\x30c2)
+    ((?T ?U) . ?\x30c3)
+    ((?T ?u) . ?\x30c4)
+    ((?D ?u) . ?\x30c5)
+    ((?T ?e) . ?\x30c6)
+    ((?D ?e) . ?\x30c7)
+    ((?T ?o) . ?\x30c8)
+    ((?D ?o) . ?\x30c9)
+    ((?N ?a) . ?\x30ca)
+    ((?N ?i) . ?\x30cb)
+    ((?N ?u) . ?\x30cc)
+    ((?N ?e) . ?\x30cd)
+    ((?N ?o) . ?\x30ce)
+    ((?H ?a) . ?\x30cf)
+    ((?B ?a) . ?\x30d0)
+    ((?P ?a) . ?\x30d1)
+    ((?H ?i) . ?\x30d2)
+    ((?B ?i) . ?\x30d3)
+    ((?P ?i) . ?\x30d4)
+    ((?H ?u) . ?\x30d5)
+    ((?B ?u) . ?\x30d6)
+    ((?P ?u) . ?\x30d7)
+    ((?H ?e) . ?\x30d8)
+    ((?B ?e) . ?\x30d9)
+    ((?P ?e) . ?\x30da)
+    ((?H ?o) . ?\x30db)
+    ((?B ?o) . ?\x30dc)
+    ((?P ?o) . ?\x30dd)
+    ((?M ?a) . ?\x30de)
+    ((?M ?i) . ?\x30df)
+    ((?M ?u) . ?\x30e0)
+    ((?M ?e) . ?\x30e1)
+    ((?M ?o) . ?\x30e2)
+    ((?Y ?A) . ?\x30e3)
+    ((?Y ?a) . ?\x30e4)
+    ((?Y ?U) . ?\x30e5)
+    ((?Y ?u) . ?\x30e6)
+    ((?Y ?O) . ?\x30e7)
+    ((?Y ?o) . ?\x30e8)
+    ((?R ?a) . ?\x30e9)
+    ((?R ?i) . ?\x30ea)
+    ((?R ?u) . ?\x30eb)
+    ((?R ?e) . ?\x30ec)
+    ((?R ?o) . ?\x30ed)
+    ((?W ?A) . ?\x30ee)
+    ((?W ?a) . ?\x30ef)
+    ((?W ?i) . ?\x30f0)
+    ((?W ?e) . ?\x30f1)
+    ((?W ?o) . ?\x30f2)
+    ((?N ?6) . ?\x30f3)
+    ((?V ?u) . ?\x30f4)
+    ((?K ?A) . ?\x30f5)
+    ((?K ?E) . ?\x30f6)
+    ((?V ?a) . ?\x30f7)
+    ((?V ?i) . ?\x30f8)
+    ((?V ?e) . ?\x30f9)
+    ((?V ?o) . ?\x30fa)
+    ((?. ?6) . ?\x30fb)
+    ((?- ?6) . ?\x30fc)
+    ((?* ?6) . ?\x30fd)
+    ((?+ ?6) . ?\x30fe)
+    ((?b ?4) . ?\x3105)
+    ((?p ?4) . ?\x3106)
+    ((?m ?4) . ?\x3107)
+    ((?f ?4) . ?\x3108)
+    ((?d ?4) . ?\x3109)
+    ((?t ?4) . ?\x310a)
+    ((?n ?4) . ?\x310b)
+    ((?l ?4) . ?\x310c)
+    ((?g ?4) . ?\x310d)
+    ((?k ?4) . ?\x310e)
+    ((?h ?4) . ?\x310f)
+    ((?j ?4) . ?\x3110)
+    ((?q ?4) . ?\x3111)
+    ((?x ?4) . ?\x3112)
+    ((?z ?h) . ?\x3113)
+    ((?c ?h) . ?\x3114)
+    ((?s ?h) . ?\x3115)
+    ((?r ?4) . ?\x3116)
+    ((?z ?4) . ?\x3117)
+    ((?c ?4) . ?\x3118)
+    ((?s ?4) . ?\x3119)
+    ((?a ?4) . ?\x311a)
+    ((?o ?4) . ?\x311b)
+    ((?e ?4) . ?\x311c)
+    ((?a ?i) . ?\x311e)
+    ((?e ?i) . ?\x311f)
+    ((?a ?u) . ?\x3120)
+    ((?o ?u) . ?\x3121)
+    ((?a ?n) . ?\x3122)
+    ((?e ?n) . ?\x3123)
+    ((?a ?N) . ?\x3124)
+    ((?e ?N) . ?\x3125)
+    ((?e ?r) . ?\x3126)
+    ((?i ?4) . ?\x3127)
+    ((?u ?4) . ?\x3128)
+    ((?i ?u) . ?\x3129)
+    ((?v ?4) . ?\x312a)
+    ((?n ?G) . ?\x312b)
+    ((?g ?n) . ?\x312c)
+    ((?1 ?c) . ?\x3220)
+    ((?2 ?c) . ?\x3221)
+    ((?3 ?c) . ?\x3222)
+    ((?4 ?c) . ?\x3223)
+    ((?5 ?c) . ?\x3224)
+    ((?6 ?c) . ?\x3225)
+    ((?7 ?c) . ?\x3226)
+    ((?8 ?c) . ?\x3227)
+    ((?9 ?c) . ?\x3228)
+    ((?\s ?\s) . ?\xe000)
+    ((?/ ?c) . ?\xe001)
+    ((?U ?A) . ?\xe002)
+    ((?U ?B) . ?\xe003)
+    ((?\" ?3) . ?\xe004)
+    ((?\" ?1) . ?\xe005)
+    ((?\" ?!) . ?\xe006)
+    ((?\" ?') . ?\xe007)
+    ((?\" ?>) . ?\xe008)
+    ((?\" ??) . ?\xe009)
+    ((?\" ?-) . ?\xe00a)
+    ((?\" ?\() . ?\xe00b)
+    ((?\" ?.) . ?\xe00c)
+    ((?\" ?:) . ?\xe00d)
+    ((?\" ?0) . ?\xe00e)
+    ((?\" ?\") . ?\xe00f)
+    ((?\" ?<) . ?\xe010)
+    ((?\" ?,) . ?\xe011)
+    ((?\" ?\;) . ?\xe012)
+    ((?\" ?_) . ?\xe013)
+    ((?\" ?=) . ?\xe014)
+    ((?\" ?/) . ?\xe015)
+    ((?\" ?i) . ?\xe016)
+    ((?\" ?d) . ?\xe017)
+    ((?\" ?p) . ?\xe018)
+    ((?\; ?\;) . ?\xe019)
+    ((?, ?,) . ?\xe01a)
+    ((?b ?3) . ?\xe01b)
+    ((?C ?i) . ?\xe01c)
+    ((?f ?\() . ?\xe01d)
+    ((?e ?d) . ?\xe01e)
+    ((?a ?m) . ?\xe01f)
+    ((?p ?m) . ?\xe020)
+    ((?F ?l) . ?\xe023)
+    ((?G ?F) . ?\xe024)
+    ((?> ?V) . ?\xe025)
+    ((?! ?*) . ?\xe026)
+    ((?? ?*) . ?\xe027)
+    ((?J ?<) . ?\xe028)
+    ((?f ?f) . ?\xfb00)
+    ((?f ?i) . ?\xfb01)
+    ((?f ?l) . ?\xfb02)
+    ((?f ?t) . ?\xfb05)
+    ((?s ?t) . ?\xfb06)
+    ((?~ ?!) . ?\x00a1)
+    ((?c ?|) . ?\x00a2)
+    ((?$ ?$) . ?\x00a3)
+    ((?o ?x) . ?\x00a4)
+    ((?Y ?-) . ?\x00a5)
+    ((?| ?|) . ?\x00a6)
+    ((?c ?O) . ?\x00a9)
+    ((?- ?,) . ?\x00ac)
+    ((?- ?=) . ?\x00af)
+    ((?~ ?o) . ?\x00b0)
+    ((?2 ?2) . ?\x00b2)
+    ((?3 ?3) . ?\x00b3)
+    ((?p ?p) . ?\x00b6)
+    ((?~ ?.) . ?\x00b7)
+    ((?1 ?1) . ?\x00b9)
+    ((?~ ??) . ?\x00bf)
+    ((?A ?`) . ?\x00c0)
+    ((?A ?^) . ?\x00c2)
+    ((?A ?~) . ?\x00c3)
+    ((?A ?\") . ?\x00c4)
+    ((?A ?@) . ?\x00c5)
+    ((?E ?`) . ?\x00c8)
+    ((?E ?^) . ?\x00ca)
+    ((?E ?\") . ?\x00cb)
+    ((?I ?`) . ?\x00cc)
+    ((?I ?^) . ?\x00ce)
+    ((?I ?\") . ?\x00cf)
+    ((?N ?~) . ?\x00d1)
+    ((?O ?`) . ?\x00d2)
+    ((?O ?^) . ?\x00d4)
+    ((?O ?~) . ?\x00d5)
+    ((?/ ?\\) . ?\x00d7)
+    ((?U ?`) . ?\x00d9)
+    ((?U ?^) . ?\x00db)
+    ((?I ?p) . ?\x00de)
+    ((?a ?`) . ?\x00e0)
+    ((?a ?^) . ?\x00e2)
+    ((?a ?~) . ?\x00e3)
+    ((?a ?\") . ?\x00e4)
+    ((?a ?@) . ?\x00e5)
+    ((?e ?`) . ?\x00e8)
+    ((?e ?^) . ?\x00ea)
+    ((?e ?\") . ?\x00eb)
+    ((?i ?`) . ?\x00ec)
+    ((?i ?^) . ?\x00ee)
+    ((?n ?~) . ?\x00f1)
+    ((?o ?`) . ?\x00f2)
+    ((?o ?^) . ?\x00f4)
+    ((?o ?~) . ?\x00f5)
+    ((?u ?`) . ?\x00f9)
+    ((?u ?^) . ?\x00fb)
+    ((?y ?\") . ?\x00ff))
+  "Table of default digraphs.
+This includes all digraphs defined in RFC 1345,
+as well as miscellaneous digraphs for multi-byte characters.
+See also `evil-digraphs-table-user'.")
+
+(defun evil-digraph (digraph)
+  "Convert DIGRAPH to character or list representation.
+If DIGRAPH is a list (CHAR1 CHAR2), return the corresponding character;
+if DIGRAPH is a character, return the corresponding list.
+Searches in `evil-digraphs-table-user' and `evil-digraphs-table'."
+  (if (listp digraph)
+      (let* ((char1 (car digraph))
+             (char2 (cadr digraph)))
+        (or (cdr (assoc (list char1 char2) evil-digraphs-table-user))
+            (cdr (assoc (list char1 char2) evil-digraphs-table))
+            (unless (eq char1 char2)
+              (or (cdr (assoc (list char2 char1) evil-digraphs-table-user))
+                  (cdr (assoc (list char2 char1) evil-digraphs-table))))))
+    (or (car (rassoc digraph evil-digraphs-table-user))
+        (car (rassoc digraph evil-digraphs-table)))))
+
+(provide 'evil-digraphs)
+
+;;; evil-digraphs.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-digraphs.elc b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-digraphs.elc
new file mode 100644
index 0000000000..7a79188023
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-digraphs.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-ex.el b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-ex.el
new file mode 100644
index 0000000000..894d8c1bf4
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-ex.el
@@ -0,0 +1,1163 @@
+;;; evil-ex.el --- Ex-mode
+
+;; Author: Frank Fischer <frank fischer at mathematik.tu-chemnitz.de>
+;; Maintainer: Vegard Øye <vegard_oye at hotmail.com>
+
+;; Version: 1.2.13
+
+;;
+;; This file is NOT part of GNU Emacs.
+
+;;; License:
+
+;; This file is part of Evil.
+;;
+;; Evil 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.
+;;
+;; Evil 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 Evil.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Ex is implemented as an extensible minilanguage, whose grammar
+;; is stored in `evil-ex-grammar'.  Ex commands are defined with
+;; `evil-ex-define-cmd', which creates a binding from a string
+;; to an interactive function.  It is also possible to define key
+;; sequences which execute a command immediately when entered:
+;; such shortcuts go in `evil-ex-map'.
+;;
+;; To provide buffer and filename completion, as well as interactive
+;; feedback, Ex defines the concept of an argument handler, specified
+;; with `evil-ex-define-argument-type'.  In the case of the
+;; substitution command (":s/foo/bar"), the handler incrementally
+;; highlights matches in the buffer as the substitution is typed.
+
+(require 'evil-common)
+(require 'evil-states)
+(require 'shell)
+
+;;; Code:
+
+(defconst evil-ex-grammar
+  '((expression
+     (count command argument #'evil-ex-call-command)
+     ((\? range) command argument #'evil-ex-call-command)
+     (line #'evil-goto-line)
+     (sexp #'eval-expression))
+    (count
+     number)
+    (command #'evil-ex-parse-command)
+    (binding
+     "[~&*@<>=:]+\\|[[:alpha:]-]+\\|!")
+    (emacs-binding
+     "[[:alpha:]-][[:alnum:][:punct:]-]+")
+    (bang
+     (\? (! space) "!" #'$1))
+    (argument
+     ((\? space) (\? "\\(?:.\\|\n\\)+") #'$2))
+    (range
+     ("%" #'(evil-ex-full-range))
+     (line ";" line #'(let ((tmp1 $1))
+                        (save-excursion
+                          (goto-line tmp1)
+                          (evil-ex-range tmp1 $3))))
+     (line "," line #'(evil-ex-range $1 $3))
+     (line #'(evil-ex-range $1 nil))
+     ("`" "[-a-zA-Z_<>']" ",`" "[-a-zA-Z_<>']"
+      #'(evil-ex-char-marker-range $2 $4)))
+    (line
+     (base (\? offset) search (\? offset)
+           #'(let ((tmp (evil-ex-line $1 $2)))
+               (save-excursion
+                 (goto-line tmp)
+                 (evil-ex-line $3 $4))))
+     ((\? base) offset search (\? offset)
+      #'(let ((tmp (evil-ex-line $1 $2)))
+          (save-excursion
+            (goto-line tmp)
+            (evil-ex-line $3 $4))))
+     (base (\? offset) #'evil-ex-line)
+     ((\? base) offset #'evil-ex-line))
+    (base
+     number
+     marker
+     search
+     ("\\^" #'(evil-ex-first-line))
+     ("\\$" #'(evil-ex-last-line))
+     ("\\." #'(evil-ex-current-line)))
+    (offset
+     (+ signed-number #'+))
+    (marker
+     ("'" "[-a-zA-Z_<>']" #'(evil-ex-marker $2)))
+    (search
+     forward
+     backward
+     next
+     prev
+     subst)
+    (forward
+     ("/" "\\(?:[\\].\\|[^/,; ]\\)+" (! "/")
+      #'(evil-ex-re-fwd $2))
+     ("/" "\\(?:[\\].\\|[^/]\\)+" "/"
+      #'(evil-ex-re-fwd $2)))
+    (backward
+     ("\\?" "\\(?:[\\].\\|[^?,; ]\\)+" (! "\\?")
+      #'(evil-ex-re-bwd $2))
+     ("\\?" "\\(?:[\\].\\|[^?]\\)+" "\\?"
+      #'(evil-ex-re-bwd $2)))
+    (next
+     "\\\\/" #'(evil-ex-prev-search))
+    (prev
+     "\\\\\\?" #'(evil-ex-prev-search))
+    (subst
+     "\\\\&" #'(evil-ex-prev-search))
+    (signed-number
+     (sign (\? number) #'evil-ex-signed-number))
+    (sign
+     "\\+\\|-" #'intern)
+    (number
+     "[0-9]+" #'string-to-number)
+    (space
+     "[ ]+")
+    (sexp
+     "(.*)" #'(car-safe (read-from-string $1))))
+  "Grammar for Ex.
+An association list of syntactic symbols and their definitions.
+The first entry is the start symbol.  A symbol's definition may
+reference other symbols, but the grammar cannot contain
+left recursion.  See `evil-parser' for a detailed explanation
+of the syntax.")
+
+(defvar evil-ex-echo-overlay nil
+  "Overlay used for displaying info messages during ex.")
+
+(defun evil-ex-p ()
+  "Whether Ex is currently active."
+  (and evil-ex-current-buffer t))
+
+(evil-define-command evil-ex (&optional initial-input)
+  "Enter an Ex command.
+The ex command line is initialized with the value of
+INITIAL-INPUT. If the command is called interactively the initial
+input depends on the current state. If the current state is
+normal state and no count argument is given then the initial
+input is empty. If a prefix count is given the initial input is
+.,.+count. If the current state is visual state then the initial
+input is the visual region '<,'> or `<,`>. If the value of the
+global variable `evil-ex-initial-input' is non-nil, its content
+is appended to the line."
+  :keep-visual t
+  :repeat abort
+  (interactive
+   (list
+    (let ((s (concat
+              (cond
+               ((and (evil-visual-state-p)
+                     evil-ex-visual-char-range
+                     (memq (evil-visual-type) '(inclusive exclusive)))
+                "`<,`>")
+               ((evil-visual-state-p)
+                "'<,'>")
+               (current-prefix-arg
+                (let ((arg (prefix-numeric-value current-prefix-arg)))
+                  (cond ((< arg 0) (setq arg (1+ arg)))
+                        ((> arg 0) (setq arg (1- arg))))
+                  (if (= arg 0) '(".")
+                    (format ".,.%+d" arg)))))
+              evil-ex-initial-input)))
+      (and (> (length s) 0) s))))
+  (let ((evil-ex-current-buffer (current-buffer))
+        (evil-ex-previous-command (unless initial-input
+                                    (car-safe evil-ex-history)))
+        evil-ex-argument-handler
+        evil-ex-info-string
+        result)
+    (minibuffer-with-setup-hook
+        (if initial-input #'evil-ex-setup-and-update #'evil-ex-setup)
+      (setq result
+            (read-from-minibuffer
+             ":"
+             (or initial-input
+                 (and evil-ex-previous-command
+                      (propertize evil-ex-previous-command 'face 'shadow)))
+             evil-ex-completion-map
+             nil
+             'evil-ex-history
+             evil-ex-previous-command
+             t)))
+    (evil-ex-execute result)))
+
+(defun evil-ex-execute (result)
+  "Execute RESULT as an ex command on `evil-ex-current-buffer'."
+  ;; empty input means repeating the previous command
+  (when (zerop (length result))
+    (setq result evil-ex-previous-command))
+  ;; parse data
+  (evil-ex-update nil nil nil result)
+  ;; execute command
+  (unless (zerop (length result))
+    (if evil-ex-expression
+        (eval evil-ex-expression)
+      (user-error "Ex: syntax error"))))
+
+(defun evil-ex-delete-backward-char ()
+  "Close the minibuffer if it is empty.
+Otherwise behaves like `delete-backward-char'."
+  (interactive)
+  (call-interactively
+   (if (zerop (length (minibuffer-contents)))
+       #'abort-recursive-edit
+     #'delete-backward-char)))
+
+(defun evil-ex-abort ()
+  "Cancel ex state when another buffer is selected."
+  (unless (minibufferp)
+    (abort-recursive-edit)))
+
+(defun evil-ex-setup ()
+  "Initialize Ex minibuffer.
+This function registers several hooks that are used for the
+interactive actions during ex state."
+  (add-hook 'post-command-hook #'evil-ex-abort)
+  (add-hook 'after-change-functions #'evil-ex-update nil t)
+  (add-hook 'minibuffer-exit-hook #'evil-ex-teardown)
+  (when evil-ex-previous-command
+    (add-hook 'pre-command-hook #'evil-ex-remove-default))
+  (remove-hook 'minibuffer-setup-hook #'evil-ex-setup)
+  (with-no-warnings
+    (make-variable-buffer-local 'completion-at-point-functions))
+  (setq completion-at-point-functions
+        '(evil-ex-command-completion-at-point
+          evil-ex-argument-completion-at-point)))
+(put 'evil-ex-setup 'permanent-local-hook t)
+
+(defun evil-ex-setup-and-update ()
+  "Initialize Ex minibuffer with `evil-ex-setup', then call `evil-ex-update'."
+  (evil-ex-setup)
+  (evil-ex-update))
+
+(defun evil-ex-teardown ()
+  "Deinitialize Ex minibuffer.
+Clean up everything set up by `evil-ex-setup'."
+  (remove-hook 'post-command-hook #'evil-ex-abort)
+  (remove-hook 'minibuffer-exit-hook #'evil-ex-teardown)
+  (remove-hook 'after-change-functions #'evil-ex-update t)
+  (when evil-ex-argument-handler
+    (let ((runner (evil-ex-argument-handler-runner
+                   evil-ex-argument-handler)))
+      (when runner
+        (funcall runner 'stop)))))
+(put 'evil-ex-teardown 'permanent-local-hook t)
+
+(defun evil-ex-remove-default ()
+  "Remove the default text shown in the ex minibuffer.
+When ex starts, the previous command is shown enclosed in
+parenthesis. This function removes this text when the first key
+is pressed."
+  (when (and (not (eq this-command 'exit-minibuffer))
+             (/= (minibuffer-prompt-end) (point-max)))
+    (if (eq this-command 'evil-ex-delete-backward-char)
+        (setq this-command 'ignore))
+    (delete-minibuffer-contents))
+  (remove-hook 'pre-command-hook #'evil-ex-remove-default))
+(put 'evil-ex-remove-default 'permanent-local-hook t)
+
+(defun evil-ex-update (&optional beg end len string)
+  "Update Ex variables when the minibuffer changes.
+This function is usually called from `after-change-functions'
+hook. If BEG is non-nil (which is the case when called from
+`after-change-functions'), then an error description is shown
+in case of incomplete or unknown commands."
+  (let* ((prompt (minibuffer-prompt-end))
+         (string (or string (buffer-substring prompt (point-max))))
+         arg bang cmd count expr func handler range tree type)
+    (cond
+     ((and (eq this-command #'self-insert-command)
+           (commandp (setq cmd (lookup-key evil-ex-map string))))
+      (setq evil-ex-expression `(call-interactively #',cmd))
+      (when (minibufferp)
+        (exit-minibuffer)))
+     (t
+      (setq cmd nil)
+      ;; store the buffer position of each character
+      ;; as the `ex-index' text property
+      (dotimes (i (length string))
+        (add-text-properties
+         i (1+ i) (list 'ex-index (+ i prompt)) string))
+      (with-current-buffer evil-ex-current-buffer
+        (setq tree (evil-ex-parse string t)
+              expr (evil-ex-parse string))
+        (when (eq (car-safe expr) 'evil-ex-call-command)
+          (setq count (eval (nth 1 expr))
+                cmd (eval (nth 2 expr))
+                arg (eval (nth 3 expr))
+                range (cond
+                       ((evil-range-p count)
+                        count)
+                       ((numberp count)
+                        (evil-ex-range count count)))
+                bang (and (save-match-data (string-match ".!$" cmd)) t))))
+      (setq evil-ex-tree tree
+            evil-ex-expression expr
+            evil-ex-range range
+            evil-ex-cmd cmd
+            evil-ex-bang bang
+            evil-ex-argument arg)
+      ;; test the current command
+      (when (and cmd (minibufferp))
+        (setq func (evil-ex-completed-binding cmd t))
+        (cond
+         ;; update argument-handler
+         (func
+          (when (setq type (evil-get-command-property
+                            func :ex-arg))
+            (setq handler (cdr-safe
+                           (assoc type
+                                  evil-ex-argument-types))))
+          (unless (eq handler evil-ex-argument-handler)
+            (let ((runner (and evil-ex-argument-handler
+                               (evil-ex-argument-handler-runner
+                                evil-ex-argument-handler))))
+              (when runner (funcall runner 'stop)))
+            (setq evil-ex-argument-handler handler)
+            (let ((runner (and evil-ex-argument-handler
+                               (evil-ex-argument-handler-runner
+                                evil-ex-argument-handler))))
+              (when runner (funcall runner 'start evil-ex-argument))))
+          (let ((runner (and evil-ex-argument-handler
+                             (evil-ex-argument-handler-runner
+                              evil-ex-argument-handler))))
+            (when runner (funcall runner 'update evil-ex-argument))))
+         (beg
+          ;; show error message only when called from `after-change-functions'
+          (let ((n (length (all-completions cmd (evil-ex-completion-table)))))
+            (cond
+             ((> n 1) (evil-ex-echo "Incomplete command"))
+             ((= n 0) (evil-ex-echo "Unknown command")))))))))))
+(put 'evil-ex-update 'permanent-local-hook t)
+
+(defun evil-ex-echo (string &rest args)
+  "Display a message after the current Ex command."
+  (with-selected-window (minibuffer-window)
+    (with-current-buffer (window-buffer (minibuffer-window))
+      (unless (or evil-no-display
+                  (zerop (length string)))
+        (let ((string (format " [%s]" (apply #'format string args)))
+              (ov (or evil-ex-echo-overlay
+                      (setq evil-ex-echo-overlay (make-overlay (point-min) (point-max) nil t t))))
+              after-change-functions before-change-functions)
+          (put-text-property 0 (length string) 'face 'evil-ex-info string)
+          ;; The following 'trick' causes point to be shown before the
+          ;; message instead behind. It is shamelessly stolen from the
+          ;; implementation of `minibuffer-message`.
+          (put-text-property 0 1 'cursor t string)
+          (move-overlay ov (point-max) (point-max))
+          (overlay-put ov 'after-string string)
+          (add-hook 'pre-command-hook #'evil--ex-remove-echo-overlay nil t))))))
+
+(defun evil--ex-remove-echo-overlay ()
+  "Remove echo overlay from ex minibuffer."
+  (when evil-ex-echo-overlay
+    (delete-overlay evil-ex-echo-overlay)
+    (setq evil-ex-echo-overlay nil))
+  (remove-hook 'pre-command-hook 'evil--ex-remove-echo-overlay t))
+
+(defun evil-ex-completion ()
+  "Completes the current ex command or argument."
+  (interactive)
+  (let (after-change-functions)
+    (evil-ex-update)
+    (completion-at-point)
+    (remove-text-properties (minibuffer-prompt-end) (point-max) '(face nil evil))))
+
+(defun evil-ex-command-completion-at-point ()
+  (let ((context (evil-ex-syntactic-context (1- (point)))))
+    (when (memq 'command context)
+      (let ((beg (or (get-text-property 0 'ex-index evil-ex-cmd)
+                     (point)))
+            (end (1+ (or (get-text-property (1- (length evil-ex-cmd))
+                                            'ex-index
+                                            evil-ex-cmd)
+                         (1- (point))))))
+        (list beg end (evil-ex-completion-table))))))
+
+(defun evil-ex-completion-table ()
+  (cond
+   ((eq evil-ex-complete-emacs-commands nil)
+    #'evil-ex-command-collection)
+   ((eq evil-ex-complete-emacs-commands 'in-turn)
+    (completion-table-in-turn
+     #'evil-ex-command-collection
+     #'(lambda (str pred flag)
+         (completion-table-with-predicate
+          obarray #'commandp t str pred flag))))
+   (t
+    #'(lambda (str pred flag)
+        (evil-completion-table-concat
+         #'evil-ex-command-collection
+         #'(lambda (str pred flag)
+             (completion-table-with-predicate
+              obarray #'commandp t str pred flag))
+         str pred flag)))))
+
+(defun evil-completion-table-concat (table1 table2 string pred flag)
+  (cond
+   ((eq flag nil)
+    (let ((result1 (try-completion string table1 pred))
+          (result2 (try-completion string table2 pred)))
+      (cond
+       ((null result1) result2)
+       ((null result2) result1)
+       ((and (eq result1 t) (eq result2 t)) t)
+       (t result1))))
+   ((eq flag t)
+    (delete-dups
+     (append (all-completions string table1 pred)
+             (all-completions string table2 pred))))
+   ((eq flag 'lambda)
+    (and (or (eq t (test-completion string table1 pred))
+             (eq t (test-completion string table2 pred)))
+         t))
+   ((eq (car-safe flag) 'boundaries)
+    (or (completion-boundaries string table1 pred (cdr flag))
+        (completion-boundaries string table2 pred (cdr flag))))
+   ((eq flag 'metadata)
+    '(metadata (display-sort-function . evil-ex-sort-completions)))))
+
+(defun evil-ex-sort-completions (completions)
+  (sort completions
+        #'(lambda (str1 str2)
+            (let ((p1 (eq 'evil-ex-commands (get-text-property 0 'face str1)))
+                  (p2 (eq 'evil-ex-commands (get-text-property 0 'face str2))))
+              (if (equal p1 p2)
+                  (string< str1 str2)
+                p1)))))
+
+(defun evil-ex-command-collection (cmd predicate flag)
+  "Called to complete a command."
+  (let (commands)
+    ;; append ! to all commands that may take a bang argument
+    (dolist (cmd (mapcar #'car evil-ex-commands))
+      (push cmd commands)
+      (if (evil-ex-command-force-p cmd)
+          (push (concat cmd "!") commands)))
+    (when (eq evil-ex-complete-emacs-commands t)
+      (setq commands
+            (mapcar #'(lambda (str) (propertize str 'face 'evil-ex-commands))
+                    commands)))
+    (cond
+     ((eq flag nil) (try-completion cmd commands predicate))
+     ((eq flag t) (all-completions cmd commands predicate))
+     ((eq flag 'lambda) (test-completion cmd commands))
+     ((eq (car-safe flag) 'boundaries)
+      `(boundaries 0 . ,(length (cdr flag)))))))
+
+(defun evil-ex-argument-completion-at-point ()
+  (let ((context (evil-ex-syntactic-context (1- (point)))))
+    (when (memq 'argument context)
+      ;; if it's an autoload, load the function; this allows external
+      ;; packages to register autoloaded ex commands which will be
+      ;; loaded when ex argument completion is triggered
+      (let ((binding-definition (symbol-function (evil-ex-binding evil-ex-cmd))))
+        (when (autoloadp binding-definition)
+          (autoload-do-load binding-definition)))
+
+      (let* ((beg (or (and evil-ex-argument
+                           (get-text-property 0 'ex-index evil-ex-argument))
+                      (point)))
+             (end (1+ (or (and evil-ex-argument
+                               (get-text-property (1- (length evil-ex-argument))
+                                                  'ex-index
+                                                  evil-ex-argument))
+                          (1- (point)))))
+             (binding (evil-ex-completed-binding evil-ex-cmd))
+             (arg-type (evil-get-command-property binding :ex-arg))
+             (arg-handler (assoc arg-type evil-ex-argument-types))
+             (completer (and arg-handler
+                             (evil-ex-argument-handler-completer
+                              (cdr arg-handler)))))
+        (when completer
+          (if (eq (car completer) 'collection)
+              (list beg end (cdr completer))
+            (save-restriction
+              (narrow-to-region beg (point-max))
+              (funcall (cdr completer)))))))))
+
+(defun evil-ex-define-cmd (cmd function)
+  "Binds the function FUNCTION to the command CMD."
+  (save-match-data
+    (if (string-match "^[^][]*\\(\\[\\(.*\\)\\]\\)[^][]*$" cmd)
+        (let ((abbrev (replace-match "" nil t cmd 1))
+              (full (replace-match "\\2" nil nil cmd 1)))
+          (evil-add-to-alist 'evil-ex-commands full function)
+          (evil-add-to-alist 'evil-ex-commands abbrev full))
+      (evil-add-to-alist 'evil-ex-commands cmd function))))
+
+(defun evil-ex-make-argument-handler (runner completer)
+  (list runner completer))
+
+(defun evil-ex-argument-handler-runner (arg-handler)
+  (car arg-handler))
+
+(defun evil-ex-argument-handler-completer (arg-handler)
+  (cadr arg-handler))
+
+(defmacro evil-ex-define-argument-type (arg-type doc &rest body)
+  "Defines a new handler for argument-type ARG-TYPE.
+DOC is the documentation string. It is followed by a list of
+keywords and function:
+
+:collection COLLECTION
+
+  A collection for completion as required by `all-completions'.
+
+:completion-at-point FUNC
+
+  Function to be called to initialize a potential
+  completion. FUNC must match the requirements as described for
+  the variable `completion-at-point-functions'. When FUNC is
+  called the minibuffer content is narrowed to exactly match the
+  argument.
+
+:runner FUNC
+
+  Function to be called when the type of the current argument
+  changes or when the content of this argument changes. This
+  function should take one obligatory argument FLAG followed by
+  an optional argument ARG. FLAG is one of three symbol 'start,
+  'stop or 'update. When the argument type is recognized for the
+  first time and this handler is started the FLAG is 'start. If
+  the argument type changes to something else or ex state
+  finished the handler FLAG is 'stop. If the content of the
+  argument has changed FLAG is 'update. If FLAG is either 'start
+  or 'update then ARG is the current value of this argument. If
+  FLAG is 'stop then arg is nil."
+  (declare (indent defun)
+           (debug (&define name
+                           [&optional stringp]
+                           [&rest [keywordp function-form]])))
+  (unless (stringp doc) (push doc body))
+  (let (runner completer)
+    (while (keywordp (car-safe body))
+      (let ((key (pop body))
+            (func (pop body)))
+        (cond
+         ((eq key :runner)
+          (setq runner func))
+         ((eq key :collection)
+          (setq completer (cons 'collection func)))
+         ((eq key :completion-at-point)
+          (setq completer (cons 'completion-at-point func))))))
+    `(eval-and-compile
+       (evil-add-to-alist
+        'evil-ex-argument-types
+        ',arg-type
+        '(,runner ,completer)))))
+
+(evil-ex-define-argument-type file
+  "Handles a file argument."
+  :collection read-file-name-internal)
+
+(evil-ex-define-argument-type buffer
+  "Called to complete a buffer name argument."
+  :collection internal-complete-buffer)
+
+(declare-function shell-completion-vars "shell" ())
+
+(defun evil-ex-init-shell-argument-completion (flag &optional arg)
+  "Prepares the current minibuffer for completion of shell commands.
+This function must be called from the :runner function of some
+argument handler that requires shell completion."
+  (when (and (eq flag 'start)
+             (not evil-ex-shell-argument-initialized))
+    (set (make-local-variable 'evil-ex-shell-argument-initialized) t)
+    (cond
+     ;; Emacs 24
+     ((fboundp 'comint-completion-at-point)
+      (shell-completion-vars))
+     (t
+      (set (make-local-variable 'minibuffer-default-add-function)
+           'minibuffer-default-add-shell-commands)))
+    (setq completion-at-point-functions
+          '(evil-ex-command-completion-at-point
+            evil-ex-argument-completion-at-point))))
+
+(define-obsolete-function-alias
+  'evil-ex-shell-command-completion-at-point
+  'comint-completion-at-point)
+
+(evil-ex-define-argument-type shell
+  "Shell argument type, supports completion."
+  :completion-at-point comint-completion-at-point
+  :runner evil-ex-init-shell-argument-completion)
+
+(defun evil-ex-file-or-shell-command-completion-at-point ()
+  (if (and (< (point-min) (point-max))
+           (= (char-after (point-min)) ?!))
+      (save-restriction
+        (narrow-to-region (1+ (point-min)) (point-max))
+        (comint-completion-at-point))
+    (list (point-min) (point-max) #'read-file-name-internal)))
+
+(evil-ex-define-argument-type file-or-shell
+  "File or shell argument type.
+If the current argument starts with a ! the rest of the argument
+is considered a shell command, otherwise a file-name. Completion
+works accordingly."
+  :completion-at-point evil-ex-file-or-shell-command-completion-at-point
+  :runner evil-ex-init-shell-argument-completion)
+
+(defun evil-ex-binding (command &optional noerror)
+  "Returns the final binding of COMMAND."
+  (save-match-data
+    (let ((binding command))
+      (when binding
+        (string-match "^\\(.+?\\)\\!?$" binding)
+        (setq binding (match-string 1 binding))
+        (while (progn
+                 (setq binding (cdr (assoc binding evil-ex-commands)))
+                 (stringp binding)))
+        (unless binding
+          (setq binding (intern command)))
+        (if (commandp binding)
+            ;; check for remaps
+            (or (command-remapping binding) binding)
+          (unless noerror
+            (user-error "Unknown command: `%s'" command)))))))
+
+(defun evil-ex-completed-binding (command &optional noerror)
+  "Returns the final binding of the completion of COMMAND."
+  (let ((completion (try-completion command evil-ex-commands)))
+    (evil-ex-binding (if (eq completion t) command
+                       (or completion command))
+                     noerror)))
+
+;;; TODO: extensions likes :p :~ <cfile> ...
+(defun evil-ex-replace-special-filenames (file-name)
+  "Replace special symbols in FILE-NAME.
+Replaces % by the current file-name,
+Replaces # by the alternate file-name in FILE-NAME."
+  (let ((current-fname (buffer-file-name))
+        (alternate-fname (and (other-buffer)
+                              (buffer-file-name (other-buffer)))))
+    (when current-fname
+      (setq file-name
+            (replace-regexp-in-string "\\(^\\|[^\\\\]\\)\\(%\\)"
+                                      current-fname file-name
+                                      t t 2)))
+    (when alternate-fname
+      (setq file-name
+            (replace-regexp-in-string "\\(^\\|[^\\\\]\\)\\(#\\)"
+                                      alternate-fname file-name
+                                      t t 2)))
+    (setq file-name
+          (replace-regexp-in-string "\\\\\\([#%]\\)"
+                                    "\\1" file-name t)))
+  file-name)
+
+(defun evil-ex-file-arg ()
+  "Returns the current Ex argument as a file name.
+This function interprets special file names like # and %."
+  (unless (or (null evil-ex-argument)
+              (zerop (length evil-ex-argument)))
+    (evil-ex-replace-special-filenames evil-ex-argument)))
+
+(defun evil-ex-repeat (count)
+  "Repeats the last ex command."
+  (interactive "P")
+  (when count
+    (goto-char (point-min))
+    (forward-line (1- count)))
+  (let ((evil-ex-current-buffer (current-buffer))
+        (hist evil-ex-history))
+    (while hist
+      (let ((evil-ex-last-cmd (pop hist)))
+        (when evil-ex-last-cmd
+          (evil-ex-update nil nil nil evil-ex-last-cmd)
+          (let ((binding (evil-ex-binding evil-ex-cmd)))
+            (unless (eq binding #'evil-ex-repeat)
+              (setq hist nil)
+              (if evil-ex-expression
+                  (eval evil-ex-expression)
+                (user-error "Ex: syntax error")))))))))
+
+(defun evil-ex-call-command (range command argument)
+  "Execute the given command COMMAND."
+  (let* ((count (when (numberp range) range))
+         (range (when (evil-range-p range) range))
+         (bang (and (save-match-data (string-match ".!$" command)) t))
+         (evil-ex-point (point))
+         (evil-ex-range
+          (or range (and count (evil-ex-range count count))))
+         (evil-ex-command (evil-ex-completed-binding command))
+         (evil-ex-bang (and bang t))
+         (evil-ex-argument (copy-sequence argument))
+         (evil-this-type (evil-type evil-ex-range))
+         (current-prefix-arg count)
+         (prefix-arg current-prefix-arg))
+    (when (stringp evil-ex-argument)
+      (set-text-properties
+       0 (length evil-ex-argument) nil evil-ex-argument))
+    (let ((buf (current-buffer)))
+      (unwind-protect
+          (cond
+           ((not evil-ex-range)
+            (setq this-command evil-ex-command)
+            (run-hooks 'pre-command-hook)
+            (call-interactively evil-ex-command)
+            (run-hooks 'post-command-hook))
+           (t
+            ;; set visual selection to match the region if an explicit
+            ;; range has been specified
+            (let ((ex-range (evil-copy-range evil-ex-range))
+                  beg end)
+              (evil-expand-range ex-range)
+              (setq beg (evil-range-beginning ex-range)
+                    end (evil-range-end ex-range))
+              (evil-sort beg end)
+              (setq this-command evil-ex-command)
+              (run-hooks 'pre-command-hook)
+              (set-mark end)
+              (goto-char beg)
+              (activate-mark)
+              (call-interactively evil-ex-command)
+              (run-hooks 'post-command-hook))))
+        (when (buffer-live-p buf)
+          (with-current-buffer buf
+            (deactivate-mark)))))))
+
+(defun evil-ex-line (base &optional offset)
+  "Return the line number of BASE plus OFFSET."
+  (+ (or base (line-number-at-pos))
+     (or offset 0)))
+
+(defun evil-ex-first-line ()
+  "Return the line number of the first line."
+  (line-number-at-pos (point-min)))
+
+(defun evil-ex-current-line ()
+  "Return the line number of the current line."
+  (line-number-at-pos (point)))
+
+(defun evil-ex-last-line ()
+  "Return the line number of the last line."
+  (save-excursion
+    (goto-char (point-max))
+    (when (bolp)
+      (forward-line -1))
+    (line-number-at-pos)))
+
+(defun evil-ex-range (beg-line &optional end-line)
+  "Returns the first and last position of the current range."
+  (evil-range
+   (evil-line-position beg-line)
+   (evil-line-position (or end-line beg-line) -1)
+   'line
+   :expanded t))
+
+(defun evil-ex-full-range ()
+  "Return a range encompassing the whole buffer."
+  (evil-range (point-min) (point-max) 'line))
+
+(defun evil-ex-marker (marker)
+  "Return MARKER's line number in the current buffer.
+Signal an error if MARKER is in a different buffer."
+  (when (stringp marker)
+    (setq marker (aref marker 0)))
+  (setq marker (evil-get-marker marker))
+  (if (numberp marker)
+      (line-number-at-pos marker)
+    (user-error "Ex does not support markers in other files")))
+
+(defun evil-ex-char-marker-range (beg end)
+  (when (stringp beg) (setq beg (aref beg 0)))
+  (when (stringp end) (setq end (aref end 0)))
+  (setq beg (evil-get-marker beg)
+        end (evil-get-marker end))
+  (if (and (numberp beg) (numberp end))
+      (evil-expand-range
+       (evil-range beg end
+                   (if (evil-visual-state-p)
+                       (evil-visual-type)
+                     'inclusive)))
+    (user-error "Ex does not support markers in other files")))
+
+(defun evil-ex-re-fwd (pattern)
+  "Search forward for PATTERN.
+Returns the line number of the match."
+  (condition-case err
+      (save-match-data
+        (save-excursion
+          (set-text-properties 0 (length pattern) nil pattern)
+          (evil-move-end-of-line)
+          (and (re-search-forward pattern nil t)
+               (line-number-at-pos (1- (match-end 0))))))
+    (invalid-regexp
+     (evil-ex-echo (cadr err))
+     nil)))
+
+(defun evil-ex-re-bwd (pattern)
+  "Search backward for PATTERN.
+Returns the line number of the match."
+  (condition-case err
+      (save-match-data
+        (save-excursion
+          (set-text-properties 0 (length pattern) nil pattern)
+          (evil-move-beginning-of-line)
+          (and (re-search-backward pattern nil t)
+               (line-number-at-pos (match-beginning 0)))))
+    (invalid-regexp
+     (evil-ex-echo (cadr err))
+     nil)))
+
+(defun evil-ex-prev-search ()
+  (error "Previous search not yet implemented"))
+
+(defun evil-ex-signed-number (sign &optional number)
+  "Return a signed number like -3 and +1.
+NUMBER defaults to 1."
+  (funcall sign (or number 1)))
+
+;; function `evil-ex-eval' has been superseded by `evil-ex-parse' plus `eval'
+(make-obsolete 'evil-ex-eval 'evil-ex-parse "1.2.14")
+
+(defun evil-ex-parse (string &optional syntax start)
+  "Parse STRING as an Ex expression and return an evaluation tree.
+If SYNTAX is non-nil, return a syntax tree instead.
+START is the start symbol, which defaults to `expression'."
+  (let* ((start (or start (car-safe (car-safe evil-ex-grammar))))
+         (match (evil-parser
+                 string start evil-ex-grammar t syntax)))
+    (car-safe match)))
+
+(defun evil-ex-parse-command (string)
+  "Parse STRING as an Ex binding."
+  (let ((result (evil-parser string 'binding evil-ex-grammar))
+        bang command)
+    (when result
+      (setq command (car-safe result)
+            string (cdr-safe result))
+      ;; check whether the parsed command is followed by a slash or
+      ;; number and the part before it is not a known ex binding
+      (when (and (> (length string) 0)
+                 (string-match-p "^[/[:digit:]]" string)
+                 (not (evil-ex-binding command t)))
+        ;; if this is the case, assume the slash or number and all
+        ;; following symbol characters form an (Emacs-)command
+        (setq result (evil-parser (concat command string)
+                                  'emacs-binding
+                                  evil-ex-grammar)
+              command (car-safe result)
+              string (cdr-safe result)))
+      ;; parse a following "!" as bang only if
+      ;; the command has the property :ex-bang t
+      (when (evil-ex-command-force-p command)
+        (setq result (evil-parser string 'bang evil-ex-grammar)
+              bang (or (car-safe result) "")
+              string (cdr-safe result)
+              command (concat command bang)))
+      (cons command string))))
+
+(defun evil-ex-command-force-p (command)
+  "Whether COMMAND accepts the bang argument."
+  (let ((binding (evil-ex-completed-binding command t)))
+    (when binding
+      (evil-get-command-property binding :ex-bang))))
+
+(defun evil-flatten-syntax-tree (tree)
+  "Find all paths from the root of TREE to its leaves.
+TREE is a syntax tree, i.e., all its leave nodes are strings.
+The `nth' element in the result is the syntactic context
+for the corresponding string index (counted from zero)."
+  (let* ((result nil)
+         (traverse nil)
+         (traverse
+          #'(lambda (tree path)
+              (if (stringp tree)
+                  (dotimes (char (length tree))
+                    (push path result))
+                (let ((path (cons (car tree) path)))
+                  (dolist (subtree (cdr tree))
+                    (funcall traverse subtree path)))))))
+    (funcall traverse tree nil)
+    (nreverse result)))
+
+(defun evil-ex-syntactic-context (&optional pos)
+  "Return the syntactical context of the character at POS.
+POS defaults to the current position of point."
+  (let* ((contexts (evil-flatten-syntax-tree evil-ex-tree))
+         (length (length contexts))
+         (pos (- (or pos (point)) (minibuffer-prompt-end))))
+    (when (>= pos length)
+      (setq pos (1- length)))
+    (when (< pos 0)
+      (setq pos 0))
+    (when contexts
+      (nth pos contexts))))
+
+(defun evil-parser (string symbol grammar &optional greedy syntax)
+  "Parse STRING as a SYMBOL in GRAMMAR.
+If GREEDY is non-nil, the whole of STRING must match.
+If the parse succeeds, the return value is a cons cell
+\(RESULT . TAIL), where RESULT is a parse tree and TAIL is
+the remainder of STRING. Otherwise, the return value is nil.
+
+GRAMMAR is an association list of symbols and their definitions.
+A definition is either a list of production rules, which are
+tried in succession, or a #'-quoted function, which is called
+to parse the input.
+
+A production rule can be one of the following:
+
+    nil matches the empty string.
+    A regular expression matches a substring.
+    A symbol matches a production for that symbol.
+    (X Y) matches X followed by Y.
+    (\\? X) matches zero or one of X.
+    (* X) matches zero or more of X.
+    (+ X) matches one or more of X.
+    (& X) matches X, but does not consume.
+    (! X) matches anything but X, but does not consume.
+
+Thus, a simple grammar may look like:
+
+    ((plus \"\\\\+\")           ; plus <- \"+\"
+     (minus \"-\")            ; minus <- \"-\"
+     (operator plus minus)) ; operator <- plus / minus
+
+All input-consuming rules have a value. A regular expression evaluates
+to the text matched, while a list evaluates to a list of values.
+The value of a list may be overridden with a semantic action, which is
+specified with a #'-quoted expression at the end:
+
+    (X Y #'foo)
+
+The value of this rule is the result of calling foo with the values
+of X and Y as arguments. Alternatively, the function call may be
+specified explicitly:
+
+    (X Y #'(foo $1 $2))
+
+Here, $1 refers to X and $2 refers to Y. $0 refers to the whole list.
+Dollar expressions can also be used directly:
+
+    (X Y #'$1)
+
+This matches X followed by Y, but ignores the value of Y;
+the value of the list is the same as the value of X.
+
+If the SYNTAX argument is non-nil, then all semantic actions
+are ignored, and a syntax tree is constructed instead. The
+syntax tree obeys the property that all the leave nodes are
+parts of the input string. Thus, by traversing the syntax tree,
+one can determine how each character was parsed.
+
+The following symbols have reserved meanings within a grammar:
+`\\?', `*', `+', `&', `!', `function', `alt', `seq' and nil."
+  (let ((string (or string ""))
+        func pair result rules tail)
+    (cond
+     ;; epsilon
+     ((member symbol '("" nil))
+      (setq pair (cons (if syntax "" nil) string)))
+     ;; token
+     ((stringp symbol)
+      (save-match-data
+        (when (or (eq (string-match symbol string) 0)
+                  ;; ignore leading whitespace
+                  (and (eq (string-match "^[ \f\t\n\r\v]+" string) 0)
+                       (eq (match-end 0)
+                           (string-match
+                            symbol string (match-end 0)))))
+          (setq result (match-string 0 string)
+                tail (substring string (match-end 0))
+                pair (cons result tail))
+          (when (and syntax pair)
+            (setq result (substring string 0
+                                    (- (length string)
+                                       (length tail))))
+            (setcar pair result)))))
+     ;; symbol
+     ((symbolp symbol)
+      (let ((context symbol))
+        (setq rules (cdr-safe (assq symbol grammar)))
+        (setq pair (evil-parser string `(alt ,@rules)
+                                grammar greedy syntax))
+        (when (and syntax pair)
+          (setq result (car pair))
+          (if (and (listp result) (sequencep (car result)))
+              (setq result `(,symbol ,@result))
+            (setq result `(,symbol ,result)))
+          (setcar pair result))))
+     ;; function
+     ((eq (car-safe symbol) 'function)
+      (setq symbol (cadr symbol)
+            pair (funcall symbol string))
+      (when (and syntax pair)
+        (setq tail (or (cdr pair) "")
+              result (substring string 0
+                                (- (length string)
+                                   (length tail))))
+        (setcar pair result)))
+     ;; list
+     ((listp symbol)
+      (setq rules symbol
+            symbol (car-safe rules))
+      (if (memq symbol '(& ! \? * + alt seq))
+          (setq rules (cdr rules))
+        (setq symbol 'seq))
+      (when (and (memq symbol '(+ alt seq))
+                 (> (length rules) 1))
+        (setq func (car (last rules)))
+        (if (eq (car-safe func) 'function)
+            (setq rules (delq func (copy-sequence rules))
+                  func (cadr func))
+          (setq func nil)))
+      (cond
+       ;; positive lookahead
+       ((eq symbol '&)
+        (when (evil-parser string rules grammar greedy syntax)
+          (setq pair (evil-parser string nil grammar nil syntax))))
+       ;; negative lookahead
+       ((eq symbol '!)
+        (unless (evil-parser string rules grammar greedy syntax)
+          (setq pair (evil-parser string nil grammar nil syntax))))
+       ;; zero or one
+       ((eq symbol '\?)
+        (setq rules (if (> (length rules) 1)
+                        `(alt ,rules nil)
+                      `(alt ,@rules nil))
+              pair (evil-parser string rules grammar greedy syntax)))
+       ;; zero or more
+       ((eq symbol '*)
+        (setq rules `(alt (+ ,@rules) nil)
+              pair (evil-parser string rules grammar greedy syntax)))
+       ;; one or more
+       ((eq symbol '+)
+        (let (current results)
+          (catch 'done
+            (while (setq current (evil-parser
+                                  string rules grammar nil syntax))
+              (setq result (car-safe current)
+                    tail (or (cdr-safe current) "")
+                    results (append results (if syntax result
+                                              (cdr-safe result))))
+              ;; stop if stuck
+              (if (equal string tail)
+                  (throw 'done nil)
+                (setq string tail))))
+          (when results
+            (setq func (or func 'list)
+                  pair (cons results tail)))))
+       ;; alternatives
+       ((eq symbol 'alt)
+        (catch 'done
+          (dolist (rule rules)
+            (when (setq pair (evil-parser
+                              string rule grammar greedy syntax))
+              (throw 'done pair)))))
+       ;; sequence
+       (t
+        (setq func (or func 'list))
+        (let ((last (car-safe (last rules)))
+              current results rule)
+          (catch 'done
+            (while rules
+              (setq rule (pop rules)
+                    current (evil-parser string rule grammar
+                                         (when greedy
+                                           (null rules))
+                                         syntax))
+              (cond
+               ((null current)
+                (setq results nil)
+                (throw 'done nil))
+               (t
+                (setq result (car-safe current)
+                      tail (cdr-safe current))
+                (unless (memq (car-safe rule) '(& !))
+                  (if (and syntax
+                           (or (null result)
+                               (and (listp result)
+                                    (listp rule)
+                                    ;; splice in single-element
+                                    ;; (\? ...) expressions
+                                    (not (and (eq (car-safe rule) '\?)
+                                              (eq (length rule) 2))))))
+                      (setq results (append results result))
+                    (setq results (append results (list result)))))
+                (setq string (or tail ""))))))
+          (when results
+            (setq pair (cons results tail))))))
+      ;; semantic action
+      (when (and pair func (not syntax))
+        (setq result (car pair))
+        (let* ((dexp
+                #'(lambda (obj)
+                    (when (symbolp obj)
+                      (let ((str (symbol-name obj)))
+                        (save-match-data
+                          (when (string-match "\\$\\([0-9]+\\)" str)
+                            (string-to-number (match-string 1 str))))))))
+               ;; traverse a tree for dollar expressions
+               (dval nil)
+               (dval
+                #'(lambda (obj)
+                    (if (listp obj)
+                        (mapcar dval obj)
+                      (let ((num (funcall dexp obj)))
+                        (if num
+                            (if (not (listp result))
+                                result
+                              (if (eq num 0)
+                                  `(list ,@result)
+                                (nth (1- num) result)))
+                          obj))))))
+          (cond
+           ((null func)
+            (setq result nil))
+           ;; lambda function
+           ((eq (car-safe func) 'lambda)
+            (if (memq symbol '(+ seq))
+                (setq result `(funcall ,func ,@result))
+              (setq result `(funcall ,func ,result))))
+           ;; string replacement
+           ((or (stringp func) (stringp (car-safe func)))
+            (let* ((symbol (or (car-safe (cdr-safe func))
+                               (and (boundp 'context) context)
+                               (car-safe (car-safe grammar))))
+                   (string (if (stringp func) func (car-safe func))))
+              (setq result (car-safe (evil-parser string symbol grammar
+                                                  greedy syntax)))))
+           ;; dollar expression
+           ((funcall dexp func)
+            (setq result (funcall dval func)))
+           ;; function call
+           ((listp func)
+            (setq result (funcall dval func)))
+           ;; symbol
+           (t
+            (if (memq symbol '(+ seq))
+                (setq result `(,func ,@result))
+              (setq result `(,func ,result))))))
+        (setcar pair result))))
+    ;; weed out incomplete matches
+    (when pair
+      (if (not greedy) pair
+        (if (null (cdr pair)) pair
+          ;; ignore trailing whitespace
+          (when (save-match-data (string-match "^[ \f\t\n\r\v]*$" (cdr pair)))
+            (unless syntax (setcdr pair nil))
+            pair))))))
+
+(provide 'evil-ex)
+
+;;; evil-ex.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-ex.elc b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-ex.elc
new file mode 100644
index 0000000000..5b393329a5
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-ex.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-integration.el b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-integration.el
new file mode 100644
index 0000000000..bc08611168
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-integration.el
@@ -0,0 +1,588 @@
+;;; evil-integration.el --- Integrate Evil with other modules
+
+;; Author: Vegard Øye <vegard_oye at hotmail.com>
+;; Maintainer: Vegard Øye <vegard_oye at hotmail.com>
+
+;; Version: 1.2.13
+
+;;
+;; This file is NOT part of GNU Emacs.
+
+;;; License:
+
+;; This file is part of Evil.
+;;
+;; Evil 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.
+;;
+;; Evil 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 Evil.  If not, see <http://www.gnu.org/licenses/>.
+
+(require 'evil-maps)
+(require 'evil-core)
+(require 'evil-macros)
+(require 'evil-types)
+(require 'evil-repeat)
+
+;;; Code:
+
+;;; Evilize some commands
+
+;; unbound keys should be ignored
+(evil-declare-ignore-repeat 'undefined)
+
+(mapc #'(lambda (cmd)
+          (evil-set-command-property cmd :keep-visual t)
+          (evil-declare-not-repeat cmd))
+      '(digit-argument
+        negative-argument
+        universal-argument
+        universal-argument-minus
+        universal-argument-more
+        universal-argument-other-key))
+(mapc #'evil-declare-not-repeat
+      '(what-cursor-position))
+(mapc #'evil-declare-change-repeat
+      '(dabbrev-expand
+        hippie-expand
+        quoted-insert))
+(mapc #'evil-declare-abort-repeat
+      '(balance-windows
+        eval-expression
+        execute-extended-command
+        exit-minibuffer
+        compile
+        delete-window
+        delete-other-windows
+        find-file-at-point
+        ffap-other-window
+        recompile
+        redo
+        save-buffer
+        split-window
+        split-window-horizontally
+        split-window-vertically
+        undo
+        undo-tree-redo
+        undo-tree-undo))
+
+(evil-set-type #'previous-line 'line)
+(evil-set-type #'next-line 'line)
+
+(dolist (cmd '(keyboard-quit keyboard-escape-quit))
+  (evil-set-command-property cmd :suppress-operator t))
+
+;;; Mouse
+(evil-declare-insert-at-point-repeat 'mouse-yank-primary)
+(evil-declare-insert-at-point-repeat 'mouse-yank-secondary)
+
+;;; key-binding
+
+;; Calling `keyboard-quit' should cancel repeat
+(defadvice keyboard-quit (before evil activate)
+  (when (fboundp 'evil-repeat-abort)
+    (evil-repeat-abort)))
+
+;; etags-select
+;; FIXME: probably etags-select should be recomended in docs
+(eval-after-load 'etags-select
+  '(progn
+     (define-key evil-motion-state-map "g]" 'etags-select-find-tag-at-point)))
+
+;;; Buffer-menu
+
+(evil-add-hjkl-bindings Buffer-menu-mode-map 'motion)
+
+;; dictionary.el
+
+(evil-add-hjkl-bindings dictionary-mode-map 'motion
+  "?" 'dictionary-help        ; "h"
+  "C-o" 'dictionary-previous) ; "l"
+
+;;; Dired
+
+(eval-after-load 'dired
+  '(progn
+     ;; use the standard Dired bindings as a base
+     (defvar dired-mode-map)
+     (evil-make-overriding-map dired-mode-map 'normal)
+     (evil-add-hjkl-bindings dired-mode-map 'normal
+       "J" 'dired-goto-file                   ; "j"
+       "K" 'dired-do-kill-lines               ; "k"
+       "r" 'dired-do-redisplay                ; "l"
+       ;; ":d", ":v", ":s", ":e"
+       ";" (lookup-key dired-mode-map ":"))))
+
+(eval-after-load 'wdired
+  '(progn
+     (add-hook 'wdired-mode-hook #'evil-change-to-initial-state)
+     (defadvice wdired-change-to-dired-mode (after evil activate)
+       (evil-change-to-initial-state nil t))))
+
+;;; ELP
+
+(eval-after-load 'elp
+  '(defadvice elp-results (after evil activate)
+     (evil-motion-state)))
+
+;;; ERT
+
+(evil-add-hjkl-bindings ert-results-mode-map 'motion)
+
+;;; Info
+
+(evil-add-hjkl-bindings Info-mode-map 'motion
+  "0" 'evil-digit-argument-or-evil-beginning-of-line
+  (kbd "\M-h") 'Info-help   ; "h"
+  "\C-t" 'Info-history-back ; "l"
+  "\C-o" 'Info-history-back
+  " " 'Info-scroll-up
+  "\C-]" 'Info-follow-nearest-node
+  (kbd "DEL") 'Info-scroll-down)
+
+;;; Parentheses
+
+(defadvice show-paren-function (around evil disable)
+  "Match parentheses in Normal state."
+  (if (if (memq 'not evil-highlight-closing-paren-at-point-states)
+          (memq evil-state evil-highlight-closing-paren-at-point-states)
+        (not (memq evil-state evil-highlight-closing-paren-at-point-states)))
+      ad-do-it
+    (let ((pos (point)) syntax narrow)
+      (setq pos
+            (catch 'end
+              (dotimes (var (1+ (* 2 evil-show-paren-range)))
+                (if (zerop (mod var 2))
+                    (setq pos (+ pos var))
+                  (setq pos (- pos var)))
+                (setq syntax (syntax-class (syntax-after pos)))
+                (cond
+                 ((eq syntax 4)
+                  (setq narrow pos)
+                  (throw 'end pos))
+                 ((eq syntax 5)
+                  (throw 'end (1+ pos)))))))
+      (if pos
+          (save-excursion
+            (goto-char pos)
+            (save-restriction
+              (when narrow
+                (narrow-to-region narrow (point-max)))
+              ad-do-it))
+        ;; prevent the preceding pair from being highlighted
+        (dolist (ov '(show-paren--overlay
+                      show-paren--overlay-1
+                      show-paren-overlay
+                      show-paren-overlay-1))
+          (let ((ov (and (boundp ov) (symbol-value ov))))
+            (when (overlayp ov) (delete-overlay ov))))))))
+
+;;; Speedbar
+
+(evil-add-hjkl-bindings speedbar-key-map 'motion
+  "h" 'backward-char
+  "j" 'speedbar-next
+  "k" 'speedbar-prev
+  "l" 'forward-char
+  "i" 'speedbar-item-info
+  "r" 'speedbar-refresh
+  "u" 'speedbar-up-directory
+  "o" 'speedbar-toggle-line-expansion
+  (kbd "RET") 'speedbar-edit-line)
+
+;; Ibuffer
+(eval-after-load 'ibuffer
+  '(progn
+     (defvar ibuffer-mode-map)
+     (evil-make-overriding-map ibuffer-mode-map 'normal)
+     (evil-define-key 'normal ibuffer-mode-map
+       "j" 'evil-next-line
+       "k" 'evil-previous-line
+       "RET" 'ibuffer-visit-buffer)))
+
+;;; Undo tree
+(when (and (require 'undo-tree nil t)
+           (fboundp 'global-undo-tree-mode))
+  (global-undo-tree-mode 1))
+
+(eval-after-load 'undo-tree
+  '(with-no-warnings
+     (defun evil-turn-on-undo-tree-mode ()
+       "Enable `undo-tree-mode' if evil is enabled.
+This function enables `undo-tree-mode' when Evil is activated in
+some buffer, but only if `global-undo-tree-mode' is also
+activated."
+       (when (and (boundp 'global-undo-tree-mode)
+                  global-undo-tree-mode)
+         (turn-on-undo-tree-mode)))
+
+     (add-hook 'evil-local-mode-hook #'evil-turn-on-undo-tree-mode)
+
+     (defadvice undo-tree-visualize (after evil activate)
+       "Initialize Evil in the visualization buffer."
+       (when evil-local-mode
+         (evil-initialize-state)))
+
+     (when (fboundp 'undo-tree-visualize)
+       (evil-ex-define-cmd "undol[ist]" 'undo-tree-visualize)
+       (evil-ex-define-cmd "ul" 'undo-tree-visualize))
+
+     (when (boundp 'undo-tree-visualizer-mode-map)
+       (define-key undo-tree-visualizer-mode-map
+         [remap evil-backward-char] 'undo-tree-visualize-switch-branch-left)
+       (define-key undo-tree-visualizer-mode-map
+         [remap evil-forward-char] 'undo-tree-visualize-switch-branch-right)
+       (define-key undo-tree-visualizer-mode-map
+         [remap evil-next-line] 'undo-tree-visualize-redo)
+       (define-key undo-tree-visualizer-mode-map
+         [remap evil-previous-line] 'undo-tree-visualize-undo)
+       (define-key undo-tree-visualizer-mode-map
+         [remap evil-ret] 'undo-tree-visualizer-set))
+
+     (when (boundp 'undo-tree-visualizer-selection-mode-map)
+       (define-key undo-tree-visualizer-selection-mode-map
+         [remap evil-backward-char] 'undo-tree-visualizer-select-left)
+       (define-key undo-tree-visualizer-selection-mode-map
+         [remap evil-forward-char] 'undo-tree-visualizer-select-right)
+       (define-key undo-tree-visualizer-selection-mode-map
+         [remap evil-next-line] 'undo-tree-visualizer-select-next)
+       (define-key undo-tree-visualizer-selection-mode-map
+         [remap evil-previous-line] 'undo-tree-visualizer-select-previous)
+       (define-key undo-tree-visualizer-selection-mode-map
+         [remap evil-ret] 'undo-tree-visualizer-set))))
+
+;;; Auto-complete
+(eval-after-load 'auto-complete
+  '(progn
+     (evil-add-command-properties 'auto-complete :repeat 'evil-ac-repeat)
+     (evil-add-command-properties 'ac-complete :repeat 'evil-ac-repeat)
+     (evil-add-command-properties 'ac-expand :repeat 'evil-ac-repeat)
+     (evil-add-command-properties 'ac-next :repeat 'ignore)
+     (evil-add-command-properties 'ac-previous :repeat 'ignore)
+
+     (defvar evil-ac-prefix-len nil
+       "The length of the prefix of the current item to be completed.")
+
+     (defvar ac-prefix)
+     (defun evil-ac-repeat (flag)
+       "Record the changes for auto-completion."
+       (cond
+        ((eq flag 'pre)
+         (setq evil-ac-prefix-len (length ac-prefix))
+         (evil-repeat-start-record-changes))
+        ((eq flag 'post)
+         ;; Add change to remove the prefix
+         (evil-repeat-record-change (- evil-ac-prefix-len)
+                                    ""
+                                    evil-ac-prefix-len)
+         ;; Add change to insert the full completed text
+         (evil-repeat-record-change
+          (- evil-ac-prefix-len)
+          (buffer-substring-no-properties (- evil-repeat-pos
+                                             evil-ac-prefix-len)
+                                          (point))
+          0)
+         ;; Finish repeation
+         (evil-repeat-finish-record-changes))))))
+
+;;; Company
+(eval-after-load 'company
+  '(progn
+     (mapc #'evil-declare-change-repeat
+           '(company-complete-mouse
+             company-complete-number
+             company-complete-selection
+             company-complete-common))
+
+     (mapc #'evil-declare-ignore-repeat
+           '(company-abort
+             company-select-next
+             company-select-previous
+             company-select-next-or-abort
+             company-select-previous-or-abort
+             company-select-mouse
+             company-show-doc-buffer
+             company-show-location
+             company-search-candidates
+             company-filter-candidates))))
+
+;; Eval last sexp
+(cond
+ ((version< emacs-version "25")
+  (defadvice preceding-sexp (around evil activate)
+    "In normal-state or motion-state, last sexp ends at point."
+    (if (and (not evil-move-beyond-eol)
+             (or (evil-normal-state-p) (evil-motion-state-p)))
+        (save-excursion
+          (unless (or (eobp) (eolp)) (forward-char))
+          ad-do-it)
+      ad-do-it))
+
+  (defadvice pp-last-sexp (around evil activate)
+    "In normal-state or motion-state, last sexp ends at point."
+    (if (and (not evil-move-beyond-eol)
+             (or (evil-normal-state-p) (evil-motion-state-p)))
+        (save-excursion
+          (unless (or (eobp) (eolp)) (forward-char))
+          ad-do-it)
+      ad-do-it)))
+ (t
+  (defun evil--preceding-sexp (command &rest args)
+    "In normal-state or motion-state, last sexp ends at point."
+    (if (and (not evil-move-beyond-eol)
+             (or (evil-normal-state-p) (evil-motion-state-p)))
+        (save-excursion
+          (unless (or (eobp) (eolp)) (forward-char))
+          (apply command args))
+      (apply command args)))
+
+  (advice-add 'elisp--preceding-sexp :around 'evil--preceding-sexp '((name . evil)))
+  (advice-add 'pp-last-sexp          :around 'evil--preceding-sexp '((name . evil)))))
+
+;; Show key
+(defadvice quail-show-key (around evil activate)
+  "Temporarily go to Emacs state"
+  (evil-with-state emacs ad-do-it))
+
+(defadvice describe-char (around evil activate)
+  "Temporarily go to Emacs state"
+  (evil-with-state emacs ad-do-it))
+
+;; ace-jump-mode
+(declare-function 'ace-jump-char-mode "ace-jump-mode")
+(declare-function 'ace-jump-word-mode "ace-jump-mode")
+(declare-function 'ace-jump-line-mode "ace-jump-mode")
+
+(defvar evil-ace-jump-active nil)
+
+(defmacro evil-enclose-ace-jump-for-motion (&rest body)
+  "Enclose ace-jump to make it suitable for motions.
+This includes restricting `ace-jump-mode' to the current window
+in visual and operator state, deactivating visual updates, saving
+the mark and entering `recursive-edit'."
+  (declare (indent defun)
+           (debug t))
+  `(let ((old-mark (mark))
+         (ace-jump-mode-scope
+          (if (and (not (memq evil-state '(visual operator)))
+                   (boundp 'ace-jump-mode-scope))
+              ace-jump-mode-scope
+            'window)))
+     (remove-hook 'pre-command-hook #'evil-visual-pre-command t)
+     (remove-hook 'post-command-hook #'evil-visual-post-command t)
+     (unwind-protect
+         (let ((evil-ace-jump-active 'prepare))
+           (add-hook 'ace-jump-mode-end-hook
+                     #'evil-ace-jump-exit-recursive-edit)
+           ,@body
+           (when evil-ace-jump-active
+             (setq evil-ace-jump-active t)
+             (recursive-edit)))
+       (remove-hook 'post-command-hook
+                    #'evil-ace-jump-exit-recursive-edit)
+       (remove-hook 'ace-jump-mode-end-hook
+                    #'evil-ace-jump-exit-recursive-edit)
+       (if (evil-visual-state-p)
+           (progn
+             (add-hook 'pre-command-hook #'evil-visual-pre-command nil t)
+             (add-hook 'post-command-hook #'evil-visual-post-command nil t)
+             (set-mark old-mark))
+         (push-mark old-mark)))))
+
+(eval-after-load 'ace-jump-mode
+  `(defadvice ace-jump-done (after evil activate)
+     (when evil-ace-jump-active
+       (add-hook 'post-command-hook #'evil-ace-jump-exit-recursive-edit))))
+
+(defun evil-ace-jump-exit-recursive-edit ()
+  "Exit a recursive edit caused by an evil jump."
+  (cond
+   ((eq evil-ace-jump-active 'prepare)
+    (setq evil-ace-jump-active nil))
+   (evil-ace-jump-active
+    (remove-hook 'post-command-hook #'evil-ace-jump-exit-recursive-edit)
+    (exit-recursive-edit))))
+
+(evil-define-motion evil-ace-jump-char-mode (count)
+  "Jump visually directly to a char using ace-jump."
+  :type inclusive
+  (evil-without-repeat
+    (let ((pnt (point))
+          (buf (current-buffer)))
+      (evil-enclose-ace-jump-for-motion
+        (call-interactively 'ace-jump-char-mode))
+      ;; if we jump backwards, motion type is exclusive, analogously
+      ;; to `evil-find-char-backward'
+      (when (and (equal buf (current-buffer))
+                 (< (point) pnt))
+        (setq evil-this-type
+              (cond
+               ((eq evil-this-type 'exclusive) 'inclusive)
+               ((eq evil-this-type 'inclusive) 'exclusive)))))))
+
+(evil-define-motion evil-ace-jump-char-to-mode (count)
+  "Jump visually to the char in front of a char using ace-jump."
+  :type inclusive
+  (evil-without-repeat
+    (let ((pnt (point))
+          (buf (current-buffer)))
+      (evil-enclose-ace-jump-for-motion
+        (call-interactively 'ace-jump-char-mode))
+      (if (and (equal buf (current-buffer))
+               (< (point) pnt))
+          (progn
+            (or (eobp) (forward-char))
+            (setq evil-this-type
+                  (cond
+                   ((eq evil-this-type 'exclusive) 'inclusive)
+                   ((eq evil-this-type 'inclusive) 'exclusive))))
+        (backward-char)))))
+
+(evil-define-motion evil-ace-jump-line-mode (count)
+  "Jump visually to the beginning of a line using ace-jump."
+  :type line
+  :repeat abort
+  (evil-without-repeat
+    (evil-enclose-ace-jump-for-motion
+      (call-interactively 'ace-jump-line-mode))))
+
+(evil-define-motion evil-ace-jump-word-mode (count)
+  "Jump visually to the beginning of a word using ace-jump."
+  :type exclusive
+  :repeat abort
+  (evil-without-repeat
+    (evil-enclose-ace-jump-for-motion
+      (call-interactively 'ace-jump-word-mode))))
+
+(define-key evil-motion-state-map [remap ace-jump-char-mode] #'evil-ace-jump-char-mode)
+(define-key evil-motion-state-map [remap ace-jump-line-mode] #'evil-ace-jump-line-mode)
+(define-key evil-motion-state-map [remap ace-jump-word-mode] #'evil-ace-jump-word-mode)
+
+;;; avy
+(declare-function 'avy-goto-word-or-subword-1 "avy")
+(declare-function 'avy-goto-line "avy")
+(declare-function 'avy-goto-char "avy")
+(declare-function 'avy-goto-char-2 "avy")
+(declare-function 'avy-goto-char-2-above "avy")
+(declare-function 'avy-goto-char-2-below "avy")
+(declare-function 'avy-goto-char-in-line "avy")
+(declare-function 'avy-goto-word-0 "avy")
+(declare-function 'avy-goto-word-1 "avy")
+(declare-function 'avy-goto-word-1-above "avy")
+(declare-function 'avy-goto-word-1-below "avy")
+(declare-function 'avy-goto-subword-0 "avy")
+(declare-function 'avy-goto-subword-1 "avy")
+(declare-function 'avy-goto-char-timer "avy")
+
+(defmacro evil-enclose-avy-for-motion (&rest body)
+  "Enclose avy to make it suitable for motions.
+Based on `evil-enclose-ace-jump-for-motion'."
+  (declare (indent defun)
+           (debug t))
+  `(let ((avy-all-windows
+          (if (and (not (memq evil-state '(visual operator)))
+                   (boundp 'avy-all-windows))
+              avy-all-windows
+            nil)))
+     ,@body))
+
+(defmacro evil-define-avy-motion (command type)
+  (declare (indent defun)
+           (debug t))
+  (let ((name (intern (format "evil-%s" command))))
+    `(evil-define-motion ,name (_count)
+       ,(format "Evil motion for `%s'." command)
+       :type ,type
+       :jump t
+       :repeat abort
+       (evil-without-repeat
+         (evil-enclose-avy-for-motion
+           (call-interactively ',command))))))
+
+;; define evil-avy-* motion commands for avy-* commands
+(evil-define-avy-motion avy-goto-char inclusive)
+(evil-define-avy-motion avy-goto-char-2 inclusive)
+(evil-define-avy-motion avy-goto-char-2-above inclusive)
+(evil-define-avy-motion avy-goto-char-2-below inclusive)
+(evil-define-avy-motion avy-goto-char-in-line inclusive)
+(evil-define-avy-motion avy-goto-char-timer inclusive)
+(evil-define-avy-motion avy-goto-line line)
+(evil-define-avy-motion avy-goto-line-above line)
+(evil-define-avy-motion avy-goto-line-below line)
+(evil-define-avy-motion avy-goto-subword-0 exclusive)
+(evil-define-avy-motion avy-goto-subword-1 exclusive)
+(evil-define-avy-motion avy-goto-symbol-1 exclusive)
+(evil-define-avy-motion avy-goto-symbol-1-above exclusive)
+(evil-define-avy-motion avy-goto-symbol-1-below exclusive)
+(evil-define-avy-motion avy-goto-word-0 exclusive)
+(evil-define-avy-motion avy-goto-word-1 exclusive)
+(evil-define-avy-motion avy-goto-word-1-above exclusive)
+(evil-define-avy-motion avy-goto-word-1-below exclusive)
+(evil-define-avy-motion avy-goto-word-or-subword-1 exclusive)
+
+;; remap avy-* commands to evil-avy-* commands
+(dolist (command '(avy-goto-char
+                   avy-goto-char-2
+                   avy-goto-char-2-above
+                   avy-goto-char-2-below
+                   avy-goto-char-in-line
+                   avy-goto-char-timer
+                   avy-goto-line
+                   avy-goto-line-above
+                   avy-goto-line-below
+                   avy-goto-subword-0
+                   avy-goto-subword-1
+                   avy-goto-symbol-1
+                   avy-goto-symbol-1-above
+                   avy-goto-symbol-1-below
+                   avy-goto-word-0
+                   avy-goto-word-1
+                   avy-goto-word-1-above
+                   avy-goto-word-1-below
+                   avy-goto-word-or-subword-1))
+  (define-key evil-motion-state-map
+    (vector 'remap command) (intern-soft (format "evil-%s" command))))
+
+;;; nXhtml/mumamo
+;; ensure that mumamo does not toggle evil through its globalized mode
+(eval-after-load 'mumamo
+  '(with-no-warnings
+     (push 'evil-mode-cmhh mumamo-change-major-mode-no-nos)))
+
+;;; ag.el
+(eval-after-load 'ag
+  '(progn
+     (defvar ag-mode-map)
+     (add-to-list 'evil-motion-state-modes 'ag-mode)
+     (evil-add-hjkl-bindings ag-mode-map 'motion)))
+
+;; visual-line-mode integration
+(when evil-respect-visual-line-mode
+  (let ((swaps '((evil-next-line . evil-next-visual-line)
+                 (evil-previous-line . evil-previous-visual-line)
+                 (evil-beginning-of-line . evil-beginning-of-visual-line)
+                 (evil-end-of-line . evil-end-of-visual-line))))
+    (dolist (swap swaps)
+      (define-key visual-line-mode-map (vector 'remap (car swap)) (cdr swap))
+      (define-key visual-line-mode-map (vector 'remap (cdr swap)) (car swap)))))
+
+;;; abbrev.el
+(when evil-want-abbrev-expand-on-insert-exit
+  (eval-after-load 'abbrev
+    '(add-hook 'evil-insert-state-exit-hook 'expand-abbrev)))
+
+;;; ElDoc
+(eval-after-load 'eldoc
+  '(when (fboundp 'eldoc-add-command-completions)
+     (eldoc-add-command-completions "evil-window-")))
+
+(provide 'evil-integration)
+
+;;; evil-integration.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-integration.elc b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-integration.elc
new file mode 100644
index 0000000000..155cdf665a
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-integration.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-jumps.el b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-jumps.el
new file mode 100644
index 0000000000..cce75cd087
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-jumps.el
@@ -0,0 +1,318 @@
+;;; evil-jumps.el --- Jump list implementation
+
+;; Author: Bailey Ling <bling at live.ca>
+
+;; Version: 1.2.13
+
+;;
+;; This file is NOT part of GNU Emacs.
+
+;;; License:
+
+;; This file is part of Evil.
+;;
+;; Evil 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.
+;;
+;; Evil 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 Evil.  If not, see <http://www.gnu.org/licenses/>.
+
+(require 'cl-lib)
+(require 'evil-core)
+(require 'evil-states)
+
+;;; Code:
+
+(defgroup evil-jumps nil
+  "Evil jump list configuration options."
+  :prefix "evil-jumps"
+  :group 'evil)
+
+(defcustom evil-jumps-cross-buffers t
+  "When non-nil, the jump commands can cross borders between buffers, otherwise the jump commands act only within the current buffer."
+  :type 'boolean
+  :group 'evil-jumps)
+
+(defcustom evil-jumps-max-length 100
+  "The maximum number of jumps to keep track of."
+  :type 'integer
+  :group 'evil-jumps)
+
+(defcustom evil-jumps-pre-jump-hook nil
+  "Hooks to run just before jumping to a location in the jump list."
+  :type 'hook
+  :group 'evil-jumps)
+
+(defcustom evil-jumps-post-jump-hook nil
+  "Hooks to run just after jumping to a location in the jump list."
+  :type 'hook
+  :group 'evil-jumps)
+
+(defcustom evil-jumps-ignored-file-patterns '("COMMIT_EDITMSG$" "TAGS$")
+  "A list of pattern regexps to match on the file path to exclude from being included in the jump list."
+  :type '(repeat string)
+  :group 'evil-jumps)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defvar savehist-additional-variables)
+
+(defvar evil--jumps-jumping nil)
+
+(eval-when-compile (defvar evil--jumps-debug nil))
+
+(defvar evil--jumps-buffer-targets "\\*\\(new\\|scratch\\)\\*"
+  "Regexp to match against `buffer-name' to determine whether it's a valid jump target.")
+
+(defvar evil--jumps-window-jumps (make-hash-table)
+  "Hashtable which stores all jumps on a per window basis.")
+
+(defvar evil-jumps-history nil
+  "History of `evil-mode' jumps that are persisted with `savehist'.")
+
+(cl-defstruct evil-jumps-struct
+  ring
+  (idx -1))
+
+(defmacro evil--jumps-message (format &rest args)
+  (when evil--jumps-debug
+    `(with-current-buffer (get-buffer-create "*evil-jumps*")
+       (goto-char (point-max))
+       (insert (apply #'format ,format ',args) "\n"))))
+
+(defun evil--jumps-get-current (&optional window)
+  (unless window
+    (setq window (frame-selected-window)))
+  (let* ((jump-struct (gethash window evil--jumps-window-jumps)))
+    (unless jump-struct
+      (setq jump-struct (make-evil-jumps-struct))
+      (puthash window jump-struct evil--jumps-window-jumps))
+    jump-struct))
+
+(defun evil--jumps-get-jumps (struct)
+  (let ((ring (evil-jumps-struct-ring struct)))
+    (unless ring
+      (setq ring (make-ring evil-jumps-max-length))
+      (setf (evil-jumps-struct-ring struct) ring))
+    ring))
+
+(defun evil--jumps-get-window-jump-list ()
+  (let ((struct (evil--jumps-get-current)))
+    (evil--jumps-get-jumps struct)))
+
+(defun evil--jumps-savehist-load ()
+  (add-to-list 'savehist-additional-variables 'evil-jumps-history)
+  (let ((ring (make-ring evil-jumps-max-length)))
+    (cl-loop for jump in (reverse evil-jumps-history)
+             do (ring-insert ring jump))
+    (setf (evil-jumps-struct-ring (evil--jumps-get-current)) ring))
+  (add-hook 'savehist-save-hook #'evil--jumps-savehist-sync)
+  (remove-hook 'savehist-mode-hook #'evil--jumps-savehist-load))
+
+(defun evil--jumps-savehist-sync ()
+  "Updates the printable value of window jumps for `savehist'."
+  (setq evil-jumps-history
+        (cl-remove-if-not #'identity
+                          (mapcar #'(lambda (jump)
+                                      (let* ((mark (car jump))
+                                             (pos (if (markerp mark)
+                                                      (marker-position mark)
+                                                    mark))
+                                             (file-name (cadr jump)))
+                                        (if (and (not (file-remote-p file-name))
+                                                 (file-exists-p file-name)
+                                                 pos)
+                                            (list pos file-name)
+                                          nil)))
+                                  (ring-elements (evil--jumps-get-window-jump-list))))))
+
+(defun evil--jumps-jump (idx shift)
+  (let ((target-list (evil--jumps-get-window-jump-list)))
+    (evil--jumps-message "jumping from %s by %s" idx shift)
+    (evil--jumps-message "target list = %s" target-list)
+    (setq idx (+ idx shift))
+    (let* ((current-file-name (or (buffer-file-name) (buffer-name)))
+           (size (ring-length target-list)))
+      (unless evil-jumps-cross-buffers
+        ;; skip jump marks pointing to other buffers
+        (while (and (< idx size) (>= idx 0)
+                    (not (string= current-file-name
+                                  (let* ((place (ring-ref target-list idx))
+                                         (pos (car place)))
+                                    (cadr place)))))
+          (setq idx (+ idx shift))))
+      (when (and (< idx size) (>= idx 0))
+        ;; actual jump
+        (run-hooks 'evil-jumps-pre-jump-hook)
+        (let* ((place (ring-ref target-list idx))
+               (pos (car place))
+               (file-name (cadr place)))
+          (setq evil--jumps-jumping t)
+          (if (string-match-p evil--jumps-buffer-targets file-name)
+              (switch-to-buffer file-name)
+            (find-file file-name))
+          (setq evil--jumps-jumping nil)
+          (goto-char pos)
+          (setf (evil-jumps-struct-idx (evil--jumps-get-current)) idx)
+          (run-hooks 'evil-jumps-post-jump-hook))))))
+
+(defun evil--jumps-push ()
+  "Pushes the current cursor/file position to the jump list."
+  (let ((target-list (evil--jumps-get-window-jump-list)))
+    (let ((file-name (buffer-file-name))
+          (buffer-name (buffer-name))
+          (current-pos (point-marker))
+          (first-pos nil)
+          (first-file-name nil)
+          (excluded nil))
+      (when (and (not file-name)
+                 (string-match-p evil--jumps-buffer-targets buffer-name))
+        (setq file-name buffer-name))
+      (when file-name
+        (dolist (pattern evil-jumps-ignored-file-patterns)
+          (when (string-match-p pattern file-name)
+            (setq excluded t)))
+        (unless excluded
+          (unless (ring-empty-p target-list)
+            (setq first-pos (car (ring-ref target-list 0)))
+            (setq first-file-name (car (cdr (ring-ref target-list 0)))))
+          (unless (and (equal first-pos current-pos)
+                       (equal first-file-name file-name))
+            (evil--jumps-message "pushing %s on %s" current-pos file-name)
+            (ring-insert target-list `(,current-pos ,file-name))))))
+    (evil--jumps-message "%s %s"
+                         (selected-window)
+                         (and (not (ring-empty-p target-list))
+                              (ring-ref target-list 0)))))
+
+(evil-define-command evil-show-jumps ()
+  "Display the contents of the jump list."
+  :repeat nil
+  (evil-with-view-list
+    :name "evil-jumps"
+    :mode "Evil Jump List"
+    :format [("Jump" 5 nil)
+             ("Marker" 8 nil)
+             ("File/text" 1000 t)]
+    :entries (let* ((jumps (evil--jumps-savehist-sync))
+                    (count 0))
+               (cl-loop for jump in jumps
+                        collect `(nil [,(number-to-string (cl-incf count))
+                                       ,(number-to-string (car jump))
+                                       (,(cadr jump))])))
+    :select-action #'evil--show-jumps-select-action))
+
+(defun evil--show-jumps-select-action (jump)
+  (let ((position (string-to-number (elt jump 1)))
+        (file (car (elt jump 2))))
+    (kill-buffer)
+    (switch-to-buffer (find-file file))
+    (goto-char position)))
+
+(defun evil-set-jump (&optional pos)
+  "Set jump point at POS.
+POS defaults to point."
+  (unless (or (region-active-p) (evil-visual-state-p))
+    (push-mark pos t))
+
+  (unless evil--jumps-jumping
+    ;; clear out intermediary jumps when a new one is set
+    (let* ((struct (evil--jumps-get-current))
+           (target-list (evil--jumps-get-jumps struct))
+           (idx (evil-jumps-struct-idx struct)))
+      (cl-loop repeat idx
+               do (ring-remove target-list))
+      (setf (evil-jumps-struct-idx struct) -1))
+    (save-excursion
+      (when pos
+        (goto-char pos))
+      (evil--jumps-push))))
+
+(defun evil--jump-backward (count)
+  (let ((count (or count 1)))
+    (evil-motion-loop (nil count)
+      (let* ((struct (evil--jumps-get-current))
+             (idx (evil-jumps-struct-idx struct)))
+        (evil--jumps-message "jumping back %s" idx)
+        (when (= idx -1)
+          (setq idx 0)
+          (setf (evil-jumps-struct-idx struct) 0)
+          (evil--jumps-push))
+        (evil--jumps-jump idx 1)))))
+
+(defun evil--jump-forward (count)
+  (let ((count (or count 1)))
+    (evil-motion-loop (nil count)
+      (let* ((struct (evil--jumps-get-current))
+             (idx (evil-jumps-struct-idx struct)))
+        (when (= idx -1)
+          (setq idx 0)
+          (setf (evil-jumps-struct-idx struct) 0)
+          (evil--jumps-push))
+          (evil--jumps-jump idx -1)))))
+
+(defun evil--jumps-window-configuration-hook (&rest args)
+  (let* ((window-list (window-list-1 nil nil t))
+         (existing-window (selected-window))
+         (new-window (previous-window)))
+    (when (and (not (eq existing-window new-window))
+               (> (length window-list) 1))
+      (let* ((target-jump-struct (evil--jumps-get-current new-window))
+             (target-jump-count (ring-length (evil--jumps-get-jumps target-jump-struct))))
+        (if (not (ring-empty-p (evil--jumps-get-jumps target-jump-struct)))
+            (evil--jumps-message "target window %s already has %s jumps" new-window target-jump-count)
+          (evil--jumps-message "new target window detected; copying %s to %s" existing-window new-window)
+          (let* ((source-jump-struct (evil--jumps-get-current existing-window))
+                 (source-list (evil--jumps-get-jumps source-jump-struct)))
+            (when (= (ring-length (evil--jumps-get-jumps target-jump-struct)) 0)
+              (setf (evil-jumps-struct-idx target-jump-struct) (evil-jumps-struct-idx source-jump-struct))
+              (setf (evil-jumps-struct-ring target-jump-struct) (ring-copy source-list)))))))
+    ;; delete obsolete windows
+    (maphash (lambda (key val)
+               (unless (member key window-list)
+                 (evil--jumps-message "removing %s" key)
+                 (remhash key evil--jumps-window-jumps)))
+             evil--jumps-window-jumps)))
+
+(defun evil--jump-hook (&optional command)
+  "Set jump point if COMMAND has a non-nil :jump property."
+  (setq command (or command this-command))
+  (when (evil-get-command-property command :jump)
+    (evil-set-jump)))
+
+(defadvice switch-to-buffer (before evil-jumps activate)
+  (evil-set-jump))
+
+(defadvice split-window-internal (before evil-jumps activate)
+  (evil-set-jump))
+
+(eval-after-load 'etags
+  '(defadvice find-tag-noselect (before evil-jumps activate)
+     (evil-set-jump)))
+
+(if (bound-and-true-p savehist-loaded)
+    (evil--jumps-savehist-load)
+  (add-hook 'savehist-mode-hook #'evil--jumps-savehist-load))
+
+(add-hook 'evil-local-mode-hook
+          (lambda ()
+            (if evil-local-mode
+                (progn
+                  (add-hook 'pre-command-hook #'evil--jump-hook nil t)
+                  (add-hook 'next-error-hook #'evil-set-jump nil t)
+                  (add-hook 'window-configuration-change-hook #'evil--jumps-window-configuration-hook nil t))
+              (progn
+                (remove-hook 'pre-command-hook #'evil--jump-hook t)
+                (remove-hook 'next-error-hook #'evil-set-jump t)
+                (remove-hook 'window-configuration-change-hook #'evil--jumps-window-configuration-hook t)))))
+
+(provide 'evil-jumps)
+
+;;; evil-jumps.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-jumps.elc b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-jumps.elc
new file mode 100644
index 0000000000..7798426b73
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-jumps.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-macros.el b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-macros.el
new file mode 100644
index 0000000000..ed98e7dd41
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-macros.el
@@ -0,0 +1,777 @@
+;;; evil-macros.el --- Macros
+
+;; Author: Vegard Øye <vegard_oye at hotmail.com>
+;; Maintainer: Vegard Øye <vegard_oye at hotmail.com>
+
+;; Version: 1.2.13
+
+;;
+;; This file is NOT part of GNU Emacs.
+
+;;; License:
+
+;; This file is part of Evil.
+;;
+;; Evil 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.
+;;
+;; Evil 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 Evil.  If not, see <http://www.gnu.org/licenses/>.
+
+(require 'evil-common)
+(require 'evil-states)
+(require 'evil-repeat)
+
+;;; Code:
+
+(declare-function evil-ex-p "evil-ex")
+
+;; set some error codes
+(put 'beginning-of-line 'error-conditions '(beginning-of-line error))
+(put 'beginning-of-line 'error-message "Beginning of line")
+(put 'end-of-line 'error-conditions '(end-of-line error))
+(put 'end-of-line 'error-message "End of line")
+
+(defun evil-motion-range (motion &optional count type)
+  "Execute a motion and return the buffer positions.
+The return value is a list (BEG END TYPE)."
+  (let ((opoint   (point))
+        (omark    (mark t))
+        (omactive (and (boundp 'mark-active) mark-active))
+        (obuffer  (current-buffer))
+        (evil-motion-marker (move-marker (make-marker) (point)))
+        range)
+    (evil-with-transient-mark-mode
+      (evil-narrow-to-field
+        (unwind-protect
+            (let ((current-prefix-arg count)
+                  ;; Store type in global variable `evil-this-type'.
+                  ;; If necessary, motions can change their type
+                  ;; during execution by setting this variable.
+                  (evil-this-type
+                   (or type (evil-type motion 'exclusive))))
+              (condition-case err
+                  (let ((repeat-type (evil-repeat-type motion t)))
+                    (if (functionp repeat-type)
+                        (funcall repeat-type 'pre))
+                    (unless (with-local-quit
+                              (setq range (call-interactively motion))
+                              t)
+                      (evil-repeat-abort)
+                      (setq quit-flag t))
+                    (if (functionp repeat-type)
+                        (funcall repeat-type 'post)))
+                (error (prog1 nil
+                         (evil-repeat-abort)
+                         ;; some operators depend on succeeding
+                         ;; motions, in particular for
+                         ;; `evil-forward-char' (e.g., used by
+                         ;; `evil-substitute'), therefore we let
+                         ;; end-of-line and end-of-buffer pass
+                         (if (not (memq (car err) '(end-of-line end-of-buffer)))
+                             (signal (car err) (cdr err))
+                           (message (error-message-string err))))))
+              (cond
+               ;; the motion returned a range
+               ((evil-range-p range))
+               ;; the motion made a Visual selection
+               ((evil-visual-state-p)
+                (setq range (evil-visual-range)))
+               ;; the motion made an active region
+               ((region-active-p)
+                (setq range (evil-range (region-beginning)
+                                        (region-end)
+                                        evil-this-type)))
+               ;; default: range from previous position to current
+               (t
+                (setq range (evil-expand-range
+                             (evil-normalize evil-motion-marker
+                                             (point)
+                                             evil-this-type)))))
+              (unless (or (null type) (eq (evil-type range) type))
+                (evil-set-type range type)
+                (evil-expand-range range))
+              (evil-set-range-properties range nil)
+              range)
+          ;; restore point and mark like `save-excursion',
+          ;; but only if the motion hasn't disabled the operator
+          (unless evil-inhibit-operator
+            (set-buffer obuffer)
+            (evil-move-mark omark)
+            (goto-char opoint))
+          ;; delete marker so it doesn't slow down editing
+          (move-marker evil-motion-marker nil))))))
+
+(defmacro evil-define-motion (motion args &rest body)
+  "Define an motion command MOTION.
+
+\(fn MOTION (COUNT ARGS...) DOC [[KEY VALUE]...] BODY...)"
+  (declare (indent defun)
+           (debug (&define name lambda-list
+                           [&optional stringp]
+                           [&rest keywordp sexp]
+                           [&optional ("interactive" [&rest form])]
+                           def-body)))
+  (let (arg doc interactive key keys type)
+    (when args
+      (setq args `(&optional ,@(delq '&optional args))
+            ;; the count is either numerical or nil
+            interactive '("<c>")))
+    ;; collect docstring
+    (when (and (> (length body) 1)
+               (or (eq (car-safe (car-safe body)) 'format)
+                   (stringp (car-safe body))))
+      (setq doc (pop body)))
+    ;; collect keywords
+    (setq keys (plist-put keys :repeat 'motion))
+    (while (keywordp (car-safe body))
+      (setq key (pop body)
+            arg (pop body)
+            keys (plist-put keys key arg)))
+    ;; collect `interactive' specification
+    (when (eq (car-safe (car-safe body)) 'interactive)
+      (setq interactive (cdr (pop body))))
+    ;; macro expansion
+    `(progn
+       ;; refresh echo area in Eldoc mode
+       (when ',motion
+         (eval-after-load 'eldoc
+           '(and (fboundp 'eldoc-add-command)
+                 (eldoc-add-command ',motion))))
+       (evil-define-command ,motion (,@args)
+         ,@(when doc `(,doc))          ; avoid nil before `interactive'
+         ,@keys
+         :keep-visual t
+         (interactive ,@interactive)
+         ,@body))))
+
+(defmacro evil-narrow-to-line (&rest body)
+  "Narrow BODY to the current line.
+BODY will signal the errors 'beginning-of-line or 'end-of-line
+upon reaching the beginning or end of the current line.
+
+\(fn [[KEY VAL]...] BODY...)"
+  (declare (indent defun)
+           (debug t))
+  `(let* ((range (evil-expand (point) (point) 'line))
+          (beg (evil-range-beginning range))
+          (end (evil-range-end range))
+          (min (point-min))
+          (max (point-max)))
+     (when (save-excursion (goto-char end) (bolp))
+       (setq end (max beg (1- end))))
+     ;; don't include the newline in Normal state
+     (when (and evil-move-cursor-back
+                (not evil-move-beyond-eol)
+                (not (evil-visual-state-p))
+                (not (evil-operator-state-p)))
+       (setq end (max beg (1- end))))
+     (evil-with-restriction beg end
+       (evil-signal-without-movement
+         (condition-case err
+             (progn ,@body)
+           (beginning-of-buffer
+            (if (= beg min)
+                (signal (car err) (cdr err))
+              (signal 'beginning-of-line nil)))
+           (end-of-buffer
+            (if (= end max)
+                (signal (car err) (cdr err))
+              (signal 'end-of-line nil))))))))
+
+;; we don't want line boundaries to trigger the debugger
+;; when `debug-on-error' is t
+(add-to-list 'debug-ignored-errors "^Beginning of line$")
+(add-to-list 'debug-ignored-errors "^End of line$")
+
+(defun evil-eobp (&optional pos)
+  "Whether point is at end-of-buffer with regard to end-of-line."
+  (save-excursion
+    (when pos (goto-char pos))
+    (cond
+     ((eobp))
+     ;; the rest only pertains to Normal state
+     ((not (evil-normal-state-p))
+      nil)
+     ;; at the end of the last line
+     ((eolp)
+      (forward-char)
+      (eobp))
+     ;; at the last character of the last line
+     (t
+      (forward-char)
+      (cond
+       ((eobp))
+       ((eolp)
+        (forward-char)
+        (eobp)))))))
+
+(defun evil-move-beginning (count forward &optional backward)
+  "Move to the beginning of the COUNT next object.
+If COUNT is negative, move to the COUNT previous object.
+FORWARD is a function which moves to the end of the object, and
+BACKWARD is a function which moves to the beginning.
+If one is unspecified, the other is used with a negative argument."
+  (let* ((count (or count 1))
+         (backward (or backward
+                       #'(lambda (count)
+                           (funcall forward (- count)))))
+         (forward (or forward
+                      #'(lambda (count)
+                          (funcall backward (- count)))))
+         (opoint (point)))
+    (cond
+     ((< count 0)
+      (when (bobp)
+        (signal 'beginning-of-buffer nil))
+      (unwind-protect
+          (evil-motion-loop (nil count count)
+            (funcall backward 1))
+        (unless (zerop count)
+          (goto-char (point-min)))))
+     ((> count 0)
+      (when (evil-eobp)
+        (signal 'end-of-buffer nil))
+      ;; Do we need to move past the current object?
+      (when (<= (save-excursion
+                  (funcall forward 1)
+                  (funcall backward 1)
+                  (point))
+                opoint)
+        (setq count (1+ count)))
+      (unwind-protect
+          (evil-motion-loop (nil count count)
+            (funcall forward 1))
+        (if (zerop count)
+            ;; go back to beginning of object
+            (funcall backward 1)
+          (goto-char (point-max)))))
+     (t
+      count))))
+
+(defun evil-move-end (count forward &optional backward inclusive)
+  "Move to the end of the COUNT next object.
+If COUNT is negative, move to the COUNT previous object.
+FORWARD is a function which moves to the end of the object, and
+BACKWARD is a function which moves to the beginning.
+If one is unspecified, the other is used with a negative argument.
+If INCLUSIVE is non-nil, then point is placed at the last character
+of the object; otherwise it is placed at the end of the object."
+  (let* ((count (or count 1))
+         (backward (or backward
+                       #'(lambda (count)
+                           (funcall forward (- count)))))
+         (forward (or forward
+                      #'(lambda (count)
+                          (funcall backward (- count)))))
+         (opoint (point)))
+    (cond
+     ((< count 0)
+      (when (bobp)
+        (signal 'beginning-of-buffer nil))
+      ;; Do we need to move past the current object?
+      (when (>= (save-excursion
+                  (funcall backward 1)
+                  (funcall forward 1)
+                  (point))
+                (if inclusive
+                    (1+ opoint)
+                  opoint))
+        (setq count (1- count)))
+      (unwind-protect
+          (evil-motion-loop (nil count count)
+            (funcall backward 1))
+        (if (not (zerop count))
+            (goto-char (point-min))
+          ;; go to end of object
+          (funcall forward 1)
+          (when inclusive
+            (unless (bobp) (backward-char)))
+          (when (or (evil-normal-state-p)
+                    (evil-motion-state-p))
+            (evil-adjust-cursor t)))))
+     ((> count 0)
+      (when (evil-eobp)
+        (signal 'end-of-buffer nil))
+      (when inclusive
+        (forward-char))
+      (unwind-protect
+          (evil-motion-loop (nil count count)
+            (funcall forward 1))
+        (if (not (zerop count))
+            (goto-char (point-max))
+          (when inclusive
+            (unless (bobp) (backward-char)))
+          (when (or (evil-normal-state-p)
+                    (evil-motion-state-p))
+            (evil-adjust-cursor t)))))
+     (t
+      count))))
+
+(defun evil-text-object-make-linewise (range)
+  "Turn the text object selection RANGE to linewise.
+The selection is adjusted in a sensible way so that the selected
+lines match the user intent. In particular, whitespace-only parts
+at the first and last lines are omitted. This function returns
+the new range."
+  ;; Bug #607
+  ;; If new type is linewise and the selection of the
+  ;; first line consists of whitespace only, the
+  ;; beginning is moved to the start of the next line. If
+  ;; the selections of the last line consists of
+  ;; whitespace only, the end is moved to the end of the
+  ;; previous line.
+  (if (eq (evil-type range) 'line)
+      range
+    (let ((expanded (plist-get (evil-range-properties range) :expanded))
+          (newrange (evil-expand-range range t)))
+      (save-excursion
+        ;; skip whitespace at the beginning
+        (goto-char (evil-range-beginning newrange))
+        (skip-chars-forward " \t")
+        (when (and (not (bolp)) (eolp))
+          (evil-set-range-beginning newrange (1+ (point))))
+        ;; skip whitepsace at the end
+        (goto-char (evil-range-end newrange))
+        (skip-chars-backward " \t")
+        (when (and (not (eolp)) (bolp))
+          (evil-set-range-end newrange (1- (point))))
+        ;; only modify range if result is not empty
+        (if (> (evil-range-beginning newrange)
+               (evil-range-end newrange))
+            range
+          (unless expanded
+            (evil-contract-range newrange))
+          newrange)))))
+
+(defmacro evil-define-text-object (object args &rest body)
+  "Define a text object command OBJECT.
+BODY should return a range (BEG END) to the right of point
+if COUNT is positive, and to the left of it if negative.
+
+\(fn OBJECT (COUNT) DOC [[KEY VALUE]...] BODY...)"
+  (declare (indent defun)
+           (debug (&define name lambda-list
+                           [&optional stringp]
+                           [&rest keywordp sexp]
+                           def-body)))
+  (let* ((args (delq '&optional args))
+         (count (or (pop args) 'count))
+         (args (when args `(&optional ,@args)))
+         (interactive '((interactive "<c><v>")))
+         arg doc key keys)
+    ;; collect docstring
+    (when (stringp (car-safe body))
+      (setq doc (pop body)))
+    ;; collect keywords
+    (setq keys (plist-put keys :extend-selection t))
+    (while (keywordp (car-safe body))
+      (setq key (pop body)
+            arg (pop body)
+            keys (plist-put keys key arg)))
+    ;; interactive
+    (when (eq (car-safe (car-safe body)) 'interactive)
+      (setq interactive (list (pop body))))
+    ;; macro expansion
+    `(evil-define-motion ,object (,count ,@args)
+       ,@(when doc `(,doc))
+       ,@keys
+       ,@interactive
+       (setq ,count (or ,count 1))
+       (when (/= ,count 0)
+         (let ((type (evil-type ',object evil-visual-char))
+               (extend (and (evil-visual-state-p)
+                            (evil-get-command-property
+                             ',object :extend-selection
+                             ',(plist-get keys :extend-selection))))
+               (dir evil-visual-direction)
+               mark point range selection)
+           (cond
+            ;; Visual state: extend the current selection
+            ((and (evil-visual-state-p)
+                  (called-interactively-p 'any))
+             ;; if we are at the beginning of the Visual selection,
+             ;; go to the left (negative COUNT); if at the end,
+             ;; go to the right (positive COUNT)
+             (setq dir evil-visual-direction
+                   ,count (* ,count dir))
+             (setq range (progn ,@body))
+             (when (evil-range-p range)
+               (setq range (evil-expand-range range))
+               (evil-set-type range (evil-type range type))
+               (setq range (evil-contract-range range))
+               ;; the beginning is mark and the end is point
+               ;; unless the selection goes the other way
+               (setq mark  (evil-range-beginning range)
+                     point (evil-range-end range)
+                     type  (evil-type
+                            (if evil-text-object-change-visual-type
+                                range
+                              (evil-visual-range))))
+               (when (and (eq type 'line)
+                          (not (eq type (evil-type range))))
+                 (let ((newrange (evil-text-object-make-linewise range)))
+                   (setq mark (evil-range-beginning newrange)
+                         point (evil-range-end newrange))))
+               (when (< dir 0)
+                 (evil-swap mark point))
+               ;; select the union
+               (evil-visual-make-selection mark point type)))
+            ;; not Visual state: return a pair of buffer positions
+            (t
+             (setq range (progn ,@body))
+             (unless (evil-range-p range)
+               (setq ,count (- ,count)
+                     range (progn ,@body)))
+             (when (evil-range-p range)
+               (setq selection (evil-range (point) (point) type))
+               (if extend
+                   (setq range (evil-range-union range selection))
+                 (evil-set-type range (evil-type range type)))
+               ;; possibly convert to linewise
+               (when (eq evil-this-type-modified 'line)
+                 (setq range (evil-text-object-make-linewise range)))
+               (evil-set-range-properties range nil)
+               range))))))))
+
+(defmacro evil-define-operator (operator args &rest body)
+  "Define an operator command OPERATOR.
+
+\(fn OPERATOR (BEG END ARGS...) DOC [[KEY VALUE]...] BODY...)"
+  (declare (indent defun)
+           (debug (&define name lambda-list
+                           [&optional stringp]
+                           [&rest keywordp sexp]
+                           [&optional ("interactive" [&rest form])]
+                           def-body)))
+  (let* ((args (delq '&optional args))
+         (interactive (if (> (length args) 2) '("<R>") '("<r>")))
+         (args (if (> (length args) 2)
+                   `(,(nth 0 args) ,(nth 1 args)
+                     &optional ,@(nthcdr 2 args))
+                 args))
+         arg doc key keys visual)
+    ;; collect docstring
+    (when (and (> (length body) 1)
+               (or (eq (car-safe (car-safe body)) 'format)
+                   (stringp (car-safe body))))
+      (setq doc (pop body)))
+    ;; collect keywords
+    (setq keys (plist-put keys :move-point t))
+    (while (keywordp (car-safe body))
+      (setq key (pop body)
+            arg (pop body))
+      (cond
+       ((eq key :keep-visual)
+        (setq visual arg))
+       (t
+        (setq keys (plist-put keys key arg)))))
+    ;; collect `interactive' specification
+    (when (eq (car-safe (car-safe body)) 'interactive)
+      (setq interactive (cdr-safe (pop body))))
+    ;; transform extended interactive specs
+    (setq interactive (apply #'evil-interactive-form interactive))
+    (setq keys (evil-concat-plists keys (cdr-safe interactive))
+          interactive (car-safe interactive))
+    ;; macro expansion
+    `(evil-define-command ,operator ,args
+       ,@(when doc `(,doc))
+       ,@keys
+       :keep-visual t
+       :suppress-operator t
+       (interactive
+        (let* ((evil-operator-range-motion
+                (when (evil-has-command-property-p ',operator :motion)
+                  ;; :motion nil is equivalent to :motion undefined
+                  (or (evil-get-command-property ',operator :motion)
+                      #'undefined)))
+               (evil-operator-range-type
+                (evil-get-command-property ',operator :type))
+               (orig (point))
+               evil-operator-range-beginning
+               evil-operator-range-end
+               evil-inhibit-operator)
+          (setq evil-inhibit-operator-value nil
+                evil-this-operator this-command)
+          (prog1 ,interactive
+            (setq orig (point)
+                  evil-inhibit-operator-value evil-inhibit-operator)
+            (if ,visual
+                (when (evil-visual-state-p)
+                  (evil-visual-expand-region))
+              (when (or (evil-visual-state-p) (region-active-p))
+                (setq deactivate-mark t)))
+            (cond
+             ((evil-visual-state-p)
+              (evil-visual-rotate 'upper-left))
+             ((evil-get-command-property ',operator :move-point)
+              (goto-char (or evil-operator-range-beginning orig)))
+             (t
+              (goto-char orig))))))
+       (unwind-protect
+           (let ((evil-inhibit-operator evil-inhibit-operator-value))
+             (unless (and evil-inhibit-operator
+                          (called-interactively-p 'any))
+               ,@body))
+         (setq evil-inhibit-operator-value nil)))))
+
+;; this is used in the `interactive' specification of an operator command
+(defun evil-operator-range (&optional return-type)
+  "Read a motion from the keyboard and return its buffer positions.
+The return value is a list (BEG END), or (BEG END TYPE) if
+RETURN-TYPE is non-nil."
+  (let ((motion (or evil-operator-range-motion
+                    (when (evil-ex-p) 'evil-line)))
+        (type evil-operator-range-type)
+        (range (evil-range (point) (point)))
+        command count modifier)
+    (setq evil-this-type-modified nil)
+    (evil-save-echo-area
+      (cond
+       ;; Ex mode
+       ((and (evil-ex-p) evil-ex-range)
+        (setq range evil-ex-range))
+       ;; Visual selection
+       ((and (not (evil-ex-p)) (evil-visual-state-p))
+        (setq range (evil-visual-range)))
+       ;; active region
+       ((and (not (evil-ex-p)) (region-active-p))
+        (setq range (evil-range (region-beginning)
+                                (region-end)
+                                (or evil-this-type 'exclusive))))
+       (t
+        ;; motion
+        (evil-save-state
+          (unless motion
+            (evil-change-state 'operator)
+            ;; Make linewise operator shortcuts. E.g., "d" yields the
+            ;; shortcut "dd", and "g?" yields shortcuts "g??" and "g?g?".
+            (let ((keys (nth 2 (evil-extract-count (this-command-keys)))))
+              (setq keys (listify-key-sequence keys))
+              (dotimes (var (length keys))
+                (define-key evil-operator-shortcut-map
+                  (vconcat (nthcdr var keys)) 'evil-line)))
+            ;; read motion from keyboard
+            (setq command (evil-read-motion motion)
+                  motion (nth 0 command)
+                  count (nth 1 command)
+                  type (or type (nth 2 command))))
+          (cond
+           ((eq motion #'undefined)
+            (setq range (if return-type '(nil nil nil) '(nil nil))
+                  motion nil))
+           ((or (null motion) ; keyboard-quit
+                (evil-get-command-property motion :suppress-operator))
+            (when (fboundp 'evil-repeat-abort)
+              (evil-repeat-abort))
+            (setq quit-flag t
+                  motion nil))
+           (evil-repeat-count
+            (setq count evil-repeat-count
+                  ;; only the first operator's count is overwritten
+                  evil-repeat-count nil))
+           ((or count current-prefix-arg)
+            ;; multiply operator count and motion count together
+            (setq count
+                  (* (prefix-numeric-value count)
+                     (prefix-numeric-value current-prefix-arg)))))
+          (when motion
+            (let ((evil-state 'operator)
+                  mark-active)
+              ;; calculate motion range
+              (setq range (evil-motion-range
+                           motion
+                           count
+                           type))))
+          ;; update global variables
+          (setq evil-this-motion motion
+                evil-this-motion-count count
+                type (evil-type range type)
+                evil-this-type type))))
+      (when (evil-range-p range)
+        (unless (or (null type) (eq (evil-type range) type))
+          (evil-contract-range range)
+          (evil-set-type range type)
+          (evil-expand-range range))
+        (evil-set-range-properties range nil)
+        (unless return-type
+          (evil-set-type range nil))
+        (setq evil-operator-range-beginning (evil-range-beginning range)
+              evil-operator-range-end (evil-range-end range)
+              evil-operator-range-type (evil-type range)))
+      range)))
+
+(defmacro evil-define-type (type doc &rest body)
+  "Define type TYPE.
+DOC is a general description and shows up in all docstrings.
+It is followed by a list of keywords and functions:
+
+:expand FUNC     Expansion function. This function should accept
+                 two positions in the current buffer, BEG and END,
+                 and return a pair of expanded buffer positions.
+:contract FUNC   The opposite of :expand, optional.
+:one-to-one BOOL Whether expansion is one-to-one. This means that
+                 :expand followed by :contract always returns the
+                 original range.
+:normalize FUNC  Normalization function, optional. This function should
+                 accept two unexpanded positions and adjust them before
+                 expansion. May be used to deal with buffer boundaries.
+:string FUNC     Description function. This takes two buffer positions
+                 and returns a human-readable string, for example,
+                 \"2 lines\".
+
+If further keywords and functions are specified, they are assumed to
+be transformations on buffer positions, like :expand and :contract.
+
+\(fn TYPE DOC [[KEY FUNC]...])"
+  (declare (indent defun)
+           (debug (&define name
+                           [&optional stringp]
+                           [&rest [keywordp function-form]])))
+  (let (args defun-forms func key name plist string sym val)
+    ;; standard values
+    (setq plist (plist-put plist :one-to-one t))
+    ;; keywords
+    (while (keywordp (car-safe body))
+      (setq key (pop body)
+            val (pop body))
+      (if (plist-member plist key) ; not a function
+          (setq plist (plist-put plist key val))
+        (setq func val
+              sym (intern (replace-regexp-in-string
+                           "^:" "" (symbol-name key)))
+              name (intern (format "evil-%s-%s" type sym))
+              args (car (cdr-safe func))
+              string (car (cdr (cdr-safe func)))
+              string (if (stringp string)
+                         (format "%s\n\n" string) "")
+              plist (plist-put plist key `',name))
+        (add-to-list
+         'defun-forms
+         (cond
+          ((eq key :string)
+           `(defun ,name (beg end &rest properties)
+              ,(format "Return size of %s from BEG to END \
+with PROPERTIES.\n\n%s%s" type string doc)
+              (let ((beg (evil-normalize-position beg))
+                    (end (evil-normalize-position end))
+                    (type ',type)
+                    plist range)
+                (when (and beg end)
+                  (save-excursion
+                    (evil-sort beg end)
+                    (unless (plist-get properties :expanded)
+                      (setq range (apply #'evil-expand
+                                         beg end type properties)
+                            beg (evil-range-beginning range)
+                            end (evil-range-end range)
+                            type (evil-type range type)
+                            plist (evil-range-properties range))
+                      (setq properties
+                            (evil-concat-plists properties plist)))
+                    (or (apply #',func beg end
+                               (when ,(> (length args) 2)
+                                 properties))
+                        ""))))))
+          (t
+           `(defun ,name (beg end &rest properties)
+              ,(format "Perform %s transformation on %s from BEG to END \
+with PROPERTIES.\n\n%s%s" sym type string doc)
+              (let ((beg (evil-normalize-position beg))
+                    (end (evil-normalize-position end))
+                    (type ',type)
+                    plist range)
+                (when (and beg end)
+                  (save-excursion
+                    (evil-sort beg end)
+                    (when (memq ,key '(:expand :contract))
+                      (setq properties
+                            (plist-put properties
+                                       :expanded
+                                       ,(eq key :expand))))
+                    (setq range (or (apply #',func beg end
+                                           (when ,(> (length args) 2)
+                                             properties))
+                                    (apply #'evil-range
+                                           beg end type properties))
+                          beg (evil-range-beginning range)
+                          end (evil-range-end range)
+                          type (evil-type range type)
+                          plist (evil-range-properties range))
+                    (setq properties
+                          (evil-concat-plists properties plist))
+                    (apply #'evil-range beg end type properties)))))))
+         t)))
+    ;; :one-to-one requires both or neither of :expand and :contract
+    (when (plist-get plist :expand)
+      (setq plist (plist-put plist :one-to-one
+                             (and (plist-get plist :contract)
+                                  (plist-get plist :one-to-one)))))
+    `(progn
+       (evil-put-property 'evil-type-properties ',type ,@plist)
+       ,@defun-forms
+       ',type)))
+
+(defmacro evil-define-interactive-code (code &rest body)
+  "Define an interactive code.
+PROMPT, if given, is the remainder of the interactive string
+up to the next newline. Command properties may be specified
+via KEY-VALUE pairs. BODY should evaluate to a list of values.
+
+\(fn CODE (PROMPT) [[KEY VALUE]...] BODY...)"
+  (declare (indent defun))
+  (let* ((args (when (and (> (length body) 1)
+                          (listp (car-safe body)))
+                 (pop body)))
+         (doc (when (stringp (car-safe body)) (pop body)))
+         func properties)
+    (while (keywordp (car-safe body))
+      (setq properties
+            (append properties (list (pop body) (pop body)))))
+    (cond
+     (args
+      (setq func `(lambda ,args
+                    ,@(when doc `(,doc))
+                    ,@body)))
+     ((> (length body) 1)
+      (setq func `(progn ,@body)))
+     (t
+      (setq func (car body))))
+    `(eval-and-compile
+       (let* ((code ,code)
+              (entry (assoc code evil-interactive-alist))
+              (value (cons ',func ',properties)))
+         (if entry
+             (setcdr entry value)
+           (push (cons code value) evil-interactive-alist))
+         code))))
+
+;;; Highlighting
+
+(when (fboundp 'font-lock-add-keywords)
+  (font-lock-add-keywords
+   'emacs-lisp-mode
+   ;; Match all `evil-define-' forms except `evil-define-key'.
+   ;; (In the interests of speed, this expression is incomplete
+   ;; and does not match all three-letter words.)
+   '(("(\\(evil-\\(?:ex-\\)?define-\
+\\(?:[^ k][^ e][^ y]\\|[-[:word:]]\\{4,\\}\\)\\)\
+\\>[ \f\t\n\r\v]*\\(\\(?:\\sw\\|\\s_\\)+\\)?"
+      (1 font-lock-keyword-face)
+      (2 font-lock-function-name-face nil t))
+     ("(\\(evil-\\(?:delay\\|narrow\\|signal\\|save\\|with\\(?:out\\)?\\)\
+\\(?:-[-[:word:]]+\\)?\\)\\>\[ \f\t\n\r\v]+"
+      1 font-lock-keyword-face)
+     ("(\\(evil-\\(?:[-[:word:]]\\)*loop\\)\\>[ \f\t\n\r\v]+"
+      1 font-lock-keyword-face))))
+
+(provide 'evil-macros)
+
+;;; evil-macros.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-macros.elc b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-macros.elc
new file mode 100644
index 0000000000..1fd266f3bf
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-macros.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-maps.el b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-maps.el
new file mode 100644
index 0000000000..8335505614
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-maps.el
@@ -0,0 +1,560 @@
+;;; evil-maps.el --- Default keymaps
+
+;; Author: Vegard Øye <vegard_oye at hotmail.com>
+;; Maintainer: Vegard Øye <vegard_oye at hotmail.com>
+
+;; Version: 1.2.13
+
+;;
+;; This file is NOT part of GNU Emacs.
+
+;;; License:
+
+;; This file is part of Evil.
+;;
+;; Evil 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.
+;;
+;; Evil 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 Evil.  If not, see <http://www.gnu.org/licenses/>.
+
+(require 'evil-states)
+(require 'evil-ex)
+(require 'evil-commands)
+(require 'evil-command-window)
+(require 'evil-common)
+
+;;; Code:
+
+;;; Normal state
+
+(define-key evil-normal-state-map "a" 'evil-append)
+(define-key evil-normal-state-map "A" 'evil-append-line)
+(define-key evil-normal-state-map "c" 'evil-change)
+(define-key evil-normal-state-map "C" 'evil-change-line)
+(define-key evil-normal-state-map "d" 'evil-delete)
+(define-key evil-normal-state-map "D" 'evil-delete-line)
+(define-key evil-normal-state-map "i" 'evil-insert)
+(define-key evil-normal-state-map (kbd "<insert>") 'evil-insert)
+(define-key evil-normal-state-map (kbd "<insertchar>") 'evil-insert)
+(define-key evil-normal-state-map "I" 'evil-insert-line)
+(define-key evil-normal-state-map "J" 'evil-join)
+(define-key evil-normal-state-map "m" 'evil-set-marker)
+(define-key evil-normal-state-map "o" 'evil-open-below)
+(define-key evil-normal-state-map "O" 'evil-open-above)
+(define-key evil-normal-state-map "p" 'evil-paste-after)
+(define-key evil-normal-state-map "P" 'evil-paste-before)
+(define-key evil-normal-state-map "q" 'evil-record-macro)
+(define-key evil-normal-state-map "r" 'evil-replace)
+(define-key evil-normal-state-map "R" 'evil-replace-state)
+(define-key evil-normal-state-map "s" 'evil-substitute)
+(define-key evil-normal-state-map "S" 'evil-change-whole-line)
+(define-key evil-normal-state-map "x" 'evil-delete-char)
+(define-key evil-normal-state-map "X" 'evil-delete-backward-char)
+(define-key evil-normal-state-map [deletechar] 'evil-delete-char)
+(define-key evil-normal-state-map "y" 'evil-yank)
+(define-key evil-normal-state-map "Y" 'evil-yank-line)
+(define-key evil-normal-state-map "&" 'evil-ex-repeat-substitute)
+(define-key evil-normal-state-map "g&" 'evil-ex-repeat-global-substitute)
+(define-key evil-normal-state-map "g8" 'what-cursor-position)
+(define-key evil-normal-state-map "ga" 'what-cursor-position)
+(define-key evil-normal-state-map "gi" 'evil-insert-resume)
+(define-key evil-normal-state-map "gJ" 'evil-join-whitespace)
+(define-key evil-normal-state-map "gq" 'evil-fill-and-move)
+(define-key evil-normal-state-map "gw" 'evil-fill)
+(define-key evil-normal-state-map "gu" 'evil-downcase)
+(define-key evil-normal-state-map "gU" 'evil-upcase)
+(define-key evil-normal-state-map "gf" 'find-file-at-point)
+(define-key evil-normal-state-map "gF" 'evil-find-file-at-point-with-line)
+(define-key evil-normal-state-map "gx" 'browse-url-at-point)
+(define-key evil-normal-state-map "g?" 'evil-rot13)
+(define-key evil-normal-state-map "g~" 'evil-invert-case)
+(define-key evil-normal-state-map "zo" 'evil-open-fold)
+(define-key evil-normal-state-map "zO" 'evil-open-fold-rec)
+(define-key evil-normal-state-map "zc" 'evil-close-fold)
+(define-key evil-normal-state-map "za" 'evil-toggle-fold)
+(define-key evil-normal-state-map "zr" 'evil-open-folds)
+(define-key evil-normal-state-map "zm" 'evil-close-folds)
+(define-key evil-normal-state-map "z=" 'ispell-word)
+(define-key evil-normal-state-map "\C-n" 'evil-paste-pop-next)
+(define-key evil-normal-state-map "\C-p" 'evil-paste-pop)
+(define-key evil-normal-state-map "\C-t" 'pop-tag-mark)
+(define-key evil-normal-state-map (kbd "C-.") 'evil-repeat-pop)
+(define-key evil-normal-state-map (kbd "M-.") 'evil-repeat-pop-next)
+(define-key evil-normal-state-map "." 'evil-repeat)
+(define-key evil-normal-state-map "@" 'evil-execute-macro)
+(define-key evil-normal-state-map "\"" 'evil-use-register)
+(define-key evil-normal-state-map "~" 'evil-invert-char)
+(define-key evil-normal-state-map "=" 'evil-indent)
+(define-key evil-normal-state-map "<" 'evil-shift-left)
+(define-key evil-normal-state-map ">" 'evil-shift-right)
+(define-key evil-normal-state-map "ZZ" 'evil-save-modified-and-close)
+(define-key evil-normal-state-map "ZQ" 'evil-quit)
+(define-key evil-normal-state-map (kbd "DEL") 'evil-backward-char)
+(define-key evil-normal-state-map [escape] 'evil-force-normal-state)
+(define-key evil-normal-state-map [remap cua-paste-pop] 'evil-paste-pop)
+(define-key evil-normal-state-map [remap yank-pop] 'evil-paste-pop)
+
+;; go to last change
+(define-key evil-normal-state-map "g;" 'goto-last-change)
+(define-key evil-normal-state-map "g," 'goto-last-change-reverse)
+
+;; undo
+(define-key evil-normal-state-map "u" 'undo)
+(define-key evil-normal-state-map "\C-r" 'redo)
+
+;; window commands
+(define-prefix-command 'evil-window-map)
+(define-key evil-window-map "b" 'evil-window-bottom-right)
+(define-key evil-window-map "c" 'evil-window-delete)
+(define-key evil-window-map "h" 'evil-window-left)
+(define-key evil-window-map "H" 'evil-window-move-far-left)
+(define-key evil-window-map "j" 'evil-window-down)
+(define-key evil-window-map "J" 'evil-window-move-very-bottom)
+(define-key evil-window-map "k" 'evil-window-up)
+(define-key evil-window-map "K" 'evil-window-move-very-top)
+(define-key evil-window-map "l" 'evil-window-right)
+(define-key evil-window-map "L" 'evil-window-move-far-right)
+(define-key evil-window-map "n" 'evil-window-new)
+(define-key evil-window-map "o" 'delete-other-windows)
+(define-key evil-window-map "p" 'evil-window-mru)
+(define-key evil-window-map "q" 'evil-quit)
+(define-key evil-window-map "r" 'evil-window-rotate-downwards)
+(define-key evil-window-map "R" 'evil-window-rotate-upwards)
+(define-key evil-window-map "s" 'evil-window-split)
+(define-key evil-window-map "S" 'evil-window-split)
+(define-key evil-window-map "t" 'evil-window-top-left)
+(define-key evil-window-map "v" 'evil-window-vsplit)
+(define-key evil-window-map "w" 'evil-window-next)
+(define-key evil-window-map "W" 'evil-window-prev)
+(define-key evil-window-map "+" 'evil-window-increase-height)
+(define-key evil-window-map "-" 'evil-window-decrease-height)
+(define-key evil-window-map "_" 'evil-window-set-height)
+(define-key evil-window-map "<" 'evil-window-decrease-width)
+(define-key evil-window-map ">" 'evil-window-increase-width)
+(define-key evil-window-map "=" 'balance-windows)
+(define-key evil-window-map "|" 'evil-window-set-width)
+(define-key evil-window-map "\C-b" 'evil-window-bottom-right)
+(define-key evil-window-map "\C-c" 'evil-window-delete)
+(define-key evil-window-map (kbd "C-S-h") 'evil-window-move-far-left)
+(define-key evil-window-map (kbd "C-S-j") 'evil-window-move-very-bottom)
+(define-key evil-window-map (kbd "C-S-k") 'evil-window-move-very-top)
+(define-key evil-window-map (kbd "C-S-l") 'evil-window-move-far-right)
+(define-key evil-window-map "\C-n" 'evil-window-new)
+(define-key evil-window-map "\C-o" 'delete-other-windows)
+(define-key evil-window-map "\C-p" 'evil-window-mru)
+(define-key evil-window-map "\C-r" 'evil-window-rotate-downwards)
+(define-key evil-window-map (kbd "C-S-r") 'evil-window-rotate-upwards)
+(define-key evil-window-map "\C-s" 'evil-window-split)
+(define-key evil-window-map (kbd "C-S-s") 'evil-window-split)
+(define-key evil-window-map "\C-t" 'evil-window-top-left)
+(define-key evil-window-map "\C-v" 'evil-window-vsplit)
+(define-key evil-window-map "\C-w" 'evil-window-next)
+(define-key evil-window-map (kbd "C-S-W") 'evil-window-prev)
+(define-key evil-window-map "\C-_" 'evil-window-set-height)
+(define-key evil-window-map "\C-f" 'ffap-other-window)
+
+;;; Motion state
+
+;; "0" is a special command when called first
+(evil-redirect-digit-argument evil-motion-state-map "0" 'evil-beginning-of-line)
+(define-key evil-motion-state-map "1" 'digit-argument)
+(define-key evil-motion-state-map "2" 'digit-argument)
+(define-key evil-motion-state-map "3" 'digit-argument)
+(define-key evil-motion-state-map "4" 'digit-argument)
+(define-key evil-motion-state-map "5" 'digit-argument)
+(define-key evil-motion-state-map "6" 'digit-argument)
+(define-key evil-motion-state-map "7" 'digit-argument)
+(define-key evil-motion-state-map "8" 'digit-argument)
+(define-key evil-motion-state-map "9" 'digit-argument)
+(define-key evil-motion-state-map "b" 'evil-backward-word-begin)
+(define-key evil-motion-state-map "B" 'evil-backward-WORD-begin)
+(define-key evil-motion-state-map "e" 'evil-forward-word-end)
+(define-key evil-motion-state-map "E" 'evil-forward-WORD-end)
+(define-key evil-motion-state-map "f" 'evil-find-char)
+(define-key evil-motion-state-map "F" 'evil-find-char-backward)
+(define-key evil-motion-state-map "G" 'evil-goto-line)
+(define-key evil-motion-state-map "h" 'evil-backward-char)
+(define-key evil-motion-state-map "H" 'evil-window-top)
+(define-key evil-motion-state-map "j" 'evil-next-line)
+(define-key evil-motion-state-map "k" 'evil-previous-line)
+(define-key evil-motion-state-map "l" 'evil-forward-char)
+(define-key evil-motion-state-map " " 'evil-forward-char)
+(define-key evil-motion-state-map "K" 'evil-lookup)
+(define-key evil-motion-state-map "L" 'evil-window-bottom)
+(define-key evil-motion-state-map "M" 'evil-window-middle)
+(define-key evil-motion-state-map "n" 'evil-search-next)
+(define-key evil-motion-state-map "N" 'evil-search-previous)
+(define-key evil-motion-state-map "t" 'evil-find-char-to)
+(define-key evil-motion-state-map "T" 'evil-find-char-to-backward)
+(define-key evil-motion-state-map "w" 'evil-forward-word-begin)
+(define-key evil-motion-state-map "W" 'evil-forward-WORD-begin)
+(define-key evil-motion-state-map "y" 'evil-yank)
+(define-key evil-motion-state-map "Y" 'evil-yank-line)
+(define-key evil-motion-state-map "gd" 'evil-goto-definition)
+(define-key evil-motion-state-map "ge" 'evil-backward-word-end)
+(define-key evil-motion-state-map "gE" 'evil-backward-WORD-end)
+(define-key evil-motion-state-map "gg" 'evil-goto-first-line)
+(define-key evil-motion-state-map "gj" 'evil-next-visual-line)
+(define-key evil-motion-state-map "gk" 'evil-previous-visual-line)
+(define-key evil-motion-state-map "g0" 'evil-beginning-of-visual-line)
+(define-key evil-motion-state-map "g_" 'evil-last-non-blank)
+(define-key evil-motion-state-map "g^" 'evil-first-non-blank-of-visual-line)
+(define-key evil-motion-state-map "gm" 'evil-middle-of-visual-line)
+(define-key evil-motion-state-map "g$" 'evil-end-of-visual-line)
+(define-key evil-motion-state-map "g\C-]" 'evil-jump-to-tag)
+(define-key evil-motion-state-map "{" 'evil-backward-paragraph)
+(define-key evil-motion-state-map "}" 'evil-forward-paragraph)
+(define-key evil-motion-state-map "#" 'evil-search-word-backward)
+(define-key evil-motion-state-map "g#" 'evil-search-unbounded-word-backward)
+(define-key evil-motion-state-map "$" 'evil-end-of-line)
+(define-key evil-motion-state-map "%" 'evil-jump-item)
+(define-key evil-motion-state-map "`" 'evil-goto-mark)
+(define-key evil-motion-state-map "'" 'evil-goto-mark-line)
+(define-key evil-motion-state-map "(" 'evil-backward-sentence-begin)
+(define-key evil-motion-state-map ")" 'evil-forward-sentence-begin)
+(define-key evil-motion-state-map "]]" 'evil-forward-section-begin)
+(define-key evil-motion-state-map "][" 'evil-forward-section-end)
+(define-key evil-motion-state-map "[[" 'evil-backward-section-begin)
+(define-key evil-motion-state-map "[]" 'evil-backward-section-end)
+(define-key evil-motion-state-map "[(" 'evil-previous-open-paren)
+(define-key evil-motion-state-map "])" 'evil-next-close-paren)
+(define-key evil-motion-state-map "[{" 'evil-previous-open-brace)
+(define-key evil-motion-state-map "]}" 'evil-next-close-brace)
+(define-key evil-motion-state-map "]s" 'evil-next-flyspell-error)
+(define-key evil-motion-state-map "[s" 'evil-prev-flyspell-error)
+(define-key evil-motion-state-map "*" 'evil-search-word-forward)
+(define-key evil-motion-state-map "g*" 'evil-search-unbounded-word-forward)
+(define-key evil-motion-state-map "," 'evil-repeat-find-char-reverse)
+(define-key evil-motion-state-map "/" 'evil-search-forward)
+(define-key evil-motion-state-map ";" 'evil-repeat-find-char)
+(define-key evil-motion-state-map "?" 'evil-search-backward)
+(define-key evil-motion-state-map "|" 'evil-goto-column)
+(define-key evil-motion-state-map "^" 'evil-first-non-blank)
+(define-key evil-motion-state-map "+" 'evil-next-line-first-non-blank)
+(define-key evil-motion-state-map "_" 'evil-next-line-1-first-non-blank)
+(define-key evil-motion-state-map "-" 'evil-previous-line-first-non-blank)
+(define-key evil-motion-state-map "\C-w" 'evil-window-map)
+(define-key evil-motion-state-map (kbd "C-6") 'evil-switch-to-windows-last-buffer)
+(define-key evil-motion-state-map "\C-]" 'evil-jump-to-tag)
+(define-key evil-motion-state-map (kbd "C-b") 'evil-scroll-page-up)
+(define-key evil-motion-state-map (kbd "C-d") 'evil-scroll-down)
+(define-key evil-motion-state-map (kbd "C-e") 'evil-scroll-line-down)
+(define-key evil-motion-state-map (kbd "C-f") 'evil-scroll-page-down)
+(define-key evil-motion-state-map (kbd "C-o") 'evil-jump-backward)
+(define-key evil-motion-state-map (kbd "C-y") 'evil-scroll-line-up)
+(define-key evil-motion-state-map (kbd "RET") 'evil-ret)
+(define-key evil-motion-state-map "\\" 'evil-execute-in-emacs-state)
+(define-key evil-motion-state-map "z^" 'evil-scroll-top-line-to-bottom)
+(define-key evil-motion-state-map "z+" 'evil-scroll-bottom-line-to-top)
+(define-key evil-motion-state-map "zt" 'evil-scroll-line-to-top)
+;; TODO: z RET has an advanced form taking an count before the RET
+;; but this requires again a special state with a single command
+;; bound to RET
+(define-key evil-motion-state-map (vconcat "z" [return]) "zt^")
+(define-key evil-motion-state-map (kbd "z RET") (vconcat "z" [return]))
+(define-key evil-motion-state-map "zz" 'evil-scroll-line-to-center)
+(define-key evil-motion-state-map "z." "zz^")
+(define-key evil-motion-state-map "zb" 'evil-scroll-line-to-bottom)
+(define-key evil-motion-state-map "z-" "zb^")
+(define-key evil-motion-state-map "v" 'evil-visual-char)
+(define-key evil-motion-state-map "V" 'evil-visual-line)
+(define-key evil-motion-state-map "\C-v" 'evil-visual-block)
+(define-key evil-motion-state-map "gv" 'evil-visual-restore)
+(define-key evil-motion-state-map (kbd "C-^") 'evil-buffer)
+(define-key evil-motion-state-map [left] 'evil-backward-char)
+(define-key evil-motion-state-map [right] 'evil-forward-char)
+(define-key evil-motion-state-map [up] 'evil-previous-line)
+(define-key evil-motion-state-map [down] 'evil-next-line)
+(define-key evil-motion-state-map "zl" 'evil-scroll-column-right)
+(define-key evil-motion-state-map [?z right] "zl")
+(define-key evil-motion-state-map "zh" 'evil-scroll-column-left)
+(define-key evil-motion-state-map [?z left] "zh")
+(define-key evil-motion-state-map "zL" 'evil-scroll-right)
+(define-key evil-motion-state-map "zH" 'evil-scroll-left)
+(define-key evil-motion-state-map
+  (read-kbd-macro evil-toggle-key) 'evil-emacs-state)
+
+;; text objects
+(define-key evil-outer-text-objects-map "w" 'evil-a-word)
+(define-key evil-outer-text-objects-map "W" 'evil-a-WORD)
+(define-key evil-outer-text-objects-map "s" 'evil-a-sentence)
+(define-key evil-outer-text-objects-map "p" 'evil-a-paragraph)
+(define-key evil-outer-text-objects-map "b" 'evil-a-paren)
+(define-key evil-outer-text-objects-map "(" 'evil-a-paren)
+(define-key evil-outer-text-objects-map ")" 'evil-a-paren)
+(define-key evil-outer-text-objects-map "[" 'evil-a-bracket)
+(define-key evil-outer-text-objects-map "]" 'evil-a-bracket)
+(define-key evil-outer-text-objects-map "B" 'evil-a-curly)
+(define-key evil-outer-text-objects-map "{" 'evil-a-curly)
+(define-key evil-outer-text-objects-map "}" 'evil-a-curly)
+(define-key evil-outer-text-objects-map "<" 'evil-an-angle)
+(define-key evil-outer-text-objects-map ">" 'evil-an-angle)
+(define-key evil-outer-text-objects-map "'" 'evil-a-single-quote)
+(define-key evil-outer-text-objects-map "\"" 'evil-a-double-quote)
+(define-key evil-outer-text-objects-map "`" 'evil-a-back-quote)
+(define-key evil-outer-text-objects-map "t" 'evil-a-tag)
+(define-key evil-outer-text-objects-map "o" 'evil-a-symbol)
+(define-key evil-inner-text-objects-map "w" 'evil-inner-word)
+(define-key evil-inner-text-objects-map "W" 'evil-inner-WORD)
+(define-key evil-inner-text-objects-map "s" 'evil-inner-sentence)
+(define-key evil-inner-text-objects-map "p" 'evil-inner-paragraph)
+(define-key evil-inner-text-objects-map "b" 'evil-inner-paren)
+(define-key evil-inner-text-objects-map "(" 'evil-inner-paren)
+(define-key evil-inner-text-objects-map ")" 'evil-inner-paren)
+(define-key evil-inner-text-objects-map "[" 'evil-inner-bracket)
+(define-key evil-inner-text-objects-map "]" 'evil-inner-bracket)
+(define-key evil-inner-text-objects-map "B" 'evil-inner-curly)
+(define-key evil-inner-text-objects-map "{" 'evil-inner-curly)
+(define-key evil-inner-text-objects-map "}" 'evil-inner-curly)
+(define-key evil-inner-text-objects-map "<" 'evil-inner-angle)
+(define-key evil-inner-text-objects-map ">" 'evil-inner-angle)
+(define-key evil-inner-text-objects-map "'" 'evil-inner-single-quote)
+(define-key evil-inner-text-objects-map "\"" 'evil-inner-double-quote)
+(define-key evil-inner-text-objects-map "`" 'evil-inner-back-quote)
+(define-key evil-inner-text-objects-map "t" 'evil-inner-tag)
+(define-key evil-inner-text-objects-map "o" 'evil-inner-symbol)
+(define-key evil-motion-state-map "gn" 'evil-next-match)
+(define-key evil-motion-state-map "gN" 'evil-previous-match)
+
+(when evil-want-C-i-jump
+  (define-key evil-motion-state-map (kbd "C-i") 'evil-jump-forward))
+
+(when evil-want-C-u-scroll
+  (define-key evil-motion-state-map (kbd "C-u") 'evil-scroll-up))
+
+;;; Visual state
+
+(define-key evil-visual-state-map "A" 'evil-append)
+(define-key evil-visual-state-map "I" 'evil-insert)
+(define-key evil-visual-state-map "o" 'exchange-point-and-mark)
+(define-key evil-visual-state-map "O" 'evil-visual-exchange-corners)
+(define-key evil-visual-state-map "R" 'evil-change)
+(define-key evil-visual-state-map "u" 'evil-downcase)
+(define-key evil-visual-state-map "U" 'evil-upcase)
+(define-key evil-visual-state-map "z=" 'ispell-word)
+(define-key evil-visual-state-map "a" evil-outer-text-objects-map)
+(define-key evil-visual-state-map "i" evil-inner-text-objects-map)
+(define-key evil-visual-state-map (kbd "<insert>") 'undefined)
+(define-key evil-visual-state-map (kbd "<insertchar>") 'undefined)
+(define-key evil-visual-state-map [remap evil-repeat] 'undefined)
+(define-key evil-visual-state-map [escape] 'evil-exit-visual-state)
+
+;;; Operator-Pending state
+
+(define-key evil-operator-state-map "a" evil-outer-text-objects-map)
+(define-key evil-operator-state-map "i" evil-inner-text-objects-map)
+;; (define-key evil-operator-state-map [escape] 'keyboard-quit)
+
+;;; Insert state
+
+(defvar evil-insert-state-bindings
+  `(("\C-v" . quoted-insert)
+    ("\C-k" . evil-insert-digraph)
+    ("\C-o" . evil-execute-in-normal-state)
+    ("\C-r" . evil-paste-from-register)
+    ("\C-y" . evil-copy-from-above)
+    ("\C-e" . evil-copy-from-below)
+    ("\C-n" . evil-complete-next)
+    ("\C-p" . evil-complete-previous)
+    ("\C-x\C-n" . evil-complete-next-line)
+    ("\C-x\C-p" . evil-complete-previous-line)
+    ("\C-t" . evil-shift-right-line)
+    ("\C-d" . evil-shift-left-line)
+    ("\C-a" . evil-paste-last-insertion)
+    ([remap delete-backward-char] . evil-delete-backward-char-and-join)
+    ,(if evil-want-C-w-delete
+         '("\C-w" . evil-delete-backward-word)
+       '("\C-w" . evil-window-map))
+    ([mouse-2] . mouse-yank-primary))
+  "Evil's bindings for insert state (for
+`evil-insert-state-map'), excluding <delete>, <escape>, and
+`evil-toggle-key'.")
+
+(defun evil-update-insert-state-bindings (&optional _option-name remove force)
+  "Update bindings in `evil-insert-state-map'.
+If no arguments are given add the bindings specified in
+`evil-insert-state-bindings'. If REMOVE is non nil, remove only
+these bindings. Unless FORCE is non nil, this will not
+overwriting existing bindings, which means bindings will not be
+added if one already exists for a key and only default bindings
+are removed.
+
+Note that <delete>, <escape> and `evil-toggle-key' are not
+included in `evil-insert-state-bindings' by default."
+  (interactive)
+  (dolist (binding evil-insert-state-bindings)
+    (cond
+     ((and remove
+           (or force
+               ;; Only remove if the default binding has not changed
+               (eq (evil-lookup-key evil-insert-state-map (car binding))
+                   (cdr binding))))
+      (define-key evil-insert-state-map (car binding) nil))
+     ((and (null remove)
+           (or force
+               ;; Check to see that nothing is bound here before adding
+               (not (evil-lookup-key evil-insert-state-map (car binding)))))
+      (define-key evil-insert-state-map (car binding) (cdr binding))))))
+
+(define-key evil-insert-state-map [delete] 'delete-char)
+(define-key evil-insert-state-map [escape] 'evil-normal-state)
+(define-key evil-insert-state-map
+  (read-kbd-macro evil-toggle-key) 'evil-emacs-state)
+
+;;; Replace state
+
+(define-key evil-replace-state-map (kbd "DEL") 'evil-replace-backspace)
+(define-key evil-replace-state-map [escape] 'evil-normal-state)
+
+;;; Emacs state
+
+(define-key evil-emacs-state-map
+  (read-kbd-macro evil-toggle-key) 'evil-exit-emacs-state)
+
+(when evil-want-C-w-in-emacs-state
+  (define-key evil-emacs-state-map "\C-w" 'evil-window-map))
+
+;;; Mouse
+(define-key evil-motion-state-map [down-mouse-1] 'evil-mouse-drag-region)
+(define-key evil-visual-state-map [mouse-2] 'evil-exit-visual-and-repeat)
+(define-key evil-normal-state-map [mouse-2] 'mouse-yank-primary)
+
+;; Ex
+(define-key evil-motion-state-map ":" 'evil-ex)
+(define-key evil-motion-state-map "!" 'evil-shell-command)
+
+(evil-ex-define-cmd "e[dit]" 'evil-edit)
+(evil-ex-define-cmd "w[rite]" 'evil-write)
+(evil-ex-define-cmd "wa[ll]" 'evil-write-all)
+(evil-ex-define-cmd "sav[eas]" 'evil-save)
+(evil-ex-define-cmd "r[ead]" 'evil-read)
+(evil-ex-define-cmd "b[uffer]" 'evil-buffer)
+(evil-ex-define-cmd "bn[ext]" 'evil-next-buffer)
+(evil-ex-define-cmd "bp[revious]" 'evil-prev-buffer)
+(evil-ex-define-cmd "bN[ext]" "bprevious")
+(evil-ex-define-cmd "sb[uffer]" 'evil-split-buffer)
+(evil-ex-define-cmd "sbn[ext]" 'evil-split-next-buffer)
+(evil-ex-define-cmd "sbp[revious]" 'evil-split-prev-buffer)
+(evil-ex-define-cmd "sbN[ext]" "sbprevious")
+(evil-ex-define-cmd "buffers" 'buffer-menu)
+(evil-ex-define-cmd "files" 'evil-show-files)
+(evil-ex-define-cmd "ls" "buffers")
+
+(evil-ex-define-cmd "c[hange]" 'evil-change)
+(evil-ex-define-cmd "co[py]" 'evil-copy)
+(evil-ex-define-cmd "t" "copy")
+(evil-ex-define-cmd "m[ove]" 'evil-move)
+(evil-ex-define-cmd "d[elete]" 'evil-ex-delete)
+(evil-ex-define-cmd "y[ank]" 'evil-ex-yank)
+(evil-ex-define-cmd "go[to]" 'evil-goto-char)
+(evil-ex-define-cmd "j[oin]" 'evil-ex-join)
+(evil-ex-define-cmd "le[ft]" 'evil-align-left)
+(evil-ex-define-cmd "ri[ght]" 'evil-align-right)
+(evil-ex-define-cmd "ce[nter]" 'evil-align-center)
+(evil-ex-define-cmd "sp[lit]" 'evil-window-split)
+(evil-ex-define-cmd "vs[plit]" 'evil-window-vsplit)
+(evil-ex-define-cmd "new" 'evil-window-new)
+(evil-ex-define-cmd "ene[w]" 'evil-buffer-new)
+(evil-ex-define-cmd "vne[w]" 'evil-window-vnew)
+(evil-ex-define-cmd "clo[se]" 'evil-window-delete)
+(evil-ex-define-cmd "on[ly]" 'delete-other-windows)
+(evil-ex-define-cmd "q[uit]" 'evil-quit)
+(evil-ex-define-cmd "wq" 'evil-save-and-close)
+(evil-ex-define-cmd "quita[ll]" 'evil-quit-all)
+(evil-ex-define-cmd "qa[ll]" "quitall")
+(evil-ex-define-cmd "cq[uit]" 'evil-quit-all-with-error-code)
+(evil-ex-define-cmd "wqa[ll]" 'evil-save-and-quit)
+(evil-ex-define-cmd "xa[ll]" "wqall")
+(evil-ex-define-cmd "x[it]" 'evil-save-modified-and-close)
+(evil-ex-define-cmd "exi[t]" 'evil-save-modified-and-close)
+(evil-ex-define-cmd "bd[elete]" 'evil-delete-buffer)
+(evil-ex-define-cmd "bw[ipeout]" 'evil-delete-buffer)
+(evil-ex-define-cmd "g[lobal]" 'evil-ex-global)
+(evil-ex-define-cmd "v[global]" 'evil-ex-global-inverted)
+(evil-ex-define-cmd "norm[al]" 'evil-ex-normal)
+(evil-ex-define-cmd "s[ubstitute]" 'evil-ex-substitute)
+(evil-ex-define-cmd "&" 'evil-ex-repeat-substitute)
+(evil-ex-define-cmd "&&" 'evil-ex-repeat-substitute-with-flags)
+(evil-ex-define-cmd "~" 'evil-ex-repeat-substitute-with-search)
+(evil-ex-define-cmd "~&" 'evil-ex-repeat-substitute-with-search-and-flags)
+(evil-ex-define-cmd "registers" 'evil-show-registers)
+(evil-ex-define-cmd "marks" 'evil-show-marks)
+(evil-ex-define-cmd "delm[arks]" 'evil-delete-marks)
+(evil-ex-define-cmd "ju[mps]" 'evil-show-jumps)
+(evil-ex-define-cmd "noh[lsearch]" 'evil-ex-nohighlight)
+(evil-ex-define-cmd "f[ile]" 'evil-show-file-info)
+(evil-ex-define-cmd "<" 'evil-shift-left)
+(evil-ex-define-cmd ">" 'evil-shift-right)
+(evil-ex-define-cmd "=" 'evil-ex-line-number)
+(evil-ex-define-cmd "!" 'evil-shell-command)
+(evil-ex-define-cmd "@:" 'evil-ex-repeat)
+(evil-ex-define-cmd "mak[e]" 'evil-make)
+(evil-ex-define-cmd "cc" 'evil-goto-error)
+(evil-ex-define-cmd "cfir[st]" 'first-error)
+(evil-ex-define-cmd "cr[ewind]" 'first-error)
+(evil-ex-define-cmd "cn[ext]" 'next-error)
+(evil-ex-define-cmd "cp[revious]" 'previous-error)
+(evil-ex-define-cmd "set-initial-state" 'evil-ex-set-initial-state)
+(evil-ex-define-cmd "show-digraphs" 'evil-ex-show-digraphs)
+(evil-ex-define-cmd "sor[t]" 'evil-ex-sort)
+(evil-ex-define-cmd "res[ize]" 'evil-ex-resize)
+
+;; search command line
+(define-key evil-ex-search-keymap "\d" #'evil-ex-delete-backward-char)
+(define-key evil-ex-search-keymap "\C-r" 'evil-paste-from-register)
+(define-key evil-ex-search-keymap "\C-n" 'next-history-element)
+(define-key evil-ex-search-keymap "\C-p" 'previous-history-element)
+
+;; ex command line
+(define-key evil-ex-completion-map "\d" #'evil-ex-delete-backward-char)
+(define-key evil-ex-completion-map "\t" #'evil-ex-completion)
+(define-key evil-ex-completion-map [tab] #'evil-ex-completion)
+(define-key evil-ex-completion-map [remap completion-at-point] #'evil-ex-completion)
+(define-key evil-ex-completion-map "\C-a" 'evil-ex-completion)
+(define-key evil-ex-completion-map "\C-b" 'move-beginning-of-line)
+(define-key evil-ex-completion-map "\C-c" 'abort-recursive-edit)
+(define-key evil-ex-completion-map "\C-d" 'evil-ex-completion)
+(define-key evil-ex-completion-map "\C-g" 'abort-recursive-edit)
+(define-key evil-ex-completion-map "\C-k" 'evil-insert-digraph)
+(define-key evil-ex-completion-map "\C-l" 'evil-ex-completion)
+(define-key evil-ex-completion-map "\C-p" #'previous-complete-history-element)
+(define-key evil-ex-completion-map "\C-r" 'evil-paste-from-register)
+(define-key evil-ex-completion-map "\C-n" #'next-complete-history-element)
+(define-key evil-ex-completion-map "\C-u" 'evil-delete-whole-line)
+(define-key evil-ex-completion-map "\C-v" #'quoted-insert)
+(define-key evil-ex-completion-map "\C-w" 'backward-kill-word)
+(define-key evil-ex-completion-map [escape] 'abort-recursive-edit)
+(define-key evil-ex-completion-map [S-left] 'backward-word)
+(define-key evil-ex-completion-map [S-right] 'forward-word)
+(define-key evil-ex-completion-map [up] 'previous-complete-history-element)
+(define-key evil-ex-completion-map [down] 'next-complete-history-element)
+(define-key evil-ex-completion-map [prior] 'previous-history-element)
+(define-key evil-ex-completion-map [next] 'next-history-element)
+(define-key evil-ex-completion-map [return] 'exit-minibuffer)
+(define-key evil-ex-completion-map (kbd "RET") 'exit-minibuffer)
+
+;; evil-read-key
+(define-key evil-read-key-map (kbd "ESC") #'keyboard-quit)
+(define-key evil-read-key-map (kbd "C-]") #'keyboard-quit)
+(define-key evil-read-key-map (kbd "C-q") #'evil-read-quoted-char)
+(define-key evil-read-key-map (kbd "C-v") #'evil-read-quoted-char)
+(define-key evil-read-key-map (kbd "C-k") #'evil-read-digraph-char)
+(define-key evil-read-key-map "\r" "\n")
+
+;; command line window
+(evil-define-key 'normal
+  evil-command-window-mode-map (kbd "RET") 'evil-command-window-execute)
+(evil-define-key 'insert
+  evil-command-window-mode-map (kbd "RET") 'evil-command-window-execute)
+
+(provide 'evil-maps)
+
+;;; evil-maps.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-maps.elc b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-maps.elc
new file mode 100644
index 0000000000..2a48c4efe3
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-maps.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-pkg.el b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-pkg.el
new file mode 100644
index 0000000000..94956b779c
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-pkg.el
@@ -0,0 +1,8 @@
+(define-package "evil" "20180517.1300" "Extensible Vi layer for Emacs."
+  '((emacs "24.1")
+    (undo-tree "0.6.3")
+    (goto-chg "1.6")
+    (cl-lib "0.5")))
+;; Local Variables:
+;; no-byte-compile: t
+;; End:
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-repeat.el b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-repeat.el
new file mode 100644
index 0000000000..80ef0bf5eb
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-repeat.el
@@ -0,0 +1,638 @@
+;;; evil-repeat.el --- Repeat system
+
+;; Author: Frank Fischer <frank.fischer at mathematik.tu-chemnitz.de>
+;; Maintainer: Vegard Øye <vegard_oye at hotmail.com>
+
+;; Version: 1.2.13
+
+;;
+;; This file is NOT part of GNU Emacs.
+
+;;; License:
+
+;; This file is part of Evil.
+;;
+;; Evil 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.
+;;
+;; Evil 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 Evil.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; A repeat begins when leaving Normal state; it ends when re-entering
+;; Normal state. The diagram below shows possible routes between
+;; Normal state (N), Insert state (I), Visual state (V),
+;; Operator-Pending state (O) and Replace state (R). (Emacs state
+;; is an exception: nothing is repeated in that state.)
+;;                              ___
+;;                             /   \
+;;                             | R |
+;;                             \___/
+;;                             ^   |
+;;                             |   |
+;;               ___           |___V           ___
+;;              /   \ <------- /   \ -------> /   \
+;;              | V |          | N |          | O |
+;;              \___/ -------> \___/ <------- \___/
+;;                  |          |   ^          |
+;;                  |          |   |          |
+;;                  |          V___|          |
+;;                  |          /   \          |
+;;                  +--------> | I | <--------+
+;;                             \___/
+;;
+;; The recording of a repeat is started in one of two cases: Either a
+;; command is about being executed (in pre-command-hook) or normal
+;; state is exited. The recording is stopped whenever a command has
+;; being completed and evil is in normal state afterwards. Therefore,
+;; a non-inserting command in normal-state is recorded as a single
+;; repeat unit. In contrast, if the command leaves normal state and
+;; starts insert-state, all commands that are executed until
+;; insert-state is left and normal state is reactivated are recorded
+;; together in one repeat unit. In other words, a repeat unit consists
+;; of all commands that are executed starting and ending in normal
+;; state.
+;;
+;; Not all commands are recorded. There are several commands that are
+;; completely ignored and other commands that even abort the currently
+;; active recording, e.g., commands that change the current buffer.
+;;
+;; During recording the repeat information is appended to the variable
+;; `evil-repeat-info', which is cleared when the recording
+;; starts. This accumulated repeat information is put into the
+;; `evil-repeat-ring' when the recording is finished. The dot command,
+;; `\[evil-repeat]' (`evil-repeat') replays the most recent entry in
+;; the ring, preceeding repeats can be replayed using
+;; `\[evil-repeat-pop]' (`evil-repeat-pop').
+;;
+;; Repeat information can be stored in almost arbitrary form. How the
+;; repeat information for each single command is recored is determined
+;; by the :repeat property of the command. This property has the
+;; following interpretation:
+;;
+;; t         record commands by storing the key-sequence that invoked it
+;; nil       ignore this command completely
+;; ignore    synonym to nil
+;; motion    command is recorded by storing the key-sequence but only in
+;;           insert state, otherwise it is ignored.
+;; abort     stop recording of repeat information immediately
+;; change    record commands by storing buffer changes
+;; SYMBOL    if SYMBOL is contained as key in `evil-repeat-types'
+;;           call the corresponding (function-)value, otherwise
+;;           call the function associated with SYMBOL. In both
+;;           cases the function should take exactly one argument
+;;           which is either 'pre or 'post depending on whether
+;;           the function is called before or after the execution
+;;           of the command.
+;;
+;; Therefore, using a certain SYMBOL one can write specific repeation
+;; functions for each command.
+;;
+;; Each value of ring `evil-repeat-info', i.e., each single repeat
+;; information must be one of the following two possibilities:
+;; If element is a sequence, it is regarded as a key-sequence to
+;; be repeated. Otherwise the element must be a list
+;; (FUNCTION PARAMS ...) which will be called using
+;; (apply FUNCTION PARAMS) whenever this repeat is being executed.
+;;
+;; A user supplied repeat function can use the functions
+;; `evil-record-repeat' to append further repeat-information of the
+;; form described above to `evil-repeat-info'. See the implementation
+;; of `evil-repeat-keystrokes' and `evil-repeat-changes' for examples.
+;; Those functions are called in different situations before and after
+;; the execution of a command. Each function should take one argument
+;; which can be either 'pre, 'post, 'pre-operator or 'post-operator
+;; specifying when the repeat function has been called. If the command
+;; is a usual command the function is called with 'pre before the
+;; command is executed and with 'post after the command has been
+;; executed.
+;;
+;; The repeat information is executed with `evil-execute-repeat-info',
+;; which passes key-sequence elements to `execute-kbd-macro' and
+;; executes other elements as defined above.  A special version is
+;; `evil-execute-repeat-info-with-count'.  This function works as
+;; `evil-execute-repeat-info', but replaces the count of the first
+;; command. This is done by parsing the key-sequence, ignoring all
+;; calls to `digit-prefix-argument' and `negative-argument', and
+;; prepending the count as a string to the vector of the remaining
+;; key-sequence.
+
+(require 'evil-states)
+
+;;; Code:
+
+(declare-function evil-visual-state-p "evil-visual")
+(declare-function evil-visual-range "evil-visual")
+(declare-function evil-visual-char "evil-visual")
+(declare-function evil-visual-line "evil-visual")
+(declare-function evil-visual-block "evil-visual")
+
+(defmacro evil-without-repeat (&rest body)
+  (declare (indent defun)
+           (debug t))
+  `(let ((pre-command-hook (remq 'evil-repeat-pre-hook pre-command-hook))
+         (post-command-hook (remq 'evil-repeat-post-hook post-command-hook)))
+     ,@body
+     (evil-repeat-abort)))
+
+(defsubst evil-repeat-recording-p ()
+  "Returns non-nil iff a recording is in progress."
+  (eq evil-recording-repeat t))
+
+(defun evil-repeat-start ()
+  "Start recording a new repeat into `evil-repeat-info'."
+  (evil-repeat-reset t)
+  (evil-repeat-record-buffer)
+  (when (evil-visual-state-p)
+    (let* ((range (evil-visual-range))
+           (beg (evil-range-beginning range))
+           (end (1- (evil-range-end range)))
+           (nfwdlines (evil-count-lines beg end)))
+      (evil-repeat-record
+       (cond
+        ((eq evil-visual-selection 'char)
+         (list #'evil-repeat-visual-char
+               nfwdlines
+               (- end
+                  (if (zerop nfwdlines)
+                      beg
+                    (save-excursion
+                      (goto-char end)
+                      (line-beginning-position))))))
+        ((eq evil-visual-selection 'line)
+         (list #'evil-repeat-visual-line nfwdlines))
+        ((eq evil-visual-selection 'block)
+         (list #'evil-repeat-visual-block
+               nfwdlines
+               (abs (- (evil-column beg) (evil-column end))))))))))
+
+(defun evil-repeat-stop ()
+  "Stop recording a repeat.
+Update `evil-repeat-ring' with the accumulated changes
+in `evil-repeat-info' and clear variables."
+  (unwind-protect
+      (when (evil-repeat-recording-p)
+        (setq evil-repeat-info
+              (evil-normalize-repeat-info evil-repeat-info))
+        (when (and evil-repeat-info evil-repeat-ring)
+          (ring-insert evil-repeat-ring evil-repeat-info)))
+    (evil-repeat-reset nil)))
+
+(defun evil-repeat-abort ()
+  "Abort current repeation."
+  (evil-repeat-reset 'abort))
+
+(defun evil-repeat-reset (flag)
+  "Clear all repeat recording variables.
+Set `evil-recording-repeat' to FLAG."
+  (setq evil-recording-repeat flag
+        evil-repeat-info nil
+        evil-repeat-buffer nil))
+
+(defsubst evil-repeat-record-position (&optional pos)
+  "Set `evil-repeat-pos' to POS or point."
+  (setq evil-repeat-pos (or pos (point))))
+
+(defun evil-repeat-record-buffer ()
+  "Set `evil-repeat-buffer' to the current buffer."
+  (unless (minibufferp)
+    (setq evil-repeat-buffer (current-buffer))))
+
+(defmacro evil-save-repeat-info (&rest body)
+  "Execute BODY, protecting the values of repeat variables."
+  (declare (indent defun)
+           (debug t))
+  `(let (evil-repeat-ring
+         evil-recording-repeat
+         evil-recording-current-command
+         evil-repeat-info
+         evil-repeat-changes
+         evil-repeat-pos
+         evil-repeat-keys
+         evil-repeat-buffer
+         this-command
+         last-command)
+     ,@body))
+
+(defun evil-repeat-different-buffer-p (&optional strict)
+  "Whether the buffer has changed in a repeat.
+If STRICT is non-nil, returns t if the previous buffer
+is unknown; otherwise returns t only if the previous
+buffer is known and different from the current buffer."
+  (and (or (buffer-live-p evil-repeat-buffer) strict)
+       (not (minibufferp))
+       (not (eq (current-buffer) evil-repeat-buffer))))
+
+(defun evil-repeat-type (command &optional default)
+  "Return the :repeat property of COMMAND.
+If COMMAND doesn't have this property, return DEFAULT."
+  (when (functionp command) ; ignore keyboard macros
+    (let* ((type (evil-get-command-property command :repeat default))
+           (repeat-type (assq type evil-repeat-types)))
+      (if repeat-type (cdr repeat-type) type))))
+
+(defun evil-repeat-force-abort-p (repeat-type)
+  "Returns non-nil iff the current command should abort the recording of repeat information."
+  (or (evil-repeat-different-buffer-p)           ; ... buffer changed
+      (eq repeat-type 'abort)                    ; ... explicitely forced
+      (eq evil-recording-repeat 'abort)          ; ... already aborted
+      (evil-emacs-state-p)                       ; ... in Emacs state
+      (and (evil-mouse-events-p (this-command-keys))  ; ... mouse events
+           (eq repeat-type nil))
+      (minibufferp)))                            ; ... minibuffer activated
+
+(defun evil-repeat-record (info)
+  "Add INFO to the end of `evil-repeat-info'."
+  (when (evil-repeat-recording-p)
+    (setq evil-repeat-info (nconc evil-repeat-info (list info)))))
+
+;; called from `evil-normal-state-exit-hook'
+(defun evil-repeat-start-hook ()
+  "Record a new repeat when exiting Normal state.
+Does not record in Emacs state or if the current command
+has :repeat nil."
+  (when (and (eq (evil-repeat-type this-command t) t)
+             (not (evil-emacs-state-p)))
+    (evil-repeat-start)))
+
+;; called from `pre-command-hook'
+(defun evil-repeat-pre-hook ()
+  "Prepare the current command for recording the repeation."
+  (when evil-local-mode
+    (let ((repeat-type (evil-repeat-type this-command t)))
+      (cond
+       ;; abort the repeat
+       ((evil-repeat-force-abort-p repeat-type)
+        ;; We mark the current record as being aborted, because there
+        ;; may be further pre-hooks following before the post-hook is
+        ;; called.
+        (evil-repeat-abort))
+       ;; ignore those commands completely
+       ((null repeat-type))
+       ;; record command
+       (t
+        ;; In normal-state or visual state, each command is a single
+        ;; repeation, therefore start a new repeation.
+        (when (or (evil-normal-state-p)
+                  (evil-visual-state-p))
+          (evil-repeat-start))
+        (setq evil-recording-current-command t)
+        (funcall repeat-type 'pre))))))
+(put 'evil-repeat-pre-hook 'permanent-local-hook t)
+
+;; called from `post-command-hook'
+(defun evil-repeat-post-hook ()
+  "Finish recording of repeat-information for the current-command."
+  (when (and evil-local-mode evil-recording-repeat)
+    (let ((repeat-type (evil-repeat-type this-command t)))
+      (cond
+       ;; abort the repeat
+       ((evil-repeat-force-abort-p repeat-type)
+        ;; The command has been aborted but is complete, so just reset
+        ;; the recording state.
+        (evil-repeat-reset nil))
+       ;; ignore if command should not be recorded or the current
+       ;; command is not being recorded
+       ((or (null repeat-type)
+            (not evil-recording-current-command)))
+       ;; record command
+       (t
+        (funcall repeat-type 'post)
+        ;; In normal state, the repeat sequence is complete, so record it.
+        (when (evil-normal-state-p)
+          (evil-repeat-stop)))))
+    ;; done with recording the current command
+    (setq evil-recording-current-command nil)))
+(put 'evil-repeat-post-hook 'permanent-local-hook t)
+
+(defun evil-clear-command-keys ()
+  "Clear `this-command-keys' and all information about the current command keys.
+Calling this function prevents further recording of the keys that
+invoked the current command"
+  (clear-this-command-keys t)
+  (setq evil-repeat-keys ""))
+
+(defun evil-this-command-keys (&optional post-cmd)
+  "Version of `this-command-keys' with finer control over prefix args."
+  (let ((arg (if post-cmd current-prefix-arg prefix-arg)))
+    (vconcat
+     (when (and (numberp arg)
+                ;; Only add prefix if no repeat info recorded yet
+                (null evil-repeat-info))
+       (string-to-vector (number-to-string arg)))
+     (this-single-command-keys))))
+
+(defun evil-repeat-keystrokes (flag)
+  "Repeation recording function for commands that are repeated by keystrokes."
+  (cond
+   ((eq flag 'pre)
+    (when evil-this-register
+      (evil-repeat-record
+       `(set evil-this-register ,evil-this-register)))
+    (setq evil-repeat-keys (evil-this-command-keys)))
+   ((eq flag 'post)
+    (evil-repeat-record (if (zerop (length (evil-this-command-keys t)))
+                            evil-repeat-keys
+                          (evil-this-command-keys t)))
+    ;; erase commands keys to prevent double recording
+    (evil-clear-command-keys))))
+
+(defun evil-repeat-motion (flag)
+  "Repeation for motions. Motions are recorded by keystroke but only in insert state."
+  (when (memq evil-state '(insert replace))
+    (evil-repeat-keystrokes flag)))
+
+(defun evil-repeat-changes (flag)
+  "Repeation recording function for commands that are repeated by buffer changes."
+  (cond
+   ((eq flag 'pre)
+    (add-hook 'after-change-functions #'evil-repeat-change-hook nil t)
+    (evil-repeat-start-record-changes))
+   ((eq flag 'post)
+    (remove-hook 'after-change-functions #'evil-repeat-change-hook t)
+    (evil-repeat-finish-record-changes))))
+
+;; called from the `after-change-functions' hook
+(defun evil-repeat-change-hook (beg end length)
+  "Record change information for current command."
+  (let ((repeat-type (evil-repeat-type this-command t)))
+    (when (and (evil-repeat-recording-p)
+               (eq repeat-type 'evil-repeat-changes)
+               (not (evil-emacs-state-p))
+               (not (evil-repeat-different-buffer-p t))
+               evil-state)
+      (unless (evil-repeat-recording-p)
+        (evil-repeat-start))
+      (evil-repeat-record-change (- beg evil-repeat-pos)
+                                 (buffer-substring beg end)
+                                 length))))
+(put 'evil-repeat-change-hook 'permanent-local-hook t)
+
+(defun evil-repeat-record-change (relpos ins ndel)
+  "Record the current buffer changes during a repeat.
+If CHANGE is specified, it is added to `evil-repeat-changes'."
+  (when (evil-repeat-recording-p)
+    (setq evil-repeat-changes
+          (nconc evil-repeat-changes (list (list relpos ins ndel))))))
+
+(defun evil-repeat-start-record-changes ()
+  "Starts the recording of a new set of buffer changes."
+  (setq evil-repeat-changes nil)
+  (evil-repeat-record-position))
+
+(defun evil-repeat-finish-record-changes ()
+  "Finishes the recording of buffer changes and records them as repeat."
+  (when (evil-repeat-recording-p)
+    (evil-repeat-record `(evil-execute-change
+                          ,evil-repeat-changes
+                          ,(- (point) evil-repeat-pos)))
+    (setq evil-repeat-changes nil)))
+
+(defun evil-repeat-insert-at-point (flag)
+  "Repeation recording function for commands that insert text in region.
+This records text insertion when a command inserts some text in a
+buffer between (point) and (mark)."
+  (cond
+   ((eq flag 'pre)
+    (add-hook 'after-change-functions #'evil-repeat-insert-at-point-hook nil t))
+   ((eq flag 'post)
+    (remove-hook 'after-change-functions #'evil-repeat-insert-at-point-hook t))))
+
+(defun evil-repeat-insert-at-point-hook (beg end length)
+  (let ((repeat-type (evil-repeat-type this-command t)))
+    (when (and (evil-repeat-recording-p)
+               (eq repeat-type 'evil-repeat-insert-at-point)
+               (not (evil-emacs-state-p))
+               (not (evil-repeat-different-buffer-p t))
+               evil-state)
+      (setq evil-repeat-pos beg)
+      (evil-repeat-record (list 'insert (buffer-substring beg end))))))
+(put 'evil-repeat-insert-at-point-hook 'permanent-local-hook t)
+
+(defun evil-normalize-repeat-info (repeat-info)
+  "Concatenate consecutive arrays in REPEAT-INFO.
+Returns a single array."
+  (let* ((result (cons nil nil))
+         (result-last result)
+         cur cur-last)
+    (dolist (rep repeat-info)
+      (cond
+       ((null rep))
+       ((arrayp rep)
+        (setq rep (listify-key-sequence rep))
+        (cond
+         (cur
+          (setcdr cur-last (cons rep nil))
+          (setq cur-last (cdr cur-last)))
+         (t
+          (setq cur (cons rep nil))
+          (setq cur-last cur))))
+       (t
+        (when cur
+          (setcdr result-last (cons (apply #'vconcat cur) nil))
+          (setq result-last (cdr result-last))
+          (setq cur nil))
+        (setcdr result-last (cons rep nil))
+        (setq result-last (cdr result-last)))))
+    (when cur
+      (setcdr result-last (cons (apply #'vconcat cur) nil)))
+    (cdr result)))
+
+(defun evil-repeat-visual-char (nfwdlines nfwdchars)
+  "Restores a character visual selection.
+If the selection is in a single line, the restored visual
+selection covers the same number of characters. If the selection
+covers several lines, the restored selection covers the same
+number of lines and the same number of characters in the last
+line as the original selection."
+  (evil-visual-char)
+  (when (> nfwdlines 0)
+    (forward-line nfwdlines))
+  (forward-char nfwdchars))
+
+(defun evil-repeat-visual-line (nfwdlines)
+  "Restores a character visual selection.
+If the selection is in a single line, the restored visual
+selection covers the same number of characters. If the selection
+covers several lines, the restored selection covers the same
+number of lines and the same number of characters in the last
+line as the original selection."
+  (evil-visual-line)
+  (forward-line nfwdlines))
+
+(defun evil-repeat-visual-block (nfwdlines nfwdchars)
+  "Restores a character visual selection.
+If the selection is in a single line, the restored visual
+selection covers the same number of characters. If the selection
+covers several lines, the restored selection covers the same
+number of lines and the same number of characters in the last
+line as the original selection."
+  (evil-visual-block)
+  (let ((col (current-column)))
+    (forward-line nfwdlines)
+    (move-to-column (+ col nfwdchars) t)))
+
+(defun evil-execute-change (changes rel-point)
+  "Executes as list of changes.
+
+CHANGES is a list of triples (REL-BEG INSERT-TEXT NDEL).
+REL-BEG is the relative position (to point) where the change
+takes place. INSERT-TEXT is the text to be inserted at that
+position and NDEL the number of characters to be deleted at that
+position before insertion.
+
+REL-POINT is the relative position to point before the changed
+where point should be placed after all changes."
+  (evil-save-repeat-info
+    (let ((point (point)))
+      (dolist (change changes)
+        (goto-char (+ point (nth 0 change)))
+        (delete-char (nth 2 change))
+        (insert (nth 1 change)))
+      (goto-char (+ point rel-point)))))
+
+(defun evil-execute-repeat-info (repeat-info)
+  "Executes a repeat-information REPEAT-INFO."
+  (evil-save-repeat-info
+    (dolist (rep repeat-info)
+      (cond
+       ((or (arrayp rep) (stringp rep))
+        (let ((input-method current-input-method)
+              (evil-input-method nil))
+          (deactivate-input-method)
+          (unwind-protect
+              (execute-kbd-macro rep)
+            (activate-input-method input-method))))
+       ((consp rep)
+        (when (and (= 3 (length rep))
+                   (eq (nth 0 rep) 'set)
+                   (eq (nth 1 rep) 'evil-this-register)
+                   (>= (nth 2 rep) ?0)
+                   (< (nth 2 rep) ?9))
+          (setcar (nthcdr 2 rep) (1+ (nth 2 rep))))
+        (apply (car rep) (cdr rep)))
+       (t
+        (error "Unexpected repeat-info: %S" rep))))))
+
+;; TODO: currently we prepend the replacing count before the
+;; key-sequence that calls the command. Can we use direct
+;; modification of prefix-arg instead? Does it work in
+;; conjunction with `execute-kbd-macro'?
+(defun evil-execute-repeat-info-with-count (count repeat-info)
+  "Repeat the repeat-information REPEAT-INFO with the count of
+the first command replaced by COUNT. The count is replaced if
+and only if COUNT is non-nil."
+  (evil-save-repeat-info
+    (cond
+     ;; do nothing (zero repeating)
+     ((and count (zerop count)))
+     ;; replace count
+     (count
+      (let ((evil-repeat-count count)
+            done)
+        (while (and repeat-info
+                    (arrayp (car repeat-info))
+                    (not done))
+          (let* ((count-and-cmd (evil-extract-count (pop repeat-info))))
+            (push (vconcat (number-to-string count)
+                           (nth 2 count-and-cmd)
+                           (nth 3 count-and-cmd))
+                  repeat-info)
+            (setq done t)))
+        (evil-execute-repeat-info repeat-info)))
+     ;; repeat with original count
+     (t
+      (evil-execute-repeat-info repeat-info)))))
+
+(evil-define-command evil-repeat (count &optional save-point)
+  "Repeat the last editing command with count replaced by COUNT.
+If SAVE-POINT is non-nil, do not move point."
+  :repeat ignore
+  :suppress-operator t
+  (interactive (list current-prefix-arg
+                     (not evil-repeat-move-cursor)))
+  (cond
+   ((null evil-repeat-ring)
+    (error "Already executing repeat"))
+   (save-point
+    (save-excursion
+      (evil-repeat count)))
+   (t
+    (unwind-protect
+        (let ((confirm-kill-emacs t)
+              (kill-buffer-hook
+               (cons #'(lambda ()
+                         (user-error "Cannot delete buffer in repeat command"))
+                     kill-buffer-hook))
+              (undo-pointer buffer-undo-list))
+          (evil-with-single-undo
+            (setq evil-last-repeat (list (point) count undo-pointer))
+            (evil-execute-repeat-info-with-count
+             count (ring-ref evil-repeat-ring 0))))
+      (evil-normal-state)))))
+
+;; TODO: the same issue concering disabled undos as for `evil-paste-pop'
+(evil-define-command evil-repeat-pop (count &optional save-point)
+  "Replace the just repeated command with a previously executed command.
+Only allowed after `evil-repeat', `evil-repeat-pop' or
+`evil-repeat-pop-next'. Uses the same repeat count that
+was used for the first repeat.
+
+The COUNT argument inserts the COUNT-th previous kill.
+If COUNT is negative, this is a more recent kill."
+  :repeat nil
+  :suppress-operator t
+  (interactive (list (prefix-numeric-value current-prefix-arg)
+                     (not evil-repeat-move-cursor)))
+  (cond
+   ((not (and (eq last-command #'evil-repeat)
+              evil-last-repeat))
+    (user-error "Previous command was not evil-repeat: %s" last-command))
+   (save-point
+    (save-excursion
+      (evil-repeat-pop count)))
+   (t
+    (unless (eq buffer-undo-list (nth 2 evil-last-repeat))
+      (evil-undo-pop))
+    (goto-char (car evil-last-repeat))
+    ;; rotate the repeat-ring
+    (while (> count 0)
+      (when evil-repeat-ring
+        (ring-insert-at-beginning evil-repeat-ring
+                                  (ring-remove evil-repeat-ring 0)))
+      (setq count (1- count)))
+    (while (< count 0)
+      (when evil-repeat-ring
+        (ring-insert evil-repeat-ring
+                     (ring-remove evil-repeat-ring)))
+      (setq count (1+ count)))
+    (setq this-command #'evil-repeat)
+    (evil-repeat (cadr evil-last-repeat)))))
+
+(evil-define-command evil-repeat-pop-next (count &optional save-point)
+  "Same as `evil-repeat-pop', but with negative COUNT."
+  :repeat nil
+  :suppress-operator t
+  (interactive (list (prefix-numeric-value current-prefix-arg)
+                     (not evil-repeat-move-cursor)))
+  (evil-repeat-pop (- count) save-point))
+
+(defadvice read-key-sequence (before evil activate)
+  "Record `this-command-keys' before it is reset."
+  (when (and (evil-repeat-recording-p)
+             evil-recording-current-command)
+    (let ((repeat-type (evil-repeat-type this-command t)))
+      (if (functionp repeat-type)
+          (funcall repeat-type 'post)))))
+
+(provide 'evil-repeat)
+
+;;; evil-repeat.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-repeat.elc b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-repeat.elc
new file mode 100644
index 0000000000..a23e41e372
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-repeat.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-search.el b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-search.el
new file mode 100644
index 0000000000..896b3b58b2
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-search.el
@@ -0,0 +1,1294 @@
+;;; evil-search.el --- Search and substitute
+
+;; Author: Vegard Øye <vegard_oye at hotmail.com>
+;; Maintainer: Vegard Øye <vegard_oye at hotmail.com>
+
+;; Version: 1.2.13
+
+;;
+;; This file is NOT part of GNU Emacs.
+
+;;; License:
+
+;; This file is part of Evil.
+;;
+;; Evil 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.
+;;
+;; Evil 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 Evil.  If not, see <http://www.gnu.org/licenses/>.
+
+(require 'evil-core)
+(require 'evil-common)
+(require 'evil-ex)
+
+;;; Code:
+
+(defun evil-select-search-module (option module)
+  "Change the search module according to MODULE.
+If MODULE is `isearch', then Emacs' isearch module is used.
+If MODULE is `evil-search', then Evil's own interactive
+search module is used."
+  (let ((search-functions
+         '(forward
+           backward
+           word-forward
+           word-backward
+           unbounded-word-forward
+           unbounded-word-backward
+           next
+           previous)))
+    (dolist (fun search-functions)
+      (let ((isearch (intern (format "evil-search-%s" fun)))
+            (evil-search (intern (format "evil-ex-search-%s" fun))))
+        (if (eq module 'isearch)
+            (substitute-key-definition
+             evil-search isearch evil-motion-state-map)
+          (substitute-key-definition
+           isearch evil-search evil-motion-state-map)))))
+  (set-default option module))
+
+;; this customization is here because it requires
+;; the knowledge of `evil-select-search-mode'
+(defcustom evil-search-module 'isearch
+  "The search module to be used."
+  :type '(radio (const :tag "Emacs built-in isearch." :value isearch)
+                (const :tag "Evil interactive search." :value evil-search))
+  :group 'evil
+  :set 'evil-select-search-module
+  :initialize 'evil-custom-initialize-pending-reset)
+
+(defun evil-push-search-history (string forward)
+  "Push STRING into the appropriate search history (determined by FORWARD)."
+  (let* ((history-var (if forward
+                          'evil-search-forward-history
+                        'evil-search-backward-history))
+         (history (symbol-value history-var)))
+    (unless (equal (car-safe history) string)
+      (set history-var (cons string history)))))
+
+(defun evil-search-incrementally (forward regexp-p)
+  "Search incrementally for user-entered text."
+  (let ((evil-search-prompt (evil-search-prompt forward))
+        (isearch-search-fun-function 'evil-isearch-function)
+        (point (point))
+        search-nonincremental-instead)
+    (setq isearch-forward forward)
+    (evil-save-echo-area
+      (evil-without-input-method-hooks
+       ;; set the input method locally rather than globally to ensure that
+       ;; isearch clears the input method when it's finished
+       (setq current-input-method evil-input-method)
+       (if forward
+           (isearch-forward regexp-p)
+         (isearch-backward regexp-p))
+       (evil-push-search-history isearch-string forward)
+       (setq current-input-method nil))
+      (when (/= (point) point)
+        ;; position the point at beginning of the match only if the call to
+        ;; `isearch' has really moved the point. `isearch' doesn't move the
+        ;; point only if "C-g" is hit twice to exit the search, in which case we
+        ;; shouldn't move the point either.
+        (when (and forward isearch-other-end)
+          (goto-char isearch-other-end))
+        (when (and (eq point (point))
+                   (not (string= isearch-string "")))
+          (if forward
+              (isearch-repeat-forward)
+            (isearch-repeat-backward))
+          (isearch-exit)
+          (when (and forward isearch-other-end)
+            (goto-char isearch-other-end)))
+        (evil-flash-search-pattern
+         (evil-search-message isearch-string forward))))))
+
+(defun evil-flash-search-pattern (string &optional all)
+  "Flash last search matches for duration of `evil-flash-delay'.
+If ALL is non-nil, flash all matches. STRING is a message
+to display in the echo area."
+  (let ((lazy-highlight-initial-delay 0)
+        (isearch-search-fun-function 'evil-isearch-function)
+        (isearch-case-fold-search case-fold-search)
+        (disable #'(lambda (&optional arg) (evil-flash-hook t))))
+    (when evil-flash-timer
+      (cancel-timer evil-flash-timer))
+    (unless (or (null string)
+                (string= string ""))
+      (evil-echo-area-save)
+      (evil-echo "%s" string)
+      (isearch-highlight (match-beginning 0) (match-end 0))
+      (when all
+        (setq isearch-lazy-highlight-wrapped nil
+              isearch-lazy-highlight-start (point)
+              isearch-lazy-highlight-end (point))
+        (isearch-lazy-highlight-new-loop)
+        (unless isearch-lazy-highlight-overlays
+          (isearch-lazy-highlight-update)))
+      (add-hook 'pre-command-hook #'evil-flash-hook nil t)
+      (add-hook 'evil-operator-state-exit-hook #'evil-flash-hook nil t)
+      (add-hook 'pre-command-hook #'evil-clean-isearch-overlays nil t)
+      (setq evil-flash-timer
+            (run-at-time evil-flash-delay nil disable)))))
+
+(defun evil-clean-isearch-overlays ()
+  "Clean isearch overlays unless `this-command' is search."
+  (remove-hook 'pre-command-hook #'evil-clean-isearch-overlays t)
+  (unless (memq this-command
+                '(evil-search-backward
+                  evil-search-forward
+                  evil-search-next
+                  evil-search-previous
+                  evil-search-word-backward
+                  evil-search-word-forward))
+    (isearch-clean-overlays)))
+(put 'evil-clean-isearch-overlays 'permanent-local-hook t)
+
+(defun evil-flash-hook (&optional force)
+  "Disable hightlighting if `this-command' is not search.
+Disable anyway if FORCE is t."
+  (when (or force
+            ;; to avoid flicker, don't disable highlighting
+            ;; if the next command is also a search command
+            (not (memq this-command
+                       '(evil-search-backward
+                         evil-search-forward
+                         evil-search-next
+                         evil-search-previous
+                         evil-search-word-backward
+                         evil-search-word-forward))))
+    (evil-echo-area-restore)
+    (isearch-dehighlight)
+    (setq isearch-lazy-highlight-last-string nil)
+    (lazy-highlight-cleanup t)
+    (when evil-flash-timer
+      (cancel-timer evil-flash-timer)))
+  (remove-hook 'pre-command-hook #'evil-flash-hook t)
+  (remove-hook 'evil-operator-state-exit-hook #'evil-flash-hook t))
+(put 'evil-flash-hook 'permanent-local-hook t)
+
+(defun evil-search-function (&optional forward regexp-p wrap)
+  "Return a search function.
+If FORWARD is nil, search backward, otherwise forward.
+If REGEXP-P is non-nil, the input is a regular expression.
+If WRAP is non-nil, the search wraps around the top or bottom
+of the buffer."
+  `(lambda (string &optional bound noerror count)
+     (let ((start (point))
+           (search-fun ',(if regexp-p
+                             (if forward
+                                 're-search-forward
+                               're-search-backward)
+                           (if forward
+                               'search-forward
+                             'search-backward)))
+           result)
+       (setq result (funcall search-fun string bound
+                             ,(if wrap t 'noerror) count))
+       (when (and ,wrap (null result))
+         (goto-char ,(if forward '(point-min) '(point-max)))
+         (unwind-protect
+             (setq result (funcall search-fun string bound noerror count))
+           (unless result
+             (goto-char start))))
+       result)))
+
+(defun evil-isearch-function ()
+  "Return a search function for use with isearch.
+Based on `isearch-regexp' and `isearch-forward'."
+  (evil-search-function isearch-forward evil-regexp-search evil-search-wrap))
+
+(defun evil-search (string forward &optional regexp-p start)
+  "Search for STRING and highlight matches.
+If FORWARD is nil, search backward, otherwise forward.
+If REGEXP-P is non-nil, STRING is taken to be a regular expression.
+START is the position to search from; if unspecified, it is
+one more than the current position."
+  (when (and (stringp string)
+             (not (string= string "")))
+    (let* ((orig (point))
+           (start (or start
+                      (if forward
+                          (min (point-max) (1+ orig))
+                        orig)))
+           (isearch-regexp regexp-p)
+           (isearch-forward forward)
+           (case-fold-search
+            (unless (and search-upper-case
+                         (not (isearch-no-upper-case-p string nil)))
+              case-fold-search))
+           (search-func (evil-search-function
+                         forward regexp-p evil-search-wrap)))
+      ;; no text properties, thank you very much
+      (set-text-properties 0 (length string) nil string)
+      ;; position to search from
+      (goto-char start)
+      (setq isearch-string string)
+      (isearch-update-ring string regexp-p)
+      (condition-case nil
+          (funcall search-func string)
+        (search-failed
+         (goto-char orig)
+         (user-error "\"%s\": %s not found"
+                     string (if regexp-p "pattern" "string"))))
+      ;; handle opening and closing of invisible area
+      (cond
+       ((boundp 'isearch-filter-predicates)
+        (dolist (pred isearch-filter-predicates)
+          (funcall pred (match-beginning 0) (match-end 0))))
+       ((boundp 'isearch-filter-predicate)
+        (funcall isearch-filter-predicate (match-beginning 0) (match-end 0))))
+      ;; always position point at the beginning of the match
+      (goto-char (match-beginning 0))
+      ;; determine message for echo area
+      (cond
+       ((and forward (< (point) start))
+        (setq string "Search wrapped around BOTTOM of buffer"))
+       ((and (not forward) (> (point) start))
+        (setq string "Search wrapped around TOP of buffer"))
+       (t
+        (setq string (evil-search-message string forward))))
+      (evil-flash-search-pattern string t))))
+
+(defun evil-search-word (forward unbounded symbol)
+  "Search for word near point.
+If FORWARD is nil, search backward, otherwise forward. If SYMBOL
+is non-nil then the functions searches for the symbol at point,
+otherwise for the word at point."
+  (let ((string (car-safe regexp-search-ring))
+        (move (if forward #'forward-char #'backward-char))
+        (end (if forward #'eobp #'bobp)))
+    (setq isearch-forward forward)
+    (cond
+     ((and (memq last-command
+                 '(evil-search-word-forward
+                   evil-search-word-backward))
+           (stringp string)
+           (not (string= string "")))
+      (evil-search string forward t))
+     (t
+      (setq string (evil-find-thing forward (if symbol 'symbol 'evil-word)))
+      (cond
+       ((null string)
+        (user-error "No word under point"))
+       (unbounded
+        (setq string (regexp-quote string)))
+       (t
+        (setq string
+              (format (if symbol "\\_<%s\\_>" "\\<%s\\>")
+                      (regexp-quote string)))))
+      (evil-push-search-history string forward)
+      (evil-search string forward t)))))
+
+(defun evil-find-thing (forward thing)
+  "Return THING near point as a string.
+THING should be a symbol understood by `thing-at-point',
+e.g. 'symbol or 'word.  If FORWARD is nil, search backward,
+otherwise forward.  Returns nil if nothing is found."
+  (let ((move (if forward #'forward-char #'backward-char))
+        (end (if forward #'eobp #'bobp))
+        string)
+    (save-excursion
+      (setq string (thing-at-point thing))
+      ;; if there's nothing under point, go forwards
+      ;; (or backwards) to find it
+      (while (and (null string) (not (funcall end)))
+        (funcall move)
+        (setq string (thing-at-point thing)))
+      (when (stringp string)
+        (set-text-properties 0 (length string) nil string))
+      (when (> (length string) 0)
+        string))))
+
+(defun evil-find-word (forward)
+  "Return word near point as a string.
+If FORWARD is nil, search backward, otherwise forward.  Returns
+nil if nothing is found."
+  (evil-find-thing forward 'word))
+
+(defun evil-find-symbol (forward)
+  "Return word near point as a string.
+If FORWARD is nil, search backward, otherwise forward.  Returns
+nil if nothing is found."
+  (evil-find-thing forward 'symbol))
+
+(defun evil-search-prompt (forward)
+  "Return the search prompt for the given direction."
+  (if forward "/" "?"))
+
+(defun evil-search-message (string forward)
+  "Prefix STRING with the search prompt."
+  (format "%s%s" (evil-search-prompt forward) string))
+
+(defadvice isearch-message-prefix (around evil activate)
+  "Use `evil-search-prompt'."
+  (if evil-search-prompt
+      (setq ad-return-value evil-search-prompt)
+    ad-do-it))
+
+(defadvice isearch-delete-char (around evil activate)
+  "Exit search if no search string."
+  (cond
+   ((and evil-search-prompt (string= isearch-string ""))
+    (let (search-nonincremental-instead)
+      (setq isearch-success nil)
+      (isearch-exit)))
+   (t
+    ad-do-it)))
+
+(defadvice isearch-lazy-highlight-search (around evil activate)
+  "Never wrap the search in this context."
+  (let (evil-search-wrap)
+    ad-do-it))
+
+;;; Ex search
+
+(defun evil-ex-regex-without-case (re)
+  "Return the regular expression without all occurrences of \\c and \\C."
+  (evil-transform-regexp re '((?c . "") (?C . ""))))
+
+(defun evil-ex-regex-case (re default-case)
+  "Return the case as implied by \\c or \\C in regular expression RE.
+If \\c appears anywhere in the pattern, the pattern is case
+insensitive. If \\C appears, the pattern is case sensitive.
+Only the first occurrence of \\c or \\C is used, all others are
+ignored. If neither \\c nor \\C appears in the pattern, the case
+specified by DEFAULT-CASE is used. DEFAULT-CASE should be either
+`sensitive', `insensitive' or `smart'. In the latter case, the pattern
+will be case-sensitive if and only if it contains an upper-case
+letter, otherwise it will be case-insensitive."
+  (cond
+   ((string-match "\\(?:^\\|[^\\\\]\\)\\(?:\\\\\\\\\\)*\\\\\\([cC]\\)" re)
+    (if (eq (aref (match-string 1 re) 0) ?c) 'insensitive 'sensitive))
+   ((eq default-case 'smart)
+    (if (isearch-no-upper-case-p re t)
+        'insensitive
+      'sensitive))
+   (t default-case)))
+
+;; a pattern
+(defun evil-ex-make-substitute-pattern (regexp flags)
+  "Creates a PATTERN for substitution with FLAGS.
+This function respects the values of `evil-ex-substitute-case'
+and `evil-ex-substitute-global'."
+  (evil-ex-make-pattern regexp
+                        (cond
+                         ((memq ?i flags) 'insensitive)
+                         ((memq ?I flags) 'sensitive)
+                         ((not evil-ex-substitute-case)
+                          evil-ex-search-case)
+                         (t evil-ex-substitute-case))
+                        (or (and evil-ex-substitute-global
+                                 (not (memq ?g flags)))
+                            (and (not evil-ex-substitute-global)
+                                 (memq ?g flags)))))
+
+(defun evil-ex-make-search-pattern (regexp)
+  "Creates a PATTERN for search.
+This function respects the values of `evil-ex-search-case'."
+  (evil-ex-make-pattern regexp evil-ex-search-case t))
+
+(defun evil-ex-make-pattern (regexp case whole-line)
+  "Create a new search pattern.
+REGEXP is the regular expression to be searched for. CASE should
+be either 'sensitive, 'insensitive for case-sensitive and
+case-insensitive search, respectively, or anything else.  In the
+latter case the pattern is smart-case, i.e. it is automatically
+sensitive of the pattern contains one upper case letter,
+otherwise it is insensitive.  The input REGEXP is considered a
+Vim-style regular expression if `evil-ex-search-vim-style-regexp'
+is non-nil, in which case it is transformed to an Emacs style
+regular expression (i.e. certain backslash-codes are
+transformed. Otherwise REGEXP must be an Emacs style regular
+expression and is not transformed."
+  (let ((re (evil-ex-regex-without-case regexp))
+        (ignore-case (eq (evil-ex-regex-case regexp case) 'insensitive)))
+    ;; possibly transform regular expression from vim-style to
+    ;; Emacs-style.
+    (if evil-ex-search-vim-style-regexp
+        (setq re (evil-transform-vim-style-regexp re))
+      ;; Even for Emacs regular expressions we translate certain
+      ;; whitespace sequences
+      (setq re (evil-transform-regexp re
+                                      '((?t . "\t")
+                                        (?n . "\n")
+                                        (?r . "\r")))))
+    (list re ignore-case whole-line)))
+
+(defun evil-ex-pattern-regex (pattern)
+  "Return the regular expression of a search PATTERN."
+  (nth 0 pattern))
+
+(defun evil-ex-pattern-ignore-case (pattern)
+  "Return t if and only if PATTERN should ignore case."
+  (nth 1 pattern))
+
+(defun evil-ex-pattern-whole-line (pattern)
+  "Return t if and only if PATTERN should match all occurences of a line.
+Otherwise PATTERN matches only the first occurence."
+  (nth 2 pattern))
+
+;; Highlight
+(defun evil-ex-make-hl (name &rest args)
+  "Create a new highlight object with name NAME and properties ARGS.
+The following properties are supported:
+:face The face to be used for the highlighting overlays.
+:win The window in which the highlighting should be shown.
+     Note that the highlight will be visible in all windows showing
+     the corresponding buffer, but only the matches visible in the
+     specified window will actually be highlighted. If :win is nil,
+     the matches in all windows will be highlighted.
+:min The minimal buffer position for highlighted matches.
+:max The maximal buffer position for highlighted matches.
+:match-hook A hook to be called once for each highlight.
+            The hook must take two arguments, the highlight and
+            the overlay for that highlight.
+:update-hook A hook called once after updating the highlighting
+             with two arguments, the highlight and a message string
+             describing the current match status."
+  (unless (symbolp name)
+    (user-error "Expected symbol as name of highlight"))
+  (let ((face 'evil-ex-lazy-highlight)
+        (win (selected-window))
+        min max match-hook update-hook)
+    (while args
+      (let ((key (pop args))
+            (val (pop args)))
+        (cond
+         ((eq key :face) (setq face val))
+         ((eq key :win)  (setq win val))
+         ((eq key :min)  (setq min val))
+         ((eq key :max)  (setq max val))
+         ((eq key :match-hook) (setq match-hook val))
+         ((eq key :update-hook) (setq update-hook val))
+         (t (user-error "Unexpected keyword: %s" key)))))
+    (when (assoc name evil-ex-active-highlights-alist)
+      (evil-ex-delete-hl name))
+    (when (null evil-ex-active-highlights-alist)
+      (add-hook 'window-scroll-functions
+                #'evil-ex-hl-update-highlights-scroll nil t)
+      (add-hook 'window-size-change-functions
+                #'evil-ex-hl-update-highlights-resize nil))
+    (push (cons name (vector name
+                             nil
+                             face
+                             win
+                             min
+                             max
+                             match-hook
+                             update-hook
+                             nil))
+          evil-ex-active-highlights-alist)))
+
+(defun evil-ex-hl-name (hl)
+  "Return the name of the highlight HL."
+  (aref hl 0))
+
+(defun evil-ex-hl-pattern (hl)
+  "Return the pattern of the highlight HL."
+  (aref hl 1))
+
+(defun evil-ex-hl-set-pattern (hl pattern)
+  "Set the pattern of the highlight HL to PATTERN."
+  (aset hl 1 pattern))
+
+(defun evil-ex-hl-face (hl)
+  "Return the face of the highlight HL."
+  (aref hl 2))
+
+(defun evil-ex-hl-window (hl)
+  "Return the window of the highlight HL."
+  (aref hl 3))
+
+(defun evil-ex-hl-min (hl)
+  "Return the minimal buffer position of the highlight HL."
+  (aref hl 4))
+
+(defun evil-ex-hl-set-min (hl min)
+  "Set the minimal buffer position of the highlight HL to MIN."
+  (aset hl 4 min))
+
+(defun evil-ex-hl-max (hl)
+  "Return the maximal buffer position of the highlight HL."
+  (aref hl 5))
+
+(defun evil-ex-hl-set-max (hl max)
+  "Set the minimal buffer position of the highlight HL to MAX."
+  (aset hl 5 max))
+
+(defun evil-ex-hl-match-hook (hl)
+  "Return the match-hook of the highlight HL."
+  (aref hl 6))
+
+(defun evil-ex-hl-update-hook (hl)
+  "Return the update-hook of the highlight HL."
+  (aref hl 7))
+
+(defun evil-ex-hl-overlays (hl)
+  "Return the list of active overlays of the highlight HL."
+  (aref hl 8))
+
+(defun evil-ex-hl-set-overlays (hl overlays)
+  "Set the list of active overlays of the highlight HL to OVERLAYS."
+  (aset hl 8 overlays))
+
+(defun evil-ex-delete-hl (name)
+  "Remove the highlighting object with a certain NAME."
+  (let ((hl (cdr-safe (assoc name evil-ex-active-highlights-alist))))
+    (when hl
+      (mapc #'delete-overlay (evil-ex-hl-overlays hl))
+      (setq evil-ex-active-highlights-alist
+            (assq-delete-all name evil-ex-active-highlights-alist))
+      (evil-ex-hl-update-highlights))
+    (when (null evil-ex-active-highlights-alist)
+      (remove-hook 'window-scroll-functions
+                   #'evil-ex-hl-update-highlights-scroll t)
+      (remove-hook 'window-size-change-functions
+                   #'evil-ex-hl-update-highlights-resize))))
+
+(defun evil-ex-hl-active-p (name)
+  "Whether the highlight with a certain NAME is active."
+  (and (assoc name evil-ex-active-highlights-alist) t))
+
+(defun evil-ex-hl-change (name pattern)
+  "Set the regular expression of highlight NAME to PATTERN."
+  (let ((hl (cdr-safe (assoc name evil-ex-active-highlights-alist))))
+    (when hl
+      (evil-ex-hl-set-pattern hl
+                              (if (zerop (length pattern))
+                                  nil
+                                pattern))
+      (evil-ex-hl-idle-update))))
+
+(defun evil-ex-hl-set-region (name beg end &optional type)
+  "Set minimal and maximal position of highlight NAME to BEG and END."
+  (let ((hl (cdr-safe (assoc name evil-ex-active-highlights-alist))))
+    (when hl
+      (evil-ex-hl-set-min hl beg)
+      (evil-ex-hl-set-max hl end)
+      (evil-ex-hl-idle-update))))
+
+(defun evil-ex-hl-get-max (name)
+  "Return the maximal position of the highlight with name NAME."
+  (let ((hl (cdr-safe (assoc name evil-ex-active-highlights-alist))))
+    (and hl (evil-ex-hl-max hl))))
+
+(defun evil-ex-hl-update-highlights ()
+  "Update the overlays of all active highlights."
+  (dolist (hl (mapcar #'cdr evil-ex-active-highlights-alist))
+    (let* ((old-ovs (evil-ex-hl-overlays hl))
+           new-ovs
+           (pattern (evil-ex-hl-pattern hl))
+           (case-fold-search (evil-ex-pattern-ignore-case pattern))
+           (case-replace case-fold-search)
+           (face (evil-ex-hl-face hl))
+           (match-hook (evil-ex-hl-match-hook hl))
+           result)
+      (if pattern
+          ;; collect all visible ranges
+          (let (ranges sranges)
+            (dolist (win (if (eq evil-ex-interactive-search-highlight
+                                 'all-windows)
+                             (get-buffer-window-list (current-buffer) nil t)
+                           (list (evil-ex-hl-window hl))))
+              (let ((beg (max (window-start win)
+                              (or (evil-ex-hl-min hl) (point-min))))
+                    (end (min (window-end win)
+                              (or (evil-ex-hl-max hl) (point-max)))))
+                (when (< beg end)
+                  (push (cons beg end) ranges))))
+            (setq ranges
+                  (sort ranges #'(lambda (r1 r2) (< (car r1) (car r2)))))
+            (while ranges
+              (let ((r1 (pop ranges))
+                    (r2 (pop ranges)))
+                (cond
+                 ;; last range
+                 ((null r2)
+                  (push r1 sranges))
+                 ;; ranges overlap, union
+                 ((>= (cdr r1) (car r2))
+                  (push (cons (car r1)
+                              (max (cdr r1) (cdr r2)))
+                        ranges))
+                 ;; ranges distinct
+                 (t
+                  (push r1 sranges)
+                  (push r2 ranges)))))
+
+            ;; run through all ranges
+            (condition-case lossage
+                (save-match-data
+                  (dolist (r sranges)
+                    (let ((beg (car r))
+                          (end (cdr r)))
+                      (save-excursion
+                        (goto-char beg)
+                        ;; set the overlays for the current highlight,
+                        ;; reusing old overlays (if possible)
+                        (while (and (not (eobp))
+                                    (evil-ex-search-find-next-pattern pattern)
+                                    (<= (match-end 0) end)
+                                    (not (and (= (match-end 0) end)
+                                              (string= (evil-ex-pattern-regex pattern)
+                                                       "^"))))
+                          (let ((ov (or (pop old-ovs) (make-overlay 0 0))))
+                            (move-overlay ov (match-beginning 0) (match-end 0))
+                            (overlay-put ov 'face face)
+                            (overlay-put ov 'evil-ex-hl (evil-ex-hl-name hl))
+                            (overlay-put ov 'priority 1000)
+                            (push ov new-ovs)
+                            (when match-hook (funcall match-hook hl ov)))
+                          (cond
+                           ((and (not (evil-ex-pattern-whole-line pattern))
+                                 (not (string-match-p "\n" (buffer-substring-no-properties
+                                                            (match-beginning 0)
+                                                            (match-end 0)))))
+                            (forward-line))
+                           ((= (match-beginning 0) (match-end 0))
+                            (forward-char))
+                           (t (goto-char (match-end 0))))))))
+                  (mapc #'delete-overlay old-ovs)
+                  (evil-ex-hl-set-overlays hl new-ovs)
+                  (if (or (null pattern) new-ovs)
+                      (setq result t)
+                    ;; Maybe the match could just not be found somewhere else?
+                    (save-excursion
+                      (goto-char (or (evil-ex-hl-min hl) (point-min)))
+                      (if (and (evil-ex-search-find-next-pattern pattern)
+                               (< (match-end 0) (or (evil-ex-hl-max hl)
+                                                    (point-max))))
+                          (setq result (format "Match in line %d"
+                                               (line-number-at-pos
+                                                (match-beginning 0))))
+                        (setq result "No match")))))
+
+              (invalid-regexp
+               (setq result (cadr lossage)))
+
+              (search-failed
+               (setq result (nth 2 lossage)))
+
+              (error
+               (setq result (format "%s" (cadr lossage))))
+
+              (user-error
+               (setq result (format "%s" (cadr lossage))))))
+        ;; no pattern, remove all highlights
+        (mapc #'delete-overlay old-ovs)
+        (evil-ex-hl-set-overlays hl new-ovs))
+      (when (evil-ex-hl-update-hook hl)
+        (funcall (evil-ex-hl-update-hook hl) hl result)))))
+
+(defun evil-ex-search-find-next-pattern (pattern &optional direction)
+  "Look for the next occurrence of PATTERN in a certain DIRECTION.
+Note that this function ignores the whole-line property of PATTERN."
+  (setq direction (or direction 'forward))
+  (let ((case-fold-search (evil-ex-pattern-ignore-case pattern)))
+    (cond
+     ((eq direction 'forward)
+      (re-search-forward (evil-ex-pattern-regex pattern) nil t))
+     ((eq direction 'backward)
+      (let* ((pnt (point))
+             (ret (re-search-backward (evil-ex-pattern-regex pattern) nil t))
+             (m (and ret (match-data))))
+        (if ret
+            (forward-char)
+          (goto-char (point-min)))
+        (let ((fwdret
+               (re-search-forward (evil-ex-pattern-regex pattern) nil t)))
+          (cond
+           ((and fwdret (< (match-beginning 0) pnt))
+            (setq ret fwdret)
+            (goto-char (match-beginning 0)))
+           (ret
+            (set-match-data m)
+            (goto-char (match-beginning 0)))
+           (t
+            (goto-char pnt)
+            ret)))))
+     (t
+      (user-error "Unknown search direction: %s" direction)))))
+
+(defun evil-ex-hl-idle-update ()
+  "Triggers the timer to update the highlights in the current buffer."
+  (when (and evil-ex-interactive-search-highlight
+             evil-ex-active-highlights-alist)
+    (when evil-ex-hl-update-timer
+      (cancel-timer evil-ex-hl-update-timer))
+    (setq evil-ex-hl-update-timer
+          (run-at-time evil-ex-hl-update-delay nil
+                       #'evil-ex-hl-do-update-highlight
+                       (current-buffer)))))
+
+(defun evil-ex-hl-do-update-highlight (&optional buffer)
+  "Timer function for updating the highlights."
+  (when (buffer-live-p buffer)
+    (with-current-buffer buffer
+      (evil-ex-hl-update-highlights)))
+  (setq evil-ex-hl-update-timer nil))
+
+(defun evil-ex-hl-update-highlights-scroll (win beg)
+  "Update highlights after scrolling in some window."
+  (with-current-buffer (window-buffer win)
+    (evil-ex-hl-idle-update)))
+(put 'evil-ex-hl-update-highlights-scroll 'permanent-local-hook t)
+
+(defun evil-ex-hl-update-highlights-resize (frame)
+  "Update highlights after resizing a window."
+  (let ((buffers (delete-dups (mapcar #'window-buffer (window-list frame)))))
+    (dolist (buf buffers)
+      (with-current-buffer buf
+        (evil-ex-hl-idle-update)))))
+(put 'evil-ex-hl-update-highlights-resize 'permanent-local-hook t)
+
+;; interactive search
+(defun evil-ex-search-activate-highlight (pattern)
+  "Activate highlighting of the search pattern set to PATTERN.
+This function does nothing if `evil-ex-search-interactive' or
+`evil-ex-search-highlight-all' is nil. "
+  (when (and evil-ex-search-interactive evil-ex-search-highlight-all)
+    (with-current-buffer (or evil-ex-current-buffer (current-buffer))
+      (unless (evil-ex-hl-active-p 'evil-ex-search)
+        (evil-ex-make-hl 'evil-ex-search
+                         :win (minibuffer-selected-window)))
+      (if pattern
+          (evil-ex-hl-change 'evil-ex-search pattern)))))
+
+(defun evil-ex-search (&optional count)
+  "Search forward or backward COUNT times for the current ex search pattern.
+The search pattern is determined by `evil-ex-search-pattern' and
+the direcion is determined by `evil-ex-search-direction'."
+  (setq evil-ex-search-start-point (point)
+        evil-ex-last-was-search t
+        count (or count 1))
+  (let ((orig (point))
+        wrapped)
+    (dotimes (i (or count 1))
+      (when (eq evil-ex-search-direction 'forward)
+        (unless (eobp) (forward-char))
+        ;; maybe skip end-of-line
+        (when (and evil-move-cursor-back (eolp) (not (eobp)))
+          (forward-char)))
+      (let ((res (evil-ex-find-next nil nil (not evil-search-wrap))))
+        (cond
+         ((not res)
+          (goto-char orig)
+          (signal 'search-failed
+                  (list (evil-ex-pattern-regex evil-ex-search-pattern))))
+         ((eq res 'wrapped) (setq wrapped t)))))
+    (if wrapped
+        (let (message-log-max)
+          (message "Search wrapped")))
+    (goto-char (match-beginning 0))
+    (setq evil-ex-search-match-beg (match-beginning 0)
+          evil-ex-search-match-end (match-end 0))
+    (evil-ex-search-goto-offset evil-ex-search-offset)
+    (evil-ex-search-activate-highlight evil-ex-search-pattern)))
+
+(defun evil-ex-find-next (&optional pattern direction nowrap)
+  "Search for the next occurrence of the PATTERN in DIRECTION.
+PATTERN must be created using `evil-ex-make-pattern', DIRECTION
+is either 'forward or 'backward. If NOWRAP is non nil, the search
+does not wrap at buffer boundaries. Furthermore this function
+only searches invisible text if `search-invisible' is t. If
+PATTERN is not specified the current global pattern
+`evil-ex-search-pattern' and if DIRECTION is not specified the
+current global direction `evil-ex-search-direction' is used.
+This function returns t if the search was successful, nil if it
+was unsuccessful and 'wrapped if the search was successful but
+has been wrapped at the buffer boundaries."
+  (setq pattern (or pattern evil-ex-search-pattern)
+        direction (or direction evil-ex-search-direction))
+  (unless (and pattern (evil-ex-pattern-regex pattern))
+    (signal 'search-failed (list "No search pattern")))
+  (catch 'done
+    (let (wrapped)
+      (while t
+        (let ((search-result (evil-ex-search-find-next-pattern pattern
+                                                               direction)))
+          (cond
+           ((and search-result
+                 (or (eq search-invisible t)
+                     (not (isearch-range-invisible
+                           (match-beginning 0) (match-end 0)))))
+            ;; successful search and not invisible
+            (throw 'done (if wrapped 'wrapped t)))
+           ((not search-result)
+            ;; unsuccessful search
+            (if nowrap
+                (throw 'done nil)
+              (setq nowrap t
+                    wrapped t)
+              (goto-char (if (eq direction 'forward)
+                             (point-min)
+                           (point-max)))))))))))
+
+(defun evil-ex-search-update (pattern offset beg end message)
+  "Update the highlighting and info-message for the search pattern.
+PATTERN is the search pattern and OFFSET the associated offset.
+BEG and END specifiy the current match, MESSAGE is the info
+message to be shown. This function does nothing if
+`evil-ex-search-interactive' is nil."
+  (when evil-ex-search-interactive
+    (cond
+     ((and beg end)
+      ;; update overlay
+      (if evil-ex-search-overlay
+          (move-overlay evil-ex-search-overlay beg end)
+        (setq evil-ex-search-overlay
+              (make-overlay beg end))
+        (overlay-put evil-ex-search-overlay 'priority 1001)
+        (overlay-put evil-ex-search-overlay 'face 'evil-ex-search))
+      ;; move point
+      (goto-char beg)
+      (evil-ex-search-goto-offset offset)
+      ;; update highlights
+      (when evil-ex-search-highlight-all
+        (evil-ex-hl-change 'evil-ex-search pattern)))
+     (t
+      ;; no match
+      (when evil-ex-search-overlay
+        ;; remove overlay
+        (delete-overlay evil-ex-search-overlay)
+        (setq evil-ex-search-overlay nil))
+      ;; no highlights
+      (when evil-ex-search-highlight-all
+        (evil-ex-hl-change 'evil-ex-search nil))
+      ;; and go to initial position
+      (goto-char evil-ex-search-start-point)))
+    (when (stringp message)
+      (evil-ex-echo "%s" message))))
+
+(defun evil-ex-search-start-session ()
+  "Initialize Ex for interactive search."
+  (remove-hook 'minibuffer-setup-hook #'evil-ex-search-start-session)
+  (add-hook 'after-change-functions #'evil-ex-search-update-pattern nil t)
+  (add-hook 'minibuffer-exit-hook #'evil-ex-search-stop-session)
+  (evil-ex-search-activate-highlight nil))
+(put 'evil-ex-search-start-session 'permanent-local-hook t)
+
+(defun evil-ex-search-stop-session ()
+  "Stop interactive search."
+  (with-current-buffer evil-ex-current-buffer
+    ;; TODO: This is a bad fix to remove duplicates. The duplicates
+    ;;       exist because `isearch-range-invisible' may add a single
+    ;;       overlay multiple times if we are in an unlucky situation
+    ;;       of overlapping overlays. This happens in our case because
+    ;;       of the overlays that are used for (lazy) highlighting.
+    ;;       Perhaps it would be better to disable those overlays
+    ;;       temporarily before calling `isearch-range-invisible'.
+    (setq isearch-opened-overlays (delete-dups isearch-opened-overlays))
+    (isearch-clean-overlays))
+  (remove-hook 'minibuffer-exit-hook #'evil-ex-search-stop-session)
+  (remove-hook 'after-change-functions #'evil-ex-search-update-pattern t)
+  (when evil-ex-search-overlay
+    (delete-overlay evil-ex-search-overlay)
+    (setq evil-ex-search-overlay nil)))
+(put 'evil-ex-search-stop-session 'permanent-local-hook t)
+
+(defun evil-ex-split-search-pattern (pattern direction)
+  "Split PATTERN in regexp, offset and next-pattern parts.
+Returns a triple (regexp  offset next-search)."
+  (save-match-data
+    (if (or (and (eq direction 'forward)
+                 (string-match "\\(?:^\\|[^\\\\]\\)\\(?:\\\\\\\\\\)*\\(/\\([^;]*\\)\\(?:;\\([/?].*\\)?\\)?\\)?$"
+                               pattern))
+            (and (eq direction 'backward)
+                 (string-match "\\(?:^\\|[^\\\\]\\)\\(?:\\\\\\\\\\)*\\(\\?\\([^;]*\\)\\(?:;\\([/?].*\\)?\\)?\\)?$"
+                               pattern)))
+        (list (substring pattern 0 (match-beginning 1))
+              (match-string 2 pattern)
+              (match-string 3 pattern))
+      (list pattern nil nil))))
+
+(defun evil-ex-search-full-pattern (pattern-string count direction)
+  "Search for a full search pattern PATTERN-STRING in DIRECTION.
+This function split PATTERN-STRING in
+pattern/offset/;next-pattern parts and performs the search in
+DIRECTION which must be either 'forward or 'backward. The first
+search is repeated COUNT times. If the pattern part of
+PATTERN-STRING is empty, the last global pattern stored in
+`evil-ex-search-pattern' is used instead if in addition the
+offset part is nil (i.e. no pattern/offset separator), the last
+global offset stored in `evil-ex-search-offset' is used as
+offset. The current match data will correspond to the last
+successful match.  This function returns a triple (RESULT PATTERN
+OFFSET) where RESULT is
+
+  t              the search has been successful without wrap
+  'wrap          the search has been successful with wrap
+  'empty-pattern the last pattern has been empty
+  nil            the search has not been successful
+
+and PATTERN and OFFSET are the last pattern and offset this
+function searched for. Note that this function does not handle
+any error conditions."
+  (setq count (or count 1))
+  (catch 'done
+    (while t
+      (let* ((res (evil-ex-split-search-pattern pattern-string direction))
+             (pat (pop res))
+             (offset (pop res))
+             (next-pat (pop res)))
+        ;; use last pattern of no new pattern has been specified
+        (if (not (zerop (length pat)))
+            (setq pat (evil-ex-make-search-pattern pat))
+          (setq pat evil-ex-search-pattern
+                offset (or offset evil-ex-search-offset)))
+        (when (zerop (length pat))
+          (throw 'done (list 'empty-pattern pat offset)))
+        (let (search-result)
+          (while (> count 0)
+            (let ((result (evil-ex-find-next pat direction
+                                             (not evil-search-wrap))))
+              (if (not result) (setq search-result nil count 0)
+                (setq search-result
+                      (if (or (eq result 'wrap)
+                              (eq search-result 'wrap))
+                          'wrap t)
+                      count (1- count)))))
+          (cond
+           ;; search failed
+           ((not search-result) (throw 'done (list nil pat offset)))
+           ;; no next pattern, search complete
+           ((zerop (length next-pat))
+            (evil-ex-search-goto-offset offset)
+            (throw 'done (list search-result pat offset)))
+           ;; next pattern but empty
+           ((= 1 (length next-pat))
+            (evil-ex-search-goto-offset offset)
+            (throw 'done (list 'empty-pattern pat offset)))
+           ;; next non-empty pattern, next search iteration
+           (t
+            (evil-ex-search-goto-offset offset)
+            (setq count 1
+                  pattern-string (substring next-pat 1)
+                  direction (if (= (aref next-pat 0) ?/)
+                                'forward
+                              'backward)))))))))
+
+(defun evil-ex-search-update-pattern (beg end range)
+  "Update the current search pattern."
+  (save-match-data
+    (let ((pattern-string (minibuffer-contents)))
+      (with-current-buffer evil-ex-current-buffer
+        (with-selected-window (minibuffer-selected-window)
+          (goto-char (1+ evil-ex-search-start-point))
+          (condition-case err
+              (let* ((result (evil-ex-search-full-pattern pattern-string
+                                                          (or evil-ex-search-count 1)
+                                                          evil-ex-search-direction))
+                     (success (pop result))
+                     (pattern (pop result))
+                     (offset (pop result)))
+                (cond
+                 ((eq success 'wrap)
+                  (evil-ex-search-update pattern offset
+                                         (match-beginning 0) (match-end 0)
+                                         "Wrapped"))
+                 ((eq success 'empty-pattern)
+                  (evil-ex-search-update nil nil nil nil nil))
+                 (success
+                  (evil-ex-search-update pattern offset
+                                         (match-beginning 0) (match-end 0)
+                                         nil))
+                 (t
+                  (evil-ex-search-update nil nil
+                                         nil nil
+                                         "search failed"))))
+            (invalid-regexp
+             (evil-ex-search-update nil nil nil nil (cadr err)))
+            (error
+             (evil-ex-search-update nil nil nil nil (format "%s" err)))))))))
+(put 'evil-ex-search-update-pattern 'permanent-local-hook t)
+
+(defun evil-ex-search-exit ()
+  "Exit interactive search, keeping lazy highlighting active."
+  (interactive)
+  (evil-ex-search-stop-session)
+  (exit-minibuffer))
+
+(defun evil-ex-search-abort ()
+  "Abort interactive search, disabling lazy highlighting."
+  (interactive)
+  (evil-ex-search-stop-session)
+  (evil-ex-delete-hl 'evil-ex-search)
+  (abort-recursive-edit))
+
+(defun evil-ex-search-goto-offset (offset)
+  "Move point according to search OFFSET and set `evil-this-type' accordingly.
+This function assumes that the current match data represents the
+current search result."
+  (unless (zerop (length offset))
+    (let ((beg (match-beginning 0))
+          (end (match-end 0)))
+      (save-match-data
+        (unless
+            (string-match
+             "^\\([esb]\\)?\\(\\([-+]\\)?\\([0-9]*\\)\\)$"
+             offset)
+          (user-error "Invalid search offset: %s" offset))
+        (let ((count (if (= (match-beginning 4) (match-end 4))
+                         (cond
+                          ((not (match-beginning 3)) 0)
+                          ((= (aref offset (match-beginning 3)) ?+) +1)
+                          (t -1))
+                       (string-to-number (match-string 2 offset)))))
+          (cond
+           ((not (match-beginning 1))
+            (setq evil-this-type 'line)
+            (forward-line count))
+           ((= (aref offset (match-beginning 1)) ?e)
+            (goto-char (+ end count -1))
+            (setq evil-this-type 'inclusive))
+           ((memq (aref offset (match-beginning 1)) '(?s ?b))
+            (goto-char (+ beg count))
+            (setq evil-this-type 'inclusive))))))))
+
+(defun evil-ex-search-setup ()
+  "Hook to initialize the minibuffer for ex search."
+  (add-hook 'pre-command-hook #'evil-ex-remove-default))
+
+(defun evil-ex-start-search (direction count)
+  "Start a new search in a certain DIRECTION."
+  ;; store buffer and window where the search started
+  (let ((evil-ex-current-buffer (current-buffer)))
+    (setq evil-ex-search-count count
+          evil-ex-search-direction direction
+          evil-ex-search-start-point (point)
+          evil-ex-last-was-search t)
+    (progn
+      ;; ensure minibuffer is initialized accordingly
+      (add-hook 'minibuffer-setup-hook #'evil-ex-search-start-session)
+      ;; read the search string
+      (let* ((minibuffer-local-map evil-ex-search-keymap)
+             (search-string
+              (condition-case err
+                  (minibuffer-with-setup-hook
+                      #'evil-ex-search-setup
+                    (read-string (if (eq evil-ex-search-direction 'forward)
+                                     "/" "?")
+                                 (and evil-ex-search-history
+                                      (propertize
+                                       (car evil-ex-search-history)
+                                       'face 'shadow))
+                                 'evil-ex-search-history))
+                (quit
+                 (evil-ex-search-stop-session)
+                 (evil-ex-delete-hl 'evil-ex-search)
+                 (goto-char evil-ex-search-start-point)
+                 (signal (car err) (cdr err))))))
+        ;; pattern entered successful
+        (goto-char (1+ evil-ex-search-start-point))
+        (let* ((result
+                (evil-ex-search-full-pattern search-string
+                                             evil-ex-search-count
+                                             evil-ex-search-direction))
+               (success (pop result))
+               (pattern (pop result))
+               (offset (pop result)))
+          (setq evil-ex-search-pattern pattern
+                evil-ex-search-offset offset)
+          (cond
+           ((memq success '(t wrap))
+            (goto-char (match-beginning 0))
+            (setq evil-ex-search-match-beg (match-beginning 0)
+                  evil-ex-search-match-end (match-end 0))
+            (evil-ex-search-goto-offset offset)
+            (evil-push-search-history search-string (eq direction 'forward))
+            (unless evil-ex-search-persistent-highlight
+              (evil-ex-delete-hl 'evil-ex-search)))
+           (t
+            (goto-char evil-ex-search-start-point)
+            (evil-ex-delete-hl 'evil-ex-search)
+            (signal 'search-failed (list search-string)))))))))
+
+(defun evil-ex-start-word-search (unbounded direction count &optional symbol)
+  "Search for the symbol under point.
+The search matches the COUNT-th occurrence of the word.  If the
+UNBOUNDED argument is nil, the search matches only at symbol
+boundaries, otherwise it matches anywhere.  The DIRECTION
+argument should be either `forward' or `backward', determining
+the search direction. If SYMBOL is non-nil then the functions
+searches for the symbol at point, otherwise for the word at
+point."
+  (let ((string (evil-find-thing (eq direction 'forward)
+                                 (if symbol 'symbol 'word))))
+    (if (null string)
+        (user-error "No word under point")
+      (let ((regex (if unbounded
+                       (regexp-quote string)
+                     (format (if symbol "\\_<%s\\_>" "\\<%s\\>")
+                             (regexp-quote string)))))
+        (setq evil-ex-search-count count
+              evil-ex-search-direction direction
+              evil-ex-search-pattern
+              (evil-ex-make-search-pattern regex)
+              evil-ex-search-offset nil
+              evil-ex-last-was-search t)
+        ;; update search history unless this pattern equals the
+        ;; previous pattern
+        (unless (equal (car-safe evil-ex-search-history) regex)
+          (push regex evil-ex-search-history))
+        (evil-push-search-history regex (eq direction 'forward)))
+      (evil-ex-delete-hl 'evil-ex-search)
+      (when (fboundp 'evil-ex-search-next)
+        (evil-ex-search-next count)))))
+
+;; substitute
+(evil-ex-define-argument-type substitution
+  "A substitution pattern argument /pattern/replacement/flags.
+This handler highlights the pattern of the current substitution."
+  :runner
+  (lambda (flag &optional arg)
+    (with-selected-window (minibuffer-selected-window)
+      (with-current-buffer evil-ex-current-buffer
+        (cond
+         ((eq flag 'start)
+          (evil-ex-make-hl
+           'evil-ex-substitute
+           :face 'evil-ex-substitute-matches
+           :update-hook #'evil-ex-pattern-update-ex-info
+           :match-hook (and evil-ex-substitute-interactive-replace
+                            #'evil-ex-pattern-update-replacement))
+          (setq flag 'update))
+
+         ((eq flag 'stop)
+          (evil-ex-delete-hl 'evil-ex-substitute))))
+
+      (when (and (eq flag 'update)
+                 evil-ex-substitute-highlight-all
+                 (not (zerop (length arg))))
+        (condition-case lossage
+            (let* ((result (evil-ex-get-substitute-info arg t))
+                   (pattern (pop result))
+                   (replacement (pop result))
+                   (range (or (evil-copy-range evil-ex-range)
+                              (evil-range (line-beginning-position)
+                                          (line-end-position)
+                                          'line
+                                          :expanded t))))
+              (setq evil-ex-substitute-current-replacement replacement)
+              (evil-expand-range range)
+              (evil-ex-hl-set-region 'evil-ex-substitute
+                                     (evil-range-beginning range)
+                                     (evil-range-end range))
+              (evil-ex-hl-change 'evil-ex-substitute pattern))
+          (end-of-file
+           (evil-ex-pattern-update-ex-info nil
+                                           "incomplete replacement"))
+          (user-error
+           (evil-ex-pattern-update-ex-info nil
+                                           (format "%s" lossage))))))))
+
+(defun evil-ex-pattern-update-ex-info (hl result)
+  "Update the Ex info string."
+  (when (stringp result)
+    (evil-ex-echo "%s" result)))
+
+(defun evil-ex-pattern-update-replacement (hl overlay)
+  "Update the replacement display."
+  (when (fboundp 'match-substitute-replacement)
+    (let ((fixedcase (not case-replace))
+          repl)
+      (setq repl (if evil-ex-substitute-current-replacement
+                     (evil-match-substitute-replacement
+                      evil-ex-substitute-current-replacement
+                      fixedcase)
+                   ""))
+      (put-text-property 0 (length repl)
+                         'face 'evil-ex-substitute-replacement
+                         repl)
+      (overlay-put overlay 'after-string repl))))
+
+(defun evil-ex-parse-global (string)
+  "Parse STRING as a global argument."
+  (let* ((args (evil-delimited-arguments string 2))
+         (pattern (nth 0 args))
+         (command (nth 1 args)))
+    ;; use last pattern if none given
+    (when (zerop (length pattern))
+      (setq pattern
+            (cond
+             ((and (eq evil-search-module 'evil-search) evil-ex-search-pattern)
+              (evil-ex-pattern-regex evil-ex-search-pattern))
+             ((and (eq evil-search-module 'isearch) (not (zerop (length isearch-string))))
+              isearch-string)
+             (t (user-error "No previous pattern")))))
+    (list pattern command)))
+
+(defun evil-ex-get-substitute-info (string &optional implicit-r)
+  "Returns the substitution info of command line STRING.
+This function returns a three-element list \(PATTERN REPLACEMENT
+FLAGS) consisting of the substitution parts of STRING. PATTERN is
+a ex-pattern (see `evil-ex-make-pattern') and REPLACEMENT in a
+compiled replacement expression (see `evil-compile-replacement').
+The information returned is the actual substitution information
+w.r.t. to special situations like empty patterns or repetition of
+previous substitution commands. If IMPLICIT-R is non-nil, then
+the flag 'r' is assumed, i.e. in the case of an empty pattern the
+last search pattern is used. This will be used when called from
+a :substitute command with arguments."
+  (let (pattern replacement flags)
+    (cond
+     ((or (null string) (string-match "^[a-zA-Z]" string))
+      ;; starts with letter so there is no pattern because the
+      ;; separator must not be a letter repeat last substitute
+      (setq replacement evil-ex-substitute-replacement)
+      ;; flags are everything that is not a white space
+      (when (and string (string-match "[^[:space:]]+" string))
+        (setq flags (match-string 0 string))))
+     (t
+      (let ((args (evil-delimited-arguments string 3)))
+        (setq pattern (pop args)
+              replacement (pop args)
+              flags (pop args))
+        ;; if replacment equals "~" use previous replacement
+        (if (equal replacement "~")
+            (setq replacement evil-ex-substitute-replacement)
+          (setq replacement (evil-compile-replacement replacement)))
+        ;; append implicit "r" flag if required
+        (when (and implicit-r (not (memq ?r (append flags nil))))
+          (setq flags (concat flags "r"))))))
+    ;; if flags equals "&" add previous flags
+    (if (and (not (zerop (length flags)))
+             (= (aref flags 0) ?&))
+        (setq flags (append (substring flags 1)
+                            evil-ex-substitute-flags))
+      (setq flags (append flags nil)))
+    ;; if no pattern, use previous pattern, either search or
+    ;; substitute pattern depending on `evil-ex-last-was-search' and
+    ;; the r flag
+    (when (zerop (length pattern))
+      (setq pattern
+            (if (eq evil-search-module 'evil-search)
+                (if (and evil-ex-last-was-search (memq ?r flags))
+                    (and evil-ex-search-pattern
+                         (evil-ex-pattern-regex evil-ex-search-pattern))
+                  (and evil-ex-substitute-pattern
+                       (evil-ex-pattern-regex evil-ex-substitute-pattern)))
+              (if (eq case-fold-search t)
+                  isearch-string
+                (concat isearch-string "\\C")))
+            flags (remq ?r flags)))
+    ;; generate pattern
+    (when pattern
+      (setq pattern (evil-ex-make-substitute-pattern pattern flags)))
+    (list pattern replacement flags)))
+
+(defun evil-ex-nohighlight ()
+  "Disable the active search highlightings."
+  (interactive)
+  (evil-ex-delete-hl 'evil-ex-substitute)
+  (evil-ex-delete-hl 'evil-ex-search))
+
+(provide 'evil-search)
+
+;;; evil-search.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-search.elc b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-search.elc
new file mode 100644
index 0000000000..2068c60377
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-search.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-states.el b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-states.el
new file mode 100644
index 0000000000..c91d673c70
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-states.el
@@ -0,0 +1,903 @@
+;;; evil-states.el --- States
+
+;; Author: Vegard Øye <vegard_oye at hotmail.com>
+;; Maintainer: Vegard Øye <vegard_oye at hotmail.com>
+
+;; Version: 1.2.13
+
+;;
+;; This file is NOT part of GNU Emacs.
+
+;;; License:
+
+;; This file is part of Evil.
+;;
+;; Evil 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.
+;;
+;; Evil 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 Evil.  If not, see <http://www.gnu.org/licenses/>.
+
+(require 'evil-core)
+
+;;; Code:
+
+;;; Normal state
+
+(evil-define-state normal
+  "Normal state.
+AKA \"Command\" state."
+  :tag " <N> "
+  :enable (motion)
+  :exit-hook (evil-repeat-start-hook)
+  (cond
+   ((evil-normal-state-p)
+    (overwrite-mode -1)
+    (add-hook 'post-command-hook #'evil-normal-post-command nil t))
+   (t
+    (remove-hook 'post-command-hook #'evil-normal-post-command t))))
+
+(defun evil-normal-post-command (&optional command)
+  "Reset command loop variables in Normal state.
+Also prevent point from reaching the end of the line.
+If the region is activated, enter Visual state."
+  (unless (or (evil-initializing-p)
+              (null this-command))
+    (setq command (or command this-command))
+    (when (evil-normal-state-p)
+      (setq evil-this-type nil
+            evil-this-operator nil
+            evil-this-motion nil
+            evil-this-motion-count nil
+            evil-inhibit-operator nil
+            evil-inhibit-operator-value nil)
+      (unless (memq command '(evil-use-register
+                              digit-argument
+                              negative-argument
+                              universal-argument
+                              universal-argument-minus
+                              universal-argument-more
+                              universal-argument-other-key))
+        (setq evil-this-register nil))
+      (evil-adjust-cursor))))
+(put 'evil-normal-post-command 'permanent-local-hook t)
+
+;;; Insert state
+
+(defun evil-maybe-remove-spaces (&optional do-remove)
+  "Remove space from newly opened empty line.
+This function removes (indentation) spaces that have been
+inserted by opening a new empty line. The behavior depends on the
+variable `evil-maybe-remove-spaces'. If this variable is nil the
+function does nothing. Otherwise the behavior depends on
+DO-REMOVE.  If DO-REMOVE is non-nil the spaces are
+removed. Otherwise `evil-maybe-remove-spaces' is set to nil
+unless the last command opened yet another new line.
+
+This function should be added as a post-command-hook to track
+commands opening a new line."
+  (cond
+   ((not evil-maybe-remove-spaces)
+    (remove-hook 'post-command-hook #'evil-maybe-remove-spaces))
+   (do-remove
+    (when (save-excursion
+            (beginning-of-line)
+            (looking-at "^\\s-*$"))
+      (delete-region (line-beginning-position)
+                     (line-end-position)))
+    (setq evil-maybe-remove-spaces nil)
+    (remove-hook 'post-command-hook #'evil-maybe-remove-spaces))
+   ((not (memq this-command
+               '(evil-open-above
+                 evil-open-below
+                 evil-append
+                 evil-append-line
+                 newline
+                 newline-and-indent
+                 indent-and-newline)))
+    (setq evil-maybe-remove-spaces nil)
+    (remove-hook 'post-command-hook #'evil-maybe-remove-spaces))))
+
+(evil-define-state insert
+  "Insert state."
+  :tag " <I> "
+  :cursor (bar . 2)
+  :message "-- INSERT --"
+  :entry-hook (evil-start-track-last-insertion)
+  :exit-hook (evil-cleanup-insert-state evil-stop-track-last-insertion)
+  :input-method t
+  (cond
+   ((evil-insert-state-p)
+    (add-hook 'post-command-hook #'evil-maybe-remove-spaces)
+    (add-hook 'pre-command-hook #'evil-insert-repeat-hook)
+    (setq evil-maybe-remove-spaces t)
+    (unless (eq evil-want-fine-undo t)
+      (evil-start-undo-step)))
+   (t
+    (remove-hook 'post-command-hook #'evil-maybe-remove-spaces)
+    (remove-hook 'pre-command-hook #'evil-insert-repeat-hook)
+    (evil-maybe-remove-spaces t)
+    (setq evil-insert-repeat-info evil-repeat-info)
+    (evil-set-marker ?^ nil t)
+    (unless (eq evil-want-fine-undo t)
+      (evil-end-undo-step))
+    (when evil-move-cursor-back
+      (when (or (evil-normal-state-p evil-next-state)
+                (evil-motion-state-p evil-next-state))
+        (evil-move-cursor-back))))))
+
+(defun evil-insert-repeat-hook ()
+  "Record insertion keys in `evil-insert-repeat-info'."
+  (setq evil-insert-repeat-info (last evil-repeat-info))
+  (remove-hook 'pre-command-hook #'evil-insert-repeat-hook))
+(put 'evil-insert-repeat-hook 'permanent-local-hook t)
+
+(defun evil-cleanup-insert-state ()
+  "Called when Insert state is about to be exited.
+Handles the repeat-count of the insertion command."
+  (when evil-insert-count
+    (dotimes (i (1- evil-insert-count))
+      (when evil-insert-lines
+        (evil-insert-newline-below)
+        (when evil-auto-indent
+          (indent-according-to-mode)))
+      (when (fboundp 'evil-execute-repeat-info)
+        (evil-execute-repeat-info
+         (cdr evil-insert-repeat-info)))))
+  (when evil-insert-vcount
+    (let ((buffer-invisibility-spec buffer-invisibility-spec))
+      ;; make all lines hidden by hideshow temporarily visible
+      (when (listp buffer-invisibility-spec)
+        (setq buffer-invisibility-spec
+              (evil-filter-list
+               #'(lambda (x)
+                   (or (eq x 'hs)
+                       (eq (car-safe x) 'hs)))
+               buffer-invisibility-spec)))
+      (let ((line (nth 0 evil-insert-vcount))
+            (col (nth 1 evil-insert-vcount))
+            (vcount (nth 2 evil-insert-vcount)))
+        (save-excursion
+          (dotimes (v (1- vcount))
+            (goto-char (point-min))
+            (forward-line (+ line v))
+            (when (or (not evil-insert-skip-empty-lines)
+                      (not (integerp col))
+                      (save-excursion
+                        (evil-move-end-of-line)
+                        (>= (current-column) col)))
+              (if (integerp col)
+                  (move-to-column col t)
+                (funcall col))
+              (dotimes (i (or evil-insert-count 1))
+                (when (fboundp 'evil-execute-repeat-info)
+                  (evil-execute-repeat-info
+                   (cdr evil-insert-repeat-info)))))))))))
+
+;;; Visual state
+
+;; Visual selections are implemented in terms of types, and are
+;; compatible with the Emacs region. This is achieved by "translating"
+;; the region to the selected text right before a command is executed.
+;; If the command is a motion, the translation is postponed until a
+;; non-motion command is invoked (distinguished by the :keep-visual
+;; command property).
+;;
+;; Visual state activates the region, enabling Transient Mark mode if
+;; not already enabled. This is only temporay: if Transient Mark mode
+;; was disabled before entering Visual state, it is disabled when
+;; exiting Visual state. This allows Visual state to harness the
+;; "transient" behavior of many commands without overriding the user's
+;; preferences in other states.
+
+(defmacro evil-define-visual-selection (selection doc &rest body)
+  "Define a Visual selection SELECTION.
+Creates a command evil-visual-SELECTION for enabling the selection.
+DOC is the function's documentation string. The following keywords
+may be specified in BODY:
+
+:message STRING         Status message when enabling the selection.
+:type TYPE              Type to use (defaults to SELECTION).
+
+Following the keywords is optional code which is executed each time
+the selection is enabled.
+
+\(fn SELECTION DOC [[KEY VAL]...] BODY...)"
+  (declare (indent defun)
+           (debug (&define name stringp
+                           [&rest keywordp sexp]
+                           def-body)))
+  (let* ((name (intern (format "evil-visual-%s" selection)))
+         (message (intern (format "%s-message" name)))
+         (type selection)
+         arg key string)
+    ;; collect keywords
+    (while (keywordp (car-safe body))
+      (setq key (pop body)
+            arg (pop body))
+      (cond
+       ((eq key :message)
+        (setq string arg))
+       ((eq key :type)
+        (setq type arg))))
+    ;; macro expansion
+    `(progn
+       (add-to-list 'evil-visual-alist (cons ',selection ',name))
+       (defvar ,name ',type ,(format "*%s" doc))
+       (defvar ,message ,string ,doc)
+       (evil-define-command ,name (&optional mark point type message)
+         ,@(when doc `(,doc))
+         :keep-visual t
+         :repeat nil
+         (interactive
+          (list nil nil
+                (if (and (evil-visual-state-p)
+                         (eq evil-visual-selection ',selection))
+                    'exit ,name) t))
+         (if (eq type 'exit)
+             (evil-exit-visual-state)
+           (setq type (or type ,name)
+                 evil-visual-selection ',selection)
+           (evil-visual-make-region mark point type message)
+           ,@body))
+       ',selection)))
+
+(evil-define-visual-selection char
+  "Characterwise selection."
+  :type inclusive
+  :message "-- VISUAL --")
+
+(evil-define-visual-selection line
+  "Linewise selection."
+  :message "-- VISUAL LINE --")
+
+(evil-define-visual-selection block
+  "Blockwise selection."
+  :message "-- VISUAL BLOCK --"
+  (evil-transient-mark -1)
+  ;; refresh the :corner property
+  (setq evil-visual-properties
+        (plist-put evil-visual-properties :corner
+                   (evil-visual-block-corner 'upper-left))))
+
+(evil-define-state visual
+  "Visual state."
+  :tag " <V> "
+  :enable (motion normal)
+  :message 'evil-visual-message
+  (cond
+   ((evil-visual-state-p)
+    (evil-save-transient-mark-mode)
+    (setq select-active-regions nil)
+    (cond
+     ((region-active-p)
+      (if (< (evil-visual-direction) 0)
+          (evil-visual-select (region-beginning) (region-end)
+                              evil-visual-char
+                              (evil-visual-direction))
+        (evil-visual-make-selection (mark t) (point)
+                                    evil-visual-char))
+      (evil-visual-highlight))
+     (t
+      (evil-visual-make-region (point) (point) evil-visual-char)))
+    (add-hook 'pre-command-hook #'evil-visual-pre-command nil t)
+    (add-hook 'post-command-hook #'evil-visual-post-command nil t)
+    (add-hook 'deactivate-mark-hook #'evil-visual-deactivate-hook nil t))
+   (t
+    ;; Postpone deactivation of region if next state is Insert.
+    ;; This gives certain insertion commands (auto-pairing characters,
+    ;; for example) an opportunity to access the region.
+    (if (and (eq evil-next-state 'insert)
+             (eq evil-visual-selection 'char))
+        (add-hook 'evil-normal-state-entry-hook
+                  #'evil-visual-deactivate-hook nil t)
+      (evil-visual-deactivate-hook))
+    (setq evil-visual-region-expanded nil)
+    (remove-hook 'pre-command-hook #'evil-visual-pre-command t)
+    (remove-hook 'post-command-hook #'evil-visual-post-command t)
+    (remove-hook 'deactivate-mark-hook #'evil-visual-deactivate-hook t)
+    (evil-visual-highlight -1))))
+
+(defun evil-visual-pre-command (&optional command)
+  "Run before each COMMAND in Visual state.
+Expand the region to the selection unless COMMAND is a motion."
+  (when (evil-visual-state-p)
+    (setq command (or command this-command))
+    (when evil-visual-x-select-timer
+      (cancel-timer evil-visual-x-select-timer))
+    (unless (evil-get-command-property command :keep-visual)
+      (evil-visual-update-x-selection)
+      (evil-visual-expand-region
+       ;; exclude final newline from linewise selection
+       ;; unless the command has real need of it
+       (and (eq (evil-visual-type) 'line)
+            (evil-get-command-property command :exclude-newline))))))
+
+(put 'evil-visual-pre-command 'permanent-local-hook t)
+
+(defun evil-visual-post-command (&optional command)
+  "Run after each COMMAND in Visual state.
+If COMMAND is a motion, refresh the selection;
+otherwise exit Visual state."
+  (when (evil-visual-state-p)
+    (setq command (or command this-command))
+    (if (or quit-flag
+            (eq command #'keyboard-quit)
+            ;; Is `mark-active' nil for an unexpanded region?
+            deactivate-mark
+            (and (not evil-visual-region-expanded)
+                 (not (region-active-p))
+                 (not (eq evil-visual-selection 'block))))
+        (progn
+          (evil-exit-visual-state)
+          (evil-adjust-cursor))
+      (if evil-visual-region-expanded
+          (evil-visual-contract-region)
+        (evil-visual-refresh))
+      (setq evil-visual-x-select-timer
+            (run-with-idle-timer evil-visual-x-select-timeout nil
+                                 #'evil-visual-update-x-selection
+                                 (current-buffer)))
+      (evil-visual-highlight))))
+(put 'evil-visual-post-command 'permanent-local-hook t)
+
+(defun evil-visual-update-x-selection (&optional buffer)
+  "Update the X selection with the current visual region."
+  (let ((buf (or buffer (current-buffer))))
+    (when (buffer-live-p buf)
+      (with-current-buffer buf
+        (when (and (evil-visual-state-p)
+                   (display-selections-p)
+                   (not (eq evil-visual-selection 'block)))
+          (evil-set-selection 'PRIMARY (buffer-substring-no-properties
+                                        evil-visual-beginning
+                                        evil-visual-end)))))))
+
+(defun evil-visual-activate-hook (&optional command)
+  "Enable Visual state if the region is activated."
+  (unless (evil-visual-state-p)
+    (evil-delay nil
+        ;; the activation may only be momentary, so re-check
+        ;; in `post-command-hook' before entering Visual state
+        '(unless (or (evil-visual-state-p)
+                     (evil-insert-state-p)
+                     (evil-emacs-state-p))
+           (when (and (region-active-p)
+                      (not deactivate-mark))
+             (evil-visual-state)))
+      'post-command-hook nil t
+      "evil-activate-visual-state")))
+(put 'evil-visual-activate-hook 'permanent-local-hook t)
+
+(defun evil-visual-deactivate-hook (&optional command)
+  "Deactivate the region and restore Transient Mark mode."
+  (setq command (or command this-command))
+  (remove-hook 'deactivate-mark-hook
+               #'evil-visual-deactivate-hook t)
+  (remove-hook 'evil-normal-state-entry-hook
+               #'evil-visual-deactivate-hook t)
+  (cond
+   ((and (evil-visual-state-p) command
+         (not (evil-get-command-property command :keep-visual)))
+    (setq evil-visual-region-expanded nil)
+    (evil-exit-visual-state))
+   ((not (evil-visual-state-p))
+    (evil-active-region -1)
+    (evil-restore-transient-mark-mode))))
+(put 'evil-visual-deactivate-hook 'permanent-local-hook t)
+
+(evil-define-command evil-exit-visual-state (&optional later buffer)
+  "Exit from Visual state to the previous state.
+If LATER is non-nil, exit after the current command."
+  :keep-visual t
+  :repeat abort
+  (with-current-buffer (or buffer (current-buffer))
+    (when (evil-visual-state-p)
+      (if later
+          (setq deactivate-mark t)
+        (when evil-visual-region-expanded
+          (evil-visual-contract-region))
+        (evil-change-to-previous-state)))))
+
+(defun evil-visual-message (&optional selection)
+  "Create an echo area message for SELECTION.
+SELECTION is a kind of selection as defined by
+`evil-define-visual-selection', such as `char', `line'
+or `block'."
+  (let (message)
+    (setq selection (or selection evil-visual-selection))
+    (when selection
+      (setq message
+            (symbol-value (intern (format "evil-visual-%s-message"
+                                          selection))))
+      (cond
+       ((functionp message)
+        (funcall message))
+       ((stringp message)
+        (evil-echo "%s" message))))))
+
+(defun evil-visual-select (beg end &optional type dir message)
+  "Create a Visual selection of type TYPE from BEG to END.
+Point and mark are positioned so that the resulting selection
+has the specified boundaries. If DIR is negative, point precedes mark,
+otherwise it succedes it. To specify point and mark directly,
+use `evil-visual-make-selection'."
+  (let* ((range (evil-contract beg end type))
+         (mark (evil-range-beginning range))
+         (point (evil-range-end range))
+         (dir (or dir 1)))
+    (when (< dir 0)
+      (evil-swap mark point))
+    (evil-visual-make-selection mark point type message)))
+
+(defun evil-visual-make-selection (mark point &optional type message)
+  "Create a Visual selection with point at POINT and mark at MARK.
+The boundaries of the selection are inferred from these
+and the current TYPE. To specify the boundaries and infer
+mark and point, use `evil-visual-select' instead."
+  (let* ((selection (evil-visual-selection-for-type type))
+         (func (evil-visual-selection-function selection))
+         (prev (and (evil-visual-state-p) evil-visual-selection))
+         (mark (evil-normalize-position mark))
+         (point (evil-normalize-position point))
+         (state evil-state))
+    (unless (evil-visual-state-p)
+      (evil-visual-state))
+    (setq evil-visual-selection selection)
+    (funcall func mark point type
+             ;; signal a message when changing the selection
+             (when (or (not (evil-visual-state-p state))
+                       (not (eq selection prev)))
+               message))))
+
+(defun evil-visual-make-region (mark point &optional type message)
+  "Create an active region from MARK to POINT.
+If TYPE is given, also set the Visual type.
+If MESSAGE is given, display it in the echo area."
+  (interactive)
+  (let* ((point (evil-normalize-position
+                 (or point (point))))
+         (mark (evil-normalize-position
+                (or mark
+                    (when (or (evil-visual-state-p)
+                              (region-active-p))
+                      (mark t))
+                    point))))
+    (unless (evil-visual-state-p)
+      (evil-visual-state))
+    (evil-active-region 1)
+    (setq evil-visual-region-expanded nil)
+    (evil-visual-refresh mark point type)
+    (cond
+     ((null evil-echo-state))
+     ((stringp message)
+      (evil-echo "%s" message))
+     (message
+      (cond
+       ((stringp evil-visual-state-message)
+        (evil-echo "%s" evil-visual-state-message))
+       ((functionp evil-visual-state-message)
+        (funcall evil-visual-state-message)))))))
+
+(defun evil-visual-expand-region (&optional exclude-newline)
+  "Expand the region to the Visual selection.
+If EXCLUDE-NEWLINE is non-nil and the selection ends with a newline,
+exclude that newline from the region."
+  (when (and (evil-visual-state-p)
+             (not evil-visual-region-expanded))
+    (let ((mark evil-visual-beginning)
+          (point evil-visual-end))
+      (when (< evil-visual-direction 0)
+        (evil-swap mark point))
+      (setq evil-visual-region-expanded t)
+      (evil-visual-refresh mark point)
+      (when (and exclude-newline
+                 (save-excursion
+                   (goto-char evil-visual-end)
+                   (and (bolp) (not (bobp)))))
+        (if (< evil-visual-direction 0)
+            (evil-move-mark (max point (1- (mark))))
+          (goto-char (max mark (1- (point)))))))))
+
+(defun evil-visual-contract-region ()
+  "The inverse of `evil-visual-expand-region'.
+Create a Visual selection that expands to the current region."
+  (evil-visual-refresh)
+  (setq evil-visual-region-expanded nil)
+  (evil-visual-refresh evil-visual-mark evil-visual-point))
+
+(defun evil-visual-refresh (&optional mark point type &rest properties)
+  "Refresh point, mark and Visual variables.
+Refreshes `evil-visual-beginning', `evil-visual-end',
+`evil-visual-mark', `evil-visual-point', `evil-visual-selection',
+`evil-visual-direction', `evil-visual-properties' and `evil-this-type'."
+  (let* ((point (or point (point)))
+         (mark (or mark (mark t) point))
+         (dir (evil-visual-direction))
+         (type (or type (evil-visual-type evil-visual-selection)
+                   (evil-visual-type)))
+         range)
+    (evil-move-mark mark)
+    (goto-char point)
+    (setq evil-visual-beginning
+          (or evil-visual-beginning
+              (let ((marker (make-marker)))
+                (move-marker marker (min point mark))))
+          evil-visual-end
+          (or evil-visual-end
+              (let ((marker (make-marker)))
+                (set-marker-insertion-type marker t)
+                (move-marker marker (max point mark))))
+          evil-visual-mark
+          (or evil-visual-mark
+              (let ((marker (make-marker)))
+                (move-marker marker mark)))
+          evil-visual-point
+          (or evil-visual-point
+              (let ((marker (make-marker)))
+                (move-marker marker point))))
+    (setq evil-visual-properties
+          (evil-concat-plists evil-visual-properties properties))
+    (cond
+     (evil-visual-region-expanded
+      (setq type (or (evil-visual-type) type))
+      (move-marker evil-visual-beginning (min point mark))
+      (move-marker evil-visual-end (max point mark))
+      ;; if the type is one-to-one, we can safely refresh
+      ;; the unexpanded positions as well
+      (when (evil-type-property type :one-to-one)
+        (setq range (apply #'evil-contract point mark type
+                           evil-visual-properties)
+              mark (evil-range-beginning range)
+              point (evil-range-end range))
+        (when (< dir 0)
+          (evil-swap mark point))
+        (move-marker evil-visual-mark mark)
+        (move-marker evil-visual-point point)))
+     (t
+      (setq range (apply #'evil-expand point mark type
+                         evil-visual-properties)
+            type (evil-type range type))
+      (move-marker evil-visual-beginning (evil-range-beginning range))
+      (move-marker evil-visual-end (evil-range-end range))
+      (move-marker evil-visual-mark mark)
+      (move-marker evil-visual-point point)))
+    (setq evil-visual-direction dir
+          evil-this-type type)))
+
+(defun evil-visual-highlight (&optional arg)
+  "Highlight Visual selection, depending on the Visual type.
+With negative ARG, disable highlighting."
+  (cond
+   ((and (numberp arg) (< arg 1))
+    (when evil-visual-overlay
+      (delete-overlay evil-visual-overlay)
+      (setq evil-visual-overlay nil))
+    (when evil-visual-block-overlays
+      (mapc #'delete-overlay evil-visual-block-overlays)
+      (setq evil-visual-block-overlays nil)))
+   ((eq evil-visual-selection 'block)
+    (when evil-visual-overlay
+      (evil-visual-highlight -1))
+    (evil-visual-highlight-block
+     evil-visual-beginning
+     evil-visual-end))
+   (t
+    (when evil-visual-block-overlays
+      (evil-visual-highlight -1))
+    (if evil-visual-overlay
+        (move-overlay evil-visual-overlay
+                      evil-visual-beginning evil-visual-end)
+      (setq evil-visual-overlay
+            (make-overlay evil-visual-beginning evil-visual-end)))
+    (overlay-put evil-visual-overlay 'face 'region)
+    (overlay-put evil-visual-overlay 'priority 99))))
+
+(defun evil-visual-highlight-block (beg end &optional overlays)
+  "Highlight rectangular region from BEG to END.
+Do this by putting an overlay on each line within the rectangle.
+Each overlay extends across all the columns of the rectangle.
+Reuse overlays where possible to prevent flicker."
+  (let* ((point (point))
+         (mark (or (mark t) point))
+         (overlays (or overlays 'evil-visual-block-overlays))
+         (old (symbol-value overlays))
+         (eol-col (and (memq this-command '(next-line previous-line))
+                       (numberp temporary-goal-column)
+                       (1+ (min (round temporary-goal-column)
+                                (1- most-positive-fixnum)))))
+         beg-col end-col new nlines overlay window-beg window-end)
+    (save-excursion
+      ;; calculate the rectangular region represented by BEG and END,
+      ;; but put BEG in the upper-left corner and END in the
+      ;; lower-right if not already there
+      (setq beg-col (evil-column beg)
+            end-col (evil-column end))
+      (when (>= beg-col end-col)
+        (if (= beg-col end-col)
+            (setq end-col (1+ end-col))
+          (evil-sort beg-col end-col))
+        (setq beg (save-excursion
+                    (goto-char beg)
+                    (evil-move-to-column beg-col))
+              end (save-excursion
+                    (goto-char end)
+                    (evil-move-to-column end-col 1))))
+      ;; update end column with eol-col (extension to eol).
+      (when (and eol-col (> eol-col end-col))
+        (setq end-col eol-col))
+      ;; force a redisplay so we can do reliable window
+      ;; BEG/END calculations
+      (sit-for 0)
+      (setq window-beg (max (window-start) beg)
+            window-end (min (window-end) (1+ end))
+            nlines (count-lines window-beg
+                                (min window-end (point-max))))
+      ;; iterate over those lines of the rectangle which are
+      ;; visible in the currently selected window
+      (goto-char window-beg)
+      (dotimes (i nlines)
+        (let (before after row-beg row-end)
+          ;; beginning of row
+          (evil-move-to-column beg-col)
+          (when (< (current-column) beg-col)
+            ;; prepend overlay with virtual spaces if unable to
+            ;; move directly to the first column
+            (setq before
+                  (propertize
+                   (make-string
+                    (- beg-col (current-column)) ?\s)
+                   'face
+                   (or (get-text-property (1- (point)) 'face)
+                       'default))))
+          (setq row-beg (point))
+          ;; end of row
+          (evil-move-to-column end-col)
+          (when (and (not (eolp))
+                     (< (current-column) end-col))
+            ;; append overlay with virtual spaces if unable to
+            ;; move directly to the last column
+            (setq after
+                  (propertize
+                   (make-string
+                    (if (= (point) row-beg)
+                        (- end-col beg-col)
+                      (- end-col (current-column)))
+                    ?\s) 'face 'region))
+            ;; place cursor on one of the virtual spaces
+            (if (= point row-beg)
+                (put-text-property
+                 0 (min (length after) 1)
+                 'cursor t after)
+              (put-text-property
+               (max 0 (1- (length after))) (length after)
+               'cursor t after)))
+          (setq row-end (min (point) (line-end-position)))
+          ;; trim old leading overlays
+          (while (and old
+                      (setq overlay (car old))
+                      (< (overlay-start overlay) row-beg)
+                      (/= (overlay-end overlay) row-end))
+            (delete-overlay overlay)
+            (setq old (cdr old)))
+          ;; reuse an overlay if possible, otherwise create one
+          (cond
+           ((and old (setq overlay (car old))
+                 (or (= (overlay-start overlay) row-beg)
+                     (= (overlay-end overlay) row-end)))
+            (move-overlay overlay row-beg row-end)
+            (overlay-put overlay 'before-string before)
+            (overlay-put overlay 'after-string after)
+            (setq new (cons overlay new)
+                  old (cdr old)))
+           (t
+            (setq overlay (make-overlay row-beg row-end))
+            (overlay-put overlay 'before-string before)
+            (overlay-put overlay 'after-string after)
+            (setq new (cons overlay new)))))
+        (forward-line 1))
+      ;; display overlays
+      (dolist (overlay new)
+        (overlay-put overlay 'face 'region)
+        (overlay-put overlay 'priority 99))
+      ;; trim old overlays
+      (dolist (overlay old)
+        (delete-overlay overlay))
+      (set overlays (nreverse new)))))
+
+(defun evil-visual-range ()
+  "Return the Visual selection as a range.
+This is a list (BEG END TYPE PROPERTIES...), where BEG is the
+beginning of the selection, END is the end of the selection,
+TYPE is the selection's type, and PROPERTIES is a property list
+of miscellaneous selection attributes."
+  (apply #'evil-range
+         evil-visual-beginning evil-visual-end
+         (evil-visual-type)
+         :expanded t
+         evil-visual-properties))
+
+(defun evil-visual-direction ()
+  "Return direction of Visual selection.
+The direction is -1 if point precedes mark and 1 otherwise.
+See also the variable `evil-visual-direction', which holds
+the direction of the last selection."
+  (let* ((point (point))
+         (mark (or (mark t) point)))
+    (if (< point mark) -1 1)))
+
+(defun evil-visual-type (&optional selection)
+  "Return the type of the Visual selection.
+If SELECTION is specified, return the type of that instead."
+  (if (and (null selection) (evil-visual-state-p))
+      (or evil-this-type (evil-visual-type evil-visual-selection))
+    (setq selection (or selection evil-visual-selection))
+    (symbol-value (cdr-safe (assq selection evil-visual-alist)))))
+
+(defun evil-visual-goto-end ()
+  "Go to the last line of the Visual selection.
+This position may differ from `evil-visual-end' depending on
+the selection type, and is contained in the selection."
+  (let ((range (evil-contract-range (evil-visual-range))))
+    (goto-char (evil-range-end range))))
+
+(defun evil-visual-alist ()
+  "Return an association list from types to selection symbols."
+  (mapcar #'(lambda (e)
+              (cons (symbol-value (cdr-safe e)) (cdr-safe e)))
+          evil-visual-alist))
+
+(defun evil-visual-selection-function (selection)
+  "Return a selection function for TYPE.
+Default to `evil-visual-make-region'."
+  (or (cdr-safe (assq selection evil-visual-alist))
+      ;; generic selection function
+      'evil-visual-make-region))
+
+(defun evil-visual-selection-for-type (type)
+  "Return a Visual selection for TYPE."
+  (catch 'done
+    (dolist (selection evil-visual-alist)
+      (when (eq (symbol-value (cdr selection)) type)
+        (throw 'done (car selection))))))
+
+(defun evil-visual-block-corner (&optional corner point mark)
+  "Block corner corresponding to POINT, with MARK in opposite corner.
+Depending on POINT and MARK, the return value is `upper-left',
+`upper-right', `lower-left' or `lower-right':
+
+        upper-left +---+ upper-right
+                   |   |
+        lower-left +---+ lower-right
+
+One-column or one-row blocks are ambiguous. In such cases,
+the horizontal or vertical component of CORNER is used.
+CORNER defaults to `upper-left'."
+  (let* ((point (or point (point)))
+         (mark (or mark (mark t)))
+         (corner (symbol-name
+                  (or corner
+                      (and (overlayp evil-visual-overlay)
+                           (overlay-get evil-visual-overlay
+                                        :corner))
+                      'upper-left)))
+         (point-col (evil-column point))
+         (mark-col (evil-column mark))
+         horizontal vertical)
+    (cond
+     ((= point-col mark-col)
+      (setq horizontal
+            (or (and (string-match "left\\|right" corner)
+                     (match-string 0 corner))
+                "left")))
+     ((< point-col mark-col)
+      (setq horizontal "left"))
+     ((> point-col mark-col)
+      (setq horizontal "right")))
+    (cond
+     ((= (line-number-at-pos point)
+         (line-number-at-pos mark))
+      (setq vertical
+            (or (and (string-match "upper\\|lower" corner)
+                     (match-string 0 corner))
+                "upper")))
+     ((< point mark)
+      (setq vertical "upper"))
+     ((> point mark)
+      (setq vertical "lower")))
+    (intern (format "%s-%s" vertical horizontal))))
+
+;;; Operator-Pending state
+
+(evil-define-state operator
+  "Operator-Pending state."
+  :tag " <O> "
+  :cursor evil-half-cursor
+  :enable (evil-operator-shortcut-map operator motion normal))
+
+(evil-define-keymap evil-operator-shortcut-map
+  "Keymap for Operator-Pending shortcuts like \"dd\" and \"gqq\"."
+  :local t
+  (setq evil-operator-shortcut-map (make-sparse-keymap))
+  (evil-initialize-local-keymaps))
+
+;; the half-height "Operator-Pending cursor" cannot be specified
+;; as a static `cursor-type' value, since its height depends on
+;; the current font size
+(defun evil-half-cursor ()
+  "Change cursor to a half-height box.
+\(This is really just a thick horizontal bar.)"
+  (let ((height (/ (window-pixel-height) (* (window-height) 2))))
+    (setq cursor-type (cons 'hbar height))))
+
+;;; Replace state
+
+(evil-define-state replace
+  "Replace state."
+  :tag " <R> "
+  :cursor hbar
+  :message "-- REPLACE --"
+  :input-method t
+  (cond
+   ((evil-replace-state-p)
+    (overwrite-mode 1)
+    (add-hook 'pre-command-hook #'evil-replace-pre-command nil t)
+    (unless (eq evil-want-fine-undo t)
+      (evil-start-undo-step)))
+   (t
+    (overwrite-mode -1)
+    (remove-hook 'pre-command-hook #'evil-replace-pre-command t)
+    (unless (eq evil-want-fine-undo t)
+      (evil-end-undo-step))
+    (when evil-move-cursor-back
+      (evil-move-cursor-back))))
+  (setq evil-replace-alist nil))
+
+(defun evil-replace-pre-command ()
+  "Remember the character under point."
+  (when (evil-replace-state-p)
+    (unless (assq (point) evil-replace-alist)
+      (add-to-list 'evil-replace-alist
+                   (cons (point)
+                         (unless (eolp)
+                           (char-after)))))))
+(put 'evil-replace-pre-command 'permanent-local-hook t)
+
+(defun evil-replace-backspace ()
+  "Restore character under cursor."
+  (interactive)
+  (let (char)
+    (backward-char)
+    (when (assq (point) evil-replace-alist)
+      (setq char (cdr (assq (point) evil-replace-alist)))
+      (save-excursion
+        (delete-char 1)
+        (when char
+          (insert char))))))
+
+;;; Motion state
+
+(evil-define-state motion
+  "Motion state."
+  :tag " <M> "
+  :suppress-keymap t)
+
+;;; Emacs state
+
+(evil-define-state emacs
+  "Emacs state."
+  :tag " <E> "
+  :message "-- EMACS --"
+  :input-method t
+  :intercept-esc nil)
+
+(provide 'evil-states)
+
+;;; evil-states.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-states.elc b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-states.elc
new file mode 100644
index 0000000000..255496a0d3
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-states.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-types.el b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-types.el
new file mode 100644
index 0000000000..eefd9acd0a
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-types.el
@@ -0,0 +1,424 @@
+;;; evil-types.el --- Type system
+
+;; Author: Vegard Øye <vegard_oye at hotmail.com>
+;; Maintainer: Vegard Øye <vegard_oye at hotmail.com>
+
+;; Version: 1.2.13
+
+;;
+;; This file is NOT part of GNU Emacs.
+
+;;; License:
+
+;; This file is part of Evil.
+;;
+;; Evil 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.
+;;
+;; Evil 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 Evil.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; A type defines a transformation on a pair of buffer positions.
+;; Types are used by Visual state (character/line/block selection)
+;; and Operator-Pending state (character/line/block motions).
+;;
+;; The basic transformation is "expansion". For example, the `line'
+;; type "expands" a pair of positions to whole lines by moving the
+;; first position to the beginning of the line and the last position
+;; to the end of the line. That expanded selection is what the rest
+;; of Emacs sees and acts on.
+;;
+;; An optional transformation is "contraction", which is the opposite
+;; of expansion. If the transformation is one-to-one, expansion
+;; followed by contraction always returns the original range.
+;; (The `line' type is not one-to-one, as it may expand multiple
+;; positions to the same lines.)
+;;
+;; Another optional transformation is "normalization", which takes
+;; two unexpanded positions and adjusts them before expansion.
+;; This is useful for cleaning up "invalid" positions.
+;;
+;; Types are defined at the end of this file using the macro
+;; `evil-define-type'.
+
+(require 'evil-common)
+(require 'evil-macros)
+
+;;; Code:
+
+;;; Type definitions
+
+(evil-define-type exclusive
+  "Return the positions unchanged, with some exceptions.
+If the end position is at the beginning of a line, then:
+
+* If the beginning position is at or before the first non-blank
+  character on the line, return `line' (expanded).
+
+* Otherwise, move the end position to the end of the previous
+  line and return `inclusive' (expanded)."
+  :normalize (lambda (beg end)
+               (cond
+                ((progn
+                   (goto-char end)
+                   (and (/= beg end) (bolp)))
+                 (setq end (max beg (1- end)))
+                 (cond
+                  ((progn
+                     (goto-char beg)
+                     (looking-back "^[ \f\t\v]*" (line-beginning-position)))
+                   (evil-expand beg end 'line))
+                  (t
+                   (unless evil-cross-lines
+                     (setq end (max beg (1- end))))
+                   (evil-expand beg end 'inclusive))))
+                (t
+                 (evil-range beg end))))
+  :string (lambda (beg end)
+            (let ((width (- end beg)))
+              (format "%s character%s" width
+                      (if (= width 1) "" "s")))))
+
+(evil-define-type inclusive
+  "Include the character under point.
+If the end position is at the beginning of a line or the end of a
+line and `evil-want-visual-char-semi-exclusive', then:
+
+* If in visual state return `exclusive' (expanded)."
+  :expand (lambda (beg end)
+            (if (and evil-want-visual-char-semi-exclusive
+                     (evil-visual-state-p)
+                     (< beg end)
+                     (save-excursion
+                       (goto-char end)
+                       (or (bolp) (eolp))))
+                (evil-range beg end 'exclusive)
+              (evil-range beg (1+ end))))
+  :contract (lambda (beg end)
+              (evil-range beg (max beg (1- end))))
+  :normalize (lambda (beg end)
+               (goto-char end)
+               (when (eq (char-after) ?\n)
+                 (setq end (max beg (1- end))))
+               (evil-range beg end))
+  :string (lambda (beg end)
+            (let ((width (- end beg)))
+              (format "%s character%s" width
+                      (if (= width 1) "" "s")))))
+
+(evil-define-type line
+  "Include whole lines."
+  :one-to-one nil
+  :expand (lambda (beg end)
+            (evil-range
+             (progn
+               (goto-char beg)
+               (min (line-beginning-position)
+                    (progn
+                      ;; move to beginning of line as displayed
+                      (evil-move-beginning-of-line)
+                      (line-beginning-position))))
+             (progn
+               (goto-char end)
+               (max (line-beginning-position 2)
+                    (progn
+                      ;; move to end of line as displayed
+                      (evil-move-end-of-line)
+                      (line-beginning-position 2))))))
+  :contract (lambda (beg end)
+              (evil-range beg (max beg (1- end))))
+  :string (lambda (beg end)
+            (let ((height (count-lines beg end)))
+              (format "%s line%s" height
+                      (if (= height 1) "" "s")))))
+
+(evil-define-type block
+  "Like `inclusive', but for rectangles:
+the last column is included."
+  :expand (lambda (beg end &rest properties)
+            (let ((beg-col (evil-column beg))
+                  (end-col (evil-column end))
+                  (corner (plist-get properties :corner)))
+              ;; Since blocks are implemented as a pair of buffer
+              ;; positions, expansion is restricted to what the buffer
+              ;; allows. In the case of a one-column block, there are
+              ;; two ways to expand it (either move the upper corner
+              ;; beyond the lower corner, or the lower beyond the
+              ;; upper), so try out both possibilities when
+              ;; encountering the end of the line.
+              (cond
+               ((= beg-col end-col)
+                (goto-char end)
+                (cond
+                 ((eolp)
+                  (goto-char beg)
+                  (if (eolp)
+                      (evil-range beg end)
+                    (evil-range (1+ beg) end)))
+                 ((memq corner '(lower-right upper-right right))
+                  (evil-range (1+ beg) end))
+                 (t
+                  (evil-range beg (1+ end)))))
+               ((< beg-col end-col)
+                (goto-char end)
+                (if (eolp)
+                    (evil-range beg end)
+                  (evil-range beg (1+ end))))
+               (t
+                (goto-char beg)
+                (if (eolp)
+                    (evil-range beg end)
+                  (evil-range (1+ beg) end))))))
+  :contract (lambda (beg end)
+              (let ((beg-col (evil-column beg))
+                    (end-col (evil-column end)))
+                (if (> beg-col end-col)
+                    (evil-range (1- beg) end)
+                  (evil-range beg (max beg (1- end))))))
+  :string (lambda (beg end)
+            (let ((height (count-lines
+                           beg
+                           (progn
+                             (goto-char end)
+                             (if (and (bolp) (not (eobp)))
+                                 (1+ end)
+                               end))))
+                  (width (abs (- (evil-column beg)
+                                 (evil-column end)))))
+              (format "%s row%s and %s column%s"
+                      height
+                      (if (= height 1) "" "s")
+                      width
+                      (if (= width 1) "" "s"))))
+  :rotate (lambda (beg end &rest properties)
+            "Rotate block according to :corner property.
+:corner can be one of `upper-left',``upper-right', `lower-left'
+and `lower-right'."
+            (let ((left  (evil-column beg))
+                  (right (evil-column end))
+                  (corner (or (plist-get properties :corner)
+                              'upper-left)))
+              (evil-sort left right)
+              (goto-char beg)
+              (if (memq corner '(upper-right lower-left))
+                  (move-to-column right)
+                (move-to-column left))
+              (setq beg (point))
+              (goto-char end)
+              (if (memq corner '(upper-right lower-left))
+                  (move-to-column left)
+                (move-to-column right))
+              (setq end (point))
+              (setq properties (plist-put properties
+                                          :corner corner))
+              (apply #'evil-range beg end properties))))
+
+(evil-define-type rectangle
+  "Like `exclusive', but for rectangles:
+the last column is excluded."
+  :expand (lambda (beg end)
+            ;; select at least one column
+            (if (= (evil-column beg) (evil-column end))
+                (evil-expand beg end 'block)
+              (evil-range beg end 'block))))
+
+;;; Standard interactive codes
+
+(evil-define-interactive-code "*"
+  "Signal error if the buffer is read-only."
+  (when buffer-read-only
+    (signal 'buffer-read-only nil)))
+
+(evil-define-interactive-code "b" (prompt)
+  "Name of existing buffer."
+  (list (read-buffer prompt (current-buffer) t)))
+
+(evil-define-interactive-code "c"
+  "Read character."
+  (list (read-char)))
+
+(evil-define-interactive-code "p"
+  "Prefix argument converted to number."
+  (list (prefix-numeric-value current-prefix-arg)))
+
+(evil-define-interactive-code "P"
+  "Prefix argument in raw form."
+  (list current-prefix-arg))
+
+;;; Custom interactive codes
+
+(evil-define-interactive-code "<c>"
+  "Count."
+  (list (when current-prefix-arg
+          (prefix-numeric-value
+           current-prefix-arg))))
+
+(evil-define-interactive-code "<vc>"
+  "Count, but only in visual state.
+This should be used by an operator taking a count. In normal
+state the count should not be handled by the operator but by the
+motion that defines the operator's range. In visual state the
+range is specified by the visual region and the count is not used
+at all. Thus in the case the operator may use the count
+directly."
+  (list (when (and (evil-visual-state-p) current-prefix-arg)
+          (prefix-numeric-value
+           current-prefix-arg))))
+
+(evil-define-interactive-code "<C>"
+  "Character read through `evil-read-key'."
+  (list
+   (if (evil-operator-state-p)
+       (evil-without-restriction (evil-read-key))
+     (evil-read-key))))
+
+(evil-define-interactive-code "<r>"
+  "Untyped motion range (BEG END)."
+  (evil-operator-range))
+
+(evil-define-interactive-code "<R>"
+  "Typed motion range (BEG END TYPE)."
+  (evil-operator-range t))
+
+(evil-define-interactive-code "<v>"
+  "Typed motion range of visual range(BEG END TYPE).
+If visual state is inactive then those values are nil."
+  (if (evil-visual-state-p)
+      (let ((range (evil-visual-range)))
+        (list (car range)
+              (cadr range)
+              (evil-type range)))
+    (list nil nil nil)))
+
+(evil-define-interactive-code "<x>"
+  "Current register."
+  (list evil-this-register))
+
+(evil-define-interactive-code "<y>"
+  "Current yank-handler."
+  (list (evil-yank-handler)))
+
+(evil-define-interactive-code "<a>"
+  "Ex argument."
+  :ex-arg t
+  (list (when (evil-ex-p) evil-ex-argument)))
+
+(evil-define-interactive-code "<f>"
+  "Ex file argument."
+  :ex-arg file
+  (list (when (evil-ex-p) (evil-ex-file-arg))))
+
+(evil-define-interactive-code "<b>"
+  "Ex buffer argument."
+  :ex-arg buffer
+  (list (when (evil-ex-p) evil-ex-argument)))
+
+(evil-define-interactive-code "<sh>"
+  "Ex shell command argument."
+  :ex-arg shell
+  (list (when (evil-ex-p) evil-ex-argument)))
+
+(evil-define-interactive-code "<fsh>"
+  "Ex file or shell command argument."
+  :ex-arg file-or-shell
+  (list (when (evil-ex-p) evil-ex-argument)))
+
+(evil-define-interactive-code "<sym>"
+  "Ex symbolic argument."
+  :ex-arg sym
+  (list (when (and (evil-ex-p) evil-ex-argument)
+          (intern evil-ex-argument))))
+
+(evil-define-interactive-code "<addr>"
+  "Ex line number."
+  (list
+   (and (evil-ex-p)
+        (let ((expr (evil-ex-parse  evil-ex-argument)))
+          (if (eq (car expr) 'evil-goto-line)
+              (save-excursion
+                (goto-char evil-ex-point)
+                (eval (cadr expr)))
+            (user-error "Invalid address"))))))
+
+(evil-define-interactive-code "<!>"
+  "Ex bang argument."
+  :ex-bang t
+  (list (when (evil-ex-p) evil-ex-bang)))
+
+(evil-define-interactive-code "</>"
+  "Ex delimited argument."
+  (when (evil-ex-p)
+    (evil-delimited-arguments evil-ex-argument)))
+
+(evil-define-interactive-code "<g/>"
+  "Ex global argument."
+  (when (evil-ex-p)
+    (evil-ex-parse-global evil-ex-argument)))
+
+(evil-define-interactive-code "<s/>"
+  "Ex substitution argument."
+  :ex-arg substitution
+  (when (evil-ex-p)
+    (evil-ex-get-substitute-info evil-ex-argument t)))
+
+(evil-define-interactive-code "<xc/>"
+  "Ex register and count argument, both optional.
+Can be used for commands such as :delete [REGISTER] [COUNT] where the
+command can be called with either zero, one or two arguments. When the
+argument is one, if it's numeric it's treated as a COUNT, otherwise -
+REGISTER"
+  (when (evil-ex-p)
+    (evil-ex-get-optional-register-and-count evil-ex-argument)))
+
+(defun evil-ex-get-optional-register-and-count (string)
+  "Parse STRING as an ex arg with both optional REGISTER and COUNT.
+Returns a list (REGISTER COUNT)."
+  (let* ((split-args (split-string (or string "")))
+         (arg-count (length split-args))
+         (arg0 (car split-args))
+         (arg1 (cadr split-args))
+         (number-regex "^-?[1-9][0-9]*$")
+         (register nil)
+         (count nil))
+    (cond
+     ;; :command REGISTER or :command COUNT
+     ((= arg-count 1)
+      (if (string-match-p number-regex arg0)
+          (setq count arg0)
+        (setq register arg0)))
+     ;; :command REGISTER COUNT
+     ((eq arg-count 2)
+      (setq register arg0
+            count arg1))
+     ;; more than 2 args aren't allowed
+     ((> arg-count 2)
+      (user-error "Invalid use")))
+
+    ;; if register is given, check it's valid
+    (when register
+      (unless (= (length register) 1)
+        (user-error "Invalid register"))
+      (setq register (string-to-char register)))
+
+    ;; if count is given, check it's valid
+    (when count
+      (unless (string-match-p number-regex count)
+        (user-error "Invalid count"))
+      (setq count (string-to-number count))
+      (unless (> count 0)
+        (user-error "Invalid count")))
+
+    (list register count)))
+
+(provide 'evil-types)
+
+;;; evil-types.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-types.elc b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-types.elc
new file mode 100644
index 0000000000..7d16df54e3
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-types.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-vars.el b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-vars.el
new file mode 100644
index 0000000000..33cb44b8e6
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-vars.el
@@ -0,0 +1,1879 @@
+;;; evil-vars.el --- Settings and variables
+
+;; Author: Vegard Øye <vegard_oye at hotmail.com>
+;; Maintainer: Vegard Øye <vegard_oye at hotmail.com>
+
+;; Version: 1.2.13
+
+;;
+;; This file is NOT part of GNU Emacs.
+
+;;; License:
+
+;; This file is part of Evil.
+;;
+;; Evil 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.
+;;
+;; Evil 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 Evil.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Code:
+
+(declare-function evil-add-command-properties "evil-common"
+                  (command &rest properties))
+(declare-function evil-update-insert-state-bindings "evil-maps"
+                  (&optional _option-name remove force))
+
+;;; Hooks
+
+(defvar evil-after-load-hook nil
+  "Functions to be run when loading of evil is finished.
+This hook can be used the execute some initialization routines
+when evil is completely loaded.")
+
+;;; Initialization
+
+(defvar evil-pending-custom-initialize nil
+  "A list of pending initializations for custom variables.
+Each element is a triple (FUNC VAR VALUE). When evil is
+completely loaded then the functions (funcall FUNC VAR VALUE) is
+called for each element. FUNC should be a function suitable for
+the :initialize property of `defcustom'.")
+
+(defun evil-custom-initialize-pending-reset (var value)
+  "Add a pending customization with `custom-initialize-reset'."
+  (push (list 'custom-initialize-reset var value)
+        evil-pending-custom-initialize))
+
+(defun evil-run-pending-custom-initialize ()
+  "Executes the pending initializations.
+See `evil-pending-custom-initialize'."
+  (dolist (init evil-pending-custom-initialize)
+    (apply (car init) (cdr init)))
+  (remove-hook 'evil-after-load-hook 'evil-run-pending-custom-initialize))
+(add-hook 'evil-after-load-hook 'evil-run-pending-custom-initialize)
+
+;;; Setters
+
+(defun evil-set-toggle-key (key)
+  "Set `evil-toggle-key' to KEY.
+KEY must be readable by `read-kbd-macro'."
+  (let ((old-key (read-kbd-macro
+                  (if (boundp 'evil-toggle-key)
+                      evil-toggle-key
+                    "C-z")))
+        (key (read-kbd-macro key)))
+    (with-no-warnings
+      (dolist (pair '((evil-motion-state-map evil-emacs-state)
+                      (evil-insert-state-map evil-emacs-state)
+                      (evil-emacs-state-map evil-exit-emacs-state)))
+        (when (boundp (car pair))
+          (let ((map (symbol-value (car pair)))
+                (fun (cadr pair)))
+            (when (keymapp map)
+              (define-key map key fun)
+              (define-key map old-key nil))))))))
+
+(defun evil-set-custom-state-maps (var pending-var key make newlist)
+  "Changes the list of special keymaps.
+VAR         is the variable containing the list of keymaps.
+PENDING-VAR is the variable containing the list of the currently pending
+            keymaps.
+KEY         the special symbol to be stored in the keymaps.
+MAKE        the creation function of the special keymaps.
+NEWLIST     the list of new special keymaps."
+  (set-default pending-var newlist)
+  (when (default-boundp var)
+    (dolist (map (default-value var))
+      (when (and (boundp (car map))
+                 (keymapp (default-value (car map))))
+        (define-key (default-value (car map)) (vector key) nil))))
+  (set-default var newlist)
+  (evil-update-pending-maps))
+
+(defun evil-update-pending-maps (&optional file)
+  "Tries to set pending special keymaps.
+This function should be called from an `after-load-functions'
+hook."
+  (let ((maps '((evil-make-overriding-map . evil-pending-overriding-maps)
+                (evil-make-intercept-map . evil-pending-intercept-maps))))
+    (while maps
+      (let* ((map (pop maps))
+             (make (car map))
+             (pending-var (cdr map))
+             (pending (symbol-value pending-var))
+             newlist)
+        (while pending
+          (let* ((map (pop pending))
+                 (kmap (and (boundp (car map))
+                            (keymapp (symbol-value (car map)))
+                            (symbol-value (car map))))
+                 (state (cdr map)))
+            (if kmap
+                (funcall make kmap state)
+              (push map newlist))))
+        (set-default pending-var newlist)))))
+
+(defun evil-set-visual-newline-commands (var value)
+  "Set the value of `evil-visual-newline-commands'.
+Setting this variable changes the properties of the appropriate
+commands."
+  (with-no-warnings
+    (when (default-boundp var)
+      (dolist (cmd (default-value var))
+        (evil-set-command-property cmd :exclude-newline nil)))
+    (set-default var value)
+    (dolist (cmd (default-value var))
+      (evil-set-command-property cmd :exclude-newline t))))
+
+(defun evil-set-custom-motions (var values)
+  "Sets the list of motion commands."
+  (with-no-warnings
+    (when (default-boundp var)
+      (dolist (motion (default-value var))
+        (evil-add-command-properties motion :keep-visual nil :repeat nil)))
+    (set-default var values)
+    (mapc #'evil-declare-motion (default-value var))))
+
+;;; Customization group
+
+(defgroup evil nil
+  "Extensible vi layer."
+  :group 'emulations
+  :prefix 'evil-)
+
+(defcustom evil-auto-indent t
+  "Whether to auto-indent when opening lines."
+  :type  'boolean
+  :group 'evil)
+(make-variable-buffer-local 'evil-auto-indent)
+
+(defcustom evil-shift-width 4
+  "The offset used by \\<evil-normal-state-map>\\[evil-shift-right] \
+and \\[evil-shift-left]."
+  :type 'integer
+  :group 'evil)
+(make-variable-buffer-local 'evil-shift-width)
+
+(defcustom evil-shift-round t
+  "Whether \\<evil-normal-state-map>\\[evil-shift-right] \
+and \\[evil-shift-left] round to the nearest multiple \
+of `evil-shift-width'."
+  :type 'boolean
+  :group 'evil)
+(make-variable-buffer-local 'evil-shift-round)
+
+(defcustom evil-indent-convert-tabs t
+  "If non-nil `evil-indent' converts between leading tabs and spaces.
+  Whether tabs are converted to spaces or vice versa depends on the
+  value of `indent-tabs-mode'."
+  :type 'boolean
+  :group 'evil)
+
+(defcustom evil-default-cursor t
+  "The default cursor.
+May be a cursor type as per `cursor-type', a color string as passed
+to `set-cursor-color', a zero-argument function for changing the
+cursor, or a list of the above."
+  :type '(set symbol (cons symbol symbol) string function)
+  :group 'evil)
+
+(defvar evil-force-cursor nil
+  "Overwrite the current states default cursor.")
+
+(defcustom evil-repeat-move-cursor t
+  "Whether \"\\<evil-normal-state-map>\\[evil-repeat]\" \
+moves the cursor."
+  :type 'boolean
+  :group 'evil)
+
+(defcustom evil-cross-lines nil
+  "Whether motions may cross newlines."
+  :type 'boolean
+  :group 'evil)
+
+(defcustom evil-backspace-join-lines t
+  "Whether backward delete in insert state may join lines."
+  :type 'boolean
+  :group 'evil)
+
+(defcustom evil-move-cursor-back t
+  "Whether the cursor is moved backwards when exiting Insert state."
+  :type 'boolean
+  :group 'evil)
+
+(defcustom evil-move-beyond-eol nil
+  "Whether the cursor is allowed to move past the last character of \
+a line."
+  :type 'boolean
+  :group 'evil)
+
+(defcustom evil-respect-visual-line-mode nil
+  "Whether to remap movement commands when `visual-line-mode' is active.
+This variable must be set before evil is loaded. The commands
+swapped are
+
+`evil-next-line'         <-> `evil-next-visual-line'
+`evil-previous-line'     <-> `evil-previous-visual-line'
+`evil-beginning-of-line' <-> `evil-beginning-of-visual-line'
+`evil-end-of-line'       <-> `evil-end-of-visual-line'"
+  :type 'boolean
+  :group 'evil)
+
+(defcustom evil-repeat-find-to-skip-next t
+  "Whether a repeat of t or T should skip an adjacent character."
+  :type 'boolean
+  :group 'evil)
+
+(defcustom evil-kbd-macro-suppress-motion-error nil
+  "Whether left/right motions signal errors during keyboard-macro definition.
+If this variable is set to non-nil, then the function
+`evil-forward-char' and `evil-backward-char' do not signal
+`end-of-line' or `beginning-of-line' errors when a keyboard macro
+is being defined and/or it is being executed. This may be desired
+because such an error would cause the macro definition/execution
+being terminated."
+  :type '(radio (const :tag "No" :value nil)
+                (const :tag "Record" :value record)
+                (const :tag "Replay" :value replay)
+                (const :tag "Both" :value t))
+  :group 'evil)
+
+(defcustom evil-track-eol t
+  "If non-nil line moves after a call to `evil-end-of-line' stay at eol.
+This is analogous to `track-eol' but deals with the end-of-line
+interpretation of evil."
+  :type 'boolean
+  :group 'evil)
+
+(defcustom evil-mode-line-format 'before
+  "The position of the mode line tag.
+Either a symbol or a cons-cell. If it is a symbol it should be
+one of 'before, 'after or 'nil. 'before means the tag is
+placed before the mode-list, 'after means it is placed after the
+mode-list, and 'nil means no mode line tag. If it is a cons cell
+it should have the form (WHERE . WHICH) where WHERE is either
+'before or 'after and WHICH is a symbol in
+`mode-line-format'. The tag is then placed right before or after
+that symbol."
+  :type '(radio :value 'before
+                (const before)
+                (const after)
+                (cons :tag "Next to symbol"
+                      (choice :value after
+                              (const before)
+                              (const after))
+                      symbol))
+  :group 'evil)
+
+(defcustom evil-mouse-word 'evil-word
+  "The thing-at-point symbol for double click selection.
+The double-click starts visual state in a special word selection
+mode. This symbol is used to determine the words to be
+selected. Possible values are 'evil-word or
+'evil-WORD."
+  :type 'symbol
+  :group 'evil)
+
+(defcustom evil-bigword "^ \t\r\n"
+  "The characters to be considered as a big word.
+This should be a regexp set without the enclosing []."
+  :type 'string
+  :group 'evil)
+(make-variable-buffer-local 'evil-bigword)
+
+(defcustom evil-want-fine-undo nil
+  "Whether actions like \"cw\" are undone in several steps.
+There are three possible choices. \"No\" means all changes made
+during insert state including a possible delete after a change
+operation are collected in a single undo step. If \"Yes\" is
+selected, undo steps are determined according to Emacs heuristics
+and no attempt is made to further aggregate changes.
+
+As of 1.2.13, the option \"fine\" is ignored and means the same
+thing as \"No\". It used to be the case that fine would only try
+to merge the first two changes in an insert operation. For
+example, merging the delete and first insert operation after
+\"cw\", but this option was removed because it did not work
+consistently."
+  :type '(radio (const :tag "No" :value nil)
+                (const :tag "Fine (obsolete)" :value fine)
+                (const :tag "Yes" :value t))
+  :group 'evil)
+
+(defcustom evil-regexp-search t
+  "Whether to use regular expressions for searching."
+  :type  'boolean
+  :group 'evil)
+
+(defcustom evil-search-wrap t
+  "Whether search wraps around."
+  :type  'boolean
+  :group 'evil)
+
+(defcustom evil-flash-delay 2
+  "Time in seconds to flash search matches."
+  :type  'number
+  :group 'evil)
+
+(defcustom evil-fold-level 0
+  "Default fold level."
+  :type  'integer
+  :group 'evil)
+
+(defcustom evil-auto-balance-windows t
+  "If non-nil creating/deleting a window causes a rebalance."
+  :type 'boolean
+  :group 'evil)
+
+(defcustom evil-split-window-below nil
+  "If non-nil split windows are created below."
+  :type 'boolean
+  :group 'evil)
+
+(defcustom evil-vsplit-window-right nil
+  "If non-nil vsplit windows are created to the right."
+  :type 'boolean
+  :group 'evil)
+
+(defcustom evil-esc-delay 0.01
+  "Time in seconds to wait for another key after ESC."
+  :type 'number
+  :group 'evil)
+
+(defvar evil-esc-mode nil
+  "Non-nil if `evil-esc-mode' is enabled.")
+
+(defvar evil-esc-map nil
+  "Original ESC prefix map in `input-decode-map'.
+Used by `evil-esc-mode'.")
+
+(defvar evil-inhibit-esc nil
+  "If non-nil, the \\e event will never be translated to 'escape.")
+
+(defcustom evil-intercept-esc 'always
+  "Whether evil should intercept the ESC key.
+In terminal, a plain ESC key and a meta-key-sequence both
+generate the same event. In order to distinguish both evil
+modifies `input-decode-map'. This is necessary in terminal but
+not in X mode. However, the terminal ESC is equivalent to C-[, so
+if you want to use C-[ instead of ESC in X, then Evil must
+intercept the ESC event in X, too. This variable determines when
+Evil should intercept the event."
+  :type '(radio (const :tag "Never" :value nil)
+                (const :tag "In terminal only" :value t)
+                (const :tag "Always" :value always))
+  :group 'evil)
+
+(defcustom evil-show-paren-range 0
+  "The minimal distance between point and a parenthesis
+which causes the parenthesis to be highlighted."
+  :type 'integer
+  :group 'evil)
+
+(defcustom evil-ex-hl-update-delay 0.02
+  "Time in seconds of idle before updating search highlighting.
+Setting this to a period shorter than that of keyboard's repeat
+rate allows highlights to update while scrolling."
+  :type 'number
+  :group 'evil)
+
+(defcustom evil-highlight-closing-paren-at-point-states
+  '(not emacs insert replace)
+  "The states in which the closing parenthesis at point should be highlighted.
+All states listed here highlight the closing parenthesis at
+point (which is Vim default behavior), all others highlight the
+parenthesis before point (which is Emacs default behavior). If
+this list contains the symbol 'not then its meaning is inverted,
+i.e., all states listed here highlight the closing parenthesis
+before point."
+  :type '(repeat symbol)
+  :group 'evil)
+
+(defcustom evil-kill-on-visual-paste t
+  "Whether `evil-visual-paste' adds the replaced text to the kill
+ring, making it the default for the next paste. The default, t,
+replicates the default vim behavior."
+  :type 'boolean
+  :group 'evil)
+
+(defcustom evil-want-C-i-jump t
+  "Whether \"C-i\" jumps forward like in Vim."
+  :type 'boolean
+  :group 'evil
+  :set #'(lambda (sym value)
+           (set-default sym value)
+           (when (boundp 'evil-motion-state-map)
+             (cond
+              ((and (not value)
+                    (eq (lookup-key evil-motion-state-map (kbd "C-i"))
+                        'evil-jump-forward))
+               (define-key evil-motion-state-map (kbd "C-i") nil))
+              ((and value
+                    (not (lookup-key evil-motion-state-map (kbd "C-i"))))
+               (define-key evil-motion-state-map (kbd "C-i") 'evil-jump-forward))))))
+
+(defcustom evil-want-C-u-scroll nil
+  "Whether \"C-u\" scrolls like in Vim."
+  :type 'boolean
+  :group 'evil
+  :set #'(lambda (sym value)
+           (set-default sym value)
+           (when (boundp 'evil-motion-state-map)
+             (cond
+              ((and (not value)
+                    (eq (lookup-key evil-motion-state-map (kbd "C-u"))
+                        'evil-scroll-up))
+               (define-key evil-motion-state-map (kbd "C-u") nil))
+              ((and value
+                    (not (lookup-key evil-motion-state-map (kbd "C-u"))))
+               (define-key evil-motion-state-map (kbd "C-u") 'evil-scroll-up))))))
+
+(defcustom evil-want-C-d-scroll t
+  "Whether \"C-d\" scrolls like in Vim."
+  :type 'boolean
+  :group 'evil
+  :set #'(lambda (sym value)
+           (set-default sym value)
+           (when (boundp 'evil-motion-state-map)
+             (cond
+              ((and (not value)
+                    (eq (lookup-key evil-motion-state-map (kbd "C-d"))
+                        'evil-scroll-down))
+               (define-key evil-motion-state-map (kbd "C-d") nil))
+              ((and value
+                    (not (lookup-key evil-motion-state-map (kbd "C-d"))))
+               (define-key evil-motion-state-map (kbd "C-d") 'evil-scroll-down))))))
+
+(defcustom evil-want-C-w-delete t
+  "Whether \"C-w\" deletes a word in Insert state."
+  :type 'boolean
+  :group 'evil
+  :set #'(lambda (sym value)
+           (set-default sym value)
+           (when (boundp 'evil-insert-state-map)
+             (cond
+              ((and (not value)
+                    (eq (lookup-key evil-insert-state-map (kbd "C-w"))
+                        'evil-delete-backward-word))
+               (define-key evil-insert-state-map (kbd "C-w") 'evil-window-map))
+              ((and value
+                    (eq (lookup-key evil-insert-state-map (kbd "C-w"))
+                        'evil-window-map))
+               (define-key evil-insert-state-map (kbd "C-w") 'evil-delete-backward-word))))))
+
+(defcustom evil-want-C-w-in-emacs-state nil
+  "Whether \"C-w\" prefixes windows commands in Emacs state."
+  :type 'boolean
+  :group 'evil
+  :set #'(lambda (sym value)
+           (set-default sym value)
+           (when (boundp 'evil-emacs-state-map)
+             (cond
+              ((and (not value)
+                    (eq (lookup-key evil-emacs-state-map (kbd "C-w"))
+                        'evil-window-map))
+               (define-key evil-emacs-state-map (kbd "C-w") nil))
+              ((and value
+                    (not (lookup-key evil-emacs-state-map (kbd "C-w"))))
+               (define-key evil-emacs-state-map (kbd "C-w") 'evil-window-map))))))
+
+(defcustom evil-want-change-word-to-end t
+  "Whether \"cw\" behaves like \"ce\"."
+  :type 'boolean
+  :group 'evil)
+
+(defcustom evil-want-Y-yank-to-eol nil
+  "Whether \"Y\" yanks to the end of the line.
+The default behavior is to yank the whole line."
+  :group 'evil
+  :type 'boolean
+  :initialize #'evil-custom-initialize-pending-reset
+  :set #'(lambda (sym value)
+           (evil-add-command-properties
+            'evil-yank-line
+            :motion (if value 'evil-end-of-line 'evil-line))))
+
+(defcustom evil-disable-insert-state-bindings nil
+  "Whether insert state bindings should be used. Excludes
+bindings for escape, delete and `evil-toggle-key'."
+  :group 'evil
+  :type 'boolean
+  :initialize #'evil-custom-initialize-pending-reset
+  :set #'evil-update-insert-state-bindings)
+
+(defcustom evil-echo-state t
+  "Whether to signal the current state in the echo area."
+  :type 'boolean
+  :group 'evil)
+
+(defcustom evil-complete-all-buffers t
+  "Whether completion looks for matches in all buffers."
+  :type 'boolean
+  :group 'evil)
+
+(defcustom evil-complete-next-func
+  #'(lambda (arg)
+      (require 'dabbrev)
+      (let ((dabbrev-search-these-buffers-only
+             (unless evil-complete-all-buffers
+               (list (current-buffer))))
+            dabbrev-case-distinction)
+        (condition-case nil
+            (if (eq last-command this-command)
+                (dabbrev-expand nil)
+              (dabbrev-expand (- (abs (or arg 1)))))
+          (error (dabbrev-expand nil)))))
+  "Completion function used by \
+\\<evil-insert-state-map>\\[evil-complete-next]."
+  :type 'function
+  :group 'evil)
+
+(defcustom evil-complete-previous-func
+  #'(lambda (arg)
+      (require 'dabbrev)
+      (let ((dabbrev-search-these-buffers-only
+             (unless evil-complete-all-buffers
+               (list (current-buffer))))
+            dabbrev-case-distinction)
+        (dabbrev-expand arg)))
+  "Completion function used by \
+\\<evil-insert-state-map>\\[evil-complete-previous]."
+  :type 'function
+  :group 'evil)
+
+(defcustom evil-complete-next-minibuffer-func 'minibuffer-complete
+  "Minibuffer completion function used by \
+\\<evil-insert-state-map>\\[evil-complete-next]."
+  :type 'function
+  :group 'evil)
+
+(defcustom evil-complete-previous-minibuffer-func 'minibuffer-complete
+  "Minibuffer completion function used by \
+\\<evil-insert-state-map>\\[evil-complete-previous]."
+  :type 'function
+  :group 'evil)
+
+(defcustom evil-complete-next-line-func
+  #'(lambda (arg)
+      (let ((hippie-expand-try-functions-list
+             '(try-expand-line
+               try-expand-line-all-buffers)))
+        (hippie-expand arg)))
+  "Minibuffer completion function used by \
+\\<evil-insert-state-map>\\[evil-complete-next-line]."
+  :type 'function
+  :group 'evil)
+
+(defcustom evil-complete-previous-line-func
+  evil-complete-next-line-func
+  "Minibuffer completion function used by \
+\\<evil-insert-state-map>\\[evil-complete-previous-line]."
+  :type 'function
+  :group 'evil)
+
+(defcustom evil-lookup-func #'woman
+  "Lookup function used by \
+\"\\<evil-motion-state-map>\\[evil-lookup]\"."
+  :type 'function
+  :group 'evil)
+
+(defcustom evil-toggle-key "C-z"
+  "The key used to change to and from Emacs state.
+Must be readable by `read-kbd-macro'. For example: \"C-z\"."
+  :type 'string
+  :group 'evil
+  :set #'(lambda (sym value)
+           (evil-set-toggle-key value)
+           (set-default sym value)))
+
+(defcustom evil-default-state 'normal
+  "The default state.
+This is the state a mode comes up in when it is not listed
+in `evil-emacs-state-modes', `evil-insert-state-modes' or
+`evil-motion-state-modes'. The value may be one of `normal',
+`insert', `visual', `replace', `operator', `motion' and
+`emacs'."
+  :type  'symbol
+  :group 'evil)
+
+(defcustom evil-buffer-regexps
+  '(("^ \\*load\\*" . nil))
+  "Regular expression determining the initial state for a buffer.
+Entries have the form (REGEXP . STATE), where REGEXP is a regular
+expression matching the buffer's name and STATE is one of `normal',
+`insert', `visual', `replace', `operator', `motion', `emacs' and nil.
+If STATE is nil, Evil is disabled in the buffer."
+  :type '(alist :key-type string :value-type symbol)
+  :group 'evil)
+
+(defcustom evil-emacs-state-modes
+  '(5x5-mode
+    archive-mode
+    bbdb-mode
+    biblio-selection-mode
+    blackbox-mode
+    bookmark-bmenu-mode
+    bookmark-edit-annotation-mode
+    browse-kill-ring-mode
+    bubbles-mode
+    bzr-annotate-mode
+    calc-mode
+    cfw:calendar-mode
+    completion-list-mode
+    Custom-mode
+    custom-theme-choose-mode
+    debugger-mode
+    delicious-search-mode
+    desktop-menu-blist-mode
+    desktop-menu-mode
+    doc-view-mode
+    dun-mode
+    dvc-bookmarks-mode
+    dvc-diff-mode
+    dvc-info-buffer-mode
+    dvc-log-buffer-mode
+    dvc-revlist-mode
+    dvc-revlog-mode
+    dvc-status-mode
+    dvc-tips-mode
+    ediff-mode
+    ediff-meta-mode
+    efs-mode
+    Electric-buffer-menu-mode
+    emms-browser-mode
+    emms-mark-mode
+    emms-metaplaylist-mode
+    emms-playlist-mode
+    ess-help-mode
+    etags-select-mode
+    fj-mode
+    gc-issues-mode
+    gdb-breakpoints-mode
+    gdb-disassembly-mode
+    gdb-frames-mode
+    gdb-locals-mode
+    gdb-memory-mode
+    gdb-registers-mode
+    gdb-threads-mode
+    gist-list-mode
+    git-commit-mode
+    git-rebase-mode
+    gnus-article-mode
+    gnus-browse-mode
+    gnus-group-mode
+    gnus-server-mode
+    gnus-summary-mode
+    gomoku-mode
+    google-maps-static-mode
+    ibuffer-mode
+    jde-javadoc-checker-report-mode
+    magit-cherry-mode
+    magit-diff-mode
+    magit-log-mode
+    magit-log-select-mode
+    magit-popup-mode
+    magit-popup-sequence-mode
+    magit-process-mode
+    magit-reflog-mode
+    magit-refs-mode
+    magit-revision-mode
+    magit-stash-mode
+    magit-stashes-mode
+    magit-status-mode
+    ;; Obsolete as of Magit v2.1.0
+    magit-mode
+    magit-branch-manager-mode
+    magit-commit-mode
+    magit-key-mode
+    magit-rebase-mode
+    magit-wazzup-mode
+    ;; end obsolete
+    mh-folder-mode
+    monky-mode
+    mpuz-mode
+    mu4e-main-mode
+    mu4e-headers-mode
+    mu4e-view-mode
+    notmuch-hello-mode
+    notmuch-search-mode
+    notmuch-show-mode
+    notmuch-tree-mode
+    occur-mode
+    org-agenda-mode
+    package-menu-mode
+    pdf-outline-buffer-mode
+    pdf-view-mode
+    proced-mode
+    rcirc-mode
+    rebase-mode
+    recentf-dialog-mode
+    reftex-select-bib-mode
+    reftex-select-label-mode
+    reftex-toc-mode
+    sldb-mode
+    slime-inspector-mode
+    slime-thread-control-mode
+    slime-xref-mode
+    snake-mode
+    solitaire-mode
+    sr-buttons-mode
+    sr-mode
+    sr-tree-mode
+    sr-virtual-mode
+    tar-mode
+    tetris-mode
+    tla-annotate-mode
+    tla-archive-list-mode
+    tla-bconfig-mode
+    tla-bookmarks-mode
+    tla-branch-list-mode
+    tla-browse-mode
+    tla-category-list-mode
+    tla-changelog-mode
+    tla-follow-symlinks-mode
+    tla-inventory-file-mode
+    tla-inventory-mode
+    tla-lint-mode
+    tla-logs-mode
+    tla-revision-list-mode
+    tla-revlog-mode
+    tla-tree-lint-mode
+    tla-version-list-mode
+    twittering-mode
+    urlview-mode
+    vc-annotate-mode
+    vc-dir-mode
+    vc-git-log-view-mode
+    vc-hg-log-view-mode
+    vc-svn-log-view-mode
+    vm-mode
+    vm-summary-mode
+    w3m-mode
+    wab-compilation-mode
+    xgit-annotate-mode
+    xgit-changelog-mode
+    xgit-diff-mode
+    xgit-revlog-mode
+    xhg-annotate-mode
+    xhg-log-mode
+    xhg-mode
+    xhg-mq-mode
+    xhg-mq-sub-mode
+    xhg-status-extra-mode)
+  "Modes that should come up in Emacs state."
+  :type  '(repeat symbol)
+  :group 'evil)
+
+(defcustom evil-insert-state-modes
+  '(comint-mode
+    erc-mode
+    eshell-mode
+    geiser-repl-mode
+    gud-mode
+    inferior-apl-mode
+    inferior-caml-mode
+    inferior-emacs-lisp-mode
+    inferior-j-mode
+    inferior-python-mode
+    inferior-scheme-mode
+    inferior-sml-mode
+    internal-ange-ftp-mode
+    prolog-inferior-mode
+    reb-mode
+    shell-mode
+    slime-repl-mode
+    term-mode
+    wdired-mode)
+  "Modes that should come up in Insert state."
+  :type  '(repeat symbol)
+  :group 'evil)
+
+(defcustom evil-motion-state-modes
+  '(apropos-mode
+    Buffer-menu-mode
+    calendar-mode
+    color-theme-mode
+    command-history-mode
+    compilation-mode
+    dictionary-mode
+    ert-results-mode
+    help-mode
+    Info-mode
+    Man-mode
+    speedbar-mode
+    undo-tree-visualizer-mode
+    woman-mode)
+  "Modes that should come up in Motion state."
+  :type  '(repeat symbol)
+  :group 'evil)
+
+(defvar evil-pending-overriding-maps nil
+  "An alist of pending overriding maps.")
+
+(defvar evil-pending-intercept-maps nil
+  "An alist of pending intercept maps.")
+
+(defcustom evil-overriding-maps
+  '((Buffer-menu-mode-map . nil)
+    (color-theme-mode-map . nil)
+    (comint-mode-map . nil)
+    (compilation-mode-map . nil)
+    (grep-mode-map . nil)
+    (dictionary-mode-map . nil)
+    (ert-results-mode-map . motion)
+    (Info-mode-map . motion)
+    (speedbar-key-map . nil)
+    (speedbar-file-key-map . nil)
+    (speedbar-buffers-key-map . nil))
+  "Keymaps that should override Evil maps.
+Entries have the form (MAP-VAR . STATE), where MAP-VAR is
+a keymap variable and STATE is the state whose bindings
+should be overridden. If STATE is nil, all states are
+overridden."
+  :type '(alist :key-type symbol :value-type symbol)
+  :group 'evil
+  :set #'(lambda (var values)
+           (evil-set-custom-state-maps 'evil-overriding-maps
+                                       'evil-pending-overriding-maps
+                                       'override-state
+                                       'evil-make-overriding-map
+                                       values))
+  :initialize 'evil-custom-initialize-pending-reset)
+
+(add-hook 'after-load-functions #'evil-update-pending-maps)
+
+(defcustom evil-intercept-maps
+  '((edebug-mode-map . nil))
+  "Keymaps that should intercept Evil maps.
+Entries have the form (MAP-VAR . STATE), where MAP-VAR is
+a keymap variable and STATE is the state whose bindings
+should be intercepted. If STATE is nil, all states are
+intercepted."
+  :type '(alist :key-type symbol :value-type symbol)
+  :group 'evil
+  :set #'(lambda (var values)
+           (evil-set-custom-state-maps 'evil-intercept-maps
+                                       'evil-pending-intercept-maps
+                                       'intercept-state
+                                       'evil-make-intercept-map
+                                       values))
+  :initialize 'evil-custom-initialize-pending-reset)
+
+(defcustom evil-motions
+  '(back-to-indentation
+    backward-char
+    backward-list
+    backward-paragraph
+    backward-sentence
+    backward-sexp
+    backward-up-list
+    backward-word
+    beginning-of-buffer
+    beginning-of-defun
+    beginning-of-line
+    beginning-of-visual-line
+    c-beginning-of-defun
+    c-end-of-defun
+    diff-file-next
+    diff-file-prev
+    diff-hunk-next
+    diff-hunk-prev
+    down-list
+    end-of-buffer
+    end-of-defun
+    end-of-line
+    end-of-visual-line
+    exchange-point-and-mark
+    forward-char
+    forward-list
+    forward-paragraph
+    forward-sentence
+    forward-sexp
+    forward-word
+    goto-last-change
+    ibuffer-backward-line
+    ibuffer-forward-line
+    isearch-abort
+    isearch-cancel
+    isearch-complete
+    isearch-del-char
+    isearch-delete-char
+    isearch-edit-string
+    isearch-exit
+    isearch-highlight-regexp
+    isearch-occur
+    isearch-other-control-char
+    isearch-other-meta-char
+    isearch-printing-char
+    isearch-query-replace
+    isearch-query-replace-regexp
+    isearch-quote-char
+    isearch-repeat-backward
+    isearch-repeat-forward
+    isearch-ring-advance
+    isearch-ring-retreat
+    isearch-toggle-case-fold
+    isearch-toggle-input-method
+    isearch-toggle-regexp
+    isearch-toggle-specified-input-method
+    isearch-toggle-word
+    isearch-yank-char
+    isearch-yank-kill
+    isearch-yank-line
+    isearch-yank-word-or-char
+    keyboard-quit
+    left-char
+    left-word
+    mouse-drag-region
+    mouse-save-then-kill
+    mouse-set-point
+    mouse-set-region
+    mwheel-scroll
+    move-beginning-of-line
+    move-end-of-line
+    next-error
+    next-line
+    paredit-backward
+    paredit-backward-down
+    paredit-backward-up
+    paredit-forward
+    paredit-forward-down
+    paredit-forward-up
+    pop-global-mark
+    pop-tag-mark
+    pop-to-mark-command
+    previous-error
+    previous-line
+    right-char
+    right-word
+    scroll-down
+    scroll-down-command
+    scroll-up
+    scroll-up-command
+    sgml-skip-tag-backward
+    sgml-skip-tag-forward
+    up-list)
+  "Non-Evil commands to initialize to motions."
+  :type  '(repeat symbol)
+  :group 'evil
+  :set 'evil-set-custom-motions
+  :initialize 'evil-custom-initialize-pending-reset)
+
+(defcustom evil-visual-newline-commands
+  '(LaTeX-section
+    TeX-font)
+  "Commands excluding the trailing newline of a Visual Line selection.
+These commands work better without this newline."
+  :type  '(repeat symbol)
+  :group 'evil
+  :set 'evil-set-visual-newline-commands
+  :initialize 'evil-custom-initialize-pending-reset)
+
+(defcustom evil-want-visual-char-semi-exclusive nil
+  "Visual character selection to beginning/end of line is exclusive.
+If non nil then an inclusive visual character selection which
+ends at the beginning or end of a line is turned into an
+exclusive selection. Thus if the selected (inclusive) range ends
+at the beginning of a line it is changed to not include the first
+character of that line, and if the selected range ends at the end
+of a line it is changed to not include the newline character of
+that line."
+  :type 'boolean
+  :group 'evil)
+
+(defcustom evil-text-object-change-visual-type t
+  "Text objects change the current visual state type.
+If non-nil then a text-object changes the type of the visual state to
+its default selection type (e.g. a word object always changes to
+charwise visual state). Otherwise the current visual state type is
+preserved."
+  :type 'boolean
+  :group 'evil)
+
+(defgroup evil-cjk nil
+  "CJK support"
+  :prefix "evil-cjk-"
+  :group 'evil)
+
+(defcustom evil-cjk-emacs-word-boundary nil
+  "Determine word boundary exactly the same way as Emacs does."
+  :type 'boolean
+  :group 'evil-cjk)
+
+(defcustom evil-cjk-word-separating-categories
+  '(;; Kanji
+    (?C . ?H) (?C . ?K) (?C . ?k) (?C . ?A) (?C . ?G)
+    ;; Hiragana
+    (?H . ?C) (?H . ?K) (?H . ?k) (?H . ?A) (?H . ?G)
+    ;; Katakana
+    (?K . ?C) (?K . ?H) (?K . ?k) (?K . ?A) (?K . ?G)
+    ;; half-width Katakana
+    (?k . ?C) (?k . ?H) (?k . ?K) ; (?k . ?A) (?k . ?G)
+    ;; full-width alphanumeric
+    (?A . ?C) (?A . ?H) (?A . ?K) ; (?A . ?k) (?A . ?G)
+    ;; full-width Greek
+    (?G . ?C) (?G . ?H) (?G . ?K) ; (?G . ?k) (?G . ?A)
+    )
+  "List of pair (cons) of categories to determine word boundary
+used in `evil-cjk-word-boundary-p'. See the documentation of
+`word-separating-categories'. Use `describe-categories' to see
+the list of categories."
+  :type '(alist :key-type (choice character (const nil))
+                :value-type (choice character (const nil)))
+  :group 'evil-cjk)
+
+(defcustom evil-cjk-word-combining-categories
+  '(;; default value in word-combining-categories
+    (nil . ?^) (?^ . nil)
+    ;; Roman
+    (?r . ?k) (?r . ?A) (?r . ?G)
+    ;; half-width Katakana
+    (?k . ?r) (?k . ?A) (?k . ?G)
+    ;; full-width alphanumeric
+    (?A . ?r) (?A . ?k) (?A . ?G)
+    ;; full-width Greek
+    (?G . ?r) (?G . ?k) (?G . ?A)
+    )
+  "List of pair (cons) of categories to determine word boundary
+used in `evil-cjk-word-boundary-p'. See the documentation of
+`word-combining-categories'. Use `describe-categories' to see the
+list of categories."
+  :type '(alist :key-type (choice character (const nil))
+                :value-type (choice character (const nil)))
+  :group 'evil-cjk)
+
+(defcustom evil-ex-complete-emacs-commands 'in-turn
+  "TAB-completion for Emacs commands in ex command line.
+This variable determines when Emacs commands are considered for
+completion, always, never, or only if no Evil ex command is
+available for completion."
+  :group 'evil
+  :type '(radio (const :tag "Only if no ex-command." :value in-turn)
+                (const :tag "Never" :value nil)
+                (const :tag "Always" :value t)))
+
+(defface evil-ex-commands '(( nil
+                              :underline t
+                              :slant italic))
+  "Face for the evil command in completion in ex mode."
+  :group 'evil)
+
+(defface evil-ex-info '(( ((supports :slant))
+                          :slant italic
+                          :foreground "red"))
+  "Face for the info message in ex mode."
+  :group 'evil)
+
+(defcustom evil-ex-visual-char-range nil
+  "Type of default ex range in visual char state.
+If non-nil the default range when starting an ex command from
+character visual state is `<,`> otherwise it is '<,'>. In the
+first case the ex command will be passed a region covering only
+the visual selection. In the second case the passed region will
+be extended to contain full lines."
+  :group 'evil
+  :type 'boolean)
+
+;; Searching
+(defcustom evil-symbol-word-search nil
+  "If nil then * and # search for words otherwise for symbols."
+  :group 'evil
+  :type 'boolean)
+(make-variable-buffer-local 'evil-symbol-word-search)
+
+(defcustom evil-magic t
+  "Meaning which characters in a pattern are magic.
+The meaning of those values is the same as in Vim. Note that it
+only has influence if the evil search module is chosen in
+`evil-search-module'."
+  :group 'evil
+  :type '(radio (const :tag "Very magic." :value very-magic)
+                (const :tag "Magic" :value t)
+                (const :tag "Nomagic" :value nil)
+                (const :tag "Very nomagic" :value very-nomagic)))
+
+(defcustom evil-ex-search-vim-style-regexp nil
+  "If non-nil Vim-style backslash codes are supported in search patterns.
+See `evil-transform-vim-style-regexp' for the supported backslash
+codes.  Note that this only affects the search command if
+`evil-search-module' is set to 'evil-search. The isearch module
+always uses plain Emacs regular expressions."
+  :type 'boolean
+  :group 'evil)
+
+(defcustom evil-ex-interactive-search-highlight 'all-windows
+  "Determine in which windows the interactive highlighting should be shown."
+  :type '(radio (const :tag "All windows." all-windows)
+                (const :tag "Selected window." selected-window)
+                (const :tag "Disable highlighting." nil))
+  :group 'evil)
+
+(defcustom evil-ex-search-persistent-highlight t
+  "If non-nil matches remain highlighted when the search ends."
+  :type 'boolean
+  :group 'evil)
+
+(defcustom evil-ex-search-case 'smart
+  "The case behaviour of the search command.
+Smart case means that the pattern is case sensitive if and only
+if it contains an upper case letter, otherwise it is case
+insensitive."
+  :type '(radio (const :tag "Case sensitive." sensitive)
+                (const :tag "Case insensitive." insensitive)
+                (const :tag "Smart case." smart))
+  :group 'evil)
+
+(defcustom evil-ex-substitute-case nil
+  "The case behaviour of the search command.
+Smart case means that the pattern is case sensitive if and only
+if it contains an upper case letter, otherwise it is case
+insensitive. If nil then the setting of `evil-ex-search-case' is
+used."
+  :type '(radio (const :tag "Same as interactive search." nil)
+                (const :tag "Case sensitive." sensitive)
+                (const :tag "Case insensitive." insensitive)
+                (const :tag "Smart case." smart))
+  :group 'evil)
+
+(defcustom evil-ex-search-interactive t
+  "If t search is interactive."
+  :type 'boolean
+  :group 'evil)
+
+(defcustom evil-ex-search-highlight-all t
+  "If t and interactive search is enabled, all matches are
+highlighted."
+  :type 'boolean
+  :group 'evil)
+
+(defcustom evil-ex-substitute-highlight-all t
+  "If t all matches for the substitute pattern are highlighted."
+  :type 'boolean
+  :group 'evil)
+
+(defcustom evil-ex-substitute-interactive-replace t
+  "If t and substitute patterns are highlighted,
+the replacement is shown interactively."
+  :type 'boolean
+  :group 'evil)
+
+(defcustom evil-ex-substitute-global nil
+  "If non-nil substitute patterns are global by default.
+Usually (if this variable is nil) a substitution works only on
+the first match of a pattern in a line unless the 'g' flag is
+given, in which case the substitution happens on all matches in a
+line. If this option is non-nil, this behaviour is reversed: the
+substitution works on all matches unless the 'g' pattern is
+specified, then is works only on the first match."
+  :type  'boolean
+  :group 'evil)
+
+(defface evil-ex-search '((t :inherit isearch))
+  "Face for interactive search."
+  :group 'evil)
+
+(defface evil-ex-lazy-highlight '((t :inherit lazy-highlight))
+  "Face for highlighting all matches in interactive search."
+  :group 'evil)
+
+(defface evil-ex-substitute-matches '((t :inherit lazy-highlight))
+  "Face for interactive substitute matches."
+  :group 'evil)
+
+(defface evil-ex-substitute-replacement '((((supports :underline))
+                                           :underline t
+                                           :foreground "red"))
+  "Face for interactive replacement text."
+  :group 'evil)
+
+(defcustom evil-command-window-height 8
+  "Height (in lines) of the command line window.
+Set to 0 to use the default height for `split-window'."
+  :type 'integer
+  :group 'evil)
+
+(defcustom evil-display-shell-error-in-message nil
+  "Show error output of a shell command in the error buffer.
+If this variable is non-nil the error output of a shell command
+goes to the messages buffer instead of being mixed with the
+regular output. This happens only if the exit status of the
+command is non-zero."
+  :type 'boolean
+  :group 'evil)
+
+(defcustom evil-want-abbrev-expand-on-insert-exit t
+  "If non-nil abbrevs will be expanded when leaving Insert state
+like in Vim. This variable is read only on load."
+  :type 'boolean
+  :group 'evil)
+
+;;; Variables
+
+(defmacro evil-define-local-var (symbol &optional initvalue docstring)
+  "Define SYMBOL as permanent buffer local variable, and return SYMBOL.
+The parameters are the same as for `defvar', but the variable
+SYMBOL is made permanent buffer local."
+  (declare (indent defun)
+           (debug (symbolp &optional form stringp)))
+  `(progn
+     (defvar ,symbol ,initvalue ,docstring)
+     (make-variable-buffer-local ',symbol)
+     (put ',symbol 'permanent-local t)))
+
+(evil-define-local-var evil-scroll-count 0
+  "Holds last used prefix for `evil-scroll-up'
+and `evil-scroll-down'.
+Determines how many lines should be scrolled.
+Default value is 0 - scroll half the screen.")
+
+(evil-define-local-var evil-state nil
+  "The current Evil state.
+To change the state, use `evil-change-state'
+or call the state function (e.g., `evil-normal-state').")
+
+;; these may be used inside `evil-define-state'
+(evil-define-local-var evil-next-state nil
+  "The Evil state being switched to.")
+
+(evil-define-local-var evil-previous-state-alist nil
+  "For Each evil state the Evil state being switched from.")
+
+(evil-define-local-var evil-previous-state nil
+  "The Evil state being switched from.")
+
+(defvar evil-execute-in-emacs-state-buffer nil
+  "The buffer of the latest `evil-execute-in-emacs-state'.
+When this command is being executed the current buffer is stored
+in this variable. This is necessary in case the Emacs-command to
+be called changes the current buffer.")
+
+(evil-define-local-var evil-mode-line-tag nil
+  "Mode-Line indicator for the current state.")
+(put 'evil-mode-line-tag 'risky-local-variable t)
+
+(defvar evil-global-keymaps-alist nil
+  "Association list of keymap variables.
+Entries have the form (MODE . KEYMAP), where KEYMAP
+is the variable containing the keymap for MODE.")
+
+(defvar evil-local-keymaps-alist nil
+  "Association list of keymap variables that must be
+reinitialized in each buffer. Entries have the form
+\(MODE . KEYMAP), where KEYMAP is the variable containing
+the keymap for MODE.")
+
+(defvar evil-minor-mode-keymaps-alist nil
+  "Association list of evil states to minor-mode keymap alists.
+Entries have the form (STATE . MODE-MAP-ALIST), where
+MODE-MAP-ALIST is an alist taking the form of
+`minor-mode-map-alist'.")
+
+(defvar evil-state-properties nil
+  "Specifications made by `evil-define-state'.
+Entries have the form (STATE . PLIST), where PLIST is a property
+list specifying various aspects of the state. To access a property,
+use `evil-state-property'.")
+
+(evil-define-local-var evil-mode-map-alist nil
+  "Association list of keymaps to use for Evil modes.
+Elements have the form (MODE . KEYMAP), with the first keymaps
+having higher priority.")
+
+(defvar evil-command-properties nil
+  "Specifications made by `evil-define-command'.")
+
+(defvar evil-change-commands '(evil-change)
+  "Commands that wrap or replace `evil-change'.
+This list exists to apply an inconsistency with vim's change command
+to commands that wrap or redefine it. See emacs-evil/evil#916.")
+
+(defvar evil-transient-vars '(cua-mode transient-mark-mode select-active-regions)
+  "List of variables pertaining to Transient Mark mode.")
+
+(defvar evil-transient-vals nil
+  "Association list of old values for Transient Mark mode variables.
+Entries have the form (VARIABLE VALUE LOCAL), where LOCAL is
+whether the variable was previously buffer-local.")
+
+(evil-define-local-var evil-no-display nil
+  "If non-nil, various Evil displays are inhibited.
+Use the macro `evil-without-display' to set this variable.")
+
+(defvar evil-type-properties nil
+  "Specifications made by `evil-define-type'.
+Entries have the form (TYPE . PLIST), where PLIST is a property
+list specifying functions for handling the type: expanding it,
+describing it, etc.")
+
+(defvar evil-interactive-alist nil
+  "Association list of Evil-specific interactive codes.")
+
+(evil-define-local-var evil-motion-marker nil
+  "Marker for storing the starting position of a motion.")
+
+(evil-define-local-var evil-this-type nil
+  "Current motion type.")
+
+(evil-define-local-var evil-this-type-modified nil
+  "Non-nil iff current motion type has been modified by the user.
+If the type has been modified, this variable contains the new
+type.")
+
+(evil-define-local-var evil-this-register nil
+  "Current register.")
+
+(defvar evil-this-macro nil
+  "Current macro register.")
+
+(evil-define-local-var evil-this-operator nil
+  "Current operator.")
+
+(evil-define-local-var evil-this-motion nil
+  "Current motion.")
+
+(evil-define-local-var evil-this-motion-count nil
+  "Current motion count.")
+
+(defvar evil-last-register nil
+  "The last executed register.")
+
+(defvar evil-inhibit-operator nil
+  "Inhibit current operator.
+If an operator calls a motion and the motion sets this variable
+to t, the operator code is not executed.")
+
+(defvar evil-inhibit-operator-value nil
+  "This variable is used to transfer the value
+of `evil-inhibit-operator' from one local scope to another.")
+
+;; used by `evil-define-operator'
+(defvar evil-operator-range-beginning nil
+  "Beginning of `evil-operator-range'.")
+
+(defvar evil-operator-range-end nil
+  "End of `evil-operator-range'.")
+
+(defvar evil-operator-range-type nil
+  "Type of `evil-operator-range'.")
+
+(defvar evil-operator-range-motion nil
+  "Motion of `evil-operator-range'.")
+
+(defvar evil-restriction-stack nil
+  "List of previous restrictions.
+Using `evil-with-restriction' stores the previous values of
+`point-min' and `point-max' as a pair in this list.")
+
+(evil-define-local-var evil-markers-alist
+  '((?\( . evil-backward-sentence)
+    (?\) . evil-forward-sentence)
+    (?{ . evil-backward-paragraph)
+    (?} . evil-forward-paragraph)
+    (?' . evil-jump-backward-swap)
+    (?` . evil-jump-backward-swap)
+    (?< . evil-visual-beginning)
+    (?> . evil-visual-goto-end)
+    (?. . (lambda ()
+            (let (last-command)
+              (goto-last-change nil)))))
+  "Association list for markers.
+Entries have the form (CHAR . DATA), where CHAR is the marker's
+name and DATA is either a marker object as returned by `make-marker',
+a variable, a movement function, or a cons cell (STRING NUMBER),
+where STRING is a file path and NUMBER is a buffer position.
+The global value of this variable holds markers available from
+every buffer, while the buffer-local value holds markers available
+only in the current buffer.")
+
+(defconst evil-suppress-map (make-keymap)
+  "Full keymap disabling default bindings to `self-insert-command'.")
+(suppress-keymap evil-suppress-map t)
+
+(defvar evil-read-key-map (make-sparse-keymap)
+  "Keymap active during `evil-read-key'.
+This keymap can be used to bind some commands during the
+execution of `evil-read-key' which is usually used to read a
+character argument for some commands, e.g. `evil-replace'.")
+
+;; TODO: customize size of ring
+(defvar evil-repeat-ring (make-ring 10)
+  "A ring of repeat-informations to repeat the last command.")
+
+(defvar evil-repeat-types
+  '((t . evil-repeat-keystrokes)
+    (change . evil-repeat-changes)
+    (motion . evil-repeat-motion)
+    (insert-at-point . evil-repeat-insert-at-point)
+    (ignore . nil))
+  "An alist of defined repeat-types.")
+
+(defvar evil-recording-repeat nil
+  "Whether we are recording a repeat.")
+
+(defvar evil-recording-current-command nil
+  "Whether we are recording the current command for repeat.")
+
+(defvar evil-repeat-changes nil
+  "Accumulated buffer changes for changed-based commands.")
+
+(defvar evil-repeat-info nil
+  "Information accumulated during current repeat.")
+
+(defvar evil-repeat-buffer nil
+  "The buffer in which the repeat started.
+If the buffer is changed, the repeat is cancelled.")
+
+(defvar evil-repeat-pos nil
+  "The position of point at the beginning of an change-tracking
+  editing command.")
+
+(defvar evil-repeat-keys nil
+  "The keys that invoked the current command.")
+
+(defvar evil-last-repeat nil
+  "Information about the latest repeat command.
+This is a list of three elements (POINT COUNT UNDO-POINTER),
+where POINT is the position of point before the latest repeat,
+COUNT the count-argument of the latest repeat command and
+UNDO-POINTER the head of the undo-list before the last command
+has been repeated.")
+
+(defvar evil-repeat-count nil
+  "The explicit count when repeating a command.")
+
+(defvar evil-maybe-remove-spaces nil
+  "Flag to determine if newly inserted spaces should be removed.
+See the function `evil-maybe-remove-spaces'.")
+
+(evil-define-local-var evil-insert-count nil
+  "The explicit count passed to an command starting Insert state.")
+
+(evil-define-local-var evil-insert-vcount nil
+  "The information about the number of following lines the
+insertion should be repeated. This is list (LINE COLUMN COUNT)
+where LINE is the line-number where the original insertion
+started and COLUMN is either a number or function determining the
+column where the repeated insertions should take place. COUNT is
+number of repeats (including the original insertion).")
+
+(defvar evil-insert-skip-empty-lines nil
+  "Non-nil of the current insertion should not take place on
+  lines at which the insertion point is behind the end of the
+  line.")
+
+(evil-define-local-var evil-insert-lines nil
+  "Non-nil if the current insertion command is a line-insertion
+command o or O.")
+
+(evil-define-local-var evil-insert-repeat-info nil
+  "Repeat information accumulated during an insertion.")
+
+(evil-define-local-var evil-replace-alist nil
+  "Association list of characters overwritten in Replace state.
+The format is (POS . CHAR).")
+
+(evil-define-local-var evil-echo-area-message nil
+  "Previous value of `current-message'.")
+
+(defvar evil-write-echo-area nil
+  "If set to t inside `evil-save-echo-area', then the echo area
+is not restored.")
+
+(defvar evil-last-find nil
+  "A pair (FUNCTION . CHAR) describing the lastest character
+  search command.")
+
+(defvar evil-last-paste nil
+  "Information about the latest paste.
+This should be a list (CMD COUNT POINT BEG END FIRSTVISUAL) where
+CMD is the last paste-command (`evil-paste-before',
+`evil-paste-after' or `evil-visual-paste'), COUNT is the repeat
+count of the paste, POINT is the position of point before the
+paste, BEG end END are the region of the inserted
+text. FIRSTVISUAL is t if and only if the previous command was
+the first visual paste (i.e. before any paste-pop).")
+
+(evil-define-local-var evil-last-undo-entry nil
+  "Information about the latest undo entry in the buffer.
+This should be a pair (OBJ . CONS) where OBJ is the entry as an
+object, and CONS is a copy of the entry.")
+
+(evil-define-local-var evil-current-insertion nil
+  "Information about the latest insertion in insert state.
+This should be a pair (BEG . END) that describes the
+buffer-region of the newly inserted text.")
+
+(defvar evil-last-insertion nil
+  "The last piece of inserted text.")
+
+(defvar evil-last-small-deletion nil
+  "The last piece of deleted text.
+The text should be less than a line.")
+
+(defvar evil-was-yanked-without-register t
+  "Whether text being saved to the numbered-register ring was
+not deleted and not yanked to a specific register.")
+
+(defvar evil-paste-count nil
+  "The count argument of the current paste command.")
+
+(defvar evil-temporary-undo nil
+  "When undo is disabled in current buffer.
+Certain commands depending on undo use this variable
+instead of `buffer-undo-list'.")
+
+(evil-define-local-var evil-undo-list-pointer nil
+  "Everything up to this mark is united in the undo-list.")
+
+(defvar evil-in-single-undo nil
+  "Set to non-nil if the current undo steps are connected.")
+
+(defvar evil-flash-timer nil
+  "Timer for flashing search results.")
+
+(defvar evil-search-prompt nil
+  "String to use for search prompt.")
+
+(defvar evil-search-forward-history nil
+  "History of forward searches.")
+
+(defvar evil-search-backward-history nil
+  "History of backward searches.")
+
+(defvar evil-inner-text-objects-map (make-sparse-keymap)
+  "Keymap for inner text objects.")
+
+(defvar evil-outer-text-objects-map (make-sparse-keymap)
+  "Keymap for outer text objects.")
+
+(defvar evil-window-map (make-sparse-keymap)
+  "Keymap for window-related commands.")
+
+(evil-define-local-var evil-input-method nil
+  "Input method used in Insert state and Emacs state.")
+
+;;; Visual state
+
+(evil-define-local-var evil-visual-beginning nil
+  "The beginning of the Visual selection, a marker.")
+
+(evil-define-local-var evil-visual-end nil
+  "The end of the Visual selection, a marker.")
+
+(evil-define-local-var evil-visual-point nil
+  "The position of point in Visual state, a marker.")
+
+(evil-define-local-var evil-visual-mark nil
+  "The position of mark in Visual state, a marker.")
+
+(evil-define-local-var evil-visual-previous-mark nil
+  "The position of mark before Visual state, a marker.")
+
+(evil-define-local-var evil-visual-selection nil
+  "The kind of Visual selection.
+This is a selection as defined by `evil-define-visual-selection'.")
+
+;; we could infer the direction by comparing `evil-visual-mark'
+;; and `evil-visual-point', but destructive operations may
+;; displace the markers
+(evil-define-local-var evil-visual-direction 0
+  "Whether point follows mark in Visual state.
+Negative if point precedes mark, otherwise positive.
+See also the function `evil-visual-direction'.")
+
+(evil-define-local-var evil-visual-properties nil
+  "Property list of miscellaneous Visual properties.")
+
+(evil-define-local-var evil-visual-region-expanded nil
+  "Whether the region matches the Visual selection.
+That is, whether the positions of point and mark have been
+expanded to coincide with the selection's boundaries.
+This makes the selection available to functions acting
+on Emacs' region.")
+
+(evil-define-local-var evil-visual-overlay nil
+  "Overlay for highlighting the Visual selection.
+Not used for blockwise selections, in which case
+see `evil-visual-block-overlays'.")
+
+(evil-define-local-var evil-visual-block-overlays nil
+  "Overlays for Visual Block selection, one for each line.
+They are reused to minimize flicker.")
+
+(defvar evil-visual-alist nil
+  "Association list of Visual selection functions.
+Elements have the form (NAME . FUNCTION).")
+
+(evil-define-local-var evil-visual-x-select-timer nil
+  "Timer for updating the X selection in visual state.")
+
+(defvar evil-visual-x-select-timeout 0.1
+  "Time in seconds for the update of the X selection.")
+
+(declare-function origami-open-all-nodes "origami.el")
+(declare-function origami-close-all-nodes "origami.el")
+(declare-function origami-toggle-node "origami.el")
+(declare-function origami-open-node "origami.el")
+(declare-function origami-open-node-recursively "origami.el")
+(declare-function origami-close-node "origami.el")
+
+(defvar evil-fold-list
+  `(((hs-minor-mode)
+     :open-all   hs-show-all
+     :close-all  hs-hide-all
+     :toggle     hs-toggle-hiding
+     :open       hs-show-block
+     :open-rec   nil
+     :close      hs-hide-block)
+    ((hide-ifdef-mode)
+     :open-all   show-ifdefs
+     :close-all  hide-ifdefs
+     :toggle     nil
+     :open       show-ifdef-block
+     :open-rec   nil
+     :close      hide-ifdef-block)
+    ((outline-mode
+      outline-minor-mode
+      org-mode
+      markdown-mode)
+     :open-all   show-all
+     :close-all  ,(lambda ()
+                    (with-no-warnings (hide-sublevels 1)))
+     :toggle     outline-toggle-children
+     :open       ,(lambda ()
+                    (with-no-warnings
+                      (show-entry)
+                      (show-children)))
+     :open-rec   show-subtree
+     :close      hide-subtree)
+    ((origami-mode)
+     :open-all   ,(lambda () (origami-open-all-nodes (current-buffer)))
+     :close-all  ,(lambda () (origami-close-all-nodes (current-buffer)))
+     :toggle     ,(lambda () (origami-toggle-node (current-buffer) (point)))
+     :open       ,(lambda () (origami-open-node (current-buffer) (point)))
+     :open-rec   ,(lambda () (origami-open-node-recursively (current-buffer) (point)))
+     :close      ,(lambda () (origami-close-node (current-buffer) (point))))
+    ((vdiff-mode)
+     :open-all   vdiff-open-all-folds
+     :close-all  vdiff-close-all-folds
+     :toggle     nil
+     :open       ,(lambda () (call-interactively 'vdiff-open-fold))
+     :open-rec   ,(lambda () (call-interactively 'vdiff-open-fold))
+     :close      ,(lambda () (call-interactively 'vdiff-close-fold))))
+  "Actions to be performed for various folding operations.
+
+The value should be a list of fold handlers, were a fold handler has
+the format:
+
+  ((MODES) PROPERTIES)
+
+MODES acts as a predicate, containing the symbols of all major or
+minor modes for which the handler should match.  For example:
+
+  '((outline-minor-mode org-mode) ...)
+
+would match for either outline-minor-mode or org-mode, even though the
+former is a minor mode and the latter is a major.
+
+PROPERTIES specifies possible folding actions and the functions to be
+applied in the event of a match on one (or more) of the MODES; the
+supported properties are:
+
+  - `:open-all'
+    Open all folds.
+  - `:close-all'
+    Close all folds.
+  - `:toggle'
+    Toggle the display of the fold at point.
+  - `:open'
+    Open the fold at point.
+  - `:open-rec'
+    Open the fold at point recursively.
+  - `:close'
+    Close the fold at point.
+
+Each value must be a function.  A value of `nil' will cause the action
+to be ignored for that respective handler.  For example:
+
+  `((org-mode)
+     :close-all  nil
+     :open       ,(lambda ()
+                    (show-entry)
+                    (show-children))
+     :close      hide-subtree)
+
+would ignore `:close-all' actions and invoke the provided functions on
+`:open' or `:close'.")
+
+;;; Ex
+
+(defvar evil-ex-map (make-sparse-keymap)
+  "Keymap for Ex.
+Key sequences bound in this map are immediately executed.")
+
+(defvar evil-ex-completion-map (make-sparse-keymap)
+  "Completion keymap for Ex.")
+
+(defvar evil-ex-initial-input nil
+  "Additional initial content of the ex command line.
+This content of this variable is appended to the ex command line
+if ex is started interactively.")
+
+(defvar evil-ex-shell-argument-initialized nil
+  "This variable is set to t if shell command completion has been initialized.
+See `evil-ex-init-shell-argument-completion'.")
+
+(defvar evil-ex-commands nil
+  "Association list of command bindings and functions.")
+
+(defvar evil-ex-history nil
+  "History of Ex commands.")
+
+(defvar evil-ex-current-buffer nil
+  "The buffer from which Ex was started.")
+
+(defvar evil-ex-expression nil
+  "The evaluation tree.")
+
+(defvar evil-ex-tree nil
+  "The syntax tree.")
+
+(defvar evil-ex-command nil
+  "The current Ex command.")
+
+(defvar evil-ex-previous-command nil
+  "The previously executed Ex command.")
+
+(defvar evil-ex-cmd nil
+  "The current Ex command string.")
+
+(defvar evil-ex-point nil
+  "The position of `point' when the ex command has been called.")
+
+(defvar evil-ex-range nil
+  "The current range of the Ex command.")
+
+(defvar evil-ex-bang nil
+  "The \"!\" argument of the current Ex command.")
+
+(defvar evil-ex-argument nil
+  "The current argument of the Ex command.")
+
+(defvar evil-ex-argument-handler nil
+  "The argument handler for the current Ex command.")
+
+(defvar evil-ex-argument-types nil
+  "Association list of argument handlers.")
+
+(defvar evil-previous-shell-command nil
+  "The last shell command.")
+
+;; Searching
+(defvar evil-ex-search-history nil
+  "The history for the search command.")
+
+(defvar evil-ex-search-direction nil
+  "The direction of the current search, either 'forward or 'backward.")
+
+(defvar evil-ex-search-count nil
+  "The count if the current search.")
+
+(defvar evil-ex-search-start-point nil
+  "The point where the search started.")
+
+(defvar evil-ex-search-overlay nil
+  "The overlay for the current search result.")
+
+(defvar evil-ex-search-pattern nil
+  "The last search pattern.")
+
+(defvar evil-ex-search-offset nil
+  "The last search offset.")
+
+(defvar evil-ex-search-match-beg nil
+  "The beginning position of the last match.")
+
+(defvar evil-ex-search-match-end nil
+  "The end position of the last match.")
+
+(defvar evil-ex-substitute-pattern nil
+  "The last substitute pattern.")
+
+(defvar evil-ex-substitute-replacement nil
+  "The last substitute replacement.")
+
+(defvar evil-ex-substitute-flags nil
+  "The last substitute flags.")
+
+(defvar evil-ex-substitute-current-replacement nil
+  "The actual replacement.")
+
+(defvar evil-ex-last-was-search nil
+  "Non-nil if the previous was a search.
+Otherwise the previous command is assumed as substitute.")
+
+;;; Command line window
+
+(defvar evil-command-window-current-buffer nil
+  "The buffer from which the command line window was called.")
+
+(evil-define-local-var evil-command-window-execute-fn nil
+  "The command to execute when exiting the command line window.")
+
+(evil-define-local-var evil-command-window-cmd-key nil
+  "The key for the command that opened the command line window (:, /, or ?).")
+
+;; The lazy-highlighting framework.
+(evil-define-local-var evil-ex-active-highlights-alist nil
+  "An alist of currently active highlights.")
+
+(evil-define-local-var evil-ex-hl-update-timer nil
+  "Time used for updating highlights.")
+
+(defvar evil-ex-search-keymap (make-sparse-keymap)
+  "Keymap used in ex-search-mode.")
+(define-key evil-ex-search-keymap [escape] 'abort-recursive-edit)
+(set-keymap-parent evil-ex-search-keymap minibuffer-local-map)
+
+(defconst evil-version
+  (eval-when-compile
+    (with-temp-buffer
+      (let ((dir (file-name-directory (or load-file-name
+                                          byte-compile-current-file))))
+        ;; git repository
+        (if (and (file-exists-p (concat dir "/.git"))
+                 (ignore-errors
+                   (zerop (call-process "git" nil '(t nil) nil
+                                        "rev-parse"
+                                        "--short" "HEAD"))))
+            (progn
+              (goto-char (point-min))
+              (concat "evil-git-"
+                      (buffer-substring (point-min)
+                                        (line-end-position))))
+          ;; no repo, use plain version
+          "1.2.13"))))
+  "The current version of Evil")
+
+(defcustom evil-want-integration t
+  "Whether to load evil-integration.el.
+This variable must be set before evil is loaded."
+  :type 'boolean
+  :group 'evil)
+
+(defun evil-version ()
+  (interactive)
+  (message "Evil version %s" evil-version))
+
+(provide 'evil-vars)
+
+;;; evil-vars.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-vars.elc b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-vars.elc
new file mode 100644
index 0000000000..8b1cc37adb
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil-vars.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil.el b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil.el
new file mode 100644
index 0000000000..5c9e54a702
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil.el
@@ -0,0 +1,148 @@
+;;; evil.el --- extensible vi layer
+
+;; The following list of authors was kept up to date until the beginning of
+;; 2017, when evil moved under new maintainers. For authors since then, please
+;; consult the git logs.
+
+;;      Alessandro Piras <laynor at gmail.com>
+;;      Alexander Baier <alexander.baier at mailbox.org>
+;;      Antono Vasiljev <antono.vasiljev at gmail.com>
+;;      Bailey Ling <bling at live.ca>
+;;      Barry O'Reilly <gundaetiapo at gmail.com>
+;;      Christoph Lange <langec at web.de>
+;;      Daniel Reiter <danieltreiter at gmail.com>
+;;      Eivind Fonn <evfonn at gmail.com>
+;;      Emanuel Evans <emanuel.evans at gmail.com>
+;;      Eric Siegel <siegel.eric at gmail.com>
+;;      Eugene Yaremenko <w3techplayground at gmail.com>
+;;      Frank Fischer <frank-fischer at shadow-soft.de>
+;;      Frank Terbeck <ft at bewatermyfriend.org>
+;;      Gordon Gustafson <gordon3.14 at gmail.com>
+;;      Herbert Jones <jones.herbert at gmail.com>
+;;      Jonas Bernoulli <jonas at bernoul.li>
+;;      Jonathan Claggett <jclaggett at lonocloud.com>
+;;      José A. Romero L. <escherdragon at gmail.com>
+;;      Justin Burkett <justin at burkett.cc>
+;;      Lars Andersen <expez at expez.com>
+;;      Lintaro Ina <tarao.gnn at gmail.com>
+;;      Lukasz Wrzosek <wrzoski at mail.com>
+;;      Marian Schubert <maio at netsafe.cz>
+;;      Matthew Malcomson <>
+;;      Michael Markert <markert.michael at googlemail.com>
+;;      Mike Gerwitz <mikegerwitz at gnu.org>
+;;      Nikolai Weibull <now at bitwi.se>
+;;      phaebz <phaebz at gmail.com>
+;;      ralesi <scio62 at gmail.com>
+;;      Rodrigo Setti <rodrigosetti at gmail.com>
+;;      Sanel Zukan <sanelz at gmail.com>
+;;      Sarah Brofeldt <sarah at thinkmonster.(none)>
+;;      Simon Hafner <hafnersimon at gmail.com>
+;;      Stefan Wehr <mail at stefanwehr.de>
+;;      Sune Simonsen <sune.simonsen at jayway.com>
+;;      Thomas Hisch <thomas at opentech.at>
+;;      Tim Harper <timcharper at gmail.com>
+;;      Tom Willemse <tom at ryuslash.org>
+;;      Trevor Murphy <trevor.m.murphy at gmail.com>
+;;      Ulrich Müller <ulm at gentoo.org>
+;;      Vasilij Schneidermann <v.schneidermann at gmail.com>
+;;      Vegard Øye <vegard_oye at hotmail.com>
+;;      Winfred Lu <winfred.lu at gmail.com>
+;;      Wolfgang Jenkner <wjenkner at inode.at>
+;;      Xiao Hanyu <xiaohanyu1988 at gmail.com>
+;;      York Zhao <yzhao at telecor.com>
+
+;; Maintainers: The emacs-evil team. <https://github.com/orgs/emacs-evil/people>
+;;      To get in touch, please use the bug tracker or the
+;;      mailing list (see below).
+;; Created: 2011-03-01
+;; Version: 1.2.13
+;; Keywords: emulation, vim
+;; URL: https://github.com/emacs-evil/evil
+;;      Repository: https://github.com/emacs-evil/evil.git
+;;      EmacsWiki: http://www.emacswiki.org/emacs/Evil
+;; Bug tracker: https://github.com/emacs-evil/evil/issues
+;;      If you have bug reports, suggestions or patches, please
+;;      create an issue at the bug tracker (open for everyone).
+;;      Other discussions (tips, extensions) go to the mailing list.
+;; Mailing list: <implementations-list at lists.ourproject.org>
+;;      Subscribe: http://tinyurl.com/implementations-list
+;;      Newsgroup: nntp://news.gmane.org/gmane.emacs.vim-emulation
+;;      Archives: http://dir.gmane.org/gmane.emacs.vim-emulation
+;;      You don't have to subscribe to post; we usually reply
+;;      within a few days and CC our replies back to you.
+;;
+;; This file is NOT part of GNU Emacs.
+
+;;; License:
+
+;; This file is part of Evil.
+;;
+;; Evil 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.
+;;
+;; Evil 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 Evil.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Evil is an extensible vi layer for Emacs. It emulates the main
+;; features of Vim, and provides facilities for writing custom
+;; extensions.
+;;
+;; Evil lives in a Git repository. To obtain Evil, do
+;;
+;;      git clone git://github.com/emacs-evil/evil.git
+;;
+;; Move Evil to ~/.emacs.d/evil (or somewhere else in the `load-path').
+;; Then add the following lines to ~/.emacs:
+;;
+;;      (add-to-list 'load-path "~/.emacs.d/evil")
+;;      (require 'evil)
+;;      (evil-mode 1)
+;;
+;; Evil requires undo-tree.el for linear undo and undo branches:
+;;
+;;      http://www.emacswiki.org/emacs/UndoTree
+;;
+;; Otherwise, Evil uses regular Emacs undo.
+;;
+;; Evil requires `goto-last-change' and `goto-last-change-reverse'
+;; function for the corresponding motions g; g, as well as the
+;; last-change-register `.'. One package providing these functions is
+;; goto-chg.el:
+;;
+;;     http://www.emacswiki.org/emacs/GotoChg
+;;
+;; Without this package the corresponding motions will raise an error.
+
+;;; Code:
+
+(require 'evil-vars)
+(require 'evil-common)
+(require 'evil-core)
+(require 'evil-states)
+(require 'evil-repeat)
+(require 'evil-macros)
+(require 'evil-search)
+(require 'evil-ex)
+(require 'evil-digraphs)
+(require 'evil-types)
+(require 'evil-commands)
+(require 'evil-jumps)
+(require 'evil-maps)
+
+(when evil-want-integration
+  (require 'evil-integration))
+
+(run-hooks 'evil-after-load-hook)
+
+(provide 'evil)
+
+;;; evil.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil.elc b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil.elc
new file mode 100644
index 0000000000..1e46f90a5a
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil.info b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil.info
new file mode 100644
index 0000000000..c62ee66ebd
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/evil.info
@@ -0,0 +1,1215 @@
+This is evil.info, produced by makeinfo version 6.1 from evil.texi.
+
+This manual is for Evil (version 0.1 of 2011-07-30), an extensible vi
+layer for Emacs.
+
+   Copyright  2011 Frank Fischer and Vegard ye.
+
+     Permission is granted to copy, distribute and/or modify this
+     document under the terms of the GNU Free Documentation License,
+     Version 1.3 or any later version published by the Free Software
+     Foundation; with no Invariant Sections, no Front-Cover Texts, and
+     no Back-Cover Texts.  A copy of the license is included in the
+     section entitled "GNU Free Documentation License".
+
+   The Evil team thanks everyone at gmane.emacs.vim-emulation for their
+feedback and contributions.
+INFO-DIR-SECTION Emacs
+START-INFO-DIR-ENTRY
+* Evil: (evil). Extensible vi layer for Emacs.
+END-INFO-DIR-ENTRY
+
+
+File: evil.info,  Node: Top,  Next: Overview,  Prev: (dir),  Up: (dir)
+
+Evil
+****
+
+This is the manual for Evil, an extensible vi layer for Emacs.
+
+* Menu:
+
+* Overview::
+* Settings::
+* Keymaps::
+* Hooks::
+* Macros::
+* Other internals::
+* GNU Free Documentation License::
+
+
+File: evil.info,  Node: Overview,  Next: Settings,  Up: Top
+
+1 Overview
+**********
+
+Evil is an extensible vi layer for Emacs.  It emulates the main features
+of Vim,(1) turning Emacs into a modal editor.  Like Emacs in general,
+Evil is extensible in Emacs Lisp.
+
+* Menu:
+
+* Installation::
+* Modes and states::
+
+   ---------- Footnotes ----------
+
+   (1) Vim is the most popular version of "vi", a modal text editor with
+many implementations.  Vim also adds some functions of its own, like
+Visual selection and text objects.  For more information, see:
+<http://www.vim.org/>
+
+
+File: evil.info,  Node: Installation,  Next: Modes and states,  Up: Overview
+
+1.1 Installation
+================
+
+Evil lives in a Git repository.  To download Evil, do:
+
+     git clone https://github.com/emacs-evil/evil.git
+
+Move Evil to '~/.emacs.d/evil'.  Then add the following lines to
+'~/.emacs':
+
+     (add-to-list 'load-path "~/.emacs.d/evil")
+     (require 'evil)
+     (evil-mode 1)
+
+Evil requires 'undo-tree.el' to provide linear undo and undo branches.
+It is available from EmacsWiki.(1)  (A copy of 'undo-tree.el' is also
+included in the Git repository.)
+
+   ---------- Footnotes ----------
+
+   (1) <http://www.emacswiki.org/emacs/UndoTree>
+
+
+File: evil.info,  Node: Modes and states,  Prev: Installation,  Up: Overview
+
+1.2 Modes and states
+====================
+
+The next time Emacs is started, it will come up in "Normal state",
+denoted by '<N>' on the mode line.  This is where the main vi bindings
+are defined.  Note that you can always disable Normal state with 'C-z',
+which switches to an "Emacs state" (denoted by '<E>') in which vi keys
+are completely disabled.  Press 'C-z' again to switch back to Normal
+state.
+
+   Evil uses the term "state" for what is called a "mode" in vi, since
+"mode" already has its own meaning in Emacs.  Evil defines a number of
+states, such as Normal state ('<N>'), Insert state ('<I>'), Visual state
+('<V>'), Replace state ('<R>'), Operator-Pending state ('<O>'), Motion
+state ('<M>') and Emacs state ('<E>').  Each state has its own keymaps
+and customization variables.
+
+   Meanwhile, a "mode" in Emacs is a set of key bindings for editing a
+certain sort of text, like 'emacs-lisp-mode' for Emacs Lisp.  Modes may
+include custom bindings for Evil states.
+
+
+File: evil.info,  Node: Settings,  Next: Keymaps,  Prev: Overview,  Up: Top
+
+2 Settings
+**********
+
+Evil's behavior can be adjusted by setting various variables.  The
+current values may be inspected by doing 'M-x customize-group RET evil
+RET'.
+
+   To change the value of a variable, add a 'setq' form to '~/.emacs',
+preferably before Evil is loaded:(1)
+
+     (setq evil-shift-width 8)
+     ;; Load Evil
+     (require 'evil) ...
+
+Note that if a variable is buffer-local, you must use 'setq-default'
+instead of 'setq' to change its global value.
+
+ -- Variable: evil-auto-indent
+     Whether the current line is indented when entering Insert state.
+     If 't' (the default), then the line is indented.  If 'nil', then
+     the line is not indented.  Buffer-local.
+
+ -- Variable: evil-shift-width
+     The number of columns a line is shifted by the commands '>' and
+     '<'.
+
+ -- Variable: evil-repeat-move-cursor
+     If 't' (the default), then repeating a command with '.' may change
+     the position of the cursor.  If 'nil', then the original position
+     is preserved.
+
+ -- Variable: evil-find-skip-newlines
+     If 't', then 'f', 'F', 't' and 'T' may skip over newlines to find a
+     character.  If 'nil' (the default), then they are restricted to the
+     current line.
+
+ -- Variable: evil-move-cursor-back
+     If 't' (the default), then the cursor moves backwards when exiting
+     Insert state.  If 'nil', then the cursor does not move.
+
+ -- Variable: evil-want-fine-undo
+     If 't', then a change-based action like 'cw' may be undone in
+     several steps.  If 'nil' (the default), then it is undone in one
+     step.
+
+ -- Variable: evil-regexp-search
+     If 't' (the default), then '/' and '?' use regular expressions for
+     searching.  If 'nil', they use plain text.
+
+ -- Variable: evil-search-wrap
+     If 't' (the default), then '/' and '?' wrap the search around the
+     buffer.  If 'nil', then they stop at buffer boundaries.
+
+ -- Variable: evil-flash-delay
+     The number of seconds to flash search matches when pressing 'n' and
+     'N'.
+
+ -- Variable: evil-want-C-i-jump
+     If 't' (the default), then 'C-i' jumps forwards in the jump list.
+     If 'nil', then 'C-i' inserts a tab.
+
+ -- Variable: evil-want-C-u-scroll
+     If 't', then 'C-u' scrolls the buffer.  If 'nil' (the default),
+     then 'C-u' begins a numeric prefix argument.
+
+* Menu:
+
+* The cursor::
+* The initial state::
+
+   ---------- Footnotes ----------
+
+   (1) Strictly speaking, the order only matters if the variable affects
+the way Evil is loaded.  This is the case with some of the 'evil-want-'
+variables.
+
+
+File: evil.info,  Node: The cursor,  Next: The initial state,  Up: Settings
+
+2.1 The cursor
+==============
+
+A state may change the cursor's appearance.  The cursor settings are
+stored in the variables below, which may contain a cursor type as per
+the 'cursor-type' variable, a color string as passed to the
+'set-cursor-color' function, a zero-argument function for changing the
+cursor, or a list of the above.  For example, the following changes the
+cursor in Replace state to a red box:
+
+     (setq evil-replace-state-cursor '("red" box))
+
+If the state does not specify a cursor, 'evil-default-cursor' is used.
+
+ -- Variable: evil-default-cursor
+     The default cursor.
+
+ -- Variable: evil-normal-state-cursor
+     The cursor for Normal state.
+
+ -- Variable: evil-insert-state-cursor
+     The cursor for Insert state.
+
+ -- Variable: evil-visual-state-cursor
+     The cursor for Visual state.
+
+ -- Variable: evil-replace-state-cursor
+     The cursor for Replace state.
+
+ -- Variable: evil-operator-state-cursor
+     The cursor for Operator-Pending state.
+
+ -- Variable: evil-motion-state-cursor
+     The cursor for Motion state.
+
+ -- Variable: evil-emacs-state-cursor
+     The cursor for Emacs state.
+
+
+File: evil.info,  Node: The initial state,  Prev: The cursor,  Up: Settings
+
+2.2 The initial state
+=====================
+
+By default, a new buffer comes up in Normal state.  This can be changed
+with the function 'evil-set-initial-state'.
+
+ -- Function: evil-set-initial-state mode state
+     Set the initial state for a buffer in which MODE is active to
+     STATE.  MODE should be a major mode such as 'text-mode', although
+     minor modes work as well.
+
+
+File: evil.info,  Node: Keymaps,  Next: Hooks,  Prev: Settings,  Up: Top
+
+3 Keymaps
+*********
+
+Evil's key bindings are stored in a number of keymaps.  Each state has a
+"global keymap", where the default key bindings for the state are
+stored.  For example, the global keymap for Normal state is
+'evil-normal-state-map', and the key bindings in this map are seen in
+all buffers that are currently in Normal state.
+
+   Keymaps are modified with the Emacs function 'define-key':
+
+     (define-key evil-normal-state-map "w" 'foo)
+
+This binds the key 'w' to the command 'foo' in Normal state.  The file
+'evil-maps.el' contains all the key bindings.
+
+ -- Variable: evil-normal-state-map
+     The global keymap for Normal state.
+
+ -- Variable: evil-insert-state-map
+     The global keymap for Insert state.
+
+ -- Variable: evil-visual-state-map
+     The global keymap for Visual state.
+
+ -- Variable: evil-replace-state-map
+     The global keymap for Replace state.
+
+ -- Variable: evil-operator-state-map
+     The global keymap for Operator-Pending state.
+
+ -- Variable: evil-motion-state-map
+     The global keymap for Motion state.
+
+Each state also has a "buffer-local keymap", which is specific to the
+current buffer and has precedence over the global keymap.  These maps
+may be changed from a mode hook.
+
+ -- Variable: evil-normal-state-local-map
+     Buffer-local keymap for Normal state.
+
+ -- Variable: evil-insert-state-local-map
+     Buffer-local keymap for Insert state.
+
+ -- Variable: evil-visual-state-local-map
+     Buffer-local keymap for Visual state.
+
+ -- Variable: evil-replace-state-local-map
+     Buffer-local keymap for Replace state.
+
+ -- Variable: evil-operator-state-local-map
+     Buffer-local keymap for Operator-Pending state.
+
+ -- Variable: evil-motion-state-local-map
+     Buffer-local keymap for Motion state.
+
+* Menu:
+
+* evil-define-key::
+
+
+File: evil.info,  Node: evil-define-key,  Up: Keymaps
+
+3.1 'evil-define-key'
+=====================
+
+Finally, Evil provides the function 'evil-define-key' for adding state
+bindings to a regular keymap.
+
+ -- Function: evil-define-key state keymap key def
+     In KEYMAP, create a binding from KEY to DEF in STATE.  STATE is one
+     of 'normal', 'insert', 'visual', 'replace', 'operator' and
+     'motion'.  The other parameters are like those of 'define-key'.
+
+'evil-define-key' can be used to augment existing modes with state
+bindings, as well as create packages for custom bindings.  For example,
+the following will create a minor mode 'foo-mode' with Normal state
+bindings for the keys 'w' and 'e':
+
+     (define-minor-mode foo-mode
+       "Foo mode."
+       :keymap (make-sparse-keymap))
+
+     (evil-define-key 'normal foo-mode-map "w" 'bar)
+     (evil-define-key 'normal foo-mode-map "e" 'baz)
+
+This minor mode can then be enabled in any buffers where the custom
+bindings are desired:
+
+     (add-hook 'text-mode-hook 'foo-mode) ; enable alongside 'text-mode'
+
+If the minor mode is put into its own file 'foo.el' with a '(provide
+'foo)' statement, it becomes an Emacs package.
+
+
+File: evil.info,  Node: Hooks,  Next: Macros,  Prev: Keymaps,  Up: Top
+
+4 Hooks
+*******
+
+A "hook" is a list of functions to execute.  Hooks are modified with the
+Emacs function 'add-hook'.  Evil provides entry and exit hooks for all
+of its states.
+
+ -- Variable: evil-normal-state-entry-hook
+     Run when entering Normal state.
+
+ -- Variable: evil-normal-state-exit-hook
+     Run when exiting Normal state.
+
+ -- Variable: evil-insert-state-entry-hook
+     Run when entering Insert state.
+
+ -- Variable: evil-insert-state-exit-hook
+     Run when exiting Insert state.
+
+ -- Variable: evil-visual-state-entry-hook
+     Run when entering Visual state.
+
+ -- Variable: evil-visual-state-exit-hook
+     Run when exiting Visual state.
+
+ -- Variable: evil-replace-state-entry-hook
+     Run when entering Replace state.
+
+ -- Variable: evil-replace-state-exit-hook
+     Run when exiting Replace state.
+
+ -- Variable: evil-operator-state-entry-hook
+     Run when entering Operator-Pending state.
+
+ -- Variable: evil-operator-state-exit-hook
+     Run when exiting Operator-Pending state.
+
+ -- Variable: evil-motion-state-entry-hook
+     Run when entering Motion state.
+
+ -- Variable: evil-motion-state-exit-hook
+     Run when exiting Motion state.
+
+When these hooks are run, the variables 'evil-next-state' and
+'evil-previous-state' hold information about the states being switched
+to and from.
+
+ -- Variable: evil-next-state
+     The state being switched to.
+
+ -- Variable: evil-previous-state
+     The state being switched from.
+
+
+File: evil.info,  Node: Macros,  Next: Other internals,  Prev: Hooks,  Up: Top
+
+5 Macros
+********
+
+Evil is implemented in terms of reusable macros.  Package writers can
+use these to define new commands.
+
+* Menu:
+
+* Motions::
+* Operators::
+* Text objects::
+* Types::
+* States::
+
+
+File: evil.info,  Node: Motions,  Next: Operators,  Up: Macros
+
+5.1 Motions
+===========
+
+A "motion" is a command which moves the cursor, such as 'w' and 'e'.
+Motions are defined with the macro 'evil-define-motion'.  Motions not
+defined in this way should be declared with 'evil-declare-motion'.
+
+ -- Function: evil-declare-motion command
+     Declare COMMAND to be a motion.  This ensures that it works
+     properly in Visual state.
+
+ -- Macro: evil-define-motion motion (count args...) doc keyword-args...
+          body...
+     Define a movement command MOTION.  A motion can have any number of
+     arguments, but the first argument, if any, has a predefined meaning
+     as the COUNT.  It is a positive or negative number, or 'nil'.  The
+     argument list is followed by the documentation string DOC, which is
+     followed by optional keyword arguments:
+
+     ':type TYPE'
+          The TYPE determines how the motion works after an operator.
+          If TYPE is 'inclusive', then the ending position is included
+          in the motion range.  If TYPE is 'line', then the range is
+          expanded to linewise positions.  If TYPE is 'block', then the
+          range is blockwise.  The default is 'exclusive', which means
+          that the range is used as-is.
+
+     ':jump JUMP'
+          If JUMP is 't', then the previous position is stored in the
+          jump list so it can be restored with 'C-o'.  The default is
+          'nil'.
+
+     The keyword arguments are followed by the BODY, which is where the
+     motion's behavior is defined.  For instance:
+
+          (evil-define-motion foo-forward (count)
+            "Move to the right by COUNT characters."
+            :type inclusive
+            (forward-char (or count 1)))
+
+     For more examples, you can view the source code for any command
+     with 'C-h k'.  For instance, 'evil-goto-line' may be viewed by
+     typing 'C-h k G' and following the file link.
+
+
+File: evil.info,  Node: Operators,  Next: Text objects,  Prev: Motions,  Up: Macros
+
+5.2 Operators
+=============
+
+An "operator" is a command which acts on the text moved over by a
+motion, such as 'c', 'd' and 'y'.  Operators are defined with the macro
+'evil-define-operator'.
+
+ -- Macro: evil-define-operator operator (beg end type args...) doc
+          keyword-args... body...
+     Define an operator command OPERATOR.  An operator must have at
+     least two or three arguments, which have predefined meanings.  BEG
+     is the beginning position, END is the ending position, and TYPE, if
+     given, is the type of the motion range.  The argument list is
+     followed by the documentation string DOC, which is followed by
+     optional keyword arguments:
+
+     ':type TYPE'
+          Make the input range be a certain TYPE.  For example, an
+          operator which only works with whole lines may set TYPE to
+          'line'.
+
+     ':motion MOTION'
+          Use the motion MOTION instead of reading one from the
+          keyboard.  This does not affect the behavior in Visual state,
+          where the selection boundaries are used instead.
+
+     ':repeat REPEAT'
+          If REPEAT is 't' (the default), then '.' will repeat the
+          operator.  If REPEAT is 'nil', then the operator will not be
+          repeated.
+
+     ':move-point MOVE-POINT'
+          If MOVE-POINT is 't' (the default), then the cursor is
+          positioned at the beginning of the range.  If MOVE-POINT is
+          'nil', then the original position is preserved.
+
+     ':keep-visual KEEP-VISUAL'
+          If KEEP-VISUAL is 't', then the selection is not disabled when
+          the operator is run in Visual state; it is up to the operator
+          to do this.  The default is 'nil', which means that Visual
+          state is exited automatically.
+
+     The keyword arguments are followed by the BODY, which is where the
+     operator's actions on BEG and END are defined.  For example,
+     'evil-rot13', which is bound to 'g?' and performs ROT13 encryption
+     on the text, may be defined as:
+
+          (evil-define-operator evil-rot13 (beg end)
+            "ROT13 encrypt text."
+            (rot13-region beg end))
+
+     Pressing 'g?w' will encrypt a word by calling 'rot13-region' on the
+     text moved over by the 'w' motion.
+
+
+File: evil.info,  Node: Text objects,  Next: Types,  Prev: Operators,  Up: Macros
+
+5.3 Text objects
+================
+
+A "text object" is a special kind of motion which sets a beginning
+position as well as an ending position, such as 'iw' and 'a('.  In
+Visual state, text objects alter both ends of the selection.  Text
+objects are defined with the macro 'evil-define-text-object'.
+
+ -- Macro: evil-define-text-object object (count args...) doc
+          keyword-args... body...
+     Define a text object OBJECT.  The first argument has a predefined
+     meaning as the COUNT: it is a positive or negative number.  The
+     argument list is followed by the documentation string DOC, which is
+     followed by optional keyword arguments:
+
+     ':type TYPE'
+          Use the type TYPE after an operator.  In Visual state, this is
+          the type of the selection.
+
+     ':extend-selection EXTEND-SELECTION'
+          If EXTEND-SELECTION is 't' (the default), then the text object
+          always enlarges the current selection.  If 'nil', then the
+          object replaces the selection.
+
+     The keyword arguments are followed by the BODY, which should
+     evaluate to a list '(BEG END)' of two positions in the buffer.  For
+     example, a text object which selects three characters following the
+     current position could be defined as:
+
+          (evil-define-text-object foo (count)
+            "Select three characters."
+            (list (point) (+ (point) 3)))
+
+Evil provides several functions which return a list of positions, for
+use in the definition of a text object.  These functions follow the rule
+that a positive COUNT selects text after the current position, while a
+negative COUNT selects text before it.
+
+ -- Function: evil-inner-object-range count forward backward
+     Return a text range '(BEG END)' of COUNT "inner" text objects
+     (e.g., 'iw', 'is').  FORWARD is a function which moves to the end
+     of an object, and BACKWARD is a function which moves to the
+     beginning.
+
+ -- Function: evil-an-object-range count forward backward
+     Return a text range '(BEG END)' of COUNT text objects with
+     whitespace (e.g., 'aw', 'as').  FORWARD is a function which moves
+     to the end of an object, and BACKWARD is a function which moves to
+     the beginning.
+
+ -- Function: evil-paren-range count open close &optional exclusive
+     Return a text range '(BEG END)' of COUNT delimited blocks (e.g.,
+     'i(', 'a(').  OPEN and CLOSE are characters.  If EXCLUSIVE is
+     non-nil, then the delimiters are excluded from the range.  This
+     function uses Emacs' syntax table and is only applicable for
+     single-character delimiters; use 'evil-regexp-range' to match
+     multiple characters.
+
+ -- Function: evil-regexp-range count open close &optional exclusive
+     Return a text range '(BEG END)' of COUNT delimited blocks (e.g.,
+     'it', 'at').  OPEN and CLOSE are regular expressions.  If EXCLUSIVE
+     is non-nil, then the delimiters are excluded from the range.
+
+
+File: evil.info,  Node: Types,  Next: States,  Prev: Text objects,  Up: Macros
+
+5.4 Types
+=========
+
+A "type" is a transformation on a pair of buffer positions.  Evil
+defines the types 'exclusive', 'inclusive', 'line' and 'block', which
+are used for motion ranges and Visual selection.  Types are defined with
+the macro 'evil-define-type'.
+
+ -- Macro: evil-define-type type doc keyword-args...
+     Define a type TYPE, described by the documentation string DOC.
+     Then follows keyword arguments:
+
+     ':expand EXPAND'
+          A function which takes two buffer positions and returns a list
+          '(BEG END)' of expanded positions.
+
+     ':contract CONTRACT'
+          A function which takes two expanded buffer positions and
+          returns a list '(BEG END)' of unexpanded positions.  Optional.
+
+     ':normalize NORMALIZE'
+          A function which takes two unexpanded buffer positions and
+          returns a list '(BEG END)' of adjusted positions.  Optional.
+
+     ':injective INJECTIVE'
+          If 't' (the default), then expansion is one-to-one - i.e.,
+          EXPAND followed by CONTRACT always returns the original
+          positions.  If 'nil', then several positions may expand to the
+          same (for example, the 'line' type is one-to-many as it
+          expands to the containing lines).
+
+     Further keywords and functions may be specified.  These are
+     understood to be transformations on buffer positions, like EXPAND
+     and CONTRACT.
+
+
+File: evil.info,  Node: States,  Prev: Types,  Up: Macros
+
+5.5 States
+==========
+
+States are defined with the macro 'evil-define-state'.  The macro
+defines the necessary hooks, keymaps and variables for a state, as well
+as a toggle function 'evil-STATE-state' for entering the state, and a
+predicate function 'evil-STATE-state-p' which returns 't' when the state
+is active, and 'nil' otherwise.
+
+ -- Macro: evil-define-state state doc keyword-args... body...
+     Define an Evil state STATE, described by the documentation string
+     DOC.  Then follows optional keyword arguments:
+
+     ':tag TAG'
+          Mode line indicitor, e.g., '"<T>"'.
+     ':message MESSAGE'
+          String shown in the echo area.
+     ':cursor CURSOR'
+          Cursor specification.
+     ':enable ENABLE'
+          List of other modes and states to enable.  A state may enable
+          another state's keymaps in addition to its own.
+
+     This is followed the BODY, which is executed whenever the state is
+     enabled or disabled.  The state's predicate function may be used to
+     distinguish between the two.
+
+
+File: evil.info,  Node: Other internals,  Next: GNU Free Documentation License,  Prev: Macros,  Up: Top
+
+6 Other internals
+*****************
+
+* Menu:
+
+* Command properties::
+
+
+File: evil.info,  Node: Command properties,  Up: Other internals
+
+6.1 Command properties
+======================
+
+Evil defines "command properties" to store information about commands,
+such as whether they should be repeated.  A command property is a
+':KEYWORD' with an associated value, e.g., ':repeat nil'.
+
+ -- Function: evil-add-command-properties command &rest properties
+     Add PROPERTIES to COMMAND.  The properties should be specified as a
+     list of keywords and values:
+
+          (evil-add-command-properties 'my-command :repeat t)
+
+ -- Function: evil-set-command-properties command &rest properties
+     Like 'evil-add-command-properties', but resets all previous
+     properties.
+
+ -- Function: evil-get-command-property command property
+     Return the value of a command property.
+
+ -- Macro: evil-define-command command (args...) doc keyword-args...
+          body...
+     Define a command with command properties KEYWORD-ARGS.
+
+For setting repeat properties, Evil provides the following functions:
+
+ -- Function: evil-declare-repeat command
+     Declare COMMAND to be repeatable.
+
+ -- Function: evil-declare-not-repeat command
+     Declare COMMAND to be nonrepeatable.
+
+ -- Function: evil-declare-change-repeat command
+     Declare COMMAND to be repeatable by buffer changes rather than
+     keystrokes.
+
+
+File: evil.info,  Node: GNU Free Documentation License,  Prev: Other internals,  Up: Top
+
+Appendix A GNU Free Documentation License
+*****************************************
+
+                     Version 1.3, 3 November 2008
+
+     Copyright  2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc.
+     <http://fsf.org/>
+
+     Everyone is permitted to copy and distribute verbatim copies
+     of this license document, but changing it is not allowed.
+
+  0. PREAMBLE
+
+     The purpose of this License is to make a manual, textbook, or other
+     functional and useful document "free" in the sense of freedom: to
+     assure everyone the effective freedom to copy and redistribute it,
+     with or without modifying it, either commercially or
+     noncommercially.  Secondarily, this License preserves for the
+     author and publisher a way to get credit for their work, while not
+     being considered responsible for modifications made by others.
+
+     This License is a kind of "copyleft", which means that derivative
+     works of the document must themselves be free in the same sense.
+     It complements the GNU General Public License, which is a copyleft
+     license designed for free software.
+
+     We have designed this License in order to use it for manuals for
+     free software, because free software needs free documentation: a
+     free program should come with manuals providing the same freedoms
+     that the software does.  But this License is not limited to
+     software manuals; it can be used for any textual work, regardless
+     of subject matter or whether it is published as a printed book.  We
+     recommend this License principally for works whose purpose is
+     instruction or reference.
+
+  1. APPLICABILITY AND DEFINITIONS
+
+     This License applies to any manual or other work, in any medium,
+     that contains a notice placed by the copyright holder saying it can
+     be distributed under the terms of this License.  Such a notice
+     grants a world-wide, royalty-free license, unlimited in duration,
+     to use that work under the conditions stated herein.  The
+     "Document", below, refers to any such manual or work.  Any member
+     of the public is a licensee, and is addressed as "you".  You accept
+     the license if you copy, modify or distribute the work in a way
+     requiring permission under copyright law.
+
+     A "Modified Version" of the Document means any work containing the
+     Document or a portion of it, either copied verbatim, or with
+     modifications and/or translated into another language.
+
+     A "Secondary Section" is a named appendix or a front-matter section
+     of the Document that deals exclusively with the relationship of the
+     publishers or authors of the Document to the Document's overall
+     subject (or to related matters) and contains nothing that could
+     fall directly within that overall subject.  (Thus, if the Document
+     is in part a textbook of mathematics, a Secondary Section may not
+     explain any mathematics.)  The relationship could be a matter of
+     historical connection with the subject or with related matters, or
+     of legal, commercial, philosophical, ethical or political position
+     regarding them.
+
+     The "Invariant Sections" are certain Secondary Sections whose
+     titles are designated, as being those of Invariant Sections, in the
+     notice that says that the Document is released under this License.
+     If a section does not fit the above definition of Secondary then it
+     is not allowed to be designated as Invariant.  The Document may
+     contain zero Invariant Sections.  If the Document does not identify
+     any Invariant Sections then there are none.
+
+     The "Cover Texts" are certain short passages of text that are
+     listed, as Front-Cover Texts or Back-Cover Texts, in the notice
+     that says that the Document is released under this License.  A
+     Front-Cover Text may be at most 5 words, and a Back-Cover Text may
+     be at most 25 words.
+
+     A "Transparent" copy of the Document means a machine-readable copy,
+     represented in a format whose specification is available to the
+     general public, that is suitable for revising the document
+     straightforwardly with generic text editors or (for images composed
+     of pixels) generic paint programs or (for drawings) some widely
+     available drawing editor, and that is suitable for input to text
+     formatters or for automatic translation to a variety of formats
+     suitable for input to text formatters.  A copy made in an otherwise
+     Transparent file format whose markup, or absence of markup, has
+     been arranged to thwart or discourage subsequent modification by
+     readers is not Transparent.  An image format is not Transparent if
+     used for any substantial amount of text.  A copy that is not
+     "Transparent" is called "Opaque".
+
+     Examples of suitable formats for Transparent copies include plain
+     ASCII without markup, Texinfo input format, LaTeX input format,
+     SGML or XML using a publicly available DTD, and standard-conforming
+     simple HTML, PostScript or PDF designed for human modification.
+     Examples of transparent image formats include PNG, XCF and JPG.
+     Opaque formats include proprietary formats that can be read and
+     edited only by proprietary word processors, SGML or XML for which
+     the DTD and/or processing tools are not generally available, and
+     the machine-generated HTML, PostScript or PDF produced by some word
+     processors for output purposes only.
+
+     The "Title Page" means, for a printed book, the title page itself,
+     plus such following pages as are needed to hold, legibly, the
+     material this License requires to appear in the title page.  For
+     works in formats which do not have any title page as such, "Title
+     Page" means the text near the most prominent appearance of the
+     work's title, preceding the beginning of the body of the text.
+
+     The "publisher" means any person or entity that distributes copies
+     of the Document to the public.
+
+     A section "Entitled XYZ" means a named subunit of the Document
+     whose title either is precisely XYZ or contains XYZ in parentheses
+     following text that translates XYZ in another language.  (Here XYZ
+     stands for a specific section name mentioned below, such as
+     "Acknowledgements", "Dedications", "Endorsements", or "History".)
+     To "Preserve the Title" of such a section when you modify the
+     Document means that it remains a section "Entitled XYZ" according
+     to this definition.
+
+     The Document may include Warranty Disclaimers next to the notice
+     which states that this License applies to the Document.  These
+     Warranty Disclaimers are considered to be included by reference in
+     this License, but only as regards disclaiming warranties: any other
+     implication that these Warranty Disclaimers may have is void and
+     has no effect on the meaning of this License.
+
+  2. VERBATIM COPYING
+
+     You may copy and distribute the Document in any medium, either
+     commercially or noncommercially, provided that this License, the
+     copyright notices, and the license notice saying this License
+     applies to the Document are reproduced in all copies, and that you
+     add no other conditions whatsoever to those of this License.  You
+     may not use technical measures to obstruct or control the reading
+     or further copying of the copies you make or distribute.  However,
+     you may accept compensation in exchange for copies.  If you
+     distribute a large enough number of copies you must also follow the
+     conditions in section 3.
+
+     You may also lend copies, under the same conditions stated above,
+     and you may publicly display copies.
+
+  3. COPYING IN QUANTITY
+
+     If you publish printed copies (or copies in media that commonly
+     have printed covers) of the Document, numbering more than 100, and
+     the Document's license notice requires Cover Texts, you must
+     enclose the copies in covers that carry, clearly and legibly, all
+     these Cover Texts: Front-Cover Texts on the front cover, and
+     Back-Cover Texts on the back cover.  Both covers must also clearly
+     and legibly identify you as the publisher of these copies.  The
+     front cover must present the full title with all words of the title
+     equally prominent and visible.  You may add other material on the
+     covers in addition.  Copying with changes limited to the covers, as
+     long as they preserve the title of the Document and satisfy these
+     conditions, can be treated as verbatim copying in other respects.
+
+     If the required texts for either cover are too voluminous to fit
+     legibly, you should put the first ones listed (as many as fit
+     reasonably) on the actual cover, and continue the rest onto
+     adjacent pages.
+
+     If you publish or distribute Opaque copies of the Document
+     numbering more than 100, you must either include a machine-readable
+     Transparent copy along with each Opaque copy, or state in or with
+     each Opaque copy a computer-network location from which the general
+     network-using public has access to download using public-standard
+     network protocols a complete Transparent copy of the Document, free
+     of added material.  If you use the latter option, you must take
+     reasonably prudent steps, when you begin distribution of Opaque
+     copies in quantity, to ensure that this Transparent copy will
+     remain thus accessible at the stated location until at least one
+     year after the last time you distribute an Opaque copy (directly or
+     through your agents or retailers) of that edition to the public.
+
+     It is requested, but not required, that you contact the authors of
+     the Document well before redistributing any large number of copies,
+     to give them a chance to provide you with an updated version of the
+     Document.
+
+  4. MODIFICATIONS
+
+     You may copy and distribute a Modified Version of the Document
+     under the conditions of sections 2 and 3 above, provided that you
+     release the Modified Version under precisely this License, with the
+     Modified Version filling the role of the Document, thus licensing
+     distribution and modification of the Modified Version to whoever
+     possesses a copy of it.  In addition, you must do these things in
+     the Modified Version:
+
+       A. Use in the Title Page (and on the covers, if any) a title
+          distinct from that of the Document, and from those of previous
+          versions (which should, if there were any, be listed in the
+          History section of the Document).  You may use the same title
+          as a previous version if the original publisher of that
+          version gives permission.
+
+       B. List on the Title Page, as authors, one or more persons or
+          entities responsible for authorship of the modifications in
+          the Modified Version, together with at least five of the
+          principal authors of the Document (all of its principal
+          authors, if it has fewer than five), unless they release you
+          from this requirement.
+
+       C. State on the Title page the name of the publisher of the
+          Modified Version, as the publisher.
+
+       D. Preserve all the copyright notices of the Document.
+
+       E. Add an appropriate copyright notice for your modifications
+          adjacent to the other copyright notices.
+
+       F. Include, immediately after the copyright notices, a license
+          notice giving the public permission to use the Modified
+          Version under the terms of this License, in the form shown in
+          the Addendum below.
+
+       G. Preserve in that license notice the full lists of Invariant
+          Sections and required Cover Texts given in the Document's
+          license notice.
+
+       H. Include an unaltered copy of this License.
+
+       I. Preserve the section Entitled "History", Preserve its Title,
+          and add to it an item stating at least the title, year, new
+          authors, and publisher of the Modified Version as given on the
+          Title Page.  If there is no section Entitled "History" in the
+          Document, create one stating the title, year, authors, and
+          publisher of the Document as given on its Title Page, then add
+          an item describing the Modified Version as stated in the
+          previous sentence.
+
+       J. Preserve the network location, if any, given in the Document
+          for public access to a Transparent copy of the Document, and
+          likewise the network locations given in the Document for
+          previous versions it was based on.  These may be placed in the
+          "History" section.  You may omit a network location for a work
+          that was published at least four years before the Document
+          itself, or if the original publisher of the version it refers
+          to gives permission.
+
+       K. For any section Entitled "Acknowledgements" or "Dedications",
+          Preserve the Title of the section, and preserve in the section
+          all the substance and tone of each of the contributor
+          acknowledgements and/or dedications given therein.
+
+       L. Preserve all the Invariant Sections of the Document, unaltered
+          in their text and in their titles.  Section numbers or the
+          equivalent are not considered part of the section titles.
+
+       M. Delete any section Entitled "Endorsements".  Such a section
+          may not be included in the Modified Version.
+
+       N. Do not retitle any existing section to be Entitled
+          "Endorsements" or to conflict in title with any Invariant
+          Section.
+
+       O. Preserve any Warranty Disclaimers.
+
+     If the Modified Version includes new front-matter sections or
+     appendices that qualify as Secondary Sections and contain no
+     material copied from the Document, you may at your option designate
+     some or all of these sections as invariant.  To do this, add their
+     titles to the list of Invariant Sections in the Modified Version's
+     license notice.  These titles must be distinct from any other
+     section titles.
+
+     You may add a section Entitled "Endorsements", provided it contains
+     nothing but endorsements of your Modified Version by various
+     parties--for example, statements of peer review or that the text
+     has been approved by an organization as the authoritative
+     definition of a standard.
+
+     You may add a passage of up to five words as a Front-Cover Text,
+     and a passage of up to 25 words as a Back-Cover Text, to the end of
+     the list of Cover Texts in the Modified Version.  Only one passage
+     of Front-Cover Text and one of Back-Cover Text may be added by (or
+     through arrangements made by) any one entity.  If the Document
+     already includes a cover text for the same cover, previously added
+     by you or by arrangement made by the same entity you are acting on
+     behalf of, you may not add another; but you may replace the old
+     one, on explicit permission from the previous publisher that added
+     the old one.
+
+     The author(s) and publisher(s) of the Document do not by this
+     License give permission to use their names for publicity for or to
+     assert or imply endorsement of any Modified Version.
+
+  5. COMBINING DOCUMENTS
+
+     You may combine the Document with other documents released under
+     this License, under the terms defined in section 4 above for
+     modified versions, provided that you include in the combination all
+     of the Invariant Sections of all of the original documents,
+     unmodified, and list them all as Invariant Sections of your
+     combined work in its license notice, and that you preserve all
+     their Warranty Disclaimers.
+
+     The combined work need only contain one copy of this License, and
+     multiple identical Invariant Sections may be replaced with a single
+     copy.  If there are multiple Invariant Sections with the same name
+     but different contents, make the title of each such section unique
+     by adding at the end of it, in parentheses, the name of the
+     original author or publisher of that section if known, or else a
+     unique number.  Make the same adjustment to the section titles in
+     the list of Invariant Sections in the license notice of the
+     combined work.
+
+     In the combination, you must combine any sections Entitled
+     "History" in the various original documents, forming one section
+     Entitled "History"; likewise combine any sections Entitled
+     "Acknowledgements", and any sections Entitled "Dedications".  You
+     must delete all sections Entitled "Endorsements."
+
+  6. COLLECTIONS OF DOCUMENTS
+
+     You may make a collection consisting of the Document and other
+     documents released under this License, and replace the individual
+     copies of this License in the various documents with a single copy
+     that is included in the collection, provided that you follow the
+     rules of this License for verbatim copying of each of the documents
+     in all other respects.
+
+     You may extract a single document from such a collection, and
+     distribute it individually under this License, provided you insert
+     a copy of this License into the extracted document, and follow this
+     License in all other respects regarding verbatim copying of that
+     document.
+
+  7. AGGREGATION WITH INDEPENDENT WORKS
+
+     A compilation of the Document or its derivatives with other
+     separate and independent documents or works, in or on a volume of a
+     storage or distribution medium, is called an "aggregate" if the
+     copyright resulting from the compilation is not used to limit the
+     legal rights of the compilation's users beyond what the individual
+     works permit.  When the Document is included in an aggregate, this
+     License does not apply to the other works in the aggregate which
+     are not themselves derivative works of the Document.
+
+     If the Cover Text requirement of section 3 is applicable to these
+     copies of the Document, then if the Document is less than one half
+     of the entire aggregate, the Document's Cover Texts may be placed
+     on covers that bracket the Document within the aggregate, or the
+     electronic equivalent of covers if the Document is in electronic
+     form.  Otherwise they must appear on printed covers that bracket
+     the whole aggregate.
+
+  8. TRANSLATION
+
+     Translation is considered a kind of modification, so you may
+     distribute translations of the Document under the terms of section
+     4.  Replacing Invariant Sections with translations requires special
+     permission from their copyright holders, but you may include
+     translations of some or all Invariant Sections in addition to the
+     original versions of these Invariant Sections.  You may include a
+     translation of this License, and all the license notices in the
+     Document, and any Warranty Disclaimers, provided that you also
+     include the original English version of this License and the
+     original versions of those notices and disclaimers.  In case of a
+     disagreement between the translation and the original version of
+     this License or a notice or disclaimer, the original version will
+     prevail.
+
+     If a section in the Document is Entitled "Acknowledgements",
+     "Dedications", or "History", the requirement (section 4) to
+     Preserve its Title (section 1) will typically require changing the
+     actual title.
+
+  9. TERMINATION
+
+     You may not copy, modify, sublicense, or distribute the Document
+     except as expressly provided under this License.  Any attempt
+     otherwise to copy, modify, sublicense, or distribute it is void,
+     and will automatically terminate your rights under this License.
+
+     However, if you cease all violation of this License, then your
+     license from a particular copyright holder is reinstated (a)
+     provisionally, unless and until the copyright holder explicitly and
+     finally terminates your license, and (b) permanently, if the
+     copyright holder fails to notify you of the violation by some
+     reasonable means prior to 60 days after the cessation.
+
+     Moreover, your license from a particular copyright holder is
+     reinstated permanently if the copyright holder notifies you of the
+     violation by some reasonable means, this is the first time you have
+     received notice of violation of this License (for any work) from
+     that copyright holder, and you cure the violation prior to 30 days
+     after your receipt of the notice.
+
+     Termination of your rights under this section does not terminate
+     the licenses of parties who have received copies or rights from you
+     under this License.  If your rights have been terminated and not
+     permanently reinstated, receipt of a copy of some or all of the
+     same material does not give you any rights to use it.
+
+  10. FUTURE REVISIONS OF THIS LICENSE
+
+     The Free Software Foundation may publish new, revised versions of
+     the GNU Free Documentation License from time to time.  Such new
+     versions will be similar in spirit to the present version, but may
+     differ in detail to address new problems or concerns.  See
+     <http://www.gnu.org/copyleft/>.
+
+     Each version of the License is given a distinguishing version
+     number.  If the Document specifies that a particular numbered
+     version of this License "or any later version" applies to it, you
+     have the option of following the terms and conditions either of
+     that specified version or of any later version that has been
+     published (not as a draft) by the Free Software Foundation.  If the
+     Document does not specify a version number of this License, you may
+     choose any version ever published (not as a draft) by the Free
+     Software Foundation.  If the Document specifies that a proxy can
+     decide which future versions of this License can be used, that
+     proxy's public statement of acceptance of a version permanently
+     authorizes you to choose that version for the Document.
+
+  11. RELICENSING
+
+     "Massive Multiauthor Collaboration Site" (or "MMC Site") means any
+     World Wide Web server that publishes copyrightable works and also
+     provides prominent facilities for anybody to edit those works.  A
+     public wiki that anybody can edit is an example of such a server.
+     A "Massive Multiauthor Collaboration" (or "MMC") contained in the
+     site means any set of copyrightable works thus published on the MMC
+     site.
+
+     "CC-BY-SA" means the Creative Commons Attribution-Share Alike 3.0
+     license published by Creative Commons Corporation, a not-for-profit
+     corporation with a principal place of business in San Francisco,
+     California, as well as future copyleft versions of that license
+     published by that same organization.
+
+     "Incorporate" means to publish or republish a Document, in whole or
+     in part, as part of another Document.
+
+     An MMC is "eligible for relicensing" if it is licensed under this
+     License, and if all works that were first published under this
+     License somewhere other than this MMC, and subsequently
+     incorporated in whole or in part into the MMC, (1) had no cover
+     texts or invariant sections, and (2) were thus incorporated prior
+     to November 1, 2008.
+
+     The operator of an MMC Site may republish an MMC contained in the
+     site under CC-BY-SA on the same site at any time before August 1,
+     2009, provided the MMC is eligible for relicensing.
+
+ADDENDUM: How to use this License for your documents
+====================================================
+
+To use this License in a document you have written, include a copy of
+the License in the document and put the following copyright and license
+notices just after the title page:
+
+       Copyright (C)  YEAR  YOUR NAME.
+       Permission is granted to copy, distribute and/or modify this document
+       under the terms of the GNU Free Documentation License, Version 1.3
+       or any later version published by the Free Software Foundation;
+       with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
+       Texts.  A copy of the license is included in the section entitled ``GNU
+       Free Documentation License''.
+
+   If you have Invariant Sections, Front-Cover Texts and Back-Cover
+Texts, replace the "with...Texts."  line with this:
+
+         with the Invariant Sections being LIST THEIR TITLES, with
+         the Front-Cover Texts being LIST, and with the Back-Cover Texts
+         being LIST.
+
+   If you have Invariant Sections without Cover Texts, or some other
+combination of the three, merge those two alternatives to suit the
+situation.
+
+   If your document contains nontrivial examples of program code, we
+recommend releasing these examples in parallel under your choice of free
+software license, such as the GNU General Public License, to permit
+their use in free software.
+
+
+
+Tag Table:
+Node: Top819
+Node: Overview1092
+Ref: Overview-Footnote-11440
+Node: Installation1668
+Ref: Installation-Footnote-12272
+Node: Modes and states2322
+Node: Settings3375
+Ref: Settings-Footnote-15826
+Node: The cursor5983
+Node: The initial state7188
+Node: Keymaps7647
+Node: evil-define-key9509
+Node: Hooks10693
+Node: Macros12215
+Node: Motions12495
+Node: Operators14432
+Node: Text objects16765
+Node: Types19778
+Node: States21260
+Node: Other internals22359
+Node: Command properties22536
+Node: GNU Free Documentation License23863
+
+End Tag Table
+
+
+Local Variables:
+coding: iso-8859-1
+End:
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/fdl-1.3.info b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/fdl-1.3.info
new file mode 100644
index 0000000000..0ad10e9eda
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/fdl-1.3.info
@@ -0,0 +1,484 @@
+This is fdl-1.3.info, produced by makeinfo version 6.1 from
+fdl-1.3.texi.
+
+                     Version 1.3, 3 November 2008
+
+     Copyright (C) 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc.
+     <http://fsf.org/>
+
+     Everyone is permitted to copy and distribute verbatim copies
+     of this license document, but changing it is not allowed.
+
+  0. PREAMBLE
+
+     The purpose of this License is to make a manual, textbook, or other
+     functional and useful document "free" in the sense of freedom: to
+     assure everyone the effective freedom to copy and redistribute it,
+     with or without modifying it, either commercially or
+     noncommercially.  Secondarily, this License preserves for the
+     author and publisher a way to get credit for their work, while not
+     being considered responsible for modifications made by others.
+
+     This License is a kind of "copyleft", which means that derivative
+     works of the document must themselves be free in the same sense.
+     It complements the GNU General Public License, which is a copyleft
+     license designed for free software.
+
+     We have designed this License in order to use it for manuals for
+     free software, because free software needs free documentation: a
+     free program should come with manuals providing the same freedoms
+     that the software does.  But this License is not limited to
+     software manuals; it can be used for any textual work, regardless
+     of subject matter or whether it is published as a printed book.  We
+     recommend this License principally for works whose purpose is
+     instruction or reference.
+
+  1. APPLICABILITY AND DEFINITIONS
+
+     This License applies to any manual or other work, in any medium,
+     that contains a notice placed by the copyright holder saying it can
+     be distributed under the terms of this License.  Such a notice
+     grants a world-wide, royalty-free license, unlimited in duration,
+     to use that work under the conditions stated herein.  The
+     "Document", below, refers to any such manual or work.  Any member
+     of the public is a licensee, and is addressed as "you".  You accept
+     the license if you copy, modify or distribute the work in a way
+     requiring permission under copyright law.
+
+     A "Modified Version" of the Document means any work containing the
+     Document or a portion of it, either copied verbatim, or with
+     modifications and/or translated into another language.
+
+     A "Secondary Section" is a named appendix or a front-matter section
+     of the Document that deals exclusively with the relationship of the
+     publishers or authors of the Document to the Document's overall
+     subject (or to related matters) and contains nothing that could
+     fall directly within that overall subject.  (Thus, if the Document
+     is in part a textbook of mathematics, a Secondary Section may not
+     explain any mathematics.)  The relationship could be a matter of
+     historical connection with the subject or with related matters, or
+     of legal, commercial, philosophical, ethical or political position
+     regarding them.
+
+     The "Invariant Sections" are certain Secondary Sections whose
+     titles are designated, as being those of Invariant Sections, in the
+     notice that says that the Document is released under this License.
+     If a section does not fit the above definition of Secondary then it
+     is not allowed to be designated as Invariant.  The Document may
+     contain zero Invariant Sections.  If the Document does not identify
+     any Invariant Sections then there are none.
+
+     The "Cover Texts" are certain short passages of text that are
+     listed, as Front-Cover Texts or Back-Cover Texts, in the notice
+     that says that the Document is released under this License.  A
+     Front-Cover Text may be at most 5 words, and a Back-Cover Text may
+     be at most 25 words.
+
+     A "Transparent" copy of the Document means a machine-readable copy,
+     represented in a format whose specification is available to the
+     general public, that is suitable for revising the document
+     straightforwardly with generic text editors or (for images composed
+     of pixels) generic paint programs or (for drawings) some widely
+     available drawing editor, and that is suitable for input to text
+     formatters or for automatic translation to a variety of formats
+     suitable for input to text formatters.  A copy made in an otherwise
+     Transparent file format whose markup, or absence of markup, has
+     been arranged to thwart or discourage subsequent modification by
+     readers is not Transparent.  An image format is not Transparent if
+     used for any substantial amount of text.  A copy that is not
+     "Transparent" is called "Opaque".
+
+     Examples of suitable formats for Transparent copies include plain
+     ASCII without markup, Texinfo input format, LaTeX input format,
+     SGML or XML using a publicly available DTD, and standard-conforming
+     simple HTML, PostScript or PDF designed for human modification.
+     Examples of transparent image formats include PNG, XCF and JPG.
+     Opaque formats include proprietary formats that can be read and
+     edited only by proprietary word processors, SGML or XML for which
+     the DTD and/or processing tools are not generally available, and
+     the machine-generated HTML, PostScript or PDF produced by some word
+     processors for output purposes only.
+
+     The "Title Page" means, for a printed book, the title page itself,
+     plus such following pages as are needed to hold, legibly, the
+     material this License requires to appear in the title page.  For
+     works in formats which do not have any title page as such, "Title
+     Page" means the text near the most prominent appearance of the
+     work's title, preceding the beginning of the body of the text.
+
+     The "publisher" means any person or entity that distributes copies
+     of the Document to the public.
+
+     A section "Entitled XYZ" means a named subunit of the Document
+     whose title either is precisely XYZ or contains XYZ in parentheses
+     following text that translates XYZ in another language.  (Here XYZ
+     stands for a specific section name mentioned below, such as
+     "Acknowledgements", "Dedications", "Endorsements", or "History".)
+     To "Preserve the Title" of such a section when you modify the
+     Document means that it remains a section "Entitled XYZ" according
+     to this definition.
+
+     The Document may include Warranty Disclaimers next to the notice
+     which states that this License applies to the Document.  These
+     Warranty Disclaimers are considered to be included by reference in
+     this License, but only as regards disclaiming warranties: any other
+     implication that these Warranty Disclaimers may have is void and
+     has no effect on the meaning of this License.
+
+  2. VERBATIM COPYING
+
+     You may copy and distribute the Document in any medium, either
+     commercially or noncommercially, provided that this License, the
+     copyright notices, and the license notice saying this License
+     applies to the Document are reproduced in all copies, and that you
+     add no other conditions whatsoever to those of this License.  You
+     may not use technical measures to obstruct or control the reading
+     or further copying of the copies you make or distribute.  However,
+     you may accept compensation in exchange for copies.  If you
+     distribute a large enough number of copies you must also follow the
+     conditions in section 3.
+
+     You may also lend copies, under the same conditions stated above,
+     and you may publicly display copies.
+
+  3. COPYING IN QUANTITY
+
+     If you publish printed copies (or copies in media that commonly
+     have printed covers) of the Document, numbering more than 100, and
+     the Document's license notice requires Cover Texts, you must
+     enclose the copies in covers that carry, clearly and legibly, all
+     these Cover Texts: Front-Cover Texts on the front cover, and
+     Back-Cover Texts on the back cover.  Both covers must also clearly
+     and legibly identify you as the publisher of these copies.  The
+     front cover must present the full title with all words of the title
+     equally prominent and visible.  You may add other material on the
+     covers in addition.  Copying with changes limited to the covers, as
+     long as they preserve the title of the Document and satisfy these
+     conditions, can be treated as verbatim copying in other respects.
+
+     If the required texts for either cover are too voluminous to fit
+     legibly, you should put the first ones listed (as many as fit
+     reasonably) on the actual cover, and continue the rest onto
+     adjacent pages.
+
+     If you publish or distribute Opaque copies of the Document
+     numbering more than 100, you must either include a machine-readable
+     Transparent copy along with each Opaque copy, or state in or with
+     each Opaque copy a computer-network location from which the general
+     network-using public has access to download using public-standard
+     network protocols a complete Transparent copy of the Document, free
+     of added material.  If you use the latter option, you must take
+     reasonably prudent steps, when you begin distribution of Opaque
+     copies in quantity, to ensure that this Transparent copy will
+     remain thus accessible at the stated location until at least one
+     year after the last time you distribute an Opaque copy (directly or
+     through your agents or retailers) of that edition to the public.
+
+     It is requested, but not required, that you contact the authors of
+     the Document well before redistributing any large number of copies,
+     to give them a chance to provide you with an updated version of the
+     Document.
+
+  4. MODIFICATIONS
+
+     You may copy and distribute a Modified Version of the Document
+     under the conditions of sections 2 and 3 above, provided that you
+     release the Modified Version under precisely this License, with the
+     Modified Version filling the role of the Document, thus licensing
+     distribution and modification of the Modified Version to whoever
+     possesses a copy of it.  In addition, you must do these things in
+     the Modified Version:
+
+       A. Use in the Title Page (and on the covers, if any) a title
+          distinct from that of the Document, and from those of previous
+          versions (which should, if there were any, be listed in the
+          History section of the Document).  You may use the same title
+          as a previous version if the original publisher of that
+          version gives permission.
+
+       B. List on the Title Page, as authors, one or more persons or
+          entities responsible for authorship of the modifications in
+          the Modified Version, together with at least five of the
+          principal authors of the Document (all of its principal
+          authors, if it has fewer than five), unless they release you
+          from this requirement.
+
+       C. State on the Title page the name of the publisher of the
+          Modified Version, as the publisher.
+
+       D. Preserve all the copyright notices of the Document.
+
+       E. Add an appropriate copyright notice for your modifications
+          adjacent to the other copyright notices.
+
+       F. Include, immediately after the copyright notices, a license
+          notice giving the public permission to use the Modified
+          Version under the terms of this License, in the form shown in
+          the Addendum below.
+
+       G. Preserve in that license notice the full lists of Invariant
+          Sections and required Cover Texts given in the Document's
+          license notice.
+
+       H. Include an unaltered copy of this License.
+
+       I. Preserve the section Entitled "History", Preserve its Title,
+          and add to it an item stating at least the title, year, new
+          authors, and publisher of the Modified Version as given on the
+          Title Page.  If there is no section Entitled "History" in the
+          Document, create one stating the title, year, authors, and
+          publisher of the Document as given on its Title Page, then add
+          an item describing the Modified Version as stated in the
+          previous sentence.
+
+       J. Preserve the network location, if any, given in the Document
+          for public access to a Transparent copy of the Document, and
+          likewise the network locations given in the Document for
+          previous versions it was based on.  These may be placed in the
+          "History" section.  You may omit a network location for a work
+          that was published at least four years before the Document
+          itself, or if the original publisher of the version it refers
+          to gives permission.
+
+       K. For any section Entitled "Acknowledgements" or "Dedications",
+          Preserve the Title of the section, and preserve in the section
+          all the substance and tone of each of the contributor
+          acknowledgements and/or dedications given therein.
+
+       L. Preserve all the Invariant Sections of the Document, unaltered
+          in their text and in their titles.  Section numbers or the
+          equivalent are not considered part of the section titles.
+
+       M. Delete any section Entitled "Endorsements".  Such a section
+          may not be included in the Modified Version.
+
+       N. Do not retitle any existing section to be Entitled
+          "Endorsements" or to conflict in title with any Invariant
+          Section.
+
+       O. Preserve any Warranty Disclaimers.
+
+     If the Modified Version includes new front-matter sections or
+     appendices that qualify as Secondary Sections and contain no
+     material copied from the Document, you may at your option designate
+     some or all of these sections as invariant.  To do this, add their
+     titles to the list of Invariant Sections in the Modified Version's
+     license notice.  These titles must be distinct from any other
+     section titles.
+
+     You may add a section Entitled "Endorsements", provided it contains
+     nothing but endorsements of your Modified Version by various
+     parties--for example, statements of peer review or that the text
+     has been approved by an organization as the authoritative
+     definition of a standard.
+
+     You may add a passage of up to five words as a Front-Cover Text,
+     and a passage of up to 25 words as a Back-Cover Text, to the end of
+     the list of Cover Texts in the Modified Version.  Only one passage
+     of Front-Cover Text and one of Back-Cover Text may be added by (or
+     through arrangements made by) any one entity.  If the Document
+     already includes a cover text for the same cover, previously added
+     by you or by arrangement made by the same entity you are acting on
+     behalf of, you may not add another; but you may replace the old
+     one, on explicit permission from the previous publisher that added
+     the old one.
+
+     The author(s) and publisher(s) of the Document do not by this
+     License give permission to use their names for publicity for or to
+     assert or imply endorsement of any Modified Version.
+
+  5. COMBINING DOCUMENTS
+
+     You may combine the Document with other documents released under
+     this License, under the terms defined in section 4 above for
+     modified versions, provided that you include in the combination all
+     of the Invariant Sections of all of the original documents,
+     unmodified, and list them all as Invariant Sections of your
+     combined work in its license notice, and that you preserve all
+     their Warranty Disclaimers.
+
+     The combined work need only contain one copy of this License, and
+     multiple identical Invariant Sections may be replaced with a single
+     copy.  If there are multiple Invariant Sections with the same name
+     but different contents, make the title of each such section unique
+     by adding at the end of it, in parentheses, the name of the
+     original author or publisher of that section if known, or else a
+     unique number.  Make the same adjustment to the section titles in
+     the list of Invariant Sections in the license notice of the
+     combined work.
+
+     In the combination, you must combine any sections Entitled
+     "History" in the various original documents, forming one section
+     Entitled "History"; likewise combine any sections Entitled
+     "Acknowledgements", and any sections Entitled "Dedications".  You
+     must delete all sections Entitled "Endorsements."
+
+  6. COLLECTIONS OF DOCUMENTS
+
+     You may make a collection consisting of the Document and other
+     documents released under this License, and replace the individual
+     copies of this License in the various documents with a single copy
+     that is included in the collection, provided that you follow the
+     rules of this License for verbatim copying of each of the documents
+     in all other respects.
+
+     You may extract a single document from such a collection, and
+     distribute it individually under this License, provided you insert
+     a copy of this License into the extracted document, and follow this
+     License in all other respects regarding verbatim copying of that
+     document.
+
+  7. AGGREGATION WITH INDEPENDENT WORKS
+
+     A compilation of the Document or its derivatives with other
+     separate and independent documents or works, in or on a volume of a
+     storage or distribution medium, is called an "aggregate" if the
+     copyright resulting from the compilation is not used to limit the
+     legal rights of the compilation's users beyond what the individual
+     works permit.  When the Document is included in an aggregate, this
+     License does not apply to the other works in the aggregate which
+     are not themselves derivative works of the Document.
+
+     If the Cover Text requirement of section 3 is applicable to these
+     copies of the Document, then if the Document is less than one half
+     of the entire aggregate, the Document's Cover Texts may be placed
+     on covers that bracket the Document within the aggregate, or the
+     electronic equivalent of covers if the Document is in electronic
+     form.  Otherwise they must appear on printed covers that bracket
+     the whole aggregate.
+
+  8. TRANSLATION
+
+     Translation is considered a kind of modification, so you may
+     distribute translations of the Document under the terms of section
+     4.  Replacing Invariant Sections with translations requires special
+     permission from their copyright holders, but you may include
+     translations of some or all Invariant Sections in addition to the
+     original versions of these Invariant Sections.  You may include a
+     translation of this License, and all the license notices in the
+     Document, and any Warranty Disclaimers, provided that you also
+     include the original English version of this License and the
+     original versions of those notices and disclaimers.  In case of a
+     disagreement between the translation and the original version of
+     this License or a notice or disclaimer, the original version will
+     prevail.
+
+     If a section in the Document is Entitled "Acknowledgements",
+     "Dedications", or "History", the requirement (section 4) to
+     Preserve its Title (section 1) will typically require changing the
+     actual title.
+
+  9. TERMINATION
+
+     You may not copy, modify, sublicense, or distribute the Document
+     except as expressly provided under this License.  Any attempt
+     otherwise to copy, modify, sublicense, or distribute it is void,
+     and will automatically terminate your rights under this License.
+
+     However, if you cease all violation of this License, then your
+     license from a particular copyright holder is reinstated (a)
+     provisionally, unless and until the copyright holder explicitly and
+     finally terminates your license, and (b) permanently, if the
+     copyright holder fails to notify you of the violation by some
+     reasonable means prior to 60 days after the cessation.
+
+     Moreover, your license from a particular copyright holder is
+     reinstated permanently if the copyright holder notifies you of the
+     violation by some reasonable means, this is the first time you have
+     received notice of violation of this License (for any work) from
+     that copyright holder, and you cure the violation prior to 30 days
+     after your receipt of the notice.
+
+     Termination of your rights under this section does not terminate
+     the licenses of parties who have received copies or rights from you
+     under this License.  If your rights have been terminated and not
+     permanently reinstated, receipt of a copy of some or all of the
+     same material does not give you any rights to use it.
+
+  10. FUTURE REVISIONS OF THIS LICENSE
+
+     The Free Software Foundation may publish new, revised versions of
+     the GNU Free Documentation License from time to time.  Such new
+     versions will be similar in spirit to the present version, but may
+     differ in detail to address new problems or concerns.  See
+     <http://www.gnu.org/copyleft/>.
+
+     Each version of the License is given a distinguishing version
+     number.  If the Document specifies that a particular numbered
+     version of this License "or any later version" applies to it, you
+     have the option of following the terms and conditions either of
+     that specified version or of any later version that has been
+     published (not as a draft) by the Free Software Foundation.  If the
+     Document does not specify a version number of this License, you may
+     choose any version ever published (not as a draft) by the Free
+     Software Foundation.  If the Document specifies that a proxy can
+     decide which future versions of this License can be used, that
+     proxy's public statement of acceptance of a version permanently
+     authorizes you to choose that version for the Document.
+
+  11. RELICENSING
+
+     "Massive Multiauthor Collaboration Site" (or "MMC Site") means any
+     World Wide Web server that publishes copyrightable works and also
+     provides prominent facilities for anybody to edit those works.  A
+     public wiki that anybody can edit is an example of such a server.
+     A "Massive Multiauthor Collaboration" (or "MMC") contained in the
+     site means any set of copyrightable works thus published on the MMC
+     site.
+
+     "CC-BY-SA" means the Creative Commons Attribution-Share Alike 3.0
+     license published by Creative Commons Corporation, a not-for-profit
+     corporation with a principal place of business in San Francisco,
+     California, as well as future copyleft versions of that license
+     published by that same organization.
+
+     "Incorporate" means to publish or republish a Document, in whole or
+     in part, as part of another Document.
+
+     An MMC is "eligible for relicensing" if it is licensed under this
+     License, and if all works that were first published under this
+     License somewhere other than this MMC, and subsequently
+     incorporated in whole or in part into the MMC, (1) had no cover
+     texts or invariant sections, and (2) were thus incorporated prior
+     to November 1, 2008.
+
+     The operator of an MMC Site may republish an MMC contained in the
+     site under CC-BY-SA on the same site at any time before August 1,
+     2009, provided the MMC is eligible for relicensing.
+
+ADDENDUM: How to use this License for your documents
+====================================================
+
+To use this License in a document you have written, include a copy of
+the License in the document and put the following copyright and license
+notices just after the title page:
+
+       Copyright (C)  YEAR  YOUR NAME.
+       Permission is granted to copy, distribute and/or modify this document
+       under the terms of the GNU Free Documentation License, Version 1.3
+       or any later version published by the Free Software Foundation;
+       with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
+       Texts.  A copy of the license is included in the section entitled ``GNU
+       Free Documentation License''.
+
+   If you have Invariant Sections, Front-Cover Texts and Back-Cover
+Texts, replace the "with...Texts."  line with this:
+
+         with the Invariant Sections being LIST THEIR TITLES, with
+         the Front-Cover Texts being LIST, and with the Back-Cover Texts
+         being LIST.
+
+   If you have Invariant Sections without Cover Texts, or some other
+combination of the three, merge those two alternatives to suit the
+situation.
+
+   If your document contains nontrivial examples of program code, we
+recommend releasing these examples in parallel under your choice of free
+software license, such as the GNU General Public License, to permit
+their use in free software.
+
+
+
+Tag Table:
+
+End Tag Table
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/macros.info b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/macros.info
new file mode 100644
index 0000000000..ec88a18b02
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/macros.info
@@ -0,0 +1,7 @@
+This is macros.info, produced by makeinfo version 6.1 from macros.texi.
+
+
+
+Tag Table:
+
+End Tag Table
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/version.info b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/version.info
new file mode 100644
index 0000000000..6646e125d6
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-20180517.1300/version.info
@@ -0,0 +1,8 @@
+This is version.info, produced by makeinfo version 6.1 from
+version.texi.
+
+
+
+Tag Table:
+
+End Tag Table
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-ace-jump-mode.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-ace-jump-mode.el
new file mode 100644
index 0000000000..f141b17c03
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-ace-jump-mode.el
@@ -0,0 +1,148 @@
+;;; evil-collection-ace-jump-mode.el --- Bindings for `ace-jump-mode' -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 James Nguyen
+
+;; Author: James Nguyen <james@jojojames.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, emacs, tools
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;; Bindings for `ace-jump-mode'
+
+;;; Code:
+(require 'evil-collection)
+(require 'ace-jump-mode nil t)
+
+(declare-function 'ace-jump-char-mode "ace-jump-mode")
+(declare-function 'ace-jump-word-mode "ace-jump-mode")
+(declare-function 'ace-jump-line-mode "ace-jump-mode")
+
+(defvar evil-collection-ace-jump-mode-jump-active nil)
+
+(defmacro evil-collection-ace-jump-mode-enclose-ace-jump-for-motion (&rest body)
+  "Enclose ace-jump to make it suitable for motions.
+This includes restricting `ace-jump-mode' to the current window
+in visual and operator state, deactivating visual updates, saving
+the mark and entering `recursive-edit'."
+  (declare (indent defun)
+           (debug t))
+  `(let ((old-mark (mark))
+         (ace-jump-mode-scope
+          (if (and (not (memq evil-state '(visual operator)))
+                   (boundp 'ace-jump-mode-scope))
+              ace-jump-mode-scope
+            'window)))
+     (ignore ace-jump-mode-scope) ;; Make byte compiler happy.
+     (remove-hook 'pre-command-hook #'evil-visual-pre-command t)
+     (remove-hook 'post-command-hook #'evil-visual-post-command t)
+     (unwind-protect
+         (let ((evil-collection-ace-jump-mode-jump-active 'prepare))
+           (add-hook 'ace-jump-mode-end-hook
+                     #'evil-collection-ace-jump-mode-jump-exit-recursive-edit)
+           ,@body
+           (when evil-collection-ace-jump-mode-jump-active
+             (setq evil-collection-ace-jump-mode-jump-active t)
+             (recursive-edit)))
+       (remove-hook 'post-command-hook
+                    #'evil-collection-ace-jump-mode-jump-exit-recursive-edit)
+       (remove-hook 'ace-jump-mode-end-hook
+                    #'evil-collection-ace-jump-mode-jump-exit-recursive-edit)
+       (if (evil-visual-state-p)
+           (progn
+             (add-hook 'pre-command-hook #'evil-visual-pre-command nil t)
+             (add-hook 'post-command-hook #'evil-visual-post-command nil t)
+             (set-mark old-mark))
+         (push-mark old-mark)))))
+
+(defun evil-collection-ace-jump-mode-jump-exit-recursive-edit ()
+  "Exit a recursive edit caused by an evil jump."
+  (cond
+   ((eq evil-collection-ace-jump-mode-jump-active 'prepare)
+    (setq evil-collection-ace-jump-mode-jump-active nil))
+   (evil-collection-ace-jump-mode-jump-active
+    (remove-hook 'post-command-hook
+                 #'evil-collection-ace-jump-mode-jump-exit-recursive-edit)
+    (exit-recursive-edit))))
+
+(evil-define-motion evil-ace-jump-char-mode (_)
+  "Jump visually directly to a char using ace-jump."
+  :type inclusive
+  (evil-without-repeat
+    (let ((pnt (point))
+          (buf (current-buffer)))
+      (evil-collection-ace-jump-mode-enclose-ace-jump-for-motion
+       (call-interactively 'ace-jump-char-mode))
+      ;; if we jump backwards, motion type is exclusive, analogously
+      ;; to `evil-find-char-backward'
+      (when (and (equal buf (current-buffer))
+                 (< (point) pnt))
+        (setq evil-this-type
+              (cond
+               ((eq evil-this-type 'exclusive) 'inclusive)
+               ((eq evil-this-type 'inclusive) 'exclusive)))))))
+
+(evil-define-motion evil-ace-jump-char-to-mode (_)
+  "Jump visually to the char in front of a char using ace-jump."
+  :type inclusive
+  (evil-without-repeat
+    (let ((pnt (point))
+          (buf (current-buffer)))
+      (evil-collection-ace-jump-mode-enclose-ace-jump-for-motion
+       (call-interactively 'ace-jump-char-mode))
+      (if (and (equal buf (current-buffer))
+               (< (point) pnt))
+          (progn
+            (or (eobp) (forward-char))
+            (setq evil-this-type
+                  (cond
+                   ((eq evil-this-type 'exclusive) 'inclusive)
+                   ((eq evil-this-type 'inclusive) 'exclusive))))
+        (backward-char)))))
+
+(evil-define-motion evil-ace-jump-line-mode (_)
+  "Jump visually to the beginning of a line using ace-jump."
+  :type line
+  :repeat abort
+  (evil-without-repeat
+    (evil-collection-ace-jump-mode-enclose-ace-jump-for-motion
+     (call-interactively 'ace-jump-line-mode))))
+
+(evil-define-motion evil-ace-jump-word-mode (_)
+  "Jump visually to the beginning of a word using ace-jump."
+  :type exclusive
+  :repeat abort
+  (evil-without-repeat
+    (evil-collection-ace-jump-mode-enclose-ace-jump-for-motion
+     (call-interactively 'ace-jump-word-mode))))
+
+(defun evil-collection-ace-jump-mode-setup ()
+  "Set up `evil' bindings for `ace-jump-mode'."
+
+  (defadvice ace-jump-done (after evil activate)
+    (when evil-collection-ace-jump-mode-jump-active
+      (add-hook 'post-command-hook #'evil-collection-ace-jump-mode-jump-exit-recursive-edit)))
+
+  (evil-collection-define-key nil 'evil-motion-state-map
+    [remap ace-jump-char-mode] #'evil-ace-jump-char-mode
+    [remap ace-jump-line-mode] #'evil-ace-jump-line-mode
+    [remap ace-jump-word-mode] #'evil-ace-jump-word-mode))
+
+(provide 'evil-collection-ace-jump-mode)
+;;; evil-collection-ace-jump-mode.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-ace-jump-mode.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-ace-jump-mode.elc
new file mode 100644
index 0000000000..86f218157f
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-ace-jump-mode.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-ag.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-ag.el
new file mode 100644
index 0000000000..33cf83c2eb
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-ag.el
@@ -0,0 +1,62 @@
+;;; evil-collection-ag.el --- Evil Bindings for Ag -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 James Nguyen
+
+;; Author: James Nguyen <james@jojojames.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, ag, tools
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; Evil bindings for `ag-mode' from the `wgrep-ag' package.
+
+;;; Code:
+(require 'ag nil t)
+(require 'evil-collection)
+
+(defconst evil-collection-ag-maps '(ag-mode-map))
+
+(defun evil-collection-ag-setup ()
+  "Set up `evil' bindings for `ag'."
+  (evil-collection-define-key '(normal visual) 'ag-mode-map
+    "k" 'evil-previous-line
+    "h" 'evil-backward-char
+
+    ;; refresh
+    "gr" 'recompile
+
+    ;; navigation
+    "gj" 'compilation-next-error
+    "gk" 'compilation-previous-error
+    (kbd "C-j") 'compilation-next-error
+    (kbd "C-k") 'compilation-previous-error
+    "]" 'compilation-next-error
+    "[" 'compilation-previous-error
+
+    ;; search
+    "?" evil-collection-evil-search-backward
+    "/" evil-collection-evil-search-forward
+    "n" evil-collection-evil-search-next
+    "N" evil-collection-evil-search-previous)
+  ;; `ag' is best set in 'normal state because its buffer can be edited.
+  ;; https://github.com/mhayashi1120/Emacs-wgrep
+  (evil-set-initial-state 'ag-mode 'normal))
+
+(provide 'evil-collection-ag)
+;;; evil-collection-ag.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-ag.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-ag.elc
new file mode 100644
index 0000000000..f49bf0c3f9
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-ag.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-alchemist.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-alchemist.el
new file mode 100644
index 0000000000..023cc8acbd
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-alchemist.el
@@ -0,0 +1,113 @@
+;;; evil-collection-alchemist.el --- Bindings for `alchemist'. -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 James Nguyen
+
+;; Author: James Nguyen <james@jojojames.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, alchemist, tools
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;; Bindings for `alchemist'.
+
+;;; Code:
+(require 'evil-collection)
+(require 'alchemist nil t)
+
+(defconst evil-collection-alchemist-maps '(alchemist-compile-mode-map
+                                           alchemist-eval-mode-map
+                                           alchemist-execute-mode-map
+                                           alchemist-message-mode-map
+                                           alchemist-help-minor-mode-map
+                                           alchemist-macroexpand-mode-map
+                                           alchemist-mix-mode-map
+                                           alchemist-test-report-mode-map
+                                           alchemist-mode-map))
+
+
+(defun evil-collection-alchemist-setup ()
+  "Set up `evil' bindings for `alchemist'."
+  (evil-set-initial-state 'alchemist-compile-mode 'normal)
+  (evil-set-initial-state 'alchemist-eval-mode 'normal)
+  (evil-set-initial-state 'alchemist-execute-mode 'normal)
+  (evil-set-initial-state 'alchemist-message-mode 'normal)
+  (evil-set-initial-state 'alchemist-help-minor-mode 'normal)
+  (evil-set-initial-state 'alchemist-macroexpand-mode 'normal)
+  (evil-set-initial-state 'alchemist-refcard-mode 'normal)
+  (evil-set-initial-state 'alchemist-mix-mode 'normal)
+  (evil-set-initial-state 'alchemist-test-mode 'normal)
+  (evil-set-initial-state 'alchemist-test-report-mode 'normal)
+
+  (evil-collection-define-key 'normal 'alchemist-compile-mode-map
+    "q" 'quit-window)
+
+  (evil-collection-define-key 'normal 'alchemist-eval-mode-map
+    "q" 'quit-window)
+
+  (evil-collection-define-key 'normal 'alchemist-execute-mode-map
+    "q" 'quit-window)
+
+  (evil-collection-define-key 'normal 'alchemist-message-mode-map
+    "q" 'quit-window)
+
+  (evil-collection-define-key 'normal 'alchemist-help-minor-mode-map
+    "q" 'quit-window
+    "K" 'alchemist-help-search-at-point
+    "m" 'alchemist-help-module
+    "s" 'alchemist-help
+    "gh" 'alchemist-help-history
+    "gd" 'alchemist-goto-definition-at-point
+    "g?" 'alchemist-help-minor-mode-key-binding-summary)
+
+  (evil-collection-define-key 'normal 'alchemist-macroexpand-mode-map
+    "q" 'quit-window)
+
+  (evil-collection-define-key 'normal 'alchemist-refcard-mode-map
+    "gd" 'alchemist-refcard--describe-funtion-at-point
+    "g?" 'alchemist-refcard--describe-funtion-at-point
+    "q" 'quit-window)
+
+  (evil-collection-define-key 'normal 'alchemist-mix-mode-map
+    "q" 'quit-window
+    "i" 'alchemist-mix-send-input-to-mix-process
+    "gr" 'alchemist-mix-rerun-last-task)
+
+  (evil-collection-define-key 'normal 'alchemist-test-report-mode-map
+    "q" 'quit-window
+    "t" 'toggle-truncate-lines
+    "gr" 'alchemist-mix-rerun-last-test
+    "gj" 'alchemist-test-next-result
+    "gk" 'alchemist-test-previous-result
+    (kbd "C-j") 'alchemist-test-next-result
+    (kbd "C-k") 'alchemist-test-previous-result
+    "]" 'alchemist-test-next-stacktrace-file
+    "[" 'alchemist-test-previous-stacktrace-file
+    (kbd "C-c C-k") 'alchemist-report-interrupt-current-process)
+
+  (evil-collection-define-key 'normal 'alchemist-mode-map
+    "gz" 'alchemist-iex-run
+    "K" 'alchemist-help-search-at-point
+    "gd" 'alchemist-goto-definition-at-point
+    (kbd "C-t") 'alchemist-goto-jump-back
+    "g?" 'alchemist-help
+    (kbd "C-j") 'alchemist-goto-jump-to-next-def-symbol
+    (kbd "C-k") 'alchemist-goto-jump-to-previous-def-symbol))
+
+(provide 'evil-collection-alchemist)
+;;; evil-collection-alchemist.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-alchemist.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-alchemist.elc
new file mode 100644
index 0000000000..ca75c637b6
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-alchemist.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-anaconda-mode.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-anaconda-mode.el
new file mode 100644
index 0000000000..adc8ef0795
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-anaconda-mode.el
@@ -0,0 +1,63 @@
+;;; evil-collection-anaconda-mode.el --- Bindings for `anaconda-mode'. -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 James Nguyen
+
+;; Author: James Nguyen <james@jojojames.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, python, tools
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;; Bindings for `anaconda-mode'.
+
+;;; Code:
+(require 'anaconda-mode nil t)
+(require 'evil-collection)
+
+(defconst evil-collection-anaconda-mode-maps '(anaconda-view-mode-map
+                                               anaconda-mode-map))
+
+(defun evil-collection-anaconda-mode-setup ()
+  "Set up `evil' bindings for `anaconda-mode'."
+  ;; Bindings don't seem to be set the first time.
+  (add-hook 'anaconda-mode-hook #'evil-normalize-keymaps)
+
+  ;; latest anaconda has replaced view mode by an xref implementation,
+  ;; anaconda stable uses `anaconda-view-mode-map'
+  (when (boundp 'anaconda-view-mode-map)
+    (evil-collection-define-key 'normal 'anaconda-view-mode-map
+      "gj" 'next-error-no-select
+      "gk" 'previous-error-no-select
+      (kbd "C-j") 'next-error-no-select
+      (kbd "C-k") 'previous-error-no-select
+      "]" 'next-error-no-select
+      "[" 'previous-error-no-select
+      "q" 'quit-window))
+
+  (evil-collection-define-key 'normal 'anaconda-mode-map
+    ;; Would be nice to support these too.
+    ;; 'anaconda-mode-find-assignments
+    ;; 'anaconda-mode-find-references
+    "gd" 'anaconda-mode-find-definitions
+    (kbd "C-t") (if (fboundp 'anaconda-mode-go-back)
+                    'anaconda-mode-go-back
+                  'xref-pop-marker-stack)
+    "K" 'anaconda-mode-show-doc))
+
+(provide 'evil-collection-anaconda-mode)
+;;; evil-collection-anaconda-mode.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-anaconda-mode.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-anaconda-mode.elc
new file mode 100644
index 0000000000..3add1e86c8
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-anaconda-mode.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-arc-mode.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-arc-mode.el
new file mode 100644
index 0000000000..53f3e9cfcb
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-arc-mode.el
@@ -0,0 +1,76 @@
+;;; evil-collection-arc-mode.el --- Evil bindings for arc-mode. -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 James Nguyen
+
+;; Author: James Nguyen <james@jojojames.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, arc-mode, archive, bindings, files
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;; Evil bindings for arc-mode.
+
+;;; Code:
+(require 'arc-mode)
+(require 'evil-collection)
+
+(defconst evil-collection-arc-mode-maps '(archive-mode-map))
+
+(defun evil-collection-arc-mode-setup ()
+  "Set up `evil' bindings for `arc-mode'."
+  (evil-set-initial-state 'arc-mode 'normal)
+  (evil-set-initial-state 'archive-mode 'normal)
+  (evil-collection-define-key 'normal 'archive-mode-map
+    "j" 'archive-next-line
+    "k" 'archive-previous-line
+    (kbd "C-j") 'archive-next-line
+    (kbd "C-k") 'archive-previous-line
+    "gj" 'archive-next-line
+    "gk" 'archive-previous-line
+
+    "gg" 'beginning-of-buffer
+    "G" 'end-of-buffer
+
+    ;; open
+    (kbd "<return>") 'archive-extract
+    (kbd "S-<return>") 'archive-extract-other-window
+    (kbd "M-<return>") 'archive-view
+    "go" 'archive-extract-other-window
+
+    "a" 'archive-alternate-display
+    "d" 'archive-flag-deleted
+    "r" 'archive-rename-entry
+    "x" 'archive-expunge
+    "M" 'archive-chmod-entry
+    "P" 'archive-chgrp-entry
+    "C" 'archive-chown-entry
+
+    ;; refresh
+    "gr" 'revert-buffer
+
+    ;; mark
+    "m" 'archive-mark
+    "u" 'archive-unflag
+    "U" 'archive-unmark-all-files
+
+    ;; quit
+    "q" 'quit-window))
+
+(provide 'evil-collection-arc-mode)
+;;; evil-collection-arc-mode.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-arc-mode.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-arc-mode.elc
new file mode 100644
index 0000000000..a3e7b0da0e
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-arc-mode.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-autoloads.el
new file mode 100644
index 0000000000..0529a3395d
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-autoloads.el
@@ -0,0 +1,115 @@
+;;; evil-collection-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "evil-collection" "evil-collection.el" (23377
+;;;;;;  61299 510440 173000))
+;;; Generated autoloads from evil-collection.el
+
+(autoload 'evil-collection-translate-key "evil-collection" "\
+Translate keys in the keymap(s) corresponding to STATES and KEYMAPS.
+STATES should be the name of an evil state, a list of states, or nil. KEYMAPS
+should be a symbol corresponding to the keymap to make the translations in or a
+list of keymap symbols. Like `evil-define-key', when a keymap does not exist,
+the keybindings will be deferred until the keymap is defined, so
+`with-eval-after-load' is not neccessary. TRANSLATIONS corresponds to a list of
+key replacement pairs. For example, specifying \"a\" \"b\" will bind \"a\" to
+\"b\"'s definition in the keymap. Specifying nil as a replacement will unbind a
+key. If DESTRUCTIVE is nil, a backup of the keymap will be stored on the initial
+invocation, and future invocations will always look up keys in the backup
+keymap. When no TRANSLATIONS are given, this function will only create the
+backup keymap without making any translations. On the other hand, if DESTRUCTIVE
+is non-nil, the keymap will be destructively altered without creating a backup.
+For example, calling this function multiple times with \"a\" \"b\" \"b\" \"a\"
+would continue to swap and unswap the definitions of these keys. This means that
+when DESTRUCTIVE is non-nil, all related swaps/cycles should be done in the same
+invocation.
+
+\(fn STATES KEYMAPS &rest TRANSLATIONS &key DESTRUCTIVE &allow-other-keys)" nil nil)
+
+(function-put 'evil-collection-translate-key 'lisp-indent-function 'defun)
+
+(autoload 'evil-collection-swap-key "evil-collection" "\
+Wrapper around `evil-collection-translate-key' for swapping keys.
+STATES, KEYMAPS, and ARGS are passed to `evil-collection-translate-key'. ARGS
+should consist of key swaps (e.g. \"a\" \"b\" is equivalent to \"a\" \"b\" \"b\"
+\"a\" with `evil-collection-translate-key') and optionally keyword arguments for
+`evil-collection-translate-key'.
+
+\(fn STATES KEYMAPS &rest ARGS)" nil t)
+
+(function-put 'evil-collection-swap-key 'lisp-indent-function 'defun)
+
+(autoload 'evil-collection-init "evil-collection" "\
+Register the Evil bindings for all modes in `evil-collection-mode-list'.
+
+Alternatively, you may register select bindings manually, for
+instance:
+
+  (with-eval-after-load 'calendar
+    (require 'evil-collection-calendar)
+    (evil-collection-calendar-setup))
+
+If MODES is specified (as either one mode or a list of modes), use those modes
+instead of the modes in `evil-collection-mode-list'.
+
+\(fn &optional MODES)" t nil)
+
+;;;***
+
+;;;### (autoloads nil nil ("evil-collection-ace-jump-mode.el" "evil-collection-ag.el"
+;;;;;;  "evil-collection-alchemist.el" "evil-collection-anaconda-mode.el"
+;;;;;;  "evil-collection-arc-mode.el" "evil-collection-avy.el" "evil-collection-bookmark.el"
+;;;;;;  "evil-collection-buff-menu.el" "evil-collection-calc.el"
+;;;;;;  "evil-collection-calendar.el" "evil-collection-cider.el"
+;;;;;;  "evil-collection-cmake-mode.el" "evil-collection-comint.el"
+;;;;;;  "evil-collection-company.el" "evil-collection-compile.el"
+;;;;;;  "evil-collection-cus-theme.el" "evil-collection-custom.el"
+;;;;;;  "evil-collection-daemons.el" "evil-collection-debbugs.el"
+;;;;;;  "evil-collection-debug.el" "evil-collection-diff-mode.el"
+;;;;;;  "evil-collection-dired.el" "evil-collection-doc-view.el"
+;;;;;;  "evil-collection-edebug.el" "evil-collection-ediff.el" "evil-collection-eldoc.el"
+;;;;;;  "evil-collection-elfeed.el" "evil-collection-elisp-mode.el"
+;;;;;;  "evil-collection-elisp-refs.el" "evil-collection-emms.el"
+;;;;;;  "evil-collection-epa.el" "evil-collection-ert.el" "evil-collection-eshell.el"
+;;;;;;  "evil-collection-etags-select.el" "evil-collection-eval-sexp-fu.el"
+;;;;;;  "evil-collection-eww.el" "evil-collection-flycheck.el" "evil-collection-free-keys.el"
+;;;;;;  "evil-collection-geiser.el" "evil-collection-ggtags.el" "evil-collection-git-timemachine.el"
+;;;;;;  "evil-collection-go-mode.el" "evil-collection-grep.el" "evil-collection-guix.el"
+;;;;;;  "evil-collection-helm.el" "evil-collection-help.el" "evil-collection-ibuffer.el"
+;;;;;;  "evil-collection-image+.el" "evil-collection-image.el" "evil-collection-imenu-list.el"
+;;;;;;  "evil-collection-indium.el" "evil-collection-info.el" "evil-collection-integration.el"
+;;;;;;  "evil-collection-ivy.el" "evil-collection-js2-mode.el" "evil-collection-kotlin-mode.el"
+;;;;;;  "evil-collection-lispy.el" "evil-collection-log-view.el"
+;;;;;;  "evil-collection-lsp-ui-imenu.el" "evil-collection-lua-mode.el"
+;;;;;;  "evil-collection-macrostep.el" "evil-collection-magit-todos.el"
+;;;;;;  "evil-collection-magit.el" "evil-collection-man.el" "evil-collection-minibuffer.el"
+;;;;;;  "evil-collection-mu4e-conversation.el" "evil-collection-mu4e.el"
+;;;;;;  "evil-collection-neotree.el" "evil-collection-notmuch.el"
+;;;;;;  "evil-collection-nov.el" "evil-collection-occur.el" "evil-collection-outline.el"
+;;;;;;  "evil-collection-p4.el" "evil-collection-package-menu.el"
+;;;;;;  "evil-collection-paren.el" "evil-collection-pass.el" "evil-collection-pdf.el"
+;;;;;;  "evil-collection-pkg.el" "evil-collection-popup.el" "evil-collection-proced.el"
+;;;;;;  "evil-collection-prodigy.el" "evil-collection-profiler.el"
+;;;;;;  "evil-collection-python.el" "evil-collection-quickrun.el"
+;;;;;;  "evil-collection-racer.el" "evil-collection-realgud.el" "evil-collection-reftex.el"
+;;;;;;  "evil-collection-rjsx-mode.el" "evil-collection-robe.el"
+;;;;;;  "evil-collection-rtags.el" "evil-collection-ruby-mode.el"
+;;;;;;  "evil-collection-settings.el" "evil-collection-simple.el"
+;;;;;;  "evil-collection-slime.el" "evil-collection-term.el" "evil-collection-tide.el"
+;;;;;;  "evil-collection-transmission.el" "evil-collection-typescript-mode.el"
+;;;;;;  "evil-collection-vc-annotate.el" "evil-collection-vdiff.el"
+;;;;;;  "evil-collection-view.el" "evil-collection-vlf.el" "evil-collection-wdired.el"
+;;;;;;  "evil-collection-wgrep.el" "evil-collection-which-key.el"
+;;;;;;  "evil-collection-woman.el" "evil-collection-xref.el" "evil-collection-ztree.el")
+;;;;;;  (23377 61299 670471 891000))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; evil-collection-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-avy.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-avy.el
new file mode 100644
index 0000000000..4ae8929fdb
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-avy.el
@@ -0,0 +1,121 @@
+;;; evil-collection-avy.el --- Bindings for `avy' -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 James Nguyen
+
+;; Author: James Nguyen <james@jojojames.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, emacs, tools
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;; Bindings for `avy'
+
+;;; Code:
+(require 'avy nil t)
+(require 'evil-collection)
+
+(declare-function 'avy-goto-word-or-subword-1 "avy")
+(declare-function 'avy-goto-line "avy")
+(declare-function 'avy-goto-char "avy")
+(declare-function 'avy-goto-char-2 "avy")
+(declare-function 'avy-goto-char-2-above "avy")
+(declare-function 'avy-goto-char-2-below "avy")
+(declare-function 'avy-goto-char-in-line "avy")
+(declare-function 'avy-goto-word-0 "avy")
+(declare-function 'avy-goto-word-1 "avy")
+(declare-function 'avy-goto-word-1-above "avy")
+(declare-function 'avy-goto-word-1-below "avy")
+(declare-function 'avy-goto-subword-0 "avy")
+(declare-function 'avy-goto-subword-1 "avy")
+(declare-function 'avy-goto-char-timer "avy")
+
+(defmacro evil-collection-avy-enclose-avy-for-motion (&rest body)
+  "Enclose avy to make it suitable for motions.
+Based on `evil-collection-ace-jump-mode-enclose-ace-jump-for-motion'."
+  (declare (indent defun)
+           (debug t))
+  `(let ((avy-all-windows
+          (if (and (not (memq evil-state '(visual operator)))
+                   (boundp 'avy-all-windows))
+              avy-all-windows
+            nil)))
+     (ignore avy-all-windows) ;; Make byte compiler happy.
+     ,@body))
+
+(defmacro evil-collection-avy-define-avy-motion (command type)
+  (declare (indent defun)
+           (debug t))
+  (let ((name (intern (format "evil-%s" command))))
+    `(evil-define-motion ,name (_count)
+       ,(format "Evil motion for `%s'." command)
+       :type ,type
+       :jump t
+       :repeat abort
+       (evil-without-repeat
+         (evil-collection-avy-enclose-avy-for-motion
+          (call-interactively ',command))))))
+
+;; define evil-avy-* motion commands for avy-* commands
+(evil-collection-avy-define-avy-motion avy-goto-char inclusive)
+(evil-collection-avy-define-avy-motion avy-goto-char-2 inclusive)
+(evil-collection-avy-define-avy-motion avy-goto-char-2-above inclusive)
+(evil-collection-avy-define-avy-motion avy-goto-char-2-below inclusive)
+(evil-collection-avy-define-avy-motion avy-goto-char-in-line inclusive)
+(evil-collection-avy-define-avy-motion avy-goto-char-timer inclusive)
+(evil-collection-avy-define-avy-motion avy-goto-line line)
+(evil-collection-avy-define-avy-motion avy-goto-line-above line)
+(evil-collection-avy-define-avy-motion avy-goto-line-below line)
+(evil-collection-avy-define-avy-motion avy-goto-subword-0 exclusive)
+(evil-collection-avy-define-avy-motion avy-goto-subword-1 exclusive)
+(evil-collection-avy-define-avy-motion avy-goto-symbol-1 exclusive)
+(evil-collection-avy-define-avy-motion avy-goto-symbol-1-above exclusive)
+(evil-collection-avy-define-avy-motion avy-goto-symbol-1-below exclusive)
+(evil-collection-avy-define-avy-motion avy-goto-word-0 exclusive)
+(evil-collection-avy-define-avy-motion avy-goto-word-1 exclusive)
+(evil-collection-avy-define-avy-motion avy-goto-word-1-above exclusive)
+(evil-collection-avy-define-avy-motion avy-goto-word-1-below exclusive)
+(evil-collection-avy-define-avy-motion avy-goto-word-or-subword-1 exclusive)
+
+(defun evil-collection-avy-setup ()
+  "Set up `evil' bindings for `avy'."
+  ;; remap avy-* commands to evil-avy-* commands
+  (dolist (command '(avy-goto-char
+                     avy-goto-char-2
+                     avy-goto-char-2-above
+                     avy-goto-char-2-below
+                     avy-goto-char-in-line
+                     avy-goto-char-timer
+                     avy-goto-line
+                     avy-goto-line-above
+                     avy-goto-line-below
+                     avy-goto-subword-0
+                     avy-goto-subword-1
+                     avy-goto-symbol-1
+                     avy-goto-symbol-1-above
+                     avy-goto-symbol-1-below
+                     avy-goto-word-0
+                     avy-goto-word-1
+                     avy-goto-word-1-above
+                     avy-goto-word-1-below
+                     avy-goto-word-or-subword-1))
+    (evil-collection-define-key nil 'evil-motion-state-map
+      (vector 'remap command) (intern-soft (format "evil-%s" command)))))
+
+(provide 'evil-collection-avy)
+;;; evil-collection-avy.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-avy.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-avy.elc
new file mode 100644
index 0000000000..561683b4c3
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-avy.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-bookmark.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-bookmark.el
new file mode 100644
index 0000000000..bcf92a4458
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-bookmark.el
@@ -0,0 +1,78 @@
+;;; evil-collection-bookmark.el --- Evil bindings for bookmarks -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 James Nguyen
+
+;; Author: James Nguyen <james@jojojames.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, bookmark, tools
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; Evil bindings for bookmarks.
+
+;;; Code:
+(require 'evil-collection)
+(require 'bookmark)
+
+(defconst evil-collection-bookmark-maps '(bookmark-bmenu-mode-map))
+
+(defun evil-collection-bookmark-setup ()
+  "Set up `evil' bindings for `bookmark'."
+  (evil-set-initial-state 'bookmark-bmenu-mode 'normal)
+
+  (evil-collection-define-key 'normal 'bookmark-bmenu-mode-map
+    "q" 'quit-window
+    "gr" 'revert-buffer
+    "g?" 'describe-mode
+
+    "j" 'next-line
+    "p" 'previous-line
+    "J" 'bookmark-bmenu-this-window
+    "2" 'bookmark-bmenu-2-window
+    "1" 'bookmark-bmenu-1-window
+    "x" 'bookmark-bmenu-execute-deletions
+    "d" 'bookmark-bmenu-delete
+    "/" 'bookmark-bmenu-search
+    "r" 'bookmark-bmenu-rename
+    "R" 'bookmark-bmenu-relocate
+    "L" 'bookmark-bmenu-load
+    "t" 'bookmark-bmenu-toggle-filenames
+    "a" 'bookmark-bmenu-show-annotation
+    "A" 'bookmark-bmenu-show-all-annotations
+    "s" 'bookmark-bmenu-save
+    "W" 'bookmark-bmenu-locate
+    "E" 'bookmark-bmenu-edit-annotation
+    "D" 'bookmark-bmenu-delete-backwards
+
+    ;; mark
+    "u" 'bookmark-bmenu-unmark
+    "m" 'bookmark-bmenu-mark
+
+    ;; open
+    "o" 'bookmark-bmenu-select
+    "O" 'bookmark-bmenu-other-window
+    "go" 'bookmark-bmenu-other-window
+    "gO" 'bookmark-bmenu-switch-other-window
+    (kbd "<return>") 'bookmark-bmenu-this-window
+    (kbd "S-<return>") 'bookmark-bmenu-other-window
+    (kbd "M-<return>") 'bookmark-bmenu-switch-other-window))
+
+
+(provide 'evil-collection-bookmark)
+;;; evil-collection-bookmark.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-bookmark.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-bookmark.elc
new file mode 100644
index 0000000000..7711ea6268
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-bookmark.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-buff-menu.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-buff-menu.el
new file mode 100644
index 0000000000..5388487e27
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-buff-menu.el
@@ -0,0 +1,121 @@
+;;; evil-collection-buff-menu.el --- Bindings for `buff-menu'. -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 James Nguyen
+
+;; Author: James Nguyen <james@jojojames.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, emacs, tools
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;; Bindings for `buff-menu'.
+
+;;; Code:
+(require 'evil-collection)
+(require 'tabulated-list)
+
+;; `evil-collection-buff-menu-Buffer-menu-unmark-all'
+
+;; Code taken from emacs-26 repository.
+
+(defconst evil-collection-buff-menu-maps '(Buffer-menu-mode-map))
+
+;; This is for `evil-collection-Buffer-menu-unmark-all-buffers.'
+(defsubst evil-collection-buff-menu-tabulated-list-header-overlay-p (&optional pos)
+  "Return non-nil if there is a fake header.
+Optional arg POS is a buffer position where to look for a fake header;
+defaults to `point-min'."
+  (overlays-at (or pos (point-min))))
+
+(defun evil-collection-buff-menu-Buffer-menu-unmark-all ()
+  "Cancel all requested operations on buffers."
+  (interactive)
+  (evil-collection-buff-menu-Buffer-menu-unmark-all-buffers ?\r))
+
+(defun evil-collection-buff-menu-Buffer-menu-unmark-all-buffers (mark)
+  "Cancel a requested operation on all buffers.
+MARK is the character to flag the operation on the buffers.
+When called interactively prompt for MARK;  RET remove all marks."
+  (interactive "cRemove marks (RET means all):")
+  (save-excursion
+    (goto-char (point-min))
+    (when (evil-collection-buff-menu-tabulated-list-header-overlay-p)
+      (forward-line))
+    (while (not (eobp))
+      (let ((xmarks (list (aref (tabulated-list-get-entry) 0)
+                          (aref (tabulated-list-get-entry) 2))))
+        (when (or (char-equal mark ?\r)
+                  (member (char-to-string mark) xmarks))
+          (Buffer-menu--unmark)))
+      (forward-line))))
+
+;; `evil-collection-buff-menu-Buffer-menu-unmark-all'
+
+(defun evil-collection-buff-menu-setup ()
+  "Set up `evil' bindings for `buff-menu'.."
+
+  (evil-set-initial-state 'Buffer-menu-mode 'normal)
+  (evil-add-hjkl-bindings Buffer-menu-mode-map 'normal)
+
+  (evil-collection-define-key 'normal 'Buffer-menu-mode-map
+    "ZQ" 'evil-quit
+    "ZZ" 'quit-window
+    "gr" 'revert-buffer
+    "go" 'Buffer-menu-this-window
+    "gO" 'Buffer-menu-other-window
+    "d" 'Buffer-menu-delete
+    "s" 'Buffer-menu-save
+    [mouse-2] 'Buffer-menu-mouse-select
+    [follow-link] 'mouse-face
+    "x" 'Buffer-menu-execute
+    "o" 'tabulated-list-sort
+    "gv" 'Buffer-menu-select
+    "gV" 'Buffer-menu-view
+    "v" 'evil-visual-char
+
+    ;; mark
+    "u" 'Buffer-menu-unmark
+    "U" (if (< emacs-major-version 26)
+            'evil-collection-buff-menu-Buffer-menu-unmark-all
+          'Buffer-menu-unmark-all)
+    "m" 'Buffer-menu-mark
+
+    "f" 'evil-find-char
+    "e" 'evil-forward-word-end
+    "b" 'evil-backward-word-begin
+
+    "X" 'Buffer-menu-bury
+
+    ;; Default ones, unchanged. Redundant ones commented
+    "2" 'Buffer-menu-2-window
+    "1" 'Buffer-menu-1-window
+    (kbd "C-m") 'Buffer-menu-this-window
+    (kbd "C-k") 'Buffer-menu-delete
+    (kbd "C-d") 'Buffer-menu-delete-backwards
+    (kbd "<delete>") 'Buffer-menu-backup-unmark
+    "~" 'Buffer-menu-not-modified
+    "t" 'Buffer-menu-visit-tags-table
+    "%" 'Buffer-menu-toggle-read-only
+    "T" 'Buffer-menu-toggle-files-only
+    (kbd "M-s a C-s") 'Buffer-menu-isearch-buffers
+    (kbd "M-s a M-C-s") 'Buffer-menu-isearch-buffers-regexp
+    (kbd "M-s a C-o") 'Buffer-menu-multi-occur))
+
+(provide 'evil-collection-buff-menu)
+;;; evil-collection-buff-menu.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-buff-menu.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-buff-menu.elc
new file mode 100644
index 0000000000..0bf2e7f765
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-buff-menu.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-calc.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-calc.el
new file mode 100644
index 0000000000..d65fa6a0ad
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-calc.el
@@ -0,0 +1,173 @@
+;;; evil-collection-calc.el --- Evil bindings for calc -*- lexical-binding: t -*-
+
+;; Copyright (C) 2018 Pierre Neidhardt
+
+;; Author: Pierre Neidhardt <ambrevar@gmail.com>
+;; Maintainer: James Nguyen <james@jojojames.com>, Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, calc, tools
+
+;; This file 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, or (at your
+;; option) any later version.
+;;
+;; This file 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.
+;;
+;; For a full copy of the GNU General Public License
+;; see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; Evil bindings for calc.
+
+;;; Code:
+(require 'evil-collection)
+(require 'calc)
+
+(defconst evil-collection-calc-maps '(calc-mode-map))
+
+(defun evil-collection-calc-setup ()
+  "Set up `evil' bindings for `calc'."
+  (evil-collection-inhibit-insert-state 'calc-mode-map)
+  (evil-set-initial-state 'calc-mode 'normal)
+
+  ;; Calc sets up its bindings just-in-time for its "extensions".  I don't think
+  ;; it's worth copying this clumsy design (for what performance benefit?),
+  ;; while making the bindings much harder to maintain.
+  (require 'calc-ext)
+
+  (evil-collection-define-key 'normal 'calc-mode-map
+    "0" 'calcDigit-start
+    "1" 'calcDigit-start
+    "2" 'calcDigit-start
+    "3" 'calcDigit-start
+    "4" 'calcDigit-start
+    "5" 'calcDigit-start
+    "6" 'calcDigit-start
+    "7" 'calcDigit-start
+    "8" 'calcDigit-start
+    "9" 'calcDigit-start
+
+    (kbd "<tab>") 'calc-roll-down
+    (kbd "S-<return>") 'calc-over
+    (kbd "<return>") 'calc-enter
+    (kbd "SPC") 'calc-enter
+
+    (kbd "C-x C-t") 'calc-transpose-lines
+    (kbd "C-M-d") 'calc-pop-above
+    (kbd "C-M-i") 'calc-roll-up
+    (kbd "M-RET") 'calc-last-args
+    (kbd "C-M-w") 'kill-ring-save
+    (kbd "M-%") 'calc-percent
+    (kbd "M-k") 'calc-copy-as-kill
+    (kbd "M-w") 'calc-copy-region-as-kill
+    (kbd "M-DEL") 'calc-pop-above
+    (kbd "M-m t") 'calc-total-algebraic-mode
+    (kbd "<delete>") 'calc-pop
+    (kbd "<mouse-2>") 'calc-yank
+    "x" 'calc-pop ; was "C-d".  TODO: Conflicts with calc-execute-extended-command.
+    "d" 'calc-kill                      ; was "C-k"
+    "u" 'calc-undo                      ; was "U"
+    "X" 'calc-call-last-kbd-macro       ; "@" is already used.
+    "pp" 'calc-yank                     ; was "C-y"
+    "pP" 'calc-copy-to-buffer           ; was "y"
+
+    (kbd "C-p") 'calc-precision         ; was "p"
+
+    "?" 'calc-help
+    ;; "h" 'calc-help-prefix ; TODO: Rebind?
+    "i" 'calc-info
+
+    "\"" 'calc-auto-algebraic-entry
+    "$" 'calc-auto-algebraic-entry      ; TODO: No need for this one?
+    "'" 'calc-algebraic-entry
+
+    "!" 'calc-factorial
+    "#" 'calcDigit-start
+    "%" 'calc-mod
+    "&" 'calc-inv
+    "(" 'calc-begin-complex
+    ")" 'calc-end-complex
+    "*" 'calc-times
+    "+" 'calc-plus
+    "," 'calc-comma
+    "-" 'calc-minus
+    "." 'calcDigit-start
+    "/" 'calc-divide
+    ":" 'calc-fdiv
+    ";" 'calc-semi         ; TODO: Shall we really override `evil-ex'?
+    "<" 'calc-scroll-left
+    "=" 'calc-evaluate
+    ">" 'calc-scroll-right
+    "@" 'calcDigit-start
+    "A" 'calc-abs
+    "B" 'calc-log
+    "C" 'calc-cos
+    ;; "D" 'calc-redo             ; TODO: What's the purpose of this?  Bind to C-r?
+    "E" 'calc-exp
+    "F" 'calc-floor
+    "G" 'calc-argument
+    "H" 'calc-hyperbolic
+    "I" 'calc-inverse
+    "J" 'calc-conj
+    "K" 'calc-keep-args
+    "L" 'calc-ln
+    "M" 'calc-more-recursion-depth
+    "N" 'calc-eval-num
+    "O" 'calc-option
+    "P" 'calc-pi
+    "Q" 'calc-sqrt
+    "R" 'calc-round
+    "S" 'calc-sin
+    "T" 'calc-tan
+    "[" 'calc-begin-vector
+    "]" 'calc-end-vector
+    "\\" 'calc-idiv
+    "^" 'calc-power
+    "_" 'calcDigit-start
+    "`" 'calc-edit
+    "e" 'calcDigit-start
+    "n" 'calc-change-sign
+    "o" 'calc-realign
+    "w" 'calc-why
+    "x" 'calc-execute-extended-command ; TODO: Conflicts with calc-pop.
+    "|" 'calc-concat
+    "{" 'calc-scroll-down               ; TODO: Not necessary?
+    "}" 'calc-scroll-up                 ; TODO: Not necessary?
+    "~" 'calc-num-prefix
+
+    "V" (lookup-key calc-mode-map (kbd "V"))
+    "Y" (lookup-key calc-mode-map (kbd "Y"))
+    "Z" (lookup-key calc-mode-map (kbd "Z"))
+    "a" (lookup-key calc-mode-map (kbd "a"))
+    "b" (lookup-key calc-mode-map (kbd "b"))
+    "c" (lookup-key calc-mode-map (kbd "c"))
+    "D" (lookup-key calc-mode-map (kbd "d"))
+    "f" (lookup-key calc-mode-map (kbd "f"))
+    "g" (lookup-key calc-mode-map (kbd "g"))
+    "zj" (lookup-key calc-mode-map (kbd "j"))
+    "zk" (lookup-key calc-mode-map (kbd "k"))
+    "zl" (lookup-key calc-mode-map (kbd "l"))
+    "m" (lookup-key calc-mode-map (kbd "m"))
+    "r" (lookup-key calc-mode-map (kbd "r"))
+    "s" (lookup-key calc-mode-map (kbd "s"))
+    "t" (lookup-key calc-mode-map (kbd "t"))
+    "U" (lookup-key calc-mode-map (kbd "u"))
+    "v" (lookup-key calc-mode-map (kbd "v"))
+    "zz" (lookup-key calc-mode-map (kbd "z"))
+
+    ;; quit
+    ;; "ZQ" 'quit-window ; TODO: Rebind "Z"?
+    ;; "ZZ" 'quit-window ; TODO: Rebind "Z"?
+    "q" 'calc-quit)
+
+  (evil-collection-define-key 'visual 'calc-mode-map
+    "d" 'calc-kill-region))
+
+(provide 'evil-collection-calc)
+;;; evil-collection-calc.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-calc.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-calc.elc
new file mode 100644
index 0000000000..34019d281e
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-calc.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-calendar.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-calendar.el
new file mode 100644
index 0000000000..09b166186d
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-calendar.el
@@ -0,0 +1,104 @@
+;;; evil-collection-calendar.el --- Evil bindings for calendar -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 Pierre Neidhardt
+
+;; Author: Pierre Neidhardt <ambrevar@gmail.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, calendar, tools
+
+;; This file 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, or (at your
+;; option) any later version.
+;;
+;; This file 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.
+;;
+;; For a full copy of the GNU General Public License
+;; see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; Evil bindings for the calendar.
+
+;;; Code:
+(require 'calendar)
+(require 'evil-collection)
+
+(defconst evil-collection-calendar-maps '(calendar-mode-map))
+
+(defun evil-collection-calendar-setup ()
+  "Set up `evil' bindings for `calendar'."
+  (evil-set-initial-state 'calendar-mode 'normal)
+  (evil-collection-define-key 'normal 'calendar-mode-map
+    ;; motion
+    "h" 'calendar-backward-day
+    "j" 'calendar-forward-week
+    "k" 'calendar-backward-week
+    "l" 'calendar-forward-day
+    "0" 'calendar-beginning-of-week
+    "^" 'calendar-beginning-of-week
+    "$" 'calendar-end-of-week
+    "[" 'calendar-backward-year
+    "]" 'calendar-forward-year
+    (kbd "M-<") 'calendar-beginning-of-year
+    (kbd "M->") 'calendar-end-of-year
+    "(" 'calendar-beginning-of-month
+    ")" 'calendar-end-of-month
+    (kbd "SPC") 'scroll-other-window
+    (kbd "S-SPC") 'scroll-other-window-down
+    (kbd "<delete>") 'scroll-other-window-down
+    "<" 'calendar-scroll-right
+    ">" 'calendar-scroll-left
+    (kbd "C-b") 'calendar-scroll-right-three-months
+    (kbd "C-f") 'calendar-scroll-left-three-months
+    "{" 'calendar-backward-month
+    "}" 'calendar-forward-month
+    (kbd "C-k") 'calendar-backward-month
+    (kbd "C-j") 'calendar-forward-month
+    "gk" 'calendar-backward-month
+    "gj" 'calendar-forward-month
+
+    ;; visual
+    "v" 'calendar-set-mark
+
+    ;; goto
+    "." 'calendar-goto-today
+    "gd" 'calendar-goto-date ; "gd" in evil-org-agenda, "gd" in Emacs.
+    ;; "gD" 'calendar-other-month ; Not very useful if we have `calendar-goto-date'.
+
+    ;; diary
+    "D" 'diary-view-other-diary-entries
+    "d" 'diary-view-entries
+    "m" 'diary-mark-entries
+    "s" 'diary-show-all-entries
+
+    "u" 'calendar-unmark
+    "x" 'calendar-mark-holidays
+
+    ;; show
+    "gm" 'calendar-lunar-phases ; "gm" in evil-org-agenda. TODO: Shadows calendar-mayan.
+    "gs" 'calendar-sunrise-sunset ; "gs" in evil-org-agenda
+    "gh" 'calendar-list-holidays ; "gh" in evil-org-agenda. TODO: Shadows calendar-hebrew.
+    "gc" 'org-calendar-goto-agenda ; "gc" in evil-org-agenda. TODO: Shadows calendar-iso.
+    "r" 'calendar-cursor-holidays
+
+    ;; refresh
+    "gr" 'calendar-redraw
+
+    "g?" 'calendar-goto-info-node
+    "?" 'calendar-goto-info-node ; Search is not very useful.
+    (kbd "M-=") 'calendar-count-days-region
+
+    ;; quit
+    "q" 'calendar-exit
+    "ZQ" 'evil-quit
+    "ZZ" 'calendar-exit))
+
+(provide 'evil-collection-calendar)
+;;; evil-collection-calendar.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-calendar.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-calendar.elc
new file mode 100644
index 0000000000..685bcaec0c
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-calendar.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-cider.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-cider.el
new file mode 100644
index 0000000000..67a1ad0a66
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-cider.el
@@ -0,0 +1,213 @@
+;;; evil-collection-cider.el --- Evil bindings for Cider -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 James Nguyen
+
+;; Author: James Nguyen <james@jojojames.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, cider, tools
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; Evil bindings for Cider.
+
+;;; Code:
+(require 'cl-macs)
+(require 'cider nil t)
+(require 'evil-collection)
+(require 'evil-collection-settings)
+
+(declare-function cider-debug-mode-send-reply "cider-debug")
+
+(defconst evil-collection-cider-maps '(cider-mode-map
+                                       cider-repl-mode-map
+                                       cider-test-report-mode-map
+                                       cider-macroexpansion-mode-map
+                                       cider-connections-buffer-mode-map))
+
+(defun evil-collection-cider-last-sexp (command &rest args)
+  "In normal-state or motion-state, last sexp ends at point."
+  (if (and (not evil-move-beyond-eol)
+           (or (evil-normal-state-p) (evil-motion-state-p)))
+      (save-excursion
+        (unless (or (eobp) (eolp)) (forward-char))
+        (apply command args))
+    (apply command args)))
+
+(defmacro evil-collection-cider-make-debug-command (&rest cider-commands)
+  "Make functions that wrap `cider-debug' commands.
+
+Cider debug commands are sent through `cider-debug-mode-send-reply'.
+
+ex. \(cider-debug-mode-send-reply \":next\"\)"
+  (let ((commands (if (consp cider-commands)
+                      cider-commands
+                    (list cider-commands))))
+    `(progn
+       ,@(cl-loop
+          for command in commands
+          collect
+          (let ((funsymbol
+                 (intern (format "evil-collection-cider-debug-%s" command))))
+            `(defun ,funsymbol ()
+               ,(format
+                 "Send :%s to `cider-debug-mode-send-reply'." command)
+               (interactive)
+               (cider-debug-mode-send-reply ,(format ":%s" command))))))))
+
+(evil-collection-cider-make-debug-command "next"
+                                          "continue"
+                                          "out"
+                                          "quit"
+                                          "eval"
+                                          "inject"
+                                          "inspect"
+                                          "locals")
+
+(defun evil-collection-cider-setup ()
+  "Set up `evil' bindings for `cider'."
+  (unless evil-move-beyond-eol
+    (advice-add 'cider-eval-last-sexp :around 'evil-collection-cider-last-sexp)
+    (advice-add 'cider-eval-last-sexp-and-replace :around 'evil-collection-cider-last-sexp)
+    (advice-add 'cider-eval-last-sexp-to-repl :around 'evil-collection-cider-last-sexp)
+    (with-eval-after-load 'cider-eval-sexp-fu
+      (advice-add 'cider-esf--bounds-of-last-sexp :around 'evil-collection-cider-last-sexp)))
+
+  (when evil-collection-settings-setup-debugger-keys
+    (add-hook 'cider-mode-hook #'evil-normalize-keymaps)
+    (add-hook 'cider--debug-mode-hook #'evil-normalize-keymaps)
+    (evil-collection-define-key 'normal 'cider-mode-map
+      [f6] 'cider-browse-instrumented-defs
+      [f9] 'cider-debug-defun-at-point)
+
+    (evil-collection-define-key 'normal 'cider--debug-mode-map
+      "b" 'cider-debug-defun-at-point
+      "n" 'evil-collection-cider-debug-next
+      "c" 'evil-collection-cider-debug-continue
+      "o" 'evil-collection-cider-debug-out
+      "q" 'evil-collection-cider-debug-quit
+      "e" 'evil-collection-cider-debug-eval
+      "J" 'evil-collection-cider-debug-inject
+      "I" 'evil-collection-cider-debug-inspect
+      "L" 'evil-collection-cider-debug-locals
+      "H" 'cider-debug-move-here))
+
+  (evil-collection-define-key '(normal visual) 'cider-mode-map
+    "gd" 'cider-find-var
+    (kbd "C-t") 'cider-pop-back
+    "gz" 'cider-switch-to-repl-buffer
+    "gf" 'cider-find-resource
+    "K" 'cider-doc)
+
+  (evil-collection-define-key '(normal visual) 'cider-repl-mode-map
+    ;; FIXME: This seems to get overwritten by `cider-switch-to-repl-buffer'.
+    "gz" 'cider-switch-to-last-clojure-buffer
+
+    "gd" 'cider-find-var
+    (kbd "C-t") 'cider-pop-back
+    "gr" 'cider-refresh
+    "gf" 'cider-find-resource
+    "K" 'cider-doc)
+
+  (evil-collection-define-key 'normal 'cider-test-report-mode-map
+    (kbd "C-c ,") 'cider-test-commands-map
+    (kbd "C-c C-t") 'cider-test-commands-map
+    (kbd "M-p") 'cider-test-previous-result
+    (kbd "M-n") 'cider-test-next-result
+
+    ;; goto
+    "gd" 'cider-test-jump
+
+    (kbd "<backtab>") 'cider-test-previous-result
+    (kbd "<tab>") 'cider-test-next-result
+    (kbd "<return>") 'cider-test-jump
+    "t" 'cider-test-jump
+    "d" 'cider-test-ediff
+    "e" 'cider-test-stacktrace
+    "f" 'cider-test-rerun-failed-tests
+    "n" 'cider-test-run-ns-tests
+    "L" 'cider-test-run-loaded-tests
+    "p" 'cider-test-run-project-tests
+    "gr" 'cider-test-run-test
+    "q" 'cider-popup-buffer-quit-function)
+
+  (evil-collection-define-key 'normal 'cider-macroexpansion-mode-map
+    ;; quit
+    "q" 'cider-popup-buffer-quit-function
+
+    "r" 'cider-macroexpand-again
+    "K" 'cider-doc ; Evil has `evil-lookup'.
+    "J" 'cider-javadoc
+    "." 'cider-find-var
+    "m" 'cider-macroexpand-1-inplace
+    "a" 'cider-macroexpand-all-inplace
+    "u" 'cider-macroexpand-undo
+    [remap undo] 'cider-macroexpand-undo)
+
+  (evil-collection-define-key 'normal 'cider-connections-buffer-mode-map
+    "d" 'cider-connections-make-default
+    "c" 'cider-connection-browser
+    "x" 'cider-connections-close-connection
+    (kbd "<return>") 'cider-connections-goto-connection
+    "g?" 'describe-mode)
+
+  (evil-set-initial-state 'cider-stacktrace-mode 'normal)
+  (evil-collection-define-key 'normal 'cider-stacktrace-mode-map
+    (kbd "C-k") 'cider-stacktrace-previous-cause
+    (kbd "C-j") 'cider-stacktrace-next-cause
+    (kbd "gk") 'cider-stacktrace-previous-cause
+    (kbd "gj") 'cider-stacktrace-next-cause
+    (kbd "[") 'cider-stacktrace-previous-cause
+    (kbd "]") 'cider-stacktrace-next-cause
+    "gd" 'cider-stacktrace-jump
+    "q" 'cider-popup-buffer-quit-function
+    "J" 'cider-stacktrace-toggle-java
+    "C" 'cider-stacktrace-toggle-clj
+    "R" 'cider-stacktrace-toggle-repl
+    "T" 'cider-stacktrace-toggle-tooling
+    "D" 'cider-stacktrace-toggle-duplicates
+    "P" 'cider-stacktrace-show-only-project
+    "A" 'cider-stacktrace-toggle-all
+    "1" 'cider-stacktrace-cycle-cause-1
+    "2" 'cider-stacktrace-cycle-cause-2
+    "3" 'cider-stacktrace-cycle-cause-3
+    "4" 'cider-stacktrace-cycle-cause-4
+    "5" 'cider-stacktrace-cycle-cause-5
+    "0" 'cider-stacktrace-cycle-all-causes
+    (kbd "TAB") 'cider-stacktrace-cycle-current-cause
+    [backtab] 'cider-stacktrace-cycle-all-causes)
+
+  (add-hook 'cider-inspector-mode-hook #'evil-normalize-keymaps)
+  (evil-collection-define-key 'normal 'cider-inspector-mode-map
+    "q" 'quit-window
+    (kbd "RET") 'cider-inspector-operate-on-point
+    [mouse-1] 'cider-inspector-operate-on-click
+    "L" 'cider-inspector-pop
+    "gr" 'cider-inspector-refresh
+    ;; Page-up/down
+    (kbd "C-j") 'cider-inspector-next-page
+    (kbd "C-k") 'cider-inspector-prev-page
+    " " 'cider-inspector-next-page
+    "s" 'cider-inspector-set-page-size
+    (kbd "]") 'cider-inspector-next-inspectable-object
+    (kbd "[") 'cider-inspector-previous-inspectable-object
+    "gj" 'cider-inspector-next-inspectable-object
+    "gk" 'cider-inspector-previous-inspectable-object))
+
+(provide 'evil-collection-cider)
+;;; evil-collection-cider.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-cider.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-cider.elc
new file mode 100644
index 0000000000..7087f4db5f
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-cider.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-cmake-mode.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-cmake-mode.el
new file mode 100644
index 0000000000..f15bbc5a01
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-cmake-mode.el
@@ -0,0 +1,43 @@
+;;; evil-collection-cmake-mode.el --- Bindings for `cmake-mode' -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 James Nguyen
+
+;; Author: James Nguyen <james@jojojames.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, emacs, tools
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;; Bindings for `cmake-mode'
+
+;;; Code:
+(require 'evil-collection)
+(require 'cmake-mode nil t)
+
+(defvar cmake-tab-width)
+(defun evil-collection-cmake-mode-set-evil-shift-width ()
+  "Set `evil-shift-width' according to `cmake-tab-with'."
+  (setq-local evil-shift-width cmake-tab-width))
+
+(defun evil-collection-cmake-mode-setup ()
+  "Set up `evil' bindings for `cmake-mode'."
+  (add-hook 'cmake-mode-hook #'evil-collection-cmake-mode-set-evil-shift-width))
+
+(provide 'evil-collection-cmake-mode)
+;;; evil-collection-cmake-mode.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-cmake-mode.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-cmake-mode.elc
new file mode 100644
index 0000000000..be4ec93a51
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-cmake-mode.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-comint.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-comint.el
new file mode 100644
index 0000000000..32a7799777
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-comint.el
@@ -0,0 +1,54 @@
+;;; evil-collection-comint.el --- Bindings for `comint-mode'. -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 James Nguyen
+
+;; Author: James Nguyen <james@jojojames.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, comint, processes
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;; Bindings for `comint-mode'.
+
+;;; Code:
+(require 'comint)
+(require 'evil-collection)
+
+(defconst evil-collection-comint-maps '(comint-mode-map))
+
+(defun evil-collection-comint-setup ()
+  "Set up `evil' bindings for `comint'."
+  (when evil-want-C-d-scroll
+    (evil-collection-define-key 'normal 'comint-mode-map
+      (kbd "C-d") #'evil-scroll-down))
+
+  (evil-collection-define-key 'normal 'comint-mode-map
+    (kbd "C-j") #'comint-next-input
+    (kbd "C-k") #'comint-previous-input
+    (kbd "gj") #'comint-next-input
+    (kbd "gk") #'comint-previous-input
+    (kbd "]") #'comint-next-input
+    (kbd "[") #'comint-previous-input)
+
+  (evil-collection-define-key 'insert 'comint-mode-map
+    (kbd "<up>") #'comint-previous-input
+    (kbd "<down>") #'comint-next-input))
+
+(provide 'evil-collection-comint)
+;;; evil-collection-comint.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-comint.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-comint.elc
new file mode 100644
index 0000000000..6ce75455c3
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-comint.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-company.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-company.el
new file mode 100644
index 0000000000..354312ffb1
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-company.el
@@ -0,0 +1,82 @@
+;;; evil-collection-company.el --- Bindings for `company-mode'. -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 James Nguyen
+
+;; Author: James Nguyen <james@jojojames.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, company, abbrev, convenience, matching
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;; Bindings for `company-mode'.
+
+;;; Code:
+(require 'company nil t)
+(require 'evil-collection)
+
+(declare-function company-tng-configure-default "company-tng")
+
+(defgroup evil-collection-company nil
+  "Evil bindings for `company-mode'."
+  :group 'evil-collection)
+
+(defcustom evil-collection-company-use-tng t
+  "Enable company-tng through `company-tng-configure-default'.
+
+This mirrors ycmd's behavior for a completion experience more
+similar to YouCompleteMe.
+
+Note that for changes to take effect, this variable may have to
+be set through custom or before evil-collection loads."
+  :group 'evil-collection-company
+  :type 'boolean)
+
+(defvar company-active-map)
+(defvar company-search-map)
+
+(defconst evil-collection-company-maps '(company-active-map company-search-map))
+
+(defun evil-collection-company-setup ()
+  "Set up `evil' bindings for `company'."
+  (evil-collection-define-key nil 'company-active-map
+    (kbd "C-n") 'company-select-next-or-abort
+    (kbd "C-p") 'company-select-previous-or-abort
+    (kbd "C-j") 'company-select-next-or-abort
+    (kbd "C-k") 'company-select-previous-or-abort
+    (kbd "M-j") 'company-select-next
+    (kbd "M-k") 'company-select-previous)
+
+  (when evil-want-C-u-scroll
+    (evil-collection-define-key nil 'company-active-map (kbd "C-u") 'company-previous-page))
+
+  (when evil-want-C-d-scroll
+    (evil-collection-define-key nil 'company-active-map (kbd "C-d") 'company-next-page))
+
+  (evil-collection-define-key nil 'company-search-map
+    (kbd "C-j") 'company-select-next-or-abort
+    (kbd "C-k") 'company-select-previous-or-abort
+    (kbd "M-j") 'company-select-next
+    (kbd "M-k") 'company-select-previous
+    (kbd "<escape>") 'company-search-abort)
+
+  ;; Sets up YCMD like behavior.
+  (when evil-collection-company-use-tng (company-tng-configure-default)))
+
+(provide 'evil-collection-company)
+;;; evil-collection-company.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-company.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-company.elc
new file mode 100644
index 0000000000..dfd407aa93
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-company.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-compile.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-compile.el
new file mode 100644
index 0000000000..0e356b7ec8
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-compile.el
@@ -0,0 +1,60 @@
+;;; evil-collection-compile.el --- Evil bindings for `compile' -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 James Nguyen
+
+;; Author: James Nguyen <james@jojojames.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, compile, tools
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; Evil bindings for `compile'.
+
+;;; Code:
+(require 'evil-collection)
+(require 'compile)
+
+(defconst evil-collection-compile-maps '(compilation-mode-map))
+
+(defun evil-collection-compile-setup ()
+  "Set up `evil' bindings for `compile'."
+  (evil-set-initial-state 'compilation-mode 'normal)
+
+  (evil-collection-define-key 'normal 'compilation-mode-map
+    "g?" 'describe-mode
+    "?" evil-collection-evil-search-backward
+    "gg" 'evil-goto-first-line
+    "0" 'evil-digit-argument-or-evil-beginning-of-line
+    [mouse-2] 'compile-goto-error
+    [follow-link] 'mouse-face
+    (kbd "<return>") 'compile-goto-error
+
+    "go" 'compilation-display-error
+    (kbd "S-<return>") 'compilation-display-error
+
+    "gj" 'compilation-next-error
+    "gk" 'compilation-previous-error
+    (kbd "C-j") 'compilation-next-error
+    (kbd "C-k") 'compilation-previous-error
+    "[" 'compilation-previous-file
+    "]" 'compilation-next-file
+    "gr" 'recompile))
+
+(provide 'evil-collection-compile)
+;;; evil-collection-compile.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-compile.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-compile.elc
new file mode 100644
index 0000000000..4993844767
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-compile.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-cus-theme.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-cus-theme.el
new file mode 100644
index 0000000000..6df53bb42f
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-cus-theme.el
@@ -0,0 +1,64 @@
+;;; evil-collection-cus-theme.el --- Bindings for `cus-theme'. -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 James Nguyen
+
+;; Author: James Nguyen <james@jojojames.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, custom themes, help, faces
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;; Bindings for `cus-theme'.
+
+;;; Code:
+(require 'cus-theme)
+(require 'evil-collection)
+
+(defconst evil-collection-cus-theme-maps '(custom-theme-choose-mode-map
+                                           custom-new-theme-mode-map))
+
+(defun evil-collection-cus-theme-setup ()
+  "Set up `evil' bindings for `cus-theme'."
+  (evil-set-initial-state 'custom-new-theme-mode 'normal)
+  (evil-set-initial-state 'custom-theme-choose-mode 'normal)
+
+  (evil-collection-define-key 'normal 'custom-theme-choose-mode-map
+    "gj" 'widget-forward
+    "gk" 'widget-backward
+    (kbd "]") 'widget-forward
+    (kbd "[") 'widget-backward
+    (kbd "C-j") 'widget-forward
+    (kbd "C-k") 'widget-backward
+    "K" 'custom-describe-theme)
+
+  (evil-collection-define-key 'normal 'custom-new-theme-mode-map
+    "gj" 'widget-forward
+    "gk" 'widget-backward
+    (kbd "]") 'widget-forward
+    (kbd "[") 'widget-backward
+    (kbd "C-j") 'widget-forward
+    (kbd "C-k") 'widget-backward
+
+    ;; quit
+    "q" 'Custom-buffer-done
+    "ZQ" 'evil-quit
+    "ZZ" 'Custom-buffer-done))
+
+(provide 'evil-collection-cus-theme)
+;;; evil-collection-cus-theme.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-cus-theme.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-cus-theme.elc
new file mode 100644
index 0000000000..4b26009910
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-cus-theme.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-custom.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-custom.el
new file mode 100644
index 0000000000..fe26690009
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-custom.el
@@ -0,0 +1,67 @@
+;;; evil-collection-custom.el --- Evil bindings for Customize -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 Pierre Neidhardt
+
+;; Author: Pierre Neidhardt <ambrevar@gmail.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, custom, tools
+
+;; This file 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, or (at your
+;; option) any later version.
+;;
+;; This file 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.
+;;
+;; For a full copy of the GNU General Public License
+;; see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; Evil bindings for the Customize interface.
+
+;;; Code:
+(require 'cus-edit)
+(require 'evil-collection)
+
+(defconst evil-collection-custom-maps '(custom-mode-map))
+
+(defun evil-collection-custom-setup ()
+  "Set up `evil' bindings for `Custom-mode'."
+  (evil-set-initial-state 'Custom-mode 'normal)
+
+  (evil-collection-define-key 'normal 'custom-mode-map
+    ;; motion
+    (kbd "<tab>") 'widget-forward
+    (kbd "S-<tab>") 'widget-backward
+    (kbd "<backtab>") 'widget-backward
+    (kbd "SPC") 'scroll-up-command
+    (kbd "S-SPC") 'scroll-down-command
+    (kbd "<delete>") 'scroll-down-command
+    (kbd "<return>") 'Custom-newline
+    (kbd "]") 'widget-forward
+    (kbd "[") 'widget-backward
+    ;; TODO: Should the following be added?
+    (kbd "C-j") 'widget-forward
+    (kbd "C-k") 'widget-backward
+    "gj" 'widget-forward
+    "gk" 'widget-backward
+
+    "^" 'Custom-goto-parent
+    (kbd "C-o") 'Custom-goto-parent
+    ;; TODO: Should the following be added?
+    "<" 'Custom-goto-parent
+
+    ;; quit
+    "q" 'Custom-buffer-done
+    "ZQ" 'evil-quit
+    "ZZ" 'Custom-buffer-done))
+
+(provide 'evil-collection-custom)
+;;; evil-collection-custom.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-custom.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-custom.elc
new file mode 100644
index 0000000000..348bee4b4d
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-custom.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-daemons.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-daemons.el
new file mode 100644
index 0000000000..c87b429d23
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-daemons.el
@@ -0,0 +1,67 @@
+;;; evil-collection-daemons.el --- Evil Bindings for Daemons -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 James Nguyen
+
+;; Author: Jay Kamat <jaygkamat@gmail.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, daemons, tools
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; Evil bindings for `daemons' from the `daemons.el' package.
+
+;;; Code:
+(require 'daemons nil t)
+(require 'evil-collection)
+
+(defconst evil-collection-daemons-maps '(daemons-mode-map
+                                         daemons-output-mode-map))
+
+(defun evil-collection-daemons-setup ()
+  "Set up `evil' bindings for `daemons'."
+  (evil-collection-define-key '(normal visual) 'daemons-mode-map
+    (kbd "RET") 'daemons-status-at-point
+    "s" 'daemons-start-at-point
+    "S" 'daemons-stop-at-point
+    "r" 'daemons-reload-at-point
+    "R" 'daemons-restart-at-point
+
+    "gr" 'revert-buffer
+
+    "q" 'quit-window
+    "ZZ" 'quit-window
+    "ZQ" 'quit-window)
+
+  ;; Functions are available in daemons-output-mode-map as well
+  (evil-collection-define-key '(normal visual) 'daemons-output-mode-map
+    (kbd "RET") 'daemons-status-at-point
+    "s" 'daemons-start-at-point
+    "S" 'daemons-stop-at-point
+    "r" 'daemons-reload-at-point
+    "R" 'daemons-restart-at-point
+
+    "q" 'quit-window
+    "ZZ" 'quit-window
+    "ZQ" 'quit-window)
+
+  (evil-set-initial-state 'daemons-mode 'normal)
+  (evil-set-initial-state 'daemons-output-mode 'normal))
+
+(provide 'evil-collection-daemons)
+;;; evil-collection-daemons.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-daemons.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-daemons.elc
new file mode 100644
index 0000000000..1cc3385840
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-daemons.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-debbugs.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-debbugs.el
new file mode 100644
index 0000000000..3085799fc4
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-debbugs.el
@@ -0,0 +1,75 @@
+;;; evil-collection-debbugs.el --- Evil bindings for debbugs -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 Pierre Neidhardt
+
+;; Author: Pierre Neidhardt <ambrevar@gmail.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, debbugs, tools
+
+;; This file 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, or (at your
+;; option) any later version.
+;;
+;; This file 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.
+;;
+;; For a full copy of the GNU General Public License
+;; see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; Evil bindings for debbugs.
+
+;;; Code:
+(require 'debbugs nil t)
+(require 'evil-collection)
+
+(defconst evil-collection-debbugs-maps '(debbugs-gnu-mode-map))
+
+(defun evil-collection-debbugs-setup ()
+  "Set up `evil' bindings for `debbugs-gnu-mode'."
+  (evil-set-initial-state 'debbugs-gnu-mode 'normal)
+
+  (evil-collection-define-key 'normal 'debbugs-gnu-mode-map
+    ;; motion
+    (kbd "<tab>") 'forward-button
+    (kbd "<backtab>") 'backward-button
+    (kbd "SPC") 'scroll-up-command
+
+    (kbd "<return>") 'debbugs-gnu-select-report
+    "c" 'debbugs-gnu-send-control-message
+    "d" 'debbugs-gnu-display-status
+
+    ;; filter
+    (kbd "s") 'debbugs-gnu-narrow-to-status
+    ;; "S" 'debbugs-gnu-widen ; Useless if we can just press "s RET" (empty filter).
+    "S" 'debbugs-gnu-toggle-suppress
+    "r" 'debbugs-gnu-show-all-blocking-reports
+
+    ;; sort
+    "o" 'debbugs-gnu-toggle-sort
+    "O" 'tabulated-list-sort
+
+    ;; show
+    "gB" 'debbugs-gnu-show-blocking-reports
+    "gb" 'debbugs-gnu-show-blocked-by-reports
+
+    ;; mark
+    "m" 'debbugs-gnu-toggle-tag
+
+    ;; refresh
+    "gr" 'debbugs-gnu-rescan
+
+    ;; quit
+    "q" 'quit-window
+    "ZQ" 'quit-window
+    "ZZ" 'quit-window))
+
+(provide 'evil-collection-debbugs)
+;;; evil-collection-debbugs.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-debbugs.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-debbugs.elc
new file mode 100644
index 0000000000..87f3aed786
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-debbugs.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-debug.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-debug.el
new file mode 100644
index 0000000000..425dd5e809
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-debug.el
@@ -0,0 +1,69 @@
+;;; evil-collection-debug.el --- Evil bindings for the debugger -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 Pierre Neidhardt
+
+;; Author: Pierre Neidhardt <ambrevar@gmail.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, debug, tools
+
+;; This file 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, or (at your
+;; option) any later version.
+;;
+;; This file 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.
+;;
+;; For a full copy of the GNU General Public License
+;; see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; Evil bindings for the debugger.
+
+;;; Code:
+
+(require 'evil-collection)
+(require 'debug)
+
+(defconst evil-collection-debug-maps '(debugger-mode-map))
+
+(defun evil-collection-debug-setup ()
+  "Set up `evil' bindings for `debug'."
+  (evil-set-initial-state 'debugger-mode 'normal)
+
+  (evil-collection-define-key 'normal 'debugger-mode-map
+    ;; motion
+    (kbd "<tab>") 'forward-button
+    (kbd "S-<tab>") 'backward-button
+    (kbd "<return>") 'debug-help-follow
+    (kbd "SPC") 'next-line
+
+    "R" 'debugger-record-expression
+    "c" 'debugger-continue
+    "d" 'debugger-step-through
+
+    "x" 'debugger-eval-expression
+    "E" 'debugger-eval-expression
+
+    "J" 'debugger-jump
+
+    "gl" 'debugger-list-functions
+    "gb" 'debugger-frame
+    "r" 'debugger-return-value
+    "u" 'debugger-frame-clear
+    "L" 'debugger-toggle-locals
+    "p" 'debugger-toggle-locals
+
+    ;; quit
+    "q" 'top-level
+    "ZQ" 'evil-quit
+    "ZZ" 'top-level))
+
+(provide 'evil-collection-debug)
+;;; evil-collection-debug.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-debug.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-debug.elc
new file mode 100644
index 0000000000..e48e503153
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-debug.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-diff-mode.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-diff-mode.el
new file mode 100644
index 0000000000..aeb480cfdb
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-diff-mode.el
@@ -0,0 +1,143 @@
+;;; evil-collection-diff-mode.el --- Add Evil bindings to diff-mode -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 Pierre Neidhardt
+
+;; Author: Pierre Neidhardt <ambrevar@gmail.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, diff, tools
+
+;; This file 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, or (at your
+;; option) any later version.
+;;
+;; This file 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.
+;;
+;; For a full copy of the GNU General Public License
+;; see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;
+;; Evil-Collection-Diff re-uses the read-only particularity of `diff-mode':
+;; When the buffer is read-only, enter motion state
+;; and manipulate the diffs with simple bindings.
+;; When the buffer is writage, use normal/insert states with some Evil-specific
+;; keys to ease navigation.
+;;
+;; See also `evil-collection-diff-toggle-setup'.
+
+;;; Code:
+
+(require 'evil-collection)
+(require 'diff-mode)
+
+(defconst evil-collection-diff-mode-maps '(diff-mode-map))
+
+(defun evil-collection-diff-read-only-state-switch ()
+  "Make read-only in motion state, writable in normal state."
+  (when (eq major-mode 'diff-mode)
+    (if buffer-read-only
+        (evil-motion-state)
+      (evil-normal-state))))
+
+(defun evil-collection-diff-toggle-setup ()
+  "Toggle visiting diff buffers in motion state."
+  (interactive)
+  (when (eq major-mode 'diff-mode)
+    (if (memq 'evil-collection-diff-read-only-state-switch read-only-mode-hook)
+        (remove-hook 'read-only-mode-hook 'evil-collection-diff-read-only-state-switch t)
+      (add-hook 'read-only-mode-hook 'evil-collection-diff-read-only-state-switch nil t))))
+
+;;; TODO: Report toggle function upstream?
+(defun evil-collection-diff-toggle-context-unified (start end)
+  "Toggle between context and unified views.
+
+START and END are either taken from the region (if a prefix arg is given) or
+else cover the whole buffer."
+  (interactive (if (or current-prefix-arg (use-region-p))
+                   (list (region-beginning) (region-end))
+                 (list (point-min) (point-max))))
+  ;; There seems to be no way to know whether we are in context or unified views.
+  ;; Workaround: assume that point-max will change.  This is brittle.
+  (let ((old-point-max (point-max)))
+    (diff-unified->context start end)
+    (when (= old-point-max (point-max))
+      (diff-context->unified start end))))
+
+;;; TODO: Report toggle function upstream?
+(defun evil-collection-diff-toggle-restrict-view (&optional arg)
+  "Toggle the restriction of the view to the current hunk.
+When restricting and if the prefix ARG is given, restrict the view to the
+current file instead."
+  (interactive "P")
+  (if (buffer-narrowed-p)
+      (widen)
+    (diff-restrict-view arg)))
+
+(defun evil-collection-diff-mode-setup ()
+  "Set up `evil' bindings for `diff-mode'."
+
+  ;; Don't switch to read-only/motion state by default as this can interfere
+  ;; with other modes which require a writable buffer, e.g. magit.
+  (evil-set-initial-state 'diff-mode 'normal)
+
+  (evil-collection-define-key 'normal 'diff-mode-map
+    ;; motion
+    (kbd "SPC") 'scroll-up-command
+    (kbd "S-SPC") 'scroll-down-command
+    (kbd "[") 'diff-file-prev
+    (kbd "]") 'diff-file-next
+    (kbd "C-j") 'diff-hunk-next
+    (kbd "C-k") 'diff-hunk-prev
+    "gj" 'diff-hunk-next
+    "gk" 'diff-hunk-prev
+
+    "\\" 'read-only-mode) ; magit has "\"
+
+  (evil-collection-define-key 'motion 'diff-mode-map
+    ;; motion
+    (kbd "SPC") 'scroll-up-command
+    (kbd "S-SPC") 'scroll-down-command
+    (kbd "[") 'diff-file-prev
+    (kbd "]") 'diff-file-next
+    (kbd "C-j") 'diff-hunk-next
+    (kbd "C-k") 'diff-hunk-prev
+    "gj" 'diff-hunk-next
+    "gk" 'diff-hunk-prev
+
+    (kbd "<return>") 'diff-goto-source
+    "A" 'diff-add-change-log-entries-other-window
+
+    "a" 'diff-apply-hunk
+    "*" 'diff-refine-hunk
+    "D" 'diff-file-kill
+    "d" 'diff-hunk-kill
+
+    "ge" 'diff-ediff-patch
+    "i" 'next-error-follow-minor-mode
+    "o" 'evil-collection-diff-toggle-restrict-view
+    "~" 'diff-reverse-direction
+    "s" 'diff-split-hunk
+    "c" 'diff-test-hunk
+    "x" 'evil-collection-diff-toggle-context-unified
+    "#" 'diff-ignore-whitespace-hunk
+
+    "\\" 'read-only-mode)) ; magit has "\"
+
+
+
+(add-hook 'diff-mode-hook 'evil-collection-diff-toggle-setup)
+
+(defun evil-collection-diff-unload-function ()
+  "For `unload-feature'."
+  (remove-hook 'diff-mode-hook 'evil-collection-diff-toggle-setup))
+
+(provide 'evil-collection-diff-mode)
+;;; evil-collection-diff-mode.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-diff-mode.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-diff-mode.elc
new file mode 100644
index 0000000000..f6f97099a9
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-diff-mode.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-dired.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-dired.el
new file mode 100644
index 0000000000..2f074cc898
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-dired.el
@@ -0,0 +1,190 @@
+;;; evil-collection-dired.el --- Evil bindings for Dired -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 James Nguyen
+
+;; Author: James Nguyen <james@jojojames.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, dired, tools
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; Evil bindings for Dired.
+
+;;; Code:
+(require 'dired)
+(require 'evil-collection)
+
+(defconst evil-collection-dired-maps '(dired-mode-map))
+
+(defun evil-collection-dired-setup ()
+  "Set up `evil' bindings for `dired'."
+  (evil-collection-define-key 'normal 'dired-mode-map
+    "q" 'quit-window
+    "j" 'dired-next-line
+    "k" 'dired-previous-line
+    [mouse-2] 'dired-mouse-find-file-other-window
+    [follow-link] 'mouse-face
+    ;; Commands to mark or flag certain categories of files
+    "#" 'dired-flag-auto-save-files
+    "." 'dired-clean-directory
+    "~" 'dired-flag-backup-files
+    ;; Upper case keys (except !) for operating on the marked files
+    "A" 'dired-do-find-regexp
+    "C" 'dired-do-copy
+    "B" 'dired-do-byte-compile
+    "D" 'dired-do-delete
+    "gG" 'dired-do-chgrp ;; FIXME: This can probably live on a better binding.
+    "H" 'dired-do-hardlink
+    "L" 'dired-do-load
+    "M" 'dired-do-chmod
+    "O" 'dired-do-chown
+    "P" 'dired-do-print
+    "Q" 'dired-do-find-regexp-and-replace
+    "R" 'dired-do-rename
+    "S" 'dired-do-symlink
+    "T" 'dired-do-touch
+    "X" 'dired-do-shell-command
+    "Z" 'dired-do-compress
+    "c" 'dired-do-compress-to
+    "!" 'dired-do-shell-command
+    "&" 'dired-do-async-shell-command
+    ;; Comparison commands
+    "=" 'dired-diff
+    ;; Tree Dired commands
+    (kbd "M-C-?") 'dired-unmark-all-files
+    (kbd "M-C-d") 'dired-tree-down
+    (kbd "M-C-u") 'dired-tree-up
+    (kbd "M-C-n") 'dired-next-subdir
+    (kbd "M-C-p") 'dired-prev-subdir
+    ;; move to marked files
+    (kbd "M-{") 'dired-prev-marked-file
+    (kbd "M-}") 'dired-next-marked-file
+    ;; Make all regexp commands share a `%' prefix:
+    ;; We used to get to the submap via a symbol dired-regexp-prefix,
+    ;; but that seems to serve little purpose, and copy-keymap
+    ;; does a better job without it.
+    "%" nil
+    "%u" 'dired-upcase
+    "%l" 'dired-downcase
+    "%d" 'dired-flag-files-regexp
+    "%g" 'dired-mark-files-containing-regexp
+    "%m" 'dired-mark-files-regexp
+    "%r" 'dired-do-rename-regexp
+    "%C" 'dired-do-copy-regexp
+    "%H" 'dired-do-hardlink-regexp
+    "%R" 'dired-do-rename-regexp
+    "%S" 'dired-do-symlink-regexp
+    "%&" 'dired-flag-garbage-files
+    ;; mark
+    "*" nil
+    "**" 'dired-mark-executables
+    "*/" 'dired-mark-directories
+    "*@" 'dired-mark-symlinks
+    "*%" 'dired-mark-files-regexp
+    "*(" 'dired-mark-sexp
+    "*." 'dired-mark-extension
+    "*O" 'dired-mark-omitted
+    "*c" 'dired-change-marks
+    "*s" 'dired-mark-subdir-files
+    "*m" 'dired-mark
+    "*u" 'dired-unmark
+    "*?" 'dired-unmark-all-files
+    "*!" 'dired-unmark-all-marks
+    "U" 'dired-unmark-all-marks
+    (kbd "* <delete>") 'dired-unmark-backward
+    (kbd "* C-n") 'dired-next-marked-file
+    (kbd "* C-p") 'dired-prev-marked-file
+    "*t" 'dired-toggle-marks
+    ;; Lower keys for commands not operating on all the marked files
+    "a" 'dired-find-alternate-file
+    "d" 'dired-flag-file-deletion
+    "gf" 'dired-find-file
+    (kbd "C-m") 'dired-find-file
+    "gr" 'revert-buffer
+    "i" 'dired-toggle-read-only
+    "I" 'dired-maybe-insert-subdir
+    "J" 'dired-goto-file
+    "K" 'dired-do-kill-lines
+    "r" 'dired-do-redisplay
+    "m" 'dired-mark
+    "t" 'dired-toggle-marks
+    "u" 'dired-unmark                   ; also "*u"
+    "W" 'browse-url-of-dired-file
+    "x" 'dired-do-flagged-delete
+    "gy" 'dired-show-file-type ;; FIXME: This could probably go on a better key.
+    "Y" 'dired-copy-filename-as-kill
+    "+" 'dired-create-directory
+    ;; open
+    (kbd "<return>") 'dired-find-file
+    (kbd "S-<return>") 'dired-find-file-other-window
+    (kbd "M-<return>") 'dired-display-file
+    "gO" 'dired-find-file-other-window
+    "go" 'dired-view-file
+    ;; sort
+    "o" 'dired-sort-toggle-or-edit
+    ;; moving
+    "gj" 'dired-next-dirline
+    "gk" 'dired-prev-dirline
+    "[" 'dired-prev-dirline
+    "]" 'dired-next-dirline
+    "<" 'dired-prev-dirline
+    ">" 'dired-next-dirline
+    "^" 'dired-up-directory
+    " " 'dired-next-line
+    [?\S-\ ] 'dired-previous-line
+    [remap next-line] 'dired-next-line
+    [remap previous-line] 'dired-previous-line
+    ;; hiding
+    "g$" 'dired-hide-subdir ;; FIXME: This can probably live on a better binding.
+    (kbd "M-$") 'dired-hide-all
+    "(" 'dired-hide-details-mode
+    ;; isearch
+    (kbd "M-s a C-s")   'dired-do-isearch
+    (kbd "M-s a M-C-s") 'dired-do-isearch-regexp
+    (kbd "M-s f C-s")   'dired-isearch-filenames
+    (kbd "M-s f M-C-s") 'dired-isearch-filenames-regexp
+    ;; misc
+    [remap read-only-mode] 'dired-toggle-read-only
+    ;; `toggle-read-only' is an obsolete alias for `read-only-mode'
+    [remap toggle-read-only] 'dired-toggle-read-only
+    "g?" 'dired-summary
+    (kbd "<delete>") 'dired-unmark-backward
+    [remap undo] 'dired-undo
+    [remap advertised-undo] 'dired-undo
+    ;; thumbnail manipulation (image-dired)
+    (kbd "C-t d") 'image-dired-display-thumbs
+    (kbd "C-t t") 'image-dired-tag-files
+    (kbd "C-t r") 'image-dired-delete-tag
+    (kbd "C-t j") 'image-dired-jump-thumbnail-buffer
+    (kbd "C-t i") 'image-dired-dired-display-image
+    (kbd "C-t x") 'image-dired-dired-display-external
+    (kbd "C-t a") 'image-dired-display-thumbs-append
+    (kbd "C-t .") 'image-dired-display-thumb
+    (kbd "C-t c") 'image-dired-dired-comment-files
+    (kbd "C-t f") 'image-dired-mark-tagged-files
+    (kbd "C-t C-t") 'image-dired-dired-toggle-marked-thumbs
+    (kbd "C-t e") 'image-dired-dired-edit-comment-and-tags
+    ;; encryption and decryption (epa-dired)
+    ";d" 'epa-dired-do-decrypt
+    ";v" 'epa-dired-do-verify
+    ";s" 'epa-dired-do-sign
+    ";e" 'epa-dired-do-encrypt))
+
+(provide 'evil-collection-dired)
+;;; evil-collection-dired.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-dired.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-dired.elc
new file mode 100644
index 0000000000..9f8507be37
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-dired.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-doc-view.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-doc-view.el
new file mode 100644
index 0000000000..41ccc539eb
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-doc-view.el
@@ -0,0 +1,83 @@
+;;; evil-collection-doc-view.el --- Evil bindings for docview. -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 James Nguyen
+
+;; Author: James Nguyen <james@jojojames.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, bindings, files, pdf, ps, dvi
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;; Evil bindings for doc-view.
+
+;;; Code:
+(require 'evil-collection)
+(require 'doc-view)
+
+(defconst evil-collection-doc-view-maps '(doc-view-mode-map))
+
+(defun evil-collection-doc-view-setup ()
+  "Set up `evil' bindings for `doc-view'."
+  (evil-set-initial-state 'doc-view-mode 'normal)
+  (evil-collection-define-key 'normal 'doc-view-mode-map
+    "q" 'quit-window
+    (kbd "C-j") 'doc-view-next-page
+    (kbd "C-k") 'doc-view-previous-page
+    "gj" 'doc-view-next-page
+    "gk" 'doc-view-previous-page
+    (kbd "C-d") 'forward-page
+    "j" 'doc-view-next-line-or-next-page
+    "k" 'doc-view-previous-line-or-previous-page
+    "gg" 'doc-view-first-page
+    "G" 'doc-view-last-page
+    "J" 'doc-view-goto-page
+    (kbd "<return>") 'image-next-line
+
+    ;; zoom
+    "+" 'doc-view-enlarge
+    "=" 'doc-view-enlarge
+    "0" 'doc-view-scale-reset
+    "-" 'doc-view-shrink
+
+    "W" 'doc-view-fit-width-to-window ; Like evil-image.
+    "H" 'doc-view-fit-height-to-window ; Like evil-image.
+    "P" 'doc-view-fit-page-to-window
+    "X" 'doc-view-kill-proc
+
+    (kbd "s s") 'doc-view-set-slice
+    (kbd "s m") 'doc-view-set-slice-using-mouse
+    (kbd "s b") 'doc-view-set-slice-from-bounding-box
+    (kbd "s r") 'doc-view-reset-slice
+
+    (kbd "/") 'doc-view-search
+    (kbd "?") 'doc-view-search-backward
+    (kbd "C-t") 'doc-view-show-tooltip
+    (kbd "C-c C-c") 'doc-view-toggle-display
+    (kbd "C-c C-t") 'doc-view-open-text
+
+    ;; refresh
+    (kbd "gr") 'doc-view-revert-buffer)
+
+  ;; TODO: What if the user changes `evil-want-C-u-scroll' after this is run?
+  (when evil-want-C-u-scroll
+    (evil-collection-define-key 'normal 'doc-view-mode-map
+      (kbd "C-u") 'backward-page)))
+
+(provide 'evil-collection-doc-view)
+;;; evil-collection-doc-view.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-doc-view.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-doc-view.elc
new file mode 100644
index 0000000000..ba2eab19fa
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-doc-view.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-edebug.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-edebug.el
new file mode 100644
index 0000000000..3da1fded5d
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-edebug.el
@@ -0,0 +1,124 @@
+;;; evil-collection-edebug.el --- Evil bindings for Edebug -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 James Nguyen
+
+;; Author: James Nguyen <james@jojojames.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, edebug, tools
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; Evil bindings for `edebug-mode'.
+
+;;; Code:
+(require 'edebug)
+(require 'evil-collection)
+
+(defconst evil-collection-edebug-maps
+  '(edebug-mode-map
+    edebug-x-instrumented-function-list-mode-map
+    edebug-x-breakpoint-list-mode-map))
+
+(defun evil-collection-edebug-setup ()
+  "Set up `evil' bindings for `edebug'."
+  (evil-set-initial-state 'edebug-mode 'normal)
+
+  (add-hook 'edebug-mode-hook #'evil-normalize-keymaps)
+
+  (evil-collection-define-key nil 'edebug-mode-map
+    "g" nil
+    "G" nil)
+
+  ;; FIXME: Seems like other minor modes will readily clash with `edebug'.
+  ;; `lispyville' and `edebug' 's' key?
+  (evil-collection-define-key 'normal 'edebug-mode-map
+    ;; control
+    "s" 'edebug-step-mode
+    "n" 'edebug-next-mode
+    "go" 'edebug-go-mode
+    "gO" 'edebug-Go-nonstop-mode
+    "t" 'edebug-trace-mode
+    "T" 'edebug-Trace-fast-mode
+    "c" 'edebug-continue-mode
+    "C" 'edebug-Continue-fast-mode
+
+    "f" 'edebug-forward-sexp
+    "H" 'edebug-goto-here
+    "I" 'edebug-instrument-callee
+    "i" 'edebug-step-in
+    "o" 'edebug-step-out
+
+    ;; quit
+    "q" 'top-level
+    "Q" 'edebug-top-level-nonstop
+    "a" 'abort-recursive-edit
+    "S" 'edebug-stop
+
+    ;; breakpoints
+    "b" 'edebug-set-breakpoint
+    "u" 'edebug-unset-breakpoint
+    "B" 'edebug-next-breakpoint
+    "x" 'edebug-set-conditional-breakpoint
+    "X" 'edebug-set-global-break-condition
+
+    ;; evaluation
+    "r" 'edebug-previous-result
+    "e" 'edebug-eval-expression
+    (kbd "C-x C-e") 'edebug-eval-last-sexp
+    "EL" 'edebug-visit-eval-list
+
+    ;; views
+    "WW" 'edebug-where
+    "p" 'edebug-bounce-point
+    "P" 'edebug-view-outside ;; same as v
+    "WS" 'edebug-toggle-save-windows
+
+    ;; misc
+    "g?" 'edebug-help
+    "d" 'edebug-backtrace
+
+    "-" 'negative-argument
+
+    ;; statistics
+    "=" 'edebug-temp-display-freq-count
+
+    ;; GUD bindings
+    (kbd "C-c C-s") 'edebug-step-mode
+    (kbd "C-c C-n") 'edebug-next-mode
+    (kbd "C-c C-c") 'edebug-go-mode
+
+    (kbd "C-x SPC") 'edebug-set-breakpoint
+    (kbd "C-c C-d") 'edebug-unset-breakpoint
+    (kbd "C-c C-t") (lambda () (interactive) (edebug-set-breakpoint t))
+    (kbd "C-c C-l") 'edebug-where)
+
+  (with-eval-after-load 'edebug-x
+    (evil-collection-define-key 'normal 'edebug-x-instrumented-function-list-mode-map
+      "E" 'edebug-x-evaluate-function
+      "Q" 'edebug-x-clear-data
+      (kbd "<return>") 'edebug-x-find-function
+      "q" 'quit-window)
+    (evil-collection-define-key 'normal 'edebug-x-breakpoint-list-mode-map
+      (kbd "<return>") 'edebug-x-visit-breakpoint
+      "x" 'edebug-x-kill-breakpoint
+      "Q" 'edebug-x-clear-data
+      "q" 'quit-window)))
+
+(provide 'evil-collection-edebug)
+;;; evil-collection-edebug.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-edebug.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-edebug.elc
new file mode 100644
index 0000000000..3571f0f3f3
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-edebug.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-ediff.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-ediff.el
new file mode 100644
index 0000000000..a37c442529
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-ediff.el
@@ -0,0 +1,204 @@
+;;; evil-collection-ediff.el --- Evil bindings for ediff -*- lexical-binding: t -*-
+;; Copyright (C) 2015 Justin Burkett
+
+;; Author: Justin Burkett <justin@burkett.cc>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Homepage: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1") (evil "1.2.3"))
+;; Keywords: evil, ediff, tools
+
+;; This file 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, or (at your
+;; option) any later version.
+;;
+;; This file 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.
+;;
+;; For a full copy of the GNU General Public License
+;; see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Make ediff a little evil. This configures ediff to be friendlier to users
+;; of vim-like keybindings. Consult the help buffer (=?=) for more info.
+
+;; Here's a table describing the bindings
+
+;; | Command                     | Original Binding | Evil-ediff  |
+;; |-----------------------------+------------------+-------------|
+;; | ediff-next-difference       | n,SPC            | C-j,n,SPC   |
+;; | ediff-previous-difference   | p,DEL            | C-k,N,p,DEL |
+;; | ediff-jump-to-difference    | j                | d           |
+;; | jump to first difference    | 1j               | gg (or 1d)  |
+;; | jump to last difference     | N/A              | G           |
+;; | copy region A to region B   | a                | a,l         |
+;; | copy region B to region A   | b                | b,h         |
+;; | scroll down 1 line          | C-u 1 v          | j           |
+;; | scroll up 1 line            | C-u 1 V          | k           |
+;; | scroll down half page       | v,C-v            | C-d,v,C-v   |
+;; | scroll up half page         | V,M-v            | C-u,V,M-v   |
+;; | scroll left                 | >                | zh          |
+;; | scroll right                | <                | zl          |
+;; | toggle highlighting         | h                | H           |
+;; | ediff-suspend               | z                | C-z         |
+
+;; Not implemented yet
+;; | restore old diff            | ra,rb,rc         | u           |
+
+;;; Code:
+
+(require 'evil-collection)
+(require 'ediff nil t)
+
+(defconst evil-collection-ediff-maps '(ediff-mode-map))
+
+(defvar evil-collection-ediff-initial-state-backup (evil-initial-state 'ediff-mode))
+(defvar evil-collection-ediff-long-help-message-compare2-backup ediff-long-help-message-compare2)
+(defvar evil-collection-ediff-long-help-message-compare3-backup  ediff-long-help-message-compare3)
+(defvar evil-collection-ediff-long-help-message-narrow2-backup  ediff-long-help-message-narrow2)
+(defvar evil-collection-ediff-long-help-message-word-backup  ediff-long-help-message-word-mode)
+(defvar evil-collection-ediff-long-help-message-merge-backup  ediff-long-help-message-merge)
+(defvar evil-collection-ediff-long-help-message-head-backup  ediff-long-help-message-head)
+(defvar evil-collection-ediff-long-help-message-tail-backup  ediff-long-help-message-tail)
+
+(defvar evil-collection-ediff-help-changed nil)
+
+(defun evil-collection-ediff-adjust-help ()
+  "Adjust long help messages to reflect evil-ediff bindings."
+  (unless evil-collection-ediff-help-changed
+    (dolist (msg '(ediff-long-help-message-compare2
+                   ediff-long-help-message-compare3
+                   ediff-long-help-message-narrow2
+                   ediff-long-help-message-word-mode
+                   ediff-long-help-message-merge
+                   ediff-long-help-message-head
+                   ediff-long-help-message-tail))
+      (dolist (chng '( ;;("^" . "  ")
+                      ("p,DEL -previous diff " . "k,N,p -previous diff ")
+                      ("n,SPC -next diff     " . "  j,n -next diff     ")
+                      ("    j -jump to diff  " . "    d -jump to diff  ")
+                      ("    h -highlighting  " . "    H -highlighting  ")
+                      ("  v/V -scroll up/dn  " . "C-u/d -scroll up/dn  ")
+                      ("  </> -scroll lt/rt  " . "zh/zl -scroll lt/rt  ")
+                      ("  z/q -suspend/quit"   . "C-z/q -suspend/quit")))
+        (setf (symbol-value msg)
+              (replace-regexp-in-string (car chng) (cdr chng) (symbol-value msg))))))
+  (setq evil-collection-ediff-help-changed t))
+
+(defun evil-collection-ediff-scroll-left (&optional arg)
+  "Scroll left."
+  (interactive "P")
+  (let ((last-command-event ?>))
+    (ediff-scroll-horizontally arg)))
+
+(defun evil-collection-ediff-scroll-right (&optional arg)
+  "Scroll right."
+  (interactive "P")
+  (let ((last-command-event ?<))
+    (ediff-scroll-horizontally arg)))
+
+(defun evil-collection-ediff-scroll-up (&optional arg)
+  "Scroll up by half of a page."
+  (interactive "P")
+  (let ((last-command-event ?V))
+    (ediff-scroll-vertically arg)))
+
+(defun evil-collection-ediff-scroll-down (&optional arg)
+  "Scroll down by half of a page."
+  (interactive "P")
+  (let ((last-command-event ?v))
+    (ediff-scroll-vertically arg)))
+
+(defun evil-collection-ediff-scroll-down-1 ()
+  "Scroll down by a line."
+  (interactive)
+  (let ((last-command-event ?v))
+    (ediff-scroll-vertically 1)))
+
+(defun evil-collection-ediff-scroll-up-1 ()
+  "Scroll down by a line."
+  (interactive)
+  (let ((last-command-event ?V))
+    (ediff-scroll-vertically 1)))
+
+(defun evil-collection-ediff-first-difference ()
+  "Jump to first difference."
+  (interactive)
+  (ediff-jump-to-difference 1))
+
+(defun evil-collection-ediff-last-difference ()
+  "Jump to last difference."
+  (interactive)
+  (ediff-jump-to-difference ediff-number-of-differences))
+
+;; (defun evil-collection-ediff-restore-diff ()
+;;   "Restore the copy of current region."
+;;   (interactive)
+;;   (ediff-restore-diff nil ?a)
+;;   (ediff-restore-diff nil ?b))
+
+(defvar evil-collection-ediff-bindings
+  '(("d"    . ediff-jump-to-difference)
+    ("H"    . ediff-toggle-hilit)
+    ("\C-e" . evil-collection-ediff-scroll-down-1)
+    ("\C-y" . evil-collection-ediff-scroll-up-1)
+    ("j"    . ediff-next-difference)
+    ("k"    . ediff-previous-difference)
+    ("N"    . ediff-previous-difference)
+    ("gg"   . evil-collection-ediff-first-difference)
+    ("G"    . evil-collection-ediff-last-difference)
+    ("\C-d" . evil-collection-ediff-scroll-down)
+    ("\C-u" . evil-collection-ediff-scroll-up)
+    ("\C-z" . ediff-suspend)
+    ("z"    . nil)
+    ("zl"   . evil-collection-ediff-scroll-right)
+    ("zh"   . evil-collection-ediff-scroll-left)
+    ;; Not working yet
+    ;; ("u"    . evil-collection-ediff-restore-diff)
+    )
+  "A list of bindings changed/added in evil-ediff.")
+
+(defun evil-collection-ediff-startup-hook ()
+  "Place evil-ediff bindings in `ediff-mode-map'."
+  (evil-make-overriding-map ediff-mode-map 'normal)
+  (dolist (entry evil-collection-ediff-bindings)
+    (define-key ediff-mode-map (car entry) (cdr entry)))
+  (unless (or ediff-3way-comparison-job
+              (eq ediff-split-window-function 'split-window-vertically))
+    (define-key ediff-mode-map "l" 'ediff-copy-A-to-B)
+    (define-key ediff-mode-map "h" 'ediff-copy-B-to-A))
+  (evil-normalize-keymaps)
+  nil)
+
+(defun evil-collection-ediff-setup ()
+  "Initialize evil-ediff."
+  (interactive)
+  (evil-set-initial-state 'ediff-mode 'normal)
+  (add-hook 'ediff-startup-hook 'evil-collection-ediff-startup-hook)
+  (evil-collection-ediff-adjust-help))
+
+(defun evil-collection-ediff-revert ()
+  "Revert changes made by evil-ediff."
+  (interactive)
+  (evil-set-initial-state 'ediff-mode evil-collection-ediff-initial-state-backup)
+  (unless evil-collection-ediff-help-changed
+    (dolist (msg
+             '((ediff-long-help-message-compare2 . ediff-long-help-message-compare2-backup)
+               (ediff-long-help-message-compare3 . ediff-long-help-message-compare3-backup)
+               (ediff-long-help-message-narrow2 . ediff-long-help-message-narrow2-backup)
+               (ediff-long-help-message-word-mode . ediff-long-help-message-word-mode-backup)
+               (ediff-long-help-message-merge . ediff-long-help-message-merge-backup)
+               (ediff-long-help-message-head . ediff-long-help-message-head-backup)
+               (ediff-long-help-message-tail . ediff-long-help-message-tail-backup)))
+      (setf (symbol-value (car msg)) (symbol-value (cdr msg)))))
+  (setq evil-collection-ediff-help-changed nil)
+  (remove-hook 'ediff-startup-hook 'evil-collection-ediff-startup-hook))
+
+(provide 'evil-collection-ediff)
+;;; evil-collection-ediff.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-ediff.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-ediff.elc
new file mode 100644
index 0000000000..c15e247c4a
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-ediff.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-eldoc.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-eldoc.el
new file mode 100644
index 0000000000..7988f0aa04
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-eldoc.el
@@ -0,0 +1,39 @@
+;;; evil-collection-eldoc.el --- Bindings for `eldoc'. -*- lexical-binding: t -*-
+
+;; Copyright (C) 2018 James Nguyen
+
+;; Author: James Nguyen <james@jojojames.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, emacs, tools
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;; Bindings for `eldoc'.
+
+;;; Code:
+(require 'eldoc)
+(require 'evil-collection)
+
+(defun evil-collection-eldoc-setup ()
+  "Set up `evil' bindings for `eldoc'.."
+  (when (fboundp 'eldoc-add-command-completions)
+    (eldoc-add-command-completions "evil-window-")))
+
+(provide 'evil-collection-eldoc)
+;;; evil-collection-eldoc.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-eldoc.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-eldoc.elc
new file mode 100644
index 0000000000..e05d134893
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-eldoc.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-elfeed.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-elfeed.el
new file mode 100644
index 0000000000..6da2e89e2e
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-elfeed.el
@@ -0,0 +1,120 @@
+;;; evil-collection-elfeed.el --- Evil bindings for elfeed -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 Pierre Neidhardt
+
+;; Author: Pierre Neidhardt <ambrevar@gmail.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, elfeed, tools
+
+;; This file 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, or (at your
+;; option) any later version.
+;;
+;; This file 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.
+;;
+;; For a full copy of the GNU General Public License
+;; see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; Evil bindings for elfeed.
+
+;;; Code:
+(require 'elfeed nil t)
+(require 'evil-collection)
+
+(defvar elfeed-search-mode-map)
+(defvar elfeed-show-mode-map)
+
+(defconst evil-collection-elfeed-maps '(elfeed-search-mode-map
+                                        elfeed-show-mode-map))
+
+(defun evil-collection-elfeed-setup ()
+  "Set up `evil' bindings for `elfeed'."
+
+  (evil-collection-inhibit-insert-state 'elfeed-search-mode-map)
+  (evil-set-initial-state 'elfeed-search-mode 'normal)
+  (evil-collection-define-key 'normal 'elfeed-search-mode-map
+    ;; open
+    (kbd "<return>") 'elfeed-search-show-entry
+    (kbd "S-<return>") 'elfeed-search-browse-url
+    "go" 'elfeed-search-browse-url
+
+    "y" 'elfeed-search-yank
+
+    (kbd "SPC") 'scroll-up-command
+    (kbd "S-SPC") 'scroll-down-command
+
+    ;; filter
+    "s" 'elfeed-search-live-filter
+    "S" 'elfeed-search-set-filter
+
+    ;; refresh
+    "gR" 'elfeed-search-fetch ; TODO: Which update function is more useful?
+    "gr" 'elfeed-search-update--force
+
+    ;; quit
+    "q" 'quit-window
+    "ZQ" 'quit-window
+    "ZZ" 'quit-window)
+
+  (evil-collection-define-key '(normal visual) 'elfeed-search-mode-map
+    "+" 'elfeed-search-tag-all
+    "-" 'elfeed-search-untag-all
+    "U" 'elfeed-search-tag-all-unread
+    "u" 'elfeed-search-untag-all-unread)
+
+  (evil-collection-inhibit-insert-state 'elfeed-show-mode-map)
+  (evil-set-initial-state 'elfeed-show-mode 'normal)
+  (evil-collection-define-key 'normal 'elfeed-show-mode-map
+    (kbd "S-<return>") 'elfeed-show-visit
+    "go" 'elfeed-show-visit
+
+    (kbd "SPC") 'scroll-up-command
+    (kbd "S-SPC") 'scroll-down-command
+
+    ;; filter
+    "s" 'elfeed-show-new-live-search
+
+    "+" 'elfeed-show-tag
+    "-" 'elfeed-show-untag
+
+    "A" 'elfeed-show-add-enclosure-to-playlist
+    "P" 'elfeed-show-play-enclosure
+    "d" 'elfeed-show-save-enclosure
+
+    "]" 'elfeed-show-next
+    "[" 'elfeed-show-prev
+    "gj" 'elfeed-show-next
+    "gk" 'elfeed-show-prev
+    (kbd "C-j") 'elfeed-show-next
+    (kbd "C-k") 'elfeed-show-prev
+
+    ;; refresh
+    "gr" 'elfeed-show-refresh
+
+    ;; quit
+    "q" 'elfeed-kill-buffer
+    "ZQ" 'elfeed-kill-buffer
+    "ZZ" 'elfeed-kill-buffer)
+
+  (evil-collection-define-key 'operator 'elfeed-show-mode-map
+    ;; Like `eww'.
+    "u" '(menu-item
+          ""
+          nil
+          :filter (lambda (&optional _)
+                    (when (memq evil-this-operator
+                                evil-collection-yank-operators)
+                      (setq evil-inhibit-operator t)
+                      #'elfeed-show-yank)))))
+
+(provide 'evil-collection-elfeed)
+;;; evil-collection-elfeed.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-elfeed.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-elfeed.elc
new file mode 100644
index 0000000000..dc44d098c1
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-elfeed.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-elisp-mode.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-elisp-mode.el
new file mode 100644
index 0000000000..7c356bb5e2
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-elisp-mode.el
@@ -0,0 +1,78 @@
+;;; evil-collection-elisp-mode.el --- Bindings for `elisp-mode'. -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 James Nguyen
+
+;; Author: James Nguyen <james@jojojames.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, elisp, lisp
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;; Bindings for `elisp-mode'.
+
+;;; Code:
+(require 'elisp-mode)
+(require 'evil-collection)
+
+(defconst evil-collection-elisp-mode-maps nil)
+
+(defun evil-collection-elisp-mode-last-sexp-setup-props (beg end value alt1 alt2)
+  "Set up text properties for the output of `elisp--eval-last-sexp'.
+BEG and END are the start and end of the output in current-buffer.
+VALUE is the Lisp value printed, ALT1 and ALT2 are strings for the
+alternative printed representations that can be displayed."
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "C-m") 'evil-collection-elisp-mode-return-or-last-sexp-toggle-display)
+    (define-key map [down-mouse-2] 'mouse-set-point)
+    (define-key map [mouse-2] 'elisp-last-sexp-toggle-display)
+    (add-text-properties
+     beg end
+     `(printed-value (,value ,alt1 ,alt2)
+                     mouse-face highlight
+                     keymap ,map
+                     help-echo "RET, mouse-2: toggle abbreviated display"
+                     rear-nonsticky (mouse-face keymap help-echo
+                                                printed-value)))))
+
+(defun evil-collection-elisp-mode-return-or-last-sexp-toggle-display ()
+  "Trigger RET or call `elisp-last-sexp-toggle-display'."
+  (interactive)
+  (if (eq evil-state 'insert)
+      (call-interactively
+       (lookup-key (current-global-map) (kbd "C-m")))
+    (call-interactively 'elisp-last-sexp-toggle-display)))
+
+(defun evil-collection-elisp-mode-last-sexp (command &rest args)
+  "In normal-state or motion-state, last sexp ends at point."
+  (if (and (not evil-move-beyond-eol)
+           (or (evil-normal-state-p) (evil-motion-state-p)))
+      (save-excursion
+        (unless (or (eobp) (eolp)) (forward-char))
+        (apply command args))
+    (apply command args)))
+
+(defun evil-collection-elisp-mode-setup ()
+  "Set up `evil' bindings for `elisp-mode'."
+  (unless evil-move-beyond-eol
+    (advice-add 'eval-print-last-sexp :around 'evil-collection-elisp-mode-last-sexp))
+  (advice-add 'last-sexp-setup-props
+              :override 'evil-collection-elisp-mode-last-sexp-setup-props))
+
+(provide 'evil-collection-elisp-mode)
+;;; evil-collection-elisp-mode.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-elisp-mode.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-elisp-mode.elc
new file mode 100644
index 0000000000..03dcb695ca
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-elisp-mode.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-elisp-refs.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-elisp-refs.el
new file mode 100644
index 0000000000..bdb06e92f1
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-elisp-refs.el
@@ -0,0 +1,51 @@
+;;; evil-collection-elisp-refs.el --- Evil bindings for Elisp Refs -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 James Nguyen
+
+;; Author: James Nguyen <james@jojojames.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, elisp-refs, tools
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; This package provides a sane set of defaults for `elisp-refs' when using
+;; `evil-mode'.
+
+;;; Code:
+(require 'evil-collection)
+(require 'elisp-refs nil t)
+
+(defconst evil-collection-elisp-refs-maps '(elisp-refs-mode-map))
+
+(defun evil-collection-elisp-refs-setup ()
+  "Set up `evil' bindings for `elisp-refs'."
+  (evil-collection-define-key 'normal 'elisp-refs-mode-map
+    (kbd "<tab>") 'elisp-refs-next-match
+    (kbd "<backtab>") 'elisp-refs-prev-match
+    (kbd "C-j") 'elisp-refs-next-match
+    (kbd "C-k") 'elisp-refs-prev-match
+    "gj" 'elisp-refs-next-match
+    "gk" 'elisp-refs-prev-match
+    (kbd "<return>") 'elisp-refs-visit-match
+
+    ;; quit
+    "q" 'kill-this-buffer))
+
+(provide 'evil-collection-elisp-refs)
+;;; evil-collection-elisp-refs.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-elisp-refs.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-elisp-refs.elc
new file mode 100644
index 0000000000..ab496d8c8e
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-elisp-refs.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-emms.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-emms.el
new file mode 100644
index 0000000000..22a3b8f371
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-emms.el
@@ -0,0 +1,234 @@
+;;; evil-collection-emms.el --- Evil bindings for EMMS -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 Pierre Neidhardt
+
+;; Author: Pierre Neidhardt <ambrevar@gmail.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, emms, tools
+
+;; This file 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, or (at your
+;; option) any later version.
+;;
+;; This file 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.
+;;
+;; For a full copy of the GNU General Public License
+;; see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; Evil bindings for EMMS.
+
+;;; Code:
+(require 'emms nil t)
+(require 'evil-collection)
+
+(declare-function emms-with-inhibit-read-only-t "emms")
+(declare-function emms-playlist-mode-correct-previous-yank "emms-playlist-mode")
+
+(defvar emms-browser-mode-map)
+(defvar emms-playlist-mode-map)
+
+(defconst evil-collection-emms-maps '(emms-browser-mode-map
+                                      emms-playlist-mode-map
+                                      emms-metaplaylist-mode-map
+                                      emms-stream-mode-map))
+
+(defun evil-collection-emms-playlist-mode-insert-newline-above ()
+  "Insert a newline above point."
+  (interactive)
+  (emms-with-inhibit-read-only-t
+   (evil-insert-newline-above)))
+
+(defun evil-collection-emms-playlist-mode-insert-newline-below ()
+  "Insert a newline below point."
+  (interactive)
+  (emms-with-inhibit-read-only-t
+   (evil-insert-newline-below)))
+
+(defun evil-collection-emms-playlist-mode-paste-before ()
+  "Pastes the latest yanked playlist items before the cursor position.
+The return value is the yanked text."
+  (interactive)
+  (emms-with-inhibit-read-only-t
+   (goto-char (point-at-bol))
+   (yank)
+   (emms-playlist-mode-correct-previous-yank)
+   (evil-previous-line)
+   (evil-beginning-of-line)))
+
+(defun evil-collection-emms-playlist-mode-paste-after ()
+  "Pastes the latest yanked playlist items behind point.
+The return value is the yanked text."
+  (interactive)
+  (unless (eobp) (evil-next-line))
+  (evil-collection-emms-playlist-mode-paste-before))
+
+(defun evil-collection-emms-browser-setup ()
+  "Set up `evil' bindings for `emms-browser'."
+  ;; TODO: Why doesn't evil-set-initial-state work with emms-browser-mode?
+
+  (evil-collection-inhibit-insert-state 'emms-browser-mode-map)
+  (add-hook 'emms-browser-mode-hook 'evil-normal-state)
+  (evil-collection-define-key 'normal 'emms-browser-mode-map
+    ;; playback controls
+    "x" 'emms-pause
+    "X" 'emms-stop
+    "r" 'emms-random
+    "<" 'emms-seek-backward
+    ">" 'emms-seek-forward
+    (kbd "<return>") 'emms-browser-add-tracks
+    (kbd "C-<return>") 'emms-browser-add-tracks-and-play
+
+    ;; volume controls
+    "+" 'emms-volume-raise
+    "=" 'emms-volume-raise
+    "-" 'emms-volume-lower
+
+    "u" 'emms-playlist-mode-undo
+
+    ;; motion
+    "[" 'emms-browser-prev-non-track
+    "]" 'emms-browser-next-non-track
+    (kbd "C-k") 'emms-browser-prev-non-track
+    (kbd "C-j") 'emms-browser-next-non-track
+    "gk" 'emms-browser-prev-non-track
+    "gj" 'emms-browser-next-non-track
+
+    (kbd "<tab>") 'emms-browser-toggle-subitems-recursively
+    (kbd "<backtab>") 'emms-browser-toggle-subitems-recursively
+    "^" 'emms-browser-move-up-level
+    (kbd "SPC") 'emms-browser-toggle-subitems
+    "g1" 'emms-browser-collapse-all
+    "g2" 'emms-browser-expand-to-level-2
+    "g3" 'emms-browser-expand-to-level-3
+    "g4" 'emms-browser-expand-to-level-4
+    "g0" 'emms-browser-expand-all
+    "ga" 'emms-browse-by-artist
+    "gA" 'emms-browse-by-album
+    "gb" 'emms-browse-by-genre
+    "gy" 'emms-browse-by-year
+    "gc" 'emms-browse-by-composer
+    "gp" 'emms-browse-by-performer
+    "zm" 'emms-browser-collapse-all
+    "zr" 'emms-browser-expand-all
+    "zo" 'emms-browser-expand-one-level
+    ;; TODO find a real replacement for zc
+    "zc" 'emms-browser-collapse-all
+
+    ;; TODO find a way to integrate this with evil-collection-evil-search
+    "/" 'emms-isearch-buffer ; This shows hidden items during search.
+    "n" 'isearch-repeat-forward
+    "N" 'isearch-repeat-backward
+
+    ;; filter
+    ;; "" 'emms-browser-previous-filter ; TODO: What does this do?
+    ;; "" 'emms-browser-next-filter
+
+    "s" (lookup-key emms-browser-mode-map (kbd "s"))
+    "g" (lookup-key emms-browser-mode-map (kbd "W")) ;; TODO: This overrides other "g-" prefixed keys.
+
+    "C" 'emms-browser-clear-playlist
+    "D" 'emms-browser-delete-files
+    "d" 'emms-browser-view-in-dired
+    "gd" 'emms-browser-view-in-dired)) ; "d" does the same, keep "gd" for consistency.
+
+(defun evil-collection-emms-setup ()
+  "Set up `evil' bindings for `emms'."
+  (with-eval-after-load 'emms-browser
+    (evil-collection-emms-browser-setup))
+
+  (evil-set-initial-state 'emms-playlist-mode 'normal)
+  (evil-collection-define-key 'normal 'emms-playlist-mode-map
+    ;; playback controls
+    "x" 'emms-pause
+    "X" 'emms-stop
+    "r" 'emms-random
+    "<" 'emms-seek-backward
+    ">" 'emms-seek-forward
+    (kbd "C-j") 'emms-next
+    (kbd "C-k") 'emms-previous
+    "gj" 'emms-next
+    "gk" 'emms-previous
+    (kbd "<return>") 'emms-playlist-mode-play-smart
+
+    ;; volume controls
+    "+" 'emms-volume-raise
+    "=" 'emms-volume-raise
+    "-" 'emms-volume-lower
+
+    "u" 'emms-playlist-mode-undo
+
+    ;; motion
+    "gg" 'emms-playlist-mode-first
+    "G" 'emms-playlist-mode-last
+    "]" 'emms-playlist-mode-next
+    "[" 'emms-playlist-mode-previous
+
+    "D" 'emms-playlist-mode-kill-track  ; emms-browser uses "D"
+    "C" 'emms-playlist-mode-clear
+    "O" 'evil-collection-emms-playlist-mode-insert-newline-above
+    "o" 'evil-collection-emms-playlist-mode-insert-newline-below
+    "P" 'evil-collection-emms-playlist-mode-paste-before
+    "p" 'evil-collection-emms-playlist-mode-paste-after
+
+    "u" 'emms-playlist-mode-undo
+
+    "ze" 'emms-tag-editor-edit
+    "R" 'emms-tag-editor-rename
+
+    "." 'emms-playlist-mode-center-current
+    "d" 'emms-playlist-mode-goto-dired-at-point
+    "gd" 'emms-playlist-mode-goto-dired-at-point ; "d" does the same, keep "gd" for consistency.
+
+    "zs" 'emms-show
+    "a" 'emms-playlist-mode-add-contents
+    "zp" 'emms-playlist-set-playlist-buffer
+
+    ;; filter
+    "S" (lookup-key emms-playlist-mode-map (kbd "S"))
+    "s" (lookup-key emms-playlist-mode-map (kbd "/"))
+    ;; "" 'emms-playlist-limit-to-all ; TODO: Test.
+
+    (kbd "M-y") 'emms-playlist-mode-yank-pop)
+
+  (evil-collection-define-key 'visual 'emms-playlist-mode-map
+    ;; "d" 'emms-playlist-mode-kill
+    "D" 'emms-playlist-mode-kill)
+
+  (evil-collection-define-key 'normal 'emms-browser-search-mode-map
+    "q" 'emms-browser-kill-search)
+
+  (evil-set-initial-state 'emms-metaplaylist-mode 'normal)
+  (evil-collection-define-key 'normal 'emms-metaplaylist-mode-map
+    (kbd "<return>") 'emms-metaplaylist-mode-goto-current
+    (kbd "<space>") 'emms-metaplaylist-mode-set-active
+    "gr" 'emms-metaplaylist-mode-update
+    "C" 'emms-metaplaylist-mode-new-buffer
+    "." 'emms-metaplaylist-mode-center-current
+    "D" 'emms-metaplaylist-mode-kill-buffer
+    "q" 'kill-this-buffer)
+
+  (evil-set-initial-state 'emms-stream-mode 'normal)
+  (evil-collection-define-key 'normal 'emms-stream-mode-map
+    (kbd "<return>") 'emms-stream-play
+    "j" 'emms-stream-next-line
+    "k" 'emms-stream-previous-line
+    "y" 'emms-stream-yank-bookmark
+    "d" 'emms-stream-kill-bookmark
+    "c" 'emms-stream-edit-bookmark
+    "r" 'emms-stream-edit-bookmark
+    "i" 'emms-stream-info-bookmark
+    "s" 'emms-stream-save-bookmarks-file
+    "x" 'emms-stream-toggle-default-action
+    "q" 'emms-stream-quit))
+
+(provide 'evil-collection-emms)
+;;; evil-collection-emms.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-emms.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-emms.elc
new file mode 100644
index 0000000000..70ab384475
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-emms.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-epa.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-epa.el
new file mode 100644
index 0000000000..f49a70df05
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-epa.el
@@ -0,0 +1,70 @@
+;;; evil-collection-epa.el --- Evil bindings for epa-mode -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 James Nguyen
+
+;; Author: Maximiliano Sandoval <msandova@protonmail.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, epa, tools
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; Evil bindings for `epa-mode'.
+
+;;; Code:
+
+(require 'evil-collection)
+(require 'epa nil t)
+
+(defconst evil-collection-epa-maps '(epa-key-list-mode-map
+                                     epa-key-mode-map
+                                     epa-info-mode-map))
+
+(defun evil-collection-epa-setup ()
+  (evil-collection-define-key 'normal 'epa-key-list-mode-map
+    (kbd "<tab>") 'widget-forward
+    "gr" 'revert-buffer
+    "q" 'epa-exit-buffer
+    "E" 'epa-decrypt-file
+    "d" 'epa-delete-keys
+    "ZZ" 'quit-window
+    "ZQ" 'evil-quit
+    "V" 'epa-verify-file
+
+    ;; mark
+    "m" 'epa-mark-key
+    "u" 'epa-unmark-key
+
+    ;; Unchanged keybindings.
+    "s" 'epa-sign-file
+    "e" 'epa-encrypt-file
+    "i" 'epa-import-keys
+    "o" 'epa-export-keys)
+
+  (evil-collection-define-key 'normal 'epa-key-mode-map
+    "q" 'epa-exit-buffer
+    "ZZ" 'quit-window
+    "ZQ" 'evil-quit)
+
+  (evil-collection-define-key 'normal 'epa-info-mode-map
+    "q" 'delete-window
+    "ZZ" 'quit-window
+    "ZQ" 'evil-quit))
+
+(provide 'evil-collection-epa)
+;;; evil-collection-epa.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-epa.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-epa.elc
new file mode 100644
index 0000000000..337e9be5a9
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-epa.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-ert.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-ert.el
new file mode 100644
index 0000000000..7ba967f61f
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-ert.el
@@ -0,0 +1,69 @@
+;;; evil-collection-ert.el --- Bindings for `ert' -*- lexical-binding: t -*-
+
+;; Copyright (C) 2018 James Nguyen
+
+;; Author: James Nguyen <james@jojojames.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, emacs, tools
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;; Bindings for `ert'
+
+;;; Code:
+(require 'ert)
+(require 'evil-collection)
+
+(defconst evil-collection-ert-maps '(ert-results-mode-map))
+
+(defun evil-collection-ert-setup ()
+  "Set up `evil' bindings for `ert'."
+  (evil-set-initial-state 'ert-results-mode 'normal)
+
+  (evil-collection-define-key 'normal 'ert-results-mode-map
+    "j" 'evil-next-line
+    "k" 'evil-previous-line
+    "h" 'evil-backward-char
+    "l" 'evil-forward-char
+    ;; Stuff that's not in the menu.
+    "J" 'ert-results-jump-between-summary-and-result
+    "L" 'ert-results-toggle-printer-limits-for-test-at-point
+    "gj" 'ert-results-next-test
+    "gk" 'ert-results-previous-test
+    "]" 'ert-results-next-test
+    "[" 'ert-results-previous-test
+    (kbd "C-j") 'ert-results-next-test
+    (kbd "C-k") 'ert-results-previous-test
+    ;; Stuff that is in the menu.
+    "gr" 'ert-results-rerun-all-tests
+    "R" 'ert-results-rerun-all-tests
+    "r" 'ert-results-rerun-test-at-point
+    "d" 'ert-results-rerun-test-at-point-debugging-errors
+    "." 'ert-results-find-test-at-point-other-window
+    "gd" 'ert-results-find-test-at-point-other-window
+    "B" 'ert-results-pop-to-backtrace-for-test-at-point
+    "M" 'ert-results-pop-to-messages-for-test-at-point
+    "S" 'ert-results-pop-to-should-forms-for-test-at-point
+    "K" 'ert-results-describe-test-at-point
+    "g?" 'ert-results-describe-test-at-point
+    "x" 'ert-delete-test
+    "T" 'ert-results-pop-to-timings))
+
+(provide 'evil-collection-ert)
+;;; evil-collection-ert.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-ert.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-ert.elc
new file mode 100644
index 0000000000..44967bc4f9
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-ert.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-eshell.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-eshell.el
new file mode 100644
index 0000000000..fb7419720c
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-eshell.el
@@ -0,0 +1,96 @@
+;;; evil-collection-eshell.el --- Evil bindings for Eshell -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 Pierre Neidhardt
+
+;; Author: Pierre Neidhardt <ambrevar@gmail.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, eshell, tools
+
+;; This file 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, or (at your
+;; option) any later version.
+;;
+;; This file 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.
+;;
+;; For a full copy of the GNU General Public License
+;; see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; Evil bindings for EMMS
+
+;;; Code:
+(require 'em-prompt)
+(require 'eshell)
+(require 'evil-collection)
+
+(defconst evil-collection-eshell-maps '(eshell-mode-map))
+
+(defun evil-collection-eshell-next-prompt ()
+  "`evil' wrapper around `eshell-next-prompt'."
+  (when (get-text-property (point) 'read-only)
+    ;; If at end of prompt, `eshell-next-prompt' will not move, so go backward.
+    (beginning-of-line)
+    (eshell-next-prompt 1)))
+
+(defun evil-collection-eshell-next-prompt-on-insert ()
+  "Go to next prompt on `evil' replace/insert enter."
+  (dolist (hook '(evil-replace-state-entry-hook evil-insert-state-entry-hook))
+    (add-hook hook 'evil-collection-eshell-next-prompt nil t)))
+
+(defun evil-collection-eshell-interrupt-process ()
+  "Interupt `eshell' process and enter insert state."
+  (interactive)
+  (eshell-interrupt-process)
+  (evil-insert 1))
+
+;;; `eshell-mode-map' is reset when Eshell is initialized in `eshell-mode'. We
+;;; need to add bindings to `eshell-first-time-mode-hook'.
+(defun evil-collection-eshell-setup-keys ()
+  "Set up `evil' bindings for `eshell'."
+  (evil-collection-define-key 'normal 'eshell-mode-map
+    ;; motion
+    "[" 'eshell-previous-prompt
+    "]" 'eshell-next-prompt
+    (kbd "C-k") 'eshell-previous-prompt
+    (kbd "C-j") 'eshell-next-prompt
+    "gk" 'eshell-previous-prompt
+    "gj" 'eshell-next-prompt
+    "0" 'eshell-bol
+    "^" 'eshell-bol
+    (kbd "M-h") 'eshell-backward-argument
+    (kbd "M-l") 'eshell-forward-argument
+
+    (kbd "<return>") 'eshell-send-input
+    (kbd "C-c C-c") 'evil-collection-eshell-interrupt-process)
+  (evil-collection-define-key 'insert 'eshell-mode-map
+    ;; motion
+    (kbd "M-h") 'eshell-backward-argument
+    (kbd "M-l") 'eshell-forward-argument)
+  (evil-collection-define-key 'visual 'eshell-mode-map
+    ;; motion
+    ;; TODO: This does not work with `evil-visual-line'.
+    "[" 'eshell-previous-prompt
+    "]" 'eshell-next-prompt
+    (kbd "C-k") 'eshell-previous-prompt
+    (kbd "C-j") 'eshell-next-prompt
+    "gk" 'eshell-previous-prompt
+    "gj" 'eshell-next-prompt
+    "0" 'eshell-bol
+    "^" 'eshell-bol))
+
+;; TODO: Compare this setup procedure with evil-ediff.
+(defun evil-collection-eshell-setup ()
+  "Set up `evil' bindings for `eshell'."
+  (add-hook 'eshell-mode-hook 'evil-collection-eshell-next-prompt-on-insert)
+  (add-hook 'eshell-first-time-mode-hook 'evil-collection-eshell-setup-keys))
+
+(provide 'evil-collection-eshell)
+;;; evil-collection-eshell.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-eshell.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-eshell.elc
new file mode 100644
index 0000000000..644a1187f1
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-eshell.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-etags-select.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-etags-select.el
new file mode 100644
index 0000000000..0f33e4b3c7
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-etags-select.el
@@ -0,0 +1,40 @@
+;;; evil-collection-etags-select.el --- Bindings for `etags-select'. -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 James Nguyen
+
+;; Author: James Nguyen <james@jojojames.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, emacs, tools
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;; Bindings for `etags-select'.
+
+;;; Code:
+(require 'evil-collection)
+(require 'etags-select nil t)
+
+(defun evil-collection-etags-select-setup ()
+  "Set up `evil' bindings for `etags-select'.."
+  ;; FIXME: probably etags-select should be recomended in docs
+  (evil-collection-define-key nil 'evil-motion-state-map
+    "g]" 'etags-select-find-tag-at-point))
+
+(provide 'evil-collection-etags-select)
+;;; evil-collection-etags-select.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-etags-select.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-etags-select.elc
new file mode 100644
index 0000000000..b12ed281c6
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-etags-select.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-eval-sexp-fu.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-eval-sexp-fu.el
new file mode 100644
index 0000000000..e181248014
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-eval-sexp-fu.el
@@ -0,0 +1,60 @@
+;;; evil-collection-eval-sexp-fu.el --- Bindings for `eval-sexp-fu'. -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 James Nguyen
+
+;; Author: James Nguyen <james@jojojames.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, eval-sexp-fu, tools
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;; Bindings for `eval-sexp-fu'.
+
+;;; Code:
+(require 'evil-collection)
+(require 'eval-sexp-fu nil t)
+
+(defconst evil-collection-eval-sexp-fu-maps nil)
+
+(defun evil-collection-eval-sexp-fu-bounds-of-thing-at-point-sexp (command &rest args)
+  "In normal-state or motion-state, last sexp ends at point."
+  (if (and (eq (nth 0 args) 'sexp)
+           (and (not evil-move-beyond-eol)
+                (or (evil-normal-state-p) (evil-motion-state-p))))
+      (save-excursion
+        (unless (or (eobp) (eolp)) (forward-char))
+        (apply command args))
+    (apply command args)))
+
+(defun evil-collection-eval-sexp-fu-advise-bounds-of-thing-at-point (command &rest args)
+  "Advise `bounds-of-thing-at-point' to handle `evil's `evil-move-beyond-eol'."
+  (advice-add 'bounds-of-thing-at-point
+              :around 'evil-collection-eval-sexp-fu-bounds-of-thing-at-point-sexp)
+  (apply command args)
+  (advice-remove 'bounds-of-thing-at-point
+                 'evil-collection-eval-sexp-fu-bounds-of-thing-at-point-sexp))
+
+(defun evil-collection-eval-sexp-fu-setup ()
+  "Set up `evil' with `eval-sexp-fu'."
+  (unless evil-move-beyond-eol
+    (advice-add 'ad-Advice-eval-last-sexp
+                :around 'evil-collection-eval-sexp-fu-advise-bounds-of-thing-at-point)))
+
+(provide 'evil-collection-eval-sexp-fu)
+;;; evil-collection-eval-sexp-fu.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-eval-sexp-fu.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-eval-sexp-fu.elc
new file mode 100644
index 0000000000..e9d901c0a0
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-eval-sexp-fu.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-eww.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-eww.el
new file mode 100644
index 0000000000..c0f7cc2737
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-eww.el
@@ -0,0 +1,152 @@
+;;; evil-collection-eww.el --- Evil bindings for EWW -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 Pierre Neidhardt
+
+;; Author: Pierre Neidhardt <ambrevar@gmail.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, eww, tools
+
+;; This file 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, or (at your
+;; option) any later version.
+;;
+;; This file 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.
+;;
+;; For a full copy of the GNU General Public License
+;; see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; Evil bindings for EWW.
+
+;;; Code:
+(require 'eww)
+(require 'evil-collection)
+
+(defvar evil-collection-eww-maps '(eww-mode-map
+                                   eww-history-mode-map
+                                   eww-buffers-mode-map
+                                   eww-bookmark-mode-map))
+
+(defun evil-collection-eww-setup ()
+  "Set up `evil' bindings for `eww'."
+
+  (evil-collection-define-key 'normal 'eww-mode-map
+    "^" 'eww-up-url
+    "u" 'eww-up-url
+    "U" 'eww-top-url
+    (kbd "<backspace>") 'eww-back-url
+    "H" 'eww-back-url
+    "L" 'eww-forward-url
+
+    "gf" 'eww-view-source               ; Like qutebrowser.
+
+    "&" 'eww-browse-with-external-browser
+    "gc" 'url-cookie-list
+    "zd" 'eww-toggle-paragraph-direction
+    "ze" 'eww-set-character-encoding
+    "zf" 'eww-toggle-fonts
+    "d" 'eww-download
+    "m" 'eww-add-bookmark
+    "R" 'eww-readable                   ; Default binding.
+    "r" 'eww-readable
+
+    "]" 'eww-next-url
+    "[" 'eww-previous-url
+    "gj" 'eww-next-url
+    "gk" 'eww-previous-url
+
+    ;; open
+    (kbd "S-<return>") 'eww-browse-with-external-browser
+    "go" 'eww-browse-with-external-browser
+    "o" 'eww                            ; Like qutebrowser.
+
+    (kbd "SPC") 'scroll-up-command
+    (kbd "S-SPC") 'scroll-down-command
+    (kbd "<tab>") 'shr-next-link
+    (kbd "<backtab>") 'shr-previous-link
+
+    ;; bookmarks
+    "gb" 'eww-list-bookmarks
+
+    "gh" 'eww-list-histories
+    "gt" 'eww-list-buffers              ; Like dwb, qutebrowser.
+
+    ;; refresh
+    "gr" 'eww-reload
+
+    ;; quit
+    "q" 'quit-window
+    "ZQ" 'quit-window
+    "ZZ" 'quit-window)
+
+  (evil-collection-define-key 'operator 'eww-mode-map
+    "u" '(menu-item
+          ""
+          nil
+          :filter (lambda (&optional _)
+                    (when (memq evil-this-operator
+                                evil-collection-yank-operators)
+                      (setq evil-inhibit-operator t)
+                      #'eww-copy-page-url))))
+
+  (evil-collection-inhibit-insert-state 'eww-history-mode-map)
+  (evil-set-initial-state 'eww-history-mode 'normal)
+  (evil-collection-define-key 'normal 'eww-history-mode-map
+    (kbd "<return>") 'eww-history-browse
+    ;; refresh
+    "gr" 'revert-buffer
+    ;; quit
+    "q" 'quit-window
+    "ZQ" 'quit-window
+    "ZZ" 'quit-window)
+
+  (evil-collection-inhibit-insert-state 'eww-buffers-mode-map)
+  (evil-set-initial-state 'eww-buffers-mode 'normal)
+  (evil-collection-define-key 'normal 'eww-buffers-mode-map
+    "D" 'eww-buffer-kill
+    (kbd "<return>") 'eww-buffer-select
+    "]" 'eww-buffer-show-next
+    "[" 'eww-buffer-show-previous
+    "gj" 'eww-buffer-show-next
+    "gk" 'eww-buffer-show-previous
+    ;; refresh
+    "gr" 'revert-buffer
+    ;; quit
+    "q" 'quit-window
+    "ZQ" 'quit-window
+    "ZZ" 'quit-window)
+
+  (evil-collection-inhibit-insert-state 'eww-bookmark-mode-map)
+  (evil-set-initial-state 'eww-bookmark-mode 'normal)
+  (evil-collection-define-key 'normal 'eww-bookmark-mode-map
+    "D" 'eww-bookmark-kill
+    "P" 'eww-bookmark-yank
+
+    (kbd "<return>") 'eww-bookmark-browse
+    ;; refresh
+    "gr" 'revert-buffer
+    ;; quit
+    "q" 'quit-window
+    "ZQ" 'quit-window
+    "ZZ" 'quit-window)
+
+  (evil-collection-define-key 'operator 'eww-bookmark-mode-map
+    "u" '(menu-item
+          ""
+          nil
+          :filter (lambda (&optional _)
+                    (when (memq evil-this-operator
+                                evil-collection-yank-operators)
+                      (setq evil-inhibit-operator t)
+                      #'eww-copy-page-url)))))
+
+(provide 'evil-collection-eww)
+;;; evil-collection-eww.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-eww.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-eww.elc
new file mode 100644
index 0000000000..626a3353e1
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-eww.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-flycheck.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-flycheck.el
new file mode 100644
index 0000000000..7a7c8305f4
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-flycheck.el
@@ -0,0 +1,55 @@
+;;; evil-collection-flycheck.el --- Evil bindings for flycheck -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 James Nguyen
+
+;; Author: James Nguyen <james@jojojames.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, flycheck, tools
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; Evil bindings for `flycheck-mode'.
+
+;;; Code:
+(require 'evil-collection)
+(require 'flycheck nil t)
+
+(defvar flycheck-error-list-mode-map)
+
+(defconst evil-collection-flycheck-maps '(flycheck-error-list-mode-map))
+
+(defun evil-collection-flycheck-setup ()
+  "Set up `evil' bindings for `flycheck'."
+  (evil-set-initial-state 'flycheck-error-list-mode 'normal)
+  (evil-collection-define-key 'normal 'flycheck-error-list-mode-map
+    "gj" 'flycheck-error-list-next-error
+    "gk" 'flycheck-error-list-previous-error
+    (kbd "C-j") 'flycheck-error-list-next-error
+    (kbd "C-k") 'flycheck-error-list-previous-error
+    "]" 'flycheck-error-list-next-error
+    "[" 'flycheck-error-list-previous-error
+    "gr" 'flycheck-error-list-check-source
+    "s" 'flycheck-error-list-set-filter
+    "S" 'flycheck-error-list-reset-filter
+    "x" 'flycheck-error-list-explain-error
+    (kbd "<return>") 'flycheck-error-list-goto-error
+    "q" 'quit-window))
+
+(provide 'evil-collection-flycheck)
+;;; evil-collection-flycheck.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-flycheck.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-flycheck.elc
new file mode 100644
index 0000000000..dc55ae691c
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-flycheck.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-free-keys.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-free-keys.el
new file mode 100644
index 0000000000..76b2002679
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-free-keys.el
@@ -0,0 +1,52 @@
+;;; evil-collection-free-keys.el --- Bindings for `free-keys' -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 James Nguyen
+
+;; Author: James Nguyen <james@jojojames.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, emacs, tools
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;; Bindings for `free-keys'.
+(require 'evil-collection)
+(require 'free-keys nil t)
+
+;;; Code:
+(defvar free-keys-mode-map)
+
+(defconst evil-collection-free-keys-maps '(free-keys-mode-map))
+
+(defun evil-collection-free-keys-set-header-line-format ()
+  "Tweak `header-line-format' locally for `free-keys'."
+  (setq-local header-line-format
+              "Help: (c) change buffer (p) change prefix (q) quit"))
+
+(defun evil-collection-free-keys-setup ()
+  "Set up `evil' bindings for `free-keys'."
+  (add-hook 'free-keys-mode-hook
+            #'evil-collection-free-keys-set-header-line-format)
+  (evil-set-initial-state 'free-keys-mode 'normal)
+  (evil-collection-define-key 'normal 'free-keys-mode-map
+    "c" 'free-keys-change-buffer
+    "p" 'free-keys-set-prefix
+    "q" 'quit-window))
+
+(provide 'evil-collection-free-keys)
+;;; evil-collection-free-keys.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-free-keys.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-free-keys.elc
new file mode 100644
index 0000000000..400e9e58fc
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-free-keys.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-geiser.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-geiser.el
new file mode 100644
index 0000000000..14e8d436e1
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-geiser.el
@@ -0,0 +1,103 @@
+;;; evil-collection-geiser.el --- Bindings for `geiser'. -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 James Nguyen
+
+;; Author: James Nguyen <james@jojojames.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, geiser, tools
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;; Bindings for `geiser'.
+
+;;; Code:
+(require 'evil-collection)
+(require 'geiser nil t)
+
+(defvar geiser-debug-mode-map)
+(defvar geiser-doc-mode-map)
+
+(defconst evil-collection-geiser-maps '(geiser-debug-mode-map
+                                        geiser-doc-mode-map
+                                        geiser-repl-mode-map
+                                        geiser-mode-map))
+
+(defun evil-collection-geiser-last-sexp (command &rest args)
+  "In normal-state or motion-state, last sexp ends at point."
+  (if (and (not evil-move-beyond-eol)
+           (or (evil-normal-state-p) (evil-motion-state-p)))
+      (save-excursion
+        (unless (or (eobp) (eolp)) (forward-char))
+        (apply command args))
+    (apply command args)))
+
+(defun evil-collection-geiser-setup ()
+  "Set up bindings for `geiser'."
+  (unless evil-move-beyond-eol
+    (advice-add 'geiser-eval-last-sexp :around 'evil-collection-geiser-last-sexp)
+    (advice-add 'geiser-eval-last-sexp-and-print :around 'evil-collection-geiser-last-sexp))
+
+  (evil-set-initial-state 'geiser-debug-mode 'normal)
+  (evil-set-initial-state 'geiser-doc-mode 'normal)
+
+  (evil-collection-define-key 'normal 'geiser-debug-mode-map
+    "q" 'quit-window)
+
+  (evil-collection-define-key 'normal 'geiser-doc-mode-map
+    (kbd "<tab>") 'forward-button
+    (kbd "<S-tab>") 'backward-button
+    "gd" 'geiser-edit-symbol-at-point
+    (kbd "C-t") 'geiser-pop-symbol-stack
+    "gr" 'geiser-doc-refresh
+    "q" 'View-quit
+    "gz" 'geiser-doc-switch-to-repl
+    ">" 'geiser-doc-next
+    "<" 'geiser-doc-previous
+    "gj" 'forward-button
+    "gk" 'backward-button
+    (kbd "C-j") 'forward-button
+    (kbd "C-k") 'backward-button
+    "]" 'geiser-doc-next-section
+    "[" 'geiser-doc-previous-section
+    "x" 'geiser-doc-kill-page
+    "X" 'geiser-doc-clean-history)
+
+  (evil-collection-define-key 'insert 'geiser-repl-mode-map
+    (kbd "S-<return>") 'geiser-repl--newline-and-indent)
+
+  (evil-collection-define-key 'normal 'geiser-repl-mode-map
+    "gd" 'geiser-edit-symbol-at-point
+    (kbd "C-t") 'geiser-pop-symbol-stack
+    "gj" 'geiser-repl-next-prompt
+    "gk" 'geiser-repl-previous-prompt
+    (kbd "C-j") 'geiser-repl-next-prompt
+    (kbd "C-k") 'geiser-repl-previous-prompt
+    "]" 'geiser-repl-next-prompt
+    "[" 'geiser-repl-previous-prompt
+    "K" 'geiser-doc-symbol-at-point)
+
+  (evil-collection-define-key 'normal 'geiser-mode-map
+    "gd" 'geiser-edit-symbol-at-point
+    (kbd "C-t") 'geiser-pop-symbol-stack
+    "gZ" 'geiser-mode-switch-to-repl-and-enter
+    "gz" 'geiser-mode-switch-to-repl
+    "K" 'geiser-doc-symbol-at-point))
+
+(provide 'evil-collection-geiser)
+;;; evil-collection-geiser.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-geiser.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-geiser.elc
new file mode 100644
index 0000000000..d7575833ef
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-geiser.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-ggtags.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-ggtags.el
new file mode 100644
index 0000000000..c9dd8cc028
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-ggtags.el
@@ -0,0 +1,99 @@
+;;; evil-collection-ggtags.el --- Evil bindings for ggtags -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 James Nguyen
+
+;; Author: James Nguyen <james@jojojames.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, ggtags, tools
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; Evil bindings for `ggtags-mode'.
+
+;;; Code:
+(require 'evil-collection)
+(require 'ggtags nil t)
+
+(defvar ggtags-global-mode-map)
+(defvar ggtags-mode-map)
+(defvar ggtags-view-search-history-mode-map)
+(defvar ggtags-view-tag-history-mode-map)
+(defvar ggtags-navigation-map)
+
+(defconst evil-collection-ggtags-maps '(ggtags-mode-map
+                                        ggtags-view-search-history-mode-map
+                                        ggtags-view-tag-history-mode-map
+                                        ggtags-navigation-map))
+
+(defun evil-collection-ggtags-setup ()
+  "Set up `evil' bindings for `ggtags'."
+  (evil-set-initial-state 'ggtags-global-mode 'normal)
+  (evil-set-initial-state 'ggtags-view-search-history-mode 'normal)
+  (evil-set-initial-state 'ggtags-view-tag-history-mode 'normal)
+
+  ;; `ggtags-navigation-mode' is global and will conflict with other bindings.
+  ;; https://github.com/leoliu/ggtags/issues/124
+  (when (boundp 'ggtags-enable-navigation-keys)
+    (setq ggtags-enable-navigation-keys nil))
+
+  (evil-collection-define-key 'normal 'ggtags-mode-map
+    "gd" 'ggtags-find-tag-dwim
+    (kbd "C-t") 'ggtags-prev-mark
+    "gf" 'ggtags-find-file)
+
+  (evil-collection-define-key 'normal 'ggtags-view-search-history-mode-map
+    "gj" 'ggtags-view-search-history-next
+    "gk" 'ggtags-view-search-history-prev
+    (kbd "C-j") 'ggtags-view-search-history-next
+    (kbd "C-k") 'ggtags-view-search-history-prev
+    "]" 'ggtags-view-search-history-next
+    "[" 'ggtags-view-search-history-prev
+    "x" 'ggtags-view-search-history-kill
+    "gr" 'ggtags-view-search-history-update
+    "r" 'ggtags-save-to-register
+    "R" 'ggtags-view-search-history-action
+    "q" 'ggtags-kill-window)
+
+  (evil-collection-define-key 'normal 'ggtags-view-tag-history-mode-map
+    "gj" 'next-error-no-select
+    (kbd "C-j") 'next-error-no-select
+    "]" 'next-error-no-select
+    "gk" 'previous-error-no-select
+    (kbd "C-k") 'previous-error-no-select
+    (kbd "[") 'previous-error-no-select
+    "q" 'ggtags-kill-window)
+
+  (evil-collection-define-key 'normal 'ggtags-navigation-map
+    ;; navigation
+    "gj" 'next-error
+    "gk" 'next-error
+    (kbd "C-j") 'previous-error
+    (kbd "C-k") 'previous-error
+    "]" 'ggtags-navigation-next-file
+    "[" 'ggtags-navigation-previous-file
+
+    ;; search
+    "s" 'ggtags-navigation-isearch-forward
+    "S" 'ggtags-navigation-isearch-forward
+
+    "go" 'ggtags-navigation-visible-mode ;; FIXME: This can be anything.
+    (kbd "<return>") 'ggtags-navigation-mode-done))
+
+(provide 'evil-collection-ggtags)
+;;; evil-collection-ggtags.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-ggtags.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-ggtags.elc
new file mode 100644
index 0000000000..4d6c72136c
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-ggtags.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-git-timemachine.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-git-timemachine.el
new file mode 100644
index 0000000000..bbf6d9472b
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-git-timemachine.el
@@ -0,0 +1,48 @@
+;;; evil-collection-git-timemachine.el --- Bindings for `git-timemachine' -*- lexical-binding: t -*-
+
+;; Author: William Carroll <wpcarro@gmail.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, git, tools
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; Evil keybindings for `git-timemachine' that conform to the principles
+;; outlines in evil-collection
+
+;;; Code:
+(require 'evil-collection)
+(require 'git-timemachine nil t)
+
+(defvar git-timemachine-mode-map)
+(defconst evil-collection-git-timemachine-map '(git-timemachine-mode-map))
+
+(defun evil-collection-git-timemachine-setup ()
+  "Setup `evil' keybindings for `git-timemachine'."
+  (evil-define-minor-mode-key 'normal 'git-timemachine-mode
+    "\C-k" 'git-timemachine-show-previous-revision
+    "\C-j" 'git-timemachine-show-next-revision
+    "q"    'git-timemachine-quit
+    "gtg"  'git-timemachine-show-nth-revision
+    "gtt"  'git-timemachine-show-revision-fuzzy
+    "gty"  'git-timemachine-kill-abbreviated-revision
+    "gtY"  'git-timemachine-kill-revision
+    "gtb"  'git-timemachine-blame))
+
+(provide 'evil-collection-git-timemachine)
+;;; evil-collection-git-timemachine.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-git-timemachine.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-git-timemachine.elc
new file mode 100644
index 0000000000..0f77eb637c
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-git-timemachine.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-go-mode.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-go-mode.el
new file mode 100644
index 0000000000..b6e77aa44f
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-go-mode.el
@@ -0,0 +1,46 @@
+;;; evil-collection-go-mode.el --- Bindings for `go-mode'. -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 James Nguyen
+
+;; Author: James Nguyen <james@jojojames.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, emacs, tools, golang
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; Bindings for `go-mode'.
+
+;;; Code:
+(require 'evil-collection)
+(require 'go-mode nil t)
+
+(defconst evil-collection-go-mode-maps '(go-mode-map
+                                         godoc-mode-map))
+
+(defun evil-collection-go-mode-setup ()
+  "Set up `evil' bindings for `go-mode'."
+  (evil-collection-define-key 'normal 'go-mode-map
+    "gd" 'godef-jump
+    "K" 'godef-describe)
+  (evil-collection-define-key 'normal 'godoc-mode-map
+    "q" 'quit-window
+    "g?" 'describe-mode))
+
+(provide 'evil-collection-go-mode)
+;;; evil-collection-go-mode.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-go-mode.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-go-mode.elc
new file mode 100644
index 0000000000..b73cf1e757
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-go-mode.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-grep.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-grep.el
new file mode 100644
index 0000000000..eaef614543
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-grep.el
@@ -0,0 +1,44 @@
+;;; evil-collection-grep.el --- Bindings for `grep' -*- lexical-binding: t -*-
+
+;; Copyright (C) 2018 James Nguyen
+
+;; Author: Fredrik Bergroth <fbergroth@gmail.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, emacs, tools
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; Bindings for `grep'.
+
+;;; Code:
+(require 'evil-collection)
+(require 'grep)
+
+(defconst evil-collection-grep-maps '(grep-mode-map))
+
+(defun evil-collection-grep-setup ()
+  "Set up `evil' bindings for `grep'."
+  (evil-collection-define-key 'normal 'grep-mode-map
+    "n" 'evil-search-next
+    "\C-j" 'next-error-no-select
+    "\C-k" 'previous-error-no-select))
+
+
+(provide 'evil-collection-grep)
+;;; evil-collection-grep.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-grep.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-grep.elc
new file mode 100644
index 0000000000..004b2eb074
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-grep.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-guix.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-guix.el
new file mode 100644
index 0000000000..0ee2dab428
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-guix.el
@@ -0,0 +1,209 @@
+;;; evil-collection-guix.el --- Evil bindings for Guix -*- lexical-binding: t -*-
+
+;; Copyright (C) 2018 Pierre Neidhardt
+
+;; Author: Pierre Neidhardt <ambrevar@gmail.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, guix, tools
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; Evil bindings for `guix'.
+
+;;; Code:
+(require 'evil-collection)
+(require 'guix nil t)
+
+(defconst evil-collection-guix-maps '(guix-output-list-mode-map
+                                      guix-package-info-mode-map
+                                      guix-profile-list-mode-map
+                                      guix-profile-info-mode-map
+                                      guix-generation-list-mode-map
+                                      guix-generation-info-mode-map
+                                      guix-license-list-mode-map
+                                      guix-license-info-mode-map
+                                      guix-location-list-mode-map
+                                      guix-hydra-build-list-mode-map
+                                      guix-hydra-build-info-mode-map
+                                      guix-build-log-mode-map))
+
+(defmacro evil-collection-guix-set (map)
+  "Set common bindings in MAP."
+  `(progn
+     (evil-collection-inhibit-insert-state ',map)
+     (evil-collection-define-key 'normal ',map
+        ;; motion
+        (kbd "SPC") 'scroll-up-command
+        (kbd "S-SPC") 'scroll-down-command
+        (kbd "<tab>") 'forward-button
+        (kbd "<backtab>") 'backward-button
+
+        "gm" 'guix-apply-manifest
+
+        ;; sort
+        "o" 'bui-list-sort
+
+        ;; filter
+        "ss" 'bui-enable-filter
+        "sd" 'bui-disable-filter
+
+        ;; mark
+        "m" 'bui-list-mark
+        "M" 'bui-list-mark-all
+        "u" 'bui-list-unmark
+        "U" 'bui-list-unmark-all
+
+        (kbd "C-o") 'bui-history-back
+        (kbd "C-i") 'bui-history-forward
+
+        "g?" 'bui-show-hint
+        "gr" 'revert-buffer
+        "gR" 'bui-redisplay
+
+        ;; repl
+        "gz" 'guix-switch-to-repl
+
+        ;; quit
+        "q" 'quit-window
+        "ZQ" 'evil-quit
+        "ZZ" 'quit-window)))
+
+(defun evil-collection-guix-setup ()
+  "Set up `evil' bindings for `guix'."
+  (evil-collection-guix-set guix-ui-map) ; Covers output-list and generation-list.
+
+  (evil-collection-define-key 'normal 'guix-output-list-mode-map
+    (kbd "<return>") 'bui-list-describe
+
+    "gb" 'guix-package-list-latest-builds
+    "gG" 'guix-output-list-graph
+    "gl" 'guix-output-list-lint
+    "gs" 'guix-package-list-size
+
+    "a" 'guix-output-list-mark-upgrade
+    "A" 'guix-output-list-mark-upgrades
+    "d" 'guix-output-list-mark-delete
+    "gd" 'guix-output-list-edit
+    "i" 'guix-output-list-mark-install
+
+    ;; mark
+    "x" 'guix-output-list-execute)
+
+  (evil-collection-guix-set guix-package-info-mode-map)
+  (evil-collection-define-key 'normal 'guix-package-info-mode-map
+    "gG" 'guix-package-info-graph
+    "gl" 'guix-package-info-lint
+    "gs" 'guix-package-info-size
+
+    "a" 'guix-package-info-upgrade
+    "d" 'guix-package-info-delete
+    "gd" 'guix-package-info-edit
+    "i" 'guix-package-info-install)
+
+  (evil-collection-guix-set guix-profile-list-mode-map)
+  (evil-collection-define-key 'normal 'guix-profile-list-mode-map
+    (kbd "<return>") 'bui-list-describe
+
+    "c" 'guix-profile-list-set-current ; TODO: Bind to "." as per the rationale?
+    "p" 'guix-profile-list-show-packages
+    "a" 'guix-profile-list-show-generations
+    "P" 'guix-profile-list-show-search-paths)
+
+  (evil-collection-guix-set guix-profile-info-mode-map)
+  (evil-collection-define-key 'normal 'guix-profile-info-mode-map
+    "gm" 'guix-profile-info-apply-manifest
+
+    "p" 'guix-profile-info-show-packages
+    "a" 'guix-profile-info-show-generations
+    "P" 'guix-profile-info-show-search-paths
+    "c" 'guix-profile-info-set-current)
+
+  (evil-collection-define-key 'normal 'guix-generation-list-mode-map
+    (kbd "<return>") 'bui-list-describe
+
+    "p" 'guix-generation-list-show-packages
+    "D" 'guix-generation-list-mark-delete
+    "P" 'guix-generation-list-show-search-paths
+    "c" 'guix-generation-list-set-current
+    "d" 'guix-generation-list-ediff
+
+    "+" 'guix-generation-list-show-added-packages
+    "-" 'guix-generation-list-show-removed-packages
+    "=" 'guix-generation-list-diff
+
+    ;; mark
+    "x" 'guix-generation-list-execute)
+
+  (evil-collection-guix-set guix-license-list-mode-map)
+  (evil-collection-define-key 'normal 'guix-license-list-mode-map
+    (kbd "<tab>") 'forward-button       ; Why isn't this binding inhibited?
+    (kbd "<return>") 'bui-list-describe
+
+    "p" 'guix-license-list-show-packages
+    "gd" 'guix-license-list-edit)
+
+  (evil-collection-guix-set guix-license-info-mode-map)
+
+  (evil-collection-guix-set guix-location-list-mode-map)
+  (evil-collection-define-key 'normal 'guix-location-list-mode-map
+    (kbd "<return>") 'guix-location-list-show-packages ; In Emacs state, it seems to be overriden by `push-button'.
+
+    "p" 'guix-location-list-show-packages
+    "gd" 'guix-location-list-edit)
+
+  (evil-collection-guix-set guix-hydra-build-list-mode-map)
+  (evil-collection-define-key 'normal 'guix-hydra-build-list-mode-map
+    (kbd "<return>") 'bui-list-describe
+
+    "gb" 'guix-hydra-build-list-latest-builds
+    "gl" 'guix-hydra-build-list-view-log)
+
+  (evil-collection-guix-set guix-hydra-build-info-mode-map)
+
+  (evil-collection-inhibit-insert-state 'guix-build-log-mode-map)
+  (evil-collection-define-key 'normal 'guix-build-log-mode-map
+    ;; motion
+    (kbd "SPC") 'scroll-up-command
+    (kbd "S-SPC") 'scroll-down-command
+    (kbd "<tab>") 'guix-build-log-phase-toggle
+    (kbd "<backtab>") 'guix-build-log-phase-toggle-all
+
+    "gk" 'guix-build-log-previous-phase
+    "gj" 'guix-build-log-next-phase
+    "[" 'guix-build-log-previous-phase
+    "]" 'guix-build-log-next-phase
+    (kbd "C-k") 'guix-build-log-previous-phase
+    (kbd "C-j") 'guix-build-log-next-phase
+
+    "gr" 'revert-buffer
+
+    ;; repl
+    "gz" 'guix-switch-to-repl           ; TODO: Does it still make sense here?
+
+    ;; quit
+    "q" 'quit-window
+    "ZQ" 'evil-quit
+    "ZZ" 'quit-window)
+
+  (evil-collection-define-key 'normal 'guix-devel-mode-map
+    ;; repl
+    "gz" 'guix-switch-to-repl))
+
+(provide 'evil-collection-guix)
+;;; evil-collection-guix.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-guix.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-guix.elc
new file mode 100644
index 0000000000..76bcd82529
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-guix.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-helm.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-helm.el
new file mode 100644
index 0000000000..4c9436e10e
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-helm.el
@@ -0,0 +1,211 @@
+;;; evil-collection-helm.el --- Evil bindings for Helm  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 Pierre Neidhardt
+
+;; Author: Pierre Neidhardt <ambrevar@gmail.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, helm, tools
+
+;; This file 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, or (at your
+;; option) any later version.
+;;
+;; This file 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.
+;;
+;; For a full copy of the GNU General Public License
+;; see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; Evil bindings for Helm.
+
+;;; Code:
+(require 'evil-collection)
+(require 'helm-files nil t) ; TODO: Check if this is the ideal requirement and if we are not loading too much.
+
+;; To navigate Helm entries with <hjkl> in insert state, we need a modifier.
+;; Using the C- modifier would conflict with the help prefix "C-h".  So we use
+;; M- prefixed bindings instead.
+
+;; Helm-find-files: We cannot use "h" and "l" in normal state to navigate up and
+;; down the file system hierarchy since we need them to use it to edit the
+;; minibuffer content.
+
+(defvar helm-map)
+(defvar helm-find-files-map)
+(defvar helm-generic-files-map)
+(defvar helm-buffer-map)
+(defvar helm-moccur-map)
+(defvar helm-grep-map)
+(defvar helm-read-file-map)
+(defvar helm-echo-input-in-header-line)
+(defvar helm--prompt)
+(defvar helm--action-prompt)
+(defvar helm-header-line-space-before-prompt)
+(defvar helm-default-prompt-display-function)
+
+(declare-function helm-window "helm-lib")
+
+(defconst evil-collection-helm-maps '(help-map
+                                      help-find-files-map
+                                      helm-read-file-map
+                                      helm-generic-files-map
+                                      helm-buffer-map
+                                      helm-moccur-map
+                                      helm-grep-map))
+
+;; From https://github.com/emacs-helm/helm/issues/362.
+;; Also see https://emacs.stackexchange.com/questions/17058/change-cursor-type-in-helm-header-line#17097.
+;; TODO: With Evil, the cursor type is not right in the header line and the evil
+;; cursor remains in the minibuffer.  Visual selections also reveal overlayed
+;; text.
+(with-no-warnings
+  (defun evil-collection-helm-hide-minibuffer-maybe ()
+    "Hide text in minibuffer when `helm-echo-input-in-header-line' is non-nil."
+    (when (with-current-buffer (helm-buffer-get) helm-echo-input-in-header-line)
+      (let ((ov (make-overlay (point-min) (point-max) nil nil t)))
+        (overlay-put ov 'window (selected-window))
+        (overlay-put ov 'face (let ((bg-color (face-background 'default nil)))
+                                `(:background ,bg-color :foreground ,bg-color)))
+        (setq-local cursor-type nil)))))
+
+(defun evil-collection-helm--set-prompt-display (pos)
+  (let (beg state region-active m)
+    (with-selected-window (minibuffer-window)
+      (setq beg (save-excursion (vertical-motion 0 (helm-window)) (point))
+            state evil-state
+            region-active (region-active-p)
+            m (mark t)))
+    (when region-active
+      (setq m (- m beg))
+      ;; Increment pos to handle the space before prompt (i.e `pref').
+      (put-text-property (1+ (min m pos)) (+ 2 (max m pos))
+                         'face
+                         (list :background (face-background 'region))
+                         header-line-format))
+    (put-text-property
+     ;; Increment pos to handle the space before prompt (i.e `pref').
+     (+ 1 pos) (+ 2 pos)
+     'face
+     (if (eq state 'insert)
+         'underline
+       ;; Don't just use 'cursor, this can hide the current character.
+       (list :inverse-video t
+             :foreground (face-background 'cursor)
+             :background (face-background 'default)))
+     header-line-format)))
+
+
+(defun evil-collection-helm-setup ()
+  "Set up `evil' bindings for `helm'."
+  (add-hook 'helm-minibuffer-set-up-hook 'evil-collection-helm-hide-minibuffer-maybe)
+  (setq helm-default-prompt-display-function 'evil-collection-helm--set-prompt-display)
+
+  (evil-collection-define-key '(insert normal) 'helm-map
+    (kbd "M-[") 'helm-previous-source
+    (kbd "M-]") 'helm-next-source
+    (kbd "M-l") 'helm-execute-persistent-action
+    (kbd "M-j") 'helm-next-line
+    (kbd "M-k") 'helm-previous-line
+    (kbd "C-f") 'helm-next-page
+    (kbd "C-b") 'helm-previous-page)
+
+  (dolist (map '(helm-find-files-map helm-read-file-map))
+    (evil-collection-define-key 'normal map
+      "go" 'helm-ff-run-switch-other-window
+      "/" 'helm-ff-run-find-sh-command)
+    (evil-collection-define-key '(insert normal) map
+      (kbd "S-<return>") 'helm-ff-run-switch-other-window
+      (kbd "M-h") 'helm-find-files-up-one-level))
+
+  ;; TODO: Change the Helm header to display "M-l" instead of "C-l".  We don't
+  ;; want to modify the Emacs Helm map.
+
+  (evil-collection-define-key '(insert normal) 'helm-generic-files-map
+    (kbd "S-<return>") 'helm-ff-run-switch-other-window)
+
+  (evil-collection-define-key '(insert normal) 'helm-buffer-map
+    (kbd "S-<return>") 'helm-buffer-switch-other-window
+    (kbd "M-<return>") 'display-buffer)
+
+  (evil-collection-define-key '(insert normal) 'helm-moccur-map
+    (kbd "S-<return>") 'helm-moccur-run-goto-line-ow)
+
+  (evil-collection-define-key '(insert normal) 'helm-grep-map
+    (kbd "S-<return>") 'helm-grep-run-other-window-action)
+
+  (evil-collection-define-key 'normal 'helm-generic-files-map
+    "go" 'helm-ff-run-switch-other-window)
+
+  (evil-collection-define-key 'normal 'helm-buffer-map
+    "go" 'helm-buffer-switch-other-window
+    "gO" 'display-buffer
+    "=" 'helm-buffer-run-ediff
+    "%" 'helm-buffer-run-query-replace-regexp
+    "D" 'helm-buffer-run-kill-persistent ; Ivy has "D".
+    )
+
+  (evil-collection-define-key 'normal 'helm-moccur-map
+    "go" 'helm-moccur-run-goto-line-ow)
+
+  (evil-collection-define-key 'normal 'helm-grep-map
+    "go" 'helm-grep-run-other-window-action)
+
+  (evil-collection-define-key 'normal 'helm-find-files-map
+    "=" 'helm-ff-run-ediff-file
+    "%" 'helm-ff-run-query-replace-regexp
+    "D" 'helm-ff-run-delete-file)       ; Ivy has "D".
+
+  ;; These helm bindings should always exist, the evil equivalents do
+  ;; nothing useful in the minibuffer (error or pure failure).
+  ;; RET can't do a second line in the minibuffer.
+  ;; The C-n/C-p completions error with 'helm in helm' session.
+  ;; C-o switches to evil state (again, not useful).
+  (evil-collection-define-key '(insert normal) 'helm-map
+    (kbd "RET") 'helm-maybe-exit-minibuffer
+    (kbd "M-v") 'helm-previous-page
+    (kbd "C-v") 'helm-next-page
+    (kbd "C-p") 'helm-previous-line
+    (kbd "C-n") 'helm-next-line
+    (kbd "C-o") 'helm-next-source)
+
+  (when evil-want-C-u-scroll
+    (evil-collection-define-key 'normal 'helm-map
+      (kbd "C-u") 'helm-previous-page))
+
+  (when evil-want-C-d-scroll
+    (evil-collection-define-key 'normal 'helm-map
+      (kbd "C-d") 'helm-next-page))
+
+  (evil-collection-define-key 'normal 'helm-map
+    (kbd "<tab>") 'helm-select-action   ; TODO: Ivy has "ga".
+    (kbd "[") 'helm-previous-source
+    (kbd "]") 'helm-next-source
+    "gk" 'helm-previous-source
+    "gj" 'helm-next-source
+    (kbd "(") 'helm-prev-visible-mark
+    (kbd ")") 'helm-next-visible-mark
+    "j" 'helm-next-line
+    "k" 'helm-previous-line
+    "gg" 'helm-beginning-of-buffer
+    "G" 'helm-end-of-buffer
+
+    "/" 'helm-quit-and-find-file
+
+    ;; refresh
+    "gr" 'helm-refresh
+
+    "yp" 'helm-yank-selection
+    "yP" 'helm-copy-to-buffer
+    "yy" 'helm-kill-selection-and-quit
+    (kbd "SPC") 'helm-toggle-visible-mark))
+
+(provide 'evil-collection-helm)
+;;; evil-collection-helm.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-helm.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-helm.elc
new file mode 100644
index 0000000000..98549b288f
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-helm.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-help.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-help.el
new file mode 100644
index 0000000000..f446bb98ad
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-help.el
@@ -0,0 +1,74 @@
+;;; evil-collection-help.el --- Evil bindings for help-mode -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 James Nguyen
+
+;; Author: James Nguyen <james@jojojames.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, help, tools
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; Evil bindings for `help-mode'.
+
+;;; Code:
+(require 'evil-collection)
+(require 'help-mode)
+
+(defconst evil-collection-help-maps '(help-mode-map))
+
+(defun evil-collection-help-setup ()
+  "Set up `evil' bindings for `help'."
+  (evil-set-initial-state 'help-mode 'normal)
+  (evil-collection-inhibit-insert-state 'help-mode-map)
+  (evil-collection-define-key 'normal 'help-mode-map
+    ;; motion
+    (kbd "SPC") 'scroll-up-command
+    (kbd "S-SPC") 'scroll-down-command
+    (kbd "C-f") 'scroll-up-command
+    (kbd "C-b") 'scroll-down-command
+    (kbd "<tab>") 'forward-button
+    (kbd "<backtab>") 'backward-button
+
+    (kbd "C-o") 'help-go-back
+    (kbd "C-i") 'help-go-forward
+
+    ;; TODO: Enable more help-go-* bindings?
+    ;; "gj" 'help-go-forward
+    ;; "gk" 'help-go-back
+    ;; "\C-j" 'help-go-forward
+    ;; "\C-k" 'help-go-back
+
+    ;; The following bindings don't do what they are supposed to. "go" should open
+    ;; in the same window and "gO" should open in a different one.
+    "go" 'push-button 
+    "gO" 'push-button
+    
+    "g?" 'describe-mode
+    "gr" 'revert-buffer
+    "<" 'help-go-back
+    ">" 'help-go-forward
+    "r" 'help-follow
+
+    ;; quit
+    "q" 'quit-window
+    "ZQ" 'evil-quit
+    "ZZ" 'quit-window))
+
+(provide 'evil-collection-help)
+;;; evil-collection-help.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-help.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-help.elc
new file mode 100644
index 0000000000..b103775b85
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-help.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-ibuffer.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-ibuffer.el
new file mode 100644
index 0000000000..eafa527aa8
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-ibuffer.el
@@ -0,0 +1,196 @@
+;;; evil-collection-ibuffer.el --- Evil bindings for IBuffer -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 James Nguyen
+
+;; Author: James Nguyen <james@jojojames.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, ibuffer, tools
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; Evil bindings for IBuffer.
+
+;;; Code:
+(require 'evil-collection)
+(require 'ibuffer)
+
+(defconst evil-collection-ibuffer-maps '(ibuffer-mode-map))
+
+(defun evil-collection-ibuffer-setup ()
+  "Set up `evil' bindings for `ibuffer'."
+  (evil-set-initial-state 'ibuffer-mode 'normal)
+
+  (evil-collection-define-key 'normal 'ibuffer-mode-map
+    (kbd "C-d") (if evil-want-C-d-scroll
+                    'evil-scroll-down
+                  'ibuffer-mark-for-delete-backwards))
+
+  (evil-collection-define-key 'normal 'ibuffer-mode-map
+    (kbd "=") 'ibuffer-diff-with-file
+    (kbd "J") 'ibuffer-jump-to-buffer
+    (kbd "M-g") 'ibuffer-jump-to-buffer
+    (kbd "M-s a C-s") 'ibuffer-do-isearch
+    (kbd "M-s a M-C-s") 'ibuffer-do-isearch-regexp
+    (kbd "M-s a C-o") 'ibuffer-do-occur
+
+    ;; mark
+    (kbd "m") 'ibuffer-mark-forward
+    (kbd "~") 'ibuffer-toggle-marks
+    (kbd "u") 'ibuffer-unmark-forward
+    (kbd "DEL") 'ibuffer-unmark-backward
+    (kbd "M-DEL") 'ibuffer-unmark-all
+    (kbd "* *") 'ibuffer-unmark-all
+    (kbd "* c") 'ibuffer-change-marks
+    (kbd "U") 'ibuffer-unmark-all-marks
+    (kbd "* M") 'ibuffer-mark-by-mode
+    (kbd "* m") 'ibuffer-mark-modified-buffers
+    (kbd "* u") 'ibuffer-mark-unsaved-buffers
+    (kbd "* s") 'ibuffer-mark-special-buffers
+    (kbd "* r") 'ibuffer-mark-read-only-buffers
+    (kbd "* /") 'ibuffer-mark-dired-buffers
+    (kbd "* e") 'ibuffer-mark-dissociated-buffers
+    (kbd "* h") 'ibuffer-mark-help-buffers
+    (kbd "* z") 'ibuffer-mark-compressed-file-buffers
+    (kbd ".") 'ibuffer-mark-old-buffers
+
+    (kbd "d") 'ibuffer-mark-for-delete
+    (kbd "x") 'ibuffer-do-kill-on-deletion-marks
+
+    ;; immediate operations
+    (kbd "gj") 'ibuffer-forward-line
+    (kbd "gk") 'ibuffer-backward-line
+
+    (kbd "}") 'ibuffer-forward-next-marked
+    (kbd "{") 'ibuffer-backwards-next-marked
+    (kbd "M-}") 'ibuffer-forward-next-marked
+    (kbd "M-{") 'ibuffer-backwards-next-marked
+
+    (kbd "gR") 'ibuffer-redisplay
+    (kbd "gr") 'ibuffer-update
+
+    "`" 'ibuffer-switch-format
+    "-" 'ibuffer-add-to-tmp-hide
+    "+" 'ibuffer-add-to-tmp-show
+    "X" 'ibuffer-bury-buffer
+    (kbd ",") 'ibuffer-toggle-sorting-mode
+    (kbd "o i") 'ibuffer-invert-sorting
+    (kbd "o a") 'ibuffer-do-sort-by-alphabetic
+    (kbd "o v") 'ibuffer-do-sort-by-recency
+    (kbd "o s") 'ibuffer-do-sort-by-size
+    (kbd "o f") 'ibuffer-do-sort-by-filename/process
+    (kbd "o m") 'ibuffer-do-sort-by-major-mode
+
+    (kbd "s RET") 'ibuffer-filter-by-mode
+    (kbd "s m") 'ibuffer-filter-by-used-mode
+    (kbd "s M") 'ibuffer-filter-by-derived-mode
+    (kbd "s n") 'ibuffer-filter-by-name
+    (kbd "s *") 'ibuffer-filter-by-starred-name
+    (kbd "s f") 'ibuffer-filter-by-filename
+    (kbd "s b") 'ibuffer-filter-by-basename
+    (kbd "s .") 'ibuffer-filter-by-file-extension
+    (kbd "s <") 'ibuffer-filter-by-size-lt
+    (kbd "s >") 'ibuffer-filter-by-size-gt
+    (kbd "s i") 'ibuffer-filter-by-modified
+    (kbd "s v") 'ibuffer-filter-by-visiting-file
+    (kbd "s c") 'ibuffer-filter-by-content
+    (kbd "s e") 'ibuffer-filter-by-predicate
+
+    (kbd "s r") 'ibuffer-switch-to-saved-filters
+    (kbd "s a") 'ibuffer-add-saved-filters
+    (kbd "s x") 'ibuffer-delete-saved-filters
+    (kbd "s d") 'ibuffer-decompose-filter
+    (kbd "s s") 'ibuffer-save-filters
+    (kbd "s p") 'ibuffer-pop-filter
+    (kbd "s <up>") 'ibuffer-pop-filter
+    (kbd "s !") 'ibuffer-negate-filter
+    (kbd "s t") 'ibuffer-exchange-filters
+    (kbd "s TAB") 'ibuffer-exchange-filters
+    (kbd "s o") 'ibuffer-or-filter
+    (kbd "s |") 'ibuffer-or-filter
+    (kbd "s &") 'ibuffer-and-filter
+    (kbd "s g") 'ibuffer-filters-to-filter-group
+    (kbd "s P") 'ibuffer-pop-filter-group
+    (kbd "s S-<up>") 'ibuffer-pop-filter-group
+    (kbd "s D") 'ibuffer-decompose-filter-group
+    (kbd "s /") 'ibuffer-filter-disable
+
+    (kbd "C-j") 'ibuffer-forward-filter-group
+    (kbd "M-n") 'ibuffer-forward-filter-group
+    (kbd "]") 'ibuffer-forward-filter-group
+    "\t" 'ibuffer-forward-filter-group
+    (kbd "M-p") 'ibuffer-backward-filter-group
+    (kbd "C-k") 'ibuffer-forward-filter-group
+    (kbd "[") 'ibuffer-backward-filter-group
+    [backtab] 'ibuffer-backward-filter-group
+    (kbd "M-j") 'ibuffer-jump-to-filter-group
+    (kbd "gx") 'ibuffer-kill-line
+    (kbd "C-y") 'ibuffer-yank
+    (kbd "s S") 'ibuffer-save-filter-groups
+    (kbd "s R") 'ibuffer-switch-to-saved-filter-groups
+    (kbd "s X") 'ibuffer-delete-saved-filter-groups
+    (kbd "s \\") 'ibuffer-clear-filter-groups
+
+    (kbd "% n") 'ibuffer-mark-by-name-regexp
+    (kbd "% m") 'ibuffer-mark-by-mode-regexp
+    (kbd "% f") 'ibuffer-mark-by-file-name-regexp
+    (kbd "% g") 'ibuffer-mark-by-content-regexp
+    (kbd "% L") 'ibuffer-mark-by-locked
+
+    (kbd "C-t") 'ibuffer-visit-tags-table
+
+    (kbd "|") 'ibuffer-do-shell-command-pipe
+    (kbd "!") 'ibuffer-do-shell-command-file
+    (kbd "t") 'ibuffer-do-toggle-modified
+    ;; marked operations
+    (kbd "A") 'ibuffer-do-view
+    (kbd "D") 'ibuffer-do-delete
+    (kbd "E") 'ibuffer-do-eval
+    (kbd "F") 'ibuffer-do-shell-command-file
+    (kbd "I") 'ibuffer-do-query-replace-regexp
+    (kbd "H") 'ibuffer-do-view-other-frame
+    (kbd "N") 'ibuffer-do-shell-command-pipe-replace
+    (kbd "M") 'ibuffer-do-toggle-modified
+    (kbd "O") 'ibuffer-do-occur
+    (kbd "P") 'ibuffer-do-print
+    (kbd "Q") 'ibuffer-do-query-replace
+    (kbd "R") 'ibuffer-do-rename-uniquely
+    (kbd "S") 'ibuffer-do-save
+    (kbd "T") 'ibuffer-do-toggle-read-only
+    (kbd "r") 'ibuffer-do-replace-regexp
+    (kbd "V") 'ibuffer-do-revert
+    (kbd "W") 'ibuffer-do-view-and-eval
+
+    (kbd "K") 'ibuffer-do-kill-lines
+    (kbd "yf") 'ibuffer-copy-filename-as-kill
+    (kbd "yb") 'ibuffer-copy-buffername-as-kill
+
+    (kbd "RET") 'ibuffer-visit-buffer
+    (kbd "go") 'ibuffer-visit-buffer-other-window
+    (kbd "C-o") 'ibuffer-visit-buffer-other-window-noselect
+    (kbd "M-o") 'ibuffer-visit-buffer-1-window
+    (kbd "gv") 'ibuffer-do-view
+    (kbd "gV") 'ibuffer-do-view-horizontally
+
+    ;; Quit
+    "q" 'quit-window
+    "ZZ" 'quit-window
+    "ZQ" 'quit-window))
+
+(provide 'evil-collection-ibuffer)
+;;; evil-collection-ibuffer.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-ibuffer.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-ibuffer.elc
new file mode 100644
index 0000000000..96e0e55939
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-ibuffer.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-image+.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-image+.el
new file mode 100644
index 0000000000..3bfe799573
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-image+.el
@@ -0,0 +1,53 @@
+;;; evil-collection-image+.el --- Evil bindings for image-mode with image+ -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 Pierre Neidhardt
+
+;; Author: Pierre Neidhardt <ambrevar@gmail.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, image, tools
+
+;; This file 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, or (at your
+;; option) any later version.
+;;
+;; This file 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.
+;;
+;; For a full copy of the GNU General Public License
+;; see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; Evil bindings for image-mode with image+.
+
+;;; Code:
+(require 'evil-collection)
+(require 'image+ nil t)
+
+(defconst evil-collection-image+-maps '(image-mode-map))
+
+(defun evil-collection-image+-setup ()
+  "Set up `evil' bindings for `image+'."
+  (evil-collection-define-key 'normal 'image-mode-map
+    ;; zoom
+    "+" 'imagex-sticky-zoom-in
+    "=" 'imagex-sticky-zoom-in
+    "-" 'imagex-sticky-zoom-out
+    "O" 'imagex-sticky-restore-original
+
+    "M" 'imagex-sticky-maximize
+    "m" 'imagex-auto-adjust-mode
+    "S" 'imagex-sticky-save-image
+    "r" 'imagex-sticky-rotate-right
+    "R" 'imagex-sticky-rotate-left
+    "<" 'imagex-sticky-rotate-left ; like sxiv
+    ">" 'imagex-sticky-rotate-right)) ; like sxiv
+
+(provide 'evil-collection-image+)
+;;; evil-collection-image+.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-image+.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-image+.elc
new file mode 100644
index 0000000000..2992105cd7
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-image+.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-image.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-image.el
new file mode 100644
index 0000000000..118051a0ad
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-image.el
@@ -0,0 +1,91 @@
+;;; evil-collection-image.el --- Evil bindings for Image -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 Pierre Neidhardt
+
+;; Author: Pierre Neidhardt <ambrevar@gmail.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, bookmark, tools
+
+;; This file 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, or (at your
+;; option) any later version.
+;;
+;; This file 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.
+;;
+;; For a full copy of the GNU General Public License
+;; see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; Evil bindings for `image-mode'.
+
+;;; Code:
+(require 'evil-collection)
+(require 'image-mode)
+
+;; TODO: pdf and doc-view conflict with image.
+;; See https://github.com/emacs-evil/evil-collection/issues/23.
+
+(defconst evil-collection-image-maps '(image-mode-map))
+
+(defun evil-collection-image-setup ()
+  "Set up `evil' bindings for `image-mode'."
+  (evil-set-initial-state 'image-mode 'normal)
+
+  (evil-collection-define-key 'normal 'image-mode-map
+    ;; motion
+    "gg" 'image-bob
+    "G" 'image-eob
+    "h" 'image-backward-hscroll
+    "l" 'image-forward-hscroll
+    "j" 'image-next-line
+    "k" 'image-previous-line
+    "0" 'image-bol
+    "^" 'image-bol
+    "$" 'image-eol
+    (kbd "C-d") 'image-scroll-up
+    (kbd "SPC") 'image-scroll-up
+    (kbd "S-SPC") 'image-scroll-down
+    (kbd "<delete>") 'image-scroll-down
+    ;; animation
+    (kbd "<return>") 'image-toggle-animation
+    "a0" 'image-reset-speed
+    "ar" 'image-reverse-speed
+    "F" 'image-goto-frame
+    "," 'image-previous-frame ; mplayer/mpv style
+    "." 'image-next-frame ; mplayer/mpv style
+    ";" 'image-next-frame ; Evil style
+    "{" 'image-decrease-speed ; mplayer/mpv style
+    "}" 'image-increase-speed ; mplayer/mpv style
+
+    "H" 'image-transform-fit-to-height
+    "W" 'image-transform-fit-to-width
+
+    "[" 'image-previous-file
+    "]" 'image-next-file
+    "gk" 'image-previous-file
+    "gj" 'image-next-file
+    (kbd "C-k") 'image-previous-file
+    (kbd "C-j") 'image-next-file
+
+    (kbd "C-c C-c") 'image-toggle-display
+
+    ;; quit
+    "q" 'quit-window
+    "ZQ" 'evil-quit
+    "ZZ" 'quit-window)
+
+  ;; TODO: What if the user changes `evil-want-C-u-scroll' after this is run?
+  (when evil-want-C-u-scroll
+    (evil-collection-define-key 'normal 'image-mode-map
+      (kbd "C-u") 'image-scroll-down)))
+
+(provide 'evil-collection-image)
+;;; evil-collection-image.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-image.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-image.elc
new file mode 100644
index 0000000000..df2abe74eb
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-image.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-imenu-list.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-imenu-list.el
new file mode 100644
index 0000000000..4d130ec99e
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-imenu-list.el
@@ -0,0 +1,46 @@
+;;; evil-collection-imenu-list.el --- Bindings for `imenu-list' -*- lexical-binding: t -*-
+
+;; Copyright (C) 2018 James Nguyen
+
+;; Author: Fredrik Bergroth <fbergroth@gmail.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, emacs, tools
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; Bindings for `imenu-list'.
+
+;;; Code:
+(require 'evil-collection)
+(require 'imenu-list nil t)
+
+(defconst evil-collection-imenu-list-maps '(imenu-list-major-mode-map))
+
+(defun evil-collection-imenu-list-setup ()
+  "Set up `evil' bindings for `imenu-list'."
+  (evil-collection-define-key 'normal 'imenu-list-major-mode-map
+    (kbd "RET") 'imenu-list-goto-entry
+    (kbd "TAB") 'hs-toggle-hiding
+    "d" 'imenu-list-display-entry
+    "gr" 'imenu-list-refresh
+    "q" 'imenu-list-quit-window))
+
+
+(provide 'evil-collection-imenu-list)
+;;; evil-collection-imenu-list.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-imenu-list.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-imenu-list.elc
new file mode 100644
index 0000000000..9fe9c0df93
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-imenu-list.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-indium.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-indium.el
new file mode 100644
index 0000000000..23e0c38845
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-indium.el
@@ -0,0 +1,133 @@
+;;; evil-collection-indium.el --- Bindings for `indium'. -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 James Nguyen
+
+;; Author: James Nguyen <james@jojojames.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: emacs, indium, javascript, tools
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; Bindings for `indium'.
+
+;;; Code:
+(require 'evil-collection)
+(require 'evil-collection-settings)
+(require 'indium nil t)
+
+(defconst evil-collection-indium-maps '(indium-debugger-mode-map
+                                        indium-inspector-mode-map
+                                        indium-debugger-locals-mode-map
+                                        indium-debugger-frames-mode-map
+                                        indium-interaction-mode-map
+                                        indium-repl-mode-map))
+
+(defun evil-collection-indium-setup ()
+  "Set up `evil' bindings for `indium'."
+  (when evil-collection-settings-setup-debugger-keys
+    (evil-collection-define-key 'normal 'indium-debugger-mode-map
+      "n" 'indium-debugger-step-over
+      "i" 'indium-debugger-step-into
+      "o" 'indium-debugger-step-out
+      "c" 'indium-debugger-resume
+      "L" 'indium-debugger-locals
+      "s" 'indium-debugger-stack-frames
+      "q" 'indium-debugger-resume
+      "H" 'indium-debugger-here
+      "e" 'indium-debugger-evaluate
+      ">" 'indium-debugger-next-frame
+      "<" 'indium-debugger-previous-frame)
+
+    (add-hook 'indium-debugger-mode-hook #'evil-normalize-keymaps))
+
+  (evil-collection-define-key 'normal 'indium-inspector-mode-map
+    "q" 'quit-window
+    (kbd "RET") 'indium-follow-link
+    [mouse-1] 'indium-follow-link
+    "L" 'indium-inspector-pop
+    "gr" 'indium-inspector-refresh
+    "gj" 'indium-inspector-next-reference
+    "gk" 'indium-inspector-previous-reference
+    (kbd "C-j") 'indium-inspector-next-reference
+    (kbd "C-k") 'indium-inspector-previous-reference
+    [tab] 'indium-inspector-next-reference
+    [backtab] 'indium-inspector-previous-reference)
+
+  (evil-collection-define-key 'normal 'indium-debugger-locals-mode-map
+    "q" 'quit-window
+    "L" nil
+    "gr" nil)
+
+  (evil-collection-define-key 'normal 'indium-debugger-frames-mode-map
+    "q" 'quit-window
+    [return] 'indium-follow-link
+    (kbd "RET") 'indium-follow-link
+    (kbd "gj") 'indium-debugger-frames-next-frame
+    (kbd "gk") 'indium-debugger-frames-previous-frame
+    (kbd "C-j") 'indium-debugger-frames-next-frame
+    (kbd "C-k") 'indium-debugger-frames-previous-frame
+    [tab] 'indium-debugger-frames-next-frame
+    [backtab] 'indium-debugger-frames-previous-frame)
+
+  (evil-collection-define-key 'normal 'indium-interaction-mode-map
+    "gr" 'indium-update-script-source
+    "gz" 'indium-switch-to-repl-buffer)
+
+  (when evil-collection-settings-setup-debugger-keys
+    (evil-collection-define-key 'normal 'indium-interaction-mode-map
+      [left-fringe mouse-1] 'evil-collection-indium-debugger-mouse-toggle-breakpoint
+      [left-margin mouse-1] 'evil-collection-indium-debugger-mouse-toggle-breakpoint
+      [f5] 'indium-debugger-resume
+      [S-f5] 'indium-debugger-resume
+      [f9] 'evil-collection-indium-debugger-toggle-breakpoint
+      [f10] 'indium-debugger-step-over
+      [f11] 'indium-debugger-step-into
+      [S-f11] 'indium-debugger-step-out))
+
+  (evil-collection-define-key 'normal 'indium-repl-mode-map
+    (kbd "gj") 'indium-repl-next-input
+    (kbd "gk") 'indium-repl-previous-input
+    (kbd "C-j") 'indium-repl-next-input
+    (kbd "C-k") 'indium-repl-previous-input))
+
+;; FIXME: It would be better for these to go upstream.
+(declare-function indium-breakpoint-on-current-line-p "indium-breakpoint")
+(declare-function indium-remove-breakpoint "indium-interaction")
+(declare-function indium-add-breakpoint "indium-interaction")
+
+(defun evil-collection-indium-debugger-toggle-breakpoint ()
+  "Toggle breakpoint at point."
+  (interactive)
+  (if (indium-breakpoint-on-current-line-p)
+      (call-interactively #'indium-remove-breakpoint)
+    (call-interactively #'indium-add-breakpoint)))
+
+(defun evil-collection-indium-debugger-mouse-toggle-breakpoint (event)
+  "Toggle breakpoint at mouse EVENT click point."
+  (interactive "e")
+  (let* ((posn (event-end event))
+         (pos (posn-point posn)))
+    (when (numberp pos)
+      (with-current-buffer (window-buffer (posn-window posn))
+        (save-excursion
+          (goto-char pos)
+          (call-interactively #'evil-collection-indium-debugger-toggle-breakpoint))))))
+
+(provide 'evil-collection-indium)
+;;; evil-collection-indium.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-indium.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-indium.elc
new file mode 100644
index 0000000000..89e04b5ef0
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-indium.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-info.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-info.el
new file mode 100644
index 0000000000..f815f61085
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-info.el
@@ -0,0 +1,110 @@
+;;; evil-collection-info.el --- Evil bindings for Info-mode -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 Pierre Neidhardt
+
+;; Author: Pierre Neidhardt <ambrevar@gmail.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, info, tools
+
+;; This file 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, or (at your
+;; option) any later version.
+;;
+;; This file 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.
+;;
+;; For a full copy of the GNU General Public License
+;; see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; The default bindings in motion state override the standard movement keys.
+;; This package uses normal state and redefines everything.
+
+;;; Code:
+(require 'evil-collection)
+(require 'info)
+
+(defconst evil-collection-info-maps '(Info-mode-map))
+
+(defun evil-collection-info-setup ()
+  "Set up `evil' bindings for `info-mode'."
+  (evil-collection-inhibit-insert-state 'Info-mode-map)
+  (evil-set-initial-state 'Info-mode 'normal)
+  (evil-collection-define-key 'normal 'Info-mode-map
+    (kbd "<tab>") 'Info-next-reference
+    (kbd "S-<tab>") 'Info-prev-reference
+
+    ;; From evil-integration.el.
+    "0" 'evil-digit-argument-or-evil-beginning-of-line
+    (kbd "M-h") 'Info-help              ; "h"
+    (kbd "C-t") 'Info-history-back      ; "l"
+    (kbd "C-o") 'Info-history-back
+    " " 'Info-scroll-up
+    (kbd "C-]") 'Info-follow-nearest-node
+    (kbd "DEL") 'Info-scroll-down
+    ;; Add "C-i" for consistency.
+    (kbd "C-i") 'Info-history-forward
+
+    "d" 'Info-directory
+    "u" 'Info-up
+    "L" 'Info-history
+    "s" 'Info-search
+    "S" 'Info-search-case-sensitively
+    "i" 'Info-index
+    "I" 'Info-virtual-index
+    "a" 'info-apropos
+    "m" 'Info-menu
+    "w" 'evil-forward-word-begin
+    "b" 'evil-backward-word-begin
+
+    "gg" 'evil-goto-first-line
+
+    ;; TODO: Restore digit arguments?  Use g[n] instead.
+
+    ;; TODO: Should search with "n"/"N" cover the full manual like "C-s"/"C-r" does?
+    ;; TODO: Directions?
+    "n" (if (evil-collection-evil-search-enabled)
+            evil-collection-evil-search-next
+          'isearch-repeat-forward)
+    "N" (if (evil-collection-evil-search-enabled)
+            evil-collection-evil-search-previous
+          'isearch-repeat-backward)
+
+    ;; goto
+    "gd" 'Info-goto-node ; TODO: "gd" does not match the rationale of "go to definition". Change?
+    "gm" 'Info-menu
+    "gt" 'Info-top-node
+    "gT" 'Info-toc
+    "gf" 'Info-follow-reference
+    ;; TODO: "[" and "]" are Emacs default for fine-grained browsing.
+    ;; We usually use "C-j"/"C-k" for that.
+    (kbd "C-j") 'Info-next
+    (kbd "C-k") 'Info-prev
+    "gj" 'Info-next
+    "gk" 'Info-prev
+
+
+    ;; quit
+    "q" 'Info-exit
+    "ZQ" 'evil-quit
+    "ZZ" 'Info-exit)
+
+  (evil-collection-define-key 'operator 'Info-mode-map
+    "u" '(menu-item                     ; Like eww.
+          ""
+          nil
+          :filter (lambda (&optional _)
+                    (when (memq evil-this-operator
+                                evil-collection-yank-operators)
+                      (setq evil-inhibit-operator t)
+                      #'Info-copy-current-node-name)))))
+
+(provide 'evil-collection-info)
+;;; evil-collection-info.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-info.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-info.elc
new file mode 100644
index 0000000000..f572d97db3
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-info.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-integration.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-integration.el
new file mode 100644
index 0000000000..7d73ab5984
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-integration.el
@@ -0,0 +1,313 @@
+;;; evil-collection-integration.el --- Integrate `evil' with other modules. -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 James Nguyen
+
+;; Author: James Nguyen <james@jojojames.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, emacs, tools
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;; Integrate `evil' with other modules.
+;;; This is an initial copy of evil-integration.el
+
+;; Previous Author/Maintainer:
+;; Author: Vegard Øye <vegard_oye at hotmail.com>
+;; Maintainer: Vegard Øye <vegard_oye at hotmail.com>
+
+;;; Code:
+(require 'evil-maps)
+(require 'evil-core)
+(require 'evil-macros)
+(require 'evil-types)
+(require 'evil-repeat)
+
+;;; Evilize some commands
+
+;; unbound keys should be ignored
+(evil-declare-ignore-repeat 'undefined)
+
+(mapc #'(lambda (cmd)
+          (evil-set-command-property cmd :keep-visual t)
+          (evil-declare-not-repeat cmd))
+      '(digit-argument
+        negative-argument
+        universal-argument
+        universal-argument-minus
+        universal-argument-more
+        universal-argument-other-key))
+(mapc #'evil-declare-not-repeat
+      '(what-cursor-position))
+(mapc #'evil-declare-change-repeat
+      '(dabbrev-expand
+        hippie-expand
+        quoted-insert))
+(mapc #'evil-declare-abort-repeat
+      '(balance-windows
+        eval-expression
+        execute-extended-command
+        exit-minibuffer
+        compile
+        delete-window
+        delete-other-windows
+        find-file-at-point
+        ffap-other-window
+        recompile
+        redo
+        save-buffer
+        split-window
+        split-window-horizontally
+        split-window-vertically
+        undo
+        undo-tree-redo
+        undo-tree-undo))
+
+(evil-set-type #'previous-line 'line)
+(evil-set-type #'next-line 'line)
+
+(dolist (cmd '(keyboard-quit keyboard-escape-quit))
+  (evil-set-command-property cmd :suppress-operator t))
+
+;;; Mouse
+(evil-declare-insert-at-point-repeat 'mouse-yank-primary)
+(evil-declare-insert-at-point-repeat 'mouse-yank-secondary)
+
+;;; key-binding
+
+;; Calling `keyboard-quit' should cancel repeat
+(defadvice keyboard-quit (before evil activate)
+  (when (fboundp 'evil-repeat-abort)
+    (evil-repeat-abort)))
+
+;; dictionary.el
+
+(evil-add-hjkl-bindings dictionary-mode-map 'motion
+  "?" 'dictionary-help        ; "h"
+  "C-o" 'dictionary-previous) ; "l"
+
+;;; Dired
+
+(eval-after-load 'wdired
+  '(progn
+     (add-hook 'wdired-mode-hook #'evil-change-to-initial-state)
+     (defadvice wdired-change-to-dired-mode (after evil activate)
+       (evil-change-to-initial-state nil t))))
+
+;;; ELP
+
+(eval-after-load 'elp
+  '(defadvice elp-results (after evil activate)
+     (evil-motion-state)))
+
+;;; Info
+
+(evil-add-hjkl-bindings Info-mode-map 'motion
+  "0" 'evil-digit-argument-or-evil-beginning-of-line
+  (kbd "\M-h") 'Info-help   ; "h"
+  "\C-t" 'Info-history-back ; "l"
+  "\C-o" 'Info-history-back
+  " " 'Info-scroll-up
+  "\C-]" 'Info-follow-nearest-node
+  (kbd "DEL") 'Info-scroll-down)
+
+;;; Speedbar
+
+(evil-add-hjkl-bindings speedbar-key-map 'motion
+  "h" 'backward-char
+  "j" 'speedbar-next
+  "k" 'speedbar-prev
+  "l" 'forward-char
+  "i" 'speedbar-item-info
+  "r" 'speedbar-refresh
+  "u" 'speedbar-up-directory
+  "o" 'speedbar-toggle-line-expansion
+  (kbd "RET") 'speedbar-edit-line)
+
+;;; Undo tree
+(when (and (require 'undo-tree nil t)
+           (fboundp 'global-undo-tree-mode))
+  (global-undo-tree-mode 1))
+
+(eval-after-load 'undo-tree
+  '(with-no-warnings
+     (defun evil-collection-integration-turn-on-undo-tree-mode ()
+       "Enable `undo-tree-mode' if evil is enabled.
+This function enables `undo-tree-mode' when Evil is activated in
+some buffer, but only if `global-undo-tree-mode' is also
+activated."
+       (when (and (boundp 'global-undo-tree-mode)
+                  global-undo-tree-mode)
+         (turn-on-undo-tree-mode)))
+
+     (add-hook 'evil-local-mode-hook #'evil-collection-integration-turn-on-undo-tree-mode)
+
+     (defadvice undo-tree-visualize (after evil activate)
+       "Initialize Evil in the visualization buffer."
+       (when evil-local-mode
+         (evil-initialize-state)))
+
+     (when (fboundp 'undo-tree-visualize)
+       (evil-ex-define-cmd "undol[ist]" 'undo-tree-visualize)
+       (evil-ex-define-cmd "ul" 'undo-tree-visualize))
+
+     (when (boundp 'undo-tree-visualizer-mode-map)
+       (define-key undo-tree-visualizer-mode-map
+         [remap evil-backward-char] 'undo-tree-visualize-switch-branch-left)
+       (define-key undo-tree-visualizer-mode-map
+         [remap evil-forward-char] 'undo-tree-visualize-switch-branch-right)
+       (define-key undo-tree-visualizer-mode-map
+         [remap evil-next-line] 'undo-tree-visualize-redo)
+       (define-key undo-tree-visualizer-mode-map
+         [remap evil-previous-line] 'undo-tree-visualize-undo)
+       (define-key undo-tree-visualizer-mode-map
+         [remap evil-ret] 'undo-tree-visualizer-set))
+
+     (when (boundp 'undo-tree-visualizer-selection-mode-map)
+       (define-key undo-tree-visualizer-selection-mode-map
+         [remap evil-backward-char] 'undo-tree-visualizer-select-left)
+       (define-key undo-tree-visualizer-selection-mode-map
+         [remap evil-forward-char] 'undo-tree-visualizer-select-right)
+       (define-key undo-tree-visualizer-selection-mode-map
+         [remap evil-next-line] 'undo-tree-visualizer-select-next)
+       (define-key undo-tree-visualizer-selection-mode-map
+         [remap evil-previous-line] 'undo-tree-visualizer-select-previous)
+       (define-key undo-tree-visualizer-selection-mode-map
+         [remap evil-ret] 'undo-tree-visualizer-set))))
+
+;;; Auto-complete
+(eval-after-load 'auto-complete
+  '(progn
+     (evil-add-command-properties 'auto-complete :repeat 'evil-collection-integration-ac-repeat)
+     (evil-add-command-properties 'ac-complete :repeat 'evil-collection-integration-ac-repeat)
+     (evil-add-command-properties 'ac-expand :repeat 'evil-collection-integration-ac-repeat)
+     (evil-add-command-properties 'ac-next :repeat 'ignore)
+     (evil-add-command-properties 'ac-previous :repeat 'ignore)
+
+     (defvar evil-collection-integration-ac-prefix-len nil
+       "The length of the prefix of the current item to be completed.")
+
+     (defvar ac-prefix)
+     (defun evil-collection-integration-ac-repeat (flag)
+       "Record the changes for auto-completion."
+       (cond
+        ((eq flag 'pre)
+         (setq evil-collection-integration-ac-prefix-len (length ac-prefix))
+         (evil-repeat-start-record-changes))
+        ((eq flag 'post)
+         ;; Add change to remove the prefix
+         (evil-repeat-record-change (- evil-collection-integration-ac-prefix-len)
+                                    ""
+                                    evil-collection-integration-ac-prefix-len)
+         ;; Add change to insert the full completed text
+         (evil-repeat-record-change
+          (- evil-collection-integration-ac-prefix-len)
+          (buffer-substring-no-properties (- evil-repeat-pos
+                                             evil-collection-integration-ac-prefix-len)
+                                          (point))
+          0)
+         ;; Finish repeation
+         (evil-repeat-finish-record-changes))))))
+
+;;; Company
+(eval-after-load 'company
+  '(progn
+     (mapc #'evil-declare-change-repeat
+           '(company-complete-mouse
+             company-complete-number
+             company-complete-selection
+             company-complete-common))
+
+     (mapc #'evil-declare-ignore-repeat
+           '(company-abort
+             company-select-next
+             company-select-previous
+             company-select-next-or-abort
+             company-select-previous-or-abort
+             company-select-mouse
+             company-show-doc-buffer
+             company-show-location
+             company-search-candidates
+             company-filter-candidates))))
+
+;; Eval last sexp
+(cond
+ ((version< emacs-version "25")
+  (defadvice preceding-sexp (around evil activate)
+    "In normal-state or motion-state, last sexp ends at point."
+    (if (and (not evil-move-beyond-eol)
+             (or (evil-normal-state-p) (evil-motion-state-p)))
+        (save-excursion
+          (unless (or (eobp) (eolp)) (forward-char))
+          ad-do-it)
+      ad-do-it))
+
+  (defadvice pp-last-sexp (around evil activate)
+    "In normal-state or motion-state, last sexp ends at point."
+    (if (and (not evil-move-beyond-eol)
+             (or (evil-normal-state-p) (evil-motion-state-p)))
+        (save-excursion
+          (unless (or (eobp) (eolp)) (forward-char))
+          ad-do-it)
+      ad-do-it)))
+ (t
+  (defun evil-collection-integration--preceding-sexp (command &rest args)
+    "In normal-state or motion-state, last sexp ends at point."
+    (if (and (not evil-move-beyond-eol)
+             (or (evil-normal-state-p) (evil-motion-state-p)))
+        (save-excursion
+          (unless (or (eobp) (eolp)) (forward-char))
+          (apply command args))
+      (apply command args)))
+
+  (advice-add 'elisp--preceding-sexp :around 'evil-collection-integration--preceding-sexp '((name . evil)))
+  (advice-add 'pp-last-sexp          :around 'evil-collection-integration--preceding-sexp '((name . evil)))))
+
+;; Show key
+(defadvice quail-show-key (around evil activate)
+  "Temporarily go to Emacs state"
+  (evil-with-state emacs ad-do-it))
+
+(defadvice describe-char (around evil activate)
+  "Temporarily go to Emacs state"
+  (evil-with-state emacs ad-do-it))
+
+;;; nXhtml/mumamo
+;; ensure that mumamo does not toggle evil through its globalized mode
+(eval-after-load 'mumamo
+  '(with-no-warnings
+     (push 'evil-mode-cmhh mumamo-change-major-mode-no-nos)))
+
+;; visual-line-mode integration
+(when evil-respect-visual-line-mode
+  (let ((swaps '((evil-next-line . evil-next-visual-line)
+                 (evil-previous-line . evil-previous-visual-line)
+                 (evil-beginning-of-line . evil-beginning-of-visual-line)
+                 (evil-end-of-line . evil-end-of-visual-line))))
+    (dolist (swap swaps)
+      (define-key visual-line-mode-map (vector 'remap (car swap)) (cdr swap))
+      (define-key visual-line-mode-map (vector 'remap (cdr swap)) (car swap)))))
+
+;;; abbrev.el
+(when evil-want-abbrev-expand-on-insert-exit
+  (eval-after-load 'abbrev
+    '(add-hook 'evil-insert-state-exit-hook 'expand-abbrev)))
+
+
+(provide 'evil-collection-integration)
+;;; evil-collection-integration.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-integration.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-integration.elc
new file mode 100644
index 0000000000..b7b735b301
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-integration.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-ivy.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-ivy.el
new file mode 100644
index 0000000000..2c1f773c16
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-ivy.el
@@ -0,0 +1,110 @@
+;;; evil-collection-ivy.el --- Evil bindings for ivy -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 James Nguyen
+
+;; Author: James Nguyen <james@jojojames.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, ivy, tools
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; Evil bindings for `ivy-mode'.
+
+;;; Code:
+(require 'evil-collection)
+(require 'ivy nil t)
+
+(defconst evil-collection-ivy-maps '(ivy-occur-mode-map
+                                     ivy-occur-grep-mode-map
+                                     ivy-minibuffer-map))
+
+(defun evil-collection-ivy-setup ()
+  "Set up `evil' bindings for `ivy-mode'."
+  (evil-collection-define-key nil 'ivy-mode-map
+    (kbd "<escape>") 'minibuffer-keyboard-quit)
+  (evil-collection-define-key 'normal 'ivy-occur-mode-map
+    [mouse-1] 'ivy-occur-click
+    (kbd "<return>") 'ivy-occur-press-and-switch
+    "j" 'ivy-occur-next-line
+    "k" 'ivy-occur-previous-line
+    "h" 'evil-backward-char
+    "l" 'evil-forward-char
+    "g" nil
+    "gg" 'evil-goto-first-line
+    "gf" 'ivy-occur-press
+    "ga" 'ivy-occur-read-action
+    "go" 'ivy-occur-dispatch
+    "gc" 'ivy-occur-toggle-calling
+
+    ;; refresh
+    "gr" 'ivy-occur-revert-buffer
+
+    ;; quit
+    "q" 'quit-window)
+
+  (when evil-want-C-d-scroll
+    (evil-collection-define-key 'normal 'ivy-occur-grep-mode-map
+      "D" 'ivy-occur-delete-candidate
+      (kbd "C-d") 'evil-scroll-down))
+
+  (evil-collection-define-key 'visual 'ivy-occur-grep-mode-map
+    "j" 'evil-next-line
+    "k" 'evil-previous-line)
+
+  (evil-collection-define-key 'normal 'ivy-occur-grep-mode-map
+    "d" 'ivy-occur-delete-candidate
+    (kbd "C-x C-q") 'ivy-wgrep-change-to-wgrep-mode
+    "i" 'ivy-wgrep-change-to-wgrep-mode
+    "gd" 'ivy-occur-delete-candidate
+    [mouse-1] 'ivy-occur-click
+    (kbd "<return>") 'ivy-occur-press-and-switch
+    "j" 'ivy-occur-next-line
+    "k" 'ivy-occur-previous-line
+    "h" 'evil-backward-char
+    "l" 'evil-forward-char
+    "g" nil
+    "gg" 'evil-goto-first-line
+    "gf" 'ivy-occur-press
+    "gr" 'ivy-occur-revert-buffer
+    "ga" 'ivy-occur-read-action
+    "go" 'ivy-occur-dispatch
+    "gc" 'ivy-occur-toggle-calling
+
+    "0" 'evil-digit-argument-or-evil-beginning-of-line
+
+    ;; quit
+    "q" 'quit-window)
+
+  (defvar evil-collection-setup-minibuffer)
+  (when evil-collection-setup-minibuffer
+    (evil-collection-define-key 'normal 'ivy-minibuffer-map
+      (kbd "<escape>") 'abort-recursive-edit
+      (kbd "<return>") 'exit-minibuffer
+      (kbd "C-m") 'ivy-done
+      "j" 'ivy-next-line
+      "k" 'ivy-previous-line)
+
+    (evil-collection-define-key 'insert 'ivy-minibuffer-map
+      [backspace] 'ivy-backward-delete-char
+      (kbd "C-r") 'ivy-reverse-i-search
+      (kbd "C-n") 'ivy-next-line
+      (kbd "C-p") 'ivy-previous-line)))
+
+(provide 'evil-collection-ivy)
+;;; evil-collection-ivy.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-ivy.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-ivy.elc
new file mode 100644
index 0000000000..6def67bcea
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-ivy.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-js2-mode.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-js2-mode.el
new file mode 100644
index 0000000000..5a361f0a8a
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-js2-mode.el
@@ -0,0 +1,45 @@
+;;; evil-collection-js2-mode.el --- Bindings for `js2-mode' -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 James Nguyen
+
+;; Author: James Nguyen <james@jojojames.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, emacs, tools
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;; Bindings for `js2-mode'
+
+;;; Code:
+(require 'evil-collection)
+(require 'js2-mode nil t)
+
+(defvar js-indent-level)
+
+(defun evil-collection-js2-set-evil-shift-width ()
+  "Set `evil-shift-width' according to `js-indent-level'."
+  (setq-local evil-shift-width js-indent-level))
+
+(defun evil-collection-js2-mode-setup ()
+  "Set up `evil' bindings for `js2-mode'."
+  (add-hook 'js2-mode-hook #'evil-collection-js2-set-evil-shift-width)
+  (add-hook 'js2-jsx-mode-hook #'evil-collection-js2-set-evil-shift-width))
+
+(provide 'evil-collection-js2-mode)
+;;; evil-collection-js2-mode.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-js2-mode.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-js2-mode.elc
new file mode 100644
index 0000000000..e701c641f0
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-js2-mode.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-kotlin-mode.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-kotlin-mode.el
new file mode 100644
index 0000000000..5ddf538862
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-kotlin-mode.el
@@ -0,0 +1,41 @@
+;;; evil-collection-kotlin-mode.el --- Bindings for `kotlin-mode'. -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 James Nguyen
+
+;; Author: James Nguyen <james@jojojames.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: emacs, evil, tools
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;; Bindings for `kotlin-mode'.
+
+;;; Code:
+(require 'evil-collection)
+(require 'kotlin-mode nil t)
+
+(defconst evil-collection-kotlin-maps '(kotlin-mode-map))
+
+(defun evil-collection-kotlin-mode-setup ()
+  "Set up `evil' bindings for `kotlin-mode'."
+  (evil-collection-define-key 'normal 'kotlin-mode-map
+    "gz" 'kotlin-repl))
+
+(provide 'evil-collection-kotlin-mode)
+;;; evil-collection-kotlin-mode.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-kotlin-mode.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-kotlin-mode.elc
new file mode 100644
index 0000000000..85ef5acfa9
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-kotlin-mode.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-lispy.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-lispy.el
new file mode 100644
index 0000000000..70e1280a04
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-lispy.el
@@ -0,0 +1,211 @@
+;;; evil-collection-lispy.el --- Evil Bindings for Lispy -*- lexical-binding: t -*-
+
+;; Copyright (C) 2018 James Nguyen
+
+;; Author: James Nguyen <james@jojojames.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, lispy, tools
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; Evil bindings for `lispy-mode'.
+;; This is not included in the default init list for `evil-collection'.
+;; Add `lispy' to `evil-collection-mode-list' to use this package.
+;; e.g. (push 'lispy evil-collection-mode-list)
+;; This file is meant to be an experimental ground for `lispy' keybindings
+;; and the changes here are intended to be created as a PR to the main `lispy'
+;; repository.
+;; PRs, tweaks or comments are very welcome!
+
+;;; Code:
+(require 'lispy nil t)
+(require 'evil-collection)
+
+(defconst evil-collection-lispy-maps '(lispy-mode-map))
+
+(defvar lispy-mode-map-base)
+(defvar lispy-mode-map-special)
+(defvar lispy-mode-map-lispy)
+(defvar lispy-mode-map-paredit)
+(defvar lispy-mode-map-parinfer)
+(defvar lispy-mode-map-evilcp)
+(defvar lispy-mode-map-c-digits)
+(defvar lispy-mode-map-oleh)
+(defvar lispy-mode-map)
+(declare-function lispy-define-key "lispy")
+(declare-function lispy-set-key-theme "lispy")
+
+(defvar evil-collection-lispy-mode-map-special-evil
+  (let ((map (make-sparse-keymap)))
+    ;; navigation
+    (lispy-define-key map "l" 'lispy-right)
+    (lispy-define-key map "h" 'lispy-left)
+    (lispy-define-key map "f" 'lispy-ace-paren
+      :override '(cond ((bound-and-true-p view-mode)
+                        (View-quit)))) ;; `lispy-flow' -> w
+    (lispy-define-key map "j" 'lispy-down)
+    (lispy-define-key map "k" 'lispy-up)
+    (lispy-define-key map "d" 'lispy-delete) ;; `lispy-different' -> o
+    (lispy-define-key map "o" 'lispy-different) ;; `lispy-other-mode' -> Q
+    (lispy-define-key map "p" 'lispy-paste) ;; `lispy-eval-other-window' -> P
+    (lispy-define-key map "P" 'lispy-eval-other-window) ;; `lispy-paste' -> p
+    (lispy-define-key map "y" 'lispy-new-copy) ;; `lispy-occur' -> /
+    (lispy-define-key map "z" 'lh-knight/body)
+
+    ;; outline
+    (lispy-define-key map "J" 'lispy-join)     ;; `lispy-outline-next'
+    (lispy-define-key map "K" 'lispy-describe) ;; `lispy-outline-prev'
+    (lispy-define-key map "L" 'lispy-outline-goto-child)
+
+    ;; Paredit transformations
+    (lispy-define-key map ">" 'lispy-slurp-or-barf-right) ;; `lispy-slurp'
+    (lispy-define-key map "<" 'lispy-slurp-or-barf-left) ;; `lispy-barf'
+
+    (lispy-define-key map "/" 'lispy-occur) ;; `lispy-x' -> q
+
+    (lispy-define-key map "r" 'lispy-raise)
+    (lispy-define-key map "R" 'lispy-raise-some)
+
+    (lispy-define-key map "+" 'lispy-join) ;; Hmnn this can be something else.
+
+    ;; more transformations
+    (lispy-define-key map "C" 'lispy-convolute)
+    (lispy-define-key map "X" 'lispy-convolute-left)
+    (lispy-define-key map "w" 'lispy-move-up)
+    (lispy-define-key map "s" 'lispy-move-down)
+    (lispy-define-key map "O" 'lispy-oneline)
+    (lispy-define-key map "M" 'lispy-alt-multiline)
+    (lispy-define-key map "S" 'lispy-stringify)
+
+    ;; marking
+    (lispy-define-key map "a" 'lispy-ace-symbol
+      :override '(cond ((looking-at lispy-outline)
+                        (lispy-meta-return))))
+    (lispy-define-key map "H" 'lispy-ace-symbol-replace)
+    (lispy-define-key map "m" 'lispy-view) ;; `lispy-mark-list' -> v
+
+    ;; dialect-specific
+    (lispy-define-key map "e" 'lispy-eval)
+    (lispy-define-key map "E" 'lispy-eval-and-insert)
+    (lispy-define-key map "G" 'lispy-goto-local)
+    (lispy-define-key map "g" 'lispy-goto)
+    (lispy-define-key map "F" 'lispy-follow t)
+    (lispy-define-key map "D" 'pop-tag-mark)
+    (lispy-define-key map "A" 'lispy-beginning-of-defun)
+    (lispy-define-key map "_" 'lispy-underscore)
+    ;; miscellanea
+    (define-key map (kbd "SPC") 'lispy-space)
+    (lispy-define-key map "i" 'lispy-tab)
+    (lispy-define-key map "I" 'lispy-shifttab)
+    (lispy-define-key map "N" 'lispy-narrow)
+    (lispy-define-key map "W" 'lispy-widen)
+    (lispy-define-key map "c" 'lispy-clone)
+    (lispy-define-key map "u" 'lispy-undo)
+
+    (lispy-define-key map "q" 'lispy-x) ;; `lispy-ace-paren' -> f
+    (lispy-define-key map "Q" 'lispy-other-mode) ;; `lispy-ace-char' -> t
+    (lispy-define-key map "v" 'lispy-mark-list)  ;; `lispy-view' -> m
+    (lispy-define-key map "t" 'lispy-ace-char) ;; `lispy-teleport' -> T
+    (lispy-define-key map "n" 'lispy-flow) ;; `lispy-new-copy' -> y
+    (lispy-define-key map "b" 'lispy-back)
+
+    (lispy-define-key map "B" 'lispy-ediff-regions)
+    (lispy-define-key map "x" 'lispy-splice) ;; `lispy-x' -> q
+
+    (lispy-define-key map "Z" 'lispy-edebug-stop)
+    (lispy-define-key map "V" 'lispy-visit)
+    (lispy-define-key map "-" 'lispy-ace-subword)
+    (lispy-define-key map "." 'lispy-repeat)
+    (lispy-define-key map "~" 'lispy-tilde)
+    ;; digit argument
+    (mapc (lambda (x) (lispy-define-key map (format "%d" x) 'digit-argument))
+          (number-sequence 0 9))
+
+    ;; additional
+    (lispy-define-key map "T" 'lispy-teleport
+      :override '(cond ((looking-at lispy-outline)
+                        (end-of-line))))
+    (lispy-define-key map "C-J" 'lispy-outline-next) ;; Hmnn...
+    (lispy-define-key map "C-K" 'lispy-outline-prev) ;; Hmnn...
+    (lispy-define-key map "]" 'lispy-forward)
+    (lispy-define-key map "[" 'lispy-backward)
+    (lispy-define-key map "{" 'lispy-brackets)
+    (lispy-define-key map "^" 'lispy-splice-sexp-killing-backward)
+    map)
+  "`evil' flavored `lispy' bindings when in special state.")
+
+(defvar evil-collection-lispy-mode-map-evil
+  (let ((map (copy-keymap lispy-mode-map-base)))
+    (define-key map (kbd "M-)") 'lispy-wrap-round)
+    (define-key map (kbd "M-s") 'lispy-splice)
+    (define-key map (kbd "M-<up>") 'lispy-splice-sexp-killing-backward)
+    (define-key map (kbd "M-<down>") 'lispy-splice-sexp-killing-backward)
+    (define-key map (kbd "M-r") 'lispy-raise-sexp)
+    (define-key map (kbd "M-C") 'lispy-convolute-sexp)
+    (define-key map (kbd "M-S") 'lispy-split)
+    (define-key map (kbd "M-J") 'lispy-join)
+    (define-key map (kbd "]") 'lispy-forward)
+    (define-key map (kbd "[") 'lispy-backward)
+    (define-key map (kbd "M-(") 'lispy-wrap-round)
+    (define-key map (kbd "M-{") 'lispy-wrap-braces)
+    (define-key map (kbd "M-}") 'lispy-wrap-braces)
+    (define-key map (kbd "<") 'lispy-slurp-or-barf-left)
+    (define-key map (kbd ">") 'lispy-slurp-or-barf-right)
+    (define-key map (kbd "M-y") 'lispy-new-copy)
+    (define-key map (kbd "<C-return>") 'lispy-open-line)
+    (define-key map (kbd "<M-return>") 'lispy-meta-return)
+    (define-key map (kbd "M-k") 'lispy-move-up)
+    (define-key map (kbd "M-j") 'lispy-move-down)
+    (define-key map (kbd "M-o") 'lispy-string-oneline)
+    (define-key map (kbd "M-p") 'lispy-clone)
+    (define-key map (kbd "M-d") 'lispy-delete)
+    map)
+  "`evil' flavored `lispy-mode' bindings.")
+
+(defun evil-collection-lispy-set-key-theme (theme)
+  "Set `lispy-mode-map' for according to THEME.
+THEME is a list of choices: 'special, 'lispy, 'paredit, 'evilcp,
+'c-digits', 'special-evil', 'evil'.
+
+This is an exact copy of `lispy-set-key-theme' except with the additions of
+'special-evil' and 'evil' themes."
+  (setq lispy-mode-map
+        (make-composed-keymap
+         (delq nil
+               (list
+                (when (memq 'special-evil theme) evil-collection-lispy-mode-map-special-evil)
+                (when (memq 'evil theme) evil-collection-lispy-mode-map-evil)
+                (when (memq 'special theme) lispy-mode-map-special)
+                (when (memq 'lispy theme) lispy-mode-map-lispy)
+                (when (memq 'paredit theme) lispy-mode-map-paredit)
+                (when (memq 'parinfer theme) lispy-mode-map-parinfer)
+                (when (memq 'evilcp theme) lispy-mode-map-evilcp)
+                (when (memq 'c-digits theme) lispy-mode-map-c-digits)
+                (when (memq 'oleh theme) lispy-mode-map-oleh)))))
+  (setcdr
+   (assq 'lispy-mode minor-mode-map-alist)
+   lispy-mode-map))
+
+(defun evil-collection-lispy-setup ()
+  "Set up `evil' bindings for `lispy'."
+  (advice-add 'lispy-set-key-theme :override 'evil-collection-lispy-set-key-theme)
+  (lispy-set-key-theme '(special-evil evil)))
+
+(provide 'evil-collection-lispy)
+;;; evil-collection-lispy.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-lispy.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-lispy.elc
new file mode 100644
index 0000000000..09a150750c
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-lispy.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-log-view.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-log-view.el
new file mode 100644
index 0000000000..83032659a7
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-log-view.el
@@ -0,0 +1,55 @@
+;;; evil-collection-log-view.el --- Bindings for `log-view' -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 James Nguyen
+
+;; Author: James Nguyen <james@jojojames.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, emacs, tools
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; Bindings for `log-view'.
+
+;;; Code:
+(require 'evil-collection)
+(require 'log-view)
+
+(defconst evil-collection-log-view-maps '(log-view-mode-map))
+
+(defun evil-collection-log-view-setup ()
+  "Set up `evil' bindings for `log-view'."
+  (evil-collection-define-key 'normal 'log-view-mode-map
+    "q" 'quit-window
+    (kbd "RET") 'log-view-toggle-entry-display
+    "m" 'log-view-toggle-mark-entry
+    "c" 'log-view-modify-change-comment
+    "d" 'log-view-diff
+    "=" 'log-view-diff
+    "D" 'log-view-diff-changeset
+    "a" 'log-view-annotate-version
+    "F" 'log-view-find-revision
+    "gj" 'log-view-msg-next
+    "gk" 'log-view-msg-prev
+    "]" 'log-view-msg-next
+    "[" 'log-view-msg-prev
+    (kbd "C-j") 'log-view-file-next
+    (kbd "C-k") 'log-view-file-prev))
+
+(provide 'evil-collection-log-view)
+;;; evil-collection-log-view.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-log-view.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-log-view.elc
new file mode 100644
index 0000000000..ab6913fa84
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-log-view.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-lsp-ui-imenu.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-lsp-ui-imenu.el
new file mode 100644
index 0000000000..623b960d11
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-lsp-ui-imenu.el
@@ -0,0 +1,46 @@
+;;; evil-collection-lsp-ui-imenu.el --- Bindings for `lsp-ui-imenu-mode'. -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 James Nguyen
+
+;; Author: Felix Dick <felix.dick@web.de>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, lsp-ui-imenu, convenience
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;; Bindings for `lsp-ui-imenu-mode'.
+
+;;; Code:
+(require 'lsp-ui nil t)
+(require 'evil-collection)
+
+(defconst evil-collection-lsp-ui-imenu-mode-maps '(lsp-ui-imenu-mode-map))
+
+(defun evil-collection-lsp-ui-imenu-setup ()
+  "Set up `evil' bindings for `lsp-ui-imenu'."
+  (evil-set-initial-state 'lsp-ui-imenu-mode 'normal)
+  (evil-collection-define-key 'normal 'lsp-ui-imenu-mode-map
+    (kbd "C-k") 'lsp-ui-imenu--prev-kind
+    (kbd "C-j") 'lsp-ui-imenu--next-kind
+    (kbd "q") 'lsp-ui-imenu--kill
+    (kbd "<return>") 'lsp-ui-imenu--view
+    (kbd "<M-return>") 'lsp-ui-imenu--visit))
+
+(provide 'evil-collection-lsp-ui-imenu)
+;;; evil-collection-lsp-ui-imenu.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-lsp-ui-imenu.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-lsp-ui-imenu.elc
new file mode 100644
index 0000000000..a8494ea9b8
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-lsp-ui-imenu.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-lua-mode.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-lua-mode.el
new file mode 100644
index 0000000000..dc79b9d386
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-lua-mode.el
@@ -0,0 +1,49 @@
+;;; evil-collection-lua-mode.el --- Bindings for `lua-mode'. -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 James Nguyen
+
+;; Author: James Nguyen <james@jojojames.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, emacs, tools
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;; Bindings for `lua-mode'.
+
+;;; Code:
+(require 'evil-collection)
+(require 'lua-mode nil t)
+
+(defvar lua-indent-level)
+(defconst evil-collection-lua-mode-maps '(lua-mode-map))
+
+(defun evil-collection-lua-mode-set-evil-shift-width ()
+  "Set `evil-shift-width' according to `lua-indent-level'."
+  (setq evil-shift-width lua-indent-level))
+
+(defun evil-collection-lua-mode-setup ()
+  "Set up `evil' bindings for `lua-mode'."
+  (add-hook 'lua-mode-hook #'evil-collection-lua-mode-set-evil-shift-width)
+
+  (evil-collection-define-key 'normal 'lua-mode-map
+    "K" 'lua-search-documentation
+    "gz" 'run-lua))
+
+(provide 'evil-collection-lua-mode)
+;;; evil-collection-lua-mode.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-lua-mode.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-lua-mode.elc
new file mode 100644
index 0000000000..5738a4d678
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-lua-mode.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-macrostep.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-macrostep.el
new file mode 100644
index 0000000000..9e15d83eb7
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-macrostep.el
@@ -0,0 +1,51 @@
+;;; evil-collection-macrostep.el --- Evil Integration for Macrostep -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 James Nguyen
+
+;; Author: James Nguyen <james@jojojames.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, macrostep, tools
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; Evil bindings for `macrostep-mode'.
+
+;;; Code:
+(require 'evil-collection)
+(require 'macrostep nil t)
+
+(defconst evil-collection-macrostep-maps '(macrostep-keymap))
+
+(defun evil-collection-macrostep-setup ()
+  "Set up `evil' bindings for `macrostep'."
+  ;; Keymaps don't seem to be populated on first try.
+  ;; Force `evil' to normalize keymaps.
+  (add-hook 'macrostep-mode-hook #'evil-normalize-keymaps)
+
+  (evil-collection-define-key 'normal 'macrostep-keymap
+    "q" 'macrostep-collapse-all
+    "e" 'macrostep-expand
+    "u" 'macrostep-collapse
+    "gj" 'macrostep-next-macro
+    "gk" 'macrostep-prev-macro
+    (kbd "C-j") 'macrostep-next-macro
+    (kbd "C-k") 'macrostep-prev-macro))
+
+(provide 'evil-collection-macrostep)
+;;; evil-collection-macrostep.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-macrostep.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-macrostep.elc
new file mode 100644
index 0000000000..38c1c2daf2
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-macrostep.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-magit-todos.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-magit-todos.el
new file mode 100644
index 0000000000..c6f2b950ed
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-magit-todos.el
@@ -0,0 +1,52 @@
+;;; evil-collection-magit-todos.el --- Bindings for `magit-todos' -*- lexical-binding: t -*-
+
+;; Copyright (C) 2018 James Nguyen
+
+;; Author: Fredrik Bergroth <fbergroth@gmail.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, emacs, tools
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; Bindings for `magit-todos'.
+
+;;; Code:
+(require 'evil-collection)
+(require 'magit-todos nil t)
+
+(defconst evil-collection-magit-todos-maps '(magit-todos-section-map
+                                             magit-status-mode-map))
+
+(defun evil-collection-magit-todos-setup-jump-key ()
+  "Add keybinding to jump to todos section."
+  (evil-collection-define-key 'normal 'magit-status-mode-map
+    "gT" (and (bound-and-true-p magit-todos-mode) 'magit-todos-jump-to-todos)))
+
+
+(defun evil-collection-magit-todos-setup ()
+  "Set up `evil' bindings for `magit-todos'."
+  ;; magit-todos binds jT which prevents evil users from stepping into the section
+  (evil-collection-define-key nil 'magit-todos-section-map
+    "j" nil)
+
+  (add-hook 'magit-todos-mode-hook 'evil-collection-magit-todos-setup-jump-key))
+
+
+(provide 'evil-collection-magit-todos)
+;;; evil-collection-magit-todos.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-magit-todos.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-magit-todos.elc
new file mode 100644
index 0000000000..2ab3e2cfdd
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-magit-todos.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-magit.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-magit.el
new file mode 100644
index 0000000000..ce1372696e
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-magit.el
@@ -0,0 +1,47 @@
+;;; evil-collection-magit.el --- Bindings for `magit' -*- lexical-binding: t -*-
+
+;; Copyright (C) 2018 James Nguyen
+
+;; Author: James Nguyen <james@jojojames.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, emacs, tools
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;; Bindings for `magit'
+;;; This file is to work around an issue described in
+;;; https://github.com/emacs-evil/evil-collection/issues/108
+;;; Ideally this file is only temporary and should be removed once
+;;; #108 is resolved.
+
+;;; Code:
+(require 'evil-collection)
+(require 'magit nil t)
+
+(defvar magit-blame-mode-map)
+
+(defconst evil-collection-magit-maps '(magit-blame-mode-map))
+
+(defun evil-collection-magit-setup ()
+  "Set up `evil' bindings for `magit'."
+  (evil-collection-define-key 'normal 'magit-blame-mode-map
+    "q" 'magit-blame-quit))
+
+(provide 'evil-collection-magit)
+;;; evil-collection-magit.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-magit.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-magit.elc
new file mode 100644
index 0000000000..818a6e281b
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-magit.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-man.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-man.el
new file mode 100644
index 0000000000..5fc9b311d6
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-man.el
@@ -0,0 +1,67 @@
+;;; evil-collection-man.el --- Evil bindings for Man-mode -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 Pierre Neidhardt
+
+;; Author: Pierre Neidhardt <ambrevar@gmail.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, man, tools
+
+;; This file 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, or (at your
+;; option) any later version.
+;;
+;; This file 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.
+;;
+;; For a full copy of the GNU General Public License
+;; see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; Evil bindings for `man'.
+
+;;; Code:
+(require 'evil-collection)
+(require 'man)
+
+(defconst evil-collection-man-maps '(Man-mode-map))
+
+(defun evil-collection-man-setup ()
+  "Set up `evil' bindings for `man'."
+  (evil-set-initial-state 'Man-mode 'normal)
+  (evil-collection-define-key 'normal 'Man-mode-map
+    ;; motion
+    (kbd "SPC") 'scroll-up-command
+    (kbd "S-SPC") 'scroll-down-command
+    (kbd "<tab>") 'forward-button
+    (kbd "<backtab>") 'backward-button
+
+    (kbd "]") 'Man-next-manpage
+    (kbd "[") 'Man-previous-manpage
+    (kbd "gj") 'Man-next-manpage
+    (kbd "gk") 'Man-previous-manpage
+    (kbd "C-j") 'Man-next-section
+    (kbd "C-k") 'Man-previous-section
+
+    ;; goto
+    "gm" 'man
+    "gd" 'Man-goto-section ; TODO: "gd" does not match the rationale of "go to definition". Change?
+    "gR" 'Man-follow-manual-reference ; TODO: Make this match Info-follow-reference?
+    "gs" 'Man-goto-see-also-section
+
+    ;; refresh
+    "gr" 'Man-update-manpage
+
+    ;; quit
+    "q" 'quit-window
+    "ZQ" 'quit-window
+    "ZZ" 'quit-window))
+
+(provide 'evil-collection-man)
+;;; evil-collection-man.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-man.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-man.elc
new file mode 100644
index 0000000000..ae7144ae54
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-man.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-minibuffer.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-minibuffer.el
new file mode 100644
index 0000000000..ed4c276402
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-minibuffer.el
@@ -0,0 +1,75 @@
+;;; evil-collection-minibuffer.el --- Evil bindings for the minibuffer -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 Pierre Neidhardt
+
+;; Author: Pierre Neidhardt <ambrevar@gmail.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, minibuffer, tools
+
+;; This file 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, or (at your
+;; option) any later version.
+;;
+;; This file 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.
+;;
+;; For a full copy of the GNU General Public License
+;; see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; Evil bindings for the minibuffer.
+
+;;; Code:
+(require 'evil-collection)
+
+(defconst evil-collection-minibuffer-maps '(minibuffer-local-map
+                                            minibuffer-local-ns-map
+                                            minibuffer-local-completion-map
+                                            minibuffer-local-must-match-map
+                                            minibuffer-local-isearch-map
+                                            evil-ex-completion-map))
+
+(defun evil-collection-minibuffer-insert ()
+  "Switch to insert state.
+
+This function is meant to be hooked in the minibuffer:
+
+  (add-hook 'minibuffer-setup-hook 'evil-collection-minibuffer-insert)
+
+`evil-set-initial-state' can not be used for the minibuffer since
+it does not have a mode."
+  (set (make-local-variable 'evil-echo-state) nil)
+  ;; (evil-set-initial-state 'mode 'insert) is the evil-proper
+  ;; way to do this, but the minibuffer doesn't have a mode.
+  ;; The alternative is to create a minibuffer mode (here), but
+  ;; then it may conflict with other packages' if they do the same.
+  (evil-insert 1))
+
+(defun evil-collection-minibuffer-setup ()
+  "Initialize minibuffer for `evil'."
+  ;; https://www.gnu.org/software/emacs/manual/html_node/elisp/Text-from-Minibuffer.html
+  (dolist (map '(minibuffer-local-map
+                 minibuffer-local-ns-map
+                 minibuffer-local-completion-map
+                 minibuffer-local-must-match-map
+                 minibuffer-local-isearch-map))
+    (evil-collection-define-key 'normal map (kbd "<escape>") 'abort-recursive-edit)
+    (evil-collection-define-key 'normal map (kbd "<return>") 'exit-minibuffer))
+
+  (add-hook 'minibuffer-setup-hook 'evil-collection-minibuffer-insert)
+  ;; Because of the above minibuffer-setup-hook, some evil-ex bindings need be reset.
+  (evil-collection-define-key 'normal 'evil-ex-completion-map (kbd "<escape>") 'abort-recursive-edit)
+  (evil-collection-define-key 'insert 'evil-ex-completion-map (kbd "C-p") 'previous-complete-history-element)
+  (evil-collection-define-key 'insert 'evil-ex-completion-map (kbd "C-n") 'next-complete-history-element)
+  (evil-collection-define-key 'normal 'evil-ex-completion-map (kbd "C-p") 'previous-history-element)
+  (evil-collection-define-key 'normal 'evil-ex-completion-map (kbd "C-n") 'next-history-element))
+
+(provide 'evil-collection-minibuffer)
+;;; evil-collection-minibuffer.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-minibuffer.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-minibuffer.elc
new file mode 100644
index 0000000000..83e2ebd10d
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-minibuffer.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-mu4e-conversation.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-mu4e-conversation.el
new file mode 100644
index 0000000000..fe592c7537
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-mu4e-conversation.el
@@ -0,0 +1,74 @@
+;;; evil-collection-mu4e-conversation.el --- Evil bindings for mu4e-conversation -*- lexical-binding: t -*-
+
+;; Copyright (C) 2018 Pierre Neidhardt <ambrevar@gmail.com>
+
+;; Author: Pierre Neidhardt <ambrevar@gmail.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "24.4") (evil "1.2.10"))
+;; Keywords: evil, mu4e, tools
+
+;; This file 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, or (at your
+;; option) any later version.
+;;
+;; This file 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.
+;;
+;; For a full copy of the GNU General Public License
+;; see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; Evil bindings for mu4e-conversation.
+
+;;; Code:
+
+(require 'evil-collection)
+(require 'mu4e-conversation nil t)
+
+(defconst evil-collection-mu4e-conversation-maps '(mu4e-conversation-map
+                                                   mu4e-conversation-thread-map))
+
+(defvar evil-collection-mu4e-conversation--local-map-p nil
+  "Non-nil if last position was on a local-map property.")
+
+(defun evil-collection-mu4e-conversation--switch ()
+  "Re-compute the bindings if point has moved between the thread
+  area and the composition area."
+  (let ((local-map-here (get-text-property (point) 'local-map)))
+    (when (or (and evil-collection-mu4e-conversation--local-map-p
+                   (not local-map-here))
+              (and (not evil-collection-mu4e-conversation--local-map-p)
+                   local-map-here))
+      (evil-normalize-keymaps))
+    (setq evil-collection-mu4e-conversation--local-map-p local-map-here)))
+
+(defun evil-collection-mu4e-conversation--update-local-map ()
+  (setq evil-collection-mu4e-conversation--local-map-p (get-text-property (point) 'local-map))
+  (evil-normalize-keymaps)
+  (add-hook 'post-command-hook 'evil-collection-mu4e-conversation--switch nil t))
+
+(defun evil-collection-mu4e-conversation-setup ()
+  "Set up `evil' bindings for `mu4e-conversation'."
+  ;; Evil does not update its current keymap state when it the point hits a
+  ;; local-map property is used.  See
+  ;; https://github.com/emacs-evil/evil/issues/301.  Thus we force the update
+  ;; with a technique similar to what `org~mu4e-mime-switch-headers-or-body'
+  ;; does.
+  (add-hook 'mu4e-conversation-hook 'evil-collection-mu4e-conversation--update-local-map)
+  (evil-collection-define-key 'normal 'mu4e-conversation-map
+    " " 'evil-scroll-page-down
+    (kbd "S-SPC") 'evil-scroll-page-up
+    "[" 'mu4e-conversation-previous-message
+    "]" 'mu4e-conversation-next-message
+    "zv" 'mu4e-conversation-toggle-view
+    "za" 'mu4e-conversation-toggle-hide-cited
+    "q" 'mu4e-conversation-quit))
+
+(provide 'evil-collection-mu4e-conversation)
+;;; evil-collection-mu4e-conversation.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-mu4e-conversation.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-mu4e-conversation.elc
new file mode 100644
index 0000000000..8b412772ae
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-mu4e-conversation.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-mu4e.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-mu4e.el
new file mode 100644
index 0000000000..e59ae0d27c
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-mu4e.el
@@ -0,0 +1,337 @@
+;;; evil-collection-mu4e.el --- Evil bindings for mu4e -*- lexical-binding: t -*-
+
+;; Copyright (C) 2015-2018 Joris Engbers
+;; Copyright (C) 2018 Pierre Neidhardt <ambrevar@gmail.com>
+
+;; Author: Joris Engbers <info@jorisengbers.nl>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.9
+;; Package-Requires: ((emacs "24.4") (evil "1.2.10"))
+;; Keywords: evil, mu4e, tools
+
+;; This file 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, or (at your
+;; option) any later version.
+;;
+;; This file 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.
+;;
+;; For a full copy of the GNU General Public License
+;; see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; Evil keybindings for mu4e that make sense for Evil users.  The following
+;; keybindings are defined:
+;;
+;; General commands:
+;; | Commmand                 | evil-mu4e | Alternative |
+;; |--------------------------+-----------+-------------|
+;; | Jump to maildir          | J         |             |
+;; | Update                   | u         |             |
+;; | Compose message          | cc        | C           |
+;; | Kill update mail process | x         |             |
+
+;; Commands for header-mode and view-mode:
+;; | Command                         | evil-mu4e | Alternative |
+;; |---------------------------------+-----------+-------------|
+;; | Next message                    | C-j       |             |
+;; | Previous message                | C-k       |             |
+;; | Mark the current thread as read | T         |             |
+;; | Compose message                 | cc        | C           |
+;; | Compose edit**                  | ce        | E           |
+;; | Compose forward**               | cf        | F           |
+;; | Compose reply                   | cr        | R           |
+;; | Change sorting***               | o         | O           |
+;; | Rerun search                    | gr        |             |
+;; | Toggle include related          | zr        |             |
+;; | Toggle threading                | zt        |             |
+;; | Toggle hide cited               | za        |             |
+;; | Skip duplicates                 | zd        |             |
+;; | Show log                        | gl        |             |
+;; | Select other view               | gv        |             |
+;; | Save attachement(s)             | p         | P           |
+;; | Save url                        | yu        |             |
+;; | Go to url                       | gx        |             |
+;; | Fetch url                       | gX        |             |
+;;
+;;  - * denotes only in header-mode
+;;  - ** denotes Alternative only in header-mode
+;;  - *** denotes Alternative only in view-mode
+;;
+;;; Code:
+
+(require 'evil-collection)
+(require 'mu4e nil t)
+
+(declare-function mu4e~main-action-str "mu4e-main")
+(declare-function mu4e~main-view-queue "mu4e-main")
+(defvar smtpmail-send-queued-mail)
+(defvar smtpmail-queue-dir)
+
+(defconst evil-collection-mu4e-maps '(mu4e-main-mode-map
+                                      mu4e-headers-mode-map
+                                      mu4e-view-mode-map
+                                      mu4e-compose-mode-map))
+
+
+
+(defun evil-collection-mu4e-set-state ()
+  "Set the appropriate initial state of all mu4e modes."
+  (dolist (mode '(mu4e-main-mode
+                  mu4e-headers-mode
+                  mu4e-view-mode
+                  mu4e-org-mode))
+    (evil-set-initial-state mode 'normal))
+  (evil-set-initial-state 'mu4e-compose-mode 'insert))
+
+
+
+;;; Define bindings
+
+;; TODO: Inhibit insert-state functions as per Evil Collection.
+(defvar evil-collection-mu4e-mode-map-bindings
+  `((mu4e-main-mode-map
+     "J" mu4e~headers-jump-to-maildir
+     "j" next-line
+     "k" previous-line
+     "u" mu4e-update-mail-and-index
+     "gr" revert-buffer
+     "b" mu4e-headers-search-bookmark
+     "B" mu4e-headers-search-bookmark-edit
+     "N" mu4e-news
+     ";" mu4e-context-switch
+     "H" mu4e-display-manual
+     "C" mu4e-compose-new
+     "cc" mu4e-compose-new
+     "x" mu4e-kill-update-mail
+     "A" mu4e-about
+     "f" smtpmail-send-queued-mail
+     "m" mu4e~main-toggle-mail-sending-mode
+     "s" mu4e-headers-search
+     "q" mu4e-quit)
+
+    (mu4e-headers-mode-map
+     "q" mu4e~headers-quit-buffer
+     "J" mu4e~headers-jump-to-maildir
+     "C" mu4e-compose-new
+     "E" mu4e-compose-edit
+     "F" mu4e-compose-forward
+     "R" mu4e-compose-reply
+     "cc" mu4e-compose-new
+     "ce" mu4e-compose-edit
+     "cf" mu4e-compose-forward
+     "cr" mu4e-compose-reply
+     "o" mu4e-headers-change-sorting
+     "j" mu4e-headers-next
+     "k" mu4e-headers-prev
+     "gr" mu4e-headers-rerun-search
+     "b" mu4e-headers-search-bookmark
+     "B" mu4e-headers-search-bookmark-edit
+     ";" mu4e-context-switch
+     ,(kbd "RET") mu4e-headers-view-message
+     "/" mu4e-headers-search-narrow
+     "s" mu4e-headers-search
+     "S" mu4e-headers-search-edit
+     "x" mu4e-mark-execute-all
+     "a" mu4e-headers-action
+     "*" mu4e-headers-mark-for-something ; TODO: Don't override evil-seach-word-forward?
+     "&" mu4e-headers-mark-custom
+     "A" mu4e-headers-mark-for-action
+     "m" mu4e-headers-mark-for-move
+     "r" mu4e-headers-mark-for-refile
+     "D" mu4e-headers-mark-for-delete
+     "d" mu4e-headers-mark-for-trash
+     "=" mu4e-headers-mark-for-untrash
+     "u" mu4e-headers-mark-for-unmark
+     "U" mu4e-mark-unmark-all
+     "?" mu4e-headers-mark-for-unread
+     "!" mu4e-headers-mark-for-read
+     "%" mu4e-headers-mark-pattern
+     "+" mu4e-headers-mark-for-flag
+     "-" mu4e-headers-mark-for-unflag
+     "[" mu4e-headers-prev-unread
+     "]" mu4e-headers-next-unread
+     "gk" mu4e-headers-prev-unread
+     "gj" mu4e-headers-next-unread
+     "\C-j" mu4e-headers-next
+     "\C-k" mu4e-headers-prev
+     "zr" mu4e-headers-toggle-include-related
+     "zt" mu4e-headers-toggle-threading
+     "zd" mu4e-headers-toggle-skip-duplicates
+     "gl" mu4e-show-log
+     "gv" mu4e-select-other-view
+     "T" (lambda ()
+           (interactive)
+           (mu4e-headers-mark-thread nil '(read))))
+
+    (mu4e-compose-mode-map
+     "gg" mu4e-compose-goto-top
+     "G" mu4e-compose-goto-bottom)
+
+    (mu4e-view-mode-map
+     " " mu4e-view-scroll-up-or-next
+     [tab] shr-next-link
+     [backtab] shr-previous-link
+     "q" mu4e~view-quit-buffer
+     "gx" mu4e-view-go-to-url
+     "gX" mu4e-view-fetch-url
+     "C" mu4e-compose-new
+     "H" mu4e-view-toggle-html
+     ;; "E"               mu4e-compose-edit
+     ;; "F"               mu4e-compose-forward
+     "R" mu4e-compose-reply
+     "cc" mu4e-compose-new
+     "ce" mu4e-compose-edit
+     "cf" mu4e-compose-forward
+     "cr" mu4e-compose-reply
+     "p" mu4e-view-save-attachment
+     "P" mu4e-view-save-attachment-multi ; Since mu4e 1.0, -multi is same as normal.
+     "O" mu4e-headers-change-sorting
+     "o" mu4e-view-open-attachment
+     "A" mu4e-view-attachment-action
+     "a" mu4e-view-action
+     "J" mu4e~headers-jump-to-maildir
+     "[" mu4e-view-headers-prev-unread
+     "]" mu4e-view-headers-next-unread
+     "gk" mu4e-view-headers-prev-unread
+     "gj" mu4e-view-headers-next-unread
+     "\C-j" mu4e-view-headers-next
+     "\C-k" mu4e-view-headers-prev
+     "x" mu4e-view-marked-execute
+     "&" mu4e-view-mark-custom
+     "*" mu4e-view-mark-for-something   ; TODO: Don't override "*".
+     "m" mu4e-view-mark-for-move
+     "r" mu4e-view-mark-for-refile
+     "D" mu4e-view-mark-for-delete
+     "d" mu4e-view-mark-for-trash
+     "=" mu4e-view-mark-for-untrash
+     "u" mu4e-view-unmark
+     "U" mu4e-view-unmark-all
+     "?" mu4e-view-mark-for-unread
+     "!" mu4e-view-mark-for-read
+     "%" mu4e-view-mark-pattern
+     "+" mu4e-view-mark-for-flag
+     "-" mu4e-view-mark-for-unflag
+     "zr" mu4e-headers-toggle-include-related
+     "zt" mu4e-headers-toggle-threading
+     "za" mu4e-view-toggle-hide-cited
+     "gl" mu4e-show-log
+     "s" mu4e-view-search-edit
+     "|" mu4e-view-pipe
+     "." mu4e-view-raw-message
+     ,(kbd "C--") mu4e-headers-split-view-shrink
+     ,(kbd "C-+") mu4e-headers-split-view-grow
+     "T" (lambda ()
+           (interactive)
+           (mu4e-headers-mark-thread nil '(read)))
+     ,@(when evil-want-C-u-scroll
+         '("\C-u" evil-scroll-up))))
+  ;; TODO: Add mu4e-headers-search-bookmark?
+  "All evil-mu4e bindings.")
+
+(defun evil-collection-mu4e-set-bindings ()
+  "Set the bindings."
+  ;; WARNING: With lexical binding, lambdas from `mapc' and `dolist' become
+  ;; closures in which we must use `evil-define-key*' instead of
+  ;; `evil-define-key'.
+  (dolist (binding evil-collection-mu4e-mode-map-bindings)
+    (apply #'evil-collection-define-key 'normal binding))
+  (evil-collection-define-key 'visual 'mu4e-compose-mode-map
+    "gg" 'mu4e-compose-goto-top
+    "G" 'mu4e-compose-goto-bottom)
+  (evil-collection-define-key 'operator 'mu4e-view-mode-map
+    "u" '(menu-item
+          ""
+          nil
+          :filter (lambda (&optional _)
+                    (when (memq evil-this-operator
+                                '(evil-yank evil-cp-yank evil-sp-yank lispyville-yank))
+                      (setq evil-inhibit-operator t)
+                      #'mu4e-view-save-url)))))
+
+
+;;; Update mu4e-main-view
+;;; To avoid confusion the main-view is updated to show the keys that are in use
+;;; for evil-mu4e.
+
+(defvar evil-collection-mu4e-begin-region-basic "\n  Basics"
+  "The place where to start overriding Basic section.")
+
+(defvar evil-collection-mu4e-end-region-basic "a new message\n"
+  "The place where to end overriding Basic section.")
+
+(defvar evil-collection-mu4e-new-region-basic
+  (concat (mu4e~main-action-str "\t* [J]ump to some maildir\n" 'mu4e-jump-to-maildir)
+          (mu4e~main-action-str "\t* enter a [s]earch query\n" 'mu4e-search)
+          (mu4e~main-action-str "\t* [C]ompose a new message\n" 'mu4e-compose-new))
+  "Define the evil-mu4e Basic region.")
+
+(defvar evil-collection-mu4e-begin-region-misc "\n  Misc"
+  "The place where to start overriding Misc section.")
+
+(defvar evil-collection-mu4e-end-region-misc "q]uit"
+  "The place where to end overriding Misc section.")
+
+(defvar evil-collection-mu4e-new-region-misc
+  (concat
+   (mu4e~main-action-str "\t* [;]Switch focus\n" 'mu4e-context-switch)
+   (mu4e~main-action-str "\t* [u]pdate email & database (Alternatively: gr)\n"
+                         'mu4e-update-mail-and-index)
+
+   ;; show the queue functions if `smtpmail-queue-dir' is defined
+   (if (file-directory-p smtpmail-queue-dir)
+       (mu4e~main-view-queue)
+     "")
+   "\n"
+
+   (mu4e~main-action-str "\t* [N]ews\n" 'mu4e-news)
+   (mu4e~main-action-str "\t* [A]bout mu4e\n" 'mu4e-about)
+   (mu4e~main-action-str "\t* [H]elp\n" 'mu4e-display-manual)
+   (mu4e~main-action-str "\t* [q]uit\n" 'mu4e-quit))
+  "Define the evil-mu4e Misc region.")
+
+(defun evil-collection-mu4e-replace-region (new-region start end)
+  "Replace region between START and END with NEW-REGION.
+START end END end are regular expressions."
+  ;; move to start of region
+  (goto-char (point-min))
+  (re-search-forward start)
+
+  ;; insert new headings
+  (insert "\n\n")
+  (insert new-region)
+  ;; Delete text until end of region.
+  (let ((start-point (point))
+        (end-point (re-search-forward end)))
+    (delete-region start-point end-point)))
+
+
+(defun evil-collection-mu4e-update-main-view ()
+  "Update 'Basic' and 'Misc' regions to reflect the new
+keybindings."
+  (evil-collection-mu4e-replace-region evil-collection-mu4e-new-region-basic
+                                       evil-collection-mu4e-begin-region-basic
+                                       evil-collection-mu4e-end-region-basic)
+  (evil-collection-mu4e-replace-region evil-collection-mu4e-new-region-misc
+                                       evil-collection-mu4e-begin-region-misc
+                                       evil-collection-mu4e-end-region-misc))
+
+
+
+;;; Initialize evil-collection-mu4e
+
+(defun evil-collection-mu4e-setup ()
+  "Initialize evil-mu4e if necessary.
+If mu4e-main-mode is in evil-state-motion-modes, initialization
+is already done earlier."
+    (evil-collection-mu4e-set-state)
+    (evil-collection-mu4e-set-bindings)
+    (add-hook 'mu4e-main-mode-hook 'evil-collection-mu4e-update-main-view))
+
+(provide 'evil-collection-mu4e)
+;;; evil-collection-mu4e.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-mu4e.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-mu4e.elc
new file mode 100644
index 0000000000..d7f00aaee5
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-mu4e.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-neotree.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-neotree.el
new file mode 100644
index 0000000000..6dc2ba9c15
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-neotree.el
@@ -0,0 +1,100 @@
+;;; evil-collection-neotree.el --- Evil bindings for neotree -*- lexical-binding: t; no-byte-compile: t; -*-
+
+;; Copyright (C) 2017 Pierre Neidhardt
+
+;; Author: Maximiliano Sandoval <msandova@protonmail.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, neotree, tools
+
+;; This file 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, or (at your
+;; option) any later version.
+;;
+;; This file 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.
+;;
+;; For a full copy of the GNU General Public License
+;; see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; Evil bindings for `neotree'
+
+;;; Code:
+
+(require 'evil-collection)
+(require 'neotree nil t)
+
+(declare-function neotree-make-executor "neotree.el")
+(defconst evil-collection-neotree-maps '(neotree-mode-map))
+
+(defun evil-collection-neotree-setup ()
+  "Set up `evil' bindings for `neotree'."
+
+  (evil-set-initial-state 'neotree-mode 'normal) ;; Neotree start in normal by default.
+
+  (evil-collection-define-key 'normal 'neotree-mode-map
+
+    (kbd "<return>") (neotree-make-executor
+                      :file-fn 'neo-open-file
+                      :dir-fn 'neo-open-dir)
+    (kbd "<tab>") (neotree-make-executor
+                   :dir-fn 'neo-open-dir)
+    "z" (neotree-make-executor
+         :dir-fn 'neo-open-dir)
+    "ZZ" 'quit-window
+    "gd" (neotree-make-executor
+          :dir-fn 'neo-open-dired)
+    "gD" (neotree-make-executor
+          :dir-fn 'neo-open-dired)
+    "go" (neotree-make-executor
+          :file-fn 'neo-open-file
+          :dir-fn 'neo-open-dir)
+    "gO" 'neotree-quick-look
+    "gr" 'neotree-refresh
+    "q" 'neotree-hide
+    "H" 'neotree-hidden-file-toggle
+    "gh" 'neotree-hidden-file-toggle
+    (kbd "C-k") 'neotree-select-up-node
+    "gk" 'neotree-select-up-node
+    "[" 'neotree-select-up-node
+    (kbd "C-j") 'neotree-select-down-node
+    "gj" 'neotree-select-down-node
+    "]" 'neotree-select-down-node
+    "gv" 'neotree-open-file-in-system-application
+    "c" 'neotree-create-node
+    "y" 'neotree-copy-node
+    "r" 'neotree-rename-node
+    "R" 'neotree-change-root
+    "d" 'neotree-delete-node
+    "J" 'neotree-dir
+    "+" 'neotree-stretch-toggle
+    "=" 'neotree-stretch-toggle
+    "ge" 'neotree-enter
+    "j" 'neotree-next-line
+    "k" 'neotree-previous-line
+
+    ;; Unchanged keybings.
+    "a" (neotree-make-executor
+         :file-fn 'neo-open-file-ace-window)
+    "|" (neotree-make-executor
+         :file-fn 'neo-open-file-vertical-split)
+    "-" (neotree-make-executor
+         :file-fn 'neo-open-file-horizontal-split)
+    "S" 'neotree-select-previous-sibling-node
+    "s" 'neotree-select-next-sibling-node
+    (kbd "C-c C-c") 'neotree-change-root
+    (kbd "C-x 1") 'neotree-empty-fn
+    (kbd "C-x 2") 'neotree-empty-fn
+    (kbd "C-x 3") 'neotree-empty-fn
+    (kbd "C-x C-f") 'find-file-other-window
+    (kbd "C-c C-f") 'find-file-other-window))
+
+(provide 'evil-collection-neotree)
+;;; evil-collection-neotree.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-notmuch.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-notmuch.el
new file mode 100644
index 0000000000..d12dc097e8
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-notmuch.el
@@ -0,0 +1,178 @@
+;;; evil-collection-notmuch.el --- Bindings for `notmuch'. -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 James Nguyen
+
+;; Author: James Nguyen <james@jojojames.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: emacs, tools, evil
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;; Bindings for `notmuch'.
+
+;;; Code:
+(require 'notmuch nil t)
+(require 'evil-collection)
+
+(declare-function notmuch-show-get-tags "notmuch-show")
+(declare-function notmuch-show-tag "notmuch-show")
+(declare-function notmuch-search-get-tags "notmuch")
+(declare-function notmuch-search-tag "notmuch")
+(declare-function notmuch-tree-tag "notmuch-tree")
+
+(declare-function notmuch-tree-close-message-pane-and "notmuch-tree")
+
+(defconst evil-collection-notmuch-maps '(notmuch-common-keymap
+                                         notmuch-hello-mode-map
+                                         notmuch-show-mode-map
+                                         notmuch-show-part-map
+                                         notmuch-tree-mode-map
+                                         notmuch-search-mode-map
+                                         notmuch-search-stash-map))
+
+(defun evil-collection-notmuch-show-toggle-delete ()
+  "Toggle deleted tag for message."
+  (interactive)
+  (if (member "deleted" (notmuch-show-get-tags))
+      (notmuch-show-tag (list "-deleted"))
+    (notmuch-show-tag (list "+deleted")))
+  (evil-next-line))
+
+(defun evil-collection-notmuch-search-toggle-delete ()
+  "Toggle deleted tag for message."
+  (interactive)
+  (if (member "deleted" (notmuch-search-get-tags))
+      (notmuch-search-tag (list "-deleted"))
+    (notmuch-search-tag (list "+deleted")))
+  (evil-next-line))
+
+(defun evil-collection-notmuch-tree-toggle-delete ()
+  "Toggle deleted tag for message."
+  (interactive)
+  (if (member "deleted" (notmuch-search-get-tags))
+      (notmuch-tree-tag (list "-deleted"))
+    (notmuch-tree-tag (list "+deleted")))
+  (evil-next-line))
+
+(defun evil-collection-notmuch-setup ()
+  "Set up `evil' bindings for `notmuch'."
+  (evil-set-initial-state 'notmuch-show-mode 'normal)
+  (evil-set-initial-state 'notmuch-search-mode 'normal)
+  (evil-set-initial-state 'notmuch-hello-mode 'normal)
+
+  (evil-collection-define-key 'normal 'notmuch-common-keymap
+    "g?" 'notmuch-help
+    "q" 'notmuch-bury-or-kill-this-buffer
+    "s" 'notmuch-search
+    "z" 'notmuch-tree
+    "c" 'notmuch-mua-new-mail
+    "gr" 'notmuch-refresh-this-buffer
+    "gR" 'notmuch-refresh-all-buffers
+    "Z" 'notmuch-poll-and-refresh-this-buffer
+    "J" 'notmuch-jump-search)
+
+  (evil-collection-define-key 'normal 'notmuch-hello-mode-map
+    "g?" 'notmuch-hello-versions
+    (kbd "TAB") 'widget-forward
+    (kbd "RET") 'widget-button-press
+    (kbd "S-TAB") 'widget-backward
+    (kbd "<C-tab>") 'widget-backward)
+
+  (evil-collection-define-key 'normal 'notmuch-show-mode-map
+    "gd" 'goto-address-at-point
+    "A" 'notmuch-show-archive-thread-then-next
+    "S" 'notmuch-show-filter-thread
+    "K" 'notmuch-tag-jump
+    "R" 'notmuch-show-reply
+    "X" 'notmuch-show-archive-thread-then-exit
+    "Z" 'notmuch-tree-from-show-current-query
+    "a" 'notmuch-show-archive-message-then-next-or-next-thread
+    "d" 'evil-collection-notmuch-show-toggle-delete
+    "H" 'notmuch-show-toggle-visibility-headers
+    "gj" 'notmuch-show-next-open-message
+    "gk" 'notmuch-show-previous-open-message
+    "]" 'notmuch-show-next-message
+    "[" 'notmuch-show-previous-message
+    (kbd "M-j") 'notmuch-show-next-thread-show
+    (kbd "M-k") 'notmuch-show-previous-thread-show
+    "r" 'notmuch-show-reply-sender
+    (kbd "x") 'notmuch-show-archive-message-then-next-or-exit
+    "|" 'notmuch-show-pipe-message
+    "*" 'notmuch-show-tag-all
+    "-" 'notmuch-show-remove-tag
+    "+" 'notmuch-show-add-tag
+    (kbd "TAB") 'notmuch-show-toggle-message
+    (kbd "RET") 'notmuch-show-toggle-message
+    "." 'notmuch-show-part-map)
+
+  (evil-collection-define-key 'normal 'notmuch-tree-mode-map
+    "g?" (notmuch-tree-close-message-pane-and 'notmuch-help)
+    "q" 'notmuch-tree-quit
+    "s" 'notmuch-tree-to-search
+    "c" (notmuch-tree-close-message-pane-and 'notmuch-mua-new-mail)
+    "J" (notmuch-tree-close-message-pane-and 'notmuch-jump-search)
+    "S" 'notmuch-search-from-tree-current-query
+    "r" (notmuch-tree-close-message-pane-and 'notmuch-show-reply-sender)
+    "R" (notmuch-tree-close-message-pane-and 'notmuch-show-reply)
+    "d" 'evil-collection-notmuch-tree-toggle-delete
+
+    "K" 'notmuch-tag-jump
+    (kbd "RET") 'notmuch-tree-show-message
+    [mouse-1] 'notmuch-tree-show-message
+    "A" 'notmuch-tree-archive-thread
+    "a" 'notmuch-tree-archive-message-then-next
+    "z" 'notmuch-tree-to-tree
+    "gj" 'notmuch-tree-next-matching-message
+    "gk" 'notmuch-tree-prev-matching-message
+    "]" 'notmuch-tree-next-message
+    "[" 'notmuch-tree-prev-message
+    (kbd "C-k") 'notmuch-tree-prev-thread
+    (kbd "C-j") 'notmuch-tree-next-thread
+    "-" 'notmuch-tree-remove-tag
+    "+" 'notmuch-tree-add-tag
+    "*" 'notmuch-tree-tag-thread
+    "e" 'notmuch-tree-resume-message)
+
+  (evil-collection-define-key 'normal 'notmuch-search-mode-map
+    "C" 'compose-mail-other-frame
+    "J" 'notmuch-jump-search
+    "S" 'notmuch-search-filter
+    "K" 'notmuch-tag-jump
+    "o" 'notmuch-search-toggle-order
+    "Z" 'notmuch-tree-from-search-current-query
+    "*" 'notmuch-search-tag-all
+    "a" 'notmuch-search-archive-thread
+    "c" 'compose-mail
+    "d" 'evil-collection-notmuch-search-toggle-delete
+    "q" 'notmuch-bury-or-kill-this-buffer
+    "r" 'notmuch-search-reply-to-thread-sender
+    "t" 'notmuch-search-filter-by-tag
+    "z" 'notmuch-search-stash-map
+    [mouse-1] 'notmuch-search-show-thread
+    "-" 'notmuch-search-remove-tag
+    "+" 'notmuch-search-add-tag
+    (kbd "RET") 'notmuch-search-show-thread)
+
+  (evil-collection-define-key 'normal 'notmuch-search-stash-map
+    "i" 'notmuch-search-stash-thread-id
+    "q" 'notmuch-stash-query
+    "g?" 'notmuch-subkeymap-help))
+
+(provide 'evil-collection-notmuch)
+;;; evil-collection-notmuch.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-notmuch.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-notmuch.elc
new file mode 100644
index 0000000000..32060974b4
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-notmuch.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-nov.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-nov.el
new file mode 100644
index 0000000000..b1bcb5a8eb
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-nov.el
@@ -0,0 +1,66 @@
+;;; evil-collection-nov.el --- Bindings for `nov'. -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 James Nguyen
+
+;; Author: James Nguyen <james@jojojames.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, emacs, tools, epub
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;; Bindings for`nov'.
+
+;;; Code:
+(require 'evil-collection)
+(require 'nov nil t)
+
+(defvar nov-mode-map)
+
+(defconst evil-collection-nov-maps '(nov-mode-map))
+
+(defun evil-collection-nov-setup ()
+  "Set up `evil' bindings for `nov'."
+  (evil-collection-define-key 'normal 'nov-mode-map
+    "gr" 'nov-render-document
+    "s" 'nov-view-source
+    "S" 'nov-view-content-source
+    "g?" 'nov-display-metadata
+    "gj" 'nov-next-document
+    (kbd "C-j") 'nov-next-document
+    (kbd "M-j") 'nov-next-document
+    "]" 'nov-next-document
+    "gk" 'nov-previous-document
+    (kbd "C-k") 'nov-previous-document
+    (kbd "M-k") 'nov-previous-document
+    "[" 'nov-previous-document
+
+    "t" 'nov-goto-toc
+    "i" 'nov-goto-toc
+    (kbd "RET") 'nov-browse-url
+    (kbd "<follow-link>") 'mouse-face
+    (kbd "<mouse-2>") 'nov-browse-url
+    (kbd "TAB") 'shr-next-link
+    (kbd "M-TAB") 'shr-previous-link
+    (kbd "<backtab>") 'shr-previous-link
+    (kbd "SPC") 'nov-scroll-up
+    (kbd "S-SPC") 'nov-scroll-down
+    (kbd "DEL") 'nov-scroll-down))
+
+(provide 'evil-collection-nov)
+;;; evil-collection-nov.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-nov.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-nov.elc
new file mode 100644
index 0000000000..fae6707b36
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-nov.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-occur.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-occur.el
new file mode 100644
index 0000000000..69285136e7
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-occur.el
@@ -0,0 +1,73 @@
+;;; evil-collection-occur.el --- Evil bindings for occur -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 James Nguyen
+
+;; Author: James Nguyen <james@jojojames.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, occur, tools
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; Evil bindings for `occur'.
+
+;;; Code:
+(require 'evil-collection)
+
+(when (> emacs-major-version 25)
+  (require 'replace))
+
+(defconst evil-collection-occur-maps '(occur-mode-map
+                                       occur-edit-mode-map))
+
+(defun evil-collection-occur-setup ()
+  "Set up `evil' bindings for `occur'."
+  (evil-set-initial-state 'occur-mode 'normal)
+
+  (evil-collection-define-key 'normal 'occur-mode-map
+    ;; Like `wdired-mode'.
+    (kbd "C-x C-q") 'occur-edit-mode
+
+    [mouse-2] 'occur-mode-mouse-goto
+    (kbd "C-c C-c") 'occur-mode-goto-occurrence
+
+    ;; open
+    (kbd "<return>") 'occur-mode-goto-occurrence
+    (kbd "S-<return>") 'occur-mode-goto-occurrence-other-window
+    (kbd "M-<return>") 'occur-mode-display-occurrence
+    "go" 'occur-mode-goto-occurrence-other-window
+
+    "gj" 'occur-next
+    "gk" 'occur-prev
+    (kbd "C-j") 'occur-next
+    (kbd "C-k") 'occur-prev
+    "r" 'occur-rename-buffer
+    "c" 'clone-buffer
+    (kbd "C-c C-f") 'next-error-follow-minor-mode)
+
+  (evil-collection-define-key 'normal 'occur-edit-mode-map
+    ;; Like `wdired-mode'.
+    (kbd "C-x C-q") 'occur-cease-edit
+
+    [mouse-2] 'occur-mode-mouse-goto
+    (kbd "C-c C-c") 'occur-cease-edit
+    (kbd "C-o") 'occur-mode-display-occurrence
+    (kbd "C-c C-f") 'next-error-follow-minor-mode))
+
+(provide 'evil-collection-occur)
+;;; evil-collection-occur.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-occur.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-occur.elc
new file mode 100644
index 0000000000..b228fe4080
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-occur.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-outline.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-outline.el
new file mode 100644
index 0000000000..558df856f6
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-outline.el
@@ -0,0 +1,97 @@
+;;; evil-collection-outline.el --- Evil bindings for outline-mode -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 Pierre Neidhardt
+
+;; Author: Pierre Neidhardt <ambrevar@gmail.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, outline, tools
+
+;; This file 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, or (at your
+;; option) any later version.
+;;
+;; This file 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.
+;;
+;; For a full copy of the GNU General Public License
+;; see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; Evil bindings for outline-mode.
+
+;;; Code:
+(require 'evil-collection)
+(require 'outline)
+
+(defcustom evil-collection-outline-bind-tab-p t
+  "Enable <tab>-based bindings in Outline mode.
+
+Unless you have Evil bindings set up for Org mode, Org will
+inherit the <tab>-based bindings from Outline.  Set this option
+to nil if you want to preserve the Emacs-state <tab> keys in Org
+mode."
+  :group 'evil-collection-outline
+  :type 'boolean)
+
+(defconst evil-collection-outline-maps '(outline-mode-map))
+
+(defun evil-collection-outline-setup ()
+  "Set up `evil' bindings for `outline'."
+  (evil-set-initial-state 'outline-mode 'normal)
+  (when evil-collection-outline-bind-tab-p
+    (evil-collection-define-key 'normal 'outline-mode-map
+      (kbd "<backtab>") 'outline-show-all ; Also "z r" by default
+      (kbd "<tab>") 'outline-toggle-children)) ; Also "z a" by default
+  (evil-collection-define-key 'normal 'outline-mode-map
+    ;; folding
+    ;; Evil default keys:
+    ;; zO: Show recursively for current branch only.
+    ;; za: Toggle first level like outline-toggle-children.
+    ;; zc: Hide complete subtree.
+    ;; zm: Show only root notes.
+    ;; zo: Show current node like "za".
+    ;; zr: Show everything.
+    ;; "ze" 'outline-hide-entry
+    ;; "zE" 'outline-show-entry
+    ;; "zl" 'outline-hide-leaves
+    ;; "zb" 'outline-show-branches
+    ;; "zo" 'outline-hide-other
+    "zB" 'outline-hide-body ; Hide all bodies, Emacs has "C-c C-t".
+    "zb" 'outline-hide-entry ; Hide current body, Emacs has "C-c C-c".
+    "ze" 'outline-show-entry ; Show current body only, not subtree, reverse of outline-hide-entry, Emacs has "C-c C-e".
+    "zl" 'outline-hide-leaves ; Like `outline-hide-body' but for current subtree only, Emacs has "C-c C-l".
+    "zK" 'outline-show-branches ; Show all children recursively but no body.  Emacs has "C-c C-k".
+    "zk" 'outline-show-children ; Direct children only unlike `outline-show-branches', and no content unlike `outline-show-entry' and `outline-toggle-children'.  Emacs has "C-c TAB".
+
+    "zp" 'outline-hide-other ; Hide all nodes and bodies except current body.  Emacs has "C-c C-o".
+    ;; outline-hide-sublevels ; q ; Is it any different from `outline-hide-body'?
+    ;; outline-hide-subtree ; Emacs has "C-c C-d", Evil has default "zc".
+    ;; outline-show-subtree ; Emacs has "C-c C-s", Evil has default "zO".
+
+    ;; TODO: To mark subtree ("C-c @"), we would need to define a tree object.
+
+    ;; motion
+    "[" 'outline-previous-visible-heading
+    "]" 'outline-next-visible-heading
+    (kbd "C-k") 'outline-backward-same-level
+    (kbd "C-j") 'outline-forward-same-level
+    "gk" 'outline-backward-same-level
+    "gj" 'outline-forward-same-level
+    "^" 'outline-up-heading
+
+    (kbd "M-h") 'outline-promote ; Org-mode has "M-<left>", Evil-org has "M-h"
+    (kbd "M-j") 'outline-move-subtree-down ; Org-mode has "M-<down>", Evil-org has "M-j"
+    (kbd "M-k") 'outline-move-subtree-up ; Org-mode has "M-<up>", Evil-org has "M-k"
+    (kbd "M-l") 'outline-demote ; Org-mode has "M-<right>", Evil-org has "M-l"
+
+    (kbd "M-<return>") 'outline-insert-heading)) ; Org-mode has "M-<return>"
+
+(provide 'evil-collection-outline)
+;;; evil-collection-outline.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-outline.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-outline.elc
new file mode 100644
index 0000000000..eea2711a19
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-outline.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-p4.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-p4.el
new file mode 100644
index 0000000000..2117ce7e68
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-p4.el
@@ -0,0 +1,57 @@
+;;; evil-collection-p4.el --- Evil bindings for P4 -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 James Nguyen
+
+;; Author: James Nguyen <james@jojojames.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, p4, tools
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; Evil bindings for P4.
+
+;;; Code:
+(require 'p4 nil t)
+(require 'evil-collection)
+
+(defvar p4-basic-mode-map)
+
+(defconst evil-collection-p4-maps '(p4-basic-mode-map))
+
+(defun evil-collection-p4-setup ()
+  "Set up `evil' bindings for `p4'."
+  (evil-set-initial-state 'p4-basic-mode 'normal)
+
+  (evil-collection-define-key 'normal 'p4-basic-mode-map
+    [mouse-1] 'p4-buffer-mouse-clicked
+    "k" 'p4-scroll-down-1-line
+    "j" 'p4-scroll-up-1-line
+    (kbd "C-j") 'p4-forward-active-link
+    (kbd "C-k") 'p4-backward-active-link
+    (kbd "<return>") 'p4-buffer-commands
+    "q" 'quit-window
+    "gr" 'revert-buffer
+    "]" 'p4-scroll-down-1-window
+    "[" 'p4-scroll-up-1-window
+    "gg" 'p4-top-of-buffer
+    "G" 'p4-bottom-of-buffer
+    "=" 'delete-other-windows))
+
+(provide 'evil-collection-p4)
+;;; evil-collection-p4.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-p4.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-p4.elc
new file mode 100644
index 0000000000..dc17038d12
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-p4.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-package-menu.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-package-menu.el
new file mode 100644
index 0000000000..9a6aeee707
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-package-menu.el
@@ -0,0 +1,55 @@
+;;; evil-collection-package-menu.el --- Evil bindings for package-menu -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 James Nguyen
+
+;; Author: James Nguyen <james@jojojames.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, package-menu, tools
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; Evil integration for `package-menu-mode'.
+
+;;; Code:
+(require 'evil-collection)
+(require 'package)
+
+(defconst evil-collection-package-menu-maps '(package-menu-mode-map))
+
+(defun evil-collection-package-menu-setup ()
+  "Set up `evil' bindings for `package-menu'."
+  (evil-set-initial-state 'package-menu-mode 'normal)
+
+  (evil-collection-define-key 'normal 'package-menu-mode-map
+    "i" 'package-menu-mark-install
+    "U" 'package-menu-mark-upgrades
+    "d" 'package-menu-mark-delete
+
+    ;; undo
+    "u" 'package-menu-mark-unmark
+
+    ;; execute
+    "x" 'package-menu-execute
+
+    "q" 'quit-window ;; FIXME: Can macros make sense here?
+    "ZQ" 'evil-quit
+    "ZZ" 'quit-window))
+
+(provide 'evil-collection-package-menu)
+;;; evil-collection-package-menu.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-package-menu.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-package-menu.elc
new file mode 100644
index 0000000000..a157fad479
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-package-menu.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-paren.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-paren.el
new file mode 100644
index 0000000000..4cfe3ce36e
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-paren.el
@@ -0,0 +1,76 @@
+;;; evil-collection-paren.el --- Bindings for `paren'. -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 James Nguyen
+
+;; Author: James Nguyen <james@jojojames.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, emacs, tools
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;; Bindings for `paren'.
+
+;;; Code:
+(require 'paren)
+(require 'evil-collection)
+
+(defun evil-collection-paren-show-paren-function (f &rest args)
+  "Integrate `show-paren-function' with `evil'."
+  (if (not (bound-and-true-p evil-mode))
+      (apply f args)
+    (if (if (memq 'not evil-highlight-closing-paren-at-point-states)
+            (memq evil-state evil-highlight-closing-paren-at-point-states)
+          (not (memq evil-state evil-highlight-closing-paren-at-point-states)))
+        (apply f args)
+      (let ((pos (point)) syntax narrow)
+        (setq pos
+              (catch 'end
+                (dotimes (var (1+ (* 2 evil-show-paren-range)))
+                  (if (zerop (mod var 2))
+                      (setq pos (+ pos var))
+                    (setq pos (- pos var)))
+                  (setq syntax (syntax-class (syntax-after pos)))
+                  (cond
+                   ((eq syntax 4)
+                    (setq narrow pos)
+                    (throw 'end pos))
+                   ((eq syntax 5)
+                    (throw 'end (1+ pos)))))))
+        (if pos
+            (save-excursion
+              (goto-char pos)
+              (save-restriction
+                (when narrow
+                  (narrow-to-region narrow (point-max)))
+                (apply f args)))
+          ;; prevent the preceding pair from being highlighted
+          (dolist (ov '(show-paren--overlay
+                        show-paren--overlay-1
+                        show-paren-overlay
+                        show-paren-overlay-1))
+            (let ((ov (and (boundp ov) (symbol-value ov))))
+              (when (overlayp ov) (delete-overlay ov)))))))))
+
+(defun evil-collection-paren-setup ()
+  "Set up `evil' bindings for `paren'."
+  (advice-add 'show-paren-function
+              :around 'evil-collection-paren-show-paren-function))
+
+(provide 'evil-collection-paren)
+;;; evil-collection-paren.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-paren.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-paren.elc
new file mode 100644
index 0000000000..ac8924ef09
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-paren.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-pass.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-pass.el
new file mode 100644
index 0000000000..39ae655366
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-pass.el
@@ -0,0 +1,59 @@
+;;; evil-collection-pass.el --- Evil bindings for pass-mode -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 James Nguyen
+
+;; Author: James Nguyen <james@jojojames.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, pass, tools
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; Evil bindings for `pass-mode'.
+
+;;; Code:
+(require 'evil-collection)
+(require 'pass nil t)
+
+(defvar pass-mode-map)
+
+(defconst evil-collection-pass-maps '(pass-mode-map))
+
+(defun evil-collection-pass-setup ()
+  "Set up `evil' bindings for `pass-mode'."
+  (evil-collection-define-key 'normal 'pass-mode-map
+    "gj" 'pass-next-entry
+    "gk" 'pass-prev-entry
+    (kbd "C-j") 'pass-next-entry
+    (kbd "C-k") 'pass-prev-entry
+    (kbd "]") 'pass-next-directory
+    (kbd "[") 'pass-prev-directory
+    "x" 'pass-kill
+    "s" 'isearch-forward
+    "g?" 'describe-mode
+    "gr" 'pass-update-buffer
+    "i" 'pass-insert
+    "I" 'pass-insert-generated
+    "Y" 'pass-copy
+    "r" 'pass-rename
+    "o" 'pass-otp-options
+    (kbd "<return>") 'pass-view
+    "q" 'pass-quit))
+
+(provide 'evil-collection-pass)
+;;; evil-collection-pass.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-pass.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-pass.elc
new file mode 100644
index 0000000000..50ebecdde3
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-pass.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-pdf.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-pdf.el
new file mode 100644
index 0000000000..a2927c353c
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-pdf.el
@@ -0,0 +1,281 @@
+;;; evil-collection-pdf.el --- Evil bindings for pdf-tools  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 Pierre Neidhardt
+
+;; Author: Pierre Neidhardt <ambrevar@gmail.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, pdf, tools
+
+;; This file 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, or (at your
+;; option) any later version.
+;;
+;; This file 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.
+;;
+;; For a full copy of the GNU General Public License
+;; see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; Evil bindings for pdf-tools.
+
+;;; Code:
+(require 'evil-collection)
+(require 'pdf-tools nil t)
+(require 'pdf-view nil t)
+
+(defconst evil-collection-pdf-maps '(pdf-view-mode-map
+                                     pdf-outline-buffer-mode-map
+                                     pdf-occur-buffer-mode-map))
+
+(declare-function pdf-view-last-page "pdf-view")
+(declare-function pdf-view-first-page "pdf-view")
+(declare-function pdf-view-goto-page "pdf-view")
+(declare-function pdf-view-previous-line-or-previous-page "pdf-view")
+(declare-function pdf-view-next-line-or-next-page "pdf-view")
+
+(defvar pdf-view-mode-map)
+(defvar pdf-outline-buffer-mode-map)
+(defvar pdf-occur-buffer-mode-map)
+
+(defvar pdf-view-mode-map)
+(defvar pdf-outline-buffer-mode-map)
+(defvar pdf-occur-buffer-mode-map)
+
+;; TODO: The following 2 functions are workarounds for
+;; 'pdf-view-next-line-or-next-page' and
+;; 'pdf-view-previous-line-or-previous-page' not playing well with
+;; EVIL. The root cause should be found and fixed instead.
+;; See https://github.com/emacs-evil/evil-collection/pull/137 for
+;; details.
+(defun evil-collection-pdf-view-next-line-or-next-page (&optional count)
+  "'evil' wrapper include a count argument to `pdf-view-next-line-or-next-page'"
+  (interactive "P")
+  (if count
+      (dotimes (_ count nil)
+	(pdf-view-next-line-or-next-page 1))
+    (pdf-view-next-line-or-next-page 1)))
+
+(defun evil-collection-pdf-view-previous-line-or-previous-page (&optional count)
+  "'evil' wrapper include a count argument to `pdf-view-previous-line-or-previous-page'"
+  (interactive "P")
+  (if count
+      (dotimes (_ count nil)
+	(pdf-view-previous-line-or-previous-page 1))
+    (pdf-view-previous-line-or-previous-page 1)))
+
+(defun evil-collection-pdf-view-goto-page (&optional page)
+  "`evil' wrapper around `pdf-view-last-page'."
+  (interactive "P")
+  (if page
+      (pdf-view-goto-page page)
+    (pdf-view-last-page)
+    (image-eob)))
+
+(defun evil-collection-pdf-view-goto-first-page (&optional page)
+  "`evil' wrapper around `pdf-view-first-page'."
+  (interactive "P")
+  (if page
+      (pdf-view-goto-page page)
+    (pdf-view-first-page)
+    (image-bob)))
+
+(defun evil-collection-pdf-setup ()
+  "Set up `evil' bindings for `pdf-view'."
+  (evil-collection-inhibit-insert-state 'pdf-view-mode-map)
+  (evil-set-initial-state 'pdf-view-mode 'normal)
+  (evil-collection-define-key 'normal 'pdf-view-mode-map
+    ;; motion
+    (kbd "<return>") 'image-next-line
+    "j" 'evil-collection-pdf-view-next-line-or-next-page
+    "k" 'evil-collection-pdf-view-previous-line-or-previous-page
+    (kbd "SPC") 'pdf-view-scroll-up-or-next-page
+    (kbd "S-SPC") 'pdf-view-scroll-down-or-previous-page
+    (kbd "<delete>") 'pdf-view-scroll-down-or-previous-page
+    (kbd "C-f") 'pdf-view-scroll-up-or-next-page
+    (kbd "C-b") 'pdf-view-scroll-down-or-previous-page
+    "]" 'pdf-view-next-page-command
+    "[" 'pdf-view-previous-page-command
+    (kbd "C-j") 'pdf-view-next-page-command
+    (kbd "C-k") 'pdf-view-previous-page-command
+    "gj" 'pdf-view-next-page-command
+    "gk" 'pdf-view-previous-page-command
+    (kbd "<next>") 'forward-page
+    (kbd "<prior>") 'backward-page
+    (kbd "<down>") 'evil-collection-pdf-view-next-line-or-next-page
+    (kbd "<up>") 'evil-collection-pdf-view-previous-line-or-previous-page
+    "gg" 'evil-collection-pdf-view-goto-first-page
+    "G" 'evil-collection-pdf-view-goto-page
+
+    ;; mark
+    "'" 'pdf-view-jump-to-register
+    "m" 'pdf-view-position-to-register
+
+    ;; zoom
+    "+" 'pdf-view-enlarge
+    "zi" 'pdf-view-enlarge
+    "=" 'pdf-view-enlarge
+    "-" 'pdf-view-shrink
+    "zo" 'pdf-view-shrink		      
+    "0" 'pdf-view-scale-reset
+    "z0" 'pdf-view-scale-reset
+
+    ;; TODO: Why are those image-* bindings in pdf-tools?
+    "a+" 'image-increase-speed
+    "a-" 'image-decrease-speed
+    "a0" 'image-reset-speed
+    "ar" 'image-reverse-speed
+    "F" 'image-goto-frame
+    "b" 'image-previous-frame
+    "f" 'image-next-frame
+    "h" 'image-backward-hscroll
+    "^" 'image-bol
+    "$" 'image-eol
+    "l" 'image-forward-hscroll
+
+    "H" 'pdf-view-fit-height-to-window ; evil-image has "H"
+    "P" 'pdf-view-fit-page-to-window
+    "W" 'pdf-view-fit-width-to-window ; evil-image has "W"
+
+    ;; refresh
+    "gr" 'revert-buffer
+
+    (kbd "<C-down-mouse-1>") 'pdf-view-mouse-extend-region
+    (kbd "<M-down-mouse-1>") 'pdf-view-mouse-set-region-rectangle
+    (kbd "<down-mouse-1>")  'pdf-view-mouse-set-region
+
+    (kbd "C-c C-c") 'docview-mode
+    (kbd "C-c <tab>") 'pdf-view-extract-region-image
+
+    "sb" 'pdf-view-set-slice-from-bounding-box
+    "sm" 'pdf-view-set-slice-using-mouse
+    "sr" 'pdf-view-reset-slice
+
+    ;; goto
+    "gl" 'pdf-view-goto-label
+
+    "y" 'pdf-view-kill-ring-save
+
+    ;; search
+    (kbd "M-s o") 'pdf-occur ; TODO: More Evil bindings?
+
+    "/" 'isearch-forward
+    "?" 'isearch-backward
+    "n" 'isearch-repeat-forward
+    "N" 'isearch-repeat-backward
+
+    "zd" 'pdf-view-dark-minor-mode
+    "zm" 'pdf-view-midnight-minor-mode
+    "zp" 'pdf-view-printer-minor-mode
+
+    "o" 'pdf-outline
+
+    ;; quit
+    "q" 'quit-window
+    "Q" 'kill-this-buffer
+    "ZQ" 'kill-this-buffer
+    "ZZ" 'quit-window)
+
+  (evil-collection-inhibit-insert-state 'pdf-outline-buffer-mode-map)
+  (evil-set-initial-state 'pdf-outline-buffer-mode 'normal)
+  (evil-collection-define-key 'normal 'pdf-outline-buffer-mode-map
+    ;; open
+    (kbd "<return>") 'pdf-outline-follow-link-and-quit
+    (kbd "S-<return>") 'pdf-outline-follow-link
+    (kbd "M-<return>") 'pdf-outline-display-link
+    "go" 'pdf-outline-follow-link
+    "." 'pdf-outline-move-to-current-page
+    (kbd "SPC") 'pdf-outline-select-pdf-window
+
+    "G" 'pdf-outline-end-of-buffer
+    "^" 'pdf-outline-up-heading
+    "<" 'pdf-outline-up-heading ; TODO: Don't set this by default?
+
+    "zf" 'pdf-outline-follow-mode ; Helm has "C-c C-f" in Emacs state.
+
+    ;; quit
+    (kbd "C-w q") 'pdf-outline-quit-and-kill ; TODO: Do we need to set this? I think not.
+    "q" 'quit-window
+    "ZQ" 'quit-window
+    "ZZ" 'pdf-outline-quit-and-kill)
+
+  (evil-collection-inhibit-insert-state 'pdf-occur-buffer-mode-map)
+  (evil-set-initial-state 'pdf-occur-buffer-mode 'normal)
+  (evil-collection-define-key 'normal 'pdf-occur-buffer-mode-map
+    ;; open
+    (kbd "<return>") 'pdf-occur-goto-occurrence
+    (kbd "S-<return>") 'pdf-occur-view-occurrence
+    (kbd "SPC") 'pdf-occur-view-occurrence
+    "gd" 'pdf-occur-goto-occurrence
+    "gD" 'pdf-occur-view-occurrence
+
+    "A" 'pdf-occur-tablist-gather-documents
+    "D" 'pdf-occur-tablist-do-delete
+
+    ;; sort
+    "o" 'tabulated-list-sort
+    "O" 'tablist-sort ; TODO: Do we need this?
+
+    ;; refresh
+    "G" 'tablist-revert
+
+    "K" 'pdf-occur-abort-search
+
+    ;; mark
+    "*m" 'tablist-mark-forward
+    "m" 'tablist-mark-forward
+    "~" 'tablist-toggle-marks
+    "u" 'tablist-unmark-forward
+    "U" 'tablist-unmark-all-marks
+    "*!" 'tablist-unmark-all-marks
+    "*c" 'tablist-change-marks
+    "*n" 'tablist-mark-items-numeric
+    "*r" 'tablist-mark-items-regexp
+    "%"  'tablist-mark-items-regexp
+
+    "a" 'tablist-flag-forward
+
+    ;; "f" 'tablist-find-entry ; TODO: Equivalent to 'pdf-occur-goto-occurrence?
+    "r" 'pdf-occur-revert-buffer-with-args
+    "d" 'tablist-do-kill-lines
+    "x" 'pdf-occur-tablist-do-flagged-delete
+    (kbd "<delete>") 'tablist-unmark-backward
+    (kbd "S-SPC") 'scroll-down-command
+    (kbd "<backtab>") 'tablist-backward-column
+    (kbd "C-c C-e") 'tablist-export-csv
+
+    [remap evil-first-non-blank] 'tablist-move-to-major-columnj
+    [remap evil-next-line] 'tablist-next-line
+    [remap evil-previous-line] 'tablist-previous-line
+
+    ;; filter
+    ;; TODO: See if overriding "/" is a good idea.
+    "/!" 'tablist-negate-filter
+    "//" 'tablist-display-filter
+    "/=" 'tablist-push-equal-filter
+    "/C" 'tablist-clear-filter
+    "/D" 'tablist-delete-named-filter
+    "/a" 'tablist-push-named-filter
+    "/d" 'tablist-deconstruct-named-filter
+    "/e" 'tablist-edit-filter
+    "/n" 'tablist-push-numeric-filter
+    "/p" 'tablist-pop-filter
+    "/r" 'tablist-push-regexp-filter
+    "/s" 'tablist-name-current-filter
+    "/t" 'tablist-toggle-first-filter-logic
+    "/z" 'tablist-suspend-filter
+
+    ;; quit
+    "q" 'tablist-quit
+    "ZQ" 'tablist-quit
+    "ZZ" 'tablist-quit))
+
+(provide 'evil-collection-pdf)
+;;; evil-collection-pdf.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-pdf.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-pdf.elc
new file mode 100644
index 0000000000..1f22897d9b
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-pdf.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-pkg.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-pkg.el
new file mode 100644
index 0000000000..2482877cda
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-pkg.el
@@ -0,0 +1,10 @@
+(define-package "evil-collection" "20180720.526" "A set of keybindings for Evil mode"
+  '((emacs "25.1")
+    (cl-lib "0.5")
+    (evil "1.2.13"))
+  :keywords
+  '("evil" "tools")
+  :url "https://github.com/emacs-evil/evil-collection")
+;; Local Variables:
+;; no-byte-compile: t
+;; End:
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-popup.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-popup.el
new file mode 100644
index 0000000000..9c1ebfb35f
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-popup.el
@@ -0,0 +1,43 @@
+;;; evil-collection-popup.el --- Bindings for `popup'. -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 James Nguyen
+
+;; Author: James Nguyen <james@jojojames.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, emacs, tools
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; Bindings for `popup'.
+
+;;; Code:
+(require 'evil-collection)
+(require 'popup nil t)
+
+(defconst evil-collection-popup-maps '(popup-menu-keymap))
+
+(defun evil-collection-popup-setup ()
+  "Set up `evil' bindings for `popup'."
+  (defvar popup-menu-keymap)
+  (evil-collection-define-key nil 'popup-menu-keymap
+    (kbd "C-j") 'popup-next
+    (kbd "C-k") 'popup-previous))
+
+(provide 'evil-collection-popup)
+;;; evil-collection-popup.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-popup.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-popup.elc
new file mode 100644
index 0000000000..efb4073312
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-popup.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-proced.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-proced.el
new file mode 100644
index 0000000000..3cdfc5b152
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-proced.el
@@ -0,0 +1,92 @@
+;;; evil-collection-proced.el --- Evil bindings for proced -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 Pierre Neidhardt
+
+;; Author: Pierre Neidhardt <ambrevar@gmail.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, proced, tools
+
+;; This file 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, or (at your
+;; option) any later version.
+;;
+;; This file 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.
+;;
+;; For a full copy of the GNU General Public License
+;; see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; Evil bindings for proced.
+
+;;; Code:
+(require 'evil-collection)
+(require 'proced)
+
+(defconst evil-collection-proced-maps '(proced-mode-map))
+
+(defun evil-collection-proced-setup ()
+  "Set up `evil' bindings for `proced'."
+  (evil-collection-inhibit-insert-state 'proced-mode-map)
+  (evil-set-initial-state 'proced-mode 'normal)
+  (evil-collection-define-key 'normal 'proced-mode-map
+    (kbd "<return>") 'proced-refine
+
+    ;; mark
+    ;; TODO: Implement a proced-toggle-mark?
+    "m" 'proced-mark ; Mentioned in documentation, should be followed.
+    "*" 'proced-mark-all
+    "M" 'proced-mark-all
+    "U" 'proced-unmark-all
+    "~" 'proced-toggle-marks
+    "c" 'proced-mark-children
+    "C" 'proced-mark-children           ; Emacs has "C"
+    "p" 'proced-mark-parents
+    "P" 'proced-mark-parents            ; Emacs has "P"
+    (kbd "<delete>") 'proced-unmark-backward
+
+    ;; motion
+    ;; TODO: Implement beginning-of-buffer / end-of-buffer.
+    (kbd "SPC") 'evil-scroll-down
+    (kbd "S-SPC") 'evil-scroll-up
+
+    "zt" 'proced-toggle-tree
+
+    "u" 'proced-undo
+
+    "O" 'proced-omit-processes         ; TODO: Change default binding?
+
+    "x" 'proced-send-signal ; Emacs has "k" and "x", "k" is mentioned in documentation
+
+    ;; filter
+    "s" 'proced-filter-interactive ; Refers to "[s]elect", Emacs has "f" mentioned in documentation.
+    "S" 'proced-format-interactive
+
+    ;; sort
+    "oo" 'proced-sort-start ; Refers to "[o]rder", Emacs has "s" mentioned in documentation.
+    "oO" 'proced-sort-interactive
+    "oc" 'proced-sort-pcpu
+    "om" 'proced-sort-pmem
+    "op" 'proced-sort-pid
+    "ot" 'proced-sort-time
+    "ou" 'proced-sort-user
+
+    "r" 'proced-renice
+
+    ;; refresh
+    "gr" 'revert-buffer
+
+    ;; quit
+    "q" 'quit-window                    ; TODO: Macro support?
+    "ZQ" 'evil-quit
+    "ZZ" 'quit-window))
+
+(provide 'evil-collection-proced)
+;;; evil-collection-proced.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-proced.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-proced.elc
new file mode 100644
index 0000000000..eb33461130
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-proced.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-prodigy.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-prodigy.el
new file mode 100644
index 0000000000..91654346cb
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-prodigy.el
@@ -0,0 +1,79 @@
+;;; evil-collection-prodigy.el --- Evil bindings for prodigy -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 James Nguyen
+
+;; Author: James Nguyen <james@jojojames.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, prodigy, tools
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; Evil bindings for `prodigy'.
+
+;;; Code:
+(require 'evil-collection)
+(require 'prodigy nil t)
+
+(defconst evil-collection-prodigy-maps '(prodigy-mode-map
+                                         prodigy-view-mode-map))
+
+(defun evil-collection-prodigy-setup ()
+  "Set up `evil' bindings for `prodigy'."
+  (evil-collection-define-key 'normal 'prodigy-mode-map
+    ;; quit
+    "q" 'quit-window
+
+    "j" 'prodigy-next
+    "k" 'prodigy-prev
+    "gg" 'prodigy-first
+    "G" 'prodigy-last
+
+    ;; mark
+    "m" 'prodigy-mark
+    "*t" 'prodigy-mark-tag
+    "M" 'prodigy-mark-all
+    "u" 'prodigy-unmark
+    "*T" 'prodigy-unmark-tag
+    "U" 'prodigy-unmark-all
+
+    "s" 'prodigy-start
+    "S" 'prodigy-stop
+
+    ;; refresh
+    "gr" 'prodigy-restart
+
+    "`" 'prodigy-display-process
+    (kbd "<return>") 'prodigy-browse
+    "it" 'prodigy-add-tag-filter
+    "in" 'prodigy-add-name-filter
+    "I" 'prodigy-clear-filters
+    "Jm" 'prodigy-jump-magit
+    "Jd" 'prodigy-jump-dired
+
+    "gj" 'prodigy-next-with-status
+    "gk" 'prodigy-prev-with-status
+    (kbd "C-j") 'prodigy-next-with-status
+    (kbd "C-k") 'prodigy-prev-with-status
+    (kbd "Y") 'prodigy-copy-cmd)
+
+  (evil-collection-define-key 'normal 'prodigy-view-mode-map
+    "x" 'prodigy-view-clear-buffer))
+
+(provide 'evil-collection-prodigy)
+;;; evil-collection-prodigy.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-prodigy.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-prodigy.elc
new file mode 100644
index 0000000000..c101b4edbf
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-prodigy.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-profiler.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-profiler.el
new file mode 100644
index 0000000000..fa3cff82c0
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-profiler.el
@@ -0,0 +1,70 @@
+;;; evil-collection-profiler.el --- Evil bindings for profiler -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 James Nguyen
+
+;; Author: Pierre Neidhardt <ambrevar@gmail.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, profiler, tools
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; Evil bindings for `profiler'.
+
+;;; Code:
+(require 'evil-collection)
+(require 'profiler)
+
+(defconst evil-collection-profiler-maps '(profiler-report-mode-map))
+
+(defun evil-collection-profiler-setup ()
+  "Set up `evil' bindings for `profiler'."
+  (evil-set-initial-state 'profiler-report-mode 'normal)
+
+  (evil-collection-define-key 'normal 'profiler-report-mode-map
+    ;; motion
+    (kbd "SPC") 'scroll-up-command
+    (kbd "S-SPC") 'scroll-down-command
+    (kbd "<delete>") 'scroll-down-command
+    "j" 'profiler-report-next-entry
+    "k" 'profiler-report-previous-entry
+
+    (kbd "<tab>") 'profiler-report-toggle-entry
+
+    ;; sort
+    "o" 'profiler-report-ascending-sort
+    "O" 'profiler-report-descending-sort
+
+    "c" 'profiler-report-render-calltree
+    "C" 'profiler-report-render-reversed-calltree
+    "i" 'profiler-report-describe-entry
+    "=" 'profiler-report-compare-profile
+
+    ;; open
+    (kbd "<return>") 'profiler-report-find-entry
+
+    ;; refresh
+    "gr" 'revert-buffer
+
+    ;; quit
+    "q" 'quit-window
+    "ZQ" 'evil-quit
+    "ZZ" 'quit-windw))
+
+(provide 'evil-collection-profiler)
+;;; evil-collection-profiler.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-profiler.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-profiler.elc
new file mode 100644
index 0000000000..d114323407
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-profiler.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-python.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-python.el
new file mode 100644
index 0000000000..21fb521da7
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-python.el
@@ -0,0 +1,47 @@
+;;; evil-collection-python.el --- Bindings for `python'. -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 James Nguyen
+
+;; Author: James Nguyen <james@jojojames.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: emacs, tools
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;; Bindings for `python'.
+
+;;; Code:
+(require 'evil-collection)
+(require 'python)
+
+(defconst evil-collection-python-maps '(python-mode-map))
+
+(defun evil-collection-python-set-evil-shift-width ()
+  "Set `evil-shift-width' according to `python-indent-offset'."
+  (setq evil-shift-width python-indent-offset))
+
+(defun evil-collection-python-setup ()
+  "Set up `evil' bindings for `python'."
+  (add-hook 'python-mode-hook #'evil-collection-python-set-evil-shift-width)
+
+  (evil-collection-define-key 'normal 'python-mode-map
+    "gz" 'python-shell-switch-to-shell))
+
+(provide 'evil-collection-python)
+;;; evil-collection-python.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-python.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-python.elc
new file mode 100644
index 0000000000..19db4c759c
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-python.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-quickrun.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-quickrun.el
new file mode 100644
index 0000000000..ae5395d7b1
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-quickrun.el
@@ -0,0 +1,41 @@
+;;; evil-collection-quickrun.el --- Bindings for `quickrun'. -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 James Nguyen
+
+;; Author: James Nguyen <james@jojojames.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, emacs, tools, quickrun
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; Bindings for `quickrun'.
+
+;;; Code:
+(require 'evil-collection)
+(require 'quickrun nil t)
+
+(defconst evil-collection-quickrun-maps '(quickrun--mode-map))
+
+(defun evil-collection-quickrun-setup ()
+  "Set up `evil' bindings for `quickrun'.."
+  (evil-collection-define-key 'normal 'quickrun--mode-map
+    "q" 'quit-window))
+
+(provide 'evil-collection-quickrun)
+;;; evil-collection-quickrun.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-quickrun.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-quickrun.elc
new file mode 100644
index 0000000000..96eb491b85
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-quickrun.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-racer.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-racer.el
new file mode 100644
index 0000000000..9e69d1bb87
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-racer.el
@@ -0,0 +1,47 @@
+;;; evil-collection-racer.el --- Bindings for `racer'. -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 James Nguyen
+
+;; Author: James Nguyen <james@jojojames.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: emacs, rust, tools, evil
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; Bindings for `racer'.
+
+;;; Code:
+(require 'evil-collection)
+(require 'racer nil t)
+
+(defconst evil-collection-racer-maps '(racer-mode-map
+                                       racer-help-mode-map))
+
+(defun evil-collection-racer-setup ()
+  "Set up `evil' bindings for `racer'."
+  (evil-collection-define-key 'normal 'racer-mode-map
+    "gd" 'racer-find-definition
+    (kbd "C-t") 'pop-tag-mark
+    "K" 'racer-describe)
+
+  (evil-collection-define-key 'normal 'racer-help-mode-map
+    "q" 'quit-window))
+
+(provide 'evil-collection-racer)
+;;; evil-collection-racer.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-racer.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-racer.elc
new file mode 100644
index 0000000000..f93bcbff5a
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-racer.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-realgud.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-realgud.el
new file mode 100644
index 0000000000..490385b845
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-realgud.el
@@ -0,0 +1,102 @@
+;;; evil-collection-realgud.el --- Bindings for `realgud'. -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 James Nguyen
+
+;; Author: James Nguyen <james@jojojames.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, emacs, tools, realgud
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; Bindings for `realgud'.
+
+;;; Code:
+(require 'evil-collection)
+(require 'realgud nil t)
+
+(defconst evil-collection-realgud-maps '(realgud:shortkey-mode-map))
+
+(defun evil-collection-realgud-setup ()
+  "Set up `evil' bindings for `realgud'."
+  ;; This one is to represent `realgud-populate-src-buffer-map-plain'.
+  (evil-collection-define-key 'normal 'realgud:shortkey-mode-map
+    "b" 'realgud:cmd-break
+    "D" 'realgud:cmd-delete
+    "X" 'realgud:cmd-clear
+    "-" 'realgud:cmd-disable
+    "+" 'realgud:cmd-enable
+    "T" 'realgud:cmd-backtrace
+    "f" 'realgud:cmd-finish
+    "n" 'realgud:cmd-next
+    "q" 'realgud:cmd-quit
+    "Q" 'realgud:cmd-kill
+    "r" 'realgud:cmd-restart
+    "R" 'realgud:cmd-restart
+    "s" 'realgud:cmd-step
+    "i" 'realgud:cmd-step
+    "!" 'realgud:cmd-shell
+
+    ;; (evil-collection-define-key nil map [M-down]    'realgud-track-hist-newer)
+    ;; (evil-collection-define-key nil map [M-kp-2]    'realgud-track-hist-newer)
+    ;; (evil-collection-define-key nil map [M-up]      'realgud-track-hist-older)
+    ;; (evil-collection-define-key nil map [M-kp-8]    'realgud-track-hist-older)
+    ;; (evil-collection-define-key nil map [M-kp-up]   'realgud-track-hist-older)
+    ;; (evil-collection-define-key nil map [M-kp-down] 'realgud-track-hist-newer)
+    ;; (evil-collection-define-key nil map [M-print]   'realgud-track-hist-older)
+    ;; (evil-collection-define-key nil map [M-S-down]  'realgud-track-hist-newest)
+    ;; (evil-collection-define-key nil map [M-S-up]    'realgud-track-hist-oldest)
+    )
+
+  (evil-collection-define-key 'normal 'realgud:shortkey-mode-map
+    (kbd "C-x C-q") 'realgud-short-key-mode
+    "1" 'realgud-goto-arrow1
+    "2" 'realgud-goto-arrow2
+    "3" 'realgud-goto-arrow3
+    "4" 'realgud:goto-loc-hist-4
+    "5" 'realgud:goto-loc-hist-5
+    "6" 'realgud:goto-loc-hist-6
+    "7" 'realgud:goto-loc-hist-7
+    "8" 'realgud:goto-loc-hist-8
+    "9" 'realgud:goto-loc-hist-9
+    "b" 'realgud:cmd-break
+    "J" 'realgud:cmd-jump
+    "c" 'realgud:cmd-continue
+    "e" 'realgud:cmd-eval-dwim
+    "E" 'realgud:cmd-eval-at-point
+    "U" 'realgud:cmd-until
+    "H" 'realgud:cmd-until
+    [mouse-2] 'realgud:tooltip-eval
+    [left-fringe mouse-1] 'realgud-cmds--mouse-add-remove-bp
+    [left-margin mouse-1] 'realgud-cmds--mouse-add-remove-bp
+    ">" 'realgud:cmd-newer-frame
+    "<" 'realgud:cmd-older-frame
+    "d" 'realgud:cmd-newer-frame
+    "u" 'realgud:cmd-older-frame
+    "gR" 'realgud-recenter-arrow ;; FIXME: Hmnn!
+    "C" 'realgud-window-cmd-undisturb-src
+    "g?" 'realgud:cmdbuf-info-describe
+    "S" 'realgud-window-src-undisturb-cmd
+    "R" 'realgud:cmd-restart
+    "gr" 'realgud:cmd-restart
+    "!" 'realgud:cmd-shell)
+
+  (add-hook 'realgud-short-key-mode-hook #'evil-normalize-keymaps))
+
+(provide 'evil-collection-realgud)
+;;; evil-collection-realgud.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-realgud.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-realgud.elc
new file mode 100644
index 0000000000..95d3e889e8
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-realgud.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-reftex.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-reftex.el
new file mode 100644
index 0000000000..9c48513bc7
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-reftex.el
@@ -0,0 +1,141 @@
+;;; evil-collection-reftex.el --- Bindings for `reftex'. -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 Pierre Neidhardt
+
+;; Author: Maximiliano Sandoval <msandova@protonmail.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, reftex, tools
+
+;; This file 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, or (at your
+;; option) any later version.
+;;
+;; This file 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.
+;;
+;; For a full copy of the GNU General Public License
+;; see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; Evil bindings for `reftex-mode'.
+
+;;; Code:
+(require 'evil-collection)
+(require 'reftex-ref nil t)
+(require 'reftex-ref nil t)
+(require 'reftex-cite nil t)
+
+(defconst evil-collection-reftex-maps '(reftex-select-shared-map
+                                        reftex-toc-mode-map))
+
+;; original code can be found in reftex-ref.el
+(setq reftex-select-label-prompt
+  "Select: [RET]select [j]next [k]previous [gr]escan [go]context [q]uit [g?]help")
+
+;; original code can be found in reftex-cite.el
+(setq reftex-citation-prompt
+  "Select: [RET]select [j]next [k]previous [q]uit [g?]help")
+
+;; original at reftex-ref.el
+(setq reftex-select-label-help
+  " j / k      Go to next/previous label (Cursor motion works as well)
+ [ / ]      Go to previous/next section heading.
+ c          Reuse last referenced label.
+ J          Jump to a specific section, e.g. '3 J' jumps to section 3.
+ s          Switch label type.
+ gr         Reparse document.
+ go / gO     Show context / Show insertion point.
+ S          Switch to label menu of external document (with LaTeX package `xr').
+ r / R      Toggle \\ref <-> \\vref / Rotate \\ref <=> \\fref <=> \\Fref.
+ TAB        Enter a label with completion.
+ m / M      Mark/unmark entry.
+ x / X      Put all marked entries into one/many \\ref commands.
+ q / RET    Quit without referencing / Accept current label.")
+
+;; code can be found in reftex-cite.el
+(setq reftex-citation-help
+  " j / k      Go to next/previous entry (Cursor motion works as well).
+ go / gO     Show citation / Show insertion point.
+ q          Quit without inserting \\cite macro into buffer.
+ TAB        Enter citation key with completion.
+ RET        Accept current entry and create \\cite macro.
+ m / M      Mark/Unmark the entry.
+ o / O      Create BibTeX file with all marked / unmarked entries.
+ X / X      Put all (marked) entries into one/many \\cite commands.")
+
+(defun evil-collection-reftex-setup ()
+  "Set up `evil' bindings for `reftex'."
+
+  (evil-set-initial-state 'reftex-select-label-mode 'normal)
+  (evil-set-initial-state 'reftex-select-bib-mode 'normal)
+
+  (evil-collection-define-key 'normal 'reftex-select-shared-map
+    "j" 'reftex-select-next
+    "k" 'reftex-select-previous
+    (kbd "]") 'reftex-select-next-heading
+    (kbd "[") 'reftex-select-previous-heading
+    (kbd "gj") 'reftex-select-next-heading
+    (kbd "gk") 'reftex-select-previous-heading
+    (kbd "C-j") 'reftex-select-next-heading
+    (kbd "C-k") 'reftex-select-previous-heading
+    "go" 'reftex-select-callback        ;shows the point where the label is
+    "gr" (lambda nil "Press `?' during selection to find out
+    about this key" (interactive) (throw (quote myexit) 114)) ;reftex binds keys in a very arcane way using the number asigned by describe-char, in this case the value of "g" is 114
+    "q" 'reftex-select-quit
+    "ZZ" 'reftex-select-quit
+    "ZQ" 'evil-quit
+    "g?" 'reftex-select-help
+    "c" (lambda nil "Press `?' during selection to find out
+    about this key." (interactive) (throw (quote myexit) 108))
+    "J" 'reftex-select-jump ;; weird binding, using default
+    (kbd "<tab>") 'reftex-select-read-label
+    "s" (lambda nil "Press `?' during selection to find out
+    about this key." (interactive) (throw (quote myexit) 115))
+    "x" (lambda nil "Press `?' during selection to find out
+    about this key." (interactive) (throw (quote myexit) 97))
+    "X" (lambda nil "Press `?' during selection to find out
+    about this key." (interactive) (throw (quote myexit) 65))
+    "S" (lambda nil "Press `?' during selection to find out
+    about this key." (interactive) (throw (quote myexit) 120))
+    "r" 'reftex-select-cycle-ref-style-forward
+    "R" 'reftex-select-cycle-ref-style-backward
+    "gO" 'reftex-select-show-insertion-point
+    "o" (lambda nil "Press `?' during selection to find out
+    about this key." (interactive) (throw (quote myexit) 101))
+    "O" (lambda nil "Press `?' during selection to find out
+    about this key." (interactive) (throw (quote myexit) 69))
+
+    ;; mark
+    "m" 'reftex-select-mark             ; TODO: Need a mark toggle function.
+    "u" 'reftex-select-unmark)
+
+  (evil-set-initial-state 'reftex-toc-mode 'normal)
+
+  ;; This one is more involved, in reftex-toc.el, line 282 it shows the prompt
+  ;; string with the keybinds and I don't see any way of changing it to show evil-like binds.
+  (evil-collection-define-key 'normal 'reftex-toc-mode-map
+    "j" 'reftex-toc-next
+    "k" 'reftex-toc-previous
+    (kbd "RET") 'reftex-toc-goto-line-and-hide
+    (kbd "<tab>") 'reftex-toc-goto-line
+    "g?" 'reftex-toc-show-help
+    "q" 'reftex-toc-quit
+    "ZZ" 'reftex-toc-quit
+    "ZQ" 'evil-quit
+    "gr" 'reftex-toc-rescan
+    "r" 'reftex-toc-rescan
+    "l" 'reftex-toc-toggle-labels
+    "?" 'reftex-toc-show-help
+    "x" 'reftex-toc-external
+    ;; (kbd "SPC") 'reftex-toc-view-line
+    "f" 'reftex-toc-toggle-follow))
+
+(provide 'evil-collection-reftex)
+;;; evil-collection-reftex.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-reftex.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-reftex.elc
new file mode 100644
index 0000000000..b52edc246b
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-reftex.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-rjsx-mode.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-rjsx-mode.el
new file mode 100644
index 0000000000..60525fa40b
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-rjsx-mode.el
@@ -0,0 +1,46 @@
+;;; evil-collection-rjsx-mode.el --- Bindings for `rjsx-mode'. -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 James Nguyen
+
+;; Author: James Nguyen <james@jojojames.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, emacs, rjsx, tools
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;; Bindings for `rjsx-mode'.
+
+;;; Code:
+(require 'evil-collection)
+(require 'rjsx-mode nil t)
+
+(defvar rjsx-mode-map)
+
+(defconst evil-collection-rjsx-maps '(rjsx-mode-map))
+
+(defun evil-collection-rjsx-mode-setup ()
+  "Set up `evil' bindings for `rjsx-mode'."
+  (when evil-want-C-d-scroll
+    (evil-collection-define-key 'insert 'rjsx-mode-map
+      (kbd "C-d") 'rjsx-delete-creates-full-tag)
+    (evil-collection-define-key 'normal 'rjsx-mode-map
+      (kbd "C-d") 'evil-scroll-down)))
+
+(provide 'evil-collection-rjsx-mode)
+;;; evil-collection-rjsx-mode.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-rjsx-mode.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-rjsx-mode.elc
new file mode 100644
index 0000000000..360c65772b
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-rjsx-mode.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-robe.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-robe.el
new file mode 100644
index 0000000000..6f83edc7e1
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-robe.el
@@ -0,0 +1,44 @@
+;;; evil-collection-robe.el --- Bindings for `robe'. -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 James Nguyen
+
+;; Author: James Nguyen <james@jojojames.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: emacs, evil, tools, robe
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;; Bindings for `robe'.
+
+;;; Code:
+(require 'evil-collection)
+(require 'robe nil t)
+
+(defconst evil-collection-robe-maps '(robe-mode-map))
+
+(defun evil-collection-robe-setup ()
+  "Set up `evil' bindings for `robe'."
+  (evil-collection-define-key 'normal 'robe-mode-map
+    "gd" 'robe-jump
+    (kbd "C-t") 'pop-tag-mark
+    "K" 'robe-doc
+    "gr" 'robe-rails-refresh))
+
+(provide 'evil-collection-robe)
+;;; evil-collection-robe.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-robe.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-robe.elc
new file mode 100644
index 0000000000..c69a3a800c
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-robe.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-rtags.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-rtags.el
new file mode 100644
index 0000000000..ddc39f2832
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-rtags.el
@@ -0,0 +1,140 @@
+;;; evil-collection-rtags.el --- Evil bindings for `rtags'. -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 James Nguyen
+
+;; Author: James Nguyen <james@jojojames.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, rtags, tools
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;; Evil bindings for `rtags'.
+
+;;; Code:
+(require 'evil-collection)
+(require 'rtags nil t)
+
+(defvar rtags-mode-map)
+(defvar rtags-dependency-tree-mode-map)
+(defvar rtags-references-tree-mode-map)
+(defvar rtags-location-stack-visualize-mode-map)
+
+(defconst evil-collection-rtags-maps '(rtags-mode-map
+                                       rtags-dependency-tree-mode-map
+                                       rtags-references-tree-mode-map
+                                       rtags-location-stack-visualize-mode-map))
+
+(defun evil-collection-rtags-setup ()
+  "Set up `evil' bindings for `rtags'."
+  (evil-set-initial-state 'rtags-mode 'normal)
+  (evil-set-initial-state 'rtags-dependency-tree-mode 'normal)
+  (evil-set-initial-state 'rtags-references-tree-mode 'normal)
+  (evil-set-initial-state 'rtags-location-stack-visualize-mode 'normal)
+
+  (evil-collection-define-key 'normal 'rtags-mode-map
+    ;; open
+    (kbd "<return>") 'rtags-select
+    (kbd "S-<return>") 'rtags-select-other-window
+    (kbd "M-<return>") 'rtags-show-in-other-window
+    (kbd "go") 'rtags-select-other-window
+    (kbd "gO") 'rtags-show-in-other-window
+    [mouse-1] 'rtags-select-other-window
+    [mouse-2] 'rtags-select-other-window
+
+    "c" 'rtags-select-caller
+    "C" 'rtags-select-caller-other-window
+    "x" 'rtags-select-and-remove-rtags-buffer
+    "q" 'rtags-call-bury-or-delete)
+
+  (evil-collection-define-key 'normal 'rtags-dependency-tree-mode-map
+    (kbd "<tab>") 'rtags-dependency-tree-toggle-current-expanded
+    "E" 'rtags-dependency-tree-expand-all
+    "c" 'rtags-dependency-tree-collapse-all
+    "-" 'rtags-dependency-tree-collapse-current
+    "+" 'rtags-dependency-tree-expand-current
+    "P" 'rtags-dependency-tree-find-path
+    "gf" 'rtags-dependency-tree-find-path
+
+    "gj" 'rtags-dependency-tree-next-level
+    "gk" 'rtags-dependency-tree-previous-level
+
+    (kbd "C-j") 'rtags-dependency-tree-next-level
+    (kbd "C-k") 'rtags-dependency-tree-previous-level
+    "]" 'rtags-dependency-tree-next-level
+    "[" 'rtags-dependency-tree-previous-level
+
+    ;; open
+    (kbd "<return>") 'rtags-select
+    (kbd "S-<return>") 'rtags-select-other-window
+    (kbd "M-<return>") 'rtags-show-in-other-window
+    "go" 'rtags-select-other-window
+    "gO" 'rtags-show-in-other-window
+    [mouse-1] 'rtags-select-other-window
+    [mouse-2] 'rtags-select-other-window
+    "s" 'rtags-show-in-other-window
+
+    "x" 'rtags-select-and-remove-rtags-buffer
+    "q" 'rtags-call-bury-or-delete)
+
+  (evil-collection-define-key 'normal 'rtags-references-tree-mode-map
+    (kbd "<tab>") 'rtags-references-tree-toggle-current-expanded
+
+    "E" 'rtags-references-tree-expand-all
+    "c" 'rtags-references-tree-collapse-all
+    "-" 'rtags-references-tree-collapse-current
+    "+" 'rtags-references-tree-expand-current
+
+    "gj" 'rtags-references-tree-next-level
+    "gk" 'rtags-references-tree-previous-level
+
+    (kbd "C-j") 'rtags-references-tree-next-level
+    (kbd "C-k") 'rtags-references-tree-previous-level
+
+    "]" 'rtags-references-tree-next-level
+    "[" 'rtags-references-tree-previous-level
+
+    ;; open
+    (kbd "<return>") 'rtags-select
+    (kbd "S-<return>") 'rtags-select-other-window
+    (kbd "M-<return>") 'rtags-show-in-other-window
+    "go" 'rtags-select-other-window
+    "gO" 'rtags-show-in-other-window
+    [mouse-1] 'rtags-select-other-window
+    [mouse-2] 'rtags-select-other-window
+    "s" 'rtags-show-in-other-window
+
+    "x" 'rtags-select-and-remove-rtags-buffer
+    "q" 'rtags-call-bury-or-delete)
+
+  (evil-collection-define-key 'normal 'rtags-location-stack-visualize-mode-map
+    ;; open
+    (kbd "<return>") 'rtags-select
+    (kbd "S-<return>") 'rtags-select-other-window
+    (kbd "M-<return>") 'rtags-show-in-other-window
+    (kbd "go") 'rtags-select-other-window
+    (kbd "gO") 'rtags-show-in-other-window
+    [mouse-1] 'rtags-select-other-window
+    [mouse-2] 'rtags-select-other-window
+    "s" 'rtags-show-in-other-window
+
+    "x" 'rtags-select-and-remove-rtags-buffer
+    "q" 'rtags-call-bury-or-delete))
+
+(provide 'evil-collection-rtags)
+;;; evil-collection-rtags.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-rtags.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-rtags.elc
new file mode 100644
index 0000000000..760f779e33
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-rtags.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-ruby-mode.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-ruby-mode.el
new file mode 100644
index 0000000000..df0b01eb20
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-ruby-mode.el
@@ -0,0 +1,44 @@
+;;; evil-collection-ruby-mode.el --- Bindings for `ruby-mode'. -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 James Nguyen
+
+;; Author: James Nguyen <james@jojojames.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: emacs, tools, ruby
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;; Bindings for `ruby-mode'.
+
+;;; Code:
+(require 'evil-collection)
+(require 'ruby-mode)
+
+(defconst evil-collection-ruby-mode-maps nil)
+
+(defun evil-collection-ruby-mode-set-evil-shift-width ()
+  "Set `evil-shift-width' according to `ruby-indent-level'."
+  (setq evil-shift-width ruby-indent-level))
+
+(defun evil-collection-ruby-mode-setup ()
+  "Set up `evil' bindings for `ruby'."
+  (add-hook 'ruby-mode-hook #'evil-collection-ruby-mode-set-evil-shift-width))
+
+(provide 'evil-collection-ruby-mode)
+;;; evil-collection-ruby-mode.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-ruby-mode.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-ruby-mode.elc
new file mode 100644
index 0000000000..64b27fa944
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-ruby-mode.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-settings.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-settings.el
new file mode 100644
index 0000000000..9c61d9cb34
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-settings.el
@@ -0,0 +1,45 @@
+;;; evil-collection-settings.el --- Settings for `evil-collection'. -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 James Nguyen
+
+;; Author: James Nguyen <james@jojojames.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, emacs, tools
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;; Settings for `evil-collection'.
+(require 'evil-collection)
+
+;;; Code:
+(defcustom evil-collection-settings-setup-debugger-keys t
+  "Whether to bind debugger keys when debugger is active.
+
+Debugger in this case is dependent on mode.
+
+This is only relevant for debug modes that are part of another mode,
+
+e.g. `indium'. Modes like `edebug' or `realgud' needs to be explicitly disabled
+
+through removing their entry from `evil-collection-mode-list'."
+  :type 'boolean
+  :group 'evil-collection)
+
+(provide 'evil-collection-settings)
+;;; evil-collection-settings.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-settings.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-settings.elc
new file mode 100644
index 0000000000..bd7c2e63ba
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-settings.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-simple.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-simple.el
new file mode 100644
index 0000000000..5248dfb4d5
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-simple.el
@@ -0,0 +1,47 @@
+;;; evil-collection-simple.el --- Bindings for `simple' -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 James Nguyen
+
+;; Author: James Nguyen <james@jojojames.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, emacs, tools
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; Bindings for `simple'
+
+;;; Code:
+(require 'evil-collection)
+(require 'simple)
+
+(defvar special-mode-map)
+
+(defconst evil-collection-simple-maps '(special-mode-map))
+
+(defun evil-collection-simple-setup ()
+  "Set up `evil' bindings for `simple'."
+  (evil-collection-define-key '(normal visual) 'special-mode-map
+    "q" 'quit-window
+    " " 'scroll-up-command
+    "g?" 'describe-mode
+    "h" 'evil-backward-char
+    "gr" 'revert-buffer))
+
+(provide 'evil-collection-simple)
+;;; evil-collection-simple.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-simple.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-simple.elc
new file mode 100644
index 0000000000..f446bcc854
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-simple.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-slime.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-slime.el
new file mode 100644
index 0000000000..f03cb8e39d
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-slime.el
@@ -0,0 +1,182 @@
+;;; evil-collection-slime.el --- Evil bindings for `slime' -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 James Nguyen
+
+;; Author: James Nguyen <james@jojojames.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, slime, tools
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; Evil bindings for `slime-mode'.
+
+;;; Code:
+(require 'evil-collection)
+(require 'slime nil t)
+
+(defvar slime-parent-map)
+(defvar sldb-mode-map)
+(defvar slime-inspector-mode-map)
+(defvar slime-mode-map)
+(defvar slime-popup-buffer-mode-map)
+(defvar slime-xref-mode-map)
+
+(defconst evil-collection-slime-maps '(slime-parent-map
+                                       sldb-mode-map
+                                       slime-inspector-mode-map
+                                       slime-mode-map
+                                       slime-popup-buffer-mode-map
+                                       slime-xref-mode-map ))
+
+(defun evil-collection-slime-last-sexp (command &rest args)
+  "In normal-state or motion-state, last sexp ends at point."
+  (if (and (not evil-move-beyond-eol)
+           (or (evil-normal-state-p) (evil-motion-state-p)))
+      (save-excursion
+        (unless (or (eobp) (eolp)) (forward-char))
+        (apply command args))
+    (apply command args)))
+
+(defun evil-collection-slime-setup ()
+  "Set up `evil' bindings for `slime'."
+  (unless evil-move-beyond-eol
+    (advice-add 'slime-eval-last-expression :around 'evil-collection-slime-last-sexp)
+    (advice-add 'slime-pprint-eval-last-expression :around 'evil-collection-slime-last-sexp)
+    (advice-add 'slime-eval-print-last-expression :around 'evil-collection-slime-last-sexp)
+    (advice-add 'slime-eval-last-expression-in-repl
+                :around 'evil-collection-slime-last-sexp))
+
+  (evil-set-initial-state 'sldb-mode 'normal)
+  (evil-set-initial-state 'slime-inspector-mode 'normal)
+  (evil-set-initial-state 'slime-popup-buffer-mode 'normal)
+  (evil-set-initial-state 'slime-xref-mode 'normal)
+
+  (evil-collection-define-key 'normal 'slime-parent-map
+    "gd" 'slime-edit-definition
+    (kbd "C-t") 'slime-pop-find-definition-stack)
+
+  (evil-collection-define-key 'normal 'sldb-mode-map
+    (kbd "RET") 'sldb-default-action
+    (kbd "C-m") 'sldb-default-action
+    [return] 'sldb-default-action
+    [mouse-2]  'sldb-default-action/mouse
+    [follow-link] 'mouse-face
+    "\C-i" 'sldb-cycle
+    "g?" 'describe-mode
+    "S" 'sldb-show-source
+    "e" 'sldb-eval-in-frame
+    "d" 'sldb-pprint-eval-in-frame
+    "D" 'sldb-disassemble
+    "i" 'sldb-inspect-in-frame
+    "gj" 'sldb-down
+    "gk" 'sldb-up
+    (kbd "C-j") 'sldb-down
+    (kbd "C-k") 'sldb-up
+    "]" 'sldb-details-down
+    "[" 'sldb-details-up
+    (kbd "M-j") 'sldb-details-down
+    (kbd "M-k") 'sldb-details-up
+    "gg" 'sldb-beginning-of-backtrace
+    "G" 'sldb-end-of-backtrace
+    "t" 'sldb-toggle-details
+    "gr" 'sldb-restart-frame
+    "I" 'sldb-invoke-restart-by-name
+    "R" 'sldb-return-from-frame
+    "c" 'sldb-continue
+    "s" 'sldb-step
+    "n" 'sldb-next
+    "o" 'sldb-out
+    "b" 'sldb-break-on-return
+    "a" 'sldb-abort
+    "q" 'sldb-quit
+    "A" 'sldb-break-with-system-debugger
+    "B" 'sldb-break-with-default-debugger
+    "P" 'sldb-print-condition
+    "C" 'sldb-inspect-condition
+    "g:" 'slime-interactive-eval
+    "0" 'sldb-invoke-restart-0
+    "1" 'sldb-invoke-restart-1
+    "2" 'sldb-invoke-restart-2
+    "3" 'sldb-invoke-restart-3
+    "4" 'sldb-invoke-restart-4
+    "5" 'sldb-invoke-restart-5
+    "6" 'sldb-invoke-restart-6
+    "7" 'sldb-invoke-restart-7
+    "8" 'sldb-invoke-restart-8
+    "9" 'sldb-invoke-restart-9)
+
+  (evil-collection-define-key 'normal 'slime-inspector-mode-map
+    [return] 'slime-inspector-operate-on-point
+    (kbd "C-m") 'slime-inspector-operate-on-point
+    [mouse-1] 'slime-inspector-operate-on-click
+    [mouse-2] 'slime-inspector-operate-on-click
+    [mouse-6] 'slime-inspector-pop
+    [mouse-7] 'slime-inspector-next
+    "gk" 'slime-inspector-pop
+    (kbd "C-k") 'slime-inspector-pop
+    "gj" 'slime-inspector-next
+    "j" 'slime-inspector-next
+    "k" 'slime-inspector-previous-inspectable-object
+    "K" 'slime-inspector-describe
+    "p" 'slime-inspector-pprint
+    "e" 'slime-inspector-eval
+    "h" 'slime-inspector-history
+    "gr" 'slime-inspector-reinspect
+    "gv" 'slime-inspector-toggle-verbose
+    "\C-i" 'slime-inspector-next-inspectable-object
+    [(shift tab)]
+    'slime-inspector-previous-inspectable-object ; Emacs translates S-TAB
+    [backtab] 'slime-inspector-previous-inspectable-object ; to BACKTAB on X.
+    "." 'slime-inspector-show-source
+    "gR" 'slime-inspector-fetch-all
+    "q" 'slime-inspector-quit)
+
+  (evil-collection-define-key 'normal 'slime-mode-map
+    (kbd "K") 'slime-describe-symbol
+    (kbd "C-t") 'slime-pop-find-definition-stack
+    ;; goto
+    "gd" 'slime-edit-definition)
+
+  (evil-collection-define-key 'normal 'slime-popup-buffer-mode-map
+    ;; quit
+    "q" 'quit-window
+
+    (kbd "C-t") 'slime-pop-find-definition-stack
+
+    ;; goto
+    "gd" 'slime-edit-definition)
+
+  (evil-collection-define-key 'normal 'slime-xref-mode-map
+    (kbd "RET") 'slime-goto-xref
+    (kbd "S-<return>") 'slime-goto-xref
+    "go" 'slime-show-xref
+    "gj" 'slime-xref-next-line
+    "gk" 'slime-xref-prev-line
+    (kbd "C-j") 'slime-xref-next-line
+    (kbd "C-k") 'slime-xref-prev-line
+    "]" 'slime-xref-next-line
+    "[" 'slime-xref-prev-line
+    "gr" 'slime-recompile-xref
+    "gR" 'slime-recompile-all-xrefs
+    "r" 'slime-xref-retract)
+
+  (add-hook 'slime-popup-buffer-mode-hook #'evil-normalize-keymaps))
+
+(provide 'evil-collection-slime)
+;;; evil-collection-slime.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-slime.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-slime.elc
new file mode 100644
index 0000000000..ce310e3652
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-slime.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-term.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-term.el
new file mode 100644
index 0000000000..a258600a6d
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-term.el
@@ -0,0 +1,159 @@
+;;; evil-collection-term.el --- Evil bindings for term and ansi-term  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 Pierre Neidhardt
+
+;; Author: Pierre Neidhardt <ambrevar@gmail.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, term, tools
+
+;; This file 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, or (at your
+;; option) any later version.
+;;
+;; This file 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.
+;;
+;; For a full copy of the GNU General Public License
+;; see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; Evil integration for `term' and `ansi-term'.
+;; This should also work for other terminal emulators such as `multi-term'.
+;;
+;; Switching to normal state will automatically switch to line mode.
+;; Conversely, switching to insert state will automatically switch to char mode.
+
+;;; Code:
+(require 'evil-collection)
+(require 'term)
+
+(defcustom evil-collection-term-sync-state-and-mode-p t
+  "Synchronize insert/normal state with char/line-mode respectively.
+
+When non-nil, going to normal state will automatically switch to
+line-mode.  Conversely, going to insert state on the last
+commandline will automatically switch to char-mode.
+
+Warning: This feature is experimental."
+  :group 'evil-collection-term
+  :type 'boolean)
+
+(defcustom evil-collection-term-sync-state-function
+  'evil-collection-term-switch-to-char-mode-on-insert
+  "Function used when synchronizing insert/normal state with char/line-mode.
+
+This is only used if `evil-collection-term-sync-state-and-mode-p' is true."
+  :group 'evil-collection-term
+  :type 'function)
+
+;; TODO: Rebinding ESC has the drawback that programs like vi cannot use it anymore.
+;; Workaround: switch to Emacs state and double-press ESC.
+;; Otherwise leave ESC to "C-c C-j".
+;; Or bind char-mode ESC to "C-c C-x"?
+
+;; TODO: Add support for normal-state editing.
+
+(defconst evil-collection-term-maps '(term-raw-map
+                                      term-mode-map))
+
+(defun evil-collection-term-escape-stay ()
+  "Go back to normal state but don't move cursor backwards.
+Moving cursor backwards is the default Vim behavior but
+it is not appropriate in some cases like terminals."
+  (setq-local evil-move-cursor-back nil))
+
+(defun evil-collection-term-char-mode-insert ()
+  "Switch to `term-char-mode' and enter insert state."
+  (interactive)
+  (term-char-mode)
+  (evil-insert-state))
+
+(defun evil-collection-term-char-mode-entry-function ()
+  "Maybe switch to `term-char-mode' on insert state."
+  (when (get-buffer-process (current-buffer))
+    (let (last-prompt)
+      (save-excursion
+        (goto-char (point-max))
+        (when (= (line-beginning-position) (line-end-position))
+          (ignore-errors (backward-char)))
+        (setq last-prompt (max (term-bol nil) (line-beginning-position))))
+      (when (>= (point) last-prompt)
+        (term-char-mode)))))
+
+(defun evil-collection-term-switch-to-char-mode-on-insert ()
+  "Switch to `term-char-mode' on insert state."
+  (when (get-buffer-process (current-buffer))
+    (term-char-mode)))
+
+(defun evil-collection-term-sync-state-and-mode ()
+  "Sync `term-char-mode' and `term-line-mode' with insert and normal state."
+  (add-hook 'evil-insert-state-entry-hook
+            evil-collection-term-sync-state-function nil t)
+  (add-hook 'evil-insert-state-exit-hook 'term-line-mode nil t))
+
+(defun evil-collection-term-send-tab ()
+  "Send tab in term mode."
+  (interactive)
+  (term-send-raw-string "\t"))
+
+(defun evil-collection-term-setup ()
+  "Set up `evil' bindings for `term'."
+  (evil-set-initial-state 'term-mode 'insert)
+  (if evil-collection-term-sync-state-and-mode-p
+      (add-hook 'term-mode-hook 'evil-collection-term-sync-state-and-mode)
+    (remove-hook 'term-mode-hook 'evil-collection-term-sync-state-and-mode))
+
+  (add-hook 'term-mode-hook 'evil-collection-term-escape-stay)
+
+  ;; Evil has some "C-" bindings in insert state that shadow regular terminal bindings.
+  ;; Don't raw-send "C-c" (prefix key) nor "C-h" (help prefix).
+  (evil-collection-define-key 'insert 'term-raw-map
+    (kbd "C-a") 'term-send-raw
+    (kbd "C-b") 'term-send-raw ; Should not be necessary.
+    (kbd "C-d") 'term-send-raw
+    (kbd "C-e") 'term-send-raw
+    (kbd "C-f") 'term-send-raw ; Should not be necessary.
+    (kbd "C-k") 'term-send-raw
+    (kbd "C-l") 'term-send-raw ; Should not be necessary.
+    (kbd "C-n") 'term-send-raw
+    (kbd "C-o") 'term-send-raw
+    (kbd "C-p") 'term-send-raw
+    (kbd "C-q") 'term-send-raw ; Should not be necessary.
+    (kbd "C-r") 'term-send-raw
+    (kbd "C-s") 'term-send-raw ; Should not be necessary.
+    (kbd "C-t") 'term-send-raw
+    (kbd "C-u") 'term-send-raw ; Should not be necessary.
+    (kbd "C-v") 'term-send-raw ; Should not be necessary.
+    (kbd "C-w") 'term-send-raw
+    (kbd "C-y") 'term-send-raw
+    (kbd "C-z") 'term-send-raw
+    (kbd "<tab>") 'evil-collection-term-send-tab ; Should not be necessary.
+    (kbd "C-c C-d") 'term-send-eof
+    (kbd "C-c C-z") 'term-stop-subjob)
+
+  (evil-collection-define-key 'normal 'term-mode-map
+    (kbd "C-c C-k") 'evil-collection-term-char-mode-insert
+    (kbd "<return>") 'term-send-input
+
+    (kbd "p") 'term-paste
+
+    ;; motion
+    "[" 'term-previous-prompt
+    "]" 'term-next-prompt
+    (kbd "C-k") 'term-previous-prompt
+    (kbd "C-j") 'term-next-prompt
+    "gk" 'term-previous-prompt
+    "gj" 'term-next-prompt
+    ;; "0" 'term-bol ; "0" is meant to really go at the beginning of line.
+    "^" 'term-bol
+    "$" 'term-show-maximum-output))
+
+(provide 'evil-collection-term)
+;;; evil-collection-term.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-term.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-term.elc
new file mode 100644
index 0000000000..1ec20ed6c1
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-term.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-tide.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-tide.el
new file mode 100644
index 0000000000..94d59ec2eb
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-tide.el
@@ -0,0 +1,65 @@
+;;; evil-collection-tide.el --- Bindings for `tide-mode'. -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 James Nguyen
+
+;; Author: James Nguyen <james@jojojames.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, tide, typescript, languages
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;; Bindings for `tide-mode'.
+
+;;; Code:
+(require 'tide nil t)
+(require 'evil-collection)
+
+(defconst evil-collection-tide-maps '(tide-mode-map
+                                      tide-references-mode-map
+                                      tide-project-errors-mode-map))
+
+(defun evil-collection-tide-setup ()
+  "Set up `evil' bindings for `tide'."
+  (evil-collection-define-key 'normal 'tide-mode-map
+    "gd" 'tide-jump-to-definition
+    (kbd "C-t") 'tide-jump-back
+    "K" 'tide-documentation-at-point)
+
+  (evil-collection-define-key 'normal 'tide-references-mode-map
+    "gj" 'tide-find-next-reference
+    "gk" 'tide-find-previous-reference
+    (kbd "C-j") 'tide-find-next-reference
+    (kbd "C-k") 'tide-find-previous-reference
+    (kbd "C-m") 'tide-goto-reference
+    (kbd "<return>") 'tide-goto-reference
+    ;; quit
+    "q" 'quit-window)
+
+  (evil-collection-define-key 'normal 'tide-project-errors-mode-map
+    "gj" 'tide-find-next-error
+    "gk" 'tide-find-previous-error
+    (kbd "C-j") 'tide-find-next-error
+    (kbd "C-k") 'tide-find-previous-error
+    (kbd "C-m") 'tide-goto-error
+    (kbd "<return>") 'tide-goto-error
+    ;; quit
+    (kbd "q") 'quit-window))
+
+(provide 'evil-collection-tide)
+;;; evil-collection-tide.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-tide.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-tide.elc
new file mode 100644
index 0000000000..c937391aaa
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-tide.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-transmission.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-transmission.el
new file mode 100644
index 0000000000..fb7e9e9ccb
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-transmission.el
@@ -0,0 +1,172 @@
+;;; evil-collection-transmission.el --- Evil bindings for transmission.el -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 Pierre Neidhardt
+
+;; Author: Pierre Neidhardt <ambrevar@gmail.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, transmission, tools
+
+;; This file 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, or (at your
+;; option) any later version.
+;;
+;; This file 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.
+;;
+;; For a full copy of the GNU General Public License
+;; see <http://www.gnu.org/licenses/>.
+
+
+;;; Commentary:
+;; Evil bindings for `transmission'.
+
+;;; Code:
+(require 'evil-collection)
+(require 'transmission nil t)
+
+(defvar transmission-mode-map)
+(defvar transmission-files-mode-map)
+(defvar transmission-info-mode-map)
+(defvar transmission-peers-mode-map)
+
+(defconst evil-collection-transmission-maps '(transmission-mode-map
+                                              transmission-files-mode-map
+                                              transmission-info-mode-map
+                                              transmission-peers-mode-map))
+
+(defun evil-collection-transmission-setup ()
+  "Set up `evil' bindings for `transmission'."
+
+  (evil-collection-inhibit-insert-state 'transmission-mode-map)
+  (evil-set-initial-state 'transmission-mode 'normal)
+  (evil-collection-define-key 'normal 'transmission-mode-map
+    ;; motion
+    (kbd "SPC") 'scroll-up-command
+    (kbd "S-SPC") 'scroll-down-command
+    (kbd "<delete>") 'scroll-down-command
+
+    ;; sort
+    "o" 'tabulated-list-sort
+
+    (kbd "<return>") 'transmission-files
+    "p" 'transmission-peers
+    "i" 'transmission-info
+
+    "a" 'transmission-add
+    ;; "D" 'transmission-delete ; Useless with `transmission-remove'?
+    "r" 'transmission-move
+    "D" 'transmission-remove
+    "x" 'transmission-toggle ; EMMS has "x" for pause.
+    "t" 'transmission-trackers-add
+    "c" 'transmission-verify ; "c" for "[c]heck".
+    "d" 'transmission-set-download
+    "u" 'transmission-set-upload
+    "S" 'transmission-set-ratio ; "S" for "[S]eed"
+    "P" 'transmission-set-bandwidth-priority
+
+    ;; mark
+    "m" 'transmission-toggle-mark
+    "U" 'transmission-unmark-all
+    "~" 'transmission-invert-marks
+
+    ;; refresh
+    "gr" 'revert-buffer
+
+    ;; quit
+    "q" 'transmission-quit
+    "ZQ" 'evil-quit
+    "ZZ" 'transmission-quit)
+
+  (evil-collection-inhibit-insert-state 'transmission-files-mode-map)
+  (evil-set-initial-state 'transmission-files-mode 'normal)
+  (evil-collection-define-key 'normal 'transmission-files-mode-map
+    (kbd "SPC") 'scroll-up-command
+    (kbd "S-SPC") 'scroll-down-command
+    (kbd "<delete>") 'scroll-down-command
+
+    ;; sort
+    "o" 'tabulated-list-sort
+
+    "p" 'transmission-peers
+    "i" 'transmission-info
+
+    "r" 'transmission-move
+    "P" 'transmission-files-priority
+
+    ;; mark
+    "u" 'transmission-files-unwant
+    "m" 'transmission-files-want
+
+    ;; open
+    (kbd "<return>") 'transmission-find-file
+    (kbd "S-<return>") 'transmission-find-file-other-window
+    (kbd "M-<return>") 'transmission-display-file
+    "go" 'transmission-find-file-other-window
+
+    "v" 'transmission-view-file
+
+    "!" 'transmission-files-command
+    ;; "X" 'transmission-files-command
+    "t" 'transmission-trackers-add
+    "T" 'transmission-trackers-remove
+
+    ;; goto URL
+    "gx" 'transmission-browse-url-of-file ; See mu4e.
+
+    ;; quit
+    "q" 'transmission-quit
+    "ZQ" 'evil-quit
+    "ZZ" 'transmission-quit)
+
+  (evil-collection-inhibit-insert-state 'transmission-info-mode-map)
+  (evil-set-initial-state 'transmission-info-mode 'normal)
+  (evil-collection-define-key 'normal 'transmission-info-mode-map
+    "p" 'transmission-peers
+
+    "t" 'transmission-trackers-add
+    "T" 'transmission-trackers-remove
+    "D" 'transmission-set-torrent-download
+    "U" 'transmission-set-torrent-upload
+    "S" 'transmission-set-torrent-ratio ; "S" for "[S]eed"
+    "P" 'transmission-set-bandwidth-priority
+    "r" 'transmission-move
+
+    ;; quit
+    "q" 'quit-window
+    "ZQ" 'evil-quit
+    "ZZ" 'quit-window)
+
+  (evil-collection-define-key 'operator 'transmission-info-mode-map
+    ;; Like `eww'.
+    "u" '(menu-item
+          ""
+          nil
+          :filter (lambda (&optional _)
+                    (when (memq evil-this-operator
+                                evil-collection-yank-operators)
+                      (setq evil-inhibit-operator t)
+                      #'transmission-copy-magnet))))
+
+
+  (evil-collection-inhibit-insert-state 'transmission-peers-mode-map)
+  (evil-set-initial-state 'transmission-peers-mode 'normal)
+  (evil-collection-define-key 'normal 'transmission-peers-mode-map
+    ;; sort
+    "o" 'tabulated-list-sort
+
+    "i" 'transmission-info
+
+    ;; quit
+    "q" 'quit-window
+    "ZQ" 'evil-quit
+    "ZZ" 'quit-window))
+
+(provide 'evil-collection-transmission)
+;;; evil-collection-transmission.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-transmission.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-transmission.elc
new file mode 100644
index 0000000000..0e662ff25e
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-transmission.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-typescript-mode.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-typescript-mode.el
new file mode 100644
index 0000000000..3e4a218d34
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-typescript-mode.el
@@ -0,0 +1,45 @@
+;;; evil-collection-typescript-mode.el --- Bindings for `typescript-mode'. -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 James Nguyen
+
+;; Author: James Nguyen <james@jojojames.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: emacs, evil, tools, typescript
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;; Bindings for `typescript-mode'.
+
+;;; Code:
+(require 'evil-collection)
+(require 'typescript-mode nil t)
+
+(defvar typescript-indent-level)
+
+(defun evil-collection-typescript-mode-set-evil-shift-width ()
+  "Set `evil-shift-width' according to `typescript-indent-level'."
+  (setq evil-shift-width typescript-indent-level))
+
+(defun evil-collection-typescript-mode-setup ()
+  "Set up `evil' bindings for `typescript-mode'."
+  (add-hook 'typescript-mode-hook
+            #'evil-collection-typescript-mode-set-evil-shift-width))
+
+(provide 'evil-collection-typescript-mode)
+;;; evil-collection-typescript-mode.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-typescript-mode.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-typescript-mode.elc
new file mode 100644
index 0000000000..765675c686
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-typescript-mode.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-vc-annotate.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-vc-annotate.el
new file mode 100644
index 0000000000..148886745b
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-vc-annotate.el
@@ -0,0 +1,58 @@
+;;; evil-collection-vc-annotate.el --- Bindings for `vc-annotate' -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 James Nguyen
+
+;; Author: James Nguyen <james@jojojames.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, emacs, tools
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; Bindings for `vc-annotate'
+
+;;; Code:
+(require 'evil-collection)
+(require 'vc-annotate)
+
+(defconst evil-collection-vc-annotate-maps '(vc-annotate-mode-map))
+
+(defun evil-collection-vc-annotate-setup ()
+  "Set up `evil' bindings for `vc-annotate'."
+  (evil-set-initial-state 'vc-annotate-mode 'normal)
+  (evil-collection-define-key 'normal 'vc-annotate-mode-map
+    "q" 'quit-window
+    "a" 'vc-annotate-revision-previous-to-line
+    "d" 'vc-annotate-show-diff-revision-at-line
+    "=" 'vc-annotate-show-diff-revision-at-line
+    "D" 'vc-annotate-show-changeset-diff-revision-at-line
+    "F" 'vc-annotate-find-revision-at-line
+    "J" 'vc-annotate-revision-at-line
+    "L" 'vc-annotate-show-log-revision-at-line
+    "gj" 'vc-annotate-next-revision
+    "gk" 'vc-annotate-prev-revision
+    "]" 'vc-annotate-next-revision
+    "[" 'vc-annotate-prev-revision
+    (kbd "C-j") 'vc-annotate-next-revision
+    (kbd "C-k") 'vc-annotate-prev-revision
+    "W" 'vc-annotate-working-revision
+    "A" 'vc-annotate-toggle-annotation-visibility
+    (kbd "RET") 'vc-annotate-goto-line))
+
+(provide 'evil-collection-vc-annotate)
+;;; evil-collection-vc-annotate.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-vc-annotate.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-vc-annotate.elc
new file mode 100644
index 0000000000..61b95dfc1b
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-vc-annotate.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-vdiff.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-vdiff.el
new file mode 100644
index 0000000000..81cd0f8fdd
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-vdiff.el
@@ -0,0 +1,66 @@
+;;; evil-collection-vdiff.el --- Evil bindings for vdiff -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 Pierre Neidhardt
+
+;; Author: Evgeni Kolev <evgenysw@gmail.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, vdiff, tools
+
+;; This file 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, or (at your
+;; option) any later version.
+;;
+;; This file 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.
+;;
+;; For a full copy of the GNU General Public License
+;; see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; Evil bindings for vdiff.el https://github.com/justbur/emacs-vdiff
+
+;;; Code:
+(require 'vdiff nil t)
+(require 'evil-collection)
+
+(defun evil-collection-vdiff-setup ()
+  "Set up `evil' bindings for `vdiff-mode'."
+
+  (dolist (mode '(vdiff-mode vdiff-3way-mode))
+    (evil-define-minor-mode-key 'normal mode
+      "zc" 'vdiff-close-fold
+      "zM" 'vdiff-close-all-folds
+      "zo" 'vdiff-open-fold
+      "zR" 'vdiff-open-all-folds
+      "go" 'vdiff-receive-changes
+      "gp" 'vdiff-send-changes
+      "]c" 'vdiff-next-hunk
+      "[c" 'vdiff-previous-hunk)
+
+    ;; define `do' (diff obtain) and `dp' (diff put) bindings
+    (evil-define-minor-mode-key 'operator mode
+      "o" '(menu-item
+            ""
+            nil
+            :filter (lambda (&optional _)
+                      (when (memq evil-this-operator
+                                  evil-collection-delete-operators)
+                        #'vdiff-receive-changes)))
+      "p" '(menu-item
+            ""
+            nil
+            :filter (lambda (&optional _)
+                      (when (memq evil-this-operator
+                                  evil-collection-delete-operators)
+                        #'vdiff-send-changes))))))
+
+(provide 'evil-collection-vdiff)
+
+;;; evil-collection-vdiff.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-vdiff.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-vdiff.elc
new file mode 100644
index 0000000000..7e7ee21ddd
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-vdiff.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-view.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-view.el
new file mode 100644
index 0000000000..4cd8141985
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-view.el
@@ -0,0 +1,53 @@
+;;; evil-collection-view.el --- Evil bindings for view. -*- lexical-binding: t -*-
+
+;; Copyright (C) 2018 Pierre Neidhardt
+
+;; Author: Pierre Neidhardt <ambrevar@gmail.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, bindings, tools
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; Evil bindings for View.
+
+;;; Code:
+(require 'evil-collection)
+(require 'view)
+
+(defconst evil-collection-view-maps '(view-mode-map))
+
+(defun evil-collection-view-setup ()
+  "Set up `evil' bindings for `view'."
+  (evil-set-initial-state 'view-mode 'normal)
+  (evil-collection-define-key 'normal 'view-mode-map
+    "q" 'quit-window
+    (kbd "SPC") 'View-scroll-page-forward
+    (kbd "S-SPC") 'View-scroll-page-backward
+
+    ;; zoom
+    "+" 'text-scale-increase
+    "=" 'text-scale-increase
+    "0" 'text-scale-adjust              ; TODO: Conflicts with `evil-beginning-of-line'.
+    "-" 'text-scale-decrease
+
+    ;; refresh
+    (kbd "gr") 'revert-buffer))
+
+(provide 'evil-collection-view)
+;;; evil-collection-view.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-view.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-view.elc
new file mode 100644
index 0000000000..c1f93aeffd
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-view.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-vlf.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-vlf.el
new file mode 100644
index 0000000000..0374f5eb1b
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-vlf.el
@@ -0,0 +1,77 @@
+;;; evil-collection-vlf.el --- Evil bindings for vlf -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 James Nguyen
+
+;; Author: James Nguyen <james@jojojames.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, vlf, tools
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; Evil bindings for `vlf'.
+
+;;; Code:
+(require 'evil-collection)
+(require 'vlf nil t)
+
+(defvar vlf-mode-map)
+(declare-function vlf-change-batch-size "vlf")
+
+(defconst evil-collection-vlf-maps '(vlf-mode-map))
+
+(defun evil-collection-vlf-decrease-batch-size ()
+  "Decrease vlf batch size by factor of 2."
+  (interactive)
+  (vlf-change-batch-size t))
+
+;;; Code:
+(defun evil-collection-vlf-setup ()
+  "Set up `evil' bindings for `vlf'."
+  (evil-set-initial-state 'vlf-mode 'normal)
+
+  (evil-collection-define-key 'normal 'vlf-mode-map
+    "gj" 'vlf-next-batch
+    "gk" 'vlf-prev-batch
+    (kbd "C-j") 'vlf-next-batch
+    (kbd "C-k") 'vlf-prev-batch
+    "]" 'vlf-next-batch
+    "[" 'vlf-prev-batch
+
+    "+" 'vlf-change-batch-size
+    "-" 'evil-collection-vlf-decrease-batch-size
+    "=" 'vlf-next-batch-from-point
+
+    ;; refresh
+    "gr" 'vlf-revert
+
+    "s" 'vlf-re-search-forward
+    "S" 'vlf-re-search-backward
+
+    "gg" 'vlf-beginning-of-file
+    "G" 'vlf-end-of-file
+    "J" 'vlf-jump-to-chunk
+    "E" 'vlf-ediff-buffers
+
+    "g%" 'vlf-query-replace
+    "go" 'vlf-occur
+    "L" 'vlf-goto-line
+    "F" 'vlf-toggle-follow))
+
+(provide 'evil-collection-vlf)
+;;; evil-collection-vlf.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-vlf.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-vlf.elc
new file mode 100644
index 0000000000..ede785e061
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-vlf.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-wdired.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-wdired.el
new file mode 100644
index 0000000000..11a1e271ef
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-wdired.el
@@ -0,0 +1,46 @@
+;;; evil-collection-wdired.el --- Bindings for `wdired' -*- lexical-binding: t -*-
+
+;; Copyright (C) 2018 James Nguyen
+
+;; Author: James Nguyen <james@jojojames.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, emacs, tools
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; Bindings for `wdired'.
+
+;;; Code:
+(require 'evil-collection)
+(require 'wdired)
+
+(defconst evil-collection-wdired-maps '(wdired-mode-map))
+
+(defun evil-collection-wdired-setup ()
+  "Set up `evil' bindings for `wdired'."
+  (evil-collection-define-key nil 'wdired-mode-map
+    [remap evil-write] 'wdired-finish-edit)
+
+  (evil-collection-define-key 'normal 'wdired-mode-map
+    "ZQ" 'wdired-abort-changes
+    "ZZ" 'wdired-finish-edit
+    (kbd "<escape>") 'wdired-exit))
+
+(provide 'evil-collection-wdired)
+;;; evil-collection-wdired.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-wdired.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-wdired.elc
new file mode 100644
index 0000000000..680c2c24a9
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-wdired.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-wgrep.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-wgrep.el
new file mode 100644
index 0000000000..efbc52081b
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-wgrep.el
@@ -0,0 +1,48 @@
+;;; evil-collection-wgrep.el --- Bindings for `wgrep' -*- lexical-binding: t -*-
+
+;; Copyright (C) 2018 James Nguyen
+
+;; Author: James Nguyen <james@jojojames.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, emacs, tools
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; Bindings for `wgrep'.
+
+;;; Code:
+(require 'evil-collection)
+(require 'wgrep nil t)
+
+(defvar wgrep-mode-map)
+
+(defconst evil-collection-wgrep-maps '(wgrep-mode-map))
+
+(defun evil-collection-wgrep-setup ()
+  "Set up `evil' bindings for `wgrep'."
+  (evil-collection-define-key nil 'wgrep-mode-map
+    [remap evil-write] 'wgrep-finish-edit)
+
+  (evil-collection-define-key 'normal 'wgrep-mode-map
+    "ZQ" 'wgrep-abort-changes
+    "ZZ" 'wgrep-finish-edit
+    (kbd "<escape>") 'wgrep-exit))
+
+(provide 'evil-collection-wgrep)
+;;; evil-collection-wgrep.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-wgrep.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-wgrep.elc
new file mode 100644
index 0000000000..df92d68e0e
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-wgrep.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-which-key.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-which-key.el
new file mode 100644
index 0000000000..391a90ce39
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-which-key.el
@@ -0,0 +1,51 @@
+;;; evil-collection-which-key.el --- Evil bindings for which-key -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 Pierre Neidhardt
+
+;; Author: Maximiliano Sandoval <msandova@protonmail.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, which-key, tools
+
+;; This file 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, or (at your
+;; option) any later version.
+;;
+;; This file 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.
+;;
+;; For a full copy of the GNU General Public License
+;; see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; Evil bindings for `which-key'
+
+;;; Code:
+
+(require 'evil-collection)
+(require 'which-key nil t)
+
+(defvar which-key-C-h-map)
+
+(defconst evil-collection-which-key-maps '(which-key-C-h-map))
+
+;; `which-key'is coded so that the prompt properly shows j and k as
+;; the bindings.
+(defun evil-collection-which-key-setup ()
+  "Set up `evil' bindings for `which-key'."
+
+  ;; (evil-collection-define-key nil 'which-key-C-h-map "u" 'which-key-undo-key)
+  (evil-collection-define-key nil 'which-key-C-h-map
+    "q" 'which-key-abort
+    "j" 'which-key-show-next-page-cycle
+    "k" 'which-key-show-previous-page-cycle
+    "?" 'which-key-show-standard-help))
+
+(provide 'evil-collection-which-key)
+;;; evil-collection-which-key.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-which-key.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-which-key.elc
new file mode 100644
index 0000000000..963c202c9d
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-which-key.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-woman.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-woman.el
new file mode 100644
index 0000000000..4fe3c3486d
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-woman.el
@@ -0,0 +1,50 @@
+;;; evil-collection-woman.el --- Evil bindings for WoMan -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 Pierre Neidhardt
+
+;; Author: Pierre Neidhardt <ambrevar@gmail.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, woman, tools
+
+;; This file 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, or (at your
+;; option) any later version.
+;;
+;; This file 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.
+;;
+;; For a full copy of the GNU General Public License
+;; see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; Evil bindings for `woman'.
+
+;;; Code:
+(require 'evil-collection)
+(require 'evil-collection-man) ; WoMan's keymap inherits from Man.
+(require 'woman)
+
+(defconst evil-collection-woman-maps '(woman-mode-map))
+
+(defun evil-collection-woman-setup ()
+  "Set up `evil' bindings for `woman'."
+  (evil-set-initial-state 'woman-mode 'normal)
+  (evil-collection-define-key 'normal 'woman-mode-map
+    (kbd "]") 'WoMan-next-manpage
+    (kbd "[") 'WoMan-previous-manpage
+
+    ;; goto
+    ;; "gm" 'woman
+
+    ;; refresh
+    "gr" 'woman-reformat-last-file))
+
+(provide 'evil-collection-woman)
+;;; evil-collection-woman.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-woman.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-woman.elc
new file mode 100644
index 0000000000..0d278e2214
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-woman.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-xref.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-xref.el
new file mode 100644
index 0000000000..c74194d466
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-xref.el
@@ -0,0 +1,54 @@
+;;; evil-collection-xref.el --- Evil bindings for xref -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 James Nguyen
+
+;; Author: James Nguyen <james@jojojames.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, xref, tools
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; Evil bindings for `xref'.
+
+;;; Code:
+(require 'evil-collection)
+(require 'xref)
+
+(defconst evil-collection-xref-maps '(xref--xref-buffer-mode-map))
+
+(defun evil-collection-xref-setup ()
+  "Set up `evil' bindings for `xref'."
+  (evil-collection-define-key 'normal 'xref--xref-buffer-mode-map
+    "q" 'quit-window
+    "gj" 'xref-next-line
+    "gk" 'xref-prev-line
+    (kbd "C-j") 'xref-next-line
+    (kbd "C-k") 'xref-prev-line
+    "]" 'xref-next-line
+    "[" 'xref-prev-line
+    "r" 'xref-query-replace-in-results
+
+    ;; open
+    (kbd "<return>") 'xref-goto-xref
+    (kbd "S-<return>") 'xref-show-location-at-point
+    "o" 'xref-show-location-at-point
+    "go" 'xref-show-location-at-point))
+
+(provide 'evil-collection-xref)
+;;; evil-collection-xref.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-xref.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-xref.elc
new file mode 100644
index 0000000000..cf465e5909
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-xref.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-ztree.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-ztree.el
new file mode 100644
index 0000000000..e7501bef4e
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-ztree.el
@@ -0,0 +1,72 @@
+;;; evil-collection-ztree.el --- Evil bindings for ztree -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 Pierre Neidhardt
+
+;; Author: Pierre Neidhardt <ambrevar@gmail.com>
+;; Maintainer: James Nguyen <james@jojojames.com>, Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: evil, ztree, tools
+
+;; This file 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, or (at your
+;; option) any later version.
+;;
+;; This file 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.
+;;
+;; For a full copy of the GNU General Public License
+;; see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; Evil bindings for ztree.
+
+;;; Code:
+(require 'evil-collection)
+(require 'ztree nil t)
+
+(defvar ztree-mode-map)
+(defvar ztreediff-mode-map)
+
+(defconst evil-collection-ztree-maps '(ztree-mode-map ztreediff-mode-map))
+
+(defun evil-collection-ztree-setup ()
+  "Set up `evil' bindings for `ztree'."
+
+  (evil-collection-inhibit-insert-state 'ztree-mode-map)
+  (evil-set-initial-state 'ztree-mode 'normal)
+  (evil-collection-define-key 'normal 'ztree-mode-map
+    (kbd "<tab>") 'ztree-jump-side
+    (kbd "<return>") 'ztree-perform-action
+    (kbd "SPC") 'ztree-perform-soft-action
+
+    "x" 'ztree-toggle-expand-subtree
+
+    ;; refresh
+    "gr" 'ztree-refresh-buffer
+
+    ;; quit
+    "q" 'quit-window
+    "ZQ" 'quit-window
+    "ZZ" 'quit-window)
+
+  (evil-collection-inhibit-insert-state 'ztreediff-mode-map)
+  (evil-set-initial-state 'ztree-mode 'normal)
+  (evil-define-minor-mode-key 'normal 'ztreediff-mode
+    "C" 'ztree-diff-copy
+    "D" 'ztree-diff-delete-file
+    "zH" 'ztree-diff-toggle-show-filtered-files
+    "d" 'ztree-diff-simple-diff-files
+    "zh" 'ztree-diff-toggle-show-equal-files
+    "gf" 'ztree-diff-view-file
+
+    ;; refresh
+    "gr" 'ztree-diff-partial-rescan
+    "gR" 'ztree-diff-full-rescan))
+
+(provide 'evil-collection-ztree)
+;;; evil-collection-ztree.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-ztree.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-ztree.elc
new file mode 100644
index 0000000000..9191d6ec63
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection-ztree.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection.el b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection.el
new file mode 100644
index 0000000000..f71835aada
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection.el
@@ -0,0 +1,496 @@
+;;; evil-collection.el --- A set of keybindings for Evil mode -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 James Nguyen
+
+;; Author: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; Maintainer: James Nguyen <james@jojojames.com>
+;; Pierre Neidhardt <ambrevar@gmail.com>
+;; URL: https://github.com/emacs-evil/evil-collection
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "25.1") (cl-lib "0.5") (evil "1.2.13"))
+;; Keywords: evil, tools
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; A set of keybindings for Evil mode.
+;;
+;; If you want to use Evil in the minibuffer, you'll have to enable it by
+;; setting `evil-collection-setup-minibuffer' to t before loading this package.
+;; This is so because many users find it confusing.
+;; Some minibuffer-related packages such as Helm rely on this option.
+
+;;; Code:
+(eval-when-compile (require 'subr-x))
+(require 'cl-lib)
+(require 'evil)
+
+(defvar evil-want-integration)
+(if (featurep 'evil-integration)
+    (if evil-want-integration
+        (display-warning
+         '(evil-collection)
+         "Make sure to set `evil-want-integration' to nil before loading evil \
+or evil-collection.")
+      (display-warning
+       '(evil-collection)
+       "`evil-want-integration' was set to nil but not before loading evil."))
+  (require 'evil-collection-integration))
+
+(declare-function org-table-align "org-table.el" nil)
+
+(defgroup evil-collection nil
+  "A set of keybindings for Evil mode"
+  :group 'evil)
+
+(defcustom evil-collection-setup-minibuffer nil
+  "Whether to setup Evil bindings in the minibuffer."
+  :type 'boolean
+  :group 'evil-collection)
+
+(defcustom evil-collection-mode-list
+  `(ace-jump-mode
+    ag
+    alchemist
+    anaconda-mode
+    arc-mode
+    avy
+    bookmark
+    (buff-menu "buff-menu")
+    calc
+    calendar
+    cider
+    cmake-mode
+    comint
+    company
+    compile
+    custom
+    cus-theme
+    daemons
+    debbugs
+    debug
+    diff-mode
+    dired
+    doc-view
+    edebug
+    ediff
+    eldoc
+    elfeed
+    elisp-mode
+    elisp-refs
+    emms
+    epa
+    ert
+    eshell
+    eval-sexp-fu
+    etags-select
+    eww
+    flycheck
+    free-keys
+    geiser
+    ggtags
+    git-timemachine
+    go-mode
+    grep
+    help
+    guix
+    helm
+    ibuffer
+    image
+    image+
+    imenu-list
+    indium
+    info
+    ivy
+    js2-mode
+    log-view
+    lsp-ui-imenu
+    lua-mode
+    kotlin-mode
+    macrostep
+    man
+    magit
+    magit-todos
+    ,@(when evil-collection-setup-minibuffer '(minibuffer))
+    mu4e
+    mu4e-conversation
+    neotree
+    notmuch
+    nov
+    ;; occur is in replace.el which was built-in before Emacs 26.
+    (occur ,(if (<= emacs-major-version 25) "replace" 'replace))
+    outline
+    p4
+    (package-menu package)
+    paren
+    pass
+    (pdf pdf-view)
+    popup
+    proced
+    prodigy
+    profiler
+    python
+    quickrun
+    racer
+    realgud
+    reftex
+    rjsx-mode
+    robe
+    ruby-mode
+    rtags
+    simple
+    slime
+    (term term ansi-term multi-term)
+    tide
+    transmission
+    typescript-mode
+    vc-annotate
+    vdiff
+    view
+    vlf
+    which-key
+    wdired
+    wgrep
+    woman
+    xref
+    (ztree ztree-diff))
+  "The list of modes which will be evilified by `evil-collection-init'.
+Elements are either target mode symbols or lists which `car' is the
+mode symbol and `cdr' the packages to register.
+
+By default, `minibuffer' is not included because many users find
+this confusing. It will be included if
+`evil-collection-setup-minibuffer' is set to t."
+  :type '(repeat (choice symbol sexp))
+  :group 'evil-collection)
+
+(defcustom evil-collection-key-whitelist '()
+  "List of keys that may be used by Evil Collection.
+This is a list of strings that are suitable for input to
+`kbd'.  If there are no keys in the list, the whitelist will be ignored."
+  :type '(repeat string)
+  :group 'evil-collection)
+
+(defcustom evil-collection-key-blacklist '()
+  "List of keys that may not be used by Evil Collection.
+This is a list of strings that are suitable for input to `kbd'."
+  :type '(repeat string)
+  :group 'evil-collection)
+
+(defvar evil-collection--bindings-record (make-hash-table :test 'eq)
+  "Record of bindings currently made by Evil Collection. This is
+a hash-table with the package symbol as a key.  The associated
+values are the package's bindings which are stored as a list of
+the form ((STATE KEY BINDING)).")
+
+(defvar evil-collection-setup-hook nil
+  "Hook run by `evil-collection-init' for each mode that is evilified.
+This hook runs after all setup (including keybindings) for a mode has already
+taken place. The arguments passed to functions for this hook are the name of the
+mode and a list of keymap names (i.e. symbols, not actual keymaps) customized by
+Evil Collection for that mode. More arguments may be added in the future, so
+functions added to this hook should include a \"&rest _rest\" for forward
+compatibility.")
+
+(defvar evil-collection-describe-buffer "*evil-collection*"
+  "Name for Evil Collection buffer used to describe bindings.")
+
+(defun evil-collection-define-key (state map-sym &rest bindings)
+  "Wrapper for `evil-define-key*' with additional features.
+Unlike `evil-define-key*' MAP-SYM should be a quoted keymap other
+than the unquoted keymap required for `evil-define-key*'.  This
+function adds the ability to filter keys on the basis of
+`evil-collection-key-whitelist' and
+`evil-collection-key-blacklist'. It also stores bindings in
+`evil-collection--bindings-record'."
+  (declare (indent defun))
+  (let* ((whitelist (mapcar 'kbd evil-collection-key-whitelist))
+         (blacklist (mapcar 'kbd evil-collection-key-blacklist))
+         (record (gethash map-sym evil-collection--bindings-record))
+         filtered-bindings)
+    (while bindings
+      (let ((key (pop bindings))
+            (def (pop bindings)))
+        (when (or (and whitelist (member key whitelist))
+                  (not (member key blacklist)))
+          (if (consp state)
+              (dolist (st state)
+                (push (list (if st st 'all) (key-description key) def)
+                      record))
+            (push (list (if state state 'all) (key-description key) def)
+                  record))
+          (push key filtered-bindings)
+          (push def filtered-bindings))))
+    (puthash map-sym record evil-collection--bindings-record)
+    (setq filtered-bindings (nreverse filtered-bindings))
+    (cond ((null filtered-bindings))
+          ((and (boundp map-sym) (keymapp (symbol-value map-sym)))
+           (apply #'evil-define-key*
+                  state (symbol-value map-sym) filtered-bindings))
+          ((boundp map-sym)
+           (user-error "evil-collection: %s is not a keymap" map-sym))
+          (t
+           (let* ((fname (format "evil-collection-define-key-in-%s" map-sym))
+                  (fun (make-symbol fname)))
+             (fset fun `(lambda (&rest args)
+                          (when (and (boundp ',map-sym) (keymapp ,map-sym))
+                            (remove-hook 'after-load-functions #',fun)
+                            (apply #'evil-define-key*
+                                   ',state ,map-sym ',filtered-bindings))))
+             (add-hook 'after-load-functions fun t))))))
+
+(defun evil-collection-inhibit-insert-state (map-sym)
+  "Unmap insertion keys from normal state.
+This is particularly useful for read-only modes."
+  (evil-collection-define-key 'normal map-sym
+    [remap evil-append] #'ignore
+    [remap evil-append-line] #'ignore
+    [remap evil-insert] #'ignore
+    [remap evil-insert-line] #'ignore
+    [remap evil-change] #'ignore
+    [remap evil-change-line] #'ignore
+    [remap evil-substitute] #'ignore
+    [remap evil-change-whole-line] #'ignore
+    [remap evil-delete] #'ignore
+    [remap evil-delete-line] #'ignore
+    [remap evil-delete-char] #'ignore
+    [remap evil-delete-backward-char] #'ignore
+    [remap evil-replace] #'ignore
+    [remap evil-replace-state] #'ignore
+    [remap evil-open-below] #'ignore
+    [remap evil-open-above] #'ignore
+    [remap evil-paste-after] #'ignore
+    [remap evil-paste-before] #'ignore
+    [remap evil-join] #'ignore
+    [remap evil-indent] #'ignore
+    [remap evil-shift-left] #'ignore
+    [remap evil-shift-right] #'ignore
+    [remap evil-invert-char] #'ignore))
+
+(defun evil-collection--binding-lessp (a b)
+  "Comparison function used to sort bindings of the form (state key def)."
+  (let ((a-state (symbol-name (nth 0 a)))
+        (b-state (symbol-name (nth 0 b)))
+        (a-key (nth 1 a))
+        (b-key (nth 1 b)))
+    (if (not (string= a-state b-state))
+        (string-lessp a-state b-state)
+      (string-lessp a-key b-key))))
+
+(defun evil-collection-describe-bindings (&optional arg)
+  "Print bindings made by Evil Collection to separate buffer.
+
+With non-nil ARG, restrict to bindings corresponding to active
+modes in the current buffer."
+  (interactive "P")
+  (let ((orig-buf (current-buffer))
+        (desc-buf (get-buffer-create evil-collection-describe-buffer)))
+    (switch-to-buffer-other-window desc-buf)
+    (with-current-buffer desc-buf
+      (erase-buffer)
+      (org-mode)
+      (dolist (keymap
+               (sort (hash-table-keys evil-collection--bindings-record)
+                     (lambda (a b)
+                       (string-lessp (symbol-name a)
+                                     (symbol-name b)))))
+        (when (or (null arg)
+                  (with-current-buffer orig-buf
+                    (and (boundp keymap)
+                         (memq (symbol-value keymap) (current-active-maps)))))
+          (insert "\n\n* " (symbol-name keymap) "\n")
+          (insert "
+| State | Key | Definition |
+|-------|-----|------------|
+")
+          (cl-loop
+           for (state key def) in
+           (sort (copy-sequence
+                  (gethash keymap evil-collection--bindings-record))
+                 #'evil-collection--binding-lessp)
+           do
+           (when (and def (not (eq def 'ignore)))
+             (insert (format "| %s | %s | %s |\n"
+                             state
+                             (replace-regexp-in-string "|" "¦" key)
+                             (cond ((symbolp def) def)
+                                   ((functionp def) "(lambda ...)")
+                                   ((consp def)
+                                    (format "(%s ...)" (car def)))
+                                   (t "??"))))))
+          (org-table-align)))
+      (goto-char (point-min)))))
+
+(defun evil-collection--translate-key (state keymap-symbol
+                                             translations
+                                             destructive)
+  "Helper function for `evil-collection-translate-key'.
+In the keymap corresponding to STATE and KEYMAP-SYMBOL, make the key
+TRANSLATIONS. When DESTRUCTIVE is non-nil, make the TRANSLATIONS destructively
+without creating/referencing a backup keymap."
+  (let* ((backup-keymap-symbol (intern (format "evil-collection-%s%s-backup-map"
+                                               keymap-symbol
+                                               (if state
+                                                   (format "-%s-state" state)
+                                                 ""))))
+         (keymap (symbol-value keymap-symbol))
+         (lookup-keymap (if (and (not destructive)
+                                 (boundp backup-keymap-symbol))
+                            (symbol-value backup-keymap-symbol)
+                          (copy-keymap
+                           (if state
+                               (evil-get-auxiliary-keymap keymap state t t)
+                             keymap))))
+         (maps (cl-loop for (key replacement) on translations by 'cddr
+                        ;; :destructive can be in TRANSLATIONS
+                        unless (keywordp key)
+                        collect key
+                        and collect (when replacement
+                                      (lookup-key lookup-keymap replacement)))))
+    (unless (or destructive
+                (boundp backup-keymap-symbol))
+      (set backup-keymap-symbol lookup-keymap))
+    (apply #'evil-define-key* state keymap maps)))
+
+;;;###autoload
+(cl-defun evil-collection-translate-key (states keymaps
+                                                &rest translations
+                                                &key destructive
+                                                &allow-other-keys)
+  "Translate keys in the keymap(s) corresponding to STATES and KEYMAPS.
+STATES should be the name of an evil state, a list of states, or nil. KEYMAPS
+should be a symbol corresponding to the keymap to make the translations in or a
+list of keymap symbols. Like `evil-define-key', when a keymap does not exist,
+the keybindings will be deferred until the keymap is defined, so
+`with-eval-after-load' is not neccessary. TRANSLATIONS corresponds to a list of
+key replacement pairs. For example, specifying \"a\" \"b\" will bind \"a\" to
+\"b\"'s definition in the keymap. Specifying nil as a replacement will unbind a
+key. If DESTRUCTIVE is nil, a backup of the keymap will be stored on the initial
+invocation, and future invocations will always look up keys in the backup
+keymap. When no TRANSLATIONS are given, this function will only create the
+backup keymap without making any translations. On the other hand, if DESTRUCTIVE
+is non-nil, the keymap will be destructively altered without creating a backup.
+For example, calling this function multiple times with \"a\" \"b\" \"b\" \"a\"
+would continue to swap and unswap the definitions of these keys. This means that
+when DESTRUCTIVE is non-nil, all related swaps/cycles should be done in the same
+invocation."
+  (declare (indent defun))
+  (unless (listp keymaps)
+    (setq keymaps (list keymaps)))
+  (unless (and (listp states)
+               (not (null states)))
+    (setq states (list states)))
+  (dolist (keymap-symbol keymaps)
+    (dolist (state states)
+      (evil-delay `(and (boundp ',keymap-symbol)
+                        (keymapp ,keymap-symbol))
+          `(evil-collection--translate-key ',state ',keymap-symbol
+                                           ',translations ,destructive)
+        'after-load-functions t nil
+        (symbol-name (cl-gensym (format "evil-collection-translate-key-in-%s"
+                                        keymap-symbol)))))))
+
+;;;###autoload
+(defmacro evil-collection-swap-key (states keymaps &rest args)
+  "Wrapper around `evil-collection-translate-key' for swapping keys.
+STATES, KEYMAPS, and ARGS are passed to `evil-collection-translate-key'. ARGS
+should consist of key swaps (e.g. \"a\" \"b\" is equivalent to \"a\" \"b\" \"b\"
+\"a\" with `evil-collection-translate-key') and optionally keyword arguments for
+`evil-collection-translate-key'."
+  (declare (indent defun))
+  (setq args (cl-loop for (key replacement) on args by 'cddr
+                      collect key and collect replacement
+                      and unless (keywordp key)
+                      collect replacement and collect key))
+  `(evil-collection-translate-key ,states ,keymaps ,@args))
+
+;;;###autoload
+(defun evil-collection-init (&optional modes)
+  "Register the Evil bindings for all modes in `evil-collection-mode-list'.
+
+Alternatively, you may register select bindings manually, for
+instance:
+
+  (with-eval-after-load 'calendar
+    (require 'evil-collection-calendar)
+    (evil-collection-calendar-setup))
+
+If MODES is specified (as either one mode or a list of modes), use those modes
+instead of the modes in `evil-collection-mode-list'."
+  (interactive)
+  (if modes
+      (or (listp modes) (setq modes (list modes)))
+    (setq modes evil-collection-mode-list))
+  (dolist (mode modes)
+    (let ((m mode)
+          (reqs (list mode)))
+      (when (listp mode)
+        (setq m (car mode)
+              reqs (cdr mode)))
+      (dolist (req reqs)
+        (with-eval-after-load req
+          (require (intern (concat "evil-collection-" (symbol-name m))))
+          (funcall (intern (concat "evil-collection-" (symbol-name m)
+                                   "-setup")))
+          (let ((mode-keymaps
+                 (ignore-errors
+                   (symbol-value
+                    (intern (format "evil-collection-%s-maps" m))))))
+            (run-hook-with-args 'evil-collection-setup-hook
+                                m mode-keymaps)))))))
+
+(defvar evil-collection-delete-operators '(evil-delete
+                                           evil-cp-delete
+                                           evil-sp-delete
+                                           lispyville-delete)
+  "List of delete operators.")
+
+(defvar evil-collection-yank-operators '(evil-yank
+                                         evil-cp-yank
+                                         evil-sp-yank
+                                         lispyville-yank)
+  "List of yank operators.")
+
+;;* Search
+
+(defun evil-collection-evil-search-enabled ()
+  (eq evil-search-module 'evil-search))
+
+(defvar evil-collection-evil-search-forward
+  '(menu-item "" nil :filter (lambda (&optional _)
+                               (if (eq evil-search-module 'evil-search)
+                                   #'evil-ex-search-forward
+                                 #'evil-search-forward))))
+
+(defvar evil-collection-evil-search-backward
+  '(menu-item "" nil :filter (lambda (&optional _)
+                               (if (eq evil-search-module 'evil-search)
+                                   #'evil-ex-search-backward
+                                 #'evil-search-backward))))
+
+(defvar evil-collection-evil-search-next
+  '(menu-item "" nil :filter (lambda (&optional _)
+                               (if (eq evil-search-module 'evil-search)
+                                   #'evil-ex-search-next
+                                 #'evil-search-next))))
+
+(defvar evil-collection-evil-search-previous
+  '(menu-item "" nil :filter (lambda (&optional _)
+                               (if (eq evil-search-module 'evil-search)
+                                   #'evil-ex-search-previous
+                                 #'evil-search-previous))))
+
+(provide 'evil-collection)
+;;; evil-collection.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection.elc b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection.elc
new file mode 100644
index 0000000000..5a07929b0b
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-collection-20180720.526/evil-collection.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-commentary-20170413.751/evil-commentary-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/evil-commentary-20170413.751/evil-commentary-autoloads.el
new file mode 100644
index 0000000000..6717b8c0aa
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-commentary-20170413.751/evil-commentary-autoloads.el
@@ -0,0 +1,45 @@
+;;; evil-commentary-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "evil-commentary" "evil-commentary.el" (23377
+;;;;;;  61304 663704 433000))
+;;; Generated autoloads from evil-commentary.el
+
+(defvar evil-commentary-mode nil "\
+Non-nil if Evil-Commentary mode is enabled.
+See the `evil-commentary-mode' command
+for a description of this minor mode.")
+
+(custom-autoload 'evil-commentary-mode "evil-commentary" nil)
+
+(autoload 'evil-commentary-mode "evil-commentary" "\
+Commentary mode.
+
+\(fn &optional ARG)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "evil-commentary-integration" "evil-commentary-integration.el"
+;;;;;;  (23377 61304 667431 263000))
+;;; Generated autoloads from evil-commentary-integration.el
+
+(autoload 'evil-commentary/org-comment-or-uncomment-region "evil-commentary-integration" "\
+Comment function for `org-mode'.
+
+\(fn BEG END)" t nil)
+
+;;;***
+
+;;;### (autoloads nil nil ("evil-commentary-pkg.el") (23377 61304
+;;;;;;  665630 323000))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; evil-commentary-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-commentary-20170413.751/evil-commentary-integration.el b/configs/shared/emacs/.emacs.d/elpa/evil-commentary-20170413.751/evil-commentary-integration.el
new file mode 100644
index 0000000000..0d2760e730
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-commentary-20170413.751/evil-commentary-integration.el
@@ -0,0 +1,37 @@
+(declare-function org-in-src-block-p "org")
+
+(defmacro evil-commentary/org-babel-do-in-edit-buffer (beg end &rest body)
+  "Do `org-babel-do-in-edit-buffer' and restore view.
+
+Return the same value as `org-babel-do-in-edit-buffer'. Save top
+line of current window and restore it if sucess."
+  (declare (indent defun))
+  `(when (and (fboundp 'org-babel-do-in-edit-buffer)
+              (org-in-src-block-p t))
+     (let ((top-line (line-number-at-pos (window-start)))
+           (current-point (point))
+           found)
+       (push-mark ,beg)
+       (goto-char ,end)
+       (setq mark-active t)
+       (setq found (eval '(org-babel-do-in-edit-buffer
+                             ,@body)))
+       (pop-mark)
+       (if (not found)
+           (goto-char current-point)
+         (save-excursion
+           (scroll-up 1)              ; stupid fix
+           (goto-char (point-min))
+           (forward-line (1- top-line))
+           (recenter 0)))
+       found)))
+
+;;;###autoload
+(defun evil-commentary/org-comment-or-uncomment-region (beg end)
+  "Comment function for `org-mode'."
+  (interactive "r")
+  (unless (evil-commentary/org-babel-do-in-edit-buffer beg end
+            (call-interactively 'evil-commentary))
+    (comment-or-uncomment-region beg end)))
+
+(provide 'evil-commentary-integration)
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-commentary-20170413.751/evil-commentary-integration.elc b/configs/shared/emacs/.emacs.d/elpa/evil-commentary-20170413.751/evil-commentary-integration.elc
new file mode 100644
index 0000000000..d0a71de3a9
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-commentary-20170413.751/evil-commentary-integration.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-commentary-20170413.751/evil-commentary-pkg.el b/configs/shared/emacs/.emacs.d/elpa/evil-commentary-20170413.751/evil-commentary-pkg.el
new file mode 100644
index 0000000000..0797dac165
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-commentary-20170413.751/evil-commentary-pkg.el
@@ -0,0 +1,8 @@
+(define-package "evil-commentary" "20170413.751" "Comment stuff out. A port of vim-commentary."
+  '((evil "1.0.0"))
+  :keywords
+  '("evil" "comment" "commentary" "evil-commentary")
+  :url "http://github.com/linktohack/evil-commentary")
+;; Local Variables:
+;; no-byte-compile: t
+;; End:
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-commentary-20170413.751/evil-commentary.el b/configs/shared/emacs/.emacs.d/elpa/evil-commentary-20170413.751/evil-commentary.el
new file mode 100644
index 0000000000..702d320b3f
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-commentary-20170413.751/evil-commentary.el
@@ -0,0 +1,121 @@
+;;; evil-commentary.el --- Comment stuff out. A port of vim-commentary.
+
+;; Copyright (C) 2014 Quang Linh LE
+
+;; Author: Quang Linh LE <linktohack@gmail.com>
+;; URL: http://github.com/linktohack/evil-commentary
+;; Version: 2.1.1
+;; Keywords: evil comment commentary evil-commentary
+;; Package-Requires: ((evil "1.0.0"))
+
+;; This file is not part of GNU Emacs.
+
+;;; License:
+
+;; This file is part of evil-commentary
+;;
+;; evil-commentary 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.
+;;
+;; evil-commentary 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;
+;; This program emulates evil-commentary initially developed by Tim Pope
+;; (tpope) It help you comment line with `counts` and `motions`.
+
+;;; Example:
+;;
+;; `gcc` to comment/uncomment a line
+;; `5gcc` to comment/uncomment 5 lines
+;; `gc$` to comment/uncomment from current position
+;; `gcap` to comment/uncomment current paragraph
+
+
+;;; Code:
+
+(require 'evil)
+(require 'evil-commentary-integration)
+
+(defgroup evil-commentary nil
+  "Comment stuff out"
+  :group 'evil
+  :prefix "evil-commentary-")
+
+(defcustom evil-commentary-comment-function-for-mode-alist
+  '((org-mode . evil-commentary/org-comment-or-uncomment-region)
+    (f90-mode . f90-comment-region)
+    (web-mode . web-mode-comment-or-uncomment-region))
+  "Mode-specific comment function.
+
+By default, `evil-commentary' use `comment-or-uncomment'
+function. By specify an alist of modes here, the comment function
+provided by major mode will be use instead.
+
+A comment functions has to accept BEG, END as its required
+parameter."
+  :group 'evil-commentary
+  :type '(alist :key-type symbol :value-type function))
+
+(evil-define-operator evil-commentary (beg end type)
+  "Comment or uncomment region that {motion} moves over."
+  :move-point nil
+  (interactive "<R>")
+  (let ((comment-function
+         (cdr (assoc major-mode
+                     evil-commentary-comment-function-for-mode-alist))))
+    (if comment-function (funcall comment-function beg end)
+      (comment-or-uncomment-region beg end))))
+
+(evil-define-operator evil-commentary-line (beg end type)
+  "Comment or uncomment [count] lines."
+  :motion evil-line
+  :move-point nil
+  (interactive "<R>")
+  (when (evil-visual-state-p)
+    (unless (memq type '(line block))
+      (let ((range (evil-expand beg end 'line)))
+        (setq beg (evil-range-beginning range)
+              end (evil-range-end range)
+              type (evil-type range))))
+    (evil-exit-visual-state))
+  (evil-commentary beg end type))
+
+(evil-define-operator evil-commentary-yank (beg end type register yank-handler)
+  "Saves the characters in motion into the kill-ring."
+  :move-point nil
+  :repeat nil
+  (interactive "<R><x><y>")
+  (evil-yank beg end type register yank-handler)
+  (evil-commentary beg end))
+
+(evil-define-operator evil-commentary-yank-line (beg end type register)
+  "Saves whole lines into the kill-ring."
+  :motion evil-line
+  :move-point nil
+  (interactive "<R><x>")
+  (evil-yank-line beg end type register)
+  (evil-commentary-line beg end))
+
+;;;###autoload
+(define-minor-mode evil-commentary-mode
+  "Commentary mode."
+  :lighter " s-/"
+  :global t
+  :keymap (let ((map (make-sparse-keymap)))
+            (evil-define-key 'normal map "gc" 'evil-commentary)
+            (evil-define-key 'normal map "gy" 'evil-commentary-yank)
+            (define-key map (kbd "s-/") 'evil-commentary-line)
+            map))
+
+(provide 'evil-commentary)
+
+;;; evil-commentary.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-commentary-20170413.751/evil-commentary.elc b/configs/shared/emacs/.emacs.d/elpa/evil-commentary-20170413.751/evil-commentary.elc
new file mode 100644
index 0000000000..2e6a041c56
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-commentary-20170413.751/evil-commentary.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-leader-20140606.543/evil-leader-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/evil-leader-20140606.543/evil-leader-autoloads.el
new file mode 100644
index 0000000000..32282ded9f
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-leader-20140606.543/evil-leader-autoloads.el
@@ -0,0 +1,42 @@
+;;; evil-leader-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "evil-leader" "evil-leader.el" (23377 61304
+;;;;;;  362906 261000))
+;;; Generated autoloads from evil-leader.el
+
+(autoload 'global-evil-leader-mode "evil-leader" "\
+Global minor mode for <leader> support.
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'evil-leader-mode "evil-leader" "\
+Minor mode to enable <leader> support.
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'evil-leader/set-key "evil-leader" "\
+Bind `key' to command `def' in `evil-leader/default-map'.
+
+Key has to be readable by `read-kbd-macro' and `def' a command.
+Accepts further `key' `def' pairs.
+
+\(fn KEY DEF &rest BINDINGS)" t nil)
+
+(autoload 'evil-leader/set-key-for-mode "evil-leader" "\
+Create keybindings for major-mode `mode' with `key' bound to command `def'.
+
+See `evil-leader/set-key'.
+
+\(fn MODE KEY DEF &rest BINDINGS)" t nil)
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; evil-leader-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-leader-20140606.543/evil-leader-pkg.el b/configs/shared/emacs/.emacs.d/elpa/evil-leader-20140606.543/evil-leader-pkg.el
new file mode 100644
index 0000000000..23d8bc0e7b
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-leader-20140606.543/evil-leader-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "evil-leader" "20140606.543" "let there be <leader>" '((evil "0")))
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-leader-20140606.543/evil-leader.el b/configs/shared/emacs/.emacs.d/elpa/evil-leader-20140606.543/evil-leader.el
new file mode 100644
index 0000000000..55bcf871ac
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-leader-20140606.543/evil-leader.el
@@ -0,0 +1,213 @@
+;;; evil-leader.el --- let there be <leader>
+
+;; Copyright (C) 2011-2013 by Michael Markert
+;; Author: Michael Markert <markert.michael@googlemail.com>
+;; URL: http://github.com/cofi/evil-leader
+;; Package-Version: 20140606.543
+;; Git-Repository: git://github.com/cofi/evil-leader.git
+;; Created: 2011-09-13
+;; Version: 0.4.3
+;; Keywords: evil vim-emulation leader
+;; Package-Requires: ((evil "0"))
+
+;; This file is not part of GNU Emacs.
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;
+;; Known Bugs:
+;; See http://github.com/cofi/evil-leader/issues
+
+;; Install:
+;; (require 'evil-leader)
+
+;; Usage:
+;;
+;; (global-evil-leader-mode)
+;;
+;;    to enable `evil-leader' in every buffer where `evil' is enabled.
+;;
+;;    Note: You should enable `global-evil-leader-mode' before you enable
+;;          `evil-mode', otherwise `evil-leader' won't be enabled in initial
+;;          buffers (*scratch*, *Messages*, ...).
+;;
+;;    Use `evil-leader/set-key' to bind keys in the leader map.
+;;    For example:
+;;
+;; (evil-leader/set-key "e" 'find-file)
+;;
+;;    You can also bind several keys at once:
+;;
+;; (evil-leader/set-key
+;;   "e" 'find-file
+;;   "b" 'switch-to-buffer
+;;   "k" 'kill-buffer)
+;;
+;;    The key map can of course be filled in several places.
+;;
+;;    After you set up the key map you can access the bindings by pressing =<leader>=
+;;    (default: \) and the key(s). E.g. \ e would call `find-file' to open a file.
+;;
+;;    If you wish to change so you can customize =evil-leader/leader= or call
+;;    `evil-leader/set-leader', e.g. (evil-leader/set-leader ",") to change it to
+;;    ",".
+;;    The leader has to be readable by `read-kbd-macro', so using Space as a
+;;    prefix key would be (evil-leader/set-leader "<SPC>").
+;;
+;;    Beginning with version 0.3 evil-leader has support for mode-local bindings:
+;;
+;; (evil-leader/set-key-for-mode 'emacs-lisp-mode "b" 'byte-compile-file)
+;;
+;;    Again, you can bind several keys at once.
+;;
+;;    A mode-local binding shadows a normal mode-independent binding.
+
+;;; Code:
+
+(require 'evil)
+
+(defvar evil-leader--default-map (make-sparse-keymap)
+  "Keymap used for mode-independent leader bindings.")
+
+(defvar evil-leader--mode-maps nil
+  "Alist of mode-local leader bindings, shadows mode-independent bindings.")
+
+;;; customization
+(defgroup evil-leader nil
+  "<leader> support for evil."
+  :group 'evil
+  :prefix 'evil-leader/)
+
+(defcustom evil-leader/leader "\\"
+  "The <leader> key, used to access keys defined by `evil-leader/set-key' in normal and visual state.
+Must be readable by `read-kbd-macro'. For example: \",\"."
+  :type 'string
+  :group 'evil-leader)
+
+(defcustom evil-leader/non-normal-prefix "C-"
+  "Prefix for leader-map in insert- and emacs-state.
+`evil-leader/in-all-states' has to be non-nil for this to be set.
+The combination has to be readable by `read-kbd-macro'."
+  :type 'string
+  :group 'evil-leader)
+
+(defcustom evil-leader/no-prefix-mode-rx nil
+  "List of regular expressions for mode names where `evil-leader/leader' is used regardless of the state.
+
+If the current major mode is matched by one of the regular expressions
+`evil-leader/leader' is installed in emacs/insert state without
+the prefix additionally to the prefixed key.
+
+`evil-leader/in-all-states' has to be non-nil for this setting to have any effect."
+  :type 'list
+  :group 'evil-leader)
+
+(defcustom evil-leader/in-all-states nil
+  "If is non-nil leader-map is accessible by <prefixed-leader> in emacs/insert state.
+
+<prefixed-leader> is `evil-leader/non-normal-prefix' + `evil-leader/leader'"
+  :type 'boolean
+  :group 'evil-leader)
+
+;;;###autoload
+(define-minor-mode global-evil-leader-mode
+  "Global minor mode for <leader> support."
+  nil nil nil
+  (if global-evil-leader-mode
+      (add-hook 'evil-local-mode-hook #'evil-leader-mode t)
+    (remove-hook 'evil-local-mode-hook #'evil-leader-mode t)))
+
+;;;###autoload
+(define-minor-mode evil-leader-mode
+  "Minor mode to enable <leader> support."
+  :init-value nil
+  :keymap nil
+  (let* ((prefixed (read-kbd-macro (concat evil-leader/non-normal-prefix evil-leader/leader)))
+         (no-prefix (read-kbd-macro evil-leader/leader))
+         (mode-map (cdr (assoc major-mode evil-leader--mode-maps)))
+         (map (or mode-map evil-leader--default-map))
+         (no-prefix-rx (if evil-leader/no-prefix-mode-rx
+                           (mapconcat #'identity evil-leader/no-prefix-mode-rx "\\|")
+                         nil)))
+    (if evil-leader-mode
+        (progn
+          (evil-normalize-keymaps)
+          (define-key evil-motion-state-local-map no-prefix map)
+          (define-key evil-normal-state-local-map no-prefix map)
+          (when evil-leader/in-all-states
+            (define-key evil-emacs-state-local-map prefixed map)
+            (define-key evil-insert-state-local-map prefixed map))
+          (when (and no-prefix-rx (string-match-p no-prefix-rx (symbol-name major-mode)))
+            (define-key evil-emacs-state-local-map no-prefix map)
+            (define-key evil-insert-state-local-map no-prefix map)))
+      (define-key evil-motion-state-local-map no-prefix nil)
+      (define-key evil-normal-state-local-map no-prefix nil)
+      (when evil-leader/in-all-states
+        (define-key evil-emacs-state-local-map prefixed nil)
+        (define-key evil-insert-state-local-map prefixed nil)
+        (when (and no-prefix-rx (string-match-p no-prefix-rx (symbol-name major-mode)))
+          (define-key evil-emacs-state-local-map no-prefix nil)
+          (define-key evil-insert-state-local-map no-prefix nil))))))
+
+(defun evil-leader/set-leader (key &optional prefix)
+  "Set leader key to `key' and non-normal-prefix to `prefix' and remove old bindings.
+
+Passing `nil' as `prefix' leaves prefix unchanged."
+  (let ((global-on global-evil-leader-mode)
+        (local-on evil-leader-mode))
+    (when local-on
+      (evil-leader-mode -1))
+    (when global-on
+      (global-evil-leader-mode -1))
+    (setq evil-leader/leader key)
+    (when prefix
+      (setq evil-leader/non-normal-prefix prefix))
+    (if global-on
+        (global-evil-leader-mode 1)
+      (when local-on
+        (evil-leader-mode 1)))))
+
+;;;###autoload
+(defun evil-leader/set-key (key def &rest bindings)
+  "Bind `key' to command `def' in `evil-leader/default-map'.
+
+Key has to be readable by `read-kbd-macro' and `def' a command.
+Accepts further `key' `def' pairs."
+  (interactive "kKey: \naCommand: ")
+  (evil-leader--def-keys evil-leader--default-map key def bindings))
+(put 'evil-leader/set-key 'lisp-indent-function 'defun)
+
+;;;###autoload
+(defun evil-leader/set-key-for-mode (mode key def &rest bindings)
+  "Create keybindings for major-mode `mode' with `key' bound to command `def'.
+
+See `evil-leader/set-key'."
+  (interactive "SMode: \nkKey: \naCommand: ")
+  (let ((mode-map (cdr (assoc mode evil-leader--mode-maps))))
+    (unless mode-map
+      (setq mode-map (make-sparse-keymap))
+      (set-keymap-parent mode-map evil-leader--default-map)
+      (push (cons mode mode-map) evil-leader--mode-maps))
+    (evil-leader--def-keys mode-map key def bindings)))
+(put 'evil-leader/set-key-for-mode 'lisp-indent-function 'defun)
+
+(defun evil-leader--def-keys (map key def bindings)
+  (while key
+    (define-key map (read-kbd-macro key) def)
+    (setq key (pop bindings)
+          def (pop bindings))))
+
+(provide 'evil-leader)
+;;; evil-leader.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-leader-20140606.543/evil-leader.elc b/configs/shared/emacs/.emacs.d/elpa/evil-leader-20140606.543/evil-leader.elc
new file mode 100644
index 0000000000..e7ec165a39
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-leader-20140606.543/evil-leader.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-surround-20180102.601/evil-surround-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/evil-surround-20180102.601/evil-surround-autoloads.el
new file mode 100644
index 0000000000..99ffa8e39b
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-surround-20180102.601/evil-surround-autoloads.el
@@ -0,0 +1,70 @@
+;;; evil-surround-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "evil-surround" "evil-surround.el" (23377 61304
+;;;;;;  963854 412000))
+;;; Generated autoloads from evil-surround.el
+
+(autoload 'evil-surround-delete "evil-surround" "\
+Delete the surrounding delimiters represented by CHAR.
+Alternatively, the text to delete can be represented with
+the overlays OUTER and INNER, where OUTER includes the delimiters
+and INNER excludes them. The intersection (i.e., difference)
+between these overlays is what is deleted.
+
+\(fn CHAR &optional OUTER INNER)" t nil)
+
+(autoload 'evil-surround-change "evil-surround" "\
+Change the surrounding delimiters represented by CHAR.
+Alternatively, the text to delete can be represented with the
+overlays OUTER and INNER, which are passed to `evil-surround-delete'.
+
+\(fn CHAR &optional OUTER INNER)" t nil)
+
+(autoload 'evil-surround-mode "evil-surround" "\
+Buffer-local minor mode to emulate surround.vim.
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'turn-on-evil-surround-mode "evil-surround" "\
+Enable evil-surround-mode in the current buffer.
+
+\(fn)" nil nil)
+
+(autoload 'turn-off-evil-surround-mode "evil-surround" "\
+Disable evil-surround-mode in the current buffer.
+
+\(fn)" nil nil)
+
+(defvar global-evil-surround-mode nil "\
+Non-nil if Global Evil-Surround mode is enabled.
+See the `global-evil-surround-mode' command
+for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `global-evil-surround-mode'.")
+
+(custom-autoload 'global-evil-surround-mode "evil-surround" nil)
+
+(autoload 'global-evil-surround-mode "evil-surround" "\
+Toggle Evil-Surround mode in all buffers.
+With prefix ARG, enable Global Evil-Surround mode if ARG is positive;
+otherwise, disable it.  If called from Lisp, enable the mode if
+ARG is omitted or nil.
+
+Evil-Surround mode is enabled in all buffers where
+`turn-on-evil-surround-mode' would do it.
+See `evil-surround-mode' for more information on Evil-Surround mode.
+
+\(fn &optional ARG)" t nil)
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; evil-surround-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-surround-20180102.601/evil-surround-pkg.el b/configs/shared/emacs/.emacs.d/elpa/evil-surround-20180102.601/evil-surround-pkg.el
new file mode 100644
index 0000000000..1e1535bfef
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-surround-20180102.601/evil-surround-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "evil-surround" "20180102.601" "emulate surround.vim from Vim" '((evil "1.2.12")))
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-surround-20180102.601/evil-surround.el b/configs/shared/emacs/.emacs.d/elpa/evil-surround-20180102.601/evil-surround.el
new file mode 100644
index 0000000000..c0b74b9f7a
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-surround-20180102.601/evil-surround.el
@@ -0,0 +1,436 @@
+;;; evil-surround.el --- emulate surround.vim from Vim
+
+;; Copyright (C) 2010 - 2017 Tim Harper
+
+;; Licensed under the same terms as Emacs (GPLv3)
+
+;;
+;; Author: Tim Harper <timcharper at gmail dot com>
+;;      Vegard Øye <vegard_oye at hotmail dot com>
+;; Current Maintainer: ninrod (github.com/ninrod)
+;; Created: July 23 2011
+;; Version: 0.1
+;; Package-Version: 20180102.601
+;; Package-Requires: ((evil "1.2.12"))
+;; Mailing list: <implementations-list at lists.ourproject.org>
+;;      Subscribe: http://tinyurl.com/implementations-list
+;;      Newsgroup: nntp://news.gmane.org/gmane.emacs.vim-emulation
+;;      Archives: http://dir.gmane.org/gmane.emacs.vim-emulation
+;; Keywords: emulation, vi, evil
+;;
+;; This file is not part of GNU Emacs.
+
+;;; Commentary:
+
+;; This package emulates surround.vim by Tim Pope.
+;; The functionality is wrapped into a minor mode. To enable
+;; it globally, add the following lines to ~/.emacs:
+;;
+;;     (require 'evil-surround)
+;;     (global-evil-surround-mode 1)
+;;
+;; Alternatively, you can enable evil-surround-mode along a major mode
+;; by adding `turn-on-evil-surround-mode' to the mode hook.
+;;
+;; This package uses Evil as its vi layer. It is available from:
+;;
+;;     https://github.com/emacs-evil/evil
+
+;;; Code:
+
+(require 'evil)
+
+(defgroup evil-surround nil
+  "surround.vim for Emacs"
+  :prefix "evil-surround-"
+  :group 'evil)
+
+;; make surround's `ysw' work like `cw', not `ce'
+(when (boundp 'evil-change-commands)
+  (add-to-list 'evil-change-commands 'evil-surround-region))
+
+(defcustom evil-surround-pairs-alist
+  '((?\( . ("( " . " )"))
+    (?\[ . ("[ " . " ]"))
+    (?\{ . ("{ " . " }"))
+
+    (?\) . ("(" . ")"))
+    (?\] . ("[" . "]"))
+    (?\} . ("{" . "}"))
+
+    (?# . ("#{" . "}"))
+    (?b . ("(" . ")"))
+    (?B . ("{" . "}"))
+    (?> . ("<" . ">"))
+    (?t . evil-surround-read-tag)
+    (?< . evil-surround-read-tag)
+    (?f . evil-surround-function))
+  "Association list of surround items.
+Each item is of the form (TRIGGER . (LEFT . RIGHT)), all strings.
+Alternatively, a function can be put in place of (LEFT . RIGHT).
+This only affects inserting pairs, not deleting or changing them."
+  :group 'evil-surround
+  :type '(alist
+          :key-type (character :tag "Key")
+          :value-type (choice
+                       (cons (string :tag "Opening") (string :tag "Closing"))
+                       (function :tag "Function"))))
+(make-variable-buffer-local 'evil-surround-pairs-alist)
+
+(defcustom evil-surround-lisp-modes '(
+				      cider-repl-mode
+				      clojure-mode
+				      clojurec-mode
+				      clojurescript-mode
+				      clojurex-mode
+				      common-lisp-mode
+				      emacs-lisp-mode
+				      eshell-mode
+				      geiser-repl-mode
+				      inf-clojure-mode
+				      inferior-emacs-lisp-mode
+				      inferior-lisp-mode
+				      inferior-scheme-mode
+				      lisp-interaction-mode
+				      lisp-mode
+				      monroe-mode
+				      racket-mode
+				      racket-repl-mode
+				      scheme-interaction-mode
+				      scheme-mode
+				      slime-repl-mode
+				      stumpwm-mode
+				      )
+  "List of Lisp-related modes."
+  :type '(repeat symbol)
+  :group 'evil-surround)
+
+(defcustom evil-surround-operator-alist
+  '((evil-change . change)
+    (evil-delete . delete))
+  "Association list of operators to their fundamental operation.
+Each item is of the form (OPERATOR . OPERATION)."
+  :group 'evil-surround
+  :type '(repeat (cons (symbol :tag "Operator")
+                       (symbol :tag "Operation"))))
+
+(defvar evil-surround-read-tag-map
+  (let ((map (copy-keymap minibuffer-local-map)))
+    (define-key map ">" 'exit-minibuffer)
+    map)
+  "Keymap used by `evil-surround-read-tag'.")
+
+(defvar evil-surround-record-repeat nil
+  "Flag to indicate we're manually recording repeat info.")
+
+(defun evil-surround-read-from-minibuffer (&rest args)
+  (when evil-surround-record-repeat
+    (evil-repeat-keystrokes 'post))
+  (let ((res (apply #'read-from-minibuffer args)))
+    (when evil-surround-record-repeat
+      (evil-repeat-record res))
+    res))
+
+(defun evil-surround-function ()
+  "Read a functionname from the minibuffer and wrap selection in function call"
+  (let ((fname (evil-surround-read-from-minibuffer "" "")))
+    (cons (format (if (member major-mode evil-surround-lisp-modes)
+		      "(%s " "%s(")
+		  (or fname "")) ")")))
+
+(defun evil-surround-read-tag ()
+  "Read a XML tag from the minibuffer."
+  (let* ((input (evil-surround-read-from-minibuffer "<" "" evil-surround-read-tag-map))
+         (match (string-match "\\([0-9a-z-]+\\)\\(.*?\\)[>]*$" input))
+         (tag  (match-string 1 input))
+         (rest (match-string 2 input)))
+    (cons (format "<%s%s>" (or tag "") (or rest ""))
+          (format "</%s>" (or tag "")))))
+
+(defun evil-surround-valid-char-p (char)
+  "Returns whether CHAR is a valid surround char or not."
+  (not (memq char '(?\C-\[ ?\C-?))))
+
+(defun evil-surround-pair (char)
+  "Return the evil-surround pair of char.
+This is a cons cell (LEFT . RIGHT), both strings."
+  (let ((pair (assoc-default char evil-surround-pairs-alist)))
+    (cond
+     ((functionp pair)
+      (funcall pair))
+
+     ((consp pair)
+      pair)
+
+     (t
+      (cons (format "%c" char) (format "%c" char))))))
+
+(defun evil-surround-outer-overlay (char)
+  "Return outer overlay for the delimited range represented by CHAR.
+This overlay includes the delimiters.
+See also `evil-surround-inner-overlay'."
+  (let ((outer (lookup-key evil-outer-text-objects-map (string char))))
+    (when (functionp outer)
+      (setq outer (funcall outer))
+      (when (evil-range-p outer)
+        (evil-surround-trim-whitespace-from-range outer "[[:space:]]")
+        (setq outer (make-overlay (evil-range-beginning outer)
+                                  (evil-range-end outer)
+                                  nil nil t))))))
+
+(defun evil-surround-trim-whitespace-from-range (range &optional regexp)
+  "Given an evil-range, trim whitespace around range by shrinking the range such that it neither begins nor ends with whitespace. Does not modify the buffer."
+  (let ((regexp (or regexp "[ \f\t\n\r\v]")))
+    (save-excursion
+      (save-match-data
+        (goto-char (evil-range-beginning range))
+        (while (looking-at regexp) (forward-char))
+        (evil-set-range-beginning range (point))
+        (goto-char (evil-range-end range))
+        (while (looking-back regexp nil) (backward-char))
+        (evil-set-range-end range (point))))))
+
+(defun evil-surround-inner-overlay (char)
+  "Return inner overlay for the delimited range represented by CHAR.
+This overlay excludes the delimiters.
+See also `evil-surround-outer-overlay'."
+  (let ((inner (lookup-key evil-inner-text-objects-map (string char))))
+    (when (functionp inner)
+      (setq inner (funcall inner))
+      (when (evil-range-p inner)
+        (when (eq (char-syntax char) ?\()
+          (evil-surround-trim-whitespace-from-range inner "[[:space:]]"))
+        (setq inner (make-overlay (evil-range-beginning inner)
+                                  (evil-range-end inner)
+                                  nil nil t))))))
+
+(evil-define-motion evil-surround-line (count)
+  "Move COUNT - 1 lines down but return exclusive character motion."
+  :type exclusive
+  (let ((beg (line-beginning-position)))
+    (evil-line count)
+    (end-of-line)
+    (let ((range (evil-range beg (point) 'exclusive)))
+      (evil-expand-range range)
+      range)))
+
+;;;###autoload
+(defun evil-surround-delete (char &optional outer inner)
+  "Delete the surrounding delimiters represented by CHAR.
+Alternatively, the text to delete can be represented with
+the overlays OUTER and INNER, where OUTER includes the delimiters
+and INNER excludes them. The intersection (i.e., difference)
+between these overlays is what is deleted."
+  (interactive "c")
+  (cond
+   ((and outer inner)
+    (delete-region (overlay-start outer) (overlay-start inner))
+    (delete-region (overlay-end inner) (overlay-end outer))
+    (goto-char (overlay-start outer)))
+   (t
+    ;; no overlays specified: create them on the basis of CHAR
+    ;; and delete after use
+    (let* ((outer (evil-surround-outer-overlay char))
+           (inner (evil-surround-inner-overlay char)))
+      (unwind-protect
+          (when (and outer inner)
+            (evil-surround-delete char outer inner))
+        (when outer (delete-overlay outer))
+        (when inner (delete-overlay inner)))))))
+
+;;;###autoload
+(defun evil-surround-change (char &optional outer inner)
+  "Change the surrounding delimiters represented by CHAR.
+Alternatively, the text to delete can be represented with the
+overlays OUTER and INNER, which are passed to `evil-surround-delete'."
+  (interactive "c")
+  (cond
+   ((and outer inner)
+    (evil-surround-delete char outer inner)
+    (let ((key (read-char)))
+      (evil-surround-region (overlay-start outer)
+                            (overlay-end outer)
+                            nil (if (evil-surround-valid-char-p key) key char))))
+   (t
+    (let* ((outer (evil-surround-outer-overlay char))
+           (inner (evil-surround-inner-overlay char)))
+      (unwind-protect
+          (when (and outer inner)
+            (evil-surround-change char outer inner))
+        (when outer (delete-overlay outer))
+        (when inner (delete-overlay inner)))))))
+
+(defun evil-surround-interactive-setup ()
+  (setq evil-inhibit-operator t)
+     (list (assoc-default evil-this-operator
+                          evil-surround-operator-alist)))
+
+(defun evil-surround-setup-surround-line-operators ()
+  (define-key evil-operator-shortcut-map "s" 'evil-surround-line)
+  (define-key evil-operator-shortcut-map "S" 'evil-surround-line))
+
+(defun evil-surround-column-at (pos)
+  (save-excursion (goto-char pos) (current-column)))
+
+(defun evil-surround-block (beg end char)
+  "Surrounds a block selection with a character, as if `evil-surround-region'
+were called on each segment in each line. This skips lines where EOL < BEG's
+column."
+  (let ((beg-col (evil-surround-column-at beg))
+        (end-col (evil-surround-column-at end)))
+    (evil-apply-on-block
+     (lambda (ibeg iend)
+       (unless (< (evil-surround-column-at ibeg) (min beg-col end-col))
+         (evil-surround-region ibeg iend t char)))
+     beg end nil)))
+
+(defun evil-surround-call-with-repeat (callback)
+  "Record keystrokes to repeat surround-region operator and it's motion.
+This is necessary because `evil-yank' operator is not repeatable (:repeat nil)"
+  (evil-repeat-start)
+  (evil-repeat-record "y")
+  (evil-repeat-record (this-command-keys))
+
+  ;; set `this-command-keys' to the command that will be executed
+  ;; interactively; as a result, `evil-this-operator' will be
+  ;; correctly set to, for example, `evil-surround-region' instead of
+  ;; `evil-yank' when surround has been invoked by `ys'
+  (setq this-command callback)
+  (let ((evil-surround-record-repeat t))
+    (call-interactively callback))
+  (evil-repeat-keystrokes 'post)
+  (evil-repeat-stop))
+
+;; Dispatcher function in Operator-Pending state.
+;; "cs" calls `evil-surround-change', "ds" calls `evil-surround-delete',
+;; and "ys" calls `evil-surround-region'.
+(evil-define-command evil-surround-edit (operation)
+  "Edit the surrounding delimiters represented by CHAR.
+If OPERATION is `change', call `evil-surround-change'.
+if OPERATION is `delete', call `evil-surround-delete'.
+Otherwise call `evil-surround-region'."
+  (interactive (evil-surround-interactive-setup))
+  (cond
+   ((eq operation 'change)
+    (call-interactively 'evil-surround-change))
+   ((eq operation 'delete)
+    (call-interactively 'evil-surround-delete))
+   (t
+    (evil-surround-setup-surround-line-operators)
+    (evil-surround-call-with-repeat 'evil-surround-region))))
+
+(evil-define-command evil-Surround-edit (operation)
+  "Like evil-surround-edit, but for surrounding with additional new-lines.
+
+It does nothing for change / delete."
+  (interactive (evil-surround-interactive-setup))
+  (cond
+   ((eq operation 'change) nil)
+   ((eq operation 'delete) nil)
+   (t
+    (evil-surround-setup-surround-line-operators)
+    (evil-surround-call-with-repeat 'evil-Surround-region))))
+
+(evil-define-operator evil-surround-region (beg end type char &optional force-new-line)
+  "Surround BEG and END with CHAR.
+
+When force-new-line is true, and region type is not line, the
+following: (vertical bars indicate region start/end points)
+
+   do |:thing|
+
+Becomes this:
+
+   do {
+     :thing
+   }"
+
+  (interactive "<R>c")
+  (when (evil-surround-valid-char-p char)
+    (let* ((overlay (make-overlay beg end nil nil t))
+           (pair (or (and (boundp 'pair) pair) (evil-surround-pair char)))
+           (open (car pair))
+           (close (cdr pair))
+           (beg-pos (overlay-start overlay)))
+      (unwind-protect
+          (progn
+            (goto-char beg-pos)
+            (cond ((eq type 'block)
+                   (evil-surround-block beg end char))
+
+                  ((eq type 'line)
+                   (setq force-new-line
+                         (or force-new-line
+                             ;; Force newline if not invoked from an operator, e.g. visual line mode with VS)
+                             (evil-visual-state-p)
+                             ;; Or on multi-line operator surrounds (like 'ysj]')
+                             (/= (line-number-at-pos) (line-number-at-pos (1- end)))))
+
+                   (back-to-indentation)
+                   (setq beg-pos (point))
+                   (insert open)
+                   (when force-new-line (newline-and-indent))
+                   (goto-char (overlay-end overlay))
+                   (if force-new-line
+                       (when (eobp)
+                         (newline-and-indent))
+                     (backward-char)
+                     (evil-last-non-blank)
+                     (forward-char))
+                   (insert close)
+                   (when (or force-new-line
+                             (/= (line-number-at-pos) (line-number-at-pos beg-pos)))
+                     (indent-region beg-pos (point))
+                     (newline-and-indent)))
+
+                  (force-new-line
+                   (insert open)
+                   (newline-and-indent)
+                   (let ((pt (point)))
+                     (goto-char (overlay-end overlay))
+                     (newline-and-indent)
+                     (insert close)
+                     (indent-region pt (point))))
+
+                  (t
+                   (insert open)
+                   (goto-char (overlay-end overlay))
+                   (insert close)))
+            (goto-char beg-pos))
+        (delete-overlay overlay)))))
+
+(evil-define-operator evil-Surround-region (beg end type char)
+  "Call surround-region, toggling force-new-line"
+  (interactive "<R>c")
+  (evil-surround-region beg end type char t))
+
+;;;###autoload
+(define-minor-mode evil-surround-mode
+  "Buffer-local minor mode to emulate surround.vim."
+  :keymap (make-sparse-keymap)
+  (evil-normalize-keymaps))
+
+;;;###autoload
+(defun turn-on-evil-surround-mode ()
+  "Enable evil-surround-mode in the current buffer."
+  (evil-surround-mode 1))
+
+;;;###autoload
+(defun turn-off-evil-surround-mode ()
+  "Disable evil-surround-mode in the current buffer."
+  (evil-surround-mode -1))
+
+;;;###autoload
+(define-globalized-minor-mode global-evil-surround-mode
+  evil-surround-mode turn-on-evil-surround-mode
+  "Global minor mode to emulate surround.vim.")
+
+(evil-define-key 'operator evil-surround-mode-map "s" 'evil-surround-edit)
+(evil-define-key 'operator evil-surround-mode-map "S" 'evil-Surround-edit)
+
+(evil-define-key 'visual evil-surround-mode-map "S" 'evil-surround-region)
+(evil-define-key 'visual evil-surround-mode-map "gS" 'evil-Surround-region)
+
+(provide 'evil-surround)
+
+;;; evil-surround.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-surround-20180102.601/evil-surround.elc b/configs/shared/emacs/.emacs.d/elpa/evil-surround-20180102.601/evil-surround.elc
new file mode 100644
index 0000000000..5ab663b3ef
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-surround-20180102.601/evil-surround.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/evil-text-objects-haskell-20180316.1833/evil-text-objects-haskell-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/evil-text-objects-haskell-20180316.1833/evil-text-objects-haskell-autoloads.el
new file mode 100644
index 0000000000..00cdbe01bf
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-text-objects-haskell-20180316.1833/evil-text-objects-haskell-autoloads.el
@@ -0,0 +1,16 @@
+;;; evil-text-objects-haskell-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil nil ("evil-text-objects-haskell.el") (23377
+;;;;;;  61619 204561 624000))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; evil-text-objects-haskell-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-text-objects-haskell-20180316.1833/evil-text-objects-haskell-pkg.el b/configs/shared/emacs/.emacs.d/elpa/evil-text-objects-haskell-20180316.1833/evil-text-objects-haskell-pkg.el
new file mode 100644
index 0000000000..b04de6d278
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-text-objects-haskell-20180316.1833/evil-text-objects-haskell-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "evil-text-objects-haskell" "20180316.1833" "Text objects for Haskell source code" 'nil)
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-text-objects-haskell-20180316.1833/evil-text-objects-haskell.el b/configs/shared/emacs/.emacs.d/elpa/evil-text-objects-haskell-20180316.1833/evil-text-objects-haskell.el
new file mode 100644
index 0000000000..4edb5810f2
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-text-objects-haskell-20180316.1833/evil-text-objects-haskell.el
@@ -0,0 +1,132 @@
+;;; evil-text-objects-haskell.el --- Text objects for Haskell source code
+;; Package-Version: 20180316.1833
+
+;;; License:
+
+;; Copyright (C) 2018 Off Market Data, Inc. DBA Urbint
+;; Permission is hereby granted, free of charge, to any person obtaining a copy
+;; of this software and associated documentation files (the "Software"), to
+;; deal in the Software without restriction, including without limitation the
+;; rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+;; sell copies of the Software, and to permit persons to whom the Software is
+;; furnished to do so, subject to the following conditions:
+;;
+;; The above copyright notice and this permission notice shall be included in
+;; all copies or substantial portions of the Software.
+;;
+;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+;; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+;; IN THE SOFTWARE.
+
+;;; Commentary:
+
+;; evil-text-objects-haskell provides text-object definitions that
+;; should make working with Haskell in Emacs more enjoyable.
+;;
+;; Currently supporting:
+;;   - functions
+;;   - multi-line comments
+;;
+;; See the README.md for installation instructions.
+
+(require 'evil)
+(require 'pcre2el)
+(require 'dash)
+(require 'bind-key)
+
+;;; Code:
+
+;; Helper Functions
+(defun string-symbol-at-point ()
+  "Return a string version of the symbol at point after stripping away
+after all of the text properties."
+  (->
+   (symbol-at-point)
+   symbol-name
+   substring-no-properties))
+
+;; multi-line comments
+(evil-define-text-object
+  evil-inner-haskell-comment-block (count &optional beg end type)
+  "Inner text object for a Haskell comment block."
+  (let ((beg (save-excursion
+               (search-backward "{-")
+               (right-char 2)
+               (point)))
+        (end (save-excursion
+               (search-forward  "-}")
+               (left-char 2)
+               (point))))
+    (evil-range beg end type)))
+
+(evil-define-text-object
+  evil-outer-haskell-comment-block (count &optional beg end type)
+  "Outer text object for a Haskell comment block."
+  (let ((beg (save-excursion
+               (search-backward "{-")
+               (point)))
+        (end (save-excursion
+               (search-forward  "-}")
+               (point))))
+    (evil-range beg end type)))
+
+;; functions
+(evil-define-text-object
+  evil-inner-haskell-function (count &optional beg end type)
+  "Inner text object for a Haskell function."
+  (evil-range 0 0 type))
+
+(evil-define-text-object
+  evil-outer-haskell-function (count &optional beg end type)
+  "Outer text object for a Haskell function."
+  (beginning-of-line)
+  (when (looking-at "--")
+    (while (looking-at "--")
+      (forward-line -1)))
+  (when (looking-at "[[:space:]]")
+    (while (looking-at "[[:space:]]")
+      (forward-line -1)))
+  (let* ((fn-name (save-excursion
+                    (search-backward-regexp "^\\w")
+                    (string-symbol-at-point)))
+         (fn-name-regexp (concat "^" fn-name "\\b"))
+         (end (save-excursion
+                (while (search-forward-regexp fn-name-regexp nil t))
+                (unless (search-forward-regexp "^\\w" nil t)
+                  (goto-char (point-max)))
+                (search-backward-regexp "^[[:space:]]+[^ ]")
+                (end-of-line)
+                (point)))
+         (beg (save-excursion
+                (goto-char end)
+                (while (search-backward-regexp fn-name-regexp nil t))
+                (beginning-of-line)
+                (forward-line -1)
+                (while (looking-at "--")
+                  (forward-line -1))
+                (point))))
+    (evil-range beg end type)))
+
+;; Installation Helper
+(defun evil-text-objects-haskell/install ()
+  "Register keybindings for the text objects defined herein.  It is
+recommended to run this after something like `haskell-mode-hook'.  See
+README.md for additional information."
+  (bind-keys :map evil-operator-state-local-map
+             ("af" . evil-outer-haskell-function)
+             ("if" . evil-inner-haskell-function)
+             ("iC" . evil-inner-haskell-comment-block)
+             ("aC" . evil-outer-haskell-comment-block))
+  (bind-keys :map evil-visual-state-local-map
+             ("af" . evil-outer-haskell-function)
+             ("if" . evil-inner-haskell-function)
+             ("iC" . evil-inner-haskell-comment-block)
+             ("aC" . evil-outer-haskell-comment-block)))
+
+(provide 'evil-text-objects-haskell)
+
+;;; evil-text-objects-haskell.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-text-objects-javascript-20180330.1320/evil-text-objects-javascript-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/evil-text-objects-javascript-20180330.1320/evil-text-objects-javascript-autoloads.el
new file mode 100644
index 0000000000..1c65411410
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-text-objects-javascript-20180330.1320/evil-text-objects-javascript-autoloads.el
@@ -0,0 +1,16 @@
+;;; evil-text-objects-javascript-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil nil ("evil-text-objects-javascript.el") (23377
+;;;;;;  61675 413338 878000))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; evil-text-objects-javascript-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-text-objects-javascript-20180330.1320/evil-text-objects-javascript-pkg.el b/configs/shared/emacs/.emacs.d/elpa/evil-text-objects-javascript-20180330.1320/evil-text-objects-javascript-pkg.el
new file mode 100644
index 0000000000..e43f689562
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-text-objects-javascript-20180330.1320/evil-text-objects-javascript-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "evil-text-objects-javascript" "20180330.1320" "Text objects for Javascript source code" 'nil)
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-text-objects-javascript-20180330.1320/evil-text-objects-javascript.el b/configs/shared/emacs/.emacs.d/elpa/evil-text-objects-javascript-20180330.1320/evil-text-objects-javascript.el
new file mode 100644
index 0000000000..f40bd7bec8
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-text-objects-javascript-20180330.1320/evil-text-objects-javascript.el
@@ -0,0 +1,163 @@
+;;; evil-text-objects-javascript.el --- Text objects for Javascript source code
+
+;; Version: 1.0.0
+;; Package-Version: 20180330.1320
+
+;;; License:
+
+;; Copyright (C) 2018 Off Market Data, Inc. DBA Urbint
+;; Permission is hereby granted, free of charge, to any person obtaining a copy
+;; of this software and associated documentation files (the "Software"), to
+;; deal in the Software without restriction, including without limitation the
+;; rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+;; sell copies of the Software, and to permit persons to whom the Software is
+;; furnished to do so, subject to the following conditions:
+;;
+;; The above copyright notice and this permission notice shall be included in
+;; all copies or substantial portions of the Software.
+;;
+;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+;; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+;; IN THE SOFTWARE.
+
+;;; Commentary:
+
+;; evil-text-objects-javascript provides text-object definitions that
+;; should make working with Javascript in Emacs more enjoyable.
+;;
+;; Currently supporting:
+;;   - functions
+;;
+;; See the README.md for installation instructions.
+
+(require 'evil)
+(require 'bind-key)
+
+;;; Code:
+
+;; functions
+(evil-define-text-object
+  evil-inner-javascript-function (count &optional beg end type)
+  "Inner text object for all Javascript functions."
+  (call-interactively #'mark-defun)
+  (narrow-to-region (region-beginning) (region-end))
+  (goto-char (point-min))
+  (let* ((beg (save-excursion
+                (search-forward "(")
+                (backward-char)
+                (evil-jump-item)
+                (search-forward-regexp "[({]")
+                (point)))
+         (end (save-excursion
+                (goto-char beg)
+                (evil-jump-item)
+                (point))))
+    (evil-range beg end type)))
+
+(evil-define-text-object
+  evil-outer-javascript-function (count &optional beg end type)
+  "Outer text object for all Javascript functions."
+  (call-interactively #'mark-defun)
+  (narrow-to-region (region-beginning) (region-end))
+  (goto-char (point-min))
+  (let* ((beg (save-excursion
+                (when (looking-at "[[:space:]]")
+                  (evil-forward-word-begin))
+                (point)))
+         (end (save-excursion
+                (goto-char beg)
+                (search-forward "(")
+                (backward-char)
+                (evil-jump-item)
+                (search-forward-regexp "[({]")
+                (evil-jump-item)
+                (forward-char)
+                (point))))
+    (evil-range beg end type)))
+
+;; comments
+(evil-define-text-object
+  evil-outer-javascript-single-line-comment (count &optional beg end type)
+  "Outer text object for a single-line Javascript comment."
+  (let ((beg (save-excursion
+               (re-search-backward "\/\/[[:space:]]*" (line-beginning-position))
+               (when (looking-at "/") (point))))
+        (end (save-excursion
+               (end-of-line)
+               (point))))
+    (evil-range beg end type)))
+
+(evil-define-text-object
+  evil-inner-javascript-single-line-comment (count &optional beg end type)
+  "Inner text object for a single-line Javascript comment."
+  (let ((beg (save-excursion
+               (re-search-backward "\/\/[[:space:]]*" (line-beginning-position))
+               (when (looking-at "/")
+                 (progn
+                   (evil-forward-char 2)
+                   (point)))))
+        (end (save-excursion
+               (end-of-line)
+               (point))))
+    (evil-range beg end type)))
+
+(defun etojs--beg-multi-line-comment ()
+  "Navigate to the beginning of a multi-line Javascript comment."
+  (re-search-backward "\/\\*\\*?"))
+
+(defun etojs--end-multi-line-comment ()
+  "Navigate to the end of a multi-line Javascript comment."
+  (re-search-forward "\*/"))
+
+(evil-define-text-object
+  evil-outer-javascript-multi-line-comment (count &optional beg end type)
+  "Outer text object for a multi-line Javascript comment."
+  (let ((end (save-excursion
+               (etojs--end-multi-line-comment)
+               (point)))
+        (beg (save-excursion
+               (etojs--beg-multi-line-comment)
+               (point))))
+    (evil-range beg end type)))
+
+(evil-define-text-object
+  evil-inner-javascript-multi-line-comment (count &optional beg end type)
+  (let ((end (save-excursion
+               (etojs--end-multi-line-comment)
+               (forward-char -4)
+               (point)))
+        (beg (save-excursion
+               (etojs--beg-multi-line-comment)
+               (evil-next-line)
+               (evil-first-non-blank)
+               (forward-char 2)
+               (point))))
+    (evil-range beg end type)))
+
+;; Installation Helper
+(defun evil-text-objects-javascript/install ()
+  "Register keybindings for the text objects defined herein.  It is
+recommended to run this after something like `rjsx-mode-hook'.  See
+README.md for additional information."
+  (bind-keys :map evil-operator-state-local-map
+             ("af" . evil-outer-javascript-function)
+             ("if" . evil-inner-javascript-function)
+             ("ac" . evil-outer-javascript-single-line-comment)
+             ("ic" . evil-inner-javascript-single-line-comment)
+             ("aC" . evil-outer-javascript-multi-line-comment)
+             ("iC" . evil-inner-javascript-multi-line-comment))
+  (bind-keys :map evil-visual-state-local-map
+             ("af" . evil-outer-javascript-function)
+             ("if" . evil-inner-javascript-function)
+             ("ac" . evil-outer-javascript-single-line-comment)
+             ("ic" . evil-inner-javascript-single-line-comment)
+             ("aC" . evil-outer-javascript-multi-line-comment)
+             ("iC" . evil-inner-javascript-multi-line-comment)))
+
+(provide 'evil-text-objects-javascript)
+
+;;; evil-text-objects-javascript.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/evil-text-objects-javascript-20180330.1320/evil-text-objects-javascript.elc b/configs/shared/emacs/.emacs.d/elpa/evil-text-objects-javascript-20180330.1320/evil-text-objects-javascript.elc
new file mode 100644
index 0000000000..d40bf7c38f
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/evil-text-objects-javascript-20180330.1320/evil-text-objects-javascript.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/exec-path-from-shell-20180323.1904/exec-path-from-shell-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/exec-path-from-shell-20180323.1904/exec-path-from-shell-autoloads.el
new file mode 100644
index 0000000000..66497adc35
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/exec-path-from-shell-20180323.1904/exec-path-from-shell-autoloads.el
@@ -0,0 +1,44 @@
+;;; exec-path-from-shell-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "exec-path-from-shell" "exec-path-from-shell.el"
+;;;;;;  (23377 60983 977233 725000))
+;;; Generated autoloads from exec-path-from-shell.el
+
+(autoload 'exec-path-from-shell-copy-envs "exec-path-from-shell" "\
+Set the environment variables with NAMES from the user's shell.
+
+As a special case, if the variable is $PATH, then `exec-path' and
+`eshell-path-env' are also set appropriately.  The result is an alist,
+as described by `exec-path-from-shell-getenvs'.
+
+\(fn NAMES)" nil nil)
+
+(autoload 'exec-path-from-shell-copy-env "exec-path-from-shell" "\
+Set the environment variable $NAME from the user's shell.
+
+As a special case, if the variable is $PATH, then `exec-path' and
+`eshell-path-env' are also set appropriately.  Return the value
+of the environment variable.
+
+\(fn NAME)" t nil)
+
+(autoload 'exec-path-from-shell-initialize "exec-path-from-shell" "\
+Initialize environment from the user's shell.
+
+The values of all the environment variables named in
+`exec-path-from-shell-variables' are set from the corresponding
+values used in the user's shell.
+
+\(fn)" t nil)
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; exec-path-from-shell-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/exec-path-from-shell-20180323.1904/exec-path-from-shell-pkg.el b/configs/shared/emacs/.emacs.d/elpa/exec-path-from-shell-20180323.1904/exec-path-from-shell-pkg.el
new file mode 100644
index 0000000000..060395c8da
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/exec-path-from-shell-20180323.1904/exec-path-from-shell-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "exec-path-from-shell" "20180323.1904" "Get environment variables such as $PATH from the shell" 'nil)
diff --git a/configs/shared/emacs/.emacs.d/elpa/exec-path-from-shell-20180323.1904/exec-path-from-shell.el b/configs/shared/emacs/.emacs.d/elpa/exec-path-from-shell-20180323.1904/exec-path-from-shell.el
new file mode 100644
index 0000000000..f71193f7db
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/exec-path-from-shell-20180323.1904/exec-path-from-shell.el
@@ -0,0 +1,272 @@
+;;; exec-path-from-shell.el --- Get environment variables such as $PATH from the shell
+
+;; Copyright (C) 2012-2014 Steve Purcell
+
+;; Author: Steve Purcell <steve@sanityinc.com>
+;; Keywords: unix, environment
+;; URL: https://github.com/purcell/exec-path-from-shell
+;; Package-Version: 20180323.1904
+;; Package-X-Original-Version: 0
+
+;; This file is not part of GNU Emacs.
+
+;; This file 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.
+
+;; This file 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 this file.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; On OS X (and perhaps elsewhere) the $PATH environment variable and
+;; `exec-path' used by a windowed Emacs instance will usually be the
+;; system-wide default path, rather than that seen in a terminal
+;; window.
+
+;; This library allows the user to set Emacs' `exec-path' and $PATH
+;; from the shell path, so that `shell-command', `compile' and the
+;; like work as expected.
+
+;; It also allows other environment variables to be retrieved from the
+;; shell, so that Emacs will see the same values you get in a terminal.
+
+;; If you use a non-POSIX-standard shell like "tcsh" or "fish", your
+;; shell will be asked to execute "sh" as a subshell in order to print
+;; out the variables in a format which can be reliably parsed.  "sh"
+;; must be a POSIX-compliant shell in this case.
+
+;; Note that shell variables which have not been exported as
+;; environment variables (e.g. using the "export" keyword) may not be
+;; visible to `exec-path-from-shell'.
+
+;; Installation:
+
+;; ELPA packages are available on Marmalade and MELPA.  Alternatively,
+;; place this file on a directory in your `load-path', and explicitly
+;; require it.
+
+;; Usage:
+;;
+;;     (require 'exec-path-from-shell) ;; if not using the ELPA package
+;;     (exec-path-from-shell-initialize)
+;;
+;; Customize `exec-path-from-shell-variables' to modify the list of
+;; variables imported.
+;;
+;; If you use your Emacs config on other platforms, you can instead
+;; make initialization conditional as follows:
+;;
+;;     (when (memq window-system '(mac ns))
+;;       (exec-path-from-shell-initialize))
+;;
+;; Alternatively, you can use `exec-path-from-shell-copy-envs' or
+;; `exec-path-from-shell-copy-env' directly, e.g.
+;;
+;;     (exec-path-from-shell-copy-env "PYTHONPATH")
+
+;;; Code:
+
+;; Satisfy the byte compiler
+(defvar eshell-path-env)
+
+(defgroup exec-path-from-shell nil
+  "Make Emacs use shell-defined values for $PATH etc."
+  :prefix "exec-path-from-shell-"
+  :group 'environment)
+
+(defcustom exec-path-from-shell-variables
+  '("PATH" "MANPATH")
+  "List of environment variables which are copied from the shell."
+  :type '(repeat (string :tag "Environment variable"))
+  :group 'exec-path-from-shell)
+
+(defcustom exec-path-from-shell-check-startup-files t
+  "If non-nil, warn if variables are being set in the wrong shell startup files.
+Environment variables should be set in .profile or .zshenv rather than
+.bashrc or .zshrc."
+  :type 'boolean
+  :group 'exec-path-from-shell)
+
+(defcustom exec-path-from-shell-shell-name nil
+  "If non-nil, use this shell executable.
+Otherwise, use either `shell-file-name' (if set), or the value of
+the SHELL environment variable."
+  :type '(choice
+          (file :tag "Shell executable")
+          (const :tag "Use `shell-file-name' or $SHELL" nil))
+  :group 'exec-path-from-shell)
+
+(defvar exec-path-from-shell-debug nil
+  "Display debug info when non-nil.")
+
+(defun exec-path-from-shell--double-quote (s)
+  "Double-quote S, escaping any double-quotes already contained in it."
+  (concat "\"" (replace-regexp-in-string "\"" "\\\\\"" s) "\""))
+
+(defun exec-path-from-shell--shell ()
+  "Return the shell to use.
+See documentation for `exec-path-from-shell-shell-name'."
+  (or
+   exec-path-from-shell-shell-name
+   shell-file-name
+   (getenv "SHELL")
+   (error "SHELL environment variable is unset")))
+
+(defcustom exec-path-from-shell-arguments
+  (if (string-match-p "t?csh$" (exec-path-from-shell--shell))
+      (list "-d")
+    (list "-l" "-i"))
+  "Additional arguments to pass to the shell.
+
+The default value denotes an interactive login shell."
+  :type '(repeat (string :tag "Shell argument"))
+  :group 'exec-path-from-shell)
+
+(defun exec-path-from-shell--debug (msg &rest args)
+  "Print MSG and ARGS like `message', but only if debug output is enabled."
+  (when exec-path-from-shell-debug
+    (apply 'message msg args)))
+
+(defun exec-path-from-shell--standard-shell-p (shell)
+  "Return non-nil iff SHELL supports the standard ${VAR-default} syntax."
+  (not (string-match "\\(fish\\|t?csh\\)$" shell)))
+
+(defun exec-path-from-shell-printf (str &optional args)
+  "Return the result of printing STR in the user's shell.
+
+Executes the shell as interactive login shell.
+
+STR is inserted literally in a single-quoted argument to printf,
+and may therefore contain backslashed escape sequences understood
+by printf.
+
+ARGS is an optional list of args which will be inserted by printf
+in place of any % placeholders in STR.  ARGS are not automatically
+shell-escaped, so they may contain $ etc."
+  (let* ((printf-bin (or (executable-find "printf") "printf"))
+         (printf-command
+          (concat printf-bin
+                  " '__RESULT\\000" str "\\000__RESULT' "
+                  (mapconcat #'exec-path-from-shell--double-quote args " ")))
+         (shell (exec-path-from-shell--shell))
+         (shell-args (append exec-path-from-shell-arguments
+                             (list "-c"
+                                   (if (exec-path-from-shell--standard-shell-p shell)
+                                       printf-command
+                                     (concat "sh -c " (shell-quote-argument printf-command)))))))
+    (with-temp-buffer
+      (exec-path-from-shell--debug "Invoking shell %s with args %S" shell shell-args)
+      (let ((exit-code (apply #'call-process shell nil t nil shell-args)))
+        (exec-path-from-shell--debug "Shell printed: %S" (buffer-string))
+        (unless (zerop exit-code)
+          (error "Non-zero exit code from shell %s invoked with args %S.  Output was:\n%S"
+                 shell shell-args (buffer-string))))
+      (goto-char (point-min))
+      (if (re-search-forward "__RESULT\0\\(.*\\)\0__RESULT" nil t)
+          (match-string 1)
+        (error "Expected printf output from shell, but got: %S" (buffer-string))))))
+
+(defun exec-path-from-shell-getenvs (names)
+  "Get the environment variables with NAMES from the user's shell.
+
+Execute the shell according to `exec-path-from-shell-arguments'.
+The result is a list of (NAME . VALUE) pairs."
+  (let* ((random-default (md5 (format "%s%s%s" (emacs-pid) (random) (current-time))))
+         (dollar-names (mapcar (lambda (n) (format "${%s-%s}" n random-default)) names))
+         (values (split-string (exec-path-from-shell-printf
+                                (mapconcat #'identity (make-list (length names) "%s") "\\000")
+                                dollar-names) "\0")))
+    (let (result)
+      (while names
+        (prog1
+            (let ((value (car values)))
+              (push (cons (car names)
+                          (unless (string-equal random-default value)
+                            value))
+                    result))
+          (setq values (cdr values)
+                names (cdr names))))
+      result)))
+
+(defun exec-path-from-shell-getenv (name)
+  "Get the environment variable NAME from the user's shell.
+
+Execute the shell as interactive login shell, have it output the
+variable of NAME and return this output as string."
+  (cdr (assoc name (exec-path-from-shell-getenvs (list name)))))
+
+(defun exec-path-from-shell-setenv (name value)
+  "Set the value of environment var NAME to VALUE.
+Additionally, if NAME is \"PATH\" then also set corresponding
+variables such as `exec-path'."
+  (setenv name value)
+  (when (string-equal "PATH" name)
+    (setq eshell-path-env value
+          exec-path (append (parse-colon-path value) (list exec-directory)))))
+
+;;;###autoload
+(defun exec-path-from-shell-copy-envs (names)
+  "Set the environment variables with NAMES from the user's shell.
+
+As a special case, if the variable is $PATH, then `exec-path' and
+`eshell-path-env' are also set appropriately.  The result is an alist,
+as described by `exec-path-from-shell-getenvs'."
+  (let ((pairs (exec-path-from-shell-getenvs names)))
+    (when exec-path-from-shell-check-startup-files
+      (exec-path-from-shell--maybe-warn-about-startup-files pairs))
+    (mapc (lambda (pair)
+            (exec-path-from-shell-setenv (car pair) (cdr pair)))
+          pairs)))
+
+(defun exec-path-from-shell--maybe-warn-about-startup-files (pairs)
+  "Warn the user if the value of PAIRS seems to depend on interactive shell startup files."
+  (let ((without-minus-i (remove "-i" exec-path-from-shell-arguments)))
+    ;; If the user is using "-i", we warn them if it is necessary.
+    (unless (eq exec-path-from-shell-arguments without-minus-i)
+      (let* ((exec-path-from-shell-arguments without-minus-i)
+             (alt-pairs (exec-path-from-shell-getenvs (mapcar 'car pairs)))
+             different)
+        (dolist (pair pairs)
+          (unless (equal pair (assoc (car pair) alt-pairs))
+            (push (car pair) different)))
+        (when different
+          (message "You appear to be setting environment variables %S in your .bashrc or .zshrc: those files are only read by interactive shells, so you should instead set environment variables in startup files like .profile, .bash_profile or .zshenv.  Refer to your shell's man page for more info.  Customize `exec-path-from-shell-arguments' to remove \"-i\" when done, or disable `exec-path-from-shell-check-startup-files' to disable this message." different))))))
+
+;;;###autoload
+(defun exec-path-from-shell-copy-env (name)
+  "Set the environment variable $NAME from the user's shell.
+
+As a special case, if the variable is $PATH, then `exec-path' and
+`eshell-path-env' are also set appropriately.  Return the value
+of the environment variable."
+  (interactive "sCopy value of which environment variable from shell? ")
+  (cdar (exec-path-from-shell-copy-envs (list name))))
+
+;;;###autoload
+(defun exec-path-from-shell-initialize ()
+  "Initialize environment from the user's shell.
+
+The values of all the environment variables named in
+`exec-path-from-shell-variables' are set from the corresponding
+values used in the user's shell."
+  (interactive)
+  (exec-path-from-shell-copy-envs exec-path-from-shell-variables))
+
+
+(provide 'exec-path-from-shell)
+
+;; Local Variables:
+;; coding: utf-8
+;; indent-tabs-mode: nil
+;; require-final-newline: t
+;; checkdoc-minor-mode: t
+;; End:
+
+;;; exec-path-from-shell.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/exec-path-from-shell-20180323.1904/exec-path-from-shell.elc b/configs/shared/emacs/.emacs.d/elpa/exec-path-from-shell-20180323.1904/exec-path-from-shell.elc
new file mode 100644
index 0000000000..2f03d80108
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/exec-path-from-shell-20180323.1904/exec-path-from-shell.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/f-20180106.122/f-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/f-20180106.122/f-autoloads.el
new file mode 100644
index 0000000000..c446d3d13b
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/f-20180106.122/f-autoloads.el
@@ -0,0 +1,15 @@
+;;; f-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil nil ("f.el") (23377 60758 959805 8000))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; f-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/f-20180106.122/f-pkg.el b/configs/shared/emacs/.emacs.d/elpa/f-20180106.122/f-pkg.el
new file mode 100644
index 0000000000..2eb607e4d3
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/f-20180106.122/f-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "f" "20180106.122" "Modern API for working with files and directories" '((s "1.7.0") (dash "2.2.0")))
diff --git a/configs/shared/emacs/.emacs.d/elpa/f-20180106.122/f.el b/configs/shared/emacs/.emacs.d/elpa/f-20180106.122/f.el
new file mode 100644
index 0000000000..36a367c57a
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/f-20180106.122/f.el
@@ -0,0 +1,624 @@
+;;; f.el --- Modern API for working with files and directories -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2013 Johan Andersson
+
+;; Author: Johan Andersson <johan.rejeep@gmail.com>
+;; Maintainer: Johan Andersson <johan.rejeep@gmail.com>
+;; Version: 0.20.0
+;; Package-Version: 20180106.122
+;; Keywords: files, directories
+;; URL: http://github.com/rejeep/f.el
+;; Package-Requires: ((s "1.7.0") (dash "2.2.0"))
+
+;; This file is NOT part of GNU Emacs.
+
+;;; License:
+
+;; This program 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, or (at your option)
+;; any later version.
+
+;; This program 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; see the file COPYING.  If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Code:
+
+
+
+(require 's)
+(require 'dash)
+
+(put 'f-guard-error 'error-conditions '(error f-guard-error))
+(put 'f-guard-error 'error-message "Destructive operation outside sandbox")
+
+(defvar f--guard-paths nil
+  "List of allowed paths to modify when guarded.
+
+Do not modify this variable.")
+
+(defmacro f--destructive (path &rest body)
+  "If PATH is allowed to be modified, yield BODY.
+
+If PATH is not allowed to be modified, throw error."
+  (declare (indent 1))
+  `(if f--guard-paths
+       (if (--any? (or (f-same? it ,path)
+                       (f-ancestor-of? it ,path)) f--guard-paths)
+           (progn ,@body)
+         (signal 'f-guard-error (list ,path f--guard-paths)))
+     ,@body))
+
+
+;;;; Paths
+
+(defun f-join (&rest args)
+  "Join ARGS to a single path."
+  (let (path (relative (f-relative? (car args))))
+    (-map
+     (lambda (arg)
+       (setq path (f-expand arg path)))
+     args)
+    (if relative (f-relative path) path)))
+
+(defun f-split (path)
+  "Split PATH and return list containing parts."
+  (let ((parts (s-split (f-path-separator) path 'omit-nulls)))
+    (if (f-absolute? path)
+        (push (f-path-separator) parts)
+      parts)))
+
+(defun f-expand (path &optional dir)
+  "Expand PATH relative to DIR (or `default-directory').
+PATH and DIR can be either a directory names or directory file
+names.  Return a directory name if PATH is a directory name, and
+a directory file name otherwise.  File name handlers are
+ignored."
+  (let (file-name-handler-alist)
+    (expand-file-name path dir)))
+
+(defun f-filename (path)
+  "Return the name of PATH."
+  (file-name-nondirectory (directory-file-name path)))
+
+(defalias 'f-parent 'f-dirname)
+(defun f-dirname (path)
+  "Return the parent directory to PATH."
+  (let ((parent (file-name-directory
+                 (directory-file-name (f-expand path default-directory)))))
+    (unless (f-same? path parent)
+      (if (f-relative? path)
+          (f-relative parent)
+        (directory-file-name parent)))))
+
+(defun f-common-parent (paths)
+  "Return the deepest common parent directory of PATHS."
+  (cond
+   ((not paths) nil)
+   ((not (cdr paths)) (f-parent (car paths)))
+   (:otherwise
+    (let* ((paths (-map 'f-split paths))
+           (common (caar paths))
+           (re nil))
+      (while (and (not (null (car paths))) (--all? (equal (car it) common) paths))
+        (setq paths (-map 'cdr paths))
+        (push common re)
+        (setq common (caar paths)))
+      (cond
+       ((null re) "")
+       ((and (= (length re) 1) (f-root? (car re)))
+        (f-root))
+       (:otherwise
+        (concat (apply 'f-join (nreverse re)) "/")))))))
+
+(defun f-ext (path)
+  "Return the file extension of PATH.
+
+The extension, in a file name, is the part that follows the last
+'.', excluding version numbers and backup suffixes."
+  (file-name-extension path))
+
+(defun f-no-ext (path)
+  "Return everything but the file extension of PATH."
+  (file-name-sans-extension path))
+
+(defun f-swap-ext (path ext)
+  "Return PATH but with EXT as the new extension.
+EXT must not be nil or empty."
+  (if (s-blank? ext)
+      (error "Extension cannot be empty or nil")
+    (concat (f-no-ext path) "." ext)))
+
+(defun f-base (path)
+  "Return the name of PATH, excluding the extension of file."
+  (f-no-ext (f-filename path)))
+
+(defun f-relative (path &optional dir)
+  "Return PATH relative to DIR."
+  (file-relative-name path dir))
+
+(defalias 'f-abbrev 'f-short)
+(defun f-short (path)
+  "Return abbrev of PATH.  See `abbreviate-file-name'."
+  (abbreviate-file-name path))
+
+(defun f-long (path)
+  "Return long version of PATH."
+  (f-expand path))
+
+(defun f-canonical (path)
+  "Return the canonical name of PATH."
+  (file-truename path))
+
+(defun f-slash (path)
+  "Append slash to PATH unless one already.
+
+Some functions, such as `call-process' requires there to be an
+ending slash."
+  (if (f-dir? path)
+      (file-name-as-directory path)
+    path))
+
+(defun f-full (path)
+  "Return absolute path to PATH, with ending slash."
+  (f-slash (f-long path)))
+
+(defun f--uniquify (paths)
+  "Helper for `f-uniquify' and `f-uniquify-alist'."
+  (let* ((files-length (length paths))
+         (uniq-filenames (--map (cons it (f-filename it)) paths))
+         (uniq-filenames-next (-group-by 'cdr uniq-filenames)))
+    (while (/= files-length (length uniq-filenames-next))
+      (setq uniq-filenames-next
+            (-group-by 'cdr
+                       (--mapcat
+                        (let ((conf-files (cdr it)))
+                          (if (> (length conf-files) 1)
+                              (--map (cons (car it) (concat (f-filename (s-chop-suffix (cdr it) (car it))) (f-path-separator) (cdr it))) conf-files)
+                            conf-files))
+                        uniq-filenames-next))))
+    uniq-filenames-next))
+
+(defun f-uniquify (files)
+  "Return unique suffixes of FILES.
+
+This function expects no duplicate paths."
+  (-map 'car (f--uniquify files)))
+
+(defun f-uniquify-alist (files)
+  "Return alist mapping FILES to unique suffixes of FILES.
+
+This function expects no duplicate paths."
+  (-map 'cadr (f--uniquify files)))
+
+
+;;;; I/O
+
+(defun f-read-bytes (path)
+  "Read binary data from PATH.
+
+Return the binary data as unibyte string."
+  (with-temp-buffer
+    (set-buffer-multibyte nil)
+    (setq buffer-file-coding-system 'binary)
+    (insert-file-contents-literally path)
+    (buffer-substring-no-properties (point-min) (point-max))))
+
+(defalias 'f-read 'f-read-text)
+(defun f-read-text (path &optional coding)
+  "Read text with PATH, using CODING.
+
+CODING defaults to `utf-8'.
+
+Return the decoded text as multibyte string."
+  (decode-coding-string (f-read-bytes path) (or coding 'utf-8)))
+
+(defalias 'f-write 'f-write-text)
+(defun f-write-text (text coding path)
+  "Write TEXT with CODING to PATH.
+
+TEXT is a multibyte string.  CODING is a coding system to encode
+TEXT with.  PATH is a file name to write to."
+  (f-write-bytes (encode-coding-string text coding) path))
+
+(defun f-unibyte-string-p (s)
+  "Determine whether S is a unibyte string."
+  (not (multibyte-string-p s)))
+
+(defun f-write-bytes (data path)
+  "Write binary DATA to PATH.
+
+DATA is a unibyte string.  PATH is a file name to write to."
+  (f--destructive path
+    (unless (f-unibyte-string-p data)
+      (signal 'wrong-type-argument (list 'f-unibyte-string-p data)))
+    (let ((file-coding-system-alist nil)
+          (coding-system-for-write 'binary))
+      (with-temp-file path
+        (setq buffer-file-coding-system 'binary)
+        (set-buffer-multibyte nil)
+        (insert data)))))
+
+(defalias 'f-append 'f-append-text)
+(defun f-append-text (text coding path)
+  "Append TEXT with CODING to PATH.
+
+If PATH does not exist, it is created."
+  (f-append-bytes (encode-coding-string text coding) path))
+
+(defun f-append-bytes (data path)
+  "Append binary DATA to PATH.
+
+If PATH does not exist, it is created."
+  (let ((content
+         (if (f-file? path)
+             (f-read-bytes path)
+           "")))
+    (f-write-bytes (concat content data) path)))
+
+
+;;;; Destructive
+
+(defun f-mkdir (&rest dirs)
+  "Create directories DIRS."
+  (let (path)
+    (-each
+        dirs
+      (lambda (dir)
+        (setq path (f-expand dir path))
+        (unless (f-directory? path)
+          (f--destructive path (make-directory path)))))))
+
+(defun f-delete (path &optional force)
+  "Delete PATH, which can be file or directory.
+
+If FORCE is t, a directory will be deleted recursively."
+  (f--destructive path
+    (if (or (f-file? path) (f-symlink? path))
+        (delete-file path)
+      (delete-directory path force))))
+
+(defun f-symlink (source path)
+  "Create a symlink to SOURCE from PATH."
+  (f--destructive path (make-symbolic-link source path)))
+
+(defun f-move (from to)
+  "Move or rename FROM to TO.
+If TO is a directory name, move FROM into TO."
+  (f--destructive to (rename-file from to t)))
+
+(defun f-copy (from to)
+  "Copy file or directory FROM to TO.
+If FROM names a directory and TO is a directory name, copy FROM
+into TO as a subdirectory."
+  (f--destructive to
+    (if (f-file? from)
+        (copy-file from to)
+      ;; The behavior of `copy-directory' differs between Emacs 23 and
+      ;; 24 in that in Emacs 23, the contents of `from' is copied to
+      ;; `to', while in Emacs 24 the directory `from' is copied to
+      ;; `to'. We want the Emacs 24 behavior.
+      (if (> emacs-major-version 23)
+          (copy-directory from to)
+        (if (f-dir? to)
+            (progn
+              (apply 'f-mkdir (f-split to))
+              (let ((new-to (f-expand (f-filename from) to)))
+                (copy-directory from new-to)))
+          (copy-directory from to))))))
+
+(defun f-copy-contents (from to)
+  "Copy contents in directory FROM, to directory TO."
+  (unless (f-exists? to)
+    (error "Cannot copy contents to non existing directory %s" to))
+  (unless (f-dir? from)
+    (error "Cannot copy contents as %s is a file" from))
+  (--each (f-entries from)
+    (f-copy it (file-name-as-directory to))))
+
+(defun f-touch (path)
+  "Update PATH last modification date or create if it does not exist."
+  (f--destructive path
+    (if (f-file? path)
+        (set-file-times path)
+      (f-write-bytes "" path))))
+
+
+;;;; Predicates
+
+(defun f-exists? (path)
+  "Return t if PATH exists, false otherwise."
+  (file-exists-p path))
+
+(defalias 'f-exists-p 'f-exists?)
+
+(defalias 'f-dir? 'f-directory?)
+(defalias 'f-dir-p 'f-dir?)
+
+(defun f-directory? (path)
+  "Return t if PATH is directory, false otherwise."
+  (file-directory-p path))
+
+(defalias 'f-directory-p 'f-directory?)
+
+(defun f-file? (path)
+  "Return t if PATH is file, false otherwise."
+  (file-regular-p path))
+
+(defalias 'f-file-p 'f-file?)
+
+(defun f-symlink? (path)
+  "Return t if PATH is symlink, false otherwise."
+  (not (not (file-symlink-p path))))
+
+(defalias 'f-symlink-p 'f-symlink?)
+
+(defun f-readable? (path)
+  "Return t if PATH is readable, false otherwise."
+  (file-readable-p path))
+
+(defalias 'f-readable-p 'f-readable?)
+
+(defun f-writable? (path)
+  "Return t if PATH is writable, false otherwise."
+  (file-writable-p path))
+
+(defalias 'f-writable-p 'f-writable?)
+
+(defun f-executable? (path)
+  "Return t if PATH is executable, false otherwise."
+  (file-executable-p path))
+
+(defalias 'f-executable-p 'f-executable?)
+
+(defun f-absolute? (path)
+  "Return t if PATH is absolute, false otherwise."
+  (file-name-absolute-p path))
+
+(defalias 'f-absolute-p 'f-absolute?)
+
+(defun f-relative? (path)
+  "Return t if PATH is relative, false otherwise."
+  (not (f-absolute? path)))
+
+(defalias 'f-relative-p 'f-relative?)
+
+(defun f-root? (path)
+  "Return t if PATH is root directory, false otherwise."
+  (not (f-parent path)))
+
+(defalias 'f-root-p 'f-root?)
+
+(defun f-ext? (path &optional ext)
+  "Return t if extension of PATH is EXT, false otherwise.
+
+If EXT is nil or omitted, return t if PATH has any extension,
+false otherwise.
+
+The extension, in a file name, is the part that follows the last
+'.', excluding version numbers and backup suffixes."
+  (if ext
+      (string= (f-ext path) ext)
+    (not (eq (f-ext path) nil))))
+
+(defalias 'f-ext-p 'f-ext?)
+
+(defalias 'f-equal? 'f-same?)
+(defalias 'f-equal-p 'f-equal?)
+
+(defun f-same? (path-a path-b)
+  "Return t if PATH-A and PATH-B are references to same file."
+  (when (and (f-exists? path-a)
+             (f-exists? path-b))
+    (equal
+     (f-canonical (directory-file-name (f-expand path-a)))
+     (f-canonical (directory-file-name (f-expand path-b))))))
+
+(defalias 'f-same-p 'f-same?)
+
+(defun f-parent-of? (path-a path-b)
+  "Return t if PATH-A is parent of PATH-B."
+  (--when-let (f-parent path-b)
+    (f-same? path-a it)))
+
+(defalias 'f-parent-of-p 'f-parent-of?)
+
+(defun f-child-of? (path-a path-b)
+  "Return t if PATH-A is child of PATH-B."
+  (--when-let (f-parent path-a)
+    (f-same? it path-b)))
+
+(defalias 'f-child-of-p 'f-child-of?)
+
+(defun f-ancestor-of? (path-a path-b)
+  "Return t if PATH-A is ancestor of PATH-B."
+  (unless (f-same? path-a path-b)
+    (s-starts-with? (f-full path-a)
+                    (f-full path-b))))
+
+(defalias 'f-ancestor-of-p 'f-ancestor-of?)
+
+(defun f-descendant-of? (path-a path-b)
+  "Return t if PATH-A is desendant of PATH-B."
+  (unless (f-same? path-a path-b)
+    (s-starts-with? (f-full path-b)
+                    (f-full path-a))))
+
+(defalias 'f-descendant-of-p 'f-descendant-of?)
+
+(defun f-hidden? (path)
+  "Return t if PATH is hidden, nil otherwise."
+  (unless (f-exists? path)
+    (error "Path does not exist: %s" path))
+  (string= (substring path 0 1) "."))
+
+(defalias 'f-hidden-p 'f-hidden?)
+
+(defun f-empty? (path)
+  "If PATH is a file, return t if the file in PATH is empty, nil otherwise.
+If PATH is directory, return t if directory has no files, nil otherwise."
+  (if (f-directory? path)
+      (equal (f-files path nil t) nil)
+    (= (f-size path) 0)))
+
+(defalias 'f-empty-p 'f-empty?)
+
+
+;;;; Stats
+
+(defun f-size (path)
+  "Return size of PATH.
+
+If PATH is a file, return size of that file.  If PATH is
+directory, return sum of all files in PATH."
+  (if (f-directory? path)
+      (-sum (-map 'f-size (f-files path nil t)))
+    (nth 7 (file-attributes path))))
+
+(defun f-depth (path)
+  "Return the depth of PATH.
+
+At first, PATH is expanded with `f-expand'.  Then the full path is used to
+detect the depth.
+'/' will be zero depth,  '/usr' will be one depth.  And so on."
+  (- (length (f-split (f-expand path))) 1))
+
+
+;;;; Misc
+
+(defun f-this-file ()
+  "Return path to this file."
+  (cond
+   (load-in-progress load-file-name)
+   ((and (boundp 'byte-compile-current-file) byte-compile-current-file)
+    byte-compile-current-file)
+   (:else (buffer-file-name))))
+
+(defvar f--path-separator nil
+  "A variable to cache result of `f-path-separator'.")
+
+(defun f-path-separator ()
+  "Return path separator."
+  (or f--path-separator
+      (setq f--path-separator (substring (f-join "x" "y") 1 2))))
+
+(defun f-glob (pattern &optional path)
+  "Find PATTERN in PATH."
+  (file-expand-wildcards
+   (f-join (or path default-directory) pattern)))
+
+(defun f--collect-entries (path recursive)
+  (let (result
+        (entries
+         (-reject
+          (lambda (file)
+            (or
+             (equal (f-filename file) ".")
+             (equal (f-filename file) "..")))
+          (directory-files path t))))
+    (cond (recursive
+           (-map
+            (lambda (entry)
+              (if (f-file? entry)
+                  (setq result (cons entry result))
+                (when (f-directory? entry)
+                  (setq result (cons entry result))
+                  (setq result (append result (f--collect-entries entry recursive))))))
+            entries))
+          (t (setq result entries)))
+    result))
+
+(defmacro f--entries (path body &optional recursive)
+  "Anaphoric version of `f-entries'."
+  `(f-entries
+    ,path
+    (lambda (path)
+      (let ((it path))
+        ,body))
+    ,recursive))
+
+(defun f-entries (path &optional fn recursive)
+  "Find all files and directories in PATH.
+
+FN - called for each found file and directory.  If FN returns a thruthy
+value, file or directory will be included.
+RECURSIVE - Search for files and directories recursive."
+  (let ((entries (f--collect-entries path recursive)))
+    (if fn (-select fn entries) entries)))
+
+(defmacro f--directories (path body &optional recursive)
+  "Anaphoric version of `f-directories'."
+  `(f-directories
+    ,path
+    (lambda (path)
+      (let ((it path))
+        ,body))
+    ,recursive))
+
+(defun f-directories (path &optional fn recursive)
+  "Find all directories in PATH.  See `f-entries'."
+  (let ((directories (-select 'f-directory? (f--collect-entries path recursive))))
+    (if fn (-select fn directories) directories)))
+
+(defmacro f--files (path body &optional recursive)
+  "Anaphoric version of `f-files'."
+  `(f-files
+    ,path
+    (lambda (path)
+      (let ((it path))
+        ,body))
+    ,recursive))
+
+(defun f-files (path &optional fn recursive)
+  "Find all files in PATH.  See `f-entries'."
+  (let ((files (-select 'f-file? (f--collect-entries path recursive))))
+    (if fn (-select fn files) files)))
+
+(defmacro f--traverse-upwards (body &optional path)
+  "Anaphoric version of `f-traverse-upwards'."
+  `(f-traverse-upwards
+    (lambda (dir)
+      (let ((it dir))
+        ,body))
+    ,path))
+
+(defun f-traverse-upwards (fn &optional path)
+  "Traverse up as long as FN return nil, starting at PATH.
+
+If FN returns a non-nil value, the path sent as argument to FN is
+returned.  If no function callback return a non-nil value, nil is
+returned."
+  (unless path
+    (setq path default-directory))
+  (when (f-relative? path)
+    (setq path (f-expand path)))
+  (if (funcall fn path)
+      path
+    (unless (f-root? path)
+      (f-traverse-upwards fn (f-parent path)))))
+
+(defun f-root ()
+  "Return absolute root."
+  (f-traverse-upwards 'f-root?))
+
+(defmacro f-with-sandbox (path-or-paths &rest body)
+  "Only allow PATH-OR-PATHS and decendants to be modified in BODY."
+  (declare (indent 1))
+  `(let ((paths (if (listp ,path-or-paths)
+                    ,path-or-paths
+                  (list ,path-or-paths))))
+     (unwind-protect
+         (let ((f--guard-paths paths))
+           ,@body)
+       (setq f--guard-paths nil))))
+
+(provide 'f)
+
+;;; f.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/f-20180106.122/f.elc b/configs/shared/emacs/.emacs.d/elpa/f-20180106.122/f.elc
new file mode 100644
index 0000000000..5690690454
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/f-20180106.122/f.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/flow-minor-mode-20180315.1124/flow-minor-mode-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/flow-minor-mode-20180315.1124/flow-minor-mode-autoloads.el
new file mode 100644
index 0000000000..71474c3cff
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/flow-minor-mode-20180315.1124/flow-minor-mode-autoloads.el
@@ -0,0 +1,27 @@
+;;; flow-minor-mode-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "flow-minor-mode" "flow-minor-mode.el" (23377
+;;;;;;  61675 692656 510000))
+;;; Generated autoloads from flow-minor-mode.el
+
+(autoload 'flow-minor-mode "flow-minor-mode" "\
+Flow mode
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'flow-minor-enable-automatically "flow-minor-mode" "\
+Search for a flow marker and enable flow-minor-mode.
+
+\(fn)" nil nil)
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; flow-minor-mode-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/flow-minor-mode-20180315.1124/flow-minor-mode-pkg.el b/configs/shared/emacs/.emacs.d/elpa/flow-minor-mode-20180315.1124/flow-minor-mode-pkg.el
new file mode 100644
index 0000000000..744fad83cb
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/flow-minor-mode-20180315.1124/flow-minor-mode-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "flow-minor-mode" "20180315.1124" "Flow type mode based on web-mode." '((emacs "25.1")))
diff --git a/configs/shared/emacs/.emacs.d/elpa/flow-minor-mode-20180315.1124/flow-minor-mode.el b/configs/shared/emacs/.emacs.d/elpa/flow-minor-mode-20180315.1124/flow-minor-mode.el
new file mode 100644
index 0000000000..0bc3d73d69
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/flow-minor-mode-20180315.1124/flow-minor-mode.el
@@ -0,0 +1,323 @@
+;;; flow-minor-mode.el --- Flow type mode based on web-mode. -*- lexical-binding: t -*-
+
+;; This source code is licensed under the BSD-style license found in
+;; the LICENSE file in the root directory of this source tree.
+
+;; Version: 0.3
+;; Package-Version: 20180315.1124
+;; URL: https://github.com/an-sh/flow-minor-mode
+
+;; Package-Requires: ((emacs "25.1"))
+
+;;; Commentary:
+
+;; Minor mode for flowtype.org, derived from web-mode.  Essentially a
+;; rewrite of an official flow-for-emacs snippet into a standalone
+;; mode with an improved usability.
+;;
+;; To enable this mode, enable it in your preferred javascript mode's
+;; hooks:
+;;
+;;   (add-hook 'js2-mode-hook 'flow-minor-enable-automatically)
+;;
+;; This will enable flow-minor-mode for a file only when there is a
+;; "// @flow" declaration at the first line and a `.flowconfig` file
+;; is present in the project.  If you wish to enable flow-minor-mode
+;; for all javascript files, use this instead:
+;;
+;;  (add-hook 'js2-mode-hook 'flow-minor-mode)
+;;
+;;; Code:
+
+(require 'xref)
+(require 'json)
+(require 'compile)
+
+(defconst flow-minor-buffer "*Flow Output*")
+
+(defcustom flow-minor-default-binary "flow"
+  "Flow executable to use when no project-specific binary is found."
+  :group 'flow-minor-mode
+  :type 'string)
+
+(defcustom flow-minor-jump-other-window nil
+  "Jump to definitions in other window."
+  :group 'flow-minor-mode
+  :type 'boolean)
+
+(defcustom flow-minor-stop-server-on-exit t
+  "Stop flow server when Emacs exits."
+  :group 'flow-minor-mode
+  :type 'boolean)
+
+(defun flow-minor-column-at-pos (position)
+  "Column number at position.
+POSITION point"
+  (save-excursion (goto-char position) (current-column)))
+
+(defun flow-minor-region ()
+  "Format region data."
+  (if (use-region-p)
+      (let ((begin (region-beginning))
+            (end (region-end)))
+        (format ":%d:%d,%d:%d"
+                (line-number-at-pos begin)
+                (flow-minor-column-at-pos begin)
+                (line-number-at-pos end)
+                (flow-minor-column-at-pos end)))
+    ""))
+
+(defun flow-minor-binary ()
+  "Search for a local or global flow binary."
+  (let* ((root (locate-dominating-file
+                (or (buffer-file-name) default-directory)
+                "node_modules"))
+         (flow (and root
+                    (expand-file-name "node_modules/.bin/flow"
+                                      root))))
+    (if (and flow (file-executable-p flow))
+        flow
+      flow-minor-default-binary)))
+
+(defun flow-minor-cmd (&rest args)
+  "Run flow with arguments, outputs to flow buffer.
+ARGS"
+  (apply #'call-process (flow-minor-binary) nil flow-minor-buffer t args))
+
+(defun flow-minor-cmd-ignore-output (&rest args)
+  "Run flow with arguments, ignore output.
+ARGS"
+  (apply #'call-process (flow-minor-binary) nil nil nil args))
+
+(defun flow-minor-cmd-to-string (&rest args)
+  "Run flow with arguments, outputs to string.
+ARGS"
+  (with-temp-buffer
+    (apply #'call-process (flow-minor-binary) nil t nil args)
+    (buffer-string)))
+
+(defmacro flow-minor-with-flow (&rest body)
+  "With flow.
+BODY progn"
+  `(progn
+     (flow-minor-cmd-ignore-output "start")
+     ,@body))
+
+(defmacro flow-minor-region-command (region-sym &rest body)
+  "Flow command on a region.
+REGION-SYM symbol
+BODY progn"
+  (declare (indent defun))
+  `(flow-minor-with-flow
+    (let ((,region-sym (concat (buffer-file-name) (flow-minor-region))))
+      (switch-to-buffer-other-window flow-minor-buffer)
+      (setf buffer-read-only nil)
+      (erase-buffer)
+      ,@body)))
+
+(defun flow-minor-status ()
+  "Show errors."
+  (interactive)
+  (flow-minor-region-command region
+    (flow-minor-cmd "status" "--from" "emacs")
+    (compilation-mode)
+    (setf buffer-read-only t)))
+
+(defun flow-minor-suggest ()
+  "Fill types."
+  (interactive)
+  (flow-minor-region-command region
+    (flow-minor-cmd "suggest" region)
+    (diff-mode)
+    (setf buffer-read-only t)))
+
+(defun flow-minor-coverage ()
+  "Show coverage."
+  (interactive)
+  (flow-minor-region-command region
+    (message "%s" region)
+    (flow-minor-cmd "coverage" region)
+    (compilation-mode)
+    (setf buffer-read-only t)))
+
+(defvar flow-type-font-lock-highlight
+  '(
+    ("\\([-_[:alnum:]]+\\)\\??:" . font-lock-variable-name-face)
+    ("\\_<\\(true\\|false\\|null\\|undefined\\|void\\)\\_>" . font-lock-constant-face)
+    ("<\\([-_[:alnum:]]+\\)>" . font-lock-type-face)
+    ))
+
+(defun flow-minor-colorize-buffer ()
+  (setq font-lock-defaults '(flow-type-font-lock-highlight))
+  (font-lock-fontify-buffer))
+
+(defun flow-minor-colorize-type (text)
+  (with-temp-buffer
+    (insert text)
+    (flow-minor-colorize-buffer)
+    (buffer-string)))
+
+(defun flow-minor-type-at-pos ()
+  "Show type at position."
+  (interactive)
+  (flow-minor-with-flow
+   (let* ((file (buffer-file-name))
+          (line (number-to-string (line-number-at-pos)))
+          (col (number-to-string (1+ (current-column))))
+          (type (flow-minor-cmd-to-string "type-at-pos" file line col)))
+     (message "%s" (flow-minor-colorize-type (car (split-string type "\n")))))))
+
+(defun flow-minor-jump-to-definition ()
+  "Jump to definition."
+  (interactive)
+  (flow-minor-with-flow
+   (let* ((file (buffer-file-name))
+          (line (number-to-string (line-number-at-pos)))
+          (col (number-to-string (1+ (current-column))))
+          (location (json-read-from-string
+                     (flow-minor-cmd-to-string "get-def" "--json" file line col)))
+          (path (alist-get 'path location))
+          (line (alist-get 'line location))
+          (offset-in-line (alist-get 'start location)))
+     (if (> (length path) 0)
+         (progn
+           (xref-push-marker-stack)
+           (funcall (if flow-minor-jump-other-window #'find-file-other-window #'find-file) path)
+           (goto-line line)
+           (when (> offset-in-line 0)
+             (forward-char (1- offset-in-line))))
+       (message "Not found")))))
+
+(defvar flow-minor-mode-map (make-sparse-keymap)
+  "Keymap for ‘flow-minor-mode’.")
+
+(define-key flow-minor-mode-map (kbd "M-.") 'flow-minor-jump-to-definition)
+(define-key flow-minor-mode-map (kbd "M-,") 'xref-pop-marker-stack)
+
+(define-key flow-minor-mode-map (kbd "C-c C-c s") 'flow-minor-status)
+(define-key flow-minor-mode-map (kbd "C-c C-c c") 'flow-minor-coverage)
+(define-key flow-minor-mode-map (kbd "C-c C-c t") 'flow-minor-type-at-pos)
+(define-key flow-minor-mode-map (kbd "C-c C-c f") 'flow-minor-suggest)
+
+(define-key flow-minor-mode-map [menu-bar flow-minor-mode]
+  (cons "Flow" flow-minor-mode-map))
+
+(define-key flow-minor-mode-map [menu-bar flow-minor-mode flow-minor-mode-s]
+  '(menu-item "Flow status" flow-minor-status))
+
+(define-key flow-minor-mode-map [menu-bar flow-minor-mode flow-minor-mode-c]
+  '(menu-item "Flow coverage" flow-minor-coverage))
+
+(define-key flow-minor-mode-map [menu-bar flow-minor-mode flow-minor-mode-t]
+  '(menu-item "Type at point" flow-minor-type-at-pos))
+
+(define-key flow-minor-mode-map [menu-bar flow-minor-mode flow-minor-mode-f]
+  '(menu-item "Type suggestions" flow-minor-suggest))
+
+(defun flow-minor-stop-flow-server ()
+  "Stop flow hook."
+  (if flow-minor-stop-server-on-exit (ignore-errors (flow-minor-cmd-ignore-output "stop"))))
+
+(add-hook 'kill-emacs-hook 'flow-minor-stop-flow-server t)
+
+(defun flow-minor-maybe-delete-process (name)
+  (when (get-process name)
+    (delete-process name)))
+
+(defun flow-minor-eldoc-sentinel (process _event)
+  (when (eq (process-status process) 'exit)
+    (if (eq (process-exit-status process) 0)
+        (with-current-buffer "*Flow Eldoc*"
+          (goto-char (point-min))
+          (forward-line 1)
+          (delete-region (point) (point-max))
+          (flow-minor-colorize-buffer)
+          (eldoc-message (car (split-string (buffer-substring (point-min) (point-max)) "\n")))))))
+
+(defun flow-minor-eldoc-documentation-function ()
+  "Display type at point with eldoc."
+  (flow-minor-maybe-delete-process "flow-minor-eldoc")
+
+  (let* ((line (line-number-at-pos (point)))
+         (col (+ 1 (current-column)))
+         (buffer (get-buffer-create "*Flow Eldoc*"))
+         (errorbuffer (get-buffer-create "*Flow Eldoc Error*"))
+         (command (list (flow-minor-binary)
+                        "type-at-pos"
+                        "--path" buffer-file-name
+                        (number-to-string line)
+                        (number-to-string col)))
+         (process (make-process :name "flow-minor-eldoc"
+                                :buffer buffer
+                                :command command
+                                :connection-type 'pipe
+                                :sentinel 'flow-minor-eldoc-sentinel
+                                :stderr errorbuffer)))
+    (with-current-buffer buffer
+      (erase-buffer))
+    (with-current-buffer errorbuffer
+      (erase-buffer))
+    (save-restriction
+      (widen)
+      (process-send-region process (point-min) (point-max)))
+    (process-send-string process "\n")
+    (process-send-eof process))
+  nil)
+
+;;;###autoload
+(define-minor-mode flow-minor-mode
+  "Flow mode"
+  nil " Flow" flow-minor-mode-map
+  (if flow-minor-mode
+      (progn
+        (setq-local eldoc-documentation-function 'flow-minor-eldoc-documentation-function)
+        (eldoc-mode))))
+
+(defun flow-minor-tag-present-p ()
+  "Return true if the '// @flow' tag is present in the current buffer."
+  (save-excursion
+    (goto-char (point-min))
+    (let (stop found)
+      (while (not stop)
+        (when (not (re-search-forward "[^\n[:space:]]" nil t))
+          (setq stop t))
+        (if (equal (point) (point-min))
+            (setq stop t)
+          (backward-char))
+        (cond ((or (looking-at "//+[ ]*@flow")
+                   (looking-at "/\\**[ ]*@flow"))
+               (setq found t)
+               (setq stop t))
+              ((looking-at "//")
+               (forward-line))
+              ((looking-at "/\\*")
+               (when (not (re-search-forward "*/" nil t))
+                 (setq stop t)))
+              (t (setq stop t))))
+      found)))
+
+(defun flow-minor-configured-p ()
+  "Predicate to check configuration."
+  (locate-dominating-file
+   (or (buffer-file-name) default-directory)
+   ".flowconfig"))
+
+;;;###autoload
+(defun flow-minor-enable-automatically ()
+  "Search for a flow marker and enable flow-minor-mode."
+  (when (and (flow-minor-configured-p)
+             (flow-minor-tag-present-p))
+    (flow-minor-mode +1)))
+
+(defun flow-status ()
+  "Invoke flow to check types"
+  (interactive)
+  (let ((cmd "flow status")
+        (regexp '(flow "^\\(Error:\\)[ \t]+\\(\\(.+\\):\\([[:digit:]]+\\)\\)"
+                       3 4 nil (1) 2 (1 compilation-error-face))))
+    (add-to-list 'compilation-error-regexp-alist 'flow)
+    (add-to-list 'compilation-error-regexp-alist-alist regexp)
+    (compile cmd)))
+
+(provide 'flow-minor-mode)
+;;; flow-minor-mode.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/flow-minor-mode-20180315.1124/flow-minor-mode.elc b/configs/shared/emacs/.emacs.d/elpa/flow-minor-mode-20180315.1124/flow-minor-mode.elc
new file mode 100644
index 0000000000..45529af6aa
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/flow-minor-mode-20180315.1124/flow-minor-mode.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/flx-20151030.1112/flx-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/flx-20151030.1112/flx-autoloads.el
new file mode 100644
index 0000000000..7992c736be
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/flx-20151030.1112/flx-autoloads.el
@@ -0,0 +1,15 @@
+;;; flx-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil nil ("flx.el") (23377 60989 582120 815000))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; flx-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/flx-20151030.1112/flx-pkg.el b/configs/shared/emacs/.emacs.d/elpa/flx-20151030.1112/flx-pkg.el
new file mode 100644
index 0000000000..cc2069613f
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/flx-20151030.1112/flx-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "flx" "20151030.1112" "fuzzy matching with good sorting" '((cl-lib "0.3")))
diff --git a/configs/shared/emacs/.emacs.d/elpa/flx-20151030.1112/flx.el b/configs/shared/emacs/.emacs.d/elpa/flx-20151030.1112/flx.el
new file mode 100644
index 0000000000..889d255404
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/flx-20151030.1112/flx.el
@@ -0,0 +1,420 @@
+;;; flx.el --- fuzzy matching with good sorting
+
+;; Copyright © 2013, 2015 Le Wang
+
+;; Author: Le Wang
+;; Maintainer: Le Wang
+;; Description: fuzzy matching with good sorting
+;; Created: Wed Apr 17 01:01:41 2013 (+0800)
+;; Version: 0.6.1
+;; Package-Version: 20151030.1112
+;; Package-Requires: ((cl-lib "0.3"))
+;; URL: https://github.com/lewang/flx
+
+;; This file is NOT part of GNU Emacs.
+
+;;; License
+
+;; This program 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, or
+;; (at your option) any later version.
+;;
+;; This program 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 this program; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+;; Floor, Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; Implementation notes
+;; --------------------
+;;
+;; Use defsubst instead of defun
+;;
+;; * Using bitmaps to check for matches worked out to be SLOWER than just
+;;   scanning the string and using `flx-get-matches'.
+;;
+;; * Consing causes GC, which can often slowdown Emacs more than the benefits
+;;   of an optimization.
+
+;;; Acknowledgments
+
+;; Scott Frazer's blog entry http://scottfrazersblog.blogspot.com.au/2009/12/emacs-better-ido-flex-matching.html
+;; provided a lot of inspiration.
+;; ido-hacks was helpful for ido optimization
+
+;;; Code:
+
+(require 'cl-lib)
+
+(defgroup flx nil
+  "Fuzzy matching with good sorting"
+  :group 'convenience
+  :prefix "flx-")
+
+(defcustom flx-word-separators '(?\  ?- ?_ ?: ?. ?/ ?\\)
+  "List of characters that act as word separators in flx"
+  :type '(repeat character)
+  :group 'flx)
+
+(defface flx-highlight-face  '((t (:inherit font-lock-variable-name-face :bold t :underline t)))
+  "Face used by flx for highlighting flx match characters."
+  :group 'flx)
+
+;;; Do we need more word separators than ST?
+(defsubst flx-word-p (char)
+  "Check if CHAR is a word character."
+  (and char
+       (not (memq char flx-word-separators))))
+
+(defsubst flx-capital-p (char)
+  "Check if CHAR is an uppercase character."
+  (and char
+       (flx-word-p char)
+       (= char (upcase char))))
+
+(defsubst flx-boundary-p (last-char char)
+  "Check if LAST-CHAR is the end of a word and CHAR the start of the next.
+
+This function is camel-case aware."
+  (or (null last-char)
+      (and (not (flx-capital-p last-char))
+           (flx-capital-p char))
+      (and (not (flx-word-p last-char))
+           (flx-word-p char))))
+
+(defsubst flx-inc-vec (vec &optional inc beg end)
+  "Increment each element of vectory by INC(default=1)
+from BEG (inclusive) to END (not inclusive)."
+  (or inc
+      (setq inc 1))
+  (or beg
+      (setq beg 0))
+  (or end
+      (setq end (length vec)))
+  (while (< beg end)
+    (cl-incf (aref vec beg) inc)
+    (cl-incf beg))
+  vec)
+
+(defun flx-get-hash-for-string (str heatmap-func)
+  "Return hash-table for string where keys are characters.
+Value is a sorted list of indexes for character occurrences."
+  (let* ((res (make-hash-table :test 'eq :size 32))
+         (str-len (length str))
+         down-char)
+    (cl-loop for index from (1- str-len) downto 0
+             for char = (aref str index)
+          do (progn
+               ;; simulate `case-fold-search'
+               (if (flx-capital-p char)
+                   (progn
+                     (push index (gethash char res))
+                     (setq down-char (downcase char)))
+                 (setq down-char char))
+               (push index (gethash down-char res))))
+    (puthash 'heatmap (funcall heatmap-func str) res)
+    res))
+
+;; So we store one fixnum per character.  Is this too memory inefficient?
+(defun flx-get-heatmap-str (str &optional group-separator)
+  "Generate the heatmap vector of string.
+
+See documentation for logic."
+  (let* ((str-len (length str))
+         (str-last-index (1- str-len))
+         ;; ++++ base
+         (scores (make-vector str-len -35))
+         (penalty-lead ?.)
+         (groups-alist (list (list -1 0))))
+    ;; ++++ final char bonus
+    (cl-incf (aref scores str-last-index) 1)
+    ;; Establish baseline mapping
+    (cl-loop for char across str
+          for index from 0
+          with last-char = nil
+          with group-word-count = 0
+          do (progn
+               (let ((effective-last-char
+                      ;; before we find any words, all separaters are
+                      ;; considered words of length 1.  This is so "foo/__ab"
+                      ;; gets penalized compared to "foo/ab".
+                      (if (zerop group-word-count) nil last-char)))
+                 (when (flx-boundary-p effective-last-char char)
+                   (setcdr (cdar groups-alist) (cons index (cl-cddar groups-alist))))
+                 (when (and (not (flx-word-p last-char))
+                            (flx-word-p char))
+                   (cl-incf group-word-count)))
+               ;; ++++ -45 penalize extension
+               (when (eq last-char penalty-lead)
+                 (cl-incf (aref scores index) -45))
+               (when (eq group-separator char)
+                 (setcar (cdar groups-alist) group-word-count)
+                 (setq group-word-count 0)
+                 (push (nconc (list index group-word-count)) groups-alist))
+               (if (= index str-last-index)
+                   (setcar (cdar groups-alist) group-word-count)
+                 (setq last-char char))))
+    (let* ((group-count (length groups-alist))
+           (separator-count (1- group-count)))
+      ;; ++++ slash group-count penalty
+      (unless (zerop separator-count)
+        (flx-inc-vec scores (* -2 group-count)))
+      ;; score each group further
+      (cl-loop for group in groups-alist
+            for index from separator-count downto 0
+            with last-group-limit = nil
+            with basepath-found = nil
+            do (let ((group-start (car group))
+                     (word-count (cadr group))
+                     ;; this is the number of effective word groups
+                     (words-length (length (cddr group)))
+                     basepath-p)
+                 (when (and (not (zerop words-length))
+                            (not basepath-found))
+                   (setq basepath-found t)
+                   (setq basepath-p t))
+                 (let (num)
+                   (setq num
+                         (if basepath-p
+                             (+ 35
+                                ;; ++++ basepath separator-count boosts
+                                (if (> separator-count 1)
+                                    (1- separator-count)
+                                  0)
+                                ;; ++++ basepath word count penalty
+                                (- word-count))
+                           ;; ++++ non-basepath penalties
+                           (if (= index 0)
+                               -3
+                             (+ -5 (1- index)))))
+                   (flx-inc-vec scores num (1+ group-start) last-group-limit))
+                 (cl-loop for word in (cddr group)
+                       for word-index from (1- words-length) downto 0
+                       with last-word = (or last-group-limit
+                                            str-len)
+                       do (progn
+                            (cl-incf (aref scores word)
+                                  ;; ++++  beg word bonus AND
+                                  85)
+                            (cl-loop for index from word below last-word
+                                  for char-i from 0
+                                  do (cl-incf (aref scores index)
+                                           (-
+                                            ;; ++++ word order penalty
+                                            (* -3 word-index)
+                                            ;; ++++ char order penalty
+                                            char-i)))
+                            (setq last-word word)))
+                 (setq last-group-limit (1+ group-start)))))
+    scores))
+
+(defun flx-get-heatmap-file (filename)
+  "Return heatmap vector for filename."
+  (flx-get-heatmap-str filename ?/))
+
+
+(defsubst flx-bigger-sublist (sorted-list val)
+  "Return sublist bigger than VAL from sorted SORTED-LIST
+
+  if VAL is nil, return entire list."
+  (if val
+      (cl-loop for sub on sorted-list
+            do (when (> (car sub) val)
+                 (cl-return sub)))
+      sorted-list))
+
+(defun flx-make-filename-cache ()
+  "Return cache hashtable appropraite for storing filenames."
+  (flx-make-string-cache 'flx-get-heatmap-file))
+
+(defun flx-make-string-cache (&optional heat-func)
+  "Return cache hashtable appropraite for storing strings."
+  (let ((hash (make-hash-table :test 'equal
+                               :size 4096)))
+    (puthash 'heatmap-func (or heat-func 'flx-get-heatmap-str) hash)
+    hash))
+
+(defun flx-process-cache (str cache)
+  "Get calculated heatmap from cache, add it if necessary."
+  (let ((res (when cache
+               (gethash str cache))))
+    (or res
+        (progn
+          (setq res (flx-get-hash-for-string
+                     str
+                     (or (and cache (gethash 'heatmap-func cache))
+                         'flx-get-heatmap-str)))
+          (when cache
+            (puthash str res cache))
+          res))))
+
+(defun flx-find-best-match (str-info
+                            heatmap
+                            greater-than
+                            query
+                            query-length
+                            q-index
+                            match-cache)
+  "Recursively compute the best match for a string, passed as STR-INFO and
+HEATMAP, according to QUERY.
+
+This function uses MATCH-CACHE to memoize its return values.
+For other parameters, see `flx-score'"
+
+  ;; Here, we use a simple N'ary hashing scheme
+  ;; You could use (/ hash-key query-length) to get greater-than
+  ;; Or, (mod hash-key query-length) to get q-index
+  ;; We use this instead of a cons key for the sake of efficiency
+  (let* ((hash-key (+ q-index
+                      (* (or greater-than 0)
+                         query-length)))
+         (hash-value (gethash hash-key match-cache)))
+    (if hash-value
+        ;; Here, we use the value 'no-match to distinguish a cache miss
+        ;; from a nil (i.e. non-matching) return value
+        (if (eq hash-value 'no-match)
+            nil
+          hash-value)
+      (let ((indexes (flx-bigger-sublist
+                       (gethash (aref query q-index) str-info)
+                       greater-than))
+            (match)
+            (temp-score)
+            (best-score most-negative-fixnum))
+
+        ;; Matches are of the form:
+        ;; ((match_indexes) . (score . contiguous-count))
+        (if (>= q-index (1- query-length))
+            ;; At the tail end of the recursion, simply
+            ;; generate all possible matches with their scores
+            ;; and return the list to parent.
+            (setq match (mapcar (lambda (index)
+                                  (cons (list index)
+                                        (cons (aref heatmap index) 0)))
+                                indexes))
+          (dolist (index indexes)
+            (dolist (elem (flx-find-best-match str-info
+                                               heatmap
+                                               index
+                                               query
+                                               query-length
+                                               (1+ q-index)
+                                               match-cache))
+              (setq temp-score
+                    (if (= (1- (caar elem)) index)
+                        (+ (cadr elem)
+                           (aref heatmap index)
+
+                           ;; boost contiguous matches
+                           (* (min (cddr elem)
+                                   3)
+                              15)
+                           60)
+                      (+ (cadr elem)
+                         (aref heatmap index))))
+
+              ;; We only care about the optimal match, so only
+              ;; forward the match with the best score to parent
+              (when (> temp-score best-score)
+                (setq best-score temp-score
+                      match (list (cons (cons index (car elem))
+                                        (cons temp-score
+                                              (if (= (1- (caar elem))
+                                                     index)
+                                                  (1+ (cddr elem))
+                                                0)))))))))
+
+        ;; Calls are cached to avoid exponential time complexity
+        (puthash hash-key
+                 (if match match 'no-match)
+                 match-cache)
+        match))))
+
+(defun flx-score (str query &optional cache)
+  "Return best score matching QUERY against STR"
+  (unless (or (zerop (length query))
+              (zerop (length str)))
+    (let*
+        ((str-info (flx-process-cache str cache))
+         (heatmap (gethash 'heatmap str-info))
+         (query-length (length query))
+         (full-match-boost (and (< 1 query-length)
+                                (< query-length 5)))
+
+         ;; Raise recursion limit
+         (max-lisp-eval-depth 5000)
+         (max-specpdl-size 10000)
+
+         ;; Dynamic Programming table for memoizing flx-find-best-match
+         (match-cache (make-hash-table :test 'eql :size 10))
+
+         (optimal-match (flx-find-best-match str-info
+                                             heatmap
+                                             nil
+                                             query
+                                             query-length
+                                             0
+                                             match-cache)))
+      ;; Postprocess candidate
+      (and optimal-match
+           (cons
+            ;; This is the computed score, adjusted to boost the scores
+            ;; of exact matches.
+            (if (and full-match-boost
+                     (=  (length (caar optimal-match))
+                         (length str)))
+                (+ (cl-cadar optimal-match) 10000)
+              (cl-cadar optimal-match))
+
+            ;; This is the list of match positions
+            (caar optimal-match))))))
+
+(defun flx-propertize (obj score &optional add-score)
+  "Return propertized copy of obj according to score.
+
+SCORE of nil means to clear the properties."
+  (let ((block-started (cadr score))
+        (last-char nil)
+        (str (if (consp obj)
+                 (substring-no-properties (car obj))
+               (substring-no-properties obj))))
+
+    (when score
+      (dolist (char (cdr score))
+        (when (and last-char
+                   (not (= (1+ last-char) char)))
+          (put-text-property block-started  (1+ last-char) 'face 'flx-highlight-face str)
+          (setq block-started char))
+        (setq last-char char))
+      (put-text-property block-started  (1+ last-char) 'face 'flx-highlight-face str)
+      (when add-score
+        (setq str (format "%s [%s]" str (car score)))))
+    (if (consp obj)
+        (cons str (cdr obj))
+      str)))
+
+
+
+(defvar flx-file-cache nil
+  "Cached heatmap info about strings.")
+
+;;; reset value on every file load.
+(setq flx-file-cache (flx-make-filename-cache))
+
+(defvar flx-strings-cache nil
+  "Cached heatmap info about filenames.")
+
+;;; reset value on every file load.
+(setq flx-strings-cache (flx-make-string-cache))
+
+
+(provide 'flx)
+
+;;; flx.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/flx-20151030.1112/flx.elc b/configs/shared/emacs/.emacs.d/elpa/flx-20151030.1112/flx.elc
new file mode 100644
index 0000000000..1f8e32d578
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/flx-20151030.1112/flx.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/flx-ido-20180117.719/flx-ido-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/flx-ido-20180117.719/flx-ido-autoloads.el
new file mode 100644
index 0000000000..49dcf8705f
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/flx-ido-20180117.719/flx-ido-autoloads.el
@@ -0,0 +1,29 @@
+;;; flx-ido-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "flx-ido" "flx-ido.el" (23377 60989 747594
+;;;;;;  79000))
+;;; Generated autoloads from flx-ido.el
+
+(defvar flx-ido-mode nil "\
+Non-nil if Flx-Ido mode is enabled.
+See the `flx-ido-mode' command
+for a description of this minor mode.")
+
+(custom-autoload 'flx-ido-mode "flx-ido" nil)
+
+(autoload 'flx-ido-mode "flx-ido" "\
+Toggle flx ido mode
+
+\(fn &optional ARG)" t nil)
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; flx-ido-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/flx-ido-20180117.719/flx-ido-pkg.el b/configs/shared/emacs/.emacs.d/elpa/flx-ido-20180117.719/flx-ido-pkg.el
new file mode 100644
index 0000000000..b538cc5689
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/flx-ido-20180117.719/flx-ido-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "flx-ido" "20180117.719" "flx integration for ido" '((flx "0.1") (cl-lib "0.3")))
diff --git a/configs/shared/emacs/.emacs.d/elpa/flx-ido-20180117.719/flx-ido.el b/configs/shared/emacs/.emacs.d/elpa/flx-ido-20180117.719/flx-ido.el
new file mode 100644
index 0000000000..b3de6291c5
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/flx-ido-20180117.719/flx-ido.el
@@ -0,0 +1,292 @@
+;;; flx-ido.el --- flx integration for ido
+
+;; Copyright © 2013, 2015 Le Wang
+
+;; Author: Le Wang
+;; Maintainer: Le Wang
+;; Description: flx integration for ido
+;; Created: Sun Apr 21 20:38:36 2013 (+0800)
+;; Version: 0.6.1
+;; Package-Version: 20180117.719
+;; URL: https://github.com/lewang/flx
+;; Package-Requires: ((flx "0.1") (cl-lib "0.3"))
+
+;; This file is NOT part of GNU Emacs.
+
+;;; License
+
+;; This program 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, or
+;; (at your option) any later version.
+;;
+;; This program 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 this program; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+;; Floor, Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; This package provides a more powerful alternative to `ido-mode''s
+;; built-in flex matching.
+
+;;; Acknowledgments
+
+;; Scott Frazer's blog entry
+;; http://scottfrazersblog.blogspot.com.au/2009/12/emacs-better-ido-flex-matching.html
+;; provided a lot of inspiration.
+;;
+;; ido-hacks was helpful for ido optimization and fontification ideas
+
+;;; Installation:
+
+;; Add the following code to your init file:
+;;
+;;     (require 'flx-ido)
+;;     (ido-mode 1)
+;;     (ido-everywhere 1)
+;;     (flx-ido-mode 1)
+;;     ;; disable ido faces to see flx highlights.
+;;     (setq ido-enable-flex-matching t)
+;;     (setq ido-use-faces nil)
+
+;;; Code:
+
+(require 'ido)
+(require 'flx)
+
+(eval-when-compile
+  (defvar ido-cur-item))
+
+(defcustom flx-ido-threshold 6000
+  "Threshold for activating flx algorithm.
+
+Flx will not kick in until collection is filtered below this
+size with idos' default \"flex\" algorithm."
+  :type 'integer
+  :group 'ido)
+
+
+(defcustom flx-ido-use-faces t
+  "Use `flx-highlight-face' to indicate characters contributing to best score."
+  :type 'boolean
+  :group 'ido)
+
+(unless (fboundp 'delete-consecutive-dups)
+  (defun delete-consecutive-dups (list &optional circular)
+    "Destructively remove `equal' consecutive duplicates from LIST.
+First and last elements are considered consecutive if CIRCULAR is
+non-nil."
+    (let ((tail list) last)
+      (while (consp tail)
+        (if (equal (car tail) (cadr tail))
+            (setcdr tail (cddr tail))
+          (setq last (car tail)
+                tail (cdr tail))))
+      (if (and circular
+               (cdr list)
+               (equal last (car list)))
+          (nbutlast list)
+        list))))
+
+(defvar flx-ido-narrowed-matches-hash (make-hash-table :test 'equal)
+  "Key is a query string.  Value is a list of narrowed matches.")
+
+(defvar flx-ido-debug nil)
+
+(defun flx-ido-debug (&rest args)
+  "Debugging util function.
+ARGS passed to message."
+  (when flx-ido-debug
+      (apply 'message args)))
+
+(defun flx-ido-is-prefix-match (str prefix)
+  "Return t if STR starts with PREFIX."
+  (when (and str prefix)
+    (let ((length (length prefix)))
+      (eq t (compare-strings prefix 0 length
+                             str 0 length)))))
+
+(defun flx-ido-narrowed (query items)
+  "Get the value from `flx-ido-narrowed-matches-hash' with the
+longest prefix match."
+  (flx-ido-debug "flx-ido-narrowed saw %s items" (length items))
+  (if (zerop (length query))
+      (list t (nreverse items))
+    (let ((query-key (flx-ido-key-for-query query))
+          best-match
+          exact
+          res)
+      (cl-loop for key being the hash-key of flx-ido-narrowed-matches-hash
+               do (when (and (>= (length query-key) (length key))
+                             (flx-ido-is-prefix-match query-key key)
+                             (or (null best-match)
+                                 (> (length key) (length best-match))))
+                    (setq best-match key)
+                    (when (= (length key)
+                             (length query-key))
+                      (setq exact t)
+                      (cl-return))))
+      (setq res (cond (exact
+                       (gethash best-match flx-ido-narrowed-matches-hash))
+                      (best-match
+                       (flx-ido-undecorate (gethash best-match flx-ido-narrowed-matches-hash)))
+                      (t
+                       (flx-ido-undecorate items))))
+      (list exact res))))
+
+(defun flx-ido-undecorate (strings)
+  "Remove decorations from STRINGS."
+  (flx-ido-decorate strings t))
+
+
+(defun flx-ido-decorate (things &optional clear)
+  "Add ido text properties to THINGS.
+If CLEAR is specified, clear them instead."
+  (if flx-ido-use-faces
+      (let ((decorate-count (min ido-max-prospects
+                                 (length things))))
+        (nconc
+         (cl-loop for thing in things
+               for i from 0 below decorate-count
+               collect (if clear
+                           (flx-propertize thing nil)
+                         (flx-propertize (car thing) (cdr thing))))
+         (if clear
+             (nthcdr decorate-count things)
+           (mapcar 'car (nthcdr decorate-count things)))))
+    (if clear
+        things
+      (mapcar 'car things))))
+
+(defun flx-ido-match-internal (query items)
+  "Match QUERY against ITEMS using flx scores.
+
+If filtered item count is still greater than `flx-ido-threshold', then use flex."
+  (flx-ido-debug "flx-ido-match-internal saw %s items" (length items))
+  (let ((flex-result (flx-flex-match query items)))
+    (flx-ido-debug "flex result count: %s" (length flex-result))
+    (if (< (length flex-result) flx-ido-threshold)
+        (let* ((matches (cl-loop for item in flex-result
+                                 for string = (ido-name item)
+                                 for score = (flx-score string query flx-file-cache)
+                                 if score
+                                 collect (cons item score)
+                                 into matches
+                                 finally return matches)))
+          (flx-ido-decorate (delete-consecutive-dups
+                             (sort matches
+                                   (lambda (x y) (> (cadr x) (cadr y))))
+                             t)))
+      flex-result)))
+
+(defun flx-ido-key-for-query (query)
+  "Canonicalize QUERY to form key."
+  (concat ido-current-directory query))
+
+(defun flx-ido-cache (query items)
+  "Possibly insert items into cache."
+  (if (memq ido-cur-item '(file dir))
+      items
+    (puthash (flx-ido-key-for-query query) items flx-ido-narrowed-matches-hash)))
+
+(defun flx-ido-reset ()
+  "Clean up flx variables between ido sessions."
+  (clrhash flx-ido-narrowed-matches-hash))
+
+(defun flx-ido-match (query items)
+  "Better sorting for flx ido matching."
+  (cl-destructuring-bind (exact res-items)
+      (flx-ido-narrowed query items)
+    (flx-ido-debug "exact: %s\nbefore hash count %s " exact (hash-table-count flx-ido-narrowed-matches-hash))
+    (flx-ido-cache query (if exact
+                             res-items
+                           (flx-ido-match-internal query res-items)))))
+
+(defun flx-ido-query-to-regexp (query)
+  "Convert QUERY to flx style case folding regexp."
+  (let* ((breakdown-str (mapcar (lambda (c)
+                                  (apply 'string c (when (= (downcase c) c)
+                                                       (list (upcase c)))))
+                                query))
+         (re (concat (format "[%s]" (nth 0 breakdown-str))
+                     (mapconcat (lambda (c)
+                                  (format "[^%s]*[%s]" c c))
+                                (cdr breakdown-str) ""))))
+    re))
+
+(defun flx-flex-match (query items)
+  "Reimplement ido's flex matching.
+Our implementation always uses flex and doesn't care about substring matches."
+  (if (zerop (length query))
+      items
+    (let* ((case-fold-search nil)
+           (re (flx-ido-query-to-regexp query))
+           matches)
+      (mapc
+       (lambda (item)
+         (let ((name (ido-name item)))
+           (if (string-match re name)
+               (setq matches (cons item matches)))))
+       items)
+      (delete-consecutive-dups (nreverse matches) t))))
+
+;;;###autoload
+(define-minor-mode flx-ido-mode
+  "Toggle flx ido mode"
+  :init-value nil
+  :lighter ""
+  :group 'ido
+  :global t)
+
+(defadvice ido-exit-minibuffer (around flx-ido-reset activate)
+  "Remove flx properties after."
+  (let* ((obj (car ido-matches))
+         (str (if (consp obj)
+                  (car obj)
+                obj)))
+    (when (and flx-ido-mode str)
+      (remove-text-properties 0 (length str)
+                              '(face flx-highlight-face) str))
+    (flx-ido-reset))
+
+  ad-do-it)
+
+(defadvice ido-read-internal (before flx-ido-reset activate)
+  "Clear flx narrowed hash beforehand."
+  (when flx-ido-mode
+    (flx-ido-reset)))
+
+(defadvice ido-restrict-to-matches (before flx-ido-reset activate)
+  "Clear flx narrowed hash."
+  (when flx-ido-mode
+    (flx-ido-reset)))
+
+(defadvice ido-set-matches-1 (around flx-ido-set-matches-1 activate compile)
+  "Choose between the regular ido-set-matches-1 and flx-ido-match"
+  (if (not flx-ido-mode)
+      ad-do-it
+    (let* ((query ido-text)
+           (original-items (ad-get-arg 0)))
+      (flx-ido-debug "query: %s" query)
+      (flx-ido-debug "id-set-matches-1 sees %s items" (length original-items))
+      (setq ad-return-value (flx-ido-match query original-items)))
+    (flx-ido-debug "id-set-matches-1 returning %s items starting with %s " (length ad-return-value) (car ad-return-value))))
+
+(defadvice ido-kill-buffer-at-head (before flx-ido-reset activate)
+  "Keep up with modification as required."
+  (when flx-ido-mode
+    ;; if not at EOB, query text is deleted.
+    (when (eobp)
+      (flx-ido-reset))))
+
+(add-hook 'ido-minibuffer-setup-hook 'flx-ido-reset nil)
+
+(provide 'flx-ido)
+
+;;; flx-ido.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/flx-ido-20180117.719/flx-ido.elc b/configs/shared/emacs/.emacs.d/elpa/flx-ido-20180117.719/flx-ido.elc
new file mode 100644
index 0000000000..1fffd37357
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/flx-ido-20180117.719/flx-ido.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/flycheck-20180720.247/flycheck-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/flycheck-20180720.247/flycheck-autoloads.el
new file mode 100644
index 0000000000..91626e3528
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/flycheck-20180720.247/flycheck-autoloads.el
@@ -0,0 +1,240 @@
+;;; flycheck-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "flycheck" "flycheck.el" (23377 61603 991554
+;;;;;;  461000))
+;;; Generated autoloads from flycheck.el
+
+(autoload 'flycheck-manual "flycheck" "\
+Open the Flycheck manual.
+
+\(fn)" t nil)
+
+(autoload 'flycheck-mode "flycheck" "\
+Minor mode for on-the-fly syntax checking.
+
+When called interactively, toggle `flycheck-mode'.  With prefix
+ARG, enable `flycheck-mode' if ARG is positive, otherwise disable
+it.
+
+When called from Lisp, enable `flycheck-mode' if ARG is omitted,
+nil or positive.  If ARG is `toggle', toggle `flycheck-mode'.
+Otherwise behave as if called interactively.
+
+In `flycheck-mode' the buffer is automatically syntax-checked
+using the first suitable syntax checker from `flycheck-checkers'.
+Use `flycheck-select-checker' to select a checker for the current
+buffer manually.
+
+\\{flycheck-mode-map}
+
+\(fn &optional ARG)" t nil)
+
+(defvar global-flycheck-mode nil "\
+Non-nil if Global Flycheck mode is enabled.
+See the `global-flycheck-mode' command
+for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `global-flycheck-mode'.")
+
+(custom-autoload 'global-flycheck-mode "flycheck" nil)
+
+(autoload 'global-flycheck-mode "flycheck" "\
+Toggle Flycheck mode in all buffers.
+With prefix ARG, enable Global Flycheck mode if ARG is positive;
+otherwise, disable it.  If called from Lisp, enable the mode if
+ARG is omitted or nil.
+
+Flycheck mode is enabled in all buffers where
+`flycheck-mode-on-safe' would do it.
+See `flycheck-mode' for more information on Flycheck mode.
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'flycheck-define-error-level "flycheck" "\
+Define a new error LEVEL with PROPERTIES.
+
+The following PROPERTIES constitute an error level:
+
+`:severity SEVERITY'
+     A number denoting the severity of this level.  The higher
+     the number, the more severe is this level compared to other
+     levels.  Defaults to 0.
+
+     The severity is used by `flycheck-error-level-<' to
+     determine the ordering of errors according to their levels.
+
+`:compilation-level LEVEL'
+
+     A number indicating the broad class of messages that errors
+     at this level belong to: one of 0 (info), 1 (warning), or
+     2 or nil (error).  Defaults to nil.
+
+     This is used by `flycheck-checker-pattern-to-error-regexp'
+     to map error levels into `compilation-mode''s hierarchy and
+     to get proper highlighting of errors in `compilation-mode'.
+
+`:overlay-category CATEGORY'
+     A symbol denoting the overlay category to use for error
+     highlight overlays for this level.  See Info
+     node `(elisp)Overlay Properties' for more information about
+     overlay categories.
+
+     A category for an error level overlay should at least define
+     the `face' property, for error highlighting.  Another useful
+     property for error level categories is `priority', to
+     influence the stacking of multiple error level overlays.
+
+`:fringe-bitmap BITMAP'
+     A fringe bitmap symbol denoting the bitmap to use for fringe
+     indicators for this level.  See Info node `(elisp)Fringe
+     Bitmaps' for more information about fringe bitmaps,
+     including a list of built-in fringe bitmaps.
+
+`:fringe-face FACE'
+     A face symbol denoting the face to use for fringe indicators
+     for this level.
+
+`:error-list-face FACE'
+     A face symbol denoting the face to use for messages of this
+     level in the error list.  See `flycheck-list-errors'.
+
+\(fn LEVEL &rest PROPERTIES)" nil nil)
+
+(function-put 'flycheck-define-error-level 'lisp-indent-function '1)
+
+(autoload 'flycheck-define-command-checker "flycheck" "\
+Define SYMBOL as syntax checker to run a command.
+
+Define SYMBOL as generic syntax checker via
+`flycheck-define-generic-checker', which uses an external command
+to check the buffer.  SYMBOL and DOCSTRING are the same as for
+`flycheck-define-generic-checker'.
+
+In addition to the properties understood by
+`flycheck-define-generic-checker', the following PROPERTIES
+constitute a command syntax checker.  Unless otherwise noted, all
+properties are mandatory.  Note that the default `:error-filter'
+of command checkers is `flycheck-sanitize-errors'.
+
+`:command COMMAND'
+     The command to run for syntax checking.
+
+     COMMAND is a list of the form `(EXECUTABLE [ARG ...])'.
+
+     EXECUTABLE is a string with the executable of this syntax
+     checker.  It can be overridden with the variable
+     `flycheck-SYMBOL-executable'.  Note that this variable is
+     NOT implicitly defined by this function.  Use
+     `flycheck-def-executable-var' to define this variable.
+
+     Each ARG is an argument to the executable, either as string,
+     or as special symbol or form for
+     `flycheck-substitute-argument', which see.
+
+`:error-patterns PATTERNS'
+     A list of patterns to parse the output of the `:command'.
+
+     Each ITEM in PATTERNS is a list `(LEVEL SEXP ...)', where
+     LEVEL is a Flycheck error level (see
+     `flycheck-define-error-level'), followed by one or more RX
+     `SEXP's which parse an error of that level and extract line,
+     column, file name and the message.
+
+     See `rx' for general information about RX, and
+     `flycheck-rx-to-string' for some special RX forms provided
+     by Flycheck.
+
+     All patterns are applied in the order of declaration to the
+     whole output of the syntax checker.  Output already matched
+     by a pattern will not be matched by subsequent patterns.  In
+     other words, the first pattern wins.
+
+     This property is optional.  If omitted, however, an
+     `:error-parser' is mandatory.
+
+`:error-parser FUNCTION'
+     A function to parse errors with.
+
+     The function shall accept three arguments OUTPUT CHECKER
+     BUFFER.  OUTPUT is the syntax checker output as string,
+     CHECKER the syntax checker that was used, and BUFFER a
+     buffer object representing the checked buffer.  The function
+     must return a list of `flycheck-error' objects parsed from
+     OUTPUT.
+
+     This property is optional.  If omitted, it defaults to
+     `flycheck-parse-with-patterns'.  In this case,
+     `:error-patterns' is mandatory.
+
+`:standard-input t'
+     Whether to send the buffer contents on standard input.
+
+     If this property is given and has a non-nil value, send the
+     contents of the buffer on standard input.
+
+     Defaults to nil.
+
+Note that you may not give `:start', `:interrupt', and
+`:print-doc' for a command checker.  You can give a custom
+`:verify' function, though, whose results will be appended to the
+default `:verify' function of command checkers.
+
+\(fn SYMBOL DOCSTRING &rest PROPERTIES)" nil nil)
+
+(function-put 'flycheck-define-command-checker 'lisp-indent-function '1)
+
+(function-put 'flycheck-define-command-checker 'doc-string-elt '2)
+
+(autoload 'flycheck-def-config-file-var "flycheck" "\
+Define SYMBOL as config file variable for CHECKER, with default FILE-NAME.
+
+SYMBOL is declared as customizable variable using `defcustom', to
+provide a configuration file for the given syntax CHECKER.
+CUSTOM-ARGS are forwarded to `defcustom'.
+
+FILE-NAME is the initial value of the new variable.  If omitted,
+the default value is nil.
+
+Use this together with the `config-file' form in the `:command'
+argument to `flycheck-define-checker'.
+
+\(fn SYMBOL CHECKER &optional FILE-NAME &rest CUSTOM-ARGS)" nil t)
+
+(function-put 'flycheck-def-config-file-var 'lisp-indent-function '3)
+
+(autoload 'flycheck-def-option-var "flycheck" "\
+Define SYMBOL as option variable with INIT-VALUE for CHECKER.
+
+SYMBOL is declared as customizable variable using `defcustom', to
+provide an option for the given syntax CHECKERS (a checker or a
+list of checkers).  INIT-VALUE is the initial value of the
+variable, and DOCSTRING is its docstring.  CUSTOM-ARGS are
+forwarded to `defcustom'.
+
+Use this together with the `option', `option-list' and
+`option-flag' forms in the `:command' argument to
+`flycheck-define-checker'.
+
+\(fn SYMBOL INIT-VALUE CHECKERS DOCSTRING &rest CUSTOM-ARGS)" nil t)
+
+(function-put 'flycheck-def-option-var 'lisp-indent-function '3)
+
+(function-put 'flycheck-def-option-var 'doc-string-elt '4)
+
+;;;***
+
+;;;### (autoloads nil nil ("flycheck-buttercup.el" "flycheck-ert.el"
+;;;;;;  "flycheck-pkg.el") (23377 61603 990182 881000))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; flycheck-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/flycheck-20180720.247/flycheck-buttercup.el b/configs/shared/emacs/.emacs.d/elpa/flycheck-20180720.247/flycheck-buttercup.el
new file mode 100644
index 0000000000..98022659d4
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/flycheck-20180720.247/flycheck-buttercup.el
@@ -0,0 +1,157 @@
+;;; flycheck-buttercup.el --- Flycheck: Extensions to Buttercup -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2017 Flycheck contributors
+;; Copyright (C) 2016 Sebastian Wiesner and Flycheck contributors
+
+;; Author: Sebastian Wiesner <swiesner@lunaryorn.com>
+;; Maintainer: Clément Pit-Claudel <clement.pitclaudel@live.com>
+;;             fmdkdd <fmdkdd@gmail.com>
+;; Keywords: lisp, tools
+
+;; This file is not part of GNU Emacs.
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Extensions to Buttercup to write BDD tests for Flycheck.
+;;
+;; Buttercup is a BDD testing framework for Emacs, see URL
+;; `https://github.com/jorgenschaefer/emacs-buttercup/'.  Flycheck uses
+;; Buttercup extensively for new tests.
+;;
+;; This library provides extensions to Buttercup to write Specs for Flycheck.
+;;
+;; * Custom matchers
+;;
+;; (expect 'foo :to-be-local) - Is `foo' a local variable in the current buffer?
+
+;;; Code:
+
+(require 'buttercup)
+(require 'flycheck)
+(require 'seq)
+
+
+;;; Buttercup helpers
+
+(defun flycheck-buttercup-format-error-list (errors)
+  "Format ERRORS into a human-readable string."
+  (mapconcat (lambda (e) (flycheck-error-format e 'with-file-name))
+             errors "\n"))
+
+
+;;; Data matchers
+
+(buttercup-define-matcher :to-be-empty-string (s)
+  (let ((s (funcall s)))
+    (if (equal s "")
+        (cons t (format "Expected %S not be an empty string" s))
+      (cons nil (format "Expected %S to be an empty string" s)))))
+
+(buttercup-define-matcher :to-match-with-group (re s index match)
+  (let* ((re (funcall re))
+         (s (funcall s))
+         (index (funcall index))
+         (match (funcall match))
+         (matches? (string-match re s))
+         (result (and matches? (match-string index s))))
+    (if (and matches? (equal result match))
+        (cons t (format "Expected %S not to match %S with %S in group %s"
+                        re s match index))
+
+      (cons nil (format "Expected %S to match %S with %S in group %s, %s"
+                        re s match index
+                        (if matches?
+                            (format "but got %S" result)
+                          "but did not match"))))))
+
+
+;;; Emacs feature matchers
+
+(buttercup-define-matcher :to-be-live (buffer)
+  (let ((buffer (get-buffer (funcall buffer))))
+    (if (buffer-live-p buffer)
+        (cons t (format "Expected %S not to be a live buffer, but it is"
+                        buffer))
+      (cons nil (format "Expected %S to be a live buffer, but it is not"
+                        buffer)))))
+
+(buttercup-define-matcher :to-be-visible (buffer)
+  (let ((buffer (get-buffer (funcall buffer))))
+    (cond
+     ((and buffer (get-buffer-window buffer))
+      (cons t (format "Expected %S not to be a visible buffer, but it is"
+                      buffer)))
+     ((not (bufferp buffer))
+      (cons nil
+            (format "Expected %S to be a visible buffer, but it is not a buffer"
+                    buffer)))
+     (t (cons
+         nil
+         (format "Expected %S to be a visible buffer, but it is not visible"
+                 buffer))))))
+
+(buttercup-define-matcher :to-be-local (symbol)
+  (let ((symbol (funcall symbol)))
+    (if (local-variable-p symbol)
+        (cons t (format "Expected %S not to be a local variable, but it is"
+                        symbol))
+      (cons nil (format "Expected %S to be a local variable, but it is not"
+                        symbol)))))
+
+(buttercup-define-matcher :to-contain-match (buffer re)
+  (let ((buffer (funcall buffer))
+        (re (funcall re)))
+    (if (not (get-buffer buffer))
+        (cons nil (format "Expected %S to contain a match of %s, \
+but is not a buffer" buffer re))
+      (with-current-buffer buffer
+        (save-excursion
+          (goto-char (point-min))
+          (if (re-search-forward re nil 'noerror)
+              (cons t (format "Expected %S to contain a match \
+for %s, but it did not" buffer re))
+            (cons nil (format "Expected %S not to contain a match for \
+%s but it did not." buffer re))))))))
+
+
+;;; Flycheck matchers
+
+(buttercup-define-matcher :to-be-equal-flycheck-errors (a b)
+  (let* ((a (funcall a))
+         (b (funcall b))
+         (a-formatted (flycheck-buttercup-format-error-list a))
+         (b-formatted (flycheck-buttercup-format-error-list b)))
+    (if (equal a b)
+        (cons t (format "Expected
+%s
+not to be equal to
+%s" a-formatted b-formatted))
+      (cons nil (format "Expected
+%s
+to be equal to
+%s" a-formatted b-formatted)))))
+
+(provide 'flycheck-buttercup)
+
+;; Disable byte compilation for this library, to prevent package.el choking on a
+;; missing `buttercup' library.  See
+;; https://github.com/flycheck/flycheck/issues/860
+
+;; Local Variables:
+;; no-byte-compile: t
+;; End:
+
+;;; flycheck-buttercup.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/flycheck-20180720.247/flycheck-ert.el b/configs/shared/emacs/.emacs.d/elpa/flycheck-20180720.247/flycheck-ert.el
new file mode 100644
index 0000000000..b7c2bc0fe0
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/flycheck-20180720.247/flycheck-ert.el
@@ -0,0 +1,483 @@
+;;; flycheck-ert.el --- Flycheck: ERT extensions  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2017-2018 Flycheck contributors
+;; Copyright (C) 2013-2016 Sebastian Wiesner and Flycheck contributors
+
+;; Author: Sebastian Wiesner <swiesner@lunaryorn.com>
+;; Maintainer: Clément Pit-Claudel <clement.pitclaudel@live.com>
+;;             fmdkdd <fmdkdd@gmail.com>
+;; URL: https://github.com/flycheck/flycheck
+
+;; This file is not part of GNU Emacs.
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Unit testing library for Flycheck, the modern on-the-fly syntax checking
+;; extension for GNU Emacs.
+
+;; Provide various utility functions and unit test helpers to test Flycheck and
+;; Flycheck extensions.
+
+;;; Code:
+
+(require 'flycheck)
+(require 'ert)
+(require 'macroexp)                     ; For macro utilities
+
+
+;;; Compatibility
+
+(eval-and-compile
+  ;; Provide `ert-skip' and friends for Emacs 24.3
+  (defconst flycheck-ert-ert-can-skip (fboundp 'ert-skip)
+    "Whether ERT supports test skipping.")
+
+  (unless (fboundp 'define-error)
+    ;; from Emacs `subr.el'
+    (defun define-error (name message &optional parent)
+      "Define NAME as a new error signal.
+MESSAGE is a string that will be output to the echo area if such an error
+is signaled without being caught by a `condition-case'.
+PARENT is either a signal or a list of signals from which it inherits.
+Defaults to `error'."
+      (unless parent (setq parent 'error))
+      (let ((conditions
+             (if (consp parent)
+                 (apply #'append
+                        (mapcar
+                         (lambda (parent)
+                           (cons parent
+                                 (or (get parent 'error-conditions)
+                                     (error "Unknown signal `%s'" parent))))
+                         parent))
+               (cons parent (get parent 'error-conditions)))))
+        (put name 'error-conditions
+             (delete-dups (copy-sequence (cons name conditions))))
+        (when message (put name 'error-message message)))))
+
+  (unless flycheck-ert-ert-can-skip
+    ;; Fake skipping
+
+    (define-error 'flycheck-ert-skipped "Test skipped")
+
+    (defun ert-skip (data)
+      (signal 'flycheck-ert-skipped data))
+
+    (defmacro skip-unless (form)
+      `(unless (ignore-errors ,form)
+         (signal 'flycheck-ert-skipped ',form)))
+
+    (defun ert-test-skipped-p (result)
+      (and (ert-test-failed-p result)
+           (eq (car (ert-test-failed-condition result))
+               'flycheck-ert-skipped)))))
+
+
+;;; Internal variables
+
+(defvar flycheck-ert--resource-directory nil
+  "The directory to get resources from in this test suite.")
+
+
+;;; Resource management macros
+
+(defmacro flycheck-ert-with-temp-buffer (&rest body)
+  "Eval BODY within a temporary buffer.
+
+Like `with-temp-buffer', but resets the modification state of the
+temporary buffer to make sure that it is properly killed even if
+it has a backing file and is modified."
+  (declare (indent 0))
+  `(with-temp-buffer
+     (unwind-protect
+         ,(macroexp-progn body)
+       ;; Reset modification state of the buffer, and unlink it from its backing
+       ;; file, if any, because Emacs refuses to kill modified buffers with
+       ;; backing files, even if they are temporary.
+       (set-buffer-modified-p nil)
+       (set-visited-file-name nil 'no-query))))
+
+(defmacro flycheck-ert-with-file-buffer (file-name &rest body)
+  "Create a buffer from FILE-NAME and eval BODY.
+
+BODY is evaluated with `current-buffer' being a buffer with the
+contents FILE-NAME."
+  (declare (indent 1))
+  `(let ((file-name ,file-name))
+     (unless (file-exists-p file-name)
+       (error "%s does not exist" file-name))
+     (flycheck-ert-with-temp-buffer
+       (insert-file-contents file-name 'visit)
+       (set-visited-file-name file-name 'no-query)
+       (cd (file-name-directory file-name))
+       ;; Mark the buffer as not modified, because we just loaded the file up to
+       ;; now.
+       (set-buffer-modified-p nil)
+       ,@body)))
+
+(defmacro flycheck-ert-with-help-buffer (&rest body)
+  "Execute BODY and kill the help buffer afterwards.
+
+Use this macro to test functions that create a Help buffer."
+  (declare (indent 0))
+  `(unwind-protect
+       ,(macroexp-progn body)
+     (when (buffer-live-p (get-buffer (help-buffer)))
+       (kill-buffer (help-buffer)))))
+
+(defmacro flycheck-ert-with-global-mode (&rest body)
+  "Execute BODY with Global Flycheck Mode enabled.
+
+After BODY, restore the old state of Global Flycheck Mode."
+  (declare (indent 0))
+  `(let ((old-state global-flycheck-mode))
+     (unwind-protect
+         (progn
+           (global-flycheck-mode 1)
+           ,@body)
+       (global-flycheck-mode (if old-state 1 -1)))))
+
+(defmacro flycheck-ert-with-env (env &rest body)
+  "Add ENV to `process-environment' in BODY.
+
+Execute BODY with a `process-environment' which contains all
+variables from ENV added.
+
+ENV is an alist, where each cons cell `(VAR . VALUE)' is a
+environment variable VAR to be added to `process-environment'
+with VALUE."
+  (declare (indent 1))
+  `(let ((process-environment (copy-sequence process-environment)))
+     (pcase-dolist (`(,var . ,value) ,env)
+       (setenv var value))
+     ,@body))
+
+
+;;; Test resources
+(defun flycheck-ert-resource-filename (resource-file)
+  "Determine the absolute file name of a RESOURCE-FILE.
+
+Relative file names are expanded against
+`flycheck-ert--resource-directory'."
+  (expand-file-name resource-file flycheck-ert--resource-directory))
+
+(defmacro flycheck-ert-with-resource-buffer (resource-file &rest body)
+  "Create a temp buffer from a RESOURCE-FILE and execute BODY.
+
+The absolute file name of RESOURCE-FILE is determined with
+`flycheck-ert-resource-filename'."
+  (declare (indent 1))
+  `(flycheck-ert-with-file-buffer
+       (flycheck-ert-resource-filename ,resource-file)
+     ,@body))
+
+
+;;; Test suite initialization
+
+(defun flycheck-ert-initialize (resource-dir)
+  "Initialize a test suite with RESOURCE-DIR.
+
+RESOURCE-DIR is the directory, `flycheck-ert-resource-filename'
+should use to lookup resource files."
+  (when flycheck-ert--resource-directory
+    (error "Test suite already initialized"))
+  (let ((tests (ert-select-tests t t)))
+    ;; Select all tests
+    (unless tests
+      (error "No tests defined.  \
+Call `flycheck-ert-initialize' after defining all tests!"))
+
+    (setq flycheck-ert--resource-directory resource-dir)
+
+    ;; Emacs 24.3 don't support skipped tests, so we add poor man's test
+    ;; skipping: We mark skipped tests as expected failures by adjusting the
+    ;; expected result of all test cases. Not particularly pretty, but works :)
+    (unless flycheck-ert-ert-can-skip
+      (dolist (test tests)
+        (let ((result (ert-test-expected-result-type test)))
+          (setf (ert-test-expected-result-type test)
+                `(or ,result (satisfies ert-test-skipped-p))))))))
+
+
+;;; Test case definitions
+(defmacro flycheck-ert-def-checker-test (checker language name
+                                                 &rest keys-and-body)
+  "Define a test case for a syntax CHECKER for LANGUAGE.
+
+CHECKER is a symbol or a list of symbols denoting syntax checkers
+being tested by the test.  The test case is skipped, if any of
+these checkers cannot be used.  LANGUAGE is a symbol or a list of
+symbols denoting the programming languages supported by the
+syntax checkers.  This is currently only used for tagging the
+test appropriately.
+
+NAME is a symbol denoting the local name of the test.  The test
+itself is ultimately named
+`flycheck-define-checker/CHECKER/NAME'.  If CHECKER is a list,
+the first checker in the list is used for naming the test.
+
+Optionally, the keyword arguments `:tags' and `:expected-result'
+may be given.  They have the same meaning as in `ert-deftest.',
+and are added to the tags and result expectations set up by this
+macro.
+
+The remaining forms KEYS-AND-BODY denote the body of the test
+case, including assertions and setup code."
+  (declare (indent 3))
+  (unless checker
+    (error "No syntax checkers specified"))
+  (unless language
+    (error "No languages specified"))
+  (let* ((checkers (if (symbolp checker) (list checker) checker))
+         (checker (car checkers))
+         (languages (if (symbolp language) (list language) language))
+         (language-tags (mapcar (lambda (l) (intern (format "language-%s" l)))
+                                languages))
+         (checker-tags (mapcar (lambda (c) (intern (format "checker-%s" c)))
+                               checkers))
+         (local-name (or name 'default))
+         (full-name (intern (format "flycheck-define-checker/%s/%s"
+                                    checker local-name)))
+         (keys-and-body (ert--parse-keys-and-body keys-and-body))
+         (body (cadr keys-and-body))
+         (keys (car keys-and-body))
+         (default-tags '(syntax-checker external-tool)))
+    `(ert-deftest ,full-name ()
+       :expected-result ,(or (plist-get keys :expected-result) :passed)
+       :tags (append ',(append default-tags language-tags checker-tags)
+                     ,(plist-get keys :tags))
+       ,@(mapcar (lambda (c)
+                   `(skip-unless
+                     ;; Ignore non-command checkers
+                     (or (not (flycheck-checker-get ',c 'command))
+                         (executable-find (flycheck-checker-executable ',c)))))
+                 checkers)
+       ,@body)))
+
+
+;;; Test case results
+
+(defun flycheck-ert-syntax-check-timed-out-p (result)
+  "Whether RESULT denotes a timed-out test.
+
+RESULT is an ERT test result object."
+  (and (ert-test-failed-p result)
+       (eq (car (ert-test-failed-condition result))
+           'flycheck-ert-syntax-check-timed-out)))
+
+
+;;; Syntax checking in tests
+
+(defvar-local flycheck-ert-syntax-checker-finished nil
+  "Non-nil if the current checker has finished.")
+
+(add-hook 'flycheck-after-syntax-check-hook
+          (lambda () (setq flycheck-ert-syntax-checker-finished t)))
+
+(defconst flycheck-ert-checker-wait-time 10
+  "Time to wait until a checker is finished in seconds.
+
+After this time has elapsed, the checker is considered to have
+failed, and the test aborted with failure.")
+
+(define-error 'flycheck-ert-syntax-check-timed-out "Syntax check timed out.")
+
+(defun flycheck-ert-wait-for-syntax-checker ()
+  "Wait until the syntax check in the current buffer is finished."
+  (let ((starttime (float-time)))
+    (while (and (not flycheck-ert-syntax-checker-finished)
+                (< (- (float-time) starttime) flycheck-ert-checker-wait-time))
+      (sleep-for 1))
+    (unless (< (- (float-time) starttime) flycheck-ert-checker-wait-time)
+      (flycheck-stop)
+      (signal 'flycheck-ert-syntax-check-timed-out nil)))
+  (setq flycheck-ert-syntax-checker-finished nil))
+
+(defun flycheck-ert-buffer-sync ()
+  "Like `flycheck-buffer', but synchronously."
+  (setq flycheck-ert-syntax-checker-finished nil)
+  (should (not (flycheck-running-p)))
+  (flycheck-mode)                       ; This will only start a deferred check,
+  (flycheck-buffer)                     ; so we need an explicit manual check
+  ;; After starting the check, the checker should either be running now, or
+  ;; already be finished (if it was fast).
+  (should (or flycheck-current-syntax-check
+              flycheck-ert-syntax-checker-finished))
+  ;; Also there should be no deferred check pending anymore
+  (should-not (flycheck-deferred-check-p))
+  (flycheck-ert-wait-for-syntax-checker))
+
+(defun flycheck-ert-ensure-clear ()
+  "Clear the current buffer.
+
+Raise an assertion error if the buffer is not clear afterwards."
+  (flycheck-clear)
+  (should (not flycheck-current-errors))
+  (should (not (-any? (lambda (ov) (overlay-get ov 'flycheck-overlay))
+                      (overlays-in (point-min) (point-max))))))
+
+
+;;; Test assertions
+
+(defun flycheck-error-without-group (err)
+  "Return a copy ERR with the `group' property set to nil."
+  (let ((copy (copy-flycheck-error err)))
+    (setf (flycheck-error-group copy) nil)
+    copy))
+
+(defun flycheck-ert-should-overlay (error)
+  "Test that ERROR has a proper overlay in the current buffer.
+
+ERROR is a Flycheck error object."
+  (let* ((overlay (-first (lambda (ov)
+                            (equal (flycheck-error-without-group
+                                    (overlay-get ov 'flycheck-error))
+                                   (flycheck-error-without-group error)))
+                          (flycheck-overlays-in 0 (+ 1 (buffer-size)))))
+         (region
+          ;; Overlays of errors from other files are on the first line
+          (if (flycheck-relevant-error-other-file-p error)
+              (cons (point-min)
+                    (save-excursion (goto-char (point-min)) (point-at-eol)))
+            (flycheck-error-region-for-mode error 'symbols)))
+         (level (flycheck-error-level error))
+         (category (flycheck-error-level-overlay-category level))
+         (face (get category 'face))
+         (fringe-bitmap (flycheck-error-level-fringe-bitmap level))
+         (fringe-face (flycheck-error-level-fringe-face level))
+         (fringe-icon (list 'left-fringe fringe-bitmap fringe-face)))
+    (should overlay)
+    (should (overlay-get overlay 'flycheck-overlay))
+    (should (= (overlay-start overlay) (car region)))
+    (should (= (overlay-end overlay) (cdr region)))
+    (should (eq (overlay-get overlay 'face) face))
+    (should (equal (get-char-property 0 'display
+                                      (overlay-get overlay 'before-string))
+                   fringe-icon))
+    (should (eq (overlay-get overlay 'category) category))
+    (should (equal (flycheck-error-without-group (overlay-get overlay
+                                                              'flycheck-error))
+                   (flycheck-error-without-group error)))))
+
+(defun flycheck-ert-should-errors (&rest errors)
+  "Test that the current buffers has ERRORS.
+
+ERRORS is a list of errors expected to be present in the current
+buffer.  Each error is given as a list of arguments to
+`flycheck-error-new-at'.
+
+If ERRORS are omitted, test that there are no errors at all in
+the current buffer.
+
+With ERRORS, test that each error in ERRORS is present in the
+current buffer, and that the number of errors in the current
+buffer is equal to the number of given ERRORS.  In other words,
+check that the buffer has all ERRORS, and no other errors."
+  (let ((expected (mapcar (apply-partially #'apply #'flycheck-error-new-at)
+                          errors)))
+    (should (equal (mapcar #'flycheck-error-without-group expected)
+                   (mapcar #'flycheck-error-without-group
+                           flycheck-current-errors)))
+    ;; Check that related errors are the same
+    (cl-mapcar (lambda (err1 err2)
+                 (should (equal (mapcar #'flycheck-error-without-group
+                                        (flycheck-related-errors err1 expected))
+                                (mapcar #'flycheck-error-without-group
+                                        (flycheck-related-errors err2)))))
+               expected flycheck-current-errors)
+    (mapc #'flycheck-ert-should-overlay expected))
+  (should (= (length errors)
+             (length (flycheck-overlays-in (point-min) (point-max))))))
+
+(define-error 'flycheck-ert-suspicious-checker "Suspicious state from checker")
+
+(defun flycheck-ert-should-syntax-check (resource-file modes &rest errors)
+  "Test a syntax check in RESOURCE-FILE with MODES.
+
+RESOURCE-FILE is the file to check.  MODES is a single major mode
+symbol or a list thereof, specifying the major modes to syntax
+check with.  If more than one major mode is specified, the test
+is run for each mode separately, so if you give three major
+modes, the entire test will run three times.  ERRORS is the list
+of expected errors, as in `flycheck-ert-should-errors'.  If
+omitted, the syntax check must not emit any errors.  The errors
+are cleared after each test.
+
+The syntax checker is selected via standard syntax checker
+selection.  To test a specific checker, you need to set
+`flycheck-checker' or `flycheck-disabled-checkers' accordingly
+before using this predicate, depending on whether you want to use
+manual or automatic checker selection.
+
+During the syntax check, configuration files of syntax checkers
+are also searched in the `config-files' sub-directory of the
+resource directory."
+  (when (symbolp modes)
+    (setq modes (list modes)))
+  (dolist (mode modes)
+    (unless (fboundp mode)
+      (ert-skip (format "%S missing" mode)))
+    (flycheck-ert-with-resource-buffer resource-file
+      (funcall mode)
+      ;; Load safe file-local variables because some tests depend on them
+      (let ((enable-local-variables :safe)
+            ;; Disable all hooks at this place, to prevent 3rd party packages
+            ;; from interfering
+            (hack-local-variables-hook))
+        (hack-local-variables))
+      ;; Configure config file locating for unit tests
+      (let ((process-hook-called 0))
+        (add-hook 'flycheck-process-error-functions
+                  (lambda (_err)
+                    (setq process-hook-called (1+ process-hook-called))
+                    nil)
+                  nil :local)
+        (add-hook 'flycheck-status-changed-functions
+                  (lambda (status)
+                    (when (eq status 'suspicious)
+                      (signal 'flycheck-ert-suspicious-checker nil))))
+        (flycheck-ert-buffer-sync)
+        (apply #'flycheck-ert-should-errors errors)
+        (should (= process-hook-called (length errors))))
+      (flycheck-ert-ensure-clear))))
+
+(defun flycheck-ert-at-nth-error (n)
+  "Determine whether point is at the N'th Flycheck error.
+
+Return non-nil if the point is at the N'th Flycheck error in the
+current buffer.  Otherwise return nil."
+  (let* ((error (nth (1- n) flycheck-current-errors))
+         (mode flycheck-highlighting-mode)
+         (region (flycheck-error-region-for-mode error mode)))
+    (and (member error (flycheck-overlay-errors-at (point)))
+         (= (point) (car region)))))
+
+(defun flycheck-ert-explain--at-nth-error (n)
+  "Explain a failed at-nth-error predicate at N."
+  (let ((errors (flycheck-overlay-errors-at (point))))
+    (if (null errors)
+        (format "Expected to be at error %s, but no error at point %s"
+                n (point))
+      (let ((pos (cl-position (car errors) flycheck-current-errors)))
+        (format "Expected to be at error %s, but point %s is at error %s"
+                n (point) (1+ pos))))))
+
+(put 'flycheck-ert-at-nth-error 'ert-explainer
+     'flycheck-ert-explain--at-nth-error)
+
+(provide 'flycheck-ert)
+
+;;; flycheck-ert.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/flycheck-20180720.247/flycheck-ert.elc b/configs/shared/emacs/.emacs.d/elpa/flycheck-20180720.247/flycheck-ert.elc
new file mode 100644
index 0000000000..f1dd24f772
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/flycheck-20180720.247/flycheck-ert.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/flycheck-20180720.247/flycheck-pkg.el b/configs/shared/emacs/.emacs.d/elpa/flycheck-20180720.247/flycheck-pkg.el
new file mode 100644
index 0000000000..9433315901
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/flycheck-20180720.247/flycheck-pkg.el
@@ -0,0 +1,12 @@
+(define-package "flycheck" "20180720.247" "On-the-fly syntax checking"
+  '((dash "2.12.1")
+    (pkg-info "0.4")
+    (let-alist "1.0.4")
+    (seq "1.11")
+    (emacs "24.3"))
+  :keywords
+  '("convenience" "languages" "tools")
+  :url "http://www.flycheck.org")
+;; Local Variables:
+;; no-byte-compile: t
+;; End:
diff --git a/configs/shared/emacs/.emacs.d/elpa/flycheck-20180720.247/flycheck.el b/configs/shared/emacs/.emacs.d/elpa/flycheck-20180720.247/flycheck.el
new file mode 100644
index 0000000000..23e85efae1
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/flycheck-20180720.247/flycheck.el
@@ -0,0 +1,10446 @@
+;;; flycheck.el --- On-the-fly syntax checking -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2017-2018 Flycheck contributors
+;; Copyright (C) 2012-2016 Sebastian Wiesner and Flycheck contributors
+;; Copyright (C) 2013, 2014 Free Software Foundation, Inc.
+;;
+;; Author: Sebastian Wiesner <swiesner@lunaryorn.com>
+;; Maintainer: Clément Pit-Claudel <clement.pitclaudel@live.com>
+;;             fmdkdd <fmdkdd@gmail.com>
+;; URL: http://www.flycheck.org
+;; Keywords: convenience, languages, tools
+;; Version: 32-cvs
+;; Package-Requires: ((dash "2.12.1") (pkg-info "0.4") (let-alist "1.0.4") (seq "1.11") (emacs "24.3"))
+
+;; This file is not part of GNU Emacs.
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; On-the-fly syntax checking for GNU Emacs 24.
+;;
+;; Flycheck is a modern on-the-fly syntax checking extension for GNU Emacs,
+;; intended as replacement for the older Flymake extension which is part of GNU
+;; Emacs.
+;;
+;; Flycheck automatically checks buffers for errors while you type, and reports
+;; warnings and errors directly in the buffer and in an optional IDE-like error
+;; list.
+;;
+;; It comes with a rich interface for custom syntax checkers and other
+;; extensions, and has already many 3rd party extensions adding new features.
+;;
+;; Please read the online manual at http://www.flycheck.org for more
+;; information.  You can open the manual directly from Emacs with `M-x
+;; flycheck-manual'.
+;;
+;; # Setup
+;;
+;; Flycheck works best on Unix systems.  It does not officially support Windows,
+;; but tries to maintain Windows compatibility and should generally work fine on
+;; Windows, too.
+;;
+;; To enable Flycheck add the following to your init file:
+;;
+;;    (add-hook 'after-init-hook #'global-flycheck-mode)
+;;
+;; Flycheck will then automatically check buffers in supported languages, as
+;; long as all necessary tools are present.  Use `flycheck-verify-setup' to
+;; troubleshoot your Flycheck setup.
+
+;;; Code:
+
+(eval-when-compile
+  (require 'let-alist)      ; `let-alist'
+  (require 'compile)        ; Compile Mode integration
+  (require 'jka-compr)      ; To inhibit compression of temp files
+  (require 'pcase)          ; `pcase-dolist' (`pcase' itself is autoloaded)
+  )
+
+(require 'dash)
+
+(require 'seq)                   ; Sequence functions
+(require 'subr-x nil 'no-error)  ; Additional utilities, Emacs 24.4 and upwards
+(require 'cl-lib)                ; `cl-defstruct' and CL utilities
+(require 'tabulated-list)        ; To list errors
+(require 'easymenu)              ; Flycheck Mode menu definition
+(require 'rx)                    ; Regexp fanciness in `flycheck-define-checker'
+(require 'help-mode)             ; `define-button-type'
+(require 'find-func)             ; `find-function-regexp-alist'
+(require 'json)                  ; `flycheck-parse-tslint'
+
+
+;; Declare a bunch of dynamic variables that we need from other modes
+(defvar sh-shell)                       ; For shell script checker predicates
+(defvar ess-language)                   ; For r-lintr predicate
+
+;; Tell the byte compiler about autoloaded functions from packages
+(declare-function pkg-info-version-info "pkg-info" (package))
+
+
+;;; Compatibility
+(eval-and-compile
+  (unless (fboundp 'string-suffix-p)
+    ;; TODO: Remove when dropping support for Emacs 24.3 and earlier
+    (defun string-suffix-p (suffix string &optional ignore-case)
+      "Return non-nil if SUFFIX is a suffix of STRING.
+If IGNORE-CASE is non-nil, the comparison is done without paying
+attention to case differences."
+      (let ((start-pos (- (length string) (length suffix))))
+        (and (>= start-pos 0)
+             (eq t (compare-strings suffix nil nil
+                                    string start-pos nil ignore-case))))))
+
+  ;; TODO: Remove when dropping support for Emacs 24.3 and earlier
+  (unless (featurep 'subr-x)
+    ;; `subr-x' function for Emacs 24.3 and below
+    (defsubst string-join (strings &optional separator)
+      "Join all STRINGS using SEPARATOR."
+      (mapconcat 'identity strings separator))
+
+    (defsubst string-trim-left (string)
+      "Remove leading whitespace from STRING."
+      (if (string-match "\\`[ \t\n\r]+" string)
+          (replace-match "" t t string)
+        string))
+
+    (defsubst string-trim-right (string)
+      "Remove trailing whitespace from STRING."
+      (if (string-match "[ \t\n\r]+\\'" string)
+          (replace-match "" t t string)
+        string))
+
+    (defsubst string-trim (string)
+      "Remove leading and trailing whitespace from STRING."
+      (string-trim-left (string-trim-right string)))
+
+    (defsubst string-empty-p (string)
+      "Check whether STRING is empty."
+      (string= string ""))))
+
+
+;;; Customization
+(defgroup flycheck nil
+  "Modern on-the-fly syntax checking for GNU Emacs."
+  :prefix "flycheck-"
+  :group 'tools
+  :link '(url-link :tag "Website" "http://www.flycheck.org")
+  :link '(url-link :tag "Github" "https://github.com/flycheck/flycheck"))
+
+(defgroup flycheck-config-files nil
+  "Configuration files for on-the-fly syntax checkers."
+  :prefix "flycheck-"
+  :group 'flycheck)
+
+(defgroup flycheck-options nil
+  "Options for on-the-fly syntax checkers."
+  :prefix "flycheck-"
+  :group 'flycheck)
+
+(defgroup flycheck-executables nil
+  "Executables of syntax checkers."
+  :prefix "flycheck-"
+  :group 'flycheck)
+
+(defgroup flycheck-faces nil
+  "Faces used by on-the-fly syntax checking."
+  :prefix "flycheck-"
+  :group 'flycheck)
+
+(defcustom flycheck-checkers
+  '(ada-gnat
+    asciidoctor
+    asciidoc
+    c/c++-clang
+    c/c++-gcc
+    c/c++-cppcheck
+    cfengine
+    chef-foodcritic
+    coffee
+    coffee-coffeelint
+    coq
+    css-csslint
+    css-stylelint
+    cwl
+    d-dmd
+    dockerfile-hadolint
+    emacs-lisp
+    emacs-lisp-checkdoc
+    erlang-rebar3
+    erlang
+    eruby-erubis
+    fortran-gfortran
+    go-gofmt
+    go-golint
+    go-vet
+    go-build
+    go-test
+    go-errcheck
+    go-unconvert
+    go-megacheck
+    groovy
+    haml
+    handlebars
+    haskell-stack-ghc
+    haskell-ghc
+    haskell-hlint
+    html-tidy
+    javascript-eslint
+    javascript-jshint
+    javascript-standard
+    json-jsonlint
+    json-python-json
+    jsonnet
+    less
+    less-stylelint
+    llvm-llc
+    lua-luacheck
+    lua
+    markdown-markdownlint-cli
+    markdown-mdl
+    nix
+    perl
+    perl-perlcritic
+    php
+    php-phpmd
+    php-phpcs
+    processing
+    proselint
+    protobuf-protoc
+    pug
+    puppet-parser
+    puppet-lint
+    python-flake8
+    python-pylint
+    python-pycompile
+    python-mypy
+    r-lintr
+    racket
+    rpm-rpmlint
+    rst-sphinx
+    rst
+    ruby-rubocop
+    ruby-reek
+    ruby-rubylint
+    ruby
+    ruby-jruby
+    rust-cargo
+    rust
+    rust-clippy
+    scala
+    scala-scalastyle
+    scheme-chicken
+    scss-lint
+    scss-stylelint
+    sass/scss-sass-lint
+    sass
+    scss
+    sh-bash
+    sh-posix-dash
+    sh-posix-bash
+    sh-zsh
+    sh-shellcheck
+    slim
+    slim-lint
+    sql-sqlint
+    systemd-analyze
+    tcl-nagelfar
+    tex-chktex
+    tex-lacheck
+    texinfo
+    typescript-tslint
+    verilog-verilator
+    vhdl-ghdl
+    xml-xmlstarlet
+    xml-xmllint
+    yaml-jsyaml
+    yaml-ruby)
+  "Syntax checkers available for automatic selection.
+
+A list of Flycheck syntax checkers to choose from when syntax
+checking a buffer.  Flycheck will automatically select a suitable
+syntax checker from this list, unless `flycheck-checker' is set,
+either directly or with `flycheck-select-checker'.
+
+You should not need to change this variable normally.  In order
+to disable syntax checkers, please use
+`flycheck-disabled-checkers'.  This variable is intended for 3rd
+party extensions to tell Flycheck about new syntax checkers.
+
+Syntax checkers in this list must be defined with
+`flycheck-define-checker'."
+  :group 'flycheck
+  :type '(repeat (symbol :tag "Checker"))
+  :risky t)
+
+(defcustom flycheck-disabled-checkers nil
+  "Syntax checkers excluded from automatic selection.
+
+A list of Flycheck syntax checkers to exclude from automatic
+selection.  Flycheck will never automatically select a syntax
+checker in this list, regardless of the value of
+`flycheck-checkers'.
+
+However, syntax checkers in this list are still available for
+manual selection with `flycheck-select-checker'.
+
+Use this variable to disable syntax checkers, instead of removing
+the syntax checkers from `flycheck-checkers'.  You may also use
+this option as a file or directory local variable to disable
+specific checkers in individual files and directories
+respectively."
+  :group 'flycheck
+  :type '(repeat (symbol :tag "Checker"))
+  :package-version '(flycheck . "0.16")
+  :safe #'flycheck-symbol-list-p)
+(make-variable-buffer-local 'flycheck-disabled-checkers)
+
+(defvar-local flycheck-checker nil
+  "Syntax checker to use for the current buffer.
+
+If unset or nil, automatically select a suitable syntax checker
+from `flycheck-checkers' on every syntax check.
+
+If set to a syntax checker only use this syntax checker and never
+select one from `flycheck-checkers' automatically.  The syntax
+checker is used regardless of whether it is contained in
+`flycheck-checkers' or `flycheck-disabled-checkers'.  If the
+syntax checker is unusable in the current buffer an error is
+signaled.
+
+A syntax checker assigned to this variable must be defined with
+`flycheck-define-checker'.
+
+Use the command `flycheck-select-checker' to select a syntax
+checker for the current buffer, or set this variable as file
+local variable to always use a specific syntax checker for a
+file.  See Info Node `(emacs)Specifying File Variables' for more
+information about file variables.")
+(put 'flycheck-checker 'safe-local-variable 'flycheck-registered-checker-p)
+
+(defcustom flycheck-locate-config-file-functions nil
+  "Functions to locate syntax checker configuration files.
+
+Each function in this hook must accept two arguments: The value
+of the configuration file variable, and the syntax checker
+symbol.  It must return either a string with an absolute path to
+the configuration file, or nil, if it cannot locate the
+configuration file.
+
+The functions in this hook are called in order of appearance, until a
+function returns non-nil.  The configuration file returned by that
+function is then given to the syntax checker if it exists.
+
+This variable is an abnormal hook.  See Info
+node `(elisp)Hooks'."
+  :group 'flycheck
+  :type 'hook
+  :risky t)
+
+(defcustom flycheck-checker-error-threshold 400
+  "Maximum errors allowed per syntax checker.
+
+The value of this variable is either an integer denoting the
+maximum number of errors per syntax checker and buffer, or nil to
+not limit the errors reported from a syntax checker.
+
+If this variable is a number and a syntax checker reports more
+errors than the value of this variable, its errors are not
+discarded, and not highlighted in the buffer or available in the
+error list.  The affected syntax checker is also disabled for
+future syntax checks of the buffer."
+  :group 'flycheck
+  :type '(choice (const :tag "Do not limit reported errors" nil)
+                 (integer :tag "Maximum number of errors"))
+  :risky t
+  :package-version '(flycheck . "0.22"))
+
+(defcustom flycheck-process-error-functions nil
+  "Functions to process errors.
+
+Each function in this hook must accept a single argument: A
+Flycheck error to process.
+
+All functions in this hook are called in order of appearance,
+until a function returns non-nil.  Thus, a function in this hook
+may return nil, to allow for further processing of the error, or
+any non-nil value, to indicate that the error was fully processed
+and inhibit any further processing.
+
+The functions are called for each newly parsed error immediately
+after the corresponding syntax checker finished.  At this stage,
+the overlays from the previous syntax checks are still present,
+and there may be further syntax checkers in the chain.
+
+This variable is an abnormal hook.  See Info
+node `(elisp)Hooks'."
+  :group 'flycheck
+  :type 'hook
+  :package-version '(flycheck . "0.13")
+  :risky t)
+
+(defcustom flycheck-display-errors-delay 0.9
+  "Delay in seconds before displaying errors at point.
+
+Use floating point numbers to express fractions of seconds."
+  :group 'flycheck
+  :type 'number
+  :package-version '(flycheck . "0.15")
+  :safe #'numberp)
+
+(defcustom flycheck-display-errors-function #'flycheck-display-error-messages
+  "Function to display error messages.
+
+If set to a function, call the function with the list of errors
+to display as single argument.  Each error is an instance of the
+`flycheck-error' struct.
+
+If set to nil, do not display errors at all."
+  :group 'flycheck
+  :type '(choice (const :tag "Display error messages"
+                        flycheck-display-error-messages)
+                 (const :tag "Display error messages only if no error list"
+                        flycheck-display-error-messages-unless-error-list)
+                 (function :tag "Error display function"))
+  :package-version '(flycheck . "0.13")
+  :risky t)
+
+(defcustom flycheck-help-echo-function #'flycheck-help-echo-all-error-messages
+  "Function to compute the contents of the error tooltips.
+
+If set to a function, call the function with the list of errors
+to display as single argument.  Each error is an instance of the
+`flycheck-error' struct.  The function is used to set the
+help-echo property of flycheck error overlays.  It should return
+a string, which is displayed when the user hovers over an error
+or presses \\[display-local-help].
+
+If set to nil, do not show error tooltips."
+  :group 'flycheck
+  :type '(choice (const :tag "Concatenate error messages to form a tooltip"
+                        flycheck-help-echo-all-error-messages)
+                 (function :tag "Help echo function"))
+  :package-version '(flycheck . "0.25")
+  :risky t)
+
+(defcustom flycheck-command-wrapper-function #'identity
+  "Function to modify checker commands before execution.
+
+The value of this option is a function which is given a list
+containing the full command of a syntax checker after
+substitution through `flycheck-substitute-argument' but before
+execution.  The function may return a new command for Flycheck to
+execute.
+
+The default value is `identity' which does not change the
+command.  You may provide your own function to run Flycheck
+commands through `bundle exec', `nix-shell' or similar wrappers."
+  :group 'flycheck
+  :type '(choice (const :tag "Do not modify commands" identity)
+                 (function :tag "Modify command with a custom function"))
+  :package-version '(flycheck . "0.25")
+  :risky t)
+
+(defcustom flycheck-executable-find #'executable-find
+  "Function to search for executables.
+
+The value of this option is a function which is given the name or
+path of an executable and shall return the full path to the
+executable, or nil if the executable does not exit.
+
+The default is the standard `executable-find' function which
+searches `exec-path'.  You can customize this option to search
+for checkers in other environments such as bundle or NixOS
+sandboxes."
+  :group 'flycheck
+  :type '(choice
+          (const :tag "Search executables in `exec-path'" executable-find)
+          (function :tag "Search executables with a custom function"))
+  :package-version '(flycheck . "0.25")
+  :risky t)
+
+(defcustom flycheck-indication-mode 'left-fringe
+  "The indication mode for Flycheck errors and warnings.
+
+This variable controls how Flycheck indicates errors in buffers.
+May either be `left-fringe', `right-fringe', or nil.
+
+If set to `left-fringe' or `right-fringe', indicate errors and
+warnings via icons in the left and right fringe respectively.
+
+If set to nil, do not indicate errors and warnings, but just
+highlight them according to `flycheck-highlighting-mode'."
+  :group 'flycheck
+  :type '(choice (const :tag "Indicate in the left fringe" left-fringe)
+                 (const :tag "Indicate in the right fringe" right-fringe)
+                 (const :tag "Do not indicate" nil))
+  :safe #'symbolp)
+
+(defcustom flycheck-highlighting-mode 'symbols
+  "The highlighting mode for Flycheck errors and warnings.
+
+The highlighting mode controls how Flycheck highlights errors in
+buffers.  The following modes are known:
+
+`columns'
+     Highlight the error column.  If the error does not have a column,
+     highlight the whole line.
+
+`symbols'
+     Highlight the symbol at the error column, if there is any,
+     otherwise behave like `columns'.  This is the default.
+
+`sexps'
+     Highlight the expression at the error column, if there is
+     any, otherwise behave like `columns'.  Note that this mode
+     can be *very* slow in some major modes.
+
+`lines'
+     Highlight the whole line.
+
+nil
+     Do not highlight errors at all.  However, errors will still
+     be reported in the mode line and in error message popups,
+     and indicated according to `flycheck-indication-mode'."
+  :group 'flycheck
+  :type '(choice (const :tag "Highlight columns only" columns)
+                 (const :tag "Highlight symbols" symbols)
+                 (const :tag "Highlight expressions" sexps)
+                 (const :tag "Highlight whole lines" lines)
+                 (const :tag "Do not highlight errors" nil))
+  :package-version '(flycheck . "0.14")
+  :safe #'symbolp)
+
+(defcustom flycheck-check-syntax-automatically '(save
+                                                 idle-change
+                                                 new-line
+                                                 mode-enabled)
+  "When Flycheck should check syntax automatically.
+
+This variable is a list of events that may trigger syntax checks.
+The following events are known:
+
+`save'
+     Check syntax immediately after the buffer was saved.
+
+`idle-change'
+     Check syntax a short time (see `flycheck-idle-change-delay')
+     after the last change to the buffer.
+
+`new-line'
+     Check syntax immediately after a new line was inserted into
+     the buffer.
+
+`mode-enabled'
+     Check syntax immediately when variable `flycheck-mode' is
+     non-nil.
+
+Flycheck performs a syntax checks only on events, which are
+contained in this list.  For instance, if the value of this
+variable is `(mode-enabled save)', Flycheck will only check if
+the mode is enabled or the buffer was saved, but never after
+changes to the buffer contents.
+
+If nil, never check syntax automatically.  In this case, use
+`flycheck-buffer' to start a syntax check manually."
+  :group 'flycheck
+  :type '(set (const :tag "After the buffer was saved" save)
+              (const :tag "After the buffer was changed and idle" idle-change)
+              (const :tag "After a new line was inserted" new-line)
+              (const :tag "After `flycheck-mode' was enabled" mode-enabled))
+  :package-version '(flycheck . "0.12")
+  :safe #'flycheck-symbol-list-p)
+
+(defcustom flycheck-idle-change-delay 0.5
+  "How many seconds to wait before checking syntax automatically.
+
+After the buffer was changed, Flycheck will wait as many seconds
+as the value of this variable before starting a syntax check.  If
+the buffer is modified during this time, Flycheck will wait
+again.
+
+This variable has no effect, if `idle-change' is not contained in
+`flycheck-check-syntax-automatically'."
+  :group 'flycheck
+  :type 'number
+  :package-version '(flycheck . "0.13")
+  :safe #'numberp)
+
+(defcustom flycheck-standard-error-navigation t
+  "Whether to support error navigation with `next-error'.
+
+If non-nil, enable navigation of Flycheck errors with
+`next-error', `previous-error' and `first-error'.  Otherwise,
+these functions just navigate errors from compilation modes.
+
+Flycheck error navigation with `flycheck-next-error',
+`flycheck-previous-error' and `flycheck-first-error' is always
+enabled, regardless of the value of this variable.
+
+Note that this setting only takes effect when variable
+`flycheck-mode' is non-nil.  Changing it will not affect buffers
+where variable `flycheck-mode' is already non-nil."
+  :group 'flycheck
+  :type 'boolean
+  :package-version '(flycheck . "0.15")
+  :safe #'booleanp)
+
+(define-widget 'flycheck-minimum-level 'lazy
+  "A radio-type choice of minimum error levels.
+
+See `flycheck-navigation-minimum-level' and
+`flycheck-error-list-minimum-level'."
+  :type '(radio (const :tag "All locations" nil)
+                (const :tag "Informational messages" info)
+                (const :tag "Warnings" warning)
+                (const :tag "Errors" error)
+                (symbol :tag "Custom error level")))
+
+(defcustom flycheck-navigation-minimum-level nil
+  "The minimum level of errors to navigate.
+
+If set to an error level, only navigate errors whose error level
+is at least as severe as this one.  If nil, navigate all errors."
+  :group 'flycheck
+  :type 'flycheck-minimum-level
+  :safe #'flycheck-error-level-p
+  :package-version '(flycheck . "0.21"))
+
+(defcustom flycheck-error-list-minimum-level nil
+  "The minimum level of errors to display in the error list.
+
+If set to an error level, only display errors whose error level
+is at least as severe as this one in the error list.  If nil,
+display all errors.
+
+This is the default level, used when the error list is opened.
+You can temporarily change the level using
+\\[flycheck-error-list-set-filter], or reset it to this value
+using \\[flycheck-error-list-reset-filter]."
+  :group 'flycheck
+  :type 'flycheck-minimum-level
+  :safe #'flycheck-error-level-p
+  :package-version '(flycheck . "0.24"))
+
+(defcustom flycheck-completing-read-function #'completing-read
+  "Function to read from minibuffer with completion.
+
+The function must be compatible to the built-in `completing-read'
+function."
+  :group 'flycheck
+  :type '(choice (const :tag "Default" completing-read)
+                 (const :tag "IDO" ido-completing-read)
+                 (function :tag "Custom function"))
+  :risky t
+  :package-version '(flycheck . "26"))
+
+(defcustom flycheck-temp-prefix "flycheck"
+  "Prefix for temporary files created by Flycheck."
+  :group 'flycheck
+  :type 'string
+  :package-version '(flycheck . "0.19")
+  :risky t)
+
+(defcustom flycheck-mode-hook nil
+  "Hooks to run after command `flycheck-mode' is toggled."
+  :group 'flycheck
+  :type 'hook
+  :risky t)
+
+(defcustom flycheck-after-syntax-check-hook nil
+  "Functions to run after each syntax check.
+
+This hook is run after a syntax check was finished.
+
+At this point, *all* chained checkers were run, and all errors
+were parsed, highlighted and reported.  The variable
+`flycheck-current-errors' contains all errors from all syntax
+checkers run during the syntax check, so you can apply any error
+analysis functions.
+
+Note that this hook does *not* run after each individual syntax
+checker in the syntax checker chain, but only after the *last
+checker*.
+
+This variable is a normal hook.  See Info node `(elisp)Hooks'."
+  :group 'flycheck
+  :type 'hook
+  :risky t)
+
+(defcustom flycheck-before-syntax-check-hook nil
+  "Functions to run before each syntax check.
+
+This hook is run right before a syntax check starts.
+
+Error information from the previous syntax check is *not*
+cleared before this hook runs.
+
+Note that this hook does *not* run before each individual syntax
+checker in the syntax checker chain, but only before the *first
+checker*.
+
+This variable is a normal hook.  See Info node `(elisp)Hooks'."
+  :group 'flycheck
+  :type 'hook
+  :risky t)
+
+(defcustom flycheck-syntax-check-failed-hook nil
+  "Functions to run if a syntax check failed.
+
+This hook is run whenever an error occurs during Flycheck's
+internal processing.  No information about the error is given to
+this hook.
+
+You should use this hook to conduct additional cleanup actions
+when Flycheck failed.
+
+This variable is a normal hook.  See Info node `(elisp)Hooks'."
+  :group 'flycheck
+  :type 'hook
+  :risky t)
+
+(defcustom flycheck-status-changed-functions nil
+  "Functions to run if the Flycheck status changed.
+
+This hook is run whenever the status of Flycheck changes.  Each
+hook function takes the status symbol as single argument, as
+given to `flycheck-report-status', which see.
+
+This variable is an abnormal hook.  See Info
+node `(elisp)Hooks'."
+  :group 'flycheck
+  :type 'hook
+  :risky t
+  :package-version '(flycheck . "0.20"))
+
+(defcustom flycheck-error-list-after-refresh-hook nil
+  "Functions to run after the error list was refreshed.
+
+This hook is run whenever the error list is refreshed.
+
+This variable is a normal hook.  See Info node `(elisp)Hooks'."
+  :group 'flycheck
+  :type 'hook
+  :risky t
+  :package-version '(flycheck . "0.21"))
+
+(defface flycheck-error
+  '((((supports :underline (:style wave)))
+     :underline (:style wave :color "Red1"))
+    (t
+     :underline t :inherit error))
+  "Flycheck face for errors."
+  :package-version '(flycheck . "0.13")
+  :group 'flycheck-faces)
+
+(defface flycheck-warning
+  '((((supports :underline (:style wave)))
+     :underline (:style wave :color "DarkOrange"))
+    (t
+     :underline t :inherit warning))
+  "Flycheck face for warnings."
+  :package-version '(flycheck . "0.13")
+  :group 'flycheck-faces)
+
+(defface flycheck-info
+  '((((supports :underline (:style wave)))
+     :underline (:style wave :color "ForestGreen"))
+    (t
+     :underline t :inherit success))
+  "Flycheck face for informational messages."
+  :package-version '(flycheck . "0.15")
+  :group 'flycheck-faces)
+
+(defface flycheck-fringe-error
+  '((t :inherit error))
+  "Flycheck face for fringe error indicators."
+  :package-version '(flycheck . "0.13")
+  :group 'flycheck-faces)
+
+(defface flycheck-fringe-warning
+  '((t :inherit warning))
+  "Flycheck face for fringe warning indicators."
+  :package-version '(flycheck . "0.13")
+  :group 'flycheck-faces)
+
+(defface flycheck-fringe-info
+  ;; Semantically `success' is probably not the right face, but it looks nice as
+  ;; a base face
+  '((t :inherit success))
+  "Flycheck face for fringe info indicators."
+  :package-version '(flycheck . "0.15")
+  :group 'flycheck-faces)
+
+(defface flycheck-error-list-error
+  '((t :inherit error))
+  "Flycheck face for error messages in the error list."
+  :package-version '(flycheck . "0.16")
+  :group 'flycheck-faces)
+
+(defface flycheck-error-list-warning
+  '((t :inherit warning))
+  "Flycheck face for warning messages in the error list."
+  :package-version '(flycheck . "0.16")
+  :group 'flycheck-faces)
+
+(defface flycheck-error-list-info
+  '((t :inherit success))
+  "Flycheck face for info messages in the error list."
+  :package-version '(flycheck . "0.16")
+  :group 'flycheck-faces)
+
+;; The base faces for the following two faces are inspired by Compilation Mode
+(defface flycheck-error-list-line-number
+  '((t :inherit font-lock-constant-face))
+  "Face for line numbers in the error list."
+  :group 'flycheck-faces
+  :package-version '(flycheck . "0.16"))
+
+(defface flycheck-error-list-column-number
+  '((t :inherit font-lock-constant-face))
+  "Face for line numbers in the error list."
+  :group 'flycheck-faces
+  :package-version '(flycheck . "0.16"))
+
+(defface flycheck-error-list-filename
+  '((t :inherit font-lock-variable-name-face))
+  "Face for filenames in the error list."
+  :group 'flycheck-faces
+  :package-version '(flycheck . "32"))
+
+(defface flycheck-error-list-id
+  '((t :inherit font-lock-type-face))
+  "Face for the error ID in the error list."
+  :group 'flycheck-faces
+  :package-version '(flycheck . "0.22"))
+
+(defface flycheck-error-list-id-with-explainer
+  '((t :inherit flycheck-error-list-id
+       :box (:style released-button)))
+  "Face for the error ID in the error list, for errors that have an explainer."
+  :group 'flycheck-faces
+  :package-version '(flycheck . "30"))
+
+(defface flycheck-error-list-checker-name
+  '((t :inherit font-lock-function-name-face))
+  "Face for the syntax checker name in the error list."
+  :group 'flycheck-faces
+  :package-version '(flycheck . "0.21"))
+
+(defface flycheck-error-list-highlight
+  '((t :inherit highlight))
+  "Flycheck face to highlight errors in the error list."
+  :package-version '(flycheck . "0.15")
+  :group 'flycheck-faces)
+
+(defvar flycheck-command-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map "c"         #'flycheck-buffer)
+    (define-key map "C"         #'flycheck-clear)
+    (define-key map (kbd "C-c") #'flycheck-compile)
+    (define-key map "n"         #'flycheck-next-error)
+    (define-key map "p"         #'flycheck-previous-error)
+    (define-key map "l"         #'flycheck-list-errors)
+    (define-key map (kbd "C-w") #'flycheck-copy-errors-as-kill)
+    (define-key map "s"         #'flycheck-select-checker)
+    (define-key map "?"         #'flycheck-describe-checker)
+    (define-key map "h"         #'flycheck-display-error-at-point)
+    (define-key map "e"         #'flycheck-explain-error-at-point)
+    (define-key map "H"         #'display-local-help)
+    (define-key map "i"         #'flycheck-manual)
+    (define-key map "V"         #'flycheck-version)
+    (define-key map "v"         #'flycheck-verify-setup)
+    (define-key map "x"         #'flycheck-disable-checker)
+    map)
+  "Keymap of Flycheck interactive commands.")
+
+(defcustom flycheck-keymap-prefix (kbd "C-c !")
+  "Prefix for key bindings of Flycheck.
+
+Changing this variable outside Customize does not have any
+effect.  To change the keymap prefix from Lisp, you need to
+explicitly re-define the prefix key:
+
+    (define-key flycheck-mode-map flycheck-keymap-prefix nil)
+    (setq flycheck-keymap-prefix (kbd \"C-c f\"))
+    (define-key flycheck-mode-map flycheck-keymap-prefix
+                flycheck-command-map)
+
+Please note that Flycheck's manual documents the default
+keybindings.  Changing this variable is at your own risk."
+  :group 'flycheck
+  :package-version '(flycheck . "0.19")
+  :type 'string
+  :risky t
+  :set
+  (lambda (variable key)
+    (when (and (boundp variable) (boundp 'flycheck-mode-map))
+      (define-key flycheck-mode-map (symbol-value variable) nil)
+      (define-key flycheck-mode-map key flycheck-command-map))
+    (set-default variable key)))
+
+(defcustom flycheck-mode-line '(:eval (flycheck-mode-line-status-text))
+  "Mode line lighter for Flycheck.
+
+The value of this variable is a mode line template as in
+`mode-line-format'.  See Info Node `(elisp)Mode Line Format' for
+more information.  Note that it should contain a _single_ mode
+line construct only.
+
+Customize this variable to change how Flycheck reports its status
+in the mode line.  You may use `flycheck-mode-line-status-text'
+to obtain a human-readable status text, including an
+error/warning count.
+
+You may also assemble your own status text.  The current status
+of Flycheck is available in `flycheck-last-status-change'.  The
+errors in the current buffer are stored in
+`flycheck-current-errors', and the function
+`flycheck-count-errors' may be used to obtain the number of
+errors grouped by error level.
+
+Set this variable to nil to disable the mode line completely."
+  :group 'flycheck
+  :type 'sexp
+  :risky t
+  :package-version '(flycheck . "0.20"))
+
+(defcustom flycheck-mode-line-prefix "FlyC"
+  "Base mode line lighter for Flycheck.
+
+This will have an effect only with the default
+`flycheck-mode-line'.
+
+If you've customized `flycheck-mode-line' then the customized
+function must be updated to use this variable."
+  :group 'flycheck
+  :type 'string
+  :package-version '(flycheck . "26"))
+
+(defcustom flycheck-error-list-mode-line
+  `(,(propertized-buffer-identification "%12b")
+    " for buffer "
+    (:eval (flycheck-error-list-propertized-source-name))
+    (:eval (flycheck-error-list-mode-line-filter-indicator)))
+  "Mode line construct for Flycheck error list.
+
+The value of this variable is a mode line template as in
+`mode-line-format', to be used as
+`mode-line-buffer-identification' in `flycheck-error-list-mode'.
+See Info Node `(elisp)Mode Line Format' for more information.
+
+Customize this variable to change how the error list appears in
+the mode line.  The default shows the name of the buffer and the
+name of the source buffer, i.e. the buffer whose errors are
+currently listed."
+  :group 'flycheck
+  :type 'sexp
+  :risky t
+  :package-version '(flycheck . "0.20"))
+
+(defcustom flycheck-global-modes t
+  "Modes for which option `flycheck-mode' is turned on.
+
+If t, Flycheck Mode is turned on for all major modes.  If a list,
+Flycheck Mode is turned on for all `major-mode' symbols in that
+list.  If the `car' of the list is `not', Flycheck Mode is turned
+on for all `major-mode' symbols _not_ in that list.  If nil,
+Flycheck Mode is never turned on by command
+`global-flycheck-mode'.
+
+Note that Flycheck is never turned on for modes whose
+`mode-class' property is `special' (see Info node `(elisp)Major
+Mode Conventions'), regardless of the value of this option.
+
+Only has effect when variable `global-flycheck-mode' is non-nil."
+  :group 'flycheck
+  :type '(choice (const :tag "none" nil)
+                 (const :tag "all" t)
+                 (set :menu-tag "mode specific" :tag "modes"
+                      :value (not)
+                      (const :tag "Except" not)
+                      (repeat :inline t (symbol :tag "mode"))))
+  :risky t
+  :package-version '(flycheck . "0.23"))
+
+;; Add built-in functions to our hooks, via `add-hook', to make sure that our
+;; functions are really present, even if the variable was implicitly defined by
+;; another call to `add-hook' that occurred before Flycheck was loaded.  See
+;; http://lists.gnu.org/archive/html/emacs-devel/2015-02/msg01271.html for why
+;; we don't initialize the hook variables right away.  We append our own
+;; functions, because a user likely expects that their functions come first,
+;; even if the added them before Flycheck was loaded.
+(dolist (hook (list #'flycheck-locate-config-file-by-path
+                    #'flycheck-locate-config-file-ancestor-directories
+                    #'flycheck-locate-config-file-home))
+  (add-hook 'flycheck-locate-config-file-functions hook 'append))
+
+(add-hook 'flycheck-process-error-functions #'flycheck-add-overlay 'append)
+
+
+;;; Global Flycheck menu
+(defvar flycheck-mode-menu-map
+  (easy-menu-create-menu
+   "Syntax Checking"
+   '(["Enable on-the-fly syntax checking" flycheck-mode
+      :style toggle :selected flycheck-mode
+      :enable (or flycheck-mode
+                  ;; Don't let users toggle the mode if there is no syntax
+                  ;; checker for this buffer
+                  (seq-find #'flycheck-checker-supports-major-mode-p
+                            flycheck-checkers))]
+     ["Check current buffer" flycheck-buffer flycheck-mode]
+     ["Clear errors in buffer" flycheck-clear t]
+     "---"
+     ["Go to next error" flycheck-next-error flycheck-mode]
+     ["Go to previous error" flycheck-previous-error flycheck-mode]
+     ["Show all errors" flycheck-list-errors flycheck-mode]
+     "---"
+     ["Copy messages at point" flycheck-copy-errors-as-kill
+      (flycheck-overlays-at (point))]
+     ["Explain error at point" flycheck-explain-error-at-point]
+     "---"
+     ["Select syntax checker" flycheck-select-checker flycheck-mode]
+     ["Disable syntax checker" flycheck-disable-checker flycheck-mode]
+     ["Set executable of syntax checker" flycheck-set-checker-executable
+      flycheck-mode]
+     "---"
+     ["Describe syntax checker" flycheck-describe-checker t]
+     ["Show Flycheck version" flycheck-version t]
+     ["Read the Flycheck manual" flycheck-info t]))
+  "Menu of command `flycheck-mode'.")
+
+(easy-menu-add-item nil '("Tools") flycheck-mode-menu-map "Spell Checking")
+
+
+;;; Version information, manual and loading of Flycheck
+(defun flycheck-version (&optional show-version)
+  "Get the Flycheck version as string.
+
+If called interactively or if SHOW-VERSION is non-nil, show the
+version in the echo area and the messages buffer.
+
+The returned string includes both, the version from package.el
+and the library version, if both a present and different.
+
+If the version number could not be determined, signal an error,
+if called interactively, or if SHOW-VERSION is non-nil, otherwise
+just return nil."
+  (interactive (list t))
+  (let ((version (pkg-info-version-info 'flycheck)))
+    (when show-version
+      (message "Flycheck version: %s" version))
+    version))
+
+(defun flycheck-unload-function ()
+  "Unload function for Flycheck."
+  (global-flycheck-mode -1)
+  (easy-menu-remove-item nil '("Tools") (cadr flycheck-mode-menu-map))
+  (remove-hook 'kill-emacs-hook #'flycheck-global-teardown)
+  (setq find-function-regexp-alist
+        (assq-delete-all 'flycheck-checker find-function-regexp-alist)))
+
+;;;###autoload
+(defun flycheck-manual ()
+  "Open the Flycheck manual."
+  (interactive)
+  (browse-url "http://www.flycheck.org"))
+
+(define-obsolete-function-alias 'flycheck-info
+  'flycheck-manual "26" "Open the Flycheck manual.")
+
+
+;;; Utility functions
+(defun flycheck-sexp-to-string (sexp)
+  "Convert SEXP to a string.
+
+Like `prin1-to-string' but ensure that the returned string
+is loadable."
+  (let ((print-quoted t)
+        (print-length nil)
+        (print-level nil))
+    (prin1-to-string sexp)))
+
+(defun flycheck-string-to-number-safe (string)
+  "Safely convert STRING to a number.
+
+If STRING is of string type and a numeric string, convert STRING
+to a number and return it.  Otherwise return nil."
+  (let ((number-re (rx string-start (one-or-more (any digit)) string-end)))
+    (when (and (stringp string) (string-match-p number-re string))
+      (string-to-number string))))
+
+(defun flycheck-string-list-p (obj)
+  "Determine if OBJ is a list of strings."
+  (and (listp obj) (seq-every-p #'stringp obj)))
+
+(defun flycheck-symbol-list-p (obj)
+  "Determine if OBJ is a list of symbols."
+  (and (listp obj) (seq-every-p #'symbolp obj)))
+
+(defun flycheck-same-files-p (file-a file-b)
+  "Determine whether FILE-A and FILE-B refer to the same file."
+  (let ((file-a (expand-file-name file-a))
+        (file-b (expand-file-name file-b)))
+    ;; We must resolve symbolic links here, since some syntax checker always
+    ;; output canonical file names with all symbolic links resolved.  However,
+    ;; we still do a simple path compassion first, to avoid the comparatively
+    ;; expensive file system call if possible.  See
+    ;; https://github.com/flycheck/flycheck/issues/561
+    (or (string= (directory-file-name file-a) (directory-file-name file-b))
+        (string= (directory-file-name (file-truename file-a))
+                 (directory-file-name (file-truename file-b))))))
+
+(defvar-local flycheck-temporaries nil
+  "Temporary files and directories created by Flycheck.")
+
+(defun flycheck-temp-dir-system ()
+  "Create a unique temporary directory.
+
+Use `flycheck-temp-prefix' as prefix, and add the directory to
+`flycheck-temporaries'.
+
+Return the path of the directory"
+  (let* ((tempdir (make-temp-file flycheck-temp-prefix 'directory)))
+    (push tempdir flycheck-temporaries)
+    tempdir))
+
+(defun flycheck-temp-file-system (filename)
+  "Create a temporary file named after FILENAME.
+
+If FILENAME is non-nil, this function creates a temporary
+directory with `flycheck-temp-dir-system', and creates a file
+with the same name as FILENAME in this directory.
+
+Otherwise this function creates a temporary file with
+`flycheck-temp-prefix' and a random suffix.  The path of the file
+is added to `flycheck-temporaries'.
+
+Return the path of the file."
+  (let ((tempfile (convert-standard-filename
+                   (if filename
+                       (expand-file-name (file-name-nondirectory filename)
+                                         (flycheck-temp-dir-system))
+                     (make-temp-file flycheck-temp-prefix)))))
+    (push tempfile flycheck-temporaries)
+    tempfile))
+
+(defun flycheck-temp-file-inplace (filename)
+  "Create an in-place copy of FILENAME.
+
+Prefix the file with `flycheck-temp-prefix' and add the path of
+the file to `flycheck-temporaries'.
+
+If FILENAME is nil, fall back to `flycheck-temp-file-system'.
+
+Return the path of the file."
+  (if filename
+      (let* ((tempname (format "%s_%s"
+                               flycheck-temp-prefix
+                               (file-name-nondirectory filename)))
+             (tempfile (convert-standard-filename
+                        (expand-file-name tempname
+                                          (file-name-directory filename)))))
+        (push tempfile flycheck-temporaries)
+        tempfile)
+    (flycheck-temp-file-system filename)))
+
+(defun flycheck-temp-directory (checker)
+  "Return the directory where CHECKER writes temporary files.
+
+Return nil if the CHECKER does not write temporary files."
+  (let ((args (flycheck-checker-arguments checker)))
+    (cond
+     ((memq 'source args) temporary-file-directory)
+     ((memq 'source-inplace args)
+      (if buffer-file-name (file-name-directory buffer-file-name)
+        temporary-file-directory))
+     (t nil))))
+
+(defun flycheck-temp-files-writable-p (checker)
+  "Whether CHECKER can write temporary files.
+
+If CHECKER has `source' or `source-inplace' in its `:command',
+return whether flycheck has the permissions to create the
+respective temporary files.
+
+Return t if CHECKER does not use temporary files."
+  (let ((dir (flycheck-temp-directory checker)))
+    (or (not dir) (file-writable-p dir))))
+
+(defun flycheck-save-buffer-to-file (file-name)
+  "Save the contents of the current buffer to FILE-NAME."
+  (make-directory (file-name-directory file-name) t)
+  (let ((jka-compr-inhibit t))
+    (write-region nil nil file-name nil 0)))
+
+(defun flycheck-save-buffer-to-temp (temp-file-fn)
+  "Save buffer to temp file returned by TEMP-FILE-FN.
+
+Return the name of the temporary file."
+  (let ((filename (funcall temp-file-fn (buffer-file-name))))
+    ;; Do not flush short-lived temporary files onto disk
+    (let ((write-region-inhibit-fsync t))
+      (flycheck-save-buffer-to-file filename))
+    filename))
+
+(defun flycheck-prepend-with-option (option items &optional prepend-fn)
+  "Prepend OPTION to each item in ITEMS, using PREPEND-FN.
+
+Prepend OPTION to each item in ITEMS.
+
+ITEMS is a list of strings to pass to the syntax checker.  OPTION
+is the option, as string.  PREPEND-FN is a function called to
+prepend OPTION to each item in ITEMS.  It receives the option and
+a single item from ITEMS as argument, and must return a string or
+a list of strings with OPTION prepended to the item.  If
+PREPEND-FN is nil or omitted, use `list'.
+
+Return a list of strings where OPTION is prepended to each item
+in ITEMS using PREPEND-FN.  If PREPEND-FN returns a list, it is
+spliced into the resulting list."
+  (unless (stringp option)
+    (error "Option %S is not a string" option))
+  (unless prepend-fn
+    (setq prepend-fn #'list))
+  (let ((prepend
+         (lambda (item)
+           (let ((result (funcall prepend-fn option item)))
+             (cond
+              ((and (listp result) (seq-every-p #'stringp result)) result)
+              ((stringp result) (list result))
+              (t (error "Invalid result type for option: %S" result)))))))
+    (apply #'append (seq-map prepend items))))
+
+(defun flycheck-find-in-buffer (pattern)
+  "Find PATTERN in the current buffer.
+
+Return the result of the first matching group of PATTERN, or nil,
+if PATTERN did not match."
+  (save-restriction
+    (widen)
+    (save-excursion
+      (goto-char (point-min))
+      (when (re-search-forward pattern nil 'no-error)
+        (match-string-no-properties 1)))))
+
+(defun flycheck-buffer-empty-p (&optional buffer)
+  "Whether a BUFFER is empty.
+
+If buffer is nil or omitted check the current buffer.
+
+Return non-nil if so, or nil if the buffer has content."
+  (<= (buffer-size buffer) 0))
+
+(defun flycheck-ephemeral-buffer-p ()
+  "Determine whether the current buffer is an ephemeral buffer.
+
+See Info node `(elisp)Buffer Names' for information about
+ephemeral buffers."
+  (string-prefix-p " " (buffer-name)))
+
+(defun flycheck-encrypted-buffer-p ()
+  "Determine whether the current buffer is an encrypted file.
+
+See Info node `(epa)Top' for Emacs' interface to encrypted
+files."
+  ;; The EPA file handler sets this variable locally to remember the recipients
+  ;; of the encrypted file for re-encryption.  Hence, a local binding of this
+  ;; variable is a good indication that the buffer is encrypted.  I haven't
+  ;; found any better indicator anyway.
+  (local-variable-p 'epa-file-encrypt-to))
+
+(defun flycheck-autoloads-file-p ()
+  "Determine whether the current buffer is an autoloads file.
+
+Autoloads are generated by package.el during installation."
+  (string-suffix-p "-autoloads.el" (buffer-name)))
+
+(defun flycheck-in-user-emacs-directory-p (filename)
+  "Whether FILENAME is in `user-emacs-directory'."
+  (string-prefix-p (file-name-as-directory (file-truename user-emacs-directory))
+                   (file-truename filename)))
+
+(defun flycheck-safe-delete (file-or-dir)
+  "Safely delete FILE-OR-DIR."
+  (ignore-errors
+    (if (file-directory-p file-or-dir)
+        (delete-directory file-or-dir 'recursive)
+      (delete-file file-or-dir))))
+
+(defun flycheck-safe-delete-temporaries ()
+  "Safely delete all temp files and directories of Flycheck.
+
+Safely delete all files and directories listed in
+`flycheck-temporaries' and set the variable's value to nil."
+  (seq-do #'flycheck-safe-delete flycheck-temporaries)
+  (setq flycheck-temporaries nil))
+
+(defun flycheck-rx-file-name (form)
+  "Translate the `(file-name)' FORM into a regular expression."
+  (let ((body (or (cdr form) '((minimal-match
+                                (one-or-more not-newline))))))
+    (rx-submatch-n `(group-n 1 ,@body))))
+
+(defun flycheck-rx-message (form)
+  "Translate the `(message)' FORM into a regular expression."
+  (let ((body (or (cdr form) '((one-or-more not-newline)))))
+    (rx-submatch-n `(group-n 4 ,@body))))
+
+(defun flycheck-rx-id (form)
+  "Translate the `(id)' FORM into a regular expression."
+  (rx-submatch-n `(group-n 5 ,@(cdr form))))
+
+(defun flycheck-rx-to-string (form &optional no-group)
+  "Like `rx-to-string' for FORM, but with special keywords:
+
+`line'
+     matches the line number.
+
+`column'
+     matches the column number.
+
+`(file-name SEXP ...)'
+     matches the file name.  SEXP describes the file name.  If no
+     SEXP is given, use a default body of `(minimal-match
+     (one-or-more not-newline))'.
+
+`(message SEXP ...)'
+     matches the message.  SEXP constitutes the body of the
+     message.  If no SEXP is given, use a default body
+     of `(one-or-more not-newline)'.
+
+`(id SEXP ...)'
+     matches an error ID.  SEXP describes the ID.
+
+NO-GROUP is passed to `rx-to-string'.
+
+See `rx' for a complete list of all built-in `rx' forms."
+  (let ((rx-constituents
+         (append
+          `((line . ,(rx (group-n 2 (one-or-more digit))))
+            (column . ,(rx (group-n 3 (one-or-more digit))))
+            (file-name flycheck-rx-file-name 0 nil)
+            (message flycheck-rx-message 0 nil)
+            (id flycheck-rx-id 0 nil))
+          rx-constituents nil)))
+    (rx-to-string form no-group)))
+
+(defun flycheck-current-load-file ()
+  "Get the source file currently being loaded.
+
+Always return the name of the corresponding source file, never
+any byte-compiled file.
+
+Return nil, if the currently loaded file cannot be determined."
+  (-when-let* ((this-file (cond
+                           (load-in-progress load-file-name)
+                           ((bound-and-true-p byte-compile-current-file))
+                           (t (buffer-file-name))))
+               ;; A best guess for the source file of a compiled library. Works
+               ;; well in most cases, and especially for ELPA packages
+               (source-file (concat (file-name-sans-extension this-file)
+                                    ".el")))
+    (when (file-exists-p source-file)
+      source-file)))
+
+(defun flycheck-module-root-directory (module &optional file-name)
+  "Get the root directory for a MODULE in FILE-NAME.
+
+MODULE is a qualified module name, either a string with
+components separated by a dot, or as list of components.
+FILE-NAME is the name of the file or directory containing the
+module as string.  When nil or omitted, defaults to the return
+value of function `buffer-file-name'.
+
+Return the root directory of the module, that is, the directory,
+from which FILE-NAME can be reached by descending directories
+along each part of MODULE.
+
+If the MODULE name does not match the directory hierarchy upwards
+from FILE-NAME, return the directory containing FILE-NAME.  When
+FILE-NAME is nil, return `default-directory'."
+  (let ((file-name (or file-name (buffer-file-name)))
+        (module-components (if (stringp module)
+                               (split-string module (rx "."))
+                             (copy-sequence module))))
+    (if (and module-components file-name)
+        (let ((parts (nreverse module-components))
+              (base-directory (directory-file-name
+                               (file-name-sans-extension file-name))))
+          (while (and parts
+                      (string= (file-name-nondirectory base-directory)
+                               (car parts)))
+            (pop parts)
+            (setq base-directory (directory-file-name
+                                  (file-name-directory base-directory))))
+          (file-name-as-directory base-directory))
+      (if file-name
+          (file-name-directory file-name)
+        (expand-file-name default-directory)))))
+
+
+;;; Minibuffer tools
+(defvar read-flycheck-checker-history nil
+  "`completing-read' history of `read-flycheck-checker'.")
+
+(defun flycheck-completing-read (prompt candidates default &optional history)
+  "Read a value from the minibuffer.
+
+Use `flycheck-completing-read-function' to read input from the
+minibuffer with completion.
+
+Show PROMPT and read one of CANDIDATES, defaulting to DEFAULT.
+HISTORY is passed to `flycheck-completing-read-function'."
+  (funcall flycheck-completing-read-function
+           prompt candidates nil 'require-match nil history default))
+
+(defun read-flycheck-checker (prompt &optional default property candidates)
+  "Read a flycheck checker from minibuffer with PROMPT and DEFAULT.
+
+PROMPT is a string to show in the minibuffer as prompt.  It
+should end with a single space.  DEFAULT is a symbol denoting the
+default checker to use, if the user did not select any checker.
+PROPERTY is a symbol denoting a syntax checker property.  If
+non-nil, only complete syntax checkers which have a non-nil value
+for PROPERTY.  CANDIDATES is an optional list of all syntax
+checkers available for completion, defaulting to all defined
+checkers.  If given, PROPERTY is ignored.
+
+Return the checker as symbol, or DEFAULT if no checker was
+chosen.  If DEFAULT is nil and no checker was chosen, signal a
+`user-error' if the underlying completion system does not provide
+a default on its own."
+  (when (and default (not (flycheck-valid-checker-p default)))
+    (error "%S is no valid Flycheck checker" default))
+  (let* ((candidates (seq-map #'symbol-name
+                              (or candidates
+                                  (flycheck-defined-checkers property))))
+         (default (and default (symbol-name default)))
+         (input (flycheck-completing-read
+                 prompt candidates default
+                 'read-flycheck-checker-history)))
+    (when (string-empty-p input)
+      (unless default
+        (user-error "No syntax checker selected"))
+      (setq input default))
+    (let ((checker (intern input)))
+      (unless (flycheck-valid-checker-p checker)
+        (error "%S is not a valid Flycheck syntax checker" checker))
+      checker)))
+
+(defun read-flycheck-error-level (prompt)
+  "Read an error level from the user with PROMPT.
+
+Only offers level for which errors currently exist, in addition
+to the default levels."
+  (let* ((levels (seq-map #'flycheck-error-level
+                          (flycheck-error-list-current-errors)))
+         (levels-with-defaults (append '(info warning error) levels))
+         (uniq-levels (seq-uniq levels-with-defaults))
+         (level (flycheck-completing-read prompt uniq-levels nil)))
+    (and (stringp level) (intern level))))
+
+
+;;; Checker API
+(defun flycheck-defined-checkers (&optional property)
+  "Find all defined syntax checkers, optionally with PROPERTY.
+
+PROPERTY is a symbol.  If given, only return syntax checkers with
+a non-nil value for PROPERTY.
+
+The returned list is sorted alphapetically by the symbol name of
+the syntax checkers."
+  (let (defined-checkers)
+    (mapatoms (lambda (symbol)
+                (when (and (flycheck-valid-checker-p symbol)
+                           (or (null property)
+                               (flycheck-checker-get symbol property)))
+                  (push symbol defined-checkers))))
+    (sort defined-checkers #'string<)))
+
+(defun flycheck-registered-checker-p (checker)
+  "Determine whether CHECKER is registered.
+
+A checker is registered if it is contained in
+`flycheck-checkers'."
+  (and (flycheck-valid-checker-p checker)
+       (memq checker flycheck-checkers)))
+
+(defun flycheck-disabled-checker-p (checker)
+  "Determine whether CHECKER is disabled.
+
+A checker is disabled if it is contained in
+`flycheck-disabled-checkers'."
+  (memq checker flycheck-disabled-checkers))
+
+
+;;; Generic syntax checkers
+(defconst flycheck-generic-checker-version 2
+  "The internal version of generic syntax checker declarations.
+
+Flycheck will not use syntax checkers whose generic version is
+less than this constant.")
+
+(defsubst flycheck--checker-property-name (property)
+  "Return the SYMBOL property for checker PROPERTY."
+  (intern (concat "flycheck-" (symbol-name property))))
+
+(defun flycheck-checker-get (checker property)
+  "Get the value of CHECKER's PROPERTY."
+  (get checker (flycheck--checker-property-name property)))
+
+(gv-define-setter flycheck-checker-get (value checker property)
+  `(setf (get ,checker (flycheck--checker-property-name ,property)) ,value))
+
+(defun flycheck-validate-next-checker (next &optional strict)
+  "Validate NEXT checker.
+
+With STRICT non-nil, also check whether the syntax checker and
+the error level in NEXT are valid.  Otherwise just check whether
+these are symbols.
+
+Signal an error if NEXT is not a valid entry for
+`:next-checkers'."
+  (when (symbolp next)
+    (setq next (cons t next)))
+  (pcase next
+    (`(,level . ,checker)
+     (if strict
+         (progn
+           (unless (or (eq level t) (flycheck-error-level-p level))
+             (error "%S is not a valid Flycheck error level" level))
+           (unless (flycheck-valid-checker-p checker)
+             (error "%s is not a valid Flycheck syntax checker" checker)))
+       (unless (symbolp level)
+         (error "Error level %S must be a symbol" level))
+       (unless (symbolp checker)
+         (error "Checker %S must be a symbol" checker))))
+    (_ (error "%S must be a symbol or cons cell" next)))
+  t)
+
+(defun flycheck-define-generic-checker (symbol docstring &rest properties)
+  "Define SYMBOL as generic syntax checker.
+
+Any syntax checker defined with this macro is eligible for manual
+syntax checker selection with `flycheck-select-checker'.  To make
+the new syntax checker available for automatic selection, it must
+be registered in `flycheck-checkers'.
+
+DOCSTRING is the documentation of the syntax checker, for
+`flycheck-describe-checker'.  The following PROPERTIES constitute
+a generic syntax checker.  Unless otherwise noted, all properties
+are mandatory.
+
+`:start FUNCTION'
+     A function to start the syntax checker.
+
+     FUNCTION shall take two arguments and return a context
+     object if the checker is started successfully.  Otherwise it
+     shall signal an error.
+
+     The first argument is the syntax checker being started.  The
+     second is a callback function to report state changes to
+     Flycheck.  The callback takes two arguments STATUS DATA,
+     where STATUS is a symbol denoting the syntax checker status
+     and DATA an optional argument with additional data for the
+     status report.  See `flycheck-report-buffer-checker-status'
+     for more information about STATUS and DATA.
+
+     FUNCTION may be synchronous or asynchronous, i.e. it may
+     call the given callback either immediately, or at some later
+     point (e.g. from a process sentinel).
+
+     A syntax checker _must_ call CALLBACK at least once with a
+     STATUS that finishes the current syntax checker.  Otherwise
+     Flycheck gets stuck at the current syntax check with this
+     syntax checker.
+
+     The context object returned by FUNCTION is passed to
+     `:interrupt'.
+
+`:interrupt FUNCTION'
+     A function to interrupt the syntax check.
+
+     FUNCTION is called with the syntax checker and the context
+     object returned by the `:start' function and shall try to
+     interrupt the syntax check.  The context may be nil, if the
+     syntax check is interrupted before actually started.
+     FUNCTION should handle this situation.
+
+     If it cannot interrupt the syntax check, it may either
+     signal an error or silently ignore the attempt to interrupt
+     the syntax checker, depending on the severity of the
+     situation.
+
+     If interrupting the syntax check failed, Flycheck will let
+     the syntax check continue, but ignore any status reports.
+     Notably, it won't highlight any errors reported by the
+     syntax check in the buffer.
+
+     This property is optional.  If omitted, Flycheck won't
+     attempt to interrupt syntax checks wit this syntax checker,
+     and simply ignore their results.
+
+`:print-doc FUNCTION'
+     A function to print additional documentation into the Help
+     buffer of this checker.
+
+     FUNCTION is called when creating the Help buffer for the
+     syntax checker, with the syntax checker as single argument,
+     after printing the name of the syntax checker and its modes
+     and predicate, but before printing DOCSTRING.  It may insert
+     additional documentation into the current buffer.
+
+     The call occurs within `with-help-window'.  Hence
+     `standard-output' points to the current buffer, so you may
+     use `princ' and friends to add content.  Also, the current
+     buffer is put into Help mode afterwards, which automatically
+     turns symbols into references, if possible.
+
+     This property is optional.  If omitted, no additional
+     documentation is printed for this syntax checker.
+
+:verify FUNCTION
+     A function to verify the checker for the current buffer.
+
+     FUNCTION is called with the syntax checker as single
+     argument, and shall return a list of
+     `flycheck-verification-result' objects indicating whether
+     the syntax checker could be used in the current buffer, and
+     highlighting potential setup problems.
+
+     This property is optional.  If omitted, no additional
+     verification occurs for this syntax checker.  It is however
+     absolutely recommended that you add a `:verify' function to
+     your syntax checker, because it will help users to spot
+     potential setup problems.
+
+`:modes MODES'
+     A major mode symbol or a list thereof, denoting major modes
+     to use this syntax checker in.
+
+     This syntax checker will only be used in buffers whose
+     `major-mode' is contained in MODES.
+
+     If `:predicate' is also given the syntax checker will only
+     be used in buffers for which the `:predicate' returns
+     non-nil.
+
+`:predicate FUNCTION'
+     A function to determine whether to use the syntax checker in
+     the current buffer.
+
+     FUNCTION is called without arguments and shall return
+     non-nil if this syntax checker shall be used to check the
+     current buffer.  Otherwise it shall return nil.
+
+     If this checker has a `:working-directory' FUNCTION is
+     called with `default-directory' bound to the checker's
+     working directory.
+
+     FUNCTION is only called in matching major modes.
+
+     This property is optional.
+
+`:enabled FUNCTION'
+     A function to determine whether to use the syntax checker in
+     the current buffer.
+
+     This property behaves as `:predicate', except that it's only
+     called the first time a syntax checker is to be used in a buffer.
+
+     FUNCTION is called without arguments and shall return
+     non-nil if this syntax checker shall be used to check the
+     current buffer.  Otherwise it shall return nil.
+
+     If FUNCTION returns a non-nil value the checker is put in a
+     whitelist in `flycheck-enabled-checkers' to prevent further
+     invocations of `:enabled'.  Otherwise it is disabled via
+     `flycheck-disabled-checkers' to prevent any further use of
+     it.
+
+     If this checker has a `:working-directory' FUNCTION is
+     called with `default-directory' bound to the checker's
+     working directory.
+
+     FUNCTION is only called in matching major modes.
+
+     This property is optional.
+
+`:error-filter FUNCTION'
+     A function to filter the errors returned by this checker.
+
+     FUNCTION is called with the list of `flycheck-error' objects
+     returned by the syntax checker and shall return another list
+     of `flycheck-error' objects, which is considered the final
+     result of this syntax checker.
+
+     FUNCTION is free to add, remove or modify errors, whether in
+     place or by copying.
+
+     This property is optional.  The default filter is
+     `identity'.
+
+`:error-explainer FUNCTION'
+     A function to return an explanation text for errors
+     generated by this checker.
+
+     FUNCTION is called with a `flycheck-error' object and shall
+     return an explanation message for this error as a string, or
+     nil if there is no explanation for this error.
+
+     This property is optional.
+
+`:next-checkers NEXT-CHECKERS'
+     A list denoting syntax checkers to apply after this syntax
+     checker, in what we call \"chaining\" of syntax checkers.
+
+     Each ITEM is a cons cell `(LEVEL . CHECKER)'.  CHECKER is a
+     syntax checker to run after this syntax checker.  LEVEL is
+     an error level.  CHECKER will only be used if there are no
+     current errors of at least LEVEL.  LEVEL may also be t, in
+     which case CHECKER is used regardless of the current errors.
+
+     ITEM may also be a syntax checker symbol, which is
+     equivalent to `(t . ITEM)'.
+
+     Flycheck tries all items in order of declaration, and uses
+     the first whose LEVEL matches and whose CHECKER is
+     registered and can be used for the current buffer.
+
+     This feature is typically used to apply more than one syntax
+     checker to a buffer.  For instance, you might first use a
+     compiler to check a buffer for syntax and type errors, and
+     then run a linting tool that checks for insecure code, or
+     questionable style.
+
+     This property is optional.  If omitted, it defaults to the
+     nil, i.e. no other syntax checkers are applied after this
+     syntax checker.
+
+`:working-directory FUNCTION'
+     The value of `default-directory' when invoking `:start'.
+
+     FUNCTION is a function taking the syntax checker as sole
+     argument.  It shall return the absolute path to an existing
+     directory to use as `default-directory' for `:start' or
+     nil to fall back to the `default-directory' of the current
+     buffer.
+
+     This property is optional.  If omitted, invoke `:start'
+     from the `default-directory' of the buffer being checked.
+
+Signal an error, if any property has an invalid value."
+  (declare (indent 1)
+           (doc-string 2))
+  (let ((start (plist-get properties :start))
+        (interrupt (plist-get properties :interrupt))
+        (print-doc (plist-get properties :print-doc))
+        (modes (plist-get properties :modes))
+        (predicate (plist-get properties :predicate))
+        (verify (plist-get properties :verify))
+        (enabled (plist-get properties :enabled))
+        (filter (or (plist-get properties :error-filter) #'identity))
+        (explainer (plist-get properties :error-explainer))
+        (next-checkers (plist-get properties :next-checkers))
+        (file (flycheck-current-load-file))
+        (working-directory (plist-get properties :working-directory)))
+
+    (unless (listp modes)
+      (setq modes (list modes)))
+
+    (unless (functionp start)
+      (error ":start %S of syntax checker %s is not a function" start symbol))
+    (unless (or (null interrupt) (functionp interrupt))
+      (error ":interrupt %S of syntax checker %s is not a function"
+             interrupt symbol))
+    (unless (or (null print-doc) (functionp print-doc))
+      (error ":print-doc %S of syntax checker %s is not a function"
+             print-doc symbol))
+    (unless (or (null verify) (functionp verify))
+      (error ":verify %S of syntax checker %S is not a function"
+             verify symbol))
+    (unless (or (null enabled) (functionp enabled))
+      (error ":enabled %S of syntax checker %S is not a function"
+             enabled symbol))
+    (unless modes
+      (error "Missing :modes in syntax checker %s" symbol))
+    (dolist (mode modes)
+      (unless (symbolp mode)
+        (error "Invalid :modes %s in syntax checker %s, %s must be a symbol"
+               modes symbol mode)))
+    (unless (or (null predicate) (functionp predicate))
+      (error ":predicate %S of syntax checker %s  is not a function"
+             predicate symbol))
+    (unless (functionp filter)
+      (error ":error-filter %S of syntax checker %s is not a function"
+             filter symbol))
+    (unless (or (null explainer) (functionp explainer))
+      (error ":error-explainer %S of syntax checker %S is not a function"
+             explainer symbol))
+    (dolist (checker next-checkers)
+      (flycheck-validate-next-checker checker))
+
+    (let ((real-predicate
+           (and predicate
+                (lambda ()
+                  ;; Run predicate in the checker's default directory
+                  (let ((default-directory
+                          (flycheck-compute-working-directory symbol)))
+                    (funcall predicate)))))
+          (real-enabled
+           (lambda ()
+             (if (flycheck-valid-checker-p symbol)
+                 (or (null enabled)
+                     ;; Run enabled in the checker's default directory
+                     (let ((default-directory
+                             (flycheck-compute-working-directory symbol)))
+                       (funcall enabled)))
+               (lwarn 'flycheck
+                      :warning "%S is no valid Flycheck syntax checker.
+Try to reinstall the package defining this syntax checker." symbol)
+               nil))))
+      (pcase-dolist (`(,prop . ,value)
+                     `((start             . ,start)
+                       (interrupt         . ,interrupt)
+                       (print-doc         . ,print-doc)
+                       (modes             . ,modes)
+                       (predicate         . ,real-predicate)
+                       (verify            . ,verify)
+                       (enabled           . ,real-enabled)
+                       (error-filter      . ,filter)
+                       (error-explainer   . ,explainer)
+                       (next-checkers     . ,next-checkers)
+                       (documentation     . ,docstring)
+                       (file              . ,file)
+                       (working-directory . ,working-directory)))
+        (setf (flycheck-checker-get symbol prop) value)))
+
+    ;; Track the version, to avoid breakage if the internal format changes
+    (setf (flycheck-checker-get symbol 'generic-checker-version)
+          flycheck-generic-checker-version)))
+
+(defun flycheck-valid-checker-p (checker)
+  "Check whether a CHECKER is valid.
+
+A valid checker is a symbol defined as syntax checker with
+`flycheck-define-checker'."
+  (and (symbolp checker)
+       (= (or (get checker 'flycheck-generic-checker-version) 0)
+          flycheck-generic-checker-version)))
+
+(defun flycheck-checker-supports-major-mode-p (checker &optional mode)
+  "Whether CHECKER supports the given major MODE.
+
+CHECKER is a syntax checker symbol and MODE a major mode symbol.
+Look at the `modes' property of CHECKER to determine whether
+CHECKER supports buffers in the given major MODE.
+
+MODE defaults to the value of `major-mode' if omitted or nil.
+
+Return non-nil if CHECKER supports MODE and nil otherwise."
+  (let ((mode (or mode major-mode)))
+    (memq mode (flycheck-checker-get checker 'modes))))
+
+(defvar-local flycheck-enabled-checkers nil
+  "Syntax checkers included in automatic selection.
+
+A list of Flycheck syntax checkers included in automatic
+selection for current buffer.")
+
+(defun flycheck-may-enable-checker (checker)
+  "Whether a generic CHECKER may be enabled for current buffer.
+
+Return non-nil if CHECKER may be used for the current buffer, and
+nil otherwise."
+  (let* ((enabled (flycheck-checker-get checker 'enabled))
+         (shall-enable (and (not (flycheck-disabled-checker-p checker))
+                            (or (memq checker flycheck-enabled-checkers)
+                                (null enabled)
+                                (funcall enabled)))))
+    (if shall-enable
+        (cl-pushnew checker flycheck-enabled-checkers)
+      (cl-pushnew checker flycheck-disabled-checkers))
+    shall-enable))
+
+(defun flycheck-may-use-checker (checker)
+  "Whether a generic CHECKER may be used.
+
+Return non-nil if CHECKER may be used for the current buffer, and
+nil otherwise."
+  (let ((predicate (flycheck-checker-get checker 'predicate)))
+    (and (flycheck-valid-checker-p checker)
+         (flycheck-checker-supports-major-mode-p checker)
+         (flycheck-may-enable-checker checker)
+         (or (null predicate) (funcall predicate)))))
+
+(defun flycheck-may-use-next-checker (next-checker)
+  "Determine whether NEXT-CHECKER may be used."
+  (when (symbolp next-checker)
+    (push t next-checker))
+  (let ((level (car next-checker))
+        (next-checker (cdr next-checker)))
+    (and (or (eq level t)
+             (flycheck-has-max-current-errors-p level))
+         (flycheck-registered-checker-p next-checker)
+         (flycheck-may-use-checker next-checker))))
+
+
+;;; Help for generic syntax checkers
+(define-button-type 'help-flycheck-checker-def
+  :supertype 'help-xref
+  'help-function #'flycheck-goto-checker-definition
+  'help-echo "mouse-2, RET: find Flycheck checker definition")
+
+(defconst flycheck-find-checker-regexp
+  (rx line-start (zero-or-more (syntax whitespace))
+      "(" symbol-start "flycheck-define-checker" symbol-end
+      (eval (list 'regexp find-function-space-re))
+      symbol-start
+      "%s"
+      symbol-end
+      (or (syntax whitespace) line-end))
+  "Regular expression to find a checker definition.")
+
+(add-to-list 'find-function-regexp-alist
+             '(flycheck-checker . flycheck-find-checker-regexp))
+
+(defun flycheck-goto-checker-definition (checker file)
+  "Go to to the definition of CHECKER in FILE."
+  (let ((location (find-function-search-for-symbol
+                   checker 'flycheck-checker file)))
+    (pop-to-buffer (car location))
+    (if (cdr location)
+        (goto-char (cdr location))
+      (message "Unable to find checker location in file"))))
+
+(defun flycheck-checker-at-point ()
+  "Return the Flycheck checker found at or before point.
+
+Return nil if there is no checker."
+  (let ((symbol (variable-at-point 'any-symbol)))
+    (when (flycheck-valid-checker-p symbol)
+      symbol)))
+
+(defun flycheck-describe-checker (checker)
+  "Display the documentation of CHECKER.
+
+CHECKER is a checker symbol.
+
+Pop up a help buffer with the documentation of CHECKER."
+  (interactive
+   (let* ((enable-recursive-minibuffers t)
+          (default (or (flycheck-checker-at-point)
+                       (ignore-errors (flycheck-get-checker-for-buffer))))
+          (prompt (if default
+                      (format "Describe syntax checker (default %s): " default)
+                    "Describe syntax checker: ")))
+     (list (read-flycheck-checker prompt default))))
+  (unless (flycheck-valid-checker-p checker)
+    (user-error "You didn't specify a Flycheck syntax checker"))
+  (help-setup-xref (list #'flycheck-describe-checker checker)
+                   (called-interactively-p 'interactive))
+  (save-excursion
+    (with-help-window (help-buffer)
+      (let ((filename (flycheck-checker-get checker 'file))
+            (modes (flycheck-checker-get checker 'modes))
+            (predicate (flycheck-checker-get checker 'predicate))
+            (print-doc (flycheck-checker-get checker 'print-doc))
+            (next-checkers (flycheck-checker-get checker 'next-checkers)))
+        (princ (format "%s is a Flycheck syntax checker" checker))
+        (when filename
+          (princ (format " in `%s'" (file-name-nondirectory filename)))
+          (with-current-buffer standard-output
+            (save-excursion
+              (re-search-backward "`\\([^`']+\\)'" nil t)
+              (help-xref-button 1 'help-flycheck-checker-def
+                                checker filename))))
+        (princ ".\n\n")
+
+        (let ((modes-start (with-current-buffer standard-output (point-max))))
+          ;; Track the start of the modes documentation, to properly re-fill
+          ;; it later
+          (princ "  This syntax checker checks syntax in the major mode(s) ")
+          (princ (string-join
+                  (seq-map (apply-partially #'format "`%s'") modes)
+                  ", "))
+          (when predicate
+            (princ ", and uses a custom predicate"))
+          (princ ".")
+          (when next-checkers
+            (princ "  It runs the following checkers afterwards:"))
+          (with-current-buffer standard-output
+            (save-excursion
+              (fill-region-as-paragraph modes-start (point-max))))
+          (princ "\n")
+
+          ;; Print the list of next checkers
+          (when next-checkers
+            (princ "\n")
+            (let ((beg-checker-list (with-current-buffer standard-output
+                                      (point))))
+              (dolist (next-checker next-checkers)
+                (if (symbolp next-checker)
+                    (princ (format "     * `%s'\n" next-checker))
+                  (princ (format "     * `%s' (maximum level `%s')\n"
+                                 (cdr next-checker) (car next-checker)))))
+              ;;
+              (with-current-buffer standard-output
+                (save-excursion
+                  (while (re-search-backward "`\\([^`']+\\)'"
+                                             beg-checker-list t)
+                    (when (flycheck-valid-checker-p
+                           (intern-soft (match-string 1)))
+                      (help-xref-button 1 'help-flycheck-checker-def checker
+                                        filename))))))))
+        ;; Call the custom print-doc function of the checker, if present
+        (when print-doc
+          (funcall print-doc checker))
+        ;; Ultimately, print the docstring
+        (princ "\nDocumentation:\n")
+        (princ (flycheck-checker-get checker 'documentation))))))
+
+
+;;; Syntax checker verification
+(cl-defstruct (flycheck-verification-result
+               (:constructor flycheck-verification-result-new))
+  "Structure for storing a single verification result.
+
+Slots:
+
+`label'
+     A label for this result, as string
+
+`message'
+     A message for this result, as string
+
+`face'
+     The face to use for the `message'.
+
+     You can either use a face symbol, or a list of face symbols."
+  label message face)
+
+(defun flycheck-verify-generic-checker (checker)
+  "Verify a generic CHECKER in the current buffer.
+
+Return a list of `flycheck-verification-result' objects."
+  (let (results
+        (predicate (flycheck-checker-get checker 'predicate))
+        (enabled (flycheck-checker-get checker 'enabled))
+        (verify (flycheck-checker-get checker 'verify)))
+    (when enabled
+      (let ((result (funcall enabled)))
+        (push (flycheck-verification-result-new
+               :label "may enable"
+               :message (if result "yes" "Automatically disabled!")
+               :face (if result 'success '(bold warning)))
+              results)))
+    (when predicate
+      (let ((result (funcall predicate)))
+        (push (flycheck-verification-result-new
+               :label "predicate"
+               :message (prin1-to-string (not (null result)))
+               :face (if result 'success '(bold warning)))
+              results)))
+    (append (nreverse results)
+            (and verify (funcall verify checker)))))
+
+(define-button-type 'help-flycheck-checker-doc
+  :supertype 'help-xref
+  'help-function #'flycheck-describe-checker
+  'help-echo "mouse-2, RET: describe Flycheck checker")
+
+(defun flycheck--verify-princ-checker (checker buffer &optional with-mm)
+  "Print verification result of CHECKER for BUFFER.
+
+When WITH-MM is given and non-nil, also include the major mode
+into the verification results."
+  (princ "  ")
+  (insert-button (symbol-name checker)
+                 'type 'help-flycheck-checker-doc
+                 'help-args (list checker))
+  (when (with-current-buffer buffer (flycheck-disabled-checker-p checker))
+    (insert (propertize " (disabled)" 'face '(bold error))))
+  (princ "\n")
+  (let ((results (with-current-buffer buffer
+                   (flycheck-verify-generic-checker checker))))
+    (when with-mm
+      (with-current-buffer buffer
+        (let ((message-and-face
+               (if (flycheck-checker-supports-major-mode-p checker)
+                   (cons (format "`%s' supported" major-mode) 'success)
+                 (cons (format "`%s' not supported" major-mode) 'error))))
+          (push (flycheck-verification-result-new
+                 :label "major mode"
+                 :message (car message-and-face)
+                 :face (cdr message-and-face))
+                results))))
+    (let* ((label-length
+            (seq-max (mapcar
+                      (lambda (res)
+                        (length (flycheck-verification-result-label res)))
+                      results)))
+           (message-column (+ 8 label-length)))
+      (dolist (result results)
+        (princ "    - ")
+        (princ (flycheck-verification-result-label result))
+        (princ ": ")
+        (princ (make-string (- message-column (current-column)) ?\ ))
+        (let ((message (flycheck-verification-result-message result))
+              (face (flycheck-verification-result-face result)))
+          (insert (propertize message 'face face)))
+        (princ "\n"))))
+  (princ "\n"))
+
+(defun flycheck--verify-print-header (desc buffer)
+  "Print a title with DESC for BUFFER in the current buffer.
+
+DESC is an arbitrary string containing a description, and BUFFER
+is the buffer being verified.  The name and the major mode mode
+of BUFFER are printed.
+
+DESC and information about BUFFER are printed in the current
+buffer."
+  (princ desc)
+  (insert (propertize (buffer-name buffer) 'face 'bold))
+  (princ " in ")
+  (let ((mode (buffer-local-value 'major-mode buffer)))
+    (insert-button (symbol-name mode)
+                   'type 'help-function
+                   'help-args (list mode)))
+  (princ ":\n\n"))
+
+(defun flycheck--verify-print-footer (buffer)
+  "Print a footer for BUFFER in the current buffer.
+
+BUFFER is the buffer being verified."
+  (princ "Flycheck Mode is ")
+  (let ((enabled (buffer-local-value 'flycheck-mode buffer)))
+    (insert (propertize (if enabled "enabled" "disabled")
+                        'face (if enabled 'success '(warning bold)))))
+  (princ
+   (with-current-buffer buffer
+     ;; Use key binding state in the verified buffer to print the help.
+     (substitute-command-keys
+      ".  Use \\[universal-argument] \\[flycheck-disable-checker] \
+to enable disabled checkers.")))
+  (save-excursion
+    (let ((end (point)))
+      (backward-paragraph)
+      (fill-region-as-paragraph (point) end)))
+
+  (princ "\n\n--------------------\n\n")
+  (princ (format "Flycheck version: %s\n" (flycheck-version)))
+  (princ (format "Emacs version:    %s\n" emacs-version))
+  (princ (format "System:           %s\n" system-configuration))
+  (princ (format "Window system:    %S\n" window-system)))
+
+(defun flycheck-verify-checker (checker)
+  "Check whether a CHECKER can be used in this buffer.
+
+Show a buffer listing possible problems that prevent CHECKER from
+being used for the current buffer.
+
+Note: Do not use this function to check whether a syntax checker
+is applicable from Emacs Lisp code.  Use
+`flycheck-may-use-checker' instead."
+  (interactive (list (read-flycheck-checker "Checker to verify: ")))
+  (unless (flycheck-valid-checker-p checker)
+    (user-error "%s is not a syntax checker" checker))
+
+  ;; Save the buffer to make sure that all predicates are good
+  (when (and (buffer-file-name) (buffer-modified-p))
+    (save-buffer))
+
+  (let ((buffer (current-buffer)))
+    (with-help-window (get-buffer-create " *Flycheck checker*")
+      (with-current-buffer standard-output
+        (flycheck--verify-print-header "Syntax checker in buffer " buffer)
+        (flycheck--verify-princ-checker checker buffer 'with-mm)
+        (if (with-current-buffer buffer (flycheck-may-use-checker checker))
+            (insert (propertize
+                     "Flycheck can use this syntax checker for this buffer.\n"
+                     'face 'success))
+          (insert (propertize
+                   "Flycheck cannot use this syntax checker for this buffer.\n"
+                   'face 'error)))
+        (insert "\n")
+        (flycheck--verify-print-footer buffer)))))
+
+(defun flycheck-verify-setup ()
+  "Check whether Flycheck can be used in this buffer.
+
+Display a new buffer listing all syntax checkers that could be
+applicable in the current buffer.  For each syntax checkers,
+possible problems are shown."
+  (interactive)
+  (when (and (buffer-file-name) (buffer-modified-p))
+    ;; Save the buffer
+    (save-buffer))
+
+  (let ((buffer (current-buffer))
+        ;; Get all checkers that support the current major mode
+        (checkers (seq-filter #'flycheck-checker-supports-major-mode-p
+                              flycheck-checkers))
+        (help-buffer (get-buffer-create " *Flycheck checkers*")))
+
+    ;; Now print all applicable checkers
+    (with-help-window help-buffer
+      (with-current-buffer standard-output
+        (flycheck--verify-print-header "Syntax checkers for buffer " buffer)
+        (unless checkers
+          (insert (propertize
+                   "There are no syntax checkers for this buffer!\n\n"
+                   'face '(bold error))))
+        (dolist (checker checkers)
+          (flycheck--verify-princ-checker checker buffer))
+
+        (-when-let (selected-checker
+                    (buffer-local-value 'flycheck-checker buffer))
+          (insert
+           (propertize
+            "The following checker is explicitly selected for this buffer:\n\n"
+            'face 'bold))
+          (flycheck--verify-princ-checker selected-checker buffer 'with-mm))
+
+        (let ((unregistered-checkers
+               (seq-difference (flycheck-defined-checkers) flycheck-checkers)))
+          (when unregistered-checkers
+            (insert (propertize
+                     "\nThe following syntax checkers are not registered:\n\n"
+                     'face '(bold warning)))
+            (dolist (checker unregistered-checkers)
+              (princ "  - ")
+              (princ checker)
+              (princ "\n"))
+            (princ
+             "\nTry adding these syntax checkers to `flycheck-checkers'.\n")))
+
+        (flycheck--verify-print-footer buffer)))
+
+    (with-current-buffer help-buffer
+      (setq-local revert-buffer-function
+                  (lambda (_ignore-auto _noconfirm)
+                    (with-current-buffer buffer (flycheck-verify-setup)))))))
+
+
+;;; Predicates for generic syntax checkers
+(defun flycheck-buffer-saved-p (&optional buffer)
+  "Determine whether BUFFER is saved to a file.
+
+BUFFER is the buffer to check.  If omitted or nil, use the
+current buffer as BUFFER.
+
+Return non-nil if the BUFFER is backed by a file, and not
+modified, or nil otherwise."
+  (let ((file-name (buffer-file-name buffer)))
+    (and file-name (file-exists-p file-name) (not (buffer-modified-p buffer)))))
+
+
+;;; Extending generic checkers
+(defun flycheck-add-next-checker (checker next &optional append)
+  "After CHECKER add a NEXT checker.
+
+CHECKER is a syntax checker symbol, to which to add NEXT checker.
+
+NEXT is a cons cell `(LEVEL . NEXT-CHECKER)'.  NEXT-CHECKER is a
+symbol denoting the syntax checker to run after CHECKER.  LEVEL
+is an error level.  NEXT-CHECKER will only be used if there is no
+current error whose level is more severe than LEVEL.  LEVEL may
+also be t, in which case NEXT-CHECKER is used regardless of the
+current errors.
+
+NEXT can also be a syntax checker symbol only, which is
+equivalent to `(t . NEXT)'.
+
+NEXT-CHECKER is prepended before other next checkers, unless
+APPEND is non-nil."
+  (unless (flycheck-valid-checker-p checker)
+    (error "%s is not a valid syntax checker" checker))
+  (flycheck-validate-next-checker next 'strict)
+  (if append
+      (setf (flycheck-checker-get checker 'next-checkers)
+            (append (flycheck-checker-get checker 'next-checkers) (list next)))
+    (push next (flycheck-checker-get checker 'next-checkers))))
+
+(defun flycheck-add-mode (checker mode)
+  "To CHECKER add a new major MODE.
+
+CHECKER and MODE are symbols denoting a syntax checker and a
+major mode respectively.
+
+Add MODE to the `:modes' property of CHECKER, so that CHECKER
+will be used in buffers with MODE."
+  (unless (flycheck-valid-checker-p checker)
+    (error "%s is not a valid syntax checker" checker))
+  (unless (symbolp mode)
+    (error "%s is not a symbol" mode))
+  (push mode (flycheck-checker-get checker 'modes)))
+
+
+;;; Generic syntax checks
+(cl-defstruct (flycheck-syntax-check
+               (:constructor flycheck-syntax-check-new))
+  "Structure for storing syntax check state.
+
+Slots:
+
+`buffer'
+     The buffer being checked.
+
+`checker'
+     The syntax checker being used.
+
+`context'
+     The context object.
+
+`working-directory'
+     Working directory for the syntax checker. Serve as a value for
+     `default-directory' for a checker."
+  buffer checker context working-directory)
+
+(defun flycheck-syntax-check-start (syntax-check callback)
+  "Start a SYNTAX-CHECK with CALLBACK."
+  (let ((checker (flycheck-syntax-check-checker syntax-check))
+        (default-directory
+          (flycheck-syntax-check-working-directory syntax-check)))
+    (setf (flycheck-syntax-check-context syntax-check)
+          (funcall (flycheck-checker-get checker 'start) checker callback))))
+
+(defun flycheck-syntax-check-interrupt (syntax-check)
+  "Interrupt a SYNTAX-CHECK."
+  (let* ((checker (flycheck-syntax-check-checker syntax-check))
+         (interrupt-fn (flycheck-checker-get checker 'interrupt))
+         (context (flycheck-syntax-check-context syntax-check)))
+    (when interrupt-fn
+      (funcall interrupt-fn checker context))))
+
+
+;;; Syntax checking mode
+
+(defvar flycheck-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map flycheck-keymap-prefix flycheck-command-map)
+    ;; We place the menu under a custom menu key.  Since this menu key is not
+    ;; present in the menu of the global map, no top-level menu entry is added
+    ;; to the global menu bar.  However, it still appears on the mode line
+    ;; lighter.
+    (define-key map [menu-bar flycheck] flycheck-mode-menu-map)
+    map)
+  "Keymap of command `flycheck-mode'.")
+
+(defvar-local flycheck-old-next-error-function nil
+  "Remember the old `next-error-function'.")
+
+(defconst flycheck-hooks-alist
+  '(
+    ;; Handle events that may start automatic syntax checks
+    (after-save-hook        . flycheck-handle-save)
+    (after-change-functions . flycheck-handle-change)
+    ;; Handle events that may triggered pending deferred checks
+    (window-configuration-change-hook . flycheck-perform-deferred-syntax-check)
+    (post-command-hook                . flycheck-perform-deferred-syntax-check)
+    ;; Teardown Flycheck whenever the buffer state is about to get lost, to
+    ;; clean up temporary files and directories.
+    (kill-buffer-hook       . flycheck-teardown)
+    (change-major-mode-hook . flycheck-teardown)
+    (before-revert-hook     . flycheck-teardown)
+    ;; Update the error list if necessary
+    (post-command-hook . flycheck-error-list-update-source)
+    (post-command-hook . flycheck-error-list-highlight-errors)
+    ;; Display errors.  Show errors at point after commands (like movements) and
+    ;; when Emacs gets focus.  Cancel the display timer when Emacs looses focus
+    ;; (as there's no need to display errors if the user can't see them), and
+    ;; hide the error buffer (for large error messages) if necessary.  Note that
+    ;; the focus hooks only work on Emacs 24.4 and upwards, but since undefined
+    ;; hooks are perfectly ok we don't need a version guard here.  They'll just
+    ;; not work silently.
+    (post-command-hook . flycheck-display-error-at-point-soon)
+    (focus-in-hook     . flycheck-display-error-at-point-soon)
+    (focus-out-hook    . flycheck-cancel-error-display-error-at-point-timer)
+    (post-command-hook . flycheck-hide-error-buffer)
+    ;; Immediately show error popups when navigating to an error
+    (next-error-hook . flycheck-display-error-at-point))
+  "Hooks which Flycheck needs to hook in.
+
+The `car' of each pair is a hook variable, the `cdr' a function
+to be added or removed from the hook variable if Flycheck mode is
+enabled and disabled respectively.")
+
+;;;###autoload
+(define-minor-mode flycheck-mode
+  "Minor mode for on-the-fly syntax checking.
+
+When called interactively, toggle `flycheck-mode'.  With prefix
+ARG, enable `flycheck-mode' if ARG is positive, otherwise disable
+it.
+
+When called from Lisp, enable `flycheck-mode' if ARG is omitted,
+nil or positive.  If ARG is `toggle', toggle `flycheck-mode'.
+Otherwise behave as if called interactively.
+
+In `flycheck-mode' the buffer is automatically syntax-checked
+using the first suitable syntax checker from `flycheck-checkers'.
+Use `flycheck-select-checker' to select a checker for the current
+buffer manually.
+
+\\{flycheck-mode-map}"
+  :init-value nil
+  :keymap flycheck-mode-map
+  :lighter flycheck-mode-line
+  :after-hook (flycheck-buffer-automatically 'mode-enabled 'force-deferred)
+  (cond
+   (flycheck-mode
+    (flycheck-clear)
+
+    (pcase-dolist (`(,hook . ,fn) flycheck-hooks-alist)
+      (add-hook hook fn nil 'local))
+
+    (setq flycheck-old-next-error-function
+          (if flycheck-standard-error-navigation
+              next-error-function
+            :unset))
+    (when flycheck-standard-error-navigation
+      (setq next-error-function #'flycheck-next-error-function)))
+   (t
+    (unless (eq flycheck-old-next-error-function :unset)
+      (setq next-error-function flycheck-old-next-error-function))
+
+    (pcase-dolist (`(,hook . ,fn) flycheck-hooks-alist)
+      (remove-hook hook fn 'local))
+
+    (flycheck-teardown))))
+
+
+;;; Syntax checker selection for the current buffer
+(defun flycheck-get-checker-for-buffer ()
+  "Find the checker for the current buffer.
+
+Use the selected checker for the current buffer, if any,
+otherwise search for the best checker from `flycheck-checkers'.
+
+Return checker if there is a checker for the current buffer, or
+nil otherwise."
+  (if flycheck-checker
+      (when (flycheck-may-use-checker flycheck-checker)
+        flycheck-checker)
+    (seq-find #'flycheck-may-use-checker flycheck-checkers)))
+
+(defun flycheck-get-next-checker-for-buffer (checker)
+  "Get the checker to run after CHECKER for the current buffer."
+  (let ((next (seq-find #'flycheck-may-use-next-checker
+                        (flycheck-checker-get checker 'next-checkers))))
+    (when next
+      (if (symbolp next) next (cdr next)))))
+
+(defun flycheck-select-checker (checker)
+  "Select CHECKER for the current buffer.
+
+CHECKER is a syntax checker symbol (see `flycheck-checkers') or
+nil.  In the former case, use CHECKER for the current buffer,
+otherwise deselect the current syntax checker (if any) and use
+automatic checker selection via `flycheck-checkers'.
+
+If called interactively prompt for CHECKER.  With prefix arg
+deselect the current syntax checker and enable automatic
+selection again.
+
+Set `flycheck-checker' to CHECKER and automatically start a new
+syntax check if the syntax checker changed.
+
+CHECKER will be used, even if it is not contained in
+`flycheck-checkers', or if it is disabled via
+`flycheck-disabled-checkers'."
+  (interactive
+   (if current-prefix-arg
+       (list nil)
+     (list (read-flycheck-checker "Select checker: "
+                                  (flycheck-get-checker-for-buffer)))))
+  (when (not (eq checker flycheck-checker))
+    (unless (or (not checker) (flycheck-may-use-checker checker))
+      (flycheck-verify-checker checker)
+      (user-error "Can't use syntax checker %S in this buffer" checker))
+    (setq flycheck-checker checker)
+    (when flycheck-mode
+      (flycheck-buffer))))
+
+(defun flycheck-disable-checker (checker &optional enable)
+  "Interactively disable CHECKER for the current buffer.
+
+Interactively, prompt for a syntax checker to disable, and add
+the syntax checker to the buffer-local value of
+`flycheck-disabled-checkers'.
+
+With non-nil ENABLE or with prefix arg, prompt for a disabled
+syntax checker and re-enable it by removing it from the
+buffer-local value of `flycheck-disabled-checkers'."
+  (declare
+   (interactive-only "Directly set `flycheck-disabled-checkers' instead"))
+  (interactive
+   (let* ((enable current-prefix-arg)
+          (candidates (if enable flycheck-disabled-checkers flycheck-checkers))
+          (prompt (if enable "Enable syntax checker: "
+                    "Disable syntax checker: ")))
+     (when (and enable (not candidates))
+       (user-error "No syntax checkers disabled in this buffer"))
+     (list (read-flycheck-checker prompt nil nil candidates) enable)))
+  (unless checker
+    (user-error "No syntax checker given"))
+  (if enable
+      ;; We must use `remq' instead of `delq', because we must _not_ modify the
+      ;; list.  Otherwise we could potentially modify the global default value,
+      ;; in case the list is the global default.
+      (when (memq checker flycheck-disabled-checkers)
+        (setq flycheck-disabled-checkers
+              (remq checker flycheck-disabled-checkers))
+        (flycheck-buffer))
+    (unless (memq checker flycheck-disabled-checkers)
+      (push checker flycheck-disabled-checkers)
+      (flycheck-buffer))))
+
+
+;;; Syntax checks for the current buffer
+(defvar-local flycheck-current-syntax-check nil
+  "The current syntax check in the this buffer.")
+(put 'flycheck-current-syntax-check 'permanent-local t)
+
+(defun flycheck-start-current-syntax-check (checker)
+  "Start a syntax check in the current buffer with CHECKER.
+
+Set `flycheck-current-syntax-check' accordingly."
+  ;; Allocate the current syntax check *before* starting it.  This allows for
+  ;; synchronous checks, which call the status callback immediately in their
+  ;; start function.
+  (let* ((check
+          (flycheck-syntax-check-new
+           :buffer (current-buffer)
+           :checker checker
+           :context nil
+           :working-directory (flycheck-compute-working-directory checker)))
+         (callback (flycheck-buffer-status-callback check)))
+    (setq flycheck-current-syntax-check check)
+    (flycheck-report-status 'running)
+    (flycheck-syntax-check-start check callback)))
+
+(defun flycheck-running-p ()
+  "Determine whether a syntax check is running in the current buffer."
+  (not (null flycheck-current-syntax-check)))
+
+(defun flycheck-stop ()
+  "Stop any ongoing syntax check in the current buffer."
+  (when (flycheck-running-p)
+    (flycheck-syntax-check-interrupt flycheck-current-syntax-check)
+    ;; Remove the current syntax check, to reset Flycheck into a non-running
+    ;; state, and to make `flycheck-report-buffer-checker-status' ignore any
+    ;; status reports from the current syntax check.
+    (setq flycheck-current-syntax-check nil)
+    (flycheck-report-status 'interrupted)))
+
+(defun flycheck-buffer-status-callback (syntax-check)
+  "Create a status callback for SYNTAX-CHECK in the current buffer."
+  (lambda (&rest args)
+    (apply #'flycheck-report-buffer-checker-status
+           syntax-check args)))
+
+(defun flycheck-buffer ()
+  "Start checking syntax in the current buffer.
+
+Get a syntax checker for the current buffer with
+`flycheck-get-checker-for-buffer', and start it."
+  (interactive)
+  (flycheck-clean-deferred-check)
+  (if flycheck-mode
+      (unless (flycheck-running-p)
+        ;; Clear error list and mark all overlays for deletion.  We do not
+        ;; delete all overlays immediately to avoid excessive re-displays and
+        ;; flickering, if the same errors gets highlighted again after the check
+        ;; completed.
+        (run-hooks 'flycheck-before-syntax-check-hook)
+        (flycheck-clear-errors)
+        (flycheck-mark-all-overlays-for-deletion)
+        (condition-case err
+            (let* ((checker (flycheck-get-checker-for-buffer)))
+              (if checker
+                  (flycheck-start-current-syntax-check checker)
+                (flycheck-clear)
+                (flycheck-report-status 'no-checker)))
+          (error
+           (flycheck-report-failed-syntax-check)
+           (signal (car err) (cdr err)))))
+    (user-error "Flycheck mode disabled")))
+
+(defun flycheck-report-buffer-checker-status
+    (syntax-check status &optional data)
+  "In BUFFER, report a SYNTAX-CHECK STATUS with DATA.
+
+SYNTAX-CHECK is the `flycheck-syntax-check' which reported
+STATUS.  STATUS denotes the status of CHECKER, with an optional
+DATA.  STATUS may be one of the following symbols:
+
+`errored'
+     The syntax checker has errored.  DATA is an optional error
+     message.
+
+     This report finishes the current syntax check.
+
+`interrupted'
+     The syntax checker was interrupted.  DATA is ignored.
+
+     This report finishes the current syntax check.
+
+`finished'
+     The syntax checker has finished with a proper error report
+     for the current buffer.  DATA is the (potentially empty)
+     list of `flycheck-error' objects reported by the syntax
+     check.
+
+     This report finishes the current syntax check.
+
+`suspicious'
+     The syntax checker encountered a suspicious state, which the
+     user needs to be informed about.  DATA is an optional
+     message.
+
+A syntax checker _must_ report a status at least once with any
+symbol that finishes the current syntax checker.  Otherwise
+Flycheck gets stuck with the current syntax check.
+
+If CHECKER is not the currently used syntax checker in
+`flycheck-current-syntax-check', the status report is largely
+ignored.  Notably, any errors reported by the checker are
+discarded."
+  (let ((buffer (flycheck-syntax-check-buffer syntax-check)))
+    ;; Ignore the status report if the buffer is gone, or if this syntax check
+    ;; isn't the current one in buffer (which can happen if this is an old
+    ;; report of an interrupted syntax check, and a new syntax check was started
+    ;; since this check was interrupted)
+    (when (and (buffer-live-p buffer)
+               (eq syntax-check
+                   (buffer-local-value 'flycheck-current-syntax-check buffer)))
+      (with-current-buffer buffer
+        (let ((checker (flycheck-syntax-check-checker syntax-check)))
+          (pcase status
+            ((or `errored `interrupted)
+             (flycheck-report-failed-syntax-check status)
+             (when (eq status 'errored)
+               ;; In case of error, show the error message
+               (message "Error from syntax checker %s: %s"
+                        checker (or data "UNKNOWN!"))))
+            (`suspicious
+             (when flycheck-mode
+               (message "Suspicious state from syntax checker %s: %s"
+                        checker (or data "UNKNOWN!")))
+             (flycheck-report-status 'suspicious))
+            (`finished
+             (when flycheck-mode
+               ;; Only report errors from the checker if Flycheck Mode is
+               ;; still enabled.
+               (flycheck-finish-current-syntax-check
+                data
+                (flycheck-syntax-check-working-directory syntax-check))))
+            (_
+             (error "Unknown status %s from syntax checker %s"
+                    status checker))))))))
+
+(defun flycheck-finish-current-syntax-check (errors working-dir)
+  "Finish the current syntax-check in the current buffer with ERRORS.
+
+ERRORS is a list of `flycheck-error' objects reported by the
+current syntax check in `flycheck-current-syntax-check'.
+
+Report all ERRORS and potentially start any next syntax checkers.
+
+If the current syntax checker reported excessive errors, it is
+disabled via `flycheck-disable-excessive-checker' for subsequent
+syntax checks.
+
+Relative file names in ERRORS will be expanded relative to
+WORKING-DIR."
+  (let* ((syntax-check flycheck-current-syntax-check)
+         (checker (flycheck-syntax-check-checker syntax-check))
+         (errors (flycheck-relevant-errors
+                  (flycheck-fill-and-expand-error-file-names
+                   (flycheck-filter-errors
+                    (flycheck-assert-error-list-p errors) checker)
+                   working-dir))))
+    (unless (flycheck-disable-excessive-checker checker errors)
+      (flycheck-report-current-errors errors))
+    (let ((next-checker (flycheck-get-next-checker-for-buffer checker)))
+      (if next-checker
+          (flycheck-start-current-syntax-check next-checker)
+        (setq flycheck-current-syntax-check nil)
+        (flycheck-report-status 'finished)
+        ;; Delete overlays only after the very last checker has run, to avoid
+        ;; flickering on intermediate re-displays
+        (flycheck-delete-marked-overlays)
+        (flycheck-error-list-refresh)
+        (run-hooks 'flycheck-after-syntax-check-hook)
+        (when (eq (current-buffer) (window-buffer))
+          (flycheck-display-error-at-point))
+        ;; Immediately try to run any pending deferred syntax check, which
+        ;; were triggered by intermediate automatic check event, to make sure
+        ;; that we quickly refine outdated error information
+        (flycheck-perform-deferred-syntax-check)))))
+
+(defun flycheck-disable-excessive-checker (checker errors)
+  "Disable CHECKER if it reported excessive ERRORS.
+
+If ERRORS has more items than `flycheck-checker-error-threshold',
+add CHECKER to `flycheck-disabled-checkers', and show a warning.
+
+Return t when CHECKER was disabled, or nil otherwise."
+  (when (and flycheck-checker-error-threshold
+             (> (length errors) flycheck-checker-error-threshold))
+    ;; Disable CHECKER for this buffer (`flycheck-disabled-checkers' is a local
+    ;; variable).
+    (lwarn '(flycheck syntax-checker) :warning
+           "Syntax checker %s reported too many errors (%s) and is disabled."
+           checker (length errors))
+    (push checker flycheck-disabled-checkers)
+    t))
+
+(defun flycheck-clear (&optional shall-interrupt)
+  "Clear all errors in the current buffer.
+
+With prefix arg or SHALL-INTERRUPT non-nil, also interrupt the
+current syntax check."
+  (interactive "P")
+  (when shall-interrupt
+    (flycheck-stop))
+  (flycheck-delete-all-overlays)
+  (flycheck-clear-errors)
+  (flycheck-error-list-refresh)
+  (flycheck-hide-error-buffer))
+
+(defun flycheck-teardown ()
+  "Teardown Flycheck in the current buffer..
+
+Completely clear the whole Flycheck state.  Remove overlays, kill
+running checks, and empty all variables used by Flycheck."
+  (flycheck-safe-delete-temporaries)
+  (flycheck-stop)
+  (flycheck-clean-deferred-check)
+  (flycheck-clear)
+  (flycheck-cancel-error-display-error-at-point-timer))
+
+
+;;; Automatic syntax checking in a buffer
+(defun flycheck-may-check-automatically (&optional condition)
+  "Determine whether the buffer may be checked under CONDITION.
+
+Read-only buffers may never be checked automatically.
+
+If CONDITION is non-nil, determine whether syntax may checked
+automatically according to
+`flycheck-check-syntax-automatically'."
+  (and (not (or buffer-read-only (flycheck-ephemeral-buffer-p)))
+       (file-exists-p default-directory)
+       (or (not condition)
+           (memq condition flycheck-check-syntax-automatically))))
+
+(defun flycheck-buffer-automatically (&optional condition force-deferred)
+  "Automatically check syntax at CONDITION.
+
+Syntax is not checked if `flycheck-may-check-automatically'
+returns nil for CONDITION.
+
+The syntax check is deferred if FORCE-DEFERRED is non-nil, or if
+`flycheck-must-defer-check' returns t."
+  (when (and flycheck-mode (flycheck-may-check-automatically condition))
+    (if (or force-deferred (flycheck-must-defer-check))
+        (flycheck-buffer-deferred)
+      (with-demoted-errors "Error while checking syntax automatically: %S"
+        (flycheck-buffer)))))
+
+(defvar-local flycheck-idle-change-timer nil
+  "Timer to mark the idle time since the last change.")
+
+(defun flycheck-clear-idle-change-timer ()
+  "Clear the idle change timer."
+  (when flycheck-idle-change-timer
+    (cancel-timer flycheck-idle-change-timer)
+    (setq flycheck-idle-change-timer nil)))
+
+(defun flycheck-handle-change (beg end _len)
+  "Handle a buffer change between BEG and END.
+
+BEG and END mark the beginning and end of the change text.  _LEN
+is ignored.
+
+Start a syntax check if a new line has been inserted into the
+buffer."
+  ;; Save and restore the match data, as recommended in (elisp)Change Hooks
+  (save-match-data
+    (when flycheck-mode
+      ;; The buffer was changed, thus clear the idle timer
+      (flycheck-clear-idle-change-timer)
+      (if (string-match-p (rx "\n") (buffer-substring beg end))
+          (flycheck-buffer-automatically 'new-line 'force-deferred)
+        (setq flycheck-idle-change-timer
+              (run-at-time flycheck-idle-change-delay nil
+                           #'flycheck--handle-idle-change-in-buffer
+                           (current-buffer)))))))
+
+(defun flycheck--handle-idle-change-in-buffer (buffer)
+  "Handle an expired idle timer in BUFFER since the last change.
+This thin wrapper around `flycheck-handle-idle-change' is needed
+because some users override that function, as described in URL
+`https://github.com/flycheck/flycheck/pull/1305'."
+  (when (buffer-live-p buffer)
+    (with-current-buffer buffer
+      (flycheck-handle-idle-change))))
+
+(defun flycheck-handle-idle-change ()
+  "Handle an expired idle timer since the last change."
+  (flycheck-clear-idle-change-timer)
+  (flycheck-buffer-automatically 'idle-change))
+
+(defun flycheck-handle-save ()
+  "Handle a save of the buffer."
+  (flycheck-buffer-automatically 'save))
+
+
+;;; Deferred syntax checking
+(defvar-local flycheck-deferred-syntax-check nil
+  "If non-nil, a deferred syntax check is pending.")
+
+(defun flycheck-must-defer-check ()
+  "Determine whether the syntax check has to be deferred.
+
+A check has to be deferred if the buffer is not visible, or if the buffer is
+currently being reverted.
+
+Return t if the check is to be deferred, or nil otherwise."
+  (or (not (get-buffer-window))
+      ;; We defer the syntax check if Flycheck is already running, to
+      ;; immediately start a new syntax check after the current one finished,
+      ;; because the result of the current check will most likely be outdated by
+      ;; the time it is finished.
+      (flycheck-running-p)
+      ;; We must defer checks while a buffer is being reverted, to avoid race
+      ;; conditions while the buffer contents are being restored.
+      revert-buffer-in-progress-p))
+
+(defun flycheck-deferred-check-p ()
+  "Determine whether the current buffer has a deferred check.
+
+Return t if so, or nil otherwise."
+  flycheck-deferred-syntax-check)
+
+(defun flycheck-buffer-deferred ()
+  "Defer syntax check for the current buffer."
+  (setq flycheck-deferred-syntax-check t))
+
+(defun flycheck-clean-deferred-check ()
+  "Clean a deferred syntax checking state."
+  (setq flycheck-deferred-syntax-check nil))
+
+(defun flycheck-perform-deferred-syntax-check ()
+  "Perform the deferred syntax check."
+  (when (flycheck-deferred-check-p)
+    (flycheck-clean-deferred-check)
+    (flycheck-buffer-automatically)))
+
+
+;;; Syntax checking in all buffers
+(defun flycheck-may-enable-mode ()
+  "Determine whether Flycheck mode may be enabled.
+
+Flycheck mode is not enabled for
+
+- the minibuffer,
+- `fundamental-mode'
+- major modes whose `mode-class' property is `special',
+- ephemeral buffers (see `flycheck-ephemeral-buffer-p'),
+- encrypted buffers (see `flycheck-encrypted-buffer-p'),
+- remote files (see `file-remote-p'),
+- and major modes excluded by `flycheck-global-modes'.
+
+Return non-nil if Flycheck mode may be enabled, and nil
+otherwise."
+  (and (pcase flycheck-global-modes
+         ;; Whether `major-mode' is disallowed by `flycheck-global-modes'
+         (`t t)
+         (`(not . ,modes) (not (memq major-mode modes)))
+         (modes (memq major-mode modes)))
+       (not (or (minibufferp)
+                (eq major-mode 'fundamental-mode)
+                (eq (get major-mode 'mode-class) 'special)
+                (flycheck-ephemeral-buffer-p)
+                (flycheck-encrypted-buffer-p)
+                (and (buffer-file-name)
+                     (file-remote-p (buffer-file-name) 'method))))))
+
+(defun flycheck-mode-on-safe ()
+  "Enable command `flycheck-mode' if it is safe to do so.
+
+Command `flycheck-mode' is only enabled if
+`flycheck-may-enable-mode' returns a non-nil result."
+  (when (flycheck-may-enable-mode)
+    (flycheck-mode)))
+
+;;;###autoload
+(define-globalized-minor-mode global-flycheck-mode flycheck-mode
+  flycheck-mode-on-safe
+  :init-value nil
+  ;; Do not expose Global Flycheck Mode on customize interface, because the
+  ;; interaction between package.el and customize is currently broken.  See
+  ;; https://github.com/flycheck/flycheck/issues/595
+
+  ;; :require 'flycheck :group
+  ;; 'flycheck
+  )
+
+(defun flycheck-global-teardown ()
+  "Teardown Flycheck in all buffers.
+
+Completely clear the whole Flycheck state in all buffers, stop
+all running checks, remove all temporary files, and empty all
+variables of Flycheck."
+  (dolist (buffer (buffer-list))
+    (with-current-buffer buffer
+      (when flycheck-mode
+        (flycheck-teardown)))))
+
+;; Clean up the entire state of Flycheck when Emacs is killed, to get rid of any
+;; pending temporary files.
+(add-hook 'kill-emacs-hook #'flycheck-global-teardown)
+
+
+;;; Errors from syntax checks
+(cl-defstruct (flycheck-error
+               (:constructor flycheck-error-new)
+               (:constructor flycheck-error-new-at
+                             (line column
+                                   &optional level message
+                                   &key checker id group
+                                   (filename (buffer-file-name))
+                                   (buffer (current-buffer)))))
+  "Structure representing an error reported by a syntax checker.
+Slots:
+
+`buffer'
+     The buffer that the error was reported for, as buffer object.
+
+`checker'
+     The syntax checker which reported this error, as symbol.
+
+`filename'
+     The file name the error refers to, as string.
+
+`line'
+     The line number the error refers to, as number.
+
+`column' (optional)
+     The column number the error refers to, as number.
+
+     For compatibility with external tools and unlike Emacs
+     itself (e.g. in Compile Mode) Flycheck uses _1-based_
+     columns: The first character on a line is column 1.
+
+     Occasionally some tools try to proactively adapt to Emacs
+     and emit 0-based columns automatically.  In these cases, the
+     columns must be adjusted for Flycheck, see
+     `flycheck-increment-error-columns'.
+
+`message' (optional)
+     The error message as a string, if any.
+
+`level'
+     The error level, as either `info', `warning' or `error'.
+
+`id' (optional)
+     An ID identifying the kind of error.
+
+`group` (optional)
+     A symbol identifying the group the error belongs to.
+
+     Some tools will emit multiple errors that relate to the same
+     issue (e.g., lifetime errors in Rust).  All related errors
+     collected by a checker should have the same `group` value,
+     in order to be able to present them to the user.
+
+     See `flycheck-related-errors`."
+  buffer checker filename line column message level id group)
+
+(defmacro flycheck-error-with-buffer (err &rest forms)
+  "Switch to the buffer of ERR and evaluate FORMS.
+
+If the buffer of ERR is not live, FORMS are not evaluated."
+  (declare (indent 1) (debug t))
+  `(when (buffer-live-p (flycheck-error-buffer ,err))
+     (with-current-buffer (flycheck-error-buffer ,err)
+       ,@forms)))
+
+(defun flycheck-error-line-region (err)
+  "Get the line region of ERR.
+
+ERR is a Flycheck error whose region to get.
+
+Return a cons cell `(BEG . END)' where BEG is the first
+non-whitespace character on the line ERR refers to, and END the
+end of the line."
+  (flycheck-error-with-buffer err
+    (save-restriction
+      (save-excursion
+        (widen)
+        (goto-char (point-min))
+        (forward-line (- (flycheck-error-line err) 1))
+        ;; We are at the beginning of the line now, so move to the beginning of
+        ;; its indentation, similar to `back-to-indentation'
+        (let ((end (line-end-position)))
+          (skip-syntax-forward " " end)
+          (backward-prefix-chars)
+          ;; If the current line is empty, include the previous line break
+          ;; character(s) to have any region at all.  When called with 0,
+          ;; `line-end-position' gives us the end of the previous line
+          (cons (if (eolp) (line-end-position 0) (point)) end))))))
+
+(defun flycheck-error-column-region (err)
+  "Get the error column region of ERR.
+
+ERR is a Flycheck error whose region to get.
+
+Return a cons cell `(BEG . END)' where BEG is the character
+before the error column, and END the actual error column, or nil
+if ERR has no column."
+  (flycheck-error-with-buffer err
+    (save-restriction
+      (save-excursion
+        (-when-let (column (flycheck-error-column err))
+          (widen)
+          (goto-char (point-min))
+          (forward-line (- (flycheck-error-line err) 1))
+          (cond
+           ((eobp)                    ; Line beyond EOF
+            ;; If we are at the end of the file (i.e. the line was beyond the
+            ;; end of the file), use the very last column in the file.
+            (cons (- (point-max) 1) (point-max)))
+           ((eolp)                    ; Empty line
+            ;; If the target line is empty, there's no column to highlight on
+            ;; this line, so return the last column of the previous line.
+            (cons (line-end-position 0) (point)))
+           (t
+            ;; The end is either the column offset of the line, or the end of
+            ;; the line, if the column offset points beyond the end of the
+            ;; line.
+            (let ((end (min (+ (point) column)
+                            (+ (line-end-position) 1))))
+              (cons (- end 1) end)))))))))
+
+(defun flycheck-error-thing-region (thing err)
+  "Get the region of THING at the column of ERR.
+
+ERR is a Flycheck error whose region to get.  THING is a
+understood by `thing-at-point'.
+
+Return a cons cell `(BEG . END)' where BEG is the beginning of
+the THING at the error column, and END the end of the symbol.  If
+ERR has no error column, or if there is no THING at this column,
+return nil."
+  (-when-let (column (car (flycheck-error-column-region err)))
+    (flycheck-error-with-buffer err
+      (save-excursion
+        (save-restriction
+          (widen)
+          (goto-char column)
+          (bounds-of-thing-at-point thing))))))
+
+(defun flycheck-error-region-for-mode (err mode)
+  "Get the region of ERR for the highlighting MODE.
+
+ERR is a Flycheck error.  MODE may be one of the following symbols:
+
+`columns'
+     Get the column region of ERR, or the line region if ERR
+     has no column.
+
+`symbols'
+     Get the symbol region of ERR, or the result of `columns', if
+     there is no sexp at the error column.
+
+`sexps'
+     Get the sexp region of ERR, or the result of `columns', if
+     there is no sexp at the error column.
+
+`lines'
+     Return the line region.
+
+Otherwise signal an error."
+  ;; Ignoring fields speeds up calls to `line-end-position' in
+  ;; `flycheck-error-column-region' and `flycheck-error-line-region'.
+  (let ((inhibit-field-text-motion t))
+    (pcase mode
+      (`columns (or (flycheck-error-column-region err)
+                    (flycheck-error-line-region err)))
+      (`symbols (or (flycheck-error-thing-region 'symbol err)
+                    (flycheck-error-region-for-mode err 'columns)))
+      (`sexps (or (flycheck-error-thing-region 'sexp err)
+                  (flycheck-error-region-for-mode err 'columns)))
+      (`lines (flycheck-error-line-region err))
+      (_ (error "Invalid mode %S" mode)))))
+
+(defun flycheck-error-pos (err)
+  "Get the buffer position of ERR.
+
+ERR is a Flycheck error whose position to get.
+
+The error position is the error column, or the first
+non-whitespace character of the error line, if ERR has no error column."
+  (car (or (flycheck-error-column-region err)
+           (flycheck-error-line-region err))))
+
+(defun flycheck-error-format-message-and-id (err)
+  "Format the message and id of ERR as human-readable string."
+  (let ((id (flycheck-error-id err))
+        (filename (flycheck-error-filename err)))
+    (concat (when (and filename (not (equal filename (buffer-file-name))))
+              (format "In \"%s\":\n"
+                      (file-relative-name filename default-directory)))
+            (flycheck-error-message err)
+            (when id
+              (format " [%s]" id)))))
+
+(defun flycheck-error-format (err &optional with-file-name)
+  "Format ERR as human-readable string, optionally WITH-FILE-NAME.
+
+Return a string that represents the given ERR.  If WITH-FILE-NAME
+is given and non-nil, include the file-name as well, otherwise
+omit it."
+  (let* ((line (flycheck-error-line err))
+         (column (flycheck-error-column err))
+         (level (symbol-name (flycheck-error-level err)))
+         (checker (symbol-name (flycheck-error-checker err)))
+         (format `(,@(when with-file-name
+                       (list (flycheck-error-filename err) ":"))
+                   ,(number-to-string line) ":"
+                   ,@(when column (list (number-to-string column) ":"))
+                   ,level ": "
+                   ,(flycheck-error-format-message-and-id err)
+                   " (" ,checker ")")))
+    (apply #'concat format)))
+
+(defun flycheck-error-< (err1 err2)
+  "Determine whether ERR1 is less than ERR2 by location.
+
+Compare by line numbers and then by column numbers."
+  (let ((line1 (flycheck-error-line err1))
+        (line2 (flycheck-error-line err2)))
+    (if (= line1 line2)
+        (let ((col1 (flycheck-error-column err1))
+              (col2 (flycheck-error-column err2)))
+          (and col2
+               ;; Sort errors for the whole line first
+               (or (not col1) (< col1 col2))))
+      (< line1 line2))))
+
+(defun flycheck-error-level-< (err1 err2)
+  "Determine whether ERR1 is less than ERR2 by error level.
+
+Like `flycheck-error-<', but compares by error level severity
+first.  Levels of the same severity are compared by name."
+  (let* ((level1 (flycheck-error-level err1))
+         (level2 (flycheck-error-level err2))
+         (severity1 (flycheck-error-level-severity level1))
+         (severity2 (flycheck-error-level-severity level2)))
+    (cond
+     ((= severity1 severity2)
+      (if (string= level1 level2)
+          (flycheck-error-< err1 err2)
+        (string< level1 level2)))
+     (t (< severity1 severity2)))))
+
+(defun flycheck-assert-error-list-p (errors)
+  "Assert that all items in ERRORS are of `flycheck-error' type.
+
+Signal an error if any item in ERRORS is not a `flycheck-error'
+object, as by `flycheck-error-p'.  Otherwise return ERRORS
+again."
+  (unless (listp errors)
+    (signal 'wrong-type-argument (list 'listp errors)))
+  (dolist (err errors)
+    (unless (flycheck-error-p err)
+      (signal 'wrong-type-argument (list 'flycheck-error-p err))))
+  errors)
+
+
+;;; Errors in the current buffer
+(defvar-local flycheck-current-errors nil
+  "A list of all errors and warnings in the current buffer.")
+
+(defun flycheck-report-current-errors (errors)
+  "Report ERRORS in the current buffer.
+
+Add ERRORS to `flycheck-current-errors' and process each error
+with `flycheck-process-error-functions'."
+  (setq flycheck-current-errors (sort (append errors flycheck-current-errors)
+                                      #'flycheck-error-<))
+  (overlay-recenter (point-max))
+  (seq-do (lambda (err)
+            (run-hook-with-args-until-success 'flycheck-process-error-functions
+                                              err))
+          errors))
+
+(defun flycheck-clear-errors ()
+  "Remove all error information from the current buffer."
+  (setq flycheck-current-errors nil)
+  (flycheck-report-status 'not-checked))
+
+(defun flycheck-fill-and-expand-error-file-names (errors directory)
+  "Fill and expand file names in ERRORS relative to DIRECTORY.
+
+Expand all file names of ERRORS against DIRECTORY.  If the file
+name of an error is nil fill in the result of function
+`buffer-file-name' in the current buffer.
+
+Return ERRORS, modified in-place."
+  (seq-do (lambda (err)
+            (setf (flycheck-error-filename err)
+                  (-if-let (filename (flycheck-error-filename err))
+                      (expand-file-name filename directory)
+                    (buffer-file-name))))
+          errors)
+  errors)
+
+(defun flycheck-relevant-error-other-file-p (err)
+  "Determine whether ERR is a relevant error for another file."
+  (let ((file-name (flycheck-error-filename err)))
+    (and file-name
+         (or (null buffer-file-name)
+             (not (flycheck-same-files-p buffer-file-name file-name)))
+         (eq 'error (flycheck-error-level err)))))
+
+(defun flycheck-relevant-error-p (err)
+  "Determine whether ERR is relevant for the current buffer.
+
+Return t if ERR may be shown for the current buffer, or nil
+otherwise."
+  (flycheck-error-with-buffer err
+    (let ((file-name (flycheck-error-filename err))
+          (message (flycheck-error-message err)))
+      (and
+       (or
+        ;; Neither the error nor buffer have a file name
+        (and (not file-name) (not buffer-file-name))
+        ;; Both have files, and they match
+        (and buffer-file-name file-name
+             (flycheck-same-files-p file-name buffer-file-name))
+        ;; This is a significant error from another file
+        (flycheck-relevant-error-other-file-p err))
+       message
+       (not (string-empty-p message))
+       (flycheck-error-line err)))))
+
+(defun flycheck-relevant-errors (errors)
+  "Filter the relevant errors from ERRORS.
+
+Return a list of all errors that are relevant for their
+corresponding buffer."
+  (seq-filter #'flycheck-relevant-error-p errors))
+
+(defun flycheck-related-errors (err &optional error-set)
+  "Get all the errors that are in the same group as ERR.
+
+Return a list of all errors (from ERROR-SET) that have the same
+`flycheck-error-group' as ERR, including ERR itself.
+
+If ERROR-SET is nil, `flycheck-current-errors' is used instead."
+  (let ((group (flycheck-error-group err))
+        (checker (flycheck-error-checker err)))
+    (if group
+        (seq-filter (lambda (e)
+                      (and (eq (flycheck-error-checker e) checker)
+                           (eq (flycheck-error-group e) group)))
+                    (or error-set flycheck-current-errors))
+      (list err))))
+
+
+;;; Status reporting for the current buffer
+(defvar-local flycheck-last-status-change 'not-checked
+  "The last status change in the current buffer.")
+
+(defun flycheck-report-failed-syntax-check (&optional status)
+  "Report a failed Flycheck syntax check with STATUS.
+
+STATUS is a status symbol for `flycheck-report-status',
+defaulting to `errored'.
+
+Clear Flycheck state, run `flycheck-syntax-check-failed-hook' and
+report an error STATUS."
+  (flycheck-clear)
+  (setq flycheck-current-syntax-check nil)
+  (run-hooks 'flycheck-syntax-check-failed-hook)
+  (flycheck-report-status (or status 'errored)))
+
+(defun flycheck-report-status (status)
+  "Report Flycheck STATUS.
+
+STATUS is one of the following symbols:
+
+`not-checked'
+     The current buffer was not checked.
+
+`no-checker'
+     Automatic syntax checker selection did not find a suitable
+     syntax checker.
+
+`running'
+     A syntax check is now running in the current buffer.
+
+`errored'
+     The current syntax check has errored.
+
+`finished'
+     The current syntax check was finished normally.
+
+`interrupted'
+     The current syntax check was interrupted.
+
+`suspicious'
+     The last syntax check had a suspicious result.
+
+Set `flycheck-last-status-change' and call
+`flycheck-status-changed-functions' with STATUS.  Afterwards
+refresh the mode line."
+  (setq flycheck-last-status-change status)
+  (run-hook-with-args 'flycheck-status-changed-functions status)
+  (force-mode-line-update))
+
+(defun flycheck-mode-line-status-text (&optional status)
+  "Get a text describing STATUS for use in the mode line.
+
+STATUS defaults to `flycheck-last-status-change' if omitted or
+nil."
+  (let ((text (pcase (or status flycheck-last-status-change)
+                (`not-checked "")
+                (`no-checker "-")
+                (`running "*")
+                (`errored "!")
+                (`finished
+                 (let-alist (flycheck-count-errors flycheck-current-errors)
+                   (if (or .error .warning)
+                       (format ":%s/%s" (or .error 0) (or .warning 0))
+                     "")))
+                (`interrupted ".")
+                (`suspicious "?"))))
+    (concat " " flycheck-mode-line-prefix text)))
+
+
+;;; Error levels
+;;;###autoload
+(defun flycheck-define-error-level (level &rest properties)
+  "Define a new error LEVEL with PROPERTIES.
+
+The following PROPERTIES constitute an error level:
+
+`:severity SEVERITY'
+     A number denoting the severity of this level.  The higher
+     the number, the more severe is this level compared to other
+     levels.  Defaults to 0.
+
+     The severity is used by `flycheck-error-level-<' to
+     determine the ordering of errors according to their levels.
+
+`:compilation-level LEVEL'
+
+     A number indicating the broad class of messages that errors
+     at this level belong to: one of 0 (info), 1 (warning), or
+     2 or nil (error).  Defaults to nil.
+
+     This is used by `flycheck-checker-pattern-to-error-regexp'
+     to map error levels into `compilation-mode''s hierarchy and
+     to get proper highlighting of errors in `compilation-mode'.
+
+`:overlay-category CATEGORY'
+     A symbol denoting the overlay category to use for error
+     highlight overlays for this level.  See Info
+     node `(elisp)Overlay Properties' for more information about
+     overlay categories.
+
+     A category for an error level overlay should at least define
+     the `face' property, for error highlighting.  Another useful
+     property for error level categories is `priority', to
+     influence the stacking of multiple error level overlays.
+
+`:fringe-bitmap BITMAP'
+     A fringe bitmap symbol denoting the bitmap to use for fringe
+     indicators for this level.  See Info node `(elisp)Fringe
+     Bitmaps' for more information about fringe bitmaps,
+     including a list of built-in fringe bitmaps.
+
+`:fringe-face FACE'
+     A face symbol denoting the face to use for fringe indicators
+     for this level.
+
+`:error-list-face FACE'
+     A face symbol denoting the face to use for messages of this
+     level in the error list.  See `flycheck-list-errors'."
+  (declare (indent 1))
+  (setf (get level 'flycheck-error-level) t)
+  (setf (get level 'flycheck-error-severity)
+        (or (plist-get properties :severity) 0))
+  (setf (get level 'flycheck-compilation-level)
+        (plist-get properties :compilation-level))
+  (setf (get level 'flycheck-overlay-category)
+        (plist-get properties :overlay-category))
+  (setf (get level 'flycheck-fringe-bitmap-double-arrow)
+        (plist-get properties :fringe-bitmap))
+  (setf (get level 'flycheck-fringe-face)
+        (plist-get properties :fringe-face))
+  (setf (get level 'flycheck-error-list-face)
+        (plist-get properties :error-list-face)))
+
+(defun flycheck-error-level-p (level)
+  "Determine whether LEVEL is a Flycheck error level."
+  (get level 'flycheck-error-level))
+
+(defun flycheck-error-level-severity (level)
+  "Get the numeric severity of LEVEL."
+  (or (get level 'flycheck-error-severity) 0))
+
+(defun flycheck-error-level-compilation-level (level)
+  "Get the compilation level for LEVEL."
+  (get level 'flycheck-compilation-level))
+
+(defun flycheck-error-level-overlay-category (level)
+  "Get the overlay category for LEVEL."
+  (get level 'flycheck-overlay-category))
+
+(defun flycheck-error-level-fringe-bitmap (level)
+  "Get the fringe bitmap for LEVEL."
+  (get level 'flycheck-fringe-bitmap-double-arrow))
+
+(defun flycheck-error-level-fringe-face (level)
+  "Get the fringe face for LEVEL."
+  (get level 'flycheck-fringe-face))
+
+(defun flycheck-error-level-error-list-face (level)
+  "Get the error list face for LEVEL."
+  (get level 'flycheck-error-list-face))
+
+(defun flycheck-error-level-make-fringe-icon (level side)
+  "Create the fringe icon for LEVEL at SIDE.
+
+Return a propertized string that shows a fringe bitmap according
+to LEVEL and the given fringe SIDE.
+
+LEVEL is a Flycheck error level defined with
+`flycheck-define-error-level', and SIDE is either `left-fringe'
+or `right-fringe'.
+
+Return a propertized string representing the fringe icon,
+intended for use as `before-string' of an overlay to actually
+show the icon."
+  (unless (memq side '(left-fringe right-fringe))
+    (error "Invalid fringe side: %S" side))
+  (propertize "!" 'display
+              (list side
+                    (flycheck-error-level-fringe-bitmap level)
+                    (flycheck-error-level-fringe-face level))))
+
+
+;;; Built-in error levels
+(when (fboundp 'define-fringe-bitmap)
+  (define-fringe-bitmap 'flycheck-fringe-bitmap-double-arrow
+    (vector #b00000000
+            #b00000000
+            #b00000000
+            #b00000000
+            #b00000000
+            #b10011000
+            #b01101100
+            #b00110110
+            #b00011011
+            #b00110110
+            #b01101100
+            #b10011000
+            #b00000000
+            #b00000000
+            #b00000000
+            #b00000000
+            #b00000000)))
+
+(setf (get 'flycheck-error-overlay 'face) 'flycheck-error)
+(setf (get 'flycheck-error-overlay 'priority) 110)
+
+(flycheck-define-error-level 'error
+  :severity 100
+  :compilation-level 2
+  :overlay-category 'flycheck-error-overlay
+  :fringe-bitmap 'flycheck-fringe-bitmap-double-arrow
+  :fringe-face 'flycheck-fringe-error
+  :error-list-face 'flycheck-error-list-error)
+
+(setf (get 'flycheck-warning-overlay 'face) 'flycheck-warning)
+(setf (get 'flycheck-warning-overlay 'priority) 100)
+
+(flycheck-define-error-level 'warning
+  :severity 10
+  :compilation-level 1
+  :overlay-category 'flycheck-warning-overlay
+  :fringe-bitmap 'flycheck-fringe-bitmap-double-arrow
+  :fringe-face 'flycheck-fringe-warning
+  :error-list-face 'flycheck-error-list-warning)
+
+(setf (get 'flycheck-info-overlay 'face) 'flycheck-info)
+(setf (get 'flycheck-info-overlay 'priority) 90)
+
+(flycheck-define-error-level 'info
+  :severity -10
+  :compilation-level 0
+  :overlay-category 'flycheck-info-overlay
+  :fringe-bitmap 'flycheck-fringe-bitmap-double-arrow
+  :fringe-face 'flycheck-fringe-info
+  :error-list-face 'flycheck-error-list-info)
+
+
+;;; Error filtering
+(defun flycheck-filter-errors (errors checker)
+  "Filter ERRORS from CHECKER.
+
+Apply the error filter of CHECKER to ERRORs and return the
+result.  If CHECKER has no error filter, fall back to
+`flycheck-sanitize-errors'."
+  (let ((filter (or (flycheck-checker-get checker 'error-filter)
+                    #'flycheck-sanitize-errors)))
+    (funcall filter errors)))
+
+(defun flycheck-sanitize-errors (errors)
+  "Sanitize ERRORS.
+
+Sanitize ERRORS by trimming leading and trailing whitespace in
+all error messages, and by replacing 0 columns and empty error
+messages with nil.
+
+Returns sanitized ERRORS."
+  (dolist (err errors)
+    (flycheck-error-with-buffer err
+      (let ((message (flycheck-error-message err))
+            (column (flycheck-error-column err))
+            (id (flycheck-error-id err)))
+        (when message
+          (setq message (string-trim message))
+          (setf (flycheck-error-message err)
+                (if (string-empty-p message) nil message)))
+        (when (and id (string-empty-p id))
+          (setf (flycheck-error-id err) nil))
+        (when (eq column 0)
+          (setf (flycheck-error-column err) nil)))))
+  errors)
+
+(defun flycheck-remove-error-file-names (file-name errors)
+  "Remove matching FILE-NAME from ERRORS.
+
+Use as `:error-filter' for syntax checkers that output faulty
+filenames.  Flycheck will later fill in the buffer file name.
+
+Return ERRORS."
+  (seq-do (lambda (err)
+            (when (and (flycheck-error-filename err)
+                       (string= (flycheck-error-filename err) file-name))
+              (setf (flycheck-error-filename err) nil)))
+          errors)
+  errors)
+
+(defun flycheck-increment-error-columns (errors &optional offset)
+  "Increment all columns of ERRORS by OFFSET.
+
+Use this as `:error-filter' if a syntax checker outputs 0-based
+columns."
+  (seq-do (lambda (err)
+            (let ((column (flycheck-error-column err)))
+              (when column
+                (setf (flycheck-error-column err)
+                      (+ column (or offset 1))))))
+          errors)
+  errors)
+
+(defun flycheck-collapse-error-message-whitespace (errors)
+  "Collapse whitespace in all messages of ERRORS.
+
+Return ERRORS."
+  (dolist (err errors)
+    (-when-let (message (flycheck-error-message err))
+      (setf (flycheck-error-message err)
+            (replace-regexp-in-string (rx (one-or-more (any space "\n" "\r")))
+                                      " " message 'fixed-case 'literal))))
+  errors)
+
+(defun flycheck-dedent-error-messages (errors)
+  "Dedent all messages of ERRORS.
+
+For each error in ERRORS, determine the indentation offset from
+the leading whitespace of the first line, and dedent all further
+lines accordingly.
+
+Return ERRORS, with in-place modifications."
+  (dolist (err errors)
+    (-when-let (message (flycheck-error-message err))
+      (with-temp-buffer
+        (insert message)
+        ;; Determine the indentation offset
+        (goto-char (point-min))
+        (back-to-indentation)
+        (let* ((indent-offset (- (point) (point-min))))
+          ;; Now iterate over all lines and dedent each according to
+          ;; `indent-offset'
+          (while (not (eobp))
+            (back-to-indentation)
+            ;; If the current line starts with sufficient whitespace, delete the
+            ;; indendation offset.  Otherwise keep the line intact, as we might
+            ;; loose valuable information
+            (when (>= (- (point) (line-beginning-position)) indent-offset)
+              (delete-char (- indent-offset)))
+            (forward-line 1)))
+        (delete-trailing-whitespace (point-min) (point-max))
+        (setf (flycheck-error-message err)
+              (buffer-substring-no-properties (point-min) (point-max))))))
+  errors)
+
+(defun flycheck-fold-include-levels (errors sentinel-message)
+  "Fold levels of ERRORS from included files.
+
+ERRORS is a list of `flycheck-error' objects.  SENTINEL-MESSAGE
+is a regular expression matched against the error message to
+determine whether the errror denotes errors from an included
+file.  Alternatively, it is a function that is given an error and
+shall return non-nil, if the error denotes errors from an
+included file."
+  (unless (or (stringp sentinel-message) (functionp sentinel-message))
+    (error "Sentinel must be string or function: %S" sentinel-message))
+  (let ((sentinel (if (functionp sentinel-message)
+                      sentinel-message
+                    (lambda (err)
+                      (string-match-p sentinel-message
+                                      (flycheck-error-message err)))))
+        (remaining-errors errors))
+    (while remaining-errors
+      (let* ((current-error (pop remaining-errors)))
+        (when (funcall sentinel current-error)
+          ;; We found an error denoting errors in the included file:
+          ;; 1. process all subsequent errors until faulty include file is found
+          ;; 2. process again all subsequent errors until an error has the
+          ;;    current file name again
+          ;; 3. find the most severe error level
+          (let ((current-filename (flycheck-error-filename current-error))
+                (current-level nil)
+                (faulty-include-filename nil)
+                (filename nil)
+                (done (null remaining-errors)))
+
+            (while (not done)
+              (setq filename (flycheck-error-filename (car remaining-errors)))
+              (unless faulty-include-filename
+                (unless (string= filename current-filename)
+                  (setq faulty-include-filename filename)))
+
+              (let* ((error-in-include (pop remaining-errors))
+                     (in-include-level (flycheck-error-level error-in-include)))
+                (unless (funcall sentinel error-in-include)
+                  ;; Ignore nested "included file" errors, we are only
+                  ;; interested in real errors because these define our level
+                  (when (or (not current-level)
+                            (> (flycheck-error-level-severity in-include-level)
+                               (flycheck-error-level-severity current-level)))
+                    (setq current-level in-include-level))))
+
+              (setq done (or (null remaining-errors)
+                             (and faulty-include-filename
+                                  (string= filename current-filename)))))
+
+            (setf (flycheck-error-level current-error) current-level
+                  (flycheck-error-message current-error)
+                  (format "In include %s" faulty-include-filename))))))
+    errors))
+
+(defun flycheck-dequalify-error-ids (errors)
+  "De-qualify error ids in ERRORS.
+
+Remove all qualifications from error ids in ERRORS, by stripping
+all leading dotted components from error IDs.  For instance, if
+the error ID is com.foo.E100, replace it with E100.
+
+This error filter is mainly useful to simplify error IDs obtained
+from parsing Checkstyle XML, which frequently has very verbose
+IDs, that include the name of the tool."
+  (seq-do (lambda (err)
+            (let ((id (flycheck-error-id err)))
+              (when id
+                (setf (flycheck-error-id err)
+                      (replace-regexp-in-string
+                       (rx string-start
+                           (group
+                            (optional (zero-or-more not-newline) "."))
+                           (one-or-more (not (any ".")))
+                           string-end)
+                       "" id 'fixedcase 'literal 1)))))
+          errors)
+  errors)
+
+(defun flycheck-remove-error-ids (errors)
+  "Remove all error ids from ERRORS."
+  (seq-do (lambda (err) (setf (flycheck-error-id err) nil)) errors)
+  errors)
+
+(defun flycheck-fill-empty-line-numbers (errors)
+  "Set ERRORS without lines to line 0.
+
+Use as `:error-filter' for syntax checkers that output errors
+without line numbers.
+
+Return ERRORS."
+  (seq-do (lambda (err)
+            (unless (flycheck-error-line err)
+              (setf (flycheck-error-line err) 0)))
+          errors)
+  errors)
+
+
+;;; Error analysis
+(defun flycheck-count-errors (errors)
+  "Count the number of ERRORS, grouped by level..
+
+Return an alist, where each ITEM is a cons cell whose `car' is an
+error level, and whose `cdr' is the number of errors of that
+level."
+  (let (counts-by-level)
+    (dolist (err errors)
+      (let* ((level (flycheck-error-level err))
+             (item (assq level counts-by-level)))
+        (if item
+            (cl-incf (cdr item))
+          (push (cons level 1) counts-by-level))))
+    counts-by-level))
+
+(defun flycheck-has-max-errors-p (errors level)
+  "Check if there is no error in ERRORS more severe than LEVEL."
+  (let ((severity (flycheck-error-level-severity level)))
+    (seq-every-p (lambda (e) (<= (flycheck-error-level-severity
+                                  (flycheck-error-level e))
+                                 severity))
+                 errors)))
+
+(defun flycheck-has-max-current-errors-p (level)
+  "Check if there is no current error more severe than LEVEL."
+  (flycheck-has-max-errors-p flycheck-current-errors level))
+
+(defun flycheck-has-errors-p (errors level)
+  "Determine if there are any ERRORS with LEVEL."
+  (seq-some (lambda (e) (eq (flycheck-error-level e) level)) errors))
+
+(defun flycheck-has-current-errors-p (&optional level)
+  "Determine if the current buffer has errors with LEVEL.
+
+If LEVEL is omitted if the current buffer has any errors at all."
+  (if level
+      (flycheck-has-errors-p flycheck-current-errors level)
+    (and flycheck-current-errors t)))
+
+
+;;; Error overlays in the current buffer
+(defun flycheck-add-overlay (err)
+  "Add overlay for ERR.
+
+Return the created overlay."
+  ;; We must have a proper error region for the sake of fringe indication,
+  ;; error display and error navigation, even if the highlighting is disabled.
+  ;; We erase the highlighting later on in this case
+  (pcase-let* ((`(,beg . ,end)
+                (if (flycheck-relevant-error-other-file-p err)
+                    ;; Display overlays for other-file errors on the first line
+                    (cons (point-min)
+                          (save-excursion (goto-char (point-min))
+                                          (point-at-eol)))
+                  (flycheck-error-region-for-mode
+                   err (or flycheck-highlighting-mode 'lines))))
+               (overlay (make-overlay beg end))
+               (level (flycheck-error-level err))
+               (category (flycheck-error-level-overlay-category level)))
+    (unless (flycheck-error-level-p level)
+      (error "Undefined error level: %S" level))
+    (setf (overlay-get overlay 'flycheck-overlay) t)
+    (setf (overlay-get overlay 'flycheck-error) err)
+    (setf (overlay-get overlay 'category) category)
+    (unless flycheck-highlighting-mode
+      ;; Erase the highlighting from the overlay if requested by the user
+      (setf (overlay-get overlay 'face) nil))
+    (when flycheck-indication-mode
+      (setf (overlay-get overlay 'before-string)
+            (flycheck-error-level-make-fringe-icon
+             level flycheck-indication-mode)))
+    (setf (overlay-get overlay 'help-echo) #'flycheck-help-echo)
+    overlay))
+
+(defun flycheck-help-echo (_window object pos)
+  "Construct a tooltip message.
+
+Most of the actual work is done by calling
+`flycheck-help-echo-function' with the appropriate list of
+errors.  Arguments WINDOW, OBJECT and POS are as described in
+info node `(elisp)Special properties', as this function is
+intended to be used as the 'help-echo property of flycheck error
+overlays."
+  (-when-let (buf (cond ((bufferp object) object)
+                        ((overlayp object) (overlay-buffer object))))
+    (with-current-buffer buf
+      (-when-let* ((fn flycheck-help-echo-function)
+                   (errs (flycheck-overlay-errors-at pos)))
+        (funcall fn errs)))))
+
+(defun flycheck-help-echo-all-error-messages (errs)
+  "Concatenate error messages and ids from ERRS."
+  (mapconcat
+   (lambda (err)
+     (when err
+       (if (flycheck-error-message err)
+           (flycheck-error-format-message-and-id err)
+         (format "Unknown %s" (flycheck-error-level err)))))
+   (reverse errs) "\n\n"))
+
+(defun flycheck-filter-overlays (overlays)
+  "Get all Flycheck overlays from OVERLAYS."
+  (seq-filter (lambda (o) (overlay-get o 'flycheck-overlay)) overlays))
+
+(defun flycheck-overlays-at (pos)
+  "Get all Flycheck overlays at POS."
+  (flycheck-filter-overlays (overlays-at pos)))
+
+(defun flycheck-overlays-in (beg end)
+  "Get all Flycheck overlays between BEG and END."
+  (flycheck-filter-overlays (overlays-in beg end)))
+
+(defun flycheck-overlay-errors-at (pos)
+  "Return a list of all flycheck errors overlayed at POS."
+  (seq-map (lambda (o) (overlay-get o 'flycheck-error))
+           (flycheck-overlays-at pos)))
+
+(defun flycheck-overlay-errors-in (beg end)
+  "Return a list of all flycheck errors overlayed between BEG and END."
+  (seq-map (lambda (o) (overlay-get o 'flycheck-error))
+           (flycheck-overlays-in beg end)))
+
+(defvar-local flycheck-overlays-to-delete nil
+  "Overlays mark for deletion after all syntax checks completed.")
+(put 'flycheck-overlays-to-delete 'permanent-local t)
+
+(defun flycheck-delete-all-overlays ()
+  "Remove all flycheck overlays in the current buffer."
+  (overlay-recenter (point-max))
+  (flycheck-delete-marked-overlays)
+  (save-restriction
+    (widen)
+    (seq-do #'delete-overlay (flycheck-overlays-in (point-min) (point-max)))))
+
+(defun flycheck-mark-all-overlays-for-deletion ()
+  "Mark all current overlays for deletion."
+  (setq flycheck-overlays-to-delete
+        (append (flycheck-overlays-in (point-min) (point-max))
+                flycheck-overlays-to-delete)))
+
+(defun flycheck-delete-marked-overlays ()
+  "Delete all overlays marked for deletion."
+  (overlay-recenter (point-max))
+  (seq-do #'delete-overlay flycheck-overlays-to-delete)
+  (setq flycheck-overlays-to-delete nil))
+
+
+;;; Error navigation in the current buffer
+(defun flycheck-error-level-interesting-at-pos-p (pos)
+  "Check if error severity at POS passes `flycheck-error-level-interesting-p'."
+  (flycheck-error-level-interesting-p (get-char-property pos 'flycheck-error)))
+
+(defun flycheck-error-level-interesting-p (err)
+  "Check if ERR severity is >= `flycheck-navigation-minimum-level'."
+  (when (flycheck-error-p err)
+    (-if-let (min-level flycheck-navigation-minimum-level)
+        (<= (flycheck-error-level-severity min-level)
+            (flycheck-error-level-severity (flycheck-error-level err)))
+      t)))
+
+(defun flycheck-next-error-pos (n &optional reset)
+  "Get the position of the N-th next error.
+
+With negative N, get the position of the (-N)-th previous error
+instead.  With non-nil RESET, search from `point-min', otherwise
+search from the current point.
+
+Return the position of the next or previous error, or nil if
+there is none."
+  (let ((n (or n 1))
+        (pos (if reset (point-min) (point))))
+    (if (>= n 0)
+        ;; Search forwards
+        (while (and pos (> n 0))
+          (setq n (1- n))
+          (when (get-char-property pos 'flycheck-error)
+            ;; Move beyond from the current error if any
+            (setq pos (next-single-char-property-change pos 'flycheck-error)))
+          (while (not (or (= pos (point-max))
+                          (flycheck-error-level-interesting-at-pos-p pos)))
+            ;; Scan for the next error
+            (setq pos (next-single-char-property-change pos 'flycheck-error)))
+          (when (and (= pos (point-max))
+                     (not (flycheck-error-level-interesting-at-pos-p pos)))
+            ;; If we reached the end of the buffer, but no error, we didn't find
+            ;; any
+            (setq pos nil)))
+      ;; Search backwards
+      (while (and pos (< n 0))
+        (setq n (1+ n))
+        ;; Loop until we find an error.  We need to check the position *before*
+        ;; the current one, because `previous-single-char-property-change'
+        ;; always moves to the position *of* the change.
+        (while (not (or (= pos (point-min))
+                        (flycheck-error-level-interesting-at-pos-p (1- pos))))
+          (setq pos (previous-single-char-property-change pos 'flycheck-error)))
+        (when (and (= pos (point-min))
+                   (not (flycheck-error-level-interesting-at-pos-p pos)))
+          ;; We didn't find any error.
+          (setq pos nil))
+        (when pos
+          ;; We found an error, so move to its beginning
+          (setq pos (previous-single-char-property-change pos
+                                                          'flycheck-error)))))
+    pos))
+
+(defun flycheck-next-error-function (n reset)
+  "Visit the N-th error from the current point.
+
+N is the number of errors to advance by, where a negative N
+advances backwards.  With non-nil RESET, advance from the
+beginning of the buffer, otherwise advance from the current
+position.
+
+Intended for use with `next-error-function'."
+  (-if-let* ((pos (flycheck-next-error-pos n reset))
+             (err (get-char-property pos 'flycheck-error)))
+      (flycheck-jump-to-error err)
+    (user-error "No more Flycheck errors")))
+
+(defun flycheck-next-error (&optional n reset)
+  "Visit the N-th error from the current point.
+
+N is the number of errors to advance by, where a negative N
+advances backwards.  With non-nil RESET, advance from the
+beginning of the buffer, otherwise advance from the current
+position."
+  (interactive "P")
+  (when (consp n)
+    ;; Universal prefix argument means reset
+    (setq reset t n nil))
+  (flycheck-next-error-function n reset)
+  (flycheck-display-error-at-point))
+
+(defun flycheck-previous-error (&optional n)
+  "Visit the N-th previous error.
+
+If given, N specifies the number of errors to move backwards by.
+If N is negative, move forwards instead."
+  (interactive "P")
+  (flycheck-next-error (- (or n 1))))
+
+(defun flycheck-first-error (&optional n)
+  "Visit the N-th error from beginning of the buffer.
+
+If given, N specifies the number of errors to move forward from
+the beginning of the buffer."
+  (interactive "P")
+  (flycheck-next-error n 'reset))
+
+
+;;; Listing errors in buffers
+(defconst flycheck-error-list-buffer "*Flycheck errors*"
+  "The name of the buffer to show error lists.")
+
+(defvar flycheck-error-list-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "f") #'flycheck-error-list-set-filter)
+    (define-key map (kbd "F") #'flycheck-error-list-reset-filter)
+    (define-key map (kbd "n") #'flycheck-error-list-next-error)
+    (define-key map (kbd "p") #'flycheck-error-list-previous-error)
+    (define-key map (kbd "g") #'flycheck-error-list-check-source)
+    (define-key map (kbd "e") #'flycheck-error-list-explain-error)
+    (define-key map (kbd "RET") #'flycheck-error-list-goto-error)
+    map)
+  "The keymap of `flycheck-error-list-mode'.")
+
+(defun flycheck-error-list-make-last-column (message checker)
+  "Compute contents of the last error list cell.
+
+MESSAGE and CHECKER are displayed in a single column to allow the
+message to stretch arbitrarily far."
+  (let ((checker-name (propertize (symbol-name checker)
+                                  'face 'flycheck-error-list-checker-name)))
+    (format "%s (%s)" message checker-name)))
+
+(defconst flycheck-error-list-format
+  `[("File" 6)
+    ("Line" 5 flycheck-error-list-entry-< :right-align t)
+    ("Col" 3 nil :right-align t)
+    ("Level" 8 flycheck-error-list-entry-level-<)
+    ("ID" 6 t)
+    (,(flycheck-error-list-make-last-column "Message" 'Checker) 0 t)]
+  "Table format for the error list.")
+
+(defconst flycheck-error-list-padding 1
+  "Padding used in error list.")
+
+(defconst flycheck--error-list-msg-offset
+  (seq-reduce
+   (lambda (offset fmt)
+     (pcase-let* ((`(,_ ,width ,_ . ,props) fmt)
+                  (padding (or (plist-get props :pad-right) 1)))
+       (+ offset width padding)))
+   (seq-subseq flycheck-error-list-format 0 -1)
+   flycheck-error-list-padding)
+  "Amount of space to use in `flycheck-flush-multiline-message'.")
+
+(define-derived-mode flycheck-error-list-mode tabulated-list-mode
+  "Flycheck errors"
+  "Major mode for listing Flycheck errors.
+
+\\{flycheck-error-list-mode-map}"
+  (setq tabulated-list-format flycheck-error-list-format
+        ;; Sort by location initially
+        tabulated-list-sort-key (cons "Line" nil)
+        tabulated-list-padding flycheck-error-list-padding
+        tabulated-list-entries #'flycheck-error-list-entries
+        ;; `revert-buffer' updates the mode line for us, so all we need to do is
+        ;; set the corresponding mode line construct.
+        mode-line-buffer-identification flycheck-error-list-mode-line)
+  ;; Guard `truncate-string-ellipsis' for Emacs 24.
+  ;; TODO: Remove when dropping Emacs 24 compatibility
+  (when (boundp 'truncate-string-ellipsis)
+    ;; See https://github.com/flycheck/flycheck/issues/1101
+    (setq-local truncate-string-ellipsis "…"))
+  (tabulated-list-init-header))
+
+(defvar-local flycheck-error-list-source-buffer nil
+  "The current source buffer of the error list.")
+;; Needs to permanently local to preserve the source buffer across buffer
+;; reversions
+(put 'flycheck-error-list-source-buffer 'permanent-local t)
+
+(defun flycheck-error-list-set-source (buffer)
+  "Set BUFFER as the source buffer of the error list."
+  (when (get-buffer flycheck-error-list-buffer)
+    (with-current-buffer flycheck-error-list-buffer
+      ;; Only update the source when required
+      (unless (eq buffer flycheck-error-list-source-buffer)
+        (setq flycheck-error-list-source-buffer buffer)
+        (flycheck-error-list-refresh)))))
+
+(defun flycheck-error-list-update-source ()
+  "Update the source buffer of the error list."
+  (when (not (eq (current-buffer) (get-buffer flycheck-error-list-buffer)))
+    ;; We must not update the source buffer, if the current buffer is the error
+    ;; list itself.
+    (flycheck-error-list-set-source (current-buffer))))
+
+(defun flycheck-error-list-check-source ()
+  "Trigger a syntax check in the source buffer of the error list."
+  (interactive)
+  (let ((buffer (get-buffer flycheck-error-list-source-buffer)))
+    (when (buffer-live-p buffer)
+      (with-current-buffer buffer
+        (flycheck-buffer)))))
+
+(define-button-type 'flycheck-error-list
+  'action #'flycheck-error-list-button-goto-error
+  'help-echo "mouse-2, RET: goto error"
+  'face nil)
+
+(defun flycheck-error-list-button-goto-error (button)
+  "Go to the error at BUTTON."
+  (flycheck-error-list-goto-error (button-start button)))
+
+(define-button-type 'flycheck-error-list-explain-error
+  'action #'flycheck-error-list-button-explain-error
+  'help-echo "mouse-2, RET: explain error")
+
+(defun flycheck-error-list-button-explain-error (button)
+  "Explain the error at BUTTON."
+  (flycheck-error-list-explain-error (button-start button)))
+
+(defsubst flycheck-error-list-make-cell (text &optional face help-echo type)
+  "Make an error list cell with TEXT and FACE.
+
+If FACE is nil don't set a FACE on TEXT.  If TEXT already has
+face properties, do not specify a FACE.  Note though, that if
+TEXT gets truncated it will not inherit any previous face
+properties.  If you expect TEXT to be truncated in the error
+list, do specify a FACE explicitly!
+
+If HELP-ECHO is non-nil, set a help-echo property on TEXT, with
+value HELP-ECHO.  This is convenient if you expect TEXT to be
+truncated.
+
+The cell will have the type TYPE unless TYPE is nil, and the
+default type `flycheck-error-list' will be used instead."
+  (append (list text 'type (if type type
+                             'flycheck-error-list))
+          (and face (list 'face face))
+          (and help-echo (list 'help-echo help-echo))))
+
+(defsubst flycheck-error-list-make-number-cell (number face)
+  "Make a table cell for a NUMBER with FACE.
+
+Convert NUMBER to string, fontify it with FACE and return the
+string with attached text properties."
+  (flycheck-error-list-make-cell
+   (if (numberp number) (number-to-string number) "")
+   face))
+
+(defun flycheck-error-list-make-entry (error)
+  "Make a table cell for the given ERROR.
+
+Return a list with the contents of the table cell."
+  (let* ((level (flycheck-error-level error))
+         (level-face (flycheck-error-level-error-list-face level))
+         (filename (flycheck-error-filename error))
+         (line (flycheck-error-line error))
+         (column (flycheck-error-column error))
+         (message (or (flycheck-error-message error)
+                      (format "Unknown %s" (symbol-name level))))
+         (flushed-msg (flycheck-flush-multiline-message message))
+         (id (flycheck-error-id error))
+         (id-str (if id (format "%s" id) ""))
+         (checker (flycheck-error-checker error))
+         (msg-and-checker
+          (flycheck-error-list-make-last-column flushed-msg checker))
+         (explainer (flycheck-checker-get checker 'error-explainer)))
+    (list error
+          (vector (flycheck-error-list-make-cell
+                   (if filename
+                       (file-name-nondirectory filename)
+                     "")
+                   'flycheck-error-list-filename)
+                  (flycheck-error-list-make-number-cell
+                   line 'flycheck-error-list-line-number)
+                  (flycheck-error-list-make-number-cell
+                   column 'flycheck-error-list-column-number)
+                  (flycheck-error-list-make-cell
+                   (symbol-name (flycheck-error-level error)) level-face)
+                  ;; Error ID use a different face when an error-explainer is
+                  ;; present
+                  (flycheck-error-list-make-cell
+                   id-str (if explainer 'flycheck-error-list-id-with-explainer
+                            'flycheck-error-list-id)
+                   id-str 'flycheck-error-list-explain-error)
+                  (flycheck-error-list-make-cell
+                   msg-and-checker nil msg-and-checker)))))
+
+(defun flycheck-flush-multiline-message (msg)
+  "Prepare error message MSG for display in the error list.
+
+Prepend all lines of MSG except the first with enough space to
+ensure that they line up properly once the message is displayed."
+  (let* ((spc-spec `(space . (:width ,flycheck--error-list-msg-offset)))
+         (spc (propertize " " 'display spc-spec))
+         (rep (concat "\\1" spc "\\2")))
+    (replace-regexp-in-string "\\([\r\n]+\\)\\(.\\)" rep msg)))
+
+(defun flycheck-error-list-current-errors ()
+  "Read the list of errors in `flycheck-error-list-source-buffer'."
+  (when (buffer-live-p flycheck-error-list-source-buffer)
+    (buffer-local-value 'flycheck-current-errors
+                        flycheck-error-list-source-buffer)))
+
+(defun flycheck-error-list-entries ()
+  "Create the entries for the error list."
+  (-when-let* ((errors (flycheck-error-list-current-errors))
+               (filtered (flycheck-error-list-apply-filter errors)))
+    (seq-map #'flycheck-error-list-make-entry filtered)))
+
+(defun flycheck-error-list-entry-< (entry1 entry2)
+  "Determine whether ENTRY1 is before ENTRY2 by location.
+
+See `flycheck-error-<'."
+  (flycheck-error-< (car entry1) (car entry2)))
+
+(defun flycheck-error-list-entry-level-< (entry1 entry2)
+  "Determine whether ENTRY1 is before ENTRY2 by level.
+
+See `flycheck-error-level-<'."
+  (not (flycheck-error-level-< (car entry1) (car entry2))))
+
+(defvar flycheck-error-list-mode-line-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map [mode-line mouse-1]
+      #'flycheck-error-list-mouse-switch-to-source)
+    map)
+  "Keymap for error list mode line.")
+
+(defun flycheck-error-list-propertized-source-name ()
+  "Get the name of the current source buffer for the mode line.
+
+Propertize the name of the current source buffer for use in the
+mode line indication of `flycheck-error-list-mode'."
+  (let ((name (replace-regexp-in-string
+               (rx "%") "%%"
+               (buffer-name flycheck-error-list-source-buffer)
+               'fixed-case 'literal)))
+    (propertize name 'face 'mode-line-buffer-id
+                'mouse-face 'mode-line-highlight
+                'help-echo "mouse-1: switch to source"
+                'local-map flycheck-error-list-mode-line-map)))
+
+(defun flycheck-error-list-mouse-switch-to-source (event)
+  "Switch to the error list source buffer of the EVENT window."
+  (interactive "e")
+  (save-selected-window
+    (when (eventp event)
+      (select-window (posn-window (event-start event))))
+    (when (buffer-live-p flycheck-error-list-source-buffer)
+      (switch-to-buffer flycheck-error-list-source-buffer))))
+
+(defun flycheck-get-error-list-window-list (&optional all-frames)
+  "Get all windows displaying the error list.
+
+ALL-FRAMES specifies the frames to consider, as in
+`get-buffer-window-list'."
+  (-when-let (buf (get-buffer flycheck-error-list-buffer))
+    (get-buffer-window-list buf nil all-frames)))
+
+(defun flycheck-get-error-list-window (&optional all-frames)
+  "Get a window displaying the error list, or nil if none.
+
+ALL-FRAMES specifies the frames to consider, as in
+`get-buffer-window'."
+  (-when-let (buf (get-buffer flycheck-error-list-buffer))
+    (get-buffer-window buf all-frames)))
+
+(defun flycheck-error-list-recenter-at (pos)
+  "Recenter the error list at POS."
+  (dolist (window (flycheck-get-error-list-window-list t))
+    (with-selected-window window
+      (goto-char pos)
+      (let ((recenter-redisplay nil))
+        (recenter)))))
+
+(defun flycheck-error-list-refresh ()
+  "Refresh the current error list.
+
+Add all errors currently reported for the current
+`flycheck-error-list-source-buffer', and recenter the error
+list."
+  ;; We only refresh the error list, when it is visible in a window, and we
+  ;; select this window while reverting, because Tabulated List mode attempts to
+  ;; recenter the error at the old location, so it must have the proper window
+  ;; selected.
+  (-when-let (window (flycheck-get-error-list-window t))
+    (with-selected-window window
+      (revert-buffer))
+    (run-hooks 'flycheck-error-list-after-refresh-hook)
+    (let ((preserve-pos (eq (current-buffer)
+                            (get-buffer flycheck-error-list-buffer))))
+      ;; If the error list is the current buffer, don't recenter when
+      ;; highlighting
+      (flycheck-error-list-highlight-errors preserve-pos))))
+
+(defun flycheck-error-list-mode-line-filter-indicator ()
+  "Create a string representing the current error list filter."
+  (if flycheck-error-list-minimum-level
+      (format " [>= %s]" flycheck-error-list-minimum-level)
+    ""))
+
+(defun flycheck-error-list-set-filter (level)
+  "Restrict the error list to errors at level LEVEL or higher.
+
+LEVEL is either an error level symbol, or nil, to remove the filter."
+  (interactive
+   (list (read-flycheck-error-level
+          "Minimum error level (errors at lower levels will be hidden): ")))
+  (when (and level (not (flycheck-error-level-p level)))
+    (user-error "Invalid level: %s" level))
+  (-when-let (buf (get-buffer flycheck-error-list-buffer))
+    (with-current-buffer buf
+      (setq-local flycheck-error-list-minimum-level level))
+    (flycheck-error-list-refresh)
+    (flycheck-error-list-recenter-at (point-min))))
+
+(defun flycheck-error-list-reset-filter ()
+  "Remove filters and show all errors in the error list."
+  (interactive)
+  (kill-local-variable 'flycheck-error-list-minimum-level))
+
+(defun flycheck-error-list-apply-filter (errors)
+  "Filter ERRORS according to `flycheck-error-list-minimum-level'."
+  (-if-let* ((min-level flycheck-error-list-minimum-level)
+             (min-severity (flycheck-error-level-severity min-level)))
+      (seq-filter (lambda (err) (>= (flycheck-error-level-severity
+                                     (flycheck-error-level err))
+                                    min-severity))
+                  errors)
+    errors))
+
+(defun flycheck-error-list-goto-error (&optional pos)
+  "Go to the location of the error at POS in the error list.
+
+POS defaults to `point'."
+  (interactive)
+  (-when-let* ((error (tabulated-list-get-id pos)))
+    (flycheck-jump-to-error error)))
+
+(defun flycheck-jump-to-error (error)
+  "Go to the location of ERROR."
+  (let* ((error-copy (copy-flycheck-error error))
+         (filename (flycheck-error-filename error))
+         (other-file-error (flycheck-relevant-error-other-file-p error))
+         (buffer (if filename
+                     (find-file-noselect filename)
+                   (flycheck-error-buffer error))))
+    (when (buffer-live-p buffer)
+      (setf (flycheck-error-buffer error-copy) buffer)
+      (flycheck-jump-in-buffer buffer error-copy)
+      ;; When jumping to an error in another file, it may not have
+      ;; this error available for highlighting yet, so we trigger a check
+      ;; if necessary.
+      (when other-file-error
+        (with-current-buffer buffer
+          (unless (seq-contains flycheck-current-errors error-copy 'equal)
+            (when flycheck-mode
+              (flycheck-buffer))))))))
+
+(defun flycheck-jump-in-buffer (buffer error)
+  "In BUFFER, jump to ERROR."
+  ;; FIXME: we assume BUFFER and the buffer of ERROR are the same.  We don't
+  ;; need the first argument then.
+  (if (eq (window-buffer) (get-buffer flycheck-error-list-buffer))
+      ;; When called from within the error list, keep the error list,
+      ;; otherwise replace the current buffer.
+      (pop-to-buffer buffer 'other-window)
+    (switch-to-buffer buffer))
+  (let ((pos (flycheck-error-pos error)))
+    (unless (eq (goto-char pos) (point))
+      ;; If widening gets in the way of moving to the right place, remove it
+      ;; and try again
+      (widen)
+      (goto-char pos)))
+  ;; Re-highlight the errors
+  (flycheck-error-list-highlight-errors 'preserve-pos))
+
+(defun flycheck-error-list-explain-error (&optional pos)
+  "Explain the error at POS in the error list.
+
+POS defaults to `point'."
+  (interactive)
+  (-when-let* ((error (tabulated-list-get-id pos))
+               (explainer (flycheck-checker-get (flycheck-error-checker error)
+                                                'error-explainer))
+               (explanation (funcall explainer error)))
+    (flycheck-display-error-explanation explanation)))
+
+(defun flycheck-error-list-next-error-pos (pos &optional n)
+  "Starting from POS get the N'th next error in the error list.
+
+N defaults to 1.  If N is negative, search for the previous error
+instead.
+
+Get the beginning position of the N'th next error from POS, or
+nil, if there is no next error."
+  (let ((n (or n 1)))
+    (if (>= n 0)
+        ;; Search forward
+        (while (and pos (/= n 0))
+          (setq n (1- n))
+          (setq pos (next-single-property-change pos 'tabulated-list-id)))
+      ;; Search backwards
+      (while (/= n 0)
+        (setq n (1+ n))
+        ;; We explicitly give the limit here to explicitly have the minimum
+        ;; point returned, to be able to move to the first error (which starts
+        ;; at `point-min')
+        (setq pos (previous-single-property-change pos 'tabulated-list-id
+                                                   nil (point-min)))))
+    pos))
+
+(defun flycheck-error-list-previous-error (n)
+  "Go to the N'th previous error in the error list."
+  (interactive "P")
+  (flycheck-error-list-next-error (- (or n 1))))
+
+(defun flycheck-error-list-next-error (n)
+  "Go to the N'th next error in the error list."
+  (interactive "P")
+  (let ((pos (flycheck-error-list-next-error-pos (point) n)))
+    (when (and pos (/= pos (point)))
+      (goto-char pos)
+      (save-selected-window
+        ;; Keep the error list selected, so that the user can navigate errors by
+        ;; repeatedly pressing n/p, without having to re-select the error list
+        ;; window.
+        (flycheck-error-list-goto-error)))))
+
+(defvar-local flycheck-error-list-highlight-overlays nil
+  "Error highlight overlays in the error list buffer.")
+(put 'flycheck-error-list-highlight-overlays 'permanent-local t)
+
+(defun flycheck-error-list-highlight-errors (&optional preserve-pos)
+  "Highlight errors in the error list.
+
+Highlight all errors in the error lists that are at point in the
+source buffer, and on the same line as point.  Then recenter the
+error list to the highlighted error, unless PRESERVE-POS is
+non-nil."
+  (when (get-buffer flycheck-error-list-buffer)
+    (let ((current-errors (flycheck-overlay-errors-in (line-beginning-position)
+                                                      (line-end-position))))
+      (with-current-buffer flycheck-error-list-buffer
+        (let ((old-overlays flycheck-error-list-highlight-overlays)
+              (min-point (point-max))
+              (max-point (point-min)))
+          ;; Display the new overlays first, to avoid re-display flickering
+          (setq flycheck-error-list-highlight-overlays nil)
+          (when current-errors
+            (let ((next-error-pos (point-min)))
+              (while next-error-pos
+                (let* ((beg next-error-pos)
+                       (end (flycheck-error-list-next-error-pos beg))
+                       (err (tabulated-list-get-id beg)))
+                  (when (member err current-errors)
+                    (setq min-point (min min-point beg)
+                          max-point (max max-point beg))
+                    (let ((ov (make-overlay beg
+                                            ;; Extend overlay to the beginning
+                                            ;; of the next line, to highlight
+                                            ;; the whole line
+                                            (or end (point-max)))))
+                      (push ov flycheck-error-list-highlight-overlays)
+                      (setf (overlay-get ov 'flycheck-error-highlight-overlay)
+                            t)
+                      (setf (overlay-get ov 'face)
+                            'flycheck-error-list-highlight)))
+                  (setq next-error-pos end)))))
+          ;; Delete the old overlays
+          (seq-do #'delete-overlay old-overlays)
+          (when (and (not preserve-pos) current-errors)
+            ;; Move point to the middle error
+            (goto-char (+ min-point (/ (- max-point min-point) 2)))
+            (beginning-of-line)
+            ;; And recenter the error list at this position
+            (flycheck-error-list-recenter-at (point))))))))
+
+(defun flycheck-list-errors ()
+  "Show the error list for the current buffer."
+  (interactive)
+  (unless flycheck-mode
+    (user-error "Flycheck mode not enabled"))
+  ;; Create and initialize the error list
+  (unless (get-buffer flycheck-error-list-buffer)
+    (with-current-buffer (get-buffer-create flycheck-error-list-buffer)
+      (flycheck-error-list-mode)))
+  (flycheck-error-list-set-source (current-buffer))
+  ;; Reset the error filter
+  (flycheck-error-list-reset-filter)
+  ;; Show the error list in a window, and re-select the old window
+  (display-buffer flycheck-error-list-buffer)
+  ;; Finally, refresh the error list to show the most recent errors
+  (flycheck-error-list-refresh))
+
+(defalias 'list-flycheck-errors 'flycheck-list-errors)
+
+
+;;; Displaying errors in the current buffer
+(defun flycheck-display-errors (errors)
+  "Display ERRORS using `flycheck-display-errors-function'."
+  (when flycheck-display-errors-function
+    (funcall flycheck-display-errors-function errors)))
+
+(defvar-local flycheck-display-error-at-point-timer nil
+  "Timer to automatically show the error at point in minibuffer.")
+
+(defun flycheck-cancel-error-display-error-at-point-timer ()
+  "Cancel the error display timer for the current buffer."
+  (when flycheck-display-error-at-point-timer
+    (cancel-timer flycheck-display-error-at-point-timer)
+    (setq flycheck-display-error-at-point-timer nil)))
+
+(defun flycheck-display-error-at-point ()
+  "Display the all error messages at point in minibuffer."
+  (interactive)
+  ;; This function runs from a timer, so we must take care to not ignore any
+  ;; errors
+  (with-demoted-errors "Flycheck error display error: %s"
+    (flycheck-cancel-error-display-error-at-point-timer)
+    (when flycheck-mode
+      (-when-let (errors (flycheck-overlay-errors-at (point)))
+        (flycheck-display-errors errors)))))
+
+(defun flycheck-display-error-at-point-soon ()
+  "Display the first error message at point in minibuffer delayed."
+  (flycheck-cancel-error-display-error-at-point-timer)
+  (when (flycheck-overlays-at (point))
+    (setq flycheck-display-error-at-point-timer
+          (run-at-time flycheck-display-errors-delay nil
+                       'flycheck-display-error-at-point))))
+
+
+;;; Functions to display errors
+(defconst flycheck-error-message-buffer "*Flycheck error messages*"
+  "The name of the buffer to show long error messages in.")
+
+(defun flycheck-error-message-buffer ()
+  "Get the buffer object to show long error messages in.
+
+Get the buffer named by variable `flycheck-error-message-buffer',
+or nil if the buffer does not exist."
+  (get-buffer flycheck-error-message-buffer))
+
+(defun flycheck-may-use-echo-area-p ()
+  "Determine whether the echo area may be used.
+
+The echo area may be used if the cursor is not in the echo area,
+and if the echo area is not occupied by minibuffer input."
+  (not (or cursor-in-echo-area (active-minibuffer-window))))
+
+(defun flycheck-display-error-messages (errors)
+  "Display the messages of ERRORS.
+
+Concatenate all non-nil messages of ERRORS separated by empty
+lines, and display them with `display-message-or-buffer', which
+shows the messages either in the echo area or in a separate
+buffer, depending on the number of lines.  See Info
+node `(elisp)Displaying Messages' for more information.
+
+In the latter case, show messages in the buffer denoted by
+variable `flycheck-error-message-buffer'."
+  (when (and errors (flycheck-may-use-echo-area-p))
+    (let ((messages (seq-map #'flycheck-error-format-message-and-id errors)))
+      (display-message-or-buffer (string-join messages "\n\n")
+                                 flycheck-error-message-buffer
+                                 'not-this-window))))
+
+(defun flycheck-display-error-messages-unless-error-list (errors)
+  "Show messages of ERRORS unless the error list is visible.
+
+Like `flycheck-display-error-messages', but only if the error
+list (see `flycheck-list-errors') is not visible in any window in
+the current frame."
+  (unless (flycheck-get-error-list-window 'current-frame)
+    (flycheck-display-error-messages errors)))
+
+(defun flycheck-hide-error-buffer ()
+  "Hide the Flycheck error buffer if necessary.
+
+Hide the error buffer if there is no error under point."
+  (-when-let* ((buffer (flycheck-error-message-buffer))
+               (window (get-buffer-window buffer)))
+    (unless (flycheck-overlays-at (point))
+      ;; save-selected-window prevents `quit-window' from changing the current
+      ;; buffer (see https://github.com/flycheck/flycheck/issues/648).
+      (save-selected-window
+        (quit-window nil window)))))
+
+
+;;; Working with errors
+(defun flycheck-copy-errors-as-kill (pos &optional formatter)
+  "Copy each error at POS into kill ring, using FORMATTER.
+
+FORMATTER is a function to turn an error into a string,
+defaulting to `flycheck-error-message'.
+
+Interactively, use `flycheck-error-format-message-and-id' as
+FORMATTER with universal prefix arg, and `flycheck-error-id' with
+normal prefix arg, i.e. copy the message and the ID with
+universal prefix arg, and only the id with normal prefix arg."
+  (interactive (list (point)
+                     (pcase current-prefix-arg
+                       ((pred not) #'flycheck-error-message)
+                       ((pred consp) #'flycheck-error-format-message-and-id)
+                       (_ #'flycheck-error-id))))
+  (let ((messages (delq nil (seq-map (or formatter #'flycheck-error-message)
+                                     (flycheck-overlay-errors-at pos)))))
+    (when messages
+      (seq-do #'kill-new (reverse messages))
+      (message (string-join messages "\n")))))
+
+(defun flycheck-explain-error-at-point ()
+  "Display an explanation for the first explainable error at point.
+
+The first explainable error at point is the first error at point
+with a non-nil `:error-explainer' function defined in its
+checker.  The `:error-explainer' function is then called with
+this error to produce the explanation to display."
+  (interactive)
+  (-when-let* ((first-error
+                ;; Get the first error at point that has an `error-explainer'.
+                (seq-find (lambda (error)
+                            (flycheck-checker-get
+                             (flycheck-error-checker error) 'error-explainer))
+                          (flycheck-overlay-errors-at (point))))
+               (explainer
+                (flycheck-checker-get (flycheck-error-checker first-error)
+                                      'error-explainer))
+               (explanation (funcall explainer first-error)))
+    (flycheck-display-error-explanation explanation)))
+
+(defconst flycheck-explain-error-buffer "*Flycheck error explanation*"
+  "The name of the buffer to show error explanations.")
+
+(defun flycheck-display-error-explanation (explanation)
+  "Display the EXPLANATION string in a help buffer."
+  (with-help-window (get-buffer-create flycheck-explain-error-buffer)
+    (princ explanation)))
+
+
+;;; Syntax checkers using external commands
+(defun flycheck-command-argument-p (arg)
+  "Check whether ARG is a valid command argument."
+  (pcase arg
+    ((pred stringp) t)
+    ((or `source `source-inplace `source-original) t)
+    ((or `temporary-directory `temporary-file-name) t)
+    (`null-device t)
+    (`(config-file ,option-name ,config-file-var)
+     (and (stringp option-name)
+          (symbolp config-file-var)))
+    (`(config-file ,option-name ,config-file-var ,prepender)
+     (and (stringp option-name)
+          (symbolp config-file-var)
+          (symbolp prepender)))
+    (`(,(or `option `option-list) ,option-name ,option-var)
+     (and (stringp option-name)
+          (symbolp option-var)))
+    (`(,(or `option `option-list) ,option-name ,option-var ,prepender)
+     (and (stringp option-name)
+          (symbolp option-var)
+          (symbolp prepender)))
+    (`(,(or `option `option-list) ,option-name ,option-var ,prepender ,filter)
+     (and (stringp option-name)
+          (symbolp option-var)
+          (symbolp prepender)
+          (symbolp filter)))
+    (`(option-flag ,option-name ,option-var)
+     (and (stringp option-name)
+          (symbolp option-var)))
+    (`(eval ,_) t)
+    (_ nil)))
+
+(defun flycheck-compute-working-directory (checker)
+  "Get the default working directory for CHECKER.
+
+Compute the value of `default-directory' for the invocation of
+the syntax checker command, by calling the function in the
+`working-directory' property of CHECKER, with CHECKER as sole
+argument, and returning its value.  Signal an error if the
+function returns a non-existing working directory.
+
+If the property is undefined or if the function returns nil
+return the `default-directory' of the current buffer."
+  (let* ((def-directory-fn (flycheck-checker-get checker 'working-directory))
+         (directory (or (and def-directory-fn
+                             (funcall def-directory-fn checker))
+                        ;; Default to the `default-directory' of the current
+                        ;; buffer
+                        default-directory)))
+    (unless (file-exists-p directory)
+      (error ":working-directory %s of syntax checker %S does not exist"
+             directory checker))
+    directory))
+
+;;;###autoload
+(defun flycheck-define-command-checker (symbol docstring &rest properties)
+  "Define SYMBOL as syntax checker to run a command.
+
+Define SYMBOL as generic syntax checker via
+`flycheck-define-generic-checker', which uses an external command
+to check the buffer.  SYMBOL and DOCSTRING are the same as for
+`flycheck-define-generic-checker'.
+
+In addition to the properties understood by
+`flycheck-define-generic-checker', the following PROPERTIES
+constitute a command syntax checker.  Unless otherwise noted, all
+properties are mandatory.  Note that the default `:error-filter'
+of command checkers is `flycheck-sanitize-errors'.
+
+`:command COMMAND'
+     The command to run for syntax checking.
+
+     COMMAND is a list of the form `(EXECUTABLE [ARG ...])'.
+
+     EXECUTABLE is a string with the executable of this syntax
+     checker.  It can be overridden with the variable
+     `flycheck-SYMBOL-executable'.  Note that this variable is
+     NOT implicitly defined by this function.  Use
+     `flycheck-def-executable-var' to define this variable.
+
+     Each ARG is an argument to the executable, either as string,
+     or as special symbol or form for
+     `flycheck-substitute-argument', which see.
+
+`:error-patterns PATTERNS'
+     A list of patterns to parse the output of the `:command'.
+
+     Each ITEM in PATTERNS is a list `(LEVEL SEXP ...)', where
+     LEVEL is a Flycheck error level (see
+     `flycheck-define-error-level'), followed by one or more RX
+     `SEXP's which parse an error of that level and extract line,
+     column, file name and the message.
+
+     See `rx' for general information about RX, and
+     `flycheck-rx-to-string' for some special RX forms provided
+     by Flycheck.
+
+     All patterns are applied in the order of declaration to the
+     whole output of the syntax checker.  Output already matched
+     by a pattern will not be matched by subsequent patterns.  In
+     other words, the first pattern wins.
+
+     This property is optional.  If omitted, however, an
+     `:error-parser' is mandatory.
+
+`:error-parser FUNCTION'
+     A function to parse errors with.
+
+     The function shall accept three arguments OUTPUT CHECKER
+     BUFFER.  OUTPUT is the syntax checker output as string,
+     CHECKER the syntax checker that was used, and BUFFER a
+     buffer object representing the checked buffer.  The function
+     must return a list of `flycheck-error' objects parsed from
+     OUTPUT.
+
+     This property is optional.  If omitted, it defaults to
+     `flycheck-parse-with-patterns'.  In this case,
+     `:error-patterns' is mandatory.
+
+`:standard-input t'
+     Whether to send the buffer contents on standard input.
+
+     If this property is given and has a non-nil value, send the
+     contents of the buffer on standard input.
+
+     Defaults to nil.
+
+Note that you may not give `:start', `:interrupt', and
+`:print-doc' for a command checker.  You can give a custom
+`:verify' function, though, whose results will be appended to the
+default `:verify' function of command checkers."
+  (declare (indent 1)
+           (doc-string 2))
+  (dolist (prop '(:start :interrupt :print-doc))
+    (when (plist-get properties prop)
+      (error "%s not allowed in definition of command syntax checker %s"
+             prop symbol)))
+
+  (unless (plist-get properties :error-filter)
+    ;; Default to `flycheck-sanitize-errors' as error filter
+    (setq properties (plist-put properties :error-filter
+                                #'flycheck-sanitize-errors)))
+  (let ((verify-fn (plist-get properties :verify)))
+    (setq properties
+          (plist-put properties :verify
+                     (lambda (checker)
+                       (append (flycheck-verify-command-checker checker)
+                               (and verify-fn
+                                    (funcall verify-fn checker)))))))
+
+  (let ((command (plist-get properties :command))
+        (patterns (plist-get properties :error-patterns))
+        (parser (or (plist-get properties :error-parser)
+                    #'flycheck-parse-with-patterns))
+        (enabled (plist-get properties :enabled))
+        (standard-input (plist-get properties :standard-input)))
+    (unless command
+      (error "Missing :command in syntax checker %s" symbol))
+    (unless (stringp (car command))
+      (error "Command executable for syntax checker %s must be a string: %S"
+             symbol (car command)))
+    (dolist (arg (cdr command))
+      (unless (flycheck-command-argument-p arg)
+        (error "Invalid command argument %S in syntax checker %s" arg symbol)))
+    (when (and (eq parser 'flycheck-parse-with-patterns)
+               (not patterns))
+      (error "Missing :error-patterns in syntax checker %s" symbol))
+
+    (setq properties
+          ;; Automatically disable command checkers if the executable does not
+          ;; exist.
+          (plist-put properties :enabled
+                     (lambda ()
+                       (and (flycheck-find-checker-executable symbol)
+                            (flycheck-temp-files-writable-p symbol)
+                            (or (not enabled) (funcall enabled))))))
+
+    (apply #'flycheck-define-generic-checker symbol docstring
+           :start #'flycheck-start-command-checker
+           :interrupt #'flycheck-interrupt-command-checker
+           :print-doc #'flycheck-command-checker-print-doc
+           properties)
+
+    ;; Pre-compile all errors patterns into strings, so that we don't need to do
+    ;; that on each error parse
+    (let ((patterns (seq-map (lambda (p)
+                               (cons (flycheck-rx-to-string `(and ,@(cdr p))
+                                                            'no-group)
+                                     (car p)))
+                             patterns)))
+      (pcase-dolist (`(,prop . ,value)
+                     `((command        . ,command)
+                       (error-parser   . ,parser)
+                       (error-patterns . ,patterns)
+                       (standard-input . ,standard-input)))
+        (setf (flycheck-checker-get symbol prop) value)))))
+
+(eval-and-compile
+  ;; Make this function available during byte-compilation, since we need it
+  ;; at macro expansion of `flycheck-def-executable-var'.
+  (defun flycheck-checker-executable-variable (checker)
+    "Get the executable variable of CHECKER.
+
+The executable variable is named `flycheck-CHECKER-executable'."
+    (intern (format "flycheck-%s-executable" checker))))
+
+(defun flycheck-checker-default-executable (checker)
+  "Get the default executable of CHECKER."
+  (car (flycheck-checker-get checker 'command)))
+
+(defun flycheck-checker-executable (checker)
+  "Get the command executable of CHECKER.
+
+The executable is either the value of the variable
+`flycheck-CHECKER-executable', or the default executable given in
+the syntax checker definition, if the variable is nil."
+  (let ((var (flycheck-checker-executable-variable checker)))
+    (or (and (boundp var) (symbol-value var))
+        (flycheck-checker-default-executable checker))))
+
+(defun flycheck-find-checker-executable (checker)
+  "Get the full path of the executable of CHECKER.
+
+Return the full absolute path to the executable of CHECKER, or
+nil if the executable does not exist."
+  (funcall flycheck-executable-find (flycheck-checker-executable checker)))
+
+(defun flycheck-checker-arguments (checker)
+  "Get the command arguments of CHECKER."
+  (cdr (flycheck-checker-get checker 'command)))
+
+(defun flycheck-substitute-argument (arg checker)
+  "Substitute ARG for CHECKER.
+
+Return a list of real arguments for the executable of CHECKER,
+substituted for the symbolic argument ARG.  Single arguments,
+e.g. if ARG is a literal strings, are wrapped in a list.
+
+ARG may be one of the following forms:
+
+STRING
+     Return ARG unchanged.
+
+`source', `source-inplace'
+     Create a temporary file to check and return its path.  With
+     `source-inplace' create the temporary file in the same
+     directory as the original file.  The value of
+     `flycheck-temp-prefix' is used as prefix of the file name.
+
+     With `source', try to retain the non-directory component of
+     the buffer's file name in the temporary file.
+
+     `source' is the preferred way to pass the input file to a
+     syntax checker.  `source-inplace' should only be used if the
+     syntax checker needs other files from the source directory,
+     such as include files in C.
+
+`source-original'
+     Return the path of the actual file to check, or an empty
+     string if the buffer has no file name.
+
+     Note that the contents of the file may not be up to date
+     with the contents of the buffer to check.  Do not use this
+     as primary input to a checker, unless absolutely necessary.
+
+     When using this symbol as primary input to the syntax
+     checker, add `flycheck-buffer-saved-p' to the `:predicate'.
+
+`temporary-directory'
+     Create a unique temporary directory and return its path.
+
+`temporary-file-name'
+     Return a unique temporary filename.  The file is *not*
+     created.
+
+     To ignore the output of syntax checkers, try `null-device'
+     first.
+
+`null-device'
+     Return the value of `null-device', i.e the system null
+     device.
+
+     Use this option to ignore the output of a syntax checker.
+     If the syntax checker cannot handle the null device, or
+     won't write to an existing file, try `temporary-file-name'
+     instead.
+
+`(config-file OPTION VARIABLE [PREPEND-FN])'
+     Search the configuration file bound to VARIABLE with
+     `flycheck-locate-config-file' and return a list of arguments
+     that pass this configuration file to the syntax checker, or
+     nil if the configuration file was not found.
+
+     PREPEND-FN is called with the OPTION and the located
+     configuration file, and should return OPTION prepended
+     before the file, either a string or as list.  If omitted,
+     PREPEND-FN defaults to `list'.
+
+`(option OPTION VARIABLE [PREPEND-FN [FILTER]])'
+     Retrieve the value of VARIABLE and return a list of
+     arguments that pass this value as value for OPTION to the
+     syntax checker.
+
+     PREPEND-FN is called with the OPTION and the value of
+     VARIABLE, and should return OPTION prepended before the
+     file, either a string or as list.  If omitted, PREPEND-FN
+     defaults to `list'.
+
+     FILTER is an optional function to be applied to the value of
+     VARIABLE before prepending.  This function must return nil
+     or a string.  In the former case, return nil.  In the latter
+     case, return a list of arguments as described above.
+
+`(option-list OPTION VARIABLE [PREPEND-FN [FILTER]])'
+     Retrieve the value of VARIABLE, which must be a list,
+     and prepend OPTION before each item in this list, using
+     PREPEND-FN.
+
+     PREPEND-FN is called with the OPTION and each item of the
+     list as second argument, and should return OPTION prepended
+     before the item, either as string or as list.  If omitted,
+     PREPEND-FN defaults to `list'.
+
+     FILTER is an optional function to be applied to each item in
+     the list before prepending OPTION.  It shall return the
+     option value for each item as string, or nil, if the item is
+     to be ignored.
+
+`(option-flag OPTION VARIABLE)'
+     Retrieve the value of VARIABLE and return OPTION, if the
+     value is non-nil.  Otherwise return nil.
+
+`(eval FORM)'
+     Return the result of evaluating FORM in the buffer to be
+     checked.  FORM must either return a string or a list of
+     strings, or nil to indicate that nothing should be
+     substituted for CELL.  For all other return types, signal an
+     error
+
+     _No_ further substitutions are performed, neither in FORM
+     before it is evaluated, nor in the result of evaluating
+     FORM.
+
+In all other cases, signal an error.
+
+Note that substitution is *not* recursive.  No symbols or cells
+are substituted within the body of cells!"
+  (pcase arg
+    ((pred stringp) (list arg))
+    (`source
+     (list (flycheck-save-buffer-to-temp #'flycheck-temp-file-system)))
+    (`source-inplace
+     (list (flycheck-save-buffer-to-temp #'flycheck-temp-file-inplace)))
+    (`source-original (list (or (buffer-file-name) "")))
+    (`temporary-directory (list (flycheck-temp-dir-system)))
+    (`temporary-file-name
+     (let ((directory (flycheck-temp-dir-system)))
+       (list (make-temp-name (expand-file-name "flycheck" directory)))))
+    (`null-device (list null-device))
+    (`(config-file ,option-name ,file-name-var)
+     (-when-let* ((value (symbol-value file-name-var))
+                  (file-name (flycheck-locate-config-file value checker)))
+       (flycheck-prepend-with-option option-name (list file-name))))
+    (`(config-file ,option-name ,file-name-var ,prepend-fn)
+     (-when-let* ((value (symbol-value file-name-var))
+                  (file-name (flycheck-locate-config-file value checker)))
+       (flycheck-prepend-with-option option-name (list file-name) prepend-fn)))
+    (`(option ,option-name ,variable)
+     (-when-let (value (symbol-value variable))
+       (unless (stringp value)
+         (error "Value %S of %S for option %s is not a string"
+                value variable option-name))
+       (flycheck-prepend-with-option option-name (list value))))
+    (`(option ,option-name ,variable ,prepend-fn)
+     (-when-let (value (symbol-value variable))
+       (unless (stringp value)
+         (error "Value %S of %S for option %s is not a string"
+                value variable option-name))
+       (flycheck-prepend-with-option option-name (list value) prepend-fn)))
+    (`(option ,option-name ,variable ,prepend-fn ,filter)
+     (-when-let (value (funcall filter (symbol-value variable)))
+       (unless (stringp value)
+         (error "Value %S of %S (filter: %S) for option %s is not a string"
+                value variable filter option-name))
+       (flycheck-prepend-with-option option-name (list value) prepend-fn)))
+    (`(option-list ,option-name ,variable)
+     (let ((value (symbol-value variable)))
+       (unless (and (listp value) (seq-every-p #'stringp value))
+         (error "Value %S of %S for option %S is not a list of strings"
+                value variable option-name))
+       (flycheck-prepend-with-option option-name value)))
+    (`(option-list ,option-name ,variable ,prepend-fn)
+     (let ((value (symbol-value variable)))
+       (unless (and (listp value) (seq-every-p #'stringp value))
+         (error "Value %S of %S for option %S is not a list of strings"
+                value variable option-name))
+       (flycheck-prepend-with-option option-name value prepend-fn)))
+    (`(option-list ,option-name ,variable ,prepend-fn ,filter)
+     (let ((value (delq nil (seq-map filter (symbol-value variable)))))
+       (unless (and (listp value) (seq-every-p #'stringp value))
+         (error "Value %S of %S for option %S is not a list of strings"
+                value variable option-name))
+       (flycheck-prepend-with-option option-name value prepend-fn)))
+    (`(option-flag ,option-name ,variable)
+     (when (symbol-value variable)
+       (list option-name)))
+    (`(eval ,form)
+     (let ((result (eval form)))
+       (cond
+        ((and (listp result) (seq-every-p #'stringp result)) result)
+        ((stringp result) (list result))
+        (t (error "Invalid result from evaluation of %S: %S" form result)))))
+    (_ (error "Unsupported argument %S" arg))))
+
+(defun flycheck-checker-substituted-arguments (checker)
+  "Get the substituted arguments of a CHECKER.
+
+Substitute each argument of CHECKER using
+`flycheck-substitute-argument'.  This replaces any special
+symbols in the command."
+  (apply #'append
+         (seq-map (lambda (arg) (flycheck-substitute-argument arg checker))
+                  (flycheck-checker-arguments checker))))
+
+(defun flycheck--process-send-buffer-contents-chunked (process)
+  "Send contents of current buffer to PROCESS in small batches.
+
+Send the entire buffer to the standard input of PROCESS in chunks
+of 4096 characters.  Chunking is done in Emacs Lisp, hence this
+function is probably far less efficient than
+`send-process-region'.  Use only when required."
+  (let ((from (point-min)))
+    (while (< from (point-max))
+      (let ((to (min (+ from 4096) (point-max))))
+        (process-send-region process from to)
+        (setq from to)))))
+
+(defvar flycheck-chunked-process-input
+  ;; Chunk process output on Windows to work around
+  ;; https://github.com/flycheck/flycheck/issues/794 and
+  ;; https://debbugs.gnu.org/cgi/bugreport.cgi?bug=22344.  The presence of
+  ;; `w32-pipe-buffer-size' denotes an Emacs version (> Emacs 25.1 )where pipe
+  ;; writes on Windows are fixed.
+  ;;
+  ;; TODO: Remove option and chunking when dropping Emacs 24 support, see
+  ;; https://github.com/flycheck/flycheck/issues/856
+  (and (eq system-type 'windows-nt) (not (boundp 'w32-pipe-buffer-size)))
+  "If non-nil send process input in small chunks.
+
+If this variable is non-nil `flycheck-process-send-buffer' sends
+buffer contents in small chunks.
+
+Defaults to nil, except on Windows to work around Emacs bug
+#22344.")
+
+(defun flycheck-process-send-buffer (process)
+  "Send all contents of current buffer to PROCESS.
+
+Sends all contents of the current buffer to the standard input of
+PROCESS, and terminates standard input with EOF.
+
+If `flycheck-chunked-process-input' is non-nil, send buffer
+contents in chunks via
+`flycheck--process-send-buffer-contents-chunked', which see.
+Otherwise use `process-send-region' to send all contents at once
+and rely on Emacs' own buffering and chunking."
+  (save-restriction
+    (widen)
+    (if flycheck-chunked-process-input
+        (flycheck--process-send-buffer-contents-chunked process)
+      (process-send-region process (point-min) (point-max))))
+  (process-send-eof process))
+
+(defun flycheck-start-command-checker (checker callback)
+  "Start a command CHECKER with CALLBACK."
+  (let (process)
+    (condition-case err
+        (let* ((program (flycheck-find-checker-executable checker))
+               (args (flycheck-checker-substituted-arguments checker))
+               (command (funcall flycheck-command-wrapper-function
+                                 (cons program args)))
+               ;; Use pipes to receive output from the syntax checker.  They are
+               ;; more efficient and more robust than PTYs, which Emacs uses by
+               ;; default, and since we don't need any job control features, we
+               ;; can easily use pipes.
+               (process-connection-type nil))
+          ;; We pass do not associate the process with any buffer, by
+          ;; passing nil for the BUFFER argument of `start-process'.
+          ;; Instead, we just remember the buffer being checked in a
+          ;; process property (see below).  This neatly avoids all
+          ;; side-effects implied by attached a process to a buffer, which
+          ;; may cause conflicts with other packages.
+          ;;
+          ;; See https://github.com/flycheck/flycheck/issues/298 for an
+          ;; example for such a conflict.
+          (setq process (apply 'start-process (format "flycheck-%s" checker)
+                               nil command))
+          (setf (process-sentinel process) #'flycheck-handle-signal)
+          (setf (process-filter process) #'flycheck-receive-checker-output)
+          (set-process-query-on-exit-flag process nil)
+          ;; Remember the syntax checker, the buffer and the callback
+          (process-put process 'flycheck-checker checker)
+          (process-put process 'flycheck-callback callback)
+          (process-put process 'flycheck-buffer (current-buffer))
+          ;; The default directory is bound in the `flycheck-syntax-check-start'
+          ;; function.
+          (process-put process 'flycheck-working-directory default-directory)
+          ;; Track the temporaries created by argument substitution in the
+          ;; process itself, to get rid of the global state ASAP.
+          (process-put process 'flycheck-temporaries flycheck-temporaries)
+          (setq flycheck-temporaries nil)
+          ;; Send the buffer to the process on standard input, if enabled.
+          (when (flycheck-checker-get checker 'standard-input)
+            (flycheck-process-send-buffer process))
+          ;; Return the process.
+          process)
+      (error
+       ;; In case of error, clean up our resources, and report the error back to
+       ;; Flycheck.
+       (flycheck-safe-delete-temporaries)
+       (when process
+         ;; No need to explicitly delete the temporary files of the process,
+         ;; because deleting runs the sentinel, which will delete them anyway.
+         (delete-process process))
+       (signal (car err) (cdr err))))))
+
+(defun flycheck-interrupt-command-checker (_checker process)
+  "Interrupt a PROCESS."
+  ;; Deleting the process always triggers the sentinel, which does the cleanup
+  (when process
+    (delete-process process)))
+
+(defun flycheck-command-checker-print-doc (checker)
+  "Print additional documentation for a command CHECKER."
+  (let ((executable (flycheck-checker-default-executable checker))
+        (config-file-var (flycheck-checker-get checker 'config-file-var))
+        (option-vars (seq-sort #'string<
+                               (flycheck-checker-get checker 'option-vars))))
+    (princ "\n")
+
+    (let ((doc-start (with-current-buffer standard-output (point-max))))
+      ;; Track the start of our documentation so that we can re-indent it
+      ;; properly
+      (princ "  This syntax checker executes \"")
+      (princ executable)
+      (princ "\"")
+      (when config-file-var
+        (princ ", using a configuration file from `")
+        (princ (symbol-name config-file-var))
+        (princ "'"))
+      (princ ". The executable can be overridden with `")
+      (princ (symbol-name (flycheck-checker-executable-variable checker)))
+      (princ "'.")
+
+      (with-current-buffer standard-output
+        (save-excursion
+          (fill-region-as-paragraph doc-start (point-max)))))
+    (princ "\n")
+    (when option-vars
+      (princ
+       "\n  This syntax checker can be configured with these options:\n\n")
+      (dolist (var option-vars)
+        (princ (format "     * `%s'\n" var))))))
+
+(defun flycheck-verify-command-checker (checker)
+  "Verify a command CHECKER in the current buffer.
+
+Return a list of `flycheck-verification-result' objects for
+CHECKER."
+  (let ((executable (flycheck-find-checker-executable checker))
+        (config-file-var (flycheck-checker-get checker 'config-file-var)))
+    `(
+      ,(flycheck-verification-result-new
+        :label "executable"
+        :message (if executable (format "Found at %s" executable) "Not found")
+        :face (if executable 'success '(bold error)))
+      ,@(when config-file-var
+          (let* ((value (symbol-value config-file-var))
+                 (path (and value (flycheck-locate-config-file value checker))))
+            (list (flycheck-verification-result-new
+                   :label "configuration file"
+                   :message (if path (format "Found at %S" path) "Not found")
+                   :face (if path 'success 'warning)))))
+      ,@(when (not (flycheck-temp-files-writable-p checker))
+          (list (flycheck-verification-result-new
+                 :label "temp directory"
+                 :message (format "%s is not writable"
+                                  (flycheck-temp-directory checker))
+                 :face 'error))))))
+
+
+;;; Process management for command syntax checkers
+(defun flycheck-receive-checker-output (process output)
+  "Receive a syntax checking PROCESS OUTPUT."
+  (push output (process-get process 'flycheck-pending-output)))
+
+(defun flycheck-get-output (process)
+  "Get the complete output of PROCESS."
+  (with-demoted-errors "Error while retrieving process output: %S"
+    (let ((pending-output (process-get process 'flycheck-pending-output)))
+      (apply #'concat (nreverse pending-output)))))
+
+(defun flycheck-handle-signal (process _event)
+  "Handle a signal from the syntax checking PROCESS.
+
+_EVENT is ignored."
+  (when (memq (process-status process) '(signal exit))
+    (let ((files (process-get process 'flycheck-temporaries))
+          (buffer (process-get process 'flycheck-buffer))
+          (callback (process-get process 'flycheck-callback))
+          (cwd (process-get process 'flycheck-working-directory)))
+      ;; Delete the temporary files
+      (seq-do #'flycheck-safe-delete files)
+      (when (buffer-live-p buffer)
+        (with-current-buffer buffer
+          (condition-case err
+              (pcase (process-status process)
+                (`signal
+                 (funcall callback 'interrupted))
+                (`exit
+                 (flycheck-finish-checker-process
+                  (process-get process 'flycheck-checker)
+                  (process-exit-status process)
+                  files
+                  (flycheck-get-output process) callback cwd)))
+            ((debug error)
+             (funcall callback 'errored (error-message-string err)))))))))
+
+(defun flycheck-finish-checker-process
+    (checker exit-status files output callback cwd)
+  "Finish a checker process from CHECKER with EXIT-STATUS.
+
+FILES is a list of files given as input to the checker.  OUTPUT
+is the output of the syntax checker.  CALLBACK is the status
+callback to use for reporting.
+
+Parse the OUTPUT and report an appropriate error status.
+
+Resolve all errors in OUTPUT using CWD as working directory."
+  (let ((errors (flycheck-parse-output output checker (current-buffer))))
+    (when (and (/= exit-status 0) (not errors))
+      ;; Warn about a suspicious result from the syntax checker.  We do right
+      ;; after parsing the errors, before filtering, because a syntax checker
+      ;; might report errors from other files (e.g. includes) even if there
+      ;; are no errors in the file being checked.
+      (funcall callback 'suspicious
+               (format "Flycheck checker %S returned non-zero \
+exit code %s, but its output contained no errors: %s\nTry \
+installing a more recent version of %S, and please open a bug \
+report if the issue persists in the latest release.  Thanks!"
+                       checker exit-status output checker)))
+    (funcall callback 'finished
+             ;; Fix error file names, by substituting them backwards from the
+             ;; temporaries.
+             (seq-map (lambda (e) (flycheck-fix-error-filename e files cwd))
+                      errors))))
+
+
+;;; Executables of command checkers.
+(defmacro flycheck-def-executable-var (checker default-executable)
+  "Define the executable variable for CHECKER.
+
+DEFAULT-EXECUTABLE is the default executable.  It is only used in
+the docstring of the variable.
+
+The variable is defined with `defcustom' in the
+`flycheck-executables' group.  It's also defined to be risky as
+file-local variable, to avoid arbitrary executables being used
+for syntax checking."
+  (let ((executable-var (flycheck-checker-executable-variable checker)))
+    `(progn
+       (defcustom ,executable-var nil
+         ,(format "The executable of the %s syntax checker.
+
+Either a string containing the name or the path of the
+executable, or nil to use the default executable from the syntax
+checker declaration.
+
+The default executable is %S." checker default-executable)
+         :type '(choice (const :tag "Default executable" nil)
+                        (string :tag "Name or path"))
+         :group 'flycheck-executables
+         :risky t))))
+
+(defun flycheck-set-checker-executable (checker &optional executable)
+  "Set the executable of CHECKER in the current buffer.
+
+CHECKER is a syntax checker symbol.  EXECUTABLE is a string with
+the name of an executable or the path to an executable file, which
+is to be used as executable for CHECKER.  If omitted or nil,
+reset the executable of CHECKER.
+
+Interactively, prompt for a syntax checker and an executable
+file, and set the executable of the selected syntax checker.
+With prefix arg, prompt for a syntax checker only, and reset the
+executable of the select checker to the default.
+
+Set the executable variable of CHECKER, that is,
+`flycheck-CHECKER-executable' to EXECUTABLE.  Signal
+`user-error', if EXECUTABLE does not denote a command or an
+executable file.
+
+This command is intended for interactive use only.  In Lisp, just
+`let'-bind the corresponding variable, or set it directly.  Use
+`flycheck-checker-executable-variable' to obtain the executable
+variable symbol for a syntax checker."
+  (declare (interactive-only "Set the executable variable directly instead"))
+  (interactive
+   (let* ((checker (read-flycheck-checker "Syntax checker: "))
+          (default-executable (flycheck-checker-default-executable checker))
+          (executable (if current-prefix-arg
+                          nil
+                        (read-file-name "Executable: " nil default-executable
+                                        nil nil flycheck-executable-find))))
+     (list checker executable)))
+  (when (and executable (not (funcall flycheck-executable-find executable)))
+    (user-error "%s is no executable" executable))
+  (let ((variable (flycheck-checker-executable-variable checker)))
+    (set (make-local-variable variable) executable)))
+
+
+;;; Configuration files and options for command checkers
+(defun flycheck-register-config-file-var (var checkers)
+  "Register VAR as config file var for CHECKERS.
+
+CHECKERS is a single syntax checker or a list thereof."
+  (when (symbolp checkers)
+    (setq checkers (list checkers)))
+  (dolist (checker checkers)
+    (setf (flycheck-checker-get checker 'config-file-var) var)))
+
+;;;###autoload
+(defmacro flycheck-def-config-file-var (symbol checker &optional file-name
+                                               &rest custom-args)
+  "Define SYMBOL as config file variable for CHECKER, with default FILE-NAME.
+
+SYMBOL is declared as customizable variable using `defcustom', to
+provide a configuration file for the given syntax CHECKER.
+CUSTOM-ARGS are forwarded to `defcustom'.
+
+FILE-NAME is the initial value of the new variable.  If omitted,
+the default value is nil.
+
+Use this together with the `config-file' form in the `:command'
+argument to `flycheck-define-checker'."
+  ;; FIXME: We should allow multiple config files per checker as well as
+  ;; multiple checkers per config file
+  (declare (indent 3))
+  `(progn
+     (defcustom ,symbol ,file-name
+       ,(format "Configuration file for `%s'.
+
+If set to a string, locate the configuration file using the
+functions from `flycheck-locate-config-file-functions'.  If the
+file is found pass it to the syntax checker as configuration
+file.
+
+If no configuration file is found, or if this variable is set to
+nil, invoke the syntax checker without a configuration file.
+
+Use this variable as file-local variable if you need a specific
+configuration file a buffer." checker)
+       :type '(choice (const :tag "No configuration file" nil)
+                      (string :tag "File name or path"))
+       :group 'flycheck-config-files
+       ,@custom-args)
+     (flycheck-register-config-file-var ',symbol ',checker)))
+
+(defun flycheck-locate-config-file (filename checker)
+  "Locate the configuration file FILENAME for CHECKER.
+
+Locate the configuration file using
+`flycheck-locate-config-file-functions'.
+
+Return the absolute path of the configuration file, or nil if no
+configuration file was found."
+  (-when-let (filepath (run-hook-with-args-until-success
+                        'flycheck-locate-config-file-functions
+                        filename checker))
+    (when (file-exists-p filepath)
+      filepath)))
+
+(defun flycheck-locate-config-file-by-path (filepath _checker)
+  "Locate a configuration file by a FILEPATH.
+
+If FILEPATH is a contains a path separator, expand it against the
+default directory and return it if it points to an existing file.
+Otherwise return nil.
+
+_CHECKER is ignored."
+  ;; If the path is just a plain file name, skip it.
+  (unless (string= (file-name-nondirectory filepath) filepath)
+    (let ((file-name (expand-file-name filepath)))
+      (and (file-exists-p file-name) file-name))))
+
+(defun flycheck-locate-config-file-ancestor-directories (filename _checker)
+  "Locate a configuration FILENAME in ancestor directories.
+
+If the current buffer has a file name, search FILENAME in the
+directory of the current buffer and all ancestors thereof (see
+`locate-dominating-file').  If the file is found, return its
+absolute path.  Otherwise return nil.
+
+_CHECKER is ignored."
+  (-when-let* ((basefile (buffer-file-name))
+               (directory (locate-dominating-file basefile filename)))
+    (expand-file-name filename directory)))
+
+(defun flycheck-locate-config-file-home (filename _checker)
+  "Locate a configuration FILENAME in the home directory.
+
+Return the absolute path, if FILENAME exists in the user's home
+directory, or nil otherwise."
+  (let ((path (expand-file-name filename "~")))
+    (when (file-exists-p path)
+      path)))
+
+(seq-do (apply-partially #'custom-add-frequent-value
+                         'flycheck-locate-config-file-functions)
+        '(flycheck-locate-config-file-by-path
+          flycheck-locate-config-file-ancestor-directories
+          flycheck-locate-config-file-home))
+
+(defun flycheck-register-option-var (var checkers)
+  "Register an option VAR with CHECKERS.
+
+VAR is an option symbol, and CHECKERS a syntax checker symbol or
+a list thereof.  Register VAR with all CHECKERS so that it
+appears in the help output."
+  (when (symbolp checkers)
+    (setq checkers (list checkers)))
+  (dolist (checker checkers)
+    (cl-pushnew var (flycheck-checker-get checker 'option-vars))))
+
+;;;###autoload
+(defmacro flycheck-def-option-var (symbol init-value checkers docstring
+                                          &rest custom-args)
+  "Define SYMBOL as option variable with INIT-VALUE for CHECKER.
+
+SYMBOL is declared as customizable variable using `defcustom', to
+provide an option for the given syntax CHECKERS (a checker or a
+list of checkers).  INIT-VALUE is the initial value of the
+variable, and DOCSTRING is its docstring.  CUSTOM-ARGS are
+forwarded to `defcustom'.
+
+Use this together with the `option', `option-list' and
+`option-flag' forms in the `:command' argument to
+`flycheck-define-checker'."
+  (declare (indent 3)
+           (doc-string 4))
+  `(progn
+     (defcustom ,symbol ,init-value
+       ,(concat docstring "
+
+This variable is an option for the following syntax checkers:
+
+"
+                (mapconcat (lambda (c) (format "  - `%s'" c))
+                           (if (symbolp checkers) (list checkers) checkers)
+                           "\n"))
+       :group 'flycheck-options
+       ,@custom-args)
+     (flycheck-register-option-var ',symbol ',checkers)))
+
+(defun flycheck-option-int (value)
+  "Convert an integral option VALUE to a string.
+
+If VALUE is nil, return nil.  Otherwise return VALUE converted to
+a string."
+  (and value (number-to-string value)))
+
+(defun flycheck-option-symbol (value)
+  "Convert a symbol option VALUE to string.
+
+If VALUE is nil return nil.  Otherwise return VALUE converted to
+a string."
+  (and value (symbol-name value)))
+
+(defun flycheck-option-comma-separated-list (value &optional separator filter)
+  "Convert VALUE into a list separated by SEPARATOR.
+
+SEPARATOR is a string to separate items in VALUE, defaulting to
+\",\".  FILTER is an optional function, which takes a single
+argument and returns either a string or nil.
+
+If VALUE is a list, apply FILTER to each item in VALUE, remove
+all nil items, and return a single string of all remaining items
+separated by SEPARATOR.
+
+Otherwise, apply FILTER to VALUE and return the result.
+SEPARATOR is ignored in this case."
+  (let ((filter (or filter #'identity))
+        (separator (or separator ",")))
+    (if (listp value)
+        (-when-let (value (delq nil (seq-map filter value)))
+          (string-join value separator))
+      (funcall filter value))))
+
+(defmacro flycheck-def-args-var (symbol checkers &rest custom-args)
+  "Define SYMBOL as argument variable for CHECKERS.
+
+SYMBOL is declared as customizable, risky and buffer-local
+variable using `defcustom' to provide an option for arbitrary
+arguments for the given syntax CHECKERS (either a single checker
+or a list of checkers).  CUSTOM-ARGS is forwarded to `defcustom'.
+
+Use the `eval' form to splice this variable into the
+`:command'."
+  (declare (indent 2))
+  `(flycheck-def-option-var ,symbol nil ,checkers
+     "A list of additional command line arguments.
+
+The value of this variable is a list of strings with additional
+command line arguments."
+     :risky t
+     :type '(repeat (string :tag "Argument"))
+     ,@custom-args))
+
+
+;;; Command syntax checkers as compile commands
+(defun flycheck-checker-pattern-to-error-regexp (pattern)
+  "Convert PATTERN into an error regexp for compile.el.
+
+Return a list representing PATTERN, suitable as element in
+`compilation-error-regexp-alist'."
+  (let* ((regexp (car pattern))
+         (level (cdr pattern))
+         (level-no (flycheck-error-level-compilation-level level)))
+    (list regexp 1 2 3 level-no)))
+
+(defun flycheck-checker-compilation-error-regexp-alist (checker)
+  "Convert error patterns of CHECKER for use with compile.el.
+
+Return an alist of all error patterns of CHECKER, suitable for
+use with `compilation-error-regexp-alist'."
+  (seq-map #'flycheck-checker-pattern-to-error-regexp
+           (flycheck-checker-get checker 'error-patterns)))
+
+(defun flycheck-checker-shell-command (checker)
+  "Get a shell command for CHECKER.
+
+Perform substitution in the arguments of CHECKER, but with
+`flycheck-substitute-shell-argument'.
+
+Return the command of CHECKER as single string, suitable for
+shell execution."
+  ;; Note: Do NOT use `combine-and-quote-strings' here.  Despite it's name it
+  ;; does not properly quote shell arguments, and actually breaks for special
+  ;; characters.  See https://github.com/flycheck/flycheck/pull/522
+  (let* ((args (apply #'append
+                      (seq-map
+                       (lambda (arg)
+                         (if (memq arg '(source source-inplace source-original))
+                             (list (buffer-file-name))
+                           (flycheck-substitute-argument arg checker)))
+                       (flycheck-checker-arguments checker))))
+         (command (mapconcat
+                   #'shell-quote-argument
+                   (funcall flycheck-command-wrapper-function
+                            (cons (flycheck-checker-executable checker) args))
+                   " ")))
+    (if (flycheck-checker-get checker 'standard-input)
+        ;; If the syntax checker expects the source from standard input add an
+        ;; appropriate shell redirection
+        (concat command " < " (shell-quote-argument (buffer-file-name)))
+      command)))
+
+(defun flycheck-compile-name (_name)
+  "Get a name for a Flycheck compilation buffer.
+
+_NAME is ignored."
+  (format "*Flycheck %s*" (buffer-file-name)))
+
+(defun flycheck-compile (checker)
+  "Run CHECKER via `compile'.
+
+CHECKER must be a valid syntax checker.  Interactively, prompt
+for a syntax checker to run.
+
+Instead of highlighting errors in the buffer, this command pops
+up a separate buffer with the entire output of the syntax checker
+tool, just like `compile' (\\[compile])."
+  (interactive
+   (let ((default (flycheck-get-checker-for-buffer)))
+     (list (read-flycheck-checker "Run syntax checker as compile command: "
+                                  (when (flycheck-checker-get default 'command)
+                                    default)
+                                  'command))))
+  (unless (flycheck-valid-checker-p checker)
+    (user-error "%S is not a valid syntax checker" checker))
+  (unless (buffer-file-name)
+    (user-error "Cannot compile buffers without backing file"))
+  (unless (flycheck-may-use-checker checker)
+    (user-error "Cannot use syntax checker %S in this buffer" checker))
+  (unless (flycheck-checker-executable checker)
+    (user-error "Cannot run checker %S as shell command" checker))
+  (let* ((default-directory (flycheck-compute-working-directory checker))
+         (command (flycheck-checker-shell-command checker))
+         (buffer (compilation-start command nil #'flycheck-compile-name)))
+    (with-current-buffer buffer
+      (setq-local compilation-error-regexp-alist
+                  (flycheck-checker-compilation-error-regexp-alist checker)))))
+
+
+;;; General error parsing for command checkers
+(defun flycheck-parse-output (output checker buffer)
+  "Parse OUTPUT from CHECKER in BUFFER.
+
+OUTPUT is a string with the output from the checker symbol
+CHECKER.  BUFFER is the buffer which was checked.
+
+Return the errors parsed with the error patterns of CHECKER."
+  (funcall (flycheck-checker-get checker 'error-parser) output checker buffer))
+
+(defun flycheck-fix-error-filename (err buffer-files cwd)
+  "Fix the file name of ERR from BUFFER-FILES.
+
+Resolves error file names relative to CWD directory.
+
+Make the file name of ERR absolute.  If the absolute file name of
+ERR is in BUFFER-FILES, replace it with the return value of the
+function `buffer-file-name'."
+  (flycheck-error-with-buffer err
+    (-when-let (filename (flycheck-error-filename err))
+      (when (seq-some (apply-partially #'flycheck-same-files-p
+                                       (expand-file-name filename cwd))
+                      buffer-files)
+        (setf (flycheck-error-filename err) buffer-file-name)
+        (when (and buffer-file-name (flycheck-error-message err))
+          (setf (flycheck-error-message err)
+                (replace-regexp-in-string
+                 (regexp-quote filename) buffer-file-name
+                 (flycheck-error-message err) 'fixed-case 'literal))))))
+  err)
+
+
+;;; Error parsers for command syntax checkers
+(defun flycheck-parse-xml-region (beg end)
+  "Parse the xml region between BEG and END.
+
+Wrapper around `xml-parse-region' which transforms the return
+value of this function into one compatible to
+`libxml-parse-xml-region' by simply returning the first element
+from the node list."
+  (ignore-errors (car (xml-parse-region beg end))))
+
+(defun flycheck-parse-xml-region-with-fallback (beg end)
+  "Parse the xml region between BEG and END.
+
+Try parsing with libxml first; if that fails, revert to
+`flycheck-parse-xml-region'.  Failures can be caused by incorrect
+XML (see URL `https://github.com/flycheck/flycheck/issues/1298'),
+or on Windows by a missing libxml DLL with a libxml-enabled Emacs
+\(see URL `https://github.com/flycheck/flycheck/issues/1330')."
+  ;; FIXME use `libxml-available-p' when it gets implemented.
+  (or (and (fboundp 'libxml-parse-xml-region)
+           (libxml-parse-xml-region beg end))
+      (flycheck-parse-xml-region beg end)))
+
+(defvar flycheck-xml-parser 'flycheck-parse-xml-region-with-fallback
+  "Function used to parse an xml string from a region.
+
+The default uses libxml if available, and falls back to
+`flycheck-parse-xml-region' otherwise.")
+
+(defun flycheck-parse-xml-string (xml)
+  "Parse an XML string.
+
+Return the document tree parsed from XML in the form `(ROOT ATTRS
+BODY...)'.  ROOT is a symbol identifying the name of the root
+element.  ATTRS is an alist of the attributes of the root node.
+BODY is zero or more body elements, either as strings (in case of
+text nodes) or as XML nodes, in the same for as the root node."
+  (with-temp-buffer
+    (insert xml)
+    (funcall flycheck-xml-parser (point-min) (point-max))))
+
+(defun flycheck-parse-checkstyle (output checker buffer)
+  "Parse Checkstyle errors from OUTPUT.
+
+Parse Checkstyle-like XML output.  Use this error parser for
+checkers that have an option to output errors in this format.
+
+CHECKER and BUFFER denoted the CHECKER that returned OUTPUT and
+the BUFFER that was checked respectively.
+
+See URL `http://checkstyle.sourceforge.net/' for information
+about Checkstyle."
+  (pcase (flycheck-parse-xml-string output)
+    (`(checkstyle ,_ . ,file-nodes)
+     (let (errors)
+       (dolist (node file-nodes)
+         (pcase node
+           (`(file ,file-attrs . ,error-nodes)
+            (dolist (node error-nodes)
+              (pcase node
+                (`(error ,error-attrs . ,_)
+                 (let-alist error-attrs
+                   (push (flycheck-error-new-at
+                          (flycheck-string-to-number-safe .line)
+                          (flycheck-string-to-number-safe .column)
+                          (pcase .severity
+                            (`"error"   'error)
+                            (`"warning" 'warning)
+                            (`"info"    'info)
+                            ;; Default to error for unknown .severity
+                            (_          'error))
+                          .message
+                          :checker checker :id .source
+                          :buffer buffer
+                          :filename (cdr (assq 'name file-attrs)))
+                         errors))))))))
+       (nreverse errors)))))
+
+(defun flycheck-parse-cppcheck (output checker buffer)
+  "Parse Cppcheck errors from OUTPUT.
+
+Parse Cppcheck XML v2 output.
+
+CHECKER and BUFFER denoted the CHECKER that returned OUTPUT and
+the BUFFER that was checked respectively.
+
+See URL `http://cppcheck.sourceforge.net/' for more information
+about Cppcheck."
+  (pcase (flycheck-parse-xml-string output)
+    (`(results ,_ . ,body)
+     (let (errors)
+       (dolist (node body)
+         (pcase node
+           (`(errors ,_ . ,error-nodes)
+            (dolist (node error-nodes)
+              (pcase node
+                (`(error ,error-attrs . ,loc-nodes)
+                 (let ((id (cdr (assq 'id error-attrs)))
+                       (message (cdr (assq 'verbose error-attrs)))
+                       (level (pcase (cdr (assq 'severity error-attrs))
+                                (`"error" 'error)
+                                (`"style" 'info)
+                                (`"information" 'info)
+                                (_ 'warning))))
+                   (dolist (node loc-nodes)
+                     (pcase node
+                       (`(location ,loc-attrs . ,_)
+                        (let-alist loc-attrs
+                          (push (flycheck-error-new-at
+                                 (flycheck-string-to-number-safe .line)
+                                 nil
+                                 level
+                                 ;; cppcheck return newline characters as "\012"
+                                 (replace-regexp-in-string "\\\\012" "\n"
+                                                           message)
+                                 :id id
+                                 :checker checker
+                                 :buffer buffer
+                                 :filename .file)
+                                errors))))))))))))
+       (nreverse errors)))))
+
+(defun flycheck-parse-phpmd (output checker buffer)
+  "Parse phpmd errors from OUTPUT.
+
+CHECKER and BUFFER denoted the CHECKER that returned OUTPUT and
+the BUFFER that was checked respectively.
+
+See URL `http://phpmd.org/' for more information about phpmd."
+  (pcase (flycheck-parse-xml-string output)
+    (`(pmd ,_ . ,body)
+     (let (errors)
+       (dolist (node body)
+         (pcase node
+           (`(file ,file-attrs . ,violation-nodes)
+            (let ((filename (cdr (assq 'name file-attrs))))
+              (dolist (node violation-nodes)
+                (pcase node
+                  (`(violation ,vio-attrs ,(and message (pred stringp)))
+                   (let-alist vio-attrs
+                     (push
+                      (flycheck-error-new-at
+                       (flycheck-string-to-number-safe .beginline)
+                       nil
+                       'warning (string-trim message)
+                       :id .rule
+                       :checker checker
+                       :buffer buffer
+                       :filename filename)
+                      errors)))))))))
+       (nreverse errors)))))
+
+(defun flycheck-parse-reek (output checker buffer)
+  "Parse Reek warnings from JSON OUTPUT.
+
+CHECKER and BUFFER denote the CHECKER that returned OUTPUT and
+the BUFFER that was checked respectively.
+
+See URL `https://github.com/troessner/reek' for more information
+about Reek."
+  (let ((errors nil))
+    (dolist (message (car (flycheck-parse-json output)))
+      (let-alist message
+        (dolist (line (delete-dups .lines))
+          (push
+           (flycheck-error-new-at
+            line
+            nil
+            'warning (concat .context " " .message)
+            :id .smell_type
+            :checker checker
+            :buffer buffer
+            :filename .source)
+           errors))))
+    (nreverse errors)))
+
+(defun flycheck-parse-tslint (output checker buffer)
+  "Parse TSLint errors from JSON OUTPUT.
+
+CHECKER and BUFFER denoted the CHECKER that returned OUTPUT and
+the BUFFER that was checked respectively.
+
+See URL `https://palantir.github.io/tslint/' for more information
+about TSLint."
+  (let ((json-array-type 'list))
+    (seq-map (lambda (message)
+               (let-alist message
+                 (flycheck-error-new-at
+                  (+ 1 .startPosition.line)
+                  (+ 1 .startPosition.character)
+                  'warning .failure
+                  :id .ruleName
+                  :checker checker
+                  :buffer buffer
+                  :filename .name)))
+             ;; Don't try to parse empty output as JSON
+             (and (not (string-empty-p output))
+                  (car (flycheck-parse-json output))))))
+
+(defun flycheck-parse-rust-collect-spans (span)
+  "Return a list of spans contained in a SPAN object."
+  (let ((spans))
+    (let-alist span
+      ;; With macro expansion errors, some spans will point to phony file names
+      ;; to indicate an error inside the std rust lib.  We skip these spans as
+      ;; they won't appear in flycheck anyway.
+      (unless (string= .file_name "<std macros>")
+        (push span spans))
+
+      ;; Macro expansion errors will have a span in the 'expansion' field, so we
+      ;; recursively collect it.
+      (if .expansion.span
+          (append (flycheck-parse-rust-collect-spans .expansion.span)
+                  spans)
+        spans))))
+
+(defun flycheck-parse-rustc-diagnostic (diagnostic checker buffer)
+  "Turn a rustc DIAGNOSTIC into a `flycheck-error'.
+
+CHECKER and BUFFER denote the CHECKER that returned DIAGNOSTIC
+and the BUFFER that was checked respectively.
+
+DIAGNOSTIC should be a parsed JSON object describing a rustc
+diagnostic, following the format described there:
+
+https://github.com/rust-lang/rust/blob/master/src/libsyntax/json.rs#L67-L139"
+  (let ((error-message)
+        (error-level)
+        (error-code)
+        (primary-filename)
+        (primary-line)
+        (primary-column)
+        (group (make-symbol "group"))
+        (spans)
+        (children)
+        (errors))
+    ;; The diagnostic format is described in the link above.  The gist of it is
+    ;; that a diagnostic can have several causes in the source text; these
+    ;; causes are represented by spans.  The diagnostic has a message and a
+    ;; level (error, warning), while the spans have a filename, line, column,
+    ;; and an optional label.  The primary span points to the root cause of the
+    ;; error in the source text, while non-primary spans point to related
+    ;; causes.  Spans may have an 'expansion' field for macro expansion errors;
+    ;; these expansion fields will contain another span (and so on).  In
+    ;; addition, a diagnostic can also have children diagnostics that are used
+    ;; to provide additional information through their message field, but do not
+    ;; seem to contain any spans (yet).
+    ;;
+    ;; We first gather spans in order to turn every span into a flycheck error
+    ;; object, that we collect into the `errors' list.
+
+    ;; Nested `let-alist' cause compilation warnings, hence we `setq' all
+    ;; these values here first to avoid nesting.
+    (let-alist diagnostic
+      (setq error-message .message
+            error-level (pcase .level
+                          (`"error" 'error)
+                          (`"warning" 'warning)
+                          (`"note" 'info)
+                          (_ 'error))
+            ;; The 'code' field of the diagnostic contains the actual error
+            ;; code and an optional explanation that we ignore
+            error-code .code.code
+            ;; Collect all spans recursively
+            spans (seq-mapcat #'flycheck-parse-rust-collect-spans .spans)
+            children .children))
+
+    ;; Turn each span into a flycheck error
+    (dolist (span spans)
+      (let-alist span
+        ;; Children may not have filename/line/column information, so we use
+        ;; those from the primary span
+        (when .is_primary
+          (setq primary-filename .file_name
+                primary-line .line_start
+                primary-column .column_start))
+        (push
+         (flycheck-error-new-at
+          .line_start
+          .column_start
+          ;; Non-primary spans are used for notes
+          (if .is_primary error-level 'info)
+          (if .is_primary
+              ;; Primary spans may have labels with additional information
+              (concat error-message (when .label
+                                      (format " (%s)" .label)))
+            ;; If the label is empty, fallback on the error message,
+            ;; otherwise we won't be able to display anything
+            (or .label error-message))
+          :id error-code
+          :checker checker
+          :buffer buffer
+          :filename .file_name
+          :group group)
+         errors)))
+
+    ;; Then we turn children messages into flycheck errors pointing to the
+    ;; location of the primary span.
+    (dolist (child children)
+      (let-alist child
+        (push
+         (flycheck-error-new-at
+          ;; Use the line/column from the first span if there is one, or
+          ;; fallback to the line/column information from the primary span of
+          ;; the diagnostic.
+          (or (cdr (assq 'line_start (car .spans)))
+              primary-line)
+          (or (cdr (assq 'column_start (car .spans)))
+              primary-column)
+          'info
+          ;; Messages from `cargo clippy' may suggest replacement code.  In
+          ;; these cases, the `message' field itself is an unhelpful `try' or
+          ;; `change this to'.  We add the `suggested_replacement' field in
+          ;; these cases.
+          (-if-let (replacement
+                    (cdr (assq 'suggested_replacement (car .spans))))
+              (format "%s: `%s`" .message replacement)
+            .message)
+          :id error-code
+          :checker checker
+          :buffer buffer
+          :filename primary-filename
+          :group group)
+         errors)))
+
+    ;; If there are no spans, the error is not associated with a specific
+    ;; file but with the project as a whole.  We still need to report it to
+    ;; the user by emitting a corresponding flycheck-error object.
+    (unless spans
+      (push (flycheck-error-new-at
+             ;; We have no specific position to attach the error to, so
+             ;; let's use the top of the file.
+             1 1
+             error-level
+             error-message
+             :id error-code
+             :checker checker
+             :buffer buffer
+             :group group)
+            errors))
+    (nreverse errors)))
+
+(defun flycheck-parse-json (output)
+  "Return parsed JSON data from OUTPUT.
+
+OUTPUT is a string that contains JSON data.  Each line of OUTPUT
+may be either plain text, a JSON array (starting with `['), or a
+JSON object (starting with `{').
+
+This function ignores the plain text lines, parses the JSON
+lines, and returns the parsed JSON lines in a list."
+  (let ((objects nil)
+        (json-array-type 'list)
+        (json-false nil))
+    (with-temp-buffer
+      (insert output)
+      (goto-char (point-min))
+      (while (not (eobp))
+        (when (memq (char-after) '(?\{ ?\[))
+          (push (json-read) objects))
+        (forward-line)))
+    (nreverse objects)))
+
+(defun flycheck-parse-rustc (output checker buffer)
+  "Parse rustc errors from OUTPUT and return a list of `flycheck-error'.
+
+CHECKER and BUFFER denote the CHECKER that returned OUTPUT and
+the BUFFER that was checked respectively.
+
+The expected format for OUTPUT is a mix of plain text lines and
+JSON lines.  This function ignores the plain text lines and
+parses only JSON lines.  Each JSON line is expected to be a JSON
+object that corresponds to a diagnostic from the compiler.  The
+expected diagnostic format is described there:
+
+https://github.com/rust-lang/rust/blob/master/src/libsyntax/json.rs#L67-L139"
+  (seq-mapcat (lambda (msg)
+                (flycheck-parse-rustc-diagnostic msg checker buffer))
+              (flycheck-parse-json output)))
+
+(defun flycheck-parse-cargo-rustc (output checker buffer)
+  "Parse Cargo errors from OUTPUT and return a list of `flycheck-error'.
+
+CHECKER and BUFFER denote the CHECKER that returned OUTPUT and
+the BUFFER that was checked respectively.
+
+The expected format for OUTPUT is a mix of plain text lines and
+JSON lines.  This function ignores the plain text lines and
+parses only JSON lines.  Each JSON line is expected to be a JSON
+object that represents a message from Cargo.  The format of
+messages emitted by Cargo is described in cargo's
+machine_message.rs at URL `https://git.io/vh24R'."
+  (let ((errors))
+    (dolist (msg (flycheck-parse-json output))
+      (let-alist msg
+        ;; Errors and warnings from rustc are wrapped by cargo, so we filter and
+        ;; unwrap them, and delegate the actual construction of `flycheck-error'
+        ;; objects to `flycheck-parse-rustc-diagnostic'.
+        (when (string= .reason "compiler-message")
+          (push (flycheck-parse-rustc-diagnostic .message checker buffer)
+                errors))))
+    (apply #'nconc errors)))
+
+
+;;; Error parsing with regular expressions
+(defun flycheck-get-regexp (patterns)
+  "Create a single regular expression from PATTERNS."
+  (rx-to-string `(or ,@(seq-map (lambda (p) (list 'regexp (car p))) patterns))
+                'no-group))
+
+(defun flycheck-tokenize-output-with-patterns (output patterns)
+  "Tokenize OUTPUT with PATTERNS.
+
+Split the output into error tokens, using all regular expressions
+from the error PATTERNS.  An error token is simply a string
+containing a single error from OUTPUT.  Such a token can then be
+parsed into a structured error by applying the PATTERNS again,
+see `flycheck-parse-errors-with-patterns'.
+
+Return a list of error tokens."
+  (let ((regexp (flycheck-get-regexp patterns))
+        (last-match 0)
+        errors)
+    (while (string-match regexp output last-match)
+      (push (match-string 0 output) errors)
+      (setq last-match (match-end 0)))
+    (reverse errors)))
+
+(defun flycheck-try-parse-error-with-pattern (err pattern checker)
+  "Try to parse a single ERR with a PATTERN for CHECKER.
+
+Return the parsed error if PATTERN matched ERR, or nil
+otherwise."
+  (let ((regexp (car pattern))
+        (level (cdr pattern)))
+    (when (string-match regexp err)
+      (let ((filename (match-string 1 err))
+            (line (match-string 2 err))
+            (column (match-string 3 err))
+            (message (match-string 4 err))
+            (id (match-string 5 err)))
+        (flycheck-error-new-at
+         (flycheck-string-to-number-safe line)
+         (flycheck-string-to-number-safe column)
+         level
+         (unless (string-empty-p message) message)
+         :id (unless (string-empty-p id) id)
+         :checker checker
+         :filename (if (or (null filename) (string-empty-p filename))
+                       (buffer-file-name)
+                     filename))))))
+
+(defun flycheck-parse-error-with-patterns (err patterns checker)
+  "Parse a single ERR with error PATTERNS for CHECKER.
+
+Apply each pattern in PATTERNS to ERR, in the given order, and
+return the first parsed error."
+  ;; Try to parse patterns in the order of declaration to make sure that the
+  ;; first match wins.
+  (let (parsed-error)
+    (while (and patterns
+                (not (setq parsed-error
+                           (flycheck-try-parse-error-with-pattern
+                            err (car patterns) checker))))
+      (setq patterns (cdr patterns)))
+    parsed-error))
+
+(defun flycheck-parse-with-patterns (output checker buffer)
+  "Parse OUTPUT from CHECKER with error patterns.
+
+Uses the error patterns of CHECKER to tokenize the output and
+tries to parse each error token with all patterns, in the order
+of declaration.  Hence an error is never matched twice by two
+different patterns.  The pattern declared first always wins.
+
+_BUFFER is ignored.
+
+Return a list of parsed errors and warnings (as `flycheck-error'
+objects)."
+  (with-current-buffer buffer
+    (let ((patterns (flycheck-checker-get checker 'error-patterns)))
+      (seq-map (lambda (err)
+                 (flycheck-parse-error-with-patterns err patterns checker))
+               (flycheck-tokenize-output-with-patterns output patterns)))))
+
+
+;;; Convenience definition of command-syntax checkers
+(defmacro flycheck-define-checker (symbol docstring &rest properties)
+  "Define SYMBOL as command syntax checker with DOCSTRING and PROPERTIES.
+
+Like `flycheck-define-command-checker', but PROPERTIES must not
+be quoted.  Also, implicitly define the executable variable for
+SYMBOL with `flycheck-def-executable-var'."
+  (declare (indent 1)
+           (doc-string 2))
+  (let ((command (plist-get properties :command))
+        (parser (plist-get properties :error-parser))
+        (filter (plist-get properties :error-filter))
+        (explainer (plist-get properties :error-explainer))
+        (predicate (plist-get properties :predicate))
+        (enabled-fn (plist-get properties :enabled))
+        (verify-fn (plist-get properties :verify)))
+
+    `(progn
+       (flycheck-def-executable-var ,symbol ,(car command))
+
+       (flycheck-define-command-checker ',symbol
+         ,docstring
+         :command ',command
+         ,@(when parser
+             `(:error-parser #',parser))
+         :error-patterns ',(plist-get properties :error-patterns)
+         ,@(when filter
+             `(:error-filter #',filter))
+         ,@(when explainer
+             `(:error-explainer #',explainer))
+         :modes ',(plist-get properties :modes)
+         ,@(when predicate
+             `(:predicate #',predicate))
+         :next-checkers ',(plist-get properties :next-checkers)
+         ,@(when enabled-fn
+             `(:enabled #',enabled-fn))
+         ,@(when verify-fn
+             `(:verify #',verify-fn))
+         :standard-input ',(plist-get properties :standard-input)
+         :working-directory ',(plist-get properties :working-directory)))))
+
+
+;;; Built-in checkers
+(flycheck-def-args-var flycheck-gnat-args ada-gnat
+  :package-version '(flycheck . "0.20"))
+
+(flycheck-def-option-var flycheck-gnat-include-path nil ada-gnat
+  "A list of include directories for GNAT.
+
+The value of this variable is a list of strings, where each
+string is a directory to add to the include path of gcc.
+Relative paths are relative to the file being checked."
+  :type '(repeat (directory :tag "Include directory"))
+  :safe #'flycheck-string-list-p
+  :package-version '(flycheck . "0.20"))
+
+(flycheck-def-option-var flycheck-gnat-language-standard "2012" ada-gnat
+  "The language standard to use in GNAT.
+
+The value of this variable is either a string denoting a language
+standard, or nil, to use the default standard. When non-nil, pass
+the language standard via the `-std' option."
+  :type '(choice (const :tag "Default standard" nil)
+                 (string :tag "Language standard"))
+  :safe #'stringp
+  :package-version '(flycheck . "0.20"))
+
+(flycheck-def-option-var flycheck-gnat-warnings
+    '("wa") ada-gnat
+  "A list of additional Ada warnings to enable in GNAT.
+
+The value of this variable is a list of strings, where each
+string is the name of a warning category to enable. By default,
+most optional warnings are recommended, as in `-gnata'.
+
+Refer to Info Node `(gnat_ugn_unw)Warning Message Control' for
+more information about GNAT warnings."
+  :type '(repeat :tag "Warnings" (string :tag "Warning name"))
+  :safe #'flycheck-string-list-p
+  :package-version '(flycheck . "0.20"))
+
+(flycheck-define-checker ada-gnat
+  "An Ada syntax checker using GNAT.
+
+Uses the GNAT compiler from GCC.  See URL
+`https://www.adacore.com/community/'."
+  :command ("gnatmake"
+            "-c"                        ; Just compile, don't bind
+            "-f"                        ; Force re-compilation
+            "-u"                        ; Compile the main file only
+            "-gnatf"                    ; Full error information
+            "-gnatef"                   ; Full source file name
+            "-D" temporary-directory
+            (option-list "-gnat" flycheck-gnat-warnings concat)
+            (option-list "-I" flycheck-gnat-include-path concat)
+            (option "-gnat" flycheck-gnat-language-standard concat)
+            (eval flycheck-gnat-args)
+            source)
+  :error-patterns
+  ((error line-start
+          (message "In file included from") " " (file-name) ":" line ":"
+          column ":"
+          line-end)
+   (info line-start (file-name) ":" line ":" column
+         ": note: " (message) line-end)
+   (warning line-start (file-name) ":" line ":" column
+            ": warning: " (message) line-end)
+   ;; no specific error prefix in Ada
+   (error line-start (file-name) ":" line ":" column
+          ": " (message) line-end))
+  :modes ada-mode)
+
+(flycheck-define-checker asciidoc
+  "A AsciiDoc syntax checker using the AsciiDoc compiler.
+
+See URL `http://www.methods.co.nz/asciidoc'."
+  :command ("asciidoc" "-o" null-device "-")
+  :standard-input t
+  :error-patterns
+  ((error line-start
+          "asciidoc: ERROR: <stdin>: Line " line ": " (message)
+          line-end)
+   (warning line-start
+            "asciidoc: WARNING: <stdin>: Line " line ": " (message)
+            line-end)
+   (info line-start
+         "asciidoc: DEPRECATED: <stdin>: Line " line ": " (message)
+         line-end))
+  :modes adoc-mode)
+
+(flycheck-define-checker asciidoctor
+  "An AsciiDoc syntax checker using the Asciidoctor compiler.
+
+See URL `http://asciidoctor.org'."
+  :command ("asciidoctor" "-o" null-device "-")
+  :standard-input t
+  :error-patterns
+  ((error line-start
+          "asciidoctor: ERROR: <stdin>: Line " line ": " (message)
+          line-end)
+   (warning line-start
+            "asciidoctor: WARNING: <stdin>: Line " line ": " (message)
+            line-end))
+  :modes adoc-mode)
+
+(flycheck-def-args-var flycheck-clang-args c/c++-clang
+  :package-version '(flycheck . "0.22"))
+
+(flycheck-def-option-var flycheck-clang-blocks nil c/c++-clang
+  "Enable blocks in Clang.
+
+When non-nil, enable blocks in Clang with `-fblocks'.  See URL
+`http://clang.llvm.org/docs/BlockLanguageSpec.html' for more
+information about blocks."
+  :type 'boolean
+  :safe #'booleanp
+  :package-version '(flycheck . "0.20"))
+
+(flycheck-def-option-var flycheck-clang-definitions nil c/c++-clang
+  "Additional preprocessor definitions for Clang.
+
+The value of this variable is a list of strings, where each
+string is an additional definition to pass to Clang, via the `-D'
+option."
+  :type '(repeat (string :tag "Definition"))
+  :safe #'flycheck-string-list-p
+  :package-version '(flycheck . "0.15"))
+
+(flycheck-def-option-var flycheck-clang-include-path nil c/c++-clang
+  "A list of include directories for Clang.
+
+The value of this variable is a list of strings, where each
+string is a directory to add to the include path of Clang.
+Relative paths are relative to the file being checked."
+  :type '(repeat (directory :tag "Include directory"))
+  :safe #'flycheck-string-list-p
+  :package-version '(flycheck . "0.14"))
+
+(flycheck-def-option-var flycheck-clang-includes nil c/c++-clang
+  "A list of additional include files for Clang.
+
+The value of this variable is a list of strings, where each
+string is a file to include before syntax checking.  Relative
+paths are relative to the file being checked."
+  :type '(repeat (file :tag "Include file"))
+  :safe #'flycheck-string-list-p
+  :package-version '(flycheck . "0.15"))
+
+(flycheck-def-option-var flycheck-clang-language-standard nil c/c++-clang
+  "The language standard to use in Clang.
+
+The value of this variable is either a string denoting a language
+standard, or nil, to use the default standard.  When non-nil,
+pass the language standard via the `-std' option."
+  :type '(choice (const :tag "Default standard" nil)
+                 (string :tag "Language standard"))
+  :safe #'stringp
+  :package-version '(flycheck . "0.15"))
+(make-variable-buffer-local 'flycheck-clang-language-standard)
+
+(flycheck-def-option-var flycheck-clang-ms-extensions nil c/c++-clang
+  "Whether to enable Microsoft extensions to C/C++ in Clang.
+
+When non-nil, enable Microsoft extensions to C/C++ via
+`-fms-extensions'."
+  :type 'boolean
+  :safe #'booleanp
+  :package-version '(flycheck . "0.16"))
+
+(flycheck-def-option-var flycheck-clang-no-exceptions nil c/c++-clang
+  "Whether to disable exceptions in Clang.
+
+When non-nil, disable exceptions for syntax checks, via
+`-fno-exceptions'."
+  :type 'boolean
+  :safe #'booleanp
+  :package-version '(flycheck . "0.20"))
+
+(flycheck-def-option-var flycheck-clang-no-rtti nil c/c++-clang
+  "Whether to disable RTTI in Clang.
+
+When non-nil, disable RTTI for syntax checks, via `-fno-rtti'."
+  :type 'boolean
+  :safe #'booleanp
+  :package-version '(flycheck . "0.15"))
+
+(flycheck-def-option-var flycheck-clang-pedantic nil c/c++-clang
+  "Whether to warn about language extensions in Clang.
+
+For ISO C, follows the version specified by any -std option used.
+When non-nil, disable non-ISO extensions to C/C++ via
+`-pedantic'."
+  :type 'boolean
+  :safe #'booleanp
+  :package-version '(flycheck . "0.23"))
+
+(flycheck-def-option-var flycheck-clang-pedantic-errors nil c/c++-clang
+  "Whether to error on language extensions in Clang.
+
+For ISO C, follows the version specified by any -std option used.
+When non-nil, disable non-ISO extensions to C/C++ via
+`-pedantic-errors'."
+  :type 'boolean
+  :safe #'booleanp
+  :package-version '(flycheck . "0.23"))
+
+(flycheck-def-option-var flycheck-clang-standard-library nil c/c++-clang
+  "The standard library to use for Clang.
+
+The value of this variable is the name of a standard library as
+string, or nil to use the default standard library.
+
+Refer to the Clang manual at URL
+`http://clang.llvm.org/docs/UsersManual.html' for more
+information about the standard library."
+  :type '(choice (const "libc++")
+                 (const :tag "GNU libstdc++" "libstdc++")
+                 (string :tag "Library name"))
+  :safe #'stringp
+  :package-version '(flycheck . "0.15"))
+
+(flycheck-def-option-var flycheck-clang-warnings '("all" "extra") c/c++-clang
+  "A list of additional warnings to enable in Clang.
+
+The value of this variable is a list of strings, where each string
+is the name of a warning category to enable.  By default, all
+recommended warnings and some extra warnings are enabled (as by
+`-Wall' and `-Wextra' respectively).
+
+Refer to the Clang manual at URL
+`http://clang.llvm.org/docs/UsersManual.html' for more
+information about warnings."
+  :type '(choice (const :tag "No additional warnings" nil)
+                 (repeat :tag "Additional warnings"
+                         (string :tag "Warning name")))
+  :safe #'flycheck-string-list-p
+  :package-version '(flycheck . "0.14"))
+
+(defun flycheck-c/c++-quoted-include-directory ()
+  "Get the directory for quoted includes.
+
+C/C++ compiles typicall look up includes with quotation marks in
+the directory of the file being compiled.  However, since
+Flycheck uses temporary copies for syntax checking, it needs to
+explicitly determine the directory for quoted includes.
+
+This function determines the directory by looking at function
+`buffer-file-name', or if that is nil, at `default-directory'."
+  (-if-let (fn (buffer-file-name))
+      (file-name-directory fn)
+    ;; If the buffer has no file name, fall back to its default directory
+    default-directory))
+
+(flycheck-define-checker c/c++-clang
+  "A C/C++ syntax checker using Clang.
+
+See URL `http://clang.llvm.org/'."
+  :command ("clang"
+            "-fsyntax-only"
+            "-fno-color-diagnostics"    ; Do not include color codes in output
+            "-fno-caret-diagnostics"    ; Do not visually indicate the source
+                                        ; location
+            "-fno-diagnostics-show-option" ; Do not show the corresponding
+                                        ; warning group
+            "-iquote" (eval (flycheck-c/c++-quoted-include-directory))
+            (option "-std=" flycheck-clang-language-standard concat)
+            (option-flag "-pedantic" flycheck-clang-pedantic)
+            (option-flag "-pedantic-errors" flycheck-clang-pedantic-errors)
+            (option "-stdlib=" flycheck-clang-standard-library concat)
+            (option-flag "-fms-extensions" flycheck-clang-ms-extensions)
+            (option-flag "-fno-exceptions" flycheck-clang-no-exceptions)
+            (option-flag "-fno-rtti" flycheck-clang-no-rtti)
+            (option-flag "-fblocks" flycheck-clang-blocks)
+            (option-list "-include" flycheck-clang-includes)
+            (option-list "-W" flycheck-clang-warnings concat)
+            (option-list "-D" flycheck-clang-definitions concat)
+            (option-list "-I" flycheck-clang-include-path)
+            (eval flycheck-clang-args)
+            "-x" (eval
+                  (pcase major-mode
+                    (`c++-mode "c++")
+                    (`c-mode "c")))
+            ;; Read from standard input
+            "-")
+  :standard-input t
+  :error-patterns
+  ((error line-start
+          (message "In file included from") " " (or "<stdin>" (file-name))
+          ":" line ":" line-end)
+   (info line-start (or "<stdin>" (file-name)) ":" line ":" column
+         ": note: " (optional (message)) line-end)
+   (warning line-start (or "<stdin>" (file-name)) ":" line ":" column
+            ": warning: " (optional (message)) line-end)
+   (error line-start (or "<stdin>" (file-name)) ":" line ":" column
+          ": " (or "fatal error" "error") ": " (optional (message)) line-end))
+  :error-filter
+  (lambda (errors)
+    (let ((errors (flycheck-sanitize-errors errors)))
+      (dolist (err errors)
+        ;; Clang will output empty messages for #error/#warning pragmas without
+        ;; messages.  We fill these empty errors with a dummy message to get
+        ;; them past our error filtering
+        (setf (flycheck-error-message err)
+              (or (flycheck-error-message err) "no message")))
+      (flycheck-fold-include-levels errors "In file included from")))
+  :modes (c-mode c++-mode)
+  :next-checkers ((warning . c/c++-cppcheck)))
+
+(flycheck-def-args-var flycheck-gcc-args c/c++-gcc
+  :package-version '(flycheck . "0.22"))
+
+(flycheck-def-option-var flycheck-gcc-definitions nil c/c++-gcc
+  "Additional preprocessor definitions for GCC.
+
+The value of this variable is a list of strings, where each
+string is an additional definition to pass to GCC, via the `-D'
+option."
+  :type '(repeat (string :tag "Definition"))
+  :safe #'flycheck-string-list-p
+  :package-version '(flycheck . "0.20"))
+
+(flycheck-def-option-var flycheck-gcc-include-path nil c/c++-gcc
+  "A list of include directories for GCC.
+
+The value of this variable is a list of strings, where each
+string is a directory to add to the include path of gcc.
+Relative paths are relative to the file being checked."
+  :type '(repeat (directory :tag "Include directory"))
+  :safe #'flycheck-string-list-p
+  :package-version '(flycheck . "0.20"))
+
+(flycheck-def-option-var flycheck-gcc-includes nil c/c++-gcc
+  "A list of additional include files for GCC.
+
+The value of this variable is a list of strings, where each
+string is a file to include before syntax checking.  Relative
+paths are relative to the file being checked."
+  :type '(repeat (file :tag "Include file"))
+  :safe #'flycheck-string-list-p
+  :package-version '(flycheck . "0.20"))
+
+(flycheck-def-option-var flycheck-gcc-language-standard nil c/c++-gcc
+  "The language standard to use in GCC.
+
+The value of this variable is either a string denoting a language
+standard, or nil, to use the default standard.  When non-nil,
+pass the language standard via the `-std' option."
+  :type '(choice (const :tag "Default standard" nil)
+                 (string :tag "Language standard"))
+  :safe #'stringp
+  :package-version '(flycheck . "0.20"))
+(make-variable-buffer-local 'flycheck-gcc-language-standard)
+
+(flycheck-def-option-var flycheck-gcc-no-exceptions nil c/c++-gcc
+  "Whether to disable exceptions in GCC.
+
+When non-nil, disable exceptions for syntax checks, via
+`-fno-exceptions'."
+  :type 'boolean
+  :safe #'booleanp
+  :package-version '(flycheck . "0.20"))
+
+(flycheck-def-option-var flycheck-gcc-no-rtti nil c/c++-gcc
+  "Whether to disable RTTI in GCC.
+
+When non-nil, disable RTTI for syntax checks, via `-fno-rtti'."
+  :type 'boolean
+  :safe #'booleanp
+  :package-version '(flycheck . "0.20"))
+
+(flycheck-def-option-var flycheck-gcc-openmp nil c/c++-gcc
+  "Whether to enable OpenMP in GCC.
+
+When non-nil, enable OpenMP for syntax checkers, via
+`-fopenmp'."
+  :type 'boolean
+  :safe #'booleanp
+  :package-version '(flycheck . "0.21"))
+
+(flycheck-def-option-var flycheck-gcc-pedantic nil c/c++-gcc
+  "Whether to warn about language extensions in GCC.
+
+For ISO C, follows the version specified by any -std option used.
+When non-nil, disable non-ISO extensions to C/C++ via
+`-pedantic'."
+  :type 'boolean
+  :safe #'booleanp
+  :package-version '(flycheck . "0.23"))
+
+(flycheck-def-option-var flycheck-gcc-pedantic-errors nil c/c++-gcc
+  "Whether to error on language extensions in GCC.
+
+For ISO C, follows the version specified by any -std option used.
+When non-nil, disable non-ISO extensions to C/C++ via
+`-pedantic-errors'."
+  :type 'boolean
+  :safe #'booleanp
+  :package-version '(flycheck . "0.23"))
+
+(flycheck-def-option-var flycheck-gcc-warnings '("all" "extra") c/c++-gcc
+  "A list of additional warnings to enable in GCC.
+
+The value of this variable is a list of strings, where each string
+is the name of a warning category to enable.  By default, all
+recommended warnings and some extra warnings are enabled (as by
+`-Wall' and `-Wextra' respectively).
+
+Refer to the gcc manual at URL
+`https://gcc.gnu.org/onlinedocs/gcc/' for more information about
+warnings."
+  :type '(choice (const :tag "No additional warnings" nil)
+                 (repeat :tag "Additional warnings"
+                         (string :tag "Warning name")))
+  :safe #'flycheck-string-list-p
+  :package-version '(flycheck . "0.20"))
+
+(flycheck-define-checker c/c++-gcc
+  "A C/C++ syntax checker using GCC.
+
+Requires GCC 4.4 or newer.  See URL `https://gcc.gnu.org/'."
+  :command ("gcc"
+            "-fshow-column"
+            "-iquote" (eval (flycheck-c/c++-quoted-include-directory))
+            (option "-std=" flycheck-gcc-language-standard concat)
+            (option-flag "-pedantic" flycheck-gcc-pedantic)
+            (option-flag "-pedantic-errors" flycheck-gcc-pedantic-errors)
+            (option-flag "-fno-exceptions" flycheck-gcc-no-exceptions)
+            (option-flag "-fno-rtti" flycheck-gcc-no-rtti)
+            (option-flag "-fopenmp" flycheck-gcc-openmp)
+            (option-list "-include" flycheck-gcc-includes)
+            (option-list "-W" flycheck-gcc-warnings concat)
+            (option-list "-D" flycheck-gcc-definitions concat)
+            (option-list "-I" flycheck-gcc-include-path)
+            (eval flycheck-gcc-args)
+            "-x" (eval
+                  (pcase major-mode
+                    (`c++-mode "c++")
+                    (`c-mode "c")))
+            ;; GCC performs full checking only when actually compiling, so
+            ;; `-fsyntax-only' is not enough. Just let it generate assembly
+            ;; code.
+            "-S" "-o" null-device
+            ;; Read from standard input
+            "-")
+  :standard-input t
+  :error-patterns
+  ((error line-start
+          (message "In file included from") " " (or "<stdin>" (file-name))
+          ":" line ":" column ":" line-end)
+   (info line-start (or "<stdin>" (file-name)) ":" line ":" column
+         ": note: " (message) line-end)
+   (warning line-start (or "<stdin>" (file-name)) ":" line ":" column
+            ": warning: " (message (one-or-more (not (any "\n["))))
+            (optional "[" (id (one-or-more not-newline)) "]") line-end)
+   (error line-start (or "<stdin>" (file-name)) ":" line ":" column
+          ": " (or "fatal error" "error") ": " (message) line-end))
+  :error-filter
+  (lambda (errors)
+    (flycheck-fold-include-levels (flycheck-sanitize-errors errors)
+                                  "In file included from"))
+  :modes (c-mode c++-mode)
+  :next-checkers ((warning . c/c++-cppcheck)))
+
+(flycheck-def-option-var flycheck-cppcheck-checks '("style") c/c++-cppcheck
+  "Enabled checks for Cppcheck.
+
+The value of this variable is a list of strings, where each
+string is the name of an additional check to enable.  By default,
+all coding style checks are enabled.
+
+See section \"Enable message\" in the Cppcheck manual at URL
+`http://cppcheck.sourceforge.net/manual.pdf', and the
+documentation of the `--enable' option for more information,
+including a list of supported checks."
+  :type '(repeat :tag "Additional checks"
+                 (string :tag "Check name"))
+  :safe #'flycheck-string-list-p
+  :package-version '(flycheck . "0.14"))
+
+(flycheck-def-option-var flycheck-cppcheck-standards nil c/c++-cppcheck
+  "The standards to use in cppcheck.
+
+The value of this variable is either a list of strings denoting
+the standards to use, or nil to pass nothing to cppcheck.  When
+non-nil, pass the standards via one or more `--std=' options."
+  :type '(choice (const :tag "Default" nil)
+                 (repeat :tag "Custom standards"
+                         (string :tag "Standard name")))
+  :safe #'flycheck-string-list-p
+  :package-version '(flycheck . "28"))
+(make-variable-buffer-local 'flycheck-cppcheck-standards)
+
+(flycheck-def-option-var flycheck-cppcheck-suppressions-file nil c/c++-cppcheck
+  "The suppressions file to use in cppcheck.
+
+The value of this variable is a file with the suppressions to
+use, or nil to pass nothing to cppcheck.  When non-nil, pass the
+suppressions file via the `--suppressions-list=' option."
+  :type '(choice (const :tag "Default" nil)
+                 (file :tag "Suppressions file"))
+  :safe #'stringp
+  :package-version '(flycheck . "32"))
+(make-variable-buffer-local 'flycheck-cppcheck-suppressions-file)
+
+(flycheck-def-option-var flycheck-cppcheck-suppressions nil c/c++-cppcheck
+  "The suppressions to use in cppcheck.
+
+The value of this variable is either a list of strings denoting
+the suppressions to use, or nil to pass nothing to cppcheck.
+When non-nil, pass the suppressions via one or more `--suppress='
+options."
+  :type '(choice (const :tag "Default" nil)
+                 (repeat :tag "Additional suppressions"
+                         (string :tag "Suppression")))
+  :safe #'flycheck-string-list-p
+  :package-version '(flycheck . "28"))
+
+(flycheck-def-option-var flycheck-cppcheck-inconclusive nil c/c++-cppcheck
+  "Whether to enable Cppcheck inconclusive checks.
+
+When non-nil, enable Cppcheck inconclusive checks.  This allows Cppcheck to
+report warnings it's not certain of, but it may result in false positives.
+
+This will have no effect when using Cppcheck 1.53 and older."
+  :type 'boolean
+  :safe #'booleanp
+  :package-version '(flycheck . "0.19"))
+
+(flycheck-def-option-var flycheck-cppcheck-include-path nil c/c++-cppcheck
+  "A list of include directories for cppcheck.
+
+The value of this variable is a list of strings, where each
+string is a directory to add to the include path of cppcheck.
+Relative paths are relative to the file being checked."
+  :type '(repeat (directory :tag "Include directory"))
+  :safe #'flycheck-string-list-p
+  :package-version '(flycheck . "0.24"))
+
+(flycheck-define-checker c/c++-cppcheck
+  "A C/C++ checker using cppcheck.
+
+See URL `http://cppcheck.sourceforge.net/'."
+  :command ("cppcheck" "--quiet" "--xml-version=2" "--inline-suppr"
+            (option "--enable=" flycheck-cppcheck-checks concat
+                    flycheck-option-comma-separated-list)
+            (option-flag "--inconclusive" flycheck-cppcheck-inconclusive)
+            (option-list "-I" flycheck-cppcheck-include-path)
+            (option-list "--std=" flycheck-cppcheck-standards concat)
+            (option-list "--suppress=" flycheck-cppcheck-suppressions concat)
+            (option "--suppressions-list="
+                    flycheck-cppcheck-suppressions-file concat)
+            "-x" (eval
+                  (pcase major-mode
+                    (`c++-mode "c++")
+                    (`c-mode "c")))
+            source)
+  :error-parser flycheck-parse-cppcheck
+  :modes (c-mode c++-mode))
+
+(flycheck-define-checker cfengine
+  "A CFEngine syntax checker using cf-promises.
+
+See URL `https://cfengine.com/'."
+  :command ("cf-promises" "-Wall" "-f"
+            ;; We must stay in the same directory to resolve @include
+            source-inplace)
+  :error-patterns
+  ((warning line-start (file-name) ":" line ":" column
+            ": warning: " (message) line-end)
+   (error line-start (file-name) ":" line ":" column
+          ": error: " (message) line-end))
+  :modes (cfengine-mode cfengine3-mode))
+
+(flycheck-def-option-var flycheck-foodcritic-tags nil chef-foodcritic
+  "A list of tags to select for Foodcritic.
+
+The value of this variable is a list of strings where each string
+is a tag expression describing Foodcritic rules to enable or
+disable, via the `--tags' option.  To disable a tag, prefix it
+with `~'."
+  :type '(repeat :tag "Tags" (string :tag "Tag expression"))
+  :safe #'flycheck-string-list-p
+  :package-version '(flycheck . "0.23"))
+
+(flycheck-define-checker chef-foodcritic
+  "A Chef cookbooks syntax checker using Foodcritic.
+
+See URL `http://www.foodcritic.io'."
+  ;; Use `source-inplace' to allow resource discovery with relative paths.
+  ;; foodcritic interprets these as relative to the source file, so we need to
+  ;; stay within the source tree.  See
+  ;; https://github.com/flycheck/flycheck/pull/556
+  :command ("foodcritic"
+            (option-list "--tags" flycheck-foodcritic-tags)
+            source-inplace)
+  :error-patterns
+  ((error line-start (id (one-or-more alnum)) ": "
+          (message) ": " (file-name) ":" line line-end))
+  :modes (enh-ruby-mode ruby-mode)
+  :predicate
+  (lambda ()
+    (let ((parent-dir (file-name-directory
+                       (directory-file-name
+                        (expand-file-name default-directory)))))
+      (or
+       ;; Chef CookBook
+       ;; http://docs.opscode.com/chef/knife.html#id38
+       (locate-dominating-file parent-dir "recipes")
+       ;; Knife Solo
+       ;; http://matschaffer.github.io/knife-solo/#label-Init+command
+       (locate-dominating-file parent-dir "cookbooks")))))
+
+(flycheck-define-checker coffee
+  "A CoffeeScript syntax checker using coffee.
+
+See URL `https://coffeescript.org/'."
+  ;; --print suppresses generation of compiled .js files
+  :command ("coffee" "--compile" "--print" "--stdio")
+  :standard-input t
+  :error-patterns
+  ((error line-start "[stdin]:" line ":" column
+          ": error: " (message) line-end))
+  :modes coffee-mode
+  :next-checkers ((warning . coffee-coffeelint)))
+
+(flycheck-def-config-file-var flycheck-coffeelintrc coffee-coffeelint
+                              ".coffeelint.json"
+  :safe #'stringp)
+
+(flycheck-define-checker coffee-coffeelint
+  "A CoffeeScript style checker using coffeelint.
+
+See URL `http://www.coffeelint.org/'."
+  :command
+  ("coffeelint"
+   (config-file "--file" flycheck-coffeelintrc)
+   "--stdin" "--reporter" "checkstyle")
+  :standard-input t
+  :error-parser flycheck-parse-checkstyle
+  :error-filter (lambda (errors)
+                  (flycheck-remove-error-file-names
+                   "stdin" (flycheck-remove-error-ids
+                            (flycheck-sanitize-errors errors))))
+  :modes coffee-mode)
+
+(flycheck-define-checker coq
+  "A Coq syntax checker using the Coq compiler.
+
+See URL `https://coq.inria.fr/'."
+  ;; We use coqtop in batch mode, because coqc is picky about file names.
+  :command ("coqtop" "-batch" "-load-vernac-source" source)
+  :error-patterns
+  ((error line-start "File \"" (file-name) "\", line " line
+          ;; TODO: Parse the end column, once Flycheck supports that
+          ", characters " column "-" (one-or-more digit) ":\n"
+          (or "Syntax error:" "Error:")
+          ;; Most Coq error messages span multiple lines, and end with a dot.
+          ;; There are simple one-line messages, too, though.
+          (message (or (and (one-or-more (or not-newline "\n")) ".")
+                       (one-or-more not-newline)))
+          line-end))
+  :error-filter
+  (lambda (errors)
+    (dolist (err (flycheck-sanitize-errors errors))
+      (setf (flycheck-error-message err)
+            (replace-regexp-in-string (rx (1+ (syntax whitespace)) line-end)
+                                      "" (flycheck-error-message err)
+                                      'fixedcase 'literal)))
+    (flycheck-increment-error-columns errors))
+  :modes coq-mode)
+
+(flycheck-define-checker css-csslint
+  "A CSS syntax and style checker using csslint.
+
+See URL `https://github.com/CSSLint/csslint'."
+  :command ("csslint" "--format=checkstyle-xml" source)
+  :error-parser flycheck-parse-checkstyle
+  :error-filter flycheck-dequalify-error-ids
+  :modes css-mode)
+
+(defconst flycheck-stylelint-args '("--formatter" "json")
+  "Common arguments to stylelint invocations.")
+
+(flycheck-def-config-file-var flycheck-stylelintrc
+    (css-stylelint scss-stylelint less-stylelint) nil
+  :safe #'stringp)
+
+(flycheck-def-option-var flycheck-stylelint-quiet
+    nil (css-stylelint scss-stylelint less-stylelint)
+  "Whether to run stylelint in quiet mode.
+
+When non-nil, enable quiet mode, via `--quiet'."
+  :type 'boolean
+  :safe #'booleanp
+  :package-version '(flycheck . 26))
+
+(defconst flycheck-stylelint-error-re
+  (flycheck-rx-to-string
+   '(: line-start (id (one-or-more word)) ": " (message) line-end)))
+
+(defun flycheck-parse-stylelint (output checker buffer)
+  "Parse stylelint errors from OUTPUT.
+
+CHECKER and BUFFER denoted the CHECKER that returned OUTPUT and
+the BUFFER that was checked respectively.
+
+The CHECKER usually returns the errors as JSON.
+
+If the CHECKER throws an Error it returns an Error message with a stacktrace."
+  (condition-case nil
+      (flycheck-parse-stylelint-json output checker buffer)
+
+    ;; The output could not be parsed as JSON
+    (json-error
+
+     ;; Extract a flycheck error from the output (with a regular expression)
+     ;; For match-string 4/5 see flycheck-rx-message/flycheck-rx-id
+     (when (string-match flycheck-stylelint-error-re output)
+       (list (flycheck-error-new-at
+              1 nil 'error
+              (match-string 4 output)
+              :id (match-string 5 output)
+              :checker checker
+              :buffer buffer
+              :filename (buffer-file-name buffer)))))))
+
+(defun flycheck-parse-stylelint-json (output checker buffer)
+  "Parse stylelint JSON errors from OUTPUT.
+
+CHECKER and BUFFER denoted the CHECKER that returned OUTPUT and
+the BUFFER that was checked respectively.
+
+See URL `http://stylelint.io/developer-guide/formatters/' for information
+about the JSON format of stylelint."
+  (let ((json-object-type 'plist))
+
+    ;; stylelint returns a vector of result objects
+    ;; Since we only passed one file, the first element is enough
+    (let* ((stylelint-output (elt (json-read-from-string output) 0))
+           (filename (buffer-file-name buffer))
+
+           ;; Turn all deprecations into warnings
+           (deprecations
+            (mapcar (lambda (d)
+                      (flycheck-error-new-at
+                       1 nil 'warning
+                       (plist-get d :text)
+                       :id "Deprecation Warning"
+                       :checker checker
+                       :buffer buffer
+                       :filename filename))
+                    (plist-get stylelint-output :deprecations)))
+
+           ;; Turn all invalid options into errors
+           (invalid-options
+            (mapcar (lambda (io)
+                      (flycheck-error-new-at
+                       1 nil 'error
+                       (plist-get io :text)
+                       :id "Invalid Option"
+                       :checker checker
+                       :buffer buffer
+                       :filename filename))
+                    (plist-get stylelint-output :invalidOptionWarnings)))
+
+           ;; Read all linting warnings
+           (warnings
+            (mapcar (lambda (w)
+                      (flycheck-error-new-at
+                       (plist-get w :line) (plist-get w :column)
+                       (pcase (plist-get w :severity)
+                         (`"error"   'error)
+                         (`"warning" 'warning)
+                         ;; Default to info for unknown .severity
+                         (_          'info))
+                       (plist-get w :text)
+                       :id (plist-get w :rule)
+                       :checker checker
+                       :buffer buffer
+                       :filename filename))
+                    (plist-get stylelint-output :warnings))))
+
+      ;; Return the combined errors (deprecations, invalid options, warnings)
+      (append deprecations invalid-options warnings))))
+
+(flycheck-define-checker css-stylelint
+  "A CSS syntax and style checker using stylelint.
+
+See URL `http://stylelint.io/'."
+  :command ("stylelint"
+            (eval flycheck-stylelint-args)
+            (option-flag "--quiet" flycheck-stylelint-quiet)
+            (config-file "--config" flycheck-stylelintrc))
+  :standard-input t
+  :error-parser flycheck-parse-stylelint
+  :modes (css-mode))
+
+(flycheck-def-option-var flycheck-cwl-schema-path nil cwl
+  "A path for the schema file for Common Workflow Language.
+
+The value of this variable is a string that denotes a path for
+the schema file of Common Workflow Language."
+  :type 'string
+  :safe #'stringp)
+
+(flycheck-define-checker cwl
+  "A CWL syntax checker using Schema Salad validator.
+
+Requires Schema Salad 2.6.20171101113912 or newer.
+See URL `https://www.commonwl.org/v1.0/SchemaSalad.html'."
+  :command ("schema-salad-tool"
+            "--quiet"
+            "--print-oneline"
+            (eval flycheck-cwl-schema-path)
+            source-inplace)
+  :error-patterns
+  ((error line-start
+          (file-name) ":" line ":" column ":" (zero-or-more blank)
+          (message (one-or-more not-newline))
+          line-end))
+  :modes cwl-mode)
+
+(defconst flycheck-d-module-re
+  (rx "module" (one-or-more (syntax whitespace))
+      (group (one-or-more (not (syntax whitespace))))
+      (zero-or-more (syntax whitespace))
+      ";")
+  "Regular expression to match a D module declaration.")
+
+(defun flycheck-d-base-directory ()
+  "Get the relative base directory path for this module."
+  (let* ((file-name (buffer-file-name))
+         (module-file (if (string= (file-name-nondirectory file-name)
+                                   "package.d")
+                          (directory-file-name (file-name-directory file-name))
+                        file-name)))
+    (flycheck-module-root-directory
+     (flycheck-find-in-buffer flycheck-d-module-re)
+     module-file)))
+
+(flycheck-def-option-var flycheck-dmd-include-path nil d-dmd
+  "A list of include directories for dmd.
+
+The value of this variable is a list of strings, where each
+string is a directory to add to the include path of dmd.
+Relative paths are relative to the file being checked."
+  :type '(repeat (directory :tag "Include directory"))
+  :safe #'flycheck-string-list-p
+  :package-version '(flycheck . "0.18"))
+
+(flycheck-def-args-var flycheck-dmd-args d-dmd
+  :package-version '(flycheck . "0.24"))
+
+(flycheck-define-checker d-dmd
+  "A D syntax checker using the DMD compiler.
+
+Requires DMD 2.066 or newer.  See URL `https://dlang.org/'."
+  :command ("dmd"
+            "-debug"                    ; Compile in debug mode
+            "-o-"                       ; Don't generate an object file
+            "-vcolumns"                 ; Add columns in output
+            "-wi" ; Compilation will continue even if there are warnings
+            (eval (concat "-I" (flycheck-d-base-directory)))
+            (option-list "-I" flycheck-dmd-include-path concat)
+            (eval flycheck-dmd-args)
+            source)
+  :error-patterns
+  ((error line-start
+          (file-name) "(" line "," column "): Error: " (message)
+          line-end)
+   (warning line-start (file-name) "(" line "," column "): "
+            (or "Warning" "Deprecation") ": " (message) line-end)
+   (info line-start (file-name) "(" line "," column "): "
+         (one-or-more " ") (message) line-end))
+  :modes d-mode)
+
+(flycheck-define-checker dockerfile-hadolint
+  "A Dockerfile syntax checker using the hadolint.
+
+See URL `http://github.com/hadolint/hadolint/'."
+  :command ("hadolint" "-")
+  :standard-input t
+  :error-patterns
+  ((error line-start
+          (file-name) ":" line ":" column " " (message)
+          line-end)
+   (warning line-start
+            (file-name) ":" line " " (id (one-or-more alnum)) " " (message)
+            line-end))
+  :error-filter
+  (lambda (errors)
+    (flycheck-sanitize-errors
+     (flycheck-remove-error-file-names "/dev/stdin" errors)))
+  :modes dockerfile-mode)
+
+(defconst flycheck-this-emacs-executable
+  (concat invocation-directory invocation-name)
+  "The path to the currently running Emacs executable.")
+
+(defconst flycheck-emacs-args '("-Q" "--batch")
+  "Common arguments to Emacs invocations.")
+
+(defmacro flycheck-prepare-emacs-lisp-form (&rest body)
+  "Prepare BODY for use as check form in a subprocess."
+  (declare (indent 0))
+  `(flycheck-sexp-to-string
+    '(progn
+       (defvar jka-compr-inhibit)
+       (unwind-protect
+           ;; Flycheck inhibits compression of temporary files, thus we
+           ;; must not attempt to decompress.
+           (let ((jka-compr-inhibit t))
+             ;; Strip option-argument separator from arguments, if present
+             (when (equal (car command-line-args-left) "--")
+               (setq command-line-args-left (cdr command-line-args-left)))
+             ,@body)
+         ;; Prevent Emacs from processing the arguments on its own, see
+         ;; https://github.com/flycheck/flycheck/issues/319
+         (setq command-line-args-left nil)))))
+
+(defconst flycheck-emacs-lisp-check-form
+  (flycheck-prepare-emacs-lisp-form
+    ;; Keep track of the generated bytecode files, to delete them after byte
+    ;; compilation.
+    (defvar flycheck-byte-compiled-files nil)
+    (let ((byte-compile-dest-file-function
+           (lambda (source)
+             (let ((temp-file (make-temp-file (file-name-nondirectory source))))
+               (push temp-file flycheck-byte-compiled-files)
+               temp-file))))
+      (unwind-protect
+          (byte-compile-file (car command-line-args-left))
+        (mapc (lambda (f) (ignore-errors (delete-file f)))
+              flycheck-byte-compiled-files))
+      (when (bound-and-true-p flycheck-emacs-lisp-check-declare)
+        (check-declare-file (car command-line-args-left))))))
+
+(flycheck-def-option-var flycheck-emacs-lisp-load-path nil emacs-lisp
+  "Load path to use in the Emacs Lisp syntax checker.
+
+When set to `inherit', use the `load-path' of the current Emacs
+session during syntax checking.
+
+When set to a list of strings, add each directory in this list to
+the `load-path' before invoking the byte compiler.  Relative
+paths in this list are expanded against the `default-directory'
+of the buffer to check.
+
+When nil, do not explicitly set the `load-path' during syntax
+checking.  The syntax check only uses the built-in `load-path' of
+Emacs in this case.
+
+Note that changing this variable can lead to wrong results of the
+syntax check, e.g. if an unexpected version of a required library
+is used."
+  :type '(choice (const :tag "Inherit current `load-path'" inherit)
+                 (repeat :tag "Load path" directory))
+  :risky t
+  :package-version '(flycheck . "0.14"))
+
+(flycheck-def-option-var flycheck-emacs-lisp-initialize-packages
+    'auto emacs-lisp
+  "Whether to initialize packages in the Emacs Lisp syntax checker.
+
+When nil, never initialize packages.  When `auto', initialize
+packages only when checking `user-init-file' or files from
+`user-emacs-directory'.  For any other non-nil value, always
+initialize packages.
+
+When initializing packages is enabled the `emacs-lisp' syntax
+checker calls `package-initialize' before byte-compiling the file
+to be checked.  It also sets `package-user-dir' according to
+`flycheck-emacs-lisp-package-user-dir'."
+  :type '(choice (const :tag "Do not initialize packages" nil)
+                 (const :tag "Initialize packages for configuration only" auto)
+                 (const :tag "Always initialize packages" t))
+  :risky t
+  :package-version '(flycheck . "0.14"))
+
+(defconst flycheck-emacs-lisp-package-initialize-form
+  (flycheck-sexp-to-string
+   '(with-demoted-errors "Error during package initialization: %S"
+      (package-initialize)))
+  "Form used to initialize packages.")
+
+(defun flycheck-option-emacs-lisp-package-initialize (value)
+  "Option VALUE filter for `flycheck-emacs-lisp-initialize-packages'."
+  (let ((shall-initialize
+         (if (eq value 'auto)
+             (or (flycheck-in-user-emacs-directory-p (buffer-file-name))
+                 ;; `user-init-file' is nil in non-interactive sessions.  Now,
+                 ;; no user would possibly use Flycheck in a non-interactive
+                 ;; session, but our unit tests run non-interactively, so we
+                 ;; have to handle this case anyway
+                 (and user-init-file
+                      (flycheck-same-files-p (buffer-file-name)
+                                             user-init-file)))
+           value)))
+    (when shall-initialize
+      ;; If packages shall be initialized, return the corresponding form,
+      ;; otherwise make Flycheck ignore the option by returning nil.
+      flycheck-emacs-lisp-package-initialize-form)))
+
+(flycheck-def-option-var flycheck-emacs-lisp-package-user-dir nil emacs-lisp
+  "Package directory for the Emacs Lisp syntax checker.
+
+If set to a string set `package-user-dir' to the value of this
+variable before initializing packages. If set to nil just inherit
+the value of `package-user-dir' from the running Emacs session.
+
+This variable has no effect, if
+`flycheck-emacs-lisp-initialize-packages' is nil."
+  :type '(choice (const :tag "Default package directory" nil)
+                 (directory :tag "Custom package directory"))
+  :risky t
+  :package-version '(flycheck . "0.14"))
+
+(defun flycheck-option-emacs-lisp-package-user-dir (value)
+  "Option VALUE filter for `flycheck-emacs-lisp-package-user-dir'."
+  ;; Inherit the package directory from our Emacs session
+  (let ((value (or value (bound-and-true-p package-user-dir))))
+    (when value
+      (flycheck-sexp-to-string `(setq package-user-dir ,value)))))
+
+(flycheck-def-option-var flycheck-emacs-lisp-check-declare nil emacs-lisp
+  "If non-nil, check ‘declare-function’ forms using ‘check-declare-file’."
+  :type '(choice (const :tag "Do not check declare forms" nil)
+                 (const :tag "Check declare forms" t))
+  :risky t
+  :package-version '(flycheck . "31"))
+
+(defun flycheck-option-emacs-lisp-check-declare (value)
+  "Option VALUE filter for `flycheck-emacs-lisp-check-declare'."
+  (when value
+    (flycheck-sexp-to-string
+     `(progn
+        (defvar flycheck-emacs-lisp-check-declare)
+        (setq flycheck-emacs-lisp-check-declare ,value)))))
+
+(flycheck-define-checker emacs-lisp
+  "An Emacs Lisp syntax checker using the Emacs Lisp Byte compiler.
+
+See Info Node `(elisp)Byte Compilation'."
+  :command ("emacs" (eval flycheck-emacs-args)
+            (eval
+             (let ((path (pcase flycheck-emacs-lisp-load-path
+                           (`inherit load-path)
+                           (p (seq-map #'expand-file-name p)))))
+               (flycheck-prepend-with-option "--directory" path)))
+            (option "--eval" flycheck-emacs-lisp-package-user-dir nil
+                    flycheck-option-emacs-lisp-package-user-dir)
+            (option "--eval" flycheck-emacs-lisp-initialize-packages nil
+                    flycheck-option-emacs-lisp-package-initialize)
+            (option "--eval" flycheck-emacs-lisp-check-declare nil
+                    flycheck-option-emacs-lisp-check-declare)
+            "--eval" (eval flycheck-emacs-lisp-check-form)
+            "--"
+            source-inplace)
+  :error-patterns
+  ((error line-start (file-name) ":" line ":" column ":Error:"
+          (message (zero-or-more not-newline)
+                   (zero-or-more "\n    " (zero-or-more not-newline)))
+          line-end)
+   (warning line-start (file-name) ":" line ":" column ":Warning:"
+            (message (zero-or-more not-newline)
+                     (zero-or-more "\n    " (zero-or-more not-newline)))
+            line-end)
+   (warning line-start (file-name) ":" line (optional ":" column)
+            ":Warning (check-declare): said\n"
+            (message (zero-or-more "    " (zero-or-more not-newline))
+                     (zero-or-more "\n    " (zero-or-more not-newline)))
+            line-end)
+   ;; The following is for Emacs 24 ‘check-declare-file’, which uses a
+   ;; less informative format.
+   (warning line-start "Warning (check-declare): " (file-name) " said "
+            (message (zero-or-more not-newline))
+            line-end))
+  :error-filter
+  (lambda (errors)
+    (flycheck-fill-empty-line-numbers
+     (flycheck-collapse-error-message-whitespace
+      (flycheck-sanitize-errors errors))))
+  :modes (emacs-lisp-mode lisp-interaction-mode)
+  :predicate
+  (lambda ()
+    (and
+     ;; Ensure that we only check buffers with a backing file.  For buffers
+     ;; without a backing file we cannot guarantee that file names in error
+     ;; messages are properly resolved, because `byte-compile-file' emits file
+     ;; names *relative to the directory of the checked file* instead of the
+     ;; working directory.  Hence our backwards-substitution will fail, because
+     ;; the checker process has a different base directory to resolve relative
+     ;; file names than the Flycheck code working on the buffer to check.
+     (buffer-file-name)
+     ;; Do not check buffers which should not be byte-compiled.  The checker
+     ;; process will refuse to compile these, which would confuse Flycheck
+     (not (bound-and-true-p no-byte-compile))
+     ;; Do not check buffers used for autoloads generation during package
+     ;; installation.  These buffers are too short-lived for being checked, and
+     ;; doing so causes spurious errors.  See
+     ;; https://github.com/flycheck/flycheck/issues/45 and
+     ;; https://github.com/bbatsov/prelude/issues/248.  We must also not check
+     ;; compilation buffers, but as these are ephemeral, Flycheck won't check
+     ;; them anyway.
+     (not (flycheck-autoloads-file-p))))
+  :next-checkers (emacs-lisp-checkdoc))
+
+(defconst flycheck-emacs-lisp-checkdoc-form
+  (flycheck-prepare-emacs-lisp-form
+    (unless (require 'elisp-mode nil 'no-error)
+      ;; TODO: Fallback for Emacs 24, remove when dropping support for 24
+      (require 'lisp-mode))
+    (require 'checkdoc)
+
+    (let ((source (car command-line-args-left))
+          ;; Remember the default directory of the process
+          (process-default-directory default-directory))
+      ;; Note that we deliberately use our custom approach even despite of
+      ;; `checkdoc-file' which was added to Emacs 25.1.  While it's conceptually
+      ;; the better thing, its implementation has too many flaws to be of use
+      ;; for us.
+      (with-temp-buffer
+        (insert-file-contents source 'visit)
+        (setq buffer-file-name source)
+        ;; And change back to the process default directory to make file-name
+        ;; back-substutition work
+        (setq default-directory process-default-directory)
+        (with-demoted-errors "Error in checkdoc: %S"
+          ;; Checkdoc needs the Emacs Lisp syntax table and comment syntax to
+          ;; parse sexps and identify docstrings correctly; see
+          ;; https://github.com/flycheck/flycheck/issues/833
+          (delay-mode-hooks (emacs-lisp-mode))
+          (setq delayed-mode-hooks nil)
+          (checkdoc-current-buffer t)
+          (with-current-buffer checkdoc-diagnostic-buffer
+            (princ (buffer-substring-no-properties (point-min) (point-max)))
+            (kill-buffer)))))))
+
+(defconst flycheck-emacs-lisp-checkdoc-variables
+  '(checkdoc-symbol-words
+    checkdoc-arguments-in-order-flag
+    checkdoc-force-history-flag
+    checkdoc-permit-comma-termination-flag
+    checkdoc-force-docstrings-flag
+    checkdoc-package-keywords-flag
+    checkdoc-spellcheck-documentation-flag
+    checkdoc-verb-check-experimental-flag
+    checkdoc-max-keyref-before-warn
+    sentence-end-double-space)
+  "Variables inherited by the checkdoc subprocess.")
+
+(defun flycheck-emacs-lisp-checkdoc-variables-form ()
+  "Make a sexp to pass relevant variables to a checkdoc subprocess.
+
+Variables are taken from `flycheck-emacs-lisp-checkdoc-variables'."
+  `(progn
+     ,@(seq-map (lambda (opt) `(setq-default ,opt ',(symbol-value opt)))
+                (seq-filter #'boundp flycheck-emacs-lisp-checkdoc-variables))))
+
+(flycheck-define-checker emacs-lisp-checkdoc
+  "An Emacs Lisp style checker using CheckDoc.
+
+The checker runs `checkdoc-current-buffer'."
+  :command ("emacs" (eval flycheck-emacs-args)
+            "--eval" (eval (flycheck-sexp-to-string
+                            (flycheck-emacs-lisp-checkdoc-variables-form)))
+            "--eval" (eval flycheck-emacs-lisp-checkdoc-form)
+            "--" source)
+  :error-patterns
+  ((warning line-start (file-name) ":" line ": " (message) line-end))
+  :modes (emacs-lisp-mode)
+  :predicate
+  (lambda ()
+    ;; Do not check Autoloads, Cask/Carton and dir-locals files.  These files
+    ;; really don't need to follow Checkdoc conventions.
+    (not (or (flycheck-autoloads-file-p)
+             (and (buffer-file-name)
+                  (member (file-name-nondirectory (buffer-file-name))
+                          '("Cask" "Carton" ".dir-locals.el")))))))
+
+(dolist (checker '(emacs-lisp emacs-lisp-checkdoc))
+  (setf (car (flycheck-checker-get checker 'command))
+        flycheck-this-emacs-executable))
+
+(flycheck-def-option-var flycheck-erlang-include-path nil erlang
+  "A list of include directories for Erlang.
+
+The value of this variable is a list of strings, where each
+string is a directory to add to the include path of erlc.
+Relative paths are relative to the file being checked."
+  :type '(repeat (directory :tag "Include directory"))
+  :safe #'flycheck-string-list-p
+  :package-version '(flycheck . "0.24"))
+
+(flycheck-def-option-var flycheck-erlang-library-path nil erlang
+  "A list of library directories for Erlang.
+
+The value of this variable is a list of strings, where each
+string is a directory to add to the library path of erlc.
+Relative paths are relative to the file being checked."
+  :type '(repeat (directory :tag "Library directory"))
+  :safe #'flycheck-string-list-p
+  :package-version '(flycheck . "0.24"))
+
+(flycheck-define-checker erlang
+  "An Erlang syntax checker using the Erlang interpreter.
+
+See URL `http://www.erlang.org/'."
+  :command ("erlc"
+            "-o" temporary-directory
+            (option-list "-I" flycheck-erlang-include-path)
+            (option-list "-pa" flycheck-erlang-library-path)
+            "-Wall"
+            source)
+  :error-patterns
+  ((warning line-start (file-name) ":" line ": Warning:" (message) line-end)
+   (error line-start (file-name) ":" line ": " (message) line-end))
+  :modes erlang-mode
+  :enabled (lambda () (string-suffix-p ".erl" (buffer-file-name))))
+
+(defun contains-rebar-config (dir-name)
+  "Return DIR-NAME if DIR-NAME/rebar.config exists, nil otherwise."
+  (when (file-exists-p (expand-file-name "rebar.config" dir-name))
+    dir-name))
+
+(defun locate-rebar3-project-root (file-name &optional prev-file-name acc)
+  "Find the top-most rebar project root for source FILE-NAME.
+
+A project root directory is any directory containing a
+rebar.config file.  Find the top-most directory to move out of any
+nested dependencies.
+
+FILE-NAME is a source file for which to find the project.
+
+PREV-FILE-NAME helps us prevent infinite looping
+
+ACC is an accumulator that keeps the list of results, the first
+non-nil of which will be our project root.
+
+Return the absolute path to the directory"
+  (if (string= file-name prev-file-name)
+      (car (remove nil acc))
+    (let ((current-dir (file-name-directory file-name)))
+      (locate-rebar3-project-root
+       (directory-file-name current-dir)
+       file-name
+       (cons (contains-rebar-config current-dir) acc)))))
+
+(defun flycheck-rebar3-project-root (&optional _checker)
+  "Return directory where rebar.config is located."
+  (locate-rebar3-project-root buffer-file-name))
+
+(flycheck-define-checker erlang-rebar3
+  "An Erlang syntax checker using the rebar3 build tool."
+  :command ("rebar3" "compile")
+  :error-parser
+  (lambda (output checker buffer)
+    ;; rebar3 outputs ANSI terminal colors, which don't match up with
+    ;; :error-patterns, so we strip those color codes from the output
+    ;; here before passing it along to the default behavior. The
+    ;; relevant discussion can be found at
+    ;; https://github.com/flycheck/flycheck/pull/1144
+    (require 'ansi-color)
+    (flycheck-parse-with-patterns
+     (and (fboundp 'ansi-color-filter-apply) (ansi-color-filter-apply output))
+     checker buffer))
+  :error-patterns
+  ((warning line-start
+            (file-name) ":" line ": Warning:" (message) line-end)
+   (error line-start
+          (file-name) ":" line ": " (message) line-end))
+  :modes erlang-mode
+  :enabled flycheck-rebar3-project-root
+  :predicate flycheck-buffer-saved-p
+  :working-directory flycheck-rebar3-project-root)
+
+(flycheck-define-checker eruby-erubis
+  "An eRuby syntax checker using the `erubis' command.
+
+See URL `http://www.kuwata-lab.com/erubis/'."
+  :command ("erubis" "-z" source)
+  :error-patterns
+  ((error line-start (file-name) ":" line ": " (message) line-end))
+  :modes (html-erb-mode rhtml-mode))
+
+(flycheck-def-args-var flycheck-gfortran-args fortran-gfortran
+  :package-version '(flycheck . "0.22"))
+
+(flycheck-def-option-var flycheck-gfortran-include-path nil fortran-gfortran
+  "A list of include directories for GCC Fortran.
+
+The value of this variable is a list of strings, where each
+string is a directory to add to the include path of gcc.
+Relative paths are relative to the file being checked."
+  :type '(repeat (directory :tag "Include directory"))
+  :safe #'flycheck-string-list-p
+  :package-version '(flycheck . "0.20"))
+
+(flycheck-def-option-var flycheck-gfortran-language-standard "f95"
+                         fortran-gfortran
+  "The language standard to use in GFortran.
+
+The value of this variable is either a string denoting a language
+standard, or nil, to use the default standard.  When non-nil,
+pass the language standard via the `-std' option."
+  :type '(choice (const :tag "Default standard" nil)
+                 (string :tag "Language standard"))
+  :safe #'stringp
+  :package-version '(flycheck . "0.20"))
+
+(flycheck-def-option-var flycheck-gfortran-layout nil fortran-gfortran
+  "The source code layout to use in GFortran.
+
+The value of this variable is one of the following symbols:
+
+nil
+     Let gfortran determine the layout from the extension
+
+`free'
+     Use free form layout
+
+
+`fixed'
+     Use fixed form layout
+
+In any other case, an error is signaled."
+  :type '(choice (const :tag "Guess layout from extension" nil)
+                 (const :tag "Free form layout" free)
+                 (const :tag "Fixed form layout" fixed))
+  :safe (lambda (value) (or (not value) (memq value '(free fixed))))
+  :package-version '(flycheck . "0.20"))
+
+(defun flycheck-option-gfortran-layout (value)
+  "Option VALUE filter for `flycheck-gfortran-layout'."
+  (pcase value
+    (`nil nil)
+    (`free "free-form")
+    (`fixed "fixed-form")
+    (_ (error "Invalid value for flycheck-gfortran-layout: %S" value))))
+
+(flycheck-def-option-var flycheck-gfortran-warnings '("all" "extra")
+                         fortran-gfortran
+  "A list of warnings for GCC Fortran.
+
+The value of this variable is a list of strings, where each string
+is the name of a warning category to enable.  By default, all
+recommended warnings and some extra warnings are enabled (as by
+`-Wall' and `-Wextra' respectively).
+
+Refer to the gfortran manual at URL
+`https://gcc.gnu.org/onlinedocs/gfortran/' for more information
+about warnings"
+  :type '(choice (const :tag "No additional warnings" nil)
+                 (repeat :tag "Additional warnings"
+                         (string :tag "Warning name")))
+  :safe #'flycheck-string-list-p
+  :package-version '(flycheck . "0.20"))
+
+(flycheck-define-checker fortran-gfortran
+  "An Fortran syntax checker using GCC.
+
+Uses GCC's Fortran compiler gfortran.  See URL
+`https://gcc.gnu.org/onlinedocs/gfortran/'."
+  :command ("gfortran"
+            "-fsyntax-only"
+            "-fshow-column"
+            ;; Do not visually indicate the source location
+            "-fno-diagnostics-show-caret"
+            ;; Do not show the corresponding warning group
+            "-fno-diagnostics-show-option"
+            ;; Fortran has similar include processing as C/C++
+            "-iquote" (eval (flycheck-c/c++-quoted-include-directory))
+            (option "-std=" flycheck-gfortran-language-standard concat)
+            (option "-f" flycheck-gfortran-layout concat
+                    flycheck-option-gfortran-layout)
+            (option-list "-W" flycheck-gfortran-warnings concat)
+            (option-list "-I" flycheck-gfortran-include-path concat)
+            (eval flycheck-gfortran-args)
+            source)
+  :error-patterns
+  ((error line-start (file-name) ":" line (or ":" ".") column (or ": " ":\n")
+          (or (= 3 (zero-or-more not-newline) "\n") "")
+          (or "Error" "Fatal Error") ": "
+          (message) line-end)
+   (warning line-start (file-name) ":" line (or ":" ".") column (or ": " ":\n")
+            (or (= 3 (zero-or-more not-newline) "\n") "")
+            "Warning: " (message) line-end))
+  :modes (fortran-mode f90-mode))
+
+(flycheck-define-checker go-gofmt
+  "A Go syntax and style checker using the gofmt utility.
+
+See URL `https://golang.org/cmd/gofmt/'."
+  :command ("gofmt")
+  :standard-input t
+  :error-patterns
+  ((error line-start "<standard input>:" line ":" column ": "
+          (message) line-end))
+  :modes go-mode
+  :next-checkers ((warning . go-golint)
+                  ;; Fall back, if go-golint doesn't exist
+                  (warning . go-vet)
+                  ;; Fall back, if go-vet doesn't exist
+                  (warning . go-build) (warning . go-test)
+                  (warning . go-errcheck)
+                  (warning . go-unconvert)
+                  (warning . go-megacheck)))
+
+(flycheck-define-checker go-golint
+  "A Go style checker using Golint.
+
+See URL `https://github.com/golang/lint'."
+  :command ("golint" source)
+  :error-patterns
+  ((warning line-start (file-name) ":" line ":" column ": " (message) line-end))
+  :modes go-mode
+  :next-checkers (go-vet
+                  ;; Fall back, if go-vet doesn't exist
+                  go-build go-test go-errcheck go-unconvert go-megacheck))
+
+(flycheck-def-option-var flycheck-go-vet-print-functions nil go-vet
+  "A list of print-like functions for `go tool vet'.
+
+Go vet will check these functions for format string problems and
+issues, such as a mismatch between the number of formats used,
+and the number of arguments given.
+
+Each entry is in the form Name:N where N is the zero-based
+argument position of the first argument involved in the print:
+either the format or the first print argument for non-formatted
+prints.  For example, if you have Warn and Warnf functions that
+take an io.Writer as their first argument, like Fprintf,
+-printfuncs=Warn:1,Warnf:1 "
+  :type '(repeat :tag "print-like functions"
+                 (string :tag "function"))
+  :safe #'flycheck-string-list-p)
+
+(flycheck-def-option-var flycheck-go-vet-shadow nil go-vet
+  "Whether to check for shadowed variables with `go tool vet'.
+
+When non-nil check for shadowed variables.  When `strict' check
+more strictly, which can very noisy.  When nil do not check for
+shadowed variables.
+
+This option requires Go 1.6 or newer."
+  :type '(choice (const :tag "Do not check for shadowed variables" nil)
+                 (const :tag "Check for shadowed variables" t)
+                 (const :tag "Strictly check for shadowed variables" strict)))
+
+(flycheck-def-option-var flycheck-go-megacheck-disabled-checkers nil
+                         go-megacheck
+  "A list of checkers to disable when running `megacheck'.
+
+The value of this variable is a list of strings, where each
+string is a checker to be disabled. Valid checkers are `simple',
+`staticcheck' and `unused'. When nil, all checkers will be
+enabled. "
+  :type '(set (const :tag "Disable simple" "simple")
+              (const :tag "Disable staticcheck" "staticcheck")
+              (const :tag "Disable unused" "unused"))
+  :safe #'flycheck-string-list-p)
+
+(flycheck-define-checker go-vet
+  "A Go syntax checker using the `go tool vet' command.
+
+See URL `https://golang.org/cmd/go/' and URL
+`https://golang.org/cmd/vet/'."
+  :command ("go" "tool" "vet" "-all"
+            (option "-printfuncs=" flycheck-go-vet-print-functions concat
+                    flycheck-option-comma-separated-list)
+            (option-flag "-shadow" flycheck-go-vet-shadow)
+            (option-list "-tags=" flycheck-go-build-tags concat)
+            (eval (when (eq flycheck-go-vet-shadow 'strict) "-shadowstrict"))
+            source)
+  :error-patterns
+  ((warning line-start (file-name) ":" line ": " (message) line-end))
+  :modes go-mode
+  ;; We must explicitly check whether the "vet" tool is available
+  :predicate (lambda ()
+               (let ((go (flycheck-checker-executable 'go-vet)))
+                 (member "vet" (ignore-errors (process-lines go "tool")))))
+  :next-checkers (go-build
+                  go-test
+                  ;; Fall back if `go build' or `go test' can be used
+                  go-errcheck
+                  go-unconvert
+                  go-megacheck)
+  :verify (lambda (_)
+            (let* ((go (flycheck-checker-executable 'go-vet))
+                   (have-vet (member "vet" (ignore-errors
+                                             (process-lines go "tool")))))
+              (list
+               (flycheck-verification-result-new
+                :label "go tool vet"
+                :message (if have-vet "present" "missing")
+                :face (if have-vet 'success '(bold error)))))))
+
+(flycheck-def-option-var flycheck-go-build-install-deps nil (go-build go-test)
+  "Whether to install dependencies in `go build' and `go test'.
+
+If non-nil automatically install dependencies with `go build'
+while syntax checking."
+  :type 'boolean
+  :safe #'booleanp
+  :package-version '(flycheck . "0.25"))
+
+(flycheck-def-option-var flycheck-go-build-tags nil go-build
+  "A list of tags for `go build'.
+
+Each item is a string with a tag to be given to `go build'."
+  :type '(repeat (string :tag "Tag"))
+  :safe #'flycheck-string-list-p
+  :package-version '(flycheck . "0.25"))
+
+(flycheck-define-checker go-build
+  "A Go syntax and type checker using the `go build' command.
+
+Requires Go 1.6 or newer.  See URL `https://golang.org/cmd/go'."
+  :command ("go" "build"
+            (option-flag "-i" flycheck-go-build-install-deps)
+            ;; multiple tags are listed as "dev debug ..."
+            (option-list "-tags=" flycheck-go-build-tags concat)
+            "-o" null-device)
+  :error-patterns
+  ((error line-start (file-name) ":" line ":"
+          (optional column ":") " "
+          (message (one-or-more not-newline)
+                   (zero-or-more "\n\t" (one-or-more not-newline)))
+          line-end)
+   ;; Catch error message about multiple packages in a directory, which doesn't
+   ;; follow the standard error message format.
+   (info line-start
+         (message "can't load package: package "
+                  (one-or-more (not (any ?: ?\n)))
+                  ": found packages "
+                  (one-or-more not-newline))
+         line-end))
+  :error-filter
+  (lambda (errors)
+    (dolist (error errors)
+      (unless (flycheck-error-line error)
+        ;; Flycheck ignores errors without line numbers, but the error
+        ;; message about multiple packages in a directory doesn't come with a
+        ;; line number, so inject a fake one.
+        (setf (flycheck-error-line error) 1)))
+    errors)
+  :modes go-mode
+  :predicate (lambda ()
+               (and (flycheck-buffer-saved-p)
+                    (not (string-suffix-p "_test.go" (buffer-file-name)))))
+  :next-checkers ((warning . go-errcheck)
+                  (warning . go-unconvert)
+                  (warning . go-megacheck)))
+
+(flycheck-define-checker go-test
+  "A Go syntax and type checker using the `go test' command.
+
+Requires Go 1.6 or newer.  See URL `https://golang.org/cmd/go'."
+  :command ("go" "test"
+            (option-flag "-i" flycheck-go-build-install-deps)
+            (option-list "-tags=" flycheck-go-build-tags concat)
+            "-c" "-o" null-device)
+  :error-patterns
+  ((error line-start (file-name) ":" line ":"
+          (optional column ":") " "
+          (message (one-or-more not-newline)
+                   (zero-or-more "\n\t" (one-or-more not-newline)))
+          line-end))
+  :modes go-mode
+  :predicate
+  (lambda () (and (flycheck-buffer-saved-p)
+                  (string-suffix-p "_test.go" (buffer-file-name))))
+  :next-checkers ((warning . go-errcheck)
+                  (warning . go-unconvert)
+                  (warning . go-megacheck)))
+
+(flycheck-define-checker go-errcheck
+  "A Go checker for unchecked errors.
+
+Requires errcheck newer than commit 8515d34 (Aug 28th, 2015).
+
+See URL `https://github.com/kisielk/errcheck'."
+  :command ("errcheck"
+            "-abspath"
+            (option-list "-tags=" flycheck-go-build-tags concat)
+            ".")
+  :error-patterns
+  ((warning line-start
+            (file-name) ":" line ":" column (or (one-or-more "\t") ": " ":\t")
+            (message)
+            line-end))
+  :error-filter
+  (lambda (errors)
+    (let ((errors (flycheck-sanitize-errors errors)))
+      (dolist (err errors)
+        (-when-let (message (flycheck-error-message err))
+          ;; Improve the messages reported by errcheck to make them more clear.
+          (setf (flycheck-error-message err)
+                (format "Ignored `error` returned from `%s`" message)))))
+    errors)
+  :modes go-mode
+  :predicate (lambda () (flycheck-buffer-saved-p))
+  :next-checkers ((warning . go-unconvert)
+                  (warning . go-megacheck)))
+
+(flycheck-define-checker go-unconvert
+  "A Go checker looking for unnecessary type conversions.
+
+See URL `https://github.com/mdempsky/unconvert'."
+  :command ("unconvert" ".")
+  :error-patterns
+  ((warning line-start (file-name) ":" line ":" column ": " (message) line-end))
+  :modes go-mode
+  :predicate (lambda () (flycheck-buffer-saved-p))
+  :next-checkers ((warning . go-megacheck)))
+
+(flycheck-define-checker go-megacheck
+  "A Go checker that performs static analysis and linting using the `megacheck'
+command.
+
+Requires Go 1.6 or newer. See URL
+`https://github.com/dominikh/go-tools'."
+  :command ("megacheck"
+            (option-list "-tags=" flycheck-go-build-tags concat)
+            (eval (mapcar (lambda (checker) (concat "-" checker
+                                                    ".enabled=false"))
+                          flycheck-go-megacheck-disabled-checkers))
+            ;; Run in current directory to make megacheck aware of symbols
+            ;; declared in other files.
+            ".")
+  :error-patterns
+  ((warning line-start (file-name) ":" line ":" column ": " (message) line-end))
+  :modes go-mode)
+
+(flycheck-define-checker groovy
+  "A groovy syntax checker using groovy compiler API.
+
+See URL `http://www.groovy-lang.org'."
+  :command ("groovy" "-e"
+            "import org.codehaus.groovy.control.*
+
+unit = new CompilationUnit()
+unit.addSource(\"input\", System.in)
+
+try {
+    unit.compile(Phases.CONVERSION)
+} catch (MultipleCompilationErrorsException e) {
+    e.errorCollector.write(new PrintWriter(System.out, true), null)
+}")
+  :standard-input t
+  :error-patterns
+  ((error line-start "input: " line ":" (message)
+          " @ line " line ", column " column "." line-end))
+  :modes groovy-mode)
+
+(flycheck-define-checker haml
+  "A Haml syntax checker using the Haml compiler.
+
+See URL `http://haml.info'."
+  :command ("haml" "-c" "--stdin")
+  :standard-input t
+  :error-patterns
+  ((error line-start "Syntax error on line " line ": " (message) line-end)
+   (error line-start ":" line ": syntax error, " (message) line-end))
+  :modes haml-mode)
+
+(flycheck-define-checker handlebars
+  "A Handlebars syntax checker using the Handlebars compiler.
+
+See URL `http://handlebarsjs.com/'."
+  :command ("handlebars" "-i-")
+  :standard-input t
+  :error-patterns
+  ((error line-start
+          "Error: Parse error on line " line ":" (optional "\r") "\n"
+          (zero-or-more not-newline) "\n" (zero-or-more not-newline) "\n"
+          (message) line-end))
+  :modes (handlebars-mode handlebars-sgml-mode web-mode)
+  :predicate
+  (lambda ()
+    (if (eq major-mode 'web-mode)
+        ;; Check if this is a handlebars file since web-mode does not store the
+        ;; non-canonical engine name
+        (let* ((regexp-alist (bound-and-true-p web-mode-engine-file-regexps))
+               (pattern (cdr (assoc "handlebars" regexp-alist))))
+          (and pattern (buffer-file-name)
+               (string-match-p pattern (buffer-file-name))))
+      t)))
+
+(defconst flycheck-haskell-module-re
+  (rx line-start (zero-or-more (or "\n" (any space)))
+      "module" (one-or-more (or "\n" (any space)))
+      (group (one-or-more (not (any space "(" "\n")))))
+  "Regular expression for a Haskell module name.")
+
+(flycheck-def-args-var flycheck-ghc-args (haskell-stack-ghc haskell-ghc)
+  :package-version '(flycheck . "0.22"))
+
+(flycheck-def-option-var flycheck-ghc-stack-use-nix nil haskell-stack-ghc
+  "Whether to enable nix support in stack.
+
+When non-nil, stack will append '--nix' flag to any call."
+  :type 'boolean
+  :safe #'booleanp
+  :package-version '(flycheck . "26"))
+
+(flycheck-def-option-var flycheck-ghc-stack-project-file nil haskell-stack-ghc
+  "Override project stack.yaml file.
+
+The value of this variable is a file path that refers to a yaml
+file for the current stack project. Relative file paths are
+resolved against the checker's working directory. When non-nil,
+stack will get overridden value via `--stack-yaml'."
+  :type 'string
+  :safe #'stringp
+  :package-version '(flycheck . "32"))
+
+(flycheck-def-option-var flycheck-ghc-no-user-package-database nil haskell-ghc
+  "Whether to disable the user package database in GHC.
+
+When non-nil, disable the user package database in GHC, via
+`-no-user-package-db'."
+  :type 'boolean
+  :safe #'booleanp
+  :package-version '(flycheck . "0.16"))
+
+(flycheck-def-option-var flycheck-ghc-package-databases nil haskell-ghc
+  "Additional module databases for GHC.
+
+The value of this variable is a list of strings, where each
+string is a directory of a package database.  Each package
+database is given to GHC via `-package-db'."
+  :type '(repeat (directory :tag "Package database"))
+  :safe #'flycheck-string-list-p
+  :package-version '(flycheck . "0.16"))
+
+(flycheck-def-option-var flycheck-ghc-search-path nil
+                         (haskell-stack-ghc haskell-ghc)
+  "Module search path for (Stack) GHC.
+
+The value of this variable is a list of strings, where each
+string is a directory containing Haskell modules.  Each directory
+is added to the GHC search path via `-i'."
+  :type '(repeat (directory :tag "Module directory"))
+  :safe #'flycheck-string-list-p
+  :package-version '(flycheck . "0.16"))
+
+(flycheck-def-option-var flycheck-ghc-language-extensions nil
+                         (haskell-stack-ghc haskell-ghc)
+  "Language extensions for (Stack) GHC.
+
+The value of this variable is a list of strings, where each
+string is a Haskell language extension, as in the LANGUAGE
+pragma.  Each extension is enabled via `-X'."
+  :type '(repeat (string :tag "Language extension"))
+  :safe #'flycheck-string-list-p
+  :package-version '(flycheck . "0.19"))
+
+(defvar flycheck-haskell-ghc-cache-directory nil
+  "The cache directory for `ghc' output.")
+
+(defun flycheck-haskell-ghc-cache-directory ()
+  "Get the cache location for `ghc' output.
+
+If no cache directory exists yet, create one and return it.
+Otherwise return the previously used cache directory."
+  (setq flycheck-haskell-ghc-cache-directory
+        (or flycheck-haskell-ghc-cache-directory
+            (make-temp-file "flycheck-haskell-ghc-cache" 'directory))))
+
+(defun flycheck--locate-dominating-file-matching (directory regexp)
+  "Search for a file in directory hierarchy starting at DIRECTORY.
+
+Look up the directory hierarchy from DIRECTORY for a directory
+containing a file that matches REGEXP."
+  (locate-dominating-file
+   directory
+   (lambda (dir)
+     (directory-files dir nil regexp t))))
+
+(defun flycheck-haskell--find-default-directory (checker)
+  "Come up with a suitable default directory for Haskell to run CHECKER in.
+
+In case of `haskell-stack-ghc' checker it is directory with
+stack.yaml file.  If there's no stack.yaml file in any parent
+directory, it will be the directory that \"stack path --project-root\"
+command returns.
+
+For all other checkers, it is the closest parent directory that
+contains a cabal file."
+  (pcase checker
+    (`haskell-stack-ghc
+     (or
+      (when (buffer-file-name)
+        (flycheck--locate-dominating-file-matching
+         (file-name-directory (buffer-file-name))
+         "stack.*\\.yaml\\'"))
+      (-when-let* ((stack (funcall flycheck-executable-find "stack"))
+                   (output (ignore-errors
+                             (process-lines stack
+                                            "--no-install-ghc"
+                                            "path" "--project-root")))
+                   (stack-dir (car output)))
+        (and (file-directory-p stack-dir) stack-dir))))
+    (_
+     (when (buffer-file-name)
+       (flycheck--locate-dominating-file-matching
+        (file-name-directory (buffer-file-name))
+        "\\.cabal\\'\\|\\`package\\.yaml\\'")))))
+
+(flycheck-define-checker haskell-stack-ghc
+  "A Haskell syntax and type checker using `stack ghc'.
+
+See URL `https://github.com/commercialhaskell/stack'."
+  :command ("stack"
+            "--no-install-ghc"
+            (option "--stack-yaml" flycheck-ghc-stack-project-file)
+            (option-flag "--nix" flycheck-ghc-stack-use-nix)
+            "ghc" "--" "-Wall" "-no-link"
+            "-outputdir" (eval (flycheck-haskell-ghc-cache-directory))
+            (option-list "-X" flycheck-ghc-language-extensions concat)
+            (option-list "-i" flycheck-ghc-search-path concat)
+            (eval (concat
+                   "-i"
+                   (flycheck-module-root-directory
+                    (flycheck-find-in-buffer flycheck-haskell-module-re))))
+            (eval flycheck-ghc-args)
+            "-x" (eval
+                  (pcase major-mode
+                    (`haskell-mode "hs")
+                    (`literate-haskell-mode "lhs")))
+            source)
+  :error-patterns
+  ((warning line-start (file-name) ":" line ":" column ":"
+            (or " " "\n    ") (in "Ww") "arning:"
+            (optional " " "[" (id (one-or-more not-newline)) "]")
+            (optional "\n")
+            (message
+             (one-or-more " ") (one-or-more not-newline)
+             (zero-or-more "\n"
+                           (one-or-more " ")
+                           (one-or-more (not (any ?\n ?|)))))
+            line-end)
+   (error line-start (file-name) ":" line ":" column ":" (optional " error:")
+          (or (message (one-or-more not-newline))
+              (and "\n"
+                   (message
+                    (one-or-more " ") (one-or-more not-newline)
+                    (zero-or-more "\n"
+                                  (one-or-more " ")
+                                  (one-or-more (not (any ?\n ?|)))))))
+          line-end))
+  :error-filter
+  (lambda (errors)
+    (flycheck-sanitize-errors (flycheck-dedent-error-messages errors)))
+  :modes (haskell-mode literate-haskell-mode)
+  :next-checkers ((warning . haskell-hlint))
+  :working-directory flycheck-haskell--find-default-directory)
+
+(flycheck-define-checker haskell-ghc
+  "A Haskell syntax and type checker using ghc.
+
+See URL `https://www.haskell.org/ghc/'."
+  :command ("ghc" "-Wall" "-no-link"
+            "-outputdir" (eval (flycheck-haskell-ghc-cache-directory))
+            (option-flag "-no-user-package-db"
+                         flycheck-ghc-no-user-package-database)
+            (option-list "-package-db" flycheck-ghc-package-databases)
+            (option-list "-i" flycheck-ghc-search-path concat)
+            ;; Include the parent directory of the current module tree, to
+            ;; properly resolve local imports
+            (eval (concat
+                   "-i"
+                   (flycheck-module-root-directory
+                    (flycheck-find-in-buffer flycheck-haskell-module-re))))
+            (option-list "-X" flycheck-ghc-language-extensions concat)
+            (eval flycheck-ghc-args)
+            "-x" (eval
+                  (pcase major-mode
+                    (`haskell-mode "hs")
+                    (`literate-haskell-mode "lhs")))
+            source)
+  :error-patterns
+  ((warning line-start (file-name) ":" line ":" column ":"
+            (or " " "\n    ") (in "Ww") "arning:"
+            (optional " " "[" (id (one-or-more not-newline)) "]")
+            (optional "\n")
+            (message
+             (one-or-more " ") (one-or-more not-newline)
+             (zero-or-more "\n"
+                           (one-or-more " ")
+                           (one-or-more (not (any ?\n ?|)))))
+            line-end)
+   (error line-start (file-name) ":" line ":" column ":" (optional " error:")
+          (or (message (one-or-more not-newline))
+              (and "\n"
+                   (message
+                    (one-or-more " ") (one-or-more not-newline)
+                    (zero-or-more "\n"
+                                  (one-or-more " ")
+                                  (one-or-more (not (any ?\n ?|)))))))
+          line-end))
+  :error-filter
+  (lambda (errors)
+    (flycheck-sanitize-errors (flycheck-dedent-error-messages errors)))
+  :modes (haskell-mode literate-haskell-mode)
+  :next-checkers ((warning . haskell-hlint))
+  :working-directory flycheck-haskell--find-default-directory)
+
+(flycheck-def-config-file-var flycheck-hlintrc haskell-hlint "HLint.hs"
+  :safe #'stringp)
+
+(flycheck-def-args-var flycheck-hlint-args haskell-hlint
+  :package-version '(flycheck . "0.25"))
+
+(flycheck-def-option-var flycheck-hlint-language-extensions
+    nil haskell-hlint
+  "Extensions list to enable for hlint.
+
+The value of this variable is a list of strings, where each
+string is a name of extension to enable in
+hlint (e.g. \"QuasiQuotes\")."
+  :type '(repeat :tag "Extensions" (string :tag "Extension"))
+  :safe #'flycheck-string-list-p
+  :package-version '(flycheck . "0.24"))
+
+(flycheck-def-option-var flycheck-hlint-ignore-rules
+    nil haskell-hlint
+  "Ignore rules list for hlint checks.
+
+The value of this variable is a list of strings, where each
+string is an ignore rule (e.g. \"Use fmap\")."
+  :type '(repeat :tag "Ignore rules" (string :tag "Ignore rule"))
+  :safe #'flycheck-string-list-p
+  :package-version '(flycheck . "0.24"))
+
+(flycheck-def-option-var flycheck-hlint-hint-packages
+    nil haskell-hlint
+  "Hint packages to include for hlint checks.
+
+The value of this variable is a list of strings, where each
+string is a default hint package (e.g. (\"Generalise\"
+\"Default\" \"Dollar\"))."
+  :type '(repeat :tag "Hint packages" (string :tag "Hint package"))
+  :safe #'flycheck-string-list-p
+  :package-version '(flycheck . "0.24"))
+
+(flycheck-define-checker haskell-hlint
+  "A Haskell style checker using hlint.
+
+See URL `https://github.com/ndmitchell/hlint'."
+  :command ("hlint"
+            (option-list "-X" flycheck-hlint-language-extensions concat)
+            (option-list "-i=" flycheck-hlint-ignore-rules concat)
+            (option-list "-h" flycheck-hlint-hint-packages concat)
+            (config-file "-h" flycheck-hlintrc)
+            (eval flycheck-hlint-args)
+            source-inplace)
+  :error-patterns
+  ((info line-start
+         (file-name) ":" line ":" column
+         ": Suggestion: "
+         (message (one-or-more (and (one-or-more (not (any ?\n))) ?\n)))
+         line-end)
+   (warning line-start
+            (file-name) ":" line ":" column
+            ": Warning: "
+            (message (one-or-more (and (one-or-more (not (any ?\n))) ?\n)))
+            line-end)
+   (error line-start
+          (file-name) ":" line ":" column
+          ": Error: "
+          (message (one-or-more (and (one-or-more (not (any ?\n))) ?\n)))
+          line-end))
+  :modes (haskell-mode literate-haskell-mode))
+
+(flycheck-def-config-file-var flycheck-tidyrc html-tidy ".tidyrc"
+  :safe #'stringp)
+
+(flycheck-define-checker html-tidy
+  "A HTML syntax and style checker using Tidy.
+
+See URL `https://github.com/htacg/tidy-html5'."
+  :command ("tidy" (config-file "-config" flycheck-tidyrc)
+            "-lang" "en"
+            "-e" "-q")
+  :standard-input t
+  :error-patterns
+  ((error line-start
+          "line " line
+          " column " column
+          " - Error: " (message) line-end)
+   (warning line-start
+            "line " line
+            " column " column
+            " - Warning: " (message) line-end))
+  :modes (html-mode mhtml-mode nxhtml-mode))
+
+(flycheck-def-config-file-var flycheck-jshintrc javascript-jshint ".jshintrc"
+  :safe #'stringp)
+
+(flycheck-def-option-var flycheck-jshint-extract-javascript nil
+                         javascript-jshint
+  "Whether jshint should extract Javascript from HTML.
+
+If nil no extract rule is given to jshint.  If `auto' only
+extract Javascript if a HTML file is detected.  If `always' or
+`never' extract Javascript always or never respectively.
+
+Refer to the jshint manual at the URL
+`http://jshint.com/docs/cli/#flags' for more information."
+  :type
+  '(choice (const :tag "No extraction rule" nil)
+           (const :tag "Try to extract Javascript when detecting HTML files"
+                  auto)
+           (const :tag "Always try to extract Javascript" always)
+           (const :tag "Never try to extract Javascript" never))
+  :safe #'symbolp
+  :package-version '(flycheck . "26"))
+
+(flycheck-define-checker javascript-jshint
+  "A Javascript syntax and style checker using jshint.
+
+See URL `http://www.jshint.com'."
+  :command ("jshint" "--reporter=checkstyle"
+            "--filename" source-original
+            (config-file "--config" flycheck-jshintrc)
+            (option "--extract=" flycheck-jshint-extract-javascript
+                    concat flycheck-option-symbol)
+            "-")
+  :standard-input t
+  :error-parser flycheck-parse-checkstyle
+  :error-filter
+  (lambda (errors)
+    (flycheck-remove-error-file-names
+     "stdin" (flycheck-dequalify-error-ids errors)))
+  :modes (js-mode js2-mode js3-mode rjsx-mode))
+
+(flycheck-def-args-var flycheck-eslint-args javascript-eslint
+  :package-version '(flycheck . "32"))
+
+(flycheck-def-option-var flycheck-eslint-rules-directories nil javascript-eslint
+  "A list of directories with custom rules for ESLint.
+
+The value of this variable is a list of strings, where each
+string is a directory with custom rules for ESLint.
+
+Refer to the ESLint manual at URL
+`http://eslint.org/docs/user-guide/command-line-interface#--rulesdir'
+for more information about the custom directories."
+  :type '(repeat (directory :tag "Custom rules directory"))
+  :safe #'flycheck-string-list-p
+  :package-version '(flycheck . "29"))
+
+(defun flycheck-eslint-config-exists-p ()
+  "Whether there is a valid eslint config for the current buffer."
+  (let* ((executable (flycheck-find-checker-executable 'javascript-eslint))
+         (exitcode (and executable (call-process executable nil nil nil
+                                                 "--print-config" "."))))
+    (eq exitcode 0)))
+
+(defun flycheck-parse-eslint (output checker buffer)
+  "Parse ESLint errors/warnings from JSON OUTPUT.
+
+CHECKER and BUFFER denote the CHECKER that returned OUTPUT and
+the BUFFER that was checked respectively.
+
+See URL `https://eslint.org' for more information about ESLint."
+  (mapcar (lambda (err)
+            (let-alist err
+              (flycheck-error-new-at
+               .line
+               .column
+               (pcase .severity
+                 (2 'error)
+                 (1 'warning)
+                 (_ 'warning))
+               .message
+               :id .ruleId
+               :checker checker
+               :buffer buffer
+               :filename (buffer-file-name buffer))))
+          (let-alist (caar (flycheck-parse-json output))
+            .messages)))
+
+(defun flycheck-eslint--find-working-directory (_checker)
+  "Look for a working directory to run ESLint CHECKER in.
+
+This will be the directory that contains the `node_modules'
+directory.  If no such directory is found in the directory
+hierarchy, it looks first for `.eslintignore' and then for
+`.eslintrc' files to detect the project root."
+  (let* ((regex-config (concat "\\`\\.eslintrc"
+                               "\\(\\.\\(js\\|ya?ml\\|json\\)\\)?\\'")))
+    (when buffer-file-name
+      (or (locate-dominating-file buffer-file-name "node_modules")
+          (locate-dominating-file buffer-file-name ".eslintignore")
+          (locate-dominating-file
+           (file-name-directory buffer-file-name)
+           (lambda (directory)
+             (> (length (directory-files directory nil regex-config t)) 0)))))))
+
+(flycheck-define-checker javascript-eslint
+  "A Javascript syntax and style checker using eslint.
+
+See URL `https://eslint.org/'."
+  :command ("eslint" "--format=json"
+            (option-list "--rulesdir" flycheck-eslint-rules-directories)
+            (eval flycheck-eslint-args)
+            "--stdin" "--stdin-filename" source-original)
+  :standard-input t
+  :error-parser flycheck-parse-eslint
+  :enabled (lambda () (flycheck-eslint-config-exists-p))
+  :modes (js-mode js-jsx-mode js2-mode js2-jsx-mode js3-mode rjsx-mode)
+  :working-directory flycheck-eslint--find-working-directory
+  :verify
+  (lambda (_)
+    (let* ((default-directory
+             (flycheck-compute-working-directory 'javascript-eslint))
+           (have-config (flycheck-eslint-config-exists-p)))
+      (list
+       (flycheck-verification-result-new
+        :label "config file"
+        :message (if have-config "found" "missing or incorrect")
+        :face (if have-config 'success '(bold error)))))))
+
+(flycheck-define-checker javascript-standard
+  "A Javascript code and style checker for the (Semi-)Standard Style.
+
+This checker works with `standard' and `semistandard', defaulting
+to the former.  To use it with the latter, set
+`flycheck-javascript-standard-executable' to `semistandard'.
+
+See URL `https://github.com/standard/standard' and URL
+`https://github.com/Flet/semistandard'."
+  :command ("standard" "--stdin")
+  :standard-input t
+  :error-patterns
+  ((error line-start "  <text>:" line ":" column ":" (message) line-end))
+  :modes (js-mode js-jsx-mode js2-mode js2-jsx-mode js3-mode rjsx-mode))
+
+(flycheck-define-checker json-jsonlint
+  "A JSON syntax and style checker using jsonlint.
+
+See URL `https://github.com/zaach/jsonlint'."
+  ;; We can't use standard input for jsonlint, because it doesn't output errors
+  ;; anymore when using -c -q with standard input :/
+  :command ("jsonlint" "-c" "-q" source)
+  :error-patterns
+  ((error line-start
+          (file-name)
+          ": line " line
+          ", col " column ", "
+          (message) line-end))
+  :error-filter
+  (lambda (errors)
+    (flycheck-sanitize-errors (flycheck-increment-error-columns errors)))
+  :modes json-mode)
+
+(flycheck-define-checker json-python-json
+  "A JSON syntax checker using Python json.tool module.
+
+See URL `https://docs.python.org/3.5/library/json.html#command-line-interface'."
+  :command ("python" "-m" "json.tool" source
+            ;; Send the pretty-printed output to the null device
+            null-device)
+  :error-patterns
+  ((error line-start
+          (message) ": line " line " column " column
+          ;; Ignore the rest of the line which shows the char position.
+          (one-or-more not-newline)
+          line-end))
+  :modes json-mode
+  ;; The JSON parser chokes if the buffer is empty and has no JSON inside
+  :predicate (lambda () (not (flycheck-buffer-empty-p))))
+
+(flycheck-define-checker jsonnet
+  "A Jsonnet syntax checker using the jsonnet binary.
+
+See URL `https://jsonnet.org'."
+  :command ("jsonnet" source-inplace)
+  :error-patterns
+  ((error line-start "STATIC ERROR: " (file-name) ":" line ":" column
+          (zero-or-one (group "-" (one-or-more digit))) ": "
+          (message) line-end)
+   (error line-start "RUNTIME ERROR: " (message) "\n"
+          (one-or-more space) (file-name) ":" (zero-or-one "(")
+          line ":" column (zero-or-more not-newline) line-end))
+  :modes jsonnet-mode)
+
+(flycheck-define-checker less
+  "A LESS syntax checker using lessc.
+
+Requires lessc 1.4 or newer.
+
+See URL `http://lesscss.org'."
+  :command ("lessc" "--lint" "--no-color"
+            "-")
+  :standard-input t
+  :error-patterns
+  ((error line-start (one-or-more word) ":"
+          (message)
+          " in - on line " line
+          ", column " column ":"
+          line-end))
+  :modes less-css-mode)
+
+(flycheck-define-checker less-stylelint
+  "A LESS syntax and style checker using stylelint.
+
+See URL `http://stylelint.io/'."
+  :command ("stylelint"
+            (eval flycheck-stylelint-args)
+            "--syntax" "less"
+            (option-flag "--quiet" flycheck-stylelint-quiet)
+            (config-file "--config" flycheck-stylelintrc))
+  :standard-input t
+  :error-parser flycheck-parse-stylelint
+  :modes (less-css-mode))
+
+(flycheck-define-checker llvm-llc
+  "Flycheck LLVM IR checker using llc.
+
+See URL `http://llvm.org/docs/CommandGuide/llc.html'."
+  :command ("llc" "-o" null-device source)
+  :error-patterns
+  ((error line-start
+          ;; llc prints the executable path
+          (zero-or-one (minimal-match (one-or-more not-newline)) ": ")
+          (file-name) ":" line ":" column ": error: " (message)
+          line-end))
+  :error-filter
+  (lambda (errors)
+    ;; sanitize errors occurring in inline assembly
+    (flycheck-sanitize-errors
+     (flycheck-remove-error-file-names "<inline asm>" errors)))
+  :modes llvm-mode)
+
+(flycheck-def-config-file-var flycheck-luacheckrc lua-luacheck ".luacheckrc"
+  :safe #'stringp)
+
+(flycheck-def-option-var flycheck-luacheck-standards nil lua-luacheck
+  "The standards to use in luacheck.
+
+The value of this variable is either a list of strings denoting
+the standards to use, or nil to pass nothing to luacheck.  When
+non-nil, pass the standards via one or more `--std' options."
+  :type '(choice (const :tag "Default" nil)
+                 (repeat :tag "Custom standards"
+                         (string :tag "Standard name")))
+  :safe #'flycheck-string-list-p)
+(make-variable-buffer-local 'flycheck-luacheck-standards)
+
+(flycheck-define-checker lua-luacheck
+  "A Lua syntax checker using luacheck.
+
+See URL `https://github.com/mpeterv/luacheck'."
+  :command ("luacheck"
+            "--formatter" "plain"
+            "--codes"                   ; Show warning codes
+            "--no-color"
+            (option-list "--std" flycheck-luacheck-standards)
+            (config-file "--config" flycheck-luacheckrc)
+            "--filename" source-original
+            ;; Read from standard input
+            "-")
+  :standard-input t
+  :error-patterns
+  ((warning line-start
+            (optional (file-name))
+            ":" line ":" column
+            ": (" (id "W" (one-or-more digit)) ") "
+            (message) line-end)
+   (error line-start
+          (optional (file-name))
+          ":" line ":" column ":"
+          ;; `luacheck' before 0.11.0 did not output codes for errors, hence
+          ;; the ID is optional here
+          (optional " (" (id "E" (one-or-more digit)) ") ")
+          (message) line-end))
+  :modes lua-mode)
+
+(flycheck-define-checker lua
+  "A Lua syntax checker using the Lua compiler.
+
+See URL `http://www.lua.org/'."
+  :command ("luac" "-p" "-")
+  :standard-input t
+  :error-patterns
+  ((error line-start
+          ;; Skip the name of the luac executable.
+          (minimal-match (zero-or-more not-newline))
+          ": stdin:" line ": " (message) line-end))
+  :modes lua-mode)
+
+(flycheck-def-option-var flycheck-perl-include-path nil perl
+  "A list of include directories for Perl.
+
+The value of this variable is a list of strings, where each
+string is a directory to add to the include path of Perl.
+Relative paths are relative to the file being checked."
+  :type '(repeat (directory :tag "Include directory"))
+  :safe #'flycheck-string-list-p
+  :package-version '(flycheck . "0.24"))
+
+(flycheck-def-option-var flycheck-perl-module-list nil perl
+  "A list of modules to use for Perl.
+
+The value of this variable is a list of strings, where each
+string is a module to 'use' in Perl."
+  :type '(repeat :tag "Module")
+  :safe #'flycheck-string-list-p
+  :package-version '(flycheck . "32"))
+
+(flycheck-define-checker perl
+  "A Perl syntax checker using the Perl interpreter.
+
+See URL `https://www.perl.org'."
+  :command ("perl" "-w" "-c"
+            (option-list "-I" flycheck-perl-include-path)
+            (option-list "-M" flycheck-perl-module-list concat))
+  :standard-input t
+  :error-patterns
+  ((error line-start (minimal-match (message))
+          " at - line " line
+          (or "." (and ", " (zero-or-more not-newline))) line-end))
+  :modes (perl-mode cperl-mode)
+  :next-checkers (perl-perlcritic))
+
+(flycheck-def-option-var flycheck-perlcritic-severity nil perl-perlcritic
+  "The message severity for Perl Critic.
+
+The value of this variable is a severity level as integer, for
+the `--severity' option to Perl Critic."
+  :type '(integer :tag "Severity level")
+  :safe #'integerp
+  :package-version '(flycheck . "0.18"))
+
+(flycheck-def-config-file-var flycheck-perlcriticrc perl-perlcritic
+                              ".perlcriticrc"
+  :safe #'stringp
+  :package-version '(flycheck . "26"))
+
+(flycheck-define-checker perl-perlcritic
+  "A Perl syntax checker using Perl::Critic.
+
+See URL `https://metacpan.org/pod/Perl::Critic'."
+  :command ("perlcritic" "--no-color" "--verbose" "%f/%l/%c/%s/%p/%m (%e)\n"
+            (config-file "--profile" flycheck-perlcriticrc)
+            (option "--severity" flycheck-perlcritic-severity nil
+                    flycheck-option-int))
+  :standard-input t
+  :error-patterns
+  ((info line-start
+         "STDIN/" line "/" column "/" (any "1") "/"
+         (id (one-or-more (not (any "/")))) "/" (message)
+         line-end)
+   (warning line-start
+            "STDIN/" line "/" column "/" (any "234") "/"
+            (id (one-or-more (not (any "/")))) "/" (message)
+            line-end)
+   (error line-start
+          "STDIN/" line "/" column "/" (any "5") "/"
+          (id (one-or-more (not (any "/")))) "/" (message)
+          line-end))
+  :modes (cperl-mode perl-mode))
+
+(flycheck-define-checker php
+  "A PHP syntax checker using the PHP command line interpreter.
+
+See URL `http://php.net/manual/en/features.commandline.php'."
+  :command ("php" "-l" "-d" "error_reporting=E_ALL" "-d" "display_errors=1"
+            "-d" "log_errors=0" source)
+  :error-patterns
+  ((error line-start (or "Parse" "Fatal" "syntax") " error" (any ":" ",") " "
+          (message) " in " (file-name) " on line " line line-end))
+  :modes (php-mode php+-mode)
+  :next-checkers ((warning . php-phpmd)
+                  (warning . php-phpcs)))
+
+(flycheck-def-option-var flycheck-phpmd-rulesets
+    '("cleancode" "codesize" "controversial" "design" "naming" "unusedcode")
+    php-phpmd
+  "The rule sets for PHP Mess Detector.
+
+Set default rule sets and custom rule set files.
+
+See section \"Using multiple rule sets\" in the PHP Mess Detector
+manual at URL `https://phpmd.org/documentation/index.html'."
+  :type '(repeat :tag "rule sets"
+                 (string :tag "A filename or rule set"))
+  :safe #'flycheck-string-list-p)
+
+(flycheck-define-checker php-phpmd
+  "A PHP style checker using PHP Mess Detector.
+
+See URL `https://phpmd.org/'."
+  :command ("phpmd" source "xml"
+            (eval (flycheck-option-comma-separated-list
+                   flycheck-phpmd-rulesets)))
+  :error-parser flycheck-parse-phpmd
+  :modes (php-mode php+-mode)
+  :next-checkers (php-phpcs))
+
+(flycheck-def-option-var flycheck-phpcs-standard nil php-phpcs
+  "The coding standard for PHP CodeSniffer.
+
+When nil, use the default standard from the global PHP
+CodeSniffer configuration.  When set to a string, pass the string
+to PHP CodeSniffer which will interpret it as name as a standard,
+or as path to a standard specification."
+  :type '(choice (const :tag "Default standard" nil)
+                 (string :tag "Standard name or file"))
+  :safe #'stringp)
+
+(flycheck-define-checker php-phpcs
+  "A PHP style checker using PHP Code Sniffer.
+
+Needs PHP Code Sniffer 2.6 or newer.
+
+See URL `http://pear.php.net/package/PHP_CodeSniffer/'."
+  :command ("phpcs" "--report=checkstyle"
+            ;; Use -q flag to force quiet mode
+            ;; Quiet mode prevents errors from extra output when phpcs has
+            ;; been configured with show_progress enabled
+            "-q"
+            (option "--standard=" flycheck-phpcs-standard concat)
+            ;; Pass original file name to phpcs.  We need to concat explicitly
+            ;; here, because phpcs really insists to get option and argument as
+            ;; a single command line argument :|
+            (eval (when (buffer-file-name)
+                    (concat "--stdin-path=" (buffer-file-name))))
+            ;; Read from standard input
+            "-")
+  :standard-input t
+  :error-parser flycheck-parse-checkstyle
+  :error-filter
+  (lambda (errors)
+    (flycheck-sanitize-errors
+     (flycheck-remove-error-file-names "STDIN" errors)))
+  :modes (php-mode php+-mode)
+  ;; phpcs seems to choke on empty standard input, hence skip phpcs if the
+  ;; buffer is empty, see https://github.com/flycheck/flycheck/issues/907
+  :predicate (lambda () (not (flycheck-buffer-empty-p))))
+
+(flycheck-define-checker processing
+  "Processing command line tool.
+
+See https://github.com/processing/processing/wiki/Command-Line"
+  :command ("processing-java" "--force"
+            ;; Don't change the order of these arguments, processing is pretty
+            ;; picky
+            (eval (concat "--sketch=" (file-name-directory (buffer-file-name))))
+            (eval (concat "--output=" (flycheck-temp-dir-system)))
+            "--build")
+  :error-patterns
+  ((error line-start (file-name) ":" line ":" column
+          (zero-or-more (or digit ":")) (message) line-end))
+  :modes processing-mode
+  ;; This syntax checker needs a file name
+  :predicate (lambda () (buffer-file-name)))
+
+(defun flycheck-proselint-parse-errors (output checker buffer)
+  "Parse proselint json output errors from OUTPUT.
+
+CHECKER and BUFFER denoted the CHECKER that returned OUTPUT and
+the BUFFER that was checked respectively.
+
+See URL `http://proselint.com/' for more information about proselint."
+  (mapcar (lambda (err)
+            (let-alist err
+              (flycheck-error-new-at
+               .line
+               .column
+               (pcase .severity
+                 (`"suggestion" 'info)
+                 (`"warning"    'warning)
+                 (`"error"      'error)
+                 ;; Default to error
+                 (_             'error))
+               .message
+               :id .check
+               :buffer buffer
+               :checker checker)))
+          (let-alist (car (flycheck-parse-json output))
+            .data.errors)))
+
+(flycheck-define-checker proselint
+  "Flycheck checker using Proselint.
+
+See URL `http://proselint.com/'."
+  :command ("proselint" "--json" "-")
+  :standard-input t
+  :error-parser flycheck-proselint-parse-errors
+  :modes (text-mode markdown-mode gfm-mode message-mode))
+
+(flycheck-define-checker protobuf-protoc
+  "A protobuf syntax checker using the protoc compiler.
+
+See URL `https://developers.google.com/protocol-buffers/'."
+  :command ("protoc" "--error_format" "gcc"
+            (eval (concat "--java_out=" (flycheck-temp-dir-system)))
+            ;; Add the file directory of protobuf path to resolve import
+            ;; directives
+            (eval (concat "--proto_path="
+                          (file-name-directory (buffer-file-name))))
+            source-inplace)
+  :error-patterns
+  ((info line-start (file-name) ":" line ":" column
+         ": note: " (message) line-end)
+   (error line-start (file-name) ":" line ":" column
+          ": " (message) line-end)
+   (error line-start
+          (message "In file included from") " " (file-name) ":" line ":"
+          column ":" line-end))
+  :modes protobuf-mode
+  :predicate (lambda () (buffer-file-name)))
+
+(flycheck-define-checker pug
+  "A Pug syntax checker using the pug compiler.
+
+See URL `https://pugjs.org/'."
+  :command ("pug" "-p" (eval (expand-file-name (buffer-file-name))))
+  :standard-input t
+  :error-patterns
+  ;; errors with includes/extends (e.g. missing files)
+  ((error "Error: " (message) (zero-or-more not-newline) "\n"
+          (zero-or-more not-newline) "at "
+          (zero-or-more not-newline) " line " line)
+   ;; syntax/runtime errors (e.g. type errors, bad indentation, etc.)
+   (error line-start
+          (optional "Type") "Error: "  (file-name) ":"
+          line (optional ":" column)
+          (zero-or-more not-newline) "\n"
+          (one-or-more (or (zero-or-more not-newline) "|"
+                           (zero-or-more not-newline) "\n")
+                       (zero-or-more "-")  (zero-or-more not-newline) "|"
+                       (zero-or-more not-newline) "\n")
+          (zero-or-more not-newline) "\n"
+          (one-or-more
+           (zero-or-more not-newline) "|"
+           (zero-or-more not-newline) "\n")
+          (zero-or-more not-newline) "\n"
+          (message)
+          line-end))
+  :modes pug-mode)
+
+(flycheck-define-checker puppet-parser
+  "A Puppet DSL syntax checker using puppet's own parser.
+
+See URL `https://puppet.com/'."
+  :command ("puppet" "parser" "validate" "--color=false")
+  :standard-input t
+  :error-patterns
+  (
+   ;; Patterns for Puppet 4
+   (error line-start "Error: Could not parse for environment "
+          (one-or-more (in "a-z" "0-9" "_")) ":"
+          (message) "(line: " line ", column: " column ")" line-end)
+   ;; Errors from Puppet < 4
+   (error line-start "Error: Could not parse for environment "
+          (one-or-more (in "a-z" "0-9" "_")) ":"
+          (message (minimal-match (one-or-more anything)))
+          " at line " line line-end)
+   (error line-start
+          ;; Skip over the path of the Puppet executable
+          (minimal-match (zero-or-more not-newline))
+          ": Could not parse for environment " (one-or-more word)
+          ": " (message (minimal-match (zero-or-more anything)))
+          " at " (file-name "/" (zero-or-more not-newline)) ":" line line-end))
+  :modes puppet-mode
+  :next-checkers ((warning . puppet-lint)))
+
+(flycheck-def-config-file-var flycheck-puppet-lint-rc puppet-lint
+                              ".puppet-lint.rc"
+  :safe #'stringp
+  :package-version '(flycheck . "26"))
+
+(flycheck-def-option-var flycheck-puppet-lint-disabled-checks nil puppet-lint
+  "Disabled checkers for `puppet-lint'.
+
+The value of this variable is a list of strings, where each
+string is the name of a check to disable (e.g. \"80chars\" or
+\"double_quoted_strings\").
+
+See URL `http://puppet-lint.com/checks/' for a list of all checks
+and their names."
+  :type '(repeat (string :tag "Check Name"))
+  :package-version '(flycheck . "26"))
+
+(defun flycheck-puppet-lint-disabled-arg-name (check)
+  "Create an argument to disable a puppetlint CHECK."
+  (concat "--no-" check "-check"))
+
+(flycheck-define-checker puppet-lint
+  "A Puppet DSL style checker using puppet-lint.
+
+See URL `http://puppet-lint.com/'."
+  ;; We must check the original file, because Puppetlint is quite picky on the
+  ;; names of files and there place in the directory structure, to comply with
+  ;; Puppet's autoload directory layout.  For instance, a class foo::bar is
+  ;; required to be in a file foo/bar.pp.  Any other place, such as a Flycheck
+  ;; temporary file will cause an error.
+  :command ("puppet-lint"
+            (config-file "--config" flycheck-puppet-lint-rc)
+            "--log-format"
+            "%{path}:%{line}:%{kind}: %{message} (%{check})"
+            (option-list "" flycheck-puppet-lint-disabled-checks concat
+                         flycheck-puppet-lint-disabled-arg-name)
+            source-original)
+  :error-patterns
+  ((warning line-start (file-name) ":" line ":warning: " (message) line-end)
+   (error line-start (file-name) ":" line ":error: " (message) line-end))
+  :modes puppet-mode
+  ;; Since we check the original file, we can only use this syntax checker if
+  ;; the buffer is actually linked to a file, and if it is not modified.
+  :predicate flycheck-buffer-saved-p)
+
+(defun flycheck-python-find-module (checker module)
+  "Check if a Python MODULE is available.
+CHECKER's executable is assumed to be a Python REPL."
+  (-when-let* ((py (flycheck-find-checker-executable checker))
+               (script (concat "import sys; sys.path.pop(0);"
+                               (format "import %s; print(%s.__file__)"
+                                       module module))))
+    (with-temp-buffer
+      (and (eq (ignore-errors (call-process py nil t nil "-c" script)) 0)
+           (string-trim (buffer-string))))))
+
+(defun flycheck-python-needs-module-p (checker)
+  "Determines whether CHECKER needs to be invoked through Python.
+Previous versions of Flycheck called pylint and flake8 directly;
+this check ensures that we don't break existing code."
+  (not (string-match-p (rx (or "pylint" "flake8")
+                           (or "-script.pyw" ".exe" ".bat" "")
+                           eos)
+                       (flycheck-checker-executable checker))))
+
+(defun flycheck-python-verify-module (checker module)
+  "Verify that a Python MODULE is available.
+Return nil if CHECKER's executable is not a Python REPL.  This
+function's is suitable for a checker's :verify."
+  (when (flycheck-python-needs-module-p checker)
+    (let ((mod-path (flycheck-python-find-module checker module)))
+      (list (flycheck-verification-result-new
+             :label (format "`%s' module" module)
+             :message (if mod-path (format "Found at %S" mod-path) "Missing")
+             :face (if mod-path 'success '(bold error)))))))
+
+(defun flycheck-python-module-args (checker module-name)
+  "Compute arguments to pass to CHECKER's executable to run MODULE-NAME.
+Return nil if CHECKER's executable is not a Python REPL.
+Otherwise, return a list starting with -c (-m is not enough
+because it adds the current directory to Python's path)."
+  (when (flycheck-python-needs-module-p checker)
+    `("-c" ,(concat "import sys,runpy;sys.path.pop(0);"
+                    (format "runpy.run_module(%S)" module-name)))))
+
+(flycheck-def-config-file-var flycheck-flake8rc python-flake8 ".flake8rc"
+  :safe #'stringp)
+
+(flycheck-def-option-var flycheck-flake8-error-level-alist
+    '(("^E9.*$"  . error)               ; Syntax errors from pep8
+      ("^F82.*$" . error)               ; undefined variables from pyflakes
+      ("^F83.*$" . error)               ; Duplicate arguments from flake8
+      ("^D.*$"   . info)                ; Docstring issues from flake8-pep257
+      ("^N.*$"   . info)                ; Naming issues from pep8-naming
+      )
+    python-flake8
+  "An alist mapping flake8 error IDs to Flycheck error levels.
+
+Each item in this list is a cons cell `(PATTERN . LEVEL)' where
+PATTERN is a regular expression matched against the error ID, and
+LEVEL is a Flycheck error level symbol.
+
+Each PATTERN is matched in the order of appearance in this list
+against the error ID.  If it matches the ID, the level of the
+corresponding error is set to LEVEL.  An error that is not
+matched by any PATTERN defaults to warning level.
+
+The default value of this option matches errors from flake8
+itself and from the following flake8 plugins:
+
+- pep8-naming
+- flake8-pep257
+
+You may add your own mappings to this option in order to support
+further flake8 plugins."
+  :type '(repeat (cons (regexp :tag "Error ID pattern")
+                       (symbol :tag "Error level")))
+  :package-version '(flycheck . "0.22"))
+
+(flycheck-def-option-var flycheck-flake8-maximum-complexity nil python-flake8
+  "The maximum McCabe complexity of methods.
+
+If nil, do not check the complexity of methods.  If set to an
+integer, report any complexity greater than the value of this
+variable as warning.
+
+If set to an integer, this variable overrules any similar setting
+in the configuration file denoted by `flycheck-flake8rc'."
+  :type '(choice (const :tag "Do not check McCabe complexity" nil)
+                 (integer :tag "Maximum complexity"))
+  :safe #'integerp)
+
+(flycheck-def-option-var flycheck-flake8-maximum-line-length nil python-flake8
+  "The maximum length of lines.
+
+If set to an integer, the value of this variable denotes the
+maximum length of lines, overruling any similar setting in the
+configuration file denoted by `flycheck-flake8rc'.  An error will
+be reported for any line longer than the value of this variable.
+
+If set to nil, use the maximum line length from the configuration
+file denoted by `flycheck-flake8rc', or the PEP 8 recommendation
+of 79 characters if there is no configuration with this setting."
+  :type '(choice (const :tag "Default value")
+                 (integer :tag "Maximum line length in characters"))
+  :safe #'integerp)
+
+(defun flycheck-flake8-fix-error-level (err)
+  "Fix the error level of ERR.
+
+Update the error level of ERR according to
+`flycheck-flake8-error-level-alist'."
+  (pcase-dolist (`(,pattern . ,level) flycheck-flake8-error-level-alist)
+    (when (string-match-p pattern (flycheck-error-id err))
+      (setf (flycheck-error-level err) level)))
+  err)
+
+(flycheck-define-checker python-flake8
+  "A Python syntax and style checker using Flake8.
+
+Requires Flake8 3.0 or newer. See URL
+`https://flake8.readthedocs.io/'."
+  ;; Not calling flake8 directly makes it easier to switch between different
+  ;; Python versions; see https://github.com/flycheck/flycheck/issues/1055.
+  :command ("python"
+            (eval (flycheck-python-module-args 'python-flake8 "flake8"))
+            "--format=default"
+            (config-file "--config" flycheck-flake8rc)
+            (option "--max-complexity" flycheck-flake8-maximum-complexity nil
+                    flycheck-option-int)
+            (option "--max-line-length" flycheck-flake8-maximum-line-length nil
+                    flycheck-option-int)
+            "-")
+  :standard-input t
+  :error-filter (lambda (errors)
+                  (let ((errors (flycheck-sanitize-errors errors)))
+                    (seq-map #'flycheck-flake8-fix-error-level errors)))
+  :error-patterns
+  ((warning line-start
+            "stdin:" line ":" (optional column ":") " "
+            (id (one-or-more (any alpha)) (one-or-more digit)) " "
+            (message (one-or-more not-newline))
+            line-end))
+  :enabled (lambda ()
+             (or (not (flycheck-python-needs-module-p 'python-flake8))
+                 (flycheck-python-find-module 'python-flake8 "flake8")))
+  :verify (lambda (_) (flycheck-python-verify-module 'python-flake8 "flake8"))
+  :modes python-mode)
+
+(flycheck-def-config-file-var flycheck-pylintrc python-pylint ".pylintrc"
+  :safe #'stringp)
+
+(flycheck-def-option-var flycheck-pylint-use-symbolic-id t python-pylint
+  "Whether to use pylint message symbols or message codes.
+
+A pylint message has both an opaque identifying code (such as `F0401') and a
+more meaningful symbolic code (such as `import-error').  This option governs
+which should be used and reported to the user."
+  :type 'boolean
+  :safe #'booleanp
+  :package-version '(flycheck . "0.25"))
+
+(flycheck-define-checker python-pylint
+  "A Python syntax and style checker using Pylint.
+
+This syntax checker requires Pylint 1.0 or newer.
+
+See URL `https://www.pylint.org/'."
+  ;; --reports=n disables the scoring report.
+  ;; Not calling pylint directly makes it easier to switch between different
+  ;; Python versions; see https://github.com/flycheck/flycheck/issues/1055.
+  :command ("python"
+            (eval (flycheck-python-module-args 'python-pylint "pylint"))
+            "--reports=n"
+            "--output-format=text"
+            (eval (if flycheck-pylint-use-symbolic-id
+                      "--msg-template={path}:{line}:{column}:{C}:{symbol}:{msg}"
+                    "--msg-template={path}:{line}:{column}:{C}:{msg_id}:{msg}"))
+            (config-file "--rcfile=" flycheck-pylintrc concat)
+            ;; Need `source-inplace' for relative imports (e.g. `from .foo
+            ;; import bar'), see https://github.com/flycheck/flycheck/issues/280
+            source-inplace)
+  :error-filter
+  (lambda (errors)
+    (flycheck-sanitize-errors (flycheck-increment-error-columns errors)))
+  :error-patterns
+  ((error line-start (file-name) ":" line ":" column ":"
+          (or "E" "F") ":"
+          (id (one-or-more (not (any ":")))) ":"
+          (message) line-end)
+   (warning line-start (file-name) ":" line ":" column ":"
+            (or "W" "R") ":"
+            (id (one-or-more (not (any ":")))) ":"
+            (message) line-end)
+   (info line-start (file-name) ":" line ":" column ":"
+         (or "C" "I") ":"
+         (id (one-or-more (not (any ":")))) ":"
+         (message) line-end))
+  :enabled (lambda ()
+             (or (not (flycheck-python-needs-module-p 'python-pylint))
+                 (flycheck-python-find-module 'python-pylint "pylint")))
+  :verify (lambda (_) (flycheck-python-verify-module 'python-pylint "pylint"))
+  :modes python-mode)
+
+(flycheck-define-checker python-pycompile
+  "A Python syntax checker using Python's builtin compiler.
+
+See URL `https://docs.python.org/3.4/library/py_compile.html'."
+  :command ("python" "-m" "py_compile" source)
+  :error-patterns
+  ;; Python 2.7
+  ((error line-start "  File \"" (file-name) "\", line " line "\n"
+          (>= 2 (zero-or-more not-newline) "\n")
+          "SyntaxError: " (message) line-end)
+   (error line-start "Sorry: IndentationError: "
+          (message) "(" (file-name) ", line " line ")"
+          line-end)
+   ;; 2.6
+   (error line-start "SyntaxError: ('" (message (one-or-more (not (any "'"))))
+          "', ('" (file-name (one-or-more (not (any "'")))) "', "
+          line ", " column ", " (one-or-more not-newline) line-end))
+  :modes python-mode)
+
+(flycheck-def-config-file-var flycheck-python-mypy-ini python-mypy
+                              "mypy.ini"
+  :safe #'stringp)
+
+(flycheck-def-option-var flycheck-python-mypy-cache-dir nil python-mypy
+  "Directory used to write .mypy_cache directories."
+  :safe #'stringp
+  :type '(choice
+          (const :tag "Write to the working directory" nil)
+          (const :tag "Never write .mypy_cache directories" null-device)
+          (string :tag "Path"))
+  :package-version '(flycheck . "32"))
+
+(flycheck-define-checker python-mypy
+  "Mypy syntax and type checker.  Requires mypy>=0.580.
+
+See URL `http://mypy-lang.org/'."
+  :command ("mypy"
+            (config-file "--config-file" flycheck-python-mypy-ini)
+            (option "--cache-dir" flycheck-python-mypy-cache-dir)
+            source-original)
+  :error-patterns
+  ((error line-start (file-name) ":" line ": error:" (message) line-end)
+   (warning line-start (file-name) ":" line ": warning:" (message) line-end))
+  :modes python-mode
+  ;; Ensure the file is saved, to work around
+  ;; https://github.com/python/mypy/issues/4746.
+  :predicate flycheck-buffer-saved-p
+  :next-checkers '(t . python-flake8))
+
+(flycheck-def-option-var flycheck-lintr-caching t r-lintr
+  "Whether to enable caching in lintr.
+
+By default, lintr caches all expressions in a file and re-checks
+only those that have changed.  Setting this option to nil
+disables caching in case there are problems."
+  :type 'boolean
+  :safe #'booleanp
+  :package-version '(flycheck . "0.23"))
+
+(flycheck-def-option-var flycheck-lintr-linters "default_linters" r-lintr
+  "Linters to use with lintr.
+
+The value of this variable is a string containing an R
+expression, which selects linters for lintr."
+  :type 'string
+  :risky t
+  :package-version '(flycheck . "0.23"))
+
+(defun flycheck-r-has-lintr (R)
+  "Whether R has installed the `lintr' library."
+  (with-temp-buffer
+    (let ((process-environment (append '("LC_ALL=C") process-environment)))
+      (call-process R nil t nil
+                    "--slave" "--restore" "--no-save" "-e"
+                    "library('lintr')")
+      (goto-char (point-min))
+      (not (re-search-forward "there is no package called 'lintr'"
+                              nil 'no-error)))))
+
+(flycheck-define-checker r-lintr
+  "An R style and syntax checker using the lintr package.
+
+See URL `https://github.com/jimhester/lintr'."
+  :command ("R" "--slave" "--restore" "--no-save" "-e"
+            (eval (concat
+                   "library(lintr);"
+                   "try(lint(commandArgs(TRUE)"
+                   ", cache=" (if flycheck-lintr-caching "TRUE" "FALSE")
+                   ", " flycheck-lintr-linters
+                   "))"))
+            "--args" source)
+  :error-patterns
+  ((info line-start (file-name) ":" line ":" column ": style: " (message)
+         line-end)
+   (warning line-start (file-name) ":" line ":" column ": warning: " (message)
+            line-end)
+   (error line-start (file-name) ":" line ":" column ": error: " (message)
+          line-end))
+  :modes ess-mode
+  :predicate
+  ;; Don't check ESS files which do not contain R, and make sure that lintr is
+  ;; actually available
+  (lambda ()
+    (and (equal ess-language "S")
+         (flycheck-r-has-lintr (flycheck-checker-executable 'r-lintr))))
+  :verify (lambda (checker)
+            (let ((has-lintr (flycheck-r-has-lintr
+                              (flycheck-checker-executable checker))))
+              (list
+               (flycheck-verification-result-new
+                :label "lintr library"
+                :message (if has-lintr "present" "missing")
+                :face (if has-lintr 'success '(bold error)))))))
+
+(defun flycheck-racket-has-expand-p (checker)
+  "Whether the executable of CHECKER provides the `expand' command."
+  (let ((raco (flycheck-find-checker-executable checker)))
+    (when raco
+      (with-temp-buffer
+        (call-process raco nil t nil "expand")
+        (goto-char (point-min))
+        (not (looking-at-p (rx bol (1+ not-newline)
+                               "Unrecognized command: expand"
+                               eol)))))))
+
+(flycheck-define-checker racket
+  "A Racket syntax checker with `raco expand'.
+
+The `compiler-lib' racket package is required for this syntax
+checker.
+
+See URL `https://racket-lang.org/'."
+  :command ("raco" "expand" source-inplace)
+  :predicate
+  (lambda ()
+    (and (or (not (eq major-mode 'scheme-mode))
+             ;; In `scheme-mode' we must check the current Scheme implementation
+             ;; being used
+             (and (boundp 'geiser-impl--implementation)
+                  (eq geiser-impl--implementation 'racket)))
+         (flycheck-racket-has-expand-p 'racket)))
+  :verify
+  (lambda (checker)
+    (let ((has-expand (flycheck-racket-has-expand-p checker))
+          (in-scheme-mode (eq major-mode 'scheme-mode))
+          (geiser-impl (bound-and-true-p geiser-impl--implementation)))
+      (list
+       (flycheck-verification-result-new
+        :label "compiler-lib package"
+        :message (if has-expand "present" "missing")
+        :face (if has-expand 'success '(bold error)))
+       (flycheck-verification-result-new
+        :label "Geiser Implementation"
+        :message (cond
+                  ((not in-scheme-mode) "Using Racket Mode")
+                  ((eq geiser-impl 'racket) "Racket")
+                  (geiser-impl (format "Other: %s" geiser-impl))
+                  (t "Geiser not active"))
+        :face (cond
+               ((or (not in-scheme-mode) (eq geiser-impl 'racket)) 'success)
+               (t '(bold error)))))))
+  :error-filter
+  (lambda (errors)
+    (flycheck-sanitize-errors
+     (flycheck-increment-error-columns
+      (seq-remove
+       (lambda (err)
+         (string=
+          "/usr/share/racket/pkgs/compiler-lib/compiler/commands/expand.rkt"
+          (flycheck-error-filename err)))
+       errors))))
+  :error-patterns
+  ((error line-start (zero-or-more space)
+          (file-name) ":" line ":" column ":" (message) line-end))
+  :modes (racket-mode scheme-mode))
+
+(flycheck-define-checker rpm-rpmlint
+  "A RPM SPEC file syntax checker using rpmlint.
+
+See URL `https://sourceforge.net/projects/rpmlint/'."
+  :command ("rpmlint" source)
+  :error-patterns
+  ((error line-start
+          (file-name) ":" (optional line ":") " E: " (message)
+          line-end)
+   (warning line-start
+            (file-name) ":" (optional line ":") " W: " (message)
+            line-end))
+  :error-filter
+  ;; Add fake line numbers if they are missing in the lint output
+  (lambda (errors)
+    (dolist (err errors)
+      (unless (flycheck-error-line err)
+        (setf (flycheck-error-line err) 1)))
+    errors)
+  :error-explainer
+  (lambda (error)
+    (-when-let* ((error-message (flycheck-error-message error))
+                 (message-id (save-match-data
+                               (string-match "\\([^ ]+\\)" error-message)
+                               (match-string 1 error-message))))
+      (with-output-to-string
+        (call-process "rpmlint" nil standard-output nil "-I" message-id))))
+  :modes (sh-mode rpm-spec-mode)
+  :predicate (lambda () (or (not (eq major-mode 'sh-mode))
+                            ;; In `sh-mode', we need the proper shell
+                            (eq sh-shell 'rpm))))
+
+(flycheck-def-config-file-var flycheck-markdown-markdownlint-cli-config
+    markdown-markdownlint-cli nil
+  :safe #'stringp
+  :package-version '(flycheck . "32"))
+
+(flycheck-define-checker markdown-markdownlint-cli
+  "Markdown checker using markdownlint-cli.
+
+See URL `https://github.com/igorshubovych/markdownlint-cli'."
+  :command ("markdownlint"
+            (config-file "--config" flycheck-markdown-markdownlint-cli-config)
+            source)
+  :error-patterns
+  ((error line-start
+          (file-name) ": " line ": " (id (one-or-more (not (any space))))
+          " " (message) line-end))
+  :error-filter
+  (lambda (errors)
+    (flycheck-sanitize-errors
+     (flycheck-remove-error-file-names "(string)" errors)))
+  :modes (markdown-mode gfm-mode))
+
+(flycheck-def-option-var flycheck-markdown-mdl-rules nil markdown-mdl
+  "Rules to enable for mdl.
+
+The value of this variable is a list of strings each of which is
+the name of a rule to enable.
+
+By default all rules are enabled.
+
+See URL `https://git.io/vhi2t'."
+  :type '(repeat :tag "Enabled rules"
+                 (string :tag "rule name"))
+  :safe #'flycheck-string-list-p
+  :package-version '(flycheck . "27"))
+
+(flycheck-def-option-var flycheck-markdown-mdl-tags nil markdown-mdl
+  "Rule tags to enable for mdl.
+
+The value of this variable is a list of strings each of which is
+the name of a rule tag.  Only rules with these tags are enabled.
+
+By default all rules are enabled.
+
+See URL `https://git.io/vhi2t'."
+  :type '(repeat :tag "Enabled tags"
+                 (string :tag "tag name"))
+  :safe #'flycheck-string-list-p
+  :package-version '(flycheck . "27"))
+
+(flycheck-def-config-file-var flycheck-markdown-mdl-style markdown-mdl nil
+  :safe #'stringp
+  :package-version '(flycheck . "27"))
+
+(flycheck-define-checker markdown-mdl
+  "Markdown checker using mdl.
+
+See URL `https://github.com/markdownlint/markdownlint'."
+  :command ("mdl"
+            (config-file "--style" flycheck-markdown-mdl-style)
+            (option "--tags=" flycheck-markdown-mdl-rules concat
+                    flycheck-option-comma-separated-list)
+            (option "--rules=" flycheck-markdown-mdl-rules concat
+                    flycheck-option-comma-separated-list))
+  :standard-input t
+  :error-patterns
+  ((error line-start
+          (file-name) ":" line ": " (id (one-or-more alnum)) " " (message)
+          line-end))
+  :error-filter
+  (lambda (errors)
+    (flycheck-sanitize-errors
+     (flycheck-remove-error-file-names "(stdin)" errors)))
+  :modes (markdown-mode gfm-mode))
+
+(flycheck-define-checker nix
+  "Nix checker using nix-instantiate.
+
+See URL `https://nixos.org/nix/manual/#sec-nix-instantiate'."
+  :command ("nix-instantiate" "--parse" "-")
+  :standard-input t
+  :error-patterns
+  ((error line-start
+          "error: " (message) " at " (file-name) ":" line ":" column
+          line-end))
+  :error-filter
+  (lambda (errors)
+    (flycheck-sanitize-errors
+     (flycheck-remove-error-file-names "(string)" errors)))
+  :modes nix-mode)
+
+(defun flycheck-locate-sphinx-source-directory ()
+  "Locate the Sphinx source directory for the current buffer.
+
+Return the source directory, or nil, if the current buffer is not
+part of a Sphinx project."
+  (-when-let* ((filename (buffer-file-name))
+               (dir (locate-dominating-file filename "conf.py")))
+    (expand-file-name dir)))
+
+(flycheck-define-checker rst
+  "A ReStructuredText (RST) syntax checker using Docutils.
+
+See URL `http://docutils.sourceforge.net/'."
+  ;; We need to use source-inplace to properly resolve relative paths in
+  ;; include:: directives
+  :command ("rst2pseudoxml.py" "--report=2" "--halt=5"
+            ;; Read from standard input and throw output away
+            "-" null-device)
+  :standard-input t
+  :error-patterns
+  ((warning line-start "<stdin>:" line ": (WARNING/2) " (message) line-end)
+   (error line-start "<stdin>:" line
+          ": (" (or "ERROR/3" "SEVERE/4") ") "
+          (message) line-end))
+  :modes rst-mode)
+
+(flycheck-def-option-var flycheck-sphinx-warn-on-missing-references t rst-sphinx
+  "Whether to warn about missing references in Sphinx.
+
+When non-nil (the default), warn about all missing references in
+Sphinx via `-n'."
+  :type 'boolean
+  :safe #'booleanp
+  :package-version '(flycheck . "0.17"))
+
+(flycheck-define-checker rst-sphinx
+  "A ReStructuredText (RST) syntax checker using Sphinx.
+
+Requires Sphinx 1.2 or newer.  See URL `http://sphinx-doc.org'."
+  :command ("sphinx-build" "-b" "pseudoxml"
+            "-q" "-N"                   ; Reduced output and no colors
+            (option-flag "-n" flycheck-sphinx-warn-on-missing-references)
+            (eval (flycheck-locate-sphinx-source-directory))
+            temporary-directory         ; Redirect the output to a temporary
+                                        ; directory
+            source-original)            ; Sphinx needs the original document
+  :error-patterns
+  ((warning line-start (file-name) ":" line ": WARNING: " (message) line-end)
+   (error line-start
+          (file-name) ":" line
+          ": " (or "ERROR" "SEVERE") ": "
+          (message) line-end))
+  :modes rst-mode
+  :predicate (lambda () (and (flycheck-buffer-saved-p)
+                             (flycheck-locate-sphinx-source-directory))))
+
+(defun flycheck-ruby--find-project-root (_checker)
+  "Compute an appropriate working-directory for flycheck-ruby.
+
+This is either a parent directory containing a Gemfile, or nil."
+  (and
+   buffer-file-name
+   (locate-dominating-file buffer-file-name "Gemfile")))
+
+(flycheck-def-config-file-var flycheck-rubocoprc ruby-rubocop ".rubocop.yml"
+  :safe #'stringp)
+
+(flycheck-def-option-var flycheck-rubocop-lint-only nil ruby-rubocop
+  "Whether to only report code issues in Rubocop.
+
+When non-nil, only report code issues in Rubocop, via `--lint'.
+Otherwise report style issues as well."
+  :safe #'booleanp
+  :type 'boolean
+  :package-version '(flycheck . "0.16"))
+
+(flycheck-define-checker ruby-rubocop
+  "A Ruby syntax and style checker using the RuboCop tool.
+
+You need at least RuboCop 0.34 for this syntax checker.
+
+See URL `http://batsov.com/rubocop/'."
+  :command ("rubocop"
+            "--display-cop-names"
+            "--force-exclusion"
+            "--format" "emacs"
+            ;; Explicitly disable caching to prevent Rubocop 0.35.1 and earlier
+            ;; from caching standard input.  Later versions of Rubocop
+            ;; automatically disable caching with --stdin, see
+            ;; https://github.com/flycheck/flycheck/issues/844 and
+            ;; https://github.com/bbatsov/rubocop/issues/2576
+            "--cache" "false"
+            (config-file "--config" flycheck-rubocoprc)
+            (option-flag "--lint" flycheck-rubocop-lint-only)
+            ;; Rubocop takes the original file name as argument when reading
+            ;; from standard input
+            "--stdin" source-original)
+  :standard-input t
+  :working-directory flycheck-ruby--find-project-root
+  :error-patterns
+  ((info line-start (file-name) ":" line ":" column ": C: "
+         (optional (id (one-or-more (not (any ":")))) ": ") (message) line-end)
+   (warning line-start (file-name) ":" line ":" column ": W: "
+            (optional (id (one-or-more (not (any ":")))) ": ") (message)
+            line-end)
+   (error line-start (file-name) ":" line ":" column ": " (or "E" "F") ": "
+          (optional (id (one-or-more (not (any ":")))) ": ") (message)
+          line-end))
+  :modes (enh-ruby-mode ruby-mode)
+  :next-checkers ((warning . ruby-reek)
+                  (warning . ruby-rubylint)))
+
+;; Default to `nil' to let Reek find its configuration file by itself
+(flycheck-def-config-file-var flycheck-reekrc ruby-reek nil
+  :safe #'string-or-null-p
+  :package-version '(flycheck . "30"))
+
+(flycheck-define-checker ruby-reek
+  "A Ruby smell checker using reek.
+
+See URL `https://github.com/troessner/reek'."
+  :command ("reek" "--format" "json"
+            (config-file "--config" flycheck-reekrc)
+            source)
+  :error-parser flycheck-parse-reek
+  :modes (enh-ruby-mode ruby-mode)
+  :next-checkers ((warning . ruby-rubylint)))
+
+;; Default to `nil' to let Rubylint find its configuration file by itself, and
+;; to maintain backwards compatibility with older Rubylint and Flycheck releases
+(flycheck-def-config-file-var flycheck-rubylintrc ruby-rubylint nil
+  :safe #'stringp)
+
+(flycheck-define-checker ruby-rubylint
+  "A Ruby syntax and code analysis checker using ruby-lint.
+
+Requires ruby-lint 2.0.2 or newer.  See URL
+`https://github.com/YorickPeterse/ruby-lint'."
+  :command ("ruby-lint" "--presenter=syntastic"
+            (config-file "--config" flycheck-rubylintrc)
+            source)
+  ;; Ruby Lint can't read from standard input
+  :error-patterns
+  ((info line-start
+         (file-name) ":I:" line ":" column ": " (message) line-end)
+   (warning line-start
+            (file-name) ":W:" line ":" column ": " (message) line-end)
+   (error line-start
+          (file-name) ":E:" line ":" column ": " (message) line-end))
+  :modes (enh-ruby-mode ruby-mode))
+
+(flycheck-define-checker ruby
+  "A Ruby syntax checker using the standard Ruby interpreter.
+
+Please note that the output of different Ruby versions and
+implementations varies wildly.  This syntax checker supports
+current versions of MRI and JRuby, but may break when used with
+other implementations or future versions of these
+implementations.
+
+Please consider using `ruby-rubocop' or `ruby-reek' instead.
+
+See URL `https://www.ruby-lang.org/'."
+  :command ("ruby" "-w" "-c")
+  :standard-input t
+  :error-patterns
+  ;; These patterns support output from JRuby, too, to deal with RVM or Rbenv
+  ((error line-start "SyntaxError in -:" line ": " (message) line-end)
+   (warning line-start "-:" line ":" (optional column ":")
+            " warning: " (message) line-end)
+   (error line-start "-:" line ": " (message) line-end))
+  :modes (enh-ruby-mode ruby-mode)
+  :next-checkers ((warning . ruby-rubylint)))
+
+(flycheck-define-checker ruby-jruby
+  "A Ruby syntax checker using the JRuby interpreter.
+
+This syntax checker is very primitive, and may break on future
+versions of JRuby.
+
+Please consider using `ruby-rubocop' or `ruby-rubylint' instead.
+
+See URL `http://jruby.org/'."
+  :command ("jruby" "-w" "-c")
+  :standard-input t
+  :error-patterns
+  ((error   line-start "SyntaxError in -:" line ": " (message) line-end)
+   (warning line-start "-:" line ": warning: " (message) line-end)
+   (error   line-start "-:" line ": "          (message) line-end))
+  :modes (enh-ruby-mode ruby-mode)
+  :next-checkers ((warning . ruby-rubylint)))
+
+(flycheck-def-args-var flycheck-cargo-check-args (rust-cargo)
+  :package-version '(flycheck . "32"))
+
+(flycheck-def-args-var flycheck-rust-args (rust)
+  :package-version '(flycheck . "0.24"))
+
+(flycheck-def-option-var flycheck-rust-check-tests t (rust-cargo rust)
+  "Whether to check test code in Rust.
+
+For the `rust' checker: When non-nil, `rustc' is passed the
+`--test' flag, which will check any code marked with the
+`#[cfg(test)]' attribute and any functions marked with
+`#[test]'. Otherwise, `rustc' is not passed `--test' and test
+code will not be checked.  Skipping `--test' is necessary when
+using `#![no_std]', because compiling the test runner requires
+`std'.
+
+For the `rust-cargo' checker: When non-nil, calls `cargo test
+--no-run' instead of `cargo check'."
+  :type 'boolean
+  :safe #'booleanp
+  :package-version '("flycheck" . "0.19"))
+
+(flycheck-def-option-var flycheck-rust-crate-root nil rust
+  "A path to the crate root for the current buffer.
+
+The value of this variable is either a string with the path to
+the crate root for the current buffer, or nil if the current buffer
+is a crate.  A relative path is relative to the current buffer.
+
+If this variable is non nil the current buffer will only be checked
+if it is not modified, i.e. after it has been saved."
+  :type 'string
+  :package-version '(flycheck . "0.20")
+  :safe #'stringp)
+(make-variable-buffer-local 'flycheck-rust-crate-root)
+
+(flycheck-def-option-var flycheck-rust-crate-type "lib" (rust-cargo rust)
+  "The type of the Rust Crate to check.
+
+For `rust-cargo', the value should be a string denoting the
+target type passed to Cargo.  See
+`flycheck-rust-valid-crate-type-p' for the list of allowed
+values.
+
+For `rust', the value should be a string denoting the crate type
+for the `--crate-type' flag of rustc."
+  :type '(choice (const :tag "nil (rust/rust-cargo)" nil)
+                 (const :tag "lib (rust/rust-cargo)" "lib")
+                 (const :tag "bin (rust/rust-cargo)" "bin")
+                 (const :tag "example (rust-cargo)" "example")
+                 (const :tag "test (rust-cargo)" "test")
+                 (const :tag "bench (rust-cargo)" "bench")
+                 (const :tag "rlib (rust)" "rlib")
+                 (const :tag "dylib (rust)" "dylib")
+                 (const :tag "cdylib (rust)" "cdylib")
+                 (const :tag "staticlib (rust)" "staticlib")
+                 (const :tag "metadata (rust)" "metadata"))
+  :safe #'stringp
+  :package-version '(flycheck . "0.20"))
+(make-variable-buffer-local 'flycheck-rust-crate-type)
+
+(flycheck-def-option-var flycheck-rust-binary-name nil rust-cargo
+  "The name of the binary to pass to `cargo check --CRATE-TYPE'.
+
+The value of this variable is a string denoting the name of the
+target to check: usually the name of the crate, or the name of
+one of the files under `src/bin', `tests', `examples' or
+`benches'.
+
+This always requires a non-nil value, unless
+`flycheck-rust-crate-type' is `lib' or nil, in which case it is
+ignored."
+  :type 'string
+  :safe #'stringp
+  :package-version '(flycheck . "28"))
+(make-variable-buffer-local 'flycheck-rust-binary-name)
+
+(flycheck-def-option-var flycheck-rust-library-path nil rust
+  "A list of library directories for Rust.
+
+The value of this variable is a list of strings, where each
+string is a directory to add to the library path of Rust.
+Relative paths are relative to the file being checked."
+  :type '(repeat (directory :tag "Library directory"))
+  :safe #'flycheck-string-list-p
+  :package-version '(flycheck . "0.18"))
+
+(defun flycheck-rust-error-explainer (error)
+  "Return an explanation text for the given `flycheck-error' ERROR."
+  (-when-let (error-code (flycheck-error-id error))
+    (with-output-to-string
+      (call-process "rustc" nil standard-output nil "--explain" error-code))))
+
+(defun flycheck-rust-error-filter (errors)
+  "Filter ERRORS from rustc output that have no explanatory value."
+  (seq-remove
+   (lambda (err)
+     (or
+      ;; Macro errors emit a diagnostic in a phony file,
+      ;; e.g. "<println macros>".
+      (string-match-p
+       (rx "macros>" line-end)
+       (flycheck-error-filename err))
+      ;; Redundant message giving the number of failed errors
+      (string-match-p
+       (rx (or (: "aborting due to " (optional (one-or-more num) " ")
+                  "previous error")
+               (: "For more information about this error, try `rustc --explain "
+                  (one-or-more alnum) "`.")))
+       (flycheck-error-message err))))
+   errors))
+
+(defun flycheck-rust-manifest-directory ()
+  "Return the nearest directory holding the Cargo manifest.
+
+Return the nearest directory containing the `Cargo.toml' manifest
+file, starting from the current buffer and using
+`locate-dominating-file'.  Return nil if there is no such file,
+or if the current buffer has no file name."
+  (and buffer-file-name
+       (locate-dominating-file buffer-file-name "Cargo.toml")))
+
+(defun flycheck-rust-cargo-metadata ()
+  "Run 'cargo metadata' and return the result as parsed JSON object."
+  (car (flycheck-parse-json
+        (with-output-to-string
+          (call-process "cargo" nil standard-output nil
+                        "metadata" "--no-deps" "--format-version" "1")))))
+
+(defun flycheck-rust-cargo-workspace-root ()
+  "Return the path to the workspace root of a Rust Cargo project.
+
+Return nil if the workspace root does not exist (for Rust
+versions inferior to 1.25)."
+  (let-alist (flycheck-rust-cargo-metadata)
+    .workspace_root))
+
+(defun flycheck-rust-cargo-has-command-p (command)
+  "Whether Cargo has COMMAND in its list of commands.
+
+Execute `cargo --list' to find out whether COMMAND is present."
+  (let ((cargo (funcall flycheck-executable-find "cargo")))
+    (member command (mapcar #'string-trim-left
+                            (ignore-errors (process-lines cargo "--list"))))))
+
+(defun flycheck-rust-valid-crate-type-p (crate-type)
+  "Whether CRATE-TYPE is a valid target type for Cargo.
+
+A valid Cargo target type is one of `lib', `bin', `example',
+`test' or `bench'."
+  (member crate-type '(nil "lib" "bin" "example" "test" "bench")))
+
+(flycheck-define-checker rust-cargo
+  "A Rust syntax checker using Cargo.
+
+This syntax checker requires Rust 1.17 or newer.  See URL
+`https://www.rust-lang.org'."
+  :command ("cargo"
+            (eval (if flycheck-rust-check-tests
+                      "test"
+                    "check"))
+            (eval (when flycheck-rust-check-tests
+                    "--no-run"))
+            (eval (when flycheck-rust-crate-type
+                    (concat "--" flycheck-rust-crate-type)))
+            ;; All crate targets except "lib" need a binary name
+            (eval (when (and flycheck-rust-crate-type
+                             (not (string= flycheck-rust-crate-type "lib")))
+                    flycheck-rust-binary-name))
+            (eval flycheck-cargo-check-args)
+            "--message-format=json")
+  :error-parser flycheck-parse-cargo-rustc
+  :error-filter (lambda (errors)
+                  ;; In Rust 1.25+, filenames are relative to the workspace
+                  ;; root.
+                  (let ((root (flycheck-rust-cargo-workspace-root)))
+                    (seq-do (lambda (err)
+                              (setf (flycheck-error-filename err)
+                                    (expand-file-name
+                                     (flycheck-error-filename err) root)))
+                            (flycheck-rust-error-filter errors))))
+  :error-explainer flycheck-rust-error-explainer
+  :modes rust-mode
+  :predicate flycheck-buffer-saved-p
+  :enabled flycheck-rust-manifest-directory
+  :working-directory (lambda (_) (flycheck-rust-manifest-directory))
+  :verify
+  (lambda (_)
+    (and buffer-file-name
+         (let* ((has-toml (flycheck-rust-manifest-directory))
+                (valid-crate-type (flycheck-rust-valid-crate-type-p
+                                   flycheck-rust-crate-type))
+                (need-binary-name
+                 (and flycheck-rust-crate-type
+                      (not (string= flycheck-rust-crate-type "lib")))))
+           (list
+            (flycheck-verification-result-new
+             :label "Cargo.toml"
+             :message (if has-toml "Found" "Missing")
+             :face (if has-toml 'success '(bold warning)))
+            (flycheck-verification-result-new
+             :label "Crate type"
+             :message (if valid-crate-type
+                          (format "%s" flycheck-rust-crate-type)
+                        (format "%s (invalid, should be one of 'lib', 'bin', \
+'test', 'example' or 'bench')"
+                                flycheck-rust-crate-type))
+             :face (if valid-crate-type 'success '(bold error)))
+            (flycheck-verification-result-new
+             :label "Binary name"
+             :message (cond
+                       ((not need-binary-name) "Not required")
+                       ((not flycheck-rust-binary-name) "Required")
+                       (t (format "%s" flycheck-rust-binary-name)))
+             :face (cond
+                    ((not need-binary-name) 'success)
+                    ((not flycheck-rust-binary-name) '(bold error))
+                    (t 'success))))))))
+
+(flycheck-define-checker rust
+  "A Rust syntax checker using Rust compiler.
+
+This syntax checker needs Rust 1.7 or newer.  See URL
+`https://www.rust-lang.org'."
+  :command ("rustc"
+            (option "--crate-type" flycheck-rust-crate-type)
+            "--error-format=json"
+            (option-flag "--test" flycheck-rust-check-tests)
+            (option-list "-L" flycheck-rust-library-path concat)
+            (eval flycheck-rust-args)
+            (eval (or flycheck-rust-crate-root
+                      (flycheck-substitute-argument 'source-original 'rust))))
+  :error-parser flycheck-parse-rustc
+  :error-filter flycheck-rust-error-filter
+  :error-explainer flycheck-rust-error-explainer
+  :modes rust-mode
+  :predicate flycheck-buffer-saved-p)
+
+(flycheck-define-checker rust-clippy
+  "A Rust syntax checker using clippy.
+
+See URL `https://github.com/rust-lang-nursery/rust-clippy'."
+  :command ("cargo" "+nightly" "clippy" "--message-format=json")
+  :error-parser flycheck-parse-cargo-rustc
+  :error-filter flycheck-rust-error-filter
+  :error-explainer flycheck-rust-error-explainer
+  :modes rust-mode
+  :predicate flycheck-buffer-saved-p
+  :enabled (lambda ()
+             (and (flycheck-rust-cargo-has-command-p "clippy")
+                  (flycheck-rust-manifest-directory)))
+  :working-directory (lambda (_) (flycheck-rust-manifest-directory))
+  :verify
+  (lambda (_)
+    (and buffer-file-name
+         (let ((has-toml (flycheck-rust-manifest-directory))
+               (has-clippy (flycheck-rust-cargo-has-command-p "clippy")))
+           (list
+            (flycheck-verification-result-new
+             :label "Clippy"
+             :message (if has-clippy "Found"
+                        "Cannot find the `cargo clippy' command")
+             :face (if has-clippy 'success '(bold warning)))
+            (flycheck-verification-result-new
+             :label "Cargo.toml"
+             :message (if has-toml "Found" "Missing")
+             :face (if has-toml 'success '(bold warning))))))))
+
+(defvar flycheck-sass-scss-cache-directory nil
+  "The cache directory for `sass' and `scss'.")
+
+(defun flycheck-sass-scss-cache-location ()
+  "Get the cache location for `sass' and `scss'.
+
+If no cache directory exists yet, create one and return it.
+Otherwise return the previously used cache directory."
+  (setq flycheck-sass-scss-cache-directory
+        (or flycheck-sass-scss-cache-directory
+            (make-temp-file "flycheck-sass-scss-cache" 'directory))))
+
+(flycheck-def-option-var flycheck-sass-compass nil sass
+  "Whether to enable the Compass CSS framework.
+
+When non-nil, enable the Compass CSS framework, via `--compass'."
+  :type 'boolean
+  :safe #'booleanp
+  :package-version '(flycheck . "0.16"))
+
+(flycheck-define-checker sass
+  "A Sass syntax checker using the Sass compiler.
+
+See URL `http://sass-lang.com'."
+  :command ("sass"
+            "--cache-location" (eval (flycheck-sass-scss-cache-location))
+            (option-flag "--compass" flycheck-sass-compass)
+            "--check" "--stdin")
+  :standard-input t
+  :error-patterns
+  ((error line-start
+          (or "Syntax error: " "Error: ")
+          (message (one-or-more not-newline)
+                   (zero-or-more "\n"
+                                 (one-or-more " ")
+                                 (one-or-more not-newline)))
+          (optional "\r") "\n" (one-or-more " ") "on line " line
+          " of standard input"
+          line-end)
+   (warning line-start
+            "WARNING: "
+            (message (one-or-more not-newline)
+                     (zero-or-more "\n"
+                                   (one-or-more " ")
+                                   (one-or-more not-newline)))
+            (optional "\r") "\n" (one-or-more " ") "on line " line
+            " of " (one-or-more not-newline)
+            line-end))
+  :modes sass-mode)
+
+(flycheck-def-config-file-var flycheck-sass-lintrc sass/scss-sass-lint
+                              ".sass-lint.yml"
+  :safe #'stringp
+  :package-version '(flycheck . "30"))
+
+(flycheck-define-checker sass/scss-sass-lint
+  "A SASS/SCSS syntax checker using sass-Lint.
+
+See URL `https://github.com/sasstools/sass-lint'."
+  :command ("sass-lint"
+            "--verbose"
+            "--no-exit"
+            "--format" "Checkstyle"
+            (config-file "--config" flycheck-sass-lintrc)
+            source)
+  :error-parser flycheck-parse-checkstyle
+  :modes (sass-mode scss-mode))
+
+(flycheck-define-checker scala
+  "A Scala syntax checker using the Scala compiler.
+
+See URL `https://www.scala-lang.org/'."
+  :command ("scalac" "-Ystop-after:parser" source)
+  :error-patterns
+  ((error line-start (file-name) ":" line ": error: " (message) line-end))
+  :modes scala-mode
+  :next-checkers ((warning . scala-scalastyle)))
+
+(flycheck-def-config-file-var flycheck-scalastylerc scala-scalastyle nil
+  :safe #'stringp
+  :package-version '(flycheck . "0.20"))
+
+(flycheck-define-checker scala-scalastyle
+  "A Scala style checker using scalastyle.
+
+Note that this syntax checker is not used if
+`flycheck-scalastylerc' is nil or refers to a non-existing file.
+
+See URL `http://www.scalastyle.org'."
+  :command ("scalastyle"
+            (config-file "-c" flycheck-scalastylerc)
+            source)
+  :error-patterns
+  ((error line-start "error file=" (file-name) " message="
+          (message) " line=" line (optional " column=" column) line-end)
+   (warning line-start "warning file=" (file-name) " message="
+            (message) " line=" line (optional " column=" column) line-end))
+  :error-filter (lambda (errors)
+                  (flycheck-sanitize-errors
+                   (flycheck-increment-error-columns errors)))
+  :modes scala-mode
+  :predicate
+  ;; Inhibit this syntax checker if the JAR or the configuration are unset or
+  ;; missing
+  (lambda () (and flycheck-scalastylerc
+                  (flycheck-locate-config-file flycheck-scalastylerc
+                                               'scala-scalastyle)))
+  :verify (lambda (checker)
+            (let ((config-file (and flycheck-scalastylerc
+                                    (flycheck-locate-config-file
+                                     flycheck-scalastylerc checker))))
+              (list
+               (flycheck-verification-result-new
+                :label "Configuration file"
+                :message (cond
+                          ((not flycheck-scalastylerc)
+                           "`flycheck-scalastyletrc' not set")
+                          ((not config-file)
+                           (format "file %s not found" flycheck-scalastylerc))
+                          (t (format "found at %s" config-file)))
+                :face (cond
+                       ((not flycheck-scalastylerc) '(bold warning))
+                       ((not config-file) '(bold error))
+                       (t 'success)))))))
+
+(flycheck-def-args-var flycheck-scheme-chicken-args scheme-chicken
+  :package-version '(flycheck . "32"))
+
+(flycheck-define-checker scheme-chicken
+  "A CHICKEN Scheme syntax checker using the CHICKEN compiler `csc'.
+
+See URL `http://call-cc.org/'."
+  :command ("csc" "-analyze-only" "-local"
+            (eval flycheck-scheme-chicken-args)
+            source)
+  :error-patterns
+  ((info line-start
+         "Note: " (zero-or-more not-newline) ":\n"
+         (one-or-more (any space)) "(" (file-name) ":" line ") " (message)
+         line-end)
+   (warning line-start
+            "Warning: " (zero-or-more not-newline) ":\n"
+            (one-or-more (any space)) "(" (file-name) ":" line ") " (message)
+            line-end)
+   (error line-start "Error: (line " line ") " (message) line-end)
+   (error line-start "Syntax error: (" (file-name) ":" line ")"
+          (zero-or-more not-newline) " - "
+          (message (one-or-more not-newline)
+                   (zero-or-more "\n"
+                                 (zero-or-more space)
+                                 (zero-or-more not-newline))
+                   (one-or-more space) "<--")
+          line-end)
+   (error line-start
+          "Error: " (zero-or-more not-newline) ":\n"
+          (one-or-more (any space)) "(" (file-name) ":" line ") " (message)
+          line-end))
+  :predicate
+  (lambda ()
+    ;; In `scheme-mode' we must check the current Scheme implementation
+    ;; being used
+    (and (boundp 'geiser-impl--implementation)
+         (eq geiser-impl--implementation 'chicken)))
+  :verify
+  (lambda (_checker)
+    (let ((geiser-impl (bound-and-true-p geiser-impl--implementation)))
+      (list
+       (flycheck-verification-result-new
+        :label "Geiser Implementation"
+        :message (cond
+                  ((eq geiser-impl 'chicken) "Chicken Scheme")
+                  (geiser-impl (format "Other: %s" geiser-impl))
+                  (t "Geiser not active"))
+        :face (cond
+               ((eq geiser-impl 'chicken) 'success)
+               (t '(bold error)))))))
+  :modes scheme-mode)
+
+(defconst flycheck-scss-lint-checkstyle-re
+  (rx "cannot load such file" (1+ not-newline) "scss_lint_reporter_checkstyle")
+  "Regular expression to parse missing checkstyle error.")
+
+(defun flycheck-parse-scss-lint (output checker buffer)
+  "Parse SCSS-Lint OUTPUT from CHECKER and BUFFER.
+
+Like `flycheck-parse-checkstyle', but catches errors about
+missing checkstyle reporter from SCSS-Lint."
+  (if (string-match-p flycheck-scss-lint-checkstyle-re output)
+      (list (flycheck-error-new-at
+             1 nil 'error "Checkstyle reporter for SCSS-Lint missing.
+Please run gem install scss_lint_reporter_checkstyle"
+             :checker checker
+             :buffer buffer
+             :filename (buffer-file-name buffer)))
+    (flycheck-parse-checkstyle output checker buffer)))
+
+(flycheck-def-config-file-var flycheck-scss-lintrc scss-lint ".scss-lint.yml"
+  :safe #'stringp
+  :package-version '(flycheck . "0.23"))
+
+(flycheck-define-checker scss-lint
+  "A SCSS syntax checker using SCSS-Lint.
+
+Needs SCSS-Lint 0.43.2 or newer.
+
+See URL `https://github.com/brigade/scss-lint'."
+  :command ("scss-lint"
+            "--require=scss_lint_reporter_checkstyle"
+            "--format=Checkstyle"
+            (config-file "--config" flycheck-scss-lintrc)
+            "--stdin-file-path" source-original "-")
+  :standard-input t
+  ;; We cannot directly parse Checkstyle XML, since for some mysterious reason
+  ;; SCSS-Lint doesn't have a built-in Checkstyle reporter, and instead ships it
+  ;; as an addon which might not be installed.  We use a custom error parser to
+  ;; check whether the addon is missing and turn that into a special kind of
+  ;; Flycheck error.
+  :error-parser flycheck-parse-scss-lint
+  :modes scss-mode
+  :verify
+  (lambda (checker)
+    (let* ((executable (flycheck-find-checker-executable checker))
+           (reporter-missing
+            (and executable
+                 (with-temp-buffer
+                   (call-process executable nil t nil
+                                 "--require=scss_lint_reporter_checkstyle")
+                   (goto-char (point-min))
+                   (re-search-forward
+                    flycheck-scss-lint-checkstyle-re
+                    nil 'no-error)))))
+      (when executable
+        (list
+         (flycheck-verification-result-new
+          :label "checkstyle reporter"
+          :message (if reporter-missing
+                       "scss_lint_reporter_checkstyle missing"
+                     "present")
+          :face (if reporter-missing
+                    '(bold error)
+                  'success)))))))
+
+(flycheck-define-checker scss-stylelint
+  "A SCSS syntax and style checker using stylelint.
+
+See URL `http://stylelint.io/'."
+  :command ("stylelint"
+            (eval flycheck-stylelint-args)
+            "--syntax" "scss"
+            (option-flag "--quiet" flycheck-stylelint-quiet)
+            (config-file "--config" flycheck-stylelintrc))
+  :standard-input t
+  :error-parser flycheck-parse-stylelint
+  :modes (scss-mode))
+
+(flycheck-def-option-var flycheck-scss-compass nil scss
+  "Whether to enable the Compass CSS framework.
+
+When non-nil, enable the Compass CSS framework, via `--compass'."
+  :type 'boolean
+  :safe #'booleanp
+  :package-version '(flycheck . "0.16"))
+
+(flycheck-define-checker scss
+  "A SCSS syntax checker using the SCSS compiler.
+
+See URL `http://sass-lang.com'."
+  :command ("scss"
+            "--cache-location" (eval (flycheck-sass-scss-cache-location))
+            (option-flag "--compass" flycheck-scss-compass)
+            "--check" "--stdin")
+  :standard-input t
+  :error-patterns
+  ((error line-start
+          (or "Syntax error: " "Error: ")
+          (message (one-or-more not-newline)
+                   (zero-or-more "\n"
+                                 (one-or-more " ")
+                                 (one-or-more not-newline)))
+          (optional "\r") "\n" (one-or-more " ") "on line " line
+          " of standard input"
+          line-end)
+   (warning line-start
+            "WARNING: "
+            (message (one-or-more not-newline)
+                     (zero-or-more "\n"
+                                   (one-or-more " ")
+                                   (one-or-more not-newline)))
+            (optional "\r") "\n" (one-or-more " ") "on line " line
+            " of an unknown file"
+            line-end))
+  :modes scss-mode)
+
+(flycheck-def-args-var flycheck-sh-bash-args (sh-bash)
+  :package-version '(flycheck . "32"))
+
+(flycheck-define-checker sh-bash
+  "A Bash syntax checker using the Bash shell.
+
+See URL `http://www.gnu.org/software/bash/'."
+  :command ("bash" "--norc" "-n"
+            (eval flycheck-sh-bash-args)
+            "--")
+  :standard-input t
+  :error-patterns
+  ((error line-start
+          ;; The name/path of the bash executable
+          (one-or-more (not (any ":"))) ":"
+          ;; A label "line", possibly localized
+          (one-or-more (not (any digit)))
+          line (zero-or-more " ") ":" (zero-or-more " ")
+          (message) line-end))
+  :modes sh-mode
+  :predicate (lambda () (eq sh-shell 'bash))
+  :next-checkers ((warning . sh-shellcheck)))
+
+(flycheck-define-checker sh-posix-dash
+  "A POSIX Shell syntax checker using the Dash shell.
+
+See URL `http://gondor.apana.org.au/~herbert/dash/'."
+  :command ("dash" "-n")
+  :standard-input t
+  :error-patterns
+  ((error line-start (one-or-more (not (any ":"))) ": " line ": " (message)))
+  :modes sh-mode
+  :predicate (lambda () (eq sh-shell 'sh))
+  :next-checkers ((warning . sh-shellcheck)))
+
+(flycheck-define-checker sh-posix-bash
+  "A POSIX Shell syntax checker using the Bash shell.
+
+See URL `http://www.gnu.org/software/bash/'."
+  :command ("bash" "--posix" "--norc" "-n" "--")
+  :standard-input t
+  :error-patterns
+  ((error line-start
+          ;; The name/path of the bash executable
+          (one-or-more (not (any ":"))) ":"
+          ;; A label "line", possibly localized
+          (one-or-more (not (any digit)))
+          line (zero-or-more " ") ":" (zero-or-more " ")
+          (message) line-end))
+  :modes sh-mode
+  :predicate (lambda () (eq sh-shell 'sh))
+  :next-checkers ((warning . sh-shellcheck)))
+
+(flycheck-define-checker sh-zsh
+  "A Zsh syntax checker using the Zsh shell.
+
+See URL `http://www.zsh.org/'."
+  :command ("zsh" "--no-exec" "--no-globalrcs" "--no-rcs" source)
+  :error-patterns
+  ((error line-start (file-name) ":" line ": " (message) line-end))
+  :modes sh-mode
+  :predicate (lambda () (eq sh-shell 'zsh))
+  :next-checkers ((warning . sh-shellcheck)))
+
+(defconst flycheck-shellcheck-supported-shells '(bash ksh88 sh)
+  "Shells supported by ShellCheck.")
+
+(flycheck-def-option-var flycheck-shellcheck-excluded-warnings nil sh-shellcheck
+  "A list of excluded warnings for ShellCheck.
+
+The value of this variable is a list of strings, where each
+string is a warning code to be excluded from ShellCheck reports.
+By default, no warnings are excluded."
+  :type '(repeat :tag "Excluded warnings"
+                 (string :tag "Warning code"))
+  :safe #'flycheck-string-list-p
+  :package-version '(flycheck . "0.21"))
+
+(flycheck-def-option-var flycheck-shellcheck-follow-sources t sh-shellcheck
+  "Whether to follow external sourced files in scripts.
+
+Shellcheck will follow and parse sourced files so long as a
+pre-runtime resolvable path to the file is present.  This can
+either be part of the source command itself:
+   source /full/path/to/file.txt
+or added as a shellcheck directive before the source command:
+   # shellcheck source=/full/path/to/file.txt."
+  :type 'boolean
+  :safe #'booleanp
+  :package-version '(flycheck . "31"))
+
+(flycheck-define-checker sh-shellcheck
+  "A shell script syntax and style checker using Shellcheck.
+
+See URL `https://github.com/koalaman/shellcheck/'."
+  :command ("shellcheck"
+            "--format" "checkstyle"
+            "--shell" (eval (symbol-name sh-shell))
+            (option-flag "--external-sources"
+                         flycheck-shellcheck-follow-sources)
+            (option "--exclude" flycheck-shellcheck-excluded-warnings list
+                    flycheck-option-comma-separated-list)
+            "-")
+  :standard-input t
+  :error-parser flycheck-parse-checkstyle
+  :error-filter
+  (lambda (errors)
+    (flycheck-remove-error-file-names
+     "-" (flycheck-dequalify-error-ids errors)))
+  :modes sh-mode
+  :predicate (lambda () (memq sh-shell flycheck-shellcheck-supported-shells))
+  :verify (lambda (_)
+            (let ((supports-shell (memq sh-shell
+                                        flycheck-shellcheck-supported-shells)))
+              (list
+               (flycheck-verification-result-new
+                :label (format "Shell %s supported" sh-shell)
+                :message (if supports-shell "yes" "no")
+                :face (if supports-shell 'success '(bold warning)))))))
+
+(flycheck-define-checker slim
+  "A Slim syntax checker using the Slim compiler.
+
+See URL `http://slim-lang.com'."
+  :command ("slimrb" "--compile")
+  :standard-input t
+  :error-patterns
+  ((error line-start
+          "Slim::Parser::SyntaxError:" (message) (optional "\r") "\n  "
+          "STDIN, Line " line (optional ", Column " column)
+          line-end))
+  :modes slim-mode
+  :next-checkers ((warning . slim-lint)))
+
+(flycheck-define-checker slim-lint
+  "A Slim linter.
+
+See URL `https://github.com/sds/slim-lint'."
+  :command ("slim-lint" "--reporter=checkstyle" source)
+  :error-parser flycheck-parse-checkstyle
+  :modes slim-mode)
+
+(flycheck-define-checker sql-sqlint
+  "A SQL syntax checker using the sqlint tool.
+
+See URL `https://github.com/purcell/sqlint'."
+  :command ("sqlint")
+  :standard-input t
+  :error-patterns
+  ((warning line-start "stdin:" line ":" column ":WARNING "
+            (message (one-or-more not-newline)
+                     (zero-or-more "\n"
+                                   (one-or-more "  ")
+                                   (one-or-more not-newline)))
+            line-end)
+   (error line-start "stdin:" line ":" column ":ERROR "
+          (message (one-or-more not-newline)
+                   (zero-or-more "\n"
+                                 (one-or-more "  ")
+                                 (one-or-more not-newline)))
+          line-end))
+  :modes (sql-mode))
+
+(flycheck-define-checker systemd-analyze
+  "A systemd unit checker using systemd-analyze(1).
+
+See URL
+`https://www.freedesktop.org/software/systemd/man/systemd-analyze.html'."
+  :command ("systemd-analyze" "verify" source)
+  :error-patterns
+  ((error line-start "[" (file-name) ":" line "] " (message) line-end))
+  :modes (systemd-mode))
+
+(flycheck-def-config-file-var flycheck-chktexrc tex-chktex ".chktexrc"
+  :safe #'stringp)
+
+(flycheck-define-checker tcl-nagelfar
+  "An extensible tcl syntax checker
+
+See URL `http://nagelfar.sourceforge.net/'."
+  :command ("nagelfar" "-H" source)
+  :error-patterns
+  ;; foo.tcl: 29: E Wrong number of arguments (4) to "set"
+  ;; foo.tcl: 29: W Expr without braces
+  ((info    line-start (file-name) ": " line ": N " (message) line-end)
+   (warning line-start (file-name) ": " line ": W " (message) line-end)
+   (error   line-start (file-name) ": " line ": E " (message) line-end))
+  :modes tcl-mode)
+
+(flycheck-define-checker tex-chktex
+  "A TeX and LaTeX syntax and style checker using chktex.
+
+See URL `http://www.nongnu.org/chktex/'."
+  :command ("chktex"
+            (config-file "--localrc" flycheck-chktexrc)
+            ;; Compact error messages, and no version information, and execute
+            ;; \input statements
+            "--verbosity=0" "--quiet" "--inputfiles")
+  :standard-input t
+  :error-patterns
+  ((warning line-start "stdin:" line ":" column ":"
+            (id (one-or-more digit)) ":" (message) line-end))
+  :error-filter
+  (lambda (errors)
+    (flycheck-sanitize-errors (flycheck-increment-error-columns errors)))
+  :modes (latex-mode plain-tex-mode))
+
+(flycheck-define-checker tex-lacheck
+  "A LaTeX syntax and style checker using lacheck.
+
+See URL `http://www.ctan.org/pkg/lacheck'."
+  :command ("lacheck" source-inplace)
+  :error-patterns
+  ((warning line-start
+            "\"" (file-name) "\", line " line ": " (message)
+            line-end))
+  :modes latex-mode)
+
+(flycheck-define-checker texinfo
+  "A Texinfo syntax checker using makeinfo.
+
+See URL `http://www.gnu.org/software/texinfo/'."
+  :command ("makeinfo" "-o" null-device "-")
+  :standard-input t
+  :error-patterns
+  ((warning line-start
+            "-:" line (optional ":" column) ": " "warning: " (message)
+            line-end)
+   (error line-start
+          "-:" line (optional ":" column) ": " (message)
+          line-end))
+  :modes texinfo-mode)
+
+(flycheck-def-config-file-var flycheck-typescript-tslint-config
+    typescript-tslint "tslint.json"
+  :safe #'stringp
+  :package-version '(flycheck . "27"))
+
+(flycheck-def-option-var flycheck-typescript-tslint-rulesdir
+    nil typescript-tslint
+  "The directory of custom rules for TSLint.
+
+The value of this variable is either a string containing the path
+to a directory with custom rules, or nil, to not give any custom
+rules to TSLint.
+
+Refer to the TSLint manual at URL
+`http://palantir.github.io/tslint/usage/cli/'
+for more information about the custom directory."
+  :type '(choice (const :tag "No custom rules directory" nil)
+                 (directory :tag "Custom rules directory"))
+  :safe #'stringp
+  :package-version '(flycheck . "27"))
+
+(flycheck-def-args-var flycheck-tslint-args (typescript-tslint)
+  :package-version '(flycheck . "31"))
+
+(flycheck-define-checker typescript-tslint
+  "TypeScript style checker using TSLint.
+
+Note that this syntax checker is not used if
+`flycheck-typescript-tslint-config' is nil or refers to a
+non-existing file.
+
+See URL `https://github.com/palantir/tslint'."
+  :command ("tslint" "--format" "json"
+            (config-file "--config" flycheck-typescript-tslint-config)
+            (option "--rules-dir" flycheck-typescript-tslint-rulesdir)
+            (eval flycheck-tslint-args)
+            source-inplace)
+  :error-parser flycheck-parse-tslint
+  :modes (typescript-mode))
+
+(flycheck-def-option-var flycheck-verilator-include-path nil verilog-verilator
+  "A list of include directories for Verilator.
+
+The value of this variable is a list of strings, where each
+string is a directory to add to the include path of Verilator.
+Relative paths are relative to the file being checked."
+  :type '(repeat (directory :tag "Include directory"))
+  :safe #'flycheck-string-list-p
+  :package-version '(flycheck . "0.24"))
+
+(flycheck-define-checker verilog-verilator
+  "A Verilog syntax checker using the Verilator Verilog HDL simulator.
+
+See URL `https://www.veripool.org/wiki/verilator'."
+  :command ("verilator" "--lint-only" "-Wall"
+            (option-list "-I" flycheck-verilator-include-path concat)
+            source)
+  :error-patterns
+  ((warning line-start "%Warning-" (zero-or-more not-newline) ": "
+            (file-name) ":" line ": " (message) line-end)
+   (error line-start "%Error: " (file-name) ":"
+          line ": " (message) line-end))
+  :modes verilog-mode)
+
+(flycheck-def-option-var flycheck-ghdl-language-standard nil vhdl-ghdl
+  "The language standard to use in GHDL.
+
+The value of this variable is either a string denoting a language
+standard, or nil, to use the default standard.  When non-nil,
+pass the language standard via the `--std' option."
+  :type '(choice (const :tag "Default standard" nil)
+                 (string :tag "Language standard"))
+  :safe #'stringp
+  :package-version '(flycheck . "32"))
+(make-variable-buffer-local 'flycheck-ghdl-language-standard)
+
+(flycheck-def-option-var flycheck-ghdl-workdir nil vhdl-ghdl
+  "The directory to use for the file library
+
+The value of this variable is either a string with the directory
+to use for the file library, or nil, to use the default value.
+When non-nil, pass the directory via the `--workdir' option."
+  :type '(choice (const :tag "Default directory" nil)
+                 (string :tag "Directory for the file library"))
+  :safe #'stringp
+  :package-version '(flycheck . "32"))
+(make-variable-buffer-local 'flycheck-ghdl-workdir)
+
+(flycheck-define-checker vhdl-ghdl
+  "A VHDL syntax checker using GHDL.
+
+See URL `https://github.com/ghdl/ghdl'."
+  :command ("ghdl"
+            "-s" ; only do the syntax checking
+            (option "--std=" flycheck-ghdl-language-standard concat)
+            (option "--workdir=" flycheck-ghdl-workdir concat)
+            source)
+  :error-patterns
+  ((error line-start (file-name) ":" line ":" column ": " (message) line-end))
+  :modes vhdl-mode)
+
+(flycheck-def-option-var flycheck-xml-xmlstarlet-xsd-path nil xml-xmlstarlet
+  "An XSD schema to validate against."
+  :type '(file :tag "XSD schema")
+  :safe #'stringp
+  :package-version '(flycheck . "31"))
+
+(flycheck-define-checker xml-xmlstarlet
+  "A XML syntax checker and validator using the xmlstarlet utility.
+
+See URL `http://xmlstar.sourceforge.net/'."
+  ;; Validate standard input with verbose error messages, and do not dump
+  ;; contents to standard output
+  :command ("xmlstarlet" "val" "--err" "--quiet"
+            (option "--xsd" flycheck-xml-xmlstarlet-xsd-path)
+            "-")
+  :standard-input t
+  :error-patterns
+  ((error line-start "-:" line "." column ": " (message) line-end))
+  :modes (xml-mode nxml-mode))
+
+(flycheck-def-option-var flycheck-xml-xmllint-xsd-path nil xml-xmllint
+  "An XSD schema to validate against."
+  :type '(file :tag "XSD schema")
+  :safe #'stringp
+  :package-version '(flycheck . "31"))
+
+(flycheck-define-checker xml-xmllint
+  "A XML syntax checker and validator using the xmllint utility.
+
+The xmllint is part of libxml2, see URL
+`http://www.xmlsoft.org/'."
+  :command ("xmllint" "--noout"
+            (option "--schema" flycheck-xml-xmllint-xsd-path)
+            "-")
+  :standard-input t
+  :error-patterns
+  ((error line-start "-:" line ": " (message) line-end))
+  :modes (xml-mode nxml-mode))
+
+(flycheck-define-checker yaml-jsyaml
+  "A YAML syntax checker using JS-YAML.
+
+See URL `https://github.com/nodeca/js-yaml'."
+  :command ("js-yaml")
+  :standard-input t
+  :error-patterns
+  ((error line-start
+          (or "JS-YAML" "YAMLException") ": "
+          (message) " at line " line ", column " column ":"
+          line-end))
+  :modes yaml-mode
+  :next-checkers ((warning . cwl)))
+
+(flycheck-define-checker yaml-ruby
+  "A YAML syntax checker using Ruby's YAML parser.
+
+This syntax checker uses the YAML parser from Ruby's standard
+library.
+
+See URL `http://www.ruby-doc.org/stdlib-2.0.0/libdoc/yaml/rdoc/YAML.html'."
+  :command ("ruby" "-ryaml" "-e" "begin;
+   YAML.load(STDIN); \
+ rescue Exception => e; \
+   STDERR.puts \"stdin:#{e}\"; \
+ end")
+  :standard-input t
+  :error-patterns
+  ((error line-start "stdin:" (zero-or-more not-newline) ":" (message)
+          "at line " line " column " column line-end))
+  :modes yaml-mode
+  :next-checkers ((warning . cwl)))
+
+(provide 'flycheck)
+
+;; Local Variables:
+;; coding: utf-8
+;; indent-tabs-mode: nil
+;; End:
+
+;;; flycheck.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/flycheck-20180720.247/flycheck.elc b/configs/shared/emacs/.emacs.d/elpa/flycheck-20180720.247/flycheck.elc
new file mode 100644
index 0000000000..2de059ed24
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/flycheck-20180720.247/flycheck.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/flycheck-flow-20180216.1156/flycheck-flow-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/flycheck-flow-20180216.1156/flycheck-flow-autoloads.el
new file mode 100644
index 0000000000..1da262674d
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/flycheck-flow-20180216.1156/flycheck-flow-autoloads.el
@@ -0,0 +1,16 @@
+;;; flycheck-flow-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil nil ("flycheck-flow.el") (23377 61676 259723
+;;;;;;  440000))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; flycheck-flow-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/flycheck-flow-20180216.1156/flycheck-flow-pkg.el b/configs/shared/emacs/.emacs.d/elpa/flycheck-flow-20180216.1156/flycheck-flow-pkg.el
new file mode 100644
index 0000000000..6980ad96ee
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/flycheck-flow-20180216.1156/flycheck-flow-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "flycheck-flow" "20180216.1156" "Support Flow in flycheck" '((flycheck "0.18") (json "1.4")))
diff --git a/configs/shared/emacs/.emacs.d/elpa/flycheck-flow-20180216.1156/flycheck-flow.el b/configs/shared/emacs/.emacs.d/elpa/flycheck-flow-20180216.1156/flycheck-flow.el
new file mode 100644
index 0000000000..866e44fb09
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/flycheck-flow-20180216.1156/flycheck-flow.el
@@ -0,0 +1,174 @@
+;;; flycheck-flow.el --- Support Flow in flycheck
+
+;; Copyright (C) 2015 Lorenzo Bolla <lbolla@gmail.com>
+;;
+;; Author: Lorenzo Bolla <lbolla@gmail.com>
+;; Created: 16 Septermber 2015
+;; Version: 1.1
+;; Package-Version: 20180216.1156
+;; Package-Requires: ((flycheck "0.18") (json "1.4"))
+
+;;; Commentary:
+
+;; This package adds support for flow to flycheck.  It requires
+;; flow>=0.20.0.
+
+;; To use it, add to your init.el:
+
+;; (require 'flycheck-flow)
+;; (add-hook 'javascript-mode-hook 'flycheck-mode)
+
+;; You want to use flow in conjunction with other JS checkers.
+;; E.g. to use with gjslint, add this to your init.el
+;; (flycheck-add-next-checker 'javascript-gjslint 'javascript-flow)
+
+;; For coverage warnings add this to your init.el
+;; (flycheck-add-next-checker 'javascript-flow 'javascript-flow-coverage)
+
+;;; License:
+
+;; This file is not part of GNU Emacs.
+;; However, it is distributed under the same license.
+
+;; 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, 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; see the file COPYING.  If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Code:
+(require 'flycheck)
+(require 'json)
+
+(flycheck-def-args-var flycheck-javascript-flow-args javascript-flow)
+(customize-set-variable 'flycheck-javascript-flow-args '())
+
+(defun flycheck-flow--parse-json (output checker buffer)
+  "Parse flycheck json OUTPUT generated by CHECKER on BUFFER."
+  (let* ((json-object-type 'alist)
+         (json-array-type 'list)
+         (flow-json-output (json-read-from-string output))
+         (flow-errors-list (cdr (assq 'errors flow-json-output)))
+         message-kind
+         message-level
+         message-code-reason
+         message-filename
+         message-line
+         message-column
+         message-descr
+         errors)
+    (dolist (error-message flow-errors-list)
+      ;; The structure for each `error-message' in `flow-errors-list' is like this:
+      ;; ((kind . `message-kind')
+      ;;  (level . `message-level')
+      ;;  (message ((descr . `message-code-reason')
+      ;;            (loc (source . `message-filename')
+      ;;                 (start (line . `message-line') (column . `message-column'))))
+      ;;           ((descr . `message-descr'))))
+      (let-alist error-message
+        (setq message-kind .kind)
+        (setq message-level (intern .level))
+
+        (let-alist (car .message)
+          (setq message-code-reason .descr
+                message-filename .loc.source
+                message-line .loc.start.line
+                message-descr .descr
+                message-column .loc.start.column))
+
+        (let-alist (car (cdr .message))
+          (when (string= .type "Comment")
+            (setq message-descr .descr))))
+
+      (when (string= message-kind "parse")
+        (setq message-descr message-kind))
+
+      (push (flycheck-error-new-at
+             message-line
+             message-column
+             message-level
+             message-descr
+             :id message-code-reason
+             :checker checker
+             :buffer buffer
+             :filename message-filename)
+            errors))
+    (nreverse errors)))
+
+(defun flycheck-flow--predicate ()
+  "Shall we run the checker?"
+  (and
+   buffer-file-name
+   (file-exists-p buffer-file-name)
+   (locate-dominating-file buffer-file-name ".flowconfig")))
+
+(flycheck-define-checker javascript-flow
+    "A JavaScript syntax and style checker using Flow.
+
+See URL `http://flowtype.org/'."
+    :command (
+              "flow"
+              "check-contents"
+              (eval flycheck-javascript-flow-args)
+              "--json"
+              "--from" "emacs"
+              "--color=never"
+              source-original)
+    :standard-input t
+    :predicate flycheck-flow--predicate
+    :error-parser flycheck-flow--parse-json
+    ;; js3-mode doesn't support jsx
+    :modes (js-mode js-jsx-mode js2-mode js2-jsx-mode js3-mode web-mode rjsx-mode))
+
+(flycheck-define-checker javascript-flow-coverage
+  "A coverage checker for Flow.
+
+See URL `http://flowtype.org/'."
+  :command (
+            "flow"
+            "coverage"
+            (eval flycheck-javascript-flow-args)
+            "--json"
+            "--from" "emacs"
+            "--path" source-original)
+  :standard-input t
+  :predicate flycheck-flow--predicate
+  :error-parser
+  (lambda (output checker buffer)
+    (let* ((json-array-type 'list)
+           (json-object-type 'alist)
+           (locs (condition-case nil
+                     (let ((report (json-read-from-string output)))
+                       (alist-get 'uncovered_locs (alist-get 'expressions report)))
+                   (error nil))))
+      (mapcar (lambda (loc)
+                (let ((start (alist-get 'start loc))
+                      (end (alist-get 'end loc)))
+                  (flycheck-error-new
+                   :buffer buffer
+                   :checker 'javascript-flow-coverage
+                   :filename buffer-file-name
+                   :line (alist-get 'line start)
+                   :column (alist-get 'column start)
+                   :message (format "no-coverage-to (%s . %s)"
+                                    (alist-get 'line end)
+                                    (alist-get 'column end))
+                   :level 'warning)))
+              locs)))
+  ;; js3-mode doesn't support jsx
+  :modes (js-mode js-jsx-mode js2-mode js2-jsx-mode js3-mode rjsx-mode))
+
+(add-to-list 'flycheck-checkers 'javascript-flow)
+(add-to-list 'flycheck-checkers 'javascript-flow-coverage t)
+
+(provide 'flycheck-flow)
+;;; flycheck-flow.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/flycheck-flow-20180216.1156/flycheck-flow.elc b/configs/shared/emacs/.emacs.d/elpa/flycheck-flow-20180216.1156/flycheck-flow.elc
new file mode 100644
index 0000000000..b468ad4ff1
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/flycheck-flow-20180216.1156/flycheck-flow.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/general-20180628.1112/general-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/general-20180628.1112/general-autoloads.el
new file mode 100644
index 0000000000..707d6a25b7
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/general-20180628.1112/general-autoloads.el
@@ -0,0 +1,368 @@
+;;; general-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "general" "general.el" (23377 60738 675521
+;;;;;;  86000))
+;;; Generated autoloads from general.el
+
+(autoload 'general-define-key "general" "\
+The primary key definition function provided by general.el.
+
+Define MAPS, optionally using DEFINER, in the keymap(s) corresponding to STATES
+and KEYMAPS.
+
+MAPS consists of paired keys (vectors or strings; also see
+`general-implicit-kbd') and definitions (those mentioned in `define-key''s
+docstring and general.el's \"extended\" definitions). All pairs (when not
+ignored) will be recorded and can be later displayed with
+`general-describe-keybindings'.
+
+If DEFINER is specified, a custom key definer will be used to bind MAPS. See
+general.el's documentation/README for more information.
+
+Unlike with normal key definitions functions, the keymaps in KEYMAPS should be
+quoted (this allows using the keymap name for other purposes, e.g. deferring
+keybindings if the keymap symbol is not bound, optionally inferring the
+corresponding major mode for a symbol by removing \"-map\" for :which-key,
+easily storing the keymap name for use with `general-describe-keybindings',
+etc.). Note that general.el provides other key definer macros that do not
+require quoting keymaps.
+
+STATES corresponds to the evil state(s) to bind the keys in. Non-evil users
+should not set STATES. When STATES is non-nil, `evil-define-key*' will be
+used (the evil auxiliary keymaps corresponding STATES and KEYMAPS will be used);
+otherwise `define-key' will be used (unless DEFINER is specified). KEYMAPS
+defaults to 'global. There is also 'local, which create buffer-local
+keybindings for both evil and non-evil keybindings. There are other special,
+user-alterable \"shorthand\" symbols for keymaps and states (see
+`general-keymap-aliases' and `general-state-aliases').
+
+Note that STATES and KEYMAPS can either be lists or single symbols. If any
+keymap does not exist, those keybindings will be deferred until the keymap does
+exist, so using `eval-after-load' is not necessary with this function.
+
+PREFIX corresponds to a key to prefix keys in MAPS with and defaults to none. To
+bind/unbind a key specified with PREFIX, \"\" can be specified as a key in
+MAPS (e.g. ...:prefix \"SPC\" \"\" nil... will unbind space).
+
+The keywords in this paragraph are only useful for evil users. If
+NON-NORMAL-PREFIX is specified, this prefix will be used instead of PREFIX for
+states in `general-non-normal-states' (e.g. the emacs and insert states). This
+argument will only have an effect if one of these states is in STATES or if
+corresponding global keymap (e.g. `evil-insert-state-map') is in KEYMAPS.
+Alternatively, GLOBAL-PREFIX can be used with PREFIX and/or NON-NORMAL-PREFIX to
+bind keys in all states under the specified prefix. Like with NON-NORMAL-PREFIX,
+GLOBAL-PREFIX will prevent PREFIX from applying to `general-non-normal-states'.
+INFIX can be used to append a string to all of the specified prefixes. This is
+potentially useful when you are using GLOBAL-PREFIX and/or NON-NORMAL-PREFIX so
+that you can sandwich keys in between all the prefixes and the specified keys in
+MAPS. This may be particularly useful if you are using default prefixes in a
+wrapper function/macro so that you can add to them without needing to re-specify
+all of them. If none of the other prefix keyword arguments are specified, INFIX
+will have no effect.
+
+If PREFIX-COMMAND or PREFIX-MAP is specified, a prefix command and/or keymap
+will be created. PREFIX-NAME can be additionally specified to set the keymap
+menu name/prompt. If PREFIX-COMMAND is specified, `define-prefix-command' will
+be used. Otherwise, only a prefix keymap will be created. Previously created
+prefix commands/keymaps will never be redefined/cleared. All prefixes (including
+the INFIX key, if specified) will then be bound to PREFIX-COMMAND or PREFIX-MAP.
+If the user did not specify any PREFIX or manually specify any KEYMAPS, general
+will bind all MAPS in the prefix keymap corresponding to either PREFIX-MAP or
+PREFIX-COMMAND instead of in the default keymap.
+
+PREDICATE corresponds to a predicate to check to determine whether a definition
+should be active (e.g. \":predicate '(eobp)\"). Definitions created with a
+predicate will only be active when the predicate is true. When the predicate is
+false, key lookup will continue to search for a match in lower-precedence
+keymaps.
+
+In addition to the normal definitions supported by `define-key', general.el also
+provides \"extended\" definitions, which are plists containing the normal
+definition as well as other keywords. For example, PREDICATE can be specified
+globally or locally in an extended definition. New global (~general-define-key~)
+and local (extended definition) keywords can be added by the user. See
+`general-extended-def-keywords' and general.el's documentation/README for more
+information.
+
+PACKAGE is the global version of the extended definition keyword that specifies
+the package a keymap is defined in (used for \"autoloading\" keymaps)
+
+PROPERTIES, REPEAT, and JUMP are the global versions of the extended definition
+keywords used for adding evil command properties to commands.
+
+MAJOR-MODES, WK-MATCH-KEYS, WK-MATCH-BINDINGS, and WK-FULL-KEYS are the
+corresponding global versions of which-key extended definition keywords. They
+will only have an effect for extended definitions that specify :which-key or
+:wk. See the section on extended definitions in the general.el
+documentation/README for more information.
+
+LISPY-PLIST and WORF-PLIST are the global versions of extended definition
+keywords that are used for each corresponding custom DEFINER.
+
+\(fn &rest MAPS &key DEFINER (STATES general-default-states) (KEYMAPS general-default-keymaps KEYMAPS-SPECIFIED-P) (PREFIX general-default-prefix) (NON-NORMAL-PREFIX general-default-non-normal-prefix) (GLOBAL-PREFIX general-default-global-prefix) INFIX PREFIX-COMMAND PREFIX-MAP PREFIX-NAME PREDICATE PACKAGE PROPERTIES REPEAT JUMP MAJOR-MODES (WK-MATCH-KEYS t) (WK-MATCH-BINDING t) (WK-FULL-KEYS t) LISPY-PLIST WORF-PLIST &allow-other-keys)" nil nil)
+
+(autoload 'general-emacs-define-key "general" "\
+A wrapper for `general-define-key' that is similar to `define-key'.
+It has a positional argument for KEYMAPS (that will not be overridden by a later
+:keymaps argument). Besides this, it acts the same as `general-define-key', and
+ARGS can contain keyword arguments in addition to keybindings. This can
+basically act as a drop-in replacement for `define-key', and unlike with
+`general-define-key', KEYMAPS does not need to be quoted.
+
+\(fn KEYMAPS &rest ARGS)" nil t)
+
+(function-put 'general-emacs-define-key 'lisp-indent-function '1)
+
+(autoload 'general-evil-define-key "general" "\
+A wrapper for `general-define-key' that is similar to `evil-define-key'.
+It has positional arguments for STATES and KEYMAPS (that will not be overridden
+by a later :keymaps or :states argument). Besides this, it acts the same as
+`general-define-key', and ARGS can contain keyword arguments in addition to
+keybindings. This can basically act as a drop-in replacement for
+`evil-define-key', and unlike with `general-define-key', KEYMAPS does not need
+to be quoted.
+
+\(fn STATES KEYMAPS &rest ARGS)" nil t)
+
+(function-put 'general-evil-define-key 'lisp-indent-function '2)
+
+(autoload 'general-def "general" "\
+General definer that takes a variable number of positional arguments in ARGS.
+This macro will act as `general-define-key', `general-emacs-define-key', or
+`general-evil-define-key' based on how many of the initial arguments do not
+correspond to keybindings. All quoted and non-quoted lists and symbols before
+the first string, vector, or keyword are considered to be positional arguments.
+This means that you cannot use a function or variable for a key that starts
+immediately after the positional arguments. If you need to do this, you should
+use one of the definers that `general-def' dispatches to or explicitly separate
+the positional arguments from the maps with a bogus keyword pair like
+\":start-maps t\"
+
+\(fn &rest ARGS)" nil t)
+
+(function-put 'general-def 'lisp-indent-function 'defun)
+
+(autoload 'general-create-definer "general" "\
+A helper macro to create wrappers for `general-def'.
+This can be used to create key definers that will use a certain keymap, evil
+state, prefix key, etc. by default. NAME is the wrapper name and DEFAULTS are
+the default arguments. WRAPPING can also be optionally specified to use a
+different definer than `general-def'. It should not be quoted.
+
+\(fn NAME &rest DEFAULTS &key WRAPPING &allow-other-keys)" nil t)
+
+(function-put 'general-create-definer 'lisp-indent-function 'defun)
+
+(autoload 'general-defs "general" "\
+A wrapper that splits into multiple `general-def's.
+Each consecutive grouping of positional argument followed by keyword/argument
+pairs (having only one or the other is fine) marks the start of a new section.
+Each section corresponds to one use of `general-def'. This means that settings
+only apply to the keybindings that directly follow.
+
+\(fn &rest ARGS)" nil t)
+
+(function-put 'general-defs 'lisp-indent-function 'defun)
+
+(autoload 'general-unbind "general" "\
+A wrapper for `general-def' to unbind multiple keys simultaneously.
+Insert after all keys in ARGS before passing ARGS to `general-def.' \":with
+ #'func\" can optionally specified to use a custom function instead (e.g.
+ `ignore').
+
+\(fn &rest ARGS)" nil t)
+
+(function-put 'general-unbind 'lisp-indent-function 'defun)
+
+(autoload 'general-describe-keybindings "general" "\
+Show all keys that have been bound with general in an org buffer.
+Any local keybindings will be shown first followed by global keybindings.
+With a non-nil prefix ARG only show bindings in active maps.
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'general-key "general" "\
+Act as KEY's definition in the current context.
+This uses an extended menu item's capability of dynamically computing a
+definition. It is recommended over `general-simulate-key' wherever possible. KEY
+should be a string given in `kbd' notation and should correspond to a single
+definition (as opposed to a sequence of commands). When STATE is specified, look
+up KEY with STATE as the current evil state. When specified, DOCSTRING will be
+the menu item's name/description. ACCEPT-DEFAULT, NO-REMAP, and POSITION are
+passed to `key-binding'.
+
+\(fn KEY &key STATE DOCSTRING ACCEPT-DEFAULT NO-REMAP POSITION)" nil t)
+
+(autoload 'general-simulate-keys "general" "\
+Deprecated. Please use `general-simulate-key' instead.
+
+\(fn KEYS &optional STATE KEYMAP (LOOKUP t) DOCSTRING NAME)" nil t)
+
+(autoload 'general-simulate-key "general" "\
+Create and return a command that simulates KEYS in STATE and KEYMAP.
+KEYS should be a string given in `kbd' notation. It can also be a list of a
+single command followed by a string of the key(s) to simulate after calling that
+command. STATE should only be specified by evil users and should be a quoted
+evil state. KEYMAP should not be quoted. Both STATE and KEYMAP aliases are
+supported (but they have to be set when the macro is expanded). When neither
+STATE or KEYMAP are specified, the key(s) will be simulated in the current
+context.
+
+If NAME is specified, it will replace the automatically generated function name.
+NAME should not be quoted. If DOCSTRING is specified, it will replace the
+automatically generated docstring.
+
+Normally the generated function will look up KEY in the correct context to try
+to match a command. To prevent this lookup, LOOKUP can be specified as nil.
+Generally, you will want to keep LOOKUP non-nil because this will allow checking
+the evil repeat property of matched commands to determine whether or not they
+should be recorded. See the docstring for `general--simulate-keys' for more
+information about LOOKUP.
+
+When a WHICH-KEY description is specified, it will replace the command name in
+the which-key popup.
+
+When a command name is specified and that command has been remapped (i.e. [remap
+command] is currently bound), the remapped version will be used instead of the
+original command unless REMAP is specified as nil (it is true by default).
+
+The advantages of this over a keyboard macro are as follows:
+- Prefix arguments are supported
+- The user can control the context in which the keys are simulated
+- The user can simulate both a named command and keys
+- The user can simulate an incomplete key sequence (e.g. for a keymap)
+
+\(fn KEYS &key STATE KEYMAP NAME DOCSTRING (LOOKUP t) WHICH-KEY (REMAP t))" nil t)
+
+(function-put 'general-simulate-key 'lisp-indent-function 'defun)
+
+(autoload 'general-key-dispatch "general" "\
+Create and return a command that runs FALLBACK-COMMAND or a command in MAPS.
+MAPS consists of <key> <command> pairs. If a key in MAPS is matched, the
+corresponding command will be run. Otherwise FALLBACK-COMMAND will be run with
+the unmatched keys. So, for example, if \"ab\" was pressed, and \"ab\" is not
+one of the key sequences from MAPS, the FALLBACK-COMMAND will be run followed by
+the simulated keypresses of \"ab\". Prefix arguments will still work regardless
+of which command is run. This is useful for binding under non-prefix keys. For
+example, this can be used to redefine a sequence like \"cw\" or \"cow\" in evil
+but still have \"c\" work as `evil-change'. If TIMEOUT is specified,
+FALLBACK-COMMAND will also be run in the case that the user does not press the
+next key within the TIMEOUT (e.g. 0.5).
+
+NAME and DOCSTRING are optional keyword arguments. They can be used to replace
+the automatically generated name and docstring for the created function. By
+default, `cl-gensym' is used to prevent name clashes (e.g. allows the user to
+create multiple different commands using `self-insert-command' as the
+FALLBACK-COMMAND without explicitly specifying NAME to manually prevent
+clashes).
+
+When INHERIT-KEYMAP is specified, all the keybindings from that keymap will be
+inherited in MAPS.
+
+When a WHICH-KEY description is specified, it will replace the command name in
+the which-key popup.
+
+When command to be executed has been remapped (i.e. [remap command] is currently
+bound), the remapped version will be used instead of the original command unless
+REMAP is specified as nil (it is true by default).
+
+\(fn FALLBACK-COMMAND &rest MAPS &key TIMEOUT INHERIT-KEYMAP NAME DOCSTRING WHICH-KEY (REMAP t) &allow-other-keys)" nil t)
+
+(function-put 'general-key-dispatch 'lisp-indent-function '1)
+
+(autoload 'general-predicate-dispatch "general" "\
+
+
+\(fn FALLBACK-DEF &rest DEFS &key DOCSTRING &allow-other-keys)" nil t)
+
+(function-put 'general-predicate-dispatch 'lisp-indent-function '1)
+
+(autoload 'general-translate-key "general" "\
+Translate keys in the keymap(s) corresponding to STATES and KEYMAPS.
+STATES should be the name of an evil state, a list of states, or nil. KEYMAPS
+should be a symbol corresponding to the keymap to make the translations in or a
+list of keymap names. Keymap and state aliases are supported (as well as 'local
+and 'global for KEYMAPS). MAPS corresponds to a list of translations (key
+replacement pairs). For example, specifying \"a\" \"b\" will bind \"a\" to
+\"b\"'s definition in the keymap. If DESTRUCTIVE is non-nil, the keymap will be
+destructively altered without creating a backup. If DESTRUCTIVE is nil, a backup
+of the keymap will be stored on the initial invocation, and future invocations
+will always look up keys in the backup keymap. On the other hand, if DESTRUCTIVE
+is non-nil, calling this function multiple times with \"a\" \"b\" \"b\" \"a\",
+for example, would continue to swap and unswap the definitions of these keys.
+This means that when DESTRUCTIVE is non-nil, all related swaps/cycles should be
+done in the same invocation.
+
+\(fn STATES KEYMAPS &rest MAPS &key DESTRUCTIVE &allow-other-keys)" nil nil)
+
+(function-put 'general-translate-key 'lisp-indent-function 'defun)
+
+(autoload 'general-swap-key "general" "\
+Wrapper around `general-translate-key' for swapping keys.
+STATES, KEYMAPS, and ARGS are passed to `general-translate-key'. ARGS should
+consist of key swaps (e.g. \"a\" \"b\" is equivalent to \"a\" \"b\" \"b\" \"a\"
+with `general-translate-key') and optionally keyword arguments for
+`general-translate-key'.
+
+\(fn STATES KEYMAPS &rest ARGS)" nil t)
+
+(function-put 'general-swap-key 'lisp-indent-function 'defun)
+
+(autoload 'general-auto-unbind-keys "general" "\
+Advise `define-key' to automatically unbind keys when necessary.
+This will prevent errors when a sub-sequence of a key is already bound (e.g. the
+user attempts to bind \"SPC a\" when \"SPC\" is bound, resulting in a \"Key
+sequnce starts with non-prefix key\" error). When UNDO is non-nil, remove
+advice.
+
+\(fn &optional UNDO)" nil nil)
+
+(autoload 'general-add-hook "general" "\
+A drop-in replacement for `add-hook'.
+Unlike `add-hook', HOOKS and FUNCTIONS can be single items or lists. APPEND and
+LOCAL are passed directly to `add-hook'.
+
+\(fn HOOKS FUNCTIONS &optional APPEND LOCAL)" nil nil)
+
+(autoload 'general-remove-hook "general" "\
+A drop-in replacement for `remove-hook'.
+Unlike `remove-hook', HOOKS and FUNCTIONS can be single items or lists. LOCAL is
+passed directly to `remove-hook'.
+
+\(fn HOOKS FUNCTIONS &optional LOCAL)" nil nil)
+
+(autoload 'general-advice-add "general" "\
+A drop-in replacement for `advice-add'.
+SYMBOLS, WHERE, FUNCTIONS, and PROPS correspond to the arguments for
+`advice-add'. Unlike `advice-add', SYMBOLS and FUNCTIONS can be single items or
+lists.
+
+\(fn SYMBOLS WHERE FUNCTIONS &optional PROPS)" nil nil)
+ (autoload 'general-add-advice "general")
+
+(autoload 'general-advice-remove "general" "\
+A drop-in replacement for `advice-remove'.
+Unlike `advice-remove', SYMBOLS and FUNCTIONS can be single items or lists.
+
+\(fn SYMBOLS FUNCTIONS)" nil nil)
+ (autoload 'general-remove-advice "general")
+
+(autoload 'general-evil-setup "general" "\
+Set up some basic equivalents for vim mapping functions.
+This creates global key definition functions for the evil states.
+Specifying SHORT-NAMES as non-nil will create non-prefixed function
+aliases such as `nmap' for `general-nmap'.
+
+\(fn &optional SHORT-NAMES _)" nil nil)
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; general-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/general-20180628.1112/general-pkg.el b/configs/shared/emacs/.emacs.d/elpa/general-20180628.1112/general-pkg.el
new file mode 100644
index 0000000000..72ef8f418d
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/general-20180628.1112/general-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "general" "20180628.1112" "Convenience wrappers for keybindings." '((emacs "24.4") (cl-lib "0.5")))
diff --git a/configs/shared/emacs/.emacs.d/elpa/general-20180628.1112/general.el b/configs/shared/emacs/.emacs.d/elpa/general-20180628.1112/general.el
new file mode 100644
index 0000000000..0f6ea39a90
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/general-20180628.1112/general.el
@@ -0,0 +1,2469 @@
+;;; general.el --- Convenience wrappers for keybindings. -*- lexical-binding: t -*-
+
+;; Author: Fox Kiester <noct@openmailbox.org>
+;; URL: https://github.com/noctuid/general.el
+;; Package-Version: 20180628.1112
+;; Created: February 17, 2016
+;; Keywords: vim, evil, leader, keybindings, keys
+;; Package-Requires: ((emacs "24.4") (cl-lib "0.5"))
+;; Version: 0.1
+
+;; This file is not part of GNU Emacs.
+
+;; This program 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.
+
+;; This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; This package provides convenient wrappers for more succinctly defining
+;; keybindings. It allows defining multiple keys at once, specifying an
+;; arbitrary number of named prefix keys to be used in key definitions,
+;; implicitly wrapping key strings with (kbd ...), and more. It provides a
+;; single function for standard emacs key definitions as well as evil key
+;; definitions for any evil state and any keymap. It also provides a setup
+;; function to generate "nmap", "vmap", etc. keybinding functions for evil.
+
+;; For more information see the README in the online repository.
+
+;;; Code:
+(require 'cl-lib)
+
+;; * Settings
+(defgroup general nil
+  "Gives convenient wrappers for key definitions."
+  :group 'convenience
+  :prefix 'general-)
+
+(defcustom general-implicit-kbd t
+  "Whether to implicitly wrap a (kbd) around `general-define-key' keys.
+This applies to the prefix key as well. This option is provided to make it easy
+  to transition from other key definers to `general-define-key'. It does not
+  apply to other helpers such as `general-key', `general-key-dispatch', and
+  `general-translate-key'. These will always use `kbd' on keys that are
+  strings."
+  :group 'general
+  :type 'boolean)
+
+(defcustom general-default-prefix nil
+  "The default prefix key sequence to use."
+  :group 'general
+  :type 'string)
+(make-obsolete-variable 'general-default-prefix
+                        "This functionality will be removed in the future."
+                        "2018-01-21")
+
+(defcustom general-default-non-normal-prefix nil
+  "The default prefix key sequence to use for the 'emacs and 'insert states.
+Note that this setting is only useful for evil-users and will only have an
+effect when binding keys in the 'emacs and/or 'insert states or in the
+'evil-insert-state-map and/or 'evil-emacs-state-map keymaps. When this is not
+specified, `general-default-prefix' will be the default prefix for any states
+and keymaps. If this is specified `general-default-prefix' or the arg to :prefix
+will not be used when binding keys in the insert and emacs states."
+  :group 'general
+  :type 'string)
+(make-obsolete-variable 'general-default-non-normal-prefix
+                        "This functionality will be removed in the future."
+                        "2018-01-21")
+
+(defcustom general-default-global-prefix nil
+  "The default prefix key sequence to use for all evil states.
+This setting is only useful for evil users. Note that like with
+`general-default-non-normal-prefix', if this or :global-prefix is specified,
+`general-default-prefix' or the arg to :prefix will not be used for binding
+keys in the insert and emacs states. If you don't need a different or extra
+prefix for one or both state types (insert and emacs vs. the other states),
+just use `general-default-prefix'/:prefix by itself."
+  :group 'general
+  :type 'string)
+(make-obsolete-variable 'general-default-global-prefix
+                        "This functionality will be removed in the future."
+                        "2018-01-21")
+
+(define-widget 'general-state 'lazy
+  "General's evil state type."
+  :type '(choice
+          (const :tag "Insert state" insert)
+          (const :tag "Emacs state" emacs)
+          (const :tag "Normal state" normal)
+          (const :tag "Visual state" visual)
+          (const :tag "Motion state" motion)
+          (const :tag "Operator state" operator)
+          (const :tag "Replace state" replace)
+          (const :tag "Use define-key not evil-define-key" nil)
+          ;; other packages define states
+          symbol))
+
+(defcustom general-default-states nil
+  "The default evil state(s) to make mappings in.
+Non-evil users should keep this nil."
+  :group 'general
+  :type '(choice general-state
+                 (set general-state)))
+(make-obsolete-variable 'general-default-states
+                        "This functionality will be removed in the future."
+                        "2018-01-21")
+
+(defcustom general-non-normal-states '(insert emacs hybrid iedit-insert)
+  "List of \"non-normal\" evil states (used with :non-normal-prefix). When
+  :states is not specified (only :keymaps), these will automatically be expanded
+  to their full global evil keymap equivalents."
+  :group 'general
+  :type '(repeat general-state))
+
+(define-widget 'general-keymap 'lazy
+  "General's keymap type."
+  :type '(choice
+          (const :tag "Global keymap" global)
+          (const :tag "Buffer local keymap" local)
+          symbol))
+
+(defcustom general-default-keymaps 'global
+  "The default keymap(s) to bind keys in."
+  :group 'general
+  :type '(choice general-keymap
+                 (repeat general-keymap)))
+(make-obsolete-variable 'general-default-keymaps
+                        "This functionality will be removed in the future."
+                        "2018-01-21")
+
+(defcustom general-vim-definer-default nil
+  "Whether set the states or keymaps in a `general-create-vim-definer' function.
+If nil, use the default from when the function was created. If 'keymaps, set the
+default keymaps. If 'states, set the default states."
+  :group 'general
+  :type '(choice
+          (const :tag "Default to setting :keymaps" keymaps)
+          (const :tag "Default to setting :states" states)
+          (const :tag "Use the initial default" nil)))
+(make-obsolete-variable 'general-vim-definer-default
+                        "This functionality is no longer necessary."
+                        "2018-01-20")
+
+(defvar general-keybindings nil
+  "Holds all the keybindings created with `general-define-key' (and wrappers).
+This is an alist of a keymap to an alist of a state to keybindings.")
+
+(defvar general-local-keybindings nil
+  "Holds all the local keybindings created with `general-define-key'.
+This is an alist of a state to keybindings.")
+(make-variable-buffer-local 'general-local-keybindings)
+
+(define-widget 'general-alist 'lazy
+  "General's alist type."
+  :type '(alist :key-type (or symbol (repeat symbol))
+                :value-type symbol))
+
+(defcustom general-keymap-aliases
+  '((override . general-override-mode-map)
+    ((i insert) . evil-insert-state-map)
+    ((e emacs) . evil-emacs-state-map)
+    ((h hybrid) . evil-hybrid-state-map)
+    ((n normal) . evil-normal-state-map)
+    ((v visual) . evil-visual-state-map)
+    ((m motion) . evil-motion-state-map)
+    ((o operator) . evil-operator-state-map)
+    ((r replace) . evil-replace-state-map)
+    ((in inner) . evil-inner-text-objects-map)
+    ((out outer) . evil-outer-text-objects-map))
+  "An alist for mapping short keymap names to their full names.
+Earlier entries have higher precedence."
+  :group 'general
+  :type 'general-alist)
+
+(defcustom general-state-aliases
+  '((i . insert)
+    (e . emacs)
+    (h . hybrid)
+    (n . normal)
+    (v . visual)
+    (m . motion)
+    (o . operator)
+    (r . replace))
+  "An alist for mapping short state names to their full names.
+Earlier entries have higher precedence."
+  :group 'general
+  :type 'general-alist)
+
+;; ** `general-describe-keybindings' Settings
+(defcustom general-describe-keybinding-sort-function nil
+  "Function used to sort keybindings for `general-describe-keybindings'."
+  :group 'general
+  :type '(choice function (const nil)))
+
+(defcustom general-describe-state-sort-function
+  #'general--sort-evil-state-conses
+  "Function used to sort the states conses for `general-describe-keybindings'."
+  :group 'general
+  :type '(choice function (const nil)))
+
+(defcustom general-describe-keymap-sort-function nil
+  "Function used to sort the keymap conses`general-keybindings' for
+`general-describe-keybindings'."
+  :group 'general
+  :type '(choice function (const nil)))
+
+(defcustom general-describe-priority-keymaps
+  '(local
+    global
+    evil-insert-state-map
+    evil-emacs-state-map
+    evil-hybrid-state-map
+    evil-normal-state-map
+    evil-visual-state-map
+    evil-motion-state-map
+    evil-operator-state-map
+    evil-replace-state-map
+    evil-inner-text-objects-map
+    evil-outer-text-objects-map
+    evil-ex-search-keymap
+    evil-ex-completion-map
+    evil-command-window-mode-map
+    evil-window-map)
+  "Keymaps to print first for `general-describe-keybindings'."
+  :group 'general
+  :type '(repeat sybmol))
+
+(defcustom general-describe-update-previous-definition 'on-change
+  "Whether to update the previous definition when a key is bound.
+When set to 'on-change, the previous definition will only be updated when the
+definition changes (e.g. re-evaluating a file with keybindings will not affect
+the stored previous definition). When set to nil, it will only be updated when
+the key was previously unbound."
+  :group 'general
+  ;; can't think of a use case, but add 'always if requested
+  ;; t is equivalent of on-change
+  :type '(choice
+          (const :tag "When definition has changed" on-change)
+          (const :tag "When the key was previously unbound" nil)))
+
+;; * Override Minor Modes
+(defcustom general-override-auto-enable t
+  "Whether to automatically enable `general-override-mode'.
+If non-nil, enable `general-override-mode' when binding a key in
+`general-override-mode-map'."
+  :group 'general
+  :type 'boolean)
+
+(defvar general-override-mode-map (make-sparse-keymap)
+  "A keymap that will take priority over other minor mode keymaps.
+This is only for non-evil keybindings (it won't override keys bound with
+`evil-define-key'.")
+
+(define-minor-mode general-override-mode
+  "A global minor mode used for key definitions that should override others."
+  :lighter ""
+  :global t
+  :keymap general-override-mode-map)
+
+(defvar-local general-override-local-mode-map (make-sparse-keymap)
+  "A keymap that will take priority over other minor mode keymaps.
+This keymap is buffer-local and will take precedence over
+`general-override-mode-map'. General uses this keymap when creating non-evil
+local keybindings.")
+
+(define-minor-mode general-override-local-mode
+  "A local minor mode used for key definitions that should override others."
+  :lighter ""
+  :keymap general-override-local-mode-map)
+
+(defvar-local general-maps-alist
+  `((general-override-mode . ,general-override-mode-map))
+  "Holds the (mode . keymap) pairs for general's override modes.")
+;; not affected by changing major modes
+(put 'general-maps-alist 'permanent-local t)
+
+(defvar-local general--maps-alist-updated nil
+  "Whether `general-maps-alist' has been set correctly for the current buffer.")
+(put 'general-maps-alist 'permanent-local t)
+
+(declare-function evil-make-intercept-map "evil-core")
+(defun general-override-make-intercept-maps (_sym states)
+  "Make intercept keymaps for STATES in `general-override-mode-map'.
+This means that keys bound in STATES for `general-override-mode-map' will take
+precedence over keys bound in other evil auxiliary maps."
+  ;; can't use `general-with-eval-after-load' here; not available
+  (with-eval-after-load 'evil
+    ;; TODO eventually use new evil-make-intercept-map arg
+    (dolist (state states)
+      (evil-make-intercept-map
+       (evil-get-auxiliary-keymap general-override-mode-map state t t)
+       state))))
+
+(defcustom general-override-states
+  '(insert
+    emacs
+    hybrid
+    normal
+    visual
+    motion
+    operator
+    replace)
+  "States to make intercept maps for in `general-override-mode-map'.
+Note that this uses :set, meaning that if you want to change the value, you
+should either set it using customize (e.g. `general-setq' or
+`customize-set-variable') or set it before loading general if using `setq'."
+  :group 'general
+  :type '(repeat general-state)
+  :set #'general-override-make-intercept-maps)
+
+(defun general--update-maps-alist ()
+  "Update `general-maps-alist' for override modes.
+This is necessary to ensure `general-override-local-mode-map' is the buffer's
+local version."
+  (setq general-maps-alist
+        `((general-override-local-mode . ,general-override-local-mode-map)
+          (general-override-mode . ,general-override-mode-map))
+        general--maps-alist-updated t))
+
+(cl-pushnew 'general-maps-alist emulation-mode-map-alists)
+
+(defun general-local-map ()
+  "Return `general-override-local-mode-map'.
+Also turn on `general-override-local-mode' and update `general-maps-alist'."
+  (or general-override-local-mode (general-override-local-mode))
+  (unless general--maps-alist-updated
+    (general--update-maps-alist))
+  general-override-local-mode-map)
+
+;; * General Helpers
+(defmacro general-with-eval-after-load (file &rest body)
+  "Like `with-eval-after-load' but don't always add to `after-load-alist'.
+When FILE has already been loaded, execute BODY immediately without adding it to
+`after-load-alist'."
+  (declare (indent 1))
+  `(if (if (stringp ,file)
+           (load-history-filename-element
+            (purecopy (load-history-regexp ,file)))
+         (featurep ,file))
+       (progn ,@body)
+     (eval-after-load ,file (lambda () ,@body))))
+
+(defun general--unalias (symbol &optional statep)
+  "Return the full keymap or state name associated with SYMBOL.
+If STATEP is non-nil, check `general-state-aliases' instead of
+`general-keymap-aliases'."
+  (let ((match
+         (cdr (cl-assoc symbol
+                        (if statep
+                            general-state-aliases
+                          general-keymap-aliases)
+                        ;; test-fn is new to assoc in 26.1
+                        :test (lambda (symbol key)
+                                (or (eq symbol key)
+                                    (ignore-errors (memq symbol key))))))))
+    (or match symbol)))
+
+;; don't want to reuse `general--unalias' since the user can alter
+;; `general-keymap-aliases'
+(defun general--evil-keymap-for-state (state)
+  "Return a symbol corresponding to the global evil keymap for STATE."
+  (intern (concat "evil-" (symbol-name state) "-state-map")))
+
+(defun general--kbd (key)
+  "Use `kbd' on KEY when it is a string."
+  (if (stringp key)
+      (kbd key)
+    key))
+
+;; TODO refactor to be more straightforward
+(defun general--concat (nokbd &rest keys)
+  "Concatenate the strings in KEYS.
+If `general-implicit-kbd' is non-nil, interleave the strings in KEYS with
+spaces; unless NOKBD is non-nil, apply (kbd ...) to the result. If
+`general-implicit-kbd' is nil, just concatenate the keys."
+  (setq keys (remove nil keys))
+  (if general-implicit-kbd
+      (let ((keys (mapconcat (lambda (x)
+                               (if (vectorp x)
+                                   (key-description x)
+                                 x))
+                             keys " ")))
+        (if nokbd
+            keys
+          (kbd keys)))
+    (apply #'concat keys)))
+
+(defun general--apply-prefix-and-kbd (prefix maps)
+  "Prepend the PREFIX sequence to all the keys that are strings in MAPS.
+Also apply (kbd ...) to key and definition strings if `general-implicit-kbd' is
+non-nil."
+  (setq prefix (or prefix ""))
+  (cl-loop for (key def) on maps by 'cddr
+           collect (general--concat nil prefix key)
+           and collect def))
+
+(defun general--lookup-key (state keymap key &optional minor-mode-p)
+  "Return the current definition for STATE, KEYMAP, and KEY."
+  (when key
+    (let ((keymap (general--get-keymap state keymap minor-mode-p)))
+      (when keymap
+        (let ((def (lookup-key keymap key)))
+          (if (and (numberp def) (= def 1))
+              nil
+            def))))))
+
+(defun general--record-keybindings (keymap state maps &optional minor-mode-p)
+  "For KEYMAP and STATE, add MAPS to `general-keybindings'.
+If KEYMAP is \"local\", add MAPS to `general-local-keybindings.' For non-evil
+keybindings, STATE will be nil. Duplicate keys will be replaced with the new
+ones. MINOR-MODE-P should be non-nil when keymap corresponds to a minor-mode
+name (as used with `evil-define-minor-mode-key') as opposed to a keymap name."
+  (if (and state (not (featurep 'evil)))
+      (general-with-eval-after-load 'evil
+        (general--record-keybindings keymap state maps minor-mode-p))
+    (let* (keys
+           (maps (cl-loop
+                  for (key new-def _orig-def) on maps by 'cl-cdddr
+                  collect
+                  (list key
+                        new-def
+                        (let* ((current-def (general--lookup-key
+                                             state keymap key minor-mode-p))
+                               ;; none of these will fail if nil
+                               (keymap-cons (assq keymap general-keybindings))
+                               (state-cons (assq state (cdr keymap-cons)))
+                               (mapping (cl-find key (cdr state-cons)
+                                                 :test #'equal :key #'car))
+                               (previous-def (cl-caddr mapping)))
+                          (if (or
+                               (and current-def (not previous-def))
+                               (and general-describe-update-previous-definition
+                                    (not (equal new-def current-def))))
+                              current-def
+                            previous-def)))
+                  do (push key keys))))
+      (cond ((eq keymap 'local)
+             (unless (assq state general-local-keybindings)
+               (add-to-list 'general-local-keybindings (list state)))
+             (let ((state-cons (assq state general-local-keybindings)))
+               (setcdr state-cons
+                       ;; remove old duplicate keys
+                       (cl-remove-duplicates (append (cdr state-cons) maps)
+                                             :key #'car
+                                             :test #'equal))))
+            (t
+             (unless (assq keymap general-keybindings)
+               (add-to-list 'general-keybindings (list keymap)))
+             (unless (assq state (assq keymap general-keybindings))
+               (setcdr (assq keymap general-keybindings)
+                       (append (cdr (assq keymap general-keybindings))
+                               (list (list state)))))
+             (let ((state-cons (assq state (assq keymap general-keybindings))))
+               (setcdr state-cons
+                       (cl-remove-duplicates (append (cdr state-cons) maps)
+                                             :key #'car
+                                             :test #'equal))))))))
+
+;; don't force non-evil user to require evil for one function
+(defun general--delay (condition form hook &optional append local name)
+  "Execute FORM when CONDITION becomes true, checking with HOOK.
+NAME specifies the name of the entry added to HOOK. If APPEND is
+non-nil, the entry is appended to the hook. If LOCAL is non-nil,
+the buffer-local value of HOOK is modified.
+
+This is `evil-delay'."
+  (declare (indent 2))
+  (if (and (not (booleanp condition)) (eval condition))
+      (eval form)
+    (let* ((name (or name (format "general-delay-form-in-%s" hook)))
+           (fun (make-symbol name))
+           (condition (or condition t)))
+      (fset fun `(lambda (&rest args)
+                   (when ,condition
+                     (remove-hook ',hook #',fun ',local)
+                     ,form)))
+      (put fun 'permanent-local-hook t)
+      (add-hook hook fun append local))))
+
+(defun general--getf (def fallback-plist keyword)
+  "From DEF or FALLBACK-PLIST get the corresponding value for KEYWORD.
+FALLBACK-PLIST will be checked when KEYWORD does not exist in DEF (not in cases
+where it is explicitly specified as nil). If DEF isn't a general extended
+definition, only check in FALLBACK-PLIST."
+  (if (general--extended-def-p def)
+      (cl-getf def keyword
+               (cl-getf fallback-plist keyword))
+    (cl-getf fallback-plist keyword)))
+
+(defun general--getf2 (plist keyword1 keyword2)
+  "Check in PLIST for either KEYWORD1 or KEYWORD2."
+  (or (cl-getf plist keyword1)
+      (cl-getf plist keyword2)))
+
+(declare-function evil-get-minor-mode-keymap "evil-core")
+(declare-function evil-state-property "evil-common")
+(declare-function evil-get-auxiliary-keymap "evil-core")
+(cl-defun general--get-keymap (state &optional keymap
+                                     minor-mode
+                                     ignore-special)
+  "Transform STATE and the symbol or keymap KEYMAP into the appropriate keymap.
+If MINOR-MODE and STATE are non-nil, use `evil-get-minor-mode-keymap'. If
+IGNORE-SPECIAL is non-nil, do not try to resolve the \"special\" keymaps 'global
+and 'local. In this case, the only thing this function will do is return the
+actually keymap if KEYMAP is a symbol besides 'global or 'local. Otherwise the
+keymap returned depends on whether STATE is specified. Note that if STATE is
+specified, evil needs to be installed and will be required.
+
+STATE nil:
+'local  - Run/return `general-local-map'
+'global - Run/return `current-global-map'
+else    - Return keymap or (symbol-value keymap)
+
+STATE non-nil:
+'local  - Return the corresponding evil local map
+'global - Return the corresponding evil global map
+else    - Return the corresponding evil auxiliary or minor mode map"
+  (when (and (symbolp keymap)
+             (not (memq keymap '(global local))))
+    (setq keymap (symbol-value keymap)))
+  (when ignore-special
+    (cl-return-from general--get-keymap keymap))
+  (if state
+      (if (require 'evil nil t)
+          (cond ((or (null keymap)
+                     (eq keymap 'global))
+                 (evil-state-property state :keymap t))
+                (minor-mode
+                 (evil-get-minor-mode-keymap state keymap))
+                ((eq keymap 'local)
+                 (evil-state-property state :local-keymap t))
+                (t
+                 (evil-get-auxiliary-keymap keymap state t t)))
+        (error "Evil is required if state is specified"))
+    (cl-case keymap
+      (global (current-global-map))
+      (local (general-local-map))
+      (t keymap))))
+(define-obsolete-function-alias 'general--parse-keymap 'general--get-keymap
+  "2018-01-14")
+
+(defun general--remove-keyword-args (rest)
+  "Remove all keyword arguments from the list REST.
+Return a list of the altered REST list and a list of the removed keyword
+arguments. The order of arguments will be preserved. Note that the length of
+REST does not need to be even (i.e. there can be an odd number of positional
+arguments)."
+  (let (args
+        kargs)
+    (while rest
+      (cond ((keywordp (car rest))
+             (push (pop rest) kargs)
+             (push (pop rest) kargs))
+            (t
+             (push (pop rest) args))))
+    (list (nreverse args) (nreverse kargs))))
+
+(defmacro general--ensure-lists (&rest vars)
+  "Ensure that all variables in VARS are lists if they are not already.
+If any variable is a lambda, it will not be considered to be a list. If a var is
+nil, it will be set to (list nil)."
+  `(progn
+     ,@(mapcar (lambda (var)
+                 `(unless (and ,var
+                               (listp ,var)
+                               ;; lambdas are lists
+                               (not (functionp ,var)))
+                    (setq ,var (list ,var))))
+               vars)))
+
+;; * Extended Key Definition Language
+;; ** Variables
+(defvar general-extended-def-keywords
+  '(:which-key :wk :properties :repeat :jump)
+  "Extra keywords that are valid for extended definitions.
+
+These can work both locally (in extended definitions) and globally (in which
+case they apply to all definitions including normal ones). Note that not all
+keywords need to make sense/work globally. If the keyword should be ignored when
+used globally, add it to `general-extended-def-global-ignore-keywords' as well.
+
+For each keyword there should be a corresponding function named
+general-extended-def-:<keyword> which will be passed state, keymap (the symbol
+not actual keymap), key (the internal representation, i.e. `kbd' already called
+if necessary), edef (always a plist; normal definitions will automatically be
+converted), and kargs (the original `general-define-key' keyword argument plist;
+useful when the keyword can be used globally or has helper keywords that can be
+used globally). This function is only called for side effects; if you actually
+need to alter the definition, you should add the keyword to
+`general-rewrite-def-keywords' or `general-rewrite-def-after-keywords' instead.
+The order of those lists matters, but the order of this list does not.
+
+`general--get-keymap' may be useful for getting the actual keymap from the
+keymap symbol. `general--getf' may be useful for keywords (helper or main) that
+can be specified globally (in kargs) and overridden locally (in def).")
+
+(defvar general-rewrite-def-keywords
+  '(:keymap :prefix-command :prefix-keymap)
+  "Extended definition keywords that alter the definition.
+
+Each keyword should have a corresponding function named
+general-extended-def-:<keyword> and should return a new extended definition
+plist (with an altered :def entry). See `general-extended-def-keywords' for
+information on the arguments this function should take. These functions will be
+run in the order they appear in this list, and each will be passed the most
+recent version of the extended definition plist.
+
+In contrast to the functions for `general-rewrite-def-after-keywords', these
+functions will alter the definition before any `general-extended-def-keyword'
+functions run. For example, if your function creates a newly named wrapper
+command around the user-specified command, you'd want to add the keyword to this
+list, so that `general-extended-def-keywords' functions would have access to new
+command name (e.g. for :which-key to work properly). On the other hand, if the
+keyword, for example, involves putting the definition in an extended menu item
+like with :predicate, you should add to `general-rewrite-def-after-keywords'
+instead.")
+
+(defvar general-rewrite-def-after-keywords
+  '(:predicate)
+  "Extended definition keywords that alter the definition.
+See `general-rewrite-def-keywords' for more information.")
+
+(defvar general-extended-def-global-ignore-keywords
+  '(:keymap :prefix-command :prefix-map)
+  "Extended definitions that should be ignored when used globally.
+For example, :prefix-command and :prefix-map are handled differently when used
+globally (they have special interaction with other global keywords). :keymap, on
+the other hand, doesn't make sense at all globally.")
+
+;; ** Normal Extended Definition Functions
+(defvar which-key-replacement-alist)
+(defun general--add-which-key-replacement (mode replacement)
+  (let* ((mode-match (assq mode which-key-replacement-alist))
+         (mode-alist (cdr mode-match)))
+    (cond (mode
+           (push replacement mode-alist)
+           (if mode-match
+               (setcdr mode-match mode-alist)
+             (push (cons mode mode-alist)
+                   which-key-replacement-alist)))
+          (t
+           (push replacement which-key-replacement-alist)))))
+
+(defvar which-key--prefix-title-alist)
+(defun general--add-which-key-title-prefix (mode keys title-prefix)
+  (let* ((mode-match (assq mode which-key--prefix-title-alist))
+         (title-mode-alist (cdr mode-match))
+         (title-cons (cons keys title-prefix)))
+    (cond (mode
+           (push title-cons title-mode-alist)
+           (if mode-match
+               (setcdr mode-match
+                       title-mode-alist)
+             (push (cons mode title-mode-alist)
+                   which-key--prefix-title-alist)))
+          (t
+           (push title-cons which-key--prefix-title-alist)))))
+
+(defun general--remove-map (keymap)
+  "Remove \"-map\" from the symbol KEYMAP." ;
+  (intern (replace-regexp-in-string "-map$" "" (symbol-name keymap))))
+
+;; TODO better documentation
+(defun general-extended-def-:which-key (_state keymap key edef kargs)
+  "Add a which-key description for KEY.
+If :major-modes is specified in EDEF, add the description for the corresponding
+major mode. KEY should not be in the kbd format (kbd should have already been
+run on it)."
+  (general-with-eval-after-load 'which-key
+    (let* ((wk (general--getf2 edef :which-key :wk))
+           (major-modes (general--getf edef kargs :major-modes))
+           (keymaps (plist-get kargs :keymaps))
+           ;; index of keymap in :keymaps
+           (keymap-index (cl-dotimes (ind (length keymaps))
+                           (when (eq (nth ind keymaps) keymap)
+                             (cl-return ind))))
+           (mode (let ((mode (if (and major-modes (listp major-modes))
+                                 (nth keymap-index major-modes)
+                               major-modes)))
+                   (if (eq mode t)
+                       (general--remove-map keymap)
+                     mode)))
+           (key (key-description key))
+           (key-regexp (concat (when (general--getf edef kargs :wk-full-keys)
+                                 "\\`")
+                               (regexp-quote key)
+                               "\\'"))
+           (prefix (plist-get kargs :prefix))
+           (binding (or (when (and (plist-get edef :def)
+                                   (not (plist-get edef :keymp)))
+                          (plist-get edef :def))
+                        (when (and prefix
+                                   (string= key prefix))
+                          (plist-get kargs :prefix-command))))
+           (replacement (cond ((stringp wk)
+                               (cons nil wk))
+                              (t
+                               wk)))
+           (match/replacement
+            (cons
+             (cons (when (general--getf edef kargs :wk-match-keys)
+                     key-regexp)
+                   (when (and (general--getf edef kargs :wk-match-binding)
+                              binding
+                              (symbolp binding))
+                     (symbol-name binding)))
+             replacement)))
+      (general--add-which-key-replacement mode match/replacement)
+      (when (and (consp replacement)
+                 ;; lambda
+                 (not (functionp replacement)))
+        (general--add-which-key-title-prefix
+         mode key (cdr replacement))))))
+
+(defalias 'general-extended-def-:wk #'general-extended-def-:which-key)
+
+(declare-function evil-add-command-properties "evil-common")
+(defun general-extended-def-:properties (_state _keymap _key edef kargs)
+  "Use `evil-add-command-properties' to add properties to a command.
+The properties should be specified with :properties in either EDEF or KARGS."
+  (general-with-eval-after-load 'evil
+    (let ((properties (general--getf edef kargs :properties))
+          (command (cl-getf edef :def)))
+      (apply #'evil-add-command-properties command properties))))
+
+(defun general-extended-def-:repeat (_state _keymap _key edef kargs)
+  "Use `evil-add-command-properties' to set the :repeat property for a command.
+The repeat property should be specified with :repeat in either EDEF or KARGS."
+  (general-with-eval-after-load 'evil
+    (let ((repeat-property (general--getf edef kargs :repeat))
+          (command (cl-getf edef :def)))
+      (evil-add-command-properties command :repeat repeat-property))))
+
+(defun general-extended-def-:jump (_state _keymap _key edef kargs)
+  "Use `evil-add-command-properties' to set the :jump property for a command.
+The jump property should be specified with :jump in either EDEF or KARGS."
+  (general-with-eval-after-load 'evil
+    (let ((jump-property (general--getf edef kargs :jump))
+          (command (cl-getf edef :def)))
+      (evil-add-command-properties command :jump jump-property))))
+
+;; ** Extended Defintion Functions That Alter the Definition
+(defun general-extended-def-:keymap (state keymap _key edef kargs)
+  "Return an extended definition for a keymap or a \"autoloaded\" keymap.
+If the specified keymap does not exist, create a function that binds the keys it
+was invoked with in STATE and KEYMAP to the keymap specified in the extended
+definition EDEF and then act as if it was originally bound to that
+keymap (subsequent keys will be looked up in the keymap). KARGS or EDEF should
+contain the package in which the keymap is created (as specified with :package).
+If the keymap already exists, it will simply be returned."
+  (let ((bind-keymap-sym (plist-get edef :def))
+        (package (general--getf edef kargs :package))
+        (definer (general--getf edef kargs :definer)))
+    (if (boundp bind-keymap-sym)
+        (setf (cl-getf edef :def) (symbol-value bind-keymap-sym))
+      (if package
+          (setf (cl-getf edef :def)
+                ;; relying on lexical binding here
+                (lambda ()
+                  (interactive)
+                  (unless (or (featurep package)
+                              (require package nil t))
+                    (error (format "Failed to load package: %s" package)))
+                  (unless (and (boundp bind-keymap-sym)
+                               (keymapp (symbol-value bind-keymap-sym)))
+                    (error (format
+                            "A keymap called %s is not defined in the %s package"
+                            bind-keymap-sym package)))
+                  ;; use `this-command-keys' as `key' may not be the full sequence
+                  (let ((keys (this-command-keys))
+                        (general-implicit-kbd nil))
+                    (general-define-key
+                     :states state
+                     :keymaps keymap
+                     :definer definer
+                     keys (symbol-value bind-keymap-sym))
+                    (setq prefix-arg current-prefix-arg
+                          unread-command-events
+                          (mapcar (lambda (ev) (cons t ev))
+                                  (listify-key-sequence keys))))))
+        (error "In order to \"autoload\" a keymap, :package must be specified"))))
+  edef)
+
+(defun general--define-prefix (command-name &optional map-name menu-name)
+  "Define a prefix command and/or keymap.
+COMMAND-NAME corresponds to the prefix command name. When COMMAND-NAME is
+non-nil, `define-prefix-command' will be used and will be passed MAP-NAME and
+MENU-NAME. When COMMAND-NAME is nil and MAP-NAME is non-nil, only a prefix
+keymap will be created, and its menu name/prompt will be set to MENU-NAME (if
+MENU-NAME is non-nil). Existing prefix keymaps/commands will not be
+recreated/rebound."
+  (if (or (and command-name (fboundp command-name))
+          (and map-name (boundp map-name)))
+      (or command-name (symbol-value map-name))
+    (cond (command-name
+           (define-prefix-command command-name map-name menu-name))
+          (map-name
+           (eval `(defvar ,map-name (make-sparse-keymap ,menu-name)))))))
+
+(defun general-extended-def-:prefix-command (_state _keymap _key edef _kargs)
+  "Create and return a prefix command or map for the extended definition EDEF.
+The :prefix-command, :prefix-map, and :prefix-name properties from EDEF are
+passed to `general--define-prefix'."
+  ;; NOTE will be called twice if both specified, but doesn't matter because
+  ;; won't recreate prefix-command
+  (setf (cl-getf edef :def)
+        (general--define-prefix (plist-get edef :prefix-command)
+                                (plist-get edef :prefix-map)
+                                (plist-get edef :prefix-name)))
+  edef)
+
+(defalias 'general-extended-def-:prefix-map
+  #'general-extended-def-:prefix-command)
+
+;; http://endlessparentheses.com/define-context-aware-keys-in-emacs.html
+(defun general-extended-def-:predicate (_state _keymap _key edef kargs)
+  "Return an altered extended definition EDEF with a predicate applied.
+The predicate is obtained either from EDEF or KARGS."
+  (let ((def (cl-getf edef :def))
+        (predicate (general--getf edef kargs :predicate)))
+    (setf (cl-getf edef :def)
+          `(menu-item
+            "" nil
+            :filter (lambda (&optional _)
+                      (when ,predicate
+                        ',def))))
+    edef))
+
+;; ** Parsing Extended Definitions
+(defun general--extended-def-p (def)
+  "Return whether DEF is an extended definition."
+  (and (listp def)
+       (not (keymapp def))
+       ;; lambda
+       (not (functionp def))
+       (not (eq (car def) 'menu-item))
+       ;; will error on cons
+       (ignore-errors (cl-some #'keywordp def))))
+
+(defun general--normalize-extended-def (edef)
+  "Rewrite the extended definition EDEF to include a :def property.
+If EDEF is not an extended defintion, make it into one.
+
+This handles the allowed shorthand syntax. For example, these are the same:
+
+ (some-func)
+ (:def some-func)
+
+Some extended definition keywords can be used instead of :def (mainly for
+backwards compatibility). For example, these are the same:
+
+ (some-keymap :keymap t)
+ (:keymap some-keymap)
+ (:def some-keymap :keymap t)"
+  ;; NOTE: This is absolutely necessary for plist functions to work
+  (if (general--extended-def-p edef)
+      (unless (keywordp (car edef))
+        (setq edef (cons :def edef)))
+    (setq edef (list :def edef)))
+  ;; :keymap checks :def always instead of :keymap, and :which-key also checks
+  ;; :def always (instead of :prefix-command)
+  ;; note that :keymap and :prefix-map will later rewrite their :def to the
+  ;; actual keymap value
+  (unless (plist-get edef :def)
+    (setf (cl-getf edef :def)
+          (cl-getf edef :keymap
+                   (cl-getf edef :prefix-command
+                            (plist-get edef :prefix-map)))))
+  edef)
+
+(defun general--extract-def (edef)
+  "Return the bindable definition from the extended definition EDEF."
+  (if (plist-get edef :ignore)
+      ;; just for side effects (e.g. which-key description for prefix)
+      ;; return something that isn't a valid definition
+      :ignore
+    (plist-get edef :def)))
+
+(defun general--run-extended-def-functions (state keymap key edef kargs)
+  "Run the extended definition functions for the matched keywords.
+Pass each extended definition function STATE, KEYMAP, KEY, EDEF, and KARGS. For
+each keyword from `general-extended-def-keywords',
+`general-rewrite-def-keywords', and `general-rewrite-def-after-keywords' found
+in EDEF or KARGS, call the corresponding function named
+general-extended-def-:<keyword>. The functions for
+`general-rewrite-def-keywords' will rewrite the extended definition plist before
+the functions for `general-extended-def-keywords' are called, and the functions
+for `general-rewrite-def-after-keywords' are called after that. Functions
+are called in the order they appear in each list. Finally, return the
+potentially altered extended definition plist."
+  (cl-flet ((run-edef-functions
+             (keywords &optional alter-def)
+             (dolist (keyword keywords)
+               (when (or (plist-get edef keyword)
+                         (and (not
+                               (memq
+                                keyword
+                                general-extended-def-global-ignore-keywords))
+                              (plist-get kargs keyword)))
+                 (let ((ret (funcall
+                             (intern (format "general-extended-def-%s" keyword))
+                             state keymap key edef kargs)))
+                   (when alter-def
+                     (setq edef ret)))))))
+    (run-edef-functions general-rewrite-def-keywords t)
+    (run-edef-functions general-extended-def-keywords)
+    (run-edef-functions general-rewrite-def-after-keywords t))
+  edef)
+
+(defun general--parse-def (state keymap key def kargs)
+  "Rewrite DEF into a valid/bindable definition.
+This function will execute all extended definitions, potentially rewriting the
+original definition (e.g. applying a predicate). Pass STATE, KEYMAP, KEY, DEF, and
+KARGS to each matched extended definition function. See
+`general--run-extended-def-functions' for more information."
+  (setq def (general--normalize-extended-def def))
+  (general--extract-def
+   (general--run-extended-def-functions state keymap key def kargs)))
+
+(defun general--parse-maps (state keymap maps kargs)
+  "Rewrite MAPS so that the definitions are bindable.
+This includes possibly calling `kbd' on keys and parsing extended definitions.
+Turn key/binding pairs in MAPS into triples in the form of (key parsed-def
+original-def) where parsed-def is the bindable form and original-def is the
+original definition as an extended definition plist (turn normal definitions
+into extended definition plists and implicitly add \":def\" to the beginning of
+extended definitions when necessary)."
+  (let (bindable-def)
+    (cl-loop for (key def) on maps by 'cddr
+             do (setq bindable-def
+                      (general--parse-def state keymap key def kargs))
+             unless (eq bindable-def :ignore)
+             collect key
+             and collect (if general-implicit-kbd
+                             (general--kbd bindable-def)
+                           bindable-def)
+             and collect (general--normalize-extended-def def))))
+
+;; * Helper Key Definers
+(declare-function evil-define-minor-mode-key "evil-core")
+(defun general-minor-mode-define-key (state mode key def _orig-def _kargs)
+  "A wrapper for `evil-define-minor-mode-key'."
+  (general-with-eval-after-load 'evil
+    (evil-define-minor-mode-key state mode key def)))
+
+(declare-function lispy-define-key "lispy")
+(defun general-lispy-define-key (_state keymap key def orig-def kargs)
+  "A wrapper for `lispy-define-key'."
+  (general-with-eval-after-load 'lispy
+    (let* ((keymap (general--get-keymap nil keymap))
+           (key (key-description key))
+           (plist (general--getf orig-def kargs :lispy-plist)))
+      (apply #'lispy-define-key keymap key def plist))))
+
+(declare-function worf-define-key "worf")
+(defun general-worf-define-key (_state keymap key def orig-def kargs)
+  "A wrapper for `worf-define-key'."
+  (general-with-eval-after-load 'worf
+    (let* ((keymap (general--get-keymap nil keymap))
+           (key (key-description key))
+           (plist (general--getf orig-def kargs :worf-plist)))
+      (apply #'worf-define-key keymap key def plist))))
+
+(declare-function lpy-define-key "lpy")
+(defun general-lpy-define-key (_state keymap key def _orig-def _kargs)
+  "A wrapper for `lpy-define-key'."
+  (general-with-eval-after-load 'lpy
+    (let* ((keymap (general--get-keymap nil keymap))
+           (key (key-description key)))
+      (lpy-define-key keymap key def))))
+
+(declare-function evil-define-key* "evil-core")
+(defun general--define-key-dispatch (state keymap maps kargs)
+  "In STATE (if non-nil) and KEYMAP, bind MAPS.
+MAPS is composed of triplets of (key parsed-def original-def). This function
+determines the appropriate base definer function to use based depending on
+whether :definer is present in original-def or KARGS or whether STATE is
+non-nil if no custom definer is specified."
+  (when (and general-override-auto-enable
+             (eq keymap 'general-override-mode-map)
+             (not general-override-mode))
+    (general-override-mode))
+  (while maps
+    (let* ((key (pop maps))
+           (def (pop maps))
+           (orig-def (pop maps))
+           (definer (general--getf orig-def kargs :definer)))
+      (if definer
+          (funcall (intern (format "general-%s-define-key"
+                                   (symbol-name definer)))
+                   state keymap key def orig-def kargs)
+        (cond (state
+               ;; just to get the symbol-value of the keymap when it is not
+               ;; global/local
+               (setq keymap (general--get-keymap nil keymap nil t))
+               (general-with-eval-after-load 'evil
+                 (evil-define-key* state keymap key def)))
+              (t
+               (setq keymap (general--get-keymap nil keymap))
+               (define-key keymap key def)))))))
+
+(defvar general--definer-p nil
+  "Whether the current keybinding is being created with `general-define-key'.")
+
+(defun general--define-key
+    (states keymap maps non-normal-maps global-maps kargs)
+  "A helper function for `general-define-key'.
+Choose based on STATES and KEYMAP which of MAPS, NON-NORMAL-MAPS, and
+GLOBAL-MAPS to use for the keybindings. This function will rewrite extended
+definitions, add predicates when applicable, and then choose the base function
+to bind the keys with by calling `general--define-key-dispatch'."
+  (let ((general--definer-p t))
+    (dolist (state states)
+      (let* ((non-normal-p (if state
+                               (memq state general-non-normal-states)
+                             (memq keymap
+                                   (mapcar #'general--evil-keymap-for-state
+                                           general-non-normal-states))))
+             (valid-maps (list (cond ((and non-normal-maps non-normal-p)
+                                      non-normal-maps)
+                                     ((and global-maps non-normal-p)
+                                      nil)
+                                     (t
+                                      maps))
+                               global-maps)))
+        (dolist (maps valid-maps)
+          (when maps
+            (setq maps (general--parse-maps state keymap maps kargs))
+            ;; NOTE: :definer 'minor-mode cannot be specified locally
+            (general--record-keybindings keymap state maps
+                                         (eq (cl-getf kargs :definer)
+                                             'minor-mode))
+            (general--define-key-dispatch state keymap maps kargs)))))))
+
+;; * Functions With Keyword Arguments
+;;;###autoload
+(cl-defun general-define-key
+    (&rest maps &key
+           definer
+           (states general-default-states)
+           (keymaps general-default-keymaps keymaps-specified-p)
+           (prefix general-default-prefix)
+           (non-normal-prefix general-default-non-normal-prefix)
+           (global-prefix general-default-global-prefix)
+           infix
+           prefix-command
+           prefix-map
+           prefix-name
+           predicate
+           ;; related to extended definitions
+           package
+           properties
+           repeat
+           jump
+           major-modes
+           (wk-match-keys t)
+           (wk-match-binding t)
+           (wk-full-keys t)
+           ;; for custom key definers
+           lispy-plist
+           worf-plist
+           &allow-other-keys)
+  "The primary key definition function provided by general.el.
+
+Define MAPS, optionally using DEFINER, in the keymap(s) corresponding to STATES
+and KEYMAPS.
+
+MAPS consists of paired keys (vectors or strings; also see
+`general-implicit-kbd') and definitions (those mentioned in `define-key''s
+docstring and general.el's \"extended\" definitions). All pairs (when not
+ignored) will be recorded and can be later displayed with
+`general-describe-keybindings'.
+
+If DEFINER is specified, a custom key definer will be used to bind MAPS. See
+general.el's documentation/README for more information.
+
+Unlike with normal key definitions functions, the keymaps in KEYMAPS should be
+quoted (this allows using the keymap name for other purposes, e.g. deferring
+keybindings if the keymap symbol is not bound, optionally inferring the
+corresponding major mode for a symbol by removing \"-map\" for :which-key,
+easily storing the keymap name for use with `general-describe-keybindings',
+etc.). Note that general.el provides other key definer macros that do not
+require quoting keymaps.
+
+STATES corresponds to the evil state(s) to bind the keys in. Non-evil users
+should not set STATES. When STATES is non-nil, `evil-define-key*' will be
+used (the evil auxiliary keymaps corresponding STATES and KEYMAPS will be used);
+otherwise `define-key' will be used (unless DEFINER is specified). KEYMAPS
+defaults to 'global. There is also 'local, which create buffer-local
+keybindings for both evil and non-evil keybindings. There are other special,
+user-alterable \"shorthand\" symbols for keymaps and states (see
+`general-keymap-aliases' and `general-state-aliases').
+
+Note that STATES and KEYMAPS can either be lists or single symbols. If any
+keymap does not exist, those keybindings will be deferred until the keymap does
+exist, so using `eval-after-load' is not necessary with this function.
+
+PREFIX corresponds to a key to prefix keys in MAPS with and defaults to none. To
+bind/unbind a key specified with PREFIX, \"\" can be specified as a key in
+MAPS (e.g. ...:prefix \"SPC\" \"\" nil... will unbind space).
+
+The keywords in this paragraph are only useful for evil users. If
+NON-NORMAL-PREFIX is specified, this prefix will be used instead of PREFIX for
+states in `general-non-normal-states' (e.g. the emacs and insert states). This
+argument will only have an effect if one of these states is in STATES or if
+corresponding global keymap (e.g. `evil-insert-state-map') is in KEYMAPS.
+Alternatively, GLOBAL-PREFIX can be used with PREFIX and/or NON-NORMAL-PREFIX to
+bind keys in all states under the specified prefix. Like with NON-NORMAL-PREFIX,
+GLOBAL-PREFIX will prevent PREFIX from applying to `general-non-normal-states'.
+INFIX can be used to append a string to all of the specified prefixes. This is
+potentially useful when you are using GLOBAL-PREFIX and/or NON-NORMAL-PREFIX so
+that you can sandwich keys in between all the prefixes and the specified keys in
+MAPS. This may be particularly useful if you are using default prefixes in a
+wrapper function/macro so that you can add to them without needing to re-specify
+all of them. If none of the other prefix keyword arguments are specified, INFIX
+will have no effect.
+
+If PREFIX-COMMAND or PREFIX-MAP is specified, a prefix command and/or keymap
+will be created. PREFIX-NAME can be additionally specified to set the keymap
+menu name/prompt. If PREFIX-COMMAND is specified, `define-prefix-command' will
+be used. Otherwise, only a prefix keymap will be created. Previously created
+prefix commands/keymaps will never be redefined/cleared. All prefixes (including
+the INFIX key, if specified) will then be bound to PREFIX-COMMAND or PREFIX-MAP.
+If the user did not specify any PREFIX or manually specify any KEYMAPS, general
+will bind all MAPS in the prefix keymap corresponding to either PREFIX-MAP or
+PREFIX-COMMAND instead of in the default keymap.
+
+PREDICATE corresponds to a predicate to check to determine whether a definition
+should be active (e.g. \":predicate '(eobp)\"). Definitions created with a
+predicate will only be active when the predicate is true. When the predicate is
+false, key lookup will continue to search for a match in lower-precedence
+keymaps.
+
+In addition to the normal definitions supported by `define-key', general.el also
+provides \"extended\" definitions, which are plists containing the normal
+definition as well as other keywords. For example, PREDICATE can be specified
+globally or locally in an extended definition. New global (~general-define-key~)
+and local (extended definition) keywords can be added by the user. See
+`general-extended-def-keywords' and general.el's documentation/README for more
+information.
+
+PACKAGE is the global version of the extended definition keyword that specifies
+the package a keymap is defined in (used for \"autoloading\" keymaps)
+
+PROPERTIES, REPEAT, and JUMP are the global versions of the extended definition
+keywords used for adding evil command properties to commands.
+
+MAJOR-MODES, WK-MATCH-KEYS, WK-MATCH-BINDINGS, and WK-FULL-KEYS are the
+corresponding global versions of which-key extended definition keywords. They
+will only have an effect for extended definitions that specify :which-key or
+:wk. See the section on extended definitions in the general.el
+documentation/README for more information.
+
+LISPY-PLIST and WORF-PLIST are the global versions of extended definition
+keywords that are used for each corresponding custom DEFINER."
+  ;; to silence compiler warning; variables that are later extracted from kargs
+  (ignore definer
+          predicate
+          package
+          properties
+          repeat
+          jump
+          major-modes
+          lispy-plist
+          worf-plist)
+  (let ((prefix-def (or prefix-command
+                        (when prefix-map
+                          (list :keymap prefix-map))))
+        non-normal-prefix-maps
+        global-prefix-maps
+        kargs)
+    ;; don't force the user to wrap a single state or keymap in a list
+    (general--ensure-lists states keymaps)
+    ;; unalias states and keymaps
+    (setq states (mapcar (lambda (state) (general--unalias state t))
+                         states))
+    (setq keymaps (mapcar #'general--unalias keymaps))
+    ;; remove keyword arguments from rest var
+    (let ((split-maps (general--remove-keyword-args maps)))
+      (setq maps (car split-maps)
+            ;; order will be preserved; matters for duplicates
+            kargs (append
+                   (list
+                    ;; should be included even if not manually specified
+                    ;; (because have non-nil defaults)
+                    :wk-match-keys wk-match-keys
+                    :wk-match-binding wk-match-binding
+                    :wk-full-keys wk-full-keys
+                    ;; so :keymaps and :states are always lists in kargs
+                    ;; needed for matching against :major-modes
+                    :keymaps keymaps
+                    ;; for consistency; may be useful in future or for user
+                    :states states)
+                   (cadr split-maps))))
+    (general--define-prefix prefix-command prefix-map prefix-name)
+    (when (and (or prefix-map prefix-command)
+               (not (or prefix keymaps-specified-p)))
+      (setq keymaps (list (or prefix-map prefix-command))))
+    ;; TODO reduce code duplication here
+    (when non-normal-prefix
+      (setq non-normal-prefix-maps
+            (general--apply-prefix-and-kbd
+             (general--concat t non-normal-prefix infix)
+             (append (when (and prefix prefix-def)
+                       (list "" prefix-def))
+                     maps))))
+    (when global-prefix
+      (setq global-prefix-maps
+            (general--apply-prefix-and-kbd
+             (general--concat t global-prefix infix)
+             (append (when (and prefix prefix-def)
+                       (list "" prefix-def))
+                     maps))))
+    ;; last so not applying prefix twice
+    (setq maps (general--apply-prefix-and-kbd
+                (general--concat t prefix infix)
+                (append (when (and prefix prefix-def)
+                          (list "" prefix-def))
+                        maps)))
+    (dolist (keymap keymaps)
+      (general--delay `(or (memq ',keymap '(local global))
+                           (boundp ',keymap))
+          `(general--define-key ',states
+                                ',keymap
+                                ',maps
+                                ',non-normal-prefix-maps
+                                ',global-prefix-maps
+                                ',kargs)
+        'after-load-functions t nil
+        (symbol-name
+         (cl-gensym (format "general-define-key-in-%s" keymap)))))))
+
+;;;###autoload
+(defmacro general-emacs-define-key (keymaps &rest args)
+  "A wrapper for `general-define-key' that is similar to `define-key'.
+It has a positional argument for KEYMAPS (that will not be overridden by a later
+:keymaps argument). Besides this, it acts the same as `general-define-key', and
+ARGS can contain keyword arguments in addition to keybindings. This can
+basically act as a drop-in replacement for `define-key', and unlike with
+`general-define-key', KEYMAPS does not need to be quoted."
+  (declare (indent 1))
+  `(general-define-key
+    :keymaps ,(if (and (listp keymaps)
+                       (eq (car keymaps) 'quote))
+                  `,keymaps
+                `',keymaps)
+    ,@args))
+
+;;;###autoload
+(defmacro general-evil-define-key (states keymaps &rest args)
+  "A wrapper for `general-define-key' that is similar to `evil-define-key'.
+It has positional arguments for STATES and KEYMAPS (that will not be overridden
+by a later :keymaps or :states argument). Besides this, it acts the same as
+`general-define-key', and ARGS can contain keyword arguments in addition to
+keybindings. This can basically act as a drop-in replacement for
+`evil-define-key', and unlike with `general-define-key', KEYMAPS does not need
+to be quoted."
+  (declare (indent 2))
+  `(general-define-key
+    :states ,(if (and (listp states)
+                      (eq (car states) 'quote))
+                 `,states
+               `',states)
+    :keymaps ,(if (and (listp keymaps)
+                       (eq (car keymaps) 'quote))
+                  `,keymaps
+                `',keymaps)
+    ,@args))
+
+(defun general--positional-arg-p (arg)
+  "Return whether ARG is a positional argument for a key definer.
+Keyword arguments and strings/vectors are not considered positional arguments."
+  (and arg
+       (or (symbolp arg) (listp arg))
+       (not (keywordp arg))))
+
+;;;###autoload
+(defmacro general-def (&rest args)
+  "General definer that takes a variable number of positional arguments in ARGS.
+This macro will act as `general-define-key', `general-emacs-define-key', or
+`general-evil-define-key' based on how many of the initial arguments do not
+correspond to keybindings. All quoted and non-quoted lists and symbols before
+the first string, vector, or keyword are considered to be positional arguments.
+This means that you cannot use a function or variable for a key that starts
+immediately after the positional arguments. If you need to do this, you should
+use one of the definers that `general-def' dispatches to or explicitly separate
+the positional arguments from the maps with a bogus keyword pair like
+\":start-maps t\""
+  (declare (indent defun))
+  (let ((pos-args 0))
+    (while (general--positional-arg-p (nth pos-args args))
+      (cl-incf pos-args))
+    (cl-case pos-args
+      (0
+       `(general-define-key ,@args))
+      (1
+       `(general-emacs-define-key ,@args))
+      (2
+       `(general-evil-define-key ,@args)))))
+
+;;;###autoload
+(cl-defmacro general-create-definer (name &rest defaults &key wrapping
+                                          &allow-other-keys)
+  "A helper macro to create wrappers for `general-def'.
+This can be used to create key definers that will use a certain keymap, evil
+state, prefix key, etc. by default. NAME is the wrapper name and DEFAULTS are
+the default arguments. WRAPPING can also be optionally specified to use a
+different definer than `general-def'. It should not be quoted."
+  (declare (indent defun))
+  (let ((defaults (cl-loop for (key val) on defaults by 'cddr
+                           unless (eq key :wrapping)
+                           collect key
+                           and collect val))
+        (definer (or wrapping 'general-def)))
+    `(defmacro ,name (&rest args)
+       (declare (indent defun))
+       ,(let ((print-quoted t))
+          (format
+           "A wrapper for `%s'.
+
+It has the following defaults:
+%s"
+           definer defaults))
+       ;; can still override keywords afterwards (first keyword takes precedence)
+       `(,',definer
+          ,@args ,@',defaults))))
+
+(defun general--starter-arg-p (arg)
+  "Return whether ARG is a keyword or positional argument for a key definer."
+  (or (keywordp arg)
+      (general--positional-arg-p arg)))
+
+;;;###autoload
+(defmacro general-defs (&rest args)
+  "A wrapper that splits into multiple `general-def's.
+Each consecutive grouping of positional argument followed by keyword/argument
+pairs (having only one or the other is fine) marks the start of a new section.
+Each section corresponds to one use of `general-def'. This means that settings
+only apply to the keybindings that directly follow."
+  (declare (indent defun)
+           (debug [&rest sexp]))
+  (let (arglists
+        arglist)
+    (while args
+      (while (and args (general--starter-arg-p (car args)))
+        (when (keywordp (car args))
+          (push (pop args) arglist))
+        (push (pop args) arglist))
+      (while (and args (not (general--starter-arg-p (car args))))
+        (push (pop args) arglist)
+        (push (pop args) arglist))
+      (push (nreverse arglist) arglists)
+      (setq arglist nil))
+    `(progn
+       ,@(mapcar (lambda (arglist)
+                   (cons 'general-def arglist))
+                 (nreverse arglists)))))
+
+;;;###autoload
+(cl-defmacro general-unbind (&rest args)
+  "A wrapper for `general-def' to unbind multiple keys simultaneously.
+Insert after all keys in ARGS before passing ARGS to `general-def.' \":with
+ #'func\" can optionally specified to use a custom function instead (e.g.
+ `ignore')."
+  (declare (indent defun))
+  ;; Note: :with can be at an odd position, so must handle internally and not
+  ;; with &key
+  (let* (with
+         (split-args (general--remove-keyword-args args))
+         (kargs (cl-loop for (key val) on (cadr split-args) by 'cddr
+                         if (eq key :with)
+                         do (setq with val)
+                         else
+                         collect key
+                         and collect val))
+         (positional-args-and-maps
+          ;; interleave appropriate definitions into maps
+          (cl-loop for key in (car split-args)
+                   collect key
+                   and
+                   unless (general--positional-arg-p key)
+                   collect (if (eq with t)
+                               nil
+                             with)))
+         (args (append positional-args-and-maps kargs)))
+    `(general-def ,@args)))
+
+;; * Displaying Keybindings
+(defun general--to-string (x)
+  "Convert key vector or symbol X to a string."
+  (cond ((vectorp x)
+         (key-description x))
+        ((symbolp x)
+         (symbol-name x))
+        (t
+         x)))
+
+;; these sorting functions assume x != y (which will hold true for
+;; `general-keybindings')
+(defun general--< (x y)
+  "Return t if X is alphabetically less than Y.
+Each should be either a string, symbol, or vector. Nil is a special case and is
+considered the \"smallest\"."
+  (cond ((null x)
+         t)
+        ((null y)
+         nil)
+        (t
+         (setq x (general--to-string x)
+               y (general--to-string y))
+         (string< x y))))
+
+(defun general-sort-by-car (list)
+  "Sort LIST by comparing the car of each element with `general--<'."
+  (cl-sort list #'general--< :key #'car))
+
+(defun general-sort-by-cadr (list)
+  "Sort LIST by comparing the cadr of each element with `general--<'."
+  (cl-sort list #'general--< :key #'cadr))
+
+(defvar general-describe-evil-states
+  '(nil
+    insert
+    emacs
+    hybrid
+    normal
+    visual
+    motion
+    operator
+    replace)
+  "Ordered list of evil states used for `general--evil-state-<'.")
+
+(defun general--evil-state-< (x y)
+  "Return t if evil state X should come before state Y.
+If X and Y are conses, the first element will be compared. Ordering is based on
+`general-describe-evil-states' or the symbol names for states not in the list."
+  (let ((xind (cl-position x general-describe-evil-states))
+        (yind (cl-position y general-describe-evil-states)))
+    (cond ((and (null xind)
+                (null yind))
+           (general--< x y))
+          ((null xind)
+           nil)
+          ((null yind)
+           t)
+          (t
+           (< xind yind)))))
+
+(defun general--sort-evil-state-conses (state-conses)
+  "Sort STATE-CONSES using `general--evil-state-<'."
+  (cl-sort state-conses #'general--evil-state-< :key #'car))
+
+(defun general--print-map (map)
+  "Print the keybinding MAP."
+  (cl-destructuring-bind (key command previous) map
+    (princ (format "|=%.50s=|~%.50s~|~%.50s~|\n"
+                   (replace-regexp-in-string "|" "¦" (key-description key))
+                   command
+                   previous))))
+
+(defun general--print-maps-table (maps)
+  "Print an org table for MAPS."
+  (when general-describe-keybinding-sort-function
+    (setq maps (funcall general-describe-keybinding-sort-function maps)))
+  (princ "|key|command|previous|\n|-+-|\n")
+  (dolist (map maps)
+    (general--print-map map))
+  (princ "\n"))
+
+(defun general--print-state-heading (state-cons)
+  "Print a table and possibly a heading for STATE-CONS."
+  (let ((state (car state-cons))
+        (maps (cdr state-cons)))
+    (unless (null state)
+      (princ (capitalize (concat "** " (symbol-name state) " State\n"))))
+    (general--print-maps-table maps)))
+
+(defun general--print-keymap-heading (keymap-cons)
+  "Print headings and tables for KEYMAP-CONS."
+  (let ((keymap (car keymap-cons))
+        (state-conses (cdr keymap-cons)))
+    (princ (capitalize (concat "* " (symbol-name keymap) " Keybindings\n")))
+    (when general-describe-state-sort-function
+      (setq state-conses (funcall general-describe-state-sort-function
+                                  state-conses)))
+    (dolist (state-cons state-conses)
+      (general--print-state-heading state-cons))))
+
+(declare-function org-at-heading-p "org")
+(declare-function org-table-align "org-table")
+(declare-function outline-next-heading "outline")
+(defvar org-startup-folded)
+;;;###autoload
+(defun general-describe-keybindings (&optional arg)
+  "Show all keys that have been bound with general in an org buffer.
+Any local keybindings will be shown first followed by global keybindings.
+With a non-nil prefix ARG only show bindings in active maps."
+  (interactive "P")
+  (with-output-to-temp-buffer "*General Keybindings*"
+    (let* ((keybindings (append
+                         (copy-alist general-keybindings)
+                         (list (cons 'local general-local-keybindings))))
+           (active-maps (current-active-maps)))
+      ;; print prioritized keymaps first (if any)
+      (dolist (keymap general-describe-priority-keymaps)
+        (let ((keymap-cons (assq keymap keybindings)))
+          (when (and keymap-cons
+                     (or (null arg)
+                         (and (boundp (car keymap-cons))
+                              (memq (symbol-value (car keymap-cons))
+                                    active-maps))))
+            (general--print-keymap-heading keymap-cons)
+            (setq keybindings (assq-delete-all keymap keybindings)))))
+      ;; sort the remaining and then print them
+      (when general-describe-keymap-sort-function
+        (setq keybindings (funcall general-describe-keymap-sort-function
+                                   keybindings)))
+      (dolist (keymap-cons keybindings)
+        (when (or (null arg)
+                  (and (boundp (car keymap-cons))
+                       (memq (symbol-value (car keymap-cons)) active-maps)))
+          (general--print-keymap-heading keymap-cons)))))
+  (with-current-buffer "*General Keybindings*"
+    (let ((org-startup-folded 'showall))
+      (org-mode))
+    (read-only-mode -1)
+    (while (progn
+             (while (progn
+                      (forward-line)
+                      (org-at-heading-p)))
+             (org-table-align)
+             (outline-next-heading)))
+    (goto-char (point-min))
+    (read-only-mode)))
+
+;; * Functions/Macros to Aid Key Definition
+;; ** Helpers
+(cl-defun general--call-interactively
+    (function &optional (remap t) record-flag keys)
+  "Like `call-interactively' but use the remapped FUNCTION if it exists.
+If REMAP is specified as nil (it is true by default), this is the same as
+`call-interactively'. FUNCTION, RECORD-FLAG, and KEYS are passed to
+`call-interactively'."
+  (when remap
+    (setq function (or (key-binding (kbd (format "<remap> <%s>" function)))
+                       function)))
+  (call-interactively function record-flag keys))
+
+;; ** Key Simulation
+;; https://emacs.stackexchange.com/questions/6037/emacs-bind-key-to-prefix/13432#13432
+;; altered to
+;; - allow execution in an arbitrary state and keymap
+;; - create a named function with a docstring
+;; - optionally dynamically lookup the key(s) up in the correct keymap to try to
+;;   match a command to execute instead
+;; - handle more edge cases like correctly working with macros/repeating
+
+;; TODO
+;; - rename keys arguments to key for consistency with builtin functions
+
+(declare-function evil-change-state "evil-core")
+(defvar evil-no-display)
+(defvar evil-state)
+(defvar evil-previous-state)
+(defvar evil-previous-state-alist)
+(defvar evil-next-state)
+(defmacro general--save-state (&rest body)
+  "Save the current state; execute BODY; restore the state.
+This is a combination of `evil-without-display' and `evil-save-state'. It is
+necessary to define this directly in general so that it is available when
+general is compiled (as evil is an optional dependency and may not be installed
+when general is compiled)."
+  (declare (indent defun)
+           (debug t))
+  `(let* ((evil-no-display t)
+          (evil-state evil-state)
+          (evil-previous-state evil-previous-state)
+          (evil-previous-state-alist (copy-tree evil-previous-state-alist))
+          (evil-next-state evil-next-state)
+          (old-state evil-state)
+          (inhibit-quit t)
+          (buf (current-buffer)))
+     (unwind-protect
+         (progn ,@body)
+       (when (buffer-live-p buf)
+         (with-current-buffer buf
+           (evil-change-state old-state))))))
+
+;;;###autoload
+(cl-defmacro general-key (key &key
+                              state
+                              docstring
+                              accept-default no-remap position)
+  "Act as KEY's definition in the current context.
+This uses an extended menu item's capability of dynamically computing a
+definition. It is recommended over `general-simulate-key' wherever possible. KEY
+should be a string given in `kbd' notation and should correspond to a single
+definition (as opposed to a sequence of commands). When STATE is specified, look
+up KEY with STATE as the current evil state. When specified, DOCSTRING will be
+the menu item's name/description. ACCEPT-DEFAULT, NO-REMAP, and POSITION are
+passed to `key-binding'."
+  `'(menu-item
+     ,(or docstring "")
+     nil
+     :filter
+     (lambda (&optional _)
+       ,(if state
+            `(general--save-state
+               (evil-change-state ,state)
+               (key-binding (general--kbd ,key) ,accept-default ,no-remap
+                            ,position))
+          `(key-binding (general--kbd ,key) ,accept-default ,no-remap
+                        ,position)))))
+
+(defvar general--last-simulated-command nil
+  "Holds the last simulated command (or nil for incomplete key sequence).")
+
+(defvar general--simulate-next-as-is nil
+  "Whether to fake keys unconditionally in the next `general--simulate-keys'.
+This is used for testing (but could potentially be useful for a user). Since
+`general--simulate-keys' will normally assume it is being run inside a macro
+that was manually recorded, this is needed when executing a keyboard macro that
+ends up running `general--simulate-keys' for the first time.")
+
+(defvar general--simulate-as-is nil
+  "Whether to fake the keys unconditionally in any `general--simulate-keys'.")
+
+(defun general--key-binding (keys &optional state keymap)
+  "Look up KEYS in the keymap corresponding to STATE and/or KEYMAP.
+Continually check whether subsequences of KEYS are bound to a command or keymap
+starting with the full KEYS and ending when a match is found or no subsequences
+remain. Unlike `lookup-key' if KEYS is not matched, fall back to checking with
+`key-binding'. If STATE is specified and KEYMAP is not, temporarily switch to
+STATE to look up the keys (this means that keybindings inherited from a
+different evil state can still be detected). Return a list of the match and the
+leftover keys (or nil if the full KEYS was matched)."
+  (let* ((keymap (when keymap
+                   (general--get-keymap state keymap)))
+         (len (length keys))
+         (ind len)
+         match)
+    (while (and (> ind 0) (not match))
+      (let* ((key (substring keys 0 ind))
+             (result (cond (keymap
+                            (or (lookup-key keymap key)
+                                (key-binding key)))
+                           (state
+                            ;; this also works fine when evil-local-mode is off
+                            (general--save-state
+                              (evil-change-state state)
+                              (key-binding key)))
+                           (t
+                            (key-binding key)))))
+        (if (or (commandp result)
+                (keymapp result))
+            (setq match result)
+          (cl-decf ind))))
+    (list match
+          (if (= ind len)
+              nil
+            (substring keys ind len)))))
+
+(cl-defun general--simulate-keys (command keys &optional state keymap
+                                          (lookup t)
+                                          (remap t))
+  "Simulate COMMAND followed by KEYS in STATE and/or KEYMAP.
+If COMMAND is nil, just simulate KEYS. If STATE and KEYMAP are nil, simulate the
+keys in the current context. When COMMAND is non-nil, STATE and KEYMAP will have
+no effect. KEYS should be a string that can be passed to `kbd' or nil. If KEYS
+is nil, the COMMAND will just be called interactively. If COMMAND is nil and
+LOOKUP is non-nil, KEYS will be looked up in the correct context to determine if
+any subsequence corresponds to a command or keymap. If a command is matched,
+that command will be called followed by the simulation of any leftover keys. To
+simulate the keys as-is without any lookup, LOOKUP can be explicitly specified
+as nil. When COMMAND has been remapped (i.e. [remap COMMAND] is currently
+bound), the remapped version will be used instead of the original command unless
+REMAP is specified as nil (it is true by default)."
+  (let* ((keys (when keys
+                 (general--kbd keys)))
+         ;; TODO remove when get rid of `general-simulate-keys'
+         (state (if (eq state t)
+                    'emacs
+                  state)))
+    (unless (or command (not lookup))
+      (cl-destructuring-bind (match leftover-keys)
+          (general--key-binding keys state keymap)
+        (cond ((commandp match)
+               (setq command match
+                     keys leftover-keys))
+              ;; not documented because no current use case
+              ;; left in because may be useful later
+              ((and (eq lookup 'always) (keymapp match))
+               (setq keymap match
+                     state nil
+                     ;; should be nil
+                     keys leftover-keys)))))
+    ;; set context for keys
+    (when (and keymap (not command))
+      ;; TODO is it possible to set transient map and then use e.g.
+      ;; `evil-execute-in-normal-state' (so that commands bound in the motion
+      ;; state auxiliary map could also be executed)?
+      (set-transient-map (general--get-keymap state keymap)))
+    (when keys
+      ;; only set prefix-arg when only keys
+      ;; (otherwise will also affect the next command)
+      (unless command
+        (setq prefix-arg current-prefix-arg))
+      (when (or general--simulate-as-is
+                general--simulate-next-as-is
+                (not executing-kbd-macro))
+        (setq general--simulate-next-as-is nil)
+        ;; keys are incorrectly saved as this-command-keys when recording macros
+        ;; these keys will be played back, so don't simulate them
+        (setq unread-command-events
+              (nconc
+               ;; force keys to be added to this-command-keys
+               ;; this happens normally already for macros but it needs to be
+               ;; forced for evil-repeat though, which will only include the
+               ;; first key otherwise (ideally no keys would ever be added in
+               ;; either case)
+               (mapcar (lambda (ev) (cons t ev))
+                       (listify-key-sequence keys))
+               unread-command-events))))
+    (when command
+      (let ((this-command command))
+        (general--call-interactively command remap)))
+    (setq general--last-simulated-command command)))
+
+;;;###autoload
+(cl-defmacro general-simulate-keys (keys &optional state keymap
+                                         (lookup t)
+                                         docstring name)
+  "Deprecated. Please use `general-simulate-key' instead."
+  (let* ((command (when (listp keys)
+                    (car keys)))
+         (keys (if (listp keys)
+                   (cadr keys)
+                 keys))
+         (state (if (eq state t)
+                    ''emacs
+                  state))
+         (name (or name
+                   (intern (concat
+                            (format "general-simulate-%s"
+                                    (if command
+                                        (eval command)
+                                      ""))
+                            (when command
+                              "-")
+                            (replace-regexp-in-string " " "_" keys)
+                            (when state
+                              (concat "-in-"
+                                      (symbol-name (eval state))
+                                      "-state"))
+                            (when keymap
+                              (concat "-in-"
+                                      (symbol-name keymap))))))))
+    `(progn
+       (eval-after-load 'evil
+         '(evil-set-command-property #',name :repeat 'general--simulate-repeat))
+       (defun ,name
+           ()
+         ,(or docstring
+              (concat "Simulate "
+                      (when command
+                        (concat "`"
+                                (symbol-name (eval command))
+                                "' then "))
+                      "'"
+                      keys
+                      "' in "
+                      (cond ((and state keymap)
+                             (concat (symbol-name (eval state))
+                                     " state in `"
+                                     (symbol-name keymap)
+                                     "'."))
+                            (keymap
+                             (concat (symbol-name keymap)
+                                     "."))
+                            (state
+                             (concat (symbol-name (eval state))
+                                     " state."))
+                            (t
+                             "the current context."))))
+         (interactive)
+         (general--simulate-keys ,command ,keys ,state ,keymap ,lookup)))))
+(make-obsolete 'general-simulate-keys 'general-simulate-key "2018-01-14")
+
+;;;###autoload
+(cl-defmacro general-simulate-key (keys
+                                   &key
+                                   state keymap
+                                   name docstring
+                                   (lookup t)
+                                   which-key
+                                   (remap t))
+  "Create and return a command that simulates KEYS in STATE and KEYMAP.
+KEYS should be a string given in `kbd' notation. It can also be a list of a
+single command followed by a string of the key(s) to simulate after calling that
+command. STATE should only be specified by evil users and should be a quoted
+evil state. KEYMAP should not be quoted. Both STATE and KEYMAP aliases are
+supported (but they have to be set when the macro is expanded). When neither
+STATE or KEYMAP are specified, the key(s) will be simulated in the current
+context.
+
+If NAME is specified, it will replace the automatically generated function name.
+NAME should not be quoted. If DOCSTRING is specified, it will replace the
+automatically generated docstring.
+
+Normally the generated function will look up KEY in the correct context to try
+to match a command. To prevent this lookup, LOOKUP can be specified as nil.
+Generally, you will want to keep LOOKUP non-nil because this will allow checking
+the evil repeat property of matched commands to determine whether or not they
+should be recorded. See the docstring for `general--simulate-keys' for more
+information about LOOKUP.
+
+When a WHICH-KEY description is specified, it will replace the command name in
+the which-key popup.
+
+When a command name is specified and that command has been remapped (i.e. [remap
+command] is currently bound), the remapped version will be used instead of the
+original command unless REMAP is specified as nil (it is true by default).
+
+The advantages of this over a keyboard macro are as follows:
+- Prefix arguments are supported
+- The user can control the context in which the keys are simulated
+- The user can simulate both a named command and keys
+- The user can simulate an incomplete key sequence (e.g. for a keymap)"
+  (declare (indent defun))
+  (let* ((command (when (listp keys)
+                    (car keys)))
+         (keys (if (listp keys)
+                   (cadr keys)
+                 keys))
+         (state (general--unalias (eval state) t))
+         (keymap (general--unalias keymap))
+         (name (or name
+                   (intern (concat
+                            (format "general-simulate-%s"
+                                    (if command
+                                        (eval command)
+                                      ""))
+                            (when command
+                              "-")
+                            (replace-regexp-in-string " " "_" keys)
+                            (when state
+                              (concat "-in-"
+                                      (symbol-name state)
+                                      "-state"))
+                            (when keymap
+                              (concat "-in-"
+                                      (symbol-name keymap))))))))
+    `(progn
+       (eval-after-load 'evil
+         '(evil-set-command-property #',name :repeat 'general--simulate-repeat))
+       (when ,which-key
+         (general-with-eval-after-load 'which-key
+           (push '((nil . ,(symbol-name name))
+                   nil . ,which-key)
+                 which-key-replacement-alist)))
+       (defun ,name
+           ()
+         ,(or docstring
+              (concat "Simulate "
+                      (when command
+                        (concat "`"
+                                (symbol-name (eval command))
+                                "' then "))
+                      "'"
+                      keys
+                      "' in "
+                      (cond ((and state keymap)
+                             (concat (symbol-name state)
+                                     " state in `"
+                                     (symbol-name keymap)
+                                     "'."))
+                            (keymap
+                             (concat (symbol-name keymap)
+                                     "."))
+                            (state
+                             (concat (symbol-name state)
+                                     " state."))
+                            (t
+                             "the current context."))))
+         (interactive)
+         (general--simulate-keys ,command ,keys ',state ,keymap ,lookup ,remap))
+       #',name)))
+
+(defun general--repeat-abort-p (repeat-prop)
+  "Return t if repeat recording should be aborted based on REPEAT-PROP."
+  (or (memq repeat-prop (list nil 'abort 'ignore))
+      (and (eq repeat-prop 'motion)
+           (not (memq evil-state '(insert replace))))))
+
+(declare-function evil-repeat-record "evil-repeat")
+(declare-function evil-get-command-property "evil-common")
+(declare-function evil-repeat-abort "evil-repeat")
+(declare-function evil-this-command-keys "evil-repeat")
+(declare-function evil-clear-command-keys "evil-repeat")
+(defvar evil-this-register)
+(defun general--simulate-repeat (flag)
+  "Modified version of `evil-repeat-keystrokes'.
+It behaves as normal but will check the repeat property of a simulated command
+to determine whether to abort recording."
+  (cond ((eq flag 'pre)
+         (when evil-this-register
+           (evil-repeat-record
+            `(set evil-this-register ,evil-this-register))))
+        ((eq flag 'post)
+         (let* ((command general--last-simulated-command)
+                (repeat-prop (evil-get-command-property command :repeat t)))
+           (if (and command (general--repeat-abort-p repeat-prop))
+               (evil-repeat-abort)
+             (evil-repeat-record
+              (evil-this-command-keys t))
+             (evil-clear-command-keys))))))
+
+;; ** Key Dispatch
+(defvar general--last-dispatch-command nil
+  "Holds the last command run from a `general-key-dispatch' function.")
+
+(defun general--extend-key-sequence (keys)
+  "Read a key and append it to KEYS.
+KEYS should be a string given in `kbd' notation."
+  (let ((key (read-event)))
+    (concat keys
+            (when keys
+              " ")
+            (key-description (if (characterp key)
+                                 (char-to-string key)
+                               (vector key))))))
+
+;;;###autoload
+(cl-defmacro general-key-dispatch
+    (fallback-command &rest maps
+                      &key
+                      timeout
+                      inherit-keymap
+                      name docstring
+                      which-key
+                      (remap t)
+                      &allow-other-keys)
+  "Create and return a command that runs FALLBACK-COMMAND or a command in MAPS.
+MAPS consists of <key> <command> pairs. If a key in MAPS is matched, the
+corresponding command will be run. Otherwise FALLBACK-COMMAND will be run with
+the unmatched keys. So, for example, if \"ab\" was pressed, and \"ab\" is not
+one of the key sequences from MAPS, the FALLBACK-COMMAND will be run followed by
+the simulated keypresses of \"ab\". Prefix arguments will still work regardless
+of which command is run. This is useful for binding under non-prefix keys. For
+example, this can be used to redefine a sequence like \"cw\" or \"cow\" in evil
+but still have \"c\" work as `evil-change'. If TIMEOUT is specified,
+FALLBACK-COMMAND will also be run in the case that the user does not press the
+next key within the TIMEOUT (e.g. 0.5).
+
+NAME and DOCSTRING are optional keyword arguments. They can be used to replace
+the automatically generated name and docstring for the created function. By
+default, `cl-gensym' is used to prevent name clashes (e.g. allows the user to
+create multiple different commands using `self-insert-command' as the
+FALLBACK-COMMAND without explicitly specifying NAME to manually prevent
+clashes).
+
+When INHERIT-KEYMAP is specified, all the keybindings from that keymap will be
+inherited in MAPS.
+
+When a WHICH-KEY description is specified, it will replace the command name in
+the which-key popup.
+
+When command to be executed has been remapped (i.e. [remap command] is currently
+bound), the remapped version will be used instead of the original command unless
+REMAP is specified as nil (it is true by default)."
+  (declare (indent 1))
+  (let ((name (or name (cl-gensym (format "general-dispatch-%s-"
+                                          (eval fallback-command)))))
+        ;; remove keyword arguments from maps
+        (maps (car (general--remove-keyword-args maps))))
+    `(progn
+       (eval-after-load 'evil
+         '(evil-set-command-property #',name :repeat 'general--dispatch-repeat))
+       (when ,which-key
+         (general-with-eval-after-load 'which-key
+           (push '((nil . ,(symbol-name name))
+                   nil . ,which-key)
+                 which-key-replacement-alist)))
+       ;; TODO list all of the bound keys in the docstring
+       (defun ,name ()
+         ,(or docstring (format (concat "Run %s or something else based"
+                                        "on the next keypresses.")
+                                (eval fallback-command)))
+         (interactive)
+         (let ((map (make-sparse-keymap))
+               (maps (list ,@maps))
+               (invoked-keys (this-command-keys))
+               (timeout ,timeout)
+               (inherit-keymap ,inherit-keymap)
+               matched-command
+               fallback
+               char
+               timed-out-p)
+           (when inherit-keymap
+             (set-keymap-parent map inherit-keymap))
+           (while maps
+             (define-key map (general--kbd (pop maps)) (pop maps)))
+           (while (progn
+                    (if timeout
+                        (with-timeout (timeout (setq timed-out-p t))
+                          ;; TODO rename char
+                          (setq char (general--extend-key-sequence char)))
+                      (setq char (general--extend-key-sequence char)))
+                    (and (not timed-out-p)
+                         (keymapp (lookup-key map (kbd char))))))
+           (cond
+            ((and (not timed-out-p)
+                  (setq matched-command (lookup-key map (kbd char))))
+             ;; necessary for evil-this-operator checks because
+             ;; evil-define-operator sets evil-this-operator to this-command
+             (let ((this-command matched-command))
+               (general--call-interactively matched-command ,remap)))
+            (t
+             (setq matched-command ,fallback-command)
+             (general--simulate-keys ,fallback-command char
+                                     nil nil t ,remap)))
+           (setq general--last-dispatch-command matched-command)))
+       #',name)))
+
+(defun general--dispatch-repeat (flag)
+  "Modified version of `evil-repeat-keystrokes'.
+It behaves as normal but will check the repeat property of a simulated command
+to determine whether to abort recording."
+  (cond ((eq flag 'pre)
+         (when evil-this-register
+           (evil-repeat-record
+            `(set evil-this-register ,evil-this-register))))
+        ((eq flag 'post)
+         (let ((repeat-prop (evil-get-command-property
+                             general--last-dispatch-command
+                             :repeat t)))
+           (if (general--repeat-abort-p repeat-prop)
+               (evil-repeat-abort)
+             (evil-repeat-record (evil-this-command-keys t))
+             (evil-clear-command-keys))))))
+
+;; ** Predicate Dispatch
+;;;###autoload
+(cl-defmacro general-predicate-dispatch
+    (fallback-def &rest defs
+                  &key docstring
+                  &allow-other-keys)
+  (declare (indent 1))
+  "Create a menu item that will run FALLBACK-DEF or a definition from DEFS.
+DEFS consists of <predicate> <definition> pairs. Binding this menu-item to a key
+will cause that key to act as the corresponding definition (a command, keymap,
+etc) for the first matched predicate. If no predicate is matched FALLBACK-DEF
+will be run. When FALLBACK-DEF is nil and no predicates are matched, the keymap
+with the next highest precedence for the pressed key will be checked. DOCSTRING
+can be specified as a description for the menu item."
+  ;; remove keyword arguments from defs and sort defs into pairs
+  (let ((defs (cl-loop for (key value) on defs by 'cddr
+                       unless (keywordp key)
+                       collect (list key value))))
+    `'(menu-item
+       ,(or docstring "") nil
+       :filter (lambda (&optional _)
+                 (cond ,@(mapcar (lambda (pred-def)
+                                   `(,(car pred-def) ,(cadr pred-def)))
+                                 defs)
+                       (t ,fallback-def))))))
+
+;; ** Key "Translation"
+;;;###autoload
+(cl-defun general-translate-key (states keymaps
+                                        &rest maps
+                                        &key destructive
+                                        &allow-other-keys)
+  "Translate keys in the keymap(s) corresponding to STATES and KEYMAPS.
+STATES should be the name of an evil state, a list of states, or nil. KEYMAPS
+should be a symbol corresponding to the keymap to make the translations in or a
+list of keymap names. Keymap and state aliases are supported (as well as 'local
+and 'global for KEYMAPS). MAPS corresponds to a list of translations (key
+replacement pairs). For example, specifying \"a\" \"b\" will bind \"a\" to
+\"b\"'s definition in the keymap. If DESTRUCTIVE is non-nil, the keymap will be
+destructively altered without creating a backup. If DESTRUCTIVE is nil, a backup
+of the keymap will be stored on the initial invocation, and future invocations
+will always look up keys in the backup keymap. On the other hand, if DESTRUCTIVE
+is non-nil, calling this function multiple times with \"a\" \"b\" \"b\" \"a\",
+for example, would continue to swap and unswap the definitions of these keys.
+This means that when DESTRUCTIVE is non-nil, all related swaps/cycles should be
+done in the same invocation."
+  (declare (indent defun))
+  (general--ensure-lists states keymaps)
+  (dolist (keymap-name keymaps)
+    (dolist (state states)
+      (setq keymap-name (general--unalias keymap-name)
+            state (general--unalias state t))
+      (let* ((keymap (general--get-keymap state keymap-name))
+             (backup-keymap (intern (format "general-%s%s-backup-map"
+                                            keymap-name
+                                            (if state
+                                                (format "-%s-state" state)
+                                              ""))))
+             (lookup-keymap (if (and (not destructive)
+                                     (boundp backup-keymap))
+                                (symbol-value backup-keymap)
+                              (copy-keymap keymap)))
+             (maps (cl-loop for (key replacement) on maps by 'cddr
+                            ;; :destructive can be in MAPS
+                            unless (keywordp key)
+                            collect (general--kbd key)
+                            and collect (lookup-key
+                                         lookup-keymap
+                                         (general--kbd replacement)))))
+        (unless (or destructive
+                    (boundp backup-keymap))
+          (set backup-keymap lookup-keymap))
+        (apply #'general-define-key :states state :keymaps keymap-name maps)))))
+
+;;;###autoload
+(defmacro general-swap-key (states keymaps &rest args)
+  "Wrapper around `general-translate-key' for swapping keys.
+STATES, KEYMAPS, and ARGS are passed to `general-translate-key'. ARGS should
+consist of key swaps (e.g. \"a\" \"b\" is equivalent to \"a\" \"b\" \"b\" \"a\"
+with `general-translate-key') and optionally keyword arguments for
+`general-translate-key'."
+  (declare (indent defun))
+  (setq args (cl-loop for (key replacement) on args by 'cddr
+                      collect key and collect replacement
+                      and unless (keywordp key)
+                      collect replacement and collect key))
+  `(general-translate-key ,states ,keymaps ,@args))
+
+;; ** Automatic Key Unbinding
+(defun general-unbind-non-prefix-key (define-key keymap key def)
+  "Use DEFINE-KEY in KEYMAP to unbind an existing non-prefix subsequence of KEY.
+When a general key definer is in use and a subsequnece of KEY is already bound
+in KEYMAP, unbind it using DEFINE-KEY. Always bind KEY to DEF using DEFINE-KEY."
+  (when general--definer-p
+    (let ((key (if (stringp key)
+                   (string-to-vector key)
+                 key)))
+      (while (numberp (lookup-key keymap key))
+        (setq key (cl-subseq key 0 -1)))
+      (funcall define-key keymap key nil)))
+  (funcall define-key keymap key def))
+
+;;;###autoload
+(defun general-auto-unbind-keys (&optional undo)
+  "Advise `define-key' to automatically unbind keys when necessary.
+This will prevent errors when a sub-sequence of a key is already bound (e.g. the
+user attempts to bind \"SPC a\" when \"SPC\" is bound, resulting in a \"Key
+sequnce starts with non-prefix key\" error). When UNDO is non-nil, remove
+advice."
+  (if undo
+      ;; using general versions in case start recording advice for later display
+      (general-advice-remove 'define-key #'general-unbind-non-prefix-key)
+    (general-advice-add 'define-key :around #'general-unbind-non-prefix-key)))
+
+;; ** Interactive Lambdas
+(defmacro general-lambda (&rest body)
+  "Wrap BODY in an interactive lamba"
+  `(lambda () (interactive)
+     ,@body))
+
+(defalias 'general-l #'general-lambda)
+
+;; * Functions/Macros to Aid Other Configuration
+;; ** Settings
+(defmacro general-setq (&rest settings)
+  "A stripped-down `customize-set-variable' with the syntax of `setq'.
+Like `setq', multiple variables can be set at once; SETTINGS should consist of
+variable value pairs. Some variables have a custom setter (specified with
+`defcustom' and :set) that is used to run code necessary for changes to take
+effect (e.g. `auto-revert-interval'). If a package has already been loaded, and
+the user uses `setq' to set one of these variables, the :set code will not
+run (e.g. in the case of `auto-revert-interval', the timer will not be updated).
+Like with `customize-set-variable', `general-setq' will use the custom :set
+setter when necessary. If the package defining the variable has not yet been
+loaded, the custom setter will not be known, but it will still be run upon
+loading the package. Unlike `customize-set-variable', `general-setq' does not
+attempt to load any dependencies for the variable and does not support giving
+variables comments."
+  `(progn
+     ,@(cl-loop for (var val) on settings by 'cddr
+                collect `(funcall (or (get ',var 'custom-set) #'set-default)
+                                  ',var ,val))))
+
+;; ** Hooks
+;;;###autoload
+(defun general-add-hook (hooks functions &optional append local)
+  "A drop-in replacement for `add-hook'.
+Unlike `add-hook', HOOKS and FUNCTIONS can be single items or lists. APPEND and
+LOCAL are passed directly to `add-hook'."
+  (general--ensure-lists hooks functions)
+  (dolist (hook hooks)
+    (dolist (func functions)
+      (add-hook hook func append local))))
+
+;;;###autoload
+(defun general-remove-hook (hooks functions &optional local)
+  "A drop-in replacement for `remove-hook'.
+Unlike `remove-hook', HOOKS and FUNCTIONS can be single items or lists. LOCAL is
+passed directly to `remove-hook'."
+  (general--ensure-lists hooks functions)
+  (dolist (hook hooks)
+    (dolist (func functions)
+      (remove-hook hook func local))))
+
+;; ** Advice
+;;;###autoload
+(defun general-advice-add (symbols where functions &optional props)
+  "A drop-in replacement for `advice-add'.
+SYMBOLS, WHERE, FUNCTIONS, and PROPS correspond to the arguments for
+`advice-add'. Unlike `advice-add', SYMBOLS and FUNCTIONS can be single items or
+lists."
+  (general--ensure-lists symbols functions)
+  (dolist (symbol symbols)
+    (dolist (func functions)
+      (advice-add symbol where func props))))
+
+;; specify full autoload to prevent function indirection (autoload generation
+;; will put a /flipped/ defalias into the autoloads file causing an infinite
+;; loop)
+;;;###autoload (autoload 'general-add-advice "general")
+(defalias 'general-add-advice #'general-advice-add)
+
+;;;###autoload
+(defun general-advice-remove (symbols functions)
+  "A drop-in replacement for `advice-remove'.
+Unlike `advice-remove', SYMBOLS and FUNCTIONS can be single items or lists."
+  (general--ensure-lists symbols functions)
+  (dolist (symbol symbols)
+    (dolist (func functions)
+      (advice-remove symbol func))))
+
+;;;###autoload (autoload 'general-remove-advice "general")
+(defalias 'general-remove-advice #'general-advice-remove)
+
+;; * Optional Setup
+;;;###autoload
+(defun general-evil-setup (&optional short-names _)
+  "Set up some basic equivalents for vim mapping functions.
+This creates global key definition functions for the evil states.
+Specifying SHORT-NAMES as non-nil will create non-prefixed function
+aliases such as `nmap' for `general-nmap'."
+  (general-create-definer general-imap :states 'insert)
+  (general-create-definer general-emap :states 'emacs)
+  (general-create-definer general-nmap :states 'normal)
+  (general-create-definer general-vmap :states 'visual)
+  (general-create-definer general-mmap :states 'motion)
+  (general-create-definer general-omap :states 'operator)
+  (general-create-definer general-rmap :states 'replace)
+  (general-create-definer general-iemap :states '(insert emacs))
+  (general-create-definer general-nvmap :states '(normal visual))
+  ;; these two don't have corresponding states
+  (general-create-definer general-itomap :keymaps 'evil-inner-text-objects-map)
+  (general-create-definer general-otomap :keymaps 'evil-outer-text-objects-map)
+  (general-create-definer general-tomap
+    :keymaps '(evil-outer-text-objects-map
+               evil-inner-text-objects-map))
+  (when short-names
+    (defalias 'imap #'general-imap)
+    (defalias 'emap #'general-emap)
+    (defalias 'nmap #'general-nmap)
+    (defalias 'vmap #'general-vmap)
+    (defalias 'mmap #'general-mmap)
+    (defalias 'omap #'general-omap)
+    (defalias 'rmap #'general-rmap)
+    (defalias 'iemap #'general-iemap)
+    (defalias 'nvmap #'general-nvmap)
+    (defalias 'itomap #'general-itomap)
+    (defalias 'otomap #'general-otomap)
+    (defalias 'tomap #'general-tomap)))
+
+;; * Use-package Integration
+;; maybe useful for something else in future
+(defun general--extract-autoloadable-symbol (def)
+  "Extract an autoloadable symbol from DEF, a normal or extended definition.
+This will also correctly extract the definition from a cons of the form (STRING
+. DEFN). If the extracted definition is nil, a string, a lambda, a keymap symbol
+from an extended definition, or some other definition that cannot be autoloaded,
+return nil."
+  ;; explicit null checks not required because nil return value means no def
+  (when (general--extended-def-p def)
+    ;; extract definition
+    (let ((first (car def)))
+      (setq def (if (keywordp first)
+                    (plist-get def :def)
+                  first))))
+  (cond ((symbolp def)
+         def)
+        ((and (consp def)
+              (symbolp (cdr def)))
+         (cdr def))))
+
+(general-with-eval-after-load 'use-package-core
+  (declare-function use-package-concat "use-package")
+  (declare-function use-package-process-keywords "use-package")
+  (defvar use-package-keywords)
+  (defvar use-package-deferring-keywords)
+  ;; ** :general Keyword
+  (setq use-package-keywords
+        ;; should go in the same location as :bind
+        ;; adding to end may not cause problems, but see issue #22
+        (cl-loop for item in use-package-keywords
+                 if (eq item :bind-keymap*)
+                 collect :bind-keymap* and collect :general
+                 else
+                 ;; don't add duplicates
+                 unless (eq item :general)
+                 collect item))
+
+  ;; altered args will be passed to the autoloads and handler functions
+  (defun use-package-normalize/:general (_name _keyword general-arglists)
+    "Return a plist containing the original ARGLISTS and autoloadable symbols."
+    (let* ((sanitized-arglist
+            ;; combine arglists into one without function names or
+            ;; positional arguments
+            (let (result)
+              (dolist (arglist general-arglists result)
+                (while (general--positional-arg-p (car arglist))
+                  (setq arglist (cdr arglist)))
+                (setq result (append result arglist)))))
+           (commands
+            (cl-loop for (key def) on sanitized-arglist by 'cddr
+                     when (and (not (keywordp key))
+                               (not (null def))
+                               (ignore-errors
+                                 ;; TODO use cdr instead if possible
+                                 (setq def (eval def))
+                                 (setq def (general--extract-autoloadable-symbol
+                                            def))))
+                     collect def)))
+      (list :arglists general-arglists :commands commands)))
+
+  (defun use-package-autoloads/:general (_name _keyword args)
+    "Return an alist of commands extracted from ARGS.
+Return something like '((some-command-to-autoload . command) ...)."
+    (mapcar (lambda (command) (cons command 'command))
+            (plist-get args :commands)))
+
+  (defun use-package-handler/:general (name _keyword args rest state)
+    "Use-package handler for :general."
+    (use-package-concat
+     (use-package-process-keywords name rest state)
+     `(,@(mapcar (lambda (arglist)
+                   ;; Note: prefix commands are not valid functions
+                   (if (or (functionp (car arglist))
+                           (macrop (car arglist)))
+                       `(,@arglist :package ',name)
+                     `(general-def
+                        ,@arglist
+                        :package ',name)))
+                 (plist-get args :arglists)))))
+
+  ;; ** :ghook and :gfhook Keyword
+  (setq use-package-keywords
+        ;; should go in the same location as :bind
+        ;; adding to end may not cause problems, but see issue #22
+        (cl-loop for item in use-package-keywords
+                 if (eq item :hook)
+                 collect :hook and collect :ghook and collect :gfhook
+                 else
+                 ;; don't add duplicates
+                 unless (memq item '(:ghook :gfhook))
+                 collect item))
+
+  (defun general-normalize-hook-arglist (arglist mode-enable mode-hook
+                                                 &optional symbol-is-function-p)
+    "Rewrite a :g(f)hook ARGLIST to a `general-add-hook' arglist.
+MODE-ENABLE is the inferred command to enable the package's mode, and MODE-HOOK
+is the mode inferred hook to enable the package's mode. When ARGLIST is a symbol
+instead of a list, it will be considered to be a hook name unless
+SYMBOL-IS-FUNCTION-P is non-nil, in which case it will considered to be a
+function."
+    ;; standalone symbols are quoted automatically; unquote
+    (when (ignore-errors (memq (car arglist) (list 'quote 'function)))
+      (setq arglist (cadr arglist)))
+    (cond ((listp arglist)
+           ;; necessary to extract commands because they could be stored in a
+           ;; variable or returned by a macro/function
+           ;; e.g. (list #'func1 #'func2) needs to be evaluated
+           (setq arglist (mapcar (lambda (arg) (eval arg))
+                                 arglist))
+           (if (= (length arglist) 1)
+               ;; <user specified hook(s)> #'<package>-mode
+               (append arglist (list mode-enable))
+             (let ((hooks (car arglist))
+                   (functions (cadr arglist)))
+               (when (or (null hooks)
+                         (not (or (symbolp hooks)
+                                  (listp hooks))))
+                 (setq hooks mode-hook))
+               (when (or (null functions)
+                         (not (or (symbolp functions)
+                                  (listp functions))))
+                 (setq functions mode-enable))
+               (cons hooks (cons functions (cddr arglist))))))
+          (t
+           (if symbol-is-function-p
+               ;; '<package>-mode-hook <user specified function>
+               (list mode-hook arglist)
+             ;; <user specified hook> #'<package>-mode
+             (list arglist mode-enable)))))
+
+  ;; altered args will be passed to the autoloads and handler functions
+  (defun general-normalize-hook (name _keyword args &optional gfhookp)
+    "Return a plist containing arglists and autoloadable commands.
+Transform ARGS into arglists suitable for `general-add-hook'."
+    (let* ((mode (if (string-match-p "mode\\'" (symbol-name name))
+                     name
+                   (intern (format "%s-mode" name))))
+           (mode-hook (intern (format "%s-hook" mode))))
+      (cl-loop for arg in args
+               collect (general-normalize-hook-arglist
+                        arg mode mode-hook gfhookp))))
+
+  (defalias 'use-package-normalize/:ghook #'general-normalize-hook)
+
+  (defun use-package-autoloads/:ghook (_name _keyword arglists)
+    "Return an alist of commands extracted from ARGLISTS.
+Return something like '((some-command-to-autoload . command) ...)."
+    (let ((commands
+           (cl-loop for (_ functions) in arglists
+                    if (symbolp functions)
+                    collect functions
+                    else
+                    unless (functionp functions)
+                    append (cl-loop for function in functions
+                                    when (symbolp function)
+                                    collect function))))
+      (mapcar (lambda (command) (cons command 'command))
+              commands)))
+
+  (defun use-package-handler/:ghook (name _keyword arglists rest state)
+    "Use-package handler for :ghook and :gfhook."
+    (use-package-concat
+     (use-package-process-keywords name rest state)
+     `(,@(mapcar (lambda (arglist)
+                   arglist
+                   ;; requote (unfortunately need to evaluate in normalizer)
+                   `(general-add-hook ,@(mapcar (lambda (x) `',x)
+                                                arglist)))
+                 arglists))))
+
+  (defun use-package-normalize/:gfhook (name keyword args)
+    "Use-package normalizer for :gfhook."
+    (general-normalize-hook name keyword args t))
+
+  (defalias 'use-package-handler/:gfhook #'use-package-handler/:ghook))
+
+;; * Key-chord "Integration"
+(defun general-chord (keys)
+  "Rewrite the string KEYS into a valid key-chord vector."
+  ;; taken straight from key-chord.el
+  (if (/= 2 (length keys))
+      (error "Key-chord keys must have two elements"))
+  ;; Exotic chars in a string are >255 but define-key wants 128..255 for those
+  (let ((key1 (logand 255 (aref keys 0)))
+        (key2 (logand 255 (aref keys 1))))
+    (vector 'key-chord key1 key2)))
+
+(provide 'general)
+;;; general.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/ghub-20180715.1159/dir b/configs/shared/emacs/.emacs.d/elpa/ghub-20180715.1159/dir
new file mode 100644
index 0000000000..6bd2b68c23
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/ghub-20180715.1159/dir
@@ -0,0 +1,18 @@
+This is the file .../info/dir, which contains the
+topmost node of the Info hierarchy, called (dir)Top.
+The first time you invoke Info you start off looking at this node.
+
+File: dir,	Node: Top	This is the top of the INFO tree
+
+  This (the Directory node) gives a menu of major topics.
+  Typing "q" exits, "?" lists all Info commands, "d" returns here,
+  "h" gives a primer for first-timers,
+  "mEmacs<Return>" visits the Emacs manual, etc.
+
+  In Emacs, you can click mouse button 2 on a menu item or cross reference
+  to select it.
+
+* Menu:
+
+Emacs
+* Ghub: (ghub).                 Minuscule client library for the Github API.
diff --git a/configs/shared/emacs/.emacs.d/elpa/ghub-20180715.1159/ghub-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/ghub-20180715.1159/ghub-autoloads.el
new file mode 100644
index 0000000000..3aa6fde0e1
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/ghub-20180715.1159/ghub-autoloads.el
@@ -0,0 +1,37 @@
+;;; ghub-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "ghub" "ghub.el" (23377 61608 155696 336000))
+;;; Generated autoloads from ghub.el
+
+(autoload 'ghub-create-token "ghub" "\
+Create, store and return a new token.
+
+HOST is the Github instance, usually \"api.github.com\".
+USERNAME is the name of a user on that instance.
+PACKAGE is the package that will use the token.
+SCOPES are the scopes the token is given access to.
+
+\(fn HOST USERNAME PACKAGE SCOPES)" t nil)
+
+(autoload 'ghub-token-scopes "ghub" "\
+Return and echo the scopes of the specified token.
+This is intended for debugging purposes only.  The user
+has to provide several values including their password.
+
+\(fn HOST USERNAME PACKAGE)" t nil)
+
+;;;***
+
+;;;### (autoloads nil nil ("ghub-pkg.el") (23377 61608 160174 126000))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; ghub-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/ghub-20180715.1159/ghub-pkg.el b/configs/shared/emacs/.emacs.d/elpa/ghub-20180715.1159/ghub-pkg.el
new file mode 100644
index 0000000000..5394ab8594
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/ghub-20180715.1159/ghub-pkg.el
@@ -0,0 +1,9 @@
+(define-package "ghub" "20180715.1159" "minuscule client library for the Github API"
+  '((emacs "24.4")
+    (let-alist "1.0.5"))
+  :keywords
+  '("tools")
+  :url "https://github.com/magit/ghub")
+;; Local Variables:
+;; no-byte-compile: t
+;; End:
diff --git a/configs/shared/emacs/.emacs.d/elpa/ghub-20180715.1159/ghub.el b/configs/shared/emacs/.emacs.d/elpa/ghub-20180715.1159/ghub.el
new file mode 100644
index 0000000000..08ee86cabc
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/ghub-20180715.1159/ghub.el
@@ -0,0 +1,849 @@
+;;; ghub.el --- minuscule client library for the Github API  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2016-2018  Jonas Bernoulli
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Homepage: https://github.com/magit/ghub
+;; Keywords: tools
+;; Package-Requires: ((emacs "24.4") (let-alist "1.0.5"))
+
+;; This file is not part of GNU Emacs.
+
+;; This file 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, or (at your option)
+;; any later version.
+
+;; This file 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.
+
+;; For a copy of the GPL see https://www.gnu.org/licenses/gpl.txt.
+
+;;; Commentary:
+
+;; Ghub is a library that provides basic support for using the Github API
+;; from Emacs packages.  It abstracts access to API resources using only
+;; a handful of functions that are not resource-specific.
+
+;; Ghub handles the creation, storage and use of access tokens using a
+;; setup wizard to make it easier for users to get started and to reduce
+;; the support burden imposed on package maintainers.  It also comes with
+;; a comprehensive manual to address the cases when things don't just
+;; work as expected or in case you don't want to use the wizard.
+
+;; Ghub is intentionally limited to only provide these two essential
+;; features — basic request functions and guided setup — to avoid being
+;; too opinionated, which would hinder wide adoption.  It is assumed that
+;; wide adoption would make life easier for users and maintainers alike,
+;; because then all packages that talk to the Github API could be
+;; configured the same way.
+
+;;; Code:
+
+(require 'auth-source)
+(require 'cl-lib)
+(require 'json)
+(require 'let-alist)
+(require 'url)
+(require 'url-auth)
+(require 'url-http)
+
+(eval-when-compile (require 'subr-x))
+
+(defvar url-callback-arguments)
+(defvar url-http-end-of-headers)
+(defvar url-http-extra-headers)
+(defvar url-http-response-status)
+
+;;; Settings
+
+(defconst ghub-default-host "api.github.com")
+
+(defvar ghub-github-token-scopes '(repo)
+  "The Github API scopes that your private tools need.
+
+The token that is created based on the value of this variable
+is used when `ghub-request' (or one of its wrappers) is called
+without providing a value for AUTH.  Packages should always
+identify themselves using that argument, but when you use Ghub
+directly in private tools, then that is not necessary and the
+request is made on behalf of the `ghub' package itself, aka on
+behalf of some private tool.
+
+By default the only requested scope is `repo' because that is
+sufficient as well as required for most common uses.  This and
+other scopes are documented at URL `https://magit.vc/goto/2e586d36'.
+
+If your private tools need other scopes, then you have to add
+them here *before* creating the token.  Alternatively you can
+edit the scopes of an existing token using the web interface
+at URL `https://github.com/settings/tokens'.")
+
+(defvar ghub-override-system-name nil
+  "If non-nil, the string used to identify the local machine.
+If this is nil, then the value returned by `system-name' is
+used instead.")
+
+;;; Request
+;;;; Object
+
+(cl-defstruct (ghub--req
+               (:constructor ghub--make-req)
+               (:copier nil))
+  (url        nil :read-only nil)
+  (silent     nil :read-only t)
+  (method     nil :read-only t)
+  (headers    nil :read-only t)
+  (unpaginate nil :read-only nil)
+  (noerror    nil :read-only t)
+  (reader     nil :read-only t)
+  (callback   nil :read-only t)
+  (errorback  nil :read-only t)
+  (value      nil :read-only nil)
+  (extra      nil :read-only nil))
+
+(defalias 'ghub-req-extra 'ghub--req-extra)
+
+;;;; API
+
+(define-error 'ghub-error "Ghub/Url Error" 'error)
+(define-error 'ghub-http-error "HTTP Error" 'ghub-error)
+
+(defvar ghub-response-headers nil
+  "The headers returned in response to the last request.
+`ghub-request' returns the response body and stores the
+response headers in this variable.")
+
+(cl-defun ghub-graphql (graphql &optional variables
+                                &key username auth host
+                                silent
+                                callback errorback extra)
+  "Make a GraphQL request using GRAPHQL and VARIABLES.
+Return the response as a JSON-like alist.  Even if the response
+contains `errors', do not raise an error.  GRAPHQL is a GraphQL
+string.  VARIABLES is a JSON-like alist.  The other arguments
+behave as for `ghub-request' (which see)."
+  (cl-assert (stringp graphql))
+  (cl-assert (not (stringp variables)))
+  (ghub-request "POST" "/graphql" nil :payload
+                (json-encode `(("query" . ,graphql)
+                               ,@(and variables `(("variables" ,@variables)))))
+                :silent silent
+                :username username :auth auth :host host
+                :callback callback :errorback errorback :extra extra))
+
+(cl-defun ghub-head (resource &optional params
+                              &key query payload headers
+                              silent unpaginate noerror reader
+                              username auth host
+                              callback errorback extra)
+  "Make a `HEAD' request for RESOURCE, with optional query PARAMS.
+Like calling `ghub-request' (which see) with \"HEAD\" as METHOD."
+  (ghub-request "HEAD" resource params
+                :query query :payload payload :headers headers
+                :silent silent :unpaginate unpaginate
+                :noerror noerror :reader reader
+                :username username :auth auth :host host
+                :callback callback :errorback errorback :extra extra))
+
+(cl-defun ghub-get (resource &optional params
+                             &key query payload headers
+                             silent unpaginate noerror reader
+                             username auth host
+                             callback errorback extra)
+  "Make a `GET' request for RESOURCE, with optional query PARAMS.
+Like calling `ghub-request' (which see) with \"GET\" as METHOD."
+  (ghub-request "GET" resource params
+                :query query :payload payload :headers headers
+                :silent silent :unpaginate unpaginate
+                :noerror noerror :reader reader
+                :username username :auth auth :host host
+                :callback callback :errorback errorback :extra extra))
+
+(cl-defun ghub-put (resource &optional params
+                             &key query payload headers
+                             silent unpaginate noerror reader
+                             username auth host
+                             callback errorback extra)
+  "Make a `PUT' request for RESOURCE, with optional payload PARAMS.
+Like calling `ghub-request' (which see) with \"PUT\" as METHOD."
+  (ghub-request "PUT" resource params
+                :query query :payload payload :headers headers
+                :silent silent :unpaginate unpaginate
+                :noerror noerror :reader reader
+                :username username :auth auth :host host
+                :callback callback :errorback errorback :extra extra))
+
+(cl-defun ghub-post (resource &optional params
+                              &key query payload headers
+                              silent unpaginate noerror reader
+                              username auth host
+                              callback errorback extra)
+  "Make a `POST' request for RESOURCE, with optional payload PARAMS.
+Like calling `ghub-request' (which see) with \"POST\" as METHOD."
+  (ghub-request "POST" resource params
+                :query query :payload payload :headers headers
+                :silent silent :unpaginate unpaginate
+                :noerror noerror :reader reader
+                :username username :auth auth :host host
+                :callback callback :errorback errorback :extra extra))
+
+(cl-defun ghub-patch (resource &optional params
+                               &key query payload headers
+                               silent unpaginate noerror reader
+                               username auth host
+                               callback errorback extra)
+  "Make a `PATCH' request for RESOURCE, with optional payload PARAMS.
+Like calling `ghub-request' (which see) with \"PATCH\" as METHOD."
+  (ghub-request "PATCH" resource params
+                :query query :payload payload :headers headers
+                :silent silent :unpaginate unpaginate
+                :noerror noerror :reader reader
+                :username username :auth auth :host host
+                :callback callback :errorback errorback :extra extra))
+
+(cl-defun ghub-delete (resource &optional params
+                                &key query payload headers
+                                silent unpaginate noerror reader
+                                username auth host
+                                callback errorback extra)
+  "Make a `DELETE' request for RESOURCE, with optional payload PARAMS.
+Like calling `ghub-request' (which see) with \"DELETE\" as METHOD."
+  (ghub-request "DELETE" resource params
+                :query query :payload payload :headers headers
+                :silent silent :unpaginate unpaginate
+                :noerror noerror :reader reader
+                :username username :auth auth :host host
+                :callback callback :errorback errorback :extra extra))
+
+(cl-defun ghub-request (method resource &optional params
+                               &key query payload headers
+                               silent unpaginate noerror reader
+                               username auth host forge
+                               callback errorback extra)
+  "Make a request for RESOURCE and return the response body.
+
+Also place the response header in `ghub-response-headers'.
+
+METHOD is the HTTP method, given as a string.
+RESOURCE is the resource to access, given as a string beginning
+  with a slash.
+
+PARAMS, QUERY, PAYLOAD and HEADERS are alists used to specify
+  data.  The Github API documentation is vague on how data has
+  to be transmitted and for a particular resource usually just
+  talks about \"parameters\".  Generally speaking when the METHOD
+  is \"HEAD\" or \"GET\", then they have to be transmitted as a
+  query, otherwise as a payload.
+Use PARAMS to automatically transmit like QUERY or PAYLOAD would
+  depending on METHOD.
+Use QUERY to explicitly transmit data as a query.
+Use PAYLOAD to explicitly transmit data as a payload.
+  Instead of an alist, PAYLOAD may also be a string, in which
+  case it gets encoded as UTF-8 but is otherwise transmitted as-is.
+Use HEADERS for those rare resources that require that the data
+  is transmitted as headers instead of as a query or payload.
+  When that is the case, then the API documentation usually
+  mentions it explicitly.
+
+If SILENT is non-nil, then don't message progress reports and
+  the like.
+
+If UNPAGINATE is t, then make as many requests as necessary to
+  get all values.  If UNPAGINATE is a natural number, then get
+  at most that many pages.  For any other non-nil value raise
+  an error.
+If NOERROR is non-nil, then do not raise an error if the request
+  fails and return nil instead.  If NOERROR is `return', then
+  return the error payload instead of nil.
+If READER is non-nil, then it is used to read and return from the
+  response buffer.  The default is `ghub--read-json-payload'.
+  For the very few resources that do not return JSON, you might
+  want to use `ghub--decode-payload'.
+
+If USERNAME is non-nil, then make a request on behalf of that
+  user.  It is better to specify the user using the Git variable
+  `github.user' for \"api.github.com\", or `github.HOST.user' if
+  connecting to a Github Enterprise instance.
+
+Each package that uses `ghub' should use its own token. If AUTH
+  is nil, then the generic `ghub' token is used instead.  This
+  is only acceptable for personal utilities.  A packages that
+  is distributed to other users should always use this argument
+  to identify itself, using a symbol matching its name.
+
+  Package authors who find this inconvenient should write a
+  wrapper around this function and possibly for the
+  method-specific functions as well.
+
+  Some symbols have a special meaning.  `none' means to make an
+  unauthorized request.  `basic' means to make a password based
+  request.  If the value is a string, then it is assumed to be
+  a valid token.  `basic' and an explicit token string are only
+  intended for internal and debugging uses.
+
+  If AUTH is a package symbol, then the scopes are specified
+  using the variable `AUTH-github-token-scopes'.  It is an error
+  if that is not specified.  See `ghub-github-token-scopes' for
+  an example.
+
+If HOST is non-nil, then connect to that Github instance.  This
+  defaults to \"api.github.com\".  When a repository is connected
+  to a Github Enterprise instance, then it is better to specify
+  that using the Git variable `github.host' instead of using this
+  argument.
+
+If FORGE is `gitlab', then connect to Gitlab.com or, depending
+  on HOST, to another Gitlab instance.  This is only intended for
+  internal use.  Instead of using this argument you should use
+  function `glab-request' and other `glab-*' functions.
+
+If CALLBACK and/or ERRORBACK is non-nil, then make one or more
+  asynchronous requests and call CALLBACK or ERRORBACK when
+  finished.  If an error occurred, then call ERRORBACK, or if
+  that is nil, then CALLBACK.  When no error occurred then call
+  CALLBACK.  When making asynchronous requests, then no errors
+  are signaled, regardless of the value of NOERROR.
+
+Both callbacks are called with four arguments.
+  1. For CALLBACK, the combined value of the retrieved pages.
+     For ERRORBACK, the error that occured when retrieving the
+     last page.
+  2. The headers of the last page as an alist.
+  3. Status information provided by `url-retrieve'. Its `:error'
+     property holds the same information as ERRORBACK's first
+     argument.
+  4. A `ghub--req' struct, which can be passed to `ghub-continue'
+     (which see) to retrieve the next page, if any."
+  (cl-assert (or (booleanp unpaginate) (natnump unpaginate)))
+  (unless (string-prefix-p "/" resource)
+    (setq resource (concat "/" resource)))
+  (unless host
+    (setq host (ghub--host forge)))
+  (unless (or username (stringp auth) (eq auth 'none))
+    (setq username (ghub--username host forge)))
+  (cond ((not params))
+        ((member method '("GET" "HEAD"))
+         (when query
+           (error "PARAMS and QUERY are mutually exclusive for METHOD %S"
+                  method))
+         (setq query params))
+        (t
+         (when payload
+           (error "PARAMS and PAYLOAD are mutually exclusive for METHOD %S"
+                  method))
+         (setq payload params)))
+  (when payload
+    (unless (stringp payload)
+      (setq payload (json-encode-list payload)))
+    (setq payload (encode-coding-string payload 'utf-8)))
+  (when (or callback errorback)
+    (setq noerror t))
+  (ghub--retrieve
+   payload
+   (ghub--make-req
+    :url (url-generic-parse-url
+          (concat "https://" host resource
+                  (and query (concat "?" (ghub--url-encode-params query)))))
+    :silent silent
+    ;; Encode in case caller used (symbol-name 'GET). #35
+    :method     (encode-coding-string method 'utf-8)
+    :headers    (ghub--headers headers host auth username forge)
+    :unpaginate unpaginate
+    :noerror    noerror
+    :reader     reader
+    :callback   callback
+    :errorback  errorback
+    :extra      extra)))
+
+(defun ghub-continue (req)
+  "If there is a next page, then retrieve that.
+
+This function is only intended to be called from callbacks.  If
+there is a next page, then retrieve that and return the buffer
+that the result will be loaded into, or t if the process has
+already completed.  If there is no next page, then return nil.
+
+Callbacks are called with four arguments (see `ghub-request').
+The forth argument is a `ghub--req' struct, intended to be passed
+to this function.  A callbacks may use the struct's `extra' slot
+to pass additional information to the callback that will be
+called after the next request has finished.  Use the function
+`ghub-req-extra' to get and set the value of this slot."
+  (and (assq 'next (ghub-response-link-relations))
+       (or (ghub--retrieve nil req) t)))
+
+(cl-defun ghub-wait (resource &optional duration &key username auth host)
+  "Busy-wait up to DURATION seconds for RESOURCE to become available.
+
+DURATION specifies how many seconds to wait at most.  It defaults
+to 64 seconds.  The first attempt is made immediately, the second
+after two seconds, and each subsequent attempt is made after
+waiting as long again as we already waited between all preceding
+attempts combined.
+
+See `ghub-request' for information about the other arguments."
+  (unless duration
+    (setq duration 64))
+  (with-local-quit
+    (let ((total 0))
+      (while (not (ghub-get resource nil
+                            :noerror t
+                            :username username
+                            :auth auth
+                            :host host))
+        (message "Waited (%3ss of %ss) for %s..." total duration resource)
+        (if (= total duration)
+            (error "Github is taking too long to create %s" resource)
+          (if (> total 0)
+              (let ((wait (min total (- duration total))))
+                (sit-for wait)
+                (cl-incf total wait))
+            (sit-for (setq total 2))))))))
+
+(defun ghub-response-link-relations (&optional headers)
+  "Return an alist of link relations in HEADERS.
+If optional HEADERS is nil, then return those
+in `ghub-response-headers'."
+  (let ((rels (cdr (assoc "Link" (or headers ghub-response-headers)))))
+    (and rels (mapcar (lambda (elt)
+                        (pcase-let ((`(,url ,rel) (split-string elt "; ")))
+                          (cons (intern (substring rel 5 -1))
+                                (substring url 1 -1))))
+                      (split-string rels ", ")))))
+
+;;;; Internal
+
+(cl-defun ghub--retrieve (payload req)
+  (let ((url-request-extra-headers
+         (let ((headers (ghub--req-headers req)))
+           (if (functionp headers) (funcall headers) headers)))
+        (url-request-method (ghub--req-method req))
+        (url-request-data payload)
+        (url-show-status nil)
+        (url (ghub--req-url req))
+        (silent (ghub--req-silent req)))
+    (if (or (ghub--req-callback  req)
+            (ghub--req-errorback req))
+        (url-retrieve url 'ghub--handle-response (list req) silent)
+      ;; When this function has already been called, then it is a
+      ;; no-op.  Otherwise it sets `url-registered-auth-schemes' among
+      ;; other things.  If we didn't ensure that it has been run, then
+      ;; `url-retrieve-synchronously' would do it, which would cause
+      ;; the value that we let-bind below to be overwritten, and the
+      ;; "default" value to be lost outside the let-binding.
+      (url-do-setup)
+      (with-current-buffer
+          (let ((url-registered-auth-schemes
+                 '(("basic" ghub--basic-auth-errorback . 10))))
+            (url-retrieve-synchronously url silent))
+        (ghub--handle-response (car url-callback-arguments) req)))))
+
+(defun ghub--handle-response (status req)
+  (let ((buffer (current-buffer)))
+    (unwind-protect
+        (progn
+          (set-buffer-multibyte t)
+          (let* ((unpaginate (ghub--req-unpaginate req))
+                 (headers    (ghub--handle-response-headers status req))
+                 (payload    (ghub--handle-response-payload req))
+                 (payload    (ghub--handle-response-error status payload req))
+                 (value      (nconc (ghub--req-value req) payload))
+                 (next       (cdr (assq 'next (ghub-response-link-relations
+                                               headers)))))
+            (when (numberp unpaginate)
+              (cl-decf unpaginate))
+            (setf (ghub--req-url req)
+                  (url-generic-parse-url next))
+            (setf (ghub--req-value req) value)
+            (setf (ghub--req-unpaginate req) unpaginate)
+            (or (and next
+                     unpaginate
+                     (or (eq unpaginate t)
+                         (>  unpaginate 0))
+                     (ghub-continue req))
+                (let ((callback  (ghub--req-callback req))
+                      (errorback (ghub--req-errorback req))
+                      (err       (plist-get status :error)))
+                  (cond ((and err errorback)
+                         (funcall errorback err headers status req))
+                        (callback
+                         (funcall callback value headers status req))
+                        (t value))))))
+      (when (buffer-live-p buffer)
+        (kill-buffer buffer)))))
+
+(defun ghub--handle-response-headers (status req)
+  (goto-char (point-min))
+  (forward-line 1)
+  (let (headers)
+    (while (re-search-forward "^\\([^:]*\\): \\(.+\\)"
+                              url-http-end-of-headers t)
+      (push (cons (match-string 1)
+                  (match-string 2))
+            headers))
+    (setq headers (nreverse headers))
+    (unless url-http-end-of-headers
+      (error "BUG: missing headers %s" (plist-get status :error)))
+    (goto-char (1+ url-http-end-of-headers))
+    (if (and req (or (ghub--req-callback req)
+                     (ghub--req-errorback req)))
+        (setq-local ghub-response-headers headers)
+      (setq-default ghub-response-headers headers))
+    headers))
+
+(defun ghub--handle-response-error (status payload req)
+  (let ((noerror (ghub--req-noerror req))
+        (err (plist-get status :error)))
+    (if err
+        (if noerror
+            (if (eq noerror 'return)
+                payload
+              (setcdr (last err) (list payload))
+              nil)
+          (pcase-let ((`(,symb . ,data) err))
+            (if (eq symb 'error)
+                (if (eq (car-safe data) 'http)
+                    (signal 'ghub-http-error
+                            (let ((code (car (cdr-safe data))))
+                              (list code
+                                    (nth 2 (assq code url-http-codes))
+                                    payload)))
+                  (signal 'ghub-error data))
+              (signal symb data))))
+      payload)))
+
+(defun ghub--handle-response-payload (req)
+  (funcall (or (ghub--req-reader req)
+               'ghub--read-json-payload)
+           url-http-response-status))
+
+(defun ghub--read-json-payload (_status)
+  (let ((raw (ghub--decode-payload)))
+    (and raw
+         (condition-case nil
+             (let ((json-object-type 'alist)
+                   (json-array-type  'list)
+                   (json-key-type    'symbol)
+                   (json-false       nil)
+                   (json-null        nil))
+               (json-read-from-string raw))
+           (json-readtable-error
+            `((message
+               . ,(if (looking-at "<!DOCTYPE html>")
+                      (if (re-search-forward
+                           "<p>\\(?:<strong>\\)?\\([^<]+\\)" nil t)
+                          (match-string 1)
+                        "error description missing")
+                    (string-trim (buffer-substring (point) (point-max)))))
+              (documentation_url
+               . "https://github.com/magit/ghub/wiki/Github-Errors")))))))
+
+(defun ghub--decode-payload (&optional _status)
+  (and (not (eobp))
+       (decode-coding-string
+        (buffer-substring-no-properties (point) (point-max))
+        'utf-8)))
+
+(defun ghub--url-encode-params (params)
+  (mapconcat (lambda (param)
+               (pcase-let ((`(,key . ,val) param))
+                 (concat (url-hexify-string (symbol-name key)) "="
+                         (if (integerp val)
+                             (number-to-string val)
+                           (url-hexify-string val)))))
+             params "&"))
+
+;;; Authentication
+;;;; API
+
+;;;###autoload
+(defun ghub-create-token (host username package scopes)
+  "Create, store and return a new token.
+
+HOST is the Github instance, usually \"api.github.com\".
+USERNAME is the name of a user on that instance.
+PACKAGE is the package that will use the token.
+SCOPES are the scopes the token is given access to."
+  (interactive
+   (pcase-let ((`(,host ,username ,package)
+                (ghub--read-triplet)))
+     (list host username package
+           (split-string
+            (read-string
+             "Scopes (separated by commas): "
+             (mapconcat #'symbol-name
+                        (symbol-value
+                         (intern (format "%s-github-token-scopes" package)))
+                        ","))
+            "," t "[\s\t]+"))))
+  (let ((user (ghub--ident username package)))
+    (cl-destructuring-bind (save token)
+        (ghub--auth-source-get (list :save-function :secret)
+          :create t :host host :user user
+          :secret
+          (cdr (assq 'token
+                     (ghub-post
+                      "/authorizations"
+                      `((scopes . ,scopes)
+                        (note   . ,(ghub--ident-github package)))
+                      :username username :auth 'basic :host host))))
+      ;; Build-in back-ends return a function that does the actual
+      ;; saving, while for some third-party back-ends ":create t"
+      ;; is enough.
+      (when (functionp save)
+        (funcall save))
+      ;; If the Auth-Source cache contains the information that there
+      ;; is no value, then setting the value does not invalidate that
+      ;; now incorrect information.
+      (auth-source-forget (list :host host :user user))
+      token)))
+
+;;;###autoload
+(defun ghub-token-scopes (host username package)
+  "Return and echo the scopes of the specified token.
+This is intended for debugging purposes only.  The user
+has to provide several values including their password."
+  (interactive (ghub--read-triplet))
+  (let ((scopes
+         (cdr (assq 'scopes (ghub--get-token-plist host username package)))))
+    (when (called-interactively-p 'any)
+      ;; Also show the input values to make it easy for package
+      ;; authors to verify that the user has done it correctly.
+      (message "Scopes for %s@%s: %S"
+               (ghub--ident username package)
+               host scopes))
+    scopes))
+
+;;;; Internal
+
+(defun ghub--headers (headers host auth username forge)
+  (push (cons "Content-Type" "application/json") headers)
+  (if (eq auth 'none)
+      headers
+    (unless (or username (stringp auth))
+      (setq username (ghub--username host forge)))
+    (lambda ()
+      (if (eq auth 'basic)
+          (if (eq forge 'gitlab)
+              (error "Gitlab does not support basic authentication")
+            (cons (cons "Authorization" (ghub--basic-auth host username))
+                  headers))
+        (cons (ghub--auth host auth username forge) headers)))))
+
+(defun ghub--auth (host auth &optional username forge)
+  (unless username
+    (setq username (ghub--username host)))
+  (if (eq auth 'basic)
+      (if (eq forge 'gitlab)
+          (error "Gitlab does not support basic authentication")
+        (cons "Authorization" (ghub--basic-auth host username)))
+    (cons (if (eq forge 'gitlab)
+              "Private-Token"
+            "Authorization")
+          (concat
+           (and (not (eq forge 'gitlab)) "token ")
+           (encode-coding-string
+            (cl-typecase auth
+              (string auth)
+              (null   (ghub--token host username 'ghub nil forge))
+              (symbol (ghub--token host username auth  nil forge))
+              (t (signal 'wrong-type-argument
+                         `((or stringp symbolp) ,auth))))
+            'utf-8)))))
+
+(defun ghub--basic-auth (host username)
+  (let ((url (url-generic-parse-url (concat "https://" host))))
+    (setf (url-user url) username)
+    (url-basic-auth url t)))
+
+(defun ghub--basic-auth-errorback (url &optional prompt _overwrite _realm _args)
+  ;; This gets called twice.  Do nothing the first time,
+  ;; when PROMPT is nil.  See `url-get-authentication'.
+  (when prompt
+    (if (assoc "X-GitHub-OTP" (ghub--handle-response-headers nil nil))
+        (progn
+          (setq url-http-extra-headers
+                `(("Content-Type" . "application/json")
+                  ("X-GitHub-OTP" . ,(ghub--read-2fa-code))
+                  ;; Without "Content-Type" and "Authorization".
+                  ;; The latter gets re-added from the return value.
+                  ,@(cddr url-http-extra-headers)))
+          ;; Return the cached values, they are correct.
+          (url-basic-auth url nil nil nil))
+      ;; Remove the invalid cached values and fail, which
+      ;; is better than the invalid values sticking around.
+      (setq url-http-real-basic-auth-storage
+            (cl-delete (format "%s:%d" (url-host url) (url-port url))
+                       url-http-real-basic-auth-storage
+                       :test #'equal :key #'car))
+      nil)))
+
+(defun ghub--token (host username package &optional nocreate forge)
+  (let* ((user (ghub--ident username package))
+         (token
+          (or (car (ghub--auth-source-get (list :secret)
+                     :host host :user user))
+              (progn
+                ;; Auth-Source caches the information that there is no
+                ;; value, but in our case that is a situation that needs
+                ;; fixing so we want to keep trying by invalidating that
+                ;; information.  The (:max 1) is needed for Emacs releases
+                ;; before 26.1.
+                (auth-source-forget (list :max 1 :host host :user user))
+                (and (not nocreate)
+                     (if (eq forge 'gitlab)
+                         (error
+                          (concat
+                           "Required Gitlab token does not exist.  See "
+                           "https://magit.vc/manual/ghub/Gitlab-Support.html "
+                           "for instructions."))
+                       (ghub--confirm-create-token host username package)))))))
+    (if (functionp token) (funcall token) token)))
+
+(defun ghub--host (&optional forge)
+  (if (eq forge 'gitlab)
+      (or (ignore-errors (car (process-lines "git" "config" "gitlab.host")))
+          (bound-and-true-p glab-default-host))
+    (or (ignore-errors (car (process-lines "git" "config" "github.host")))
+        ghub-default-host)))
+
+(defun ghub--username (host &optional forge)
+  (let ((var (cond ((string-prefix-p "api.github.com" host) "github.user")
+                   ((string-prefix-p "gitlab.com/api" host) "gitlab.user")
+                   ((eq forge 'gitlab)     (format "gitlab.%s.user" host))
+                   (t                      (format "github.%s.user" host)))))
+    (condition-case nil
+        (car (process-lines "git" "config" var))
+      (error
+       (let ((user (read-string
+                    (format "Git variable `%s' is unset.  Set to: " var))))
+         (or (and user (progn (call-process "git" nil nil nil
+                                            "config" "--global" var user)
+                              user))
+             (user-error "Abort")))))))
+
+(defun ghub--ident (username package)
+  (format "%s^%s" username package))
+
+(defun ghub--ident-github (package)
+  (format "Emacs package %s @ %s"
+          package
+          (or ghub-override-system-name (system-name))))
+
+(defun ghub--package-scopes (package)
+  (let ((var (intern (format "%s-github-token-scopes" package))))
+    (if (boundp var)
+        (symbol-value var)
+      (error "%s fails to define %s" package var))))
+
+(defun ghub--confirm-create-token (host username package)
+  (let* ((ident (ghub--ident-github package))
+         (scopes (ghub--package-scopes package))
+         (max-mini-window-height 40))
+    (if (let ((message-log-max nil))
+          (yes-or-no-p
+           (format
+            "Such a Github API token is not available:
+
+  Host:    %s
+  User:    %s
+  Package: %s
+
+  Scopes requested in `%s-github-token-scopes':\n%s
+  Store on Github as:\n    %S
+  Store locally according to option `auth-sources':\n    %S
+%s
+If in doubt, then abort and first view the section of the Ghub
+documentation called \"Manually Creating and Storing a Token\".
+
+Otherwise confirm and then provide your Github username and
+password at the next two prompts.  Depending on the backend
+you might have to provide a passphrase and confirm that you
+really want to save the token.
+
+Create and store such a token? "
+            host username package package
+            (mapconcat (lambda (scope) (format "    %s" scope)) scopes "\n")
+            ident auth-sources
+            (if (and (stringp (car auth-sources))
+                     (not (string-suffix-p ".gpg" (car auth-sources))))
+                (format "
+WARNING: The token will be stored unencrypted in %S.
+         If you don't want that, you have to abort and customize
+         the `auth-sources' option.\n" (car auth-sources))
+              ""))))
+        (progn
+          (when (ghub--get-token-id host username package)
+            (if (yes-or-no-p
+                 (format
+                  "A token named %S\nalready exists on Github.  Replace it?"
+                  ident))
+                (ghub--delete-token host username package)
+              (user-error "Abort")))
+          (ghub-create-token host username package scopes))
+      (user-error "Abort"))))
+
+(defun ghub--get-token-id (host username package)
+  (let ((ident (ghub--ident-github package)))
+    (cl-some (lambda (x)
+               (let-alist x
+                 (and (equal .app.name ident) .id)))
+             (ghub-get "/authorizations"
+                       '((per_page . 100))
+                       :unpaginate t
+                       :username username :auth 'basic :host host))))
+
+(defun ghub--get-token-plist (host username package)
+  (ghub-get (format "/authorizations/%s"
+                    (ghub--get-token-id host username package))
+            nil :username username :auth 'basic :host host))
+
+(defun ghub--delete-token (host username package)
+  (ghub-delete (format "/authorizations/%s"
+                       (ghub--get-token-id host username package))
+               nil :username username :auth 'basic :host host))
+
+(defun ghub--read-triplet ()
+  (let ((host (read-string "Host: " (ghub--host))))
+    (list host
+          (read-string "Username: " (ghub--username host))
+          (intern (read-string "Package: " "ghub")))))
+
+(defvar ghub--2fa-cache nil)
+
+(defun ghub--read-2fa-code ()
+  (let ((code (read-number "Two-factor authentication code: "
+                           (and ghub--2fa-cache
+                                (< (float-time (time-subtract
+                                                (current-time)
+                                                (cdr ghub--2fa-cache)))
+                                   25)
+                                (car ghub--2fa-cache)))))
+    (setq ghub--2fa-cache (cons code (current-time)))
+    (number-to-string code)))
+
+(defun ghub--auth-source-get (keys &rest spec)
+  (declare (indent 1))
+  (let ((plist (car (apply #'auth-source-search :max 1 spec))))
+    (mapcar (lambda (k)
+              (plist-get plist k))
+            keys)))
+
+(advice-add 'auth-source-netrc-parse-next-interesting :around
+            'auth-source-netrc-parse-next-interesting@save-match-data)
+(defun auth-source-netrc-parse-next-interesting@save-match-data (fn)
+  "Save match-data for the benefit of caller `auth-source-netrc-parse-one'.
+Without wrapping this function in `save-match-data' the caller
+won't see the secret from a line that is followed by a commented
+line."
+  (save-match-data (funcall fn)))
+
+;;; _
+(provide 'ghub)
+;; Local Variables:
+;; indent-tabs-mode: nil
+;; End:
+;;; ghub.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/ghub-20180715.1159/ghub.elc b/configs/shared/emacs/.emacs.d/elpa/ghub-20180715.1159/ghub.elc
new file mode 100644
index 0000000000..9ffed41691
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/ghub-20180715.1159/ghub.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/ghub-20180715.1159/ghub.info b/configs/shared/emacs/.emacs.d/elpa/ghub-20180715.1159/ghub.info
new file mode 100644
index 0000000000..311e5e3311
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/ghub-20180715.1159/ghub.info
@@ -0,0 +1,1002 @@
+This is ghub.info, produced by makeinfo version 6.1 from ghub.texi.
+
+     Copyright (C) 2017-2018 Jonas Bernoulli <jonas@bernoul.li>
+
+     You can redistribute this document 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.
+
+     This document 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.
+INFO-DIR-SECTION Emacs
+START-INFO-DIR-ENTRY
+* Ghub: (ghub).         Minuscule client library for the Github API.
+END-INFO-DIR-ENTRY
+
+
+File: ghub.info,  Node: Top,  Next: Introduction,  Up: (dir)
+
+Ghub User and Developer Manual
+******************************
+
+Ghub is a library that provides basic support for using the Github API
+from Emacs packages.  It abstracts access to API resources using only a
+handful of functions that are not resource-specific.
+
+   Ghub handles the creation, storage and use of access tokens using a
+setup wizard to make it easier for users to get started and to reduce
+the support burden imposed on package maintainers.  It also comes with a
+comprehensive manual to address the cases when things don’t just work as
+expected or in case you don’t want to use the wizard.
+
+   Ghub is intentionally limited to only provide these two essential
+features — basic request functions and guided setup — to avoid being too
+opinionated, which would hinder wide adoption.  It is assumed that wide
+adoption would make life easier for users and maintainers alike, because
+then all packages that talk to the Github API could be configured the
+same way.
+
+This manual is for Ghub version 2.0.1 (v2.0.1-10-g85b5ae3+1).
+
+     Copyright (C) 2017-2018 Jonas Bernoulli <jonas@bernoul.li>
+
+     You can redistribute this document 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.
+
+     This document 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.
+
+* Menu:
+
+* Introduction::
+* Getting Started::
+* Using Ghub in Personal Scripts::
+* Using Ghub in a Package::
+* API::
+* Gitlab Support::
+
+— The Detailed Node Listing —
+
+Getting Started
+
+* Setting the Username::
+* Interactively Creating and Storing a Token::
+* Manually Creating and Storing a Token::
+* How Ghub uses Auth-Source::
+
+API
+
+* Making Requests::
+* Authentication::
+* Configuration Variables::
+
+
+
+File: ghub.info,  Node: Introduction,  Next: Getting Started,  Prev: Top,  Up: Top
+
+1 Introduction
+**************
+
+Ghub is a library that provides basic support for using the Github API
+from Emacs packages.  It abstracts access to API resources using only a
+handful of functions that are not resource-specific.
+
+   Ghub handles the creation, storage and use of access tokens using a
+setup wizard to make it easier for users to get started and to reduce
+the support burden imposed on package maintainers.  It also comes with a
+comprehensive manual to address the cases when things don’t just work as
+expected or in case you don’t want to use the wizard.
+
+   Ghub is intentionally limited to only provide these two essential
+features — basic request functions and guided setup — to avoid being too
+opinionated, which would hinder wide adoption.  It is assumed that wide
+adoption would make life easier for users and maintainers alike, because
+then all packages that talk to the Github API could be configured the
+same way.
+
+   Fancier interfaces can be implemented on top of Ghub, and one such
+wrapper — named simply Ghub+ — has already been implemented.  The
+benefit of basing various opinionated interfaces on top of a single
+library that provides only the core functionality is that choosing the
+programming interface no longer dictates how access tokens are handled.
+Users can then use multiple packages that access the Github API without
+having to learn the various incompatible ways packages expect the
+appropriate token to be made available to them.
+
+   Ghub uses the built-in ‘auth-source’ library to store access tokens.
+That library is very flexible and supports multiple backends, which
+means that it is up to the user how secrets are stored.  They can, among
+other things, choose between storing secrets in plain text for ease of
+use, or encrypted for better security.
+
+   Previously (as in until this library is widely adopted) it was up to
+package authors to decide if things should be easy or secure.  (Note
+that ‘auth-source’ defaults to "easy" — you have been warned.)
+
+   Ghub expects package authors to use a dedicated access token instead
+of sharing a single token between all packages that rely on it.  That
+means that users cannot configure Ghub once and later start using a new
+package without any additional setup.  But Ghub helps with that.
+
+   When the user invokes some command that ultimately results in
+‘ghub-request’ being called and the appropriate token is not available
+yet, then the user is guided through the process of creating and storing
+a new token, and at the end of that process the request is carried out
+as if the token had been available to begin with.
+
+
+File: ghub.info,  Node: Getting Started,  Next: Using Ghub in Personal Scripts,  Prev: Introduction,  Up: Top
+
+2 Getting Started
+*****************
+
+Each package that uses Ghub uses its own token.  Despite that, chances
+are good that after successfully configuring one package you can just
+start using another package pretty much instantly.
+
+   If the necessary token is not available when a package makes an API
+request, then a setup wizard pops up, and after answering a few
+questions you are good to go.  Even the request that caused the wizard
+to be summoned should succeed and for most users this should be true
+even when configuring the very first token.
+
+   However, in some situations some manual configuration is necessary
+*before* using the wizard, or the wizard cannot be used at all:
+
+   • If you don’t want to use the wizard then you don’t have to and can
+     create tokens manually as described in *note Manually Creating and
+     Storing a Token::.
+
+   • If you want to access Gitlab.com or another Gitlab instance, then
+     you have to create the token manually as describe in *note Manually
+     Creating and Storing a Token::.  Also see *note Gitlab Support::.
+
+   • If you want to access a Github Enterprise instance, then you have
+     to tell Ghub about that before the wizard makes its appearance by
+     setting the Git variable ‘github.host’.  You also have to tell Ghub
+     your username for that instance using the variable
+     ‘github.HOST.user’ even if it is the same as on Github.com.
+
+   • If the variable ‘github.user’ (or ‘github.HOST.user’ for an
+     Enterprise instance) is unset when the wizard is first summoned,
+     then you are asked to provide your username.  That value is then
+     stored *globally* to avoid having to ask you that question once per
+     repository.  If you have multiple accounts on Github.com (or an
+     Enterprise instance), then you have to explicitly tell Ghub about
+     that.  This can be done by setting the repository-local values of
+     the appropriate variable *before* the wizard is invoked.
+
+   • You might forget to do the above, which is why it is important to
+     carefully read the output of the wizard.  If it turns out that you
+     forgot to set a variable, then you must abort, set the variable,
+     and repeat the request to trigger the wizard again.
+
+   • The setup wizard should work even if you have enabled two-factor
+     authentication.  However if your Github Enterprise instance
+     enforces Single Sign-On as an additional security measure, then you
+     are out of luck and have to create the token manually as described
+     in *note Manually Creating and Storing a Token::.
+
+   The variables mentioned above — and others — are documented in *note
+Configuration Variables:: and the setup wizard is documented in *note
+Interactively Creating and Storing a Token::.
+
+* Menu:
+
+* Setting the Username::
+* Interactively Creating and Storing a Token::
+* Manually Creating and Storing a Token::
+* How Ghub uses Auth-Source::
+
+
+File: ghub.info,  Node: Setting the Username,  Next: Interactively Creating and Storing a Token,  Up: Getting Started
+
+2.1 Setting the Username
+========================
+
+If you haven’t set the Git variable ‘github.user’ yet when making a
+request, then you will be asked:
+
+     Git variable `github.user' is unset.  Set to:
+
+   You are expected to provide your Github username here.  The provided
+value will be saved globally (using ‘git config --global github.user
+USERNAME’).
+
+   If you need to identify as another user in a particular repository,
+then you have to set that variable locally, *before* making a request:
+
+     cd /path/to/repo
+     git config github.user USERNAME
+
+   For Github Enterprise instances you have to specify where the API can
+be accessed *before* you try to access it and a different variable has
+to be used to set the username.  For example if the API is available at
+‘https://example.com/api/v3’, then you should do this:
+
+     # Do this once
+     git config --global github.example.com/api/v3.user EMPLOYEE
+
+     # Do this for every corporate repository
+     cd /path/to/repo
+     git config github.host example.com/api/v3
+
+   If you do not set ‘github.example.com/api/v3.user’, then you will be
+asked to provide the value when trying to make a request, but you do
+have to manually set ‘github.host’, or Ghub assumes that you are trying
+to access ‘api.github.com’.
+
+
+File: ghub.info,  Node: Interactively Creating and Storing a Token,  Next: Manually Creating and Storing a Token,  Prev: Setting the Username,  Up: Getting Started
+
+2.2 Interactively Creating and Storing a Token
+==============================================
+
+Ghub uses a different token for every package as well as for every
+machine from which you access the Github API (and obviously also for
+every Github instance and user).  This allows packages to only request
+the scopes that they actually need and also gives users the opportunity
+to refuse access to certain scopes if they expect to not use the
+features that need them.
+
+   Usually you don’t have to worry about creating and storing a token
+yourself and can just make a request.  Note however that you don’t have
+to use the setup wizard described below.  Alternatively you can perform
+the setup manually as described in the next section.
+
+   If you make a request and the required token is not available yet,
+then the setup wizard will first ask you something like this:
+
+     Such a Github API token is not available:
+
+       Host:    api.github.com
+       User:    USERNAME
+       Package: PACKAGE
+
+       Scopes requested in `PACKAGE-github-token-scopes':
+         repo
+       Store on Github as:
+         "Emacs package PACKAGE @ LOCAL-MACHINE"
+       Store locally according to option `auth-sources':
+         ("~/.authinfo" "~/.authinfo.gpg" "~/.netrc")
+
+     If in doubt, then abort and first view the section of the Ghub
+     documentation called "Manually Creating and Storing a Token".
+
+     Create and store such a token? (yes or no)
+
+   If you don’t have any doubts, then answer "yes".  Lets address some
+of the doubts that you might have:
+
+   • ‘Host’ usually is "api.github.com" and that is usually what you
+     want.  If you are trying to access a Github Enterprise instance,
+     then it should be something else and you have to set the value
+     manually before the setup wizard is summoned, as described in the
+     parent section.
+
+   • ‘User’ should be your Github.com (or Github Enterprise instance)
+     username.  If it is something else and it doesn’t look like a
+     simple typo, then you should read the parent section again.  In
+     either case you have to abort.
+
+   • ‘Package’ should be the name of the package you are using to access
+     the Github API.
+
+     If it is ‘ghub’, then the package author disregarded that
+     convention and you should probably report a bug in the issue
+     tracker of that package.
+
+     Or you yourself are using ‘ghub-request’ or one of its wrappers
+     directly, in which case this is expected and perfectly fine.  In
+     that case you might however want to abort and change the value of
+     the variable ‘ghub-github-token-scopes’ before triggering the
+     wizard again.
+
+   • Each ‘PACKAGE’ has to specify the tokens that it needs using a
+     variable named ‘PACKAGE-github-token-scopes’.  The doc-string of
+     that variable should document why the various scopes are needed.
+
+     The meaning of the various scopes are documented at
+     <https://magit.vc/goto/f63aeb0a>.
+
+   • The value of ‘auth-sources’ is shown.  The default value causes
+     secrets to be stored in plain text.  Because this might be
+     unexpected, Ghub additionally displays a warning when appropriate.
+
+          WARNING: The token will be stored unencrypted in "~/.authinfo".
+                   If you don't want that, you have to abort and customize
+                   the `auth-sources' option.\n\n" (car auth-sources))
+
+     Whether that is something that needs fixing, is up to you.  If your
+     answer is yes, then you should abort and see *note How Ghub uses
+     Auth-Source:: for instructions on how to save the token more
+     securely.
+
+   • When creating a token it is necessary to provide a token
+     description.  Ghub uses descriptions that have the form "Emacs
+     package PACKAGE @ LOCAL-MACHINE".
+
+     Github uses the token description to identify the token, not merely
+     as something useful to humans.  Token descriptions therefore have
+     to be unique and in rare cases you get an additional prompt, asking
+     you something like:
+
+          A token named "Emacs package PACKAGE @ LOCAL-MACHINE"
+          already exists on Github.  Replace it?
+
+     You might see this message when you have lost the old token and
+     want to replace it with a new one, in which case you should
+     obviously just proceed.
+
+     Or two of your computers have the same hostname, which is bad
+     practice because it gains you nothing but leads to issues such as
+     this.  Or you are dual-booting on this machine and use the same
+     hostname in all operating systems, which is a somewhat reasonable
+     thing to do, but never-the-less leads to issues like this.
+
+     In either case you will have to use something other than the value
+     returned by ‘system-name’ to identify the current machine or
+     operating system.  Or you can continue to identify different things
+     using the same identifier, in which case you have to manually
+     distribute the token.
+
+     The former is recommended and also easier to do, using the variable
+     ‘ghub-override-system-name’.  See *note Configuration Variables::
+     for details.
+
+   After the above prompt you are also asked for you username and
+password.  If you have enabled two-factor authentication, then you also
+have to provide the authentication code at least twice.  If you make
+sure the code is still good for a while when asked for it first, then
+you can just press ‘RET’ at the later prompt(s).
+
+
+File: ghub.info,  Node: Manually Creating and Storing a Token,  Next: How Ghub uses Auth-Source,  Prev: Interactively Creating and Storing a Token,  Up: Getting Started
+
+2.3 Manually Creating and Storing a Token
+=========================================
+
+If you cannot or don’t want to use the wizard then you have to (1)
+figure out what scopes a package wants, (2) create such a token using
+the web interface and (3) store the token where Ghub expects to find it.
+
+   A package named ‘PACKAGE’ has to specify the scopes that it wants in
+the variable named ‘PACKAGE-ghub-token-scopes’.  The doc-string of such
+variables should document what the various scopes are needed for.
+
+   To create or edit a token go to <https://github.com/settings/tokens>.
+For Gitlab.com use <https://gitlab.com/profile/personal_access_tokens>.
+
+   Finally store the token in a place where Ghub looks for it, as
+described in *note How Ghub uses Auth-Source::.
+
+   If you store the token in a file like ‘~/.authinfo’, then note that
+‘auth-source’’s parsing of that file is brittle.  Make sure the file
+ends with a newline character, that there are no empty or invalid lines,
+and that all comments are prefixed with ‘#’.
+
+
+File: ghub.info,  Node: How Ghub uses Auth-Source,  Prev: Manually Creating and Storing a Token,  Up: Getting Started
+
+2.4 How Ghub uses Auth-Source
+=============================
+
+Please see *note (auth)Top:: for all the gory details about Auth-Source.
+Some Ghub-specific information and important notes follow.
+
+   The variable ‘auth-sources’ controls how and where Auth-Source stores
+new secrets and where it looks for known secrets.  The default value is
+‘("~/.authinfo" "~/.authinfo.gpg" "~/.netrc")’, which means that it
+looks in all of these files in order to find secrets and that it stores
+new secrets in ‘~/.authinfo’ because that is the first element of the
+list.  It doesn’t matter which files already do or don’t exist when
+storing a new secret, the first file is always used.
+
+   Secrets are stored in ‘~/.authinfo’ in plain text.  If you don’t want
+that (good choice), then you have to customize ‘auth-sources’, e.g.  by
+flipping the positions of the first two elements.
+
+   Auth-Source also supports storing secrets in various key-chains.
+Refer to its documentation for more information.
+
+   Some Auth-Source backends only support storing three values per
+entry, the "machine", the "login" and the "password".  Because Ghub uses
+separate tokens for each package, it has to squeeze four values into
+those three slots, and it does that by using "USERNAME^PACKAGE" as the
+"login".
+
+   Assuming your username is "ziggy",the package is named "stardust",
+and you want to access *Github.com* an entry in one of the three
+mentioned files would then look like this:
+
+     machine api.github.com login ziggy^stardust password 012345abcdef...
+
+   Assuming your username is "ziggy",the package is named "stardust",
+and you want to access *Gitlab.com* an entry in one of the three
+mentioned files would then look like this:
+
+     machine gitlab.com/api/v4 login ziggy^stardust password 012345abcdef...
+
+
+File: ghub.info,  Node: Using Ghub in Personal Scripts,  Next: Using Ghub in a Package,  Prev: Getting Started,  Up: Top
+
+3 Using Ghub in Personal Scripts
+********************************
+
+You can use ‘ghub-request’ and its wrapper functions in your personal
+scripts, of course.  Unlike when you use Ghub from a package that you
+distribute for others to use, you don’t have to specify a package in
+personal scripts.
+
+     ;; This is perfectly acceptable in personal scripts ...
+     (ghub-get "/user")
+
+     ;; ... and actually equal to
+     (ghub-get "/user" nil :auth 'ghub)
+
+     ;; In packages you have to specify the package using AUTH.
+     (ghub-get "/user" nil :auth 'foobar)
+
+   When you do not specify the ‘AUTH’ argument, then a request is made
+on behalf of the ‘ghub’ package itself.  Like for any package that uses
+Ghub, ‘ghub’ has to declare what scopes it needs, using, in this case,
+the variable ‘ghub-github-token-scopes’.
+
+   The default value of that variable is ‘(repo)’ and you might want to
+add additional scopes.  You can later add additional scopes to an
+existing token, using the web interface at
+<https://github.com/settings/tokens>.
+
+   If you do that, then you might want to also set the variable
+accordingly, but note that Ghub only consults that when *creating* a new
+token.  If you want to know a token’s effective scopes use the command
+‘ghub-token-scopes’, described in the next section.
+
+
+File: ghub.info,  Node: Using Ghub in a Package,  Next: API,  Prev: Using Ghub in Personal Scripts,  Up: Top
+
+4 Using Ghub in a Package
+*************************
+
+Every package should use its own token.  This allows you as the author
+of some package to only request access to API scopes that are actually
+needed, which in turn might make it easier for users to trust your
+package not to do unwanted things.
+
+   The scopes used by ‘PACKAGE’ have to be defined using the variable
+‘PACKAGE-github-token-scopes’, and you have to tell ‘ghub-request’ on
+behalf of which package a request is being made by passing the symbol
+‘PACKAGE’ as the value of its ‘AUTH’ argument.
+
+     (ghub-request "GET" "/user" nil :auth 'PACKAGE)
+
+ -- Variable: PACKAGE-github-token-scopes
+
+     This variable defines the token scopes requested by the package
+     named ‘PACKAGE’.  The doc-string should explain what the various
+     scopes are needed for to prevent users from giving ‘PACKAGE’ fewer
+     permissions than it absolutely needs and also to give them greater
+     confidence that ‘PACKAGE’ is only requesting the permissions that
+     it actually needs.
+
+     The value of this variable does not necessarily correspond to the
+     scopes that the respective token actually gives access to.  There
+     is nothing that prevents users from changing the value *after*
+     creating the token or from editing the token’s scopes later on.
+
+     So it is pointless to check the value of this variable before
+     making a request.  You also should not query the API to reliably
+     determine the supported tokens before making a query.  Doing the
+     latter would mean that every request becomes two requests and that
+     the first request would have to be done using the user’s password
+     instead of a token.
+
+ -- Command: ghub-token-scopes
+
+     Because we cannot be certain that the user hasn’t messed up the
+     scopes, Ghub provides this command to make it easy to debug such
+     issues without having to rely on users being thoughtful enough to
+     correctly determine the used scopes manually.
+
+     Just tell users to run ‘M-x ghub-token-scopes’ and to provide the
+     correct values for the ‘HOST’, ‘USERNAME’ and ‘PACKAGE’ when
+     prompted, and to then post the output.
+
+     It is to be expected that users will occasionally mess that up so
+     this command outputs not only the scopes but also the user input so
+     that you can have greater confidence in the validity of the user’s
+     answer.
+
+          Scopes for USERNAME^PACKAGE@HOST: (SCOPE...)
+
+
+File: ghub.info,  Node: API,  Next: Gitlab Support,  Prev: Using Ghub in a Package,  Up: Top
+
+5 API
+*****
+
+This section describes the Ghub API.  In other words it describes the
+public functions and variables provided by the Ghub library and not the
+Github API that can be accessed by using those functions.  The latter is
+documented at <https://developer.github.com/v3>.
+
+* Menu:
+
+* Making Requests::
+* Authentication::
+* Configuration Variables::
+
+
+File: ghub.info,  Node: Making Requests,  Next: Authentication,  Up: API
+
+5.1 Making Requests
+===================
+
+ -- Function: ghub-request method resource &optional params &key query
+          payload headers unpaginate noerror reader username auth host
+          callback errorback url value error extra method*
+
+     This function makes a request for ‘RESOURCE’ using ‘METHOD’.
+     ‘PARAMS’, ‘QUERY’, ‘PAYLOAD’ and/or ‘HEADERS’ are alists holding
+     additional request data.  The response body is returned and the
+     response header is stored in the variable ‘ghub-response-headers’.
+
+        • ‘METHOD’ is the HTTP method, given as a string.
+
+        • ‘RESOURCE’ is the resource to access, given as a string
+          beginning with a slash.
+
+        • ‘PARAMS’, ‘QUERY’, ‘PAYLOAD’ and ‘HEADERS’ are alists and are
+          used to specify request data.  All these arguments are alists
+          that resemble the JSON expected and returned by the Github
+          API.  The keys are symbols and the values stored in the ‘cdr’
+          (not the ‘cadr’) can be strings, integers, or lists of strings
+          and integers.
+
+          The Github API documentation is vague on how data has to be
+          transmitted and for a particular resource usually just talks
+          about "parameters".  Generally speaking when the ‘METHOD’ is
+          "HEAD" or "GET", then they have to be transmitted as a query,
+          otherwise as a payload.
+
+             • Use ‘PARAMS’ to automatically transmit like ‘QUERY’ or
+               ‘PAYLOAD’ would depending on ‘METHOD’.
+
+             • Use ‘QUERY’ to explicitly transmit data as a query.
+
+             • Use ‘PAYLOAD’ to explicitly transmit data as a payload.
+               Instead of an alist, ‘PAYLOAD’ may also be a string, in
+               which case it gets encoded as UTF-8 but is otherwise
+               transmitted as-is.
+
+             • Use ‘HEADERS’ for those rare resources that require that
+               the data is transmitted as headers instead of as a query
+               or payload.  When that is the case, then the Github API
+               documentation usually mentions it explicitly.
+
+        • If ‘SILENT’ is non-nil, then progress reports and the like are
+          not messaged.
+
+        • If ‘UNPAGINATE’ is t, then this function make as many requests
+          as necessary to get all values.  If ‘UNPAGINATE’ is a natural
+          number, then it gets at most that many pages.  For any other
+          non-nil value it raises an error.
+
+        • If ‘NOERROR’ is non-nil, then no error is raised if the
+          request fails and ‘nil’ is returned instead.  If ‘NOERROR’ is
+          ‘return’, then the error payload is returned instead of ‘nil’.
+
+        • If ‘READER’ is non-nil, then it is used to read and return
+          from the response buffer.  The default is
+          ‘ghub--read-json-payload’.  For the very few resources that do
+          not return JSON, you might want to use ‘ghub--decode-payload’.
+
+        • If ‘USERNAME’ is non-nil, then the request is made on behalf
+          of that user.  It is better to specify the user using the Git
+          variable ‘github.user’ for "api.github.com", or
+          ‘github.HOST.user’ if connecting to a Github Enterprise
+          instance.
+
+        • Each package that uses Ghub should use its own token.  If
+          ‘AUTH’ is ‘nil’ or unspecified, then the generic ‘ghub’ token
+          is used instead.  This is only acceptable for personal
+          utilities.  A packages that is distributed to other users
+          should always use this argument to identify itself, using a
+          symbol matching its name.
+
+          Package authors who find this inconvenient should write a
+          wrapper around this function and possibly for the
+          method-specific functions as well.
+
+          Beside ‘nil’, some other symbols have a special meaning too.
+          ‘none’ means to make an unauthorized request.  ‘basic’ means
+          to make a password based request.  If the value is a string,
+          then it is assumed to be a valid token.  ‘basic’ and an
+          explicit token string are only intended for internal and
+          debugging uses.
+
+          If ‘AUTH’ is a package symbol, then the scopes are specified
+          using the variable ‘AUTH-github-token-scopes’.  It is an error
+          if that is not specified.  See ‘ghub-github-token-scopes’ for
+          an example.
+
+        • If ‘HOST’ is non-nil, then connect to that Github instance.
+          This defaults to "api.github.com".  When a repository is
+          connected to a Github Enterprise instance, then it is better
+          to specify that using the Git variable ‘github.host’ instead
+          of using this argument.
+
+        • If ‘FORGE’ is ‘gitlab’, then connect to Gitlab.com or,
+          depending on ‘HOST’, to another Gitlab instance.  This is only
+          intended for internal use.  Instead of using this argument you
+          should use function ‘glab-request’ and other ‘glab-*’
+          functions.
+
+        • If ‘CALLBACK’ and/or ‘ERRORBACK’ is non-nil, then this
+          function makes one or more asynchronous requests and calls
+          ‘CALLBACK’ or ‘ERRORBACK’ when finished.  If an error
+          occurred, then it calls ‘ERRORBACK’, or if that is ‘nil’, then
+          ‘CALLBACK’.  When no error occurred then it calls ‘CALLBACK’.
+          When making asynchronous requests, then no errors are
+          signaled, regardless of the value of ‘NOERROR’.
+
+          Both callbacks are called with four arguments.
+
+             • For ‘CALLBACK’, the combined value of the retrieved
+               pages.  For ‘ERRORBACK’, the error that occured when
+               retrieving the last page.
+
+             • The headers of the last page as an alist.
+
+             • Status information provided by ‘url-retrieve’.  Its
+               ‘:error’ property holds the same information as the first
+               argument to ‘ERRORBACK’.
+
+             • A ‘ghub--req’ struct, which can be passed to
+               ‘ghub-continue’ (which see) to retrieve the next page, if
+               any.
+
+ -- Function: ghub-continue args
+
+     If there is a next page, then this function retrieves that.
+
+     This function is only intended to be called from callbacks.  If
+     there is a next page, then that is retrieve and the buffer that the
+     result will be loaded into is returned, or t if the process has
+     already completed.  If there is no next page, then return nil.
+
+     Callbacks are called with four arguments (see ‘ghub-request’).  The
+     forth argument is a ‘ghub--req’ struct, intended to be passed to
+     this function.  A callbacks may use the struct’s ‘extra’ slot to
+     pass additional information to the callback that will be called
+     after the next request.  Use the function ‘ghub-req-extra’ to get
+     and set the value of that slot.
+
+     As an example, using ‘ghub-continue’ in a callback like so:
+
+          (ghub-get "/users/tarsius/repos" nil
+                    :callback (lambda (value _headers _status req)
+                                (unless (ghub-continue req)
+                                  (setq my-value value))))
+
+     is equivalent to:
+
+          (ghub-get "/users/tarsius/repos" nil
+                    :unpaginate t
+                    :callback (lambda (value _headers _status _req)
+                                (setq my-value value)))
+
+     To demonstrate how to pass information from one callback to the
+     next, here we record when we start fetching each page:
+
+          (ghub-get "/users/tarsius/repos" nil
+                    :extra (list (current-time))
+                    :callback (lambda (value _headers _status req)
+                                (push (current-time) (ghub-req-extra req))
+                                (unless (ghub-continue req)
+                                  (setq my-times (ghub-req-extra req))
+                                  (setq my-value value))))
+
+ -- Variable: ghub-response-headers
+
+     A select few Github API resources respond by transmitting data in
+     the response header instead of in the response body.  Because there
+     are so few of these inconsistencies, ‘ghub-request’ always returns
+     the response body.
+
+     To access the response headers use this variable after
+     ‘ghub-request’ has returned.
+
+ -- Function: ghub-response-link-relations headers
+
+     This function returns an alist of the link relations in ‘HEADERS’,
+     or if optional ‘HEADERS’ is nil, then those in
+     ‘ghub-response-headers’.
+
+ -- Variable: ghub-override-system-name
+
+     If non-nil, the value of this variable is used to override the
+     value returned by ‘system-name’ for the purpose of identifying the
+     local machine, which is necessary because Ghub uses separate tokens
+     for each machine.  Also see *note Configuration Variables::.
+
+ -- Variable: ghub-github-token-scopes
+ -- Variable: PACKAGE-github-token-scopes
+
+     Such a variable defines the token scopes requested by the
+     respective package ‘PACKAGE’ given by the first word in the
+     variable name.  ‘ghub’ itself is treated like any other package.
+     Also see *note Using Ghub in a Package::.
+
+ -- Function: ghub-head resource &optional params &key query payload
+          headers unpaginate noerror reader username auth host callback
+          errorback
+ -- Function: ghub-get resource &optional params &key query payload
+          headers unpaginate noerror reader username auth host callback
+          errorback
+
+     These functions are simple wrappers around ‘ghub-request’.  Their
+     signature is identical to that of the latter, except that they do
+     not have an argument named ‘METHOD’.  The HTTP method is instead
+     given by the second word in the function name.
+
+     As described in the documentation for ‘ghub-request’, it depends on
+     the used method whether the value of the ‘PARAMS’ argument is used
+     as the query or the payload.  For the "HEAD" and "GET" methods it
+     is used as the query.
+
+ -- Function: ghub-put resource &optional params &key query payload
+          headers unpaginate noerror reader username auth host callback
+          errorback
+ -- Function: ghub-post resource &optional params &key query payload
+          headers unpaginate noerror reader username auth host callback
+          errorback
+ -- Function: ghub-patch resource &optional params &key query payload
+          headers unpaginate noerror reader username auth host callback
+          errorback
+ -- Function: ghub-delete resource &optional params &key query payload
+          headers unpaginate noerror reader username auth host callback
+          errorback
+
+     These functions are simple wrappers around ‘ghub-request’.  Their
+     signature is identical to that of the latter, except that they do
+     not have an argument named ‘METHOD’.  The HTTP method is instead
+     given by the second word in the function name.
+
+     As described in the documentation for ‘ghub-request’, it depends on
+     the used method whether the value of the ‘PARAMS’ argument is used
+     as the query or the payload.  For the "PUT", "POST", "PATCH" and
+     "DELETE" methods it is used as the payload.
+
+ -- Function: ghub-wait resource &optional duration &key username auth
+          host
+
+     Some API requests result in an immediate successful response even
+     when the requested action has not actually been carried out yet.
+     An example is the request for the creation of a new repository,
+     which doesn’t cause the repository to immediately become available.
+     The Github API documentation usually mentions this when describing
+     an affected resource.
+
+     If you want to do something with some resource right after making a
+     request for its creation, then you might have to wait for it to
+     actually be created.  This function can be used to do so.  It
+     repeatedly tries to access the resource until it becomes available
+     or until the timeout exceeds.  In the latter case it signals
+     ‘ghub-error’.
+
+     ‘RESOURCE’ specifies the resource that this function waits for.
+
+     ‘DURATION’ specifies the maximum number of seconds to wait for,
+     defaulting to 64 seconds.  Emacs will block during that time, but
+     the user can abort using ‘C-g’.
+
+     The first attempt is made immediately and will often succeed.  If
+     not, then another attempt is made after two seconds, and each
+     subsequent attempt is made after waiting as long as we already
+     waited between all preceding attempts combined.
+
+     See ‘ghub-request’’s documentation above for information about the
+     other arguments.
+
+ -- Function: ghub-graphql graphql &optional variables &key username
+          auth host callback
+
+     This function makes a GraphQL request using ‘GRAPHQL’ and
+     ‘VARIABLES’ as inputs.  ‘GRAPHQL’ is a GraphQL string.  ‘VARIABLES’
+     is a JSON-like alist.  The other arguments behave as for
+     ‘ghub-request’ (which see).
+
+     The response is returned as a JSON-like alist.  Even if the
+     response contains ‘errors’, this function does not raise an error.
+     Cursor-handling is likewise left to the caller.
+
+
+File: ghub.info,  Node: Authentication,  Next: Configuration Variables,  Prev: Making Requests,  Up: API
+
+5.2 Authentication
+==================
+
+ -- Command: ghub-create-token
+
+     This command creates a new token using the values it reads from the
+     user and then stores it according to the variable ‘auth-sources’.
+     It can also be called non-interactively, but you shouldn’t do that
+     yourself.
+
+     This is useful if you want to fully setup things before attempting
+     to make the initial request, if you want to provide fewer than the
+     requested scopes or customize ‘auth-sources’ first, or if something
+     has gone wrong when using the wizard that is used when making a
+     request without doing this first.  (Note that instead of using this
+     command you can also just repeat the initial request after making
+     the desired adjustments — that is easier.)
+
+     This command reads, in order, the ‘HOST’ (Github instance), the
+     ‘USERNAME’, the ‘PACKAGE’, and the ‘SCOPES’ in the minibuffer,
+     providing reasonable default choices.  ‘SCOPES’ defaults to the
+     scopes that ‘PACKAGE’ requests using the variable
+     ‘PACKAGE-github-token-scopes’.
+
+ -- Command: ghub-token-scopes
+
+     Users are free to give a token access to fewer scopes than what the
+     respective package requested.  That can, of course, lead to issues,
+     and package maintainers have to be able to quickly determine if
+     such a (mis-)configuration is the root cause when users report
+     issues.
+
+     This command reads the required values in the minibuffer and then
+     shows a message containing these values along with the scopes of
+     the respective token.  It also returns the scopes (only) when
+     called non-interactively.  Also see *note Using Ghub in a
+     Package::.
+
+
+File: ghub.info,  Node: Configuration Variables,  Prev: Authentication,  Up: API
+
+5.3 Configuration Variables
+===========================
+
+The username and, unless you only use Github.com itself, the Github
+Enterprise instance have to be configured using Git variables.  In rare
+cases it might also be necessary to specify the identity of the local
+machine, which is done using a lisp variable.
+
+ -- Variable: github.user
+
+     The Github.com username.  This should be set globally and if you
+     have multiple Github.com user accounts, then you should set this
+     locally only for those repositories that you want to access using
+     the secondary identity.
+
+ -- Variable: github.HOST.user
+
+     This variable serves the same purpose as ‘github.user’ but for the
+     Github Enterprise instance identified by ‘HOST’.
+
+     The reason why separate variables are used is that this makes it
+     possible to set both values globally instead of having to set one
+     of the values locally in each and every repository that is
+     connected to the Github Enterprise instance, not Github.com.
+
+ -- Variable: github.host
+
+     This variable should only be set locally for a repository and
+     specifies the Github Enterprise edition that that repository is
+     connected to.  You should not set this globally because then each
+     and every repository becomes connected to the specified Github
+     Enterprise instance, including those that should actually be
+     connected to Github.com.
+
+     When this is undefined, then "api.github.com" is used (defined in
+     the constant ‘ghub-default-host’, which you should never attempt to
+     change.)
+
+ -- Variable: ghub-override-system-name
+
+     Ghub uses a different token for each quadruple ‘(USERNAME PACKAGE
+     HOST LOCAL-MACHINE)’.  Theoretically it could reuse tokens to some
+     extent but that would be more difficult to implement, less
+     flexible, and less secure (though slightly more convenient).
+
+     A token is identified on the respective Github instance (Github.com
+     or a Github Enterprise instance) using the pair ‘(PACKAGE .
+     LOCAL-MACHINE)’, or more precisely the string "Emacs package
+     PACKAGE @ LOCAL-MACHINE". ‘USERNAME’ and ‘HOST’ do not have to be
+     encoded because the token is stored for ‘USERNAME’ on ‘HOST’ and
+     cannot be used by another user and/or on another instance.
+
+     There is one potential problem though; for any given ‘(PACKAGE .
+     LOCAL-MACHINE)’ there can only be one token identified by "Emacs
+     package PACKAGE @ LOCAL-MACHINE"; Github does not allow multiple
+     tokens with the same description because it uses the description as
+     the identifier (it could use some hash instead, but alas it does
+     not).
+
+     If you have multiple machines and some of them have the same name,
+     then you should probably change that as this is not how things
+     ought to be.  However if you dual-boot, then it might make sense to
+     give that machine the same name regardless of what operating system
+     you have booted into.
+
+     You could use the same token on both operating systems, but setting
+     that up might be somewhat difficult because it is not possible to
+     download an existing token from Github.  You could, of course,
+     locally copy the token, but that is inconvenient and would make it
+     harder to only revoke the token used on your infected Windows
+     installation without also revoking it for your totally safe *BSD
+     installation.
+
+     Alternatively you can set this variable to a unique value, that
+     will then be used to identify the local machine instead of the
+     value returned by ‘system-name’.
+
+
+File: ghub.info,  Node: Gitlab Support,  Prev: API,  Up: Top
+
+6 Gitlab Support
+****************
+
+Support for Gitlab.com and other Gitlab instances is implemented in the
+library ‘glab.el’.  This library is build on top of ‘ghub.el’ and is
+maintained in the same repository, but it is distributed as a separate
+package.
+
+   When accessing Gitlab.com or another Gitlab instance, use
+‘glab-request’ instead of ‘ghub-request’, ‘glab-get’ instead of
+‘ghub-get’, etc.  Likewise use the Git variables in the ‘gitlab’ group
+instead of those in the ‘github’ group, i.e.  ‘gitlab.user’,
+‘gitlab.HOST.user’ and ‘gitlab.host’.
+
+   The Gitlab API cannot be used to create tokens, so Glab cannot
+provide a setup wizard like Ghub does.  As a consequence, if the user
+makes a request and the necessary token cannot be found, then that
+results in an error.
+
+   You have to manually create and store the necessary tokens.  Tokens
+can be created at <https://gitlab.com/profile/personal_access_tokens>,
+or the equivalent URL for another Gitlab instance.  To store the token
+locally, follow the instructions in *note Manually Creating and Storing
+a Token:: and *note How Ghub uses Auth-Source::.
+
+   Packages that use Glab can define ‘PACKAGE-gitlab-token-scopes’ for
+documentation purposes.  But unlike ‘PACKAGE-github-token-scopes’, which
+is used by the setup wizard, this is optional.
+
+   And a random hint: where you would use ‘user/repo’ when accessing
+Github, you have to use ‘user%2Frepo’ when accessing Gitlab, e.g.:
+
+     (glab-get "/projects/python-mode-devs%2Fpython-mode")
+
+
+
+Tag Table:
+Node: Top763
+Node: Introduction2838
+Node: Getting Started5562
+Node: Setting the Username8620
+Node: Interactively Creating and Storing a Token10045
+Node: Manually Creating and Storing a Token15710
+Node: How Ghub uses Auth-Source16933
+Node: Using Ghub in Personal Scripts18866
+Node: Using Ghub in a Package20322
+Node: API22940
+Node: Making Requests23391
+Node: Authentication37080
+Node: Configuration Variables38925
+Node: Gitlab Support42645
+
+End Tag Table
+
+
+Local Variables:
+coding: utf-8
+End:
diff --git a/configs/shared/emacs/.emacs.d/elpa/git-commit-20180713.1444/git-commit-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/git-commit-20180713.1444/git-commit-autoloads.el
new file mode 100644
index 0000000000..f47a2a7773
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/git-commit-20180713.1444/git-commit-autoloads.el
@@ -0,0 +1,48 @@
+;;; git-commit-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "git-commit" "git-commit.el" (23377 61607 152033
+;;;;;;  451000))
+;;; Generated autoloads from git-commit.el
+
+(defvar global-git-commit-mode t "\
+Non-nil if Global Git-Commit mode is enabled.
+See the `global-git-commit-mode' command
+for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `global-git-commit-mode'.")
+
+(custom-autoload 'global-git-commit-mode "git-commit" nil)
+
+(autoload 'global-git-commit-mode "git-commit" "\
+Edit Git commit messages.
+This global mode arranges for `git-commit-setup' to be called
+when a Git commit message file is opened.  That usually happens
+when Git uses the Emacsclient as $GIT_EDITOR to have the user
+provide such a commit message.
+
+\(fn &optional ARG)" t nil)
+
+(defconst git-commit-filename-regexp "/\\(\\(\\(COMMIT\\|NOTES\\|PULLREQ\\|TAG\\)_EDIT\\|MERGE_\\|\\)MSG\\|\\(BRANCH\\|EDIT\\)_DESCRIPTION\\)\\'")
+
+(autoload 'git-commit-setup-check-buffer "git-commit" "\
+
+
+\(fn)" nil nil)
+
+(autoload 'git-commit-setup "git-commit" "\
+
+
+\(fn)" nil nil)
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; git-commit-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/git-commit-20180713.1444/git-commit-pkg.el b/configs/shared/emacs/.emacs.d/elpa/git-commit-20180713.1444/git-commit-pkg.el
new file mode 100644
index 0000000000..40fb60c228
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/git-commit-20180713.1444/git-commit-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "git-commit" "20180713.1444" "Edit Git commit messages" '((emacs "25.1") (dash "20180413") (with-editor "20180414")))
diff --git a/configs/shared/emacs/.emacs.d/elpa/git-commit-20180713.1444/git-commit.el b/configs/shared/emacs/.emacs.d/elpa/git-commit-20180713.1444/git-commit.el
new file mode 100644
index 0000000000..4291b339cd
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/git-commit-20180713.1444/git-commit.el
@@ -0,0 +1,881 @@
+;;; git-commit.el --- Edit Git commit messages  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2010-2018  The Magit Project Contributors
+;;
+;; You should have received a copy of the AUTHORS.md file which
+;; lists all contributors.  If not, see http://magit.vc/authors.
+
+;; Authors: Jonas Bernoulli <jonas@bernoul.li>
+;;	Sebastian Wiesner <lunaryorn@gmail.com>
+;;	Florian Ragwitz <rafl@debian.org>
+;;	Marius Vollmer <marius.vollmer@gmail.com>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; Package-Requires: ((emacs "25.1") (dash "20180413") (with-editor "20180414"))
+;; Package-Version: 20180713.1444
+;; Keywords: git tools vc
+;; Homepage: https://github.com/magit/magit
+
+;; This file is not part of GNU Emacs.
+
+;; This file 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, or (at your option)
+;; any later version.
+
+;; This file 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 this file.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This package assists the user in writing good Git commit messages.
+
+;; While Git allows for the message to be provided on the command
+;; line, it is preferable to tell Git to create the commit without
+;; actually passing it a message.  Git then invokes the `$GIT_EDITOR'
+;; (or if that is undefined `$EDITOR') asking the user to provide the
+;; message by editing the file ".git/COMMIT_EDITMSG" (or another file
+;; in that directory, e.g. ".git/MERGE_MSG" for merge commits).
+
+;; When `global-git-commit-mode' is enabled, which it is by default,
+;; then opening such a file causes the features described below, to
+;; be enabled in that buffer.  Normally this would be done using a
+;; major-mode but to allow the use of any major-mode, as the user sees
+;; fit, it is done here by running a setup function, which among other
+;; things turns on the preferred major-mode, by default `text-mode'.
+
+;; Git waits for the `$EDITOR' to finish and then either creates the
+;; commit using the contents of the file as commit message, or, if the
+;; editor process exited with a non-zero exit status, aborts without
+;; creating a commit.  Unfortunately Emacsclient (which is what Emacs
+;; users should be using as `$EDITOR' or at least as `$GIT_EDITOR')
+;; does not differentiate between "successfully" editing a file and
+;; aborting; not out of the box that is.
+
+;; By making use of the `with-editor' package this package provides
+;; both ways of finish an editing session.  In either case the file
+;; is saved, but Emacseditor's exit code differs.
+;;
+;;   C-c C-c  Finish the editing session successfully by returning
+;;            with exit code 0.  Git then creates the commit using
+;;            the message it finds in the file.
+;;
+;;   C-c C-k  Aborts the edit editing session by returning with exit
+;;            code 1.  Git then aborts the commit.
+
+;; Aborting the commit does not cause the message to be lost, but
+;; relying solely on the file not being tampered with is risky.  This
+;; package additionally stores all aborted messages for the duration
+;; of the current session (i.e. until you close Emacs).  To get back
+;; an aborted message use M-p and M-n while editing a message.
+;;
+;;   M-p      Replace the buffer contents with the previous message
+;;            from the message ring.  Of course only after storing
+;;            the current content there too.
+;;
+;;   M-n      Replace the buffer contents with the next message from
+;;            the message ring, after storing the current content.
+
+;; Some support for pseudo headers as used in some projects is
+;; provided by these commands:
+;;
+;;   C-c C-s  Insert a Signed-off-by header.
+;;   C-c C-a  Insert a Acked-by header.
+;;   C-c C-m  Insert a Modified-by header.
+;;   C-c C-t  Insert a Tested-by header.
+;;   C-c C-r  Insert a Reviewed-by header.
+;;   C-c C-o  Insert a Cc header.
+;;   C-c C-p  Insert a Reported-by header.
+;;   C-c M-s  Insert a Suggested-by header.
+
+;; When Git requests a commit message from the user, it does so by
+;; having her edit a file which initially contains some comments,
+;; instructing her what to do, and providing useful information, such
+;; as which files were modified.  These comments, even when left
+;; intact by the user, do not become part of the commit message.  This
+;; package ensures these comments are propertizes as such and further
+;; prettifies them by using different faces for various parts, such as
+;; files.
+
+;; Finally this package highlights style errors, like lines that are
+;; too long, or when the second line is not empty.  It may even nag
+;; you when you attempt to finish the commit without having fixed
+;; these issues.  The style checks and many other settings can easily
+;; be configured:
+;;
+;;   M-x customize-group RET git-commit RET
+
+;;; Code:
+;;;; Dependencies
+
+(require 'dash)
+(require 'log-edit)
+(require 'magit-git nil t)
+(require 'magit-utils nil t)
+(require 'ring)
+(require 'server)
+(require 'with-editor)
+
+(eval-when-compile (require 'recentf))
+
+;;;; Declarations
+
+(defvar diff-default-read-only)
+(defvar flyspell-generic-check-word-predicate)
+(defvar font-lock-beg)
+(defvar font-lock-end)
+
+(declare-function magit-expand-git-file-name "magit-git" (filename))
+(declare-function magit-list-local-branch-names "magit-git" ())
+(declare-function magit-list-remote-branch-names "magit-git"
+                  (&optional remote relative))
+
+;;; Options
+;;;; Variables
+
+(defgroup git-commit nil
+  "Edit Git commit messages."
+  :prefix "git-commit-"
+  :link '(info-link "(magit)Editing Commit Messages")
+  :group 'tools)
+
+;;;###autoload
+(define-minor-mode global-git-commit-mode
+  "Edit Git commit messages.
+This global mode arranges for `git-commit-setup' to be called
+when a Git commit message file is opened.  That usually happens
+when Git uses the Emacsclient as $GIT_EDITOR to have the user
+provide such a commit message."
+  :group 'git-commit
+  :type 'boolean
+  :global t
+  :init-value t
+  :initialize (lambda (symbol exp)
+                (custom-initialize-default symbol exp)
+                (when global-git-commit-mode
+                  (add-hook 'find-file-hook 'git-commit-setup-check-buffer)))
+  (if global-git-commit-mode
+      (add-hook  'find-file-hook 'git-commit-setup-check-buffer)
+    (remove-hook 'find-file-hook 'git-commit-setup-check-buffer)))
+
+(defcustom git-commit-major-mode 'text-mode
+  "Major mode used to edit Git commit messages.
+The major mode configured here is turned on by the minor mode
+`git-commit-mode'."
+  :group 'git-commit
+  :type '(choice (function-item text-mode)
+                 (const :tag "No major mode")))
+
+(defcustom git-commit-setup-hook
+  '(git-commit-save-message
+    git-commit-setup-changelog-support
+    git-commit-turn-on-auto-fill
+    git-commit-propertize-diff
+    with-editor-usage-message)
+  "Hook run at the end of `git-commit-setup'."
+  :group 'git-commit
+  :type 'hook
+  :get (and (featurep 'magit-utils) 'magit-hook-custom-get)
+  :options '(git-commit-save-message
+             git-commit-setup-changelog-support
+             git-commit-turn-on-auto-fill
+             git-commit-turn-on-flyspell
+             git-commit-propertize-diff
+             bug-reference-mode
+             with-editor-usage-message))
+
+(defcustom git-commit-finish-query-functions
+  '(git-commit-check-style-conventions)
+  "List of functions called to query before performing commit.
+
+The commit message buffer is current while the functions are
+called.  If any of them returns nil, then the commit is not
+performed and the buffer is not killed.  The user should then
+fix the issue and try again.
+
+The functions are called with one argument.  If it is non-nil,
+then that indicates that the user used a prefix argument to
+force finishing the session despite issues.  Functions should
+usually honor this wish and return non-nil."
+  :options '(git-commit-check-style-conventions)
+  :type 'hook
+  :group 'git-commit)
+
+(defcustom git-commit-style-convention-checks '(non-empty-second-line)
+  "List of checks performed by `git-commit-check-style-conventions'.
+Valid members are `non-empty-second-line' and `overlong-summary-line'.
+That function is a member of `git-commit-finish-query-functions'."
+  :options '(non-empty-second-line overlong-summary-line)
+  :type '(list :convert-widget custom-hook-convert-widget)
+  :group 'git-commit)
+
+(defcustom git-commit-summary-max-length 68
+  "Column beyond which characters in the summary lines are highlighted.
+
+The highlighting indicates that the summary is getting too long
+by some standards.  It does in no way imply that going over the
+limit a few characters or in some cases even many characters is
+anything that deserves shaming.  It's just a friendly reminder
+that if you can make the summary shorter, then you might want
+to consider doing so."
+  :group 'git-commit
+  :safe 'numberp
+  :type 'number)
+
+(defcustom git-commit-fill-column nil
+  "Override `fill-column' in commit message buffers.
+
+If this is non-nil, then it should be an integer.  If that is the
+case and the buffer-local value of `fill-column' is not already
+set by the time `git-commit-turn-on-auto-fill' is called as a
+member of `git-commit-setup-hook', then that function sets the
+buffer-local value of `fill-column' to the value of this option.
+
+This option exists mostly for historic reasons.  If you are not
+already using it, then you probably shouldn't start doing so."
+  :group 'git-commit
+  :safe 'numberp
+  :type '(choice (const :tag "use regular fill-column")
+                 number))
+
+(make-obsolete-variable 'git-commit-fill-column 'fill-column
+                        "Magit 2.11.0" 'set)
+
+(defcustom git-commit-known-pseudo-headers
+  '("Signed-off-by" "Acked-by" "Modified-by" "Cc"
+    "Suggested-by" "Reported-by" "Tested-by" "Reviewed-by")
+  "A list of Git pseudo headers to be highlighted."
+  :group 'git-commit
+  :safe (lambda (val) (and (listp val) (-all-p 'stringp val)))
+  :type '(repeat string))
+
+;;;; Faces
+
+(defgroup git-commit-faces nil
+  "Faces used for highlighting Git commit messages."
+  :prefix "git-commit-"
+  :group 'git-commit
+  :group 'faces)
+
+(defface git-commit-summary
+  '((t :inherit font-lock-type-face))
+  "Face used for the summary in commit messages."
+  :group 'git-commit-faces)
+
+(defface git-commit-overlong-summary
+  '((t :inherit font-lock-warning-face))
+  "Face used for the tail of overlong commit message summaries."
+  :group 'git-commit-faces)
+
+(defface git-commit-nonempty-second-line
+  '((t :inherit font-lock-warning-face))
+  "Face used for non-whitespace on the second line of commit messages."
+  :group 'git-commit-faces)
+
+(defface git-commit-note
+  '((t :inherit font-lock-string-face))
+  "Face used for notes in commit messages."
+  :group 'git-commit-faces)
+
+(defface git-commit-pseudo-header
+  '((t :inherit font-lock-string-face))
+  "Face used for pseudo headers in commit messages."
+  :group 'git-commit-faces)
+
+(defface git-commit-known-pseudo-header
+  '((t :inherit font-lock-keyword-face))
+  "Face used for the keywords of known pseudo headers in commit messages."
+  :group 'git-commit-faces)
+
+(defface git-commit-comment-branch-local
+  (if (featurep 'magit)
+      '((t :inherit magit-branch-local))
+    '((t :inherit font-lock-variable-name-face)))
+  "Face used for names of local branches in commit message comments."
+  :group 'git-commit-faces)
+
+(define-obsolete-face-alias 'git-commit-comment-branch
+  'git-commit-comment-branch-local "Git-Commit 2.12.0")
+
+(defface git-commit-comment-branch-remote
+  (if (featurep 'magit)
+      '((t :inherit magit-branch-remote))
+    '((t :inherit font-lock-variable-name-face)))
+  "Face used for names of remote branches in commit message comments.
+This is only used if Magit is available."
+  :group 'git-commit-faces)
+
+(defface git-commit-comment-detached
+  '((t :inherit git-commit-comment-branch-local))
+  "Face used for detached `HEAD' in commit message comments."
+  :group 'git-commit-faces)
+
+(defface git-commit-comment-heading
+  '((t :inherit git-commit-known-pseudo-header))
+  "Face used for headings in commit message comments."
+  :group 'git-commit-faces)
+
+(defface git-commit-comment-file
+  '((t :inherit git-commit-pseudo-header))
+  "Face used for file names in commit message comments."
+  :group 'git-commit-faces)
+
+(defface git-commit-comment-action
+  '((t :inherit bold))
+  "Face used for actions in commit message comments."
+  :group 'git-commit-faces)
+
+;;; Keymap
+
+(defvar git-commit-mode-map
+  (let ((map (make-sparse-keymap)))
+    (cond ((featurep 'jkl)
+           (define-key map (kbd "C-M-i") 'git-commit-prev-message)
+           (define-key map (kbd "C-M-k") 'git-commit-next-message))
+          (t
+           (define-key map (kbd "M-p") 'git-commit-prev-message)
+           (define-key map (kbd "M-n") 'git-commit-next-message)
+           ;; Old bindings to avoid confusion
+           (define-key map (kbd "C-c C-x a") 'git-commit-ack)
+           (define-key map (kbd "C-c C-x i") 'git-commit-suggested)
+           (define-key map (kbd "C-c C-x m") 'git-commit-modified)
+           (define-key map (kbd "C-c C-x o") 'git-commit-cc)
+           (define-key map (kbd "C-c C-x p") 'git-commit-reported)
+           (define-key map (kbd "C-c C-x r") 'git-commit-review)
+           (define-key map (kbd "C-c C-x s") 'git-commit-signoff)
+           (define-key map (kbd "C-c C-x t") 'git-commit-test)))
+    (define-key map (kbd "C-c C-a") 'git-commit-ack)
+    (define-key map (kbd "C-c C-i") 'git-commit-suggested)
+    (define-key map (kbd "C-c C-m") 'git-commit-modified)
+    (define-key map (kbd "C-c C-o") 'git-commit-cc)
+    (define-key map (kbd "C-c C-p") 'git-commit-reported)
+    (define-key map (kbd "C-c C-r") 'git-commit-review)
+    (define-key map (kbd "C-c C-s") 'git-commit-signoff)
+    (define-key map (kbd "C-c C-t") 'git-commit-test)
+    (define-key map (kbd "C-c M-s") 'git-commit-save-message)
+    map)
+  "Key map used by `git-commit-mode'.")
+
+;;; Menu
+
+(require 'easymenu)
+(easy-menu-define git-commit-mode-menu git-commit-mode-map
+  "Git Commit Mode Menu"
+  '("Commit"
+    ["Previous" git-commit-prev-message t]
+    ["Next" git-commit-next-message t]
+    "-"
+    ["Ack" git-commit-ack :active t
+     :help "Insert an 'Acked-by' header"]
+    ["Sign-Off" git-commit-signoff :active t
+     :help "Insert a 'Signed-off-by' header"]
+    ["Modified-by" git-commit-modified :active t
+     :help "Insert a 'Modified-by' header"]
+    ["Tested-by" git-commit-test :active t
+     :help "Insert a 'Tested-by' header"]
+    ["Reviewed-by" git-commit-review :active t
+     :help "Insert a 'Reviewed-by' header"]
+    ["CC" git-commit-cc t
+     :help "Insert a 'Cc' header"]
+    ["Reported" git-commit-reported :active t
+     :help "Insert a 'Reported-by' header"]
+    ["Suggested" git-commit-suggested t
+     :help "Insert a 'Suggested-by' header"]
+    "-"
+    ["Save" git-commit-save-message t]
+    ["Cancel" with-editor-cancel t]
+    ["Commit" with-editor-finish t]))
+
+;;; Hooks
+
+;;;###autoload
+(defconst git-commit-filename-regexp "/\\(\
+\\(\\(COMMIT\\|NOTES\\|PULLREQ\\|TAG\\)_EDIT\\|MERGE_\\|\\)MSG\
+\\|\\(BRANCH\\|EDIT\\)_DESCRIPTION\\)\\'")
+
+(eval-after-load 'recentf
+  '(add-to-list 'recentf-exclude git-commit-filename-regexp))
+
+(add-to-list 'with-editor-file-name-history-exclude git-commit-filename-regexp)
+
+(defun git-commit-setup-font-lock-in-buffer ()
+  (and buffer-file-name
+       (string-match-p git-commit-filename-regexp buffer-file-name)
+       (git-commit-setup-font-lock)))
+
+(add-hook 'after-change-major-mode-hook 'git-commit-setup-font-lock-in-buffer)
+
+;;;###autoload
+(defun git-commit-setup-check-buffer ()
+  (and buffer-file-name
+       (string-match-p git-commit-filename-regexp buffer-file-name)
+       (git-commit-setup)))
+
+(defvar git-commit-mode)
+
+;;;###autoload
+(defun git-commit-setup ()
+  ;; cygwin git will pass a cygwin path (/cygdrive/c/foo/.git/...),
+  ;; try to handle this in window-nt Emacs.
+  (--when-let
+      (and (eq system-type 'windows-nt)
+           (not (file-accessible-directory-p default-directory))
+           (if (require 'magit-git nil t)
+               ;; Emacs prepends a "c:".
+               (magit-expand-git-file-name (substring buffer-file-name 2))
+             ;; Fallback if we can't load `magit-git'.
+             (and (string-match "\\`[a-z]:/\\(cygdrive/\\)?\\([a-z]\\)/\\(.*\\)"
+                                buffer-file-name)
+                  (concat (match-string 2 buffer-file-name) ":/"
+                          (match-string 3 buffer-file-name)))))
+    (when (file-accessible-directory-p (file-name-directory it))
+      (find-alternate-file it)))
+  ;; Pretend that git-commit-mode is a major-mode,
+  ;; so that directory-local settings can be used.
+  (let ((default-directory
+          (if (file-exists-p ".dir-locals.el")
+              default-directory
+            ;; When $GIT_DIR/.dir-locals.el doesn't exist,
+            ;; fallback to $GIT_WORK_TREE/.dir-locals.el,
+            ;; because the maintainer can use the latter
+            ;; to enforce conventions, while s/he has no
+            ;; control over the former.
+            (magit-toplevel))))
+    (let ((buffer-file-name nil)         ; trick hack-dir-local-variables
+          (major-mode 'git-commit-mode)) ; trick dir-locals-collect-variables
+      (hack-dir-local-variables)
+      (hack-local-variables-apply)))
+  (when git-commit-major-mode
+    (let ((auto-mode-alist (list (cons (concat "\\`"
+                                               (regexp-quote buffer-file-name)
+                                               "\\'")
+                                       git-commit-major-mode)))
+          ;; The major-mode hook might want to consult these minor
+          ;; modes, while the minor-mode hooks might want to consider
+          ;; the major mode.
+          (git-commit-mode t)
+          (with-editor-mode t))
+      (normal-mode t)))
+  (setq with-editor-show-usage nil)
+  (unless with-editor-mode
+    ;; Maybe already enabled when using `shell-command' or an Emacs shell.
+    (with-editor-mode 1))
+  (add-hook 'with-editor-finish-query-functions
+            'git-commit-finish-query-functions nil t)
+  (add-hook 'with-editor-pre-finish-hook
+            'git-commit-save-message nil t)
+  (add-hook 'with-editor-pre-cancel-hook
+            'git-commit-save-message nil t)
+  (setq with-editor-cancel-message
+        'git-commit-cancel-message)
+  (make-local-variable 'log-edit-comment-ring-index)
+  (git-commit-mode 1)
+  (git-commit-setup-font-lock)
+  (when (boundp 'save-place)
+    (setq save-place nil))
+  (save-excursion
+    (goto-char (point-min))
+    (when (looking-at "\\`\\(\\'\\|\n[^\n]\\)")
+      (open-line 1)))
+  (run-hooks 'git-commit-setup-hook)
+  (set-buffer-modified-p nil))
+
+(define-minor-mode git-commit-mode
+  "Auxiliary minor mode used when editing Git commit messages.
+This mode is only responsible for setting up some key bindings.
+Don't use it directly, instead enable `global-git-commit-mode'."
+  :lighter "")
+
+(put 'git-commit-mode 'permanent-local t)
+
+(defun git-commit-setup-changelog-support ()
+  "Treat ChangeLog entries as paragraphs."
+  (setq-local paragraph-start (concat paragraph-start "\\|\\*\\|(")))
+
+(defun git-commit-turn-on-auto-fill ()
+  "Unconditionally turn on Auto Fill mode.
+If `git-commit-fill-column' is non-nil, and `fill-column'
+doesn't already have a buffer-local value, then set that
+to `git-commit-fill-column'."
+  (when (and (numberp git-commit-fill-column)
+             (not (local-variable-p 'fill-column)))
+    (setq fill-column git-commit-fill-column))
+  (setq-local comment-auto-fill-only-comments nil)
+  (turn-on-auto-fill))
+
+(defun git-commit-turn-on-flyspell ()
+  "Unconditionally turn on Flyspell mode.
+Also prevent comments from being checked and
+finally check current non-comment text."
+  (require 'flyspell)
+  (turn-on-flyspell)
+  (setq flyspell-generic-check-word-predicate
+        'git-commit-flyspell-verify)
+  (let ((end)
+        (comment-start-regex (format "^\\(%s\\|$\\)" comment-start)))
+    (save-excursion
+      (goto-char (point-max))
+      (while (and (not (bobp)) (looking-at comment-start-regex))
+        (forward-line -1))
+      (unless (looking-at comment-start-regex)
+        (forward-line))
+      (setq end (point)))
+    (flyspell-region (point-min) end)))
+
+(defun git-commit-flyspell-verify ()
+  (not (= (char-after (line-beginning-position))
+          (aref comment-start 0))))
+
+(defun git-commit-finish-query-functions (force)
+  (run-hook-with-args-until-failure
+   'git-commit-finish-query-functions force))
+
+(defun git-commit-check-style-conventions (force)
+  "Check for violations of certain basic style conventions.
+
+For each violation ask the user if she wants to proceed anyway.
+Option `git-commit-check-style-conventions' controls which
+conventions are checked."
+  (or force
+      (save-excursion
+        (goto-char (point-min))
+        (re-search-forward (git-commit-summary-regexp) nil t)
+        (if (equal (match-string 1) "")
+            t ; Just try; we don't know whether --allow-empty-message was used.
+          (and (or (not (memq 'overlong-summary-line
+                              git-commit-style-convention-checks))
+                   (equal (match-string 2) "")
+                   (y-or-n-p "Summary line is too long.  Commit anyway? "))
+               (or (not (memq 'non-empty-second-line
+                              git-commit-style-convention-checks))
+                   (not (match-string 3))
+                   (y-or-n-p "Second line is not empty.  Commit anyway? ")))))))
+
+(defun git-commit-cancel-message ()
+  (message
+   (concat "Commit canceled"
+           (and (memq 'git-commit-save-message with-editor-pre-cancel-hook)
+                ".  Message saved to `log-edit-comment-ring'"))))
+
+;;; History
+
+(defun git-commit-prev-message (arg)
+  "Cycle backward through message history, after saving current message.
+With a numeric prefix ARG, go back ARG comments."
+  (interactive "*p")
+  (when (and (git-commit-save-message) (> arg 0))
+    (setq log-edit-comment-ring-index
+          (log-edit-new-comment-index
+           arg (ring-length log-edit-comment-ring))))
+  (save-restriction
+    (goto-char (point-min))
+    (narrow-to-region (point)
+                      (if (re-search-forward (concat "^" comment-start) nil t)
+                          (max 1 (- (point) 2))
+                        (point-max)))
+    (log-edit-previous-comment arg)))
+
+(defun git-commit-next-message (arg)
+  "Cycle forward through message history, after saving current message.
+With a numeric prefix ARG, go forward ARG comments."
+  (interactive "*p")
+  (git-commit-prev-message (- arg)))
+
+(defun git-commit-save-message ()
+  "Save current message to `log-edit-comment-ring'."
+  (interactive)
+  (--when-let (git-commit-buffer-message)
+    (unless (ring-member log-edit-comment-ring it)
+      (ring-insert log-edit-comment-ring it))))
+
+(defun git-commit-buffer-message ()
+  (let ((flush (concat "^" comment-start))
+        (str (buffer-substring-no-properties (point-min) (point-max))))
+    (with-temp-buffer
+      (insert str)
+      (goto-char (point-min))
+      (when (re-search-forward (concat flush " -+ >8 -+$") nil t)
+        (delete-region (point-at-bol) (point-max)))
+      (goto-char (point-min))
+      (flush-lines flush)
+      (goto-char (point-max))
+      (unless (eq (char-before) ?\n)
+        (insert ?\n))
+      (setq str (buffer-string)))
+    (unless (string-match "\\`[ \t\n\r]*\\'" str)
+      (when (string-match "\\`\n\\{2,\\}" str)
+        (setq str (replace-match "\n" t t str)))
+      (when (string-match "\n\\{2,\\}\\'" str)
+        (setq str (replace-match "\n" t t str)))
+      str)))
+
+;;; Headers
+
+(defun git-commit-ack (name mail)
+  "Insert a header acknowledging that you have looked at the commit."
+  (interactive (git-commit-self-ident))
+  (git-commit-insert-header "Acked-by" name mail))
+
+(defun git-commit-modified (name mail)
+  "Insert a header to signal that you have modified the commit."
+  (interactive (git-commit-self-ident))
+  (git-commit-insert-header "Modified-by" name mail))
+
+(defun git-commit-review (name mail)
+  "Insert a header acknowledging that you have reviewed the commit."
+  (interactive (git-commit-self-ident))
+  (git-commit-insert-header "Reviewed-by" name mail))
+
+(defun git-commit-signoff (name mail)
+  "Insert a header to sign off the commit."
+  (interactive (git-commit-self-ident))
+  (git-commit-insert-header "Signed-off-by" name mail))
+
+(defun git-commit-test (name mail)
+  "Insert a header acknowledging that you have tested the commit."
+  (interactive (git-commit-self-ident))
+  (git-commit-insert-header "Tested-by" name mail))
+
+(defun git-commit-cc (name mail)
+  "Insert a header mentioning someone who might be interested."
+  (interactive (git-commit-read-ident))
+  (git-commit-insert-header "Cc" name mail))
+
+(defun git-commit-reported (name mail)
+  "Insert a header mentioning the person who reported the issue."
+  (interactive (git-commit-read-ident))
+  (git-commit-insert-header "Reported-by" name mail))
+
+(defun git-commit-suggested (name mail)
+  "Insert a header mentioning the person who suggested the change."
+  (interactive (git-commit-read-ident))
+  (git-commit-insert-header "Suggested-by" name mail))
+
+(defun git-commit-self-ident ()
+  (list (or (getenv "GIT_AUTHOR_NAME")
+            (getenv "GIT_COMMITTER_NAME")
+            (ignore-errors (car (process-lines "git" "config" "user.name")))
+            user-full-name
+            (read-string "Name: "))
+        (or (getenv "GIT_AUTHOR_EMAIL")
+            (getenv "GIT_COMMITTER_EMAIL")
+            (getenv "EMAIL")
+            (ignore-errors (car (process-lines "git" "config" "user.email")))
+            (read-string "Email: "))))
+
+(defun git-commit-read-ident ()
+  (list (read-string "Name: ")
+        (read-string "Email: ")))
+
+(defun git-commit-insert-header (header name email)
+  (setq header (format "%s: %s <%s>" header name email))
+  (save-excursion
+    (goto-char (point-max))
+    (cond ((re-search-backward "^[-a-zA-Z]+: [^<]+? <[^>]+>" nil t)
+           (end-of-line)
+           (insert ?\n header)
+           (unless (= (char-after) ?\n)
+             (insert ?\n)))
+          (t
+           (while (re-search-backward (concat "^" comment-start) nil t))
+           (unless (looking-back "\n\n" nil)
+             (insert ?\n))
+           (insert header ?\n)))
+    (unless (or (eobp) (= (char-after) ?\n))
+      (insert ?\n))))
+
+;;; Font-Lock
+
+(defun git-commit-summary-regexp ()
+  (concat
+   ;; Leading empty lines and comments
+   (format "\\`\\(?:^\\(?:\\s-*\\|%s.*\\)\n\\)*" comment-start)
+   ;; Summary line
+   (format "\\(.\\{0,%d\\}\\)\\(.*\\)" git-commit-summary-max-length)
+   ;; Non-empty non-comment second line
+   (format "\\(?:\n%s\\|\n\\(.+\\)\\)?" comment-start)))
+
+(defun git-commit-extend-region-summary-line ()
+  "Identify the multiline summary-regexp construct.
+Added to `font-lock-extend-region-functions'."
+  (save-excursion
+    (save-match-data
+      (goto-char (point-min))
+      (when (looking-at (git-commit-summary-regexp))
+        (let ((summary-beg (match-beginning 0))
+              (summary-end (match-end 0)))
+          (when (or (< summary-beg font-lock-beg summary-end)
+                    (< summary-beg font-lock-end summary-end))
+            (setq font-lock-beg (min font-lock-beg summary-beg))
+            (setq font-lock-end (max font-lock-end summary-end))))))))
+
+(defvar-local git-commit--branch-name-regexp nil)
+
+(defconst git-commit-comment-headings
+  '("Changes to be committed:"
+    "Untracked files:"
+    "Changed but not updated:"
+    "Changes not staged for commit:"
+    "Unmerged paths:"
+    "Author:"
+    "Date:"))
+
+(defconst git-commit-font-lock-keywords-1
+  '(;; Pseudo headers
+    (eval . `(,(format "^\\(%s:\\)\\( .*\\)"
+                       (regexp-opt git-commit-known-pseudo-headers))
+              (1 'git-commit-known-pseudo-header)
+              (2 'git-commit-pseudo-header)))
+    ("^[-a-zA-Z]+: [^<]+? <[^>]+>"
+     (0 'git-commit-pseudo-header))
+    ;; Summary
+    (eval . `(,(git-commit-summary-regexp)
+              (1 'git-commit-summary)))
+    ;; - Note (overrides summary)
+    ("\\[.+?\\]"
+     (0 'git-commit-note t))
+    ;; - Non-empty second line (overrides summary and note)
+    (eval . `(,(git-commit-summary-regexp)
+              (2 'git-commit-overlong-summary t t)
+              (3 'git-commit-nonempty-second-line t t)))))
+
+(defconst git-commit-font-lock-keywords-2
+  `(,@git-commit-font-lock-keywords-1
+    ;; Comments
+    (eval . `(,(format "^%s.*" comment-start)
+              (0 'font-lock-comment-face)))
+    (eval . `(,(format "^%s On branch \\(.*\\)" comment-start)
+              (1 'git-commit-comment-branch-local t)))
+    (eval . `(,(format "^%s \\(HEAD\\) detached at" comment-start)
+              (1 'git-commit-comment-detached t)))
+    (eval . `(,(format "^%s %s" comment-start
+                       (regexp-opt git-commit-comment-headings t))
+              (1 'git-commit-comment-heading t)))
+    (eval . `(,(format "^%s\t\\(?:\\([^:\n]+\\):\\s-+\\)?\\(.*\\)" comment-start)
+              (1 'git-commit-comment-action t t)
+              (2 'git-commit-comment-file t)))))
+
+(defconst git-commit-font-lock-keywords-3
+  `(,@git-commit-font-lock-keywords-2
+    ;; More comments
+    (eval
+     ;; Your branch is ahead of 'master' by 3 commits.
+     ;; Your branch is behind 'master' by 2 commits, and can be fast-forwarded.
+     . `(,(format
+           "^%s Your branch is \\(?:ahead\\|behind\\) of '%s' by \\([0-9]*\\)"
+           comment-start git-commit--branch-name-regexp)
+         (1 'git-commit-comment-branch-local t)
+         (2 'git-commit-comment-branch-remote t)
+         (3 'bold t)))
+    (eval
+     ;; Your branch is up to date with 'master'.
+     ;; Your branch and 'master' have diverged,
+     . `(,(format
+           "^%s Your branch \\(?:is up-to-date with\\|and\\) '%s'"
+           comment-start git-commit--branch-name-regexp)
+         (1 'git-commit-comment-branch-local t)
+         (2 'git-commit-comment-branch-remote t)))
+    (eval
+     ;; and have 1 and 2 different commits each, respectively.
+     . `(,(format
+           "^%s and have \\([0-9]*\\) and \\([0-9]*\\) commits each"
+           comment-start)
+         (1 'bold t)
+         (2 'bold t)))))
+
+(defvar git-commit-font-lock-keywords git-commit-font-lock-keywords-2
+  "Font-Lock keywords for Git-Commit mode.")
+
+(defun git-commit-setup-font-lock ()
+  (let ((table (make-syntax-table (syntax-table))))
+    (when comment-start
+      (modify-syntax-entry (string-to-char comment-start) "." table))
+    (modify-syntax-entry ?#  "." table)
+    (modify-syntax-entry ?\" "." table)
+    (modify-syntax-entry ?\' "." table)
+    (modify-syntax-entry ?`  "." table)
+    (set-syntax-table table))
+  (setq-local comment-start
+              (or (ignore-errors
+                    (car (process-lines "git" "config" "core.commentchar")))
+                  "#"))
+  (setq-local comment-start-skip (format "^%s+[\s\t]*" comment-start))
+  (setq-local comment-end-skip "\n")
+  (setq-local comment-use-syntax nil)
+  (setq-local git-commit--branch-name-regexp
+              (if (featurep 'magit-git)
+                  (progn
+                    ;; Make sure the below functions are available.
+                    (require 'magit)
+                    ;; Font-Lock wants every submatch to succeed,
+                    ;; so also match the empty string.  Do not use
+                    ;; `regexp-quote' because that is slow if there
+                    ;; are thousands of branches outweighing the
+                    ;; benefit of an efficient regep.
+                    (format "\\(\\(?:%s\\)\\|\\)\\(\\(?:%s\\)\\|\\)"
+                            (mapconcat #'identity
+                                       (magit-list-local-branch-names)
+                                       "\\|")
+                            (mapconcat #'identity
+                                       (magit-list-remote-branch-names)
+                                       "\\|")))
+                "\\([^']*\\)"))
+  (setq-local font-lock-multiline t)
+  (add-hook 'font-lock-extend-region-functions
+            #'git-commit-extend-region-summary-line
+            t t)
+  (font-lock-add-keywords nil git-commit-font-lock-keywords t))
+
+(defun git-commit-propertize-diff ()
+  (require 'diff-mode)
+  (save-excursion
+    (goto-char (point-min))
+    (when (re-search-forward "^diff --git" nil t)
+      (beginning-of-line)
+      (let ((buffer (current-buffer)))
+        (insert
+         (with-temp-buffer
+           (insert
+            (with-current-buffer buffer
+              (prog1 (buffer-substring-no-properties (point) (point-max))
+                (delete-region (point) (point-max)))))
+           (let ((diff-default-read-only nil))
+             (diff-mode))
+           (let (font-lock-verbose font-lock-support-mode)
+             (if (fboundp 'font-lock-ensure)
+                 (font-lock-ensure)
+               (with-no-warnings
+                 (font-lock-fontify-buffer))))
+           (let (next (pos (point-min)))
+             (while (setq next (next-single-property-change pos 'face))
+               (put-text-property pos next 'font-lock-face
+                                  (get-text-property pos 'face))
+               (setq pos next))
+             (put-text-property pos (point-max) 'font-lock-face
+                                (get-text-property pos 'face)))
+           (buffer-string)))))))
+
+;;; Elisp Text Mode
+
+(define-derived-mode git-commit-elisp-text-mode text-mode "ElText"
+  "Major mode for editing commit messages of elisp projects.
+This is intended for use as `git-commit-major-mode' for projects
+that expect `symbols' to look like this.  I.e. like they look in
+Elisp doc-strings, including this one.  Unlike in doc-strings,
+\"strings\" also look different than the other text."
+  (setq font-lock-defaults '(git-commit-elisp-text-mode-keywords)))
+
+(defvar git-commit-elisp-text-mode-keywords
+  `((,(concat "[`‘]\\(\\(?:\\sw\\|\\s_\\|\\\\.\\)"
+              lisp-mode-symbol-regexp "\\)['’]")
+     (1 font-lock-constant-face prepend))
+    ("\"[^\"]*\"" (0 font-lock-string-face prepend))))
+
+;;; _
+(provide 'git-commit)
+;;; git-commit.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/git-commit-20180713.1444/git-commit.elc b/configs/shared/emacs/.emacs.d/elpa/git-commit-20180713.1444/git-commit.elc
new file mode 100644
index 0000000000..0fd927cd9b
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/git-commit-20180713.1444/git-commit.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/git-timemachine-20180607.120/git-timemachine-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/git-timemachine-20180607.120/git-timemachine-autoloads.el
new file mode 100644
index 0000000000..e295833b6b
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/git-timemachine-20180607.120/git-timemachine-autoloads.el
@@ -0,0 +1,32 @@
+;;; git-timemachine-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "git-timemachine" "git-timemachine.el" (23377
+;;;;;;  61605 587341 154000))
+;;; Generated autoloads from git-timemachine.el
+
+(autoload 'git-timemachine-toggle "git-timemachine" "\
+Toggle git timemachine mode.
+
+\(fn)" t nil)
+
+(autoload 'git-timemachine "git-timemachine" "\
+Enable git timemachine for file of current buffer.
+
+\(fn)" t nil)
+
+(autoload 'git-timemachine-switch-branch "git-timemachine" "\
+Enable git timemachine for current buffer, switching to GIT-BRANCH.
+
+\(fn GIT-BRANCH)" t nil)
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; git-timemachine-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/git-timemachine-20180607.120/git-timemachine-pkg.el b/configs/shared/emacs/.emacs.d/elpa/git-timemachine-20180607.120/git-timemachine-pkg.el
new file mode 100644
index 0000000000..981bb8b0a7
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/git-timemachine-20180607.120/git-timemachine-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "git-timemachine" "20180607.120" "Walk through git revisions of a file" '((emacs "24.3")))
diff --git a/configs/shared/emacs/.emacs.d/elpa/git-timemachine-20180607.120/git-timemachine.el b/configs/shared/emacs/.emacs.d/elpa/git-timemachine-20180607.120/git-timemachine.el
new file mode 100644
index 0000000000..9cbd09a64d
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/git-timemachine-20180607.120/git-timemachine.el
@@ -0,0 +1,395 @@
+;;; git-timemachine.el --- Walk through git revisions of a file
+
+;; Copyright (C) 2014 Peter Stiernström
+
+;; Author: Peter Stiernström <peter@stiernstrom.se>
+;; Version: 4.6
+;; Package-Version: 20180607.120
+;; URL: https://github.com/pidu/git-timemachine
+;; Keywords: git
+;; Package-Requires: ((emacs "24.3"))
+
+;; This file is not part of GNU Emacs
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;; Use git-timemachine to browse historic versions of a file with p
+;;; (previous) and n (next).
+
+;;; Code:
+
+(require 'vc-git)
+(require 'cl-lib)
+
+(defcustom git-timemachine-abbreviation-length 12
+ "Number of chars from the full sha1 hash to use for abbreviation."
+ :type 'integer
+ :group 'git-timemachine)
+
+(defcustom git-timemachine-show-minibuffer-details t
+ "Non-nil means that details of the commit (its hash and date)
+will be shown in the minibuffer while navigating commits."
+ :type 'boolean
+ :group 'git-timemachine)
+
+(defface git-timemachine-commit
+ '((default :weight bold))
+ "Face for git timemachine commit sha"
+ :group 'git-timemachine)
+
+(defface git-timemachine-minibuffer-detail-face
+  '((((class color) (background dark))
+     :foreground "yellow")
+    (((class color) (background light))
+     :foreground "yellow4"))
+  "How to display the minibuffer detail"
+  :group 'git-timemachine)
+
+(defface git-timemachine-minibuffer-author-face
+  '((((class color) (background dark))
+     :foreground "orange")
+    (((class color) (background light))
+     :foreground "DarkOrange4"))
+  "How to display the author in minibuffer"
+  :group 'git-timemachine)
+
+(defcustom git-timemachine-minibuffer-detail
+ 'subject
+ "What to display when `git-timemachine-show-minibuffer-details` is t.
+Available values are:
+`commit` : The SHA hash of the commit
+`subject`: The subject of the commit message"
+ :type '(radio (const :tag "Commit SHA" commit) (const :tag "Commit Subject" subject))
+ :group 'git-timemachine)
+
+(defcustom git-timemachine-show-author
+ t
+ "Prepend author to minibuffer details."
+ :type 'boolean
+ :group 'git-timemachine)
+
+(defcustom git-timemachine-global-git-arguments
+ '("-c" "log.showSignature=false" "--no-pager")
+ "Common arguments for all git commands."
+ :type 'list
+ :group 'git-timemachine)
+
+(defvar-local git-timemachine-directory nil)
+(defvar-local git-timemachine-revision nil)
+(defvar-local git-timemachine-file nil)
+(defvar-local git-timemachine--revisions-cache nil)
+
+(defun git-timemachine-completing-read-fn (&rest args)
+ "Apply ARGS to `ido-completing-read' if available and fall back to `completing-read'."
+ (cond
+  ((fboundp 'ivy-read) (apply 'ivy-read args))
+  ((fboundp 'ido-completing-read) (apply 'ido-completing-read args))
+  (t (apply 'completing-read args))))
+
+(defun git-timemachine--process-file (&rest args)
+ "Run ‘process-file’ with ARGS and ‘git-timemachine-global-git-arguments’ applied."
+ (apply #'process-file vc-git-program nil t nil (append git-timemachine-global-git-arguments args)))
+
+(defun git-timemachine--revisions (&optional git-branch)
+ "List git revisions of current buffers file.
+
+When passed a GIT-BRANCH, lists revisions from that branch."
+ (if git-timemachine--revisions-cache
+  git-timemachine--revisions-cache
+  (setq git-timemachine--revisions-cache
+   (prog2
+    (message "Fetching Revisions...")
+    (let ((default-directory git-timemachine-directory)
+          (file git-timemachine-file))
+     (with-temp-buffer
+
+      (unless (zerop (if git-branch
+                      (git-timemachine--process-file "log" git-branch "--name-only" "--follow" "--pretty=format:%H%x00%ar%x00%ad%x00%s%x00%an" "--" file)
+                      (git-timemachine--process-file "log" "--name-only" "--follow" "--pretty=format:%H%x00%ar%x00%ad%x00%s%x00%an" "--" file)))
+       (error "Git log command exited with non-zero exit status for file: %s" file))
+
+      (goto-char (point-min))
+      (let ((lines)
+            (commit-number (/ (1+ (count-lines (point-min) (point-max))) 3)))
+       (while (not (eobp))
+        (let ((line (buffer-substring-no-properties (line-beginning-position) (line-end-position))))
+         (string-match "\\([^\0]*\\)\0\\([^\0]*\\)\0\\([^\0]*\\)\0\\(.*\\)\0\\(.*\\)" line)
+         (let ((commit (match-string 1 line))
+               (date-relative (match-string 2 line))
+               (date-full (match-string 3 line))
+               (subject (match-string 4 line))
+               (author (match-string 5 line)))
+          (forward-line 1)
+          (let ((file-name (buffer-substring-no-properties (line-beginning-position) (line-end-position))))
+           (push (list commit file-name commit-number date-relative date-full subject author) lines))))
+        (setq commit-number (1- commit-number))
+        (forward-line 2))
+       (nreverse lines))))
+    (message "Fetching Revisions...done")))))
+
+(defun git-timemachine-show-current-revision ()
+ "Show last (current) revision of file."
+ (interactive)
+ (git-timemachine-show-revision (car (git-timemachine--revisions))))
+
+(defun git-timemachine-show-latest-revision-in-branch (git-branch)
+ "Show last (current) revision of file in GIT-BRANCH."
+ (interactive "MGit branch: ")
+ (git-timemachine-show-revision (car (git-timemachine--revisions git-branch))))
+
+(defun git-timemachine--next-revision (revisions)
+ "Return the revision following the current revision in REVISIONS."
+ (or (cadr (cl-member (car git-timemachine-revision) revisions :key #'car :test #'string=))
+  (car (reverse revisions))))
+
+(defun git-timemachine-show-previous-revision ()
+ "Show previous revision of file."
+ (interactive)
+ (let ((new-line nil)
+       (curr-revision git-timemachine-revision)
+       (new-revision (git-timemachine--next-revision (git-timemachine--revisions)))
+       (cursor-win-pos (git-timemachine--get-cursor-position)))
+   (setq new-line (git-timemachine--find-new-current-line curr-revision new-revision (line-number-at-pos)))
+   (git-timemachine-show-revision new-revision)
+   (forward-line (- new-line (line-number-at-pos)))
+   (git-timemachine--set-cursor-position cursor-win-pos)))
+
+(defun git-timemachine-show-next-revision ()
+ "Show next revision of file."
+ (interactive)
+ (let ((new-line nil)
+       (curr-revision git-timemachine-revision)
+       (new-revision (git-timemachine--next-revision (reverse (git-timemachine--revisions))))
+       (cursor-win-pos (git-timemachine--get-cursor-position)))
+  (setq new-line (git-timemachine--find-new-current-line curr-revision new-revision (line-number-at-pos)))
+  (git-timemachine-show-revision new-revision)
+  (forward-line (- new-line (line-number-at-pos)))
+  (git-timemachine--set-cursor-position cursor-win-pos)))
+
+(defun git-timemachine-show-revision-fuzzy ()
+ "Show the revision with the chosen commit message."
+  (interactive)
+ (let* ((revisions (git-timemachine--revisions))
+        (wanted
+         (funcall #'git-timemachine-completing-read-fn "Commit message: "
+          (mapcar (apply-partially #'nth 5) revisions))))
+  (git-timemachine-show-revision
+   (cl-find wanted revisions
+    :key (apply-partially #'nth 5)
+    :test #'equal))))
+
+(defun git-timemachine-show-nth-revision (rev-number)
+ "Show the REV-NUMBER revision."
+ (interactive "nEnter revision number: ")
+ (let* ((revisions (reverse (git-timemachine--revisions)))
+	(num-revisions (length revisions))
+	(curr-revision git-timemachine-revision)
+	(new-revision (nth (1- rev-number) revisions))
+	(new-line nil)
+	(cursor-win-pos (git-timemachine--get-cursor-position)))
+   (if (not new-revision)
+       (message "Only %d revisions exist." num-revisions)
+     (setq new-line (git-timemachine--find-new-current-line curr-revision new-revision (line-number-at-pos)))
+     (git-timemachine-show-revision new-revision)
+     (forward-line (- new-line (line-number-at-pos)))
+     (git-timemachine--set-cursor-position cursor-win-pos))))
+
+(defun git-timemachine-show-revision (revision)
+ "Show a REVISION (commit hash) of the current file."
+ (when revision
+  (let ((current-position (point))
+        (commit (car revision))
+        (revision-file-name (nth 1 revision))
+        (commit-index (nth 2 revision))
+        (date-relative (nth 3 revision))
+        (date-full (nth 4 revision))
+        (subject (nth 5 revision)))
+   (setq buffer-read-only nil)
+   (erase-buffer)
+   (let ((default-directory git-timemachine-directory)
+         (process-coding-system-alist (list (cons "" (cons buffer-file-coding-system default-process-coding-system)))))
+    (git-timemachine--process-file "show" (concat commit ":" revision-file-name)))
+   (setq buffer-read-only t)
+   (set-buffer-modified-p nil)
+   (let* ((revisions (git-timemachine--revisions))
+          (n-of-m (format "(%d/%d %s)" commit-index (length revisions) date-relative)))
+    (setq mode-line-buffer-identification
+     (list (propertized-buffer-identification "%12b") "@"
+      (propertize (git-timemachine-abbreviate commit) 'face 'git-timemachine-commit) " name:" revision-file-name" " n-of-m)))
+   (setq git-timemachine-revision revision)
+   (goto-char current-position)
+   (when git-timemachine-show-minibuffer-details
+    (git-timemachine--show-minibuffer-details revision)))))
+
+(defun git-timemachine--show-minibuffer-details (revision)
+ "Show details for REVISION in minibuffer."
+ (let* ((date-relative (nth 3 revision))
+        (date-full (nth 4 revision))
+        (author (if git-timemachine-show-author (concat (nth 6 revision) ": ") ""))
+        (sha-or-subject (if (eq git-timemachine-minibuffer-detail 'commit) (car revision) (nth 5 revision))))
+  (message "%s%s [%s (%s)]"
+   (propertize author 'face 'git-timemachine-minibuffer-author-face)
+   (propertize sha-or-subject 'face 'git-timemachine-minibuffer-detail-face) date-full date-relative)))
+
+(defun git-timemachine--find-new-current-line (curr-revision new-revision current-line)
+  "Return the new current line after a revision jump."
+  (let* ((revisions (reverse (git-timemachine--revisions)))
+	 (current-commit (car curr-revision))
+	 (curr-rev-number (+ (or (cl-position curr-revision revisions) 0) 1))
+	 (new-commit (car new-revision))
+	 (new-rev-number (+ (or (cl-position new-revision revisions) 0) 1))
+	 (new-line nil)
+	 (file git-timemachine-file)
+	 (reverse (< curr-rev-number new-rev-number)))
+    ;; If no commit change, do nothing
+    (if (= curr-rev-number new-rev-number)
+	current-line
+      ;; Get new current line number using `git-blame`
+      (with-temp-buffer
+	(if reverse
+	    (git-timemachine--process-file "blame" "--reverse" "-n" (format "-L %s,%s" current-line current-line) file (format "%s..%s" current-commit new-commit))
+	  (git-timemachine--process-file "blame" "-n" (format "-L %s,%s" current-line current-line) file (format "%s..%s" new-commit current-commit)))
+	(goto-char (point-min))
+	;; If end-of-buffer problem
+	(when (search-forward-regexp "^fatal: file .+ has only .+ lines" nil t)
+	  (setq current-line (- current-line 1))
+	  (erase-buffer)
+	  (if reverse
+	      (git-timemachine--process-file "blame" "--reverse" "-n" (format "-L %s,%s" current-line current-line) file (format "%s..%s" current-commit new-commit))
+	    (git-timemachine--process-file "blame" "-n" (format "-L %s,%s" current-line current-line) file (format "%s..%s" new-commit current-commit))))
+	(goto-char (point-min))
+	(search-forward-regexp "^[^ ]+ \\([^ ]+\\)")
+	(setq new-line (string-to-number (match-string 1)))
+	;; In case git blame doesn't give what we expect
+	(when (= new-line 0) (setq new-line current-line))
+	new-line))))
+
+(defun git-timemachine--get-cursor-position ()
+  "Return the cursor visual line number with respect to the
+current window first line"
+  (let* ((win-point-min (save-excursion (move-to-window-line 0) (point)))
+	 (cur-pos (count-screen-lines win-point-min (point))))
+    cur-pos))
+
+(defun git-timemachine--set-cursor-position (POS)
+  "Set the cursor position to the POS visual line with
+respect to the window first line"
+  (recenter POS))
+
+(defun git-timemachine-abbreviate (revision)
+ "Return REVISION abbreviated to `git-timemachine-abbreviation-length' chars."
+ (substring revision 0 git-timemachine-abbreviation-length))
+
+(defun git-timemachine-quit ()
+ "Exit the timemachine."
+ (interactive)
+ (kill-buffer))
+
+(defun git-timemachine-blame ()
+ "Call magit-blame on current revision."
+ (interactive)
+ (if (fboundp 'magit-blame)
+  (let ((magit-buffer-revision (car git-timemachine-revision)))
+   (magit-blame))
+  (message "You need to install magit for blame capabilities")))
+
+(defun git-timemachine-kill-revision ()
+ "Kill the current revisions abbreviated commit hash."
+ (interactive)
+ (let ((revision (car git-timemachine-revision)))
+  (message revision)
+  (kill-new revision)))
+
+(defun git-timemachine-kill-abbreviated-revision ()
+ "Kill the current revisions full commit hash."
+ (interactive)
+ (let ((revision (git-timemachine-abbreviate (car git-timemachine-revision))))
+  (message revision)
+  (kill-new revision)))
+
+(define-minor-mode git-timemachine-mode
+ "Git Timemachine, feel the wings of history."
+ :init-value nil
+ :lighter " Timemachine"
+ :keymap
+ '(("p" . git-timemachine-show-previous-revision)
+   ("n" . git-timemachine-show-next-revision)
+   ("g" . git-timemachine-show-nth-revision)
+   ("t" . git-timemachine-show-revision-fuzzy)
+   ("q" . git-timemachine-quit)
+   ("w" . git-timemachine-kill-abbreviated-revision)
+   ("W" . git-timemachine-kill-revision)
+   ("b" . git-timemachine-blame))
+ :group 'git-timemachine)
+
+(defun git-timemachine-validate (file)
+ "Validate that there is a FILE and that it belongs to a git repository.
+Call with the value of 'buffer-file-name."
+ (unless file
+  (error "This buffer is not visiting a file"))
+ (unless (vc-git-registered file)
+  (error "This file is not git tracked")))
+
+(defun git-timemachine--start (get-revision-fn)
+ "Setup a timemachine buffer and populate it from the result of GET-REVISION-FN."
+ (setq git-timemachine--revisions-cache nil)
+ (git-timemachine-validate (buffer-file-name))
+ (let ((git-directory (expand-file-name (vc-git-root (buffer-file-name))))
+       (file-name (buffer-file-name))
+       (timemachine-buffer (format "timemachine:%s" (buffer-name)))
+       (cur-line (line-number-at-pos))
+       (cursor-position (git-timemachine--get-cursor-position))
+       (new-line nil)
+       (mode major-mode)
+       (coding-system buffer-file-coding-system))
+  (with-current-buffer (get-buffer-create timemachine-buffer)
+   (switch-to-buffer timemachine-buffer)
+   (setq buffer-file-name file-name)
+   (setq buffer-file-coding-system coding-system)
+   (funcall mode)
+   (setq git-timemachine-directory git-directory
+         git-timemachine-file (file-relative-name file-name git-directory)
+    git-timemachine-revision nil)
+   (funcall get-revision-fn)
+   (setq new-line (git-timemachine--find-new-current-line git-timemachine-revision (list "HEAD" "" 0 "" "" "" "") cur-line)) ;; Allow to stay on the same line
+   (goto-char (point-min))
+   (forward-line (- new-line 1))
+   (git-timemachine--set-cursor-position cursor-position)
+   (git-timemachine-mode))))
+
+;;;###autoload
+(defun git-timemachine-toggle ()
+ "Toggle git timemachine mode."
+ (interactive)
+ (if (bound-and-true-p git-timemachine-mode)
+  (git-timemachine-quit)
+  (git-timemachine)))
+
+;;;###autoload
+(defun git-timemachine ()
+ "Enable git timemachine for file of current buffer."
+ (interactive)
+ (git-timemachine--start #'git-timemachine-show-current-revision))
+
+;;;###autoload
+(defun git-timemachine-switch-branch (git-branch)
+ "Enable git timemachine for current buffer, switching to GIT-BRANCH."
+ (interactive (list (git-timemachine-completing-read-fn "Branch to switch to: "(vc-git-branches))))
+ (git-timemachine--start (lambda () (git-timemachine-show-latest-revision-in-branch git-branch))))
+
+(provide 'git-timemachine)
+
+;;; git-timemachine.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/git-timemachine-20180607.120/git-timemachine.elc b/configs/shared/emacs/.emacs.d/elpa/git-timemachine-20180607.120/git-timemachine.elc
new file mode 100644
index 0000000000..6810ac4639
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/git-timemachine-20180607.120/git-timemachine.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/gntp-20141024.1950/gntp-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/gntp-20141024.1950/gntp-autoloads.el
new file mode 100644
index 0000000000..84537dd3f9
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/gntp-20141024.1950/gntp-autoloads.el
@@ -0,0 +1,22 @@
+;;; gntp-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "gntp" "gntp.el" (23377 61297 558143 423000))
+;;; Generated autoloads from gntp.el
+
+(autoload 'gntp-notify "gntp" "\
+Send notification NAME with TITLE, TEXT, PRIORITY and ICON to SERVER:PORT.
+PORT defaults to `gntp-server-port'
+
+\(fn NAME TITLE TEXT SERVER &optional PORT PRIORITY ICON)" nil nil)
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; gntp-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/gntp-20141024.1950/gntp-pkg.el b/configs/shared/emacs/.emacs.d/elpa/gntp-20141024.1950/gntp-pkg.el
new file mode 100644
index 0000000000..513673c0bd
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/gntp-20141024.1950/gntp-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "gntp" "20141024.1950" "Growl Notification Protocol for Emacs" 'nil)
diff --git a/configs/shared/emacs/.emacs.d/elpa/gntp-20141024.1950/gntp.el b/configs/shared/emacs/.emacs.d/elpa/gntp-20141024.1950/gntp.el
new file mode 100644
index 0000000000..c7af09ffb5
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/gntp-20141024.1950/gntp.el
@@ -0,0 +1,243 @@
+;;; gntp.el --- Growl Notification Protocol for Emacs -*- lexical-binding: t -*-
+
+;; Author: Engelke Eschner <tekai@gmx.li>
+;; Version: 0.1
+;; Package-Version: 20141024.1950
+;; Created: 2013-03-21
+
+;; LICENSE
+;; Copyright (c) 2013 Engelke Eschner
+;; All rights reserved.
+
+;; Redistribution and use in source and binary forms, with or without
+;; modification, are permitted provided that the following conditions
+;; are met:
+;;     * Redistributions of source code must retain the above copyright
+;;       notice, this list of conditions and the following disclaimer.
+;;     * Redistributions in binary form must reproduce the above
+;;       copyright notice, this list of conditions and the following
+;;       disclaimer in the documentation and/or other materials provided
+;;       with the distribution.
+;;     * Neither the name of the gntp.el nor the names of its
+;;       contributors may be used to endorse or promote products derived
+;;       from this software without specific prior written permission.
+
+;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+;; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+;; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+;; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT
+;; HOLDER> BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+;; EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+;; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+;; PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+;; OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+;; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+;; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+;;; Commentary:
+;; This package implements the Growl Notification Protocol GNTP
+;; described at http://www.growlforwindows.com/gfw/help/gntp.aspx
+;; It is incomplete as it only lets you send but not receive
+;; notifications.
+
+;;; Code:
+
+(defgroup gntp nil
+  "GNTP, send/register growl notifications via GNTP from within emacs."
+  :group 'external)
+
+(defcustom gntp-application-name "Emacs/gntp.el"
+  "Name of the application gntp registers itself."
+  :type '(string))
+
+(defcustom gntp-application-icon nil
+  "Icon to display as the application icon.
+Either a URL or a path to a file."
+  :type '(string))
+
+(defcustom gntp-server "localhost"
+  "Default port of the server.
+Standard says can't be changed, but port-forwarding etc."
+  :type '(string))
+
+(defcustom gntp-server-port 23053
+  "Default port of the server.
+Standard says can't be changed, but port-forwarding etc."
+  :type '(integer))
+
+(defcustom gntp-register-alist nil
+  "Registration item list."
+  :type '(choice string (const nil)))
+
+(defun gntp-register (&optional notifications server  port)
+  (interactive)
+  "Register NOTIFICATIONS at SERVER:PORT.
+PORT defaults to `gntp-server-port'."
+  (let ((message (gntp-build-message-register (if notifications notifications gntp-register-alist))))
+    (gntp-send message (if server server gntp-server) port)))
+
+;;;###autoload
+(defun gntp-notify (name title text server &optional port priority icon)
+  "Send notification NAME with TITLE, TEXT, PRIORITY and ICON to SERVER:PORT.
+PORT defaults to `gntp-server-port'"
+  (let ((message (gntp-build-message-notify name title text priority icon)))
+    (gntp-send message server port)))
+
+(defun gntp-build-message-register (notifications)
+  "Build the message to register NOTIFICATIONS types."
+  (let ((lines (list "GNTP/1.0 REGISTER NONE"
+                     (format "Application-Name: %s"
+                             gntp-application-name)
+                     (format "Notifications-Count: %d"
+                             (length notifications))))
+        (icon-uri (gntp-app-icon-uri))
+        (icon-data (gntp-app-icon-data))
+        (icons (list)))
+
+    ;; append icon uri
+    (when icon-uri
+      (nconc lines (list (format "Application-Icon: %s" icon-uri)))
+      ;; and data when it exists
+      (when icon-data
+        (setq icons (cons icon-data icons))))
+
+    (dolist (notice notifications)
+      ;; "For each notification being registered:
+      ;; Each notification being registered should be seperated by a
+      ;; blank line, including the first notification
+      (nconc lines (cons "" (gntp-notification-lines notice)))
+      ;; c
+      (let ((icon (gntp-notice-icon-data notice)))
+        (when icon
+          (nconc icons (list "" icon)))))
+
+    ;; icon data must come last
+    (when icons
+      (nconc lines (cons "" icons)))
+
+    (mapconcat 'identity (remove nil lines) "\r\n")))
+
+(defun gntp-notification-lines (notice)
+  "Transform NOTICE into a list of strings."
+  (let ((display-name (gntp-notice-get notice :display))
+        (enabled (gntp-notice-get notice :enabled))
+        (icon-uri (gntp-notice-icon-uri notice)))
+  (list
+   ;; Required - The name (type) of the notification being registered
+   (concat "Notification-Name: " (gntp-notice-name notice))
+   ;; Optional - The name of the notification that is displayed to
+   ;; the user (defaults to the same value as Notification-Name)
+   (when display-name
+     (concat "Notification-Display-Name: " display-name))
+   ;; Optional - Indicates if the notification should be enabled by
+   ;; default (defaults to False)
+   (when enabled
+     "Notification-Enabled: True")
+   ;; Optional - The default icon to use for notifications of this type
+   (when icon-uri
+     (concat "Notification-Icon: " icon-uri)))))
+
+(defun gntp-build-message-notify (name title text &optional priority icon)
+  "Build a message of type NAME with TITLE and TEXT."
+
+  (format
+   "GNTP/1.0 NOTIFY NONE\r\n\
+Application-Name: %s\r\n\
+Notification-Name: %s\r\n\
+Notification-Title: %s\r\n\
+Notification-Text: %s\r\n\
+Notification-Priority: %s\r\n\
+Notification-Icon: %s\r\n\
+\r\n"
+          gntp-application-name
+          (if (symbolp name) (symbol-name name) name)
+          title
+          ;; no CRLF in the text to avoid accidentel msg end
+          (replace-regexp-in-string "\r\n" "\n" text)
+          (if priority priority "0")
+          (if icon (gntp-icon-uri icon) "")))
+
+;; notice
+;;(list name ; everthing else is optional
+;;      :display "name to display"
+;;      :enabled nil
+;;      :icon "url or file")
+
+
+(defun gntp-notice-icon-uri (notice)
+  "Get the icon URI from NOTICE."
+  (gntp-icon-uri (gntp-notice-get notice :icon)))
+
+(defun gntp-notice-icon-data (notice)
+  "Get icon data from NOTICE."
+  (gntp-icon-data (gntp-notice-get notice :icon)))
+
+(defun gntp-app-icon-uri ()
+  "Return the value to be used in the Application-Icon header."
+  (gntp-icon-uri gntp-application-icon))
+
+(defun gntp-app-icon-data ()
+  "Return the value to be used in the Application-Icon header."
+  (gntp-icon-data gntp-application-icon))
+
+(defun gntp-icon-uri (icon)
+  "Get the URI of ICON."
+  (when icon
+    (cond ((string-equal (substring icon 0 7) "http://") icon)
+          ((and (file-exists-p icon) (file-readable-p icon))
+           (concat "x-growl-resource://" (md5 icon))))))
+
+(defun gntp-icon-data (icon)
+  "Get the URI of ICON."
+  (when (and icon (not (string-equal (substring icon 0 7) "http://"))
+             (file-exists-p icon) (file-readable-p icon))
+    (let ((id (md5 icon))
+          (data (gntp-file-string icon)))
+      (format "Identifier: %s\r\nLength: %d\r\n\r\n%s"
+              id (length data) data))))
+
+(defun gntp-notice-name (notice)
+  "Get the name of NOTICE.  The name must be either a symbol or string."
+  (let ((name (car notice)))
+    (if (symbolp name)
+        (symbol-name name)
+      name)))
+
+(defun gntp-notice-get (notice property)
+  "Get PROPERTY from NOTICE."
+  (plist-get (cdr notice) property))
+
+(defun gntp-send (message server &optional port)
+  "Send MESSAGE to SERVER:PORT.  PORT defaults to `gntp-server-port'."
+  (let ((proc (make-network-process
+               :name "gntp"
+               :host server
+               :server nil
+               :service (if port port gntp-server-port)
+               ;;:sentinel 'gntp-sentinel
+               :filter 'gntp-filter)))
+    ;; hmm one CRLF too much?
+    (process-send-string proc (concat message "\r\n\r\n\r\n"))))
+
+(defun gntp-filter (proc string)
+  "Filter for PROC started by `gntp-send'.
+Argument STRING reply from the server."
+  (when (string-equal "GNTP/1.0 -ERROR" (substring string 0 15))
+    (error "GNTP: Something went wrong take a look at the reply:\n %s"
+           string)))
+
+;; (defun gntp-sentinel (proc msg)
+;;   (when (string= msg "connection broken by remote peer\n")
+;;     (message (format "client %s has quit" proc))))
+
+
+(defun gntp-file-string (file)
+  "Read the contents of a FILE and return as a string."
+  (with-temp-buffer
+    (insert-file-contents-literally file)
+    (buffer-string)))
+
+(provide 'gntp)
+
+;;; gntp.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/gntp-20141024.1950/gntp.elc b/configs/shared/emacs/.emacs.d/elpa/gntp-20141024.1950/gntp.elc
new file mode 100644
index 0000000000..11e462b137
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/gntp-20141024.1950/gntp.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/gnupg/pubring.kbx b/configs/shared/emacs/.emacs.d/elpa/gnupg/pubring.kbx
new file mode 100644
index 0000000000..8f78b01c83
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/gnupg/pubring.kbx
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/gnupg/pubring.kbx~ b/configs/shared/emacs/.emacs.d/elpa/gnupg/pubring.kbx~
new file mode 100644
index 0000000000..d1bb3e9648
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/gnupg/pubring.kbx~
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/gnupg/trustdb.gpg b/configs/shared/emacs/.emacs.d/elpa/gnupg/trustdb.gpg
new file mode 100644
index 0000000000..9db3f9b0bb
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/gnupg/trustdb.gpg
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/goto-chg-20180105.1033/goto-chg-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/goto-chg-20180105.1033/goto-chg-autoloads.el
new file mode 100644
index 0000000000..a98de81281
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/goto-chg-20180105.1033/goto-chg-autoloads.el
@@ -0,0 +1,50 @@
+;;; goto-chg-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "goto-chg" "goto-chg.el" (23377 61205 249354
+;;;;;;  959000))
+;;; Generated autoloads from goto-chg.el
+
+(autoload 'goto-last-change "goto-chg" "\
+Go to the point where the last edit was made in the current buffer.
+Repeat the command to go to the second last edit, etc.
+
+To go back to more recent edit, the reverse of this command, use \\[goto-last-change-reverse]
+or precede this command with \\[universal-argument] - (minus).
+
+It does not go to the same point twice even if there has been many edits
+there. I call the minimal distance between distinguishable edits \"span\".
+Set variable `glc-default-span' to control how close is \"the same point\".
+Default span is 8.
+The span can be changed temporarily with \\[universal-argument] right before \\[goto-last-change]:
+\\[universal-argument] <NUMBER> set current span to that number,
+\\[universal-argument] (no number) multiplies span by 4, starting with default.
+The so set span remains until it is changed again with \\[universal-argument], or the consecutive
+repetition of this command is ended by any other command.
+
+When span is zero (i.e. \\[universal-argument] 0) subsequent \\[goto-last-change] visits each and
+every point of edit and a message shows what change was made there.
+In this case it may go to the same point twice.
+
+This command uses undo information. If undo is disabled, so is this command.
+At times, when undo information becomes too large, the oldest information is
+discarded. See variable `undo-limit'.
+
+\(fn ARG)" t nil)
+
+(autoload 'goto-last-change-reverse "goto-chg" "\
+Go back to more recent changes after \\[goto-last-change] have been used.
+See `goto-last-change' for use of prefix argument.
+
+\(fn ARG)" t nil)
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; goto-chg-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/goto-chg-20180105.1033/goto-chg-pkg.el b/configs/shared/emacs/.emacs.d/elpa/goto-chg-20180105.1033/goto-chg-pkg.el
new file mode 100644
index 0000000000..7161c28ece
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/goto-chg-20180105.1033/goto-chg-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "goto-chg" "20180105.1033" "goto last change" 'nil)
diff --git a/configs/shared/emacs/.emacs.d/elpa/goto-chg-20180105.1033/goto-chg.el b/configs/shared/emacs/.emacs.d/elpa/goto-chg-20180105.1033/goto-chg.el
new file mode 100644
index 0000000000..19bf24fe67
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/goto-chg-20180105.1033/goto-chg.el
@@ -0,0 +1,360 @@
+;;; goto-chg.el --- goto last change
+;;--------------------------------------------------------------------
+;;
+;; Copyright (C) 2002-2008,2013 David Andersson
+;;
+;; This program 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 2 of
+;; the License, or (at your option) any later version.
+;;
+;; This program 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 this program; if not, write to the Free
+;; Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+;; MA 02111-1307 USA
+;;
+;;-------------------------------------------------------------------
+;;
+;; Author: David Andersson <l.david.andersson(at)sverige.nu>
+;; Maintainer: Vasilij Schneidermann <v.schneidermann@github.com>
+;; Created: 16 May 2002
+;; Version: 1.7.2
+;; Package-Version: 20180105.1033
+;; Keywords: convenience, matching
+;; URL: https://github.com/emacs-evil/goto-chg
+;;
+;;; Commentary:
+;;
+;; Goto Last Change
+;;
+;; Goto the point of the most recent edit in the buffer.
+;; When repeated, goto the second most recent edit, etc.
+;; Negative argument, C-u -, for reverse direction.
+;; Works by looking into buffer-undo-list to find points of edit.
+;;
+;; You would probably like to bind this command to a key.
+;; For example in your ~/.emacs:
+;;
+;;   (require 'goto-chg)
+;;
+;;   (global-set-key [(control ?.)] 'goto-last-change)
+;;   (global-set-key [(control ?,)] 'goto-last-change-reverse)
+;;
+;; Works with emacs-19.29, 19.31, 20.3, 20.7, 21.1, 21.4, 22.1 and 23.1
+;; Works with XEmacs-20.4 and 21.4 (but see todo about `last-command' below)
+;;
+;;--------------------------------------------------------------------
+;; History
+;;
+;; Ver 1.7.2 2018-01-05 Vasilij Schneidermann
+;;    Fix byte-compiler warnings again
+;; Ver 1.7.1 2017-12-31 Vasilij Schneidermann
+;;    Fix byte-compiler warnings
+;; Ver 1.7 2017-09-17 Vasilij Schneidermann
+;;    Make it work with undo-tree-mode (see
+;;    <https://github.com/martinp26/goto-chg>)
+;; Ver 1.6 2013-12-12 David Andersson
+;;    Add keywords; Cleanup comments
+;; Ver 1.5 2013-12-11 David Andersson
+;;    Autoload and document `goto-last-change-reverse'
+;; Ver 1.4 2008-09-20 David Andersson
+;;    Improved property change description; Update comments.
+;; Ver 1.3 2007-03-14 David Andersson
+;;    Added `goto-last-change-reverse'
+;; Ver 1.2 2003-04-06 David Andersson
+;;    Don't let repeating error depthen glc-probe-depth.
+;; Ver 1.1 2003-04-06 David Andersson
+;;    Zero arg describe changes. Negative arg go back.
+;;    Autoload. Remove message using nil in stead of an empty string.
+;; Ver 1.0 2002-05-18 David Andersson
+;;    Initial version
+;;
+;;--------------------------------------------------------------------
+;;
+;;todo: Rename "goto-chg.el" -> "gotochange.el" or "goto-chgs" ?
+;;todo: Rename function goto-last-change -> goto-last-edit ?
+;;todo: Rename adjective "-last-" -> "-latest-" or "-most-recent-" ?
+;;todo: There are some, maybe useful, funcs  for region undo
+;;       in simple.el in emacs 20. Take a look.
+;;todo: Add functionality to visit changed point in text order, not only in
+;;        chronological order. (Naa, highlight-changes-mode does that).
+;;todo: Inverse indication that a change has been saved or not
+;;todo: Highlight the range of text involved in the last change?
+;;todo: See session-jump-to-last-change in session.el?
+;;todo: Unhide invisible text (e.g. outline mode) like isearch do.
+;;todo: XEmacs sets last-command to `t' after an error, so you cannot reverse
+;;        after "No furter change info". Should we bother?
+;;todo: Try distinguish "No further change info" (end of truncated undo list)
+;;        and "No further changes" (end of a complete undo list).
+;;
+;;--------------------------------------------------------------------
+
+;;; Code:
+
+(defvar glc-default-span 8 "*goto-last-change don't visit the same point twice. glc-default-span tells how far around a visited point not to visit again.")
+(defvar glc-current-span 8 "Internal for goto-last-change.\nA copy of glc-default-span or the ARG passed to goto-last-change.")
+(defvar glc-probe-depth 0 "Internal for goto-last-change.\nIt is non-zero between successive goto-last-change.")
+(defvar glc-direction 1 "Direction goto-last-change moves towards.")
+
+;;todo: Find begin and end of line, then use it somewhere
+
+(defun glc-center-ellipsis (str maxlen &optional ellipsis)
+  "Truncate STRING in the middle to length MAXLEN.
+If STRING is max MAXLEN just return the string.
+Optional third argument is the replacement, which defaults to \"...\"."
+  (if (<= (length str) maxlen)
+      str
+    ;; else
+    (let* ((lipsis (or ellipsis "..."))
+           (i (/ (- maxlen (length lipsis)) 2)))
+      (concat (substring str 0 i)
+              lipsis
+              (substring str (- i))))))
+
+(defun glc-adjust-pos2 (pos p1 p2 adj)
+  ;; Helper function to glc-adjust-pos
+  ;; p1, p2: interval where an edit occured
+  ;; adj: amount of text added (positive) or removed (negativ) by the edit
+  ;; Return pos if well before p1, or pos+adj if well after p2, or nil if too close
+  (cond ((<= pos (- p1 glc-current-span))
+         pos)
+        ((> pos (+ p2 glc-current-span))
+         (+ pos adj))
+        ((zerop glc-current-span)
+         p1)
+        (t
+         nil)))
+
+(defun glc-adjust-pos (pos e)
+  "Given POS, a buffer position before the edit E, compute and return
+the \"same\" buffer position after E happened.
+Exception: return nil if POS is closer than `glc-current-span' to the edit E.
+\nInsertion edits before POS returns a larger value.
+Deletion edits before POS returns a smaller value.
+\nThe edit E is an entry from the `buffer-undo-list'. See for details."
+  (cond ((atom e)                       ; nil==cmd boundary, or, num==changed pos
+         pos)
+        ((numberp (car e))              ; (beg . end)==insertion
+         (glc-adjust-pos2 pos (car e) (car e) (- (cdr e) (car e))))
+        ((stringp (car e))              ; (string . pos)==deletion
+         (glc-adjust-pos2 pos (abs (cdr e)) (+ (abs (cdr e)) (length (car e))) (- (length (car e)))))
+        ((null (car e))                 ; (nil prop val beg . end)==prop change
+         (glc-adjust-pos2 pos (nth 3 e) (nthcdr 4 e) 0))
+        (t                              ; (marker . dist)==marker moved
+         pos)))
+
+;; If recursive in stead of iterative (while), it tends to fill the call stack.
+;; (Isn't it tail optimized?)
+(defun glc-adjust-list (r)
+  "R is list of edit entries in chronological order.
+Pick the point of the first edit entry and update that point with
+the second, third, etc, edit entries. Return the final updated point,
+or nil if the point was closer than `glc-current-span' to some edit in R.
+\nR is basically a reversed slice from the buffer-undo-list."
+  (if r
+      ;; Get pos
+      (let ((pos (glc-get-pos (car r))))
+        (setq r (cdr r))
+        ;; Walk back in reverse list
+        (while (and r pos)
+          (setq pos (glc-adjust-pos pos (car r))
+                r (cdr r)))
+        pos)
+    ;; else
+    nil))
+
+(defun glc-get-pos (e)
+  "If E represents an edit, return a position value in E, the position
+where the edit took place. Return nil if E represents no real change.
+\nE is an entry in the buffer-undo-list."
+  (cond ((numberp e) e)                 ; num==changed position
+        ((atom e) nil)                  ; nil==command boundary
+        ((numberp (car e)) (cdr e))     ; (beg . end)==insertion
+        ((stringp (car e)) (abs (cdr e))) ; (string . pos)==deletion
+        ((null (car e)) (nthcdr 4 e))   ; (nil ...)==text property change
+        ((atom (car e)) nil)            ; (t ...)==file modification time
+        (t nil)))                       ; (marker ...)==marker moved
+
+(defun glc-get-descript (e &optional n)
+  "If E represents an edit, return a short string describing E.
+Return nil if E represents no real change.
+\nE is an entry in the buffer-undo-list."
+  (let ((nn (or (format "T-%d: " n) "")))
+    (cond ((numberp e) "New position")  ; num==changed position
+          ((atom e) nil)                ; nil==command boundary
+          ((numberp (car e))            ; (beg . end)==insertion
+           (if (and n (< n 2))
+               (format "%sInserted %d chars \"%s\"" nn (- (cdr e) (car e))
+                       (glc-center-ellipsis (buffer-substring (car e) (cdr e)) 60))
+             ;; else
+             ;; An older insert. The inserted text cannot easily be computed.
+             ;; Just show the char count.
+             (format "%sInserted %d chars" nn (- (cdr e) (car e)))))
+          ((stringp (car e))            ; (string . pos)==deletion
+           (format "%sDeleted \"%s\"" nn (glc-center-ellipsis (car e) 60)))
+          ((null (car e))               ; (nil ...)==text property change
+           (format "%sProperty change" nn))
+          ((atom (car e)) nil)          ; (t ...)==file modification time
+          (t nil))))                    ; (marker ...)==marker moved
+
+(defun glc-is-positionable (e)
+  "Return non-nil if E is an insertion, deletion or text property change.
+\nE is an entry in the buffer-undo-list."
+  (and (not (numberp e)) (glc-get-pos e)))
+
+(defun glc-is-filetime (e)
+  "Return t if E indicates a buffer became \"modified\",
+that is, it was previously saved or unchanged. Nil otherwise."
+  (and (listp e) (eq (car e) t)))
+
+(defvar buffer-undo-tree)
+(declare-function undo-tree-current "undo-tree.el")
+(declare-function undo-tree-node-undo "undo-tree.el")
+(declare-function undo-tree-node-previous "undo-tree.el")
+
+;;;###autoload
+(defun goto-last-change (arg)
+"Go to the point where the last edit was made in the current buffer.
+Repeat the command to go to the second last edit, etc.
+\nTo go back to more recent edit, the reverse of this command, use \\[goto-last-change-reverse]
+or precede this command with \\[universal-argument] - (minus).
+\nIt does not go to the same point twice even if there has been many edits
+there. I call the minimal distance between distinguishable edits \"span\".
+Set variable `glc-default-span' to control how close is \"the same point\".
+Default span is 8.
+The span can be changed temporarily with \\[universal-argument] right before \\[goto-last-change]:
+\\[universal-argument] <NUMBER> set current span to that number,
+\\[universal-argument] (no number) multiplies span by 4, starting with default.
+The so set span remains until it is changed again with \\[universal-argument], or the consecutive
+repetition of this command is ended by any other command.
+\nWhen span is zero (i.e. \\[universal-argument] 0) subsequent \\[goto-last-change] visits each and
+every point of edit and a message shows what change was made there.
+In this case it may go to the same point twice.
+\nThis command uses undo information. If undo is disabled, so is this command.
+At times, when undo information becomes too large, the oldest information is
+discarded. See variable `undo-limit'."
+  (interactive "P")
+  (cond ((not (eq this-command last-command))
+         ;; Start a glc sequence
+         ;; Don't go to current point if last command was an obvious edit
+         ;; (yank or self-insert, but not kill-region). Makes it easier to
+         ;; jump back and forth when copying seleced lines.
+         (setq glc-probe-depth (if (memq last-command '(yank self-insert-command)) 1 0)
+               glc-direction 1
+               glc-current-span glc-default-span)
+         (if (< (prefix-numeric-value arg) 0)
+             (error "Negative arg: Cannot reverse as the first operation"))))
+  (cond ((null buffer-undo-list)
+         (error "Buffer has not been changed"))
+        ((eq buffer-undo-list t)
+         (error "No change info (undo is disabled)")))
+  (cond ((numberp arg)                  ; Numeric arg sets span
+         (setq glc-current-span (abs arg)))
+        ((consp arg)                    ; C-u's multiply previous span by 4
+         (setq glc-current-span (* (abs (car arg)) glc-default-span))
+         (message "Current span is %d chars" glc-current-span))) ;todo: keep message with "waiting" and "is saved"
+  (cond ((< (prefix-numeric-value arg) 0)
+         (setq glc-direction -1))
+        (t
+         (setq glc-direction 1)))
+  (let (rev                             ; Reversed (and filtered) undo list
+        pos                             ; The pos we look for, nil until found
+        (n 0)                           ; Steps in undo list (length of 'rev')
+        (l buffer-undo-list)
+        (passed-save-entry (not (buffer-modified-p)))
+        (new-probe-depth glc-probe-depth)
+        (undo-tree-p (bound-and-true-p undo-tree-mode))
+        glc-seen-canary)
+    ;; Walk back and forth in the buffer-undo-list, each time one step deeper,
+    ;; until we can walk back the whole list with a 'pos' that is not coming
+    ;; too close to another edit.
+    (while (null pos)
+      (setq new-probe-depth (+ new-probe-depth glc-direction))
+      (if (< glc-direction 0)
+          (setq rev ()
+                n 0
+                l buffer-undo-list
+                passed-save-entry (not (buffer-modified-p))))
+      (if (< new-probe-depth 1)
+          (error "No later change info"))
+      (if (> n 150)
+          (message "working..."))
+      ;; Walk forward in buffer-undo-list, glc-probe-depth steps.
+      ;; Build reverse list along the way
+      (if (not undo-tree-p)
+          (while (< n new-probe-depth)
+            (cond ((null l)
+                   ;(setq this-command t)   ; Disrupt repeat sequence
+                   (error "No further change info"))
+                  ((glc-is-positionable (car l))
+                   (setq n (1+ n)
+                         rev (cons (car l) rev)))
+                  ((or passed-save-entry (glc-is-filetime (car l)))
+                   (setq passed-save-entry t)))
+            (setq l (cdr l)))
+        (when (not glc-seen-canary)
+          (while (and (not (null l)) (not glc-seen-canary) (< n new-probe-depth))
+            (cond ((eq 'undo-tree-canary (car l))  ; used by buffer-undo-tree
+                   (message "Canary found...")
+                   (setq l (undo-tree-current buffer-undo-tree)
+                         glc-seen-canary t))
+                  ((glc-is-positionable (car l))
+                   (setq n (1+ n)
+                         rev (cons (car l) rev)))
+                  ((or passed-save-entry (glc-is-filetime (car l)))
+                   (setq passed-save-entry t)))
+            (when (not glc-seen-canary)
+              (setq l (cdr l)))))
+        (when glc-seen-canary
+          (while (< n new-probe-depth)
+            (cond ((null l)
+                   ;(setq this-command t)	; Disrupt repeat sequence
+                   (error "No further change info"))
+                  ((glc-is-positionable (car (undo-tree-node-undo l)))
+                   (setq n (1+ n)
+                         rev (cons (car (undo-tree-node-undo l)) rev)))
+                  ((or passed-save-entry (glc-is-filetime (car (undo-tree-node-undo l))))
+                   (setq passed-save-entry t)))
+            (setq l (undo-tree-node-previous l))))
+        (when (null l)
+          (error "No further change info")))
+      ;; Walk back in reverse list, from older to newer edits.
+      ;; Adjusting pos along the way.
+      (setq pos (glc-adjust-list rev)))
+    ;; Found a place not previously visited, in 'pos'.
+    ;; (An error have been issued if nothing (more) found.)
+    (if (> n 150)
+        (message nil))                  ; remove message "working..."
+    (if (and (= glc-current-span 0) (glc-get-descript (car rev) n))
+        (message "%s" (glc-get-descript (car rev) n))
+      ;; else
+      (if passed-save-entry
+          (message "(This change is saved)")))
+    (setq glc-probe-depth new-probe-depth)
+    (goto-char pos)))
+
+;;;###autoload
+(defun goto-last-change-reverse (arg)
+  "Go back to more recent changes after \\[goto-last-change] have been used.
+See `goto-last-change' for use of prefix argument."
+  (interactive "P")
+  ;; Negate arg, all kinds
+  (cond ((eq arg nil)  (setq arg '-))
+        ((eq arg '-)   (setq arg nil))
+        ((listp arg)   (setq arg (list (- (car arg)))))
+        (t (setq arg   (- arg))))
+  ;; Make 'goto-last-change-reverse' look like 'goto-last-change'
+  (cond ((eq last-command this-command)
+         (setq last-command 'goto-last-change)))
+  (setq this-command 'goto-last-change)
+  ;; Call 'goto-last-change' to do the job
+  (goto-last-change arg))
+
+(provide 'goto-chg)
+
+;;; goto-chg.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/goto-chg-20180105.1033/goto-chg.elc b/configs/shared/emacs/.emacs.d/elpa/goto-chg-20180105.1033/goto-chg.elc
new file mode 100644
index 0000000000..9b2524214f
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/goto-chg-20180105.1033/goto-chg.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/NEWS b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/NEWS
new file mode 100644
index 0000000000..e4d1a99400
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/NEWS
@@ -0,0 +1,600 @@
+Haskell Mode NEWS                                -*- org -*-
+
+This file uses Org mode. Some useful (default) key-bindings:
+ - Use "C-c C-n"/"C-c C-p" to jump to next/prev heading
+ - Use "<tab>" to expand/collapse nodes
+ - Use "<backtab>" to cycle visibility of all nodes
+ - Use "C-c C-o" to open links
+
+* Changes in 16.1
+
+- Require at least Emacs 24.3
+
+- Implemented standalone deriving indentation
+
+- Removed haskell-indentation-ifte-offset
+
+- Implemented electric characters
+
+- Added LiquidHaskell annotation highlight
+
+- Introduced haskell-hasktags-path defcustom
+
+- Added font lock tests for pattern synonyms
+
+- Hardcoded haskell-ghc-supported-extensions/options
+
+- Added multi-line input in haskell-interactive
+
+- Added haskell-mode-stylish-haskell-path
+
+- Added Windows CI builds
+
+- Added syntax highlight to Yesod rules quasi quote
+
+- Added support for line continuation in #define's
+
+- Added support unterminated strings in indentation
+
+- Implemented /italic/ and *bold* for haddock
+
+- Added significant speedups in font-lock engine
+
+- Added support for full complexity of backtick syntax
+
+- Operators at the end or beggining of line force expression continuation in indentation
+
+- Map haskell-mode-format-imports to C-c C-, to avoid conflict with haskell-indent
+
+- Improve auto add dependencies in cabal
+
+- Fix inferior-haskell warning font lock for GHC 8.0
+
+* Changes in 13.20
+
+- Require at least Emacs 24.1
+
+- Honor equals on its own line in data decl
+
+- Honor equals on separate line after guards
+
+- Allow haskell-process-path-* to be lists
+
+- Fontify True/False in cabal mode
+
+- Align | with = in data declarations
+
+- Remove haskell-package.el
+
+- Run stylish-haskell before save
+
+- Improved lexeme parsing in haskell-lexeme
+
+- Add haskell-interactive-copy-to-prompt
+
+- Remove haskell-mode-contextual-space and related var
+
+- Make haskell-indent-region do nothing
+
+- Add c2hs mode
+
+- Improve hasktags handling
+
+- Move documentation from wiki to haskell-mode manual
+
+* Changes in 13.18
+
+- Removed haskell-bot
+
+- Implement shallow indentation
+
+- Removed haskell-simple-indent
+
+- Removed haskell-indentation show dynamic positions
+
+- Improved indentation inside multiline strings
+
+- Implemented font-lock for quasi quoted XML, HTML and JavaScript
+
+- Added '{type|data} family' to font-lock-keywords-create
+
+- Started using undercover.el for emacs lisp coverage
+
+- Added keybinding for `haskell-cabal-visit-file`
+
+- Added type role to font lock
+
+- Detect and respect the comma style of a section in cabal files
+
+* Changes in 13.16
+
+- Improved parsing of comma lists in haskell indentation
+
+- Declared turn-on-haskell-indentation as obsolete
+
+- Improved QuasiQuote font lock
+
+- Fixed indentation for Unicode symbols
+
+- Improved completion engine
+
+- Added support for interaction with stack ghci
+
+- Added haskell-forward-sexp
+
+- Added overlays to haskell load
+
+- Made use of lexical binding for all emacs lisp sources
+
+- Improved indentation of guards with commas
+
+- Made three indentation modes mutually turn each other off
+
+- Added an additional trigger for pragma suggestions
+
+- Improved and documented `toggle-scc-at-point` in manual
+
+* Changes in 13.14
+
+- Add official Haskell Mode logo
+
+- Add auto deploy for html manual
+
+- Improve presentation mode
+
+- Font Lock refactoring and improvements
+
+- Properly delimit operators in prettify mode
+
+- OPTIONS and LANGUAGE completion using ghci
+
+- Merge hi2 (haskell-indentation attempt 2) in place of haskell-indentation
+
+- Prompt to reconfigure when Cabal demands it
+
+- Fontify pragmas while fontifying comments
+
+- Operators are fontified
+
+- Remove all mentions of cabal-dev
+
+- Merge hsc-mode into haskell-mode
+
+- Get type information from ghci in interaction-mode
+
+- Prettify Haskell types in eldoc support
+
+- Added haskell-hoogle-url
+
+- Fix w3m-haddock in the case of no local files
+
+* Changes in 13.12
+
+- Added haskell-bot.el
+
+- Added support for cabal repl build targets
+
+- Automatically add import lines via Hoogle
+
+- Automatically add package to cabal file
+
+- Added w3m-haddock.el
+
+- Added debugger mode
+
+- Added preliminary :present support
+
+- Added haskell-sort-imports
+
+- Added haskell-complete-module
+
+- Support if and multi-way if in indentation
+
+- Add support to generate tags on windows
+
+- Add haskell-language-extensions variable
+
+- Improve haskell-simple-indent mode
+
+- Improve test cases
+
+* Changes in 13.10
+
+- Small fix for haskell-simple-indent: Certain indentation situations
+  cause valname-string to be nil, which haskell-trim did not handle
+  gracefully (naturally, since nil != "").
+
+- Luke Hoersten's Shnippet merged in under snippets/.
+
+- haskell-presentation-mode is now a haskell-mode derived mode.
+
+- Small improvement to haskell-process-do-info (works on constructors
+  now and underscored names).
+
+- Add haskell-indent-spaces configuration variable.
+
+- The command string to run cabal commands is slightly more
+  configurable. See: C-h f haskell-process-do-cabal-format-string
+
+* Changes in 13.8
+
+See also [[https://github.com/haskell/haskell-mode/compare/v13.07...v13.08][detailed Git history]].
+
+- Make `haskell-simple-indent-mode' a proper minor mode with `SInd` as
+  mode-line lighter
+
+- Support popular "λ> " prompt in inf-haskell by default
+
+- Hide internal `*print-haskell-mode*' buffers
+  (used when `haskell-interactive-mode-eval-mode' is active)
+
+- Add tab-completion support for haskell-interactive-mode
+  (requires `:complete' command support in GHCi)
+
+- Add support to `haskell-process-do-info` to perform `:browse!` query
+  on module name when called on import statement line
+
+- `haskell-decl-scan-mode':
+  - New customize group `haskell-decl-scan'
+  - New flag `haskell-decl-scan-bindings-as-variables' for controlling
+    whether to put value bindings into the "Variables" category.
+  - New flag `haskell-decl-scan-add-to-menubar' for controlling
+    whether to add "Declarations" menu entry to menu bar.
+  - New manual section node `(haskell-mode)haskell-decl-scan-mode'
+
+- Add support for [[http://www.haskell.org/ghc/docs/latest/html/users_guide/syntax-extns.html#lambda-case][LambdaCase]] syntax extension to `haskell-indentation`
+
+- Change `haskell-indentation-mode' to never jump back a whole line
+  when pressing DEL.  The old behavior can be restored by setting
+  `haskell-indentation-delete-backward-jump-line' to t
+
+- New convenience function `haskell-cabal-visit-file' for locating and
+  visiting most likely `.cabal` file associated with current buffer
+
+- Add support for [[http://www.haskell.org/ghc/docs/latest/html/users_guide/syntax-extns.html#package-import][PackageImports]] and [[http://www.haskell.org/ghc/docs/latest/html/users_guide/syntax-extns.html#safe-imports-ext][SafeHaskell]] syntax extensions to
+  `haskell-decl-scan-mode' parser
+
+- Add `turn-{on,off}-haskell-doc' commands as aliases for the existing
+  `turn-{on,off}-haskell-doc-mode' commands
+
+- Add support for "cabal repl" process type to `haskell-interactive-mode'
+
+- Add new Haskell compilation sub-mode and associated `haskell-compile'
+  command
+
+* Changes in 13.7
+
+See also [[https://github.com/haskell/haskell-mode/compare/v13.06...v13.07][detailed Git history]].
+
+- Convert NEWS (this file) to Org mode style and include NEWS file in
+  package and add command for visiting NEWS file
+  (M-x haskell-mode-view-news)
+
+- Officially drop support for versions prior to Emacs 23
+
+- New work-in-progress Info manual for haskell-mode
+
+- Remove deprecated `haskell-{hugs,ghci}' modules
+
+- Font-locking changes:
+  - Remove deprecated `turn-on-haskell-font-lock` function
+  - Improve font-locking of type-signatures in presence of newlines
+  - Use `font-lock-preprocessor-face' instead of the previously used
+    `font-lock-warning-face` for CPP directives
+  - Use `font-lock-warning-face` instead  of the previously used
+    `font-lock-preprocessor-face` for Git merge conflict annotations.
+
+- Improvements to `haskell-move-nested' module:
+  - Add support for operating on active regions
+  - New interactive commands `haskell-move-nested-{left,right}` which
+    support numeric prefix arguments for controlling the amount of
+    shifting to apply.
+
+- Add `haskell-unicode-input-method.el` to distribution
+  (enable with `turn-on-haskell-unicode-input-method`)
+
+- Fix all byte-compilation warnings
+
+- Build-system:
+  - For in-place installation, `haskell-site-file.el' is renamed
+    to `haskell-mode-autoloads.el`
+  - Auto-generate ELPA compatible README file by extracting header of
+    haskell-mode.el
+  - New "make check" target
+  - Add Travis-CI build jobs for testing byte-compilation with
+    multiple Emacs versions
+
+- Reorganize customize settings
+  - Add new convenience function for browsing all Haskell Mode settings
+    (M-x haskell-customize)
+  - Add `:link' keywords pointing to the new Info manual
+  - Add `:group' keywords to modes to make (M-x customize-mode) work
+  - Create new customization groups `haskell-interactive' and `inferior-haskell'
+    to clean up namespace
+  - Create new customization group `ghc-core` containing the two new
+    customization variables `ghc-core-program` and `ghc-core-program-args`.
+
+- Improvements to haskell-interactive-mode
+  - Add support for deleting compile messages superseded by recompile/reloads
+    (M-x customize-variable RET haskell-interactive-mode-delete-superseded-errors)
+  - Fix `C-u M-x haskell-process-do-type` inserting bad signatures
+  - Integrate with Emacs' `next-error` subsystem
+  - Add "C-c C-f" binding to REPL keymap for enabling `next-error-follow-minor-mode'
+  - Add support for `-ferror-spans`-style compile messages
+  - Add `-ferror-spans` as default for `haskell-process-args-ghci`
+  - Add optional argument to
+    `haskell-session-{all,installed,project}-modules' to suppress
+    session-creation. This is useful for yasnippet usage, see commit
+    517fd7e for an example.
+  - Change default for `haskell-process-path-ghci` to a static "ghci"
+  - Fix `haskell-interactive-switch` not selecting the REPL window
+  - Make `*haskell-process-log*` buffer configurable
+    (controlled via new `haskell-process-log` customize option)
+
+* Changes in 13.6
+
+See also [[https://github.com/haskell/haskell-mode/compare/2_9_1...v13.06][detailed Git history]].
+
+- Switch to new versioning scheme
+
+- Switch to MELPA/Marmalade based packaging
+
+- Cleanup/refactor build-system
+
+- Enhance `M-x haskell-version` to report more detailed versioning
+  information
+
+- Make haskell-interactive-mode emulate comint/eshell history navigation
+  (see commit 0e96843 for more details)
+
+- Improvements to haskell-interactive-mode
+  - Improve killing/restarting haskell-interactive sessions
+  - Improve directory prompting and resolution
+  - Fix redundant-import suggest trigger to support qualified imports
+  - Detect all abbreviations of an user-inputted ":quit"
+  - Fix regexps for recent GHC 7.x compiler messages
+  - Customizable commandline args for GHCi
+    (M-x customize-variable RET haskell-process-args-ghci)
+  - New command to load or reload via prefix argument
+    (M-x haskell-process-load-or-reload)
+  - Fix haskell-interactive-mode prompt detection
+  - Add cabal-ghci as supported process mode
+  - Add a customization option for the visibility of multi-line errors
+    (M-x customize-variable RET haskell-interactive-mode-hide-multi-line-errors)
+
+- Add forward declarations to reduce Elisp bytecompile warnings
+
+- Improvements to `haskell-indentation`
+  - Add support for the UnicodeSyntax tokens `→`, `←`, and `∷`.
+  - Indent "=" following data/type/newtype declarations.
+  - Align "->"/"→" arrows in types under "::"/"∷"
+  - Make customizable whether "<backspace>" deletes indentation too
+    (via `haskell-indentation-delete-backward-indentation` and
+     `haskell-indentation-delete-indentation`)
+  - Properly indent 'rec' keyword, same as 'mdo'
+  - Minor optimizations.
+
+- Add support for "'"-prefixed constructors (-> DataKinds) to font-locking
+
+- New experimental haskell session menu mode (M-x haskell-menu)
+
+- Various minor cleanups/fixes/improvements...
+
+* Changes in 2.9.1
+
+See also [[https://github.com/haskell/haskell-mode/compare/2_9_0...2_9_1][detailed Git history]].
+
+- Bugfix release adding missing autoload declaration
+
+* Changes in 2.9.0
+
+See also [[https://github.com/haskell/haskell-mode/compare/2_8_0...2_9_0][detailed Git history]].
+
+- This is the first release after haskell-mode was migrated to GitHub
+
+- New experimental `haskell-interactive-mode' module implementing a
+  new REPL interaction mode for GHCi sessions to eventually replace
+  the existing "inf-haskell" mode.
+
+- New `haskell-process-cabal' command for interaction with cabal-install
+
+- New `haskell-checkers' module
+
+- Update haskell-cabal-mode font-lock keywords
+
+- Improve scrolling of hoogle output (haskell-mode.el)
+
+- Derive `haskell-mode` from `prog-mode` for Emacs 24+
+
+- Add new binding for "<backtab>" to haskell-mode's keymap which
+  unindents current line
+
+- New modules `haskell-navigate-imports`, `haskell-sort-imports' and
+  `haskell-align-imports' for operating on module import lines in
+  Haskell source code
+
+- Add new binding for "C-c C-." to haskell-mode's keymap to sort and
+  realign Haskell module imports
+
+- Add new binding for "C-c i" to haskell-mode's keymap to jump back and
+  forth from/to the current Haskell module's module import section.
+
+- New `inferior-haskell-kind' function for querying kind via GHCi's ":kind"
+
+- New `inferior-haskell-send-decl' for sending declarations to GHCi
+  (bound to "C-x C-d" by default)
+
+- Add new `haskell-doc-use-inf-haskell` customization variable
+
+- Add support for bird-style literate haskell editing and a new
+  related customization variable
+  `haskell-indentation-birdtrack-extra-space'
+
+- Font locking improvements
+  - Add support for Git's merge annotation
+    (with `font-lock-preprocessor-face')
+  - Improve `import', `foreign import' and `foreign export' font
+    locking
+  - Add support for `rec', `proc' and `mdo` as keywords
+  - Make whitespace within `-- |' and `{- |' optional when possible
+
+- New `haskell-move-nested` module providing utilities for
+  interactively {in,de}denting nested "hanging" blocks.
+
+- Add stylish-haskell support
+  (enable via `haskell-stylish-on-save` customization variable)
+
+- Add support for generating tags on save
+  (enable via `haskell-tags-on-save' customization variable)
+
+- Set sensible dabbrev defaults in haskell-mode
+
+- Added `SCC` pragma insert/delete commands
+  (`haskell-mode-insert-scc-at-point` and `haskell-mode-kill-scc-at-point')
+
+- New experimental `haskell-mode-contextual-space' command
+
+- And a couple more cleanups/fixes/improvements...
+
+* Changes in 2.8.0 (since 2.7.0)
+
+See also [[https://github.com/haskell/haskell-mode/compare/2_7_0...2_8_0][detailed Git history]].
+
+- Minimal indentation support for arrow syntax
+
+- Avoid opening a new inf-haskell window if one is already visible.
+  Windows on other virtual desktops or iconified frames don't count.
+
+- Force comint-process-echoes to nil
+
+- Autolaunch haskell-mode for files starting with #!/usr/bin/runghc
+  and similar
+
+- Added minimal major mode for parsing GHC core files, courtesy of Johan Tibell.
+  There is a corresponding Haskell menu entry.
+
+- Allow configuration of where-clause indentation; M-x customize-group
+  haskell-indentation.
+
+* Changes since 2.6.4
+
+- fill-paragraph (M-q) now only affects comments, and correctly
+  handles Haddock commentary. adaptive-fill-mode is turned off, as it
+  was interfering.
+
+- Yet more unicode symbols
+
+- Better support for unicode encoding of haskell source files
+
+- mdo correctly indented
+
+- Indentation fixes, fixes to the fixes, and fixes to the fixes to the
+  fixes
+
+- New command: M-x haskell-check, calls (by default) hlint on the
+  current file. Also bound to C-c C-v.
+
+  You can also use the flymake minor mode with this.
+
+* Changes since 2.5.1
+
+- Parser corrections for haskell-indentation and haskell-decl-scan
+
+- haskell-indentation: Pressing tab in the rightmost position now
+  moves to the leftmost, by default with a warning.
+
+- Typo fix: One haskell-indentation variable had ended up in the
+  haskell-ntation customize group.
+
+- haskell-hoogle aliased to hoogle, haskell-hayoo aliased to hayoo
+
+- Courtesy of Alex Ott:
+  - Additional unicode symbols for font-lock-symbols: () == /= >= <= !! && || sqrt
+  - M-x haskell-hayoo search added, opens using browse-url
+  - Bug-fix for inferior-haskell-type
+
+- If haskell-indentation errors out, it now fail-safes to inserting
+  a literal newline or deleting one character, for return and
+  backspace respectively.
+
+* Changes since 2.4:
+
+- haskell-indentation, a new minor mode for indentation.
+
+* Changes since 2.3:
+
+- Update license to GPLv3.
+
+- New derived major mode for .hsc files.
+
+- Removed the C-c C-r binding to reload a file.  You can still call
+  inferior-haskell-reload-file (and/or bind it to your favorite key,
+  including C-c C-r) or you can now use C-u C-c C-l.
+
+- C-c C-d looks up the symbol at point in the Haddock docs.
+
+- Haddock comments are highlighted with font-lock-doc-face if it exists.
+
+- Use `tex' rather than `latex' for haskell-literate.
+
+- inf-haskell.el tries to find the root of the module hierarchy to determine
+  the root of a project (either by looking for a Cabal file or relying on
+  the `module' declaration line).  If all works well, this will make C-c C-l
+  automatically switch to the root dir, so that dependencies in other
+  directories are automatically found.  If it doesn't, complain and/or set
+  inferior-haskell-find-project-root to nil.
+
+- The new command haskell-hoogle helps you query Hoogle from Emacs.
+
+* Changes since 2.2:
+
+- Trivial support for Cabal package description files.
+
+- Minor bug fixes.
+
+* Changes since 2.1:
+
+- There are now commands to find type and info of identifiers by querying an
+  inferior haskell process.  Available under C-c C-t, C-c C-i, and C-c M-.
+
+- Indentation now looks back further, until a line that has no indentation.
+  To recover the earlier behavior of stopping at the first empty line
+  instead, configure haskell-indent-look-past-empty-line.
+
+- inf-haskell can wait until a file load completes and jump directly to the
+  first error, like haskell-ghci and haskell-hugs used to do.  See the var
+  inferior-haskell-wait-and-jump.
+
+* Changes since 2.0:
+
+- inf-haskell uses ghci if hugs is absent.
+
+- Fix up some binding conflicts (C-c C-o in haskell-doc)
+
+- Many (hopefully minor) changes to the indentation.
+
+- New symbols in haskell-font-lock-symbols-alist.
+
+* Changes since 1.45:
+
+- keybindings C-c <char> have been replaced by C-c C-<char> so as not
+  to collide with minor modes.
+
+- The following modules are now automatically activated without having to
+  add anything to haskell-mode-hook:
+  haskell-font-lock (just turn on global-font-lock-mode).
+  haskell-decl-scan (just bind `imenu' to some key).
+
+- In recent Emacsen, haskell-doc hooks into eldoc-mode.
+
+- haskell-hugs and haskell-ghci are superceded by inf-haskell.
+
+- Indentation rules have been improved when using layout inside parens/braces.
+
+- Symbols like -> and \ can be displayed as actual arrows and lambdas.
+  See haskell-font-lock-symbols.
+
+- Tweaks to the font-lock settings.  Among other things paren-matching
+  with things like \(x,y) should work correctly now.
+
+- New maintainer <monnier@gnu.org>.
diff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/dir b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/dir
new file mode 100644
index 0000000000..de046d84b0
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/dir
@@ -0,0 +1,18 @@
+This is the file .../info/dir, which contains the
+topmost node of the Info hierarchy, called (dir)Top.
+The first time you invoke Info you start off looking at this node.
+
+File: dir,	Node: Top	This is the top of the INFO tree
+
+  This (the Directory node) gives a menu of major topics.
+  Typing "q" exits, "?" lists all Info commands, "d" returns here,
+  "h" gives a primer for first-timers,
+  "mEmacs<Return>" visits the Emacs manual, etc.
+
+  In Emacs, you can click mouse button 2 on a menu item or cross reference
+  to select it.
+
+* Menu:
+
+Emacs
+* Haskell Mode: (haskell-mode). Haskell Development Environment for Emacs(en)
diff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/ghc-core.el b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/ghc-core.el
new file mode 100644
index 0000000000..34ee781e11
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/ghc-core.el
@@ -0,0 +1,123 @@
+;;; ghc-core.el --- Syntax highlighting module for GHC Core -*- lexical-binding: t -*-
+
+;; Copyright (C) 2010  Johan Tibell
+
+;; Author: Johan Tibell <johan.tibell@gmail.com>
+
+;; This file is not part of GNU Emacs.
+
+;; This file 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, or (at your option)
+;; any later version.
+
+;; This file 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; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; Purpose:
+;;
+;; To make it easier to read GHC Core output by providing highlighting
+;; and removal of commonly ignored annotations.
+
+;;; Code:
+(require 'haskell-mode)
+(require 'haskell-font-lock)
+
+;;;###autoload
+(defgroup ghc-core nil
+  "Major mode for viewing pretty printed GHC Core output."
+  :link '(custom-manual "(haskell-mode)")
+  :group 'haskell
+  :prefix "ghc-core-")
+
+(defcustom ghc-core-program
+  "ghc"
+  "Name of the GHC executable (excluding any arguments)."
+  :type 'string
+  :group 'ghc-core)
+
+(defcustom ghc-core-program-args
+  '("-O2")
+  "Additional options to be passed to GHC when generating core output.
+GHC (see variable `ghc-core-program') is invoked with the basic
+command line options \"-ddump-simpl -c <source-file>\"
+followed by the additional options defined here.
+
+The following `-ddump-simpl` options might be of interest:
+
+ - `-dsuppress-all'
+ - `-dsuppress-uniques'
+ - `-dsuppress-idinfo'
+ - `-dsuppress-module-prefixes'
+ - `-dsuppress-type-signatures'
+ - `-dsuppress-type-applications'
+ - `-dsuppress-coercions'
+
+See `M-x manual-entry RET ghc' for more details."
+  :type '(repeat (string :tag "Argument"))
+  :group 'ghc-core)
+
+(define-obsolete-variable-alias 'ghc-core-create-options 'ghc-core-program-args
+  "haskell-mode 13.7")
+
+(defun ghc-core-clean-region (start end)
+  "Remove commonly ignored annotations and namespace prefixes
+in the region between START and END."
+  (interactive "r")
+  (save-restriction
+    (narrow-to-region start end)
+    (goto-char (point-min))
+    (while (search-forward-regexp "GHC\.[^\.]*\." nil t)
+      (replace-match "" nil t))
+    (goto-char (point-min))
+    (while (flush-lines "^ *GblId *$" nil))
+    (goto-char (point-min))
+    (while (flush-lines "^ *LclId *$" nil))
+    (goto-char (point-min))
+    (while (flush-lines (concat "^ *\\[\\(?:Arity [0-9]+\\|NoCafRefs\\|"
+                                "Str: DmdType\\|Worker \\)"
+                                "\\([^]]*\\n?\\).*\\] *$") nil))
+    (goto-char (point-min))
+    (while (search-forward "Main." nil t) (replace-match "" nil t))))
+
+(defun ghc-core-clean-buffer ()
+  "Remove commonly ignored annotations and namespace prefixes
+in the current buffer."
+  (interactive)
+  (ghc-core-clean-region (point-min) (point-max)))
+
+;;;###autoload
+(defun ghc-core-create-core ()
+  "Compile and load the current buffer as tidy core."
+  (interactive)
+  (save-buffer)
+  (let* ((core-buffer (generate-new-buffer "ghc-core"))
+         (neh (lambda () (kill-buffer core-buffer))))
+    (add-hook 'next-error-hook neh)
+    (apply #'call-process ghc-core-program nil core-buffer nil
+           "-ddump-simpl" "-c" (buffer-file-name) ghc-core-program-args)
+    (display-buffer core-buffer)
+    (with-current-buffer core-buffer
+      (ghc-core-mode))
+    (remove-hook 'next-error-hook neh)))
+
+;;;###autoload
+(add-to-list 'auto-mode-alist '("\\.hcr\\'" . ghc-core-mode))
+;;;###autoload
+(add-to-list 'auto-mode-alist '("\\.dump-simpl\\'" . ghc-core-mode))
+
+;;;###autoload
+(define-derived-mode ghc-core-mode haskell-mode "GHC-Core"
+  "Major mode for GHC Core files.")
+
+(provide 'ghc-core)
+;;; ghc-core.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/ghc-core.elc b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/ghc-core.elc
new file mode 100644
index 0000000000..e42eb93fff
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/ghc-core.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/ghci-script-mode.el b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/ghci-script-mode.el
new file mode 100644
index 0000000000..2ec905cd14
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/ghci-script-mode.el
@@ -0,0 +1,66 @@
+;;; ghci-script-mode.el --- GHCi scripts major mode -*- lexical-binding: t -*-
+
+;; Copyright (c) 2014 Chris Done. All rights reserved.
+
+;; This file 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, or (at your option)
+;; any later version.
+
+;; This file 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Code:
+
+(require 'haskell)
+
+(defvar ghci-script-mode-keywords
+  ;; The comment syntax can't be described simply in syntax-table.
+  ;; We could use font-lock-syntactic-keywords, but is it worth it?
+  '(("^[ \t]*--.*" . font-lock-comment-face)
+    ("^ *\\([^ \t:]+\\):" (1 font-lock-keyword-face))
+    ("^:[a-z{]+ *\\+" . font-lock-keyword-face)
+    ("^:[a-z{]+ " . font-lock-keyword-face)))
+
+;;;###autoload
+(define-derived-mode ghci-script-mode text-mode "GHCi-Script"
+  "Major mode for working with .ghci files."
+  (setq-local adaptive-fill-mode nil)
+  (setq-local comment-start "-- ")
+  (setq-local comment-padding 0)
+  (setq-local comment-start-skip "[-{]-[ \t]*")
+  (setq-local comment-end "")
+  (setq-local comment-end-skip "[ \t]*\\(-}\\|\\s>\\)")
+  (setq-local font-lock-defaults '(ghci-script-mode-keywords t t nil nil))
+  (setq-local indent-tabs-mode nil)
+  (setq-local tab-width 8)
+  (when (boundp 'electric-indent-inhibit)
+    (setq electric-indent-inhibit t))
+  (setq-local dabbrev-case-fold-search nil)
+  (setq-local dabbrev-case-distinction nil)
+  (setq-local dabbrev-case-replace nil)
+  (setq-local dabbrev-abbrev-char-regexp "\\sw\\|[.]")
+  (setq haskell-literate nil))
+
+;;;###autoload
+(add-to-list 'auto-mode-alist '("\\.ghci\\'" . ghci-script-mode))
+
+(define-key ghci-script-mode-map (kbd "C-c C-l") 'ghci-script-mode-load)
+
+(defun ghci-script-mode-load ()
+  "Load the current script file into the GHCi session."
+  (interactive)
+  (let ((buffer (haskell-session-interactive-buffer (haskell-session)))
+        (filename (buffer-file-name)))
+    (save-buffer)
+    (with-current-buffer buffer
+      (set-marker haskell-interactive-mode-prompt-start (point-max))
+      (haskell-interactive-mode-run-expr
+       (concat ":script " filename)))))
+
+(provide 'ghci-script-mode)
diff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/ghci-script-mode.elc b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/ghci-script-mode.elc
new file mode 100644
index 0000000000..1359354eb6
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/ghci-script-mode.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-align-imports.el b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-align-imports.el
new file mode 100644
index 0000000000..694ee25929
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-align-imports.el
@@ -0,0 +1,231 @@
+;;; haskell-align-imports.el --- Align the import lines in a Haskell file -*- lexical-binding: t -*-
+
+;; Copyright (C) 2010  Chris Done
+
+;; Author: Chris Done <chrisdone@gmail.com>
+
+;; This file is not part of GNU Emacs.
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see
+;; <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Consider the following imports list:
+;;
+;; import One
+;; import Two as A
+;; import qualified Three
+;; import qualified Four as PRELUDE
+;; import Five (A)
+;; import Six (A,B)
+;; import qualified Seven (A,B)
+;; import "abc" Eight
+;; import "abc" Nine as TWO
+;; import qualified "abc" Ten
+;; import qualified "defg" Eleven as PRELUDE
+;; import "barmu" Twelve (A)
+;; import "zotconpop" Thirteen (A,B)
+;; import qualified "z" Fourteen (A,B)
+;; import Fifteen hiding (A)
+;; import Sixteen as TWO hiding (A)
+;; import qualified Seventeen hiding (A)
+;; import qualified Eighteen as PRELUDE hiding (A)
+;; import "abc" Nineteen hiding (A)
+;; import "abc" Twenty as TWO hiding (A)
+;;
+;; When haskell-align-imports is run within the same buffer, the
+;; import list is transformed to:
+;;
+;; import "abc"            Eight
+;; import qualified        Eighteen as PRELUDE hiding (A)
+;; import qualified "defg" Eleven as PRELUDE
+;; import                  Fifteen hiding (A)
+;; import                  Five (A)
+;; import qualified        Four as PRELUDE
+;; import qualified "z"    Fourteen  (A,B)
+;; import "abc"            Nine as TWO
+;; import "abc"            Nineteen hiding (A)
+;; import                  One
+;; import qualified        Seven (A,B)
+;; import qualified        Seventeen hiding (A)
+;; import                  Six (A,B)
+;; import                  Sixteen as TWO hiding (A)
+;; import qualified "abc"  Ten
+;; import "zotconpop"      Thirteen (A,B)
+;; import qualified        Three
+;; import "barmu"          Twelve (A)
+;; import "abc"            Twenty as TWO hiding (A)
+;; import                  Two as A
+;;
+;; If you want everything after module names to be padded out, too,
+;; customize `haskell-align-imports-pad-after-name', and you'll get:
+;;
+;; import                  One
+;; import                  Two       as A
+;; import qualified        Three
+;; import qualified        Four      as PRELUDE
+;; import                  Five      (A)
+;; import                  Six       (A,B)
+;; import qualified        Seven     (A,B)
+;; import "abc"            Eight
+;; import "abc"            Nine      as TWO
+;; import qualified "abc"  Ten
+;; import qualified "defg" Eleven    as PRELUDE
+;; import "barmu"          Twelve    (A)
+;; import "zotconpop"      Thirteen  (A,B)
+;; import qualified "z"    Fourteen  (A,B)
+;; import                  Fifteen   hiding (A)
+;; import                  Sixteen   as TWO hiding (A)
+;; import qualified        Seventeen hiding (A)
+;; import qualified        Eighteen  as PRELUDE hiding (A)
+;; import "abc"            Nineteen  hiding (A)
+;; import "abc"            Twenty    as TWO hiding (A)
+
+;;; Code:
+
+(require 'cl-lib)
+
+(defvar haskell-align-imports-regexp
+  (concat "^\\(import[ ]+\\)"
+          "\\(qualified \\)?"
+          "[ ]*\\(\"[^\"]*\" \\)?"
+          "[ ]*\\([A-Za-z0-9_.']+\\)"
+          "[ ]*\\([ ]*as [A-Z][^ ]*\\)?"
+          "[ ]*\\((.*)\\)?"
+          "\\([ ]*hiding (.*)\\)?"
+          "\\( -- .*\\)?[ ]*$")
+  "Regex used for matching components of an import.")
+
+(defcustom haskell-align-imports-pad-after-name
+  nil
+  "Pad layout after the module name also."
+  :type 'boolean
+  :group 'haskell-interactive)
+
+;;;###autoload
+(defun haskell-align-imports ()
+  "Align all the imports in the buffer."
+  (interactive)
+  (when (haskell-align-imports-line-match)
+    (save-excursion
+      (goto-char (point-min))
+      (let* ((imports (haskell-align-imports-collect))
+             (padding (haskell-align-imports-padding imports)))
+        (mapc (lambda (x)
+                (goto-char (cdr x))
+                (delete-region (point) (line-end-position))
+                (insert (haskell-align-imports-chomp
+                         (haskell-align-imports-fill padding (car x)))))
+              imports))))
+  nil)
+
+(defun haskell-align-imports-line-match ()
+  "Try to match the current line as a regexp."
+  (let ((line (buffer-substring-no-properties (line-beginning-position)
+                                              (line-end-position))))
+    (if (string-match "^import " line)
+        line
+      nil)))
+
+(defun haskell-align-imports-collect ()
+  "Collect a list of mark / import statement pairs."
+  (let ((imports '()))
+    (while (not (or (equal (point) (point-max)) (haskell-align-imports-after-imports-p)))
+      (let ((line (haskell-align-imports-line-match-it)))
+        (when line
+          (let ((match
+                 (haskell-align-imports-merge-parts
+                  (cl-loop for i from 1 to 8
+                           collect (haskell-align-imports-chomp (match-string i line))))))
+            (setq imports (cons (cons match (line-beginning-position))
+                                imports)))))
+      (forward-line))
+    imports))
+
+(defun haskell-align-imports-merge-parts (l)
+  "Merge together parts of an import statement that shouldn't be separated."
+  (let ((parts (apply #'vector l))
+        (join (lambda (ls)
+                (cl-reduce (lambda (a b)
+                             (concat a
+                                     (if (and (> (length a) 0)
+                                              (> (length b) 0))
+                                         " "
+                                       "")
+                                     b))
+                           ls))))
+    (if haskell-align-imports-pad-after-name
+        (list (funcall join (list (aref parts 0)
+                                  (aref parts 1)
+                                  (aref parts 2)))
+              (aref parts 3)
+              (funcall join (list (aref parts 4)
+                                  (aref parts 5)
+                                  (aref parts 6)))
+              (aref parts 7))
+      (list (funcall join (list (aref parts 0)
+                                (aref parts 1)
+                                (aref parts 2)))
+            (funcall join (list (aref parts 3)
+                                (aref parts 4)
+                                (aref parts 5)
+                                (aref parts 6)
+                                (aref parts 7)))))))
+
+(defun haskell-align-imports-chomp (str)
+  "Chomp leading and tailing whitespace from STR."
+  (if str
+      (replace-regexp-in-string "\\(^[[:space:]\n]*\\|[[:space:]\n]*$\\)" ""
+                                str)
+    ""))
+
+(defun haskell-align-imports-padding (imports)
+  "Find the padding for each part of the import statements."
+  (if (null imports)
+      imports
+    (cl-reduce (lambda (a b) (cl-mapcar #'max a b))
+               (mapcar (lambda (x) (mapcar #'length (car x)))
+                       imports))))
+
+(defun haskell-align-imports-fill (padding line)
+  "Fill an import line using the padding worked out from all statements."
+  (mapconcat #'identity
+             (cl-mapcar (lambda (pad part)
+                          (if (> (length part) 0)
+                              (concat part (make-string (- pad (length part)) ? ))
+                            (make-string pad ? )))
+                        padding
+                        line)
+             " "))
+
+(defun haskell-align-imports-line-match-it ()
+  "Try to match the current line as a regexp."
+  (let ((line (buffer-substring-no-properties (line-beginning-position)
+                                              (line-end-position))))
+    (if (string-match haskell-align-imports-regexp line)
+        line
+      nil)))
+
+(defun haskell-align-imports-after-imports-p ()
+  "Are we after the imports list?"
+  (save-excursion
+    (goto-char (line-beginning-position))
+    (let ((case-fold-search nil))
+      (not (not (search-forward-regexp "\\( = \\|\\<instance\\>\\| :: \\| ∷ \\)"
+                                       (line-end-position) t 1))))))
+
+(provide 'haskell-align-imports)
+
+;;; haskell-align-imports.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-align-imports.elc b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-align-imports.elc
new file mode 100644
index 0000000000..44947d2880
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-align-imports.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-c2hs.el b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-c2hs.el
new file mode 100644
index 0000000000..c4cb41ec37
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-c2hs.el
@@ -0,0 +1,207 @@
+;; haskell-c2hs.el --- -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2016 Sergey Vinokurov
+;;
+;; Author: Sergey Vinokurov <serg.foo@gmail.com>
+;; Created: Monday,  7 March 2016
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; This mode is mostly intended for highlighting {#...#} hooks.
+;;
+;; Quick setup:
+;; (autoload 'haskell-c2hs-mode "haskell-c2hs-mode" nil t)
+;; (add-to-list 'auto-mode-alist '("\\.chs\\'" . haskell-c2hs-mode))
+;;
+
+(require 'haskell-mode)
+(require 'haskell-font-lock)
+(require 'haskell-utils)
+
+;;;###autoload
+(add-to-list 'auto-mode-alist '("\\.chs\\'" . haskell-c2hs-mode))
+
+(defface haskell-c2hs-hook-pair-face
+  '((t (:inherit 'font-lock-preprocessor-face)))
+  "Face for highlighting {#...#} pairs."
+  :group 'haskell)
+
+(defface haskell-c2hs-hook-name-face
+  '((t (:inherit 'font-lock-keyword-face)))
+  "Face for highlighting c2hs hook names."
+  :group 'haskell)
+
+(defvar haskell-c2hs-font-lock-keywords
+  `((,(eval-when-compile
+        (let* ((ws '(any ?\s ?\t ?\n ?\r))
+               (anychar '(or (not (any ?#))
+                             (seq "#"
+                                  (not (any ?\})))))
+               (any-nonquote '(or (not (any ?# ?\"))
+                                  (seq "#"
+                                       (not (any ?\} ?\")))))
+               (cid '(seq (any (?a . ?z) (?A . ?Z) ?_)
+                          (* (any (?a . ?z) (?A . ?Z) (?0 . ?9) ?_))))
+               (hsid-type '(seq (? "'")
+                                (any (?A . ?Z))
+                                (* (any (?a . ?z) (?A . ?Z) (?0 . ?9) ?_ ?'))))
+               (equals-str-val `(seq (* ,ws)
+                                     "="
+                                     (* ,ws)
+                                     "\""
+                                     (* ,any-nonquote)
+                                     "\"")))
+          (eval
+           `(rx
+             (seq
+              (group-n 1 "{#")
+              (* ,ws)
+              (or (seq (group-n 2
+                                "import"
+                                (opt (+ ,ws)
+                                     "qualified"))
+                       (+ ,ws))
+                  (seq (group-n 2
+                                "context")
+                       (opt (+ ,ws)
+                            (group-n 3
+                                     "lib")
+                            ,equals-str-val)
+                       (opt (+ ,ws)
+                            (group-n 4
+                                     "prefix")
+                            ,equals-str-val)
+                       (opt (+ ,ws)
+                            (group-n 5
+                                     "add"
+                                     (+ ,ws)
+                                     "prefix")
+                            ,equals-str-val))
+                  (seq (group-n 2
+                                "type")
+                       (+ ,ws)
+                       ,cid)
+                  (seq (group-n 2
+                                "sizeof")
+                       (+ ,ws)
+                       ,cid)
+                  (seq (group-n 2
+                                "enum"
+                                (+ ,ws)
+                                "define")
+                       (+ ,ws)
+                       ,cid)
+                  ;; TODO: vanilla enum fontification is incomplete
+                  (seq (group-n 2
+                                "enum")
+                       (+ ,ws)
+                       ,cid
+                       (opt (+ ,ws)
+                            (group-n 3
+                                     "as")))
+                  ;; TODO: fun hook highlighting is incompelete
+                  (seq (group-n 2
+                                (or "call"
+                                    "fun")
+                                (opt (+ ,ws)
+                                     "pure")
+                                (opt (+ ,ws)
+                                     "unsafe"))
+                       (+ ,ws)
+                       ,cid
+                       (opt (+ ,ws)
+                            (group-n 3
+                                     "as")
+                            (opt (+ ,ws)
+                                 (group-n 8
+                                          "^"))))
+                  (group-n 2
+                           "get")
+                  (group-n 2
+                           "set")
+                  (seq (group-n 2
+                                "pointer")
+                       (or (seq (* ,ws)
+                                (group-n 3 "*")
+                                (* ,ws))
+                           (+ ,ws))
+                       ,cid
+                       (opt (+ ,ws)
+                            (group-n 4 "as")
+                            (+ ,ws)
+                            ,hsid-type)
+                       (opt (+ ,ws)
+                            (group-n 5
+                                     (or "foreign"
+                                         "stable")))
+                       (opt
+                        (or (seq (+ ,ws)
+                                 (group-n 6
+                                          "newtype"))
+                            (seq (* ,ws)
+                                 "->"
+                                 (* ,ws)
+                                 ,hsid-type)))
+                       (opt (+ ,ws)
+                            (group-n 7
+                                     "nocode")))
+                  (group-n 2
+                           "class")
+                  (group-n 2
+                           "alignof")
+                  (group-n 2
+                           "offsetof")
+                  (seq (group-n 2
+                                "const")
+                       (+ ,ws)
+                       ,cid)
+                  (seq (group-n 2
+                                "typedef")
+                       (+ ,ws)
+                       ,cid
+                       (+ ,ws)
+                       ,hsid-type)
+                  (group-n 2
+                           "nonGNU")
+                  ;; TODO: default hook not implemented
+                  )
+              (* ,anychar)
+              (group-n 9 "#}"))))))
+     ;; Override highlighting for pairs in order to always distinguish them.
+     (1 'haskell-c2hs-hook-pair-face t)
+     (2 'haskell-c2hs-hook-name-face)
+     ;; Make matches lax, i.e. do not signal error if nothing
+     ;; matched.
+     (3 'haskell-c2hs-hook-name-face nil t)
+     (4 'haskell-c2hs-hook-name-face nil t)
+     (5 'haskell-c2hs-hook-name-face nil t)
+     (6 'haskell-c2hs-hook-name-face nil t)
+     (7 'haskell-c2hs-hook-name-face nil t)
+     (8 'font-lock-negation-char-face nil t)
+     ;; Override highlighting for pairs in order to always distinguish them.
+     (9 'haskell-c2hs-hook-pair-face t))
+    ,@(haskell-font-lock-keywords)))
+
+;;;###autoload
+(define-derived-mode haskell-c2hs-mode haskell-mode "C2HS"
+  "Mode for editing *.chs files of the c2hs haskell tool."
+  (setq-local font-lock-defaults
+              (cons 'haskell-c2hs-font-lock-keywords
+                    (cdr font-lock-defaults))))
+
+
+(provide 'haskell-c2hs)
+
+;; haskell-c2hs.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-c2hs.elc b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-c2hs.elc
new file mode 100644
index 0000000000..20f7e72763
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-c2hs.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-cabal.el b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-cabal.el
new file mode 100644
index 0000000000..35dcca6c59
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-cabal.el
@@ -0,0 +1,1178 @@
+;;; haskell-cabal.el --- Support for Cabal packages -*- lexical-binding: t -*-
+
+;; Copyright © 2007, 2008  Stefan Monnier
+;;             2016 Arthur Fayzrakhmanov
+
+;; Author: Stefan Monnier <monnier@iro.umontreal.ca>
+
+;; This file is not part of GNU Emacs.
+
+;; This file 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, or (at your option)
+;; any later version.
+
+;; This file 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; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; Todo:
+
+;; - distinguish continued lines from indented lines.
+;; - indent-line-function.
+;; - outline-minor-mode.
+
+;;; Code:
+
+;; (defun haskell-cabal-extract-fields-from-doc ()
+;;   (require 'xml)
+;;   (let ((section (completing-read
+;;                   "Section: "
+;;                   '("general-fields" "library" "executable" "buildinfo"))))
+;;     (goto-char (point-min))
+;;     (search-forward (concat "<sect3 id=\"" section "\">")))
+;;   (let* ((xml (xml-parse-region
+;;                (progn (search-forward "<variablelist>") (match-beginning 0))
+;;                (progn (search-forward "</variablelist>") (point))))
+;;          (varlist (cl-remove-if-not 'consp (cl-cddar xml)))
+;;          (syms (mapcar (lambda (entry) (cl-caddr (assq 'literal (assq 'term entry))))
+;;                        varlist))
+;;          (fields (mapcar (lambda (sym) (substring-no-properties sym 0 -1)) syms)))
+;;     fields))
+
+(require 'cl-lib)
+(require 'haskell-utils)
+
+(defcustom haskell-hasktags-path "hasktags"
+  "Path to `hasktags' executable."
+  :group 'haskell
+  :type 'string)
+
+(defcustom haskell-hasktags-arguments '("-e" "-x")
+  "Additional arguments for `hasktags' executable.
+By default these are:
+
+-e - generate ETAGS file
+-x - generate additional information in CTAGS file."
+  :group 'haskell
+  :type '(list string))
+
+(defconst haskell-cabal-general-fields
+  ;; Extracted with (haskell-cabal-extract-fields-from-doc "general-fields")
+  '("name" "version" "cabal-version" "license" "license-file" "copyright"
+    "author" "maintainer" "stability" "homepage" "package-url" "synopsis"
+    "description" "category" "tested-with" "build-depends" "data-files"
+    "extra-source-files" "extra-tmp-files"))
+
+(defconst haskell-cabal-library-fields
+  ;; Extracted with (haskell-cabal-extract-fields-from-doc "library")
+  '("exposed-modules"))
+
+(defconst haskell-cabal-executable-fields
+  ;; Extracted with (haskell-cabal-extract-fields-from-doc "executable")
+  '("executable" "main-is"))
+
+(defconst haskell-cabal-buildinfo-fields
+  ;; Extracted with (haskell-cabal-extract-fields-from-doc "buildinfo")
+  '("buildable" "other-modules" "hs-source-dirs" "extensions" "ghc-options"
+    "ghc-prof-options" "hugs-options" "nhc-options" "includes"
+    "install-includes" "include-dirs" "c-sources" "extra-libraries"
+    "extra-lib-dirs" "cc-options" "ld-options" "frameworks"))
+
+(defvar haskell-cabal-mode-syntax-table
+  (let ((st (make-syntax-table)))
+    ;; The comment syntax can't be described simply in syntax-table.
+    ;; We could use font-lock-syntactic-keywords, but is it worth it?
+    ;; (modify-syntax-entry ?- ". 12" st)
+    (modify-syntax-entry ?\n ">" st)
+    (modify-syntax-entry ?- "w" st)
+    st))
+
+(defvar haskell-cabal-font-lock-keywords
+  ;; The comment syntax can't be described simply in syntax-table.
+  ;; We could use font-lock-syntactic-keywords, but is it worth it?
+  '(("^[ \t]*--.*" . font-lock-comment-face)
+    ("^ *\\([^ \t:]+\\):" (1 font-lock-keyword-face))
+    ("^\\(Library\\)[ \t]*\\({\\|$\\)" (1 font-lock-keyword-face))
+    ("^\\(Executable\\|Test-Suite\\|Benchmark\\)[ \t]+\\([^\n \t]*\\)"
+     (1 font-lock-keyword-face) (2 font-lock-function-name-face))
+    ("^\\(Flag\\)[ \t]+\\([^\n \t]*\\)"
+     (1 font-lock-keyword-face) (2 font-lock-constant-face))
+    ("^\\(Source-Repository\\)[ \t]+\\(head\\|this\\)"
+     (1 font-lock-keyword-face) (2 font-lock-constant-face))
+    ("^ *\\(if\\)[ \t]+.*\\({\\|$\\)" (1 font-lock-keyword-face))
+    ("^ *\\(}[ \t]*\\)?\\(else\\)[ \t]*\\({\\|$\\)"
+     (2 font-lock-keyword-face))
+    ("\\<\\(?:True\\|False\\)\\>"
+     (0 font-lock-constant-face))))
+
+(defvar haskell-cabal-buffers nil
+  "List of Cabal buffers.")
+
+(defun haskell-cabal-buffers-clean (&optional buffer)
+  "Refresh list of known cabal buffers.
+
+Check each buffer in variable `haskell-cabal-buffers' and remove
+it from list if one of the following conditions are hold:
++ buffer is killed;
++ buffer's mode is not derived from `haskell-cabal-mode';
++ buffer is a BUFFER (if given)."
+  (let ((bufs ()))
+    (dolist (buf haskell-cabal-buffers)
+      (if (and (buffer-live-p buf)
+               (not (eq buf buffer))
+               (with-current-buffer buf (derived-mode-p 'haskell-cabal-mode)))
+          (push buf bufs)))
+    (setq haskell-cabal-buffers bufs)))
+
+(defun haskell-cabal-unregister-buffer ()
+  "Exclude current buffer from global list of known cabal buffers."
+  (haskell-cabal-buffers-clean (current-buffer)))
+
+;;;###autoload
+(add-to-list 'auto-mode-alist '("\\.cabal\\'" . haskell-cabal-mode))
+
+(defvar haskell-cabal-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "C-c C-s") 'haskell-cabal-subsection-arrange-lines)
+    (define-key map (kbd "C-M-n") 'haskell-cabal-next-section)
+    (define-key map (kbd "C-M-p") 'haskell-cabal-previous-section)
+    (define-key map (kbd "M-n") 'haskell-cabal-next-subsection)
+    (define-key map (kbd "M-p") 'haskell-cabal-previous-subsection)
+    (define-key map (kbd "C-<down>") 'haskell-cabal-next-subsection)
+    (define-key map (kbd "C-<up>") 'haskell-cabal-previous-subsection)
+    (define-key map (kbd "C-c C-f") 'haskell-cabal-find-or-create-source-file)
+    (define-key map (kbd "M-g l") 'haskell-cabal-goto-library-section)
+    (define-key map (kbd "M-g e") 'haskell-cabal-goto-executable-section)
+    (define-key map (kbd "M-g b") 'haskell-cabal-goto-benchmark-section)
+    (define-key map (kbd "M-g t") 'haskell-cabal-goto-test-suite-section)
+    map))
+
+;;;###autoload
+(define-derived-mode haskell-cabal-mode fundamental-mode "Haskell-Cabal"
+  "Major mode for Cabal package description files."
+  (setq-local font-lock-defaults
+              '(haskell-cabal-font-lock-keywords t t nil nil))
+  (add-to-list 'haskell-cabal-buffers (current-buffer))
+  (add-hook 'change-major-mode-hook 'haskell-cabal-unregister-buffer nil 'local)
+  (add-hook 'kill-buffer-hook 'haskell-cabal-unregister-buffer nil 'local)
+  (setq-local comment-start "-- ")
+  (setq-local comment-start-skip "\\(^[ \t]*\\)--[ \t]*")
+  (setq-local comment-end "")
+  (setq-local comment-end-skip "[ \t]*\\(\\s>\\|\n\\)")
+  (setq-local indent-line-function 'haskell-cabal-indent-line)
+  (setq indent-tabs-mode nil)
+  )
+
+(make-obsolete 'haskell-cabal-get-setting
+               'haskell-cabal--get-field
+               "March 14, 2016")
+(defalias 'haskell-cabal-get-setting 'haskell-cabal--get-field
+  "Try to read value of field with NAME from current buffer.
+Obsolete function.  Defined for backward compatibility.  Use
+`haskell-cabal--get-field' instead.")
+
+(defun haskell-cabal--get-field (name)
+  "Try to read value of field with NAME from current buffer."
+  (save-excursion
+    (let ((case-fold-search t))
+      (goto-char (point-min))
+      (when (re-search-forward
+             (concat "^[ \t]*" (regexp-quote name)
+                     ":[ \t]*\\(.*\\(\n[ \t]+[ \t\n].*\\)*\\)")
+             nil t)
+        (let ((val (match-string 1))
+              (start 1))
+          (when (match-end 2)             ;Multiple lines.
+            ;; The documentation is not very precise about what to do about
+            ;; the \n and the indentation: are they part of the value or
+            ;; the encoding?  I take the point of view that \n is part of
+            ;; the value (so that values can span multiple lines as well),
+            ;; and that only the first char in the indentation is part of
+            ;; the encoding, the rest is part of the value (otherwise, lines
+            ;; in the value cannot start with spaces or tabs).
+            (while (string-match "^[ \t]\\(?:\\.$\\)?" val start)
+              (setq start (1+ (match-beginning 0)))
+              (setq val (replace-match "" t t val))))
+          val)))))
+
+
+(make-obsolete 'haskell-cabal-guess-setting
+               'haskell-cabal-get-field
+               "March 14, 2016")
+(defalias 'haskell-cabal-guess-setting 'haskell-cabal-get-field
+  "Read the value of field with NAME from project's cabal file.
+Obsolete function.  Defined for backward compatibility.  Use
+`haskell-cabal-get-field' instead.")
+
+;;;###autoload
+(defun haskell-cabal-get-field (name)
+  "Read the value of field with NAME from project's cabal file.
+If there is no valid .cabal file to get the setting from (or
+there is no corresponding setting with that name in the .cabal
+file), then this function returns nil."
+  (interactive)
+  (when (and name buffer-file-name)
+    (let ((cabal-file (haskell-cabal-find-file)))
+      (when (and cabal-file (file-readable-p cabal-file))
+        (with-temp-buffer
+          (insert-file-contents cabal-file)
+          (haskell-cabal--get-field name))))))
+
+;;;###autoload
+(defun haskell-cabal-get-dir (&optional use-defaults)
+  "Get the Cabal dir for a new project. Various ways of figuring this out,
+   and indeed just prompting the user. Do them all."
+  (let* ((file (haskell-cabal-find-file))
+         (dir (if file (file-name-directory file) default-directory)))
+    (if use-defaults
+        dir
+        (haskell-utils-read-directory-name
+         (format "Cabal dir%s: " (if file (format " (guessed from %s)" (file-relative-name file)) ""))
+         dir))))
+
+(defun haskell-cabal-compute-checksum (dir)
+  "Compute MD5 checksum of package description file in DIR.
+Return nil if no Cabal description file could be located via
+`haskell-cabal-find-pkg-desc'."
+  (let ((cabal-file (haskell-cabal-find-pkg-desc dir)))
+    (when cabal-file
+      (with-temp-buffer
+        (insert-file-contents cabal-file)
+        (md5 (buffer-string))))))
+
+(defun haskell-cabal-find-file (&optional dir)
+  "Search for package description file upwards starting from DIR.
+If DIR is nil, `default-directory' is used as starting point for
+directory traversal.  Upward traversal is aborted if file owner
+changes.  Uses `haskell-cabal-find-pkg-desc' internally."
+  (let ((use-dir (or dir default-directory)))
+    (while (and use-dir (not (file-directory-p use-dir)))
+      (setq use-dir (file-name-directory (directory-file-name use-dir))))
+    (when use-dir
+      (catch 'found
+        (let ((user (nth 2 (file-attributes use-dir)))
+              ;; Abbreviate, so as to stop when we cross ~/.
+              (root (abbreviate-file-name use-dir)))
+          ;; traverse current dir up to root as long as file owner doesn't change
+          (while (and root (equal user (nth 2 (file-attributes root))))
+            (let ((cabal-file (haskell-cabal-find-pkg-desc root)))
+              (when cabal-file
+                (throw 'found cabal-file)))
+
+            (let ((proot (file-name-directory (directory-file-name root))))
+              (if (equal proot root) ;; fix-point reached?
+                  (throw 'found nil)
+                (setq root proot))))
+          nil)))))
+
+(defun haskell-cabal-find-pkg-desc (dir &optional allow-multiple)
+  "Find a package description file in the directory DIR.
+Returns nil if none or multiple \".cabal\" files were found.  If
+ALLOW-MULTIPLE is non nil, in case of multiple \".cabal\" files,
+a list is returned instead of failing with a nil result."
+  ;; This is basically a port of Cabal's
+  ;; Distribution.Simple.Utils.findPackageDesc function
+  ;;  http://hackage.haskell.org/packages/archive/Cabal/1.16.0.3/doc/html/Distribution-Simple-Utils.html
+  ;; but without the exception throwing.
+  (let* ((cabal-files
+          (cl-remove-if 'file-directory-p
+                        (cl-remove-if-not 'file-exists-p
+                                          (directory-files dir t ".\\.cabal\\'")))))
+    (cond
+     ((= (length cabal-files) 1) (car cabal-files)) ;; exactly one candidate found
+     (allow-multiple cabal-files) ;; pass-thru multiple candidates
+     (t nil))))
+
+(defun haskell-cabal-find-dir (&optional dir)
+  "Like `haskell-cabal-find-file' but returns directory instead.
+See `haskell-cabal-find-file' for meaning of DIR argument."
+  (let ((cabal-file (haskell-cabal-find-file dir)))
+    (when cabal-file
+      (file-name-directory cabal-file))))
+
+;;;###autoload
+(defun haskell-cabal-visit-file (other-window)
+  "Locate and visit package description file for file visited by current buffer.
+This uses `haskell-cabal-find-file' to locate the closest
+\".cabal\" file and open it.  This command assumes a common Cabal
+project structure where the \".cabal\" file is in the top-folder
+of the project, and all files related to the project are in or
+below the top-folder.  If called with non-nil prefix argument
+OTHER-WINDOW use `find-file-other-window'."
+  (interactive "P")
+  ;; Note: We aren't allowed to rely on haskell-session here (which,
+  ;; in pathological cases, can have a different .cabal file
+  ;; associated with the current buffer)
+  (if buffer-file-name
+      (let ((cabal-file (haskell-cabal-find-file (file-name-directory buffer-file-name))))
+        (if cabal-file
+            (if other-window
+                (find-file-other-window cabal-file)
+              (find-file cabal-file))
+          (error "Could not locate \".cabal\" file for %S" buffer-file-name)))
+    (error "Cannot locate \".cabal\" file for buffers not visiting any file")))
+
+(defvar haskell-cabal-commands
+  '("install"
+    "update"
+    "list"
+    "info"
+    "upgrade"
+    "fetch"
+    "unpack"
+    "check"
+    "sdist"
+    "upload"
+    "report"
+    "init"
+    "configure"
+    "build"
+    "copy"
+    "haddock"
+    "clean"
+    "hscolour"
+    "register"
+    "test"
+    "help"
+    "run"))
+
+;;;###autoload
+(defgroup haskell-cabal nil
+  "Haskell cabal files"
+  :group 'haskell
+)
+
+(defconst haskell-cabal-section-header-regexp "^[[:alnum:]]" )
+(defconst haskell-cabal-subsection-header-regexp "^[ \t]*[[:alnum:]]\\w*:")
+(defconst haskell-cabal-comment-regexp "^[ \t]*--")
+(defconst haskell-cabal-empty-regexp "^[ \t]*$")
+(defconst haskell-cabal-conditional-regexp "^[ \t]*\\(\\if\\|else\\|}\\)")
+
+(defun haskell-cabal-classify-line ()
+  "Classify the current line into 'section-header 'subsection-header 'section-data 'comment and 'empty '"
+  (save-excursion
+    (beginning-of-line)
+    (cond
+     ((looking-at haskell-cabal-subsection-header-regexp ) 'subsection-header)
+     ((looking-at haskell-cabal-section-header-regexp) 'section-header)
+     ((looking-at haskell-cabal-comment-regexp) 'comment)
+     ((looking-at haskell-cabal-empty-regexp ) 'empty)
+     ((looking-at haskell-cabal-conditional-regexp ) 'conditional)
+     (t 'section-data))))
+
+(defun haskell-cabal-header-p ()
+  "Is the current line a section or subsection header?"
+  (cl-case (haskell-cabal-classify-line)
+    ((section-header subsection-header) t)))
+
+(defun haskell-cabal-section-header-p ()
+  "Is the current line a section or subsection header?"
+  (cl-case (haskell-cabal-classify-line)
+    ((section-header) t)))
+
+
+(defun haskell-cabal-section-beginning ()
+  "Find the beginning of the current section"
+  (save-excursion
+    (while (not (or (bobp) (haskell-cabal-section-header-p)))
+      (forward-line -1))
+    (point)))
+
+(defun haskell-cabal-beginning-of-section ()
+  "go to the beginning of the section"
+  (interactive)
+  (goto-char (haskell-cabal-section-beginning))
+)
+
+(defun haskell-cabal-section-end ()
+  "Find the end of the current section"
+  (interactive)
+  (save-excursion
+    (if (re-search-forward "\n\\([ \t]*\n\\)*[[:alnum:]]" nil t)
+        (match-beginning 0)
+        (point-max))))
+
+(defun haskell-cabal-end-of-section ()
+  "go to the end of the section"
+  (interactive)
+  (goto-char (haskell-cabal-section-end)))
+
+(defun haskell-cabal-next-section ()
+  "Go to the next section"
+  (interactive)
+  (when (haskell-cabal-section-header-p) (forward-line))
+  (while (not (or (eobp) (haskell-cabal-section-header-p)))
+    (forward-line)))
+
+(defun haskell-cabal-previous-section ()
+  "Go to the next section"
+  (interactive)
+  (when (haskell-cabal-section-header-p) (forward-line -1))
+  (while (not (or (bobp) (haskell-cabal-section-header-p)))
+    (forward-line -1)))
+
+(defun haskell-cabal-subsection-end ()
+  "find the end of the current subsection"
+  (save-excursion
+    (haskell-cabal-beginning-of-subsection)
+    (forward-line)
+    (while (and (not (eobp))
+                (member (haskell-cabal-classify-line) '(empty section-data)))
+      (forward-line))
+    (unless (eobp) (forward-line -1))
+    (while (and (equal (haskell-cabal-classify-line) 'empty)
+                (not (bobp)))
+      (forward-line -1))
+    (end-of-line)
+    (point)))
+
+(defun haskell-cabal-end-of-subsection ()
+  "go to the end of the current subsection"
+  (interactive)
+  (goto-char (haskell-cabal-subsection-end)))
+
+(defun haskell-cabal-section ()
+  "Get the name and data of the associated section"
+  (save-excursion
+    (haskell-cabal-beginning-of-section)
+    (when (and (haskell-cabal-section-header-p)
+               (looking-at "^\\(\\w+\\)[ \t]*\\(.*\\)$"))
+      (list :name (match-string-no-properties 1)
+            :value (match-string-no-properties 2)
+            :beginning (match-beginning 0)
+            :end (haskell-cabal-section-end)))))
+
+
+(defun haskell-cabal-subsection ()
+  "Get the name and bounds of of the current subsection"
+  (save-excursion
+    (haskell-cabal-beginning-of-subsection)
+    (when (looking-at "\\([ \t]*\\(\\w*\\):\\)[ \t]*")
+      (list :name (match-string-no-properties 2)
+            :beginning (match-end 0)
+            :end (save-match-data (haskell-cabal-subsection-end))
+            :data-start-column (save-excursion (goto-char (match-end 0))
+                                               (current-column)
+                                               )))))
+
+
+(defun haskell-cabal-section-name (section)
+  (plist-get section :name))
+
+(defun haskell-cabal-section-value (section)
+  (plist-get section :value))
+
+(defun haskell-cabal-section-start (section)
+  (plist-get section :beginning))
+
+(defun haskell-cabal-section-data-start-column (section)
+  (plist-get section :data-start-column))
+
+(defun haskell-cabal-map-component-type (component-type)
+  "Map from cabal file COMPONENT-TYPE to build command component-type."
+  (let ((component-type (downcase component-type)))
+    (cond ((equal component-type "executable") "exe")
+          ((equal component-type "test-suite") "test")
+          ((equal component-type "benchmark")  "bench"))))
+
+(defun haskell-cabal-enum-targets (&optional process-type)
+  "Enumerate .cabal targets. PROCESS-TYPE determines the format of the returned target."
+  (let ((cabal-file (haskell-cabal-find-file))
+        (process-type (if process-type process-type 'ghci)))
+    (when (and cabal-file (file-readable-p cabal-file))
+      (with-temp-buffer
+        (insert-file-contents cabal-file)
+        (haskell-cabal-mode)
+        (goto-char (point-min))
+        (let ((matches)
+              (package-name (haskell-cabal--get-field "name")))
+          (haskell-cabal-next-section)
+          (while (not (eobp))
+            (if (haskell-cabal-source-section-p (haskell-cabal-section))
+                (let* ((section (haskell-cabal-section))
+                       (component-type (haskell-cabal-section-name section))
+                       (val (car (split-string
+                                  (haskell-cabal-section-value section)))))
+                  (if (equal (downcase component-type) "library")
+                      (let ((lib-target (if (eq 'stack-ghci process-type)
+                                            (concat package-name ":lib")
+                                          (concat "lib:" package-name))))
+                        (push lib-target matches))
+                    (push (concat  (when (eq 'stack-ghci process-type)
+                                     (concat package-name ":"))
+                                   (haskell-cabal-map-component-type component-type)
+                                   ":"
+                                   val)
+                          matches))))
+            (haskell-cabal-next-section))
+          (reverse matches))))))
+
+(defmacro haskell-cabal-with-subsection (subsection replace &rest funs)
+  "Copy subsection data into a temporary buffer, save indentation
+and execute FORMS
+
+If REPLACE is non-nil the subsection data is replaced with the
+resulting buffer-content"
+  (let ((section (make-symbol "section"))
+        (beg (make-symbol "beg"))
+        (end (make-symbol "end"))
+        (start-col (make-symbol "start-col"))
+        (section-data (make-symbol "section-data")))
+    `(let* ((,section ,subsection)
+            (,beg (plist-get ,section :beginning))
+            (,end (plist-get ,section :end))
+            (,start-col (plist-get ,section :data-start-column))
+            (,section-data (buffer-substring ,beg ,end)))
+       (save-excursion
+         (prog1
+             (with-temp-buffer
+               (setq indent-tabs-mode nil)
+               (indent-to ,start-col)
+               (insert ,section-data)
+               (goto-char (point-min))
+               (prog1
+                   (progn (haskell-cabal-save-indentation ,@funs))
+                 (goto-char (point-min))
+                 (when (looking-at (format "[ ]\\{0,%d\\}" (1+ ,start-col)))
+                     (replace-match ""))
+
+                 (setq ,section-data (buffer-substring (point-min) (point-max)))))
+           ,@(when replace
+               `((delete-region ,beg ,end)
+                 (goto-char ,beg)
+                 (insert ,section-data))))))))
+
+(defmacro haskell-cabal-each-line (&rest fun)
+  "Execute FORMS on each line"
+  `(save-excursion
+     (while (< (point) (point-max))
+       ,@fun
+       (forward-line))))
+
+(defun haskell-cabal-chomp-line ()
+  "Remove leading and trailing whitespaces from current line"
+  (beginning-of-line)
+  (when (looking-at "^[ \t]*\\([^ \t]\\|\\(?:[^ \t].*[^ \t]\\)\\)[ \t]*$")
+    (replace-match (match-string 1) nil t)
+    t))
+
+
+(defun haskell-cabal-min-indentation (&optional beg end)
+  "Compute largest common whitespace prefix of each line in between BEG and END"
+  (save-excursion
+    (goto-char (or beg (point-min)))
+    (let ((min-indent nil))
+      (while (< (point) (or end (point-max)))
+        (let ((indent (current-indentation)))
+          (if (and (not (haskell-cabal-ignore-line-p))
+                   (or (not min-indent)
+                       (< indent min-indent)))
+              (setq min-indent indent)))
+        (forward-line))
+      min-indent)))
+
+(defun haskell-cabal-ignore-line-p ()
+  "Does line only contain whitespaces and comments?"
+  (save-excursion
+    (beginning-of-line)
+    (looking-at "^[ \t]*\\(?:--.*\\)?$")))
+
+(defun haskell-cabal-kill-indentation ()
+  "Remove longest common whitespace prefix from each line"
+  (goto-char (point-min))
+  (let ((indent (haskell-cabal-min-indentation)))
+    (haskell-cabal-each-line (unless (haskell-cabal-ignore-line-p)
+                               (delete-char indent)) )
+    indent))
+
+(defun haskell-cabal-add-indentation (indent)
+  (goto-char (point-min))
+  (haskell-cabal-each-line
+   (unless (haskell-cabal-ignore-line-p)
+     (indent-to indent))))
+
+
+(defmacro haskell-cabal-save-indentation (&rest funs)
+  "Strip indentation from each line, execute FORMS and reinstate indentation
+   so that the indentation of the FIRST LINE matches"
+  (let ((old-l1-indent (make-symbol "new-l1-indent"))
+        (new-l1-indent (make-symbol "old-l1-indent")))
+    `(let ( (,old-l1-indent (save-excursion
+                              (goto-char (point-min))
+                              (current-indentation))))
+       (unwind-protect
+           (progn
+             (haskell-cabal-kill-indentation)
+             ,@funs)
+         (progn
+           (goto-char (point-min))
+           (let ((,new-l1-indent (current-indentation)))
+             (haskell-cabal-add-indentation (- ,old-l1-indent
+                                           ,new-l1-indent))))))))
+
+(defun haskell-cabal-comma-separatorp (pos)
+  "Return non-nil when the char at POS is a comma separator.
+Characters that are not a comma, or commas inside a commment or
+string, are not comma separators."
+  (when (eq (char-after pos) ?,)
+    (let ((ss (syntax-ppss pos)))
+      (not
+       (or
+        ;; inside a string
+        (nth 3 ss)
+        ;; inside a comment
+        (nth 4 ss))))))
+
+(defun haskell-cabal-strip-list-and-detect-style ()
+  "Strip commas from a comma-separated list.
+Detect and return the comma style.  The possible options are:
+
+before: a comma at the start of each line (except the first), e.g.
+    Foo
+  , Bar
+
+after: a comma at the end of each line (except the last), e.g.
+    Foo,
+    Bar
+
+single: everything on a single line, but comma-separated, e.g.
+    Foo, Bar
+
+nil: no commas, e.g.
+    Foo Bar
+
+If the styles are mixed, the position of the first comma
+determines the style. If there is only one element then `after'
+style is assumed."
+  (let (comma-style)
+    ;; split list items on single line
+    (goto-char (point-min))
+    (while (re-search-forward
+            "\\([^ \t,\n]\\)[ \t]*\\(,\\)[ \t]*\\([^ \t,\n]\\)" nil t)
+      (when (haskell-cabal-comma-separatorp (match-beginning 2))
+        (setq comma-style 'single)
+        (replace-match "\\1\n\\3" nil nil)))
+    ;; remove commas before
+    (goto-char (point-min))
+    (while (re-search-forward "^\\([ \t]*\\),\\([ \t]*\\)" nil t)
+      (setq comma-style 'before)
+      (replace-match "" nil nil))
+    ;; remove trailing commas
+    (goto-char (point-min))
+    (while (re-search-forward ",[ \t]*$" nil t)
+      (unless (eq comma-style 'before)
+        (setq comma-style 'after))
+      (replace-match "" nil nil))
+
+    ;; if there is just one line then set default as 'after
+    (unless comma-style
+      (goto-char (point-min))
+      (forward-line)
+      (when (eobp)
+        (setq comma-style 'after)))
+    (goto-char (point-min))
+
+    (haskell-cabal-each-line (haskell-cabal-chomp-line))
+    comma-style))
+
+(defun haskell-cabal-listify (comma-style)
+  "Add commas so that the buffer contains a comma-separated list.
+Respect the COMMA-STYLE, see
+`haskell-cabal-strip-list-and-detect-style' for the possible
+styles."
+  (cl-case comma-style
+    ('before
+     (goto-char (point-min))
+     (while (haskell-cabal-ignore-line-p) (forward-line))
+     (indent-to 2)
+     (forward-line)
+     (haskell-cabal-each-line
+      (unless (haskell-cabal-ignore-line-p)
+        (insert ", "))))
+    ('after
+     (goto-char (point-max))
+     (while (equal 0 (forward-line -1))
+       (unless (haskell-cabal-ignore-line-p)
+         (end-of-line)
+         (insert ",")
+         (beginning-of-line))))
+    ('single
+     (goto-char (point-min))
+     (while (not (eobp))
+       (end-of-line)
+       (unless (eobp)
+         (insert ", ")
+         (delete-char 1)
+         (just-one-space))))))
+
+(defmacro haskell-cabal-with-cs-list (&rest funs)
+  "Format the buffer so that each line contains a list element.
+Respect the comma style."
+  (let ((comma-style (make-symbol "comma-style")))
+    `(let ((,comma-style
+            (save-excursion
+              (haskell-cabal-strip-list-and-detect-style))))
+       (unwind-protect (progn ,@funs)
+         (haskell-cabal-listify ,comma-style)))))
+
+
+(defun haskell-cabal-sort-lines-key-fun ()
+  (when (looking-at "[ \t]*--[ \t,]*")
+    (goto-char (match-end 0)))
+  nil)
+
+(defmacro haskell-cabal-save-position (&rest forms)
+  "Save position as mark, execute FORMs and go back to mark"
+  `(prog2
+       (haskell-cabal-mark)
+       (progn ,@forms)
+     (haskell-cabal-goto-mark)
+     (haskell-cabal-remove-mark)))
+
+(defun haskell-cabal-sort-lines-depends-compare (key1 key2)
+  (let* ((key1str (buffer-substring (car key1) (cdr key1)))
+         (key2str (buffer-substring (car key2) (cdr key2)))
+         (base-regex "^[ \t]*base\\($\\|[^[:alnum:]-]\\)"))
+    (cond
+     ((string-match base-regex key1str) t)
+     ((string-match base-regex key2str) nil)
+     (t (string< key1str key2str)))))
+
+(defun haskell-cabal-subsection-arrange-lines ()
+  "Sort lines of current subsection"
+  (interactive)
+  (haskell-cabal-save-position
+   (let* ((subsection (haskell-cabal-section-name (haskell-cabal-subsection)))
+          (compare-lines (if (string= (downcase subsection) "build-depends")
+                            'haskell-cabal-sort-lines-depends-compare
+                          nil)))
+     (haskell-cabal-with-subsection
+      (haskell-cabal-subsection) t
+      (haskell-cabal-with-cs-list
+       (sort-subr nil 'forward-line 'end-of-line
+                  'haskell-cabal-sort-lines-key-fun
+                  'end-of-line
+                  compare-lines
+                  ))))))
+
+(defun haskell-cabal-subsection-beginning ()
+  "find the beginning of the current subsection"
+  (save-excursion
+    (while (and (not (bobp))
+                (not (haskell-cabal-header-p)))
+      (forward-line -1))
+    (back-to-indentation)
+    (point)))
+
+(defun haskell-cabal-beginning-of-subsection ()
+  "go to the beginning of the current subsection"
+  (interactive)
+  (goto-char (haskell-cabal-subsection-beginning)))
+
+(defun haskell-cabal-next-subsection ()
+  "go to the next subsection"
+  (interactive)
+  (if (haskell-cabal-header-p) (forward-line))
+  (while (and (not (eobp))
+              (not (haskell-cabal-header-p)))
+    (forward-line))
+  (haskell-cabal-forward-to-line-entry))
+
+(defun haskell-cabal-previous-subsection ()
+  "go to the previous subsection"
+  (interactive)
+  (if (haskell-cabal-header-p) (forward-line -1))
+  (while (and (not (bobp))
+              (not (haskell-cabal-header-p)))
+    (forward-line -1))
+  (haskell-cabal-forward-to-line-entry)
+  )
+
+
+(defun haskell-cabal-find-subsection-by (section pred)
+  "Find subsection with name NAME"
+  (save-excursion
+    (when section (goto-char (haskell-cabal-section-start section)))
+    (let* ((end (if section (haskell-cabal-section-end) (point-max)))
+           (found nil))
+      (while (and (< (point) end)
+                  (not found))
+        (let ((subsection (haskell-cabal-subsection)))
+          (when (and subsection (funcall pred subsection))
+            (setq found subsection)))
+        (haskell-cabal-next-subsection))
+      found)))
+
+(defun haskell-cabal-find-subsection (section name)
+  "Find subsection with name NAME"
+  (let ((downcase-name (downcase name)))
+    (haskell-cabal-find-subsection-by
+     section
+     `(lambda (subsection)
+        (string= (downcase (haskell-cabal-section-name subsection))
+                 ,downcase-name)))))
+
+(defun haskell-cabal-goto-subsection (name)
+  (let ((subsection (haskell-cabal-find-subsection (haskell-cabal-section) name)))
+    (when subsection
+      (goto-char (haskell-cabal-section-start subsection)))))
+
+(defun haskell-cabal-goto-exposed-modules ()
+  (interactive)
+  (haskell-cabal-goto-subsection "exposed-modules"))
+
+(defun haskell-cabal-subsection-entry-list (section name)
+  "Get the data of a subsection as a list"
+  (let ((subsection (haskell-cabal-find-subsection section name)))
+    (when subsection
+      (haskell-cabal-with-subsection
+       subsection nil
+       (haskell-cabal-with-cs-list
+        (delete-matching-lines
+         (format "\\(?:%s\\)\\|\\(?:%s\\)"
+                 haskell-cabal-comment-regexp
+                 haskell-cabal-empty-regexp)
+         (point-min) (point-max))
+        (split-string (buffer-substring-no-properties (point-min) (point-max))
+                      "\n" t))))))
+
+(defun haskell-cabal-remove-mark ()
+  (remove-list-of-text-properties (point-min) (point-max)
+                                  '(haskell-cabal-marker)))
+
+
+(defun haskell-cabal-mark ()
+  "Mark the current position with the text property haskell-cabal-marker"
+  (haskell-cabal-remove-mark)
+  (put-text-property (line-beginning-position) (line-end-position)
+                     'haskell-cabal-marker 'marked-line)
+  (put-text-property (point) (1+ (point))
+                     'haskell-cabal-marker 'marked))
+
+
+(defun haskell-cabal-goto-mark ()
+  "Go to marked line"
+  (let ((marked-pos (text-property-any (point-min) (point-max)
+                                       'haskell-cabal-marker
+                                       'marked))
+        (marked-line (text-property-any (point-min) (point-max)
+                                       'haskell-cabal-marker
+                                       'marked-line) )
+        )
+    (cond (marked-pos (goto-char marked-pos))
+          (marked-line (goto-char marked-line)))))
+
+(defmacro haskell-cabal-with-subsection-line (replace &rest forms)
+  "Mark line, copy subsection data into a temporary buffer, save indentation
+and execute FORMS at the marked line.
+
+If REPLACE is non-nil the subsection data is replaced with the
+resulting buffer-content.  Unmark line at the end."
+  `(progn
+     (haskell-cabal-mark)
+     (unwind-protect
+         (haskell-cabal-with-subsection (haskell-cabal-subsection) ,replace
+          (haskell-cabal-goto-mark)
+          ,@forms)
+       (haskell-cabal-remove-mark))))
+
+
+(defun haskell-cabal-get-line-content ()
+  (haskell-cabal-with-subsection-line
+   nil
+   (haskell-cabal-with-cs-list
+    (haskell-cabal-goto-mark)
+    (buffer-substring-no-properties (line-beginning-position)
+                                    (line-end-position)))))
+
+(defun haskell-cabal-module-to-filename (module)
+  (concat (replace-regexp-in-string "[.]" "/" module ) ".hs"))
+
+(defconst haskell-cabal-module-sections '("exposed-modules" "other-modules")
+  "List of sections that contain module names"
+)
+
+(defconst haskell-cabal-file-sections
+  '("main-is" "c-sources" "data-files" "extra-source-files"
+    "extra-doc-files" "extra-tmp-files" )
+  "List of subsections that contain filenames"
+  )
+
+(defconst haskell-cabal-source-bearing-sections
+  '("library" "executable" "test-suite" "benchmark"))
+
+(defun haskell-cabal-source-section-p (section)
+  (not (not (member (downcase (haskell-cabal-section-name section))
+                    haskell-cabal-source-bearing-sections))))
+
+(defun haskell-cabal-line-filename ()
+  "Expand filename in current line according to the subsection type
+
+Module names in exposed-modules and other-modules are expanded by replacing each dot (.) in the module name with a foward slash (/) and appending \".hs\"
+
+Example: Foo.Bar.Quux ==> Foo/Bar/Quux.hs
+
+Source names from main-is and c-sources sections are left untouched
+
+"
+  (let ((entry (haskell-cabal-get-line-content))
+        (subsection (downcase (haskell-cabal-section-name
+                               (haskell-cabal-subsection)))))
+    (cond ((member subsection haskell-cabal-module-sections)
+           (haskell-cabal-module-to-filename entry))
+          ((member subsection haskell-cabal-file-sections) entry))))
+
+(defun haskell-cabal-join-paths (&rest args)
+  "Crude hack to replace f-join"
+  (mapconcat 'identity args "/")
+)
+
+(defun haskell-cabal-find-or-create-source-file ()
+  "Open the source file this line refers to."
+  (interactive)
+  (let* ((src-dirs (append (haskell-cabal-subsection-entry-list
+                            (haskell-cabal-section) "hs-source-dirs")
+                           '("")))
+         (base-dir (file-name-directory (buffer-file-name)))
+         (filename (haskell-cabal-line-filename)))
+    (when filename
+      (let ((candidates
+             (delq nil (mapcar
+                        (lambda (dir)
+                          (let ((file (haskell-cabal-join-paths base-dir
+                                                                dir
+                                                                filename)))
+                            (when (and (file-readable-p file)
+                                       (not (file-directory-p file)))
+                              file)))
+                        src-dirs))))
+        (if (null candidates)
+            (unwind-protect
+                (progn
+                  (haskell-mode-toggle-interactive-prompt-state)
+                  (let* ((src-dir
+                          (haskell-cabal-join-paths base-dir
+                                                    (or (car src-dirs) "")))
+                         (newfile (haskell-cabal-join-paths src-dir filename))
+                         (do-create-p (y-or-n-p (format "Create file %s ?" newfile))))
+                    (when do-create-p
+                      (find-file-other-window newfile ))))
+              (haskell-mode-toggle-interactive-prompt-state t))
+          (find-file-other-window (car candidates)))))))
+
+
+(defun haskell-cabal-find-section-type (type &optional wrap)
+  (save-excursion
+    (haskell-cabal-next-section)
+    (while
+        (not
+         (or
+          (eobp)
+          (string=
+           (downcase type)
+           (downcase (haskell-cabal-section-name (haskell-cabal-section))))))
+      (haskell-cabal-next-section))
+    (if (eobp)
+      (if wrap (progn
+                 (goto-char (point-min))
+                 (haskell-cabal-find-section-type type nil) )
+        nil)
+      (point))))
+
+(defun haskell-cabal-goto-section-type (type)
+  (let ((section (haskell-cabal-find-section-type type t)))
+    (if section (goto-char section)
+      (message "No %s section found" type))))
+
+(defun haskell-cabal-goto-library-section ()
+  (interactive)
+  (haskell-cabal-goto-section-type "library"))
+
+(defun haskell-cabal-goto-test-suite-section ()
+  (interactive)
+  (haskell-cabal-goto-section-type "test-suite"))
+
+(defun haskell-cabal-goto-executable-section ()
+  (interactive)
+  (haskell-cabal-goto-section-type "executable"))
+
+(defun haskell-cabal-goto-benchmark-section ()
+  (interactive)
+  (haskell-cabal-goto-section-type "benchmark"))
+
+
+
+(defun haskell-cabal-line-entry-column ()
+  "Column at which the line entry starts"
+  (save-excursion
+    (cl-case (haskell-cabal-classify-line)
+      (section-data (beginning-of-line)
+                    (when (looking-at "[ ]*\\(?:,[ ]*\\)?")
+                      (goto-char (match-end 0))
+                      (current-column)))
+      (subsection-header
+       (haskell-cabal-section-data-start-column (haskell-cabal-subsection))))))
+
+(defun haskell-cabal-forward-to-line-entry ()
+  "go forward to the beginning of the line entry (but never move backwards)"
+  (let ((col (haskell-cabal-line-entry-column)))
+    (when (and col (< (current-column) col))
+      (beginning-of-line)
+      (forward-char col))))
+
+(defun haskell-cabal-indent-line ()
+  "Indent current line according to subsection"
+  (interactive)
+  (cl-case (haskell-cabal-classify-line)
+    (section-data
+     (save-excursion
+       (let ((indent (haskell-cabal-section-data-start-column
+                      (haskell-cabal-subsection))))
+         (indent-line-to indent)
+         (beginning-of-line)
+         (when (looking-at "[ ]*\\([ ]\\{2\\},[ ]*\\)")
+           (replace-match ", " t t nil 1)))))
+    (empty
+     (indent-relative)))
+  (haskell-cabal-forward-to-line-entry))
+
+(defun haskell-cabal-map-sections (fun)
+  "Execute fun over each section, collecting the result"
+  (save-excursion
+    (goto-char (point-min))
+    (let ((results nil))
+        (while (not (eobp))
+          (let* ((section (haskell-cabal-section))
+                 (result (and section (funcall fun (haskell-cabal-section)))))
+            (when section (setq results (cons result results))))
+          (haskell-cabal-next-section))
+        (nreverse results))))
+
+(defun haskell-cabal-section-add-build-dependency (dependency &optional sort sec)
+  "Add a build dependency to the build-depends section"
+  (let* ((section (or sec (haskell-cabal-section)))
+         (subsection (and section
+                          (haskell-cabal-find-subsection section "build-depends"))))
+    (when subsection
+      (haskell-cabal-with-subsection
+       subsection t
+       (haskell-cabal-with-cs-list
+        (insert dependency)
+        (insert "\n")
+        (when sort
+          (goto-char (point-min))
+          (sort-subr nil 'forward-line 'end-of-line
+                     'haskell-cabal-sort-lines-key-fun)))))))
+
+(defun haskell-cabal-add-build-dependency (dependency &optional sort silent)
+  "Add the given DEPENDENCY to every section in cabal file.
+If SORT argument is given sort dependencies in section after update.
+Pass SILENT argument to update all sections without asking user."
+  (haskell-cabal-map-sections
+   (lambda (section)
+     (when (haskell-cabal-source-section-p section)
+       (unwind-protect
+           (progn
+             (when
+                 (or silent
+                     (y-or-n-p (format "Add dependency %s to %s section %s?"
+                                       dependency
+                                       (haskell-cabal-section-name section)
+                                       (haskell-cabal-section-value section))))
+               (haskell-cabal-section-add-build-dependency dependency
+                                                           sort
+                                                           section))
+             nil)
+         (haskell-mode-toggle-interactive-prompt-state t))))))
+
+(defun haskell-cabal-add-dependency
+    (package &optional version no-prompt sort silent)
+  "Add PACKAGE to the cabal file.
+If VERSION is non-nil it will be appended as a minimum version.
+If NO-PROMPT is nil the minimum package version is read from the
+minibuffer.  When SORT is non-nil the package entries are sorted
+afterwards.  If SILENT is non-nil the user is prompted for each
+source-section."
+  (interactive
+   (list (read-from-minibuffer "Package entry: ") nil t t nil))
+  (haskell-mode-toggle-interactive-prompt-state)
+  (unwind-protect
+      (save-window-excursion
+        (find-file-other-window (haskell-cabal-find-file))
+        (let ((entry (if no-prompt package
+                       (read-from-minibuffer
+                        "Package entry: "
+                        (concat package
+                                (if version (concat " >= " version) ""))))))
+          (haskell-cabal-add-build-dependency entry sort silent)
+          (when (or silent (y-or-n-p "Save cabal file? "))
+            (save-buffer))))
+    ;; unwind
+    (haskell-mode-toggle-interactive-prompt-state t)))
+
+
+(defun haskell-cabal--find-tags-dir ()
+  "Return a directory where TAGS file will be generated.
+Tries to find cabal file first and if succeeds uses its location.
+If cabal file not found uses current file directory.  If current
+buffer not visiting a file returns nil."
+  (or (haskell-cabal-find-dir)
+      (when buffer-file-name
+        (file-name-directory buffer-file-name))))
+
+(defun haskell-cabal--compose-hasktags-command (dir)
+  "Prepare command to execute `hasktags` command in DIR folder.
+
+To customise the command executed, see `haskell-hasktags-path'
+and `haskell-hasktags-arguments'.
+
+This function takes into account the user's operating system: in case
+of Windows it generates a simple command, relying on Hasktags
+itself to find source files:
+
+hasktags --output=DIR\TAGS -x -e DIR
+
+In other cases it uses `find` command to find all source files
+recursively avoiding visiting unnecessary heavy directories like
+.git, .svn, _darcs and build directories created by
+cabal-install, stack, etc and passes list of found files to Hasktags."
+  (if (eq system-type 'windows-nt)
+      (format "%s --output=%s %s %s"
+              haskell-hasktags-path
+              (shell-quote-argument (expand-file-name "TAGS" dir))
+              (mapconcat #'identity haskell-hasktags-arguments " ")
+              (shell-quote-argument dir))
+    (format "cd %s && %s | %s"
+            (shell-quote-argument dir)
+            (concat "find . "
+                    "-type d \\( "
+                    "-path ./.git "
+                    "-o -path ./.svn "
+                    "-o -path ./_darcs "
+                    "-o -path ./.stack-work "
+                    "-o -path ./dist "
+                    "-o -path ./.cabal-sandbox "
+                    "\\) -prune "
+                    "-o -type f \\( "
+                    "-name '*.hs' "
+                    "-or -name '*.lhs' "
+                    "-or -name '*.hsc' "
+                    "\\) -not \\( "
+                    "-name '#*' "
+                    "-or -name '.*' "
+                    "\\) -print0")
+            (format "xargs -0 %s %s"
+                    (shell-quote-argument haskell-hasktags-path)
+                    (mapconcat #'identity haskell-hasktags-arguments " ")))))
+
+(provide 'haskell-cabal)
+;;; haskell-cabal.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-cabal.elc b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-cabal.elc
new file mode 100644
index 0000000000..7609bc3bc1
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-cabal.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-collapse.el b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-collapse.el
new file mode 100644
index 0000000000..8a73fa3887
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-collapse.el
@@ -0,0 +1,114 @@
+;;; haskell-collapse.el --- Collapse expressions -*- lexical-binding: t -*-
+
+;; Copyright (c) 2014 Chris Done. All rights reserved.
+;; Copyright (c) 2017 Vasantha Ganesh Kanniappan <vasanthaganesh.k@tuta.io>.
+
+;; This file 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, or (at your option)
+;; any later version.
+
+;; This file 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Code:
+
+(require 'hideshow)
+
+;;; TODO:
+;;; -> Make it work for braces
+
+(defun haskell-hide-toggle ()
+  "Toggle visibility of existing forms at point. "
+  (interactive)
+  (hs-minor-mode 1)
+  (save-excursion
+    (let* ((modified (buffer-modified-p))
+           (inhibit-read-only t)
+           (position (haskell-indented-block))
+           (beg (car position))
+           (end (cdr position)))
+      (if (and beg end)
+          (if (overlays-in beg end)
+              (hs-discard-overlays beg end)
+            (hs-make-overlay beg end 'code)))
+      (set-buffer-modified-p modified))))
+
+(defun haskell-blank-line-p ()
+  "Returns `t' if line is empty or composed only of whitespace."
+  (save-excursion
+    (beginning-of-line)
+    (= (point-at-eol)
+       (progn (skip-chars-forward "[:blank:]") (point)))))
+
+(defun haskell-indented-block ()
+  "return (start-of-indentation . end-of-indentation)"
+  (let ((cur-indent (current-indentation))
+        (nxt-line-indent (haskell-next-line-indentation 1))
+        (prev-line-indent (haskell-next-line-indentation -1))
+        (beg-of-line (save-excursion (end-of-line)
+                                     (point))))
+    (cond ((and (= cur-indent 0)
+                (= nxt-line-indent 0)) nil)
+          ((haskell-blank-line-p) nil)
+          ((> nxt-line-indent cur-indent)
+           (cons beg-of-line
+                 (haskell-find-line-with-indentation '> 1)))
+          ((or (= nxt-line-indent cur-indent)
+               (<= prev-line-indent cur-indent))
+           (cons (haskell-find-line-with-indentation '>= -1)
+                 (haskell-find-line-with-indentation '>= 1)))
+          (t nil))))
+
+(defun haskell-next-line-indentation (dir)
+  "returns (integer) indentation of the next if dir=1, previous line
+indentation if dir=-1"
+  (save-excursion
+    (progn
+      (while (and (zerop (forward-line dir))
+                  (haskell-blank-line-p)))
+      (current-indentation))))
+
+(defun haskell-find-line-with-indentation (comparison direction)
+  "comparison is >= or >, direction if 1 finds forward, if -1 finds backward"
+  (save-excursion
+    (let ((start-indent (current-indentation)))
+      (progn
+        (while (and (zerop (forward-line direction))
+                    (or (haskell-blank-line-p)
+                        (funcall comparison (current-indentation) start-indent))))
+        (when (= direction 1) (forward-line -1))
+        (end-of-line)
+        (point)))))
+
+(defun haskell-hide-toggle-all ()
+  "hides all top level functions"
+  (interactive)
+  (save-excursion
+    (goto-char (point-max))
+    (while (zerop (forward-line -1))
+      (goto-char (point-at-bol))
+      (when (= (current-indentation) 0) (haskell-hide-toggle)))))
+
+(defvar haskell-collapse-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "C-c @ C-c") 'haskell-hide-toggle)
+    (define-key map (kbd "C-c @ C-M-c") 'haskell-hide-toggle-all)
+    (define-key map (kbd "C-c @ C-M-s") 'haskell-hide-toggle-all)
+    (define-key map (kbd "C-c @ C-M-h") 'haskell-hide-toggle-all)
+    map)
+  "Keymap for using `haskell-collapse-mode'.")
+
+;;;###autoload
+(define-minor-mode haskell-collapse-mode
+  "Minor mode to collapse and expand haskell expressions"
+  :init-value nil
+  :lighter " Haskell-Collapse"
+  :keymap haskell-collapse-mode-map)
+
+(provide 'haskell-collapse)
diff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-collapse.elc b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-collapse.elc
new file mode 100644
index 0000000000..2d6b9b8286
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-collapse.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-commands.el b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-commands.el
new file mode 100644
index 0000000000..b0898553d2
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-commands.el
@@ -0,0 +1,961 @@
+;;; haskell-commands.el --- Commands that can be run on the process -*- lexical-binding: t -*-
+
+;;; Commentary:
+
+;;; This module provides varoius `haskell-mode' and `haskell-interactive-mode'
+;;; specific commands such as show type signature, show info, haskell process
+;;; commands and etc.
+
+;; Copyright © 2014 Chris Done.  All rights reserved.
+;;             2016 Arthur Fayzrakhmanov
+
+;; This file 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, or (at your option)
+;; any later version.
+
+;; This file 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'etags)
+(require 'haskell-mode)
+(require 'haskell-compat)
+(require 'haskell-process)
+(require 'haskell-font-lock)
+(require 'haskell-interactive-mode)
+(require 'haskell-session)
+(require 'haskell-string)
+(require 'haskell-presentation-mode)
+(require 'haskell-utils)
+(require 'highlight-uses-mode)
+(require 'haskell-cabal)
+
+(defcustom haskell-mode-stylish-haskell-path "stylish-haskell"
+  "Path to `stylish-haskell' executable."
+  :group 'haskell
+  :type 'string)
+
+(defcustom haskell-interactive-set-+c
+  t
+  "Issue ':set +c' in interactive session to support type introspection."
+  :group 'haskell-interactive
+  :type 'boolean)
+
+;;;###autoload
+(defun haskell-process-restart ()
+  "Restart the inferior Haskell process."
+  (interactive)
+  (haskell-process-reset (haskell-interactive-process))
+  (haskell-process-set (haskell-interactive-process) 'command-queue nil)
+  (haskell-process-start (haskell-interactive-session)))
+
+(defun haskell-process-start (session)
+  "Start the inferior Haskell process with a given SESSION.
+You can create new session using function `haskell-session-make'."
+  (let ((existing-process (get-process (haskell-session-name (haskell-interactive-session)))))
+    (when (processp existing-process)
+      (haskell-interactive-mode-echo session "Restarting process ...")
+      (haskell-process-set (haskell-session-process session) 'is-restarting t)
+      (delete-process existing-process)))
+  (let ((process (or (haskell-session-process session)
+                     (haskell-process-make (haskell-session-name session))))
+        (old-queue (haskell-process-get (haskell-session-process session)
+                                        'command-queue)))
+    (haskell-session-set-process session process)
+    (haskell-process-set-session process session)
+    (haskell-process-set-cmd process nil)
+    (haskell-process-set (haskell-session-process session) 'is-restarting nil)
+    (let ((default-directory (haskell-session-cabal-dir session))
+          (log-and-command (haskell-process-compute-process-log-and-command session (haskell-process-type))))
+      (haskell-session-prompt-set-current-dir session (not haskell-process-load-or-reload-prompt))
+      (haskell-process-set-process
+       process
+       (progn
+         (haskell-process-log (propertize (format "%S" log-and-command)))
+         (apply #'start-process (cdr log-and-command)))))
+    (progn (set-process-sentinel (haskell-process-process process) 'haskell-process-sentinel)
+           (set-process-filter (haskell-process-process process) 'haskell-process-filter))
+    (haskell-process-send-startup process)
+    (unless (or (eq 'cabal-repl (haskell-process-type))
+                (eq 'cabal-new-repl (haskell-process-type))
+                   (eq 'stack-ghci (haskell-process-type))) ;; Both "cabal repl" and "stack ghci" set the proper CWD.
+      (haskell-process-change-dir session
+                                  process
+                                  (haskell-session-current-dir session)))
+    (haskell-process-set process 'command-queue
+                         (append (haskell-process-get (haskell-session-process session)
+                                                      'command-queue)
+                                 old-queue))
+    process))
+
+(defun haskell-process-send-startup (process)
+  "Send the necessary start messages to haskell PROCESS."
+  (haskell-process-queue-command
+   process
+   (make-haskell-command
+    :state process
+
+    :go (lambda (process)
+          ;; We must set the prompt last, so that this command as a
+          ;; whole produces only one prompt marker as a response.
+          (haskell-process-send-string process
+                                       (mapconcat #'identity
+                                                  (append '("Prelude.putStrLn \"\""
+                                                            ":set -v1")
+                                                          (when haskell-interactive-set-+c
+                                                            '(":set +c"))) ; :type-at in GHC 8+
+                                                  "\n"))
+          (haskell-process-send-string process ":set prompt \"\\4\"")
+          (haskell-process-send-string process (format ":set prompt2 \"%s\""
+                                                       haskell-interactive-prompt2)))
+
+    :live (lambda (process buffer)
+            (when (haskell-process-consume
+                   process
+                   "^\*\*\* WARNING: \\(.+\\) is writable by someone else, IGNORING!$")
+              (let ((path (match-string 1 buffer)))
+                (haskell-session-modify
+                 (haskell-process-session process)
+                 'ignored-files
+                 (lambda (files)
+                   (cl-remove-duplicates (cons path files) :test 'string=)))
+                (haskell-interactive-mode-compile-warning
+                 (haskell-process-session process)
+                 (format "GHCi is ignoring: %s (run M-x haskell-process-unignore)"
+                         path)))))
+
+    :complete (lambda (process _)
+                (haskell-interactive-mode-echo
+                 (haskell-process-session process)
+                 (concat (nth (random (length haskell-process-greetings))
+                              haskell-process-greetings)
+                         (when haskell-process-show-debug-tips
+                           "
+If I break, you can:
+  1. Restart:           M-x haskell-process-restart
+  2. Configure logging: C-h v haskell-process-log (useful for debugging)
+  3. General config:    M-x customize-mode
+  4. Hide these tips:   C-h v haskell-process-show-debug-tips")))
+                (with-current-buffer (haskell-interactive-buffer)
+                  (goto-char haskell-interactive-mode-prompt-start))))))
+
+(defun haskell-commands-process ()
+  "Get the Haskell session, throws an error if not available."
+  (or (haskell-session-process (haskell-session-maybe))
+      (error "No Haskell session/process associated with this
+      buffer. Maybe run M-x haskell-session-change?")))
+
+;;;###autoload
+(defun haskell-process-clear ()
+  "Clear the current process."
+  (interactive)
+  (haskell-process-reset (haskell-commands-process))
+  (haskell-process-set (haskell-commands-process) 'command-queue nil))
+
+;;;###autoload
+(defun haskell-process-interrupt ()
+  "Interrupt the process (SIGINT)."
+  (interactive)
+  (interrupt-process (haskell-process-process (haskell-commands-process))))
+
+(defun haskell-process-reload-with-fbytecode (process module-buffer)
+  "Query a PROCESS to reload MODULE-BUFFER with -fbyte-code set.
+Restores -fobject-code after reload finished.
+MODULE-BUFFER is the actual Emacs buffer of the module being loaded."
+  (haskell-process-queue-without-filters process ":set -fbyte-code")
+  ;; We prefix the module's filename with a "*", which asks ghci to
+  ;; ignore any existing object file and interpret the module.
+  ;; Dependencies will still use their object files as usual.
+  (haskell-process-queue-without-filters
+   process
+   (format ":load \"*%s\""
+           (replace-regexp-in-string
+            "\""
+            "\\\\\""
+            (buffer-file-name module-buffer))))
+  (haskell-process-queue-without-filters process ":set -fobject-code"))
+
+(defvar url-http-response-status)
+(defvar url-http-end-of-headers)
+(defvar haskell-cabal-targets-history nil
+  "History list for session targets.")
+
+(defun haskell-process-hayoo-ident (ident)
+  "Hayoo for IDENT, return a list of modules"
+  ;; We need a real/simulated closure, because otherwise these
+  ;; variables will be unbound when the url-retrieve callback is
+  ;; called.
+  ;; TODO: Remove when this code is converted to lexical bindings by
+  ;; default (Emacs 24.1+)
+  (let ((url (format haskell-process-hayoo-query-url (url-hexify-string ident))))
+    (with-current-buffer (url-retrieve-synchronously url)
+      (if (= 200 url-http-response-status)
+          (progn
+            (goto-char url-http-end-of-headers)
+            (let* ((res (json-read))
+                   (results (assoc-default 'result res)))
+              ;; TODO: gather packages as well, and when we choose a
+              ;; given import, check that we have the package in the
+              ;; cabal file as well.
+              (cl-mapcan (lambda (r)
+                           ;; append converts from vector -> list
+                           (append (assoc-default 'resultModules r) nil))
+                         results)))
+        (warn "HTTP error %s fetching %s" url-http-response-status url)))))
+
+(defun haskell-process-hoogle-ident (ident)
+  "Hoogle for IDENT, return a list of modules."
+  (with-temp-buffer
+    (let ((hoogle-error (call-process "hoogle" nil t nil "search" "--exact" ident)))
+      (goto-char (point-min))
+      (unless (or (/= 0 hoogle-error)
+                  (looking-at "^No results found")
+                  (looking-at "^package "))
+        (while (re-search-forward "^\\([^ ]+\\).*$" nil t)
+          (replace-match "\\1" nil nil))
+        (cl-remove-if (lambda (a) (string= "" a))
+                      (split-string (buffer-string)
+                                    "\n"))))))
+
+(defun haskell-process-haskell-docs-ident (ident)
+  "Search with haskell-docs for IDENT, return a list of modules."
+  (cl-remove-if-not
+   (lambda (a) (string-match "^[[:upper:]][[:alnum:]_'.]+$" a))
+   (split-string
+      (with-output-to-string
+        (with-current-buffer
+            standard-output
+          (call-process "haskell-docs"
+                        nil             ; no infile
+                        t               ; output to current buffer (that is string)
+                        nil             ; do not redisplay
+                        "--modules" ident)))
+      "\n")))
+
+(defun haskell-process-import-modules (process modules)
+  "Query PROCESS `:m +' command to import MODULES."
+  (when haskell-process-auto-import-loaded-modules
+    (haskell-process-queue-command
+     process
+     (make-haskell-command
+      :state (cons process modules)
+      :go (lambda (state)
+            (haskell-process-send-string
+             (car state)
+             (format ":m + %s" (mapconcat 'identity (cdr state) " "))))))))
+
+;;;###autoload
+(defun haskell-describe (ident)
+  "Describe the given identifier IDENT."
+  (interactive (list (read-from-minibuffer "Describe identifier: "
+                                           (haskell-ident-at-point))))
+  (let ((results (read (shell-command-to-string
+                        (concat "haskell-docs --sexp "
+                                ident)))))
+    (help-setup-xref (list #'haskell-describe ident)
+                     (called-interactively-p 'interactive))
+    (save-excursion
+      (with-help-window (help-buffer)
+        (with-current-buffer (help-buffer)
+          (if results
+              (cl-loop for result in results
+                       do (insert (propertize ident 'font-lock-face
+                                              '((:inherit font-lock-type-face
+                                                          :underline t)))
+                                  " is defined in "
+                                  (let ((module (cadr (assoc 'module result))))
+                                    (if module
+                                        (concat module " ")
+                                      ""))
+                                  (cadr (assoc 'package result))
+                                  "\n\n")
+                       do (let ((type (cadr (assoc 'type result))))
+                            (when type
+                              (insert (haskell-fontify-as-mode type 'haskell-mode)
+                                      "\n")))
+                       do (let ((args (cadr (assoc 'type results))))
+                            (cl-loop for arg in args
+                                     do (insert arg "\n"))
+                            (insert "\n"))
+                       do (insert (cadr (assoc 'documentation result)))
+                       do (insert "\n\n"))
+            (insert "No results for " ident)))))))
+
+;;;###autoload
+(defun haskell-rgrep (&optional prompt)
+  "Grep the effective project for the symbol at point.
+Very useful for codebase navigation.
+
+Prompts for an arbitrary regexp given a prefix arg PROMPT."
+  (interactive "P")
+  (let ((sym (if prompt
+                 (read-from-minibuffer "Look for: ")
+               (haskell-ident-at-point))))
+    (rgrep sym
+           "*.hs *.lhs *.hsc *.chs *.hs-boot *.lhs-boot"
+           (haskell-session-current-dir (haskell-interactive-session)))))
+
+;;;###autoload
+(defun haskell-process-do-info (&optional prompt-value)
+  "Print info on the identifier at point.
+If PROMPT-VALUE is non-nil, request identifier via mini-buffer."
+  (interactive "P")
+  (let ((at-point (haskell-ident-at-point)))
+    (when (or prompt-value at-point)
+      (let* ((ident (replace-regexp-in-string
+                     "^!\\([A-Z_a-z]\\)"
+                     "\\1"
+                     (if prompt-value
+                         (read-from-minibuffer "Info: " at-point)
+                       at-point)))
+             (modname (unless prompt-value
+                        (haskell-utils-parse-import-statement-at-point)))
+             (command (cond
+                       (modname
+                        (format ":browse! %s" modname))
+                       ((string= ident "") ; For the minibuffer input case
+                        nil)
+                       (t (format (if (string-match "^[a-zA-Z_]" ident)
+                                      ":info %s"
+                                    ":info (%s)")
+                                  (or ident
+                                      at-point))))))
+        (when command
+          (haskell-process-show-repl-response command))))))
+
+;;;###autoload
+(defun haskell-process-do-type (&optional insert-value)
+  "Print the type of the given expression.
+
+Given INSERT-VALUE prefix indicates that result type signature
+should be inserted."
+  (interactive "P")
+  (if insert-value
+      (haskell-process-insert-type)
+    (let* ((expr
+            (if (use-region-p)
+                (buffer-substring-no-properties (region-beginning) (region-end))
+              (haskell-ident-at-point)))
+           (expr-okay (and expr
+                         (not (string-match-p "\\`[[:space:]]*\\'" expr))
+                         (not (string-match-p "\n" expr)))))
+      ;; No newlines in expressions, and surround with parens if it
+      ;; might be a slice expression
+      (when expr-okay
+        (haskell-process-show-repl-response
+         (format
+          (if (or (string-match-p "\\`(" expr)
+                  (string-match-p "\\`[_[:alpha:]]" expr))
+              ":type %s"
+            ":type (%s)")
+          expr))))))
+
+;;;###autoload
+(defun haskell-mode-jump-to-def-or-tag (&optional _next-p)
+  ;; FIXME NEXT-P arg is not used
+  "Jump to the definition.
+Jump to definition of identifier at point by consulting GHCi, or
+tag table as fallback.
+
+Remember: If GHCi is busy doing something, this will delay, but
+it will always be accurate, in contrast to tags, which always
+work but are not always accurate.
+If the definition or tag is found, the location from which you jumped
+will be pushed onto `xref--marker-ring', so you can return to that
+position with `xref-pop-marker-stack'."
+  (interactive "P")
+  (if (haskell-session-maybe)
+        (let ((initial-loc (point-marker))
+            (loc (haskell-mode-find-def (haskell-ident-at-point))))
+          (haskell-mode-handle-generic-loc loc)
+          (unless (equal initial-loc (point-marker))
+            (xref-push-marker-stack initial-loc)))
+      (call-interactively 'haskell-mode-tag-find)))
+
+;;;###autoload
+(defun haskell-mode-goto-loc ()
+  "Go to the location of the thing at point.
+Requires the :loc-at command from GHCi."
+  (interactive)
+  (let ((loc (haskell-mode-loc-at)))
+    (when loc
+      (haskell-mode-goto-span loc))))
+
+(defun haskell-mode-goto-span (span)
+  "Jump to the SPAN, whatever file and line and column it needs to get there."
+  (xref-push-marker-stack)
+  (find-file (expand-file-name (plist-get span :path)
+                               (haskell-session-cabal-dir (haskell-interactive-session))))
+  (goto-char (point-min))
+  (forward-line (1- (plist-get span :start-line)))
+  (forward-char (plist-get span :start-col)))
+
+(defun haskell-process-insert-type ()
+  "Get the identifier at the point and insert its type.
+Use GHCi's :type if it's possible."
+  (let ((ident (haskell-ident-at-point)))
+    (when ident
+      (let ((process (haskell-interactive-process))
+            (query (format (if (string-match "^[_[:lower:][:upper:]]" ident)
+                               ":type %s"
+                             ":type (%s)")
+                           ident)))
+        (haskell-process-queue-command
+         process
+         (make-haskell-command
+          :state (list process query (current-buffer))
+          :go (lambda (state)
+                (haskell-process-send-string (nth 0 state)
+                                             (nth 1 state)))
+          :complete (lambda (state response)
+                      (cond
+                       ;; TODO: Generalize this into a function.
+                       ((or (string-match "^Top level" response)
+                            (string-match "^<interactive>" response))
+                        (message "%s" response))
+                       (t
+                        (with-current-buffer (nth 2 state)
+                          (goto-char (line-beginning-position))
+                          (insert (format "%s\n" (replace-regexp-in-string "\n$" "" response)))))))))))))
+
+(defun haskell-mode-find-def (ident)
+  ;; TODO Check if it possible to exploit `haskell-process-do-info'
+  "Find definition location of identifier IDENT.
+Uses the GHCi process to find the location.  Returns nil if it
+can't find the identifier or the identifier isn't a string.
+
+Returns:
+
+    (library <package> <module>)
+    (file <path> <line> <col>)
+    (module <name>)
+    nil"
+  (when (stringp ident)
+    (let ((reply (haskell-process-queue-sync-request
+                  (haskell-interactive-process)
+                  (format (if (string-match "^[a-zA-Z_]" ident)
+                              ":info %s"
+                            ":info (%s)")
+                          ident))))
+      (let ((match (string-match "-- Defined \\(at\\|in\\) \\(.+\\)$" reply)))
+        (when match
+          (let ((defined (match-string 2 reply)))
+            (let ((match (string-match "\\(.+?\\):\\([0-9]+\\):\\([0-9]+\\)$" defined)))
+              (cond
+               (match
+                (list 'file
+                      (expand-file-name (match-string 1 defined)
+                                        (haskell-session-current-dir (haskell-interactive-session)))
+                      (string-to-number (match-string 2 defined))
+                      (string-to-number (match-string 3 defined))))
+               (t
+                (let ((match (string-match "`\\(.+?\\):\\(.+?\\)'$" defined)))
+                  (if match
+                      (list 'library
+                            (match-string 1 defined)
+                            (match-string 2 defined))
+                    (let ((match (string-match "`\\(.+?\\)'$" defined)))
+                      (if match
+                          (list 'module
+                                (match-string 1 defined)))))))))))))))
+
+;;;###autoload
+(defun haskell-mode-jump-to-def (ident)
+  "Jump to definition of identifier IDENT at point."
+  (interactive
+   (list
+    (haskell-string-drop-qualifier
+     (haskell-ident-at-point))))
+  (let ((loc (haskell-mode-find-def ident)))
+    (when loc
+      (haskell-mode-handle-generic-loc loc))))
+
+(defun haskell-mode-handle-generic-loc (loc)
+  "Either jump to or echo a generic location LOC.
+Either a file or a library."
+  (cl-case (car loc)
+    (file (progn
+              (find-file (elt loc 1))
+              (goto-char (point-min))
+              (forward-line (1- (elt loc 2)))
+              (goto-char (+ (line-beginning-position)
+                            (1- (elt loc 3))))))
+    (library (message "Defined in `%s' (%s)."
+                      (elt loc 2)
+                      (elt loc 1)))
+    (module (message "Defined in `%s'."
+                     (elt loc 1)))))
+
+(defun haskell-mode-loc-at ()
+  "Get the location at point.
+Requires the :loc-at command from GHCi."
+  (let ((pos (or (when (region-active-p)
+                   (cons (region-beginning)
+                         (region-end)))
+                 (haskell-spanable-pos-at-point)
+                 (cons (point)
+                       (point)))))
+    (when pos
+      (let ((reply (haskell-process-queue-sync-request
+                    (haskell-interactive-process)
+                    (save-excursion
+                      (format ":loc-at %s %d %d %d %d %s"
+                              (buffer-file-name)
+                              (progn (goto-char (car pos))
+                                     (line-number-at-pos))
+                              (1+ (current-column)) ;; GHC uses 1-based columns.
+                              (progn (goto-char (cdr pos))
+                                     (line-number-at-pos))
+                              (1+ (current-column)) ;; GHC uses 1-based columns.
+                              (buffer-substring-no-properties (car pos)
+                                                              (cdr pos)))))))
+        (if reply
+            (if (string-match "\\(.*?\\):(\\([0-9]+\\),\\([0-9]+\\))-(\\([0-9]+\\),\\([0-9]+\\))"
+                              reply)
+                (list :path (match-string 1 reply)
+                      :start-line (string-to-number (match-string 2 reply))
+                      ;; ;; GHC uses 1-based columns.
+                      :start-col (1- (string-to-number (match-string 3 reply)))
+                      :end-line (string-to-number (match-string 4 reply))
+                      ;; GHC uses 1-based columns.
+                      :end-col (1- (string-to-number (match-string 5 reply))))
+              (error (propertize reply 'face 'compilation-error)))
+          (error (propertize "No reply. Is :loc-at supported?"
+                             'face 'compilation-error)))))))
+
+;;;###autoload
+(defun haskell-process-cd (&optional _not-interactive)
+  ;; FIXME optional arg is not used
+  "Change directory."
+  (interactive)
+  (let* ((session (haskell-interactive-session))
+         (dir (haskell-session-prompt-set-current-dir session)))
+    (haskell-process-log
+     (propertize (format "Changing directory to %s ...\n" dir)
+                 'face font-lock-comment-face))
+    (haskell-process-change-dir session
+                                (haskell-interactive-process)
+                                dir)))
+
+(defun haskell-session-buffer-default-dir (session &optional buffer)
+  "Try to deduce a sensible default directory for SESSION and BUFFER,
+of which the latter defaults to the current buffer."
+  (or (haskell-session-get session 'current-dir)
+      (haskell-session-get session 'cabal-dir)
+      (if (buffer-file-name buffer)
+          (file-name-directory (buffer-file-name buffer))
+          "~/")))
+
+(defun haskell-session-prompt-set-current-dir (session &optional use-default)
+  "Prompt for the current directory.
+Return current working directory for SESSION."
+  (let ((default (haskell-session-buffer-default-dir session)))
+    (haskell-session-set-current-dir
+     session
+     (if use-default
+         default
+         (haskell-utils-read-directory-name "Set current directory: " default))))
+  (haskell-session-get session 'current-dir))
+
+(defun haskell-process-change-dir (session process dir)
+  "Change SESSION's current directory.
+Query PROCESS to `:cd` to directory DIR."
+  (haskell-process-queue-command
+   process
+   (make-haskell-command
+    :state (list session process dir)
+    :go
+    (lambda (state)
+      (haskell-process-send-string
+       (cadr state) (format ":cd %s" (cl-caddr state))))
+
+    :complete
+    (lambda (state _)
+      (haskell-session-set-current-dir (car state) (cl-caddr state))
+      (haskell-interactive-mode-echo (car state)
+                                     (format "Changed directory: %s"
+                                             (cl-caddr state)))))))
+
+;;;###autoload
+(defun haskell-process-cabal-macros ()
+  "Send the cabal macros string."
+  (interactive)
+  (haskell-process-queue-without-filters (haskell-interactive-process)
+                                         ":set -optP-include -optPdist/build/autogen/cabal_macros.h"))
+
+(defun haskell-process-do-try-info (sym)
+  "Get info of SYM and echo in the minibuffer."
+  (let ((process (haskell-interactive-process)))
+    (haskell-process-queue-command
+     process
+     (make-haskell-command
+      :state (cons process sym)
+      :go (lambda (state)
+            (haskell-process-send-string
+             (car state)
+             (if (string-match "^[A-Za-z_]" (cdr state))
+                 (format ":info %s" (cdr state))
+               (format ":info (%s)" (cdr state)))))
+      :complete (lambda (_state response)
+                  (unless (or (string-match "^Top level" response)
+                              (string-match "^<interactive>" response))
+                    (haskell-mode-message-line response)))))))
+
+(defun haskell-process-do-try-type (sym)
+  "Get type of SYM and echo in the minibuffer."
+  (let ((process (haskell-interactive-process)))
+    (haskell-process-queue-command
+     process
+     (make-haskell-command
+      :state (cons process sym)
+      :go (lambda (state)
+            (haskell-process-send-string
+             (car state)
+             (if (string-match "^[A-Za-z_]" (cdr state))
+                 (format ":type %s" (cdr state))
+               (format ":type (%s)" (cdr state)))))
+      :complete (lambda (_state response)
+                  (unless (or (string-match "^Top level" response)
+                              (string-match "^<interactive>" response))
+                    (haskell-mode-message-line response)))))))
+
+;;;###autoload
+(defun haskell-mode-show-type-at (&optional insert-value)
+  "Show type of the thing at point or within active region asynchronously.
+This function requires GHCi 8+ or GHCi-ng.
+
+\\<haskell-interactive-mode-map>
+To make this function works sometimes you need to load the file in REPL
+first using command `haskell-process-load-file' bound to
+\\[haskell-process-load-file].
+
+Optional argument INSERT-VALUE indicates that
+recieved type signature should be inserted (but only if nothing
+happened since function invocation)."
+  (interactive "P")
+  (let* ((pos (haskell-command-capture-expr-bounds))
+         (req (haskell-utils-compose-type-at-command pos))
+         (process (haskell-interactive-process))
+         (buf (current-buffer))
+         (pos-reg (cons pos (region-active-p))))
+    (haskell-process-queue-command
+     process
+     (make-haskell-command
+      :state (list process req buf insert-value pos-reg)
+      :go
+      (lambda (state)
+        (let* ((prc (car state))
+               (req (nth 1 state)))
+          (haskell-utils-async-watch-changes)
+          (haskell-process-send-string prc req)))
+      :complete
+      (lambda (state response)
+        (let* ((init-buffer (nth 2 state))
+               (insert-value (nth 3 state))
+               (pos-reg (nth 4 state))
+               (wrap (cdr pos-reg))
+               (min-pos (caar pos-reg))
+               (max-pos (cdar pos-reg))
+               (sig (haskell-utils-reduce-string response))
+               (res-type (haskell-utils-repl-response-error-status sig)))
+
+          (cl-case res-type
+            ;; neither popup presentation buffer
+            ;; nor insert response in error case
+            ('unknown-command
+             (message "This command requires GHCi 8+ or GHCi-ng. Please read command description for details."))
+            ('option-missing
+             (message "Could not infer type signature. You need to load file first. Also :set +c is required, see customization `haskell-interactive-set-+c'. Please read command description for details."))
+            ('interactive-error (message "Wrong REPL response: %s" sig))
+            (otherwise
+             (if insert-value
+                 ;; Only insert type signature and do not present it
+                 (if (= (length haskell-utils-async-post-command-flag) 1)
+                     (if wrap
+                         ;; Handle region case
+                         (progn
+                           (deactivate-mark)
+                           (save-excursion
+                             (delete-region min-pos max-pos)
+                             (goto-char min-pos)
+                             (insert (concat "(" sig ")"))))
+                       ;; Non-region cases
+                       (haskell-command-insert-type-signature sig))
+                   ;; Some commands registered, prevent insertion
+                   (message "Type signature insertion was prevented. These commands were registered: %s"
+                            (cdr (reverse haskell-utils-async-post-command-flag))))
+               ;; Present the result only when response is valid and not asked
+               ;; to insert result
+               (haskell-command-echo-or-present response)))
+
+            (haskell-utils-async-stop-watching-changes init-buffer))))))))
+
+(make-obsolete 'haskell-process-generate-tags
+               'haskell-mode-generate-tags
+               "2016-03-14")
+(defun haskell-process-generate-tags (&optional and-then-find-this-tag)
+  "Regenerate the TAGS table.
+If optional AND-THEN-FIND-THIS-TAG argument is present it is used with
+function `xref-find-definitions' after new table was generated."
+  (interactive)
+  (let ((process (haskell-interactive-process)))
+    (haskell-process-queue-command
+     process
+     (make-haskell-command
+      :state (cons process and-then-find-this-tag)
+      :go
+      (lambda (state)
+        (let* ((process (car state))
+               (cabal-dir (haskell-session-cabal-dir
+                           (haskell-process-session process)))
+               (command (haskell-cabal--compose-hasktags-command cabal-dir)))
+          (haskell-process-send-string process command)))
+      :complete (lambda (state _response)
+                  (when (cdr state)
+                    (let ((tags-file-name
+                           (haskell-session-tags-filename
+                            (haskell-process-session (car state)))))
+                      (xref-find-definitions (cdr state))))
+                  (haskell-mode-message-line "Tags generated."))))))
+
+(defun haskell-process-add-cabal-autogen ()
+  "Add cabal's autogen dir to the GHCi search path.
+Add <cabal-project-dir>/dist/build/autogen/ to GHCi seatch path.
+This allows modules such as 'Path_...', generated by cabal, to be
+loaded by GHCi."
+  (unless (or (eq 'cabal-repl (haskell-process-type))
+              (eq 'cabal-new-repl (haskell-process-type))) ;; redundant with "cabal repl"
+    (let*
+        ((session       (haskell-interactive-session))
+         (cabal-dir     (haskell-session-cabal-dir session))
+         (ghci-gen-dir  (format "%sdist/build/autogen/" cabal-dir)))
+      (haskell-process-queue-without-filters
+       (haskell-interactive-process)
+       (format ":set -i%s" ghci-gen-dir)))))
+
+;;;###autoload
+(defun haskell-process-unignore ()
+  "Unignore any ignored files.
+Do not ignore files that were specified as being ignored by the
+inferior GHCi process."
+  (interactive)
+  (let ((session (haskell-interactive-session))
+        (changed nil))
+    (if (null (haskell-session-get session 'ignored-files))
+        (message "Nothing to unignore!")
+      (cl-loop for file in (haskell-session-get session 'ignored-files)
+               do
+               (haskell-mode-toggle-interactive-prompt-state)
+               (unwind-protect
+                   (progn
+                     (cl-case
+                         (read-event
+                          (propertize
+                           (format "Set permissions? %s (y, n, v: stop and view file)"
+                                   file)
+                           'face
+                           'minibuffer-prompt))
+                       (?y
+                        (haskell-process-unignore-file session file)
+                        (setq changed t))
+                       (?v
+                        (find-file file)
+                        (cl-return)))
+                     (when (and changed
+                                (y-or-n-p "Restart GHCi process now? "))
+                       (haskell-process-restart)))
+                 ;; unwind
+                 (haskell-mode-toggle-interactive-prompt-state t))))))
+
+;;;###autoload
+(defun haskell-session-change-target (target)
+  "Set the build TARGET for cabal REPL."
+  (interactive
+   (list
+    (completing-read "New build target: "
+                     (haskell-cabal-enum-targets (haskell-process-type))
+                     nil
+                     nil
+                     nil
+                     'haskell-cabal-targets-history)))
+  (let* ((session haskell-session)
+         (old-target (haskell-session-get session 'target)))
+    (when session
+      (haskell-session-set-target session target)
+      (when (not (string= old-target target))
+        (haskell-mode-toggle-interactive-prompt-state)
+        (unwind-protect
+            (when (y-or-n-p "Target changed, restart haskell process?")
+              (haskell-process-start session)))
+        (haskell-mode-toggle-interactive-prompt-state t)))))
+
+;;;###autoload
+(defun haskell-mode-stylish-buffer ()
+  "Apply stylish-haskell to the current buffer.
+
+Use `haskell-mode-stylish-haskell-path' to know where to find
+stylish-haskell executable. This function tries to preserve
+cursor position and markers by using
+`haskell-mode-buffer-apply-command'."
+  (interactive)
+  (haskell-mode-buffer-apply-command haskell-mode-stylish-haskell-path))
+
+(defun haskell-mode-buffer-apply-command (cmd)
+  "Execute shell command CMD with current buffer as input and output.
+Use buffer as input and replace the whole buffer with the
+output.  If CMD fails the buffer remains unchanged."
+  (set-buffer-modified-p t)
+  (let* ((out-file (make-temp-file "stylish-output"))
+         (err-file (make-temp-file "stylish-error")))
+        (unwind-protect
+          (let* ((_errcode
+                  (call-process-region (point-min) (point-max) cmd nil
+                                       `((:file ,out-file) ,err-file)
+                                       nil))
+                 (err-file-empty-p
+                  (equal 0 (nth 7 (file-attributes err-file))))
+                 (out-file-empty-p
+                  (equal 0 (nth 7 (file-attributes out-file)))))
+            (if err-file-empty-p
+                (if out-file-empty-p
+                    (message "Error: %s produced no output and no error information, leaving buffer alone" cmd)
+                  ;; Command successful, insert file with replacement to preserve
+                  ;; markers.
+                  (insert-file-contents out-file nil nil nil t))
+              (progn
+                ;; non-null stderr, command must have failed
+                (with-current-buffer
+                    (get-buffer-create "*haskell-mode*")
+                  (insert-file-contents err-file)
+                  (buffer-string))
+                (message "Error: %s ended with errors, leaving buffer alone, see *haskell-mode* buffer for stderr" cmd)
+                (with-temp-buffer
+                  (insert-file-contents err-file)
+                  ;; use (warning-minimum-level :debug) to see this
+                  (display-warning cmd
+                                   (buffer-substring-no-properties (point-min) (point-max))
+                                   :debug)))))
+          (ignore-errors
+            (delete-file err-file))
+          (ignore-errors
+            (delete-file out-file)))))
+
+;;;###autoload
+(defun haskell-mode-find-uses ()
+  "Find use cases of the identifier at point and highlight them all."
+  (interactive)
+  (let ((spans (haskell-mode-uses-at)))
+    (unless (null spans)
+      (highlight-uses-mode 1)
+      (cl-loop for span in spans
+               do (haskell-mode-make-use-highlight span)))))
+
+(defun haskell-mode-make-use-highlight (span)
+  "Make a highlight overlay at the given SPAN."
+  (save-window-excursion
+    (save-excursion
+      (haskell-mode-goto-span span)
+      (save-excursion
+        (highlight-uses-mode-highlight
+         (progn
+           (goto-char (point-min))
+           (forward-line (1- (plist-get span :start-line)))
+           (forward-char (plist-get span :start-col))
+           (point))
+         (progn
+           (goto-char (point-min))
+           (forward-line (1- (plist-get span :end-line)))
+           (forward-char (plist-get span :end-col))
+           (point)))))))
+
+(defun haskell-mode-uses-at ()
+  "Get the locations of use cases for the ident at point.
+Requires the :uses command from GHCi."
+  (let ((pos (or (when (region-active-p)
+                   (cons (region-beginning)
+                         (region-end)))
+                 (haskell-ident-pos-at-point)
+                 (cons (point)
+                       (point)))))
+    (when pos
+      (let ((reply (haskell-process-queue-sync-request
+                    (haskell-interactive-process)
+                    (save-excursion
+                      (format ":uses %s %d %d %d %d %s"
+                              (buffer-file-name)
+                              (progn (goto-char (car pos))
+                                     (line-number-at-pos))
+                              (1+ (current-column)) ;; GHC uses 1-based columns.
+                              (progn (goto-char (cdr pos))
+                                     (line-number-at-pos))
+                              (1+ (current-column)) ;; GHC uses 1-based columns.
+                              (buffer-substring-no-properties (car pos)
+                                                              (cdr pos)))))))
+        (if reply
+            (let ((lines (split-string reply "\n" t)))
+              (cl-remove-if
+               #'null
+               (mapcar (lambda (line)
+                         (if (string-match "\\(.*?\\):(\\([0-9]+\\),\\([0-9]+\\))-(\\([0-9]+\\),\\([0-9]+\\))"
+                                           line)
+                             (list :path (match-string 1 line)
+                                   :start-line (string-to-number (match-string 2 line))
+                                   ;; ;; GHC uses 1-based columns.
+                                   :start-col (1- (string-to-number (match-string 3 line)))
+                                   :end-line (string-to-number (match-string 4 line))
+                                   ;; GHC uses 1-based columns.
+                                   :end-col (1- (string-to-number (match-string 5 line))))
+                           (error (propertize line 'face 'compilation-error))))
+                       lines)))
+          (error (propertize "No reply. Is :uses supported?"
+                             'face 'compilation-error)))))))
+
+(defun haskell-command-echo-or-present (msg)
+  "Present message in some manner depending on configuration.
+If variable `haskell-process-use-presentation-mode' is NIL it will output
+modified message MSG to echo area."
+  (if haskell-process-use-presentation-mode
+      (let ((session (haskell-process-session (haskell-interactive-process))))
+        (haskell-presentation-present session msg))
+    (let ((m (haskell-utils-reduce-string msg)))
+      (message "%s" m))))
+
+(defun haskell-command-capture-expr-bounds ()
+  "Capture position bounds of expression at point.
+If there is an active region then it returns region
+bounds.  Otherwise it uses `haskell-spanable-pos-at-point` to
+capture identifier bounds.  If latter function returns NIL this function
+will return cons cell where min and max positions both are equal
+to point."
+  (or (when (region-active-p)
+        (cons (region-beginning)
+              (region-end)))
+      (haskell-spanable-pos-at-point)
+      (cons (point) (point))))
+
+(defun haskell-command-insert-type-signature (signature)
+  "Insert type signature.
+In case of active region is present, wrap it by parentheses and
+append SIGNATURE to original expression.  Otherwise tries to
+carefully insert SIGNATURE above identifier at point.  Removes
+newlines and extra whitespace in signature before insertion."
+  (let* ((ident-pos (or (haskell-ident-pos-at-point)
+                        (cons (point) (point))))
+         (min-pos (car ident-pos))
+         (sig (haskell-utils-reduce-string signature)))
+    (save-excursion
+      (goto-char min-pos)
+      (let ((col (current-column)))
+        (insert sig "\n")
+        (indent-to col)))))
+
+(provide 'haskell-commands)
+;;; haskell-commands.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-commands.elc b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-commands.elc
new file mode 100644
index 0000000000..d236651b7c
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-commands.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-compat.el b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-compat.el
new file mode 100644
index 0000000000..c023ca6075
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-compat.el
@@ -0,0 +1,65 @@
+;;; haskell-compat.el --- legacy/compatibility backports for haskell-mode -*- lexical-binding: t -*-
+;;
+;; Filename: haskell-compat.el
+;; Description: legacy/compatibility backports for haskell-mode
+
+;; This file is not part of GNU Emacs.
+
+;; This file 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, or (at your option)
+;; any later version.
+
+;; This file 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;; Code:
+(require 'etags)
+(require 'ring)
+(require 'outline)
+(require 'xref nil t)
+
+(eval-when-compile
+  (setq byte-compile-warnings '(not cl-functions obsolete)))
+
+
+;; Cross-referencing commands have been replaced since Emacs 25.1.
+;; These aliases are required to provide backward compatibility.
+(unless (fboundp 'xref-push-marker-stack)
+  (defalias 'xref-pop-marker-stack 'pop-tag-mark)
+
+  (defun xref-push-marker-stack (&optional m)
+    "Add point M (defaults to `point-marker') to the marker stack."
+    (ring-insert find-tag-marker-ring (or m (point-marker)))))
+
+(unless (fboundp 'outline-hide-sublevels)
+  (defalias 'outline-hide-sublevels 'hide-sublevels))
+
+(unless (fboundp 'outline-show-subtree)
+  (defalias 'outline-show-subtree 'show-subtree))
+
+(unless (fboundp 'outline-hide-sublevels)
+  (defalias 'outline-hide-sublevels 'hide-sublevels))
+
+(unless (fboundp 'outline-show-subtree)
+  (defalias 'outline-show-subtree 'show-subtree))
+
+(unless (fboundp 'xref-find-definitions)
+  (defun xref-find-definitions (ident)
+    (let ((next-p (and (boundp 'xref-prompt-for-identifier)
+                       xref-prompt-for-identifier)))
+      (find-tag ident next-p))))
+
+(unless (fboundp 'font-lock-ensure)
+  (defalias 'font-lock-ensure 'font-lock-fontify-buffer))
+
+(provide 'haskell-compat)
+
+;;; haskell-compat.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-compat.elc b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-compat.elc
new file mode 100644
index 0000000000..c07ad194cd
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-compat.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-compile.el b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-compile.el
new file mode 100644
index 0000000000..2f4224032a
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-compile.el
@@ -0,0 +1,154 @@
+;;; haskell-compile.el --- Haskell/GHC compilation sub-mode -*- lexical-binding: t -*-
+
+;; Copyright (C) 2013  Herbert Valerio Riedel
+
+;; Author: Herbert Valerio Riedel <hvr@gnu.org>
+
+;; This file is not part of GNU Emacs.
+
+;; This file 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.
+
+;; This file 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Simple GHC-centric compilation sub-mode; see info node
+;; `(haskell-mode)compilation' for more information
+
+;;; Code:
+
+(require 'compile)
+(require 'haskell-cabal)
+
+;;;###autoload
+(defgroup haskell-compile nil
+  "Settings for Haskell compilation mode"
+  :link '(custom-manual "(haskell-mode)compilation")
+  :group 'haskell)
+
+(defcustom haskell-compile-cabal-build-command
+  "cd %s && cabal build --ghc-option=-ferror-spans"
+  "Default build command to use for `haskell-cabal-build' when a cabal file is detected.
+The `%s' placeholder is replaced by the cabal package top folder."
+  :group 'haskell-compile
+  :type 'string)
+
+(defcustom haskell-compile-cabal-build-alt-command
+  "cd %s && cabal clean -s && cabal build --ghc-option=-ferror-spans"
+  "Alternative build command to use when `haskell-cabal-build' is called with a negative prefix argument.
+The `%s' placeholder is replaced by the cabal package top folder."
+  :group 'haskell-compile
+  :type 'string)
+
+(defcustom haskell-compile-command
+  "ghc -Wall -ferror-spans -fforce-recomp -c %s"
+  "Default build command to use for `haskell-cabal-build' when no cabal file is detected.
+The `%s' placeholder is replaced by the current buffer's filename."
+  :group 'haskell-compile
+  :type 'string)
+
+(defcustom haskell-compile-ghc-filter-linker-messages
+  t
+  "Filter out unremarkable \"Loading package...\" linker messages during compilation."
+  :group 'haskell-compile
+  :type 'boolean)
+
+(defconst haskell-compilation-error-regexp-alist
+  `((,(concat
+       "^ *\\(?1:[^\t\r\n]+?\\):"
+       "\\(?:"
+       "\\(?2:[0-9]+\\):\\(?4:[0-9]+\\)\\(?:-\\(?5:[0-9]+\\)\\)?" ;; "121:1" & "12:3-5"
+       "\\|"
+       "(\\(?2:[0-9]+\\),\\(?4:[0-9]+\\))-(\\(?3:[0-9]+\\),\\(?5:[0-9]+\\))" ;; "(289,5)-(291,36)"
+       "\\)"
+       ":\\(?6:\n?[ \t]+[Ww]arning:\\)?")
+     1 (2 . 3) (4 . 5) (6 . nil)) ;; error/warning locus
+
+    ;; multiple declarations
+    ("^    \\(?:Declared at:\\|            \\) \\(?1:[^ \t\r\n]+\\):\\(?2:[0-9]+\\):\\(?4:[0-9]+\\)$"
+     1 2 4 0) ;; info locus
+
+    ;; this is the weakest pattern as it's subject to line wrapping et al.
+    (" at \\(?1:[^ \t\r\n]+\\):\\(?2:[0-9]+\\):\\(?4:[0-9]+\\)\\(?:-\\(?5:[0-9]+\\)\\)?[)]?$"
+     1 2 (4 . 5) 0)) ;; info locus
+  "Regexps used for matching GHC compile messages.
+See `compilation-error-regexp-alist' for semantics.")
+
+(defvar haskell-compilation-mode-map
+  (let ((map (make-sparse-keymap)))
+    (set-keymap-parent map compilation-mode-map))
+  "Keymap for `haskell-compilation-mode' buffers.
+This is a child of `compilation-mode-map'.")
+
+(defun haskell-compilation-filter-hook ()
+  "Local `compilation-filter-hook' for `haskell-compilation-mode'."
+
+  (when haskell-compile-ghc-filter-linker-messages
+    (delete-matching-lines "^ *Loading package [^ \t\r\n]+ [.]+ linking [.]+ done\\.$"
+                           (save-excursion (goto-char compilation-filter-start)
+                                           (line-beginning-position))
+                           (point))))
+
+(define-compilation-mode haskell-compilation-mode "HsCompilation"
+  "Haskell/GHC specific `compilation-mode' derivative.
+This mode provides support for GHC 7.[46]'s compile
+messages. Specifically, also the `-ferror-spans` source location
+format is supported, as well as info-locations within compile
+messages pointing to additional source locations."
+  (setq-local compilation-error-regexp-alist
+              haskell-compilation-error-regexp-alist)
+
+  (add-hook 'compilation-filter-hook
+            'haskell-compilation-filter-hook nil t)
+  )
+
+;;;###autoload
+(defun haskell-compile (&optional edit-command)
+  "Compile the Haskell program including the current buffer.
+Tries to locate the next cabal description in current or parent
+folders via `haskell-cabal-find-dir' and if found, invoke
+`haskell-compile-cabal-build-command' from the cabal package root
+folder. If no cabal package could be detected,
+`haskell-compile-command' is used instead.
+
+If prefix argument EDIT-COMMAND is non-nil (and not a negative
+prefix `-'), `haskell-compile' prompts for custom compile
+command.
+
+If EDIT-COMMAND contains the negative prefix argument `-',
+`haskell-compile' calls the alternative command defined in
+`haskell-compile-cabal-build-alt-command' if a cabal package was
+detected.
+
+`haskell-compile' uses `haskell-compilation-mode' which is
+derived from `compilation-mode'. See Info
+node `(haskell-mode)compilation' for more details."
+  (interactive "P")
+  (save-some-buffers (not compilation-ask-about-save)
+                         compilation-save-buffers-predicate)
+  (let* ((cabdir (haskell-cabal-find-dir))
+         (command1 (if (eq edit-command '-)
+                       haskell-compile-cabal-build-alt-command
+                     haskell-compile-cabal-build-command))
+         (srcname (buffer-file-name))
+         (command (if cabdir
+                      (format command1 cabdir)
+                    (if (and srcname (derived-mode-p 'haskell-mode))
+                        (format haskell-compile-command srcname)
+                      command1))))
+    (when (and edit-command (not (eq edit-command '-)))
+      (setq command (compilation-read-command command)))
+
+    (compilation-start command 'haskell-compilation-mode)))
+
+(provide 'haskell-compile)
+;;; haskell-compile.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-compile.elc b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-compile.elc
new file mode 100644
index 0000000000..a1626cc1cc
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-compile.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-complete-module.el b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-complete-module.el
new file mode 100644
index 0000000000..ce165348f7
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-complete-module.el
@@ -0,0 +1,131 @@
+;;; haskell-complete-module.el --- A fast way to complete Haskell module names -*- lexical-binding: t -*-
+
+;; Copyright (c) 2014 Chris Done. All rights reserved.
+
+;; This file 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, or (at your option)
+;; any later version.
+
+;; This file 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Code:
+
+(require 'cl-lib)
+
+(defcustom haskell-complete-module-preferred
+  '()
+  "Override ordering of module results by specifying preferred modules."
+  :group 'haskell
+  :type '(repeat string))
+
+(defcustom haskell-complete-module-max-display
+  10
+  "Maximum items to display in minibuffer."
+  :group 'haskell
+  :type 'number)
+
+(defun haskell-complete-module-read (prompt candidates)
+  "Interactively auto-complete from a list of candidates."
+  (let ((stack (list))
+        (pattern "")
+        (result nil))
+    (delete-dups candidates)
+    (setq candidates
+          (sort candidates
+                (lambda (a b)
+                  (let ((a-mem (member a haskell-complete-module-preferred))
+                        (b-mem (member b haskell-complete-module-preferred)))
+                    (cond
+                     ((and a-mem (not b-mem))
+                      t)
+                     ((and b-mem (not a-mem))
+                      nil)
+                     (t
+                      (string< a b)))))))
+    (while (not result)
+      (let ((key
+             (key-description
+              (vector
+               (read-key
+                (concat (propertize prompt 'face 'minibuffer-prompt)
+                        (propertize pattern 'face 'font-lock-type-face)
+                        "{"
+                        (mapconcat #'identity
+                                   (let* ((i 0))
+                                     (cl-loop for candidate in candidates
+                                              while (<= i haskell-complete-module-max-display)
+                                              do (cl-incf i)
+                                              collect (cond ((> i haskell-complete-module-max-display)
+                                                             "...")
+                                                            ((= i 1)
+                                                             (propertize candidate 'face 'ido-first-match-face))
+                                                            (t candidate))))
+                                   " | ")
+                        "}"))))))
+        (cond
+         ((string= key "C-g")
+          (keyboard-quit))
+         ((string= key "DEL")
+          (unless (null stack)
+            (setq candidates (pop stack)))
+          (unless (string= "" pattern)
+            (setq pattern (substring pattern 0 -1))))
+         ((string= key "RET")
+          (setq result (or (car candidates)
+                           pattern)))
+         ((string= key "<left>")
+          (setq candidates
+                (append (last candidates)
+                        (butlast candidates))))
+         ((string= key "<right>")
+          (setq candidates
+                (append (cdr candidates)
+                        (list (car candidates)))))
+         (t
+          (when (string-match "[A-Za-z0-9_'.]+" key)
+            (push candidates stack)
+            (setq pattern (concat pattern key))
+            (setq candidates (haskell-complete-module pattern candidates)))))))
+    result))
+
+(defun haskell-complete-module (pattern candidates)
+  "Filter the CANDIDATES using PATTERN."
+  (let ((case-fold-search t))
+    (cl-loop for candidate in candidates
+             when (haskell-complete-module-match pattern candidate)
+             collect candidate)))
+
+(defun haskell-complete-module-match (pattern text)
+  "Match PATTERN against TEXT."
+  (string-match (haskell-complete-module-regexp pattern)
+                text))
+
+(defun haskell-complete-module-regexp (pattern)
+  "Make a regular expression for the given module pattern. Example:
+
+\"c.m.s\" -> \"^c[^.]*\\.m[^.]*\\.s[^.]*\"
+
+"
+  (let ((components (mapcar #'haskell-complete-module-component
+                            (split-string pattern "\\." t))))
+    (concat "^"
+            (mapconcat #'identity
+                       components
+                       "\\."))))
+
+(defun haskell-complete-module-component (component)
+  "Make a regular expression for the given component. Example:
+
+\"co\" -> \"c[^.]*o[^.]*\"
+
+"
+  (replace-regexp-in-string "\\(.\\)" "\\1[^.]*" component))
+
+(provide 'haskell-complete-module)
diff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-complete-module.elc b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-complete-module.elc
new file mode 100644
index 0000000000..bb8c572f24
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-complete-module.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-completions.el b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-completions.el
new file mode 100644
index 0000000000..59d2e24130
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-completions.el
@@ -0,0 +1,393 @@
+;;; haskell-completions.el --- Haskell Completion package -*- lexical-binding: t -*-
+
+;; Copyright © 2015-2016 Athur Fayzrakhmanov. All rights reserved.
+
+;; This file is part of haskell-mode package.
+;; You can contact with authors using GitHub issue tracker:
+;; https://github.com/haskell/haskell-mode/issues
+
+;; This file 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, or (at your option)
+;; any later version.
+
+;; This file 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; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; This package provides completions related functionality for
+;; Haskell Mode such grab completion prefix at point, and etc..
+
+;; Some description
+;; ================
+;;
+;; For major use function `haskell-completions-grab-prefix' is supposed, and
+;; other prefix grabbing functions are used internally by it.  So, only this
+;; funciton have prefix minimal length functionality and invokes predicate
+;; function `haskell-completions-can-grab-prefix'.
+
+;;; Code:
+
+(require 'haskell-mode)
+(require 'haskell-process)
+(require 'haskell-interactive-mode)
+
+;;;###autoload
+(defgroup haskell-completions nil
+  "Settings for completions provided by `haskell-mode'"
+  :link '(custom-manual "(haskell-mode)Completion support")
+  :group 'haskell)
+
+(defcustom haskell-completions-complete-operators
+  t
+  "Should `haskell-completions-sync-repl-completion-at-point' complete operators.
+
+Note: GHCi prior to version 8.0.1 have bug in `:complete`
+ command: when completing operators it returns a list of all
+ imported identifiers (see Track ticket URL
+ `https://ghc.haskell.org/trac/ghc/ticket/10576'). This leads to
+ significant Emacs slowdown. To aviod slowdown you should set
+ this variable to `nil'."
+  :group 'haskell-completions
+  :type 'boolean)
+
+(defvar haskell-completions--pragma-names
+  (list "DEPRECATED"
+        "INCLUDE"
+        "INCOHERENT"
+        "INLINABLE"
+        "INLINE"
+        "LANGUAGE"
+        "LINE"
+        "MINIMAL"
+        "NOINLINE"
+        "NOUNPACK"
+        "OPTIONS"
+        "OPTIONS_GHC"
+        "OVERLAPPABLE"
+        "OVERLAPPING"
+        "OVERLAPS"
+        "RULES"
+        "SOURCE"
+        "SPECIALIZE"
+        "UNPACK"
+        "WARNING")
+  "A list of supported pragmas.
+This list comes from GHC documentation (URL
+`https://downloads.haskell.org/~ghc/7.10.1/docs/html/users_guide/pragmas.html'.")
+
+(defvar haskell-completions--keywords
+  (list
+   "as"
+   "case"
+   "class"
+   "data family"
+   "data instance"
+   "data"
+   "default"
+   "deriving instance"
+   "deriving"
+   "do"
+   "else"
+   "family"
+   "forall"
+   "foreign import"
+   "foreign"
+   "hiding"
+   "if"
+   "import qualified"
+   "import"
+   "in"
+   "infix"
+   "infixl"
+   "infixr"
+   "instance"
+   "let"
+   "mdo"
+   "module"
+   "newtype"
+   "of"
+   "proc"
+   "qualified"
+   "rec"
+   "signature"
+   "then"
+   "type family"
+   "type instance"
+   "type"
+   "where")
+  "A list of Haskell's keywords (URL `https://wiki.haskell.org/Keywords').
+Single char keywords and operator like keywords are not included
+in this list.")
+
+
+(defun haskell-completions-can-grab-prefix ()
+  "Check if the case is appropriate for grabbing completion prefix.
+Returns t if point is either at whitespace character, or at
+punctuation, or at line end and preceeding character is not a
+whitespace or new line, otherwise returns nil.
+
+  Returns nil in presence of active region."
+  (when (not (region-active-p))
+    (when (looking-at-p (rx (| space line-end punct)))
+      (when (not (bobp))
+        (save-excursion
+          (backward-char)
+          (not (looking-at-p (rx (| space line-end)))))))))
+
+(defun haskell-completions-grab-pragma-prefix ()
+  "Grab completion prefix for pragma completions.
+Returns a list of form '(prefix-start-position
+prefix-end-position prefix-value prefix-type) for pramga names
+such as WARNING, DEPRECATED, LANGUAGE etc.  Also returns
+completion prefixes for options in case OPTIONS_GHC pragma, or
+language extensions in case of LANGUAGE pragma.  Obsolete OPTIONS
+pragma is supported also."
+  (when (nth 4 (syntax-ppss))
+    ;; We're inside comment
+    (let ((p (point))
+          (comment-start (nth 8 (syntax-ppss)))
+          (case-fold-search nil)
+          prefix-start
+          prefix-end
+          prefix-type
+          prefix-value)
+      (save-excursion
+        (goto-char comment-start)
+        (when (looking-at (rx "{-#" (1+ (| space "\n"))))
+          (let ((pragma-start (match-end 0)))
+            (when (> p pragma-start)
+              ;; point stands after `{-#`
+              (goto-char pragma-start)
+              (when (looking-at (rx (1+ (| upper "_"))))
+                ;; found suitable sequence for pragma name
+                (let ((pragma-end (match-end 0))
+                      (pragma-value (match-string-no-properties 0)))
+                  (if (eq p pragma-end)
+                      ;; point is at the end of (in)complete pragma name
+                      ;; prepare resulting values
+                      (progn
+                        (setq prefix-start pragma-start)
+                        (setq prefix-end pragma-end)
+                        (setq prefix-value pragma-value)
+                        (setq prefix-type
+                              'haskell-completions-pragma-name-prefix))
+                    (when (and (> p pragma-end)
+                               (or (equal "OPTIONS_GHC" pragma-value)
+                                   (equal "OPTIONS" pragma-value)
+                                   (equal "LANGUAGE" pragma-value)))
+                      ;; point is after pragma name, so we need to check
+                      ;; special cases of `OPTIONS_GHC` and `LANGUAGE` pragmas
+                      ;; and provide a completion prefix for possible ghc
+                      ;; option or language extension.
+                      (goto-char pragma-end)
+                      (when (re-search-forward
+                             (rx (* anything)
+                                 (1+ (regexp "\\S-")))
+                             p
+                             t)
+                        (let* ((str (match-string-no-properties 0))
+                               (split (split-string str (rx (| space "\n")) t))
+                               (val (car (last split)))
+                               (end (point)))
+                          (when (and (equal p end)
+                                     (not (string-match-p "#" val)))
+                            (setq prefix-value val)
+                            (backward-char (length val))
+                            (setq prefix-start (point))
+                            (setq prefix-end end)
+                            (setq
+                             prefix-type
+                             (if (not (equal "LANGUAGE" pragma-value))
+                                 'haskell-completions-ghc-option-prefix
+                               'haskell-completions-language-extension-prefix
+                               )))))))))))))
+      (when prefix-value
+        (list prefix-start prefix-end prefix-value prefix-type)))))
+
+(defun haskell-completions-grab-identifier-prefix ()
+  "Grab completion prefix for identifier at point.
+Returns a list of form '(prefix-start-position
+prefix-end-position prefix-value prefix-type) for haskell
+identifier at point depending on result of function
+`haskell-ident-pos-at-point'."
+  (let ((pos-at-point (haskell-ident-pos-at-point))
+        (p (point)))
+    (when pos-at-point
+      (let* ((start (car pos-at-point))
+             (end (cdr pos-at-point))
+             (type 'haskell-completions-identifier-prefix)
+             (case-fold-search nil)
+             value)
+        ;; we need end position of result, becase of
+        ;; `haskell-ident-pos-at-point' ignores trailing whitespace, e.g. the
+        ;; result will be same for `map|` and `map  |` invocations.
+        (when (<= p end)
+          (setq end p)
+          (setq value (buffer-substring-no-properties start end))
+          (when (string-match-p (rx bos upper) value)
+            ;; we need to check if found identifier is a module name
+            (save-excursion
+              (goto-char (line-beginning-position))
+              (when (re-search-forward
+                     (rx "import"
+                         (? (1+ space) "qualified")
+                         (1+ space)
+                         upper
+                         (1+ (| alnum ".")))
+                     p    ;; bound
+                     t)   ;; no-error
+                (if (equal p (point))
+                    (setq type 'haskell-completions-module-name-prefix)
+                  (when (re-search-forward
+                         (rx (| " as " "("))
+                         start
+                         t)
+                    ;; but uppercase ident could occur after `as` keyword, or in
+                    ;; module imports after opening parenthesis, in this case
+                    ;; restore identifier type again, it's neccessary to
+                    ;; distinguish the means of completions retrieval
+                    (setq type 'haskell-completions-identifier-prefix))))))
+          (when (nth 8 (syntax-ppss))
+            ;; eighth element of syntax-ppss result is string or comment start,
+            ;; so when it's not nil word at point is inside string or comment,
+            ;; return special literal prefix type
+            (setq type 'haskell-completions-general-prefix))
+          ;; finally take in account minlen if given and return the result
+          (when value (list start end value type)))))))
+
+(defun haskell-completions-grab-prefix (&optional minlen)
+   "Grab prefix at point for possible completion.
+Returns a list of form '(prefix-start-position
+prefix-end-position prefix-value prefix-type) depending on
+situation, e.g. is it needed to complete pragma, module name,
+arbitrary identifier, etc.  Returns nil in case it is
+impossible to grab prefix.
+
+Possible prefix types are:
+
+* haskell-completions-pragma-name-prefix
+* haskell-completions-ghc-option-prefix
+* haskell-completions-language-extension-prefix
+* haskell-completions-module-name-prefix
+* haskell-completions-identifier-prefix
+* haskell-completions-general-prefix
+
+the last type is used in cases when completing things inside comments.
+
+If provided optional MINLEN parameter this function will return
+result only if prefix length is not less than MINLEN."
+   (when (haskell-completions-can-grab-prefix)
+     (let ((prefix (cond
+                    ((haskell-completions-grab-pragma-prefix))
+                    ((haskell-completions-grab-identifier-prefix)))))
+       (cond ((and minlen prefix)
+              (when (>= (length (nth 2 prefix)) minlen)
+                prefix))
+             (prefix prefix)))))
+
+(defun haskell-completions--simple-completions (prefix)
+  "Provide a list of completion candidates for given PREFIX.
+This function is used internally in
+`haskell-completions-completion-at-point' and
+`haskell-completions-sync-repl-completion-at-point'.
+
+It provides completions for haskell keywords, language pragmas,
+GHC's options, and language extensions.
+
+PREFIX should be a list such one returned by
+`haskell-completions-grab-identifier-prefix'."
+  (cl-destructuring-bind (beg end _pfx typ) prefix
+    (when (not (eql typ 'haskell-completions-general-prefix))
+      (let ((candidates
+             (cl-case typ
+               ('haskell-completions-pragma-name-prefix
+                haskell-completions--pragma-names)
+               ('haskell-completions-ghc-option-prefix
+                haskell-ghc-supported-options)
+               ('haskell-completions-language-extension-prefix
+                haskell-ghc-supported-extensions)
+               (otherwise
+                (append (when (bound-and-true-p haskell-tags-on-save)
+                          tags-completion-table)
+                        haskell-completions--keywords)))))
+        (list beg end candidates)))))
+
+;;;###autoload
+(defun haskell-completions-completion-at-point ()
+  "Provide completion list for thing at point.
+This function is used in non-interactive `haskell-mode'.  It
+provides completions for haskell keywords, language pragmas,
+GHC's options, and language extensions, but not identifiers."
+  (let ((prefix (haskell-completions-grab-prefix)))
+    (when prefix
+      (haskell-completions--simple-completions prefix))))
+
+(defun haskell-completions-sync-repl-completion-at-point ()
+  "A completion function used in `interactive-haskell-mode'.
+Completion candidates are provided quering current haskell
+process, that is sending `:complete repl' command.
+
+Completes all possible things: everything that can be completed
+with non-interactive function
+`haskell-completions-completion-at-point' plus identifier
+completions.
+
+Returns nil if no completions available."
+  (let ((prefix-data (haskell-completions-grab-prefix)))
+    (when prefix-data
+      (cl-destructuring-bind (beg end pfx typ) prefix-data
+        (when (and (not (eql typ 'haskell-completions-general-prefix))
+                   (or haskell-completions-complete-operators
+                       (not (save-excursion
+                              (goto-char (1- end))
+                              (haskell-mode--looking-at-varsym)))))
+          ;; do not complete things in comments
+          (if (cl-member
+               typ
+               '(haskell-completions-pragma-name-prefix
+                 haskell-completions-ghc-option-prefix
+                 haskell-completions-language-extension-prefix))
+              ;; provide simple completions
+              (haskell-completions--simple-completions prefix-data)
+            ;; only two cases left: haskell-completions-module-name-prefix
+            ;; and haskell-completions-identifier-prefix
+            (let* ((is-import (eql typ 'haskell-completions-module-name-prefix))
+                   (candidates
+                    (when (and (haskell-session-maybe)
+                               (not (haskell-process-cmd
+                                     (haskell-interactive-process)))
+                               ;; few possible extra checks would be:
+                               ;; (haskell-process-get 'is-restarting)
+                               ;; (haskell-process-get 'evaluating)
+                               )
+                      ;; if REPL is available and not busy try to query it for
+                      ;; completions list in case of module name or identifier
+                      ;; prefixes
+                      (haskell-completions-sync-complete-repl pfx is-import))))
+              ;; append candidates with keywords
+              (list beg end (append
+                             candidates
+                             haskell-completions--keywords)))))))))
+
+(defun haskell-completions-sync-complete-repl (prefix &optional import)
+  "Return completion list for given PREFIX querying REPL synchronously.
+When optional IMPORT argument is non-nil complete PREFIX
+prepending \"import \" keyword (useful for module names).  This
+function is supposed for internal use."
+  (haskell-process-get-repl-completions
+   (haskell-interactive-process)
+   (if import
+       (concat "import " prefix)
+     prefix)))
+
+(provide 'haskell-completions)
+;;; haskell-completions.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-completions.elc b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-completions.elc
new file mode 100644
index 0000000000..dd79847383
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-completions.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-customize.el b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-customize.el
new file mode 100644
index 0000000000..2b00751c0f
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-customize.el
@@ -0,0 +1,466 @@
+;;; haskell-customize.el --- Customization settings -*- lexical-binding: t -*-
+
+;; Copyright (c) 2014 Chris Done. All rights reserved.
+
+;; This file 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, or (at your option)
+;; any later version.
+
+;; This file 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Code:
+
+(require 'cl-lib)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Customization variables
+
+(defcustom haskell-process-load-or-reload-prompt nil
+  "Nil means there will be no prompts on starting REPL. Defaults will be accepted."
+  :type 'boolean
+  :group 'haskell-interactive)
+
+;;;###autoload
+(defgroup haskell nil
+  "Major mode for editing Haskell programs."
+  :link '(custom-manual "(haskell-mode)")
+  :group 'languages
+  :prefix "haskell-")
+
+(defvar haskell-mode-pkg-base-dir (file-name-directory load-file-name)
+  "Package base directory of installed `haskell-mode'.
+Used for locating additional package data files.")
+
+(defcustom haskell-completing-read-function 'ido-completing-read
+  "Default function to use for completion."
+  :group 'haskell
+  :type '(choice
+          (function-item :tag "ido" :value ido-completing-read)
+          (function-item :tag "helm" :value helm--completing-read-default)
+          (function-item :tag "completing-read" :value completing-read)
+          (function :tag "Custom function")))
+
+(defcustom haskell-process-type
+  'auto
+  "The inferior Haskell process type to use.
+
+When set to 'auto (the default), the directory contents and
+available programs will be used to make a best guess at the
+process type:
+
+If the project directory or one of its parents contains a
+\"cabal.sandbox.config\" file, then cabal-repl will be used.
+
+If there's a \"stack.yaml\" file and the \"stack\" executable can
+be located, then stack-ghci will be used.
+
+Otherwise if there's a *.cabal file, cabal-repl will be used.
+
+If none of the above apply, ghci will be used."
+  :type '(choice (const auto)
+                 (const ghci)
+                 (const cabal-repl)
+                 (const stack-ghci)
+                 (const cabal-new-repl))
+  :group 'haskell-interactive)
+
+(defcustom haskell-process-wrapper-function
+  #'identity
+  "Wrap or transform haskell process commands using this function.
+
+Can be set to a custom function which takes a list of arguments
+and returns a possibly-modified list.
+
+The following example function arranges for all haskell process
+commands to be started in the current nix-shell environment:
+
+  (lambda (argv) (append (list \"nix-shell\" \"-I\" \".\" \"--command\" )
+                    (list (mapconcat 'identity argv \" \"))))
+
+See Info Node `(emacs)Directory Variables' for a way to set this option on
+a per-project basis."
+  :group 'haskell-interactive
+  :type '(choice
+          (function-item :tag "None" :value identity)
+          (function :tag "Custom function")))
+
+(defcustom haskell-ask-also-kill-buffers
+  t
+  "Ask whether to kill all associated buffers when a session
+ process is killed."
+  :type 'boolean
+  :group 'haskell-interactive)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Configuration
+
+(defcustom haskell-doc-prettify-types t
+  "Replace some parts of types with Unicode characters like \"∷\"
+when showing type information about symbols."
+  :group 'haskell-doc
+  :type 'boolean
+  :safe 'booleanp)
+
+(defvar haskell-process-ended-functions (list 'haskell-process-prompt-restart)
+  "Hook for when the haskell process ends.")
+
+;;;###autoload
+(defgroup haskell-interactive nil
+  "Settings for REPL interaction via `haskell-interactive-mode'"
+  :link '(custom-manual "(haskell-mode)haskell-interactive-mode")
+  :group 'haskell)
+
+(defcustom haskell-process-path-ghci
+  "ghci"
+  "The path for starting ghci.
+This can either be a single string or a list of strings, where the
+first elements is a string and the remaining elements are arguments,
+which will be prepended to `haskell-process-args-ghci'."
+  :group 'haskell-interactive
+  :type '(choice string (repeat string)))
+
+(defcustom haskell-process-path-cabal
+  "cabal"
+  "Path to the `cabal' executable.
+This can either be a single string or a list of strings, where the
+first elements is a string and the remaining elements are arguments,
+which will be prepended to `haskell-process-args-cabal-repl'."
+  :group 'haskell-interactive
+  :type '(choice string (repeat string)))
+
+(defcustom haskell-process-path-stack
+  "stack"
+  "The path for starting stack.
+This can either be a single string or a list of strings, where the
+first elements is a string and the remaining elements are arguments,
+which will be prepended to `haskell-process-args-stack-ghci'."
+  :group 'haskell-interactive
+  :type '(choice string (repeat string)))
+
+(defcustom haskell-process-args-ghci
+  '("-ferror-spans")
+  "Any arguments for starting ghci."
+  :group 'haskell-interactive
+  :type '(repeat (string :tag "Argument")))
+
+(defcustom haskell-process-args-cabal-repl
+  '("--ghc-option=-ferror-spans")
+  "Additional arguments for `cabal repl' invocation.
+Note: The settings in `haskell-process-path-ghci' and
+`haskell-process-args-ghci' are not automatically reused as `cabal repl'
+currently invokes `ghc --interactive'. Use
+`--with-ghc=<path-to-executable>' if you want to use a different
+interactive GHC frontend; use `--ghc-option=<ghc-argument>' to
+pass additional flags to `ghc'."
+  :group 'haskell-interactive
+  :type '(repeat (string :tag "Argument")))
+
+(defcustom haskell-process-args-cabal-new-repl
+  '("--ghc-option=-ferror-spans")
+  "Additional arguments for `cabal new-repl' invocation.
+Note: The settings in `haskell-process-path-ghci' and
+`haskell-process-args-ghci' are not automatically reused as
+`cabal new-repl' currently invokes `ghc --interactive'. Use
+`--with-ghc=<path-to-executable>' if you want to use a different
+interactive GHC frontend; use `--ghc-option=<ghc-argument>' to
+pass additional flags to `ghc'."
+  :group 'haskell-interactive
+  :type '(repeat (string :tag "Argument")))
+
+(defcustom haskell-process-args-stack-ghci
+  '("--ghci-options=-ferror-spans" "--no-build" "--no-load")
+  "Additional arguments for `stack ghci' invocation."
+  :group 'haskell-interactive
+  :type '(repeat (string :tag "Argument")))
+
+(defcustom haskell-process-do-cabal-format-string
+  ":!cd %s && %s"
+  "The way to run cabal comands. It takes two arguments -- the directory and the command.
+See `haskell-process-do-cabal' for more details."
+  :group 'haskell-interactive
+  :type 'string)
+
+(defcustom haskell-process-log
+  nil
+  "Enable debug logging to \"*haskell-process-log*\" buffer."
+  :type 'boolean
+  :group 'haskell-interactive)
+
+(defcustom haskell-process-show-debug-tips
+  t
+  "Show debugging tips when starting the process."
+  :type 'boolean
+  :group 'haskell-interactive)
+
+(defcustom haskell-process-show-overlays
+  t
+  "Show in-buffer overlays for errors/warnings.
+Flycheck users might like to disable this."
+  :type 'boolean
+  :group 'haskell-interactive)
+
+(defcustom haskell-notify-p
+  nil
+  "Notify using notifications.el (if loaded)?"
+  :type 'boolean
+  :group 'haskell-interactive)
+
+(defcustom haskell-process-suggest-no-warn-orphans
+  t
+  "Suggest adding -fno-warn-orphans pragma to file when getting orphan warnings."
+  :type 'boolean
+  :group 'haskell-interactive)
+
+(defcustom haskell-process-suggest-hoogle-imports
+  nil
+  "Suggest to add import statements using Hoogle as a backend."
+  :type 'boolean
+  :group 'haskell-interactive)
+
+(defcustom haskell-process-suggest-hayoo-imports
+  nil
+  "Suggest to add import statements using Hayoo as a backend."
+  :type 'boolean
+  :group 'haskell-interactive)
+
+(defcustom haskell-process-hayoo-query-url
+  "http://hayoo.fh-wedel.de/json/?query=%s"
+  "Query url for json hayoo results."
+  :type 'string
+  :group 'haskell-interactive)
+
+(defcustom haskell-process-suggest-haskell-docs-imports
+  nil
+  "Suggest to add import statements using haskell-docs as a backend."
+  :type 'boolean
+  :group 'haskell-interactive)
+
+(defcustom haskell-process-suggest-add-package
+  t
+  "Suggest to add packages to your .cabal file when Cabal says it
+is a member of the hidden package, blah blah."
+  :type 'boolean
+  :group 'haskell-interactive)
+
+(defcustom haskell-process-suggest-language-pragmas
+  t
+  "Suggest adding LANGUAGE pragmas recommended by GHC."
+  :type 'boolean
+  :group 'haskell-interactive)
+
+(defcustom haskell-process-suggest-remove-import-lines
+  nil
+  "Suggest removing import lines as warned by GHC."
+  :type 'boolean
+  :group 'haskell-interactive)
+
+(defcustom haskell-process-suggest-overloaded-strings
+  t
+  "Suggest adding OverloadedStrings pragma to file when getting type mismatches with [Char]."
+  :type 'boolean
+  :group 'haskell-interactive)
+
+(defcustom haskell-process-check-cabal-config-on-load
+  t
+  "Check changes cabal config on loading Haskell files and
+restart the GHCi process if changed.."
+  :type 'boolean
+  :group 'haskell-interactive)
+
+(defcustom haskell-process-prompt-restart-on-cabal-change
+  t
+  "Ask whether to restart the GHCi process when the Cabal file
+has changed?"
+  :type 'boolean
+  :group 'haskell-interactive)
+
+(defcustom haskell-process-auto-import-loaded-modules
+  nil
+  "Auto import the modules reported by GHC to have been loaded?"
+  :type 'boolean
+  :group 'haskell-interactive)
+
+(defcustom haskell-process-reload-with-fbytecode
+  nil
+  "When using -fobject-code, auto reload with -fbyte-code (and
+then restore the -fobject-code) so that all module info and
+imports become available?"
+  :type 'boolean
+  :group 'haskell-interactive)
+
+(defcustom haskell-process-use-presentation-mode
+  nil
+  "Use presentation mode to show things like type info instead of
+  printing to the message area."
+  :type 'boolean
+  :group 'haskell-interactive)
+
+(defcustom haskell-process-suggest-restart
+  t
+  "Suggest restarting the process when it has died"
+  :type 'boolean
+  :group 'haskell-interactive)
+
+(defcustom haskell-interactive-popup-errors
+  t
+  "Popup errors in a separate buffer."
+  :type 'boolean
+  :group 'haskell-interactive)
+
+(defcustom haskell-interactive-mode-collapse
+  nil
+  "Collapse printed results."
+  :type 'boolean
+  :group 'haskell-interactive)
+
+(defcustom haskell-interactive-types-for-show-ambiguous
+  t
+  "Show types when there's no Show instance or there's an
+ambiguous class constraint."
+  :type 'boolean
+  :group 'haskell-interactive)
+
+(defcustom haskell-interactive-prompt "λ> "
+  "The prompt to use."
+  :type 'string
+  :group 'haskell-interactive)
+
+(defcustom haskell-interactive-prompt2 (replace-regexp-in-string
+                                        "> $"
+                                        "| "
+                                        haskell-interactive-prompt)
+  "The multi-line prompt to use.
+The default is `haskell-interactive-prompt' with the last > replaced with |."
+  :type 'string
+  :group 'haskell-interactive)
+
+(defcustom haskell-interactive-mode-eval-mode
+  nil
+  "Use the given mode's font-locking to render some text."
+  :type '(choice function (const :tag "None" nil))
+  :group 'haskell-interactive)
+
+(defcustom haskell-interactive-mode-hide-multi-line-errors
+  nil
+  "Hide collapsible multi-line compile messages by default."
+  :type 'boolean
+  :group 'haskell-interactive)
+
+(defcustom haskell-interactive-mode-delete-superseded-errors
+  t
+  "Whether to delete compile messages superseded by recompile/reloads."
+  :type 'boolean
+  :group 'haskell-interactive)
+
+(defcustom haskell-interactive-mode-include-file-name
+  t
+  "Include the file name of the module being compiled when
+printing compilation messages."
+  :type 'boolean
+  :group 'haskell-interactive)
+
+(defcustom haskell-interactive-mode-read-only
+  t
+  "Non-nil means most GHCi/haskell-interactive-mode output is read-only.
+This does not include the prompt.  Configure
+`haskell-interactive-prompt-read-only' to change the prompt's
+read-only property."
+  :type 'boolean
+  :group 'haskell-interactive)
+
+(defcustom haskell-interactive-prompt-read-only
+  haskell-interactive-mode-read-only
+  "Non-nil means the prompt (and prompt2) is read-only."
+  :type 'boolean
+  :group 'haskell-interactive)
+
+(defcustom haskell-import-mapping
+  '()
+  "Support a mapping from module to import lines.
+
+E.g. '((\"Data.Map\" . \"import qualified Data.Map as M
+import Data.Map (Map)
+\"))
+
+This will import
+
+import qualified Data.Map as M
+import Data.Map (Map)
+
+when Data.Map is the candidate.
+
+"
+  :type '(repeat (cons (string :tag "Module name")
+                       (string :tag "Import lines")))
+  :group 'haskell-interactive)
+
+(defcustom haskell-language-extensions
+  '()
+  "Language extensions in use. Should be in format: -XFoo,
+-XNoFoo etc. The idea is that various tools written with HSE (or
+any haskell-mode code that needs to be aware of syntactical
+properties; such as an indentation mode) that don't know what
+extensions to use can use this variable. Examples: hlint,
+hindent, structured-haskell-mode, tool-de-jour, etc.
+
+You can set this per-project with a .dir-locals.el file"
+  :group 'haskell
+  :type '(repeat 'string))
+
+(defcustom haskell-stylish-on-save nil
+  "Whether to run stylish-haskell on the buffer before saving.
+If this is true, `haskell-add-import' will not sort or align the
+imports."
+  :group 'haskell
+  :type 'boolean)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Accessor functions
+
+(defvar inferior-haskell-root-dir nil
+  "The path which is considered as project root, this is determined by the
+presence of a *.cabal file or stack.yaml file or something similar.")
+
+(defun haskell-process-type ()
+  "Return `haskell-process-type', or a guess if that variable is 'auto.
+This function also sets the `inferior-haskell-root-dir'"
+  (let ((cabal-sandbox (locate-dominating-file default-directory
+                                               "cabal.sandbox.config"))
+        (stack         (locate-dominating-file default-directory
+                                               "stack.yaml"))
+        (cabal         (locate-dominating-file default-directory
+                                               (lambda (d)
+                                                 (cl-find-if
+                                                  (lambda (f)
+                                                    (string-match-p ".\\.cabal\\'" f))
+                                                  (directory-files d))))))
+    (if (eq 'auto haskell-process-type)
+        (cond
+         ;; User has explicitly initialized this project with cabal
+         ((and cabal-sandbox
+               (executable-find "cabal"))
+          (setq inferior-haskell-root-dir cabal-sandbox)
+          'cabal-repl)
+         ((and stack
+               (executable-find "stack"))
+          (setq inferior-haskell-root-dir stack)
+          'stack-ghci)
+         ((and cabal
+               (executable-find "cabal"))
+          (setq inferior-haskell-root-dir cabal)
+          'cabal-repl)
+         ((executable-find "ghc")
+          (setq inferior-haskell-root-dir default-directory)
+          'ghci)
+         (t
+          (error "Could not find any installation of GHC.")))
+      haskell-process-type)))
+
+(provide 'haskell-customize)
diff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-customize.elc b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-customize.elc
new file mode 100644
index 0000000000..a286303e7a
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-customize.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-debug.el b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-debug.el
new file mode 100644
index 0000000000..38a6859bbd
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-debug.el
@@ -0,0 +1,757 @@
+;;; haskell-debug.el --- Debugging mode via GHCi -*- lexical-binding: t -*-
+
+;; Copyright © 2014 Chris Done. All rights reserved.
+;;             2016 Arthur Fayzrakhmanov
+
+;; This file 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, or (at your option)
+;; any later version.
+
+;; This file 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'haskell-session)
+(require 'haskell-process)
+(require 'haskell-interactive-mode)
+(require 'haskell-font-lock)
+(require 'haskell-utils)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Configuration
+
+;;;###autoload
+(defgroup haskell-debug nil
+  "Settings for debugging support."
+  :link '(custom-manual "(haskell-mode)haskell-debug")
+  :group 'haskell)
+
+;;;###autoload
+(defface haskell-debug-warning-face
+  '((t :inherit 'compilation-warning))
+  "Face for warnings."
+  :group 'haskell-debug)
+
+;;;###autoload
+(defface haskell-debug-trace-number-face
+  '((t :weight bold :background "#f5f5f5"))
+  "Face for numbers in backtrace."
+  :group 'haskell-debug)
+
+;;;###autoload
+(defface haskell-debug-newline-face
+  '((t :weight bold :background "#f0f0f0"))
+  "Face for newlines in trace steps."
+  :group 'haskell-debug)
+
+;;;###autoload
+(defface haskell-debug-keybinding-face
+  '((t :inherit 'font-lock-type-face :weight bold))
+  "Face for keybindings."
+  :group 'haskell-debug)
+
+;;;###autoload
+(defface haskell-debug-heading-face
+  '((t :inherit 'font-lock-keyword-face))
+  "Face for headings."
+  :group 'haskell-debug)
+
+;;;###autoload
+(defface haskell-debug-muted-face
+  '((t :foreground "#999"))
+  "Face for muteds."
+  :group 'haskell-debug)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Mode
+
+(defvar haskell-debug-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "g") 'haskell-debug/refresh)
+    (define-key map (kbd "s") 'haskell-debug/step)
+    (define-key map (kbd "t") 'haskell-debug/trace)
+    (define-key map (kbd "d") 'haskell-debug/delete)
+    (define-key map (kbd "b") 'haskell-debug/break-on-function)
+    (define-key map (kbd "a") 'haskell-debug/abandon)
+    (define-key map (kbd "c") 'haskell-debug/continue)
+    (define-key map (kbd "p") 'haskell-debug/previous)
+    (define-key map (kbd "n") 'haskell-debug/next)
+    (define-key map (kbd "RET") 'haskell-debug/select)
+    map)
+  "Keymap for `haskell-debug-mode'.")
+
+(define-derived-mode haskell-debug-mode
+  text-mode "Debug"
+  "Major mode for debugging Haskell via GHCi.")
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Globals
+
+(defvar haskell-debug-history-cache nil
+  "Cache of the tracing history.")
+
+(defvar haskell-debug-bindings-cache nil
+  "Cache of the current step's bindings.")
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Macros
+
+(defmacro haskell-debug-with-breakpoints (&rest body)
+  "Breakpoints need to exist to start stepping."
+  `(if (haskell-debug-get-breakpoints)
+       ,@body
+     (error "No breakpoints to step into!")))
+
+(defmacro haskell-debug-with-modules (&rest body)
+  "Modules need to exist to do debugging stuff."
+  `(if (haskell-debug-get-modules)
+       ,@body
+     (error "No modules loaded!")))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Interactive functions
+
+(defun haskell-debug/select ()
+  "Select whatever is at point."
+  (interactive)
+  (cond
+   ((get-text-property (point) 'break)
+    (let ((break (get-text-property (point) 'break)))
+      (haskell-debug-highlight (plist-get break :path)
+                               (plist-get break :span))))
+   ((get-text-property (point) 'module)
+    (let ((break (get-text-property (point) 'module)))
+      (haskell-debug-highlight (plist-get break :path))))))
+
+(defun haskell-debug/abandon ()
+  "Abandon the current computation."
+  (interactive)
+  (haskell-debug-with-breakpoints
+   (haskell-process-queue-sync-request (haskell-debug-process) ":abandon")
+   (message "Computation abandoned.")
+   (setq haskell-debug-history-cache nil)
+   (setq haskell-debug-bindings-cache nil)
+   (haskell-debug/refresh)))
+
+(defun haskell-debug/continue ()
+  "Continue the current computation."
+  (interactive)
+  (haskell-debug-with-breakpoints
+   (haskell-process-queue-sync-request (haskell-debug-process) ":continue")
+   (message "Computation continued.")
+   (setq haskell-debug-history-cache nil)
+   (setq haskell-debug-bindings-cache nil)
+   (haskell-debug/refresh)))
+
+(defun haskell-debug/break-on-function ()
+  "Break on function IDENT."
+  (interactive)
+  (haskell-debug-with-modules
+   (let ((ident (read-from-minibuffer "Function: "
+                                      (haskell-ident-at-point))))
+     (haskell-process-queue-sync-request
+      (haskell-debug-process)
+      (concat ":break "
+              ident))
+     (message "Breaking on function: %s" ident)
+     (haskell-debug/refresh))))
+
+(defun haskell-debug/start-step (expr)
+  "Start stepping EXPR."
+  (interactive (list (read-from-minibuffer "Expression to step through: ")))
+  (haskell-debug/step expr))
+
+(defun haskell-debug/breakpoint-numbers ()
+  "List breakpoint numbers."
+  (interactive)
+  (let ((breakpoints (mapcar (lambda (breakpoint)
+                               (number-to-string (plist-get breakpoint :number)))
+                             (haskell-debug-get-breakpoints))))
+    (if (null breakpoints)
+        (message "No breakpoints.")
+      (message "Breakpoint(s): %s"
+               (mapconcat #'identity
+                          breakpoints
+                          ", ")))))
+
+(defun haskell-debug/next ()
+  "Go to next step to inspect bindings."
+  (interactive)
+  (haskell-debug-with-breakpoints
+   (haskell-debug-navigate "forward")))
+
+(defun haskell-debug/previous ()
+  "Go to previous step to inspect the bindings."
+  (interactive)
+  (haskell-debug-with-breakpoints
+   (haskell-debug-navigate "back")))
+
+(defun haskell-debug/refresh ()
+  "Refresh the debugger buffer."
+  (interactive)
+  (with-current-buffer (haskell-debug-buffer-name (haskell-debug-session))
+    (cd (haskell-session-current-dir (haskell-debug-session)))
+    (let ((inhibit-read-only t)
+          (p (point)))
+      (erase-buffer)
+      (insert (propertize (concat "Debugging "
+                                  (haskell-session-name (haskell-debug-session))
+                                  "\n\n")
+                          'face `((:weight bold))))
+      (let ((modules (haskell-debug-get-modules))
+            (breakpoints (haskell-debug-get-breakpoints))
+            (context (haskell-debug-get-context))
+            (history (haskell-debug-get-history)))
+        (unless modules
+          (insert (propertize "You have to load a module to start debugging."
+                              'face
+                              'haskell-debug-warning-face)
+                  "\n\n"))
+        (haskell-debug-insert-bindings modules breakpoints context)
+        (when modules
+          (haskell-debug-insert-current-context context history)
+          (haskell-debug-insert-breakpoints breakpoints))
+        (haskell-debug-insert-modules modules))
+      (insert "\n")
+      (goto-char (min (point-max) p)))))
+
+(defun haskell-debug/delete ()
+  "Delete whatever's at the point."
+  (interactive)
+  (cond
+   ((get-text-property (point) 'break)
+    (let ((break (get-text-property (point) 'break)))
+      (haskell-mode-toggle-interactive-prompt-state)
+      (unwind-protect
+          (when (y-or-n-p (format "Delete breakpoint #%d?"
+                                  (plist-get break :number)))
+            (haskell-process-queue-sync-request
+             (haskell-debug-process)
+             (format ":delete %d"
+                     (plist-get break :number)))
+            (haskell-debug/refresh))
+        (haskell-mode-toggle-interactive-prompt-state t))))))
+
+(defun haskell-debug/trace ()
+  "Trace the expression."
+  (interactive)
+  (haskell-debug-with-modules
+   (haskell-debug-with-breakpoints
+    (let ((expr (read-from-minibuffer "Expression to trace: "
+                                      (haskell-ident-at-point))))
+      (haskell-process-queue-sync-request
+       (haskell-debug-process)
+       (concat ":trace " expr))
+      (message "Tracing expression: %s" expr)
+      (haskell-debug/refresh)))))
+
+(defun haskell-debug/step (&optional expr)
+  "Step into the next function."
+  (interactive)
+  (haskell-debug-with-breakpoints
+   (let* ((breakpoints (haskell-debug-get-breakpoints))
+          (context (haskell-debug-get-context))
+          (string
+           (haskell-process-queue-sync-request
+            (haskell-debug-process)
+            (if expr
+                (concat ":step " expr)
+              ":step"))))
+     (cond
+      ((string= string "not stopped at a breakpoint\n")
+       (if haskell-debug-bindings-cache
+           (progn (setq haskell-debug-bindings-cache nil)
+                  (haskell-debug/refresh))
+         (call-interactively 'haskell-debug/start-step)))
+      (t (let ((maybe-stopped-at (haskell-debug-parse-stopped-at string)))
+           (cond
+            (maybe-stopped-at
+             (setq haskell-debug-bindings-cache
+                   maybe-stopped-at)
+             (message "Computation paused.")
+             (haskell-debug/refresh))
+            (t
+             (if context
+                 (message "Computation finished.")
+               (progn
+                 (haskell-mode-toggle-interactive-prompt-state)
+                 (unwind-protect
+                     (when (y-or-n-p "Computation completed without breaking. Reload the module and retry?")
+                       (message "Reloading and resetting breakpoints...")
+                       (haskell-interactive-mode-reset-error (haskell-debug-session))
+                       (cl-loop for break in breakpoints
+                                do (haskell-process-queue-sync-request
+                                    (haskell-debug-process)
+                                    (concat ":load " (plist-get break :path))))
+                       (cl-loop for break in breakpoints
+                                do (haskell-debug-break break))
+                       (haskell-debug/step expr))
+                   (haskell-mode-toggle-interactive-prompt-state t))))))))))
+   (haskell-debug/refresh)))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Internal functions
+
+(defun haskell-debug-session ()
+  "Get the Haskell session."
+  (or (haskell-session-maybe)
+      (error "No Haskell session associated with this debug
+      buffer. Please just close the buffer and start again.")))
+
+(defun haskell-debug-process ()
+  "Get the Haskell session."
+  (or (haskell-session-process (haskell-session-maybe))
+      (error "No Haskell session associated with this debug
+      buffer. Please just close the buffer and start again.")))
+
+(defun haskell-debug-buffer-name (session)
+  "The debug buffer name for the current session."
+  (format "*debug:%s*"
+          (haskell-session-name session)))
+
+(defun haskell-debug-get-breakpoints ()
+  "Get the list of breakpoints currently set."
+  (let ((string (haskell-process-queue-sync-request
+                 (haskell-debug-process)
+                 ":show breaks")))
+    (if (string= string "No active breakpoints.\n")
+        (list)
+      (mapcar #'haskell-debug-parse-break-point
+              (haskell-debug-split-string string)))))
+
+(defun haskell-debug-get-modules ()
+  "Get the list of modules currently set."
+  (let ((string (haskell-process-queue-sync-request
+                 (haskell-debug-process)
+                 ":show modules")))
+    (if (string= string "")
+        (list)
+      (mapcar #'haskell-debug-parse-module
+              (haskell-debug-split-string string)))))
+
+(defun haskell-debug-get-context ()
+  "Get the current context."
+  (let ((string (haskell-process-queue-sync-request
+                 (haskell-debug-process)
+                 ":show context")))
+    (if (string= string "")
+        nil
+      (haskell-debug-parse-context string))))
+
+(defun haskell-debug-get-history ()
+  "Get the step history."
+  (let ((string (haskell-process-queue-sync-request
+                 (haskell-debug-process)
+                 ":history")))
+    (if (or (string= string "")
+            (string= string "Not stopped at a breakpoint\n"))
+        nil
+      (if (string= string "Empty history. Perhaps you forgot to use :trace?\n")
+          nil
+        (let ((entries (mapcar #'haskell-debug-parse-history-entry
+                               (cl-remove-if (lambda (line) (or (string= "<end of history>" line)
+                                                                (string= "..." line)))
+                                             (haskell-debug-split-string string)))))
+          (setq haskell-debug-history-cache
+                entries)
+          entries)))))
+
+(defun haskell-debug-insert-bindings (modules breakpoints context)
+  "Insert a list of bindings."
+  (if breakpoints
+      (progn (haskell-debug-insert-binding "t" "trace an expression")
+             (haskell-debug-insert-binding "s" "step into an expression")
+             (haskell-debug-insert-binding "b" "breakpoint" t))
+    (progn
+      (when modules
+        (haskell-debug-insert-binding "b" "breakpoint"))
+      (when breakpoints
+        (haskell-debug-insert-binding "s" "step into an expression" t))))
+  (when breakpoints
+    (haskell-debug-insert-binding "d" "delete breakpoint"))
+  (when context
+    (haskell-debug-insert-binding "a" "abandon context")
+    (haskell-debug-insert-binding "c" "continue" t))
+  (when context
+    (haskell-debug-insert-binding "p" "previous step")
+    (haskell-debug-insert-binding "n" "next step" t))
+  (haskell-debug-insert-binding "g" "refresh" t)
+  (insert "\n"))
+
+(defun haskell-debug-insert-current-context (context history)
+  "Insert the current context."
+  (haskell-debug-insert-header "Context")
+  (if context
+      (haskell-debug-insert-context context history)
+    (haskell-debug-insert-debug-finished))
+  (insert "\n"))
+
+(defun haskell-debug-insert-breakpoints (breakpoints)
+  "insert the list of breakpoints."
+  (haskell-debug-insert-header "Breakpoints")
+  (if (null breakpoints)
+      (haskell-debug-insert-muted "No active breakpoints.")
+    (cl-loop for break in breakpoints
+             do (insert (propertize (format "%d"
+                                            (plist-get break :number))
+                                    'face `((:weight bold))
+                                    'break break)
+                        (haskell-debug-muted " - ")
+                        (propertize (plist-get break :module)
+                                    'break break
+                                    'break break)
+                        (haskell-debug-muted
+                         (format " (%d:%d)"
+                                 (plist-get (plist-get break :span) :start-line)
+                                 (plist-get (plist-get break :span) :start-col)))
+                        "\n")))
+  (insert "\n"))
+
+(defun haskell-debug-insert-modules (modules)
+  "Insert the list of modules."
+  (haskell-debug-insert-header "Modules")
+  (if (null modules)
+      (haskell-debug-insert-muted "No loaded modules.")
+    (progn (cl-loop for module in modules
+                    do (insert (propertize (plist-get module :module)
+                                           'module module
+                                           'face `((:weight bold)))
+                               (haskell-debug-muted " - ")
+                               (propertize (file-name-nondirectory (plist-get module :path))
+                                           'module module))
+                    do (insert "\n")))))
+
+(defun haskell-debug-split-string (string)
+  "Split GHCi's line-based output, stripping the trailing newline."
+  (split-string string "\n" t))
+
+(defun haskell-debug-parse-context (string)
+  "Parse the context."
+  (cond
+   ((string-match "^--> \\(.+\\)\n  \\(.+\\)" string)
+    (let ((name (match-string 1 string))
+          (stopped (haskell-debug-parse-stopped-at (match-string 2 string))))
+      (list :name name
+            :path (plist-get stopped :path)
+            :span (plist-get stopped :span))))))
+
+(defun haskell-debug-insert-binding (binding desc &optional end)
+  "Insert a helpful keybinding."
+  (insert (propertize binding 'face 'haskell-debug-keybinding-face)
+          (haskell-debug-muted " - ")
+          desc
+          (if end
+              "\n"
+            (haskell-debug-muted ", "))))
+
+(defun haskell-debug-insert-header (title)
+  "Insert a header title."
+  (insert (propertize title
+                      'face 'haskell-debug-heading-face)
+          "\n\n"))
+
+(defun haskell-debug-insert-context (context history)
+  "Insert the context and history."
+  (when context
+    (insert (propertize (plist-get context :name) 'face `((:weight bold)))
+            (haskell-debug-muted " - ")
+            (file-name-nondirectory (plist-get context :path))
+            (haskell-debug-muted " (stopped)")
+            "\n"))
+  (when haskell-debug-bindings-cache
+    (insert "\n")
+    (let ((bindings haskell-debug-bindings-cache))
+      (insert
+       (haskell-debug-get-span-string
+        (plist-get bindings :path)
+        (plist-get bindings :span)))
+      (insert "\n\n")
+      (cl-loop for binding in (plist-get bindings :types)
+               do (insert (haskell-fontify-as-mode binding 'haskell-mode)
+                          "\n"))))
+  (let ((history (or history
+                     (list (haskell-debug-make-fake-history context)))))
+    (when history
+      (insert "\n")
+      (haskell-debug-insert-history history))))
+
+(defun haskell-debug-insert-debug-finished ()
+  "Insert message that no debugging is happening, but if there is
+some old history, then display that."
+  (if haskell-debug-history-cache
+      (progn (haskell-debug-insert-muted "Finished debugging.")
+             (insert "\n")
+             (haskell-debug-insert-history haskell-debug-history-cache))
+    (haskell-debug-insert-muted "Not debugging right now.")))
+
+(defun haskell-debug-insert-muted (text)
+  "Insert some muted text."
+  (insert (haskell-debug-muted text)
+          "\n"))
+
+(defun haskell-debug-muted (text)
+  "Make some muted text."
+  (propertize text 'face 'haskell-debug-muted-face))
+
+(defun haskell-debug-parse-logged (string)
+  "Parse the logged breakpoint."
+  (cond
+   ((string= "no more logged breakpoints\n" string)
+    nil)
+   ((string= "already at the beginning of the history\n" string)
+    nil)
+   (t
+    (with-temp-buffer
+      (insert string)
+      (goto-char (point-min))
+      (list :path (progn (search-forward " at ")
+                         (buffer-substring-no-properties
+                          (point)
+                          (1- (search-forward ":"))))
+            :span (haskell-debug-parse-span
+                   (buffer-substring-no-properties
+                    (point)
+                    (line-end-position)))
+            :types (progn (forward-line)
+                          (haskell-debug-split-string
+                           (buffer-substring-no-properties
+                            (point)
+                            (point-max)))))))))
+
+(defun haskell-debug-parse-stopped-at (string)
+  "Parse the location stopped at from the given string.
+
+For example:
+
+Stopped at /home/foo/project/src/x.hs:6:25-36
+
+"
+  (let ((index (string-match "Stopped at \\([^:]+\\):\\(.+\\)\n?"
+                             string)))
+    (when index
+      (list :path (match-string 1 string)
+            :span (haskell-debug-parse-span (match-string 2 string))
+            :types (cdr (haskell-debug-split-string (substring string index)))))))
+
+(defun haskell-debug-get-span-string (path span)
+  "Get the string from the PATH and the SPAN."
+  (save-window-excursion
+    (find-file path)
+    (buffer-substring
+     (save-excursion
+       (goto-char (point-min))
+       (forward-line (1- (plist-get span :start-line)))
+       (forward-char (1- (plist-get span :start-col)))
+       (point))
+     (save-excursion
+       (goto-char (point-min))
+       (forward-line (1- (plist-get span :end-line)))
+       (forward-char (plist-get span :end-col))
+       (point)))))
+
+(defun haskell-debug-make-fake-history (context)
+  "Make a fake history item."
+  (list :index -1
+        :path (plist-get context :path)
+        :span (plist-get context :span)))
+
+(defun haskell-debug-insert-history (history)
+  "Insert tracing HISTORY."
+  (let ((i (length history)))
+    (cl-loop for span in history
+             do (let ((string (haskell-debug-get-span-string
+                               (plist-get span :path)
+                               (plist-get span :span))))
+                  (insert (propertize (format "%4d" i)
+                                      'face 'haskell-debug-trace-number-face)
+                          " "
+                          (haskell-debug-preview-span
+                           (plist-get span :span)
+                           string
+                           t)
+                          "\n")
+                  (setq i (1- i))))))
+
+(defun haskell-debug-parse-span (string)
+  "Parse a source span from a string.
+
+Examples:
+
+  (5,1)-(6,37)
+  6:25-36
+  5:20
+
+People like to make other people's lives interesting by making
+variances in source span notation."
+  (cond
+   ((string-match "\\([0-9]+\\):\\([0-9]+\\)-\\([0-9]+\\)"
+                  string)
+    (list :start-line (string-to-number (match-string 1 string))
+          :start-col (string-to-number (match-string 2 string))
+          :end-line (string-to-number (match-string 1 string))
+          :end-col (string-to-number (match-string 3 string))))
+   ((string-match "\\([0-9]+\\):\\([0-9]+\\)"
+                  string)
+    (list :start-line (string-to-number (match-string 1 string))
+          :start-col (string-to-number (match-string 2 string))
+          :end-line (string-to-number (match-string 1 string))
+          :end-col (string-to-number (match-string 2 string))))
+   ((string-match "(\\([0-9]+\\),\\([0-9]+\\))-(\\([0-9]+\\),\\([0-9]+\\))"
+                  string)
+    (list :start-line (string-to-number (match-string 1 string))
+          :start-col (string-to-number (match-string 2 string))
+          :end-line (string-to-number (match-string 3 string))
+          :end-col (string-to-number (match-string 4 string))))
+   (t (error "Unable to parse source span from string: %s"
+             string))))
+
+(defun haskell-debug-preview-span (span string &optional collapsed)
+  "Make a one-line preview of the given expression."
+  (with-temp-buffer
+    (haskell-mode)
+    (insert string)
+    (when (/= 0 (plist-get span :start-col))
+      (indent-rigidly (point-min)
+                      (point-max)
+                      1))
+    (if (fboundp 'font-lock-ensure)
+        (font-lock-ensure)
+      (with-no-warnings (font-lock-fontify-buffer)))
+    (when (/= 0 (plist-get span :start-col))
+      (indent-rigidly (point-min)
+                      (point-max)
+                      -1))
+    (goto-char (point-min))
+    (if collapsed
+        (replace-regexp-in-string
+         "\n[ ]*"
+         (propertize " " 'face 'haskell-debug-newline-face)
+         (buffer-substring (point-min)
+                           (point-max)))
+      (buffer-string))))
+
+(defun haskell-debug-start (session)
+  "Start the debug mode."
+  (setq buffer-read-only t)
+  (haskell-session-assign session)
+  (haskell-debug/refresh))
+
+(defun haskell-debug ()
+  "Start the debugger for the current Haskell (GHCi) session."
+  (interactive)
+  (let ((session (haskell-debug-session)))
+    (switch-to-buffer-other-window (haskell-debug-buffer-name session))
+    (unless (eq major-mode 'haskell-debug-mode)
+      (haskell-debug-mode)
+      (haskell-debug-start session))))
+
+(defun haskell-debug-break (break)
+  "Set BREAK breakpoint in module at line/col."
+  (haskell-process-queue-without-filters
+   (haskell-debug-process)
+   (format ":break %s %s %d"
+           (plist-get break :module)
+           (plist-get (plist-get break :span) :start-line)
+           (plist-get (plist-get break :span) :start-col))))
+
+(defun haskell-debug-navigate (direction)
+  "Navigate in DIRECTION \"back\" or \"forward\"."
+  (let ((string (haskell-process-queue-sync-request
+                 (haskell-debug-process)
+                 (concat ":" direction))))
+    (let ((bindings (haskell-debug-parse-logged string)))
+      (setq haskell-debug-bindings-cache
+            bindings)
+      (when (not bindings)
+        (message "No more %s results!" direction)))
+    (haskell-debug/refresh)))
+
+(defun haskell-debug-session-debugging-p (session)
+  "Does the session have a debugging buffer open?"
+  (not (not (get-buffer (haskell-debug-buffer-name session)))))
+
+(defun haskell-debug-highlight (path &optional span)
+  "Highlight the file at span."
+  (let ((p (make-overlay
+            (line-beginning-position)
+            (line-end-position))))
+    (overlay-put p 'face `((:background "#eee")))
+    (with-current-buffer
+        (if span
+            (save-window-excursion
+              (find-file path)
+              (current-buffer))
+          (find-file path)
+          (current-buffer))
+      (let ((o (when span
+                 (make-overlay
+                  (save-excursion
+                    (goto-char (point-min))
+                    (forward-line (1- (plist-get span :start-line)))
+                    (forward-char (1- (plist-get span :start-col)))
+                    (point))
+                  (save-excursion
+                    (goto-char (point-min))
+                    (forward-line (1- (plist-get span :end-line)))
+                    (forward-char (plist-get span :end-col))
+                    (point))))))
+        (when o
+          (overlay-put o 'face `((:background "#eee"))))
+        (sit-for 0.5)
+        (when o
+          (delete-overlay o))
+        (delete-overlay p)))))
+
+(defun haskell-debug-parse-history-entry (string)
+  "Parse a history entry."
+  (if (string-match "^\\([-0-9]+\\)[ ]+:[ ]+\\([A-Za-z0-9_':]+\\)[ ]+(\\([^:]+\\):\\(.+?\\))$"
+                    string)
+      (list :index (string-to-number (match-string 1 string))
+            :name (match-string 2 string)
+            :path (match-string 3 string)
+            :span (haskell-debug-parse-span (match-string 4 string)))
+    (error "Unable to parse history entry: %s" string)))
+
+(defun haskell-debug-parse-module (string)
+  "Parse a module and path.
+
+For example:
+
+X                ( /home/foo/X.hs, interpreted )
+Main             ( /home/foo/X.hs, /home/foo/X.o )
+"
+  (if (string-match "\\([^ ]+\\)[ ]+( \\([^ ]+?\\), [/a-zA-Z0-9\.]+ )$"
+                    string)
+      (list :module (match-string 1 string)
+            :path (match-string 2 string))
+    (error "Unable to parse module from string: %s"
+           string)))
+
+(defun haskell-debug-parse-break-point (string)
+  "Parse a breakpoint number, module and location from a string.
+
+For example:
+
+[13] Main /home/foo/src/x.hs:(5,1)-(6,37)
+
+"
+  (if (string-match "^\\[\\([0-9]+\\)\\] \\([^ ]+\\) \\([^:]+\\):\\(.+\\)$"
+                    string)
+      (list :number (string-to-number (match-string 1 string))
+            :module (match-string 2 string)
+            :path (match-string 3 string)
+            :span (haskell-debug-parse-span (match-string 4 string)))
+    (error "Unable to parse breakpoint from string: %s"
+           string)))
+
+(provide 'haskell-debug)
+
+;;; haskell-debug.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-debug.elc b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-debug.elc
new file mode 100644
index 0000000000..4eb01e9eec
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-debug.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-decl-scan.el b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-decl-scan.el
new file mode 100644
index 0000000000..75da0a9d6b
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-decl-scan.el
@@ -0,0 +1,687 @@
+;;; haskell-decl-scan.el --- Declaration scanning module for Haskell Mode -*- lexical-binding: t -*-
+
+;; Copyright (C) 2004, 2005, 2007, 2009  Free Software Foundation, Inc.
+;; Copyright (C) 1997-1998  Graeme E Moss
+;; Copyright (C) 2016  Chris Gregory
+
+;; Author: 1997-1998 Graeme E Moss <gem@cs.york.ac.uk>
+;; Maintainer: Stefan Monnier <monnier@gnu.org>
+;; Keywords: declarations menu files Haskell
+;; URL: http://cvs.haskell.org/cgi-bin/cvsweb.cgi/fptools/CONTRIB/haskell-modes/emacs/haskell-decl-scan.el?rev=HEAD
+
+;; This file is not part of GNU Emacs.
+
+;; This file 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, or (at your option)
+;; any later version.
+
+;; This file 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Purpose:
+;;
+;; Top-level declarations are scanned and placed in a menu.  Supports
+;; full Latin1 Haskell 1.4 as well as literate scripts.
+;;
+;;
+;; Installation:
+;;
+;; To turn declaration scanning on for all Haskell buffers under the
+;; Haskell mode of Moss&Thorn, add this to .emacs:
+;;
+;;    (add-hook 'haskell-mode-hook 'haskell-decl-scan-mode)
+;;
+;; Otherwise, call `haskell-decl-scan-mode'.
+;;
+;;
+;; Customisation:
+;;
+;; M-x customize-group haskell-decl-scan
+;;
+;;
+;; History:
+;;
+;; If you have any problems or suggestions, after consulting the list
+;; below, email gem@cs.york.ac.uk quoting the version of the library
+;; you are using, the version of Emacs you are using, and a small
+;; example of the problem or suggestion.  Note that this library
+;; requires a reasonably recent version of Emacs.
+;;
+;; Uses `imenu' under Emacs.
+;;
+;; Version 1.2:
+;;   Added support for LaTeX-style literate scripts.
+;;
+;; Version 1.1:
+;;   Use own syntax table.  Fixed bug for very small buffers.  Use
+;;   markers instead of pointers (markers move with the text).
+;;
+;; Version 1.0:
+;;   Brought over from Haskell mode v1.1.
+;;
+;;
+;; Present Limitations/Future Work (contributions are most welcome!):
+;;
+;; . Declarations requiring information extending beyond starting line
+;;   don't get scanned properly, eg.
+;;   > class Eq a =>
+;;   >       Test a
+;;
+;; . Comments placed in the midst of the first few lexemes of a
+;;   declaration will cause havoc, eg.
+;;   > infixWithComments :: Int -> Int -> Int
+;;   > x {-nastyComment-} `infixWithComments` y = x + y
+;;   but are not worth worrying about.
+;;
+;; . Would be nice to scan other top-level declarations such as
+;;   methods of a class, datatype field labels...  any more?
+;;
+;; . Support for GreenCard?
+;;
+;; . Re-running (literate-)haskell-imenu should not cause the problems
+;;   that it does.  The ability to turn off scanning would also be
+;;   useful.  (Note that re-running (literate-)haskell-mode seems to
+;;   cause no problems.)
+
+;; All functions/variables start with
+;; `(turn-(on/off)-)haskell-decl-scan' or `haskell-ds-'.
+
+;; The imenu support is based on code taken from `hugs-mode',
+;; thanks go to Chris Van Humbeeck.
+
+;; Version.
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'haskell-mode)
+(require 'syntax)
+(require 'imenu)
+
+;;;###autoload
+(defgroup haskell-decl-scan nil
+  "Haskell declaration scanning (`imenu' support)."
+  :link '(custom-manual "(haskell-mode)haskell-decl-scan-mode")
+  :group 'haskell
+  :prefix "haskell-decl-scan-")
+
+(defcustom haskell-decl-scan-bindings-as-variables nil
+  "Whether to put top-level value bindings into a \"Variables\" category."
+  :group 'haskell-decl-scan
+  :type 'boolean)
+
+(defcustom haskell-decl-scan-add-to-menubar t
+  "Whether to add a \"Declarations\" menu entry to menu bar."
+  :group 'haskell-decl-scan
+  :type 'boolean)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; General declaration scanning functions.
+
+(defvar haskell-ds-start-keywords-re
+  (concat "\\(\\<"
+          "class\\|data\\|i\\(mport\\|n\\(fix\\(\\|[lr]\\)\\|stance\\)\\)\\|"
+          "module\\|primitive\\|type\\|newtype"
+          "\\)\\>")
+  "Keywords that may start a declaration.")
+
+(defvar haskell-ds-syntax-table
+  (let ((table (copy-syntax-table haskell-mode-syntax-table)))
+    (modify-syntax-entry ?\' "w" table)
+    (modify-syntax-entry ?_  "w" table)
+    (modify-syntax-entry ?\\ "_" table)
+    table)
+  "Syntax table used for Haskell declaration scanning.")
+
+
+(defun haskell-ds-get-variable (prefix)
+  "Return variable involved in value binding or type signature.
+Assumes point is looking at the regexp PREFIX followed by the
+start of a declaration (perhaps in the middle of a series of
+declarations concerning a single variable).  Otherwise return nil.
+Point is not changed."
+  ;; I think I can now handle all declarations bar those with comments
+  ;; nested before the second lexeme.
+  (save-excursion
+    (with-syntax-table haskell-ds-syntax-table
+      (if (looking-at prefix) (goto-char (match-end 0)))
+      ;; Keyword.
+      (if (looking-at haskell-ds-start-keywords-re)
+          nil
+        (or ;; Parenthesized symbolic variable.
+         (and (looking-at "(\\(\\s_+\\))") (match-string-no-properties 1))
+         ;; General case.
+         (if (looking-at
+              (if (eq ?\( (char-after))
+                  ;; Skip paranthesised expression.
+                  (progn
+                    (forward-sexp)
+                    ;; Repeating this code and avoiding moving point if
+                    ;; possible speeds things up.
+                    "\\(\\'\\)?\\s-*\\(\\s_+\\|`\\(\\sw+\\)`\\)")
+                "\\(\\sw+\\)?\\s-*\\(\\s_+\\|`\\(\\sw+\\)`\\)"))
+             (let ((match2 (match-string-no-properties 2)))
+               ;; Weed out `::', `∷',`=' and `|' from potential infix
+               ;; symbolic variable.
+               (if (member match2 '("::" "∷" "=" "|"))
+                   ;; Variable identifier.
+                   (match-string-no-properties 1)
+                 (if (eq (aref match2 0) ?\`)
+                     ;; Infix variable identifier.
+                     (match-string-no-properties 3)
+                   ;; Infix symbolic variable.
+                   match2))))
+         ;; Variable identifier.
+         (and (looking-at "\\sw+") (match-string-no-properties 0)))))))
+
+(defun haskell-ds-move-to-start-regexp (inc regexp)
+  "Move to beginning of line that succeeds/precedes (INC = 1/-1)
+current line that starts with REGEXP and is not in `font-lock-comment-face'."
+  ;; Making this defsubst instead of defun appears to have little or
+  ;; no effect on efficiency.  It is probably not called enough to do
+  ;; so.
+  (while (and (= (forward-line inc) 0)
+              (or (not (looking-at regexp))
+                  (eq (get-text-property (point) 'face)
+                      'font-lock-comment-face)))))
+
+(defun haskell-ds-move-to-start-regexp-skipping-comments (inc regexp)
+  "Like haskell-ds-move-to-start-regexp, but uses syntax-ppss to
+  skip comments"
+  (let (p)
+    (cl-loop
+     do (setq p (point))
+     (haskell-ds-move-to-start-regexp inc regexp)
+     while (and (nth 4 (syntax-ppss))
+                (/= p (point))))))
+
+(defvar literate-haskell-ds-line-prefix "> ?"
+  "Regexp matching start of a line of Bird-style literate code.
+Current value is \"> \" as we assume top-level declarations start
+at column 3.  Must not contain the special \"^\" regexp as we may
+not use the regexp at the start of a regexp string.  Note this is
+only for `imenu' support.")
+
+(defvar haskell-ds-start-decl-re "\\(\\sw\\|(\\)"
+  "The regexp that starts a Haskell declaration.")
+
+(defvar literate-haskell-ds-start-decl-re
+  (concat literate-haskell-ds-line-prefix haskell-ds-start-decl-re)
+  "The regexp that starts a Bird-style literate Haskell declaration.")
+
+(defun haskell-ds-whitespace-p (char)
+  "Test if CHAR is a whitespace character."
+  ;; the nil is a bob/eob test
+  (member char '(nil ?\t ?\n ?\ )))
+
+(defun haskell-ds-move-to-decl (direction bird-literate fix)
+  "General function for moving to the start of a declaration,
+either forwards or backwards from point, with normal or with Bird-style
+literate scripts.  If DIRECTION is t, then forward, else backward.  If
+BIRD-LITERATE is t, then treat as Bird-style literate scripts, else
+normal scripts.  Returns point if point is left at the start of a
+declaration, and nil otherwise, ie. because point is at the beginning
+or end of the buffer and no declaration starts there.  If FIX is t,
+then point does not move if already at the start of a declaration."
+  ;; As `haskell-ds-get-variable' cannot separate an infix variable
+  ;; identifier out of a value binding with non-alphanumeric first
+  ;; argument, this function will treat such value bindings as
+  ;; separate from the declarations surrounding it.
+  (let ( ;; The variable typed or bound in the current series of
+        ;; declarations.
+        name
+        ;; The variable typed or bound in the new declaration.
+        newname
+        ;; Hack to solve hard problem for Bird-style literate scripts
+        ;; that start with a declaration.  We are in the abyss if
+        ;; point is before start of this declaration.
+        abyss
+        (line-prefix (if bird-literate literate-haskell-ds-line-prefix ""))
+        ;; The regexp to match for the start of a declaration.
+        (start-decl-re (if bird-literate
+                           literate-haskell-ds-start-decl-re
+                         haskell-ds-start-decl-re))
+        (increment (if direction 1 -1))
+        (bound (if direction (point-max) (point-min))))
+    ;; Change syntax table.
+    (with-syntax-table haskell-ds-syntax-table
+      ;; move to beginning of line that starts the "current
+      ;; declaration" (dependent on DIRECTION and FIX), and then get
+      ;; the variable typed or bound by this declaration, if any.
+      (let ( ;; Where point was at call of function.
+            (here (point))
+            ;; Where the declaration on this line (if any) starts.
+            (start (progn
+                     (beginning-of-line)
+                     ;; Checking the face to ensure a declaration starts
+                     ;; here seems to be the only addition to make this
+                     ;; module support LaTeX-style literate scripts.
+                     (if (and (looking-at start-decl-re)
+                              (not (elt (syntax-ppss) 4)))
+                         (match-beginning 1)))))
+        (if (and start
+                 ;; This complicated boolean determines whether we
+                 ;; should include the declaration that starts on the
+                 ;; current line as the "current declaration" or not.
+                 (or (and (or (and direction (not fix))
+                              (and (not direction) fix))
+                          (>= here start))
+                     (and (or (and direction fix)
+                              (and (not direction) (not fix)))
+                          (> here start))))
+            ;; If so, we are already at start of the current line, so
+            ;; do nothing.
+            ()
+          ;; If point was before start of a declaration on the first
+          ;; line of the buffer (possible for Bird-style literate
+          ;; scripts) then we are in the abyss.
+          (if (and start (bobp))
+              (setq abyss t)
+            ;; Otherwise we move to the start of the first declaration
+            ;; on a line preceding the current one, skipping comments
+            (haskell-ds-move-to-start-regexp-skipping-comments -1 start-decl-re))))
+      ;; If we are in the abyss, position and return as appropriate.
+      (if abyss
+          (if (not direction)
+              nil
+            (re-search-forward (concat "\\=" line-prefix) nil t)
+            (point))
+        ;; Get the variable typed or bound by this declaration, if any.
+        (setq name (haskell-ds-get-variable line-prefix))
+        (if (not name)
+            ;; If no such variable, stop at the start of this
+            ;; declaration if moving backward, or move to the next
+            ;; declaration if moving forward.
+            (if direction
+                (haskell-ds-move-to-start-regexp-skipping-comments 1 start-decl-re))
+          ;; If there is a variable, find the first
+          ;; succeeding/preceding declaration that does not type or
+          ;; bind it.  Check for reaching start/end of buffer and
+          ;; comments.
+          (haskell-ds-move-to-start-regexp-skipping-comments increment start-decl-re)
+          (while (and (/= (point) bound)
+                      (and (setq newname (haskell-ds-get-variable line-prefix))
+                           (string= name newname)))
+            (setq name newname)
+            (haskell-ds-move-to-start-regexp-skipping-comments increment start-decl-re))
+          ;; If we are going backward, and have either reached a new
+          ;; declaration or the beginning of a buffer that does not
+          ;; start with a declaration, move forward to start of next
+          ;; declaration (which must exist).  Otherwise, we are done.
+          (if (and (not direction)
+                   (or (and (looking-at start-decl-re)
+                            (not (string= name
+                                          ;; Note we must not use
+                                          ;; newname here as this may
+                                          ;; not have been set if we
+                                          ;; have reached the beginning
+                                          ;; of the buffer.
+                                          (haskell-ds-get-variable
+                                           line-prefix))))
+                       (and (not (looking-at start-decl-re))
+                            (bobp))))
+              (haskell-ds-move-to-start-regexp-skipping-comments 1 start-decl-re)))
+        ;; Store whether we are at the start of a declaration or not.
+        ;; Used to calculate final result.
+        (let ((at-start-decl (looking-at start-decl-re)))
+          ;; If we are at the beginning of a line, move over
+          ;; line-prefix, if present at point.
+          (if (bolp)
+              (re-search-forward (concat "\\=" line-prefix) (point-max) t))
+          ;; Return point if at the start of a declaration and nil
+          ;; otherwise.
+          (if at-start-decl (point) nil))))))
+
+(defun haskell-ds-bird-p ()
+  (and (boundp 'haskell-literate) (eq haskell-literate 'bird)))
+
+(defun haskell-ds-backward-decl ()
+  "Move backward to the first character that starts a top-level declaration.
+A series of declarations concerning one variable is treated as one
+declaration by this function.  So, if point is within a top-level
+declaration then move it to the start of that declaration.  If point
+is already at the start of a top-level declaration, then move it to
+the start of the preceding declaration.  Returns point if point is
+left at the start of a declaration, and nil otherwise, because
+point is at the beginning of the buffer and no declaration starts
+there."
+  (interactive)
+  (haskell-ds-move-to-decl nil (haskell-ds-bird-p) nil))
+
+(defun haskell-ds-comment-p
+    (&optional
+     pt)
+  "Test if the cursor is on whitespace or a comment.
+
+`PT' defaults to `(point)'"
+  ;; ensure result is `t' or `nil' instead of just truthy
+  (if (or
+       ;; is cursor on whitespace
+       (haskell-ds-whitespace-p (following-char))
+       ;; http://emacs.stackexchange.com/questions/14269/how-to-detect-if-the-point-is-within-a-comment-area
+       ;; is cursor at begging, inside, or end of comment
+       (let ((fontfaces (get-text-property (or pt
+                                               (point)) 'face)))
+         (when (not (listp fontfaces))
+           (setf fontfaces (list fontfaces)))
+         (delq nil (mapcar
+                    #'(lambda (f)
+                        (member f '(font-lock-comment-face
+                                    font-lock-doc-face
+                                    font-lock-comment-delimiter-face)))
+                    fontfaces))))
+      t
+    nil))
+
+(defun haskell-ds-line-commented-p ()
+  "Tests if all characters from `point' to `end-of-line' pass
+`haskell-ds-comment-p'"
+  (let ((r t))
+    (while (and r (not (eolp)))
+      (if (not (haskell-ds-comment-p))
+          (setq r nil))
+      (forward-char))
+    r))
+
+(defun haskell-ds-forward-decl ()
+  "Move forward to the first character that starts a top-level
+declaration.  As `haskell-ds-backward-decl' but forward."
+  (interactive)
+  (let ((p (point)) b e empty was-at-bob)
+    ;; Go back to beginning of defun, then go to beginning of next
+    (haskell-ds-move-to-decl nil (haskell-ds-bird-p) nil)
+    (setq b (point))
+    (haskell-ds-move-to-decl t (haskell-ds-bird-p) nil)
+    (setq e (point))
+    ;; tests if line is empty
+    (setq empty (and (<= (point) p)
+                     (not (eolp))))
+    (setq was-at-bob (and (= (point-min) b)
+                          (= b p)
+                          (< p e)))
+    ;; this conditional allows for when empty lines at end, first
+    ;; `C-M-e' will go to end of defun, next will go to end of file.
+    (when (or was-at-bob
+              empty)
+      (if (or (and was-at-bob
+                   (= ?\n
+                      (save-excursion
+                        (goto-char (point-min))
+                        (following-char))))
+              empty)
+          (haskell-ds-move-to-decl t (haskell-ds-bird-p) nil))
+      ;; Then go back to end of current
+      (forward-line -1)
+      (while (and (haskell-ds-line-commented-p)
+                  ;; prevent infinite loop
+                  (not (bobp)))
+        (forward-line -1))
+      (forward-line 1)))
+  (point))
+
+(defun haskell-ds-generic-find-next-decl (bird-literate)
+  "Find the name, position and type of the declaration at or after point.
+Return ((NAME . (START-POSITION . NAME-POSITION)) . TYPE)
+if one exists and nil otherwise.  The start-position is at the start
+of the declaration, and the name-position is at the start of the name
+of the declaration.  The name is a string, the positions are buffer
+positions and the type is one of the symbols \"variable\", \"datatype\",
+\"class\", \"import\" and \"instance\"."
+  (let ( ;; The name, type and name-position of the declaration to
+        ;; return.
+        name
+        type
+        name-pos
+        ;; Buffer positions marking the start and end of the space
+        ;; containing a declaration.
+        start
+        end)
+    ;; Change to declaration scanning syntax.
+    (with-syntax-table haskell-ds-syntax-table
+      ;; Stop when we are at the end of the buffer or when a valid
+      ;; declaration is grabbed.
+      (while (not (or (eobp) name))
+        ;; Move forward to next declaration at or after point.
+        (haskell-ds-move-to-decl t bird-literate t)
+        ;; Start and end of search space is currently just the starting
+        ;; line of the declaration.
+        (setq start (point)
+              end   (line-end-position))
+        (cond
+         ;; If the start of the top-level declaration does not begin
+         ;; with a starting keyword, then (if legal) must be a type
+         ;; signature or value binding, and the variable concerned is
+         ;; grabbed.
+         ((not (looking-at haskell-ds-start-keywords-re))
+          (setq name (haskell-ds-get-variable ""))
+          (if name
+              (progn
+                (setq type 'variable)
+                (re-search-forward (regexp-quote name) end t)
+                (setq name-pos (match-beginning 0)))))
+         ;; User-defined datatype declaration.
+         ((re-search-forward "\\=\\(data\\|newtype\\|type\\)\\>" end t)
+          (re-search-forward "=>" end t)
+          (if (looking-at "[ \t]*\\(\\sw+\\)")
+              (progn
+                (setq name (match-string-no-properties 1))
+                (setq name-pos (match-beginning 1))
+                (setq type 'datatype))))
+         ;; Class declaration.
+         ((re-search-forward "\\=class\\>" end t)
+          (re-search-forward "=>" end t)
+          (if (looking-at "[ \t]*\\(\\sw+\\)")
+              (progn
+                (setq name (match-string-no-properties 1))
+                (setq name-pos (match-beginning 1))
+                (setq type 'class))))
+         ;; Import declaration.
+         ((looking-at "import[ \t]+\\(?:safe[\t ]+\\)?\\(?:qualified[ \t]+\\)?\\(?:\"[^\"]*\"[\t ]+\\)?\\(\\(?:\\sw\\|.\\)+\\)")
+          (setq name (match-string-no-properties 1))
+          (setq name-pos (match-beginning 1))
+          (setq type 'import))
+         ;; Instance declaration.
+         ((re-search-forward "\\=instance[ \t]+" end t)
+          (re-search-forward "=>[ \t]+" end t)
+          ;; The instance "title" starts just after the `instance' (and
+          ;; any context) and finishes just before the _first_ `where'
+          ;; if one exists.  This solution is ugly, but I can't find a
+          ;; nicer one---a simple regexp will pick up the last `where',
+          ;; which may be rare but nevertheless...
+          (setq name-pos (point))
+          (setq name (buffer-substring-no-properties
+                      (point)
+                      (progn
+                        ;; Look for a `where'.
+                        (if (re-search-forward "\\<where\\>" end t)
+                            ;; Move back to just before the `where'.
+                            (progn
+                              (re-search-backward "\\s-where")
+                              (point))
+                          ;; No `where' so move to last non-whitespace
+                          ;; before `end'.
+                          (progn
+                            (goto-char end)
+                            (skip-chars-backward " \t")
+                            (point))))))
+          ;; If we did not manage to extract a name, cancel this
+          ;; declaration (eg. when line ends in "=> ").
+          (if (string-match "^[ \t]*$" name) (setq name nil))
+          (setq type 'instance)))
+        ;; Move past start of current declaration.
+        (goto-char end))
+      ;; If we have a valid declaration then return it, otherwise return
+      ;; nil.
+      (if name
+          (cons (cons name (cons (copy-marker start t) (copy-marker name-pos t)))
+                type)
+        nil))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Declaration scanning via `imenu'.
+
+;;;###autoload
+(defun haskell-ds-create-imenu-index ()
+  "Function for finding `imenu' declarations in Haskell mode.
+Finds all declarations (classes, variables, imports, instances and
+datatypes) in a Haskell file for the `imenu' package."
+  ;; Each list has elements of the form `(INDEX-NAME . INDEX-POSITION)'.
+  ;; These lists are nested using `(INDEX-TITLE . INDEX-ALIST)'.
+  (let* ((bird-literate (haskell-ds-bird-p))
+         (index-alist '())
+         (index-class-alist '()) ;; Classes
+         (index-var-alist '())   ;; Variables
+         (index-imp-alist '())   ;; Imports
+         (index-inst-alist '())  ;; Instances
+         (index-type-alist '())  ;; Datatypes
+         ;; Variables for showing progress.
+         (bufname (buffer-name))
+         (divisor-of-progress (max 1 (/ (buffer-size) 100)))
+         ;; The result we wish to return.
+         result)
+    (goto-char (point-min))
+    ;; Loop forwards from the beginning of the buffer through the
+    ;; starts of the top-level declarations.
+    (while (< (point) (point-max))
+      (message "Scanning declarations in %s... (%3d%%)" bufname
+               (/ (- (point) (point-min)) divisor-of-progress))
+      ;; Grab the next declaration.
+      (setq result (haskell-ds-generic-find-next-decl bird-literate))
+      (if result
+          ;; If valid, extract the components of the result.
+          (let* ((name-posns (car result))
+                 (name (car name-posns))
+                 (posns (cdr name-posns))
+                 (start-pos (car posns))
+                 (type (cdr result)))
+                 ;; Place `(name . start-pos)' in the correct alist.
+                 (cl-case type
+                   (variable
+                    (setq index-var-alist
+                          (cl-acons name start-pos index-var-alist)))
+                   (datatype
+                    (setq index-type-alist
+                          (cl-acons name start-pos index-type-alist)))
+                   (class
+                    (setq index-class-alist
+                          (cl-acons name start-pos index-class-alist)))
+                   (import
+                    (setq index-imp-alist
+                          (cl-acons name start-pos index-imp-alist)))
+                   (instance
+                    (setq index-inst-alist
+                          (cl-acons name start-pos index-inst-alist)))))))
+    ;; Now sort all the lists, label them, and place them in one list.
+    (message "Sorting declarations in %s..." bufname)
+    (when index-type-alist
+      (push (cons "Datatypes"
+                  (sort index-type-alist 'haskell-ds-imenu-label-cmp))
+            index-alist))
+    (when index-inst-alist
+      (push (cons "Instances"
+                  (sort index-inst-alist 'haskell-ds-imenu-label-cmp))
+            index-alist))
+    (when index-imp-alist
+      (push (cons "Imports"
+                  (sort index-imp-alist 'haskell-ds-imenu-label-cmp))
+            index-alist))
+    (when index-class-alist
+      (push (cons "Classes"
+                  (sort index-class-alist 'haskell-ds-imenu-label-cmp))
+            index-alist))
+    (when index-var-alist
+      (if haskell-decl-scan-bindings-as-variables
+          (push (cons "Variables"
+                      (sort index-var-alist 'haskell-ds-imenu-label-cmp))
+                index-alist)
+        (setq index-alist (append index-alist
+                                  (sort index-var-alist 'haskell-ds-imenu-label-cmp)))))
+    (message "Sorting declarations in %s...done" bufname)
+    ;; Return the alist.
+    index-alist))
+
+(defun haskell-ds-imenu-label-cmp (el1 el2)
+  "Predicate to compare labels in lists from `haskell-ds-create-imenu-index'."
+  (string< (car el1) (car el2)))
+
+(defun haskell-ds-imenu ()
+  "Install `imenu' for Haskell scripts."
+  (setq imenu-create-index-function 'haskell-ds-create-imenu-index)
+  (when haskell-decl-scan-add-to-menubar
+    (imenu-add-to-menubar "Declarations")))
+
+;; The main functions to turn on declaration scanning.
+;;;###autoload
+(defun turn-on-haskell-decl-scan ()
+  "Unconditionally activate `haskell-decl-scan-mode'."
+  (interactive)
+  (haskell-decl-scan-mode))
+(make-obsolete 'turn-on-haskell-decl-scan
+               'haskell-decl-scan-mode
+               "2015-07-23")
+
+;;;###autoload
+(define-minor-mode haskell-decl-scan-mode
+  "Toggle Haskell declaration scanning minor mode on or off.
+With a prefix argument ARG, enable minor mode if ARG is
+positive, and disable it otherwise.  If called from Lisp, enable
+the mode if ARG is omitted or nil, and toggle it if ARG is `toggle'.
+
+See also info node `(haskell-mode)haskell-decl-scan-mode' for
+more details about this minor mode.
+
+Top-level declarations are scanned and listed in the menu item
+\"Declarations\" (if enabled via option
+`haskell-decl-scan-add-to-menubar').  Selecting an item from this
+menu will take point to the start of the declaration.
+
+\\[beginning-of-defun] and \\[end-of-defun] move forward and backward to the start of a declaration.
+
+This may link with `haskell-doc-mode'.
+
+For non-literate and LaTeX-style literate scripts, we assume the
+common convention that top-level declarations start at the first
+column.  For Bird-style literate scripts, we assume the common
+convention that top-level declarations start at the third column,
+ie. after \"> \".
+
+Anything in `font-lock-comment-face' is not considered for a
+declaration.  Therefore, using Haskell font locking with comments
+coloured in `font-lock-comment-face' improves declaration scanning.
+
+Literate Haskell scripts are supported: If the value of
+`haskell-literate' (set automatically by `literate-haskell-mode')
+is `bird', a Bird-style literate script is assumed.  If it is nil
+or `tex', a non-literate or LaTeX-style literate script is
+assumed, respectively.
+
+Invokes `haskell-decl-scan-mode-hook' on activation."
+  :group 'haskell-decl-scan
+
+  (kill-local-variable 'beginning-of-defun-function)
+  (kill-local-variable 'end-of-defun-function)
+  (kill-local-variable 'imenu-create-index-function)
+  (unless haskell-decl-scan-mode
+    ;; How can we cleanly remove the "Declarations" menu?
+    (when haskell-decl-scan-add-to-menubar
+      (local-set-key [menu-bar index] nil)))
+
+  (when haskell-decl-scan-mode
+    (setq-local beginning-of-defun-function 'haskell-ds-backward-decl)
+    (setq-local end-of-defun-function 'haskell-ds-forward-decl)
+    (haskell-ds-imenu)))
+
+
+;; Provide ourselves:
+
+(provide 'haskell-decl-scan)
+
+;;; haskell-decl-scan.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-decl-scan.elc b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-decl-scan.elc
new file mode 100644
index 0000000000..f00f8d1eba
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-decl-scan.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-doc.el b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-doc.el
new file mode 100644
index 0000000000..5ac49b8f87
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-doc.el
@@ -0,0 +1,1861 @@
+;;; haskell-doc.el --- show function types in echo area  -*- coding: utf-8; lexical-binding: t -*-
+
+;; Copyright © 2004, 2005, 2006, 2007, 2009, 2016  Free Software Foundation, Inc.
+;; Copyright © 1997  Hans-Wolfgang Loidl
+;;             2016  Arthur Fayzrakhmanov
+
+;; Author: Hans-Wolfgang Loidl <hwloidl@dcs.glasgow.ac.uk>
+;; Temporary Maintainer and Hacker: Graeme E Moss <gem@cs.york.ac.uk>
+;; Keywords: extensions, minor mode, language mode, Haskell
+;; Created: 1997-06-17
+;; URL: http://cvs.haskell.org/cgi-bin/cvsweb.cgi/fptools/CONTRIB/haskell-modes/emacs/haskell-doc.el?rev=HEAD
+
+;; This file is not part of GNU Emacs.
+
+;; This program 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, or (at your option)
+;; any later version.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This program shows the type of the Haskell function under the cursor in the
+;; minibuffer.  It acts as a kind of "Emacs background process", by regularly
+;; checking the word under the cursor and matching it against a list of
+;; prelude, library, local and global functions.
+
+;; This program was inspired by the `eldoc.el' package by Noah Friedman.
+
+;; Installation:
+
+;; Depending on the major mode you use for your Haskell programs add
+;; one of the following to your .emacs:
+;;
+;;   (add-hook 'haskell-mode-hook 'haskell-doc-mode)
+
+;; Customisation:
+
+;; You can control what exactly is shown by setting the following variables to
+;; either t or nil:
+;;  `haskell-doc-show-global-types' (default: nil)
+;;  `haskell-doc-show-reserved'     (default: t)
+;;  `haskell-doc-show-prelude'      (default: t)
+;;  `haskell-doc-show-strategy'     (default: t)
+;;  `haskell-doc-show-user-defined' (default: t)
+
+;; If you want to define your own strings for some identifiers define an
+;; alist of (ID . STRING) and set `haskell-doc-show-user-defined' to t.
+;; E.g:
+;;
+;;   (setq haskell-doc-show-user-defined t)
+;;   (setq haskell-doc-user-defined-ids
+;;      (list
+;;         '("main" . "just another pathetic main function")
+;;         '("foo" . "a very dummy name")
+;;         '("bar" . "another dummy name")))
+
+;;  The following two variables are useful to make the type fit on one line:
+;;  If `haskell-doc-chop-off-context' is non-nil the context part of the type
+;;  of a local fct will be eliminated (default: t).
+;;  If `haskell-doc-chop-off-fctname' is non-nil the function name is not
+;;  shown together with the type (default: nil).
+
+;; Internals:
+
+;; `haskell-doc-mode' is implemented as a minor-mode.  So, you can combine it
+;; with any other mode.  To enable it just type
+;;   M-x haskell-doc-mode
+
+;; These are the names of the functions that can be called directly by the
+;; user (with keybindings in `haskell-mode'):
+;;  `haskell-doc-mode' ... toggle haskell-doc-mode; with prefix turn it on
+;;                        unconditionally if the prefix is greater 0 otherwise
+;;                        turn it off
+;;                        Key: CTRL-c CTRL-o (CTRL-u CTRL-c CTRL-o)
+;;  `haskell-doc-ask-mouse-for-type' ... show the type of the id under the mouse
+;;                                      Key: C-S-M-mouse-3
+;;  `haskell-doc-show-reserved'     ... toggle echoing of reserved id's types
+;;  `haskell-doc-show-prelude'      ... toggle echoing of prelude id's types
+;;  `haskell-doc-show-strategy'     ... toggle echoing of strategy id's types
+;;  `haskell-doc-show-user-defined' ... toggle echoing of user def id's types
+;;  `haskell-doc-check-active' ... check whether haskell-doc is active;
+;;                                 Key: CTRL-c ESC-/
+
+;; ToDo:
+
+;;   - Fix byte-compile problems in `haskell-doc-prelude-types' for getArgs etc
+;;   - Write a parser for .hi files.  Read library interfaces via this parser.
+;;   - Indicate kind of object with colours
+;;   - Handle multi-line types
+;;   - Encode i-am-fct info in the alist of ids and types.
+
+;; Bugs:
+
+;;   - Some prelude fcts aren't displayed properly.  This might be due to a
+;;     name clash of Haskell and Elisp functions (e.g. length) which
+;;     confuses Emacs when reading `haskell-doc-prelude-types'
+
+;;; Changelog:
+
+;;  $Log: haskell-doc.el,v $
+;;  Revision 1.31 2015/07/23 10:34:20  ankhers
+;;  (turn-on-haskell-doc-mode): marked obsolete
+;;  (turn-on-haskell-doc): marked obsolete
+;;  other packages have been moving away from (turn-on-haskell-*)
+;;
+;;  Revision 1.30  2009/02/02 21:00:33  monnier
+;;  (haskell-doc-imported-list): Don't add current buffer
+;;  to the imported file list if it is not (yet?) visiting a file.
+;;
+;;  Revision 1.29  2007-12-12 04:04:19  monnier
+;;  (haskell-doc-in-code-p): New function.
+;;  (haskell-doc-show-type): Use it.
+;;
+;;  Revision 1.28  2007/08/30 03:10:08  monnier
+;;  Comment/docs fixes.
+;;
+;;  Revision 1.27  2007/07/30 17:36:50  monnier
+;;  (displayed-month): Remove declaration since it's not used here.
+;;
+;;  Revision 1.26  2007/02/10 06:28:55  monnier
+;;  (haskell-doc-get-current-word): Remove.
+;;  Change all refs to it, to use haskell-ident-at-point instead.
+;;
+;;  Revision 1.25  2007/02/09 21:53:42  monnier
+;;  (haskell-doc-get-current-word): Correctly distinguish
+;;  variable identifiers and infix identifiers.
+;;  (haskell-doc-rescan-files): Avoid switch-to-buffer.
+;;  (haskell-doc-imported-list): Operate on current buffer.
+;;  (haskell-doc-make-global-fct-index): Adjust call.
+;;
+;;  Revision 1.24  2006/11/20 20:18:24  monnier
+;;  (haskell-doc-mode-print-current-symbol-info): Fix thinko.
+;;
+;;  Revision 1.23  2006/10/20 03:12:31  monnier
+;;  Drop post-command-idle-hook in favor of run-with-idle-timer.
+;;  (haskell-doc-timer, haskell-doc-buffers): New vars.
+;;  (haskell-doc-mode): Use them.
+;;  (haskell-doc-check-active): Update the check.
+;;  (haskell-doc-mode-print-current-symbol-info): Remove the interactive spec.
+;;  Don't sit-for unless it's really needed.
+;;
+;;  Revision 1.22  2006/09/20 18:42:35  monnier
+;;  Doc fix.
+;;
+;;  Revision 1.21  2005/11/21 21:48:52  monnier
+;;  * haskell-doc.el (haskell-doc-extract-types): Get labelled data working.
+;;  (haskell-doc-prelude-types): Update via auto-generation.
+;;
+;;  * haskell-doc.el (haskell-doc-extract-types): Get it partly working.
+;;  (haskell-doc-fetch-lib-urls): Don't use a literal if we apply
+;;  `nreverse' on it later on.
+;;  (haskell-doc-prelude-types): Update some parts by auto-generation.
+;;  (haskell-doc-grab, haskell-doc-string-nub-ws): Simplify.
+;;
+;;  * haskell-doc.el (haskell-doc-maintainer, haskell-doc-varlist)
+;;  (haskell-doc-submit-bug-report, haskell-doc-ftp-site)
+;;  (haskell-doc-visit-home): Remove.
+;;  (haskell-doc-reserved-ids, haskell-doc-fetch-lib-urls)
+;;  (haskell-doc-extract-and-insert-types): New funs.
+;;  (haskell-doc-reserved-ids): Fix type of `map'.
+;;
+;;  Revision 1.20  2005/11/21 21:27:57  monnier
+;;  (haskell-doc-extract-types): Get labelled data working.
+;;  (haskell-doc-prelude-types): Update via auto-generation.
+;;
+;;  Revision 1.19  2005/11/21 20:44:13  monnier
+;;  (haskell-doc-extract-types): Get it partly working.
+;;  (haskell-doc-fetch-lib-urls): Don't use a literal if we apply
+;;  `nreverse' on it later on.
+;;  (haskell-doc-prelude-types): Update some parts by auto-generation.
+;;  (haskell-doc-grab, haskell-doc-string-nub-ws): Simplify.
+;;
+;;  Revision 1.18  2005/11/21 18:02:15  monnier
+;;  (haskell-doc-maintainer, haskell-doc-varlist)
+;;  (haskell-doc-submit-bug-report, haskell-doc-ftp-site)
+;;  (haskell-doc-visit-home): Remove.
+;;  (haskell-doc-reserved-ids, haskell-doc-fetch-lib-urls)
+;;  (haskell-doc-extract-and-insert-types): New funs.
+;;  (haskell-doc-reserved-ids): Fix type of `map'.
+;;
+;;  Revision 1.17  2005/11/20 23:55:09  monnier
+;;  Add coding cookie.
+;;
+;;  Revision 1.16  2005/11/07 01:28:16  monnier
+;;  (haskell-doc-xemacs-p, haskell-doc-emacs-p)
+;;  (haskell-doc-message): Remove.
+;;  (haskell-doc-is-id-char-at): Remove.
+;;  (haskell-doc-get-current-word): Rewrite.
+;;
+;;  Revision 1.15  2005/11/04 17:11:12  monnier
+;;  Add arch-tag.
+;;
+;;  Revision 1.14  2005/08/24 11:36:32  monnier
+;;  (haskell-doc-message): Paren typo.
+;;
+;;  Revision 1.13  2005/08/23 19:23:27  monnier
+;;  (haskell-doc-show-type): Assume that the availability
+;;  of display-message won't change at runtime.
+;;
+;;  Revision 1.12  2005/07/18 21:04:14  monnier
+;;  (haskell-doc-message): Remove.
+;;  (haskell-doc-show-type): inline it.  Do nothing for if there's no doc to show.
+;;
+;;  Revision 1.11  2004/12/10 17:33:18  monnier
+;;  (haskell-doc-minor-mode-string): Make it dynamic.
+;;  (haskell-doc-install-keymap): Remove conflicting C-c C-o binding.
+;;  (haskell-doc-mode): Make a nil arg turn the mode ON.
+;;  (turn-on-haskell-doc-mode): Make it an alias for haskell-doc-mode.
+;;  (haskell-doc-mode): Don't touch haskell-doc-minor-mode-string.
+;;  (haskell-doc-show-global-types): Don't touch
+;;  haskell-doc-minor-mode-string.  Call haskell-doc-make-global-fct-index.
+;;  (haskell-doc-check-active): Fix message.
+;;  (define-key-after): Don't define.
+;;  (haskell-doc-install-keymap): Check existence of define-key-after.
+;;
+;;  Revision 1.10  2004/11/25 23:03:23  monnier
+;;  (haskell-doc-sym-doc): Make even the last char bold.
+;;
+;;  Revision 1.9  2004/11/24 22:14:36  monnier
+;;  (haskell-doc-install-keymap): Don't blindly assume there's a Hugs menu.
+;;
+;;  Revision 1.8  2004/11/22 10:45:35  simonmar
+;;  Fix type of getLine
+;;
+;;  Revision 1.7  2004/10/14 22:27:47  monnier
+;;  (turn-off-haskell-doc-mode, haskell-doc-current-info): Don't autoload.
+;;
+;;  Revision 1.6  2004/10/13 22:45:22  monnier
+;;  (haskell-doc): New group.
+;;  (haskell-doc-show-reserved, haskell-doc-show-prelude)
+;;  (haskell-doc-show-strategy, haskell-doc-show-user-defined)
+;;  (haskell-doc-chop-off-context, haskell-doc-chop-off-fctname):
+;;  Make them custom vars.
+;;  (haskell-doc-keymap): Declare and fill it right there.
+;;  (haskell-doc-mode): Simplify.
+;;  (haskell-doc-toggle-var): Make it into what it was supposed to be.
+;;  (haskell-doc-mode-print-current-symbol-info): Simplify.
+;;  (haskell-doc-current-info): New autoloaded function.
+;;  (haskell-doc-sym-doc): New fun extracted from haskell-doc-show-type.
+;;  (haskell-doc-show-type): Use it.
+;;  (haskell-doc-wrapped-type-p): Remove unused var `lim'.
+;;  (haskell-doc-forward-sexp-safe, haskell-doc-current-symbol): Remove.  Unused.
+;;  (haskell-doc-visit-home): Don't require ange-ftp, it's autoloaded.
+;;  (haskell-doc-install-keymap): Simplify.
+;;
+;;  Revision 1.5  2003/01/09 11:56:26  simonmar
+;;  Patches from Ville Skyttä <scop@xemacs.org>, the XEmacs maintainer of
+;;  the haskell-mode:
+;;
+;;   - Make the auto-mode-alist modifications autoload-only.
+;;
+;;  Revision 1.4  2002/10/14 09:55:03  simonmar
+;;  Patch to update the Prelude/libraries function names and to remove
+;;  support for older versions of Haskell.
+;;
+;;  Submitted by: Anders Lau Olsen <alauo@mip.sdu.dk>
+;;
+;;  Revision 1.3  2002/04/30 09:34:37  rrt
+;;  Remove supporting Haskell 1.4 and 1.2 from the ToDo list. It's Far Too Late.
+;;
+;;  Add (require 'imenu). Thanks to N. Y. Kwok.
+;;
+;;  Revision 1.2  2002/04/23 14:45:10  simonmar
+;;  Tweaks to the doc strings and support for customization, from
+;;  Ville Skyttä <scop@xemacs.org>.
+;;
+;;  Revision 1.1  2001/07/19 16:17:36  rrt
+;;  Add the current version of the Moss/Thorn/Marlow Emacs mode, along with its
+;;  web pages and sample files. This is now the preferred mode, and the
+;;  haskell.org pages are being changed to reflect that. Also includes the new
+;;  GHCi mode from Chris Webb.
+;;
+;;  Revision 1.6  1998/12/10 16:27:25  hwloidl
+;;  Minor changes ("Doc" as modeline string, mouse-3 moved to C-S-M-mouse-3)
+;;
+;;  Revision 1.5  1998/09/24 14:25:46  gem
+;;  Fixed minor compatibility bugs with Haskell mode of Moss&Thorn.
+;;  Disabled M-/ binding.
+;;
+;;  Revision 1.4  1997/11/12 23:51:19  hwloidl
+;;  Fixed start-up problem under emacs-19.34.
+;;  Added support for wrapped (multi-line) types and 2 vars to control the
+;;  behaviour with long fct types
+;;
+;;  Revision 1.3  1997/11/03 00:48:03  hwloidl
+;;  Major revision for first release.
+;;  Added alists for showing prelude fcts, haskell syntax, and strategies
+;;  Added mouse interface to show type under mouse
+;;  Fixed bug which causes demon to fall over
+;;  Works now with hugs-mode and haskell-mode under emacs 19.34,20 and xemacs 19.15
+;;
+
+;;; Code:
+
+(require 'haskell-mode)
+(require 'haskell-process)
+(require 'haskell)
+(require 'haskell-utils)
+(require 'inf-haskell)
+(require 'imenu)
+(require 'eldoc)
+
+;;;###autoload
+(defgroup haskell-doc nil
+  "Show Haskell function types in echo area."
+  :group 'haskell
+  :prefix "haskell-doc-")
+
+
+(defvar-local haskell-doc-mode nil
+  "*If non-nil, show the type of the function near point or a related comment.
+
+If the identifier near point is a Haskell keyword and the variable
+`haskell-doc-show-reserved' is non-nil show a one line summary
+of the syntax.
+
+If the identifier near point is a Prelude or one of the standard library
+functions and `haskell-doc-show-prelude' is non-nil show its type.
+
+If the identifier near point is local \(i.e. defined in this module\) check
+the `imenu' list of functions for the type.  This obviously requires that
+your language mode uses `imenu'.
+
+If the identifier near point is global \(i.e. defined in an imported module\)
+and the variable `haskell-doc-show-global-types' is non-nil show the type of its
+function.
+
+If the identifier near point is a standard strategy or a function, type related
+related to strategies and `haskell-doc-show-strategy' is non-nil show the type
+of the function.  Strategies are special to the parallel execution of Haskell.
+If you're not interested in that just turn it off.
+
+If the identifier near point is a user defined function that occurs as key
+in the alist `haskell-doc-user-defined-ids' and the variable
+`haskell-doc-show-user-defined' is non-nil show the type of the function.
+
+This variable is buffer-local.")
+
+(defvar haskell-doc-mode-hook nil
+  "Hook invoked when entering `haskell-doc-mode'.")
+
+(defvar-local haskell-doc-index nil
+  "Variable holding an alist matching file names to fct-type alists.
+The function `haskell-doc-make-global-fct-index' rebuilds this variables
+\(similar to an `imenu' rescan\).
+This variable is buffer-local.")
+
+(defcustom haskell-doc-show-global-types nil
+  "If non-nil, search for the types of global functions by loading the files.
+This variable is buffer-local."
+  :group 'haskell-doc
+  :type 'boolean)
+(make-variable-buffer-local 'haskell-doc-show-global-types)
+
+(defcustom haskell-doc-show-reserved t
+  "If non-nil, show a documentation string for reserved ids.
+This variable is buffer-local."
+  :group 'haskell-doc
+  :type 'boolean)
+(make-variable-buffer-local 'haskell-doc-show-reserved)
+
+(defcustom haskell-doc-show-prelude t
+  "If non-nil, show a documentation string for prelude functions.
+This variable is buffer-local."
+  :group 'haskell-doc
+  :type 'boolean)
+(make-variable-buffer-local 'haskell-doc-show-prelude)
+
+(defcustom haskell-doc-show-strategy t
+  "If non-nil, show a documentation string for strategies.
+This variable is buffer-local."
+  :group 'haskell-doc
+  :type 'boolean)
+(make-variable-buffer-local 'haskell-doc-show-strategy)
+
+(defcustom haskell-doc-show-user-defined t
+  "If non-nil, show a documentation string for user defined ids.
+This variable is buffer-local."
+  :group 'haskell-doc
+  :type 'boolean)
+(make-variable-buffer-local 'haskell-doc-show-user-defined)
+
+(defcustom haskell-doc-chop-off-context t
+  "If non-nil eliminate the context part in a Haskell type."
+  :group 'haskell-doc
+  :type 'boolean)
+
+(defcustom haskell-doc-chop-off-fctname nil
+  "If non-nil omit the function name and show only the type."
+  :group 'haskell-doc
+  :type 'boolean)
+
+(defcustom haskell-doc-use-inf-haskell nil
+  "If non-nil use inf-haskell.el to get type and kind information."
+  :group 'haskell-doc
+  :type 'boolean)
+
+(defvar haskell-doc-search-distance 40  ; distance in characters
+  "*How far to search when looking for the type declaration of fct under cursor.")
+
+
+(defvar haskell-doc-idle-delay 0.50
+  "*Number of seconds of idle time to wait before printing.
+If user input arrives before this interval of time has elapsed after the
+last input, no documentation will be printed.
+
+If this variable is set to 0, no idle time is required.")
+
+(defvar haskell-doc-argument-case 'identity ; 'upcase
+  "Case in which to display argument names of functions, as a symbol.
+This has two preferred values: `upcase' or `downcase'.
+Actually, any name of a function which takes a string as an argument and
+returns another string is acceptable.")
+
+(defvar haskell-doc-mode-message-commands nil
+  "*Obarray of command names where it is appropriate to print in the echo area.
+
+This is not done for all commands since some print their own
+messages in the echo area, and these functions would instantly overwrite
+them.  But `self-insert-command' as well as most motion commands are good
+candidates.
+
+It is probably best to manipulate this data structure with the commands
+`haskell-doc-add-command' and `haskell-doc-remove-command'.")
+
+;;(cond ((null haskell-doc-mode-message-commands)
+;;       ;; If you increase the number of buckets, keep it a prime number.
+;;       (setq haskell-doc-mode-message-commands (make-vector 31 0))
+;;       (let ((list '("self-insert-command"
+;;                     "next-"         "previous-"
+;;                     "forward-"      "backward-"
+;;                     "beginning-of-" "end-of-"
+;;                     "goto-"
+;;                     "recenter"
+;;                     "scroll-"))
+;;             (syms nil))
+;;         (while list
+;;           (setq syms (all-completions (car list) obarray 'fboundp))
+;;           (setq list (cdr list))
+;;           (while syms
+;;             (set (intern (car syms) haskell-doc-mode-message-commands) t)
+;;             (setq syms (cdr syms)))))))
+
+;; Bookkeeping; the car contains the last symbol read from the buffer.
+;; The cdr contains the string last displayed in the echo area, so it can
+;; be printed again if necessary without reconsing.
+(defvar haskell-doc-last-data '(nil . nil))
+
+(defvar haskell-doc-minor-mode-string
+  '(haskell-doc-show-global-types " DOC" " Doc")
+  "*String to display in mode line when Haskell-Doc Mode is enabled.")
+
+
+(defvar haskell-doc-reserved-ids
+  '(("case" . "case exp of { alts [;] }")
+    ("class" . "class [context =>] simpleclass [where { cbody [;] }]")
+    ("data" . "data [context =>] simpletype = constrs [deriving]")
+    ("default" . "default (type1 , ... , typen)")
+    ("deriving" . "deriving (dclass | (dclass1, ... , dclassn))") ; used with data or newtype
+    ("do" . "do { stmts [;] }  stmts -> exp [; stmts] | pat <- exp ; stmts | let decllist ; stmts")
+    ("else" . "if exp then exp else exp")
+    ("if" . "if exp then exp else exp")
+    ("import" . "import [qualified] modid [as modid] [impspec]")
+    ("in" . "let decllist in exp")
+    ("infix" . "infix [digit] ops")
+    ("infixl" . "infixl [digit] ops")
+    ("infixr" . "infixr [digit] ops")
+    ("instance" . "instance [context =>] qtycls inst [where { valdefs [;] }]")
+    ("let" . "let { decl; ...; decl [;] } in exp")
+    ("module" . "module modid [exports] where body")
+    ("newtype" . "newtype [context =>] simpletype = con atype [deriving]")
+    ("of" . "case exp of { alts [;] }")
+    ("then" . "if exp then exp else exp")
+    ("type" . "type simpletype = type")
+    ("where" . "exp where { decl; ...; decl [;] }") ; check that ; see also class, instance, module
+    ("as" . "import [qualified] modid [as modid] [impspec]")
+    ("qualified" . "import [qualified] modid [as modid] [impspec]")
+    ("hiding" . "hiding ( import1 , ... , importn [ , ] )")
+    ("family" . "(type family type [kind] [= type_fam_equations]) | (data family type [kind])"))
+  "An alist of reserved identifiers.
+Each element is of the form (ID . DOC) where both ID and DOC are strings.
+DOC should be a concise single-line string describing the construct in which
+the keyword is used.")
+
+
+(defun haskell-doc-extract-types (url)
+  (with-temp-buffer
+    (insert-file-contents url)
+    (goto-char (point-min))
+    (while (search-forward "&nbsp;" nil t) (replace-match " " t t))
+
+    ;; First, focus on the actual code, removing the surrounding HTML text.
+    (goto-char (point-min))
+    (let ((last (point-min))
+          (modules nil))
+      (while (re-search-forward "^module +\\([[:alnum:]]+\\)" nil t)
+        (let ((module (match-string 1)))
+          (if (member module modules)
+              ;; The library nodes of the HTML doc contain modules twice:
+              ;; once at the top, with only type declarations, and once at
+              ;; the bottom with an actual sample implementation which may
+              ;; include declaration of non-exported values.
+              ;; We're now at this second occurrence is the implementation
+              ;; which should thus be ignored.
+              nil
+            (push module modules)
+            (delete-region last (point))
+            (search-forward "</tt>")
+            ;; Some of the blocks of code are split.
+            (while (looking-at "\\(<[^<>]+>[ \t\n]*\\)*<tt>")
+              (goto-char (match-end 0))
+              (search-forward "</tt>"))
+            (setq last (point)))))
+      (delete-region last (point-max))
+
+      ;; Then process the HTML encoding to get back to pure ASCII.
+      (goto-char (point-min))
+      (while (search-forward "<br>" nil t) (replace-match "\n" t t))
+      ;; (goto-char (point-min))
+      ;; (while (re-search-forward "<[^<>]+>" nil t) (replace-match "" t t))
+      (goto-char (point-min))
+      (while (search-forward "&gt;" nil t) (replace-match ">" t t))
+      (goto-char (point-min))
+      (while (search-forward "&lt;" nil t) (replace-match "<" t t))
+      (goto-char (point-min))
+      (while (search-forward "&amp;" nil t) (replace-match "&" t t))
+      (goto-char (point-min))
+      (if (re-search-forward "&[a-z]+;" nil t)
+          (error "Unexpected charref %s" (match-string 0)))
+      ;; Remove TABS.
+      (goto-char (point-min))
+      (while (search-forward "\t" nil t) (replace-match "        " t t))
+
+      ;; Finally, extract the actual data.
+      (goto-char (point-min))
+      (let* ((elems nil)
+             (space-re "[ \t\n]*\\(?:--.*\n[ \t\n]*\\)*")
+             (comma-re (concat " *," space-re))
+             ;; A list of identifiers.  We have to be careful to weed out
+             ;; entries like "ratPrec = 7 :: Int".  Also ignore entries
+             ;; which start with a < since they're actually in the HTML text
+             ;; part.  And the list may be spread over several lines, cut
+             ;; after a comma.
+             (idlist-re
+              (concat "\\([^< \t\n][^ \t\n]*"
+                      "\\(?:" comma-re "[^ \t\n]+\\)*\\)"))
+             ;; A type.  A few types are spread over 2 lines,
+             ;; cut after the "=>", so we have to handle these as well.
+             (type-re "\\(.*[^\n>]\\(?:>[ \t\n]+.*[^\n>]\\)*\\) *$")
+             ;; A decl of a list of values, possibly indented.
+             (val-decl-re
+              (concat "^\\( +\\)?" idlist-re "[ \t\n]*::[ \t\n]*" type-re))
+             (re (concat
+                  ;; 3 possibilities: a class decl, a data decl, or val decl.
+                  ;; First, let's match a class decl.
+                  "^class \\(?:.*=>\\)? *\\(.*[^ \t\n]\\)[ \t\n]*where"
+
+                  ;; Or a value decl:
+                  "\\|" val-decl-re
+
+                  "\\|" ;; Or a data decl.  We only handle single-arm
+                  ;; datatypes with labels.
+                  "^data +\\([[:alnum:]][[:alnum:] ]*[[:alnum:]]\\)"
+                  " *=.*{\\([^}]+\\)}"
+                  ))
+             (re-class (concat "^[^ \t\n]\\|" re))
+             curclass)
+        (while (re-search-forward (if curclass re-class re) nil t)
+          (cond
+           ;; A class decl.
+           ((match-end 1) (setq curclass (match-string 1)))
+           ;; A value decl.
+           ((match-end 4)
+            (let ((type (match-string 4))
+                  (vars (match-string 3))
+                  (indented (match-end 2)))
+              (if (string-match "[ \t\n][ \t\n]+" type)
+                  (setq type (replace-match " " t t type)))
+              (if (string-match " *\\(--.*\\)?\\'" type)
+                  (setq type (substring type 0 (match-beginning 0))))
+              (if indented
+                  (if curclass
+                      (if (string-match "\\`\\(.*[^ \t\n]\\) *=> *" type)
+                          (let ((classes (match-string 1 type)))
+                            (setq type (substring type (match-end 0)))
+                            (if (string-match "\\`(.*)\\'" classes)
+                                (setq classes (substring classes 1 -1)))
+                            (setq type (concat "(" curclass ", " classes
+                                               ") => " type)))
+                        (setq type (concat curclass " => " type)))
+                    ;; It's actually not an error: just a type annotation on
+                    ;; some local variable.
+                    ;; (error "Indentation outside a class in %s: %s"
+                    ;;        module vars)
+                    nil)
+                (setq curclass nil))
+              (dolist (var (split-string vars comma-re t))
+                (if (string-match "(.*)" var) (setq var (substring var 1 -1)))
+                (push (cons var type) elems))))
+           ;; A datatype decl.
+           ((match-end 5)
+            (setq curclass nil)
+            (let ((name (match-string 5)))
+              (save-excursion
+                (save-restriction
+                  (narrow-to-region (match-beginning 6) (match-end 6))
+                  (goto-char (point-min))
+                  (while (re-search-forward val-decl-re nil t)
+                    (let ((vars (match-string 2))
+                          (type (match-string 3)))
+                      (if (string-match "[ \t\n][ \t\n]+" type)
+                          (setq type (replace-match " " t t type)))
+                      (if (string-match " *\\(--.*\\)?\\'" type)
+                          (setq type (substring type 0 (match-beginning 0))))
+                      (if (string-match ",\\'" type)
+                          (setq type (substring type 0 -1)))
+                      (setq type (concat name " -> " type))
+                      (dolist (var (split-string vars comma-re t))
+                        (if (string-match "(.*)" var)
+                            (setq var (substring var 1 -1)))
+                        (push (cons var type) elems))))))))
+
+           ;; The end of a class declaration.
+           (t (setq curclass nil) (beginning-of-line))))
+        (cons (car (last modules)) elems)))))
+
+(defun haskell-doc-fetch-lib-urls (base-url)
+  (with-temp-buffer
+    (insert-file-contents base-url)
+    (goto-char (point-min))
+    (search-forward "Part II: Libraries")
+    (delete-region (point-min) (point))
+    (search-forward "</table>")
+    (delete-region (point) (point-max))
+    (goto-char (point-min))
+    (let ((libs (list "standard-prelude.html")))
+      (while (re-search-forward "<a href=\"\\([^\"]+\\)\">" nil t)
+        (push (match-string 1) libs))
+      (mapcar (lambda (s) (expand-file-name s (file-name-directory base-url)))
+              (nreverse libs)))))
+
+(defun haskell-doc-extract-and-insert-types (url)
+  "Fetch the types from the online doc and insert them at point.
+URL is the URL of the online doc."
+  (interactive (if current-prefix-arg
+                   (read-file-name "URL: ")
+                 (list "http://www.haskell.org/onlinereport/")))
+  (let ((urls (haskell-doc-fetch-lib-urls url)))
+    (dolist (url urls)
+      (let ((data (haskell-doc-extract-types url)))
+        (insert ";; " (pop data)) (indent-according-to-mode) (newline)
+        (dolist (elem (sort data (lambda (x y) (string-lessp (car x) (car y)))))
+          (prin1 elem (current-buffer))
+          (indent-according-to-mode) (newline))))))
+
+(defvar haskell-doc-prelude-types
+  ;; This list was auto generated by `haskell-doc-extract-and-insert-types'.
+  '(
+    ;; Prelude
+    ("!!" . "[a] -> Int -> a")
+    ("$" . "(a -> b) -> a -> b")
+    ("$!" . "(a -> b) -> a -> b")
+    ("&&" . "Bool -> Bool -> Bool")
+    ("*" . "Num a => a -> a -> a")
+    ("**" . "Floating a => a -> a -> a")
+    ("+" . "Num a => a -> a -> a")
+    ("++" . "[a] -> [a] -> [a]")
+    ("-" . "Num a => a -> a -> a")
+    ("." . "(b -> c) -> (a -> b) -> a -> c")
+    ("/" . "Fractional a => a -> a -> a")
+    ("/=" . "Eq a => a -> a -> Bool")
+    ("<" . "Ord a => a -> a -> Bool")
+    ("<=" . "Ord a => a -> a -> Bool")
+    ("=<<" . "Monad m => (a -> m b) -> m a -> m b")
+    ("==" . "Eq a => a -> a -> Bool")
+    (">" . "Ord a => a -> a -> Bool")
+    (">=" . "Ord a => a -> a -> Bool")
+    (">>" . "Monad m => m a -> m b -> m b")
+    (">>=" . "Monad m => m a -> (a -> m b) -> m b")
+    ("^" . "(Num a, Integral b) => a -> b -> a")
+    ("^^" . "(Fractional a, Integral b) => a -> b -> a")
+    ("abs" . "Num a => a -> a")
+    ("acos" . "Floating a => a -> a")
+    ("acosh" . "Floating a => a -> a")
+    ("all" . "(a -> Bool) -> [a] -> Bool")
+    ("and" . "[Bool] -> Bool")
+    ("any" . "(a -> Bool) -> [a] -> Bool")
+    ("appendFile" . "FilePath -> String -> IO ()")
+    ("asTypeOf" . "a -> a -> a")
+    ("asin" . "Floating a => a -> a")
+    ("asinh" . "Floating a => a -> a")
+    ("atan" . "Floating a => a -> a")
+    ("atan2" . "RealFloat a => a -> a -> a")
+    ("atanh" . "Floating a => a -> a")
+    ("break" . "(a -> Bool) -> [a] -> ([a],[a])")
+    ("catch" . "IO a -> (IOError -> IO a) -> IO a")
+    ("ceiling" . "(RealFrac a, Integral b) => a -> b")
+    ("compare" . "Ord a => a -> a -> Ordering")
+    ("concat" . "[[a]] -> [a]")
+    ("concatMap" . "(a -> [b]) -> [a] -> [b]")
+    ("const" . "a -> b -> a")
+    ("cos" . "Floating a => a -> a")
+    ("cosh" . "Floating a => a -> a")
+    ("curry" . "((a, b) -> c) -> a -> b -> c")
+    ("cycle" . "[a] -> [a]")
+    ("decodeFloat" . "RealFloat a => a -> (Integer,Int)")
+    ("div" . "Integral a => a -> a -> a")
+    ("divMod" . "Integral a => a -> a -> (a,a)")
+    ("drop" . "Int -> [a] -> [a]")
+    ("dropWhile" . "(a -> Bool) -> [a] -> [a]")
+    ("either" . "(a -> c) -> (b -> c) -> Either a b -> c")
+    ("elem" . "(Eq a) => a -> [a] -> Bool")
+    ("encodeFloat" . "RealFloat a => Integer -> Int -> a")
+    ("enumFrom" . "Enum a => a -> [a]")
+    ("enumFromThen" . "Enum a => a -> a -> [a]")
+    ("enumFromThenTo" . "Enum a => a -> a -> a -> [a]")
+    ("enumFromTo" . "Enum a => a -> a -> [a]")
+    ("error" . "String -> a")
+    ("even" . "(Integral a) => a -> Bool")
+    ("exp" . "Floating a => a -> a")
+    ("exponent" . "RealFloat a => a -> Int")
+    ("fail" . "Monad m => String -> m a")
+    ("filter" . "(a -> Bool) -> [a] -> [a]")
+    ("flip" . "(a -> b -> c) -> b -> a -> c")
+    ("floatDigits" . "RealFloat a => a -> Int")
+    ("floatRadix" . "RealFloat a => a -> Integer")
+    ("floatRange" . "RealFloat a => a -> (Int,Int)")
+    ("floor" . "(RealFrac a, Integral b) => a -> b")
+    ("fmap" . "Functor f => (a -> b) -> f a -> f b")
+    ("foldl" . "(a -> b -> a) -> a -> [b] -> a")
+    ("foldl1" . "(a -> a -> a) -> [a] -> a")
+    ("foldr" . "(a -> b -> b) -> b -> [a] -> b")
+    ("foldr1" . "(a -> a -> a) -> [a] -> a")
+    ("fromEnum" . "Enum a => a -> Int")
+    ("fromInteger" . "Num a => Integer -> a")
+    ("fromIntegral" . "(Integral a, Num b) => a -> b")
+    ("fromRational" . "Fractional a => Rational -> a")
+    ("fst" . "(a,b) -> a")
+    ("gcd" . "(Integral a) => a -> a -> a")
+    ("getChar" . "IO Char")
+    ("getContents" . "IO String")
+    ("getLine" . "IO String")
+    ("head" . "[a] -> a")
+    ("id" . "a -> a")
+    ("init" . "[a] -> [a]")
+    ("interact" . "(String -> String) -> IO ()")
+    ("ioError" . "IOError -> IO a")
+    ("isDenormalized" . "RealFloat a => a -> Bool")
+    ("isIEEE" . "RealFloat a => a -> Bool")
+    ("isInfinite" . "RealFloat a => a -> Bool")
+    ("isNaN" . "RealFloat a => a -> Bool")
+    ("isNegativeZero" . "RealFloat a => a -> Bool")
+    ("iterate" . "(a -> a) -> a -> [a]")
+    ("last" . "[a] -> a")
+    ("lcm" . "(Integral a) => a -> a -> a")
+    ("length" . "[a] -> Int")
+    ("lex" . "ReadS String")
+    ("lines" . "String -> [String]")
+    ("log" . "Floating a => a -> a")
+    ("logBase" . "Floating a => a -> a -> a")
+    ("lookup" . "(Eq a) => a -> [(a,b)] -> Maybe b")
+    ("map" . "(a -> b) -> [a] -> [b]")
+    ("mapM" . "Monad m => (a -> m b) -> [a] -> m [b]")
+    ("mapM_" . "Monad m => (a -> m b) -> [a] -> m ()")
+    ("max" . "Ord a => a -> a -> a")
+    ("maxBound" . "Bounded a => a")
+    ("maximum" . "(Ord a) => [a] -> a")
+    ("maybe" . "b -> (a -> b) -> Maybe a -> b")
+    ("min" . "Ord a => a -> a -> a")
+    ("minBound" . "Bounded a => a")
+    ("minimum" . "(Ord a) => [a] -> a")
+    ("mod" . "Integral a => a -> a -> a")
+    ("negate" . "Num a => a -> a")
+    ("not" . "Bool -> Bool")
+    ("notElem" . "(Eq a) => a -> [a] -> Bool")
+    ("null" . "[a] -> Bool")
+    ("numericEnumFrom" . "(Fractional a) => a -> [a]")
+    ("numericEnumFromThen" . "(Fractional a) => a -> a -> [a]")
+    ("numericEnumFromThenTo" . "(Fractional a, Ord a) => a -> a -> a -> [a]")
+    ("numericEnumFromTo" . "(Fractional a, Ord a) => a -> a -> [a]")
+    ("odd" . "(Integral a) => a -> Bool")
+    ("or" . "[Bool] -> Bool")
+    ("otherwise" . "Bool")
+    ("pi" . "Floating a => a")
+    ("pred" . "Enum a => a -> a")
+    ("print" . "Show a => a -> IO ()")
+    ("product" . "(Num a) => [a] -> a")
+    ("properFraction" . "(RealFrac a, Integral b) => a -> (b,a)")
+    ("putChar" . "Char -> IO ()")
+    ("putStr" . "String -> IO ()")
+    ("putStrLn" . "String -> IO ()")
+    ("quot" . "Integral a => a -> a -> a")
+    ("quotRem" . "Integral a => a -> a -> (a,a)")
+    ("read" . "(Read a) => String -> a")
+    ("readFile" . "FilePath -> IO String")
+    ("readIO" . "Read a => String -> IO a")
+    ("readList" . "Read a => ReadS [a]")
+    ("readLn" . "Read a => IO a")
+    ("readParen" . "Bool -> ReadS a -> ReadS a")
+    ("reads" . "(Read a) => ReadS a")
+    ("readsPrec" . "Read a => Int -> ReadS a")
+    ("realToFrac" . "(Real a, Fractional b) => a -> b")
+    ("recip" . "Fractional a => a -> a")
+    ("rem" . "Integral a => a -> a -> a")
+    ("repeat" . "a -> [a]")
+    ("replicate" . "Int -> a -> [a]")
+    ("return" . "Monad m => a -> m a")
+    ("reverse" . "[a] -> [a]")
+    ("round" . "(RealFrac a, Integral b) => a -> b")
+    ("scaleFloat" . "RealFloat a => Int -> a -> a")
+    ("scanl" . "(a -> b -> a) -> a -> [b] -> [a]")
+    ("scanl1" . "(a -> a -> a) -> [a] -> [a]")
+    ("scanr" . "(a -> b -> b) -> b -> [a] -> [b]")
+    ("scanr1" . "(a -> a -> a) -> [a] -> [a]")
+    ("seq" . "a -> b -> b")
+    ("sequence" . "Monad m => [m a] -> m [a]")
+    ("sequence_" . "Monad m => [m a] -> m ()")
+    ("show" . "Show a => a -> String")
+    ("showChar" . "Char -> ShowS")
+    ("showList" . "Show a => [a] -> ShowS")
+    ("showParen" . "Bool -> ShowS -> ShowS")
+    ("showString" . "String -> ShowS")
+    ("shows" . "(Show a) => a -> ShowS")
+    ("showsPrec" . "Show a => Int -> a -> ShowS")
+    ("significand" . "RealFloat a => a -> a")
+    ("signum" . "Num a => a -> a")
+    ("sin" . "Floating a => a -> a")
+    ("sinh" . "Floating a => a -> a")
+    ("snd" . "(a,b) -> b")
+    ("span" . "(a -> Bool) -> [a] -> ([a],[a])")
+    ("splitAt" . "Int -> [a] -> ([a],[a])")
+    ("sqrt" . "Floating a => a -> a")
+    ("subtract" . "(Num a) => a -> a -> a")
+    ("succ" . "Enum a => a -> a")
+    ("sum" . "(Num a) => [a] -> a")
+    ("tail" . "[a] -> [a]")
+    ("take" . "Int -> [a] -> [a]")
+    ("takeWhile" . "(a -> Bool) -> [a] -> [a]")
+    ("tan" . "Floating a => a -> a")
+    ("tanh" . "Floating a => a -> a")
+    ("toEnum" . "Enum a => Int -> a")
+    ("toInteger" . "Integral a => a -> Integer")
+    ("toRational" . "Real a => a -> Rational")
+    ("truncate" . "(RealFrac a, Integral b) => a -> b")
+    ("uncurry" . "(a -> b -> c) -> ((a, b) -> c)")
+    ("undefined" . "a")
+    ("unlines" . "[String] -> String")
+    ("until" . "(a -> Bool) -> (a -> a) -> a -> a")
+    ("unwords" . "[String] -> String")
+    ("unzip" . "[(a,b)] -> ([a],[b])")
+    ("unzip3" . "[(a,b,c)] -> ([a],[b],[c])")
+    ("userError" . "String -> IOError")
+    ("words" . "String -> [String]")
+    ("writeFile" . "FilePath -> String -> IO ()")
+    ("zip" . "[a] -> [b] -> [(a,b)]")
+    ("zip3" . "[a] -> [b] -> [c] -> [(a,b,c)]")
+    ("zipWith" . "(a->b->c) -> [a]->[b]->[c]")
+    ("zipWith3" . "(a->b->c->d) -> [a]->[b]->[c]->[d]")
+    ("||" . "Bool -> Bool -> Bool")
+    ;; Ratio
+    ("%" . "(Integral a) => a -> a -> Ratio a")
+    ("approxRational" . "(RealFrac a) => a -> a -> Rational")
+    ("denominator" . "(Integral a) => Ratio a -> a")
+    ("numerator" . "(Integral a) => Ratio a -> a")
+    ;; Complex
+    ("cis" . "(RealFloat a) => a -> Complex a")
+    ("conjugate" . "(RealFloat a) => Complex a -> Complex a")
+    ("imagPart" . "(RealFloat a) => Complex a -> a")
+    ("magnitude" . "(RealFloat a) => Complex a -> a")
+    ("mkPolar" . "(RealFloat a) => a -> a -> Complex a")
+    ("phase" . "(RealFloat a) => Complex a -> a")
+    ("polar" . "(RealFloat a) => Complex a -> (a,a)")
+    ("realPart" . "(RealFloat a) => Complex a -> a")
+    ;; Numeric
+    ("floatToDigits" . "(RealFloat a) => Integer -> a -> ([Int], Int)")
+    ("fromRat" . "(RealFloat a) => Rational -> a")
+    ("lexDigits" . "ReadS String")
+    ("readDec" . "(Integral a) => ReadS a")
+    ("readFloat" . "(RealFrac a) => ReadS a")
+    ("readHex" . "(Integral a) => ReadS a")
+    ("readInt" . "(Integral a) => a -> (Char -> Bool) -> (Char -> Int) -> ReadS a")
+    ("readOct" . "(Integral a) => ReadS a")
+    ("readSigned" . "(Real a) => ReadS a -> ReadS a")
+    ("showEFloat" . "(RealFloat a) => Maybe Int -> a -> ShowS")
+    ("showFFloat" . "(RealFloat a) => Maybe Int -> a -> ShowS")
+    ("showFloat" . "(RealFloat a) => a -> ShowS")
+    ("showGFloat" . "(RealFloat a) => Maybe Int -> a -> ShowS")
+    ("showHex" . "Integral a => a -> ShowS")
+    ("showInt" . "Integral a => a -> ShowS")
+    ("showIntAtBase" . "Integral a => a -> (Int -> Char) -> a -> ShowS")
+    ("showOct" . "Integral a => a -> ShowS")
+    ("showSigned" . "(Real a) => (a -> ShowS) -> Int -> a -> ShowS")
+    ;; Ix
+    ("inRange" . "Ix a => (a,a) -> a -> Bool")
+    ("index" . "Ix a => (a,a) -> a -> Int")
+    ("range" . "Ix a => (a,a) -> [a]")
+    ("rangeSize" . "Ix a => (a,a) -> Int")
+    ;; Array
+    ("!" . "(Ix a) => Array a b -> a -> b")
+    ("//" . "(Ix a) => Array a b -> [(a,b)] -> Array a b")
+    ("accum" . "(Ix a) => (b -> c -> b) -> Array a b -> [(a,c)]")
+    ("accumArray" . "(Ix a) => (b -> c -> b) -> b -> (a,a) -> [(a,c)]")
+    ("array" . "(Ix a) => (a,a) -> [(a,b)] -> Array a b")
+    ("assocs" . "(Ix a) => Array a b -> [(a,b)]")
+    ("bounds" . "(Ix a) => Array a b -> (a,a)")
+    ("elems" . "(Ix a) => Array a b -> [b]")
+    ("indices" . "(Ix a) => Array a b -> [a]")
+    ("ixmap" . "(Ix a, Ix b) => (a,a) -> (a -> b) -> Array b c")
+    ("listArray" . "(Ix a) => (a,a) -> [b] -> Array a b")
+    ;; List
+    ("\\\\" . "Eq a => [a] -> [a] -> [a]")
+    ("delete" . "Eq a => a -> [a] -> [a]")
+    ("deleteBy" . "(a -> a -> Bool) -> a -> [a] -> [a]")
+    ("deleteFirstsBy" . "(a -> a -> Bool) -> [a] -> [a] -> [a]")
+    ("elemIndex" . "Eq a => a -> [a] -> Maybe Int")
+    ("elemIndices" . "Eq a => a -> [a] -> [Int]")
+    ("find" . "(a -> Bool) -> [a] -> Maybe a")
+    ("findIndex" . "(a -> Bool) -> [a] -> Maybe Int")
+    ("findIndices" . "(a -> Bool) -> [a] -> [Int]")
+    ("genericDrop" . "Integral a => a -> [b] -> [b]")
+    ("genericIndex" . "Integral a => [b] -> a -> b")
+    ("genericLength" . "Integral a => [b] -> a")
+    ("genericReplicate" . "Integral a => a -> b -> [b]")
+    ("genericSplitAt" . "Integral a => a -> [b] -> ([b],[b])")
+    ("genericTake" . "Integral a => a -> [b] -> [b]")
+    ("group" . "Eq a => [a] -> [[a]]")
+    ("groupBy" . "(a -> a -> Bool) -> [a] -> [[a]]")
+    ("inits" . "[a] -> [[a]]")
+    ("insert" . "Ord a => a -> [a] -> [a]")
+    ("insertBy" . "(a -> a -> Ordering) -> a -> [a] -> [a]")
+    ("intersect" . "Eq a => [a] -> [a] -> [a]")
+    ("intersectBy" . "(a -> a -> Bool) -> [a] -> [a] -> [a]")
+    ("intersperse" . "a -> [a] -> [a]")
+    ("isPrefixOf" . "Eq a => [a] -> [a] -> Bool")
+    ("isSuffixOf" . "Eq a => [a] -> [a] -> Bool")
+    ("mapAccumL" . "(a -> b -> (a, c)) -> a -> [b] -> (a, [c])")
+    ("mapAccumR" . "(a -> b -> (a, c)) -> a -> [b] -> (a, [c])")
+    ("maximumBy" . "(a -> a -> Ordering) -> [a] -> a")
+    ("minimumBy" . "(a -> a -> Ordering) -> [a] -> a")
+    ("nub" . "Eq a => [a] -> [a]")
+    ("nubBy" . "(a -> a -> Bool) -> [a] -> [a]")
+    ("partition" . "(a -> Bool) -> [a] -> ([a],[a])")
+    ("sort" . "Ord a => [a] -> [a]")
+    ("sortBy" . "(a -> a -> Ordering) -> [a] -> [a]")
+    ("tails" . "[a] -> [[a]]")
+    ("transpose" . "[[a]] -> [[a]]")
+    ("unfoldr" . "(b -> Maybe (a,b)) -> b -> [a]")
+    ("union" . "Eq a => [a] -> [a] -> [a]")
+    ("unionBy" . "(a -> a -> Bool) -> [a] -> [a] -> [a]")
+    ("unzip4" . "[(a,b,c,d)] -> ([a],[b],[c],[d])")
+    ("unzip5" . "[(a,b,c,d,e)] -> ([a],[b],[c],[d],[e])")
+    ("unzip6" . "[(a,b,c,d,e,f)] -> ([a],[b],[c],[d],[e],[f])")
+    ("unzip7" . "[(a,b,c,d,e,f,g)] -> ([a],[b],[c],[d],[e],[f],[g])")
+    ("zip4" . "[a] -> [b] -> [c] -> [d] -> [(a,b,c,d)]")
+    ("zip5" . "[a] -> [b] -> [c] -> [d] -> [e] -> [(a,b,c,d,e)]")
+    ("zip6" . "[a] -> [b] -> [c] -> [d] -> [e] -> [f]")
+    ("zip7" . "[a] -> [b] -> [c] -> [d] -> [e] -> [f] -> [g]")
+    ("zipWith4" . "(a->b->c->d->e) -> [a]->[b]->[c]->[d]->[e]")
+    ("zipWith5" . "(a->b->c->d->e->f) ->")
+    ("zipWith6" . "(a->b->c->d->e->f->g) -> [a]->[b]->[c]->[d]->[e]->[f]->[g]")
+    ("zipWith7" . "(a->b->c->d->e->f->g->h) -> [a]->[b]->[c]->[d]->[e]->[f]->[g]->[h]")
+    ;; Maybe
+    ("catMaybes" . "[Maybe a] -> [a]")
+    ("fromJust" . "Maybe a -> a")
+    ("fromMaybe" . "a -> Maybe a -> a")
+    ("isJust" . "Maybe a -> Bool")
+    ("isNothing" . "Maybe a -> Bool")
+    ("listToMaybe" . "[a] -> Maybe a")
+    ("mapMaybe" . "(a -> Maybe b) -> [a] -> [b]")
+    ("maybeToList" . "Maybe a -> [a]")
+    ;; Char
+    ("chr" . "Int -> Char")
+    ("digitToInt" . "Char -> Int")
+    ("intToDigit" . "Int -> Char")
+    ("isAlpha" . "Char -> Bool")
+    ("isAlphaNum" . "Char -> Bool")
+    ("isAscii" . "Char -> Bool")
+    ("isControl" . "Char -> Bool")
+    ("isDigit" . "Char -> Bool")
+    ("isHexDigit" . "Char -> Bool")
+    ("isLatin1" . "Char -> Bool")
+    ("isLower" . "Char -> Bool")
+    ("isOctDigit" . "Char -> Bool")
+    ("isPrint" . "Char -> Bool")
+    ("isSpace" . "Char -> Bool")
+    ("isUpper" . "Char -> Bool")
+    ("lexLitChar" . "ReadS String")
+    ("ord" . "Char -> Int")
+    ("readLitChar" . "ReadS Char")
+    ("showLitChar" . "Char -> ShowS")
+    ("toLower" . "Char -> Char")
+    ("toUpper" . "Char -> Char")
+    ;; Monad
+    ("ap" . "Monad m => m (a -> b) -> m a -> m b")
+    ("filterM" . "Monad m => (a -> m Bool) -> [a] -> m [a]")
+    ("foldM" . "Monad m => (a -> b -> m a) -> a -> [b] -> m a")
+    ("guard" . "MonadPlus m => Bool -> m ()")
+    ("join" . "Monad m => m (m a) -> m a")
+    ("liftM" . "Monad m => (a -> b) -> (m a -> m b)")
+    ("liftM2" . "Monad m => (a -> b -> c) -> (m a -> m b -> m c)")
+    ("liftM3" . "Monad m => (a -> b -> c -> d) -> (m a -> m b -> m c -> m d)")
+    ("liftM4" . "Monad m => (a -> b -> c -> d -> e) -> (m a -> m b -> m c -> m d -> m e)")
+    ("liftM5" . "Monad m => (a -> b -> c -> d -> e -> f) -> (m a -> m b -> m c -> m d -> m e -> m f)")
+    ("mapAndUnzipM" . "Monad m => (a -> m (b,c)) -> [a] -> m ([b], [c])")
+    ("mplus" . "MonadPlus m => m a -> m a -> m a")
+    ("msum" . "MonadPlus m => [m a] -> m a")
+    ("mzero" . "MonadPlus m => m a")
+    ("unless" . "Monad m => Bool -> m () -> m ()")
+    ("when" . "Monad m => Bool -> m () -> m ()")
+    ("zipWithM" . "Monad m => (a -> b -> m c) -> [a] -> [b] -> m [c]")
+    ("zipWithM_" . "Monad m => (a -> b -> m c) -> [a] -> [b] -> m ()")
+    ;; IO
+    ("bracket" . "IO a -> (a -> IO b) -> (a -> IO c) -> IO c")
+    ("bracket_" . "IO a -> (a -> IO b) -> IO c -> IO c")
+    ("hClose" . "Handle -> IO ()")
+    ("hFileSize" . "Handle -> IO Integer")
+    ("hFlush" . "Handle -> IO ()")
+    ("hGetBuffering" . "Handle -> IO BufferMode")
+    ("hGetChar" . "Handle -> IO Char")
+    ("hGetContents" . "Handle -> IO String")
+    ("hGetLine" . "Handle -> IO String")
+    ("hGetPosn" . "Handle -> IO HandlePosn")
+    ("hIsClosed" . "Handle -> IO Bool")
+    ("hIsEOF" . "Handle -> IO Bool")
+    ("hIsOpen" . "Handle -> IO Bool")
+    ("hIsReadable" . "Handle -> IO Bool")
+    ("hIsSeekable" . "Handle -> IO Bool")
+    ("hIsWritable" . "Handle -> IO Bool")
+    ("hLookAhead" . "Handle -> IO Char")
+    ("hPrint" . "Show a => Handle -> a -> IO ()")
+    ("hPutChar" . "Handle -> Char -> IO ()")
+    ("hPutStr" . "Handle -> String -> IO ()")
+    ("hPutStrLn" . "Handle -> String -> IO ()")
+    ("hReady" . "Handle -> IO Bool")
+    ("hSeek" . "Handle -> SeekMode -> Integer -> IO ()")
+    ("hSetBuffering" . "Handle -> BufferMode -> IO ()")
+    ("hSetPosn" . "HandlePosn -> IO ()")
+    ("hWaitForInput" . "Handle -> Int -> IO Bool")
+    ("ioeGetErrorString" . "IOError -> String")
+    ("ioeGetFileName" . "IOError -> Maybe FilePath")
+    ("ioeGetHandle" . "IOError -> Maybe Handle")
+    ("isAlreadyExistsError" . "IOError -> Bool")
+    ("isAlreadyInUseError" . "IOError -> Bool")
+    ("isDoesNotExistError" . "IOError -> Bool")
+    ("isEOF" . "IO Bool")
+    ("isEOFError" . "IOError -> Bool")
+    ("isFullError" . "IOError -> Bool")
+    ("isIllegalOperation" . "IOError -> Bool")
+    ("isPermissionError" . "IOError -> Bool")
+    ("isUserError" . "IOError -> Bool")
+    ("openFile" . "FilePath -> IOMode -> IO Handle")
+    ("stderr" . "Handle")
+    ("stdin" . "Handle")
+    ("stdout" . "Handle")
+    ("try" . "IO a -> IO (Either IOError a)")
+    ;; Directory
+    ("createDirectory" . "FilePath -> IO ()")
+    ("doesDirectoryExist" . "FilePath -> IO Bool")
+    ("doesFileExist" . "FilePath -> IO Bool")
+    ("executable" . "Permissions -> Bool")
+    ("getCurrentDirectory" . "IO FilePath")
+    ("getDirectoryContents" . "FilePath -> IO [FilePath]")
+    ("getModificationTime" . "FilePath -> IO ClockTime")
+    ("getPermissions" . "FilePath -> IO Permissions")
+    ("readable" . "Permissions -> Bool")
+    ("removeDirectory" . "FilePath -> IO ()")
+    ("removeFile" . "FilePath -> IO ()")
+    ("renameDirectory" . "FilePath -> FilePath -> IO ()")
+    ("renameFile" . "FilePath -> FilePath -> IO ()")
+    ("searchable" . "Permissions -> Bool")
+    ("setCurrentDirectory" . "FilePath -> IO ()")
+    ("setPermissions" . "FilePath -> Permissions -> IO ()")
+    ("writable" . "Permissions -> Bool")
+    ;; System
+    ("exitFailure" . "IO a")
+    ("exitWith" . "ExitCode -> IO a")
+    ("getArgs" . "IO [String]")
+    ("getEnv" . "String -> IO String")
+    ("getProgName" . "IO String")
+    ("system" . "String -> IO ExitCode")
+    ;; Time
+    ("addToClockTime" . "TimeDiff -> ClockTime -> ClockTime")
+    ("calendarTimeToString" . "CalendarTime -> String")
+    ("ctDay" . "CalendarTime -> Int")
+    ("ctHour" . "CalendarTime -> Int")
+    ("ctIsDST" . "CalendarTime -> Bool")
+    ("ctMin" . "CalendarTime -> Int")
+    ("ctMonth" . "CalendarTime -> Month")
+    ("ctPicosec" . "CalendarTime -> Integer")
+    ("ctSec" . "CalendarTime -> Int")
+    ("ctTZ" . "CalendarTime -> Int")
+    ("ctTZName" . "CalendarTime -> String")
+    ("ctWDay" . "CalendarTime -> Day")
+    ("ctYDay" . "CalendarTime -> Int")
+    ("ctYear" . "CalendarTime -> Int")
+    ("diffClockTimes" . "ClockTime -> ClockTime -> TimeDiff")
+    ("formatCalendarTime" . "TimeLocale -> String -> CalendarTime -> String")
+    ("getClockTime" . "IO ClockTime")
+    ("tdDay" . "TimeDiff -> Int")
+    ("tdHour" . "TimeDiff -> Int")
+    ("tdMin" . "TimeDiff -> Int")
+    ("tdMonth" . "TimeDiff -> Int")
+    ("tdPicosec" . "TimeDiff -> Integer")
+    ("tdSec" . "TimeDiff -> Int")
+    ("tdYear" . "TimeDiff -> Int")
+    ("toCalendarTime" . "ClockTime -> IO CalendarTime")
+    ("toClockTime" . "CalendarTime -> ClockTime")
+    ("toUTCTime" . "ClockTime -> CalendarTime")
+    ;; Locale
+    ("amPm" . "TimeLocale -> (String, String)")
+    ("dateFmt" . "TimeLocale -> String")
+    ("dateTimeFmt" . "TimeLocale -> String")
+    ("defaultTimeLocale" . "TimeLocale")
+    ("months" . "TimeLocale -> [(String, String)]")
+    ("time12Fmt" . "TimeLocale -> String")
+    ("timeFmt" . "TimeLocale -> String")
+    ("wDays" . "TimeLocale -> [(String, String)]")
+    ;; CPUTime
+    ("cpuTimePrecision" . "Integer")
+    ("getCPUTime" . "IO Integer")
+    ;; Random
+    ("genRange" . "RandomGen g => g -> (Int, Int)")
+    ("getStdGen" . "IO StdGen")
+    ("getStdRandom" . "(StdGen -> (a, StdGen)) -> IO a")
+    ("mkStdGen" . "Int -> StdGen")
+    ("newStdGen" . "IO StdGen")
+    ("next" . "RandomGen g => g -> (Int, g)")
+    ("random" . "(Random a, RandomGen g) => g -> (a, g)")
+    ("randomIO" . "Random a => IO a")
+    ("randomR" . "(Random a, RandomGen g) => (a, a) -> g -> (a, g)")
+    ("randomRIO" . "Random a => (a,a) -> IO a")
+    ("randomRs" . "(Random a, RandomGen g) => (a, a) -> g -> [a]")
+    ("randoms" . "(Random a, RandomGen g) => g -> [a]")
+    ("setStdGen" . "StdGen -> IO ()")
+    ("split" . "RandomGen g => g -> (g, g)")
+    )
+  "Alist of prelude functions and their types.")
+
+
+(defvar haskell-doc-strategy-ids
+  (list
+   '("par"  . "Done -> Done -> Done ; [infixr 0]")
+   '("seq"  . "Done -> Done -> Done ; [infixr 1]")
+
+   '("using"      . "a -> Strategy a -> a ; [infixl 0]")
+   '("demanding"  . "a -> Done -> a ; [infixl 0]")
+   '("sparking"   . "a -> Done -> a ; [infixl 0]")
+
+   '(">||" . "Done -> Done -> Done ; [infixr 2]")
+   '(">|" .  "Done -> Done -> Done ; [infixr 3]")
+   '("$||" . "(a -> b) -> Strategy a -> a -> b ; [infixl 6]")
+   '("$|"  . "(a -> b) -> Strategy a -> a -> b ; [infixl 6]")
+   '(".|"  . "(b -> c) -> Strategy b -> (a -> b) -> (a -> c) ; [infixl 9]")
+   '(".||" . "(b -> c) -> Strategy b -> (a -> b) -> (a -> c) ; [infixl 9]")
+   '("-|"  . "(a -> b) -> Strategy b -> (b -> c) -> (a -> c) ; [infixl 9]")
+   '("-||" . "(a -> b) -> Strategy b -> (b -> c) -> (a -> c) ; [infixl 9]")
+
+   '("Done" . "type Done = ()")
+   '("Strategy" . "type Strategy a = a -> Done")
+
+   '("r0"    . "Strategy a")
+   '("rwhnf" . "Eval a => Strategy a")
+   '("rnf" . "Strategy a")
+   '("NFData" . "class Eval a => NFData a where rnf :: Strategy a")
+   '("NFDataIntegral" ."class (NFData a, Integral a) => NFDataIntegral a")
+   '("NFDataOrd" . "class (NFData a, Ord a) => NFDataOrd a")
+
+   '("markStrat" . "Int -> Strategy a -> Strategy a")
+
+   '("seqPair" . "Strategy a -> Strategy b -> Strategy (a,b)")
+   '("parPair" . "Strategy a -> Strategy b -> Strategy (a,b)")
+   '("seqTriple" . "Strategy a -> Strategy b -> Strategy c -> Strategy (a,b,c)")
+   '("parTriple" . "Strategy a -> Strategy b -> Strategy c -> Strategy (a,b,c)")
+
+   '("parList"  . "Strategy a -> Strategy [a]")
+   '("parListN"  . "(Integral b) => b -> Strategy a -> Strategy [a]")
+   '("parListNth"  . "Int -> Strategy a -> Strategy [a]")
+   '("parListChunk"  . "Int -> Strategy a -> Strategy [a]")
+   '("parMap"  . "Strategy b -> (a -> b) -> [a] -> [b]")
+   '("parFlatMap"  . "Strategy [b] -> (a -> [b]) -> [a] -> [b]")
+   '("parZipWith"  . "Strategy c -> (a -> b -> c) -> [a] -> [b] -> [c]")
+   '("seqList"  . "Strategy a -> Strategy [a]")
+   '("seqListN"  . "(Integral a) => a -> Strategy b -> Strategy [b]")
+   '("seqListNth"  . "Int -> Strategy b -> Strategy [b]")
+
+   '("parBuffer"  . "Int -> Strategy a -> [a] -> [a]")
+
+   '("seqArr"  . "(Ix b) => Strategy a -> Strategy (Array b a)")
+   '("parArr"  . "(Ix b) => Strategy a -> Strategy (Array b a)")
+
+   '("fstPairFstList"  . "(NFData a) => Strategy [(a,b)]")
+   '("force"  . "(NFData a) => a -> a ")
+   '("sforce"  . "(NFData a) => a -> b -> b")
+   )
+  "Alist of strategy functions and their types as defined in Strategies.lhs.")
+
+(defvar haskell-doc-user-defined-ids nil
+  "Alist of functions and strings defined by the user.")
+
+
+(defsubst haskell-doc-is-of (fn types)
+  "Check whether FN is one of the functions in the alist TYPES and return the type."
+  (assoc fn types) )
+
+
+;; Put this minor mode on the global minor-mode-alist.
+(or (assq 'haskell-doc-mode (default-value 'minor-mode-alist))
+    (setq-default minor-mode-alist
+                  (append (default-value 'minor-mode-alist)
+                          '((haskell-doc-mode haskell-doc-minor-mode-string)))))
+
+
+(defvar haskell-doc-keymap
+  (let ((map (make-sparse-keymap)))
+    (define-key map [visit]
+      '("Visit FTP home site" . haskell-doc-visit-home))
+    (define-key map [submit]
+      '("Submit bug report" . haskell-doc-submit-bug-report))
+    (define-key map [dummy] '("---" . nil))
+    (define-key map [make-index]
+      '("Make global fct index" . haskell-doc-make-global-fct-index))
+    (define-key map [global-types-on]
+      '("Toggle display of global types" . haskell-doc-show-global-types))
+    (define-key map [strategy-on]
+      '("Toggle display of strategy ids" . haskell-doc-show-strategy))
+    (define-key map [user-defined-on]
+      '("Toggle display of user defined ids" . haskell-doc-show-user-defined))
+    (define-key map [prelude-on]
+      '("Toggle display of prelude functions" . haskell-doc-show-prelude))
+    (define-key map [reserved-ids-on]
+      '("Toggle display of reserved ids" . haskell-doc-show-reserved))
+    (define-key map [haskell-doc-on]
+      '("Toggle haskell-doc mode" . haskell-doc-mode))
+    map))
+
+(defun haskell-doc-install-keymap ()
+  "Install a menu for `haskell-doc-mode' as a submenu of \"Hugs\"."
+  (interactive)
+  ;; Add the menu to the hugs menu as last entry.
+  (let ((hugsmap (lookup-key (current-local-map) [menu-bar Hugs])))
+    (if (not (or (featurep 'xemacs) ; XEmacs has problems here
+                 (not (keymapp hugsmap))
+                 (lookup-key hugsmap [haskell-doc])))
+        (if (functionp 'define-key-after)
+            (define-key-after hugsmap [haskell-doc]
+              (cons "Haskell-doc" haskell-doc-keymap)
+              [Haskell-doc mode]))))
+  ;; Add shortcuts for these commands.
+  (local-set-key "\C-c\e/" 'haskell-doc-check-active)
+  ;; Conflicts with the binding of haskell-insert-otherwise.
+  ;; (local-set-key "\C-c\C-o" 'haskell-doc-mode)
+  (local-set-key [(control shift meta mouse-3)]
+                 'haskell-doc-ask-mouse-for-type))
+
+
+(defvar haskell-doc-timer nil)
+(defvar haskell-doc-buffers nil)
+
+;;;###autoload
+(defun haskell-doc-mode (&optional arg)
+  "Enter `haskell-doc-mode' for showing fct types in the echo area.
+See variable docstring."
+  (interactive (list (or current-prefix-arg 'toggle)))
+
+  (setq haskell-doc-mode
+        (cond
+         ((eq arg 'toggle) (not haskell-doc-mode))
+         (arg (> (prefix-numeric-value arg) 0))
+         (t)))
+
+  ;; First, unconditionally turn the mode OFF.
+
+  (setq haskell-doc-buffers (delq (current-buffer) haskell-doc-buffers))
+  ;; Refresh the buffers list.
+  (dolist (buf haskell-doc-buffers)
+    (unless (and (buffer-live-p buf)
+                 (with-current-buffer buf haskell-doc-mode))
+      (setq haskell-doc-buffers (delq buf haskell-doc-buffers))))
+  ;; Turn off the idle timer (or idle post-command-hook).
+  (when (and haskell-doc-timer (null haskell-doc-buffers))
+    (cancel-timer haskell-doc-timer)
+    (setq haskell-doc-timer nil))
+  (remove-hook 'post-command-hook
+               'haskell-doc-mode-print-current-symbol-info 'local)
+
+  (when haskell-doc-mode
+    ;; Turning the mode ON.
+    (push (current-buffer) haskell-doc-buffers)
+
+    (if (fboundp 'run-with-idle-timer)
+        (unless haskell-doc-timer
+          (setq haskell-doc-timer
+                (run-with-idle-timer
+                 haskell-doc-idle-delay t
+                 'haskell-doc-mode-print-current-symbol-info)))
+      (add-hook 'post-command-hook
+                'haskell-doc-mode-print-current-symbol-info nil 'local))
+    (and haskell-doc-show-global-types
+         (haskell-doc-make-global-fct-index)) ; build type index for global fcts
+
+    (haskell-doc-install-keymap)
+
+    (run-hooks 'haskell-doc-mode-hook))
+
+  (and (called-interactively-p 'any)
+       (message "haskell-doc-mode is %s"
+                (if haskell-doc-mode "enabled" "disabled")))
+  haskell-doc-mode)
+
+(defmacro haskell-doc-toggle-var (id prefix)
+  ;; toggle variable or set it based on prefix value
+  `(setq ,id
+         (if ,prefix
+             (>= (prefix-numeric-value ,prefix) 0)
+           (not ,id))) )
+
+(defun haskell-doc-show-global-types (&optional prefix)
+  "Turn on global types information in `haskell-doc-mode'."
+  (interactive "P")
+  (haskell-doc-toggle-var haskell-doc-show-global-types prefix)
+  (if haskell-doc-show-global-types
+      (haskell-doc-make-global-fct-index)))
+
+(defun haskell-doc-show-reserved (&optional prefix)
+  "Toggle the automatic display of a doc string for reserved ids."
+  (interactive "P")
+  (haskell-doc-toggle-var haskell-doc-show-reserved prefix))
+
+(defun haskell-doc-show-prelude (&optional prefix)
+  "Toggle the automatic display of a doc string for reserved ids."
+  (interactive "P")
+  (haskell-doc-toggle-var haskell-doc-show-prelude prefix))
+
+(defun haskell-doc-show-strategy (&optional prefix)
+  "Toggle the automatic display of a doc string for strategy ids."
+  (interactive "P")
+  (haskell-doc-toggle-var haskell-doc-show-strategy prefix))
+
+(defun haskell-doc-show-user-defined (&optional prefix)
+  "Toggle the automatic display of a doc string for user defined ids."
+  (interactive "P")
+  (haskell-doc-toggle-var haskell-doc-show-user-defined prefix))
+
+
+;;;###autoload
+(defalias 'turn-on-haskell-doc-mode 'haskell-doc-mode)
+(make-obsolete 'turn-on-haskell-doc-mode
+               'haskell-doc-mode
+               "2015-07-23")
+
+;;;###autoload
+(defalias 'turn-on-haskell-doc 'haskell-doc-mode)
+(make-obsolete 'turn-on-haskell-doc
+               'haskell-doc-mode
+               "2015-07-23")
+
+(defalias 'turn-off-haskell-doc-mode 'turn-off-haskell-doc)
+
+(defun turn-off-haskell-doc ()
+  "Unequivocally turn off `haskell-doc-mode' (which see)."
+  (haskell-doc-mode 0))
+
+(defun haskell-doc-check-active ()
+  "Check whether the print function is hooked in.
+Should be the same as the value of `haskell-doc-mode' but alas currently it
+is not."
+  (interactive)
+  (message "%s"
+           (if (or (and haskell-doc-mode haskell-doc-timer)
+                   (memq 'haskell-doc-mode-print-current-symbol-info
+                         post-command-hook))
+               "haskell-doc is ACTIVE"
+             (substitute-command-keys
+              "haskell-doc is not ACTIVE \(Use \\[haskell-doc-mode] to turn it on\)"))))
+
+
+;; This is the function hooked into the elisp command engine
+(defun haskell-doc-mode-print-current-symbol-info ()
+  "Print the type of the symbol under the cursor.
+
+This function is run by an idle timer to print the type
+ automatically if `haskell-doc-mode' is turned on."
+  (and haskell-doc-mode
+       (haskell-doc-in-code-p)
+       (not haskell-mode-interactive-prompt-state)
+       (not (eobp))
+       (not executing-kbd-macro)
+       ;; Having this mode operate in the minibuffer makes it impossible to
+       ;; see what you're doing.
+       (not (eq (selected-window) (minibuffer-window)))
+       ;; not in string or comment
+       ;; take a nap, if run straight from post-command-hook.
+       (if (fboundp 'run-with-idle-timer) t
+         (sit-for haskell-doc-idle-delay))
+       ;; good morning! read the word under the cursor for breakfast
+       (haskell-doc-show-type)))
+;; ;; ToDo: find surrounding fct
+;; (cond ((eq current-symbol current-fnsym)
+;;        (haskell-doc-show-type current-fnsym))
+;;       (t
+;;        (or nil ; (haskell-doc-print-var-docstring current-symbol)
+;;            (haskell-doc-show-type current-fnsym)))))))
+
+;;;###autoload
+(defun haskell-doc-current-info ()
+  "Return the info about symbol at point.
+Meant for `eldoc-documentation-function'."
+  ;; There are a number of possible documentation functions.
+  ;; Some of them are asynchronous.
+  (when (haskell-doc-in-code-p)
+    (let ((msg (or
+                (haskell-doc-current-info--interaction)
+                (haskell-doc-sym-doc (haskell-ident-at-point)))))
+      (unless (symbolp msg) msg))))
+
+(defun haskell-doc-ask-mouse-for-type (event)
+  "Read the identifier under the mouse and echo its type.
+This uses the same underlying function `haskell-doc-show-type' as the hooked
+function.  Only the user interface is different."
+  (interactive "e")
+  (save-excursion
+    (select-window (posn-window (event-end event)))
+    (goto-char (posn-point (event-end event)))
+    (haskell-doc-show-type)))
+
+(defun haskell-doc-in-code-p ()
+  "A predicate indicating suitable case to show docs."
+  (not (or (and (eq haskell-literate 'bird)
+                ;; Copied from haskell-indent-bolp.
+                (<= (current-column) 2)
+                (eq (char-after (line-beginning-position)) ?\>))
+           (nth 8 (syntax-ppss)))))
+
+;;;###autoload
+(defun haskell-doc-show-type (&optional sym)
+  "Show the type of the function near point or given symbol SYM.
+For the function under point, show the type in the echo area.
+This information is extracted from the `haskell-doc-prelude-types' alist
+of prelude functions and their types, or from the local functions in the
+current buffer."
+  (interactive)
+  (unless sym (setq sym (haskell-ident-at-point)))
+  ;; if printed before do not print it again
+  (unless (string= sym (car haskell-doc-last-data))
+    (let ((doc (or (haskell-doc-current-info--interaction t)
+                  (haskell-doc-sym-doc sym))))
+      (when (and doc (haskell-doc-in-code-p))
+        ;; In Emacs 19.29 and later, and XEmacs 19.13 and later, all
+        ;; messages are recorded in a log.  Do not put haskell-doc messages
+        ;; in that log since they are legion.
+        (let ((message-log-max nil))
+          (message "%s" doc))))))
+
+(defvar haskell-doc-current-info--interaction-last nil
+  "Async message stack.
+If non-nil, a previous eldoc message from an async call, that
+hasn't been displayed yet.")
+
+(defun haskell-doc-current-info--interaction (&optional sync)
+  "Asynchronous call to `haskell-process-get-type'.
+Suitable for use in the eldoc function `haskell-doc-current-info'.
+
+If SYNC is non-nil, the call will be synchronous instead, and
+instead of calling `eldoc-print-current-symbol-info', the result
+will be returned directly."
+  ;; Return nil if nothing is available, or 'async if something might
+  ;; be available, but asynchronously later. This will call
+  ;; `eldoc-print-current-symbol-info' later.
+  (when (haskell-doc-in-code-p)
+    ;; do nothing when inside string or comment
+    (let (sym prev-message)
+      (cond
+       ((setq prev-message haskell-doc-current-info--interaction-last)
+        (setq haskell-doc-current-info--interaction-last nil)
+        (cdr prev-message))
+       ((setq sym
+              (if (use-region-p)
+                  (buffer-substring-no-properties
+                   (region-beginning) (region-end))
+                (haskell-ident-at-point)))
+        (if sync
+            (haskell-process-get-type sym #'identity t)
+          (haskell-process-get-type
+           sym (lambda (response)
+                 (setq haskell-doc-current-info--interaction-last
+                       (cons 'async response))
+                 (eldoc-print-current-symbol-info)))))))))
+
+(defun haskell-process-get-type (expr-string &optional callback sync)
+  "Asynchronously get the type of a given string.
+
+EXPR-STRING should be an expression passed to :type in ghci.
+
+CALLBACK will be called with a formatted type string.
+
+If SYNC is non-nil, make the call synchronously instead."
+  (unless callback (setq callback (lambda (response) (message "%s" response))))
+  (let ((process (and (haskell-session-maybe)
+                    (haskell-session-process (haskell-session-maybe))))
+        ;; Avoid passing bad strings to ghci
+        (expr-okay
+         (and (not (string-match-p "\\`[[:space:]]*\\'" expr-string))
+            (not (string-match-p "\n" expr-string))))
+        (ghci-command (concat ":type " expr-string))
+        (process-response
+         (lambda (response)
+           ;; Responses with empty first line are likely errors
+           (if (string-match-p (rx string-start line-end) response)
+               (setq response nil)
+             ;; Remove a newline at the end
+             (setq response (replace-regexp-in-string "\n\\'" "" response))
+             ;; Propertize for eldoc
+             (save-match-data
+               (when (string-match " :: " response)
+                 ;; Highlight type
+                 (let ((name (substring response 0 (match-end 0)))
+                       (type (propertize
+                              (substring response (match-end 0))
+                              'face 'eldoc-highlight-function-argument)))
+                   (setq response (concat name type)))))
+             (when haskell-doc-prettify-types
+               (dolist (re '(("::" . "∷") ("=>" . "⇒") ("->" . "→")))
+                 (setq response
+                       (replace-regexp-in-string (car re) (cdr re) response))))
+             response))))
+    (when (and process expr-okay)
+      (if sync
+          (let ((response (haskell-process-queue-sync-request process ghci-command)))
+            (funcall callback (funcall process-response response)))
+        (haskell-process-queue-command
+         process
+         (make-haskell-command
+          :go (lambda (_) (haskell-process-send-string process ghci-command))
+          :complete
+          (lambda (_ response)
+            (funcall callback (funcall process-response response)))))
+        'async))))
+
+(defun haskell-doc-sym-doc (sym)
+  "Show the type of given symbol SYM.
+For the function under point, show the type in the echo area.
+This information is extracted from the `haskell-doc-prelude-types' alist
+of prelude functions and their types, or from the local functions in the
+current buffer.
+If `haskell-doc-use-inf-haskell' is non-nil, this function will consult
+the inferior Haskell process for type/kind information, rather than using
+the haskell-doc database."
+  (if haskell-doc-use-inf-haskell
+      (unless (or (null sym) (string= "" sym))
+        (let* ((message-log-max nil)
+               (result (ignore-errors
+                         (unwind-protect
+                             (inferior-haskell-type sym)
+                           (message "")))))
+          (if (and result (string-match " :: " result))
+              result
+            (setq result (unwind-protect
+                             (inferior-haskell-kind sym)
+                           (message "")))
+            (and result (string-match " :: " result) result))))
+    (let ((i-am-prelude nil)
+          (i-am-fct nil)
+          (type nil)
+          (is-reserved (haskell-doc-is-of sym haskell-doc-reserved-ids))
+          (is-prelude  (haskell-doc-is-of sym haskell-doc-prelude-types))
+          (is-strategy (haskell-doc-is-of sym haskell-doc-strategy-ids))
+          (is-user-defined (haskell-doc-is-of sym haskell-doc-user-defined-ids)))
+      (cond
+       ;; if reserved id (i.e. Haskell keyword
+       ((and haskell-doc-show-reserved
+             is-reserved)
+        (setq type (cdr is-reserved))
+        (setcdr haskell-doc-last-data type))
+       ;; if built-in function get type from docstring
+       ((and (not (null haskell-doc-show-prelude))
+             is-prelude)
+        (setq type (cdr is-prelude)) ; (cdr (assoc sym haskell-doc-prelude-types)))
+        (if (= 2 (length type))      ; horrible hack to remove bad formatting
+            (setq type (car (cdr type))))
+        (setq i-am-prelude t)
+        (setq i-am-fct t)
+        (setcdr haskell-doc-last-data type))
+       ((and haskell-doc-show-strategy
+             is-strategy)
+        (setq i-am-fct t)
+        (setq type (cdr is-strategy))
+        (setcdr haskell-doc-last-data type))
+       ((and haskell-doc-show-user-defined
+             is-user-defined)
+        ;; (setq i-am-fct t)
+        (setq type (cdr is-user-defined))
+        (setcdr haskell-doc-last-data type))
+       (t
+        (let ( (x (haskell-doc-get-and-format-fct-type sym)) )
+          (if (null x)
+              (setcdr haskell-doc-last-data nil) ; if not found reset last data
+            (setq type (car x))
+            (setq i-am-fct (string= "Variables" (cdr x)))
+            (if (and haskell-doc-show-global-types (null type))
+                (setq type (haskell-doc-get-global-fct-type sym)))
+            (setcdr haskell-doc-last-data type)))) )
+      ;; ToDo: encode i-am-fct info into alist of types
+      (and type
+           ;; drop `::' if it's not a fct
+           (let ( (str (cond ((and i-am-fct (not haskell-doc-chop-off-fctname))
+                              (format "%s :: %s" sym type))
+                             (t
+                              (format "%s" type)))) )
+             (if i-am-prelude
+                 (add-text-properties 0 (length str) '(face bold) str))
+             str)))))
+
+
+;; ToDo: define your own notion of `near' to find surrounding fct
+;;(defun haskell-doc-fnsym-in-current-sexp ()
+;;  (let* ((p (point))
+;;         (sym (progn
+;;              (forward-word -1)
+;;                (while (and (forward-word -1) ; (haskell-doc-forward-sexp-safe -1)
+;;                            (> (point) (point-min))))
+;;                (cond ((or (= (point) (point-min))
+;;                           (memq (or (char-after (point)) 0)
+;;                                 '(?\( ?\"))
+;;                           ;; If we hit a quotation mark before a paren, we
+;;                           ;; are inside a specific string, not a list of
+;;                           ;; symbols.
+;;                           (eq (or (char-after (1- (point))) 0) ?\"))
+;;                       nil)
+;;                      (t (condition-case nil
+;;                             (read (current-buffer))
+;;                           (error nil)))))))
+;;    (goto-char p)
+;;    (if sym
+;;      (format "%s" sym)
+;;      sym)))
+
+;;    (and (symbolp sym)
+;;         sym)))
+
+
+;; ToDo: handle open brackets to decide if it's a wrapped type
+
+(defun haskell-doc-grab-line (fct-and-pos)
+  "Get the type of an \(FCT POSITION\) pair from the current buffer."
+  ;; (if (null fct-and-pos)
+  ;;     "" ; fn is not a local fct
+  (let ( (str ""))
+    (goto-char (cdr fct-and-pos))
+    (beginning-of-line)
+    ;; search for start of type (phsp give better bound?)
+    (if (null (search-forward "::" (+ (point) haskell-doc-search-distance) t))
+        ""
+      (setq str (haskell-doc-grab))        ; leaves point at end of line
+      (while (haskell-doc-wrapped-type-p)  ; while in a multi-line type expr
+        (forward-line 1)
+        (beginning-of-line)
+        (skip-chars-forward " \t")
+        (setq str (concat str (haskell-doc-grab))))
+      (haskell-doc-string-nub-ws           ; squeeze string
+       (if haskell-doc-chop-off-context    ; no context
+           (haskell-doc-chop-off-context str)
+         str)))))
+;; (concat (car fct-and-pos) "::" (haskell-doc-string-nub-ws str))))
+
+(defun haskell-doc-wrapped-type-p ()
+  "Check whether the type under the cursor is wrapped over several lines.
+The cursor must be at the end of a line, which contains the type.
+Currently, only the following is checked:
+If this line ends with a `->' or the next starts with an `->' it is a
+multi-line type \(same for `=>'\).
+`--' comments are ignored.
+ToDo: Check for matching parenthesis!."
+  (save-excursion
+    (let ( (here (point))
+           (lim (progn (beginning-of-line) (point)))
+           ;; (foo "")
+           (res nil)
+           )
+      (goto-char here)
+      (search-backward "--" lim t) ; skip over `--' comment
+      (skip-chars-backward " \t")
+      (if (bolp)                   ; skip empty lines
+          (progn
+            (forward-line 1)
+            (end-of-line)
+            (setq res (haskell-doc-wrapped-type-p)))
+        (forward-char -1)
+        ;; (setq foo (concat foo (char-to-string (preceding-char)) (char-to-string (following-char))))
+        (if (or (and (or (char-equal (preceding-char) ?-) (char-equal (preceding-char) ?=))
+                     (char-equal (following-char) ?>)) ; (or -!> =!>
+                (char-equal (following-char) ?,))      ;     !,)
+            (setq res t)
+          (forward-line)
+          (let ((here (point)))
+            (goto-char here)
+            (skip-chars-forward " \t")
+            (if (looking-at "--")  ; it is a comment line
+                (progn
+                  (forward-line 1)
+                  (end-of-line)
+                  (setq res (haskell-doc-wrapped-type-p)))
+              (forward-char 1)
+              ;; (setq foo (concat foo (char-to-string (preceding-char)) (char-to-string (following-char))))
+              ;; (message "|%s|" foo)
+              (if (and (or (char-equal (preceding-char) ?-) (char-equal (preceding-char) ?=))
+                       (char-equal (following-char) ?>)) ; -!> or =!>
+                  (setq res t))))))
+      res)))
+
+(defun haskell-doc-grab ()
+  "Return the text from point to the end of the line, chopping off comments.
+Leaves point at end of line."
+  (let ((str (buffer-substring-no-properties
+              (point) (progn (end-of-line) (point)))))
+    (if (string-match "--" str)
+        (substring str 0 (match-beginning 0))
+      str)))
+
+(defun haskell-doc-string-nub-ws (str)
+  "Replace all sequences of whitespace in STR by just one space.
+ToDo: Also eliminate leading and trailing whitespace."
+  (let ((i -1))
+    (while (setq i (string-match " [ \t\n]+\\|[\t\n]+" str (1+ i)))
+      (setq str (replace-match " " t t str)))
+    str))
+
+(defun haskell-doc-chop-off-context (str)
+  "Eliminate the context in a type represented by the string STR."
+  (let ((i (string-match "=>" str)) )
+    (if (null i)
+        str
+      (substring str (+ i 2)))))
+
+(defun haskell-doc-get-imenu-info (obj kind)
+  "Return a string describing OBJ of KIND \(Variables, Types, Data\)."
+  (cond
+   ((eq major-mode 'haskell-mode)
+    (let* ((imenu-info-alist (cdr (assoc kind imenu--index-alist)))
+           ;; (names (mapcar 'car imenu-info-alist))
+           (x (assoc obj imenu-info-alist)))
+      (when x (haskell-doc-grab-line x))))
+
+   (t ;; (error "Cannot get local functions in %s mode, sorry" major-mode)))
+    nil)))
+
+;; ToDo:
+;;  - modular way of defining a mapping of module name to file
+;;  - use a path to search for file (not just current directory)
+
+
+(defun haskell-doc-imported-list ()
+  "Return a list of the imported modules in current buffer."
+  (interactive "fName of outer `include' file: ") ;  (buffer-file-name))
+  ;; Don't add current buffer to the imported file list if it is not (yet?)
+  ;; visiting a file since it leads to errors further down.
+  (let ((imported-file-list (and buffer-file-name (list buffer-file-name))))
+    (widen)
+    (goto-char (point-min))
+    (while (re-search-forward "^\\s-*import\\s-+\\([^ \t\n]+\\)" nil t)
+      (let ((basename (match-string 1)))
+        (dolist (ext '(".hs" ".lhs"))
+          (let ((file (concat basename ext)))
+            (if (file-exists-p file)
+                (push file imported-file-list))))))
+    (nreverse imported-file-list)
+    ;;(message imported-file-list)
+    ))
+
+;; ToDo: generalise this to "Types" etc (not just "Variables")
+
+(defun haskell-doc-rescan-files (filelist)
+  "Do an `imenu' rescan on every file in FILELIST and return the fct-list.
+This function switches to and potentially loads many buffers."
+  (save-current-buffer
+    (mapcar (lambda (f)
+              (set-buffer (find-file-noselect f))
+              (imenu--make-index-alist t)
+              (cons f
+                    (mapcar (lambda (x)
+                              `(,(car x) . ,(haskell-doc-grab-line x)))
+                            (cdr (assoc "Variables" imenu--index-alist)))))
+            filelist)))
+
+(defun haskell-doc-make-global-fct-index ()
+  "Scan imported files for types of global fcts and update `haskell-doc-index'."
+  (interactive)
+  (setq haskell-doc-index
+        (haskell-doc-rescan-files (haskell-doc-imported-list))))
+
+;; ToDo: use a separate munge-type function to format type concisely
+
+(defun haskell-doc-get-global-fct-type (&optional sym)
+  "Get type for function symbol SYM by examining `haskell-doc-index'."
+  (interactive) ;  "fName of outer `include' file: \nsFct:")
+  (save-excursion
+    ;; (switch-to-buffer "*scratch*")
+    ;; (goto-char (point-max))
+    ;; ;; Produces a list of fct-type alists
+    ;; (if (null sym)
+    ;;     (setq sym (progn (forward-word -1) (read (current-buffer)))))
+    (or sym
+        (current-word))
+    (let* ( (fn sym) ; (format "%s" sym))
+            (fal haskell-doc-index)
+            (res "") )
+      (while (not (null fal))
+        (let* ( (l (car fal))
+                (f (car l))
+                (x (assoc fn (cdr l))) )
+          (if (not (null x))
+              (let* ( (ty (cdr x)) ; the type as string
+                      (idx (string-match "::" ty))
+                      (str (if (null idx)
+                               ty
+                             (substring ty (+ idx 2)))) )
+                (setq res (format "[%s] %s" f str))))
+          (setq fal (cdr fal))))
+      res))) ; (message res)) )
+
+(defun haskell-doc-get-and-format-fct-type (fn)
+  "Get the type and kind of FN by checking local and global functions."
+  (save-excursion
+    (save-match-data
+      (let ((docstring "")
+            (doc nil)
+            )
+        ;; is it a local function?
+        (setq docstring (haskell-doc-get-imenu-info fn "Variables"))
+        (if (not (null docstring))
+            ;; (string-match (format "^%s\\s-+::\\s-+\\(.*\\)$" fn) docstring))
+            (setq doc `(,docstring . "Variables"))) ; `(,(match-string 1 docstring) . "Variables") ))
+        ;; is it a type declaration?
+        (setq docstring (haskell-doc-get-imenu-info fn "Types"))
+        (if (not (null docstring))
+            ;; (string-match (format "^\\s-*type\\s-+%s.*$" fn) docstring))
+            (setq doc `(,docstring . "Types"))) ; `(,(match-string 0 docstring) . "Types")) )
+        (if (not (null docstring))
+            ;; (string-match (format "^\\s-*data.*%s.*$" fn) docstring))
+            (setq doc `(,docstring . "Data"))) ; (setq doc `(,(match-string 0 docstring) . "Data")) )
+        ;; return the result
+        doc ))))
+
+(defun inferior-haskell-kind (sym)
+  "Find the kind of SYM with `:kind' ghci feature."
+  (inferior-haskell-get-result (format ":kind %s" sym)))
+
+(defun inferior-haskell-type (sym)
+  "Find the type of SYM with `:type' ghci feature."
+  (inferior-haskell-get-result (format ":type (%s)" sym)))
+
+(provide 'haskell-doc)
+
+;;; haskell-doc.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-doc.elc b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-doc.elc
new file mode 100644
index 0000000000..b7629b4ccc
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-doc.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-font-lock.el b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-font-lock.el
new file mode 100644
index 0000000000..8360c7dd06
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-font-lock.el
@@ -0,0 +1,711 @@
+;;; haskell-font-lock.el --- Font locking module for Haskell Mode -*- lexical-binding: t -*-
+
+;; Copyright 2003, 2004, 2005, 2006, 2007, 2008  Free Software Foundation, Inc.
+;; Copyright 1997-1998  Graeme E Moss, and Tommy Thorn
+
+;; Author: 1997-1998 Graeme E Moss <gem@cs.york.ac.uk>
+;;         1997-1998 Tommy Thorn <thorn@irisa.fr>
+;;         2003      Dave Love <fx@gnu.org>
+;; Keywords: faces files Haskell
+
+;; This file is not part of GNU Emacs.
+
+;; This file 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, or (at your option)
+;; any later version.
+
+;; This file 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'haskell-compat)
+(require 'haskell-lexeme)
+(require 'font-lock)
+
+;;;###autoload
+(defgroup haskell-appearance nil
+  "Haskell Appearance."
+  :group 'haskell)
+
+
+(defcustom haskell-font-lock-symbols nil
+  "Display \\ and -> and such using symbols in fonts.
+
+This may sound like a neat trick, but be extra careful: it changes the
+alignment and can thus lead to nasty surprises with regards to layout."
+  :group 'haskell-appearance
+  :type 'boolean)
+
+(defcustom haskell-font-lock-symbols-alist
+  '(("\\" . "λ")
+    ("not" . "¬")
+    ("->" . "→")
+    ("<-" . "←")
+    ("=>" . "⇒")
+    ("()" . "∅")
+    ("==" . "≡")
+    ("/=" . "≢")
+    (">=" . "≥")
+    ("<=" . "≤")
+    ("!!" . "‼")
+    ("&&" . "∧")
+    ("||" . "∨")
+    ("sqrt" . "√")
+    ("undefined" . "⊥")
+    ("pi" . "π")
+    ("~>" . "⇝") ;; Omega language
+    ;; ("~>" "↝") ;; less desirable
+    ("-<" . "↢") ;; Paterson's arrow syntax
+    ;; ("-<" "⤙") ;; nicer but uncommon
+    ("::" . "∷")
+    ("." "∘" ; "○"
+     ;; Need a predicate here to distinguish the . used by
+     ;; forall <foo> . <bar>.
+     haskell-font-lock-dot-is-not-composition)
+    ("forall" . "∀"))
+  "Alist mapping Haskell symbols to chars.
+
+Each element has the form (STRING . COMPONENTS) or (STRING
+COMPONENTS PREDICATE).
+
+STRING is the Haskell symbol.
+COMPONENTS is a representation specification suitable as an argument to
+`compose-region'.
+PREDICATE if present is a function of one argument (the start position
+of the symbol) which should return non-nil if this mapping should
+be disabled at that position."
+  :type '(alist string string)
+  :group 'haskell-appearance)
+
+(defcustom haskell-font-lock-keywords
+  ;; `as', `hiding', and `qualified' are part of the import
+  ;; spec syntax, but they are not reserved.
+  ;; `_' can go in here since it has temporary word syntax.
+  '("case" "class" "data" "default" "deriving" "do"
+    "else" "if" "import" "in" "infix" "infixl"
+    "infixr" "instance" "let" "module" "mdo" "newtype" "of"
+    "rec" "pattern" "proc" "signature" "then" "type" "where" "_")
+  "Identifiers treated as reserved keywords in Haskell."
+  :group 'haskell-appearance
+  :type '(repeat string))
+
+
+(defun haskell-font-lock-dot-is-not-composition (start)
+  "Return non-nil if the \".\" at START is not a composition operator.
+This is the case if the \".\" is part of a \"forall <tvar> . <type>\"."
+  (save-excursion
+    (goto-char start)
+    (or (re-search-backward "\\<forall\\>[^.\"]*\\="
+                            (line-beginning-position) t)
+        (not (or
+              (string= " " (string (char-after start)))
+              (null (char-before start))
+              (string= " " (string (char-before start))))))))
+
+(defvar haskell-yesod-parse-routes-mode-keywords
+  '(("^\\([^ \t\n]+\\)\\(?:[ \t]+\\([^ \t\n]+\\)\\)?"
+     (1 'font-lock-string-face)
+     (2 'haskell-constructor-face nil lax))))
+
+(define-derived-mode haskell-yesod-parse-routes-mode text-mode "Yesod parseRoutes mode"
+  "Mode for parseRoutes from Yesod."
+  (setq-local font-lock-defaults '(haskell-yesod-parse-routes-mode-keywords t t nil nil)))
+
+(defcustom haskell-font-lock-quasi-quote-modes
+  `(("hsx" . xml-mode)
+    ("hamlet" . shakespeare-hamlet-mode)
+    ("shamlet" . shakespeare-hamlet-mode)
+    ("whamlet" . shakespeare-hamlet-mode)
+    ("xmlQQ" . xml-mode)
+    ("xml" . xml-mode)
+    ("cmd" . shell-mode)
+    ("sh_" . shell-mode)
+    ("jmacro" . javascript-mode)
+    ("jmacroE" . javascript-mode)
+    ("r" . ess-mode)
+    ("rChan" . ess-mode)
+    ("sql" . sql-mode)
+    ("json" . json-mode)
+    ("aesonQQ" . json-mode)
+    ("parseRoutes" . haskell-yesod-parse-routes-mode))
+  "Mapping from quasi quoter token to fontification mode.
+
+If a quasi quote is seen in Haskell code its contents will have
+font faces assigned as if respective mode was enabled."
+  :group 'haskell-appearance
+  :type '(repeat (cons string symbol)))
+
+;;;###autoload
+(defface haskell-keyword-face
+  '((t :inherit font-lock-keyword-face))
+  "Face used to highlight Haskell keywords."
+  :group 'haskell-appearance)
+
+;;;###autoload
+(defface haskell-type-face
+  '((t :inherit font-lock-type-face))
+  "Face used to highlight Haskell types"
+  :group 'haskell-appearance)
+
+;;;###autoload
+(defface haskell-constructor-face
+  '((t :inherit font-lock-type-face))
+  "Face used to highlight Haskell constructors."
+  :group 'haskell-appearance)
+
+;; This used to be `font-lock-variable-name-face' but it doesn't result in
+;; a highlighting that's consistent with other modes (it's mostly used
+;; for function defintions).
+(defface haskell-definition-face
+  '((t :inherit font-lock-function-name-face))
+  "Face used to highlight Haskell definitions."
+  :group 'haskell-appearance)
+
+;; This is probably just wrong, but it used to use
+;; `font-lock-function-name-face' with a result that was not consistent with
+;; other major modes, so I just exchanged with `haskell-definition-face'.
+;;;###autoload
+(defface haskell-operator-face
+  '((t :inherit font-lock-variable-name-face))
+  "Face used to highlight Haskell operators."
+  :group 'haskell-appearance)
+
+;;;###autoload
+(defface haskell-pragma-face
+  '((t :inherit font-lock-preprocessor-face))
+  "Face used to highlight Haskell pragmas ({-# ... #-})."
+  :group 'haskell-appearance)
+
+;;;###autoload
+(defface haskell-liquid-haskell-annotation-face
+  '((t :inherit haskell-pragma-face))
+  "Face used to highlight LiquidHaskell annotations ({-@ ... @-})."
+  :group 'haskell-appearance)
+
+;;;###autoload
+(defface haskell-literate-comment-face
+  '((t :inherit font-lock-doc-face))
+  "Face with which to fontify literate comments.
+Inherit from `default' to avoid fontification of them."
+  :group 'haskell-appearance)
+
+(defface haskell-quasi-quote-face
+  '((t :inherit font-lock-string-face))
+  "Generic face for quasiquotes.
+
+Some quote types are fontified according to other mode defined in
+`haskell-font-lock-quasi-quote-modes'."
+  :group 'haskell-appearance)
+
+(defun haskell-font-lock-compose-symbol (alist)
+  "Compose a sequence of ascii chars into a symbol.
+Regexp match data 0 points to the chars."
+  ;; Check that the chars should really be composed into a symbol.
+  (let* ((start (match-beginning 0))
+         (end (match-end 0))
+         (syntaxes (cond
+                    ((eq (char-syntax (char-after start)) ?w) '(?w))
+                    ((eq (char-syntax (char-after start)) ?.) '(?.))
+                    ;; Special case for the . used for qualified names.
+                    ((and (eq (char-after start) ?\.) (= end (1+ start)))
+                     '(?_ ?\\ ?w))
+                    (t '(?_ ?\\))))
+         sym-data)
+    (if (or (memq (char-syntax (or (char-before start) ?\ )) syntaxes)
+            (memq (char-syntax (or (char-after end) ?\ )) syntaxes)
+            (or (elt (syntax-ppss) 3) (elt (syntax-ppss) 4))
+            (and (consp (setq sym-data (cdr (assoc (match-string 0) alist))))
+                 (let ((pred (cadr sym-data)))
+                   (setq sym-data (car sym-data))
+                   (funcall pred start))))
+        ;; No composition for you.  Let's actually remove any composition
+        ;; we may have added earlier and which is now incorrect.
+        (remove-text-properties start end '(composition))
+      ;; That's a symbol alright, so add the composition.
+      (compose-region start end sym-data)))
+  ;; Return nil because we're not adding any face property.
+  nil)
+
+(defun haskell-font-lock-symbols-keywords ()
+  (when (and haskell-font-lock-symbols
+             haskell-font-lock-symbols-alist)
+    `((,(regexp-opt (mapcar 'car haskell-font-lock-symbols-alist) t)
+       (0 (haskell-font-lock-compose-symbol ',haskell-font-lock-symbols-alist)
+          ;; In Emacs-21, if the `override' field is nil, the face
+          ;; expressions is only evaluated if the text has currently
+          ;; no face.  So force evaluation by using `keep'.
+          keep)))))
+
+(defun haskell-font-lock--forward-type (&optional ignore)
+  "Find where does this type declaration end.
+
+Moves the point to the end of type declaration. It should be
+invoked with point just after one of type introducing keywords
+like ::, class, instance, data, newtype, type."
+  (interactive)
+  (let ((cont t)
+        (end (point))
+        (token nil)
+        ;; we are starting right after ::
+        (last-token-was-operator t)
+        (last-token-was-newline nil)
+        (open-parens 0))
+    (while cont
+      (setq token (haskell-lexeme-looking-at-token 'newline))
+
+      (cond
+       ((null token)
+        (setq cont nil))
+       ((member token '(newline))
+        (setq last-token-was-newline (not last-token-was-operator))
+        (setq end (match-end 0))
+        (goto-char (match-end 0)))
+       ((member (match-string-no-properties 0)
+                    '(")" "]" "}"))
+        (setq open-parens (1- open-parens))
+        (if (< open-parens 0)
+            ;; unmatched closing parenthesis closes type declaration
+            (setq cont nil)
+          (setq end (match-end 0))
+          (goto-char end))
+        (setq last-token-was-newline nil))
+       ((and (member (match-string-no-properties 0)
+                     '("," ";" "|"))
+             (not (member (match-string-no-properties 0) ignore)))
+        (if (equal 0 open-parens)
+            (setq cont nil)
+          (setq last-token-was-operator t)
+          (setq end (match-end 0))
+          (goto-char end))
+        (setq last-token-was-newline nil))
+       ((and (or (member (match-string-no-properties 0)
+                         '("<-" "=" "←"))
+                 (member (match-string-no-properties 0) haskell-font-lock-keywords))
+             (not (member (match-string-no-properties 0) ignore)))
+        (setq cont nil)
+        (setq last-token-was-newline nil))
+       ((member (match-string-no-properties 0)
+                '("(" "[" "{"))
+        (if last-token-was-newline
+            (setq cont nil)
+          (setq open-parens (1+ open-parens))
+          (setq end (match-end 0))
+          (goto-char end)
+          (setq last-token-was-newline nil)))
+       ((member token '(qsymid char string number template-haskell-quote template-haskell-quasi-quote))
+        (setq last-token-was-operator (member (haskell-lexeme-classify-by-first-char (char-after (match-beginning 1)))
+                                              '(varsym consym)))
+        (if (and (not last-token-was-operator) last-token-was-newline)
+            (setq cont nil)
+
+          (goto-char (match-end 0))
+          (setq end (point)))
+        (setq last-token-was-newline nil))
+       ((member token '(comment nested-comment literate-comment))
+        (goto-char (match-end 0))
+        (setq end (point)))
+       (t
+        (goto-char (match-end 0))
+        (setq end (point))
+        (setq last-token-was-newline nil))))
+    (goto-char end)))
+
+
+(defun haskell-font-lock--select-face-on-type-or-constructor ()
+  "Private function used to select either type or constructor face
+on an uppercase identifier."
+  (cl-case (haskell-lexeme-classify-by-first-char (char-after (match-beginning 1)))
+    (varid (let ((word (match-string-no-properties 0)))
+             (cond
+              ((member word haskell-font-lock-keywords)
+               ;; Note: keywords parse as keywords only when not qualified.
+               ;; GHC parses Control.let as a single but illegal lexeme.
+               (when (member word '("class" "instance" "type" "data" "newtype"))
+                 (save-excursion
+                   (goto-char (match-end 0))
+                   (save-match-data
+                     (haskell-font-lock--forward-type
+                      (cond
+                       ((member word '("class" "instance"))
+                        '("|"))
+                       ((member word '("type"))
+                        ;; Need to support 'type instance'
+                        '("=" "instance")))))
+                   (add-text-properties (match-end 0) (point) '(font-lock-multiline t haskell-type t))))
+               'haskell-keyword-face)
+              ((member word '("forall"))
+               (when (get-text-property (match-beginning 0) 'haskell-type)
+                 'haskell-keyword-face)))))
+    (conid (if (get-text-property (match-beginning 0) 'haskell-type)
+               'haskell-type-face
+             'haskell-constructor-face))
+    (varsym (unless (and (member (match-string 0) '("-" "+" "."))
+                         (equal (string-to-syntax "w") (syntax-after (match-beginning 0))))
+              ;; We need to protect against the case of
+              ;; plus, minus or dot inside a floating
+              ;; point number.
+              'haskell-operator-face))
+    (consym (if (not (member (match-string 1) '("::" "∷")))
+                (if (get-text-property (match-beginning 0) 'haskell-type)
+                    'haskell-type-face
+                  'haskell-constructor-face)
+              (save-excursion
+                (goto-char (match-end 0))
+                (save-match-data
+                  (haskell-font-lock--forward-type))
+                (add-text-properties (match-end 0) (point) '(font-lock-multiline t haskell-type t)))
+              'haskell-operator-face))))
+
+(defun haskell-font-lock--put-face-on-type-or-constructor ()
+  "Private function used to put either type or constructor face
+on an uppercase identifier."
+  (let ((face (haskell-font-lock--select-face-on-type-or-constructor)))
+    (when (and face
+               (not (text-property-not-all (match-beginning 0) (match-end 0) 'face nil)))
+      (put-text-property (match-beginning 0) (match-end 0) 'face face))))
+
+
+(defun haskell-font-lock-keywords ()
+  ;; this has to be a function because it depends on global value of
+  ;; `haskell-font-lock-symbols'
+  "Generate font lock eywords."
+  (let* (;; Bird-style literate scripts start a line of code with
+         ;; "^>", otherwise a line of code starts with "^".
+         (line-prefix "^\\(?:> ?\\)?")
+
+         (varid "[[:lower:]_][[:alnum:]'_]*")
+         ;; We allow ' preceding conids because of DataKinds/PolyKinds
+         (conid "'?[[:upper:]][[:alnum:]'_]*")
+         (sym "\\s.+")
+
+         ;; Top-level declarations
+         (topdecl-var
+          (concat line-prefix "\\(" varid "\\(?:\\s-*,\\s-*" varid "\\)*" "\\)"
+                  ;; optionally allow for a single newline after identifier
+                  "\\(\\s-+\\|\\s-*[\n]\\s-+\\)"
+                  ;; A toplevel declaration can be followed by a definition
+                  ;; (=), a type (::) or (∷), a guard, or a pattern which can
+                  ;; either be a variable, a constructor, a parenthesized
+                  ;; thingy, or an integer or a string.
+                  "\\(" varid "\\|" conid "\\|::\\|∷\\|=\\||\\|\\s(\\|[0-9\"']\\)"))
+         (topdecl-var2
+          (concat line-prefix "\\(" varid "\\|" conid "\\)\\s-*`\\(" varid "\\)`"))
+         (topdecl-bangpat
+          (concat line-prefix "\\(" varid "\\)\\s-*!"))
+         (topdecl-sym
+          (concat line-prefix "\\(" varid "\\|" conid "\\)\\s-*\\(" sym "\\)"))
+         (topdecl-sym2 (concat line-prefix "(\\(" sym "\\))"))
+
+         keywords)
+
+    (setq keywords
+          `(;; NOTICE the ordering below is significant
+            ;;
+            ("^#\\(?:[^\\\n]\\|\\\\\\(?:.\\|\n\\|\\'\\)\\)*\\(?:\n\\|\\'\\)" 0 'font-lock-preprocessor-face t)
+
+            ,@(haskell-font-lock-symbols-keywords)
+
+            ;; Special case for `as', `hiding', `safe' and `qualified', which are
+            ;; keywords in import statements but are not otherwise reserved.
+            ("\\<import[ \t]+\\(?:\\(safe\\>\\)[ \t]*\\)?\\(?:\\(qualified\\>\\)[ \t]*\\)?\\(?:\"[^\"]*\"[\t ]*\\)?[^ \t\n()]+[ \t]*\\(?:\\(\\<as\\>\\)[ \t]*[^ \t\n()]+[ \t]*\\)?\\(\\<hiding\\>\\)?"
+             (1 'haskell-keyword-face nil lax)
+             (2 'haskell-keyword-face nil lax)
+             (3 'haskell-keyword-face nil lax)
+             (4 'haskell-keyword-face nil lax))
+
+            ;; Special case for `foreign import'
+            ;; keywords in foreign import statements but are not otherwise reserved.
+            ("\\<\\(foreign\\)[ \t]+\\(import\\)[ \t]+\\(?:\\(ccall\\|stdcall\\|cplusplus\\|jvm\\|dotnet\\)[ \t]+\\)?\\(?:\\(safe\\|unsafe\\|interruptible\\)[ \t]+\\)?"
+             (1 'haskell-keyword-face nil lax)
+             (2 'haskell-keyword-face nil lax)
+             (3 'haskell-keyword-face nil lax)
+             (4 'haskell-keyword-face nil lax))
+
+            ;; Special case for `foreign export'
+            ;; keywords in foreign export statements but are not otherwise reserved.
+            ("\\<\\(foreign\\)[ \t]+\\(export\\)[ \t]+\\(?:\\(ccall\\|stdcall\\|cplusplus\\|jvm\\|dotnet\\)[ \t]+\\)?"
+             (1 'haskell-keyword-face nil lax)
+             (2 'haskell-keyword-face nil lax)
+             (3 'haskell-keyword-face nil lax))
+
+            ;; Special case for `type family' and `data family'.
+            ;; `family' is only reserved in these contexts.
+            ("\\<\\(type\\|data\\)[ \t]+\\(family\\>\\)"
+             (1 'haskell-keyword-face nil lax)
+             (2 'haskell-keyword-face nil lax))
+
+            ;; Special case for `type role'
+            ;; `role' is only reserved in this context.
+            ("\\<\\(type\\)[ \t]+\\(role\\>\\)"
+             (1 'haskell-keyword-face nil lax)
+             (2 'haskell-keyword-face nil lax))
+
+            ;; Toplevel Declarations.
+            ;; Place them *before* generic id-and-op highlighting.
+            (,topdecl-var  (1 (unless (member (match-string 1) haskell-font-lock-keywords)
+                                'haskell-definition-face)))
+            (,topdecl-var2 (2 (unless (member (match-string 2) haskell-font-lock-keywords)
+                                'haskell-definition-face)))
+            (,topdecl-bangpat  (1 (unless (member (match-string 1) haskell-font-lock-keywords)
+                                'haskell-definition-face)))
+            (,topdecl-sym  (2 (unless (member (match-string 2) '("\\" "=" "->" "→" "<-" "←" "::" "∷" "," ";" "`"))
+                                'haskell-definition-face)))
+            (,topdecl-sym2 (1 (unless (member (match-string 1) '("\\" "=" "->" "→" "<-" "←" "::" "∷" "," ";" "`"))
+                                'haskell-definition-face)))
+
+            ;; These four are debatable...
+            ("(\\(,*\\|->\\))" 0 'haskell-constructor-face)
+            ("\\[\\]" 0 'haskell-constructor-face)
+
+            ("`"
+             (0 (if (or (elt (syntax-ppss) 3) (elt (syntax-ppss) 4))
+                    (parse-partial-sexp (point) (point-max) nil nil (syntax-ppss)
+                                        'syntax-table)
+                  (when (save-excursion
+                          (goto-char (match-beginning 0))
+                          (haskell-lexeme-looking-at-backtick))
+                    (goto-char (match-end 0))
+                    (unless (text-property-not-all (match-beginning 1) (match-end 1) 'face nil)
+                      (put-text-property (match-beginning 1) (match-end 1) 'face 'haskell-operator-face))
+                    (unless (text-property-not-all (match-beginning 2) (match-end 2) 'face nil)
+                      (put-text-property (match-beginning 2) (match-end 2) 'face 'haskell-operator-face))
+                    (unless (text-property-not-all (match-beginning 4) (match-end 4) 'face nil)
+                      (put-text-property (match-beginning 4) (match-end 4) 'face 'haskell-operator-face))
+                    (add-text-properties
+                     (match-beginning 0) (match-end 0)
+                     '(font-lock-fontified t fontified t font-lock-multiline t))))))
+
+            (,haskell-lexeme-idsym-first-char
+             (0 (if (or (elt (syntax-ppss) 3) (elt (syntax-ppss) 4))
+                    (parse-partial-sexp (point) (point-max) nil nil (syntax-ppss)
+                                        'syntax-table)
+                  (when (save-excursion
+                          (goto-char (match-beginning 0))
+                          (haskell-lexeme-looking-at-qidsym))
+                    (goto-char (match-end 0))
+                    ;; note that we have to put face ourselves here because font-lock
+                    ;; will use match data from the original matcher
+                    (haskell-font-lock--put-face-on-type-or-constructor)))))))
+    keywords))
+
+
+(defun haskell-font-lock-fontify-block (lang-mode start end)
+  "Fontify a block as LANG-MODE."
+  (let ((string (buffer-substring-no-properties start end))
+        (modified (buffer-modified-p))
+        (org-buffer (current-buffer)) pos next)
+    (remove-text-properties start end '(face nil))
+    (with-current-buffer
+        (get-buffer-create
+         (concat " haskell-font-lock-fontify-block:" (symbol-name lang-mode)))
+      (delete-region (point-min) (point-max))
+      (insert string " ") ;; so there's a final property change
+      (cl-letf (((symbol-function 'message)
+                 (lambda (_fmt &rest _args))))
+        ;; silence messages
+        (unless (eq major-mode lang-mode) (funcall lang-mode))
+        (font-lock-ensure))
+      (setq pos (point-min))
+      (while (setq next (next-single-property-change pos 'face))
+        (put-text-property
+         (+ start (1- pos)) (1- (+ start next)) 'face
+         (or (get-text-property pos 'face) 'default) org-buffer)
+        (setq pos next))
+      (unless (equal pos (point-max))
+        (put-text-property
+         (+ start (1- pos)) (1- (+ start (point-max))) 'face
+         'default org-buffer)))
+    (add-text-properties
+     start end
+     '(font-lock-fontified t fontified t font-lock-multiline t))
+    (set-buffer-modified-p modified)))
+
+(defun haskell-syntactic-face-function (state)
+  "`font-lock-syntactic-face-function' for Haskell."
+  (cond
+   ((nth 3 state)
+    (if (equal ?| (nth 3 state))
+        ;; find out what kind of QuasiQuote is this
+        (let* ((qqname (save-excursion
+                        (goto-char (nth 8 state))
+                        (skip-syntax-backward "w._")
+                        (buffer-substring-no-properties (point) (nth 8 state))))
+               (lang-mode (cdr (assoc qqname haskell-font-lock-quasi-quote-modes))))
+
+          (if (and lang-mode
+                   (fboundp lang-mode))
+              (save-excursion
+                ;; find the end of the QuasiQuote
+                (parse-partial-sexp (point) (point-max) nil nil state
+                                    'syntax-table)
+                (haskell-font-lock-fontify-block lang-mode (1+ (nth 8 state)) (1- (point)))
+                ;; must return nil here so that it is not fontified again as string
+                nil)
+            ;; fontify normally as string because lang-mode is not present
+            'haskell-quasi-quote-face))
+      (save-excursion
+        (let
+            ((state2
+              (parse-partial-sexp (point) (point-max) nil nil state
+                                  'syntax-table))
+             (end-of-string (point)))
+
+          (put-text-property (nth 8 state) (point)
+                             'face 'font-lock-string-face)
+
+
+          (if (or (equal t (nth 3 state)) (nth 3 state2))
+              ;; This is an unterminated string constant, use warning
+              ;; face for the opening quote.
+              (put-text-property (nth 8 state) (1+ (nth 8 state))
+                                 'face 'font-lock-warning-face))
+
+          (goto-char (1+ (nth 8 state)))
+          (while (re-search-forward "\\\\" end-of-string t)
+
+            (goto-char (1- (point)))
+
+            (if (looking-at haskell-lexeme-string-literal-inside-item)
+                (goto-char (match-end 0))
+
+              ;; We are looking at an unacceptable escape
+              ;; sequence. Use warning face to highlight that.
+              (put-text-property (point) (1+ (point))
+                                 'face 'font-lock-warning-face)
+              (goto-char (1+ (point)))))))
+      ;; must return nil here so that it is not fontified again as string
+      nil))
+   ;; Detect literate comment lines starting with syntax class '<'
+   ((save-excursion
+      (goto-char (nth 8 state))
+      (equal (string-to-syntax "<") (syntax-after (point))))
+    'haskell-literate-comment-face)
+   ;; Detect pragmas. A pragma is enclosed in special comment
+   ;; delimiters {-# .. #-}.
+   ((save-excursion
+      (goto-char (nth 8 state))
+      (and (looking-at-p "{-#")
+           (forward-comment 1)
+           (goto-char (- (point) 3))
+           (looking-at-p "#-}")))
+    'haskell-pragma-face)
+   ;; Detect Liquid Haskell annotations enclosed in special comment
+   ;; delimiters {-@ .. @-}.
+   ((save-excursion
+      (goto-char (nth 8 state))
+      (and (looking-at-p "{-@")
+           (forward-comment 1)
+           (goto-char (- (point) 3))
+           (looking-at-p "@-}")))
+    'haskell-liquid-haskell-annotation-face)
+   ;; Haddock comment start with either "-- [|^*$]" or "{- ?[|^*$]"
+   ;; (note space optional for nested comments and mandatory for
+   ;; double dash comments).
+   ;;
+   ;; Haddock comment will also continue on next line, provided:
+   ;; - current line is a double dash haddock comment
+   ;; - next line is also double dash comment
+   ;; - there is only whitespace between
+   ;;
+   ;; We recognize double dash haddock comments by property
+   ;; 'font-lock-doc-face attached to newline. In case of {- -}
+   ;; comments newline is outside of comment.
+   ((save-excursion
+      (goto-char (nth 8 state))
+      (or (looking-at-p "\\(?:{- ?\\|-- \\)[|^*$]")
+          (and (looking-at-p "--")            ; are we at double dash comment
+               (forward-line -1)              ; this is nil on first line
+               (eq (get-text-property (line-end-position) 'face)
+                   'font-lock-doc-face)       ; is a doc face
+               (forward-line)
+               (skip-syntax-forward "-")      ; see if there is only whitespace
+               (eq (point) (nth 8 state)))))  ; we are back in position
+    ;; Here we look inside the comment to see if there are substrings
+    ;; worth marking inside we try to emulate as much of haddock as
+    ;; possible.  First we add comment face all over the comment, then
+    ;; we add special features.
+    (let ((beg (nth 8 state))
+          (end (save-excursion
+                 (parse-partial-sexp (point) (point-max) nil nil state
+                                     'syntax-table)
+                 (point)))
+          (emphasis-open-point nil)
+          (strong-open-point nil))
+      (put-text-property beg end 'face 'font-lock-doc-face)
+
+      (when (fboundp 'add-face-text-property)
+        ;; `add-face-text-property' is not defined in Emacs 23
+
+        ;; iterate over chars, take escaped chars unconditionally
+        ;; mark when a construct is opened, close and face it when
+        ;; it is closed
+
+        (save-excursion
+          (while (< (point) end)
+            (if (looking-at "__\\|\\\\.\\|\\\n\\|[/]")
+                (progn
+                  (cond
+                   ((equal (match-string 0) "/")
+                    (if emphasis-open-point
+                        (progn
+                          (add-face-text-property emphasis-open-point (match-end 0)
+                                                  '(:slant italic))
+                          (setq emphasis-open-point nil))
+                      (setq emphasis-open-point (point))))
+                   ((equal (match-string 0) "__")
+                    (if strong-open-point
+                        (progn
+                          (add-face-text-property strong-open-point (match-end 0)
+                                                  '(:weight bold))
+                          (setq strong-open-point nil))
+                      (setq strong-open-point (point))))
+                   (t
+                    ;; this is a backslash escape sequence, skip over it
+                    ))
+                  (goto-char (match-end 0)))
+              ;; skip chars that are not interesting
+              (goto-char (1+ (point)))
+              (skip-chars-forward "^_\\\\/" end))))))
+    nil)
+   (t 'font-lock-comment-face)))
+
+(defun haskell-font-lock-defaults-create ()
+  "Locally set `font-lock-defaults' for Haskell."
+  (setq-local font-lock-defaults
+              '((haskell-font-lock-keywords)
+                nil nil nil nil
+                (font-lock-syntactic-face-function
+                 . haskell-syntactic-face-function)
+                ;; Get help from font-lock-syntactic-keywords.
+                (parse-sexp-lookup-properties . t)
+                (font-lock-extra-managed-props . (composition)))))
+
+(defun haskell-fontify-as-mode (text mode)
+  "Fontify TEXT as MODE, returning the fontified text."
+  (with-temp-buffer
+    (funcall mode)
+    (insert text)
+    (if (fboundp 'font-lock-ensure)
+        (font-lock-ensure)
+      (with-no-warnings (font-lock-fontify-buffer)))
+    (buffer-substring (point-min) (point-max))))
+
+;; Provide ourselves:
+
+(provide 'haskell-font-lock)
+
+;; Local Variables:
+;; coding: utf-8-unix
+;; tab-width: 8
+;; End:
+
+;;; haskell-font-lock.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-font-lock.elc b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-font-lock.elc
new file mode 100644
index 0000000000..c7eaff6090
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-font-lock.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-ghc-support.el b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-ghc-support.el
new file mode 100644
index 0000000000..93690170c6
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-ghc-support.el
@@ -0,0 +1,1344 @@
+;;; haskell-ghc-support.el --- GHC specific code    -*- coding: utf-8; lexical-binding: t -*-
+
+;; Copyright © 2016 Haskell Mode
+;; Author:  2016 Gracjan Polak
+
+;; This file is not part of GNU Emacs.
+
+;; This file 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, or (at your option)
+;; any later version.
+
+;; This file 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This file containt GHC specific constants and information.
+
+;;; Code:
+
+(defvar haskell-ghc-supported-extensions
+  '(
+    ;;; BEGIN haskell-ghc-supported-extensions
+    "AllowAmbiguousTypes"
+    "AlternativeLayoutRule"
+    "AlternativeLayoutRuleTransitional"
+    "ApplicativeDo"
+    "Arrows"
+    "AutoDeriveTypeable"
+    "BangPatterns"
+    "BinaryLiterals"
+    "CApiFFI"
+    "CPP"
+    "ConstrainedClassMethods"
+    "ConstraintKinds"
+    "DataKinds"
+    "DatatypeContexts"
+    "DefaultSignatures"
+    "DeriveAnyClass"
+    "DeriveDataTypeable"
+    "DeriveFoldable"
+    "DeriveFunctor"
+    "DeriveGeneric"
+    "DeriveLift"
+    "DeriveTraversable"
+    "DisambiguateRecordFields"
+    "DoAndIfThenElse"
+    "DoRec"
+    "DuplicateRecordFields"
+    "EmptyCase"
+    "EmptyDataDecls"
+    "ExistentialQuantification"
+    "ExplicitForAll"
+    "ExplicitNamespaces"
+    "ExtendedDefaultRules"
+    "FlexibleContexts"
+    "FlexibleInstances"
+    "ForeignFunctionInterface"
+    "FunctionalDependencies"
+    "GADTSyntax"
+    "GADTs"
+    "GHCForeignImportPrim"
+    "GeneralizedNewtypeDeriving"
+    "Haskell2010"
+    "Haskell98"
+    "ImplicitParams"
+    "ImplicitPrelude"
+    "ImpredicativeTypes"
+    "IncoherentInstances"
+    "InstanceSigs"
+    "InterruptibleFFI"
+    "JavaScriptFFI"
+    "KindSignatures"
+    "LambdaCase"
+    "LiberalTypeSynonyms"
+    "MagicHash"
+    "MonadComprehensions"
+    "MonadFailDesugaring"
+    "MonoLocalBinds"
+    "MonoPatBinds"
+    "MonomorphismRestriction"
+    "MultiParamTypeClasses"
+    "MultiWayIf"
+    "NPlusKPatterns"
+    "NamedFieldPuns"
+    "NamedWildCards"
+    "NegativeLiterals"
+    "NoAllowAmbiguousTypes"
+    "NoAlternativeLayoutRule"
+    "NoAlternativeLayoutRuleTransitional"
+    "NoApplicativeDo"
+    "NoArrows"
+    "NoAutoDeriveTypeable"
+    "NoBangPatterns"
+    "NoBinaryLiterals"
+    "NoCApiFFI"
+    "NoCPP"
+    "NoConstrainedClassMethods"
+    "NoConstraintKinds"
+    "NoDataKinds"
+    "NoDatatypeContexts"
+    "NoDefaultSignatures"
+    "NoDeriveAnyClass"
+    "NoDeriveDataTypeable"
+    "NoDeriveFoldable"
+    "NoDeriveFunctor"
+    "NoDeriveGeneric"
+    "NoDeriveLift"
+    "NoDeriveTraversable"
+    "NoDisambiguateRecordFields"
+    "NoDoAndIfThenElse"
+    "NoDoRec"
+    "NoDuplicateRecordFields"
+    "NoEmptyCase"
+    "NoEmptyDataDecls"
+    "NoExistentialQuantification"
+    "NoExplicitForAll"
+    "NoExplicitNamespaces"
+    "NoExtendedDefaultRules"
+    "NoFlexibleContexts"
+    "NoFlexibleInstances"
+    "NoForeignFunctionInterface"
+    "NoFunctionalDependencies"
+    "NoGADTSyntax"
+    "NoGADTs"
+    "NoGHCForeignImportPrim"
+    "NoGeneralizedNewtypeDeriving"
+    "NoImplicitParams"
+    "NoImplicitPrelude"
+    "NoImpredicativeTypes"
+    "NoIncoherentInstances"
+    "NoInstanceSigs"
+    "NoInterruptibleFFI"
+    "NoJavaScriptFFI"
+    "NoKindSignatures"
+    "NoLambdaCase"
+    "NoLiberalTypeSynonyms"
+    "NoMagicHash"
+    "NoMonadComprehensions"
+    "NoMonadFailDesugaring"
+    "NoMonoLocalBinds"
+    "NoMonoPatBinds"
+    "NoMonomorphismRestriction"
+    "NoMultiParamTypeClasses"
+    "NoMultiWayIf"
+    "NoNPlusKPatterns"
+    "NoNamedFieldPuns"
+    "NoNamedWildCards"
+    "NoNegativeLiterals"
+    "NoNondecreasingIndentation"
+    "NoNullaryTypeClasses"
+    "NoNumDecimals"
+    "NoOverlappingInstances"
+    "NoOverloadedLabels"
+    "NoOverloadedLists"
+    "NoOverloadedStrings"
+    "NoPackageImports"
+    "NoParallelArrays"
+    "NoParallelListComp"
+    "NoPartialTypeSignatures"
+    "NoPatternGuards"
+    "NoPatternSignatures"
+    "NoPatternSynonyms"
+    "NoPolyKinds"
+    "NoPolymorphicComponents"
+    "NoPostfixOperators"
+    "NoQuasiQuotes"
+    "NoRank2Types"
+    "NoRankNTypes"
+    "NoRebindableSyntax"
+    "NoRecordPuns"
+    "NoRecordWildCards"
+    "NoRecursiveDo"
+    "NoRelaxedLayout"
+    "NoRelaxedPolyRec"
+    "NoRoleAnnotations"
+    "NoScopedTypeVariables"
+    "NoStandaloneDeriving"
+    "NoStaticPointers"
+    "NoStrict"
+    "NoStrictData"
+    "NoTemplateHaskell"
+    "NoTemplateHaskellQuotes"
+    "NoTraditionalRecordSyntax"
+    "NoTransformListComp"
+    "NoTupleSections"
+    "NoTypeApplications"
+    "NoTypeFamilies"
+    "NoTypeFamilyDependencies"
+    "NoTypeInType"
+    "NoTypeOperators"
+    "NoTypeSynonymInstances"
+    "NoUnboxedTuples"
+    "NoUndecidableInstances"
+    "NoUndecidableSuperClasses"
+    "NoUnicodeSyntax"
+    "NoUnliftedFFITypes"
+    "NoViewPatterns"
+    "NondecreasingIndentation"
+    "NullaryTypeClasses"
+    "NumDecimals"
+    "OverlappingInstances"
+    "OverloadedLabels"
+    "OverloadedLists"
+    "OverloadedStrings"
+    "PackageImports"
+    "ParallelArrays"
+    "ParallelListComp"
+    "PartialTypeSignatures"
+    "PatternGuards"
+    "PatternSignatures"
+    "PatternSynonyms"
+    "PolyKinds"
+    "PolymorphicComponents"
+    "PostfixOperators"
+    "QuasiQuotes"
+    "Rank2Types"
+    "RankNTypes"
+    "RebindableSyntax"
+    "RecordPuns"
+    "RecordWildCards"
+    "RecursiveDo"
+    "RelaxedLayout"
+    "RelaxedPolyRec"
+    "RoleAnnotations"
+    "Safe"
+    "ScopedTypeVariables"
+    "StandaloneDeriving"
+    "StaticPointers"
+    "Strict"
+    "StrictData"
+    "TemplateHaskell"
+    "TemplateHaskellQuotes"
+    "TraditionalRecordSyntax"
+    "TransformListComp"
+    "Trustworthy"
+    "TupleSections"
+    "TypeApplications"
+    "TypeFamilies"
+    "TypeFamilyDependencies"
+    "TypeInType"
+    "TypeOperators"
+    "TypeSynonymInstances"
+    "UnboxedTuples"
+    "UndecidableInstances"
+    "UndecidableSuperClasses"
+    "UnicodeSyntax"
+    "UnliftedFFITypes"
+    "Unsafe"
+    "ViewPatterns"
+    ;;; END haskell-ghc-supported-extensions
+    )
+  "List of language extensions supported by any known version of GHC.
+
+This list should be updated by running `haskell-update-ghc-support'.")
+
+(defvar haskell-ghc-supported-options
+  '(
+    ;;; BEGIN haskell-ghc-supported-options
+    "-#include"
+    "--abi-hash"
+    "--frontend"
+    "--help"
+    "--info"
+    "--interactive"
+    "--make"
+    "--numeric-version"
+    "--print-booter-version"
+    "--print-build-platform"
+    "--print-c-compiler-flags"
+    "--print-c-compiler-link-flags"
+    "--print-debug-on"
+    "--print-gcc-linker-flags"
+    "--print-global-package-db"
+    "--print-have-interpreter"
+    "--print-have-native-code-generator"
+    "--print-host-platform"
+    "--print-ld-flags"
+    "--print-ld-linker-flags"
+    "--print-leading-underscore"
+    "--print-libdir"
+    "--print-object-splitting-supported"
+    "--print-project-git-commit-id"
+    "--print-project-version"
+    "--print-rts-ways"
+    "--print-stage"
+    "--print-support-smp"
+    "--print-tables-next-to-code"
+    "--print-target-platform"
+    "--print-unregisterised"
+    "--show-iface"
+    "--show-options"
+    "--show-packages"
+    "--supported-extensions"
+    "--supported-languages"
+    "--version"
+    "-?"
+    "-C"
+    "-D"
+    "-E"
+    "-F"
+    "-H"
+    "-I"
+    "-L"
+    "-M"
+    "-O"
+    "-Odph"
+    "-Onot"
+    "-Rghc-timing"
+    "-S"
+    "-U"
+    "-V"
+    "-W"
+    "-Wall"
+    "-Wall-missed-specialisations"
+    "-Walternative-layout-rule-transitional"
+    "-Wamp"
+    "-Wauto-orphans"
+    "-Wcompat"
+    "-Wcontext-quantification"
+    "-Wdefault"
+    "-Wdeferred-type-errors"
+    "-Wdeprecated-flags"
+    "-Wdeprecations"
+    "-Wderiving-typeable"
+    "-Wdodgy-exports"
+    "-Wdodgy-foreign-imports"
+    "-Wdodgy-imports"
+    "-Wduplicate-constraints"
+    "-Wduplicate-exports"
+    "-Wempty-enumerations"
+    "-Werror"
+    "-Weverything"
+    "-Wextra"
+    "-Whi-shadowing"
+    "-Widentities"
+    "-Wimplicit-prelude"
+    "-Wincomplete-patterns"
+    "-Wincomplete-record-updates"
+    "-Wincomplete-uni-patterns"
+    "-Winline-rule-shadowing"
+    "-Wmissed-specialisations"
+    "-Wmissing-exported-signatures"
+    "-Wmissing-exported-sigs"
+    "-Wmissing-fields"
+    "-Wmissing-import-lists"
+    "-Wmissing-local-signatures"
+    "-Wmissing-local-sigs"
+    "-Wmissing-methods"
+    "-Wmissing-monadfail-instances"
+    "-Wmissing-pattern-synonym-signatures"
+    "-Wmissing-signatures"
+    "-Wmonomorphism-restriction"
+    "-Wname-shadowing"
+    "-Wno-all"
+    "-Wno-all-missed-specialisations"
+    "-Wno-alternative-layout-rule-transitional"
+    "-Wno-amp"
+    "-Wno-auto-orphans"
+    "-Wno-compat"
+    "-Wno-context-quantification"
+    "-Wno-default"
+    "-Wno-deferred-type-errors"
+    "-Wno-deprecated-flags"
+    "-Wno-deprecations"
+    "-Wno-deriving-typeable"
+    "-Wno-dodgy-exports"
+    "-Wno-dodgy-foreign-imports"
+    "-Wno-dodgy-imports"
+    "-Wno-duplicate-constraints"
+    "-Wno-duplicate-exports"
+    "-Wno-empty-enumerations"
+    "-Wno-everything"
+    "-Wno-extra"
+    "-Wno-hi-shadowing"
+    "-Wno-identities"
+    "-Wno-implicit-prelude"
+    "-Wno-incomplete-patterns"
+    "-Wno-incomplete-record-updates"
+    "-Wno-incomplete-uni-patterns"
+    "-Wno-inline-rule-shadowing"
+    "-Wno-missed-specialisations"
+    "-Wno-missing-exported-signatures"
+    "-Wno-missing-exported-sigs"
+    "-Wno-missing-fields"
+    "-Wno-missing-import-lists"
+    "-Wno-missing-local-signatures"
+    "-Wno-missing-local-sigs"
+    "-Wno-missing-methods"
+    "-Wno-missing-monadfail-instances"
+    "-Wno-missing-pattern-synonym-signatures"
+    "-Wno-missing-signatures"
+    "-Wno-monomorphism-restriction"
+    "-Wno-name-shadowing"
+    "-Wno-noncanonical-monad-instances"
+    "-Wno-noncanonical-monadfail-instances"
+    "-Wno-noncanonical-monoid-instances"
+    "-Wno-orphans"
+    "-Wno-overflowed-literals"
+    "-Wno-overlapping-patterns"
+    "-Wno-partial-type-signatures"
+    "-Wno-redundant-constraints"
+    "-Wno-safe"
+    "-Wno-semigroup"
+    "-Wno-tabs"
+    "-Wno-trustworthy-safe"
+    "-Wno-type-defaults"
+    "-Wno-typed-holes"
+    "-Wno-unrecognised-pragmas"
+    "-Wno-unrecognised-warning-flags"
+    "-Wno-unsafe"
+    "-Wno-unsupported-calling-conventions"
+    "-Wno-unsupported-llvm-version"
+    "-Wno-unticked-promoted-constructors"
+    "-Wno-unused-binds"
+    "-Wno-unused-do-bind"
+    "-Wno-unused-foralls"
+    "-Wno-unused-imports"
+    "-Wno-unused-local-binds"
+    "-Wno-unused-matches"
+    "-Wno-unused-pattern-binds"
+    "-Wno-unused-top-binds"
+    "-Wno-unused-type-patterns"
+    "-Wno-warnings-deprecations"
+    "-Wno-wrong-do-bind"
+    "-Wnoncanonical-monad-instances"
+    "-Wnoncanonical-monadfail-instances"
+    "-Wnoncanonical-monoid-instances"
+    "-Wnot"
+    "-Worphans"
+    "-Woverflowed-literals"
+    "-Woverlapping-patterns"
+    "-Wpartial-type-signatures"
+    "-Wredundant-constraints"
+    "-Wsafe"
+    "-Wsemigroup"
+    "-Wtabs"
+    "-Wtrustworthy-safe"
+    "-Wtype-defaults"
+    "-Wtyped-holes"
+    "-Wunrecognised-pragmas"
+    "-Wunrecognised-warning-flags"
+    "-Wunsafe"
+    "-Wunsupported-calling-conventions"
+    "-Wunsupported-llvm-version"
+    "-Wunticked-promoted-constructors"
+    "-Wunused-binds"
+    "-Wunused-do-bind"
+    "-Wunused-foralls"
+    "-Wunused-imports"
+    "-Wunused-local-binds"
+    "-Wunused-matches"
+    "-Wunused-pattern-binds"
+    "-Wunused-top-binds"
+    "-Wunused-type-patterns"
+    "-Wwarn"
+    "-Wwarnings-deprecations"
+    "-Wwrong-do-bind"
+    "-XAllowAmbiguousTypes"
+    "-XAlternativeLayoutRule"
+    "-XAlternativeLayoutRuleTransitional"
+    "-XApplicativeDo"
+    "-XArrows"
+    "-XAutoDeriveTypeable"
+    "-XBangPatterns"
+    "-XBinaryLiterals"
+    "-XCApiFFI"
+    "-XCPP"
+    "-XConstrainedClassMethods"
+    "-XConstraintKinds"
+    "-XDataKinds"
+    "-XDatatypeContexts"
+    "-XDefaultSignatures"
+    "-XDeriveAnyClass"
+    "-XDeriveDataTypeable"
+    "-XDeriveFoldable"
+    "-XDeriveFunctor"
+    "-XDeriveGeneric"
+    "-XDeriveLift"
+    "-XDeriveTraversable"
+    "-XDisambiguateRecordFields"
+    "-XDoAndIfThenElse"
+    "-XDoRec"
+    "-XDuplicateRecordFields"
+    "-XEmptyCase"
+    "-XEmptyDataDecls"
+    "-XExistentialQuantification"
+    "-XExplicitForAll"
+    "-XExplicitNamespaces"
+    "-XExtendedDefaultRules"
+    "-XFlexibleContexts"
+    "-XFlexibleInstances"
+    "-XForeignFunctionInterface"
+    "-XFunctionalDependencies"
+    "-XGADTSyntax"
+    "-XGADTs"
+    "-XGHCForeignImportPrim"
+    "-XGeneralizedNewtypeDeriving"
+    "-XGenerics"
+    "-XHaskell2010"
+    "-XHaskell98"
+    "-XImplicitParams"
+    "-XImplicitPrelude"
+    "-XImpredicativeTypes"
+    "-XIncoherentInstances"
+    "-XInstanceSigs"
+    "-XInterruptibleFFI"
+    "-XJavaScriptFFI"
+    "-XKindSignatures"
+    "-XLambdaCase"
+    "-XLiberalTypeSynonyms"
+    "-XMagicHash"
+    "-XMonadComprehensions"
+    "-XMonadFailDesugaring"
+    "-XMonoLocalBinds"
+    "-XMonoPatBinds"
+    "-XMonomorphismRestriction"
+    "-XMultiParamTypeClasses"
+    "-XMultiWayIf"
+    "-XNPlusKPatterns"
+    "-XNamedFieldPuns"
+    "-XNamedWildCards"
+    "-XNegativeLiterals"
+    "-XNoAllowAmbiguousTypes"
+    "-XNoAlternativeLayoutRule"
+    "-XNoAlternativeLayoutRuleTransitional"
+    "-XNoApplicativeDo"
+    "-XNoArrows"
+    "-XNoAutoDeriveTypeable"
+    "-XNoBangPatterns"
+    "-XNoBinaryLiterals"
+    "-XNoCApiFFI"
+    "-XNoCPP"
+    "-XNoConstrainedClassMethods"
+    "-XNoConstraintKinds"
+    "-XNoDataKinds"
+    "-XNoDatatypeContexts"
+    "-XNoDefaultSignatures"
+    "-XNoDeriveAnyClass"
+    "-XNoDeriveDataTypeable"
+    "-XNoDeriveFoldable"
+    "-XNoDeriveFunctor"
+    "-XNoDeriveGeneric"
+    "-XNoDeriveLift"
+    "-XNoDeriveTraversable"
+    "-XNoDisambiguateRecordFields"
+    "-XNoDoAndIfThenElse"
+    "-XNoDoRec"
+    "-XNoDuplicateRecordFields"
+    "-XNoEmptyCase"
+    "-XNoEmptyDataDecls"
+    "-XNoExistentialQuantification"
+    "-XNoExplicitForAll"
+    "-XNoExplicitNamespaces"
+    "-XNoExtendedDefaultRules"
+    "-XNoFlexibleContexts"
+    "-XNoFlexibleInstances"
+    "-XNoForeignFunctionInterface"
+    "-XNoFunctionalDependencies"
+    "-XNoGADTSyntax"
+    "-XNoGADTs"
+    "-XNoGHCForeignImportPrim"
+    "-XNoGeneralizedNewtypeDeriving"
+    "-XNoGenerics"
+    "-XNoImplicitParams"
+    "-XNoImplicitPrelude"
+    "-XNoImpredicativeTypes"
+    "-XNoIncoherentInstances"
+    "-XNoInstanceSigs"
+    "-XNoInterruptibleFFI"
+    "-XNoJavaScriptFFI"
+    "-XNoKindSignatures"
+    "-XNoLambdaCase"
+    "-XNoLiberalTypeSynonyms"
+    "-XNoMagicHash"
+    "-XNoMonadComprehensions"
+    "-XNoMonadFailDesugaring"
+    "-XNoMonoLocalBinds"
+    "-XNoMonoPatBinds"
+    "-XNoMonomorphismRestriction"
+    "-XNoMultiParamTypeClasses"
+    "-XNoMultiWayIf"
+    "-XNoNPlusKPatterns"
+    "-XNoNamedFieldPuns"
+    "-XNoNamedWildCards"
+    "-XNoNegativeLiterals"
+    "-XNoNondecreasingIndentation"
+    "-XNoNullaryTypeClasses"
+    "-XNoNumDecimals"
+    "-XNoOverlappingInstances"
+    "-XNoOverloadedLabels"
+    "-XNoOverloadedLists"
+    "-XNoOverloadedStrings"
+    "-XNoPackageImports"
+    "-XNoParallelArrays"
+    "-XNoParallelListComp"
+    "-XNoPartialTypeSignatures"
+    "-XNoPatternGuards"
+    "-XNoPatternSignatures"
+    "-XNoPatternSynonyms"
+    "-XNoPolyKinds"
+    "-XNoPolymorphicComponents"
+    "-XNoPostfixOperators"
+    "-XNoQuasiQuotes"
+    "-XNoRank2Types"
+    "-XNoRankNTypes"
+    "-XNoRebindableSyntax"
+    "-XNoRecordPuns"
+    "-XNoRecordWildCards"
+    "-XNoRecursiveDo"
+    "-XNoRelaxedLayout"
+    "-XNoRelaxedPolyRec"
+    "-XNoRoleAnnotations"
+    "-XNoScopedTypeVariables"
+    "-XNoStandaloneDeriving"
+    "-XNoStaticPointers"
+    "-XNoStrict"
+    "-XNoStrictData"
+    "-XNoTemplateHaskell"
+    "-XNoTemplateHaskellQuotes"
+    "-XNoTraditionalRecordSyntax"
+    "-XNoTransformListComp"
+    "-XNoTupleSections"
+    "-XNoTypeApplications"
+    "-XNoTypeFamilies"
+    "-XNoTypeFamilyDependencies"
+    "-XNoTypeInType"
+    "-XNoTypeOperators"
+    "-XNoTypeSynonymInstances"
+    "-XNoUnboxedTuples"
+    "-XNoUndecidableInstances"
+    "-XNoUndecidableSuperClasses"
+    "-XNoUnicodeSyntax"
+    "-XNoUnliftedFFITypes"
+    "-XNoViewPatterns"
+    "-XNondecreasingIndentation"
+    "-XNullaryTypeClasses"
+    "-XNumDecimals"
+    "-XOverlappingInstances"
+    "-XOverloadedLabels"
+    "-XOverloadedLists"
+    "-XOverloadedStrings"
+    "-XPackageImports"
+    "-XParallelArrays"
+    "-XParallelListComp"
+    "-XPartialTypeSignatures"
+    "-XPatternGuards"
+    "-XPatternSignatures"
+    "-XPatternSynonyms"
+    "-XPolyKinds"
+    "-XPolymorphicComponents"
+    "-XPostfixOperators"
+    "-XQuasiQuotes"
+    "-XRank2Types"
+    "-XRankNTypes"
+    "-XRebindableSyntax"
+    "-XRecordPuns"
+    "-XRecordWildCards"
+    "-XRecursiveDo"
+    "-XRelaxedLayout"
+    "-XRelaxedPolyRec"
+    "-XRoleAnnotations"
+    "-XSafe"
+    "-XScopedTypeVariables"
+    "-XStandaloneDeriving"
+    "-XStaticPointers"
+    "-XStrict"
+    "-XStrictData"
+    "-XTemplateHaskell"
+    "-XTemplateHaskellQuotes"
+    "-XTraditionalRecordSyntax"
+    "-XTransformListComp"
+    "-XTrustworthy"
+    "-XTupleSections"
+    "-XTypeApplications"
+    "-XTypeFamilies"
+    "-XTypeFamilyDependencies"
+    "-XTypeInType"
+    "-XTypeOperators"
+    "-XTypeSynonymInstances"
+    "-XUnboxedTuples"
+    "-XUndecidableInstances"
+    "-XUndecidableSuperClasses"
+    "-XUnicodeSyntax"
+    "-XUnliftedFFITypes"
+    "-XUnsafe"
+    "-XViewPatterns"
+    "-auto"
+    "-auto-all"
+    "-c"
+    "-caf-all"
+    "-clear-package-db"
+    "-cpp"
+    "-dannot-lint"
+    "-dasm-lint"
+    "-dcmm-lint"
+    "-dcore-lint"
+    "-ddump-asm"
+    "-ddump-asm-conflicts"
+    "-ddump-asm-expanded"
+    "-ddump-asm-liveness"
+    "-ddump-asm-native"
+    "-ddump-asm-regalloc"
+    "-ddump-asm-regalloc-stages"
+    "-ddump-asm-stats"
+    "-ddump-bcos"
+    "-ddump-call-arity"
+    "-ddump-cmm"
+    "-ddump-cmm-cbe"
+    "-ddump-cmm-cfg"
+    "-ddump-cmm-cps"
+    "-ddump-cmm-info"
+    "-ddump-cmm-proc"
+    "-ddump-cmm-procmap"
+    "-ddump-cmm-raw"
+    "-ddump-cmm-sink"
+    "-ddump-cmm-sp"
+    "-ddump-cmm-split"
+    "-ddump-cmm-switch"
+    "-ddump-core-stats"
+    "-ddump-cs-trace"
+    "-ddump-cse"
+    "-ddump-debug"
+    "-ddump-deriv"
+    "-ddump-ds"
+    "-ddump-file-prefix"
+    "-ddump-foreign"
+    "-ddump-hi"
+    "-ddump-hi-diffs"
+    "-ddump-hpc"
+    "-ddump-if-trace"
+    "-ddump-inlinings"
+    "-ddump-llvm"
+    "-ddump-minimal-imports"
+    "-ddump-mod-cycles"
+    "-ddump-mod-map"
+    "-ddump-occur-anal"
+    "-ddump-opt-cmm"
+    "-ddump-parsed"
+    "-ddump-prep"
+    "-ddump-rn"
+    "-ddump-rn-stats"
+    "-ddump-rn-trace"
+    "-ddump-rtti"
+    "-ddump-rule-firings"
+    "-ddump-rule-rewrites"
+    "-ddump-rules"
+    "-ddump-simpl"
+    "-ddump-simpl-iterations"
+    "-ddump-simpl-stats"
+    "-ddump-simpl-trace"
+    "-ddump-spec"
+    "-ddump-splices"
+    "-ddump-stg"
+    "-ddump-str-signatures"
+    "-ddump-stranal"
+    "-ddump-strsigs"
+    "-ddump-tc"
+    "-ddump-tc-trace"
+    "-ddump-ticked"
+    "-ddump-to-file"
+    "-ddump-types"
+    "-ddump-vect"
+    "-ddump-view-pattern-commoning"
+    "-ddump-vt-trace"
+    "-ddump-worker-wrapper"
+    "-debug"
+    "-dep-makefile"
+    "-dep-suffix"
+    "-dfaststring-stats"
+    "-dinitial-unique"
+    "-distrust"
+    "-distrust-all-packages"
+    "-dno-debug-output"
+    "-dno-llvm-mangler"
+    "-dno-ppr-case-as-let"
+    "-dno-ppr-ticks"
+    "-dno-suppress-coercions"
+    "-dno-suppress-idinfo"
+    "-dno-suppress-module-prefixes"
+    "-dno-suppress-type-applications"
+    "-dno-suppress-type-signatures"
+    "-dno-suppress-unfoldings"
+    "-dno-suppress-uniques"
+    "-dno-suppress-var-kinds"
+    "-dppr-case-as-let"
+    "-dppr-cols"
+    "-dppr-debug"
+    "-dppr-ticks"
+    "-dppr-user-length"
+    "-dshow-passes"
+    "-dsource-stats"
+    "-dstg-lint"
+    "-dstg-stats"
+    "-dsuppress-all"
+    "-dsuppress-coercions"
+    "-dsuppress-idinfo"
+    "-dsuppress-module-prefixes"
+    "-dsuppress-type-applications"
+    "-dsuppress-type-signatures"
+    "-dsuppress-unfoldings"
+    "-dsuppress-uniques"
+    "-dsuppress-var-kinds"
+    "-dth-dec-file"
+    "-dtrace-level"
+    "-dumpdir"
+    "-dunique-increment"
+    "-dverbose-core2core"
+    "-dverbose-stg2stg"
+    "-dylib-install-name"
+    "-dynamic"
+    "-dynamic-too"
+    "-dynhisuf"
+    "-dynload"
+    "-dyno"
+    "-dynosuf"
+    "-e"
+    "-eventlog"
+    "-exclude-module"
+    "-fPArr"
+    "-fPIC"
+    "-fallow-incoherent-instances"
+    "-fallow-overlapping-instances"
+    "-fallow-undecidable-instances"
+    "-farrows"
+    "-fasm"
+    "-fbang-patterns"
+    "-fbuilding-cabal-package"
+    "-fbyte-code"
+    "-fcall-arity"
+    "-fcase-merge"
+    "-fcmm-elim-common-blocks"
+    "-fcmm-sink"
+    "-fconstraint-solver-iterations"
+    "-fcontext-stack"
+    "-fcpr-anal"
+    "-fcpr-off"
+    "-fcross-module-specialise"
+    "-fcse"
+    "-fdefer-type-errors"
+    "-fdefer-typed-holes"
+    "-fdicts-cheap"
+    "-fdicts-strict"
+    "-fdmd-tx-dict-sel"
+    "-fdo-eta-reduction"
+    "-fdo-lambda-eta-expansion"
+    "-feager-blackholing"
+    "-fembed-manifest"
+    "-fenable-rewrite-rules"
+    "-ferror-spans"
+    "-fexcess-precision"
+    "-fexpose-all-unfoldings"
+    "-fext-core"
+    "-fextended-default-rules"
+    "-fexternal-interpreter"
+    "-fffi"
+    "-ffi"
+    "-fflat-cache"
+    "-ffloat-all-lams"
+    "-ffloat-in"
+    "-ffloat-lam-args"
+    "-fforce-recomp"
+    "-ffrontend-opt"
+    "-ffull-laziness"
+    "-ffun-to-thunk"
+    "-fgen-manifest"
+    "-fghci-history"
+    "-fghci-sandbox"
+    "-fglasgow-exts"
+    "-fhelpful-errors"
+    "-fhistory-size"
+    "-fhpc"
+    "-fhpc-no-auto"
+    "-fignore-asserts"
+    "-fignore-interface-pragmas"
+    "-fimplicit-params"
+    "-fimplicit-prelude"
+    "-firrefutable-tuples"
+    "-fkill-absence"
+    "-fkill-one-shot"
+    "-flate-dmd-anal"
+    "-fliberate-case"
+    "-fliberate-case-threshold"
+    "-fllvm"
+    "-floopification"
+    "-fmax-inline-alloc-size"
+    "-fmax-inline-memcpy-insns"
+    "-fmax-inline-memset-insns"
+    "-fmax-pmcheck-iterations"
+    "-fmax-relevant-binds"
+    "-fmax-simplifier-iterations"
+    "-fmax-worker-args"
+    "-fmono-pat-binds"
+    "-fmonomorphism-restriction"
+    "-fno-PArr"
+    "-fno-PIC"
+    "-fno-allow-incoherent-instances"
+    "-fno-allow-overlapping-instances"
+    "-fno-allow-undecidable-instances"
+    "-fno-arrows"
+    "-fno-bang-patterns"
+    "-fno-building-cabal-package"
+    "-fno-call-arity"
+    "-fno-case-merge"
+    "-fno-cmm-elim-common-blocks"
+    "-fno-cmm-sink"
+    "-fno-code"
+    "-fno-cpr-anal"
+    "-fno-cross-module-specialise"
+    "-fno-cse"
+    "-fno-defer-type-errors"
+    "-fno-defer-typed-holes"
+    "-fno-dicts-cheap"
+    "-fno-dicts-strict"
+    "-fno-dmd-tx-dict-sel"
+    "-fno-do-eta-reduction"
+    "-fno-do-lambda-eta-expansion"
+    "-fno-eager-blackholing"
+    "-fno-embed-manifest"
+    "-fno-enable-rewrite-rules"
+    "-fno-error-spans"
+    "-fno-excess-precision"
+    "-fno-expose-all-unfoldings"
+    "-fno-ext-core"
+    "-fno-extended-default-rules"
+    "-fno-external-interpreter"
+    "-fno-ffi"
+    "-fno-fi"
+    "-fno-flat-cache"
+    "-fno-float-in"
+    "-fno-force-recomp"
+    "-fno-full-laziness"
+    "-fno-fun-to-thunk"
+    "-fno-gen-manifest"
+    "-fno-ghci-history"
+    "-fno-ghci-sandbox"
+    "-fno-glasgow-exts"
+    "-fno-helpful-errors"
+    "-fno-hpc"
+    "-fno-hpc-no-auto"
+    "-fno-ignore-asserts"
+    "-fno-ignore-interface-pragmas"
+    "-fno-implicit-params"
+    "-fno-implicit-prelude"
+    "-fno-irrefutable-tuples"
+    "-fno-kill-absence"
+    "-fno-kill-one-shot"
+    "-fno-late-dmd-anal"
+    "-fno-liberate-case"
+    "-fno-liberate-case-threshold"
+    "-fno-loopification"
+    "-fno-max-relevant-binds"
+    "-fno-mono-pat-binds"
+    "-fno-monomorphism-restriction"
+    "-fno-omit-interface-pragmas"
+    "-fno-omit-yields"
+    "-fno-opt-coercion"
+    "-fno-parr"
+    "-fno-pedantic-bottoms"
+    "-fno-pre-inlining"
+    "-fno-print-equality-relations"
+    "-fno-print-expanded-synonyms"
+    "-fno-print-explicit-coercions"
+    "-fno-print-explicit-foralls"
+    "-fno-print-explicit-kinds"
+    "-fno-print-explicit-runtime-reps"
+    "-fno-print-potential-instances"
+    "-fno-print-typechecker-elaboration"
+    "-fno-print-unicode-syntax"
+    "-fno-prof-auto"
+    "-fno-prof-cafs"
+    "-fno-prof-count-entries"
+    "-fno-regs-graph"
+    "-fno-regs-iterative"
+    "-fno-reverse-errors"
+    "-fno-rewrite-rules"
+    "-fno-safe-infer"
+    "-fno-scoped-type-variables"
+    "-fno-shared-implib"
+    "-fno-show-warning-groups"
+    "-fno-simple-list-literals"
+    "-fno-spec-constr"
+    "-fno-spec-constr-count"
+    "-fno-spec-constr-threshold"
+    "-fno-specialise"
+    "-fno-specialise-aggressively"
+    "-fno-state-hack"
+    "-fno-static-argument-transformation"
+    "-fno-strictness"
+    "-fno-th"
+    "-fno-unbox-small-strict-fields"
+    "-fno-unbox-strict-fields"
+    "-fno-use-rpaths"
+    "-fno-vectorisation-avoidance"
+    "-fno-vectorise"
+    "-fno-version-macros"
+    "-fno-warn-"
+    "-fno-warn-alternative-layout-rule-transitional"
+    "-fno-warn-amp"
+    "-fno-warn-auto-orphans"
+    "-fno-warn-context-quantification"
+    "-fno-warn-deprecated-flags"
+    "-fno-warn-deprecations"
+    "-fno-warn-deriving-typeable"
+    "-fno-warn-dodgy-exports"
+    "-fno-warn-dodgy-foreign-imports"
+    "-fno-warn-dodgy-imports"
+    "-fno-warn-duplicate-constraints"
+    "-fno-warn-duplicate-exports"
+    "-fno-warn-empty-enumerations"
+    "-fno-warn-hi-shadowing"
+    "-fno-warn-identities"
+    "-fno-warn-implicit-prelude"
+    "-fno-warn-incomplete-patterns"
+    "-fno-warn-incomplete-record-updates"
+    "-fno-warn-incomplete-uni-patterns"
+    "-fno-warn-inline-rule-shadowing"
+    "-fno-warn-missing-exported-sigs"
+    "-fno-warn-missing-fields"
+    "-fno-warn-missing-import-lists"
+    "-fno-warn-missing-local-sigs"
+    "-fno-warn-missing-methods"
+    "-fno-warn-missing-signatures"
+    "-fno-warn-monomorphism-restriction"
+    "-fno-warn-name-shadowing"
+    "-fno-warn-orphans"
+    "-fno-warn-overflowed-literals"
+    "-fno-warn-overlapping-patterns"
+    "-fno-warn-partial-type-signatures"
+    "-fno-warn-pointless-pragmas"
+    "-fno-warn-safe"
+    "-fno-warn-tabs"
+    "-fno-warn-trustworthy-safe"
+    "-fno-warn-type-defaults"
+    "-fno-warn-typed-holes"
+    "-fno-warn-unrecognised-pragmas"
+    "-fno-warn-unsafe"
+    "-fno-warn-unsupported-calling-conventions"
+    "-fno-warn-unsupported-llvm-version"
+    "-fno-warn-unticked-promoted-constructors"
+    "-fno-warn-unused-binds"
+    "-fno-warn-unused-do-bind"
+    "-fno-warn-unused-imports"
+    "-fno-warn-unused-matches"
+    "-fno-warn-warnings-deprecations"
+    "-fno-warn-wrong-do-bind"
+    "-fno-worker-wrapper"
+    "-fno-write-interface"
+    "-fobject-code"
+    "-fomit-interface-pragmas"
+    "-fomit-yields"
+    "-fpackage-trust"
+    "-fparr"
+    "-fpedantic-bottoms"
+    "-fplugin"
+    "-fplugin-opt"
+    "-fpre-inlining"
+    "-fprint-equality-relations"
+    "-fprint-expanded-synonyms"
+    "-fprint-explicit-coercions"
+    "-fprint-explicit-foralls"
+    "-fprint-explicit-kinds"
+    "-fprint-explicit-runtime-reps"
+    "-fprint-potential-instances"
+    "-fprint-typechecker-elaboration"
+    "-fprint-unicode-syntax"
+    "-fprof-auto"
+    "-fprof-auto-calls"
+    "-fprof-auto-exported"
+    "-fprof-auto-top"
+    "-fprof-cafs"
+    "-fprof-count-entries"
+    "-framework"
+    "-framework-path"
+    "-freduction-depth"
+    "-fregs-graph"
+    "-fregs-iterative"
+    "-freverse-errors"
+    "-frewrite-rules"
+    "-frule-check"
+    "-fscoped-type-variables"
+    "-fshared-implib"
+    "-fshow-warning-groups"
+    "-fsimpl-tick-factor"
+    "-fsimple-list-literals"
+    "-fsimplifier-phases"
+    "-fspec-constr"
+    "-fspec-constr-count"
+    "-fspec-constr-recursive"
+    "-fspec-constr-threshold"
+    "-fspecialise"
+    "-fspecialise-aggressively"
+    "-fstatic-argument-transformation"
+    "-fstrictness"
+    "-fstrictness-before"
+    "-fth"
+    "-ftype-function-depth"
+    "-funbox-small-strict-fields"
+    "-funbox-strict-fields"
+    "-funfolding-creation-threshold"
+    "-funfolding-dict-discount"
+    "-funfolding-fun-discount"
+    "-funfolding-keeness-factor"
+    "-funfolding-use-threshold"
+    "-fuse-rpaths"
+    "-fvectorisation-avoidance"
+    "-fvectorise"
+    "-fversion-macros"
+    "-fvia-C"
+    "-fvia-c"
+    "-fwarn-"
+    "-fwarn-alternative-layout-rule-transitional"
+    "-fwarn-amp"
+    "-fwarn-auto-orphans"
+    "-fwarn-context-quantification"
+    "-fwarn-deprecated-flags"
+    "-fwarn-deprecations"
+    "-fwarn-deriving-typeable"
+    "-fwarn-dodgy-exports"
+    "-fwarn-dodgy-foreign-imports"
+    "-fwarn-dodgy-imports"
+    "-fwarn-duplicate-constraints"
+    "-fwarn-duplicate-exports"
+    "-fwarn-empty-enumerations"
+    "-fwarn-hi-shadowing"
+    "-fwarn-identities"
+    "-fwarn-implicit-prelude"
+    "-fwarn-incomplete-patterns"
+    "-fwarn-incomplete-record-updates"
+    "-fwarn-incomplete-uni-patterns"
+    "-fwarn-inline-rule-shadowing"
+    "-fwarn-missing-exported-sigs"
+    "-fwarn-missing-fields"
+    "-fwarn-missing-import-lists"
+    "-fwarn-missing-local-sigs"
+    "-fwarn-missing-methods"
+    "-fwarn-missing-signatures"
+    "-fwarn-monomorphism-restriction"
+    "-fwarn-name-shadowing"
+    "-fwarn-orphans"
+    "-fwarn-overflowed-literals"
+    "-fwarn-overlapping-patterns"
+    "-fwarn-partial-type-signatures"
+    "-fwarn-pointless-pragmas"
+    "-fwarn-safe"
+    "-fwarn-tabs"
+    "-fwarn-trustworthy-safe"
+    "-fwarn-type-defaults"
+    "-fwarn-typed-holes"
+    "-fwarn-unrecognised-pragmas"
+    "-fwarn-unsafe"
+    "-fwarn-unsupported-calling-conventions"
+    "-fwarn-unsupported-llvm-version"
+    "-fwarn-unticked-promoted-constructors"
+    "-fwarn-unused-binds"
+    "-fwarn-unused-do-bind"
+    "-fwarn-unused-imports"
+    "-fwarn-unused-matches"
+    "-fwarn-warnings-deprecations"
+    "-fwarn-wrong-do-bind"
+    "-fworker-wrapper"
+    "-fwrite-interface"
+    "-g"
+    "-global-package-db"
+    "-gransim"
+    "-haddock"
+    "-haddock-opts"
+    "-hcsuf"
+    "-hide-all-packages"
+    "-hide-all-plugin-packages"
+    "-hide-package"
+    "-hidir"
+    "-hisuf"
+    "-hpcdir"
+    "-i"
+    "-ignore-package"
+    "-include-pkg-deps"
+    "-j"
+    "-keep-hc-file"
+    "-keep-hc-files"
+    "-keep-llvm-file"
+    "-keep-llvm-files"
+    "-keep-s-file"
+    "-keep-s-files"
+    "-keep-tmp-files"
+    "-l"
+    "-main-is"
+    "-mavx"
+    "-mavx2"
+    "-mavx512cd"
+    "-mavx512er"
+    "-mavx512f"
+    "-mavx512pf"
+    "-msse"
+    "-msse2"
+    "-msse3"
+    "-msse4"
+    "-msse4.2"
+    "-n"
+    "-ndp"
+    "-no-auto"
+    "-no-auto-all"
+    "-no-auto-link-packages"
+    "-no-caf-all"
+    "-no-global-package-db"
+    "-no-hs-main"
+    "-no-link"
+    "-no-recomp"
+    "-no-rtsopts"
+    "-no-rtsopts-suggestions"
+    "-no-user-package-conf"
+    "-no-user-package-db"
+    "-o"
+    "-odir"
+    "-ohi"
+    "-optF"
+    "-optL"
+    "-optP"
+    "-opta"
+    "-optc"
+    "-opti"
+    "-optl"
+    "-optlc"
+    "-optlo"
+    "-optwindres"
+    "-osuf"
+    "-outputdir"
+    "-package"
+    "-package-conf"
+    "-package-db"
+    "-package-env"
+    "-package-id"
+    "-package-key"
+    "-package-name"
+    "-parallel"
+    "-pgmF"
+    "-pgmL"
+    "-pgmP"
+    "-pgma"
+    "-pgmc"
+    "-pgmdll"
+    "-pgmi"
+    "-pgml"
+    "-pgmlc"
+    "-pgmlibtool"
+    "-pgmlo"
+    "-pgms"
+    "-pgmwindres"
+    "-plugin-package"
+    "-plugin-package-id"
+    "-prof"
+    "-rdynamic"
+    "-recomp"
+    "-relative-dynlib-paths"
+    "-rtsopts"
+    "-rtsopts=all"
+    "-rtsopts=none"
+    "-rtsopts=some"
+    "-shared"
+    "-sig-of"
+    "-smp"
+    "-split-objs"
+    "-split-sections"
+    "-static"
+    "-staticlib"
+    "-stubdir"
+    "-syslib"
+    "-this-package-key"
+    "-this-unit-id"
+    "-threaded"
+    "-ticky"
+    "-ticky-LNE"
+    "-ticky-allocd"
+    "-ticky-dyn-thunk"
+    "-tmpdir"
+    "-trust"
+    "-user-package-db"
+    "-v"
+    "-w"
+    "-with-rtsopts"
+    ;;; END haskell-ghc-supported-options
+    )
+  "List of options supported by any known version of GHC.
+
+This list should be updated by running `haskell-update-ghc-support'.")
+
+
+(defun haskell-update-ghc-support (ghc-path)
+  "Update `haskell-ghc-supported-options' and `haskell-ghc-supported-extensions'.
+
+This command should be run once a GHC is released. It will use
+--show-options and --supported-extensions to source the
+information from GHC-PATH. Then it will update source code to
+include newly found options. Old options are never removed and
+are retained to support old versions of the compiler.
+
+Options and extension are kept in ascending order."
+  (interactive
+   (list
+    (read-shell-command "GHC command: " nil nil
+                        (let ((filename
+                               (cond
+                                (buffer-file-name)
+                                ((eq major-mode 'dired-mode)
+                                 (when (fboundp 'dired-get-filename)
+                                   ;; silence the checker
+                                   (dired-get-filename nil t))))))
+                          (and filename (file-relative-name filename))))))
+
+
+  (let ((extentions (split-string (shell-command-to-string (concat ghc-path " --supported-extensions"))))
+        (options (split-string (shell-command-to-string (concat ghc-path " --show-options")))))
+    (with-current-buffer
+        (find-file-noselect (replace-regexp-in-string "\\.elc$" ".el" (symbol-file 'haskell-ghc-supported-options)))
+      (save-excursion
+        (goto-char (point-min))
+        (re-search-forward "BEGIN haskell-ghc-supported-extensions")
+        (forward-line 1)
+        (let ((point (point)))
+          (re-search-forward "END haskell-ghc-supported-extensions")
+          (goto-char (line-beginning-position))
+          (delete-region point (point)))
+        (setq haskell-ghc-supported-extensions
+              (delete-dups (sort (append extentions haskell-ghc-supported-extensions) #'string<)))
+        (dolist (item haskell-ghc-supported-extensions)
+          (insert "    \"" item "\"\n"))
+        (re-search-forward "BEGIN haskell-ghc-supported-options")
+        (forward-line 1)
+        (let ((point (point)))
+          (re-search-forward "END haskell-ghc-supported-options")
+          (goto-char (line-beginning-position))
+          (delete-region point (point)))
+        (setq haskell-ghc-supported-options
+              (delete-dups (sort (append options haskell-ghc-supported-options) #'string<)))
+        (dolist (item haskell-ghc-supported-options)
+          (insert "    \"" item "\"\n"))))))
+
+(provide 'haskell-ghc-support)
diff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-ghc-support.elc b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-ghc-support.elc
new file mode 100644
index 0000000000..1fde197f64
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-ghc-support.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-hoogle.el b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-hoogle.el
new file mode 100644
index 0000000000..62aaaaad7a
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-hoogle.el
@@ -0,0 +1,151 @@
+;;; haskell-hoogle.el --- Look up Haskell documentation via hoogle or hayoo  -*- lexical-binding: t; -*-
+
+;; Copyright © 2015 Steve Purcell
+;;             2016 Arthur Fayzrakhmanov
+
+;; Author: Steve Purcell <steve@sanityinc.com>
+;; Keywords: docs
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Functions for looking up documentation with hayoo or hoogle, via
+;; either local or remote servers.
+
+;;; Code:
+
+(require 'ansi-color)
+(require 'haskell-mode)
+(require 'haskell-utils)
+
+
+(defcustom haskell-hoogle-command
+  (if (executable-find "hoogle") "hoogle")
+  "Name of the command to use to query Hoogle.
+If nil, use the Hoogle web-site."
+  :group 'haskell
+  :type '(choice (const :tag "Use Web-site" nil)
+                 string))
+
+(defcustom haskell-hoogle-url "http://haskell.org/hoogle/?q=%s"
+  "Default value for hoogle web site."
+  :group 'haskell
+  :type '(choice
+          (const :tag "haskell-org" "http://haskell.org/hoogle/?q=%s")
+          (const :tag "fp-complete" "https://www.stackage.org/lts/hoogle?q=%s")
+          (const :tag "hayoo" "http://hayoo.fh-wedel.de/?query=%s")
+          string))
+
+;;;###autoload
+(defun haskell-hoogle (query &optional info)
+  "Do a Hoogle search for QUERY.
+When `haskell-hoogle-command' is non-nil, this command runs
+that.  Otherwise, it opens a hoogle search result in the browser.
+
+If prefix argument INFO is given, then `haskell-hoogle-command'
+is asked to show extra info for the items matching QUERY.."
+  (interactive
+   (let ((def (haskell-ident-at-point)))
+     (if (and def (symbolp def)) (setq def (symbol-name def)))
+     (list (read-string (if def
+                            (format "Hoogle query (default %s): " def)
+                          "Hoogle query: ")
+                        nil nil def)
+           current-prefix-arg)))
+  (if (null haskell-hoogle-command)
+      (browse-url (format haskell-hoogle-url (url-hexify-string query)))
+    (let ((command (concat haskell-hoogle-command
+                           (if info " -i " "")
+                           " --color " (shell-quote-argument query))))
+      (with-help-window "*hoogle*"
+        (with-current-buffer standard-output
+          (insert (shell-command-to-string command))
+          (ansi-color-apply-on-region (point-min) (point-max)))))))
+
+;;;###autoload
+(defalias 'hoogle 'haskell-hoogle)
+
+(defvar haskell-hoogle-server-process-name "emacs-local-hoogle")
+(defvar haskell-hoogle-server-buffer-name (format "*%s*" haskell-hoogle-server-process-name))
+(defvar haskell-hoogle-port-number 49513 "Port number.")
+(defvar haskell-hoogle-server-process nil "The process handle of the local hoogle server.")
+
+(defun haskell-hoogle-start-server ()
+  "Start hoogle local server."
+  (interactive)
+  (if (executable-find "hoogle")
+      (unless (haskell-hoogle-server-live-p)
+        (set 'haskell-hoogle-server-process
+             (start-process
+              haskell-hoogle-server-process-name
+              (get-buffer-create haskell-hoogle-server-buffer-name)
+              "hoogle" "server" "-p" (number-to-string haskell-hoogle-port-number))))
+    (error "\"hoogle\" executable not found")))
+
+(defun haskell-hoogle-server-live-p ()
+  "Whether the hoogle server process is live."
+  (condition-case _err
+      (process-live-p haskell-hoogle-server-process)
+    (error nil)))
+
+(defun haskell-hoogle-kill-server ()
+  "Kill the hoogle server if it is live."
+  (interactive)
+  (when (haskell-hoogle-server-live-p)
+    (kill-process (get-buffer-create haskell-hoogle-server-buffer-name))
+    (set 'haskell-hoogle-server-process nil)))
+
+;;;###autoload
+(defun haskell-hoogle-lookup-from-local ()
+  "Lookup by local hoogle."
+  (interactive)
+  (if (haskell-hoogle-server-live-p)
+      (browse-url (format "http://localhost:%i/?hoogle=%s"
+                          haskell-hoogle-port-number
+                          (read-string "hoogle: " (haskell-ident-at-point))))
+    (haskell-mode-toggle-interactive-prompt-state)
+    (unwind-protect
+        (when (y-or-n-p "Hoogle server not running, start hoogle server? ")
+          (haskell-hoogle-start-server))
+      (haskell-mode-toggle-interactive-prompt-state t))))
+
+
+(defcustom haskell-hayoo-url "http://hayoo.fh-wedel.de/?query=%s"
+  "Default value for hayoo web site."
+  :group 'haskell
+  :type '(choice
+          (const :tag "fh-wedel.de" "http://hayoo.fh-wedel.de/?query=%s")
+          string))
+
+;;;###autoload
+(defun haskell-hayoo (query)
+  "Do a Hayoo search for QUERY."
+  (interactive
+   (let ((def (haskell-ident-at-point)))
+     (if (and def (symbolp def)) (setq def (symbol-name def)))
+     (list (read-string (if def
+                            (format "Hayoo query (default %s): " def)
+                          "Hayoo query: ")
+                        nil nil def))))
+  (browse-url (format haskell-hayoo-url (url-hexify-string query))))
+
+;;;###autoload
+(defalias 'hayoo 'haskell-hayoo)
+
+
+
+
+(provide 'haskell-hoogle)
+;;; haskell-hoogle.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-hoogle.elc b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-hoogle.elc
new file mode 100644
index 0000000000..93ab3fc36c
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-hoogle.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-indent.el b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-indent.el
new file mode 100644
index 0000000000..afa558503b
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-indent.el
@@ -0,0 +1,1596 @@
+;;; haskell-indent.el --- "semi-intelligent" indentation module for Haskell Mode -*- lexical-binding: t -*-
+
+;; Copyright 2004, 2005, 2007, 2008, 2009  Free Software Foundation, Inc.
+;; Copyright 1997-1998  Guy Lapalme
+
+;; Author: 1997-1998 Guy Lapalme <lapalme@iro.umontreal.ca>
+
+;; Keywords: indentation Haskell layout-rule
+;; URL: http://www.iro.umontreal.ca/~lapalme/layout/index.html
+
+;; This file is not part of GNU Emacs.
+
+;; This file 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, or (at your option)
+;; any later version.
+
+;; This file 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Purpose:
+;;
+;; To support automatic indentation of Haskell programs using
+;; the layout rule described in section 1.5 and appendix B.3 of the
+;; the Haskell report.  The rationale and the implementation principles
+;; are described in an article to appear in Journal of Functional Programming.
+;;   "Dynamic tabbing for automatic indentation with the layout rule"
+;;
+;; It supports literate scripts.
+;; Haskell indentation is performed
+;;     within \begin{code}...\end{code} sections of a literate script
+;;     and in lines beginning with > with Bird style literate script
+;; TAB aligns to the left column outside of these sections.
+;;
+;; Installation:
+;;
+;; To turn indentation on for all Haskell buffers under the Haskell
+;; mode of Moss&Thorn <http://www.haskell.org/haskell-mode/>
+;; add this to .emacs:
+;;
+;;    (add-hook 'haskell-mode-hook 'turn-on-haskell-indent)
+;;
+;; Otherwise, call `turn-on-haskell-indent'.
+;;
+;;
+;; Customisation:
+;;       The "standard" offset for statements is 4 spaces.
+;;       It can be changed by setting the variable "haskell-indent-offset" to
+;;       another value
+;;
+;;       The default number of blanks after > in a Bird style literate script
+;;       is 1; it can be changed by setting the variable
+;;       "haskell-indent-literate-Bird-default-offset"
+;;
+;;       `haskell-indent-hook' is invoked if not nil.
+;;
+;; All functions/variables start with
+;; `(turn-(on/off)-)haskell-indent' or `haskell-indent-'.
+
+;; This file can also be used as a hook for the Hugs Mode developed by
+;;         Chris Van Humbeeck <chris.vanhumbeeck@cs.kuleuven.ac.be>
+;; It can be obtained at:
+;; http://www-i2.informatik.rwth-aachen.de/Forschung/FP/Haskell/hugs-mode.el
+;;
+;; For the Hugs mode put the following in your .emacs
+;;
+;;(setq auto-mode-alist (append auto-mode-alist '(("\\.hs\\'" . hugs-mode))))
+;;(autoload 'hugs-mode "hugs-mode" "Go into hugs mode" t)
+;;
+;; If only the indentation mode is used then replace the two
+;; preceding lines with
+;;(setq auto-mode-alist (append auto-mode-alist
+;;                              '(("\\.hs\\'" . turn-on-haskell-indent))))
+;;(autoload 'turn-on-haskell-indent "hindent" "Indentation mode for Haskell" t)
+;;
+;; For indentation in both cases then add the following to your .emacs
+;;(add-hook 'hugs-mode-hook 'turn-on-haskell-indent)
+;;(autoload 'haskell-indent-cycle "hindent" "Indentation cycle for Haskell" t)
+;;
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'haskell-string)
+
+(defvar haskell-literate)
+
+;;;###autoload
+(defgroup haskell-indent nil
+  "Haskell indentation."
+  :group 'haskell
+  :link '(custom-manual "(haskell-mode)Indentation")
+  :prefix "haskell-indent-")
+
+(defcustom haskell-indent-offset 4
+  "Indentation of Haskell statements with respect to containing block."
+  :type 'integer
+  :safe #'natnump
+  :group 'haskell-indent)
+
+(defcustom haskell-indent-literate-Bird-default-offset 1
+  "Default number of blanks after > in a Bird style literate script."
+  :type 'integer
+  :safe #'natnump
+  :group 'haskell-indent)
+
+(defcustom haskell-indent-rhs-align-column 0
+  "Column on which to align right-hand sides (use 0 for ad-hoc alignment)."
+  :type 'integer
+  :safe #'natnump
+  :group 'haskell-indent)
+
+(defun haskell-indent-point-to-col (apoint)
+  "Return the column number of APOINT."
+  (save-excursion
+    (goto-char apoint)
+    (current-column)))
+
+(defconst haskell-indent-start-keywords-re
+  (concat "\\<"
+          (regexp-opt '("class" "data" "import" "infix" "infixl" "infixr"
+                        "instance" "module" "newtype" "primitive" "signature" "type") t)
+          "\\>")
+  "Regexp for keywords to complete when standing at the first word of a line.")
+
+
+;; Customizations for different kinds of environments
+;; in which dealing with low-level events are different.
+(defun haskell-indent-mark-active ()
+  (if (featurep 'xemacs)
+      (if zmacs-regions
+          zmacs-region-active-p
+        t)
+    mark-active))
+
+;;  for pushing indentation information
+
+(defvar haskell-indent-info)            ;Used with dynamic scoping.
+
+(defun haskell-indent-push-col (col &optional name)
+  "Push indentation information for the column COL.
+The info is followed by NAME (if present).
+Makes sure that the same indentation info is not pushed twice.
+Uses free var `haskell-indent-info'."
+  (let ((tmp (cons col name)))
+    (if (member tmp haskell-indent-info)
+        haskell-indent-info
+      (push tmp haskell-indent-info))))
+
+(defun haskell-indent-push-pos (pos &optional name)
+  "Push indentation information for POS followed by NAME (if present)."
+  (haskell-indent-push-col (haskell-indent-point-to-col pos) name))
+
+;; (defvar haskell-indent-tab-align nil
+;;   "Align all indentations on TAB stops.")
+
+(defun haskell-indent-column+offset (column offset)
+  (unless offset (setq offset haskell-indent-offset))
+  (setq column (+ column offset))
+  ;; (if (and haskell-indent-tab-align (> offset 0))
+  ;;     (* 8 (/ (+ column 7) 8))
+  column) ;; )
+
+(defun haskell-indent-push-pos-offset (pos &optional offset)
+  "Pushes indentation information for the column corresponding to POS
+followed by an OFFSET (if present use its value otherwise use
+`haskell-indent-offset')."
+  (haskell-indent-push-col (haskell-indent-column+offset
+                            (haskell-indent-point-to-col pos)
+                            offset)))
+
+;; redefinition of some Emacs function for dealing with
+;; Bird Style literate scripts
+
+(defun haskell-indent-bolp ()
+  "`bolp' but dealing with Bird-style literate scripts."
+  (or (bolp)
+      (and (eq haskell-literate 'bird)
+           (<= (current-column) (1+ haskell-indent-literate-Bird-default-offset))
+           (eq (char-after (line-beginning-position)) ?\>))))
+
+(defun haskell-indent-empty-line-p ()
+  "Checks if the current line is empty; deals with Bird style scripts."
+  (save-excursion
+    (beginning-of-line)
+    (if (and (eq haskell-literate 'bird)
+             (eq (following-char) ?\>))
+        (forward-char 1))
+    (looking-at "[ \t]*$")))
+
+(defun haskell-indent-back-to-indentation ()
+  "`back-to-indentation' function but dealing with Bird-style literate scripts."
+  (if (and (eq haskell-literate 'bird)
+           (progn (beginning-of-line) (eq (following-char) ?\>)))
+      (progn
+        (forward-char 1)
+        (skip-chars-forward " \t"))
+    (back-to-indentation)))
+
+(defun haskell-indent-current-indentation ()
+  "`current-indentation' function dealing with Bird-style literate scripts."
+  (if (eq haskell-literate 'bird)
+      (save-excursion
+        (haskell-indent-back-to-indentation)
+        (current-column))
+    (current-indentation)))
+
+(defun haskell-indent-backward-to-indentation (n)
+  "`backward-to-indentation' function dealing with Bird-style literate scripts."
+  (if (eq haskell-literate 'bird)
+      (progn
+        (forward-line (- n))
+        (haskell-indent-back-to-indentation))
+    (backward-to-indentation n)))
+
+(defun haskell-indent-forward-line (&optional n)
+  "`forward-line' function but dealing with Bird-style literate scripts."
+  (prog1
+      (forward-line n)
+    (if (and (eq haskell-literate 'bird) (eq (following-char) ?\>))
+        (progn (forward-char 1)                ; skip > and initial blanks...
+               (skip-chars-forward " \t")))))
+
+(defun haskell-indent-line-to (n)
+  "`indent-line-to' function but dealing with Bird-style literate scripts."
+  (if (eq haskell-literate 'bird)
+      (progn
+        (beginning-of-line)
+        (if (eq (following-char) ?\>)
+            (delete-char 1))
+        (delete-horizontal-space)       ; remove any starting TABs so
+        (indent-line-to n)              ; that indent-line only adds spaces
+        (save-excursion
+          (beginning-of-line)
+          (if (> n 0) (delete-char 1))  ; delete the first space before
+          (insert ?\>)))                ; inserting a >
+    (indent-line-to n)))
+
+(defun haskell-indent-skip-blanks-and-newlines-forward (end)
+  "Skip forward blanks, tabs and newlines until END.
+Take account of Bird-style literate scripts."
+  (skip-chars-forward " \t\n" end)
+  (if (eq haskell-literate 'bird)
+      (while (and (bolp) (eq (following-char) ?\>))
+        (forward-char 1)                ; skip >
+        (skip-chars-forward " \t\n" end))))
+
+(defun haskell-indent-skip-blanks-and-newlines-backward (start)
+  "Skip backward blanks, tabs and newlines up to START.
+Take account of Bird-style literate scripts."
+  (skip-chars-backward " \t\n" start)
+  (if (eq haskell-literate 'bird)
+      (while (and (eq (current-column) 1)
+                  (eq (preceding-char) ?\>))
+        (forward-char -1)               ; skip back >
+        (skip-chars-backward " \t\n" start))))
+
+;; specific functions for literate code
+
+(defun haskell-indent-within-literate-code ()
+  "Check if point is within a part of literate Haskell code.
+If so, return its start; otherwise return nil:
+If it is Bird-style, then return the position of the >;
+otherwise return the ending position of \\begin{code}."
+  (save-excursion
+    (cl-case haskell-literate
+      (bird
+       (beginning-of-line)
+       (if (or (eq (following-char) ?\>)
+               (and (bolp) (forward-line -1) (eq (following-char) ?\>)))
+           (progn
+             (while (and (zerop (forward-line -1))
+                         (eq (following-char) ?\>)))
+             (if (not (eq (following-char) ?\>))
+                 (forward-line))
+             (point))))
+      ;;  Look for a \begin{code} or \end{code} line.
+      ((latex tex)
+       (if (re-search-backward
+            "^\\(\\\\begin{code}$\\)\\|\\(\\\\end{code}$\\)" nil t)
+           ;; within a literate code part if it was a \\begin{code}.
+           (match-end 1)))
+      (t (error "haskell-indent-within-literate-code: should not happen!")))))
+
+(defun haskell-indent-put-region-in-literate (beg end &optional arg)
+  "Put lines of the region as a piece of literate code.
+With prefix arg, remove indication that the region is literate code.
+It deals with both Bird style and non Bird-style scripts."
+  (interactive "r\nP")
+  (unless haskell-literate
+    (error "Cannot put a region in literate in a non literate script"))
+  (if (eq haskell-literate 'bird)
+      (let ((comment-start "> ")        ; Change dynamic bindings for
+            (comment-start-skip "^> ?") ; comment-region.
+            (comment-end "")
+            (comment-end-skip "\n")
+            (comment-style 'plain))
+        (comment-region beg end arg))
+    ;; Not Bird style.
+    (if arg                             ; Remove the literate indication.
+        (save-excursion
+          (goto-char end)               ; Remove end.
+          (if (re-search-backward "^\\\\end{code}[ \t\n]*\\="
+                                  (line-beginning-position -2) t)
+              (delete-region (point) (line-beginning-position 2)))
+          (goto-char beg)               ; Remove end.
+          (beginning-of-line)
+          (if (looking-at "\\\\begin{code}")
+              (kill-line 1)))
+      (save-excursion                   ; Add the literate indication.
+        (goto-char end)
+        (unless (bolp) (newline))
+        (insert "\\end{code}\n")
+        (goto-char beg)
+        (unless (bolp) (newline))
+        (insert "\\begin{code}\n")))))
+
+;;; Start of indentation code
+(defcustom haskell-indent-look-past-empty-line t
+  "If nil, indentation engine will not look past an empty line for layout points."
+  :group 'haskell-indent
+  :safe #'booleanp
+  :type 'boolean)
+
+(defun haskell-indent-start-of-def ()
+  "Return the position of the start of a definition.
+The start of a def is expected to be recognizable by starting in column 0,
+unless `haskell-indent-look-past-empty-line' is nil, in which case we
+take a coarser approximation and stop at the first empty line."
+  (save-excursion
+    (let ((start-code (and haskell-literate
+                           (haskell-indent-within-literate-code)))
+          (top-col (if (eq haskell-literate 'bird) 2 0))
+          (save-point (point)))
+      ;; determine the starting point of the current piece of code
+      (setq start-code (if start-code (1+ start-code) (point-min)))
+      ;; go backward until the first preceding empty line
+      (haskell-indent-forward-line -1)
+      (while (and (if haskell-indent-look-past-empty-line
+                      (or (> (haskell-indent-current-indentation) top-col)
+                          (haskell-indent-empty-line-p))
+                    (and (> (haskell-indent-current-indentation) top-col)
+                         (not (haskell-indent-empty-line-p))))
+                  (> (point) start-code)
+                  (= 0 (haskell-indent-forward-line -1))))
+      ;; go forward after the empty line
+      (if (haskell-indent-empty-line-p)
+          (haskell-indent-forward-line 1))
+      (setq start-code (point))
+      ;; find the first line of code which is not a comment
+      (forward-comment (point-max))
+      (if (> (point) save-point)
+          start-code
+        (point)))))
+
+(defun haskell-indent-open-structure (start end)
+  "If any structure (list or tuple) is not closed, between START and END,
+returns the location of the opening symbol, nil otherwise."
+  (save-excursion
+    (nth 1 (parse-partial-sexp start end))))
+
+(defun haskell-indent-in-string (start end)
+  "If a string is not closed , between START and END, returns the
+location of the opening symbol, nil otherwise."
+  (save-excursion
+    (let ((pps (parse-partial-sexp start end)))
+      (if (nth 3 pps) (nth 8 pps)))))
+
+(defun haskell-indent-in-comment (start end)
+  "Check, starting from START, if END is at or within a comment.
+Returns the location of the start of the comment, nil otherwise."
+  (let (pps)
+    (cl-assert (<= start end))
+    (cond ((= start end) nil)
+          ((nth 4 (save-excursion (setq pps (parse-partial-sexp start end))))
+           (nth 8 pps))
+          ;; We also want to say that we are *at* the beginning of a comment.
+          ((and (not (nth 8 pps))
+                (>= (point-max) (+ end 2))
+                (nth 4 (save-excursion
+                         (setq pps (parse-partial-sexp end (+ end 2))))))
+           (nth 8 pps)))))
+
+(defvar haskell-indent-off-side-keywords-re
+  "\\<\\(do\\|let\\|of\\|where\\|mdo\\|rec\\)\\>[ \t]*")
+
+(defun haskell-indent-type-at-point ()
+  "Return the type of the line (also puts information in `match-data')."
+  (cond
+   ((haskell-indent-empty-line-p) 'empty)
+   ((haskell-indent-in-comment (point-min) (point)) 'comment)
+   ((looking-at "\\(\\([[:alpha:]]\\(\\sw\\|'\\)*\\)\\|_\\)[ \t\n]*")
+    'ident)
+   ((looking-at "\\(|[^|]\\)[ \t\n]*") 'guard)
+   ((looking-at "\\(=[^>=]\\|::\\|∷\\|→\\|←\\|->\\|<-\\)[ \t\n]*") 'rhs)
+   (t 'other)))
+
+(defvar haskell-indent-current-line-first-ident ""
+  "Global variable that keeps track of the first ident of the line to indent.")
+
+
+(defun haskell-indent-contour-line (start end)
+  "Generate contour information between START and END points."
+  (if (< start end)
+      (save-excursion
+        (goto-char end)
+        (haskell-indent-skip-blanks-and-newlines-backward start)
+        (let ((cur-col (current-column)) ; maximum column number
+              (fl 0) ; number of lines that forward-line could not advance
+              contour)
+          (while (and (> cur-col 0) (= fl 0) (>= (point) start))
+            (haskell-indent-back-to-indentation)
+            (if (< (point) start) (goto-char start))
+            (and (not (member (haskell-indent-type-at-point)
+                              '(empty comment))) ; skip empty and comment lines
+                 (< (current-column) cur-col) ; less indented column found
+                 (push (point) contour) ; new contour point found
+                 (setq cur-col (current-column)))
+            (setq fl (haskell-indent-forward-line -1)))
+          contour))))
+
+(defun haskell-indent-next-symbol (end)
+  "Move point to the next symbol."
+  (skip-syntax-forward ")" end)
+  (if (< (point) end)
+      (progn
+        (forward-sexp 1)
+        (haskell-indent-skip-blanks-and-newlines-forward end))))
+
+(defun haskell-indent-next-symbol-safe (end)
+  "Puts point to the next following symbol, or to end if there are no more symbols in the sexp."
+  (condition-case _errlist (haskell-indent-next-symbol end)
+    (error (goto-char end))))
+
+(defun haskell-indent-separate-valdef (start end)
+  "Return a list of positions for important parts of a valdef."
+  (save-excursion
+    (let (valname valname-string aft-valname
+                  guard aft-guard
+                  rhs-sign aft-rhs-sign
+                  type)
+      ;; "parse" a valdef separating important parts
+      (goto-char start)
+      (setq type (haskell-indent-type-at-point))
+      (if (or (memq type '(ident other))) ; possible start of a value def
+          (progn
+            (if (eq type 'ident)
+                (progn
+                  (setq valname (match-beginning 0))
+                  (setq valname-string (match-string 0))
+                  (goto-char (match-end 0)))
+              (skip-chars-forward " \t" end)
+              (setq valname (point))    ; type = other
+              (haskell-indent-next-symbol-safe end))
+            (while (and (< (point) end)
+                        (setq type (haskell-indent-type-at-point))
+                        (or (memq type '(ident other))))
+              (if (null aft-valname)
+                  (setq aft-valname (point)))
+              (haskell-indent-next-symbol-safe end))))
+      (if (and (< (point) end) (eq type 'guard)) ; start of a guard
+          (progn
+            (setq guard (match-beginning 0))
+            (goto-char (match-end 0))
+            (while (and (< (point) end)
+                        (setq type (haskell-indent-type-at-point))
+                        (not (eq type 'rhs)))
+              (if (null aft-guard)
+                  (setq aft-guard (point)))
+              (haskell-indent-next-symbol-safe end))))
+      (if (and (< (point) end) (eq type 'rhs)) ; start of a rhs
+          (progn
+            (setq rhs-sign (match-beginning 0))
+            (goto-char (match-end 0))
+            (if (< (point) end)
+                (setq aft-rhs-sign (point)))))
+      (list valname valname-string aft-valname
+            guard aft-guard rhs-sign aft-rhs-sign))))
+
+(defsubst haskell-indent-no-otherwise (guard)
+  "Check if there is no otherwise at GUARD."
+  (save-excursion
+    (goto-char guard)
+    (not (looking-at "|[ \t]*otherwise\\>"))))
+
+
+(defun haskell-indent-guard (start end end-visible indent-info)
+  "Find indentation information for a line starting with a guard."
+  (save-excursion
+    (let* ((haskell-indent-info indent-info)
+           (sep (haskell-indent-separate-valdef start end))
+           (valname (nth 0 sep))
+           (guard (nth 3 sep))
+           (rhs-sign (nth 5 sep)))
+      ;; push information indentation for the visible part
+      (if (and guard (< guard end-visible) (haskell-indent-no-otherwise guard))
+          (haskell-indent-push-pos guard)
+        (if rhs-sign
+            (haskell-indent-push-pos rhs-sign) ; probably within a data definition...
+          (if valname
+              (haskell-indent-push-pos-offset valname))))
+      haskell-indent-info)))
+
+(defun haskell-indent-rhs (start end end-visible indent-info)
+  "Find indentation information for a line starting with a rhs."
+  (save-excursion
+    (let* ((haskell-indent-info indent-info)
+           (sep (haskell-indent-separate-valdef start end))
+           (valname (nth 0 sep))
+           (guard (nth 3 sep))
+           (rhs-sign (nth 5 sep)))
+      ;; push information indentation for the visible part
+      (if (and rhs-sign (< rhs-sign end-visible))
+          (haskell-indent-push-pos rhs-sign)
+        (if (and guard (< guard end-visible))
+            (haskell-indent-push-pos-offset guard)
+          (if valname                   ; always visible !!
+              (haskell-indent-push-pos-offset valname))))
+      haskell-indent-info)))
+
+(defconst haskell-indent-decision-table
+  (let ((or "\\)\\|\\("))
+    (concat "\\("
+            "1.1.11" or                 ; 1= vn gd rh arh
+            "1.1.10" or                 ; 2= vn gd rh
+            "1.1100" or                 ; 3= vn gd agd
+            "1.1000" or                 ; 4= vn gd
+            "1.0011" or                 ; 5= vn rh arh
+            "1.0010" or                 ; 6= vn rh
+            "110000" or                 ; 7= vn avn
+            "100000" or                 ; 8= vn
+            "001.11" or                 ; 9= gd rh arh
+            "001.10" or                 ;10= gd rh
+            "001100" or                 ;11= gd agd
+            "001000" or                 ;12= gd
+            "000011" or                 ;13= rh arh
+            "000010" or                 ;14= rh
+            "000000"                    ;15=
+            "\\)")))
+
+(defun haskell-indent-find-case (test)
+  "Find the index that matches TEST in the decision table."
+  (if (string-match haskell-indent-decision-table test)
+      ;; use the fact that the resulting match-data is a list of the form
+      ;; (0 6 [2*(n-1) nil] 0 6) where n is the number of the matching regexp
+      ;; so n= ((length match-data)/2)-1
+      (- (/ (length (match-data 'integers)) 2) 1)
+    (error "haskell-indent-find-case: impossible case: %s" test)))
+
+(defun haskell-indent-empty (start end end-visible indent-info)
+  "Find indentation points for an empty line."
+  (save-excursion
+    (let* ((haskell-indent-info indent-info)
+           (sep (haskell-indent-separate-valdef start end))
+           (valname (pop sep))
+           (valname-string (pop sep))
+           (aft-valname (pop sep))
+           (guard (pop sep))
+           (aft-guard (pop sep))
+           (rhs-sign (pop sep))
+           (aft-rhs-sign (pop sep))
+           (last-line (= end end-visible))
+           (test (string
+                  (if valname ?1 ?0)
+                  (if (and aft-valname (< aft-valname end-visible)) ?1 ?0)
+                  (if (and guard (< guard end-visible)) ?1 ?0)
+                  (if (and aft-guard (< aft-guard end-visible)) ?1 ?0)
+                  (if (and rhs-sign (< rhs-sign end-visible)) ?1 ?0)
+                  (if (and aft-rhs-sign (< aft-rhs-sign end-visible)) ?1 ?0))))
+      (if (and valname-string           ; special case for start keywords
+               (string-match haskell-indent-start-keywords-re valname-string))
+          (progn
+            (haskell-indent-push-pos valname)
+            ;; very special for data keyword
+            (if (string-match "\\<data\\>" valname-string)
+                (if rhs-sign (haskell-indent-push-pos rhs-sign)
+                  (haskell-indent-push-pos-offset valname))
+              (haskell-indent-push-pos-offset valname)))
+        (cl-case                        ; general case
+            (haskell-indent-find-case test)
+          ;; "1.1.11"   1= vn gd rh arh
+          (1 (haskell-indent-push-pos valname)
+             (haskell-indent-push-pos valname valname-string)
+             (if (haskell-indent-no-otherwise guard) (haskell-indent-push-pos guard "| "))
+             (haskell-indent-push-pos aft-rhs-sign))
+          ;; "1.1.10"   2= vn gd rh
+          (2 (haskell-indent-push-pos valname)
+             (haskell-indent-push-pos valname valname-string)
+             (if last-line
+                 (haskell-indent-push-pos-offset guard)
+               (if (haskell-indent-no-otherwise guard) (haskell-indent-push-pos guard "| "))))
+          ;; "1.1100"   3= vn gd agd
+          (3 (haskell-indent-push-pos valname)
+             (haskell-indent-push-pos aft-guard)
+             (if last-line (haskell-indent-push-pos-offset valname)))
+          ;; "1.1000"   4= vn gd
+          (4 (haskell-indent-push-pos valname)
+             (if last-line (haskell-indent-push-pos-offset guard 2)))
+          ;; "1.0011"   5= vn rh arh
+          (5 (haskell-indent-push-pos valname)
+             (if (or (and aft-valname (= (char-after rhs-sign) ?\=))
+                     (= (char-after rhs-sign) ?\:))
+                 (haskell-indent-push-pos valname valname-string))
+             (haskell-indent-push-pos aft-rhs-sign))
+          ;; "1.0010"   6= vn rh
+          (6 (haskell-indent-push-pos valname)
+             (haskell-indent-push-pos valname valname-string)
+             (if last-line (haskell-indent-push-pos-offset valname)))
+          ;; "110000"   7= vn avn
+          (7 (haskell-indent-push-pos valname)
+             (if last-line
+                 (haskell-indent-push-pos aft-valname)
+               (haskell-indent-push-pos valname valname-string)))
+          ;; "100000"   8= vn
+          (8 (haskell-indent-push-pos valname))
+          ;; "001.11"   9= gd rh arh
+          (9 (if (haskell-indent-no-otherwise guard) (haskell-indent-push-pos guard "| "))
+             (haskell-indent-push-pos aft-rhs-sign))
+          ;; "001.10"  10= gd rh
+          (10 (if (haskell-indent-no-otherwise guard) (haskell-indent-push-pos guard "| "))
+              (if last-line (haskell-indent-push-pos-offset guard)))
+          ;; "001100"  11= gd agd
+          (11 (if (haskell-indent-no-otherwise guard) (haskell-indent-push-pos guard "| "))
+              (haskell-indent-push-pos aft-guard))
+          ;; "001000"  12= gd
+          (12 (if (haskell-indent-no-otherwise guard) (haskell-indent-push-pos guard "| "))
+              (if last-line (haskell-indent-push-pos-offset guard 2)))
+          ;; "000011"  13= rh arh
+          (13 (haskell-indent-push-pos aft-rhs-sign))
+          ;; "000010"  14= rh
+          (14 (if last-line (haskell-indent-push-pos-offset rhs-sign 2 )))
+          ;; "000000"  15=
+          (t (error "haskell-indent-empty: %s impossible case" test ))))
+      haskell-indent-info)))
+
+(defun haskell-indent-ident (start end end-visible indent-info)
+  "Find indentation points for a line starting with an identifier."
+  (save-excursion
+    (let*
+        ((haskell-indent-info indent-info)
+         (sep (haskell-indent-separate-valdef start end))
+         (valname (pop sep))
+         (valname-string (pop sep))
+         (aft-valname (pop sep))
+         (guard (pop sep))
+         (aft-guard (pop sep))
+         (rhs-sign (pop sep))
+         (aft-rhs-sign (pop sep))
+         (last-line (= end end-visible))
+         (is-where
+          (string-match "where[ \t]*" haskell-indent-current-line-first-ident))
+         (diff-first                 ; not a function def with the same name
+          (or (null valname-string)
+              (not (string= (haskell-string-trim valname-string)
+                            (haskell-string-trim haskell-indent-current-line-first-ident)))))
+
+         ;; (is-type-def
+         ;;  (and rhs-sign (eq (char-after rhs-sign) ?\:)))
+         (test (string
+                (if valname ?1 ?0)
+                (if (and aft-valname (< aft-valname end-visible)) ?1 ?0)
+                (if (and guard (< guard end-visible)) ?1 ?0)
+                (if (and aft-guard (< aft-guard end-visible)) ?1 ?0)
+                (if (and rhs-sign (< rhs-sign end-visible)) ?1 ?0)
+                (if (and aft-rhs-sign (< aft-rhs-sign end-visible)) ?1 ?0))))
+      (if (and valname-string           ; special case for start keywords
+               (string-match haskell-indent-start-keywords-re valname-string))
+          (progn
+            (haskell-indent-push-pos valname)
+            (if (string-match "\\<data\\>" valname-string)
+                ;; very special for data keyword
+                (if aft-rhs-sign (haskell-indent-push-pos aft-rhs-sign)
+                  (haskell-indent-push-pos-offset valname))
+              (if (not (string-match
+                        haskell-indent-start-keywords-re
+                        haskell-indent-current-line-first-ident))
+                  (haskell-indent-push-pos-offset valname))))
+        (if (string= haskell-indent-current-line-first-ident "::")
+            (if valname (haskell-indent-push-pos valname))
+          (cl-case                      ; general case
+              (haskell-indent-find-case test)
+            ;; "1.1.11"   1= vn gd rh arh
+            (1 (if is-where
+                   (haskell-indent-push-pos guard)
+                 (haskell-indent-push-pos valname)
+                 (if diff-first (haskell-indent-push-pos aft-rhs-sign))))
+            ;; "1.1.10"   2= vn gd rh
+            (2 (if is-where
+                   (haskell-indent-push-pos guard)
+                 (haskell-indent-push-pos valname)
+                 (if last-line
+                     (haskell-indent-push-pos-offset guard))))
+            ;; "1.1100"   3= vn gd agd
+            (3 (if is-where
+                   (haskell-indent-push-pos-offset guard)
+                 (haskell-indent-push-pos valname)
+                 (if diff-first
+                     (haskell-indent-push-pos aft-guard))))
+            ;; "1.1000"   4= vn gd
+            (4 (if is-where
+                   (haskell-indent-push-pos guard)
+                 (haskell-indent-push-pos valname)
+                 (if last-line
+                     (haskell-indent-push-pos-offset guard 2))))
+            ;; "1.0011"   5= vn rh arh
+            (5 (if is-where
+                   (haskell-indent-push-pos-offset valname)
+                 (haskell-indent-push-pos valname)
+                 (if diff-first
+                     (haskell-indent-push-pos aft-rhs-sign))))
+            ;; "1.0010"   6= vn rh
+            (6 (if is-where
+                   (haskell-indent-push-pos-offset valname)
+                 (haskell-indent-push-pos valname)
+                 (if last-line
+                     (haskell-indent-push-pos-offset valname))))
+            ;; "110000"   7= vn avn
+            (7 (if is-where
+                   (haskell-indent-push-pos-offset valname)
+                 (haskell-indent-push-pos valname)
+                 (if last-line
+                     (haskell-indent-push-pos aft-valname))))
+            ;; "100000"   8= vn
+            (8 (if is-where
+                   (haskell-indent-push-pos-offset valname)
+                 (haskell-indent-push-pos valname)))
+            ;; "001.11"   9= gd rh arh
+            (9 (if is-where
+                   (haskell-indent-push-pos guard)
+                 (haskell-indent-push-pos aft-rhs-sign)))
+            ;; "001.10"  10= gd rh
+            (10 (if is-where
+                    (haskell-indent-push-pos guard)
+                  (if last-line
+                      (haskell-indent-push-pos-offset guard))))
+            ;; "001100"  11= gd agd
+            (11 (if is-where
+                    (haskell-indent-push-pos guard)
+                  (if (haskell-indent-no-otherwise guard)
+                      (haskell-indent-push-pos aft-guard))))
+            ;; "001000"  12= gd
+            (12 (if last-line (haskell-indent-push-pos-offset guard 2)))
+            ;; "000011"  13= rh arh
+            (13 (haskell-indent-push-pos aft-rhs-sign))
+            ;; "000010"  14= rh
+            (14 (if last-line (haskell-indent-push-pos-offset rhs-sign 2)))
+            ;; "000000"  15=
+            (t (error "haskell-indent-ident: %s impossible case" test )))))
+      haskell-indent-info)))
+
+(defun haskell-indent-other (start end end-visible indent-info)
+  "Find indentation points for a non-empty line starting with something other
+than an identifier, a guard or rhs."
+  (save-excursion
+    (let* ((haskell-indent-info indent-info)
+           (sep (haskell-indent-separate-valdef start end))
+           (valname (pop sep))
+           (valname-string (pop sep))
+           (aft-valname (pop sep))
+           (guard (pop sep))
+           (aft-guard (pop sep))
+           (rhs-sign (pop sep))
+           (aft-rhs-sign (pop sep))
+           (last-line (= end end-visible))
+           (test (string
+                  (if valname ?1 ?0)
+                  (if (and aft-valname (< aft-valname end-visible)) ?1 ?0)
+                  (if (and guard (< guard end-visible)) ?1 ?0)
+                  (if (and aft-guard (< aft-guard end-visible)) ?1 ?0)
+                  (if (and rhs-sign (< rhs-sign end-visible)) ?1 ?0)
+                  (if (and aft-rhs-sign (< aft-rhs-sign end-visible)) ?1 ?0))))
+      (if (and valname-string           ; special case for start keywords
+               (string-match haskell-indent-start-keywords-re valname-string))
+          (haskell-indent-push-pos-offset valname)
+        (cl-case                        ; general case
+            (haskell-indent-find-case test)
+          ;; "1.1.11"   1= vn gd rh arh
+          (1 (haskell-indent-push-pos aft-rhs-sign))
+          ;; "1.1.10"   2= vn gd rh
+          (2 (if last-line
+                 (haskell-indent-push-pos-offset guard)
+               (haskell-indent-push-pos-offset rhs-sign 2)))
+          ;; "1.1100"   3= vn gd agd
+          (3 (haskell-indent-push-pos aft-guard))
+          ;; "1.1000"   4= vn gd
+          (4 (haskell-indent-push-pos-offset guard 2))
+          ;; "1.0011"   5= vn rh arh
+          (5 (haskell-indent-push-pos valname)
+             (haskell-indent-push-pos aft-rhs-sign))
+          ;; "1.0010"   6= vn rh
+          (6 (if last-line
+                 (haskell-indent-push-pos-offset valname)
+               (haskell-indent-push-pos-offset rhs-sign 2)))
+          ;; "110000"   7= vn avn
+          (7 (haskell-indent-push-pos-offset aft-valname))
+          ;; "100000"   8= vn
+          (8 (haskell-indent-push-pos valname))
+          ;; "001.11"   9= gd rh arh
+          (9 (haskell-indent-push-pos aft-rhs-sign))
+          ;; "001.10"  10= gd rh
+          (10 (if last-line
+                  (haskell-indent-push-pos-offset guard)
+                (haskell-indent-push-pos-offset rhs-sign 2)))
+          ;; "001100"  11= gd agd
+          (11 (if (haskell-indent-no-otherwise guard)
+                  (haskell-indent-push-pos aft-guard)))
+          ;; "001000"  12= gd
+          (12 (if last-line (haskell-indent-push-pos-offset guard 2)))
+          ;; "000011"  13= rh arh
+          (13 (haskell-indent-push-pos aft-rhs-sign))
+          ;; "000010"  14= rh
+          (14 (if last-line (haskell-indent-push-pos-offset rhs-sign 2)))
+          ;; "000000"  15=
+          (t (error "haskell-indent-other: %s impossible case" test ))))
+      haskell-indent-info)))
+
+(defun haskell-indent-valdef-indentation (start end end-visible curr-line-type
+                                                indent-info)
+  "Find indentation information for a value definition."
+  (let ((haskell-indent-info indent-info))
+    (if (< start end-visible)
+        (cl-case curr-line-type
+          (empty (haskell-indent-empty start end end-visible indent-info))
+          (ident (haskell-indent-ident start end end-visible indent-info))
+          (guard (haskell-indent-guard start end end-visible indent-info))
+          (rhs   (haskell-indent-rhs start end end-visible indent-info))
+          (comment (error "Comment indent should never happen"))
+          (other (haskell-indent-other start end end-visible indent-info)))
+      haskell-indent-info)))
+
+(defun haskell-indent-line-indentation (line-start line-end end-visible
+                                                   curr-line-type indent-info)
+  "Compute indentation info between LINE-START and END-VISIBLE.
+Separate a line of program into valdefs between offside keywords
+and find indentation info for each part."
+  (save-excursion
+    ;; point is (already) at line-start
+    (cl-assert (eq (point) line-start))
+    (let ((haskell-indent-info indent-info)
+          (start (or (haskell-indent-in-comment line-start line-end)
+                     (haskell-indent-in-string line-start line-end))))
+      (if start                         ; if comment at the end
+          (setq line-end start))  ; end line before it
+      ;; loop on all parts separated by off-side-keywords
+      (while (and (re-search-forward haskell-indent-off-side-keywords-re
+                                     line-end t)
+                  (not (or (haskell-indent-in-comment line-start (point))
+                           (haskell-indent-in-string line-start (point)))))
+        (let ((beg-match (match-beginning 0)) ; save beginning of match
+              (end-match (match-end 0)))      ; save end of match
+          ;; Do not try to find indentation points if off-side-keyword at
+          ;; the start...
+          (if (or (< line-start beg-match)
+                  ;; Actually, if we're looking at a "let" inside a "do", we
+                  ;; should add the corresponding indentation point.
+                  (eq (char-after beg-match) ?l))
+              (setq haskell-indent-info
+                    (haskell-indent-valdef-indentation line-start beg-match
+                                                       end-visible
+                                                       curr-line-type
+                                                       haskell-indent-info)))
+          ;; ...but keep the start of the line if keyword alone on the line
+          (if (= line-end end-match)
+              (haskell-indent-push-pos beg-match))
+          (setq line-start end-match)
+          (goto-char line-start)))
+      (haskell-indent-valdef-indentation line-start line-end end-visible
+                                         curr-line-type haskell-indent-info))))
+
+
+(defun haskell-indent-layout-indent-info (start contour-line)
+  (let ((haskell-indent-info nil)
+        (curr-line-type (haskell-indent-type-at-point))
+        line-start line-end end-visible)
+    (save-excursion
+      (if (eq curr-line-type 'ident)
+          (let                          ; guess the type of line
+              ((sep
+                (haskell-indent-separate-valdef
+                 (point) (line-end-position))))
+            ;; if the first ident is where or the start of a def
+            ;; keep it in a global variable
+            (setq haskell-indent-current-line-first-ident
+                  (if (string-match "where[ \t]*" (nth 1 sep))
+                      (nth 1 sep)
+                    (if (nth 5 sep)              ; is there a rhs-sign
+                        (if (= (char-after (nth 5 sep)) ?\:) ;is it a typdef
+                            "::" (nth 1 sep))
+                      "")))))
+      (while contour-line               ; explore the contour points
+        (setq line-start (pop contour-line))
+        (goto-char line-start)
+        (setq line-end (line-end-position))
+        (setq end-visible            ; visible until the column of the
+              (if contour-line       ; next contour point
+                  (save-excursion
+                    (move-to-column
+                     (haskell-indent-point-to-col (car contour-line)))
+                    (point))
+                line-end))
+        (unless (or (haskell-indent-open-structure start line-start)
+                    (haskell-indent-in-comment start line-start))
+          (setq haskell-indent-info
+                (haskell-indent-line-indentation line-start line-end
+                                                 end-visible curr-line-type
+                                                 haskell-indent-info)))))
+    haskell-indent-info))
+
+(defun haskell-indent-find-matching-start (regexp limit &optional pred start)
+  (let ((open (haskell-indent-open-structure limit (point))))
+    (if open (setq limit (1+ open))))
+  (unless start (setq start (point)))
+  (when (re-search-backward regexp limit t)
+    (let ((nestedcase (match-end 1))
+          (outer (or (haskell-indent-in-string limit (point))
+                     (haskell-indent-in-comment limit (point))
+                     (haskell-indent-open-structure limit (point))
+                     (if (and pred (funcall pred start)) (point)))))
+      (cond
+       (outer
+        (goto-char outer)
+        (haskell-indent-find-matching-start regexp limit pred start))
+       (nestedcase
+        ;; Nested case.
+        (and (haskell-indent-find-matching-start regexp limit pred)
+             (haskell-indent-find-matching-start regexp limit pred start)))
+       (t (point))))))
+
+(defun haskell-indent-filter-let-no-in (start)
+  "Return non-nil if point is in front of a `let' that has no `in'.
+START is the position of the presumed `in'."
+  ;; We're looking at either `in' or `let'.
+  (when (looking-at "let")
+    (ignore-errors
+      (save-excursion
+        (forward-word 1)
+        (forward-comment (point-max))
+        (if (looking-at "{")
+            (progn
+              (forward-sexp 1)
+              (forward-comment (point-max))
+              (< (point) start))
+          ;; Use the layout rule to see whether this let is already closed
+          ;; without an `in'.
+          (let ((col (current-column)))
+            (while (progn (forward-line 1) (haskell-indent-back-to-indentation)
+                          (< (point) start))
+              (when (< (current-column) col)
+                (setq col nil)
+                (goto-char start)))
+            (null col)))))))
+
+(defun haskell-indent-comment (open start)
+  "Compute indent info for comments and text inside comments.
+OPEN is the start position of the comment in which point is."
+  ;; Ideally we'd want to guess whether it's commented out code or
+  ;; whether it's text.  Instead, we'll assume it's text.
+  (save-excursion
+    (if (= open (point))
+        ;; We're actually just in front of a comment: align with following
+        ;; code or with comment on previous line.
+        (let ((prev-line-info
+               (cond
+                ((eq (char-after) ?\{) nil) ;Align as if it were code.
+                ((and (forward-comment -1)
+                      (> (line-beginning-position 3) open))
+                 ;; We're after another comment and there's no empty line
+                 ;; between us.
+                 (list (list (haskell-indent-point-to-col (point)))))
+                (t nil))))              ;Else align as if it were code
+          ;; Align with following code.
+          (forward-comment (point-max))
+          ;; There are several possible indentation points for this code-line,
+          ;; but the only valid indentation point for the comment is the one
+          ;; that the user will select for the code-line.  Obviously we can't
+          ;; know that, so we just assume that the code-line is already at its
+          ;; proper place.
+          ;; Strictly speaking "assume it's at its proper place" would mean
+          ;; we'd just use (current-column), but since this is using info from
+          ;; lines further down and it's common to reindent line-by-line,
+          ;; we'll align not with the current indentation, but with the
+          ;; one that auto-indentation "will" select.
+          (append
+           prev-line-info
+           (let ((indent-info (save-excursion
+                                (haskell-indent-indentation-info start)))
+                 (col (current-column)))
+             ;; Sort the indent-info so that the current indentation comes
+             ;; out first.
+             (setq indent-info
+                   (sort indent-info
+                         (lambda (x y)
+                           (<= (abs (- col (car x))) (abs (- col (car y)))))))
+             indent-info)))
+
+      ;; We really are inside a comment.
+      (if (looking-at "-}")
+          (progn
+            (forward-char 2)
+            (forward-comment -1)
+            (list (list (1+ (haskell-indent-point-to-col (point))))))
+        (let ((offset (if (looking-at "--?")
+                          (- (match-beginning 0) (match-end 0)))))
+          (forward-line -1)             ;Go to previous line.
+          (haskell-indent-back-to-indentation)
+          (if (< (point) start) (goto-char start))
+
+          (list (list (if (looking-at comment-start-skip)
+                          (if offset
+                              (+ 2 offset (haskell-indent-point-to-col (point)))
+                            (haskell-indent-point-to-col (match-end 0)))
+                        (haskell-indent-point-to-col (point))))))))))
+
+(defcustom haskell-indent-thenelse 0
+  "If non-nil, \"then\" and \"else\" are indented.
+This is necessary in the \"do\" layout under Haskell-98.
+See http://hackage.haskell.org/trac/haskell-prime/wiki/DoAndIfThenElse"
+  :group 'haskell-indent
+  :safe #'booleanp
+  :type 'integer)
+
+(defun haskell-indent-closing-keyword (start)
+  (let ((open (save-excursion
+                (haskell-indent-find-matching-start
+                 (cl-case (char-after)
+                   (?i "\\<\\(?:\\(in\\)\\|let\\)\\>")
+                   (?o "\\<\\(?:\\(of\\)\\|case\\)\\>")
+                   (?t "\\<\\(?:\\(then\\)\\|if\\)\\>")
+                   (?e "\\<\\(?:\\(else\\)\\|if\\)\\>"))
+                 start
+                 (if (eq (char-after) ?i)
+                     ;; Filter out the `let's that have no `in'.
+                     'haskell-indent-filter-let-no-in)))))
+    ;; For a "hanging let/case/if at EOL" we should use a different
+    ;; indentation scheme.
+    (save-excursion
+      (goto-char open)
+      (if (haskell-indent-hanging-p)
+          (setq open (haskell-indent-virtual-indentation start))))
+    ;; FIXME: we should try and figure out if the `if' is in a `do' layout
+    ;; before using haskell-indent-thenelse.
+    (list (list (+ (if (memq (char-after) '(?t ?e)) haskell-indent-thenelse 0)
+                   (haskell-indent-point-to-col open))))))
+
+(defcustom haskell-indent-after-keywords
+  '(("where" 2 0)
+    ("of" 2)
+    ("do" 2)
+    ("mdo" 2)
+    ("rec" 2)
+    ("in" 2 0)
+    ("{" 2)
+    "if"
+    "then"
+    "else"
+    "let")
+  "Keywords after which indentation should be indented by some offset.
+Each keyword info can have the following forms:
+
+   KEYWORD | (KEYWORD OFFSET [OFFSET-HANGING])
+
+If absent OFFSET-HANGING defaults to OFFSET.
+If absent OFFSET defaults to `haskell-indent-offset'.
+
+OFFSET-HANGING is the offset to use in the case where the keyword
+is at the end of an otherwise-non-empty line."
+  :group 'haskell-indent
+  :type '(repeat (choice string
+                         (cons :tag "" (string :tag "keyword:")
+                               (cons :tag "" (integer :tag "offset")
+                                     (choice (const nil)
+                                             (list :tag ""
+                                                   (integer :tag "offset-pending"))))))))
+
+(defun haskell-indent-skip-lexeme-forward ()
+  (and (zerop (skip-syntax-forward "w"))
+       (skip-syntax-forward "_")
+       (skip-syntax-forward "(")
+       (skip-syntax-forward ")")))
+
+(defvar haskell-indent-inhibit-after-offset nil)
+
+(defun haskell-indent-offset-after-info ()
+  "Return the info from `haskell-indent-after-keywords' for keyword at point."
+  (let ((id (buffer-substring
+             (point)
+             (save-excursion
+               (haskell-indent-skip-lexeme-forward)
+               (point)))))
+    (or (assoc id haskell-indent-after-keywords)
+        (car (member id haskell-indent-after-keywords)))))
+
+(defcustom haskell-indent-dont-hang '("(")
+  "Lexemes that should never be considered as hanging."
+  :group 'haskell-indent
+  :type '(repeat string))
+
+(defun haskell-indent-hanging-p ()
+  ;; A Hanging keyword is one that's at the end of a line except it's not at
+  ;; the beginning of a line.
+  (not (or (= (current-column) (haskell-indent-current-indentation))
+           (save-excursion
+             (let ((lexeme
+                    (buffer-substring
+                     (point)
+                     (progn (haskell-indent-skip-lexeme-forward) (point)))))
+               (or (member lexeme haskell-indent-dont-hang)
+                   (> (line-end-position)
+                      (progn (forward-comment (point-max)) (point)))))))))
+
+(defun haskell-indent-after-keyword-column (offset-info start &optional default)
+  (unless offset-info
+    (setq offset-info (haskell-indent-offset-after-info)))
+  (unless default (setq default haskell-indent-offset))
+  (setq offset-info
+        (if haskell-indent-inhibit-after-offset '(0) (cdr-safe offset-info)))
+  (if (not (haskell-indent-hanging-p))
+      (haskell-indent-column+offset (current-column)
+                                    (or (car offset-info) default))
+    ;; The keyword is hanging at the end of the line.
+    (haskell-indent-column+offset
+     (haskell-indent-virtual-indentation start)
+     (or (cadr offset-info) (car offset-info) default))))
+
+(defun haskell-indent-inside-paren (open)
+  ;; there is an open structure to complete
+  (if (looking-at "\\s)\\|[;,]")
+      ;; A close-paren or a , or ; can only correspond syntactically to
+      ;; the open-paren at `open'.  So there is no ambiguity.
+      (progn
+        (if (or (and (eq (char-after) ?\;) (eq (char-after open) ?\())
+                (and (eq (char-after) ?\,) (eq (char-after open) ?\{)))
+            (message "Mismatched punctuation: `%c' in %c...%c"
+                     (char-after) (char-after open)
+                     (if (eq (char-after open) ?\() ?\) ?\})))
+        (save-excursion
+          (goto-char open)
+          (list (list
+                 (if (haskell-indent-hanging-p)
+                     (haskell-indent-virtual-indentation nil)
+                   (haskell-indent-point-to-col open))))))
+    ;; There might still be layout within the open structure.
+    (let* ((end (point))
+           (basic-indent-info
+            ;; Anything else than a ) is subject to layout.
+            (if (looking-at "\\s.\\|\\$ ")
+                (haskell-indent-point-to-col open) ; align a punct with (
+              (let ((follow (save-excursion
+                              (goto-char (1+ open))
+                              (haskell-indent-skip-blanks-and-newlines-forward end)
+                              (point))))
+                (if (= follow end)
+                    (save-excursion
+                      (goto-char open)
+                      (haskell-indent-after-keyword-column nil nil 1))
+                  (haskell-indent-point-to-col follow)))))
+           (open-column (haskell-indent-point-to-col open))
+           (contour-line (haskell-indent-contour-line (1+ open) end)))
+      (if (null contour-line)
+          (list (list basic-indent-info))
+        (let ((indent-info
+               (haskell-indent-layout-indent-info
+                (1+ open) contour-line)))
+          ;; Fix up indent info.
+          (let ((base-elem (assoc open-column indent-info)))
+            (if base-elem
+                (progn (setcar base-elem basic-indent-info)
+                       (setcdr base-elem nil))
+              (setq indent-info
+                    (append indent-info (list (list basic-indent-info)))))
+            indent-info))))))
+
+(defun haskell-indent-virtual-indentation (start)
+  "Compute the \"virtual indentation\" of text at point.
+The \"virtual indentation\" is the indentation that text at point would have
+had, if it had been placed on its own line."
+  (let ((col (current-column))
+        (haskell-indent-inhibit-after-offset (haskell-indent-hanging-p)))
+    (if (save-excursion (skip-chars-backward " \t") (bolp))
+        ;; If the text is indeed on its own line, than the virtual indent is
+        ;; the current indentation.
+        col
+      ;; Else, compute the indentation that it would have had.
+      (let ((info (haskell-indent-indentation-info start))
+            (max -1))
+        ;; `info' is a list of possible indent points.  Each indent point is
+        ;; assumed to correspond to a different parse.  So we need to find
+        ;; the parse that corresponds to the case at hand (where there's no
+        ;; line break), which is assumed to always be the
+        ;; deepest indentation.
+        (dolist (x info)
+          (setq x (car x))
+          ;; Sometimes `info' includes the current indentation (or yet
+          ;; deeper) by mistake, because haskell-indent-indentation-info
+          ;; wasn't designed to be called on a piece of text that is not at
+          ;; BOL.  So ignore points past `col'.
+          (if (and (> x max) (not (>= x col)))
+              (setq max x)))
+        ;; In case all the indent points are past `col', just use `col'.
+        (if (>= max 0) max col)))))
+
+(defun haskell-indent-indentation-info (&optional start)
+  "Return a list of possible indentations for the current line.
+These are then used by `haskell-indent-cycle'.
+START if non-nil is a presumed start pos of the current definition."
+  (unless start (setq start (haskell-indent-start-of-def)))
+  (let (open contour-line)
+    (cond
+     ;; in string?
+     ((setq open (haskell-indent-in-string start (point)))
+      (list (list (+ (haskell-indent-point-to-col open)
+                     (if (looking-at "\\\\") 0 1)))))
+
+     ;; in comment ?
+     ((setq open (haskell-indent-in-comment start (point)))
+      (haskell-indent-comment open start))
+
+     ;; Closing the declaration part of a `let' or the test exp part of a case.
+     ((looking-at "\\(?:in\\|of\\|then\\|else\\)\\>")
+      (haskell-indent-closing-keyword start))
+
+     ;; Right after a special keyword.
+     ((save-excursion
+        (forward-comment (- (point-max)))
+        (when (and (not (zerop (skip-syntax-backward "w")))
+                   (setq open (haskell-indent-offset-after-info)))
+          (list (list (haskell-indent-after-keyword-column open start))))))
+
+     ;; open structure? ie  ( { [
+     ((setq open (haskell-indent-open-structure start (point)))
+      (haskell-indent-inside-paren open))
+
+     ;; full indentation
+     ((setq contour-line (haskell-indent-contour-line start (point)))
+      (haskell-indent-layout-indent-info start contour-line))
+
+     (t
+      ;; simple contour just one indentation at start
+      (list (list (if (and (eq haskell-literate 'bird)
+                           (eq (haskell-indent-point-to-col start) 1))
+                      ;; for a Bird style literate script put default offset
+                      ;; in the case of no indentation
+                      (1+ haskell-indent-literate-Bird-default-offset)
+                    (haskell-indent-point-to-col start))))))))
+
+(defvar haskell-indent-last-info nil)
+
+
+(defun haskell-indent-cycle ()
+  "Indentation cycle.
+We stay in the cycle as long as the TAB key is pressed."
+  (interactive "*")
+  (if (and haskell-literate
+           (not (haskell-indent-within-literate-code)))
+      ;; use the ordinary tab for text...
+      (funcall (default-value 'indent-line-function))
+    (let ((marker (if (> (current-column) (haskell-indent-current-indentation))
+                      (point-marker)))
+          (bol (progn (beginning-of-line) (point))))
+      (haskell-indent-back-to-indentation)
+      (unless (and (eq last-command this-command)
+                   (eq bol (car haskell-indent-last-info)))
+        (save-excursion
+          (setq haskell-indent-last-info
+                (list bol (haskell-indent-indentation-info) 0 0))))
+
+      (let* ((il (nth 1 haskell-indent-last-info))
+             (index (nth 2 haskell-indent-last-info))
+             (last-insert-length (nth 3 haskell-indent-last-info))
+             (indent-info (nth index il)))
+
+        (haskell-indent-line-to (car indent-info)) ; insert indentation
+        (delete-char last-insert-length)
+        (setq last-insert-length 0)
+        (let ((text (cdr indent-info)))
+          (if text
+              (progn
+                (insert text)
+                (setq last-insert-length (length text)))))
+
+        (setq haskell-indent-last-info
+              (list bol il (% (1+ index) (length il)) last-insert-length))
+
+        (if (= (length il) 1)
+            (message "Sole indentation")
+          (message "Indent cycle (%d)..." (length il)))
+
+        (if marker
+            (goto-char (marker-position marker)))))))
+
+(defun haskell-indent-region (_start _end)
+  (error "Auto-reindentation of a region is not supported"))
+
+;;; alignment functions
+
+(defun haskell-indent-shift-columns (dest-column region-stack)
+  "Shift columns in REGION-STACK to go to DEST-COLUMN.
+Elements of the stack are pairs of points giving the start and end
+of the regions to move."
+  (let (reg col diffcol reg-end)
+    (while (setq reg (pop region-stack))
+      (setq reg-end (copy-marker (cdr reg)))
+      (goto-char (car reg))
+      (setq col (current-column))
+      (setq diffcol (- dest-column col))
+      (if (not (zerop diffcol))
+          (catch 'end-of-buffer
+            (while (<= (point) (marker-position reg-end))
+              (if (< diffcol 0)
+                  (backward-delete-char-untabify (- diffcol) nil)
+                (insert-char ?\  diffcol))
+              (end-of-line 2)           ; should be (forward-line 1)
+              (if (eobp)                ; but it adds line at the end...
+                  (throw 'end-of-buffer nil))
+              (move-to-column col)))))))
+
+(defun haskell-indent-align-def (p-arg type)
+  "Align guards or rhs within the current definition before point.
+If P-ARG is t align all defs up to the mark.
+TYPE is either 'guard or 'rhs."
+  (save-excursion
+    (let (start-block end-block
+                      (maxcol (if (eq type 'rhs) haskell-indent-rhs-align-column 0))
+                      contour sep defname defnamepos
+                      defcol pos lastpos
+                      regstack eqns-start start-found)
+      ;; find the starting and ending boundary points for alignment
+      (if p-arg
+          (if (mark)                    ; aligning everything in the region
+              (progn
+                (when (> (mark) (point)) (exchange-point-and-mark))
+                (setq start-block
+                      (save-excursion
+                        (goto-char (mark))
+                        (line-beginning-position)))
+                (setq end-block
+                      (progn (if (haskell-indent-bolp)
+                                 (haskell-indent-forward-line -1))
+                             (line-end-position))))
+            (error "The mark is not set for aligning definitions"))
+        ;; aligning the current definition
+        (setq start-block (haskell-indent-start-of-def))
+        (setq end-block (line-end-position)))
+      ;; find the start of the current valdef using the contour line
+      ;; in reverse order because we need the nearest one from the end
+      (setq contour
+            (reverse (haskell-indent-contour-line start-block end-block)))
+      (setq pos (car contour))          ; keep the start of the first contour
+      ;; find the nearest start of a definition
+      (while (and (not defname) contour)
+        (goto-char (pop contour))
+        (if (haskell-indent-open-structure start-block (point))
+            nil
+          (setq sep (haskell-indent-separate-valdef (point) end-block))
+          (if (nth 5 sep)               ; is there a rhs?
+              (progn (setq defnamepos (nth 0 sep))
+                     (setq defname (nth 1 sep))))))
+      ;; start building the region stack
+      (if defnamepos
+          (progn                        ; there is a valdef
+            ;; find the start of each equation or guard
+            (if p-arg      ; when indenting a region
+                ;; accept any start of id or pattern as def name
+                (setq defname "\\<\\|("))
+            (setq defcol (haskell-indent-point-to-col defnamepos))
+            (goto-char pos)
+            (setq end-block (line-end-position))
+            (catch 'top-of-buffer
+              (while (and (not start-found)
+                          (>= (point) start-block))
+                (if (<= (haskell-indent-current-indentation) defcol)
+                    (progn
+                      (move-to-column defcol)
+                      (if (and (looking-at defname) ; start of equation
+                               (not (haskell-indent-open-structure start-block (point))))
+                          (push (cons (point) 'eqn) eqns-start)
+                        ;; found a less indented point not starting an equation
+                        (setq start-found t)))
+                  ;; more indented line
+                  (haskell-indent-back-to-indentation)
+                  (if (and (eq (haskell-indent-type-at-point) 'guard) ; start of a guard
+                           (not (haskell-indent-open-structure start-block (point))))
+                      (push (cons (point) 'gd) eqns-start)))
+                (if (bobp)
+                    (throw 'top-of-buffer nil)
+                  (haskell-indent-backward-to-indentation 1))))
+            ;; remove the spurious guards before the first equation
+            (while (and eqns-start (eq (cdar eqns-start) 'gd))
+              (pop eqns-start))
+            ;; go through each equation to find the region to indent
+            (while eqns-start
+              (let ((eqn (caar eqns-start)))
+                (setq lastpos (if (cdr eqns-start)
+                                  (save-excursion
+                                    (goto-char (cl-caadr eqns-start))
+                                    (haskell-indent-forward-line -1)
+                                    (line-end-position))
+                                end-block))
+                (setq sep (haskell-indent-separate-valdef eqn lastpos)))
+              (if (eq type 'guard)
+                  (setq pos (nth 3 sep))
+                ;; check if what follows a rhs sign is more indented or not
+                (let ((rhs (nth 5 sep))
+                      (aft-rhs (nth 6 sep)))
+                  (if (and rhs aft-rhs
+                           (> (haskell-indent-point-to-col rhs)
+                              (haskell-indent-point-to-col aft-rhs)))
+                      (setq pos aft-rhs)
+                    (setq pos rhs))))
+              (if pos
+                  (progn                ; update region stack
+                    (push (cons pos (or lastpos pos)) regstack)
+                    (setq maxcol        ; find the highest column number
+                          (max maxcol
+                               (progn   ;find the previous non-empty column
+                                 (goto-char pos)
+                                 (skip-chars-backward
+                                  " \t"
+                                  (line-beginning-position))
+                                 (if (haskell-indent-bolp)
+                                     ;;if on an empty prefix
+                                     (haskell-indent-point-to-col pos) ;keep original indent
+                                   (1+ (haskell-indent-point-to-col (point)))))))))
+              (pop eqns-start))
+            ;; now shift according to the region stack
+            (if regstack
+                (haskell-indent-shift-columns maxcol regstack)))))))
+
+(defun haskell-indent-align-guards-and-rhs (_start _end)
+  "Align the guards and rhs of functions in the region, which must be active."
+  ;; The `start' and `end' args are dummys right now: they're just there so
+  ;; we can use the "r" interactive spec which properly signals an error.
+  (interactive "*r")
+  (haskell-indent-align-def t 'guard)
+  (haskell-indent-align-def t 'rhs))
+
+;;;  insertion functions
+
+(defun haskell-indent-insert-equal ()
+  "Insert an = sign and align the previous rhs of the current function."
+  (interactive "*")
+  (if (or (haskell-indent-bolp)
+          (/= (preceding-char) ?\ ))
+      (insert ?\ ))
+  (insert "= ")
+  (haskell-indent-align-def (haskell-indent-mark-active) 'rhs))
+
+(defun haskell-indent-insert-guard (&optional text)
+  "Insert and align a guard sign (|) followed by optional TEXT.
+Alignment works only if all guards are to the south-east of their |."
+  (interactive "*")
+  (let ((pc (if (haskell-indent-bolp) ?\012
+              (preceding-char)))
+        (pc1 (or (char-after (- (point) 2)) 0)))
+    ;; check what guard to insert depending on the previous context
+    (if (= pc ?\ )                      ; x = any char other than blank or |
+        (if (/= pc1 ?\|)
+            (insert "| ")               ; after " x"
+          ())                           ; after " |"
+      (if (= pc ?\|)
+          (if (= pc1 ?\|)
+              (insert " | ")            ; after "||"
+            (insert " "))               ; after "x|"
+        (insert " | ")))                ; general case
+    (if text (insert text))
+    (haskell-indent-align-def (haskell-indent-mark-active) 'guard)))
+
+(defun haskell-indent-insert-otherwise ()
+  "Insert a guard sign (|) followed by `otherwise'.
+Also align the previous guards of the current function."
+  (interactive "*")
+  (haskell-indent-insert-guard "otherwise")
+  (haskell-indent-insert-equal))
+
+(defun haskell-indent-insert-where ()
+  "Insert a where keyword at point and indent resulting line.
+One indentation cycle is used."
+  (interactive "*")
+  (insert "where ")
+  (haskell-indent-cycle))
+
+
+;;; haskell-indent-mode
+
+(defvar-local haskell-indent-mode nil
+  "Non-nil if the semi-intelligent Haskell indentation mode is in effect.")
+
+(defvar haskell-indent-map
+  (let ((map (make-sparse-keymap)))
+    ;; Removed: remapping DEL seems a bit naughty --SDM
+    ;; (define-key map "\177"  'backward-delete-char-untabify)
+    ;; The binding to TAB is already handled by indent-line-function.  --Stef
+    ;; (define-key map "\t"    'haskell-indent-cycle)
+    (define-key map (kbd "C-c C-=") 'haskell-indent-insert-equal)
+    (define-key map (kbd "C-c C-|") 'haskell-indent-insert-guard)
+    ;; Alternate binding, in case C-c C-| is too inconvenient to type.
+    ;; Duh, C-g is a special key, let's not use it here.
+    ;; (define-key map (kbd "C-c C-g") 'haskell-indent-insert-guard)
+    (define-key map (kbd "C-c C-o") 'haskell-indent-insert-otherwise)
+    (define-key map (kbd "C-c C-w") 'haskell-indent-insert-where)
+    (define-key map (kbd "C-c C-.") 'haskell-indent-align-guards-and-rhs)
+    (define-key map (kbd "C-c C->") 'haskell-indent-put-region-in-literate)
+    map))
+
+;;;###autoload
+(defun turn-on-haskell-indent ()
+  "Turn on ``intelligent'' Haskell indentation mode."
+  (when (and (bound-and-true-p haskell-indentation-mode)
+             (fboundp 'haskell-indentation-mode))
+    (haskell-indentation-mode 0))
+
+  (setq-local indent-line-function 'haskell-indent-cycle)
+  (setq-local indent-region-function 'haskell-indent-region)
+  (setq haskell-indent-mode t)
+  ;; Activate our keymap.
+  (let ((map (current-local-map)))
+    (while (and map (not (eq map haskell-indent-map)))
+      (setq map (keymap-parent map)))
+    ;; if haskell-indent-map is already active: there's nothing to do.
+    (unless map
+      ;; Put our keymap on top of the others.  We could also put it in
+      ;; second place, or in a minor-mode.  The minor-mode approach would be
+      ;; easier, but it's harder for the user to override it.  This approach
+      ;; is the closest in behavior compared to the previous code that just
+      ;; used a bunch of local-set-key.
+      (set-keymap-parent haskell-indent-map (current-local-map))
+      ;; Protect our keymap.
+      (setq map (make-sparse-keymap))
+      (set-keymap-parent map haskell-indent-map)
+      (use-local-map map)))
+  (run-hooks 'haskell-indent-hook))
+
+(defun turn-off-haskell-indent ()
+  "Turn off ``intelligent'' Haskell indentation mode."
+  (kill-local-variable 'indent-line-function)
+  (kill-local-variable 'indent-region-function)
+  ;; Remove haskell-indent-map from the local map.
+  (let ((map (current-local-map)))
+    (while map
+      (let ((parent (keymap-parent map)))
+        (if (eq haskell-indent-map parent)
+            (set-keymap-parent map (keymap-parent parent))
+          (setq map parent)))))
+  (setq haskell-indent-mode nil))
+
+;; Put this minor mode on the global minor-mode-alist.
+(or (assq 'haskell-indent-mode (default-value 'minor-mode-alist))
+    (setq-default minor-mode-alist
+                  (append (default-value 'minor-mode-alist)
+                          '((haskell-indent-mode " Ind")))))
+
+;;;###autoload
+(defun haskell-indent-mode (&optional arg)
+  "``Intelligent'' Haskell indentation mode.
+This deals with the layout rule of Haskell.
+\\[haskell-indent-cycle] starts the cycle which proposes new
+possibilities as long as the TAB key is pressed.  Any other key
+or mouse click terminates the cycle and is interpreted except for
+RET which merely exits the cycle.
+Other special keys are:
+    \\[haskell-indent-insert-equal]
+      inserts an =
+    \\[haskell-indent-insert-guard]
+      inserts an |
+    \\[haskell-indent-insert-otherwise]
+      inserts an | otherwise =
+these functions also align the guards and rhs of the current definition
+    \\[haskell-indent-insert-where]
+      inserts a where keyword
+    \\[haskell-indent-align-guards-and-rhs]
+      aligns the guards and rhs of the region
+    \\[haskell-indent-put-region-in-literate]
+      makes the region a piece of literate code in a literate script
+
+If `ARG' is falsey, toggle `haskell-indent-mode'.  Else sets
+`haskell-indent-mode' to whether `ARG' is greater than 0.
+
+Invokes `haskell-indent-hook' if not nil."
+  (interactive "P")
+  (setq haskell-indent-mode
+        (if (null arg) (not haskell-indent-mode)
+          (> (prefix-numeric-value arg) 0)))
+  (if haskell-indent-mode
+      (turn-on-haskell-indent)
+    (turn-off-haskell-indent)))
+
+(provide 'haskell-indent)
+
+;;; haskell-indent.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-indent.elc b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-indent.elc
new file mode 100644
index 0000000000..a22b1be264
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-indent.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-indentation.el b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-indentation.el
new file mode 100644
index 0000000000..0ab735ff2a
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-indentation.el
@@ -0,0 +1,1255 @@
+;;; haskell-indentation.el --- indentation module for Haskell Mode -*- lexical-binding: t -*-
+
+;; Copyright (C) 2013  Kristof Bastiaensen, Gergely Risko
+
+;; Author: Kristof Bastiaensen <kristof.bastiaensen@vleeuwen.org>
+;; Author: Gergely Risko <errge@nilcons.com>
+;; Keywords: indentation haskell
+;; URL: https://github.com/haskell/haskell-mode
+
+;; This file is not part of GNU Emacs.
+
+;; This file 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, or (at your option)
+;; any later version.
+
+;; This file 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Installation:
+;;
+;; To turn indentation on for all Haskell buffers under Haskell mode add
+;; this to your configuration file:
+;;
+;;     (add-hook haskell-mode-hook 'haskell-indentation-mode)
+;;
+;; Otherwise, call `haskell-indentation-mode'.
+
+;;; Code:
+
+;; TODO eliminate magic number 2 where possible, use a variable
+
+;; TODO `haskell-indentation-find-indentation' — fix it, get rid of "safe"
+;; version
+
+(require 'cl-lib)
+(require 'haskell-lexeme)
+
+;;;###autoload
+(defgroup haskell-indentation nil
+  "Haskell indentation."
+  :link '(custom-manual "(haskell-mode)Indentation")
+  :group 'haskell
+  :prefix "haskell-indentation-")
+
+(defcustom haskell-indentation-layout-offset 2
+  "Extra indentation to add before expressions in a Haskell layout list."
+  :type 'integer
+  :group 'haskell-indentation)
+
+(defcustom haskell-indentation-starter-offset 2
+  "Extra indentation after an opening keyword (e.g. \"let\")."
+  :type 'integer
+  :group 'haskell-indentation)
+
+(defcustom haskell-indentation-left-offset 2
+  "Extra indentation after an indentation to the left (e.g. after \"do\")."
+  :type 'integer
+  :group 'haskell-indentation)
+
+(defcustom haskell-indentation-where-pre-offset 2
+  "Extra indentation before the keyword \"where\"."
+  :type 'integer
+  :group 'haskell-indentation)
+
+(defcustom haskell-indentation-where-post-offset 2
+  "Extra indentation after the keyword \"where\"."
+  :type 'integer
+  :group 'haskell-indentation)
+
+(defcustom haskell-indentation-electric-flag nil
+  "Non-nil means insertion of some characters may auto reindent the line.
+If the variable `electric-indent-mode' is non-nil then this variable is
+overridden."
+  :type 'symbol
+  :group 'haskell-indentation)
+(make-variable-buffer-local 'haskell-indentation-electric-flag)
+
+(defvar haskell-indentation-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "RET") #'haskell-indentation-newline-and-indent)
+    (define-key map (kbd "<backtab>") #'haskell-indentation-indent-backwards)
+    (define-key map (kbd ",") #'haskell-indentation-common-electric-command)
+    (define-key map (kbd ";") #'haskell-indentation-common-electric-command)
+    (define-key map (kbd ")") #'haskell-indentation-common-electric-command)
+    (define-key map (kbd "}") #'haskell-indentation-common-electric-command)
+    (define-key map (kbd "]") #'haskell-indentation-common-electric-command)
+    map)
+  "Keymap for `haskell-indentation-mode'.")
+
+;;;###autoload
+(define-minor-mode haskell-indentation-mode
+  "Haskell indentation mode that deals with the layout rule.
+It rebinds RET, DEL and BACKSPACE, so that indentations can be
+set and deleted as if they were real tabs."
+  :keymap haskell-indentation-mode-map
+  (kill-local-variable 'indent-line-function)
+  (kill-local-variable 'indent-region-function)
+
+  (when haskell-indentation-mode
+    (when (and (bound-and-true-p haskell-indent-mode)
+               (fboundp 'turn-off-haskell-indent))
+      (turn-off-haskell-indent))
+    (setq-local indent-line-function #'haskell-indentation-indent-line)
+    (setq-local indent-region-function #'haskell-indentation-indent-region)))
+
+;;;###autoload
+(defun turn-on-haskell-indentation ()
+  "Turn on the haskell-indentation minor mode."
+  (interactive)
+  (haskell-indentation-mode t))
+
+(make-obsolete 'turn-on-haskell-indentation
+               'haskell-indentation-mode
+               "2015-05-25")
+
+(defvar haskell-literate) ; defined in haskell-mode.el
+
+(defun haskell-indentation-bird-p ()
+  "Return t if this is a literate Haskell buffer in bird style, NIL otherwise."
+  (eq haskell-literate 'bird))
+
+;;----------------------------------------------------------------------------
+;; UI starts here
+
+(defun haskell-indentation-reindent-to (col &optional move)
+  "Reindent current line to COL, move the point there if MOVE is non-NIL."
+  (let* ((ci (haskell-indentation-current-indentation)))
+    (save-excursion
+      (move-to-column ci)
+      (if (<= ci col)
+          (insert-before-markers (make-string (- col ci) ? ))
+        (delete-char (- col ci))))
+    (when move
+      (move-to-column col))))
+
+(defun haskell-indentation-indent-rigidly (start end arg)
+  "Indent all lines starting in the region sideways by ARG columns.
+Called from a program, takes three arguments, START, END and ARG.
+You can remove all indentation from a region by giving a large
+negative ARG.  Handles bird style literate Haskell too."
+  (interactive "*r\np")
+  (save-excursion
+    (goto-char end)
+    (let ((end-marker (point-marker)))
+      (goto-char start)
+      (or (bolp) (forward-line 0))
+      (while (< (point) end-marker)
+        (let ((ci (haskell-indentation-current-indentation)))
+          (when (and t
+                     (eq (char-after) ?>))
+            (forward-char 1))
+          (skip-syntax-forward "-")
+          (unless (eolp)
+            (haskell-indentation-reindent-to (max 0 (+ ci arg))))
+          (forward-line 1)))
+      (move-marker end-marker nil))))
+
+(defun haskell-indentation-current-indentation ()
+  "Column position of first non-whitespace character in current line."
+  (save-excursion
+    (beginning-of-line)
+    (when (haskell-indentation-bird-p)
+      (forward-char))
+    (skip-syntax-forward "-")
+    (current-column)))
+
+(defun haskell-indentation-bird-outside-code-p ()
+  "Non-NIL if we are in bird literate mode, but outside of code."
+  (and (haskell-indentation-bird-p)
+       (or (< (current-column) 2)
+           (save-excursion
+             (beginning-of-line)
+             (not (eq (char-after) ?>))))))
+
+(defun haskell-indentation-newline-and-indent ()
+  "Insert newline and indent."
+  (interactive "*")
+  ;; On RET (or C-j), we:
+  ;;   - just jump to the next line if literate haskell, but outside code
+  (if (haskell-indentation-bird-outside-code-p)
+      (progn
+        (delete-horizontal-space)
+        (newline))
+    ;;  - save the current column
+    (let ((ci (haskell-indentation-current-indentation)))
+      ;; - jump to the next line and reindent to at the least same level
+      (delete-horizontal-space)
+      (newline)
+      ;; calculate indentation after newline is inserted because if we
+      ;; break an identifier we might create a keyword, for example
+      ;; "dowhere" => "do where"
+      (let ((indentations (or (haskell-indentation-find-indentations)
+                              '(0))))
+        (when (haskell-indentation-bird-p)
+          (insert "> "))
+        (haskell-indentation-reindent-to
+         (haskell-indentation-next-indentation (- ci 1) indentations 'nofail)
+         'move)))))
+
+(defun haskell-indentation-next-indentation (col indentations &optional nofail)
+  "Find the leftmost indentation which is greater than COL.
+Indentations are taken from INDENTATIONS, which should be a
+list.  Return the last indentation if there are no bigger ones and
+NOFAIL is non-NIL."
+  (when (null indentations)
+    (error "haskell-indentation-next-indentation called with empty list"))
+  (or (cl-find-if (lambda (i) (> i col)) indentations)
+      (when nofail
+        (car (last indentations)))))
+
+(defun haskell-indentation-previous-indentation (col indentations &optional nofail)
+  "Find the rightmost indentation less than COL from INDENTATIONS.
+When no indentations are less than COL, return the rightmost indentation
+if NOFAIL is non-nil, or nil otherwise."
+  (when (null indentations)
+    (error "haskell-indentation-previous-indentation called with empty list"))
+  (let ((rev (reverse indentations)))
+    (or (cl-find-if (lambda (i) (< i col)) rev)
+        (when nofail
+          (car rev)))))
+
+(defvar haskell-indentation-dyn-last-direction nil
+  "") ; FIXME
+(defvar haskell-indentation-dyn-last-indentations nil
+  "") ; FIXME
+
+(defun haskell-indentation-indent-line ()
+  "Indent current line, cycle though indentation positions.
+Do nothing inside multiline comments and multiline strings.
+Start enumerating the indentation points to the right.  The user
+can continue by repeatedly pressing TAB.  When there is no more
+indentation points to the right, we switch going to the left."
+  (interactive "*")
+  ;; try to repeat
+  (when (not (haskell-indentation-indent-line-repeat))
+    (setq haskell-indentation-dyn-last-direction nil)
+    ;; parse error is intentionally not cought here, it may come from
+    ;; `haskell-indentation-find-indentations', but escapes the scope
+    ;; and aborts the opertaion before any moving happens
+    (let* ((cc (current-column))
+           (ci (haskell-indentation-current-indentation))
+           (inds (save-excursion
+                   (move-to-column ci)
+                   (or (haskell-indentation-find-indentations)
+                       '(0))))
+           (valid (memq ci inds))
+           (cursor-in-whitespace (< cc ci)))
+
+      (if (and valid cursor-in-whitespace)
+          (move-to-column ci)
+        (haskell-indentation-reindent-to
+         (haskell-indentation-next-indentation ci inds 'nofail)
+         cursor-in-whitespace))
+      (setq haskell-indentation-dyn-last-direction 'right
+            haskell-indentation-dyn-last-indentations inds))))
+
+(defun haskell-indentation-indent-line-repeat ()
+  "Cycle though indentation positions."
+  (cond
+   ((and (memq last-command
+               '(indent-for-tab-command
+                 haskell-indentation-indent-backwards))
+         (eq haskell-indentation-dyn-last-direction 'region))
+    (let ((mark-even-if-inactive t))
+      (haskell-indentation-indent-rigidly
+       (region-beginning)
+       (region-end)
+       1))
+    t)
+   ((and (eq last-command 'indent-for-tab-command)
+         (memq haskell-indentation-dyn-last-direction '(left right))
+         haskell-indentation-dyn-last-indentations)
+    (let ((ci (haskell-indentation-current-indentation)))
+      (if (eq haskell-indentation-dyn-last-direction 'left)
+          (haskell-indentation-reindent-to
+           (haskell-indentation-previous-indentation
+            ci haskell-indentation-dyn-last-indentations 'nofail))
+        ;; right
+        (if (haskell-indentation-next-indentation
+             ci haskell-indentation-dyn-last-indentations)
+            (haskell-indentation-reindent-to
+             (haskell-indentation-next-indentation
+              ci haskell-indentation-dyn-last-indentations 'nofail))
+          ;; but failed, switch to left
+          (setq haskell-indentation-dyn-last-direction 'left)
+          (haskell-indentation-indent-line-repeat)))
+      t))
+   (t nil)))
+
+(defun haskell-indentation-indent-region (_start _end)
+  "This function does nothing.
+
+It is better to do nothing to indent region in Haskell than to
+break the semantics of indentation.  This function is used for
+`indent-region-function' because the default is to call
+`indent-line-function' on every line from START to END and that
+also produces catastrophic results.
+
+Someday we will have indent region that preserves semantics and
+fixes up only indentation."
+  nil)
+
+(defun haskell-indentation-indent-backwards ()
+  "Indent the current line to the previous indentation point."
+  (interactive "*")
+  (cond
+   ((and (memq last-command
+               '(indent-for-tab-command haskell-indentation-indent-backwards))
+         (eq haskell-indentation-dyn-last-direction 'region))
+    (let ((mark-even-if-inactive t))
+      (haskell-indentation-indent-rigidly (region-beginning) (region-end) -1)))
+   ((use-region-p)
+    (setq haskell-indentation-dyn-last-direction 'region)
+    (haskell-indentation-indent-rigidly (region-beginning) (region-end) -1)
+    (message "Press TAB or S-TAB again to indent the region more"))
+   (t
+    (setq haskell-indentation-dyn-last-direction nil)
+    (let* ((cc (current-column))
+           (ci (haskell-indentation-current-indentation))
+           (inds (save-excursion
+                   (move-to-column ci)
+                   (or (haskell-indentation-find-indentations)
+                       '(0))))
+           (cursor-in-whitespace (< cc ci))
+           (pi (haskell-indentation-previous-indentation ci inds)))
+      (if (null pi)
+          ;; if there are no more indentations to the left, just go to column 0
+          (haskell-indentation-reindent-to
+           (car (haskell-indentation-first-indentation)) cursor-in-whitespace)
+        (haskell-indentation-reindent-to pi cursor-in-whitespace))))))
+
+(defun haskell-indentation-common-electric-command (arg)
+  "Call `self-insert-command' to insert the character typed ARG times
+and indent when all of the following are true:
+1) The character is the first non-whitespace character on the line.
+2) There is only one possible indentation position.
+3) The variable `electric-indent-mode' or `haskell-indentation-electric-flag'
+   is non-nil.
+4) The point is not in a comment, string, or quasiquote."
+  (interactive "*p")
+  (let ((col (current-column))
+        ind)
+    (self-insert-command arg)
+    (when (and (or haskell-indentation-electric-flag
+                   electric-indent-mode)
+               (= (haskell-indentation-current-indentation)
+                  col)
+               (> arg 0)
+               (not (nth 8 (syntax-ppss)))
+               (= 1 (save-excursion
+                      (move-to-column col)
+                      (length (setq ind (haskell-indentation-find-indentations))))))
+      (haskell-indentation-reindent-to (car ind)))))
+
+
+;;----------------------------------------------------------------------------
+;; Parser Starts Here
+
+;; The parser is implemented as a recursive descent parser.  Each parser
+;; advances the point to after the expression it parses, and sets the
+;; dynamic scoped variables containing the information about the
+;; indentations.  The dynamic scoping allows transparent backtracking to
+;; previous states of these variables.  A new state can be set using `let'.
+;; When the scope of this function ends, the variable is automatically
+;; reverted to its old value.
+
+;; This is basicly a performance hack.  It would have been possible to
+;; thread this state using a association-list through the parsers, but it
+;; would be probably more complicated and slower due to the lack of real
+;; closures in Emacs Lisp.
+;;
+;; When finished parsing, the tokenizer returns 'end-token, and
+;; following-token is set to the token after point.  The parser adds its
+;; indentations to possible-indentations and returns to it's parent, or
+;; exits non-locally by throwing parse-end, so that the parent will not add
+;; new indentations to it.
+
+;; the parse state:
+(defvar following-token)        ;; the next token after parsing finished
+;; the token at the current parser point or a pseudo-token (see
+;; `haskell-indentation-read-next-token')
+(defvar current-token)
+(defvar previous-token)
+(defvar left-indent)            ;; most left possible indentation
+(defvar starter-indent)         ;; column at a keyword
+(defvar current-indent)         ;; the most right indentation
+(defvar layout-indent)          ;; the column of the layout list
+(defvar possible-indentations)  ;; the return value of the indentations
+(defvar indentation-point)      ;; where to stop parsing
+(defvar implicit-layout-active) ;; is "off-side" rule active?
+
+(defun haskell-indentation-goto-least-indentation ()
+  "" ; FIXME
+  (beginning-of-line)
+  (if (haskell-indentation-bird-p)
+      (catch 'return
+        (while t
+          (when (not (eq (char-after) ?>))
+            (forward-line)
+            (forward-char 2)
+            (throw 'return nil))
+          (let ((ps (nth 8 (syntax-ppss))))
+            (when ps ;; inside comment or string
+              (goto-char ps)
+              (beginning-of-line)))
+          (when (and (>= 2 (haskell-indentation-current-indentation))
+                     (not (looking-at ">\\s-*$")))
+            (forward-char 2)
+            (throw 'return nil))
+          (when (bobp)
+            (forward-char 2)
+            (throw 'return nil))
+          (forward-line -1)))
+    ;; not bird style
+    (catch 'return
+      (while (not (bobp))
+        (let ((point (point)))
+          ;; (forward-comment -1) gets lost if there are unterminated
+          ;; string constants and does not move point anywhere. We fix
+          ;; that case with (forward-line -1)
+          (forward-comment (- (buffer-size)))
+          (if (equal (point) point)
+              (forward-line -1)
+            (beginning-of-line)))
+        (let* ((ps (syntax-ppss))
+              (start-of-comment-or-string (nth 8 ps))
+              (start-of-list-expression (nth 1 ps)))
+          (cond
+           (start-of-comment-or-string
+            ;; inside comment or string
+            (goto-char start-of-comment-or-string))
+           (start-of-list-expression
+            ;; inside a parenthesized expression
+            (goto-char start-of-list-expression))
+           ((= 0 (haskell-indentation-current-indentation))
+             (throw 'return nil))))))
+    (beginning-of-line)
+    (when (bobp)
+      (forward-comment (buffer-size)))))
+
+(defun haskell-indentation-parse-to-indentations ()
+  "" ; FIXME
+  (save-excursion
+    (skip-syntax-forward "-")
+    (let ((indentation-point (point))
+          (layout-indent 0)
+          (current-indent haskell-indentation-layout-offset)
+          (starter-indent haskell-indentation-layout-offset)
+          (left-indent haskell-indentation-layout-offset)
+          (case-fold-search nil)
+          current-token
+          previous-token
+          following-token
+          possible-indentations
+          implicit-layout-active)
+      (haskell-indentation-goto-least-indentation)
+      (if (<= indentation-point (point))
+          (haskell-indentation-first-indentation)
+        (setq current-token (haskell-indentation-peek-token))
+        (catch 'parse-end
+          (haskell-indentation-toplevel))
+        possible-indentations))))
+
+(defun haskell-indentation-first-indentation ()
+  "Return column of first indentation."
+  (list (if (haskell-indentation-bird-p) 2 0)))
+
+(defun haskell-indentation-find-indentations ()
+  "Return list of indentation positions corresponding to actual cursor position."
+  (let ((ppss (syntax-ppss)))
+    (cond
+     ((nth 3 ppss)
+      (if (save-excursion
+            (and (forward-line -1)
+                 (< (nth 8 ppss) (point))))
+          ;; if this string goes over more than one line we want to
+          ;; sync with the last line, not the first one
+          (list (save-excursion
+                  (forward-line -1)
+                  (current-indentation)))
+
+        (append
+         (haskell-indentation-first-indentation)
+         (list (save-excursion
+                 (goto-char (nth 8 ppss))
+                 (current-column))))))
+     ((nth 4 ppss)
+      (if (save-excursion
+            (and (skip-syntax-forward "-")
+                 (eolp)
+                 (not (> (forward-line 1) 0))
+                 (not (nth 4 (syntax-ppss)))))
+          (haskell-indentation-parse-to-indentations)
+        (haskell-indentation-first-indentation)))
+     (t
+      (haskell-indentation-parse-to-indentations)))))
+
+(defconst haskell-indentation-unicode-tokens
+  '(("→" . "->")     ;; #x2192 RIGHTWARDS ARROW
+    ("∷" . "::")     ;; #x2237 PROPORTION
+    ("←" . "<-")     ;; #x2190 LEFTWARDS ARROW
+    ("⇒" . "=>")     ;; #x21D2 RIGHTWARDS DOUBLE ARROW
+    ("∀" . "forall") ;; #x2200 FOR ALL
+    ("⤙" . "-<")     ;; #x2919 LEFTWARDS ARROW-TAIL
+    ("⤚" . ">-")     ;; #x291A RIGHTWARDS ARROW-TAIL
+    ("⤛" . "-<<")    ;; #x291B LEFTWARDS DOUBLE ARROW-TAIL
+    ("⤜" . ">>-")    ;; #x291C RIGHTWARDS DOUBLE ARROW-TAIL
+    ("★" . "*"))     ;; #x2605 BLACK STAR
+  "Translation from UnicodeSyntax tokens to their ASCII representation.")
+
+(defconst haskell-indentation-toplevel-list
+  `(("module"    . haskell-indentation-module)
+    ("signature" . haskell-indentation-module)
+    ("data"      . haskell-indentation-data)
+    ("type"      . haskell-indentation-data)
+    ("newtype"   . haskell-indentation-data)
+    ("import"    . haskell-indentation-import)
+    ("foreign"   . haskell-indentation-foreign)
+    ("where"     . haskell-indentation-toplevel-where)
+    ("class"     . haskell-indentation-class-declaration)
+    ("instance"  . haskell-indentation-class-declaration)
+    ("deriving"  . haskell-indentation-deriving))
+  "Alist of toplevel keywords with associated parsers.")
+
+(defconst haskell-indentation-type-list
+  `(("::" .
+     ,(apply-partially 'haskell-indentation-with-starter
+                       (apply-partially 'haskell-indentation-separated
+                                        'haskell-indentation-type '("->" "=>"))))
+    ("("  .
+     ,(apply-partially 'haskell-indentation-list
+                       'haskell-indentation-type ")" ","))
+    ("["  .
+     ,(apply-partially 'haskell-indentation-list
+                       'haskell-indentation-type "]" ","))
+    ("{"  .
+     ,(apply-partially 'haskell-indentation-list
+                       'haskell-indentation-type "}" ",")))
+  "Alist of tokens in type declarations with associated parsers.")
+
+(defconst haskell-indentation-expression-list
+  `(("data"    . haskell-indentation-data)
+    ("type"    . haskell-indentation-data)
+    ("newtype" . haskell-indentation-data)
+    ("if"      . haskell-indentation-if)
+    ("let"     .
+     ,(apply-partially 'haskell-indentation-phrase
+                       '(haskell-indentation-declaration-layout
+                         "in" haskell-indentation-expression)))
+    ("do"      .
+     ,(apply-partially 'haskell-indentation-with-starter
+                       'haskell-indentation-expression-layout))
+    ("mdo"     .
+     ,(apply-partially 'haskell-indentation-with-starter
+                       'haskell-indentation-expression-layout))
+    ("rec"     .
+     ,(apply-partially 'haskell-indentation-with-starter
+                       'haskell-indentation-expression-layout))
+    ("case"    .
+     ,(apply-partially 'haskell-indentation-phrase
+                       '(haskell-indentation-expression
+                         "of" haskell-indentation-case-layout)))
+    ("\\"      .
+     ,(apply-partially 'haskell-indentation-with-starter
+                       'haskell-indentation-lambda-maybe-lambdacase))
+    ("proc"    .
+     ,(apply-partially 'haskell-indentation-phrase
+                       '(haskell-indentation-expression
+                         "->" haskell-indentation-expression)))
+    ("where"   .
+     ,(apply-partially 'haskell-indentation-with-starter
+                       'haskell-indentation-declaration-layout nil t))
+    ("::"      .        haskell-indentation-scoped-type)
+    ("="       .
+     ,(apply-partially 'haskell-indentation-statement-right
+                       'haskell-indentation-expression))
+    ("<-"      .
+     ,(apply-partially 'haskell-indentation-statement-right
+                       'haskell-indentation-expression))
+    ("("       .
+     ,(apply-partially 'haskell-indentation-list
+                       'haskell-indentation-expression
+                       ")"
+                       '(list "," "->")))
+    ("["       .
+     ,(apply-partially 'haskell-indentation-list
+                       'haskell-indentation-expression "]" "," "|"))
+    ("{"       .
+     ,(apply-partially 'haskell-indentation-list
+                       'haskell-indentation-expression "}" ",")))
+  "Alist of keywords in expressions with associated parsers.")
+
+(defun haskell-indentation-expression-layout ()
+  "Parse layout list with expressions, such as after \"do\"."
+  (haskell-indentation-layout #'haskell-indentation-expression))
+
+(defun haskell-indentation-declaration-layout ()
+  "Parse layout list with declarations, such as after \"where\"."
+  (haskell-indentation-layout #'haskell-indentation-declaration))
+
+(defun haskell-indentation-case-layout ()
+  "Parse layout list with case expressions."
+  (haskell-indentation-layout #'haskell-indentation-case))
+
+(defun haskell-indentation-lambda-maybe-lambdacase ()
+  "Parse lambda or lambda-case expression.
+After a lambda (backslash) there are two possible cases:
+
+- the new lambdacase expression, that can be recognized by the
+  next token being \"case\";
+
+- or simply an anonymous function definition in the form of
+  \"expression -> expression\"."
+  (if (string= current-token "case")
+      (haskell-indentation-with-starter
+       #'haskell-indentation-case-layout)
+    (haskell-indentation-phrase-rest
+     '(haskell-indentation-expression "->" haskell-indentation-expression))))
+
+(defun haskell-indentation-fundep ()
+  "Parse functional dependency."
+  (haskell-indentation-with-starter
+   (apply-partially #'haskell-indentation-separated
+                    #'haskell-indentation-fundep1 ",")))
+
+(defun haskell-indentation-fundep1 ()
+  "Parse an item in functional dependency declaration."
+  (let ((current-indent (current-column)))
+    (while (member current-token '(value "->"))
+      (haskell-indentation-read-next-token))
+    (when (and (eq current-token 'end-tokens)
+               (member following-token '(value "->")))
+      (haskell-indentation-add-indentation current-indent))))
+
+(defun haskell-indentation-toplevel ()
+  "Parse toplevel statements."
+  (haskell-indentation-layout
+   (lambda ()
+     (let ((parser (assoc current-token haskell-indentation-toplevel-list)))
+       (if parser
+           (funcall (cdr parser))
+         (haskell-indentation-declaration))))))
+
+(defun haskell-indentation-type ()
+  "Parse type declaration."
+  (let ((current-indent (current-column)))
+    (catch 'return
+      (while t
+        (cond
+         ((member current-token '(value operator "->" "=>"))
+          (haskell-indentation-read-next-token))
+
+         ((eq current-token 'end-tokens)
+          (when (member following-token
+                        '(value operator no-following-token
+                                "(" "[" "{" "::"))
+            (if (equal following-token "=>")
+                (haskell-indentation-add-indentation starter-indent)
+              (haskell-indentation-add-indentation current-indent))
+            (haskell-indentation-add-indentation left-indent))
+          (throw 'return nil))
+         (t (let ((parser (assoc current-token haskell-indentation-type-list)))
+              (if (not parser)
+                  (throw 'return nil)
+                (funcall (cdr parser))))))))))
+
+(defun haskell-indentation-type-1 ()
+  "Parse a single type declaration."
+  (let ((current-indent (current-column)))
+    (catch 'return
+      (cond
+       ((member current-token '(value operator "->" "=>"))
+        (haskell-indentation-read-next-token))
+
+       ((eq current-token 'end-tokens)
+        (when (member following-token
+                      '(value operator no-following-token
+                              "->" "=>" "(" "[" "{" "::"))
+          (haskell-indentation-add-indentation current-indent))
+        (throw 'return nil))
+       (t (let ((parser (assoc current-token haskell-indentation-type-list)))
+            (if (not parser)
+                (throw 'return nil)
+              (funcall (cdr parser)))))))))
+
+(defun haskell-indentation-scoped-type ()
+  "Parse scoped type declaration.
+
+For example
+   let x :: Int = 12
+   do x :: Int <- return 12"
+  (haskell-indentation-with-starter
+   (apply-partially #'haskell-indentation-separated #'haskell-indentation-type '("->" "=>")))
+  (when (member current-token '("<-" "="))
+    (haskell-indentation-statement-right #'haskell-indentation-expression)))
+
+(defun haskell-indentation-data ()
+  "Parse data or type declaration."
+  (haskell-indentation-read-next-token)
+  (when (string= current-token "instance")
+    (haskell-indentation-read-next-token))
+  (haskell-indentation-type)
+  (cond ((eq current-token 'end-tokens)
+         (when (member following-token '("=" "where"))
+           (haskell-indentation-add-indentation current-indent)
+           (throw 'parse-end nil)))
+        ((string= current-token "=")
+         (let ((starter-indent-inside (current-column)))
+           (haskell-indentation-with-starter
+            (lambda ()
+              (haskell-indentation-separated
+               #'haskell-indentation-expression "|")))
+           (cond
+            ((equal current-token 'end-tokens)
+             (when (string= following-token "deriving")
+               (haskell-indentation-push-indentation starter-indent-inside)
+               (haskell-indentation-add-left-indent)))
+            ((equal current-token "deriving")
+             (haskell-indentation-with-starter
+              #'haskell-indentation-type-1)))))
+        ((string= current-token "where")
+         (haskell-indentation-with-starter
+          #'haskell-indentation-expression-layout nil)
+         (cond
+          ((equal current-token 'end-tokens)
+           (when (string= following-token "deriving")
+             (haskell-indentation-add-left-indent)))
+          ((equal current-token "deriving")
+           (haskell-indentation-with-starter
+            #'haskell-indentation-type-1))))))
+
+(defun haskell-indentation-import ()
+  "Parse import declaration."
+  (haskell-indentation-with-starter #'haskell-indentation-expression))
+
+(defun haskell-indentation-foreign ()
+  "Parse foreign import declaration."
+  (haskell-indentation-with-starter (apply-partially #'haskell-indentation-expression '(value operator "import"))))
+
+(defun haskell-indentation-class-declaration ()
+  "Parse class declaration."
+  (haskell-indentation-with-starter
+   (lambda ()
+     (haskell-indentation-type)
+     (when (string= current-token "|")
+       (haskell-indentation-fundep))
+     (when (string= current-token "where")
+       (haskell-indentation-with-starter
+        #'haskell-indentation-declaration-layout nil)))))
+
+(defun haskell-indentation-deriving ()
+  "Parse standalone declaration."
+  (haskell-indentation-with-starter
+   (lambda ()
+     (when (string= "instance" current-token)
+       (haskell-indentation-read-next-token))
+     (when (equal current-token 'end-tokens)
+       (haskell-indentation-add-left-indent)
+       (throw 'parse-end nil))
+     (haskell-indentation-type)
+     (when (string= current-token "|")
+       (haskell-indentation-fundep)))))
+
+(defun haskell-indentation-module ()
+  "Parse module declaration."
+  (haskell-indentation-with-starter
+   (lambda ()
+     (haskell-indentation-read-next-token)
+     (when (equal current-token 'layout-item)
+       (haskell-indentation-read-next-token))
+     (when (string= current-token "(")
+       (haskell-indentation-list
+        #'haskell-indentation-module-export
+        ")" ","))
+     (if (string= current-token "where")
+         (haskell-indentation-read-next-token)
+
+       (when (eq current-token 'end-tokens)
+         (when (member following-token '(value no-following-token "("))
+           (haskell-indentation-add-indentation
+            (+ starter-indent haskell-indentation-starter-offset))
+           (haskell-indentation-add-indentation
+            (+ left-indent haskell-indentation-starter-offset))
+           (throw 'parse-end nil))
+         (haskell-indentation-add-layout-indent)
+         (throw 'parse-end nil))))))
+
+(defun haskell-indentation-toplevel-where ()
+  "Parse 'where' that we may hit as a standalone in module declaration."
+  (haskell-indentation-read-next-token)
+
+  (when (eq current-token 'end-tokens)
+    (haskell-indentation-add-layout-indent)
+    (throw 'parse-end nil)))
+
+(defun haskell-indentation-module-export ()
+  "Parse export list."
+  (cond ((string= current-token "module")
+         (let ((current-indent (current-column)))
+           (haskell-indentation-read-next-token)
+           (cond ((eq current-token 'end-tokens)
+                  (haskell-indentation-add-indentation current-indent))
+                 ((eq current-token 'value)
+                  (haskell-indentation-read-next-token)))))
+        (t (haskell-indentation-type))))
+
+(defun haskell-indentation-list (parser end sep &optional stmt-sep)
+  "Parse a list, pair or other expression containing multiple
+items parsed by PARSER, separated by SEP or STMT-SEP, and ending
+with END."
+  ;; note that we use macro expansion here to preserver Emacs 23
+  ;; compatibility and its lack of lexical binding
+  (haskell-indentation-with-starter
+   `(lambda ()
+      (let ((implicit-layout-active nil))
+        (haskell-indentation-separated
+         #',parser ,sep ,stmt-sep)))
+   end))
+
+(defun haskell-indentation-with-starter (parser &optional end where-expr?)
+  "Parse an expression starting with a keyword or parenthesis.
+Skip the keyword or parenthesis." ; FIXME: better description needed
+  (let ((starter-column (current-column))
+        (current-indent current-indent)
+        (left-indent
+         (if (= (current-column) (haskell-indentation-current-indentation))
+             (current-column)
+           left-indent)))
+    (haskell-indentation-read-next-token)
+    (when (eq current-token 'end-tokens)
+      (cond ((equal following-token end)
+             ;; indent before keyword or parenthesis
+             (haskell-indentation-add-indentation starter-column))
+            (where-expr?
+             ;; left indent + where post indent
+             (haskell-indentation-add-where-post-indent left-indent))
+            (t
+             (haskell-indentation-add-left-indent)))
+      (throw 'parse-end nil))
+    (let* ((current-indent (current-column))
+           (starter-indent (min starter-column current-indent))
+           (left-indent
+            (if end
+                (+ starter-indent haskell-indentation-starter-offset)
+              left-indent)))
+      (funcall parser)
+      (cond ((eq current-token 'end-tokens)
+             (when (equal following-token end)
+               ;; indent before keyword or parenthesis
+               (haskell-indentation-add-indentation starter-indent))
+             ;; add no more indentations if we expect a closing keyword
+             (when end
+               (throw 'parse-end nil)))
+            ((equal current-token end)
+             (haskell-indentation-read-next-token))))))
+
+(defun haskell-indentation-case-alternative ()
+  "" ; FIXME
+  (setq left-indent (current-column))
+  (haskell-indentation-separated #'haskell-indentation-expression "," nil)
+  (cond ((eq current-token 'end-tokens)
+         (haskell-indentation-add-indentation current-indent))
+        ((string= current-token "->")
+         (haskell-indentation-statement-right #'haskell-indentation-expression))
+        ;; otherwise fallthrough
+        ))
+
+(defun haskell-indentation-case ()
+  "" ; FIXME
+  (haskell-indentation-expression)
+  (cond ((eq current-token 'end-tokens)
+         (haskell-indentation-add-indentation current-indent))
+        ((string= current-token "|")
+         (haskell-indentation-with-starter
+          (apply-partially #'haskell-indentation-separated
+                           #'haskell-indentation-case-alternative "|" nil)
+          nil))
+        ((string= current-token "->")
+         (haskell-indentation-statement-right #'haskell-indentation-expression))
+        ;; otherwise fallthrough
+        ))
+
+(defun haskell-indentation-statement-right (parser)
+  "Process right side of a statement.
+Set `current-indent' to the current column and calls the given
+parser.  If parsing ends here, set indentation to left-indent."
+  (haskell-indentation-read-next-token)
+  (when (eq current-token 'end-tokens)
+    (haskell-indentation-add-left-indent)
+    (haskell-indentation-add-indentation current-indent)
+    (throw 'parse-end nil))
+  (funcall parser)
+  (when (equal current-token "where")
+    (haskell-indentation-with-starter
+     #'haskell-indentation-expression-layout nil)))
+
+(defun haskell-indentation-guard ()
+  "Parse \"guard\" statement."
+  (setq left-indent (current-column))
+  (haskell-indentation-separated
+   #'haskell-indentation-expression "," nil))
+
+(defun haskell-indentation-declaration ()
+  "Parse function or type declaration."
+  (haskell-indentation-separated #'haskell-indentation-expression "," nil)
+  (when (string= current-token "|")
+    (haskell-indentation-with-starter
+     (apply-partially #'haskell-indentation-separated
+                      #'haskell-indentation-guard "|" nil)
+     nil))
+  (when (eq current-token 'end-tokens)
+   (when (member following-token '("|" "=" "::" ","))
+     (haskell-indentation-add-indentation current-indent)
+     (throw 'parse-end nil))))
+
+(defun haskell-indentation-layout (parser)
+  "Parse layout list, where each layout item is parsed by parser."
+  (if (string= current-token "{")
+      (haskell-indentation-list parser "}" ";") ; explicit layout
+    (haskell-indentation-implicit-layout-list parser)))
+
+(defun haskell-indentation-expression-token-p (token)
+  "Return non-NIL value if TOKEN is an expression token."
+  (member token
+          '("if" "let" "do" "case" "\\" "(" "{" "[" "::"
+            value operator no-following-token)))
+
+(defun haskell-indentation-expression (&optional accepted-tokens)
+  "Parse an expression until an unknown token is encountered."
+  (catch 'return
+    (let ((current-indent (current-column)))
+      (unless accepted-tokens
+        (setq accepted-tokens '(value operator)))
+      (while t
+        (cond
+         ((memq current-token accepted-tokens)
+          (haskell-indentation-read-next-token))
+         ((eq current-token 'end-tokens)
+          (cond ((string= following-token "where")
+                 (haskell-indentation-add-where-pre-indent)) ; before a where
+                ((haskell-indentation-expression-token-p following-token)
+                 ;; a normal expression can be either continued or have
+                 ;; left indent
+                 (haskell-indentation-add-indentation
+                  current-indent)
+                 (haskell-indentation-add-indentation
+                  left-indent)))
+          (throw 'return nil))
+         (t (let ((parser (assoc current-token
+                                 haskell-indentation-expression-list)))
+              (when (null parser)
+                (throw 'return nil)) ; not expression token, so exit
+              (funcall (cdr parser)) ; run parser
+
+              ;; after an 'open' expression such as 'if', exit
+              (unless (member (car parser) '("(" "[" "{" "case"))
+                (throw 'return nil)))))))))
+
+(defun haskell-indentation-separated (parser separator &optional stmt-separator)
+  "Evaluate PARSER separated by SEPARATOR and STMT-SEPARATOR.
+If STMT-SEPARATOR is not NIL, it will be used to set a new starter-indent.
+
+For example:
+
+   [ i | i <- [1..10]
+    ,"
+  (catch 'return
+    (unless (listp separator)
+      (setq separator (list separator)))
+    (unless (listp stmt-separator)
+      (setq stmt-separator (list stmt-separator)))
+    (while t
+      (funcall parser)
+      (cond ((member current-token separator)
+             (haskell-indentation-at-separator))
+
+            ((member current-token stmt-separator)
+             (setq starter-indent (current-column))
+             (haskell-indentation-at-separator))
+
+            ((eq current-token 'end-tokens)
+             (when (or (member following-token separator)
+                       (member following-token stmt-separator))
+               ;; Set an indentation before a separator, for example:
+               ;;  [ 1   or   [ 1 | a
+               ;;  , 2            , 20
+               (haskell-indentation-add-indentation starter-indent)
+               (when (< left-indent starter-indent)
+                 (haskell-indentation-add-indentation left-indent))
+               (throw 'parse-end nil))
+             (when (equal following-token 'no-following-token)
+               ;; Set an indentation before a separator, for example:
+               ;;  [ 1   or   [ 1 | a
+               ;;  , 2            , 20
+               (haskell-indentation-add-indentation starter-indent)
+               (haskell-indentation-add-indentation left-indent))
+             (throw 'return nil))
+            (t (throw 'return nil))))))
+
+(defun haskell-indentation-at-separator ()
+  "At a separator.
+
+If at a new line, set starter-indent at the separator
+and current-indent after the separator, for example:
+
+l = [  1
+     , 2
+     ,    -- start now here."
+  (let ((separator-column
+         (and (= (current-column) (haskell-indentation-current-indentation))
+              (current-column))))
+    (haskell-indentation-read-next-token)
+    (cond ((eq current-token 'end-tokens)
+           (haskell-indentation-add-indentation current-indent)
+           (haskell-indentation-add-indentation left-indent)
+           (throw 'return nil))
+          (separator-column ; on the beginning of the line
+           (setq current-indent (current-column))
+           (setq starter-indent separator-column)
+           (setq left-indent
+            (+ starter-indent haskell-indentation-starter-offset))))))
+
+(defun haskell-indentation-implicit-layout-list (parser)
+  "An implicit layout list, elements are parsed with PARSER.
+This sets the `layout-indent' variable to the column where the
+layout starts."
+  (let* ((layout-indent (current-column))
+         (current-indent (current-column))
+         (left-indent (current-column))
+         (implicit-layout-active t))
+    (catch 'return
+      (while t
+        (let ((left-indent left-indent))
+          (funcall parser))
+        (cond ((member current-token '(layout-item ";"))
+               (haskell-indentation-read-next-token))
+              ((eq current-token 'end-tokens)
+               (when (or (and
+                          (not (member following-token '("{" operator)))
+                          (not (member previous-token '(operator)))
+                          (haskell-indentation-expression-token-p following-token))
+                         (string= following-token ";")
+                         (and (equal layout-indent 0)
+                              (member following-token (mapcar #'car haskell-indentation-toplevel-list))
+                              (not (string= following-token "where"))))
+                 (haskell-indentation-add-layout-indent))
+               (throw 'return nil))
+              (t (throw 'return nil))))))
+  ;; put `haskell-indentation-read-next-token' outside the current-indent
+  ;; definition so it will not return 'layout-end again
+  (when (eq current-token 'layout-end)
+    (let ((implicit-layout-active t))
+      ;; leave layout at 'layout-end or illegal token
+      (haskell-indentation-read-next-token))))
+
+(defun haskell-indentation-if ()
+  "" ; FIXME
+  (haskell-indentation-with-starter
+   (lambda ()
+     (if (string= current-token "|")
+         (haskell-indentation-with-starter
+          (lambda ()
+            (haskell-indentation-separated
+             #'haskell-indentation-case-alternative "|" nil))
+          nil)
+       (haskell-indentation-phrase-rest
+        '(haskell-indentation-expression
+          "then" haskell-indentation-expression
+          "else" haskell-indentation-expression))))
+   nil))
+
+(defun haskell-indentation-phrase (phrase)
+  "" ; FIXME
+  (haskell-indentation-with-starter
+   (apply-partially #'haskell-indentation-phrase-rest phrase)
+   nil))
+
+(defun haskell-indentation-phrase-rest (phrase1)
+  "" ; FIXME
+  (while phrase1
+    (let ((phrase phrase1))
+      (setq phrase1 nil)
+      (let ((current-indent (current-column))
+            (left-indent left-indent)
+            (layout-indent layout-indent))
+        (funcall (car phrase)))
+      (cond
+       ((eq current-token 'end-tokens)
+        (cond ((null (cdr phrase))) ;; fallthrough
+              ((equal following-token (cadr phrase))
+               (haskell-indentation-add-indentation starter-indent)
+               (unless (member following-token '("," ";"))
+                 ;; we want to keep comma and semicolon aligned always
+                 (haskell-indentation-add-indentation left-indent))
+               (throw 'parse-end nil))
+              ((string= (cadr phrase) "in")
+               (when (= left-indent layout-indent)
+                 (haskell-indentation-add-layout-indent)
+                 (throw 'parse-end nil)))
+              (t (throw 'parse-end nil))))
+       ((null (cdr phrase)))
+       ((equal (cadr phrase) current-token)
+        (haskell-indentation-read-next-token)
+        (when (eq current-token 'end-tokens)
+          (haskell-indentation-add-indentation
+           (+ starter-indent haskell-indentation-starter-offset))
+          (haskell-indentation-add-indentation
+           (+ left-indent haskell-indentation-starter-offset))
+          (throw 'parse-end nil))
+        (setq phrase1 (cddr phrase)))
+       ((string= (cadr phrase) "in"))))))
+
+(defun haskell-indentation-add-indentation (indent)
+  "" ; FIXME
+  (haskell-indentation-push-indentation
+   (if (<= indent layout-indent)
+       (+ layout-indent haskell-indentation-layout-offset)
+     indent)))
+
+(defun haskell-indentation-add-layout-indent ()
+  "" ; FIXME
+  (haskell-indentation-push-indentation layout-indent))
+
+(defun haskell-indentation-add-where-pre-indent ()
+  "" ; FIXME
+  (haskell-indentation-push-indentation
+   (+ layout-indent haskell-indentation-where-pre-offset))
+  (if (= layout-indent haskell-indentation-layout-offset)
+      (haskell-indentation-push-indentation
+       haskell-indentation-where-pre-offset)))
+
+(defun haskell-indentation-add-where-post-indent (indent)
+  "" ; FIXME
+  (haskell-indentation-push-indentation
+   (+ indent haskell-indentation-where-post-offset)))
+
+(defun haskell-indentation-add-left-indent ()
+  "" ; FIXME
+  (haskell-indentation-add-indentation
+   (+ left-indent haskell-indentation-left-offset)))
+
+(defun haskell-indentation-push-indentation (indent)
+  "Add INDENT to list of possible indentations.
+
+Add INDENT to `possible-indentations' if it is not there
+yet. Keep the list in ascending order."
+  (unless (member indent possible-indentations)
+    (setq possible-indentations
+          (sort (cons indent possible-indentations) #'<))))
+
+(defun haskell-indentation-read-next-token ()
+  "Go to the next token and set current-token to the next token.
+
+The following symbols are used as pseudo tokens:
+
+'layout-item: A new item in a layout list.  The next token
+              will be the first token from the item.
+
+'layout-end:  the end of a layout list.  Next token will be
+              the first token after the layout list.
+
+'end-tokens:  back at point where we started, following-token
+              will be set to the next token.
+
+Pseudo tokens are used only when implicit-layout-active is
+t. That is the case only after keywords \"do\", \"where\",
+\"let\" and \"of\".
+
+If we are at a new line, parse-line is increased, and
+current-indent and left-indent are set to the indentation of the
+line."
+  (cond ((and implicit-layout-active
+              (eq current-token 'end-tokens))
+         'end-tokens)
+        ((and implicit-layout-active
+              (eq current-token 'layout-end))
+         (cond ((> layout-indent (current-column))
+                'layout-end)
+               ((= layout-indent (current-column))
+                (setq current-token 'layout-item))
+               ((< layout-indent (current-column))
+                (setq current-token (haskell-indentation-peek-token)))))
+        ((and implicit-layout-active
+              (eq current-token 'layout-item))
+         (setq current-token (haskell-indentation-peek-token)))
+        ((and implicit-layout-active
+              (> layout-indent (current-column)))
+         (setq current-token 'layout-end))
+        (t
+         (setq previous-token (haskell-indentation-peek-token))
+         (haskell-indentation-skip-token)
+         (if (>= (point) indentation-point)
+             (progn
+               (setq following-token
+                     (if (and (not (eobp))
+                              (= (point) indentation-point))
+                         (haskell-indentation-peek-token)
+                       'no-following-token))
+               (setq current-token 'end-tokens))
+           (when (= (current-column) (haskell-indentation-current-indentation))
+             ;; on a new line
+             (setq current-indent (current-column)))
+           (cond ((and implicit-layout-active
+                       (> layout-indent (current-column)))
+                  (setq current-token 'layout-end))
+                 ((and implicit-layout-active
+                       (= layout-indent (current-column)))
+                  (setq current-token 'layout-item))
+                 (t (setq current-token (haskell-indentation-peek-token))))))))
+
+(defun haskell-indentation-peek-token ()
+  "Return token starting at point."
+  (cond ((looking-at "\\(if\\|then\\|else\\|let\\|in\\|mdo\\|rec\\|do\\|proc\\|case\\|of\\|where\\|module\\|signature\\|deriving\\|import\\|data\\|type\\|newtype\\|class\\|instance\\)\\([^[:alnum:]'_]\\|$\\)")
+         (match-string-no-properties 1))
+        ((looking-at "[][(){}[,;]")
+         (match-string-no-properties 0))
+        ((looking-at "\\(\\\\\\|->\\|<-\\|::\\|=\\||\\|=>\\)\\([^-:!#$%&*+./<=>?@\\\\^|~]\\|$\\)")
+         (match-string-no-properties 1))
+        ((looking-at "\\(→\\|←\\|∷\\|⇒\\)\\([^-:!#$%&*+./<=>?@\\\\^|~]\\|$\\)")
+         (let ((tok (match-string-no-properties 1)))
+           (or (cdr (assoc tok haskell-indentation-unicode-tokens)) tok)))
+        ((looking-at"[-:!#$%&*+./<=>?@\\\\^|~`]" )
+         'operator)
+        (t 'value)))
+
+(defun haskell-indentation-skip-token ()
+  "Skip to the next token."
+  (if (haskell-lexeme-looking-at-token)
+      (goto-char (match-end 0))
+    ;; otherwise skip until space found
+    (skip-syntax-forward "^-"))
+  ;; we have to skip unterminated string fence at the end of line
+  (skip-chars-forward "\n")
+  (forward-comment (buffer-size))
+  (while (and (haskell-indentation-bird-p)
+              (bolp)
+              (eq (char-after) ?>))
+    (forward-char)
+    (forward-comment (buffer-size))))
+
+(provide 'haskell-indentation)
+
+;; Local Variables:
+;; tab-width: 8
+;; End:
+
+;;; haskell-indentation.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-indentation.elc b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-indentation.elc
new file mode 100644
index 0000000000..4d5b998fe2
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-indentation.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-interactive-mode.el b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-interactive-mode.el
new file mode 100644
index 0000000000..c218c6c3fa
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-interactive-mode.el
@@ -0,0 +1,1129 @@
+;;; haskell-interactive-mode.el --- The interactive Haskell mode -*- lexical-binding: t -*-
+
+;; Copyright © 2011-2012  Chris Done
+;;             2016       Arthur Fayzrakhmanov
+
+;; Author: Chris Done <chrisdone@gmail.com>
+
+;; This file is not part of GNU Emacs.
+
+;; This file 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, or (at your option)
+;; any later version.
+
+;; This file 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; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;;; Todo:
+
+;;; Code:
+
+(require 'haskell-mode)
+(require 'haskell-compile)
+(require 'haskell-process)
+(require 'haskell-session)
+(require 'haskell-font-lock)
+(require 'haskell-presentation-mode)
+(require 'haskell-utils)
+(require 'haskell-string)
+(require 'ansi-color)
+(require 'cl-lib)
+(require 'etags)
+
+(defvar-local haskell-interactive-mode-history-index 0)
+
+(defvar-local haskell-interactive-mode-history (list))
+
+(defvar-local haskell-interactive-mode-old-prompt-start nil
+  "Mark used for the old beginning of the prompt.")
+
+(defun haskell-interactive-prompt-regex ()
+  "Generate a regex for searching for any occurence of the prompt\
+at the beginning of the line.  This should prevent any
+interference with prompts that look like haskell expressions."
+  (concat "^" (regexp-quote haskell-interactive-prompt)))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Globals used internally
+
+(declare-function haskell-interactive-kill "haskell")
+
+(defvar haskell-interactive-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "RET") 'haskell-interactive-mode-return)
+    (define-key map (kbd "SPC") 'haskell-interactive-mode-space)
+    (define-key map (kbd "C-j") 'haskell-interactive-mode-newline-indent)
+    (define-key map (kbd "C-a") 'haskell-interactive-mode-beginning)
+    (define-key map (kbd "<home>") 'haskell-interactive-mode-beginning)
+    (define-key map (kbd "C-c C-k") 'haskell-interactive-mode-clear)
+    (define-key map (kbd "C-c C-c") 'haskell-process-interrupt)
+    (define-key map (kbd "C-c C-f") 'next-error-follow-minor-mode)
+    (define-key map (kbd "C-c C-z") 'haskell-interactive-switch-back)
+    (define-key map (kbd "M-p") 'haskell-interactive-mode-history-previous)
+    (define-key map (kbd "M-n") 'haskell-interactive-mode-history-next)
+    (define-key map (kbd "C-c C-p") 'haskell-interactive-mode-prompt-previous)
+    (define-key map (kbd "C-c C-n") 'haskell-interactive-mode-prompt-next)
+    (define-key map (kbd "C-<up>") 'haskell-interactive-mode-history-previous)
+    (define-key map (kbd "C-<down>") 'haskell-interactive-mode-history-next)
+    (define-key map (kbd "TAB") 'haskell-interactive-mode-tab)
+    (define-key map (kbd "<C-S-backspace>") 'haskell-interactive-mode-kill-whole-line)
+    map)
+  "Keymap used in `haskell-interactive-mode'.")
+
+(define-derived-mode haskell-interactive-mode fundamental-mode "Interactive-Haskell"
+  "Interactive mode for Haskell.
+
+Key bindings:
+\\{haskell-interactive-mode-map}"
+  :group 'haskell-interactive
+  :syntax-table haskell-mode-syntax-table
+
+  (setq haskell-interactive-mode-history (list))
+  (setq haskell-interactive-mode-history-index 0)
+
+  (setq next-error-function #'haskell-interactive-next-error-function)
+  (add-hook 'completion-at-point-functions
+            #'haskell-interactive-mode-completion-at-point-function nil t)
+  (add-hook 'kill-buffer-hook #'haskell-interactive-kill nil t)
+  (haskell-interactive-mode-prompt))
+
+(defvar haskell-interactive-mode-prompt-start
+  nil
+  "Mark used for the beginning of the prompt.")
+
+(defvar haskell-interactive-mode-result-end
+  nil
+  "Mark used to figure out where the end of the current result output is.
+Used to distinguish betwen user input.")
+
+(defvar-local haskell-interactive-previous-buffer nil
+  "Records the buffer to which `haskell-interactive-switch-back' should jump.
+This is set by `haskell-interactive-switch', and should otherwise
+be nil.")
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Hooks
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Mode
+
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Faces
+
+;;;###autoload
+(defface haskell-interactive-face-prompt
+  '((t :inherit font-lock-function-name-face))
+  "Face for the prompt."
+  :group 'haskell-interactive)
+
+;;;###autoload
+(defface haskell-interactive-face-prompt2
+  '((t :inherit font-lock-keyword-face))
+  "Face for the prompt2 in multi-line mode."
+  :group 'haskell-interactive)
+
+;;;###autoload
+(defface haskell-interactive-face-compile-error
+  '((t :inherit compilation-error))
+  "Face for compile errors."
+  :group 'haskell-interactive)
+
+;;;###autoload
+(defface haskell-interactive-face-compile-warning
+  '((t :inherit compilation-warning))
+  "Face for compiler warnings."
+  :group 'haskell-interactive)
+
+;;;###autoload
+(defface haskell-interactive-face-result
+  '((t :inherit font-lock-string-face))
+  "Face for the result."
+  :group 'haskell-interactive)
+
+;;;###autoload
+(defface haskell-interactive-face-garbage
+  '((t :inherit font-lock-string-face))
+  "Face for trailing garbage after a command has completed."
+  :group 'haskell-interactive)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Actions
+
+(defun haskell-interactive-mode-newline-indent ()
+  "Make newline and indent."
+  (interactive)
+  (newline)
+  (indent-to (length haskell-interactive-prompt))
+  (indent-relative))
+
+(defun haskell-interactive-mode-kill-whole-line ()
+  "Kill the whole REPL line."
+  (interactive)
+  (kill-region haskell-interactive-mode-prompt-start
+               (line-end-position)))
+
+(defun haskell-interactive-switch-back ()
+  "Switch back to the buffer from which this interactive buffer was reached."
+  (interactive)
+  (if haskell-interactive-previous-buffer
+      (switch-to-buffer-other-window haskell-interactive-previous-buffer)
+    (message "No previous buffer.")))
+
+(defun haskell-interactive-copy-to-prompt ()
+  "Copy the current line to the prompt, overwriting the current prompt."
+  (interactive)
+  (let ((l (buffer-substring-no-properties (line-beginning-position)
+                                           (line-end-position))))
+    ;; If it looks like the prompt is at the start of the line, chop
+    ;; it off.
+    (when (and (>= (length l) (length haskell-interactive-prompt))
+               (string= (substring l 0 (length haskell-interactive-prompt))
+                        haskell-interactive-prompt))
+      (setq l (substring l (length haskell-interactive-prompt))))
+
+    (haskell-interactive-mode-set-prompt l)))
+
+(defun haskell-interactive-mode-space (n)
+  "Handle the space key."
+  (interactive "p")
+  (if (and (bound-and-true-p god-local-mode)
+           (fboundp 'god-mode-self-insert))
+      (call-interactively 'god-mode-self-insert)
+    (if (haskell-interactive-at-compile-message)
+        (next-error-no-select 0)
+      (self-insert-command n))))
+
+(defun haskell-interactive-at-prompt (&optional end-line)
+  "If at prompt, return start position of user-input, otherwise return nil.
+If END-LINE is non-nil, then return non-nil when the end of line
+is at the prompt."
+  (if (>= (if end-line (line-end-position) (point))
+          haskell-interactive-mode-prompt-start)
+      haskell-interactive-mode-prompt-start
+    nil))
+
+(define-derived-mode haskell-error-mode
+  special-mode "Error"
+  "Major mode for viewing Haskell compile errors.")
+
+;; (define-key haskell-error-mode-map (kbd "q") 'quit-window)
+
+(defun haskell-interactive-mode-handle-h ()
+  "Handle ^H in output."
+  (let ((bound (point-min))
+        (inhibit-read-only t))
+    (save-excursion
+      (while (search-backward "\b" bound t 1)
+        (save-excursion
+          (forward-char)
+          (let ((end (point)))
+            (if (search-backward-regexp "[^\b]" bound t 1)
+                (forward-char)
+              (goto-char (point-min)))
+            (let ((start (point)))
+              (delete-region (max (- (point) (- end start))
+                                  (point-min))
+                             end))))))))
+
+(defun haskell-interactive-mode-multi-line (expr)
+  "If a multi-line expression EXPR has been entered, then reformat it to be:
+
+:{
+do the
+   multi-liner
+   expr
+:}"
+  (if (not (string-match-p "\n" expr))
+      expr
+    (let ((pre (format "^%s" (regexp-quote haskell-interactive-prompt)))
+          (lines (split-string expr "\n")))
+      (cl-loop for elt on (cdr lines) do
+               (setcar elt (replace-regexp-in-string pre "" (car elt))))
+      ;; Temporarily set prompt2 to be empty to avoid unwanted output
+      (concat ":set prompt2 \"\"\n"
+              ":{\n"
+              (mapconcat #'identity lines "\n")
+              "\n:}\n"
+              (format ":set prompt2 \"%s\"" haskell-interactive-prompt2)))))
+
+(defun haskell-interactive-mode-line-is-query (line)
+  "Is LINE actually a :t/:k/:i?"
+  (and (string-match "^:[itk] " line)
+       t))
+
+(defun haskell-interactive-mode-beginning ()
+  "Go to the start of the line."
+  (interactive)
+  (if (haskell-interactive-at-prompt)
+      (goto-char haskell-interactive-mode-prompt-start)
+    (move-beginning-of-line nil)))
+
+(defun haskell-interactive-mode-input-partial ()
+  "Get the interactive mode input up to point."
+  (let ((input-start (haskell-interactive-at-prompt)))
+    (unless input-start
+      (error "not at prompt"))
+    (buffer-substring-no-properties input-start (point))))
+
+(defun haskell-interactive-mode-input ()
+  "Get the interactive mode input."
+  (buffer-substring-no-properties
+   haskell-interactive-mode-prompt-start
+   (point-max)))
+
+(defun haskell-interactive-mode-prompt (&optional session)
+  "Show a prompt at the end of the REPL buffer.
+If SESSION is non-nil, use the REPL buffer associated with
+SESSION, otherwise operate on the current buffer."
+  (with-current-buffer (if session
+                           (haskell-session-interactive-buffer session)
+                         (current-buffer))
+    (save-excursion
+      (goto-char (point-max))
+      (let ((prompt (propertize haskell-interactive-prompt
+                                'font-lock-face 'haskell-interactive-face-prompt
+                                'prompt t
+                                'read-only haskell-interactive-prompt-read-only
+                                'rear-nonsticky t)))
+        ;; At the time of writing, front-stickying the first char gives an error
+        ;; Has unfortunate side-effect of being able to insert before the prompt
+        (insert (substring prompt 0 1)
+                (propertize (substring prompt 1)
+                            'front-sticky t)))
+      (let ((marker (setq-local haskell-interactive-mode-prompt-start (make-marker))))
+        (set-marker marker (point))))
+    (when (haskell-interactive-at-prompt t)
+      (haskell-interactive-mode-scroll-to-bottom))))
+
+(defun haskell-interactive-mode-eval-result (session text)
+  "Insert the result of an eval as plain text."
+  (with-current-buffer (haskell-session-interactive-buffer session)
+    (let ((at-end (eobp))
+          (prop-text (propertize text
+                                 'font-lock-face 'haskell-interactive-face-result
+                                 'front-sticky t
+                                 'prompt t
+                                 'read-only haskell-interactive-mode-read-only
+                                 'rear-nonsticky t
+                                 'result t)))
+      (save-excursion
+        (goto-char (point-max))
+        (when (string= text haskell-interactive-prompt2)
+          (setq prop-text
+                (propertize prop-text
+                            'font-lock-face 'haskell-interactive-face-prompt2
+                            'read-only haskell-interactive-prompt-read-only)))
+        (insert (ansi-color-apply prop-text))
+        (haskell-interactive-mode-handle-h)
+        (let ((marker (setq-local haskell-interactive-mode-result-end (make-marker))))
+          (set-marker marker (point))))
+      (when at-end
+        (haskell-interactive-mode-scroll-to-bottom)))))
+
+(defun haskell-interactive-mode-scroll-to-bottom ()
+  "Scroll to bottom."
+  (let ((w (get-buffer-window (current-buffer))))
+    (when w
+      (goto-char (point-max))
+      (set-window-point w (point)))))
+
+(defun haskell-interactive-mode-compile-error (session message)
+  "Echo an error."
+  (haskell-interactive-mode-compile-message
+   session message 'haskell-interactive-face-compile-error))
+
+(defun haskell-interactive-mode-compile-warning (session message)
+  "Warning message."
+  (haskell-interactive-mode-compile-message
+   session message 'haskell-interactive-face-compile-warning))
+
+(defun haskell-interactive-mode-compile-message (session message type)
+  "Echo a compiler warning."
+  (with-current-buffer (haskell-session-interactive-buffer session)
+    (setq next-error-last-buffer (current-buffer))
+    (save-excursion
+      (haskell-interactive-mode-goto-end-point)
+      (let ((lines (string-match "^\\(.*\\)\n\\([[:unibyte:][:nonascii:]]+\\)" message)))
+        (if lines
+            (progn
+              (insert (propertize (concat (match-string 1 message) " …\n")
+                                  'expandable t
+                                  'font-lock-face type
+                                  'front-sticky t
+                                  'read-only haskell-interactive-mode-read-only
+                                  'rear-nonsticky t))
+              (insert (propertize (concat (match-string 2 message) "\n")
+                                  'collapsible t
+                                  'font-lock-face type
+                                  'front-sticky t
+                                  'invisible haskell-interactive-mode-hide-multi-line-errors
+                                  'message-length (length (match-string 2 message))
+                                  'read-only haskell-interactive-mode-read-only
+                                  'rear-nonsticky t)))
+          (insert (propertize (concat message "\n")
+                              'font-lock-face type
+                              'front-sticky t
+                              'read-only haskell-interactive-mode-read-only
+                              'rear-nonsticky t)))))))
+
+(defun haskell-interactive-mode-insert (session message)
+  "Echo a read only piece of text before the prompt."
+  (with-current-buffer (haskell-session-interactive-buffer session)
+    (save-excursion
+      (haskell-interactive-mode-goto-end-point)
+      (insert (propertize message
+                          'front-sticky t
+                          'read-only t
+                          'rear-nonsticky t)))))
+
+(defun haskell-interactive-mode-goto-end-point ()
+  "Go to the 'end' of the buffer (before the prompt)."
+  (goto-char haskell-interactive-mode-prompt-start)
+  (goto-char (line-beginning-position)))
+
+(defun haskell-interactive-mode-history-add (input)
+  "Add INPUT to the history."
+  (setq haskell-interactive-mode-history
+        (cons ""
+              (cons input
+                    (cl-remove-if (lambda (i) (or (string= i input) (string= i "")))
+                                  haskell-interactive-mode-history))))
+  (setq haskell-interactive-mode-history-index
+        0))
+
+(defun haskell-interactive-mode-tab ()
+  "Do completion if at prompt or else try collapse/expand."
+  (interactive)
+  (cond
+   ((haskell-interactive-at-prompt)
+    (completion-at-point))
+   ((get-text-property (point) 'collapsible)
+    (let ((column (current-column)))
+      (search-backward-regexp "^[^ ]")
+      (haskell-interactive-mode-tab-expand)
+      (goto-char (+ column (line-beginning-position)))))
+   (t (haskell-interactive-mode-tab-expand))))
+
+(defun haskell-interactive-mode-tab-expand ()
+  "Expand the rest of the message."
+  (cond ((get-text-property (point) 'expandable)
+         (let* ((pos (1+ (line-end-position)))
+                (visibility (get-text-property pos 'invisible))
+                (length (1+ (get-text-property pos 'message-length))))
+           (let ((inhibit-read-only t))
+             (put-text-property pos
+                                (+ pos length)
+                                'invisible
+                                (not visibility)))))))
+
+(defconst haskell-interactive-mode-error-regexp
+  "^\\(\\(?:[A-Z]:\\)?[^ \r\n:][^\r\n:]*\\):\\([0-9()-:]+\\):?")
+
+(defun haskell-interactive-at-compile-message ()
+  "Am I on a compile message?"
+  (and (not (haskell-interactive-at-prompt))
+       (save-excursion
+         (goto-char (line-beginning-position))
+         (looking-at haskell-interactive-mode-error-regexp))))
+
+(defun haskell-interactive-mode-error-backward (&optional count)
+  "Go backward to the previous error."
+  (interactive)
+  (search-backward-regexp haskell-interactive-mode-error-regexp nil t count))
+
+(defun haskell-interactive-mode-error-forward (&optional count)
+  "Go forward to the next error, or return to the REPL."
+  (interactive)
+  (goto-char (line-end-position))
+  (if (search-forward-regexp haskell-interactive-mode-error-regexp nil t count)
+      (progn (goto-char (line-beginning-position))
+             t)
+    (progn (goto-char (point-max))
+           nil)))
+
+(defun haskell-interactive-mode-delete-compile-messages (session &optional file-name)
+  "Delete compile messages in REPL buffer.
+If FILE-NAME is non-nil, restrict to removing messages concerning
+FILE-NAME only."
+  (with-current-buffer (haskell-session-interactive-buffer session)
+    (save-excursion
+      (goto-char (point-min))
+      (when (search-forward-regexp "^Compilation failed.$" nil t 1)
+        (let ((inhibit-read-only t))
+          (delete-region (line-beginning-position)
+                         (1+ (line-end-position))))
+        (goto-char (point-min)))
+      (while (when (re-search-forward haskell-interactive-mode-error-regexp nil t)
+               (let ((msg-file-name (match-string-no-properties 1))
+                     (msg-startpos (line-beginning-position)))
+                 ;; skip over hanging continuation message lines
+                 (while (progn (forward-line) (looking-at "^[ ]+")))
+
+                 (when (or (not file-name) (string= file-name msg-file-name))
+                   (let ((inhibit-read-only t))
+                     (set-text-properties msg-startpos (point) nil))
+                   (delete-region msg-startpos (point))
+                   ))
+               t)))))
+
+;;;###autoload
+(defun haskell-interactive-mode-reset-error (session)
+  "Reset the error cursor position."
+  (interactive)
+  (with-current-buffer (haskell-session-interactive-buffer session)
+    (haskell-interactive-mode-goto-end-point)
+    (let ((mrk (point-marker)))
+      (haskell-session-set session 'next-error-locus nil)
+      (haskell-session-set session 'next-error-region (cons mrk (copy-marker mrk t))))
+    (goto-char (point-max))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Misc
+
+(declare-function haskell-interactive-switch "haskell")
+(declare-function haskell-session "haskell")
+
+(defun haskell-session-interactive-buffer (s)
+  "Get the session interactive buffer."
+  (let ((buffer (haskell-session-get s 'interactive-buffer)))
+    (if (and buffer (buffer-live-p buffer))
+        buffer
+      (let ((buffer-name (format "*%s*" (haskell-session-name s)))
+            (index 0))
+        (while (get-buffer buffer-name)
+          (setq buffer-name (format "*%s <%d>*" (haskell-session-name s) index))
+          (setq index (1+ index)))
+        (let ((buffer (get-buffer-create buffer-name)))
+          (haskell-session-set-interactive-buffer s buffer)
+          (with-current-buffer buffer
+            (haskell-interactive-mode)
+            (haskell-session-assign s))
+          (haskell-interactive-switch)
+          buffer)))))
+
+(defun haskell-interactive-buffer ()
+  "Get the interactive buffer of the session."
+  (haskell-session-interactive-buffer (haskell-session)))
+
+(defun haskell-process-cabal-live (state buffer)
+  "Do live updates for Cabal processes."
+  (haskell-interactive-mode-insert
+   (haskell-process-session (cadr state))
+   (replace-regexp-in-string
+    haskell-process-prompt-regex
+    ""
+    (substring buffer (cl-cadddr state))))
+  (setf (cl-cdddr state) (list (length buffer)))
+  nil)
+
+(defun haskell-process-parse-error (string)
+  "Parse the line number from the error string STRING."
+  (let ((span nil))
+    (cl-loop for regex
+             in haskell-compilation-error-regexp-alist
+             do (when (string-match (car regex) string)
+                  (setq span
+                        (list :file (match-string 1 string)
+                              :line (string-to-number (match-string 2 string))
+                              :col (string-to-number (match-string 4 string))
+                              :line2 (when (match-string 3 string)
+                                       (string-to-number (match-string 3 string)))
+                              :col2 (when (match-string 5 string)
+                                      (string-to-number (match-string 5 string)))))))
+    span))
+
+(defun haskell-process-suggest-add-package (session msg)
+  "Add the (matched) module to your cabal file.
+Cabal file is selected using SESSION's name, module matching is done in MSG."
+  (let* ((suggested-package (match-string 1 msg))
+         (package-name (replace-regexp-in-string "-[^-]+$" "" suggested-package))
+         (version (progn (string-match "\\([^-]+\\)$" suggested-package)
+                         (match-string 1 suggested-package)))
+         (cabal-file (concat (haskell-session-name session)
+                             ".cabal")))
+    (haskell-mode-toggle-interactive-prompt-state)
+    (unwind-protect
+        (when (y-or-n-p
+               (format "Add `%s' to %s?"
+                       package-name
+                       cabal-file))
+          (haskell-cabal-add-dependency package-name version nil t)
+          (when (y-or-n-p (format "Enable -package %s in the GHCi session?" package-name))
+            (haskell-process-queue-without-filters
+             (haskell-session-process session)
+             (format ":set -package %s" package-name))))
+      (haskell-mode-toggle-interactive-prompt-state t))))
+
+(defun haskell-process-suggest-remove-import (session file import line)
+  "Suggest removing or commenting out import statement.
+Asks user to handle redundant import statement using interactive
+SESSION in specified FILE to remove IMPORT on given LINE."
+  (let ((first t))
+    (haskell-mode-toggle-interactive-prompt-state)
+    (unwind-protect
+        (cl-case (read-event
+                  (propertize (format "%sThe import line `%s' is redundant. Remove? (y, n, c: comment out)  "
+                                      (if (not first)
+                                          "Please answer n, y or c: "
+                                        "")
+                                      import)
+                              'face
+                              'minibuffer-prompt))
+          (?y
+           (haskell-process-find-file session file)
+           (save-excursion
+             (goto-char (point-min))
+             (forward-line (1- line))
+             (goto-char (line-beginning-position))
+             (delete-region (line-beginning-position)
+                            (line-end-position))))
+          (?n
+           (message "Ignoring redundant import %s" import))
+          (?c
+           (haskell-process-find-file session file)
+           (save-excursion
+             (goto-char (point-min))
+             (forward-line (1- line))
+             (goto-char (line-beginning-position))
+             (insert "-- "))))
+      ;; unwind
+      (haskell-mode-toggle-interactive-prompt-state t))))
+
+(defun haskell-process-find-file (session file)
+  "Find the given file in the project."
+  (find-file (cond ((file-exists-p (concat (haskell-session-current-dir session) "/" file))
+                    (concat (haskell-session-current-dir session) "/" file))
+                   ((file-exists-p (concat (haskell-session-cabal-dir session) "/" file))
+                    (concat (haskell-session-cabal-dir session) "/" file))
+                   (t file))))
+
+(defun haskell-process-suggest-pragma (session pragma extension file)
+  "Suggest to add something to the top of the file.
+SESSION is used to search given file.  Adds PRAGMA and EXTENSION
+wrapped in compiler directive at the top of FILE."
+  (let ((string  (format "{-# %s %s #-}" pragma extension)))
+    (haskell-mode-toggle-interactive-prompt-state)
+    (unwind-protect
+        (when (y-or-n-p (format "Add %s to the top of the file? " string))
+          (haskell-process-find-file session file)
+          (save-excursion
+            (goto-char (point-min))
+            (insert (concat string "\n"))))
+      (haskell-mode-toggle-interactive-prompt-state t))))
+
+(defun haskell-interactive-mode-insert-error (response)
+  "Insert an error message."
+  (insert "\n"
+          (haskell-fontify-as-mode
+           response
+           'haskell-mode))
+  (haskell-interactive-mode-prompt))
+
+(defun haskell-interactive-popup-error (response)
+  "Popup an error."
+  (if haskell-interactive-popup-errors
+      (let ((buf (get-buffer-create "*HS-Error*")))
+        (pop-to-buffer buf nil t)
+        (with-current-buffer buf
+
+          (haskell-error-mode)
+          (let ((inhibit-read-only t))
+            (erase-buffer)
+            (insert (propertize response
+                                'font-lock-face
+                                'haskell-interactive-face-compile-error))
+            (goto-char (point-min))
+            (delete-blank-lines)
+            (insert (propertize "-- Hit `q' to close this window.\n\n"
+                                'font-lock-face 'font-lock-comment-face))
+            (save-excursion
+              (goto-char (point-max))
+              (insert (propertize "\n-- To disable popups, customize `haskell-interactive-popup-errors'.\n\n"
+                                  'font-lock-face 'font-lock-comment-face))))))
+    (haskell-interactive-mode-insert-error response)))
+
+(defun haskell-interactive-next-error-function (&optional n reset)
+  "See `next-error-function' for more information."
+
+  (let* ((session (haskell-interactive-session))
+         (next-error-region (haskell-session-get session 'next-error-region))
+         (next-error-locus (haskell-session-get session 'next-error-locus))
+         (reset-locus nil))
+
+    (when (and next-error-region (or reset (and (/= n 0) (not next-error-locus))))
+      (goto-char (car next-error-region))
+      (unless (looking-at haskell-interactive-mode-error-regexp)
+        (haskell-interactive-mode-error-forward))
+
+      (setq reset-locus t)
+      (unless (looking-at haskell-interactive-mode-error-regexp)
+        (error "no errors found")))
+
+    ;; move point if needed
+    (cond
+     (reset-locus nil)
+     ((> n 0) (unless (haskell-interactive-mode-error-forward n)
+                (error "no more errors")))
+
+     ((< n 0) (unless (haskell-interactive-mode-error-backward (- n))
+                (error "no more errors"))))
+
+    (let ((orig-line (buffer-substring-no-properties (line-beginning-position) (line-end-position))))
+
+      (when (string-match haskell-interactive-mode-error-regexp orig-line)
+        (let* ((msgmrk (set-marker (make-marker) (line-beginning-position)))
+               (location (haskell-process-parse-error orig-line))
+               (file (plist-get location :file))
+               (line (plist-get location :line))
+               (col1 (plist-get location :col))
+               (col2 (plist-get location :col2))
+
+               (cabal-relative-file (expand-file-name file (haskell-session-cabal-dir session)))
+               (src-relative-file (expand-file-name file (haskell-session-current-dir session)))
+
+               (real-file (cond ((file-exists-p cabal-relative-file) cabal-relative-file)
+                                ((file-exists-p src-relative-file) src-relative-file))))
+
+          (haskell-session-set session 'next-error-locus msgmrk)
+
+          (if real-file
+              (let ((m1 (make-marker))
+                    (m2 (make-marker)))
+                (with-current-buffer (find-file-noselect real-file)
+                  (save-excursion
+                    (goto-char (point-min))
+                    (forward-line (1- line))
+                    (set-marker m1 (+ col1 (point) -1))
+
+                    (when col2
+                      (set-marker m2 (- (point) col2)))))
+                ;; ...finally select&hilight error locus
+                (compilation-goto-locus msgmrk m1 (and (marker-position m2) m2)))
+            (error "don't know where to find %S" file)))))))
+
+(defun haskell-interactive-session ()
+  "Get the `haskell-session', throw an error if it's not available."
+  (or (haskell-session-maybe)
+      (haskell-session-assign
+       (or (haskell-session-from-buffer)
+           (haskell-session-choose)
+           (error "No session associated with this buffer. Try M-x haskell-session-change or report this as a bug.")))))
+
+(defun haskell-interactive-process ()
+  "Get the Haskell session."
+  (or (haskell-session-process (haskell-interactive-session))
+      (error "No Haskell session/process associated with this
+      buffer. Maybe run M-x haskell-process-restart?")))
+
+(defun haskell-interactive-mode-do-presentation (expr)
+  "Present the given expression EXPR.
+Requires the `present' package to be installed.
+Will automatically import it qualified as Present."
+  (let ((p (haskell-interactive-process)))
+    ;; If Present.code isn't available, we probably need to run the
+    ;; setup.
+    (unless (string-match "^Present" (haskell-process-queue-sync-request p ":t Present.encode"))
+      (haskell-interactive-mode-setup-presentation p))
+    ;; Happily, let statements don't affect the `it' binding in any
+    ;; way, so we can fake it, no pun intended.
+    (let ((error (haskell-process-queue-sync-request
+                  p (concat "let it = Present.asData (" expr ")"))))
+      (if (not (string= "" error))
+          (haskell-interactive-mode-eval-result (haskell-interactive-session) (concat error "\n"))
+        (let ((hash (haskell-interactive-mode-presentation-hash)))
+          (haskell-process-queue-sync-request
+           p (format "let %s = Present.asData (%s)" hash expr))
+          (let* ((presentation (haskell-interactive-mode-present-id
+                                hash
+                                (list 0))))
+            (insert "\n")
+            (haskell-interactive-mode-insert-presentation hash presentation)
+            (haskell-interactive-mode-eval-result (haskell-interactive-session) "\n"))))
+      (haskell-interactive-mode-prompt (haskell-interactive-session)))))
+
+(defun haskell-interactive-mode-present-id (hash id)
+  "Generate a presentation for the current expression at ID."
+  ;; See below for commentary of this statement.
+  (let ((p (haskell-interactive-process)))
+    (haskell-process-queue-without-filters
+     p "let _it = it")
+    (let* ((text (haskell-process-queue-sync-request
+                  p
+                  (format "Present.putStr (Present.encode (Present.fromJust (Present.present (Present.fromJust (Present.fromList [%s])) %s)))"
+                          (mapconcat 'identity (mapcar 'number-to-string id) ",")
+                          hash)))
+           (reply
+            (if (string-match "^*** " text)
+                '((rep nil))
+              (read text))))
+      ;; Not necessary, but nice to restore it to the expression that
+      ;; the user actually typed in.
+      (haskell-process-queue-without-filters
+       p "let it = _it")
+      reply)))
+
+(defun haskell-presentation-present-slot (btn)
+  "The callback to evaluate the slot and present it in place of the button BTN."
+  (let ((id (button-get btn 'presentation-id))
+        (hash (button-get btn 'hash))
+        (parent-rep (button-get btn 'parent-rep))
+        (continuation (button-get btn 'continuation)))
+    (let ((point (point)))
+      (button-put btn 'invisible t)
+      (delete-region (button-start btn) (button-end btn))
+      (haskell-interactive-mode-insert-presentation
+       hash
+       (haskell-interactive-mode-present-id hash id)
+       parent-rep
+       continuation)
+      (when (> (point) point)
+        (goto-char (1+ point))))))
+
+(defun haskell-interactive-mode-presentation-slot (hash slot parent-rep &optional continuation)
+  "Make a slot at point, pointing to ID."
+  (let ((type (car slot))
+        (id (cadr slot)))
+    (if (member (intern type) '(Integer Char Int Float Double))
+        (haskell-interactive-mode-insert-presentation
+         hash
+         (haskell-interactive-mode-present-id hash id)
+         parent-rep
+         continuation)
+      (haskell-interactive-mode-presentation-slot-button slot parent-rep continuation hash))))
+
+(defun haskell-interactive-mode-presentation-slot-button (slot parent-rep continuation hash)
+  (let ((start (point))
+        (type (car slot))
+        (id (cadr slot)))
+    (insert (propertize type 'font-lock-face '(:height 0.8 :underline t :inherit font-lock-comment-face)))
+    (let ((button (make-text-button start (point)
+                                    :type 'haskell-presentation-slot-button)))
+      (button-put button 'hide-on-click t)
+      (button-put button 'presentation-id id)
+      (button-put button 'parent-rep parent-rep)
+      (button-put button 'continuation continuation)
+      (button-put button 'hash hash))))
+
+(defun haskell-interactive-mode-insert-presentation (hash presentation &optional parent-rep continuation)
+  "Insert the presentation, hooking up buttons for each slot."
+  (let* ((rep (cadr (assoc 'rep presentation)))
+         (text (cadr (assoc 'text presentation)))
+         (slots (cadr (assoc 'slots presentation)))
+         (nullary (null slots)))
+    (cond
+     ((string= "integer" rep)
+      (insert (propertize text 'font-lock-face 'font-lock-constant)))
+     ((string= "floating" rep)
+      (insert (propertize text 'font-lock-face 'font-lock-constant)))
+     ((string= "char" rep)
+      (insert (propertize
+               (if (string= "string" parent-rep)
+                   (replace-regexp-in-string "^'\\(.+\\)'$" "\\1" text)
+                 text)
+               'font-lock-face 'font-lock-string-face)))
+     ((string= "tuple" rep)
+      (insert "(")
+      (let ((first t))
+        (cl-loop for slot in slots
+                 do (unless first (insert ","))
+                 do (haskell-interactive-mode-presentation-slot hash slot rep)
+                 do (setq first nil)))
+      (insert ")"))
+     ((string= "list" rep)
+      (if (null slots)
+          (if continuation
+              (progn (delete-char -1)
+                     (delete-indentation))
+            (insert "[]"))
+        (let ((i 0))
+          (unless continuation
+            (insert "["))
+          (let ((start-column (current-column)))
+            (cl-loop for slot in slots
+                     do (haskell-interactive-mode-presentation-slot
+                         hash
+                         slot
+                         rep
+                         (= i (1- (length slots))))
+                     do (when (not (= i (1- (length slots))))
+                          (insert "\n")
+                          (indent-to (1- start-column))
+                          (insert ","))
+                     do (setq i (1+ i))))
+          (unless continuation
+            (insert "]")))))
+     ((string= "string" rep)
+      (unless (string= "string" parent-rep)
+        (insert (propertize "\"" 'font-lock-face 'font-lock-string-face)))
+      (cl-loop for slot in slots
+               do (haskell-interactive-mode-presentation-slot hash slot rep))
+      (unless (string= "string" parent-rep)
+        (insert (propertize "\"" 'font-lock-face 'font-lock-string-face))))
+     ((string= "alg" rep)
+      (when (and parent-rep
+                 (not nullary)
+                 (not (string= "list" parent-rep)))
+        (insert "("))
+      (let ((start-column (current-column)))
+        (insert (propertize text 'font-lock-face 'font-lock-type-face))
+        (cl-loop for slot in slots
+                 do (insert "\n")
+                 do (indent-to (+ 2 start-column))
+                 do (haskell-interactive-mode-presentation-slot hash slot rep)))
+      (when (and parent-rep
+                 (not nullary)
+                 (not (string= "list" parent-rep)))
+        (insert ")")))
+     ((string= "record" rep)
+      (let ((start-column (current-column)))
+        (insert (propertize text 'font-lock-face 'font-lock-type-face)
+                " { ")
+        (cl-loop for field in slots
+                 do (insert "\n")
+                 do (indent-to (+ 2 start-column))
+                 do (let ((name (nth 0 field))
+                          (slot (nth 1 field)))
+                      (insert name " = ")
+                      (haskell-interactive-mode-presentation-slot hash slot rep)))
+        (insert "\n")
+        (indent-to start-column)
+        (insert "}")))
+     ((eq rep nil)
+      (insert (propertize "?" 'font-lock-face 'font-lock-warning)))
+     (t
+      (let ((err "Unable to present! This very likely means Emacs
+is out of sync with the `present' package. You should make sure
+they're both up to date, or report a bug."))
+        (insert err)
+        (error err))))))
+
+(defun haskell-interactive-mode-setup-presentation (p)
+  "Setup the GHCi REPL for using presentations.
+
+Using asynchronous queued commands as opposed to sync at this
+stage, as sync would freeze up the UI a bit, and we actually
+don't care when the thing completes as long as it's soonish."
+  ;; Import dependencies under Present.* namespace
+  (haskell-process-queue-without-filters p "import qualified Data.Maybe as Present")
+  (haskell-process-queue-without-filters p "import qualified Data.ByteString.Lazy as Present")
+  (haskell-process-queue-without-filters p "import qualified Data.AttoLisp as Present")
+  (haskell-process-queue-without-filters p "import qualified Present.ID as Present")
+  (haskell-process-queue-without-filters p "import qualified Present as Present")
+  ;; Make a dummy expression to avoid "Loading package" nonsense
+  (haskell-process-queue-without-filters
+   p "Present.present (Present.fromJust (Present.fromList [0])) ()"))
+
+(defvar haskell-interactive-mode-presentation-hash 0
+  "Counter for the hash.")
+
+(defun haskell-interactive-mode-presentation-hash ()
+  "Generate a presentation hash."
+  (format "_present_%s"
+          (setq haskell-interactive-mode-presentation-hash
+                (1+ haskell-interactive-mode-presentation-hash))))
+
+(define-button-type 'haskell-presentation-slot-button
+  'action 'haskell-presentation-present-slot
+  'follow-link t
+  'help-echo "Click to expand…")
+
+(defun haskell-interactive-mode-history-toggle (n)
+  "Toggle the history N items up or down."
+  (unless (null haskell-interactive-mode-history)
+    (setq haskell-interactive-mode-history-index
+          (mod (+ haskell-interactive-mode-history-index n)
+               (length haskell-interactive-mode-history)))
+    (unless (zerop haskell-interactive-mode-history-index)
+      (message "History item: %d" haskell-interactive-mode-history-index))
+    (haskell-interactive-mode-set-prompt
+     (nth haskell-interactive-mode-history-index
+          haskell-interactive-mode-history))))
+
+(defun haskell-interactive-mode-set-prompt (p)
+  "Set (and overwrite) the current prompt."
+  (with-current-buffer (haskell-session-interactive-buffer (haskell-interactive-session))
+    (goto-char haskell-interactive-mode-prompt-start)
+    (delete-region (point) (point-max))
+    (insert p)))
+
+(defun haskell-interactive-mode-history-previous (arg)
+  "Cycle backwards through input history."
+  (interactive "*p")
+  (when (haskell-interactive-at-prompt)
+    (if (not (zerop arg))
+        (haskell-interactive-mode-history-toggle arg)
+      (setq haskell-interactive-mode-history-index 0)
+      (haskell-interactive-mode-history-toggle 1))))
+
+(defun haskell-interactive-mode-history-next (arg)
+  "Cycle forward through input history."
+  (interactive "*p")
+  (when (haskell-interactive-at-prompt)
+    (if (not (zerop arg))
+        (haskell-interactive-mode-history-toggle (- arg))
+      (setq haskell-interactive-mode-history-index 0)
+      (haskell-interactive-mode-history-toggle -1))))
+
+(defun haskell-interactive-mode-prompt-previous ()
+  "Jump to the previous prompt."
+  (interactive)
+  (let ((prev-prompt-pos
+         (save-excursion
+           (beginning-of-line) ;; otherwise prompt at current line matches
+           (and (search-backward-regexp (haskell-interactive-prompt-regex) nil t)
+                (match-end 0)))))
+    (when prev-prompt-pos (goto-char prev-prompt-pos))))
+
+(defun haskell-interactive-mode-prompt-next ()
+  "Jump to the next prompt."
+  (interactive)
+  (search-forward-regexp (haskell-interactive-prompt-regex) nil t))
+
+(defun haskell-interactive-mode-clear ()
+  "Clear the screen and put any current input into the history."
+  (interactive)
+  (let ((session (haskell-interactive-session)))
+    (with-current-buffer (haskell-session-interactive-buffer session)
+      (let ((inhibit-read-only t))
+        (set-text-properties (point-min) (point-max) nil))
+      (delete-region (point-min) (point-max))
+      (remove-overlays)
+      (haskell-interactive-mode-prompt session)
+      (haskell-session-set session 'next-error-region nil)
+      (haskell-session-set session 'next-error-locus nil))
+    (with-current-buffer (get-buffer-create "*haskell-process-log*")
+      (let ((inhibit-read-only t))
+        (delete-region (point-min) (point-max)))
+      (remove-overlays))))
+
+(defun haskell-interactive-mode-completion-at-point-function ()
+  "Offer completions for partial expression between prompt and point.
+This completion function is used in interactive REPL buffer itself."
+  (when (haskell-interactive-at-prompt)
+    (let* ((process (haskell-interactive-process))
+           (inp (haskell-interactive-mode-input-partial))
+           (resp2 (haskell-process-get-repl-completions process inp))
+           (rlen (-  (length inp) (length (car resp2))))
+           (coll (append (if (string-prefix-p inp "import") '("import"))
+                         (if (string-prefix-p inp "let") '("let"))
+                         (cdr resp2))))
+      (list (- (point) rlen) (point) coll))))
+
+(defun haskell-interactive-mode-trigger-compile-error (state response)
+  "Look for an <interactive> compile error.
+If there is one, pop that up in a buffer, similar to `debug-on-error'."
+  (when (and haskell-interactive-types-for-show-ambiguous
+             (string-match "^\n<interactive>:[-0-9]+:[-0-9]+:" response)
+             (not (string-match "^\n<interactive>:[-0-9]+:[-0-9]+:[\n ]+[Ww]arning:" response)))
+    (let ((inhibit-read-only t))
+      (delete-region haskell-interactive-mode-prompt-start (point))
+      (set-marker haskell-interactive-mode-prompt-start
+                  haskell-interactive-mode-old-prompt-start)
+      (goto-char (point-max)))
+    (cond
+     ((and (not (haskell-interactive-mode-line-is-query (elt state 2)))
+           (or (string-match "No instance for (?Show[ \n]" response)
+               (string-match "Ambiguous type variable " response)))
+      (haskell-process-reset (haskell-interactive-process))
+      (let ((resp (haskell-process-queue-sync-request
+                   (haskell-interactive-process)
+                   (concat ":t "
+                           (buffer-substring-no-properties
+                            haskell-interactive-mode-prompt-start
+                            (point-max))))))
+        (cond
+         ((not (string-match "<interactive>:" resp))
+          (haskell-interactive-mode-insert-error resp))
+         (t (haskell-interactive-popup-error response)))))
+     (t (haskell-interactive-popup-error response)
+        t))
+    t))
+
+;;;###autoload
+(defun haskell-interactive-mode-echo (session message &optional mode)
+  "Echo a read only piece of text before the prompt."
+  (with-current-buffer (haskell-session-interactive-buffer session)
+    (save-excursion
+      (haskell-interactive-mode-goto-end-point)
+      (insert (if mode
+                  (haskell-fontify-as-mode
+                   (concat message "\n")
+                   mode)
+                (propertize (concat message "\n")
+                            'front-sticky t
+                            'read-only t
+                            'rear-nonsticky t))))))
+
+(defun haskell-interactive-mode-splices-buffer (session)
+  "Get the splices buffer for the current SESSION."
+  (get-buffer-create (haskell-interactive-mode-splices-buffer-name session)))
+
+(defun haskell-interactive-mode-splices-buffer-name (session)
+  (format "*%s:splices*" (haskell-session-name session)))
+
+(defun haskell-interactive-mode-compile-splice (session message)
+  "Echo a compiler splice."
+  (with-current-buffer (haskell-interactive-mode-splices-buffer session)
+    (unless (eq major-mode 'haskell-mode)
+      (haskell-mode))
+    (let* ((parts (split-string message "\n  ======>\n"))
+           (file-and-decl-lines (split-string (nth 0 parts) "\n"))
+           (file (nth 0 file-and-decl-lines))
+           (decl (mapconcat #'identity (cdr file-and-decl-lines) "\n"))
+           (output (nth 1 parts)))
+      (insert "-- " file "\n")
+      (let ((start (point)))
+        (insert decl "\n")
+        (indent-rigidly start (point) -4))
+      (insert "-- =>\n")
+      (let ((start (point)))
+        (insert output "\n")
+        (indent-rigidly start (point) -4)))))
+
+(defun haskell-interactive-mode-insert-garbage (session message)
+  "Echo a read only piece of text before the prompt."
+  (with-current-buffer (haskell-session-interactive-buffer session)
+    (save-excursion
+      (haskell-interactive-mode-goto-end-point)
+      (insert (propertize message
+                          'front-sticky t
+                          'font-lock-face 'haskell-interactive-face-garbage
+                          'read-only t
+                          'rear-nonsticky t)))))
+
+;;;###autoload
+(defun haskell-process-show-repl-response (line)
+  "Send LINE to the GHCi process and echo the result in some fashion.
+Result will be printed in the minibuffer or presented using
+function `haskell-presentation-present', depending on variable
+`haskell-process-use-presentation-mode'."
+  (let ((process (haskell-interactive-process)))
+    (haskell-process-queue-command
+     process
+     (make-haskell-command
+      :state (cons process line)
+      :go (lambda (state)
+            (haskell-process-send-string (car state) (cdr state)))
+      :complete (lambda (state response)
+                  (if haskell-process-use-presentation-mode
+                      (haskell-presentation-present
+                       (haskell-process-session (car state))
+                       response)
+                    (haskell-mode-message-line response)))))))
+
+(provide 'haskell-interactive-mode)
+
+;;; haskell-interactive-mode.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-interactive-mode.elc b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-interactive-mode.elc
new file mode 100644
index 0000000000..2d82cfc43d
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-interactive-mode.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-lexeme.el b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-lexeme.el
new file mode 100644
index 0000000000..877774e775
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-lexeme.el
@@ -0,0 +1,513 @@
+;;; haskell-lexeme.el --- haskell lexical tokens   -*- coding: utf-8; lexical-binding: t -*-
+
+;; Copyright (C) 2015 Gracjan Polak
+
+;; This file 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, or (at your option)
+;; any later version.
+
+;; This file 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;; Code:
+
+(require 'rx)
+
+(unless (category-docstring ?P)
+  (define-category ?P "Haskell symbol constituent characters")
+  (map-char-table
+   #'(lambda (key val)
+       (if (or
+            (and (consp key) (> (car key) 128))
+            (and (numberp key) (> key 128)))
+           (if (member val '(Pc Pd Po Sm Sc Sk So))
+               (modify-category-entry key ?P))))
+   unicode-category-table)
+
+  (dolist (key (string-to-list "!#$%&*+./<=>?@^|~\\-:"))
+    (modify-category-entry key ?P)))
+
+(defconst haskell-lexeme-modid
+  "[[:upper:]][[:alnum:]'_]*"
+  "Regexp matching a valid Haskell module identifier.
+
+Note that GHC accepts Unicode category UppercaseLetter as a first
+character. Following letters are from Unicode categories
+UppercaseLetter, LowercaseLetter, OtherLetter, TitlecaseLetter,
+ModifierLetter, DecimalNumber, OtherNumber, backslash or
+underscore.")
+
+(defconst haskell-lexeme-id
+  "[[:alpha:]_][[:alnum:]'_]*"
+  "Regexp matching a valid Haskell identifier.
+
+GHC accepts a string starting with any alphabetic character or
+underscore followed by any alphanumeric character or underscore
+or apostrophe.")
+
+(defconst haskell-lexeme-sym
+  "\\cP+"
+  "Regexp matching a valid Haskell variable or constructor symbol.
+
+GHC accepts a string of chars from the set
+[:!#$%&*+./<=>?@^|~\\-] or Unicode category Symbol for chars with
+codes larger than 128 only.")
+
+(defconst haskell-lexeme-idsym-first-char
+  "\\(?:[[:alpha:]_]\\|\\cP\\)"
+  "Regexp matching first character of a qualified or unqualified
+identifier or symbol.
+
+Useful for `re-search-forward'.")
+
+(defconst haskell-lexeme-modid-opt-prefix
+  (concat "\\(?:" haskell-lexeme-modid "\\.\\)*")
+  "Regexp matching a valid Haskell module prefix, potentially empty.
+
+Module path prefix is separated by dots and finishes with a
+dot. For path component syntax see `haskell-lexeme-modid'.")
+
+(defconst haskell-lexeme-qid-or-qsym
+  (rx-to-string `(: (regexp ,haskell-lexeme-modid-opt-prefix)
+                    (group (| (regexp ,haskell-lexeme-id) (regexp ,haskell-lexeme-sym)
+                              ))))
+  "Regexp matching a valid qualified identifier or symbol.
+
+Note that (match-string 1) returns the unqualified part.")
+
+(defun haskell-lexeme-looking-at-qidsym ()
+  "Non-nil when point is just in front of an optionally qualified
+identifier or symbol.
+
+Using this function is more efficient than matching against the
+regexp `haskell-lexeme-qid-or-qsym'.
+
+Returns:
+  'qid - if matched a qualified id: 'Data.Map' or 'Map'
+  'qsym - if matched a qualified id: 'Monad.>>=' or '>>='
+  'qprefix - if matched only modid prefix: 'Data.'
+
+After successful 'qid or 'qsym match (match-string 1) will return
+the unqualified part (if any)."
+  (let ((begin (point))
+        (match-data-old (match-data)))
+    (save-excursion
+      (while (looking-at (concat haskell-lexeme-modid "\\."))
+        (goto-char (match-end 0)))
+      (cond
+       ((looking-at haskell-lexeme-id)
+        (let ((beg (match-beginning 0))
+              (end (match-end 0)))
+
+          ;; check is MagicHash is present at the end of the token
+          (goto-char end)
+          (when (looking-at "#+")
+            (setq end (match-end 0)))
+
+          (set-match-data
+           (list begin end
+                 beg end)))
+        'qid)
+       ((looking-at haskell-lexeme-sym)
+        (set-match-data
+          (list begin (match-end 0)
+                (match-beginning 0) (match-end 0)))
+        'qsym)
+       ((equal begin (point))
+        (set-match-data match-data-old)
+        nil)
+       (t
+        (set-match-data
+         (list begin (point)
+               nil nil))
+        'qprefix)))))
+
+(defun haskell-lexeme-looking-at-backtick ()
+  "Non-nil when point is just in front of an identifier quoted with backticks.
+
+When match is successful, match-data will contain:
+  (match-text 1) - opening backtick
+  (match-text 2) - whole qualified identifier
+  (match-text 3) - unqualified part of identifier
+  (match-text 4) - closing backtick"
+  (let ((match-data-old (match-data))
+        first-backtick-start
+        last-backtick-start
+        qid-start
+        id-start
+        id-end
+        result)
+    (save-excursion
+      (when (looking-at "`")
+        (setq first-backtick-start (match-beginning 0))
+        (goto-char (match-end 0))
+        (forward-comment (buffer-size))
+        (when (haskell-lexeme-looking-at-qidsym)
+          (setq qid-start (match-beginning 0))
+          (setq id-start (match-beginning 1))
+          (setq id-end (match-end 1))
+          (goto-char (match-end 0))
+          (forward-comment (buffer-size))
+          (when (looking-at "`")
+            (setq last-backtick-start (match-beginning 0))
+            (set-match-data
+             (mapcar
+              (lambda (p)
+                (set-marker (make-marker) p))
+              (list
+               first-backtick-start (1+ last-backtick-start)
+               first-backtick-start (1+ first-backtick-start)
+               qid-start id-end
+               id-start id-end
+               last-backtick-start (1+ last-backtick-start))))
+            (setq result t)))))
+    (unless result
+      (set-match-data match-data-old))
+    result))
+
+(defconst haskell-lexeme-qid
+  (rx-to-string `(: (regexp "'*")
+                    (regexp ,haskell-lexeme-modid-opt-prefix)
+                    (group (regexp ,haskell-lexeme-id))))
+  "Regexp matching a valid qualified identifier.
+
+Note that (match-string 1) returns the unqualified part.")
+
+(defconst haskell-lexeme-qsym
+  (rx-to-string `(: (regexp "'*")
+                    (regexp ,haskell-lexeme-modid-opt-prefix)
+                    (group (regexp ,haskell-lexeme-id))))
+  "Regexp matching a valid qualified symbol.
+
+Note that (match-string 1) returns the unqualified part.")
+
+(defconst haskell-lexeme-number
+  (rx (| (: (regexp "[0-9]+\\.[0-9]+") (opt (regexp "[eE][-+]?[0-9]+")))
+         (regexp "[0-9]+[eE][-+]?[0-9]+")
+         (regexp "0[xX][0-9a-fA-F]+")
+         (regexp "0[oO][0-7]+")
+         (regexp "[0-9]+")))
+  "Regexp matching a floating point, decimal, octal or hexadecimal number.
+
+Note that negative sign char is not part of a number.")
+
+(defconst haskell-lexeme-char-literal-inside
+  (rx (| (not (any "\n'\\"))
+         (: "\\"
+            (| "a" "b" "f" "n" "r" "t" "v" "\\" "\"" "'"
+               "NUL" "SOH" "STX" "ETX" "EOT" "ENQ" "ACK"
+               "BEL" "BS" "HT" "LF" "VT" "FF" "CR" "SO" "SI" "DLE"
+               "DC1" "DC2" "DC3" "DC4" "NAK" "SYN" "ETB" "CAN"
+               "EM" "SUB" "ESC" "FS" "GS" "RS" "US" "SP" "DEL"
+               (regexp "[0-9]+")
+               (: "x" (regexp "[0-9a-fA-F]+"))
+               (: "o" (regexp "[0-7]+"))
+               (: "^" (regexp "[]A-Z@^_\\[]"))))))
+  "Regexp matching an inside of a character literal.
+
+Note that `haskell-lexeme-char-literal-inside' matches strictly
+only escape sequences defined in Haskell Report.")
+
+(defconst haskell-lexeme--char-literal-rx
+  (rx-to-string `(: (group "'")
+                    (| (: (group (regexp "[[:alpha:]_([]")) (group "'")) ; exactly one char
+                       (: (group (| (regexp "\\\\[^\n][^'\n]*") ; allow quote just after first backslash
+                                    (regexp "[^[:alpha:]_:(['\n][^'\n]*")))
+                          (| (group "'") "\n" (regexp "\\'"))))))
+  "Regexp matching a character literal lookalike.
+
+Note that `haskell-lexeme--char-literal-rx' matches more than
+Haskell Report specifies because we want to support also code
+under edit.
+
+Character literals end with a quote or a newline or end of
+buffer.
+
+Regexp has subgroup expressions:
+ (match-text 1) matches the opening quote.
+ (match-text 2) matches the inside of the character literal.
+ (match-text 3) matches the closing quote or an empty string
+                at the end of line or the end buffer.")
+
+(defun haskell-lexeme-looking-at-char-literal ()
+  "Non-nil when point is at a char literal lookalike.
+
+Note that this function matches more than Haskell Report
+specifies because we want to support also code under edit.
+
+Char literals end with a quote or an unescaped newline or end
+of buffer.
+
+After successful match:
+ (match-text 1) matches the opening quote.
+ (match-text 2) matches the inside of the char literla.
+ (match-text 3) matches the closing quote, or a closing
+                newline or is nil when at the end of the buffer."
+  (when (looking-at haskell-lexeme--char-literal-rx)
+    (set-match-data
+     (list (match-beginning 0) (match-end 0)
+           (match-beginning 1) (match-end 1)
+           (or (match-beginning 2) (match-beginning 4)) (or (match-end 2) (match-end 4))
+           (or (match-beginning 3) (match-beginning 5)) (or (match-end 3) (match-end 5))))
+    t))
+
+(defconst haskell-lexeme-string-literal-inside-item
+  (rx (| (not (any "\n\"\\"))
+         (: "\\"
+            (| "a" "b" "f" "n" "r" "t" "v" "\\" "\"" "'" "&"
+               "NUL" "SOH" "STX" "ETX" "EOT" "ENQ" "ACK"
+               "BEL" "BS" "HT" "LF" "VT" "FF" "CR" "SO" "SI" "DLE"
+               "DC1" "DC2" "DC3" "DC4" "NAK" "SYN" "ETB" "CAN"
+               "EM" "SUB" "ESC" "FS" "GS" "RS" "US" "SP" "DEL"
+               (regexp "[0-9]+")
+               (: "x" (regexp "[0-9a-fA-F]+"))
+               (: "o" (regexp "[0-7]+"))
+               (: "^" (regexp "[]A-Z@^_\\[]"))
+               (regexp "[ \t\n\r\v\f]*\\\\")))))
+  "Regexp matching an item that is a single character or a single
+escape sequence inside of a string literal.
+
+Note that `haskell-lexeme-string-literal-inside-item' matches
+strictly only escape sequences defined in Haskell Report.")
+
+(defconst haskell-lexeme-string-literal
+  (rx (: (group "\"")
+         (group (* (| (regexp "\\\\[ \t\n\r\v\f]*\\\\")
+                      (regexp "\\\\[ \t\n\r\v\f]+")
+                      (regexp "\\\\[^ \t\n\r\v\f]")
+                      (* (regexp "[^\"\n\\]")))))
+         (group (| "\"" (regexp "$") (regexp "\\\\?\\'")
+                   ))))
+  "Regexp matching a string literal lookalike.
+
+Note that `haskell-lexeme-string-literal' matches more than
+Haskell Report specifies because we want to support also code
+under edit.
+
+String literals end with double quote or unescaped newline or end
+of buffer.
+
+Regexp has subgroup expressions:
+ (match-text 1) matches the opening double quote.
+ (match-text 2) matches the inside of the string.
+ (match-text 3) matches the closing double quote or an empty string
+                at the end of line or the end buffer.")
+
+(defun haskell-lexeme-looking-at-string-literal ()
+  "Non-nil when point is at a string literal lookalike.
+
+Note that this function matches more than Haskell Report
+specifies because we want to support also code under edit.
+
+String literals end with double quote or unescaped newline or end
+of buffer.
+
+After successful match:
+ (match-text 1) matches the opening doublequote.
+ (match-text 2) matches the inside of the string.
+ (match-text 3) matches the closing quote, or a closing
+                newline or is nil when at the end of the buffer."
+  (when (looking-at "\"")
+    (save-excursion
+      (let ((begin (point)))
+        (goto-char (match-end 0))
+        (let (finish)
+          (while (and (not finish)
+                      (re-search-forward "[\"\n\\]" nil 'goto-eob))
+            (cond
+             ((equal (match-string 0) "\\")
+              (if (looking-at "[ \t\n\r\v\f]+\\\\?")
+                  (goto-char (match-end 0))
+                (goto-char (1+ (point)))))
+
+             ((equal (match-string 0) "\"")
+              (set-match-data
+               (list begin (match-end 0)
+                     begin (1+ begin)
+                     (1+ begin) (match-beginning 0)
+                     (match-beginning 0) (match-end 0)))
+              (setq finish t))
+
+             ((equal (match-string 0) "\n")
+              (set-match-data
+               (list begin (match-beginning 0)
+                     begin (1+ begin)
+                     (1+ begin) (match-beginning 0)
+                     nil nil))
+              (setq finish t))))
+          (unless finish
+            ;; string closed by end of buffer
+            (set-match-data
+             (list begin (point)
+                   begin (1+ begin)
+                   (1+ begin) (point)
+                   nil nil))))))
+    ;; there was a match
+    t))
+
+(defun haskell-lexeme-looking-at-quasi-quote-literal ()
+  "Non-nil when point is just in front of Template Haskell
+quaisquote literal.
+
+Quasi quotes start with '[xxx|' or '[$xxx|' sequence and end with
+  '|]'. The 'xxx' is a quoter name. There is no escaping mechanism
+provided for the ending sequence.
+
+Regexp has subgroup expressions:
+ (match-text 1) matches the quoter name (without $ sign if present).
+ (match-text 2) matches the opening vertical bar.
+ (match-text 3) matches the inside of the quoted string.
+ (match-text 4) matches the closing vertical bar
+                or nil if at the end of the buffer.
+
+Note that this function excludes 'e', 't', 'd', 'p' as quoter
+names according to Template Haskell specification."
+  (let ((match-data-old (match-data)))
+    (if (and
+         (looking-at (rx-to-string `(: "[" (optional "$")
+                                       (group (regexp ,haskell-lexeme-id))
+                                       (group "|"))))
+         (equal (haskell-lexeme-classify-by-first-char (char-after (match-beginning 1)))
+                'varid)
+         (not (member (match-string 1) '("e" "t" "d" "p"))))
+      (save-excursion
+        ;; note that quasi quote syntax does not have any escaping
+        ;; mechanism and if not closed it will span til lthe end of buffer
+        (goto-char (match-end 0))
+        (let ((match-data (match-data))
+              (match-data-2 (and (re-search-forward "|]" nil t)
+                                 (match-data))))
+          (if match-data-2
+              (set-match-data
+               (list
+                (nth 0 match-data) (nth 1 match-data-2)          ;; whole match
+                (nth 2 match-data) (nth 3 match-data)            ;; quoter name
+                (nth 4 match-data) (nth 5 match-data)            ;; opening bar
+                (nth 5 match-data) (nth 0 match-data-2)          ;; inner string
+                (nth 0 match-data-2) (1+ (nth 0 match-data-2)))) ;; closing bar
+
+            (set-match-data
+             (list
+              (nth 0 match-data) (point-max)                   ;; whole match
+              (nth 2 match-data) (nth 3 match-data)            ;; quoter name
+              (nth 4 match-data) (nth 5 match-data)            ;; opening bar
+              (nth 5 match-data) (point-max)                   ;; inner string
+              nil nil))                                        ;; closing bar
+            ))
+        t)
+      ;; restore old match data if not matched
+      (set-match-data match-data-old)
+      nil)))
+
+(defun haskell-lexeme-classify-by-first-char (char)
+  "Classify token by CHAR.
+
+CHAR is a chararacter that is assumed to be the first character
+of a token."
+  (let ((category (get-char-code-property (or char ?\ ) 'general-category)))
+
+    (cond
+     ((or (member char '(?! ?# ?$ ?% ?& ?* ?+ ?. ?/ ?< ?= ?> ?? ?@ ?^ ?| ?~ ?\\ ?-))
+          (and (> char 127)
+               (member category '(Pc Pd Po Sm Sc Sk So))))
+      'varsym)
+     ((equal char ?:)
+      'consym)
+     ((equal char ?\')
+      'char)
+     ((equal char ?\")
+      'string)
+     ((member category '(Lu Lt))
+      'conid)
+     ((or (equal char ?_)
+          (member category '(Ll Lo)))
+      'varid)
+     ((and (>= char ?0) (<= char ?9))
+      'number)
+     ((member char '(?\] ?\[ ?\( ?\) ?\{ ?\} ?\` ?\, ?\;))
+      'special))))
+
+(defun haskell-lexeme-looking-at-token (&rest flags)
+  "Like `looking-at' but understands Haskell lexemes.
+
+Moves point forward over whitespace.  Returns a symbol describing
+type of Haskell token recognized.  Use `match-string',
+`match-beginning' and `match-end' with argument 0 to query match
+result.
+
+Possible results are:
+- 'special: for chars [](){}`,;
+- 'comment: for single line comments
+- 'nested-comment: for multiline comments
+- 'qsymid: for qualified identifiers or symbols
+- 'string: for strings literals
+- 'char: for char literals
+- 'number: for decimal, float, hexadecimal and octal number literals
+- 'template-haskell-quote: for a string of apostrophes for template haskell
+- 'template-haskell-quasi-quote: for a string of apostrophes for template haskell
+
+Note that for qualified symbols (match-string 1) returns the
+unqualified identifier or symbol.  Further qualification for
+symbol or identifier can be done with:
+
+   (haskell-lexeme-classify-by-first-char (char-after (match-beginning 1)))
+
+See `haskell-lexeme-classify-by-first-char' for details."
+  (while
+      ;; Due to how unterminated strings terminate at newline, some
+      ;; newlines have syntax set to generic string delimeter. We want
+      ;; those to be treated as whitespace anyway
+      (or
+       (> (skip-syntax-forward "-") 0)
+       (and (not (member 'newline flags))
+            (> (skip-chars-forward "\n") 0))))
+  (let
+      ((case-fold-search nil)
+       (point (point-marker)))
+    (or
+     (and
+      (equal (string-to-syntax "<")
+             (get-char-property (point) 'syntax-table))
+      (progn
+        (set-match-data (list point (set-marker (make-marker) (line-end-position))))
+        'literate-comment))
+     (and (looking-at "\n")
+          'newline)
+     (and (looking-at "{-")
+          (save-excursion
+            (forward-comment 1)
+            (set-match-data (list point (point-marker)))
+            'nested-comment))
+     (and (haskell-lexeme-looking-at-char-literal)
+          'char)
+     (and (haskell-lexeme-looking-at-string-literal)
+          'string)
+     (and (looking-at "[][(){}`,;]")
+          (if (haskell-lexeme-looking-at-quasi-quote-literal)
+              'template-haskell-quasi-quote
+            'special))
+     (and (haskell-lexeme-looking-at-qidsym)
+          (if (save-match-data
+                (string-match "\\`---*\\'" (match-string-no-properties 0)))
+              (progn
+                (set-match-data (list point (set-marker (make-marker) (line-end-position))))
+                'comment)
+            'qsymid))
+     (and (looking-at haskell-lexeme-number)
+          'number)
+     (and (looking-at "'+")
+          'template-haskell-quote)
+     (and (looking-at ".")
+          'illegal))))
+
+(provide 'haskell-lexeme)
+
+;;; haskell-lexeme.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-lexeme.elc b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-lexeme.elc
new file mode 100644
index 0000000000..1ea9b604e9
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-lexeme.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-load.el b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-load.el
new file mode 100644
index 0000000000..fb8bd98f3a
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-load.el
@@ -0,0 +1,632 @@
+;;; haskell-load.el --- Compiling and loading modules in the GHCi process -*- lexical-binding: t -*-
+
+;; Copyright © 2014 Chris Done. All rights reserved.
+;;             2016 Arthur Fayzrakhmanov
+
+;; This file 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, or (at your option)
+;; any later version.
+
+;; This file 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'haskell-mode)
+(require 'haskell-process)
+(require 'haskell-interactive-mode)
+(require 'haskell-modules)
+(require 'haskell-commands)
+(require 'haskell-session)
+(require 'haskell-string)
+
+(defun haskell-process-look-config-changes (session)
+  "Check whether a cabal configuration file has changed.
+Restarts the SESSION's process if that is the case."
+  (let ((current-checksum (haskell-session-get session 'cabal-checksum))
+        (new-checksum (haskell-cabal-compute-checksum
+                       (haskell-session-get session 'cabal-dir))))
+    (when (not (string= current-checksum new-checksum))
+      (haskell-interactive-mode-echo
+       session
+       (format "Cabal file changed: %s" new-checksum))
+      (haskell-session-set-cabal-checksum
+       session
+       (haskell-session-get session 'cabal-dir))
+      (haskell-mode-toggle-interactive-prompt-state)
+      (unwind-protect
+          (unless
+              (and haskell-process-prompt-restart-on-cabal-change
+                   (not
+                    (y-or-n-p "Cabal file changed. Restart GHCi process? ")))
+            (haskell-process-start (haskell-interactive-session)))
+        (haskell-mode-toggle-interactive-prompt-state t)))))
+
+(defun haskell-process-live-build (process buffer echo-in-repl)
+  "Show live updates for loading files."
+  (cond
+   ((haskell-process-consume
+     process
+     (concat "\\[[ ]*\\([0-9]+\\) of \\([0-9]+\\)\\]"
+             " Compiling \\([^ ]+\\)[ ]+"
+             "( \\([^ ]+\\), \\([^ ]+\\) )[^\r\n]*[\r\n]+"))
+    (haskell-process-echo-load-message process buffer echo-in-repl nil)
+    t)
+   ((haskell-process-consume
+     process
+     (concat "\\[[ ]*\\([0-9]+\\) of \\([0-9]+\\)\\]"
+             " Compiling \\[TH\\] \\([^ ]+\\)[ ]+"
+             "( \\([^ ]+\\), \\([^ ]+\\) )[^\r\n]*[\r\n]+"))
+    (haskell-process-echo-load-message process buffer echo-in-repl t)
+    t)
+   ((haskell-process-consume
+     process
+     "Loading package \\([^ ]+\\) ... linking ... done.\n")
+    (haskell-mode-message-line
+     (format "Loading: %s"
+             (match-string 1 buffer)))
+    t)
+   ((haskell-process-consume
+     process
+     "^Preprocessing executables for \\(.+?\\)\\.\\.\\.")
+    (let ((msg (format "Preprocessing: %s" (match-string 1 buffer))))
+      (haskell-interactive-mode-echo (haskell-process-session process) msg)
+      (haskell-mode-message-line msg)))
+   ((haskell-process-consume process "Linking \\(.+?\\) \\.\\.\\.")
+    (let ((msg (format "Linking: %s" (match-string 1 buffer))))
+      (haskell-interactive-mode-echo (haskell-process-session process) msg)
+      (haskell-mode-message-line msg)))
+   ((haskell-process-consume process "\nBuilding \\(.+?\\)\\.\\.\\.")
+    (let ((msg (format "Building: %s" (match-string 1 buffer))))
+      (haskell-interactive-mode-echo (haskell-process-session process) msg)
+      (haskell-mode-message-line msg)))
+   ((string-match "Collecting type info for [[:digit:]]+ module(s) \\.\\.\\."
+                  (haskell-process-response process)
+                  (haskell-process-response-cursor process))
+    (haskell-mode-message-line (match-string 0 buffer))
+    ;; Do not consume "Ok, modules loaded" that goes before
+    ;; "Collecting type info...", just exit.
+    nil)))
+
+(defun haskell-process-load-complete (session process buffer reload module-buffer &optional cont)
+  "Handle the complete loading response. BUFFER is the string of
+text being sent over the process pipe. MODULE-BUFFER is the
+actual Emacs buffer of the module being loaded."
+  (when (get-buffer (format "*%s:splices*" (haskell-session-name session)))
+    (with-current-buffer (haskell-interactive-mode-splices-buffer session)
+      (erase-buffer)))
+  (let* ((ok (cond
+              ((haskell-process-consume
+                process
+                "Ok, \\(?:[0-9]+\\) modules? loaded\\.$")
+               t)
+              ((haskell-process-consume
+                process
+                "Failed, \\(?:[0-9]+\\) modules? loaded\\.$")
+               nil)
+              ((haskell-process-consume
+                process
+                "Ok, modules loaded: \\(.+\\)\\.$")
+               t)
+              ((haskell-process-consume
+                process
+                "Failed, modules loaded: \\(.+\\)\\.$")
+               nil)
+              (t
+               (error (message "Unexpected response from haskell process.")))))
+         (modules (haskell-process-extract-modules buffer))
+         (cursor (haskell-process-response-cursor process))
+         (warning-count 0))
+    (haskell-process-set-response-cursor process 0)
+    (haskell-check-remove-overlays module-buffer)
+    (while
+        (haskell-process-errors-warnings module-buffer session process buffer)
+      (setq warning-count (1+ warning-count)))
+    (haskell-process-set-response-cursor process cursor)
+    (if (and (not reload)
+             haskell-process-reload-with-fbytecode)
+        (haskell-process-reload-with-fbytecode process module-buffer)
+      (haskell-process-import-modules process (car modules)))
+    (if ok
+        (haskell-mode-message-line (if reload "Reloaded OK." "OK."))
+      (haskell-interactive-mode-compile-error session "Compilation failed."))
+    (when cont
+      (condition-case-unless-debug e
+          (funcall cont ok)
+        (error (message "%S" e))
+        (quit nil)))))
+
+(defun haskell-process-suggest-imports (session file modules ident)
+  "Suggest add missed imports to file.
+Asks user to add to SESSION's FILE missed import.  MODULES is a
+list of modules where missed IDENT was found."
+  (cl-assert session)
+  (cl-assert file)
+  (cl-assert ident)
+  (haskell-mode-toggle-interactive-prompt-state)
+  (unwind-protect
+      (let* ((process (haskell-session-process session))
+             (suggested-already (haskell-process-suggested-imports process))
+             (module
+              (cond
+               ((> (length modules) 1)
+                (when (y-or-n-p
+                       (format
+                        "Identifier `%s' not in scope, choose module to import?"
+                        ident))
+                  (haskell-complete-module-read "Module: " modules)))
+               ((= (length modules) 1)
+                (let ((module (car modules)))
+                  (unless (member module suggested-already)
+                    (haskell-process-set-suggested-imports
+                     process
+                     (cons module suggested-already))
+                    (when (y-or-n-p
+                           (format "Identifier `%s' not in scope, import `%s'?"
+                                   ident
+                                   module))
+                      module)))))))
+        (when module
+          (haskell-process-find-file session file)
+          (haskell-add-import module)))
+    (haskell-mode-toggle-interactive-prompt-state t)))
+
+(defun haskell-process-trigger-suggestions (session msg file line)
+  "Trigger prompting to add any extension suggestions."
+  (cond ((let ((case-fold-search nil))
+           (or
+            (and (string-match " -X\\([A-Z][A-Za-z]+\\)" msg)
+                 (not (string-match "\\([A-Z][A-Za-z]+\\) is deprecated" msg)))
+            (string-match "Use \\([A-Z][A-Za-z]+\\) to permit this" msg)
+            (string-match "Use \\([A-Z][A-Za-z]+\\) to allow" msg)
+            (string-match "Use \\([A-Z][A-Za-z]+\\) to enable" msg)
+            (string-match
+             "Use \\([A-Z][A-Za-z]+\\) if you want to disable this"
+             msg)
+            (string-match "use \\([A-Z][A-Za-z]+\\)" msg)
+            (string-match "You need \\([A-Z][A-Za-z]+\\)" msg)))
+         (when haskell-process-suggest-language-pragmas
+           (haskell-process-suggest-pragma
+            session
+            "LANGUAGE"
+            (match-string 1 msg)
+            file)))
+        ((string-match
+          " The \\(qualified \\)?import of[ ][‘`‛]\\([^ ]+\\)['’] is redundant"
+          msg)
+         (when haskell-process-suggest-remove-import-lines
+           (haskell-process-suggest-remove-import
+            session
+            file
+            (match-string 2 msg)
+            line)))
+        ((string-match "[Ww]arning: orphan instance: " msg)
+         (when haskell-process-suggest-no-warn-orphans
+           (haskell-process-suggest-pragma
+            session
+            "OPTIONS" "-fno-warn-orphans"
+            file)))
+        ((or (string-match "against inferred type [‘`‛]\\[Char\\]['’]" msg)
+             (string-match "with actual type [‘`‛]\\[Char\\]['’]" msg))
+         (when haskell-process-suggest-overloaded-strings
+           (haskell-process-suggest-pragma
+            session
+            "LANGUAGE" "OverloadedStrings"
+            file)))
+        ((string-match "^Not in scope: .*[‘`‛]\\(.+\\)['’]$" msg)
+         (let* ((match1 (match-string 1 msg))
+                (ident (if (string-match "^[A-Za-z0-9_'.]+\\.\\(.+\\)$" match1)
+                           ;; Skip qualification.
+                           (match-string 1 match1)
+                         match1)))
+           (when haskell-process-suggest-hoogle-imports
+             (let ((modules (haskell-process-hoogle-ident ident)))
+               (haskell-process-suggest-imports session file modules ident)))
+           (when haskell-process-suggest-haskell-docs-imports
+             (let ((modules (haskell-process-haskell-docs-ident ident)))
+               (haskell-process-suggest-imports session file modules ident)))
+           (when haskell-process-suggest-hayoo-imports
+             (let ((modules (haskell-process-hayoo-ident ident)))
+               (haskell-process-suggest-imports session file modules ident)))))
+        ((string-match "^[ ]+It is a member of the hidden package [‘`‛]\\([^@\r\n]+\\).*['’].$" msg)
+         (when haskell-process-suggest-add-package
+           (haskell-process-suggest-add-package session msg)))))
+
+(defun haskell-process-do-cabal (command)
+  "Run a Cabal command."
+  (let ((process (ignore-errors
+                   (haskell-interactive-process))))
+    (cond
+     ((or (eq process nil)
+          (let ((child (haskell-process-process process)))
+            (not (equal 'run (process-status child)))))
+      (message "Process is not running, so running directly.")
+      (shell-command (concat "cabal " command)
+                     (get-buffer-create "*haskell-process-log*")
+                     (get-buffer-create "*haskell-process-log*"))
+      (switch-to-buffer-other-window (get-buffer "*haskell-process-log*")))
+     (t (haskell-process-queue-command
+         process
+         (make-haskell-command
+          :state (list (haskell-interactive-session) process command 0)
+          :go
+          (lambda (state)
+            (haskell-process-send-string
+             (cadr state)
+             (format haskell-process-do-cabal-format-string
+                     (haskell-session-cabal-dir (car state))
+                     (format "%s %s"
+                             (cl-ecase (haskell-process-type)
+                               ('ghci haskell-process-path-cabal)
+                               ('cabal-repl haskell-process-path-cabal)
+                               ('cabal-new-repl haskell-process-path-cabal)
+                               ('cabal-ghci haskell-process-path-cabal)
+                               ('stack-ghci haskell-process-path-stack))
+                             (cl-caddr state)))))
+          :live
+          (lambda (state buffer)
+            (let ((cmd (replace-regexp-in-string "^\\([a-z]+\\).*"
+                                                 "\\1"
+                                                 (cl-caddr state))))
+              (cond ((or (string= cmd "build")
+                         (string= cmd "install"))
+                     (haskell-process-live-build (cadr state) buffer t))
+                    (t
+                     (haskell-process-cabal-live state buffer)))))
+          :complete
+          (lambda (state response)
+            (let* ((process (cadr state))
+                   (session (haskell-process-session process))
+                   (message-count 0)
+                   (cursor (haskell-process-response-cursor process)))
+              ;; XXX: what the hell about the rampant code duplication?
+              (haskell-process-set-response-cursor process 0)
+              (while (haskell-process-errors-warnings nil session process response)
+                (setq message-count (1+ message-count)))
+              (haskell-process-set-response-cursor process cursor)
+              (let ((msg (format "Complete: cabal %s (%s compiler messages)"
+                                 (cl-caddr state)
+                                 message-count)))
+                (haskell-interactive-mode-echo session msg)
+                (when (= message-count 0)
+                  (haskell-interactive-mode-echo
+                   session
+                   "No compiler messages, dumping complete output:")
+                  (haskell-interactive-mode-echo session response))
+                (haskell-mode-message-line msg)
+                (when (and haskell-notify-p
+                           (fboundp 'notifications-notify))
+                  (notifications-notify
+                   :title (format "*%s*" (haskell-session-name (car state)))
+                   :body msg
+                   :app-name (cl-ecase (haskell-process-type)
+                               ('ghci haskell-process-path-cabal)
+                               ('cabal-repl haskell-process-path-cabal)
+                               ('cabal-new-repl haskell-process-path-cabal)
+                               ('cabal-ghci haskell-process-path-cabal)
+                               ('stack-ghci haskell-process-path-stack))
+                   :app-icon haskell-process-logo)))))))))))
+
+(defun haskell-process-echo-load-message (process buffer echo-in-repl th)
+  "Echo a load message."
+  (let ((session (haskell-process-session process))
+        (module-name (match-string 3 buffer))
+        (file-name (match-string 4 buffer)))
+    (haskell-interactive-show-load-message
+     session
+     'compiling
+     module-name
+     (haskell-session-strip-dir session file-name)
+     echo-in-repl
+     th)))
+
+(defun haskell-process-extract-modules (buffer)
+  "Extract the modules from the process buffer."
+  (let* ((modules-string (match-string 1 buffer))
+         (modules (and modules-string (split-string modules-string ", "))))
+    (cons modules modules-string)))
+
+;;;###autoload
+(defface haskell-error-face
+  '((((supports :underline (:style wave)))
+     :underline (:style wave :color "#dc322f"))
+    (t
+     :inherit error))
+  "Face used for marking error lines."
+  :group 'haskell-mode)
+
+;;;###autoload
+(defface haskell-warning-face
+  '((((supports :underline (:style wave)))
+     :underline (:style wave :color "#b58900"))
+    (t
+     :inherit warning))
+  "Face used for marking warning lines."
+  :group 'haskell-mode)
+
+;;;###autoload
+(defface haskell-hole-face
+  '((((supports :underline (:style wave)))
+     :underline (:style wave :color "#6c71c4"))
+    (t
+     :inherit warning))
+  "Face used for marking hole lines."
+  :group 'haskell-mode)
+
+(defvar haskell-check-error-fringe   (propertize "!" 'display '(left-fringe exclamation-mark)))
+(defvar haskell-check-warning-fringe (propertize "?" 'display '(left-fringe question-mark)))
+(defvar haskell-check-hole-fringe    (propertize "_" 'display '(left-fringe horizontal-bar)))
+
+(defun haskell-check-overlay-p (ovl)
+  (overlay-get ovl 'haskell-check))
+
+(defun haskell-check-filter-overlays (xs)
+  (cl-remove-if-not 'haskell-check-overlay-p xs))
+
+(defun haskell-check-remove-overlays (buffer)
+  (with-current-buffer buffer
+    (remove-overlays (point-min) (point-max) 'haskell-check t)))
+
+(defmacro haskell-with-overlay-properties (proplist ovl &rest body)
+  "Evaluate BODY with names in PROPLIST bound to the values of
+correspondingly-named overlay properties of OVL."
+  (let ((ovlvar (cl-gensym "OVL-")))
+    `(let* ((,ovlvar ,ovl)
+            ,@(mapcar (lambda (p) `(,p (overlay-get ,ovlvar ',p))) proplist))
+       ,@body)))
+
+(defun haskell-overlay-start> (o1 o2)
+  (> (overlay-start o1) (overlay-start o2)))
+(defun haskell-overlay-start< (o1 o2)
+  (< (overlay-start o1) (overlay-start o2)))
+
+(defun haskell-first-overlay-in-if (test beg end)
+  (let ((ovls (cl-remove-if-not test (overlays-in beg end))))
+    (cl-first (sort (cl-copy-list ovls) 'haskell-overlay-start<))))
+
+(defun haskell-last-overlay-in-if (test beg end)
+  (let ((ovls (cl-remove-if-not test (overlays-in beg end))))
+    (cl-first (sort (cl-copy-list ovls) 'haskell-overlay-start>))))
+
+(defun haskell-error-overlay-briefly (ovl)
+  (haskell-with-overlay-properties
+   (haskell-msg haskell-msg-type) ovl
+   (cond
+    ((not (eq haskell-msg-type 'warning))
+     haskell-msg)
+    ((string-prefix-p "[Ww]arning:\n    " haskell-msg)
+     (cl-subseq haskell-msg 13))
+    (t
+     (error
+      "Invariant failed: a warning message from GHC has unexpected form: %s."
+      haskell-msg)))))
+
+(defun haskell-goto-error-overlay (ovl)
+  (cond (ovl
+         (goto-char (overlay-start ovl))
+         (haskell-mode-message-line (haskell-error-overlay-briefly ovl)))
+        (t
+         (message "No further notes from Haskell compiler."))))
+
+(defun haskell-goto-first-error ()
+  (interactive)
+  (haskell-goto-error-overlay
+   (haskell-first-overlay-in-if 'haskell-check-overlay-p
+                        (buffer-end 0) (buffer-end 1))))
+
+(defun haskell-goto-prev-error ()
+  (interactive)
+  (haskell-goto-error-overlay
+   (let ((ovl-at
+          (cl-first (haskell-check-filter-overlays (overlays-at (point))))))
+     (or (haskell-last-overlay-in-if 'haskell-check-overlay-p
+                             (point-min)
+                             (if ovl-at (overlay-start ovl-at) (point)))
+         ovl-at))))
+
+(defun haskell-goto-next-error ()
+  (interactive)
+  (haskell-goto-error-overlay
+   (let ((ovl-at
+          (cl-first (haskell-check-filter-overlays (overlays-at (point))))))
+     (or (haskell-first-overlay-in-if
+          'haskell-check-overlay-p
+          (if ovl-at (overlay-end ovl-at) (point)) (point-max))
+         ovl-at))))
+
+(defun haskell-check-paint-overlay
+    (buffer error-from-this-file-p line msg file type hole coln)
+  (with-current-buffer buffer
+    (let (beg end)
+      (goto-char (point-min))
+      ;; XXX: we can avoid excess buffer walking by relying on the maybe-fact
+      ;;      that GHC sorts error messages by line number, maybe.
+      (cond
+       (error-from-this-file-p
+        (forward-line (1- line))
+        (forward-char (1- coln))
+        (setq beg (point))
+        (if (eq type 'hole)
+            (forward-char (length hole))
+          (skip-chars-forward "^[:space:]" (line-end-position)))
+        (setq end (point)))
+       (t
+        (setq beg (point))
+        (forward-line)
+        (setq end (point))))
+      (let ((ovl (make-overlay beg end)))
+        (overlay-put ovl 'haskell-check t)
+        (overlay-put ovl 'haskell-file file)
+        (overlay-put ovl 'haskell-msg msg)
+        (overlay-put ovl 'haskell-msg-type type)
+        (overlay-put ovl 'help-echo msg)
+        (overlay-put ovl 'haskell-hole hole)
+        (cl-destructuring-bind
+            (face fringe)
+            (cl-case type
+              (warning
+               (list 'haskell-warning-face haskell-check-warning-fringe))
+              (hole
+               (list 'haskell-hole-face    haskell-check-hole-fringe))
+              (error
+               (list 'haskell-error-face   haskell-check-error-fringe)))
+          (overlay-put ovl 'before-string fringe)
+          (overlay-put ovl 'face face))))))
+
+(defun haskell-process-errors-warnings
+    (module-buffer session process buffer &optional return-only)
+  "Trigger handling type errors or warnings.
+Either prints the messages in the interactive buffer or if CONT
+is specified, passes the error onto that.
+
+When MODULE-BUFFER is non-NIL, paint error overlays."
+  (save-excursion
+    (cond
+     ((haskell-process-consume
+       process
+       "\\(Module imports form a cycle:[ \n]+module [^ ]+ ([^)]+)[[:unibyte:][:nonascii:]]+?\\)\nFailed")
+      (let ((err (match-string 1 buffer)))
+        (if (string-match "module [`'‘‛]\\([^ ]+\\)['’`] (\\([^)]+\\))" err)
+            (let* ((default-directory (haskell-session-current-dir session))
+                   (module (match-string 1 err))
+                   (file (match-string 2 err))
+                   (relative-file-name (file-relative-name file)))
+              (unless return-only
+                (haskell-interactive-show-load-message
+                 session
+                 'import-cycle
+                 module
+                 relative-file-name
+                 nil
+                 nil)
+                (haskell-interactive-mode-compile-error
+                 session
+                 (format "%s:1:0: %s"
+                         relative-file-name
+                         err)))
+              (list :file file :line 1 :col 0 :msg err :type 'error))
+          t)))
+     ((haskell-process-consume
+       process
+       (concat "[\r\n]\\([A-Z]?:?[^ \r\n:][^:\n\r]+\\):\\([0-9()-:]+\\):"
+               "[ \n\r]+\\([[:unibyte:][:nonascii:]]+?\\)\n[^ ]"))
+      (haskell-process-set-response-cursor
+       process
+       (- (haskell-process-response-cursor process) 1))
+      (let* ((buffer (haskell-process-response process))
+             (file (match-string 1 buffer))
+             (location-raw (match-string 2 buffer))
+             (error-msg (match-string 3 buffer))
+             (type (cond ((string-match "^[Ww]arning:" error-msg)  'warning)
+                         ((string-match "^Splicing " error-msg) 'splice)
+                         (t                                     'error)))
+             (critical (not (eq type 'warning)))
+             ;; XXX: extract hole information, pass down to
+             ;; `haskell-check-paint-overlay'
+             (final-msg (format "%s:%s: %s"
+                                (haskell-session-strip-dir session file)
+                                location-raw
+                                error-msg))
+             (location (haskell-process-parse-error
+                        (concat file ":" location-raw ": x")))
+             (line (plist-get location :line))
+             (col1 (plist-get location :col)))
+        (when (and module-buffer haskell-process-show-overlays)
+          (haskell-check-paint-overlay
+           module-buffer
+           (string= (file-truename (buffer-file-name module-buffer))
+                    (file-truename file))
+           line error-msg file type nil col1))
+        (if return-only
+            (list :file file :line line :col col1 :msg error-msg :type type)
+          (progn (funcall (cl-case type
+                            (warning  'haskell-interactive-mode-compile-warning)
+                            (splice   'haskell-interactive-mode-compile-splice)
+                            (error    'haskell-interactive-mode-compile-error))
+                          session final-msg)
+                 (when critical
+                   (haskell-mode-message-line final-msg))
+                 (haskell-process-trigger-suggestions
+                  session
+                  error-msg
+                  file
+                  line)
+                 t)))))))
+
+(defun haskell-interactive-show-load-message (session type module-name file-name echo th)
+  "Show the '(Compiling|Loading) X' message."
+  (let ((msg (concat
+              (cl-ecase type
+                ('compiling
+                 (if haskell-interactive-mode-include-file-name
+                     (format "Compiling: %s (%s)" module-name file-name)
+                   (format "Compiling: %s" module-name)))
+                ('loading (format "Loading: %s" module-name))
+                ('import-cycle
+                 (format "Module has an import cycle: %s" module-name)))
+              (if th " [TH]" ""))))
+    (haskell-mode-message-line msg)
+    (when haskell-interactive-mode-delete-superseded-errors
+      (haskell-interactive-mode-delete-compile-messages session file-name))
+    (when echo
+      (haskell-interactive-mode-echo session msg))))
+
+;;;###autoload
+(defun haskell-process-reload-devel-main ()
+  "Reload the module `DevelMain' and then run `DevelMain.update'.
+
+This is for doing live update of the code of servers or GUI
+applications.  Put your development version of the program in
+`DevelMain', and define `update' to auto-start the program on a
+new thread, and use the `foreign-store' package to access the
+running context across :load/:reloads in GHCi."
+  (interactive)
+  (haskell-mode-toggle-interactive-prompt-state)
+  (unwind-protect
+      (with-current-buffer
+          (or (get-buffer "DevelMain.hs")
+              (if (y-or-n-p
+                   "You need to open a buffer named DevelMain.hs. Find now?")
+                  (ido-find-file)
+                (error "No DevelMain.hs buffer.")))
+        (let ((session (haskell-interactive-session)))
+          (let ((process (haskell-interactive-process)))
+            (haskell-process-queue-command
+             process
+             (make-haskell-command
+              :state (list :session session
+                           :process process
+                           :buffer (current-buffer))
+              :go (lambda (state)
+                    (haskell-process-send-string (plist-get state ':process)
+                                                 ":l DevelMain"))
+              :live (lambda (state buffer)
+                      (haskell-process-live-build (plist-get state ':process)
+                                                  buffer
+                                                  nil))
+              :complete (lambda (state response)
+                          (haskell-process-load-complete
+                           (plist-get state ':session)
+                           (plist-get state ':process)
+                           response
+                           nil
+                           (plist-get state ':buffer)
+                           (lambda (ok)
+                             (when ok
+                               (haskell-process-queue-without-filters
+                                (haskell-interactive-process)
+                                "DevelMain.update")
+                               (message "DevelMain updated."))))))))))
+    (haskell-mode-toggle-interactive-prompt-state t)))
+
+(provide 'haskell-load)
+;;; haskell-load.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-load.elc b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-load.elc
new file mode 100644
index 0000000000..e03be46bc6
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-load.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-menu.el b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-menu.el
new file mode 100644
index 0000000000..7e1f1b0b7b
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-menu.el
@@ -0,0 +1,162 @@
+;;; haskell-menu.el --- A Haskell sessions menu -*- lexical-binding: t -*-
+
+;; Copyright (C) 2013  Chris Done
+
+;; Author: Chris Done <chrisdone@gmail.com>
+
+;; This file is not part of GNU Emacs.
+
+;; This file 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, or (at your option)
+;; any later version.
+
+;; This file 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; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;;; Todo:
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'haskell-compat)
+(require 'haskell-session)
+(require 'haskell-process)
+(require 'haskell-interactive-mode)
+
+(defcustom haskell-menu-buffer-name "*haskell-menu*"
+  "The name of the Haskell session menu buffer"
+  :group 'haskell-interactive
+  :type 'string)
+
+;;;###autoload
+(defun haskell-menu ()
+  "Launch the Haskell sessions menu."
+  (interactive)
+  (or (get-buffer haskell-menu-buffer-name)
+      (with-current-buffer (get-buffer-create haskell-menu-buffer-name)
+        (haskell-menu-mode)))
+  (switch-to-buffer-other-window (get-buffer haskell-menu-buffer-name))
+  (haskell-menu-revert-function nil nil))
+
+(defvar haskell-menu-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "n") 'next-line)
+    (define-key map (kbd "p") 'previous-line)
+    (define-key map (kbd "RET") 'haskell-menu-mode-ret)
+    map)
+  "Keymap for `haskell-menu-mode'.")
+
+(define-derived-mode haskell-menu-mode special-mode "Haskell Session Menu"
+  "Major mode for managing Haskell sessions.
+Each line describes one session.
+Letters do not insert themselves; instead, they are commands."
+  (setq buffer-read-only t)
+  (setq-local revert-buffer-function 'haskell-menu-revert-function)
+  (setq truncate-lines t)
+  (haskell-menu-revert-function nil t))
+
+(suppress-keymap haskell-menu-mode-map t)
+
+(defun haskell-menu-revert-function (_arg1 _arg2)
+  "Function to refresh the display."
+  (let ((buffer-read-only nil)
+        (orig-line (line-number-at-pos))
+        (orig-col (current-column)))
+    (or (eq buffer-undo-list t)
+        (setq buffer-undo-list nil))
+    (erase-buffer)
+    (haskell-menu-insert-menu)
+    (goto-char (point-min))
+    (forward-line (1- orig-line))
+    (forward-char orig-col)))
+
+(defun haskell-menu-insert-menu ()
+  "Insert the Haskell sessions menu to the current buffer."
+  (if (null haskell-sessions)
+      (insert "No Haskell sessions.")
+    (haskell-menu-tabulate
+     (list "Name" "PID" "Time" "RSS" "Cabal directory" "Working directory" "Command")
+     (mapcar (lambda (session)
+               (let ((process (haskell-process-process (haskell-session-process session))))
+                 (cond
+                  (process
+                   (let ((id (process-id process)))
+                     (list (propertize (haskell-session-name session) 'face 'buffer-menu-buffer)
+                           (if (process-live-p process) (number-to-string id) "-")
+                           (if (process-live-p process)
+                               (format-time-string "%H:%M:%S"
+                                                   (encode-time (cl-caddr (assoc 'etime (process-attributes id)))
+                                                                0 0 0 0 0))
+                             "-")
+                           (if (process-live-p process)
+                               (concat (number-to-string (/ (cdr (assoc 'rss (process-attributes id)))
+                                                            1024))
+                                       "MB")
+                             "-")
+                           (haskell-session-cabal-dir session)
+                           (haskell-session-current-dir session)
+                           (mapconcat 'identity (process-command process) " "))))
+                  (t (list (propertize (haskell-session-name session) 'face 'buffer-menu-buffer)
+                           "—"
+                           "—"
+                           "—"
+                           (haskell-session-cabal-dir session)
+                           (haskell-session-current-dir session))))))
+             haskell-sessions))))
+
+(defun haskell-menu-tabulate (headings rows)
+  "Prints a list of lists as a formatted table to the current buffer."
+  (let* ((columns (length headings))
+         (widths (make-list columns 0)))
+    ;; Calculate column widths. This is kind of hideous.
+    (dolist (row rows)
+      (setq widths
+            (let ((list (list)))
+              (dotimes (i columns)
+                (setq list (cons (max (nth i widths)
+                                      (1+ (length (nth i row)))
+                                      (1+ (length (nth i headings))))
+                                 list)))
+              (reverse list))))
+    ;; Print headings.
+    (let ((heading (propertize " " 'display '(space :align-to 0))))
+      (dotimes (i columns)
+        (setq heading (concat heading
+                              (format (concat "%-" (number-to-string (nth i widths)) "s")
+                                      (nth i headings)))))
+      (setq header-line-format heading))
+    ;; Print tabulated rows.
+    (dolist (row rows)
+      (dotimes (i columns)
+        (insert (format (concat "%-" (number-to-string (nth i widths)) "s")
+                        (nth i row))))
+      (insert "\n"))))
+
+(defun haskell-menu-mode-ret ()
+  "Handle RET key."
+  (interactive)
+  (let* ((name (save-excursion
+                 (goto-char (line-beginning-position))
+                 (buffer-substring-no-properties (point)
+                                                 (progn (search-forward " ")
+                                                        (forward-char -1)
+                                                        (point)))))
+         (session (car (cl-remove-if-not (lambda (session)
+                                           (string= (haskell-session-name session)
+                                                    name))
+                                         haskell-sessions))))
+    (switch-to-buffer (haskell-session-interactive-buffer session))))
+
+(provide 'haskell-menu)
+
+;;; haskell-menu.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-menu.elc b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-menu.elc
new file mode 100644
index 0000000000..c1a3de07d0
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-menu.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-mode-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-mode-autoloads.el
new file mode 100644
index 0000000000..8e49f2f0b4
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-mode-autoloads.el
@@ -0,0 +1,1011 @@
+;;; haskell-mode-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "ghc-core" "ghc-core.el" (23377 61614 464227
+;;;;;;  981000))
+;;; Generated autoloads from ghc-core.el
+
+(let ((loads (get 'ghc-core 'custom-loads))) (if (member '"ghc-core" loads) nil (put 'ghc-core 'custom-loads (cons '"ghc-core" loads))))
+
+(autoload 'ghc-core-create-core "ghc-core" "\
+Compile and load the current buffer as tidy core.
+
+\(fn)" t nil)
+
+(add-to-list 'auto-mode-alist '("\\.hcr\\'" . ghc-core-mode))
+
+(add-to-list 'auto-mode-alist '("\\.dump-simpl\\'" . ghc-core-mode))
+
+(autoload 'ghc-core-mode "ghc-core" "\
+Major mode for GHC Core files.
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "ghci-script-mode" "ghci-script-mode.el" (23377
+;;;;;;  61614 444618 708000))
+;;; Generated autoloads from ghci-script-mode.el
+
+(autoload 'ghci-script-mode "ghci-script-mode" "\
+Major mode for working with .ghci files.
+
+\(fn)" t nil)
+
+(add-to-list 'auto-mode-alist '("\\.ghci\\'" . ghci-script-mode))
+
+;;;***
+
+;;;### (autoloads nil "haskell" "haskell.el" (23377 61614 468670
+;;;;;;  911000))
+;;; Generated autoloads from haskell.el
+
+(autoload 'interactive-haskell-mode "haskell" "\
+Minor mode for enabling haskell-process interaction.
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'haskell-interactive-mode-return "haskell" "\
+Handle the return key.
+
+\(fn)" t nil)
+
+(autoload 'haskell-session-kill "haskell" "\
+Kill the session process and buffer, delete the session.
+0. Prompt to kill all associated buffers.
+1. Kill the process.
+2. Kill the interactive buffer unless LEAVE-INTERACTIVE-BUFFER is not given.
+3. Walk through all the related buffers and set their haskell-session to nil.
+4. Remove the session from the sessions list.
+
+\(fn &optional LEAVE-INTERACTIVE-BUFFER)" t nil)
+
+(autoload 'haskell-interactive-kill "haskell" "\
+Kill the buffer and (maybe) the session.
+
+\(fn)" t nil)
+
+(autoload 'haskell-session "haskell" "\
+Get the Haskell session, prompt if there isn't one or fail.
+
+\(fn)" nil nil)
+
+(autoload 'haskell-interactive-switch "haskell" "\
+Switch to the interactive mode for this session.
+
+\(fn)" t nil)
+
+(autoload 'haskell-session-change "haskell" "\
+Change the session for the current buffer.
+
+\(fn)" t nil)
+
+(autoload 'haskell-kill-session-process "haskell" "\
+Kill the process.
+
+\(fn &optional SESSION)" t nil)
+
+(autoload 'haskell-interactive-mode-visit-error "haskell" "\
+Visit the buffer of the current (or last) error message.
+
+\(fn)" t nil)
+
+(autoload 'haskell-mode-jump-to-tag "haskell" "\
+Jump to the tag of the given identifier.
+
+Give optional NEXT-P parameter to override value of
+`xref-prompt-for-identifier' during definition search.
+
+\(fn &optional NEXT-P)" t nil)
+
+(autoload 'haskell-mode-after-save-handler "haskell" "\
+Function that will be called after buffer's saving.
+
+\(fn)" nil nil)
+
+(autoload 'haskell-mode-tag-find "haskell" "\
+The tag find function, specific for the particular session.
+
+\(fn &optional NEXT-P)" t nil)
+
+(autoload 'haskell-interactive-bring "haskell" "\
+Bring up the interactive mode for this session.
+
+\(fn)" t nil)
+
+(autoload 'haskell-process-load-file "haskell" "\
+Load the current buffer file.
+
+\(fn)" t nil)
+
+(autoload 'haskell-process-reload "haskell" "\
+Re-load the current buffer file.
+
+\(fn)" t nil)
+
+(autoload 'haskell-process-reload-file "haskell" "\
+
+
+\(fn)" nil nil)
+
+(autoload 'haskell-process-load-or-reload "haskell" "\
+Load or reload. Universal argument toggles which.
+
+\(fn &optional TOGGLE)" t nil)
+
+(autoload 'haskell-process-cabal-build "haskell" "\
+Build the Cabal project.
+
+\(fn)" t nil)
+
+(autoload 'haskell-process-cabal "haskell" "\
+Prompts for a Cabal command to run.
+
+\(fn P)" t nil)
+
+(autoload 'haskell-process-minimal-imports "haskell" "\
+Dump minimal imports.
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "haskell-align-imports" "haskell-align-imports.el"
+;;;;;;  (23377 61614 510222 266000))
+;;; Generated autoloads from haskell-align-imports.el
+
+(autoload 'haskell-align-imports "haskell-align-imports" "\
+Align all the imports in the buffer.
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "haskell-c2hs" "haskell-c2hs.el" (23377 61614
+;;;;;;  473135 401000))
+;;; Generated autoloads from haskell-c2hs.el
+
+(add-to-list 'auto-mode-alist '("\\.chs\\'" . haskell-c2hs-mode))
+
+(autoload 'haskell-c2hs-mode "haskell-c2hs" "\
+Mode for editing *.chs files of the c2hs haskell tool.
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "haskell-cabal" "haskell-cabal.el" (23377 61614
+;;;;;;  491779 380000))
+;;; Generated autoloads from haskell-cabal.el
+
+(add-to-list 'auto-mode-alist '("\\.cabal\\'" . haskell-cabal-mode))
+
+(autoload 'haskell-cabal-mode "haskell-cabal" "\
+Major mode for Cabal package description files.
+
+\(fn)" t nil)
+
+(autoload 'haskell-cabal-get-field "haskell-cabal" "\
+Read the value of field with NAME from project's cabal file.
+If there is no valid .cabal file to get the setting from (or
+there is no corresponding setting with that name in the .cabal
+file), then this function returns nil.
+
+\(fn NAME)" t nil)
+
+(autoload 'haskell-cabal-get-dir "haskell-cabal" "\
+Get the Cabal dir for a new project. Various ways of figuring this out,
+   and indeed just prompting the user. Do them all.
+
+\(fn &optional USE-DEFAULTS)" nil nil)
+
+(autoload 'haskell-cabal-visit-file "haskell-cabal" "\
+Locate and visit package description file for file visited by current buffer.
+This uses `haskell-cabal-find-file' to locate the closest
+\".cabal\" file and open it.  This command assumes a common Cabal
+project structure where the \".cabal\" file is in the top-folder
+of the project, and all files related to the project are in or
+below the top-folder.  If called with non-nil prefix argument
+OTHER-WINDOW use `find-file-other-window'.
+
+\(fn OTHER-WINDOW)" t nil)
+
+(let ((loads (get 'haskell-cabal 'custom-loads))) (if (member '"haskell-cabal" loads) nil (put 'haskell-cabal 'custom-loads (cons '"haskell-cabal" loads))))
+
+;;;***
+
+;;;### (autoloads nil "haskell-collapse" "haskell-collapse.el" (23377
+;;;;;;  61614 449081 791000))
+;;; Generated autoloads from haskell-collapse.el
+
+(autoload 'haskell-collapse-mode "haskell-collapse" "\
+Minor mode to collapse and expand haskell expressions
+
+\(fn &optional ARG)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "haskell-commands" "haskell-commands.el" (23377
+;;;;;;  61614 507848 25000))
+;;; Generated autoloads from haskell-commands.el
+
+(autoload 'haskell-process-restart "haskell-commands" "\
+Restart the inferior Haskell process.
+
+\(fn)" t nil)
+
+(autoload 'haskell-process-clear "haskell-commands" "\
+Clear the current process.
+
+\(fn)" t nil)
+
+(autoload 'haskell-process-interrupt "haskell-commands" "\
+Interrupt the process (SIGINT).
+
+\(fn)" t nil)
+
+(autoload 'haskell-describe "haskell-commands" "\
+Describe the given identifier IDENT.
+
+\(fn IDENT)" t nil)
+
+(autoload 'haskell-rgrep "haskell-commands" "\
+Grep the effective project for the symbol at point.
+Very useful for codebase navigation.
+
+Prompts for an arbitrary regexp given a prefix arg PROMPT.
+
+\(fn &optional PROMPT)" t nil)
+
+(autoload 'haskell-process-do-info "haskell-commands" "\
+Print info on the identifier at point.
+If PROMPT-VALUE is non-nil, request identifier via mini-buffer.
+
+\(fn &optional PROMPT-VALUE)" t nil)
+
+(autoload 'haskell-process-do-type "haskell-commands" "\
+Print the type of the given expression.
+
+Given INSERT-VALUE prefix indicates that result type signature
+should be inserted.
+
+\(fn &optional INSERT-VALUE)" t nil)
+
+(autoload 'haskell-mode-jump-to-def-or-tag "haskell-commands" "\
+Jump to the definition.
+Jump to definition of identifier at point by consulting GHCi, or
+tag table as fallback.
+
+Remember: If GHCi is busy doing something, this will delay, but
+it will always be accurate, in contrast to tags, which always
+work but are not always accurate.
+If the definition or tag is found, the location from which you jumped
+will be pushed onto `xref--marker-ring', so you can return to that
+position with `xref-pop-marker-stack'.
+
+\(fn &optional NEXT-P)" t nil)
+
+(autoload 'haskell-mode-goto-loc "haskell-commands" "\
+Go to the location of the thing at point.
+Requires the :loc-at command from GHCi.
+
+\(fn)" t nil)
+
+(autoload 'haskell-mode-jump-to-def "haskell-commands" "\
+Jump to definition of identifier IDENT at point.
+
+\(fn IDENT)" t nil)
+
+(autoload 'haskell-process-cd "haskell-commands" "\
+Change directory.
+
+\(fn &optional NOT-INTERACTIVE)" t nil)
+
+(autoload 'haskell-process-cabal-macros "haskell-commands" "\
+Send the cabal macros string.
+
+\(fn)" t nil)
+
+(autoload 'haskell-mode-show-type-at "haskell-commands" "\
+Show type of the thing at point or within active region asynchronously.
+This function requires GHCi 8+ or GHCi-ng.
+
+\\<haskell-interactive-mode-map>
+To make this function works sometimes you need to load the file in REPL
+first using command `haskell-process-load-file' bound to
+\\[haskell-process-load-file].
+
+Optional argument INSERT-VALUE indicates that
+recieved type signature should be inserted (but only if nothing
+happened since function invocation).
+
+\(fn &optional INSERT-VALUE)" t nil)
+
+(autoload 'haskell-process-unignore "haskell-commands" "\
+Unignore any ignored files.
+Do not ignore files that were specified as being ignored by the
+inferior GHCi process.
+
+\(fn)" t nil)
+
+(autoload 'haskell-session-change-target "haskell-commands" "\
+Set the build TARGET for cabal REPL.
+
+\(fn TARGET)" t nil)
+
+(autoload 'haskell-mode-stylish-buffer "haskell-commands" "\
+Apply stylish-haskell to the current buffer.
+
+Use `haskell-mode-stylish-haskell-path' to know where to find
+stylish-haskell executable. This function tries to preserve
+cursor position and markers by using
+`haskell-mode-buffer-apply-command'.
+
+\(fn)" t nil)
+
+(autoload 'haskell-mode-find-uses "haskell-commands" "\
+Find use cases of the identifier at point and highlight them all.
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "haskell-compile" "haskell-compile.el" (23377
+;;;;;;  61614 495238 977000))
+;;; Generated autoloads from haskell-compile.el
+
+(let ((loads (get 'haskell-compile 'custom-loads))) (if (member '"haskell-compile" loads) nil (put 'haskell-compile 'custom-loads (cons '"haskell-compile" loads))))
+
+(autoload 'haskell-compile "haskell-compile" "\
+Compile the Haskell program including the current buffer.
+Tries to locate the next cabal description in current or parent
+folders via `haskell-cabal-find-dir' and if found, invoke
+`haskell-compile-cabal-build-command' from the cabal package root
+folder. If no cabal package could be detected,
+`haskell-compile-command' is used instead.
+
+If prefix argument EDIT-COMMAND is non-nil (and not a negative
+prefix `-'), `haskell-compile' prompts for custom compile
+command.
+
+If EDIT-COMMAND contains the negative prefix argument `-',
+`haskell-compile' calls the alternative command defined in
+`haskell-compile-cabal-build-alt-command' if a cabal package was
+detected.
+
+`haskell-compile' uses `haskell-compilation-mode' which is
+derived from `compilation-mode'. See Info
+node `(haskell-mode)compilation' for more details.
+
+\(fn &optional EDIT-COMMAND)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "haskell-completions" "haskell-completions.el"
+;;;;;;  (23377 61614 502566 919000))
+;;; Generated autoloads from haskell-completions.el
+
+(let ((loads (get 'haskell-completions 'custom-loads))) (if (member '"haskell-completions" loads) nil (put 'haskell-completions 'custom-loads (cons '"haskell-completions" loads))))
+
+(autoload 'haskell-completions-completion-at-point "haskell-completions" "\
+Provide completion list for thing at point.
+This function is used in non-interactive `haskell-mode'.  It
+provides completions for haskell keywords, language pragmas,
+GHC's options, and language extensions, but not identifiers.
+
+\(fn)" nil nil)
+
+;;;***
+
+;;;### (autoloads nil "haskell-customize" "haskell-customize.el"
+;;;;;;  (23377 61614 493162 389000))
+;;; Generated autoloads from haskell-customize.el
+
+(let ((loads (get 'haskell 'custom-loads))) (if (member '"haskell-customize" loads) nil (put 'haskell 'custom-loads (cons '"haskell-customize" loads))))
+
+(let ((loads (get 'haskell-interactive 'custom-loads))) (if (member '"haskell-customize" loads) nil (put 'haskell-interactive 'custom-loads (cons '"haskell-customize" loads))))
+
+;;;***
+
+;;;### (autoloads nil "haskell-debug" "haskell-debug.el" (23377 61614
+;;;;;;  443095 895000))
+;;; Generated autoloads from haskell-debug.el
+
+(let ((loads (get 'haskell-debug 'custom-loads))) (if (member '"haskell-debug" loads) nil (put 'haskell-debug 'custom-loads (cons '"haskell-debug" loads))))
+
+(defface haskell-debug-warning-face '((t :inherit 'compilation-warning)) "\
+Face for warnings." :group (quote haskell-debug))
+
+(defface haskell-debug-trace-number-face '((t :weight bold :background "#f5f5f5")) "\
+Face for numbers in backtrace." :group (quote haskell-debug))
+
+(defface haskell-debug-newline-face '((t :weight bold :background "#f0f0f0")) "\
+Face for newlines in trace steps." :group (quote haskell-debug))
+
+(defface haskell-debug-keybinding-face '((t :inherit 'font-lock-type-face :weight bold)) "\
+Face for keybindings." :group (quote haskell-debug))
+
+(defface haskell-debug-heading-face '((t :inherit 'font-lock-keyword-face)) "\
+Face for headings." :group (quote haskell-debug))
+
+(defface haskell-debug-muted-face '((t :foreground "#999")) "\
+Face for muteds." :group (quote haskell-debug))
+
+;;;***
+
+;;;### (autoloads nil "haskell-decl-scan" "haskell-decl-scan.el"
+;;;;;;  (23377 61614 526149 653000))
+;;; Generated autoloads from haskell-decl-scan.el
+
+(let ((loads (get 'haskell-decl-scan 'custom-loads))) (if (member '"haskell-decl-scan" loads) nil (put 'haskell-decl-scan 'custom-loads (cons '"haskell-decl-scan" loads))))
+
+(autoload 'haskell-ds-create-imenu-index "haskell-decl-scan" "\
+Function for finding `imenu' declarations in Haskell mode.
+Finds all declarations (classes, variables, imports, instances and
+datatypes) in a Haskell file for the `imenu' package.
+
+\(fn)" nil nil)
+
+(autoload 'turn-on-haskell-decl-scan "haskell-decl-scan" "\
+Unconditionally activate `haskell-decl-scan-mode'.
+
+\(fn)" t nil)
+
+(autoload 'haskell-decl-scan-mode "haskell-decl-scan" "\
+Toggle Haskell declaration scanning minor mode on or off.
+With a prefix argument ARG, enable minor mode if ARG is
+positive, and disable it otherwise.  If called from Lisp, enable
+the mode if ARG is omitted or nil, and toggle it if ARG is `toggle'.
+
+See also info node `(haskell-mode)haskell-decl-scan-mode' for
+more details about this minor mode.
+
+Top-level declarations are scanned and listed in the menu item
+\"Declarations\" (if enabled via option
+`haskell-decl-scan-add-to-menubar').  Selecting an item from this
+menu will take point to the start of the declaration.
+
+\\[beginning-of-defun] and \\[end-of-defun] move forward and backward to the start of a declaration.
+
+This may link with `haskell-doc-mode'.
+
+For non-literate and LaTeX-style literate scripts, we assume the
+common convention that top-level declarations start at the first
+column.  For Bird-style literate scripts, we assume the common
+convention that top-level declarations start at the third column,
+ie. after \"> \".
+
+Anything in `font-lock-comment-face' is not considered for a
+declaration.  Therefore, using Haskell font locking with comments
+coloured in `font-lock-comment-face' improves declaration scanning.
+
+Literate Haskell scripts are supported: If the value of
+`haskell-literate' (set automatically by `literate-haskell-mode')
+is `bird', a Bird-style literate script is assumed.  If it is nil
+or `tex', a non-literate or LaTeX-style literate script is
+assumed, respectively.
+
+Invokes `haskell-decl-scan-mode-hook' on activation.
+
+\(fn &optional ARG)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "haskell-doc" "haskell-doc.el" (23377 61614
+;;;;;;  465805 530000))
+;;; Generated autoloads from haskell-doc.el
+
+(let ((loads (get 'haskell-doc 'custom-loads))) (if (member '"haskell-doc" loads) nil (put 'haskell-doc 'custom-loads (cons '"haskell-doc" loads))))
+
+(autoload 'haskell-doc-mode "haskell-doc" "\
+Enter `haskell-doc-mode' for showing fct types in the echo area.
+See variable docstring.
+
+\(fn &optional ARG)" t nil)
+
+(defalias 'turn-on-haskell-doc-mode 'haskell-doc-mode)
+
+(defalias 'turn-on-haskell-doc 'haskell-doc-mode)
+
+(autoload 'haskell-doc-current-info "haskell-doc" "\
+Return the info about symbol at point.
+Meant for `eldoc-documentation-function'.
+
+\(fn)" nil nil)
+
+(autoload 'haskell-doc-show-type "haskell-doc" "\
+Show the type of the function near point or given symbol SYM.
+For the function under point, show the type in the echo area.
+This information is extracted from the `haskell-doc-prelude-types' alist
+of prelude functions and their types, or from the local functions in the
+current buffer.
+
+\(fn &optional SYM)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "haskell-font-lock" "haskell-font-lock.el"
+;;;;;;  (23377 61614 481501 453000))
+;;; Generated autoloads from haskell-font-lock.el
+
+(let ((loads (get 'haskell-appearance 'custom-loads))) (if (member '"haskell-font-lock" loads) nil (put 'haskell-appearance 'custom-loads (cons '"haskell-font-lock" loads))))
+
+(defface haskell-keyword-face '((t :inherit font-lock-keyword-face)) "\
+Face used to highlight Haskell keywords." :group (quote haskell-appearance))
+
+(defface haskell-type-face '((t :inherit font-lock-type-face)) "\
+Face used to highlight Haskell types" :group (quote haskell-appearance))
+
+(defface haskell-constructor-face '((t :inherit font-lock-type-face)) "\
+Face used to highlight Haskell constructors." :group (quote haskell-appearance))
+
+(defface haskell-operator-face '((t :inherit font-lock-variable-name-face)) "\
+Face used to highlight Haskell operators." :group (quote haskell-appearance))
+
+(defface haskell-pragma-face '((t :inherit font-lock-preprocessor-face)) "\
+Face used to highlight Haskell pragmas ({-# ... #-})." :group (quote haskell-appearance))
+
+(defface haskell-liquid-haskell-annotation-face '((t :inherit haskell-pragma-face)) "\
+Face used to highlight LiquidHaskell annotations ({-@ ... @-})." :group (quote haskell-appearance))
+
+(defface haskell-literate-comment-face '((t :inherit font-lock-doc-face)) "\
+Face with which to fontify literate comments.
+Inherit from `default' to avoid fontification of them." :group (quote haskell-appearance))
+
+;;;***
+
+;;;### (autoloads nil "haskell-hoogle" "haskell-hoogle.el" (23377
+;;;;;;  61614 467321 953000))
+;;; Generated autoloads from haskell-hoogle.el
+
+(autoload 'haskell-hoogle "haskell-hoogle" "\
+Do a Hoogle search for QUERY.
+When `haskell-hoogle-command' is non-nil, this command runs
+that.  Otherwise, it opens a hoogle search result in the browser.
+
+If prefix argument INFO is given, then `haskell-hoogle-command'
+is asked to show extra info for the items matching QUERY..
+
+\(fn QUERY &optional INFO)" t nil)
+
+(defalias 'hoogle 'haskell-hoogle)
+
+(autoload 'haskell-hoogle-lookup-from-local "haskell-hoogle" "\
+Lookup by local hoogle.
+
+\(fn)" t nil)
+
+(autoload 'haskell-hayoo "haskell-hoogle" "\
+Do a Hayoo search for QUERY.
+
+\(fn QUERY)" t nil)
+
+(defalias 'hayoo 'haskell-hayoo)
+
+;;;***
+
+;;;### (autoloads nil "haskell-indent" "haskell-indent.el" (23377
+;;;;;;  61614 517159 450000))
+;;; Generated autoloads from haskell-indent.el
+
+(let ((loads (get 'haskell-indent 'custom-loads))) (if (member '"haskell-indent" loads) nil (put 'haskell-indent 'custom-loads (cons '"haskell-indent" loads))))
+
+(autoload 'turn-on-haskell-indent "haskell-indent" "\
+Turn on ``intelligent'' Haskell indentation mode.
+
+\(fn)" nil nil)
+
+(autoload 'haskell-indent-mode "haskell-indent" "\
+``Intelligent'' Haskell indentation mode.
+This deals with the layout rule of Haskell.
+\\[haskell-indent-cycle] starts the cycle which proposes new
+possibilities as long as the TAB key is pressed.  Any other key
+or mouse click terminates the cycle and is interpreted except for
+RET which merely exits the cycle.
+Other special keys are:
+    \\[haskell-indent-insert-equal]
+      inserts an =
+    \\[haskell-indent-insert-guard]
+      inserts an |
+    \\[haskell-indent-insert-otherwise]
+      inserts an | otherwise =
+these functions also align the guards and rhs of the current definition
+    \\[haskell-indent-insert-where]
+      inserts a where keyword
+    \\[haskell-indent-align-guards-and-rhs]
+      aligns the guards and rhs of the region
+    \\[haskell-indent-put-region-in-literate]
+      makes the region a piece of literate code in a literate script
+
+If `ARG' is falsey, toggle `haskell-indent-mode'.  Else sets
+`haskell-indent-mode' to whether `ARG' is greater than 0.
+
+Invokes `haskell-indent-hook' if not nil.
+
+\(fn &optional ARG)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "haskell-indentation" "haskell-indentation.el"
+;;;;;;  (23377 61614 474683 85000))
+;;; Generated autoloads from haskell-indentation.el
+
+(let ((loads (get 'haskell-indentation 'custom-loads))) (if (member '"haskell-indentation" loads) nil (put 'haskell-indentation 'custom-loads (cons '"haskell-indentation" loads))))
+
+(autoload 'haskell-indentation-mode "haskell-indentation" "\
+Haskell indentation mode that deals with the layout rule.
+It rebinds RET, DEL and BACKSPACE, so that indentations can be
+set and deleted as if they were real tabs.
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'turn-on-haskell-indentation "haskell-indentation" "\
+Turn on the haskell-indentation minor mode.
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "haskell-interactive-mode" "haskell-interactive-mode.el"
+;;;;;;  (23377 61614 446289 590000))
+;;; Generated autoloads from haskell-interactive-mode.el
+
+(defface haskell-interactive-face-prompt '((t :inherit font-lock-function-name-face)) "\
+Face for the prompt." :group (quote haskell-interactive))
+
+(defface haskell-interactive-face-prompt2 '((t :inherit font-lock-keyword-face)) "\
+Face for the prompt2 in multi-line mode." :group (quote haskell-interactive))
+
+(defface haskell-interactive-face-compile-error '((t :inherit compilation-error)) "\
+Face for compile errors." :group (quote haskell-interactive))
+
+(defface haskell-interactive-face-compile-warning '((t :inherit compilation-warning)) "\
+Face for compiler warnings." :group (quote haskell-interactive))
+
+(defface haskell-interactive-face-result '((t :inherit font-lock-string-face)) "\
+Face for the result." :group (quote haskell-interactive))
+
+(defface haskell-interactive-face-garbage '((t :inherit font-lock-string-face)) "\
+Face for trailing garbage after a command has completed." :group (quote haskell-interactive))
+
+(autoload 'haskell-interactive-mode-reset-error "haskell-interactive-mode" "\
+Reset the error cursor position.
+
+\(fn SESSION)" t nil)
+
+(autoload 'haskell-interactive-mode-echo "haskell-interactive-mode" "\
+Echo a read only piece of text before the prompt.
+
+\(fn SESSION MESSAGE &optional MODE)" nil nil)
+
+(autoload 'haskell-process-show-repl-response "haskell-interactive-mode" "\
+Send LINE to the GHCi process and echo the result in some fashion.
+Result will be printed in the minibuffer or presented using
+function `haskell-presentation-present', depending on variable
+`haskell-process-use-presentation-mode'.
+
+\(fn LINE)" nil nil)
+
+;;;***
+
+;;;### (autoloads nil "haskell-load" "haskell-load.el" (23377 61614
+;;;;;;  434479 297000))
+;;; Generated autoloads from haskell-load.el
+
+(defface haskell-error-face '((((supports :underline (:style wave))) :underline (:style wave :color "#dc322f")) (t :inherit error)) "\
+Face used for marking error lines." :group (quote haskell-mode))
+
+(defface haskell-warning-face '((((supports :underline (:style wave))) :underline (:style wave :color "#b58900")) (t :inherit warning)) "\
+Face used for marking warning lines." :group (quote haskell-mode))
+
+(defface haskell-hole-face '((((supports :underline (:style wave))) :underline (:style wave :color "#6c71c4")) (t :inherit warning)) "\
+Face used for marking hole lines." :group (quote haskell-mode))
+
+(autoload 'haskell-process-reload-devel-main "haskell-load" "\
+Reload the module `DevelMain' and then run `DevelMain.update'.
+
+This is for doing live update of the code of servers or GUI
+applications.  Put your development version of the program in
+`DevelMain', and define `update' to auto-start the program on a
+new thread, and use the `foreign-store' package to access the
+running context across :load/:reloads in GHCi.
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "haskell-menu" "haskell-menu.el" (23377 61614
+;;;;;;  486880 305000))
+;;; Generated autoloads from haskell-menu.el
+
+(autoload 'haskell-menu "haskell-menu" "\
+Launch the Haskell sessions menu.
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "haskell-mode" "haskell-mode.el" (23377 61614
+;;;;;;  513037 533000))
+;;; Generated autoloads from haskell-mode.el
+
+(autoload 'haskell-version "haskell-mode" "\
+Show the `haskell-mode` version in the echo area.
+With prefix argument HERE, insert it at point.
+
+\(fn &optional HERE)" t nil)
+
+(autoload 'haskell-mode-view-news "haskell-mode" "\
+Display information on recent changes to haskell-mode.
+
+\(fn)" t nil)
+
+(autoload 'haskell-mode "haskell-mode" "\
+Major mode for editing Haskell programs.
+
+\\<haskell-mode-map>
+
+Literate Haskell scripts are supported via `literate-haskell-mode'.
+The variable `haskell-literate' indicates the style of the script in the
+current buffer.  See the documentation on this variable for more details.
+
+Use `haskell-version' to find out what version of Haskell mode you are
+currently using.
+
+Additional Haskell mode modules can be hooked in via `haskell-mode-hook'.
+
+Indentation modes:
+
+    `haskell-indentation-mode', Kristof Bastiaensen, Gergely Risko
+      Intelligent semi-automatic indentation Mk2
+
+    `haskell-indent-mode', Guy Lapalme
+      Intelligent semi-automatic indentation.
+
+Interaction modes:
+
+    `interactive-haskell-mode'
+      Interact with per-project GHCi processes through a REPL and
+      directory-aware sessions.
+
+Other modes:
+
+    `haskell-decl-scan-mode', Graeme E Moss
+      Scans top-level declarations, and places them in a menu.
+
+    `haskell-doc-mode', Hans-Wolfgang Loidl
+      Echoes types of functions or syntax of keywords when the cursor is idle.
+
+To activate a minor-mode, simply run the interactive command. For
+example, `M-x haskell-doc-mode'. Run it again to disable it.
+
+To enable a mode for every haskell-mode buffer, add a hook in
+your Emacs configuration. To do that you can customize
+`haskell-mode-hook' or add lines to your .emacs file. For
+example, to enable `interactive-haskell-mode', use the following:
+
+    (add-hook 'haskell-mode-hook 'interactive-haskell-mode)
+
+Minor modes that work well with `haskell-mode':
+
+- `smerge-mode': show and work with diff3 conflict markers used
+  by git, svn and other version control systems.
+
+\(fn)" t nil)
+
+(autoload 'haskell-forward-sexp "haskell-mode" "\
+Haskell specific version of `forward-sexp'.
+
+Move forward across one balanced expression (sexp).  With ARG, do
+it that many times.  Negative arg -N means move backward across N
+balanced expressions.  This command assumes point is not in a
+string or comment.
+
+If unable to move over a sexp, signal `scan-error' with three
+arguments: a message, the start of the obstacle (a parenthesis or
+list marker of some kind), and end of the obstacle.
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'literate-haskell-mode "haskell-mode" "\
+As `haskell-mode' but for literate scripts.
+
+\(fn)" t nil)
+
+(add-to-list 'auto-mode-alist '("\\.[gh]s\\'" . haskell-mode))
+
+(add-to-list 'auto-mode-alist '("\\.hsig\\'" . haskell-mode))
+
+(add-to-list 'auto-mode-alist '("\\.l[gh]s\\'" . literate-haskell-mode))
+
+(add-to-list 'auto-mode-alist '("\\.hsc\\'" . haskell-mode))
+
+(add-to-list 'interpreter-mode-alist '("runghc" . haskell-mode))
+
+(add-to-list 'interpreter-mode-alist '("runhaskell" . haskell-mode))
+
+(add-to-list 'completion-ignored-extensions ".hi")
+
+(autoload 'haskell-mode-generate-tags "haskell-mode" "\
+Generate tags using Hasktags.  This is synchronous function.
+
+If optional AND-THEN-FIND-THIS-TAG argument is present it is used
+with function `xref-find-definitions' after new table was
+generated.
+
+\(fn &optional AND-THEN-FIND-THIS-TAG)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "haskell-modules" "haskell-modules.el" (23377
+;;;;;;  61614 520638 53000))
+;;; Generated autoloads from haskell-modules.el
+
+(autoload 'haskell-session-installed-modules "haskell-modules" "\
+Get the modules installed in the current package set.
+
+\(fn SESSION &optional DONTCREATE)" nil nil)
+
+(autoload 'haskell-session-all-modules "haskell-modules" "\
+Get all modules -- installed or in the current project.
+If DONTCREATE is non-nil don't create a new session.
+
+\(fn SESSION &optional DONTCREATE)" nil nil)
+
+(autoload 'haskell-session-project-modules "haskell-modules" "\
+Get the modules of the current project.
+If DONTCREATE is non-nil don't create a new session.
+
+\(fn SESSION &optional DONTCREATE)" nil nil)
+
+;;;***
+
+;;;### (autoloads nil "haskell-move-nested" "haskell-move-nested.el"
+;;;;;;  (23377 61614 514693 505000))
+;;; Generated autoloads from haskell-move-nested.el
+
+(autoload 'haskell-move-nested "haskell-move-nested" "\
+Shift the nested off-side-rule block adjacent to point by COLS columns to the right.
+
+In Transient Mark mode, if the mark is active, operate on the contents
+of the region instead.
+
+\(fn COLS)" nil nil)
+
+(autoload 'haskell-move-nested-right "haskell-move-nested" "\
+Increase indentation of the following off-side-rule block adjacent to point.
+
+Use a numeric prefix argument to indicate amount of indentation to apply.
+
+In Transient Mark mode, if the mark is active, operate on the contents
+of the region instead.
+
+\(fn COLS)" t nil)
+
+(autoload 'haskell-move-nested-left "haskell-move-nested" "\
+Decrease indentation of the following off-side-rule block adjacent to point.
+
+Use a numeric prefix argument to indicate amount of indentation to apply.
+
+In Transient Mark mode, if the mark is active, operate on the contents
+of the region instead.
+
+\(fn COLS)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "haskell-navigate-imports" "haskell-navigate-imports.el"
+;;;;;;  (23377 61614 522273 319000))
+;;; Generated autoloads from haskell-navigate-imports.el
+
+(autoload 'haskell-navigate-imports "haskell-navigate-imports" "\
+Cycle the Haskell import lines or return to point (with prefix arg).
+
+\(fn &optional RETURN)" t nil)
+
+(autoload 'haskell-navigate-imports-go "haskell-navigate-imports" "\
+Go to the first line of a list of consecutive import lines. Cycles.
+
+\(fn)" t nil)
+
+(autoload 'haskell-navigate-imports-return "haskell-navigate-imports" "\
+Return to the non-import point we were at before going to the module list.
+   If we were originally at an import list, we can just cycle through easily.
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "haskell-session" "haskell-session.el" (23377
+;;;;;;  61614 476646 160000))
+;;; Generated autoloads from haskell-session.el
+
+(autoload 'haskell-session-maybe "haskell-session" "\
+Maybe get the Haskell session, return nil if there isn't one.
+
+\(fn)" nil nil)
+
+(autoload 'haskell-session-process "haskell-session" "\
+Get the session process.
+
+\(fn S)" nil nil)
+
+;;;***
+
+;;;### (autoloads nil "haskell-sort-imports" "haskell-sort-imports.el"
+;;;;;;  (23377 61614 489920 40000))
+;;; Generated autoloads from haskell-sort-imports.el
+
+(autoload 'haskell-sort-imports "haskell-sort-imports" "\
+Sort the import list at point. It sorts the current group
+i.e. an import list separated by blank lines on either side.
+
+If the region is active, it will restrict the imports to sort
+within that region.
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "haskell-unicode-input-method" "haskell-unicode-input-method.el"
+;;;;;;  (23377 61614 457460 312000))
+;;; Generated autoloads from haskell-unicode-input-method.el
+
+(autoload 'turn-on-haskell-unicode-input-method "haskell-unicode-input-method" "\
+Set input method `haskell-unicode'.
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "highlight-uses-mode" "highlight-uses-mode.el"
+;;;;;;  (23377 61614 499589 351000))
+;;; Generated autoloads from highlight-uses-mode.el
+
+(autoload 'highlight-uses-mode "highlight-uses-mode" "\
+Minor mode for highlighting and jumping between uses.
+
+\(fn &optional ARG)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "inf-haskell" "inf-haskell.el" (23377 61614
+;;;;;;  441568 997000))
+;;; Generated autoloads from inf-haskell.el
+
+(let ((loads (get 'inferior-haskell 'custom-loads))) (if (member '"inf-haskell" loads) nil (put 'inferior-haskell 'custom-loads (cons '"inf-haskell" loads))))
+
+(defalias 'run-haskell 'switch-to-haskell)
+
+(autoload 'switch-to-haskell "inf-haskell" "\
+Show the inferior-haskell buffer.  Start the process if needed.
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "w3m-haddock" "w3m-haddock.el" (23377 61614
+;;;;;;  505606 375000))
+;;; Generated autoloads from w3m-haddock.el
+
+(defface w3m-haddock-heading-face '((((class color)) :inherit highlight)) "\
+Face for quarantines." :group (quote haskell))
+
+;;;***
+
+;;;### (autoloads nil nil ("haskell-compat.el" "haskell-complete-module.el"
+;;;;;;  "haskell-ghc-support.el" "haskell-lexeme.el" "haskell-mode-pkg.el"
+;;;;;;  "haskell-presentation-mode.el" "haskell-process.el" "haskell-repl.el"
+;;;;;;  "haskell-sandbox.el" "haskell-string.el" "haskell-utils.el")
+;;;;;;  (23377 61614 524498 941000))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; haskell-mode-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-mode-pkg.el b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-mode-pkg.el
new file mode 100644
index 0000000000..5b37f9cac5
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-mode-pkg.el
@@ -0,0 +1,8 @@
+(define-package "haskell-mode" "20180601.143" "A Haskell editing mode"
+  '((emacs "24.3"))
+  :keywords
+  '("haskell" "cabal" "ghc" "repl")
+  :url "https://github.com/haskell/haskell-mode")
+;; Local Variables:
+;; no-byte-compile: t
+;; End:
diff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-mode.el b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-mode.el
new file mode 100644
index 0000000000..7823e13ddc
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-mode.el
@@ -0,0 +1,1195 @@
+;;; haskell-mode.el --- A Haskell editing mode    -*- coding: utf-8; lexical-binding: t -*-
+
+;; Copyright © 2003, 2004, 2005, 2006, 2007, 2008, 2016
+;;             Free Software Foundation, Inc
+
+;; Copyright © 1992, 1997-1998  Simon Marlow, Graeme E Moss, and Tommy Thorn
+
+;; Author:  1992      Simon Marlow
+;;          1997-1998 Graeme E Moss <gem@cs.york.ac.uk> and
+;;                    Tommy Thorn <thorn@irisa.fr>,
+;;          2001-2002 Reuben Thomas (>=v1.4)
+;;          2003      Dave Love <fx@gnu.org>
+;;          2016      Arthur Fayzrakhmanov
+;; Keywords: faces files Haskell
+;; Version: 16.2-git
+;; URL: https://github.com/haskell/haskell-mode
+
+;; This file is not part of GNU Emacs.
+
+;; This file 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, or (at your option)
+;; any later version.
+
+;; This file 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; A major mode for editing Haskell (the functional programming
+;; language, see URL `http://www.haskell.org') in Emacs.
+;;
+;; Some of its major features include:
+;;
+;;  - syntax highlighting (font lock),
+;;
+;;  - automatic indentation,
+;;
+;;  - on-the-fly documentation,
+;;
+;;  - interaction with inferior GHCi/Hugs instance,
+;;
+;;  - scans declarations and places them in a menu.
+;;
+;; See URL `https://github.com/haskell/haskell-mode' and/or
+;; Info node `(haskell-mode)Introduction' for more information.
+;;
+;; Use `M-x haskell-mode-view-news` (after Haskell Mode is installed)
+;; to show information on recent changes in Haskell Mode.
+
+;;; Change Log:
+
+;; This mode is based on an editing mode by Simon Marlow 11/1/92
+;; and heavily modified by Graeme E Moss and Tommy Thorn 7/11/98.
+;;
+;; Version 1.5:
+;;   Added autoload for haskell-indentation
+;;
+;; Version 1.43:
+;;   Various tweaks to doc strings and customization support from
+;;   Ville Skyttä <scop@xemacs.org>.
+;;
+;; Version 1.42:
+;;   Added autoload for GHCi inferior mode (thanks to Scott
+;;   Williams for the bug report and fix).
+;;
+;; Version 1.41:
+;;   Improved packaging, and made a couple more variables
+;;   interactively settable.
+;;
+;; Version 1.4:
+;;   Added GHCi mode from Chris Webb, and tidied up a little.
+;;
+;; Version 1.3:
+;;   The literate or non-literate style of a buffer is now indicated
+;;   by just the variable haskell-literate: nil, `bird', or `tex'.
+;;   For literate buffers with ambiguous style, the value of
+;;   haskell-literate-default is used.
+;;
+;; Version 1.2:
+;;   Separated off font locking, declaration scanning and simple
+;;   indentation, and made them separate modules.  Modules can be
+;;   added easily now.  Support for modules haskell-doc,
+;;   haskell-indent, and haskell-hugs.  Literate and non-literate
+;;   modes integrated into one mode, and literate buffer indicated by
+;;   value of haskell-literate(-bird-style).
+;;
+;; Version 1.1:
+;;   Added support for declaration scanning under XEmacs via
+;;   func-menu.  Moved operators to level two fontification.
+;;
+;; Version 1.0:
+;;   Added a nice indention support from Heribert Schuetz
+;;   <Heribert.Schuetz@informatik.uni-muenchen.de>:
+;;
+;;     I have just hacked an Emacs Lisp function which you might prefer
+;;     to `indent-relative' in haskell-mode.el.  See below.  It is not
+;;     really Haskell-specific because it does not take into account
+;;     keywords like `do', `of', and `let' (where the layout rule
+;;     applies), but I already find it useful.
+;;
+;;   Cleaned up the imenu support.  Added support for literate scripts.
+;;
+;; Version 0.103 [HWL]:
+;;   From Hans Wolfgang Loidl <hwloidl@dcs.gla.ac.uk>:
+;;
+;;   I (HWL) added imenu support by copying the appropriate functions
+;;   from hugs-mode.  A menu-bar item "Declarations" is now added in
+;;   haskell mode.  The new code, however, needs some clean-up.
+;;
+;; Version 0.102:
+;;
+;;   Moved C-c C-c key binding to comment-region.  Leave M-g M-g to do
+;;   the work.  comment-start-skip is changed to comply with comment-start.
+;;
+;; Version 0.101:
+;;
+;;   Altered indent-line-function to indent-relative.
+;;
+;; Version 0.100:
+;;
+;;   First official release.
+
+;;; Code:
+
+(require 'haskell-customize)
+(require 'ansi-color)
+(require 'dabbrev)
+(require 'compile)
+(require 'etags)
+(require 'flymake)
+(require 'outline)
+(require 'cl-lib)
+(require 'haskell-ghc-support)
+(require 'haskell-complete-module)
+(require 'haskell-compat)
+(require 'haskell-align-imports)
+(require 'haskell-lexeme)
+(require 'haskell-sort-imports)
+(require 'haskell-string)
+(require 'haskell-indentation)
+(require 'haskell-font-lock)
+(require 'haskell-cabal)
+
+;; All functions/variables start with `(literate-)haskell-'.
+
+;; Version of mode.
+(defconst haskell-version "16.2-git"
+  "The release version of `haskell-mode'.")
+
+;;;###autoload
+(defun haskell-version (&optional here)
+  "Show the `haskell-mode` version in the echo area.
+With prefix argument HERE, insert it at point."
+  (interactive "P")
+  (let* ((haskell-mode-dir (ignore-errors
+                             (file-name-directory (or (locate-library "haskell-mode") ""))))
+         (version (format "haskell-mode version %s (%s)"
+                           haskell-version
+                           haskell-mode-dir)))
+    (if here
+        (insert version)
+      (message "%s" version))))
+
+;;;###autoload
+(defun haskell-mode-view-news ()
+  "Display information on recent changes to haskell-mode."
+  (interactive)
+  (with-current-buffer (find-file-read-only (expand-file-name "NEWS" haskell-mode-pkg-base-dir))
+    (goto-char (point-min))
+    (outline-hide-sublevels 1)
+    (outline-next-visible-heading 1)
+    (outline-show-subtree)))
+
+;; Are we looking at a literate script?
+(defvar-local haskell-literate nil
+  "If not nil, the current buffer contains a literate Haskell script.
+Possible values are: `bird' and `tex', for Bird-style and LaTeX-style
+literate scripts respectively.  Set by `haskell-mode' and
+`literate-haskell-mode'.  For an ambiguous literate buffer -- i.e. does
+not contain either \"\\begin{code}\" or \"\\end{code}\" on a line on
+its own, nor does it contain \">\" at the start of a line -- the value
+of `haskell-literate-default' is used.")
+(put 'haskell-literate 'safe-local-variable 'symbolp)
+
+;; Default literate style for ambiguous literate buffers.
+(defcustom haskell-literate-default 'bird
+  "Default value for `haskell-literate'.
+Used if the style of a literate buffer is ambiguous.  This variable should
+be set to the preferred literate style."
+  :group 'haskell
+  :type '(choice (const bird) (const tex) (const nil)))
+
+(defvar haskell-mode-map
+  (let ((map (make-sparse-keymap)))
+    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+    ;; Editing-specific commands
+    (define-key map (kbd "C-c C-,") 'haskell-mode-format-imports)
+    (define-key map [remap delete-indentation] 'haskell-delete-indentation)
+    (define-key map (kbd "C-c C-l") 'haskell-mode-enable-process-minor-mode)
+    (define-key map (kbd "C-c C-b") 'haskell-mode-enable-process-minor-mode)
+    (define-key map (kbd "C-c C-v") 'haskell-mode-enable-process-minor-mode)
+    (define-key map (kbd "C-c C-t") 'haskell-mode-enable-process-minor-mode)
+    (define-key map (kbd "C-c C-i") 'haskell-mode-enable-process-minor-mode)
+    (define-key map (kbd "C-c C-s") 'haskell-mode-toggle-scc-at-point)
+    map)
+  "Keymap used in `haskell-mode'.")
+
+(defun haskell-mode-enable-process-minor-mode ()
+  "Tell the user to choose a minor mode for process interaction."
+  (interactive)
+  (error "Run `C-h f haskell-mode` for instruction how to setup a Haskell interaction mode."))
+
+(easy-menu-define haskell-mode-menu haskell-mode-map
+  "Menu for the Haskell major mode."
+  ;; Suggestions from Pupeno <pupeno@pupeno.com>:
+  ;; - choose the underlying interpreter
+  ;; - look up docs
+  `("Haskell"
+    ["Indent line" indent-according-to-mode]
+    ["(Un)Comment region" comment-region mark-active]
+    "---"
+    ["Start interpreter" haskell-interactive-switch]
+    ["Load file" haskell-process-load-file]
+    "---"
+    ["Load tidy core" ghc-core-create-core]
+    "---"
+    ,(if (default-boundp 'eldoc-documentation-function)
+         ["Doc mode" eldoc-mode
+          :style toggle :selected (bound-and-true-p eldoc-mode)]
+       ["Doc mode" haskell-doc-mode
+        :style toggle :selected (and (boundp 'haskell-doc-mode) haskell-doc-mode)])
+    ["Customize" (customize-group 'haskell)]
+    ))
+
+;; Procedurally generated (see Lexeme.hs in ghc).
+;; This is a bit unsightly: it's generated by making a list of all
+;; unicode characters whose Unicode general category ghc would
+;; recognize as valid symbol (or identifier, below) constituent.
+(defvar haskell--char-syntax-symbols
+  '((161 . 169) 172 (174 . 177) 180 (182 . 184) 191 215 247
+    (706 . 709) (722 . 735) (741 . 747) 749 (751 . 767) 885
+    894 (900 . 901) 903 1014 1154 (1370 . 1375) (1417 . 1418)
+    (1421 . 1423) 1470 1472 1475 1478 (1523 . 1524) (1542 . 1551)
+    1563 (1566 . 1567) (1642 . 1645) 1748 1758 1769 (1789 . 1790)
+    (1792 . 1805) (2038 . 2041) (2096 . 2110) 2142 (2404 . 2405)
+    2416 (2546 . 2547) (2554 . 2555) (2800 . 2801) 2928
+    (3059 . 3066) 3199 3449 3572 3647 3663 (3674 . 3675)
+    (3841 . 3863) (3866 . 3871) 3892 3894 3896 3973 (4030 . 4037)
+    (4039 . 4044) (4046 . 4058) (4170 . 4175) (4254 . 4255)
+    4347 (4960 . 4968) (5008 . 5017) 5120 (5741 . 5742)
+    (5867 . 5869) (5941 . 5942) (6100 . 6102) (6104 . 6107)
+    (6144 . 6154) 6464 (6468 . 6469) (6622 . 6623) (6624 . 6655)
+    (6686 . 6687) (6816 . 6822) (6824 . 6829) (7002 . 7018)
+    (7028 . 7036) (7164 . 7167) (7227 . 7231) (7294 . 7295)
+    (7360 . 7367) 7379 8125 (8127 . 8129) (8141 . 8143)
+    (8157 . 8159) (8173 . 8175) (8189 . 8190) (8208 . 8215)
+    (8224 . 8231) (8240 . 8248) (8251 . 8260) (8263 . 8286)
+    (8314 . 8316) (8330 . 8332) (8352 . 8381) (8448 . 8449)
+    (8451 . 8454) (8456 . 8457) 8468 (8470 . 8472) (8478 . 8483)
+    8485 8487 8489 8494 (8506 . 8507) (8512 . 8516) (8522 . 8525)
+    8527 (8592 . 8703) (8704 . 8959) (8960 . 8967) (8972 . 9000)
+    (9003 . 9210) (9216 . 9254) (9280 . 9290) (9372 . 9449)
+    (9472 . 9599) (9600 . 9631) (9632 . 9727) (9728 . 9983)
+    (9984 . 10087) (10132 . 10175) (10176 . 10180) (10183 . 10213)
+    (10224 . 10239) (10240 . 10495) (10496 . 10623) (10624 . 10626)
+    (10649 . 10711) (10716 . 10747) (10750 . 10751) (10752 . 11007)
+    (11008 . 11123) (11126 . 11157) (11160 . 11193) (11197 . 11208)
+    (11210 . 11217) (11493 . 11498) (11513 . 11516) (11518 . 11519)
+    11632 (11776 . 11777) (11782 . 11784) 11787 (11790 . 11803)
+    (11806 . 11807) (11818 . 11822) (11824 . 11841) (11904 . 11929)
+    (11931 . 12019) (12032 . 12245) (12272 . 12283) (12289 . 12292)
+    (12306 . 12307) 12316 12320 12336 (12342 . 12343)
+    (12349 . 12351) (12443 . 12444) 12448 12539 (12688 . 12689)
+    (12694 . 12703) (12736 . 12771) (12800 . 12830) (12842 . 12871)
+    12880 (12896 . 12927) (12938 . 12976) (12992 . 13054)
+    (13056 . 13311) (19904 . 19967) (42128 . 42182) (42238 . 42239)
+    (42509 . 42511) 42611 42622 (42738 . 42743) (42752 . 42774)
+    (42784 . 42785) (42889 . 42890) (43048 . 43051) (43062 . 43065)
+    (43124 . 43127) (43214 . 43215) (43256 . 43258) (43310 . 43311)
+    43359 (43457 . 43469) (43486 . 43487) (43612 . 43615)
+    (43639 . 43641) (43742 . 43743) (43760 . 43761) 43867
+    44011 64297 (64434 . 64449) (65020 . 65021) (65040 . 65046)
+    65049 (65072 . 65076) (65093 . 65094) (65097 . 65103)
+    (65104 . 65106) (65108 . 65112) (65119 . 65126) (65128 . 65131)
+    (65281 . 65287) (65290 . 65295) (65306 . 65312) 65340
+    (65342 . 65344) 65372 65374 65377 (65380 . 65381)
+    (65504 . 65510) (65512 . 65518) (65532 . 65533) (65792 . 65794)
+    (65847 . 65855) (65913 . 65929) 65932 (65936 . 65947)
+    65952 (66000 . 66044) 66463 66512 66927 67671 (67703 . 67704)
+    67871 67903 (68176 . 68184) 68223 68296 (68336 . 68342)
+    (68409 . 68415) (68505 . 68508) (69703 . 69709) (69819 . 69820)
+    (69822 . 69825) (69952 . 69955) (70004 . 70005) (70085 . 70088)
+    70093 (70200 . 70205) 70854 (71105 . 71113) (71233 . 71235)
+    (74864 . 74868) (92782 . 92783) 92917 (92983 . 92991)
+    (92996 . 92997) 113820 113823 (118784 . 119029) (119040 . 119078)
+    (119081 . 119140) (119146 . 119148) (119171 . 119172)
+    (119180 . 119209) (119214 . 119261) (119296 . 119361)
+    119365 (119552 . 119638) 120513 120539 120571 120597
+    120629 120655 120687 120713 120745 120771 (126704 . 126705)
+    (126976 . 127019) (127024 . 127123) (127136 . 127150)
+    (127153 . 127167) (127169 . 127183) (127185 . 127221)
+    (127248 . 127278) (127280 . 127339) (127344 . 127386)
+    (127462 . 127487) (127488 . 127490) (127504 . 127546)
+    (127552 . 127560) (127568 . 127569) (127744 . 127788)
+    (127792 . 127869) (127872 . 127950) (127956 . 127991)
+    (128000 . 128254) (128256 . 128330) (128336 . 128377)
+    (128379 . 128419) (128421 . 128511) (128512 . 128578)
+    (128581 . 128591) (128592 . 128639) (128640 . 128719)
+    (128736 . 128748) (128752 . 128755) (128768 . 128883)
+    (128896 . 128980) (129024 . 129035) (129040 . 129095)
+    (129104 . 129113) (129120 . 129159) (129168 . 129197)))
+
+(defvar haskell--char-syntax-identifiers
+  '(170
+    (178 . 179) 181 (185 . 186) (188 . 190) (192 . 214) (216 . 246)
+    (248 . 255) (256 . 383) (384 . 591) (592 . 687) (880 . 883)
+    (886 . 887) (891 . 893) 895 902 (904 . 906) 908 (910 . 929) (931 . 1013)
+    (1015 . 1023) (1024 . 1153) (1162 . 1279) (1280 . 1327)
+    (1329 . 1366) (1377 . 1415) (1488 . 1514) (1520 . 1522) (1568 . 1599)
+    (1601 . 1610) (1632 . 1641) (1646 . 1647) (1649 . 1747) 1749
+    (1774 . 1788) 1791 1808 (1810 . 1839) (1869 . 1871) (1872 . 1919)
+    (1920 . 1957) 1969 (1984 . 2026) (2048 . 2069) (2112 . 2136) (2208 . 2226)
+    (2308 . 2361) 2365 2384 (2392 . 2401) (2406 . 2415) (2418 . 2431)
+    2432 (2437 . 2444) (2447 . 2448) (2451 . 2472) (2474 . 2480)
+    2482 (2486 . 2489) 2493 2510 (2524 . 2525) (2527 . 2529) (2534 . 2545)
+    (2548 . 2553) (2565 . 2570) (2575 . 2576) (2579 . 2600)
+    (2602 . 2608) (2610 . 2611) (2613 . 2614) (2616 . 2617) (2649 . 2652)
+    2654 (2662 . 2671) (2674 . 2676) (2693 . 2701) (2703 . 2705)
+    (2707 . 2728) (2730 . 2736) (2738 . 2739) (2741 . 2745) 2749 2768
+    (2784 . 2785) (2790 . 2799) (2821 . 2828) (2831 . 2832) (2835 . 2856)
+    (2858 . 2864) (2866 . 2867) (2869 . 2873) 2877 (2908 . 2909)
+    (2911 . 2913) (2918 . 2927) (2929 . 2935) 2947 (2949 . 2954) (2958 . 2960)
+    (2962 . 2965) (2969 . 2970) 2972 (2974 . 2975) (2979 . 2980)
+    (2984 . 2986) (2990 . 3001) 3024 (3046 . 3058) (3077 . 3084) (3086 . 3088)
+    (3090 . 3112) (3114 . 3129) 3133 (3160 . 3161) (3168 . 3169)
+    (3174 . 3183) (3192 . 3198) (3205 . 3212) (3214 . 3216) (3218 . 3240)
+    (3242 . 3251) (3253 . 3257) 3261 3294 (3296 . 3297) (3302 . 3311)
+    (3313 . 3314) (3333 . 3340) (3342 . 3344) (3346 . 3386) 3389
+    3406 (3424 . 3425) (3430 . 3445) (3450 . 3455) (3461 . 3478) (3482 . 3505)
+    (3507 . 3515) 3517 (3520 . 3526) (3558 . 3567) (3585 . 3632)
+    (3634 . 3635) (3648 . 3653) (3664 . 3673) (3713 . 3714) 3716 (3719 . 3720)
+    3722 3725 (3732 . 3735) (3737 . 3743) (3745 . 3747) 3749
+    3751 (3754 . 3755) (3757 . 3760) (3762 . 3763) 3773 (3776 . 3780)
+    (3792 . 3801) (3804 . 3807) 3840 (3872 . 3891) (3904 . 3911) (3913 . 3948)
+    (3976 . 3980) (4096 . 4138) (4159 . 4169) (4176 . 4181)
+    (4186 . 4189) 4193 (4197 . 4198) (4206 . 4208) (4213 . 4225) 4238
+    (4240 . 4249) (4256 . 4293) 4295 4301 (4304 . 4346) (4349 . 4351)
+    (4352 . 4607) (4608 . 4680) (4682 . 4685) (4688 . 4694) 4696 (4698 . 4701)
+    (4704 . 4744) (4746 . 4749) (4752 . 4784) (4786 . 4789)
+    (4792 . 4798) 4800 (4802 . 4805) (4808 . 4822) (4824 . 4880) (4882 . 4885)
+    (4888 . 4954) (4969 . 4988) (4992 . 5007) (5024 . 5108)
+    (5121 . 5740) (5743 . 5759) (5761 . 5786) (5792 . 5866) (5873 . 5880)
+    (5888 . 5900) (5902 . 5905) (5920 . 5937) (5952 . 5969)
+    (5984 . 5996) (5998 . 6000) (6016 . 6067) 6108 (6112 . 6121) (6128 . 6137)
+    (6160 . 6169) (6176 . 6210) (6212 . 6263) (6272 . 6312) 6314
+    (6320 . 6389) (6400 . 6430) (6470 . 6479) (6480 . 6509) (6512 . 6516)
+    (6528 . 6571) (6593 . 6599) (6608 . 6618) (6656 . 6678)
+    (6688 . 6740) (6784 . 6793) (6800 . 6809) (6917 . 6963) (6981 . 6987)
+    (6992 . 7001) (7043 . 7072) (7086 . 7103) (7104 . 7141)
+    (7168 . 7203) (7232 . 7241) (7245 . 7247) (7248 . 7287) (7401 . 7404)
+    (7406 . 7409) (7413 . 7414) (7424 . 7467) (7531 . 7543)
+    (7545 . 7551) (7552 . 7578) (7680 . 7935) (7936 . 7957) (7960 . 7965)
+    (7968 . 8005) (8008 . 8013) (8016 . 8023) 8025 8027 8029
+    (8031 . 8061) (8064 . 8116) (8118 . 8124) 8126 (8130 . 8132) (8134 . 8140)
+    (8144 . 8147) (8150 . 8155) (8160 . 8172) (8178 . 8180)
+    (8182 . 8188) 8304 (8308 . 8313) (8320 . 8329) 8450 8455 (8458 . 8467)
+    8469 (8473 . 8477) 8484 8486 8488 (8490 . 8493) (8495 . 8505)
+    (8508 . 8511) (8517 . 8521) 8526 (8528 . 8543) (8579 . 8580)
+    8585 (9312 . 9371) (9450 . 9471) (10102 . 10131) (11264 . 11310)
+    (11312 . 11358) (11360 . 11387) (11390 . 11391) (11392 . 11492)
+    (11499 . 11502) (11506 . 11507) 11517 (11520 . 11557) 11559 11565
+    (11568 . 11623) (11648 . 11670) (11680 . 11686) (11688 . 11694)
+    (11696 . 11702) (11704 . 11710) (11712 . 11718) (11720 . 11726)
+    (11728 . 11734) (11736 . 11742) 12294 12348 (12353 . 12438) 12447
+    (12449 . 12538) 12543 (12549 . 12589) (12593 . 12686) (12690 . 12693)
+    (12704 . 12730) (12784 . 12799) (12832 . 12841) (12872 . 12879)
+    (12881 . 12895) (12928 . 12937) (12977 . 12991) (13312 . 19893)
+    (19968 . 40908) (40960 . 40980) (40982 . 42124) (42192 . 42231)
+    (42240 . 42507) (42512 . 42539) (42560 . 42606) (42624 . 42651)
+    (42656 . 42725) (42786 . 42863) (42865 . 42887) (42891 . 42894)
+    (42896 . 42925) (42928 . 42929) 42999 (43002 . 43007)
+    (43008 . 43009) (43011 . 43013) (43015 . 43018) (43020 . 43042)
+    (43056 . 43061) (43072 . 43123) (43138 . 43187) (43216 . 43225)
+    (43250 . 43255) 43259 (43264 . 43301) (43312 . 43334) (43360 . 43388)
+    (43396 . 43442) (43472 . 43481) (43488 . 43492) (43495 . 43518)
+    (43520 . 43560) (43584 . 43586) (43588 . 43595) (43600 . 43609)
+    (43616 . 43631) (43633 . 43638) 43642 (43646 . 43647)
+    (43648 . 43695) 43697 (43701 . 43702) (43705 . 43709) 43712 43714
+    (43739 . 43740) (43744 . 43754) 43762 (43777 . 43782) (43785 . 43790)
+    (43793 . 43798) (43808 . 43814) (43816 . 43822) (43824 . 43866)
+    (43876 . 43877) (43968 . 44002) (44016 . 44025) (44032 . 55203)
+    (55216 . 55238) (55243 . 55291) (63744 . 64109) (64112 . 64217)
+    (64256 . 64262) (64275 . 64279) 64285 (64287 . 64296)
+    (64298 . 64310) (64312 . 64316) 64318 (64320 . 64321) (64323 . 64324)
+    (64326 . 64335) (64336 . 64433) (64467 . 64829) (64848 . 64911)
+    (64914 . 64967) (65008 . 65019) (65136 . 65140) (65142 . 65276)
+    (65296 . 65305) (65313 . 65338) (65345 . 65370) (65382 . 65391)
+    (65393 . 65437) (65440 . 65470) (65474 . 65479) (65482 . 65487)
+    (65490 . 65495) (65498 . 65500) (65536 . 65547) (65549 . 65574)
+    (65576 . 65594) (65596 . 65597) (65599 . 65613) (65616 . 65629)
+    (65664 . 65786) (65799 . 65843) (65909 . 65912) (65930 . 65931)
+    (66176 . 66204) (66208 . 66256) (66273 . 66299) (66304 . 66339)
+    (66352 . 66368) (66370 . 66377) (66384 . 66421) (66432 . 66461)
+    (66464 . 66499) (66504 . 66511) (66560 . 66639) (66640 . 66687)
+    (66688 . 66717) (66720 . 66729) (66816 . 66855) (66864 . 66915)
+    (67072 . 67382) (67392 . 67413) (67424 . 67431) (67584 . 67589)
+    67592 (67594 . 67637) (67639 . 67640) 67644 67647 (67648 . 67669)
+    (67672 . 67679) (67680 . 67702) (67705 . 67711) (67712 . 67742)
+    (67751 . 67759) (67840 . 67867) (67872 . 67897) (67968 . 67999)
+    (68000 . 68023) (68030 . 68031) 68096 (68112 . 68115)
+    (68117 . 68119) (68121 . 68147) (68160 . 68167) (68192 . 68222)
+    (68224 . 68255) (68288 . 68295) (68297 . 68324) (68331 . 68335)
+    (68352 . 68405) (68416 . 68437) (68440 . 68447) (68448 . 68466)
+    (68472 . 68479) (68480 . 68497) (68521 . 68527) (68608 . 68680)
+    (69216 . 69246) (69635 . 69687) (69714 . 69743) (69763 . 69807)
+    (69840 . 69864) (69872 . 69881) (69891 . 69926) (69942 . 69951)
+    (69968 . 70002) 70006 (70019 . 70066) (70081 . 70084) (70096 . 70106)
+    (70113 . 70132) (70144 . 70161) (70163 . 70187) (70320 . 70366)
+    (70384 . 70393) (70405 . 70412) (70415 . 70416) (70419 . 70440)
+    (70442 . 70448) (70450 . 70451) (70453 . 70457) 70461
+    (70493 . 70497) (70784 . 70831) (70852 . 70853) 70855 (70864 . 70873)
+    (71040 . 71086) (71168 . 71215) 71236 (71248 . 71257)
+    (71296 . 71338) (71360 . 71369) (71840 . 71922) 71935 (72384 . 72440)
+    (73728 . 74648) (77824 . 78894) (92160 . 92728) (92736 . 92766)
+    (92768 . 92777) (92880 . 92909) (92928 . 92975) (93008 . 93017)
+    (93019 . 93025) (93027 . 93047) (93053 . 93071) (93952 . 94020)
+    94032 (110592 . 110593) (113664 . 113770) (113776 . 113788)
+    (113792 . 113800) (113808 . 113817) (119648 . 119665) (119808 . 119892)
+    (119894 . 119964) (119966 . 119967) 119970 (119973 . 119974)
+    (119977 . 119980) (119982 . 119993) 119995 (119997 . 120003)
+    (120005 . 120069) (120071 . 120074) (120077 . 120084)
+    (120086 . 120092) (120094 . 120121) (120123 . 120126) (120128 . 120132)
+    120134 (120138 . 120144) (120146 . 120485) (120488 . 120512)
+    (120514 . 120538) (120540 . 120570) (120572 . 120596)
+    (120598 . 120628) (120630 . 120654) (120656 . 120686) (120688 . 120712)
+    (120714 . 120744) (120746 . 120770) (120772 . 120779)
+    (120782 . 120831) (124928 . 125124) (125127 . 125135) (126464 . 126467)
+    (126469 . 126495) (126497 . 126498) 126500 126503 (126505 . 126514)
+    (126516 . 126519) 126521 126523 126530 126535 126537
+    126539 (126541 . 126543) (126545 . 126546) 126548 126551 126553
+    126555 126557 126559 (126561 . 126562) 126564 (126567 . 126570)
+    (126572 . 126578) (126580 . 126583) (126585 . 126588) 126590 (126592 . 126601)
+    (126603 . 126619) (126625 . 126627) (126629 . 126633)
+    (126635 . 126651) (127232 . 127244) (131072 . 173782) (173824 . 177972)
+    (177984 . 178205) (194560 . 195101)))
+
+
+;; Syntax table.
+(defvar haskell-mode-syntax-table
+  (let ((table (make-syntax-table)))
+    (modify-syntax-entry ?\  " " table)
+    (modify-syntax-entry ?\t " " table)
+    (modify-syntax-entry ?\" "\"" table)
+    (modify-syntax-entry ?\' "_" table)
+    (modify-syntax-entry ?_  "_" table)
+    (modify-syntax-entry ?\( "()" table)
+    (modify-syntax-entry ?\) ")(" table)
+    (modify-syntax-entry ?\[  "(]" table)
+    (modify-syntax-entry ?\]  ")[" table)
+
+    (modify-syntax-entry ?\{  "(}1nb" table)
+    (modify-syntax-entry ?\}  "){4nb" table)
+    (modify-syntax-entry ?-  ". 123" table)
+    (modify-syntax-entry ?\n ">" table)
+
+    (modify-syntax-entry ?\` "$`" table)
+
+    (mapc (lambda (x)
+            (modify-syntax-entry x "." table))
+          "!#$%&*+./:<=>?@^|~,;\\")
+
+    ;; Haskell symbol characters are treated as punctuation because
+    ;; they are not able to form identifiers with word constituent 'w'
+    ;; class characters.
+    (dolist (charcodes haskell--char-syntax-symbols)
+      (modify-syntax-entry charcodes "." table))
+    ;; ... and for identifier characters
+    (dolist (charcodes haskell--char-syntax-identifiers)
+      (modify-syntax-entry charcodes "w" table))
+
+    table)
+  "Syntax table used in Haskell mode.")
+
+(defun haskell-syntax-propertize (begin end)
+  (save-excursion
+    (when haskell-literate
+      (goto-char begin)
+      ;; Algorithm (first matching rule wins):
+      ;; - current line is latex code if previous non-empty line was
+      ;;   latex code or was \begin{code} and current line is not
+      ;;   \end{code}
+      ;; - current line is bird code if it starts with >
+      ;; - else literate comment
+      (let ((previous-line-latex-code
+             (catch 'return
+               (save-excursion
+                 (when (= (forward-line -1) 0)
+                   (while (looking-at-p "^[\t ]*$")
+                     (unless (= (forward-line -1) 0)
+                       (throw 'return nil)))
+                   (or
+                    (and
+                     (not (equal (string-to-syntax "<") (syntax-after (point))))
+                     (not (looking-at-p "^>")))
+                    (looking-at-p "^\\\\begin{code}[\t ]*$")))))))
+        (while (< (point) end)
+          (unless (looking-at-p "^[\t ]*$")
+            (if previous-line-latex-code
+                (if (looking-at-p "^\\\\end{code}[\t ]*$")
+                    (progn
+                      (put-text-property (point) (1+ (point)) 'syntax-table (string-to-syntax "<"))
+                      (setq previous-line-latex-code nil))
+                  ;; continue latex-code
+                  )
+              (if (looking-at-p "^>")
+                  ;; this is a whitespace
+                  (put-text-property (point) (1+ (point)) 'syntax-table (string-to-syntax "-"))
+                ;; this is a literate comment
+                (progn
+                  (put-text-property (point) (1+ (point)) 'syntax-table (string-to-syntax "<"))
+                  (when (looking-at-p "^\\\\begin{code}[\t ]*$")
+                    (setq previous-line-latex-code t))))))
+          (forward-line 1))))
+
+    (goto-char begin)
+    (let ((ppss (syntax-ppss)))
+      (when (nth 4 ppss)
+        ;; go to the end of a comment, there is nothing to see inside
+        ;; a comment so we might as well just skip over it
+        ;; immediatelly
+        (setq ppss (parse-partial-sexp (point) (point-max) nil nil ppss
+                                       'syntax-table)))
+      (when (nth 8 ppss)
+        ;; go to the beginning of a comment or string
+        (goto-char (nth 8 ppss))
+        (when (equal ?| (nth 3 ppss))
+          ;; if this is a quasi quote we need to backtrack even more
+          ;; to the opening bracket
+          (skip-chars-backward "^[")
+          (goto-char (1- (point)))))
+
+      (while (< (point) end)
+        (let
+            ((token-kind (haskell-lexeme-looking-at-token)))
+
+          (cond
+           ((equal token-kind 'qsymid)
+            (when (member
+                   (haskell-lexeme-classify-by-first-char (char-after (match-beginning 1)))
+                   '(varsym consym))
+              ;; we have to neutralize potential comments here
+              (put-text-property (match-beginning 1) (match-end 1) 'syntax-table (string-to-syntax "."))))
+           ((equal token-kind 'number)
+            (put-text-property (match-beginning 0) (match-end 0) 'syntax-table (string-to-syntax "w")))
+           ((equal token-kind 'char)
+            (save-excursion
+              (goto-char (match-beginning 2))
+              (let ((limit (match-end 2)))
+                (save-match-data
+                  (while (re-search-forward "\"" limit t)
+                    (put-text-property (match-beginning 0) (match-end 0) 'syntax-table (string-to-syntax ".")))))
+              ;; Place a generic string delimeter only when an open
+              ;; quote is closed by end-of-line Emacs acts strangely
+              ;; when a generic delimiter is not closed so in case
+              ;; string ends at the end of the buffer we will use
+              ;; plain string
+              (if (and (not (match-beginning 3))
+                       (not (equal (match-end 2) (point-max))))
+                  (progn
+                    (put-text-property (match-beginning 1) (match-end 1) 'syntax-table (string-to-syntax "|"))
+                    (put-text-property (match-end 2 ) (1+ (match-end 2)) 'syntax-table (string-to-syntax "|")))
+                (put-text-property (match-beginning 1) (match-end 1) 'syntax-table (string-to-syntax "\""))
+                (when (not (equal (match-end 2) (point-max)))
+                  (put-text-property (match-end 2 ) (1+ (match-end 2)) 'syntax-table (string-to-syntax "\""))))))
+           ((equal token-kind 'string)
+            (save-excursion
+              (goto-char (match-beginning 2))
+              (let ((limit (match-end 2)))
+                (save-match-data
+                  (while (re-search-forward "\"" limit t)
+                    (put-text-property (match-beginning 0) (match-end 0) 'syntax-table (string-to-syntax ".")))))
+              ;; Place a generic string delimeter only when an open
+              ;; quote is closed by end-of-line Emacs acts strangely
+              ;; when a generic delimiter is not closed so in case
+              ;; string ends at the end of the buffer we will use
+              ;; plain string
+              (when (and (not (match-beginning 3))
+                         (not (equal (match-end 2) (point-max))))
+                (put-text-property (match-beginning 1) (match-end 1) 'syntax-table (string-to-syntax "|"))
+                (put-text-property (match-end 2 ) (1+ (match-end 2)) 'syntax-table (string-to-syntax "|")))))
+           ((equal token-kind 'template-haskell-quasi-quote)
+            (put-text-property (match-beginning 2) (match-end 2) 'syntax-table (string-to-syntax "\""))
+            (when (match-beginning 4)
+              (put-text-property (match-beginning 4) (match-end 4) 'syntax-table (string-to-syntax "\"")))
+            (save-excursion
+              (goto-char (match-beginning 3))
+              (let ((limit (match-end 3)))
+                (save-match-data
+                  (while (re-search-forward "\"" limit t)
+                    (put-text-property (match-beginning 0) (match-end 0) 'syntax-table (string-to-syntax "."))))))))
+          (if token-kind
+              (goto-char (match-end 0))
+            (goto-char end)))))))
+
+(defun haskell-ident-at-point ()
+  "Return the identifier near point going backward or nil if none found.
+May return a qualified name."
+  (let ((reg (haskell-ident-pos-at-point)))
+    (when reg
+      (buffer-substring-no-properties (car reg) (cdr reg)))))
+
+(defun haskell-spanable-pos-at-point ()
+  "Like `haskell-ident-pos-at-point', but includes any surrounding backticks."
+  (save-excursion
+    (let ((pos (haskell-ident-pos-at-point)))
+      (when pos
+        (cl-destructuring-bind (start . end) pos
+          (if (and (eq ?` (char-before start))
+                   (eq ?` (char-after end)))
+              (cons (- start 1) (+ end 1))
+            (cons start end)))))))
+
+(defun haskell-ident-pos-at-point ()
+  "Return the span of the identifier near point going backward.
+Returns nil if no identifier found or point is inside string or
+comment.  May return a qualified name."
+  (when (not (nth 8 (syntax-ppss)))
+    ;; Do not handle comments and strings
+    (let (start end)
+      ;; Initial point position is non-deterministic, it may occur anywhere
+      ;; inside identifier span, so the approach is:
+      ;; - first try go left and find left boundary
+      ;; - then try go right and find right boundary
+      ;;
+      ;; In both cases assume the longest path, e.g. when going left take into
+      ;; account than point may occur at the end of identifier, when going right
+      ;; take into account that point may occur at the beginning of identifier.
+      ;;
+      ;; We should handle `.` character very careful because it is heavily
+      ;; overloaded.  Examples of possible cases:
+      ;; Control.Monad.>>=  -- delimiter
+      ;; Control.Monad.when -- delimiter
+      ;; Data.Aeson..:      -- delimiter and operator symbol
+      ;; concat.map         -- composition function
+      ;; .?                 -- operator symbol
+      (save-excursion
+        ;; First, skip whitespace if we're on it, moving point to last
+        ;; identifier char.  That way, if we're at "map ", we'll see the word
+        ;; "map".
+        (when (and (eolp)
+                   (not (bolp)))
+          (backward-char))
+        (when (and (not (eobp))
+                   (eq (char-syntax (char-after)) ? ))
+          (skip-chars-backward " \t")
+          (backward-char))
+        ;; Now let's try to go left.
+        (save-excursion
+          (if (not (haskell-mode--looking-at-varsym))
+              ;; Looking at non-operator char, this is quite simple
+              (progn
+                (skip-syntax-backward "w_")
+                ;; Remember position
+                (setq start (point)))
+            ;; Looking at operator char.
+            (while (and (not (bobp))
+                        (haskell-mode--looking-at-varsym))
+              ;; skip all operator chars backward
+              (setq start (point))
+              (backward-char))
+            ;; Extra check for case when reached beginning of the buffer.
+            (when (haskell-mode--looking-at-varsym)
+              (setq start (point))))
+          ;; Slurp qualification part if present.  If identifier is qualified in
+          ;; case of non-operator point will stop before `.` dot, but in case of
+          ;; operator it will stand at `.` delimiting dot.  So if we're looking
+          ;; at `.` let's step one char forward and try to get qualification
+          ;; part.
+          (goto-char start)
+          (when (looking-at-p (rx "."))
+            (forward-char))
+          (let ((pos (haskell-mode--skip-qualification-backward)))
+            (when pos
+              (setq start pos))))
+        ;; Finally, let's try to go right.
+        (save-excursion
+          ;; Try to slurp qualification part first.
+          (skip-syntax-forward "w_")
+          (setq end (point))
+          (while (and (looking-at (rx "." upper))
+                      (not (zerop (progn (forward-char)
+                                         (skip-syntax-forward "w_")))))
+            (setq end (point)))
+          ;; If point was at non-operator we already done, otherwise we need an
+          ;; extra check.
+          (while (haskell-mode--looking-at-varsym)
+            (forward-char)
+            (setq end (point))))
+        (when (not (= start end))
+          (cons start end))))))
+
+(defun haskell-mode--looking-at-varsym ()
+  "Return t when point stands at operator symbol."
+  (when (not (eobp))
+    (let ((lex (haskell-lexeme-classify-by-first-char (char-after))))
+      (or (eq lex 'varsym)
+          (eq lex 'consym)))))
+
+(defun haskell-mode--skip-qualification-backward ()
+  "Skip qualified part of identifier backward.
+Expects point stands *after* delimiting dot.
+Returns beginning position of qualified part or nil if no qualified part found."
+  (when (not (and (bobp)
+                  (looking-at (rx bol))))
+    (let ((case-fold-search nil)
+          pos)
+      (while (and (eq (char-before) ?.)
+                  (progn (backward-char)
+                         (not (zerop (skip-syntax-backward "w'"))))
+                  (skip-syntax-forward "'")
+                  (looking-at "[[:upper:]]"))
+        (setq pos (point)))
+      pos)))
+
+(defun haskell-delete-indentation (&optional arg)
+  "Like `delete-indentation' but ignoring Bird-style \">\"."
+  (interactive "*P")
+  (let ((fill-prefix (or fill-prefix (if (eq haskell-literate 'bird) ">"))))
+    (delete-indentation arg)))
+
+(defvar eldoc-print-current-symbol-info-function)
+
+;; The main mode functions
+;;;###autoload
+(define-derived-mode haskell-mode prog-mode "Haskell"
+  "Major mode for editing Haskell programs.
+
+\\<haskell-mode-map>
+
+Literate Haskell scripts are supported via `literate-haskell-mode'.
+The variable `haskell-literate' indicates the style of the script in the
+current buffer.  See the documentation on this variable for more details.
+
+Use `haskell-version' to find out what version of Haskell mode you are
+currently using.
+
+Additional Haskell mode modules can be hooked in via `haskell-mode-hook'.
+
+Indentation modes:
+
+    `haskell-indentation-mode', Kristof Bastiaensen, Gergely Risko
+      Intelligent semi-automatic indentation Mk2
+
+    `haskell-indent-mode', Guy Lapalme
+      Intelligent semi-automatic indentation.
+
+Interaction modes:
+
+    `interactive-haskell-mode'
+      Interact with per-project GHCi processes through a REPL and
+      directory-aware sessions.
+
+Other modes:
+
+    `haskell-decl-scan-mode', Graeme E Moss
+      Scans top-level declarations, and places them in a menu.
+
+    `haskell-doc-mode', Hans-Wolfgang Loidl
+      Echoes types of functions or syntax of keywords when the cursor is idle.
+
+To activate a minor-mode, simply run the interactive command. For
+example, `M-x haskell-doc-mode'. Run it again to disable it.
+
+To enable a mode for every haskell-mode buffer, add a hook in
+your Emacs configuration. To do that you can customize
+`haskell-mode-hook' or add lines to your .emacs file. For
+example, to enable `interactive-haskell-mode', use the following:
+
+    (add-hook 'haskell-mode-hook 'interactive-haskell-mode)
+
+Minor modes that work well with `haskell-mode':
+
+- `smerge-mode': show and work with diff3 conflict markers used
+  by git, svn and other version control systems."
+  :group 'haskell
+  (when (version< emacs-version "24.3")
+    (error "haskell-mode requires at least Emacs 24.3"))
+
+  ;; paragraph-{start,separate} should treat comments as paragraphs as well.
+  (setq-local paragraph-start (concat " *{-\\| *-- |\\|" page-delimiter))
+  (setq-local paragraph-separate (concat " *$\\| *\\({-\\|-}\\) *$\\|" page-delimiter))
+  (setq-local fill-paragraph-function 'haskell-fill-paragraph)
+  ;; (setq-local adaptive-fill-function 'haskell-adaptive-fill)
+  (setq-local comment-start "-- ")
+  (setq-local comment-padding 0)
+  (setq-local comment-start-skip "[-{]-[ \t]*")
+  (setq-local comment-end "")
+  (setq-local comment-end-skip "[ \t]*\\(-}\\|\\s>\\)")
+  (setq-local forward-sexp-function #'haskell-forward-sexp)
+  (setq-local parse-sexp-ignore-comments nil)
+  (setq-local syntax-propertize-function #'haskell-syntax-propertize)
+
+  ;; Set things up for eldoc-mode.
+  (setq-local eldoc-documentation-function 'haskell-doc-current-info)
+  ;; Set things up for imenu.
+  (setq-local imenu-create-index-function 'haskell-ds-create-imenu-index)
+  ;; Set things up for font-lock.
+  (setq-local font-lock-defaults
+              '((haskell-font-lock-keywords)
+                nil nil nil nil
+                (font-lock-syntactic-face-function
+                 . haskell-syntactic-face-function)
+                ;; Get help from font-lock-syntactic-keywords.
+                (parse-sexp-lookup-properties . t)
+                (font-lock-extra-managed-props . (composition haskell-type))))
+  ;; Preprocessor definitions can have backslash continuations
+  (setq-local font-lock-multiline t)
+  ;; Haskell's layout rules mean that TABs have to be handled with extra care.
+  ;; The safer option is to avoid TABs.  The second best is to make sure
+  ;; TABs stops are 8 chars apart, as mandated by the Haskell Report.  --Stef
+  (setq-local indent-tabs-mode nil)
+  (setq-local tab-width 8)
+  (setq-local comment-auto-fill-only-comments t)
+  ;; Haskell is not generally suitable for electric indentation, since
+  ;; there is no unambiguously correct indent level for any given line.
+  (when (boundp 'electric-indent-inhibit)
+    (setq electric-indent-inhibit t))
+
+  ;; dynamic abbrev support: recognize Haskell identifiers
+  ;; Haskell is case-sensitive language
+  (setq-local dabbrev-case-fold-search nil)
+  (setq-local dabbrev-case-distinction nil)
+  (setq-local dabbrev-case-replace nil)
+  (setq-local dabbrev-abbrev-char-regexp "\\sw\\|[.]")
+  (setq haskell-literate nil)
+  (add-hook 'before-save-hook 'haskell-mode-before-save-handler nil t)
+  (add-hook 'after-save-hook 'haskell-mode-after-save-handler nil t)
+  ;; provide non-interactive completion function
+  (add-hook 'completion-at-point-functions
+            'haskell-completions-completion-at-point
+            nil
+            t)
+  (haskell-indentation-mode))
+
+(defcustom haskell-mode-hook '(haskell-indentation-mode interactive-haskell-mode)
+  "List of functions to run after `haskell-mode' is enabled.
+
+Use to enable minor modes coming with `haskell-mode' or run an
+arbitrary function.
+
+Note that  `haskell-indentation-mode' and `haskell-indent-mode' should not be
+run at the same time."
+  :group 'haskell
+  :type 'hook
+  :options '(capitalized-words-mode
+             flyspell-prog-mode
+             haskell-decl-scan-mode
+             haskell-indent-mode
+             haskell-indentation-mode
+             highlight-uses-mode
+             imenu-add-menubar-index
+             interactive-haskell-mode
+             turn-on-haskell-unicode-input-method))
+
+(defun haskell-fill-paragraph (justify)
+  (save-excursion
+    ;; Fill paragraph should only work in comments.
+    ;; The -- comments are handled properly by default
+    ;; The {- -} comments need some extra love.
+    (let* ((syntax-values (syntax-ppss))
+           (comment-num (nth 4 syntax-values)))
+      (cond
+       ((eq t comment-num)
+        ;; standard fill works wonders inside a non-nested comment
+        (fill-comment-paragraph justify))
+
+       ((integerp comment-num)
+        ;; we are in a nested comment. lets narrow to comment content
+        ;; and use plain paragraph fill for that
+        (let* ((comment-start-point (nth 8 syntax-values))
+               (comment-end-point
+                (save-excursion
+                  (goto-char comment-start-point)
+                  (forward-sexp)
+                  ;; Find end of any comment even if forward-sexp
+                  ;; fails to find the right braces.
+                  (backward-char 3)
+                  (re-search-forward "[ \t]?-}" nil t)
+                  (match-beginning 0)))
+               (fill-start (+ 2 comment-start-point))
+               (fill-end comment-end-point)
+               (fill-paragraph-handle-comment nil))
+          (save-restriction
+            (narrow-to-region fill-start fill-end)
+            (fill-paragraph justify)
+            ;; If no filling happens, whatever called us should not
+            ;; continue with standard text filling, so return t
+            t)))
+       ((eolp)
+        ;; do nothing outside of a comment
+        t)
+       (t
+        ;; go to end of line and try again
+        (end-of-line)
+        (haskell-fill-paragraph justify))))))
+
+
+;; (defun haskell-adaptive-fill ()
+;;   ;; We want to use "--  " as the prefix of "-- |", etc.
+;;   (let* ((line-end (save-excursion (end-of-line) (point)))
+;;          (line-start (point)))
+;;     (save-excursion
+;;       (unless (in-comment)
+;;         ;; Try to find the start of a comment. We only fill comments.
+;;         (search-forward-regexp comment-start-skip line-end t))
+;;       (when (in-comment)
+;;         (let ();(prefix-start (point)))
+;;           (skip-syntax-forward "^w")
+;;           (make-string (- (point) line-start) ?\s))))))
+
+;;;###autoload
+(defun haskell-forward-sexp (&optional arg)
+  "Haskell specific version of `forward-sexp'.
+
+Move forward across one balanced expression (sexp).  With ARG, do
+it that many times.  Negative arg -N means move backward across N
+balanced expressions.  This command assumes point is not in a
+string or comment.
+
+If unable to move over a sexp, signal `scan-error' with three
+arguments: a message, the start of the obstacle (a parenthesis or
+list marker of some kind), and end of the obstacle."
+  (interactive "^p")
+  (or arg (setq arg 1))
+  (if (< arg 0)
+      (while (< arg 0)
+        (skip-syntax-backward "->")
+        ;; Navigate backwards using plain `backward-sexp', assume that it
+        ;; skipped over at least one Haskell expression, and jump forward until
+        ;; last possible point before the starting position. If applicable,
+        ;; `scan-error' is signalled by `backward-sexp'.
+        (let ((end (point))
+              (forward-sexp-function nil))
+          (backward-sexp)
+          (let ((cur (point)))
+            (while (< (point) end)
+              (setf cur (point))
+              (haskell-forward-sexp)
+              (skip-syntax-forward "->"))
+            (goto-char cur)))
+        (setf arg (1+ arg)))
+    (save-match-data
+      (while (> arg 0)
+        (when (haskell-lexeme-looking-at-token)
+          (cond ((member (match-string 0) (list "(" "[" "{"))
+                 (goto-char (or (scan-sexps (point) 1) (buffer-end 1))))
+                ((member (match-string 0) (list ")" "]" "}"))
+                 (signal 'scan-error (list "Containing expression ends prematurely."
+                                           (match-beginning 0)
+                                           (match-end 0))))
+                (t (goto-char (match-end 0)))))
+        (setf arg (1- arg))))))
+
+
+
+;;;###autoload
+(define-derived-mode literate-haskell-mode haskell-mode "LitHaskell"
+  "As `haskell-mode' but for literate scripts."
+  (setq haskell-literate
+        (save-excursion
+          (goto-char (point-min))
+          (cond
+           ((re-search-forward "^\\\\\\(begin\\|end\\){code}$" nil t) 'tex)
+           ((re-search-forward "^>" nil t) 'bird)
+           (t haskell-literate-default))))
+  (if (eq haskell-literate 'bird)
+      ;; fill-comment-paragraph isn't much use there, and even gets confused
+      ;; by the syntax-table text-properties we add to mark the first char
+      ;; of each line as a comment-starter.
+      (setq-local fill-paragraph-handle-comment nil))
+  (setq-local mode-line-process '("/" (:eval (symbol-name haskell-literate)))))
+
+;;;###autoload
+(add-to-list 'auto-mode-alist        '("\\.[gh]s\\'" . haskell-mode))
+;;;###autoload
+(add-to-list 'auto-mode-alist        '("\\.hsig\\'" . haskell-mode))
+;;;###autoload
+(add-to-list 'auto-mode-alist        '("\\.l[gh]s\\'" . literate-haskell-mode))
+;;;###autoload
+(add-to-list 'auto-mode-alist        '("\\.hsc\\'" . haskell-mode))
+;;;###autoload
+(add-to-list 'interpreter-mode-alist '("runghc" . haskell-mode))
+;;;###autoload
+(add-to-list 'interpreter-mode-alist '("runhaskell" . haskell-mode))
+;;;###autoload
+(add-to-list 'completion-ignored-extensions ".hi")
+
+
+(defcustom haskell-check-command "hlint"
+  "*Command used to check a Haskell file."
+  :group 'haskell
+  :type '(choice (const "hlint")
+                 (const "ghc -fno-code")
+                 (string :tag "Other command")))
+
+(defcustom haskell-tags-on-save nil
+  "Generate tags via hasktags after saving."
+  :group 'haskell
+  :type 'boolean)
+
+(defvar haskell-saved-check-command nil
+  "Internal use.")
+
+;; Like Python.  Should be abstracted, sigh.
+(defun haskell-check (command)
+  "Check a Haskell file (default current buffer's file).
+Runs COMMAND, a shell command, as if by `compile'.
+See `haskell-check-command' for the default."
+  (interactive
+   (list (read-string "Checker command: "
+                      (or haskell-saved-check-command
+                          (concat haskell-check-command " "
+                                  (let ((name (buffer-file-name)))
+                                    (if name
+                                        (file-name-nondirectory name))))))))
+  (setq haskell-saved-check-command command)
+  (save-some-buffers (not compilation-ask-about-save) nil)
+  (compilation-start command))
+
+(defun haskell-flymake-init ()
+  "Flymake init function for Haskell.
+To be added to `flymake-init-create-temp-buffer-copy'."
+  (let ((checker-elts (and haskell-saved-check-command
+                           (split-string haskell-saved-check-command))))
+    (list (car checker-elts)
+          (append (cdr checker-elts)
+                  (list (flymake-init-create-temp-buffer-copy
+                         'flymake-create-temp-inplace))))))
+
+(add-to-list 'flymake-allowed-file-name-masks '("\\.l?hs\\'" haskell-flymake-init))
+
+(defun haskell-mode-format-imports ()
+  "Format the imports by aligning and sorting them."
+  (interactive)
+  (let ((col (current-column)))
+    (haskell-sort-imports)
+    (haskell-align-imports)
+    (goto-char (+ (line-beginning-position)
+                  col))))
+
+(declare-function haskell-mode-stylish-buffer "haskell-commands")
+
+(defun haskell-mode-before-save-handler ()
+  "Function that will be called before buffer's saving."
+  (when haskell-stylish-on-save
+    (ignore-errors (haskell-mode-stylish-buffer))))
+
+;; From Bryan O'Sullivan's blog:
+;; http://www.serpentine.com/blog/2007/10/09/using-emacs-to-insert-scc-annotations-in-haskell-code/
+(defun haskell-mode-try-insert-scc-at-point ()
+  "Try to insert an SCC annotation at point.  Return true if
+successful, nil otherwise."
+  (if (or (looking-at "\\b\\|[ \t]\\|$")
+          ;; Allow SCC if point is on a non-letter with whitespace to the left
+          (and (not (bolp))
+               (save-excursion
+                 (forward-char -1)
+                 (looking-at "[ \t]"))))
+      (let ((space-at-point (looking-at "[ \t]")))
+        (unless (and (not (bolp)) (save-excursion
+                                    (forward-char -1)
+                                    (looking-at "[ \t]")))
+          (insert " "))
+        (insert "{-# SCC \"\" #-}")
+        (unless space-at-point
+          (insert " "))
+        (forward-char (if space-at-point -5 -6))
+        t )))
+
+(defun haskell-mode-insert-scc-at-point ()
+  "Insert an SCC annotation at point."
+  (interactive)
+  (if (not (haskell-mode-try-insert-scc-at-point))
+      (error "Not over an area of whitespace")))
+
+(make-obsolete
+ 'haskell-mode-insert-scc-at-point
+ 'haskell-mode-toggle-scc-at-point
+ "2015-11-11")
+
+(defun haskell-mode-try-kill-scc-at-point ()
+  "Try to kill an SCC annotation at point.  Return true if
+successful, nil otherwise."
+  (save-excursion
+    (let ((old-point (point))
+          (scc "\\({-#[ \t]*SCC \"[^\"]*\"[ \t]*#-}\\)[ \t]*"))
+      (while (not (or (looking-at scc) (bolp)))
+        (forward-char -1))
+      (if (and (looking-at scc)
+               (<= (match-beginning 1) old-point)
+               (> (match-end 1) old-point))
+          (progn (kill-region (match-beginning 0) (match-end 0))
+                 t)))))
+
+;; Also Bryan O'Sullivan's.
+(defun haskell-mode-kill-scc-at-point ()
+  "Kill the SCC annotation at point."
+  (interactive)
+  (if (not (haskell-mode-try-kill-scc-at-point))
+      (error "No SCC at point")))
+
+(make-obsolete
+ 'haskell-mode-kill-scc-at-point
+ 'haskell-mode-toggle-scc-at-point
+ "2015-11-11")
+
+(defun haskell-mode-toggle-scc-at-point ()
+  "If point is in an SCC annotation, kill the annotation.  Otherwise, try to insert a new annotation."
+  (interactive)
+  (if (not (haskell-mode-try-kill-scc-at-point))
+      (if (not (haskell-mode-try-insert-scc-at-point))
+          (error "Could not insert or remove SCC"))))
+
+(defun haskell-guess-module-name-from-file-name (file-name)
+  "Guess the module name from FILE-NAME.
+
+Based on given FILE-NAME this function tries to find path
+components that look like module identifiers and composes full
+module path using this information. For example:
+
+    /Abc/Def/Xyz.lhs => Abc.Def.Xyz
+    /Ab-c/Def/Xyz.lhs => Def.Xyz
+    src/Abc/Def/Xyz.hs => Abc.Def.Xyz
+    c:\\src\\Abc\\Def\\Xyz.hs => Abc.Def.Xyz
+    nonmodule.txt => nil
+
+This function usually will be used with `buffer-file-name':
+
+    (haskell-guess-module-name-from-file-name (buffer-file-name))"
+
+  (let* ((file-name-sans-ext (file-name-sans-extension file-name))
+         (components (cl-loop for part
+                             in (reverse (split-string file-name-sans-ext "/"))
+                             while (let ((case-fold-search nil))
+                                     (string-match (concat "^" haskell-lexeme-modid "$") part))
+                             collect part)))
+    (when components
+      (mapconcat 'identity (reverse components) "."))))
+
+(defun haskell-guess-module-name ()
+  "Guess the current module name of the buffer.
+Uses `haskell-guess-module-name-from-file-name'."
+  (haskell-guess-module-name-from-file-name (buffer-file-name)))
+
+(defvar haskell-auto-insert-module-format-string
+  "-- | \n\nmodule %s where\n\n"
+  "Template string that will be inserted in new haskell buffers via `haskell-auto-insert-module-template'.")
+
+(defun haskell-auto-insert-module-template ()
+  "Insert a module template for the newly created buffer."
+  (interactive)
+  (when (and (= (point-min)
+                (point-max))
+             (buffer-file-name))
+    (insert (format haskell-auto-insert-module-format-string (haskell-guess-module-name-from-file-name (buffer-file-name))))
+    (goto-char (point-min))
+    (end-of-line)))
+
+;;;###autoload
+(defun haskell-mode-generate-tags (&optional and-then-find-this-tag)
+  "Generate tags using Hasktags.  This is synchronous function.
+
+If optional AND-THEN-FIND-THIS-TAG argument is present it is used
+with function `xref-find-definitions' after new table was
+generated."
+  (interactive)
+  (let* ((dir (haskell-cabal--find-tags-dir))
+         (command (haskell-cabal--compose-hasktags-command dir)))
+    (if (not command)
+        (error "Unable to compose hasktags command")
+      (shell-command command)
+      (haskell-mode-message-line "Tags generated.")
+      (when and-then-find-this-tag
+        (let ((tags-file-name dir))
+          (xref-find-definitions and-then-find-this-tag))))))
+
+;; Provide ourselves:
+(provide 'haskell-mode)
+;;; haskell-mode.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-mode.elc b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-mode.elc
new file mode 100644
index 0000000000..b72cd8ee64
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-mode.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-mode.info b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-mode.info
new file mode 100644
index 0000000000..69dcfd97ab
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-mode.info
@@ -0,0 +1,2425 @@
+This is haskell-mode.info, produced by makeinfo version 6.1 from
+haskell-mode.texi.
+
+This manual is for Haskell mode, version 16.1-git
+
+   Copyright © 2013-2017 Haskell Mode contributors.
+
+     Permission is granted to copy, distribute and/or modify this
+     document under the terms of the GNU Free Documentation License
+     (http://www.gnu.org/licenses/fdl.html), Version 1.3 or any later
+     version published by the Free Software Foundation; with no
+     Invariant Sections, no Front-Cover Texts and no Back-Cover Texts.
+INFO-DIR-SECTION Emacs
+START-INFO-DIR-ENTRY
+* Haskell Mode: (haskell-mode).             Haskell Development Environment for Emacs(en)
+END-INFO-DIR-ENTRY
+
+
+File: haskell-mode.info,  Node: Top,  Next: Introduction,  Up: (dir)
+
+Haskell Mode
+************
+
+Haskell Mode is an Haskell development Environment for GNU Emacs version
+24.3 or later.  It provides syntax-based indentation, font locking,
+editing cabal files, and supports running an inferior Haskell
+interpreter (e.g.  GHCi).
+
+* Menu:
+
+* Introduction::                         An introduction to Haskell Mode
+* Installation::                         How to get started
+* Editing Haskell Code::                 How to edit code
+* Syntax highlighting::                  Haskell Mode has colors
+* Completion support::                   Autocomplete
+* Unicode support::                      How to use Unicode
+* Indentation::                          Notes about indentation
+* External indentation::                 Other ways to indent code
+* Autoformating::                        Using external formatters
+* Module templates::                     Module templates
+* Declaration scanning::                 How to navigate in a source file
+* Compilation::                          How to compile
+* Interactive Haskell::                  How to interact with GHCi
+* Editing Cabal files::                  Cabal support
+* Browsing Haddocks::                    Using ‘w3m’ to browse documentation
+* Spell checking strings and comments::  Using ‘flyspell-prog-mode’
+* Aligning code::                        Aligning code using ‘align-regexp’
+* Rectangular commands::                 Manage indentation manually
+* REPL::                                 GHCi REPL
+* Collapsing Haskell code::              View more code on screen
+* Getting Help and Reporting Bugs::      How to improve Haskell Mode
+* Concept index::                        Index of Haskell Mode concepts
+* Function index::                       Index of commands
+* Variable index::                       Index of options and types
+
+
+File: haskell-mode.info,  Node: Introduction,  Next: Installation,  Prev: Top,  Up: Top
+
+1 Introduction
+**************
+
+“Haskell Mode” is a major mode providing a convenient environment for
+editing Haskell (http://www.haskell.org) programs.
+
+   Some of its major features are:
+
+   • Syntax highlighting (font lock),
+   • automatic semi-intelligent indentation,
+   • on-the-fly documentation,
+   • interaction with inferior GHCi/Hugs instance,
+   • project building with cabal and stack
+   • scanning declarations and placing them in a menu.
+
+   The name Haskell Mode refers to the whole collection of modules in
+this package.  There is specifically a file ‘haskell-mode.el’ which
+defines a major mode called ‘haskell-mode’.  Generally, in this
+documentation they will be distinguished by normal font and title case
+(Haskell Mode) and code font (‘haskell-mode’).
+
+1.1 History
+===========
+
+‘haskell-mode’ has a long history.  It goes all the way back to 1992.
+Since then, it has received many contributions in many forms.  Some
+design choices that remain in haskell-mode today are historical.  Some
+modules are outdated or no longer used, or are used by a few people.
+
+   Historically there hasn’t been a single individual or set of
+individuals directing the package’s architecture for a long period of
+time, rather, patches and new modules were accepted in liberally and we
+are left with a box full of interesting toys that may or may not work.
+
+   As of 2016 Haskell Mode is coordinated using Github at
+<https://github.com/haskell/haskell-mode>.
+
+
+File: haskell-mode.info,  Node: Installation,  Next: Editing Haskell Code,  Prev: Introduction,  Up: Top
+
+2 Installation
+**************
+
+Haskell Mode is distributed as a package in MELPA repository
+(https://melpa.org).  To use MELPA as Emacs package archive do the
+following:
+
+  1. Customize ‘package-archives’ using
+          M-x customize-option RET package-archives
+  2. Use ‘INS’ to add new archive, use:
+          Archive name:          melpa-stable
+          URL or directory name: http://stable.melpa.org/packages/
+  3. Fetch new packages using:
+          M-x package-refresh-contents
+  4. Install Haskell Mode using:
+          M-x package-install RET haskell-mode RET
+
+   Voila!  ‘haskell-mode’ is installed!  You should be able to edit
+Haskell source code in color now.
+
+   The above steps should result in the following snippet in your
+‘.emacs’:
+
+     (require 'package)
+     (custom-set-variables
+      ;; custom-set-variables was added by Custom.
+      ;; If you edit it by hand, you could mess it up, so be careful.
+      ;; Your init file should contain only one such instance.
+      ;; If there is more than one, they won't work right.
+      '(package-archives
+        (quote
+         (("gnu" . "http://elpa.gnu.org/packages/")
+          ("melpa-stable" . "http://stable.melpa.org/packages/")))))
+
+   Haskell Mode supports GNU Emacs versions 24.3+, including 25
+(snapshot).
+
+   Haskell Mode is available from melpa-stable (releases)
+(http://stable.melpa.org) and melpa (git snapshots) (http://melpa.org).
+
+   Other means of obtaining ‘haskell-mode’ include el-get
+(https://github.com/dimitri/el-get), Emacs Prelude
+(https://github.com/bbatsov/prelude) and Debian package
+(https://packages.debian.org/search?keywords=haskell-mode).
+
+   Last version of ‘haskell-mode’ that supported Emacs 23, 24.1, and
+24.2 is ‘haskell-mode’ 13.16 available at
+<https://github.com/haskell/haskell-mode/releases/tag/v13.16>.
+
+2.1 Customizing
+===============
+
+Most of Haskell Mode’s settings are configurable via customizable
+variables (*note (emacs)Easy Customization::, for details).  You can use
+‘M-x customize-group <RET> haskell’ to browse the ‘haskell’
+customization sub-tree.
+
+   One of the important setting you should customize is the
+‘haskell-mode-hook’ variable (*note (emacs)Hooks::) which gets run right
+after the ‘haskell-mode’ major mode is initialized for a buffer.  You
+can customize ‘haskell-mode-hook’ by
+
+     M-x customize-variable RET haskell-mode-hook
+
+   There you can enable or disable a couple of predefined options or add
+any function to the list.
+
+
+File: haskell-mode.info,  Node: Editing Haskell Code,  Next: Syntax highlighting,  Prev: Installation,  Up: Top
+
+3 Editing Haskell Code
+**********************
+
+Haskell Mode as one of its components provides a major mode for editing
+Haskell source code called ‘haskell-mode’, which gave the name to the
+whole project.  There is a derived mode provided called
+‘literate-haskell-mode’ that support Literate Haskell source code both
+in Bird and in Latex forms.
+
+   Haskell Mode supports files with the following extensions:
+
+‘.hs’
+     official file extension for Haskell files.  Haskell Mode out of the
+     box supports most of GHC extensions.
+‘.lhs’
+     official file extension for Literate Haskell files.  Both Bird and
+     Latex styles are supported.
+‘.hsc’
+     Haskell interfaces to C code used by hsc2hs
+     (http://www.haskell.org/ghc/docs/latest/html/users_guide/hsc2hs.html)
+     pre-processor.
+‘.cpphs’
+     Haskell source with CPP pragmas used with cpphs
+     (http://projects.haskell.org/cpphs) pre-processor.
+‘.c2hs’
+     Haskell FFI bindings to C libraries used with c2hs
+     (https://github.com/haskell/c2hs) pre-processor.
+
+   Haskell Mode offers many productivity tools described in following
+chapters in this manual.
+
+3.1 Managing imports
+====================
+
+There are a few functions for managing imports.
+
+3.1.1 Jump to imports
+---------------------
+
+To jump to your import list, run
+
+   ‘M-x’ ‘haskell-navigate-imports’
+
+   It’s nicer to have a keybinding to do this, for example:
+
+     (define-key haskell-mode-map (kbd "<f8>") 'haskell-navigate-imports)
+
+   You can hit it repeatedly to jump between groups of imports.  It will
+cycle.
+
+3.1.2 Format imports
+--------------------
+
+To generally format (sort, align) your imports, you can run
+
+   ‘M-x’ ‘haskell-mode-format-imports’
+
+   Or ‘C-c C-,’.
+
+3.1.3 Sort imports
+------------------
+
+To just sort imports, jump to an import section and run
+
+   ‘M-x’ ‘haskell-sort-imports’
+
+3.1.4 Align imports
+-------------------
+
+To just align imports, jump to an import section and run
+
+   ‘M-x’ ‘haskell-align-imports’
+
+3.1.5 stylish-haskell
+---------------------
+
+As an alternative to the elisp functions described above, haskell-mode
+can use the program stylish-haskell
+(http://hackage.haskell.org/package/stylish-haskell) to format imports.
+You can set this behavior by typing: ‘M-x’ ‘customize-variable’ ‘RET’
+‘haskell-stylish-on-save’.  You can install ‘stylish-haskell’ by running
+‘stack install stylish-haskell’, or if you have not installed ‘stack’,
+‘cabal install stylish-haskell’.
+
+3.2 Haskell Tags
+================
+
+‘haskell-mode’ can generate tags when saving source files.  To generate
+tags ‘haskell-mode’ uses external program — Hasktags
+(https://github.com/MarcWeber/hasktags) (wiki-article
+(https://wiki.haskell.org/Tags)).  To turn on tags generatation
+customize or set to ‘t’ ‘haskell-tags-on-save’ variable.  Also, you may
+find useful to revert tags tables automatically, this can be done by
+customizing ‘tags-revert-without-query’ variable (either globally or for
+Haskell buffers only).
+
+3.3 Profiling and Debugging support
+===================================
+
+When profiling code with GHC, it is often useful to add cost centres
+(https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/profiling.html#cost-centres)
+by hand.  These allow finer-grained information about program behavior.
+‘haskell-mode’ provides the function ‘haskell-mode-toggle-scc-at-point’
+to make this more convenient.  It will remove an SCC annotation at point
+if one is present, or add one if point is over whitespace.  By default
+it is bound to ‘C-c C-s’.
+
+
+File: haskell-mode.info,  Node: Syntax highlighting,  Next: Completion support,  Prev: Editing Haskell Code,  Up: Top
+
+4 Syntax highlighting
+*********************
+
+‘haskell-mode’ supports “syntax highlighting” via Emacs’ Font Lock minor
+mode which should be enabled by default in current Emacsen.  *Note
+(emacs)Font Lock::, for more information on how to control
+‘font-lock-mode’.
+
+   Syntax highlighting facilities parse strings and string escape
+sequences and are able to highlight unrecognized constructs.
+
+   Haskell Mode shows keywords, identifiers, operators, constructors and
+types in different colors.
+
+   There is also support to use mode-specific syntax highlighing for
+quasiquotes.
+
+   At this point quasi quotes for HTML, XML, shell scripts, Hamlet
+templates and SQL are supported out of the box.  Customize
+‘haskell-font-lock-quasi-quote-modes’ to make sure your quoters are
+supported.
+
+   The following customization variables are responsible for faces
+applied:
+
+   ‘’ ‘haskell-keyword-face’: for keywords
+   ‘’ ‘haskell-type-face’: for type names and type class names
+   ‘’ ‘haskell-constructor-face’: for constructors
+   ‘’ ‘haskell-definition-face’: function and operator name at the
+     definition place
+   ‘’ ‘haskell-operator-face’: operators
+   ‘’ ‘haskell-pragma-face’: GHC pragmas
+   ‘’ ‘haskell-literate-comment-face’: literate comments
+   ‘’ ‘haskell-quasi-quote-face’: quasi quotes unless using mode
+     specific highlighting
+   ‘’ ‘haskell-c2hs-hook-pair-face’: c2hs hooks
+   ‘’ ‘haskell-c2hs-hook-name-face’: c2hs hook names
+
+   All the above are available for customization.
+
+   GHC quasi quote syntax is ambiguous with list comprehension therefore
+syntax highlighting might get confused with situations like these:
+
+     result = [html| html <- htmlList]
+     result = [html| <html><body>...</body></html> |]
+
+   Please use spaces around a list comprehension variable to make this
+unambiguous.  Any of the following will work:
+
+     result = [ html| html <- htmlList]
+     result = [html | html <- htmlList]
+
+   GHC’s ambiguity is an accident of the past but it is unlikely to be
+fixed due to backward compatibility baggage.
+
+
+File: haskell-mode.info,  Node: Completion support,  Next: Unicode support,  Prev: Syntax highlighting,  Up: Top
+
+5 Completion support
+********************
+
+‘haskell-mode’ can complete symbols, pragma directives, language
+extensions, and language keywords out-of-box.  ‘haskell-mode’ completes
+identifiers (symbols) using tags (see “Tags”), however you can get more
+precise completions with ‘haskell-interactive-mode’.  In interactive
+mode completion candidates are produced by querying GHCi REPL.
+
+   If ‘haskell-interactive-mode’ is enabled and working Haskell mode
+provides completions for import statements taking into account currently
+loaded and available packages.  Also it completes symbols querying REPL
+with ‘:complete’ command, hence completion candidate list also includes
+symbols from imported modules.
+
+   Unfortunatelly, it is not possible to provide candidates for
+identifiers defined locally in ‘let’ and ‘where’ blocks even in
+interactive mode.  But if you’re using company-mode
+(http://company-mode.github.io/) you can override ‘company-backends’
+variable for Haskell buffers to combine completion candidates from
+completion-at-point function (‘company-capf’ backend) and dynamic
+abbrevs.  ‘company-mode’ provides special backend for dabbrev code
+completions, namely ‘company-dabbrev-code’.  To combine completions from
+diffrent backends you can create grouped backends, it is very easy — a
+grouped backend is just a list of backends, for example:
+
+     (add-hook 'haskell-mode-hook
+               (lambda ()
+                 (set (make-local-variable 'company-backends)
+                      (append '((company-capf company-dabbrev-code))
+                              company-backends))))
+
+   If you use a GHCi version prior to 8.0.1 you might want to set
+‘haskell-completions-complete-operators’ to ‘nil’, if you experience
+major slowdown while trying to complete after an Haskell operator (See
+GHC-Bug 10576 (https://ghc.haskell.org/trac/ghc/ticket/10576)).
+
+
+File: haskell-mode.info,  Node: Unicode support,  Next: Indentation,  Prev: Completion support,  Up: Top
+
+6 Unicode support
+*****************
+
+See the Haskell Wiki’s entry on Unicode Symbols
+(http://www.haskell.org/haskellwiki/Unicode-symbols) for general
+information about Unicode support in Haskell.
+
+   As Emacs supports editing files containing Unicode out of the box, so
+does Haskell Mode.  As an add-on, Haskell Mode includes the
+‘haskell-unicode’ input method which allows you to easily type a number
+of Unicode symbols that are useful when writing Haskell code; *Note
+(emacs)Input Methods::, for more details.
+
+   To automatically enable the ‘haskell-unicode’ input method in
+haskell-mode buffers use ‘M-x customize-variable <RET>
+haskell-mode-hook’ or put the following code in your ‘.emacs’ file:
+
+     (add-hook 'haskell-mode-hook 'turn-on-haskell-unicode-input-method)
+
+To temporarily enable this input method for a single buffer you can use
+‘M-x turn-on-haskell-unicode-input-method’.
+
+   When the ‘haskell-unicode’ input method is active, you can simply
+type ‘->’ and it is immediately replaced with ‘→’.  Use ‘C-\’ to toggle
+the input method.  To see a table of all key sequences use ‘M-x
+describe-input-method <RET> haskell-unicode’.  A sequence like ‘<=’ is
+ambiguous and can mean either ‘⇐’ or ‘≤’.  Typing it presents you with a
+choice.  Type ‘1’ or ‘2’ to select an option or keep typing to use the
+default option.
+
+   Currently defined sequences are listed in the following table:
+
+SequenceUnicode    SequenceUnicode    SequenceUnicode    SequenceUnicode
+----------------------------------------------------------------------------
+alpha  α           Alpha  Α           beta   β           Beta   Β
+gamma  γ           Gamma  Γ           delta  δ           Delta  Δ
+epsilonε           EpsilonΕ           zeta   ζ           Zeta   Ζ
+eta    η           Eta    Η           theta  θ           Theta  Θ
+iota   ι           Iota   Ι           kappa  κ           Kappa  Κ
+lambda λ           Lambda Λ           lamda  λ           Lamda  Λ
+mu     μ           Mu     Μ           nu     ν           Nu     Ν
+xi     ξ           Xi     Ξ           omicronο           OmicronΟ
+pi     π           Pi     Π           rho    ρ           Rho    Ρ
+sigma  σ           Sigma  Σ           tau    τ           Tau    Τ
+upsilonυ           UpsilonΥ           phi    φ           Phi    Φ
+chi    χ           Chi    Χ           psi    ψ           Psi    Ψ
+omega  ω           Omega  Ω           digammaϝ           DigammaϜ
+san    ϻ           San    Ϻ           qoppa  ϙ           Qoppa  Ϙ
+sampi  ϡ           Sampi  Ϡ           stigma ϛ           Stigma Ϛ
+heta   ͱ           Heta   Ͱ           sho    ϸ           Sho    Ϸ
+|A|    𝔸           |B|    𝔹           |C|    ℂ           |D|    𝔻
+|E|    𝔼           |F|    𝔽           |G|    𝔾           |H|    ℍ
+|I|    𝕀           |J|    𝕁           |K|    𝕂           |L|    𝕃
+|M|    𝕄           |N|    ℕ           |O|    𝕆           |P|    ℙ
+|Q|    ℚ           |R|    ℝ           |S|    𝕊           |T|    𝕋
+|U|    𝕌           |V|    𝕍           |W|    𝕎           |X|    𝕏
+|Y|    𝕐           |Z|    ℤ           |gamma|ℽ           |Gamma|ℾ
+|pi|   ℼ           |Pi|   ℿ           ::     ∷           forall ∀
+exists ∃           ->     →           <-     ←           =>     ⇒
+~>     ⇝           <~     ⇜           &&     ∧           ||     ∨
+==     ≡           /=     ≢, ≠        <=     ≤           >=     ≥
+/<     ≮           />     ≯           *      ⋅           elem   ∈
+notElem∉           member ∈           notMember∉         union  ∪
+intersection∩      isSubsetOf⊆        isProperSubsetOf⊂  <<<    ⋘
+>>>    ⋙           <|     ⊲           |>     ⊳           ><     ⋈
+mappend⊕           .      ∘           undefined⊥         :=     ≔
+=:     ≕           =def   ≝           =?     ≟           ...    …
+_0     ₀           _1     ₁           _2     ₂           _3     ₃
+_4     ₄           _5     ₅           _6     ₆           _7     ₇
+_8     ₈           _9     ₉           ^0     ⁰           ^1     ¹
+^2     ²           ^3     ³           ^4     ⁴           ^5     ⁵
+^6     ⁶           ^7     ⁷           ^8     ⁸           ^9     ⁹
+
+   If you don’t like the highlighting of partially matching tokens you
+can turn it off by setting ‘input-method-highlight-flag’ to ‘nil’ via
+‘M-x customize-variable’.
+
+
+File: haskell-mode.info,  Node: Indentation,  Next: External indentation,  Prev: Unicode support,  Up: Top
+
+7 Indentation
+*************
+
+In Haskell, code indentation has semantic meaning as it defines the
+block structure.  Haskell also supports braces and semicolons notation
+for conveying the block structure.  However, most Haskell programs
+written by humans use indentation for block structuring.
+
+   Haskell Mode ships with two indentation modes:
+
+   • ‘haskell-indentation-mode’ (default).
+
+     This is a semi-intelligent indentation mode doing a decent job at
+     recognizing Haskell syntactical constructs.  It is based on a
+     recursive descent Haskell parser.  ‘TAB’ selects the next potential
+     indentation position, ‘S-TAB’ selects the previous one.  If a block
+     is selected you can use ‘TAB’ to indent the block more and ‘S-TAB’
+     to indent the block less.
+
+     When ‘electric-indent-mode’ is enabled or the variable
+     ‘haskell-indentation-electric-flag’ is non-nil, the insertion of
+     some characters (by default ‘,’ ‘;’ ‘)’ ‘}’ ‘]’) may trigger auto
+     reindentation under appropriate conditions.  See the documentation
+     of ‘haskell-indentation-common-electric-command’ for more details.
+
+   • ‘haskell-indent-mode’ (optional).
+
+     This is a semi-intelligent indentation mode doing a decent job at
+     recognizing Haskell syntactical constructs.  It is based on a
+     decision table.  Sadly it is no longer developed and does not
+     recognize newer Haskell syntax.  ‘TAB’ cycles through all available
+     indentation positions.
+
+     To use ‘haskell-indent-mode’, add this to your ‘~/.emacs’ file:
+
+          (add-hook 'haskell-mode-hook 'turn-on-haskell-indent)
+
+     Note that ‘turn-on-haskell-indent’ will disable
+     ‘haskell-indentation-mode’.
+
+   For general information about indentation support in GNU Emacs, *note
+(emacs)Indentation::.
+
+7.1 Rectangle Commands
+======================
+
+GNU Emacs provides so-called “rectangle commands” which operate on
+rectangular areas of text, which are particularly useful for languages
+with a layout rule such as Haskell.  *Note (emacs)Rectangles::, to learn
+more about rectangle commands.
+
+   Moreover, CUA mode (*note (emacs)CUA Bindings::) provides enhanced
+rectangle support with visible rectangle highlighting.  When CUA mode is
+active, you can initiate a rectangle selection by ‘C-RET’ and extend it
+simply by movement commands.  You don’t have to enable full CUA mode to
+benefit from these enhanced rectangle commands; you can activate CUA
+selection mode (without redefining ‘C-x’,‘C-c’,‘C-v’, and ‘C-z’) by
+calling ‘M-x cua-selection-mode’ (or adding ‘(cua-selection-mode nil)’
+to your ‘haskell-mode-hook’).
+
+7.2 Region indent is a no-op
+============================
+
+There is a ‘indent-region’ function that supposedly could be used to
+indent code region without changing its semantics.  Sadly it does not
+work that way because usual use case for ‘indent-region’ is:
+
+  1. Alter first line of code in region.
+  2. Call ‘indent-region’ to fix indentation for remaining lines.
+
+   Note that between 1 and 2 program is already semantically broken and
+knowing how to indent it preserving semantic from before step 1 would
+require time travel.
+
+   To stay on the safe side ‘indent-region-function’ is bound to a no-op
+in ‘haskell-mode’.
+
+
+File: haskell-mode.info,  Node: External indentation,  Next: Autoformating,  Prev: Indentation,  Up: Top
+
+8 Other ways to indent code
+***************************
+
+8.1 Indentation with tabs, not spaces
+=====================================
+
+Some projects require indenting code with tabs and forbid indenting it
+with spaces.  For hacking on such projects, check out
+haskell-tab-indent-mode
+(https://spwhitton.name/tech/code/haskell-tab-indent).
+
+8.2 Structured indentation
+==========================
+
+Another alternative is to install structured-haskell-mode
+(https://github.com/chrisdone/structured-haskell-mode).  which indents
+code by parsing the code with a full Haskell parser and deciding where
+to indent based on that.
+
+
+File: haskell-mode.info,  Node: Autoformating,  Next: Module templates,  Prev: External indentation,  Up: Top
+
+9 Using external formatters
+***************************
+
+You can enable stylish-haskell
+(https://github.com/jaspervdj/stylish-haskell) by installing it:
+
+     $ cabal install stylish-haskell
+
+   And by enabling it with a customization
+
+     (custom-set-variables
+      '(haskell-stylish-on-save t))
+
+   Now when you run ‘save-buffer’ (or ‘C-x C-s’) the module will be
+automatically formatted.
+
+   Alternatively, you can run the function directly on demand with ‘M-x’
+‘haskell-mode-stylish-buffer’.
+
+
+File: haskell-mode.info,  Node: Module templates,  Next: Declaration scanning,  Prev: Autoformating,  Up: Top
+
+10 Module templates
+*******************
+
+To enable auto-insertion of module templates, enable:
+
+     (add-hook 'haskell-mode-hook 'haskell-auto-insert-module-template)
+
+   When you open a file called ‘Foo.hs’, it will auto-insert
+
+     -- |
+
+     module Foo where
+
+   And put your cursor in the comment section.
+
+
+File: haskell-mode.info,  Node: Declaration scanning,  Next: Compilation,  Prev: Module templates,  Up: Top
+
+11 Declaration scannning
+************************
+
+‘haskell-decl-scan-mode’ is a minor mode which performs declaration
+scanning and provides ‘M-x imenu’ support (*note (emacs)Imenu:: for more
+information).
+
+   For non-literate and TeX-style literate scripts, the common
+convention that top-level declarations start at the first column is
+assumed.  For Bird-style literate scripts, the common convention that
+top-level declarations start at the third column, ie.  after ‘> ’, is
+assumed.
+
+   When ‘haskell-decl-scan-mode’ is active, the standard Emacs top-level
+definition movement commands (*note (emacs)Moving by Defuns::) are
+enabled to operate on Haskell declarations:
+
+‘C-M-a’
+     Move to beginning of current or preceding declaration
+     (‘beginning-of-defun’).
+
+‘C-M-e’
+     Move to end of current or following declaration (‘end-of-defun’).
+
+‘C-M-h’
+     Select whole current or following declaration (‘mark-defun’).
+
+   Moreover, if enabled via the option
+‘haskell-decl-scan-add-to-menubar’, a menu item “Declarations” is added
+to the menu bar listing the scanned declarations and allowing to jump to
+declarations in the source buffer.
+
+   It’s recommended to have font lock mode enabled (*note (emacs)Font
+Lock::) as ‘haskell-decl-scan-mode’ ignores text highlighted with
+‘font-lock-comment-face’.
+
+   As usual, in order to activate ‘haskell-decl-scan-mode’ automatically
+for Haskell buffers, add ‘haskell-decl-scan-mode’ to
+‘haskell-mode-hook’:
+
+     (add-hook 'haskell-mode-hook 'haskell-decl-scan-mode)
+
+   ‘haskell-decl-scan-mode’ enables the use of features that build upon
+‘imenu’ support such as Speedbar Frames (*note (emacs)Speedbar::) or the
+global “Which Function” minor mode (*note (emacs)Which Function::).
+
+   In order to enable ‘which-function-mode’ for Haskell buffers you need
+to add the following to your Emacs initialization:
+
+     (eval-after-load "which-func"
+       '(add-to-list 'which-func-modes 'haskell-mode))
+
+11.1 Speedbar
+=============
+
+Haskell-mode comes with declaration scanning support.  This means that
+if you enable Haskell support for speedbar:
+
+     (speedbar-add-supported-extension ".hs")
+
+   And open speedbar with
+
+   ‘M-x speedbar’
+
+   It gives a listing of each module and under each module:
+
+         Imports
+         Instances
+         Data types
+         Classes
+         Bindings
+
+   You will get a bar that looks like this:
+
+~/Projects/ace/src/ACE/
+0:<+> Types
+0:[+] Combinators.hs
+0:[-] Datalog.hs
+1:   {-} Classes
+2:      > ToTerm
+1:   {-} Imports
+2:      > ACE.Types.Syntax
+2:      > Database.Datalog
+1:   {-} Instances
+2:    {+} ToTerm A
+2:    {+} ToTerm Co to ToTerm Gen
+2:    {+} ToTerm Intransitive to ToTerm N
+2:    {+} ToTerm P
+2:    {+} ToTerm Quotation to ToTerm Un
+2:    {+} ToTerm V
+0:[-] Html.hs
+1:   {+} Imports
+1:   {+} Instances
+1:     > mtoMarkup
+1:     > toMarkupm
+1:     > wrap
+0:[-] Parsers.hs
+1:   {+} Imports
+1:   {-} Datatypes
+2:      > ACEParser
+0:[+] Pretty.hs
+0:[+] Tokenizer.hs
+
+   The hierarchy is expandable/collapsible and each entry will jump to
+the line in the right file when clicked/selected.
+
+
+File: haskell-mode.info,  Node: Compilation,  Next: Interactive Haskell,  Prev: Declaration scanning,  Up: Top
+
+12 Compilation
+**************
+
+Haskell mode comes equipped with a specialized “Compilation mode”
+tailored to GHC’s compiler messages with optional support for Cabal
+projects.  *Note (emacs)Compilation Mode::, for more information about
+the basic commands provided by the Compilation mode which are available
+in the Haskell compilation sub-mode as well.  The additional features
+provided compared to Emacs’ basic Compilation mode are:
+
+   • DWIM-style auto-detection of compile command (including support for
+     CABAL projects)
+   • Support for GHC’s compile messages and recognizing error, warning
+     and info source locations (including ‘-ferror-spans’ syntax)
+   • Support for filtering out GHC’s uninteresting ‘Loading package...’
+     linker messages
+
+   In order to use it, invoke the ‘haskell-compile’ command instead of
+‘compile’ as you would for the ordinary Compilation mode.  It’s
+recommended to bind ‘haskell-compile’ to a convenient key binding.  For
+instance, you can add the following to your Emacs initialization to bind
+‘haskell-compile’ to ‘C-c C-c’.
+
+     (eval-after-load "haskell-mode"
+         '(define-key haskell-mode-map (kbd "C-c C-c") 'haskell-compile))
+
+     (eval-after-load "haskell-cabal"
+         '(define-key haskell-cabal-mode-map (kbd "C-c C-c") 'haskell-compile))
+
+The following description assumes that ‘haskell-compile’ has been bound
+to ‘C-c C-c’.
+
+   When invoked, ‘haskell-compile’ tries to guess how to compile the
+Haskell program your currently visited buffer belongs to, by searching
+for a ‘.cabal’ file in the current of enclosing parent folders.  If a
+‘.cabal’ file was found, the command defined in the
+‘haskell-compile-cabal-build-command’ option is used.  Note that to
+compile a ‘stack’ based project you will need to set this variable to
+‘stack build’.  As usual you can do it using ‘M-x customize-variable’ or
+with:
+
+     (setq haskell-compile-cabal-build-command "stack build")
+
+   Moreover, when requesting to compile a ‘.cabal’-file is detected and
+a negative prefix argument (e.g.  ‘C-- C-c C-c’) was given, the
+alternative ‘haskell-compile-cabal-build-command-alt’ is invoked.  By
+default, ‘haskell-compile-cabal-build-command-alt’ contains a ‘cabal
+clean -s’ command in order to force a full rebuild.
+
+   Otherwise if no ‘.cabal’ could be found, a single-module compilation
+is assumed and ‘haskell-compile-command’ is used (_if_ the currently
+visited buffer contains Haskell source code).
+
+   You can also inspect and modify the compile command to be invoked
+temporarily by invoking ‘haskell-compile’ with a prefix argument (e.g.
+‘C-u C-c C-c’).  If later-on you want to recompile using the same
+customized compile command, invoke ‘recompile’ (bound to ‘g’) inside the
+‘*haskell-compilation*’ buffer.
+
+12.1 Keybindings
+================
+
+Key   Function
+binding
+------------
+TAB   compilation-next-error
+      
+RET   compile-goto-error
+      
+C-o   compilation-display-error
+      
+SPC   scroll-up-command
+      
+-     negative-argument
+      
+0     digit-argument
+..    
+9
+<     beginning-of-buffer
+      
+>     end-of-buffer
+      
+?     describe-mode
+      
+g     recompile
+      
+h     describe-mode
+      
+q     quit-window
+      
+DEL   scroll-down-command
+      
+S-SPC scroll-down-command
+      
+<backtab>compilation-previous-error
+      
+<follow-link>mouse-face
+      
+<mouse-2>compile-goto-error
+      
+<remap>Prefix
+      Command
+      
+M-n   compilation-next-error
+      
+M-p   compilation-previous-error
+      
+M-{   compilation-previous-file
+      
+M-}   compilation-next-file
+      
+C-c   compile-goto-error
+C-c   
+C-c   next-error-follow-minor-mode
+C-f   
+C-c   kill-compilation
+C-k   
+
+
+File: haskell-mode.info,  Node: Interactive Haskell,  Next: Editing Cabal files,  Prev: Compilation,  Up: Top
+
+13 Interactive Haskell
+**********************
+
+REPL (read–eval–print loop) is provided both via Comint
+(‘inferior-haskell-mode’) and an adhoc way called
+‘haskell-interactive-mode’.  The Comint based ‘inferior-haskell-mode’ is
+just the REPL, it comes with the standard key bindings(like ‘ielm’ or
+‘eshell’).
+
+   ‘haskell-interactive-mode’ comes with a different set of features:
+
+   • Separate sessions per Cabal project ‘haskell-session.el’.
+   • A new inferior Haskell process handling code ‘haskell-process.el’.
+   • New REPL implementation similiar to SLIME/IELM
+   • Navigatable error overlays ‘haskell-interactive-mode.el’.
+
+   With ‘haskell-interactive-mode’, each Haskell source buffer is
+associated with at most one GHCi session, so when you call
+‘haskell-process-load-file’ for a Haskell source buffer which has no
+session associated yet, you’re asked which GHCi session to create or
+associate with.
+
+13.1 Goto Error
+===============
+
+In a Haskell source buffer associated with a GHCi session, errors that
+prevent the file from loading are highlighted with ‘haskell-error-face’.
+You can move between these error lines with
+
+‘M-n’
+     is bound to ‘haskell-goto-next-error’
+‘M-p’
+     is bound to ‘haskell-goto-prev-error’
+‘C-c M-p’
+     is bound to ‘haskell-goto-first-error’
+
+13.2 Using GHCi 8+ or GHCi-ng
+=============================
+
+If you use either of the above, then you can use these functions:
+
+     (define-key interactive-haskell-mode-map (kbd "M-.") 'haskell-mode-goto-loc)
+     (define-key interactive-haskell-mode-map (kbd "C-c C-t") 'haskell-mode-show-type-at)
+
+   You have to load the module before it works, after that it will
+remember for the current GHCi session.
+
+13.3 Customizing
+================
+
+What kind of Haskell REPL ‘haskell-interactive-mode’ will start up
+depends on the value of ‘haskell-process-type’.  This can be one of the
+symbols ‘auto’, ‘ghci’, ‘cabal-repl’, ‘cabal-new-repl’, or ‘stack-ghci’.
+If it’s ‘auto’, the directory contents and available programs will be
+used to make a best guess at the process type.  The actual process type
+will then determine which variables ‘haskell-interactive-mode’ will
+access to determine the program to start and its arguments:
+
+   • If it’s ‘ghci’, ‘haskell-process-path-ghci’ and
+     ‘haskell-process-args-ghci’ will be used.
+   • If it’s ‘cabal-repl’, ‘haskell-process-path-cabal’ and
+     ‘haskell-process-args-cabal-repl’.
+   • If it’s ‘cabal-new-repl’, ‘haskell-process-path-cabal’ and
+     ‘haskell-process-args-cabal-new-repl’.
+   • If it’s ‘stack-ghci’, ‘haskell-process-path-stack’ and
+     ‘haskell-process-args-stack-ghci’ will be used.
+
+   With each of these pairs, the the ‘haskell-process-path-...’ variable
+needs to be a string specifying the program path, or a list of strings
+where the first element is the program path and the rest are initial
+arguments.  The ‘haskell-process-args-...’ is a list of strings
+specifying (further) command-line arguments.
+
+13.4 Haskell Interactive Mode Setup
+===================================
+
+The most straight-forward way to get setup with Interactive Mode is to
+bind the right keybindings and set some customizations.  This page
+contains a good base setup.
+
+   To enable the minor mode which activates keybindings associated with
+interactive mode, use:
+
+     (require 'haskell-interactive-mode)
+     (require 'haskell-process)
+     (add-hook 'haskell-mode-hook 'interactive-haskell-mode)
+
+13.4.1 Customizations
+---------------------
+
+This enables some handy and benign features.
+
+     (custom-set-variables
+       '(haskell-process-suggest-remove-import-lines t)
+       '(haskell-process-auto-import-loaded-modules t)
+       '(haskell-process-log t))
+
+13.4.2 Haskell-mode bindings
+----------------------------
+
+This gives the basic ways to start a session.  In a Haskell buffer:
+
+   • Run ‘C-`’ to make a REPL open, this will create a session, start
+     GHCi, and open the REPL.
+   • Or: run ‘C-c C-l’ to load the file.  This will first try to start a
+     session as the previous command does.
+   • Or: run any command which requires a running session.  It will
+     always prompt to create one if there isn’t one already for the
+     current project.
+
+     (define-key haskell-mode-map (kbd "C-c C-l") 'haskell-process-load-or-reload)
+     (define-key haskell-mode-map (kbd "C-`") 'haskell-interactive-bring)
+     (define-key haskell-mode-map (kbd "C-c C-t") 'haskell-process-do-type)
+     (define-key haskell-mode-map (kbd "C-c C-i") 'haskell-process-do-info)
+     (define-key haskell-mode-map (kbd "C-c C-c") 'haskell-process-cabal-build)
+     (define-key haskell-mode-map (kbd "C-c C-k") 'haskell-interactive-mode-clear)
+     (define-key haskell-mode-map (kbd "C-c c") 'haskell-process-cabal)
+
+13.4.3 Cabal-mode bindings
+--------------------------
+
+The below commands pretty much match the ones above, but are handy to
+have in cabal-mode, too:
+
+     (define-key haskell-cabal-mode-map (kbd "C-`") 'haskell-interactive-bring)
+     (define-key haskell-cabal-mode-map (kbd "C-c C-k") 'haskell-interactive-mode-clear)
+     (define-key haskell-cabal-mode-map (kbd "C-c C-c") 'haskell-process-cabal-build)
+     (define-key haskell-cabal-mode-map (kbd "C-c c") 'haskell-process-cabal)
+
+13.4.4 GHCi process type
+------------------------
+
+By default ‘haskell-process-type’ is set to ‘auto’.  It is smart enough
+to pick the right type based on your project structure and installed
+tools, but in case something goes funky or you want to explicitly set
+the process type and ignore the inferred type, you can customize this
+setting by running ‘M-x’ ‘customize-variable’ ‘RET’
+‘haskell-process-type’ ‘RET’, or by setting the code:
+
+     (custom-set-variables
+       '(haskell-process-type 'cabal-repl))
+
+   Here is a list of available process types:
+
+   • ghci
+   • cabal-repl
+   • cabal-new-repl
+   • cabal-dev
+   • cabal-ghci
+   • stack-ghci
+
+   Please, check the documentation for ‘haskell-process-type’ to see how
+the real type is guessed, when it’s set to ‘auto’.
+
+13.4.5 Troubleshooting
+----------------------
+
+Launching your GHCi process can fail when you’re first getting setup,
+depending on the type you choose.  If it does fail to launch, switch to
+the buffer ‘*haskell-process-log*’ and see what’s up.  The buffer
+contains a log of incoming/outgoing messages to the GHCi process.
+
+13.5 Haskell Interactive Mode Tags Using GHCi
+=============================================
+
+You can bind the following to use GHCi to find definitions of things:
+
+     (define-key haskell-mode-map (kbd "M-.") 'haskell-mode-jump-to-def)
+
+   The one problem with this approach is that if your code doesn’t
+compile, GHCi doesn’t give any location info.  So you need to make sure
+your code compiles and the modules you want to jump to are loaded
+byte-compiled.
+
+   Note: I think that when you restart GHCi you lose location
+information, even if you have the ‘.o’ and ‘.hi’ files lying around.
+I’m not sure.  But sometimes ‘:i foo’ will give ‘foo is defined in Bar’
+rather than ‘foo is defined in /foo/Bar.hs:123:23’.
+
+   Alternatively, you can use tags generation, which doesn’t require a
+valid compile.
+
+13.5.1 Tags Setup
+-----------------
+
+Make sure to install ‘hasktags’.
+
+         $ cabal install hasktags
+
+   Then add the customization variable to enable tags generation on
+save:
+
+     (custom-set-variables
+       '(haskell-tags-on-save t))
+
+   And make sure ‘hasktags’ is in your ‘$PATH’ which Emacs can see.
+
+13.5.2 Generating tags
+----------------------
+
+Now, every time you run ‘save-buffer’ (‘C-x C-s’), there is a hook that
+will run and generate Emacs *Note (emacs)Tags:: for the whole project
+directory.  The resulting file will be called ‘TAGS’.
+
+   WARNING: You should be careful that your project root isn’t your home
+directory or something, otherwise it will traverse all the way down and
+take an impossibly long time.
+
+13.5.3 Jumping to tags
+----------------------
+
+Bind the following keybinding:
+
+     (define-key haskell-mode-map (kbd "M-.") 'haskell-mode-tag-find)
+
+   To jump to the location of the top-level identifier at point, run
+‘M-x’ ‘haskell-mode-tag-find’ or ‘M-.’.
+
+13.5.4 Hybrid: GHCi and fallback to tags
+----------------------------------------
+
+To use GHCi first and then if that fails to fallback to tags for
+jumping, use:
+
+     (define-key haskell-mode-map (kbd "M-.") 'haskell-mode-jump-to-def-or-tag)
+
+13.5.5 Troubleshooting tags
+---------------------------
+
+Sometimes a ‘TAGS’ file is deleted (by you or some other process).
+Emacs will complain that it doesn’t exist anymore.  To resolve this
+simply do ‘M-x’ ‘tags-reset-tags-tables’.
+
+13.6 Sessions
+=============
+
+All commands in Haskell Interactive Mode work within a session.
+Consider it like a “project” or a “solution” in popular IDEs.  It tracks
+the root of your project and an associated process and REPL.
+
+13.6.1 Start a session
+----------------------
+
+To start a session run the following steps:
+
+   • Open some Cabal or Haskell file.
+   • Run ‘C-`’ to make a REPL open, this will create a session, start
+     GHCi, and open the REPL.
+   • Or: run ‘C-c C-l’ to load the file.  This will first try to start a
+     session as the previous command does.
+   • Or: run any command which requires a running session.  It will
+     always prompt to create one if there isn’t one already for the
+     current project.
+
+   It will prompt for a Cabal directory and a current directory.  It
+figures out where the cabal directory is and defaults for the current
+directory, so you should be able to just hit RET twice.
+
+13.6.2 Switch a session
+-----------------------
+
+Sometimes a particular file is used in two different sessions/projects.
+You can run
+
+         M-x haskell-session-change
+
+   If it prompts you to make a new session, tell it no (that’s a bug).
+It will ask you to choose from a list of sessions.
+
+13.6.3 Killing a session
+------------------------
+
+To kill a session you can run
+
+         M-x haskell-session-kill
+
+   Which will prompt to kill all associated buffers, too.  Hit ‘n‘ to
+retain them.
+
+   Alternatively, you can switch to the REPL and just kill the buffer
+normally with ‘C-x k RET’.  It will prompt
+
+         Kill the whole session (y or n)?
+
+   You can choose ‘y’ to kill the session itself, or ‘n’ to just kill
+the REPL buffer.  You can bring it back with ‘M-x’
+‘haskell-interactive-bring’.
+
+13.6.4 Menu
+-----------
+
+To see a list of all sessions you have open with some simple statistics
+about memory usage, etc.  run
+
+         M-x haskell-menu
+
+   For example:
+
+         foo  14648 08:21:42 214MB /path/to/fpco/foo/  /path/to/fpco/foo/ ghci
+         bar  29119 00:22:03 130MB /path/to/bar/       /path/to/bar/      ghci
+         mu   22575 08:48:20 73MB  /path/to/fpco/mu/   /path/to/fpco/mu/  ghci
+
+13.7 Compiling
+==============
+
+There are a bunch of ways to compile Haskell modules.  This page covers
+a few of them.
+
+13.7.1 Load into GHCi
+---------------------
+
+To compile and load a Haskell module into GHCi, run the following
+
+         M-x haskell-process-load
+
+   Or ‘C-c C-l’.  You’ll see any compile errors in the REPL window.
+
+13.7.2 Build the Cabal project
+------------------------------
+
+To compile the whole Cabal project, run the following
+
+         M-x haskell-process-cabal-build
+
+   Or ‘C-c C-c’.  You’ll see any compile errors in the REPL window.
+
+13.7.3 Reloading modules
+------------------------
+
+To reload the current module, even when you’re in other modules, you can
+run ‘C-u M-x’ ‘haskell-process-load-or-reload’ or ‘C-u C-c C-l’.  It
+will now reload that module whenever you run ‘C-c C-l’ in the future
+from whatever module you’re in.  To disable this mode, just run ‘C-u C-c
+C-l’ again.
+
+13.7.4 Jumping to compile errors
+--------------------------------
+
+You can use the standard compile error navigation function ‘C-x `’ —
+jump to the next error.
+
+   Or you can move your cursor to an error in the REPL and hit ‘RET’ to
+jump to it.
+
+13.7.5 Auto-removing imports
+----------------------------
+
+If the customization variable
+‘haskell-process-suggest-remove-import-lines’ is enabled.
+
+     (custom-set-variables
+       '(haskell-process-suggest-remove-import-lines t))
+
+   Building and loading modules which output warnings like,
+
+         Warning: The import of `Control.Monad' is redundant
+           except perhaps to import instances from `Control.Monad'
+         To import instances alone, use: import Control.Monad()
+
+   will prompt the user with
+
+     > The import line `Control.Monad' is redundant. Remove? (y, n, c: comment out)
+
+   If you answer
+
+   • ‘y’: it will delete the import, but leave the empty line remaining
+     (this avoids messing with line positions in subsequent error
+     messages).
+   • ‘n’: it will leave the import.
+   • ‘c’: it will comment out the import (this is handy for when you
+     just want to temporarily hide an import).
+
+13.7.6 Auto-adding of modules to import
+---------------------------------------
+
+Enable the customization variable
+‘haskell-process-suggest-hoogle-imports’.
+
+     (custom-set-variables
+       '(haskell-process-suggest-hoogle-imports t))
+
+   Whenever GHC says something is not in scope, it will hoogle that
+symbol.  If there are results, it will prompt to add one of the modules
+from Hoogle’s results.
+
+   You need to make sure you’ve generated your Hoogle database properly.
+
+13.7.7 Auto-adding of extensions
+--------------------------------
+
+It you use an extension which is not enabled, GHC will often inform you.
+For example, if you write:
+
+     newtype X a = X (IO a)
+       deriving (Monad)
+
+   Then you’ll see a message like:
+
+         x.hs:13:13: Can't make a derived instance of `Monad X': …
+               `Monad' is not a derivable class
+               Try -XGeneralizedNewtypeDeriving for GHC's newtype-deriving extension
+             In the newtype declaration for `X'
+
+   This ‘-XFoo’ pattern will be picked up and you will be prompted:
+
+     > Add `{-# LANGUAGE GeneralizedNewtypeDeriving #-}` to the top of the
+     > file? (y or n)
+
+   If you answer ‘y‘, it will temporarily jump to the buffer and it to
+the top of the file.
+
+13.7.8 Orphan instances
+-----------------------
+
+If GHC complains about orphan instances, you usually are doing it
+intentionally, so it prompts to add ‘-fno-warn-orphans’ to the top of
+the file with an ‘OPTIONS’ pragma.
+
+13.7.9 Auto-adding of dependencies
+----------------------------------
+
+When doing a build, you will sometimes get a message from GHC like:
+
+         src/ACE/Tokenizer.hs:11:18: Could not find module `Data.Attoparsec.Text' …
+             It is a member of the hidden package `attoparsec-0.11.1.0'.
+
+   This message contains all the necessary information to add this to
+your .cabal file, so you will be prompted to add it to your .cabal file:
+
+         Add `attoparsec' to ace.cabal? (y or n)  y
+
+   If you hit ‘y’, it will prompt with this:
+
+         attoparsec >= 0.11.1.0
+
+   Which you can edit (e.g.  do some PVP decision or remove constraints
+entirely), and then it will open up your ‘.cabal’ file and go through
+each section:
+
+         Add to library? (y or n)  y
+
+   This will add it to the top of the ‘build-depends’ field in your
+library section.  If you have any executables, it will go through each
+of those, prompting, too.
+
+   Now you can rebuild with ‘C-c C-c’ again.
+
+13.8 Haskell Interactive Mode REPL
+==================================
+
+When GHCi has been launched, it works on a read-eval-print basis.  So
+you will be presented with the prompt:
+
+         The lambdas must flow.
+         Changed directory: /path/to/your/project/
+         λ>
+
+13.8.1 Changing REPL target
+---------------------------
+
+With ‘haskell-session-change-target’ you can change the target for REPL
+session.
+
+   After REPL session started, in ‘haskell-interactive-mode’ buffer
+invoke the ‘haskell-session-change-target’ and select from available
+targets for
+
+   - Testing
+
+   - Benchmark
+
+   - Executable
+
+   - Library
+
+   Answer “yes” to restart the session and run your tests, benchmarks,
+executables.
+
+   TODO/WRITEME
+
+13.8.2 Bringing the REPL
+------------------------
+
+If you don’t know where the REPL buffer is, you can always bring it
+with:
+
+         M-x haskell-interactive-bring
+
+   Or ‘C-`’.
+
+13.8.3 Evaluating expressions
+-----------------------------
+
+To evaluate expressions, simply type one out and hit ‘RET‘.
+
+         λ> 123
+         123
+
+13.8.4 Evaluating multiline expressions
+---------------------------------------
+
+GHCi features two ways to evaluate multiline expressions.  You can use
+‘:set +m’ to enable multiline input
+(https://www.haskell.org/ghc/docs/latest/html/users_guide/ghci.html#multiline-input)
+for all expressions, or you can wrap your expression in ‘:{’ and ‘:}’
+(they have to be on their own lines).
+
+   The prompt will change to indicate that you’re inputting a multiline
+expression:
+
+     λ> :{
+     λ| let a = 10
+     λ|     b = 20
+     λ|     c = 30
+     λ| :}
+
+   You can also simulate multiline mode by having your input contain
+newline characters.  You can input a literal newline character with ‘C-q
+C-j’, or you can use:
+
+         M-x haskell-interactive-mode-newline-indent
+
+   which is bound to ‘C-j’.  This command indents after the newline.
+You can simulate the above example like so:
+
+     λ> let a = 10
+            b = 20
+            c = 30
+
+13.8.5 Type of expressions
+--------------------------
+
+You can use normal ‘:type’ which is part of GHCi to get the type of
+something:
+
+         λ> :t id
+         id :: a -> a
+
+   But you can also just write out the value directly,
+
+         λ> id
+         id :: a -> a
+
+   and because there’s no ‘Show’ instance for ‘(a -> a)’.  This would
+normally yield a compile error:
+
+         No instance for (Show (a0 -> a0))
+           arising from a use of `print'
+         Possible fix: add an instance declaration for (Show (a0 -> a0))
+         In a stmt of an interactive GHCi command: print it
+
+   It will run ‘:type id’ in the background and print out the result.
+The same is true for ambiguous things:
+
+         λ> :t read "a"
+         read "a" :: Read a => a
+
+   Because this would normally be an ambiguous constraint:
+
+         Ambiguous type variable `a0' in the constraint:
+           (Read a0) arising from a use of `read'
+         Probable fix: add a type signature that fixes these type variable(s)
+         In the expression: read \"a\"
+         In an equation for `it': it = read \"a\"
+
+   Which is less useful than just printing the type out.
+
+   You can disable this behaviour by disabling the customization option:
+
+     (custom-set-variables
+       '(haskell-interactive-types-for-show-ambiguous nil))
+
+13.8.6 Printing mode
+--------------------
+
+You can choose between printing modes used for the results of evaluating
+expressions.  To do that, configure the variable
+‘haskell-interactive-mode-eval-mode’.  Example:
+
+     (setq haskell-interactive-mode-eval-mode 'haskell-mode)
+
+   A handy function you can use is:
+
+     (defun haskell-interactive-toggle-print-mode ()
+       (interactive)
+       (setq haskell-interactive-mode-eval-mode
+             (intern
+              (ido-completing-read "Eval result mode: "
+                                   '("fundamental-mode"
+                                     "haskell-mode"
+                                     "espresso-mode"
+                                     "ghc-core-mode"
+                                     "org-mode")))))
+
+   (Add whichever modes you want to use.)
+
+   And then run
+
+         M-x haskell-interactive-toggle-print-mode
+
+   Or ‘C-c C-v’:
+
+     (define-key haskell-interactive-mode-map (kbd "C-c C-v")
+                 'haskell-interactive-toggle-print-mode)
+
+   There you can choose ‘haskell-mode‘, for example, to pretty print the
+output as Haskell.
+
+13.8.7 Presentations
+--------------------
+
+If you have the ‘present’ package installed, you can use the following
+syntax to print anything which is an instance of ‘Data’:
+
+         λ> :present 123
+         123
+
+   It will print data structures lazily:
+
+         λ> :present [1..]
+         [1
+         ,[Integer]]
+
+   It shows types when there is an unevaluated field in a constructor.
+You can click the ‘[Integer]’ or press ‘RET’ on it to expand further:
+
+         λ> :present [1..]
+         [1
+         ,2
+         ,[Integer]]
+
+   Etc.  Remember: this only works for instances of ‘Data.Data.Data’.
+
+13.8.8 History
+--------------
+
+A history is maintained for the duration of the REPL buffer.  To go up
+and down in the history, run ‘M-p’ for previous and ‘M-n’ for next.
+
+13.8.9 Cancelling commands
+--------------------------
+
+To cancel a running REPL command, run ‘C-c C-c’.
+
+13.8.10 Clear the REPL
+----------------------
+
+Run ‘C-c C-k’ to clear the REPL.
+
+13.8.11 Trick: Put Interactive REPL in Separate Frame
+-----------------------------------------------------
+
+The following ‘create-haskell-interactive-frame’ is a quick hack to move
+the repl to a separate frame, for those that want a more predictable
+layout of windows in Emacs.
+
+     (defun create-unfocused-frame ()
+       (let*
+         ((prv (window-frame))
+          (created (make-frame)))
+         (select-frame-set-input-focus prv) created))
+
+     (defun create-haskell-interactive-frame ()
+       (interactive)
+       (haskell-interactive-bring)
+       (create-unfocused-frame)
+       (delete-window))
+
+
+13.8.12 Troubleshooting
+-----------------------
+
+If the REPL ever goes funny, you can clear the command queue via:
+
+         M-x haskell-process-clear
+
+   Alternatively, you can just restart the process:
+
+         M-x haskell-process-restart
+
+   You can also switch to the buffer ‘*haskell-process-log*’, which can
+be enabled and disabled with the customization variable
+‘haskell-process-log‘, to see what the cause of your troubles are.
+
+   If the process fails and nothing unusual is in the process log, the
+following command can dump the ‘haskell-process’ state:
+
+         M-: (haskell-process)
+
+   The output can be copied from the ‘*Messages*’ buffer.
+
+13.9 Haskell Interactive Mode Querying
+======================================
+
+There a few ways GHCi lets you query information about your code.
+
+13.9.1 Get identifer type
+-------------------------
+
+To print the type of the top-level identifier at point in the REPL and
+in the message buffer, run the following command:
+
+         M-x haskell-process-do-type
+
+   or ‘C-c C-t’.
+
+13.9.2 Insert identifier’s type as type signature
+-------------------------------------------------
+
+To print the type of the top-level identifier at point, run the
+following command:
+
+         C-u M-x haskell-process-do-type
+
+   or ‘C-u C-c C-t’.
+
+13.9.3 Get identifier info
+--------------------------
+
+To print the info of the identifier at point, run the following command:
+
+         M-x haskell-process-do-info
+
+   or ‘C-c C-i’.
+
+13.9.4 Presentation mode
+------------------------
+
+When using ‘C-c C-i’ or ‘C-c C-t’ it will open a buffer in
+haskell-presentation-mode.  You can hit ‘q’ to close the buffer.
+
+   But you can also continue to use ‘C-c C-i’ inside the buffer to drill
+further down data types and classes.
+
+   E.g.  if you go to ‘Ord’ in your code buffer and ‘C-c C-i’, it will
+popup a buffer containing
+
+     class Eq a => Ord a where
+       compare :: a -> a -> Ordering
+       (<) :: a -> a -> Bool
+       (>=) :: a -> a -> Bool
+       (>) :: a -> a -> Bool
+       (<=) :: a -> a -> Bool
+       max :: a -> a -> a
+       min :: a -> a -> a
+       	-- Defined in `GHC.Classes'
+
+   And all the instances of that class.  But then you can also move your
+cursor to ‘Ordering’ and hit ‘C-c C-i’ again to get another popup:
+
+     data Ordering = LT | EQ | GT 	-- Defined in `GHC.Types'
+     instance Bounded Ordering -- Defined in `GHC.Enum'
+     instance Enum Ordering -- Defined in `GHC.Enum'
+     instance Eq Ordering -- Defined in `GHC.Classes'
+     instance Ord Ordering -- Defined in `GHC.Classes'
+     instance Read Ordering -- Defined in `GHC.Read'
+     instance Show Ordering -- Defined in `GHC.Show'
+
+   And so on.  It’s a very good way of exploring a new codebase.
+
+13.9.5 Browse import’s module
+-----------------------------
+
+To print all exported identifiers of the module imported by the import
+line at point, run the following command:
+
+         M-x haskell-process-do-info
+
+   or ‘C-c C-i’.  It will print all exports by running ‘:browse
+The.Module’ in the GHCi process.
+
+13.10 Haskell Interactive Mode Cabal integration
+================================================
+
+There’s some integration with Cabal in Haskell Interactive Mode.  Once
+you’ve started a session, the features below are available.
+
+13.10.1 Cabal building
+----------------------
+
+The most common Cabal action is building, so that has a specific
+command:
+
+         M-x haskell-process-cabal-build
+
+   Or ‘C-c C-c’.  When building, it will hide unneccessary output.
+
+   For example, to build the ‘ace‘ package, the output is simply:
+
+         Compiling: ACE.Types.Tokens
+         Compiling: ACE.Combinators
+         Compiling: ACE.Tokenizer
+         Compiling: ACE.Parsers
+         Compiling: ACE.Pretty
+         Compiling: ACE
+         Complete: cabal build (0 compiler messages)
+
+   Whereas the complete output is normally:
+
+         Building ace-0.5...
+         Preprocessing library ace-0.5...
+         [4 of 9] Compiling ACE.Types.Tokens ( src/ACE/Types/Tokens.hs, dist/build/ACE/Types/Tokens.o )
+         [5 of 9] Compiling ACE.Combinators  ( src/ACE/Combinators.hs, dist/build/ACE/Combinators.o ) [ACE.Types.Tokens changed]
+         [6 of 9] Compiling ACE.Tokenizer    ( src/ACE/Tokenizer.hs, dist/build/ACE/Tokenizer.o ) [ACE.Types.Tokens changed]
+         [7 of 9] Compiling ACE.Parsers      ( src/ACE/Parsers.hs, dist/build/ACE/Parsers.o )
+         [8 of 9] Compiling ACE.Pretty       ( src/ACE/Pretty.hs, dist/build/ACE/Pretty.o )
+         [9 of 9] Compiling ACE              ( src/ACE.hs, dist/build/ACE.o ) [ACE.Tokenizer changed]
+         In-place registering ace-0.5...
+
+   Which is considerably more verbose but rarely useful or interesting.
+
+13.10.2 Arbitrary cabal commands
+--------------------------------
+
+To run an arbitrary Cabal command:
+
+         C-u M-x haskell-process-cabal
+
+   Or run ‘C-u C-c c’.
+
+   It will prompt for an input, so you can write ‘configure -fdev’, for
+example.
+
+13.10.3 Completing cabal commands
+---------------------------------
+
+To run some common Cabal commands, just run:
+
+         M-x haskell-process-cabal
+
+   Or ‘C-c c’.  This is commonly used to do ‘install’, ‘haddock’,
+‘configure’, etc.
+
+13.11 Haskell Interactive Mode Debugger
+=======================================
+
+There is limited support for debugging in GHCi.  Haskell Interactive
+Mode provides an interface for interacting with this.
+
+13.11.1 Opening the debug buffer
+--------------------------------
+
+To open the debug buffer run the following command from any buffer
+associated with a session:
+
+         M-x haskell-debug
+
+   It will open a buffer that looks like this:
+
+         Debugging haskell
+
+         You have to load a module to start debugging.
+
+         g - refresh
+
+         Modules
+
+         No loaded modules.
+
+13.11.2 Loading modules
+-----------------------
+
+To debug anything you need to load something into GHCi.  Switch to a
+normal file, for example:
+
+     main = do putStrLn "Hello!"
+               putStrLn "World"
+
+   and load it into GHCi (‘C-c C-l’).  Now when you hit ‘g’ (to refresh)
+in the debugging buffer, you’ll see something like:
+
+
+         Debugging haskell
+
+         b - breakpoint, g - refresh
+
+         Context
+
+         Not debugging right now.
+
+         Breakpoints
+
+         No active breakpoints.
+
+         Modules
+
+         Main - hello.hs
+
+13.11.3 Setting a breakpoint
+----------------------------
+
+To set a breakpoint hit ‘b’ in the debugger buffer.  It will prompt for
+a name.  Enter ‘main’ and hit ‘RET’.
+
+   Now the buffer will look like this:
+
+         Debugging haskell
+
+         s - step into an expression, b - breakpoint
+         d - delete breakpoint, g - refresh
+
+         Context
+
+         Not debugging right now.
+
+         Breakpoints
+
+         0 - Main (1:8)
+
+         Modules
+
+         Main - hello.hs
+
+13.11.4 Start stepping
+----------------------
+
+Hit ‘s’ to step through an expression: it will prompt for an expression
+to evaluate and step through.  Enter ‘main’ and hit ‘RET’.  Now the
+buffer will look like this:
+
+         Debugging haskell
+
+         s - step into an expression, b - breakpoint
+         d - delete breakpoint, a - abandon context, c - continue
+         p - previous step, n - next step
+         g - refresh
+
+         Context
+
+         main - hello.hs (stopped)
+
+         do putStrLn "Hello!"
+            putStrLn "World"
+
+         _result :: IO () = _
+
+            1 do putStrLn "Hello!" putStrLn "World"
+
+         Breakpoints
+
+         0 - Main (1:8)
+
+         Modules
+
+         Main - hello.hs
+
+   What we see here is the current expression being evaluated:
+
+     do putStrLn "Hello!"
+        putStrLn "World"
+
+   And we see the type of it:
+
+     _result :: IO () = _
+
+   And we see a backtrace of steps so far:
+
+     1 do putStrLn "Hello!" putStrLn "World"
+
+13.11.5 Continue stepping
+-------------------------
+
+To continue stepping, just hit ‘s’ again.  Now the context will change
+to:
+
+     main - hello.hs (stopped)
+
+     putStrLn "Hello!"
+
+     _result :: IO () = _
+
+        1 do putStrLn "Hello!" putStrLn "World"
+
+   Hitting ‘s’ once more, we see the context change to:
+
+     putStrLn "World"
+
+     _result :: IO () = _
+
+        2 putStrLn "Hello!"
+        1 do putStrLn "Hello!" putStrLn "World"
+
+   Finally hitting ‘s’ again will say "Computation finished".  Hitting
+‘s’ a final time will change the display back to:
+
+         Debugging haskell
+
+         s - step into an expression, b - breakpoint
+         d - delete breakpoint, g - refresh
+
+         Context
+
+         Finished debugging.
+
+            2 putStrLn "Hello!"
+            1 do putStrLn "Hello!" putStrLn "World"
+
+         Breakpoints
+
+         1 - Main (1:8)
+
+         Modules
+
+         Main - hello.hs
+
+   And you’re done debugging.
+
+
+File: haskell-mode.info,  Node: Editing Cabal files,  Next: Browsing Haddocks,  Prev: Interactive Haskell,  Up: Top
+
+14 Editing Cabal files
+**********************
+
+‘haskell-cabal-mode’ is a major mode for editing Cabal package
+description files
+(http://www.haskell.org/cabal/users-guide/developing-packages.html) and
+is automatically associated with files having a ‘.cabal’ extension.
+
+   For quickly locating and jumping to the nearest ‘.cabal’ file from a
+Haskell source buffer, you can use ‘M-x haskell-cabal-visit-file’; with
+a prefix argument (i.e.  ‘C-u’) ‘find-file-other-window’ is used to
+visit the ‘.cabal’ file.  ‘haskell-cabal-visit-file’ is bound to the key
+sequence ‘C-c v c’.
+
+   TODO/WRITEME
+
+
+File: haskell-mode.info,  Node: Browsing Haddocks,  Next: Spell checking strings and comments,  Prev: Editing Cabal files,  Up: Top
+
+15 Browsing Haddocks using ‘w3m’
+********************************
+
+An experimental feature is use of the w3m browser to browse Haddock docs
+inside Emacs.
+
+15.1 Get w3m
+============
+
+Most Linux distributions will have a package for the binary:
+
+     $ sudo apt-get install w3m
+
+   Now grab ‘w3m.el’ from:
+
+   • <http://emacs-w3m.namazu.org/>
+   • ‘M-x’ ‘package-install’ ‘RET’ ‘w3m’ ‘RET’
+
+   Confirm installation by trying ‘M-x’ ‘w3m-browse-url’ ‘RET’
+‘haskell.org’ ‘RET’.
+
+   If this works, you’re good to go.
+
+15.2 Configure w3m
+==================
+
+Now that you have w3m, you probably want to configure it to be more of a
+passive viewer than a full-fledged browser.  For example:
+
+     (setq w3m-mode-map (make-sparse-keymap))
+
+     (define-key w3m-mode-map (kbd "RET") 'w3m-view-this-url)
+     (define-key w3m-mode-map (kbd "q") 'bury-buffer)
+     (define-key w3m-mode-map (kbd "<mouse-1>") 'w3m-maybe-url)
+     (define-key w3m-mode-map [f5] 'w3m-reload-this-page)
+     (define-key w3m-mode-map (kbd "C-c C-d") 'haskell-w3m-open-haddock)
+     (define-key w3m-mode-map (kbd "M-<left>") 'w3m-view-previous-page)
+     (define-key w3m-mode-map (kbd "M-<right>") 'w3m-view-next-page)
+     (define-key w3m-mode-map (kbd "M-.") 'w3m-haddock-find-tag)
+
+     (defun w3m-maybe-url ()
+       (interactive)
+       (if (or (equal '(w3m-anchor) (get-text-property (point) 'face))
+               (equal '(w3m-arrived-anchor) (get-text-property (point) 'face)))
+           (w3m-view-this-url)))
+
+15.3 Import w3m-haddock
+=======================
+
+It’s not enabled by default in haskell-mode at present, so you need to
+import it manually:
+
+     (require 'w3m-haddock)
+
+15.4 Add a hook for w3m
+=======================
+
+In order to make haddock pages a little more palatable (and add syntax
+highlighting to source view), you can add this hook:
+
+     (add-hook 'w3m-display-hook 'w3m-haddock-display)
+
+   It’s a little rough around the edges, but it’s a start.
+
+15.5 Configure your package locations
+=====================================
+
+By default, the package locations is set to:
+
+     (defcustom haskell-w3m-haddock-dirs
+       '("~/.cabal/share/doc/"))
+
+   If you are using an hsenv or a custom package directory, you should
+configure this variable with M-x customize-variable or by writing the
+custom-set-variables code for it.
+
+15.6 Finally
+============
+
+You did all that!  Now you’re ready to bind a useful key:
+
+     (define-key haskell-mode-map (kbd "C-c C-d") 'haskell-w3m-open-haddock)
+
+   Now when you press ‘C-c’ ‘C-d’ it will prompt for a package to browse
+to.
+
+   This feature will be improved gradually as time goes on.
+
+
+File: haskell-mode.info,  Node: Spell checking strings and comments,  Next: Aligning code,  Prev: Browsing Haddocks,  Up: Top
+
+16 Using with ‘flyspell-prog-mode’
+**********************************
+
+Strings and comments can be checked for spelling mistakes.  There is a
+standard Emacs mode for this purpose, ‘flyspell-prog-mode’, that can be
+enabled in Haskell buffers.  Spelling errors are underlined using
+squiggly red lines.
+
+   Documentation for ‘flyspell-prog-mode’ can be found in *Note
+(emacs)Spelling::.  Here we point to a couple of useful keybindings:
+
+   • ‘M-$’ - Check and correct spelling of the word at point
+     (‘ispell-word’).
+
+   • ‘digit’ - Replace the word, just this time, with one of the
+     displayed near-misses.  Each near-miss is listed with a digit; type
+     that digit to select it.
+
+   • ‘SPC’ - Skip this word—continue to consider it incorrect, but don’t
+     change it here.
+
+   To enable spell checking of strings and comments add this line to
+your ‘~/.emacs’ file:
+
+   ‘(add-hook 'haskell-mode-hook 'flyspell-prog-mode)’
+
+
+File: haskell-mode.info,  Node: Aligning code,  Next: Rectangular commands,  Prev: Spell checking strings and comments,  Up: Top
+
+17 Aligning code
+****************
+
+Select a region you want to align text within, ‘M-x’ ‘align-regexp’, and
+type a regexp representing the alignment delimiter.
+
+   For example, I often line up my Haddock comments:
+
+     f :: a -- ^ does a
+       -> Foo b -- ^ and b
+       -> c -- ^ to c
+
+   Select the region, and let the regexp be ‘--’:
+
+     f :: a     -- ^ does a
+       -> Foo b -- ^ and b
+       -> c     -- ^ to c
+
+   Of course, this works for just about anything.  Personally, I’ve
+globally bound it to ‘C-x a r’:
+
+     (global-set-key (kbd "C-x a r") 'align-regexp)
+
+   Note that you can also just use the rules below for telling the
+aligner about Haskell.  Once you evaluate this, you can just use ‘M-x’
+‘align’, which I like to bind to ‘M-[’.
+
+     (add-to-list 'align-rules-list
+                  '(haskell-types
+                    (regexp . "\\(\\s-+\\)\\(::\\|∷\\)\\s-+")
+                    (modes quote (haskell-mode literate-haskell-mode))))
+     (add-to-list 'align-rules-list
+                  '(haskell-assignment
+                    (regexp . "\\(\\s-+\\)=\\s-+")
+                    (modes quote (haskell-mode literate-haskell-mode))))
+     (add-to-list 'align-rules-list
+                  '(haskell-arrows
+                    (regexp . "\\(\\s-+\\)\\(->\\|→\\)\\s-+")
+                    (modes quote (haskell-mode literate-haskell-mode))))
+     (add-to-list 'align-rules-list
+                  '(haskell-left-arrows
+                    (regexp . "\\(\\s-+\\)\\(<-\\|←\\)\\s-+")
+                    (modes quote (haskell-mode literate-haskell-mode))))
+
+
+File: haskell-mode.info,  Node: Rectangular commands,  Next: REPL,  Prev: Aligning code,  Up: Top
+
+18 Using rectangular region commands
+************************************
+
+Emacs has a set of commands which operate on the region as if it were
+rectangular.  This turns out to be extremely useful when dealing with
+whitespace sensitive languages.
+
+   • ‘C-x r o’ is "Open Rectangle".
+
+     It will shift any text within the rectangle to the right side.
+     Also see:
+
+   • ‘C-x r t’ is "String Rectangle".
+
+     It will replace any text within the rectangle with the given string
+     on all the lines in the region.  If comment-region didn’t already
+     exist, you could use this instead, for example.
+
+   • ‘C-x r d’ is "Delete Rectangle".
+
+     It will delete the contents of the rectangle and move anything on
+     the right over.
+
+   • ‘C-x r r’ is "Copy Rectangle to Register".
+
+     It will prompt you for a register number so it can save it for
+     later.
+
+   • ‘C-x r g’ is "Insert register".
+
+     This will insert the contents of the given register, overwriting
+     whatever happens to be within the target rectangle.  (So make room)
+
+   • ‘C-x r k’ is "Kill rectangle".
+
+     Delete rectangle and save contents for:
+
+   • ‘C-x r y’ is "Yank rectangle".
+
+     This will insert the contents of the last killed rectangle.
+
+   As with all Emacs modifier combos, you can type ‘C-x r C-h’ to find
+out what keys are bound beginning with the ‘C-x r’ prefix.
+
+
+File: haskell-mode.info,  Node: REPL,  Next: Collapsing Haskell code,  Prev: Rectangular commands,  Up: Top
+
+19 Using GHCi REPL within Emacs
+*******************************
+
+To start the REPL you can run one of the following:
+
+   • ‘M-x run-haskell’
+   • ‘M-x switch-to-haskell’
+
+   This repl works with Comint
+(https://www.emacswiki.org/emacs/ComintMode).  So you will feel at home
+if you are already using ‘M-x Shell’ or ‘M-x ielm’.
+
+   ‘Inf-Haskell’ is a Major mode for running GHCi, with comint.
+
+   Important key bindings in ‘Inf-haskell’:
+
+‘RET’
+     invokes ‘comint-send-input’.  Sends the input to the GHCi process,
+     evaluates the line and returns the output.
+
+‘C-d or <delete>’
+     deletes the forward character
+
+‘<C-up> or M-p’
+     invokes ‘comint-previous-input’.  Cycle backwards through input
+     history, saving input.
+
+‘<C-down> or M-n’
+     invokes ‘comint-next-input’.  Cycle forwards through input history.
+
+‘C-c C-c’
+     invokes ‘comint-interrupt-subjob’.  Sends KeyboardInterrupt signal.
+
+‘C-c C-\’
+     invokes ‘comint-quit-subjob’.  Sends KeyboardInterrupt signal.
+
+‘C-c C-z’
+     invokes ‘comint-stop-subjob’.  Kills the GHCi process.
+
+‘C-c M-r’
+     invokes ‘comint-previous-matching-input-from-input’.  If you are
+     familiar with ‘C-r’ in bash.  This is the same as that.  Searches
+     backwards through input history for match for current input.
+
+‘C-c M-s’
+     invokes ‘comint-next-matching-input-from-input’.  Searches forwards
+     through input history for match for current input.
+
+‘C-c C-l’
+     invokes ‘comint-dynamic-list-input-ring’.  Displays a list of
+     recent inputs entered into the current buffer.
+
+‘C-c M-o’
+     invokes ‘comint-clear-buffer’.  Clears the buffer (Only with Emacs
+     25.X and above)
+
+‘C-c C-n’
+     invokes ‘comint-next-prompt’.  Goes to the start of the previous
+     REPL prompt.
+
+‘C-c C-p’
+     invokes ‘comint-previous-prompt’.  Goes to the start of the next
+     REPL prompt.
+
+‘C-c C-o’
+     invokes ‘comint-delete-output’.  Clears the output of the most
+     recently evaluated expression.
+
+‘C-c C-e’
+     invokes ‘comint-show-maximum-output’.  Moves the point to the end
+     of the buffer.
+
+‘C-c C-u’
+     invokes ‘comint-kill-input’.  Kills backward, the line at point.
+     (Use this when you have typed in an expression into the prompt but
+     you dont want to evaluate it.)
+
+‘C-c C-w’
+     invokes ‘backward-kill-word’.  Kills backward, the word at point
+
+‘C-c C-s’
+     invokes ‘comint-write-output’.  Write output from interpreter since
+     last input to FILENAME. Any prompt at the end of the output is not
+     written.
+
+19.1 Relevant defcustoms:
+=========================
+
+Interpreter (defcustom)       Default        Possible Values
+                              Value
+---------------------------------------------------------------------------
+‘haskell-process-type’        ‘'auto’        ‘'stack-ghci, 'cabal-repl,
+                                             'ghci, 'auto’
+‘inferior-haskell-hook’       ‘nil’          -
+‘haskell-process-path-ghci’   ‘ghci’         -
+‘haskell-process-args-ghci’   ‘-ferror-spans’-
+‘haskell-process-path-cabal’  ‘cabal’        -
+‘haskell-process-args-cabal-repl’‘--ghc-option=-ferror-spans’-
+‘haskell-process-path-stack’  ‘stack’        -
+‘haskell-process-args-stack-ghci’‘--ghci-options=-ferror-spans-
+                              --no-build
+                              --no-load’
+
+19.2 More on ‘haskell-process-type’
+===================================
+
+The Haskell interpreter used by ‘Inf-Haskell’ is auto-detected by
+default, but is customizable with defcustom ‘haskell-process-type’.  The
+values recognized by it are (default is ’auto):
+
+   • ‘'stack-ghci’
+   • ‘'cabal-repl’
+   • ‘'ghci’
+   • ‘'auto’
+
+   if the ‘haskell-process-type’ is ‘'auto’, the directories are
+searched for ‘cabal.sandbox.config’ or ‘stack.yaml’ or ‘*.cabal’ file.
+If the file is present, then appropriate process is started.
+
+   When ‘cabal.sandbox.config’ is found ‘haskell-process-type’ is
+‘'cabal-repl’.  Similarly, when ‘stack.yaml’ is found
+‘haskell-process-type’ is ‘'stack-ghci’.  Similarly, when ‘xyz.cabal’ is
+found ‘haskell-process-type’ is ‘'cabal-repl’.  When nothing is found
+‘haskell-process-type’ is ‘'ghci’.  When more than one file such as
+‘cabal.sandbox.config’ and ‘stack.yaml’ are found the following
+preference is followed.
+
+   ‘cabal.sandbox.config’ > ‘stack.yaml’ > ‘*.cabal’
+
+
+File: haskell-mode.info,  Node: Collapsing Haskell code,  Next: Getting Help and Reporting Bugs,  Prev: REPL,  Up: Top
+
+20 Collapsing Haskell code
+**************************
+
+This is ‘hs-minor-mode’ for ‘haskell-mode’.  This module uses hideshow
+module.
+
+   To activate this minor mode (haskell-collapse-mode)
+   • ‘M-x haskell-collapse-mode’ is "To start haskell-collapse-mode".
+   This minor mode works with indentation.
+
+   In a quick glance:
+
+‘C-c  C-c’
+     is bound to ‘haskell-hide-toggle’
+‘C-c  C-M-c’
+‘C-c  C-M-h’
+‘C-c  C-M-s’
+     are all bound to ‘haskell-hide-toggle-all’
+
+   How to use ‘M-x haskell-hide-toggle’?
+
+   Place your point on the code block that you want to collapse and hit
+the keybinding.  Now the code collapses and you can see the first line
+of the block and elipsis.
+
+   Take this example code (example usage of ‘M-x haskell-hide-toggle’):
+when you place the cursor here, like this (notice the thick block in the
+first line):
+
+   ‘ f█x | rem i 3 == 0 = if i == 0 && (k /= 0) then (c k) else (h j) |
+otherwise = 0 where i = sum x j = g x (div i 3) 0 0 [] k = zeroes x 0 ’
+
+   or
+
+   ‘ f x | rem i 3 == 0 = if i == 0 && (k /= 0) then (c k) else (h j) █
+| otherwise = 0 where i = sum x j = g x (div i 3) 0 0 [] k = zeroes x 0
+’
+
+   then when you collapse it becomes something like this:
+
+   ‘ f█x... ’
+
+   It works in terms of (indentation) blocks.
+
+   One more example:
+
+   ‘ f x | rem i 3 == 0 = if i == 0 && (k /= 0) then (c k) else (h j) |
+otherwise = 0 w█ere i = sum x j = g x (div i 3) 0 0 [] k = zeroes x 0 ’
+
+   or
+
+   ‘ f x | rem i 3 == 0 = if i == 0 && (k /= 0) then (c k) else (h j) |
+otherwise = 0 where i = sum x j = g x (div i 3) 0 0 [] █ k = zeroes x 0
+’
+
+   this, will result in something like:
+
+   ‘ f x | rem i 3 == 0 = if i == 0 && (k /= 0) then (c k) else (h j) |
+otherwise = 0 where i = sum █... ’
+
+   The other functionality ‘M-x haskell-hide-toggle-all’ also works only
+for indentation and it collapses all toplevel functions.
+
+   So a file that looks like this:
+
+     main = interact $ show.f. map read .words
+     f (x:xs) = dp x xs
+
+     dp money a | money < 0 || null a = [1..1000]
+     dp 0 a = []
+     dp money a @ (coin:coins)
+       | (length i) <= length j = i
+       | otherwise = j
+       where i = (coin:(dp (money-coin) a))
+             j = (dp money coins)
+
+   will turn into this:
+
+     main = interact $ show.f. map read .words
+     f (x:xs) = dp x xs
+
+     dp money a | money < 0 || null a = [1..1000]
+     dp 0 a = []
+     dp money a @ (coin:coins)...
+
+
+File: haskell-mode.info,  Node: Getting Help and Reporting Bugs,  Next: Concept index,  Prev: Collapsing Haskell code,  Up: Top
+
+21 Getting Help and Reporting Bugs
+**********************************
+
+Work on Haskell Mode is organized with Github ‘haskell-mode’ project.
+To understand how the project is run please read the information in the
+project wiki pages (https://github.com/haskell/haskell-mode/wiki).
+
+   To report any issues please use the Github’s issue mechanism
+available from Haskell Mode’s GitHub Home
+(https://github.com/haskell/haskell-mode).
+
+   For a quick question visit ‘#haskell-emacs’ channel on IRC
+‘irc.freenode.net’.
+
+   There is also a (now defunct) Haskellmode-emacs mailing list
+(http://projects.haskell.org/cgi-bin/mailman/listinfo/haskellmode-emacs),
+also available on Gmane (http://gmane.org/) via the
+gmane.comp.lang.haskell.emacs
+(http://dir.gmane.org/gmane.comp.lang.haskell.emacs) newsgroup.
+
+   We welcome code and non-code contributions so that we can all enjoy
+coding Haskell even more.
+
+
+File: haskell-mode.info,  Node: Concept index,  Next: Function index,  Prev: Getting Help and Reporting Bugs,  Up: Top
+
+Concept index
+*************
+
+
+* Menu:
+
+* benchmarking:                          Interactive Haskell. (line 472)
+* CUA mode:                              Indentation.         (line  49)
+* customizing:                           Installation.        (line  55)
+* customizing <1>:                       Interactive Haskell. (line  53)
+* haskell-mode:                          Editing Haskell Code.
+                                                              (line   6)
+* indentation:                           Indentation.         (line   6)
+* layout rule:                           Indentation.         (line   6)
+* off-side rule:                         Indentation.         (line   6)
+* rectangle:                             Indentation.         (line  49)
+* testing:                               Interactive Haskell. (line 470)
+* Unicode:                               Unicode support.     (line   6)
+
+
+File: haskell-mode.info,  Node: Function index,  Next: Variable index,  Prev: Concept index,  Up: Top
+
+Function index
+**************
+
+
+* Menu:
+
+* haskell-cabal-mode:                    Editing Cabal files. (line   6)
+* haskell-cabal-visit-file:              Editing Cabal files. (line  11)
+* haskell-compile:                       Compilation.         (line   6)
+* haskell-decl-scan-mode:                Declaration scanning.
+                                                              (line   6)
+* haskell-mode:                          Editing Haskell Code.
+                                                              (line   6)
+* haskell-session-change-target:         Interactive Haskell. (line 463)
+
+
+File: haskell-mode.info,  Node: Variable index,  Prev: Function index,  Up: Top
+
+Variable index
+**************
+
+
+* Menu:
+
+* haskell-c2hs-hook-name-face:           Syntax highlighting. (line  39)
+* haskell-c2hs-hook-pair-face:           Syntax highlighting. (line  38)
+* haskell-cabal-mode-hook:               Editing Cabal files. (line   6)
+* haskell-compile-cabal-build-command:   Compilation.         (line  35)
+* haskell-compile-cabal-build-command-alt: Compilation.       (line  35)
+* haskell-compile-command:               Compilation.         (line  35)
+* haskell-constructor-face:              Syntax highlighting. (line  30)
+* haskell-decl-scan-mode-hook:           Declaration scanning.
+                                                              (line   6)
+* haskell-definition-face:               Syntax highlighting. (line  31)
+* haskell-interactive-mode-hook:         Interactive Haskell. (line 463)
+* haskell-keyword-face:                  Syntax highlighting. (line  28)
+* haskell-literate-comment-face:         Syntax highlighting. (line  35)
+* haskell-mode-hook:                     Installation.        (line  60)
+* haskell-operator-face:                 Syntax highlighting. (line  33)
+* haskell-pragma-face:                   Syntax highlighting. (line  34)
+* haskell-process-args-cabal-new-repl:   Interactive Haskell. (line  76)
+* haskell-process-args-cabal-repl:       Interactive Haskell. (line  76)
+* haskell-process-args-ghci:             Interactive Haskell. (line  76)
+* haskell-process-args-stack-ghci:       Interactive Haskell. (line  75)
+* haskell-process-path-cabal:            Interactive Haskell. (line  76)
+* haskell-process-path-ghci:             Interactive Haskell. (line  76)
+* haskell-process-path-stack:            Interactive Haskell. (line  76)
+* haskell-process-type:                  Interactive Haskell. (line  76)
+* haskell-quasi-quote-face:              Syntax highlighting. (line  36)
+* haskell-type-face:                     Syntax highlighting. (line  29)
+
+
+
+Tag Table:
+Node: Top683
+Node: Introduction2588
+Node: Installation4173
+Node: Editing Haskell Code6796
+Node: Syntax highlighting10556
+Node: Completion support12816
+Node: Unicode support14860
+Node: Indentation19532
+Node: External indentation23008
+Node: Autoformating23736
+Node: Module templates24364
+Node: Declaration scanning24794
+Node: Compilation28082
+Node: Interactive Haskell31987
+Node: Editing Cabal files62914
+Node: Browsing Haddocks63661
+Node: Spell checking strings and comments66486
+Node: Aligning code67592
+Node: Rectangular commands69337
+Node: REPL70857
+Node: Collapsing Haskell code75635
+Node: Getting Help and Reporting Bugs78243
+Node: Concept index79287
+Node: Function index80326
+Node: Variable index81048
+
+End Tag Table
+
+
+Local Variables:
+coding: utf-8
+End:
diff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-modules.el b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-modules.el
new file mode 100644
index 0000000000..cb4e841d67
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-modules.el
@@ -0,0 +1,117 @@
+;;; haskell-modules.el --- -*- lexical-binding: t -*-
+
+;; Copyright (c) 2014 Chris Done. All rights reserved.
+
+;; This file 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, or (at your option)
+;; any later version.
+
+;; This file 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Code:
+
+(require 'haskell-sort-imports)
+(require 'haskell-align-imports)
+(require 'haskell-session)
+(require 'haskell-navigate-imports)
+(require 'haskell-complete-module)
+(require 'haskell-sandbox)
+(require 'haskell-customize)
+
+(defun haskell-add-import (&optional module)
+  "Add an import to the import list.  Sorts and aligns imports,
+unless `haskell-stylish-on-save' is set, in which case we defer
+to stylish-haskell."
+  (interactive)
+  (save-excursion
+    (goto-char (point-max))
+    (haskell-navigate-imports)
+    (insert (haskell-import-for-module
+             (or module
+                 (haskell-complete-module-read
+                  "Module: "
+                  (haskell-session-all-modules (haskell-modules-session))))))
+    (unless haskell-stylish-on-save (haskell-sort-imports)
+            (haskell-align-imports))))
+
+(defun haskell-import-for-module (module)
+  "Get import statements for the given module."
+  (let ((mapping (assoc module haskell-import-mapping)))
+    (if mapping
+        (cdr mapping)
+      (concat (read-from-minibuffer "Import line: "
+                                    (format "import %s" module))
+              "\n"))))
+
+;;;###autoload
+(defun haskell-session-installed-modules (_session &optional _dontcreate)
+  "Get the modules installed in the current package set."
+  ;; TODO: Again, this makes HEAVY use of unix utilities. It'll work
+  ;; fine in Linux, probably okay on OS X, and probably not at all on
+  ;; Windows. Again, if someone wants to test on Windows and come up
+  ;; with alternatives that's OK.
+  ;;
+  ;; Ideally all these package queries can be provided by a Haskell
+  ;; program based on the Cabal API. Possibly as a nice service. Such
+  ;; a service could cache and do nice things like that. For now, this
+  ;; simple shell script takes us far.
+  ;;
+  ;; Probably also we can take the code from inferior-haskell-mode.
+  ;;
+  ;; Ugliness aside, if it saves us time to type it's a winner.
+  ;;
+  ;; FIXME/TODO: add support for (eq 'cabal-repl (haskell-process-type))
+  (let ((session (haskell-session-maybe)))
+    (when session
+      (let ((modules (shell-command-to-string
+                      (format "%s 2> /dev/null | %s | %s"
+                              (cond
+                               ((haskell-sandbox-exists-p session)
+                                (concat "ghc-pkg dump -f "
+                                        (shell-quote-argument (haskell-sandbox-pkgdb session))))
+                               (t "ghc-pkg dump"))
+                              "egrep '^(exposed-modules: |                 )[A-Z]'"
+                              "cut -c18-"))))
+        (split-string modules)))))
+
+;;;###autoload
+(defun haskell-session-all-modules (session &optional dontcreate)
+  "Get all modules -- installed or in the current project.
+If DONTCREATE is non-nil don't create a new session."
+  (append (haskell-session-installed-modules session dontcreate)
+          (haskell-session-project-modules session dontcreate)))
+
+;;;###autoload
+(defun haskell-session-project-modules (session &optional dontcreate)
+  "Get the modules of the current project.
+If DONTCREATE is non-nil don't create a new session."
+  (if (or (not dontcreate) (haskell-session-maybe))
+      (let* ((modules
+              (shell-command-to-string
+               (format "%s && %s"
+                       (format "cd %s" (haskell-session-cabal-dir session))
+                       ;; TODO: Use a different, better source. Possibly hasktags or some such.
+                       ;; TODO: At least make it cross-platform. Linux
+                       ;; (and possibly OS X) have egrep, Windows
+                       ;; doesn't -- or does it via Cygwin or MinGW?
+                       ;; This also doesn't handle module\nName. But those gits can just cut it out!
+                       "egrep '^module[\t\r ]+[^(\t\r ]+' . -r -I --include='*.*hs' --include='*.hsc' -s -o -h | sed 's/^module[\t\r ]*//' | sort | uniq"))))
+        (split-string modules))))
+
+(defun haskell-modules-session ()
+  "Get the `haskell-session', throw an error if it's not
+  available."
+  (or (haskell-session-maybe)
+      (haskell-session-assign
+       (or (haskell-session-from-buffer)
+           (haskell-session-choose)
+           (error "No session associated with this buffer. Try M-x haskell-session-change or report this as a bug.")))))
+
+(provide 'haskell-modules)
diff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-modules.elc b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-modules.elc
new file mode 100644
index 0000000000..9290a413e0
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-modules.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-move-nested.el b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-move-nested.el
new file mode 100644
index 0000000000..1e4774de4f
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-move-nested.el
@@ -0,0 +1,130 @@
+;;; haskell-move-nested.el --- Change the column of text nested below a line -*- lexical-binding: t -*-
+
+;; Copyright (C) 2010  Chris Done
+
+;; Author: Chris Done <chrisdone@gmail.com>
+
+;; This file is not part of GNU Emacs.
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see
+;; <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This module is intended for Haskell mode users, but is
+;; independent of Haskell mode.
+
+;; Example usage:
+
+;; (define-key haskell-mode-map (kbd "C-,") 'haskell-move-nested-left)
+;; (define-key haskell-mode-map (kbd "C-.") 'haskell-move-nested-right)
+
+;;; Code:
+
+;;;###autoload
+(defun haskell-move-nested (cols)
+  "Shift the nested off-side-rule block adjacent to point by COLS columns to the right.
+
+In Transient Mark mode, if the mark is active, operate on the contents
+of the region instead.
+"
+  (save-excursion
+    (if (and transient-mark-mode mark-active)
+        (progn
+          (indent-rigidly (region-beginning) (region-end) cols)
+          (setq deactivate-mark nil))
+      (let ((region (haskell-move-nested-region)))
+        (when region
+          (indent-rigidly (car region) (cdr region) cols))))))
+
+;;;###autoload
+(defun haskell-move-nested-right (cols)
+  "Increase indentation of the following off-side-rule block adjacent to point.
+
+Use a numeric prefix argument to indicate amount of indentation to apply.
+
+In Transient Mark mode, if the mark is active, operate on the contents
+of the region instead."
+  (interactive "p")
+  (haskell-move-nested cols)
+  )
+
+;;;###autoload
+(defun haskell-move-nested-left (cols)
+  "Decrease indentation of the following off-side-rule block adjacent to point.
+
+Use a numeric prefix argument to indicate amount of indentation to apply.
+
+In Transient Mark mode, if the mark is active, operate on the contents
+of the region instead."
+  (interactive "p")
+  (haskell-move-nested (- cols))
+  )
+
+(defun haskell-move-nested-region ()
+  "Infer region off-side-rule block adjacent to point.
+Used by `haskell-move-nested'.
+"
+  (save-excursion
+    (let ((starting-level (current-column)))
+      (forward-line)
+      (let ((current-level (haskell-move-nested-indent-level)))
+        (let ((start-point (line-beginning-position))
+              (start-end-point (line-end-position))
+              (end-point nil)
+              (last-line 0))
+          (forward-line)
+          (while (and (not (= (line-beginning-position) last-line))
+                      (or (> (haskell-move-nested-indent-level) starting-level)
+                          (and (> current-level starting-level)
+                               (>= (haskell-move-nested-indent-level) current-level))))
+            (setq last-line (line-beginning-position))
+            (setq end-point (line-end-position))
+            (forward-line))
+          (cons start-point (or end-point
+                                start-end-point)))))))
+
+(defun haskell-move-nested-indent-level ()
+  (max
+   0
+   (1- (length
+        (buffer-substring-no-properties
+         (line-beginning-position)
+         (or (save-excursion (goto-char (line-beginning-position))
+                             (search-forward-regexp "[^ ]" (line-end-position) t 1))
+             (line-beginning-position)))))))
+
+(defun haskell-kill-nested ()
+  "Kill the nested region after point."
+  (interactive)
+  (let ((start (point))
+        (reg (save-excursion
+               (search-backward-regexp "^[ ]+" (line-beginning-position) t 1)
+               (search-forward-regexp "[^ ]" (line-end-position) t 1)
+               (haskell-move-nested-region))))
+    (kill-region start (cdr reg))))
+
+(defun haskell-delete-nested ()
+  "Kill the nested region after point."
+  (interactive)
+  (let ((start (point))
+        (reg (save-excursion
+               (search-backward-regexp "^[ ]+" (line-beginning-position) t 1)
+               (search-forward-regexp "[^ ]" (line-end-position) t 1)
+               (haskell-move-nested-region))))
+    (delete-region start (cdr reg))))
+
+(provide 'haskell-move-nested)
+
+;;; haskell-move-nested.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-move-nested.elc b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-move-nested.elc
new file mode 100644
index 0000000000..f4a3b68471
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-move-nested.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-navigate-imports.el b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-navigate-imports.el
new file mode 100644
index 0000000000..7600d23056
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-navigate-imports.el
@@ -0,0 +1,130 @@
+;;; haskell-navigate-imports.el --- A function for cycling through Haskell import lists -*- lexical-binding: t -*-
+
+;; Copyright (C) 2010  Chris Done
+
+;; Author: Chris Done <chrisdone@gmail.com>
+
+;; This file is not part of GNU Emacs.
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see
+;; <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; The cycling step will stop once at the last import list so
+;; that it is easy to add a new import list.
+
+;; This module works completely independently of any libraries
+;; (including haskell-mode).
+
+;; Exports three interactive functions:
+;; 1. haskell-navigate-imports
+;; 2. haskell-navigate-imports-go
+;; 3. haskell-navigate-imports-return
+
+;; Example usage:
+
+;; (require 'haskell-navigate-imports)
+;; (define-key haskell-mode-map (kbd "<f8>") 'haskell-navigate-imports)
+
+;;; Code:
+
+(defvar haskell-navigate-imports-start-point nil)
+
+(defvar haskell-literate) ; defined in haskell-mode.el
+
+;;;###autoload
+(defun haskell-navigate-imports (&optional return)
+  "Cycle the Haskell import lines or return to point (with prefix arg)."
+  (interactive "P")
+  (if return
+      (haskell-navigate-imports-return)
+    (haskell-navigate-imports-go)))
+
+;;;###autoload
+(defun haskell-navigate-imports-go ()
+  "Go to the first line of a list of consecutive import lines. Cycles."
+  (interactive)
+  (unless (or (haskell-navigate-imports-line)
+              (equal (line-beginning-position) (point-min))
+              (save-excursion (forward-line -1)
+                              (haskell-navigate-imports-line)))
+    (setq haskell-navigate-imports-start-point (point)))
+  (haskell-navigate-imports-go-internal))
+
+;;;###autoload
+(defun haskell-navigate-imports-return ()
+  "Return to the non-import point we were at before going to the module list.
+   If we were originally at an import list, we can just cycle through easily."
+  (interactive)
+  (when haskell-navigate-imports-start-point
+    (goto-char haskell-navigate-imports-start-point)))
+
+(defun haskell-navigate-imports-go-internal ()
+  "Go to the first line of a list of consecutive import lines. Cycle."
+  (if (haskell-navigate-imports-line)
+      (progn (haskell-navigate-imports-goto-end)
+             (when (haskell-navigate-imports-find-forward-line)
+               (haskell-navigate-imports-go-internal)))
+    (let ((point (haskell-navigate-imports-find-forward-line)))
+      (if point
+          (goto-char point)
+        (progn (goto-char (point-min))
+               (if (haskell-navigate-imports-find-forward-line)
+                   (haskell-navigate-imports-go-internal)
+                 (let ((module (if (eq haskell-literate 'bird)
+                                   "^> ?module"
+                                 "^module")))
+                   (when (search-forward-regexp module nil t 1)
+                     (search-forward "\n\n" nil t 1)))))))))
+
+(defun haskell-navigate-imports-goto-end ()
+  "Skip a bunch of consecutive import lines."
+  (while (not (or (equal (point)
+                         (point-max))
+                  (not (haskell-navigate-imports-line))))
+    (forward-line)))
+
+(defun haskell-navigate-imports-find-forward-line ()
+  "Return a point with at an import line, or nothing."
+  (save-excursion
+    (while (not (or (equal (point) (point-max))
+                    (haskell-navigate-imports-after-imports-p) ;; This one just speeds it up.
+                    (haskell-navigate-imports-line)))
+      (forward-line))
+    (if (haskell-navigate-imports-line)
+        (point)
+        nil)))
+
+(defun haskell-navigate-imports-line ()
+  "Try to match the current line as a regexp."
+  (let ((line (buffer-substring-no-properties (line-beginning-position)
+                                              (line-end-position)))
+        (import (if (eq haskell-literate 'bird)
+                    "^> ?import "
+                  "^import ")))
+    (if (string-match import line)
+        line
+      nil)))
+
+(defun haskell-navigate-imports-after-imports-p ()
+  "Are we after the imports list? Just for a speed boost."
+  (save-excursion
+    (goto-char (line-beginning-position))
+    (not (not (search-forward-regexp "\\( = \\|\\<instance\\>\\| :: \\)"
+                                     (line-end-position) t 1)))))
+
+(provide 'haskell-navigate-imports)
+
+;;; haskell-navigate-imports.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-navigate-imports.elc b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-navigate-imports.elc
new file mode 100644
index 0000000000..afcbdd270f
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-navigate-imports.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-presentation-mode.el b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-presentation-mode.el
new file mode 100644
index 0000000000..c1d3fad72e
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-presentation-mode.el
@@ -0,0 +1,104 @@
+;;; haskell-presentation-mode.el --- Presenting Haskell things -*- lexical-binding: t -*-
+
+;; Copyright (C) 2013  Chris Done
+
+;; Author: Chris Done <chrisdone@gmail.com>
+
+;; This file is not part of GNU Emacs.
+
+;; This file 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, or (at your option)
+;; any later version.
+
+;; This file 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; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;;; Code:
+
+(require 'haskell-mode)
+(require 'haskell-session)
+
+(defvar haskell-presentation-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "q") 'quit-window)
+    (define-key map (kbd "c") 'haskell-presentation-clear)
+    map)
+  "Keymap for `haskell-presentation-mode'.")
+
+(define-derived-mode haskell-presentation-mode
+  haskell-mode "Presentation"
+  "Major mode for viewing Haskell snippets.
+          \\{hypertext-mode-map}"
+  (setq case-fold-search nil))
+
+(defconst haskell-presentation-buffer-name
+  "*Haskell Presentation*"
+  "Haskell Presentation buffer name.")
+
+(defconst haskell-presentation-hint-message
+  "-- Hit `q' to close this window; `c' to clear.\n\n"
+  "Hint message appered in Haskell Presentation buffer.")
+
+(defun haskell-presentation-buffer ()
+  "Return Haskell Presentaion buffer.
+Return current presenation buffer or create new one if absent.
+Never returns nil."
+  ;; TODO Provide interactive calling options: when called interactively make
+  ;; the presentation buffer current.
+  (let ((may-buffer (get-buffer haskell-presentation-buffer-name)))
+    (if may-buffer
+        may-buffer
+      (let ((buffer (generate-new-buffer haskell-presentation-buffer-name)))
+        (with-current-buffer buffer
+          (insert haskell-presentation-hint-message)
+          (haskell-presentation-mode)
+          (setq buffer-read-only t))
+          buffer))))
+
+(defun haskell-presentation-clear ()
+  "Clear Haskell Presentation buffer."
+  (interactive)
+  (let ((hp-buf (get-buffer haskell-presentation-buffer-name)))
+    (when hp-buf
+      (with-current-buffer hp-buf
+        (let ((buffer-read-only nil))
+          (erase-buffer)
+          (insert haskell-presentation-hint-message))))))
+
+(defun haskell-presentation-present (session code &optional clear)
+  "Present given code in a popup buffer.
+Creates temporal Haskell Presentation buffer and assigns it to
+given haskell SESSION; presented CODE will be fontified as
+haskell code.  Give an optional non-nil CLEAR arg to clear the
+buffer before presenting message."
+  (let ((buffer (haskell-presentation-buffer)))
+    (with-current-buffer buffer
+
+      (when (boundp 'shm-display-quarantine)
+        (setq-local shm-display-quarantine nil))
+
+      (when clear (haskell-presentation-clear))
+      (haskell-session-assign session)
+      (goto-char (point-min))
+      (forward-line 2)
+      (save-excursion
+        (let ((buffer-read-only nil))
+          (insert code "\n\n"))))
+
+    (if (eq major-mode 'haskell-presentation-mode)
+        (switch-to-buffer buffer)
+      (pop-to-buffer buffer))))
+
+(provide 'haskell-presentation-mode)
+
+;;; haskell-presentation-mode.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-presentation-mode.elc b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-presentation-mode.elc
new file mode 100644
index 0000000000..7838ae6d3b
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-presentation-mode.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-process.el b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-process.el
new file mode 100644
index 0000000000..6e922c61cd
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-process.el
@@ -0,0 +1,510 @@
+;;; haskell-process.el --- Communicating with the inferior Haskell process -*- lexical-binding: t -*-
+
+;; Copyright (C) 2011  Chris Done
+
+;; Author: Chris Done <chrisdone@gmail.com>
+
+;; This file is not part of GNU Emacs.
+
+;; This file 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, or (at your option)
+;; any later version.
+
+;; This file 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; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'json)
+(require 'url-util)
+(require 'haskell-compat)
+(require 'haskell-session)
+(require 'haskell-customize)
+(require 'haskell-string)
+
+(defconst haskell-process-prompt-regex "\4"
+  "Used for delimiting command replies. 4 is End of Transmission.")
+
+(defvar haskell-reload-p nil
+  "Used internally for `haskell-process-loadish'.")
+
+(defconst haskell-process-greetings
+  (list "Hello, Haskell!"
+        "The lambdas must flow."
+        "Hours of hacking await!"
+        "The next big Haskell project is about to start!"
+        "Your wish is my IO ().")
+  "Greetings for when the Haskell process starts up.")
+
+(defconst haskell-process-logo
+  (expand-file-name "logo.svg" haskell-mode-pkg-base-dir)
+  "Haskell logo for notifications.")
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Accessing commands -- using cl 'defstruct'
+
+(cl-defstruct haskell-command
+  "Data structure representing a command to be executed when with
+  a custom state and three callback."
+  ;; hold the custom command state
+  ;; state :: a
+  state
+  ;; called when to execute a command
+  ;; go :: a -> ()
+  go
+  ;; called whenever output was collected from the haskell process
+  ;; live :: a -> Response -> Bool
+  live
+  ;; called when the output from the haskell process indicates that the command
+  ;; is complete
+  ;; complete :: a -> Response -> ()
+  complete)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Building the process
+
+(defun haskell-process-compute-process-log-and-command (session hptype)
+  "Compute the log and process to start command for the SESSION from the HPTYPE.
+Do not actually start any process.
+HPTYPE is the result of calling `'haskell-process-type`' function."
+  (let ((session-name (haskell-session-name session)))
+    (cl-ecase hptype
+      ('ghci
+       (append (list (format "Starting inferior GHCi process %s ..."
+                             haskell-process-path-ghci)
+                     session-name
+                     nil)
+               (apply haskell-process-wrapper-function
+                      (list
+                       (append (haskell-process-path-to-list haskell-process-path-ghci)
+                               haskell-process-args-ghci)))))
+      ('cabal-new-repl
+       (append (list (format "Starting inferior `cabal new-repl' process using %s ..."
+                             haskell-process-path-cabal)
+                     session-name
+                     nil)
+               (apply haskell-process-wrapper-function
+                      (list
+                       (append
+                        (haskell-process-path-to-list haskell-process-path-cabal)
+                        (list "new-repl")
+                        haskell-process-args-cabal-new-repl
+                        (let ((target (haskell-session-target session)))
+                          (if target (list target) nil)))))))
+      ('cabal-repl
+       (append (list (format "Starting inferior `cabal repl' process using %s ..."
+                             haskell-process-path-cabal)
+                     session-name
+                     nil)
+               (apply haskell-process-wrapper-function
+                      (list
+                       (append
+                        (haskell-process-path-to-list haskell-process-path-cabal)
+                        (list "repl")
+                        haskell-process-args-cabal-repl
+                        (let ((target (haskell-session-target session)))
+                          (if target (list target) nil)))))))
+      ('stack-ghci
+       (append (list (format "Starting inferior stack GHCi process using %s" haskell-process-path-stack)
+                     session-name
+                     nil)
+               (apply haskell-process-wrapper-function
+                      (list
+                       (append
+                        (haskell-process-path-to-list haskell-process-path-stack)
+                        (list "ghci")
+                        (let ((target (haskell-session-target session)))
+                          (if target (list target) nil))
+                        haskell-process-args-stack-ghci))))))))
+
+(defun haskell-process-path-to-list (path)
+  "Convert a path (which may be a string or a list) to a list."
+  (if (stringp path)
+      (list path)
+    path))
+
+(defun haskell-process-make (name)
+  "Make an inferior Haskell process."
+  (list (cons 'name name)))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Process communication
+
+(defun haskell-process-sentinel (proc event)
+  "The sentinel for the process pipe."
+  (let ((session (haskell-process-project-by-proc proc)))
+    (when session
+      (let* ((process (haskell-session-process session)))
+        (unless (haskell-process-restarting process)
+          (haskell-process-log
+           (propertize (format "Event: %S\n" event)
+                       'face '((:weight bold))))
+          (haskell-process-log
+           (propertize "Process reset.\n"
+                       'face 'font-lock-comment-face))
+          (run-hook-with-args 'haskell-process-ended-functions process))))))
+
+(defun haskell-process-filter (proc response)
+  "The filter for the process pipe."
+  (let ((i 0))
+    (cl-loop for line in (split-string response "\n")
+             do (haskell-process-log
+                 (concat (if (= i 0)
+                             (propertize "<- " 'face 'font-lock-comment-face)
+                           "   ")
+                         (propertize line 'face 'haskell-interactive-face-compile-warning)))
+             do (setq i (1+ i))))
+  (let ((session (haskell-process-project-by-proc proc)))
+    (when session
+      (if (haskell-process-cmd (haskell-session-process session))
+          (haskell-process-collect session
+                                   response
+                                   (haskell-session-process session))))))
+
+(defun haskell-process-log (msg)
+  "Effective append MSG to the process log (if enabled)."
+  (when haskell-process-log
+    (let* ((append-to (get-buffer-create "*haskell-process-log*")))
+      (with-current-buffer append-to
+        ;; point should follow insertion so that it stays at the end
+        ;; of the buffer
+        (setq-local window-point-insertion-type t)
+        (let ((buffer-read-only nil))
+          (insert msg "\n"))))))
+
+(defun haskell-process-project-by-proc (proc)
+  "Find project by process."
+  (cl-find-if (lambda (project)
+                (string= (haskell-session-name project)
+                         (process-name proc)))
+              haskell-sessions))
+
+(defun haskell-process-collect (_session response process)
+  "Collect input for the response until receives a prompt."
+  (haskell-process-set-response process
+                                (concat (haskell-process-response process) response))
+  (while (haskell-process-live-updates process))
+  (when (string-match haskell-process-prompt-regex
+                      (haskell-process-response process))
+    (haskell-command-exec-complete
+     (haskell-process-cmd process)
+     (replace-regexp-in-string
+      haskell-process-prompt-regex
+      ""
+      (haskell-process-response process)))
+    (haskell-process-reset process)
+    (haskell-process-trigger-queue process)))
+
+(defun haskell-process-reset (process)
+  "Reset the process's state, ready for the next send/reply."
+  (progn (haskell-process-set-response-cursor process 0)
+         (haskell-process-set-response process "")
+         (haskell-process-set-cmd process nil)))
+
+(defun haskell-process-consume (process regex)
+  "Consume a regex from the response and move the cursor along if succeed."
+  (when (string-match regex
+                      (haskell-process-response process)
+                      (haskell-process-response-cursor process))
+    (haskell-process-set-response-cursor process (match-end 0))
+    t))
+
+(defun haskell-process-send-string (process string)
+  "Try to send a string to the process's process. Ask to restart if it's not running."
+  (let ((child (haskell-process-process process)))
+    (if (equal 'run (process-status child))
+        (let ((out (concat string "\n")))
+          (let ((i 0))
+            (cl-loop for line in (split-string out "\n")
+                     do (unless (string-equal "" line)
+                          (haskell-process-log
+                           (concat (if (= i 0)
+                                       (propertize "-> " 'face 'font-lock-comment-face)
+                                     "   ")
+                                   (propertize line 'face 'font-lock-string-face))))
+                     do (setq i (1+ i))))
+          (process-send-string child out))
+      (unless (haskell-process-restarting process)
+        (run-hook-with-args 'haskell-process-ended-functions process)))))
+
+(defun haskell-process-live-updates (process)
+  "Process live updates."
+  (haskell-command-exec-live (haskell-process-cmd process)
+                             (haskell-process-response process)))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Making commands
+
+(defun haskell-process-queue-without-filters (process line)
+  "Queue LINE to be sent to PROCESS without bothering to look at
+the response."
+  (haskell-process-queue-command
+   process
+   (make-haskell-command
+    :state (cons process line)
+    :go (lambda (state)
+          (haskell-process-send-string (car state)
+                                       (cdr state))))))
+
+
+(defun haskell-process-queue-command (process command)
+  "Add a command to the process command queue."
+  (haskell-process-cmd-queue-add process command)
+  (haskell-process-trigger-queue process))
+
+(defun haskell-process-trigger-queue (process)
+  "Trigger the next command in the queue to be ran if there is no current command."
+  (if (and (haskell-process-process process)
+           (process-live-p (haskell-process-process process)))
+      (unless (haskell-process-cmd process)
+        (let ((cmd (haskell-process-cmd-queue-pop process)))
+          (when cmd
+            (haskell-process-set-cmd process cmd)
+            (haskell-command-exec-go cmd))))
+    (progn (haskell-process-reset process)
+           (haskell-process-set process 'command-queue nil)
+           (run-hook-with-args 'haskell-process-ended-functions process))))
+
+(defun haskell-process-queue-flushed-p (process)
+  "Return t if command queue has been completely processed."
+  (not (or (haskell-process-cmd-queue process)
+           (haskell-process-cmd process))))
+
+(defun haskell-process-queue-flush (process)
+  "Block till PROCESS' command queue has been completely processed.
+This uses `accept-process-output' internally."
+  (while (not (haskell-process-queue-flushed-p process))
+    (haskell-process-trigger-queue process)
+    (accept-process-output (haskell-process-process process) 1)))
+
+(defun haskell-process-queue-sync-request (process reqstr)
+  "Queue submitting REQSTR to PROCESS and return response blockingly."
+  (let ((cmd (make-haskell-command
+              :state (cons nil process)
+              :go `(lambda (s) (haskell-process-send-string (cdr s) ,reqstr))
+              :complete 'setcar)))
+    (haskell-process-queue-command process cmd)
+    (haskell-process-queue-flush process)
+    (car-safe (haskell-command-state cmd))))
+
+(defun haskell-process-get-repl-completions (process inputstr &optional limit)
+  "Query PROCESS with `:complete repl ...' for INPUTSTR.
+Give optional LIMIT arg to limit completion candidates count,
+zero, negative values, and nil means all possible completions.
+Returns NIL when no completions found."
+  (let* ((mlimit (if (and limit (> limit 0))
+                     (concat " " (number-to-string limit) " ")
+                   " "))
+         (reqstr (concat ":complete repl"
+                         mlimit
+                         (haskell-string-literal-encode inputstr)))
+         (rawstr (haskell-process-queue-sync-request process reqstr))
+         (response-status (haskell-utils-repl-response-error-status rawstr)))
+    (if (eq 'unknown-command response-status)
+        (error
+         "GHCi lacks `:complete' support (try installing GHC 7.8+ or ghci-ng)")
+      (when rawstr
+        ;; parse REPL response if any
+        (let* ((s1 (split-string rawstr "\r?\n" t))
+               (cs (mapcar #'haskell-string-literal-decode (cdr s1)))
+               (h0 (car s1))) ;; "<limit count> <all count> <unused string>"
+          (unless (string-match
+                   "\\`\\([0-9]+\\) \\([0-9]+\\) \\(\".*\"\\)\\'"
+                   h0)
+            (error "Invalid `:complete' response"))
+          (let ((cnt1 (match-string 1 h0))
+                (h1 (haskell-string-literal-decode (match-string 3 h0))))
+            (unless (= (string-to-number cnt1) (length cs))
+              (error "Lengths inconsistent in `:complete' reponse"))
+            (cons h1 cs)))))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Accessing the process
+
+(defun haskell-process-get (process key)
+  "Get the PROCESS's KEY value.
+Returns nil if KEY not set."
+  (cdr (assq key process)))
+
+(defun haskell-process-set (process key value)
+  "Set the PROCESS's KEY to VALUE.
+Returns newly set VALUE."
+  (if process
+      (let ((cell (assq key process)))
+        (if cell
+            (setcdr cell value)         ; modify cell in-place
+          (setcdr process (cons (cons key value) (cdr process))) ; new cell
+          value))
+    (display-warning 'haskell-interactive
+                     "`haskell-process-set' called with nil process")))
+
+;; Wrappers using haskell-process-{get,set}
+
+(defun haskell-process-set-sent-stdin (p v)
+  "We've sent stdin, so let's not clear the output at the end."
+  (haskell-process-set p 'sent-stdin v))
+
+(defun haskell-process-sent-stdin-p (p)
+  "Did we send any stdin to the process during evaluation?"
+  (haskell-process-get p 'sent-stdin))
+
+(defun haskell-process-set-suggested-imports (p v)
+  "Remember what imports have been suggested, to avoid
+re-asking about the same imports."
+  (haskell-process-set p 'suggested-imported v))
+
+(defun haskell-process-suggested-imports (p)
+  "Get what modules have already been suggested and accepted."
+  (haskell-process-get p 'suggested-imported))
+
+(defun haskell-process-set-evaluating (p v)
+  "Set status of evaluating to be on/off."
+  (haskell-process-set p 'evaluating v))
+
+(defun haskell-process-evaluating-p (p)
+  "Get status of evaluating (on/off)."
+  (haskell-process-get p 'evaluating))
+
+(defun haskell-process-set-process (p v)
+  "Set the process's inferior process."
+  (haskell-process-set p 'inferior-process v))
+
+(defun haskell-process-process (p)
+  "Get the process child."
+  (haskell-process-get p 'inferior-process))
+
+(defun haskell-process-name (p)
+  "Get the process name."
+  (haskell-process-get p 'name))
+
+(defun haskell-process-cmd (p)
+  "Get the process's current command.
+Return nil if no current command."
+  (haskell-process-get p 'current-command))
+
+(defun haskell-process-set-cmd (p v)
+  "Set the process's current command."
+  (haskell-process-set-evaluating p nil)
+  (haskell-process-set-sent-stdin p nil)
+  (haskell-process-set-suggested-imports p nil)
+  (haskell-process-set p 'current-command v))
+
+(defun haskell-process-response (p)
+  "Get the process's current response."
+  (haskell-process-get p 'current-response))
+
+(defun haskell-process-session (p)
+  "Get the process's current session."
+  (haskell-process-get p 'session))
+
+(defun haskell-process-set-response (p v)
+  "Set the process's current response."
+  (haskell-process-set p 'current-response v))
+
+(defun haskell-process-set-session (p v)
+  "Set the process's current session."
+  (haskell-process-set p 'session v))
+
+(defun haskell-process-response-cursor (p)
+  "Get the process's current response cursor."
+  (haskell-process-get p 'current-response-cursor))
+
+(defun haskell-process-set-response-cursor (p v)
+  "Set the process's response cursor."
+  (haskell-process-set p 'current-response-cursor v))
+
+;; low-level command queue operations
+
+(defun haskell-process-restarting (process)
+  "Is the PROCESS restarting?"
+  (haskell-process-get process 'is-restarting))
+
+(defun haskell-process-cmd-queue (process)
+  "Get the PROCESS' command queue.
+New entries get added to the end of the list. Use
+`haskell-process-cmd-queue-add' and
+`haskell-process-cmd-queue-pop' to modify the command queue."
+  (haskell-process-get process 'command-queue))
+
+(defun haskell-process-cmd-queue-add (process cmd)
+  "Add CMD to end of PROCESS's command queue."
+  (cl-check-type cmd haskell-command)
+  (haskell-process-set process
+                       'command-queue
+                       (append (haskell-process-cmd-queue process)
+                               (list cmd))))
+
+(defun haskell-process-cmd-queue-pop (process)
+  "Pop the PROCESS' next entry from command queue.
+Returns nil if queue is empty."
+  (let ((queue (haskell-process-cmd-queue process)))
+    (when queue
+      (haskell-process-set process 'command-queue (cdr queue))
+      (car queue))))
+
+
+(defun haskell-process-unignore-file (session file)
+  "
+
+Note to Windows Emacs hackers:
+
+chmod is how to change the mode of files in POSIX
+systems. This will not work on your operating
+system.
+
+There is a command a bit like chmod called \"Calcs\"
+that you can try using here:
+
+http://technet.microsoft.com/en-us/library/bb490872.aspx
+
+If it works, you can submit a patch to this
+function and remove this comment.
+"
+  (shell-command (read-from-minibuffer "Permissions command: "
+                                       (concat "chmod 700 "
+                                               file)))
+  (haskell-session-modify
+   session
+   'ignored-files
+   (lambda (files)
+     (cl-remove-if (lambda (path)
+                     (string= path file))
+                   files))))
+
+(defun haskell-command-exec-go (command)
+  "Call the command's go function."
+  (let ((go-func (haskell-command-go command)))
+    (when go-func
+      (funcall go-func (haskell-command-state command)))))
+
+(defun haskell-command-exec-complete (command response)
+  "Call the command's complete function."
+  (let ((comp-func (haskell-command-complete command)))
+    (when comp-func
+      (condition-case-unless-debug e
+          (funcall comp-func
+                   (haskell-command-state command)
+                   response)
+        (quit (message "Quit"))
+        (error (message "Haskell process command errored with: %S" e))))))
+
+(defun haskell-command-exec-live (command response)
+  "Trigger the command's live updates callback."
+  (let ((live-func (haskell-command-live command)))
+    (when live-func
+      (funcall live-func
+               (haskell-command-state command)
+               response))))
+
+(provide 'haskell-process)
+
+;;; haskell-process.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-process.elc b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-process.elc
new file mode 100644
index 0000000000..69bfb8a377
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-process.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-repl.el b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-repl.el
new file mode 100644
index 0000000000..fe811ee1dd
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-repl.el
@@ -0,0 +1,124 @@
+;;; haskell-repl.el --- REPL evaluation -*- lexical-binding: t -*-
+
+;; Copyright (c) 2014 Chris Done. All rights reserved.
+
+;; This file 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, or (at your option)
+;; any later version.
+
+;; This file 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'haskell-interactive-mode)
+(require 'haskell-collapse)
+
+(defun haskell-interactive-handle-expr ()
+  "Handle an inputted expression at the REPL."
+  (let ((expr (haskell-interactive-mode-input)))
+    (if (string= "" (replace-regexp-in-string " " "" expr))
+        ;; Just make a new prompt on space-only input
+        (progn
+          (goto-char (point-max))
+          (insert "\n")
+          (haskell-interactive-mode-prompt))
+      (when (haskell-interactive-at-prompt)
+        (cond
+         ;; If already evaluating, then the user is trying to send
+         ;; input to the REPL during evaluation. Most likely in
+         ;; response to a getLine-like function.
+         ((and (haskell-process-evaluating-p (haskell-interactive-process))
+               (= (line-end-position) (point-max)))
+          (goto-char (point-max))
+          (let ((process (haskell-interactive-process))
+                (string (buffer-substring-no-properties
+                         haskell-interactive-mode-result-end
+                         (point))))
+            ;; here we need to go to end of line again as evil-mode
+            ;; might have managed to put us one char back
+            (goto-char (point-max))
+            (insert "\n")
+            ;; Bring the marker forward
+            (setq haskell-interactive-mode-result-end
+                  (point-max))
+            (haskell-process-set-sent-stdin process t)
+            (haskell-process-send-string process string)))
+         ;; Otherwise we start a normal evaluation call.
+         (t (setq haskell-interactive-mode-old-prompt-start
+                  (copy-marker haskell-interactive-mode-prompt-start))
+            (set-marker haskell-interactive-mode-prompt-start (point-max))
+            (haskell-interactive-mode-history-add expr)
+            (haskell-interactive-mode-do-expr expr)))))))
+
+(defun haskell-interactive-mode-do-expr (expr)
+  (cond
+   ((string-match "^:present " expr)
+    (haskell-interactive-mode-do-presentation (replace-regexp-in-string "^:present " "" expr)))
+   (t
+    (haskell-interactive-mode-run-expr expr))))
+
+(defun haskell-interactive-mode-run-expr (expr)
+  "Run the given expression."
+  (let ((session (haskell-interactive-session))
+        (process (haskell-interactive-process)))
+    (haskell-process-queue-command
+     process
+     (make-haskell-command
+      :state (list session process expr 0)
+      :go (lambda (state)
+            (goto-char (point-max))
+            (insert "\n")
+            (setq haskell-interactive-mode-result-end
+                  (point-max))
+            (haskell-process-send-string (cadr state)
+                                         (haskell-interactive-mode-multi-line (cl-caddr state)))
+            (haskell-process-set-evaluating (cadr state) t))
+      :live (lambda (state buffer)
+              (unless (and (string-prefix-p ":q" (cl-caddr state))
+                           (string-prefix-p (cl-caddr state) ":quit"))
+                (let* ((cursor (cl-cadddr state))
+                       (next (replace-regexp-in-string
+                              haskell-process-prompt-regex
+                              ""
+                              (substring buffer cursor))))
+                  (haskell-interactive-mode-eval-result (car state) next)
+                  (setf (cl-cdddr state) (list (length buffer)))
+                  nil)))
+      :complete
+      (lambda (state response)
+        (haskell-process-set-evaluating (cadr state) nil)
+        (unless (haskell-interactive-mode-trigger-compile-error state response)
+          (haskell-interactive-mode-expr-result state response)))))))
+
+(defun haskell-interactive-mode-expr-result (state response)
+  "Print the result of evaluating the expression."
+  (let ((response
+         (with-temp-buffer
+           (insert response)
+           (haskell-interactive-mode-handle-h)
+           (buffer-string))))
+    (when haskell-interactive-mode-eval-mode
+      (unless (haskell-process-sent-stdin-p (cadr state))
+        (haskell-interactive-mode-eval-as-mode (car state) response))))
+  (haskell-interactive-mode-prompt (car state)))
+
+(defun haskell-interactive-mode-eval-as-mode (session text)
+  "Insert TEXT font-locked according to `haskell-interactive-mode-eval-mode'."
+  (with-current-buffer (haskell-session-interactive-buffer session)
+    (let ((inhibit-read-only t))
+      (delete-region (1+ haskell-interactive-mode-prompt-start) (point))
+      (goto-char (point-max))
+      (insert (haskell-fontify-as-mode text
+                                       haskell-interactive-mode-eval-mode))
+      (when haskell-interactive-mode-collapse
+        (haskell-hide-toggle)))))
+
+(provide 'haskell-repl)
diff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-repl.elc b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-repl.elc
new file mode 100644
index 0000000000..c7d5f85c65
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-repl.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-sandbox.el b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-sandbox.el
new file mode 100644
index 0000000000..ba605fd66c
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-sandbox.el
@@ -0,0 +1,41 @@
+;;; haskell-sandbox.el --- Support for sandboxes -*- lexical-binding: t -*-
+
+;; Copyright (c) 2014 Chris Done. All rights reserved.
+
+;; This file 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, or (at your option)
+;; any later version.
+
+;; This file 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'haskell-session)
+
+(defun haskell-sandbox-path (session)
+  "If there is a haskell-session, return the path to the usual sandbox location."
+  (concat (haskell-session-cabal-dir session)
+          "/.cabal-sandbox"))
+
+(defun haskell-sandbox-exists-p (session)
+  "Is there a cabal sandbox?"
+  (file-exists-p (haskell-sandbox-path session)))
+
+(defun haskell-sandbox-pkgdb (session)
+  "Get the package database of the sandbox."
+  (let* ((files (directory-files (haskell-sandbox-path session)))
+         (dir (car (cl-remove-if-not (lambda (file)
+                                        (string-match ".conf.d$" file))
+                                      files))))
+    (when dir
+      (concat (haskell-sandbox-path session) "/" dir))))
+
+(provide 'haskell-sandbox)
diff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-sandbox.elc b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-sandbox.elc
new file mode 100644
index 0000000000..3fb5781eaf
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-sandbox.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-session.el b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-session.el
new file mode 100644
index 0000000000..2c5344d13f
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-session.el
@@ -0,0 +1,227 @@
+;;; haskell-session.el --- Haskell sessions -*- lexical-binding: t -*-
+
+;; Copyright (C) 2011-2012  Chris Done
+
+;; Author: Chris Done <chrisdone@gmail.com>
+
+;; This file is not part of GNU Emacs.
+
+;; This file 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, or (at your option)
+;; any later version.
+
+;; This file 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; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;;; Todo:
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'haskell-cabal)
+(require 'haskell-customize)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Globals
+
+;; Used internally
+(defvar-local haskell-session nil)
+
+(defvar haskell-sessions (list)
+  "All Haskell sessions in the Emacs session.")
+
+(defun haskell-session-tags-filename (session)
+  "Get the filename for the TAGS file."
+  (concat (haskell-session-cabal-dir session) "/TAGS"))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Finding/clearing the session
+
+;;;###autoload
+(defun haskell-session-maybe ()
+  "Maybe get the Haskell session, return nil if there isn't one."
+  (if (default-boundp 'haskell-session)
+      haskell-session
+    (setq haskell-session nil)))
+
+(defun haskell-session-from-buffer ()
+  "Get the session based on the buffer."
+  (when (and (buffer-file-name)
+             (consp haskell-sessions))
+    (cl-reduce (lambda (acc a)
+                 (let ((dir (haskell-session-get a 'cabal-dir)))
+                   (if dir
+                       (if (string-prefix-p dir
+                                            (file-name-directory (buffer-file-name)))
+                           (if acc
+                               (if (and
+                                    (> (length (haskell-session-get a 'cabal-dir))
+                                       (length (haskell-session-get acc 'cabal-dir))))
+                                   a
+                                 acc)
+                             a)
+                         acc)
+                     acc)))
+               haskell-sessions
+               :initial-value nil)))
+
+(defun haskell-session-default-name ()
+  "Generate a default project name for the new project prompt."
+  (let ((file (haskell-cabal-find-file)))
+    (or (when file
+          (downcase (file-name-sans-extension
+                     (file-name-nondirectory file))))
+        "haskell")))
+
+(defun haskell-session-assign (session)
+  "Assing current buffer to SESSION.
+
+This could be helpful for temporary or auxiliary buffers such as
+presentation mode buffers (e.g. in case when session is killed
+with all relevant buffers)."
+  (setq-local haskell-session session))
+
+(defun haskell-session-choose ()
+  "Find a session by choosing from a list of the current sessions."
+  (when haskell-sessions
+    (let* ((session-name (funcall haskell-completing-read-function
+                                  "Choose Haskell session: "
+                                  (cl-remove-if (lambda (name)
+                                                  (and haskell-session
+                                                       (string= (haskell-session-name haskell-session)
+                                                                name)))
+                                                (mapcar 'haskell-session-name haskell-sessions))))
+           (session (cl-find-if (lambda (session)
+                                  (string= (haskell-session-name session)
+                                           session-name))
+                                haskell-sessions)))
+      session)))
+
+(defun haskell-session-clear ()
+  "Clear the buffer of any Haskell session choice."
+  (setq-local haskell-session nil))
+
+(defun haskell-session-lookup (name)
+  "Get the session by name."
+  (cl-remove-if-not (lambda (s)
+                      (string= name (haskell-session-name s)))
+                    haskell-sessions))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Session modules
+
+(defun haskell-session-strip-dir (session file)
+  "Strip the load dir from the file path."
+  (let ((cur-dir (haskell-session-current-dir session)))
+    (if (> (length file) (length cur-dir))
+        (if (string= (substring file 0 (length cur-dir))
+                     cur-dir)
+            (replace-regexp-in-string
+             "^[/\\]" ""
+             (substring file
+                        (length cur-dir)))
+          file)
+      file)))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Accessing the session
+
+(defun haskell-session-current-dir (s)
+  "Get the session current directory."
+  (let ((dir (haskell-session-get s 'current-dir)))
+    (or dir
+        (error "No current directory."))))
+
+(defun haskell-session-name (s)
+  "Get the session name."
+  (haskell-session-get s 'name))
+
+(defun haskell-session-target (s)
+  "Get the session build target.
+If `haskell-process-load-or-reload-prompt' is nil, accept `default'."
+  (let* ((maybe-target (haskell-session-get s 'target))
+         (target (if maybe-target maybe-target
+                   (let ((new-target
+                          (if haskell-process-load-or-reload-prompt
+                              (read-string "build target (empty for default):")
+                            "")))
+                     (haskell-session-set-target s new-target)))))
+    (if (not (string= target "")) target nil)))
+
+(defun haskell-session-set-target (s target)
+  "Set the session build target."
+  (haskell-session-set s 'target target))
+
+(defun haskell-session-set-interactive-buffer (s v)
+  "Set the session interactive buffer."
+  (haskell-session-set s 'interactive-buffer v))
+
+(defun haskell-session-set-process (s v)
+  "Set the session process."
+  (haskell-session-set s 'process v))
+
+;;;###autoload
+(defun haskell-session-process (s)
+  "Get the session process."
+  (haskell-session-get s 'process))
+
+(defun haskell-session-set-cabal-dir (s v)
+  "Set the session cabal-dir."
+  (let ((true-path (file-truename v)))
+    (haskell-session-set s 'cabal-dir true-path)
+    (haskell-session-set-cabal-checksum s true-path)))
+
+(defun haskell-session-set-current-dir (s v)
+  "Set the session current directory."
+  (let ((true-path (file-truename v)))
+    (haskell-session-set s 'current-dir true-path)))
+
+(defun haskell-session-set-cabal-checksum (s cabal-dir)
+  "Set the session checksum of .cabal files"
+  (haskell-session-set s 'cabal-checksum
+                       (haskell-cabal-compute-checksum cabal-dir)))
+
+(defun haskell-session-cabal-dir (s)
+  "Get the session cabal-dir."
+  (or (haskell-session-get s 'cabal-dir)
+      (let ((set-dir (haskell-cabal-get-dir (not haskell-process-load-or-reload-prompt))))
+        (if set-dir
+            (progn (haskell-session-set-cabal-dir s set-dir)
+                   set-dir)
+            (haskell-session-cabal-dir s)))))
+
+(defun haskell-session-modify (session key update)
+  "Update the value at KEY in SESSION with UPDATE."
+  (haskell-session-set
+   session
+   key
+   (funcall update
+            (haskell-session-get session key))))
+
+(defun haskell-session-get (session key)
+  "Get the SESSION's KEY value.
+Returns nil if KEY not set."
+  (cdr (assq key session)))
+
+(defun haskell-session-set (session key value)
+  "Set the SESSION's KEY to VALUE.
+Returns newly set VALUE."
+  (let ((cell (assq key session)))
+    (if cell
+        (setcdr cell value) ; modify cell in-place
+      (setcdr session (cons (cons key value) (cdr session))) ; new cell
+      value)))
+
+(provide 'haskell-session)
+
+;;; haskell-session.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-session.elc b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-session.elc
new file mode 100644
index 0000000000..70767fe3cf
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-session.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-sort-imports.el b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-sort-imports.el
new file mode 100644
index 0000000000..bd676dc73e
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-sort-imports.el
@@ -0,0 +1,129 @@
+;;; haskell-sort-imports.el --- Sort the list of Haskell imports at the point alphabetically -*- lexical-binding: t -*-
+
+;; Copyright (C) 2010  Chris Done
+
+;; Author: Chris Done <chrisdone@gmail.com>
+
+;; This file is not part of GNU Emacs.
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see
+;; <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; If the region is active it sorts the imports within the
+;; region.
+
+;; This will align and sort the columns of the current import
+;; list.  It's more or less the coolest thing on the planet.
+
+;;; Code:
+
+(require 'cl-lib)
+
+(defvar haskell-sort-imports-regexp
+  (concat "^import[ ]+"
+          "\\(qualified \\)?"
+          "[ ]*\\(\"[^\"]*\" \\)?"
+          "[ ]*\\([A-Za-z0-9_.']*.*\\)"))
+
+;;;###autoload
+(defun haskell-sort-imports ()
+  "Sort the import list at point. It sorts the current group
+i.e. an import list separated by blank lines on either side.
+
+If the region is active, it will restrict the imports to sort
+within that region."
+  (interactive)
+  (when (haskell-sort-imports-at-import)
+    (let* ((points (haskell-sort-imports-decl-points))
+           (current-string (buffer-substring-no-properties (car points)
+                                                           (cdr points)))
+           (current-offset (- (point) (car points))))
+      (if (region-active-p)
+          (progn (goto-char (region-beginning))
+                 (haskell-sort-imports-goto-import-start))
+        (haskell-sort-imports-goto-group-start))
+      (let* ((start (point))
+             (imports (haskell-sort-imports-collect-imports))
+             (sorted (sort (cl-copy-list imports)
+                           (lambda (a b)
+                             (string< (haskell-sort-imports-normalize a)
+                                      (haskell-sort-imports-normalize b))))))
+        (when (not (equal imports sorted))
+          (delete-region start (point))
+          (mapc (lambda (import) (insert import "\n")) sorted))
+        (goto-char start)
+        (when (search-forward current-string nil t 1)
+          (forward-char (- (length current-string)))
+          (forward-char current-offset))))))
+
+(defun haskell-sort-imports-normalize (i)
+  "Normalize an import, if possible, so that it can be sorted."
+  (if (string-match haskell-sort-imports-regexp
+                    i)
+      (match-string 3 i)
+    i))
+
+(defun haskell-sort-imports-collect-imports ()
+  (let ((imports (list)))
+    (while (looking-at "import")
+      (let* ((points (haskell-sort-imports-decl-points))
+             (string (buffer-substring-no-properties (car points)
+                                                     (cdr points))))
+        (goto-char (min (1+ (cdr points))
+                        (point-max)))
+        (setq imports (cons string imports))))
+    (reverse (delq nil (delete-dups imports)))))
+
+(defun haskell-sort-imports-goto-group-start ()
+  "Go to the start of the import group."
+  (or (and (search-backward "\n\n" nil t 1)
+           (goto-char (+ 2 (line-end-position))))
+      (when (search-backward-regexp "^module " nil t 1)
+        (goto-char (1+ (line-end-position))))
+      (goto-char (point-min))))
+
+(defun haskell-sort-imports-at-import ()
+  "Are we at an import?"
+  (save-excursion
+    (haskell-sort-imports-goto-import-start)
+    (looking-at "import")))
+
+(defun haskell-sort-imports-goto-import-start ()
+  "Go to the start of the import."
+  (goto-char (car (haskell-sort-imports-decl-points))))
+
+(defun haskell-sort-imports-decl-points ()
+  "Get the points of the declaration."
+  (save-excursion
+    (let ((start (or (progn (goto-char (line-end-position))
+                            (search-backward-regexp "^[^ \n]" nil t 1)
+                            (unless (or (looking-at "^-}$")
+                                        (looking-at "^{-$"))
+                              (point)))
+                     0))
+          (end (progn (goto-char (1+ (point)))
+                      (or (when (search-forward-regexp "[\n]+[^ \n]" nil t 1)
+                            (forward-char -1)
+                            (search-backward-regexp "[^\n ]" nil t)
+                            (line-end-position))
+                          (when (search-forward-regexp "\n" nil t 1)
+                            (1- (point)))
+                          (point-max)))))
+      (cons start end))))
+
+(provide 'haskell-sort-imports)
+
+;;; haskell-sort-imports.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-sort-imports.elc b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-sort-imports.elc
new file mode 100644
index 0000000000..1b5fe2e253
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-sort-imports.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-string.el b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-string.el
new file mode 100644
index 0000000000..1427aa3199
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-string.el
@@ -0,0 +1,219 @@
+;;; haskell-string.el --- Haskell related string utilities -*- lexical-binding: t -*-
+
+;; Copyright (C) 2013  Herbert Valerio Riedel
+
+;; Author: Herbert Valerio Riedel <hvr@gnu.org>
+
+;; This file is not part of GNU Emacs.
+
+;; This file 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.
+
+;; This file 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;; Todo:
+
+;; - write ERT tests
+
+;;; Code:
+
+(require 'cl-lib)
+
+(defun haskell-string-trim (string)
+  "Remove whitespace around STRING.
+
+A Whitespace character is defined in the Haskell Report as follows
+
+  whitechar -> newline | vertab | space | tab | uniWhite
+  newline   -> return linefeed | return | linefeed | formfeed
+  uniWhite  -> any Unicode character defined as whitespace
+
+Note: The implementation currently only supports ASCII
+      white-space characters, i.e. the implemention doesn't
+      consider uniWhite."
+
+  (let ((s1 (if (string-match "[\t\n\v\f\r ]+\\'" string) (replace-match "" t t string) string)))
+    (if (string-match "\\`[\t\n\v\f\r ]+" s1) (replace-match "" t t s1) s1)))
+
+(defun haskell-string-only-spaces-p (string)
+  "Return t if STRING contains only whitespace (or is empty)."
+  (string= "" (haskell-string-trim string)))
+
+(defun haskell-string-take (string n)
+  "Return (up to) N character length prefix of STRING."
+  (substring string 0 (min (length string) n)))
+
+(defconst haskell-string-literal-encode-ascii-array
+  [ "\\NUL" "\\SOH" "\\STX" "\\ETX" "\\EOT" "\\ENQ" "\\ACK" "\\a" "\\b" "\\t" "\\n" "\\v" "\\f" "\\r" "\\SO" "\\SI" "\\DLE" "\\DC1" "\\DC2" "\\DC3" "\\DC4" "\\NAK" "\\SYN" "\\ETB" "\\CAN" "\\EM" "\\SUB" "\\ESC" "\\FS" "\\GS" "\\RS" "\\US" " " "!" "\\\"" "#" "$" "%" "&" "'" "(" ")" "*" "+" "," "-" "." "/" "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" ":" ";" "<" "=" ">" "?" "@" "A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K" "L" "M" "N" "O" "P" "Q" "R" "S" "T" "U" "V" "W" "X" "Y" "Z" "[" "\\\\" "]" "^" "_" "`" "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q" "r" "s" "t" "u" "v" "w" "x" "y" "z" "{" "|" "}" "~" "\\DEL" ]
+  "Array of encodings for 7-bit ASCII character points indexed by ASCII value.")
+
+(defun haskell-string-literal-encode (str &optional no-quotes)
+  "Encode STR according Haskell escape rules using 7-bit ASCII representation.
+
+The serialization has been implemented to closely match the
+behaviour of GHC's Show instance for Strings.
+
+If NO-QUOTES is non-nil, omit wrapping result in quotes.
+
+This is the dual operation to `haskell-string-literal-decode'."
+
+  (let ((lastc -1))
+    (let ((encode (lambda (c)
+                    (let ((lc lastc))
+                      (setq lastc c)
+                      (if (>= c 128) ;; if non-ASCII code point
+                          (format "\\%d" c)
+                        ;; else, for ASCII code points
+                        (if (or (and (= lc 14) (= c ?H)) ;; "\SO\&H"
+                                (and (>= lc 128) (>= c ?0) (<= c ?9))) ;; "\123\&4"
+                            (concat "\\&" (aref haskell-string-literal-encode-ascii-array c))
+                          (aref haskell-string-literal-encode-ascii-array c)
+                          ))))))
+
+      (if no-quotes
+          (mapconcat encode str "")
+        (concat "\"" (mapconcat encode str "") "\"")))))
+
+(defconst haskell-string-literal-escapes-regexp
+  (concat "[\\]\\(?:"
+          (regexp-opt (append
+                       (mapcar (lambda (c) (format "%c" c))
+                               "abfnrtv\\\"'&") ;; "charesc" escape sequences
+                       (mapcar (lambda (c) (format "^%c" c))
+                               "ABCDEFGHIJKLMNOPQRSTUVWXYZ@[\\]^_") ;; "cntrl" escape sequences
+                       (mapcar (lambda (s) (format "%s" s))
+                               (split-string "NUL SOH STX ETX EOT ENQ ACK BEL BS HT LF VT FF CR
+                                              SO SI DLE DC1 DC2 DC3 DC4 NAK SYN ETB CAN EM SUB ESC
+                                              FS GS RS US SP DEL")))) ;; "ascii" (w\o "cntrl") escape sequences
+          "\\|" "[\t\n\v\f\r ]+[\\]"  ;; whitespace gaps
+          "\\|" "[0-9]+"              ;; decimal escape sequence
+          "\\|" "o[0-7]+"             ;; octal escape sequence
+          "\\|" "x[0-9a-f]+"          ;; hex escape sequence
+          "\\)?") ;; everything else is an invalid escape sequence
+  "Regexp for matching escape codes in string literals.
+See Haskell Report Sect 2.6,
+URL `http://www.haskell.org/onlinereport/haskell2010/haskellch2.html#x7-200002.6',
+for more details.")
+
+(defconst haskell-string-literal-decode1-table
+  (let ((h (make-hash-table :test 'equal)))
+    (mapc (lambda (c) (puthash (concat "\\" (car c)) (cdr c) h))
+          '(;; ascii-escapes
+            ("NUL" . "\x00") ("SOH" . "\x01") ("STX" . "\x02") ("ETX" . "\x03") ("EOT" . "\x04") ("ENQ" . "\x05")
+            ("ACK" . "\x06") ("BEL" . "\x07") ("BS"  . "\x08") ("HT"  . "\x09") ("LF"  . "\x0a") ("VT"  . "\x0b")
+            ("FF"  . "\x0c") ("CR"  . "\x0d") ("SO"  . "\x0e") ("SI"  . "\x0f") ("DLE" . "\x10") ("DC1" . "\x11")
+            ("DC2" . "\x12") ("DC3" . "\x13") ("DC4" . "\x14") ("NAK" . "\x15") ("SYN" . "\x16") ("ETB" . "\x17")
+            ("CAN" . "\x18") ("EM"  . "\x19") ("SUB" . "\x1a") ("ESC" . "\x1b") ("FS"  . "\x1c") ("GS"  . "\x1d")
+            ("RS"  . "\x1e") ("US"  . "\x1f") ("SP"  . "\x20")                                   ("DEL" . "\x7f" )
+            ;; C-compatible single-char escape sequences
+            ("a" . "\x07") ("b" . "\x08") ("f" . "\x0c") ("n" . "\x0a") ("r" . "\x0d") ("t" . "\x09") ("v" . "\x0b")
+            ;; trivial escapes
+            ("\\" . "\\") ("\"" . "\"") ("'" . "'")
+            ;; "empty" escape
+            ("&" . "")))
+    h)
+  "Hash table containing irregular escape sequences and their decoded strings.
+Used by `haskell-string-literal-decode1'.")
+
+(defun haskell-string-literal-decode1 (l)
+  "Decode a single string literal escape sequence.
+L must contain exactly one escape sequence.
+This is an internal function used by `haskell-string-literal-decode'."
+  (let ((case-fold-search nil))
+    (cond
+     ((gethash l haskell-string-literal-decode1-table))
+     ((string-match "\\`[\\][0-9]+\\'" l)         (char-to-string (string-to-number (substring l 1) 10)))
+     ((string-match "\\`[\\]x[[:xdigit:]]+\\'" l) (char-to-string (string-to-number (substring l 2) 16)))
+     ((string-match "\\`[\\]o[0-7]+\\'" l)        (char-to-string (string-to-number (substring l 2) 8)))
+     ((string-match "\\`[\\]\\^[@-_]\\'" l)       (char-to-string (- (aref l 2) ?@))) ;; "cntrl" escapes
+     ((string-match "\\`[\\][\t\n\v\f\r ]+[\\]\\'" l) "") ;; whitespace gap
+     (t (error "Invalid escape sequence")))))
+
+(defun haskell-string-literal-decode (estr &optional no-quotes)
+  "Decode a Haskell string-literal.
+If NO-QUOTES is nil, ESTR must be surrounded by quotes.
+
+This is the dual operation to `haskell-string-literal-encode'."
+  (if (and (not no-quotes)
+           (string-match-p "\\`\"[^\\\"[:cntrl:]]*\"\\'" estr))
+      (substring estr 1 -1) ;; optimized fast-path for trivial strings
+    (let ((s (if no-quotes ;; else: do general decoding
+                 estr
+               (if (string-match-p "\\`\".*\"\\'" estr)
+                   (substring estr 1 -1)
+                 (error "String literal must be delimited by quotes"))))
+          (case-fold-search nil))
+      (replace-regexp-in-string haskell-string-literal-escapes-regexp #'haskell-string-literal-decode1 s t t))))
+
+(defun haskell-string-ellipsize (string n)
+  "Return STRING truncated to (at most) N characters.
+If truncation occured, last character in string is replaced by `…'.
+See also `haskell-string-take'."
+  (cond
+   ((<= (length string) n) string) ;; no truncation needed
+   ((< n 1) "")
+   (t (concat (substring string 0 (1- n)) "…"))))
+
+(defun haskell-string-chomp (str)
+  "Chomp leading and tailing whitespace from STR."
+  (while (string-match "\\`\n+\\|^\\s-+\\|\\s-+$\\|\n+\\'"
+                       str)
+    (setq str (replace-match "" t t str)))
+  str)
+
+(defun haskell-string-split-to-lines (str)
+  "Split STR to lines and return a list of strings with preceeding and
+succeding space removed."
+  (when (stringp str)
+    (cl-mapcar #'haskell-string-chomp (split-string str "\n"))))
+
+(defun haskell-string-trim-prefix (prefix str)
+  "If PREFIX is prefix of STR, the string is trimmed."
+  (when (and (stringp prefix)
+             (stringp str))
+    (if (string-prefix-p prefix str)
+        (substring str (length prefix)))))
+
+(defun haskell-string-trim-suffix (suffix str)
+  "If SUFFIX is suffix of STR, the string is trimmed."
+  (when (and (stringp suffix)
+             (stringp str))
+    (if (string-suffix-p suffix str)
+        (substring str 0 (* -1 (length suffix))))))
+
+(defun haskell-string-drop-qualifier (ident)
+  "Drop qualifier from given identifier IDENT.
+
+If the identifier is not qualified return it unchanged."
+  (or (and (string-match "^\\([^.]*\\.\\)*\\(?1:[^.]+\\)$" ident)
+           (match-string 1 ident))
+      ident))
+
+(defun haskell-mode-message-line (str)
+  "Echo STR in mini-buffer.
+Given string is shrinken to single line, multiple lines just
+disturbs the programmer."
+  (message "%s" (haskell-mode-one-line str (frame-width))))
+
+(defun haskell-mode-one-line (str &optional width)
+  "Try to fit STR as much as possible on one line according to given WIDTH."
+  (unless width
+    (setq width (length str)))
+  (let* ((long-line (replace-regexp-in-string "\n" " " str))
+         (condensed  (replace-regexp-in-string
+                      " +" " " (haskell-string-trim long-line))))
+    (truncate-string-to-width condensed width nil nil "…")))
+
+(provide 'haskell-string)
+
+;;; haskell-string.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-string.elc b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-string.elc
new file mode 100644
index 0000000000..b748e6b101
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-string.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-unicode-input-method.el b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-unicode-input-method.el
new file mode 100644
index 0000000000..de792b58e4
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-unicode-input-method.el
@@ -0,0 +1,300 @@
+;;; haskell-unicode-input-method.el --- Haskell Unicode helper functions  -*- coding: utf-8; lexical-binding: t -*-
+
+;; Copyright (C) 2010-2011  Roel van Dijk
+
+;; Author: Roel van Dijk <vandijk.roel@gmail.com>
+
+;; This file is not part of GNU Emacs.
+
+;; This file 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.
+
+;; This file 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;; Code:
+
+(require 'quail)
+
+;;;###autoload
+(defun turn-on-haskell-unicode-input-method ()
+  "Set input method `haskell-unicode'."
+  (interactive)
+  (set-input-method "haskell-unicode"))
+
+(quail-define-package
+ "haskell-unicode" ;; name
+ "UTF-8"           ;; language
+ "\\"              ;; title
+ t                 ;; guidance
+ "Haskell Unicode input method.
+Designed to be used with the Haskell UnicodeSyntax language
+extension in combination with the x-unicode-symbols set of
+packages (base-unicode-symbols and containers-unicode-symbols).
+"                  ;; docstring
+ nil              ;; translation-keys
+ nil              ;; forget-last-selection
+ nil              ;; deterministic
+ nil              ;; kbd-translate
+ nil              ;; show-layout
+ nil              ;; create-decode-map
+ nil              ;; maximum-shortest
+ nil              ;; overlay-plist
+ nil              ;; update-translation-function
+ nil              ;; conversion-keys
+ t                ;; simple
+ )
+
+(quail-define-rules
+ ;; Greek letters
+ ("alpha "           ["α"])
+ ("Alpha "           ["Α"])
+ ("beta "            ["β"])
+ ("Beta "            ["Β"])
+ ("gamma "           ["γ"])
+ ("Gamma "           ["Γ"])
+ ("delta "           ["δ"])
+ ("Delta "           ["Δ"])
+ ("epsilon "         ["ε"])
+ ("Epsilon "         ["Ε"])
+ ("zeta "            ["ζ"])
+ ("Zeta "            ["Ζ"])
+ ("eta "             ["η"])
+ ("Eta "             ["Η"])
+ ("theta "           ["θ"])
+ ("Theta "           ["Θ"])
+ ("iota "            ["ι"])
+ ("Iota "            ["Ι"])
+ ("kappa "           ["κ"])
+ ("Kappa "           ["Κ"])
+ ("lambda "          ["λ"])
+ ("Lambda "          ["Λ"])
+ ("lamda "           ["λ"])
+ ("Lamda "           ["Λ"])
+ ("mu "              ["μ"])
+ ("Mu "              ["Μ"])
+ ("nu "              ["ν"])
+ ("Nu "              ["Ν"])
+ ("xi "              ["ξ"])
+ ("Xi "              ["Ξ"])
+ ("omicron "         ["ο"])
+ ("Omicron "         ["Ο"])
+ ("pi "              ["π"])
+ ("Pi "              ["Π"])
+ ("rho "             ["ρ"])
+ ("Rho "             ["Ρ"])
+ ("sigma "           ["σ"])
+ ("Sigma "           ["Σ"])
+ ("tau "             ["τ"])
+ ("Tau "             ["Τ"])
+ ("upsilon "         ["υ"])
+ ("Upsilon "         ["Υ"])
+ ("phi "             ["φ"])
+ ("Phi "             ["Φ"])
+ ("chi "             ["χ"])
+ ("Chi "             ["Χ"])
+ ("psi "             ["ψ"])
+ ("Psi "             ["Ψ"])
+ ("omega "           ["ω"])
+ ("Omega "           ["Ω"])
+ ("digamma "         ["ϝ"])
+ ("Digamma "         ["Ϝ"])
+ ("san "             ["ϻ"])
+ ("San "             ["Ϻ"])
+ ("qoppa "           ["ϙ"])
+ ("Qoppa "           ["Ϙ"])
+ ("sampi "           ["ϡ"])
+ ("Sampi "           ["Ϡ"])
+ ("stigma "          ["ϛ"])
+ ("Stigma "          ["Ϛ"])
+ ("heta "            ["ͱ"])
+ ("Heta "            ["Ͱ"])
+ ("sho "             ["ϸ"])
+ ("Sho "             ["Ϸ"])
+
+ ;; Double-struck letters
+ ("|A|"              ["𝔸"])
+ ("|B|"              ["𝔹"])
+ ("|C|"              ["ℂ"])
+ ("|D|"              ["𝔻"])
+ ("|E|"              ["𝔼"])
+ ("|F|"              ["𝔽"])
+ ("|G|"              ["𝔾"])
+ ("|H|"              ["ℍ"])
+ ("|I|"              ["𝕀"])
+ ("|J|"              ["𝕁"])
+ ("|K|"              ["𝕂"])
+ ("|L|"              ["𝕃"])
+ ("|M|"              ["𝕄"])
+ ("|N|"              ["ℕ"])
+ ("|O|"              ["𝕆"])
+ ("|P|"              ["ℙ"])
+ ("|Q|"              ["ℚ"])
+ ("|R|"              ["ℝ"])
+ ("|S|"              ["𝕊"])
+ ("|T|"              ["𝕋"])
+ ("|U|"              ["𝕌"])
+ ("|V|"              ["𝕍"])
+ ("|W|"              ["𝕎"])
+ ("|X|"              ["𝕏"])
+ ("|Y|"              ["𝕐"])
+ ("|Z|"              ["ℤ"])
+ ("|gamma|"          ["ℽ"])
+ ("|Gamma|"          ["ℾ"])
+ ("|pi|"             ["ℼ"])
+ ("|Pi|"             ["ℿ"])
+
+ ;; Types
+ ("::"               ["∷"])
+
+ ;; Quantifiers
+ ("forall"           ["∀"])
+ ("exists"           ["∃"])
+
+ ;; Arrows
+ ("->"               ["→"])
+ ;; ("-->"              ["⟶"])
+ ("<-"               ["←"])
+ ;; ("<--"              ["⟵"])
+ ;; ("<->"              ["↔"])
+ ;; ("<-->"             ["⟷"])
+
+ ("=>"               ["⇒"])
+ ;; ("==>"              ["⟹"])
+ ;; ("<="               ["⇐"])
+ ;; ("<=="              ["⟸"])
+ ;; ("<=>"              ["⇔"])
+ ;; ("<==>"             ["⟺"])
+
+ ;; ("|->"              ["↦"])
+ ;; ("|-->"             ["⟼"])
+ ;; ("<-|"              ["↤"])
+ ;; ("<--|"             ["⟻"])
+
+ ;; ("|=>"              ["⤇"])
+ ;; ("|==>"             ["⟾"])
+ ;; ("<=|"              ["⤆"])
+ ;; ("<==|"             ["⟽"])
+
+ ("~>"               ["⇝"])
+ ;; ("~~>"              ["⟿"])
+ ("<~"               ["⇜"])
+ ;; ("<~~"              ["⬳"])
+
+ ;; (">->"              ["↣"])
+ ;; ("<-<"              ["↢"])
+ ;; ("->>"              ["↠"])
+ ;; ("<<-"              ["↞"])
+
+ ;; (">->>"             ["⤖"])
+ ;; ("<<-<"             ["⬻"])
+
+ ;; ("<|-"              ["⇽"])
+ ;; ("-|>"              ["⇾"])
+ ;; ("<|-|>"            ["⇿"])
+
+ ;; ("<-/-"             ["↚"])
+ ;; ("-/->"             ["↛"])
+
+ ;; ("<-|-"             ["⇷"])
+ ;; ("-|->"             ["⇸"])
+ ;; ("<-|->"            ["⇹"])
+
+ ;; ("<-||-"            ["⇺"])
+ ;; ("-||->"            ["⇻"])
+ ;; ("<-||->"           ["⇼"])
+
+ ;; ("-o->"             ["⇴"])
+ ;; ("<-o-"             ["⬰"])
+
+ ;; Boolean operators
+ ;; ("not"              ["¬"])
+ ("&&"               ["∧"])
+ ("||"               ["∨"])
+
+ ;; Relational operators
+ ("=="               ["≡"])
+ ("/="               ["≢" "≠"])
+ ("<="               ["≤"])
+ (">="               ["≥"])
+ ("/<"               ["≮"])
+ ("/>"               ["≯"])
+
+ ;; Arithmetic
+ ;; (" / "              [" ÷ "])
+ (" * "              [" ⋅ "])
+
+ ;; Containers / Collections
+ ;; ("++"               ["⧺"])
+ ;; ("+++"              ["⧻"])
+ ;; ("|||"              ["⫴"])
+ ;; ("empty"            ["∅"])
+ ("elem"             ["∈"])
+ ("notElem"          ["∉"])
+ ("member"           ["∈"])
+ ("notMember"        ["∉"])
+ ("union"            ["∪"])
+ ("intersection"     ["∩"])
+ ("isSubsetOf"       ["⊆"])
+ ("isProperSubsetOf" ["⊂"])
+
+ ;; Other
+ ;; ("<<"               ["≪"])
+ ;; (">>"               ["≫"])
+ ("<<<"              ["⋘"])
+ (">>>"              ["⋙"])
+ ("<|"               ["⊲"])
+ ("|>"               ["⊳"])
+ ("><"               ["⋈"])
+ ;; ("mempty"           ["∅"])
+ ("mappend"          ["⊕"])
+ ;; ("<*>"              ["⊛"])
+ (" . "              [" ∘ "])
+ ("undefined"        ["⊥"])
+ (":="               ["≔"])
+ ("=:"               ["≕"])
+ ("=def"             ["≝"])
+ ("=?"               ["≟"])
+ ("..."              ["…"])
+
+ ;; Braces
+ ;; ("[|"               ["〚"])
+ ;; ("|]"               ["〛"])
+
+ ;; Numeric subscripts
+ ("_0 "              ["₀"])
+ ("_1 "              ["₁"])
+ ("_2 "              ["₂"])
+ ("_3 "              ["₃"])
+ ("_4 "              ["₄"])
+ ("_5 "              ["₅"])
+ ("_6 "              ["₆"])
+ ("_7 "              ["₇"])
+ ("_8 "              ["₈"])
+ ("_9 "              ["₉"])
+
+ ;; Numeric superscripts
+ ("^0 "              ["⁰"])
+ ("^1 "              ["¹"])
+ ("^2 "              ["²"])
+ ("^3 "              ["³"])
+ ("^4 "              ["⁴"])
+ ("^5 "              ["⁵"])
+ ("^6 "              ["⁶"])
+ ("^7 "              ["⁷"])
+ ("^8 "              ["⁸"])
+ ("^9 "              ["⁹"])
+ )
+
+(provide 'haskell-unicode-input-method)
+
+;;; haskell-unicode-input-method.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-unicode-input-method.elc b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-unicode-input-method.elc
new file mode 100644
index 0000000000..f5257af4e2
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-unicode-input-method.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-utils.el b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-utils.el
new file mode 100644
index 0000000000..1126a2614d
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-utils.el
@@ -0,0 +1,193 @@
+;;; haskell-utils.el --- General utility functions used by haskell-mode modules -*- lexical-binding: t -*-
+
+;; Copyright © 2013 Herbert Valerio Riedel
+;;             2016 Arthur Fayzrakhmanov
+
+;; Author: Herbert Valerio Riedel <hvr@gnu.org>
+
+;; This file is not part of GNU Emacs.
+
+;; This file 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.
+
+;; This file 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This module's purpose is to provide a place for helper functions
+;; which are general enough to be usable by multiple modules and/or
+;; to alleviate circular module dependency problems.
+;;
+;; When possible, functions in this module shall be accompanied by
+;; ERT-based unit tests.
+;;
+;; See also `haskell-str.el' for string utility functions.
+;;
+;; All symbols in this module have a `haskell-utils-' prefix.
+
+;;; Code:
+
+;; =============================================================================
+;;                                     NOTE:
+;; THIS MODULE IS SUPPOSED TO BE A LEAF-MODULE AND SHALL NOT REQUIRE/DEPEND-ON
+;; ANY OTHER HASKELL-MODE MODULES IN ORDER TO STAY AT THE BOTTOM OF THE MODULE
+;; DEPENDENCY GRAPH.
+;; =============================================================================
+
+(eval-when-compile (require 'cl-lib))
+
+(defvar-local haskell-utils-async-post-command-flag nil
+  "Non-nil means some commands were triggered during async function execution.")
+
+(defvar haskell-mode-interactive-prompt-state nil
+  "Special variable indicating a state of user input waiting.")
+
+(defun haskell-utils-read-directory-name (prompt default)
+  "Read directory name and normalize to true absolute path.
+Refer to `read-directory-name' for the meaning of PROMPT and
+DEFAULT.  If `haskell-process-load-or-reload-prompt' is nil,
+accept `default'."
+  (let ((filename (file-truename (read-directory-name prompt default default))))
+    (concat (replace-regexp-in-string "/$" "" filename) "/")))
+
+(defun haskell-utils-parse-import-statement-at-point ()
+  "Return imported module name if on import statement or nil otherwise.
+This currently assumes that the \"import\" keyword and the module
+name are on the same line.
+
+This function supports the SafeHaskell and PackageImports syntax extensions.
+
+Note: doesn't detect if in {--}-style comment."
+  (save-excursion
+    (goto-char (line-beginning-position))
+    (if (looking-at (concat "[\t ]*import[\t ]+"
+                            "\\(?:safe[\t ]+\\)?" ;; SafeHaskell
+                            "\\(?:qualified[\t ]+\\)?"
+                            "\\(?:\"[^\"]*\"[\t ]+\\)?" ;; PackageImports
+                            "\\([[:digit:][:upper:][:lower:]_.]+\\)"))
+        (match-string-no-properties 1))))
+
+(defun haskell-utils-async-update-post-command-flag ()
+  "A special hook which collects triggered commands during async execution.
+This hook pushes value of variable `this-command' to flag variable
+`haskell-utils-async-post-command-flag'."
+  (let* ((cmd this-command)
+         (updated-flag (cons cmd haskell-utils-async-post-command-flag)))
+    (setq haskell-utils-async-post-command-flag updated-flag)))
+
+(defun haskell-utils-async-watch-changes ()
+  "Watch for triggered commands during async operation execution.
+Resets flag variable
+`haskell-utils-async-update-post-command-flag' to NIL.  By changes it is
+assumed that nothing happened, e.g. nothing was inserted in
+buffer, point was not moved, etc.  To collect data `post-command-hook' is used."
+  (setq haskell-utils-async-post-command-flag nil)
+  (add-hook
+   'post-command-hook #'haskell-utils-async-update-post-command-flag nil t))
+
+(defun haskell-utils-async-stop-watching-changes (buffer)
+  "Clean up after async operation finished.
+This function takes care about cleaning up things made by
+`haskell-utils-async-watch-changes'.  The BUFFER argument is a buffer where
+`post-command-hook' should be disabled.  This is neccessary, because
+it is possible that user will change buffer during async function
+execusion."
+  (with-current-buffer buffer
+    (setq haskell-utils-async-post-command-flag nil)
+    (remove-hook
+     'post-command-hook #'haskell-utils-async-update-post-command-flag t)))
+
+(defun haskell-utils-reduce-string (str)
+  "Remove newlines and extra whitespace from string STR.
+If line starts with a sequence of whitespaces, substitutes this
+sequence with a single whitespace.  Removes all newline
+characters."
+  (let ((s (replace-regexp-in-string "^\s+" " " str)))
+    (replace-regexp-in-string "\r?\n" "" s)))
+
+(defun haskell-utils-repl-response-error-status (response)
+  "Parse response REPL's RESPONSE for errors.
+Returns one of the following symbols:
+
++ unknown-command
++ option-missing
++ interactive-error
++ no-error
+
+*Warning*: this funciton covers only three kind of responses:
+
+* \"unknown command …\"
+  REPL missing requested command
+* \"<interactive>:3:5: …\"
+  interactive REPL error
+* \"Couldn't guess that module name. Does it exist?\"
+  (:type-at and maybe some other commands error)
+* *all other reposnses* are treated as success reposneses and
+  'no-error is returned."
+  (if response
+      (let ((first-line (car (split-string response "\n" t))))
+        (cond
+         ((null first-line) 'no-error)
+         ((string-match-p "^unknown command" first-line)
+          'unknown-command)
+         ((string-match-p
+           "^Couldn't guess that module name. Does it exist?"
+           first-line)
+          'option-missing)
+         ((string-match-p "^<interactive>:" first-line)
+          'interactive-error)
+         (t 'no-error)))
+    ;; in case of nil-ish reponse it's not clear is it error response or not
+    'no-error))
+
+(defun haskell-utils-compose-type-at-command (pos)
+  "Prepare :type-at command to be send to haskell process.
+POS is a cons cell containing min and max positions, i.e. target
+expression bounds."
+  (save-excursion
+    (let ((start-p (car pos))
+          (end-p (cdr pos))
+          start-l
+          start-c
+          end-l
+          end-c
+          value)
+      (goto-char start-p)
+      (setq start-l (line-number-at-pos))
+      (setq start-c (1+ (current-column)))
+      (goto-char end-p)
+      (setq end-l (line-number-at-pos))
+      (setq end-c (1+ (current-column)))
+      (setq value (buffer-substring-no-properties start-p end-p))
+      ;; supress multiline expressions
+      (let ((lines (split-string value "\n" t)))
+        (when (and (cdr lines)
+                   (stringp (car lines)))
+          (setq value (format "[ %s … ]" (car lines)))))
+      (replace-regexp-in-string
+       "\n$"
+       ""
+       (format ":type-at %s %d %d %d %d %s"
+               (buffer-file-name)
+               start-l
+               start-c
+               end-l
+               end-c
+               value)))))
+
+
+(defun haskell-mode-toggle-interactive-prompt-state (&optional disabled)
+  "Set `haskell-mode-interactive-prompt-state' to t.
+If given DISABLED argument sets variable value to nil, otherwise to t."
+  (setq haskell-mode-interactive-prompt-state (not disabled)))
+
+(provide 'haskell-utils)
+;;; haskell-utils.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-utils.elc b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-utils.elc
new file mode 100644
index 0000000000..3c2ddd80e6
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell-utils.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell.el b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell.el
new file mode 100644
index 0000000000..641fea3567
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell.el
@@ -0,0 +1,528 @@
+;;; haskell.el --- Top-level Haskell package -*- lexical-binding: t -*-
+
+;; Copyright © 2014 Chris Done.  All rights reserved.
+;;             2016 Arthur Fayzrakhmanov
+
+;; This file 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, or (at your option)
+;; any later version.
+
+;; This file 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'haskell-mode)
+(require 'haskell-hoogle)
+(require 'haskell-process)
+(require 'haskell-debug)
+(require 'haskell-interactive-mode)
+(require 'haskell-repl)
+(require 'haskell-load)
+(require 'haskell-commands)
+(require 'haskell-modules)
+(require 'haskell-string)
+(require 'haskell-completions)
+(require 'haskell-utils)
+(require 'haskell-customize)
+
+(defvar interactive-haskell-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "C-c C-l") 'haskell-process-load-file)
+    (define-key map (kbd "C-c C-r") 'haskell-process-reload)
+    (define-key map (kbd "C-c C-t") 'haskell-process-do-type)
+    (define-key map (kbd "C-c C-i") 'haskell-process-do-info)
+    (define-key map (kbd "M-.") 'haskell-mode-jump-to-def-or-tag)
+    (define-key map (kbd "C-c C-k") 'haskell-interactive-mode-clear)
+    (define-key map (kbd "C-c C-c") 'haskell-process-cabal-build)
+    (define-key map (kbd "C-c C-v") 'haskell-cabal-visit-file)
+    (define-key map (kbd "C-c C-x") 'haskell-process-cabal)
+    (define-key map (kbd "C-c C-b") 'haskell-interactive-switch)
+    (define-key map (kbd "C-c C-z") 'haskell-interactive-switch)
+    map)
+  "Keymap for using `interactive-haskell-mode'.")
+
+;;;###autoload
+(define-minor-mode interactive-haskell-mode
+  "Minor mode for enabling haskell-process interaction."
+  :lighter " Interactive"
+  :keymap interactive-haskell-mode-map
+  (add-hook 'completion-at-point-functions
+            #'haskell-completions-sync-repl-completion-at-point
+            nil
+            t))
+
+(make-obsolete 'haskell-process-completions-at-point
+               'haskell-completions-sync-repl-completion-at-point
+               "June 19, 2015")
+
+(defun haskell-process-completions-at-point ()
+  "A `completion-at-point' function using the current haskell process."
+  (when (haskell-session-maybe)
+    (let ((process (haskell-process))
+          symbol-bounds)
+      (cond
+       ;; ghci can complete module names, but it needs the "import "
+       ;; string at the beginning
+       ((looking-back (rx line-start
+                          "import" (1+ space)
+                          (? "qualified" (1+ space))
+                          (group (? (char upper) ; modid
+                                    (* (char alnum ?' ?.)))))
+                      (line-beginning-position))
+        (let ((text (match-string-no-properties 0))
+              (start (match-beginning 1))
+              (end (match-end 1)))
+          (list start end
+                (haskell-process-get-repl-completions process text))))
+       ;; Complete OPTIONS, a completion list comes from variable
+       ;; `haskell-ghc-supported-options'
+       ((and (nth 4 (syntax-ppss))
+           (save-excursion
+             (let ((p (point)))
+               (and (search-backward "{-#" nil t)
+                  (search-forward-regexp "\\_<OPTIONS\\(?:_GHC\\)?\\_>" p t))))
+           (looking-back
+            (rx symbol-start "-" (* (char alnum ?-)))
+            (line-beginning-position)))
+        (list (match-beginning 0) (match-end 0) haskell-ghc-supported-options))
+       ;; Complete LANGUAGE, a list of completions comes from variable
+       ;; `haskell-ghc-supported-extensions'
+       ((and (nth 4 (syntax-ppss))
+           (save-excursion
+             (let ((p (point)))
+               (and (search-backward "{-#" nil t)
+                  (search-forward-regexp "\\_<LANGUAGE\\_>" p t))))
+           (setq symbol-bounds (bounds-of-thing-at-point 'symbol)))
+        (list (car symbol-bounds) (cdr symbol-bounds)
+              haskell-ghc-supported-extensions))
+       ((setq symbol-bounds (haskell-ident-pos-at-point))
+        (cl-destructuring-bind (start . end) symbol-bounds
+          (list start end
+                (haskell-process-get-repl-completions
+                 process (buffer-substring-no-properties start end)))))))))
+
+;;;###autoload
+(defun haskell-interactive-mode-return ()
+  "Handle the return key."
+  (interactive)
+  (cond
+   ;; At a compile message, jump to the location of the error in the
+   ;; source.
+   ((haskell-interactive-at-compile-message)
+    (next-error-internal))
+   ;; At the input prompt, handle the expression in the usual way.
+   ((haskell-interactive-at-prompt)
+    (haskell-interactive-handle-expr))
+   ;; At any other location in the buffer, copy the line to the
+   ;; current prompt.
+   (t
+    (haskell-interactive-copy-to-prompt))))
+
+;;;###autoload
+(defun haskell-session-kill (&optional leave-interactive-buffer)
+  "Kill the session process and buffer, delete the session.
+0. Prompt to kill all associated buffers.
+1. Kill the process.
+2. Kill the interactive buffer unless LEAVE-INTERACTIVE-BUFFER is not given.
+3. Walk through all the related buffers and set their haskell-session to nil.
+4. Remove the session from the sessions list."
+  (interactive)
+  (haskell-mode-toggle-interactive-prompt-state)
+  (unwind-protect
+      (let* ((session (haskell-session))
+             (name (haskell-session-name session))
+             (also-kill-buffers
+              (and haskell-ask-also-kill-buffers
+                   (y-or-n-p
+                    (format "Killing `%s'. Also kill all associated buffers?"
+                            name)))))
+        (haskell-kill-session-process session)
+        (unless leave-interactive-buffer
+          (kill-buffer (haskell-session-interactive-buffer session)))
+        (cl-loop for buffer in (buffer-list)
+                 do (with-current-buffer buffer
+                      (when (and (boundp 'haskell-session)
+                                 (string= (haskell-session-name haskell-session)
+                                          name))
+                        (setq haskell-session nil)
+                        (when also-kill-buffers
+                          (kill-buffer)))))
+        (setq haskell-sessions
+              (cl-remove-if (lambda (session)
+                              (string= (haskell-session-name session)
+                                       name))
+                            haskell-sessions)))
+    (haskell-mode-toggle-interactive-prompt-state t)))
+
+;;;###autoload
+(defun haskell-interactive-kill ()
+  "Kill the buffer and (maybe) the session."
+  (interactive)
+  (when (eq major-mode 'haskell-interactive-mode)
+    (haskell-mode-toggle-interactive-prompt-state)
+    (unwind-protect
+        (when (and (boundp 'haskell-session)
+                   haskell-session
+                   (y-or-n-p "Kill the whole session?"))
+          (haskell-session-kill t)))
+    (haskell-mode-toggle-interactive-prompt-state t)))
+
+(defun haskell-session-make (name)
+  "Make a Haskell session."
+  (when (haskell-session-lookup name)
+    (error "Session of name %s already exists!" name))
+  (let ((session (setq haskell-session
+                       (list (cons 'name name)))))
+    (add-to-list 'haskell-sessions session)
+    (haskell-process-start session)
+    session))
+
+(defun haskell-session-new-assume-from-cabal ()
+  "Prompt to create a new project based on a guess from the nearest Cabal file.
+If `haskell-process-load-or-reload-prompt' is nil, accept `default'."
+  (let ((name (haskell-session-default-name)))
+    (unless (haskell-session-lookup name)
+      (haskell-mode-toggle-interactive-prompt-state)
+      (unwind-protect
+          (if (or (not haskell-process-load-or-reload-prompt)
+                  (y-or-n-p (format "Start a new project named “%s”? " name)))
+              (haskell-session-make name))
+        (haskell-mode-toggle-interactive-prompt-state t)))))
+
+;;;###autoload
+(defun haskell-session ()
+  "Get the Haskell session, prompt if there isn't one or fail."
+  (or (haskell-session-maybe)
+      (haskell-session-assign
+       (or (haskell-session-from-buffer)
+           (haskell-session-new-assume-from-cabal)
+           (haskell-session-choose)
+           (haskell-session-new)))))
+
+;;;###autoload
+(defun haskell-interactive-switch ()
+  "Switch to the interactive mode for this session."
+  (interactive)
+  (let ((initial-buffer (current-buffer))
+        (buffer (haskell-session-interactive-buffer (haskell-session))))
+    (with-current-buffer buffer
+      (setq haskell-interactive-previous-buffer initial-buffer))
+    (unless (eq buffer (window-buffer))
+      (switch-to-buffer-other-window buffer))))
+
+(defun haskell-session-new ()
+  "Make a new session."
+  (let ((name (read-from-minibuffer "Project name: " (haskell-session-default-name))))
+    (when (not (string= name ""))
+      (let ((session (haskell-session-lookup name)))
+        (haskell-mode-toggle-interactive-prompt-state)
+        (unwind-protect
+            (if session
+                (when
+                    (y-or-n-p
+                     (format "Session %s already exists. Use it?" name))
+                  session)
+              (haskell-session-make name)))
+        (haskell-mode-toggle-interactive-prompt-state t)))))
+
+;;;###autoload
+(defun haskell-session-change ()
+  "Change the session for the current buffer."
+  (interactive)
+  (haskell-session-assign (or (haskell-session-new-assume-from-cabal)
+                              (haskell-session-choose)
+                              (haskell-session-new))))
+
+(defun haskell-process-prompt-restart (process)
+  "Prompt to restart the died PROCESS."
+  (let ((process-name (haskell-process-name process))
+        (cursor-in-echo-area t))
+    (if haskell-process-suggest-restart
+        (progn
+          (haskell-mode-toggle-interactive-prompt-state)
+          (unwind-protect
+              (cond
+               ((string-match "You need to re-run the 'configure' command."
+                              (haskell-process-response process))
+                (cl-case (read-char-choice
+                          (concat
+                           "The Haskell process ended. Cabal wants you to run "
+                           (propertize "cabal configure"
+                                       'face
+                                       'font-lock-keyword-face)
+                           " because there is a version mismatch. Re-configure (y, n, l: view log)?"
+                           "\n\n"
+                           "Cabal said:\n\n"
+                           (propertize (haskell-process-response process)
+                                       'face
+                                       'font-lock-comment-face))
+                          '(?l ?n ?y))
+                  (?y (let ((default-directory
+                              (haskell-session-cabal-dir
+                               (haskell-process-session process))))
+                        (message "%s"
+                                 (shell-command-to-string "cabal configure"))))
+                  (?l (let* ((response (haskell-process-response process))
+                             (buffer (get-buffer "*haskell-process-log*")))
+                        (if buffer
+                            (switch-to-buffer buffer)
+                          (progn (switch-to-buffer
+                                  (get-buffer-create "*haskell-process-log*"))
+                                 (insert response)))))
+                  (?n)))
+               (t
+                (cl-case (read-char-choice
+                          (propertize
+                           (format "The Haskell process `%s' has died. Restart? (y, n, l: show process log) "
+                                   process-name)
+                           'face
+                           'minibuffer-prompt)
+                          '(?l ?n ?y))
+                  (?y (haskell-process-start (haskell-process-session process)))
+                  (?l (let* ((response (haskell-process-response process))
+                             (buffer (get-buffer "*haskell-process-log*")))
+                        (if buffer
+                            (switch-to-buffer buffer)
+                          (progn (switch-to-buffer
+                                  (get-buffer-create "*haskell-process-log*"))
+                                 (insert response)))))
+                  (?n))))
+            ;; unwind
+            (haskell-mode-toggle-interactive-prompt-state t)))
+      (message "The Haskell process `%s' is dearly departed." process-name))))
+
+(defun haskell-process ()
+  "Get the current process from the current session."
+  (haskell-session-process (haskell-session)))
+
+;;;###autoload
+(defun haskell-kill-session-process (&optional session)
+  "Kill the process."
+  (interactive)
+  (let* ((session (or session (haskell-session)))
+         (existing-process (get-process (haskell-session-name session))))
+    (when (processp existing-process)
+      (haskell-interactive-mode-echo session "Killing process ...")
+      (haskell-process-set (haskell-session-process session) 'is-restarting t)
+      (delete-process existing-process))))
+
+;;;###autoload
+(defun haskell-interactive-mode-visit-error ()
+  "Visit the buffer of the current (or last) error message."
+  (interactive)
+  (with-current-buffer (haskell-session-interactive-buffer (haskell-session))
+    (if (progn (goto-char (line-beginning-position))
+               (looking-at haskell-interactive-mode-error-regexp))
+        (progn (forward-line -1)
+               (haskell-interactive-jump-to-error-line))
+      (progn (goto-char (point-max))
+             (haskell-interactive-mode-error-backward)
+             (haskell-interactive-jump-to-error-line)))))
+
+(defvar xref-prompt-for-identifier nil)
+
+;;;###autoload
+(defun haskell-mode-jump-to-tag (&optional next-p)
+  "Jump to the tag of the given identifier.
+
+Give optional NEXT-P parameter to override value of
+`xref-prompt-for-identifier' during definition search."
+  (interactive "P")
+  (let ((ident (haskell-string-drop-qualifier (haskell-ident-at-point)))
+        (tags-file-dir (haskell-cabal--find-tags-dir))
+        (tags-revert-without-query t))
+    (when (and ident
+               (not (string= "" (haskell-string-trim ident)))
+               tags-file-dir)
+      (let ((tags-file-name (concat tags-file-dir "TAGS")))
+        (cond ((file-exists-p tags-file-name)
+               (let ((xref-prompt-for-identifier next-p))
+                 (xref-find-definitions ident)))
+              (t (haskell-mode-generate-tags ident)))))))
+
+;;;###autoload
+(defun haskell-mode-after-save-handler ()
+  "Function that will be called after buffer's saving."
+  (when haskell-tags-on-save
+    (ignore-errors (haskell-mode-generate-tags))))
+
+;;;###autoload
+(defun haskell-mode-tag-find (&optional _next-p)
+  "The tag find function, specific for the particular session."
+  (interactive "P")
+  (cond
+   ((elt (syntax-ppss) 3) ;; Inside a string
+    (haskell-mode-jump-to-filename-in-string))
+   (t (call-interactively 'haskell-mode-jump-to-tag))))
+
+(defun haskell-mode-jump-to-filename-in-string ()
+  "Jump to the filename in the current string."
+  (let* ((string (save-excursion
+                   (buffer-substring-no-properties
+                    (1+ (search-backward-regexp "\"" (line-beginning-position) nil 1))
+                    (1- (progn (forward-char 1)
+                               (search-forward-regexp "\"" (line-end-position) nil 1))))))
+         (fp (expand-file-name string
+                               (haskell-session-cabal-dir (haskell-session)))))
+    (find-file
+     (read-file-name
+      ""
+      fp
+      fp))))
+
+;;;###autoload
+(defun haskell-interactive-bring ()
+  "Bring up the interactive mode for this session."
+  (interactive)
+  (let* ((session (haskell-session))
+         (buffer (haskell-session-interactive-buffer session)))
+    (pop-to-buffer buffer)))
+
+;;;###autoload
+(defun haskell-process-load-file ()
+  "Load the current buffer file."
+  (interactive)
+  (save-buffer)
+  (haskell-interactive-mode-reset-error (haskell-session))
+  (haskell-process-file-loadish (format "load \"%s\"" (replace-regexp-in-string
+                                                       "\""
+                                                       "\\\\\""
+                                                       (buffer-file-name)))
+                                nil
+                                (current-buffer)))
+
+;;;###autoload
+(defun haskell-process-reload ()
+  "Re-load the current buffer file."
+  (interactive)
+  (save-buffer)
+  (haskell-interactive-mode-reset-error (haskell-session))
+  (haskell-process-file-loadish "reload" t (current-buffer)))
+
+;;;###autoload
+(defun haskell-process-reload-file () (haskell-process-reload))
+
+(make-obsolete 'haskell-process-reload-file 'haskell-process-reload
+               "2015-11-14")
+
+;;;###autoload
+(defun haskell-process-load-or-reload (&optional toggle)
+  "Load or reload. Universal argument toggles which."
+  (interactive "P")
+  (if toggle
+      (progn (setq haskell-reload-p (not haskell-reload-p))
+             (message "%s (No action taken this time)"
+                      (if haskell-reload-p
+                          "Now running :reload."
+                        "Now running :load <buffer-filename>.")))
+    (if haskell-reload-p (haskell-process-reload) (haskell-process-load-file))))
+
+(make-obsolete 'haskell-process-load-or-reload 'haskell-process-load-file
+               "2015-11-14")
+
+;;;###autoload
+(defun haskell-process-cabal-build ()
+  "Build the Cabal project."
+  (interactive)
+  (haskell-process-do-cabal "build")
+  (haskell-process-add-cabal-autogen))
+
+;;;###autoload
+(defun haskell-process-cabal (p)
+  "Prompts for a Cabal command to run."
+  (interactive "P")
+  (if p
+      (haskell-process-do-cabal
+       (read-from-minibuffer "Cabal command (e.g. install): "))
+    (haskell-process-do-cabal
+     (funcall haskell-completing-read-function "Cabal command: "
+              (append haskell-cabal-commands
+                      (list "build --ghc-options=-fforce-recomp"))))))
+
+(defun haskell-process-file-loadish (command reload-p module-buffer)
+  "Run a loading-ish COMMAND that wants to pick up type errors\
+and things like that.  RELOAD-P indicates whether the notification
+should say 'reloaded' or 'loaded'.  MODULE-BUFFER may be used
+for various things, but is optional."
+  (let ((session (haskell-session)))
+    (haskell-session-current-dir session)
+    (when haskell-process-check-cabal-config-on-load
+      (haskell-process-look-config-changes session))
+    (let ((process (haskell-process)))
+      (haskell-process-queue-command
+       process
+       (make-haskell-command
+        :state (list session process command reload-p module-buffer)
+        :go (lambda (state)
+              (haskell-process-send-string
+               (cadr state) (format ":%s" (cl-caddr state))))
+        :live (lambda (state buffer)
+                (haskell-process-live-build
+                 (cadr state) buffer nil))
+        :complete (lambda (state response)
+                    (haskell-process-load-complete
+                     (car state)
+                     (cadr state)
+                     response
+                     (cl-cadddr state)
+                     (cl-cadddr (cdr state)))))))))
+
+;;;###autoload
+(defun haskell-process-minimal-imports ()
+  "Dump minimal imports."
+  (interactive)
+  (unless (> (save-excursion
+               (goto-char (point-min))
+               (haskell-navigate-imports-go)
+               (point))
+             (point))
+    (goto-char (point-min))
+    (haskell-navigate-imports-go))
+  (haskell-process-queue-sync-request (haskell-process)
+                                      ":set -ddump-minimal-imports")
+  (haskell-process-load-file)
+  (insert-file-contents-literally
+   (concat (haskell-session-current-dir (haskell-session))
+           "/"
+           (haskell-guess-module-name-from-file-name (buffer-file-name))
+           ".imports")))
+
+(defun haskell-interactive-jump-to-error-line ()
+  "Jump to the error line."
+  (let ((orig-line (buffer-substring-no-properties (line-beginning-position)
+                                                   (line-end-position))))
+    (and (string-match "^\\([^:]+\\):\\([0-9]+\\):\\([0-9]+\\)\\(-[0-9]+\\)?:" orig-line)
+         (let* ((file (match-string 1 orig-line))
+                (line (match-string 2 orig-line))
+                (col (match-string 3 orig-line))
+                (session (haskell-interactive-session))
+                (cabal-path (haskell-session-cabal-dir session))
+                (src-path (haskell-session-current-dir session))
+                (cabal-relative-file (expand-file-name file cabal-path))
+                (src-relative-file (expand-file-name file src-path)))
+           (let ((file (cond ((file-exists-p cabal-relative-file)
+                              cabal-relative-file)
+                             ((file-exists-p src-relative-file)
+                              src-relative-file))))
+             (when file
+               (other-window 1)
+               (find-file file)
+               (haskell-interactive-bring)
+               (goto-char (point-min))
+               (forward-line (1- (string-to-number line)))
+               (goto-char (+ (point) (string-to-number col) -1))
+               (haskell-mode-message-line orig-line)
+               t))))))
+
+(provide 'haskell)
+;;; haskell.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell.elc b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell.elc
new file mode 100644
index 0000000000..bdc81f55d3
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/haskell.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/highlight-uses-mode.el b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/highlight-uses-mode.el
new file mode 100644
index 0000000000..722c964143
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/highlight-uses-mode.el
@@ -0,0 +1,106 @@
+;;; highlight-uses-mode.el --- Mode for highlighting uses -*- lexical-binding: t -*-
+
+;; Copyright (c) 2014 Chris Done. All rights reserved.
+
+;; This file 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, or (at your option)
+;; any later version.
+
+;; This file 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Code:
+
+(require 'cl-lib)
+
+(defvar highlight-uses-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "TAB") 'highlight-uses-mode-next)
+    (define-key map (kbd "S-TAB") 'highlight-uses-mode-prev)
+    (define-key map (kbd "<backtab>") 'highlight-uses-mode-prev)
+    (define-key map (kbd "RET") 'highlight-uses-mode-stop-here)
+    (define-key map (kbd "C-g") 'highlight-uses-mode)
+    map)
+  "Keymap for using `highlight-uses-mode'.")
+
+(defvar-local highlight-uses-mode-point nil)
+
+;;;###autoload
+(define-minor-mode highlight-uses-mode
+  "Minor mode for highlighting and jumping between uses."
+  :lighter " Uses"
+  :keymap highlight-uses-mode-map
+  (if highlight-uses-mode
+      (setq highlight-uses-mode-point (point))
+    (when highlight-uses-mode-point
+      (goto-char highlight-uses-mode-point)))
+  (remove-overlays (point-min) (point-max) 'highlight-uses-mode-highlight t))
+
+(defun highlight-uses-mode-replace ()
+  "Replace all highlighted instances in the buffer with something
+  else."
+  (interactive)
+  (save-excursion
+    (goto-char (point-min))
+    (let ((o (highlight-uses-mode-next)))
+      (when o
+        (let ((replacement (read-from-minibuffer (format "Replace uses %s with: "
+                                                         (buffer-substring
+                                                          (overlay-start o)
+                                                          (overlay-end o))))))
+
+          (while o
+            (goto-char (overlay-start o))
+            (delete-region (overlay-start o)
+                           (overlay-end o))
+            (insert replacement)
+            (setq o (highlight-uses-mode-next))))))))
+
+(defun highlight-uses-mode-stop-here ()
+  "Stop at this point."
+  (interactive)
+  (setq highlight-uses-mode-point (point))
+  (highlight-uses-mode -1))
+
+(defun highlight-uses-mode-next ()
+  "Jump to next result."
+  (interactive)
+  (let ((os (sort (cl-remove-if (lambda (o)
+                                  (or (<= (overlay-start o) (point))
+                                      (not (overlay-get o 'highlight-uses-mode-highlight))))
+                                (overlays-in (point) (point-max)))
+                  (lambda (a b)
+                    (< (overlay-start a)
+                       (overlay-start b))))))
+    (when os
+      (goto-char (overlay-start (car os)))
+      (car os))))
+
+(defun highlight-uses-mode-prev ()
+  "Jump to previous result."
+  (interactive)
+  (let ((os (sort (cl-remove-if (lambda (o)
+                                  (or (>= (overlay-end o) (point))
+                                      (not (overlay-get o 'highlight-uses-mode-highlight))))
+                                (overlays-in (point-min) (point)))
+                  (lambda (a b)
+                    (> (overlay-start a)
+                       (overlay-start b))))))
+    (when os
+      (goto-char (overlay-start (car os)))
+      (car os))))
+
+(defun highlight-uses-mode-highlight (start end)
+  "Make a highlight overlay at the given span."
+  (let ((o (make-overlay start end)))
+    (overlay-put o 'priority 999)
+    (overlay-put o 'face 'isearch)
+    (overlay-put o 'highlight-uses-mode-highlight t)))
+
+(provide 'highlight-uses-mode)
diff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/highlight-uses-mode.elc b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/highlight-uses-mode.elc
new file mode 100644
index 0000000000..3b9bba06c0
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/highlight-uses-mode.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/inf-haskell.el b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/inf-haskell.el
new file mode 100644
index 0000000000..a1ee32fe2f
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/inf-haskell.el
@@ -0,0 +1,262 @@
+;;; inf-haskell.el --- Interaction with an inferior Haskell process -*- lexical-binding: t -*-
+
+;; Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation, Inc.
+;; Copyright (C) 2017 Vasantha Ganesh Kanniappan <vasanthaganesh.k@tuta.io>
+
+;; Author: Stefan Monnier <monnier@iro.umontreal.ca>
+;; Keywords: Haskell
+
+;; This file 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, or (at your option)
+;; any later version.
+
+;; This file 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; A major mode for the buffer that holds the inferior process
+
+;; Todo:
+
+;; - Check out Shim for ideas.
+;; - i-h-load-buffer and i-h-send-region.
+
+;;; Code:
+
+(require 'comint)
+(require 'shell)             ; For directory tracking.
+(require 'etags)
+(require 'haskell-compat)
+(require 'compile)
+(require 'haskell-decl-scan)
+(require 'haskell-cabal)
+(require 'haskell-customize)
+(require 'cl-lib)
+(require 'haskell-string)
+
+;;;###autoload
+(defgroup inferior-haskell nil
+  "Settings for REPL interaction via `inferior-haskell-mode'"
+  :link '(custom-manual "(haskell-mode)inferior-haskell-mode")
+  :prefix "inferior-haskell-"
+  :prefix "haskell-"
+  :group 'haskell)
+
+(defcustom inferior-haskell-hook nil
+  "The hook that is called after starting inf-haskell."
+  :type 'hook)
+
+(defun haskell-program-name-with-args ()
+  "Return the command with the arguments to start the repl based on the
+directory structure."
+  (cl-ecase (haskell-process-type)
+    ('ghci       (cond ((eq system-type 'cygwin) (nconc "ghcii.sh"
+                                                        haskell-process-args-ghci))
+                       (t (nconc `(,haskell-process-path-ghci)
+                                 haskell-process-args-ghci))))
+    ('cabal-repl (nconc `(,haskell-process-path-cabal
+                          "repl")
+                        haskell-process-args-cabal-repl))
+    ('stack-ghci (nconc `(,haskell-process-path-stack
+                          "ghci")
+                        haskell-process-args-stack-ghci))))
+
+(defconst inferior-haskell-info-xref-re
+  "-- Defined at \\(.+\\):\\([0-9]+\\):\\([0-9]+\\)\\(?:-\\([0-9]+\\)\\)?$")
+
+(defconst inferior-haskell-module-re
+  "-- Defined in \\(.+\\)$"
+  "Regular expression for matching module names in :info.")
+
+(defvar inferior-haskell-multiline-prompt-re
+  "^\\*?[[:upper:]][\\._[:alnum:]]*\\(?: \\*?[[:upper:]][\\._[:alnum:]]*\\)*| "
+  "Regular expression for matching multiline prompt (the one inside :{ ... :} blocks).")
+
+(defconst inferior-haskell-error-regexp-alist
+  `(;; Format of error messages used by GHCi.
+    ("^\\(.+?\\):\\([0-9]+\\):\\(\\([0-9]+\\):\\)?\\( \\|\n *\\)\\([Ww]arning\\)?"
+     1 2 4 ,@(if (fboundp 'compilation-fake-loc)
+                 '((6) nil (5 '(face nil font-lock-multiline t)))))
+    ;; Runtime exceptions, from ghci.
+    ("^\\*\\*\\* Exception: \\(.+?\\):(\\([0-9]+\\),\\([0-9]+\\))-(\\([0-9]+\\),\\([0-9]+\\)): .*"
+     1 ,@(if (fboundp 'compilation-fake-loc) '((2 . 4) (3 . 5)) '(2 3)))
+    ;; GHCi uses two different forms for line/col ranges, depending on
+    ;; whether it's all on the same line or not :-( In Emacs-23, I could use
+    ;; explicitly numbered subgroups to merge the two patterns.
+    ("^\\*\\*\\* Exception: \\(.+?\\):\\([0-9]+\\):\\([0-9]+\\)-\\([0-9]+\\): .*"
+     1 2 ,(if (fboundp 'compilation-fake-loc) '(3 . 4) 3))
+    ;; Info messages.  Not errors per se.
+    ,@(when (fboundp 'compilation-fake-loc)
+        `(;; Other GHCi patterns used in type errors.
+          ("^[ \t]+at \\(.+\\):\\([0-9]+\\):\\([0-9]+\\)-\\([0-9]+\\)$"
+           1 2 (3 . 4) 0)
+          ;; Foo.hs:318:80:
+          ;;     Ambiguous occurrence `Bar'
+          ;;     It could refer to either `Bar', defined at Zork.hs:311:5
+          ;;                  or `Bar', imported from Bars at Frob.hs:32:0-16
+          ;;                       (defined at Location.hs:97:5)
+          ("[ (]defined at \\(.+\\):\\([0-9]+\\):\\([0-9]+\\))?$" 1 2 3 0)
+          ("imported from .* at \\(.+\\):\\([0-9]+\\):\\([0-9]+\\)-\\([0-9]+\\)$"
+           1 2 (3 . 4) 0)
+          ;; Info xrefs.
+          (,inferior-haskell-info-xref-re 1 2 (3 . 4) 0))))
+  "Regexps for error messages generated by inferior Haskell processes.
+The format should be the same as for `compilation-error-regexp-alist'.")
+
+(defconst haskell-prompt-regexp
+  ;; Why the backslash in [\\._[:alnum:]]?
+  "^\\*?[[:upper:]][\\._[:alnum:]]*\\(?: \\*?[[:upper:]][\\._[:alnum:]]*\\)*\\( λ\\)?> \\|^λ?> $")
+
+;;; TODO
+;;; -> Make font lock work for strings, directories, hyperlinks
+;;; -> Make font lock work for key words???
+
+(defvar inf-haskell-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map "\C-c\C-d" 'comint-kill-subjob)
+    map))
+
+(defvaralias 'inferior-haskell-mode-map 'inf-haskell-map)
+
+(define-derived-mode inferior-haskell-mode comint-mode "Inf-Haskell"
+  "Major mode for interacting with an inferior Haskell process."
+  :group 'inferior-haskell
+  (setq-local comint-prompt-regexp haskell-prompt-regexp)
+
+  (setq-local paragraph-start haskell-prompt-regexp)
+
+  (setq-local comint-input-autoexpand nil)
+  (setq-local comint-prompt-read-only t)
+
+  ;; Setup directory tracking.
+  (setq-local shell-cd-regexp ":cd")
+  (condition-case nil
+      (shell-dirtrack-mode 1)
+    (error      ;The minor mode function may not exist or not accept an arg.
+     (setq-local shell-dirtrackp t)
+     (add-hook 'comint-input-filter-functions 'shell-directory-tracker
+               nil 'local)))
+
+  ;; Setup `compile' support so you can just use C-x ` and friends.
+  (setq-local compilation-error-regexp-alist inferior-haskell-error-regexp-alist)
+  (setq-local compilation-first-column 0) ;GHCI counts from 0.
+  (if (and (not (boundp 'minor-mode-overriding-map-alist))
+           (fboundp 'compilation-shell-minor-mode))
+      ;; If we can't remove compilation-minor-mode bindings, at least try to
+      ;; use compilation-shell-minor-mode, so there are fewer
+      ;; annoying bindings.
+      (compilation-shell-minor-mode 1)
+    ;; Else just use compilation-minor-mode but without its bindings because
+    ;; things like mouse-2 are simply too annoying.
+    (compilation-minor-mode 1)
+    (let ((map (make-sparse-keymap)))
+      (dolist (keys '([menu-bar] [follow-link]))
+        ;; Preserve some of the bindings.
+        (define-key map keys (lookup-key compilation-minor-mode-map keys)))
+      (add-to-list 'minor-mode-overriding-map-alist
+                   (cons 'compilation-minor-mode map))))
+  (add-hook 'inferior-haskell-hook 'inferior-haskell-init))
+
+(defvar inferior-haskell-buffer nil
+  "The buffer in which the inferior process is running.")
+
+(defun inferior-haskell-start-process ()
+  "Start an inferior haskell process.
+With universal prefix \\[universal-argument], prompts for a COMMAND,
+otherwise uses `haskell-program-name-with-args'.
+It runs the hook `inferior-haskell-hook' after starting the process and
+setting up the inferior-haskell buffer."
+  (let ((command (haskell-program-name-with-args)))
+    (setq default-directory inferior-haskell-root-dir)
+    (setq inferior-haskell-buffer
+          (apply 'make-comint "haskell" (car command) nil (cdr command)))
+    (with-current-buffer inferior-haskell-buffer
+      (inferior-haskell-mode)
+      (run-hooks 'inferior-haskell-hook))))
+
+(defun inferior-haskell-process ()
+  "Restart if not present."
+  (cond ((and (buffer-live-p inferior-haskell-buffer)
+              (comint-check-proc inferior-haskell-buffer))
+         (get-buffer-process inferior-haskell-buffer))
+        (t (inferior-haskell-start-process)
+           (inferior-haskell-process))))
+
+;;;###autoload
+(defalias 'run-haskell 'switch-to-haskell)
+;;;###autoload
+(defun switch-to-haskell ()
+  "Show the inferior-haskell buffer.  Start the process if needed."
+  (interactive)
+  (let ((proc (inferior-haskell-process)))
+    (pop-to-buffer-same-window (process-buffer proc))))
+
+(defvar inferior-haskell-result-history nil)
+
+(defvar haskell-next-input ""
+  "This is a temporary variable to store the intermediate results while
+`accecpt-process-output' with `haskell-extract-exp'")
+
+(defun haskell-extract-exp (str)
+  (setq haskell-next-input (concat haskell-next-input str))
+  (if (with-temp-buffer
+        (insert haskell-next-input)
+        (re-search-backward haskell-prompt-regexp nil t 1))
+      (progn
+        (push (substring haskell-next-input
+                         0
+                         (1- (with-temp-buffer
+                               (insert haskell-next-input)
+                               (re-search-backward haskell-prompt-regexp nil t 1))))
+              inferior-haskell-result-history)
+        (setq haskell-next-input ""))
+    ""))
+
+(defun inferior-haskell-no-result-return (strg)
+  (let ((proc (inferior-haskell-process)))
+    (with-local-quit
+      (progn
+        (add-to-list 'comint-preoutput-filter-functions
+                     (lambda (output)
+                       (haskell-extract-exp output)))
+        (process-send-string proc strg)
+        (accept-process-output proc)
+        (sit-for 0.1)
+        (setq comint-preoutput-filter-functions nil)))))
+
+(defun inferior-haskell-get-result (inf-expr)
+  "Submit the expression `inf-expr' to ghci and read the result."
+  (let* ((times 5))
+    (inferior-haskell-no-result-return (concat inf-expr "\n"))
+    (while (and (> times 0)
+                (not (stringp (car inferior-haskell-result-history))))
+      (setq times (1- times))
+      (inferior-haskell-no-result-return (concat inf-expr "\n")))
+    (haskell-string-chomp (car inferior-haskell-result-history))))
+
+(defun inferior-haskell-init ()
+  "The first thing run while initalizing inferior-haskell-buffer"
+  (with-local-quit
+    (with-current-buffer inferior-haskell-buffer
+      (process-send-string (inferior-haskell-process) "\n")
+      (accept-process-output (inferior-haskell-process))
+      (sit-for 0.1))))
+
+(defvar haskell-set+c-p nil
+  "t if `:set +c` else nil")
+
+(defun haskell-set+c ()
+  "set `:set +c` is not already set"
+  (if (not haskell-set+c-p)
+      (inferior-haskell-get-result ":set +c")))
+
+(provide 'inf-haskell)
+
+;;; inf-haskell.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/inf-haskell.elc b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/inf-haskell.elc
new file mode 100644
index 0000000000..91bd9d4d03
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/inf-haskell.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/logo.svg b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/logo.svg
new file mode 100644
index 0000000000..401e5990ec
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/logo.svg
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="481.8897pt" height="340.1574pt" viewBox="0 0 481.8897 340.1574" version="1.1">
+<defs>
+<clipPath id="clip1">
+  <path d="M 0 340.15625 L 481.890625 340.15625 L 481.890625 0 L 0 0 L 0 340.15625 Z M 0 340.15625 "/>
+</clipPath>
+</defs>
+<g id="surface0">
+<g clip-path="url(#clip1)" clip-rule="nonzero">
+<path style=" stroke:none;fill-rule: nonzero; fill: rgb(40%,40%,40%); fill-opacity: 1;" d="M 0 340.15625 L 113.386719 170.078125 L 0 0 L 85.039062 0 L 198.425781 170.078125 L 85.039062 340.15625 L 0 340.15625 Z M 0 340.15625 "/>
+<path style=" stroke:none;fill-rule: nonzero; fill: rgb(60%,60%,60%); fill-opacity: 1;" d="M 113.386719 340.15625 L 226.773438 170.078125 L 113.386719 0 L 198.425781 0 L 425.195312 340.15625 L 340.15625 340.15625 L 269.292969 233.859375 L 198.425781 340.15625 L 113.386719 340.15625 Z M 113.386719 340.15625 "/>
+<path style=" stroke:none;fill-rule: nonzero; fill: rgb(40%,40%,40%); fill-opacity: 1;" d="M 387.402344 240.945312 L 349.609375 184.253906 L 481.890625 184.25 L 481.890625 240.945312 L 387.402344 240.945312 Z M 387.402344 240.945312 "/>
+<path style=" stroke:none;fill-rule: nonzero; fill: rgb(40%,40%,40%); fill-opacity: 1;" d="M 330.710938 155.90625 L 292.914062 99.214844 L 481.890625 99.210938 L 481.890625 155.90625 L 330.710938 155.90625 Z M 330.710938 155.90625 "/>
+</g>
+</g>
+</svg>
diff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/w3m-haddock.el b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/w3m-haddock.el
new file mode 100644
index 0000000000..ee6ce43722
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/w3m-haddock.el
@@ -0,0 +1,190 @@
+;;; -*- lexical-binding: t -*-
+;;; w3m-haddock.el --- Make browsing haddocks with w3m-mode better.
+
+;; Copyright (C) 2014 Chris Done
+
+;; Author: Chris Done <chrisdone@gmail.com>
+
+;; This file is not part of GNU Emacs.
+
+;; This file 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, or (at your option)
+;; any later version.
+
+;; This file 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; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+(require 'cl-lib)
+(require 'haskell-mode)
+(require 'haskell-font-lock)
+
+(declare-function w3m-buffer-title "ext:w3m")
+(declare-function w3m-browse-url "ext:w3m")
+(defvar w3m-current-url)
+
+(add-hook 'w3m-display-hook 'w3m-haddock-display)
+
+;;;###autoload
+(defface w3m-haddock-heading-face
+  '((((class color)) :inherit highlight))
+  "Face for quarantines."
+  :group 'haskell)
+
+(defcustom haskell-w3m-haddock-dirs
+  '("~/.cabal/share/doc/")
+  "The path to your cabal documentation dir. It should contain
+directories of package-name-x.x.
+
+You can rebind this if you're using hsenv by adding it to your
+.dir-locals.el in your project root. E.g.
+
+    ((haskell-mode . ((haskell-w3m-haddock-dirs . (\"/home/chris/Projects/foobar/.hsenv/cabal/share/doc\")))))
+
+"
+  :group 'haskell
+  :type 'list)
+
+(defvar w3m-haddock-entry-regex "^\\(\\(data\\|type\\) \\|[a-z].* :: \\)"
+  "Regex to match entry headings.")
+
+(defun haskell-w3m-open-haddock ()
+  "Open a haddock page in w3m."
+  (interactive)
+  (let* ((entries (cl-remove-if (lambda (s) (string= s ""))
+                                (apply 'append (mapcar (lambda (dir)
+                                                         (split-string (shell-command-to-string (concat "ls -1 " dir))
+
+                                                                       "\n"))
+                                                       haskell-w3m-haddock-dirs))))
+         (package-dir (ido-completing-read
+                       "Package: "
+                       entries)))
+    (cond
+     ((member package-dir entries)
+      (unless (cl-loop for dir in haskell-w3m-haddock-dirs
+                       when (w3m-haddock-find-index dir package-dir)
+                       do (progn (w3m-browse-url (w3m-haddock-find-index dir package-dir)
+                                                 t)
+                                 (cl-return t)))
+        (w3m-browse-url (concat "http://hackage.haskell.org/package/"
+                                package-dir)
+                        t)))
+     (t
+      (w3m-browse-url (concat "http://hackage.haskell.org/package/"
+                              package-dir)
+                      t)))))
+
+(defun w3m-haddock-find-index (dir package)
+  (let ((html-index (concat dir "/" package "/html/index.html"))
+        (index (concat dir "/" package "/index.html")))
+    (cond
+     ((file-exists-p html-index)
+      html-index)
+     ((file-exists-p index)
+      index))))
+
+(defun w3m-haddock-page-p ()
+  "Haddock general page?"
+  (save-excursion
+    (goto-char (point-max))
+    (forward-line -2)
+    (looking-at "[ ]*Produced by Haddock")))
+
+(defun w3m-haddock-source-p ()
+  "Haddock source page?"
+  (save-excursion
+    (goto-char (point-min))
+    (or (looking-at "Location: https?://hackage.haskell.org/package/.*/docs/src/")
+        (looking-at "Location: file://.*cabal/share/doc/.*/html/src/")
+        (looking-at "Location: .*src/.*.html$"))))
+
+(defun w3m-haddock-p ()
+  "Any haddock page?"
+  (or (w3m-haddock-page-p)
+      (w3m-haddock-source-p)))
+
+(defun w3m-haddock-find-tag ()
+  "Find a tag by jumping to the \"All\" index and doing a
+  search-forward."
+  (interactive)
+  (when (w3m-haddock-p)
+    (let ((ident (haskell-ident-at-point)))
+      (when ident
+        (w3m-browse-url
+         (replace-regexp-in-string "docs/.*" "docs/doc-index-All.html" w3m-current-url))
+        (search-forward ident)))))
+
+(defun w3m-haddock-display (_url)
+  "To be run by w3m's display hook. This takes a normal w3m
+  buffer containing hadddock documentation and reformats it to be
+  more usable and look like a dedicated documentation page."
+  (when (w3m-haddock-page-p)
+    (save-excursion
+      (goto-char (point-min))
+      (let ((inhibit-read-only t))
+        (delete-region (point)
+                       (line-end-position))
+        (w3m-haddock-next-heading)
+        ;; Start formatting entries
+        (while (looking-at w3m-haddock-entry-regex)
+          (when (w3m-haddock-valid-heading)
+            (w3m-haddock-format-heading))
+          (w3m-haddock-next-heading))))
+    (rename-buffer (concat "*haddock: " (w3m-buffer-title (current-buffer)) "*")))
+  (when (w3m-haddock-source-p)
+    (font-lock-mode -1)
+    (let ((n (line-number-at-pos)))
+      (save-excursion
+        (goto-char (point-min))
+        (forward-line 1)
+        (let ((text (buffer-substring (point)
+                                      (point-max)))
+              (inhibit-read-only t))
+          (delete-region (point)
+                         (point-max))
+          (insert
+           (haskell-fontify-as-mode text
+                                    'haskell-mode))))
+      (goto-char (point-min))
+      (forward-line (1- n)))))
+
+(defun w3m-haddock-format-heading ()
+  "Format a haddock entry."
+  (let ((o (make-overlay (line-beginning-position)
+                         (1- (save-excursion (w3m-haddock-header-end))))))
+    (overlay-put o 'face 'w3m-haddock-heading-face))
+  (let ((end (save-excursion
+               (w3m-haddock-next-heading)
+               (when (w3m-haddock-valid-heading)
+                 (point)))))
+    (when end
+      (save-excursion
+        (w3m-haddock-header-end)
+        (indent-rigidly (point)
+                        end
+                        4)))))
+
+(defun w3m-haddock-next-heading ()
+  "Go to the next heading, or end of the buffer."
+  (forward-line 1)
+  (or (search-forward-regexp w3m-haddock-entry-regex nil t 1)
+      (goto-char (point-max)))
+  (goto-char (line-beginning-position)))
+
+(defun w3m-haddock-valid-heading ()
+  "Is this a valid heading?"
+  (not (get-text-property (point) 'face)))
+
+(defun w3m-haddock-header-end ()
+  "Go to the end of the header."
+  (search-forward-regexp "\n[ \n]"))
+
+(provide 'w3m-haddock)
diff --git a/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/w3m-haddock.elc b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/w3m-haddock.elc
new file mode 100644
index 0000000000..391a591249
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/haskell-mode-20180601.143/w3m-haddock.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/ht-20180129.1434/ht-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/ht-20180129.1434/ht-autoloads.el
new file mode 100644
index 0000000000..b81c09a25f
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/ht-20180129.1434/ht-autoloads.el
@@ -0,0 +1,15 @@
+;;; ht-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil nil ("ht.el") (23377 61593 963740 506000))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; ht-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/ht-20180129.1434/ht-pkg.el b/configs/shared/emacs/.emacs.d/elpa/ht-20180129.1434/ht-pkg.el
new file mode 100644
index 0000000000..716a2a7192
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/ht-20180129.1434/ht-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "ht" "20180129.1434" "The missing hash table library for Emacs" '((dash "2.12.0")))
diff --git a/configs/shared/emacs/.emacs.d/elpa/ht-20180129.1434/ht.el b/configs/shared/emacs/.emacs.d/elpa/ht-20180129.1434/ht.el
new file mode 100644
index 0000000000..255c54fd99
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/ht-20180129.1434/ht.el
@@ -0,0 +1,296 @@
+;;; ht.el --- The missing hash table library for Emacs
+
+;; Copyright (C) 2013 Wilfred Hughes
+
+;; Author: Wilfred Hughes <me@wilfred.me.uk>
+;; Version: 2.3
+;; Package-Version: 20180129.1434
+;; Keywords: hash table, hash map, hash
+;; Package-Requires: ((dash "2.12.0"))
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; The missing hash table library for Emacs.
+;;
+;; See documentation at https://github.com/Wilfred/ht.el
+
+;;; Code:
+
+(require 'dash)
+
+(defmacro ht (&rest pairs)
+  "Create a hash table with the key-value pairs given.
+Keys are compared with `equal'.
+
+\(fn (KEY-1 VALUE-1) (KEY-2 VALUE-2) ...)"
+  (let* ((table-symbol (make-symbol "ht-temp"))
+         (assignments
+          (mapcar
+           (lambda (pair) `(ht-set! ,table-symbol ,@pair))
+           pairs)))
+    `(let ((,table-symbol (ht-create)))
+       ,@assignments
+       ,table-symbol)))
+
+(defsubst ht-set! (table key value)
+  "Associate KEY in TABLE with VALUE."
+  (puthash key value table)
+  nil)
+
+(defalias 'ht-set 'ht-set!)
+
+(defsubst ht-create (&optional test)
+  "Create an empty hash table.
+
+TEST indicates the function used to compare the hash
+keys.  Default is `equal'.  It can be `eq', `eql', `equal' or a
+user-supplied test created via `define-hash-table-test'."
+  (make-hash-table :test (or test 'equal)))
+
+(defun ht<-alist (alist &optional test)
+  "Create a hash table with initial values according to ALIST.
+
+TEST indicates the function used to compare the hash
+keys.  Default is `equal'.  It can be `eq', `eql', `equal' or a
+user-supplied test created via `define-hash-table-test'."
+  (let ((h (ht-create test)))
+    ;; the first key-value pair in an alist gets precedence, so we
+    ;; start from the end of the list:
+    (dolist (pair (reverse alist) h)
+      (let ((key (car pair))
+            (value (cdr pair)))
+        (ht-set! h key value)))))
+
+(defalias 'ht-from-alist 'ht<-alist)
+
+(defun ht<-plist (plist &optional test)
+  "Create a hash table with initial values according to PLIST.
+
+TEST indicates the function used to compare the hash
+keys.  Default is `equal'.  It can be `eq', `eql', `equal' or a
+user-supplied test created via `define-hash-table-test'."
+  (let ((h (ht-create test)))
+    (dolist (pair (nreverse (-partition 2 plist)) h)
+      (let ((key (car pair))
+            (value (cadr pair)))
+        (ht-set! h key value)))))
+
+(defalias 'ht-from-plist 'ht<-plist)
+
+(defsubst ht-get (table key &optional default)
+  "Look up KEY in TABLE, and return the matching value.
+If KEY isn't present, return DEFAULT (nil if not specified)."
+  (gethash key table default))
+
+(defun ht-get* (table &rest keys)
+  "Look up KEYS in nested hash tables, starting with TABLE.
+The lookup for each key should return another hash table, except
+for the final key, which may return any value."
+  (if (cdr keys)
+      (apply #'ht-get* (ht-get table (car keys)) (cdr keys))
+    (ht-get table (car keys))))
+
+(defun ht-update! (table from-table)
+  "Update TABLE according to every key-value pair in FROM-TABLE."
+  (maphash
+   (lambda (key value) (puthash key value table))
+   from-table)
+  nil)
+
+(defalias 'ht-update 'ht-update!)
+
+(defun ht-merge (&rest tables)
+  "Crete a new tables that includes all the key-value pairs from TABLES.
+If multiple have tables have the same key, the value in the last
+table is used."
+  (let ((merged (ht-create)))
+    (mapc (lambda (table) (ht-update! merged table)) tables)
+    merged))
+
+(defsubst ht-remove! (table key)
+  "Remove KEY from TABLE."
+  (remhash key table))
+
+(defalias 'ht-remove 'ht-remove!)
+
+(defsubst ht-clear! (table)
+  "Remove all keys from TABLE."
+  (clrhash table)
+  nil)
+
+(defalias 'ht-clear 'ht-clear!)
+
+(defun ht-map (function table)
+  "Apply FUNCTION to each key-value pair of TABLE, and make a list of the results.
+FUNCTION is called with two arguments, KEY and VALUE."
+  (let (results)
+    (maphash
+     (lambda (key value)
+       (push (funcall function key value) results))
+     table)
+    results))
+
+(defmacro ht-amap (form table)
+  "Anaphoric version of `ht-map'.
+For every key-value pair in TABLE, evaluate FORM with the
+variables KEY and VALUE bound."
+  `(ht-map (lambda (key value) ,form) ,table))
+
+(defun ht-keys (table)
+  "Return a list of all the keys in TABLE."
+  (ht-amap key table))
+
+(defun ht-values (table)
+  "Return a list of all the values in TABLE."
+  (ht-amap value table))
+
+(defun ht-items (table)
+  "Return a list of two-element lists '(key value) from TABLE."
+  (ht-amap (list key value) table))
+
+(defalias 'ht-each 'maphash
+  "Apply FUNCTION to each key-value pair of TABLE.
+Returns nil, used for side-effects only.")
+
+(defmacro ht-aeach (form table)
+  "Anaphoric version of `ht-each'.
+For every key-value pair in TABLE, evaluate FORM with the
+variables key and value bound."
+  `(ht-each (lambda (key value) ,form) ,table))
+
+(defun ht-select-keys (table keys)
+  "Return a copy of TABLE with only the specified KEYS."
+  (let (result)
+    (setq result (make-hash-table :test (hash-table-test table)))
+    (dolist (key keys result)
+      (if (not (equal (gethash key table 'key-not-found) 'key-not-found))
+          (puthash key (gethash key table) result)))))
+
+(defun ht->plist (table)
+  "Return a flat list '(key1 value1 key2 value2...) from TABLE.
+
+Note that hash tables are unordered, so this cannot be an exact
+inverse of `ht<-plist'.  The following is not guaranteed:
+
+\(let ((data '(a b c d)))
+  (equalp data
+          (ht->plist (ht<-plist data))))"
+  (apply 'append (ht-items table)))
+
+(defalias 'ht-to-plist 'ht->plist)
+
+(defsubst ht-copy (table)
+  "Return a shallow copy of TABLE (keys and values are shared)."
+  (copy-hash-table table))
+
+(defun ht->alist (table)
+  "Return a list of two-element lists '(key . value) from TABLE.
+
+Note that hash tables are unordered, so this cannot be an exact
+inverse of `ht<-alist'.  The following is not guaranteed:
+
+\(let ((data '((a . b) (c . d))))
+  (equalp data
+          (ht->alist (ht<-alist data))))"
+  (ht-amap (cons key value) table))
+
+(defalias 'ht-to-alist 'ht->alist)
+
+(defalias 'ht? 'hash-table-p)
+
+(defalias 'ht-p 'hash-table-p)
+
+(defun ht-contains? (table key)
+  "Return 't if TABLE contains KEY."
+  (not (eq (ht-get table key 'ht--not-found) 'ht--not-found)))
+
+(defalias 'ht-contains-p 'ht-contains?)
+
+(defsubst ht-size (table)
+  "Return the actual number of entries in TABLE."
+  (hash-table-count table))
+
+(defsubst ht-empty? (table)
+  "Return true if the actual number of entries in TABLE is zero."
+  (zerop (ht-size table)))
+
+(defun ht-select (function table)
+  "Return a hash table containing all entries in TABLE for which
+FUNCTION returns a truthy value.
+
+FUNCTION is called with two arguments, KEY and VALUE."
+  (let ((results (ht-create)))
+    (ht-each
+     (lambda (key value)
+       (when (funcall function key value)
+         (ht-set! results key value)))
+     table)
+    results))
+
+(defun ht-reject (function table)
+  "Return a hash table containing all entries in TABLE for which
+FUNCTION returns a falsy value.
+
+FUNCTION is called with two arguments, KEY and VALUE."
+  (let ((results (ht-create)))
+    (ht-each
+     (lambda (key value)
+       (unless (funcall function key value)
+         (ht-set! results key value)))
+     table)
+    results))
+
+(defun ht-reject! (function table)
+  "Delete entries from TABLE for which FUNCTION returns a falsy value.
+
+FUNCTION is called with two arguments, KEY and VALUE."
+  (ht-each
+   (lambda (key value)
+     (when (funcall function key value)
+       (remhash key table)))
+   table)
+  nil)
+
+(defalias 'ht-delete-if 'ht-reject!)
+
+(defun ht-find (function table)
+  "Return (key, value) from TABLE for which FUNCTION returns a truthy value.
+Return nil otherwise.
+
+FUNCTION is called with two arguments, KEY and VALUE."
+  (catch 'break
+    (ht-each
+     (lambda (key value)
+       (when (funcall function key value)
+         (throw 'break (list key value))))
+     table)))
+
+(defun ht-equal? (table1 table2)
+  "Return t if TABLE1 and TABLE2 have the same keys and values.
+Does not compare equality predicates."
+  (let ((keys1 (ht-keys table1))
+        (keys2 (ht-keys table2))
+        (sentinel (make-symbol "ht-sentinel")))
+    (and (equal (length keys1) (length keys2))
+         (--all?
+          (equal (ht-get table1 it)
+                 (ht-get table2 it sentinel))
+          keys1))))
+
+(defalias 'ht-equal-p 'ht-equal?)
+
+(provide 'ht)
+;;; ht.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/ht-20180129.1434/ht.elc b/configs/shared/emacs/.emacs.d/elpa/ht-20180129.1434/ht.elc
new file mode 100644
index 0000000000..40011165cf
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/ht-20180129.1434/ht.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/intero-20180703.18/intero-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/intero-20180703.18/intero-autoloads.el
new file mode 100644
index 0000000000..48e30f989d
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/intero-20180703.18/intero-autoloads.el
@@ -0,0 +1,60 @@
+;;; intero-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "intero" "intero.el" (23377 61617 969126 355000))
+;;; Generated autoloads from intero.el
+
+(autoload 'intero-mode "intero" "\
+Minor mode for Intero.
+
+\\{intero-mode-map}
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'intero-mode-whitelist "intero" "\
+Run intero-mode when the current project is in `intero-whitelist'.
+
+\(fn)" t nil)
+
+(autoload 'intero-mode-blacklist "intero" "\
+Run intero-mode unless the current project is in `intero-blacklist'.
+
+\(fn)" t nil)
+
+(defvar intero-global-mode nil "\
+Non-nil if Intero-Global mode is enabled.
+See the `intero-global-mode' command
+for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `intero-global-mode'.")
+
+(custom-autoload 'intero-global-mode "intero" nil)
+
+(autoload 'intero-global-mode "intero" "\
+Toggle Intero mode in all buffers.
+With prefix ARG, enable Intero-Global mode if ARG is positive;
+otherwise, disable it.  If called from Lisp, enable the mode if
+ARG is omitted or nil.
+
+Intero mode is enabled in all buffers where
+`intero-mode-maybe' would do it.
+See `intero-mode' for more information on Intero mode.
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'intero-highlight-uses-mode "intero" "\
+Minor mode for highlighting and jumping between uses.
+
+\(fn &optional ARG)" t nil)
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; intero-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/intero-20180703.18/intero-pkg.el b/configs/shared/emacs/.emacs.d/elpa/intero-20180703.18/intero-pkg.el
new file mode 100644
index 0000000000..2cd2a5bd92
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/intero-20180703.18/intero-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "intero" "20180703.18" "Complete development mode for Haskell" '((flycheck "0.25") (company "0.8") (emacs "24.4") (haskell-mode "13.0")))
diff --git a/configs/shared/emacs/.emacs.d/elpa/intero-20180703.18/intero.el b/configs/shared/emacs/.emacs.d/elpa/intero-20180703.18/intero.el
new file mode 100644
index 0000000000..0553b63073
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/intero-20180703.18/intero.el
@@ -0,0 +1,3648 @@
+;;; intero.el --- Complete development mode for Haskell
+
+;; Copyright (c) 2016 Chris Done
+;; Copyright (c) 2016 Steve Purcell
+;; Copyright (C) 2016 Артур Файзрахманов
+;; Copyright (c) 2015 Athur Fayzrakhmanov
+;; Copyright (C) 2015 Gracjan Polak
+;; Copyright (c) 2013 Herbert Valerio Riedel
+;; Copyright (c) 2007 Stefan Monnier
+
+;; Author: Chris Done <chrisdone@fpcomplete.com>
+;; Maintainer: Chris Done <chrisdone@fpcomplete.com>
+;; URL: https://github.com/commercialhaskell/intero
+;; Package-Version: 20180703.18
+;; Created: 3rd June 2016
+;; Version: 0.1.13
+;; Keywords: haskell, tools
+;; Package-Requires: ((flycheck "0.25") (company "0.8") (emacs "24.4") (haskell-mode "13.0"))
+
+;; This file 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, or (at your option)
+;; any later version.
+
+;; This file 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; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+;;
+;; Mode that enables:
+;;
+;; * Flycheck type checking ✓
+;; * Company mode completion ✓
+;; * Go to definition ✓
+;; * Type of selection ✓
+;; * Info ✓
+;; * REPL ✓
+;; * Apply suggestions (extensions, imports, etc.) ✓
+;; * Find uses
+;; * Completion of stack targets ✓
+;; * List all types in all expressions
+;; * Import management
+;; * Dependency management
+
+;;; Code:
+
+(require 'flycheck)
+(require 'json)
+(require 'warnings)
+(require 'cl-lib)
+(require 'company)
+(require 'comint)
+(require 'widget)
+(require 'eldoc)
+(eval-when-compile
+  (require 'wid-edit))
+(require 'tramp)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Configuration
+
+(defgroup intero nil
+  "Complete development mode for Haskell"
+  :group 'haskell)
+
+(defcustom intero-package-version
+  (cl-case system-type
+    ;; Until <https://github.com/haskell/network/issues/313> is fixed:
+    (windows-nt "0.1.32")
+    (cygwin "0.1.32")
+    (t "0.1.32"))
+  "Package version to auto-install.
+
+This version does not necessarily have to be the latest version
+of intero published on Hackage.  Sometimes there are changes to
+Intero which have no use for the Emacs mode.  It is only bumped
+when the Emacs mode actually requires newer features from the
+intero executable, otherwise we force our users to upgrade
+pointlessly."
+  :group 'intero
+  :type 'string)
+
+(defcustom intero-repl-no-load
+  t
+  "Pass --no-load when starting the repl.
+This causes it to skip loading the files from the selected target."
+  :group 'intero
+  :type 'boolean)
+
+(defcustom intero-repl-no-build
+  t
+  "Pass --no-build when starting the repl.
+This causes it to skip building the target."
+  :group 'intero
+  :type 'boolean)
+
+(defcustom intero-debug nil
+  "Show debug output."
+  :group 'intero
+  :type 'boolean)
+
+(defcustom intero-whitelist
+  nil
+  "Projects to whitelist.
+
+It should be a list of directories.
+
+To use this, use the following mode hook:
+  (add-hook 'haskell-mode-hook 'intero-mode-whitelist)
+or use `intero-global-mode' and add \"/\" to `intero-blacklist'."
+  :group 'intero
+  :type 'string)
+
+(defcustom intero-blacklist
+  nil
+  "Projects to blacklist.
+
+It should be a list of directories.
+
+To use this, use the following mode hook:
+  (add-hook 'haskell-mode-hook 'intero-mode-blacklist)
+or use `intero-global-mode'."
+  :group 'intero
+  :type 'string)
+
+(defcustom intero-stack-executable
+  "stack"
+  "Name or path to the Stack executable to use."
+  :group 'intero
+  :type 'string)
+
+(defcustom intero-pop-to-repl
+  t
+  "When non-nil, pop to REPL when code is sent to it."
+  :group 'intero
+  :type 'boolean)
+
+(defcustom intero-extra-ghc-options nil
+  "Extra GHC options to pass to intero executable.
+
+For example, this variable can be used to run intero with extra
+warnings and perform more checks via flycheck error reporting."
+  :group 'intero
+  :type '(repeat string))
+
+(defcustom intero-extra-ghci-options nil
+  "Extra options to pass to GHCi when running `intero-repl'.
+
+For example, this variable can be used to enable some ghci extensions
+by default."
+  :group 'intero
+  :type '(repeat string))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Modes
+
+(defvar intero-mode-map (make-sparse-keymap)
+  "Intero minor mode's map.")
+
+(defvar-local intero-lighter " Intero"
+  "Lighter for the intero minor mode.")
+
+;;;###autoload
+(define-minor-mode intero-mode
+  "Minor mode for Intero.
+
+\\{intero-mode-map}"
+  :lighter intero-lighter
+  :keymap intero-mode-map
+  (when (bound-and-true-p interactive-haskell-mode)
+    (when (fboundp 'interactive-haskell-mode)
+      (message "Disabling interactive-haskell-mode ...")
+      (interactive-haskell-mode -1)))
+  (if intero-mode
+      (progn
+        (intero-flycheck-enable)
+        (add-hook 'completion-at-point-functions 'intero-completion-at-point nil t)
+        (add-to-list (make-local-variable 'company-backends) 'intero-company)
+        (company-mode)
+        (setq-local company-minimum-prefix-length 1)
+        (unless eldoc-documentation-function
+          (setq-local eldoc-documentation-function #'ignore))
+        (add-function :before-until (local 'eldoc-documentation-function) #'intero-eldoc)
+        )
+    (progn
+      (remove-function (local 'eldoc-documentation-function) #'intero-eldoc)
+      (message "Intero mode disabled."))))
+
+;;;###autoload
+(defun intero-mode-whitelist ()
+  "Run intero-mode when the current project is in `intero-whitelist'."
+  (interactive)
+  (when (intero-directories-contain-file (buffer-file-name) intero-whitelist)
+    (intero-mode)))
+
+;;;###autoload
+(defun intero-mode-blacklist ()
+  "Run intero-mode unless the current project is in `intero-blacklist'."
+  (interactive)
+  (unless (intero-directories-contain-file (buffer-file-name) intero-blacklist)
+    (intero-mode)))
+
+(dolist (f '(intero-mode-whitelist intero-mode-blacklist))
+  (make-obsolete
+   f
+   "use `intero-global-mode', which honours `intero-whitelist' and `intero-blacklist'."
+   "2017-05-13"))
+
+
+(define-key intero-mode-map (kbd "C-c C-t") 'intero-type-at)
+(define-key intero-mode-map (kbd "M-?") 'intero-uses-at)
+(define-key intero-mode-map (kbd "C-c C-i") 'intero-info)
+(define-key intero-mode-map (kbd "M-.") 'intero-goto-definition)
+(define-key intero-mode-map (kbd "C-c C-l") 'intero-repl-load)
+(define-key intero-mode-map (kbd "C-c C-c") 'intero-repl-eval-region)
+(define-key intero-mode-map (kbd "C-c C-z") 'intero-repl)
+(define-key intero-mode-map (kbd "C-c C-r") 'intero-apply-suggestions)
+(define-key intero-mode-map (kbd "C-c C-e") 'intero-expand-splice-at-point)
+
+(defun intero-directories-contain-file (file dirs)
+  "Return non-nil if FILE is contained in at least one of DIRS."
+  (and (not (null file))
+       (cl-some (lambda (directory)
+                  (file-in-directory-p file directory))
+                dirs)))
+
+(defun intero-mode-maybe ()
+  "Enable `intero-mode' in all Haskell mode buffers.
+The buffer's filename (or working directory) is checked against
+`intero-whitelist' and `intero-blacklist'.  If both the whitelist
+and blacklist match, then the whitelist entry wins, and
+`intero-mode' is enabled."
+  (when (and (derived-mode-p 'haskell-mode)
+             (let* ((file (or (buffer-file-name) default-directory))
+                    (blacklisted (intero-directories-contain-file
+                                  file intero-blacklist))
+                    (whitelisted (intero-directories-contain-file
+                                  file intero-whitelist)))
+               (or whitelisted (not blacklisted))))
+    (intero-mode 1)))
+
+;;;###autoload
+(define-globalized-minor-mode intero-global-mode
+  intero-mode intero-mode-maybe
+  :require 'intero)
+
+(define-obsolete-function-alias 'global-intero-mode 'intero-global-mode)
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Global variables/state
+
+(defvar intero-temp-file-buffer-mapping
+  (make-hash-table)
+  "A mapping from file names to buffers.")
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Buffer-local variables/state
+
+(defvar-local intero-callbacks (list)
+  "List of callbacks waiting for output.
+LIST is a FIFO.")
+
+(defvar-local intero-async-network-cmd nil
+  "Command to send to the async network process when we connect.")
+
+(defvar-local intero-async-network-connected nil
+  "Did we successfully connect to the intero service?")
+
+(defvar-local intero-async-network-state nil
+  "State to pass to the callback once we get a response.")
+
+(defvar-local intero-async-network-worker nil
+  "The worker we're associated with.")
+
+(defvar-local intero-async-network-callback nil
+  "Callback to call when the connection is closed.")
+
+(defvar-local intero-arguments (list)
+  "Arguments used to call the stack process.")
+
+(defvar-local intero-targets (list)
+  "Targets used for the stack process.")
+
+(defvar-local intero-repl-last-loaded nil
+  "Last loaded module in the REPL.")
+
+(defvar-local intero-repl-send-after-load nil
+  "Send a command after every load.")
+
+(defvar-local intero-start-time nil
+  "Start time of the stack process.")
+
+(defvar-local intero-source-buffer (list)
+  "Buffer from which Intero was first requested to start.")
+
+(defvar-local intero-project-root nil
+  "The project root of the current buffer.")
+
+(defvar-local intero-package-name nil
+  "The package name associated with the current buffer.")
+
+(defvar-local intero-deleting nil
+  "The process of the buffer is being deleted.")
+
+(defvar-local intero-give-up nil
+  "When non-nil, give up trying to start the backend.
+A true value indicates that the backend could not start, or could
+not be installed.  The user will have to manually run
+`intero-restart' or `intero-targets' to destroy the buffer and
+create a fresh one without this variable enabled.")
+
+(defvar-local intero-try-with-build nil
+  "Try starting intero without --no-build.
+This is slower, but will build required dependencies.")
+
+(defvar-local intero-starting nil
+  "When non-nil, indicates that the intero process starting up.")
+
+(defvar-local intero-service-port nil
+  "Port that the intero process is listening on for asynchronous commands.")
+
+(defvar-local intero-hoogle-port nil
+  "Port that hoogle server is listening on.")
+
+(defvar-local intero-suggestions nil
+  "Auto actions for the buffer.")
+
+(defvar-local intero-extensions nil
+  "Extensions supported by the compiler.")
+
+(defvar-local intero-ghc-version nil
+  "GHC version used by the project.")
+
+(defvar-local intero-buffer-host nil
+  "The hostname of the box hosting the intero process for the current buffer.")
+
+(defvar-local intero-stack-yaml nil
+  "The yaml file that intero should tell stack to use. When nil,
+  intero relies on stack's default, usually the 'stack.yaml' in
+  the project root.")
+
+(defun intero-inherit-local-variables (buffer)
+  "Make the current buffer inherit values of certain local variables from BUFFER."
+  (let ((variables '(intero-stack-executable
+                     intero-repl-no-build
+                     intero-repl-no-load
+                     intero-stack-yaml
+                     ;; TODO: shouldn’t more of the above be here?
+                     )))
+    (cl-loop for v in variables do
+             (set (make-local-variable v) (buffer-local-value v buffer)))))
+
+(defmacro intero-with-temp-buffer (&rest body)
+  "Run BODY in `with-temp-buffer', but inherit certain local variables from the current buffer first."
+  (declare (indent 0) (debug t))
+  `(let ((initial-buffer (current-buffer)))
+     (with-temp-buffer
+       (intero-inherit-local-variables initial-buffer)
+       ,@body)))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Interactive commands
+
+(defun intero-add-package (package)
+  "Add a dependency on PACKAGE to the currently-running project backend."
+  (interactive "sPackage: ")
+  (intero-blocking-call 'backend (concat ":set -package " package))
+  (flycheck-buffer))
+
+(defun intero-toggle-debug ()
+  "Toggle debugging mode on/off."
+  (interactive)
+  (setq intero-debug (not intero-debug))
+  (message "Intero debugging is: %s" (if intero-debug "ON" "OFF")))
+
+(defun intero-list-buffers ()
+  "List hidden process buffers created by intero.
+
+You can use this to kill them or look inside."
+  (interactive)
+  (let ((buffers (cl-remove-if-not
+                  (lambda (buffer)
+                    (string-match-p " intero:" (buffer-name buffer)))
+                  (buffer-list))))
+    (if buffers
+        (display-buffer
+         (list-buffers-noselect
+          nil
+          buffers))
+      (error "There are no Intero process buffers"))))
+
+(defun intero-cd ()
+  "Change directory in the backend process."
+  (interactive)
+  (intero-async-call
+   'backend
+   (concat ":cd "
+           (read-directory-name "Change Intero directory: "))))
+
+(defun intero-fontify-expression (expression)
+  "Return a haskell-fontified version of EXPRESSION."
+  (intero-with-temp-buffer
+    (when (fboundp 'haskell-mode)
+      (let ((flycheck-checkers nil)
+            (haskell-mode-hook nil))
+        (haskell-mode)))
+    (insert expression)
+    (if (fboundp 'font-lock-ensure)
+        (font-lock-ensure)
+      (font-lock-fontify-buffer))
+    (buffer-string)))
+
+(defun intero-uses-at ()
+  "Highlight where the identifier at point is used."
+  (interactive)
+  (let* ((thing (intero-thing-at-point))
+         (uses (split-string (apply #'intero-get-uses-at thing)
+                             "\n"
+                             t)))
+    (unless (null uses)
+      (let ((highlighted nil))
+        (cl-loop
+         for use in uses
+         when (string-match
+               "\\(.*?\\):(\\([0-9]+\\),\\([0-9]+\\))-(\\([0-9]+\\),\\([0-9]+\\))$"
+               use)
+         do (let* ((returned-file (match-string 1 use))
+                   (loaded-file (intero-extend-path-by-buffer-host returned-file))
+                   (sline (string-to-number (match-string 2 use)))
+                   (scol (string-to-number (match-string 3 use)))
+                   (eline (string-to-number (match-string 4 use)))
+                   (ecol (string-to-number (match-string 5 use)))
+                   (start (save-excursion (goto-char (point-min))
+                                          (forward-line (1- sline))
+                                          (forward-char (1- scol))
+                                          (point))))
+              (when (intero-temp-file-p loaded-file)
+                (unless highlighted
+                  (intero-highlight-uses-mode))
+                (setq highlighted t)
+                (intero-highlight-uses-mode-highlight
+                 start
+                 (save-excursion (goto-char (point-min))
+                                 (forward-line (1- eline))
+                                 (forward-char (1- ecol))
+                                 (point))
+                 (= start (car thing))))))))))
+
+(defun intero-type-at (insert)
+  "Get the type of the thing or selection at point.
+
+With prefix argument INSERT, inserts the type above the current
+line as a type signature."
+  (interactive "P")
+  (let* ((thing (intero-thing-at-point))
+         (origin-buffer (current-buffer))
+         (origin (buffer-name))
+         (package (intero-package-name))
+         (ty (apply #'intero-get-type-at thing))
+         (string (buffer-substring (nth 0 thing) (nth 1 thing))))
+    (if insert
+        (save-excursion
+          (goto-char (line-beginning-position))
+          (insert (intero-fontify-expression ty) "\n"))
+      (with-current-buffer (intero-help-buffer)
+        (let ((buffer-read-only nil)
+              (help-string
+               (concat
+                (intero-fontify-expression string)
+                " in `"
+                (propertize origin 'origin-buffer origin-buffer)
+                "'"
+                " (" package ")"
+                "\n\n"
+                (intero-fontify-expression ty))))
+          (erase-buffer)
+          (intero-help-push-history origin-buffer help-string)
+          (intero-help-pagination)
+          (insert help-string)
+          (goto-char (point-min))))
+      (message
+       "%s" (intero-fontify-expression ty)))))
+
+(defun intero-info (ident)
+  "Get the info of the thing with IDENT at point."
+  (interactive (list (intero-ident-at-point)))
+  (let ((origin-buffer (current-buffer))
+        (package (intero-package-name))
+        (info (intero-get-info-of ident))
+        (origin (buffer-name)))
+    (with-current-buffer (pop-to-buffer (intero-help-buffer))
+      (let ((buffer-read-only nil)
+            (help-string
+             (concat
+              (intero-fontify-expression ident)
+              " in `"
+              (propertize origin 'origin-buffer origin-buffer)
+              "'"
+              " (" package ")"
+              "\n\n"
+              (intero-fontify-expression info))))
+        (erase-buffer)
+        (intero-help-push-history origin-buffer help-string)
+        (intero-help-pagination)
+        (insert help-string)
+        (goto-char (point-min))))))
+
+(defun intero-goto-definition ()
+  "Jump to the definition of the thing at point.
+Returns nil when unable to find definition."
+  (interactive)
+  (let ((result (apply #'intero-get-loc-at (intero-thing-at-point))))
+
+    (if (not (string-match "\\(.*?\\):(\\([0-9]+\\),\\([0-9]+\\))-(\\([0-9]+\\),\\([0-9]+\\))$"
+                       result))
+        (message "%s" result)
+      (if (fboundp 'xref-push-marker-stack) ;; Emacs 25
+          (xref-push-marker-stack)
+        (with-no-warnings
+          (ring-insert find-tag-marker-ring (point-marker))))
+      (let* ((returned-file (match-string 1 result))
+             (line (string-to-number (match-string 2 result)))
+             (col (string-to-number (match-string 3 result)))
+             (loaded-file (intero-extend-path-by-buffer-host returned-file)))
+        (if (intero-temp-file-p loaded-file)
+            (let ((original-buffer (intero-temp-file-origin-buffer loaded-file)))
+              (if original-buffer
+                  (switch-to-buffer original-buffer)
+                (error "Attempted to load temp file.  Try restarting Intero.
+If the problem persists, please report this as a bug!")))
+          (find-file
+           (expand-file-name
+            returned-file
+            (intero-extend-path-by-buffer-host (intero-project-root)))))
+        (pop-mark)
+        (goto-char (point-min))
+        (forward-line (1- line))
+        (forward-char (1- col))
+        t))))
+
+(defmacro intero-with-dump-splices (exp)
+  "Run EXP but with dump-splices enabled in the intero backend process."
+  `(when (intero-blocking-call 'backend ":set -ddump-splices")
+     (let ((result ,exp))
+       (progn
+         nil ; Disable dump-splices here in future
+         result))))
+
+(defun intero-expand-splice-at-point ()
+  "Show the expansion of the template haskell splice at point."
+  (interactive)
+  (unless (intero-gave-up 'backend)
+    (intero-with-dump-splices
+     (let* ((output (intero-blocking-call
+                     'backend
+                     (concat ":load " (intero-path-for-ghci (intero-temp-file-name)))))
+            (msgs (intero-parse-errors-warnings-splices nil (current-buffer) output))
+            (line (line-number-at-pos))
+            (column (if (save-excursion
+                          (forward-char 1)
+                          (looking-back "$(" 1))
+                        (+ 2 (current-column))
+                      (if (looking-at-p "$(")
+                          (+ 3 (current-column))
+                        (1+ (current-column)))))
+            (expansion-msg
+             (cl-loop for msg in msgs
+                      when (and (eq (flycheck-error-level msg) 'splice)
+                                (= (flycheck-error-line msg) line)
+                                (<= (flycheck-error-column msg) column))
+                      return (flycheck-error-message msg)))
+            (expansion
+             (when expansion-msg
+               (string-trim
+                (replace-regexp-in-string "^Splicing expression" "" expansion-msg)))))
+       (when expansion
+         (message "%s" (intero-fontify-expression expansion)))))))
+
+(defun intero-restart ()
+  "Simply restart the process with the same configuration as before."
+  (interactive)
+  (when (intero-buffer-p 'backend)
+    (let ((targets (buffer-local-value 'intero-targets
+                                       (intero-buffer 'backend)))
+          (stack-yaml (buffer-local-value 'intero-stack-yaml
+                                          (intero-buffer 'backend))))
+      (intero-destroy 'backend)
+      (intero-get-worker-create 'backend targets (current-buffer) stack-yaml)
+      (intero-repl-restart))))
+
+(defun intero-read-targets ()
+  "Read a list of stack targets."
+  (let ((old-targets
+         (buffer-local-value 'intero-targets (intero-buffer 'backend)))
+        (available-targets (intero-get-targets)))
+    (if available-targets
+        (intero-multiswitch
+         "Set the targets to use for stack ghci:"
+         (mapcar (lambda (target)
+                   (list :key target
+                         :title target
+                         :default (member target old-targets)))
+                 available-targets))
+      (split-string (read-from-minibuffer "Targets: " nil nil nil nil old-targets)
+                    " "
+                    t))))
+
+(defun intero-targets (targets save-dir-local)
+  "Set the TARGETS to use for stack ghci.
+When SAVE-DIR-LOCAL is non-nil, save TARGETS as the
+directory-local value for `intero-targets'."
+  (interactive (list (intero-read-targets)
+                     (y-or-n-p "Save selected target(s) in directory local variables for future sessions? ")))
+  (intero-destroy)
+  (intero-get-worker-create 'backend targets (current-buffer))
+  (intero-repl-restart)
+  (when save-dir-local
+    (save-window-excursion
+      (let ((default-directory (intero-project-root)))
+        (add-dir-local-variable 'haskell-mode 'intero-targets targets)
+        (save-buffer)))))
+
+(defun intero-stack-yaml (file save-dir-local)
+  "Change the yaml FILE that intero should tell stack to use.
+Intero will be restarted with the new configuration.  When
+SAVE-DIR-LOCAL is non-nil, save FILE as the directory-local value
+for `intero-stack-yaml'."
+  (interactive (list (read-file-name
+                      "Select YAML config: "
+                      (file-name-as-directory (intero-project-root)))
+                     (y-or-n-p "Save selected stack yaml config in directory local variable for future sessions? ")))
+  (let ((stack-yaml (expand-file-name file)))
+    (setq intero-stack-yaml stack-yaml)
+    (with-current-buffer (intero-buffer 'backend)
+      (setq intero-stack-yaml stack-yaml))
+    (intero-restart)
+    (intero-repl-restart)
+    (when save-dir-local
+      (save-window-excursion
+        (let ((default-directory (intero-project-root)))
+          (add-dir-local-variable 'haskell-mode 'intero-stack-yaml stack-yaml)
+          (save-buffer))))))
+
+(defun intero-destroy (&optional worker)
+  "Stop WORKER and kill its associated process buffer.
+If not provided, WORKER defaults to the current worker process."
+  (interactive)
+  (if worker
+      (intero-delete-worker worker)
+    (intero-delete-worker 'backend)))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; DevelMain integration
+
+(defun intero-devel-reload ()
+  "Reload the module `DevelMain' and then run `DevelMain.update'.
+
+This is for doing live update of the code of servers or GUI
+applications.  Put your development version of the program in
+`DevelMain', and define `update' to auto-start the program on a
+new thread, and use the `foreign-store' package to access the
+running context across :load/:reloads in Intero."
+  (interactive)
+  (unwind-protect
+      (with-current-buffer
+          (or (get-buffer "DevelMain.hs")
+              (if (y-or-n-p
+                   "You need to open a buffer named DevelMain.hs.  Find now? ")
+                  (ido-find-file)
+                (error "No DevelMain.hs buffer")))
+        (message "Reloading ...")
+        (intero-async-call
+         'backend
+         ":load DevelMain"
+         (current-buffer)
+         (lambda (buffer reply)
+           (if (string-match-p "^O[Kk], modules loaded" reply)
+               (intero-async-call
+                'backend
+                "DevelMain.update"
+                buffer
+                (lambda (_buffer reply)
+                  (message "DevelMain updated. Output was:\n%s"
+                           reply)))
+             (progn
+               (message "DevelMain FAILED. Switch to DevelMain.hs and compile that.")
+               (switch-to-buffer buffer)
+               (flycheck-buffer)
+               (flycheck-list-errors))))))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Flycheck integration
+
+(defun intero-flycheck-enable ()
+  "Enable intero's flycheck support in this buffer."
+  (flycheck-select-checker 'intero)
+  (setq intero-check-last-mod-time nil
+        intero-check-last-results nil)
+  (flycheck-mode))
+
+(defun intero-check (checker cont)
+  "Run a check with CHECKER and pass the status onto CONT."
+  (if (intero-gave-up 'backend)
+      (run-with-timer 0
+                      nil
+                      cont
+                      'interrupted)
+    (let* ((file-buffer (current-buffer))
+           (staging-file (intero-path-for-ghci (intero-staging-file-name)))
+           (temp-file (intero-path-for-ghci (intero-temp-file-name))))
+      ;; We queue up to :move the staging file to the target temp
+      ;; file, which also updates its modified time.
+      (intero-async-call
+       'backend
+       (format ":move %s %s" staging-file temp-file))
+      ;; We load up the target temp file, which has only been updated
+      ;; by the copy above.
+      (intero-async-call
+       'backend
+       (concat ":load " temp-file)
+       (list :cont cont
+             :file-buffer file-buffer
+             :checker checker)
+       (lambda (state string)
+         (with-current-buffer (plist-get state :file-buffer)
+           (let* ((compile-ok (string-match "O[Kk], modules loaded: \\(.*\\)\\.$" string))
+                  (modules (match-string 1 string))
+                  (msgs (intero-parse-errors-warnings-splices
+                         (plist-get state :checker)
+                         (current-buffer)
+                         string)))
+             (intero-collect-compiler-messages msgs)
+             (let ((results (cl-remove-if (lambda (msg)
+                                            (eq 'splice (flycheck-error-level msg)))
+                                          msgs)))
+               (setq intero-check-last-results results)
+               (funcall (plist-get state :cont) 'finished results))
+             (when compile-ok
+               (intero-async-call 'backend
+                                  (concat ":module + "
+                                          (replace-regexp-in-string "," "" modules))
+                                  nil
+                                  (lambda (_st _))))))))
+      ;; We sleep for at least one second to allow a buffer period
+      ;; between module updates. GHCi will consider a module Foo to be
+      ;; unchanged even if its filename has changed or timestmap has
+      ;; changed, if the timestamp is less than 1 second.
+      (intero-async-call
+       'backend
+       ":sleep 1"))))
+
+(flycheck-define-generic-checker 'intero
+  "A syntax and type checker for Haskell using an Intero worker
+process."
+  :start 'intero-check
+  :modes '(haskell-mode literate-haskell-mode)
+  :predicate (lambda () intero-mode))
+
+(add-to-list 'flycheck-checkers 'intero)
+
+(defun intero-parse-errors-warnings-splices (checker buffer string)
+  "Parse flycheck errors and warnings.
+CHECKER and BUFFER are added to each item parsed from STRING."
+  (intero-with-temp-buffer
+    (insert string)
+    (goto-char (point-min))
+    (let ((messages (list))
+          (temp-file (intero-temp-file-name buffer))
+          (found-error-as-warning nil))
+      (while (search-forward-regexp
+              (concat "[\r\n]\\([A-Z]?:?[^ \r\n:][^:\n\r]+\\):\\([0-9()-:]+\\):"
+                      "[ \n\r]+\\([[:unibyte:][:nonascii:]]+?\\)\n[^ ]")
+              nil t 1)
+        (let* ((local-file (intero-canonicalize-path (match-string 1)))
+               (file (intero-extend-path-by-buffer-host local-file buffer))
+               (location-raw (match-string 2))
+               (msg (replace-regexp-in-string
+                     "[\n\r ]*|$"
+                     ""
+                     (match-string 3))) ;; Replace gross bullet points.
+               (type (cond ((string-match "^Warning:" msg)
+                            (setq msg (replace-regexp-in-string "^Warning: *" "" msg))
+                            (if (string-match-p
+                                 (rx bol
+                                     "["
+                                     (or "-Wdeferred-type-errors"
+                                         "-Wdeferred-out-of-scope-variables"
+                                         "-Wtyped-holes")
+                                     "]")
+                                 msg)
+                                (progn (setq found-error-as-warning t)
+                                       'error)
+                              'warning))
+                           ((string-match-p "^Splicing " msg) 'splice)
+                           (t                                 'error)))
+               (location (intero-parse-error
+                          (concat local-file ":" location-raw ": x")))
+               (line (plist-get location :line))
+               (column (plist-get location :col)))
+          (setq messages
+                (cons (flycheck-error-new-at
+                       line column type
+                       msg
+                       :checker checker
+                       :buffer buffer
+                       :filename (if (intero-paths-for-same-file temp-file file)
+                                     (intero-buffer-file-name buffer)
+                                   file))
+                      messages)))
+        (forward-line -1))
+      (delete-dups
+       (if found-error-as-warning
+           (cl-remove-if (lambda (msg) (eq 'warning (flycheck-error-level msg))) messages)
+         messages)))))
+
+(defconst intero-error-regexp-alist
+  `((,(concat
+       "^ *\\(?1:[^\t\r\n]+?\\):"
+       "\\(?:"
+       "\\(?2:[0-9]+\\):\\(?4:[0-9]+\\)\\(?:-\\(?5:[0-9]+\\)\\)?" ;; "121:1" & "12:3-5"
+       "\\|"
+       "(\\(?2:[0-9]+\\),\\(?4:[0-9]+\\))-(\\(?3:[0-9]+\\),\\(?5:[0-9]+\\))" ;; "(289,5)-(291,36)"
+       "\\)"
+       ":\\(?6: Warning:\\)?")
+     1 (2 . 3) (4 . 5) (6 . nil)) ;; error/warning locus
+
+    ;; multiple declarations
+    ("^    \\(?:Declared at:\\|            \\) \\(?1:[^ \t\r\n]+\\):\\(?2:[0-9]+\\):\\(?4:[0-9]+\\)$"
+     1 2 4 0) ;; info locus
+
+    ;; this is the weakest pattern as it's subject to line wrapping et al.
+    (" at \\(?1:[^ \t\r\n]+\\):\\(?2:[0-9]+\\):\\(?4:[0-9]+\\)\\(?:-\\(?5:[0-9]+\\)\\)?[)]?$"
+     1 2 (4 . 5) 0)) ;; info locus
+  "Regexps used for matching GHC compile messages.")
+
+(defun intero-parse-error (string)
+  "Parse the line number from the error in STRING."
+  (save-match-data
+    (when (string-match (mapconcat #'car intero-error-regexp-alist "\\|")
+                        string)
+      (let ((string3 (match-string 3 string))
+            (string5 (match-string 5 string)))
+        (list :file (match-string 1 string)
+              :line (string-to-number (match-string 2 string))
+              :col (string-to-number (match-string 4 string))
+              :line2 (when string3
+                       (string-to-number string3))
+              :col2 (when string5
+                      (string-to-number string5)))))))
+
+(defun intero-call-in-buffer (buffer func &rest args)
+  "In BUFFER, call FUNC with ARGS."
+  (with-current-buffer buffer
+    (apply func args)))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Traditional completion-at-point function
+
+(defun intero-completion-at-point ()
+  "A (blocking) function suitable for use in `completion-at-point-functions'."
+  (let ((prefix-info (intero-completions-grab-prefix)))
+    (when prefix-info
+      (cl-destructuring-bind
+          (beg end prefix _type) prefix-info
+        (let ((completions
+               (intero-completion-response-to-list
+                (intero-blocking-call
+                 'backend
+                 (format ":complete repl %S" prefix)))))
+          (when completions
+            (list beg end completions)))))))
+
+(defun intero-repl-completion-at-point ()
+  "A (blocking) function suitable for use in `completion-at-point-functions'.
+Should only be used in the repl"
+  (let* ((beg (save-excursion (intero-repl-beginning-of-line) (point)))
+         (end (point))
+         (str (buffer-substring-no-properties beg end))
+         (repl-buffer (current-buffer))
+         (proc (get-buffer-process (current-buffer))))
+    (with-temp-buffer
+      (comint-redirect-send-command-to-process
+       (format ":complete repl %S" str) ;; command
+       (current-buffer) ;; output buffer
+       proc ;; target process
+       nil  ;; echo
+       t)   ;; no-display
+      (while (not (with-current-buffer repl-buffer
+                    comint-redirect-completed))
+        (sleep-for 0.01))
+      (let* ((completions (intero-completion-response-to-list (buffer-string)))
+             (first-line (car completions)))
+        (when (string-match "[^ ]* [^ ]* " first-line) ;; "2 2 :load src/"
+          (setq first-line (replace-match "" nil nil first-line))
+          (list (+ beg (length first-line)) end (cdr completions)))))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Company integration (auto-completion)
+
+(defconst intero-pragmas
+  '("CONLIKE" "SCC" "DEPRECATED" "INCLUDE" "INCOHERENT" "INLINABLE" "INLINE"
+    "LANGUAGE" "LINE" "MINIMAL" "NOINLINE" "NOUNPACK" "OPTIONS" "OPTIONS_GHC"
+    "OVERLAPPABLE" "OVERLAPPING" "OVERLAPS" "RULES" "SOURCE" "SPECIALIZE"
+    "UNPACK" "WARNING")
+  "Pragmas that GHC supports.")
+
+(defun intero-company (command &optional arg &rest ignored)
+  "Company source for intero, with the standard COMMAND and ARG args.
+Other arguments are IGNORED."
+  (interactive (list 'interactive))
+  (cl-case command
+    (interactive (company-begin-backend 'intero-company))
+    (prefix
+     (unless (intero-gave-up 'backend)
+       (or (let ((hole (intero-grab-hole)))
+             (when hole
+               (save-excursion
+                 (goto-char (cdr hole))
+                 (buffer-substring (car hole) (cdr hole)))))
+           (let ((prefix-info (intero-completions-grab-prefix)))
+             (when prefix-info
+               (cl-destructuring-bind
+                   (beg end prefix _type) prefix-info
+                 prefix))))))
+    (candidates
+     (unless (intero-gave-up 'backend)
+       (let ((beg-end (intero-grab-hole)))
+         (if beg-end
+             (cons :async
+                   (-partial 'intero-async-fill-at
+                             (current-buffer)
+                             (car beg-end)))
+           (let ((prefix-info (intero-completions-grab-prefix)))
+             (when prefix-info
+               (cons :async
+                     (-partial 'intero-company-callback
+                               (current-buffer)
+                               prefix-info))))))))))
+
+(define-obsolete-function-alias 'company-intero 'intero-company)
+
+(defun intero-company-callback (source-buffer prefix-info cont)
+  "Generate completions for SOURCE-BUFFER based on PREFIX-INFO and call CONT on the results."
+  (cl-destructuring-bind
+      (beg end prefix type) prefix-info
+    (or (and (bound-and-true-p intero-mode)
+             (cl-case type
+               (haskell-completions-module-name-prefix
+                (intero-get-repl-completions source-buffer (concat "import " prefix) cont)
+                t)
+               (haskell-completions-identifier-prefix
+                (intero-get-completions source-buffer beg end cont)
+                t)
+               (haskell-completions-language-extension-prefix
+                (intero-get-repl-completions
+                 source-buffer
+                 (concat ":set -X" prefix)
+                 (-partial (lambda (cont results)
+                             (funcall cont
+                                      (mapcar (lambda (x)
+                                                (replace-regexp-in-string "^-X" "" x))
+                                              results)))
+                           cont))
+                t)
+               (haskell-completions-pragma-name-prefix
+                (funcall cont
+                         (cl-remove-if-not
+                          (lambda (candidate)
+                            (string-prefix-p prefix candidate))
+                          intero-pragmas))
+                t)))
+        (intero-get-repl-completions source-buffer prefix cont))))
+
+(defun intero-completions-grab-prefix (&optional minlen)
+  "Grab prefix at point for possible completion.
+If specified, MINLEN is the shortest completion which will be
+considered."
+  (when (intero-completions-can-grab-prefix)
+    (let ((prefix (cond
+                   ((intero-completions-grab-pragma-prefix))
+                   ((intero-completions-grab-identifier-prefix)))))
+      (cond ((and minlen prefix)
+             (when (>= (length (nth 2 prefix)) minlen)
+               prefix))
+            (prefix prefix)))))
+
+(defun intero-completions-can-grab-prefix ()
+  "Check if the case is appropriate for grabbing completion prefix."
+  (when (not (region-active-p))
+    (when (looking-at-p (rx (| space line-end punct)))
+      (when (not (bobp))
+        (save-excursion
+          (backward-char)
+          (not (looking-at-p (rx (| space line-end)))))))))
+
+(defun intero-completions-grab-identifier-prefix ()
+  "Grab identifier prefix."
+  (let ((pos-at-point (intero-ident-pos-at-point))
+        (p (point)))
+    (when pos-at-point
+      (let* ((start (car pos-at-point))
+             (end (cdr pos-at-point))
+             (type 'haskell-completions-identifier-prefix)
+             (case-fold-search nil)
+             value)
+        (when (<= p end)
+          (setq end p)
+          (setq value (buffer-substring-no-properties start end))
+          (when (string-match-p (rx bos upper) value)
+            (save-excursion
+              (goto-char (line-beginning-position))
+              (when (re-search-forward
+                     (rx "import"
+                         (? (1+ space) "qualified")
+                         (1+ space)
+                         upper
+                         (1+ (| alnum ".")))
+                     p    ;; bound
+                     t)   ;; no-error
+                (if (equal p (point))
+                    (setq type 'haskell-completions-module-name-prefix)
+                  (when (re-search-forward
+                         (rx (| " as " "("))
+                         start
+                         t)
+                    (setq type 'haskell-completions-identifier-prefix))))))
+          (when (nth 8 (syntax-ppss))
+            (setq type 'haskell-completions-general-prefix))
+          (when value (list start end value type)))))))
+
+(defun intero-completions-grab-pragma-prefix ()
+  "Grab completion prefix for pragma completions.
+Returns a list of form '(prefix-start-position
+prefix-end-position prefix-value prefix-type) for pramga names
+such as WARNING, DEPRECATED, LANGUAGE etc.  Also returns
+completion prefixes for options in case OPTIONS_GHC pragma, or
+language extensions in case of LANGUAGE pragma.  Obsolete OPTIONS
+pragma is supported also."
+  (when (nth 4 (syntax-ppss))
+    ;; We're inside comment
+    (let ((p (point))
+          (comment-start (nth 8 (syntax-ppss)))
+          (case-fold-search nil)
+          prefix-start
+          prefix-end
+          prefix-type
+          prefix-value)
+      (save-excursion
+        (goto-char comment-start)
+        (when (looking-at (rx "{-#" (1+ (| space "\n"))))
+          (let ((pragma-start (match-end 0)))
+            (when (> p pragma-start)
+              ;; point stands after `{-#`
+              (goto-char pragma-start)
+              (when (looking-at (rx (1+ (| upper "_"))))
+                ;; found suitable sequence for pragma name
+                (let ((pragma-end (match-end 0))
+                      (pragma-value (match-string-no-properties 0)))
+                  (if (eq p pragma-end)
+                      ;; point is at the end of (in)complete pragma name
+                      ;; prepare resulting values
+                      (progn
+                        (setq prefix-start pragma-start)
+                        (setq prefix-end pragma-end)
+                        (setq prefix-value pragma-value)
+                        (setq prefix-type
+                              'haskell-completions-pragma-name-prefix))
+                    (when (and (> p pragma-end)
+                               (or (equal "OPTIONS_GHC" pragma-value)
+                                   (equal "OPTIONS" pragma-value)
+                                   (equal "LANGUAGE" pragma-value)))
+                      ;; point is after pragma name, so we need to check
+                      ;; special cases of `OPTIONS_GHC` and `LANGUAGE` pragmas
+                      ;; and provide a completion prefix for possible ghc
+                      ;; option or language extension.
+                      (goto-char pragma-end)
+                      (when (re-search-forward
+                             (rx (* anything)
+                                 (1+ (regexp "\\S-")))
+                             p
+                             t)
+                        (let* ((str (match-string-no-properties 0))
+                               (split (split-string str (rx (| space "\n")) t))
+                               (val (car (last split)))
+                               (end (point)))
+                          (when (and (equal p end)
+                                     (not (string-match-p "#" val)))
+                            (setq prefix-value val)
+                            (backward-char (length val))
+                            (setq prefix-start (point))
+                            (setq prefix-end end)
+                            (setq
+                             prefix-type
+                             (if (not (equal "LANGUAGE" pragma-value))
+                                 'haskell-completions-ghc-option-prefix
+                               'haskell-completions-language-extension-prefix
+                               )))))))))))))
+      (when prefix-value
+        (list prefix-start prefix-end prefix-value prefix-type)))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Hole filling
+
+(defun intero-async-fill-at (buffer beg cont)
+  "Make the blocking call to the process."
+  (with-current-buffer buffer
+    (intero-async-call
+     'backend
+     (format
+      ":fill %s %d %d"
+      (intero-path-for-ghci (intero-temp-file-name))
+      (save-excursion (goto-char beg)
+                      (line-number-at-pos))
+      (save-excursion (goto-char beg)
+                      (1+ (current-column))))
+     (list :buffer (current-buffer) :cont cont)
+     (lambda (state reply)
+       (if (or (string-match "^Couldn't guess" reply)
+               (string-match "^Unable to " reply)
+               (intero-parse-error reply))
+           (funcall (plist-get state :cont) (list))
+         (with-current-buffer (plist-get state :buffer)
+           (let ((candidates
+                  (split-string
+                   (replace-regexp-in-string
+                    "\n$" ""
+                    reply)
+                   "[\r\n]"
+                   t)))
+             (when candidates
+               (funcall (plist-get state :cont) candidates)))))))))
+
+(defun intero-grab-hole ()
+  "When user is at a hole _ or _foo, return the starting point of
+that hole."
+  (let ((beg-end (intero-ident-pos-at-point)))
+    (when beg-end
+      (let ((string (buffer-substring-no-properties (car beg-end) (cdr beg-end))))
+        (when (string-match-p "^_" string)
+          beg-end)))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; ELDoc integration
+
+(defvar-local intero-eldoc-cache (make-hash-table :test 'equal)
+  "Cache for types of regions, used by `intero-eldoc'.
+This is not for saving on requests (we make a request even if
+something is in cache, overwriting the old entry), but rather for
+making types show immediately when we do have them cached.")
+
+(defun intero-eldoc-maybe-print (msg)
+  "Print MSG with eldoc if eldoc would display a message now.
+Like `eldoc-print-current-symbol-info', but just printing MSG
+instead of using `eldoc-documentation-function'."
+  (with-demoted-errors "eldoc error: %s"
+    (and (or (eldoc-display-message-p)
+             ;; Erase the last message if we won't display a new one.
+             (when eldoc-last-message
+               (eldoc-message nil)
+               nil))
+         (eldoc-message msg))))
+
+(defun intero-eldoc ()
+  "ELDoc backend for intero."
+  (let ((buffer (intero-buffer 'backend)))
+    (when (and buffer (process-live-p (get-buffer-process buffer)))
+      (apply #'intero-get-type-at-async
+             (lambda (beg end ty)
+               (let ((response-status (intero-haskell-utils-repl-response-error-status ty)))
+                 (if (eq 'no-error response-status)
+                     (let ((msg (intero-fontify-expression
+                                 (replace-regexp-in-string "[ \n]+" " " ty))))
+                       ;; Got an updated type-at-point, cache and print now:
+                       (puthash (list beg end)
+                                msg
+                                intero-eldoc-cache)
+                       (intero-eldoc-maybe-print msg))
+                   ;; But if we're seeing errors, invalidate cache-at-point:
+                   (remhash (list beg end) intero-eldoc-cache))))
+             (intero-thing-at-point))))
+  ;; If we have something cached at point, print that first:
+  (gethash (intero-thing-at-point) intero-eldoc-cache))
+
+(defun intero-haskell-utils-repl-response-error-status (response)
+  "Parse response REPL's RESPONSE for errors.
+Returns one of the following symbols:
+
++ unknown-command
++ option-missing
++ interactive-error
++ no-error
+
+*Warning*: this funciton covers only three kind of responses:
+
+* \"unknown command …\"
+  REPL missing requested command
+* \"<interactive>:3:5: …\"
+  interactive REPL error
+* \"Couldn't guess that module name. Does it exist?\"
+  (:type-at and maybe some other commands error)
+* *all other reposnses* are treated as success reposneses and
+  'no-error is returned."
+  (let ((first-line (car (split-string response "\n" t))))
+    (cond
+     ((null first-line) 'no-error)
+     ((string-match-p "^unknown command" first-line)
+      'unknown-command)
+     ((string-match-p
+       "^Couldn't guess that module name. Does it exist?"
+       first-line)
+      'option-missing)
+     ((string-match-p "^<interactive>:" first-line)
+      'interactive-error)
+     ((string-match-p "^<no location info>:" first-line)
+      'inspection-error)
+     (t 'no-error))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; REPL
+
+(defconst intero-prompt-regexp "^\4 ")
+
+(defvar-local intero-repl-previous-buffer nil
+  "Records the buffer to which `intero-repl-switch-back' should jump.
+This is set by `intero-repl-buffer', and should otherwise be nil.")
+
+(defun intero-repl-clear-buffer ()
+  "Clear the current REPL buffer."
+  (interactive)
+  (let ((comint-buffer-maximum-size 0))
+    (comint-truncate-buffer)))
+
+(defmacro intero-with-repl-buffer (prompt-options &rest body)
+  "Evaluate given forms with the REPL as the current buffer.
+The REPL will be started if necessary, and the REPL buffer will
+be activated after evaluation.  PROMPT-OPTIONS are passed to
+`intero-repl-buffer'.  BODY is the forms to be evaluated."
+  (declare (indent defun))
+  (let ((repl-buffer (cl-gensym)))
+    `(let ((,repl-buffer (intero-repl-buffer ,prompt-options t)))
+       (with-current-buffer ,repl-buffer
+         ,@body)
+       (when intero-pop-to-repl
+         (pop-to-buffer ,repl-buffer)))))
+
+(defun intero-repl-after-load ()
+  "Set the command to run after load."
+  (interactive)
+  (if (eq major-mode 'intero-repl-mode)
+      (setq intero-repl-send-after-load
+            (read-from-minibuffer
+             "Command to run: "
+             (or intero-repl-send-after-load
+                 (car (ring-elements comint-input-ring))
+                 "")))
+    (error "Run this in the REPL.")))
+
+(defun intero-repl-load (&optional prompt-options)
+  "Load the current file in the REPL.
+If PROMPT-OPTIONS is non-nil, prompt with an options list."
+  (interactive "P")
+  (save-buffer)
+  (let ((file (intero-path-for-ghci (intero-buffer-file-name))))
+    (intero-with-repl-buffer prompt-options
+      (comint-simple-send
+         (get-buffer-process (current-buffer))
+         ":set prompt \"\\n\"")
+        (if (or (not intero-repl-last-loaded)
+                (not (equal file intero-repl-last-loaded)))
+            (progn
+              (comint-simple-send
+               (get-buffer-process (current-buffer))
+               (concat ":load " file))
+              (setq intero-repl-last-loaded file))
+          (comint-simple-send
+           (get-buffer-process (current-buffer))
+           ":reload"))
+        (when intero-repl-send-after-load
+          (comint-simple-send
+           (get-buffer-process (current-buffer))
+           intero-repl-send-after-load))
+        (comint-simple-send (get-buffer-process (current-buffer))
+                            ":set prompt \"\\4 \""))))
+
+(defun intero-repl-eval-region (begin end &optional prompt-options)
+  "Evaluate the code in region from BEGIN to END in the REPL.
+If the region is unset, the current line will be used.
+PROMPT-OPTIONS are passed to `intero-repl-buffer' if supplied."
+  (interactive "r")
+  (unless (use-region-p)
+    (setq begin (line-beginning-position)
+          end (line-end-position)))
+  (let ((text (buffer-substring-no-properties begin end)))
+    (intero-with-repl-buffer prompt-options
+      (comint-simple-send
+       (get-buffer-process (current-buffer))
+       text))))
+
+(defun intero-repl (&optional prompt-options)
+  "Start up the REPL for this stack project.
+If PROMPT-OPTIONS is non-nil, prompt with an options list."
+  (interactive "P")
+  (switch-to-buffer-other-window (intero-repl-buffer prompt-options t)))
+
+(defun intero-repl-restart ()
+  "Restart the REPL."
+  (interactive)
+  (let* ((root (intero-project-root))
+         (package-name (intero-package-name))
+         (backend-buffer (intero-buffer 'backend))
+         (name (format "*intero:%s:%s:repl*"
+                       (file-name-nondirectory root)
+                       package-name)))
+    (when (get-buffer name)
+      (with-current-buffer (get-buffer name)
+        (goto-char (point-max))
+        (let ((process (get-buffer-process (current-buffer))))
+          (when process (kill-process process)))
+        (intero-repl-mode-start backend-buffer
+                                (buffer-local-value 'intero-targets backend-buffer)
+                                nil
+                                (buffer-local-value 'intero-stack-yaml backend-buffer))))))
+
+(defun intero-repl-buffer (prompt-options &optional store-previous)
+  "Start the REPL buffer.
+If PROMPT-OPTIONS is non-nil, prompt with an options list.  When
+STORE-PREVIOUS is non-nil, note the caller's buffer in
+`intero-repl-previous-buffer'."
+  (let* ((root (intero-project-root))
+         (package-name (intero-package-name))
+         (name (format "*intero:%s:%s:repl*"
+                       (file-name-nondirectory root)
+                       package-name))
+         (initial-buffer (current-buffer))
+         (backend-buffer (intero-buffer 'backend)))
+    (with-current-buffer
+        (or (get-buffer name)
+            (with-current-buffer
+                (get-buffer-create name)
+              ;; The new buffer doesn't know if the initial buffer was hosted
+              ;; remotely or not, so we need to extend by the host of the
+              ;; initial buffer to cd. We could also achieve this by setting the
+              ;; buffer's intero-buffer-host, but intero-repl-mode wipes this, so
+              ;; we defer setting that until after.
+              (cd (intero-extend-path-by-buffer-host root initial-buffer))
+              (intero-repl-mode) ; wipes buffer-local variables
+              (intero-inherit-local-variables initial-buffer)
+              (setq intero-buffer-host (intero-buffer-host initial-buffer))
+              (intero-repl-mode-start backend-buffer
+                                      (buffer-local-value 'intero-targets backend-buffer)
+                                      prompt-options
+                                      (buffer-local-value 'intero-stack-yaml backend-buffer))
+              (current-buffer)))
+      (progn
+        (when store-previous
+          (setq intero-repl-previous-buffer initial-buffer))
+        (current-buffer)))))
+
+(defvar intero-hyperlink-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map [mouse-1]  'intero-find-file-with-line-and-char)
+    (define-key map [C-return] 'intero-find-file-with-line-and-char)
+    map)
+  "Keymap for clicking on links in REPL.")
+
+(define-derived-mode intero-repl-mode comint-mode "Intero-REPL"
+  "Interactive prompt for Intero."
+  (when (and (not (eq major-mode 'fundamental-mode))
+             (eq this-command 'intero-repl-mode))
+    (error "You probably meant to run: M-x intero-repl"))
+  (setq-local comint-prompt-regexp intero-prompt-regexp)
+  (setq-local warning-suppress-types (cons '(undo discard-info) warning-suppress-types))
+  (setq-local comint-prompt-read-only t)
+  (add-hook 'completion-at-point-functions 'intero-repl-completion-at-point nil t)
+  (company-mode))
+
+(defun intero-repl-mode-start (backend-buffer targets prompt-options stack-yaml)
+  "Start the process for the repl in the current buffer.
+BACKEND-BUFFER is used for options.  TARGETS is the targets to
+load.  If PROMPT-OPTIONS is non-nil, prompt with an options list.
+STACK-YAML is the stack yaml config to use.  When nil, tries to
+use project-wide intero-stack-yaml when nil, otherwise uses
+stack's default)."
+  (setq intero-targets targets)
+  (setq intero-repl-last-loaded nil)
+  (when stack-yaml
+    (setq intero-stack-yaml stack-yaml))
+  (when prompt-options
+    (intero-repl-options backend-buffer))
+  (let ((stack-yaml (if stack-yaml
+                        stack-yaml
+                      (buffer-local-value 'intero-stack-yaml backend-buffer)))
+        (arguments (intero-make-options-list
+                    "ghci"
+                    (or targets
+                        (let ((package-name (buffer-local-value 'intero-package-name
+                                                                backend-buffer)))
+                          (unless (equal "" package-name)
+                            (list package-name))))
+                    (buffer-local-value 'intero-repl-no-build backend-buffer)
+                    (buffer-local-value 'intero-repl-no-load backend-buffer)
+                    nil
+                    stack-yaml)))
+    (insert (propertize
+             (format "Starting:\n  %s ghci %s\n" intero-stack-executable
+                     (combine-and-quote-strings arguments))
+             'face 'font-lock-comment-face))
+    (let* ((script-buffer
+            (with-current-buffer (find-file-noselect (intero-make-temp-file "intero-script"))
+              (insert ":set prompt \"\"
+:set -fbyte-code
+:set -fdefer-type-errors
+:set -fdiagnostics-color=never
+:set prompt \"\\4 \"
+")
+              (basic-save-buffer)
+              (current-buffer)))
+           (script
+            (with-current-buffer script-buffer
+              (intero-localize-path (intero-buffer-file-name)))))
+      (let ((process
+             (get-buffer-process
+              (apply #'make-comint-in-buffer "intero" (current-buffer) intero-stack-executable nil "ghci"
+                     (append arguments
+                             (list "--verbosity" "silent")
+                             (list "--ghci-options"
+                                   (concat "-ghci-script=" script))
+                             (cl-mapcan (lambda (x) (list "--ghci-options" x)) intero-extra-ghci-options))))))
+        (when (process-live-p process)
+          (set-process-query-on-exit-flag process nil)
+          (message "Started Intero process for REPL.")
+          (kill-buffer script-buffer))))))
+
+(defun intero-repl-options (backend-buffer)
+  "Open an option menu to set options used when starting the REPL.
+Default options come from user customization and any temporary
+changes in the BACKEND-BUFFER."
+  (interactive)
+  (let* ((old-options
+          (list
+           (list :key "load-all"
+                 :title "Load all modules"
+                 :default (not (buffer-local-value 'intero-repl-no-load backend-buffer)))
+           (list :key "build-first"
+                 :title "Build project first"
+                 :default (not (buffer-local-value 'intero-repl-no-build backend-buffer)))))
+         (new-options (intero-multiswitch "Start REPL with options:" old-options)))
+    (with-current-buffer backend-buffer
+      (setq-local intero-repl-no-load (not (member "load-all" new-options)))
+      (setq-local intero-repl-no-build (not (member "build-first" new-options))))))
+
+(font-lock-add-keywords
+ 'intero-repl-mode
+ '(("\\(\4\\)"
+    (0 (prog1 ()
+         (compose-region (match-beginning 1)
+                         (match-end 1)
+                         ?λ))))))
+
+(define-key intero-repl-mode-map [remap move-beginning-of-line] 'intero-repl-beginning-of-line)
+(define-key intero-repl-mode-map [remap delete-backward-char] 'intero-repl-delete-backward-char)
+(define-key intero-repl-mode-map (kbd "C-c C-k") 'intero-repl-clear-buffer)
+(define-key intero-repl-mode-map (kbd "C-c C-z") 'intero-repl-switch-back)
+
+(defun intero-repl-delete-backward-char ()
+  "Delete backwards, excluding the prompt."
+  (interactive)
+  (unless (looking-back intero-prompt-regexp (line-beginning-position))
+    (call-interactively 'delete-backward-char)))
+
+(defun intero-repl-beginning-of-line ()
+  "Go to the beginning of the line, excluding the prompt."
+  (interactive)
+  (if (search-backward-regexp intero-prompt-regexp (line-beginning-position) t 1)
+      (goto-char (+ 2 (line-beginning-position)))
+    (call-interactively 'move-beginning-of-line)))
+
+(defun intero-repl-switch-back ()
+  "Switch back to the buffer from which this REPL buffer was reached."
+  (interactive)
+  (if intero-repl-previous-buffer
+      (switch-to-buffer-other-window intero-repl-previous-buffer)
+    (message "No previous buffer.")))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Buffer operations
+
+(defun intero-thing-at-point ()
+  "Return (list START END) of something at the point."
+  (if (region-active-p)
+      (list (region-beginning)
+            (region-end))
+    (let ((pos (intero-ident-pos-at-point)))
+      (if pos
+          (list (car pos) (cdr pos))
+        (list (point) (point))))))
+
+(defun intero-ident-at-point ()
+  "Return the identifier under point, or nil if none found.
+May return a qualified name."
+  (let ((reg (intero-ident-pos-at-point)))
+    (when reg
+      (buffer-substring-no-properties (car reg) (cdr reg)))))
+
+(defun intero-ident-pos-at-point ()
+  "Return the span of the identifier near point going backward.
+Returns nil if no identifier found or point is inside string or
+comment.  May return a qualified name."
+  (when (not (nth 8 (syntax-ppss)))
+    ;; Do not handle comments and strings
+    (let (start end)
+      ;; Initial point position is non-deterministic, it may occur anywhere
+      ;; inside identifier span, so the approach is:
+      ;; - first try go left and find left boundary
+      ;; - then try go right and find right boundary
+      ;;
+      ;; In both cases assume the longest path, e.g. when going left take into
+      ;; account than point may occur at the end of identifier, when going right
+      ;; take into account that point may occur at the beginning of identifier.
+      ;;
+      ;; We should handle `.` character very careful because it is heavily
+      ;; overloaded.  Examples of possible cases:
+      ;; Control.Monad.>>=  -- delimiter
+      ;; Control.Monad.when -- delimiter
+      ;; Data.Aeson..:      -- delimiter and operator symbol
+      ;; concat.map         -- composition function
+      ;; .?                 -- operator symbol
+      (save-excursion
+        ;; First, skip whitespace if we're on it, moving point to last
+        ;; identifier char.  That way, if we're at "map ", we'll see the word
+        ;; "map".
+        (when (and (looking-at-p (rx eol))
+                   (not (bolp)))
+          (backward-char))
+        (when (and (not (eobp))
+                   (eq (char-syntax (char-after)) ? ))
+          (skip-chars-backward " \t")
+          (backward-char))
+        ;; Now let's try to go left.
+        (save-excursion
+          (if (not (intero-mode--looking-at-varsym))
+              ;; Looking at non-operator char, this is quite simple
+              (progn
+                (skip-syntax-backward "w_")
+                ;; Remember position
+                (setq start (point)))
+            ;; Looking at operator char.
+            (while (and (not (bobp))
+                        (intero-mode--looking-at-varsym))
+              ;; skip all operator chars backward
+              (setq start (point))
+              (backward-char))
+            ;; Extra check for case when reached beginning of the buffer.
+            (when (intero-mode--looking-at-varsym)
+              (setq start (point))))
+          ;; Slurp qualification part if present.  If identifier is qualified in
+          ;; case of non-operator point will stop before `.` dot, but in case of
+          ;; operator it will stand at `.` delimiting dot.  So if we're looking
+          ;; at `.` let's step one char forward and try to get qualification
+          ;; part.
+          (goto-char start)
+          (when (looking-at-p (rx "."))
+            (forward-char))
+          (let ((pos (intero-mode--skip-qualification-backward)))
+            (when pos
+              (setq start pos))))
+        ;; Finally, let's try to go right.
+        (save-excursion
+          ;; Try to slurp qualification part first.
+          (skip-syntax-forward "w_")
+          (setq end (point))
+          (while (and (looking-at-p (rx "." upper))
+                      (not (zerop (progn (forward-char)
+                                         (skip-syntax-forward "w_")))))
+            (setq end (point)))
+          ;; If point was at non-operator we already done, otherwise we need an
+          ;; extra check.
+          (while (intero-mode--looking-at-varsym)
+            (forward-char)
+            (setq end (point))))
+        (when (not (= start end))
+          (cons start end))))))
+
+(defun intero-mode--looking-at-varsym ()
+  "Return t when point stands at operator symbol."
+  (when (not (eobp))
+    (let ((lex (intero-lexeme-classify-by-first-char (char-after))))
+      (or (eq lex 'varsym)
+          (eq lex 'consym)))))
+
+(defun intero-mode--skip-qualification-backward ()
+  "Skip qualified part of identifier backward.
+Expects point stands *after* delimiting dot.
+Returns beginning position of qualified part or nil if no qualified part found."
+  (when (not (and (bobp)
+                  (looking-at-p (rx bol))))
+    (let ((case-fold-search nil)
+          pos)
+      (while (and (eq (char-before) ?.)
+                  (progn (backward-char)
+                         (not (zerop (skip-syntax-backward "w'"))))
+                  (skip-syntax-forward "'")
+                  (looking-at-p "[[:upper:]]"))
+        (setq pos (point)))
+      pos)))
+
+(defun intero-lexeme-classify-by-first-char (char)
+  "Classify token by CHAR.
+CHAR is a chararacter that is assumed to be the first character
+of a token."
+  (let ((category (get-char-code-property char 'general-category)))
+
+    (cond
+     ((or (member char '(?! ?# ?$ ?% ?& ?* ?+ ?. ?/ ?< ?= ?> ?? ?@ ?^ ?| ?~ ?\\ ?-))
+          (and (> char 127)
+               (member category '(Pc Pd Po Sm Sc Sk So))))
+      'varsym)
+     ((equal char ?:)
+      'consym)
+     ((equal char ?\')
+      'char)
+     ((equal char ?\")
+      'string)
+     ((member category '(Lu Lt))
+      'conid)
+     ((or (equal char ?_)
+          (member category '(Ll Lo)))
+      'varid)
+     ((and (>= char ?0) (<= char ?9))
+      'number)
+     ((member char '(?\] ?\[ ?\( ?\) ?\{ ?\} ?\` ?\, ?\;))
+      'special))))
+
+(defun intero-buffer-file-name (&optional buffer)
+  "Call function `buffer-file-name' for BUFFER and clean its result.
+The path returned is canonicalized and stripped of any text properties."
+  (let ((name (buffer-file-name buffer)))
+    (when name
+      (intero-canonicalize-path (substring-no-properties name)))))
+
+(defun intero-paths-for-same-file (path-1 path-2)
+  "Compare PATH-1 and PATH-2 to see if they represent the same file."
+  (let ((simplify-path #'(lambda (path)
+                           (if (tramp-tramp-file-p path)
+                               (let* ((dissection (tramp-dissect-file-name path))
+                                      (host (tramp-file-name-host dissection))
+                                      (localname (tramp-file-name-localname dissection)))
+                                 (concat host ":" localname))
+                             (expand-file-name path)))))
+    (string= (funcall simplify-path path-1) (funcall simplify-path path-2))))
+
+(defun intero-buffer-host (&optional buffer)
+  "Get the hostname of the box hosting the file behind the BUFFER."
+  (with-current-buffer (or buffer (current-buffer))
+    (let ((file (intero-buffer-file-name)))
+      (if intero-buffer-host
+          intero-buffer-host
+        (setq intero-buffer-host
+              (when file
+                (if (tramp-tramp-file-p file)
+                    (tramp-file-name-host (tramp-dissect-file-name file))
+                  "")))))))
+
+(defun intero-extend-path-by-buffer-host (path &optional buffer)
+  "Take a PATH, and extend it by the host of the provided BUFFER (default to current buffer).  Return PATH unchanged if the file is local, or the BUFFER has no host."
+  (with-current-buffer (or buffer (current-buffer))
+    (if (or (eq nil (intero-buffer-host)) (eq "" (intero-buffer-host)))
+        path
+      (expand-file-name
+       (concat "/"
+               (intero-buffer-host)
+               ":"
+               path)))))
+
+(defvar-local intero-temp-file-name nil
+  "The name of a temporary file to which the current buffer's content is copied.")
+
+(defun intero-temp-file-p (path)
+  "Is PATH a temp file?"
+  (string= (file-name-directory path)
+           (file-name-directory (intero-temp-file-dir))))
+
+(defun intero-temp-file-origin-buffer (temp-file)
+  "Get the original buffer that TEMP-FILE was created for."
+  (or
+   (gethash (intero-canonicalize-path temp-file)
+            intero-temp-file-buffer-mapping)
+   (cl-loop
+    for buffer in (buffer-list)
+    when (string= (intero-canonicalize-path temp-file)
+                  (buffer-local-value 'intero-temp-file-name buffer))
+    return buffer)))
+
+(defun intero-unmangle-file-path (file)
+  "If FILE is an intero temp file, return the original source path, otherwise FILE."
+  (or (when (intero-temp-file-p file)
+        (let ((origin-buffer (intero-temp-file-origin-buffer file)))
+          (when origin-buffer
+            (buffer-file-name origin-buffer))))
+      file))
+
+(defun intero-make-temp-file (prefix &optional dir-flag suffix)
+  "Like `make-temp-file', but using a different temp directory.
+PREFIX, DIR-FLAG and SUFFIX are all passed to `make-temp-file'
+unmodified.  A different directory is applied so that if docker
+is used with stack, the commands run inside docker can find the
+path."
+  (let ((temporary-file-directory
+         (intero-temp-file-dir)))
+    (make-directory temporary-file-directory t)
+    (make-temp-file prefix dir-flag suffix)))
+
+(defun intero-temp-file-dir ()
+  "Get the temporary file directory for the current intero project."
+  (let* ((intero-absolute-project-root
+          (intero-extend-path-by-buffer-host (intero-project-root)))
+         (temporary-file-directory
+          (expand-file-name ".stack-work/intero/"
+                            intero-absolute-project-root)))
+    temporary-file-directory))
+
+(defun intero-temp-file-name (&optional buffer)
+  "Return the name of a temp file pertaining to BUFFER."
+  (with-current-buffer (or buffer (current-buffer))
+    (or intero-temp-file-name
+        (progn (setq intero-temp-file-name
+                     (intero-canonicalize-path
+                      (intero-make-temp-file
+                       "intero" nil
+                       (concat "-TEMP." (if (buffer-file-name)
+                                            (file-name-extension (buffer-file-name))
+                                          "hs")))))
+               (puthash intero-temp-file-name
+                        (current-buffer)
+                        intero-temp-file-buffer-mapping)
+               intero-temp-file-name))))
+
+(defun intero-staging-file-name (&optional buffer)
+  "Return the name of a temp file containing an up-to-date copy of BUFFER's contents."
+  (with-current-buffer (or buffer (current-buffer))
+    (let* ((contents (buffer-string))
+           (fname (intero-canonicalize-path
+                   (intero-make-temp-file
+                    "intero" nil
+                    (concat "-STAGING." (if (buffer-file-name)
+                                            (file-name-extension (buffer-file-name))
+                                          "hs"))))))
+      (with-temp-file fname
+        (insert contents))
+      fname)))
+
+(defun intero-quote-path-for-ghci (path)
+  "Quote PATH as necessary so that it can be passed to a GHCi :command."
+  (concat "\"" (replace-regexp-in-string "\\([\\\"]\\)" "\\\\\\1" path nil nil) "\""))
+
+(defun intero-path-for-ghci (path)
+  "Turn a possibly-remote PATH into one that can be passed to a GHCi :command."
+  (intero-quote-path-for-ghci (intero-localize-path path)))
+
+(defun intero-localize-path (path)
+  "Turn a possibly-remote PATH to a purely local one.
+This is used to create paths which a remote intero process can load."
+  (if (tramp-tramp-file-p path)
+      (tramp-file-name-localname (tramp-dissect-file-name path))
+    path))
+
+(defun intero-canonicalize-path (path)
+  "Return a standardized version of PATH.
+Path names are standardised and drive names are
+capitalized (relevant on Windows)."
+  (intero-capitalize-drive-letter (convert-standard-filename path)))
+
+(defun intero-capitalize-drive-letter (path)
+  "Ensures the drive letter is capitalized in PATH.
+This applies to paths of the form
+x:\\foo\\bar (i.e., Windows)."
+  (save-match-data
+    (let ((drive-path (split-string path ":\\\\")))
+      (if (or (null (car drive-path)) (null (cdr drive-path)))
+          path
+        (concat (upcase (car drive-path)) ":\\" (cadr drive-path))))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Query/commands
+
+(defun intero-get-all-types ()
+  "Get all types in all expressions in all modules."
+  (intero-blocking-network-call 'backend ":all-types"))
+
+(defun intero-get-type-at (beg end)
+  "Get the type at the given region denoted by BEG and END."
+  (let ((result (intero-get-type-at-helper beg end)))
+    (if (string-match (regexp-quote "Couldn't guess that module name. Does it exist?")
+                      result)
+        (progn (flycheck-buffer)
+               (message "No type information yet, compiling module ...")
+               (intero-get-type-at-helper-process beg end))
+      result)))
+
+(defun intero-get-type-at-helper (beg end)
+  (replace-regexp-in-string
+   "\n$" ""
+   (intero-blocking-network-call
+    'backend
+    (intero-format-get-type-at beg end))))
+
+(defun intero-get-type-at-helper-process (beg end)
+  (replace-regexp-in-string
+   "\n$" ""
+   (intero-blocking-call
+    'backend
+    (intero-format-get-type-at beg end))))
+
+(defun intero-get-type-at-async (cont beg end)
+  "Call CONT with type of the region denoted by BEG and END.
+CONT is called within the current buffer, with BEG, END and the
+type as arguments."
+  (intero-async-network-call
+   'backend
+   (intero-format-get-type-at beg end)
+   (list :cont cont
+         :source-buffer (current-buffer)
+         :beg beg
+         :end end)
+   (lambda (state reply)
+     (with-current-buffer (plist-get state :source-buffer)
+       (funcall (plist-get state :cont)
+                (plist-get state :beg)
+                (plist-get state :end)
+                (replace-regexp-in-string "\n$" "" reply))))))
+
+(defun intero-format-get-type-at (beg end)
+  "Compose a request for getting types in region from BEG to END."
+  (format ":type-at %s %d %d %d %d %S"
+          (intero-path-for-ghci (intero-temp-file-name))
+          (save-excursion (goto-char beg)
+                          (line-number-at-pos))
+          (save-excursion (goto-char beg)
+                          (1+ (current-column)))
+          (save-excursion (goto-char end)
+                          (line-number-at-pos))
+          (save-excursion (goto-char end)
+                          (1+ (current-column)))
+          (buffer-substring-no-properties beg end)))
+
+(defun intero-get-info-of (thing)
+  "Get info for THING."
+  (let ((optimistic-result
+         (replace-regexp-in-string
+          "\n$" ""
+          (intero-blocking-call
+           'backend
+           (format ":info %s" thing)))))
+    (if (string-match-p "^<interactive>" optimistic-result)
+        ;; Load the module Interpreted so that we get information,
+        ;; then restore bytecode.
+        (progn (intero-async-call
+                'backend
+                ":set -fbyte-code")
+               (set-buffer-modified-p t)
+               (save-buffer)
+               (unless (member 'save flycheck-check-syntax-automatically)
+                 (intero-async-call
+                  'backend
+                  (concat ":load " (intero-path-for-ghci (intero-temp-file-name)))))
+               (intero-async-call
+                'backend
+                ":set -fobject-code")
+               (replace-regexp-in-string
+                "\n$" ""
+                (intero-blocking-call
+                 'backend
+                 (format ":info %s" thing))))
+      optimistic-result)))
+
+(defconst intero-unloaded-module-string "Couldn't guess that module name. Does it exist?")
+
+(defun intero-get-loc-at (beg end)
+  "Get the location of the identifier denoted by BEG and END."
+  (let ((result (intero-get-loc-at-helper beg end)))
+    (if (string-match (regexp-quote intero-unloaded-module-string)
+                      result)
+        (progn (flycheck-buffer)
+               (message "No location information yet, compiling module ...")
+               (intero-get-loc-at-helper-process beg end))
+      result)))
+
+(defun intero-get-loc-at-helper (beg end)
+  "Make the blocking call to the process."
+  (replace-regexp-in-string
+   "\n$" ""
+   (intero-blocking-network-call
+    'backend
+    (format ":loc-at %s %d %d %d %d %S"
+            (intero-path-for-ghci (intero-temp-file-name))
+            (save-excursion (goto-char beg)
+                            (line-number-at-pos))
+            (save-excursion (goto-char beg)
+                            (1+ (current-column)))
+            (save-excursion (goto-char end)
+                            (line-number-at-pos))
+            (save-excursion (goto-char end)
+                            (1+ (current-column)))
+            (buffer-substring-no-properties beg end)))))
+
+(defun intero-get-loc-at-helper-process (beg end)
+  "Make the blocking call to the process."
+  (replace-regexp-in-string
+   "\n$" ""
+   (intero-blocking-call
+    'backend
+    (format ":loc-at %s %d %d %d %d %S"
+            (intero-path-for-ghci (intero-temp-file-name))
+            (save-excursion (goto-char beg)
+                            (line-number-at-pos))
+            (save-excursion (goto-char beg)
+                            (1+ (current-column)))
+            (save-excursion (goto-char end)
+                            (line-number-at-pos))
+            (save-excursion (goto-char end)
+                            (1+ (current-column)))
+            (buffer-substring-no-properties beg end)))))
+
+(defun intero-get-uses-at (beg end)
+  "Return usage list for identifier denoted by BEG and END."
+  (let ((result (intero-get-uses-at-helper beg end)))
+    (if (string-match (regexp-quote intero-unloaded-module-string)
+                      result)
+        (progn (flycheck-buffer)
+               (message "No use information yet, compiling module ...")
+               (intero-get-uses-at-helper-process beg end))
+      result)))
+
+(defun intero-get-uses-at-helper (beg end)
+  "Return usage list for identifier denoted by BEG and END."
+  (replace-regexp-in-string
+   "\n$" ""
+   (intero-blocking-network-call
+    'backend
+    (format ":uses %s %d %d %d %d %S"
+            (intero-path-for-ghci (intero-temp-file-name))
+            (save-excursion (goto-char beg)
+                            (line-number-at-pos))
+            (save-excursion (goto-char beg)
+                            (1+ (current-column)))
+            (save-excursion (goto-char end)
+                            (line-number-at-pos))
+            (save-excursion (goto-char end)
+                            (1+ (current-column)))
+            (buffer-substring-no-properties beg end)))))
+
+(defun intero-get-uses-at-helper-process (beg end)
+  "Return usage list for identifier denoted by BEG and END."
+  (replace-regexp-in-string
+   "\n$" ""
+   (intero-blocking-call
+    'backend
+    (format ":uses %s %d %d %d %d %S"
+            (intero-path-for-ghci (intero-temp-file-name))
+            (save-excursion (goto-char beg)
+                            (line-number-at-pos))
+            (save-excursion (goto-char beg)
+                            (1+ (current-column)))
+            (save-excursion (goto-char end)
+                            (line-number-at-pos))
+            (save-excursion (goto-char end)
+                            (1+ (current-column)))
+            (buffer-substring-no-properties beg end)))))
+
+(defun intero-get-completions (source-buffer beg end cont)
+  "Get completions and send to SOURCE-BUFFER.
+Prefix is marked by positions BEG and END.  Completions are
+passed to CONT in SOURCE-BUFFER."
+  (intero-async-network-call
+   'backend
+   (format ":complete-at %s %d %d %d %d %S"
+           (intero-path-for-ghci (intero-temp-file-name))
+           (save-excursion (goto-char beg)
+                           (line-number-at-pos))
+           (save-excursion (goto-char beg)
+                           (1+ (current-column)))
+           (save-excursion (goto-char end)
+                           (line-number-at-pos))
+           (save-excursion (goto-char end)
+                           (1+ (current-column)))
+           (buffer-substring-no-properties beg end))
+   (list :cont cont :source-buffer source-buffer)
+   (lambda (state reply)
+     (with-current-buffer
+         (plist-get state :source-buffer)
+       (funcall
+        (plist-get state :cont)
+        (intero-completion-response-to-list reply))))))
+
+(defun intero-completion-response-to-list (reply)
+  "Convert the REPLY from a backend completion to a list."
+  (if (string-match-p "^*** Exception" reply)
+      (list)
+    (mapcar
+     (lambda (x)
+       (replace-regexp-in-string "\\\"" "" x))
+     (split-string reply "\n" t))))
+
+(defun intero-get-repl-completions (source-buffer prefix cont)
+  "Get REPL completions and send to SOURCE-BUFFER.
+Completions for PREFIX are passed to CONT in SOURCE-BUFFER."
+  (intero-async-call
+   'backend
+   (format ":complete repl %S" prefix)
+   (list :cont cont :source-buffer source-buffer)
+   (lambda (state reply)
+     (with-current-buffer
+         (plist-get state :source-buffer)
+       (funcall
+        (plist-get state :cont)
+        (mapcar
+         (lambda (x)
+           (replace-regexp-in-string "\\\"" "" x))
+         (cdr (split-string reply "\n" t))))))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Process communication
+
+(defun intero-call-process (program &optional infile destination display &rest args)
+  "Synchronously call PROGRAM.
+INFILE, DESTINATION, DISPLAY and ARGS are as for
+'call-process'/'process-file'.  Provides TRAMP compatibility for
+'call-process'; when the 'default-directory' is on a remote
+machine, PROGRAM is launched on that machine."
+  (let ((process-args (append (list program infile destination display) args)))
+    (apply 'process-file process-args)))
+
+(defun intero-call-stack (&optional infile destination display stack-yaml &rest args)
+  "Synchronously call stack using the same arguments as `intero-call-process'.
+INFILE, DESTINATION, DISPLAY and ARGS are as for
+`call-process'/`process-file'.  STACK-YAML specifies which stack
+yaml config to use, or stack's default when nil."
+  (let ((stack-yaml-args (when stack-yaml
+                           (list "--stack-yaml" stack-yaml))))
+    (apply #'intero-call-process intero-stack-executable
+           infile destination display
+           (append stack-yaml-args args))))
+
+(defun intero-delete-worker (worker)
+  "Delete the given WORKER."
+  (when (intero-buffer-p worker)
+    (with-current-buffer (intero-get-buffer-create worker)
+      (when (get-buffer-process (current-buffer))
+        (setq intero-deleting t)
+        (kill-process (get-buffer-process (current-buffer)))
+        (delete-process (get-buffer-process (current-buffer))))
+      (kill-buffer (current-buffer)))))
+
+(defun intero-blocking-call (worker cmd)
+  "Send WORKER the command string CMD and block pending its result."
+  (let ((result (list nil)))
+    (intero-async-call
+     worker
+     cmd
+     result
+     (lambda (result reply)
+       (setf (car result) reply)))
+    (let ((buffer (intero-buffer worker)))
+      (while (not (null (buffer-local-value 'intero-callbacks buffer)))
+        (sleep-for 0.0001)))
+    (car result)))
+
+(defun intero-blocking-network-call (worker cmd)
+  "Send WORKER the command string CMD via the network and block pending its result."
+  (let ((result (list nil)))
+    (intero-async-network-call
+     worker
+     cmd
+     result
+     (lambda (result reply)
+       (setf (car result) reply)))
+    (while (eq (car result) nil)
+      (sleep-for 0.0001))
+    (car result)))
+
+(defun intero-async-network-call (worker cmd &optional state callback)
+  "Send WORKER the command string CMD, via a network connection.
+The result, along with the given STATE, is passed to CALLBACK
+as (CALLBACK STATE REPLY)."
+  (if (file-remote-p default-directory)
+      (intero-async-call worker cmd state callback)
+      (let ((buffer (intero-buffer worker)))
+        (if (and buffer (process-live-p (get-buffer-process buffer)))
+            (with-current-buffer buffer
+              (if intero-service-port
+                  (let* ((buffer (generate-new-buffer (format " intero-network:%S" worker)))
+                         (process
+                          (make-network-process
+                           :name (format "%S" worker)
+                           :buffer buffer
+                           :host 'local
+                           :service intero-service-port
+                           :family 'ipv4
+                           :nowait t
+                           :noquery t
+                           :sentinel 'intero-network-call-sentinel)))
+                    (with-current-buffer buffer
+                      (setq intero-async-network-cmd cmd)
+                      (setq intero-async-network-state state)
+                      (setq intero-async-network-worker worker)
+                      (setq intero-async-network-callback callback)))
+                (progn (when intero-debug (message "No `intero-service-port', falling back ..."))
+                       (intero-async-call worker cmd state callback))))
+          (error "Intero process is not running: run M-x intero-restart to start it")))))
+
+(defun intero-network-call-sentinel (process event)
+  (pcase event
+    ;; This event sometimes gets sent when (delete-process) is called, but
+    ;; inconsistently. We can't rely on it for killing buffers, but we need to
+    ;; handle the possibility.
+    ("deleted\n")
+
+    ("open\n"
+     (with-current-buffer (process-buffer process)
+       (when intero-debug (message "Connected to service, sending %S" intero-async-network-cmd))
+       (setq intero-async-network-connected t)
+       (if intero-async-network-cmd
+           (process-send-string process (concat intero-async-network-cmd "\n"))
+         (delete-process process)
+         (kill-buffer (process-buffer process)))))
+    (_
+     (with-current-buffer (process-buffer process)
+       (if intero-async-network-connected
+           (when intero-async-network-callback
+             (when intero-debug (message "Calling callback with %S" (buffer-string)))
+             (funcall intero-async-network-callback
+                      intero-async-network-state
+                      (buffer-string)))
+         ;; We didn't successfully connect, so let's fallback to the
+         ;; process pipe.
+         (when intero-async-network-callback
+           (when intero-debug (message "Failed to connect, falling back ... "))
+           (setq intero-async-network-callback nil)
+           (intero-async-call
+            intero-async-network-worker
+            intero-async-network-cmd
+            intero-async-network-state
+            intero-async-network-callback))))
+     (delete-process process)
+     (kill-buffer (process-buffer process)))))
+
+(defun intero-async-call (worker cmd &optional state callback)
+  "Send WORKER the command string CMD.
+The result, along with the given STATE, is passed to CALLBACK
+as (CALLBACK STATE REPLY)."
+  (let ((buffer (intero-buffer worker)))
+    (if (and buffer (process-live-p (get-buffer-process buffer)))
+        (progn (with-current-buffer buffer
+                 (setq intero-callbacks
+                       (append intero-callbacks
+                               (list (list state
+                                           (or callback #'ignore)
+                                           cmd)))))
+               (when intero-debug
+                 (message "[Intero] -> %s" cmd))
+               (comint-simple-send (intero-process worker) cmd))
+      (error "Intero process is not running: run M-x intero-restart to start it"))))
+
+(defun intero-buffer (worker)
+  "Get the WORKER buffer for the current directory."
+  (let ((buffer (intero-get-buffer-create worker))
+        (targets (buffer-local-value 'intero-targets (current-buffer))))
+    (if (get-buffer-process buffer)
+        buffer
+      (intero-get-worker-create worker targets (current-buffer)
+                                (buffer-local-value
+                                 'intero-stack-yaml (current-buffer))))))
+
+(defun intero-process (worker)
+  "Get the WORKER process for the current directory."
+  (get-buffer-process (intero-buffer worker)))
+
+(defun intero-get-worker-create (worker &optional targets source-buffer stack-yaml)
+  "Start the given WORKER.
+If provided, use the specified TARGETS, SOURCE-BUFFER and STACK-YAML."
+  (let* ((buffer (intero-get-buffer-create worker)))
+    (if (get-buffer-process buffer)
+        buffer
+      (let ((install-status (intero-installed-p)))
+        (if (eq install-status 'installed)
+            (intero-start-process-in-buffer buffer targets source-buffer stack-yaml)
+          (intero-auto-install buffer install-status targets source-buffer stack-yaml))))))
+
+(defun intero-auto-install (buffer install-status &optional targets source-buffer stack-yaml)
+  "Automatically install Intero appropriately for BUFFER.
+INSTALL-STATUS indicates the current installation status.
+If supplied, use the given TARGETS, SOURCE-BUFFER and STACK-YAML."
+  (if (buffer-local-value 'intero-give-up buffer)
+      buffer
+    (let ((source-buffer (or source-buffer (current-buffer))))
+      (switch-to-buffer buffer)
+      (erase-buffer)
+      (insert (cl-case install-status
+                (not-installed "Intero is not installed in the Stack environment.")
+                (wrong-version "The wrong version of Intero is installed for this Emacs package.")))
+      (if (intero-version>= (intero-stack-version) '(1 6 1))
+          (intero-copy-compiler-tool-auto-install source-buffer targets buffer)
+        (intero-old-auto-install source-buffer targets buffer stack-yaml)))))
+
+(defun intero-copy-compiler-tool-auto-install (source-buffer targets buffer)
+  "Automatically install Intero appropriately for BUFFER.
+Use the given TARGETS, SOURCE-BUFFER and STACK-YAML."
+  (let ((ghc-version (intero-ghc-version-raw)))
+    (insert
+     (format "
+
+Installing intero-%s for GHC %s ...
+
+" intero-package-version ghc-version))
+    (redisplay)
+    (cl-case
+        (let ((default-directory (make-temp-file "intero" t)))
+          (intero-call-stack
+           nil (current-buffer) t nil "build"
+           "--copy-compiler-tool"
+           (concat "intero-" intero-package-version)
+           "--flag" "haskeline:-terminfo"
+           "--resolver" (concat "ghc-" ghc-version)
+           "ghc-paths-0.1.0.9" "mtl-2.2.2" "network-2.7.0.0" "random-1.1" "syb-0.7"))
+      (0
+       (message "Installed successfully! Starting Intero in a moment ...")
+       (bury-buffer buffer)
+       (switch-to-buffer source-buffer)
+       (intero-start-process-in-buffer buffer targets source-buffer))
+      (1
+       (with-current-buffer buffer (setq-local intero-give-up t))
+       (insert (propertize "Could not install Intero!
+
+We don't know why it failed. Please read the above output and try
+installing manually. If that doesn't work, report this as a
+problem.
+
+WHAT TO DO NEXT
+
+If you don't want to Intero to try installing itself again for
+this project, just keep this buffer around in your Emacs.
+
+If you'd like to try again next time you try use an Intero
+feature, kill this buffer.
+"
+                           'face 'compilation-error))
+       nil))))
+
+(defun intero-old-auto-install (source-buffer targets buffer stack-yaml)
+  "Automatically install Intero appropriately for BUFFER.
+Use the given TARGETS, SOURCE-BUFFER and STACK-YAML."
+  (insert
+   "
+
+Installing intero-%s automatically ...
+
+" intero-package-version)
+  (redisplay)
+  (cl-case (intero-call-stack
+            nil (current-buffer) t stack-yaml
+            "build"
+            (with-current-buffer buffer
+              (let* ((cabal-file (intero-cabal-find-file))
+                     (package-name (intero-package-name cabal-file)))
+                ;; For local development. Most users'll
+                ;; never hit this behaviour.
+                (if (string= package-name "intero")
+                    "intero"
+                  (concat "intero-" intero-package-version))))
+            "ghc-paths" "syb"
+            "--flag" "haskeline:-terminfo")
+    (0
+     (message "Installed successfully! Starting Intero in a moment ...")
+     (bury-buffer buffer)
+     (switch-to-buffer source-buffer)
+     (intero-start-process-in-buffer buffer targets source-buffer))
+    (1
+     (with-current-buffer buffer (setq-local intero-give-up t))
+     (insert (propertize "Could not install Intero!
+
+We don't know why it failed. Please read the above output and try
+installing manually. If that doesn't work, report this as a
+problem.
+
+WHAT TO DO NEXT
+
+If you don't want to Intero to try installing itself again for
+this project, just keep this buffer around in your Emacs.
+
+If you'd like to try again next time you try use an Intero
+feature, kill this buffer.
+"
+                         'face 'compilation-error))
+     nil)))
+
+(defun intero-start-process-in-buffer (buffer &optional targets source-buffer stack-yaml)
+  "Start an Intero worker in BUFFER.
+Uses the specified TARGETS if supplied.
+Automatically performs initial actions in SOURCE-BUFFER, if specified.
+Uses the default stack config file, or STACK-YAML file if given."
+  (if (buffer-local-value 'intero-give-up buffer)
+      buffer
+    (let* ((options
+            (intero-make-options-list
+             (intero-executable-path stack-yaml)
+             (or targets
+                 (let ((package-name (buffer-local-value 'intero-package-name buffer)))
+                   (unless (equal "" package-name)
+                     (list package-name))))
+             (not (buffer-local-value 'intero-try-with-build buffer))
+             t ;; pass --no-load to stack
+             t ;; pass -ignore-dot-ghci to intero
+             stack-yaml ;; let stack choose a default when nil
+             ))
+           (arguments (cons "ghci" options))
+           (process (with-current-buffer buffer
+                      (when intero-debug
+                        (message "Intero arguments: %s" (combine-and-quote-strings arguments)))
+                      (message "Booting up intero ...")
+                      (apply #'start-file-process "stack" buffer intero-stack-executable
+                             arguments))))
+      (set-process-query-on-exit-flag process nil)
+      (process-send-string process ":set -fobject-code\n")
+      (process-send-string process ":set -fdefer-type-errors\n")
+      (process-send-string process ":set -fdiagnostics-color=never\n")
+      (process-send-string process ":set prompt \"\\4\"\n")
+      (with-current-buffer buffer
+        (erase-buffer)
+        (when stack-yaml
+          (setq intero-stack-yaml stack-yaml))
+        (setq intero-targets targets)
+        (setq intero-start-time (current-time))
+        (setq intero-source-buffer source-buffer)
+        (setq intero-arguments arguments)
+        (setq intero-starting t)
+        (setq intero-callbacks
+              (list (list (cons source-buffer
+                                buffer)
+                          (lambda (buffers msg)
+                            (let ((source-buffer (car buffers))
+                                  (process-buffer (cdr buffers)))
+                              (with-current-buffer process-buffer
+                                (when (string-match "^Intero-Service-Port: \\([0-9]+\\)\n" msg)
+                                  (setq intero-service-port (string-to-number (match-string 1 msg))))
+                                (setq-local intero-starting nil))
+                              (when source-buffer
+                                (with-current-buffer source-buffer
+                                  (when flycheck-mode
+                                    (run-with-timer 0 nil
+                                                    'intero-call-in-buffer
+                                                    (current-buffer)
+                                                    'intero-flycheck-buffer)))))
+                            (message "Booted up intero!"))))))
+      (set-process-filter
+       process
+       (lambda (process string)
+         (when intero-debug
+           (message "[Intero] <- %s" string))
+         (when (buffer-live-p (process-buffer process))
+           (with-current-buffer (process-buffer process)
+             (goto-char (point-max))
+             (insert string)
+             (when (and intero-try-with-build
+                        intero-starting)
+               (let ((last-line (buffer-substring-no-properties
+                                 (line-beginning-position)
+                                 (line-end-position))))
+                 (if (string-match-p "^Progress" last-line)
+                     (message "Booting up intero (building dependencies: %s)"
+                              (downcase
+                               (or (car (split-string (replace-regexp-in-string
+                                                       "\u0008+" "\n"
+                                                       last-line)
+                                                      "\n" t))
+                                   "...")))
+                   (message "Booting up intero ..."))))
+             (intero-read-buffer)))))
+      (set-process-sentinel process 'intero-sentinel)
+      buffer)))
+
+(defun intero-flycheck-buffer ()
+  "Run flycheck in the buffer.
+Restarts flycheck in case there was a problem and flycheck is stuck."
+  (flycheck-mode -1)
+  (flycheck-mode)
+  (flycheck-buffer))
+
+(defun intero-make-options-list (with-ghc targets no-build no-load ignore-dot-ghci stack-yaml)
+  "Make the stack ghci options list.
+TARGETS are the build targets.  When non-nil, NO-BUILD and
+NO-LOAD enable the correspondingly-named stack options.  When
+IGNORE-DOT-GHCI is non-nil, it enables the corresponding GHCI
+option.  STACK-YAML is the stack config file to use (or stack's
+default when nil)."
+  (append (when stack-yaml
+            (list "--stack-yaml" stack-yaml))
+          (list "--with-ghc"
+                with-ghc
+                "--docker-run-args=--interactive=true --tty=false"
+                )
+          (when no-build
+            (list "--no-build"))
+          (when no-load
+            (list "--no-load"))
+          (when ignore-dot-ghci
+            (list "--ghci-options" "-ignore-dot-ghci"))
+          (cl-mapcan (lambda (x) (list "--ghci-options" x)) intero-extra-ghc-options)
+          targets))
+
+(defun intero-sentinel (process change)
+  "Handle when PROCESS reports a CHANGE.
+This is a standard process sentinel function."
+  (when (buffer-live-p (process-buffer process))
+    (when (and (not (process-live-p process)))
+      (let ((buffer (process-buffer process)))
+        (if (with-current-buffer buffer intero-deleting)
+            (message "Intero process deleted.")
+          (if (and (intero-unsatisfied-package-p buffer)
+                   (not (buffer-local-value 'intero-try-with-build buffer)))
+              (progn (with-current-buffer buffer (setq-local intero-try-with-build t))
+                     (intero-start-process-in-buffer
+                      buffer
+                      (buffer-local-value 'intero-targets buffer)
+                      (buffer-local-value 'intero-source-buffer buffer)))
+            (progn (with-current-buffer buffer (setq-local intero-give-up t))
+                   (intero-show-process-problem process change))))))))
+
+(defun intero-unsatisfied-package-p (buffer)
+  "Return non-nil if BUFFER contain GHCi's unsatisfied package complaint."
+  (with-current-buffer buffer
+    (save-excursion
+      (goto-char (point-min))
+      (search-forward-regexp "cannot satisfy -package" nil t 1))))
+
+(defun intero-executable-path (stack-yaml)
+  "The path for the intero executable."
+  (intero-with-temp-buffer
+    (cl-case (save-excursion
+               (intero-call-stack
+                nil (current-buffer) t intero-stack-yaml "path" "--compiler-tools-bin"))
+      (0 (replace-regexp-in-string "[\r\n]+$" "/intero" (buffer-string)))
+      (1 "intero"))))
+
+(defun intero-installed-p ()
+  "Return non-nil if intero (of the right version) is installed in the stack environment."
+  (redisplay)
+  (intero-with-temp-buffer
+    (if (= 0 (intero-call-stack
+              nil t nil intero-stack-yaml
+              "exec"
+              "--verbosity" "silent"
+              "--"
+              (intero-executable-path intero-stack-yaml)
+              "--version"))
+        (progn
+          (goto-char (point-min))
+          ;; This skipping comes due to https://github.com/commercialhaskell/intero/pull/216/files
+          (when (looking-at "Intero ")
+            (goto-char (match-end 0)))
+          ;;
+          (if (string= (buffer-substring (point) (line-end-position))
+                       intero-package-version)
+              'installed
+            'wrong-version))
+      'not-installed)))
+
+(defun intero-show-process-problem (process change)
+  "Report to the user that PROCESS reported CHANGE, causing it to end."
+  (message "Problem with Intero!")
+  (switch-to-buffer (process-buffer process))
+  (goto-char (point-max))
+  (insert "\n---\n\n")
+  (insert
+   (propertize
+    (concat
+     "This is the buffer where Emacs talks to intero. It's normally hidden,
+but a problem occcured.
+
+TROUBLESHOOTING
+
+It may be obvious if there is some text above this message
+indicating a problem.
+
+If you do not wish to use Intero for some projects, see
+https://github.com/commercialhaskell/intero#whitelistingblacklisting-projects
+
+The process ended. Here is the reason that Emacs gives us:
+
+"
+     "  " change
+     "\n"
+     "For troubleshooting purposes, here are the arguments used to launch intero:
+
+"
+     (format "  %s %s"
+             intero-stack-executable
+             (combine-and-quote-strings intero-arguments))
+
+     "
+
+It's worth checking that the correct stack executable is being
+found on your path, or has been set via
+`intero-stack-executable'.  The executable being used now is:
+
+  "
+     (executable-find intero-stack-executable)
+     "
+
+WHAT TO DO NEXT
+
+If you fixed the problem, just kill this buffer, Intero will make
+a fresh one and attempt to start the process automatically as
+soon as you start editing code again.
+
+If you are unable to fix the problem, just leave this buffer
+around in Emacs and Intero will not attempt to start the process
+anymore.
+
+You can always run M-x intero-restart to make it try again.
+
+")
+    'face 'compilation-error)))
+
+(defun intero-read-buffer ()
+  "In the process buffer, we read what's in it."
+  (let ((repeat t))
+    (while repeat
+      (setq repeat nil)
+      (goto-char (point-min))
+      (when (search-forward "\4" (point-max) t 1)
+        (let* ((next-callback (pop intero-callbacks))
+               (state (nth 0 next-callback))
+               (func (nth 1 next-callback)))
+          (let ((string (intero-strip-carriage-returns (buffer-substring (point-min) (1- (point))))))
+            (if next-callback
+                (progn (intero-with-temp-buffer
+                         (funcall func state string))
+                       (setq repeat t))
+              (when intero-debug
+                (intero--warn "Received output but no callback in `intero-callbacks': %S"
+                              string)))))
+        (delete-region (point-min) (point))))))
+
+(defun intero-strip-carriage-returns (string)
+  "Strip the \\r from Windows \\r\\n line endings in STRING."
+  (replace-regexp-in-string "\r" "" string))
+
+(defun intero-get-buffer-create (worker)
+  "Get or create the stack buffer for WORKER.
+Uses the directory of the current buffer for context."
+  (let* ((root (intero-extend-path-by-buffer-host (intero-project-root)))
+         (cabal-file (intero-cabal-find-file))
+         (package-name (if cabal-file
+                           (intero-package-name cabal-file)
+                         ""))
+         (initial-buffer (current-buffer))
+         (buffer-name (intero-buffer-name worker))
+         (default-directory (if cabal-file
+                                (file-name-directory cabal-file)
+                              root)))
+    (with-current-buffer
+        (get-buffer-create buffer-name)
+      (intero-inherit-local-variables initial-buffer)
+      (setq intero-package-name package-name)
+      (cd default-directory)
+      (current-buffer))))
+
+(defun intero-gave-up (worker)
+  "Return non-nil if starting WORKER or installing intero failed."
+  (and (intero-buffer-p worker)
+       (let ((buffer (get-buffer (intero-buffer-name worker))))
+         (buffer-local-value 'intero-give-up buffer))))
+
+(defun intero-buffer-p (worker)
+  "Return non-nil if a buffer exists for WORKER."
+  (get-buffer (intero-buffer-name worker)))
+
+(defun intero-buffer-name (worker)
+  "For a given WORKER, create a buffer name."
+  (let* ((root (intero-project-root))
+         (package-name (intero-package-name)))
+    (concat " intero:"
+            (format "%s" worker)
+            ":"
+            package-name
+            " "
+            root)))
+
+(defun intero-project-root ()
+  "Get the current stack config directory.
+This is the directory where the file specified in
+`intero-stack-yaml' is located, or if nil then the directory
+where stack.yaml is placed for this project, or the global one if
+no such project-specific config exists."
+  (if intero-project-root
+      intero-project-root
+    (let ((stack-yaml intero-stack-yaml))
+      (setq intero-project-root
+            (intero-with-temp-buffer
+              (cl-case (save-excursion
+                         (intero-call-stack nil (current-buffer) nil stack-yaml
+                                            "path"
+                                            "--project-root"
+                                            "--verbosity" "silent"))
+                (0 (buffer-substring (line-beginning-position) (line-end-position)))
+                (t (intero--warn "Couldn't get the Stack project root.
+
+This can be caused by a syntax error in your stack.yaml file. Check that out.
+
+If you do not wish to use Intero for some projects, see
+https://github.com/commercialhaskell/intero#whitelistingblacklisting-projects
+
+Otherwise, please report this as a bug!
+
+For debugging purposes, try running the following in your terminal:
+
+%s path --project-root" intero-stack-executable)
+                   nil)))))))
+
+(defun intero-ghc-version ()
+  "Get the GHC version used by the project, calls only once per backend."
+  (with-current-buffer (intero-buffer 'backend)
+    (or intero-ghc-version
+        (setq intero-ghc-version
+              (intero-ghc-version-raw)))))
+
+(defun intero-ghc-version-raw ()
+  "Get the GHC version used by the project."
+  (intero-with-temp-buffer
+    (cl-case (save-excursion
+               (intero-call-stack
+                nil (current-buffer) t intero-stack-yaml
+                "ghc" "--" "--numeric-version"))
+      (0
+       (buffer-substring (line-beginning-position) (line-end-position)))
+      (1 nil))))
+
+(defun intero-version>= (new0 old0)
+  "Is the version NEW >= OLD?"
+  (or (and (null new0) (null old0))
+      (let ((new (or new0 (list 0)))
+            (old (or old0 (list 0))))
+        (or (> (car new)
+               (car old))
+            (and (= (car new)
+                    (car old))
+                 (intero-version>= (cdr new)
+                                   (cdr old)))))))
+
+(defun intero-stack-version ()
+  "Get the version components of stack."
+  (let* ((str (intero-stack-version-raw))
+         (parts (mapcar #'string-to-number (split-string str "\\."))))
+    parts))
+
+(defun intero-stack-version-raw ()
+  "Get the Stack version in PATH."
+  (intero-with-temp-buffer
+    (cl-case (save-excursion
+               (intero-call-stack
+                nil (current-buffer) t intero-stack-yaml "--numeric-version"))
+      (0
+       (buffer-substring (line-beginning-position) (line-end-position)))
+      (1 nil))))
+
+(defun intero-get-targets ()
+  "Get all available targets."
+  (with-current-buffer (intero-buffer 'backend)
+    (intero-with-temp-buffer
+      (cl-case (intero-call-stack nil (current-buffer) t
+                                  intero-stack-yaml
+                                  "ide" "targets")
+        (0
+         (cl-remove-if-not
+          (lambda (line)
+            (string-match-p "^[A-Za-z0-9-:_]+$" line))
+          (split-string (buffer-string) "[\r\n]" t)))
+        (1 nil)))))
+
+(defun intero-package-name (&optional cabal-file)
+  "Get the current package name from a nearby .cabal file.
+If there is none, return an empty string.  If specified, use
+CABAL-FILE rather than trying to locate one."
+  (or intero-package-name
+      (setq intero-package-name
+            (let ((cabal-file (or cabal-file
+                                  (intero-cabal-find-file))))
+              (if cabal-file
+                  (replace-regexp-in-string
+                   ".cabal$" ""
+                   (file-name-nondirectory cabal-file))
+                "")))))
+
+(defun intero-cabal-find-file (&optional dir)
+  "Search for package description file upwards starting from DIR.
+If DIR is nil, `default-directory' is used as starting point for
+directory traversal.  Upward traversal is aborted if file owner
+changes.  Uses `intero-cabal-find-pkg-desc' internally."
+  (let ((use-dir (or dir default-directory)))
+    (while (and use-dir (not (file-directory-p use-dir)))
+      (setq use-dir (file-name-directory (directory-file-name use-dir))))
+    (when use-dir
+      (catch 'found
+        (let ((user (nth 2 (file-attributes use-dir)))
+              ;; Abbreviate, so as to stop when we cross ~/.
+              (root (abbreviate-file-name use-dir)))
+          ;; traverse current dir up to root as long as file owner doesn't change
+          (while (and root (equal user (nth 2 (file-attributes root))))
+            (let ((cabal-file (intero-cabal-find-pkg-desc root)))
+              (when cabal-file
+                (throw 'found cabal-file)))
+
+            (let ((proot (file-name-directory (directory-file-name root))))
+              (if (equal proot root) ;; fix-point reached?
+                  (throw 'found nil)
+                (setq root proot))))
+          nil)))))
+
+(defun intero-cabal-find-pkg-desc (dir &optional allow-multiple)
+  "Find a package description file in the directory DIR.
+Returns nil if none or multiple \".cabal\" files were found.  If
+ALLOW-MULTIPLE is non nil, in case of multiple \".cabal\" files,
+a list is returned instead of failing with a nil result."
+  ;; This is basically a port of Cabal's
+  ;; Distribution.Simple.Utils.findPackageDesc function
+  ;;  http://hackage.haskell.org/packages/archive/Cabal/1.16.0.3/doc/html/Distribution-Simple-Utils.html
+  ;; but without the exception throwing.
+  (let* ((cabal-files
+          (cl-remove-if (lambda (path)
+                          (or (file-directory-p path)
+                              (not (file-exists-p path))))
+                        (directory-files dir t ".\\.cabal\\'" t))))
+    (cond
+     ((= (length cabal-files) 1) (car cabal-files)) ;; exactly one candidate found
+     (allow-multiple cabal-files) ;; pass-thru multiple candidates
+     (t nil))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Multiselection
+
+(defvar intero-multiswitch-keymap
+  (let ((map (copy-keymap widget-keymap)))
+    (define-key map (kbd "C-c C-c") 'exit-recursive-edit)
+    (define-key map (kbd "C-c C-k") 'abort-recursive-edit)
+    (define-key map (kbd "C-g")     'abort-recursive-edit)
+    map))
+
+(defun intero-multiswitch (title options)
+  "Displaying TITLE, read multiple flags from a list of OPTIONS.
+Each option is a plist of (:key :default :title) wherein:
+
+  :key should be something comparable with EQUAL
+  :title should be a string
+  :default (boolean) specifies the default checkedness"
+  (let ((available-width (window-total-width)))
+    (save-window-excursion
+      (intero-with-temp-buffer
+        (rename-buffer (generate-new-buffer-name "multiswitch"))
+        (widget-insert (concat title "\n\n"))
+        (widget-insert (propertize "Select options with RET, hit " 'face 'font-lock-comment-face))
+        (widget-create 'push-button :notify
+                       (lambda (&rest ignore)
+                         (exit-recursive-edit))
+                       "C-c C-c")
+        (widget-insert (propertize " to apply these choices, or hit " 'face 'font-lock-comment-face))
+        (widget-create 'push-button :notify
+                       (lambda (&rest ignore)
+                         (abort-recursive-edit))
+                       "C-c C-k")
+        (widget-insert (propertize " to cancel.\n\n" 'face 'font-lock-comment-face))
+        (let* ((me (current-buffer))
+               (choices (mapcar (lambda (option)
+                                  (append option (list :value (plist-get option :default))))
+                                options)))
+          (cl-loop for option in choices
+                   do (widget-create
+                       'toggle
+                       :notify (lambda (widget &rest ignore)
+                                 (setq choices
+                                       (mapcar (lambda (choice)
+                                                 (if (equal (plist-get choice :key)
+                                                            (plist-get (cdr widget) :key))
+                                                     (plist-put choice :value (plist-get (cdr widget) :value))
+                                                   choice))
+                                               choices)))
+                       :on (concat "[x] " (plist-get option :title))
+                       :off (concat "[ ] " (plist-get option :title))
+                       :value (plist-get option :default)
+                       :key (plist-get option :key)))
+          (let ((lines (line-number-at-pos)))
+            (select-window (split-window-below))
+            (switch-to-buffer me)
+            (goto-char (point-min)))
+          (use-local-map intero-multiswitch-keymap)
+          (widget-setup)
+          (recursive-edit)
+          (kill-buffer me)
+          (mapcar (lambda (choice)
+                    (plist-get choice :key))
+                  (cl-remove-if-not (lambda (choice)
+                                      (plist-get choice :value))
+                                    choices)))))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Hoogle
+
+(defun intero-hoogle-blocking-query (query)
+  "Make a request of QUERY using the local hoogle server.
+If running, otherwise returns nil.
+
+It is the responsibility of the caller to make sure the server is
+running; the user might not want to start the server
+automatically."
+  (let ((buffer (intero-hoogle-get-buffer)))
+    (when buffer
+      (let ((url (intero-hoogle-url buffer query)))
+        (with-current-buffer (url-retrieve-synchronously url t)
+          (search-forward "\n\n" nil t 1)
+          (json-read-from-string
+           (buffer-substring (line-beginning-position)
+                             (line-end-position))))))))
+
+(defun intero-hoogle-url (buffer query)
+  "Via hoogle server BUFFER make the HTTP URL for QUERY."
+  (format "http://127.0.0.1:%d/?hoogle=%s&mode=json"
+          (buffer-local-value 'intero-hoogle-port buffer)
+          (url-encode-url query)))
+
+(defun intero-hoogle-get-worker-create ()
+  "Get or create the hoogle worker."
+  (let* ((buffer (intero-hoogle-get-buffer-create)))
+    (if (get-buffer-process buffer)
+        buffer
+      (intero-start-hoogle-process-in-buffer buffer))))
+
+(defun intero-start-hoogle-process-in-buffer (buffer)
+  "Start the process in BUFFER, returning BUFFER."
+  (let* ((port (intero-free-port))
+         (process (with-current-buffer buffer
+                    (message "Booting up hoogle ...")
+                    (setq intero-hoogle-port port)
+                    (start-process "hoogle"
+                                   buffer
+                                   intero-stack-executable
+                                   "hoogle"
+                                   "server"
+                                   "--no-setup"
+                                   "--"
+                                   "--local"
+                                   "--port"
+                                   (number-to-string port)))))
+    (set-process-query-on-exit-flag process nil)
+    (set-process-sentinel process 'intero-hoogle-sentinel)
+    buffer))
+
+(defun intero-free-port ()
+  "Get the next free port to use."
+  (let ((proc (make-network-process
+               :name "port-check"
+               :family 'ipv4
+               :host "127.0.0.1"
+               :service t
+               :server t)))
+    (delete-process proc)
+    (process-contact proc :service)))
+
+(defun intero-hoogle-sentinel (process change)
+  "For the hoogle PROCESS there is a CHANGE to handle."
+  (message "Hoogle sentinel: %S %S" process change))
+
+(defun intero-hoogle-get-buffer-create ()
+  "Get or create the Hoogle buffer for the current stack project."
+  (let* ((root (intero-project-root))
+         (buffer-name (intero-hoogle-buffer-name root))
+         (buf (get-buffer buffer-name))
+         (initial-buffer (current-buffer))
+         (default-directory root))
+    (if buf
+        buf
+      (with-current-buffer (get-buffer-create buffer-name)
+        (intero-inherit-local-variables initial-buffer)
+        (cd default-directory)
+        (current-buffer)))))
+
+(defun intero-hoogle-get-buffer ()
+  "Get the Hoogle buffer for the current stack project."
+  (let* ((root (intero-project-root))
+         (buffer-name (intero-hoogle-buffer-name root)))
+    (get-buffer buffer-name)))
+
+(defun intero-hoogle-buffer-name (root)
+  "For a given worker, create a buffer name using ROOT."
+  (concat "*Hoogle:" root "*"))
+
+(defun intero-hoogle-ready-p ()
+  "Is hoogle ready to be started?"
+  (intero-with-temp-buffer
+    (cl-case (intero-call-stack nil (current-buffer) t intero-stack-yaml
+                                "hoogle" "--no-setup" "--verbosity" "silent")
+      (0 t))))
+
+(defun intero-hoogle-supported-p ()
+  "Is the stack hoogle command supported?"
+  (intero-with-temp-buffer
+    (cl-case (intero-call-stack nil (current-buffer) t
+                                intero-stack-yaml
+                                "hoogle" "--help")
+      (0 t))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Collecting information from compiler messages
+
+(defun intero-collect-compiler-messages (msgs)
+  "Collect information from compiler MSGS.
+
+This may update in-place the MSGS objects to hint that
+suggestions are available."
+  (setq intero-suggestions nil)
+  (let ((extension-regex (concat " " (regexp-opt (intero-extensions) t) "\\>"))
+        (quoted-symbol-regex "[‘`‛]\\([^ ]+\\)['’]"))
+    (cl-loop
+     for msg in msgs
+     do (let ((text (flycheck-error-message msg))
+              (note nil))
+          ;; Messages of this format:
+          ;;
+          ;;     • Constructor ‘Assert’ does not have the required strict field(s): assertName,
+          ;; assertDoc, assertExpression,
+          ;; assertSection
+          (let ((start 0))
+            (while (or
+                    (string-match "does not have the required strict field.*?:[\n\t\r ]" text start)
+                    (string-match "Fields of .*? not initialised:[\n\t\r ]" text start))
+              (let* ((match-end (match-end 0))
+                     (fields
+                      (let ((reached-end nil))
+                        (mapcar
+                         (lambda (field)
+                           (with-temp-buffer
+                             (insert field)
+                             (goto-char (point-min))
+                             (intero-ident-at-point)))
+                         (cl-remove-if
+                          (lambda (field)
+                            (or reached-end
+                                (when (string-match "[\r\n]" field)
+                                  (setq reached-end t)
+                                  nil)))
+                          (split-string
+                           (substring text match-end)
+                           "[\n\t\r ]*,[\n\t\r ]*" t))))))
+                (setq note t)
+                (add-to-list
+                 'intero-suggestions
+                 (list :type 'add-missing-fields
+                       :fields fields
+                       :line (flycheck-error-line msg)
+                       :column (flycheck-error-column msg)))
+                (setq start (min (length text) (1+ match-end))))))
+
+          ;; Messages of this format:
+          ;;
+          ;; Can't make a derived instance of ‘Functor X’:
+          ;;       You need DeriveFunctor to derive an instance for this class
+          ;;       Try GeneralizedNewtypeDeriving for GHC's newtype-deriving extension
+          ;;       In the newtype declaration for ‘X’
+          (let ((start 0))
+            (while (let ((case-fold-search nil))
+                     (string-match extension-regex text start))
+              (setq note t)
+              (add-to-list 'intero-suggestions
+                           (list :type 'add-extension
+                                 :extension (match-string 1 text)))
+              (setq start (min (length text) (1+ (match-end 0))))))
+          ;; Messages of this format:
+          ;;
+          ;; Could not find module ‘Language.Haskell.TH’
+          ;;     It is a member of the hidden package ‘template-haskell’.
+          ;;     Use -v to see a list of the files searched for....
+          (let ((start 0))
+            (while (string-match "It is a member of the hidden package [‘`‛]\\([^ ]+\\)['’]" text start)
+              (setq note t)
+              (add-to-list 'intero-suggestions
+                           (list :type 'add-package
+                                 :package (match-string 1 text)))
+              (setq start (min (length text) (1+ (match-end 0))))))
+          ;; Messages of this format:
+          ;; Expected type: String
+          ;; Actual type: Data.Text.Internal.Builder.Builder
+          (let ((start 0))
+            (while (or (string-match
+                        "Expected type: String" text start)
+                       (string-match
+                        "Actual type: String" text start)
+                       (string-match
+                        "Actual type: \\[Char\\]" text start)
+                       (string-match
+                        "Expected type: \\[Char\\]" text start))
+              (setq note t)
+              (add-to-list 'intero-suggestions
+                           (list :type 'add-extension
+                                 :extension "OverloadedStrings"))
+              (setq start (min (length text) (1+ (match-end 0))))))
+          ;; Messages of this format:
+          ;;
+          ;; Defaulting the following constraint(s) to type ‘Integer’
+          ;;   (Num a0) arising from the literal ‘1’
+          ;; In the expression: 2
+          ;; In an equation for ‘x'’: x' = 2
+          (let ((start 0))
+            (while (string-match
+                    " Defaulting the following constraint" text start)
+              (setq note t)
+              (add-to-list 'intero-suggestions
+                           (list :type 'add-ghc-option
+                                 :option "-fno-warn-type-defaults"))
+              (setq start (min (length text) (1+ (match-end 0))))))
+          ;; Messages of this format:
+          ;;
+          ;;     This binding for ‘x’ shadows the existing binding
+          (let ((start 0))
+            (while (string-match
+                    " This binding for ‘\\(.*\\)’ shadows the existing binding" text start)
+              (setq note t)
+              (add-to-list 'intero-suggestions
+                           (list :type 'add-ghc-option
+                                 :option "-fno-warn-name-shadowing"))
+              (setq start (min (length text) (1+ (match-end 0))))))
+          ;; Messages of this format:
+          ;; Perhaps you want to add ‘foo’ to the import list
+          ;; in the import of ‘Blah’
+          ;; (/path/to/thing:19
+          (when (string-match "Perhaps you want to add [‘`‛]\\([^ ]+\\)['’][\n ]+to[\n ]+the[\n ]+import[\n ]+list[\n ]+in[\n ]+the[\n ]+import[\n ]+of[\n ]+[‘`‛]\\([^ ]+\\)['’][\n ]+(\\([^ ]+\\):(?\\([0-9]+\\)[:,]"
+                              text)
+            (let ((ident (match-string 1 text))
+                  (module (match-string 2 text))
+                  (file (match-string 3 text))
+                  (line (string-to-number (match-string 4 text))))
+              (setq note t)
+              (add-to-list 'intero-suggestions
+                           (list :type 'add-to-import
+                                 :module module
+                                 :ident ident
+                                 :line line))))
+          ;; Messages of this format:
+          ;;
+          ;; The import of ‘Control.Monad’ is redundant
+          ;;   except perhaps to import instances from ‘Control.Monad’
+          ;; To import instances alone, use: import Control.Monad()... (intero)
+          (when (string-match
+                 " The \\(qualified \\)?import of[ ][‘`‛]\\([^ ]+\\)['’] is redundant"
+                 text)
+            (setq note t)
+            (add-to-list 'intero-suggestions
+                         (list :type 'remove-import
+                               :module (match-string 2 text)
+                               :line (flycheck-error-line msg))))
+          ;; Messages of this format:
+          ;;
+          ;; Not in scope: ‘putStrn’
+          ;; Perhaps you meant one of these:
+          ;;   ‘putStr’ (imported from Prelude),
+          ;;   ‘putStrLn’ (imported from Prelude)
+          ;;
+          ;; Or this format:
+          ;;
+          ;; error:
+          ;;    • Variable not in scope: lopSetup :: [Statement Exp']
+          ;;    • Perhaps you meant ‘loopSetup’ (line 437)
+          (when (string-match
+                 "[Nn]ot in scope: \\(data constructor \\|type constructor or class \\)?[‘`‛]?\\([^'’ ]+\\).*\n.*Perhaps you meant"
+                 text)
+            (let ((typo (match-string 2 text))
+                  (start (min (length text) (1+ (match-end 0)))))
+              (while (string-match quoted-symbol-regex text start)
+                (setq note t)
+                (add-to-list 'intero-suggestions
+                             (list :type 'fix-typo
+                                   :typo typo
+                                   :replacement (match-string 1 text)
+                                   :column (flycheck-error-column msg)
+                                   :line (flycheck-error-line msg)))
+                (setq start (min (length text) (1+ (match-end 0)))))))
+          ;; Messages of this format:
+          ;;
+          ;;     Top-level binding with no type signature: main :: IO ()
+          (when (string-match
+                 "Top-level binding with no type signature:"
+                 text)
+            (let ((start (min (length text) (match-end 0))))
+              (setq note t)
+              (add-to-list 'intero-suggestions
+                           (list :type 'add-signature
+                                 :signature (mapconcat #'identity (split-string (substring text start)) " ")
+                                 :line (flycheck-error-line msg)))))
+          ;; Messages of this format:
+          (when (string-match "The import of [‘`‛]\\(.+?\\)[’`'][\n ]+from[\n ]+module[\n ]+[‘`‛]\\(.+?\\)[’`'][\n ]+is[\n ]+redundant" text)
+            (let ((module (match-string 2 text))
+                  (idents (split-string (match-string 1 text) "," t "[ \n]+")))
+              (setq note t)
+              (add-to-list 'intero-suggestions
+                           (list :type 'redundant-import-item
+                                 :idents idents
+                                 :line (flycheck-error-line msg)
+                                 :module module))))
+          ;; Messages of this format:
+          ;;
+          ;;     Redundant constraints: (Arith var, Bitwise var)
+          ;; Or
+          ;;     Redundant constraint: Arith var
+          ;; Or
+          ;;     Redundant constraints: (Arith var,
+          ;;                             Bitwise var,
+          ;;                             Functor var,
+          ;;                             Applicative var,
+          ;;                             Monad var)
+          (when (string-match "Redundant constraints?: " text)
+            (let* ((redundant-start (match-end 0))
+                   (parts (intero-with-temp-buffer
+                            (insert (substring text redundant-start))
+                            (goto-char (point-min))
+                            ;; A lone unparenthesized constraint might
+                            ;; be multiple sexps.
+                            (while (not (eq (point) (point-at-eol)))
+                              (forward-sexp))
+                            (let ((redundant-end (point)))
+                              (search-forward-regexp ".*\n.*In the ")
+                              (cons (buffer-substring (point-min) redundant-end)
+                                    (buffer-substring (match-end 0) (point-max)))))))
+              (setq note t)
+              (add-to-list
+               'intero-suggestions
+               (let ((rest (cdr parts))
+                     (redundant (let ((raw (car parts)))
+                                  (if (eq (string-to-char raw) ?\()
+                                      (substring raw 1 (1- (length raw)))
+                                    raw))))
+                 (list :type 'redundant-constraint
+                       :redundancies (mapcar #'string-trim
+                                             (intero-parse-comma-list redundant))
+                       :signature (mapconcat #'identity (split-string rest) " ")
+                       :line (flycheck-error-line msg))))))
+          ;; Add a note if we found a suggestion to make
+          (when note
+            (setf (flycheck-error-message msg)
+                  (concat text
+                          "\n\n"
+                          (propertize "(Hit `C-c C-r' in the Haskell buffer to apply suggestions)"
+                                      'face 'font-lock-warning-face)))))))
+  (setq intero-lighter
+        (if (null intero-suggestions)
+            " Intero"
+          (format " Intero:%d" (length intero-suggestions)))))
+
+(defun intero-extensions ()
+  "Get extensions for the current project's GHC."
+  (with-current-buffer (intero-buffer 'backend)
+    (or intero-extensions
+        (setq intero-extensions
+              (cl-remove-if-not
+               (lambda (str) (let ((case-fold-search nil))
+                               (string-match "^[A-Z][A-Za-z0-9]+$" str)))
+               (split-string
+                (shell-command-to-string
+                 (concat intero-stack-executable
+                         (if intero-stack-yaml
+                             (concat "--stack-yaml " intero-stack-yaml)
+                           "")
+                         " exec --verbosity silent -- ghc --supported-extensions"))))))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Auto actions
+
+(defun intero-parse-comma-list (text)
+  "Parse a list of comma-separated expressions in TEXT."
+  (cl-loop for tok in (split-string text "[[:space:]\n]*,[[:space:]\n]*")
+           with acc = nil
+           append (let* ((clist (string-to-list tok))
+                         (num-open (-count (lambda (c) (or (eq c ?\() (eq c ?\[)))
+                                           clist))
+                         (num-close (-count (lambda (c) (or (eq c ?\)) (eq c ?\])))
+                                            clist)))
+                    (cond
+                     ((> num-open num-close) (progn (add-to-list 'acc tok) nil))
+                     ((> num-close num-open) (let ((tmp (reverse (cons tok acc))))
+                                               (setq acc nil)
+                                               (list (string-join tmp ", "))))
+                     (t (list tok))))))
+
+(defun intero-apply-suggestions ()
+  "Prompt and apply the suggestions."
+  (interactive)
+  (if (null intero-suggestions)
+      (message "No suggestions to apply")
+    (let ((to-apply
+           (intero-multiswitch
+            (format "There are %d suggestions to apply:" (length intero-suggestions))
+            (cl-remove-if-not
+             #'identity
+             (mapcar
+              (lambda (suggestion)
+                (cl-case (plist-get suggestion :type)
+                  (add-to-import
+                   (list :key suggestion
+                         :title (format "Add ‘%s’ to import of ‘%s’"
+                                        (plist-get suggestion :ident)
+                                        (plist-get suggestion :module))
+                         :default t))
+                  (add-missing-fields
+                   (list :key suggestion
+                         :default t
+                         :title
+                         (format "Add missing fields to record: %s"
+                                 (mapconcat (lambda (ident)
+                                              (concat "‘" ident "’"))
+                                            (plist-get suggestion :fields)
+                                            ", "))))
+                  (redundant-import-item
+                   (list :key suggestion
+                         :title
+                         (format "Remove redundant imports %s from import of ‘%s’"
+                                 (mapconcat (lambda (ident)
+                                              (concat "‘" ident "’"))
+                                            (plist-get suggestion :idents) ", ")
+                                 (plist-get suggestion :module))
+                         :default t))
+                  (add-extension
+                   (list :key suggestion
+                         :title (concat "Add {-# LANGUAGE "
+                                        (plist-get suggestion :extension)
+                                        " #-}")
+                         :default (not (string= "OverloadedStrings" (plist-get suggestion :extension)))))
+                  (add-ghc-option
+                   (list :key suggestion
+                         :title (concat "Add {-# OPTIONS_GHC "
+                                        (plist-get suggestion :option)
+                                        " #-}")
+                         :default (not
+                                   (string=
+                                    (plist-get suggestion :option)
+                                    "-fno-warn-name-shadowing"))))
+                  (add-package
+                   (list :key suggestion
+                         :title (concat "Enable package: " (plist-get suggestion :package))
+                         :default t))
+                  (remove-import
+                   (list :key suggestion
+                         :title (concat "Remove: import "
+                                        (plist-get suggestion :module))
+                         :default t))
+                  (fix-typo
+                   (list :key suggestion
+                         :title (concat "Replace ‘"
+                                        (plist-get suggestion :typo)
+                                        "’ with ‘"
+                                        (plist-get suggestion :replacement)
+                                        "’")
+                         :default (null (cdr intero-suggestions))))
+                  (add-signature
+                   (list :key suggestion
+                         :title (concat "Add signature: "
+                                        (plist-get suggestion :signature))
+                         :default t))
+                  (redundant-constraint
+                   (list :key suggestion
+                         :title (concat
+                                 "Remove redundant constraints: "
+                                 (string-join (plist-get suggestion :redundancies)
+                                              ", ")
+                                 "\n    from the "
+                                 (plist-get suggestion :signature))
+                         :default nil))))
+              intero-suggestions)))))
+      (if (null to-apply)
+          (message "No changes selected to apply.")
+        (let ((sorted (sort to-apply
+                            (lambda (lt gt)
+                              (let ((lt-line   (or (plist-get lt :line)   0))
+                                    (lt-column (or (plist-get lt :column) 0))
+                                    (gt-line   (or (plist-get gt :line)   0))
+                                    (gt-column (or (plist-get gt :column) 0)))
+                                (or (> lt-line gt-line)
+                                    (and (= lt-line gt-line)
+                                         (> lt-column gt-column))))))))
+          ;; # Changes unrelated to the buffer
+          (cl-loop
+           for suggestion in sorted
+           do (cl-case (plist-get suggestion :type)
+                (add-package
+                 (intero-add-package (plist-get suggestion :package)))))
+          ;; # Changes that do not increase/decrease line numbers
+          ;;
+          ;; Update in-place suggestions
+          (cl-loop
+           for suggestion in sorted
+           do (cl-case (plist-get suggestion :type)
+                (add-to-import
+                 (save-excursion
+                   (goto-char (point-min))
+                   (forward-line (1- (plist-get suggestion :line)))
+                   (when (and (search-forward (plist-get suggestion :module) nil t 1)
+                              (search-forward "(" nil t 1))
+                     (insert (if (string-match-p "^[_a-zA-Z]" (plist-get suggestion :ident))
+                                 (plist-get suggestion :ident)
+                               (concat "(" (plist-get suggestion :ident) ")")))
+                     (unless (looking-at-p "[:space:]*)")
+                       (insert ", ")))))
+                (redundant-import-item
+                 (save-excursion
+                   (goto-char (point-min))
+                   (forward-line (1- (plist-get suggestion :line)))
+                   (let* ((case-fold-search nil)
+                          (start (search-forward "(" nil t 1))
+                          (end (or (save-excursion
+                                     (when (search-forward-regexp "\n[^ \t]" nil t 1)
+                                       (1- (point))))
+                                   (line-end-position)))
+                          (regex
+                           (concat
+                            "\\("
+                            (mapconcat
+                             (lambda (ident)
+                               (if (string-match-p "^[_a-zA-Z]" ident)
+                                   (concat "\\<" (regexp-quote ident) "\\> ?" "\\("(regexp-quote "(..)") "\\)?")
+                                 (concat "(" (regexp-quote ident) ")")))
+                             (plist-get suggestion :idents)
+                             "\\|")
+                            "\\)"))
+                          (string (buffer-substring start end)))
+                     (delete-region start end)
+                     (insert
+                      (replace-regexp-in-string
+                       ",[\n ]*)" ")"
+                       (replace-regexp-in-string
+                        "^[\n ,]*" ""
+                        (replace-regexp-in-string
+                         "[\n ,]*,[\n ,]*" ", "
+                         (replace-regexp-in-string
+                          ",[\n ]*)" ")"
+                          (replace-regexp-in-string
+                           regex ""
+                           string)))))
+                      (make-string (1- (length (split-string string "\n" t))) 10)))))
+                (fix-typo
+                 (save-excursion
+                   (goto-char (point-min))
+                   (forward-line (1- (plist-get suggestion :line)))
+                   (move-to-column (- (plist-get suggestion :column) 1))
+                   (delete-char (length (plist-get suggestion :typo)))
+                   (insert (plist-get suggestion :replacement))))
+                (add-missing-fields
+                 (save-excursion
+                   (goto-char (point-min))
+                   (forward-line (1- (plist-get suggestion :line)))
+                   (move-to-column (- (plist-get suggestion :column) 1))
+                   (search-forward "{")
+                   (unless (looking-at "}")
+                     (save-excursion (insert ", ")))
+                   (insert (mapconcat (lambda (field) (concat field " = _"))
+                                      (plist-get suggestion :fields)
+                                      ", "))))))
+          ;; # Changes that do increase/decrease line numbers
+          ;;
+          ;; Remove redundant constraints
+          (cl-loop
+           for suggestion in sorted
+           do (cl-case (plist-get suggestion :type)
+                (redundant-constraint
+                 (save-excursion
+                   (goto-char (point-min))
+                   (forward-line (1- (plist-get suggestion :line)))
+                   (search-forward-regexp "[[:alnum:][:space:]\n]*=>")
+                   (backward-sexp 2)
+                   (let ((start (1+ (point))))
+                     (forward-sexp)
+                     (let* ((end (1- (point)))
+                            (constraints (intero-parse-comma-list
+                                          (buffer-substring start end)))
+                            (nonredundant
+                             (cl-loop for r in (plist-get suggestion :redundancies)
+                                      with nonredundant = constraints
+                                      do (setq nonredundant (delete r nonredundant))
+                                      finally return nonredundant)))
+                       (goto-char start)
+                       (delete-char (- end start))
+                       (insert (string-join nonredundant ", "))))))))
+
+          ;; Add a type signature to a top-level binding.
+          (cl-loop
+           for suggestion in sorted
+           do (cl-case (plist-get suggestion :type)
+                (add-signature
+                 (save-excursion
+                   (goto-char (point-min))
+                   (forward-line (1- (plist-get suggestion :line)))
+                   (insert (plist-get suggestion :signature))
+                   (insert "\n")))))
+
+          ;; Remove import lines from the file. May remove more than one
+          ;; line per import.
+          (cl-loop
+           for suggestion in sorted
+           do (cl-case (plist-get suggestion :type)
+                (remove-import
+                 (save-excursion
+                   (goto-char (point-min))
+                   (forward-line (1- (plist-get suggestion :line)))
+                   (delete-region (line-beginning-position)
+                                  (or (when (search-forward-regexp "\n[^ \t]" nil t 1)
+                                        (1- (point)))
+                                      (line-end-position)))))))
+          ;; Add extensions to the top of the file
+          (cl-loop
+           for suggestion in sorted
+           do (cl-case (plist-get suggestion :type)
+                (add-extension
+                 (save-excursion
+                   (goto-char (point-min))
+                   (intero-skip-shebangs)
+                   (insert "{-# LANGUAGE "
+                           (plist-get suggestion :extension)
+                           " #-}\n")))
+                (add-ghc-option
+                 (save-excursion
+                   (goto-char (point-min))
+                   (intero-skip-shebangs)
+                   (insert "{-# OPTIONS_GHC "
+                           (plist-get suggestion :option)
+                           " #-}\n"))))))))))
+
+(defun intero-skip-shebangs ()
+  "Skip #! and -- shebangs used in Haskell scripts."
+  (when (looking-at-p "#!") (forward-line 1))
+  (when (looking-at-p "-- stack ") (forward-line 1)))
+
+(defun intero--warn (message &rest args)
+  "Display a warning message made from (format MESSAGE ARGS...).
+Equivalent to 'warn', but label the warning as coming from intero."
+  (display-warning 'intero (apply 'format message args) :warning))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Intero help buffer
+
+(defun intero-help-buffer ()
+  "Get the help buffer."
+  (with-current-buffer (get-buffer-create "*Intero-Help*")
+    (unless (eq major-mode 'intero-help-mode) (intero-help-mode))
+    (current-buffer)))
+
+(defvar-local intero-help-entries nil
+  "History for help entries.")
+
+(defun intero-help-pagination ()
+  "Insert pagination for the current help buffer."
+  (let ((buffer-read-only nil))
+    (when (> (length intero-help-entries) 1)
+      (insert-text-button
+       "[back]"
+       'buffer (current-buffer)
+       'action (lambda (&rest ignore)
+                 (let ((first (pop intero-help-entries)))
+                   (setcdr (last intero-help-entries) (cons first nil))
+                   (intero-help-refresh)))
+       'keymap (let ((map (make-sparse-keymap)))
+                 (define-key map [mouse-1] 'push-button)
+                 map))
+      (insert " ")
+      (insert-text-button
+       "[forward]"
+       'buffer (current-buffer)
+       'keymap (let ((map (make-sparse-keymap)))
+                 (define-key map [mouse-1] 'push-button)
+                 map)
+       'action (lambda (&rest ignore)
+                 (setq intero-help-entries
+                       (intero-bring-to-front intero-help-entries))
+                 (intero-help-refresh)))
+      (insert " ")
+      (insert-text-button
+       "[forget]"
+       'buffer (current-buffer)
+       'keymap (let ((map (make-sparse-keymap)))
+                 (define-key map [mouse-1] 'push-button)
+                 map)
+       'action (lambda (&rest ignore)
+                 (pop intero-help-entries)
+                 (intero-help-refresh)))
+      (insert "\n\n"))))
+
+(defun intero-help-refresh ()
+  "Refresh the help buffer with the current thing in the history."
+  (interactive)
+  (let ((buffer-read-only nil))
+    (erase-buffer)
+    (if (car intero-help-entries)
+        (progn
+          (intero-help-pagination)
+          (insert (cdr (car intero-help-entries)))
+          (goto-char (point-min)))
+      (insert "No help entries."))))
+
+(defun intero-bring-to-front (xs)
+  "Bring the last element of XS to the front."
+  (cons (car (last xs)) (butlast xs)))
+
+(defun intero-help-push-history (buffer item)
+  "Add (BUFFER . ITEM) to the history of help entries."
+  (push (cons buffer item) intero-help-entries))
+
+(defun intero-help-info (ident)
+  "Get the info of the thing with IDENT at point."
+  (interactive (list (intero-ident-at-point)))
+  (with-current-buffer (car (car intero-help-entries))
+    (intero-info ident)))
+
+(define-derived-mode intero-help-mode help-mode "Intero-Help"
+  "Help mode for intero."
+  (setq buffer-read-only t)
+  (setq intero-help-entries nil))
+
+(define-key intero-help-mode-map (kbd "g") 'intero-help-refresh)
+(define-key intero-help-mode-map (kbd "C-c C-i") 'intero-help-info)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Intero highlight uses mode
+
+(defvar intero-highlight-uses-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "n") 'intero-highlight-uses-mode-next)
+    (define-key map (kbd "TAB") 'intero-highlight-uses-mode-next)
+    (define-key map (kbd "p") 'intero-highlight-uses-mode-prev)
+    (define-key map (kbd "S-TAB") 'intero-highlight-uses-mode-prev)
+    (define-key map (kbd "<backtab>") 'intero-highlight-uses-mode-prev)
+    (define-key map (kbd "RET") 'intero-highlight-uses-mode-stop-here)
+    (define-key map (kbd "r") 'intero-highlight-uses-mode-replace)
+    (define-key map (kbd "q") 'intero-highlight-uses-mode)
+    map)
+  "Keymap for using `intero-highlight-uses-mode'.")
+
+(defvar-local intero-highlight-uses-mode-point nil)
+(defvar-local intero-highlight-uses-buffer-old-mode nil)
+
+;;;###autoload
+(define-minor-mode intero-highlight-uses-mode
+  "Minor mode for highlighting and jumping between uses."
+  :lighter " Uses"
+  :keymap intero-highlight-uses-mode-map
+  (if intero-highlight-uses-mode
+      (progn (setq intero-highlight-uses-buffer-old-mode buffer-read-only)
+             (setq buffer-read-only t)
+             (setq intero-highlight-uses-mode-point (point)))
+    (progn (setq buffer-read-only intero-highlight-uses-buffer-old-mode)
+           (when intero-highlight-uses-mode-point
+             (goto-char intero-highlight-uses-mode-point))))
+  (remove-overlays (point-min) (point-max) 'intero-highlight-uses-mode-highlight t))
+
+(defun intero-highlight-uses-mode-replace ()
+  "Replace all highlighted instances in the buffer with something else."
+  (interactive)
+  (save-excursion
+    (goto-char (point-min))
+    (let ((o (intero-highlight-uses-mode-next)))
+      (when o
+        (let ((replacement
+               (read-from-minibuffer
+                (format "Replace uses %s with: "
+                        (buffer-substring
+                         (overlay-start o)
+                         (overlay-end o))))))
+          (let ((inhibit-read-only t))
+            (while o
+              (goto-char (overlay-start o))
+              (delete-region (overlay-start o)
+                             (overlay-end o))
+              (insert replacement)
+              (setq o (intero-highlight-uses-mode-next))))))))
+  (intero-highlight-uses-mode -1))
+
+(defun intero-highlight-uses-mode-stop-here ()
+  "Stop at this point."
+  (interactive)
+  (setq intero-highlight-uses-mode-point (point))
+  (intero-highlight-uses-mode -1))
+
+(defun intero-highlight-uses-mode-next ()
+  "Jump to next result."
+  (interactive)
+  (let ((os (sort (cl-remove-if (lambda (o)
+                                  (or (<= (overlay-start o) (point))
+                                      (not (overlay-get o 'intero-highlight-uses-mode-highlight))))
+                                (overlays-in (point) (point-max)))
+                  (lambda (a b)
+                    (< (overlay-start a)
+                       (overlay-start b))))))
+    (when os
+      (mapc
+       (lambda (o)
+         (when (overlay-get o 'intero-highlight-uses-mode-highlight)
+           (overlay-put o 'face 'lazy-highlight)))
+       (overlays-in (line-beginning-position) (line-end-position)))
+      (goto-char (overlay-start (car os)))
+      (overlay-put (car os) 'face 'isearch)
+      (car os))))
+
+(defun intero-highlight-uses-mode-prev ()
+  "Jump to previous result."
+  (interactive)
+  (let ((os (sort (cl-remove-if (lambda (o)
+                                  (or (>= (overlay-end o) (point))
+                                      (not (overlay-get o 'intero-highlight-uses-mode-highlight))))
+                                (overlays-in (point-min) (point)))
+                  (lambda (a b)
+                    (> (overlay-start a)
+                       (overlay-start b))))))
+    (when os
+      (mapc
+       (lambda (o)
+         (when (overlay-get o 'intero-highlight-uses-mode-highlight)
+           (overlay-put o 'face 'lazy-highlight)))
+       (overlays-in (line-beginning-position) (line-end-position)))
+      (goto-char (overlay-start (car os)))
+      (overlay-put (car os) 'face 'isearch)
+      (car os))))
+
+(defun intero-highlight-uses-mode-highlight (start end current)
+  "Make a highlight overlay at the span from START to END.
+If CURRENT, highlight the span uniquely."
+  (let ((o (make-overlay start end)))
+    (overlay-put o 'priority 999)
+    (overlay-put o 'face
+                 (if current
+                     'isearch
+                   'lazy-highlight))
+    (overlay-put o 'intero-highlight-uses-mode-highlight t)))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(provide 'intero)
+
+;;; intero.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/intero-20180703.18/intero.elc b/configs/shared/emacs/.emacs.d/elpa/intero-20180703.18/intero.elc
new file mode 100644
index 0000000000..373854ad66
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/intero-20180703.18/intero.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/ivy-20180719.1037/colir.el b/configs/shared/emacs/.emacs.d/elpa/ivy-20180719.1037/colir.el
new file mode 100644
index 0000000000..b872cfc712
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/ivy-20180719.1037/colir.el
@@ -0,0 +1,124 @@
+;;; colir.el --- Color blending library -*- lexical-binding: t -*-
+
+;; Copyright (C) 2015-2018  Free Software Foundation, Inc.
+
+;; Author: Oleh Krehel <ohwoeowho@gmail.com>
+
+;; This file is part of GNU Emacs.
+
+;; This file 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, or (at your option)
+;; any later version.
+
+;; This program 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.
+
+;; For a full copy of the GNU General Public License
+;; see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This package solves the problem of adding a face with a background
+;; to text which may already have a background.  In all conflicting
+;; areas, instead of choosing either the original or the new
+;; background face, their blended sum is used.
+;;
+;; The blend mode functions are taken from URL
+;; `http://en.wikipedia.org/wiki/Blend_modes'.
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'color)
+
+(defcustom colir-compose-method #'colir-compose-alpha
+  "Select a method to compose two color channels."
+  :group 'ivy
+  :type '(radio
+          (function-item colir-compose-alpha)
+          (function-item colir-compose-overlay)
+          (function-item colir-compose-soft-light)))
+
+(defun colir-compose-soft-light (a b)
+  "Compose A and B channels."
+  (if (< b 0.5)
+      (+ (* 2 a b) (* a a (- 1 b b)))
+    (+ (* 2 a (- 1 b)) (* (sqrt a) (- (* 2 b) 1)))))
+
+(defun colir-compose-overlay (a b)
+  "Compose A and B channels."
+  (if (< a 0.5)
+      (* 2 a b)
+    (- 1 (* 2 (- 1 a) (- 1 b)))))
+
+(defun colir-compose-alpha (a b &optional alpha gamma)
+  "Compose A and B channels.
+Optional argument ALPHA is a number between 0.0 and 1.0 which corresponds
+to the influence of A on the result.  Default value is 0.5.
+Optional argument GAMMA is used for gamma correction.  Default value is 2.2."
+  (setq alpha (or alpha 0.5))
+  (setq gamma (or gamma 2.2))
+  (+ (* (expt a gamma) alpha) (* (expt b gamma) (- 1 alpha))))
+
+(defun colir-blend (c1 c2)
+  "Blend the two colors C1 and C2 using `colir-compose-method'.
+C1 and C2 are triples of floats in [0.0 1.0] range."
+  (apply #'color-rgb-to-hex
+         (cl-mapcar
+          (if (eq (frame-parameter nil 'background-mode) 'dark)
+              ;; this method works nicely for dark themes
+              'colir-compose-soft-light
+            colir-compose-method)
+          c1 c2)))
+
+(defun colir-color-parse (color)
+  "Convert string COLOR to triple of floats in [0.0 1.0]."
+  (if (string-match "#\\([[:xdigit:]]\\{2\\}\\)\\([[:xdigit:]]\\{2\\}\\)\\([[:xdigit:]]\\{2\\}\\)" color)
+      (mapcar (lambda (v) (/ (string-to-number v 16) 255.0))
+              (list (match-string 1 color) (match-string 2 color) (match-string 3 color)))
+    ;; does not work properly in terminal (maps color to nearest color
+    ;; from available color palette).
+    (color-name-to-rgb color)))
+
+(defun colir--blend-background (start next prevn face object)
+  (let ((background-prev (face-background prevn)))
+    (progn
+      (put-text-property
+       start next 'face
+       (if background-prev
+           (cons `(background-color
+                   . ,(colir-blend
+                       (colir-color-parse background-prev)
+                       (colir-color-parse (face-background face nil t))))
+                 prevn)
+         (list face prevn))
+       object))))
+
+(defun colir-blend-face-background (start end face &optional object)
+  "Append to the face property of the text from START to END the face FACE.
+When the text already has a face with a non-plain background,
+blend it with the background of FACE.
+Optional argument OBJECT is the string or buffer containing the text.
+See also `font-lock-append-text-property'."
+  (let (next prev prevn)
+    (while (/= start end)
+      (setq next (next-single-property-change start 'face object end))
+      (setq prev (get-text-property start 'face object))
+      (setq prevn (if (listp prev)
+                      (cl-find-if #'atom prev)
+                    prev))
+      (cond
+        ((or (keywordp (car-safe prev)) (consp (car-safe prev)))
+         (put-text-property start next 'face (cons face prev) object))
+        ((facep prevn)
+         (colir--blend-background start next prevn face object))
+        (t
+         (put-text-property start next 'face face object)))
+      (setq start next))))
+
+(provide 'colir)
+
+;;; colir.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/ivy-20180719.1037/colir.elc b/configs/shared/emacs/.emacs.d/elpa/ivy-20180719.1037/colir.elc
new file mode 100644
index 0000000000..1369e83043
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/ivy-20180719.1037/colir.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/ivy-20180719.1037/dir b/configs/shared/emacs/.emacs.d/elpa/ivy-20180719.1037/dir
new file mode 100644
index 0000000000..2347cbc1be
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/ivy-20180719.1037/dir
@@ -0,0 +1,18 @@
+This is the file .../info/dir, which contains the
+topmost node of the Info hierarchy, called (dir)Top.
+The first time you invoke Info you start off looking at this node.
+
+File: dir,	Node: Top	This is the top of the INFO tree
+
+  This (the Directory node) gives a menu of major topics.
+  Typing "q" exits, "?" lists all Info commands, "d" returns here,
+  "h" gives a primer for first-timers,
+  "mEmacs<Return>" visits the Emacs manual, etc.
+
+  In Emacs, you can click mouse button 2 on a menu item or cross reference
+  to select it.
+
+* Menu:
+
+Emacs
+* Ivy: (ivy).                   Using Ivy for completion.
diff --git a/configs/shared/emacs/.emacs.d/elpa/ivy-20180719.1037/ivy-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/ivy-20180719.1037/ivy-autoloads.el
new file mode 100644
index 0000000000..301885147b
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/ivy-20180719.1037/ivy-autoloads.el
@@ -0,0 +1,135 @@
+;;; ivy-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "ivy" "ivy.el" (23377 60989 960273 842000))
+;;; Generated autoloads from ivy.el
+
+(autoload 'ivy-resume "ivy" "\
+Resume the last completion session.
+
+\(fn)" t nil)
+
+(autoload 'ivy-read "ivy" "\
+Read a string in the minibuffer, with completion.
+
+PROMPT is a format string, normally ending in a colon and a
+space; %d anywhere in the string is replaced by the current
+number of matching candidates.  For the literal % character,
+escape it with %%. See also `ivy-count-format'.
+
+COLLECTION is either a list of strings, a function, an alist, or
+a hash table.
+
+PREDICATE is applied to filter out the COLLECTION immediately.
+This argument is for `completing-read' compat.
+
+When REQUIRE-MATCH is non-nil, only members of COLLECTION can be
+selected, i.e. custom text.
+
+If INITIAL-INPUT is not nil, then insert that input in the
+minibuffer initially.
+
+HISTORY is a name of a variable to hold the completion session
+history.
+
+KEYMAP is composed with `ivy-minibuffer-map'.
+
+If PRESELECT is not nil, then select the corresponding candidate
+out of the ones that match the INITIAL-INPUT.
+
+DEF is for compatibility with `completing-read'.
+
+UPDATE-FN is called each time the current candidate(s) is changed.
+
+When SORT is t, use `ivy-sort-functions-alist' for sorting.
+
+ACTION is a lambda function to call after selecting a result.  It
+takes a single string argument.
+
+UNWIND is a lambda function to call before exiting.
+
+RE-BUILDER is a lambda function to call to transform text into a
+regex pattern.
+
+MATCHER is to override matching.
+
+DYNAMIC-COLLECTION is a boolean to specify if the list of
+candidates is updated after each input by calling COLLECTION.
+
+CALLER is a symbol to uniquely identify the caller to `ivy-read'.
+It is used, along with COLLECTION, to determine which
+customizations apply to the current completion session.
+
+\(fn PROMPT COLLECTION &key PREDICATE REQUIRE-MATCH INITIAL-INPUT HISTORY PRESELECT DEF KEYMAP UPDATE-FN SORT ACTION UNWIND RE-BUILDER MATCHER DYNAMIC-COLLECTION CALLER)" nil nil)
+
+(autoload 'ivy-completing-read "ivy" "\
+Read a string in the minibuffer, with completion.
+
+This interface conforms to `completing-read' and can be used for
+`completing-read-function'.
+
+PROMPT is a string that normally ends in a colon and a space.
+COLLECTION is either a list of strings, an alist, an obarray, or a hash table.
+PREDICATE limits completion to a subset of COLLECTION.
+REQUIRE-MATCH is a boolean value.  See `completing-read'.
+INITIAL-INPUT is a string inserted into the minibuffer initially.
+HISTORY is a list of previously selected inputs.
+DEF is the default value.
+INHERIT-INPUT-METHOD is currently ignored.
+
+\(fn PROMPT COLLECTION &optional PREDICATE REQUIRE-MATCH INITIAL-INPUT HISTORY DEF INHERIT-INPUT-METHOD)" nil nil)
+
+(defvar ivy-mode nil "\
+Non-nil if Ivy mode is enabled.
+See the `ivy-mode' command
+for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `ivy-mode'.")
+
+(custom-autoload 'ivy-mode "ivy" nil)
+
+(autoload 'ivy-mode "ivy" "\
+Toggle Ivy mode on or off.
+Turn Ivy mode on if ARG is positive, off otherwise.
+Turning on Ivy mode sets `completing-read-function' to
+`ivy-completing-read'.
+
+Global bindings:
+\\{ivy-mode-map}
+
+Minibuffer bindings:
+\\{ivy-minibuffer-map}
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'ivy-switch-buffer "ivy" "\
+Switch to another buffer.
+
+\(fn)" t nil)
+
+(autoload 'ivy-switch-view "ivy" "\
+Switch to one of the window views stored by `ivy-push-view'.
+
+\(fn)" t nil)
+
+(autoload 'ivy-switch-buffer-other-window "ivy" "\
+Switch to another buffer in another window.
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads nil nil ("colir.el" "ivy-overlay.el" "ivy-pkg.el")
+;;;;;;  (23377 60989 957130 228000))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; ivy-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/ivy-20180719.1037/ivy-help.org b/configs/shared/emacs/.emacs.d/elpa/ivy-20180719.1037/ivy-help.org
new file mode 100644
index 0000000000..1eb71c7cd8
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/ivy-20180719.1037/ivy-help.org
@@ -0,0 +1,138 @@
+* Ivy Generic Help
+
+=ivy= is an Emacs incremental completion framework.
+
+- Narrow the list by typing some pattern,
+- Multiple patterns are allowed by separating with a space,
+- Select with ~C-n~ and ~C-p~, choose with ~RET~.
+
+** Help
+
+- ~C-h m~ :: Pop to this generic help buffer.
+
+** Basic Operations
+*** Key bindings for navigation
+
+- ~C-n~ (=ivy-next-line=) :: next candidate.
+- ~C-p~ (=ivy-previous-line=) :: previous candidate.
+- ~C-v~ (=ivy-scroll-up-command=) :: next page.
+- ~M-v~ (=ivy-scroll-down-command=) :: previous page.
+- ~M-<~ (=ivy-beginning-of-buffer=) :: first candidate.
+- ~M->~ (=ivy-end-of-buffer=) :: last candidate.
+
+*** Key bindings for single selection
+
+When selecting a candidate, an action is called on it. You can think
+of an action as a function that takes the selected candidate as an
+argument and does something with it.
+
+Ivy can offer several actions from which to choose. This can be
+independently composed with whether you want to end completion when
+the action is called. Depending on this, the short term is either
+"calling an action" or "exiting with action".
+
+~C-m~ or ~RET~ (=ivy-done=) - exit with the current action.
+
+~M-o~ (=ivy-dispatching-done=) - select an action and exit with it.
+
+~C-j~ (=ivy-alt-done=) - when the candidate is a directory, enter
+it. Otherwise, exit with the current action.
+
+~TAB~ (=ivy-partial-or-done=) - attempt partial completion, extending
+the current input as much as possible. ~TAB TAB~ is the same as ~C-j~.
+
+~C-M-j~ (=ivy-immediate-done=) - exit with the current action, calling
+it on the /current input/ instead of the current candidate. This is
+useful especially when creating new files or directories - often the
+input will match an existing file, which you don't want to select.
+
+~C-'~ (=ivy-avy=) - select a candidate from the current page with avy
+and exit with the current action.
+
+** Advanced Operations
+*** Key bindings for multiple selection
+
+For repeatedly applying multiple actions or acting on multiple
+candidates, Ivy does not close the minibuffer between commands. It
+keeps the minibuffer open for applying subsequent actions.
+
+Adding an extra meta key to the normal key chord invokes the special
+version of the regular commands that enables applying multiple
+actions.
+
+~C-M-m~ (=ivy-call=) is the non-exiting version of ~C-m~ (=ivy-done=).
+
+~C-M-n~ (=ivy-next-line-and-call=) combines ~C-n~ and ~C-M-m~.
+
+~C-M-p~ (=ivy-previous-line-and-call=) combines ~C-p~ and ~C-M-m~.
+
+~C-M-o~ (=ivy-dispatching-call=) is a non-exiting version of ~M-o~
+(=ivy-dispatching-done=).
+
+*** Key bindings that alter the minibuffer input
+
+~M-n~ (=ivy-next-history-element=) select the next history element or
+symbol/URL at point.
+
+~M-p~ (=ivy-previous-history-element=) select the previous history
+element.
+
+~C-r~ (=ivy-reverse-i-search=) start a recursive completion session to
+select a history element.
+
+~M-i~ (=ivy-insert-current=) insert the current candidate into the
+minibuffer. Useful for copying and renaming files, for example: ~M-i~
+to insert the original file name string, edit it, and then ~C-m~ to
+complete the renaming.
+
+~M-j~ (=ivy-yank-word=) insert the sub-word at point into the
+minibuffer.
+
+~S-SPC~ (=ivy-restrict-to-matches=) deletes the current input, and
+resets the candidates list to the currently restricted matches. This
+is how Ivy provides narrowing in successive tiers.
+
+*** Other key bindings
+
+~M-w~ (=ivy-kill-ring-save=) copies the selected candidates to the
+kill ring; when the region is active, copies the active region.
+
+*** Saving the current completion session to a buffer
+
+~C-c C-o~ (=ivy-occur=) saves the current candidates to a new buffer;
+the list is active in the new buffer.
+
+~RET~ or ~mouse-1~ in the new buffer calls the appropriate action on
+the selected candidate.
+
+Ivy has no limit on the number of active buffers like these.
+
+Ivy takes care of making these buffer names unique. It applies
+descriptive names, for example: =*ivy-occur counsel-describe-variable
+"function$*=.
+
+*** Global key bindings
+
+=ivy-resume= recalls the state of the completion session just before
+its last exit. Useful after an accidental ~C-m~ (=ivy-done=).
+Recommended global binding: ~C-c C-r~.
+
+*** Hydra in the minibuffer
+
+~C-o~ (=hydra-ivy/body=) invokes Hydra menus with key shortcuts.
+
+When in Hydra, ~C-o~ or ~i~ resumes editing.
+
+Hydra reduces key strokes, for example: ~C-n C-n C-n C-n~ is ~C-o
+jjjj~ in Hydra. Besides certain shorter keys, Hydra shows useful info
+such as case folding and the current action.
+
+Additionally, here are the keys that are otherwise not bound:
+
+- ~<~ and ~>~ adjust the height of the minibuffer.
+- ~c~ (=ivy-toggle-calling=) - toggle calling the current action each
+  time a different candidate is selected.
+- ~m~ (=ivy-rotate-preferred-builders=) - rotate regex matcher.
+- ~w~ and ~s~ scroll the actions list.
+
+Minibuffer editing is disabled when Hydra is active.
diff --git a/configs/shared/emacs/.emacs.d/elpa/ivy-20180719.1037/ivy-overlay.el b/configs/shared/emacs/.emacs.d/elpa/ivy-20180719.1037/ivy-overlay.el
new file mode 100644
index 0000000000..70750536f3
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/ivy-20180719.1037/ivy-overlay.el
@@ -0,0 +1,139 @@
+;;; ivy-overlay.el --- Overlay display functions for Ivy  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2016-2018  Free Software Foundation, Inc.
+
+;; Author: Oleh Krehel <ohwoeowho@gmail.com>
+;; Keywords: convenience
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This package allows to setup Ivy's completion at point to actually
+;; show the candidates and the input at point, instead of in the
+;; minibuffer.
+
+;;; Code:
+
+(defface ivy-cursor
+  '((t (:background "black"
+        :foreground "white")))
+  "Cursor face for inline completion."
+  :group 'ivy-faces)
+
+(defvar ivy--old-cursor-type t)
+
+(defvar ivy-overlay-at nil
+  "Overlay variable for `ivy-display-function-overlay'.")
+
+(declare-function ivy--truncate-string "ivy")
+
+(defun ivy-left-pad (str width)
+  "Return STR, but with each line indented by WIDTH spaces.
+Lines are truncated to the window width."
+  (let ((padding (make-string width ?\s)))
+    (mapconcat (lambda (x)
+                 (ivy--truncate-string (concat padding x)
+                                       (1- (+ (window-width)
+                                              (window-hscroll)))))
+               (split-string str "\n")
+               "\n")))
+
+(defun ivy-overlay-cleanup ()
+  "Clean up after `ivy-display-function-overlay'."
+  (when (overlayp ivy-overlay-at)
+    (delete-overlay ivy-overlay-at)
+    (setq ivy-overlay-at nil))
+  (unless cursor-type
+    (setq cursor-type ivy--old-cursor-type))
+  (when (fboundp 'company-abort)
+    (company-abort)))
+
+(defun ivy-overlay-show-after (str)
+  "Display STR in an overlay at point.
+
+First, fill each line of STR with spaces to the current column.
+Then attach the overlay the character before point."
+  (if ivy-overlay-at
+      (progn
+        (move-overlay ivy-overlay-at (1- (point)) (line-end-position))
+        (overlay-put ivy-overlay-at 'invisible nil))
+    (setq ivy-overlay-at (make-overlay (1- (point)) (line-end-position)))
+    (overlay-put ivy-overlay-at 'priority 9999))
+  (overlay-put ivy-overlay-at 'display str)
+  (overlay-put ivy-overlay-at 'after-string ""))
+
+(declare-function org-current-level "org")
+(defvar org-indent-indentation-per-level)
+(defvar ivy-height)
+(defvar ivy-last)
+(defvar ivy-text)
+(defvar ivy-completion-beg)
+(declare-function ivy-add-face-text-property "ivy")
+(declare-function ivy--get-window "ivy")
+(declare-function ivy-state-current "ivy")
+(declare-function ivy-state-window "ivy")
+
+(defun ivy-overlay-impossible-p (str)
+  (or
+   (<= (window-height) (+ ivy-height 3))
+   (= (point) (point-min))
+   (< (- (+ (window-width) (window-hscroll)) (current-column))
+      (apply #'max
+             (mapcar #'length
+                     (split-string str "\n"))))))
+
+(defun ivy-display-function-overlay (str)
+  "Called from the minibuffer, display STR in an overlay in Ivy window.
+Hide the minibuffer contents and cursor."
+  (if (save-selected-window
+        (select-window (ivy-state-window ivy-last))
+        (ivy-overlay-impossible-p str))
+      (let ((buffer-undo-list t))
+        (save-excursion
+          (forward-line 1)
+          (insert str)))
+    (ivy-add-face-text-property (minibuffer-prompt-end) (point-max)
+                                '(:foreground "white"))
+    (let ((cursor-pos (1+ (- (point) (minibuffer-prompt-end))))
+          (ivy-window (ivy--get-window ivy-last)))
+      (setq cursor-type nil)
+      (with-selected-window ivy-window
+        (when cursor-type
+          (setq ivy--old-cursor-type cursor-type))
+        (setq cursor-type nil)
+        (let ((overlay-str
+               (concat
+                (buffer-substring (max 1 (1- (point))) (point))
+                ivy-text
+                (if (eolp)
+                    " "
+                  "")
+                (buffer-substring (point) (line-end-position))
+                (ivy-left-pad
+                 str
+                 (+ (if (and (eq major-mode 'org-mode)
+                             (bound-and-true-p org-indent-mode))
+                        (* org-indent-indentation-per-level (org-current-level))
+                      0)
+                    (save-excursion
+                      (goto-char ivy-completion-beg)
+                      (current-column)))))))
+          (ivy-add-face-text-property cursor-pos (1+ cursor-pos)
+                                      'ivy-cursor overlay-str t)
+          (ivy-overlay-show-after overlay-str))))))
+
+(provide 'ivy-overlay)
+
+;;; ivy-overlay.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/ivy-20180719.1037/ivy-overlay.elc b/configs/shared/emacs/.emacs.d/elpa/ivy-20180719.1037/ivy-overlay.elc
new file mode 100644
index 0000000000..5f85e818f7
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/ivy-20180719.1037/ivy-overlay.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/ivy-20180719.1037/ivy-pkg.el b/configs/shared/emacs/.emacs.d/elpa/ivy-20180719.1037/ivy-pkg.el
new file mode 100644
index 0000000000..4e9b9731b8
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/ivy-20180719.1037/ivy-pkg.el
@@ -0,0 +1,8 @@
+(define-package "ivy" "20180719.1037" "Incremental Vertical completYon"
+  '((emacs "24.1"))
+  :keywords
+  '("matching")
+  :url "https://github.com/abo-abo/swiper")
+;; Local Variables:
+;; no-byte-compile: t
+;; End:
diff --git a/configs/shared/emacs/.emacs.d/elpa/ivy-20180719.1037/ivy.el b/configs/shared/emacs/.emacs.d/elpa/ivy-20180719.1037/ivy.el
new file mode 100644
index 0000000000..177aa35a7c
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/ivy-20180719.1037/ivy.el
@@ -0,0 +1,4283 @@
+;;; ivy.el --- Incremental Vertical completYon -*- lexical-binding: t -*-
+
+;; Copyright (C) 2015-2018  Free Software Foundation, Inc.
+
+;; Author: Oleh Krehel <ohwoeowho@gmail.com>
+;; URL: https://github.com/abo-abo/swiper
+;; Version: 0.10.0
+;; Package-Requires: ((emacs "24.1"))
+;; Keywords: matching
+
+;; This file is part of GNU Emacs.
+
+;; This file 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, or (at your option)
+;; any later version.
+
+;; This program 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.
+
+;; For a full copy of the GNU General Public License
+;; see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This package provides `ivy-read' as an alternative to
+;; `completing-read' and similar functions.
+;;
+;; There's no intricate code to determine the best candidate.
+;; Instead, the user can navigate to it with `ivy-next-line' and
+;; `ivy-previous-line'.
+;;
+;; The matching is done by splitting the input text by spaces and
+;; re-building it into a regex.
+;; So "for example" is transformed into "\\(for\\).*\\(example\\)".
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'ffap)
+(require 'ivy-overlay)
+(require 'colir)
+
+;;* Customization
+(defgroup ivy nil
+  "Incremental vertical completion."
+  :group 'convenience)
+
+(defgroup ivy-faces nil
+  "Font-lock faces for `ivy'."
+  :group 'ivy
+  :group 'faces)
+
+(defface ivy-current-match
+  '((((class color) (background light))
+     :background "#1a4b77" :foreground "white")
+    (((class color) (background dark))
+     :background "#65a7e2" :foreground "black"))
+  "Face used by Ivy for highlighting the current match.")
+
+(defface ivy-minibuffer-match-highlight
+  '((t :inherit highlight))
+  "Face used by Ivy for highlighting the match under the cursor.")
+
+(defface ivy-minibuffer-match-face-1
+  '((((class color) (background light))
+     :background "#d3d3d3")
+    (((class color) (background dark))
+     :background "#555555"))
+  "The background face for `ivy' minibuffer matches.")
+
+(defface ivy-minibuffer-match-face-2
+  '((((class color) (background light))
+     :background "#e99ce8" :weight bold)
+    (((class color) (background dark))
+     :background "#777777" :weight bold))
+  "Face for `ivy' minibuffer matches numbered 1 modulo 3.")
+
+(defface ivy-minibuffer-match-face-3
+  '((((class color) (background light))
+     :background "#bbbbff" :weight bold)
+    (((class color) (background dark))
+     :background "#7777ff" :weight bold))
+  "Face for `ivy' minibuffer matches numbered 2 modulo 3.")
+
+(defface ivy-minibuffer-match-face-4
+  '((((class color) (background light))
+     :background "#ffbbff" :weight bold)
+    (((class color) (background dark))
+     :background "#8a498a" :weight bold))
+  "Face for `ivy' minibuffer matches numbered 3 modulo 3.")
+
+(defface ivy-confirm-face
+  '((t :foreground "ForestGreen" :inherit minibuffer-prompt))
+  "Face used by Ivy for a confirmation prompt.")
+
+(defface ivy-match-required-face
+  '((t :foreground "red" :inherit minibuffer-prompt))
+  "Face used by Ivy for a match required prompt.")
+
+(defface ivy-subdir
+  '((t :inherit dired-directory))
+  "Face used by Ivy for highlighting subdirs in the alternatives.")
+
+(defface ivy-modified-buffer
+  '((t :inherit default))
+  "Face used by Ivy for highlighting modified file visiting buffers.")
+
+(defface ivy-remote
+  '((((class color) (background light))
+     :foreground "#110099")
+    (((class color) (background dark))
+     :foreground "#7B6BFF"))
+  "Face used by Ivy for highlighting remotes in the alternatives.")
+
+(defface ivy-virtual
+  '((t :inherit font-lock-builtin-face))
+  "Face used by Ivy for matching virtual buffer names.")
+
+(defface ivy-action
+  '((t :inherit font-lock-builtin-face))
+  "Face used by Ivy for displaying keys in `ivy-read-action'.")
+
+(defface ivy-highlight-face
+  '((t :inherit highlight))
+  "Face used by Ivy to highlight certain candidates.")
+
+(defface ivy-prompt-match
+  '((t :inherit ivy-current-match))
+  "Face used by Ivy for highlighting the selected prompt line.")
+
+(setcdr (assoc load-file-name custom-current-group-alist) 'ivy)
+
+(defcustom ivy-height 10
+  "Number of lines for the minibuffer window.
+
+See also `ivy-height-alist'."
+  :type 'integer)
+
+(defcustom ivy-count-format "%-4d "
+  "The style to use for displaying the current candidate count for `ivy-read'.
+Set this to \"\" to suppress the count visibility.
+Set this to \"(%d/%d) \" to display both the index and the count."
+  :type '(choice
+          (const :tag "Count disabled" "")
+          (const :tag "Count matches" "%-4d ")
+          (const :tag "Count matches and show current match" "(%d/%d) ")
+          string))
+
+(defcustom ivy-add-newline-after-prompt nil
+  "When non-nil, add a newline after the `ivy-read' prompt."
+  :type 'boolean)
+
+(defcustom ivy-wrap nil
+  "When non-nil, wrap around after the first and the last candidate."
+  :type 'boolean)
+
+(defcustom ivy-display-style (and (fboundp 'add-face-text-property) 'fancy)
+  "The style for formatting the minibuffer.
+
+By default, the matched strings are copied as is.
+
+The fancy display style highlights matching parts of the regexp,
+a behavior similar to `swiper'.
+
+This setting depends on `add-face-text-property' - a C function
+available since Emacs 24.4.  Fancy style will render poorly in
+earlier versions of Emacs."
+  :type '(choice
+          (const :tag "Plain" nil)
+          (const :tag "Fancy" fancy)))
+
+(defcustom ivy-on-del-error-function #'minibuffer-keyboard-quit
+  "Function to call when deletion fails during completion.
+The usual reason for `ivy-backward-delete-char' to fail is when
+there is no text left to delete, i.e., when it is called at the
+beginning of the minibuffer.
+The default setting provides a quick exit from completion."
+  :type '(choice
+          (const :tag "Exit completion" minibuffer-keyboard-quit)
+          (const :tag "Do nothing" ignore)
+          (function :tag "Custom function")))
+
+(defcustom ivy-extra-directories '("../" "./")
+  "Add this to the front of the list when completing file names.
+Only \"./\" and \"../\" apply here.  They appear in reverse order."
+  :type '(repeat :tag "Dirs"
+          (choice
+           (const :tag "Parent Directory" "../")
+           (const :tag "Current Directory" "./"))))
+
+(defcustom ivy-use-virtual-buffers nil
+  "When non-nil, add recent files and bookmarks to `ivy-switch-buffer'."
+  :type 'boolean)
+
+(defcustom ivy-display-function nil
+  "Determine where to display candidates.
+When nil (the default), candidates are shown in the minibuffer.
+Otherwise, this can be set to a function which takes a string
+argument comprising the current matching candidates and displays
+it somewhere.
+
+This user option acts as a global default for Ivy-based
+completion commands.  You can customize the display function on a
+per-command basis via `ivy-display-functions-alist', which see.
+See also URL
+`https://github.com/abo-abo/swiper/wiki/ivy-display-function'."
+  :type '(choice
+          (const :tag "Minibuffer" nil)
+          (const :tag "LV" ivy-display-function-lv)
+          (const :tag "Popup" ivy-display-function-popup)
+          (const :tag "Overlay" ivy-display-function-overlay)))
+
+(defvar ivy-display-functions-props
+  '((ivy-display-function-overlay :cleanup ivy-overlay-cleanup))
+  "Map Ivy display functions to their property lists.
+Examples of properties include associated `:cleanup' functions.")
+
+(defvar ivy-display-functions-alist
+  '((ivy-completion-in-region . ivy-display-function-overlay))
+  "An alist for customizing `ivy-display-function'.")
+
+(defvar ivy-completing-read-dynamic-collection nil
+  "Run `ivy-completing-read' with `:dynamic-collection t`.")
+
+(defcustom ivy-completing-read-handlers-alist
+  '((tmm-menubar . completing-read-default)
+    (tmm-shortcut . completing-read-default)
+    (bbdb-create . ivy-completing-read-with-empty-string-def)
+    (auto-insert . ivy-completing-read-with-empty-string-def)
+    (Info-on-current-buffer . ivy-completing-read-with-empty-string-def)
+    (Info-follow-reference . ivy-completing-read-with-empty-string-def)
+    (Info-menu . ivy-completing-read-with-empty-string-def)
+    (Info-index . ivy-completing-read-with-empty-string-def)
+    (Info-virtual-index . ivy-completing-read-with-empty-string-def)
+    (info-display-manual . ivy-completing-read-with-empty-string-def)
+    (webjump . ivy-completing-read-with-empty-string-def))
+  "An alist of handlers to replace `completing-read' in `ivy-mode'."
+  :type '(alist :key-type function :value-type function))
+
+(defcustom ivy-height-alist nil
+  "An alist to customize `ivy-height'.
+
+It is a list of (CALLER . HEIGHT).  CALLER is a caller of
+`ivy-read' and HEIGHT is the number of lines displayed."
+  :type '(alist :key-type function :value-type integer))
+
+(defvar ivy-completing-read-ignore-handlers-depth -1
+  "Used to avoid infinite recursion.
+
+If `(minibuffer-depth)' equals this, `ivy-completing-read' will
+act as if `ivy-completing-read-handlers-alist' is empty.")
+
+(defvar ivy-highlight-grep-commands nil
+  "List of counsel grep-like commands.")
+
+(defvar ivy--actions-list nil
+  "A list of extra actions per command.")
+
+(defun ivy-set-actions (cmd actions)
+  "Set CMD extra exit points to ACTIONS."
+  (setq ivy--actions-list
+        (plist-put ivy--actions-list cmd actions)))
+
+(defun ivy-add-actions (cmd actions)
+  "Add extra exit points ACTIONS to CMD.
+Existing exit points of CMD are overwritten by those in
+ACTIONS that have the same key."
+  (setq ivy--actions-list
+        (plist-put ivy--actions-list cmd
+                   (cl-delete-duplicates
+                    (append (plist-get ivy--actions-list cmd) actions)
+                    :key #'car :test #'equal))))
+
+(defvar ivy--prompts-list nil)
+
+(defun ivy-set-prompt (caller prompt-fn)
+  "Associate CALLER with PROMPT-FN.
+PROMPT-FN is a function of no arguments that returns a prompt string."
+  (setq ivy--prompts-list
+        (plist-put ivy--prompts-list caller prompt-fn)))
+
+(defvar ivy--display-transformers-list nil
+  "A list of str->str transformers per command.")
+
+(defun ivy-set-display-transformer (cmd transformer)
+  "Set CMD a displayed candidate TRANSFORMER.
+
+It's a lambda that takes a string one of the candidates in the
+collection and returns a string for display, the same candidate
+plus some extra information.
+
+This lambda is called only on the `ivy-height' candidates that
+are about to be displayed, not on the whole collection."
+  (setq ivy--display-transformers-list
+        (plist-put ivy--display-transformers-list cmd transformer)))
+
+(defvar ivy--sources-list nil
+  "A list of extra sources per command.")
+
+(defun ivy-set-sources (cmd sources)
+  "Attach to CMD a list of extra SOURCES.
+
+Each static source is a function that takes no argument and
+returns a list of strings.
+
+The (original-source) determines the position of the original
+dynamic source.
+
+Extra dynamic sources aren't supported yet.
+
+Example:
+
+    (defun small-recentf ()
+      (cl-subseq recentf-list 0 20))
+
+    (ivy-set-sources
+     'counsel-locate
+     '((small-recentf)
+       (original-source)))"
+  (setq ivy--sources-list
+        (plist-put ivy--sources-list cmd sources)))
+
+(defvar ivy-current-prefix-arg nil
+  "Prefix arg to pass to actions.
+This is a global variable that is set by ivy functions for use in
+action functions.")
+
+;;* Keymap
+(require 'delsel)
+(defvar ivy-minibuffer-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "C-m") 'ivy-done)
+    (define-key map [down-mouse-1] 'ignore)
+    (define-key map [mouse-1] 'ivy-mouse-done)
+    (define-key map [mouse-3] 'ivy-mouse-dispatching-done)
+    (define-key map (kbd "C-M-m") 'ivy-call)
+    (define-key map (kbd "C-j") 'ivy-alt-done)
+    (define-key map (kbd "C-M-j") 'ivy-immediate-done)
+    (define-key map (kbd "TAB") 'ivy-partial-or-done)
+    (define-key map [remap next-line] 'ivy-next-line)
+    (define-key map [remap previous-line] 'ivy-previous-line)
+    (define-key map (kbd "C-s") 'ivy-next-line-or-history)
+    (define-key map (kbd "C-r") 'ivy-reverse-i-search)
+    (define-key map (kbd "SPC") 'self-insert-command)
+    (define-key map [remap delete-backward-char] 'ivy-backward-delete-char)
+    (define-key map [remap backward-delete-char-untabify] 'ivy-backward-delete-char)
+    (define-key map [remap backward-kill-word] 'ivy-backward-kill-word)
+    (define-key map [remap delete-char] 'ivy-delete-char)
+    (define-key map [remap forward-char] 'ivy-forward-char)
+    (define-key map (kbd "<right>") 'ivy-forward-char)
+    (define-key map [remap kill-word] 'ivy-kill-word)
+    (define-key map [remap beginning-of-buffer] 'ivy-beginning-of-buffer)
+    (define-key map [remap end-of-buffer] 'ivy-end-of-buffer)
+    (define-key map (kbd "M-n") 'ivy-next-history-element)
+    (define-key map (kbd "M-p") 'ivy-previous-history-element)
+    (define-key map (kbd "C-g") 'minibuffer-keyboard-quit)
+    (define-key map [remap scroll-up-command] 'ivy-scroll-up-command)
+    (define-key map [remap scroll-down-command] 'ivy-scroll-down-command)
+    (define-key map (kbd "<next>") 'ivy-scroll-up-command)
+    (define-key map (kbd "<prior>") 'ivy-scroll-down-command)
+    (define-key map (kbd "C-v") 'ivy-scroll-up-command)
+    (define-key map (kbd "M-v") 'ivy-scroll-down-command)
+    (define-key map (kbd "C-M-n") 'ivy-next-line-and-call)
+    (define-key map (kbd "C-M-p") 'ivy-previous-line-and-call)
+    (define-key map (kbd "M-r") 'ivy-toggle-regexp-quote)
+    (define-key map (kbd "M-j") 'ivy-yank-word)
+    (define-key map (kbd "M-i") 'ivy-insert-current)
+    (define-key map (kbd "C-o") 'hydra-ivy/body)
+    (define-key map (kbd "M-o") 'ivy-dispatching-done)
+    (define-key map (kbd "C-M-o") 'ivy-dispatching-call)
+    (define-key map [remap kill-line] 'ivy-kill-line)
+    (define-key map [remap kill-whole-line] 'ivy-kill-whole-line)
+    (define-key map (kbd "S-SPC") 'ivy-restrict-to-matches)
+    (define-key map [remap kill-ring-save] 'ivy-kill-ring-save)
+    (define-key map (kbd "C-'") 'ivy-avy)
+    (define-key map (kbd "C-M-a") 'ivy-read-action)
+    (define-key map (kbd "C-c C-o") 'ivy-occur)
+    (define-key map (kbd "C-c C-a") 'ivy-toggle-ignore)
+    (define-key map (kbd "C-c C-s") 'ivy-rotate-sort)
+    (define-key map [remap describe-mode] 'ivy-help)
+    map)
+  "Keymap used in the minibuffer.")
+(autoload 'hydra-ivy/body "ivy-hydra" "" t)
+
+(defvar ivy-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map [remap switch-to-buffer]
+      'ivy-switch-buffer)
+    (define-key map [remap switch-to-buffer-other-window]
+      'ivy-switch-buffer-other-window)
+    map)
+  "Keymap for `ivy-mode'.")
+
+;;* Globals
+(cl-defstruct ivy-state
+  prompt collection
+  predicate require-match initial-input
+  history preselect keymap update-fn sort
+  ;; The frame in which `ivy-read' was called
+  frame
+  ;; The window in which `ivy-read' was called
+  window
+  ;; The buffer in which `ivy-read' was called
+  buffer
+  ;; The value of `ivy-text' to be used by `ivy-occur'
+  text
+  action
+  unwind
+  re-builder
+  matcher
+  ;; When this is non-nil, call it for each input change to get new candidates
+  dynamic-collection
+  ;; A lambda that transforms candidates only for display
+  display-transformer-fn
+  directory
+  caller
+  current
+  def)
+
+(defvar ivy-last (make-ivy-state)
+  "The last parameters passed to `ivy-read'.
+
+This should eventually become a stack so that you could use
+`ivy-read' recursively.")
+
+(defvar ivy-recursive-last nil)
+
+(defvar ivy-recursive-restore t
+  "When non-nil, restore the above state when exiting the minibuffer.
+This variable is let-bound to nil by functions that take care of
+the restoring themselves.")
+
+(defsubst ivy-set-action (action)
+  "Set the current `ivy-last' field to ACTION."
+  (setf (ivy-state-action ivy-last) action))
+
+(defun ivy-thing-at-point ()
+  "Return a string that corresponds to the current thing at point."
+  (substring-no-properties
+   (or
+    (thing-at-point 'url)
+    (and (eq (ivy-state-collection ivy-last) 'read-file-name-internal)
+         (let ((inhibit-message t))
+           (ignore-errors
+             (ffap-file-at-point))))
+    (let (s)
+      (cond ((stringp (setq s (thing-at-point 'symbol)))
+             (if (string-match "\\`[`']?\\(.*?\\)'?\\'" s)
+                 (match-string 1 s)
+               s))
+            ((looking-at "(+\\(\\(?:\\sw\\|\\s_\\)+\\)\\_>")
+             (match-string-no-properties 1))
+            (t
+             ""))))))
+
+(defvar ivy-history nil
+  "History list of candidates entered in the minibuffer.
+
+Maximum length of the history list is determined by the value
+of `history-length'.")
+
+(defvar ivy--directory nil
+  "Current directory when completing file names.")
+
+(defvar ivy--length 0
+  "Store the amount of viable candidates.")
+
+(defvar ivy-text ""
+  "Store the user's string as it is typed in.")
+
+(defvar ivy--index 0
+  "Store the index of the current candidate.")
+
+(defvar ivy--window-index 0
+  "Store the index of the current candidate in the minibuffer window.
+
+This means it's between 0 and `ivy-height'.")
+
+(defvar ivy-exit nil
+  "Store `done' if the completion was successfully selected.
+Otherwise, store nil.")
+
+(defvar ivy--all-candidates nil
+  "Store the candidates passed to `ivy-read'.")
+
+(defvar ivy--extra-candidates '((original-source))
+  "Store candidates added by the extra sources.
+
+This is an internal-use alist.  Each key is a function name, or
+original-source (which represents where the current dynamic
+candidates should go).
+
+Each value is an evaluation of the function, in case of static
+sources.  These values will subsequently be filtered on `ivy-text'.
+
+This variable is set by `ivy-read' and used by `ivy--set-candidates'.")
+
+(defcustom ivy-use-ignore-default t
+  "The default policy for user-configured candidate filtering."
+  :type '(choice
+          (const :tag "Ignore ignored always" always)
+          (const :tag "Ignore ignored when others exist" t)
+          (const :tag "Don't ignore" nil)))
+
+(defvar ivy-use-ignore t
+  "Store policy for user-configured candidate filtering.
+This may be changed dynamically by `ivy-toggle-ignore'.
+Use `ivy-use-ignore-default' for a permanent configuration.")
+
+(defvar ivy--default nil
+  "Default initial input.")
+
+(defvar ivy--prompt nil
+  "Store the format-style prompt.
+When non-nil, it should contain at least one %d.")
+
+(defvar ivy--prompt-extra ""
+  "Temporary modifications to the prompt.")
+
+(defvar ivy--old-re nil
+  "Store the old regexp.
+Either a string or a list for `ivy-re-match'.")
+
+(defvar ivy--old-cands nil
+  "Store the candidates matched by `ivy--old-re'.")
+
+(defvar ivy--regex-function 'ivy--regex
+  "Current function for building a regex.")
+
+(defvar ivy--highlight-function 'ivy--highlight-default
+  "Current function for formatting the candidates.")
+
+(defvar ivy--subexps 0
+  "Number of groups in the current `ivy--regex'.")
+
+(defvar ivy--full-length nil
+  "The total amount of candidates when :dynamic-collection is non-nil.")
+
+(defvar ivy--old-text ""
+  "Store old `ivy-text' for dynamic completion.")
+
+(defcustom ivy-case-fold-search-default
+  (if search-upper-case
+      'auto
+    case-fold-search)
+  "The default value for `case-fold-search' in Ivy operations.
+The special value `auto' means case folding is performed so long
+as the entire input string comprises lower-case characters.  This
+corresponds to the default behaviour of most Emacs search
+functionality, e.g. as seen in `isearch'."
+  :link '(info-link "(emacs)Lax Search")
+  :type '(choice
+          (const :tag "Auto" auto)
+          (const :tag "Always" t)
+          (const :tag "Never" nil)))
+
+(defvar ivy-case-fold-search ivy-case-fold-search-default
+  "Store the current overriding `case-fold-search'.")
+
+(defun ivy--case-fold-p (string)
+  "Return nil if STRING should be matched case-sensitively."
+  (if (eq ivy-case-fold-search 'auto)
+      (string= string (downcase string))
+    ivy-case-fold-search))
+
+(defun ivy--case-fold-string= (s1 s2)
+  "Like `string=', but obeys `case-fold-search'."
+  (eq t (compare-strings s1 nil nil s2 nil nil case-fold-search)))
+
+(defvar Info-current-file)
+
+(defun ivy-re-to-str (re)
+  (if (stringp re)
+      re
+    (caar re)))
+
+(eval-and-compile
+  (unless (fboundp 'defvar-local)
+    (defmacro defvar-local (var val &optional docstring)
+      "Define VAR as a buffer-local variable with default value VAL."
+      (declare (debug defvar) (doc-string 3))
+      (list 'progn (list 'defvar var val docstring)
+            (list 'make-variable-buffer-local (list 'quote var)))))
+  (unless (fboundp 'setq-local)
+    (defmacro setq-local (var val)
+      "Set variable VAR to value VAL in current buffer."
+      (list 'set (list 'make-local-variable (list 'quote var)) val))))
+
+(defmacro ivy-quit-and-run (&rest body)
+  "Quit the minibuffer and run BODY afterwards."
+  (declare (indent 0))
+  `(progn
+     (put 'quit 'error-message "")
+     (run-at-time nil nil
+                  (lambda ()
+                    (put 'quit 'error-message "Quit")
+                    (with-demoted-errors "Error: %S"
+                      ,@body)))
+     (abort-recursive-edit)))
+
+(defun ivy-exit-with-action (action)
+  "Quit the minibuffer and call ACTION afterwards."
+  (ivy-set-action
+   `(lambda (x)
+      (funcall ',action x)
+      (ivy-set-action ',(ivy-state-action ivy-last))))
+  (setq ivy-exit 'done)
+  (exit-minibuffer))
+
+(defmacro with-ivy-window (&rest body)
+  "Execute BODY in the window from which `ivy-read' was called."
+  (declare (indent 0)
+           (debug t))
+  `(with-selected-window (ivy--get-window ivy-last)
+     ,@body))
+
+(defun ivy--done (text)
+  "Insert TEXT and exit minibuffer."
+  (insert
+   (setf (ivy-state-current ivy-last)
+         (if (and ivy--directory
+                  (not (eq (ivy-state-history ivy-last) 'grep-files-history)))
+             (expand-file-name text ivy--directory)
+           text)))
+  (setq ivy-exit 'done)
+  (exit-minibuffer))
+
+(defcustom ivy-use-selectable-prompt nil
+  "When non-nil, make the prompt line selectable like a candidate.
+
+The prompt line can be selected by calling `ivy-previous-line' when the first
+regular candidate is selected.  Both actions `ivy-done' and `ivy-alt-done',
+when called on a selected prompt, are forwarded to `ivy-immediate-done', which
+results to the same as calling `ivy-immediate-done' explicitly when a regular
+candidate is selected.
+
+Note that if `ivy-wrap' is set to t, calling `ivy-previous-line' when the
+prompt is selected wraps around to the last candidate, while calling
+`ivy-next-line' on the last candidate wraps around to the first
+candidate, not the prompt."
+  :type 'boolean)
+
+(defun ivy--prompt-selectable-p ()
+  "Return t if the prompt line is selectable."
+  (and ivy-use-selectable-prompt
+       (memq (ivy-state-require-match ivy-last)
+             '(nil confirm confirm-after-completion))))
+
+(defun ivy--prompt-selected-p ()
+  "Return t if the prompt line is selected."
+  (and (ivy--prompt-selectable-p)
+       (= ivy--index -1)))
+
+;;* Commands
+(defun ivy-done ()
+  "Exit the minibuffer with the selected candidate."
+  (interactive)
+  (if (ivy--prompt-selected-p)
+      (ivy-immediate-done)
+    (setq ivy-current-prefix-arg current-prefix-arg)
+    (delete-minibuffer-contents)
+    (cond ((or (> ivy--length 0)
+               ;; the action from `ivy-dispatching-done' may not need a
+               ;; candidate at all
+               (eq this-command 'ivy-dispatching-done))
+           (ivy--done (ivy-state-current ivy-last)))
+          ((memq (ivy-state-collection ivy-last)
+                 '(read-file-name-internal internal-complete-buffer))
+           (if (or (not (eq confirm-nonexistent-file-or-buffer t))
+                   (equal " (confirm)" ivy--prompt-extra))
+               (ivy--done ivy-text)
+             (setq ivy--prompt-extra " (confirm)")
+             (insert ivy-text)
+             (ivy--exhibit)))
+          ((memq (ivy-state-require-match ivy-last)
+                 '(nil confirm confirm-after-completion))
+           (ivy--done ivy-text))
+          (t
+           (setq ivy--prompt-extra " (match required)")
+           (insert ivy-text)
+           (ivy--exhibit)))))
+
+(defvar ivy-mouse-1-tooltip
+  "Exit the minibuffer with the selected candidate."
+  "The doc visible in the tooltip for mouse-1 binding in the minibuffer")
+(defvar ivy-mouse-3-tooltip
+  "Display alternative actions."
+  "The doc visible in the tooltip for mouse-3 binding in the minibuffer")
+
+(defun ivy-mouse-offset (event)
+  "Compute the offset between the candidate at point and the selected one."
+  (if event
+      (let* ((line-number-at-point
+              (max 2
+                   (line-number-at-pos (posn-point (event-start event)))))
+
+             (line-number-candidate ;; convert to 0 based index
+              (- line-number-at-point 2))
+             (offset
+              (- line-number-candidate
+                 ivy--window-index)))
+        offset)
+    nil))
+
+(defun ivy-mouse-done (event)
+  (interactive "@e")
+  (let ((offset (ivy-mouse-offset event)))
+    (when offset
+      (ivy-next-line offset)
+      (ivy--exhibit)
+      (ivy-alt-done))))
+
+(defun ivy-mouse-dispatching-done (event)
+  (interactive "@e")
+  (let ((offset (ivy-mouse-offset event)))
+    (when offset
+      (ivy-next-line offset)
+      (ivy--exhibit)
+      (ivy-dispatching-done))))
+
+(defvar ivy-read-action-format-function 'ivy-read-action-format-default
+  "Function used to transform the actions list into a docstring.")
+
+(defun ivy-read-action-format-default (actions)
+  "Create a docstring from ACTIONS.
+
+ACTIONS is a list.  Each list item is a list of 3 items:
+key (a string), cmd and doc (a string)."
+  (format "%s\n%s\n"
+          (if (eq this-command 'ivy-read-action)
+              "Select action: "
+            (ivy-state-current ivy-last))
+          (mapconcat
+           (lambda (x)
+             (format "%s: %s"
+                     (propertize
+                      (car x)
+                      'face 'ivy-action)
+                     (nth 2 x)))
+           actions
+           "\n")))
+
+(defun ivy-read-action ()
+  "Change the action to one of the available ones.
+
+Return nil for `minibuffer-keyboard-quit' or wrong key during the
+selection, non-nil otherwise."
+  (interactive)
+  (let ((actions (ivy-state-action ivy-last)))
+    (if (not (ivy--actionp actions))
+        t
+      (let* ((hint (funcall ivy-read-action-format-function (cdr actions)))
+             (resize-mini-windows t)
+             (key "")
+             action-idx)
+        (while (and (setq action-idx (cl-position-if
+                                      (lambda (x)
+                                        (string-prefix-p key (car x)))
+                                      (cdr actions)))
+                    (not (string= key (car (nth action-idx (cdr actions))))))
+          (setq key (concat key (string (read-key hint)))))
+        (cond ((member key '("" ""))
+               nil)
+              ((null action-idx)
+               (message "%s is not bound" key)
+               nil)
+              (t
+               (message "")
+               (setcar actions (1+ action-idx))
+               (ivy-set-action actions)))))))
+
+(defun ivy-shrink-after-dispatching ()
+  "Shrink the window after dispatching when action list is too large."
+  (let ((window (selected-window)))
+    (window-resize window (- ivy-height (window-height window)))))
+
+(defun ivy-dispatching-done ()
+  "Select one of the available actions and call `ivy-done'."
+  (interactive)
+  (when (ivy-read-action)
+    (ivy-done))
+  (ivy-shrink-after-dispatching))
+
+(defun ivy-dispatching-call ()
+  "Select one of the available actions and call `ivy-call'."
+  (interactive)
+  (setq ivy-current-prefix-arg current-prefix-arg)
+  (let ((actions (copy-sequence (ivy-state-action ivy-last))))
+    (unwind-protect
+         (when (ivy-read-action)
+           (ivy-call))
+      (ivy-set-action actions)))
+  (ivy-shrink-after-dispatching))
+
+(defun ivy-build-tramp-name (x)
+  "Reconstruct X into a path.
+Is is a cons cell, related to `tramp-get-completion-function'."
+  (let ((user (car x))
+        (domain (cadr x)))
+    (if user
+        (concat user "@" domain)
+      domain)))
+
+(declare-function tramp-get-completion-function "tramp")
+(declare-function Info-find-node "info")
+
+(defun ivy-alt-done (&optional arg)
+  "Exit the minibuffer with the selected candidate.
+When ARG is t, exit with current text, ignoring the candidates."
+  (interactive "P")
+  (setq ivy-current-prefix-arg current-prefix-arg)
+  (cond ((or arg
+             (ivy--prompt-selected-p))
+         (ivy-immediate-done))
+        (ivy--directory
+         (ivy--directory-done))
+        ((eq (ivy-state-collection ivy-last) 'Info-read-node-name-1)
+         (if (member (ivy-state-current ivy-last) '("(./)" "(../)"))
+             (ivy-quit-and-run
+               (ivy-read "Go to file: " 'read-file-name-internal
+                         :action (lambda (x)
+                                   (Info-find-node
+                                    (expand-file-name x ivy--directory)
+                                    "Top"))))
+           (ivy-done)))
+        (t
+         (ivy-done))))
+
+(defvar ivy-auto-select-single-candidate nil
+  "When non-nil, auto-select the candidate if it is the only one.
+When t, it is the same as if the user were prompted and selected the candidate
+by calling the default action.  This variable has no use unless the collection
+contains a single candidate.")
+
+(defun ivy--directory-done ()
+  "Handle exit from the minibuffer when completing file names."
+  (let (dir)
+    (cond
+      ((equal ivy-text "/sudo::")
+       (setq dir (concat ivy-text (expand-file-name ivy--directory)))
+       (ivy--cd dir)
+       (ivy--exhibit))
+      ((and
+        (> ivy--length 0)
+        (not (string= (ivy-state-current ivy-last) "./"))
+        (setq dir (ivy-expand-file-if-directory (ivy-state-current ivy-last))))
+       (ivy--cd dir)
+       (ivy--exhibit))
+      ((unless (string= ivy-text "")
+         (let ((file (expand-file-name
+                      (if (> ivy--length 0) (ivy-state-current ivy-last) ivy-text)
+                      ivy--directory)))
+           (when (ignore-errors (file-exists-p file))
+             (if (file-directory-p file)
+                 (ivy--cd (file-name-as-directory file))
+               (ivy-done))
+             ivy-text))))
+      ((or (and (equal ivy--directory "/")
+                (string-match "\\`[^/]+:.*:.*\\'" ivy-text))
+           (string-match "\\`/[^/]+:.*:.*\\'" ivy-text))
+       (ivy-done))
+      ((or (and (equal ivy--directory "/")
+                (cond ((string-match
+                        "\\`\\([^/]+?\\):\\(?:\\(.*\\)@\\)?\\(.*\\)\\'"
+                        ivy-text))
+                      ((string-match
+                        "\\`\\([^/]+?\\):\\(?:\\(.*\\)@\\)?\\(.*\\)\\'"
+                        (ivy-state-current ivy-last))
+                       (setq ivy-text (ivy-state-current ivy-last)))))
+           (string-match
+            "\\`/\\([^/]+?\\):\\(?:\\(.*\\)@\\)?\\(.*\\)\\'"
+            ivy-text))
+       (let ((method (match-string 1 ivy-text))
+             (user (match-string 2 ivy-text))
+             (rest (match-string 3 ivy-text))
+             res)
+         (require 'tramp)
+         (dolist (x (tramp-get-completion-function method))
+           (setq res (append res (funcall (car x) (cadr x)))))
+         (setq res (delq nil res))
+         (when user
+           (dolist (x res)
+             (setcar x user)))
+         (setq res (cl-delete-duplicates res :test #'equal))
+         (let* ((old-ivy-last ivy-last)
+                (enable-recursive-minibuffers t)
+                (host (let ((ivy-auto-select-single-candidate nil))
+                        (ivy-read "user@host: "
+                                  (mapcar #'ivy-build-tramp-name res)
+                                  :initial-input rest))))
+           (setq ivy-last old-ivy-last)
+           (when host
+             (setq ivy--directory "/")
+             (ivy--cd (concat "/" method ":" host ":"))))))
+      (t
+       (ivy-done)))))
+
+(defun ivy-expand-file-if-directory (file-name)
+  "Expand FILE-NAME as directory.
+When this directory doesn't exist, return nil."
+  (when (stringp file-name)
+    (let ((full-name
+           ;; Ignore host name must not match method "ssh"
+           (ignore-errors
+             (file-name-as-directory
+              (expand-file-name file-name ivy--directory)))))
+      (when (and full-name (file-directory-p full-name))
+        full-name))))
+
+(defcustom ivy-tab-space nil
+  "When non-nil, `ivy-partial-or-done' should insert a space."
+  :type 'boolean)
+
+(defun ivy-partial-or-done ()
+  "Complete the minibuffer text as much as possible.
+If the text hasn't changed as a result, forward to `ivy-alt-done'."
+  (interactive)
+  (if (and (eq (ivy-state-collection ivy-last) #'read-file-name-internal)
+           (or (and (equal ivy--directory "/")
+                    (string-match "\\`[^/]+:.*\\'" ivy-text))
+               (string-match "\\`/" ivy-text)))
+      (let ((default-directory ivy--directory)
+            dir)
+        (minibuffer-complete)
+        (setq ivy-text (ivy--input))
+        (when (setq dir (ivy-expand-file-if-directory ivy-text))
+          (ivy--cd dir)))
+    (or (ivy-partial)
+        (when (or (eq this-command last-command)
+                  (eq ivy--length 1))
+          (ivy-alt-done)))))
+
+(defun ivy-partial ()
+  "Complete the minibuffer text as much as possible."
+  (interactive)
+  (let* ((parts (or (split-string ivy-text " " t) (list "")))
+         (postfix (car (last parts)))
+         (case-fold-search (ivy--case-fold-p ivy-text))
+         (completion-ignore-case case-fold-search)
+         (startp (string-match "^\\^" postfix))
+         (new (try-completion (if startp
+                                  (substring postfix 1)
+                                postfix)
+                              (if (ivy-state-dynamic-collection ivy-last)
+                                  ivy--all-candidates
+                                (mapcar (lambda (str)
+                                          (let ((i (string-match postfix str)))
+                                            (when i
+                                              (substring str i))))
+                                        ivy--old-cands)))))
+    (cond ((eq new t) nil)
+          ((string= new ivy-text) nil)
+          (new
+           (delete-region (minibuffer-prompt-end) (point-max))
+           (setcar (last parts)
+                   (if startp
+                       (concat "^" new)
+                     new))
+           (insert (mapconcat #'identity parts " ")
+                   (if ivy-tab-space " " ""))
+           t))))
+
+(defvar ivy-completion-beg nil
+  "Completion bounds start.")
+
+(defvar ivy-completion-end nil
+  "Completion bounds end.")
+
+(defun ivy-immediate-done ()
+  "Exit the minibuffer with current input instead of current candidate."
+  (interactive)
+  (delete-minibuffer-contents)
+  (insert (setf (ivy-state-current ivy-last)
+                (if (and ivy--directory
+                         (not (eq (ivy-state-history ivy-last)
+                                  'grep-files-history)))
+                    (expand-file-name ivy-text ivy--directory)
+                  ivy-text)))
+  (setq ivy-completion-beg ivy-completion-end)
+  (setq ivy-exit 'done)
+  (exit-minibuffer))
+
+;;;###autoload
+(defun ivy-resume ()
+  "Resume the last completion session."
+  (interactive)
+  (if (null (ivy-state-action ivy-last))
+      (user-error "The last session isn't compatible with `ivy-resume'")
+    (when (eq (ivy-state-caller ivy-last) 'swiper)
+      (switch-to-buffer (ivy-state-buffer ivy-last)))
+    (with-current-buffer (ivy-state-buffer ivy-last)
+      (let ((default-directory (ivy-state-directory ivy-last)))
+        (ivy-read
+         (ivy-state-prompt ivy-last)
+         (ivy-state-collection ivy-last)
+         :predicate (ivy-state-predicate ivy-last)
+         :require-match (ivy-state-require-match ivy-last)
+         :initial-input ivy-text
+         :history (ivy-state-history ivy-last)
+         :preselect (ivy-state-current ivy-last)
+         :keymap (ivy-state-keymap ivy-last)
+         :update-fn (ivy-state-update-fn ivy-last)
+         :sort (ivy-state-sort ivy-last)
+         :action (ivy-state-action ivy-last)
+         :unwind (ivy-state-unwind ivy-last)
+         :re-builder (ivy-state-re-builder ivy-last)
+         :matcher (ivy-state-matcher ivy-last)
+         :dynamic-collection (ivy-state-dynamic-collection ivy-last)
+         :caller (ivy-state-caller ivy-last))))))
+
+(defvar-local ivy-calling nil
+  "When non-nil, call the current action when `ivy--index' changes.")
+
+(defun ivy-set-index (index)
+  "Set `ivy--index' to INDEX."
+  (setq ivy--index index)
+  (when ivy-calling
+    (ivy--exhibit)
+    (ivy-call)))
+
+(defun ivy-beginning-of-buffer ()
+  "Select the first completion candidate."
+  (interactive)
+  (ivy-set-index 0))
+
+(defun ivy-end-of-buffer ()
+  "Select the last completion candidate."
+  (interactive)
+  (ivy-set-index (1- ivy--length)))
+
+(defun ivy-scroll-up-command ()
+  "Scroll the candidates upward by the minibuffer height."
+  (interactive)
+  (ivy-set-index (min (1- (+ ivy--index ivy-height))
+                      (1- ivy--length))))
+
+(defun ivy-scroll-down-command ()
+  "Scroll the candidates downward by the minibuffer height."
+  (interactive)
+  (ivy-set-index (max (1+ (- ivy--index ivy-height))
+                      0)))
+
+(defun ivy-minibuffer-grow ()
+  "Grow the minibuffer window by 1 line."
+  (interactive)
+  (setq-local max-mini-window-height
+              (cl-incf ivy-height)))
+
+(defun ivy-minibuffer-shrink ()
+  "Shrink the minibuffer window by 1 line."
+  (interactive)
+  (unless (<= ivy-height 2)
+    (setq-local max-mini-window-height
+                (cl-decf ivy-height))
+    (window-resize (selected-window) -1)))
+
+(defun ivy-next-line (&optional arg)
+  "Move cursor vertically down ARG candidates."
+  (interactive "p")
+  (setq arg (or arg 1))
+  (let ((index (+ ivy--index arg)))
+    (if (> index (1- ivy--length))
+        (if ivy-wrap
+            (ivy-beginning-of-buffer)
+          (ivy-set-index (1- ivy--length)))
+      (ivy-set-index index))))
+
+(defun ivy-next-line-or-history (&optional arg)
+  "Move cursor vertically down ARG candidates.
+If the input is empty, select the previous history element instead."
+  (interactive "p")
+  (if (string= ivy-text "")
+      (ivy-previous-history-element 1)
+    (ivy-next-line arg)))
+
+(defun ivy-previous-line (&optional arg)
+  "Move cursor vertically up ARG candidates."
+  (interactive "p")
+  (setq arg (or arg 1))
+  (let ((index (- ivy--index arg))
+        (min-index (or (and (ivy--prompt-selectable-p) -1)
+                       0)))
+    (if (< index min-index)
+        (if ivy-wrap
+            (ivy-end-of-buffer)
+          (ivy-set-index min-index))
+      (ivy-set-index index))))
+
+(defun ivy-previous-line-or-history (arg)
+  "Move cursor vertically up ARG candidates.
+If the input is empty, select the previous history element instead."
+  (interactive "p")
+  (when (and (zerop ivy--index) (string= ivy-text ""))
+    (ivy-previous-history-element 1))
+  (ivy-previous-line arg))
+
+(defun ivy-toggle-calling ()
+  "Flip `ivy-calling'."
+  (interactive)
+  (when (setq ivy-calling (not ivy-calling))
+    (ivy-call)))
+
+(defun ivy-toggle-ignore ()
+  "Toggle user-configured candidate filtering."
+  (interactive)
+  (setq ivy-use-ignore
+        (if ivy-use-ignore
+            nil
+          (or ivy-use-ignore-default t)))
+  ;; invalidate cache
+  (setq ivy--old-cands nil))
+
+(defun ivy--get-action (state)
+  "Get the action function from STATE."
+  (let ((action (ivy-state-action state)))
+    (when action
+      (if (functionp action)
+          action
+        (cadr (nth (car action) action))))))
+
+(defun ivy--get-window (state)
+  "Get the window from STATE."
+  (if (ivy-state-p state)
+      (let ((window (ivy-state-window state)))
+        (if (window-live-p window)
+            window
+          (if (= (length (window-list)) 1)
+              (selected-window)
+            (next-window))))
+    (selected-window)))
+
+(defun ivy--actionp (x)
+  "Return non-nil when X is a list of actions."
+  (and (consp x) (not (memq (car x) '(closure lambda)))))
+
+(defcustom ivy-action-wrap nil
+  "When non-nil, `ivy-next-action' and `ivy-prev-action' wrap."
+  :type 'boolean)
+
+(defun ivy-next-action ()
+  "When the current action is a list, scroll it forwards."
+  (interactive)
+  (let ((action (ivy-state-action ivy-last)))
+    (when (ivy--actionp action)
+      (let ((len (1- (length action)))
+            (idx (car action)))
+        (if (>= idx len)
+            (when ivy-action-wrap
+              (setf (car action) 1))
+          (cl-incf (car action)))))))
+
+(defun ivy-prev-action ()
+  "When the current action is a list, scroll it backwards."
+  (interactive)
+  (let ((action (ivy-state-action ivy-last)))
+    (when (ivy--actionp action)
+      (if (<= (car action) 1)
+          (when ivy-action-wrap
+            (setf (car action) (1- (length action))))
+        (cl-decf (car action))))))
+
+(defun ivy-action-name ()
+  "Return the name associated with the current action."
+  (let ((action (ivy-state-action ivy-last)))
+    (if (ivy--actionp action)
+        (format "[%d/%d] %s"
+                (car action)
+                (1- (length action))
+                (nth 2 (nth (car action) action)))
+      "[1/1] default")))
+
+(defvar ivy-inhibit-action nil
+  "When non-nil, `ivy-call' does nothing.
+
+Example use:
+
+    (let* ((ivy-inhibit-action t)
+          (str (counsel-locate \"lispy.el\")))
+     ;; do whatever with str - the corresponding file will not be opened
+     )")
+
+(defun ivy-recursive-restore ()
+  "Restore the above state when exiting the minibuffer.
+See variable `ivy-recursive-restore' for further information."
+  (when (and ivy-recursive-last
+             ivy-recursive-restore
+             (not (eq ivy-last ivy-recursive-last)))
+    (ivy--reset-state (setq ivy-last ivy-recursive-last))))
+
+(defun ivy-call ()
+  "Call the current action without exiting completion."
+  (interactive)
+  (unless
+      (or
+       ;; this is needed for testing in ivy-with which seems to call ivy-call
+       ;; again, and this-command is nil in that case.
+       (null this-command)
+       (memq this-command '(ivy-done
+                            ivy-alt-done
+                            ivy-dispatching-done)))
+    (setq ivy-current-prefix-arg current-prefix-arg))
+  (unless ivy-inhibit-action
+    (let ((action (ivy--get-action ivy-last)))
+      (when action
+        (let* ((collection (ivy-state-collection ivy-last))
+               (x (cond
+                    ;; Alist type.
+                    ((and (consp collection)
+                          (consp (car collection))
+                          ;; Previously, the cdr of the selected
+                          ;; candidate would be returned.  Now, the
+                          ;; whole candidate is returned.
+                          (let (idx)
+                            (if (setq idx (get-text-property
+                                           0 'idx (ivy-state-current ivy-last)))
+                                (nth idx collection)
+                              (assoc (ivy-state-current ivy-last)
+                                     collection)))))
+                    (ivy--directory
+                     (expand-file-name
+                      (ivy-state-current ivy-last)
+                      ivy--directory))
+                    ((equal (ivy-state-current ivy-last) "")
+                     ivy-text)
+                    (t
+                     (ivy-state-current ivy-last)))))
+          (if (eq action 'identity)
+              (funcall action x)
+            (select-window (ivy--get-window ivy-last))
+            (set-buffer (ivy-state-buffer ivy-last))
+            (prog1 (with-current-buffer (ivy-state-buffer ivy-last)
+                     (unwind-protect (funcall action x)
+                       (ivy-recursive-restore)))
+              (unless (or (eq ivy-exit 'done)
+                          (equal (selected-window)
+                                 (active-minibuffer-window))
+                          (null (active-minibuffer-window)))
+                (select-window (active-minibuffer-window))))))))))
+
+(defun ivy-call-and-recenter ()
+  "Call action and recenter window according to the selected candidate."
+  (interactive)
+  (ivy-call)
+  (with-ivy-window
+    (recenter-top-bottom)))
+
+(defun ivy-next-line-and-call (&optional arg)
+  "Move cursor vertically down ARG candidates.
+Call the permanent action if possible."
+  (interactive "p")
+  (ivy-next-line arg)
+  (ivy--exhibit)
+  (ivy-call))
+
+(defun ivy-previous-line-and-call (&optional arg)
+  "Move cursor vertically down ARG candidates.
+Call the permanent action if possible."
+  (interactive "p")
+  (ivy-previous-line arg)
+  (ivy--exhibit)
+  (ivy-call))
+
+(defun ivy-previous-history-element (arg)
+  "Forward to `previous-history-element' with ARG."
+  (interactive "p")
+  (previous-history-element arg)
+  (ivy--cd-maybe)
+  (move-end-of-line 1)
+  (ivy--maybe-scroll-history))
+
+(defun ivy-next-history-element (arg)
+  "Forward to `next-history-element' with ARG."
+  (interactive "p")
+  (if (and (= minibuffer-history-position 0)
+           (equal ivy-text ""))
+      (progn
+        (insert ivy--default)
+        (when (and (with-ivy-window (derived-mode-p 'prog-mode))
+                   (eq (ivy-state-caller ivy-last) 'swiper)
+                   (not (file-exists-p ivy--default))
+                   (not (ffap-url-p ivy--default))
+                   (not (ivy-state-dynamic-collection ivy-last))
+                   (> (point) (minibuffer-prompt-end)))
+          (undo-boundary)
+          (insert "\\_>")
+          (goto-char (minibuffer-prompt-end))
+          (insert "\\_<")
+          (forward-char (+ 2 (length ivy--default)))))
+    (next-history-element arg))
+  (ivy--cd-maybe)
+  (move-end-of-line 1)
+  (ivy--maybe-scroll-history))
+
+(defvar ivy-ffap-url-functions nil
+  "List of functions that check if the point is on a URL.")
+
+(defun ivy--cd-maybe ()
+  "Check if the current input points to a different directory.
+If so, move to that directory, while keeping only the file name."
+  (when ivy--directory
+    (let ((input (ivy--input))
+          url)
+      (if (setq url (or (ffap-url-p input)
+                        (with-ivy-window
+                          (cl-reduce
+                           (lambda (a b)
+                             (or a (funcall b)))
+                           ivy-ffap-url-functions
+                           :initial-value nil))))
+          (ivy-exit-with-action
+           (lambda (_)
+             (funcall ffap-url-fetcher url)))
+        (setq input (expand-file-name input))
+        (let ((file (file-name-nondirectory input))
+              (dir (expand-file-name (file-name-directory input))))
+          (if (string= dir ivy--directory)
+              (progn
+                (delete-minibuffer-contents)
+                (insert file))
+            (ivy--cd dir)
+            (insert file)))))))
+
+(defun ivy--maybe-scroll-history ()
+  "If the selected history element has an index, scroll there."
+  (let ((idx (ignore-errors
+               (get-text-property
+                (minibuffer-prompt-end)
+                'ivy-index))))
+    (when idx
+      (ivy--exhibit)
+      (ivy-set-index idx))))
+
+(defun ivy--cd (dir)
+  "When completing file names, move to directory DIR."
+  (if (null ivy--directory)
+      (error "Unexpected")
+    (setq ivy--old-cands nil)
+    (setq ivy--old-re nil)
+    (ivy-set-index 0)
+    (setq ivy--all-candidates
+          (ivy--sorted-files (setq ivy--directory dir)))
+    (setq ivy-text "")
+    (setf (ivy-state-directory ivy-last) dir)
+    (delete-minibuffer-contents)))
+
+(defun ivy-backward-delete-char ()
+  "Forward to `delete-backward-char'.
+Call `ivy-on-del-error-function' if an error occurs, usually when
+there is no more text to delete at the beginning of the
+minibuffer."
+  (interactive)
+  (if (and ivy--directory (= (minibuffer-prompt-end) (point)))
+      (progn
+        (ivy--cd (file-name-directory
+                  (directory-file-name
+                   (expand-file-name
+                    ivy--directory))))
+        (ivy--exhibit))
+    (setq prefix-arg current-prefix-arg)
+    (condition-case nil
+        (call-interactively #'delete-backward-char)
+      (error
+       (when ivy-on-del-error-function
+         (funcall ivy-on-del-error-function))))))
+
+(defun ivy-delete-char (arg)
+  "Forward to `delete-char' ARG."
+  (interactive "p")
+  (unless (eolp)
+    (delete-char arg)))
+
+(defun ivy-forward-char (arg)
+  "Forward to `forward-char' ARG."
+  (interactive "p")
+  (unless (eolp)
+    (forward-char arg)))
+
+(defun ivy-kill-word (arg)
+  "Forward to `kill-word' ARG."
+  (interactive "p")
+  (unless (eolp)
+    (kill-word arg)))
+
+(defun ivy-kill-line ()
+  "Forward to `kill-line'."
+  (interactive)
+  (if (eolp)
+      (kill-region (minibuffer-prompt-end) (point))
+    (kill-line)))
+
+(defun ivy-kill-whole-line ()
+  "Forward to `kill-whole-line'."
+  (interactive)
+  (kill-region (minibuffer-prompt-end) (line-end-position)))
+
+(defun ivy-backward-kill-word ()
+  "Forward to `backward-kill-word'."
+  (interactive)
+  (if (and ivy--directory (= (minibuffer-prompt-end) (point)))
+      (progn
+        (ivy--cd (file-name-directory
+                  (directory-file-name
+                   (expand-file-name
+                    ivy--directory))))
+        (ivy--exhibit))
+    (ignore-errors
+      (let ((pt (point)))
+        (forward-word -1)
+        (delete-region (point) pt)))))
+
+(defvar ivy--regexp-quote #'regexp-quote
+  "Store the regexp quoting state.")
+
+(defun ivy-toggle-regexp-quote ()
+  "Toggle the regexp quoting."
+  (interactive)
+  (setq ivy--old-re nil)
+  (cl-rotatef ivy--regex-function ivy--regexp-quote))
+
+(defvar avy-all-windows)
+(defvar avy-action)
+(defvar avy-keys)
+(defvar avy-keys-alist)
+(defvar avy-style)
+(defvar avy-styles-alist)
+(declare-function avy--process "ext:avy")
+(declare-function avy--style-fn "ext:avy")
+
+(defcustom ivy-format-function #'ivy-format-function-default
+  "Function to transform the list of candidates into a string.
+This string is inserted into the minibuffer."
+  :type '(choice
+          (const :tag "Default" ivy-format-function-default)
+          (const :tag "Arrow prefix" ivy-format-function-arrow)
+          (const :tag "Full line" ivy-format-function-line)))
+
+(eval-after-load 'avy
+  '(add-to-list 'avy-styles-alist '(ivy-avy . pre)))
+
+(defun ivy-avy ()
+  "Jump to one of the current ivy candidates."
+  (interactive)
+  (unless (require 'avy nil 'noerror)
+    (error "Package avy isn't installed"))
+  (let* ((avy-all-windows nil)
+         (avy-keys (or (cdr (assq 'ivy-avy avy-keys-alist))
+                       avy-keys))
+         (avy-style (or (cdr (assq 'ivy-avy
+                                   avy-styles-alist))
+                        avy-style))
+         (candidate
+          (let ((candidates))
+            (save-excursion
+              (save-restriction
+                (narrow-to-region
+                 (window-start)
+                 (window-end))
+                (goto-char (point-min))
+                (forward-line)
+                (while (< (point) (point-max))
+                  (push
+                   (cons (point)
+                         (selected-window))
+                   candidates)
+                  (forward-line))))
+            (setq avy-action #'identity)
+            (avy--process
+             (nreverse candidates)
+             (avy--style-fn avy-style)))))
+    (when (number-or-marker-p candidate)
+      (ivy--done
+       (substring-no-properties
+        (nth (- (line-number-at-pos candidate) 2) ivy--old-cands))))))
+
+(defun ivy-sort-file-function-default (x y)
+  "Compare two files X and Y.
+Prioritize directories."
+  (if (get-text-property 0 'dirp x)
+      (if (get-text-property 0 'dirp y)
+          (string< (directory-file-name x) (directory-file-name y))
+        t)
+    (if (get-text-property 0 'dirp y)
+        nil
+      (string< x y))))
+
+(declare-function ido-file-extension-lessp "ido")
+
+(defun ivy-sort-file-function-using-ido (x y)
+  "Compare two files X and Y using `ido-file-extensions-order'.
+
+This function is suitable as a replacement for
+`ivy-sort-file-function-default' in `ivy-sort-functions-alist'."
+  (if (and (bound-and-true-p ido-file-extensions-order))
+      (ido-file-extension-lessp x y)
+    (ivy-sort-file-function-default x y)))
+
+(defun ivy-string< (x y)
+  "Like `string<', but operate on CARs when given cons cells."
+  (if (consp x)
+      (string< (car x) (car y))
+    (string< x y)))
+
+(defcustom ivy-sort-functions-alist
+  '((read-file-name-internal . ivy-sort-file-function-default)
+    (internal-complete-buffer . nil)
+    (ivy-completion-in-region . nil)
+    (counsel-git-grep-function . nil)
+    (Man-goto-section . nil)
+    (org-refile . nil)
+    (t . ivy-string<))
+  "An alist of sorting functions for each collection function.
+Interactive functions that call completion fit in here as well.
+
+Nil means no sorting, which is useful to turn off the sorting for
+functions that have candidates in the natural buffer order, like
+`org-refile' or `Man-goto-section'.
+
+A list can be used to associate multiple sorting functions with a
+collection.  The car of the list is the current sort
+function.  This list can be rotated with `ivy-rotate-sort'.
+
+The entry associated with t is used for all fall-through cases.
+
+See also `ivy-sort-max-size'."
+  :type
+  '(alist
+    :key-type (choice
+               (const :tag "Fall-through" t)
+               (symbol :tag "Collection"))
+    :value-type (choice
+                 (const :tag "Plain sort" string-lessp)
+                 (const :tag "File sort" ivy-sort-file-function-default)
+                 (const :tag "No sort" nil)
+                 (function :tag "Custom function")
+                 (repeat (function :tag "Custom function"))))
+  :group 'ivy)
+
+(defun ivy--sort-function (collection)
+  "Retrieve sort function for COLLECTION from `ivy-sort-functions-alist'."
+  (let ((entry (cdr (or (assq collection ivy-sort-functions-alist)
+                        (assq (ivy-state-caller ivy-last) ivy-sort-functions-alist)
+                        (assq t ivy-sort-functions-alist)))))
+    (and (or (functionp entry)
+             (functionp (setq entry (car-safe entry))))
+         entry)))
+
+(defun ivy-rotate-sort ()
+  "Rotate through sorting functions available for current collection.
+This only has an effect if multiple sorting functions are
+specified for the current collection in
+`ivy-sort-functions-alist'."
+  (interactive)
+  (let ((cell (or (assq (ivy-state-collection ivy-last) ivy-sort-functions-alist)
+                  (assq (ivy-state-caller ivy-last) ivy-sort-functions-alist))))
+    (when (consp (cdr cell))
+      (setcdr cell (nconc (cddr cell) (list (cadr cell))))
+      (ivy--reset-state ivy-last))))
+
+(defvar ivy-index-functions-alist
+  '((swiper . ivy-recompute-index-swiper)
+    (swiper-multi . ivy-recompute-index-swiper)
+    (counsel-git-grep . ivy-recompute-index-swiper)
+    (counsel-grep . ivy-recompute-index-swiper-async)
+    (t . ivy-recompute-index-zero))
+  "An alist of index recomputing functions for each collection function.
+When the input changes, the appropriate function returns an
+integer - the index of the matched candidate that should be
+selected.")
+
+(defvar ivy-re-builders-alist
+  '((t . ivy--regex-plus))
+  "An alist of regex building functions for each collection function.
+
+Each key is (in order of priority):
+1. The actual collection function, e.g. `read-file-name-internal'.
+2. The symbol passed by :caller into `ivy-read'.
+3. `this-command'.
+4. t.
+
+Each value is a function that should take a string and return a
+valid regex or a regex sequence (see below).
+
+Possible choices: `ivy--regex', `regexp-quote',
+`ivy--regex-plus', `ivy--regex-fuzzy', `ivy--regex-ignore-order'.
+
+If a function returns a list, it should format like this:
+'((\"matching-regexp\" . t) (\"non-matching-regexp\") ...).
+
+The matches will be filtered in a sequence, you can mix the
+regexps that should match and that should not match as you
+like.")
+
+(defvar ivy-highlight-functions-alist
+  '((ivy--regex-ignore-order . ivy--highlight-ignore-order)
+    (ivy--regex-fuzzy . ivy--highlight-fuzzy)
+    (ivy--regex-plus . ivy--highlight-default))
+  "An alist of highlighting functions for each regex buidler function.")
+
+(defvar ivy-initial-inputs-alist
+  '((org-refile . "^")
+    (org-agenda-refile . "^")
+    (org-capture-refile . "^")
+    (counsel-M-x . "^")
+    (counsel-describe-function . "^")
+    (counsel-describe-variable . "^")
+    (counsel-org-capture . "^")
+    (Man-completion-table . "^")
+    (woman . "^"))
+  "Command to initial input table.")
+
+(defcustom ivy-sort-max-size 30000
+  "Sorting won't be done for collections larger than this."
+  :type 'integer)
+
+(defalias 'ivy--dirname-p
+    (if (fboundp 'directory-name-p)
+        #'directory-name-p
+      (lambda (name)
+        "Return non-nil if NAME ends with a directory separator."
+        (string-match-p "/\\'" name))))
+
+(defun ivy--sorted-files (dir)
+  "Return the list of files in DIR.
+Directories come first."
+  (let* ((default-directory dir)
+         (predicate (ivy-state-predicate ivy-last))
+         (seq (condition-case nil
+                  (all-completions "" 'read-file-name-internal)
+                (error
+                 (directory-files dir))))
+         sort-fn)
+    (if (equal dir "/")
+        seq
+      (setq seq (delete "./" (delete "../" seq)))
+      (when (eq (setq sort-fn (ivy--sort-function 'read-file-name-internal))
+                #'ivy-sort-file-function-default)
+        (setq seq (mapcar (lambda (x)
+                            (propertize x 'dirp (ivy--dirname-p x)))
+                          seq)))
+      (when sort-fn
+        (setq seq (sort seq sort-fn)))
+      (dolist (dir ivy-extra-directories)
+        (push dir seq))
+      (if predicate
+          (cl-remove-if-not predicate seq)
+        seq))))
+
+(defun ivy-alist-setting (alist &optional key)
+  "Return the value associated with KEY in ALIST, using `assq'.
+KEY defaults to the last caller of `ivy-read'; if no entry is
+found, it falls back to the key t."
+  (cdr (or (let ((caller (or key (ivy-state-caller ivy-last))))
+             (and caller (assq caller alist)))
+           (assq t alist))))
+
+;;** Entry Point
+;;;###autoload
+(cl-defun ivy-read (prompt collection
+                    &key
+                      predicate require-match initial-input
+                      history preselect def keymap update-fn sort
+                      action unwind re-builder matcher
+                      dynamic-collection caller)
+  "Read a string in the minibuffer, with completion.
+
+PROMPT is a format string, normally ending in a colon and a
+space; %d anywhere in the string is replaced by the current
+number of matching candidates.  For the literal % character,
+escape it with %%. See also `ivy-count-format'.
+
+COLLECTION is either a list of strings, a function, an alist, or
+a hash table.
+
+PREDICATE is applied to filter out the COLLECTION immediately.
+This argument is for `completing-read' compat.
+
+When REQUIRE-MATCH is non-nil, only members of COLLECTION can be
+selected, i.e. custom text.
+
+If INITIAL-INPUT is not nil, then insert that input in the
+minibuffer initially.
+
+HISTORY is a name of a variable to hold the completion session
+history.
+
+KEYMAP is composed with `ivy-minibuffer-map'.
+
+If PRESELECT is not nil, then select the corresponding candidate
+out of the ones that match the INITIAL-INPUT.
+
+DEF is for compatibility with `completing-read'.
+
+UPDATE-FN is called each time the current candidate(s) is changed.
+
+When SORT is t, use `ivy-sort-functions-alist' for sorting.
+
+ACTION is a lambda function to call after selecting a result.  It
+takes a single string argument.
+
+UNWIND is a lambda function to call before exiting.
+
+RE-BUILDER is a lambda function to call to transform text into a
+regex pattern.
+
+MATCHER is to override matching.
+
+DYNAMIC-COLLECTION is a boolean to specify if the list of
+candidates is updated after each input by calling COLLECTION.
+
+CALLER is a symbol to uniquely identify the caller to `ivy-read'.
+It is used, along with COLLECTION, to determine which
+customizations apply to the current completion session."
+  (let ((extra-actions (delete-dups
+                        (append (plist-get ivy--actions-list t)
+                                (plist-get ivy--actions-list this-command)
+                                (plist-get ivy--actions-list caller)))))
+    (when extra-actions
+      (setq action
+            (cond ((functionp action)
+                   `(1
+                     ("o" ,action "default")
+                     ,@extra-actions))
+                  ((null action)
+                   `(1
+                     ("o" identity "default")
+                     ,@extra-actions))
+                  (t
+                   (delete-dups (append action extra-actions)))))))
+  (unless caller
+    (setq caller this-command))
+  (let ((extra-sources (plist-get ivy--sources-list caller)))
+    (if extra-sources
+        (progn
+          (setq ivy--extra-candidates nil)
+          (dolist (source extra-sources)
+            (cond ((equal source '(original-source))
+                   (setq ivy--extra-candidates
+                         (cons source ivy--extra-candidates)))
+                  ((null (cdr source))
+                   (setq ivy--extra-candidates
+                         (cons
+                          (list (car source) (funcall (car source)))
+                          ivy--extra-candidates))))))
+      (setq ivy--extra-candidates '((original-source)))))
+  (let ((ivy-recursive-last (and (active-minibuffer-window) ivy-last))
+        (transformer-fn
+         (plist-get ivy--display-transformers-list
+                    (cond (caller)
+                          ((functionp collection)
+                           collection))))
+        (ivy-display-function
+         (unless (window-minibuffer-p)
+           (or ivy-display-function
+               (ivy-alist-setting ivy-display-functions-alist caller))))
+        (height
+         (or (cdr (assq caller ivy-height-alist))
+             ivy-height)))
+    (setq ivy-last
+          (make-ivy-state
+           :prompt prompt
+           :collection collection
+           :predicate predicate
+           :require-match require-match
+           :initial-input initial-input
+           :history history
+           :preselect preselect
+           :keymap keymap
+           :update-fn update-fn
+           :sort sort
+           :action action
+           :frame (selected-frame)
+           :window (selected-window)
+           :buffer (current-buffer)
+           :unwind unwind
+           :re-builder re-builder
+           :matcher matcher
+           :dynamic-collection dynamic-collection
+           :display-transformer-fn transformer-fn
+           :directory default-directory
+           :caller caller
+           :def def))
+    (ivy--reset-state ivy-last)
+    (prog1
+        (unwind-protect
+             (minibuffer-with-setup-hook
+                 #'ivy--minibuffer-setup
+               (let* ((hist (or history 'ivy-history))
+                      (minibuffer-completion-table collection)
+                      (minibuffer-completion-predicate predicate)
+                      (ivy-height height)
+                      (resize-mini-windows
+                       (cond
+                         ((display-graphic-p) nil)
+                         ((null resize-mini-windows) 'grow-only)
+                         (t resize-mini-windows))))
+                 (if (and ivy-auto-select-single-candidate
+                          (= (length ivy--all-candidates) 1))
+                     (progn
+                       (setf (ivy-state-current ivy-last)
+                             (car ivy--all-candidates))
+                       (setq ivy-exit 'done))
+                   (read-from-minibuffer
+                    prompt
+                    (ivy-state-initial-input ivy-last)
+                    (make-composed-keymap keymap ivy-minibuffer-map)
+                    nil
+                    hist))
+                 (when (eq ivy-exit 'done)
+                   (let ((item (if ivy--directory
+                                   (ivy-state-current ivy-last)
+                                 ivy-text)))
+                     (unless (equal item "")
+                       (set hist (cons (propertize item 'ivy-index ivy--index)
+                                       (delete item
+                                               (cdr (symbol-value hist))))))))
+                 (ivy-state-current ivy-last)))
+          ;; Fixes a bug in ESS, #1660
+          (put 'post-command-hook 'permanent-local nil)
+          (remove-hook 'post-command-hook #'ivy--queue-exhibit)
+          (let ((cleanup (ivy--display-function-prop :cleanup)))
+            (when (functionp cleanup)
+              (funcall cleanup)))
+          (when (setq unwind (ivy-state-unwind ivy-last))
+            (funcall unwind))
+          (unless (eq ivy-exit 'done)
+            (ivy-recursive-restore)))
+      (ivy-call)
+      (when (> (length (ivy-state-current ivy-last)) 0)
+        (remove-list-of-text-properties
+         0 1 '(idx) (ivy-state-current ivy-last))))))
+
+(defun ivy--display-function-prop (prop)
+  "Return PROP associated with current `ivy-display-function'."
+  (plist-get (cdr (assq ivy-display-function
+                        ivy-display-functions-props))
+             prop))
+
+(defun ivy--reset-state (state)
+  "Reset the ivy to STATE.
+This is useful for recursive `ivy-read'."
+  (unless (equal (selected-frame) (ivy-state-frame state))
+    (select-window (active-minibuffer-window)))
+  (let* ((prompt (or (ivy-state-prompt state) ""))
+         (collection (ivy-state-collection state))
+         (predicate (ivy-state-predicate state))
+         (history (ivy-state-history state))
+         (preselect (ivy-state-preselect state))
+         (sort (ivy-state-sort state))
+         (re-builder (ivy-state-re-builder state))
+         (dynamic-collection (ivy-state-dynamic-collection state))
+         (require-match (ivy-state-require-match state))
+         (caller (or (ivy-state-caller state) this-command))
+         (initial-input (or (ivy-state-initial-input state)
+                            (cdr (assq caller ivy-initial-inputs-alist))))
+         (def (ivy-state-def state)))
+    (setq ivy--directory nil)
+    (setq ivy-case-fold-search ivy-case-fold-search-default)
+    (setq ivy--regex-function
+          (or re-builder
+              (and (functionp collection)
+                   (cdr (assq collection ivy-re-builders-alist)))
+              (ivy-alist-setting ivy-re-builders-alist)
+              #'ivy--regex))
+    (setq ivy--subexps 0)
+    (setq ivy--regexp-quote #'regexp-quote)
+    (setq ivy--old-text "")
+    (setq ivy--full-length nil)
+    (setq ivy-text "")
+    (setq ivy--index 0)
+    (setq ivy-calling nil)
+    (setq ivy-use-ignore ivy-use-ignore-default)
+    (setq ivy--highlight-function
+          (or (cdr (assq ivy--regex-function ivy-highlight-functions-alist))
+              #'ivy--highlight-default))
+    (let (coll sort-fn)
+      (cond ((eq collection 'Info-read-node-name-1)
+             (if (equal Info-current-file "dir")
+                 (setq coll
+                       (mapcar (lambda (x) (format "(%s)" x))
+                               (cl-delete-duplicates
+                                (all-completions "(" collection predicate)
+                                :test #'equal)))
+               (setq coll (all-completions "" collection predicate))))
+            ((eq collection 'read-file-name-internal)
+             (when (and (equal def initial-input)
+                        (member "./" ivy-extra-directories))
+               (setf (ivy-state-def state) (setq def nil)))
+             (setq ivy--directory default-directory)
+             (when (and initial-input
+                        (not (equal initial-input "")))
+               (cond ((file-directory-p initial-input)
+                      (when (equal (file-name-nondirectory initial-input) "")
+                        (setf (ivy-state-preselect state) (setq preselect nil))
+                        (setf (ivy-state-def state) (setq def nil)))
+                      (setq ivy--directory (file-name-as-directory initial-input))
+                      (setq initial-input nil)
+                      (when preselect
+                        (let ((preselect-directory
+                               (file-name-directory preselect)))
+                          (when (and preselect-directory
+                                     (not (equal
+                                           (expand-file-name
+                                            preselect-directory)
+                                           (expand-file-name ivy--directory))))
+                            (setf (ivy-state-preselect state)
+                                  (setq preselect nil))))))
+                     ((ignore-errors
+                        (file-exists-p (file-name-directory initial-input)))
+                      (setq ivy--directory (file-name-directory initial-input))
+                      (setf (ivy-state-preselect state)
+                            (file-name-nondirectory initial-input)))))
+             (require 'dired)
+             (when preselect
+               (let ((preselect-directory (file-name-directory
+                                           (directory-file-name preselect))))
+                 (unless (or (null preselect-directory)
+                             (string= preselect-directory
+                                      default-directory))
+                   (setq ivy--directory preselect-directory))
+                 (setf
+                  (ivy-state-preselect state)
+                  (setq preselect (file-relative-name preselect
+                                                      preselect-directory)))))
+             (setq coll (ivy--sorted-files ivy--directory))
+             (when initial-input
+               (unless (or require-match
+                           (equal initial-input default-directory)
+                           (equal initial-input ""))
+                 (setq coll (cons initial-input coll)))
+               (unless (and (ivy-state-action ivy-last)
+                            (not (equal (ivy--get-action ivy-last) 'identity)))
+                 (setq initial-input nil))))
+            ((eq collection 'internal-complete-buffer)
+             (setq coll (ivy--buffer-list "" ivy-use-virtual-buffers predicate)))
+            (dynamic-collection
+             (setq coll (funcall collection ivy-text)))
+            ((and (consp collection) (listp (car collection)))
+             (if (and sort (setq sort-fn (ivy--sort-function caller)))
+                 (progn
+                   (setq sort nil)
+                   (setq coll (mapcar #'car
+                                      (sort (copy-sequence collection)
+                                            sort-fn))))
+               (setq collection
+                     (setf (ivy-state-collection ivy-last)
+                           (cl-remove-if-not predicate collection)))
+               (setq coll (all-completions "" collection)))
+             (let ((i 0))
+               (ignore-errors
+                 ;; cm can be read-only
+                 (dolist (cm coll)
+                   (add-text-properties 0 1 `(idx ,i) cm)
+                   (cl-incf i)))))
+            ((or (functionp collection)
+                 (byte-code-function-p collection)
+                 (vectorp collection)
+                 (hash-table-p collection)
+                 (and (listp collection) (symbolp (car collection))))
+             (setq coll (all-completions "" collection predicate)))
+            (t
+             (setq coll
+                   (if predicate
+                       (cl-remove-if-not predicate collection)
+                     collection))))
+      (unless (ivy-state-dynamic-collection ivy-last)
+        (setq coll (delete "" coll)))
+      (when def
+        (cond ((listp def)
+               (setq coll (cl-union def coll :test 'equal)))
+              ((member def coll))
+              (t
+               (push def coll))))
+      (when sort
+        (if (functionp collection)
+            (when (and (not (eq collection 'read-file-name-internal))
+                       (<= (length coll) ivy-sort-max-size)
+                       (setq sort-fn (ivy--sort-function collection)))
+              (setq coll (sort (copy-sequence coll) sort-fn)))
+          (when (and (not (eq history 'org-refile-history))
+                     (<= (length coll) ivy-sort-max-size)
+                     (setq sort-fn (ivy--sort-function caller)))
+            (setq coll (sort (copy-sequence coll) sort-fn)))))
+      (setq coll (ivy--set-candidates coll))
+      (setq ivy--old-re nil)
+      (setq ivy--old-cands nil)
+      (when (integerp preselect)
+        (setq ivy--old-re "")
+        (ivy-set-index preselect))
+      (when initial-input
+        ;; Needed for anchor to work
+        (setq ivy--old-cands coll)
+        (setq ivy--old-cands (ivy--filter initial-input coll)))
+      (setq ivy--all-candidates coll)
+      (unless (integerp preselect)
+        (ivy-set-index (or
+                        (and dynamic-collection
+                             ivy--index)
+                        (and preselect
+                             (ivy--preselect-index
+                              preselect
+                              (if initial-input
+                                  ivy--old-cands
+                                coll)))
+                        0))))
+    (setq ivy-exit nil)
+    (setq ivy--default
+          (if (region-active-p)
+              (buffer-substring
+               (region-beginning)
+               (region-end))
+            (ivy-thing-at-point)))
+    (setq ivy--prompt (ivy-add-prompt-count prompt))
+    (setf (ivy-state-initial-input ivy-last) initial-input)))
+
+(defun ivy-add-prompt-count (prompt)
+  "Add count information to PROMPT."
+  (cond ((string-match "%.*d" prompt)
+         prompt)
+        ((null ivy-count-format)
+         (error
+          "`ivy-count-format' can't be nil.  Set it to \"\" instead"))
+        ((string-match "%d.*%d" ivy-count-format)
+         (let ((w (length (number-to-string
+                           (length ivy--all-candidates))))
+               (s (copy-sequence ivy-count-format)))
+           (string-match "%d" s)
+           (match-end 0)
+           (string-match "%d" s (match-end 0))
+           (setq s (replace-match (format "%%-%dd" w) nil nil s))
+           (string-match "%d" s)
+           (concat (replace-match (format "%%%dd" w) nil nil s)
+                   prompt)))
+        ((string-match "%.*d" ivy-count-format)
+         (concat ivy-count-format prompt))
+        (ivy--directory
+         prompt)
+        (t
+         prompt)))
+
+;;;###autoload
+(defun ivy-completing-read (prompt collection
+                            &optional predicate require-match initial-input
+                              history def inherit-input-method)
+  "Read a string in the minibuffer, with completion.
+
+This interface conforms to `completing-read' and can be used for
+`completing-read-function'.
+
+PROMPT is a string that normally ends in a colon and a space.
+COLLECTION is either a list of strings, an alist, an obarray, or a hash table.
+PREDICATE limits completion to a subset of COLLECTION.
+REQUIRE-MATCH is a boolean value.  See `completing-read'.
+INITIAL-INPUT is a string inserted into the minibuffer initially.
+HISTORY is a list of previously selected inputs.
+DEF is the default value.
+INHERIT-INPUT-METHOD is currently ignored."
+  (let ((handler
+         (when (< ivy-completing-read-ignore-handlers-depth (minibuffer-depth))
+           (assoc this-command ivy-completing-read-handlers-alist))))
+    (if handler
+        (let ((completion-in-region-function #'completion--in-region)
+              (ivy-completing-read-ignore-handlers-depth (1+ (minibuffer-depth))))
+          (funcall (cdr handler)
+                   prompt collection
+                   predicate require-match
+                   initial-input history
+                   def inherit-input-method))
+      ;; See the doc of `completing-read'.
+      (when (consp history)
+        (when (numberp (cdr history))
+          (setq initial-input (nth (1- (cdr history))
+                                   (symbol-value (car history)))))
+        (setq history (car history)))
+      (ivy-read (replace-regexp-in-string "%" "%%" prompt)
+                collection
+                :predicate predicate
+                :require-match (and collection require-match)
+                :initial-input (cond ((consp initial-input)
+                                      (car initial-input))
+                                     ((and (stringp initial-input)
+                                           (not (eq collection 'read-file-name-internal))
+                                           (string-match "\\+" initial-input))
+                                      (replace-regexp-in-string
+                                       "\\+" "\\\\+" initial-input))
+                                     (t
+                                      initial-input))
+                :preselect (if (listp def) (car def) def)
+                :def (if (listp def) (car def) def)
+                :history history
+                :keymap nil
+                :sort t
+                :dynamic-collection ivy-completing-read-dynamic-collection
+                :caller (cond ((called-interactively-p 'any)
+                               this-command)
+                              ((and collection (symbolp collection))
+                               collection))))))
+
+(defun ivy-completing-read-with-empty-string-def
+    (prompt collection
+     &optional predicate require-match initial-input
+       history def inherit-input-method)
+  "Same as `ivy-completing-read' but with different handling of DEF.
+
+Specifically, if DEF is nil, it is treated the same as if DEF was
+the empty string. This mimics the behavior of
+`completing-read-default'. This function can therefore be used in
+place of `ivy-completing-read' for commands that rely on this
+behavior."
+  (ivy-completing-read
+   prompt collection predicate require-match initial-input
+   history (or def "") inherit-input-method))
+
+(defun ivy-completion-in-region-action (str)
+  "Insert STR, erasing the previous one.
+The previous string is between `ivy-completion-beg' and `ivy-completion-end'."
+  (when (consp str)
+    (setq str (cdr str)))
+  (when (stringp str)
+    (let ((fake-cursors (and (fboundp 'mc/all-fake-cursors)
+                             (mc/all-fake-cursors)))
+          (pt (point))
+          (beg ivy-completion-beg)
+          (end ivy-completion-end))
+      (when beg
+        (delete-region beg end))
+      (setq ivy-completion-beg (point))
+      (insert (substring-no-properties str))
+      (setq ivy-completion-end (point))
+      (save-excursion
+        (dolist (cursor fake-cursors)
+          (goto-char (overlay-start cursor))
+          (delete-region (+ (point) (- beg pt))
+                         (+ (point) (- end pt)))
+          (insert (substring-no-properties str))
+          ;; manually move the fake cursor
+          (move-overlay cursor (point) (1+ (point)))
+          (set-marker (overlay-get cursor 'point) (point))
+          (set-marker (overlay-get cursor 'mark) (point)))))))
+
+(defun ivy-completion-common-length (str)
+  "Return the amount of characters that match in  STR.
+
+`completion-all-completions' computes this and returns the result
+via text properties.
+
+The first non-matching part is propertized:
+- either with: (face (completions-first-difference))
+- or: (font-lock-face completions-first-difference)."
+  (let ((char-property-alias-alist '((face font-lock-face)))
+        (i (1- (length str))))
+    (catch 'done
+      (while (>= i 0)
+        (when (equal (get-text-property i 'face str)
+                     '(completions-first-difference))
+          (throw 'done i))
+        (cl-decf i))
+      (throw 'done (length str)))))
+
+(defun ivy-completion-in-region (start end collection &optional predicate)
+  "An Ivy function suitable for `completion-in-region-function'.
+The function completes the text between START and END using COLLECTION.
+PREDICATE (a function called with no arguments) says when to exit.
+See `completion-in-region' for further information."
+  (let* ((enable-recursive-minibuffers t)
+         (str (buffer-substring-no-properties start end))
+         (completion-ignore-case (ivy--case-fold-p str))
+         (comps
+          (completion-all-completions str collection predicate (- end start)))
+         (ivy--prompts-list (if (window-minibuffer-p)
+                                ivy--prompts-list
+                              (list #'ivy-completion-in-region (lambda ())))))
+    (cond ((null comps)
+           (message "No matches"))
+          ((progn
+             (nconc comps nil)
+             (and (null (cdr comps))
+                  (string= str (car comps))))
+           (message "Sole match"))
+          (t
+           (let* ((len (ivy-completion-common-length (car comps)))
+                  (str-len (length str))
+                  (initial (cond ((= len 0)
+                                  "")
+                                 ((> len str-len)
+                                  (setq len str-len)
+                                  str)
+                                 (t
+                                  (substring str (- len))))))
+             (setq ivy--old-re nil)
+             (unless (ivy--filter initial comps)
+               (setq initial nil))
+             (delete-region (- end len) end)
+             (setq ivy-completion-beg (- end len))
+             (setq ivy-completion-end ivy-completion-beg)
+             (if (null (cdr comps))
+                 (progn
+                   (unless (minibuffer-window-active-p (selected-window))
+                     (setf (ivy-state-window ivy-last) (selected-window)))
+                   (ivy-completion-in-region-action
+                    (substring-no-properties
+                     (car comps))))
+               (let* ((w (1+ (floor (log (length comps) 10))))
+                      (ivy-count-format (if (string= ivy-count-format "")
+                                            ivy-count-format
+                                          (format "%%-%dd " w)))
+                      (prompt (format "(%s): " str)))
+                 (and
+                  (ivy-read (if (string= ivy-count-format "")
+                                prompt
+                              (replace-regexp-in-string "%" "%%" prompt))
+                            ;; remove 'completions-first-difference face
+                            (mapcar #'substring-no-properties comps)
+                            ;; predicate was already applied by `completion-all-completions'
+                            :predicate nil
+                            :initial-input initial
+                            :sort t
+                            :action #'ivy-completion-in-region-action
+                            :unwind (lambda ()
+                                      (unless (eq ivy-exit 'done)
+                                        (goto-char ivy-completion-beg)
+                                        (insert initial)))
+                            :caller 'ivy-completion-in-region)
+                  t))))))))
+
+(defcustom ivy-do-completion-in-region t
+  "When non-nil `ivy-mode' will set `completion-in-region-function'."
+  :type 'boolean)
+
+;;;###autoload
+(define-minor-mode ivy-mode
+  "Toggle Ivy mode on or off.
+Turn Ivy mode on if ARG is positive, off otherwise.
+Turning on Ivy mode sets `completing-read-function' to
+`ivy-completing-read'.
+
+Global bindings:
+\\{ivy-mode-map}
+
+Minibuffer bindings:
+\\{ivy-minibuffer-map}"
+  :group 'ivy
+  :global t
+  :keymap ivy-mode-map
+  :lighter " ivy"
+  (if ivy-mode
+      (progn
+        (setq completing-read-function 'ivy-completing-read)
+        (when ivy-do-completion-in-region
+          (setq completion-in-region-function 'ivy-completion-in-region)))
+    (setq completing-read-function 'completing-read-default)
+    (setq completion-in-region-function 'completion--in-region)))
+
+(defun ivy--preselect-index (preselect candidates)
+  "Return the index of PRESELECT in CANDIDATES."
+  (cond ((integerp preselect)
+         preselect)
+        ((cl-position preselect candidates :test #'equal))
+        ((stringp preselect)
+         (let ((re preselect))
+           (cl-position-if
+            (lambda (x)
+              (string-match re x))
+            candidates)))))
+
+;;* Implementation
+;;** Regex
+(defun ivy-re-match (re-seq str)
+  "Return non-nil if RE-SEQ is matched by STR.
+
+RE-SEQ is a list of (RE . MATCH-P).
+
+RE is a regular expression.
+
+MATCH-P is t when RE should match STR and nil when RE should not
+match STR.
+
+Each element of RE-SEQ must match for the function to return true.
+
+This concept is used to generalize regular expressions for
+`ivy--regex-plus' and `ivy--regex-ignore-order'."
+  (let ((res t)
+        re)
+    (while (and res (setq re (pop re-seq)))
+      (setq res
+            (if (cdr re)
+                (string-match-p (car re) str)
+              (not (string-match-p (car re) str)))))
+    res))
+
+(defvar ivy--regex-hash
+  (make-hash-table :test #'equal)
+  "Store pre-computed regex.")
+
+(defun ivy--split (str)
+  "Split STR into list of substrings bounded by spaces.
+Single spaces act as splitting points.  Consecutive spaces
+\"quote\" their preceding spaces, i.e., guard them from being
+split.  This allows the literal interpretation of N spaces by
+inputting N+1 spaces.  Any substring not constituting a valid
+regexp is passed to `regexp-quote'."
+  (let ((len (length str))
+        start0
+        (start1 0)
+        res s
+        match-len)
+    (while (and (string-match " +" str start1)
+                (< start1 len))
+      (if (and (> (match-beginning 0) 2)
+               (string= "[^" (substring
+                              str
+                              (- (match-beginning 0) 2)
+                              (match-beginning 0))))
+          (progn
+            (setq start0 start1)
+            (setq start1 (match-end 0)))
+        (setq match-len (- (match-end 0) (match-beginning 0)))
+        (if (= match-len 1)
+            (progn
+              (when start0
+                (setq start1 start0)
+                (setq start0 nil))
+              (push (substring str start1 (match-beginning 0)) res)
+              (setq start1 (match-end 0)))
+          (setq str (replace-match
+                     (make-string (1- match-len) ?\ )
+                     nil nil str))
+          (setq start0 (or start0 start1))
+          (setq start1 (1- (match-end 0))))))
+    (if start0
+        (push (substring str start0) res)
+      (setq s (substring str start1))
+      (unless (= (length s) 0)
+        (push s res)))
+    (mapcar #'ivy--regex-or-literal (nreverse res))))
+
+(defun ivy--regex (str &optional greedy)
+  "Re-build regex pattern from STR in case it has a space.
+When GREEDY is non-nil, join words in a greedy way."
+  (let ((hashed (unless greedy
+                  (gethash str ivy--regex-hash))))
+    (if hashed
+        (prog1 (cdr hashed)
+          (setq ivy--subexps (car hashed)))
+      (when (string-match "\\([^\\]\\|^\\)\\\\$" str)
+        (setq str (substring str 0 -1)))
+      (cdr (puthash str
+                    (let ((subs (ivy--split str)))
+                      (if (= (length subs) 1)
+                          (cons
+                           (setq ivy--subexps 0)
+                           (car subs))
+                        (cons
+                         (setq ivy--subexps (length subs))
+                         (mapconcat
+                          (lambda (x)
+                            (if (string-match "\\`\\\\([^?].*\\\\)\\'" x)
+                                x
+                              (format "\\(%s\\)" x)))
+                          subs
+                          (if greedy
+                              ".*"
+                            ".*?")))))
+                    ivy--regex-hash)))))
+
+(defun ivy--legal-regex-p (str)
+  "Return t if STR is valid regular expression."
+  (condition-case nil
+      (progn
+        (string-match-p str "")
+        t)
+    (invalid-regexp nil)))
+
+(defun ivy--regex-or-literal (str)
+  "If STR isn't a legal regex, escape it."
+  (if (ivy--legal-regex-p str) str (regexp-quote str)))
+
+(defun ivy--split-negation (str)
+  "Split STR into text before and after ! delimiter.
+Do not split if the delimiter is escaped as \\!.
+
+Assumes there is at most one unescaped delimiter and discards
+text after delimiter if it is empty.  Modifies match data."
+  (unless (string= str "")
+    (let ((delim "\\(?:\\`\\|[^\\]\\)\\(!\\)"))
+      (mapcar (lambda (split)
+                ;; Store "\!" as "!".
+                (replace-regexp-in-string "\\\\!" "!" split t t))
+              (if (string-match delim str)
+                  ;; Ignore everything past first unescaped ! rather than
+                  ;; crashing.  We can't warn or error because the minibuffer is
+                  ;; already active.
+                  (let* ((i (match-beginning 1))
+                         (j (and (string-match delim str (1+ i))
+                                 (match-beginning 1)))
+                         (neg (substring str (1+ i) j)))
+                    (cons (substring str 0 i)
+                          (and (not (string= neg ""))
+                               (list neg))))
+                (list str))))))
+
+(defun ivy--split-spaces (str)
+  "Split STR on spaces, unless they're preceded by \\.
+No unescaped spaces are left in the output.  Any substring not
+constituting a valid regexp is passed to `regexp-quote'."
+  (when str
+    (let ((i 0) ; End of last search.
+          (j 0) ; End of last delimiter.
+          parts)
+      (while (string-match "\\(\\\\ \\)\\| +" str i)
+        (setq i (match-end 0))
+        (if (not (match-beginning 1))
+            ;; Unescaped space(s).
+            (let ((delim (match-beginning 0)))
+              (when (< j delim)
+                (push (substring str j delim) parts))
+              (setq j i))
+          ;; Store "\ " as " ".
+          (setq str (replace-match " " t t str 1))
+          (setq i (1- i))))
+      (when (< j (length str))
+        (push (substring str j) parts))
+      (mapcar #'ivy--regex-or-literal (nreverse parts)))))
+
+(defun ivy--regex-ignore-order (str)
+  "Re-build regex from STR by splitting at spaces and using ! for negation.
+
+Examples:
+foo          -> matches \"foo\"
+foo bar      -> matches if both \"foo\" and \"bar\" match (any order)
+foo !bar     -> matches if \"foo\" matches and \"bar\" does not match
+foo !bar baz -> matches if \"foo\" matches and neither \"bar\" nor \"baz\" match
+foo[a-z]     -> matches \"foo[a-z]\"
+
+Escaping examples:
+foo\!bar -> matches \"foo!bar\"
+foo\ bar -> matches \"foo bar\"
+
+Returns a list suitable for `ivy-re-match'."
+  (let* (regex-parts
+         (raw-parts (ivy--split-negation str)))
+    (dolist (part (ivy--split-spaces (car raw-parts)))
+      (push (cons part t) regex-parts))
+    (when (cdr raw-parts)
+      (dolist (part (ivy--split-spaces (cadr raw-parts)))
+        (push (cons part nil) regex-parts)))
+    (if regex-parts (nreverse regex-parts)
+      "")))
+
+(defun ivy--regex-plus (str)
+  "Build a regex sequence from STR.
+Spaces are wild card characters, everything before \"!\" should
+match.  Everything after \"!\" should not match."
+  (let ((parts (ivy--split-negation str)))
+    (cl-case (length parts)
+      (0
+       "")
+      (1
+       (if (string= (substring str 0 1) "!")
+           (list (cons "" t)
+                 (list (ivy--regex (car parts))))
+         (ivy--regex (car parts))))
+      (2
+       (cons
+        (cons (ivy--regex (car parts)) t)
+        (mapcar #'list (split-string (cadr parts) " " t))))
+      (t (error "Unexpected: use only one !")))))
+
+(defun ivy--regex-fuzzy (str)
+  "Build a regex sequence from STR.
+Insert .* between each char."
+  (if (string-match "\\`\\(\\^?\\)\\(.*?\\)\\(\\$?\\)\\'" str)
+      (prog1
+          (concat (match-string 1 str)
+                  (mapconcat
+                   (lambda (x)
+                     (format "\\(%s\\)" (regexp-quote (string x))))
+                   (string-to-list (match-string 2 str))
+                   ".*?")
+                  (match-string 3 str))
+        (setq ivy--subexps (length (match-string 2 str))))
+    str))
+
+(defcustom ivy-fixed-height-minibuffer nil
+  "When non nil, fix the height of the minibuffer during ivy completion.
+This effectively sets the minimum height at this level to `ivy-height' and
+tries to ensure that it does not change depending on the number of candidates."
+  :group 'ivy
+  :type 'boolean)
+
+;;** Rest
+(defcustom ivy-truncate-lines t
+  "Minibuffer setting for `truncate-lines'."
+  :type 'boolean)
+
+(defun ivy--minibuffer-setup ()
+  "Setup ivy completion in the minibuffer."
+  (setq-local mwheel-scroll-up-function 'ivy-next-line)
+  (setq-local mwheel-scroll-down-function 'ivy-previous-line)
+  (setq-local completion-show-inline-help nil)
+  (setq-local minibuffer-default-add-function
+              (lambda ()
+                (list ivy--default)))
+  (setq-local inhibit-field-text-motion nil)
+  (when (display-graphic-p)
+    (setq truncate-lines ivy-truncate-lines))
+  (setq-local max-mini-window-height ivy-height)
+  (if (and ivy-fixed-height-minibuffer
+           (not (eq (ivy-state-caller ivy-last) 'ivy-completion-in-region)))
+      (set-window-text-height (selected-window)
+                              (+ ivy-height
+                                 (if ivy-add-newline-after-prompt
+                                     1
+                                   0)))
+    (when ivy-add-newline-after-prompt
+      (set-window-text-height (selected-window) 2)))
+  (add-hook 'post-command-hook #'ivy--queue-exhibit nil t)
+  ;; show completions with empty input
+  (ivy--exhibit))
+
+(defun ivy--input ()
+  "Return the current minibuffer input."
+  ;; assume one-line minibuffer input
+  (buffer-substring-no-properties
+   (minibuffer-prompt-end)
+   (line-end-position)))
+
+(defun ivy--cleanup ()
+  "Delete the displayed completion candidates."
+  (save-excursion
+    (goto-char (minibuffer-prompt-end))
+    (delete-region (line-end-position) (point-max))))
+
+(defun ivy-cleanup-string (str)
+  "Remove unwanted text properties from STR."
+  (remove-list-of-text-properties 0 (length str) '(field) str)
+  str)
+
+(defvar ivy-set-prompt-text-properties-function
+  'ivy-set-prompt-text-properties-default
+  "Function to set the text properties of the default ivy prompt.
+Called with two arguments, PROMPT and STD-PROPS.
+The returned value should be the updated PROMPT.")
+
+(defun ivy-set-prompt-text-properties-default (prompt std-props)
+  "Set text properties of PROMPT.
+STD-PROPS is a property list containing the default text properties."
+  (ivy--set-match-props prompt "confirm"
+                        `(face ivy-confirm-face ,@std-props))
+  (ivy--set-match-props prompt "match required"
+                        `(face ivy-match-required-face ,@std-props))
+  prompt)
+
+(defun ivy-prompt ()
+  "Return the current prompt."
+  (let ((fn (plist-get ivy--prompts-list (ivy-state-caller ivy-last))))
+    (if fn
+        (condition-case nil
+            (funcall fn)
+          (error
+           (warn "`counsel-prompt-function' should take 0 args")
+           ;; old behavior
+           (funcall fn (ivy-state-prompt ivy-last))))
+      ivy--prompt)))
+
+(defun ivy--insert-prompt ()
+  "Update the prompt according to `ivy--prompt'."
+  (when (setq ivy--prompt (ivy-prompt))
+    (unless (memq this-command '(ivy-done ivy-alt-done ivy-partial-or-done
+                                 counsel-find-symbol))
+      (setq ivy--prompt-extra ""))
+    (let (head tail)
+      (if (string-match "\\(.*?\\)\\(:? ?\\)\\'" ivy--prompt)
+          (progn
+            (setq head (match-string 1 ivy--prompt))
+            (setq tail (match-string 2 ivy--prompt)))
+        (setq head ivy--prompt)
+        (setq tail ""))
+      (let ((inhibit-read-only t)
+            (std-props '(front-sticky t rear-nonsticky t field t read-only t))
+            (n-str
+             (concat
+              (if (and (bound-and-true-p minibuffer-depth-indicate-mode)
+                       (> (minibuffer-depth) 1))
+                  (format "[%d] " (minibuffer-depth))
+                "")
+              (concat
+               (if (string-match "%d.*%d" ivy-count-format)
+                   (format head
+                           (1+ ivy--index)
+                           (or (and (ivy-state-dynamic-collection ivy-last)
+                                    ivy--full-length)
+                               ivy--length))
+                 (format head
+                         (or (and (ivy-state-dynamic-collection ivy-last)
+                                  ivy--full-length)
+                             ivy--length)))
+               ivy--prompt-extra
+               tail)))
+            (d-str (if ivy--directory
+                       (abbreviate-file-name ivy--directory)
+                     "")))
+        (save-excursion
+          (goto-char (point-min))
+          (delete-region (point-min) (minibuffer-prompt-end))
+          (let ((len-n (length n-str))
+                (len-d (length d-str))
+                (ww (window-width)))
+            (setq n-str
+                  (cond ((> (+ len-n len-d) ww)
+                         (concat n-str "\n" d-str "\n"))
+                        ((> (+ len-n len-d (length ivy-text)) ww)
+                         (concat n-str d-str "\n"))
+                        (t
+                         (concat n-str d-str)))))
+          (when ivy-add-newline-after-prompt
+            (setq n-str (concat n-str "\n")))
+          (let ((regex (format "\\([^\n]\\{%d\\}\\)[^\n]" (window-width))))
+            (while (string-match regex n-str)
+              (setq n-str (replace-match
+                           (concat (match-string 1 n-str) "\n")
+                           nil t n-str 1))))
+          (set-text-properties 0 (length n-str)
+                               `(face minibuffer-prompt ,@std-props)
+                               n-str)
+          (setq n-str (funcall ivy-set-prompt-text-properties-function
+                               n-str std-props))
+          (insert n-str))
+        ;; Mark prompt as selected if the user moves there or it is the only
+        ;; option left.  Since the user input stays put, we have to manually
+        ;; remove the face as well.
+        (when (ivy--prompt-selectable-p)
+          (if (or (= ivy--index -1)
+                  (= ivy--length 0))
+              (ivy-add-face-text-property
+               (minibuffer-prompt-end) (line-end-position) 'ivy-prompt-match)
+            (remove-list-of-text-properties
+             (minibuffer-prompt-end) (line-end-position) '(face))))
+        ;; get out of the prompt area
+        (constrain-to-field nil (point-max))))))
+
+(defun ivy--set-match-props (str match props &optional subexp)
+  "Set text properties of STR that match MATCH to PROPS.
+SUBEXP is a number which specifies the regexp group to use.
+If nil, the text properties are applied to the whole match."
+  (when (null subexp)
+    (setq subexp 0))
+  (when (string-match match str)
+    (set-text-properties
+     (match-beginning subexp)
+     (match-end subexp)
+     props
+     str)))
+
+(defvar inhibit-message)
+
+(defun ivy--sort-maybe (collection)
+  "Sort COLLECTION if needed."
+  (let ((sort (ivy-state-sort ivy-last)))
+    (if (and sort
+             (or (functionp sort)
+                 (functionp (setq sort (ivy--sort-function
+                                        (ivy-state-collection ivy-last))))))
+        (sort (copy-sequence collection) sort)
+      collection)))
+
+(defcustom ivy-magic-slash-non-match-action 'ivy-magic-slash-non-match-cd-selected
+  "Action to take when a slash is added to the end of a non existing directory.
+Possible choices are 'ivy-magic-slash-non-match-cd-selected,
+'ivy-magic-slash-non-match-create, or nil"
+  :type '(choice
+          (const :tag "Use currently selected directory"
+           ivy-magic-slash-non-match-cd-selected)
+          (const :tag "Create and use new directory"
+           ivy-magic-slash-non-match-create)
+          (const :tag "Do nothing"
+           nil)))
+
+(defun ivy--create-and-cd (dir)
+  "When completing file names, create directory DIR and move there."
+  (make-directory dir)
+  (ivy--cd dir))
+
+(defun ivy--magic-file-slash ()
+  "Handle slash when completing file names."
+  (when (or (and (eq this-command 'self-insert-command)
+                 (eolp))
+            (eq this-command 'ivy-partial-or-done))
+    (cond ((member ivy-text ivy--all-candidates)
+           (ivy--cd (expand-file-name ivy-text ivy--directory)))
+          ((string-match "//\\'" ivy-text)
+           (if (and default-directory
+                    (string-match "\\`[[:alpha:]]:/" default-directory))
+               (ivy--cd (match-string 0 default-directory))
+             (ivy--cd "/")))
+          ((string-match "\\`/ssh:" ivy-text)
+           (ivy--cd (file-name-directory ivy-text)))
+          ((string-match "[[:alpha:]]:/\\'" ivy-text)
+           (let ((drive-root (match-string 0 ivy-text)))
+             (when (file-exists-p drive-root)
+               (ivy--cd drive-root))))
+          ((and (file-exists-p ivy-text)
+                (not (string= ivy-text "/"))
+                (file-directory-p ivy-text))
+           (ivy--cd (expand-file-name ivy-text)))
+          ((and (or (> ivy--index 0)
+                    (= ivy--length 1)
+                    (not (string= ivy-text "/")))
+                (let ((default-directory ivy--directory))
+                  (and
+                   (not (equal (ivy-state-current ivy-last) ""))
+                   (file-directory-p (ivy-state-current ivy-last))
+                   (file-exists-p (ivy-state-current ivy-last)))))
+           (when (eq ivy-magic-slash-non-match-action 'ivy-magic-slash-non-match-cd-selected)
+             (ivy--cd
+              (expand-file-name (ivy-state-current ivy-last) ivy--directory)))
+           (when (and (eq ivy-magic-slash-non-match-action 'ivy-magic-slash-non-match-create)
+                      (not (string= ivy-text "/")))
+             (ivy--create-and-cd (expand-file-name ivy-text ivy--directory))))
+          (t
+           (when (and
+                  (eq ivy-magic-slash-non-match-action 'ivy-magic-slash-non-match-create)
+                  (not (string= ivy-text "/")))
+             (ivy--create-and-cd (expand-file-name ivy-text ivy--directory)))))))
+
+(defcustom ivy-magic-tilde t
+  "When non-nil, ~ will move home when selecting files.
+Otherwise, ~/ will move home."
+  :type 'boolean)
+
+(defcustom ivy-dynamic-exhibit-delay-ms 0
+  "Delay in ms before dynamic collections are refreshed"
+  :type 'integer)
+
+(defvar ivy--exhibit-timer nil)
+
+(defun ivy--queue-exhibit ()
+  "Insert Ivy completions display, possibly after a timeout for
+dynamic collections.
+Should be run via minibuffer `post-command-hook'."
+  (if (and (> ivy-dynamic-exhibit-delay-ms 0)
+           (ivy-state-dynamic-collection ivy-last))
+      (progn
+        (when ivy--exhibit-timer (cancel-timer ivy--exhibit-timer))
+        (setq ivy--exhibit-timer
+              (run-with-timer
+               (/ ivy-dynamic-exhibit-delay-ms 1000.0)
+               nil
+               'ivy--exhibit)))
+    (ivy--exhibit)))
+
+(defun ivy--exhibit ()
+  "Insert Ivy completions display.
+Should be run via minibuffer `post-command-hook'."
+  (when (memq 'ivy--queue-exhibit post-command-hook)
+    (let ((inhibit-field-text-motion nil))
+      (constrain-to-field nil (point-max)))
+    (setq ivy-text (ivy--input))
+    (if (ivy-state-dynamic-collection ivy-last)
+        ;; while-no-input would cause annoying
+        ;; "Waiting for process to die...done" message interruptions
+        (let ((inhibit-message t))
+          (unless (equal ivy--old-text ivy-text)
+            (while-no-input
+              (setq ivy--all-candidates
+                    (ivy--sort-maybe
+                     (funcall (ivy-state-collection ivy-last) ivy-text)))
+              (setq ivy--old-text ivy-text)))
+          (when (or ivy--all-candidates
+                    (not (get-process " *counsel*")))
+            (ivy--insert-minibuffer
+             (ivy--format ivy--all-candidates))))
+      (cond (ivy--directory
+             (cond ((or (string= "~/" ivy-text)
+                        (and (string= "~" ivy-text)
+                             ivy-magic-tilde))
+                    (ivy--cd (expand-file-name "~/")))
+                   ((string-match "/\\'" ivy-text)
+                    (ivy--magic-file-slash))))
+            ((eq (ivy-state-collection ivy-last) 'internal-complete-buffer)
+             (when (or (and (string-match "\\` " ivy-text)
+                            (not (string-match "\\` " ivy--old-text)))
+                       (and (string-match "\\` " ivy--old-text)
+                            (not (string-match "\\` " ivy-text))))
+               (setq ivy--all-candidates
+                     (if (and (> (length ivy-text) 0)
+                              (eq (aref ivy-text 0)
+                                  ?\ ))
+                         (ivy--buffer-list " ")
+                       (ivy--buffer-list "" ivy-use-virtual-buffers)))
+               (setq ivy--old-re nil))))
+      (ivy--insert-minibuffer
+       (with-current-buffer (ivy-state-buffer ivy-last)
+         (ivy--format
+          (ivy--filter ivy-text ivy--all-candidates))))
+      (setq ivy--old-text ivy-text))))
+
+(defun ivy-display-function-fallback (str)
+  (let ((buffer-undo-list t))
+    (save-excursion
+      (forward-line 1)
+      (insert str))))
+
+(defun ivy--insert-minibuffer (text)
+  "Insert TEXT into minibuffer with appropriate cleanup."
+  (let ((resize-mini-windows nil)
+        (update-fn (ivy-state-update-fn ivy-last))
+        (old-mark (marker-position (mark-marker)))
+        deactivate-mark)
+    (ivy--cleanup)
+    (when update-fn
+      (funcall update-fn))
+    (ivy--insert-prompt)
+    ;; Do nothing if while-no-input was aborted.
+    (when (stringp text)
+      (if ivy-display-function
+          (funcall ivy-display-function text)
+        (ivy-display-function-fallback text)))
+    (when (display-graphic-p)
+      (ivy--resize-minibuffer-to-fit))
+    ;; prevent region growing due to text remove/add
+    (when (region-active-p)
+      (set-mark old-mark))))
+
+(defun ivy--resize-minibuffer-to-fit ()
+  "Resize the minibuffer window size to fit the text in the minibuffer."
+  (unless (frame-root-window-p (minibuffer-window))
+    (with-selected-window (minibuffer-window)
+      (if (fboundp 'window-text-pixel-size)
+          (let ((text-height (cdr (window-text-pixel-size)))
+                (body-height (window-body-height nil t)))
+            (when (> text-height body-height)
+              ;; Note: the size increment needs to be at least
+              ;; frame-char-height, otherwise resizing won't do
+              ;; anything.
+              (let ((delta (max (- text-height body-height)
+                                (frame-char-height))))
+                (window-resize nil delta nil t t))))
+        (let ((text-height (count-screen-lines))
+              (body-height (window-body-height)))
+          (when (> text-height body-height)
+            (window-resize nil (- text-height body-height) nil t)))))))
+
+(defun ivy--add-face (str face)
+  "Propertize STR with FACE.
+`font-lock-append-text-property' is used, since it's better than
+`propertize' or `add-face-text-property' in this case."
+  (let ((len (length str)))
+    (condition-case nil
+        (progn
+          (colir-blend-face-background 0 len face str)
+          (let ((foreground (face-foreground face)))
+            (when foreground
+              (ivy-add-face-text-property
+               0 len (list :foreground foreground) str))))
+      (error
+       (ignore-errors
+         (font-lock-append-text-property 0 len 'face face str)))))
+  str)
+
+(declare-function flx-make-string-cache "ext:flx")
+(declare-function flx-score "ext:flx")
+
+(defvar ivy--flx-cache nil)
+
+(eval-after-load 'flx
+  '(setq ivy--flx-cache (flx-make-string-cache)))
+
+(defun ivy-toggle-case-fold ()
+  "Toggle `case-fold-search' for Ivy operations.
+
+Instead of modifying `case-fold-search' directly, this command
+toggles `ivy-case-fold-search', which can take on more values
+than the former, between nil and either `auto' or t.  See
+`ivy-case-fold-search-default' for the meaning of these values.
+
+In any Ivy completion session, the case folding starts with
+`ivy-case-fold-search-default'."
+  (interactive)
+  (setq ivy-case-fold-search
+        (and (not ivy-case-fold-search)
+             (or ivy-case-fold-search-default 'auto)))
+  ;; Reset cache so that the candidate list updates.
+  (setq ivy--old-re nil))
+
+(defun ivy--re-filter (re candidates &optional mkpred)
+  "Return all RE matching CANDIDATES.
+RE is a list of cons cells, with a regexp car and a boolean cdr.
+When the cdr is t, the car must match.
+Otherwise, the car must not match."
+  (ignore-errors
+    (dolist (re (if (stringp re) (list (cons re t)) re))
+      (let* ((re-str (car re))
+             (pred
+              (if mkpred
+                  (funcall mkpred re-str)
+                (lambda (x) (string-match re-str x)))))
+        (setq candidates
+              (cl-remove nil candidates
+                         (if (cdr re) :if-not :if)
+                         pred))))
+    candidates))
+
+(defun ivy--filter (name candidates)
+  "Return all items that match NAME in CANDIDATES.
+CANDIDATES are assumed to be static."
+  (let ((re (funcall ivy--regex-function name)))
+    (if (and
+         ivy--old-re
+         ivy--old-cands
+         (equal re ivy--old-re))
+        ;; quick caching for "C-n", "C-p" etc.
+        ivy--old-cands
+      (let* ((re-str (if (listp re) (caar re) re))
+             (matcher (ivy-state-matcher ivy-last))
+             (case-fold-search (ivy--case-fold-p name))
+             (cands (cond
+                      (matcher
+                       (funcall matcher re candidates))
+                      ((and ivy--old-re
+                            (stringp re)
+                            (stringp ivy--old-re)
+                            (not (string-match "\\\\" ivy--old-re))
+                            (not (equal ivy--old-re ""))
+                            (memq (cl-search
+                                   (if (string-match "\\\\)\\'" ivy--old-re)
+                                       (substring ivy--old-re 0 -2)
+                                     ivy--old-re)
+                                   re)
+                                  '(0 2)))
+                       (ignore-errors
+                         (cl-remove-if-not
+                          (lambda (x) (string-match re x))
+                          ivy--old-cands)))
+                      (t
+                       (ivy--re-filter re candidates)))))
+        (if (memq (cdr (assoc (ivy-state-caller ivy-last)
+                              ivy-index-functions-alist))
+                  '(ivy-recompute-index-swiper
+                    ivy-recompute-index-swiper-async))
+            (progn
+              (ivy--recompute-index name re-str cands)
+              (setq ivy--old-cands (ivy--sort name cands)))
+          (setq ivy--old-cands (ivy--sort name cands))
+          (ivy--recompute-index name re-str ivy--old-cands))
+        (setq ivy--old-re re)
+        ivy--old-cands))))
+
+(defun ivy--set-candidates (x)
+  "Update `ivy--all-candidates' with X."
+  (let (res)
+    (dolist (source ivy--extra-candidates)
+      (if (equal source '(original-source))
+          (if (null res)
+              (setq res x)
+            (setq res (append x res)))
+        (setq ivy--old-re nil)
+        (setq res (append
+                   (ivy--filter ivy-text (cadr source))
+                   res))))
+    (setq ivy--all-candidates res)))
+
+(defcustom ivy-sort-matches-functions-alist
+  '((t . nil)
+    (ivy-switch-buffer . ivy-sort-function-buffer))
+  "An alist of functions for sorting matching candidates.
+
+Unlike `ivy-sort-functions-alist', which is used to sort the
+whole collection only once, this alist of functions are used to
+sort only matching candidates after each change in input.
+
+The alist KEY is either a collection function or t to match
+previously unmatched collection functions.
+
+The alist VAL is a sorting function with the signature of
+`ivy--prefix-sort'."
+  :type '(alist
+          :key-type (choice
+                     (const :tag "Fall-through" t)
+                     (symbol :tag "Collection"))
+          :value-type
+          (choice
+           (const :tag "Don't sort" nil)
+           (const :tag "Put prefix matches ahead" ivy--prefix-sort)
+           (function :tag "Custom sort function"))))
+
+(defun ivy--sort-files-by-date (_name candidates)
+  "Re-sort CANDIDATES according to file modification date."
+  (let ((default-directory ivy--directory))
+    (sort (copy-sequence candidates) #'file-newer-than-file-p)))
+
+(defvar ivy--flx-featurep (require 'flx nil 'noerror))
+
+(defun ivy--sort (name candidates)
+  "Re-sort candidates by NAME.
+All CANDIDATES are assumed to match NAME."
+  (let ((key (or (ivy-state-caller ivy-last)
+                 (when (functionp (ivy-state-collection ivy-last))
+                   (ivy-state-collection ivy-last))
+                 this-command))
+        fun)
+    (cond ((and ivy--flx-featurep
+                (eq ivy--regex-function 'ivy--regex-fuzzy))
+           (ivy--flx-sort name candidates))
+          ((setq fun (ivy-alist-setting ivy-sort-matches-functions-alist key))
+           (funcall fun name candidates))
+          (t
+           candidates))))
+
+(defun ivy--prefix-sort (name candidates)
+  "Re-sort candidates by NAME.
+All CANDIDATES are assumed to match NAME.
+Prefix matches to NAME are put ahead of the list."
+  (if (or (string-match "^\\^" name) (string= name ""))
+      candidates
+    (let ((re-prefix (concat "^" (funcall ivy--regex-function name)))
+          res-prefix
+          res-noprefix)
+      (dolist (s candidates)
+        (if (string-match re-prefix s)
+            (push s res-prefix)
+          (push s res-noprefix)))
+      (nconc
+       (nreverse res-prefix)
+       (nreverse res-noprefix)))))
+
+(defvar ivy--virtual-buffers nil
+  "Store the virtual buffers alist.")
+
+(defun ivy-generic-regex-to-str (re)
+  "Transform RE to a string.
+
+Functions like `ivy--regex-ignore-order' return a cons list.
+This function extracts a string from the cons list."
+  (if (consp re) (caar re) re))
+
+(defun ivy-sort-function-buffer (name candidates)
+  "Re-sort candidates by NAME.
+CANDIDATES is a list of buffer names each containing NAME.
+Sort open buffers before virtual buffers, and prefix matches
+before substring matches."
+  (if (or (string-match "^\\^" name) (string= name ""))
+      candidates
+    (let* ((base-re (ivy-generic-regex-to-str (funcall ivy--regex-function name)))
+           (re-prefix (concat "^\\*" base-re))
+           res-prefix
+           res-noprefix
+           res-virtual-prefix
+           res-virtual-noprefix)
+      (unless (cl-find-if (lambda (s) (string-match re-prefix s)) candidates)
+        (setq re-prefix (concat "^" base-re)))
+      (dolist (s candidates)
+        (cond
+          ((and (assoc s ivy--virtual-buffers) (string-match re-prefix s))
+           (push s res-virtual-prefix))
+          ((assoc s ivy--virtual-buffers)
+           (push s res-virtual-noprefix))
+          ((string-match re-prefix s)
+           (push s res-prefix))
+          (t
+           (push s res-noprefix))))
+      (nconc
+       (nreverse res-prefix)
+       (nreverse res-noprefix)
+       (nreverse res-virtual-prefix)
+       (nreverse res-virtual-noprefix)))))
+
+(defun ivy--recompute-index (name re-str cands)
+  "Recompute index of selected candidate matching NAME.
+RE-STR is the regexp, CANDS are the current candidates."
+  (let* ((caller (ivy-state-caller ivy-last))
+         (func (or
+                (ivy-alist-setting ivy-index-functions-alist)
+                #'ivy-recompute-index-zero))
+         (case-fold-search (ivy--case-fold-p name))
+         (preselect (ivy-state-preselect ivy-last))
+         (current (ivy-state-current ivy-last)))
+    (unless (eq this-command 'ivy-resume)
+      (ivy-set-index
+       (or
+        (cl-position (if (and (> (length name) 0)
+                              (eq ?^ (aref name 0)))
+                         (substring name 1)
+                       name)
+                     cands
+                     :test #'ivy--case-fold-string=)
+        (and ivy--directory
+             (cl-position (concat re-str "/")
+                          cands
+                          :test #'ivy--case-fold-string=))
+        (and (eq caller 'ivy-switch-buffer)
+             (> (length name) 0)
+             0)
+        (and (not (string= name ""))
+             (not (and ivy--flx-featurep
+                       (eq ivy--regex-function 'ivy--regex-fuzzy)
+                       (< (length cands) 200)))
+             ;; If there was a preselected candidate, don't try to
+             ;; keep it selected even if the regexp still matches it.
+             ;; See issue #1563.  See also `ivy--preselect-index',
+             ;; which this logic roughly mirrors.
+             (not (or
+                   (and (integerp preselect)
+                        (= ivy--index preselect))
+                   (equal current preselect)
+                   (and (stringp preselect)
+                        (stringp current)
+                        (string-match-p preselect current))))
+             ivy--old-cands
+             (cl-position current cands :test #'equal))
+        (funcall func re-str cands))))
+    (when (or (string= name "")
+              (string= name "^"))
+      (ivy-set-index
+       (or (ivy--preselect-index preselect cands)
+           ivy--index)))))
+
+(defun ivy-recompute-index-swiper (_re-str cands)
+  "Recompute index of selected candidate when using `swiper'.
+CANDS are the current candidates."
+  (condition-case nil
+      (let ((tail (nthcdr ivy--index ivy--old-cands))
+            idx)
+        (if (and tail ivy--old-cands (not (equal "^" ivy--old-re)))
+            (progn
+              (while (and tail (null idx))
+                ;; Compare with eq to handle equal duplicates in cands
+                (setq idx (cl-position (pop tail) cands)))
+              (or
+               idx
+               (1- (length cands))))
+          (if ivy--old-cands
+              ivy--index
+            ;; already in ivy-state-buffer
+            (let ((n (line-number-at-pos))
+                  (res 0)
+                  (i 0))
+              (dolist (c cands)
+                (when (eq n (read (get-text-property 0 'swiper-line-number c)))
+                  (setq res i))
+                (cl-incf i))
+              res))))
+    (error 0)))
+
+(defun ivy-recompute-index-swiper-async (_re-str cands)
+  "Recompute index of selected candidate when using `swiper' asynchronously.
+CANDS are the current candidates."
+  (if (null ivy--old-cands)
+      (let ((ln (with-ivy-window
+                  (line-number-at-pos))))
+        (or
+         ;; closest to current line going forwards
+         (cl-position-if (lambda (x)
+                           (>= (string-to-number x) ln))
+                         cands)
+         ;; closest to current line going backwards
+         (1- (length cands))))
+    (let ((tail (nthcdr ivy--index ivy--old-cands))
+          idx)
+      (if (and tail ivy--old-cands (not (equal "^" ivy--old-re)))
+          (progn
+            (while (and tail (null idx))
+              ;; Compare with `equal', since the collection is re-created
+              ;; each time with `split-string'
+              (setq idx (cl-position (pop tail) cands :test #'equal)))
+            (or idx 0))
+        ivy--index))))
+
+(defun ivy-recompute-index-zero (_re-str _cands)
+  "Recompute index of selected candidate.
+This function serves as a fallback when nothing else is available."
+  0)
+
+(defcustom ivy-minibuffer-faces
+  '(ivy-minibuffer-match-face-1
+    ivy-minibuffer-match-face-2
+    ivy-minibuffer-match-face-3
+    ivy-minibuffer-match-face-4)
+  "List of `ivy' faces for minibuffer group matches."
+  :type '(repeat :tag "Faces"
+          (choice
+           (const ivy-minibuffer-match-face-1)
+           (const ivy-minibuffer-match-face-2)
+           (const ivy-minibuffer-match-face-3)
+           (const ivy-minibuffer-match-face-4)
+           (face :tag "Other face"))))
+
+(defvar ivy-flx-limit 200
+  "Used to conditionally turn off flx sorting.
+
+When the amount of matching candidates exceeds this limit, then
+no sorting is done.")
+
+(defun ivy--flx-propertize (x)
+  "X is (cons (flx-score STR ...) STR)."
+  (let ((str (copy-sequence (cdr x)))
+        (i 0)
+        (last-j -2))
+    (dolist (j (cdar x))
+      (unless (eq j (1+ last-j))
+        (cl-incf i))
+      (setq last-j j)
+      (ivy-add-face-text-property
+       j (1+ j)
+       (nth (1+ (mod (+ i 2) (1- (length ivy-minibuffer-faces))))
+            ivy-minibuffer-faces)
+       str))
+    str))
+
+(defun ivy--flx-sort (name cands)
+  "Sort according to closeness to string NAME the string list CANDS."
+  (condition-case nil
+      (let* ((bolp (= (string-to-char name) ?^))
+             ;; An optimized regex for fuzzy matching
+             ;; "abc" → "^[^a]*a[^b]*b[^c]*c"
+             (fuzzy-regex (concat "^"
+                                  (and bolp (regexp-quote (substring name 1 2)))
+                                  (mapconcat
+                                   (lambda (x)
+                                     (setq x (char-to-string x))
+                                     (concat "[^" x "]*" (regexp-quote x)))
+                                   (if bolp (substring name 2) name)
+                                   "")))
+             ;; Strip off the leading "^" for flx matching
+             (flx-name (if bolp (substring name 1) name))
+             cands-left
+             cands-to-sort)
+
+        ;; Filter out non-matching candidates
+        (dolist (cand cands)
+          (when (string-match-p fuzzy-regex cand)
+            (push cand cands-left)))
+
+        ;; pre-sort the candidates by length before partitioning
+        (setq cands-left (cl-sort cands-left #'< :key #'length))
+
+        ;; partition the candidates into sorted and unsorted groups
+        (dotimes (_ (min (length cands-left) ivy-flx-limit))
+          (push (pop cands-left) cands-to-sort))
+
+        (nconc
+         ;; Compute all of the flx scores in one pass and sort
+         (mapcar #'car
+                 (sort (mapcar
+                        (lambda (cand)
+                          (cons cand
+                                (car (flx-score cand flx-name ivy--flx-cache))))
+                        cands-to-sort)
+                       (lambda (c1 c2)
+                         ;; Break ties by length
+                         (if (/= (cdr c1) (cdr c2))
+                             (> (cdr c1)
+                                (cdr c2))
+                           (< (length (car c1))
+                              (length (car c2)))))))
+
+         ;; Add the unsorted candidates
+         cands-left))
+    (error cands)))
+
+(defun ivy--truncate-string (str width)
+  "Truncate STR to WIDTH."
+  (truncate-string-to-width str width nil nil t))
+
+(defun ivy--format-function-generic (selected-fn other-fn cands separator)
+  "Transform candidates into a string for minibuffer.
+SELECTED-FN is called for the selected candidate, OTHER-FN for the others.
+Both functions take one string argument each.  CANDS is a list of candidates
+and SEPARATOR is used to join them."
+  (let ((i -1))
+    (mapconcat
+     (lambda (str)
+       (let ((curr (eq (cl-incf i) ivy--window-index)))
+         (if curr
+             (funcall selected-fn str)
+           (funcall other-fn str))))
+     cands
+     separator)))
+
+(defun ivy-format-function-default (cands)
+  "Transform CANDS into a string for minibuffer."
+  (ivy--format-function-generic
+   (lambda (str)
+     (ivy--add-face str 'ivy-current-match))
+   #'identity
+   cands
+   "\n"))
+
+(defun ivy-format-function-arrow (cands)
+  "Transform CANDS into a string for minibuffer."
+  (ivy--format-function-generic
+   (lambda (str)
+     (concat "> " (ivy--add-face str 'ivy-current-match)))
+   (lambda (str)
+     (concat "  " str))
+   cands
+   "\n"))
+
+(defun ivy-format-function-line (cands)
+  "Transform CANDS into a string for minibuffer."
+  (ivy--format-function-generic
+   (lambda (str)
+     (ivy--add-face (concat str "\n") 'ivy-current-match))
+   (lambda (str)
+     (concat str "\n"))
+   cands
+   ""))
+
+(defalias 'ivy-add-face-text-property
+  (if (fboundp 'add-face-text-property)
+      (lambda (start end face &optional object append)
+        (add-face-text-property start end face append object))
+    (lambda (start end face &optional object append)
+      (funcall (if append
+                   #'font-lock-append-text-property
+                 #'font-lock-prepend-text-property)
+               start end 'face face object)))
+  "Compatibility shim for `add-face-text-property'.
+Fall back on `font-lock-prepend-text-property' in Emacs versions
+prior to 24.4 (`font-lock-append-text-property' when APPEND is
+non-nil).
+Note: The usual last two arguments are flipped for convenience.")
+
+(defun ivy--highlight-ignore-order (str)
+  "Highlight STR, using the ignore-order method."
+  (when (consp ivy--old-re)
+    (let ((i 1))
+      (dolist (re ivy--old-re)
+        (when (string-match (car re) str)
+          (ivy-add-face-text-property
+           (match-beginning 0) (match-end 0)
+           (nth (1+ (mod (+ i 2) (1- (length ivy-minibuffer-faces))))
+                ivy-minibuffer-faces)
+           str))
+        (cl-incf i))))
+  str)
+
+(defun ivy--highlight-fuzzy (str)
+  "Highlight STR, using the fuzzy method."
+  (if ivy--flx-featurep
+      (let ((flx-name (if (string-match "^\\^" ivy-text)
+                          (substring ivy-text 1)
+                        ivy-text)))
+        (ivy--flx-propertize
+         (cons (flx-score str flx-name ivy--flx-cache) str)))
+    (ivy--highlight-default str)))
+
+(defun ivy--highlight-default (str)
+  "Highlight STR, using the default method."
+  (unless ivy--old-re
+    (setq ivy--old-re (funcall ivy--regex-function ivy-text)))
+  (let ((start
+         (if (and (memq (ivy-state-caller ivy-last) ivy-highlight-grep-commands)
+                  (string-match "^[^:]+:[^:]+:" str))
+             (match-end 0)
+           0))
+        (regexps
+         (if (listp ivy--old-re)
+             (mapcar #'car (cl-remove-if-not #'cdr ivy--old-re))
+           (list ivy--old-re))))
+    (dolist (re regexps)
+      (ignore-errors
+        (while (and (string-match re str start)
+                    (> (- (match-end 0) (match-beginning 0)) 0))
+          (setq start (match-end 0))
+          (let ((i 0))
+            (while (<= i ivy--subexps)
+              (let ((face
+                     (cond ((zerop ivy--subexps)
+                            (cadr ivy-minibuffer-faces))
+                           ((zerop i)
+                            (car ivy-minibuffer-faces))
+                           (t
+                            (nth (1+ (mod (+ i 2)
+                                          (1- (length ivy-minibuffer-faces))))
+                                 ivy-minibuffer-faces)))))
+                (ivy-add-face-text-property
+                 (match-beginning i) (match-end i)
+                 face str))
+              (cl-incf i)))))))
+  str)
+
+(defun ivy--format-minibuffer-line (str)
+  "Format line STR for use in minibuffer."
+  (let* ((str (ivy-cleanup-string str))
+         (str (if (eq ivy-display-style 'fancy)
+                  (funcall ivy--highlight-function (copy-sequence str))
+                (copy-sequence str))))
+    (add-text-properties
+     0 (length str)
+     '(mouse-face
+       ivy-minibuffer-match-highlight
+       help-echo
+       (format
+        (if tooltip-mode
+            "mouse-1: %s\nmouse-3: %s"
+          "mouse-1: %s   mouse-3: %s")
+        ivy-mouse-1-tooltip ivy-mouse-3-tooltip))
+     str)
+    str))
+
+(ivy-set-display-transformer
+ 'counsel-find-file 'ivy-read-file-transformer)
+(ivy-set-display-transformer
+ 'read-file-name-internal 'ivy-read-file-transformer)
+
+(defun ivy-read-file-transformer (str)
+  "Transform candidate STR when reading files."
+  (if (ivy--dirname-p str)
+      (propertize str 'face 'ivy-subdir)
+    str))
+
+(defun ivy--format (cands)
+  "Return a string for CANDS suitable for display in the minibuffer.
+CANDS is a list of strings."
+  (setq ivy--length (length cands))
+  (when (>= ivy--index ivy--length)
+    (ivy-set-index (max (1- ivy--length) 0)))
+  (if (null cands)
+      (setf (ivy-state-current ivy-last) "")
+    (setf (ivy-state-current ivy-last) (copy-sequence (nth ivy--index cands)))
+    (let* ((half-height (/ ivy-height 2))
+           (start (max 0 (- ivy--index half-height)))
+           (end (min (+ start (1- ivy-height)) ivy--length))
+           (start (max 0 (min start (- end (1- ivy-height)))))
+           (wnd-cands (cl-subseq cands start end))
+           transformer-fn)
+      (setq ivy--window-index (- ivy--index start))
+      (when (setq transformer-fn (ivy-state-display-transformer-fn ivy-last))
+        (with-ivy-window
+          (with-current-buffer (ivy-state-buffer ivy-last)
+            (setq wnd-cands (mapcar transformer-fn wnd-cands)))))
+      (ivy--wnd-cands-to-str wnd-cands))))
+
+(defun ivy--wnd-cands-to-str (wnd-cands)
+  (let ((str (concat "\n"
+                     (funcall ivy-format-function
+                              (mapcar
+                               #'ivy--format-minibuffer-line
+                               wnd-cands)))))
+    (put-text-property 0 (length str) 'read-only nil str)
+    str))
+
+(defvar recentf-list)
+(defvar bookmark-alist)
+
+(defcustom ivy-virtual-abbreviate 'name
+  "The mode of abbreviation for virtual buffer names."
+  :type '(choice
+          (const :tag "Only name" name)
+          (const :tag "Abbreviated path" abbreviate)
+          (const :tag "Full path" full)
+          ;; eventually, uniquify
+          ))
+(declare-function bookmark-maybe-load-default-file "bookmark")
+(declare-function bookmark-get-filename "bookmark")
+
+(defun ivy--virtual-buffers ()
+  "Adapted from `ido-add-virtual-buffers-to-list'."
+  (require 'bookmark)
+  (unless recentf-mode
+    (recentf-mode 1))
+  (let (virtual-buffers)
+    (bookmark-maybe-load-default-file)
+    (dolist (head (append
+                   (copy-sequence recentf-list)
+                   (delete "   - no file -"
+                           (delq nil (mapcar #'bookmark-get-filename
+                                             (copy-sequence bookmark-alist))))))
+      (let ((file-name (if (stringp head)
+                           head
+                         (cdr head)))
+            name)
+        (setq name
+              (cond ((eq ivy-virtual-abbreviate 'name)
+                     (file-name-nondirectory file-name))
+                    ((eq ivy-virtual-abbreviate 'abbreviate)
+                     (abbreviate-file-name file-name))
+                    (t
+                     (expand-file-name file-name))))
+        (when (equal name "")
+          (if (consp head)
+              (setq name (car head))
+            (setq name (file-name-nondirectory
+                        (directory-file-name file-name)))))
+        (and (not (equal name ""))
+             (null (get-file-buffer file-name))
+             (not (assoc name virtual-buffers))
+             (push (cons name file-name) virtual-buffers))))
+    (when virtual-buffers
+      (dolist (comp virtual-buffers)
+        (put-text-property 0 (length (car comp))
+                           'face 'ivy-virtual
+                           (car comp)))
+      (setq ivy--virtual-buffers (nreverse virtual-buffers))
+      (mapcar #'car ivy--virtual-buffers))))
+
+(defcustom ivy-ignore-buffers '("\\` ")
+  "List of regexps or functions matching buffer names to ignore."
+  :type '(repeat (choice regexp function)))
+
+(defvar ivy-switch-buffer-faces-alist '((dired-mode . ivy-subdir)
+                                        (org-mode . org-level-4))
+  "Store face customizations for `ivy-switch-buffer'.
+Each KEY is `major-mode', each VALUE is a face name.")
+
+(defun ivy--buffer-list (str &optional virtual predicate)
+  "Return the buffers that match STR.
+If VIRTUAL is non-nil, add virtual buffers.
+If optional argument PREDICATE is non-nil, use it to test each
+possible match.  See `all-completions' for further information."
+  (delete-dups
+   (append
+    (mapcar
+     (lambda (x)
+       (if (with-current-buffer x
+             (and default-directory
+                  (file-remote-p
+                   (abbreviate-file-name default-directory))))
+           (propertize x 'face 'ivy-remote)
+         (let ((face (with-current-buffer x
+                       (cdr (assoc major-mode
+                                   ivy-switch-buffer-faces-alist)))))
+           (if face
+               (propertize x 'face face)
+             x))))
+     (all-completions str 'internal-complete-buffer predicate))
+    (and virtual
+         (ivy--virtual-buffers)))))
+
+(defvar ivy-views (and nil
+                       `(("ivy + *scratch* {}"
+                          (vert
+                           (file ,(expand-file-name "ivy.el"))
+                           (buffer "*scratch*")))
+                         ("swiper + *scratch* {}"
+                          (horz
+                           (file ,(expand-file-name "swiper.el"))
+                           (buffer "*scratch*")))))
+  "Store window configurations selectable by `ivy-switch-buffer'.
+
+The default value is given as an example.
+
+Each element is a list of (NAME TREE).  NAME is a string, it's
+recommended to end it with a distinctive snippet e.g. \"{}\" so
+that it's easy to distinguish the window configurations.
+
+TREE is a nested list with the following valid cars:
+- vert: split the window vertically
+- horz: split the window horizontally
+- file: open the specified file
+- buffer: open the specified buffer
+
+TREE can be nested multiple times to have multiple window splits.")
+
+(defun ivy-default-view-name ()
+  "Return default name for new view."
+  (let* ((default-view-name
+          (concat "{} "
+                  (mapconcat #'identity
+                             (sort
+                              (mapcar (lambda (w)
+                                        (let* ((b (window-buffer w))
+                                               (f (buffer-file-name b)))
+                                          (if f
+                                              (file-name-nondirectory f)
+                                            (buffer-name b))))
+                                      (window-list))
+                              #'string-lessp)
+                             " ")))
+         (view-name-re (concat "\\`"
+                               (regexp-quote default-view-name)
+                               " \\([0-9]+\\)"))
+         old-view)
+    (cond ((setq old-view
+                 (cl-find-if
+                  (lambda (x)
+                    (string-match view-name-re (car x)))
+                  ivy-views))
+           (format "%s %d"
+                   default-view-name
+                   (1+ (string-to-number
+                        (match-string 1 (car old-view))))))
+          ((assoc default-view-name ivy-views)
+           (concat default-view-name " 1"))
+          (t
+           default-view-name))))
+
+(defun ivy-push-view ()
+  "Push the current window tree on `ivy-views'.
+Currently, the split configuration (i.e. horizonal or vertical)
+and point positions are saved, but the split positions aren't.
+Use `ivy-pop-view' to delete any item from `ivy-views'."
+  (interactive)
+  (let* ((view (cl-labels
+                   ((ft (tr)
+                      (if (consp tr)
+                          (if (eq (car tr) t)
+                              (cons 'vert
+                                    (mapcar #'ft (cddr tr)))
+                            (cons 'horz
+                                  (mapcar #'ft (cddr tr))))
+                        (with-current-buffer (window-buffer tr)
+                          (cond ((buffer-file-name)
+                                 (list 'file (buffer-file-name) (point)))
+                                ((eq major-mode 'dired-mode)
+                                 (list 'file default-directory (point)))
+                                (t
+                                 (list 'buffer (buffer-name) (point))))))))
+                 (ft (car (window-tree)))))
+         (view-name (ivy-read "Name view: " nil
+                              :initial-input (ivy-default-view-name))))
+    (when view-name
+      (push (list view-name view) ivy-views))))
+
+(defun ivy-pop-view-action (view)
+  "Delete VIEW from `ivy-views'."
+  (setq ivy-views (delete view ivy-views))
+  (setq ivy--all-candidates
+        (delete (car view) ivy--all-candidates))
+  (setq ivy--old-cands nil))
+
+(defun ivy-pop-view ()
+  "Delete a view to delete from `ivy-views'."
+  (interactive)
+  (ivy-read "Pop view: " ivy-views
+            :preselect (caar ivy-views)
+            :action #'ivy-pop-view-action
+            :caller 'ivy-pop-view))
+
+(defun ivy-source-views ()
+  "Return the name of the views saved in `ivy-views'."
+  (mapcar #'car ivy-views))
+
+(ivy-set-sources
+ 'ivy-switch-buffer
+ '((original-source)
+   (ivy-source-views)))
+
+(defun ivy-set-view-recur (view)
+  "Set VIEW recursively."
+  (cond ((eq (car view) 'vert)
+         (let* ((wnd1 (selected-window))
+                (wnd2 (split-window-vertically))
+                (views (cdr view))
+                (v (pop views)))
+           (with-selected-window wnd1
+             (ivy-set-view-recur v))
+           (while (setq v (pop views))
+             (with-selected-window wnd2
+               (ivy-set-view-recur v))
+             (when views
+               (setq wnd2 (split-window-vertically))))))
+        ((eq (car view) 'horz)
+         (let* ((wnd1 (selected-window))
+                (wnd2 (split-window-horizontally))
+                (views (cdr view))
+                (v (pop views)))
+           (with-selected-window wnd1
+             (ivy-set-view-recur v))
+           (while (setq v (pop views))
+             (with-selected-window wnd2
+               (ivy-set-view-recur v))
+             (when views
+               (setq wnd2 (split-window-horizontally))))))
+        ((eq (car view) 'file)
+         (let* ((name (nth 1 view))
+                (virtual (assoc name ivy--virtual-buffers))
+                buffer)
+           (cond ((setq buffer (get-buffer name))
+                  (switch-to-buffer buffer nil 'force-same-window))
+                 (virtual
+                  (find-file (cdr virtual)))
+                 ((file-exists-p name)
+                  (find-file name))))
+         (when (and (> (length view) 2)
+                    (numberp (nth 2 view)))
+           (goto-char (nth 2 view))))
+        ((eq (car view) 'buffer)
+         (switch-to-buffer (nth 1 view))
+         (when (and (> (length view) 2)
+                    (numberp (nth 2 view)))
+           (goto-char (nth 2 view))))
+        ((eq (car view) 'sexp)
+         (eval (nth 1 view)))))
+
+(defun ivy--switch-buffer-action (buffer)
+  "Switch to BUFFER.
+BUFFER may be a string or nil."
+  (with-ivy-window
+    (if (zerop (length buffer))
+        (switch-to-buffer
+         ivy-text nil 'force-same-window)
+      (let ((virtual (assoc buffer ivy--virtual-buffers))
+            (view (assoc buffer ivy-views)))
+        (cond ((and virtual
+                    (not (get-buffer buffer)))
+               (find-file (cdr virtual)))
+              (view
+               (delete-other-windows)
+               (let (
+                     ;; silence "Directory has changed on disk"
+                     (inhibit-message t))
+                 (ivy-set-view-recur (cadr view))))
+              (t
+               (switch-to-buffer
+                buffer nil 'force-same-window)))))))
+
+(defun ivy--switch-buffer-other-window-action (buffer)
+  "Switch to BUFFER in other window.
+BUFFER may be a string or nil."
+  (if (zerop (length buffer))
+      (switch-to-buffer-other-window ivy-text)
+    (let ((virtual (assoc buffer ivy--virtual-buffers)))
+      (if (and virtual
+               (not (get-buffer buffer)))
+          (find-file-other-window (cdr virtual))
+        (switch-to-buffer-other-window buffer)))))
+
+(defun ivy--rename-buffer-action (buffer)
+  "Rename BUFFER."
+  (let ((new-name (read-string "Rename buffer (to new name): ")))
+    (with-current-buffer buffer
+      (rename-buffer new-name))))
+
+(defun ivy--find-file-action (buffer)
+  "Find file from BUFFER's directory."
+  (let* ((b (get-buffer buffer))
+         (default-directory
+          (or (and b (buffer-local-value 'default-directory b))
+              default-directory)))
+    (call-interactively (if (functionp 'counsel-find-file)
+                            #'counsel-find-file
+                          #'find-file))))
+
+(defun ivy--kill-buffer-action (buffer)
+  "Kill BUFFER."
+  (kill-buffer buffer)
+  (unless (buffer-live-p (ivy-state-buffer ivy-last))
+    (setf (ivy-state-buffer ivy-last) (current-buffer)))
+  (setq ivy--index 0)
+  (ivy--reset-state ivy-last))
+
+(defvar ivy-switch-buffer-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "C-c C-k") 'ivy-switch-buffer-kill)
+    map))
+
+(defun ivy-switch-buffer-kill ()
+  "Kill the current buffer in `ivy-switch-buffer'."
+  (interactive)
+  (let ((bn (ivy-state-current ivy-last)))
+    (when (get-buffer bn)
+      (kill-buffer bn))
+    (unless (buffer-live-p (ivy-state-buffer ivy-last))
+      (setf (ivy-state-buffer ivy-last)
+            (with-ivy-window (current-buffer))))
+    (setf (ivy-state-preselect ivy-last) ivy--index)
+    (setq ivy--old-re nil)
+    (setq ivy--all-candidates (delete bn ivy--all-candidates))
+    (ivy--exhibit)))
+
+(ivy-set-actions
+ 'ivy-switch-buffer
+ '(("f"
+    ivy--find-file-action
+    "find file")
+   ("j"
+    ivy--switch-buffer-other-window-action
+    "other window")
+   ("k"
+    ivy--kill-buffer-action
+    "kill")
+   ("r"
+    ivy--rename-buffer-action
+    "rename")))
+
+(ivy-set-actions
+ t
+ `(("i" ,(lambda (x) (insert (if (stringp x) x (car x)))) "insert")
+   ("w" ,(lambda (x) (kill-new (if (stringp x) x (car x)))) "copy")))
+
+(defun ivy--switch-buffer-matcher (regexp candidates)
+  "Return REGEXP matching CANDIDATES.
+Skip buffers that match `ivy-ignore-buffers'."
+  (let ((res (ivy--re-filter regexp candidates)))
+    (if (or (null ivy-use-ignore)
+            (null ivy-ignore-buffers))
+        res
+      (or (cl-remove-if
+           (lambda (buf)
+             (cl-find-if
+              (lambda (f-or-r)
+                (if (functionp f-or-r)
+                    (funcall f-or-r buf)
+                  (string-match-p f-or-r buf)))
+              ivy-ignore-buffers))
+           res)
+          (and (eq ivy-use-ignore t)
+               res)))))
+
+(ivy-set-display-transformer
+ 'ivy-switch-buffer 'ivy-switch-buffer-transformer)
+(ivy-set-display-transformer
+ 'internal-complete-buffer 'ivy-switch-buffer-transformer)
+
+(defun ivy-append-face (str face)
+  "Append to STR the property FACE."
+  (setq str (copy-sequence str))
+  (ivy-add-face-text-property 0 (length str) face str t)
+  str)
+
+(defun ivy-switch-buffer-transformer (str)
+  "Transform candidate STR when switching buffers."
+  (let ((b (get-buffer str)))
+    (if (and b
+             (buffer-file-name b)
+             (buffer-modified-p b))
+        (ivy-append-face str 'ivy-modified-buffer)
+      str)))
+
+(defun ivy-switch-buffer-occur ()
+  "Occur function for `ivy-switch-buffer' using `ibuffer'."
+  (ibuffer nil (buffer-name) (list (cons 'name ivy--old-re))))
+
+;;;###autoload
+(defun ivy-switch-buffer ()
+  "Switch to another buffer."
+  (interactive)
+  (let ((this-command 'ivy-switch-buffer))
+    (ivy-read "Switch to buffer: " 'internal-complete-buffer
+              :matcher #'ivy--switch-buffer-matcher
+              :preselect (buffer-name (other-buffer (current-buffer)))
+              :action #'ivy--switch-buffer-action
+              :keymap ivy-switch-buffer-map
+              :caller 'ivy-switch-buffer)))
+
+;;;###autoload
+(defun ivy-switch-view ()
+  "Switch to one of the window views stored by `ivy-push-view'."
+  (interactive)
+  (let ((ivy-initial-inputs-alist
+         '((ivy-switch-buffer . "{}"))))
+    (ivy-switch-buffer)))
+
+;;;###autoload
+(defun ivy-switch-buffer-other-window ()
+  "Switch to another buffer in another window."
+  (interactive)
+  (ivy-read "Switch to buffer in other window: " 'internal-complete-buffer
+            :matcher #'ivy--switch-buffer-matcher
+            :preselect (buffer-name (other-buffer (current-buffer)))
+            :action #'ivy--switch-buffer-other-window-action
+            :keymap ivy-switch-buffer-map
+            :caller 'ivy-switch-buffer-other-window))
+
+(define-obsolete-function-alias 'ivy-recentf 'counsel-recentf "0.8.0")
+
+(defun ivy--yank-by (fn &rest args)
+  "Pull buffer text from current line into search string.
+The region to extract is determined by the respective values of
+point before and after applying FN to ARGS."
+  (let (text)
+    (with-ivy-window
+      (let ((pos (point))
+            (bol (line-beginning-position))
+            (eol (line-end-position)))
+        (unwind-protect
+             (progn (apply fn args)
+                    (setq text (buffer-substring-no-properties
+                                pos (goto-char (max bol (min (point) eol))))))
+          (unless text
+            (goto-char pos)))))
+    (when text
+      (insert (replace-regexp-in-string "  +" " " text t t)))))
+
+(defun ivy-yank-word (&optional arg)
+  "Pull next word from buffer into search string.
+If optional ARG is non-nil, pull in the next ARG
+words (previous if ARG is negative)."
+  (interactive "p")
+  (ivy--yank-by #'forward-word arg))
+
+(defun ivy-yank-symbol (&optional arg)
+  "Pull next symbol from buffer into search string.
+If optional ARG is non-nil, pull in the next ARG
+symbols (previous if ARG is negative)."
+  (interactive "p")
+  ;; Emacs < 24.4 compatibility
+  (unless (fboundp 'forward-symbol)
+    (require 'thingatpt))
+  (ivy--yank-by #'forward-symbol (or arg 1)))
+
+(defun ivy-yank-char (&optional arg)
+  "Pull next character from buffer into search string.
+If optional ARG is non-nil, pull in the next ARG
+characters (previous if ARG is negative)."
+  (interactive "p")
+  (ivy--yank-by #'forward-char arg))
+
+(defun ivy-kill-ring-save ()
+  "Store the current candidates into the kill ring.
+If the region is active, forward to `kill-ring-save' instead."
+  (interactive)
+  (if (region-active-p)
+      (call-interactively 'kill-ring-save)
+    (kill-new
+     (mapconcat
+      #'identity
+      ivy--old-cands
+      "\n"))))
+
+(defun ivy-insert-current ()
+  "Make the current candidate into current input.
+Don't finish completion."
+  (interactive)
+  (delete-minibuffer-contents)
+  (if (and ivy--directory
+           (string-match "/$" (ivy-state-current ivy-last)))
+      (insert (substring (ivy-state-current ivy-last) 0 -1))
+    (insert (ivy-state-current ivy-last))))
+
+(define-obsolete-variable-alias 'ivy--preferred-re-builders
+    'ivy-preferred-re-builders "0.10.0")
+
+(defcustom ivy-preferred-re-builders
+  '((ivy--regex-plus . "ivy")
+    (ivy--regex-ignore-order . "order")
+    (ivy--regex-fuzzy . "fuzzy"))
+  "Alist of preferred re-builders with display names.
+This list can be rotated with `ivy-rotate-preferred-builders'."
+  :type '(alist :key-type function :value-type string))
+
+(defun ivy-rotate-preferred-builders ()
+  "Switch to the next re builder in `ivy-preferred-re-builders'."
+  (interactive)
+  (when ivy-preferred-re-builders
+    (setq ivy--old-re nil)
+    (setq ivy--regex-function
+          (let ((cell (assq ivy--regex-function ivy-preferred-re-builders)))
+            (car (or (cadr (memq cell ivy-preferred-re-builders))
+                     (car ivy-preferred-re-builders)))))))
+
+(defun ivy-toggle-fuzzy ()
+  "Toggle the re builder between `ivy--regex-fuzzy' and `ivy--regex-plus'."
+  (interactive)
+  (setq ivy--old-re nil)
+  (if (eq ivy--regex-function 'ivy--regex-fuzzy)
+      (setq ivy--regex-function 'ivy--regex-plus)
+    (setq ivy--regex-function 'ivy--regex-fuzzy)))
+
+(defun ivy-reverse-i-search ()
+  "Enter a recursive `ivy-read' session using the current history.
+The selected history element will be inserted into the minibuffer."
+  (interactive)
+  (let ((enable-recursive-minibuffers t)
+        (history (symbol-value (ivy-state-history ivy-last)))
+        (old-last ivy-last)
+        (ivy-recursive-restore nil))
+    (ivy-read "Reverse-i-search: "
+              (delete-dups (copy-sequence history))
+              :action (lambda (x)
+                        (ivy--reset-state
+                         (setq ivy-last old-last))
+                        (delete-minibuffer-contents)
+                        (insert (substring-no-properties x))
+                        (ivy--cd-maybe)))))
+
+(defun ivy-restrict-to-matches ()
+  "Restrict candidates to current input and erase input."
+  (interactive)
+  (delete-minibuffer-contents)
+  (setq ivy--all-candidates
+        (ivy--filter ivy-text ivy--all-candidates)))
+
+;;* Occur
+(defvar-local ivy-occur-last nil
+  "Buffer-local value of `ivy-last'.
+Can't re-use `ivy-last' because using e.g. `swiper' in the same
+buffer would modify `ivy-last'.")
+
+(defvar ivy-occur-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map [mouse-1] 'ivy-occur-click)
+    (define-key map (kbd "RET") 'ivy-occur-press-and-switch)
+    (define-key map (kbd "j") 'ivy-occur-next-line)
+    (define-key map (kbd "k") 'ivy-occur-previous-line)
+    (define-key map (kbd "h") 'backward-char)
+    (define-key map (kbd "l") 'forward-char)
+    (define-key map (kbd "f") 'ivy-occur-press)
+    (define-key map (kbd "g") 'ivy-occur-revert-buffer)
+    (define-key map (kbd "a") 'ivy-occur-read-action)
+    (define-key map (kbd "o") 'ivy-occur-dispatch)
+    (define-key map (kbd "c") 'ivy-occur-toggle-calling)
+    (define-key map (kbd "q") 'quit-window)
+    (define-key map (kbd "R") 'read-only-mode)
+    (define-key map (kbd "C-d") 'ivy-occur-delete-candidate)
+    map)
+  "Keymap for Ivy Occur mode.")
+
+(defun ivy-occur-toggle-calling ()
+  "Toggle `ivy-calling'."
+  (interactive)
+  (if (setq ivy-calling (not ivy-calling))
+      (progn
+        (setq mode-name "Ivy-Occur [calling]")
+        (ivy-occur-press))
+    (setq mode-name "Ivy-Occur"))
+  (force-mode-line-update))
+
+(defun ivy-occur-next-line (&optional arg)
+  "Move the cursor down ARG lines.
+When `ivy-calling' isn't nil, call `ivy-occur-press'."
+  (interactive "p")
+  (forward-line arg)
+  (when ivy-calling
+    (ivy-occur-press)))
+
+(defun ivy-occur-previous-line (&optional arg)
+  "Move the cursor up ARG lines.
+When `ivy-calling' isn't nil, call `ivy-occur-press'."
+  (interactive "p")
+  (forward-line (- arg))
+  (when ivy-calling
+    (ivy-occur-press)))
+
+(define-derived-mode ivy-occur-mode fundamental-mode "Ivy-Occur"
+  "Major mode for output from \\[ivy-occur].
+
+\\{ivy-occur-mode-map}"
+  (setq-local view-read-only nil))
+
+(defvar ivy-occur-grep-mode-map
+  (let ((map (copy-keymap ivy-occur-mode-map)))
+    (define-key map (kbd "C-x C-q") 'ivy-wgrep-change-to-wgrep-mode)
+    (define-key map "w" 'ivy-wgrep-change-to-wgrep-mode)
+    map)
+  "Keymap for Ivy Occur Grep mode.")
+
+(defun ivy-occur-delete-candidate ()
+  (interactive)
+  (let ((inhibit-read-only t))
+    (delete-region (line-beginning-position)
+                   (1+ (line-end-position)))))
+
+(define-derived-mode ivy-occur-grep-mode grep-mode "Ivy-Occur"
+  "Major mode for output from \\[ivy-occur].
+
+\\{ivy-occur-grep-mode-map}"
+  (setq-local view-read-only nil)
+  (when (fboundp 'wgrep-setup)
+    (wgrep-setup)))
+
+(defvar ivy--occurs-list nil
+  "A list of custom occur generators per command.")
+
+(defun ivy-set-occur (cmd occur)
+  "Assign CMD a custom OCCUR function."
+  (setq ivy--occurs-list
+        (plist-put ivy--occurs-list cmd occur)))
+
+(ivy-set-occur 'ivy-switch-buffer 'ivy-switch-buffer-occur)
+(ivy-set-occur 'ivy-switch-buffer-other-window 'ivy-switch-buffer-occur)
+
+(defun ivy--occur-insert-lines (cands)
+  "Insert CANDS into `ivy-occur' buffer."
+  (dolist (str cands)
+    (add-text-properties
+     0 (length str)
+     `(mouse-face
+       highlight
+       help-echo "mouse-1: call ivy-action")
+     str)
+    (insert str "\n"))
+  (goto-char (point-min))
+  (forward-line 4))
+
+(defun ivy-occur ()
+  "Stop completion and put the current candidates into a new buffer.
+
+The new buffer remembers current action(s).
+
+While in the *ivy-occur* buffer, selecting a candidate with RET or
+a mouse click will call the appropriate action for that candidate.
+
+There is no limit on the number of *ivy-occur* buffers."
+  (interactive)
+  (if (not (window-minibuffer-p))
+      (user-error "No completion session is active")
+    (let* ((caller (ivy-state-caller ivy-last))
+           (occur-fn (plist-get ivy--occurs-list caller))
+           (buffer
+            (generate-new-buffer
+             (format "*ivy-occur%s \"%s\"*"
+                     (if caller
+                         (concat " " (prin1-to-string caller))
+                       "")
+                     ivy-text))))
+      (with-current-buffer buffer
+        (let ((inhibit-read-only t))
+          (erase-buffer)
+          (if occur-fn
+              (funcall occur-fn)
+            (ivy-occur-mode)
+            (insert (format "%d candidates:\n" (length ivy--old-cands)))
+            (read-only-mode)
+            (ivy--occur-insert-lines
+             (mapcar
+              (lambda (cand) (concat "    " cand))
+              ivy--old-cands))))
+        (setf (ivy-state-text ivy-last) ivy-text)
+        (setq ivy-occur-last ivy-last)
+        (setq-local ivy--directory ivy--directory))
+      (ivy-exit-with-action
+       (lambda (_) (pop-to-buffer buffer))))))
+
+(defun ivy-occur-revert-buffer ()
+  "Refresh the buffer making it up-to date with the collection.
+
+Currently only works for `swiper'.  In that specific case, the
+*ivy-occur* buffer becomes nearly useless as the orignal buffer
+is updated, since the line numbers no longer match.
+
+Calling this function is as if you called `ivy-occur' on the
+updated original buffer."
+  (interactive)
+  (let ((caller (ivy-state-caller ivy-occur-last))
+        (ivy-last ivy-occur-last))
+    (cond ((eq caller 'swiper)
+           (let ((buffer (ivy-state-buffer ivy-occur-last)))
+             (unless (buffer-live-p buffer)
+               (error "Buffer was killed"))
+             (let ((inhibit-read-only t))
+               (erase-buffer)
+               (funcall (plist-get ivy--occurs-list caller) t)
+               (ivy-occur-grep-mode))))
+          ((memq caller '(counsel-git-grep counsel-grep counsel-ag counsel-rg))
+           (let ((inhibit-read-only t))
+             (erase-buffer)
+             (funcall (plist-get ivy--occurs-list caller)))))
+    (setq ivy-occur-last ivy-last)))
+
+(declare-function wgrep-change-to-wgrep-mode "ext:wgrep")
+
+(defun ivy-wgrep-change-to-wgrep-mode ()
+  "Forward to `wgrep-change-to-wgrep-mode'."
+  (interactive)
+  (if (require 'wgrep nil 'noerror)
+      (wgrep-change-to-wgrep-mode)
+    (error "Package wgrep isn't installed")))
+
+(defun ivy-occur-read-action ()
+  "Select one of the available actions as the current one."
+  (interactive)
+  (let ((ivy-last ivy-occur-last))
+    (ivy-read-action)))
+
+(defun ivy-occur-dispatch ()
+  "Call one of the available actions on the current item."
+  (interactive)
+  (let* ((state-action (ivy-state-action ivy-occur-last))
+         (actions (if (symbolp state-action)
+                      state-action
+                    (copy-sequence state-action))))
+    (unwind-protect
+         (progn
+           (ivy-occur-read-action)
+           (ivy-occur-press))
+      (setf (ivy-state-action ivy-occur-last) actions))))
+
+(defun ivy-occur-click (event)
+  "Execute action for the current candidate.
+EVENT gives the mouse position."
+  (interactive "e")
+  (let ((window (posn-window (event-end event)))
+        (pos (posn-point (event-end event))))
+    (with-current-buffer (window-buffer window)
+      (goto-char pos)
+      (ivy-occur-press))))
+
+(declare-function swiper--cleanup "swiper")
+(declare-function swiper--add-overlays "swiper")
+(defvar ivy-occur-timer nil)
+(defvar counsel-grep-last-line)
+
+(defun ivy--occur-press-update-window ()
+  (cl-case (ivy-state-caller ivy-occur-last)
+    ((swiper counsel-git-grep counsel-grep counsel-ag counsel-rg)
+     (let ((window (ivy-state-window ivy-occur-last)))
+       (when (or (null (window-live-p window))
+                 (equal window (selected-window)))
+         (save-selected-window
+           (setf (ivy-state-window ivy-occur-last)
+                 (display-buffer (ivy-state-buffer ivy-occur-last)
+                                 'display-buffer-pop-up-window))))))
+
+    ((counsel-describe-function counsel-describe-variable)
+     (setf (ivy-state-window ivy-occur-last)
+           (selected-window))
+     (selected-window))))
+
+(defun ivy--occur-press-buffer ()
+  (let ((buffer (ivy-state-buffer ivy-last)))
+    (if (buffer-live-p buffer)
+        buffer
+      (current-buffer))))
+
+(defun ivy-occur-press ()
+  "Execute action for the current candidate."
+  (interactive)
+  (ivy--occur-press-update-window)
+  (when (save-excursion
+          (beginning-of-line)
+          (looking-at "\\(?:./\\|    \\)\\(.*\\)$"))
+    (let* ((ivy-last ivy-occur-last)
+           (ivy-text (ivy-state-text ivy-last))
+           (str (buffer-substring
+                 (match-beginning 1)
+                 (match-end 1)))
+           (coll (ivy-state-collection ivy-last))
+           (action (ivy--get-action ivy-last))
+           (ivy-exit 'done))
+      (with-ivy-window
+        (setq counsel-grep-last-line nil)
+        (with-current-buffer (ivy--occur-press-buffer)
+          (funcall action
+                   (if (and (consp coll)
+                            (consp (car coll)))
+                       (assoc str coll)
+                     str)))
+        (if (memq (ivy-state-caller ivy-last)
+                  '(swiper counsel-git-grep counsel-grep counsel-ag counsel-rg))
+            (with-current-buffer (window-buffer (selected-window))
+              (swiper--cleanup)
+              (swiper--add-overlays
+               (ivy--regex ivy-text)
+               (line-beginning-position)
+               (line-end-position)
+               (selected-window))
+              (when (timerp ivy-occur-timer)
+                (cancel-timer ivy-occur-timer))
+              (setq ivy-occur-timer
+                    (run-at-time 1.0 nil 'swiper--cleanup))))))))
+
+(defun ivy-occur-press-and-switch ()
+  "Execute action for the current candidate and switch window."
+  (interactive)
+  (ivy-occur-press)
+  (select-window (ivy--get-window ivy-occur-last)))
+
+(defconst ivy-help-file (let ((default-directory
+                               (if load-file-name
+                                   (file-name-directory load-file-name)
+                                 default-directory)))
+                          (if (file-exists-p "ivy-help.org")
+                              (expand-file-name "ivy-help.org")
+                            (if (file-exists-p "doc/ivy-help.org")
+                                (expand-file-name "doc/ivy-help.org"))))
+  "The file for `ivy-help'.")
+
+(defun ivy-help ()
+  "Help for `ivy'."
+  (interactive)
+  (let ((buf (get-buffer "*Ivy Help*")))
+    (unless buf
+      (setq buf (get-buffer-create "*Ivy Help*"))
+      (with-current-buffer buf
+        (insert-file-contents ivy-help-file)
+        (org-mode)
+        (view-mode)
+        (goto-char (point-min))))
+    (if (eq this-command 'ivy-help)
+        (switch-to-buffer buf)
+      (with-ivy-window
+        (pop-to-buffer buf)))
+    (view-mode)
+    (goto-char (point-min))))
+
+(provide 'ivy)
+
+;;; ivy.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/ivy-20180719.1037/ivy.elc b/configs/shared/emacs/.emacs.d/elpa/ivy-20180719.1037/ivy.elc
new file mode 100644
index 0000000000..563437c142
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/ivy-20180719.1037/ivy.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/ivy-20180719.1037/ivy.info b/configs/shared/emacs/.emacs.d/elpa/ivy-20180719.1037/ivy.info
new file mode 100644
index 0000000000..18c63a7fed
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/ivy-20180719.1037/ivy.info
@@ -0,0 +1,1885 @@
+This is ivy.info, produced by makeinfo version 6.1 from ivy.texi.
+
+Ivy manual, version 0.8.0
+
+   Ivy is an interactive interface for completion in Emacs.  Emacs uses
+completion mechanism in a variety of contexts: code, menus, commands,
+variables, functions, etc.  Completion entails listing, sorting,
+filtering, previewing, and applying actions on selected items.  When
+active, ‘ivy-mode’ completes the selection process by narrowing
+available choices while previewing in the minibuffer.  Selecting the
+final candidate is either through simple keyboard character inputs or
+through powerful regular expressions.
+
+   Copyright (C) 2015-2018 Free Software Foundation, Inc.
+
+     Permission is granted to copy, distribute and/or modify this
+     document under the terms of the GNU Free Documentation License,
+     Version 1.3 or any later version published by the Free Software
+     Foundation; with no Invariant Sections, with the Front-Cover Texts
+     being “A GNU Manual,” and with the Back-Cover Texts as in (a)
+     below.  A copy of the license is included in the section entitled
+     “GNU Free Documentation License.”
+
+     (a) The FSF’s Back-Cover Text is: “You have the freedom to copy and
+     modify this GNU manual.”
+INFO-DIR-SECTION Emacs
+START-INFO-DIR-ENTRY
+* Ivy: (ivy).           Using Ivy for completion.
+END-INFO-DIR-ENTRY
+
+
+File: ivy.info,  Node: Top,  Next: Introduction,  Up: (dir)
+
+Ivy User Manual
+***************
+
+* Menu:
+
+* Introduction::
+* Installation::
+* Getting started::
+* Key bindings::
+* Completion Styles::
+* Customization::
+* Commands::
+* API::
+* Variable Index::
+* Keystroke Index::
+
+— The Detailed Node Listing —
+
+Installation
+
+* Installing from Emacs Package Manager::
+* Installing from the Git repository::
+
+Getting started
+
+* Basic customization::
+
+Key bindings
+
+* Global key bindings::
+* Minibuffer key bindings::
+
+Minibuffer key bindings
+
+* Key bindings for navigation::
+* Key bindings for single selection, action, then exit minibuffer: Key bindings for single selection action then exit minibuffer. 
+* Key bindings for multiple selections and actions, keep minibuffer open: Key bindings for multiple selections and actions keep minibuffer open. 
+* Key bindings that alter the minibuffer input::
+* Other key bindings::
+* Hydra in the minibuffer::
+* Saving the current completion session to a buffer::
+
+Completion Styles
+
+* ivy--regex-plus::
+* ivy--regex-ignore-order::
+* ivy--regex-fuzzy::
+
+Customization
+
+* Faces::
+* Defcustoms::
+* Actions::
+* Packages::
+
+Actions
+
+* What are actions?::
+* How can different actions be called?::
+* How to modify the actions list?::
+* Example - add two actions to each command::
+* Example - define a new command with several actions::
+
+Example - add two actions to each command
+
+* How to undo adding the two actions::
+* How to add actions to a specific command::
+
+Example - define a new command with several actions
+
+* Test the above function with ivy-occur::
+
+Commands
+
+* File Name Completion::
+* Buffer Name Completion::
+* Counsel commands::
+
+File Name Completion
+
+* Using TRAMP::
+
+API
+
+* Required arguments for ivy-read::
+* Optional arguments for ivy-read::
+* Example - counsel-describe-function::
+* Example - counsel-locate::
+* Example - ivy-read-with-extra-properties::
+
+
+
+File: ivy.info,  Node: Introduction,  Next: Installation,  Prev: Top,  Up: Top
+
+1 Introduction
+**************
+
+Ivy is for quick and easy selection from a list.  When Emacs prompts for
+a string from a list of several possible choices, Ivy springs into
+action to assist in narrowing and picking the right string from a vast
+number of choices.
+
+   Ivy strives for minimalism, simplicity, customizability and
+discoverability.
+
+Minimalism
+..........
+
+     Uncluttered minibuffer is minimalism.  Ivy shows the completion
+     defaults, the number of matches, and 10 candidate matches below the
+     input line.  Customize ‘ivy-height’ to adjust the number of
+     candidate matches displayed in the minibuffer.
+
+Simplicity
+..........
+
+     Simplicity is about Ivy’s behavior in the minibuffer.  It is also
+     about the code interface to extend Ivy’s functionality.  The
+     minibuffer area behaves as close to ‘fundamental-mode’ as possible.
+     ‘SPC’ inserts a space, for example, instead of being bound to the
+     more complex ‘minibuffer-complete-word’.  Ivy’s code uses
+     easy-to-examine global variables; avoids needless complications
+     with branch-introducing custom macros.
+
+Customizability
+...............
+
+     Customizability is about being able to use different methods and
+     interfaces of completion to tailor the selection process.  For
+     example, adding a custom display function that points to a selected
+     candidate with ‘>’, instead of highlighting the selected candidate
+     with the ‘ivy-current-match’ face (see ‘ivy-format-function’).  Or
+     take the customization of actions, say after the candidate function
+     is selected.  ‘RET’ uses ‘counsel-describe-function’ to describe
+     the function, whereas ‘M-o d’ jumps to that function’s definition
+     in the code.  The ‘M-o’ prefix can be uniformly used with
+     characters like ‘d’ to group similar actions.
+
+Discoverability
+...............
+
+     Ivy displays easily discoverable commands through the hydra
+     facility.  ‘C-o’ in the minibuffer displays a hydra menu.  It opens
+     up within an expanded minibuffer area.  Each menu item comes with
+     short documentation strings and highlighted one-key completions.
+     So discovering even seldom used keys is simply a matter of ‘C-o’ in
+     the minibuffer while in the midst of the Ivy interaction.  This
+     discoverability minimizes exiting Ivy interface for documentation
+     look-ups.
+
+
+File: ivy.info,  Node: Installation,  Next: Getting started,  Prev: Introduction,  Up: Top
+
+2 Installation
+**************
+
+Install Ivy automatically through Emacs’s package manager, or manually
+from Ivy’s development repository.
+
+   Emacs 24.3 is the oldest version to run Ivy.  Emacs 24.4 is the
+oldest version that runs Ivy with fancy faces display.
+
+* Menu:
+
+* Installing from Emacs Package Manager::
+* Installing from the Git repository::
+
+
+File: ivy.info,  Node: Installing from Emacs Package Manager,  Next: Installing from the Git repository,  Up: Installation
+
+2.1 Installing from Emacs Package Manager
+=========================================
+
+‘M-x’ ‘package-install’ ‘RET’ ‘ivy’ ‘RET’
+
+   Ivy is installed as part of ‘ivy’ package, which is available from
+two different package archives, GNU ELPA and MELPA. For the latest
+stable version, use the GNU ELPA archives using the above M-x command.
+
+   For current hourly builds, use the MELPA archives.  In MELPA, Ivy is
+split into three packages: ‘ivy’, ‘swiper’ and ‘counsel’; you can simply
+install ‘counsel’ which will bring in the other two as dependencies.
+See the code below for adding MELPA to the list of package archives:
+
+     (require 'package)
+     (add-to-list 'package-archives
+     	     '("melpa" . "http://melpa.org/packages/"))
+
+   After this do ‘M-x’ ‘package-refresh-contents’ ‘RET’, followed by
+‘M-x’ ‘package-install’ ‘RET’ ‘counsel’ ‘RET’.
+
+   For package manager details, see *note (emacs)Packages::.
+
+
+File: ivy.info,  Node: Installing from the Git repository,  Prev: Installing from Emacs Package Manager,  Up: Installation
+
+2.2 Installing from the Git repository
+======================================
+
+Why install from Git?
+.....................
+
+        • No need to wait for MELPA’s hourly builds
+        • Easy to revert to previous versions
+        • Contribute to Ivy’s development; send patches; pull requests
+
+Configuration steps
+...................
+
+     First clone the Swiper repository with:
+
+          cd ~/git && git clone https://github.com/abo-abo/swiper
+          cd swiper && make compile
+
+     Second, add these lines to the Emacs init file:
+
+          (add-to-list 'load-path "~/git/swiper/")
+          (require 'ivy)
+
+     Then, update the code with:
+
+          git pull
+          make
+
+
+File: ivy.info,  Node: Getting started,  Next: Key bindings,  Prev: Installation,  Up: Top
+
+3 Getting started
+*****************
+
+First enable Ivy completion everywhere:
+
+     (ivy-mode 1)
+
+   Note: ‘ivy-mode’ can be toggled on and off with ‘M-x’ ‘ivy-mode’.
+
+* Menu:
+
+* Basic customization::
+
+
+File: ivy.info,  Node: Basic customization,  Up: Getting started
+
+3.1 Basic customization
+=======================
+
+Here are some basic settings particularly useful for new Ivy users:
+
+     (setq ivy-use-virtual-buffers t)
+     (setq ivy-count-format "(%d/%d) ")
+
+   If you want, you can go without any customizations at all.  The above
+settings are the most bang for the buck in terms of customization.  So
+users that typically don’t like customize a lot are advised to look at
+these settings first.
+
+   For more advanced customizations, refer to ‘M-x describe-variable’
+documentation.
+
+
+File: ivy.info,  Node: Key bindings,  Next: Completion Styles,  Prev: Getting started,  Up: Top
+
+4 Key bindings
+**************
+
+* Menu:
+
+* Global key bindings::
+* Minibuffer key bindings::
+
+
+File: ivy.info,  Node: Global key bindings,  Next: Minibuffer key bindings,  Up: Key bindings
+
+4.1 Global key bindings
+=======================
+
+The recommended key bindings are:
+
+Ivy-based interface to standard commands
+........................................
+
+          (global-set-key (kbd "C-s") 'swiper)
+          (global-set-key (kbd "M-x") 'counsel-M-x)
+          (global-set-key (kbd "C-x C-f") 'counsel-find-file)
+          (global-set-key (kbd "<f1> f") 'counsel-describe-function)
+          (global-set-key (kbd "<f1> v") 'counsel-describe-variable)
+          (global-set-key (kbd "<f1> l") 'counsel-find-library)
+          (global-set-key (kbd "<f2> i") 'counsel-info-lookup-symbol)
+          (global-set-key (kbd "<f2> u") 'counsel-unicode-char)
+
+Ivy-based interface to shell and system tools
+.............................................
+
+          (global-set-key (kbd "C-c g") 'counsel-git)
+          (global-set-key (kbd "C-c j") 'counsel-git-grep)
+          (global-set-key (kbd "C-c k") 'counsel-ag)
+          (global-set-key (kbd "C-x l") 'counsel-locate)
+          (global-set-key (kbd "C-S-o") 'counsel-rhythmbox)
+
+Ivy-resume and other commands
+.............................
+
+     ‘ivy-resume’ resumes the last Ivy-based completion.
+
+          (global-set-key (kbd "C-c C-r") 'ivy-resume)
+
+
+File: ivy.info,  Node: Minibuffer key bindings,  Prev: Global key bindings,  Up: Key bindings
+
+4.2 Minibuffer key bindings
+===========================
+
+Ivy includes several minibuffer bindings, which are defined in the
+‘ivy-minibuffer-map’ keymap variable.  The most frequently used ones are
+described here.
+
+   ‘swiper’ or ‘counsel-M-x’ add more key bindings through the ‘keymap’
+argument to ‘ivy-read’.  These keys, also active in the minibuffer, are
+described under their respective commands.
+
+   A key feature of ‘ivy-minibuffer-map’ is its full editing capability
+where the familiar ‘C-a’, ‘C-f’, ‘M-d’, ‘M-DEL’, ‘M-b’, ‘M-w’, ‘C-k’,
+‘C-y’ key bindings work the same as in ‘fundamental-mode’.
+
+* Menu:
+
+* Key bindings for navigation::
+* Key bindings for single selection, action, then exit minibuffer: Key bindings for single selection action then exit minibuffer. 
+* Key bindings for multiple selections and actions, keep minibuffer open: Key bindings for multiple selections and actions keep minibuffer open. 
+* Key bindings that alter the minibuffer input::
+* Other key bindings::
+* Hydra in the minibuffer::
+* Saving the current completion session to a buffer::
+
+
+File: ivy.info,  Node: Key bindings for navigation,  Next: Key bindings for single selection action then exit minibuffer,  Up: Minibuffer key bindings
+
+4.2.1 Key bindings for navigation
+---------------------------------
+
+   • ‘C-n’ (‘ivy-next-line’) selects the next candidate
+   • ‘C-p’ (‘ivy-previous-line’) selects the previous candidate
+   • ‘M-<’ (‘ivy-beginning-of-buffer’) selects the first candidate
+   • ‘M->’ (‘ivy-end-of-buffer’) selects the last candidate
+   • ‘C-v’ (‘ivy-scroll-up-command’) scrolls up by ‘ivy-height’ lines
+   • ‘M-v’ (‘ivy-scroll-down-command’) scrolls down by ‘ivy-height’
+     lines
+
+ -- User Option: ivy-wrap
+     Specifies the wrap-around behavior for ‘C-n’ and ‘C-p’.  When
+     ‘ivy-wrap’ is set to ‘t’, ‘ivy-next-line’ and ‘ivy-previous-line’
+     will cycle past the last and the first candidates respectively.
+
+     Warp-around behavior is off by default.
+
+ -- User Option: ivy-height
+     Use this option to adjust the minibuffer height, which also affects
+     scroll size when using ‘C-v’ and ‘M-v’ key bindings.
+
+     ‘ivy-height’ is 10 lines by default.
+
+
+File: ivy.info,  Node: Key bindings for single selection action then exit minibuffer,  Next: Key bindings for multiple selections and actions keep minibuffer open,  Prev: Key bindings for navigation,  Up: Minibuffer key bindings
+
+4.2.2 Key bindings for single selection, action, then exit minibuffer
+---------------------------------------------------------------------
+
+Ivy can offer several actions from which to choose which action to run.
+This "calling an action" operates on the selected candidate.  For
+example, when viewing a list of files, one action could open it for
+editing, one to view it, another to invoke a special function, and so
+on.  Custom actions can be added to this interface.  The precise action
+to call on the selected candidate can be delayed until after the
+narrowing is completed.  No need to exit the interface if unsure which
+action to run.  This delayed flexibility and customization of actions
+extends usability of lists in Emacs.
+
+‘C-m’ or ‘RET’ (‘ivy-done’)
+...........................
+
+     Calls the default action and then exits the minibuffer.
+
+‘M-o’ (‘ivy-dispatching-done’)
+..............................
+
+     Presents valid actions from which to choose.  When only one action
+     is available, there is no difference between ‘M-o’ and ‘C-m’.
+
+‘C-j’ (‘ivy-alt-done’)
+......................
+
+     When completing file names, selects the current directory candidate
+     and starts a new completion session there.  Otherwise, it is the
+     same as ‘ivy-done’.
+
+‘TAB’ (‘ivy-partial-or-done’)
+.............................
+
+     Attempts partial completion, extending current input as much as
+     possible.  ‘TAB TAB’ is the same as ‘C-j’ (‘ivy-alt-done’).
+
+     Example ERT test:
+
+          (should
+           (equal (ivy-with
+          	 '(progn
+          	   (ivy-read "Test: " '("can do" "can't, sorry" "other"))
+          	   ivy-text)
+          	 "c <tab>")
+          	"can"))
+
+‘C-M-j’ (‘ivy-immediate-done’)
+..............................
+
+     Exits with _the current input_ instead of _the current candidate_
+     (like other commands).
+
+     This is useful e.g.  when you call ‘find-file’ to create a new
+     file, but the desired name matches an existing file.  In that case,
+     using ‘C-j’ would select that existing file, which isn’t what you
+     want - use this command instead.
+
+‘C-'’ (‘ivy-avy’)
+.................
+
+     Uses avy to select one of the candidates on the current candidate
+     page.  This can often be faster than multiple ‘C-n’ or ‘C-p’
+     keystrokes followed by ‘C-m’.
+
+
+File: ivy.info,  Node: Key bindings for multiple selections and actions keep minibuffer open,  Next: Key bindings that alter the minibuffer input,  Prev: Key bindings for single selection action then exit minibuffer,  Up: Minibuffer key bindings
+
+4.2.3 Key bindings for multiple selections and actions, keep minibuffer open
+----------------------------------------------------------------------------
+
+For repeatedly applying multiple actions or acting on multiple
+candidates, Ivy does not close the minibuffer between commands.  It
+keeps the minibuffer open for applying subsequent actions.
+
+   Adding an extra meta key to the normal key chord invokes the special
+version of the regular commands that enables applying multiple actions.
+
+‘C-M-m’ (‘ivy-call’)
+....................
+
+     Is the non-exiting version of ‘C-m’ (‘ivy-done’).
+
+     Instead of closing the minibuffer, ‘C-M-m’ allows selecting another
+     candidate or another action.  For example, ‘C-M-m’ on functions
+     list invokes ‘describe-function’.  When combined with ‘C-n’,
+     function descriptions can be invoked quickly in succession.
+
+‘C-M-o’ (‘ivy-dispatching-call’)
+................................
+
+     Is the non-exiting version of ‘M-o’ (‘ivy-dispatching-done’).
+
+     For example, during the ‘counsel-rhythmbox’ completion, press
+     ‘C-M-o e’ to en-queue the selected candidate, followed by ‘C-n C-m’
+     to play the next candidate - the current action reverts to the
+     default one after ‘C-M-o’.
+
+‘C-M-n’ (‘ivy-next-line-and-call’)
+..................................
+
+     Combines ‘C-n’ and ‘C-M-m’.  Applies an action and moves to next
+     line.
+
+     Comes in handy when opening multiple files from
+     ‘counsel-find-file’, ‘counsel-git-grep’, ‘counsel-ag’,
+     ‘counsel-rg’, or ‘counsel-locate’ lists.  Just hold ‘C-M-n’ for
+     rapid-fire default action on each successive element of the list.
+
+‘C-M-p’ (‘ivy-previous-line-and-call’)
+......................................
+
+     Combines ‘C-p’ and ‘C-M-m’.
+
+     Similar to the above except it moves through the list in the other
+     direction.
+
+‘ivy-resume’
+............
+
+     Recalls the state of the completion session just before its last
+     exit.
+
+     Useful after an accidental ‘C-m’ (‘ivy-done’).
+
+
+File: ivy.info,  Node: Key bindings that alter the minibuffer input,  Next: Other key bindings,  Prev: Key bindings for multiple selections and actions keep minibuffer open,  Up: Minibuffer key bindings
+
+4.2.4 Key bindings that alter the minibuffer input
+--------------------------------------------------
+
+‘M-n’ (‘ivy-next-history-element’)
+..................................
+
+     Cycles forward through the Ivy command history.
+
+     Ivy updates an internal history list after each action.  When this
+     history list is empty, ‘M-n’ inserts symbol (or URL) at point into
+     the minibuffer.
+
+‘M-p’ (‘ivy-previous-history-element’)
+......................................
+
+     Cycles forward through the Ivy command history.
+
+‘M-i’ (‘ivy-insert-current’)
+............................
+
+     Inserts the current candidate into the minibuffer.
+
+     Useful for copying and renaming files, for example: ‘M-i’ to insert
+     the original file name string, edit it, and then ‘C-m’ to complete
+     the renaming.
+
+‘M-j’ (‘ivy-yank-word’)
+.......................
+
+     Inserts the sub-word at point into the minibuffer.
+
+     This is similar to ‘C-s C-w’ with ‘isearch’.  Ivy reserves ‘C-w’
+     for ‘kill-region’.  See also ‘ivy-yank-symbol’ and ‘ivy-yank-char’.
+
+‘S-SPC’ (‘ivy-restrict-to-matches’)
+...................................
+
+     Deletes the current input, and resets the candidates list to the
+     currently restricted matches.
+
+     This is how Ivy provides narrowing in successive tiers.
+
+‘C-r’ (‘ivy-reverse-i-search’)
+..............................
+
+     Starts a recursive completion session through the command’s
+     history.
+
+     This works just like ‘C-r’ at the bash command prompt, where the
+     completion candidates are the history items.  Upon completion, the
+     selected candidate string is inserted into the minibuffer.
+
+
+File: ivy.info,  Node: Other key bindings,  Next: Hydra in the minibuffer,  Prev: Key bindings that alter the minibuffer input,  Up: Minibuffer key bindings
+
+4.2.5 Other key bindings
+------------------------
+
+‘M-w’ (‘ivy-kill-ring-save’)
+............................
+
+     Copies selected candidates to the kill ring.
+
+     Copies the region if the region is active.
+
+
+File: ivy.info,  Node: Hydra in the minibuffer,  Next: Saving the current completion session to a buffer,  Prev: Other key bindings,  Up: Minibuffer key bindings
+
+4.2.6 Hydra in the minibuffer
+-----------------------------
+
+‘C-o’ (‘hydra-ivy/body’)
+........................
+
+     Invokes the hydra menu with short key bindings.
+
+   When Hydra is active, minibuffer editing is disabled and menus
+display short aliases:
+
+Short   Normal      Command name
+------------------------------------------------
+‘o’     ‘C-g’       ‘keyboard-escape-quit’
+‘j’     ‘C-n’       ‘ivy-next-line’
+‘k’     ‘C-p’       ‘ivy-previous-line’
+‘h’     ‘M-<’       ‘ivy-beginning-of-buffer’
+‘l’     ‘M->’       ‘ivy-end-of-buffer’
+‘d’     ‘C-m’       ‘ivy-done’
+‘f’     ‘C-j’       ‘ivy-alt-done’
+‘g’     ‘C-M-m’     ‘ivy-call’
+‘u’     ‘C-c C-o’   ‘ivy-occur’
+
+   Hydra reduces key strokes, for example: ‘C-n C-n C-n C-n’ is ‘C-o
+jjjj’ in Hydra.
+
+   Hydra menu offers these additional bindings:
+
+‘c’ (‘ivy-toggle-calling’)
+..........................
+
+     Toggle calling the action after each candidate change.  It modifies
+     ‘j’ to ‘jg’, ‘k’ to ‘kg’ etc.
+
+‘m’ (‘ivy-rotate-preferred-builders’)
+.....................................
+
+     Rotate the current regexp matcher.
+
+‘>’ (‘ivy-minibuffer-grow’)
+...........................
+
+     Increase ‘ivy-height’ for the current minibuffer.
+
+‘<’ (‘ivy-minibuffer-shrink’)
+.............................
+
+     Decrease ‘ivy-height’ for the current minibuffer.
+
+‘w’ (‘ivy-prev-action’)
+.......................
+
+     Select the previous action.
+
+‘s’ (‘ivy-next-action’)
+.......................
+
+     Select the next action.
+
+‘a’ (‘ivy-read-action’)
+.......................
+
+     Use a menu to select an action.
+
+‘C’ (‘ivy-toggle-case-fold’)
+............................
+
+     Toggle case folding (match both upper and lower case characters for
+     lower case input).
+
+
+File: ivy.info,  Node: Saving the current completion session to a buffer,  Prev: Hydra in the minibuffer,  Up: Minibuffer key bindings
+
+4.2.7 Saving the current completion session to a buffer
+-------------------------------------------------------
+
+‘C-c C-o’ (‘ivy-occur’)
+.......................
+
+     Saves the current candidates to a new buffer and exits completion.
+
+   The new buffer is read-only and has a few useful bindings defined.
+
+‘RET’ or ‘f’ (‘ivy-occur-press’)
+................................
+
+     Call the current action on the selected candidate.
+
+‘mouse-1’ (‘ivy-occur-click’)
+.............................
+
+     Call the current action on the selected candidate.
+
+‘j’ (‘next-line’)
+.................
+
+     Move to next line.
+
+‘k’ (‘previous-line’)
+.....................
+
+     Move to previous line.
+
+‘a’ (‘ivy-occur-read-action’)
+.............................
+
+     Read an action and make it current for this buffer.
+
+‘o’ (‘ivy-occur-dispatch’)
+..........................
+
+     Read an action and call it on the selected candidate.
+
+‘q’ (‘quit-window’)
+...................
+
+     Bury the current buffer.
+
+   Ivy has no limit on the number of active buffers like these.
+
+   Ivy takes care of naming buffers uniquely by constructing descriptive
+names.  For example: ‘*ivy-occur counsel-describe-variable "function$*’.
+
+
+File: ivy.info,  Node: Completion Styles,  Next: Customization,  Prev: Key bindings,  Up: Top
+
+5 Completion Styles
+*******************
+
+Ivy’s completion functions rely on a regex builder - a function that
+transforms a string input to a string regex.  All current candidates
+simply have to match this regex.  Each collection can be assigned its
+own regex builder by customizing ‘ivy-re-builders-alist’.
+
+   The keys of this alist are collection names, and the values are one
+of the following:
+   • ‘ivy--regex’
+   • ‘ivy--regex-plus’
+   • ‘ivy--regex-ignore-order’
+   • ‘ivy--regex-fuzzy’
+   • ‘regexp-quote’
+
+   A catch-all key, ‘t’, applies to all collections that don’t have
+their own key.
+
+   The default is:
+
+     (setq ivy-re-builders-alist
+           '((t . ivy--regex-plus)))
+
+   This example shows a custom regex builder assigned to file name
+completion:
+
+     (setq ivy-re-builders-alist
+           '((read-file-name-internal . ivy--regex-fuzzy)
+     	(t . ivy--regex-plus)))
+
+   Here, ‘read-file-name-internal’ is a function that is passed as the
+second argument to ‘completing-read’ for file name completion.
+
+   The regex builder resolves as follows (in order of priority):
+  1. ‘re-builder’ argument passed to ‘ivy-read’.
+  2. ‘collection’ argument passed to ‘ivy-read’ is a function and has an
+     entry on ‘ivy-re-builders-alist’.
+  3. ‘caller’ argument passed to ‘ivy-read’ has an entry on
+     ‘ivy-re-builders-alist’.
+  4. ‘this-command’ has an entry on ‘ivy-re-builders-alist’.
+  5. ‘t’ has an entry on ‘ivy-re-builders-alist’.
+  6. ‘ivy--regex’.
+
+* Menu:
+
+* ivy--regex-plus::
+* ivy--regex-ignore-order::
+* ivy--regex-fuzzy::
+
+
+File: ivy.info,  Node: ivy--regex-plus,  Next: ivy--regex-ignore-order,  Up: Completion Styles
+
+5.1 ivy–regex-plus
+==================
+
+‘ivy--regex-plus’ is Ivy’s default completion method.
+
+   ‘ivy--regex-plus’ matches by splitting the input by spaces and
+rebuilding it into a regex.
+
+   As the search string is typed in Ivy’s minibuffer, it is transformed
+into valid regex syntax.  If the string is ‘"for example"’, it is
+transformed into
+
+     "\\(for\\).*\\(example\\)"
+
+   which in regex terminology matches ‘"for"’ followed by a wild card
+and then ‘"example"’.  Note how Ivy uses the space character to build
+wild cards.  To match a literal white space, use an extra space.  So to
+match one space type two spaces, to match two spaces type three spaces,
+and so on.
+
+   As Ivy transforms typed characters into regex strings, it provides an
+intuitive feedback through font highlights.
+
+   Ivy supports regexp negation with ‘"!"’.  For example, ‘"define key !
+ivy quit"’ first selects everything matching ‘"define.*key"’, then
+removes everything matching ‘"ivy"’, and finally removes everything
+matching ‘"quit"’.  What remains is the final result set of the negation
+regexp.
+
+   Since Ivy treats minibuffer input as a regexp, the standard regexp
+identifiers work: ‘"^"’, ‘"$"’, ‘"\b"’ or ‘"[a-z]"’.  The exceptions are
+spaces, which translate to ‘".*"’, and ‘"!"’ that signal the beginning
+of a negation group.
+
+
+File: ivy.info,  Node: ivy--regex-ignore-order,  Next: ivy--regex-fuzzy,  Prev: ivy--regex-plus,  Up: Completion Styles
+
+5.2 ivy–regex-ignore-order
+==========================
+
+‘ivy--regex-ignore-order’ ignores the order of regexp tokens when
+searching for matching candidates.  For instance, the input ‘"for
+example"’ will match ‘"example test for"’.
+
+
+File: ivy.info,  Node: ivy--regex-fuzzy,  Prev: ivy--regex-ignore-order,  Up: Completion Styles
+
+5.3 ivy–regex-fuzzy
+===================
+
+‘ivy--regex-fuzzy’ splits each character with a wild card.  Searching
+for ‘"for"’ returns all ‘"f.*o.*r"’ matches, resulting in a large number
+of hits.  Yet some searches need these extra hits.  Ivy sorts such large
+lists using ‘flx’ package’s scoring mechanism, if it’s installed.
+
+   ‘C-o m’ toggles the current regexp builder.
+
+
+File: ivy.info,  Node: Customization,  Next: Commands,  Prev: Completion Styles,  Up: Top
+
+6 Customization
+***************
+
+* Menu:
+
+* Faces::
+* Defcustoms::
+* Actions::
+* Packages::
+
+
+File: ivy.info,  Node: Faces,  Next: Defcustoms,  Up: Customization
+
+6.1 Faces
+=========
+
+‘ivy-current-match’
+...................
+
+     Highlights the currently selected candidate.
+
+‘ivy-minibuffer-match-face-1’
+.............................
+
+     Highlights the background of the match.
+
+‘ivy-minibuffer-match-face-2’
+.............................
+
+     Highlights the first (modulo 3) matched group.
+
+‘ivy-minibuffer-match-face-3’
+.............................
+
+     Highlights the second (modulo 3) matched group.
+
+‘ivy-minibuffer-match-face-4’
+.............................
+
+     Highlights the third (modulo 3) matched group.
+
+‘ivy-confirm-face’
+..................
+
+     Highlights the "(confirm)" part of the prompt.
+
+     When ‘confirm-nonexistent-file-or-buffer’ set to ‘t’, then
+     confirming non-existent files in ‘ivy-mode’ requires an additional
+     ‘RET’.
+
+     The confirmation prompt will use this face.
+
+     For example:
+
+          (setq confirm-nonexistent-file-or-buffer t)
+
+     Then call ‘find-file’, enter "eldorado" and press ‘RET’ - the
+     prompt will be appended with "(confirm)".  Press ‘RET’ once more to
+     confirm, or any key to continue the completion.
+
+‘ivy-match-required-face’
+.........................
+
+     Highlights the "(match required)" part of the prompt.
+
+     When completions have to match available candidates and cannot take
+     random input, the "(match required)" prompt signals this
+     constraint.
+
+     For example, call ‘describe-variable’, enter "waldo" and press
+     ‘RET’ - "(match required)" is prompted.  Press any key for the
+     prompt to disappear.
+
+‘ivy-subdir’
+............
+
+     Highlights directories when completing file names.
+
+‘ivy-remote’
+............
+
+     Highlights remote files when completing file names.
+
+‘ivy-virtual’
+.............
+
+     Highlights virtual buffers when completing buffer names.
+
+     Virtual buffers correspond to bookmarks and recent files list,
+     ‘recentf’.
+
+     Enable virtual buffers with:
+
+          (setq ivy-use-virtual-buffers t)
+
+
+File: ivy.info,  Node: Defcustoms,  Next: Actions,  Prev: Faces,  Up: Customization
+
+6.2 Defcustoms
+==============
+
+ -- User Option: ivy-count-format
+     A string that specifies display of number of candidates and current
+     candidate, if one exists.
+
+     The number of matching candidates by default is shown as a right-
+     padded integer value.
+
+     To disable showing the number of candidates:
+
+          (setq ivy-count-format "")
+
+     To also display the current candidate:
+
+          (setq ivy-count-format "(%d/%d) ")
+
+     The ‘format’-style switches this variable uses are described in the
+     ‘format’ documentation.
+
+ -- User Option: ivy-display-style
+     Specifies highlighting candidates in the minibuffer.
+
+     The default setting is ‘'fancy’ in Emacs versions 24.4 or newer.
+
+     Set ‘ivy-display-style’ to ‘nil’ for a plain minibuffer.
+
+ -- User Option: ivy-on-del-error-function
+     Specifies what to do when ‘DEL’ (‘ivy-backward-delete-char’) fails.
+
+     This is usually the case when there is no text left to delete,
+     i.e., when ‘DEL’ is typed at the beginning of the minibuffer.
+
+     The default behavior is to quit the completion after ‘DEL’ – a
+     handy key to invoke after mistakenly triggering a completion.
+
+
+File: ivy.info,  Node: Actions,  Next: Packages,  Prev: Defcustoms,  Up: Customization
+
+6.3 Actions
+===========
+
+* Menu:
+
+* What are actions?::
+* How can different actions be called?::
+* How to modify the actions list?::
+* Example - add two actions to each command::
+* Example - define a new command with several actions::
+
+
+File: ivy.info,  Node: What are actions?,  Next: How can different actions be called?,  Up: Actions
+
+6.3.1 What are actions?
+-----------------------
+
+An action is a function that is called after you select a candidate
+during completion.  This function takes a single string argument, which
+is the selected candidate.
+
+Window context when calling an action
+.....................................
+
+     Currently, the action is executed in the minibuffer window context.
+     This means e.g.  that if you call ‘insert’ the text will be
+     inserted into the minibuffer.
+
+     If you want to execute the action in the initial window from which
+     the completion started, use the ‘with-ivy-window’ wrapper macro.
+
+          (defun ivy-insert-action (x)
+            (with-ivy-window
+              (insert x)))
+
+
+File: ivy.info,  Node: How can different actions be called?,  Next: How to modify the actions list?,  Prev: What are actions?,  Up: Actions
+
+6.3.2 How can different actions be called?
+------------------------------------------
+
+   • ‘C-m’ (‘ivy-done’) calls the current action.
+   • ‘M-o’ (‘ivy-dispatching-done’) presents available actions for
+     selection, calls it after selection, and then exits.
+   • ‘C-M-o’ (‘ivy-dispatching-call’) presents available actions for
+     selection, calls it after selection, and then does not exit.
+
+
+File: ivy.info,  Node: How to modify the actions list?,  Next: Example - add two actions to each command,  Prev: How can different actions be called?,  Up: Actions
+
+6.3.3 How to modify the actions list?
+-------------------------------------
+
+Currently, you can append any amount of your own actions to the default
+list of actions.  This can be done either for a specific command, or for
+all commands at once.
+
+   Usually, the command has only one default action.  The convention is
+to use single letters when selecting a command, and the letter ‘o’ is
+designated for the default command.  This way, ‘M-o o’ should be always
+equivalent to ‘C-m’.
+
+
+File: ivy.info,  Node: Example - add two actions to each command,  Next: Example - define a new command with several actions,  Prev: How to modify the actions list?,  Up: Actions
+
+6.3.4 Example - add two actions to each command
+-----------------------------------------------
+
+The first action inserts the current candidate into the Ivy window - the
+window from which ‘ivy-read’ was called.
+
+   The second action copies the current candidate to the kill ring.
+
+     (defun ivy-yank-action (x)
+       (kill-new x))
+
+     (defun ivy-copy-to-buffer-action (x)
+       (with-ivy-window
+         (insert x)))
+
+     (ivy-set-actions
+      t
+      '(("i" ivy-copy-to-buffer-action "insert")
+        ("y" ivy-yank-action "yank")))
+
+   Then in any completion session, ‘M-o y’ invokes ‘ivy-yank-action’,
+and ‘M-o i’ invokes ‘ivy-copy-to-buffer-action’.
+
+* Menu:
+
+* How to undo adding the two actions::
+* How to add actions to a specific command::
+
+
+File: ivy.info,  Node: How to undo adding the two actions,  Next: How to add actions to a specific command,  Up: Example - add two actions to each command
+
+6.3.4.1 How to undo adding the two actions
+..........................................
+
+Since ‘ivy-set-actions’ modifies the internal dictionary with new data,
+set the extra actions list to ‘nil’ by assigning ‘nil’ value to the ‘t’
+key as follows:
+
+     (ivy-set-actions t nil)
+
+
+File: ivy.info,  Node: How to add actions to a specific command,  Prev: How to undo adding the two actions,  Up: Example - add two actions to each command
+
+6.3.4.2 How to add actions to a specific command
+................................................
+
+Use the command name as the key:
+
+     (ivy-set-actions
+      'swiper
+      '(("i" ivy-copy-to-buffer-action "insert")
+        ("y" ivy-yank-action "yank")))
+
+
+File: ivy.info,  Node: Example - define a new command with several actions,  Prev: Example - add two actions to each command,  Up: Actions
+
+6.3.5 Example - define a new command with several actions
+---------------------------------------------------------
+
+     (defun my-action-1 (x)
+       (message "action-1: %s" x))
+
+     (defun my-action-2 (x)
+       (message "action-2: %s" x))
+
+     (defun my-action-3 (x)
+       (message "action-3: %s" x))
+
+     (defun my-command-with-3-actions ()
+       (interactive)
+       (ivy-read "test: " '("foo" "bar" "baz")
+     	    :action '(1
+     		      ("o" my-action-1 "action 1")
+     		      ("j" my-action-2 "action 2")
+     		      ("k" my-action-3 "action 3"))))
+
+   The number 1 above is the index of the default action.  Each action
+has its own string description for easy selection.
+
+* Menu:
+
+* Test the above function with ivy-occur::
+
+
+File: ivy.info,  Node: Test the above function with ivy-occur,  Up: Example - define a new command with several actions
+
+6.3.5.1 Test the above function with ‘ivy-occur’
+................................................
+
+To examine each action with each candidate in a key-efficient way, try:
+
+   • Call ‘my-command-with-3-actions’
+   • Press ‘C-c C-o’ to close the completion window and move to an
+     ivy-occur buffer
+   • Press ‘kkk’ to move to the first candidate, since the point is most
+     likely at the end of the buffer
+   • Press ‘oo’ to call the first action
+   • Press ‘oj’ and ‘ok’ to call the second and the third actions
+   • Press ‘j’ to move to the next candidate
+   • Press ‘oo’, ‘oj’, ‘ok’
+   • Press ‘j’ to move to the next candidate
+   • and so on...
+
+
+File: ivy.info,  Node: Packages,  Prev: Actions,  Up: Customization
+
+6.4 Packages
+============
+
+‘org-mode’
+..........
+
+     ‘org-mode’ versions 8.3.3 or later obey ‘completing-read-function’
+     (which ‘ivy-mode’ sets).  Try refiling headings with similar names
+     to appreciate ‘ivy-mode’.
+
+‘magit’
+.......
+
+     Magit requires this setting for ivy completion:
+
+          (setq magit-completing-read-function 'ivy-completing-read)
+
+‘find-file-in-project’
+......................
+
+     It uses ivy by default if Ivy is installed.
+
+‘projectile’
+............
+
+     Projectile requires this setting for ivy completion:
+
+          (setq projectile-completion-system 'ivy)
+
+‘helm-make’
+...........
+
+     Helm-make requires this setting for ivy completion.
+
+          (setq helm-make-completion-method 'ivy)
+
+
+File: ivy.info,  Node: Commands,  Next: API,  Prev: Customization,  Up: Top
+
+7 Commands
+**********
+
+* Menu:
+
+* File Name Completion::
+* Buffer Name Completion::
+* Counsel commands::
+
+
+File: ivy.info,  Node: File Name Completion,  Next: Buffer Name Completion,  Up: Commands
+
+7.1 File Name Completion
+========================
+
+Since file name completion is ubiquitous, Ivy provides extra bindings
+that work here:
+
+‘C-j’ (‘ivy-alt-done’)
+......................
+
+     On a directory, restarts completion from that directory.
+
+     On a file or ‘./’, exit completion with the selected candidate.
+
+‘DEL’ (‘ivy-backward-delete-char’)
+..................................
+
+     Restart the completion in the parent directory if current input is
+     empty.
+
+‘//’ (‘self-insert-command’)
+............................
+
+     Switch to the root directory.
+
+‘~’ (‘self-insert-command’)
+...........................
+
+     Switch to the home directory.
+
+‘/’ (‘self-insert-command’)
+...........................
+
+     If the current input matches an existing directory name exactly,
+     switch the completion to that directory.
+
+‘M-r’ (‘ivy-toggle-regexp-quote’)
+.................................
+
+     Toggle between input as regexp or not.
+
+     Switch to matching literally since file names include ‘.’, which is
+     for matching any char in regexp mode.
+ -- User Option: ivy-extra-directories
+     Decide if you want to see ‘../’ and ‘./’ during file name
+     completion.
+
+     Reason to remove: ‘../’ is the same as ‘DEL’.
+
+     Reason not to remove: navigate anywhere with only ‘C-n’, ‘C-p’ and
+     ‘C-j’.
+
+     Likewise, ‘./’ can be removed.
+
+History
+.......
+
+     File history works the same with ‘M-p’, ‘M-n’, and ‘C-r’, but uses
+     a custom code for file name completion that cycles through files
+     previously opened.  It also works with TRAMP files.
+
+* Menu:
+
+* Using TRAMP::
+
+
+File: ivy.info,  Node: Using TRAMP,  Up: File Name Completion
+
+7.1.1 Using TRAMP
+-----------------
+
+From any directory, with the empty input, inputting ‘/ssh:’ and pressing
+‘C-j’ (or ‘RET’, which is the same thing) completes for host and user
+names.
+
+   For ‘/ssh:user@’ input, completes the domain name.
+
+   ‘C-i’ works in a similar way to the default completion.
+
+   You can also get sudo access for the current directory by inputting
+‘/sudo::’ ‘RET’.  Using ‘/sudo:’ (i.e.  single colon instead of double)
+will result in a completion session for the desired user.
+
+   Multi-hopping is possible, although a bit complex.
+
+Example : connect to a remote host ‘cloud’ and open a file with ‘sudo’ there
+............................................................................
+
+        • ‘C-x C-f’ ‘/ssh:cloud|sudo:root:/’.
+
+
+File: ivy.info,  Node: Buffer Name Completion,  Next: Counsel commands,  Prev: File Name Completion,  Up: Commands
+
+7.2 Buffer Name Completion
+==========================
+
+ -- User Option: ivy-use-virtual-buffers
+     When non-nil, add ‘recentf-mode’ and bookmarks to
+     ‘ivy-switch-buffer’ completion candidates.
+
+     Adding this to Emacs init file:
+
+          (setq ivy-use-virtual-buffers t)
+     will add additional virtual buffers to the buffers list for recent
+     files.  Selecting such virtual buffers, which are highlighted with
+     ‘ivy-virtual’ face, will open the corresponding file.
+
+
+File: ivy.info,  Node: Counsel commands,  Prev: Buffer Name Completion,  Up: Commands
+
+7.3 Counsel commands
+====================
+
+The main advantages of ‘counsel-’ functions over their basic equivalents
+in ‘ivy-mode’ are:
+
+  1. Multi-actions and non-exiting actions work.
+  2. ‘ivy-resume’ can resume the last completion session.
+  3. Customize ‘ivy-set-actions’, ‘ivy-re-builders-alist’.
+  4. Customize individual keymaps, such as ‘counsel-describe-map’,
+     ‘counsel-git-grep-map’, or ‘counsel-find-file-map’, instead of
+     customizing ‘ivy-minibuffer-map’ that applies to all completion
+     sessions.
+
+
+File: ivy.info,  Node: API,  Next: Variable Index,  Prev: Commands,  Up: Top
+
+8 API
+*****
+
+The main (and only) entry point is the ‘ivy-read’ function.  It takes
+two required arguments and many optional arguments that can be passed by
+a key.  The optional ‘:action’ argument is highly recommended for
+features such as multi-actions, non-exiting actions, ‘ivy-occur’ and
+‘ivy-resume’.
+
+* Menu:
+
+* Required arguments for ivy-read::
+* Optional arguments for ivy-read::
+* Example - counsel-describe-function::
+* Example - counsel-locate::
+* Example - ivy-read-with-extra-properties::
+
+
+File: ivy.info,  Node: Required arguments for ivy-read,  Next: Optional arguments for ivy-read,  Up: API
+
+8.1 Required arguments for ‘ivy-read’
+=====================================
+
+‘prompt’
+........
+
+     A format string normally ending in a colon and a space.
+
+     ‘%d’ anywhere in the string is replaced by the current number of
+     matching candidates.  To use a literal ‘%’ character, escape it as
+     ‘%%’.  See also ‘ivy-count-format’.
+
+‘collection’
+............
+
+     Either a list of strings, a function, an alist or a hash table.
+
+     If a function, then it has to be compatible with ‘all-completions’.
+
+
+File: ivy.info,  Node: Optional arguments for ivy-read,  Next: Example - counsel-describe-function,  Prev: Required arguments for ivy-read,  Up: API
+
+8.2 Optional arguments for ‘ivy-read’
+=====================================
+
+‘predicate’
+...........
+
+     Is a function to filter the initial collection.  It has to be
+     compatible with ‘all-completions’.  Tip: most of the time, it’s
+     simpler to just apply this filter to the ‘collection’ argument
+     itself, e.g.  ‘(cl-remove-if-not predicate collection)’.
+
+‘require-match’
+...............
+
+     When set to a non-nil value, input must match one of the
+     candidates.  Custom input is not accepted.
+
+‘initial-input’
+...............
+
+     This string argument is included for compatibility with
+     ‘completing-read’, which inserts it into the minibuffer.
+
+     It’s recommended to use the ‘preselect’ argument instead of this.
+
+‘history’
+.........
+
+     Name of the symbol to store history.  See ‘completing-read’.
+
+‘preselect’
+...........
+
+     When set to a string value, select the first candidate matching
+     this value.
+
+     When set to an integer value, select the candidate with that index
+     value.
+
+     Every time the input becomes empty, the item corresponding to to
+     ‘preselect’ is selected.
+
+‘keymap’
+........
+
+     A keymap to be composed with ‘ivy-minibuffer-map’.  This keymap has
+     priority over ‘ivy-minibuffer-map’ and can be modified at any later
+     stage.
+
+‘update-fn’
+...........
+
+     Is the function called each time the current candidate changes.
+     This function takes no arguments and is called in the minibuffer’s
+     ‘post-command-hook’.  See ‘swiper’ for an example usage.
+
+‘sort’
+......
+
+     When non-nil, use ‘ivy-sort-functions-alist’ to sort the collection
+     as long as the collection is not larger than ‘ivy-sort-max-size’.
+
+‘action’
+........
+
+     Is the function to call after selection.  It takes a string
+     argument.
+
+‘unwind’
+........
+
+     Is the function to call before exiting completion.  It takes no
+     arguments.  This function is called even if the completion is
+     interrupted with ‘C-g’.  See ‘swiper’ for an example usage.
+
+‘re-builder’
+............
+
+     Is a function that takes a string and returns a valid regex.  See
+     ‘Completion Styles’ for details.
+
+‘matcher’
+.........
+
+     Is a function that takes a regex string and a list of strings and
+     returns a list of strings matching the regex.  Any ordinary Emacs
+     matching function will suffice, yet finely tuned matching functions
+     can be used.  See ‘counsel-find-file’ for an example usage.
+
+‘dynamic-collection’
+....................
+
+     When non-nil, ‘collection’ will be used to dynamically generate the
+     candidates each time the input changes, instead of being used once
+     statically with ‘all-completions’ to generate a list of strings.
+     See ‘counsel-locate’ for an example usage.
+
+‘caller’
+........
+
+     Is a symbol that uniquely identifies the function that called
+     ‘ivy-read’, which may be useful for further customizations.
+
+
+File: ivy.info,  Node: Example - counsel-describe-function,  Next: Example - counsel-locate,  Prev: Optional arguments for ivy-read,  Up: API
+
+8.3 Example - ‘counsel-describe-function’
+=========================================
+
+This is a typical example of a function with a non-async collection,
+which is a collection where all the strings in the collection are known
+prior to any input from the user.
+
+   Only the first two arguments (along with ‘action’) are essential -
+the rest of the arguments are for fine-tuning, and could be omitted.
+
+   The ‘action’ argument could also be omitted - but then ‘ivy-read’
+would do nothing except returning the string result, which you could
+later use yourself.  However, it’s recommended that you use the ‘action’
+argument.
+
+     (defun counsel-describe-function ()
+       "Forward to `describe-function'."
+       (interactive)
+       (ivy-read "Describe function: "
+     	    (let (cands)
+     	      (mapatoms
+     	       (lambda (x)
+     		 (when (fboundp x)
+     		   (push (symbol-name x) cands))))
+     	      cands)
+     	    :keymap counsel-describe-map
+     	    :preselect (counsel-symbol-at-point)
+     	    :history 'counsel-describe-symbol-history
+     	    :require-match t
+     	    :sort t
+     	    :action (lambda (x)
+     		      (describe-function
+     		       (intern x)))
+     	    :caller 'counsel-describe-function))
+
+   Here are the interesting features of the above function, in the order
+that they appear:
+
+   • The ‘prompt’ argument is a simple string ending in ": ".
+   • The ‘collection’ argument evaluates to a (large) list of strings.
+   • The ‘keymap’ argument is for a custom keymap to supplement
+     ‘ivy-minibuffer-map’.
+   • The ‘preselect’ is provided by ‘counsel-symbol-at-point’, which
+     returns a symbol near the point.  Ivy then selects the first
+     candidate from the collection that matches this symbol.  To select
+     this pre-selected candidate, a ‘RET’ will suffice.  No further user
+     input is necessary.
+   • The ‘history’ argument is for keeping the history of this command
+     separate from the common history in ‘ivy-history’.
+   • The ‘require-match’ is set to ‘t’ since it doesn’t make sense to
+     call ‘describe-function’ on an un-interned symbol.
+   • The ‘sort’ argument is set to ‘t’ so choosing between similar
+     candidates becomes easier.  Sometimes, the collection size will
+     exceed ‘ivy-sort-max-size’, which is 30000 by default.  In that
+     case the sorting will not happen to avoid delays.
+
+     Adjust this variable to choose between sorting time and completion
+     start-up time.
+   • The ‘action’ argument calls ‘describe-function’ on the interned
+     selected candidate.
+   • The ‘caller’ argument identifies this completion session.  This is
+     important, since with the collection being a list of strings and
+     not a function name, the only other way for ‘ivy-read’ to identify
+     "who’s calling" and to apply the appropriate customizations is to
+     examine ‘this-command’.  But ‘this-command’ would be modified if
+     another command called ‘counsel-describe-function’.
+
+
+File: ivy.info,  Node: Example - counsel-locate,  Next: Example - ivy-read-with-extra-properties,  Prev: Example - counsel-describe-function,  Up: API
+
+8.4 Example - ‘counsel-locate’
+==============================
+
+This is a typical example of a function with an async collection.  Since
+the collection function cannot pre-compute all the locatable files in
+memory within reasonable limits (time or memory), it relies on user
+input to filter the universe of possible candidates to a manageable size
+while also continuing to search asynchronously for possible candidates.
+Both the filtering and searching continues with each character change of
+the input with rapid updates to the collection presented without idle
+waiting times.  This live update will continue as long as there are
+likely candidates.  Eventually updates to the minibuffer will stop after
+user input, filtering, and searching have exhausted looking for possible
+candidates.
+
+   Async collections suit long-running shell commands, such as ‘locate’.
+With each new input, a new process starts while the old process is
+killed.  The collection is refreshed anew with each new process.
+Meanwhile the user can provide more input characters (for further
+narrowing) or select a candidate from the visible collection.
+
+     (defun counsel-locate-function (str)
+       (or
+        (counsel-more-chars)
+        (progn
+          (counsel--async-command
+           (format "locate %s '%s'"
+     	      (mapconcat #'identity counsel-locate-options " ")
+     	      (counsel-unquote-regex-parens
+     	       (ivy--regex str))))
+          '("" "working..."))))
+
+     ;;;###autoload
+     (defun counsel-locate (&optional initial-input)
+       "Call the \"locate\" shell command.
+     INITIAL-INPUT can be given as the initial minibuffer input."
+       (interactive)
+       (ivy-read "Locate: " #'counsel-locate-function
+     	    :initial-input initial-input
+     	    :dynamic-collection t
+     	    :history 'counsel-locate-history
+     	    :action (lambda (file)
+     		      (with-ivy-window
+     			(when file
+     			  (find-file file))))
+     	    :unwind #'counsel-delete-process
+     	    :caller 'counsel-locate))
+
+   Here are the interesting features of the above functions, in the
+order that they appear:
+
+   • ‘counsel-locate-function’ takes a string argument and returns a
+     list of strings.  Note that it’s not compatible with
+     ‘all-completions’, but since we’re not using that here, might as
+     well use one argument instead of three.
+   • ‘counsel-more-chars’ is a simple function that returns e.g.  ‘'("2
+     chars more")’ asking the user for more input.
+   • ‘counsel--async-command’ is a very easy API simplification that
+     takes a single string argument suitable for
+     ‘shell-command-to-string’.  So you could prototype your function as
+     non-async using ‘shell-command-to-string’ and ‘split-string’ to
+     produce a collection, then decide that you want async and simply
+     swap in ‘counsel--async-command’.
+   • ‘counsel-locate’ is an interactive function with an optional
+     ‘initial-input’.
+   • ‘#'counsel-locate-function’ is passed as the ‘collection’ argument.
+   • ‘dynamic-collection’ is set to t, since this is an async
+     collection.
+   • ‘action’ argument uses ‘with-ivy-window’ wrapper, since we want to
+     open the selected file in the same window from which
+     ‘counsel-locate’ was called.
+   • ‘unwind’ argument is set to ‘#'counsel-delete-process’: when we
+     press ‘C-g’ we want to kill the running process created by
+     ‘counsel--async-command’.
+   • ‘caller’ argument identifies this command for easier customization.
+
+
+File: ivy.info,  Node: Example - ivy-read-with-extra-properties,  Prev: Example - counsel-locate,  Up: API
+
+8.5 Example - ‘ivy-read-with-extra-properties’
+==============================================
+
+This is another example to show how to associate additional values to
+each displayed strings.
+
+     (defun find-candidates-function (str pred _)
+       (let ((props '(1 2))
+     	(strs '("foo" "foo2")))
+         (cl-mapcar (lambda (s p) (propertize s 'property p))
+     	       strs
+     	       props)))
+
+     (defun find-candidates ()
+       (interactive)
+       (ivy-read "Find symbols: "
+     	    #'find-candidates-function
+     	    :action (lambda (x)
+     		      (message "Value: %s" (get-text-property 0 'property x)
+     		       ))))
+
+   Here are the interesting features of the above function:
+
+   • ‘find-candidates-function’ builds up a list of strings and
+     associates "foo" with the value 1 and "foo2" with 2.
+   • ‘find-candidates’ is an interactive function.
+   • ‘#'find-candidates’ is passed as the ‘collection’ argument.
+   • ‘action’ gets passed the selected string with the associated value.
+     It then retrieves that value and displays it.
+
+
+File: ivy.info,  Node: Variable Index,  Next: Keystroke Index,  Prev: API,  Up: Top
+
+Variable Index
+**************
+
+
+* Menu:
+
+* ivy-alt-done:                          Key bindings for single selection action then exit minibuffer.
+                                                               (line 30)
+* ivy-alt-done <1>:                      File Name Completion. (line 12)
+* ivy-avy:                               Key bindings for single selection action then exit minibuffer.
+                                                               (line 64)
+* ivy-backward-delete-char:              File Name Completion. (line 19)
+* ivy-call:                              Key bindings for multiple selections and actions keep minibuffer open.
+                                                               (line 16)
+* ivy-confirm-face:                      Faces.                (line 34)
+* ivy-count-format:                      Defcustoms.           (line  6)
+* ivy-current-match:                     Faces.                (line  9)
+* ivy-dispatching-call:                  Key bindings for multiple selections and actions keep minibuffer open.
+                                                               (line 26)
+* ivy-dispatching-done:                  Key bindings for single selection action then exit minibuffer.
+                                                               (line 24)
+* ivy-display-style:                     Defcustoms.           (line 24)
+* ivy-done:                              Key bindings for single selection action then exit minibuffer.
+                                                               (line 19)
+* ivy-extra-directories:                 File Name Completion. (line 45)
+* ivy-height:                            Key bindings for navigation.
+                                                               (line 21)
+* ivy-immediate-done:                    Key bindings for single selection action then exit minibuffer.
+                                                               (line 53)
+* ivy-insert-current:                    Key bindings that alter the minibuffer input.
+                                                               (line 23)
+* ivy-kill-ring-save:                    Other key bindings.   (line  9)
+* ivy-match-required-face:               Faces.                (line 53)
+* ivy-minibuffer-grow:                   Hydra in the minibuffer.
+                                                               (line 45)
+* ivy-minibuffer-map:                    Minibuffer key bindings.
+                                                               (line  6)
+* ivy-minibuffer-match-face-1:           Faces.                (line 14)
+* ivy-minibuffer-match-face-2:           Faces.                (line 19)
+* ivy-minibuffer-match-face-3:           Faces.                (line 24)
+* ivy-minibuffer-match-face-4:           Faces.                (line 29)
+* ivy-minibuffer-shrink:                 Hydra in the minibuffer.
+                                                               (line 50)
+* ivy-next-action:                       Hydra in the minibuffer.
+                                                               (line 60)
+* ivy-next-history-element:              Key bindings that alter the minibuffer input.
+                                                               (line  9)
+* ivy-next-line-and-call:                Key bindings for multiple selections and actions keep minibuffer open.
+                                                               (line 36)
+* ivy-occur:                             Saving the current completion session to a buffer.
+                                                               (line  9)
+* ivy-occur-click:                       Saving the current completion session to a buffer.
+                                                               (line 21)
+* ivy-occur-dispatch:                    Saving the current completion session to a buffer.
+                                                               (line 41)
+* ivy-occur-press:                       Saving the current completion session to a buffer.
+                                                               (line 16)
+* ivy-occur-read-action:                 Saving the current completion session to a buffer.
+                                                               (line 36)
+* ivy-on-del-error-function:             Defcustoms.           (line 31)
+* ivy-partial-or-done:                   Key bindings for single selection action then exit minibuffer.
+                                                               (line 37)
+* ivy-prev-action:                       Hydra in the minibuffer.
+                                                               (line 55)
+* ivy-previous-history-element:          Key bindings that alter the minibuffer input.
+                                                               (line 18)
+* ivy-previous-line-and-call:            Key bindings for multiple selections and actions keep minibuffer open.
+                                                               (line 47)
+* ivy-read-action:                       Hydra in the minibuffer.
+                                                               (line 65)
+* ivy-remote:                            Faces.                (line 71)
+* ivy-restrict-to-matches:               Key bindings that alter the minibuffer input.
+                                                               (line 40)
+* ivy-resume:                            Key bindings for multiple selections and actions keep minibuffer open.
+                                                               (line 55)
+* ivy-reverse-i-search:                  Key bindings that alter the minibuffer input.
+                                                               (line 48)
+* ivy-rotate-preferred-builders:         Hydra in the minibuffer.
+                                                               (line 40)
+* ivy-subdir:                            Faces.                (line 66)
+* ivy-toggle-calling:                    Hydra in the minibuffer.
+                                                               (line 34)
+* ivy-toggle-case-fold:                  Hydra in the minibuffer.
+                                                               (line 70)
+* ivy-toggle-regexp-quote:               File Name Completion. (line 41)
+* ivy-use-virtual-buffers:               Buffer Name Completion.
+                                                               (line  6)
+* ivy-virtual:                           Faces.                (line 76)
+* ivy-wrap:                              Key bindings for navigation.
+                                                               (line 14)
+* ivy-yank-word:                         Key bindings that alter the minibuffer input.
+                                                               (line 32)
+
+
+File: ivy.info,  Node: Keystroke Index,  Prev: Variable Index,  Up: Top
+
+Keystroke Index
+***************
+
+
+* Menu:
+
+* /:                                     File Name Completion. (line 35)
+* //:                                    File Name Completion. (line 25)
+* <:                                     Hydra in the minibuffer.
+                                                               (line 50)
+* >:                                     Hydra in the minibuffer.
+                                                               (line 45)
+* ~:                                     File Name Completion. (line 30)
+* a:                                     Hydra in the minibuffer.
+                                                               (line 65)
+* a <1>:                                 Saving the current completion session to a buffer.
+                                                               (line 36)
+* c:                                     Hydra in the minibuffer.
+                                                               (line 34)
+* C:                                     Hydra in the minibuffer.
+                                                               (line 70)
+* C-':                                   Key bindings for single selection action then exit minibuffer.
+                                                               (line 64)
+* C-c C-o:                               Saving the current completion session to a buffer.
+                                                               (line  9)
+* C-j:                                   Key bindings for single selection action then exit minibuffer.
+                                                               (line 30)
+* C-j <1>:                               File Name Completion. (line 12)
+* C-m:                                   Key bindings for single selection action then exit minibuffer.
+                                                               (line 19)
+* C-M-j:                                 Key bindings for single selection action then exit minibuffer.
+                                                               (line 53)
+* C-M-m:                                 Key bindings for multiple selections and actions keep minibuffer open.
+                                                               (line 16)
+* C-M-n:                                 Key bindings for multiple selections and actions keep minibuffer open.
+                                                               (line 36)
+* C-M-o:                                 Key bindings for multiple selections and actions keep minibuffer open.
+                                                               (line 26)
+* C-M-p:                                 Key bindings for multiple selections and actions keep minibuffer open.
+                                                               (line 47)
+* C-o:                                   Hydra in the minibuffer.
+                                                               (line  9)
+* C-r:                                   Key bindings that alter the minibuffer input.
+                                                               (line 48)
+* DEL:                                   File Name Completion. (line 19)
+* f:                                     Saving the current completion session to a buffer.
+                                                               (line 16)
+* j:                                     Saving the current completion session to a buffer.
+                                                               (line 26)
+* k:                                     Saving the current completion session to a buffer.
+                                                               (line 31)
+* m:                                     Hydra in the minibuffer.
+                                                               (line 40)
+* M-i:                                   Key bindings that alter the minibuffer input.
+                                                               (line 23)
+* M-j:                                   Key bindings that alter the minibuffer input.
+                                                               (line 32)
+* M-n:                                   Key bindings that alter the minibuffer input.
+                                                               (line  9)
+* M-o:                                   Key bindings for single selection action then exit minibuffer.
+                                                               (line 24)
+* M-p:                                   Key bindings that alter the minibuffer input.
+                                                               (line 18)
+* M-r:                                   File Name Completion. (line 41)
+* M-w:                                   Other key bindings.   (line  9)
+* mouse-1:                               Saving the current completion session to a buffer.
+                                                               (line 21)
+* o:                                     Saving the current completion session to a buffer.
+                                                               (line 41)
+* q:                                     Saving the current completion session to a buffer.
+                                                               (line 46)
+* RET:                                   Key bindings for single selection action then exit minibuffer.
+                                                               (line 19)
+* RET <1>:                               Saving the current completion session to a buffer.
+                                                               (line 16)
+* s:                                     Hydra in the minibuffer.
+                                                               (line 60)
+* S-SPC:                                 Key bindings that alter the minibuffer input.
+                                                               (line 40)
+* TAB:                                   Key bindings for single selection action then exit minibuffer.
+                                                               (line 37)
+* w:                                     Hydra in the minibuffer.
+                                                               (line 55)
+
+
+
+Tag Table:
+Node: Top1360
+Node: Introduction3273
+Node: Installation5784
+Node: Installing from Emacs Package Manager6234
+Node: Installing from the Git repository7347
+Node: Getting started8167
+Node: Basic customization8474
+Node: Key bindings9069
+Node: Global key bindings9261
+Node: Minibuffer key bindings10579
+Node: Key bindings for navigation11813
+Node: Key bindings for single selection action then exit minibuffer13020
+Node: Key bindings for multiple selections and actions keep minibuffer open15667
+Node: Key bindings that alter the minibuffer input18059
+Node: Other key bindings20004
+Node: Hydra in the minibuffer20382
+Node: Saving the current completion session to a buffer22485
+Node: Completion Styles23897
+Node: ivy--regex-plus25648
+Node: ivy--regex-ignore-order27134
+Node: ivy--regex-fuzzy27502
+Node: Customization27999
+Node: Faces28185
+Node: Defcustoms30312
+Node: Actions31606
+Node: What are actions?31932
+Node: How can different actions be called?32750
+Node: How to modify the actions list?33321
+Node: Example - add two actions to each command33981
+Node: How to undo adding the two actions34940
+Node: How to add actions to a specific command35392
+Node: Example - define a new command with several actions35808
+Node: Test the above function with ivy-occur36696
+Node: Packages37538
+Node: Commands38381
+Node: File Name Completion38566
+Node: Using TRAMP40362
+Node: Buffer Name Completion41239
+Node: Counsel commands41854
+Node: API42501
+Node: Required arguments for ivy-read43099
+Node: Optional arguments for ivy-read43752
+Node: Example - counsel-describe-function46968
+Node: Example - counsel-locate50221
+Node: Example - ivy-read-with-extra-properties53985
+Node: Variable Index55193
+Node: Keystroke Index62094
+
+End Tag Table
+
+
+Local Variables:
+coding: utf-8
+End:
diff --git a/configs/shared/emacs/.emacs.d/elpa/js2-mode-20180627.744/js2-imenu-extras.el b/configs/shared/emacs/.emacs.d/elpa/js2-mode-20180627.744/js2-imenu-extras.el
new file mode 100644
index 0000000000..dfdedc8ee0
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/js2-mode-20180627.744/js2-imenu-extras.el
@@ -0,0 +1,349 @@
+;;; js2-imenu-extras.el --- Imenu support for additional constructs
+
+;; Copyright (C) 2012-2014  Free Software Foundation, Inc.
+
+;; Author:    Dmitry Gutov <dgutov@yandex.ru>
+;; Keywords:  languages, javascript, imenu
+
+;; 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:
+
+;; This package adds Imenu support for additional framework constructs and
+;; structural patterns to `js2-mode'.
+
+;; Usage:
+
+;; (add-hook 'js2-mode-hook 'js2-imenu-extras-mode)
+
+;; To customize how it works:
+;;   M-x customize-group RET js2-imenu RET
+
+(eval-when-compile
+  (require 'cl))
+
+(require 'js2-mode)
+
+(defvar js2-imenu-extension-styles
+  `((:framework jquery
+     :call-re   "\\_<\\(?:jQuery\\|\\$\\|_\\)\\.extend\\s-*("
+     :recorder  js2-imenu-record-jquery-extend)
+
+    (:framework jquery-ui
+     :call-re   "^\\s-*\\(?:jQuery\\|\\$\\)\\.widget\\s-*("
+     :recorder  js2-imenu-record-string-declare)
+
+    (:framework dojo
+     :call-re   "^\\s-*dojo.declare\\s-*("
+     :recorder  js2-imenu-record-string-declare)
+
+    (:framework backbone
+     :call-re   ,(concat "\\_<" js2-mode-identifier-re "\\.extend\\s-*(")
+     :recorder  js2-imenu-record-backbone-extend)
+
+    (:framework enyo
+     :call-re   "\\_<enyo\\.kind\\s-*("
+     :recorder  js2-imenu-record-enyo-kind)
+
+    (:framework react
+     :call-re "\\_<React\\.createClass\\s-*("
+     :recorder js2-imenu-record-react-class)
+
+    (:framework sencha
+     :call-re "^\\s-*Ext\\.define\\s-*("
+     :recorder js2-imenu-record-sencha-class))
+  "List of JavaScript class definition or extension styles.
+
+:framework is a valid value in `js2-imenu-enabled-frameworks'.
+
+:call-re is a regular expression that has no capturing groups.
+
+:recorder is a function name that will be called when the regular
+expression matches some text in the buffer.  When it's called, point will be
+at the end of the match.  The function must keep the point position.")
+
+(defconst js2-imenu-available-frameworks
+  (mapcar (lambda (style) (plist-get style :framework)) js2-imenu-extension-styles)
+  "List of available JavaScript framework symbols.")
+
+(defcustom js2-imenu-enabled-frameworks js2-imenu-available-frameworks
+  "Frameworks to be recognized by `js2-mode'."
+  :type (cons 'set (mapcar (lambda (x) (list 'const x))
+                           js2-imenu-available-frameworks))
+  :group 'js2-imenu)
+
+(defcustom js2-imenu-show-other-functions t
+  "Non-nil to show functions not recognized by other mechanisms,
+in a shared namespace."
+  :type 'boolean
+  :group 'js2-imenu)
+
+(defcustom js2-imenu-other-functions-ns "?"
+  "Namespace name to use for other functions."
+  :type 'string
+  :group 'js2-imenu)
+
+(defcustom js2-imenu-show-module-pattern t
+  "Non-nil to recognize the module pattern:
+
+var foobs = (function(a) {
+  return {fib: function() {}, fub: function() {}};
+})(b);
+
+We record the returned hash as belonging to the named module, and
+prefix any functions defined inside the IIFE with the module name."
+  :type 'boolean
+  :group 'js2-imenu)
+
+(defcustom js2-imenu-split-string-identifiers t
+  "When non-nil, split string identifiers on dots.
+Currently used for jQuery widgets, Dojo and Enyo declarations."
+  :type 'boolean
+  :group 'js2-imenu)
+
+;;;###autoload
+(defun js2-imenu-extras-setup ()
+  (when js2-imenu-enabled-frameworks
+    (add-hook 'js2-build-imenu-callbacks 'js2-imenu-record-declarations t t))
+  (when (or js2-imenu-show-other-functions js2-imenu-show-module-pattern)
+    (add-hook 'js2-build-imenu-callbacks 'js2-imenu-walk-ast t t)))
+
+(defun js2-imenu-extras-remove ()
+  (remove-hook 'js2-build-imenu-callbacks 'js2-imenu-record-declarations t)
+  (remove-hook 'js2-build-imenu-callbacks 'js2-imenu-walk-ast t))
+
+(defun js2-imenu-record-declarations ()
+  (let* ((styles (loop for style in js2-imenu-extension-styles
+                       when (memq (plist-get style :framework)
+                                  js2-imenu-enabled-frameworks)
+                       collect style))
+         (re (mapconcat (lambda (style)
+                          (concat "\\(" (plist-get style :call-re) "\\)"))
+                        styles "\\|")))
+    (goto-char (point-min))
+    (while (js2-re-search-forward re nil t)
+      (loop for i from 0 to (1- (length styles))
+            when (match-beginning (1+ i))
+            return (funcall (plist-get (nth i styles) :recorder))))))
+
+(defun js2-imenu-record-jquery-extend ()
+  (let ((pred (lambda (subject)
+                (and
+                 (js2-prop-get-node-p subject)
+                 (string= (js2-name-node-name (js2-prop-get-node-right subject))
+                          "prototype")))))
+    (js2-imenu-record-extend-first-arg (1- (point)) pred
+                                       'js2-compute-nested-prop-get)))
+
+(defun js2-imenu-record-string-declare ()
+  (js2-imenu-record-extend-first-arg
+   (1- (point)) 'js2-string-node-p
+   (lambda (node)
+     (if js2-imenu-split-string-identifiers
+         (split-string (js2-string-node-value node) "\\." t)
+       (list (js2-string-node-value node))))))
+
+(defun js2-imenu-record-extend-first-arg (point pred qname-fn)
+  (let* ((node (js2-node-at-point point))
+         (args (js2-call-node-args node))
+         (subject (first args)))
+    (when (funcall pred subject)
+      (loop for arg in (cdr args)
+            when (js2-object-node-p arg)
+            do (js2-record-object-literal
+                arg (funcall qname-fn subject) (js2-node-abs-pos arg))))))
+
+(defun js2-imenu-record-backbone-or-react ()
+  (let* ((node (js2-node-at-point (1- (point))))
+         (args (js2-call-node-args node))
+         (methods (first args))
+         (parent (js2-node-parent node)))
+    (when (js2-object-node-p methods)
+      (let ((subject (cond ((js2-var-init-node-p parent)
+                            (js2-var-init-node-target parent))
+                           ((js2-assign-node-p parent)
+                            (js2-assign-node-left parent)))))
+        (when subject
+          (js2-record-object-literal methods
+                                     (js2-compute-nested-prop-get subject)
+                                     (js2-node-abs-pos methods)))))))
+
+(defalias 'js2-imenu-record-backbone-extend 'js2-imenu-record-backbone-or-react)
+
+(defalias 'js2-imenu-record-react-class 'js2-imenu-record-backbone-or-react)
+
+(defun js2-imenu-record-enyo-kind ()
+  (let* ((node (js2-node-at-point (1- (point))))
+         (args (js2-call-node-args node))
+         (options (first args)))
+    (when (js2-object-node-p options)
+      (let ((name-value
+             (loop for elem in (js2-object-node-elems options)
+                   thereis
+                   (let ((key (js2-object-prop-node-left elem))
+                         (value (js2-object-prop-node-right elem)))
+                     (when (and (equal
+                                 (cond ((js2-name-node-p key)
+                                        (js2-name-node-name key))
+                                       ((js2-string-node-p key)
+                                        (js2-string-node-value key)))
+                                 "name")
+                                (js2-string-node-p value))
+                       (js2-string-node-value value))))))
+        (when name-value
+          (js2-record-object-literal options
+                                     (if js2-imenu-split-string-identifiers
+                                         (split-string name-value "\\.")
+                                       (list name-value))
+                                     (js2-node-abs-pos options)))))))
+
+(defun js2-imenu-record-sencha-class ()
+  (let* ((node (js2-node-at-point (1- (point))))
+         (args (js2-call-node-args node))
+         (name (first args))
+         (methods (second args)))
+    (when (and (js2-string-node-p name) (js2-object-node-p methods))
+      (let ((name-value (js2-string-node-value name)))
+        (js2-record-object-literal methods
+                                   (if js2-imenu-split-string-identifiers
+                                       (split-string name-value "\\." t)
+                                     (list name-value))
+                                   (js2-node-abs-pos methods))))))
+
+(defun js2-imenu-walk-ast ()
+  (js2-visit-ast
+   js2-mode-ast
+   (lambda (node end-p)
+     (unless end-p
+       (cond
+        ((and js2-imenu-show-other-functions
+              (js2-object-prop-node-p node))
+         (js2-imenu-record-orphan-prop-node-function node))
+        ((js2-assign-node-p node)
+         (cond
+          ((and js2-imenu-show-other-functions
+                (js2-function-node-p
+                 (js2-assign-node-right node)))
+           (js2-imenu-record-orphan-assign-node-function
+            (js2-assign-node-left node)
+            (js2-assign-node-right node)))
+          ((and js2-imenu-show-module-pattern
+                (js2-call-node-p
+                 (js2-assign-node-right node)))
+           (js2-imenu-record-module-pattern
+            (js2-assign-node-left node)
+            (js2-assign-node-right node)))))
+        ((js2-var-init-node-p node)
+         (cond
+          ((and js2-imenu-show-other-functions
+                (js2-function-node-p
+                 (js2-var-init-node-initializer node)))
+           (js2-imenu-record-orphan-assign-node-function
+            (js2-var-init-node-target node)
+            (js2-var-init-node-initializer node)))
+          ((and js2-imenu-show-module-pattern
+                (js2-call-node-p
+                 (js2-var-init-node-initializer node)))
+           (js2-imenu-record-module-pattern
+            (js2-var-init-node-target node)
+            (js2-var-init-node-initializer node))))))
+       t))))
+
+(defun js2-imenu-parent-key-names (node)
+  "Get the list of parent key names of NODE.
+
+For example, for code
+
+  {rules: {password: {required: function() {}}}}
+
+when NODE is the inner `js2-object-prop-mode',
+it returns `(\"rules\" \"password\")'."
+  (let (rlt (n node))
+    (while (setq n (js2-imenu-parent-prop-node n))
+      (push (js2-prop-node-name (js2-object-prop-node-left n)) rlt))
+    rlt))
+
+(defun js2-imenu-parent-prop-node (node)
+  "When the parent of NODE is `js2-object-node',
+and the grandparent is `js2-object-prop-node',
+return the grandparent."
+  ;; Suppose the code is:
+  ;; {parent-key: {required: function() {}}}
+  ;; NODE is `required: function() {}'.
+  (let (p2 p3)
+    ;; Parent is `{required: function() {}}'.
+    (setq p2 (js2-node-parent node))
+    ;; GP is `parent-key: {required: function() {}}'.
+    (when (and p2 (js2-object-node-p p2))
+      (setq p3 (js2-node-parent p2))
+      (if (and p3 (js2-object-prop-node-p p3)) p3))))
+
+(defun js2-imenu-record-orphan-prop-node-function (node)
+  "Record orphan function when it's the value of NODE.
+NODE must be `js2-object-prop-node'."
+  (when (js2-function-node-p (js2-object-prop-node-right node))
+    (let ((fn-node (js2-object-prop-node-right node)))
+      (unless (and js2-imenu-function-map
+                   (gethash fn-node js2-imenu-function-map))
+        (let ((key-node (js2-object-prop-node-left node))
+              (parent-prop-node (js2-imenu-parent-prop-node node))
+              chain)
+          (setq chain (nconc (js2-imenu-parent-key-names node)
+                             (list (js2-prop-node-name key-node))))
+          (push js2-imenu-other-functions-ns chain)
+          (js2-record-imenu-entry fn-node chain
+                                  (js2-node-abs-pos key-node)))))))
+
+(defun js2-imenu-record-orphan-assign-node-function (target-node fn-node)
+  "Record orphan function FN-NODE assigned to node TARGET."
+  (when (or (not js2-imenu-function-map)
+            (eq 'skip
+                (gethash fn-node js2-imenu-function-map 'skip)))
+    (let ((chain (js2-compute-nested-prop-get target-node)))
+      (when chain
+        (push js2-imenu-other-functions-ns chain)
+        (js2-record-imenu-entry fn-node chain (js2-node-abs-pos fn-node))))))
+
+(defun js2-imenu-record-module-pattern (target init)
+  "Recognize and record module pattern use instance.
+INIT must be `js2-call-node'."
+  (let ((callt (js2-call-node-target init)))
+    ;; Just basic call form: (function() {...})();
+    ;; TODO: Handle variations without duplicating `js2-wrapper-function-p'?
+    (when (and (js2-paren-node-p callt)
+               (js2-function-node-p (js2-paren-node-expr callt)))
+      (let* ((fn (js2-paren-node-expr callt))
+             (blk (js2-function-node-body fn))
+             (ret (car (last (js2-block-node-kids blk)))))
+        (when (and (js2-return-node-p ret)
+                   (js2-object-node-p (js2-return-node-retval ret)))
+          ;; TODO: Map function names when revealing module pattern is used.
+          (let ((retval (js2-return-node-retval ret))
+                (target-qname (js2-compute-nested-prop-get target)))
+            (js2-record-object-literal retval target-qname
+                                       (js2-node-abs-pos retval))
+            (js2-record-imenu-entry fn target-qname
+                                    (js2-node-abs-pos target))))))))
+
+;;;###autoload
+(define-minor-mode js2-imenu-extras-mode
+  "Toggle Imenu support for frameworks and structural patterns."
+  :lighter ""
+  (if js2-imenu-extras-mode
+      (js2-imenu-extras-setup)
+    (js2-imenu-extras-remove)))
+
+(provide 'js2-imenu-extras)
diff --git a/configs/shared/emacs/.emacs.d/elpa/js2-mode-20180627.744/js2-imenu-extras.elc b/configs/shared/emacs/.emacs.d/elpa/js2-mode-20180627.744/js2-imenu-extras.elc
new file mode 100644
index 0000000000..7254cb3c30
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/js2-mode-20180627.744/js2-imenu-extras.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/js2-mode-20180627.744/js2-mode-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/js2-mode-20180627.744/js2-mode-autoloads.el
new file mode 100644
index 0000000000..5ff6829110
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/js2-mode-20180627.744/js2-mode-autoloads.el
@@ -0,0 +1,68 @@
+;;; js2-mode-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "js2-imenu-extras" "js2-imenu-extras.el" (23377
+;;;;;;  61668 460640 682000))
+;;; Generated autoloads from js2-imenu-extras.el
+
+(autoload 'js2-imenu-extras-setup "js2-imenu-extras" "\
+
+
+\(fn)" nil nil)
+
+(autoload 'js2-imenu-extras-mode "js2-imenu-extras" "\
+Toggle Imenu support for frameworks and structural patterns.
+
+\(fn &optional ARG)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "js2-mode" "js2-mode.el" (23377 61668 469934
+;;;;;;  313000))
+;;; Generated autoloads from js2-mode.el
+
+(autoload 'js2-highlight-unused-variables-mode "js2-mode" "\
+Toggle highlight of unused variables.
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'js2-minor-mode "js2-mode" "\
+Minor mode for running js2 as a background linter.
+This allows you to use a different major mode for JavaScript editing,
+such as `js-mode', while retaining the asynchronous error/warning
+highlighting features of `js2-mode'.
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'js2-mode "js2-mode" "\
+Major mode for editing JavaScript code.
+
+\(fn)" t nil)
+
+(autoload 'js2-jsx-mode "js2-mode" "\
+Major mode for editing JSX code.
+
+To customize the indentation for this mode, set the SGML offset
+variables (`sgml-basic-offset' et al) locally, like so:
+
+  (defun set-jsx-indentation ()
+    (setq-local sgml-basic-offset js2-basic-offset))
+  (add-hook \\='js2-jsx-mode-hook #\\='set-jsx-indentation)
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads nil nil ("js2-mode-pkg.el" "js2-old-indent.el")
+;;;;;;  (23377 61668 468577 362000))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; js2-mode-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/js2-mode-20180627.744/js2-mode-pkg.el b/configs/shared/emacs/.emacs.d/elpa/js2-mode-20180627.744/js2-mode-pkg.el
new file mode 100644
index 0000000000..72595867dc
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/js2-mode-20180627.744/js2-mode-pkg.el
@@ -0,0 +1,9 @@
+(define-package "js2-mode" "20180627.744" "Improved JavaScript editing mode"
+  '((emacs "24.1")
+    (cl-lib "0.5"))
+  :keywords
+  '("languages" "javascript")
+  :url "https://github.com/mooz/js2-mode/")
+;; Local Variables:
+;; no-byte-compile: t
+;; End:
diff --git a/configs/shared/emacs/.emacs.d/elpa/js2-mode-20180627.744/js2-mode.el b/configs/shared/emacs/.emacs.d/elpa/js2-mode-20180627.744/js2-mode.el
new file mode 100644
index 0000000000..5058020d95
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/js2-mode-20180627.744/js2-mode.el
@@ -0,0 +1,12854 @@
+;;; js2-mode.el --- Improved JavaScript editing mode -*- lexical-binding: t -*-
+
+;; Copyright (C) 2009, 2011-2018  Free Software Foundation, Inc.
+
+;; Author: Steve Yegge <steve.yegge@gmail.com>
+;;         mooz <stillpedant@gmail.com>
+;;         Dmitry Gutov <dgutov@yandex.ru>
+;; URL:  https://github.com/mooz/js2-mode/
+;;       http://code.google.com/p/js2-mode/
+;; Version: 20180301
+;; Keywords: languages, javascript
+;; Package-Requires: ((emacs "24.1") (cl-lib "0.5"))
+
+;; 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:
+
+;; This JavaScript editing mode supports:
+
+;;  - strict recognition of the Ecma-262 language standard
+;;  - support for most Rhino and SpiderMonkey extensions from 1.5 and up
+;;  - parsing support for ECMAScript for XML (E4X, ECMA-357)
+;;  - accurate syntax highlighting using a recursive-descent parser
+;;  - on-the-fly reporting of syntax errors and strict-mode warnings
+;;  - undeclared-variable warnings using a configurable externs framework
+;;  - "bouncing" line indentation to choose among alternate indentation points
+;;  - smart line-wrapping within comments and strings
+;;  - code folding:
+;;    - show some or all function bodies as {...}
+;;    - show some or all block comments as /*...*/
+;;  - context-sensitive menu bar and popup menus
+;;  - code browsing using the `imenu' package
+;;  - many customization options
+
+;; Installation:
+;;
+;; To install it as your major mode for JavaScript editing:
+
+;;   (add-to-list 'auto-mode-alist '("\\.js\\'" . js2-mode))
+
+;; Alternatively, to install it as a minor mode just for JavaScript linting,
+;; you must add it to the appropriate major-mode hook.  Normally this would be:
+
+;;   (add-hook 'js-mode-hook 'js2-minor-mode)
+
+;; You may also want to hook it in for shell scripts running via node.js:
+
+;;   (add-to-list 'interpreter-mode-alist '("node" . js2-mode))
+
+;; Support for JSX is available via the derived mode `js2-jsx-mode'.  If you
+;; also want JSX support, use that mode instead:
+
+;;   (add-to-list 'auto-mode-alist '("\\.jsx?\\'" . js2-jsx-mode))
+;;   (add-to-list 'interpreter-mode-alist '("node" . js2-jsx-mode))
+
+;; To customize how it works:
+;;   M-x customize-group RET js2-mode RET
+
+;; Notes:
+
+;; This mode includes a port of Mozilla Rhino's scanner, parser and
+;; symbol table.  Ideally it should stay in sync with Rhino, keeping
+;; `js2-mode' current as the EcmaScript language standard evolves.
+
+;; Unlike cc-engine based language modes, js2-mode's line-indentation is not
+;; customizable.  It is a surprising amount of work to support customizable
+;; indentation.  The current compromise is that the tab key lets you cycle among
+;; various likely indentation points, similar to the behavior of python-mode.
+
+;; This mode does not yet work with "multi-mode" modes such as `mmm-mode'
+;; and `mumamo', although it could be made to do so with some effort.
+;; This means that `js2-mode' is currently only useful for editing JavaScript
+;; files, and not for editing JavaScript within <script> tags or templates.
+
+;; The project page on GitHub is used for development and issue tracking.
+;; The original homepage at Google Code has outdated information and is mostly
+;; unmaintained.
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'imenu)
+(require 'js)
+(require 'etags)
+
+(eval-and-compile
+  (if (version< emacs-version "25.0")
+      (require 'js2-old-indent)
+    (defvaralias 'js2-basic-offset 'js-indent-level nil)
+    (defalias 'js2-proper-indentation 'js--proper-indentation)
+    (defalias 'js2-jsx-indent-line 'js-jsx-indent-line)
+    (defalias 'js2-indent-line 'js-indent-line)
+    (defalias 'js2-re-search-forward 'js--re-search-forward)))
+
+;;; Externs (variables presumed to be defined by the host system)
+
+(defvar js2-ecma-262-externs
+  (mapcar 'symbol-name
+          '(Array Boolean Date Error EvalError Function Infinity JSON
+          Math NaN Number Object RangeError ReferenceError RegExp
+          String SyntaxError TypeError URIError
+          decodeURI decodeURIComponent encodeURI
+          encodeURIComponent escape eval isFinite isNaN
+          parseFloat parseInt undefined unescape))
+"Ecma-262 externs.  Never highlighted as undeclared variables.")
+
+(defvar js2-browser-externs
+  (mapcar 'symbol-name
+          '(;; DOM level 1
+            Attr CDATASection CharacterData Comment DOMException
+            DOMImplementation Document DocumentFragment
+            DocumentType Element Entity EntityReference
+            ExceptionCode NamedNodeMap Node NodeList Notation
+            ProcessingInstruction Text
+
+            ;; DOM level 2
+            HTMLAnchorElement HTMLAppletElement HTMLAreaElement
+            HTMLBRElement HTMLBaseElement HTMLBaseFontElement
+            HTMLBodyElement HTMLButtonElement HTMLCollection
+            HTMLDListElement HTMLDirectoryElement HTMLDivElement
+            HTMLDocument HTMLElement HTMLFieldSetElement
+            HTMLFontElement HTMLFormElement HTMLFrameElement
+            HTMLFrameSetElement HTMLHRElement HTMLHeadElement
+            HTMLHeadingElement HTMLHtmlElement HTMLIFrameElement
+            HTMLImageElement HTMLInputElement HTMLIsIndexElement
+            HTMLLIElement HTMLLabelElement HTMLLegendElement
+            HTMLLinkElement HTMLMapElement HTMLMenuElement
+            HTMLMetaElement HTMLModElement HTMLOListElement
+            HTMLObjectElement HTMLOptGroupElement
+            HTMLOptionElement HTMLOptionsCollection
+            HTMLParagraphElement HTMLParamElement HTMLPreElement
+            HTMLQuoteElement HTMLScriptElement HTMLSelectElement
+            HTMLStyleElement HTMLTableCaptionElement
+            HTMLTableCellElement HTMLTableColElement
+            HTMLTableElement HTMLTableRowElement
+            HTMLTableSectionElement HTMLTextAreaElement
+            HTMLTitleElement HTMLUListElement
+
+            ;; DOM level 3
+            DOMConfiguration DOMError DOMException
+            DOMImplementationList DOMImplementationSource
+            DOMLocator DOMStringList NameList TypeInfo
+            UserDataHandler
+
+            ;; Window
+            window alert confirm document java navigator prompt screen
+            self top requestAnimationFrame cancelAnimationFrame
+
+            ;; W3C CSS
+            CSSCharsetRule CSSFontFace CSSFontFaceRule
+            CSSImportRule CSSMediaRule CSSPageRule
+            CSSPrimitiveValue CSSProperties CSSRule CSSRuleList
+            CSSStyleDeclaration CSSStyleRule CSSStyleSheet
+            CSSValue CSSValueList Counter DOMImplementationCSS
+            DocumentCSS DocumentStyle ElementCSSInlineStyle
+            LinkStyle MediaList RGBColor Rect StyleSheet
+            StyleSheetList ViewCSS
+
+            ;; W3C Event
+            EventListener EventTarget Event DocumentEvent UIEvent
+            MouseEvent MutationEvent KeyboardEvent
+
+            ;; W3C Range
+            DocumentRange Range RangeException
+
+            ;; W3C XML
+            XPathResult XMLHttpRequest
+
+            ;; console object.  Provided by at least Chrome and Firefox.
+            console))
+  "Browser externs.
+You can cause these to be included or excluded with the custom
+variable `js2-include-browser-externs'.")
+
+(defvar js2-rhino-externs
+  (mapcar 'symbol-name
+          '(Packages importClass importPackage com org java
+            ;; Global object (shell) externs.
+            defineClass deserialize doctest gc help load
+            loadClass print quit readFile readUrl runCommand seal
+            serialize spawn sync toint32 version))
+  "Mozilla Rhino externs.
+Set `js2-include-rhino-externs' to t to include them.")
+
+(defvar js2-node-externs
+  (mapcar 'symbol-name
+          '(__dirname __filename Buffer clearInterval clearTimeout require
+            console exports global module process setInterval setTimeout
+            querystring setImmediate clearImmediate))
+  "Node.js externs.
+Set `js2-include-node-externs' to t to include them.")
+
+(defvar js2-typed-array-externs
+  (mapcar 'symbol-name
+          '(ArrayBuffer Uint8ClampedArray DataView
+            Int8Array Uint8Array Int16Array Uint16Array Int32Array Uint32Array
+            Float32Array Float64Array))
+  "Khronos typed array externs. Available in most modern browsers and
+in node.js >= 0.6. If `js2-include-node-externs' or `js2-include-browser-externs'
+are enabled, these will also be included.")
+
+(defvar js2-harmony-externs
+  (mapcar 'symbol-name
+          '(Map Promise Proxy Reflect Set Symbol WeakMap WeakSet))
+  "ES6 externs.  If `js2-include-browser-externs' is enabled and
+`js2-language-version' is sufficiently high, these will be included.")
+
+;;; Variables
+
+(defcustom js2-ignored-warnings nil
+  "A list of warning message types that will not be reported.
+
+Possible values are the keys of `js2-message-table'."
+  :group 'js2-mode
+  :type '(repeat string))
+
+(defcustom js2-highlight-level 2
+  "Amount of syntax highlighting to perform.
+0 or a negative value means none.
+1 adds basic syntax highlighting.
+2 adds highlighting of some Ecma built-in properties.
+3 adds highlighting of many Ecma built-in functions."
+  :group 'js2-mode
+  :type '(choice (const :tag "None" 0)
+                 (const :tag "Basic" 1)
+                 (const :tag "Include Properties" 2)
+                 (const :tag "Include Functions" 3)))
+
+(defvar js2-mode-dev-mode-p nil
+  "Non-nil if running in development mode.  Normally nil.")
+
+(defgroup js2-mode nil
+  "An improved JavaScript mode."
+  :group 'languages)
+
+(defcustom js2-idle-timer-delay 0.2
+  "Delay in secs before re-parsing after user makes changes.
+Multiplied by `js2-dynamic-idle-timer-adjust', which see."
+  :type 'number
+  :group 'js2-mode)
+(make-variable-buffer-local 'js2-idle-timer-delay)
+
+(defcustom js2-dynamic-idle-timer-adjust 0
+  "Positive to adjust `js2-idle-timer-delay' based on file size.
+The idea is that for short files, parsing is faster so we can be
+more responsive to user edits without interfering with editing.
+The buffer length in characters (typically bytes) is divided by
+this value and used to multiply `js2-idle-timer-delay' for the
+buffer.  For example, a 21k file and 10k adjust yields 21k/10k
+== 2, so js2-idle-timer-delay is multiplied by 2.
+If `js2-dynamic-idle-timer-adjust' is 0 or negative,
+`js2-idle-timer-delay' is not dependent on the file size."
+  :type 'number
+  :group 'js2-mode)
+
+(defcustom js2-concat-multiline-strings t
+  "When non-nil, `js2-line-break' in mid-string will make it a
+string concatenation. When `eol', the '+' will be inserted at the
+end of the line, otherwise, at the beginning of the next line."
+  :type '(choice (const t) (const eol) (const nil))
+  :group 'js2-mode)
+
+(defcustom js2-mode-show-parse-errors t
+  "True to highlight parse errors."
+  :type 'boolean
+  :group 'js2-mode)
+
+(defcustom js2-mode-assume-strict nil
+  "Non-nil to start files in strict mode automatically."
+  :type 'boolean
+  :group 'js2-mode)
+
+(defcustom js2-mode-show-strict-warnings t
+  "Non-nil to emit Ecma strict-mode warnings.
+Some of the warnings can be individually disabled by other flags,
+even if this flag is non-nil."
+  :type 'boolean
+  :group 'js2-mode)
+
+(defcustom js2-strict-trailing-comma-warning nil
+  "Non-nil to warn about trailing commas in array literals.
+Ecma-262-5.1 allows them, but older versions of IE raise an error."
+  :type 'boolean
+  :group 'js2-mode)
+
+(defcustom js2-strict-missing-semi-warning t
+  "Non-nil to warn about semicolon auto-insertion after statement.
+Technically this is legal per Ecma-262, but some style guides disallow
+depending on it."
+  :type 'boolean
+  :group 'js2-mode)
+
+(defcustom js2-missing-semi-one-line-override nil
+  "Non-nil to permit missing semicolons in one-line functions.
+In one-liner functions such as `function identity(x) {return x}'
+people often omit the semicolon for a cleaner look.  If you are
+such a person, you can suppress the missing-semicolon warning
+by setting this variable to t."
+  :type 'boolean
+  :group 'js2-mode)
+
+(defcustom js2-strict-inconsistent-return-warning t
+  "Non-nil to warn about mixing returns with value-returns.
+It's perfectly legal to have a `return' and a `return foo' in the
+same function, but it's often an indicator of a bug, and it also
+interferes with type inference (in systems that support it.)"
+  :type 'boolean
+  :group 'js2-mode)
+
+(defcustom js2-strict-cond-assign-warning t
+  "Non-nil to warn about expressions like if (a = b).
+This often should have been '==' instead of '='.  If the warning
+is enabled, you can suppress it on a per-expression basis by
+parenthesizing the expression, e.g. if ((a = b)) ..."
+  :type 'boolean
+  :group 'js2-mode)
+
+(defcustom js2-strict-var-redeclaration-warning t
+  "Non-nil to warn about redeclaring variables in a script or function."
+  :type 'boolean
+  :group 'js2-mode)
+
+(defcustom js2-strict-var-hides-function-arg-warning t
+  "Non-nil to warn about a var decl hiding a function argument."
+  :type 'boolean
+  :group 'js2-mode)
+
+(defcustom js2-skip-preprocessor-directives nil
+  "Non-nil to treat lines beginning with # as comments.
+Useful for viewing Mozilla JavaScript source code."
+  :type 'boolean
+  :group 'js2-mode)
+
+(defcustom js2-language-version 200
+  "Configures what JavaScript language version to recognize.
+Currently versions 150, 160, 170, 180 and 200 are supported,
+corresponding to JavaScript 1.5, 1.6, 1.7, 1.8 and 2.0 (Harmony),
+respectively.  In a nutshell, 1.6 adds E4X support, 1.7 adds let,
+yield, and Array comprehensions, and 1.8 adds function closures."
+  :type 'integer
+  :group 'js2-mode)
+
+(defcustom js2-instanceof-has-side-effects nil
+  "If non-nil, treats the instanceof operator as having side effects.
+This is useful for xulrunner apps."
+  :type 'boolean
+  :group 'js2-mode)
+
+(defcustom js2-getprop-has-side-effects nil
+  "If non-nil, treats the getprop operator as having side effects.
+This is useful for testing libraries with nontrivial getters and for
+compilers that use empty getprops to declare interface properties."
+  :type 'boolean
+  :group 'js2-mode)
+
+(defcustom js2-move-point-on-right-click t
+  "Non-nil to move insertion point when you right-click.
+This makes right-click context menu behavior a bit more intuitive,
+since menu operations generally apply to the point.  The exception
+is if there is a region selection, in which case the point does -not-
+move, so cut/copy/paste can work properly.
+
+Note that IntelliJ moves the point, and Eclipse leaves it alone,
+so this behavior is customizable."
+  :group 'js2-mode
+  :type 'boolean)
+
+(defcustom js2-allow-rhino-new-expr-initializer t
+  "Non-nil to support a Rhino's experimental syntactic construct.
+
+Rhino supports the ability to follow a `new' expression with an object
+literal, which is used to set additional properties on the new object
+after calling its constructor.  Syntax:
+
+  new <expr> [ ( arglist ) ] [initializer]
+
+Hence, this expression:
+
+  new Object {a: 1, b: 2}
+
+results in an Object with properties a=1 and b=2.  This syntax is
+apparently not configurable in Rhino - it's currently always enabled,
+as of Rhino version 1.7R2."
+  :type 'boolean
+  :group 'js2-mode)
+
+(defcustom js2-allow-member-expr-as-function-name nil
+  "Non-nil to support experimental Rhino syntax for function names.
+
+Rhino supports an experimental syntax configured via the Rhino Context
+setting `allowMemberExprAsFunctionName'.  The experimental syntax is:
+
+  function <member-expr> ( [ arg-list ] ) { <body> }
+
+Where member-expr is a non-parenthesized 'member expression', which
+is anything at the grammar level of a new-expression or lower, meaning
+any expression that does not involve infix or unary operators.
+
+When <member-expr> is not a simple identifier, then it is syntactic
+sugar for assigning the anonymous function to the <member-expr>.  Hence,
+this code:
+
+  function a.b().c[2] (x, y) { ... }
+
+is rewritten as:
+
+  a.b().c[2] = function(x, y) {...}
+
+which doesn't seem particularly useful, but Rhino permits it."
+  :type 'boolean
+  :group 'js2-mode)
+
+;; scanner variables
+
+(defmacro js2-deflocal (name value &optional comment)
+  "Define a buffer-local variable NAME with VALUE and COMMENT."
+  (declare (debug defvar) (doc-string 3))
+  `(progn
+     (defvar ,name ,value ,comment)
+     (make-variable-buffer-local ',name)))
+
+(defvar js2-EOF_CHAR -1
+  "Represents end of stream.  Distinct from js2-EOF token type.")
+
+;; I originally used symbols to represent tokens, but Rhino uses
+;; ints and then sets various flag bits in them, so ints it is.
+;; The upshot is that we need a `js2-' prefix in front of each name.
+(defvar js2-ERROR -1)
+(defvar js2-EOF 0)
+(defvar js2-EOL 1)
+(defvar js2-ENTERWITH 2)       ; begin interpreter bytecodes
+(defvar js2-LEAVEWITH 3)
+(defvar js2-RETURN 4)
+(defvar js2-GOTO 5)
+(defvar js2-IFEQ 6)
+(defvar js2-IFNE 7)
+(defvar js2-SETNAME 8)
+(defvar js2-BITOR 9)
+(defvar js2-BITXOR 10)
+(defvar js2-BITAND 11)
+(defvar js2-EQ 12)
+(defvar js2-NE 13)
+(defvar js2-LT 14)
+(defvar js2-LE 15)
+(defvar js2-GT 16)
+(defvar js2-GE 17)
+(defvar js2-LSH 18)
+(defvar js2-RSH 19)
+(defvar js2-URSH 20)
+(defvar js2-ADD 21)            ; infix plus
+(defvar js2-SUB 22)            ; infix minus
+(defvar js2-MUL 23)
+(defvar js2-DIV 24)
+(defvar js2-MOD 25)
+(defvar js2-NOT 26)
+(defvar js2-BITNOT 27)
+(defvar js2-POS 28)            ; unary plus
+(defvar js2-NEG 29)            ; unary minus
+(defvar js2-NEW 30)
+(defvar js2-DELPROP 31)
+(defvar js2-TYPEOF 32)
+(defvar js2-GETPROP 33)
+(defvar js2-GETPROPNOWARN 34)
+(defvar js2-SETPROP 35)
+(defvar js2-GETELEM 36)
+(defvar js2-SETELEM 37)
+(defvar js2-CALL 38)
+(defvar js2-NAME 39)           ; an identifier
+(defvar js2-NUMBER 40)
+(defvar js2-STRING 41)
+(defvar js2-NULL 42)
+(defvar js2-THIS 43)
+(defvar js2-FALSE 44)
+(defvar js2-TRUE 45)
+(defvar js2-SHEQ 46)           ; shallow equality (===)
+(defvar js2-SHNE 47)           ; shallow inequality (!==)
+(defvar js2-REGEXP 48)
+(defvar js2-BINDNAME 49)
+(defvar js2-THROW 50)
+(defvar js2-RETHROW 51)        ; rethrow caught exception: catch (e if ) uses it
+(defvar js2-IN 52)
+(defvar js2-INSTANCEOF 53)
+(defvar js2-LOCAL_LOAD 54)
+(defvar js2-GETVAR 55)
+(defvar js2-SETVAR 56)
+(defvar js2-CATCH_SCOPE 57)
+(defvar js2-ENUM_INIT_KEYS 58) ; FIXME: what are these?
+(defvar js2-ENUM_INIT_VALUES 59)
+(defvar js2-ENUM_INIT_ARRAY 60)
+(defvar js2-ENUM_NEXT 61)
+(defvar js2-ENUM_ID 62)
+(defvar js2-THISFN 63)
+(defvar js2-RETURN_RESULT 64)  ; to return previously stored return result
+(defvar js2-ARRAYLIT 65)       ; array literal
+(defvar js2-OBJECTLIT 66)      ; object literal
+(defvar js2-GET_REF 67)        ; *reference
+(defvar js2-SET_REF 68)        ; *reference = something
+(defvar js2-DEL_REF 69)        ; delete reference
+(defvar js2-REF_CALL 70)       ; f(args) = something or f(args)++
+(defvar js2-REF_SPECIAL 71)    ; reference for special properties like __proto
+(defvar js2-YIELD 72)          ; JS 1.7 yield pseudo keyword
+
+;; XML support
+(defvar js2-DEFAULTNAMESPACE 73)
+(defvar js2-ESCXMLATTR 74)
+(defvar js2-ESCXMLTEXT 75)
+(defvar js2-REF_MEMBER 76)     ; Reference for x.@y, x..y etc.
+(defvar js2-REF_NS_MEMBER 77)  ; Reference for x.ns::y, x..ns::y etc.
+(defvar js2-REF_NAME 78)       ; Reference for @y, @[y] etc.
+(defvar js2-REF_NS_NAME 79)    ; Reference for ns::y, @ns::y@[y] etc.
+
+(defvar js2-first-bytecode js2-ENTERWITH)
+(defvar js2-last-bytecode js2-REF_NS_NAME)
+
+(defvar js2-TRY 80)
+(defvar js2-SEMI 81)           ; semicolon
+(defvar js2-LB 82)             ; left and right brackets
+(defvar js2-RB 83)
+(defvar js2-LC 84)             ; left and right curly-braces
+(defvar js2-RC 85)
+(defvar js2-LP 86)             ; left and right parens
+(defvar js2-RP 87)
+(defvar js2-COMMA 88)          ; comma operator
+
+(defvar js2-ASSIGN 89)         ; simple assignment (=)
+(defvar js2-ASSIGN_BITOR 90)   ; |=
+(defvar js2-ASSIGN_BITXOR 91)  ; ^=
+(defvar js2-ASSIGN_BITAND 92)  ; &=
+(defvar js2-ASSIGN_LSH 93)     ; <<=
+(defvar js2-ASSIGN_RSH 94)     ; >>=
+(defvar js2-ASSIGN_URSH 95)    ; >>>=
+(defvar js2-ASSIGN_ADD 96)     ; +=
+(defvar js2-ASSIGN_SUB 97)     ; -=
+(defvar js2-ASSIGN_MUL 98)     ; *=
+(defvar js2-ASSIGN_DIV 99)     ; /=
+(defvar js2-ASSIGN_MOD 100)    ; %=
+(defvar js2-ASSIGN_EXPON 101)
+
+(defvar js2-first-assign js2-ASSIGN)
+(defvar js2-last-assign js2-ASSIGN_EXPON)
+
+(defvar js2-COLON 102)
+(defvar js2-OR 103)            ; logical or (||)
+(defvar js2-AND 104)           ; logical and (&&)
+(defvar js2-INC 105)           ; increment/decrement (++ --)
+(defvar js2-DEC 106)
+(defvar js2-DOT 107)           ; member operator (.)
+(defvar js2-FUNCTION 108)      ; function keyword
+(defvar js2-EXPORT 109)        ; export keyword
+(defvar js2-IMPORT 110)        ; import keyword
+(defvar js2-IF 111)            ; if keyword
+(defvar js2-ELSE 112)          ; else keyword
+(defvar js2-SWITCH 113)        ; switch keyword
+(defvar js2-CASE 114)          ; case keyword
+(defvar js2-DEFAULT 115)       ; default keyword
+(defvar js2-WHILE 116)         ; while keyword
+(defvar js2-DO 117)            ; do keyword
+(defvar js2-FOR 118)           ; for keyword
+(defvar js2-BREAK 119)         ; break keyword
+(defvar js2-CONTINUE 120)      ; continue keyword
+(defvar js2-VAR 121)           ; var keyword
+(defvar js2-WITH 122)          ; with keyword
+(defvar js2-CATCH 123)         ; catch keyword
+(defvar js2-FINALLY 124)       ; finally keyword
+(defvar js2-VOID 125)          ; void keyword
+(defvar js2-RESERVED 126)      ; reserved keywords
+
+(defvar js2-EMPTY 127)
+
+;; Types used for the parse tree - never returned by scanner.
+
+(defvar js2-BLOCK 128)         ; statement block
+(defvar js2-LABEL 129)         ; label
+(defvar js2-TARGET 130)
+(defvar js2-LOOP 131)
+(defvar js2-EXPR_VOID 132)     ; expression statement in functions
+(defvar js2-EXPR_RESULT 133)   ; expression statement in scripts
+(defvar js2-JSR 134)
+(defvar js2-SCRIPT 135)        ; top-level node for entire script
+(defvar js2-TYPEOFNAME 136)    ; for typeof(simple-name)
+(defvar js2-USE_STACK 137)
+(defvar js2-SETPROP_OP 138)    ; x.y op= something
+(defvar js2-SETELEM_OP 139)    ; x[y] op= something
+(defvar js2-LOCAL_BLOCK 140)
+(defvar js2-SET_REF_OP 141)    ; *reference op= something
+
+;; For XML support:
+(defvar js2-DOTDOT 142)        ; member operator (..)
+(defvar js2-COLONCOLON 143)    ; namespace::name
+(defvar js2-XML 144)           ; XML type
+(defvar js2-DOTQUERY 145)      ; .() -- e.g., x.emps.emp.(name == "terry")
+(defvar js2-XMLATTR 146)       ; @
+(defvar js2-XMLEND 147)
+
+;; Optimizer-only tokens
+(defvar js2-TO_OBJECT 148)
+(defvar js2-TO_DOUBLE 149)
+
+(defvar js2-GET 150)           ; JS 1.5 get pseudo keyword
+(defvar js2-SET 151)           ; JS 1.5 set pseudo keyword
+(defvar js2-LET 152)           ; JS 1.7 let pseudo keyword
+(defvar js2-CONST 153)
+(defvar js2-SETCONST 154)
+(defvar js2-SETCONSTVAR 155)
+(defvar js2-ARRAYCOMP 156)
+(defvar js2-LETEXPR 157)
+(defvar js2-WITHEXPR 158)
+(defvar js2-DEBUGGER 159)
+
+(defvar js2-COMMENT 160)
+(defvar js2-TRIPLEDOT 161)     ; for rest parameter
+(defvar js2-ARROW 162)         ; function arrow (=>)
+(defvar js2-CLASS 163)
+(defvar js2-EXTENDS 164)
+(defvar js2-SUPER 165)
+(defvar js2-TEMPLATE_HEAD 166)    ; part of template literal before substitution
+(defvar js2-NO_SUBS_TEMPLATE 167) ; template literal without substitutions
+(defvar js2-TAGGED_TEMPLATE 168)  ; tagged template literal
+
+(defvar js2-AWAIT 169)  ; await (pseudo keyword)
+
+(defvar js2-HOOK 170)          ; conditional (?:)
+(defvar js2-EXPON 171)
+
+(defconst js2-num-tokens (1+ js2-EXPON))
+
+(defconst js2-debug-print-trees nil)
+
+;; Rhino accepts any string or stream as input.  Emacs character
+;; processing works best in buffers, so we'll assume the input is a
+;; buffer.  JavaScript strings can be copied into temp buffers before
+;; scanning them.
+
+;; Buffer-local variables yield much cleaner code than using `defstruct'.
+;; They're the Emacs equivalent of instance variables, more or less.
+
+(js2-deflocal js2-ts-dirty-line nil
+  "Token stream buffer-local variable.
+Indicates stuff other than whitespace since start of line.")
+
+(js2-deflocal js2-ts-hit-eof nil
+  "Token stream buffer-local variable.")
+
+;; FIXME: Unused.
+(js2-deflocal js2-ts-line-start 0
+  "Token stream buffer-local variable.")
+
+(js2-deflocal js2-ts-lineno 1
+  "Token stream buffer-local variable.")
+
+;; FIXME: Unused.
+(js2-deflocal js2-ts-line-end-char -1
+  "Token stream buffer-local variable.")
+
+(js2-deflocal js2-ts-cursor 1  ; emacs buffers are 1-indexed
+  "Token stream buffer-local variable.
+Current scan position.")
+
+;; FIXME: Unused.
+(js2-deflocal js2-ts-is-xml-attribute nil
+  "Token stream buffer-local variable.")
+
+(js2-deflocal js2-ts-xml-is-tag-content nil
+  "Token stream buffer-local variable.")
+
+(js2-deflocal js2-ts-xml-open-tags-count 0
+  "Token stream buffer-local variable.")
+
+(js2-deflocal js2-ts-string-buffer nil
+  "Token stream buffer-local variable.
+List of chars built up while scanning various tokens.")
+
+(cl-defstruct (js2-token
+               (:constructor make-js2-token (beg)))
+  "Value returned from the token stream."
+  (type js2-EOF)
+  (beg 1)
+  (end -1)
+  (string "")
+  number
+  number-base
+  number-legacy-octal-p
+  regexp-flags
+  comment-type
+  follows-eol-p)
+
+;; Have to call `js2-init-scanner' to initialize the values.
+(js2-deflocal js2-ti-tokens nil)
+(js2-deflocal js2-ti-tokens-cursor nil)
+(js2-deflocal js2-ti-lookahead nil)
+
+(cl-defstruct (js2-ts-state
+               (:constructor make-js2-ts-state (&key (lineno js2-ts-lineno)
+                                                     (cursor js2-ts-cursor)
+                                                     (tokens (copy-sequence js2-ti-tokens))
+                                                     (tokens-cursor js2-ti-tokens-cursor)
+                                                     (lookahead js2-ti-lookahead))))
+  lineno
+  cursor
+  tokens
+  tokens-cursor
+  lookahead)
+
+;;; Parser variables
+
+(js2-deflocal js2-parsed-errors nil
+  "List of errors produced during scanning/parsing.")
+
+(js2-deflocal js2-parsed-warnings nil
+  "List of warnings produced during scanning/parsing.")
+
+(js2-deflocal js2-recover-from-parse-errors t
+  "Non-nil to continue parsing after a syntax error.
+
+In recovery mode, the AST will be built in full, and any error
+nodes will be flagged with appropriate error information.  If
+this flag is nil, a syntax error will result in an error being
+signaled.
+
+The variable is automatically buffer-local, because different
+modes that use the parser will need different settings.")
+
+(js2-deflocal js2-parse-hook nil
+  "List of callbacks for receiving parsing progress.")
+
+(defvar js2-parse-finished-hook nil
+  "List of callbacks to notify when parsing finishes.
+Not called if parsing was interrupted.")
+
+(js2-deflocal js2-is-eval-code nil
+  "True if we're evaluating code in a string.
+If non-nil, the tokenizer will record the token text, and the AST nodes
+will record their source text.  Off by default for IDE modes, since the
+text is available in the buffer.")
+
+(defvar js2-parse-ide-mode t
+  "Non-nil if the parser is being used for `js2-mode'.
+If non-nil, the parser will set text properties for fontification
+and the syntax table.  The value should be nil when using the
+parser as a frontend to an interpreter or byte compiler.")
+
+;;; Parser instance variables (buffer-local vars for js2-parse)
+
+(defconst js2-ti-after-eol (lsh 1 16)
+  "Flag:  first token of the source line.")
+
+;; Inline Rhino's CompilerEnvirons vars as buffer-locals.
+
+(js2-deflocal js2-compiler-generate-debug-info t)
+(js2-deflocal js2-compiler-use-dynamic-scope nil)
+(js2-deflocal js2-compiler-reserved-keywords-as-identifier nil)
+(js2-deflocal js2-compiler-xml-available t)
+(js2-deflocal js2-compiler-optimization-level 0)
+(js2-deflocal js2-compiler-generating-source t)
+(js2-deflocal js2-compiler-strict-mode nil)
+(js2-deflocal js2-compiler-report-warning-as-error nil)
+(js2-deflocal js2-compiler-generate-observer-count nil)
+(js2-deflocal js2-compiler-activation-names nil)
+
+;; SKIP:  sourceURI
+
+;; There's a compileFunction method in Context.java - may need it.
+(js2-deflocal js2-called-by-compile-function nil
+  "True if `js2-parse' was called by `js2-compile-function'.
+Will only be used when we finish implementing the interpreter.")
+
+;; SKIP:  ts  (we just call `js2-init-scanner' and use its vars)
+
+;; SKIP:  node factory - we're going to just call functions directly,
+;; and eventually go to a unified AST format.
+
+(js2-deflocal js2-nesting-of-function 0)
+
+(js2-deflocal js2-recorded-identifiers nil
+  "Tracks identifiers found during parsing.")
+
+(js2-deflocal js2-is-in-destructuring nil
+  "True while parsing destructuring expression.")
+
+(js2-deflocal js2-in-use-strict-directive nil
+  "True while inside a script or function under strict mode.")
+
+(defcustom js2-global-externs nil
+  "A list of any extern names you'd like to consider always declared.
+This list is global and is used by all `js2-mode' files.
+You can create buffer-local externs list using `js2-additional-externs'."
+  :type 'list
+  :group 'js2-mode)
+
+(defcustom js2-include-browser-externs t
+  "Non-nil to include browser externs in the master externs list.
+If you work on JavaScript files that are not intended for browsers,
+such as Mozilla Rhino server-side JavaScript, set this to nil.
+See `js2-additional-externs' for more information about externs."
+  :type 'boolean
+  :group 'js2-mode)
+
+(defcustom js2-include-rhino-externs nil
+  "Non-nil to include Mozilla Rhino externs in the master externs list.
+See `js2-additional-externs' for more information about externs."
+  :type 'boolean
+  :group 'js2-mode)
+
+(defcustom js2-include-node-externs nil
+  "Non-nil to include Node.js externs in the master externs list.
+See `js2-additional-externs' for more information about externs."
+  :type 'boolean
+  :group 'js2-mode)
+
+(js2-deflocal js2-additional-externs nil
+  "A buffer-local list of additional external declarations.
+It is used to decide whether variables are considered undeclared
+for purposes of highlighting.  See `js2-highlight-undeclared-vars'.
+
+Each entry is a Lisp string.  The string should be the fully qualified
+name of an external entity.  All externs should be added to this list,
+so that as js2-mode's processing improves it can take advantage of them.
+
+You may want to declare your externs in three ways.
+First, you can add externs that are valid for all your JavaScript files.
+You should probably do this by adding them to `js2-global-externs', which
+is a global list used for all js2-mode files.
+
+Next, you can add a function to `js2-init-hook' that adds additional
+externs appropriate for the specific file, perhaps based on its path.
+These should go in `js2-additional-externs', which is buffer-local.
+
+Third, you can use JSLint's global declaration, as long as
+`js2-include-jslint-globals' is non-nil, which see.
+
+Finally, you can add a function to `js2-post-parse-callbacks',
+which is called after parsing completes, and `js2-mode-ast' is bound to
+the root of the parse tree.  At this stage you can set up an AST
+node visitor using `js2-visit-ast' and examine the parse tree
+for specific import patterns that may imply the existence of
+other externs, possibly tied to your build system.  These should also
+be added to `js2-additional-externs'.
+
+Your post-parse callback may of course also use the simpler and
+faster (but perhaps less robust) approach of simply scanning the
+buffer text for your imports, using regular expressions.")
+
+(put 'js2-additional-externs 'safe-local-variable
+     (lambda (val) (cl-every #'stringp val)))
+
+;; SKIP:  decompiler
+;; SKIP:  encoded-source
+
+;;; The following variables are per-function and should be saved/restored
+;;; during function parsing...
+
+(js2-deflocal js2-current-script-or-fn nil)
+(js2-deflocal js2-current-scope nil)
+(js2-deflocal js2-nesting-of-with 0)
+(js2-deflocal js2-label-set nil
+  "An alist mapping label names to nodes.")
+
+(js2-deflocal js2-loop-set nil)
+(js2-deflocal js2-loop-and-switch-set nil)
+(js2-deflocal js2-has-return-value nil)
+(js2-deflocal js2-end-flags 0)
+
+;;; ...end of per function variables
+
+;; These flags enumerate the possible ways a statement/function can
+;; terminate. These flags are used by endCheck() and by the Parser to
+;; detect inconsistent return usage.
+;;
+;; END_UNREACHED is reserved for code paths that are assumed to always be
+;; able to execute (example: throw, continue)
+;;
+;; END_DROPS_OFF indicates if the statement can transfer control to the
+;; next one. Statement such as return dont. A compound statement may have
+;; some branch that drops off control to the next statement.
+;;
+;; END_RETURNS indicates that the statement can return (without arguments)
+;; END_RETURNS_VALUE indicates that the statement can return a value.
+;;
+;; A compound statement such as
+;; if (condition) {
+;;   return value;
+;; }
+;; Will be detected as (END_DROPS_OFF | END_RETURN_VALUE) by endCheck()
+
+(defconst js2-end-unreached     #x0)
+(defconst js2-end-drops-off     #x1)
+(defconst js2-end-returns       #x2)
+(defconst js2-end-returns-value #x4)
+
+;; Rhino awkwardly passes a statementLabel parameter to the
+;; statementHelper() function, the main statement parser, which
+;; is then used by quite a few of the sub-parsers.  We just make
+;; it a buffer-local variable and make sure it's cleaned up properly.
+(js2-deflocal js2-labeled-stmt nil)  ; type `js2-labeled-stmt-node'
+
+;; Similarly, Rhino passes an inForInit boolean through about half
+;; the expression parsers.  We use a dynamically-scoped variable,
+;; which makes it easier to funcall the parsers individually without
+;; worrying about whether they take the parameter or not.
+(js2-deflocal js2-in-for-init nil)
+(js2-deflocal js2-temp-name-counter 0)
+(js2-deflocal js2-parse-stmt-count 0)
+
+(defsubst js2-get-next-temp-name ()
+  (format "$%d" (cl-incf js2-temp-name-counter)))
+
+(defvar js2-parse-interruptable-p t
+  "Set this to nil to force parse to continue until finished.
+This will mostly be useful for interpreters.")
+
+(defvar js2-statements-per-pause 50
+  "Pause after this many statements to check for user input.
+If user input is pending, stop the parse and discard the tree.
+This makes for a smoother user experience for large files.
+You may have to wait a second or two before the highlighting
+and error-reporting appear, but you can always type ahead if
+you wish.  This appears to be more or less how Eclipse, IntelliJ
+and other editors work.")
+
+(js2-deflocal js2-record-comments t
+  "Instructs the scanner to record comments in `js2-scanned-comments'.")
+
+(js2-deflocal js2-scanned-comments nil
+  "List of all comments from the current parse.")
+
+(defcustom js2-mode-indent-inhibit-undo nil
+  "Non-nil to disable collection of Undo information when indenting lines.
+Some users have requested this behavior.  It's nil by default because
+other Emacs modes don't work this way."
+  :type 'boolean
+  :group 'js2-mode)
+
+(defcustom js2-mode-indent-ignore-first-tab nil
+  "If non-nil, ignore first TAB keypress if we look indented properly.
+It's fairly common for users to navigate to an already-indented line
+and press TAB for reassurance that it's been indented.  For this class
+of users, we want the first TAB press on a line to be ignored if the
+line is already indented to one of the precomputed alternatives.
+
+This behavior is only partly implemented.  If you TAB-indent a line,
+navigate to another line, and then navigate back, it fails to clear
+the last-indented variable, so it thinks you've already hit TAB once,
+and performs the indent.  A full solution would involve getting on the
+point-motion hooks for the entire buffer.  If we come across another
+use cases that requires watching point motion, I'll consider doing it.
+
+If you set this variable to nil, then the TAB key will always change
+the indentation of the current line, if more than one alternative
+indentation spot exists."
+  :type 'boolean
+  :group 'js2-mode)
+
+(defvar js2-indent-hook nil
+  "A hook for user-defined indentation rules.
+
+Functions on this hook should expect two arguments:    (LIST INDEX)
+The LIST argument is the list of computed indentation points for
+the current line.  INDEX is the list index of the indentation point
+that `js2-bounce-indent' plans to use.  If INDEX is nil, then the
+indent function is not going to change the current line indentation.
+
+If a hook function on this list returns a non-nil value, then
+`js2-bounce-indent' assumes the hook function has performed its own
+indentation, and will do nothing.  If all hook functions on the list
+return nil, then `js2-bounce-indent' will use its computed indentation
+and reindent the line.
+
+When hook functions on this hook list are called, the variable
+`js2-mode-ast' may or may not be set, depending on whether the
+parse tree is available.  If the variable is nil, you can pass a
+callback to `js2-mode-wait-for-parse', and your callback will be
+called after the new parse tree is built.  This can take some time
+in large files.")
+
+(defface js2-warning
+  `((((class color) (background light))
+     (:underline  "orange"))
+    (((class color) (background dark))
+     (:underline "orange"))
+    (t (:underline t)))
+  "Face for JavaScript warnings."
+  :group 'js2-mode)
+
+(defface js2-error
+  `((((class color) (background light))
+     (:foreground "red"))
+    (((class color) (background dark))
+     (:foreground "red"))
+    (t (:foreground "red")))
+  "Face for JavaScript errors."
+  :group 'js2-mode)
+
+(defface js2-jsdoc-tag
+  '((t :foreground "SlateGray"))
+  "Face used to highlight @whatever tags in jsdoc comments."
+  :group 'js2-mode)
+
+(defface js2-jsdoc-type
+  '((t :foreground "SteelBlue"))
+  "Face used to highlight {FooBar} types in jsdoc comments."
+  :group 'js2-mode)
+
+(defface js2-jsdoc-value
+  '((t :foreground "PeachPuff3"))
+  "Face used to highlight tag values in jsdoc comments."
+  :group 'js2-mode)
+
+(defface js2-function-param
+  '((t :foreground "SeaGreen"))
+  "Face used to highlight function parameters in javascript."
+  :group 'js2-mode)
+
+(defface js2-function-call
+  '((t :inherit default))
+  "Face used to highlight function name in calls."
+  :group 'js2-mode)
+
+(defface js2-object-property
+  '((t :inherit default))
+  "Face used to highlight named property in object literal."
+  :group 'js2-mode)
+
+(defface js2-object-property-access
+  '((t :inherit js2-object-property))
+  "Face used to highlight property access with dot on an object."
+  :group 'js2-mode)
+
+(defface js2-instance-member
+  '((t :foreground "DarkOrchid"))
+  "Face used to highlight instance variables in javascript.
+Not currently used."
+  :group 'js2-mode)
+
+(defface js2-private-member
+  '((t :foreground "PeachPuff3"))
+  "Face used to highlight calls to private methods in javascript.
+Not currently used."
+  :group 'js2-mode)
+
+(defface js2-private-function-call
+  '((t :foreground "goldenrod"))
+  "Face used to highlight calls to private functions in javascript.
+Not currently used."
+  :group 'js2-mode)
+
+(defface js2-jsdoc-html-tag-name
+  '((((class color) (min-colors 88) (background light))
+     (:foreground "rosybrown"))
+    (((class color) (min-colors 8) (background dark))
+     (:foreground "yellow"))
+    (((class color) (min-colors 8) (background light))
+     (:foreground "magenta")))
+    "Face used to highlight jsdoc html tag names"
+  :group 'js2-mode)
+
+(defface js2-jsdoc-html-tag-delimiter
+  '((((class color) (min-colors 88) (background light))
+     (:foreground "dark khaki"))
+    (((class color) (min-colors 8) (background dark))
+     (:foreground "green"))
+    (((class color) (min-colors 8) (background light))
+     (:foreground "green")))
+  "Face used to highlight brackets in jsdoc html tags."
+  :group 'js2-mode)
+
+(defface js2-external-variable
+  '((t :foreground "orange"))
+  "Face used to highlight undeclared variable identifiers.")
+
+(defcustom js2-init-hook nil
+  ;; FIXME: We don't really need this anymore.
+  "List of functions to be called after `js2-mode' or
+`js2-minor-mode' has initialized all variables, before parsing
+the buffer for the first time."
+  :type 'hook
+  :group 'js2-mode
+  :version "20130608")
+
+(defcustom js2-post-parse-callbacks nil
+  "List of callback functions invoked after parsing finishes.
+Currently, the main use for this function is to add synthetic
+declarations to `js2-recorded-identifiers', which see."
+  :type 'hook
+  :group 'js2-mode)
+
+(defcustom js2-build-imenu-callbacks nil
+  "List of functions called during Imenu index generation.
+It's a good place to add additional entries to it, using
+`js2-record-imenu-entry'."
+  :type 'hook
+  :group 'js2-mode)
+
+(defcustom js2-highlight-external-variables t
+  "Non-nil to highlight undeclared variable identifiers.
+An undeclared variable is any variable not declared with var or let
+in the current scope or any lexically enclosing scope.  If you use
+such a variable, then you are either expecting it to originate from
+another file, or you've got a potential bug."
+  :type 'boolean
+  :group 'js2-mode)
+
+(defcustom js2-warn-about-unused-function-arguments nil
+  "Non-nil to treat function arguments like declared-but-unused variables."
+  :type 'booleanp
+  :group 'js2-mode)
+
+(defcustom js2-include-jslint-globals t
+  "Non-nil to include the identifiers from JSLint global
+declaration (see http://www.jslint.com/help.html#global) in the
+buffer-local externs list.  See `js2-additional-externs' for more
+information."
+  :type 'boolean
+  :group 'js2-mode)
+
+(defcustom js2-include-jslint-declaration-externs t
+  "Non-nil to include the identifiers JSLint assumes to be there
+under certain declarations in the buffer-local externs list.  See
+`js2-additional-externs' for more information."
+  :type 'boolean
+  :group 'js2-mode)
+
+(defvar js2-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map [remap indent-new-comment-line] #'js2-line-break)
+    (define-key map (kbd "C-c C-e") #'js2-mode-hide-element)
+    (define-key map (kbd "C-c C-s") #'js2-mode-show-element)
+    (define-key map (kbd "C-c C-a") #'js2-mode-show-all)
+    (define-key map (kbd "C-c C-f") #'js2-mode-toggle-hide-functions)
+    (define-key map (kbd "C-c C-t") #'js2-mode-toggle-hide-comments)
+    (define-key map (kbd "C-c C-o") #'js2-mode-toggle-element)
+    (define-key map (kbd "C-c C-w") #'js2-mode-toggle-warnings-and-errors)
+    (define-key map [down-mouse-3] #'js2-down-mouse-3)
+    (define-key map [remap js-find-symbol] #'js2-jump-to-definition)
+
+    (define-key map [menu-bar javascript]
+      (cons "JavaScript" (make-sparse-keymap "JavaScript")))
+
+    (define-key map [menu-bar javascript customize-js2-mode]
+      '(menu-item "Customize js2-mode" js2-mode-customize
+                  :help "Customize the behavior of this mode"))
+
+    (define-key map [menu-bar javascript js2-force-refresh]
+      '(menu-item "Force buffer refresh" js2-mode-reset
+                  :help "Re-parse the buffer from scratch"))
+
+    (define-key map [menu-bar javascript separator-2]
+      '("--"))
+
+    (define-key map [menu-bar javascript next-error]
+      '(menu-item "Next warning or error" next-error
+                  :enabled (and js2-mode-ast
+                                (or (js2-ast-root-errors js2-mode-ast)
+                                    (js2-ast-root-warnings js2-mode-ast)))
+                  :help "Move to next warning or error"))
+
+    (define-key map [menu-bar javascript display-errors]
+      '(menu-item "Show errors and warnings" js2-mode-display-warnings-and-errors
+                  :visible (not js2-mode-show-parse-errors)
+                  :help "Turn on display of warnings and errors"))
+
+    (define-key map [menu-bar javascript hide-errors]
+      '(menu-item "Hide errors and warnings" js2-mode-hide-warnings-and-errors
+                  :visible js2-mode-show-parse-errors
+                  :help "Turn off display of warnings and errors"))
+
+    (define-key map [menu-bar javascript separator-1]
+      '("--"))
+
+    (define-key map [menu-bar javascript js2-toggle-function]
+      '(menu-item "Show/collapse element" js2-mode-toggle-element
+                  :help "Hide or show function body or comment"))
+
+    (define-key map [menu-bar javascript show-comments]
+      '(menu-item "Show block comments" js2-mode-toggle-hide-comments
+                  :visible js2-mode-comments-hidden
+                  :help "Expand all hidden block comments"))
+
+    (define-key map [menu-bar javascript hide-comments]
+      '(menu-item "Hide block comments" js2-mode-toggle-hide-comments
+                  :visible (not js2-mode-comments-hidden)
+                  :help "Show block comments as /*...*/"))
+
+    (define-key map [menu-bar javascript show-all-functions]
+      '(menu-item "Show function bodies" js2-mode-toggle-hide-functions
+                  :visible js2-mode-functions-hidden
+                  :help "Expand all hidden function bodies"))
+
+    (define-key map [menu-bar javascript hide-all-functions]
+      '(menu-item "Hide function bodies" js2-mode-toggle-hide-functions
+                  :visible (not js2-mode-functions-hidden)
+                  :help "Show {...} for all top-level function bodies"))
+
+    map)
+  "Keymap used in `js2-mode' buffers.")
+
+(defcustom js2-bounce-indent-p nil
+  "Non-nil to bind `js2-indent-bounce' and `js2-indent-bounce-backward'.
+They will augment the default indent-line behavior with cycling
+among several computed alternatives.  See the function
+`js2-bounce-indent' for details.  The above commands will be
+bound to TAB and backtab."
+  :type 'boolean
+  :group 'js2-mode
+  :set (lambda (sym value)
+         (set-default sym value)
+         (let ((map js2-mode-map))
+           (if (not value)
+               (progn
+                 (define-key map "\t" nil)
+                 (define-key map (kbd "<backtab>") nil))
+             (define-key map "\t" #'js2-indent-bounce)
+             (define-key map (kbd "<backtab>") #'js2-indent-bounce-backward)))))
+
+(defconst js2-mode-identifier-re "[[:alpha:]_$][[:alnum:]_$]*")
+
+(defvar js2-mode-//-comment-re "^\\(\\s-*\\)//.+"
+  "Matches a //-comment line.  Must be first non-whitespace on line.
+First match-group is the leading whitespace.")
+
+(defvar js2-mode-hook nil)
+
+(js2-deflocal js2-mode-ast nil "Private variable.")
+(js2-deflocal js2-mode-parse-timer nil "Private variable.")
+(js2-deflocal js2-mode-buffer-dirty-p nil "Private variable.")
+(js2-deflocal js2-mode-parsing nil "Private variable.")
+(js2-deflocal js2-mode-node-overlay nil)
+
+(defvar js2-mode-show-overlay js2-mode-dev-mode-p
+  "Debug:  Non-nil to highlight AST nodes on mouse-down.")
+
+(js2-deflocal js2-mode-fontifications nil "Private variable")
+(js2-deflocal js2-mode-deferred-properties nil "Private variable")
+(js2-deflocal js2-imenu-recorder nil "Private variable")
+(js2-deflocal js2-imenu-function-map nil "Private variable")
+
+(defvar js2-mode-verbose-parse-p js2-mode-dev-mode-p
+  "Non-nil to emit status messages during parsing.")
+
+(defvar js2-mode-functions-hidden nil "Private variable.")
+(defvar js2-mode-comments-hidden nil "Private variable.")
+
+(defvar js2-mode-syntax-table
+  (let ((table (make-syntax-table)))
+    (c-populate-syntax-table table)
+    (modify-syntax-entry ?` "\"" table)
+    table)
+  "Syntax table used in `js2-mode' buffers.")
+
+(defvar js2-mode-abbrev-table nil
+  "Abbrev table in use in `js2-mode' buffers.")
+(define-abbrev-table 'js2-mode-abbrev-table ())
+
+(defvar js2-mode-pending-parse-callbacks nil
+  "List of functions waiting to be notified that parse is finished.")
+
+(defvar js2-mode-last-indented-line -1)
+
+;;; Localizable error and warning messages
+
+;; Messages are copied from Rhino's Messages.properties.
+;; Many of the Java-specific messages have been elided.
+;; Add any js2-specific ones at the end, so we can keep
+;; this file synced with changes to Rhino's.
+
+(defvar js2-message-table
+  (make-hash-table :test 'equal :size 250)
+  "Contains localized messages for `js2-mode'.")
+
+;; TODO(stevey):  construct this table at compile-time.
+(defmacro js2-msg (key &rest strings)
+  `(puthash ,key (concat ,@strings)
+            js2-message-table))
+
+(defun js2-get-msg (msg-key)
+  "Look up a localized message.
+MSG-KEY is a list of (MSG ARGS).  If the message takes parameters,
+the correct number of ARGS must be provided."
+  (let* ((key (if (listp msg-key) (car msg-key) msg-key))
+         (args (if (listp msg-key) (cdr msg-key)))
+         (msg (gethash key js2-message-table)))
+    (if msg
+        (apply #'format msg args)
+      key)))  ; default to showing the key
+
+(js2-msg "msg.dup.parms"
+         "Duplicate parameter name '%s'.")
+
+(js2-msg "msg.too.big.jump"
+         "Program too complex: jump offset too big.")
+
+(js2-msg "msg.too.big.index"
+         "Program too complex: internal index exceeds 64K limit.")
+
+(js2-msg "msg.while.compiling.fn"
+         "Encountered code generation error while compiling function '%s': %s")
+
+(js2-msg "msg.while.compiling.script"
+         "Encountered code generation error while compiling script: %s")
+
+;; Context
+(js2-msg "msg.ctor.not.found"
+         "Constructor for '%s' not found.")
+
+(js2-msg "msg.not.ctor"
+         "'%s' is not a constructor.")
+
+;; FunctionObject
+(js2-msg "msg.varargs.ctor"
+         "Method or constructor '%s' must be static "
+         "with the signature (Context cx, Object[] args, "
+         "Function ctorObj, boolean inNewExpr) "
+         "to define a variable arguments constructor.")
+
+(js2-msg "msg.varargs.fun"
+         "Method '%s' must be static with the signature "
+         "(Context cx, Scriptable thisObj, Object[] args, Function funObj) "
+         "to define a variable arguments function.")
+
+(js2-msg "msg.incompat.call"
+         "Method '%s' called on incompatible object.")
+
+(js2-msg "msg.bad.parms"
+         "Unsupported parameter type '%s' in method '%s'.")
+
+(js2-msg "msg.bad.method.return"
+         "Unsupported return type '%s' in method '%s'.")
+
+(js2-msg "msg.bad.ctor.return"
+         "Construction of objects of type '%s' is not supported.")
+
+(js2-msg "msg.no.overload"
+         "Method '%s' occurs multiple times in class '%s'.")
+
+(js2-msg "msg.method.not.found"
+         "Method '%s' not found in '%s'.")
+
+;; IRFactory
+
+(js2-msg "msg.bad.for.in.lhs"
+         "Invalid left-hand side of for..in loop.")
+
+(js2-msg "msg.mult.index"
+         "Only one variable allowed in for..in loop.")
+
+(js2-msg "msg.bad.for.in.destruct"
+         "Left hand side of for..in loop must be an array of "
+         "length 2 to accept key/value pair.")
+
+(js2-msg "msg.cant.convert"
+         "Can't convert to type '%s'.")
+
+(js2-msg "msg.bad.assign.left"
+         "Invalid assignment left-hand side.")
+
+(js2-msg "msg.bad.decr"
+         "Invalid decrement operand.")
+
+(js2-msg "msg.bad.incr"
+         "Invalid increment operand.")
+
+(js2-msg "msg.bad.yield"
+         "yield must be in a function.")
+
+(js2-msg "msg.bad.await"
+         "await must be in async functions.")
+
+;; NativeGlobal
+(js2-msg "msg.cant.call.indirect"
+          "Function '%s' must be called directly, and not by way of a "
+          "function of another name.")
+
+(js2-msg "msg.eval.nonstring"
+          "Calling eval() with anything other than a primitive "
+          "string value will simply return the value. "
+          "Is this what you intended?")
+
+(js2-msg "msg.eval.nonstring.strict"
+         "Calling eval() with anything other than a primitive "
+         "string value is not allowed in strict mode.")
+
+(js2-msg "msg.bad.destruct.op"
+         "Invalid destructuring assignment operator")
+
+;; NativeCall
+(js2-msg "msg.only.from.new"
+         "'%s' may only be invoked from a `new' expression.")
+
+(js2-msg "msg.deprec.ctor"
+         "The '%s' constructor is deprecated.")
+
+;; NativeFunction
+(js2-msg "msg.no.function.ref.found"
+         "no source found to decompile function reference %s")
+
+(js2-msg "msg.arg.isnt.array"
+         "second argument to Function.prototype.apply must be an array")
+
+;; NativeGlobal
+(js2-msg "msg.bad.esc.mask"
+         "invalid string escape mask")
+
+;; NativeRegExp
+(js2-msg "msg.bad.quant"
+  "Invalid quantifier %s")
+
+(js2-msg "msg.overlarge.backref"
+  "Overly large back reference %s")
+
+(js2-msg "msg.overlarge.min"
+  "Overly large minimum %s")
+
+(js2-msg "msg.overlarge.max"
+  "Overly large maximum %s")
+
+(js2-msg "msg.zero.quant"
+  "Zero quantifier %s")
+
+(js2-msg "msg.max.lt.min"
+  "Maximum %s less than minimum")
+
+(js2-msg "msg.unterm.quant"
+  "Unterminated quantifier %s")
+
+(js2-msg "msg.unterm.paren"
+  "Unterminated parenthetical %s")
+
+(js2-msg "msg.unterm.class"
+  "Unterminated character class %s")
+
+(js2-msg "msg.bad.range"
+  "Invalid range in character class.")
+
+(js2-msg "msg.trail.backslash"
+  "Trailing \\ in regular expression.")
+
+(js2-msg "msg.re.unmatched.right.paren"
+  "unmatched ) in regular expression.")
+
+(js2-msg "msg.no.regexp"
+  "Regular expressions are not available.")
+
+(js2-msg "msg.bad.backref"
+  "back-reference exceeds number of capturing parentheses.")
+
+(js2-msg "msg.bad.regexp.compile"
+         "Only one argument may be specified if the first "
+         "argument to RegExp.prototype.compile is a RegExp object.")
+
+;; Parser
+(js2-msg "msg.got.syntax.errors"
+         "Compilation produced %s syntax errors.")
+
+(js2-msg "msg.var.redecl"
+         "Redeclaration of var %s.")
+
+(js2-msg "msg.const.redecl"
+         "TypeError: redeclaration of const %s.")
+
+(js2-msg "msg.let.redecl"
+         "TypeError: redeclaration of variable %s.")
+
+(js2-msg "msg.parm.redecl"
+         "TypeError: redeclaration of formal parameter %s.")
+
+(js2-msg "msg.fn.redecl"
+         "TypeError: redeclaration of function %s.")
+
+(js2-msg "msg.let.decl.not.in.block"
+         "SyntaxError: let declaration not directly within block")
+
+(js2-msg "msg.mod.import.decl.at.top.level"
+         "SyntaxError: import declarations may only appear at the top level")
+
+(js2-msg "msg.mod.as.after.reserved.word"
+         "SyntaxError: missing keyword 'as' after reserved word %s")
+
+(js2-msg "msg.mod.rc.after.import.spec.list"
+         "SyntaxError: missing '}' after module specifier list")
+
+(js2-msg "msg.mod.from.after.import.spec.set"
+         "SyntaxError: missing keyword 'from' after import specifier set")
+
+(js2-msg "msg.mod.declaration.after.import"
+         "SyntaxError: missing declaration after 'import' keyword")
+
+(js2-msg "msg.mod.spec.after.from"
+         "SyntaxError: missing module specifier after 'from' keyword")
+
+(js2-msg "msg.mod.export.decl.at.top.level"
+         "SyntaxError: export declarations may only appear at top level")
+
+(js2-msg "msg.mod.rc.after.export.spec.list"
+         "SyntaxError: missing '}' after export specifier list")
+
+;; NodeTransformer
+(js2-msg "msg.dup.label"
+         "duplicated label")
+
+(js2-msg "msg.undef.label"
+         "undefined label")
+
+(js2-msg "msg.bad.break"
+         "unlabelled break must be inside loop or switch")
+
+(js2-msg "msg.continue.outside"
+         "continue must be inside loop")
+
+(js2-msg "msg.continue.nonloop"
+         "continue can only use labels of iteration statements")
+
+(js2-msg "msg.bad.throw.eol"
+         "Line terminator is not allowed between the throw "
+         "keyword and throw expression.")
+
+(js2-msg "msg.unnamed.function.stmt" ; added by js2-mode
+         "function statement requires a name")
+
+(js2-msg "msg.no.paren.parms"
+         "missing ( before function parameters.")
+
+(js2-msg "msg.no.parm"
+         "missing formal parameter")
+
+(js2-msg "msg.no.paren.after.parms"
+         "missing ) after formal parameters")
+
+(js2-msg "msg.no.default.after.default.param" ; added by js2-mode
+         "parameter without default follows parameter with default")
+
+(js2-msg "msg.param.after.rest" ; added by js2-mode
+         "parameter after rest parameter")
+
+(js2-msg "msg.bad.arrow.args" ; added by js2-mode
+         "invalid arrow-function arguments (parentheses around the arrow-function may help)")
+
+(js2-msg "msg.no.brace.body"
+         "missing '{' before function body")
+
+(js2-msg "msg.no.brace.after.body"
+         "missing } after function body")
+
+(js2-msg "msg.no.paren.cond"
+         "missing ( before condition")
+
+(js2-msg "msg.no.paren.after.cond"
+         "missing ) after condition")
+
+(js2-msg "msg.no.semi.stmt"
+         "missing ; before statement")
+
+(js2-msg "msg.missing.semi"
+         "missing ; after statement")
+
+(js2-msg "msg.no.name.after.dot"
+         "missing name after . operator")
+
+(js2-msg "msg.no.name.after.coloncolon"
+         "missing name after :: operator")
+
+(js2-msg "msg.no.name.after.dotdot"
+         "missing name after .. operator")
+
+(js2-msg "msg.no.name.after.xmlAttr"
+         "missing name after .@")
+
+(js2-msg "msg.no.bracket.index"
+         "missing ] in index expression")
+
+(js2-msg "msg.no.paren.switch"
+         "missing ( before switch expression")
+
+(js2-msg "msg.no.paren.after.switch"
+         "missing ) after switch expression")
+
+(js2-msg "msg.no.brace.switch"
+         "missing '{' before switch body")
+
+(js2-msg "msg.bad.switch"
+         "invalid switch statement")
+
+(js2-msg "msg.no.colon.case"
+         "missing : after case expression")
+
+(js2-msg "msg.double.switch.default"
+         "double default label in the switch statement")
+
+(js2-msg "msg.no.while.do"
+         "missing while after do-loop body")
+
+(js2-msg "msg.no.paren.for"
+         "missing ( after for")
+
+(js2-msg "msg.no.semi.for"
+         "missing ; after for-loop initializer")
+
+(js2-msg "msg.no.semi.for.cond"
+         "missing ; after for-loop condition")
+
+(js2-msg "msg.in.after.for.name"
+         "missing in or of after for")
+
+(js2-msg "msg.no.paren.for.ctrl"
+         "missing ) after for-loop control")
+
+(js2-msg "msg.no.paren.with"
+         "missing ( before with-statement object")
+
+(js2-msg "msg.no.paren.after.with"
+         "missing ) after with-statement object")
+
+(js2-msg "msg.no.with.strict"
+         "with statements not allowed in strict mode")
+
+(js2-msg "msg.no.paren.after.let"
+         "missing ( after let")
+
+(js2-msg "msg.no.paren.let"
+         "missing ) after variable list")
+
+(js2-msg "msg.no.curly.let"
+         "missing } after let statement")
+
+(js2-msg "msg.bad.return"
+         "invalid return")
+
+(js2-msg "msg.no.brace.block"
+         "missing } in compound statement")
+
+(js2-msg "msg.bad.label"
+         "invalid label")
+
+(js2-msg "msg.bad.var"
+         "missing variable name")
+
+(js2-msg "msg.bad.var.init"
+         "invalid variable initialization")
+
+(js2-msg "msg.no.colon.cond"
+         "missing : in conditional expression")
+
+(js2-msg "msg.no.paren.arg"
+         "missing ) after argument list")
+
+(js2-msg "msg.no.bracket.arg"
+         "missing ] after element list")
+
+(js2-msg "msg.bad.prop"
+         "invalid property id")
+
+(js2-msg "msg.no.colon.prop"
+         "missing : after property id")
+
+(js2-msg "msg.no.brace.prop"
+         "missing } after property list")
+
+(js2-msg "msg.no.paren"
+         "missing ) in parenthetical")
+
+(js2-msg "msg.reserved.id"
+         "'%s' is a reserved identifier")
+
+(js2-msg "msg.no.paren.catch"
+         "missing ( before catch-block condition")
+
+(js2-msg "msg.bad.catchcond"
+         "invalid catch block condition")
+
+(js2-msg "msg.catch.unreachable"
+         "any catch clauses following an unqualified catch are unreachable")
+
+(js2-msg "msg.no.brace.try"
+         "missing '{' before try block")
+
+(js2-msg "msg.no.brace.catchblock"
+         "missing '{' before catch-block body")
+
+(js2-msg "msg.try.no.catchfinally"
+         "'try' without 'catch' or 'finally'")
+
+(js2-msg "msg.no.return.value"
+         "function %s does not always return a value")
+
+(js2-msg "msg.anon.no.return.value"
+         "anonymous function does not always return a value")
+
+(js2-msg "msg.return.inconsistent"
+         "return statement is inconsistent with previous usage")
+
+(js2-msg "msg.generator.returns"
+         "TypeError: legacy generator function '%s' returns a value")
+
+(js2-msg "msg.anon.generator.returns"
+         "TypeError: anonymous legacy generator function returns a value")
+
+(js2-msg "msg.syntax"
+         "syntax error")
+
+(js2-msg "msg.unexpected.eof"
+         "Unexpected end of file")
+
+(js2-msg "msg.XML.bad.form"
+         "illegally formed XML syntax")
+
+(js2-msg "msg.XML.not.available"
+         "XML runtime not available")
+
+(js2-msg "msg.too.deep.parser.recursion"
+         "Too deep recursion while parsing")
+
+(js2-msg "msg.no.side.effects"
+         "Code has no side effects")
+
+(js2-msg "msg.extra.trailing.comma"
+         "Trailing comma is not supported in some browsers")
+
+(js2-msg "msg.array.trailing.comma"
+         "Trailing comma yields different behavior across browsers")
+
+(js2-msg "msg.equal.as.assign"
+         (concat "Test for equality (==) mistyped as assignment (=)?"
+                 " (parenthesize to suppress warning)"))
+
+(js2-msg "msg.var.hides.arg"
+         "Variable %s hides argument")
+
+(js2-msg "msg.destruct.assign.no.init"
+         "Missing = in destructuring declaration")
+
+(js2-msg "msg.init.no.destruct"
+         "Binding initializer not in destructuring assignment")
+
+(js2-msg "msg.no.octal.strict"
+         "Octal numbers prohibited in strict mode.")
+
+(js2-msg "msg.dup.obj.lit.prop.strict"
+         "Property '%s' already defined in this object literal.")
+
+(js2-msg "msg.dup.param.strict"
+         "Parameter '%s' already declared in this function.")
+
+(js2-msg "msg.bad.id.strict"
+         "'%s' is not a valid identifier for this use in strict mode.")
+
+;; ScriptRuntime
+(js2-msg "msg.no.properties"
+         "%s has no properties.")
+
+(js2-msg "msg.invalid.iterator"
+         "Invalid iterator value")
+
+(js2-msg "msg.iterator.primitive"
+         "__iterator__ returned a primitive value")
+
+(js2-msg "msg.assn.create.strict"
+         "Assignment to undeclared variable %s")
+
+(js2-msg "msg.undeclared.variable"  ; added by js2-mode
+         "Undeclared variable or function '%s'")
+
+(js2-msg "msg.unused.variable"  ; added by js2-mode
+         "Unused variable or function '%s'")
+
+(js2-msg "msg.uninitialized.variable"  ; added by js2-mode
+         "Variable '%s' referenced but never initialized")
+
+(js2-msg "msg.ref.undefined.prop"
+         "Reference to undefined property '%s'")
+
+(js2-msg "msg.prop.not.found"
+         "Property %s not found.")
+
+(js2-msg "msg.invalid.type"
+         "Invalid JavaScript value of type %s")
+
+(js2-msg "msg.primitive.expected"
+         "Primitive type expected (had %s instead)")
+
+(js2-msg "msg.namespace.expected"
+         "Namespace object expected to left of :: (found %s instead)")
+
+(js2-msg "msg.null.to.object"
+         "Cannot convert null to an object.")
+
+(js2-msg "msg.undef.to.object"
+         "Cannot convert undefined to an object.")
+
+(js2-msg "msg.cyclic.value"
+         "Cyclic %s value not allowed.")
+
+(js2-msg "msg.is.not.defined"
+         "'%s' is not defined.")
+
+(js2-msg "msg.undef.prop.read"
+         "Cannot read property '%s' from %s")
+
+(js2-msg "msg.undef.prop.write"
+         "Cannot set property '%s' of %s to '%s'")
+
+(js2-msg "msg.undef.prop.delete"
+         "Cannot delete property '%s' of %s")
+
+(js2-msg "msg.undef.method.call"
+         "Cannot call method '%s' of %s")
+
+(js2-msg "msg.undef.with"
+         "Cannot apply 'with' to %s")
+
+(js2-msg "msg.isnt.function"
+         "%s is not a function, it is %s.")
+
+(js2-msg "msg.isnt.function.in"
+         "Cannot call property %s in object %s. "
+         "It is not a function, it is '%s'.")
+
+(js2-msg "msg.function.not.found"
+         "Cannot find function %s.")
+
+(js2-msg "msg.function.not.found.in"
+         "Cannot find function %s in object %s.")
+
+(js2-msg "msg.isnt.xml.object"
+         "%s is not an xml object.")
+
+(js2-msg "msg.no.ref.to.get"
+         "%s is not a reference to read reference value.")
+
+(js2-msg "msg.no.ref.to.set"
+         "%s is not a reference to set reference value to %s.")
+
+(js2-msg "msg.no.ref.from.function"
+         "Function %s can not be used as the left-hand "
+         "side of assignment or as an operand of ++ or -- operator.")
+
+(js2-msg "msg.bad.default.value"
+         "Object's getDefaultValue() method returned an object.")
+
+(js2-msg "msg.instanceof.not.object"
+         "Can't use instanceof on a non-object.")
+
+(js2-msg "msg.instanceof.bad.prototype"
+         "'prototype' property of %s is not an object.")
+
+(js2-msg "msg.bad.radix"
+         "illegal radix %s.")
+
+;; ScriptableObject
+(js2-msg "msg.default.value"
+         "Cannot find default value for object.")
+
+(js2-msg "msg.zero.arg.ctor"
+         "Cannot load class '%s' which has no zero-parameter constructor.")
+
+(js2-msg "msg.ctor.multiple.parms"
+         "Can't define constructor or class %s since more than "
+         "one constructor has multiple parameters.")
+
+(js2-msg "msg.extend.scriptable"
+         "%s must extend ScriptableObject in order to define property %s.")
+
+(js2-msg "msg.bad.getter.parms"
+         "In order to define a property, getter %s must have zero "
+         "parameters or a single ScriptableObject parameter.")
+
+(js2-msg "msg.obj.getter.parms"
+         "Expected static or delegated getter %s to take "
+         "a ScriptableObject parameter.")
+
+(js2-msg "msg.getter.static"
+         "Getter and setter must both be static or neither be static.")
+
+(js2-msg "msg.setter.return"
+         "Setter must have void return type: %s")
+
+(js2-msg "msg.setter2.parms"
+         "Two-parameter setter must take a ScriptableObject as "
+         "its first parameter.")
+
+(js2-msg "msg.setter1.parms"
+         "Expected single parameter setter for %s")
+
+(js2-msg "msg.setter2.expected"
+         "Expected static or delegated setter %s to take two parameters.")
+
+(js2-msg "msg.setter.parms"
+         "Expected either one or two parameters for setter.")
+
+(js2-msg "msg.setter.bad.type"
+         "Unsupported parameter type '%s' in setter '%s'.")
+
+(js2-msg "msg.add.sealed"
+         "Cannot add a property to a sealed object: %s.")
+
+(js2-msg "msg.remove.sealed"
+         "Cannot remove a property from a sealed object: %s.")
+
+(js2-msg "msg.modify.sealed"
+         "Cannot modify a property of a sealed object: %s.")
+
+(js2-msg "msg.modify.readonly"
+         "Cannot modify readonly property: %s.")
+
+;; TokenStream
+(js2-msg "msg.missing.exponent"
+         "missing exponent")
+
+(js2-msg "msg.caught.nfe"
+         "number format error")
+
+(js2-msg "msg.unterminated.string.lit"
+         "unterminated string literal")
+
+(js2-msg "msg.unterminated.comment"
+         "unterminated comment")
+
+(js2-msg "msg.unterminated.re.lit"
+         "unterminated regular expression literal")
+
+(js2-msg "msg.invalid.re.flag"
+         "invalid flag after regular expression")
+
+(js2-msg "msg.no.re.input.for"
+         "no input for %s")
+
+(js2-msg "msg.illegal.character"
+         "illegal character")
+
+(js2-msg "msg.invalid.escape"
+         "invalid Unicode escape sequence")
+
+(js2-msg "msg.bad.namespace"
+         "not a valid default namespace statement. "
+         "Syntax is: default xml namespace = EXPRESSION;")
+
+;; TokensStream warnings
+(js2-msg "msg.bad.octal.literal"
+         "illegal octal literal digit %s; "
+         "interpreting it as a decimal digit")
+
+(js2-msg "msg.missing.hex.digits"
+         "missing hexadecimal digits after '0x'")
+
+(js2-msg "msg.missing.binary.digits"
+         "missing binary digits after '0b'")
+
+(js2-msg "msg.missing.octal.digits"
+         "missing octal digits after '0o'")
+
+(js2-msg "msg.script.is.not.constructor"
+         "Script objects are not constructors.")
+
+;; Arrays
+(js2-msg "msg.arraylength.bad"
+         "Inappropriate array length.")
+
+;; Arrays
+(js2-msg "msg.arraylength.too.big"
+         "Array length %s exceeds supported capacity limit.")
+
+;; URI
+(js2-msg "msg.bad.uri"
+         "Malformed URI sequence.")
+
+;; Number
+(js2-msg "msg.bad.precision"
+         "Precision %s out of range.")
+
+;; NativeGenerator
+(js2-msg "msg.send.newborn"
+         "Attempt to send value to newborn generator")
+
+(js2-msg "msg.already.exec.gen"
+         "Already executing generator")
+
+(js2-msg "msg.StopIteration.invalid"
+         "StopIteration may not be changed to an arbitrary object.")
+
+;; Interpreter
+(js2-msg "msg.yield.closing"
+         "Yield from closing generator")
+
+;; Classes
+(js2-msg "msg.unnamed.class.stmt" ; added by js2-mode
+         "class statement requires a name")
+
+(js2-msg "msg.class.unexpected.comma" ; added by js2-mode
+         "unexpected ',' between class properties")
+
+(js2-msg "msg.unexpected.static" ; added by js2-mode
+         "unexpected 'static'")
+
+(js2-msg "msg.missing.extends" ; added by js2-mode
+         "name is required after extends")
+
+(js2-msg "msg.no.brace.class" ; added by js2-mode
+         "missing '{' before class body")
+
+(js2-msg "msg.missing.computed.rb" ; added by js2-mode
+         "missing ']' after computed property expression")
+
+;;; Tokens Buffer
+
+(defconst js2-ti-max-lookahead 2)
+(defconst js2-ti-ntokens (1+ js2-ti-max-lookahead))
+
+(defun js2-new-token (offset)
+  (let ((token (make-js2-token (+ offset js2-ts-cursor))))
+    (setq js2-ti-tokens-cursor (mod (1+ js2-ti-tokens-cursor) js2-ti-ntokens))
+    (aset js2-ti-tokens js2-ti-tokens-cursor token)
+    token))
+
+(defsubst js2-current-token ()
+  (aref js2-ti-tokens js2-ti-tokens-cursor))
+
+(defsubst js2-current-token-string ()
+  (js2-token-string (js2-current-token)))
+
+(defsubst js2-current-token-type ()
+  (js2-token-type (js2-current-token)))
+
+(defsubst js2-current-token-beg ()
+  (js2-token-beg (js2-current-token)))
+
+(defsubst js2-current-token-end ()
+  (js2-token-end (js2-current-token)))
+
+(defun js2-current-token-len ()
+  (let ((token (js2-current-token)))
+    (- (js2-token-end token)
+       (js2-token-beg token))))
+
+(defun js2-ts-seek (state)
+  (setq js2-ts-lineno (js2-ts-state-lineno state)
+        js2-ts-cursor (js2-ts-state-cursor state)
+        js2-ti-tokens (js2-ts-state-tokens state)
+        js2-ti-tokens-cursor (js2-ts-state-tokens-cursor state)
+        js2-ti-lookahead (js2-ts-state-lookahead state)))
+
+;;; Utilities
+
+(defun js2-delete-if (predicate list)
+  "Remove all items satisfying PREDICATE in LIST."
+  (cl-loop for item in list
+           if (not (funcall predicate item))
+           collect item))
+
+(defun js2-position (element list)
+  "Find 0-indexed position of ELEMENT in LIST comparing with `eq'.
+Returns nil if element is not found in the list."
+  (let ((count 0)
+        found)
+    (while (and list (not found))
+      (if (eq element (car list))
+          (setq found t)
+        (setq count (1+ count)
+              list (cdr list))))
+    (if found count)))
+
+(defun js2-find-if (predicate list)
+  "Find first item satisfying PREDICATE in LIST."
+  (let (result)
+    (while (and list (not result))
+      (if (funcall predicate (car list))
+          (setq result (car list)))
+      (setq list (cdr list)))
+    result))
+
+(defmacro js2-time (form)
+  "Evaluate FORM, discard result, and return elapsed time in sec."
+  (declare (debug t))
+  (let ((beg (make-symbol "--js2-time-beg--")))
+    `(let ((,beg (current-time)))
+       ,form
+       (/ (truncate (* (- (float-time (current-time))
+                          (float-time ,beg))
+                       10000))
+          10000.0))))
+
+(defsubst js2-same-line (pos)
+  "Return t if POS is on the same line as current point."
+  (and (>= pos (point-at-bol))
+       (<= pos (point-at-eol))))
+
+(defun js2-code-bug ()
+  "Signal an error when we encounter an unexpected code path."
+  (error "failed assertion"))
+
+(defsubst js2-record-text-property (beg end prop value)
+  "Record a text property to set when parsing finishes."
+  (push (list beg end prop value) js2-mode-deferred-properties))
+
+;; I'd like to associate errors with nodes, but for now the
+;; easiest thing to do is get the context info from the last token.
+(defun js2-record-parse-error (msg &optional arg pos len)
+  (push (list (list msg arg)
+              (or pos (js2-current-token-beg))
+              (or len (js2-current-token-len)))
+        js2-parsed-errors))
+
+(defun js2-report-error (msg &optional msg-arg pos len)
+  "Signal a syntax error or record a parse error."
+  (if js2-recover-from-parse-errors
+      (js2-record-parse-error msg msg-arg pos len)
+      (signal 'js2-syntax-error
+              (list msg
+                    js2-ts-lineno
+                    (save-excursion
+                     (goto-char js2-ts-cursor)
+                     (current-column))
+                    js2-ts-hit-eof))))
+
+(defun js2-report-warning (msg &optional msg-arg pos len face)
+  (if js2-compiler-report-warning-as-error
+      (js2-report-error msg msg-arg pos len)
+    (push (list (list msg msg-arg)
+                (or pos (js2-current-token-beg))
+                (or len (js2-current-token-len))
+                face)
+          js2-parsed-warnings)))
+
+(defun js2-add-strict-warning (msg-id &optional msg-arg beg end)
+  (if js2-compiler-strict-mode
+      (js2-report-warning msg-id msg-arg beg
+                          (and beg end (- end beg)))))
+
+(put 'js2-syntax-error 'error-conditions
+     '(error syntax-error js2-syntax-error))
+(put 'js2-syntax-error 'error-message "Syntax error")
+
+(put 'js2-parse-error 'error-conditions
+     '(error parse-error js2-parse-error))
+(put 'js2-parse-error 'error-message "Parse error")
+
+(defmacro js2-clear-flag (flags flag)
+  `(setq ,flags (logand ,flags (lognot ,flag))))
+
+(defmacro js2-set-flag (flags flag)
+  "Logical-or FLAG into FLAGS."
+  `(setq ,flags (logior ,flags ,flag)))
+
+(defsubst js2-flag-set-p (flags flag)
+  (/= 0 (logand flags flag)))
+
+(defsubst js2-flag-not-set-p (flags flag)
+  (zerop (logand flags flag)))
+
+;;; AST struct and function definitions
+
+;; flags for ast node property 'member-type (used for e4x operators)
+(defvar js2-property-flag    #x1 "Property access: element is valid name.")
+(defvar js2-attribute-flag   #x2 "x.@y or x..@y.")
+(defvar js2-descendants-flag #x4 "x..y or x..@i.")
+
+(defsubst js2-relpos (pos anchor)
+  "Convert POS to be relative to ANCHOR.
+If POS is nil, returns nil."
+  (and pos (- pos anchor)))
+
+(defun js2-make-pad (indent)
+  (if (zerop indent)
+      ""
+    (make-string (* indent js2-basic-offset) ? )))
+
+(defun js2-visit-ast (node callback)
+  "Visit every node in ast NODE with visitor CALLBACK.
+
+CALLBACK is a function that takes two arguments:  (NODE END-P).  It is
+called twice:  once to visit the node, and again after all the node's
+children have been processed.  The END-P argument is nil on the first
+call and non-nil on the second call.  The return value of the callback
+affects the traversal:  if non-nil, the children of NODE are processed.
+If the callback returns nil, or if the node has no children, then the
+callback is called immediately with a non-nil END-P argument.
+
+The node traversal is approximately lexical-order, although there
+are currently no guarantees around this."
+  (when node
+    (let ((vfunc (get (aref node 0) 'js2-visitor)))
+      ;; visit the node
+      (when  (funcall callback node nil)
+        ;; visit the kids
+        (cond
+         ((eq vfunc 'js2-visit-none)
+          nil)                            ; don't even bother calling it
+         ;; Each AST node type has to define a `js2-visitor' function
+         ;; that takes a node and a callback, and calls `js2-visit-ast'
+         ;; on each child of the node.
+         (vfunc
+          (funcall vfunc node callback))
+         (t
+          (error "%s does not define a visitor-traversal function"
+                 (aref node 0)))))
+      ;; call the end-visit
+      (funcall callback node t))))
+
+(cl-defstruct (js2-node
+               (:constructor nil))  ; abstract
+  "Base AST node type."
+  (type -1)  ; token type
+  (pos -1)   ; start position of this AST node in parsed input
+  (len 1)    ; num characters spanned by the node
+  props      ; optional node property list (an alist)
+  parent)    ; link to parent node; null for root
+
+(defsubst js2-node-get-prop (node prop &optional default)
+  (or (cadr (assoc prop (js2-node-props node))) default))
+
+(defsubst js2-node-set-prop (node prop value)
+  (setf (js2-node-props node)
+        (cons (list prop value) (js2-node-props node))))
+
+(defun js2-fixup-starts (n nodes)
+  "Adjust the start positions of NODES to be relative to N.
+Any node in the list may be nil, for convenience."
+  (dolist (node nodes)
+    (when node
+      (setf (js2-node-pos node) (- (js2-node-pos node)
+                                   (js2-node-pos n))))))
+
+(defun js2-node-add-children (parent &rest nodes)
+  "Set parent node of NODES to PARENT, and return PARENT.
+Does nothing if we're not recording parent links.
+If any given node in NODES is nil, doesn't record that link."
+  (js2-fixup-starts parent nodes)
+  (dolist (node nodes)
+    (and node
+         (setf (js2-node-parent node) parent))))
+
+;; Non-recursive since it's called a frightening number of times.
+(defun js2-node-abs-pos (n)
+  (let ((pos (js2-node-pos n)))
+    (while (setq n (js2-node-parent n))
+      (setq pos (+ pos (js2-node-pos n))))
+    pos))
+
+(defsubst js2-node-abs-end (n)
+  "Return absolute buffer position of end of N."
+  (+ (js2-node-abs-pos n) (js2-node-len n)))
+
+(defun js2--struct-put (name key value)
+  (put name key value)
+  (put (intern (format "cl-struct-%s" name)) key value))
+
+;; It's important to make sure block nodes have a Lisp list for the
+;; child nodes, to limit printing recursion depth in an AST that
+;; otherwise consists of defstruct vectors.  Emacs will crash printing
+;; a sufficiently large vector tree.
+
+(cl-defstruct (js2-block-node
+               (:include js2-node)
+               (:constructor make-js2-block-node (&key (type js2-BLOCK)
+                                                       (pos (js2-current-token-beg))
+                                                       len
+                                                       props
+                                                       kids)))
+  "A block of statements."
+  kids)  ; a Lisp list of the child statement nodes
+
+(js2--struct-put 'js2-block-node 'js2-visitor 'js2-visit-block)
+(js2--struct-put 'js2-block-node 'js2-printer 'js2-print-block)
+
+(defun js2-visit-block (ast callback)
+  "Visit the `js2-block-node' children of AST."
+  (dolist (kid (js2-block-node-kids ast))
+    (js2-visit-ast kid callback)))
+
+(defun js2-print-block (n i)
+  (let ((pad (js2-make-pad i)))
+    (insert pad "{\n")
+    (dolist (kid (js2-block-node-kids n))
+      (js2-print-ast kid (1+ i)))
+    (insert pad "}")))
+
+(cl-defstruct (js2-scope
+               (:include js2-block-node)
+               (:constructor make-js2-scope (&key (type js2-BLOCK)
+                                                  (pos (js2-current-token-beg))
+                                                  len
+                                                  kids)))
+  ;; The symbol-table is a LinkedHashMap<String,Symbol> in Rhino.
+  ;; I don't have one of those handy, so I'll use an alist for now.
+  ;; It's as fast as an emacs hashtable for up to about 50 elements,
+  ;; and is much lighter-weight to construct (both CPU and mem).
+  ;; The keys are interned strings (symbols) for faster lookup.
+  ;; Should switch to hybrid alist/hashtable eventually.
+  symbol-table  ; an alist of (symbol . js2-symbol)
+  parent-scope  ; a `js2-scope'
+  top)          ; top-level `js2-scope' (script/function)
+
+(js2--struct-put 'js2-scope 'js2-visitor 'js2-visit-block)
+(js2--struct-put 'js2-scope 'js2-printer 'js2-print-none)
+
+(defun js2-node-get-enclosing-scope (node)
+  "Return the innermost `js2-scope' node surrounding NODE.
+Returns nil if there is no enclosing scope node."
+  (while (and (setq node (js2-node-parent node))
+              (not (js2-scope-p node))))
+  node)
+
+(defun js2-get-defining-scope (scope name &optional point)
+  "Search up scope chain from SCOPE looking for NAME, a string or symbol.
+Returns `js2-scope' in which NAME is defined, or nil if not found.
+
+If POINT is non-nil, and if the found declaration type is
+`js2-LET', also check that the declaration node is before POINT."
+  (let ((sym (if (symbolp name)
+                 name
+               (intern name)))
+        result
+        (continue t))
+    (while (and scope continue)
+      (if (or
+           (let ((entry (cdr (assq sym (js2-scope-symbol-table scope)))))
+             (and entry
+                  (or (not point)
+                      (not (eq js2-LET (js2-symbol-decl-type entry)))
+                      (>= point
+                          (js2-node-abs-pos (js2-symbol-ast-node entry))))))
+           (and (eq sym 'arguments)
+                (js2-function-node-p scope)))
+          (setq continue nil
+                result scope)
+        (setq scope (js2-scope-parent-scope scope))))
+    result))
+
+(defun js2-scope-get-symbol (scope name)
+  "Return symbol table entry for NAME in SCOPE.
+NAME can be a string or symbol.   Returns a `js2-symbol' or nil if not found."
+  (and (js2-scope-symbol-table scope)
+       (cdr (assq (if (symbolp name)
+                      name
+                    (intern name))
+                  (js2-scope-symbol-table scope)))))
+
+(defun js2-scope-put-symbol (scope name symbol)
+  "Enter SYMBOL into symbol-table for SCOPE under NAME.
+NAME can be a Lisp symbol or string.  SYMBOL is a `js2-symbol'."
+  (let* ((table (js2-scope-symbol-table scope))
+         (sym (if (symbolp name) name (intern name)))
+         (entry (assq sym table)))
+    (if entry
+        (setcdr entry symbol)
+      (push (cons sym symbol)
+            (js2-scope-symbol-table scope)))))
+
+(cl-defstruct (js2-symbol
+               (:constructor make-js2-symbol (decl-type name &optional ast-node)))
+  "A symbol table entry."
+  ;; One of js2-FUNCTION, js2-LP (for parameters), js2-VAR,
+  ;; js2-LET, or js2-CONST
+  decl-type
+  name  ; string
+  ast-node) ; a `js2-node'
+
+(cl-defstruct (js2-error-node
+               (:include js2-node)
+               (:constructor make-js2-error-node (&key (type js2-ERROR)
+                                                       (pos (js2-current-token-beg))
+                                                       len)))
+  "AST node representing a parse error.")
+
+(js2--struct-put 'js2-error-node 'js2-visitor 'js2-visit-none)
+(js2--struct-put 'js2-error-node 'js2-printer 'js2-print-none)
+
+(cl-defstruct (js2-script-node
+               (:include js2-scope)
+               (:constructor make-js2-script-node (&key (type js2-SCRIPT)
+                                                        (pos (js2-current-token-beg))
+                                                        len)))
+  functions   ; Lisp list of nested functions
+  regexps     ; Lisp list of (string . flags)
+  symbols     ; alist (every symbol gets unique index)
+  (param-count 0)
+  var-names   ; vector of string names
+  consts      ; bool-vector matching var-decls
+  (temp-number 0))  ; for generating temp variables
+
+(js2--struct-put 'js2-script-node 'js2-visitor 'js2-visit-block)
+(js2--struct-put 'js2-script-node 'js2-printer 'js2-print-script)
+
+(defun js2-print-script (node indent)
+  (dolist (kid (js2-block-node-kids node))
+    (js2-print-ast kid indent)))
+
+(cl-defstruct (js2-ast-root
+               (:include js2-script-node)
+               (:constructor make-js2-ast-root (&key (type js2-SCRIPT)
+                                                     (pos (js2-current-token-beg))
+                                                     len
+                                                     buffer)))
+  "The root node of a js2 AST."
+  buffer         ; the source buffer from which the code was parsed
+  comments       ; a Lisp list of comments, ordered by start position
+  errors         ; a Lisp list of errors found during parsing
+  warnings       ; a Lisp list of warnings found during parsing
+  node-count)    ; number of nodes in the tree, including the root
+
+(js2--struct-put 'js2-ast-root 'js2-visitor 'js2-visit-ast-root)
+(js2--struct-put 'js2-ast-root 'js2-printer 'js2-print-script)
+
+(defun js2-visit-ast-root (ast callback)
+  (dolist (kid (js2-ast-root-kids ast))
+    (js2-visit-ast kid callback))
+  (dolist (comment (js2-ast-root-comments ast))
+    (js2-visit-ast comment callback)))
+
+(cl-defstruct (js2-comment-node
+               (:include js2-node)
+               (:constructor make-js2-comment-node (&key (type js2-COMMENT)
+                                                         (pos (js2-current-token-beg))
+                                                         len
+                                                         format)))
+  format)  ; 'line, 'block, 'jsdoc or 'html
+
+(js2--struct-put 'js2-comment-node 'js2-visitor 'js2-visit-none)
+(js2--struct-put 'js2-comment-node 'js2-printer 'js2-print-comment)
+
+(defun js2-print-comment (n i)
+  ;; We really ought to link end-of-line comments to their nodes.
+  ;; Or maybe we could add a new comment type, 'endline.
+  (insert (js2-make-pad i)
+          (js2-node-string n)))
+
+(cl-defstruct (js2-expr-stmt-node
+               (:include js2-node)
+               (:constructor make-js2-expr-stmt-node (&key (type js2-EXPR_VOID)
+                                                           (pos js2-ts-cursor)
+                                                           len
+                                                           expr)))
+  "An expression statement."
+  expr)
+
+(defsubst js2-expr-stmt-node-set-has-result (node)
+  "Change NODE type to `js2-EXPR_RESULT'.  Used for code generation."
+  (setf (js2-node-type node) js2-EXPR_RESULT))
+
+(js2--struct-put 'js2-expr-stmt-node 'js2-visitor 'js2-visit-expr-stmt-node)
+(js2--struct-put 'js2-expr-stmt-node 'js2-printer 'js2-print-expr-stmt-node)
+
+(defun js2-visit-expr-stmt-node (n v)
+  (js2-visit-ast (js2-expr-stmt-node-expr n) v))
+
+(defun js2-print-expr-stmt-node (n indent)
+  (js2-print-ast (js2-expr-stmt-node-expr n) indent)
+  (insert ";\n"))
+
+(cl-defstruct (js2-loop-node
+               (:include js2-scope)
+               (:constructor nil))
+  "Abstract supertype of loop nodes."
+  body      ; a `js2-block-node'
+  lp        ; position of left-paren, nil if omitted
+  rp)       ; position of right-paren, nil if omitted
+
+(cl-defstruct (js2-do-node
+               (:include js2-loop-node)
+               (:constructor make-js2-do-node (&key (type js2-DO)
+                                                    (pos (js2-current-token-beg))
+                                                    len
+                                                    body
+                                                    condition
+                                                    while-pos
+                                                    lp
+                                                    rp)))
+  "AST node for do-loop."
+  condition  ; while (expression)
+  while-pos) ; buffer position of 'while' keyword
+
+(js2--struct-put 'js2-do-node 'js2-visitor 'js2-visit-do-node)
+(js2--struct-put 'js2-do-node 'js2-printer 'js2-print-do-node)
+
+(defun js2-visit-do-node (n v)
+  (js2-visit-ast (js2-do-node-body n) v)
+  (js2-visit-ast (js2-do-node-condition n) v))
+
+(defun js2-print-do-node (n i)
+  (let ((pad (js2-make-pad i)))
+    (insert pad "do {\n")
+    (dolist (kid (js2-block-node-kids (js2-do-node-body n)))
+      (js2-print-ast kid (1+ i)))
+    (insert pad "} while (")
+    (js2-print-ast (js2-do-node-condition n) 0)
+    (insert ");\n")))
+
+(cl-defstruct (js2-export-node
+               (:include js2-node)
+               (:constructor make-js2-export-node (&key (type js2-EXPORT)
+                                                        (pos (js2-current-token-beg))
+                                                        len
+                                                        exports-list
+                                                        from-clause
+                                                        declaration
+                                                        default)))
+  "AST node for an export statement. There are many things that can be exported,
+so many of its properties will be nil.
+"
+  exports-list ; lisp list of js2-export-binding-node to export
+  from-clause ; js2-from-clause-node for re-exporting symbols from another module
+  declaration ; js2-var-decl-node (var, let, const) or js2-class-node
+  default) ; js2-function-node or js2-assign-node
+
+(js2--struct-put 'js2-export-node 'js2-visitor 'js2-visit-export-node)
+(js2--struct-put 'js2-export-node 'js2-printer 'js2-print-export-node)
+
+(defun js2-visit-export-node (n v)
+  (let ((exports-list (js2-export-node-exports-list n))
+        (from (js2-export-node-from-clause n))
+        (declaration (js2-export-node-declaration n))
+        (default (js2-export-node-default n)))
+    (when exports-list
+      (dolist (export exports-list)
+        (js2-visit-ast export v)))
+    (when from
+      (js2-visit-ast from v))
+    (when declaration
+      (js2-visit-ast declaration v))
+    (when default
+      (js2-visit-ast default v))))
+
+(defun js2-print-export-node (n i)
+  (let ((pad (js2-make-pad i))
+        (exports-list (js2-export-node-exports-list n))
+        (from (js2-export-node-from-clause n))
+        (declaration (js2-export-node-declaration n))
+        (default (js2-export-node-default n)))
+    (insert pad "export ")
+    (cond
+     (default
+       (insert "default ")
+       (js2-print-ast default i))
+     (declaration
+       (js2-print-ast declaration i))
+     ((and exports-list from)
+      (js2-print-named-imports exports-list)
+      (insert " ")
+      (js2-print-from-clause from))
+     (from
+      (insert "* ")
+      (js2-print-from-clause from))
+     (exports-list
+      (js2-print-named-imports exports-list)))
+    (unless (or (and default (not (js2-assign-node-p default)))
+                (and declaration (or (js2-function-node-p declaration)
+                                     (js2-class-node-p declaration))))
+      (insert ";\n"))))
+
+(cl-defstruct (js2-while-node
+               (:include js2-loop-node)
+               (:constructor make-js2-while-node (&key (type js2-WHILE)
+                                                       (pos (js2-current-token-beg))
+                                                       len body
+                                                       condition lp
+                                                       rp)))
+  "AST node for while-loop."
+  condition)    ; while-condition
+
+(js2--struct-put 'js2-while-node 'js2-visitor 'js2-visit-while-node)
+(js2--struct-put 'js2-while-node 'js2-printer 'js2-print-while-node)
+
+(defun js2-visit-while-node (n v)
+  (js2-visit-ast (js2-while-node-condition n) v)
+  (js2-visit-ast (js2-while-node-body n) v))
+
+(defun js2-print-while-node (n i)
+  (let ((pad (js2-make-pad i)))
+    (insert pad "while (")
+    (js2-print-ast (js2-while-node-condition n) 0)
+    (insert ") {\n")
+    (js2-print-body (js2-while-node-body n) (1+ i))
+    (insert pad "}\n")))
+
+(cl-defstruct (js2-for-node
+               (:include js2-loop-node)
+               (:constructor make-js2-for-node (&key (type js2-FOR)
+                                                     (pos js2-ts-cursor)
+                                                     len body init
+                                                     condition
+                                                     update lp rp)))
+  "AST node for a C-style for-loop."
+  init       ; initialization expression
+  condition  ; loop condition
+  update)    ; update clause
+
+(js2--struct-put 'js2-for-node 'js2-visitor 'js2-visit-for-node)
+(js2--struct-put 'js2-for-node 'js2-printer 'js2-print-for-node)
+
+(defun js2-visit-for-node (n v)
+  (js2-visit-ast (js2-for-node-init n) v)
+  (js2-visit-ast (js2-for-node-condition n) v)
+  (js2-visit-ast (js2-for-node-update n) v)
+  (js2-visit-ast (js2-for-node-body n) v))
+
+(defun js2-print-for-node (n i)
+  (let ((pad (js2-make-pad i)))
+    (insert pad "for (")
+    (js2-print-ast (js2-for-node-init n) 0)
+    (insert "; ")
+    (js2-print-ast (js2-for-node-condition n) 0)
+    (insert "; ")
+    (js2-print-ast (js2-for-node-update n) 0)
+    (insert ") {\n")
+    (js2-print-body (js2-for-node-body n) (1+ i))
+    (insert pad "}\n")))
+
+(cl-defstruct (js2-for-in-node
+               (:include js2-loop-node)
+               (:constructor make-js2-for-in-node (&key (type js2-FOR)
+                                                        (pos js2-ts-cursor)
+                                                        len body
+                                                        iterator
+                                                        object
+                                                        in-pos
+                                                        each-pos
+                                                        foreach-p forof-p
+                                                        lp rp)))
+  "AST node for a for..in loop."
+  iterator  ; [var] foo in ...
+  object    ; object over which we're iterating
+  in-pos    ; buffer position of 'in' keyword
+  each-pos  ; buffer position of 'each' keyword, if foreach-p
+  foreach-p ; t if it's a for-each loop
+  forof-p)  ; t if it's a for-of loop
+
+(js2--struct-put 'js2-for-in-node 'js2-visitor 'js2-visit-for-in-node)
+(js2--struct-put 'js2-for-in-node 'js2-printer 'js2-print-for-in-node)
+
+(defun js2-visit-for-in-node (n v)
+  (js2-visit-ast (js2-for-in-node-iterator n) v)
+  (js2-visit-ast (js2-for-in-node-object n) v)
+  (js2-visit-ast (js2-for-in-node-body n) v))
+
+(defun js2-print-for-in-node (n i)
+  (let ((pad (js2-make-pad i))
+        (foreach (js2-for-in-node-foreach-p n))
+        (forof (js2-for-in-node-forof-p n)))
+    (insert pad "for ")
+    (if foreach
+        (insert "each "))
+    (insert "(")
+    (js2-print-ast (js2-for-in-node-iterator n) 0)
+    (insert (if forof " of " " in "))
+    (js2-print-ast (js2-for-in-node-object n) 0)
+    (insert ") {\n")
+    (js2-print-body (js2-for-in-node-body n) (1+ i))
+    (insert pad "}\n")))
+
+(cl-defstruct (js2-return-node
+               (:include js2-node)
+               (:constructor make-js2-return-node (&key (type js2-RETURN)
+                                                        (pos js2-ts-cursor)
+                                                        len
+                                                        retval)))
+  "AST node for a return statement."
+  retval)  ; expression to return, or 'undefined
+
+(js2--struct-put 'js2-return-node 'js2-visitor 'js2-visit-return-node)
+(js2--struct-put 'js2-return-node 'js2-printer 'js2-print-return-node)
+
+(defun js2-visit-return-node (n v)
+  (js2-visit-ast (js2-return-node-retval n) v))
+
+(defun js2-print-return-node (n i)
+  (insert (js2-make-pad i) "return")
+  (when (js2-return-node-retval n)
+    (insert " ")
+    (js2-print-ast (js2-return-node-retval n) 0))
+  (insert ";\n"))
+
+(cl-defstruct (js2-if-node
+               (:include js2-node)
+               (:constructor make-js2-if-node (&key (type js2-IF)
+                                                    (pos js2-ts-cursor)
+                                                    len condition
+                                                    then-part
+                                                    else-pos
+                                                    else-part lp
+                                                    rp)))
+  "AST node for an if-statement."
+  condition   ; expression
+  then-part   ; statement or block
+  else-pos    ; optional buffer position of 'else' keyword
+  else-part   ; optional statement or block
+  lp          ; position of left-paren, nil if omitted
+  rp)         ; position of right-paren, nil if omitted
+
+(js2--struct-put 'js2-if-node 'js2-visitor 'js2-visit-if-node)
+(js2--struct-put 'js2-if-node 'js2-printer 'js2-print-if-node)
+
+(defun js2-visit-if-node (n v)
+  (js2-visit-ast (js2-if-node-condition n) v)
+  (js2-visit-ast (js2-if-node-then-part n) v)
+  (js2-visit-ast (js2-if-node-else-part n) v))
+
+(defun js2-print-if-node (n i)
+  (let ((pad (js2-make-pad i))
+        (then-part (js2-if-node-then-part n))
+        (else-part (js2-if-node-else-part n)))
+    (insert pad "if (")
+    (js2-print-ast (js2-if-node-condition n) 0)
+    (insert ") {\n")
+    (js2-print-body then-part (1+ i))
+    (insert pad "}")
+    (cond
+     ((not else-part)
+      (insert "\n"))
+     ((js2-if-node-p else-part)
+      (insert " else ")
+      (js2-print-body else-part i))
+     (t
+      (insert " else {\n")
+      (js2-print-body else-part (1+ i))
+      (insert pad "}\n")))))
+
+(cl-defstruct (js2-export-binding-node
+               (:include js2-node)
+               (:constructor make-js2-export-binding-node (&key (type -1)
+                                                                pos
+                                                                len
+                                                                local-name
+                                                                extern-name)))
+  "AST node for an external symbol binding.
+It contains a local-name node which is the name of the value in the
+current scope, and extern-name which is the name of the value in the
+imported or exported scope. By default these are the same, but if the
+name is aliased as in {foo as bar}, it would have an extern-name node
+containing 'foo' and a local-name node containing 'bar'."
+  local-name ; js2-name-node with the variable name in this scope
+  extern-name)   ; js2-name-node with the value name in the exporting module
+
+(js2--struct-put 'js2-export-binding-node 'js2-printer 'js2-print-extern-binding)
+(js2--struct-put 'js2-export-binding-node 'js2-visitor 'js2-visit-extern-binding)
+
+(defun js2-visit-extern-binding (n v)
+  "Visit an extern binding node. First visit the local-name, and, if
+different, visit the extern-name."
+  (let ((local-name (js2-export-binding-node-local-name n))
+        (extern-name (js2-export-binding-node-extern-name n)))
+    (when local-name
+      (js2-visit-ast local-name v))
+    (when (not (equal local-name extern-name))
+      (js2-visit-ast extern-name v))))
+
+(defun js2-print-extern-binding (n _i)
+  "Print a representation of a single extern binding. E.g. 'foo' or
+'foo as bar'."
+  (let ((local-name (js2-export-binding-node-local-name n))
+        (extern-name (js2-export-binding-node-extern-name n)))
+    (insert (js2-name-node-name extern-name))
+    (when (not (equal local-name extern-name))
+      (insert " as ")
+      (insert (js2-name-node-name local-name)))))
+
+
+(cl-defstruct (js2-import-node
+               (:include js2-node)
+               (:constructor make-js2-import-node (&key (type js2-IMPORT)
+                                                        (pos (js2-current-token-beg))
+                                                        len
+                                                        import
+                                                        from
+                                                        module-id)))
+  "AST node for an import statement. It follows the form
+
+import ModuleSpecifier;
+import ImportClause FromClause;"
+  import     ; js2-import-clause-node specifying which names are to imported.
+  from       ; js2-from-clause-node indicating the module from which to import.
+  module-id) ; module-id of the import. E.g. 'src/mylib'.
+
+(js2--struct-put 'js2-import-node 'js2-printer 'js2-print-import)
+(js2--struct-put 'js2-import-node 'js2-visitor 'js2-visit-import)
+
+(defun js2-visit-import (n v)
+  (let ((import-clause (js2-import-node-import n))
+        (from-clause (js2-import-node-from n)))
+    (when import-clause
+      (js2-visit-ast import-clause v))
+    (when from-clause
+      (js2-visit-ast from-clause v))))
+
+(defun js2-print-import (n i)
+  "Prints a representation of the import node"
+  (let ((pad (js2-make-pad i))
+        (import-clause (js2-import-node-import n))
+        (from-clause (js2-import-node-from n))
+        (module-id (js2-import-node-module-id n)))
+    (insert pad "import ")
+    (if import-clause
+        (progn
+          (js2-print-import-clause import-clause)
+          (insert " ")
+          (js2-print-from-clause from-clause))
+      (insert "'")
+      (insert module-id)
+      (insert "'"))
+    (insert ";\n")))
+
+(cl-defstruct (js2-import-clause-node
+               (:include js2-node)
+               (:constructor make-js2-import-clause-node (&key (type -1)
+                                                               pos
+                                                               len
+                                                               namespace-import
+                                                               named-imports
+                                                               default-binding)))
+  "AST node corresponding to the import clause of an import statement. This is
+the portion of the import that bindings names from the external context to the
+local context."
+  namespace-import ; js2-namespace-import-node. E.g. '* as lib'
+  named-imports    ; lisp list of js2-export-binding-node for all named imports.
+  default-binding) ; js2-export-binding-node for the default import binding
+
+(js2--struct-put 'js2-import-clause-node 'js2-visitor 'js2-visit-import-clause)
+(js2--struct-put 'js2-import-clause-node 'js2-printer 'js2-print-import-clause)
+
+(defun js2-visit-import-clause (n v)
+  (let ((ns-import (js2-import-clause-node-namespace-import n))
+        (named-imports (js2-import-clause-node-named-imports n))
+        (default (js2-import-clause-node-default-binding n)))
+    (when default
+      (js2-visit-ast default v))
+    (when ns-import
+      (js2-visit-ast ns-import v))
+    (when named-imports
+      (dolist (import named-imports)
+        (js2-visit-ast import v)))))
+
+(defun js2-print-import-clause (n)
+  (let ((ns-import (js2-import-clause-node-namespace-import n))
+        (named-imports (js2-import-clause-node-named-imports n))
+        (default (js2-import-clause-node-default-binding n)))
+    (cond
+     ((and default ns-import)
+      (js2-print-ast default)
+      (insert ", ")
+      (js2-print-namespace-import ns-import))
+     ((and default named-imports)
+      (js2-print-ast default)
+      (insert ", ")
+      (js2-print-named-imports named-imports))
+     (default
+      (js2-print-ast default))
+     (ns-import
+      (js2-print-namespace-import ns-import))
+     (named-imports
+      (js2-print-named-imports named-imports)))))
+
+(defun js2-print-namespace-import (node)
+  (insert "* as ")
+  (insert (js2-name-node-name (js2-namespace-import-node-name node))))
+
+(defun js2-print-named-imports (imports)
+  (insert "{")
+  (let ((len (length imports))
+        (n 0))
+    (while (< n len)
+      (js2-print-extern-binding (nth n imports) 0)
+      (unless (= n (- len 1))
+        (insert ", "))
+      (setq n (+ n 1))))
+  (insert "}"))
+
+(cl-defstruct (js2-namespace-import-node
+               (:include js2-node)
+               (:constructor make-js2-namespace-import-node (&key (type -1)
+                                                                  pos
+                                                                  len
+                                                                  name)))
+  "AST node for a complete namespace import.
+E.g. the '* as lib' expression in:
+
+import * as lib from 'src/lib'
+
+It contains a single name node referring to the bound name."
+  name) ; js2-name-node of the bound name.
+
+(defun js2-visit-namespace-import (n v)
+  (js2-visit-ast (js2-namespace-import-node-name n) v))
+
+(js2--struct-put 'js2-namespace-import-node 'js2-visitor 'js2-visit-namespace-import)
+(js2--struct-put 'js2-namespace-import-node 'js2-printer 'js2-print-namespace-import)
+
+(cl-defstruct (js2-from-clause-node
+               (:include js2-node)
+               (:constructor make-js2-from-clause-node (&key (type js2-NAME)
+                                                             pos
+                                                             len
+                                                             module-id
+                                                             metadata-p)))
+  "AST node for the from clause in an import or export statement.
+E.g. from 'my/module'. It can refere to either an external module, or to the
+modules metadata itself."
+  module-id ; string containing the module specifier.
+  metadata-p) ; true if this clause refers to the module's metadata
+
+(js2--struct-put 'js2-from-clause-node 'js2-visitor 'js2-visit-none)
+(js2--struct-put 'js2-from-clause-node 'js2-printer 'js2-print-from-clause)
+
+(defun js2-print-from-clause (n)
+  (insert "from ")
+  (if (js2-from-clause-node-metadata-p n)
+      (insert "this module")
+    (insert "'")
+    (insert (js2-from-clause-node-module-id n))
+    (insert "'")))
+
+(cl-defstruct (js2-try-node
+               (:include js2-node)
+               (:constructor make-js2-try-node (&key (type js2-TRY)
+                                                     (pos js2-ts-cursor)
+                                                     len
+                                                     try-block
+                                                     catch-clauses
+                                                     finally-block)))
+  "AST node for a try-statement."
+  try-block
+  catch-clauses  ; a Lisp list of `js2-catch-node'
+  finally-block) ; a `js2-finally-node'
+
+(js2--struct-put 'js2-try-node 'js2-visitor 'js2-visit-try-node)
+(js2--struct-put 'js2-try-node 'js2-printer 'js2-print-try-node)
+
+(defun js2-visit-try-node (n v)
+  (js2-visit-ast (js2-try-node-try-block n) v)
+  (dolist (clause (js2-try-node-catch-clauses n))
+    (js2-visit-ast clause v))
+  (js2-visit-ast (js2-try-node-finally-block n) v))
+
+(defun js2-print-try-node (n i)
+  (let ((pad (js2-make-pad i))
+        (catches (js2-try-node-catch-clauses n))
+        (finally (js2-try-node-finally-block n)))
+    (insert pad "try {\n")
+    (js2-print-body (js2-try-node-try-block n) (1+ i))
+    (insert pad "}")
+    (when catches
+      (dolist (catch catches)
+        (js2-print-ast catch i)))
+    (if finally
+        (js2-print-ast finally i)
+      (insert "\n"))))
+
+(cl-defstruct (js2-catch-node
+               (:include js2-scope)
+               (:constructor make-js2-catch-node (&key (type js2-CATCH)
+                                                       (pos js2-ts-cursor)
+                                                       len
+                                                       param
+                                                       guard-kwd
+                                                       guard-expr
+                                                       lp rp)))
+  "AST node for a catch clause."
+  param       ; destructuring form or simple name node
+  guard-kwd   ; relative buffer position of "if" in "catch (x if ...)"
+  guard-expr  ; catch condition, a `js2-node'
+  lp          ; buffer position of left-paren, nil if omitted
+  rp)         ; buffer position of right-paren, nil if omitted
+
+(js2--struct-put 'js2-catch-node 'js2-visitor 'js2-visit-catch-node)
+(js2--struct-put 'js2-catch-node 'js2-printer 'js2-print-catch-node)
+
+(defun js2-visit-catch-node (n v)
+  (js2-visit-ast (js2-catch-node-param n) v)
+  (when (js2-catch-node-guard-kwd n)
+    (js2-visit-ast (js2-catch-node-guard-expr n) v))
+  (js2-visit-block n v))
+
+(defun js2-print-catch-node (n i)
+  (let ((pad (js2-make-pad i))
+        (guard-kwd (js2-catch-node-guard-kwd n))
+        (guard-expr (js2-catch-node-guard-expr n)))
+    (insert " catch (")
+    (js2-print-ast (js2-catch-node-param n) 0)
+    (when guard-kwd
+      (insert " if ")
+      (js2-print-ast guard-expr 0))
+    (insert ") {\n")
+    (js2-print-body n (1+ i))
+    (insert pad "}")))
+
+(cl-defstruct (js2-finally-node
+               (:include js2-node)
+               (:constructor make-js2-finally-node (&key (type js2-FINALLY)
+                                                         (pos js2-ts-cursor)
+                                                         len body)))
+  "AST node for a finally clause."
+  body)  ; a `js2-node', often but not always a block node
+
+(js2--struct-put 'js2-finally-node 'js2-visitor 'js2-visit-finally-node)
+(js2--struct-put 'js2-finally-node 'js2-printer 'js2-print-finally-node)
+
+(defun js2-visit-finally-node (n v)
+  (js2-visit-ast (js2-finally-node-body n) v))
+
+(defun js2-print-finally-node (n i)
+  (let ((pad (js2-make-pad i)))
+    (insert " finally {\n")
+    (js2-print-body (js2-finally-node-body n) (1+ i))
+    (insert pad "}\n")))
+
+(cl-defstruct (js2-switch-node
+               (:include js2-scope)
+               (:constructor make-js2-switch-node (&key (type js2-SWITCH)
+                                                        (pos js2-ts-cursor)
+                                                        len
+                                                        discriminant
+                                                        cases lp
+                                                        rp)))
+  "AST node for a switch statement."
+  discriminant  ; a `js2-node' (switch expression)
+  cases  ; a Lisp list of `js2-case-node'
+  lp     ; position of open-paren for discriminant, nil if omitted
+  rp)    ; position of close-paren for discriminant, nil if omitted
+
+(js2--struct-put 'js2-switch-node 'js2-visitor 'js2-visit-switch-node)
+(js2--struct-put 'js2-switch-node 'js2-printer 'js2-print-switch-node)
+
+(defun js2-visit-switch-node (n v)
+  (js2-visit-ast (js2-switch-node-discriminant n) v)
+  (dolist (c (js2-switch-node-cases n))
+    (js2-visit-ast c v)))
+
+(defun js2-print-switch-node (n i)
+  (let ((pad (js2-make-pad i))
+        (cases (js2-switch-node-cases n)))
+    (insert pad "switch (")
+    (js2-print-ast (js2-switch-node-discriminant n) 0)
+    (insert ") {\n")
+    (dolist (case cases)
+      (js2-print-ast case i))
+    (insert pad "}\n")))
+
+(cl-defstruct (js2-case-node
+               (:include js2-block-node)
+               (:constructor make-js2-case-node (&key (type js2-CASE)
+                                                      (pos js2-ts-cursor)
+                                                      len kids expr)))
+  "AST node for a case clause of a switch statement."
+  expr)   ; the case expression (nil for default)
+
+(js2--struct-put 'js2-case-node 'js2-visitor 'js2-visit-case-node)
+(js2--struct-put 'js2-case-node 'js2-printer 'js2-print-case-node)
+
+(defun js2-visit-case-node (n v)
+  (js2-visit-ast (js2-case-node-expr n) v)
+  (js2-visit-block n v))
+
+(defun js2-print-case-node (n i)
+  (let ((pad (js2-make-pad i))
+        (expr (js2-case-node-expr n)))
+    (insert pad)
+    (if (null expr)
+        (insert "default:\n")
+      (insert "case ")
+      (js2-print-ast expr 0)
+      (insert ":\n"))
+    (dolist (kid (js2-case-node-kids n))
+      (js2-print-ast kid (1+ i)))))
+
+(cl-defstruct (js2-throw-node
+               (:include js2-node)
+               (:constructor make-js2-throw-node (&key (type js2-THROW)
+                                                       (pos js2-ts-cursor)
+                                                       len expr)))
+  "AST node for a throw statement."
+  expr)   ; the expression to throw
+
+(js2--struct-put 'js2-throw-node 'js2-visitor 'js2-visit-throw-node)
+(js2--struct-put 'js2-throw-node 'js2-printer 'js2-print-throw-node)
+
+(defun js2-visit-throw-node (n v)
+  (js2-visit-ast (js2-throw-node-expr n) v))
+
+(defun js2-print-throw-node (n i)
+  (insert (js2-make-pad i) "throw ")
+  (js2-print-ast (js2-throw-node-expr n) 0)
+  (insert ";\n"))
+
+(cl-defstruct (js2-with-node
+               (:include js2-node)
+               (:constructor make-js2-with-node (&key (type js2-WITH)
+                                                      (pos js2-ts-cursor)
+                                                      len object
+                                                      body lp rp)))
+  "AST node for a with-statement."
+  object
+  body
+  lp    ; buffer position of left-paren around object, nil if omitted
+  rp)   ; buffer position of right-paren around object, nil if omitted
+
+(js2--struct-put 'js2-with-node 'js2-visitor 'js2-visit-with-node)
+(js2--struct-put 'js2-with-node 'js2-printer 'js2-print-with-node)
+
+(defun js2-visit-with-node (n v)
+  (js2-visit-ast (js2-with-node-object n) v)
+  (js2-visit-ast (js2-with-node-body n) v))
+
+(defun js2-print-with-node (n i)
+  (let ((pad (js2-make-pad i)))
+    (insert pad "with (")
+    (js2-print-ast (js2-with-node-object n) 0)
+    (insert ") {\n")
+    (js2-print-body (js2-with-node-body n) (1+ i))
+    (insert pad "}\n")))
+
+(cl-defstruct (js2-label-node
+               (:include js2-node)
+               (:constructor make-js2-label-node (&key (type js2-LABEL)
+                                                       (pos js2-ts-cursor)
+                                                       len name)))
+  "AST node for a statement label or case label."
+  name   ; a string
+  loop)  ; for validating and code-generating continue-to-label
+
+(js2--struct-put 'js2-label-node 'js2-visitor 'js2-visit-none)
+(js2--struct-put 'js2-label-node 'js2-printer 'js2-print-label)
+
+(defun js2-print-label (n i)
+  (insert (js2-make-pad i)
+          (js2-label-node-name n)
+          ":\n"))
+
+(cl-defstruct (js2-labeled-stmt-node
+               (:include js2-node)
+               ;; type needs to be in `js2-side-effecting-tokens' to avoid spurious
+               ;; no-side-effects warnings, hence js2-EXPR_RESULT.
+               (:constructor make-js2-labeled-stmt-node (&key (type js2-EXPR_RESULT)
+                                                              (pos js2-ts-cursor)
+                                                              len labels stmt)))
+  "AST node for a statement with one or more labels.
+Multiple labels for a statement are collapsed into the labels field."
+  labels  ; Lisp list of `js2-label-node'
+  stmt)   ; the statement these labels are for
+
+(js2--struct-put 'js2-labeled-stmt-node 'js2-visitor 'js2-visit-labeled-stmt)
+(js2--struct-put 'js2-labeled-stmt-node 'js2-printer 'js2-print-labeled-stmt)
+
+(defun js2-get-label-by-name (lbl-stmt name)
+  "Return a `js2-label-node' by NAME from LBL-STMT's labels list.
+Returns nil if no such label is in the list."
+  (let ((label-list (js2-labeled-stmt-node-labels lbl-stmt))
+        result)
+    (while (and label-list (not result))
+      (if (string= (js2-label-node-name (car label-list)) name)
+          (setq result (car label-list))
+        (setq label-list (cdr label-list))))
+    result))
+
+(defun js2-visit-labeled-stmt (n v)
+  (dolist (label (js2-labeled-stmt-node-labels n))
+    (js2-visit-ast label v))
+  (js2-visit-ast (js2-labeled-stmt-node-stmt n) v))
+
+(defun js2-print-labeled-stmt (n i)
+  (dolist (label (js2-labeled-stmt-node-labels n))
+    (js2-print-ast label i))
+  (js2-print-ast (js2-labeled-stmt-node-stmt n) i))
+
+(defun js2-labeled-stmt-node-contains (node label)
+  "Return t if NODE contains LABEL in its label set.
+NODE is a `js2-labels-node'.  LABEL is an identifier."
+  (cl-loop for nl in (js2-labeled-stmt-node-labels node)
+           if (string= label (js2-label-node-name nl))
+           return t
+           finally return nil))
+
+(defsubst js2-labeled-stmt-node-add-label (node label)
+  "Add a `js2-label-node' to the label set for this statement."
+  (setf (js2-labeled-stmt-node-labels node)
+        (nconc (js2-labeled-stmt-node-labels node) (list label))))
+
+(cl-defstruct (js2-jump-node
+               (:include js2-node)
+               (:constructor nil))
+  "Abstract supertype of break and continue nodes."
+  label   ; `js2-name-node' for location of label identifier, if present
+  target) ; target js2-labels-node or loop/switch statement
+
+(defun js2-visit-jump-node (n v)
+  ;; We don't visit the target, since it's a back-link.
+  (js2-visit-ast (js2-jump-node-label n) v))
+
+(cl-defstruct (js2-break-node
+               (:include js2-jump-node)
+               (:constructor make-js2-break-node (&key (type js2-BREAK)
+                                                       (pos js2-ts-cursor)
+                                                       len label target)))
+  "AST node for a break statement.
+The label field is a `js2-name-node', possibly nil, for the named label
+if provided.  E.g. in 'break foo', it represents 'foo'.  The target field
+is the target of the break - a label node or enclosing loop/switch statement.")
+
+(js2--struct-put 'js2-break-node 'js2-visitor 'js2-visit-jump-node)
+(js2--struct-put 'js2-break-node 'js2-printer 'js2-print-break-node)
+
+(defun js2-print-break-node (n i)
+  (insert (js2-make-pad i) "break")
+  (when (js2-break-node-label n)
+    (insert " ")
+    (js2-print-ast (js2-break-node-label n) 0))
+  (insert ";\n"))
+
+(cl-defstruct (js2-continue-node
+               (:include js2-jump-node)
+               (:constructor make-js2-continue-node (&key (type js2-CONTINUE)
+                                                          (pos js2-ts-cursor)
+                                                          len label target)))
+  "AST node for a continue statement.
+The label field is the user-supplied enclosing label name, a `js2-name-node'.
+It is nil if continue specifies no label.  The target field is the jump target:
+a `js2-label-node' or the innermost enclosing loop.")
+
+(js2--struct-put 'js2-continue-node 'js2-visitor 'js2-visit-jump-node)
+(js2--struct-put 'js2-continue-node 'js2-printer 'js2-print-continue-node)
+
+(defun js2-print-continue-node (n i)
+  (insert (js2-make-pad i) "continue")
+  (when (js2-continue-node-label n)
+    (insert " ")
+    (js2-print-ast (js2-continue-node-label n) 0))
+  (insert ";\n"))
+
+(cl-defstruct (js2-function-node
+               (:include js2-script-node)
+               (:constructor make-js2-function-node (&key (type js2-FUNCTION)
+                                                          (pos js2-ts-cursor)
+                                                          len
+                                                          (ftype 'FUNCTION)
+                                                          (form 'FUNCTION_STATEMENT)
+                                                          (name "")
+                                                          params rest-p
+                                                          body
+                                                          generator-type
+                                                          async
+                                                          lp rp)))
+  "AST node for a function declaration.
+The `params' field is a Lisp list of nodes.  Each node is either a simple
+`js2-name-node', or if it's a destructuring-assignment parameter, a
+`js2-array-node' or `js2-object-node'."
+  ftype            ; FUNCTION, GETTER or SETTER
+  form             ; FUNCTION_{STATEMENT|EXPRESSION|ARROW}
+  name             ; function name (a `js2-name-node', or nil if anonymous)
+  params           ; a Lisp list of destructuring forms or simple name nodes
+  rest-p           ; if t, the last parameter is rest parameter
+  body             ; a `js2-block-node' or expression node (1.8 only)
+  lp               ; position of arg-list open-paren, or nil if omitted
+  rp               ; position of arg-list close-paren, or nil if omitted
+  ignore-dynamic   ; ignore value of the dynamic-scope flag (interpreter only)
+  needs-activation ; t if we need an activation object for this frame
+  generator-type   ; STAR, LEGACY, COMPREHENSION or nil
+  async            ; t if the function is defined as `async function`
+  member-expr)     ; nonstandard Ecma extension from Rhino
+
+(js2--struct-put 'js2-function-node 'js2-visitor 'js2-visit-function-node)
+(js2--struct-put 'js2-function-node 'js2-printer 'js2-print-function-node)
+
+(defun js2-visit-function-node (n v)
+  (js2-visit-ast (js2-function-node-name n) v)
+  (dolist (p (js2-function-node-params n))
+    (js2-visit-ast p v))
+  (js2-visit-ast (js2-function-node-body n) v))
+
+(defun js2-print-function-node (n i)
+  (let* ((pad (js2-make-pad i))
+         (method (js2-node-get-prop n 'METHOD_TYPE))
+         (name (or (js2-function-node-name n)
+                   (js2-function-node-member-expr n)))
+         (params (js2-function-node-params n))
+         (arrow (eq (js2-function-node-form n) 'FUNCTION_ARROW))
+         (rest-p (js2-function-node-rest-p n))
+         (body (js2-function-node-body n))
+         (expr (not (eq (js2-function-node-form n) 'FUNCTION_STATEMENT))))
+    (unless method
+      (insert pad)
+      (when (js2-function-node-async n) (insert "async "))
+      (unless arrow (insert "function"))
+      (when (eq (js2-function-node-generator-type n) 'STAR)
+        (insert "*")))
+    (when name
+      (insert " ")
+      (js2-print-ast name 0))
+    (insert "(")
+    (cl-loop with len = (length params)
+             for param in params
+             for count from 1
+             do
+             (when (and rest-p (= count len))
+               (insert "..."))
+             (js2-print-ast param 0)
+             (when (< count len)
+               (insert ", ")))
+    (insert ") ")
+    (when arrow
+      (insert "=> "))
+    (insert "{")
+    ;; TODO:  fix this to be smarter about indenting, etc.
+    (unless expr
+      (insert "\n"))
+    (if (js2-block-node-p body)
+        (js2-print-body body (1+ i))
+      (js2-print-ast body 0))
+    (insert pad "}")
+    (unless expr
+      (insert "\n"))))
+
+(defun js2-function-name (node)
+  "Return function name for NODE, a `js2-function-node', or nil if anonymous."
+  (and (js2-function-node-name node)
+       (js2-name-node-name (js2-function-node-name node))))
+
+;; Having this be an expression node makes it more flexible.
+;; There are IDE contexts, such as indentation in a for-loop initializer,
+;; that work better if you assume it's an expression.  Whenever we have
+;; a standalone var/const declaration, we just wrap with an expr stmt.
+;; Eclipse apparently screwed this up and now has two versions, expr and stmt.
+(cl-defstruct (js2-var-decl-node
+               (:include js2-node)
+               (:constructor make-js2-var-decl-node (&key (type js2-VAR)
+                                                          (pos (js2-current-token-beg))
+                                                          len kids
+                                                          decl-type)))
+  "AST node for a variable declaration list (VAR, CONST or LET).
+The node bounds differ depending on the declaration type.  For VAR or
+CONST declarations, the bounds include the var/const keyword.  For LET
+declarations, the node begins at the position of the first child."
+  kids        ; a Lisp list of `js2-var-init-node' structs.
+  decl-type)  ; js2-VAR, js2-CONST or js2-LET
+
+(js2--struct-put 'js2-var-decl-node 'js2-visitor 'js2-visit-var-decl)
+(js2--struct-put 'js2-var-decl-node 'js2-printer 'js2-print-var-decl)
+
+(defun js2-visit-var-decl (n v)
+  (dolist (kid (js2-var-decl-node-kids n))
+    (js2-visit-ast kid v)))
+
+(defun js2-print-var-decl (n i)
+  (let ((pad (js2-make-pad i))
+        (tt (js2-var-decl-node-decl-type n)))
+    (insert pad)
+    (insert (cond
+             ((= tt js2-VAR) "var ")
+             ((= tt js2-LET) "let ")
+             ((= tt js2-CONST) "const ")
+             (t
+              (error "malformed var-decl node"))))
+    (cl-loop with kids = (js2-var-decl-node-kids n)
+             with len = (length kids)
+             for kid in kids
+             for count from 1
+             do
+             (js2-print-ast kid 0)
+             (if (< count len)
+                 (insert ", ")))))
+
+(cl-defstruct (js2-var-init-node
+               (:include js2-node)
+               (:constructor make-js2-var-init-node (&key (type js2-VAR)
+                                                          (pos js2-ts-cursor)
+                                                          len target
+                                                          initializer)))
+  "AST node for a variable declaration.
+The type field will be js2-CONST for a const decl."
+  target        ; `js2-name-node', `js2-object-node', or `js2-array-node'
+  initializer)  ; initializer expression, a `js2-node'
+
+(js2--struct-put 'js2-var-init-node 'js2-visitor 'js2-visit-var-init-node)
+(js2--struct-put 'js2-var-init-node 'js2-printer 'js2-print-var-init-node)
+
+(defun js2-visit-var-init-node (n v)
+  (js2-visit-ast (js2-var-init-node-target n) v)
+  (js2-visit-ast (js2-var-init-node-initializer n) v))
+
+(defun js2-print-var-init-node (n i)
+  (let ((pad (js2-make-pad i))
+        (name (js2-var-init-node-target n))
+        (init (js2-var-init-node-initializer n)))
+    (insert pad)
+    (js2-print-ast name 0)
+    (when init
+      (insert " = ")
+      (js2-print-ast init 0))))
+
+(cl-defstruct (js2-cond-node
+               (:include js2-node)
+               (:constructor make-js2-cond-node (&key (type js2-HOOK)
+                                                      (pos js2-ts-cursor)
+                                                      len
+                                                      test-expr
+                                                      true-expr
+                                                      false-expr
+                                                      q-pos c-pos)))
+  "AST node for the ternary operator"
+  test-expr
+  true-expr
+  false-expr
+  q-pos   ; buffer position of ?
+  c-pos)  ; buffer position of :
+
+(js2--struct-put 'js2-cond-node 'js2-visitor 'js2-visit-cond-node)
+(js2--struct-put 'js2-cond-node 'js2-printer 'js2-print-cond-node)
+
+(defun js2-visit-cond-node (n v)
+  (js2-visit-ast (js2-cond-node-test-expr n) v)
+  (js2-visit-ast (js2-cond-node-true-expr n) v)
+  (js2-visit-ast (js2-cond-node-false-expr n) v))
+
+(defun js2-print-cond-node (n i)
+  (let ((pad (js2-make-pad i)))
+    (insert pad)
+    (js2-print-ast (js2-cond-node-test-expr n) 0)
+    (insert " ? ")
+    (js2-print-ast (js2-cond-node-true-expr n) 0)
+    (insert " : ")
+    (js2-print-ast (js2-cond-node-false-expr n) 0)))
+
+(cl-defstruct (js2-infix-node
+               (:include js2-node)
+               (:constructor make-js2-infix-node (&key type
+                                                       (pos js2-ts-cursor)
+                                                       len op-pos
+                                                       left right)))
+  "Represents infix expressions.
+Includes assignment ops like `|=', and the comma operator.
+The type field inherited from `js2-node' holds the operator."
+  op-pos    ; buffer position where operator begins
+  left      ; any `js2-node'
+  right)    ; any `js2-node'
+
+(js2--struct-put 'js2-infix-node 'js2-visitor 'js2-visit-infix-node)
+(js2--struct-put 'js2-infix-node 'js2-printer 'js2-print-infix-node)
+
+(defun js2-visit-infix-node (n v)
+  (js2-visit-ast (js2-infix-node-left n) v)
+  (js2-visit-ast (js2-infix-node-right n) v))
+
+(defconst js2-operator-tokens
+  (let ((table (make-hash-table :test 'eq))
+        (tokens
+         (list (cons js2-IN "in")
+               (cons js2-TYPEOF "typeof")
+               (cons js2-INSTANCEOF "instanceof")
+               (cons js2-DELPROP "delete")
+               (cons js2-AWAIT "await")
+               (cons js2-VOID "void")
+               (cons js2-COMMA ",")
+               (cons js2-COLON ":")
+               (cons js2-OR "||")
+               (cons js2-AND "&&")
+               (cons js2-INC "++")
+               (cons js2-DEC "--")
+               (cons js2-BITOR "|")
+               (cons js2-BITXOR "^")
+               (cons js2-BITAND "&")
+               (cons js2-EQ "==")
+               (cons js2-NE "!=")
+               (cons js2-LT "<")
+               (cons js2-LE "<=")
+               (cons js2-GT ">")
+               (cons js2-GE ">=")
+               (cons js2-LSH "<<")
+               (cons js2-RSH ">>")
+               (cons js2-URSH ">>>")
+               (cons js2-ADD "+")       ; infix plus
+               (cons js2-SUB "-")       ; infix minus
+               (cons js2-MUL "*")
+               (cons js2-EXPON "**")
+               (cons js2-DIV "/")
+               (cons js2-MOD "%")
+               (cons js2-NOT "!")
+               (cons js2-BITNOT "~")
+               (cons js2-POS "+")       ; unary plus
+               (cons js2-NEG "-")       ; unary minus
+               (cons js2-TRIPLEDOT "...")
+               (cons js2-SHEQ "===")    ; shallow equality
+               (cons js2-SHNE "!==")    ; shallow inequality
+               (cons js2-ASSIGN "=")
+               (cons js2-ASSIGN_BITOR "|=")
+               (cons js2-ASSIGN_BITXOR "^=")
+               (cons js2-ASSIGN_BITAND "&=")
+               (cons js2-ASSIGN_LSH "<<=")
+               (cons js2-ASSIGN_RSH ">>=")
+               (cons js2-ASSIGN_URSH ">>>=")
+               (cons js2-ASSIGN_ADD "+=")
+               (cons js2-ASSIGN_SUB "-=")
+               (cons js2-ASSIGN_MUL "*=")
+               (cons js2-ASSIGN_EXPON "**=")
+               (cons js2-ASSIGN_DIV "/=")
+               (cons js2-ASSIGN_MOD "%="))))
+    (cl-loop for (k . v) in tokens do
+             (puthash k v table))
+    table))
+
+(defun js2-print-infix-node (n i)
+  (let* ((tt (js2-node-type n))
+         (op (gethash tt js2-operator-tokens)))
+    (unless op
+      (error "unrecognized infix operator %s" (js2-node-type n)))
+    (insert (js2-make-pad i))
+    (js2-print-ast (js2-infix-node-left n) 0)
+    (unless (= tt js2-COMMA)
+      (insert " "))
+    (insert op)
+    (insert " ")
+    (js2-print-ast (js2-infix-node-right n) 0)))
+
+(cl-defstruct (js2-assign-node
+               (:include js2-infix-node)
+               (:constructor make-js2-assign-node (&key type
+                                                        (pos js2-ts-cursor)
+                                                        len op-pos
+                                                        left right)))
+  "Represents any assignment.
+The type field holds the actual assignment operator.")
+
+(js2--struct-put 'js2-assign-node 'js2-visitor 'js2-visit-infix-node)
+(js2--struct-put 'js2-assign-node 'js2-printer 'js2-print-infix-node)
+
+(cl-defstruct (js2-unary-node
+               (:include js2-node)
+               (:constructor make-js2-unary-node (&key type ; required
+                                                       (pos js2-ts-cursor)
+                                                       len operand)))
+  "AST node type for unary operator nodes.
+The type field can be NOT, BITNOT, POS, NEG, INC, DEC,
+TYPEOF, DELPROP, TRIPLEDOT or AWAIT.  For INC or DEC, a 'postfix node
+property is added if the operator follows the operand."
+  operand)  ; a `js2-node' expression
+
+(js2--struct-put 'js2-unary-node 'js2-visitor 'js2-visit-unary-node)
+(js2--struct-put 'js2-unary-node 'js2-printer 'js2-print-unary-node)
+
+(defun js2-visit-unary-node (n v)
+  (js2-visit-ast (js2-unary-node-operand n) v))
+
+(defun js2-print-unary-node (n i)
+  (let* ((tt (js2-node-type n))
+         (op (gethash tt js2-operator-tokens))
+         (postfix (js2-node-get-prop n 'postfix)))
+    (unless op
+      (error "unrecognized unary operator %s" tt))
+    (insert (js2-make-pad i))
+    (unless postfix
+      (insert op))
+    (if (or (= tt js2-TYPEOF)
+            (= tt js2-DELPROP)
+            (= tt js2-AWAIT)
+            (= tt js2-VOID))
+        (insert " "))
+    (js2-print-ast (js2-unary-node-operand n) 0)
+    (when postfix
+      (insert op))))
+
+(cl-defstruct (js2-let-node
+               (:include js2-scope)
+               (:constructor make-js2-let-node (&key (type js2-LETEXPR)
+                                                     (pos (js2-current-token-beg))
+                                                     len vars body
+                                                     lp rp)))
+  "AST node for a let expression or a let statement.
+Note that a let declaration such as let x=6, y=7 is a `js2-var-decl-node'."
+  vars   ; a `js2-var-decl-node'
+  body   ; a `js2-node' representing the expression or body block
+  lp
+  rp)
+
+(js2--struct-put 'js2-let-node 'js2-visitor 'js2-visit-let-node)
+(js2--struct-put 'js2-let-node 'js2-printer 'js2-print-let-node)
+
+(defun js2-visit-let-node (n v)
+  (js2-visit-ast (js2-let-node-vars n) v)
+  (js2-visit-ast (js2-let-node-body n) v))
+
+(defun js2-print-let-node (n i)
+  (insert (js2-make-pad i) "let (")
+  (let ((p (point)))
+    (js2-print-ast (js2-let-node-vars n) 0)
+    (delete-region p (+ p 4)))
+  (insert ") ")
+  (js2-print-ast (js2-let-node-body n) i))
+
+(cl-defstruct (js2-keyword-node
+               (:include js2-node)
+               (:constructor make-js2-keyword-node (&key type
+                                                         (pos (js2-current-token-beg))
+                                                         (len (- js2-ts-cursor pos)))))
+  "AST node representing a literal keyword such as `null'.
+Used for `null', `this', `true', `false' and `debugger'.
+The node type is set to js2-NULL, js2-THIS, etc.")
+
+(js2--struct-put 'js2-keyword-node 'js2-visitor 'js2-visit-none)
+(js2--struct-put 'js2-keyword-node 'js2-printer 'js2-print-keyword-node)
+
+(defun js2-print-keyword-node (n i)
+  (insert (js2-make-pad i)
+          (let ((tt (js2-node-type n)))
+            (cond
+             ((= tt js2-THIS) "this")
+             ((= tt js2-SUPER) "super")
+             ((= tt js2-NULL) "null")
+             ((= tt js2-TRUE) "true")
+             ((= tt js2-FALSE) "false")
+             ((= tt js2-DEBUGGER) "debugger")
+             (t (error "Invalid keyword literal type: %d" tt))))))
+
+(defsubst js2-this-or-super-node-p (node)
+  "Return t if NODE is a `js2-literal-node' of type js2-THIS or js2-SUPER."
+  (let ((type (js2-node-type node)))
+    (or (eq type js2-THIS) (eq type js2-SUPER))))
+
+(cl-defstruct (js2-new-node
+               (:include js2-node)
+               (:constructor make-js2-new-node (&key (type js2-NEW)
+                                                     (pos (js2-current-token-beg))
+                                                     len target
+                                                     args initializer
+                                                     lp rp)))
+  "AST node for new-expression such as new Foo()."
+  target  ; an identifier or reference
+  args    ; a Lisp list of argument nodes
+  lp      ; position of left-paren, nil if omitted
+  rp      ; position of right-paren, nil if omitted
+  initializer) ; experimental Rhino syntax:  optional `js2-object-node'
+
+(js2--struct-put 'js2-new-node 'js2-visitor 'js2-visit-new-node)
+(js2--struct-put 'js2-new-node 'js2-printer 'js2-print-new-node)
+
+(defun js2-visit-new-node (n v)
+  (js2-visit-ast (js2-new-node-target n) v)
+  (dolist (arg (js2-new-node-args n))
+    (js2-visit-ast arg v))
+  (js2-visit-ast (js2-new-node-initializer n) v))
+
+(defun js2-print-new-node (n i)
+  (insert (js2-make-pad i) "new ")
+  (js2-print-ast (js2-new-node-target n))
+  (insert "(")
+  (js2-print-list (js2-new-node-args n))
+  (insert ")")
+  (when (js2-new-node-initializer n)
+    (insert " ")
+    (js2-print-ast (js2-new-node-initializer n))))
+
+(cl-defstruct (js2-name-node
+               (:include js2-node)
+               (:constructor make-js2-name-node (&key (type js2-NAME)
+                                                      (pos (js2-current-token-beg))
+                                                      (len (- js2-ts-cursor
+                                                              (js2-current-token-beg)))
+                                                      (name (js2-current-token-string)))))
+  "AST node for a JavaScript identifier"
+  name   ; a string
+  scope) ; a `js2-scope' (optional, used for codegen)
+
+(js2--struct-put 'js2-name-node 'js2-visitor 'js2-visit-none)
+(js2--struct-put 'js2-name-node 'js2-printer 'js2-print-name-node)
+
+(defun js2-print-name-node (n i)
+  (insert (js2-make-pad i)
+          (js2-name-node-name n)))
+
+(defsubst js2-name-node-length (node)
+  "Return identifier length of NODE, a `js2-name-node'.
+Returns 0 if NODE is nil or its identifier field is nil."
+  (if node
+      (length (js2-name-node-name node))
+    0))
+
+(cl-defstruct (js2-number-node
+               (:include js2-node)
+               (:constructor make-js2-number-node (&key (type js2-NUMBER)
+                                                        (pos (js2-current-token-beg))
+                                                        (len (- js2-ts-cursor
+                                                                (js2-current-token-beg)))
+                                                        (value (js2-current-token-string))
+                                                        (num-value (js2-token-number
+                                                                    (js2-current-token)))
+                                                        (num-base (js2-token-number-base
+                                                                   (js2-current-token)))
+                                                        (legacy-octal-p (js2-token-number-legacy-octal-p
+                                                                         (js2-current-token))))))
+  "AST node for a number literal."
+  value      ; the original string, e.g. "6.02e23"
+  num-value  ; the parsed number value
+  num-base  ; the number's base
+  legacy-octal-p)  ; whether the number is a legacy octal (0123 instead of 0o123)
+
+(js2--struct-put 'js2-number-node 'js2-visitor 'js2-visit-none)
+(js2--struct-put 'js2-number-node 'js2-printer 'js2-print-number-node)
+
+(defun js2-print-number-node (n i)
+  (insert (js2-make-pad i)
+          (number-to-string (js2-number-node-num-value n))))
+
+(cl-defstruct (js2-regexp-node
+               (:include js2-node)
+               (:constructor make-js2-regexp-node (&key (type js2-REGEXP)
+                                                        (pos (js2-current-token-beg))
+                                                        (len (- js2-ts-cursor
+                                                                (js2-current-token-beg)))
+                                                        value flags)))
+  "AST node for a regular expression literal."
+  value  ; the regexp string, without // delimiters
+  flags) ; a string of flags, e.g. `mi'.
+
+(js2--struct-put 'js2-regexp-node 'js2-visitor 'js2-visit-none)
+(js2--struct-put 'js2-regexp-node 'js2-printer 'js2-print-regexp)
+
+(defun js2-print-regexp (n i)
+  (insert (js2-make-pad i)
+          "/"
+          (js2-regexp-node-value n)
+          "/")
+  (if (js2-regexp-node-flags n)
+      (insert (js2-regexp-node-flags n))))
+
+(cl-defstruct (js2-string-node
+               (:include js2-node)
+               (:constructor make-js2-string-node (&key (type js2-STRING)
+                                                        (pos (js2-current-token-beg))
+                                                        (len (- js2-ts-cursor
+                                                                (js2-current-token-beg)))
+                                                        (value (js2-current-token-string)))))
+  "String literal.
+Escape characters are not evaluated; e.g. \n is 2 chars in value field.
+You can tell the quote type by looking at the first character."
+  value) ; the characters of the string, including the quotes
+
+(js2--struct-put 'js2-string-node 'js2-visitor 'js2-visit-none)
+(js2--struct-put 'js2-string-node 'js2-printer 'js2-print-string-node)
+
+(defun js2-print-string-node (n i)
+  (insert (js2-make-pad i)
+          (js2-node-string n)))
+
+(cl-defstruct (js2-template-node
+               (:include js2-node)
+               (:constructor make-js2-template-node (&key (type js2-TEMPLATE_HEAD)
+                                                          pos len kids)))
+  "Template literal."
+  kids)  ; `js2-string-node' is used for string segments, other nodes
+         ; for substitutions inside.
+
+(js2--struct-put 'js2-template-node 'js2-visitor 'js2-visit-template)
+(js2--struct-put 'js2-template-node 'js2-printer 'js2-print-template)
+
+(defun js2-visit-template (n callback)
+  (dolist (kid (js2-template-node-kids n))
+    (js2-visit-ast kid callback)))
+
+(defun js2-print-template (n i)
+  (insert (js2-make-pad i))
+  (dolist (kid (js2-template-node-kids n))
+    (if (js2-string-node-p kid)
+        (insert (js2-node-string kid))
+      (js2-print-ast kid))))
+
+(cl-defstruct (js2-tagged-template-node
+               (:include js2-node)
+               (:constructor make-js2-tagged-template-node (&key (type js2-TAGGED_TEMPLATE)
+                                                                 pos len tag template)))
+  "Tagged template literal."
+  tag       ; `js2-node' with the tag expression.
+  template) ; `js2-template-node' with the template.
+
+(js2--struct-put 'js2-tagged-template-node 'js2-visitor 'js2-visit-tagged-template)
+(js2--struct-put 'js2-tagged-template-node 'js2-printer 'js2-print-tagged-template)
+
+(defun js2-visit-tagged-template (n callback)
+  (js2-visit-ast (js2-tagged-template-node-tag n) callback)
+  (js2-visit-ast (js2-tagged-template-node-template n) callback))
+
+(defun js2-print-tagged-template (n i)
+  (insert (js2-make-pad i))
+  (js2-print-ast (js2-tagged-template-node-tag n))
+  (js2-print-ast (js2-tagged-template-node-template n)))
+
+(cl-defstruct (js2-array-node
+               (:include js2-node)
+               (:constructor make-js2-array-node (&key (type js2-ARRAYLIT)
+                                                       (pos js2-ts-cursor)
+                                                       len elems)))
+  "AST node for an array literal."
+  elems)  ; list of expressions.  [foo,,bar] yields a nil middle element.
+
+(js2--struct-put 'js2-array-node 'js2-visitor 'js2-visit-array-node)
+(js2--struct-put 'js2-array-node 'js2-printer 'js2-print-array-node)
+
+(defun js2-visit-array-node (n v)
+  (dolist (e (js2-array-node-elems n))
+    (js2-visit-ast e v)))  ; Can be nil; e.g. [a, ,b].
+
+(defun js2-print-array-node (n i)
+  (insert (js2-make-pad i) "[")
+  (let ((elems (js2-array-node-elems n)))
+    (js2-print-list elems)
+    (when (and elems (null (car (last elems))))
+      (insert ",")))
+  (insert "]"))
+
+(cl-defstruct (js2-object-node
+               (:include js2-node)
+               (:constructor make-js2-object-node (&key (type js2-OBJECTLIT)
+                                                        (pos js2-ts-cursor)
+                                                        len
+                                                        elems)))
+  "AST node for an object literal expression.
+`elems' is a list of `js2-object-prop-node'."
+  elems)
+
+(js2--struct-put 'js2-object-node 'js2-visitor 'js2-visit-object-node)
+(js2--struct-put 'js2-object-node 'js2-printer 'js2-print-object-node)
+
+(defun js2-visit-object-node (n v)
+  (dolist (e (js2-object-node-elems n))
+    (js2-visit-ast e v)))
+
+(defun js2-print-object-node (n i)
+  (insert (js2-make-pad i) "{")
+  (js2-print-list (js2-object-node-elems n))
+  (insert "}"))
+
+(cl-defstruct (js2-class-node
+               (:include js2-object-node)
+               (:constructor make-js2-class-node (&key (type js2-CLASS)
+                                                       (pos js2-ts-cursor)
+                                                       (form 'CLASS_STATEMENT)
+                                                       (name "")
+                                                       extends len elems)))
+  "AST node for an class expression.
+`elems' is a list of `js2-object-prop-node', and `extends' is an
+optional `js2-expr-node'"
+  form             ; CLASS_{STATEMENT|EXPRESSION}
+  name             ; class name (a `js2-node-name', or nil if anonymous)
+  extends          ; class heritage (a `js2-expr-node', or nil if none)
+  )
+
+(js2--struct-put 'js2-class-node 'js2-visitor 'js2-visit-class-node)
+(js2--struct-put 'js2-class-node 'js2-printer 'js2-print-class-node)
+
+(defun js2-visit-class-node (n v)
+  (js2-visit-ast (js2-class-node-name n) v)
+  (js2-visit-ast (js2-class-node-extends n) v)
+  (dolist (e (js2-class-node-elems n))
+    (js2-visit-ast e v)))
+
+(defun js2-print-class-node (n i)
+  (let* ((pad (js2-make-pad i))
+         (name (js2-class-node-name n))
+         (extends (js2-class-node-extends n))
+         (elems (js2-class-node-elems n)))
+    (insert pad "class")
+    (when name
+      (insert " ")
+      (js2-print-ast name 0))
+    (when extends
+      (insert " extends ")
+      (js2-print-ast extends))
+    (insert " {")
+    (dolist (elem elems)
+      (insert "\n")
+      (if (js2-node-get-prop elem 'STATIC)
+          (progn (insert (js2-make-pad (1+ i)) "static ")
+                 (js2-print-ast elem 0)) ;; TODO(sdh): indentation isn't quite right
+        (js2-print-ast elem (1+ i))))
+    (insert "\n" pad "}")))
+
+(cl-defstruct (js2-computed-prop-name-node
+               (:include js2-node)
+               (:constructor make-js2-computed-prop-name-node
+                             (&key
+                              (type js2-LB)
+                              expr
+                              (pos (js2-current-token-beg))
+                              (len (- js2-ts-cursor
+                                      (js2-current-token-beg))))))
+  "AST node for a `ComputedPropertyName'."
+  expr)
+
+(js2--struct-put 'js2-computed-prop-name-node 'js2-visitor 'js2-visit-computed-prop-name-node)
+(js2--struct-put 'js2-computed-prop-name-node 'js2-printer 'js2-print-computed-prop-name-node)
+
+(defun js2-visit-computed-prop-name-node (n v)
+  (js2-visit-ast (js2-computed-prop-name-node-expr n) v))
+
+(defun js2-print-computed-prop-name-node (n i)
+  (insert (js2-make-pad i) "[")
+  (js2-print-ast (js2-computed-prop-name-node-expr n) 0)
+  (insert "]"))
+
+(cl-defstruct (js2-object-prop-node
+               (:include js2-infix-node)
+               (:constructor make-js2-object-prop-node (&key (type js2-COLON)
+                                                             (pos js2-ts-cursor)
+                                                             len left
+                                                             right op-pos)))
+  "AST node for an object literal prop:value entry.
+The `left' field is the property: a name node, string node,
+number node or expression node.  The `right' field is a
+`js2-node' representing the initializer value.  If the property
+is abbreviated, the node's `SHORTHAND' property is non-nil and
+both fields have the same value.")
+
+(js2--struct-put 'js2-object-prop-node 'js2-visitor 'js2-visit-infix-node)
+(js2--struct-put 'js2-object-prop-node 'js2-printer 'js2-print-object-prop-node)
+
+(defun js2-print-object-prop-node (n i)
+  (let* ((left (js2-object-prop-node-left n))
+         (right (js2-object-prop-node-right n)))
+    (js2-print-ast left i)
+    (if (not (js2-node-get-prop n 'SHORTHAND))
+        (progn
+          (insert ": ")
+          (js2-print-ast right 0)))))
+
+(cl-defstruct (js2-method-node
+               (:include js2-infix-node)
+               (:constructor make-js2-method-node (&key (pos js2-ts-cursor)
+                                                        len left right)))
+  "AST node for a method in an object literal or a class body.
+The `left' field is the `js2-name-node' naming the method.
+The `right' field is always an anonymous `js2-function-node' with a node
+property `METHOD_TYPE' set to 'GET or 'SET. ")
+
+(js2--struct-put 'js2-method-node 'js2-visitor 'js2-visit-infix-node)
+(js2--struct-put 'js2-method-node 'js2-printer 'js2-print-method)
+
+(defun js2-print-method (n i)
+  (let* ((pad (js2-make-pad i))
+         (left (js2-method-node-left n))
+         (right (js2-method-node-right n))
+         (type (js2-node-get-prop right 'METHOD_TYPE)))
+    (insert pad)
+    (when type
+      (insert (cdr (assoc type '((GET . "get ")
+                                 (SET . "set ")
+                                 (ASYNC . "async ")
+                                 (FUNCTION . ""))))))
+    (when (and (js2-function-node-p right)
+               (eq 'STAR (js2-function-node-generator-type right)))
+      (insert "*"))
+    (js2-print-ast left 0)
+    (js2-print-ast right 0)))
+
+(cl-defstruct (js2-prop-get-node
+               (:include js2-infix-node)
+               (:constructor make-js2-prop-get-node (&key (type js2-GETPROP)
+                                                          (pos js2-ts-cursor)
+                                                          len left right)))
+  "AST node for a dotted property reference, e.g. foo.bar or foo().bar")
+
+(js2--struct-put 'js2-prop-get-node 'js2-visitor 'js2-visit-prop-get-node)
+(js2--struct-put 'js2-prop-get-node 'js2-printer 'js2-print-prop-get-node)
+
+(defun js2-visit-prop-get-node (n v)
+  (js2-visit-ast (js2-prop-get-node-left n) v)
+  (js2-visit-ast (js2-prop-get-node-right n) v))
+
+(defun js2-print-prop-get-node (n i)
+  (insert (js2-make-pad i))
+  (js2-print-ast (js2-prop-get-node-left n) 0)
+  (insert ".")
+  (js2-print-ast (js2-prop-get-node-right n) 0))
+
+(cl-defstruct (js2-elem-get-node
+               (:include js2-node)
+               (:constructor make-js2-elem-get-node (&key (type js2-GETELEM)
+                                                          (pos js2-ts-cursor)
+                                                          len target element
+                                                          lb rb)))
+  "AST node for an array index expression such as foo[bar]."
+  target  ; a `js2-node' - the expression preceding the "."
+  element ; a `js2-node' - the expression in brackets
+  lb      ; position of left-bracket, nil if omitted
+  rb)     ; position of right-bracket, nil if omitted
+
+(js2--struct-put 'js2-elem-get-node 'js2-visitor 'js2-visit-elem-get-node)
+(js2--struct-put 'js2-elem-get-node 'js2-printer 'js2-print-elem-get-node)
+
+(defun js2-visit-elem-get-node (n v)
+  (js2-visit-ast (js2-elem-get-node-target n) v)
+  (js2-visit-ast (js2-elem-get-node-element n) v))
+
+(defun js2-print-elem-get-node (n i)
+  (insert (js2-make-pad i))
+  (js2-print-ast (js2-elem-get-node-target n) 0)
+  (insert "[")
+  (js2-print-ast (js2-elem-get-node-element n) 0)
+  (insert "]"))
+
+(cl-defstruct (js2-call-node
+               (:include js2-node)
+               (:constructor make-js2-call-node (&key (type js2-CALL)
+                                                      (pos js2-ts-cursor)
+                                                      len target args
+                                                      lp rp)))
+  "AST node for a JavaScript function call."
+  target  ; a `js2-node' evaluating to the function to call
+  args  ; a Lisp list of `js2-node' arguments
+  lp    ; position of open-paren, or nil if missing
+  rp)   ; position of close-paren, or nil if missing
+
+(js2--struct-put 'js2-call-node 'js2-visitor 'js2-visit-call-node)
+(js2--struct-put 'js2-call-node 'js2-printer 'js2-print-call-node)
+
+(defun js2-visit-call-node (n v)
+  (js2-visit-ast (js2-call-node-target n) v)
+  (dolist (arg (js2-call-node-args n))
+    (js2-visit-ast arg v)))
+
+(defun js2-print-call-node (n i)
+  (insert (js2-make-pad i))
+  (js2-print-ast (js2-call-node-target n) 0)
+  (insert "(")
+  (js2-print-list (js2-call-node-args n))
+  (insert ")"))
+
+(cl-defstruct (js2-yield-node
+               (:include js2-node)
+               (:constructor make-js2-yield-node (&key (type js2-YIELD)
+                                                       (pos js2-ts-cursor)
+                                                       len value star-p)))
+  "AST node for yield statement or expression."
+  star-p ; whether it's yield*
+  value) ; optional:  value to be yielded
+
+(js2--struct-put 'js2-yield-node 'js2-visitor 'js2-visit-yield-node)
+(js2--struct-put 'js2-yield-node 'js2-printer 'js2-print-yield-node)
+
+(defun js2-visit-yield-node (n v)
+  (js2-visit-ast (js2-yield-node-value n) v))
+
+(defun js2-print-yield-node (n i)
+  (insert (js2-make-pad i))
+  (insert "yield")
+  (when (js2-yield-node-star-p n)
+    (insert "*"))
+  (when (js2-yield-node-value n)
+    (insert " ")
+    (js2-print-ast (js2-yield-node-value n) 0)))
+
+(cl-defstruct (js2-paren-node
+               (:include js2-node)
+               (:constructor make-js2-paren-node (&key (type js2-LP)
+                                                       (pos js2-ts-cursor)
+                                                       len expr)))
+  "AST node for a parenthesized expression.
+In particular, used when the parens are syntactically optional,
+as opposed to required parens such as those enclosing an if-conditional."
+  expr)   ; `js2-node'
+
+(js2--struct-put 'js2-paren-node 'js2-visitor 'js2-visit-paren-node)
+(js2--struct-put 'js2-paren-node 'js2-printer 'js2-print-paren-node)
+
+(defun js2-visit-paren-node (n v)
+  (js2-visit-ast (js2-paren-node-expr n) v))
+
+(defun js2-print-paren-node (n i)
+  (insert (js2-make-pad i))
+  (insert "(")
+  (js2-print-ast (js2-paren-node-expr n) 0)
+  (insert ")"))
+
+(cl-defstruct (js2-comp-node
+               (:include js2-scope)
+               (:constructor make-js2-comp-node (&key (type js2-ARRAYCOMP)
+                                                      (pos js2-ts-cursor)
+                                                      len result
+                                                      loops filters
+                                                      form)))
+  "AST node for an Array comprehension such as [[x,y] for (x in foo) for (y in bar)]."
+  result  ; result expression (just after left-bracket)
+  loops   ; a Lisp list of `js2-comp-loop-node'
+  filters ; a Lisp list of guard/filter expressions
+  form    ; ARRAY, LEGACY_ARRAY or STAR_GENERATOR
+          ; SpiderMonkey also supports "legacy generator expressions", but we dont.
+  )
+
+(js2--struct-put 'js2-comp-node 'js2-visitor 'js2-visit-comp-node)
+(js2--struct-put 'js2-comp-node 'js2-printer 'js2-print-comp-node)
+
+(defun js2-visit-comp-node (n v)
+  (js2-visit-ast (js2-comp-node-result n) v)
+  (dolist (l (js2-comp-node-loops n))
+    (js2-visit-ast l v))
+  (dolist (f (js2-comp-node-filters n))
+    (js2-visit-ast f v)))
+
+(defun js2-print-comp-node (n i)
+  (let ((pad (js2-make-pad i))
+        (result (js2-comp-node-result n))
+        (loops (js2-comp-node-loops n))
+        (filters (js2-comp-node-filters n))
+        (legacy-p (eq (js2-comp-node-form n) 'LEGACY_ARRAY))
+        (gen-p (eq (js2-comp-node-form n) 'STAR_GENERATOR)))
+    (insert pad (if gen-p "(" "["))
+    (when legacy-p
+      (js2-print-ast result 0))
+    (dolist (l loops)
+      (when legacy-p
+        (insert " "))
+      (js2-print-ast l 0)
+      (unless legacy-p
+        (insert " ")))
+    (dolist (f filters)
+      (when legacy-p
+        (insert " "))
+      (insert "if (")
+      (js2-print-ast f 0)
+      (insert ")")
+      (unless legacy-p
+        (insert " ")))
+    (unless legacy-p
+      (js2-print-ast result 0))
+    (insert (if gen-p ")" "]"))))
+
+(cl-defstruct (js2-comp-loop-node
+               (:include js2-for-in-node)
+               (:constructor make-js2-comp-loop-node (&key (type js2-FOR)
+                                                           (pos js2-ts-cursor)
+                                                           len iterator
+                                                           object in-pos
+                                                           foreach-p
+                                                           each-pos
+                                                           forof-p
+                                                           lp rp)))
+  "AST subtree for each 'for (foo in bar)' loop in an array comprehension.")
+
+(js2--struct-put 'js2-comp-loop-node 'js2-visitor 'js2-visit-comp-loop)
+(js2--struct-put 'js2-comp-loop-node 'js2-printer 'js2-print-comp-loop)
+
+(defun js2-visit-comp-loop (n v)
+  (js2-visit-ast (js2-comp-loop-node-iterator n) v)
+  (js2-visit-ast (js2-comp-loop-node-object n) v))
+
+(defun js2-print-comp-loop (n _i)
+  (insert "for ")
+  (when (js2-comp-loop-node-foreach-p n) (insert "each "))
+  (insert "(")
+  (js2-print-ast (js2-comp-loop-node-iterator n) 0)
+  (insert (if (js2-comp-loop-node-forof-p n)
+              " of " " in "))
+  (js2-print-ast (js2-comp-loop-node-object n) 0)
+  (insert ")"))
+
+(cl-defstruct (js2-empty-expr-node
+               (:include js2-node)
+               (:constructor make-js2-empty-expr-node (&key (type js2-EMPTY)
+                                                            (pos (js2-current-token-beg))
+                                                            len)))
+  "AST node for an empty expression.")
+
+(js2--struct-put 'js2-empty-expr-node 'js2-visitor 'js2-visit-none)
+(js2--struct-put 'js2-empty-expr-node 'js2-printer 'js2-print-none)
+
+(cl-defstruct (js2-xml-node
+               (:include js2-block-node)
+               (:constructor make-js2-xml-node (&key (type js2-XML)
+                                                     (pos (js2-current-token-beg))
+                                                     len kids)))
+  "AST node for initial parse of E4X literals.
+The kids field is a list of XML fragments, each a `js2-string-node' or
+a `js2-xml-js-expr-node'.  Equivalent to Rhino's XmlLiteral node.")
+
+(js2--struct-put 'js2-xml-node 'js2-visitor 'js2-visit-block)
+(js2--struct-put 'js2-xml-node 'js2-printer 'js2-print-xml-node)
+
+(defun js2-print-xml-node (n i)
+  (dolist (kid (js2-xml-node-kids n))
+    (js2-print-ast kid i)))
+
+(cl-defstruct (js2-xml-js-expr-node
+               (:include js2-xml-node)
+               (:constructor make-js2-xml-js-expr-node (&key (type js2-XML)
+                                                             (pos js2-ts-cursor)
+                                                             len expr)))
+  "AST node for an embedded JavaScript {expression} in an E4X literal.
+The start and end fields correspond to the curly-braces."
+  expr)  ; a `js2-expr-node' of some sort
+
+(js2--struct-put 'js2-xml-js-expr-node 'js2-visitor 'js2-visit-xml-js-expr)
+(js2--struct-put 'js2-xml-js-expr-node 'js2-printer 'js2-print-xml-js-expr)
+
+(defun js2-visit-xml-js-expr (n v)
+  (js2-visit-ast (js2-xml-js-expr-node-expr n) v))
+
+(defun js2-print-xml-js-expr (n i)
+  (insert (js2-make-pad i))
+  (insert "{")
+  (js2-print-ast (js2-xml-js-expr-node-expr n) 0)
+  (insert "}"))
+
+(cl-defstruct (js2-xml-dot-query-node
+               (:include js2-infix-node)
+               (:constructor make-js2-xml-dot-query-node (&key (type js2-DOTQUERY)
+                                                               (pos js2-ts-cursor)
+                                                               op-pos len left
+                                                               right rp)))
+  "AST node for an E4X foo.(bar) filter expression.
+Note that the left-paren is automatically the character immediately
+following the dot (.) in the operator.  No whitespace is permitted
+between the dot and the lp by the scanner."
+  rp)
+
+(js2--struct-put 'js2-xml-dot-query-node 'js2-visitor 'js2-visit-infix-node)
+(js2--struct-put 'js2-xml-dot-query-node 'js2-printer 'js2-print-xml-dot-query)
+
+(defun js2-print-xml-dot-query (n i)
+  (insert (js2-make-pad i))
+  (js2-print-ast (js2-xml-dot-query-node-left n) 0)
+  (insert ".(")
+  (js2-print-ast (js2-xml-dot-query-node-right n) 0)
+  (insert ")"))
+
+(cl-defstruct (js2-xml-ref-node
+               (:include js2-node)
+               (:constructor nil))  ; abstract
+  "Base type for E4X XML attribute-access or property-get expressions.
+Such expressions can take a variety of forms.  The general syntax has
+three parts:
+
+  - (optional) an @ (specifying an attribute access)
+  - (optional) a namespace (a `js2-name-node') and double-colon
+  - (required) either a `js2-name-node' or a bracketed [expression]
+
+The property-name expressions (examples:  ns::name, @name) are
+represented as `js2-xml-prop-ref' nodes.  The bracketed-expression
+versions (examples:  ns::[name], @[name]) become `js2-xml-elem-ref' nodes.
+
+This node type (or more specifically, its subclasses) will sometimes
+be the right-hand child of a `js2-prop-get-node' or a
+`js2-infix-node' of type `js2-DOTDOT', the .. xml-descendants operator.
+The `js2-xml-ref-node' may also be a standalone primary expression with
+no explicit target, which is valid in certain expression contexts such as
+
+  company..employee.(@id < 100)
+
+in this case, the @id is a `js2-xml-ref' that is part of an infix '<'
+expression whose parent is a `js2-xml-dot-query-node'."
+  namespace
+  at-pos
+  colon-pos)
+
+(defsubst js2-xml-ref-node-attr-access-p (node)
+  "Return non-nil if this expression began with an @-token."
+  (and (numberp (js2-xml-ref-node-at-pos node))
+       (cl-plusp (js2-xml-ref-node-at-pos node))))
+
+(cl-defstruct (js2-xml-prop-ref-node
+               (:include js2-xml-ref-node)
+               (:constructor make-js2-xml-prop-ref-node (&key (type js2-REF_NAME)
+                                                              (pos (js2-current-token-beg))
+                                                              len propname
+                                                              namespace at-pos
+                                                              colon-pos)))
+  "AST node for an E4X XML [expr] property-ref expression.
+The JavaScript syntax is an optional @, an optional ns::, and a name.
+
+  [ '@' ] [ name '::' ] name
+
+Examples include name, ns::name, ns::*, *::name, *::*, @attr, @ns::attr,
+@ns::*, @*::attr, @*::*, and @*.
+
+The node starts at the @ token, if present.  Otherwise it starts at the
+namespace name.  The node bounds extend through the closing right-bracket,
+or if it is missing due to a syntax error, through the end of the index
+expression."
+  propname)
+
+(js2--struct-put 'js2-xml-prop-ref-node 'js2-visitor 'js2-visit-xml-prop-ref-node)
+(js2--struct-put 'js2-xml-prop-ref-node 'js2-printer 'js2-print-xml-prop-ref-node)
+
+(defun js2-visit-xml-prop-ref-node (n v)
+  (js2-visit-ast (js2-xml-prop-ref-node-namespace n) v)
+  (js2-visit-ast (js2-xml-prop-ref-node-propname n) v))
+
+(defun js2-print-xml-prop-ref-node (n i)
+  (insert (js2-make-pad i))
+  (if (js2-xml-ref-node-attr-access-p n)
+      (insert "@"))
+  (when (js2-xml-prop-ref-node-namespace n)
+    (js2-print-ast (js2-xml-prop-ref-node-namespace n) 0)
+    (insert "::"))
+  (if (js2-xml-prop-ref-node-propname n)
+      (js2-print-ast (js2-xml-prop-ref-node-propname n) 0)))
+
+(cl-defstruct (js2-xml-elem-ref-node
+               (:include js2-xml-ref-node)
+               (:constructor make-js2-xml-elem-ref-node (&key (type js2-REF_MEMBER)
+                                                              (pos (js2-current-token-beg))
+                                                              len expr lb rb
+                                                              namespace at-pos
+                                                              colon-pos)))
+  "AST node for an E4X XML [expr] member-ref expression.
+Syntax:
+
+ [ '@' ] [ name '::' ] '[' expr ']'
+
+Examples include ns::[expr], @ns::[expr], @[expr], *::[expr] and @*::[expr].
+
+Note that the form [expr] (i.e. no namespace or attribute-qualifier)
+is not a legal E4X XML element-ref expression, since it's already used
+for standard JavaScript element-get array indexing.  Hence, a
+`js2-xml-elem-ref-node' always has either the attribute-qualifier, a
+non-nil namespace node, or both.
+
+The node starts at the @ token, if present.  Otherwise it starts
+at the namespace name.  The node bounds extend through the closing
+right-bracket, or if it is missing due to a syntax error, through the
+end of the index expression."
+  expr  ; the bracketed index expression
+  lb
+  rb)
+
+(js2--struct-put 'js2-xml-elem-ref-node 'js2-visitor 'js2-visit-xml-elem-ref-node)
+(js2--struct-put 'js2-xml-elem-ref-node 'js2-printer 'js2-print-xml-elem-ref-node)
+
+(defun js2-visit-xml-elem-ref-node (n v)
+  (js2-visit-ast (js2-xml-elem-ref-node-namespace n) v)
+  (js2-visit-ast (js2-xml-elem-ref-node-expr n) v))
+
+(defun js2-print-xml-elem-ref-node (n i)
+  (insert (js2-make-pad i))
+  (if (js2-xml-ref-node-attr-access-p n)
+      (insert "@"))
+  (when (js2-xml-elem-ref-node-namespace n)
+    (js2-print-ast (js2-xml-elem-ref-node-namespace n) 0)
+    (insert "::"))
+  (insert "[")
+  (if (js2-xml-elem-ref-node-expr n)
+      (js2-print-ast (js2-xml-elem-ref-node-expr n) 0))
+  (insert "]"))
+
+;;; Placeholder nodes for when we try parsing the XML literals structurally.
+
+(cl-defstruct (js2-xml-start-tag-node
+               (:include js2-xml-node)
+               (:constructor make-js2-xml-start-tag-node (&key (type js2-XML)
+                                                               (pos js2-ts-cursor)
+                                                               len name attrs kids
+                                                               empty-p)))
+  "AST node for an XML start-tag.  Not currently used.
+The `kids' field is a Lisp list of child content nodes."
+  name      ; a `js2-xml-name-node'
+  attrs     ; a Lisp list of `js2-xml-attr-node'
+  empty-p)  ; t if this is an empty element such as <foo bar="baz"/>
+
+(js2--struct-put 'js2-xml-start-tag-node 'js2-visitor 'js2-visit-xml-start-tag)
+(js2--struct-put 'js2-xml-start-tag-node 'js2-printer 'js2-print-xml-start-tag)
+
+(defun js2-visit-xml-start-tag (n v)
+  (js2-visit-ast (js2-xml-start-tag-node-name n) v)
+  (dolist (attr (js2-xml-start-tag-node-attrs n))
+    (js2-visit-ast attr v))
+  (js2-visit-block n v))
+
+(defun js2-print-xml-start-tag (n i)
+  (insert (js2-make-pad i) "<")
+  (js2-print-ast (js2-xml-start-tag-node-name n) 0)
+  (when (js2-xml-start-tag-node-attrs n)
+    (insert " ")
+    (js2-print-list (js2-xml-start-tag-node-attrs n) " "))
+  (insert ">"))
+
+;; I -think- I'm going to make the parent node the corresponding start-tag,
+;; and add the end-tag to the kids list of the parent as well.
+(cl-defstruct (js2-xml-end-tag-node
+               (:include js2-xml-node)
+               (:constructor make-js2-xml-end-tag-node (&key (type js2-XML)
+                                                             (pos js2-ts-cursor)
+                                                             len name)))
+  "AST node for an XML end-tag.  Not currently used."
+  name)  ; a `js2-xml-name-node'
+
+(js2--struct-put 'js2-xml-end-tag-node 'js2-visitor 'js2-visit-xml-end-tag)
+(js2--struct-put 'js2-xml-end-tag-node 'js2-printer 'js2-print-xml-end-tag)
+
+(defun js2-visit-xml-end-tag (n v)
+  (js2-visit-ast (js2-xml-end-tag-node-name n) v))
+
+(defun js2-print-xml-end-tag (n i)
+  (insert (js2-make-pad i))
+  (insert "</")
+  (js2-print-ast (js2-xml-end-tag-node-name n) 0)
+  (insert ">"))
+
+(cl-defstruct (js2-xml-name-node
+               (:include js2-xml-node)
+               (:constructor make-js2-xml-name-node (&key (type js2-XML)
+                                                          (pos js2-ts-cursor)
+                                                          len namespace kids)))
+  "AST node for an E4X XML name.  Not currently used.
+Any XML name can be qualified with a namespace, hence the namespace field.
+Further, any E4X name can be comprised of arbitrary JavaScript {} expressions.
+The kids field is a list of `js2-name-node' and `js2-xml-js-expr-node'.
+For a simple name, the kids list has exactly one node, a `js2-name-node'."
+  namespace)  ; a `js2-string-node'
+
+(js2--struct-put 'js2-xml-name-node 'js2-visitor 'js2-visit-xml-name-node)
+(js2--struct-put 'js2-xml-name-node 'js2-printer 'js2-print-xml-name-node)
+
+(defun js2-visit-xml-name-node (n v)
+  (js2-visit-ast (js2-xml-name-node-namespace n) v))
+
+(defun js2-print-xml-name-node (n i)
+  (insert (js2-make-pad i))
+  (when (js2-xml-name-node-namespace n)
+    (js2-print-ast (js2-xml-name-node-namespace n) 0)
+    (insert "::"))
+  (dolist (kid (js2-xml-name-node-kids n))
+    (js2-print-ast kid 0)))
+
+(cl-defstruct (js2-xml-pi-node
+               (:include js2-xml-node)
+               (:constructor make-js2-xml-pi-node (&key (type js2-XML)
+                                                        (pos js2-ts-cursor)
+                                                        len name attrs)))
+  "AST node for an E4X XML processing instruction.  Not currently used."
+  name   ; a `js2-xml-name-node'
+  attrs) ; a list of `js2-xml-attr-node'
+
+(js2--struct-put 'js2-xml-pi-node 'js2-visitor 'js2-visit-xml-pi-node)
+(js2--struct-put 'js2-xml-pi-node 'js2-printer 'js2-print-xml-pi-node)
+
+(defun js2-visit-xml-pi-node (n v)
+  (js2-visit-ast (js2-xml-pi-node-name n) v)
+  (dolist (attr (js2-xml-pi-node-attrs n))
+    (js2-visit-ast attr v)))
+
+(defun js2-print-xml-pi-node (n i)
+  (insert (js2-make-pad i) "<?")
+  (js2-print-ast (js2-xml-pi-node-name n))
+  (when (js2-xml-pi-node-attrs n)
+    (insert " ")
+    (js2-print-list (js2-xml-pi-node-attrs n)))
+  (insert "?>"))
+
+(cl-defstruct (js2-xml-cdata-node
+               (:include js2-xml-node)
+               (:constructor make-js2-xml-cdata-node (&key (type js2-XML)
+                                                           (pos js2-ts-cursor)
+                                                           len content)))
+  "AST node for a CDATA escape section.  Not currently used."
+  content)  ; a `js2-string-node' with node-property 'quote-type 'cdata
+
+(js2--struct-put 'js2-xml-cdata-node 'js2-visitor 'js2-visit-xml-cdata-node)
+(js2--struct-put 'js2-xml-cdata-node 'js2-printer 'js2-print-xml-cdata-node)
+
+(defun js2-visit-xml-cdata-node (n v)
+  (js2-visit-ast (js2-xml-cdata-node-content n) v))
+
+(defun js2-print-xml-cdata-node (n i)
+  (insert (js2-make-pad i))
+  (js2-print-ast (js2-xml-cdata-node-content n)))
+
+(cl-defstruct (js2-xml-attr-node
+               (:include js2-xml-node)
+               (:constructor make-js2-attr-node (&key (type js2-XML)
+                                                      (pos js2-ts-cursor)
+                                                      len name value
+                                                      eq-pos quote-type)))
+  "AST node representing a foo='bar' XML attribute value.  Not yet used."
+  name   ; a `js2-xml-name-node'
+  value  ; a `js2-xml-name-node'
+  eq-pos ; buffer position of "=" sign
+  quote-type) ; 'single or 'double
+
+(js2--struct-put 'js2-xml-attr-node 'js2-visitor 'js2-visit-xml-attr-node)
+(js2--struct-put 'js2-xml-attr-node 'js2-printer 'js2-print-xml-attr-node)
+
+(defun js2-visit-xml-attr-node (n v)
+  (js2-visit-ast (js2-xml-attr-node-name n) v)
+  (js2-visit-ast (js2-xml-attr-node-value n) v))
+
+(defun js2-print-xml-attr-node (n i)
+  (let ((quote (if (eq (js2-xml-attr-node-quote-type n) 'single)
+                   "'"
+                 "\"")))
+    (insert (js2-make-pad i))
+    (js2-print-ast (js2-xml-attr-node-name n) 0)
+    (insert "=" quote)
+    (js2-print-ast (js2-xml-attr-node-value n) 0)
+    (insert quote)))
+
+(cl-defstruct (js2-xml-text-node
+               (:include js2-xml-node)
+               (:constructor make-js2-text-node (&key (type js2-XML)
+                                                      (pos js2-ts-cursor)
+                                                      len content)))
+  "AST node for an E4X XML text node.  Not currently used."
+  content)  ; a Lisp list of `js2-string-node' and `js2-xml-js-expr-node'
+
+(js2--struct-put 'js2-xml-text-node 'js2-visitor 'js2-visit-xml-text-node)
+(js2--struct-put 'js2-xml-text-node 'js2-printer 'js2-print-xml-text-node)
+
+(defun js2-visit-xml-text-node (n v)
+  (js2-visit-ast (js2-xml-text-node-content n) v))
+
+(defun js2-print-xml-text-node (n i)
+  (insert (js2-make-pad i))
+  (dolist (kid (js2-xml-text-node-content n))
+    (js2-print-ast kid)))
+
+(cl-defstruct (js2-xml-comment-node
+               (:include js2-xml-node)
+               (:constructor make-js2-xml-comment-node (&key (type js2-XML)
+                                                             (pos js2-ts-cursor)
+                                                             len)))
+  "AST node for E4X XML comment.  Not currently used.")
+
+(js2--struct-put 'js2-xml-comment-node 'js2-visitor 'js2-visit-none)
+(js2--struct-put 'js2-xml-comment-node 'js2-printer 'js2-print-xml-comment)
+
+(defun js2-print-xml-comment (n i)
+  (insert (js2-make-pad i)
+          (js2-node-string n)))
+
+;;; Node utilities
+
+(defsubst js2-node-line (n)
+  "Fetch the source line number at the start of node N.
+This is O(n) in the length of the source buffer; use prudently."
+  (1+ (count-lines (point-min) (js2-node-abs-pos n))))
+
+(defsubst js2-block-node-kid (n i)
+  "Return child I of node N, or nil if there aren't that many."
+  (nth i (js2-block-node-kids n)))
+
+(defsubst js2-block-node-first (n)
+  "Return first child of block node N, or nil if there is none."
+  (cl-first (js2-block-node-kids n)))
+
+(defun js2-node-root (n)
+  "Return the root of the AST containing N.
+If N has no parent pointer, returns N."
+  (let ((parent (js2-node-parent n)))
+    (if parent
+        (js2-node-root parent)
+      n)))
+
+(defsubst js2-node-short-name (n)
+  "Return the short name of node N as a string, e.g. `js2-if-node'."
+  (let ((name (symbol-name (aref n 0))))
+    (if (string-prefix-p "cl-struct-" name)
+        (substring (symbol-name (aref n 0))
+                   (length "cl-struct-"))
+      name)))
+
+(defun js2-node-child-list (node)
+  "Return the child list for NODE, a Lisp list of nodes.
+Works for block nodes, array nodes, obj literals, funarg lists,
+var decls and try nodes (for catch clauses).  Note that you should call
+`js2-block-node-kids' on the function body for the body statements.
+Returns nil for zero-length child lists or unsupported nodes."
+  (cond
+   ((js2-function-node-p node)
+    (js2-function-node-params node))
+   ((js2-block-node-p node)
+    (js2-block-node-kids node))
+   ((js2-try-node-p node)
+    (js2-try-node-catch-clauses node))
+   ((js2-array-node-p node)
+    (js2-array-node-elems node))
+   ((js2-object-node-p node)
+    (js2-object-node-elems node))
+   ((js2-call-node-p node)
+    (js2-call-node-args node))
+   ((js2-new-node-p node)
+    (js2-new-node-args node))
+   ((js2-var-decl-node-p node)
+    (js2-var-decl-node-kids node))
+   (t
+    nil)))
+
+(defun js2-node-set-child-list (node kids)
+  "Set the child list for NODE to KIDS."
+   (cond
+    ((js2-function-node-p node)
+     (setf (js2-function-node-params node) kids))
+    ((js2-block-node-p node)
+     (setf (js2-block-node-kids node) kids))
+    ((js2-try-node-p node)
+     (setf (js2-try-node-catch-clauses node) kids))
+    ((js2-array-node-p node)
+     (setf (js2-array-node-elems node) kids))
+    ((js2-object-node-p node)
+     (setf (js2-object-node-elems node) kids))
+    ((js2-call-node-p node)
+     (setf (js2-call-node-args node) kids))
+    ((js2-new-node-p node)
+     (setf (js2-new-node-args node) kids))
+    ((js2-var-decl-node-p node)
+     (setf (js2-var-decl-node-kids node) kids))
+    (t
+     (error "Unsupported node type: %s" (js2-node-short-name node))))
+   kids)
+
+;; All because Common Lisp doesn't support multiple inheritance for defstructs.
+(defconst js2-paren-expr-nodes
+  '(cl-struct-js2-comp-loop-node
+    cl-struct-js2-comp-node
+    cl-struct-js2-call-node
+    cl-struct-js2-catch-node
+    cl-struct-js2-do-node
+    cl-struct-js2-elem-get-node
+    cl-struct-js2-for-in-node
+    cl-struct-js2-for-node
+    cl-struct-js2-function-node
+    cl-struct-js2-if-node
+    cl-struct-js2-let-node
+    cl-struct-js2-new-node
+    cl-struct-js2-paren-node
+    cl-struct-js2-switch-node
+    cl-struct-js2-while-node
+    cl-struct-js2-with-node
+    cl-struct-js2-xml-dot-query-node)
+  "Node types that can have a parenthesized child expression.
+In particular, nodes that respond to `js2-node-lp' and `js2-node-rp'.")
+
+(defsubst js2-paren-expr-node-p (node)
+  "Return t for nodes that typically have a parenthesized child expression.
+Useful for computing the indentation anchors for arg-lists and conditions.
+Note that it may return a false positive, for instance when NODE is
+a `js2-new-node' and there are no arguments or parentheses."
+  (memq (aref node 0) js2-paren-expr-nodes))
+
+;; Fake polymorphism... yech.
+(defun js2-node-lp (node)
+  "Return relative left-paren position for NODE, if applicable.
+For `js2-elem-get-node' structs, returns left-bracket position.
+Note that the position may be nil in the case of a parse error."
+  (cond
+   ((js2-elem-get-node-p node)
+    (js2-elem-get-node-lb node))
+   ((js2-loop-node-p node)
+    (js2-loop-node-lp node))
+   ((js2-function-node-p node)
+    (js2-function-node-lp node))
+   ((js2-if-node-p node)
+    (js2-if-node-lp node))
+   ((js2-new-node-p node)
+    (js2-new-node-lp node))
+   ((js2-call-node-p node)
+    (js2-call-node-lp node))
+   ((js2-paren-node-p node)
+    0)
+   ((js2-switch-node-p node)
+    (js2-switch-node-lp node))
+   ((js2-catch-node-p node)
+    (js2-catch-node-lp node))
+   ((js2-let-node-p node)
+    (js2-let-node-lp node))
+   ((js2-comp-node-p node)
+    0)
+   ((js2-with-node-p node)
+    (js2-with-node-lp node))
+   ((js2-xml-dot-query-node-p node)
+    (1+ (js2-infix-node-op-pos node)))
+   (t
+    (error "Unsupported node type: %s" (js2-node-short-name node)))))
+
+;; Fake polymorphism... blech.
+(defun js2-node-rp (node)
+  "Return relative right-paren position for NODE, if applicable.
+For `js2-elem-get-node' structs, returns right-bracket position.
+Note that the position may be nil in the case of a parse error."
+  (cond
+   ((js2-elem-get-node-p node)
+    (js2-elem-get-node-rb node))
+   ((js2-loop-node-p node)
+    (js2-loop-node-rp node))
+   ((js2-function-node-p node)
+    (js2-function-node-rp node))
+   ((js2-if-node-p node)
+    (js2-if-node-rp node))
+   ((js2-new-node-p node)
+    (js2-new-node-rp node))
+   ((js2-call-node-p node)
+    (js2-call-node-rp node))
+   ((js2-paren-node-p node)
+    (1- (js2-node-len node)))
+   ((js2-switch-node-p node)
+    (js2-switch-node-rp node))
+   ((js2-catch-node-p node)
+    (js2-catch-node-rp node))
+   ((js2-let-node-p node)
+    (js2-let-node-rp node))
+   ((js2-comp-node-p node)
+    (1- (js2-node-len node)))
+   ((js2-with-node-p node)
+    (js2-with-node-rp node))
+   ((js2-xml-dot-query-node-p node)
+    (1+ (js2-xml-dot-query-node-rp node)))
+   (t
+    (error "Unsupported node type: %s" (js2-node-short-name node)))))
+
+(defsubst js2-node-first-child (node)
+  "Return the first element of `js2-node-child-list' for NODE."
+  (car (js2-node-child-list node)))
+
+(defsubst js2-node-last-child (node)
+  "Return the last element of `js2-node-last-child' for NODE."
+  (car (last (js2-node-child-list node))))
+
+(defun js2-node-prev-sibling (node)
+  "Return the previous statement in parent.
+Works for parents supported by `js2-node-child-list'.
+Returns nil if NODE is not in the parent, or PARENT is
+not a supported node, or if NODE is the first child."
+  (let* ((p (js2-node-parent node))
+         (kids (js2-node-child-list p))
+         (sib (car kids)))
+    (while (and kids
+                (not (eq node (cadr kids))))
+      (setq kids (cdr kids)
+            sib (car kids)))
+    sib))
+
+(defun js2-node-next-sibling (node)
+  "Return the next statement in parent block.
+Returns nil if NODE is not in the block, or PARENT is not
+a block node, or if NODE is the last statement."
+  (let* ((p (js2-node-parent node))
+         (kids (js2-node-child-list p)))
+    (while (and kids
+                (not (eq node (car kids))))
+      (setq kids (cdr kids)))
+    (cadr kids)))
+
+(defun js2-node-find-child-before (pos parent &optional after)
+  "Find the last child that starts before POS in parent.
+If AFTER is non-nil, returns first child starting after POS.
+POS is an absolute buffer position.  PARENT is any node
+supported by `js2-node-child-list'.
+Returns nil if no applicable child is found."
+  (let ((kids (if (js2-function-node-p parent)
+                  (js2-block-node-kids (js2-function-node-body parent))
+                (js2-node-child-list parent)))
+        (beg (js2-node-abs-pos (if (js2-function-node-p parent)
+                                   (js2-function-node-body parent)
+                                 parent)))
+        kid result fn
+        (continue t))
+    (setq fn (if after '>= '<))
+    (while (and kids continue)
+      (setq kid (car kids))
+      (if (funcall fn (+ beg (js2-node-pos kid)) pos)
+          (setq result kid
+                continue (not after))
+        (setq continue after))
+      (setq kids (cdr kids)))
+    result))
+
+(defun js2-node-find-child-after (pos parent)
+  "Find first child that starts after POS in parent.
+POS is an absolute buffer position.  PARENT is any node
+supported by `js2-node-child-list'.
+Returns nil if no applicable child is found."
+  (js2-node-find-child-before pos parent 'after))
+
+(defun js2-node-replace-child (pos parent new-node)
+  "Replace node at index POS in PARENT with NEW-NODE.
+Only works for parents supported by `js2-node-child-list'."
+  (let ((kids (js2-node-child-list parent))
+        (i 0))
+    (while (< i pos)
+      (setq kids (cdr kids)
+            i (1+ i)))
+    (setcar kids new-node)
+    (js2-node-add-children parent new-node)))
+
+(defun js2-node-buffer (n)
+  "Return the buffer associated with AST N.
+Returns nil if the buffer is not set as a property on the root
+node, or if parent links were not recorded during parsing."
+  (let ((root (js2-node-root n)))
+    (and root
+         (js2-ast-root-p root)
+         (js2-ast-root-buffer root))))
+
+(defun js2-block-node-push (n kid)
+  "Push js2-node KID onto the end of js2-block-node N's child list.
+KID is always added to the -end- of the kids list.
+Function also calls `js2-node-add-children' to add the parent link."
+  (let ((kids (js2-node-child-list n)))
+    (if kids
+        (setcdr kids (nconc (cdr kids) (list kid)))
+      (js2-node-set-child-list n (list kid)))
+    (js2-node-add-children n kid)))
+
+(defun js2-node-string (node)
+  (with-current-buffer (or (js2-node-buffer node)
+                           (error "No buffer available for node %s" node))
+    (let ((pos (js2-node-abs-pos node)))
+      (buffer-substring-no-properties pos (+ pos (js2-node-len node))))))
+
+;; Container for storing the node we're looking for in a traversal.
+(js2-deflocal js2-discovered-node nil)
+
+;; Keep track of absolute node position during traversals.
+(js2-deflocal js2-visitor-offset nil)
+
+(js2-deflocal js2-node-search-point nil)
+
+(when js2-mode-dev-mode-p
+  (defun js2-find-node-at-point ()
+    (interactive)
+    (let ((node (js2-node-at-point)))
+      (message "%s" (or node "No node found at point"))))
+  (defun js2-node-name-at-point ()
+    (interactive)
+    (let ((node (js2-node-at-point)))
+      (message "%s" (if node
+                        (js2-node-short-name node)
+                      "No node found at point.")))))
+
+(defun js2-node-at-point (&optional pos skip-comments)
+  "Return AST node at POS, a buffer position, defaulting to current point.
+The `js2-mode-ast' variable must be set to the current parse tree.
+Signals an error if the AST (`js2-mode-ast') is nil.
+Always returns a node - if it can't find one, it returns the root.
+If SKIP-COMMENTS is non-nil, comment nodes are ignored."
+  (let ((ast js2-mode-ast)
+        result)
+    (unless ast
+      (error "No JavaScript AST available"))
+    ;; Look through comments first, since they may be inside nodes that
+    ;; would otherwise report a match.
+    (setq pos (or pos (point))
+          result (if (> pos (js2-node-abs-end ast))
+                     ast
+                   (if (not skip-comments)
+                       (js2-comment-at-point pos))))
+    (unless result
+      (setq js2-discovered-node nil
+            js2-visitor-offset 0
+            js2-node-search-point pos)
+      (unwind-protect
+          (catch 'js2-visit-done
+            (js2-visit-ast ast #'js2-node-at-point-visitor))
+        (setq js2-visitor-offset nil
+              js2-node-search-point nil))
+      (setq result js2-discovered-node))
+    ;; may have found a comment beyond end of last child node,
+    ;; since visiting the ast-root looks at the comment-list last.
+    (if (and skip-comments
+             (js2-comment-node-p result))
+        (setq result nil))
+    (or result js2-mode-ast)))
+
+(defun js2-node-at-point-visitor (node end-p)
+  (let ((rel-pos (js2-node-pos node))
+        abs-pos
+        abs-end
+        (point js2-node-search-point))
+    (cond
+     (end-p
+      ;; this evaluates to a non-nil return value, even if it's zero
+      (cl-decf js2-visitor-offset rel-pos))
+     ;; we already looked for comments before visiting, and don't want them now
+     ((js2-comment-node-p node)
+      nil)
+     (t
+      (setq abs-pos (cl-incf js2-visitor-offset rel-pos)
+            ;; we only want to use the node if the point is before
+            ;; the last character position in the node, so we decrement
+            ;; the absolute end by 1.
+            abs-end (+ abs-pos (js2-node-len node) -1))
+      (cond
+       ;; If this node starts after search-point, stop the search.
+       ((> abs-pos point)
+        (throw 'js2-visit-done nil))
+       ;; If this node ends before the search-point, don't check kids.
+       ((> point abs-end)
+        nil)
+       (t
+        ;; Otherwise point is within this node, possibly in a child.
+        (setq js2-discovered-node node)
+        t))))))  ; keep processing kids to look for more specific match
+
+(defsubst js2-block-comment-p (node)
+  "Return non-nil if NODE is a comment node of format `jsdoc' or `block'."
+  (and (js2-comment-node-p node)
+       (memq (js2-comment-node-format node) '(jsdoc block))))
+
+;; TODO:  put the comments in a vector and binary-search them instead
+(defun js2-comment-at-point (&optional pos)
+  "Look through scanned comment nodes for one containing POS.
+POS is a buffer position that defaults to current point.
+Function returns nil if POS was not in any comment node."
+  (let ((ast js2-mode-ast)
+        (x (or pos (point)))
+        beg end)
+    (unless ast
+      (error "No JavaScript AST available"))
+    (catch 'done
+      ;; Comments are stored in lexical order.
+      (dolist (comment (js2-ast-root-comments ast) nil)
+        (setq beg (js2-node-abs-pos comment)
+              end (+ beg (js2-node-len comment)))
+        (if (and (>= x beg)
+                 (<= x end))
+          (throw 'done comment))))))
+
+(defun js2-comments-between (start end comments-list)
+  "Return comment nodes between START and END, nil if not found.
+START and END are absolute positions in current buffer.
+COMMENTS-LIST is the comments list to check."
+  (let (comments c-start c-end)
+    (nreverse
+      (dolist (comment comments-list comments)
+        (setq c-start (js2-node-abs-pos comment)
+              c-end (1- (+ c-start (js2-node-len comment))))
+        (unless (or (< c-end start)
+                    (> c-start end))
+          (push comment comments))))))
+
+(defun js2-mode-find-parent-fn (node)
+  "Find function enclosing NODE.
+Returns nil if NODE is not inside a function."
+  (setq node (js2-node-parent node))
+  (while (and node (not (js2-function-node-p node)))
+    (setq node (js2-node-parent node)))
+  (and (js2-function-node-p node) node))
+
+(defun js2-mode-find-enclosing-fn (node)
+  "Find function or root enclosing NODE."
+  (if (js2-ast-root-p node)
+      node
+    (setq node (js2-node-parent node))
+    (while (not (or (js2-ast-root-p node)
+                    (js2-function-node-p node)))
+      (setq node (js2-node-parent node)))
+    node))
+
+ (defun js2-mode-find-enclosing-node (beg end)
+  "Find node fully enclosing BEG and END."
+  (let ((node (js2-node-at-point beg))
+        pos
+        (continue t))
+    (while continue
+      (if (or (js2-ast-root-p node)
+              (and
+               (<= (setq pos (js2-node-abs-pos node)) beg)
+               (>= (+ pos (js2-node-len node)) end)))
+          (setq continue nil)
+        (setq node (js2-node-parent node))))
+    node))
+
+(defun js2-node-parent-script-or-fn (node)
+  "Find script or function immediately enclosing NODE.
+If NODE is the ast-root, returns nil."
+  (if (js2-ast-root-p node)
+      nil
+    (setq node (js2-node-parent node))
+    (while (and node (not (or (js2-function-node-p node)
+                              (js2-script-node-p node))))
+      (setq node (js2-node-parent node)))
+    node))
+
+(defun js2-node-is-descendant (node ancestor)
+  "Return t if NODE is a descendant of ANCESTOR."
+  (while (and node
+              (not (eq node ancestor)))
+    (setq node (js2-node-parent node)))
+  node)
+
+;;; visitor infrastructure
+
+(defun js2-visit-none (_node _callback)
+  "Visitor for AST node that have no node children."
+  nil)
+
+(defun js2-print-none (_node _indent)
+  "Visitor for AST node with no printed representation.")
+
+(defun js2-print-body (node indent)
+  "Print a statement, or a block without braces."
+  (if (js2-block-node-p node)
+      (dolist (kid (js2-block-node-kids node))
+        (js2-print-ast kid indent))
+    (js2-print-ast node indent)))
+
+(defun js2-print-list (args &optional delimiter)
+  (cl-loop with len = (length args)
+           for arg in args
+           for count from 1
+           do
+           (when arg (js2-print-ast arg 0))
+           (if (< count len)
+               (insert (or delimiter ", ")))))
+
+(defun js2-print-tree (ast)
+  "Prints an AST to the current buffer.
+Makes `js2-ast-parent-nodes' available to the printer functions."
+  (let ((max-lisp-eval-depth (max max-lisp-eval-depth 1500)))
+    (js2-print-ast ast)))
+
+(defun js2-print-ast (node &optional indent)
+  "Helper function for printing AST nodes.
+Requires `js2-ast-parent-nodes' to be non-nil.
+You should use `js2-print-tree' instead of this function."
+  (let ((printer (get (aref node 0) 'js2-printer))
+        (i (or indent 0)))
+    ;; TODO:  wedge comments in here somewhere
+    (if printer
+        (funcall printer node i))))
+
+(defconst js2-side-effecting-tokens
+  (let ((tokens (make-bool-vector js2-num-tokens nil)))
+    (dolist (tt (list js2-ASSIGN
+                      js2-ASSIGN_ADD
+                      js2-ASSIGN_BITAND
+                      js2-ASSIGN_BITOR
+                      js2-ASSIGN_BITXOR
+                      js2-ASSIGN_DIV
+                      js2-ASSIGN_LSH
+                      js2-ASSIGN_MOD
+                      js2-ASSIGN_MUL
+                      js2-ASSIGN_RSH
+                      js2-ASSIGN_SUB
+                      js2-ASSIGN_URSH
+                      js2-ASSIGN_EXPON
+                      js2-BLOCK
+                      js2-BREAK
+                      js2-CALL
+                      js2-CATCH
+                      js2-CATCH_SCOPE
+                      js2-CLASS
+                      js2-CONST
+                      js2-CONTINUE
+                      js2-DEBUGGER
+                      js2-DEC
+                      js2-DELPROP
+                      js2-DEL_REF
+                      js2-DO
+                      js2-ELSE
+                      js2-EMPTY
+                      js2-ENTERWITH
+                      js2-EXPORT
+                      js2-EXPR_RESULT
+                      js2-FINALLY
+                      js2-FOR
+                      js2-FUNCTION
+                      js2-GOTO
+                      js2-IF
+                      js2-IFEQ
+                      js2-IFNE
+                      js2-IMPORT
+                      js2-INC
+                      js2-JSR
+                      js2-LABEL
+                      js2-LEAVEWITH
+                      js2-LET
+                      js2-LETEXPR
+                      js2-LOCAL_BLOCK
+                      js2-LOOP
+                      js2-NEW
+                      js2-REF_CALL
+                      js2-RETHROW
+                      js2-RETURN
+                      js2-RETURN_RESULT
+                      js2-SEMI
+                      js2-SETELEM
+                      js2-SETELEM_OP
+                      js2-SETNAME
+                      js2-SETPROP
+                      js2-SETPROP_OP
+                      js2-SETVAR
+                      js2-SET_REF
+                      js2-SET_REF_OP
+                      js2-SWITCH
+                      js2-TARGET
+                      js2-THROW
+                      js2-TRY
+                      js2-VAR
+                      js2-WHILE
+                      js2-WITH
+                      js2-WITHEXPR
+                      js2-YIELD))
+      (aset tokens tt t))
+    tokens))
+
+(defun js2-node-has-side-effects (node)
+  "Return t if NODE has side effects."
+  (when node  ; makes it easier to handle malformed expressions
+    (let ((tt (js2-node-type node)))
+      (cond
+       ;; This doubtless needs some work, since EXPR_VOID is used
+       ;; in several ways in Rhino and I may not have caught them all.
+       ;; I'll wait for people to notice incorrect warnings.
+       ((and (= tt js2-EXPR_VOID)
+             (js2-expr-stmt-node-p node)) ; but not if EXPR_RESULT
+        (let ((expr (js2-expr-stmt-node-expr node)))
+          (or (js2-node-has-side-effects expr)
+              (when (js2-string-node-p expr)
+                (member (js2-string-node-value expr) '("use strict" "use asm"))))))
+       ((= tt js2-AWAIT) t)
+       ((= tt js2-COMMA)
+        (js2-node-has-side-effects (js2-infix-node-right node)))
+       ((or (= tt js2-AND)
+            (= tt js2-OR))
+        (or (js2-node-has-side-effects (js2-infix-node-right node))
+            (js2-node-has-side-effects (js2-infix-node-left node))))
+       ((= tt js2-HOOK)
+        (and (js2-node-has-side-effects (js2-cond-node-true-expr node))
+             (js2-node-has-side-effects (js2-cond-node-false-expr node))))
+       ((js2-paren-node-p node)
+        (js2-node-has-side-effects (js2-paren-node-expr node)))
+       ((= tt js2-ERROR) ; avoid cascaded error messages
+        nil)
+       ((or (and js2-instanceof-has-side-effects (= tt js2-INSTANCEOF))
+            (and js2-getprop-has-side-effects (= tt js2-GETPROP)))
+        t)
+       (t
+        (aref js2-side-effecting-tokens tt))))))
+
+(defconst js2-stmt-node-types
+  (list js2-BLOCK
+        js2-BREAK
+        js2-CONTINUE
+        js2-DEFAULT  ; e4x "default xml namespace" statement
+        js2-DO
+        js2-EXPORT
+        js2-EXPR_RESULT
+        js2-EXPR_VOID
+        js2-FOR
+        js2-IF
+        js2-IMPORT
+        js2-RETURN
+        js2-SWITCH
+        js2-THROW
+        js2-TRY
+        js2-WHILE
+        js2-WITH)
+  "Node types that only appear in statement contexts.
+The list does not include nodes that always appear as the child
+of another specific statement type, such as switch-cases,
+catch and finally blocks, and else-clauses.  The list also excludes
+nodes like yield, let and var, which may appear in either expression
+or statement context, and in the latter context always have a
+`js2-expr-stmt-node' parent.  Finally, the list does not include
+functions or scripts, which are treated separately from statements
+by the JavaScript parser and runtime.")
+
+(defun js2-stmt-node-p (node)
+  "Heuristic for figuring out if NODE is a statement.
+Some node types can appear in either an expression context or a
+statement context, e.g. let-nodes, yield-nodes, and var-decl nodes.
+For these node types in a statement context, the parent will be a
+`js2-expr-stmt-node'.
+Functions aren't included in the check."
+  (memq (js2-node-type node) js2-stmt-node-types))
+
+(defun js2-mode-find-first-stmt (node)
+  "Search upward starting from NODE looking for a statement.
+For purposes of this function, a `js2-function-node' counts."
+  (while (not (or (js2-stmt-node-p node)
+                  (js2-function-node-p node)))
+    (setq node (js2-node-parent node)))
+  node)
+
+(defun js2-node-parent-stmt (node)
+  "Return the node's first ancestor that is a statement.
+Returns nil if NODE is a `js2-ast-root'.  Note that any expression
+appearing in a statement context will have a parent that is a
+`js2-expr-stmt-node' that will be returned by this function."
+  (let ((parent (js2-node-parent node)))
+    (if (or (null parent)
+            (js2-stmt-node-p parent)
+            (and (js2-function-node-p parent)
+                 (eq (js2-function-node-form parent) 'FUNCTION_STATEMENT)))
+        parent
+      (js2-node-parent-stmt parent))))
+
+;; In the Mozilla Rhino sources, Roshan James writes:
+;;  Does consistent-return analysis on the function body when strict mode is
+;;  enabled.
+;;
+;;    function (x) { return (x+1) }
+;;
+;;  is ok, but
+;;
+;;    function (x) { if (x < 0) return (x+1); }
+;;
+;;  is not because the function can potentially return a value when the
+;;  condition is satisfied and if not, the function does not explicitly
+;;  return a value.
+;;
+;;  This extends to checking mismatches such as "return" and "return <value>"
+;;  used in the same function. Warnings are not emitted if inconsistent
+;;  returns exist in code that can be statically shown to be unreachable.
+;;  Ex.
+;;    function (x) { while (true) { ... if (..) { return value } ... } }
+;;
+;;  emits no warning. However if the loop had a break statement, then a
+;;  warning would be emitted.
+;;
+;;  The consistency analysis looks at control structures such as loops, ifs,
+;;  switch, try-catch-finally blocks, examines the reachable code paths and
+;;  warns the user about an inconsistent set of termination possibilities.
+;;
+;;  These flags enumerate the possible ways a statement/function can
+;;  terminate. These flags are used by endCheck() and by the Parser to
+;;  detect inconsistent return usage.
+;;
+;;  END_UNREACHED is reserved for code paths that are assumed to always be
+;;  able to execute (example: throw, continue)
+;;
+;;  END_DROPS_OFF indicates if the statement can transfer control to the
+;;  next one. Statement such as return dont. A compound statement may have
+;;  some branch that drops off control to the next statement.
+;;
+;;  END_RETURNS indicates that the statement can return with no value.
+;;  END_RETURNS_VALUE indicates that the statement can return a value.
+;;
+;;  A compound statement such as
+;;  if (condition) {
+;;    return value;
+;;  }
+;;  Will be detected as (END_DROPS_OFF | END_RETURN_VALUE) by endCheck()
+
+(defconst js2-END_UNREACHED 0)
+(defconst js2-END_DROPS_OFF 1)
+(defconst js2-END_RETURNS 2)
+(defconst js2-END_RETURNS_VALUE 4)
+(defconst js2-END_YIELDS 8)
+
+(defun js2-has-consistent-return-usage (node)
+  "Check that every return usage in a function body is consistent.
+Returns t if the function satisfies strict mode requirement."
+  (let ((n (js2-end-check node)))
+    ;; either it doesn't return a value in any branch...
+    (or (js2-flag-not-set-p n js2-END_RETURNS_VALUE)
+        ;; or it returns a value (or is unreached) at every branch
+        (js2-flag-not-set-p n (logior js2-END_DROPS_OFF
+                                      js2-END_RETURNS
+                                      js2-END_YIELDS)))))
+
+(defun js2-end-check-if (node)
+  "Ensure that return usage in then/else blocks is consistent.
+If there is no else block, then the return statement can fall through.
+Returns logical OR of END_* flags"
+  (let ((th (js2-if-node-then-part node))
+        (el (js2-if-node-else-part node)))
+    (if (null th)
+        js2-END_UNREACHED
+      (logior (js2-end-check th) (if el
+                                     (js2-end-check el)
+                                   js2-END_DROPS_OFF)))))
+
+(defun js2-end-check-switch (node)
+  "Consistency of return statements is checked between the case statements.
+If there is no default, then the switch can fall through. If there is a
+default, we check to see if all code paths in the default return or if
+there is a code path that can fall through.
+Returns logical OR of END_* flags."
+  (let ((rv js2-END_UNREACHED)
+        default-case)
+    ;; examine the cases
+    (catch 'break
+      (dolist (c (js2-switch-node-cases node))
+        (if (js2-case-node-expr c)
+            (js2-set-flag rv (js2-end-check-block c))
+          (setq default-case c)
+          (throw 'break nil))))
+    ;; we don't care how the cases drop into each other
+    (js2-clear-flag rv js2-END_DROPS_OFF)
+    ;; examine the default
+    (js2-set-flag rv (if default-case
+                         (js2-end-check default-case)
+                       js2-END_DROPS_OFF))
+    rv))
+
+(defun js2-end-check-try (node)
+ "If the block has a finally, return consistency is checked in the
+finally block. If all code paths in the finally return, then the
+returns in the try-catch blocks don't matter. If there is a code path
+that does not return or if there is no finally block, the returns
+of the try and catch blocks are checked for mismatch.
+Returns logical OR of END_* flags."
+ (let ((finally (js2-try-node-finally-block node))
+       rv)
+   ;; check the finally if it exists
+   (setq rv (if finally
+                (js2-end-check (js2-finally-node-body finally))
+              js2-END_DROPS_OFF))
+   ;; If the finally block always returns, then none of the returns
+   ;; in the try or catch blocks matter.
+   (when (js2-flag-set-p rv js2-END_DROPS_OFF)
+     (js2-clear-flag rv js2-END_DROPS_OFF)
+     ;; examine the try block
+     (js2-set-flag rv (js2-end-check (js2-try-node-try-block node)))
+     ;; check each catch block
+     (dolist (cb (js2-try-node-catch-clauses node))
+       (js2-set-flag rv (js2-end-check cb))))
+   rv))
+
+(defun js2-end-check-loop (node)
+  "Return statement in the loop body must be consistent.
+The default assumption for any kind of a loop is that it will eventually
+terminate.  The only exception is a loop with a constant true condition.
+Code that follows such a loop is examined only if one can determine
+statically that there is a break out of the loop.
+
+    for(... ; ... ; ...) {}
+    for(... in ... ) {}
+    while(...) { }
+    do { } while(...)
+
+Returns logical OR of END_* flags."
+  (let ((rv (js2-end-check (js2-loop-node-body node)))
+        (condition (cond
+                    ((js2-while-node-p node)
+                     (js2-while-node-condition node))
+                     ((js2-do-node-p node)
+                      (js2-do-node-condition node))
+                     ((js2-for-node-p node)
+                      (js2-for-node-condition node)))))
+
+    ;; check to see if the loop condition is always true
+    (if (and condition
+             (eq (js2-always-defined-boolean-p condition) 'ALWAYS_TRUE))
+        (js2-clear-flag rv js2-END_DROPS_OFF))
+
+    ;; look for effect of breaks
+    (js2-set-flag rv (js2-node-get-prop node
+                                        'CONTROL_BLOCK_PROP
+                                        js2-END_UNREACHED))
+    rv))
+
+(defun js2-end-check-block (node)
+  "A general block of code is examined statement by statement.
+If any statement (even a compound one) returns in all branches, then
+subsequent statements are not examined.
+Returns logical OR of END_* flags."
+  (let* ((rv js2-END_DROPS_OFF)
+         (kids (js2-block-node-kids node))
+         (n (car kids)))
+    ;; Check each statement.  If the statement can continue onto the next
+    ;; one (i.e. END_DROPS_OFF is set), then check the next statement.
+    (while (and n (js2-flag-set-p rv js2-END_DROPS_OFF))
+      (js2-clear-flag rv js2-END_DROPS_OFF)
+      (js2-set-flag rv (js2-end-check n))
+      (setq kids (cdr kids)
+            n (car kids)))
+    rv))
+
+(defun js2-end-check-label (node)
+  "A labeled statement implies that there may be a break to the label.
+The function processes the labeled statement and then checks the
+CONTROL_BLOCK_PROP property to see if there is ever a break to the
+particular label.
+Returns logical OR of END_* flags."
+  (let ((rv (js2-end-check (js2-labeled-stmt-node-stmt node))))
+    (logior rv (js2-node-get-prop node
+                                  'CONTROL_BLOCK_PROP
+                                  js2-END_UNREACHED))))
+
+(defun js2-end-check-break (node)
+  "When a break is encountered annotate the statement being broken
+out of by setting its CONTROL_BLOCK_PROP property.
+Returns logical OR of END_* flags."
+  (and (js2-break-node-target node)
+       (js2-node-set-prop (js2-break-node-target node)
+                          'CONTROL_BLOCK_PROP
+                          js2-END_DROPS_OFF))
+  js2-END_UNREACHED)
+
+(defun js2-end-check (node)
+  "Examine the body of a function, doing a basic reachability analysis.
+Returns a combination of flags END_* flags that indicate
+how the function execution can terminate. These constitute only the
+pessimistic set of termination conditions. It is possible that at
+runtime certain code paths will never be actually taken. Hence this
+analysis will flag errors in cases where there may not be errors.
+Returns logical OR of END_* flags"
+  (let (kid)
+    (cond
+     ((js2-break-node-p node)
+      (js2-end-check-break node))
+     ((js2-expr-stmt-node-p node)
+      (if (setq kid (js2-expr-stmt-node-expr node))
+          (js2-end-check kid)
+        js2-END_DROPS_OFF))
+     ((or (js2-continue-node-p node)
+          (js2-throw-node-p node))
+      js2-END_UNREACHED)
+     ((js2-return-node-p node)
+      (if (setq kid (js2-return-node-retval node))
+          js2-END_RETURNS_VALUE
+        js2-END_RETURNS))
+     ((js2-loop-node-p node)
+      (js2-end-check-loop node))
+     ((js2-switch-node-p node)
+      (js2-end-check-switch node))
+     ((js2-labeled-stmt-node-p node)
+      (js2-end-check-label node))
+     ((js2-if-node-p node)
+      (js2-end-check-if node))
+     ((js2-try-node-p node)
+      (js2-end-check-try node))
+     ((js2-block-node-p node)
+      (if (null (js2-block-node-kids node))
+          js2-END_DROPS_OFF
+        (js2-end-check-block node)))
+     ((js2-yield-node-p node)
+      js2-END_YIELDS)
+     (t
+      js2-END_DROPS_OFF))))
+
+(defun js2-always-defined-boolean-p (node)
+  "Check if NODE always evaluates to true or false in boolean context.
+Returns 'ALWAYS_TRUE, 'ALWAYS_FALSE, or nil if it's neither always true
+nor always false."
+  (let ((tt (js2-node-type node))
+        num)
+    (cond
+     ((or (= tt js2-FALSE) (= tt js2-NULL))
+      'ALWAYS_FALSE)
+     ((= tt js2-TRUE)
+      'ALWAYS_TRUE)
+     ((= tt js2-NUMBER)
+      (setq num (js2-number-node-num-value node))
+      (if (and (not (eq num 0.0e+NaN))
+               (not (zerop num)))
+          'ALWAYS_TRUE
+        'ALWAYS_FALSE))
+     (t
+      nil))))
+
+;;; Scanner -- a port of Mozilla Rhino's lexer.
+;; Corresponds to Rhino files Token.java and TokenStream.java.
+
+(defvar js2-tokens nil
+  "List of all defined token names.")  ; initialized in `js2-token-names'
+
+(defconst js2-token-names
+  (let* ((names (make-vector js2-num-tokens -1))
+         (case-fold-search nil)  ; only match js2-UPPER_CASE
+         (syms (apropos-internal "^js2-\\(?:[[:upper:]_]+\\)")))
+    (cl-loop for sym in syms
+             for i from 0
+             do
+             (unless (or (memq sym '(js2-EOF_CHAR js2-ERROR))
+                         (not (boundp sym)))
+               (aset names (symbol-value sym)           ; code, e.g. 152
+                     (downcase
+                      (substring (symbol-name sym) 4))) ; name, e.g. "let"
+               (push sym js2-tokens)))
+    names)
+  "Vector mapping int values to token string names, sans `js2-' prefix.")
+
+(defun js2-tt-name (tok)
+  "Return a string name for TOK, a token symbol or code.
+Signals an error if it's not a recognized token."
+  (let ((code tok))
+    (if (symbolp tok)
+        (setq code (symbol-value tok)))
+    (if (eq code -1)
+        "ERROR"
+      (if (and (numberp code)
+               (not (cl-minusp code))
+               (< code js2-num-tokens))
+          (aref js2-token-names code)
+        (error "Invalid token: %s" code)))))
+
+(defsubst js2-tt-sym (tok)
+  "Return symbol for TOK given its code, e.g. 'js2-LP for code 86."
+  (intern (js2-tt-name tok)))
+
+(defconst js2-token-codes
+  (let ((table (make-hash-table :test 'eq :size 256)))
+    (cl-loop for name across js2-token-names
+             for sym = (intern (concat "js2-" (upcase name)))
+             do
+             (puthash sym (symbol-value sym) table))
+    ;; clean up a few that are "wrong" in Rhino's token codes
+    (puthash 'js2-DELETE js2-DELPROP table)
+    table)
+  "Hashtable mapping token type symbols to their bytecodes.")
+
+(defsubst js2-tt-code (sym)
+  "Return code for token symbol SYM, e.g. 86 for 'js2-LP."
+  (or (gethash sym js2-token-codes)
+      (error "Invalid token symbol: %s " sym)))  ; signal code bug
+
+(defun js2-report-scan-error (msg &optional no-throw beg len)
+  (setf (js2-token-end (js2-current-token)) js2-ts-cursor)
+  (js2-report-error msg nil
+                    (or beg (js2-current-token-beg))
+                    (or len (js2-current-token-len)))
+  (unless no-throw
+    (throw 'return js2-ERROR)))
+
+(defun js2-set-string-from-buffer (token)
+  "Set `string' and `end' slots for TOKEN, return the string."
+  (setf (js2-token-end token) js2-ts-cursor
+        (js2-token-string token) (js2-collect-string js2-ts-string-buffer)))
+
+;; TODO:  could potentially avoid a lot of consing by allocating a
+;; char buffer the way Rhino does.
+(defsubst js2-add-to-string (c)
+  (push c js2-ts-string-buffer))
+
+;; Note that when we "read" the end-of-file, we advance js2-ts-cursor
+;; to (1+ (point-max)), which lets the scanner treat end-of-file like
+;; any other character:  when it's not part of the current token, we
+;; unget it, allowing it to be read again by the following call.
+(defsubst js2-unget-char ()
+  (cl-decf js2-ts-cursor))
+
+;; Rhino distinguishes \r and \n line endings.  We don't need to
+;; because we only scan from Emacs buffers, which always use \n.
+(defun js2-get-char ()
+  "Read and return the next character from the input buffer.
+Increments `js2-ts-lineno' if the return value is a newline char.
+Updates `js2-ts-cursor' to the point after the returned char.
+Returns `js2-EOF_CHAR' if we hit the end of the buffer.
+Also updates `js2-ts-hit-eof' and `js2-ts-line-start' as needed."
+  (let (c)
+    ;; check for end of buffer
+    (if (>= js2-ts-cursor (point-max))
+        (setq js2-ts-hit-eof t
+              js2-ts-cursor (1+ js2-ts-cursor)
+              c js2-EOF_CHAR)  ; return value
+      ;; otherwise read next char
+      (setq c (char-before (cl-incf js2-ts-cursor)))
+      ;; if we read a newline, update counters
+      (if (= c ?\n)
+          (setq js2-ts-line-start js2-ts-cursor
+                js2-ts-lineno (1+ js2-ts-lineno)))
+      ;; TODO:  skip over format characters
+      c)))
+
+(defun js2-read-unicode-escape ()
+  "Read a \\uNNNN sequence from the input.
+Assumes the ?\ and ?u have already been read.
+Returns the unicode character, or nil if it wasn't a valid character.
+Doesn't change the values of any scanner variables."
+  ;; I really wish I knew a better way to do this, but I can't
+  ;; find the Emacs function that takes a 16-bit int and converts
+  ;; it to a Unicode/utf-8 character.  So I basically eval it with (read).
+  ;; Have to first check that it's 4 hex characters or it may stop
+  ;; the read early.
+  (ignore-errors
+    (let ((s (buffer-substring-no-properties js2-ts-cursor
+                                             (+ 4 js2-ts-cursor))))
+      (if (string-match "[0-9a-fA-F]\\{4\\}" s)
+          (read (concat "?\\u" s))))))
+
+(defun js2-match-char (test)
+  "Consume and return next character if it matches TEST, a character.
+Returns nil and consumes nothing if TEST is not the next character."
+  (let ((c (js2-get-char)))
+    (if (eq c test)
+        t
+      (js2-unget-char)
+      nil)))
+
+(defun js2-peek-char ()
+  (prog1
+      (js2-get-char)
+    (js2-unget-char)))
+
+(defun js2-identifier-start-p (c)
+  "Is C a valid start to an ES5 Identifier?
+See http://es5.github.io/#x7.6"
+  (or
+   (memq c '(?$ ?_))
+   (memq (get-char-code-property c 'general-category)
+         ;; Letters
+         '(Lu Ll Lt Lm Lo Nl))))
+
+(defun js2-identifier-part-p (c)
+  "Is C a valid part of an ES5 Identifier?
+See http://es5.github.io/#x7.6"
+  (or
+   (memq c '(?$ ?_ ?\u200c  ?\u200d))
+   (memq (get-char-code-property c 'general-category)
+         '(;; Letters
+           Lu Ll Lt Lm Lo Nl
+           ;; Combining Marks
+           Mn Mc
+           ;; Digits
+           Nd
+           ;; Connector Punctuation
+           Pc))))
+
+(defun js2-alpha-p (c)
+  (cond ((and (<= ?A c) (<= c ?Z)) t)
+        ((and (<= ?a c) (<= c ?z)) t)
+        (t nil)))
+
+(defsubst js2-digit-p (c)
+  (and (<= ?0 c) (<= c ?9)))
+
+(defun js2-js-space-p (c)
+  (if (<= c 127)
+      (memq c '(#x20 #x9 #xB #xC #xD))
+    (or
+     (eq c #xA0)
+     ;; TODO:  change this nil to check for Unicode space character
+     nil)))
+
+(defconst js2-eol-chars (list js2-EOF_CHAR ?\n ?\r))
+
+(defun js2-skip-line ()
+  "Skip to end of line."
+  (while (not (memq (js2-get-char) js2-eol-chars)))
+  (js2-unget-char)
+  (setf (js2-token-end (js2-current-token)) js2-ts-cursor))
+
+(defun js2-init-scanner (&optional buf line)
+  "Create token stream for BUF starting on LINE.
+BUF defaults to `current-buffer' and LINE defaults to 1.
+
+A buffer can only have one scanner active at a time, which yields
+dramatically simpler code than using a defstruct.  If you need to
+have simultaneous scanners in a buffer, copy the regions to scan
+into temp buffers."
+  (with-current-buffer (or buf (current-buffer))
+    (setq js2-ts-dirty-line nil
+          js2-ts-hit-eof nil
+          js2-ts-line-start 0
+          js2-ts-lineno (or line 1)
+          js2-ts-line-end-char -1
+          js2-ts-cursor (point-min)
+          js2-ti-tokens (make-vector js2-ti-ntokens nil)
+          js2-ti-tokens-cursor 0
+          js2-ti-lookahead 0
+          js2-ts-is-xml-attribute nil
+          js2-ts-xml-is-tag-content nil
+          js2-ts-xml-open-tags-count 0
+          js2-ts-string-buffer nil)))
+
+;; This function uses the cached op, string and number fields in
+;; TokenStream; if getToken has been called since the passed token
+;; was scanned, the op or string printed may be incorrect.
+(defun js2-token-to-string (token)
+  ;; Not sure where this function is used in Rhino.  Not tested.
+  (if (not js2-debug-print-trees)
+      ""
+    (let ((name (js2-tt-name token)))
+      (cond
+       ((memq token '(js2-STRING js2-REGEXP js2-NAME
+                      js2-TEMPLATE_HEAD js2-NO_SUBS_TEMPLATE))
+        (concat name " `" (js2-current-token-string) "'"))
+       ((eq token js2-NUMBER)
+        (format "NUMBER %g" (js2-token-number (js2-current-token))))
+       (t
+        name)))))
+
+(defconst js2-keywords
+  '(break
+    case catch class const continue
+    debugger default delete do
+    else extends export
+    false finally for function
+    if in instanceof import
+    let
+    new null
+    return
+    super switch
+    this throw true try typeof
+    var void
+    while with
+    yield))
+
+;; Token names aren't exactly the same as the keywords, unfortunately.
+;; E.g. delete is js2-DELPROP.
+(defconst js2-kwd-tokens
+  (let ((table (make-vector js2-num-tokens nil))
+        (tokens
+         (list js2-BREAK
+               js2-CASE js2-CATCH js2-CLASS js2-CONST js2-CONTINUE
+               js2-DEBUGGER js2-DEFAULT js2-DELPROP js2-DO
+               js2-ELSE js2-EXPORT
+               js2-ELSE js2-EXTENDS js2-EXPORT
+               js2-FALSE js2-FINALLY js2-FOR js2-FUNCTION
+               js2-IF js2-IN js2-INSTANCEOF js2-IMPORT
+               js2-LET
+               js2-NEW js2-NULL
+               js2-RETURN
+               js2-SUPER js2-SWITCH
+               js2-THIS js2-THROW js2-TRUE js2-TRY js2-TYPEOF
+               js2-VAR
+               js2-WHILE js2-WITH
+               js2-YIELD)))
+    (dolist (i tokens)
+      (aset table i 'font-lock-keyword-face))
+    (aset table js2-STRING 'font-lock-string-face)
+    (aset table js2-REGEXP 'font-lock-string-face)
+    (aset table js2-NO_SUBS_TEMPLATE 'font-lock-string-face)
+    (aset table js2-TEMPLATE_HEAD 'font-lock-string-face)
+    (aset table js2-COMMENT 'font-lock-comment-face)
+    (aset table js2-THIS 'font-lock-builtin-face)
+    (aset table js2-SUPER 'font-lock-builtin-face)
+    (aset table js2-VOID 'font-lock-constant-face)
+    (aset table js2-NULL 'font-lock-constant-face)
+    (aset table js2-TRUE 'font-lock-constant-face)
+    (aset table js2-FALSE 'font-lock-constant-face)
+    (aset table js2-NOT 'font-lock-negation-char-face)
+    table)
+  "Vector whose values are non-nil for tokens that are keywords.
+The values are default faces to use for highlighting the keywords.")
+
+;; FIXME: Support strict mode-only future reserved words, after we know
+;; which parts scopes are in strict mode, and which are not.
+(defconst js2-reserved-words '(class enum export extends import static super)
+  "Future reserved keywords in ECMAScript 5.1.")
+
+(defconst js2-keyword-names
+  (let ((table (make-hash-table :test 'equal)))
+    (cl-loop for k in js2-keywords
+             do (puthash
+                 (symbol-name k)                            ; instanceof
+                 (intern (concat "js2-"
+                                 (upcase (symbol-name k)))) ; js2-INSTANCEOF
+                 table))
+    table)
+  "JavaScript keywords by name, mapped to their symbols.")
+
+(defconst js2-reserved-word-names
+  (let ((table (make-hash-table :test 'equal)))
+    (cl-loop for k in js2-reserved-words
+             do
+             (puthash (symbol-name k) 'js2-RESERVED table))
+    table)
+  "JavaScript reserved words by name, mapped to 'js2-RESERVED.")
+
+(defun js2-collect-string (buf)
+  "Convert BUF, a list of chars, to a string.
+Reverses BUF before converting."
+  (if buf
+      (apply #'string (nreverse buf))
+    ""))
+
+(defun js2-string-to-keyword (s)
+  "Return token for S, a string, if S is a keyword or reserved word.
+Returns a symbol such as 'js2-BREAK, or nil if not keyword/reserved."
+  (or (gethash s js2-keyword-names)
+      (gethash s js2-reserved-word-names)))
+
+(defsubst js2-ts-set-char-token-bounds (token)
+  "Used when next token is one character."
+  (setf (js2-token-beg token) (1- js2-ts-cursor)
+        (js2-token-end token) js2-ts-cursor))
+
+(defsubst js2-ts-return (token type)
+  "Update the `end' and `type' slots of TOKEN,
+then throw `return' with value TYPE."
+  (setf (js2-token-end token) js2-ts-cursor
+        (js2-token-type token) type)
+  (throw 'return type))
+
+(defun js2-x-digit-to-int (c accumulator)
+  "Build up a hex number.
+If C is a hexadecimal digit, return ACCUMULATOR * 16 plus
+corresponding number.  Otherwise return -1."
+  (catch 'return
+    (catch 'check
+      ;; Use 0..9 < A..Z < a..z
+      (cond
+       ((<= c ?9)
+        (cl-decf c ?0)
+        (if (<= 0 c)
+            (throw 'check nil)))
+       ((<= c ?F)
+        (when (<= ?A c)
+          (cl-decf c (- ?A 10))
+          (throw 'check nil)))
+       ((<= c ?f)
+        (when (<= ?a c)
+          (cl-decf c (- ?a 10))
+          (throw 'check nil))))
+      (throw 'return -1))
+    (logior c (lsh accumulator 4))))
+
+(defun js2-get-token (&optional modifier)
+  "If `js2-ti-lookahead' is zero, call scanner to get new token.
+Otherwise, move `js2-ti-tokens-cursor' and return the type of
+next saved token.
+
+This function will not return a newline (js2-EOL) - instead, it
+gobbles newlines until it finds a non-newline token.  Call
+`js2-peek-token-or-eol' when you care about newlines.
+
+This function will also not return a js2-COMMENT.  Instead, it
+records comments found in `js2-scanned-comments'.  If the token
+returned by this function immediately follows a jsdoc comment,
+the token is flagged as such."
+  (if (zerop js2-ti-lookahead)
+      (js2-get-token-internal modifier)
+    (cl-decf js2-ti-lookahead)
+    (setq js2-ti-tokens-cursor (mod (1+ js2-ti-tokens-cursor) js2-ti-ntokens))
+    (let ((tt (js2-current-token-type)))
+      (cl-assert (not (= tt js2-EOL)))
+      tt)))
+
+(defun js2-unget-token ()
+  (cl-assert (< js2-ti-lookahead js2-ti-max-lookahead))
+  (cl-incf js2-ti-lookahead)
+  (setq js2-ti-tokens-cursor (mod (1- js2-ti-tokens-cursor) js2-ti-ntokens)))
+
+(defun js2-get-token-internal (modifier)
+  (let* ((token (js2-get-token-internal-1 modifier)) ; call scanner
+         (tt (js2-token-type token))
+         saw-eol
+         face)
+    ;; process comments
+    (while (or (= tt js2-EOL) (= tt js2-COMMENT))
+      (if (= tt js2-EOL)
+          (setq saw-eol t)
+        (setq saw-eol nil)
+        (when js2-record-comments
+          (js2-record-comment token)))
+      (setq js2-ti-tokens-cursor (mod (1- js2-ti-tokens-cursor) js2-ti-ntokens))
+      (setq token (js2-get-token-internal-1 modifier) ; call scanner again
+            tt (js2-token-type token)))
+
+    (when saw-eol
+      (setf (js2-token-follows-eol-p token) t))
+
+    ;; perform lexical fontification as soon as token is scanned
+    (when js2-parse-ide-mode
+      (cond
+       ((cl-minusp tt)
+        (js2-record-face 'js2-error token))
+       ((setq face (aref js2-kwd-tokens tt))
+        (js2-record-face face token))
+       ((and (= tt js2-NAME)
+             (equal (js2-token-string token) "undefined"))
+        (js2-record-face 'font-lock-constant-face token))))
+    tt))
+
+(defsubst js2-string-to-number (str base)
+  ;; TODO:  Maybe port ScriptRuntime.stringToNumber.
+  (condition-case nil
+      (string-to-number str base)
+    (overflow-error -1)))
+
+(defun js2-get-token-internal-1 (modifier)
+  "Return next JavaScript token type, an int such as js2-RETURN.
+During operation, creates an instance of `js2-token' struct, sets
+its relevant fields and puts it into `js2-ti-tokens'."
+  (let (identifier-start
+        is-unicode-escape-start c
+        contains-escape escape-val str result base
+        look-for-slash continue tt legacy-octal
+        (token (js2-new-token 0)))
+    (setq
+     tt
+     (catch 'return
+       (when (eq modifier 'TEMPLATE_TAIL)
+         (setf (js2-token-beg token) (1- js2-ts-cursor))
+         (throw 'return (js2-get-string-or-template-token ?` token)))
+       (while t
+         ;; Eat whitespace, possibly sensitive to newlines.
+         (setq continue t)
+         (while continue
+           (setq c (js2-get-char))
+           (cond
+            ((eq c js2-EOF_CHAR)
+             (js2-unget-char)
+             (js2-ts-set-char-token-bounds token)
+             (throw 'return js2-EOF))
+            ((eq c ?\n)
+             (js2-ts-set-char-token-bounds token)
+             (setq js2-ts-dirty-line nil)
+             (throw 'return js2-EOL))
+            ((not (js2-js-space-p c))
+             (if (/= c ?-)              ; in case end of HTML comment
+                 (setq js2-ts-dirty-line t))
+             (setq continue nil))))
+         ;; Assume the token will be 1 char - fixed up below.
+         (js2-ts-set-char-token-bounds token)
+         (when (eq c ?@)
+           (throw 'return js2-XMLATTR))
+         ;; identifier/keyword/instanceof?
+         ;; watch out for starting with a <backslash>
+         (cond
+          ((eq c ?\\)
+           (setq c (js2-get-char))
+           (if (eq c ?u)
+               (setq identifier-start t
+                     is-unicode-escape-start t
+                     js2-ts-string-buffer nil)
+             (setq identifier-start nil)
+             (js2-unget-char)
+             (setq c ?\\)))
+          (t
+           (when (setq identifier-start (js2-identifier-start-p c))
+             (setq js2-ts-string-buffer nil)
+             (js2-add-to-string c))))
+         (when identifier-start
+           (setq contains-escape is-unicode-escape-start)
+           (catch 'break
+             (while t
+               (if is-unicode-escape-start
+                   ;; strictly speaking we should probably push-back
+                   ;; all the bad characters if the <backslash>uXXXX
+                   ;; sequence is malformed. But since there isn't a
+                   ;; correct context(is there?) for a bad Unicode
+                   ;; escape sequence in an identifier, we can report
+                   ;; an error here.
+                   (progn
+                     (setq escape-val 0)
+                     (dotimes (_ 4)
+                       (setq c (js2-get-char)
+                             escape-val (js2-x-digit-to-int c escape-val))
+                       ;; Next check takes care of c < 0 and bad escape
+                       (if (cl-minusp escape-val)
+                           (throw 'break nil)))
+                     (if (cl-minusp escape-val)
+                         (js2-report-scan-error "msg.invalid.escape" t))
+                     (js2-add-to-string escape-val)
+                     (setq is-unicode-escape-start nil))
+                 (setq c (js2-get-char))
+                 (cond
+                  ((eq c ?\\)
+                   (setq c (js2-get-char))
+                   (if (eq c ?u)
+                       (setq is-unicode-escape-start t
+                             contains-escape t)
+                     (js2-report-scan-error "msg.illegal.character" t)))
+                  (t
+                   (if (or (eq c js2-EOF_CHAR)
+                           (not (js2-identifier-part-p c)))
+                       (throw 'break nil))
+                   (js2-add-to-string c))))))
+           (js2-unget-char)
+           (setf str (js2-collect-string js2-ts-string-buffer)
+                 (js2-token-end token) js2-ts-cursor)
+           ;; FIXME: Invalid in ES5 and ES6, see
+           ;; https://bugzilla.mozilla.org/show_bug.cgi?id=694360
+           ;; Probably should just drop this conditional.
+           (unless contains-escape
+             ;; OPT we shouldn't have to make a string (object!) to
+             ;; check if it's a keyword.
+             ;; Return the corresponding token if it's a keyword
+             (when (and (not (eq modifier 'KEYWORD_IS_NAME))
+                        (setq result (js2-string-to-keyword str)))
+               (if (and (< js2-language-version 170)
+                        (memq result '(js2-LET js2-YIELD)))
+                   ;; LET and YIELD are tokens only in 1.7 and later
+                   (setq result 'js2-NAME))
+               (when (eq result 'js2-RESERVED)
+                 (setf (js2-token-string token) str))
+               (throw 'return (js2-tt-code result))))
+           ;; If we want to intern these as Rhino does, just use (intern str)
+           (setf (js2-token-string token) str)
+           (throw 'return js2-NAME))    ; end identifier/kwd check
+         ;; is it a number?
+         (when (or (js2-digit-p c)
+                   (and (eq c ?.) (js2-digit-p (js2-peek-char))))
+           (setq js2-ts-string-buffer nil
+                 base 10)
+           (when (eq c ?0)
+             (setq c (js2-get-char))
+             (cond
+              ((or (eq c ?x) (eq c ?X))
+               (setq base 16)
+               (setq c (js2-get-char)))
+              ((and (or (eq c ?b) (eq c ?B))
+                    (>= js2-language-version 200))
+               (setq base 2)
+               (setq c (js2-get-char)))
+              ((and (or (eq c ?o) (eq c ?O))
+                    (>= js2-language-version 200))
+               (setq base 8)
+               (setq legacy-octal nil)
+               (setq c (js2-get-char)))
+              ((js2-digit-p c)
+               (setq base 'maybe-8))
+              (t
+               (js2-add-to-string ?0))))
+           (cond
+            ((eq base 16)
+             (if (> 0 (js2-x-digit-to-int c 0))
+                 (js2-report-scan-error "msg.missing.hex.digits")
+               (while (<= 0 (js2-x-digit-to-int c 0))
+                 (js2-add-to-string c)
+                 (setq c (js2-get-char)))))
+            ((eq base 2)
+             (if (not (memq c '(?0 ?1)))
+                 (js2-report-scan-error "msg.missing.binary.digits")
+               (while (memq c '(?0 ?1))
+                 (js2-add-to-string c)
+                 (setq c (js2-get-char)))))
+            ((eq base 8)
+             (if (or (> ?0 c) (< ?7 c))
+                 (js2-report-scan-error "msg.missing.octal.digits")
+               (while (and (<= ?0 c) (>= ?7 c))
+                 (js2-add-to-string c)
+                 (setq c (js2-get-char)))))
+            (t
+             (while (and (<= ?0 c) (<= c ?9))
+               ;; We permit 08 and 09 as decimal numbers, which
+               ;; makes our behavior a superset of the ECMA
+               ;; numeric grammar.  We might not always be so
+               ;; permissive, so we warn about it.
+               (when (and (eq base 'maybe-8) (>= c ?8))
+                 (js2-report-warning "msg.bad.octal.literal"
+                                     (if (eq c ?8) "8" "9"))
+                 (setq base 10))
+               (js2-add-to-string c)
+               (setq c (js2-get-char)))
+             (when (eq base 'maybe-8)
+               (setq base 8
+                     legacy-octal t))))
+           (when (and (eq base 10) (memq c '(?. ?e ?E)))
+             (when (eq c ?.)
+               (cl-loop do
+                        (js2-add-to-string c)
+                        (setq c (js2-get-char))
+                        while (js2-digit-p c)))
+             (when (memq c '(?e ?E))
+               (js2-add-to-string c)
+               (setq c (js2-get-char))
+               (when (memq c '(?+ ?-))
+                 (js2-add-to-string c)
+                 (setq c (js2-get-char)))
+               (unless (js2-digit-p c)
+                 (js2-report-scan-error "msg.missing.exponent" t))
+               (cl-loop do
+                        (js2-add-to-string c)
+                        (setq c (js2-get-char))
+                        while (js2-digit-p c))))
+           (js2-unget-char)
+           (let ((str (js2-set-string-from-buffer token)))
+             (setf (js2-token-number token) (js2-string-to-number str base)
+                   (js2-token-number-base token) base
+                   (js2-token-number-legacy-octal-p token) (and (= base 8) legacy-octal)))
+           (throw 'return js2-NUMBER))
+         ;; is it a string?
+         (when (or (memq c '(?\" ?\'))
+                   (and (>= js2-language-version 200)
+                        (= c ?`)))
+           (throw 'return
+                  (js2-get-string-or-template-token c token)))
+         (js2-ts-return token
+                        (cl-case c
+                          (?\;
+                           (throw 'return js2-SEMI))
+                          (?\[
+                           (throw 'return js2-LB))
+                          (?\]
+                           (throw 'return js2-RB))
+                          (?{
+                           (throw 'return js2-LC))
+                          (?}
+                           (throw 'return js2-RC))
+                          (?\(
+                           (throw 'return js2-LP))
+                          (?\)
+                           (throw 'return js2-RP))
+                          (?,
+                           (throw 'return js2-COMMA))
+                          (??
+                           (throw 'return js2-HOOK))
+                          (?:
+                           (if (js2-match-char ?:)
+                               js2-COLONCOLON
+                             (throw 'return js2-COLON)))
+                          (?.
+                           (if (js2-match-char ?.)
+                               (if (js2-match-char ?.)
+                                   js2-TRIPLEDOT js2-DOTDOT)
+                             (if (js2-match-char ?\()
+                                 js2-DOTQUERY
+                               (throw 'return js2-DOT))))
+                          (?|
+                           (if (js2-match-char ?|)
+                               (throw 'return js2-OR)
+                             (if (js2-match-char ?=)
+                                 js2-ASSIGN_BITOR
+                               (throw 'return js2-BITOR))))
+                          (?^
+                           (if (js2-match-char ?=)
+                               js2-ASSIGN_BITOR
+                             (throw 'return js2-BITXOR)))
+                          (?&
+                           (if (js2-match-char ?&)
+                               (throw 'return js2-AND)
+                             (if (js2-match-char ?=)
+                                 js2-ASSIGN_BITAND
+                               (throw 'return js2-BITAND))))
+                          (?=
+                           (if (js2-match-char ?=)
+                               (if (js2-match-char ?=)
+                                   js2-SHEQ
+                                 (throw 'return js2-EQ))
+                             (if (js2-match-char ?>)
+                                 (js2-ts-return token js2-ARROW)
+                               (throw 'return js2-ASSIGN))))
+                          (?!
+                           (if (js2-match-char ?=)
+                               (if (js2-match-char ?=)
+                                   js2-SHNE
+                                 js2-NE)
+                             (throw 'return js2-NOT)))
+                          (?<
+                           ;; NB:treat HTML begin-comment as comment-till-eol
+                           (when (js2-match-char ?!)
+                             (when (js2-match-char ?-)
+                               (when (js2-match-char ?-)
+                                 (js2-skip-line)
+                                 (setf (js2-token-comment-type (js2-current-token)) 'html)
+                                 (throw 'return js2-COMMENT)))
+                             (js2-unget-char))
+                           (if (js2-match-char ?<)
+                               (if (js2-match-char ?=)
+                                   js2-ASSIGN_LSH
+                                 js2-LSH)
+                             (if (js2-match-char ?=)
+                                 js2-LE
+                               (throw 'return js2-LT))))
+                          (?>
+                           (if (js2-match-char ?>)
+                               (if (js2-match-char ?>)
+                                   (if (js2-match-char ?=)
+                                       js2-ASSIGN_URSH
+                                     js2-URSH)
+                                 (if (js2-match-char ?=)
+                                     js2-ASSIGN_RSH
+                                   js2-RSH))
+                             (if (js2-match-char ?=)
+                                 js2-GE
+                               (throw 'return js2-GT))))
+                          (?*
+                           (if (js2-match-char ?=)
+                               js2-ASSIGN_MUL
+                             (if (js2-match-char ?*)
+                                 (if (js2-match-char ?=)
+                                     js2-ASSIGN_EXPON
+                                   js2-EXPON)
+                               (throw 'return js2-MUL))))
+                          (?/
+                           ;; is it a // comment?
+                           (when (js2-match-char ?/)
+                             (setf (js2-token-beg token) (- js2-ts-cursor 2))
+                             (js2-skip-line)
+                             (setf (js2-token-comment-type token) 'line)
+                             ;; include newline so highlighting goes to end of
+                             ;; window, if there actually is a newline; if we
+                             ;; hit eof, then implicitly there isn't
+                             (unless js2-ts-hit-eof
+                               (cl-incf (js2-token-end token)))
+                             (throw 'return js2-COMMENT))
+                           ;; is it a /* comment?
+                           (when (js2-match-char ?*)
+                             (setf look-for-slash nil
+                                   (js2-token-beg token) (- js2-ts-cursor 2)
+                                   (js2-token-comment-type token)
+                                   (if (js2-match-char ?*)
+                                       (progn
+                                         (setq look-for-slash t)
+                                         'jsdoc)
+                                     'block))
+                             (while t
+                               (setq c (js2-get-char))
+                               (cond
+                                ((eq c js2-EOF_CHAR)
+                                 (setf (js2-token-end token) (1- js2-ts-cursor))
+                                 (js2-report-error "msg.unterminated.comment")
+                                 (throw 'return js2-COMMENT))
+                                ((eq c ?*)
+                                 (setq look-for-slash t))
+                                ((eq c ?/)
+                                 (if look-for-slash
+                                     (js2-ts-return token js2-COMMENT)))
+                                (t
+                                 (setf look-for-slash nil
+                                       (js2-token-end token) js2-ts-cursor)))))
+                           (if (js2-match-char ?=)
+                               js2-ASSIGN_DIV
+                             (throw 'return js2-DIV)))
+                          (?#
+                           (when js2-skip-preprocessor-directives
+                             (js2-skip-line)
+                             (setf (js2-token-comment-type token) 'preprocessor
+                                   (js2-token-end token) js2-ts-cursor)
+                             (throw 'return js2-COMMENT))
+                           (throw 'return js2-ERROR))
+                          (?%
+                           (if (js2-match-char ?=)
+                               js2-ASSIGN_MOD
+                             (throw 'return js2-MOD)))
+                          (?~
+                           (throw 'return js2-BITNOT))
+                          (?+
+                           (if (js2-match-char ?=)
+                               js2-ASSIGN_ADD
+                             (if (js2-match-char ?+)
+                                 js2-INC
+                               (throw 'return js2-ADD))))
+                          (?-
+                           (cond
+                            ((js2-match-char ?=)
+                             (setq c js2-ASSIGN_SUB))
+                            ((js2-match-char ?-)
+                             (unless js2-ts-dirty-line
+                               ;; treat HTML end-comment after possible whitespace
+                               ;; after line start as comment-until-eol
+                               (when (js2-match-char ?>)
+                                 (js2-skip-line)
+                                 (setf (js2-token-comment-type (js2-current-token)) 'html)
+                                 (throw 'return js2-COMMENT)))
+                             (setq c js2-DEC))
+                            (t
+                             (setq c js2-SUB)))
+                           (setq js2-ts-dirty-line t)
+                           c)
+                          (otherwise
+                           (js2-report-scan-error "msg.illegal.character")))))))
+    (setf (js2-token-type token) tt)
+    token))
+
+(defun js2-get-string-or-template-token (quote-char token)
+  ;; We attempt to accumulate a string the fast way, by
+  ;; building it directly out of the reader.  But if there
+  ;; are any escaped characters in the string, we revert to
+  ;; building it out of a string buffer.
+  (let ((c (js2-get-char))
+        js2-ts-string-buffer
+        nc c1 val escape-val)
+    (catch 'break
+      (while (/= c quote-char)
+        (catch 'continue
+          (when (eq c js2-EOF_CHAR)
+            (js2-unget-char)
+            (js2-report-error "msg.unterminated.string.lit")
+            (throw 'break nil))
+          (when (and (eq c ?\n) (not (eq quote-char ?`)))
+            (js2-unget-char)
+            (js2-report-error "msg.unterminated.string.lit")
+            (throw 'break nil))
+          (when (eq c ?\\)
+            ;; We've hit an escaped character
+            (setq c (js2-get-char))
+            (cl-case c
+              (?b (setq c ?\b))
+              (?f (setq c ?\f))
+              (?n (setq c ?\n))
+              (?r (setq c ?\r))
+              (?t (setq c ?\t))
+              (?v (setq c ?\v))
+              (?u
+               (setq c1 (js2-read-unicode-escape))
+               (if js2-parse-ide-mode
+                   (if c1
+                       (progn
+                         ;; just copy the string in IDE-mode
+                         (js2-add-to-string ?\\)
+                         (js2-add-to-string ?u)
+                         (dotimes (_ 3)
+                           (js2-add-to-string (js2-get-char)))
+                         (setq c (js2-get-char))) ; added at end of loop
+                     ;; flag it as an invalid escape
+                     (js2-report-warning "msg.invalid.escape"
+                                         nil (- js2-ts-cursor 2) 6))
+                 ;; Get 4 hex digits; if the u escape is not
+                 ;; followed by 4 hex digits, use 'u' + the
+                 ;; literal character sequence that follows.
+                 (js2-add-to-string ?u)
+                 (setq escape-val 0)
+                 (dotimes (_ 4)
+                   (setq c (js2-get-char)
+                         escape-val (js2-x-digit-to-int c escape-val))
+                   (if (cl-minusp escape-val)
+                       (throw 'continue nil))
+                   (js2-add-to-string c))
+                 ;; prepare for replace of stored 'u' sequence by escape value
+                 (setq js2-ts-string-buffer (nthcdr 5 js2-ts-string-buffer)
+                       c escape-val)))
+              (?x
+               ;; Get 2 hex digits, defaulting to 'x'+literal
+               ;; sequence, as above.
+               (setq c (js2-get-char)
+                     escape-val (js2-x-digit-to-int c 0))
+               (if (cl-minusp escape-val)
+                   (progn
+                     (js2-add-to-string ?x)
+                     (throw 'continue nil))
+                 (setq c1 c
+                       c (js2-get-char)
+                       escape-val (js2-x-digit-to-int c escape-val))
+                 (if (cl-minusp escape-val)
+                     (progn
+                       (js2-add-to-string ?x)
+                       (js2-add-to-string c1)
+                       (throw 'continue nil))
+                   ;; got 2 hex digits
+                   (setq c escape-val))))
+              (?\n
+               ;; Remove line terminator after escape to follow
+               ;; SpiderMonkey and C/C++
+               (setq c (js2-get-char))
+               (throw 'continue nil))
+              (t
+               (when (and (<= ?0 c) (< c ?8))
+                 (setq val (- c ?0)
+                       c (js2-get-char))
+                 (when (and (<= ?0 c) (< c ?8))
+                   (setq val (- (+ (* 8 val) c) ?0)
+                         c (js2-get-char))
+                   (when (and (<= ?0 c)
+                              (< c ?8)
+                              (< val #o37))
+                     ;; c is 3rd char of octal sequence only
+                     ;; if the resulting val <= 0377
+                     (setq val (- (+ (* 8 val) c) ?0)
+                           c (js2-get-char))))
+                 (js2-unget-char)
+                 (setq c val)))))
+          (when (and (eq quote-char ?`) (eq c ?$))
+            (when (eq (setq nc (js2-get-char)) ?\{)
+              (throw 'break nil))
+            (js2-unget-char))
+          (js2-add-to-string c)
+          (setq c (js2-get-char)))))
+    (js2-set-string-from-buffer token)
+    (if (not (eq quote-char ?`))
+        js2-STRING
+      (if (and (eq c ?$) (eq nc ?\{))
+          js2-TEMPLATE_HEAD
+        js2-NO_SUBS_TEMPLATE))))
+
+(defun js2-read-regexp (start-tt start-pos)
+  "Called by parser when it gets / or /= in literal context."
+  (let (c err
+        in-class  ; inside a '[' .. ']' character-class
+        flags
+        (continue t)
+        (token (js2-new-token 0)))
+    (js2-record-text-property start-pos (1+ start-pos)
+                              'syntax-table (string-to-syntax "\"/"))
+    (setq js2-ts-string-buffer nil)
+    (if (eq start-tt js2-ASSIGN_DIV)
+        ;; mis-scanned /=
+        (js2-add-to-string ?=)
+      (if (not (eq start-tt js2-DIV))
+          (error "failed assertion")))
+    (while (and (not err)
+                (or (/= (setq c (js2-get-char)) ?/)
+                    in-class))
+      (cond
+       ((or (= c ?\n)
+            (= c js2-EOF_CHAR))
+        (setf (js2-token-end token) (1- js2-ts-cursor)
+              err t
+              (js2-token-string token) (js2-collect-string js2-ts-string-buffer))
+        (js2-report-error "msg.unterminated.re.lit"))
+       (t (cond
+           ((= c ?\\)
+            (js2-add-to-string c)
+            (setq c (js2-get-char)))
+           ((= c ?\[)
+            (setq in-class t))
+           ((= c ?\])
+            (setq in-class nil)))
+          (js2-add-to-string c))))
+    (unless err
+      (js2-record-text-property (1- js2-ts-cursor) js2-ts-cursor
+                                'syntax-table (string-to-syntax "\"/"))
+      (while continue
+        (cond
+         ((js2-match-char ?g)
+          (push ?g flags))
+         ((js2-match-char ?i)
+          (push ?i flags))
+         ((js2-match-char ?m)
+          (push ?m flags))
+         ((and (js2-match-char ?u)
+               (>= js2-language-version 200))
+          (push ?u flags))
+         ((and (js2-match-char ?y)
+               (>= js2-language-version 200))
+          (push ?y flags))
+         (t
+          (setq continue nil))))
+      (if (js2-alpha-p (js2-peek-char))
+          (js2-report-scan-error "msg.invalid.re.flag" t
+                                 js2-ts-cursor 1))
+      (js2-set-string-from-buffer token))
+    (js2-collect-string flags)))
+
+(defun js2-get-first-xml-token ()
+  (setq js2-ts-xml-open-tags-count 0
+        js2-ts-is-xml-attribute nil
+        js2-ts-xml-is-tag-content nil)
+  (js2-unget-char)
+  (js2-get-next-xml-token))
+
+(defun js2-xml-discard-string (token)
+  "Throw away the string in progress and flag an XML parse error."
+  (setf js2-ts-string-buffer nil
+        (js2-token-string token) nil)
+  (js2-report-scan-error "msg.XML.bad.form" t))
+
+(defun js2-get-next-xml-token ()
+  (setq js2-ts-string-buffer nil)  ; for recording the XML
+  (let ((token (js2-new-token 0))
+        c result)
+    (setq result
+          (catch 'return
+            (while t
+              (setq c (js2-get-char))
+              (cond
+               ((= c js2-EOF_CHAR)
+                (throw 'return js2-ERROR))
+               (js2-ts-xml-is-tag-content
+                (cl-case c
+                  (?>
+                   (js2-add-to-string c)
+                   (setq js2-ts-xml-is-tag-content nil
+                         js2-ts-is-xml-attribute nil))
+                  (?/
+                   (js2-add-to-string c)
+                   (when (eq ?> (js2-peek-char))
+                     (setq c (js2-get-char))
+                     (js2-add-to-string c)
+                     (setq js2-ts-xml-is-tag-content nil)
+                     (cl-decf js2-ts-xml-open-tags-count)))
+                  (?{
+                   (js2-unget-char)
+                   (js2-set-string-from-buffer token)
+                   (throw 'return js2-XML))
+                  ((?\' ?\")
+                   (js2-add-to-string c)
+                   (unless (js2-read-quoted-string c token)
+                     (throw 'return js2-ERROR)))
+                  (?=
+                   (js2-add-to-string c)
+                   (setq js2-ts-is-xml-attribute t))
+                  ((? ?\t ?\r ?\n)
+                   (js2-add-to-string c))
+                  (t
+                   (js2-add-to-string c)
+                   (setq js2-ts-is-xml-attribute nil)))
+                (when (and (not js2-ts-xml-is-tag-content)
+                           (zerop js2-ts-xml-open-tags-count))
+                  (js2-set-string-from-buffer token)
+                  (throw 'return js2-XMLEND)))
+               (t
+                ;; else not tag content
+                (cl-case c
+                  (?<
+                   (js2-add-to-string c)
+                   (setq c (js2-peek-char))
+                   (cl-case c
+                     (?!
+                      (setq c (js2-get-char)) ;; skip !
+                      (js2-add-to-string c)
+                      (setq c (js2-peek-char))
+                      (cl-case c
+                        (?-
+                         (setq c (js2-get-char)) ;; skip -
+                         (js2-add-to-string c)
+                         (if (eq c ?-)
+                             (progn
+                               (js2-add-to-string c)
+                               (unless (js2-read-xml-comment token)
+                                 (throw 'return js2-ERROR)))
+                           (js2-xml-discard-string token)
+                           (throw 'return js2-ERROR)))
+                        (?\[
+                         (setq c (js2-get-char)) ;; skip [
+                         (js2-add-to-string c)
+                         (if (and (= (js2-get-char) ?C)
+                                  (= (js2-get-char) ?D)
+                                  (= (js2-get-char) ?A)
+                                  (= (js2-get-char) ?T)
+                                  (= (js2-get-char) ?A)
+                                  (= (js2-get-char) ?\[))
+                             (progn
+                               (js2-add-to-string ?C)
+                               (js2-add-to-string ?D)
+                               (js2-add-to-string ?A)
+                               (js2-add-to-string ?T)
+                               (js2-add-to-string ?A)
+                               (js2-add-to-string ?\[)
+                               (unless (js2-read-cdata token)
+                                 (throw 'return js2-ERROR)))
+                           (js2-xml-discard-string token)
+                           (throw 'return js2-ERROR)))
+                        (t
+                         (unless (js2-read-entity token)
+                           (throw 'return js2-ERROR))))
+                      ;; Allow bare CDATA section, e.g.:
+                      ;;   let xml = <![CDATA[ foo bar baz ]]>;
+                      (when (zerop js2-ts-xml-open-tags-count)
+                        (throw 'return js2-XMLEND)))
+                     (??
+                      (setq c (js2-get-char)) ;; skip ?
+                      (js2-add-to-string c)
+                      (unless (js2-read-PI token)
+                        (throw 'return js2-ERROR)))
+                     (?/
+                      ;; end tag
+                      (setq c (js2-get-char)) ;; skip /
+                      (js2-add-to-string c)
+                      (when (zerop js2-ts-xml-open-tags-count)
+                        (js2-xml-discard-string token)
+                        (throw 'return js2-ERROR))
+                      (setq js2-ts-xml-is-tag-content t)
+                      (cl-decf js2-ts-xml-open-tags-count))
+                     (t
+                      ;; start tag
+                      (setq js2-ts-xml-is-tag-content t)
+                      (cl-incf js2-ts-xml-open-tags-count))))
+                  (?{
+                   (js2-unget-char)
+                   (js2-set-string-from-buffer token)
+                   (throw 'return js2-XML))
+                  (t
+                   (js2-add-to-string c))))))))
+    (setf (js2-token-end token) js2-ts-cursor)
+    (setf (js2-token-type token) result)
+    result))
+
+(defun js2-read-quoted-string (quote token)
+  (let (c)
+    (catch 'return
+      (while (/= (setq c (js2-get-char)) js2-EOF_CHAR)
+        (js2-add-to-string c)
+        (if (eq c quote)
+            (throw 'return t)))
+      (js2-xml-discard-string token)  ;; throw away string in progress
+      nil)))
+
+(defun js2-read-xml-comment (token)
+  (let ((c (js2-get-char)))
+    (catch 'return
+      (while (/= c js2-EOF_CHAR)
+        (catch 'continue
+          (js2-add-to-string c)
+          (when (and (eq c ?-) (eq ?- (js2-peek-char)))
+            (setq c (js2-get-char))
+            (js2-add-to-string c)
+            (if (eq (js2-peek-char) ?>)
+                (progn
+                  (setq c (js2-get-char)) ;; skip >
+                  (js2-add-to-string c)
+                  (throw 'return t))
+              (throw 'continue nil)))
+          (setq c (js2-get-char))))
+      (js2-xml-discard-string token)
+      nil)))
+
+(defun js2-read-cdata (token)
+  (let ((c (js2-get-char)))
+    (catch 'return
+      (while (/= c js2-EOF_CHAR)
+        (catch 'continue
+          (js2-add-to-string c)
+          (when (and (eq c ?\]) (eq (js2-peek-char) ?\]))
+            (setq c (js2-get-char))
+            (js2-add-to-string c)
+            (if (eq (js2-peek-char) ?>)
+                (progn
+                  (setq c (js2-get-char)) ;; Skip >
+                  (js2-add-to-string c)
+                  (throw 'return t))
+              (throw 'continue nil)))
+          (setq c (js2-get-char))))
+      (js2-xml-discard-string token)
+      nil)))
+
+(defun js2-read-entity (token)
+  (let ((decl-tags 1)
+        c)
+    (catch 'return
+      (while (/= js2-EOF_CHAR (setq c (js2-get-char)))
+        (js2-add-to-string c)
+        (cl-case c
+          (?<
+           (cl-incf decl-tags))
+          (?>
+           (cl-decf decl-tags)
+           (if (zerop decl-tags)
+               (throw 'return t)))))
+      (js2-xml-discard-string token)
+      nil)))
+
+(defun js2-read-PI (token)
+  "Scan an XML processing instruction."
+  (let (c)
+    (catch 'return
+      (while (/= js2-EOF_CHAR (setq c (js2-get-char)))
+        (js2-add-to-string c)
+        (when (and (eq c ??) (eq (js2-peek-char) ?>))
+          (setq c (js2-get-char))  ;; Skip >
+          (js2-add-to-string c)
+          (throw 'return t)))
+      (js2-xml-discard-string token)
+      nil)))
+
+;;; Highlighting
+
+(defun js2-set-face (beg end face &optional record)
+  "Fontify a region.  If RECORD is non-nil, record for later."
+  (when (cl-plusp js2-highlight-level)
+    (setq beg (min (point-max) beg)
+          beg (max (point-min) beg)
+          end (min (point-max) end)
+          end (max (point-min) end))
+    (if record
+        (push (list beg end face) js2-mode-fontifications)
+      (put-text-property beg end 'font-lock-face face))))
+
+(defsubst js2-clear-face (beg end)
+  (remove-text-properties beg end '(font-lock-face nil
+                                    help-echo nil
+                                    point-entered nil
+                                    cursor-sensor-functions nil
+                                    c-in-sws nil)))
+
+(defconst js2-ecma-global-props
+  (concat "^"
+          (regexp-opt
+           '("Infinity" "NaN" "undefined" "arguments") t)
+          "$")
+  "Value properties of the Ecma-262 Global Object.
+Shown at or above `js2-highlight-level' 2.")
+
+;; might want to add the name "arguments" to this list?
+(defconst js2-ecma-object-props
+  (concat "^"
+          (regexp-opt
+           '("prototype" "__proto__" "__parent__") t)
+          "$")
+  "Value properties of the Ecma-262 Object constructor.
+Shown at or above `js2-highlight-level' 2.")
+
+(defconst js2-ecma-global-funcs
+  (concat
+   "^"
+   (regexp-opt
+    '("decodeURI" "decodeURIComponent" "encodeURI" "encodeURIComponent"
+      "eval" "isFinite" "isNaN" "parseFloat" "parseInt") t)
+   "$")
+  "Function properties of the Ecma-262 Global object.
+Shown at or above `js2-highlight-level' 2.")
+
+(defconst js2-ecma-number-props
+  (concat "^"
+          (regexp-opt '("MAX_VALUE" "MIN_VALUE" "NaN"
+                        "NEGATIVE_INFINITY"
+                        "POSITIVE_INFINITY") t)
+          "$")
+  "Properties of the Ecma-262 Number constructor.
+Shown at or above `js2-highlight-level' 2.")
+
+(defconst js2-ecma-date-props "^\\(parse\\|UTC\\)$"
+  "Properties of the Ecma-262 Date constructor.
+Shown at or above `js2-highlight-level' 2.")
+
+(defconst js2-ecma-math-props
+  (concat "^"
+          (regexp-opt
+           '("E" "LN10" "LN2" "LOG2E" "LOG10E" "PI" "SQRT1_2" "SQRT2")
+           t)
+          "$")
+  "Properties of the Ecma-262 Math object.
+Shown at or above `js2-highlight-level' 2.")
+
+(defconst js2-ecma-math-funcs
+  (concat "^"
+          (regexp-opt
+           '("abs" "acos" "asin" "atan" "atan2" "ceil" "cos" "exp" "floor"
+             "log" "max" "min" "pow" "random" "round" "sin" "sqrt" "tan") t)
+          "$")
+  "Function properties of the Ecma-262 Math object.
+Shown at or above `js2-highlight-level' 2.")
+
+(defconst js2-ecma-function-props
+  (concat
+   "^"
+   (regexp-opt
+    '(;; properties of the Object prototype object
+      "hasOwnProperty" "isPrototypeOf" "propertyIsEnumerable"
+      "toLocaleString" "toString" "valueOf"
+      ;; properties of the Function prototype object
+      "apply" "call"
+      ;; properties of the Array prototype object
+      "concat" "join" "pop" "push" "reverse" "shift" "slice" "sort"
+      "splice" "unshift"
+      ;; properties of the String prototype object
+      "charAt" "charCodeAt" "fromCharCode" "indexOf" "lastIndexOf"
+      "localeCompare" "match" "replace" "search" "split" "substring"
+      "toLocaleLowerCase" "toLocaleUpperCase" "toLowerCase"
+      "toUpperCase"
+      ;; properties of the Number prototype object
+      "toExponential" "toFixed" "toPrecision"
+      ;; properties of the Date prototype object
+      "getDate" "getDay" "getFullYear" "getHours" "getMilliseconds"
+      "getMinutes" "getMonth" "getSeconds" "getTime"
+      "getTimezoneOffset" "getUTCDate" "getUTCDay" "getUTCFullYear"
+      "getUTCHours" "getUTCMilliseconds" "getUTCMinutes" "getUTCMonth"
+      "getUTCSeconds" "setDate" "setFullYear" "setHours"
+      "setMilliseconds" "setMinutes" "setMonth" "setSeconds" "setTime"
+      "setUTCDate" "setUTCFullYear" "setUTCHours" "setUTCMilliseconds"
+      "setUTCMinutes" "setUTCMonth" "setUTCSeconds" "toDateString"
+      "toLocaleDateString" "toLocaleString" "toLocaleTimeString"
+      "toTimeString" "toUTCString"
+      ;; properties of the RegExp prototype object
+      "exec" "test"
+      ;; properties of the JSON prototype object
+      "parse" "stringify"
+      ;; SpiderMonkey/Rhino extensions, versions 1.5+
+      "toSource" "__defineGetter__" "__defineSetter__"
+      "__lookupGetter__" "__lookupSetter__" "__noSuchMethod__"
+      "every" "filter" "forEach" "lastIndexOf" "map" "some")
+    t)
+   "$")
+  "Built-in functions defined by Ecma-262 and SpiderMonkey extensions.
+Shown at or above `js2-highlight-level' 3.")
+
+(defun js2-parse-highlight-prop-get (parent target prop call-p)
+  (let ((target-name (and target
+                          (js2-name-node-p target)
+                          (js2-name-node-name target)))
+        (prop-name (if prop (js2-name-node-name prop)))
+        (level2 (>= js2-highlight-level 2))
+        (level3 (>= js2-highlight-level 3)))
+    (when level2
+      (let ((face
+             (if call-p
+                 (cond
+                  ((and target prop)
+                   (cond
+                    ((and level3 (string-match js2-ecma-function-props prop-name))
+                     'font-lock-builtin-face)
+                    ((and target-name prop)
+                     (cond
+                      ((string= target-name "Date")
+                       (if (string-match js2-ecma-date-props prop-name)
+                           'font-lock-builtin-face))
+                      ((string= target-name "Math")
+                       (if (string-match js2-ecma-math-funcs prop-name)
+                           'font-lock-builtin-face))))))
+                  (prop
+                   (if (string-match js2-ecma-global-funcs prop-name)
+                       'font-lock-builtin-face)))
+               (cond
+                ((and target prop)
+                 (cond
+                  ((string= target-name "Number")
+                   (if (string-match js2-ecma-number-props prop-name)
+                       'font-lock-constant-face))
+                  ((string= target-name "Math")
+                   (if (string-match js2-ecma-math-props prop-name)
+                       'font-lock-constant-face))))
+                (prop
+                 (if (string-match js2-ecma-object-props prop-name)
+                     'font-lock-constant-face))))))
+        (when (and (not face) target (not call-p) prop-name)
+          (setq face 'js2-object-property-access))
+        (when face
+          (let ((pos (+ (js2-node-pos parent)  ; absolute
+                        (js2-node-pos prop)))) ; relative
+            (js2-set-face pos
+                          (+ pos (js2-node-len prop))
+                          face 'record)))))))
+
+(defun js2-parse-highlight-member-expr-node (node)
+  "Perform syntax highlighting of EcmaScript built-in properties.
+The variable `js2-highlight-level' governs this highlighting."
+  (let (face target prop name pos end parent call-p callee)
+    (cond
+     ;; case 1:  simple name, e.g. foo
+     ((js2-name-node-p node)
+      (setq name (js2-name-node-name node))
+      ;; possible for name to be nil in rare cases - saw it when
+      ;; running js2-mode on an elisp buffer.  Might as well try to
+      ;; make it so js2-mode never barfs.
+      (when name
+        (setq face (if (string-match js2-ecma-global-props name)
+                       'font-lock-constant-face))
+        (when face
+          (setq pos (js2-node-pos node)
+                end (+ pos (js2-node-len node)))
+          (js2-set-face pos end face 'record))))
+     ;; case 2:  property access or function call
+     ((or (js2-prop-get-node-p node)
+          ;; highlight function call if expr is a prop-get node
+          ;; or a plain name (i.e. unqualified function call)
+          (and (setq call-p (js2-call-node-p node))
+               (setq callee (js2-call-node-target node)) ; separate setq!
+               (or (js2-prop-get-node-p callee)
+                   (js2-name-node-p callee))))
+      (setq parent node
+            node (if call-p callee node))
+      (if (and call-p (js2-name-node-p callee))
+          (setq prop callee)
+        (setq target (js2-prop-get-node-left node)
+              prop (js2-prop-get-node-right node)))
+      (cond
+       ((js2-name-node-p prop)
+        ;; case 2(a&c):  simple or complex target, simple name, e.g. x[y].bar
+        (js2-parse-highlight-prop-get parent target prop call-p))
+       ((js2-name-node-p target)
+        ;; case 2b:  simple target, complex name, e.g. foo.x[y]
+        (js2-parse-highlight-prop-get parent target nil call-p)))))))
+
+(defun js2-parse-highlight-member-expr-fn-name (expr)
+  "Highlight the `baz' in function foo.bar.baz(args) {...}.
+This is experimental Rhino syntax.  EXPR is the foo.bar.baz member expr.
+We currently only handle the case where the last component is a prop-get
+of a simple name.  Called before EXPR has a parent node."
+  (let (pos
+        (name (and (js2-prop-get-node-p expr)
+                   (js2-prop-get-node-right expr))))
+    (when (js2-name-node-p name)
+      (js2-set-face (setq pos (+ (js2-node-pos expr)  ; parent is absolute
+                                 (js2-node-pos name)))
+                    (+ pos (js2-node-len name))
+                    'font-lock-function-name-face
+                    'record))))
+
+;; source:  http://jsdoc.sourceforge.net/
+;; Note - this syntax is for Google's enhanced jsdoc parser that
+;; allows type specifications, and needs work before entering the wild.
+
+(defconst js2-jsdoc-param-tag-regexp
+  (concat "^\\s-*\\*+\\s-*\\(@"
+          (regexp-opt '("param" "arg" "argument" "prop" "property" "typedef"))
+          "\\)"
+          "\\s-*\\({[^}]+}\\)?"         ; optional type
+          "\\s-*\\[?\\([[:alnum:]_$\.]+\\)?\\]?"  ; name
+          "\\_>")
+  "Matches jsdoc tags with optional type and optional param name.")
+
+(defconst js2-jsdoc-typed-tag-regexp
+  (concat "^\\s-*\\*+\\s-*\\(@\\(?:"
+          (regexp-opt
+           '("enum"
+             "extends"
+             "field"
+             "id"
+             "implements"
+             "lends"
+             "mods"
+             "requires"
+             "return"
+             "returns"
+             "yield"
+             "yields"
+             "type"
+             "throw"
+             "throws"))
+          "\\)\\)\\s-*\\({[^}]+}\\)?")
+  "Matches jsdoc tags with optional type.")
+
+(defconst js2-jsdoc-arg-tag-regexp
+  (concat "^\\s-*\\*+\\s-*\\(@\\(?:"
+          (regexp-opt
+           '("alias"
+             "augments"
+             "borrows"
+             "callback"
+             "bug"
+             "base"
+             "config"
+             "default"
+             "define"
+             "exception"
+             "func"
+             "function"
+             "member"
+             "memberOf"
+             "method"
+             "module"
+             "name"
+             "namespace"
+             "since"
+             "suppress"
+             "this"
+             "throws"
+             "version"))
+          "\\)\\)\\s-+\\([^ \t\n]+\\)")
+  "Matches jsdoc tags with a single argument.")
+
+(defconst js2-jsdoc-empty-tag-regexp
+  (concat "^\\s-*\\*+\\s-*\\(@\\(?:"
+          (regexp-opt
+           '("abstract"
+             "addon"
+             "author"
+             "class"
+             "const"
+             "constant"
+             "constructor"
+             "constructs"
+             "deprecated"
+             "desc"
+             "description"
+             "event"
+             "example"
+             "exec"
+             "export"
+             "fileoverview"
+             "final"
+             "func"
+             "function"
+             "hidden"
+             "ignore"
+             "implicitCast"
+             "inheritDoc"
+             "inner"
+             "interface"
+             "license"
+             "method"
+             "noalias"
+             "noshadow"
+             "notypecheck"
+             "override"
+             "owner"
+             "preserve"
+             "preserveTry"
+             "private"
+             "protected"
+             "public"
+             "static"
+             "supported"
+             "virtual"
+             ))
+          "\\)\\)\\s-*")
+  "Matches empty jsdoc tags.")
+
+(defconst js2-jsdoc-link-tag-regexp
+  "{\\(@\\(?:link\\|code\\)\\)\\s-+\\([^#}\n]+\\)\\(#.+\\)?}"
+  "Matches a jsdoc link or code tag.")
+
+(defconst js2-jsdoc-see-tag-regexp
+  "^\\s-*\\*+\\s-*\\(@see\\)\\s-+\\([^#}\n]+\\)\\(#.+\\)?"
+  "Matches a jsdoc @see tag.")
+
+(defconst js2-jsdoc-html-tag-regexp
+  "\\(</?\\)\\([[:alpha:]]+\\)\\s-*\\(/?>\\)"
+  "Matches a simple (no attributes) html start- or end-tag.")
+
+(defun js2-jsdoc-highlight-helper ()
+  (js2-set-face (match-beginning 1)
+                (match-end 1)
+                'js2-jsdoc-tag)
+  (if (match-beginning 2)
+      (if (save-excursion
+            (goto-char (match-beginning 2))
+            (= (char-after) ?{))
+          (js2-set-face (1+ (match-beginning 2))
+                        (1- (match-end 2))
+                        'js2-jsdoc-type)
+        (js2-set-face (match-beginning 2)
+                      (match-end 2)
+                      'js2-jsdoc-value)))
+  (if (match-beginning 3)
+      (js2-set-face (match-beginning 3)
+                    (match-end 3)
+                    'js2-jsdoc-value)))
+
+(defun js2-highlight-jsdoc (ast)
+  "Highlight doc comment tags."
+  (let ((comments (js2-ast-root-comments ast))
+        beg end)
+    (save-excursion
+      (dolist (node comments)
+        (when (eq (js2-comment-node-format node) 'jsdoc)
+          ;; Slice off the leading /* and trailing */ in case there
+          ;; are tags on the first line
+          (setq beg (+ 2 (js2-node-abs-pos node))
+                end (+ beg -4 (js2-node-len node)))
+          (save-restriction
+            (narrow-to-region beg end)
+            (dolist (re (list js2-jsdoc-param-tag-regexp
+                              js2-jsdoc-typed-tag-regexp
+                              js2-jsdoc-arg-tag-regexp
+                              js2-jsdoc-link-tag-regexp
+                              js2-jsdoc-see-tag-regexp
+                              js2-jsdoc-empty-tag-regexp))
+              (goto-char beg)
+              (while (re-search-forward re nil t)
+                (js2-jsdoc-highlight-helper)))
+            ;; simple highlighting for html tags
+            (goto-char beg)
+            (while (re-search-forward js2-jsdoc-html-tag-regexp nil t)
+              (js2-set-face (match-beginning 1)
+                            (match-end 1)
+                            'js2-jsdoc-html-tag-delimiter)
+              (js2-set-face (match-beginning 2)
+                            (match-end 2)
+                            'js2-jsdoc-html-tag-name)
+              (js2-set-face (match-beginning 3)
+                            (match-end 3)
+                            'js2-jsdoc-html-tag-delimiter))))))))
+
+(defun js2-highlight-assign-targets (_node left right)
+  "Highlight function properties and external variables."
+  (let (leftpos name)
+    ;; highlight vars and props assigned function values
+    (when (or (js2-function-node-p right)
+              (js2-class-node-p right))
+      (cond
+       ;; var foo = function() {...}
+       ((js2-name-node-p left)
+        (setq name left))
+       ;; foo.bar.baz = function() {...}
+       ((and (js2-prop-get-node-p left)
+             (js2-name-node-p (js2-prop-get-node-right left)))
+        (setq name (js2-prop-get-node-right left))))
+      (when name
+        (js2-set-face (setq leftpos (js2-node-abs-pos name))
+                      (+ leftpos (js2-node-len name))
+                      'font-lock-function-name-face
+                      'record)))))
+
+(defun js2-record-name-node (node)
+  "Saves NODE to `js2-recorded-identifiers' to check for undeclared variables
+later. NODE must be a name node."
+  (let ((leftpos (js2-node-abs-pos node)))
+    (push (list node js2-current-scope
+                leftpos
+                (+ leftpos (js2-node-len node)))
+          js2-recorded-identifiers)))
+
+(defun js2-highlight-undeclared-vars ()
+  "After entire parse is finished, look for undeclared variable references.
+We have to wait until entire buffer is parsed, since JavaScript permits var
+declarations to occur after they're used.
+
+Some identifiers may be assumed to be externally defined.
+These externs are not highlighted, even if there is no declaration
+for them in the source code (in the current file).
+
+The list of externs consists of the following:
+
+  - `js2-ecma262-externs' for basic names from the ECMAScript language standard.
+  - Depending on the buffer-local variables `js2-include-*-externs'
+    the corresponding `js2-*-externs' to add names for certain environments
+    like the browser, Node or Rhino.
+  - Two customizable lists `js2-global-externs' and `js2-additional-externs',
+    the latter of which should be set per-buffer.
+
+See especially `js2-additional-externs' for further details about externs."
+  (let ((default-externs
+          (append js2-ecma-262-externs
+                  (if (and js2-include-browser-externs
+                           (>= js2-language-version 200)) js2-harmony-externs)
+                  (if js2-include-rhino-externs js2-rhino-externs)
+                  (if js2-include-node-externs js2-node-externs)
+                  (if (or js2-include-browser-externs js2-include-node-externs)
+                      js2-typed-array-externs)
+                  (if js2-include-browser-externs js2-browser-externs)))
+        name)
+    (dolist (entry js2-recorded-identifiers)
+      (cl-destructuring-bind (name-node scope pos end) entry
+        (setq name (js2-name-node-name name-node))
+        (unless (or (member name js2-global-externs)
+                    (member name default-externs)
+                    (member name js2-additional-externs)
+                    (js2-get-defining-scope scope name pos))
+          (js2-report-warning "msg.undeclared.variable" name pos (- end pos)
+                              'js2-external-variable))))))
+
+(defun js2--add-or-update-symbol (symbol inition used vars)
+  "Add or update SYMBOL entry in VARS, an hash table.
+SYMBOL is a js2-name-node, INITION either nil, t, or ?P,
+respectively meaning that SYMBOL is a mere declaration, an
+assignment or a function parameter; when USED is t, the symbol
+node is assumed to be an usage and thus added to the list stored
+in the cdr of the entry.
+"
+  (let* ((nm (js2-name-node-name symbol))
+         (es (js2-node-get-enclosing-scope symbol))
+         (ds (js2-get-defining-scope es nm)))
+    (when (and ds (not (equal nm "arguments")))
+      (let* ((sym (js2-scope-get-symbol ds nm))
+             (var (gethash sym vars))
+             (err-var-p (js2-catch-node-p ds)))
+        (unless inition
+          (setq inition err-var-p))
+        (if var
+            (progn
+              (when (and inition (not (equal (car var) ?P)))
+                (setcar var inition))
+              (when (and used (not (memq symbol (cdr var))))
+                (push symbol (cdr var))))
+          ;; do not consider the declaration of catch parameter as an usage
+          (when (and err-var-p used)
+            (setq used nil))
+          (puthash sym (cons inition (if used (list symbol))) vars))))))
+
+(defun js2--collect-target-symbols (node strict)
+  "Collect the `js-name-node' symbols declared in NODE and return a list of them.
+NODE is either `js2-array-node', `js2-object-node', or `js2-name-node'.
+When STRICT, signal an error if NODE is not one of the expected types."
+  (let (targets)
+    (cond
+     ((js2-name-node-p node)
+      (push node targets))
+     ((js2-array-node-p node)
+      (dolist (elt (js2-array-node-elems node))
+        (when elt
+          (setq elt (cond ((js2-infix-node-p elt) ;; default (=)
+                           (js2-infix-node-left elt))
+                          ((js2-unary-node-p elt) ;; rest (...)
+                           (js2-unary-node-operand elt))
+                          (t elt)))
+          (setq targets (append (js2--collect-target-symbols elt strict)
+                                targets)))))
+     ((js2-object-node-p node)
+      (dolist (elt (js2-object-node-elems node))
+        (let ((subexpr (cond
+                        ((and (js2-infix-node-p elt)
+                              (= js2-ASSIGN (js2-infix-node-type elt)))
+                         ;; Destructuring with default argument.
+                         (js2-infix-node-left elt))
+                        ((and (js2-infix-node-p elt)
+                              (= js2-COLON (js2-infix-node-type elt)))
+                         ;; In regular destructuring {a: aa, b: bb},
+                         ;; the var is on the right.  In abbreviated
+                         ;; destructuring {a, b}, right == left.
+                         (js2-infix-node-right elt))
+                        ((and (js2-unary-node-p elt)
+                              (= js2-TRIPLEDOT (js2-unary-node-type elt)))
+                         ;; Destructuring with spread.
+                         (js2-unary-node-operand elt)))))
+          (when subexpr
+            (setq targets (append
+                           (js2--collect-target-symbols subexpr strict)
+                           targets))))))
+     ((js2-assign-node-p node)
+      (setq targets (append (js2--collect-target-symbols
+                             (js2-assign-node-left node) strict)
+                            targets)))
+     (strict
+      (js2-report-error "msg.no.parm" nil (js2-node-abs-pos node)
+                        (js2-node-len node))
+        nil))
+    targets))
+
+(defun js2--examine-variable (parent node var-init-node)
+  "Examine the usage of the variable NODE, a js2-name-node.
+PARENT is its direct ancestor and VAR-INIT-NODE is the node to be
+examined: return a list of three values, respectively if the
+variable is declared and/or assigned or whether it is simply a
+key of a literal object."
+  (let ((target (js2-var-init-node-target var-init-node))
+        declared assigned object-key)
+    (setq declared (memq node (js2--collect-target-symbols target nil)))
+    ;; Is there an initializer for the declared variable?
+    (when (js2-var-init-node-initializer var-init-node)
+      (setq assigned declared)
+      ;; Determine if the name is actually a literal object key that we shall
+      ;; ignore later
+      (when (and (not declared)
+                 (js2-object-prop-node-p parent)
+                 (eq node (js2-object-prop-node-left parent)))
+        (setq object-key t)))
+    ;; Maybe this is a for loop and the variable is one of its iterators?
+    (unless assigned
+      (let* ((gp (js2-node-parent parent))
+             (ggp (if gp (js2-node-parent gp))))
+        (when (and ggp (js2-for-in-node-p ggp))
+          (setq assigned (memq node
+                               (cl-loop
+                                for kid in (js2-var-decl-node-kids
+                                            (js2-for-in-node-iterator ggp))
+                                with syms = '()
+                                do
+                                (setq syms (append syms
+                                                   (js2--collect-target-symbols
+                                                    (js2-var-init-node-target kid)
+                                                    nil)))
+                                finally return syms))))))
+    (list declared assigned object-key)))
+
+(defun js2--classify-variable (parent node vars)
+  "Classify the single variable NODE, a js2-name-node."
+  (let ((function-param (and (js2-function-node-p parent)
+                             (memq node (js2-function-node-params parent)))))
+    (if (js2-prop-get-node-p parent)
+        ;; If we are within a prop-get, e.g. the "bar" in "foo.bar",
+        ;; just mark "foo" as used
+        (let ((left (js2-prop-get-node-left parent)))
+          (when (js2-name-node-p left)
+            (js2--add-or-update-symbol left nil t vars)))
+      ;; If the node is the external name of an export-binding-node, and
+      ;; it is different from the local name, ignore it
+      (when (or (not (js2-export-binding-node-p parent))
+                (not (and (eq (js2-export-binding-node-extern-name parent) node)
+                          (not (eq (js2-export-binding-node-local-name parent) node)))))
+        (let ((granparent parent)
+              var-init-node
+              assign-node
+              object-key         ; is name actually an object prop key?
+              declared           ; is it declared in narrowest scope?
+              assigned           ; does it get assigned or initialized?
+              (used (null function-param)))
+          ;; Determine the closest var-init-node and assign-node: this
+          ;; is needed because the name may be within a "destructured"
+          ;; declaration/assignment, so we cannot just take its parent
+          (while (and granparent (not (js2-scope-p granparent)))
+            (cond
+             ((js2-var-init-node-p granparent)
+              (when (null var-init-node)
+                (setq var-init-node granparent)))
+             ((js2-assign-node-p granparent)
+              (when (null assign-node)
+                (setq assign-node granparent))))
+            (setq granparent (js2-node-parent granparent)))
+
+          ;; If we are within a var-init-node, determine if the name is
+          ;; declared and initialized
+          (when var-init-node
+            (let ((result (js2--examine-variable parent node var-init-node)))
+              (setq declared (car result)
+                    assigned (cadr result)
+                    object-key (car (cddr result)))))
+
+          ;; Ignore literal object keys, which are not really variables
+          (unless object-key
+            (when function-param
+              (setq assigned ?P))
+
+            (when (null assigned)
+              (cond
+               ((js2-for-in-node-p parent)
+                (setq assigned (eq node (js2-for-in-node-iterator parent))
+                      used (not assigned)))
+               ((js2-function-node-p parent)
+                (setq assigned t
+                      used (js2-wrapper-function-p parent)))
+               ((js2-export-binding-node-p parent)
+                (if (js2-import-clause-node-p (js2-node-parent parent))
+                    (setq declared t
+                          assigned t)
+                  (setq used t)))
+               ((js2-namespace-import-node-p parent)
+                (setq assigned t
+                      used nil))
+               (assign-node
+                (setq assigned (memq node
+                                     (js2--collect-target-symbols
+                                      (js2-assign-node-left assign-node)
+                                      nil))
+                      used (not assigned)))))
+
+            (when declared
+              (setq used nil))
+
+            (js2--add-or-update-symbol node assigned used vars)))))))
+
+(defun js2--classify-variables ()
+  "Collect and classify variables declared or used within js2-mode-ast.
+Traverse the whole ast tree returning a summary of the variables
+usage as an hash-table, keyed by their corresponding symbol table
+entry.
+Each variable is described by a tuple where the car is a flag
+indicating whether the variable has been initialized and the cdr
+is a possibly empty list of name nodes where it is used. External
+symbols, i.e. those not present in the whole scopes hierarchy,
+are ignored."
+  (let ((vars (make-hash-table :test #'eq :size 100)))
+    (js2-visit-ast
+     js2-mode-ast
+     (lambda (node end-p)
+       (when (and (null end-p) (js2-name-node-p node))
+         (let ((parent (js2-node-parent node)))
+           (when parent
+             (js2--classify-variable parent node vars))))
+       t))
+    vars))
+
+(defun js2--get-name-node (node)
+  (cond
+   ((js2-name-node-p node) node)
+   ((js2-function-node-p node)
+    (js2-function-node-name node))
+   ((js2-class-node-p node)
+    (js2-class-node-name node))
+   ((js2-comp-loop-node-p node)
+    (js2-comp-loop-node-iterator node))
+   (t node)))
+
+(defun js2--highlight-unused-variable (symbol info)
+  (let ((name (js2-symbol-name symbol))
+        (inited (car info))
+        (refs (cdr info))
+        pos len)
+    (unless (and inited refs)
+      (if refs
+          (dolist (ref refs)
+            (setq pos (js2-node-abs-pos ref))
+            (setq len (js2-name-node-len ref))
+            (js2-report-warning "msg.uninitialized.variable" name pos len
+                                'js2-warning))
+        (when (or js2-warn-about-unused-function-arguments
+                  (not (eq inited ?P)))
+          (let* ((symn (js2-symbol-ast-node symbol))
+                 (namen (js2--get-name-node symn)))
+            (unless (js2-node-top-level-decl-p namen)
+              (setq pos (js2-node-abs-pos namen))
+              (setq len (js2-name-node-len namen))
+              (js2-report-warning "msg.unused.variable" name pos len
+                                  'js2-warning))))))))
+
+(defun js2-highlight-unused-variables ()
+  "Highlight unused variables."
+  (let ((vars (js2--classify-variables)))
+    (maphash #'js2--highlight-unused-variable vars)))
+
+;;;###autoload
+(define-minor-mode js2-highlight-unused-variables-mode
+  "Toggle highlight of unused variables."
+  :lighter ""
+  (if js2-highlight-unused-variables-mode
+      (add-hook 'js2-post-parse-callbacks
+                #'js2-highlight-unused-variables nil t)
+    (remove-hook 'js2-post-parse-callbacks
+                 #'js2-highlight-unused-variables t)))
+
+(defun js2-add-additional-externs (externs)
+  (setq js2-additional-externs
+        (nconc externs
+               js2-additional-externs)))
+
+(defun js2-get-jslint-comment-identifiers (comment)
+  (js2-reparse)
+  (cl-loop for node in (js2-ast-root-comments js2-mode-ast)
+           when (and (eq 'block (js2-comment-node-format node))
+                     (save-excursion
+                       (goto-char (js2-node-abs-pos node))
+                       (looking-at (concat "/\\* *" comment "\\(?: \\|$\\)"))))
+           append (js2-get-jslint-comment-identifiers-in
+                   (match-end 0)
+                   (js2-node-abs-end node))))
+
+(defun js2-get-jslint-comment-identifiers-in (beg end)
+  (let (res)
+    (save-excursion
+      (goto-char beg)
+      (while (re-search-forward js2-mode-identifier-re end t)
+        (let ((match (match-string 0)))
+          (unless (member match '("true" "false"))
+            (push match res)))))
+    (nreverse res)))
+
+(defun js2-apply-jslint-globals ()
+  (js2-add-additional-externs (js2-get-jslint-globals)))
+
+(defun js2-get-jslint-globals ()
+  (js2-get-jslint-comment-identifiers "global"))
+
+(defun js2-apply-jslint-declaration-externs ()
+  (js2-add-additional-externs (js2-get-jslint-declaration-externs)))
+
+(defvar js2-jslint-declaration-externs
+  `(("browser" . ,(mapcar 'symbol-name
+                          '(Audio clearInterval clearTimeout document
+                            event history Image location name
+                            navigator Option screen setInterval
+                            setTimeout XMLHttpRequest)))
+    ("node" . ,(mapcar 'symbol-name
+                       '(Buffer clearImmediate clearInterval
+                         clearTimeout console exports global module
+                         process querystring require setImmediate
+                         setInterval setTimeout __dirname
+                         __filename)))
+    ("es6" . ,(mapcar 'symbol-name
+                      '(ArrayBuffer DataView Float32Array
+                        Float64Array Int8Array Int16Array Int32Array
+                        Intl Map Promise Proxy Reflect Set Symbol
+                        System Uint8Array Uint8ClampedArray
+                        Uint16Array Uint32Array WeakMap WeakSet)))
+    ("couch" . ,(mapcar 'symbol-name
+                        '(emit getRow isArray log provides
+                          registerType require send start sum
+                          toJSON)))
+    ("devel" . ,(mapcar 'symbol-name
+                        '(alert confirm console Debug opera prompt
+                          WSH)))))
+
+(defun js2-get-jslint-declaration-externs ()
+  (apply 'append
+         (mapcar (lambda (identifier)
+                   (cdr (assoc identifier
+                               js2-jslint-declaration-externs)))
+                 (js2-get-jslint-comment-identifiers "jslint"))))
+
+;;; IMenu support
+
+;; We currently only support imenu, but eventually should support speedbar and
+;; possibly other browsing mechanisms.
+
+;; The basic strategy is to identify function assignment targets of the form
+;; `foo.bar.baz', convert them to (list fn foo bar baz <position>), and push the
+;; list into `js2-imenu-recorder'.  The lists are merged into a trie-like tree
+;; for imenu after parsing is finished.
+
+;; A `foo.bar.baz' assignment target may be expressed in many ways in
+;; JavaScript, and the general problem is undecidable.  However, several forms
+;; are readily recognizable at parse-time; the forms we attempt to recognize
+;; include:
+
+;;  function foo()  -- function declaration
+;;  foo = function()  -- function expression assigned to variable
+;;  foo.bar.baz = function()  -- function expr assigned to nested property-get
+;;  foo = {bar: function()}  -- fun prop in object literal assigned to var
+;;  foo = {bar: {baz: function()}} -- inside nested object literal
+;;  foo.bar = {baz: function()}} -- obj lit assigned to nested prop get
+;;  a.b = {c: {d: function()}} -- nested obj lit assigned to nested prop get
+;;  foo = {get bar() {...}}  -- getter/setter in obj literal
+;;  function foo() {function bar() {...}}  -- nested function
+;;  foo['a'] = function()  -- fun expr assigned to deterministic element-get
+
+;; This list boils down to a few forms that can be combined recursively.
+;; Top-level named function declarations include both the left-hand (name)
+;; and the right-hand (function value) expressions needed to produce an imenu
+;; entry.  The other "right-hand" forms we need to look for are:
+;;  - functions declared as props/getters/setters in object literals
+;;  - nested named function declarations
+;; The "left-hand" expressions that functions can be assigned to include:
+;;  - local/global variables
+;;  - nested property-get expressions like a.b.c.d
+;;  - element gets like foo[10] or foo['bar'] where the index
+;;    expression can be trivially converted to a property name.  They
+;;    effectively then become property gets.
+
+;; All the different definition types are canonicalized into the form
+;; foo.bar.baz = position-of-function-keyword
+
+;; We need to build a trie-like structure for imenu.  As an example,
+;; consider the following JavaScript code:
+
+;; a = function() {...}  // function at position 5
+;; b = function() {...}  // function at position 25
+;; foo = function() {...} // function at position 100
+;; foo.bar = function() {...} // function at position 200
+;; foo.bar.baz = function() {...} // function at position 300
+;; foo.bar.zab = function() {...} // function at position 400
+
+;; During parsing we accumulate an entry for each definition in
+;; the variable `js2-imenu-recorder', like so:
+
+;; '((fn a 5)
+;;   (fn b 25)
+;;   (fn foo 100)
+;;   (fn foo bar 200)
+;;   (fn foo bar baz 300)
+;;   (fn foo bar zab 400))
+
+;; Where 'fn' is the respective function node.
+;; After parsing these entries are merged into this alist-trie:
+
+;; '((a . 1)
+;;   (b . 2)
+;;   (foo (<definition> . 3)
+;;        (bar (<definition> . 6)
+;;             (baz . 100)
+;;             (zab . 200))))
+
+;; Note the wacky need for a <definition> name.  The token can be anything
+;; that isn't a valid JavaScript identifier, because you might make foo
+;; a function and then start setting properties on it that are also functions.
+
+(defun js2-prop-node-name (node)
+  "Return the name of a node that may be a property-get/property-name.
+If NODE is not a valid name-node, string-node or integral number-node,
+returns nil.  Otherwise returns the string name/value of the node."
+  (cond
+   ((js2-name-node-p node)
+    (js2-name-node-name node))
+   ((js2-string-node-p node)
+    (js2-string-node-value node))
+   ((and (js2-number-node-p node)
+         (string-match "^[0-9]+$" (js2-number-node-value node)))
+    (js2-number-node-value node))
+   ((eq (js2-node-type node) js2-THIS)
+    "this")
+   ((eq (js2-node-type node) js2-SUPER)
+    "super")))
+
+(defun js2-node-qname-component (node)
+  "Return the name of this node, if it contributes to a qname.
+Returns nil if the node doesn't contribute."
+  (copy-sequence
+   (or (js2-prop-node-name node)
+       (cond
+        ((and (js2-function-node-p node)
+              (js2-function-node-name node))
+         (js2-name-node-name (js2-function-node-name node)))
+        ((js2-computed-prop-name-node-p node)
+         "[computed]")))))
+
+(defun js2-record-imenu-entry (fn-node qname pos)
+  "Add an entry to `js2-imenu-recorder'.
+FN-NODE should be the current item's function node.
+
+Associate FN-NODE with its QNAME for later lookup.
+This is used in postprocessing the chain list.  For each chain, we find
+the parent function, look up its qname, then prepend a copy of it to the chain."
+  (push (cons fn-node (append qname (list pos))) js2-imenu-recorder)
+  (unless js2-imenu-function-map
+    (setq js2-imenu-function-map (make-hash-table :test 'eq)))
+  (puthash fn-node qname js2-imenu-function-map))
+
+(defun js2-record-imenu-functions (node &optional var)
+  "Record function definitions for imenu.
+NODE is a function node or an object literal.
+VAR, if non-nil, is the expression that NODE is being assigned to.
+When passed arguments of wrong type, does nothing."
+  (when js2-parse-ide-mode
+    (let ((fun-p (js2-function-node-p node))
+          qname fname-node)
+      (cond
+       ;; non-anonymous function declaration?
+       ((and fun-p
+             (not var)
+             (setq fname-node (js2-function-node-name node)))
+        (js2-record-imenu-entry node (list fname-node) (js2-node-pos node)))
+       ;; for remaining forms, compute left-side tree branch first
+       ((and var (setq qname (js2-compute-nested-prop-get var)))
+        (cond
+         ;; foo.bar.baz = function
+         (fun-p
+          (js2-record-imenu-entry node qname (js2-node-pos node)))
+         ;; foo.bar.baz = object-literal
+         ;; look for nested functions:  {a: {b: function() {...} }}
+         ((js2-object-node-p node)
+          ;; Node position here is still absolute, since the parser
+          ;; passes the assignment target and value expressions
+          ;; to us before they are added as children of the assignment node.
+          (js2-record-object-literal node qname (js2-node-pos node)))))))))
+
+(defun js2-compute-nested-prop-get (node)
+  "If NODE is of form foo.bar, foo['bar'], or any nested combination, return
+component nodes as a list.  Otherwise return nil.  Element-gets are treated
+as property-gets if the index expression is a string, or a positive integer."
+  (let (left right head)
+    (cond
+     ((or (js2-name-node-p node)
+          (js2-this-or-super-node-p node))
+      (list node))
+     ;; foo.bar.baz is parenthesized as (foo.bar).baz => right operand is a leaf
+     ((js2-prop-get-node-p node)        ; foo.bar
+      (setq left (js2-prop-get-node-left node)
+            right (js2-prop-get-node-right node))
+      (if (setq head (js2-compute-nested-prop-get left))
+          (nconc head (list right))))
+     ((js2-elem-get-node-p node)        ; foo['bar'] or foo[101]
+      (setq left (js2-elem-get-node-target node)
+            right (js2-elem-get-node-element node))
+      (if (or (js2-string-node-p right)      ; ['bar']
+              (and (js2-number-node-p right) ; [10]
+                   (string-match "^[0-9]+$"
+                                 (js2-number-node-value right))))
+          (if (setq head (js2-compute-nested-prop-get left))
+              (nconc head (list right))))))))
+
+(defun js2-record-object-literal (node qname pos)
+  "Recursively process an object literal looking for functions.
+NODE is an object literal that is the right-hand child of an assignment
+expression.  QNAME is a list of nodes representing the assignment target,
+e.g. for foo.bar.baz = {...}, QNAME is (foo-node bar-node baz-node).
+POS is the absolute position of the node.
+We do a depth-first traversal of NODE.  For any functions we find,
+we append the property name to QNAME, then call `js2-record-imenu-entry'."
+  (let (right)
+    (dolist (e (js2-object-node-elems node))  ; e is a `js2-object-prop-node'
+      (when (js2-infix-node-p e)
+        (let ((left (js2-infix-node-left e))
+              ;; Element positions are relative to the parent position.
+              (pos (+ pos (js2-node-pos e))))
+          (cond
+           ;; foo: function() {...}
+           ((js2-function-node-p (setq right (js2-infix-node-right e)))
+            (when (js2-prop-node-name left)
+              ;; As a policy decision, we record the position of the property,
+              ;; not the position of the `function' keyword, since the property
+              ;; is effectively the name of the function.
+              (js2-record-imenu-entry right (append qname (list left)) pos)))
+           ;; foo: {object-literal} -- add foo to qname, offset position, and recurse
+           ((js2-object-node-p right)
+            (js2-record-object-literal right
+                                       (append qname (list (js2-infix-node-left e)))
+                                       (+ pos (js2-node-pos right))))))))))
+
+(defun js2-node-top-level-decl-p (node)
+  "Return t if NODE's name is defined in the top-level scope.
+Also returns t if NODE's name is not defined in any scope, since it implies
+that it's an external variable, which must also be in the top-level scope."
+  (let* ((name (js2-prop-node-name node))
+         (this-scope (js2-node-get-enclosing-scope node))
+         defining-scope)
+    (cond
+     ((js2-this-or-super-node-p node)
+      nil)
+     ((null this-scope)
+      t)
+     ((setq defining-scope (js2-get-defining-scope this-scope name))
+      (js2-ast-root-p defining-scope))
+     (t t))))
+
+(defun js2-wrapper-function-p (node)
+  "Return t if NODE is a function expression that's immediately invoked.
+NODE must be `js2-function-node'."
+  (let ((parent (js2-node-parent node)))
+    (or
+     ;; function(){...}();
+     (and (js2-call-node-p parent)
+          (eq node (js2-call-node-target parent)))
+     (and (js2-paren-node-p parent)
+          ;; (function(){...})();
+          (or (js2-call-node-p (setq parent (js2-node-parent parent)))
+              ;; (function(){...}).call(this);
+              (and (js2-prop-get-node-p parent)
+                   (member (js2-name-node-name (js2-prop-get-node-right parent))
+                           '("call" "apply"))
+                   (js2-call-node-p (js2-node-parent parent))))))))
+
+(defun js2-browse-postprocess-chains ()
+  "Modify function-declaration name chains after parsing finishes.
+Some of the information is only available after the parse tree is complete.
+For instance, processing a nested scope requires a parent function node."
+  (let (result fn parent-qname p elem)
+    (dolist (entry js2-imenu-recorder)
+      ;; function node goes first
+      (cl-destructuring-bind (current-fn &rest (&whole chain head &rest)) entry
+        ;; Examine head's defining scope:
+        ;; Pre-processed chain, or top-level/external, keep as-is.
+        (if (or (stringp head) (js2-node-top-level-decl-p head))
+            (push chain result)
+          (when (js2-this-or-super-node-p head)
+            (setq chain (cdr chain))) ; discard this-node
+          (when (setq fn (js2-node-parent-script-or-fn current-fn))
+            (setq parent-qname (gethash fn js2-imenu-function-map 'not-found))
+            (when (eq parent-qname 'not-found)
+              ;; anonymous function expressions are not recorded
+              ;; during the parse, so we need to handle this case here
+              (setq parent-qname
+                    (if (js2-wrapper-function-p fn)
+                        (let ((grandparent (js2-node-parent-script-or-fn fn)))
+                          (if (js2-ast-root-p grandparent)
+                              nil
+                            (gethash grandparent js2-imenu-function-map 'skip)))
+                      'skip))
+              (puthash fn parent-qname js2-imenu-function-map))
+            (if (eq parent-qname 'skip)
+                ;; We don't show it, let's record that fact.
+                (remhash current-fn js2-imenu-function-map)
+              ;; Prepend parent fn qname to this chain.
+              (let ((qname (append parent-qname chain)))
+                (puthash current-fn (butlast qname) js2-imenu-function-map)
+                (push qname result)))))))
+    ;; Collect chains obtained by third-party code.
+    (let (js2-imenu-recorder)
+      (run-hooks 'js2-build-imenu-callbacks)
+      (dolist (entry js2-imenu-recorder)
+        (push (cdr entry) result)))
+    ;; Finally replace each node in each chain with its name.
+    (dolist (chain result)
+      (setq p chain)
+      (while p
+        (if (js2-node-p (setq elem (car p)))
+            (setcar p (js2-node-qname-component elem)))
+        (setq p (cdr p))))
+    result))
+
+;; Merge name chains into a trie-like tree structure of nested lists.
+;; To simplify construction of the trie, we first build it out using the rule
+;; that the trie consists of lists of pairs.  Each pair is a 2-element array:
+;; [key, num-or-list].  The second element can be a number; if so, this key
+;; is a leaf-node with only one value.  (I.e. there is only one declaration
+;; associated with the key at this level.)  Otherwise the second element is
+;; a list of pairs, with the rule applied recursively.  This symmetry permits
+;; a simple recursive formulation.
+;;
+;; js2-mode is building the data structure for imenu.  The imenu documentation
+;; claims that it's the structure above, but in practice it wants the children
+;; at the same list level as the key for that level, which is how I've drawn
+;; the "Expected final result" above.  We'll postprocess the trie to remove the
+;; list wrapper around the children at each level.
+;;
+;; A completed nested imenu-alist entry looks like this:
+;;       '(("foo"
+;;          ("<definition>" . 7)
+;;          ("bar"
+;;           ("a" . 40)
+;;           ("b" . 60))))
+;;
+;; In particular, the documentation for `imenu--index-alist' says that
+;; a nested sub-alist element looks like (INDEX-NAME SUB-ALIST).
+;; The sub-alist entries immediately follow INDEX-NAME, the head of the list.
+
+(defun js2-treeify (lst)
+  "Convert (a b c d) to (a ((b ((c d)))))."
+  (if (null (cddr lst))  ; list length <= 2
+      lst
+    (list (car lst) (list (js2-treeify (cdr lst))))))
+
+(defun js2-build-alist-trie (chains trie)
+  "Merge declaration name chains into a trie-like alist structure for imenu.
+CHAINS is the qname chain list produced during parsing. TRIE is a
+list of elements built up so far."
+  (let (head tail pos branch kids)
+    (dolist (chain chains)
+      (setq head (car chain)
+            tail (cdr chain)
+            pos (if (numberp (car tail)) (car tail))
+            branch (js2-find-if (lambda (n)
+                                  (string= (car n) head))
+                                trie)
+            kids (cl-second branch))
+      (cond
+       ;; case 1:  this key isn't in the trie yet
+       ((null branch)
+        (if trie
+            (setcdr (last trie) (list (js2-treeify chain)))
+          (setq trie (list (js2-treeify chain)))))
+       ;; case 2:  key is present with a single number entry:  replace w/ list
+       ;;  ("a1" 10)  +  ("a1" 20) => ("a1" (("<definition>" 10)
+       ;;                                    ("<definition>" 20)))
+       ((numberp kids)
+        (setcar (cdr branch)
+                (list (list "<definition-1>" kids)
+                      (if pos
+                          (list "<definition-2>" pos)
+                        (js2-treeify tail)))))
+       ;; case 3:  key is there (with kids), and we're a number entry
+       (pos
+        (setcdr (last kids)
+                (list
+                 (list (format "<definition-%d>"
+                               (1+ (cl-loop for kid in kids
+                                            count (eq ?< (aref (car kid) 0)))))
+                       pos))))
+       ;; case 4:  key is there with kids, need to merge in our chain
+       (t
+        (js2-build-alist-trie (list tail) kids))))
+    trie))
+
+(defun js2-flatten-trie (trie)
+  "Convert TRIE to imenu-format.
+Recurses through nodes, and for each one whose second element is a list,
+appends the list's flattened elements to the current element.  Also
+changes the tails into conses.  For instance, this pre-flattened trie
+
+'(a ((b 20)
+     (c ((d 30)
+         (e 40)))))
+
+becomes
+
+'(a (b . 20)
+    (c (d . 30)
+       (e . 40)))
+
+Note that the root of the trie has no key, just a list of chains.
+This is also true for the value of any key with multiple children,
+e.g. key 'c' in the example above."
+  (cond
+   ((listp (car trie))
+    (mapcar #'js2-flatten-trie trie))
+   (t
+    (if (numberp (cl-second trie))
+        (cons (car trie) (cl-second trie))
+      ;; else pop list and append its kids
+      (apply #'append (list (car trie)) (js2-flatten-trie (cdr trie)))))))
+
+(defun js2-build-imenu-index ()
+  "Turn `js2-imenu-recorder' into an imenu data structure."
+  (when (eq js2-imenu-recorder 'empty)
+    (setq js2-imenu-recorder nil))
+  (let* ((chains (js2-browse-postprocess-chains))
+         (result (js2-build-alist-trie chains nil)))
+    (js2-flatten-trie result)))
+
+(defun js2-test-print-chains (chains)
+  "Print a list of qname chains.
+Each element of CHAINS is a list of the form (NODE [NODE *] pos);
+i.e. one or more nodes, and an integer position as the list tail."
+  (mapconcat (lambda (chain)
+               (concat "("
+                       (mapconcat (lambda (elem)
+                                    (if (js2-node-p elem)
+                                        (or (js2-node-qname-component elem)
+                                            "nil")
+                                      (number-to-string elem)))
+                                  chain
+                                  " ")
+                       ")"))
+             chains
+             "\n"))
+
+;;; Parser
+
+(defconst js2-version "1.8.5"
+  "Version of JavaScript supported.")
+
+(defun js2-record-face (face &optional token)
+  "Record a style run of FACE for TOKEN or the current token."
+  (unless token (setq token (js2-current-token)))
+  (js2-set-face (js2-token-beg token) (js2-token-end token) face 'record))
+
+(defsubst js2-node-end (n)
+  "Computes the absolute end of node N.
+Use with caution!  Assumes `js2-node-pos' is -absolute-, which
+is only true until the node is added to its parent; i.e., while parsing."
+  (+ (js2-node-pos n)
+     (js2-node-len n)))
+
+(defun js2-record-comment (token)
+  "Record a comment in `js2-scanned-comments'."
+  (let ((ct (js2-token-comment-type token))
+        (beg (js2-token-beg token))
+        (end (js2-token-end token)))
+    (push (make-js2-comment-node :len (- end beg)
+                                 :format ct)
+          js2-scanned-comments)
+    (when js2-parse-ide-mode
+      (js2-record-face (if (eq ct 'jsdoc)
+                           'font-lock-doc-face
+                         'font-lock-comment-face)
+                       token)
+      (when (memq ct '(html preprocessor))
+        ;; Tell cc-engine the bounds of the comment.
+        (js2-record-text-property beg (1- end) 'c-in-sws t)))))
+
+(defun js2-peek-token (&optional modifier)
+  "Return the next token type without consuming it.
+If `js2-ti-lookahead' is positive, return the type of next token
+from `js2-ti-tokens'.  Otherwise, call `js2-get-token'."
+  (if (not (zerop js2-ti-lookahead))
+      (js2-token-type
+       (aref js2-ti-tokens (mod (1+ js2-ti-tokens-cursor) js2-ti-ntokens)))
+    (let ((tt (js2-get-token-internal modifier)))
+      (js2-unget-token)
+      tt)))
+
+(defalias 'js2-next-token 'js2-get-token)
+
+(defun js2-match-token (match &optional dont-unget)
+  "Get next token and return t if it matches MATCH, a bytecode.
+Returns nil and consumes nothing if MATCH is not the next token."
+  (if (/= (js2-get-token) match)
+      (ignore (unless dont-unget (js2-unget-token)))
+    t))
+
+(defun js2-match-contextual-kwd (name)
+  "Consume and return t if next token is `js2-NAME', and its
+string is NAME.  Returns nil and keeps current token otherwise."
+  (if (js2-contextual-kwd-p (progn (js2-get-token)
+                                   (js2-current-token))
+                            name)
+      (progn (js2-record-face 'font-lock-keyword-face) t)
+    (js2-unget-token)
+    nil))
+
+(defun js2-contextual-kwd-p (token name)
+  "Return t if TOKEN is `js2-NAME', and its string is NAME."
+  (and (= (js2-token-type token) js2-NAME)
+       (string= (js2-token-string token) name)))
+
+(defun js2-match-async-function ()
+  (when (and (js2-contextual-kwd-p (js2-current-token) "async")
+             (= (js2-peek-token) js2-FUNCTION))
+    (js2-record-face 'font-lock-keyword-face)
+    (js2-get-token)
+    t))
+
+(defun js2-match-async-arrow-function ()
+  (and (js2-contextual-kwd-p (js2-current-token) "async")
+       (/= (js2-peek-token) js2-FUNCTION)))
+
+(defsubst js2-inside-function ()
+  (cl-plusp js2-nesting-of-function))
+
+(defsubst js2-inside-async-function ()
+  (and (js2-inside-function)
+       (js2-function-node-async js2-current-script-or-fn)))
+
+(defun js2-parse-await-maybe (tt)
+  "Parse \"await\" as an AwaitExpression, if it is one."
+  (and (= tt js2-NAME)
+       (js2-contextual-kwd-p (js2-current-token) "await")
+       ;; Per the proposal, AwaitExpression consists of "await"
+       ;; followed by a UnaryExpression.  So look ahead for one.
+       (let ((ts-state (make-js2-ts-state))
+             (recorded-identifiers js2-recorded-identifiers)
+             (parsed-errors js2-parsed-errors)
+             (current-token (js2-current-token))
+             (beg (js2-current-token-beg))
+             (end (js2-current-token-end))
+             pn)
+         (js2-get-token)
+         (setq pn (js2-make-unary beg js2-AWAIT 'js2-parse-unary-expr))
+         (if (= (js2-node-type (js2-unary-node-operand pn)) js2-ERROR)
+             ;; The parse failed, so pretend like nothing happened and restore
+             ;; the previous parsing state.
+             (progn
+               (js2-ts-seek ts-state)
+               (setq js2-recorded-identifiers recorded-identifiers
+                     js2-parsed-errors parsed-errors)
+               ;; And ensure the caller knows about the failure.
+               nil)
+           ;; The parse was successful, so process and return the "await".
+           (js2-record-face 'font-lock-keyword-face current-token)
+           (unless (js2-inside-async-function)
+             (js2-report-error "msg.bad.await" nil
+                               beg (- end beg)))
+           pn))))
+
+(defun js2-get-prop-name-token ()
+  (js2-get-token (and (>= js2-language-version 170) 'KEYWORD_IS_NAME)))
+
+(defun js2-match-prop-name ()
+  "Consume token and return t if next token is a valid property name.
+If `js2-language-version' is >= 180, a keyword or reserved word
+is considered valid name as well."
+  (if (eq js2-NAME (js2-get-prop-name-token))
+      t
+    (js2-unget-token)
+    nil))
+
+(defun js2-must-match-prop-name (msg-id &optional pos len)
+  (if (js2-match-prop-name)
+      t
+    (js2-report-error msg-id nil pos len)
+    nil))
+
+(defun js2-peek-token-or-eol ()
+  "Return js2-EOL if the next token immediately follows a newline.
+Else returns the next token.  Used in situations where we don't
+consider certain token types valid if they are preceded by a newline.
+One example is the postfix ++ or -- operator, which has to be on the
+same line as its operand."
+  (let ((tt (js2-get-token))
+        (follows-eol (js2-token-follows-eol-p (js2-current-token))))
+    (js2-unget-token)
+    (if follows-eol
+        js2-EOL
+      tt)))
+
+(defun js2-must-match (token msg-id &optional pos len)
+  "Match next token to token code TOKEN, or record a syntax error.
+MSG-ID is the error message to report if the match fails.
+Returns t on match, nil if no match."
+  (if (js2-match-token token t)
+      t
+    (js2-report-error msg-id nil pos len)
+    (js2-unget-token)
+    nil))
+
+(defun js2-must-match-name (msg-id)
+  (if (js2-match-token js2-NAME t)
+      t
+    (if (eq (js2-current-token-type) js2-RESERVED)
+        (js2-report-error "msg.reserved.id" (js2-current-token-string))
+      (js2-report-error msg-id)
+      (js2-unget-token))
+    nil))
+
+(defun js2-set-requires-activation ()
+  (if (js2-function-node-p js2-current-script-or-fn)
+      (setf (js2-function-node-needs-activation js2-current-script-or-fn) t)))
+
+(defun js2-check-activation-name (name _token)
+  (when (js2-inside-function)
+    ;; skip language-version 1.2 check from Rhino
+    (if (or (string= "arguments" name)
+            (and js2-compiler-activation-names  ; only used in codegen
+                 (gethash name js2-compiler-activation-names)))
+        (js2-set-requires-activation))))
+
+(defun js2-set-is-generator ()
+  (let ((fn-node js2-current-script-or-fn))
+    (when (and (js2-function-node-p fn-node)
+               (not (js2-function-node-generator-type fn-node)))
+      (setf (js2-function-node-generator-type js2-current-script-or-fn) 'LEGACY))))
+
+(defun js2-must-have-xml ()
+  (unless js2-compiler-xml-available
+    (js2-report-error "msg.XML.not.available")))
+
+(defun js2-push-scope (scope)
+  "Push SCOPE, a `js2-scope', onto the lexical scope chain."
+  (cl-assert (js2-scope-p scope))
+  (cl-assert (null (js2-scope-parent-scope scope)))
+  (cl-assert (not (eq js2-current-scope scope)))
+  (setf (js2-scope-parent-scope scope) js2-current-scope
+        js2-current-scope scope))
+
+(defsubst js2-pop-scope ()
+  (setq js2-current-scope
+        (js2-scope-parent-scope js2-current-scope)))
+
+(defun js2-enter-loop (loop-node)
+  (push loop-node js2-loop-set)
+  (push loop-node js2-loop-and-switch-set)
+  (js2-push-scope loop-node)
+  ;; Tell the current labeled statement (if any) its statement,
+  ;; and set the jump target of the first label to the loop.
+  ;; These are used in `js2-parse-continue' to verify that the
+  ;; continue target is an actual labeled loop.  (And for codegen.)
+  (when js2-labeled-stmt
+    (setf (js2-labeled-stmt-node-stmt js2-labeled-stmt) loop-node
+          (js2-label-node-loop (car (js2-labeled-stmt-node-labels
+                                     js2-labeled-stmt))) loop-node)))
+
+(defun js2-exit-loop ()
+  (pop js2-loop-set)
+  (pop js2-loop-and-switch-set)
+  (js2-pop-scope))
+
+(defsubst js2-enter-switch (switch-node)
+  (js2-push-scope switch-node)
+  (push switch-node js2-loop-and-switch-set))
+
+(defsubst js2-exit-switch ()
+  (js2-pop-scope)
+  (pop js2-loop-and-switch-set))
+
+(defsubst js2-get-directive (node)
+  "Return NODE's value if it is a directive, nil otherwise.
+
+A directive is an otherwise-meaningless expression statement
+consisting of a string literal, such as \"use strict\"."
+  (and (js2-expr-stmt-node-p node)
+       (js2-string-node-p (setq node (js2-expr-stmt-node-expr node)))
+       (js2-string-node-value node)))
+
+(defun js2-parse (&optional buf cb)
+  "Tell the js2 parser to parse a region of JavaScript.
+
+BUF is a buffer or buffer name containing the code to parse.
+Call `narrow-to-region' first to parse only part of the buffer.
+
+The returned AST root node is given some additional properties:
+  `node-count' - total number of nodes in the AST
+  `buffer' - BUF.  The buffer it refers to may change or be killed,
+             so the value is not necessarily reliable.
+
+An optional callback CB can be specified to report parsing
+progress.  If `(functionp CB)' returns t, it will be called with
+the current line number once before parsing begins, then again
+each time the lexer reaches a new line number.
+
+CB can also be a list of the form `(symbol cb ...)' to specify
+multiple callbacks with different criteria.  Each symbol is a
+criterion keyword, and the following element is the callback to
+call
+
+  :line  - called whenever the line number changes
+  :token - called for each new token consumed
+
+The list of criteria could be extended to include entering or
+leaving a statement, an expression, or a function definition."
+  (if (and cb (not (functionp cb)))
+      (error "criteria callbacks not yet implemented"))
+  (let ((inhibit-point-motion-hooks t)
+        (js2-compiler-xml-available (>= js2-language-version 160))
+        ;; This is a recursive-descent parser, so give it a big stack.
+        (max-lisp-eval-depth (max max-lisp-eval-depth 3000))
+        (max-specpdl-size (max max-specpdl-size 3000))
+        (case-fold-search nil)
+        ast)
+    (with-current-buffer (or buf (current-buffer))
+      (setq js2-scanned-comments nil
+            js2-parsed-errors nil
+            js2-parsed-warnings nil
+            js2-imenu-recorder nil
+            js2-imenu-function-map nil
+            js2-label-set nil)
+      (js2-init-scanner)
+      (setq ast (js2-do-parse))
+      (unless js2-ts-hit-eof
+        (js2-report-error "msg.got.syntax.errors" (length js2-parsed-errors)))
+      (setf (js2-ast-root-errors ast) js2-parsed-errors
+            (js2-ast-root-warnings ast) js2-parsed-warnings)
+      ;; if we didn't find any declarations, put a dummy in this list so we
+      ;; don't end up re-parsing the buffer in `js2-mode-create-imenu-index'
+      (unless js2-imenu-recorder
+        (setq js2-imenu-recorder 'empty))
+      (run-hooks 'js2-parse-finished-hook)
+      ast)))
+
+;; Corresponds to Rhino's Parser.parse() method.
+(defun js2-do-parse ()
+  "Parse current buffer starting from current point.
+Scanner should be initialized."
+  (let ((pos js2-ts-cursor)
+        (end js2-ts-cursor)  ; in case file is empty
+        root n tt
+        (in-directive-prologue t)
+        (js2-in-use-strict-directive js2-in-use-strict-directive)
+        directive)
+    ;; initialize buffer-local parsing vars
+    (setf root (make-js2-ast-root :buffer (buffer-name) :pos pos)
+          js2-current-script-or-fn root
+          js2-current-scope root
+          js2-nesting-of-function 0
+          js2-labeled-stmt nil
+          js2-recorded-identifiers nil  ; for js2-highlight
+          js2-in-use-strict-directive js2-mode-assume-strict)
+    (while (/= (setq tt (js2-get-token)) js2-EOF)
+      (if (= tt js2-FUNCTION)
+          (progn
+            (setq n (if js2-called-by-compile-function
+                        (js2-parse-function-expr)
+                      (js2-parse-function-stmt))))
+        ;; not a function - parse a statement
+        (js2-unget-token)
+        (setq n (js2-parse-statement))
+        (when in-directive-prologue
+          (setq directive (js2-get-directive n))
+          (cond
+           ((null directive)
+            (setq in-directive-prologue nil))
+           ((string= directive "use strict")
+            (setq js2-in-use-strict-directive t)))))
+      ;; add function or statement to script
+      (setq end (js2-node-end n))
+      (js2-block-node-push root n))
+    ;; add comments to root in lexical order
+    (when js2-scanned-comments
+      ;; if we find a comment beyond end of normal kids, use its end
+      (setq end (max end (js2-node-end (cl-first js2-scanned-comments))))
+      (dolist (comment js2-scanned-comments)
+        (push comment (js2-ast-root-comments root))
+        (js2-node-add-children root comment)))
+    (setf (js2-node-len root) (- end pos))
+    (setq js2-mode-ast root)  ; Make sure this is available for callbacks.
+    ;; Give extensions a chance to muck with things before highlighting starts.
+    (let ((js2-additional-externs js2-additional-externs))
+      (js2-filter-parsed-warnings)
+      (save-excursion
+        (run-hooks 'js2-post-parse-callbacks))
+      (js2-highlight-undeclared-vars))
+    root))
+
+(defun js2-filter-parsed-warnings ()
+  "Remove `js2-parsed-warnings' elements that match `js2-ignored-warnings'."
+  (when js2-ignored-warnings
+    (setq js2-parsed-warnings
+          (cl-remove-if
+           (lambda (warning)
+             (let ((msg (caar warning)))
+               (member msg js2-ignored-warnings)))
+           js2-parsed-warnings)))
+  js2-parsed-warnings)
+
+(defun js2-parse-function-closure-body (fn-node)
+  "Parse a JavaScript 1.8 function closure body."
+  (let ((js2-nesting-of-function (1+ js2-nesting-of-function)))
+    (if js2-ts-hit-eof
+        (js2-report-error "msg.no.brace.body" nil
+                          (js2-node-pos fn-node)
+                          (- js2-ts-cursor (js2-node-pos fn-node)))
+      (js2-node-add-children fn-node
+                             (setf (js2-function-node-body fn-node)
+                                   (js2-parse-expr t))))))
+
+(defun js2-parse-function-body (fn-node)
+  (js2-must-match js2-LC "msg.no.brace.body"
+                  (js2-node-pos fn-node)
+                  (- js2-ts-cursor (js2-node-pos fn-node)))
+  (let ((pos (js2-current-token-beg))         ; LC position
+        (pn (make-js2-block-node))  ; starts at LC position
+        tt
+        end
+        not-in-directive-prologue
+        node
+        directive)
+    (cl-incf js2-nesting-of-function)
+    (unwind-protect
+        (while (not (or (= (setq tt (js2-peek-token)) js2-ERROR)
+                        (= tt js2-EOF)
+                        (= tt js2-RC)))
+          (js2-block-node-push
+           pn
+           (if (/= tt js2-FUNCTION)
+               (if not-in-directive-prologue
+                   (js2-parse-statement)
+                 (setq node (js2-parse-statement)
+                       directive (js2-get-directive node))
+                 (cond
+                  ((null directive)
+                   (setq not-in-directive-prologue t))
+                  ((string= directive "use strict")
+                   ;; Back up and reparse the function, because new rules apply
+                   ;; to the function name and parameters.
+                   (when (not js2-in-use-strict-directive)
+                     (setq js2-in-use-strict-directive t)
+                     (throw 'reparse t))))
+                 node)
+             (js2-get-token)
+             (js2-parse-function-stmt))))
+      (cl-decf js2-nesting-of-function))
+    (setq end (js2-current-token-end))  ; assume no curly and leave at current token
+    (if (js2-must-match js2-RC "msg.no.brace.after.body" pos)
+        (setq end (js2-current-token-end)))
+    (setf (js2-node-pos pn) pos
+          (js2-node-len pn) (- end pos))
+    (setf (js2-function-node-body fn-node) pn)
+    (js2-node-add-children fn-node pn)
+    pn))
+
+(defun js2-define-destruct-symbols (node decl-type face &optional ignore-not-in-block)
+  "Declare and fontify destructuring parameters inside NODE.
+NODE is either `js2-array-node', `js2-object-node', or `js2-name-node'.
+
+Return a list of `js2-name-node' nodes representing the symbols
+declared; probably to check them for errors."
+  (let ((name-nodes (js2--collect-target-symbols node t)))
+    (dolist (node name-nodes)
+      (let (leftpos)
+        (js2-define-symbol decl-type (js2-name-node-name node)
+                           node ignore-not-in-block)
+        (when face
+          (js2-set-face (setq leftpos (js2-node-abs-pos node))
+                        (+ leftpos (js2-node-len node))
+                        face 'record))))
+    name-nodes))
+
+(defvar js2-illegal-strict-identifiers
+  '("eval" "arguments")
+  "Identifiers not allowed as variables in strict mode.")
+
+(defun js2-check-strict-identifier (name-node)
+  "Check that NAME-NODE makes a legal strict mode identifier."
+  (when js2-in-use-strict-directive
+    (let ((param-name (js2-name-node-name name-node)))
+      (when (member param-name js2-illegal-strict-identifiers)
+        (js2-report-error "msg.bad.id.strict" param-name
+                          (js2-node-abs-pos name-node) (js2-node-len name-node))))))
+
+(defun js2-check-strict-function-params (preceding-params params)
+  "Given PRECEDING-PARAMS in a function's parameter list, check
+for strict mode errors caused by PARAMS."
+  (when js2-in-use-strict-directive
+    (dolist (param params)
+      (let ((param-name (js2-name-node-name param)))
+        (js2-check-strict-identifier param)
+        (when (cl-some (lambda (param)
+                         (string= (js2-name-node-name param) param-name))
+                       preceding-params)
+          (js2-report-error "msg.dup.param.strict" param-name
+                            (js2-node-abs-pos param) (js2-node-len param)))))))
+
+(defun js2-parse-function-params (function-type fn-node pos)
+  "Parse the parameters of a function of FUNCTION-TYPE
+represented by FN-NODE at POS."
+  (if (js2-match-token js2-RP)
+      (setf (js2-function-node-rp fn-node) (- (js2-current-token-beg) pos))
+    (let ((paren-free-arrow (and (eq function-type 'FUNCTION_ARROW)
+                                 (eq (js2-current-token-type) js2-NAME)))
+          params param
+          param-name-nodes new-param-name-nodes
+          rest-param-at)
+      (when paren-free-arrow
+        (js2-unget-token))
+      (cl-loop for tt = (js2-peek-token)
+               do
+               (cond
+                ;; destructuring param
+                ((and (not paren-free-arrow)
+                      (or (= tt js2-LB) (= tt js2-LC)))
+                 (js2-get-token)
+                 (setq param (js2-parse-destruct-primary-expr)
+                       new-param-name-nodes (js2-define-destruct-symbols
+                                             param js2-LP 'js2-function-param))
+                 (js2-check-strict-function-params param-name-nodes new-param-name-nodes)
+                 (setq param-name-nodes (append param-name-nodes new-param-name-nodes)))
+                ;; variable name
+                (t
+                 (when (and (>= js2-language-version 200)
+                            (not paren-free-arrow)
+                            (js2-match-token js2-TRIPLEDOT)
+                            (not rest-param-at))
+                   ;; to report errors if there are more parameters
+                   (setq rest-param-at (length params)))
+                 (js2-must-match-name "msg.no.parm")
+                 (js2-record-face 'js2-function-param)
+                 (setq param (js2-create-name-node))
+                 (js2-define-symbol js2-LP (js2-current-token-string) param)
+                 (js2-check-strict-function-params param-name-nodes (list param))
+                 (setq param-name-nodes (append param-name-nodes (list param)))))
+               ;; default parameter value
+               (when (and (not rest-param-at)
+                          (>= js2-language-version 200)
+                          (js2-match-token js2-ASSIGN))
+                 (cl-assert (not paren-free-arrow))
+                 (let* ((pos (js2-node-pos param))
+                        (tt (js2-current-token-type))
+                        (op-pos (- (js2-current-token-beg) pos))
+                        (left param)
+                        (right (js2-parse-assign-expr))
+                        (len (- (js2-node-end right) pos)))
+                   (setq param (make-js2-assign-node
+                                :type tt :pos pos :len len :op-pos op-pos
+                                :left left :right right))
+                   (js2-node-add-children param left right)))
+               (push param params)
+               (when (and rest-param-at (> (length params) (1+ rest-param-at)))
+                 (js2-report-error "msg.param.after.rest" nil
+                                   (js2-node-pos param) (js2-node-len param)))
+               while
+               (and (js2-match-token js2-COMMA)
+                    (or (< js2-language-version 200)
+                        (not (= js2-RP (js2-peek-token))))))
+      (when (and (not paren-free-arrow)
+                 (js2-must-match js2-RP "msg.no.paren.after.parms"))
+        (setf (js2-function-node-rp fn-node) (- (js2-current-token-beg) pos)))
+      (when rest-param-at
+        (setf (js2-function-node-rest-p fn-node) t))
+      (dolist (p params)
+        (js2-node-add-children fn-node p)
+        (push p (js2-function-node-params fn-node))))))
+
+(defun js2-check-inconsistent-return-warning (fn-node name)
+  "Possibly show inconsistent-return warning.
+Last token scanned is the close-curly for the function body."
+  (when (and js2-mode-show-strict-warnings
+             js2-strict-inconsistent-return-warning
+             (not (js2-has-consistent-return-usage
+                   (js2-function-node-body fn-node))))
+    ;; Have it extend from close-curly to bol or beginning of block.
+    (let ((pos (save-excursion
+                 (goto-char (js2-current-token-end))
+                 (max (js2-node-abs-pos (js2-function-node-body fn-node))
+                      (point-at-bol))))
+          (end (js2-current-token-end)))
+      (if (cl-plusp (js2-name-node-length name))
+          (js2-add-strict-warning "msg.no.return.value"
+                                  (js2-name-node-name name) pos end)
+        (js2-add-strict-warning "msg.anon.no.return.value" nil pos end)))))
+
+(defun js2-parse-function-stmt (&optional async-p)
+  (let ((pos (js2-current-token-beg))
+        (star-p (js2-match-token js2-MUL)))
+    (js2-must-match-name "msg.unnamed.function.stmt")
+    (let ((name (js2-create-name-node t))
+          pn member-expr)
+      (cond
+       ((js2-match-token js2-LP)
+        (js2-parse-function 'FUNCTION_STATEMENT pos star-p async-p name))
+       (js2-allow-member-expr-as-function-name
+        (setq member-expr (js2-parse-member-expr-tail nil name))
+        (js2-parse-highlight-member-expr-fn-name member-expr)
+        (js2-must-match js2-LP "msg.no.paren.parms")
+        (setf pn (js2-parse-function 'FUNCTION_STATEMENT pos star-p async-p)
+              (js2-function-node-member-expr pn) member-expr)
+        pn)
+       (t
+        (js2-report-error "msg.no.paren.parms")
+        (make-js2-error-node))))))
+
+(defun js2-parse-async-function-stmt ()
+  (js2-parse-function-stmt t))
+
+(defun js2-parse-function-expr (&optional async-p)
+  (let ((pos (js2-current-token-beg))
+        (star-p (js2-match-token js2-MUL))
+        name)
+    (when (js2-match-token js2-NAME)
+      (setq name (js2-create-name-node t)))
+    (js2-must-match js2-LP "msg.no.paren.parms")
+    (js2-parse-function 'FUNCTION_EXPRESSION pos star-p async-p name)))
+
+(defun js2-parse-function-internal (function-type pos star-p &optional async-p name)
+  (let (fn-node lp)
+    (if (= (js2-current-token-type) js2-LP) ; eventually matched LP?
+        (setq lp (js2-current-token-beg)))
+    (setf fn-node (make-js2-function-node :pos pos
+                                          :name name
+                                          :form function-type
+                                          :lp (if lp (- lp pos))
+                                          :generator-type (and star-p 'STAR)
+                                          :async async-p))
+    (when name
+      (js2-set-face (js2-node-pos name) (js2-node-end name)
+                    'font-lock-function-name-face 'record)
+      (when (and (eq function-type 'FUNCTION_STATEMENT)
+                 (cl-plusp (js2-name-node-length name)))
+        ;; Function statements define a symbol in the enclosing scope
+        (js2-define-symbol js2-FUNCTION (js2-name-node-name name) fn-node))
+      (when js2-in-use-strict-directive
+        (js2-check-strict-identifier name)))
+    (if (or (js2-inside-function) (cl-plusp js2-nesting-of-with))
+        ;; 1. Nested functions are not affected by the dynamic scope flag
+        ;;    as dynamic scope is already a parent of their scope.
+        ;; 2. Functions defined under the with statement also immune to
+        ;;    this setup, in which case dynamic scope is ignored in favor
+        ;;    of the with object.
+        (setf (js2-function-node-ignore-dynamic fn-node) t))
+    ;; dynamically bind all the per-function variables
+    (let ((js2-current-script-or-fn fn-node)
+          (js2-current-scope fn-node)
+          (js2-nesting-of-with 0)
+          (js2-end-flags 0)
+          js2-label-set
+          js2-loop-set
+          js2-loop-and-switch-set)
+      (js2-parse-function-params function-type fn-node pos)
+      (when (eq function-type 'FUNCTION_ARROW)
+        (js2-must-match js2-ARROW "msg.bad.arrow.args"))
+      (if (and (>= js2-language-version 180)
+               (/= (js2-peek-token) js2-LC))
+          (js2-parse-function-closure-body fn-node)
+        (js2-parse-function-body fn-node))
+      (js2-check-inconsistent-return-warning fn-node name)
+
+      (when name
+        (js2-node-add-children fn-node name)
+        ;; Function expressions define a name only in the body of the
+        ;; function, and only if not hidden by a parameter name
+        (when (and (eq function-type 'FUNCTION_EXPRESSION)
+                   (null (js2-scope-get-symbol js2-current-scope
+                                               (js2-name-node-name name))))
+          (js2-define-symbol js2-FUNCTION
+                             (js2-name-node-name name)
+                             fn-node))
+        (when (eq function-type 'FUNCTION_STATEMENT)
+          (js2-record-imenu-functions fn-node))))
+
+    (setf (js2-node-len fn-node) (- (js2-current-token-end) pos))
+    ;; Rhino doesn't do this, but we need it for finding undeclared vars.
+    ;; We wait until after parsing the function to set its parent scope,
+    ;; since `js2-define-symbol' needs the defining-scope check to stop
+    ;; at the function boundary when checking for redeclarations.
+    (setf (js2-scope-parent-scope fn-node) js2-current-scope)
+    fn-node))
+
+(defun js2-parse-function (function-type pos star-p &optional async-p name)
+  "Function parser.  FUNCTION-TYPE is a symbol, POS is the
+beginning of the first token (function keyword, unless it's an
+arrow function), NAME is js2-name-node."
+  (let ((continue t)
+        ts-state
+        fn-node
+        ;; Preserve strict state outside this function.
+        (js2-in-use-strict-directive js2-in-use-strict-directive))
+    ;; Parse multiple times if a new strict mode directive is discovered in the
+    ;; function body, as new rules will be retroactively applied to the legality
+    ;; of function names and parameters.
+    (while continue
+      (setq ts-state (make-js2-ts-state))
+      (setq continue (catch 'reparse
+                       (setq fn-node (js2-parse-function-internal
+                                      function-type pos star-p async-p name))
+                       ;; Don't continue.
+                       nil))
+      (when continue
+        (js2-ts-seek ts-state)))
+    fn-node))
+
+(defun js2-parse-statements (&optional parent)
+  "Parse a statement list.  Last token consumed must be js2-LC.
+
+PARENT can be a `js2-block-node', in which case the statements are
+appended to PARENT.  Otherwise a new `js2-block-node' is created
+and returned.
+
+This function does not match the closing js2-RC: the caller
+matches the RC so it can provide a suitable error message if not
+matched.  This means it's up to the caller to set the length of
+the node to include the closing RC.  The node start pos is set to
+the absolute buffer start position, and the caller should fix it
+up to be relative to the parent node.  All children of this block
+node are given relative start positions and correct lengths."
+  (let ((pn (or parent (make-js2-block-node)))
+        tt)
+    (while (and (> (setq tt (js2-peek-token)) js2-EOF)
+                (/= tt js2-RC))
+      (js2-block-node-push pn (js2-parse-statement)))
+    pn))
+
+(defun js2-parse-statement ()
+  (let (pn beg end)
+    ;; coarse-grained user-interrupt check - needs work
+    (and js2-parse-interruptable-p
+         (zerop (% (cl-incf js2-parse-stmt-count)
+                   js2-statements-per-pause))
+         (input-pending-p)
+         (throw 'interrupted t))
+    (setq pn (js2-statement-helper))
+    ;; no-side-effects warning check
+    (unless (js2-node-has-side-effects pn)
+      (setq end (js2-node-end pn))
+      (save-excursion
+        (goto-char end)
+        (setq beg (max (js2-node-pos pn) (point-at-bol))))
+      (js2-add-strict-warning "msg.no.side.effects" nil beg end))
+    pn))
+
+;; These correspond to the switch cases in Parser.statementHelper
+(defconst js2-parsers
+  (let ((parsers (make-vector js2-num-tokens
+                                #'js2-parse-expr-stmt)))
+    (aset parsers js2-BREAK     #'js2-parse-break)
+    (aset parsers js2-CLASS     #'js2-parse-class-stmt)
+    (aset parsers js2-CONST     #'js2-parse-const-var)
+    (aset parsers js2-CONTINUE  #'js2-parse-continue)
+    (aset parsers js2-DEBUGGER  #'js2-parse-debugger)
+    (aset parsers js2-DEFAULT   #'js2-parse-default-xml-namespace)
+    (aset parsers js2-DO        #'js2-parse-do)
+    (aset parsers js2-EXPORT    #'js2-parse-export)
+    (aset parsers js2-FOR       #'js2-parse-for)
+    (aset parsers js2-FUNCTION  #'js2-parse-function-stmt)
+    (aset parsers js2-IF        #'js2-parse-if)
+    (aset parsers js2-IMPORT    #'js2-parse-import)
+    (aset parsers js2-LC        #'js2-parse-block)
+    (aset parsers js2-LET       #'js2-parse-let-stmt)
+    (aset parsers js2-NAME      #'js2-parse-name-or-label)
+    (aset parsers js2-RETURN    #'js2-parse-ret-yield)
+    (aset parsers js2-SEMI      #'js2-parse-semi)
+    (aset parsers js2-SWITCH    #'js2-parse-switch)
+    (aset parsers js2-THROW     #'js2-parse-throw)
+    (aset parsers js2-TRY       #'js2-parse-try)
+    (aset parsers js2-VAR       #'js2-parse-const-var)
+    (aset parsers js2-WHILE     #'js2-parse-while)
+    (aset parsers js2-WITH      #'js2-parse-with)
+    (aset parsers js2-YIELD     #'js2-parse-ret-yield)
+    parsers)
+  "A vector mapping token types to parser functions.")
+
+(defun js2-parse-warn-missing-semi (beg end)
+  (and js2-mode-show-strict-warnings
+       js2-strict-missing-semi-warning
+       (js2-add-strict-warning
+        "msg.missing.semi" nil
+        ;; back up to beginning of statement or line
+        (max beg (save-excursion
+                   (goto-char end)
+                   (point-at-bol)))
+        end)))
+
+(defconst js2-no-semi-insertion
+  (list js2-IF
+        js2-SWITCH
+        js2-WHILE
+        js2-DO
+        js2-FOR
+        js2-TRY
+        js2-WITH
+        js2-LC
+        js2-ERROR
+        js2-SEMI
+        js2-CLASS
+        js2-FUNCTION
+        js2-EXPORT)
+  "List of tokens that don't do automatic semicolon insertion.")
+
+(defconst js2-autoinsert-semi-and-warn
+  (list js2-ERROR js2-EOF js2-RC))
+
+(defun js2-statement-helper ()
+  (let* ((tt (js2-get-token))
+         (first-tt tt)
+         (async-stmt (js2-match-async-function))
+         (parser (if (= tt js2-ERROR)
+                     #'js2-parse-semi
+                   (if async-stmt
+                       #'js2-parse-async-function-stmt
+                     (aref js2-parsers tt))))
+         pn)
+    ;; If the statement is set, then it's been told its label by now.
+    (and js2-labeled-stmt
+         (js2-labeled-stmt-node-stmt js2-labeled-stmt)
+         (setq js2-labeled-stmt nil))
+    (setq pn (funcall parser))
+    ;; Don't do auto semi insertion for certain statement types.
+    (unless (or (memq first-tt js2-no-semi-insertion)
+                (js2-labeled-stmt-node-p pn)
+                async-stmt)
+      (js2-auto-insert-semicolon pn))
+    pn))
+
+(defun js2-auto-insert-semicolon (pn)
+  (let* ((tt (js2-get-token))
+         (pos (js2-node-pos pn)))
+      (cond
+       ((= tt js2-SEMI)
+        ;; extend the node bounds to include the semicolon.
+        (setf (js2-node-len pn) (- (js2-current-token-end) pos)))
+       ((memq tt js2-autoinsert-semi-and-warn)
+        (js2-unget-token) ; Not ';', do not consume.
+        ;; Autoinsert ;
+        (js2-parse-warn-missing-semi pos (js2-node-end pn)))
+       (t
+        (if (not (js2-token-follows-eol-p (js2-current-token)))
+            ;; Report error if no EOL or autoinsert ';' otherwise
+            (js2-report-error "msg.no.semi.stmt")
+          (js2-parse-warn-missing-semi pos (js2-node-end pn)))
+        (js2-unget-token) ; Not ';', do not consume.
+        ))))
+
+(defun js2-parse-condition ()
+  "Parse a parenthesized boolean expression, e.g. in an if- or while-stmt.
+The parens are discarded and the expression node is returned.
+The `pos' field of the return value is set to an absolute position
+that must be fixed up by the caller.
+Return value is a list (EXPR LP RP), with absolute paren positions."
+  (let (pn lp rp)
+    (if (js2-must-match js2-LP "msg.no.paren.cond")
+        (setq lp (js2-current-token-beg)))
+    (setq pn (js2-parse-expr))
+    (if (js2-must-match js2-RP "msg.no.paren.after.cond")
+        (setq rp (js2-current-token-beg)))
+    ;; Report strict warning on code like "if (a = 7) ..."
+    (if (and js2-strict-cond-assign-warning
+             (js2-assign-node-p pn))
+        (js2-add-strict-warning "msg.equal.as.assign" nil
+                                (js2-node-pos pn)
+                                (+ (js2-node-pos pn)
+                                   (js2-node-len pn))))
+    (list pn lp rp)))
+
+(defun js2-parse-if ()
+  "Parser for if-statement.  Last matched token must be js2-IF."
+  (let ((pos (js2-current-token-beg))
+        cond if-true if-false else-pos end pn)
+    (setq cond (js2-parse-condition)
+          if-true (js2-parse-statement)
+          if-false (if (js2-match-token js2-ELSE)
+                       (progn
+                         (setq else-pos (- (js2-current-token-beg) pos))
+                         (js2-parse-statement)))
+          end (js2-node-end (or if-false if-true))
+          pn (make-js2-if-node :pos pos
+                               :len (- end pos)
+                               :condition (car cond)
+                               :then-part if-true
+                               :else-part if-false
+                               :else-pos else-pos
+                               :lp (js2-relpos (cl-second cond) pos)
+                               :rp (js2-relpos (cl-third cond) pos)))
+    (js2-node-add-children pn (car cond) if-true if-false)
+    pn))
+
+(defun js2-parse-import ()
+  "Parse import statement. The current token must be js2-IMPORT."
+  (unless (js2-ast-root-p js2-current-scope)
+    (js2-report-error "msg.mod.import.decl.at.top.level"))
+  (let ((beg (js2-current-token-beg)))
+    (cond ((js2-match-token js2-STRING)
+           (make-js2-import-node
+            :pos beg
+            :len (- (js2-current-token-end) beg)
+            :module-id (js2-current-token-string)))
+          (t
+           (let* ((import-clause (js2-parse-import-clause))
+                  (from-clause (and import-clause (js2-parse-from-clause)))
+                  (module-id (when from-clause (js2-from-clause-node-module-id from-clause)))
+                  (node (make-js2-import-node
+                         :pos beg
+                         :len (- (js2-current-token-end) beg)
+                         :import import-clause
+                         :from from-clause
+                         :module-id module-id)))
+             (when import-clause
+               (js2-node-add-children node import-clause))
+             (when from-clause
+               (js2-node-add-children node from-clause))
+             node)))))
+
+(defun js2-parse-import-clause ()
+  "Parse the bindings in an import statement.
+This can take many forms:
+
+ImportedDefaultBinding -> 'foo'
+NameSpaceImport -> '* as lib'
+NamedImports -> '{foo as bar, bang}'
+ImportedDefaultBinding , NameSpaceImport -> 'foo, * as lib'
+ImportedDefaultBinding , NamedImports -> 'foo, {bar, baz as bif}'
+
+Try to match namespace imports and named imports first because nothing can
+come after them. If it is an imported default binding, then it could have named
+imports or a namespace import that follows it.
+"
+  (let* ((beg (js2-current-token-beg))
+         (clause (make-js2-import-clause-node
+                  :pos beg))
+         (children (list)))
+    (cond
+     ((js2-match-token js2-MUL)
+      (let ((ns-import (js2-parse-namespace-import)))
+        (when ns-import
+          (let ((name-node (js2-namespace-import-node-name ns-import)))
+            (js2-define-symbol
+             js2-LET (js2-name-node-name name-node) name-node t))
+          (setf (js2-import-clause-node-namespace-import clause) ns-import)
+          (push ns-import children))))
+     ((js2-match-token js2-LC)
+      (let ((imports (js2-parse-export-bindings t)))
+        (setf (js2-import-clause-node-named-imports clause) imports)
+        (dolist (import imports)
+          (push import children)
+          (let ((name-node (js2-export-binding-node-local-name import)))
+            (when name-node
+              (js2-define-symbol
+               js2-LET (js2-name-node-name name-node) name-node t))))))
+     ((= (js2-peek-token) js2-NAME)
+      (let ((binding (js2-maybe-parse-export-binding t)))
+        (let ((node-name (js2-export-binding-node-local-name binding)))
+          (js2-define-symbol js2-LET (js2-name-node-name node-name) node-name t))
+        (setf (js2-import-clause-node-default-binding clause) binding)
+        (push binding children))
+      (when (js2-match-token js2-COMMA)
+        (cond
+         ((js2-match-token js2-MUL)
+          (let ((ns-import (js2-parse-namespace-import)))
+            (let ((name-node (js2-namespace-import-node-name ns-import)))
+              (js2-define-symbol
+               js2-LET (js2-name-node-name name-node) name-node t))
+            (setf (js2-import-clause-node-namespace-import clause) ns-import)
+            (push ns-import children)))
+         ((js2-match-token js2-LC)
+          (let ((imports (js2-parse-export-bindings t)))
+            (setf (js2-import-clause-node-named-imports clause) imports)
+            (dolist (import imports)
+              (push import children)
+              (let ((name-node (js2-export-binding-node-local-name import)))
+                (when name-node
+                  (js2-define-symbol
+                   js2-LET (js2-name-node-name name-node) name-node t))))))
+         (t (js2-report-error "msg.syntax")))))
+     (t (js2-report-error "msg.mod.declaration.after.import")))
+    (setf (js2-node-len clause) (- (js2-current-token-end) beg))
+    (apply #'js2-node-add-children clause children)
+    clause))
+
+(defun js2-parse-namespace-import ()
+  "Parse a namespace import expression such as  '* as bar'.
+The current token must be js2-MUL."
+  (let ((beg (js2-current-token-beg)))
+    (cond
+      ((js2-match-contextual-kwd "as")
+       (when (js2-must-match-prop-name "msg.syntax")
+         (let ((node (make-js2-namespace-import-node
+                      :pos beg
+                      :len (- (js2-current-token-end) beg)
+                      :name (make-js2-name-node
+                             :pos (js2-current-token-beg)
+                             :len (- (js2-current-token-end)
+                                     (js2-current-token-beg))
+                             :name (js2-current-token-string)))))
+           (js2-node-add-children node (js2-namespace-import-node-name node))
+           node)))
+      (t
+       (js2-unget-token)
+       (js2-report-error "msg.syntax")
+       nil))))
+
+
+(defun js2-parse-from-clause ()
+  "Parse the from clause in an import or export statement. E.g. from 'src/lib'"
+  (if (js2-match-contextual-kwd "from")
+      (let ((beg (js2-current-token-beg)))
+        (cond
+         ((js2-match-token js2-STRING)
+          (make-js2-from-clause-node
+           :pos beg
+           :len (- (js2-current-token-end) beg)
+           :module-id (js2-current-token-string)
+           :metadata-p nil))
+         ((js2-match-token js2-THIS)
+          (when (js2-must-match-name "msg.mod.spec.after.from")
+            (if (equal "module" (js2-current-token-string))
+                (make-js2-from-clause-node
+                 :pos beg
+                 :len (- (js2-current-token-end) beg)
+                 :module-id "this"
+                 :metadata-p t)
+              (js2-unget-token)
+              (js2-unget-token)
+              (js2-report-error "msg.mod.spec.after.from")
+              nil)))
+         (t (js2-report-error "msg.mod.spec.after.from") nil)))
+    (js2-report-error "msg.mod.from.after.import.spec.set")
+    nil))
+
+(defun js2-parse-export-bindings (&optional import-p)
+  "Parse a list of export binding expressions such as {}, {foo, bar}, and
+{foo as bar, baz as bang}. The current token must be
+js2-LC. Return a lisp list of js2-export-binding-node"
+  (let ((bindings (list)))
+    (while
+        (let ((binding (js2-maybe-parse-export-binding import-p)))
+          (when binding
+            (push binding bindings))
+          (js2-match-token js2-COMMA)))
+    (when (js2-must-match js2-RC (if import-p
+                                     "msg.mod.rc.after.import.spec.list"
+                                   "msg.mod.rc.after.export.spec.list"))
+      (reverse bindings))))
+
+(defun js2-maybe-parse-export-binding (&optional import-p)
+  "Attempt to parse a binding expression found inside an import/export statement.
+This can take the form of either as single js2-NAME token as in 'foo' or as in a
+rebinding expression 'bar as foo'. If it matches, it will return an instance of
+js2-export-binding-node and consume all the tokens. If it does not match, it
+consumes no tokens."
+  (let ((extern-name (when (js2-match-prop-name) (js2-current-token-string)))
+        (beg (js2-current-token-beg))
+        (extern-name-len (js2-current-token-len))
+        (is-reserved-name (or (= (js2-current-token-type) js2-RESERVED)
+                              (aref js2-kwd-tokens (js2-current-token-type)))))
+    (if extern-name
+        (if (js2-match-contextual-kwd "as")
+            (let ((name
+                   (or
+                    (and (js2-match-token js2-DEFAULT) "default")
+                    (and (js2-match-token js2-NAME) (js2-current-token-string)))))
+              (if name
+                  (let ((node (make-js2-export-binding-node
+                               :pos beg
+                               :len (- (js2-current-token-end) beg)
+                               :local-name (make-js2-name-node
+                                            :name name
+                                            :pos (js2-current-token-beg)
+                                            :len (js2-current-token-len))
+                               :extern-name (make-js2-name-node
+                                             :name extern-name
+                                             :pos beg
+                                             :len extern-name-len))))
+                    (js2-node-add-children
+                     node
+                     (js2-export-binding-node-local-name node)
+                     (js2-export-binding-node-extern-name node))
+                    (if import-p
+                        (js2-set-face (js2-current-token-beg) (js2-current-token-end)
+                                      'font-lock-variable-name-face 'record))
+                    node)
+                (js2-unget-token)
+                nil))
+          (let* ((name-node (make-js2-name-node
+                             :name (js2-current-token-string)
+                             :pos (js2-current-token-beg)
+                             :len (js2-current-token-len)))
+                 (node (make-js2-export-binding-node
+                        :pos (js2-current-token-beg)
+                        :len (js2-current-token-len)
+                        :local-name name-node
+                        :extern-name name-node)))
+            (when is-reserved-name
+              (js2-report-error "msg.mod.as.after.reserved.word" extern-name))
+            (js2-node-add-children node name-node)
+            (if import-p
+                (js2-set-face (js2-current-token-beg) (js2-current-token-end)
+                              'font-lock-variable-name-face 'record))
+            node))
+      nil)))
+
+(defun js2-parse-switch ()
+  "Parser for switch-statement.  Last matched token must be js2-SWITCH."
+  (let ((pos (js2-current-token-beg))
+        tt pn discriminant has-default case-expr case-node
+        case-pos cases stmt lp)
+    (if (js2-must-match js2-LP "msg.no.paren.switch")
+        (setq lp (js2-current-token-beg)))
+    (setq discriminant (js2-parse-expr)
+          pn (make-js2-switch-node :discriminant discriminant
+                                   :pos pos
+                                   :lp (js2-relpos lp pos)))
+    (js2-node-add-children pn discriminant)
+    (js2-enter-switch pn)
+    (unwind-protect
+        (progn
+          (if (js2-must-match js2-RP "msg.no.paren.after.switch")
+              (setf (js2-switch-node-rp pn) (- (js2-current-token-beg) pos)))
+          (js2-must-match js2-LC "msg.no.brace.switch")
+          (catch 'break
+            (while t
+              (setq tt (js2-next-token)
+                    case-pos (js2-current-token-beg))
+              (cond
+               ((= tt js2-RC)
+                (setf (js2-node-len pn) (- (js2-current-token-end) pos))
+                (throw 'break nil))  ; done
+               ((= tt js2-CASE)
+                (setq case-expr (js2-parse-expr))
+                (js2-must-match js2-COLON "msg.no.colon.case"))
+               ((= tt js2-DEFAULT)
+                (if has-default
+                    (js2-report-error "msg.double.switch.default"))
+                (setq has-default t
+                      case-expr nil)
+                (js2-must-match js2-COLON "msg.no.colon.case"))
+               (t
+                (js2-report-error "msg.bad.switch")
+                (throw 'break nil)))
+              (setq case-node (make-js2-case-node :pos case-pos
+                                                  :len (- (js2-current-token-end) case-pos)
+                                                  :expr case-expr))
+              (js2-node-add-children case-node case-expr)
+              (while (and (/= (setq tt (js2-peek-token)) js2-RC)
+                          (/= tt js2-CASE)
+                          (/= tt js2-DEFAULT)
+                          (/= tt js2-EOF))
+                (setf stmt (js2-parse-statement)
+                      (js2-node-len case-node) (- (js2-node-end stmt) case-pos))
+                (js2-block-node-push case-node stmt))
+              (push case-node cases)))
+          ;; add cases last, as pushing reverses the order to be correct
+          (dolist (kid cases)
+            (js2-node-add-children pn kid)
+            (push kid (js2-switch-node-cases pn)))
+          pn)  ; return value
+      (js2-exit-switch))))
+
+(defun js2-parse-while ()
+  "Parser for while-statement.  Last matched token must be js2-WHILE."
+  (let ((pos (js2-current-token-beg))
+        (pn (make-js2-while-node))
+        cond body)
+    (js2-enter-loop pn)
+    (unwind-protect
+        (progn
+          (setf cond (js2-parse-condition)
+                (js2-while-node-condition pn) (car cond)
+                body (js2-parse-statement)
+                (js2-while-node-body pn) body
+                (js2-node-len pn) (- (js2-node-end body) pos)
+                (js2-while-node-lp pn) (js2-relpos (cl-second cond) pos)
+                (js2-while-node-rp pn) (js2-relpos (cl-third cond) pos))
+          (js2-node-add-children pn body (car cond)))
+      (js2-exit-loop))
+    pn))
+
+(defun js2-parse-do ()
+  "Parser for do-statement.  Last matched token must be js2-DO."
+  (let ((pos (js2-current-token-beg))
+        (pn (make-js2-do-node))
+        cond body end)
+    (js2-enter-loop pn)
+    (unwind-protect
+        (progn
+          (setq body (js2-parse-statement))
+          (js2-must-match js2-WHILE "msg.no.while.do")
+          (setf (js2-do-node-while-pos pn) (- (js2-current-token-beg) pos)
+                cond (js2-parse-condition)
+                (js2-do-node-condition pn) (car cond)
+                (js2-do-node-body pn) body
+                end js2-ts-cursor
+                (js2-do-node-lp pn) (js2-relpos (cl-second cond) pos)
+                (js2-do-node-rp pn) (js2-relpos (cl-third cond) pos))
+          (js2-node-add-children pn (car cond) body))
+      (js2-exit-loop))
+    ;; Always auto-insert semicolon to follow SpiderMonkey:
+    ;; It is required by ECMAScript but is ignored by the rest of
+    ;; world; see bug 238945
+    (if (js2-match-token js2-SEMI)
+        (setq end js2-ts-cursor))
+    (setf (js2-node-len pn) (- end pos))
+    pn))
+
+(defun js2-parse-export ()
+  "Parse an export statement.
+The Last matched token must be js2-EXPORT. Currently, the 'default' and 'expr'
+expressions should only be either hoistable expressions (function or generator)
+or assignment expressions, but there is no checking to enforce that and so it
+will parse without error a small subset of
+invalid export statements."
+  (unless (js2-ast-root-p js2-current-scope)
+    (js2-report-error "msg.mod.export.decl.at.top.level"))
+  (let ((beg (js2-current-token-beg))
+        (children (list))
+        exports-list from-clause declaration default)
+    (cond
+     ((js2-match-token js2-MUL)
+      (setq from-clause (js2-parse-from-clause))
+      (when from-clause
+        (push from-clause children)))
+     ((js2-match-token js2-LC)
+      (setq exports-list (js2-parse-export-bindings))
+      (when exports-list
+        (dolist (export exports-list)
+          (push export children)))
+      (when (js2-match-contextual-kwd "from")
+        (js2-unget-token)
+        (setq from-clause (js2-parse-from-clause))))
+     ((js2-match-token js2-DEFAULT)
+      (setq default (cond ((js2-match-token js2-CLASS)
+                           (if (eq (js2-peek-token) js2-NAME)
+                               (js2-parse-class-stmt)
+                             (js2-parse-class-expr)))
+                          ((js2-match-token js2-NAME)
+                           (if (js2-match-async-function)
+                               (if (eq (js2-peek-token) js2-NAME)
+                                   (js2-parse-async-function-stmt)
+                                 (js2-parse-function-expr t))
+                             (js2-unget-token)
+                             (js2-parse-expr)))
+                          ((js2-match-token js2-FUNCTION)
+                           (if (eq (js2-peek-token) js2-NAME)
+                               (js2-parse-function-stmt)
+                             (js2-parse-function-expr)))
+                          (t (js2-parse-expr)))))
+     ((or (js2-match-token js2-VAR) (js2-match-token js2-CONST) (js2-match-token js2-LET))
+      (setq declaration (js2-parse-variables (js2-current-token-type) (js2-current-token-beg))))
+     ((js2-match-token js2-CLASS)
+      (setq declaration (js2-parse-class-stmt)))
+     ((js2-match-token js2-NAME)
+      (setq declaration
+            (if (js2-match-async-function)
+                (js2-parse-async-function-stmt)
+              (js2-unget-token)
+              (js2-parse-expr))))
+     ((js2-match-token js2-FUNCTION)
+      (setq declaration (js2-parse-function-stmt)))
+     (t
+      (setq declaration (js2-parse-expr))))
+    (when from-clause
+      (push from-clause children))
+    (when declaration
+      (push declaration children)
+      (when (not (or (js2-function-node-p declaration)
+                     (js2-class-node-p declaration)))
+        (js2-auto-insert-semicolon declaration)))
+    (when default
+      (push default children)
+      (when (not (or (js2-function-node-p default)
+                     (js2-class-node-p default)))
+        (js2-auto-insert-semicolon default)))
+    (let ((node (make-js2-export-node
+                  :pos beg
+                  :len (- (js2-current-token-end) beg)
+                  :exports-list exports-list
+                  :from-clause from-clause
+                  :declaration declaration
+                  :default default)))
+      (apply #'js2-node-add-children node children)
+      node)))
+
+(defun js2-parse-for ()
+  "Parse a for, for-in or for each-in statement.
+Last matched token must be js2-FOR."
+  (let ((for-pos (js2-current-token-beg))
+        (tmp-scope (make-js2-scope))
+        pn is-for-each is-for-in-or-of is-for-of
+        in-pos each-pos tmp-pos
+        init  ; Node init is also foo in 'foo in object'.
+        cond  ; Node cond is also object in 'foo in object'.
+        incr  ; 3rd section of for-loop initializer.
+        body tt lp rp)
+    ;; See if this is a for each () instead of just a for ()
+    (when (js2-match-token js2-NAME)
+      (if (string= "each" (js2-current-token-string))
+          (progn
+            (setq is-for-each t
+                  each-pos (- (js2-current-token-beg) for-pos)) ; relative
+            (js2-record-face 'font-lock-keyword-face))
+        (js2-report-error "msg.no.paren.for")))
+    (if (js2-must-match js2-LP "msg.no.paren.for")
+        (setq lp (- (js2-current-token-beg) for-pos)))
+    (setq tt (js2-get-token))
+    ;; Capture identifiers inside parens.  We can't create the node
+    ;; (and use it as the current scope) until we know its type.
+    (js2-push-scope tmp-scope)
+    (unwind-protect
+        (progn
+          ;; parse init clause
+          (let ((js2-in-for-init t))  ; set as dynamic variable
+            (cond
+             ((= tt js2-SEMI)
+              (js2-unget-token)
+              (setq init (make-js2-empty-expr-node)))
+             ((or (= tt js2-VAR) (= tt js2-LET) (= tt js2-CONST))
+              (setq init (js2-parse-variables tt (js2-current-token-beg))))
+             (t
+              (js2-unget-token)
+              (setq init (js2-parse-expr)))))
+          (if (or (js2-match-token js2-IN)
+                  (and (>= js2-language-version 200)
+                       (js2-match-contextual-kwd "of")
+                       (setq is-for-of t)))
+              (setq is-for-in-or-of t
+                    in-pos (- (js2-current-token-beg) for-pos)
+                    ;; scope of iteration target object is not the scope we've created above.
+                    ;; stash current scope temporary.
+                    cond (let ((js2-current-scope (js2-scope-parent-scope js2-current-scope)))
+                           (js2-parse-expr)))  ; object over which we're iterating
+            ;; else ordinary for loop - parse cond and incr
+            (js2-must-match js2-SEMI "msg.no.semi.for")
+            (setq cond (if (= (js2-peek-token) js2-SEMI)
+                           (make-js2-empty-expr-node) ; no loop condition
+                         (js2-parse-expr)))
+            (js2-must-match js2-SEMI "msg.no.semi.for.cond")
+            (setq tmp-pos (js2-current-token-end)
+                  incr (if (= (js2-peek-token) js2-RP)
+                           (make-js2-empty-expr-node :pos tmp-pos)
+                         (js2-parse-expr)))))
+      (js2-pop-scope))
+    (if (js2-must-match js2-RP "msg.no.paren.for.ctrl")
+        (setq rp (- (js2-current-token-beg) for-pos)))
+    (if (not is-for-in-or-of)
+        (setq pn (make-js2-for-node :init init
+                                    :condition cond
+                                    :update incr
+                                    :lp lp
+                                    :rp rp))
+      ;; cond could be null if 'in obj' got eaten by the init node.
+      (if (js2-infix-node-p init)
+          ;; it was (foo in bar) instead of (var foo in bar)
+          (setq cond (js2-infix-node-right init)
+                init (js2-infix-node-left init))
+        (if (and (js2-var-decl-node-p init)
+                 (> (length (js2-var-decl-node-kids init)) 1))
+            (js2-report-error "msg.mult.index")))
+      (setq pn (make-js2-for-in-node :iterator init
+                                     :object cond
+                                     :in-pos in-pos
+                                     :foreach-p is-for-each
+                                     :each-pos each-pos
+                                     :forof-p is-for-of
+                                     :lp lp
+                                     :rp rp)))
+    ;; Transplant the declarations.
+    (setf (js2-scope-symbol-table pn)
+          (js2-scope-symbol-table tmp-scope))
+    (unwind-protect
+        (progn
+          (js2-enter-loop pn)
+          ;; We have to parse the body -after- creating the loop node,
+          ;; so that the loop node appears in the js2-loop-set, allowing
+          ;; break/continue statements to find the enclosing loop.
+          (setf body (js2-parse-statement)
+                (js2-loop-node-body pn) body
+                (js2-node-pos pn) for-pos
+                (js2-node-len pn) (- (js2-node-end body) for-pos))
+          (js2-node-add-children pn init cond incr body))
+      ;; finally
+      (js2-exit-loop))
+    pn))
+
+(defun js2-parse-try ()
+  "Parse a try statement.  Last matched token must be js2-TRY."
+  (let ((try-pos (js2-current-token-beg))
+        try-end
+        try-block
+        catch-blocks
+        finally-block
+        saw-default-catch
+        peek)
+    (if (/= (js2-peek-token) js2-LC)
+        (js2-report-error "msg.no.brace.try"))
+    (setq try-block (js2-parse-statement)
+          try-end (js2-node-end try-block)
+          peek (js2-peek-token))
+    (cond
+     ((= peek js2-CATCH)
+      (while (js2-match-token js2-CATCH)
+        (let* ((catch-pos (js2-current-token-beg))
+               (catch-node (make-js2-catch-node :pos catch-pos))
+               param
+               guard-kwd
+               catch-cond
+               lp rp)
+          (if saw-default-catch
+              (js2-report-error "msg.catch.unreachable"))
+          (if (js2-must-match js2-LP "msg.no.paren.catch")
+              (setq lp (- (js2-current-token-beg) catch-pos)))
+          (js2-push-scope catch-node)
+          (let ((tt (js2-peek-token)))
+            (cond
+             ;; Destructuring pattern:
+             ;;     catch ({ message, file }) { ... }
+             ((or (= tt js2-LB) (= tt js2-LC))
+              (js2-get-token)
+              (setq param (js2-parse-destruct-primary-expr))
+              (js2-define-destruct-symbols param js2-LET nil))
+             ;; Simple name.
+             (t
+              (js2-must-match-name "msg.bad.catchcond")
+              (setq param (js2-create-name-node))
+              (js2-define-symbol js2-LET (js2-current-token-string) param)
+              (js2-check-strict-identifier param))))
+          ;; Catch condition.
+          (if (js2-match-token js2-IF)
+              (setq guard-kwd (- (js2-current-token-beg) catch-pos)
+                    catch-cond (js2-parse-expr))
+            (setq saw-default-catch t))
+          (if (js2-must-match js2-RP "msg.bad.catchcond")
+              (setq rp (- (js2-current-token-beg) catch-pos)))
+          (js2-must-match js2-LC "msg.no.brace.catchblock")
+          (js2-parse-statements catch-node)
+          (if (js2-must-match js2-RC "msg.no.brace.after.body")
+              (setq try-end (js2-current-token-end)))
+          (js2-pop-scope)
+          (setf (js2-node-len catch-node) (- try-end catch-pos)
+                (js2-catch-node-param catch-node) param
+                (js2-catch-node-guard-expr catch-node) catch-cond
+                (js2-catch-node-guard-kwd catch-node) guard-kwd
+                (js2-catch-node-lp catch-node) lp
+                (js2-catch-node-rp catch-node) rp)
+          (js2-node-add-children catch-node param catch-cond)
+          (push catch-node catch-blocks))))
+     ((/= peek js2-FINALLY)
+      (js2-must-match js2-FINALLY "msg.try.no.catchfinally"
+                      (js2-node-pos try-block)
+                      (- (setq try-end (js2-node-end try-block))
+                         (js2-node-pos try-block)))))
+    (when (js2-match-token js2-FINALLY)
+      (let ((finally-pos (js2-current-token-beg))
+            (block (js2-parse-statement)))
+        (setq try-end (js2-node-end block)
+              finally-block (make-js2-finally-node :pos finally-pos
+                                                   :len (- try-end finally-pos)
+                                                   :body block))
+        (js2-node-add-children finally-block block)))
+    (let ((pn (make-js2-try-node :pos try-pos
+                                 :len (- try-end try-pos)
+                                 :try-block try-block
+                                 :finally-block finally-block)))
+      (js2-node-add-children pn try-block finally-block)
+      ;; Push them onto the try-node, which reverses and corrects their order.
+      (dolist (cb catch-blocks)
+        (js2-node-add-children pn cb)
+        (push cb (js2-try-node-catch-clauses pn)))
+      pn)))
+
+(defun js2-parse-throw ()
+  "Parser for throw-statement.  Last matched token must be js2-THROW."
+  (let ((pos (js2-current-token-beg))
+        expr pn)
+    (if (= (js2-peek-token-or-eol) js2-EOL)
+        ;; ECMAScript does not allow new lines before throw expression,
+        ;; see bug 256617
+        (js2-report-error "msg.bad.throw.eol"))
+    (setq expr (js2-parse-expr)
+          pn (make-js2-throw-node :pos pos
+                                  :len (- (js2-node-end expr) pos)
+                                  :expr expr))
+    (js2-node-add-children pn expr)
+    pn))
+
+(defun js2-match-jump-label-name (label-name)
+  "If break/continue specified a label, return that label's labeled stmt.
+Returns the corresponding `js2-labeled-stmt-node', or if LABEL-NAME
+does not match an existing label, reports an error and returns nil."
+  (let ((bundle (cdr (assoc label-name js2-label-set))))
+    (if (null bundle)
+        (js2-report-error "msg.undef.label"))
+    bundle))
+
+(defun js2-parse-break ()
+  "Parser for break-statement.  Last matched token must be js2-BREAK."
+  (let ((pos (js2-current-token-beg))
+        (end (js2-current-token-end))
+        break-target ; statement to break from
+        break-label  ; in "break foo", name-node representing the foo
+        labels       ; matching labeled statement to break to
+        pn)
+    (when (eq (js2-peek-token-or-eol) js2-NAME)
+      (js2-get-token)
+      (setq break-label (js2-create-name-node)
+            end (js2-node-end break-label)
+            ;; matchJumpLabelName only matches if there is one
+            labels (js2-match-jump-label-name (js2-current-token-string))
+            break-target (if labels (car (js2-labeled-stmt-node-labels labels)))))
+    (unless (or break-target break-label)
+      ;; no break target specified - try for innermost enclosing loop/switch
+      (if (null js2-loop-and-switch-set)
+          (unless break-label
+            (js2-report-error "msg.bad.break" nil pos (length "break")))
+        (setq break-target (car js2-loop-and-switch-set))))
+    (setq pn (make-js2-break-node :pos pos
+                                  :len (- end pos)
+                                  :label break-label
+                                  :target break-target))
+    (js2-node-add-children pn break-label)  ; but not break-target
+    pn))
+
+(defun js2-parse-continue ()
+  "Parser for continue-statement.  Last matched token must be js2-CONTINUE."
+  (let ((pos (js2-current-token-beg))
+        (end (js2-current-token-end))
+        label   ; optional user-specified label, a `js2-name-node'
+        labels  ; current matching labeled stmt, if any
+        target  ; the `js2-loop-node' target of this continue stmt
+        pn)
+    (when (= (js2-peek-token-or-eol) js2-NAME)
+      (js2-get-token)
+      (setq label (js2-create-name-node)
+            end (js2-node-end label)
+            ;; matchJumpLabelName only matches if there is one
+            labels (js2-match-jump-label-name (js2-current-token-string))))
+    (cond
+     ((null labels)  ; no current label to go to
+      (if (null js2-loop-set)  ; no loop to continue to
+          (js2-report-error "msg.continue.outside" nil pos
+                            (length "continue"))
+        (setq target (car js2-loop-set))))  ; innermost enclosing loop
+     (t
+      (if (js2-loop-node-p (js2-labeled-stmt-node-stmt labels))
+          (setq target (js2-labeled-stmt-node-stmt labels))
+        (js2-report-error "msg.continue.nonloop" nil pos (- end pos)))))
+    (setq pn (make-js2-continue-node :pos pos
+                                     :len (- end pos)
+                                     :label label
+                                     :target target))
+    (js2-node-add-children pn label)  ; but not target - it's not our child
+    pn))
+
+(defun js2-parse-with ()
+  "Parser for with-statement.  Last matched token must be js2-WITH."
+  (when js2-in-use-strict-directive
+    (js2-report-error "msg.no.with.strict"))
+  (let ((pos (js2-current-token-beg))
+        obj body pn lp rp)
+    (if (js2-must-match js2-LP "msg.no.paren.with")
+        (setq lp (js2-current-token-beg)))
+    (setq obj (js2-parse-expr))
+    (if (js2-must-match js2-RP "msg.no.paren.after.with")
+        (setq rp (js2-current-token-beg)))
+    (let ((js2-nesting-of-with (1+ js2-nesting-of-with)))
+        (setq body (js2-parse-statement)))
+    (setq pn (make-js2-with-node :pos pos
+                                 :len (- (js2-node-end body) pos)
+                                 :object obj
+                                 :body body
+                                 :lp (js2-relpos lp pos)
+                                 :rp (js2-relpos rp pos)))
+    (js2-node-add-children pn obj body)
+    pn))
+
+(defun js2-parse-const-var ()
+  "Parser for var- or const-statement.
+Last matched token must be js2-CONST or js2-VAR."
+  (let ((tt (js2-current-token-type))
+        (pos (js2-current-token-beg))
+        expr pn)
+    (setq expr (js2-parse-variables tt (js2-current-token-beg))
+          pn (make-js2-expr-stmt-node :pos pos
+                                      :len (- (js2-node-end expr) pos)
+                                      :expr expr))
+    (js2-node-add-children pn expr)
+    pn))
+
+(defun js2-wrap-with-expr-stmt (pos expr &optional add-child)
+  (let ((pn (make-js2-expr-stmt-node :pos pos
+                                     :len (js2-node-len expr)
+                                     :type (if (js2-inside-function)
+                                               js2-EXPR_VOID
+                                             js2-EXPR_RESULT)
+                                     :expr expr)))
+    (if add-child
+        (js2-node-add-children pn expr))
+    pn))
+
+(defun js2-parse-let-stmt ()
+  "Parser for let-statement.  Last matched token must be js2-LET."
+  (let ((pos (js2-current-token-beg))
+        expr pn)
+    (if (= (js2-peek-token) js2-LP)
+        ;; let expression in statement context
+        (setq expr (js2-parse-let pos 'statement)
+              pn (js2-wrap-with-expr-stmt pos expr t))
+      ;; else we're looking at a statement like let x=6, y=7;
+      (setf expr (js2-parse-variables js2-LET pos)
+            pn (js2-wrap-with-expr-stmt pos expr t)
+            (js2-node-type pn) js2-EXPR_RESULT))
+    pn))
+
+(defun js2-parse-ret-yield ()
+  (js2-parse-return-or-yield (js2-current-token-type) nil))
+
+(defconst js2-parse-return-stmt-enders
+  (list js2-SEMI js2-RC js2-EOF js2-EOL js2-ERROR js2-RB js2-RP))
+
+(defsubst js2-now-all-set (before after mask)
+  "Return whether or not the bits in the mask have changed to all set.
+BEFORE is bits before change, AFTER is bits after change, and MASK is
+the mask for bits.  Returns t if all the bits in the mask are set in AFTER
+but not BEFORE."
+  (and (/= (logand before mask) mask)
+       (= (logand after mask) mask)))
+
+(defun js2-parse-return-or-yield (tt expr-context)
+  (let* ((pos (js2-current-token-beg))
+         (end (js2-current-token-end))
+         (before js2-end-flags)
+         (inside-function (js2-inside-function))
+         (gen-type (and inside-function (js2-function-node-generator-type
+                                         js2-current-script-or-fn)))
+         e ret name yield-star-p)
+    (unless inside-function
+      (js2-report-error (if (eq tt js2-RETURN)
+                            "msg.bad.return"
+                          "msg.bad.yield")))
+    (when (and inside-function
+               (eq gen-type 'STAR)
+               (js2-match-token js2-MUL))
+      (setq yield-star-p t))
+    ;; This is ugly, but we don't want to require a semicolon.
+    (unless (memq (js2-peek-token-or-eol) js2-parse-return-stmt-enders)
+      (setq e (if (eq gen-type 'STAR)
+                  (js2-parse-assign-expr)
+                (js2-parse-expr))
+            end (js2-node-end e)))
+    (cond
+     ((eq tt js2-RETURN)
+      (js2-set-flag js2-end-flags (if (null e)
+                                      js2-end-returns
+                                    js2-end-returns-value))
+      (setq ret (make-js2-return-node :pos pos
+                                      :len (- end pos)
+                                      :retval e))
+      (js2-node-add-children ret e)
+      ;; See if we need a strict mode warning.
+      ;; TODO:  The analysis done by `js2-has-consistent-return-usage' is
+      ;; more thorough and accurate than this before/after flag check.
+      ;; E.g. if there's a finally-block that always returns, we shouldn't
+      ;; show a warning generated by inconsistent returns in the catch blocks.
+      ;; Basically `js2-has-consistent-return-usage' needs to keep more state,
+      ;; so we know which returns/yields to highlight, and we should get rid of
+      ;; all the checking in `js2-parse-return-or-yield'.
+      (if (and js2-strict-inconsistent-return-warning
+               (js2-now-all-set before js2-end-flags
+                                (logior js2-end-returns js2-end-returns-value)))
+          (js2-add-strict-warning "msg.return.inconsistent" nil pos end)))
+     ((eq gen-type 'COMPREHENSION)
+      ;; FIXME: We should probably switch to saving and using lastYieldOffset,
+      ;; like SpiderMonkey does.
+      (js2-report-error "msg.syntax" nil pos 5))
+     (t
+      (setq ret (make-js2-yield-node :pos pos
+                                     :len (- end pos)
+                                     :value e
+                                     :star-p yield-star-p))
+      (js2-node-add-children ret e)
+      (unless expr-context
+        (setq e ret
+              ret (js2-wrap-with-expr-stmt pos e t))
+      (js2-set-requires-activation)
+      (js2-set-is-generator))))
+    ;; see if we are mixing yields and value returns.
+    (when (and inside-function
+               (js2-flag-set-p js2-end-flags js2-end-returns-value)
+               (eq (js2-function-node-generator-type js2-current-script-or-fn)
+                   'LEGACY))
+      (setq name (js2-function-name js2-current-script-or-fn))
+      (if (zerop (length name))
+          (js2-report-error "msg.anon.generator.returns" nil pos (- end pos))
+        (js2-report-error "msg.generator.returns" name pos (- end pos))))
+    ret))
+
+(defun js2-parse-debugger ()
+  (make-js2-keyword-node :type js2-DEBUGGER))
+
+(defun js2-parse-block ()
+  "Parser for a curly-delimited statement block.
+Last token matched must be `js2-LC'."
+  (let ((pos (js2-current-token-beg))
+        (pn (make-js2-scope)))
+    (js2-push-scope pn)
+    (unwind-protect
+        (progn
+          (js2-parse-statements pn)
+          (js2-must-match js2-RC "msg.no.brace.block")
+          (setf (js2-node-len pn) (- (js2-current-token-end) pos)))
+      (js2-pop-scope))
+    pn))
+
+;; For `js2-ERROR' too, to have a node for error recovery to work on.
+(defun js2-parse-semi ()
+  "Parse a statement or handle an error.
+Current token type is `js2-SEMI' or `js2-ERROR'."
+  (let ((tt (js2-current-token-type)) pos len)
+    (if (eq tt js2-SEMI)
+        (make-js2-empty-expr-node :len 1)
+      (setq pos (js2-current-token-beg)
+            len (- (js2-current-token-end) pos))
+      (js2-report-error "msg.syntax" nil pos len)
+      (make-js2-error-node :pos pos :len len))))
+
+(defun js2-parse-default-xml-namespace ()
+  "Parse a `default xml namespace = <expr>' e4x statement."
+  (let ((pos (js2-current-token-beg))
+        end len expr unary)
+    (js2-must-have-xml)
+    (js2-set-requires-activation)
+    (setq len (- js2-ts-cursor pos))
+    (unless (and (js2-match-token js2-NAME)
+                 (string= (js2-current-token-string) "xml"))
+      (js2-report-error "msg.bad.namespace" nil pos len))
+    (unless (and (js2-match-token js2-NAME)
+                 (string= (js2-current-token-string) "namespace"))
+      (js2-report-error "msg.bad.namespace" nil pos len))
+    (unless (js2-match-token js2-ASSIGN)
+      (js2-report-error "msg.bad.namespace" nil pos len))
+    (setq expr (js2-parse-expr)
+          end (js2-node-end expr)
+          unary (make-js2-unary-node :type js2-DEFAULTNAMESPACE
+                                     :pos pos
+                                     :len (- end pos)
+                                     :operand expr))
+    (js2-node-add-children unary expr)
+    (make-js2-expr-stmt-node :pos pos
+                             :len (- end pos)
+                             :expr unary)))
+
+(defun js2-record-label (label bundle)
+  ;; current token should be colon that `js2-parse-primary-expr' left untouched
+  (js2-get-token)
+  (let ((name (js2-label-node-name label))
+        labeled-stmt
+        dup)
+    (when (setq labeled-stmt (cdr (assoc name js2-label-set)))
+      ;; flag both labels if possible when used in editing mode
+      (if (and js2-parse-ide-mode
+               (setq dup (js2-get-label-by-name labeled-stmt name)))
+          (js2-report-error "msg.dup.label" nil
+                            (js2-node-abs-pos dup) (js2-node-len dup)))
+      (js2-report-error "msg.dup.label" nil
+                        (js2-node-pos label) (js2-node-len label)))
+    (js2-labeled-stmt-node-add-label bundle label)
+    (js2-node-add-children bundle label)
+    ;; Add one reference to the bundle per label in `js2-label-set'
+    (push (cons name bundle) js2-label-set)))
+
+(defun js2-parse-name-or-label ()
+  "Parser for identifier or label.  Last token matched must be js2-NAME.
+Called when we found a name in a statement context.  If it's a label, we gather
+up any following labels and the next non-label statement into a
+`js2-labeled-stmt-node' bundle and return that.  Otherwise we parse an
+expression and return it wrapped in a `js2-expr-stmt-node'."
+  (let ((pos (js2-current-token-beg))
+        expr stmt bundle
+        (continue t))
+    ;; set check for label and call down to `js2-parse-primary-expr'
+    (setq expr (js2-maybe-parse-label))
+    (if (null expr)
+        ;; Parse the non-label expression and wrap with expression stmt.
+        (js2-wrap-with-expr-stmt pos (js2-parse-expr) t)
+      ;; else parsed a label
+      (setq bundle (make-js2-labeled-stmt-node :pos pos))
+      (js2-record-label expr bundle)
+      ;; look for more labels
+      (while (and continue (= (js2-get-token) js2-NAME))
+        (if (setq expr (js2-maybe-parse-label))
+            (js2-record-label expr bundle)
+          (setq expr (js2-parse-expr)
+                stmt (js2-wrap-with-expr-stmt (js2-node-pos expr) expr t)
+                continue nil)
+          (js2-auto-insert-semicolon stmt)))
+      ;; no more labels; now parse the labeled statement
+      (unwind-protect
+            (unless stmt
+              (let ((js2-labeled-stmt bundle))  ; bind dynamically
+                (js2-unget-token)
+                (setq stmt (js2-statement-helper))))
+        ;; remove the labels for this statement from the global set
+        (dolist (label (js2-labeled-stmt-node-labels bundle))
+          (setq js2-label-set (remove label js2-label-set))))
+      (setf (js2-labeled-stmt-node-stmt bundle) stmt
+            (js2-node-len bundle) (- (js2-node-end stmt) pos))
+      (js2-node-add-children bundle stmt)
+      bundle)))
+
+(defun js2-maybe-parse-label ()
+  (cl-assert (= (js2-current-token-type) js2-NAME))
+  (let (label-pos
+        (next-tt (js2-get-token))
+        (label-end (js2-current-token-end)))
+    ;; Do not consume colon, it is used as unwind indicator
+    ;; to return to statementHelper.
+    (js2-unget-token)
+    (if (= next-tt js2-COLON)
+        (prog2
+            (setq label-pos (js2-current-token-beg))
+            (make-js2-label-node :pos label-pos
+                                 :len (- label-end label-pos)
+                                 :name (js2-current-token-string))
+          (js2-set-face label-pos
+                        label-end
+                        'font-lock-variable-name-face 'record))
+      ;; Backtrack from the name token, too.
+      (js2-unget-token)
+      nil)))
+
+(defun js2-parse-expr-stmt ()
+  "Default parser in statement context, if no recognized statement found."
+  (js2-wrap-with-expr-stmt (js2-current-token-beg)
+                           (progn
+                             (js2-unget-token)
+                             (js2-parse-expr)) t))
+
+(defun js2-parse-variables (decl-type pos)
+  "Parse a comma-separated list of variable declarations.
+Could be a 'var', 'const' or 'let' expression, possibly in a for-loop initializer.
+
+DECL-TYPE is a token value: either VAR, CONST, or LET depending on context.
+For 'var' or 'const', the keyword should be the token last scanned.
+
+POS is the position where the node should start. It's sometimes the
+var/const/let keyword, and other times the beginning of the first token
+in the first variable declaration.
+
+Returns the parsed `js2-var-decl-node' expression node."
+  (let* ((result (make-js2-var-decl-node :decl-type decl-type
+                                         :pos pos))
+         destructuring kid-pos tt init name end nbeg nend vi
+         (continue t))
+    ;; Example:
+    ;; var foo = {a: 1, b: 2}, bar = [3, 4];
+    ;; var {b: s2, a: s1} = foo, x = 6, y, [s3, s4] = bar;
+    ;; var {a, b} = baz;
+    (while continue
+      (setq destructuring nil
+            name nil
+            tt (js2-get-token)
+            kid-pos (js2-current-token-beg)
+            end (js2-current-token-end)
+            init nil)
+      (if (or (= tt js2-LB) (= tt js2-LC))
+          ;; Destructuring assignment, e.g., var [a, b] = ...
+          (setq destructuring (js2-parse-destruct-primary-expr)
+                end (js2-node-end destructuring))
+        ;; Simple variable name
+        (js2-unget-token)
+        (when (js2-must-match-name "msg.bad.var")
+          (setq name (js2-create-name-node)
+                nbeg (js2-current-token-beg)
+                nend (js2-current-token-end)
+                end nend)
+          (js2-define-symbol decl-type (js2-current-token-string) name js2-in-for-init)
+          (js2-check-strict-identifier name)))
+      (when (js2-match-token js2-ASSIGN)
+        (setq init (js2-parse-assign-expr)
+              end (js2-node-end init))
+        (js2-record-imenu-functions init name))
+      (when name
+        (js2-set-face nbeg nend (if (js2-function-node-p init)
+                                    'font-lock-function-name-face
+                                  'font-lock-variable-name-face)
+                      'record))
+      (setq vi (make-js2-var-init-node :pos kid-pos
+                                       :len (- end kid-pos)
+                                       :type decl-type))
+      (if destructuring
+          (progn
+            (if (and (null init) (not js2-in-for-init))
+                (js2-report-error "msg.destruct.assign.no.init"))
+            (js2-define-destruct-symbols destructuring
+                                         decl-type
+                                         'font-lock-variable-name-face)
+            (setf (js2-var-init-node-target vi) destructuring))
+        (setf (js2-var-init-node-target vi) name))
+      (setf (js2-var-init-node-initializer vi) init)
+      (js2-node-add-children vi name destructuring init)
+      (js2-block-node-push result vi)
+      (unless (js2-match-token js2-COMMA)
+        (setq continue nil)))
+    (setf (js2-node-len result) (- end pos))
+    result))
+
+(defun js2-parse-let (pos &optional stmt-p)
+  "Parse a let expression or statement.
+A let-expression is of the form `let (vars) expr'.
+A let-statement is of the form `let (vars) {statements}'.
+The third form of let is a variable declaration list, handled
+by `js2-parse-variables'."
+  (let ((pn (make-js2-let-node :pos pos))
+        beg vars body)
+    (if (js2-must-match js2-LP "msg.no.paren.after.let")
+        (setf (js2-let-node-lp pn) (- (js2-current-token-beg) pos)))
+    (js2-push-scope pn)
+    (unwind-protect
+        (progn
+          (setq vars (js2-parse-variables js2-LET (js2-current-token-beg)))
+          (if (js2-must-match js2-RP "msg.no.paren.let")
+              (setf (js2-let-node-rp pn) (- (js2-current-token-beg) pos)))
+          (if (and stmt-p (js2-match-token js2-LC))
+              ;; let statement
+              (progn
+                (setf beg (js2-current-token-beg)  ; position stmt at LC
+                      body (js2-parse-statements))
+                (js2-must-match js2-RC "msg.no.curly.let")
+                (setf (js2-node-len body) (- (js2-current-token-end) beg)
+                      (js2-node-len pn) (- (js2-current-token-end) pos)
+                      (js2-let-node-body pn) body
+                      (js2-node-type pn) js2-LET))
+            ;; let expression
+            (setf body (js2-parse-expr)
+                  (js2-node-len pn) (- (js2-node-end body) pos)
+                  (js2-let-node-body pn) body))
+          (setf (js2-let-node-vars pn) vars)
+          (js2-node-add-children pn vars body))
+      (js2-pop-scope))
+    pn))
+
+(defun js2-define-new-symbol (decl-type name node &optional scope)
+  (js2-scope-put-symbol (or scope js2-current-scope)
+                        name
+                        (make-js2-symbol decl-type name node)))
+
+(defun js2-define-symbol (decl-type name &optional node ignore-not-in-block)
+  "Define a symbol in the current scope.
+If NODE is non-nil, it is the AST node associated with the symbol."
+  (let* ((defining-scope (js2-get-defining-scope js2-current-scope name))
+         (symbol (if defining-scope
+                     (js2-scope-get-symbol defining-scope name)))
+         (sdt (if symbol (js2-symbol-decl-type symbol) -1))
+         (pos (if node (js2-node-abs-pos node)))
+         (len (if node (js2-node-len node))))
+    (cond
+     ((and symbol ; already defined in this block
+           (or (= sdt js2-LET)
+               (= sdt js2-CONST))
+           (eq defining-scope js2-current-scope))
+      (js2-report-error
+       (cond
+        ((= sdt js2-CONST) "msg.const.redecl")
+        ((= sdt js2-LET) "msg.let.redecl")
+        ((= sdt js2-VAR) "msg.var.redecl")
+        ((= sdt js2-FUNCTION) "msg.function.redecl")
+        (t "msg.parm.redecl"))
+       name pos len))
+     ((or (= decl-type js2-LET)
+          (= decl-type js2-CONST))
+      (if (and (= decl-type js2-LET)
+               (not ignore-not-in-block)
+               (or (= (js2-node-type js2-current-scope) js2-IF)
+                   (js2-loop-node-p js2-current-scope)))
+          (js2-report-error "msg.let.decl.not.in.block")
+        (js2-define-new-symbol decl-type name node)))
+     ((or (= decl-type js2-VAR)
+          (= decl-type js2-FUNCTION))
+      (if symbol
+          (if (and js2-strict-var-redeclaration-warning (= sdt js2-VAR))
+              (js2-add-strict-warning "msg.var.redecl" name)
+            (if (and js2-strict-var-hides-function-arg-warning (= sdt js2-LP))
+                (js2-add-strict-warning "msg.var.hides.arg" name)))
+        (js2-define-new-symbol decl-type name node
+                               js2-current-script-or-fn)))
+     ((= decl-type js2-LP)
+      (if symbol
+          ;; must be duplicate parameter. Second parameter hides the
+          ;; first, so go ahead and add the second pararameter
+          (js2-report-warning "msg.dup.parms" name))
+      (js2-define-new-symbol decl-type name node))
+     (t (js2-code-bug)))))
+
+(defun js2-parse-paren-expr-or-generator-comp ()
+  (let ((px-pos (js2-current-token-beg)))
+    (cond
+     ((and (>= js2-language-version 200)
+           (js2-match-token js2-FOR))
+      (js2-parse-generator-comp px-pos))
+     ((and (>= js2-language-version 200)
+           (js2-match-token js2-RP))
+      ;; Not valid expression syntax, but this is valid in an arrow
+      ;; function with no params: () => body.
+      (if (eq (js2-peek-token) js2-ARROW)
+          ;; Return whatever, it will hopefully be rewinded and
+          ;; reparsed when we reach the =>.
+          (make-js2-keyword-node :type js2-NULL)
+        (js2-report-error "msg.syntax")
+        (make-js2-error-node)))
+     (t
+      (let* ((js2-in-for-init nil)
+             (expr (js2-parse-expr))
+             (pn (make-js2-paren-node :pos px-pos
+                                      :expr expr)))
+        (js2-node-add-children pn (js2-paren-node-expr pn))
+        (js2-must-match js2-RP "msg.no.paren")
+        (setf (js2-node-len pn) (- (js2-current-token-end) px-pos))
+        pn)))))
+
+(defun js2-parse-expr (&optional oneshot)
+  (let* ((pn (js2-parse-assign-expr))
+         (pos (js2-node-pos pn))
+         left
+         right
+         op-pos)
+    (while (and (not oneshot)
+                (js2-match-token js2-COMMA))
+      (setq op-pos (- (js2-current-token-beg) pos))  ; relative
+      (setq right (js2-parse-assign-expr)
+            left pn
+            pn (make-js2-infix-node :type js2-COMMA
+                                    :pos pos
+                                    :len (- js2-ts-cursor pos)
+                                    :op-pos op-pos
+                                    :left left
+                                    :right right))
+      (js2-node-add-children pn left right))
+    pn))
+
+(defun js2-parse-assign-expr ()
+  (let ((tt (js2-get-token))
+        (pos (js2-current-token-beg))
+        pn left right op-pos
+        ts-state recorded-identifiers parsed-errors
+        async-p)
+    (if (= tt js2-YIELD)
+        (js2-parse-return-or-yield tt t)
+      ;; TODO(mooz): Bit confusing.
+      ;; If we meet `async` token and it's not part of `async
+      ;; function`, then this `async` is for a succeeding async arrow
+      ;; function.
+      ;; Since arrow function parsing doesn't rely on neither
+      ;; `js2-parse-function-stmt' nor `js2-parse-function-expr' that
+      ;; interpret `async` token, we trash `async` and just remember
+      ;; we met `async` keyword to `async-p'.
+      (when (js2-match-async-arrow-function)
+        (setq async-p t))
+      ;; Save the tokenizer state in case we find an arrow function
+      ;; and have to rewind.
+      (setq ts-state (make-js2-ts-state)
+            recorded-identifiers js2-recorded-identifiers
+            parsed-errors js2-parsed-errors)
+      ;; not yield - parse assignment expression
+      (setq pn (js2-parse-cond-expr)
+            tt (js2-get-token))
+      (cond
+       ((and (<= js2-first-assign tt)
+             (<= tt js2-last-assign))
+        ;; tt express assignment (=, |=, ^=, ..., %=)
+        (setq op-pos (- (js2-current-token-beg) pos)  ; relative
+              left pn)
+        ;; The assigned node could be a js2-prop-get-node (foo.bar = 0), we only
+        ;; care about assignment to strict variable names.
+        (when (js2-name-node-p left)
+          (js2-check-strict-identifier left))
+        (setq right (js2-parse-assign-expr)
+              pn (make-js2-assign-node :type tt
+                                       :pos pos
+                                       :len (- (js2-node-end right) pos)
+                                       :op-pos op-pos
+                                       :left left
+                                       :right right))
+        (when js2-parse-ide-mode
+          (js2-highlight-assign-targets pn left right)
+          (js2-record-imenu-functions right left))
+        ;; do this last so ide checks above can use absolute positions
+        (js2-node-add-children pn left right))
+       ((and (>= js2-language-version 200)
+             (or
+              (= tt js2-ARROW)
+              (and async-p
+                   (= (js2-peek-token) js2-ARROW))))
+        (js2-ts-seek ts-state)
+        (when async-p
+          (js2-record-face 'font-lock-keyword-face)
+          (js2-get-token))
+        (setq js2-recorded-identifiers recorded-identifiers
+              js2-parsed-errors parsed-errors)
+        (setq pn (js2-parse-function 'FUNCTION_ARROW (js2-current-token-beg) nil async-p)))
+       (t
+        (js2-unget-token)))
+      pn)))
+
+(defun js2-parse-cond-expr ()
+  (let ((pos (js2-current-token-beg))
+        (pn (js2-parse-or-expr))
+        test-expr
+        if-true
+        if-false
+        q-pos
+        c-pos)
+    (when (js2-match-token js2-HOOK)
+      (setq q-pos (- (js2-current-token-beg) pos)
+            if-true (let (js2-in-for-init) (js2-parse-assign-expr)))
+      (js2-must-match js2-COLON "msg.no.colon.cond")
+      (setq c-pos (- (js2-current-token-beg) pos)
+            if-false (js2-parse-assign-expr)
+            test-expr pn
+            pn (make-js2-cond-node :pos pos
+                                   :len (- (js2-node-end if-false) pos)
+                                   :test-expr test-expr
+                                   :true-expr if-true
+                                   :false-expr if-false
+                                   :q-pos q-pos
+                                   :c-pos c-pos))
+      (js2-node-add-children pn test-expr if-true if-false))
+    pn))
+
+(defun js2-make-binary (type left parser &optional no-get)
+  "Helper for constructing a binary-operator AST node.
+LEFT is the left-side-expression, already parsed, and the
+binary operator should have just been matched.
+PARSER is a function to call to parse the right operand,
+or a `js2-node' struct if it has already been parsed.
+FIXME: The latter option is unused?"
+  (let* ((pos (js2-node-pos left))
+         (op-pos (- (js2-current-token-beg) pos))
+         (right (if (js2-node-p parser)
+                    parser
+                  (unless no-get (js2-get-token))
+                  (funcall parser)))
+         (pn (make-js2-infix-node :type type
+                                  :pos pos
+                                  :len (- (js2-node-end right) pos)
+                                  :op-pos op-pos
+                                  :left left
+                                  :right right)))
+    (js2-node-add-children pn left right)
+    pn))
+
+(defun js2-parse-or-expr ()
+  (let ((pn (js2-parse-and-expr)))
+    (when (js2-match-token js2-OR)
+      (setq pn (js2-make-binary js2-OR
+                                pn
+                                'js2-parse-or-expr)))
+    pn))
+
+(defun js2-parse-and-expr ()
+  (let ((pn (js2-parse-bit-or-expr)))
+    (when (js2-match-token js2-AND)
+      (setq pn (js2-make-binary js2-AND
+                                pn
+                                'js2-parse-and-expr)))
+    pn))
+
+(defun js2-parse-bit-or-expr ()
+  (let ((pn (js2-parse-bit-xor-expr)))
+    (while (js2-match-token js2-BITOR)
+      (setq pn (js2-make-binary js2-BITOR
+                                pn
+                                'js2-parse-bit-xor-expr)))
+    pn))
+
+(defun js2-parse-bit-xor-expr ()
+  (let ((pn (js2-parse-bit-and-expr)))
+    (while (js2-match-token js2-BITXOR)
+      (setq pn (js2-make-binary js2-BITXOR
+                                pn
+                                'js2-parse-bit-and-expr)))
+    pn))
+
+(defun js2-parse-bit-and-expr ()
+  (let ((pn (js2-parse-eq-expr)))
+    (while (js2-match-token js2-BITAND)
+      (setq pn (js2-make-binary js2-BITAND
+                                pn
+                                'js2-parse-eq-expr)))
+    pn))
+
+(defconst js2-parse-eq-ops
+  (list js2-EQ js2-NE js2-SHEQ js2-SHNE))
+
+(defun js2-parse-eq-expr ()
+  (let ((pn (js2-parse-rel-expr))
+        tt)
+    (while (memq (setq tt (js2-get-token)) js2-parse-eq-ops)
+      (setq pn (js2-make-binary tt
+                                pn
+                                'js2-parse-rel-expr)))
+    (js2-unget-token)
+    pn))
+
+(defconst js2-parse-rel-ops
+  (list js2-IN js2-INSTANCEOF js2-LE js2-LT js2-GE js2-GT))
+
+(defun js2-parse-rel-expr ()
+  (let ((pn (js2-parse-shift-expr))
+        (continue t)
+        tt)
+    (while continue
+      (setq tt (js2-get-token))
+      (cond
+       ((and js2-in-for-init (= tt js2-IN))
+        (js2-unget-token)
+        (setq continue nil))
+       ((memq tt js2-parse-rel-ops)
+        (setq pn (js2-make-binary tt pn 'js2-parse-shift-expr)))
+       (t
+        (js2-unget-token)
+        (setq continue nil))))
+    pn))
+
+(defconst js2-parse-shift-ops
+  (list js2-LSH js2-URSH js2-RSH))
+
+(defun js2-parse-shift-expr ()
+  (let ((pn (js2-parse-add-expr))
+        tt
+        (continue t))
+    (while continue
+      (setq tt (js2-get-token))
+      (if (memq tt js2-parse-shift-ops)
+          (setq pn (js2-make-binary tt pn 'js2-parse-add-expr))
+        (js2-unget-token)
+        (setq continue nil)))
+    pn))
+
+(defun js2-parse-add-expr ()
+  (let ((pn (js2-parse-mul-expr))
+        tt
+        (continue t))
+    (while continue
+      (setq tt (js2-get-token))
+      (if (or (= tt js2-ADD) (= tt js2-SUB))
+          (setq pn (js2-make-binary tt pn 'js2-parse-mul-expr))
+        (js2-unget-token)
+        (setq continue nil)))
+    pn))
+
+(defconst js2-parse-mul-ops
+  (list js2-MUL js2-DIV js2-MOD))
+
+(defun js2-parse-mul-expr ()
+  (let ((pn (js2-parse-expon-expr))
+        tt
+        (continue t))
+    (while continue
+      (setq tt (js2-get-token))
+      (if (memq tt js2-parse-mul-ops)
+          (setq pn (js2-make-binary tt pn 'js2-parse-expon-expr))
+        (js2-unget-token)
+        (setq continue nil)))
+    pn))
+
+(defun js2-parse-expon-expr ()
+  (let ((pn (js2-parse-unary-expr)))
+    (when (>= js2-language-version 200)
+      (while (js2-match-token js2-EXPON)
+        (when (and (js2-unary-node-p pn)
+                   (not (memq (js2-node-type pn) '(js2-INC js2-DEC))))
+          (js2-report-error "msg.syntax" nil
+                            (js2-node-abs-pos pn) (js2-node-len pn)))
+        ;; Make it right-associative.
+        (setq pn (js2-make-binary js2-EXPON pn 'js2-parse-expon-expr))))
+    pn))
+
+(defun js2-make-unary (beg type parser &rest args)
+  "Make a unary node starting at BEG of type TYPE.
+If BEG is nil, `(js2-current-token-beg)' is used for the node
+start position.  PARSER is either a node (for postfix operators)
+or a function to call to parse the operand (for prefix
+operators)."
+  (let* ((pos (or beg (js2-current-token-beg)))
+         (postfix (js2-node-p parser))
+         (expr (if postfix
+                   parser
+                 (apply parser args)))
+         end
+         pn)
+    (if postfix  ; e.g. i++
+        (setq pos (js2-node-pos expr)
+              end (js2-current-token-end))
+      (setq end (js2-node-end expr)))
+    (setq pn (make-js2-unary-node :type type
+                                  :pos pos
+                                  :len (- end pos)
+                                  :operand expr))
+    (js2-node-add-children pn expr)
+    pn))
+
+(defconst js2-incrementable-node-types
+  (list js2-NAME js2-GETPROP js2-GETELEM js2-GET_REF js2-CALL)
+  "Node types that can be the operand of a ++ or -- operator.")
+
+(defun js2-check-bad-inc-dec (tt beg end unary)
+  (unless (memq (js2-node-type (js2-unary-node-operand unary))
+                js2-incrementable-node-types)
+    (js2-report-error (if (= tt js2-INC)
+                          "msg.bad.incr"
+                        "msg.bad.decr")
+                      nil beg (- end beg))))
+
+(defun js2-parse-unary-expr ()
+  (let ((tt (js2-current-token-type))
+        (beg (js2-current-token-beg)))
+    (cond
+     ((or (= tt js2-VOID)
+          (= tt js2-NOT)
+          (= tt js2-BITNOT)
+          (= tt js2-TYPEOF))
+      (js2-get-token)
+      (js2-make-unary beg tt 'js2-parse-unary-expr))
+     ((= tt js2-ADD)
+      (js2-get-token)
+      ;; Convert to special POS token in decompiler and parse tree
+      (js2-make-unary beg js2-POS 'js2-parse-unary-expr))
+     ((= tt js2-SUB)
+      (js2-get-token)
+      ;; Convert to special NEG token in decompiler and parse tree
+      (js2-make-unary beg js2-NEG 'js2-parse-unary-expr))
+     ((or (= tt js2-INC)
+          (= tt js2-DEC))
+      (js2-get-token)
+      (let ((beg2 (js2-current-token-beg))
+            (end (js2-current-token-end))
+            (expr (js2-make-unary beg tt 'js2-parse-member-expr t)))
+        (js2-check-bad-inc-dec tt beg2 end expr)
+        expr))
+     ((= tt js2-DELPROP)
+      (js2-get-token)
+      (js2-make-unary beg js2-DELPROP 'js2-parse-unary-expr))
+     ((js2-parse-await-maybe tt))
+     ((= tt js2-ERROR)
+      (js2-get-token)
+      (make-js2-error-node))  ; try to continue
+     ((and (= tt js2-LT)
+           js2-compiler-xml-available)
+      ;; XML stream encountered in expression.
+      (js2-parse-member-expr-tail t (js2-parse-xml-initializer)))
+     (t
+      (let ((pn (js2-parse-member-expr t))
+            ;; Don't look across a newline boundary for a postfix incop.
+            (tt (js2-peek-token-or-eol))
+            expr)
+        (when (or (= tt js2-INC) (= tt js2-DEC))
+          (js2-get-token)
+          (setf expr pn
+                pn (js2-make-unary (js2-node-pos expr) tt expr))
+          (js2-node-set-prop pn 'postfix t)
+          (js2-check-bad-inc-dec tt (js2-current-token-beg) (js2-current-token-end) pn))
+        pn)))))
+
+(defun js2-parse-xml-initializer ()
+  "Parse an E4X XML initializer.
+I'm parsing it the way Rhino parses it, but without the tree-rewriting.
+Then I'll postprocess the result, depending on whether we're in IDE
+mode or codegen mode, and generate the appropriate rewritten AST.
+IDE mode uses a rich AST that models the XML structure.  Codegen mode
+just concatenates everything and makes a new XML or XMLList out of it."
+  (let ((tt (js2-get-first-xml-token))
+        pn-xml pn expr kids expr-pos
+        (continue t)
+        (first-token t))
+    (when (not (or (= tt js2-XML) (= tt js2-XMLEND)))
+      (js2-report-error "msg.syntax"))
+    (setq pn-xml (make-js2-xml-node))
+    (while continue
+      (if first-token
+          (setq first-token nil)
+        (setq tt (js2-get-next-xml-token)))
+      (cond
+       ;; js2-XML means we found a {expr} in the XML stream.
+       ;; The token string is the XML up to the left-curly.
+       ((= tt js2-XML)
+        (push (make-js2-string-node :pos (js2-current-token-beg)
+                                    :len (- js2-ts-cursor (js2-current-token-beg)))
+              kids)
+        (js2-must-match js2-LC "msg.syntax")
+        (setq expr-pos js2-ts-cursor
+              expr (if (eq (js2-peek-token) js2-RC)
+                       (make-js2-empty-expr-node :pos expr-pos)
+                     (js2-parse-expr)))
+        (js2-must-match js2-RC "msg.syntax")
+        (setq pn (make-js2-xml-js-expr-node :pos (js2-node-pos expr)
+                                            :len (js2-node-len expr)
+                                            :expr expr))
+        (js2-node-add-children pn expr)
+        (push pn kids))
+       ;; a js2-XMLEND token means we hit the final close-tag.
+       ((= tt js2-XMLEND)
+        (push (make-js2-string-node :pos (js2-current-token-beg)
+                                    :len (- js2-ts-cursor (js2-current-token-beg)))
+              kids)
+        (dolist (kid (nreverse kids))
+          (js2-block-node-push pn-xml kid))
+        (setf (js2-node-len pn-xml) (- js2-ts-cursor
+                                       (js2-node-pos pn-xml))
+              continue nil))
+       (t
+        (js2-report-error "msg.syntax")
+        (setq continue nil))))
+    pn-xml))
+
+
+(defun js2-parse-argument-list ()
+  "Parse an argument list and return it as a Lisp list of nodes.
+Returns the list in reverse order.  Consumes the right-paren token."
+  (let (result)
+    (unless (js2-match-token js2-RP)
+      (cl-loop do
+               (let ((tt (js2-get-token))
+                     (beg (js2-current-token-beg)))
+                 (if (and (= tt js2-TRIPLEDOT)
+                          (>= js2-language-version 200))
+                     (push (js2-make-unary beg tt 'js2-parse-assign-expr) result)
+                   (js2-unget-token)
+                   (push (js2-parse-assign-expr) result)))
+               while
+               (and (js2-match-token js2-COMMA)
+                    (or (< js2-language-version 200)
+                        (not (= js2-RP (js2-peek-token))))))
+      (js2-must-match js2-RP "msg.no.paren.arg")
+      result)))
+
+(defun js2-parse-member-expr (&optional allow-call-syntax)
+  (let ((tt (js2-current-token-type))
+        pn pos target args beg end init)
+    (if (/= tt js2-NEW)
+        (setq pn (js2-parse-primary-expr))
+      ;; parse a 'new' expression
+      (js2-get-token)
+      (setq pos (js2-current-token-beg)
+            beg pos
+            target (js2-parse-member-expr)
+            end (js2-node-end target)
+            pn (make-js2-new-node :pos pos
+                                  :target target
+                                  :len (- end pos)))
+      (js2-highlight-function-call (js2-current-token))
+      (js2-node-add-children pn target)
+      (when (js2-match-token js2-LP)
+        ;; Add the arguments to pn, if any are supplied.
+        (setf beg pos  ; start of "new" keyword
+              pos (js2-current-token-beg)
+              args (nreverse (js2-parse-argument-list))
+              (js2-new-node-args pn) args
+              end (js2-current-token-end)
+              (js2-new-node-lp pn) (- pos beg)
+              (js2-new-node-rp pn) (- end 1 beg))
+        (apply #'js2-node-add-children pn args))
+      (when (and js2-allow-rhino-new-expr-initializer
+                 (js2-match-token js2-LC))
+        (setf init (js2-parse-object-literal)
+              end (js2-node-end init)
+              (js2-new-node-initializer pn) init)
+        (js2-node-add-children pn init))
+        (setf (js2-node-len pn) (- end beg)))  ; end outer if
+    (js2-parse-member-expr-tail allow-call-syntax pn)))
+
+(defun js2-parse-member-expr-tail (allow-call-syntax pn)
+  "Parse a chain of property/array accesses or function calls.
+Includes parsing for E4X operators like `..' and `.@'.
+If ALLOW-CALL-SYNTAX is nil, stops when we encounter a left-paren.
+Returns an expression tree that includes PN, the parent node."
+  (let (tt
+        (continue t))
+    (while continue
+      (setq tt (js2-get-token))
+      (cond
+       ((or (= tt js2-DOT) (= tt js2-DOTDOT))
+        (setq pn (js2-parse-property-access tt pn)))
+       ((= tt js2-DOTQUERY)
+        (setq pn (js2-parse-dot-query pn)))
+       ((= tt js2-LB)
+        (setq pn (js2-parse-element-get pn)))
+       ((= tt js2-LP)
+        (js2-unget-token)
+        (if allow-call-syntax
+            (setq pn (js2-parse-function-call pn))
+          (setq continue nil)))
+       ((= tt js2-TEMPLATE_HEAD)
+        (setq pn (js2-parse-tagged-template pn (js2-parse-template-literal))))
+       ((= tt js2-NO_SUBS_TEMPLATE)
+        (setq pn (js2-parse-tagged-template pn (make-js2-string-node :type tt))))
+       (t
+        (js2-unget-token)
+        (setq continue nil)))
+      (if (>= js2-highlight-level 2)
+          (js2-parse-highlight-member-expr-node pn)))
+    pn))
+
+(defun js2-parse-tagged-template (tag-node tpl-node)
+  "Parse tagged template expression."
+  (let* ((pos (js2-node-pos tag-node))
+         (pn (make-js2-tagged-template-node :pos pos
+                                            :len (- (js2-current-token-end) pos)
+                                            :tag tag-node
+                                            :template tpl-node)))
+    (js2-node-add-children pn tag-node tpl-node)
+    pn))
+
+(defun js2-parse-dot-query (pn)
+  "Parse a dot-query expression, e.g. foo.bar.(@name == 2)
+Last token parsed must be `js2-DOTQUERY'."
+  (let ((pos (js2-node-pos pn))
+        op-pos expr end)
+    (js2-must-have-xml)
+    (js2-set-requires-activation)
+    (setq op-pos (js2-current-token-beg)
+          expr (js2-parse-expr)
+          end (js2-node-end expr)
+          pn (make-js2-xml-dot-query-node :left pn
+                                          :pos pos
+                                          :op-pos op-pos
+                                          :right expr))
+    (js2-node-add-children pn
+                           (js2-xml-dot-query-node-left pn)
+                           (js2-xml-dot-query-node-right pn))
+    (if (js2-must-match js2-RP "msg.no.paren")
+        (setf (js2-xml-dot-query-node-rp pn) (js2-current-token-beg)
+              end (js2-current-token-end)))
+    (setf (js2-node-len pn) (- end pos))
+    pn))
+
+(defun js2-parse-element-get (pn)
+  "Parse an element-get expression, e.g. foo[bar].
+Last token parsed must be `js2-RB'."
+  (let ((lb (js2-current-token-beg))
+        (pos (js2-node-pos pn))
+        rb expr)
+    (setq expr (js2-parse-expr))
+    (if (js2-must-match js2-RB "msg.no.bracket.index")
+        (setq rb (js2-current-token-beg)))
+    (setq pn (make-js2-elem-get-node :target pn
+                                     :pos pos
+                                     :element expr
+                                     :lb (js2-relpos lb pos)
+                                     :rb (js2-relpos rb pos)
+                                     :len (- (js2-current-token-end) pos)))
+    (js2-node-add-children pn
+                           (js2-elem-get-node-target pn)
+                           (js2-elem-get-node-element pn))
+    pn))
+
+(defun js2-highlight-function-call (token)
+  (when (eq (js2-token-type token) js2-NAME)
+    (js2-record-face 'js2-function-call token)))
+
+(defun js2-parse-function-call (pn)
+  (js2-highlight-function-call (js2-current-token))
+  (js2-get-token)
+  (let (args
+        (pos (js2-node-pos pn)))
+    (setq pn (make-js2-call-node :pos pos
+                                 :target pn
+                                 :lp (- (js2-current-token-beg) pos)))
+    (js2-node-add-children pn (js2-call-node-target pn))
+    ;; Add the arguments to pn, if any are supplied.
+    (setf args (nreverse (js2-parse-argument-list))
+          (js2-call-node-rp pn) (- (js2-current-token-beg) pos)
+          (js2-call-node-args pn) args)
+    (apply #'js2-node-add-children pn args)
+    (setf (js2-node-len pn) (- js2-ts-cursor pos))
+    pn))
+
+(defun js2-parse-property-access (tt pn)
+  "Parse a property access, XML descendants access, or XML attr access."
+  (let ((member-type-flags 0)
+        (dot-pos (js2-current-token-beg))
+        (dot-len (if (= tt js2-DOTDOT) 2 1))
+        name
+        ref  ; right side of . or .. operator
+        result)
+    (when (= tt js2-DOTDOT)
+      (js2-must-have-xml)
+      (setq member-type-flags js2-descendants-flag))
+    (if (not js2-compiler-xml-available)
+        (progn
+          (js2-must-match-prop-name "msg.no.name.after.dot")
+          (setq name (js2-create-name-node t js2-GETPROP)
+                result (make-js2-prop-get-node :left pn
+                                               :pos (js2-current-token-beg)
+                                               :right name
+                                               :len (js2-current-token-len)))
+          (js2-node-add-children result pn name)
+          result)
+      ;; otherwise look for XML operators
+      (setf result (if (= tt js2-DOT)
+                       (make-js2-prop-get-node)
+                     (make-js2-infix-node :type js2-DOTDOT))
+            (js2-node-pos result) (js2-node-pos pn)
+            (js2-infix-node-op-pos result) dot-pos
+            (js2-infix-node-left result) pn  ; do this after setting position
+            tt (js2-get-prop-name-token))
+      (cond
+       ;; handles: name, ns::name, ns::*, ns::[expr]
+       ((= tt js2-NAME)
+        (setq ref (js2-parse-property-name -1 nil member-type-flags)))
+       ;; handles: *, *::name, *::*, *::[expr]
+       ((= tt js2-MUL)
+        (setq ref (js2-parse-property-name nil "*" member-type-flags)))
+       ;; handles: '@attr', '@ns::attr', '@ns::*', '@ns::[expr]', etc.
+       ((= tt js2-XMLATTR)
+        (setq result (js2-parse-attribute-access)))
+       (t
+        (js2-report-error "msg.no.name.after.dot" nil dot-pos dot-len)))
+      (if ref
+          (setf (js2-node-len result) (- (js2-node-end ref)
+                                         (js2-node-pos result))
+                (js2-infix-node-right result) ref))
+      (if (js2-infix-node-p result)
+          (js2-node-add-children result
+                                 (js2-infix-node-left result)
+                                 (js2-infix-node-right result)))
+      result)))
+
+(defun js2-parse-attribute-access ()
+  "Parse an E4X XML attribute expression.
+This includes expressions of the forms:
+
+  @attr      @ns::attr     @ns::*
+  @*         @*::attr      @*::*
+  @[expr]    @*::[expr]    @ns::[expr]
+
+Called if we peeked an '@' token."
+  (let ((tt (js2-get-prop-name-token))
+        (at-pos (js2-current-token-beg)))
+    (cond
+     ;; handles: @name, @ns::name, @ns::*, @ns::[expr]
+     ((= tt js2-NAME)
+      (js2-parse-property-name at-pos nil 0))
+     ;; handles: @*, @*::name, @*::*, @*::[expr]
+     ((= tt js2-MUL)
+      (js2-parse-property-name (js2-current-token-beg) "*" 0))
+     ;; handles @[expr]
+     ((= tt js2-LB)
+      (js2-parse-xml-elem-ref at-pos))
+     (t
+      (js2-report-error "msg.no.name.after.xmlAttr")
+      ;; Avoid cascaded errors that happen if we make an error node here.
+      (js2-parse-property-name (js2-current-token-beg) "" 0)))))
+
+(defun js2-parse-property-name (at-pos s member-type-flags)
+  "Check if :: follows name in which case it becomes qualified name.
+
+AT-POS is a natural number if we just read an '@' token, else nil.
+S is the name or string that was matched:  an identifier, 'throw' or '*'.
+MEMBER-TYPE-FLAGS is a bit set tracking whether we're a '.' or '..' child.
+
+Returns a `js2-xml-ref-node' if it's an attribute access, a child of a '..'
+operator, or the name is followed by ::.  For a plain name, returns a
+`js2-name-node'.  Returns a `js2-error-node' for malformed XML expressions."
+  (let ((pos (or at-pos (js2-current-token-beg)))
+        colon-pos
+        (name (js2-create-name-node t (js2-current-token-type) s))
+        ns tt pn)
+    (catch 'return
+      (when (js2-match-token js2-COLONCOLON)
+        (setq ns name
+              colon-pos (js2-current-token-beg)
+              tt (js2-get-prop-name-token))
+        (cond
+         ;; handles name::name
+         ((= tt js2-NAME)
+          (setq name (js2-create-name-node)))
+         ;; handles name::*
+         ((= tt js2-MUL)
+          (setq name (js2-create-name-node nil nil "*")))
+         ;; handles name::[expr]
+         ((= tt js2-LB)
+          (throw 'return (js2-parse-xml-elem-ref at-pos ns colon-pos)))
+         (t
+          (js2-report-error "msg.no.name.after.coloncolon"))))
+      (if (and (null ns) (zerop member-type-flags))
+          name
+        (prog1
+            (setq pn
+                  (make-js2-xml-prop-ref-node :pos pos
+                                              :len (- (js2-node-end name) pos)
+                                              :at-pos at-pos
+                                              :colon-pos colon-pos
+                                              :propname name))
+          (js2-node-add-children pn name))))))
+
+(defun js2-parse-xml-elem-ref (at-pos &optional namespace colon-pos)
+  "Parse the [expr] portion of an xml element reference.
+For instance, @[expr], @*::[expr], or ns::[expr]."
+  (let* ((lb (js2-current-token-beg))
+         (pos (or at-pos lb))
+         rb
+         (expr (js2-parse-expr))
+         (end (js2-node-end expr))
+         pn)
+    (if (js2-must-match js2-RB "msg.no.bracket.index")
+        (setq rb (js2-current-token-beg)
+              end (js2-current-token-end)))
+    (prog1
+        (setq pn
+              (make-js2-xml-elem-ref-node :pos pos
+                                          :len (- end pos)
+                                          :namespace namespace
+                                          :colon-pos colon-pos
+                                          :at-pos at-pos
+                                          :expr expr
+                                          :lb (js2-relpos lb pos)
+                                          :rb (js2-relpos rb pos)))
+      (js2-node-add-children pn namespace expr))))
+
+(defun js2-parse-destruct-primary-expr ()
+  (let ((js2-is-in-destructuring t))
+    (js2-parse-primary-expr)))
+
+(defun js2-parse-primary-expr ()
+  "Parse a literal (leaf) expression of some sort.
+Includes complex literals such as functions, object-literals,
+array-literals, array comprehensions and regular expressions."
+  (let (tt node)
+    (setq tt (js2-current-token-type))
+    (cond
+     ((= tt js2-CLASS)
+      (js2-parse-class-expr))
+     ((= tt js2-FUNCTION)
+      (js2-parse-function-expr))
+     ((js2-match-async-function)
+      (js2-parse-function-expr t))
+     ((= tt js2-LB)
+      (js2-parse-array-comp-or-literal))
+     ((= tt js2-LC)
+      (js2-parse-object-literal))
+     ((= tt js2-LET)
+      (js2-parse-let (js2-current-token-beg)))
+     ((= tt js2-LP)
+      (js2-parse-paren-expr-or-generator-comp))
+     ((= tt js2-XMLATTR)
+      (js2-must-have-xml)
+      (js2-parse-attribute-access))
+     ((= tt js2-NAME)
+      (js2-parse-name tt))
+     ((= tt js2-NUMBER)
+      (setq node (make-js2-number-node))
+      (when (and js2-in-use-strict-directive
+                 (= (js2-number-node-num-base node) 8)
+                 (js2-number-node-legacy-octal-p node))
+        (js2-report-error "msg.no.octal.strict"))
+      node)
+     ((or (= tt js2-STRING) (= tt js2-NO_SUBS_TEMPLATE))
+      (make-js2-string-node :type tt))
+     ((= tt js2-TEMPLATE_HEAD)
+      (js2-parse-template-literal))
+     ((or (= tt js2-DIV) (= tt js2-ASSIGN_DIV))
+      ;; Got / or /= which in this context means a regexp literal
+      (let* ((px-pos (js2-current-token-beg))
+             (flags (js2-read-regexp tt px-pos))
+             (end (js2-current-token-end)))
+        (prog1
+            (make-js2-regexp-node :pos px-pos
+                                  :len (- end px-pos)
+                                  :value (js2-current-token-string)
+                                  :flags flags)
+          (js2-set-face px-pos end 'font-lock-string-face 'record))))
+     ((or (= tt js2-NULL)
+          (= tt js2-THIS)
+          (= tt js2-SUPER)
+          (= tt js2-FALSE)
+          (= tt js2-TRUE))
+      (make-js2-keyword-node :type tt))
+     ((= tt js2-TRIPLEDOT)
+      ;; Likewise, only valid in an arrow function with a rest param.
+      (if (and (js2-match-token js2-NAME)
+               (js2-match-token js2-RP)
+               (eq (js2-peek-token) js2-ARROW))
+          (progn
+            (js2-unget-token)  ; Put back the right paren.
+            ;; See the previous case.
+            (make-js2-keyword-node :type js2-NULL))
+        (js2-report-error "msg.syntax")
+        (make-js2-error-node)))
+     ((= tt js2-RESERVED)
+      (js2-report-error "msg.reserved.id")
+      (make-js2-name-node))
+     ((= tt js2-ERROR)
+      ;; the scanner or one of its subroutines reported the error.
+      (make-js2-error-node))
+     ((= tt js2-EOF)
+      (let* ((px-pos (point-at-bol))
+             (len (- js2-ts-cursor px-pos)))
+        (js2-report-error "msg.unexpected.eof" nil px-pos len))
+      (make-js2-error-node :pos (1- js2-ts-cursor)))
+     (t
+      (js2-report-error "msg.syntax")
+      (make-js2-error-node)))))
+
+(defun js2-parse-template-literal ()
+  (let ((beg (js2-current-token-beg))
+        (kids (list (make-js2-string-node :type js2-TEMPLATE_HEAD)))
+        (tt js2-TEMPLATE_HEAD))
+    (while (eq tt js2-TEMPLATE_HEAD)
+      (push (js2-parse-expr) kids)
+      (js2-must-match js2-RC "msg.syntax")
+      (setq tt (js2-get-token 'TEMPLATE_TAIL))
+      (push (make-js2-string-node :type tt) kids))
+    (setq kids (nreverse kids))
+    (let ((tpl (make-js2-template-node :pos beg
+                                       :len (- (js2-current-token-end) beg)
+                                       :kids kids)))
+      (apply #'js2-node-add-children tpl kids)
+      tpl)))
+
+(defun js2-parse-name (_tt)
+  (let ((name (js2-current-token-string))
+        node)
+    (setq node (if js2-compiler-xml-available
+                   (js2-parse-property-name nil name 0)
+                 (js2-create-name-node 'check-activation nil name)))
+    (if (and js2-highlight-external-variables
+             ;; FIXME: What's TRT for `js2-xml-ref-node'?
+             (js2-name-node-p node))
+        (js2-record-name-node node))
+    node))
+
+(defun js2-parse-warn-trailing-comma (msg pos elems comma-pos)
+  (js2-add-strict-warning
+   msg nil
+   ;; back up from comma to beginning of line or array/objlit
+   (max (if elems
+            (js2-node-pos (car elems))
+          pos)
+        (save-excursion
+          (goto-char comma-pos)
+          (back-to-indentation)
+          (point)))
+   comma-pos))
+
+(defun js2-parse-array-comp-or-literal ()
+  (let ((pos (js2-current-token-beg)))
+    (if (and (>= js2-language-version 200)
+             (js2-match-token js2-FOR))
+        (js2-parse-array-comp pos)
+      (js2-parse-array-literal pos))))
+
+(defun js2-parse-array-literal (pos)
+  (let ((after-lb-or-comma t)
+        after-comma tt elems pn was-rest
+        (continue t))
+    (unless js2-is-in-destructuring
+      (js2-push-scope (make-js2-scope))) ; for the legacy array comp
+    (while continue
+      (setq tt (js2-get-token))
+      (cond
+       ;; end of array
+       ((or (= tt js2-RB)
+            (= tt js2-EOF))  ; prevent infinite loop
+        (if (= tt js2-EOF)
+            (js2-report-error "msg.no.bracket.arg" nil pos))
+        (when (and after-comma (< js2-language-version 170))
+          (js2-parse-warn-trailing-comma "msg.array.trailing.comma"
+                                         pos (remove nil elems) after-comma))
+        (setq continue nil
+              pn (make-js2-array-node :pos pos
+                                      :len (- js2-ts-cursor pos)
+                                      :elems (nreverse elems)))
+        (apply #'js2-node-add-children pn (js2-array-node-elems pn)))
+       ;; anything after rest element (...foo)
+       (was-rest
+        (js2-report-error "msg.param.after.rest"))
+       ;; comma
+       ((= tt js2-COMMA)
+        (setq after-comma (js2-current-token-end))
+        (if (not after-lb-or-comma)
+            (setq after-lb-or-comma t)
+          (push nil elems)))
+       ;; array comp
+       ((and (>= js2-language-version 170)
+             (not js2-is-in-destructuring)
+             (= tt js2-FOR)          ; check for array comprehension
+             (not after-lb-or-comma) ; "for" can't follow a comma
+             elems                   ; must have at least 1 element
+             (not (cdr elems)))      ; but no 2nd element
+        (js2-unget-token)
+        (setf continue nil
+              pn (js2-parse-legacy-array-comp (car elems) pos)))
+       ;; another element
+       (t
+        (unless after-lb-or-comma
+          (js2-report-error "msg.no.bracket.arg"))
+        (if (and (= tt js2-TRIPLEDOT)
+                 (>= js2-language-version 200))
+            ;; rest/spread operator
+            (progn
+              (push (js2-make-unary nil tt 'js2-parse-assign-expr)
+                    elems)
+              (if js2-is-in-destructuring
+                  (setq was-rest t)))
+          (js2-unget-token)
+          (push (js2-parse-assign-expr) elems))
+        (setq after-lb-or-comma nil
+              after-comma nil))))
+    (unless js2-is-in-destructuring
+      (js2-pop-scope))
+    pn))
+
+(defun js2-parse-legacy-array-comp (expr pos)
+  "Parse a legacy array comprehension (JavaScript 1.7).
+EXPR is the first expression after the opening left-bracket.
+POS is the beginning of the LB token preceding EXPR.
+We should have just parsed the 'for' keyword before calling this function."
+  (let ((current-scope js2-current-scope)
+        loops first filter result)
+    (unwind-protect
+        (progn
+          (while (js2-match-token js2-FOR)
+            (let ((loop (make-js2-comp-loop-node)))
+              (js2-push-scope loop)
+              (push loop loops)
+              (js2-parse-comp-loop loop)))
+          ;; First loop takes expr scope's parent.
+          (setf (js2-scope-parent-scope (setq first (car (last loops))))
+                (js2-scope-parent-scope current-scope))
+          ;; Set expr scope's parent to the last loop.
+          (setf (js2-scope-parent-scope current-scope) (car loops))
+          (if (/= (js2-get-token) js2-IF)
+              (js2-unget-token)
+            (setq filter (js2-parse-condition))))
+      (dotimes (_ (1- (length loops)))
+        (js2-pop-scope)))
+    (js2-must-match js2-RB "msg.no.bracket.arg" pos)
+    (setq result (make-js2-comp-node :pos pos
+                                     :len (- js2-ts-cursor pos)
+                                     :result expr
+                                     :loops (nreverse loops)
+                                     :filters (and filter (list (car filter)))
+                                     :form 'LEGACY_ARRAY))
+    ;; Set comp loop's parent to the last loop.
+    ;; TODO: Get rid of the bogus expr scope.
+    (setf (js2-scope-parent-scope result) first)
+    (apply #'js2-node-add-children result expr (car filter)
+           (js2-comp-node-loops result))
+    result))
+
+(defun js2-parse-array-comp (pos)
+  "Parse an ES6 array comprehension.
+POS is the beginning of the LB token.
+We should have just parsed the 'for' keyword before calling this function."
+  (let ((pn (js2-parse-comprehension pos 'ARRAY)))
+    (js2-must-match js2-RB "msg.no.bracket.arg" pos)
+    pn))
+
+(defun js2-parse-generator-comp (pos)
+  (let* ((js2-nesting-of-function (1+ js2-nesting-of-function))
+         (js2-current-script-or-fn
+          (make-js2-function-node :generator-type 'COMPREHENSION))
+         (pn (js2-parse-comprehension pos 'STAR_GENERATOR)))
+    (js2-must-match js2-RP "msg.no.paren" pos)
+    pn))
+
+(defun js2-parse-comprehension (pos form)
+  (let (loops filters expr result last)
+    (unwind-protect
+        (progn
+          (js2-unget-token)
+          (while (js2-match-token js2-FOR)
+            (let ((loop (make-js2-comp-loop-node)))
+              (js2-push-scope loop)
+              (push loop loops)
+              (js2-parse-comp-loop loop)))
+          (while (js2-match-token js2-IF)
+            (push (car (js2-parse-condition)) filters))
+          (setq expr (js2-parse-assign-expr))
+          (setq last (car loops)))
+      (dolist (_ loops)
+        (js2-pop-scope)))
+    (setq result (make-js2-comp-node :pos pos
+                                     :len (- js2-ts-cursor pos)
+                                     :result expr
+                                     :loops (nreverse loops)
+                                     :filters (nreverse filters)
+                                     :form form))
+    (apply #'js2-node-add-children result (js2-comp-node-loops result))
+    (apply #'js2-node-add-children result expr (js2-comp-node-filters result))
+    (setf (js2-scope-parent-scope result) last)
+    result))
+
+(defun js2-parse-comp-loop (pn &optional only-of-p)
+  "Parse a 'for [each] (foo [in|of] bar)' expression in an Array comprehension.
+The current token should be the initial FOR.
+If ONLY-OF-P is non-nil, only the 'for (foo of bar)' form is allowed."
+  (let ((pos (js2-comp-loop-node-pos pn))
+        tt iter obj foreach-p forof-p in-pos each-pos lp rp)
+    (when (and (not only-of-p) (js2-match-token js2-NAME))
+      (if (string= (js2-current-token-string) "each")
+          (progn
+            (setq foreach-p t
+                  each-pos (- (js2-current-token-beg) pos)) ; relative
+            (js2-record-face 'font-lock-keyword-face))
+        (js2-report-error "msg.no.paren.for")))
+    (if (js2-must-match js2-LP "msg.no.paren.for")
+        (setq lp (- (js2-current-token-beg) pos)))
+    (setq tt (js2-peek-token))
+    (cond
+     ((or (= tt js2-LB)
+          (= tt js2-LC))
+      (js2-get-token)
+      (setq iter (js2-parse-destruct-primary-expr))
+      (js2-define-destruct-symbols iter js2-LET
+                                   'font-lock-variable-name-face t))
+     ((js2-match-token js2-NAME)
+      (setq iter (js2-create-name-node)))
+     (t
+      (js2-report-error "msg.bad.var")))
+    ;; Define as a let since we want the scope of the variable to
+    ;; be restricted to the array comprehension
+    (if (js2-name-node-p iter)
+        (js2-define-symbol js2-LET (js2-name-node-name iter) pn t))
+    (if (or (and (not only-of-p) (js2-match-token js2-IN))
+            (and (>= js2-language-version 200)
+                 (js2-match-contextual-kwd "of")
+                 (setq forof-p t)))
+        (setq in-pos (- (js2-current-token-beg) pos))
+      (js2-report-error "msg.in.after.for.name"))
+    (setq obj (js2-parse-expr))
+    (if (js2-must-match js2-RP "msg.no.paren.for.ctrl")
+        (setq rp (- (js2-current-token-beg) pos)))
+    (setf (js2-node-pos pn) pos
+          (js2-node-len pn) (- js2-ts-cursor pos)
+          (js2-comp-loop-node-iterator pn) iter
+          (js2-comp-loop-node-object pn) obj
+          (js2-comp-loop-node-in-pos pn) in-pos
+          (js2-comp-loop-node-each-pos pn) each-pos
+          (js2-comp-loop-node-foreach-p pn) foreach-p
+          (js2-comp-loop-node-forof-p pn) forof-p
+          (js2-comp-loop-node-lp pn) lp
+          (js2-comp-loop-node-rp pn) rp)
+    (js2-node-add-children pn iter obj)
+    pn))
+
+(defun js2-parse-class-stmt ()
+  (let ((pos (js2-current-token-beg))
+        (_ (js2-must-match-name "msg.unnamed.class.stmt"))
+        (name (js2-create-name-node t)))
+    (js2-set-face (js2-node-pos name) (js2-node-end name)
+                  'font-lock-function-name-face 'record)
+    (let ((node (js2-parse-class pos 'CLASS_STATEMENT name)))
+      (js2-record-imenu-functions node name)
+      (js2-define-symbol js2-FUNCTION
+                         (js2-name-node-name name)
+                         node)
+      node)))
+
+(defun js2-parse-class-expr ()
+  (let ((pos (js2-current-token-beg))
+        name)
+    (when (js2-match-token js2-NAME)
+      (setq name (js2-create-name-node t)))
+    (js2-parse-class pos 'CLASS_EXPRESSION name)))
+
+(defun js2-parse-class (pos form name)
+  ;; class X [extends ...] {
+  (let (pn elems extends)
+    (if (js2-match-token js2-EXTENDS)
+        (if (= (js2-peek-token) js2-LC)
+            (js2-report-error "msg.missing.extends")
+          ;; TODO(sdh): this should be left-hand-side-expr, not assign-expr
+          (setq extends (js2-parse-assign-expr))
+          (if (not extends)
+              (js2-report-error "msg.bad.extends"))))
+    (js2-must-match js2-LC "msg.no.brace.class")
+    (setq elems (js2-parse-object-literal-elems t)
+          pn (make-js2-class-node :pos pos
+                                  :len (- js2-ts-cursor pos)
+                                  :form form
+                                  :name name
+                                  :extends extends
+                                  :elems elems))
+    (apply #'js2-node-add-children
+           pn name extends (js2-class-node-elems pn))
+    pn))
+
+(defun js2-parse-object-literal ()
+  (let* ((pos (js2-current-token-beg))
+         (elems (js2-parse-object-literal-elems))
+         (result (make-js2-object-node :pos pos
+                                       :len (- js2-ts-cursor pos)
+                                       :elems elems)))
+    (apply #'js2-node-add-children result (js2-object-node-elems result))
+    result))
+
+(defun js2-property-key-string (property-node)
+  "Return the key of PROPERTY-NODE (a `js2-object-prop-node' or
+`js2-method-node') as a string, or nil if it can't be
+represented as a string (e.g., the key is computed by an
+expression)."
+  (cond
+   ((js2-unary-node-p property-node) nil) ;; {...foo}
+   (t
+    (let ((key (js2-infix-node-left property-node)))
+      (when (js2-computed-prop-name-node-p key)
+        (setq key (js2-computed-prop-name-node-expr key)))
+      (cond
+       ((js2-name-node-p key)
+        (js2-name-node-name key))
+       ((js2-string-node-p key)
+        (js2-string-node-value key))
+       ((js2-number-node-p key)
+        (js2-number-node-value key)))))))
+
+(defun js2-parse-object-literal-elems (&optional class-p)
+  (let ((pos (js2-current-token-beg))
+        (static nil)
+        (continue t)
+        tt elems elem
+        elem-key-string previous-elem-key-string
+        after-comma previous-token)
+    (while continue
+      (setq tt (js2-get-prop-name-token)
+            static nil
+            elem nil
+            previous-token nil)
+      ;; Handle 'static' keyword only if we're in a class
+      (when (and class-p (= js2-NAME tt)
+                 (string= "static" (js2-current-token-string)))
+        (js2-record-face 'font-lock-keyword-face)
+        (setq static t
+              tt (js2-get-prop-name-token)))
+      ;; Handle generator * before the property name for in-line functions
+      (when (and (>= js2-language-version 200)
+                 (= js2-MUL tt))
+        (setq previous-token (js2-current-token)
+              tt (js2-get-prop-name-token)))
+      ;; Handle getter, setter and async methods
+      (let ((prop (js2-current-token-string)))
+        (when (and (>= js2-language-version 200)
+                   (= js2-NAME tt)
+                   (member prop '("get" "set" "async"))
+                   (member (js2-peek-token 'KEYWORD_IS_NAME)
+                           (list js2-NAME js2-STRING js2-NUMBER js2-LB)))
+          (setq previous-token (js2-current-token)
+                tt (js2-get-prop-name-token))))
+      (cond
+       ;; Rest/spread (...expr)
+       ((and (>= js2-language-version 200)
+             (not class-p) (not static) (not previous-token)
+             (= js2-TRIPLEDOT tt))
+        (setq after-comma nil
+              elem (js2-make-unary nil js2-TRIPLEDOT 'js2-parse-assign-expr)))
+       ;; Found a key/value property (of any sort)
+       ((member tt (list js2-NAME js2-STRING js2-NUMBER js2-LB))
+        (setq after-comma nil
+              elem (js2-parse-named-prop tt previous-token class-p))
+        (if (and (null elem)
+                 (not js2-recover-from-parse-errors))
+            (setq continue nil)))
+       ;; Break out of loop, and handle trailing commas.
+       ((or (= tt js2-RC)
+            (= tt js2-EOF))
+        (js2-unget-token)
+        (setq continue nil)
+        (if after-comma
+            (js2-parse-warn-trailing-comma "msg.extra.trailing.comma"
+                                           pos elems after-comma)))
+       ;; Skip semicolons in a class body
+       ((and class-p
+             (= tt js2-SEMI))
+        nil)
+       (t
+        (js2-report-error "msg.bad.prop")
+        (unless js2-recover-from-parse-errors
+          (setq continue nil))))         ; end switch
+      ;; Handle static for classes' codegen.
+      (if static
+          (if elem (js2-node-set-prop elem 'STATIC t)
+            (js2-report-error "msg.unexpected.static")))
+      ;; Handle commas, depending on class-p.
+      (let ((tok (js2-get-prop-name-token)))
+        (if (eq tok js2-COMMA)
+            (if class-p
+                (js2-report-error "msg.class.unexpected.comma")
+              (setq after-comma (js2-current-token-end)))
+          (js2-unget-token)
+          (unless class-p (setq continue nil))))
+      (when elem
+        (when (and js2-in-use-strict-directive
+                   (setq elem-key-string (js2-property-key-string elem))
+                   (cl-some
+                    (lambda (previous-elem)
+                      (and (setq previous-elem-key-string
+                                 (js2-property-key-string previous-elem))
+                           ;; Check if the property is a duplicate.
+                           (string= previous-elem-key-string elem-key-string)
+                           ;; But make an exception for getter / setter pairs.
+                           (not (and (js2-method-node-p elem)
+                                     (js2-method-node-p previous-elem)
+                                     (let ((type (js2-node-get-prop (js2-method-node-right elem) 'METHOD_TYPE))
+                                           (previous-type (js2-node-get-prop (js2-method-node-right previous-elem) 'METHOD_TYPE)))
+                                       (and (member type '(GET SET))
+                                            (member previous-type '(GET SET))
+                                            (not (eq type previous-type))))))))
+                    elems))
+          (js2-report-error "msg.dup.obj.lit.prop.strict"
+                            elem-key-string
+                            (js2-node-abs-pos (js2-infix-node-left elem))
+                            (js2-node-len (js2-infix-node-left elem))))
+        ;; Append any parsed element.
+        (push elem elems)))       ; end loop
+    (js2-must-match js2-RC "msg.no.brace.prop")
+    (nreverse elems)))
+
+(defun js2-parse-named-prop (tt previous-token &optional class-p)
+  "Parse a name, string, or getter/setter object property.
+When `js2-is-in-destructuring' is t, forms like {a, b, c} will be permitted."
+  (let ((key (js2-parse-prop-name tt))
+        (prop (and previous-token (js2-token-string previous-token)))
+        (property-type (when previous-token
+                             (if (= (js2-token-type previous-token) js2-MUL)
+                                 "*"
+                               (js2-token-string previous-token))))
+        pos)
+    (when (member prop '("get" "set" "async"))
+      (setq pos (js2-token-beg previous-token))
+      (js2-set-face (js2-token-beg previous-token)
+                    (js2-token-end previous-token)
+                    'font-lock-keyword-face 'record))  ; get/set/async
+    (cond
+     ;; method definition: {f() {...}}
+     ((and (= (js2-peek-token) js2-LP)
+           (>= js2-language-version 200))
+      (when (or (js2-name-node-p key) (js2-string-node-p key))
+        ;; highlight function name properties
+        (js2-record-face 'font-lock-function-name-face))
+      (js2-parse-method-prop pos key property-type))
+     ;; class field or binding element with initializer
+     ((and (= (js2-peek-token) js2-ASSIGN)
+           (>= js2-language-version 200))
+      (if (not (or class-p
+                   js2-is-in-destructuring))
+          (js2-report-error "msg.init.no.destruct"))
+      (js2-parse-initialized-binding key))
+     ;; regular prop
+     (t
+      (let ((beg (js2-current-token-beg))
+            (end (js2-current-token-end))
+            (expr (js2-parse-plain-property key class-p)))
+        (when (and (= tt js2-NAME)
+                   (not js2-is-in-destructuring)
+                   js2-highlight-external-variables
+                   (js2-node-get-prop expr 'SHORTHAND))
+          (js2-record-name-node key))
+        (js2-set-face beg end
+                      (if (js2-function-node-p
+                           (js2-object-prop-node-right expr))
+                          'font-lock-function-name-face
+                        'js2-object-property)
+                      'record)
+        expr)))))
+
+(defun js2-parse-initialized-binding (name)
+  "Parse a `SingleNameBinding' with initializer.
+
+`name' is the `BindingIdentifier'."
+  (when (js2-match-token js2-ASSIGN)
+    (js2-make-binary js2-ASSIGN name 'js2-parse-assign-expr t)))
+
+(defun js2-parse-prop-name (tt)
+  (cond
+   ;; Literal string keys: {'foo': 'bar'}
+   ((= tt js2-STRING)
+    (make-js2-string-node))
+   ;; Handle computed keys: {[Symbol.iterator]: ...}, *[1+2]() {...}},
+   ;; {[foo + bar]() { ... }}, {[get ['x' + 1]() {...}}
+   ((and (= tt js2-LB)
+         (>= js2-language-version 200))
+    (make-js2-computed-prop-name-node
+     :expr (prog1 (js2-parse-assign-expr)
+             (js2-must-match js2-RB "msg.missing.computed.rb"))))
+   ;; Numeric keys: {12: 'foo'}, {10.7: 'bar'}
+   ((= tt js2-NUMBER)
+    (make-js2-number-node))
+   ;; Unquoted names: {foo: 12}
+   ((= tt js2-NAME)
+    (js2-create-name-node))
+   ;; Anything else is an error
+   (t (js2-report-error "msg.bad.prop"))))
+
+(defun js2-parse-plain-property (prop &optional class-p)
+  "Parse a non-getter/setter property in an object literal.
+PROP is the node representing the property: a number, name,
+string or expression."
+  (let* (tt
+         (pos (js2-node-pos prop))
+         colon expr result)
+    (cond
+     ;; Abbreviated property, as in {foo, bar} or class {a; b}
+     ((and (>= js2-language-version 200)
+           (if class-p
+               (and (setq tt (js2-peek-token-or-eol))
+                    (member tt (list js2-EOL js2-RC js2-SEMI)))
+             (and (setq tt (js2-peek-token))
+                  (member tt (list js2-COMMA js2-RC))
+                  (js2-name-node-p prop))))
+      (setq result (make-js2-object-prop-node
+                    :pos pos
+                    :len (js2-node-len prop)
+                    :left prop
+                    :right prop
+                    :op-pos (- (js2-current-token-beg) pos)))
+      (js2-node-add-children result prop)
+      (js2-node-set-prop result 'SHORTHAND t)
+      result)
+     ;; Normal property
+     (t
+      (setq tt (js2-get-token))
+      (if (= tt js2-COLON)
+          (setq colon (- (js2-current-token-beg) pos)
+                expr (js2-parse-assign-expr))
+        (js2-report-error "msg.no.colon.prop")
+        (setq expr (make-js2-error-node)))
+      (setq result (make-js2-object-prop-node
+                   :pos pos
+                   ;; don't include last consumed token in length
+                   :len (- (+ (js2-node-pos expr)
+                              (js2-node-len expr))
+                           pos)
+                   :left prop
+                   :right expr
+                   :op-pos colon))
+      (js2-node-add-children result prop expr)
+      result))))
+
+(defun js2-parse-method-prop (pos prop type-string)
+  "Parse method property in an object literal or a class body.
+JavaScript syntax is:
+
+  { foo(...) {...}, get foo() {...}, set foo(x) {...}, *foo(...) {...},
+    async foo(...) {...} }
+
+and expression closure style is also supported
+
+  { get foo() x, set foo(x) _x = x }
+
+POS is the start position of the `get' or `set' keyword, if any.
+PROP is the `js2-name-node' representing the property name.
+TYPE-STRING is a string `get', `set', `*', or nil, indicating a found keyword."
+  (let* ((type (or (cdr (assoc type-string '(("get" . GET)
+                                             ("set" . SET)
+                                             ("async" . ASYNC))))
+                   'FUNCTION))
+         result end
+         (pos (or pos (js2-current-token-beg)))
+         (_ (js2-must-match js2-LP "msg.no.paren.parms"))
+         (fn (js2-parse-function 'FUNCTION_EXPRESSION pos
+                                 (string= type-string "*")
+                                 (eq type 'ASYNC)
+                                 nil)))
+    (js2-node-set-prop fn 'METHOD_TYPE type)  ; for codegen
+    (unless pos (setq pos (js2-node-pos prop)))
+    (setq end (js2-node-end fn)
+          result (make-js2-method-node :pos pos
+                                       :len (- end pos)
+                                       :left prop
+                                       :right fn))
+    (js2-node-add-children result prop fn)
+    result))
+
+(defun js2-create-name-node (&optional check-activation-p token string)
+  "Create a name node using the current token and, optionally, STRING.
+And, if CHECK-ACTIVATION-P is non-nil, use the value of TOKEN."
+  (let* ((beg (js2-current-token-beg))
+         (tt (js2-current-token-type))
+         (s (or string
+                (if (= js2-NAME tt)
+                    (js2-current-token-string)
+                  (js2-tt-name tt))))
+         name)
+    (setq name (make-js2-name-node :pos beg
+                                   :name s
+                                   :len (length s)))
+    (if check-activation-p
+        (js2-check-activation-name s (or token js2-NAME)))
+    name))
+
+;;; Use AST to extract semantic information
+
+(defun js2-get-element-index-from-array-node (elem array-node &optional hardcoded-array-index)
+  "Get index of ELEM from ARRAY-NODE or 0 and return it as string."
+  (let ((idx 0) elems (rlt hardcoded-array-index))
+    (setq elems (js2-array-node-elems array-node))
+    (if (and elem (not hardcoded-array-index))
+        (setq rlt (catch 'nth-elt
+                    (dolist (x elems)
+                      ;; We know the ELEM does belong to ARRAY-NODE,
+                      (if (eq elem x) (throw 'nth-elt idx))
+                      (setq idx (1+ idx)))
+                    0)))
+    (format "[%s]" rlt)))
+
+(defun js2-print-json-path (&optional hardcoded-array-index)
+  "Print the path to the JSON value under point, and save it in the kill ring.
+If HARDCODED-ARRAY-INDEX provided, array index in JSON path is replaced with it."
+  (interactive "P")
+  (js2-reparse)
+  (let (previous-node current-node
+        key-name
+        rlt)
+
+    ;; The `js2-node-at-point' starts scanning from AST root node.
+    ;; So there is no way to optimize it.
+    (setq current-node (js2-node-at-point))
+
+    (while (not (js2-ast-root-p current-node))
+      (cond
+       ;; JSON property node
+       ((js2-object-prop-node-p current-node)
+        (setq key-name (js2-prop-node-name (js2-object-prop-node-left current-node)))
+        (if rlt (setq rlt (concat "." key-name rlt))
+          (setq rlt (concat "." key-name))))
+
+       ;; Array node
+       ((or (js2-array-node-p current-node))
+        (setq rlt (concat (js2-get-element-index-from-array-node previous-node
+                                                                 current-node
+                                                                 hardcoded-array-index)
+                          rlt)))
+
+       ;; Other nodes are ignored
+       (t))
+
+      ;; current node is archived
+      (setq previous-node current-node)
+      ;; Get parent node and continue the loop
+      (setq current-node (js2-node-parent current-node)))
+
+    (cond
+     (rlt
+      ;; Clean the final result
+      (setq rlt (replace-regexp-in-string "^\\." "" rlt))
+      (kill-new rlt)
+      (message "%s => kill-ring" rlt))
+     (t
+      (message "No JSON path found!")))
+
+    rlt))
+
+;;; Indentation support (bouncing)
+
+;; In recent-enough Emacs, we reuse the indentation code from
+;; `js-mode'.  To continue support for the older versions, some code
+;; that was here previously was moved to `js2-old-indent.el'.
+
+;; Whichever indenter is used, it's often "wrong", however, and needs
+;; to be overridden.  The right long-term solution is probably to
+;; emulate (or integrate with) cc-engine, but it's a nontrivial amount
+;; of coding.  Even when a parse tree from `js2-parse' is present,
+;; which is not true at the moment the user is typing, computing
+;; indentation is still thousands of lines of code to handle every
+;; possible syntactic edge case.
+
+;; In the meantime, the compromise solution is that we offer a "bounce
+;; indenter", configured with `js2-bounce-indent-p', which cycles the
+;; current line indent among various likely guess points.  This approach
+;; is far from perfect, but should at least make it slightly easier to
+;; move the line towards its desired indentation when manually
+;; overriding Karl's heuristic nesting guesser.
+
+(defun js2-backward-sws ()
+  "Move backward through whitespace and comments."
+  (interactive)
+  (while (forward-comment -1)))
+
+(defun js2-forward-sws ()
+  "Move forward through whitespace and comments."
+  (interactive)
+  (while (forward-comment 1)))
+
+(defun js2-arglist-close ()
+  "Return non-nil if we're on a line beginning with a close-paren/brace."
+  (save-excursion
+    (goto-char (point-at-bol))
+    (js2-forward-sws)
+    (looking-at "[])}]")))
+
+(defun js2-indent-looks-like-label-p ()
+  (goto-char (point-at-bol))
+  (js2-forward-sws)
+  (looking-at (concat js2-mode-identifier-re ":")))
+
+(defun js2-indent-in-objlit-p (parse-status)
+  "Return non-nil if this looks like an object-literal entry."
+  (let ((start (nth 1 parse-status)))
+    (and
+     start
+     (save-excursion
+       (and (zerop (forward-line -1))
+            (not (< (point) start))     ; crossed a {} boundary
+            (js2-indent-looks-like-label-p)))
+     (save-excursion
+       (js2-indent-looks-like-label-p)))))
+
+;; If prev line looks like foobar({ then we're passing an object
+;; literal to a function call, and people pretty much always want to
+;; de-dent back to the previous line, so move the 'basic-offset'
+;; position to the front.
+(defun js2-indent-objlit-arg-p (parse-status)
+  (save-excursion
+    (back-to-indentation)
+    (js2-backward-sws)
+    (and (eq (1- (point)) (nth 1 parse-status))
+         (eq (char-before) ?{)
+         (progn
+           (forward-char -1)
+           (skip-chars-backward " \t")
+           (eq (char-before) ?\()))))
+
+(defun js2-indent-case-block-p ()
+  (save-excursion
+    (back-to-indentation)
+    (js2-backward-sws)
+    (goto-char (point-at-bol))
+    (skip-chars-forward " \t")
+    (looking-at "case\\s-.+:")))
+
+(defun js2-bounce-indent (normal-col parse-status &optional backward)
+  "Cycle among alternate computed indentation positions.
+PARSE-STATUS is the result of `parse-partial-sexp' from the beginning
+of the buffer to the current point.  NORMAL-COL is the indentation
+column computed by the heuristic guesser based on current paren,
+bracket, brace and statement nesting.  If BACKWARDS, cycle positions
+in reverse."
+  (let ((cur-indent (current-indentation))
+        (old-buffer-undo-list buffer-undo-list)
+        ;; Emacs 21 only has `count-lines', not `line-number-at-pos'
+        (current-line (save-excursion
+                        (forward-line 0)  ; move to bol
+                        (1+ (count-lines (point-min) (point)))))
+        positions pos main-pos anchor arglist-cont same-indent
+        basic-offset computed-pos)
+    ;; temporarily don't record undo info, if user requested this
+    (when js2-mode-indent-inhibit-undo
+      (setq buffer-undo-list t))
+    (unwind-protect
+        (progn
+          ;; First likely point:  indent from beginning of previous code line
+          (push (setq basic-offset
+                      (+ (save-excursion
+                           (back-to-indentation)
+                           (js2-backward-sws)
+                           (back-to-indentation)
+                           (current-column))
+                         js2-basic-offset))
+                positions)
+
+          ;; (First + epsilon) likely point:  indent 2x from beginning of
+          ;; previous code line.  Google does it this way.
+          (push (setq basic-offset
+                      (+ (save-excursion
+                           (back-to-indentation)
+                           (js2-backward-sws)
+                           (back-to-indentation)
+                           (current-column))
+                         (* 2 js2-basic-offset)))
+                positions)
+
+          ;; Second likely point:  indent from assign-expr RHS.  This
+          ;; is just a crude guess based on finding " = " on the previous
+          ;; line containing actual code.
+          (setq pos (save-excursion
+                      (forward-line -1)
+                      (goto-char (point-at-bol))
+                      (when (re-search-forward "\\s-+\\(=\\)\\s-+"
+                                               (point-at-eol) t)
+                        (goto-char (match-end 1))
+                        (skip-chars-forward " \t\r\n")
+                        (current-column))))
+          (when pos
+            (cl-incf pos js2-basic-offset)
+            (push pos positions))
+
+          ;; Third likely point:  same indent as previous line of code.
+          ;; Make it the first likely point if we're not on an
+          ;; arglist-close line and previous line ends in a comma, or
+          ;; both this line and prev line look like object-literal
+          ;; elements.
+          (setq pos (save-excursion
+                      (goto-char (point-at-bol))
+                      (js2-backward-sws)
+                      (back-to-indentation)
+                      (prog1
+                          (current-column)
+                        ;; while we're here, look for trailing comma
+                        (if (save-excursion
+                              (goto-char (point-at-eol))
+                              (js2-backward-sws)
+                              (eq (char-before) ?,))
+                            (setq arglist-cont (1- (point)))))))
+          (when pos
+            (if (and (or arglist-cont
+                         (js2-indent-in-objlit-p parse-status))
+                     (not (js2-arglist-close)))
+                (setq same-indent pos))
+            (push pos positions))
+
+          ;; Fourth likely point:  first preceding code with less indentation.
+          ;; than the immediately preceding code line.
+          (setq pos (save-excursion
+                      (back-to-indentation)
+                      (js2-backward-sws)
+                      (back-to-indentation)
+                      (setq anchor (current-column))
+                      (while (and (zerop (forward-line -1))
+                                  (>= (progn
+                                        (back-to-indentation)
+                                        (current-column))
+                                      anchor)))
+                      (setq pos (current-column))))
+          (push pos positions)
+
+          ;; nesting-heuristic position, main by default
+          (push (setq main-pos normal-col) positions)
+
+          ;; delete duplicates and sort positions list
+          (setq positions (sort (delete-dups positions) '<))
+
+          ;; comma-list continuation lines:  prev line indent takes precedence
+          (if same-indent
+              (setq main-pos same-indent))
+
+          ;; common special cases where we want to indent in from previous line
+          (if (or (js2-indent-case-block-p)
+                  (js2-indent-objlit-arg-p parse-status))
+              (setq main-pos basic-offset))
+
+          ;; if bouncing backward, reverse positions list
+          (if backward
+              (setq positions (reverse positions)))
+
+          ;; record whether we're already sitting on one of the alternatives
+          (setq pos (member cur-indent positions))
+
+          (cond
+           ;; case 0:  we're one one of the alternatives and this is the
+           ;; first time they've pressed TAB on this line (best-guess).
+           ((and js2-mode-indent-ignore-first-tab
+                 pos
+                 ;; first time pressing TAB on this line?
+                 (not (eq js2-mode-last-indented-line current-line)))
+            ;; do nothing
+            (setq computed-pos nil))
+           ;; case 1:  only one computed position => use it
+           ((null (cdr positions))
+            (setq computed-pos 0))
+           ;; case 2:  not on any of the computed spots => use main spot
+           ((not pos)
+            (setq computed-pos (js2-position main-pos positions)))
+           ;; case 3:  on last position:  cycle to first position
+           ((null (cdr pos))
+            (setq computed-pos 0))
+           ;; case 4:  on intermediate position:  cycle to next position
+           (t
+            (setq computed-pos (js2-position (cl-second pos) positions))))
+
+          ;; see if any hooks want to indent; otherwise we do it
+          (cl-loop with result = nil
+                   for hook in js2-indent-hook
+                   while (null result)
+                   do
+                   (setq result (funcall hook positions computed-pos))
+                   finally do
+                   (unless (or result (null computed-pos))
+                     (indent-line-to (nth computed-pos positions)))))
+
+      ;; finally
+      (if js2-mode-indent-inhibit-undo
+          (setq buffer-undo-list old-buffer-undo-list))
+      ;; see commentary for `js2-mode-last-indented-line'
+      (setq js2-mode-last-indented-line current-line))))
+
+(defun js2-1-line-comment-continuation-p ()
+  "Return t if we're in a 1-line comment continuation.
+If so, we don't ever want to use bounce-indent."
+  (save-excursion
+    (and (progn
+           (forward-line 0)
+           (looking-at "\\s-*//"))
+         (progn
+           (forward-line -1)
+           (forward-line 0)
+           (when (looking-at "\\s-*$")
+             (js2-backward-sws)
+             (forward-line 0))
+           (looking-at "\\s-*//")))))
+
+(defun js2-indent-bounce (&optional backward)
+  "Indent the current line, bouncing between several positions."
+  (interactive)
+  (let (parse-status offset indent-col
+        ;; Don't whine about errors/warnings when we're indenting.
+        ;; This has to be set before calling parse-partial-sexp below.
+        (inhibit-point-motion-hooks t))
+    (setq parse-status (save-excursion
+                         (syntax-ppss (point-at-bol)))
+          offset (- (point) (save-excursion
+                              (back-to-indentation)
+                              (point))))
+    ;; Don't touch multiline strings.
+    (unless (nth 3 parse-status)
+      (setq indent-col (js2-proper-indentation parse-status))
+      (cond
+       ;; It doesn't work well on first line of buffer.
+       ((and (not (nth 4 parse-status))
+             (not (js2-same-line (point-min)))
+             (not (js2-1-line-comment-continuation-p)))
+        (js2-bounce-indent indent-col parse-status backward))
+       ;; just indent to the guesser's likely spot
+       (t (indent-line-to indent-col)))
+      (when (cl-plusp offset)
+        (forward-char offset)))))
+
+(defun js2-indent-bounce-backward ()
+  "Indent the current line, bouncing between positions in reverse."
+  (interactive)
+  (js2-indent-bounce t))
+
+(defun js2-indent-region (start end)
+  "Indent the region, but don't use bounce indenting."
+  (let ((js2-bounce-indent-p nil)
+        (indent-region-function nil)
+        (after-change-functions (remq 'js2-mode-edit
+                                      after-change-functions)))
+    (indent-region start end nil) ; nil for byte-compiler
+    (js2-mode-edit start end (- end start))))
+
+(defvar js2-minor-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "C-c C-`") #'js2-next-error)
+    map)
+  "Keymap used when `js2-minor-mode' is active.")
+
+;;;###autoload
+(define-minor-mode js2-minor-mode
+  "Minor mode for running js2 as a background linter.
+This allows you to use a different major mode for JavaScript editing,
+such as `js-mode', while retaining the asynchronous error/warning
+highlighting features of `js2-mode'."
+  :group 'js2-mode
+  :lighter " js-lint"
+  (if (derived-mode-p 'js2-mode)
+      (setq js2-minor-mode nil)
+    (if js2-minor-mode
+        (js2-minor-mode-enter)
+      (js2-minor-mode-exit))))
+
+(defun js2-minor-mode-enter ()
+  "Initialization for `js2-minor-mode'."
+  (set (make-local-variable 'max-lisp-eval-depth)
+       (max max-lisp-eval-depth 3000))
+  (setq next-error-function #'js2-next-error)
+  ;; Experiment:  make reparse-delay longer for longer files.
+  (if (cl-plusp js2-dynamic-idle-timer-adjust)
+      (setq js2-idle-timer-delay
+            (* js2-idle-timer-delay
+               (/ (point-max) js2-dynamic-idle-timer-adjust))))
+  (setq js2-mode-buffer-dirty-p t
+        js2-mode-parsing nil)
+  (set (make-local-variable 'js2-highlight-level) 0) ; no syntax highlighting
+  (add-hook 'after-change-functions #'js2-minor-mode-edit nil t)
+  (add-hook 'change-major-mode-hook #'js2-minor-mode-exit nil t)
+  (when js2-include-jslint-globals
+    (add-hook 'js2-post-parse-callbacks 'js2-apply-jslint-globals nil t))
+  (when js2-include-jslint-declaration-externs
+    (add-hook 'js2-post-parse-callbacks 'js2-apply-jslint-declaration-externs nil t))
+  (run-hooks 'js2-init-hook)
+  (js2-reparse))
+
+(defun js2-minor-mode-exit ()
+  "Turn off `js2-minor-mode'."
+  (setq next-error-function nil)
+  (remove-hook 'after-change-functions #'js2-mode-edit t)
+  (remove-hook 'change-major-mode-hook #'js2-minor-mode-exit t)
+  (when js2-mode-node-overlay
+    (delete-overlay js2-mode-node-overlay)
+    (setq js2-mode-node-overlay nil))
+  (js2-remove-overlays)
+  (remove-hook 'js2-post-parse-callbacks 'js2-apply-jslint-globals t)
+  (remove-hook 'js2-post-parse-callbacks 'js2-apply-jslint-declaration-externs t)
+  (setq js2-mode-ast nil))
+
+(defvar js2-source-buffer nil "Linked source buffer for diagnostics view")
+(make-variable-buffer-local 'js2-source-buffer)
+
+(cl-defun js2-display-error-list ()
+  "Display a navigable buffer listing parse errors/warnings."
+  (interactive)
+  (unless (js2-have-errors-p)
+    (message "No errors")
+    (cl-return-from js2-display-error-list))
+  (cl-labels ((annotate-list
+               (lst type)
+               "Add diagnostic TYPE and line number to errs list"
+               (mapcar (lambda (err)
+                         (list err type (line-number-at-pos (nth 1 err))))
+                       lst)))
+    (let* ((srcbuf (current-buffer))
+           (errbuf (get-buffer-create "*js-lint*"))
+           (errors (annotate-list
+                    (when js2-mode-ast (js2-ast-root-errors js2-mode-ast))
+                    'js2-error))  ; must be a valid face name
+           (warnings (annotate-list
+                      (when js2-mode-ast (js2-ast-root-warnings js2-mode-ast))
+                      'js2-warning))  ; must be a valid face name
+           (all-errs (sort (append errors warnings)
+                           (lambda (e1 e2) (< (cl-cadar e1) (cl-cadar e2))))))
+      (with-current-buffer errbuf
+        (let ((inhibit-read-only t))
+          (erase-buffer)
+          (dolist (err all-errs)
+            (cl-destructuring-bind ((msg-key beg _end &rest) type line) err
+              (insert-text-button
+               (format "line %d: %s" line (js2-get-msg msg-key))
+               'face type
+               'follow-link "\C-m"
+               'action 'js2-error-buffer-jump
+               'js2-msg (js2-get-msg msg-key)
+               'js2-pos beg)
+              (insert "\n"))))
+        (js2-error-buffer-mode)
+        (setq js2-source-buffer srcbuf)
+        (pop-to-buffer errbuf)
+        (goto-char (point-min))
+        (unless (eobp)
+          (js2-error-buffer-view))))))
+
+(defvar js2-error-buffer-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map "n" #'js2-error-buffer-next)
+    (define-key map "p" #'js2-error-buffer-prev)
+    (define-key map (kbd "RET") #'js2-error-buffer-jump)
+    (define-key map "o" #'js2-error-buffer-view)
+    (define-key map "q" #'js2-error-buffer-quit)
+    map)
+  "Keymap used for js2 diagnostics buffers.")
+
+(defun js2-error-buffer-mode ()
+  "Major mode for js2 diagnostics buffers.
+Selecting an error will jump it to the corresponding source-buffer error.
+\\{js2-error-buffer-mode-map}"
+  (interactive)
+  (setq major-mode 'js2-error-buffer-mode
+        mode-name "JS Lint Diagnostics")
+  (use-local-map js2-error-buffer-mode-map)
+  (setq truncate-lines t)
+  (set-buffer-modified-p nil)
+  (setq buffer-read-only t)
+  (run-hooks 'js2-error-buffer-mode-hook))
+
+(defun js2-error-buffer-next ()
+  "Move to next error and view it."
+  (interactive)
+  (when (zerop (forward-line 1))
+    (js2-error-buffer-view)))
+
+(defun js2-error-buffer-prev ()
+  "Move to previous error and view it."
+  (interactive)
+  (when (zerop (forward-line -1))
+    (js2-error-buffer-view)))
+
+(defun js2-error-buffer-quit ()
+  "Kill the current buffer."
+  (interactive)
+  (kill-buffer))
+
+(defun js2-error-buffer-jump (&rest ignored)
+  "Jump cursor to current error in source buffer."
+  (interactive)
+  (when (js2-error-buffer-view)
+    (pop-to-buffer js2-source-buffer)))
+
+(defun js2-error-buffer-view ()
+  "Scroll source buffer to show error at current line."
+  (interactive)
+  (cond
+   ((not (eq major-mode 'js2-error-buffer-mode))
+    (message "Not in a js2 errors buffer"))
+   ((not (buffer-live-p js2-source-buffer))
+    (message "Source buffer has been killed"))
+   ((not (wholenump (get-text-property (point) 'js2-pos)))
+    (message "There does not seem to be an error here"))
+   (t
+    (let ((pos (get-text-property (point) 'js2-pos))
+          (msg (get-text-property (point) 'js2-msg)))
+      (save-selected-window
+        (pop-to-buffer js2-source-buffer)
+        (goto-char pos)
+        (message msg))))))
+
+;;;###autoload
+(define-derived-mode js2-mode js-mode "Javascript-IDE"
+  "Major mode for editing JavaScript code."
+  (set (make-local-variable 'max-lisp-eval-depth)
+       (max max-lisp-eval-depth 3000))
+  (set (make-local-variable 'indent-line-function) #'js2-indent-line)
+  (set (make-local-variable 'indent-region-function) #'js2-indent-region)
+  (set (make-local-variable 'syntax-propertize-function) nil)
+  (set (make-local-variable 'comment-line-break-function) #'js2-line-break)
+  (set (make-local-variable 'beginning-of-defun-function) #'js2-beginning-of-defun)
+  (set (make-local-variable 'end-of-defun-function) #'js2-end-of-defun)
+  ;; We un-confuse `parse-partial-sexp' by setting syntax-table properties
+  ;; for characters inside regexp literals.
+  (set (make-local-variable 'parse-sexp-lookup-properties) t)
+  ;; this is necessary to make `show-paren-function' work properly
+  (set (make-local-variable 'parse-sexp-ignore-comments) t)
+  ;; needed for M-x rgrep, among other things
+  (put 'js2-mode 'find-tag-default-function #'js2-mode-find-tag)
+
+  (setq font-lock-defaults '(nil t))
+
+  ;; Experiment:  make reparse-delay longer for longer files.
+  (when (cl-plusp js2-dynamic-idle-timer-adjust)
+    (setq js2-idle-timer-delay
+          (* js2-idle-timer-delay
+             (/ (point-max) js2-dynamic-idle-timer-adjust))))
+
+  (add-hook 'change-major-mode-hook #'js2-mode-exit nil t)
+  (add-hook 'after-change-functions #'js2-mode-edit nil t)
+  (setq imenu-create-index-function #'js2-mode-create-imenu-index)
+  (setq next-error-function #'js2-next-error)
+  (imenu-add-to-menubar (concat "IM-" mode-name))
+  (add-to-invisibility-spec '(js2-outline . t))
+  (set (make-local-variable 'line-move-ignore-invisible) t)
+  (set (make-local-variable 'forward-sexp-function) #'js2-mode-forward-sexp)
+  (when (fboundp 'cursor-sensor-mode) (cursor-sensor-mode 1))
+
+  (setq js2-mode-functions-hidden nil
+        js2-mode-comments-hidden nil
+        js2-mode-buffer-dirty-p t
+        js2-mode-parsing nil)
+
+  (when js2-include-jslint-globals
+    (add-hook 'js2-post-parse-callbacks 'js2-apply-jslint-globals nil t))
+  (when js2-include-jslint-declaration-externs
+    (add-hook 'js2-post-parse-callbacks 'js2-apply-jslint-declaration-externs nil t))
+
+  (run-hooks 'js2-init-hook)
+
+  (let ((js2-idle-timer-delay 0))
+    ;; Schedule parsing for after when the mode hooks run.
+    (js2-mode-reset-timer)))
+
+;; We may eventually want js2-jsx-mode to derive from js-jsx-mode, but that'd be
+;; a bit more complicated and it doesn't net us much yet.
+;;;###autoload
+(define-derived-mode js2-jsx-mode js2-mode "JSX-IDE"
+  "Major mode for editing JSX code.
+
+To customize the indentation for this mode, set the SGML offset
+variables (`sgml-basic-offset' et al) locally, like so:
+
+  (defun set-jsx-indentation ()
+    (setq-local sgml-basic-offset js2-basic-offset))
+  (add-hook \\='js2-jsx-mode-hook #\\='set-jsx-indentation)"
+  (set (make-local-variable 'indent-line-function) #'js2-jsx-indent-line))
+
+(defun js2-mode-exit ()
+  "Exit `js2-mode' and clean up."
+  (interactive)
+  (when js2-mode-node-overlay
+    (delete-overlay js2-mode-node-overlay)
+    (setq js2-mode-node-overlay nil))
+  (js2-remove-overlays)
+  (setq js2-mode-ast nil)
+  (remove-hook 'change-major-mode-hook #'js2-mode-exit t)
+  (remove-from-invisibility-spec '(js2-outline . t))
+  (js2-mode-show-all)
+  (with-silent-modifications
+    (js2-clear-face (point-min) (point-max))))
+
+(defun js2-mode-reset-timer ()
+  "Cancel any existing parse timer and schedule a new one."
+  (if js2-mode-parse-timer
+      (cancel-timer js2-mode-parse-timer))
+  (setq js2-mode-parsing nil)
+  (let ((timer (timer-create)))
+    (setq js2-mode-parse-timer timer)
+    (timer-set-function timer 'js2-mode-idle-reparse (list (current-buffer)))
+    (timer-set-idle-time timer js2-idle-timer-delay)
+    ;; http://debbugs.gnu.org/cgi/bugreport.cgi?bug=12326
+    (timer-activate-when-idle timer nil)))
+
+(defun js2-mode-idle-reparse (buffer)
+  "Run `js2-reparse' if BUFFER is the current buffer, or schedule
+it to be reparsed when the buffer is selected."
+  (cond ((eq buffer (current-buffer))
+         (js2-reparse))
+        ((buffer-live-p buffer)
+         ;; reparse when the buffer is selected again
+         (with-current-buffer buffer
+           (add-hook 'window-configuration-change-hook
+                     #'js2-mode-idle-reparse-inner
+                     nil t)))))
+
+(defun js2-mode-idle-reparse-inner ()
+  (remove-hook 'window-configuration-change-hook
+               #'js2-mode-idle-reparse-inner
+               t)
+  (js2-reparse))
+
+(defun js2-mode-edit (_beg _end _len)
+  "Schedule a new parse after buffer is edited.
+Buffer edit spans from BEG to END and is of length LEN."
+  (setq js2-mode-buffer-dirty-p t)
+  (js2-mode-hide-overlay)
+  (js2-mode-reset-timer))
+
+(defun js2-minor-mode-edit (_beg _end _len)
+  "Callback for buffer edits in `js2-mode'.
+Schedules a new parse after buffer is edited.
+Buffer edit spans from BEG to END and is of length LEN."
+  (setq js2-mode-buffer-dirty-p t)
+  (js2-mode-hide-overlay)
+  (js2-mode-reset-timer))
+
+(defun js2-reparse (&optional force)
+  "Re-parse current buffer after user finishes some data entry.
+If we get any user input while parsing, including cursor motion,
+we discard the parse and reschedule it.  If FORCE is nil, then the
+buffer will only rebuild its `js2-mode-ast' if the buffer is dirty."
+  (let (time
+        interrupted-p
+        (js2-compiler-strict-mode js2-mode-show-strict-warnings))
+    (unless js2-mode-parsing
+      (setq js2-mode-parsing t)
+      (unwind-protect
+          (when (or js2-mode-buffer-dirty-p force)
+            (js2-remove-overlays)
+            (setq js2-mode-buffer-dirty-p nil
+                  js2-mode-fontifications nil
+                  js2-mode-deferred-properties nil)
+            (if js2-mode-verbose-parse-p
+                (message "parsing..."))
+            (setq time
+                  (js2-time
+                   (setq interrupted-p
+                         (catch 'interrupted
+                           (js2-parse)
+                           (with-silent-modifications
+                             ;; if parsing is interrupted, comments and regex
+                             ;; literals stay ignored by `parse-partial-sexp'
+                             (remove-text-properties (point-min) (point-max)
+                                                     '(syntax-table))
+                             (js2-mode-apply-deferred-properties)
+                             (js2-mode-remove-suppressed-warnings)
+                             (js2-mode-show-warnings)
+                             (js2-mode-show-errors)
+                             (if (>= js2-highlight-level 1)
+                                 (js2-highlight-jsdoc js2-mode-ast)))
+                           nil))))
+            (if interrupted-p
+                (progn
+                  ;; unfinished parse => try again
+                  (setq js2-mode-buffer-dirty-p t)
+                  (js2-mode-reset-timer))
+              (if js2-mode-verbose-parse-p
+                  (message "Parse time: %s" time))))
+        (setq js2-mode-parsing nil)
+        (unless interrupted-p
+          (setq js2-mode-parse-timer nil))))))
+
+;; We bound it to [mouse-1] previously.  But the signature of
+;; mouse-set-point changed around 24.4, so it's kind of hard to keep
+;; it working in 24.1-24.3.  Since the command is not hugely
+;; important, we removed the binding (#356).  Maybe we'll bring it
+;; back when supporting <24.4 is not a goal anymore.
+(defun js2-mode-show-node (event &optional promote-to-region)
+  "Debugging aid:  highlight selected AST node on mouse click."
+  (interactive "e\np")
+  (mouse-set-point event promote-to-region)
+  (when js2-mode-show-overlay
+    (let ((node (js2-node-at-point))
+          beg end)
+      (if (null node)
+          (message "No node found at location %s" (point))
+        (setq beg (js2-node-abs-pos node)
+              end (+ beg (js2-node-len node)))
+        (if js2-mode-node-overlay
+            (move-overlay js2-mode-node-overlay beg end)
+          (setq js2-mode-node-overlay (make-overlay beg end))
+          (overlay-put js2-mode-node-overlay 'font-lock-face 'highlight))
+        (with-silent-modifications
+          (if (fboundp 'cursor-sensor-mode)
+              (put-text-property beg end 'cursor-sensor-functions
+                                 '(js2-mode-hide-overlay))
+            (put-text-property beg end 'point-left #'js2-mode-hide-overlay)))
+        (message "%s, parent: %s"
+                 (js2-node-short-name node)
+                 (if (js2-node-parent node)
+                     (js2-node-short-name (js2-node-parent node))
+                   "nil"))))))
+
+(defun js2-mode-hide-overlay (&optional arg1 arg2 _arg3)
+  "Remove the debugging overlay when point moves.
+ARG1, ARG2 and ARG3 have different values depending on whether this function
+was found on `point-left' or in `cursor-sensor-functions'."
+  (when js2-mode-node-overlay
+    (let ((beg (overlay-start js2-mode-node-overlay))
+          (end (overlay-end js2-mode-node-overlay))
+          (p2 (if (windowp arg1)
+                  ;; Called from cursor-sensor-functions.
+                  (window-point arg1)
+                ;; Called from point-left.
+                arg2)))
+      ;; Sometimes we're called spuriously.
+      (unless (and p2
+                   (>= p2 beg)
+                   (<= p2 end))
+        (with-silent-modifications
+          (remove-text-properties beg end
+                                  '(point-left nil cursor-sensor-functions)))
+        (delete-overlay js2-mode-node-overlay)
+        (setq js2-mode-node-overlay nil)))))
+
+(defun js2-mode-reset ()
+  "Debugging helper:  reset everything."
+  (interactive)
+  (js2-mode-exit)
+  (js2-mode))
+
+(defun js2-mode-show-warn-or-err (e face)
+  "Highlight a warning or error E with FACE.
+E is a list of ((MSG-KEY MSG-ARG) BEG LEN OVERRIDE-FACE).
+The last element is optional.  When present, use instead of FACE."
+  (let* ((key (cl-first e))
+         (beg (cl-second e))
+         (end (+ beg (cl-third e)))
+         ;; Don't inadvertently go out of bounds.
+         (beg (max (point-min) (min beg (point-max))))
+         (end (max (point-min) (min end (point-max))))
+         (ovl (make-overlay beg end)))
+    ;; FIXME: Why a mix of overlays and text-properties?
+    (overlay-put ovl 'font-lock-face (or (cl-fourth e) face))
+    (overlay-put ovl 'js2-error t)
+    (put-text-property beg end 'help-echo (js2-get-msg key))
+    (if (fboundp 'cursor-sensor-mode)
+        (put-text-property beg end 'cursor-sensor-functions '(js2-echo-error))
+      (put-text-property beg end 'point-entered #'js2-echo-error))))
+
+(defun js2-remove-overlays ()
+  "Remove overlays from buffer that have a `js2-error' property."
+  (let ((beg (point-min))
+        (end (point-max)))
+    (save-excursion
+      (dolist (o (overlays-in beg end))
+        (when (overlay-get o 'js2-error)
+          (delete-overlay o))))))
+
+(defun js2-mode-apply-deferred-properties ()
+  "Apply fontifications and other text properties recorded during parsing."
+  (when (cl-plusp js2-highlight-level)
+    ;; We defer clearing faces as long as possible to eliminate flashing.
+    (js2-clear-face (point-min) (point-max))
+    ;; Have to reverse the recorded fontifications list so that errors
+    ;; and warnings overwrite the normal fontifications.
+    (dolist (f (nreverse js2-mode-fontifications))
+      (put-text-property (cl-first f) (cl-second f) 'font-lock-face (cl-third f)))
+    (setq js2-mode-fontifications nil))
+  (dolist (p js2-mode-deferred-properties)
+    (apply #'put-text-property p))
+  (setq js2-mode-deferred-properties nil))
+
+(defun js2-mode-show-errors ()
+  "Highlight syntax errors."
+  (when js2-mode-show-parse-errors
+    (dolist (e (js2-ast-root-errors js2-mode-ast))
+      (js2-mode-show-warn-or-err e 'js2-error))))
+
+(defun js2-mode-remove-suppressed-warnings ()
+  "Take suppressed warnings out of the AST warnings list.
+This ensures that the counts and `next-error' are correct."
+  (setf (js2-ast-root-warnings js2-mode-ast)
+        (js2-delete-if
+         (lambda (e)
+           (let ((key (caar e)))
+             (or
+              (and (not js2-strict-trailing-comma-warning)
+                   (string-match "trailing\\.comma" key))
+              (and (not js2-strict-cond-assign-warning)
+                   (string= key "msg.equal.as.assign"))
+              (and js2-missing-semi-one-line-override
+                   (string= key "msg.missing.semi")
+                   (let* ((beg (cl-second e))
+                          (node (js2-node-at-point beg))
+                          (fn (js2-mode-find-parent-fn node))
+                          (body (and fn (js2-function-node-body fn)))
+                          (lc (and body (js2-node-abs-pos body)))
+                          (rc (and lc (+ lc (js2-node-len body)))))
+                     (and fn
+                          (or (null body)
+                              (save-excursion
+                                (goto-char beg)
+                                (and (js2-same-line lc)
+                                     (js2-same-line rc))))))))))
+         (js2-ast-root-warnings js2-mode-ast))))
+
+(defun js2-mode-show-warnings ()
+  "Highlight strict-mode warnings."
+  (when js2-mode-show-strict-warnings
+    (dolist (e (js2-ast-root-warnings js2-mode-ast))
+      (js2-mode-show-warn-or-err e 'js2-warning))))
+
+(defun js2-echo-error (arg1 arg2 &optional _arg3)
+  "Called by point-motion hooks.
+ARG1, ARG2 and ARG3 have different values depending on whether this function
+was found on `point-entered' or in `cursor-sensor-functions'."
+  (let* ((new-point (if (windowp arg1)
+                        ;; Called from cursor-sensor-functions.
+                        (window-point arg1)
+                      ;; Called from point-left.
+                      arg2))
+         (msg (get-text-property new-point 'help-echo)))
+    (when (and (stringp msg)
+               (not (active-minibuffer-window))
+               (not (current-message)))
+      (message msg))))
+
+(defun js2-line-break (&optional _soft)
+  "Break line at point and indent, continuing comment if within one.
+If inside a string, and `js2-concat-multiline-strings' is not
+nil, turn it into concatenation."
+  (interactive)
+  (let ((parse-status (syntax-ppss)))
+    (cond
+     ;; Check if we're inside a string.
+     ((nth 3 parse-status)
+      (if js2-concat-multiline-strings
+          (js2-mode-split-string parse-status)
+        (insert "\n")))
+     ;; Check if inside a block comment.
+     ((nth 4 parse-status)
+      (js2-mode-extend-comment (nth 8 parse-status)))
+     (t
+      (newline-and-indent)))))
+
+(defun js2-mode-split-string (parse-status)
+  "Turn a newline in mid-string into a string concatenation.
+PARSE-STATUS is as documented in `parse-partial-sexp'."
+  (let* ((quote-char (nth 3 parse-status))
+         (at-eol (eq js2-concat-multiline-strings 'eol)))
+    (insert quote-char)
+    (insert (if at-eol " +\n" "\n"))
+    (unless at-eol
+      (insert "+ "))
+    (js2-indent-line)
+    (insert quote-char)
+    (when (eolp)
+      (insert quote-char)
+      (backward-char 1))))
+
+(defun js2-mode-extend-comment (start-pos)
+  "Indent the line and, when inside a comment block, add comment prefix."
+  (let (star single col first-line needs-close)
+    (save-excursion
+      (back-to-indentation)
+      (when (< (point) start-pos)
+        (goto-char start-pos))
+      (cond
+       ((looking-at "\\*[^/]")
+        (setq star t
+              col (current-column)))
+       ((looking-at "/\\*")
+        (setq star t
+              first-line t
+              col (1+ (current-column))))
+       ((looking-at "//")
+        (setq single t
+              col (current-column)))))
+    ;; Heuristic for whether we need to close the comment:
+    ;; if we've got a parse error here, assume it's an unterminated
+    ;; comment.
+    (setq needs-close
+          (or
+           (get-char-property (1- (point)) 'js2-error)
+           ;; The heuristic above doesn't work well when we're
+           ;; creating a comment and there's another one downstream,
+           ;; as our parser thinks this one ends at the end of the
+           ;; next one.  (You can have a /* inside a js block comment.)
+           ;; So just close it if the next non-ws char isn't a *.
+           (and first-line
+                (eolp)
+                (save-excursion
+                  (skip-chars-forward " \t\r\n")
+                  (not (eq (char-after) ?*))))))
+    (delete-horizontal-space)
+    (insert "\n")
+    (cond
+     (star
+      (indent-to col)
+      (insert "* ")
+      (if (and first-line needs-close)
+          (save-excursion
+            (insert "\n")
+            (indent-to col)
+            (insert "*/"))))
+     (single
+      (indent-to col)
+      (insert "// ")))
+    ;; Don't need to extend the comment after all.
+    (js2-indent-line)))
+
+(defun js2-beginning-of-line ()
+  "Toggle point between bol and first non-whitespace char in line.
+Also moves past comment delimiters when inside comments."
+  (interactive)
+  (let (node)
+    (cond
+     ((bolp)
+      (back-to-indentation))
+     ((looking-at "//")
+      (skip-chars-forward "/ \t"))
+     ((and (eq (char-after) ?*)
+           (setq node (js2-comment-at-point))
+           (memq (js2-comment-node-format node) '(jsdoc block))
+           (save-excursion
+             (skip-chars-backward " \t")
+             (bolp)))
+      (skip-chars-forward "\* \t"))
+     (t
+      (goto-char (point-at-bol))))))
+
+(defun js2-end-of-line ()
+  "Toggle point between eol and last non-whitespace char in line."
+  (interactive)
+  (if (eolp)
+      (skip-chars-backward " \t")
+    (goto-char (point-at-eol))))
+
+(defun js2-mode-wait-for-parse (callback)
+  "Invoke CALLBACK when parsing is finished.
+If parsing is already finished, calls CALLBACK immediately."
+  (if (not js2-mode-buffer-dirty-p)
+      (funcall callback)
+    (push callback js2-mode-pending-parse-callbacks)
+    (add-hook 'js2-parse-finished-hook #'js2-mode-parse-finished)))
+
+(defun js2-mode-parse-finished ()
+  "Invoke callbacks in `js2-mode-pending-parse-callbacks'."
+  ;; We can't let errors propagate up, since it prevents the
+  ;; `js2-parse' method from completing normally and returning
+  ;; the ast, which makes things mysteriously not work right.
+  (unwind-protect
+      (dolist (cb js2-mode-pending-parse-callbacks)
+        (condition-case err
+            (funcall cb)
+          (error (message "%s" err))))
+    (setq js2-mode-pending-parse-callbacks nil)))
+
+(defun js2-mode-flag-region (from to flag)
+  "Hide or show text from FROM to TO, according to FLAG.
+If FLAG is nil then text is shown, while if FLAG is t the text is hidden.
+Returns the created overlay if FLAG is non-nil."
+  (remove-overlays from to 'invisible 'js2-outline)
+  (when flag
+    (let ((o (make-overlay from to)))
+      (overlay-put o 'invisible 'js2-outline)
+      (overlay-put o 'isearch-open-invisible
+                   'js2-isearch-open-invisible)
+      o)))
+
+;; Function to be set as an outline-isearch-open-invisible' property
+;; to the overlay that makes the outline invisible (see
+;; `js2-mode-flag-region').
+(defun js2-isearch-open-invisible (_overlay)
+  ;; We rely on the fact that isearch places point on the matched text.
+  (js2-mode-show-element))
+
+(defun js2-mode-invisible-overlay-bounds (&optional pos)
+  "Return cons cell of bounds of folding overlay at POS.
+Returns nil if not found."
+  (let ((overlays (overlays-at (or pos (point))))
+        o)
+    (while (and overlays
+                (not o))
+      (if (overlay-get (car overlays) 'invisible)
+          (setq o (car overlays))
+        (setq overlays (cdr overlays))))
+    (if o
+        (cons (overlay-start o) (overlay-end o)))))
+
+(defun js2-mode-function-at-point (&optional pos)
+  "Return the innermost function node enclosing current point.
+Returns nil if point is not in a function."
+  (let ((node (js2-node-at-point pos)))
+    (while (and node (not (js2-function-node-p node)))
+      (setq node (js2-node-parent node)))
+    (if (js2-function-node-p node)
+        node)))
+
+(defun js2-mode-toggle-element ()
+  "Hide or show the foldable element at the point."
+  (interactive)
+  (let (comment fn pos)
+    (save-excursion
+      (cond
+       ;; /* ... */ comment?
+       ((js2-block-comment-p (setq comment (js2-comment-at-point)))
+        (if (js2-mode-invisible-overlay-bounds
+             (setq pos (+ 3 (js2-node-abs-pos comment))))
+            (progn
+              (goto-char pos)
+              (js2-mode-show-element))
+          (js2-mode-hide-element)))
+       ;; //-comment?
+       ((save-excursion
+          (back-to-indentation)
+          (looking-at js2-mode-//-comment-re))
+        (js2-mode-toggle-//-comment))
+       ;; function?
+       ((setq fn (js2-mode-function-at-point))
+        (setq pos (and (js2-function-node-body fn)
+                       (js2-node-abs-pos (js2-function-node-body fn))))
+        (goto-char (1+ pos))
+        (if (js2-mode-invisible-overlay-bounds)
+            (js2-mode-show-element)
+          (js2-mode-hide-element)))
+       (t
+        (message "Nothing at point to hide or show"))))))
+
+(defun js2-mode-hide-element ()
+  "Fold/hide contents of a block, showing ellipses.
+Show the hidden text with \\[js2-mode-show-element]."
+  (interactive)
+  (if js2-mode-buffer-dirty-p
+      (js2-mode-wait-for-parse #'js2-mode-hide-element))
+  (let (node body beg end)
+    (cond
+     ((js2-mode-invisible-overlay-bounds)
+      (message "already hidden"))
+     (t
+      (setq node (js2-node-at-point))
+      (cond
+       ((js2-block-comment-p node)
+        (js2-mode-hide-comment node))
+       (t
+        (while (and node (not (js2-function-node-p node)))
+          (setq node (js2-node-parent node)))
+        (if (and node
+                 (setq body (js2-function-node-body node)))
+            (progn
+              (setq beg (js2-node-abs-pos body)
+                    end (+ beg (js2-node-len body)))
+              (js2-mode-flag-region (1+ beg) (1- end) 'hide))
+          (message "No collapsable element found at point"))))))))
+
+(defun js2-mode-show-element ()
+  "Show the hidden element at current point."
+  (interactive)
+  (let ((bounds (js2-mode-invisible-overlay-bounds)))
+    (if bounds
+        (js2-mode-flag-region (car bounds) (cdr bounds) nil)
+      (message "Nothing to un-hide"))))
+
+(defun js2-mode-show-all ()
+  "Show all of the text in the buffer."
+  (interactive)
+  (js2-mode-flag-region (point-min) (point-max) nil))
+
+(defun js2-mode-toggle-hide-functions ()
+  (interactive)
+  (if js2-mode-functions-hidden
+      (js2-mode-show-functions)
+    (js2-mode-hide-functions)))
+
+(defun js2-mode-hide-functions ()
+  "Hides all non-nested function bodies in the buffer.
+Use \\[js2-mode-show-all] to reveal them, or \\[js2-mode-show-element]
+to open an individual entry."
+  (interactive)
+  (if js2-mode-buffer-dirty-p
+      (js2-mode-wait-for-parse #'js2-mode-hide-functions))
+  (if (null js2-mode-ast)
+      (message "Oops - parsing failed")
+    (setq js2-mode-functions-hidden t)
+    (js2-visit-ast js2-mode-ast #'js2-mode-function-hider)))
+
+(defun js2-mode-function-hider (n endp)
+  (when (not endp)
+    (let ((tt (js2-node-type n))
+          body beg end)
+      (cond
+       ((and (= tt js2-FUNCTION)
+             (setq body (js2-function-node-body n)))
+        (setq beg (js2-node-abs-pos body)
+              end (+ beg (js2-node-len body)))
+        (js2-mode-flag-region (1+ beg) (1- end) 'hide)
+        nil)   ; don't process children of function
+       (t
+        t))))) ; keep processing other AST nodes
+
+(defun js2-mode-show-functions ()
+  "Un-hide any folded function bodies in the buffer."
+  (interactive)
+  (setq js2-mode-functions-hidden nil)
+  (save-excursion
+    (goto-char (point-min))
+    (while (/= (goto-char (next-overlay-change (point)))
+               (point-max))
+      (dolist (o (overlays-at (point)))
+        (when (and (overlay-get o 'invisible)
+                   (not (overlay-get o 'comment)))
+          (js2-mode-flag-region (overlay-start o) (overlay-end o) nil))))))
+
+(defun js2-mode-hide-comment (n)
+  (let* ((head (if (eq (js2-comment-node-format n) 'jsdoc)
+                   3  ; /**
+                 2))  ; /*
+         (beg (+ (js2-node-abs-pos n) head))
+         (end (- (+ beg (js2-node-len n)) head 2))
+         (o (js2-mode-flag-region beg end 'hide)))
+    (overlay-put o 'comment t)))
+
+(defun js2-mode-toggle-hide-comments ()
+  "Folds all block comments in the buffer.
+Use \\[js2-mode-show-all] to reveal them, or \\[js2-mode-show-element]
+to open an individual entry."
+  (interactive)
+  (if js2-mode-comments-hidden
+      (js2-mode-show-comments)
+    (js2-mode-hide-comments)))
+
+(defun js2-mode-hide-comments ()
+  (interactive)
+  (if js2-mode-buffer-dirty-p
+      (js2-mode-wait-for-parse #'js2-mode-hide-comments))
+  (if (null js2-mode-ast)
+      (message "Oops - parsing failed")
+    (setq js2-mode-comments-hidden t)
+    (dolist (n (js2-ast-root-comments js2-mode-ast))
+      (when (js2-block-comment-p n)
+        (js2-mode-hide-comment n)))
+    (js2-mode-hide-//-comments)))
+
+(defun js2-mode-extend-//-comment (direction)
+  "Find start or end of a block of similar //-comment lines.
+DIRECTION is -1 to look back, 1 to look forward.
+INDENT is the indentation level to match.
+Returns the end-of-line position of the furthest adjacent
+//-comment line with the same indentation as the current line.
+If there is no such matching line, returns current end of line."
+  (let ((pos (point-at-eol))
+        (indent (current-indentation)))
+    (save-excursion
+      (while (and (zerop (forward-line direction))
+                  (looking-at js2-mode-//-comment-re)
+                  (eq indent (length (match-string 1))))
+        (setq pos (point-at-eol)))
+      pos)))
+
+(defun js2-mode-hide-//-comments ()
+  "Fold adjacent 1-line comments, showing only snippet of first one."
+  (let (beg end)
+    (save-excursion
+      (goto-char (point-min))
+      (while (re-search-forward js2-mode-//-comment-re nil t)
+        (setq beg (point)
+              end (js2-mode-extend-//-comment 1))
+        (unless (eq beg end)
+          (overlay-put (js2-mode-flag-region beg end 'hide)
+                       'comment t))
+        (goto-char end)
+        (forward-char 1)))))
+
+(defun js2-mode-toggle-//-comment ()
+  "Fold or un-fold any multi-line //-comment at point.
+Caller should have determined that this line starts with a //-comment."
+  (let* ((beg (point-at-eol))
+         (end beg))
+    (save-excursion
+      (goto-char end)
+      (if (js2-mode-invisible-overlay-bounds)
+          (js2-mode-show-element)
+        ;; else hide the comment
+        (setq beg (js2-mode-extend-//-comment -1)
+              end (js2-mode-extend-//-comment 1))
+        (unless (eq beg end)
+          (overlay-put (js2-mode-flag-region beg end 'hide)
+                       'comment t))))))
+
+(defun js2-mode-show-comments ()
+  "Un-hide any hidden comments, leaving other hidden elements alone."
+  (interactive)
+  (setq js2-mode-comments-hidden nil)
+  (save-excursion
+    (goto-char (point-min))
+    (while (/= (goto-char (next-overlay-change (point)))
+               (point-max))
+      (dolist (o (overlays-at (point)))
+        (when (overlay-get o 'comment)
+          (js2-mode-flag-region (overlay-start o) (overlay-end o) nil))))))
+
+(defun js2-mode-display-warnings-and-errors ()
+  "Turn on display of warnings and errors."
+  (interactive)
+  (setq js2-mode-show-parse-errors t
+        js2-mode-show-strict-warnings t)
+  (js2-reparse 'force))
+
+(defun js2-mode-hide-warnings-and-errors ()
+  "Turn off display of warnings and errors."
+  (interactive)
+  (setq js2-mode-show-parse-errors nil
+        js2-mode-show-strict-warnings nil)
+  (js2-reparse 'force))
+
+(defun js2-mode-toggle-warnings-and-errors ()
+  "Toggle the display of warnings and errors.
+Some users don't like having warnings/errors reported while they type."
+  (interactive)
+  (setq js2-mode-show-parse-errors (not js2-mode-show-parse-errors)
+        js2-mode-show-strict-warnings (not js2-mode-show-strict-warnings))
+  (if (called-interactively-p 'any)
+      (message "warnings and errors %s"
+               (if js2-mode-show-parse-errors
+                   "enabled"
+                 "disabled")))
+  (js2-reparse 'force))
+
+(defun js2-mode-customize ()
+  (interactive)
+  (customize-group 'js2-mode))
+
+(defun js2-mode-forward-sexp (&optional arg)
+  "Move forward across one statement or balanced expression.
+With ARG, do it that many times.  Negative arg -N means
+move backward across N balanced expressions."
+  (interactive "p")
+  (setq arg (or arg 1))
+  (save-restriction
+    (widen) ;; `blink-matching-open' calls `narrow-to-region'
+    (js2-reparse)
+    (let (forward-sexp-function
+          node (start (point)) pos lp rp child)
+      (cond
+       ((js2-string-node-p (js2-node-at-point))
+        (forward-sexp arg))
+       ;; backward-sexp
+       ;; could probably make this better for some cases:
+       ;;  - if in statement block (e.g. function body), go to parent
+       ;;  - infix exprs like (foo in bar) - maybe go to beginning
+       ;;    of infix expr if in the right-side expression?
+       ((and arg (cl-minusp arg))
+        (dotimes (_ (- arg))
+          (js2-backward-sws)
+          (forward-char -1)   ; Enter the node we backed up to.
+          (when (setq node (js2-node-at-point (point) t))
+            (setq pos (js2-node-abs-pos node))
+            (let ((parens (js2-mode-forward-sexp-parens node pos)))
+              (setq lp (car parens)
+                    rp (cdr parens)))
+            (when (and lp (> start lp))
+              (if (and rp (<= start rp))
+                  ;; Between parens, check if there's a child node we can jump.
+                  (when (setq child (js2-node-closest-child node (point) lp t))
+                    (setq pos (js2-node-abs-pos child)))
+                ;; Before both parens.
+                (setq pos lp)))
+            (let ((state (parse-partial-sexp start pos)))
+              (goto-char (if (not (zerop (car state)))
+                             ;; Stumble at the unbalanced paren if < 0, or
+                             ;; jump a bit further if > 0.
+                             (scan-sexps start -1)
+                           pos))))
+          (unless pos (goto-char (point-min)))))
+       (t
+        ;; forward-sexp
+        (dotimes (_ arg)
+          (js2-forward-sws)
+          (when (setq node (js2-node-at-point (point) t))
+            (setq pos (js2-node-abs-pos node))
+            (let ((parens (js2-mode-forward-sexp-parens node pos)))
+              (setq lp (car parens)
+                    rp (cdr parens)))
+            (or
+             (when (and rp (<= start rp))
+               (if (> start lp)
+                   (when (setq child (js2-node-closest-child node (point) rp))
+                     (setq pos (js2-node-abs-end child)))
+                 (setq pos (1+ rp))))
+             ;; No parens or child nodes, looks for the end of the current node.
+             (cl-incf pos (js2-node-len
+                           (if (js2-expr-stmt-node-p (js2-node-parent node))
+                               ;; Stop after the semicolon.
+                               (js2-node-parent node)
+                             node))))
+            (let ((state (save-excursion (parse-partial-sexp start pos))))
+              (goto-char (if (not (zerop (car state)))
+                             (scan-sexps start 1)
+                           pos))))
+          (unless pos (goto-char (point-max)))))))))
+
+(defun js2-mode-forward-sexp-parens (node abs-pos)
+  "Return a cons cell with positions of main parens in NODE."
+  (cond
+   ((or (js2-array-node-p node)
+        (js2-object-node-p node)
+        (js2-comp-node-p node)
+        (memq (aref node 0) '(cl-struct-js2-block-node cl-struct-js2-scope)))
+    (cons abs-pos (+ abs-pos (js2-node-len node) -1)))
+   ((js2-paren-expr-node-p node)
+    (let ((lp (js2-node-lp node))
+          (rp (js2-node-rp node)))
+      (cons (when lp (+ abs-pos lp))
+            (when rp (+ abs-pos rp)))))))
+
+(defun js2-node-closest-child (parent point limit &optional before)
+  (let* ((parent-pos (js2-node-abs-pos parent))
+         (rpoint (- point parent-pos))
+         (rlimit (- limit parent-pos))
+         (min (min rpoint rlimit))
+         (max (max rpoint rlimit))
+         found)
+    (catch 'done
+      (js2-visit-ast
+       parent
+       (lambda (node _end-p)
+         (if (eq node parent)
+             t
+           (let ((pos (js2-node-pos node)) ;; Both relative values.
+                 (end (+ (js2-node-pos node) (js2-node-len node))))
+             (when (and (>= pos min) (<= end max)
+                        (if before (< pos rpoint) (> end rpoint)))
+               (setq found node))
+             (when (> end rpoint)
+               (throw 'done nil)))
+           nil))))
+    found))
+
+(defun js2-errors ()
+  "Return a list of errors found."
+  (and js2-mode-ast
+       (js2-ast-root-errors js2-mode-ast)))
+
+(defun js2-warnings ()
+  "Return a list of warnings found."
+  (and js2-mode-ast
+       (js2-ast-root-warnings js2-mode-ast)))
+
+(defun js2-have-errors-p ()
+  "Return non-nil if any parse errors or warnings were found."
+  (or (js2-errors) (js2-warnings)))
+
+(defun js2-errors-and-warnings ()
+  "Return a copy of the concatenated errors and warnings lists.
+They are appended:  first the errors, then the warnings.
+Entries are of the form (MSG BEG END)."
+  (when js2-mode-ast
+    (append (js2-ast-root-errors js2-mode-ast)
+            (copy-sequence (js2-ast-root-warnings js2-mode-ast)))))
+
+(defun js2-next-error (&optional arg reset)
+  "Move to next parse error.
+Typically invoked via \\[next-error].
+ARG is the number of errors, forward or backward, to move.
+RESET means start over from the beginning."
+  (interactive "p")
+  (if (not (or (js2-errors) (js2-warnings)))
+      (message "No errors")
+    (when reset
+      (goto-char (point-min)))
+    (let* ((errs (js2-errors-and-warnings))
+           (continue t)
+           (start (point))
+           (count (or arg 1))
+           (backward (cl-minusp count))
+           (sorter (if backward '> '<))
+           (stopper (if backward '< '>))
+           (count (abs count))
+           all-errs err)
+      ;; Sort by start position.
+      (setq errs (sort errs (lambda (e1 e2)
+                              (funcall sorter (cl-second e1) (cl-second e2))))
+            all-errs errs)
+      ;; Find nth error with pos > start.
+      (while (and errs continue)
+        (when (funcall stopper (cl-cadar errs) start)
+          (setq err (car errs))
+          (if (zerop (cl-decf count))
+              (setq continue nil)))
+        (setq errs (cdr errs)))
+      ;; Clear for `js2-echo-error'.
+      (message nil)
+      (if err
+          (goto-char (cl-second err))
+        ;; Wrap around to first error.
+        (goto-char (cl-second (car all-errs)))
+        ;; If we were already on it, echo msg again.
+        (if (= (point) start)
+            (js2-echo-error (point) (point)))))))
+
+(defun js2-down-mouse-3 ()
+  "Make right-click move the point to the click location.
+This makes right-click context menu operations a bit more intuitive.
+The point will not move if the region is active, however, to avoid
+destroying the region selection."
+  (interactive)
+  (when (and js2-move-point-on-right-click
+             (not mark-active))
+    (let ((e last-input-event))
+      (ignore-errors
+        (goto-char (cl-cadadr e))))))
+
+(defun js2-mode-create-imenu-index ()
+  "Returns an alist for `imenu--index-alist'. Returns nil on first
+scan if buffer size > `imenu-auto-rescan-maxout'."
+  (when (and (not js2-mode-ast)
+             (<= (buffer-size) imenu-auto-rescan-maxout))
+      (js2-reparse))
+  (when js2-mode-ast
+    ;; if we have an ast but no recorder, they're requesting a rescan
+    (unless js2-imenu-recorder
+      (js2-reparse 'force))
+    (prog1
+        (js2-build-imenu-index)
+      (setq js2-imenu-recorder nil
+            js2-imenu-function-map nil))))
+
+(defun js2-mode-find-tag ()
+  "Replacement for `find-tag-default'.
+`find-tag-default' returns a ridiculous answer inside comments."
+  (let (beg end)
+    (save-excursion
+      (if (looking-at "\\_>")
+          (setq beg (progn (forward-symbol -1) (point))
+                end (progn (forward-symbol 1) (point)))
+        (setq beg (progn (forward-symbol 1) (point))
+              end (progn (forward-symbol -1) (point))))
+      (replace-regexp-in-string
+       "[\"']" ""
+       (buffer-substring-no-properties beg end)))))
+
+(defun js2-mode-forward-sibling ()
+  "Move to the end of the sibling following point in parent.
+Returns non-nil if successful, or nil if there was no following sibling."
+  (let* ((node (js2-node-at-point))
+         (parent (js2-mode-find-enclosing-fn node))
+         sib)
+    (when (setq sib (js2-node-find-child-after (point) parent))
+      (goto-char (+ (js2-node-abs-pos sib)
+                    (js2-node-len sib))))))
+
+(defun js2-mode-backward-sibling ()
+  "Move to the beginning of the sibling node preceding point in parent.
+Parent is defined as the enclosing script or function."
+  (let* ((node (js2-node-at-point))
+         (parent (js2-mode-find-enclosing-fn node))
+         sib)
+    (when (setq sib (js2-node-find-child-before (point) parent))
+      (goto-char (js2-node-abs-pos sib)))))
+
+(defun js2-beginning-of-defun (&optional arg)
+  "Go to line on which current function starts, and return t on success.
+If we're not in a function or already at the beginning of one, go
+to beginning of previous script-level element.
+With ARG N, do that N times. If N is negative, move forward."
+  (setq arg (or arg 1))
+  (if (cl-plusp arg)
+      (let ((parent (js2-node-parent-script-or-fn (js2-node-at-point))))
+        (when (cond
+               ((js2-function-node-p parent)
+                (goto-char (js2-node-abs-pos parent)))
+               (t
+                (js2-mode-backward-sibling)))
+          (if (> arg 1)
+              (js2-beginning-of-defun (1- arg))
+            t)))
+    (when (js2-end-of-defun)
+      (js2-beginning-of-defun (if (>= arg -1) 1 (1+ arg))))))
+
+(defun js2-end-of-defun ()
+  "Go to the char after the last position of the current function
+or script-level element."
+  (let* ((node (js2-node-at-point))
+         (parent (or (and (js2-function-node-p node) node)
+                     (js2-node-parent-script-or-fn node)))
+         script)
+    (unless (js2-function-node-p parent)
+      ;; Use current script-level node, or, if none, the next one.
+      (setq script (or parent node)
+            parent (js2-node-find-child-before (point) script))
+      (when (or (null parent)
+                (>= (point) (+ (js2-node-abs-pos parent)
+                               (js2-node-len parent))))
+        (setq parent (js2-node-find-child-after (point) script))))
+    (when parent
+      (goto-char (+ (js2-node-abs-pos parent)
+                    (js2-node-len parent))))))
+
+(defun js2-mark-defun (&optional allow-extend)
+  "Put mark at end of this function, point at beginning.
+The function marked is the one that contains point.
+
+Interactively, if this command is repeated,
+or (in Transient Mark mode) if the mark is active,
+it marks the next defun after the ones already marked."
+  (interactive "p")
+  (let (extended)
+    (when (and allow-extend
+               (or (and (eq last-command this-command) (mark t))
+                   (and transient-mark-mode mark-active)))
+      (let ((sib (save-excursion
+                   (goto-char (mark))
+                   (if (js2-mode-forward-sibling)
+                       (point)))))
+        (if sib
+            (progn
+              (set-mark sib)
+              (setq extended t))
+          ;; no more siblings - try extending to enclosing node
+          (goto-char (mark t)))))
+   (when (not extended)
+     (let ((node (js2-node-at-point (point) t)) ; skip comments
+           ast fn stmt parent beg end)
+       (when (js2-ast-root-p node)
+         (setq ast node
+               node (or (js2-node-find-child-after (point) node)
+                        (js2-node-find-child-before (point) node))))
+       ;; only mark whole buffer if we can't find any children
+       (if (null node)
+           (setq node ast))
+       (if (js2-function-node-p node)
+           (setq parent node)
+         (setq fn (js2-mode-find-enclosing-fn node)
+               stmt (if (or (null fn)
+                            (js2-ast-root-p fn))
+                        (js2-mode-find-first-stmt node))
+               parent (or stmt fn)))
+       (setq beg (js2-node-abs-pos parent)
+             end (+ beg (js2-node-len parent)))
+       (push-mark beg)
+       (goto-char end)
+       (exchange-point-and-mark)))))
+
+(defun js2-narrow-to-defun ()
+  "Narrow to the function enclosing point."
+  (interactive)
+  (let* ((node (js2-node-at-point (point) t))  ; skip comments
+         (fn (if (js2-script-node-p node)
+                 node
+               (js2-mode-find-enclosing-fn node)))
+         (beg (js2-node-abs-pos fn)))
+    (unless (js2-ast-root-p fn)
+      (narrow-to-region beg (+ beg (js2-node-len fn))))))
+
+(defun js2-jump-to-definition (&optional arg)
+  "Jump to the definition of an object's property, variable or function."
+  (interactive "P")
+  (if (eval-when-compile (fboundp 'xref-push-marker-stack))
+      (xref-push-marker-stack)
+    (ring-insert find-tag-marker-ring (point-marker)))
+  (js2-reparse)
+  (let* ((node (js2-node-at-point))
+         (parent (js2-node-parent node))
+         (names (if (js2-prop-get-node-p parent)
+                    (reverse (let ((temp (js2-compute-nested-prop-get parent)))
+                               (cl-loop for n in temp
+                                        with result = '()
+                                        do (push n result)
+                                        until (equal node n)
+                                        finally return result)))))
+         node-init)
+    (unless (and (js2-name-node-p node)
+                 (not (js2-var-init-node-p parent))
+                 (not (js2-function-node-p parent)))
+      (error "Node is not a supported jump node"))
+    (push (or (and names (pop names))
+              (unless (and (js2-object-prop-node-p parent)
+                           (eq node (js2-object-prop-node-left parent)))
+                node)) names)
+    (setq node-init (js2-search-scope node names))
+
+    ;; todo: display list of results in buffer
+    ;; todo: group found references by buffer
+    (unless node-init
+      (switch-to-buffer
+       (catch 'found
+         (unless arg
+           (mapc (lambda (b)
+                   (with-current-buffer b
+                     (when (derived-mode-p 'js2-mode)
+                       (setq node-init (js2-search-scope js2-mode-ast names))
+                       (if node-init
+                           (throw 'found b)))))
+                 (buffer-list)))
+         nil)))
+    (setq node-init (if (listp node-init) (car node-init) node-init))
+    (unless node-init
+      (pop-tag-mark)
+      (error "No jump location found"))
+    (goto-char (js2-node-abs-pos node-init))))
+
+(defun js2-search-object (node name-node)
+  "Check if object NODE contains element with NAME-NODE."
+  (cl-assert (js2-object-node-p node))
+  ;; Only support name-node and nodes for the time being
+  (cl-loop for elem in (js2-object-node-elems node)
+           for left = (js2-object-prop-node-left elem)
+           if (or (and (js2-name-node-p left)
+                       (equal (js2-name-node-name name-node)
+                              (js2-name-node-name left)))
+                  (and (js2-string-node-p left)
+                       (string= (js2-name-node-name name-node)
+                                (js2-string-node-value left))))
+           return elem))
+
+(defun js2-search-object-for-prop (object prop-names)
+  "Return node in OBJECT that matches PROP-NAMES or nil.
+PROP-NAMES is a list of values representing a path to a value in OBJECT.
+i.e. ('name' 'value') = {name : { value: 3}}"
+  (let (node
+        (temp-object object)
+        (temp t) ;temporay node
+        (names prop-names))
+    (while (and temp names (js2-object-node-p temp-object))
+      (setq temp (js2-search-object temp-object (pop names)))
+      (and (setq node temp)
+         (setq temp-object (js2-object-prop-node-right temp))))
+    (unless names node)))
+
+(defun js2-search-scope (node names)
+  "Searches NODE scope for jump location matching NAMES.
+NAMES is a list of property values to search for. For functions
+and variables NAMES will contain one element."
+  (let (node-init
+        (val (js2-name-node-name (car names))))
+    (setq node-init (js2-get-symbol-declaration node val))
+
+    (when (> (length names) 1)
+
+      ;; Check var declarations
+      (when (and node-init (string= val (js2-name-node-name node-init)))
+        (let ((parent (js2-node-parent node-init))
+              (temp-names names))
+          (pop temp-names) ;; First element is var name
+          (setq node-init (when (js2-var-init-node-p parent)
+                            (js2-search-object-for-prop
+                             (js2-var-init-node-initializer parent)
+                             temp-names)))))
+
+      ;; Check all assign nodes
+      (js2-visit-ast
+       js2-mode-ast
+       (lambda (node endp)
+         (unless endp
+           (if (js2-assign-node-p node)
+               (let ((left (js2-assign-node-left node))
+                     (right (js2-assign-node-right node))
+                     (temp-names names))
+                 (when (js2-prop-get-node-p left)
+                   (let* ((prop-list (js2-compute-nested-prop-get left))
+                          (found (cl-loop for prop in prop-list
+                                          until (not (string= (js2-name-node-name
+                                                               (pop temp-names))
+                                                              (js2-name-node-name prop)))
+                                          if (not temp-names) return prop))
+                          (found-node (or found
+                                          (when (js2-object-node-p right)
+                                            (js2-search-object-for-prop right
+                                                                        temp-names)))))
+                     (if found-node (push found-node node-init))))))
+           t))))
+    node-init))
+
+(defun js2-get-symbol-declaration (node name)
+  "Find scope for NAME from NODE."
+  (let ((scope (js2-get-defining-scope
+          (or (js2-node-get-enclosing-scope node)
+             node) name)))
+    (if scope (js2-symbol-ast-node (js2-scope-get-symbol scope name)))))
+
+(provide 'js2-mode)
+
+;;; js2-mode.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/js2-mode-20180627.744/js2-mode.elc b/configs/shared/emacs/.emacs.d/elpa/js2-mode-20180627.744/js2-mode.elc
new file mode 100644
index 0000000000..1db359a235
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/js2-mode-20180627.744/js2-mode.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/js2-mode-20180627.744/js2-old-indent.el b/configs/shared/emacs/.emacs.d/elpa/js2-mode-20180627.744/js2-old-indent.el
new file mode 100644
index 0000000000..5538736eb9
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/js2-mode-20180627.744/js2-old-indent.el
@@ -0,0 +1,712 @@
+;;; js2-old-indent.el --- Indentation code kept for compatibility
+
+;; Copyright (C) 2015  Free Software Foundation, Inc.
+
+;; 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:
+
+;; All features of this indentation code have been ported to Emacs's
+;; built-in `js-mode' by now, so we derive from it.  An older
+;; commentary follows.
+
+;; This code is kept for Emacs 24.5 and ealier.
+
+;; This indenter is based on Karl Landström's "javascript.el" indenter.
+;; Karl cleverly deduces that the desired indentation level is often a
+;; function of paren/bracket/brace nesting depth, which can be determined
+;; quickly via the built-in `parse-partial-sexp' function.  His indenter
+;; then does some equally clever checks to see if we're in the context of a
+;; substatement of a possibly braceless statement keyword such as if, while,
+;; or finally.  This approach yields pretty good results.
+
+;; The indenter is often "wrong", however, and needs to be overridden.
+;; The right long-term solution is probably to emulate (or integrate
+;; with) cc-engine, but it's a nontrivial amount of coding.  Even when a
+;; parse tree from `js2-parse' is present, which is not true at the
+;; moment the user is typing, computing indentation is still thousands
+;; of lines of code to handle every possible syntactic edge case.
+
+;; In the meantime, the compromise solution is that we offer a "bounce
+;; indenter", configured with `js2-bounce-indent-p', which cycles the
+;; current line indent among various likely guess points.  This approach
+;; is far from perfect, but should at least make it slightly easier to
+;; move the line towards its desired indentation when manually
+;; overriding Karl's heuristic nesting guesser.
+
+;; I've made miscellaneous tweaks to Karl's code to handle some Ecma
+;; extensions such as `let' and Array comprehensions.  Major kudos to
+;; Karl for coming up with the initial approach, which packs a lot of
+;; punch for so little code. -- Steve
+
+;;; Code:
+
+(require 'sgml-mode)
+
+(defvar js2-language-version)
+
+(declare-function js2-backward-sws "js2-mode")
+(declare-function js2-forward-sws "js2-mode")
+(declare-function js2-same-line "js2-mode")
+
+(defcustom js2-basic-offset (if (and (boundp 'c-basic-offset)
+                                     (numberp c-basic-offset))
+                                c-basic-offset
+                              4)
+  "Number of spaces to indent nested statements.
+Similar to `c-basic-offset'."
+  :group 'js2-mode
+  :safe 'integerp
+  :type 'integer)
+
+(defcustom js2-pretty-multiline-declarations t
+  "Non-nil to line up multiline declarations vertically:
+
+  var a = 10,
+      b = 20,
+      c = 30;
+
+If the value is t, and the first assigned value in the
+declaration is a function/array/object literal spanning several
+lines, it won't be indented additionally:
+
+  var o = {                   var bar = 2,
+    foo: 3          vs.           o = {
+  },                                foo: 3
+      bar = 2;                    };
+
+If the value is `all', it will always be indented additionally:
+
+  var o = {
+        foo: 3
+      };
+
+  var o = {
+        foo: 3
+      },
+      bar = 2;
+
+If the value is `dynamic', it will be indented additionally only
+if the declaration contains more than one variable:
+
+  var o = {
+    foo: 3
+  };
+
+  var o = {
+        foo: 3
+      },
+      bar = 2;"
+  :group 'js2-mode
+  :safe  'symbolp
+  :type 'symbol)
+
+(defcustom js2-indent-switch-body nil
+  "When nil, case labels are indented on the same level as the
+containing switch statement.  Otherwise, all lines inside
+switch statement body are indented one additional level."
+  :type 'boolean
+  :safe 'booleanp
+  :group 'js2-mode)
+
+(defconst js2-possibly-braceless-keywords-re
+  (concat "else[ \t]+if\\|for[ \t]+each\\|"
+          (regexp-opt '("catch" "do" "else" "finally" "for" "if"
+                        "try" "while" "with" "let")))
+  "Regular expression matching keywords that are optionally
+followed by an opening brace.")
+
+(defconst js2-indent-operator-re
+  (concat "[-+*/%<>&^|?:.]\\([^-+*/.]\\|$\\)\\|!?=\\|"
+          (regexp-opt '("in" "instanceof") 'symbols))
+  "Regular expression matching operators that affect indentation
+of continued expressions.")
+
+(defconst js2-declaration-keyword-re
+  (regexp-opt '("var" "let" "const") 'symbols)
+  "Regular expression matching variable declaration keywords.")
+
+(defun js2-re-search-forward-inner (regexp &optional bound count)
+  "Auxiliary function for `js2-re-search-forward'."
+  (let (parse saved-point)
+    (while (> count 0)
+      (re-search-forward regexp bound)
+      (setq parse (if saved-point
+                      (parse-partial-sexp saved-point (point))
+                    (syntax-ppss (point))))
+      (cond ((nth 3 parse)
+             (re-search-forward
+              (concat "\\(\\=\\|[^\\]\\|^\\)" (string (nth 3 parse)))
+              (save-excursion (end-of-line) (point)) t))
+            ((nth 7 parse)
+             (forward-line))
+            ((or (nth 4 parse)
+                 (and (eq (char-before) ?\/) (eq (char-after) ?\*)))
+             (re-search-forward "\\*/"))
+            (t
+             (setq count (1- count))))
+      (setq saved-point (point))))
+  (point))
+
+(defun js2-re-search-forward (regexp &optional bound noerror count)
+  "Search forward but ignore strings and comments.
+Invokes `re-search-forward' but treats the buffer as if strings
+and comments have been removed."
+  (let ((saved-point (point)))
+    (condition-case err
+        (cond ((null count)
+               (js2-re-search-forward-inner regexp bound 1))
+              ((< count 0)
+               (js2-re-search-backward-inner regexp bound (- count)))
+              ((> count 0)
+               (js2-re-search-forward-inner regexp bound count)))
+      (search-failed
+       (goto-char saved-point)
+       (unless noerror
+         (error (error-message-string err)))))))
+
+(defun js2-re-search-backward-inner (regexp &optional bound count)
+  "Auxiliary function for `js2-re-search-backward'."
+  (let (parse)
+    (while (> count 0)
+      (re-search-backward regexp bound)
+      (setq parse (syntax-ppss (point)))
+      (cond ((nth 3 parse)
+             (re-search-backward
+              (concat "\\([^\\]\\|^\\)" (string (nth 3 parse)))
+              (line-beginning-position) t))
+            ((nth 7 parse)
+             (goto-char (nth 8 parse)))
+            ((or (nth 4 parse)
+                 (and (eq (char-before) ?/) (eq (char-after) ?*)))
+             (re-search-backward "/\\*"))
+            (t
+             (setq count (1- count))))))
+  (point))
+
+(defun js2-re-search-backward (regexp &optional bound noerror count)
+  "Search backward but ignore strings and comments.
+Invokes `re-search-backward' but treats the buffer as if strings
+and comments have been removed."
+  (let ((saved-point (point)))
+    (condition-case err
+        (cond ((null count)
+               (js2-re-search-backward-inner regexp bound 1))
+              ((< count 0)
+               (js2-re-search-forward-inner regexp bound (- count)))
+              ((> count 0)
+               (js2-re-search-backward-inner regexp bound count)))
+      (search-failed
+       (goto-char saved-point)
+       (unless noerror
+         (error (error-message-string err)))))))
+
+(defun js2-looking-at-operator-p ()
+  "Return non-nil if text after point is a non-comma operator."
+  (defvar js2-mode-identifier-re)
+  (and (looking-at js2-indent-operator-re)
+       (or (not (eq (char-after) ?:))
+           (save-excursion
+             (and (js2-re-search-backward "[?:{]\\|\\_<case\\_>" nil t)
+                  (eq (char-after) ??))))
+       (not (and
+             (eq (char-after) ?/)
+             (save-excursion
+               (eq (nth 3 (syntax-ppss)) ?/))))
+       (not (and
+             (eq (char-after) ?*)
+             ;; Generator method (possibly using computed property).
+             (looking-at (concat "\\* *\\(?:\\[\\|"
+                                 js2-mode-identifier-re
+                                 " *(\\)"))
+             (save-excursion
+               (js2-backward-sws)
+               ;; We might misindent some expressions that would
+               ;; return NaN anyway.  Shouldn't be a problem.
+               (memq (char-before) '(?, ?} ?{)))))))
+
+(defun js2-continued-expression-p ()
+  "Return non-nil if the current line continues an expression."
+  (save-excursion
+    (back-to-indentation)
+    (if (js2-looking-at-operator-p)
+        (or (not (memq (char-after) '(?- ?+)))
+            (progn
+              (forward-comment (- (point)))
+              (not (memq (char-before) '(?, ?\[ ?\()))))
+      (forward-comment (- (point)))
+      (or (bobp) (backward-char))
+      (when (js2-looking-at-operator-p)
+        (backward-char)
+        (not (looking-at "\\*\\|\\+\\+\\|--\\|/[/*]"))))))
+
+(defun js2-end-of-do-while-loop-p ()
+  "Return non-nil if word after point is `while' of a do-while
+statement, else returns nil. A braceless do-while statement
+spanning several lines requires that the start of the loop is
+indented to the same column as the current line."
+  (interactive)
+  (save-excursion
+    (when (looking-at "\\s-*\\_<while\\_>")
+      (if (save-excursion
+            (skip-chars-backward "[ \t\n]*}")
+            (looking-at "[ \t\n]*}"))
+          (save-excursion
+            (backward-list) (backward-word 1) (looking-at "\\_<do\\_>"))
+        (js2-re-search-backward "\\_<do\\_>" (point-at-bol) t)
+        (or (looking-at "\\_<do\\_>")
+            (let ((saved-indent (current-indentation)))
+              (while (and (js2-re-search-backward "^[ \t]*\\_<" nil t)
+                          (/= (current-indentation) saved-indent)))
+              (and (looking-at "[ \t]*\\_<do\\_>")
+                   (not (js2-re-search-forward
+                         "\\_<while\\_>" (point-at-eol) t))
+                   (= (current-indentation) saved-indent))))))))
+
+(defun js2-multiline-decl-indentation ()
+  "Return the declaration indentation column if the current line belongs
+to a multiline declaration statement.  See `js2-pretty-multiline-declarations'."
+  (let (forward-sexp-function ; use Lisp version
+        at-opening-bracket)
+    (save-excursion
+      (back-to-indentation)
+      (when (not (looking-at js2-declaration-keyword-re))
+        (when (looking-at js2-indent-operator-re)
+          (goto-char (match-end 0))) ; continued expressions are ok
+        (while (and (not at-opening-bracket)
+                    (not (bobp))
+                    (let ((pos (point)))
+                      (save-excursion
+                        (js2-backward-sws)
+                        (or (eq (char-before) ?,)
+                            (and (not (eq (char-before) ?\;))
+                                 (prog2 (skip-syntax-backward ".")
+                                     (looking-at js2-indent-operator-re)
+                                   (js2-backward-sws))
+                                 (not (eq (char-before) ?\;)))
+                            (js2-same-line pos)))))
+          (condition-case _
+              (backward-sexp)
+            (scan-error (setq at-opening-bracket t))))
+        (when (looking-at js2-declaration-keyword-re)
+          (goto-char (match-end 0))
+          (1+ (current-column)))))))
+
+(defun js2-ctrl-statement-indentation ()
+  "Return the proper indentation of current line if it is a control statement.
+Returns an indentation if this line starts the body of a control
+statement without braces, else returns nil."
+  (let (forward-sexp-function)
+    (save-excursion
+      (back-to-indentation)
+      (when (and (not (js2-same-line (point-min)))
+                 (not (looking-at "{"))
+                 (js2-re-search-backward "[[:graph:]]" nil t)
+                 (not (looking-at "[{([]"))
+                 (progn
+                   (forward-char)
+                   (when (= (char-before) ?\))
+                     ;; scan-sexps sometimes throws an error
+                     (ignore-errors (backward-sexp))
+                     (skip-chars-backward " \t" (point-at-bol)))
+                   (let ((pt (point)))
+                     (back-to-indentation)
+                     (when (looking-at "}[ \t]*")
+                       (goto-char (match-end 0)))
+                     (and (looking-at js2-possibly-braceless-keywords-re)
+                          (= (match-end 0) pt)
+                          (not (js2-end-of-do-while-loop-p))))))
+        (+ (current-indentation) js2-basic-offset)))))
+
+(defun js2-indent-in-array-comp (parse-status)
+  "Return non-nil if we think we're in an array comprehension.
+In particular, return the buffer position of the first `for' kwd."
+  (let ((bracket (nth 1 parse-status))
+        (end (point)))
+    (when bracket
+      (save-excursion
+        (goto-char bracket)
+        (when (looking-at "\\[")
+          (forward-char 1)
+          (js2-forward-sws)
+          (if (looking-at "[[{]")
+              (let (forward-sexp-function) ; use Lisp version
+                (forward-sexp)             ; skip destructuring form
+                (js2-forward-sws)
+                (if (and (/= (char-after) ?,) ; regular array
+                         (looking-at "for"))
+                    (match-beginning 0)))
+            ;; to skip arbitrary expressions we need the parser,
+            ;; so we'll just guess at it.
+            (if (and (> end (point)) ; not empty literal
+                     (re-search-forward "[^,]]* \\(for\\) " end t)
+                     ;; not inside comment or string literal
+                     (let ((state (parse-partial-sexp bracket (point))))
+                       (and (= 1 (car state))
+                            (not (nth 8 state)))))
+                (match-beginning 1))))))))
+
+(defun js2-array-comp-indentation (parse-status for-kwd)
+  (if (js2-same-line for-kwd)
+      ;; first continuation line
+      (save-excursion
+        (goto-char (nth 1 parse-status))
+        (forward-char 1)
+        (skip-chars-forward " \t")
+        (current-column))
+    (save-excursion
+      (goto-char for-kwd)
+      (current-column))))
+
+(defun js2-maybe-goto-declaration-keyword-end (bracket)
+  "Helper function for `js2-proper-indentation'.
+Depending on the value of `js2-pretty-multiline-declarations',
+move point to the end of a variable declaration keyword so that
+indentation is aligned to that column."
+  (cond
+   ((eq js2-pretty-multiline-declarations 'all)
+    (when (looking-at js2-declaration-keyword-re)
+      (goto-char (1+ (match-end 0)))))
+   ((eq js2-pretty-multiline-declarations 'dynamic)
+    (let (declaration-keyword-end
+          at-closing-bracket-p
+          comma-p)
+      (when (looking-at js2-declaration-keyword-re)
+        ;; Preserve the match data lest it somehow be overridden.
+        (setq declaration-keyword-end (match-end 0))
+        (save-excursion
+          (goto-char bracket)
+          (setq at-closing-bracket-p
+                ;; Handle scan errors gracefully.
+                (condition-case nil
+                    (progn
+                      ;; Use the regular `forward-sexp-function' because the
+                      ;; normal one for this mode uses the AST.
+                      (let (forward-sexp-function)
+                        (forward-sexp))
+                      t)
+                  (error nil)))
+          (when at-closing-bracket-p
+            (js2-forward-sws)
+            (setq comma-p (looking-at-p ","))))
+        (when comma-p
+          (goto-char (1+ declaration-keyword-end))))))))
+
+(cl-defun js2-proper-indentation (parse-status)
+  "Return the proper indentation for the current line."
+  (save-excursion
+    (back-to-indentation)
+    (when (nth 4 parse-status)
+      (cl-return-from js2-proper-indentation (js2--comment-indent parse-status)))
+    (let* ((at-closing-bracket (looking-at "[]})]"))
+           (same-indent-p (or at-closing-bracket
+                              (looking-at "\\_<case\\_>[^:]")
+                              (and (looking-at "\\_<default:")
+                                   (save-excursion
+                                     (js2-backward-sws)
+                                     (not (memq (char-before) '(?, ?{)))))))
+           (continued-expr-p (js2-continued-expression-p))
+           (declaration-indent (and js2-pretty-multiline-declarations
+                                    (js2-multiline-decl-indentation)))
+           (bracket (nth 1 parse-status))
+           beg indent)
+      (cond
+       ;; indent array comprehension continuation lines specially
+       ((and bracket
+             (>= js2-language-version 170)
+             (not (js2-same-line bracket))
+             (setq beg (js2-indent-in-array-comp parse-status))
+             (>= (point) (save-excursion
+                           (goto-char beg)
+                           (point-at-bol)))) ; at or after first loop?
+        (js2-array-comp-indentation parse-status beg))
+
+       ((js2-ctrl-statement-indentation))
+
+       ((and declaration-indent continued-expr-p)
+        (+ declaration-indent js2-basic-offset))
+
+       (declaration-indent)
+
+       (bracket
+        (goto-char bracket)
+        (cond
+         ((looking-at "[({[][ \t]*\\(/[/*]\\|$\\)")
+          (when (save-excursion (skip-chars-backward " \t\n)")
+                                (looking-at ")"))
+            (backward-list))
+          (back-to-indentation)
+          (js2-maybe-goto-declaration-keyword-end bracket)
+          (setq indent
+                (cond (same-indent-p
+                       (current-column))
+                      (continued-expr-p
+                       (+ (current-column) (* 2 js2-basic-offset)))
+                      (t
+                       (+ (current-column) js2-basic-offset))))
+          (if (and js2-indent-switch-body
+                   (not at-closing-bracket)
+                   (looking-at "\\_<switch\\_>"))
+              (+ indent js2-basic-offset)
+            indent))
+         (t
+          (unless same-indent-p
+            (forward-char)
+            (skip-chars-forward " \t"))
+          (current-column))))
+
+       (continued-expr-p js2-basic-offset)
+
+       (t 0)))))
+
+(defun js2--comment-indent (parse-status)
+  "Indentation inside a multi-line block comment continuation line."
+  (save-excursion
+    (goto-char (nth 8 parse-status))
+    (if (looking-at "/\\*")
+        (+ 1 (current-column))
+      0)))
+
+(defun js2-indent-line (&optional bounce-backwards)
+  "Indent the current line as JavaScript source text."
+  (interactive)
+  (let (parse-status offset
+        ;; Don't whine about errors/warnings when we're indenting.
+        ;; This has to be set before calling parse-partial-sexp below.
+        (inhibit-point-motion-hooks t))
+    (setq parse-status (save-excursion
+                         (syntax-ppss (point-at-bol)))
+          offset (- (point) (save-excursion
+                              (back-to-indentation)
+                              (point))))
+    ;; Don't touch multiline strings.
+    (unless (nth 3 parse-status)
+      (indent-line-to (js2-proper-indentation parse-status))
+      (when (cl-plusp offset)
+        (forward-char offset)))))
+
+;;; JSX Indentation
+
+;; The following JSX indentation code is copied basically verbatim from js.el at
+;; 958da7f, except that the prefixes on the functions/variables are changed.
+
+(defsubst js2--jsx-find-before-tag ()
+  "Find where JSX starts.
+
+Assume JSX appears in the following instances:
+- Inside parentheses, when returned or as the first argument
+  to a function, and after a newline
+- When assigned to variables or object properties, but only
+  on a single line
+- As the N+1th argument to a function
+
+This is an optimized version of (re-search-backward \"[(,]\n\"
+nil t), except set point to the end of the match.  This logic
+executes up to the number of lines in the file, so it should be
+really fast to reduce that impact."
+  (let (pos)
+    (while (and (> (point) (point-min))
+                (not (progn
+                       (end-of-line 0)
+                       (when (or (eq (char-before) 40)   ; (
+                                 (eq (char-before) 44))  ; ,
+                         (setq pos (1- (point))))))))
+    pos))
+
+(defconst js2--jsx-end-tag-re
+  (concat "</" sgml-name-re ">\\|/>")
+  "Find the end of a JSX element.")
+
+(defconst js2--jsx-after-tag-re "[),]"
+  "Find where JSX ends.
+This complements the assumption of where JSX appears from
+`js--jsx-before-tag-re', which see.")
+
+(defun js2--jsx-indented-element-p ()
+  "Determine if/how the current line should be indented as JSX.
+
+Return `first' for the first JSXElement on its own line.
+Return `nth' for subsequent lines of the first JSXElement.
+Return `expression' for an embedded JS expression.
+Return `after' for anything after the last JSXElement.
+Return nil for non-JSX lines.
+
+Currently, JSX indentation supports the following styles:
+
+- Single-line elements (indented like normal JS):
+
+  var element = <div></div>;
+
+- Multi-line elements (enclosed in parentheses):
+
+  function () {
+    return (
+      <div>
+        <div></div>
+      </div>
+    );
+ }
+
+- Function arguments:
+
+  React.render(
+    <div></div>,
+    document.querySelector('.root')
+  );"
+  (let ((current-pos (point))
+        (current-line (line-number-at-pos))
+        last-pos
+        before-tag-pos before-tag-line
+        tag-start-pos tag-start-line
+        tag-end-pos tag-end-line
+        after-tag-line
+        parens paren type)
+    (save-excursion
+      (and
+       ;; Determine if we're inside a jsx element
+       (progn
+         (end-of-line)
+         (while (and (not tag-start-pos)
+                     (setq last-pos (js2--jsx-find-before-tag)))
+           (while (forward-comment 1))
+           (when (= (char-after) 60) ; <
+             (setq before-tag-pos last-pos
+                   tag-start-pos (point)))
+           (goto-char last-pos))
+         tag-start-pos)
+       (progn
+         (setq before-tag-line (line-number-at-pos before-tag-pos)
+               tag-start-line (line-number-at-pos tag-start-pos))
+         (and
+          ;; A "before" line which also starts an element begins with js, so
+          ;; indent it like js
+          (> current-line before-tag-line)
+          ;; Only indent the jsx lines like jsx
+          (>= current-line tag-start-line)))
+       (cond
+        ;; Analyze bounds if there are any
+        ((progn
+           (while (and (not tag-end-pos)
+                       (setq last-pos (re-search-forward js2--jsx-end-tag-re nil t)))
+             (while (forward-comment 1))
+             (when (looking-at js2--jsx-after-tag-re)
+               (setq tag-end-pos last-pos)))
+           tag-end-pos)
+         (setq tag-end-line (line-number-at-pos tag-end-pos)
+               after-tag-line (line-number-at-pos after-tag-line))
+         (or (and
+              ;; Ensure we're actually within the bounds of the jsx
+              (<= current-line tag-end-line)
+              ;; An "after" line which does not end an element begins with
+              ;; js, so indent it like js
+              (<= current-line after-tag-line))
+             (and
+              ;; Handle another case where there could be e.g. comments after
+              ;; the element
+              (> current-line tag-end-line)
+              (< current-line after-tag-line)
+              (setq type 'after))))
+        ;; They may not be any bounds (yet)
+        (t))
+       ;; Check if we're inside an embedded multi-line js expression
+       (cond
+        ((not type)
+         (goto-char current-pos)
+         (end-of-line)
+         (setq parens (nth 9 (syntax-ppss)))
+         (while (and parens (not type))
+           (setq paren (car parens))
+           (cond
+            ((and (>= paren tag-start-pos)
+                  ;; Curly bracket indicates the start of an embedded expression
+                  (= (char-after paren) 123) ; {
+                  ;; The first line of the expression is indented like sgml
+                  (> current-line (line-number-at-pos paren))
+                  ;; Check if within a closing curly bracket (if any)
+                  ;; (exclusive, as the closing bracket is indented like sgml)
+                  (cond
+                   ((progn
+                      (goto-char paren)
+                      (ignore-errors (let (forward-sexp-function)
+                                       (forward-sexp))))
+                    (< current-line (line-number-at-pos)))
+                   (t)))
+             ;; Indicate this guy will be indented specially
+             (setq type 'expression))
+            (t (setq parens (cdr parens)))))
+         t)
+        (t))
+       (cond
+        (type)
+        ;; Indent the first jsx thing like js so we can indent future jsx things
+        ;; like sgml relative to the first thing
+        ((= current-line tag-start-line) 'first)
+        ('nth))))))
+
+(defmacro js2--as-sgml (&rest body)
+  "Execute BODY as if in sgml-mode."
+  `(with-syntax-table sgml-mode-syntax-table
+     (let (forward-sexp-function
+           parse-sexp-lookup-properties)
+       ,@body)))
+
+(defun js2--expression-in-sgml-indent-line ()
+  "Indent the current line as JavaScript or SGML (whichever is farther)."
+  (let* (indent-col
+         (savep (point))
+         ;; Don't whine about errors/warnings when we're indenting.
+         ;; This has to be set before calling parse-partial-sexp below.
+         (inhibit-point-motion-hooks t)
+         (parse-status (save-excursion
+                         (syntax-ppss (point-at-bol)))))
+    ;; Don't touch multiline strings.
+    (unless (nth 3 parse-status)
+      (setq indent-col (save-excursion
+                         (back-to-indentation)
+                         (if (>= (point) savep) (setq savep nil))
+                         (js2--as-sgml (sgml-calculate-indent))))
+      (if (null indent-col)
+          'noindent
+        ;; Use whichever indentation column is greater, such that the sgml
+        ;; column is effectively a minimum
+        (setq indent-col (max (js2-proper-indentation parse-status)
+                              (+ indent-col js2-basic-offset)))
+        (if savep
+            (save-excursion (indent-line-to indent-col))
+          (indent-line-to indent-col))))))
+
+(defun js2-jsx-indent-line ()
+  "Indent the current line as JSX (with SGML offsets).
+i.e., customize JSX element indentation with `sgml-basic-offset'
+et al."
+  (interactive)
+  (let ((indentation-type (js2--jsx-indented-element-p)))
+    (cond
+     ((eq indentation-type 'expression)
+      (js2--expression-in-sgml-indent-line))
+     ((or (eq indentation-type 'first)
+          (eq indentation-type 'after))
+      ;; Don't treat this first thing as a continued expression (often a "<" or
+      ;; ">" causes this misinterpretation)
+      (cl-letf (((symbol-function #'js2-continued-expression-p) 'ignore))
+        (js2-indent-line)))
+     ((eq indentation-type 'nth)
+      (js2--as-sgml (sgml-indent-line)))
+     (t (js2-indent-line)))))
+
+(provide 'js2-old-indent)
+
+;;; js2-old-indent.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/js2-mode-20180627.744/js2-old-indent.elc b/configs/shared/emacs/.emacs.d/elpa/js2-mode-20180627.744/js2-old-indent.elc
new file mode 100644
index 0000000000..a226eada4f
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/js2-mode-20180627.744/js2-old-indent.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/json-mode-20180718.109/json-mode-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/json-mode-20180718.109/json-mode-autoloads.el
new file mode 100644
index 0000000000..39eefad272
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/json-mode-20180718.109/json-mode-autoloads.el
@@ -0,0 +1,58 @@
+;;; json-mode-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "json-mode" "json-mode.el" (23377 61611 162337
+;;;;;;  59000))
+;;; Generated autoloads from json-mode.el
+
+(defconst json-mode-standard-file-ext '(".json" ".jsonld") "\
+List of JSON file extensions.")
+
+(defsubst json-mode--update-auto-mode (filenames) "\
+Update the `json-mode' entry of `auto-mode-alist'.
+
+FILENAMES should be a list of file as string.
+Return the new `auto-mode-alist' entry" (let* ((new-regexp (rx-to-string (\` (seq (eval (cons (quote or) (append json-mode-standard-file-ext (quote (\, filenames))))) eot)))) (new-entry (cons new-regexp (quote json-mode))) (old-entry (when (boundp (quote json-mode--auto-mode-entry)) json-mode--auto-mode-entry))) (setq auto-mode-alist (delete old-entry auto-mode-alist)) (add-to-list (quote auto-mode-alist) new-entry) new-entry))
+
+(defvar json-mode-auto-mode-list '(".babelrc" ".bowerrc" "composer.lock") "\
+List of filename as string to pass for the JSON entry of
+`auto-mode-alist'.
+
+Note however that custom `json-mode' entries in `auto-mode-alist'
+won’t be affected.")
+
+(custom-autoload 'json-mode-auto-mode-list "json-mode" nil)
+
+(defvar json-mode--auto-mode-entry (json-mode--update-auto-mode json-mode-auto-mode-list) "\
+Regexp generated from the `json-mode-auto-mode-list'.")
+
+(autoload 'json-mode "json-mode" "\
+Major mode for editing JSON files
+
+\(fn)" t nil)
+
+(autoload 'json-mode-show-path "json-mode" "\
+Print the path to the node at point to the minibuffer, and yank to the kill ring.
+
+\(fn)" t nil)
+
+(autoload 'json-mode-kill-path "json-mode" "\
+
+
+\(fn)" t nil)
+
+(autoload 'json-mode-beautify "json-mode" "\
+Beautify / pretty-print the active region (or the entire buffer if no active region).
+
+\(fn)" t nil)
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; json-mode-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/json-mode-20180718.109/json-mode-pkg.el b/configs/shared/emacs/.emacs.d/elpa/json-mode-20180718.109/json-mode-pkg.el
new file mode 100644
index 0000000000..e6c5f34a58
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/json-mode-20180718.109/json-mode-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "json-mode" "20180718.109" "Major mode for editing JSON files." '((json-reformat "0.0.5") (json-snatcher "1.0.0")))
diff --git a/configs/shared/emacs/.emacs.d/elpa/json-mode-20180718.109/json-mode.el b/configs/shared/emacs/.emacs.d/elpa/json-mode-20180718.109/json-mode.el
new file mode 100644
index 0000000000..2de0d9cfa7
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/json-mode-20180718.109/json-mode.el
@@ -0,0 +1,222 @@
+;;; json-mode.el --- Major mode for editing JSON files.
+
+;; Copyright (C) 2011-2014 Josh Johnston
+
+;; Author: Josh Johnston
+;; URL: https://github.com/joshwnj/json-mode
+;; Package-Version: 20180718.109
+;; Version: 1.6.0
+;; Package-Requires: ((json-reformat "0.0.5") (json-snatcher "1.0.0"))
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; extend the builtin js-mode's syntax highlighting
+
+;;; Code:
+
+(require 'js)
+(require 'rx)
+(require 'json-snatcher)
+(require 'json-reformat)
+
+(defgroup json-mode '()
+  "Major mode for editing JSON files."
+  :group 'js)
+
+;;;###autoload
+(defconst json-mode-standard-file-ext '(".json" ".jsonld")
+  "List of JSON file extensions.")
+
+;; This is to be sure the customization is loaded.  Otherwise,
+;; autoload discards any defun or defcustom.
+;;;###autoload
+(defsubst json-mode--update-auto-mode (filenames)
+  "Update the `json-mode' entry of `auto-mode-alist'.
+
+FILENAMES should be a list of file as string.
+Return the new `auto-mode-alist' entry"
+  (let* ((new-regexp
+          (rx-to-string
+           `(seq (eval
+                  (cons 'or
+                        (append json-mode-standard-file-ext
+                                ',filenames))) eot)))
+         (new-entry (cons new-regexp 'json-mode))
+         (old-entry (when (boundp 'json-mode--auto-mode-entry)
+                      json-mode--auto-mode-entry)))
+    (setq auto-mode-alist (delete old-entry auto-mode-alist))
+    (add-to-list 'auto-mode-alist new-entry)
+    new-entry))
+
+;;;###autoload
+(defcustom json-mode-auto-mode-list '(
+                                      ".babelrc"
+                                      ".bowerrc"
+                                      "composer.lock"
+                                      )
+  "List of filename as string to pass for the JSON entry of
+`auto-mode-alist'.
+
+Note however that custom `json-mode' entries in `auto-mode-alist'
+won’t be affected."
+  :group 'json-mode
+  :type '(repeat string)
+  :set (lambda (symbol value)
+         "Update SYMBOL with a new regexp made from VALUE.
+
+This function calls `json-mode--update-auto-mode' to change the
+`json-mode--auto-mode-entry' entry in `auto-mode-alist'."
+         (set-default symbol value)
+         (setq json-mode--auto-mode-entry (json-mode--update-auto-mode value))))
+
+;; Autoload needed to initalize the the `auto-list-mode' entry.
+;;;###autoload
+(defvar json-mode--auto-mode-entry (json-mode--update-auto-mode json-mode-auto-mode-list)
+  "Regexp generated from the `json-mode-auto-mode-list'.")
+
+(defconst json-mode-quoted-string-re
+  (rx (group (char ?\")
+             (zero-or-more (or (seq ?\\ ?\\)
+                               (seq ?\\ ?\")
+                               (seq ?\\ (not (any ?\" ?\\)))
+                               (not (any ?\" ?\\))))
+             (char ?\"))))
+(defconst json-mode-quoted-key-re
+  (rx (group (char ?\")
+             (zero-or-more (or (seq ?\\ ?\\)
+                               (seq ?\\ ?\")
+                               (seq ?\\ (not (any ?\" ?\\)))
+                               (not (any ?\" ?\\))))
+             (char ?\"))
+      (zero-or-more blank)
+      ?\:))
+(defconst json-mode-number-re (rx (group (one-or-more digit)
+                                         (optional ?\. (one-or-more digit)))))
+(defconst json-mode-keyword-re  (rx (group (or "true" "false" "null"))))
+
+(defconst json-font-lock-keywords-1
+  (list
+   (list json-mode-quoted-key-re 1 font-lock-keyword-face)
+   (list json-mode-quoted-string-re 1 font-lock-string-face)
+   (list json-mode-keyword-re 1 font-lock-constant-face)
+   (list json-mode-number-re 1 font-lock-constant-face)
+   )
+  "Level one font lock.")
+
+;;;###autoload
+(define-derived-mode json-mode javascript-mode "JSON"
+  "Major mode for editing JSON files"
+  (set (make-local-variable 'font-lock-defaults) '(json-font-lock-keywords-1 t)))
+
+;; Well formatted JSON files almost always begin with “{” or “[”.
+(add-to-list 'magic-mode-alist '("^[{[]$" . json-mode))
+
+;;;###autoload
+(defun json-mode-show-path ()
+  "Print the path to the node at point to the minibuffer, and yank to the kill ring."
+  (interactive)
+  (message (jsons-print-path)))
+
+(define-key json-mode-map (kbd "C-c C-p") 'json-mode-show-path)
+
+;;;###autoload
+(defun json-mode-kill-path ()
+  (interactive)
+    (kill-new (jsons-print-path)))
+
+(define-key json-mode-map (kbd "C-c P") 'json-mode-kill-path)
+
+;;;###autoload
+(defun json-mode-beautify ()
+  "Beautify / pretty-print the active region (or the entire buffer if no active region)."
+  (interactive)
+  (let ((json-reformat:indent-width js-indent-level)
+        (json-reformat:pretty-string? t))
+    (if (use-region-p)
+        (json-reformat-region (region-beginning) (region-end))
+      (json-reformat-region (buffer-end -1) (buffer-end 1)))))
+
+(define-key json-mode-map (kbd "C-c C-f") 'json-mode-beautify)
+
+(defun json-toggle-boolean ()
+  "If point is on `true' or `false', toggle it."
+  (interactive)
+  (unless (nth 8 (syntax-ppss)) ; inside a keyword, string or comment
+    (let* ((bounds (bounds-of-thing-at-point 'symbol))
+           (string (and bounds (buffer-substring-no-properties (car bounds) (cdr bounds))))
+           (pt (point)))
+      (when (and bounds (member string '("true" "false")))
+        (delete-region (car bounds) (cdr bounds))
+        (cond
+         ((string= "true" string)
+          (insert "false")
+          (goto-char (if (= pt (cdr bounds)) (1+ pt) pt)))
+         (t
+          (insert "true")
+          (goto-char (if (= pt (cdr bounds)) (1- pt) pt))))))))
+
+(define-key json-mode-map (kbd "C-c C-t") 'json-toggle-boolean)
+
+(defun json-nullify-sexp ()
+  "Replace the sexp at point with `null'."
+  (interactive)
+  (let ((syntax (syntax-ppss)) symbol)
+    (cond
+     ((nth 4 syntax) nil)               ; inside a comment
+     ((nth 3 syntax)                    ; inside a string
+      (goto-char (nth 8 syntax))
+      (when (save-excursion (forward-sexp) (skip-chars-forward "[:space:]") (eq (char-after) ?:))
+        ;; sexp is an object key, so we nullify the entire object
+        (goto-char (nth 1 syntax)))
+      (kill-sexp)
+      (insert "null"))
+     ((setq symbol (bounds-of-thing-at-point 'symbol))
+      (cond
+       ((looking-at-p "null"))
+       ((save-excursion (skip-chars-backward "[0-9.]") (looking-at json-mode-number-re))
+        (kill-region (match-beginning 0) (match-end 0))
+        (insert "null"))
+       (t (kill-region (car symbol) (cdr symbol)) (insert "null"))))
+     ((< 0 (nth 0 syntax))
+      (goto-char (nth 1 syntax))
+      (kill-sexp)
+      (insert "null"))
+     (t nil))))
+
+(define-key json-mode-map (kbd "C-c C-k") 'json-nullify-sexp)
+
+(defun json-increment-number-at-point (&optional delta)
+  "Add DELTA to the number at point; DELTA defaults to 1."
+  (interactive)
+  (when (save-excursion (skip-chars-backward "[0-9.]") (looking-at json-mode-number-re))
+    (let ((num (+ (or delta 1)
+                  (string-to-number (buffer-substring-no-properties (match-beginning 0) (match-end 0)))))
+          (pt (point)))
+      (delete-region (match-beginning 0) (match-end 0))
+      (insert (number-to-string num))
+      (goto-char pt))))
+
+(define-key json-mode-map (kbd "C-c C-i") 'json-increment-number-at-point)
+
+(defun json-decrement-number-at-point ()
+  "Decrement the number at point."
+  (interactive)
+  (json-increment-number-at-point -1))
+
+(define-key json-mode-map (kbd "C-c C-d") 'json-decrement-number-at-point)
+
+(provide 'json-mode)
+;;; json-mode.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/json-mode-20180718.109/json-mode.elc b/configs/shared/emacs/.emacs.d/elpa/json-mode-20180718.109/json-mode.elc
new file mode 100644
index 0000000000..ea7010e8d0
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/json-mode-20180718.109/json-mode.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/json-reformat-20160212.53/json-reformat-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/json-reformat-20160212.53/json-reformat-autoloads.el
new file mode 100644
index 0000000000..56b08a47af
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/json-reformat-20160212.53/json-reformat-autoloads.el
@@ -0,0 +1,26 @@
+;;; json-reformat-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "json-reformat" "json-reformat.el" (23377 61610
+;;;;;;  863500 121000))
+;;; Generated autoloads from json-reformat.el
+
+(autoload 'json-reformat-region "json-reformat" "\
+Reformat the JSON in the specified region.
+
+If you want to customize the reformat style,
+please see the documentation of `json-reformat:indent-width'
+and `json-reformat:pretty-string?'.
+
+\(fn BEGIN END)" t nil)
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; json-reformat-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/json-reformat-20160212.53/json-reformat-pkg.el b/configs/shared/emacs/.emacs.d/elpa/json-reformat-20160212.53/json-reformat-pkg.el
new file mode 100644
index 0000000000..b626490856
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/json-reformat-20160212.53/json-reformat-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "json-reformat" "20160212.53" "Reformatting tool for JSON" 'nil)
diff --git a/configs/shared/emacs/.emacs.d/elpa/json-reformat-20160212.53/json-reformat.el b/configs/shared/emacs/.emacs.d/elpa/json-reformat-20160212.53/json-reformat.el
new file mode 100644
index 0000000000..4bc0142209
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/json-reformat-20160212.53/json-reformat.el
@@ -0,0 +1,221 @@
+;;; json-reformat.el --- Reformatting tool for JSON
+
+;; Author: Wataru MIYAGUNI <gonngo@gmail.com>
+;; URL: https://github.com/gongo/json-reformat
+;; Package-Version: 20160212.53
+;; Version: 0.0.6
+;; Keywords: json
+
+;; Copyright (c) 2012 Wataru MIYAGUNI
+;;
+;; MIT License
+;;
+;; Permission is hereby granted, free of charge, to any person obtaining
+;; a copy of this software and associated documentation files (the
+;; "Software"), to deal in the Software without restriction, including
+;; without limitation the rights to use, copy, modify, merge, publish,
+;; distribute, sublicense, and/or sell copies of the Software, and to
+;; permit persons to whom the Software is furnished to do so, subject to
+;; the following conditions:
+;;
+;; The above copyright notice and this permission notice shall be
+;; included in all copies or substantial portions of the Software.
+;;
+;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+;; EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+;; MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+;; NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+;; LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+;; OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+;; WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+;;; Commentary:
+
+;; json-reformat.el is a reformatting tool for JSON (http://json.org/).
+;;
+;; ## Usage
+;;
+;;   1. Specify region
+;;   2. Call 'M-x json-reformat-region'
+;;
+;; ## Customize
+;;
+;;   - `json-reformat:indent-width'
+;;   - `json-reformat:pretty-string?'
+;;
+
+;;; Code:
+
+(require 'json)
+(eval-when-compile (require 'cl))
+
+(unless (require 'subr-x nil t)
+  ;; built-in subr-x from 24.4
+  (defsubst hash-table-keys (hash-table)
+    "Return a list of keys in HASH-TABLE."
+    (let ((keys '()))
+      (maphash (lambda (k _v) (push k keys)) hash-table)
+      keys)))
+
+(put 'json-reformat-error 'error-message "JSON Reformat error")
+(put 'json-reformat-error 'error-conditions '(json-reformat-error error))
+
+(defconst json-reformat:special-chars-as-pretty-string
+  '((?\" . ?\")
+    (?\\ . ?\\)))
+
+(defcustom json-reformat:indent-width 4
+  "How much indentation `json-reformat-region' should do at each level."
+  :type 'integer
+  :safe #'integerp
+  :group 'json-reformat)
+
+(defcustom json-reformat:pretty-string? nil
+  "Whether to decode the string.
+
+Example:
+
+{\"name\":\"foobar\",\"nick\":\"foo \\u00e4 bar\",\"description\":\"<pre>\\nbaz\\n</pre>\"}
+
+If nil:
+
+    {
+        \"name\": \"foobar\",
+        \"nick\": \"foo \\u00e4 bar\",
+        \"description\": \"<pre>\\nbaz\\n<\\/pre>\"
+    }
+
+Else t:
+
+    {
+        \"name\": \"foobar\",
+        \"nick\": \"foo ä bar\",
+        \"description\": \"<pre>
+    baz
+    </pre>\"
+    }"
+  :type 'boolean
+  :safe #'booleanp
+  :group 'json-reformat)
+
+(defun json-reformat:indent (level)
+  (make-string (* level json-reformat:indent-width) ? ))
+
+(defun json-reformat:number-to-string (val)
+  (number-to-string val))
+
+(defun json-reformat:symbol-to-string (val)
+  (cond ((equal 't val) "true")
+        ((equal json-false val) "false")
+        (t (symbol-name val))))
+
+(defun json-reformat:encode-char-as-pretty (char)
+  (setq char (encode-char char 'ucs))
+  (let ((special-char (car (rassoc char json-reformat:special-chars-as-pretty-string))))
+    (if special-char
+        (format "\\%c" special-char)
+      (format "%c" char))))
+
+(defun json-reformat:string-to-string (val)
+  (if json-reformat:pretty-string?
+      (format "\"%s\"" (mapconcat 'json-reformat:encode-char-as-pretty val ""))
+    (json-encode-string val)))
+
+(defun json-reformat:vector-to-string (val level)
+  (if (= (length val) 0) "[]"
+    (concat "[\n"
+            (mapconcat
+             'identity
+             (loop for v across val
+                   collect (concat
+                            (json-reformat:indent (1+ level))
+                            (json-reformat:print-node v (1+ level))
+                            ))
+             (concat ",\n"))
+            "\n" (json-reformat:indent level) "]"
+            )))
+
+(defun json-reformat:print-node (val level)
+  (cond ((hash-table-p val) (json-reformat:tree-to-string (json-reformat:tree-sibling-to-plist val) level))
+        ((numberp val)      (json-reformat:number-to-string val))
+        ((vectorp val)      (json-reformat:vector-to-string val level))
+        ((null val)         "null")
+        ((symbolp val)      (json-reformat:symbol-to-string val))
+        (t                  (json-reformat:string-to-string val))))
+
+(defun json-reformat:tree-sibling-to-plist (root)
+  (let (pl)
+    (dolist (key (reverse (hash-table-keys root)) pl)
+      (setq pl (plist-put pl key (gethash key root))))))
+
+(defun json-reformat:tree-to-string (root level)
+  (concat "{\n"
+          (let (key val str)
+            (while root
+              (setq key (car root)
+                    val (cadr root)
+                    root (cddr root))
+              (setq str
+                    (concat str (json-reformat:indent (1+ level))
+                            "\"" key "\""
+                            ": "
+                            (json-reformat:print-node val (1+ level))
+                            (when root ",")
+                            "\n"
+                            )))
+            str)
+          (json-reformat:indent level)
+          "}"))
+
+(defun json-reformat-from-string (string)
+  (with-temp-buffer
+    (insert string)
+    (goto-char (point-min))
+    (condition-case errvar
+        (let ((json-key-type 'string)
+              (json-object-type 'hash-table)
+              json-tree)
+          (setq json-tree (json-read))
+          (json-reformat:print-node json-tree 0))
+      (json-error
+       (signal 'json-reformat-error
+               (list (error-message-string errvar)
+                     (line-number-at-pos (point))
+                     (point)))))))
+
+;;;###autoload
+(defun json-reformat-region (begin end)
+  "Reformat the JSON in the specified region.
+
+If you want to customize the reformat style,
+please see the documentation of `json-reformat:indent-width'
+and `json-reformat:pretty-string?'."
+  (interactive "*r")
+  (let ((start-line (line-number-at-pos begin))
+        (start-pos  begin))
+    (save-excursion
+      (save-restriction
+        (narrow-to-region begin end)
+        (goto-char (point-min))
+        (let (reformatted)
+          (condition-case errvar
+              (progn
+                (setq reformatted
+                      (json-reformat-from-string
+                       (buffer-substring-no-properties (point-min) (point-max))))
+                (delete-region (point-min) (point-max))
+                (insert reformatted))
+            (json-reformat-error
+             (let ((reason   (nth 1 errvar))
+                   (line     (nth 2 errvar))
+                   (position (nth 3 errvar)))
+               (message
+                "JSON parse error [Reason] %s [Position] In buffer, line %d (char %d)"
+                reason
+                (+ start-line line -1)
+                (+ start-pos position -1))))))))))
+
+(provide 'json-reformat)
+
+;;; json-reformat.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/json-reformat-20160212.53/json-reformat.elc b/configs/shared/emacs/.emacs.d/elpa/json-reformat-20160212.53/json-reformat.elc
new file mode 100644
index 0000000000..7fd7b9ac88
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/json-reformat-20160212.53/json-reformat.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/json-snatcher-20150511.2047/json-snatcher-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/json-snatcher-20150511.2047/json-snatcher-autoloads.el
new file mode 100644
index 0000000000..a3d712fbfe
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/json-snatcher-20150511.2047/json-snatcher-autoloads.el
@@ -0,0 +1,22 @@
+;;; json-snatcher-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "json-snatcher" "json-snatcher.el" (23377 61610
+;;;;;;  572975 982000))
+;;; Generated autoloads from json-snatcher.el
+
+(autoload 'jsons-print-path "json-snatcher" "\
+Print the path to the JSON value under point, and save it in the kill ring.
+
+\(fn)" t nil)
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; json-snatcher-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/json-snatcher-20150511.2047/json-snatcher-pkg.el b/configs/shared/emacs/.emacs.d/elpa/json-snatcher-20150511.2047/json-snatcher-pkg.el
new file mode 100644
index 0000000000..317262efa6
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/json-snatcher-20150511.2047/json-snatcher-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "json-snatcher" "20150511.2047" "Grabs the path to JSON values in a JSON file" '((emacs "24")))
diff --git a/configs/shared/emacs/.emacs.d/elpa/json-snatcher-20150511.2047/json-snatcher.el b/configs/shared/emacs/.emacs.d/elpa/json-snatcher-20150511.2047/json-snatcher.el
new file mode 100644
index 0000000000..61fb713713
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/json-snatcher-20150511.2047/json-snatcher.el
@@ -0,0 +1,351 @@
+;;; json-snatcher.el --- Grabs the path to JSON values in a JSON file -*- lexical-binding: t -*-
+
+;; Copyright (C) 2013 Sterling Graham <sterlingrgraham@gmail.com>
+
+;; Author: Sterling Graham <sterlingrgraham@gmail.com>
+;; URL: http://github.com/sterlingg/json-snatcher
+;; Package-Version: 20150511.2047
+;; Version: 1.0
+;; Package-Requires: ((emacs "24"))
+
+;; This file is not part of GNU Emacs.
+
+;;; Commentary:
+;;
+;; Well this was my first excursion into ELisp programmming.  It didn't go too badly once
+;; I fiddled around with a bunch of the functions.
+;;
+;; The process of getting the path to a JSON value at point starts with
+;; a call to the jsons-print-path function.
+;;
+;; It works by parsing the current buffer into a list of parse tree nodes
+;; if the buffer hasn't already been parsed in the current Emacs session.
+;; While parsing, the region occupied by the node is recorded into the
+;; jsons-parsed-regions hash table as a list.The list contains the location
+;; of the first character occupied by the node, the location of the last
+;; character occupied, and the path to the node.  The parse tree is also stored
+;; in the jsons-parsed list for possible future use.
+;;
+;; Once the buffer has been parsed, the node at point is looked up in the
+;; jsons-curr-region list, which is the list of regions described in the
+;; previous paragraph for the current buffer.  If point is not in one of these
+;; interval ranges nil is returned, otherwise the path to the value is returned
+;; in the form [<key-string>] for objects, and [<loc-int>] for arrays.
+;; eg: ['value1'][0]['value2'] gets the array at with name value1, then gets the
+;; 0th element of the array (another object), then gets the value at 'value2'.
+;;
+
+;;; Installation:
+;;
+;; IMPORTANT: Works ONLY in Emacs 24 due to the use of the lexical-binding variable.
+;;
+;; To install add the json-snatcher.el file to your load-path, and
+;; add the following lines to your .emacs file:
+;;(require 'json-snatcher)
+;; (defun js-mode-bindings ()
+;;   "Sets a hotkey for using the json-snatcher plugin."
+;;   (when (string-match  "\\.json$" (buffer-name))
+;;       (local-set-key (kbd "C-c C-g") 'jsons-print-path)))
+;; (add-hook 'js-mode-hook 'js-mode-bindings)
+;; (add-hook 'js2-mode-hook 'js-mode-bindings)
+;;
+;; This binds the key to snatch the path to the JSON value to C-c C-g only
+;; when either JS mode, or JS2 mode is active on a buffer ending with
+;; the .json extension.
+
+;;; License:
+
+;; This program 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.
+;;
+;; This program 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; see the file COPYING.  If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Code:
+
+
+(defvar jsons-curr-token 0
+  "The current character in the buffer being parsed.")
+(defvar jsons-parsed (make-hash-table :test 'equal)
+  "Hashes each open buffer to the parse tree for that buffer.")
+(defvar jsons-parsed-regions (make-hash-table :test 'equal)
+  "Hashes each open buffer to the ranges in the buffer for each of the parse trees nodes.")
+(defvar jsons-curr-region () "The node ranges in the current buffer.")
+(defvar jsons-path-printer 'jsons-print-path-python "Default jsons path printer")
+(add-hook 'kill-buffer-hook 'jsons-remove-buffer)
+
+(defun jsons-consume-token ()
+  "Return the next token in the stream."
+  (goto-char jsons-curr-token)
+  (let* ((delim_regex "\\([\][\\{\\}:,]\\)")
+         ;; TODO: Improve this regex. Although now it SEEMS to be working, and can be
+         ;; used to validate escapes if needed later. The second half of the string regex is pretty
+         ;; pointless at the moment. I did it this way, so that the code closely mirrors
+         ;; the RFC.
+         (string_regex "\\(\"\\(\\([^\"\\\\\r\s\t\n]\\)*\\([\r\s\t\n]\\)*\\|\\(\\(\\\\\\\\\\)*\\\\\\(\\([^\r\s\t\n]\\|\\(u[0-9A-Fa-f]\\{4\\}\\)\\)\\)\\)\\)+\"\\)")
+         (num_regex "\\(-?\\(0\\|\\([1-9][[:digit:]]*\\)\\)\\(\\.[[:digit:]]+\\)?\\([eE][-+]?[[:digit:]]+\\)?\\)")
+         (literal_regex "\\(true\\|false\\|null\\)")
+         (full_regex (concat "\\(" delim_regex "\\|" literal_regex "\\|" string_regex "\\|" num_regex "\\)")))
+
+    (if (re-search-forward full_regex (point-max) "Not nil")
+        (progn
+          (setq jsons-curr-token (match-end 0))
+          (buffer-substring-no-properties (match-beginning 0) (match-end 0)))
+      (message "Reached EOF. Possibly invalid JSON."))))
+
+(defun jsons-array (path)
+  "Create a new json array object that contain the identifier \"json-array\".
+a list of the elements contained in the array, and the PATH to the array."
+  (let*(
+        (token (jsons-consume-token))
+        (array "json-array")
+        (elements ())
+        (i 0))
+    (while (not (string= token "]"))
+      (if (not (string= token ","))
+          (let ((json-val (jsons-value token path i)))
+            (setq i (+ i 1))
+            (push json-val elements)
+            (setq token (jsons-consume-token)))
+        (setq token (jsons-consume-token))))
+    (list array (reverse elements) path)))
+
+(defun jsons-literal (token path)
+  "Given a TOKEN and PATH, this function return the PATH to the literal."
+  (let ((match_start (match-beginning 0))
+        (match_end (match-end 0)))
+    (progn
+      (setq jsons-curr-region (append (list (list match_start match_end path)) jsons-curr-region))
+      (list "json-literal" token path (list match_start match_end)))))
+
+(defun jsons-member (token path)
+  "This function is called when a member in a JSON object needs to be parsed.
+Given the current TOKEN, and the PATH to this member."
+  (let* ((member ())
+         (value token)
+         (range_start (match-beginning 0))
+         (range_end (match-end 0))
+         )
+    (setq member (list "json-member" token))
+    (if (not (string= (jsons-consume-token) ":"))
+        (error "Encountered token other than : in jsons-member")
+      nil)
+    (let ((json-val (jsons-value (jsons-consume-token) (cons value path) nil)))
+      (setq member (list member (append json-val
+                                        (list range_start range_end))))
+      (setq jsons-curr-region (append (list (list range_start range_end (elt json-val 2))) jsons-curr-region))
+    member)))
+
+(defun jsons-number (token path)
+  "This function will return a json-number given by the current TOKEN.
+PATH points to the path to this number.  A json-number is defined as per
+the num_regex in the `jsons-get-tokens' function."
+  (progn
+    (setq jsons-curr-region (append (list (list (match-beginning 0) (match-end 0) path)) jsons-curr-region))
+    (list "json-number" token path)))
+
+(defun jsons-object (path)
+  "This function is called when a { is encountered while parsing.
+PATH is the path in the tree to this object."
+  (let*(
+        (token (jsons-consume-token))
+        (members (make-hash-table :test 'equal))
+        (object (list "json-object" members path)))
+    (while (not (string= token "}"))
+      (if (not (string= token ","))
+          (let ((json-mem (jsons-member token path)))
+            (puthash (elt (elt json-mem 0) 1) (elt json-mem 1) (elt object 1))
+            (setq token (jsons-consume-token)))
+        (setq token (jsons-consume-token))))
+    object))
+
+(defun jsons-string (token path)
+  "This function is called when a string is encountered while parsing.
+The TOKEN is the current token being examined.
+The PATH is the path to this string."
+(let ((match_start (match-beginning 0))
+      (match_end (match-end 0)))
+  (progn
+    (setq jsons-curr-region (append (list (list match_start match_end path)) jsons-curr-region))
+  (list "json-string" token path (list match_start match_end)))))
+
+(defun jsons-value (token path array-index)
+  "A value, which is either an object, array, string, number, or literal.
+The is-array variable is nil if inside an array, or the index in
+the array that it occupies.
+TOKEN is the current token being parsed.
+PATH is the path to this value.
+ARRAY-INDEX is non-nil if the value is contained within an array, and
+points to the index of this value in the containing array."
+;;TODO: Refactor the if array-index statement.
+  (if array-index
+      (if (jsons-is-number token)
+          (list "json-value" (jsons-number token (cons array-index path)) (list (match-beginning 0) (match-end 0)))
+        (cond
+         ((string= token "{") (jsons-object (cons array-index path)))
+         ((string= token "[") (jsons-array (cons array-index path)))
+         ((string= (substring token 0 1) "\"") (jsons-string token (cons array-index path)))
+         (t (jsons-literal token (cons array-index path)))))
+    (if (jsons-is-number token)
+        (list "json-value" (jsons-number token path) path (list (match-beginning 0) (match-end 0)))
+      (cond
+       ((string= token "{") (jsons-object path))
+       ((string= token "[") (jsons-array path))
+       ((string= (substring token 0 1) "\"") (jsons-string token path))
+       (t (jsons-literal token path))))))
+
+
+(defun jsons-get-path ()
+  "Function to check whether we can grab the json path from the cursor position in the json file."
+  (let ((i 0)
+        (node nil))
+    (setq jsons-curr-region (gethash (current-buffer) jsons-parsed-regions))
+    (when (not (gethash (current-buffer) jsons-parsed))
+      (jsons-parse))
+    (while (< i (length jsons-curr-region))
+      (let*
+          ((json_region (elt jsons-curr-region i))
+           (min_token (elt json_region 0))
+           (max_token (elt json_region 1)))
+        (when (and (> (point) min_token) (< (point) max_token))
+          (setq node (elt json_region 2))))
+      (setq i (+ i 1)))
+    node))
+
+(defun jsons-is-number (str)
+  "Test to see whether STR is a valid JSON number."
+  (progn
+    (match-end 0)
+    (save-match-data
+      (if (string-match "^\\(-?\\(0\\|\\([1-9][[:digit:]]*\\)\\)\\(\\.[[:digit:]]+\\)?\\([eE][-+]?[[:digit:]]+\\)?\\)$" str)
+          (progn
+            (match-end 0)
+            t)
+        nil))))
+
+(defun jsons-parse ()
+  "Parse the file given in file, return a list of nodes representing the file."
+  (save-excursion
+    (setq jsons-curr-token 0)
+    (setq jsons-curr-region ())
+    (if (not (gethash (current-buffer) jsons-parsed))
+        (let* ((token (jsons-consume-token))
+               (return_val nil))
+          (cond
+           ((string= token "{") (setq return_val (jsons-object ())))
+           ((string= token "[") (setq return_val (jsons-array ())))
+           (t nil))
+          (puthash (current-buffer) return_val jsons-parsed)
+          (puthash (current-buffer) jsons-curr-region jsons-parsed-regions)
+          return_val)
+      (gethash (current-buffer) jsons-parsed))))
+
+(defun jsons-print-to-buffer (node buffer)
+  "Prints the given NODE to the BUFFER specified in buffer argument.
+TODO: Remove extra comma printed after lists of object members, and lists of array members."
+  (let ((id (elt node 0)))
+    (cond
+     ((string= id "json-array")
+      (progn
+        (jsons-put-string buffer "[")
+        (mapc (lambda (x) (progn
+                            (jsons-print-to-buffer buffer x)
+                            (jsons-put-string buffer ",") )) (elt node 1))
+        (jsons-put-string buffer "]")))
+     ((string= id "json-literal")
+      (jsons-put-string buffer (elt node 1)))
+     ((string= id "json-member")
+      (jsons-put-string buffer (elt node 1))
+      (jsons-put-string buffer ": ")
+      (jsons-print-to-buffer buffer (elt node 2)))
+     ((string= id "json-number")
+      (jsons-put-string buffer (elt node 1)))
+     ((string= id "json-object")
+      (progn
+        (jsons-put-string buffer "{")
+        (maphash (lambda (key value)
+                   (progn
+                     (jsons-put-string buffer key)
+                     (jsons-put-string buffer ":")
+                     (jsons-print-to-buffer buffer value)
+                     (jsons-put-string buffer ","))) (elt node 1))
+      (jsons-put-string buffer "}")))
+     ((string= id "json-string")
+      (jsons-put-string buffer (elt node 1)))
+     ((string= id "json-value")
+      (jsons-print-to-buffer buffer (elt node 1)))
+     (t nil))))
+
+(defun jsons-print-path-jq ()
+  "Print the jq path to the JSON value under point, and save it in the kill ring."
+  (let* ((path (jsons-get-path))
+         (i 0)
+         (jq_str ".")
+         key)
+    (setq path (reverse path))
+    (while (< i (length path))
+      (if (numberp (elt path i))
+          (progn
+            (setq jq_str (concat jq_str "[" (number-to-string (elt path i)) "]"))
+            (setq i (+ i 1)))
+        (progn
+          (setq key (elt path i))
+          (setq jq_str (concat jq_str (substring key 1 (- (length key) 1))))
+          (setq i (+ i 1))))
+      (when (elt path i)
+        (unless (numberp (elt path i))
+          (setq jq_str (concat jq_str ".")))))
+    (progn (kill-new jq_str)
+           (princ jq_str))))
+
+(defun jsons-print-path-python ()
+  "Print the python path to the JSON value under point, and save it in the kill ring."
+  (let ((path (jsons-get-path))
+        (i 0)
+        (python_str ""))
+    (setq path (reverse path))
+    (while (< i (length path))
+      (if (numberp (elt path i))
+          (progn
+            (setq python_str (concat python_str "[" (number-to-string (elt path i)) "]"))
+            (setq i (+ i 1)))
+        (progn
+          (setq python_str (concat python_str "[" (elt path i) "]"))
+          (setq i (+ i 1)))))
+    (progn (kill-new python_str)
+           (princ python_str))))
+
+;;;###autoload
+(defun jsons-print-path ()
+  "Print the path to the JSON value under point, and save it in the kill ring."
+  (interactive)
+  (funcall jsons-path-printer))
+
+(defun jsons-put-string (buffer str)
+  "Append STR to the BUFFER specified in the argument."
+    (save-current-buffer
+      (set-buffer (get-buffer-create buffer))
+      (insert (prin1-to-string str t))))
+
+(defun jsons-remove-buffer ()
+  "Used to clean up the token regions, and parse tree used by the parser."
+  (progn
+    (remhash (current-buffer) jsons-parsed)
+    (remhash (current-buffer) jsons-parsed-regions)))
+
+(provide 'json-snatcher)
+
+;; Local-Variables:
+;; indent-tabs-mode: nil
+;; End:
+
+;;; json-snatcher.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/json-snatcher-20150511.2047/json-snatcher.elc b/configs/shared/emacs/.emacs.d/elpa/json-snatcher-20150511.2047/json-snatcher.elc
new file mode 100644
index 0000000000..f76b23d350
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/json-snatcher-20150511.2047/json-snatcher.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/key-chord-20160227.438/key-chord-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/key-chord-20160227.438/key-chord-autoloads.el
new file mode 100644
index 0000000000..6058903a7e
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/key-chord-20160227.438/key-chord-autoloads.el
@@ -0,0 +1,67 @@
+;;; key-chord-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "key-chord" "key-chord.el" (23377 61305 247790
+;;;;;;  551000))
+;;; Generated autoloads from key-chord.el
+
+(autoload 'key-chord-mode "key-chord" "\
+Toggle key chord mode.
+With positive ARG enable the mode. With zero or negative arg disable the mode.
+A key chord is two keys that are pressed simultaneously, or one key quickly
+pressed twice.
+
+See functions `key-chord-define-global', `key-chord-define-local', and
+`key-chord-define' and variables `key-chord-two-keys-delay' and
+`key-chord-one-key-delay'.
+
+\(fn ARG)" t nil)
+
+(autoload 'key-chord-define-global "key-chord" "\
+Define a key-chord of the two keys in KEYS starting a COMMAND.
+
+KEYS can be a string or a vector of two elements. Currently only elements
+that corresponds to ascii codes in the range 32 to 126 can be used.
+
+COMMAND can be an interactive function, a string, or nil.
+If COMMAND is nil, the key-chord is removed.
+
+Note that KEYS defined locally in the current buffer will have precedence.
+
+\(fn KEYS COMMAND)" t nil)
+
+(autoload 'key-chord-define-local "key-chord" "\
+Locally define a key-chord of the two keys in KEYS starting a COMMAND.
+
+KEYS can be a string or a vector of two elements. Currently only elements
+that corresponds to ascii codes in the range 32 to 126 can be used.
+
+COMMAND can be an interactive function, a string, or nil.
+If COMMAND is nil, the key-chord is removed.
+
+The binding goes in the current buffer's local map,
+which in most cases is shared with all other buffers in the same major mode.
+
+\(fn KEYS COMMAND)" t nil)
+
+(autoload 'key-chord-define "key-chord" "\
+Define in KEYMAP, a key-chord of the two keys in KEYS starting a COMMAND.
+
+KEYS can be a string or a vector of two elements. Currently only elements
+that corresponds to ascii codes in the range 32 to 126 can be used.
+
+COMMAND can be an interactive function, a string, or nil.
+If COMMAND is nil, the key-chord is removed.
+
+\(fn KEYMAP KEYS COMMAND)" nil nil)
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; key-chord-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/key-chord-20160227.438/key-chord-pkg.el b/configs/shared/emacs/.emacs.d/elpa/key-chord-20160227.438/key-chord-pkg.el
new file mode 100644
index 0000000000..4c7f55793a
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/key-chord-20160227.438/key-chord-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "key-chord" "20160227.438" "map pairs of simultaneously pressed keys to commands" 'nil)
diff --git a/configs/shared/emacs/.emacs.d/elpa/key-chord-20160227.438/key-chord.el b/configs/shared/emacs/.emacs.d/elpa/key-chord-20160227.438/key-chord.el
new file mode 100644
index 0000000000..cfb5499c22
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/key-chord-20160227.438/key-chord.el
@@ -0,0 +1,373 @@
+;;; key-chord.el --- map pairs of simultaneously pressed keys to commands
+;;-------------------------------------------------------------------
+;;
+;; Copyright (C) 2003,2005,2008,2012 David Andersson
+;;
+;; This file is NOT part of Emacs.
+;;
+;; This program 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 2 of
+;; the License, or (at your option) any later version.
+;;
+;; This program 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 this program; if not, write to the Free
+;; Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+;; MA 02111-1307 USA
+;;
+;;-------------------------------------------------------------------
+
+;; Author: David Andersson <l.david.andersson(at)sverige.nu>
+;; Created: 27 April 2003
+;; Version: 0.6 (2012-10-23)
+;; Package-Version: 20160227.438
+;; Keywords: keyboard chord input
+
+;;; Commentary:
+
+;; ########   Compatibility   ########################################
+;;
+;; Works with Emacs-20.3, 20.6, 20.7, 21.2, 21.4, 22.1 and 23.1
+;; Does not work with Emacs-19.31 nor XEmacs-20.4 and 21.4.
+
+;; ########   Quick start   ########################################
+;;
+;; Add to your ~/.emacs
+;;
+;;      (require 'key-chord)
+;;      (key-chord-mode 1)
+;;
+;; and some chords, for example
+;;
+;;      (key-chord-define-global "hj"     'undo)
+;;      (key-chord-define-global ",."     "<>\C-b")
+
+;; ########   Terminology   ########################################
+;;
+;; In this package, a "key chord" is two keys pressed simultaneously,
+;; or a single key quickly pressed twice.
+;;
+;; (Sometimes pressing SHIFT and/or META plus another key is call a chord,
+;; but not here. However SHIFT plus two normal keys can be a "key chord".)
+
+;; ########   Description   ########################################
+;;
+;; Key chord mode acts like a global minor mode controlled by the function
+;; `key-chord-mode'.
+;;
+;; Key chord definitions are stored in ordinary key-maps.
+;; The function `key-chord-define-global' defines a chord in the global
+;; key-map and `key-chord-define' defines a chord in a specified key-map,
+;; for example for a specific mode.
+;;
+;; A TWO-key chord is two distinct keys pressed simultaneously (within
+;; one tenth of a second, or so).
+;;
+;; Examples:
+;;
+;;      (key-chord-define-global ",."     "<>\C-b")
+;;      (key-chord-define-global "hj"     'undo)
+;;      (key-chord-define-global [?h ?j]  'undo)  ; the same
+;;      (key-chord-define-global "jk"     'dabbrev-expand)
+;;      (key-chord-define-global "cv"     'reindent-then-newline-and-indent)
+;;      (key-chord-define-global "4r"     "$")
+;;
+;; Comma and dot pressed together insert a pair of angle brackets.
+;; `h' and `j' pressed together invoke the undo command.
+;; `j' and `k' pressed together invoke the dabbrev-expand command.
+;; 'c' and 'v' pressed together insert a newline.
+;; `4' and `r' pressed together insert a dollar sign.
+;;
+;; A ONE-key chord is a single key quickly pressed twice (within one third
+;; of a second or so). 
+;;
+;; Examples:
+;;
+;;      (key-chord-define-global "''"     "`'\C-b")
+;;      (key-chord-define-global ",,"     'indent-for-comment)
+;;      (key-chord-define-global "qq"     "the ")
+;;      (key-chord-define-global "QQ"     "The ")
+;;
+;; Tick (') pressed twice inserts a back-tick and a tick (`').
+;; Comma (,) pressed twice indents for and/or inserts a comment.
+;; `q' pressed twice inserts the word "the ".
+;;
+;; Examples: Mode specific chords
+;;
+;;      (key-chord-define c++-mode-map ";;"  "\C-e;")
+;;      (key-chord-define c++-mode-map "{}"  "{\n\n}\C-p\t")
+;;
+;; The command `key-chord-describe' lists currently defined key chords.
+;; The standard command `describe-bindings' (C-h b) will also show key chords.
+;;
+;; The standard command `describe-key' (C-h k) will accept a key chord and
+;; show its definition. (Isn't that amazing. There is no explicit code to
+;; carry out this functionality.)
+
+;; ########   Tips   ########################################
+;;
+;; Don't chord key combinations that exists in the languages you typically
+;; write. Otherwise, if you are typing fast, two key intended to be separate
+;; letters might instead trig a chord.
+;; E.g. "uu" would be a good chord in spanish but not in finnish, and
+;; "hj" would be a good chord in english but not in swedish. 
+;;
+;; Don't rely solely on /usr/dict/words to find unusual combination.
+;; For example "cv" or "fg" can be quite common in certain kinds of
+;; programming. Grep your own texts to verify that a combination is unusual.
+;; And don't forget to check both permutations: "fg" and "gf".
+;;
+;; Choose two keys that are close to each other on the keyboard, so they
+;; can be quickly typed without effort. Chords involving two hands (as
+;; opposed to two fingers on one hand) are harder to type (quickly).
+;; The idea is that key chords are to replace function keys for functions
+;; that are frequently performed while the hands are in writing position.
+;;
+;; Key chords might not work well over a slow network.
+
+;; ########   Limitations   ########################################
+;;
+;; When recording keyboard macros, the time between keyboard inputs are not
+;; recorded. Thus, the key-chord-input-method cannot know for sure if two keys
+;; in a macro was a chord or not. The current solution remembers the first key
+;; of the chords typed during macro recording, and keys that match those (and
+;; are defined as chords) are considered key-chords during macro execution.
+;; This knowledge is not saved with `name-last-kbd-macro', so they may
+;; execute wrong if they contain pair of keys that match defined chords.
+;;
+;; Emacs will not call input-method-function for keys that have non numeric
+;; codes or whos code is outside the range 32..126. Thus you cannot define
+;; key chords involving function keys, control keys, or even your non-english
+;; letters (on national keyboards) that otherwise are well positioned for
+;; chording on your keyboard.
+;; (I think chording left and right arrow keys would be useful, but cannot do.
+;; I consider this a bug in Emacs. Input methods could happily return
+;; unmodified *any* key they don't know about.)
+;;
+;; Key chords longer that 2 keys are not supported. It could be done, but I
+;; don't think it is worth the trubbel since most keyboards will not reliably
+;; send all key codes when 3 or more keys are pressed simultaneously.
+;; It might also be a bit trickier to maintain performance.
+;;
+;; Key chord mode uses input-method-function. And so do internationalisation
+;; packages (mule, quail, etc). Do not expect them to work well together.
+;; The last one that gets the input-method-function rules.
+
+;; ########   Implementation   ########################################
+;;
+;; Key chords piggy back in ordinary key maps, so they can be defined
+;; per mode without having to add hooks to all modes.
+;;
+;; Key chord key codes are vectors beginning with the atom `key-chord'.
+;; A two key chord, e.g. "hj", will add two entries in the key-map.
+;; E.g. [key-chord ?h ?j] and [key-chord ?j ?h].
+;;
+;; When key-chord-mode is enabled input-method-function is set to
+;; key-chord-input-method.
+
+;; ########   To do   ########################################
+;;
+;; * Find a way to save key-chord info in keyboard macros.
+;;
+;; * Save previous value of input-method-function? And call it?
+;;
+;; * input-method-function is reset in *info* buffers! What to do?
+;;
+;; * How to enter interactively command OR string in key-chord-define-global?
+;;
+;; * Customize public vars (defcustom).
+
+;; ########   History   ########################################
+;;
+;; 0.6 (2012-10-23) l.david.andersson(at)sverige.nu
+;;      Add key-chord-define-local, key-chord-unset-local, key-chord-unset-global
+;; 0.5 (2008-09-15) david(at)symsoft.se
+;;      Bugfix sit-for; Improved examples; New E-mail in comment
+;; 0.4 (2005-05-07) david(at)symsoft.se
+;;      Slightly better macro heuristics; Added option key-chord-in-macros
+;; 0.3 (2005-04-14) david(at)symsoft.se
+;;      Require advice; More examples
+;; 0.2 (2003-09-13) david(at)symsoft.se
+;;      Quick and dirty fix for keyboard macros
+;; 0.1 (2003-04-27) david(at)symsoft.se
+;;      First release
+
+;;; Code:
+
+(defvar key-chord-two-keys-delay 0.1	; 0.05 or 0.1
+  "Max time delay between two key press to be considered a key chord.")
+
+(defvar key-chord-one-key-delay 0.2	; 0.2 or 0.3 to avoid first autorepeat
+  "Max time delay between two press of the same key to be considered a key chord.
+This should normally be a little longer than `key-chord-two-keys-delay'.")
+
+(defvar key-chord-in-macros t
+  "If nil, don't expand key chords when executing keyboard macros.
+If non-nil, expand chord sequenses in macros, but only if a similar chord was
+entered during the last interactive macro recording. (This carries a bit of
+guesswork. We can't know for sure when executing whether two keys were
+typed quickly or slowly when recorded.)")
+
+;; Internal vars
+(defvar key-chord-mode nil)
+
+;; Shortcut for key-chord-input-method: no need to test a key again if it
+;; didn't matched a chord the last time. Improves feedback during autorepeat.
+(defvar key-chord-last-unmatched nil)
+
+;; Macro heuristics: Keep track of which chords was used when the last macro
+;; was defined. Or rather, only the first-char of the chords. Only expand
+;; matching chords during macro execution.
+(defvar key-chord-in-last-kbd-macro nil)
+(defvar key-chord-defining-kbd-macro nil)
+
+;;;###autoload
+(defun key-chord-mode (arg)
+  "Toggle key chord mode.
+With positive ARG enable the mode. With zero or negative arg disable the mode.
+A key chord is two keys that are pressed simultaneously, or one key quickly
+pressed twice.
+\nSee functions `key-chord-define-global', `key-chord-define-local', and
+`key-chord-define' and variables `key-chord-two-keys-delay' and
+`key-chord-one-key-delay'."
+
+  (interactive "P")
+  (setq key-chord-mode (if arg
+			   (> (prefix-numeric-value arg) 0)
+			 (not key-chord-mode)))
+  (cond (key-chord-mode
+	 (setq input-method-function 'key-chord-input-method)
+	 (message "Key Chord mode on"))
+	(t
+	 (setq input-method-function nil)
+	 (message "Key Chord mode off"))))
+
+;;;###autoload
+(defun key-chord-define-global (keys command)
+  "Define a key-chord of the two keys in KEYS starting a COMMAND.
+\nKEYS can be a string or a vector of two elements. Currently only elements
+that corresponds to ascii codes in the range 32 to 126 can be used.
+\nCOMMAND can be an interactive function, a string, or nil.
+If COMMAND is nil, the key-chord is removed.
+\nNote that KEYS defined locally in the current buffer will have precedence."
+  (interactive "sSet key chord globally (2 keys): \nCSet chord \"%s\" to command: ")
+  (key-chord-define (current-global-map) keys command))
+
+;;;###autoload
+(defun key-chord-define-local (keys command)
+  "Locally define a key-chord of the two keys in KEYS starting a COMMAND.
+\nKEYS can be a string or a vector of two elements. Currently only elements
+that corresponds to ascii codes in the range 32 to 126 can be used.
+\nCOMMAND can be an interactive function, a string, or nil.
+If COMMAND is nil, the key-chord is removed.
+\nThe binding goes in the current buffer's local map,
+which in most cases is shared with all other buffers in the same major mode."
+  (interactive "sSet key chord locally (2 keys): \nCSet chord \"%s\" to command: ")
+  (key-chord-define (current-local-map) keys command))
+
+(defun key-chord-unset-global (keys)
+  "Remove global key-chord of the two keys in KEYS."
+  (interactive "sUnset key chord globally (2 keys): ")
+  (key-chord-define (current-global-map) keys nil))
+
+(defun key-chord-unset-local (keys)
+  "Remove local key-chord of the two keys in KEYS."
+  (interactive "sUnset key chord locally (2 keys): ")
+  (key-chord-define (current-local-map) keys nil))
+
+;;;###autoload
+(defun key-chord-define (keymap keys command)
+  "Define in KEYMAP, a key-chord of the two keys in KEYS starting a COMMAND.
+\nKEYS can be a string or a vector of two elements. Currently only elements
+that corresponds to ascii codes in the range 32 to 126 can be used.
+\nCOMMAND can be an interactive function, a string, or nil.
+If COMMAND is nil, the key-chord is removed."
+  (if (/= 2 (length keys))
+      (error "Key-chord keys must have two elements"))
+  ;; Exotic chars in a string are >255 but define-key wants 128..255 for those
+  (let ((key1 (logand 255 (aref keys 0)))
+	(key2 (logand 255 (aref keys 1))))
+    (if (eq key1 key2)
+	(define-key keymap (vector 'key-chord key1 key2) command)
+      ;; else
+      (define-key keymap (vector 'key-chord key1 key2) command)
+      (define-key keymap (vector 'key-chord key2 key1) command))))
+
+(defun key-chord-lookup-key1 (keymap key)
+  "Like lookup-key but no third arg and no numeric return value."
+  (let ((res (lookup-key keymap key)))
+    (if (numberp res)
+	nil
+      ;; else
+      res)))
+
+(defun key-chord-lookup-key (key)
+  "Lookup KEY in all current key maps."
+  (let ((maps (current-minor-mode-maps))
+	res)
+    (while (and maps (not res))
+      (setq res (key-chord-lookup-key1 (car maps) key)
+	    maps (cdr maps)))
+    (or res
+	(if (current-local-map) 
+	    (key-chord-lookup-key1 (current-local-map) key))
+	(key-chord-lookup-key1 (current-global-map) key))))
+
+(defun key-chord-describe ()
+  "List key chord bindings in a help buffer.
+\nTwo key chords will be listed twice and there will be Prefix Commands.
+Please ignore that."
+  (interactive)
+  (describe-bindings [key-chord]))
+
+(defun key-chord-input-method (first-char)
+  "Input method controlled by key bindings with the prefix `key-chord'."
+  (if (and (not (eq first-char key-chord-last-unmatched))
+	   (key-chord-lookup-key (vector 'key-chord first-char)))
+      (let ((delay (if (key-chord-lookup-key (vector 'key-chord first-char first-char))
+		       key-chord-one-key-delay
+		     ;; else
+		     key-chord-two-keys-delay)))
+	(if (if executing-kbd-macro
+		(not (memq first-char key-chord-in-last-kbd-macro))
+              (when (bound-and-true-p eldoc-mode)
+                (eldoc-pre-command-refresh-echo-area))
+
+	      (sit-for delay 0 'no-redisplay))
+	    (progn
+	      (setq key-chord-last-unmatched nil)
+	      (list first-char))
+	  ;; else input-pending-p
+	  (let* ((input-method-function nil)
+		 (next-char (read-event))
+		 (res (vector 'key-chord first-char next-char)))
+	    (if (key-chord-lookup-key res)
+		(progn
+		  (setq key-chord-defining-kbd-macro
+			(cons first-char key-chord-defining-kbd-macro))
+		  (list 'key-chord first-char next-char))
+	      ;; else put back next-char and return first-char
+	      (setq unread-command-events (cons next-char unread-command-events))
+	      (if (eq first-char next-char)
+		  (setq key-chord-last-unmatched first-char))
+	      (list first-char)))))
+    ;; else no key-chord keymap
+    (setq key-chord-last-unmatched first-char)
+    (list first-char)))
+
+(require 'advice)
+
+(defadvice start-kbd-macro (after key-chord activate)
+  (setq key-chord-defining-kbd-macro nil))
+
+(defadvice end-kbd-macro (after key-chord activate)
+  (setq key-chord-in-last-kbd-macro key-chord-defining-kbd-macro))
+
+(provide 'key-chord)
+
+;;; key-chord.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/key-chord-20160227.438/key-chord.elc b/configs/shared/emacs/.emacs.d/elpa/key-chord-20160227.438/key-chord.elc
new file mode 100644
index 0000000000..259688062a
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/key-chord-20160227.438/key-chord.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/let-alist-1.0.5.signed b/configs/shared/emacs/.emacs.d/elpa/let-alist-1.0.5.signed
new file mode 100644
index 0000000000..14291adebb
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/let-alist-1.0.5.signed
@@ -0,0 +1 @@
+Good signature from 474F05837FBDEF9B GNU ELPA Signing Agent <elpasign@elpa.gnu.org> (trust undefined) created at 2017-02-01T05:05:02-0500 using DSA
\ No newline at end of file
diff --git a/configs/shared/emacs/.emacs.d/elpa/let-alist-1.0.5/let-alist-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/let-alist-1.0.5/let-alist-autoloads.el
new file mode 100644
index 0000000000..69330c7053
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/let-alist-1.0.5/let-alist-autoloads.el
@@ -0,0 +1,50 @@
+;;; let-alist-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "let-alist" "let-alist.el" (23377 61607 857843
+;;;;;;  708000))
+;;; Generated autoloads from let-alist.el
+
+(autoload 'let-alist "let-alist" "\
+Let-bind dotted symbols to their cdrs in ALIST and execute BODY.
+Dotted symbol is any symbol starting with a `.'.  Only those present
+in BODY are let-bound and this search is done at compile time.
+
+For instance, the following code
+
+  (let-alist alist
+    (if (and .title .body)
+        .body
+      .site
+      .site.contents))
+
+essentially expands to
+
+  (let ((.title (cdr (assq \\='title alist)))
+        (.body  (cdr (assq \\='body alist)))
+        (.site  (cdr (assq \\='site alist)))
+        (.site.contents (cdr (assq \\='contents (cdr (assq \\='site alist))))))
+    (if (and .title .body)
+        .body
+      .site
+      .site.contents))
+
+If you nest `let-alist' invocations, the inner one can't access
+the variables of the outer one. You can, however, access alists
+inside the original alist by using dots inside the symbol, as
+displayed in the example above.
+
+\(fn ALIST &rest BODY)" nil t)
+
+(function-put 'let-alist 'lisp-indent-function '1)
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; let-alist-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/let-alist-1.0.5/let-alist-pkg.el b/configs/shared/emacs/.emacs.d/elpa/let-alist-1.0.5/let-alist-pkg.el
new file mode 100644
index 0000000000..30740b7cd3
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/let-alist-1.0.5/let-alist-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "let-alist" "1.0.5" "Easily let-bind values of an assoc-list by their names" '((emacs "24.1")) :url "http://elpa.gnu.org/packages/let-alist.html" :keywords '("extensions" "lisp"))
diff --git a/configs/shared/emacs/.emacs.d/elpa/let-alist-1.0.5/let-alist.el b/configs/shared/emacs/.emacs.d/elpa/let-alist-1.0.5/let-alist.el
new file mode 100644
index 0000000000..43973c26cd
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/let-alist-1.0.5/let-alist.el
@@ -0,0 +1,182 @@
+;;; let-alist.el --- Easily let-bind values of an assoc-list by their names -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2014-2017 Free Software Foundation, Inc.
+
+;; Author: Artur Malabarba <emacs@endlessparentheses.com>
+;; Package-Requires: ((emacs "24.1"))
+;; Version: 1.0.5
+;; Keywords: extensions lisp
+;; Prefix: let-alist
+;; Separator: -
+
+;; This is an Elpa :core package. Don't use functionality that is not
+;; compatible with Emacs 24.1.
+
+;; 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:
+
+;; This package offers a single macro, `let-alist'.  This macro takes a
+;; first argument (whose value must be an alist) and a body.
+;;
+;; The macro expands to a let form containing body, where each dotted
+;; symbol inside body is let-bound to their cdrs in the alist.  Dotted
+;; symbol is any symbol starting with a `.'.  Only those present in
+;; the body are let-bound and this search is done at compile time.
+;;
+;; For instance, the following code
+;;
+;;   (let-alist alist
+;;     (if (and .title .body)
+;;         .body
+;;       .site
+;;       .site.contents))
+;;
+;; essentially expands to
+;;
+;;   (let ((.title (cdr (assq 'title alist)))
+;;         (.body  (cdr (assq 'body alist)))
+;;         (.site  (cdr (assq 'site alist)))
+;;         (.site.contents (cdr (assq 'contents (cdr (assq 'site alist))))))
+;;     (if (and .title .body)
+;;         .body
+;;       .site
+;;       .site.contents))
+;;
+;; If you nest `let-alist' invocations, the inner one can't access
+;; the variables of the outer one. You can, however, access alists
+;; inside the original alist by using dots inside the symbol, as
+;; displayed in the example above by the `.site.contents'.
+;;
+;;; Code:
+
+
+(defun let-alist--deep-dot-search (data)
+  "Return alist of symbols inside DATA that start with a `.'.
+Perform a deep search and return an alist where each car is the
+symbol, and each cdr is the same symbol without the `.'."
+  (cond
+   ((symbolp data)
+    (let ((name (symbol-name data)))
+      (when (string-match "\\`\\." name)
+        ;; Return the cons cell inside a list, so it can be appended
+        ;; with other results in the clause below.
+        (list (cons data (intern (replace-match "" nil nil name)))))))
+   ((not (consp data)) nil)
+   ((eq (car data) 'let-alist)
+    ;; For nested ‘let-alist’ forms, ignore symbols appearing in the
+    ;; inner body because they don’t refer to the alist currently
+    ;; being processed.  See Bug#24641.
+    (let-alist--deep-dot-search (cadr data)))
+   (t (append (let-alist--deep-dot-search (car data))
+              (let-alist--deep-dot-search (cdr data))))))
+
+(defun let-alist--access-sexp (symbol variable)
+  "Return a sexp used to access SYMBOL inside VARIABLE."
+  (let* ((clean (let-alist--remove-dot symbol))
+         (name (symbol-name clean)))
+    (if (string-match "\\`\\." name)
+        clean
+      (let-alist--list-to-sexp
+       (mapcar #'intern (nreverse (split-string name "\\.")))
+       variable))))
+
+(defun let-alist--list-to-sexp (list var)
+  "Turn symbols LIST into recursive calls to `cdr' `assq' on VAR."
+  `(cdr (assq ',(car list)
+              ,(if (cdr list) (let-alist--list-to-sexp (cdr list) var)
+                 var))))
+
+(defun let-alist--remove-dot (symbol)
+  "Return SYMBOL, sans an initial dot."
+  (let ((name (symbol-name symbol)))
+    (if (string-match "\\`\\." name)
+        (intern (replace-match "" nil nil name))
+      symbol)))
+
+
+;;; The actual macro.
+;;;###autoload
+(defmacro let-alist (alist &rest body)
+  "Let-bind dotted symbols to their cdrs in ALIST and execute BODY.
+Dotted symbol is any symbol starting with a `.'.  Only those present
+in BODY are let-bound and this search is done at compile time.
+
+For instance, the following code
+
+  (let-alist alist
+    (if (and .title .body)
+        .body
+      .site
+      .site.contents))
+
+essentially expands to
+
+  (let ((.title (cdr (assq \\='title alist)))
+        (.body  (cdr (assq \\='body alist)))
+        (.site  (cdr (assq \\='site alist)))
+        (.site.contents (cdr (assq \\='contents (cdr (assq \\='site alist))))))
+    (if (and .title .body)
+        .body
+      .site
+      .site.contents))
+
+If you nest `let-alist' invocations, the inner one can't access
+the variables of the outer one. You can, however, access alists
+inside the original alist by using dots inside the symbol, as
+displayed in the example above."
+  (declare (indent 1) (debug t))
+  (let ((var (make-symbol "alist")))
+    `(let ((,var ,alist))
+       (let ,(mapcar (lambda (x) `(,(car x) ,(let-alist--access-sexp (car x) var)))
+                     (delete-dups (let-alist--deep-dot-search body)))
+         ,@body))))
+
+;;;; ChangeLog:
+
+;; 2015-12-01  Artur Malabarba  <bruce.connor.am@gmail.com>
+;; 
+;; 	packages/let-alist: Define it as a :core package
+;; 
+;; 2015-06-11  Artur Malabarba  <bruce.connor.am@gmail.com>
+;; 
+;; 	* let-alist (let-alist--deep-dot-search): Fix cons
+;; 
+;; 2015-03-07  Artur Malabarba  <bruce.connor.am@gmail.com>
+;; 
+;; 	let-alist: Update copyright
+;; 
+;; 2014-12-22  Artur Malabarba  <bruce.connor.am@gmail.com>
+;; 
+;; 	packages/let-alist: Use `make-symbol' instead of `gensym'.
+;; 
+;; 2014-12-20  Artur Malabarba  <bruce.connor.am@gmail.com>
+;; 
+;; 	packages/let-alist: Enable access to deeper alists
+;; 
+;; 2014-12-14  Artur Malabarba  <bruce.connor.am@gmail.com>
+;; 
+;; 	let-alist.el: Add lexical binding. Version bump.
+;; 
+;; 2014-12-11  Artur Malabarba  <bruce.connor.am@gmail.com>
+;; 
+;; 	let-alist: New package
+;; 
+
+
+(provide 'let-alist)
+
+;;; let-alist.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/let-alist-1.0.5/let-alist.elc b/configs/shared/emacs/.emacs.d/elpa/let-alist-1.0.5/let-alist.elc
new file mode 100644
index 0000000000..59bd437099
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/let-alist-1.0.5/let-alist.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/log4e-20170401.604/log4e-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/log4e-20170401.604/log4e-autoloads.el
new file mode 100644
index 0000000000..bfa1aa9aa7
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/log4e-20170401.604/log4e-autoloads.el
@@ -0,0 +1,29 @@
+;;; log4e-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "log4e" "log4e.el" (23377 61297 288780 794000))
+;;; Generated autoloads from log4e.el
+
+(autoload 'log4e-mode "log4e" "\
+Major mode for browsing a buffer made by log4e.
+
+\\<log4e-mode-map>
+\\{log4e-mode-map}
+
+\(fn)" t nil)
+
+(autoload 'log4e:insert-start-log-quickly "log4e" "\
+Insert logging statment for trace level log at start of current function/macro.
+
+\(fn)" t nil)
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; log4e-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/log4e-20170401.604/log4e-pkg.el b/configs/shared/emacs/.emacs.d/elpa/log4e-20170401.604/log4e-pkg.el
new file mode 100644
index 0000000000..584d7fb031
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/log4e-20170401.604/log4e-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "log4e" "20170401.604" "provide logging framework for elisp" 'nil)
diff --git a/configs/shared/emacs/.emacs.d/elpa/log4e-20170401.604/log4e.el b/configs/shared/emacs/.emacs.d/elpa/log4e-20170401.604/log4e.el
new file mode 100644
index 0000000000..b60f8f7a8e
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/log4e-20170401.604/log4e.el
@@ -0,0 +1,592 @@
+;;; log4e.el --- provide logging framework for elisp
+
+;; Copyright (C) 2013  Hiroaki Otsu
+
+;; Author: Hiroaki Otsu <ootsuhiroaki@gmail.com>
+;; Keywords: log
+;; Package-Version: 20170401.604
+;; URL: https://github.com/aki2o/log4e
+;; Version: 0.3.1
+
+;; This program 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.
+
+;; This file 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; 
+;; This extension provides logging framework for elisp.
+
+;;; Dependency:
+;; 
+;; Nothing.
+
+;;; Installation:
+;;
+;; Put this to your load-path.
+;; And put the following lines in your elisp file.
+;; 
+;; (require 'log4e)
+
+;;; Configuration:
+;; 
+;; See <https://github.com/aki2o/log4e/blob/master/README.md>
+;; Otherwise, eval following sexp.
+;; (describe-function 'log4e:deflogger)
+
+;;; API:
+;; 
+;; [EVAL] (autodoc-document-lisp-buffer :type 'command :prefix "log4e:" :docstring t)
+;; `log4e:next-log'
+;; Move to start of next log on log4e-mode.
+;; `log4e:previous-log'
+;; Move to start of previous log on log4e-mode.
+;; `log4e:insert-start-log-quickly'
+;; Insert logging statment for trace level log at start of current function/macro.
+;; 
+;;  *** END auto-documentation
+;; 
+;; For detail, see <https://github.com/aki2o/log4e/blob/master/README.md>
+;; 
+;; [Note] Other than listed above, Those specifications may be changed without notice.
+
+;;; Tested On:
+;; 
+;; - Emacs ... GNU Emacs 23.3.1 (i386-mingw-nt5.1.2600) of 2011-08-15 on GNUPACK
+
+
+;; Enjoy!!!
+
+
+;;; Code:
+(eval-when-compile (require 'cl))
+(require 'rx)
+
+
+(defconst log4e-log-level-alist '((fatal . 6)
+                                  (error . 5)
+                                  (warn  . 4)
+                                  (info  . 3)
+                                  (debug . 2)
+                                  (trace . 1))
+  "Alist of log level value.")
+
+(defconst log4e-default-logging-function-name-alist '((fatal . "log-fatal")
+                                                      (error . "log-error")
+                                                      (warn  . "log-warn")
+                                                      (info  . "log-info")
+                                                      (debug . "log-debug")
+                                                      (trace . "log-trace"))
+  "Alist of logging function name at default.")
+
+
+(defmacro log4e--def-symmaker (symnm)
+  `(progn
+     (defsubst ,(intern (concat "log4e--make-symbol-" symnm)) (prefix)
+       (intern (concat ,(format "log4e--%s-" symnm) prefix)))))
+
+(log4e--def-symmaker "log-buffer")
+(log4e--def-symmaker "msg-buffer")
+(log4e--def-symmaker "log-template")
+(log4e--def-symmaker "time-template")
+(log4e--def-symmaker "min-level")
+(log4e--def-symmaker "max-level")
+(log4e--def-symmaker "toggle-logging")
+(log4e--def-symmaker "toggle-debugging")
+(log4e--def-symmaker "buffer-coding-system")
+(log4e--def-symmaker "author-mail-address")
+
+(defmacro log4e--def-level-logger (prefix suffix level)
+  (let ((argform (if suffix
+                     '(msg &rest msgargs)
+                   '(level msg &rest msgargs)))
+        (buff (log4e--make-symbol-log-buffer prefix))
+        (codsys (log4e--make-symbol-buffer-coding-system prefix))
+        (logtmpl (log4e--make-symbol-log-template prefix))
+        (timetmpl (log4e--make-symbol-time-template prefix))
+        (minlvl (log4e--make-symbol-min-level prefix))
+        (maxlvl (log4e--make-symbol-max-level prefix))
+        (logging-p (log4e--make-symbol-toggle-logging prefix)))
+    `(progn
+
+       ;; Define logging function
+       (defun ,(intern (concat prefix "--" (or suffix "log"))) ,argform
+         ,(format "Do logging for %s level log.
+%sMSG/MSGARGS are passed to `format'."
+                  (or (eval level) "any")
+                  (if suffix "" "LEVEL is symbol as a log level in '(trace debug info warn error fatal).\n"))
+         (let ((log4e--current-msg-buffer ,(log4e--make-symbol-msg-buffer prefix)))
+           (apply 'log4e--logging ,buff ,codsys ,logtmpl ,timetmpl ,minlvl ,maxlvl ,logging-p ,(if suffix level 'level) msg msgargs)))
+       
+       ;; Define logging macro
+       (defmacro ,(intern (concat prefix "--" (or suffix "log") "*")) ,argform
+         ,(format "Do logging for %s level log.
+%sMSG/MSGARGS are passed to `format'.
+Evaluation of MSGARGS is invoked only if %s level log should be printed."
+                  (or (eval level) "any")
+                  (if suffix "" "LEVEL is symbol as a log level in '(trace debug info warn error fatal).\n")
+                  (or (eval level) "the"))
+         (let ((prefix ,prefix)
+               (suffix ,suffix)
+               (level ',level)
+               (msg msg)
+               (msgargs msgargs)
+               (buff (log4e--make-symbol-log-buffer ,prefix))
+               (codsys (log4e--make-symbol-buffer-coding-system ,prefix))
+               (logtmpl (log4e--make-symbol-log-template ,prefix))
+               (timetmpl (log4e--make-symbol-time-template ,prefix))
+               (minlvl (log4e--make-symbol-min-level ,prefix))
+               (maxlvl (log4e--make-symbol-max-level ,prefix))
+               (logging-p (log4e--make-symbol-toggle-logging ,prefix)))
+           `(let ((log4e--current-msg-buffer ,(log4e--make-symbol-msg-buffer prefix)))
+              (when (and ,logging-p
+                         (log4e--logging-level-p ,minlvl ,maxlvl ,level))
+                (log4e--logging ,buff ,codsys ,logtmpl ,timetmpl ,minlvl ,maxlvl ,logging-p ,(if suffix level 'level) ,msg ,@msgargs)))))
+       
+       )))
+
+(defsubst log4e--logging-level-p (minlevel maxlevel currlevel)
+  (let ((minlvlvalue (or (assoc-default minlevel log4e-log-level-alist)
+                         1))
+        (maxlvlvalue (or (assoc-default maxlevel log4e-log-level-alist)
+                         6))
+        (currlvlvalue (or (assoc-default currlevel log4e-log-level-alist)
+                          0)))
+    (and (>= currlvlvalue minlvlvalue)
+         (<= currlvlvalue maxlvlvalue))))
+
+(defsubst log4e--get-or-create-log-buffer (buffnm &optional codesys)
+  (or (get-buffer buffnm)
+      (let ((buff (get-buffer-create buffnm)))
+        (with-current-buffer buff
+          (log4e-mode)
+          (when codesys
+            (setq buffer-file-coding-system codesys)))
+        buff)))
+
+(defvar log4e--regexp-msg-format
+  (rx-to-string `(and "%"
+                      (* (any "+#-0"))        ; flags
+                      (* (any "0-9"))         ; width
+                      (? "." (+ (any "0-9"))) ; precision
+                      (any "a-zA-Z"))))
+
+(defsubst log4e--insert-log (logtmpl timetmpl level msg msgargs propertize-p)
+  (let ((timetext (format-time-string timetmpl))
+        (lvltext (format "%-05s" (upcase (symbol-name level))))
+        (buffer-read-only nil))
+    (when propertize-p
+      (put-text-property 0 (length timetext) 'face 'font-lock-doc-face timetext)
+      (put-text-property 0 (length lvltext) 'face 'font-lock-keyword-face lvltext))
+    (let* ((logtext logtmpl)
+           (logtext (replace-regexp-in-string "%t" timetext logtext))
+           (logtext (replace-regexp-in-string "%l" lvltext logtext))
+           (logtext (replace-regexp-in-string "%m" msg logtext))
+           (begin (point)))
+      (insert logtext "\n")
+      (when propertize-p
+        (put-text-property begin (+ begin 1) 'log4e--level level))
+      (loop initially (goto-char begin)
+            while (and msgargs
+                       (re-search-forward log4e--regexp-msg-format nil t))
+            for currtype = (match-string-no-properties 0)
+            for currarg = (pop msgargs)
+            for failfmt = nil
+            for currtext = (condition-case e
+                               (format currtype currarg)
+                             (error (setq failfmt t)
+                                    (format "=%s=" (error-message-string e))))
+            if propertize-p
+            do (ignore-errors
+                 (cond (failfmt (put-text-property 0 (length currtext) 'face 'font-lock-warning-face currtext))
+                       (t       (put-text-property 0 (length currtext) 'face 'font-lock-string-face currtext))))
+            do (replace-match currtext t t))
+      (goto-char begin))))
+
+(defvar log4e--current-msg-buffer nil)
+
+;; We needs this signature be stay for other compiled plugins using old version
+(defun log4e--logging (buffnm codsys logtmpl timetmpl minlevel maxlevel logging-p level msg &rest msgargs)
+  (when (and logging-p
+             (log4e--logging-level-p minlevel maxlevel level))
+    (save-match-data
+      (with-current-buffer (log4e--get-or-create-log-buffer buffnm codsys)
+        (goto-char (point-max))
+        (let* ((buffer-read-only nil)
+               (begin (point))
+               (currlog (progn
+                          (log4e--insert-log logtmpl timetmpl level msg msgargs t)
+                          (goto-char (point-max))
+                          (buffer-substring-no-properties begin (point))))
+               (msgbuf (or (when (and log4e--current-msg-buffer
+                                      (not (eq log4e--current-msg-buffer t)))
+                             (ignore-errors (get-buffer log4e--current-msg-buffer)))
+                           log4e--current-msg-buffer)))
+          (when msgbuf
+            (let ((standard-output (if (buffer-live-p msgbuf)
+                                       msgbuf
+                                     standard-output)))
+              (princ currlog))))
+        nil))))
+
+(defun log4e--get-current-log-line-level ()
+  (save-excursion
+    (beginning-of-line)
+    (get-text-property (point) 'log4e--level)))
+
+;; We needs this signature be stay for other plugins compiled with this old version
+(defun log4e--clear-log (buffnm)
+  (with-current-buffer (log4e--get-or-create-log-buffer buffnm)
+    (setq buffer-read-only nil)
+    (erase-buffer)))
+
+;; We needs this signature be stay for other plugins compiled with this old version
+(defun log4e--open-log (buffnm)
+  (let* ((buff (get-buffer buffnm)))
+    (if (not (buffer-live-p buff))
+        (message "[Log4E] Not exist log buffer.")
+      (with-current-buffer buff
+        (setq buffer-read-only t))
+      (pop-to-buffer buff))))
+
+;; We needs this signature be stay for other plugins compiled with this old version
+(defun log4e--open-log-if-debug (buffnm dbg)
+  (when dbg
+    (log4e--open-log buffnm)))
+
+;; (defun log4e--send-report-if-not-debug (buffnm dbg addr prefix)
+;;   (let* ((buff (get-buffer buffnm)))
+;;     (when (and (not dbg)
+;;                (stringp addr)
+;;                (buffer-live-p buff))
+;;       (reporter-submit-bug-report addr prefix nil nil nil nil))))
+
+
+(defmacro log4e:deflogger (prefix msgtmpl timetmpl &optional log-function-name-custom-alist)
+  "Define the functions of logging for your elisp.
+
+Specification:
+ After eval this, you can use the functions for supporting about logging. They are the following ...
+ - do logging for each log level. Log level are trace, debug, info, warn, error and fatal.
+ - set max and min log level.
+ - switch logging.
+ - switch debugging.
+ - open and clear log buffer.
+ - send bug report for you.
+ For details, see Functions section.
+
+Argument:
+ - PREFIX is string as your elisp prefix.
+ - MSGTMPL is string as format of log. The following words has a special meaning.
+   - %t ... Replaced with time string. About it, see TIMETMPL argument.
+   - %l ... Replaced with log level. They are 'TRACE', 'DEBUG', 'INFO', 'WARN', 'ERROR', 'FATAL'.
+   - %m ... Replaced with log message that passed by you.
+ - TIMETMPL is string as format of time. This value is passed to `format-time-string'.
+ - LOG-FUNCTION-NAME-CUSTOM-ALIST is alist as the function name of logging.
+   - If this value is nil, define the following functions.
+      yourprefix--log-trace
+      yourprefix--log-debug
+      ...
+      yourprefix--log-fatal
+   - If you want to custom the name of them, give like the following value.
+      '((fatal . \"fatal\")
+        (error . \"error\")
+        (warn  . \"warn\")
+        (info  . \"info\")
+        (debug . \"debug\")
+        (trace . \"trace\"))
+     Then, define the following functions.
+      yourprefix--trace
+      yourprefix--debug
+      ...
+      yourprefix--fatal
+
+Functions:
+ List all functions defined below. PREFIX is your prefix.
+ - PREFIX--log-fatal    ... #1
+ - PREFIX--log-error    ... #1
+ - PREFIX--log-warn     ... #1
+ - PREFIX--log-info     ... #1
+ - PREFIX--log-debug    ... #1
+ - PREFIX--log-trace    ... #1
+ - PREFIX--log-fatal*   ... #2
+ - PREFIX--log-error*   ... #2
+ - PREFIX--log-warn*    ... #2
+ - PREFIX--log-info*    ... #2
+ - PREFIX--log-debug*   ... #2
+ - PREFIX--log-trace*   ... #2
+ - PREFIX--log
+ - PREFIX--log-set-level
+ - PREFIX--log-enable-logging            ... #3
+ - PREFIX--log-disable-logging           ... #3
+ - PREFIX--log-enable-messaging          ... #3
+ - PREFIX--log-disable-messaging         ... #3
+ - PREFIX--log-enable-debugging          ... #3
+ - PREFIX--log-disable-debugging         ... #3
+ - PREFIX--log-debugging-p
+ - PREFIX--log-set-coding-system
+ - PREFIX--log-set-author-mail-address
+ - PREFIX--log-clear-log                 ... #3
+ - PREFIX--log-open-log                  ... #3
+ - PREFIX--log-open-log-if-debug
+
+ #1 : You can customize this name
+ #2 : Name is a #1 name + \"*\"
+ #3 : This is command
+
+Example:
+;; If you develop elisp that has prefix \"hoge\", write and eval the following sexp in your elisp file.
+
+ (require 'log4e)
+ (log4e:deflogger \"hoge\" \"%t [%l] %m\" \"%H:%M:%S\")
+
+;; Eval the following
+ (hoge--log-enable-logging)
+
+;; Then, write the following
+
+ (defun hoge-do-hoge (hoge)
+   (if (not (stringp hoge))
+       (hoge--log-fatal \"failed do hoge : hoge is '%s'\" hoge)
+     (hoge--log-debug \"start do hoge about '%s'\" hoge)
+     (message \"hoge!\")
+     (hoge--log-info \"done hoge about '%s'\" hoge)))
+
+;; Eval the following
+ (hoge-do-hoge \"HOGEGE\")
+
+;; Do M-x hoge--log-open-log
+;; Open the buffer which name is \" *log4e-hoge*\". The buffer string is below
+12:34:56 [INFO ] done hoge about 'HOGEGE'
+
+;; Eval the following
+ (hoge--log-set-level 'trace)
+ (hoge-do-hoge \"FUGAGA\")
+
+;; Do M-x hoge--log-open-log
+;; Open the buffer. its string is below
+12:34:56 [INFO ] done hoge about 'HOGEGE'
+12:35:43 [DEBUG] start do hoge about 'FUGAGA'
+12:35:43 [INFO ] done hoge about 'FUGAGA'
+ 
+"
+  (declare (indent 0))
+  (if (or (not (stringp prefix))   (string= prefix "")
+          (not (stringp msgtmpl))  (string= msgtmpl "")
+          (not (stringp timetmpl)) (string= timetmpl ""))
+      (message "[LOG4E] invalid argument of deflogger")
+    (let* ((bufsym (log4e--make-symbol-log-buffer prefix))
+           (msgbufsym (log4e--make-symbol-msg-buffer prefix))
+           (logtmplsym (log4e--make-symbol-log-template prefix))
+           (timetmplsym (log4e--make-symbol-time-template prefix))
+           (minlvlsym (log4e--make-symbol-min-level prefix))
+           (maxlvlsym (log4e--make-symbol-max-level prefix))
+           (tglsym (log4e--make-symbol-toggle-logging prefix))
+           (dbgsym (log4e--make-symbol-toggle-debugging prefix))
+           (codsyssym (log4e--make-symbol-buffer-coding-system prefix))
+           (addrsym (log4e--make-symbol-author-mail-address prefix))
+           (funcnm-alist (loop with custom-alist = (car (cdr log-function-name-custom-alist))
+                                  for lvl in '(fatal error warn info debug trace)
+                                  for lvlpair = (assq lvl custom-alist)
+                                  for fname = (or (cdr-safe lvlpair) "")
+                                  collect (or (if (string-match "\*" fname)
+                                                  (progn
+                                                    (message "[LOG4E] ignore %s level name in log-function-name-custom-alist. can't use '*' for the name." lvl)
+                                                    nil)
+                                                lvlpair)
+                                              (assq lvl log4e-default-logging-function-name-alist)))))
+      `(progn
+
+         ;; Define variable for prefix
+         (defvar ,bufsym (format " *log4e-%s*" ,prefix))
+         (defvar ,logtmplsym ,msgtmpl)
+         (defvar ,timetmplsym ,timetmpl)
+         (defvar ,minlvlsym 'info)
+         (defvar ,maxlvlsym 'fatal)
+         (defvar ,tglsym nil)
+         (defvar ,msgbufsym nil)
+         (defvar ,dbgsym nil)
+         (defvar ,codsyssym nil)
+         (defvar ,addrsym nil)
+
+         ;; Define level set function
+         (defun ,(intern (concat prefix "--log-set-level")) (minlevel &optional maxlevel)
+           "Set range for doing logging.
+
+MINLEVEL is symbol of lowest level for doing logging. its default is 'info.
+MAXLEVEL is symbol of highest level for doing logging. its default is 'fatal."
+           (setq ,minlvlsym minlevel)
+           (setq ,maxlvlsym maxlevel))
+
+         ;; Define logging toggle function
+         (defun ,(intern (concat prefix "--log-enable-logging")) ()
+           "Enable logging by logging functions."
+           (interactive)
+           (setq ,tglsym t))
+         (defun ,(intern (concat prefix "--log-disable-logging")) ()
+           "Disable logging by logging functions."
+           (interactive)
+           (setq ,tglsym nil))
+
+         ;; Define messaging toggle function
+         (defun ,(intern (concat prefix "--log-enable-messaging")) (&optional buffer)
+           "Enable dump the log into other buffer by logging functions.
+
+BUFFER is a buffer dumped log into. nil means *Messages* buffer."
+           (interactive)
+           (setq ,msgbufsym (or buffer t)))
+         (defun ,(intern (concat prefix "--log-disable-messaging")) ()
+           "Disable dump the log into other buffer by logging functions."
+           (interactive)
+           (setq ,msgbufsym nil))
+
+         ;; Define debugging toggle function
+         (defun ,(intern (concat prefix "--log-enable-debugging")) ()
+           "Enable debugging and logging.
+
+`PREFIX--log-debugging-p' will return t."
+           (interactive)
+           (setq ,tglsym t)
+           (setq ,dbgsym t))
+         (defun ,(intern (concat prefix "--log-disable-debugging")) ()
+           "Disable debugging.
+
+`PREFIX--log-debugging-p' will return nil."
+           (interactive)
+           (setq ,dbgsym nil))
+         (defun ,(intern (concat prefix "--log-debugging-p")) ()
+           ,dbgsym)
+
+         ;; Define coding system set funtion
+         (defun ,(intern (concat prefix "--log-set-coding-system")) (coding-system)
+           "Set charset and linefeed of LOG-BUFFER.
+
+CODING-SYSTEM is symbol for setting to `buffer-file-coding-system'.
+LOG-BUFFER is a buffer which name is \" *log4e-PREFIX*\"."
+           (setq ,codsyssym coding-system))
+
+         ;;          ;; Define author mail set function
+         ;;          (defun ,(intern (concat prefix "--log-set-author-mail-address")) (before-atmark after-atmark)
+         ;;            "Set mail address of author for elisp that has PREFIX. This value is used SEND-REPORT.
+
+         ;; BEFORE-ATMARK is string as part of mail address. If your address is \"hoge@example.co.jp\", it is \"hoge\".
+         ;; AFTER-ATMARK is string as part of mail address. If your address is \"hoge@example.co.jp\", it is \"example.co.jp\".
+         ;; SEND-REPORT is `PREFIX--log-send-report-if-not-debug'."
+         ;;            (setq ,addrsym (concat before-atmark "@" after-atmark)))
+
+         ;; Define log buffer handle function
+         (defun ,(intern (concat prefix "--log-clear-log")) ()
+           "Clear buffer string of buffer which name is \" *log4e-PREFIX*\"."
+           (interactive)
+           (log4e--clear-log ,bufsym))
+         (defun ,(intern (concat prefix "--log-open-log")) ()
+           "Open buffer which name is \" *log4e-PREFIX*\"."
+           (interactive)
+           (log4e--open-log ,bufsym))
+         (defun ,(intern (concat prefix "--log-open-log-if-debug")) ()
+           "Open buffer which name is \" *log4e-PREFIX*\" if debugging is enabled."
+           (log4e--open-log-if-debug ,bufsym ,dbgsym))
+
+         ;;          ;; Define report send function
+         ;;          (defun ,(intern (concat prefix "--log-send-report-if-not-debug")) ()
+         ;;            "Send bug report to author if debugging is disabled.
+
+         ;; The author mailaddress is set by `PREFIX--log-set-author-mail-address'.
+         ;; About the way of sending bug report, see `reporter-submit-bug-report'."
+         ;;            (log4e--send-report-if-not-debug ,bufsym ,dbgsym ,addrsym ,prefix))
+
+         ;; Define each level logging function
+         (log4e--def-level-logger ,prefix nil nil)
+         (log4e--def-level-logger ,prefix ,(assoc-default 'fatal funcnm-alist) 'fatal)
+         (log4e--def-level-logger ,prefix ,(assoc-default 'error funcnm-alist) 'error)
+         (log4e--def-level-logger ,prefix ,(assoc-default 'warn  funcnm-alist) 'warn)
+         (log4e--def-level-logger ,prefix ,(assoc-default 'info  funcnm-alist) 'info)
+         (log4e--def-level-logger ,prefix ,(assoc-default 'debug funcnm-alist) 'debug)
+         (log4e--def-level-logger ,prefix ,(assoc-default 'trace funcnm-alist) 'trace)
+         
+         ))))
+
+
+;;;###autoload
+(define-derived-mode log4e-mode view-mode "Log4E"
+  "Major mode for browsing a buffer made by log4e.
+
+\\<log4e-mode-map>
+\\{log4e-mode-map}"
+  (define-key log4e-mode-map (kbd "J") 'log4e:next-log)
+  (define-key log4e-mode-map (kbd "K") 'log4e:previous-log))
+
+(defun log4e:next-log ()
+  "Move to start of next log on log4e-mode."
+  (interactive)
+  (let* ((level))
+    (while (and (not level)
+                (< (point) (point-max)))
+      (forward-line 1)
+      (setq level (log4e--get-current-log-line-level)))
+    level))
+
+(defun log4e:previous-log ()
+  "Move to start of previous log on log4e-mode."
+  (interactive)
+  (let* ((level))
+    (while (and (not level)
+                (> (point) (point-min)))
+      (forward-line -1)
+      (setq level (log4e--get-current-log-line-level)))
+    level))
+
+;;;###autoload
+(defun log4e:insert-start-log-quickly ()
+  "Insert logging statment for trace level log at start of current function/macro."
+  (interactive)
+  (let* ((fstartpt (when (re-search-backward "(\\(?:defun\\|defmacro\\|defsubst\\)\\*? +\\([^ ]+\\) +(\\([^)]*\\))" nil t)
+                     (point)))
+         (fncnm (when fstartpt (match-string-no-properties 1)))
+         (argtext (when fstartpt (match-string-no-properties 2)))
+         (prefix (save-excursion
+                   (goto-char (point-min))
+                   (loop while (re-search-forward "(log4e:deflogger[ \n]+\"\\([^\"]+\\)\"" nil t)
+                            for prefix = (match-string-no-properties 1)
+                            for currface = (get-text-property (match-beginning 0) 'face)
+                            if (not (eq currface 'font-lock-comment-face))
+                            return prefix))))
+    (when (and fstartpt prefix)
+      (let* ((fncnm (replace-regexp-in-string (concat "\\`" prefix "[^a-zA-Z0-9]+") "" fncnm))
+             (fncnm (replace-regexp-in-string "-" " " fncnm))
+             (argtext (replace-regexp-in-string "\n" " " argtext))
+             (argtext (replace-regexp-in-string "^ +" "" argtext))
+             (argtext (replace-regexp-in-string " +$" "" argtext))
+             (args (split-string argtext " +"))
+             (args (loop for arg in args
+                            if (and (not (string= arg ""))
+                                    (not (string-match "\\`&" arg)))
+                            collect arg))
+             (logtext (loop with ret = (format "start %s." fncnm)
+                               for arg in args
+                               do (setq ret (concat ret " " arg "[%s]"))
+                               finally return ret))
+             (sexpformat (loop with ret = "(%s--log 'trace \"%s\""
+                                  for arg in args
+                                  do (setq ret (concat ret " %s"))
+                                  finally return (concat ret ")")))
+             (inserttext (apply 'format sexpformat prefix logtext args)))
+        (forward-char)
+        (forward-sexp 3)
+        (when (re-search-forward "\\=[ \n]+\"" nil t)
+          (forward-char -1)
+          (forward-sexp))
+        (newline-and-indent)
+        (insert inserttext)))))
+
+
+(provide 'log4e)
+;;; log4e.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/log4e-20170401.604/log4e.elc b/configs/shared/emacs/.emacs.d/elpa/log4e-20170401.604/log4e.elc
new file mode 100644
index 0000000000..8570c5d8fe
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/log4e-20170401.604/log4e.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/lsp-haskell-20180826.1119/lsp-haskell-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/lsp-haskell-20180826.1119/lsp-haskell-autoloads.el
new file mode 100644
index 0000000000..d3069465bb
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/lsp-haskell-20180826.1119/lsp-haskell-autoloads.el
@@ -0,0 +1,31 @@
+;;; lsp-haskell-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "lsp-haskell" "lsp-haskell.el" (23428 20523
+;;;;;;  947450 33000))
+;;; Generated autoloads from lsp-haskell.el
+
+(let ((loads (get 'lsp-haskell 'custom-loads))) (if (member '"lsp-haskell" loads) nil (put 'lsp-haskell 'custom-loads (cons '"lsp-haskell" loads))))
+
+(defvar lsp-haskell-process-path-hie "hie-wrapper" "\
+The path for starting the haskell-ide-engine
+server. hie-wrapper exists on HIE master from 2018-06-10")
+
+(custom-autoload 'lsp-haskell-process-path-hie "lsp-haskell" t)
+
+(defvar lsp-haskell-process-args-hie '("-d" "-l" "/tmp/hie.log") "\
+The arguments for starting the haskell-ide-engine server.
+For a debug log, use `-d -l /tmp/hie.log'.")
+
+(custom-autoload 'lsp-haskell-process-args-hie "lsp-haskell" t)
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; lsp-haskell-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/lsp-haskell-20180826.1119/lsp-haskell-pkg.el b/configs/shared/emacs/.emacs.d/elpa/lsp-haskell-20180826.1119/lsp-haskell-pkg.el
new file mode 100644
index 0000000000..8a697f7d90
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/lsp-haskell-20180826.1119/lsp-haskell-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "lsp-haskell" "20180826.1119" "Haskell support for lsp-mode" '((lsp-mode "3.0") (haskell-mode "1.0")) :commit "1173dbc4299717058b0a33e473d138d60761e92e" :keywords '("haskell") :url "https://github.com/emacs-lsp/lsp-haskell")
diff --git a/configs/shared/emacs/.emacs.d/elpa/lsp-haskell-20180826.1119/lsp-haskell.el b/configs/shared/emacs/.emacs.d/elpa/lsp-haskell-20180826.1119/lsp-haskell.el
new file mode 100644
index 0000000000..4197334b9c
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/lsp-haskell-20180826.1119/lsp-haskell.el
@@ -0,0 +1,301 @@
+;;; lsp-haskell.el --- Haskell support for lsp-mode
+
+;; Version: 1.0
+;; Package-Version: 20180826.1119
+;; Package-Requires: ((lsp-mode "3.0") (haskell-mode "1.0"))
+;; Keywords: haskell
+;; URL: https://github.com/emacs-lsp/lsp-haskell
+
+;;; Code:
+
+(require 'haskell)
+(require 'lsp-mode)
+(require 'projectile nil 'noerror)
+
+;; ---------------------------------------------------------------------
+;; Configuration
+
+;;;###autoload
+(defgroup lsp-haskell nil
+  "Customization group for ‘lsp-haskell’."
+  :group 'lsp-mode)
+
+;;;###autoload
+(defcustom lsp-haskell-process-path-hie
+  ;; "hie"
+  "hie-wrapper"
+  "The path for starting the haskell-ide-engine
+server. hie-wrapper exists on HIE master from 2018-06-10"
+  :group 'lsp-haskell
+  :type '(choice string))
+
+;;;###autoload
+(defcustom lsp-haskell-process-args-hie
+  '("-d" "-l" "/tmp/hie.log")
+  "The arguments for starting the haskell-ide-engine server.
+For a debug log, use `-d -l /tmp/hie.log'."
+  :group 'lsp-haskell
+  :type '(repeat (string :tag "Argument")))
+
+;; ---------------------------------------------------------------------
+;; HaRe functions
+
+(defun lsp-demote ()
+  "Demote a function to the level it is used"
+  (interactive)
+  (lsp--cur-workspace-check)
+  (lsp--send-execute-command
+   "hare:demote"
+   (vector `(:file ,(concat "file://" buffer-file-name)
+             :pos  ,(lsp-point-to-position (point))))))
+
+(defun lsp-duplicate-definition (newname)
+  "Duplicate a definition"
+  (interactive "sNew definition name: ")
+  (lsp--cur-workspace-check)
+  (lsp--send-execute-command
+   "hare:dupdef"
+   (vector `(:file ,(concat "file://" buffer-file-name)
+             :pos  ,(lsp-point-to-position (point))
+             :text ,newname))))
+
+(defun lsp-if-to-case ()
+  "Convert an if statement to a case statement"
+  (interactive)
+  (lsp--cur-workspace-check)
+  (lsp--send-execute-command
+   "hare:iftocase"
+   (vector `(:file      ,(concat "file://" buffer-file-name)
+             :start_pos ,(lsp-get-start-position)
+             :end_pos   ,(lsp-get-end-position)))))
+
+(defun lsp-lift-level ()
+  "Lift a function to the top level"
+  (interactive)
+  (lsp--cur-workspace-check)
+  (lsp--send-execute-command
+   "hare:liftonelevel"
+   (vector `(:file ,(concat "file://" buffer-file-name)
+             :pos  ,(lsp-point-to-position (point))))))
+
+(defun lsp-lift-to-top ()
+  "Lift a function to the top level"
+  (interactive)
+  (lsp--cur-workspace-check)
+  (lsp--send-execute-command
+   "hare:lifttotoplevel"
+   (vector `(:file ,(concat "file://" buffer-file-name)
+             :pos  ,(lsp-point-to-position (point))))))
+
+(defun lsp-delete-definition ()
+  "Delete a definition"
+  (interactive)
+  (lsp--cur-workspace-check)
+  (lsp--send-execute-command
+   "hare:deletedef"
+   (vector `(:file ,(concat "file://" buffer-file-name)
+             :pos  ,(lsp-point-to-position (point))))))
+
+(defun lsp-generalise-applicative ()
+  "Generalise a monadic function to use applicative"
+  (interactive)
+  (lsp--cur-workspace-check)
+  (lsp--send-execute-command
+   "hare:genapplicative"
+   (vector `(:file ,(concat "file://" buffer-file-name)
+             :pos  ,(lsp-point-to-position (point))))))
+
+;; ---------------------------------------------------------------------
+
+(defun lsp-haskell--session-cabal-dir ()
+  "Get the session cabal-dir."
+  (let* ((cabal-file (haskell-cabal-find-file))
+         (cabal-dir (if cabal-file
+                        (file-name-directory cabal-file)
+                      "." ;; no cabal file, use directory only
+                      )))
+    (progn
+      (message "cabal-dir: %s" cabal-dir)
+      cabal-dir)))
+
+(defun lsp-haskell--get-root ()
+  "Get project root directory.
+
+First searches for root via projectile.  Tries to find cabal file
+if projectile way fails"
+  (if (fboundp 'projectile-project-root)
+      (projectile-project-root)
+    (let ((dir (lsp-haskell--session-cabal-dir)))
+      (if (string= dir "/")
+          (user-error (concat "Couldn't find cabal file, using:" dir))
+        dir))))
+
+;; ---------------------------------------------------------------------
+
+;;----------------------------------------------------------------------
+;; AZ: Not sure where this section should go, putting it here for now
+
+;; AZ: This section based on/inspired by the intero 'intero-apply-suggestions' code, at
+;; https://github.com/commercialhaskell/intero/blob/master/elisp/intero.el
+
+(defun lsp-apply-commands ()
+  "Prompt and apply any codeAction commands."
+  (interactive)
+  (if (null lsp-code-actions)
+      (message "No actions to apply")
+    (let ((to-apply
+           (lsp--intero-multiswitch
+            (format "There are %d suggestions to apply:" (length lsp-code-actions))
+            (cl-remove-if-not
+             #'identity
+             (mapcar
+              (lambda (suggestion)
+                ;; (pcase (plist-get suggestion :type)
+                ;;   (add-extension
+                ;;    (list :key suggestion
+                ;;          :title (concat "Add {-# LANGUAGE "
+                ;;                         (plist-get suggestion :extension)
+                ;;                         " #-}")
+                ;;          :default t))
+                ;;   (redundant-constraint
+                ;;    (list :key suggestion
+                ;;          :title (concat
+                ;;                  "Remove redundant constraints: "
+                ;;                  (string-join (plist-get suggestion :redundancies)
+                ;;                               ", ")
+                ;;                  "\n    from the "
+                ;;                  (plist-get suggestion :signature))
+                ;;          :default nil)))
+                ;; (message "lsp-apply-command:suggestion command=%s"    (gethash "command" suggestion))
+                ;; (message "lsp-apply-command:suggestion ommand=args%s" (gethash "arguments" suggestion))
+                (list :key   (gethash "title" suggestion)
+                      :title (gethash "title" suggestion)
+                      :type  "codeAction"
+                      :default t
+                      :command suggestion)
+                )
+              lsp-code-actions)))))
+      (if (null to-apply)
+          (message "No changes selected to apply.")
+        (let ((sorted (sort to-apply
+                            (lambda (lt gt)
+                              (let ((lt-line   (or (plist-get lt :line)   0))
+                                    (lt-column (or (plist-get lt :column) 0))
+                                    (gt-line   (or (plist-get gt :line)   0))
+                                    (gt-column (or (plist-get gt :column) 0)))
+                                (or (> lt-line gt-line)
+                                    (and (= lt-line gt-line)
+                                         (> lt-column gt-column))))))))
+          ;; # Changes unrelated to the buffer
+          (cl-loop
+           for suggestion in sorted
+           do ;; (message "lsp-apply-commands:suggestion=%s" suggestion)
+              (pcase (plist-get suggestion :type)
+                (otherwise
+                 (lsp--execute-lsp-server-command suggestion))))
+          ;; # Changes that do not increase/decrease line numbers
+          ;;
+          ;; Update in-place suggestions
+
+          ;; # Changes that do increase/decrease line numbers
+          ;;
+
+          ;; Add extensions to the top of the file
+          )))))
+
+;; The following is copied directly from intero. I suspect it would be better to
+;; have it in a dependency somewhere
+
+(defun lsp--intero-multiswitch (title options)
+  "Displaying TITLE, read multiple flags from a list of OPTIONS.
+Each option is a plist of (:key :default :title) wherein:
+
+  :key should be something comparable with EQUAL
+  :title should be a string
+  :default (boolean) specifies the default checkedness"
+  (let ((available-width (window-total-width)))
+    (save-window-excursion
+      (lsp--intero-with-temp-buffer
+        (rename-buffer (generate-new-buffer-name "multiswitch"))
+        (widget-insert (concat title "\n\n"))
+        (widget-insert (propertize "Hit " 'face 'font-lock-comment-face))
+        (widget-create 'push-button :notify
+                       (lambda (&rest ignore)
+                         (exit-recursive-edit))
+                       "C-c C-c")
+        (widget-insert (propertize " to apply these choices.\n\n" 'face 'font-lock-comment-face))
+        (let* ((me (current-buffer))
+               (choices (mapcar (lambda (option)
+                                  (append option (list :value (plist-get option :default))))
+                                options)))
+          (cl-loop for option in choices
+                   do (widget-create
+                       'toggle
+                       :notify (lambda (widget &rest ignore)
+                                 (setq choices
+                                       (mapcar (lambda (choice)
+                                                 (if (equal (plist-get choice :key)
+                                                            (plist-get (cdr widget) :key))
+                                                     (plist-put choice :value (plist-get (cdr widget) :value))
+                                                   choice))
+                                               choices)))
+                       :on (concat "[x] " (plist-get option :title))
+                       :off (concat "[ ] " (plist-get option :title))
+                       :value (plist-get option :default)
+                       :key (plist-get option :key)
+                       :command (plist-get option :command)))
+          (let ((lines (line-number-at-pos)))
+            (select-window (split-window-below))
+            (switch-to-buffer me)
+            (goto-char (point-min)))
+          (use-local-map
+           (let ((map (copy-keymap widget-keymap)))
+             (define-key map (kbd "C-c C-c") 'exit-recursive-edit)
+             (define-key map (kbd "C-g") 'abort-recursive-edit)
+             map))
+          (widget-setup)
+          (recursive-edit)
+          (kill-buffer me)
+          (mapcar (lambda (choice)
+                    (plist-get choice :command))
+                  (cl-remove-if-not (lambda (choice)
+                                      (plist-get choice :value))
+                                    choices)))))))
+
+;; The following is copied directly from intero. I suspect it would be better to
+;; have it in a dependency somewhere
+(defmacro lsp--intero-with-temp-buffer (&rest body)
+  "Run BODY in `with-temp-buffer', but inherit certain local variables from the current buffer first."
+  (declare (indent 0) (debug t))
+  `(let ((initial-buffer (current-buffer)))
+     (with-temp-buffer
+       (lsp--intero-inherit-local-variables initial-buffer)
+       ,@body)))
+
+;; The following is copied directly from intero. I suspect it would be better to
+;; have it in a dependency somewhere
+(defun lsp--intero-inherit-local-variables (buffer)
+  "Make the current buffer inherit values of certain local variables from BUFFER."
+  (let ((variables '(
+                     ;; TODO: shouldn’t more of the above be here?
+                     )))
+    (cl-loop for v in variables do
+             (set (make-local-variable v) (buffer-local-value v buffer)))))
+;; ---------------------------------------------------------------------
+
+(lsp-define-stdio-client lsp-haskell "haskell" #'lsp-haskell--get-root
+			 ;; '("hie" "--lsp" "-d" "-l" "/tmp/hie.log"))
+       ;; '("hie" "--lsp" "-d" "-l" "/tmp/hie.log" "--vomit"))
+       (lsp--haskell-hie-command))
+
+(defun lsp--haskell-hie-command ()
+  "Comamnd and arguments for launching the inferior hie process.
+These are assembled from the customizable variables
+ `lsp-haskell-process-path-hie' and
+ `lsp-haskell-process-args-hie'. If the hie executable is
+ installed via its Makefile, there will be compiler-specific
+ versions with names like 'hie-8.0.2' or 'hie-8.2.2'."
+   (append (list lsp-haskell-process-path-hie "--lsp") lsp-haskell-process-args-hie) )
+
+(provide 'lsp-haskell)
+;;; lsp-haskell.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/lsp-haskell-20180826.1119/lsp-haskell.elc b/configs/shared/emacs/.emacs.d/elpa/lsp-haskell-20180826.1119/lsp-haskell.elc
new file mode 100644
index 0000000000..1917cffde8
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/lsp-haskell-20180826.1119/lsp-haskell.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/lsp-javascript-flow-20180613.508/lsp-javascript-flow-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/lsp-javascript-flow-20180613.508/lsp-javascript-flow-autoloads.el
new file mode 100644
index 0000000000..3baef67e10
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/lsp-javascript-flow-20180613.508/lsp-javascript-flow-autoloads.el
@@ -0,0 +1,29 @@
+;;; lsp-javascript-flow-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "lsp-javascript-flow" "lsp-javascript-flow.el"
+;;;;;;  (23432 13006 579149 747000))
+;;; Generated autoloads from lsp-javascript-flow.el
+
+(defvar lsp-javascript-flow-server "flow-language-server" "\
+The flow-language-server executable to use.
+Leave as just the executable name to use the default behavior of
+finding the executable with `exec-path'.")
+
+(custom-autoload 'lsp-javascript-flow-server "lsp-javascript-flow" t)
+
+(defvar lsp-javascript-flow-server-args 'nil "\
+Extra arguments for the javascript-flow-stdio language server")
+
+(custom-autoload 'lsp-javascript-flow-server-args "lsp-javascript-flow" t)
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; lsp-javascript-flow-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/lsp-javascript-flow-20180613.508/lsp-javascript-flow-pkg.el b/configs/shared/emacs/.emacs.d/elpa/lsp-javascript-flow-20180613.508/lsp-javascript-flow-pkg.el
new file mode 100644
index 0000000000..8c4b9a3cd7
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/lsp-javascript-flow-20180613.508/lsp-javascript-flow-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "lsp-javascript-flow" "20180613.508" "Javascript/Flow support for lsp-mode" '((lsp-mode "3.0") (emacs "25.1")) :commit "7e7c5f66b02321f402712841064347cb872c41e4" :keywords '("languages" "tools") :authors '(("Ozan Sener" . "hi@ozan.email")) :maintainer '("Ozan Sener" . "hi@ozan.email") :url "https://github.com/emacs-lsp/lsp-javascript")
diff --git a/configs/shared/emacs/.emacs.d/elpa/lsp-javascript-flow-20180613.508/lsp-javascript-flow.el b/configs/shared/emacs/.emacs.d/elpa/lsp-javascript-flow-20180613.508/lsp-javascript-flow.el
new file mode 100644
index 0000000000..3b92ae5995
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/lsp-javascript-flow-20180613.508/lsp-javascript-flow.el
@@ -0,0 +1,71 @@
+;;; lsp-javascript-flow.el --- Javascript/Flow support for lsp-mode  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2017 George Pittarelli <g@gjp.cc>
+;; Copyright (C) 2017 Ozan Sener <hi@ozan.email>
+
+;; Author: Ozan Sener <hi@ozan.email>
+;; Version: 1.0
+;; Package-Version: 20180613.508
+;; Package-Requires: ((lsp-mode "3.0") (emacs "25.1"))
+;; Keywords: languages tools
+;; URL: https://github.com/emacs-lsp/lsp-javascript
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Javascript and Flow support for lsp-mode using
+;;   https://github.com/flowtype/flow-language-server
+
+;;; Code:
+
+(require 'lsp-mode)
+
+;;;###autoload
+(defcustom lsp-javascript-flow-server
+  "flow-language-server"
+  "The flow-language-server executable to use.
+Leave as just the executable name to use the default behavior of
+finding the executable with `exec-path'."
+  :group 'lsp-javascript-flow
+  :risky t
+  :type 'file)
+
+;;;###autoload
+(defcustom lsp-javascript-flow-server-args
+  '()
+  "Extra arguments for the javascript-flow-stdio language server"
+  :group 'lsp-javascript-flow
+  :risky t
+  :type '(repeat string))
+
+(defun lsp-javascript-flow--ls-command ()
+  "Generate the language server startup command."
+  `(,lsp-javascript-flow-server
+    "--stdio"
+    ,@lsp-javascript-flow-server-args))
+
+(defconst lsp-javascript-flow--get-root
+  (lsp-make-traverser #'(lambda (dir)
+                          (directory-files dir nil "package.json"))))
+
+(lsp-define-stdio-client
+ lsp-javascript-flow "javascript"
+ lsp-javascript-flow--get-root
+ nil
+ :ignore-messages '("\[INFO].*?nuclide")
+ :command-fn 'lsp-javascript-flow--ls-command)
+
+(provide 'lsp-javascript-flow)
+;;; lsp-javascript-flow.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/lsp-javascript-flow-20180613.508/lsp-javascript-flow.elc b/configs/shared/emacs/.emacs.d/elpa/lsp-javascript-flow-20180613.508/lsp-javascript-flow.elc
new file mode 100644
index 0000000000..18a036a48d
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/lsp-javascript-flow-20180613.508/lsp-javascript-flow.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/lsp-mode-20180827.344/lsp-common.el b/configs/shared/emacs/.emacs.d/elpa/lsp-mode-20180827.344/lsp-common.el
new file mode 100755
index 0000000000..0bf952fa72
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/lsp-mode-20180827.344/lsp-common.el
@@ -0,0 +1,192 @@
+;; Copyright (C) 2016-2018  Vibhav Pant <vibhavp@gmail.com>  -*- lexical-binding: t -*-
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Code:
+
+(require 'compile)
+(require 'url-util)
+(require 'url-parse)
+(require 'subr-x)
+(require 'filenotify)
+(require 'cl)
+
+(defconst lsp--message-type-face
+  `((1 . ,compilation-error-face)
+    (2 . ,compilation-warning-face)
+    (3 . ,compilation-message-face)
+    (4 . ,compilation-info-face)))
+
+(defcustom lsp-print-io nil
+  "If non-nil, print all messages to and from the language server to *Messages*."
+  :group 'lsp-mode
+  :type 'boolean)
+
+(defvar-local lsp--cur-workspace nil)
+
+(defvar lsp--uri-file-prefix (pcase system-type
+                               (`windows-nt "file:///")
+                               (_ "file://"))
+  "Prefix for a file-uri.")
+
+(defvar-local lsp-buffer-uri nil
+  "If set, return it instead of calculating it using `buffer-file-name'.")
+
+(define-error 'lsp-error "Unknown lsp-mode error")
+(define-error 'lsp-empty-response-error
+  "Empty response from the language server" 'lsp-error)
+(define-error 'lsp-timed-out-error
+  "Timed out while waiting for a response from the language server" 'lsp-error)
+(define-error 'lsp-capability-not-supported
+  "Capability not supported by the language server" 'lsp-error)
+
+(defun lsp--propertize (str type)
+  "Propertize STR as per TYPE."
+  (propertize str 'face (alist-get type lsp--message-type-face)))
+
+(defvar lsp--no-response)
+
+;; from http://emacs.stackexchange.com/questions/8082/how-to-get-buffer-position-given-line-number-and-column-number
+(defun lsp--position-to-point (params)
+  "Convert Position object in PARAMS to a point."
+  (save-excursion
+    (save-restriction
+      (widen)
+      (goto-char (point-min))
+      (forward-line (gethash "line" params))
+      (forward-char (gethash "character" params))
+      (point))))
+
+;;; TODO: Use the current LSP client name instead of lsp-mode for the type.
+(defun lsp-warn (message &rest args)
+  "Display a warning message made from (`format-message' MESSAGE ARGS...).
+This is equivalent to `display-warning', using `lsp-mode' as the type and
+`:warning' as the level."
+  (display-warning 'lsp-mode (apply #'format-message message args)))
+
+(defvar lsp-message-project-root-warning nil
+  "Output the project root warning as a message and not to the *Warnings* buffer.")
+
+(defun lsp-make-traverser (name)
+  "Return a closure that walks up the current directory until NAME is found.
+NAME can either be a string or a predicate used for `locate-dominating-file'.
+The value returned by the function will be the directory name for NAME.
+
+If no such directory could be found, log a warning and return `default-directory'"
+  (lambda ()
+    (let ((dir (locate-dominating-file "." name)))
+      (if dir
+          (file-truename dir)
+	(if lsp-message-project-root-warning
+	    (message "Couldn't find project root, using the current directory as the root.")
+          (lsp-warn "Couldn't find project root, using the current directory as the root.")
+          default-directory)))))
+
+(defun lsp--get-uri-handler (scheme)
+  "Get uri handler for SCHEME in the current workspace."
+  (when lsp--cur-workspace
+    (gethash scheme (lsp--client-uri-handlers
+                      (lsp--workspace-client lsp--cur-workspace)))))
+
+(defun lsp--uri-to-path (uri)
+  "Convert URI to a file path."
+  (let* ((url (url-generic-parse-url (url-unhex-string uri)))
+         (type (url-type url))
+         (file (url-filename url)))
+    (if (and type (not (string= type "file")))
+      (let ((handler (lsp--get-uri-handler type)))
+        (if handler
+          (funcall handler uri)
+          (error "Unsupported file scheme: %s" uri)))
+      ;; `url-generic-parse-url' is buggy on windows:
+      ;; https://github.com/emacs-lsp/lsp-mode/pull/265
+      (or (and (eq system-type 'windows-nt)
+            (eq (elt file 0) ?\/)
+            (substring file 1))
+        file))))
+
+(define-inline lsp--buffer-uri ()
+  "Return URI of the current buffer."
+  (inline-quote
+    (or lsp-buffer-uri (lsp--path-to-uri buffer-file-name))))
+
+(define-inline lsp--path-to-uri (path)
+  "Convert PATH to a uri."
+  (inline-quote
+    (concat lsp--uri-file-prefix
+      (url-hexify-string (file-truename ,path) url-path-allowed-chars))))
+
+(defun lsp--string-match-any (regex-list str)
+  "Given a list of REGEX-LIST and STR return the first matching regex if any."
+  (find-if (lambda (regex) (string-match regex str)) regex-list))
+
+(defun lsp-create-watch (dir file-regexp-list callback &optional watches root-dir)
+  "Create recursive file notificaton watch in DIR monitoring FILE-REGEXP-LIST.
+CALLBACK is the will be called when there are changes in any of
+the monitored files. WATCHES is a hash table directory->file
+notification handle which contains all of the watches that
+already have been created. "
+  (let ((all-dirs (thread-last
+                    (directory-files-recursively dir ".*" t)
+                    (seq-filter (lambda (f) (file-directory-p f)))
+                    (list* dir)))
+         (watches (or watches (make-hash-table :test 'equal)))
+         (root-dir (or root-dir dir)))
+    (seq-do
+      (lambda (dir-to-watch)
+        (puthash
+          dir-to-watch
+          (file-notify-add-watch
+            dir-to-watch
+            '(change)
+            (lambda (event)
+              (let ((file-name (caddr event))
+                    (event-type (cadr event)))
+                (cond
+                 ((and (file-directory-p file-name)
+                    (equal 'created event-type))
+
+                   (lsp-create-watch file-name file-regexp-list callback watches root-dir)
+
+                   ;; process the files that are already present in
+                   ;; the directory.
+                   (thread-last
+                     (directory-files-recursively file-name ".*" t)
+                     (seq-do (lambda (f)
+                               (when (and (lsp--string-match-any
+                                           file-regexp-list
+                                           (concat "/" (file-relative-name f root-dir)))
+                                       (not (file-directory-p f)))
+                                 (funcall callback (list nil 'created f)))))))
+                 ((and (not (file-directory-p file-name))
+                       (lsp--string-match-any
+                        file-regexp-list
+                        (concat "/" (file-relative-name file-name root-dir))))
+                   (funcall callback event))))))
+          watches))
+      all-dirs)
+    watches))
+
+(defun lsp-kill-watch (watches)
+  "Delete WATCHES."
+  (maphash
+    (lambda (_dir watch)
+      (file-notify-rm-watch watch))
+    watches))
+
+(declare-function lsp--workspace-client "lsp-methods" (cl-x))
+(declare-function lsp--client-uri-handlers "lsp-methods" (cl-x))
+
+(provide 'lsp-common)
+;;; lsp-common.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/lsp-mode-20180827.344/lsp-common.elc b/configs/shared/emacs/.emacs.d/elpa/lsp-mode-20180827.344/lsp-common.elc
new file mode 100644
index 0000000000..fdd6560daa
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/lsp-mode-20180827.344/lsp-common.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/lsp-mode-20180827.344/lsp-flycheck.el b/configs/shared/emacs/.emacs.d/elpa/lsp-mode-20180827.344/lsp-flycheck.el
new file mode 100644
index 0000000000..725098d059
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/lsp-mode-20180827.344/lsp-flycheck.el
@@ -0,0 +1,3 @@
+(user-error "Flycheck support has been moved to package lsp-ui. Please consult https://github.com/emacs-lsp/lsp-ui for documentation on lsp-ui-flycheck.")
+
+(provide 'lsp-flycheck)
diff --git a/configs/shared/emacs/.emacs.d/elpa/lsp-mode-20180827.344/lsp-flycheck.elc b/configs/shared/emacs/.emacs.d/elpa/lsp-mode-20180827.344/lsp-flycheck.elc
new file mode 100644
index 0000000000..cd4bb77793
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/lsp-mode-20180827.344/lsp-flycheck.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/lsp-mode-20180827.344/lsp-imenu.el b/configs/shared/emacs/.emacs.d/elpa/lsp-mode-20180827.344/lsp-imenu.el
new file mode 100644
index 0000000000..1c1869aaef
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/lsp-mode-20180827.344/lsp-imenu.el
@@ -0,0 +1,75 @@
+;; Copyright (C) 2016-2018  Vibhav Pant <vibhavp@gmail.com>  -*- lexical-binding: t -*-
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Imenu integration with lsp-mode.  Enable with:
+;; (require 'lsp-imenu)
+;; (add-hook 'lsp-after-open-hook 'lsp-enable-imenu)
+
+;;; Code:
+
+(require 'imenu)
+(require 'lsp-methods)
+(require 'seq)
+
+(defgroup lsp-imenu nil
+  "Customization group for `lsp-imenu'."
+  :group 'lsp-mode)
+
+(defcustom lsp-imenu-show-container-name t
+  "Display the symbol's container name in an imenu entry."
+  :type 'boolean
+  :group 'lsp-imenu)
+
+(defcustom lsp-imenu-container-name-separator "/"
+  "Separator string to use to separate the container name from the symbol while displaying imenu entries."
+  :type 'string
+  :group 'lsp-imenu)
+
+(define-inline lsp--point-to-marker (p)
+  (inline-quote (save-excursion (goto-char ,p) (point-marker))))
+
+(defun lsp--symbol-to-imenu-elem (sym)
+  (let ((pt (lsp--position-to-point
+             (gethash "start" (gethash "range" (gethash "location" sym)))))
+        (name (gethash "name" sym))
+        (container (gethash "containerName" sym)))
+    (cons (if (and lsp-imenu-show-container-name container)
+              (concat container lsp-imenu-container-name-separator name)
+            name)
+          (if imenu-use-markers (lsp--point-to-marker pt) pt))))
+
+(defun lsp--symbol-filter (sym)
+  (not
+    (lsp--equal-files
+      (lsp--uri-to-path (gethash "uri" (gethash "location" sym)))
+      (buffer-file-name))))
+
+(defun lsp--get-symbol-type (sym)
+  (or (cdr (assoc (gethash "kind" sym) lsp--symbol-kind)) "Other"))
+
+(defun lsp--imenu-create-index ()
+  (let ((symbols (seq-remove #'lsp--symbol-filter (lsp--get-document-symbols))))
+    (mapcar (lambda (nested-alist)
+              (cons (car nested-alist)
+                (mapcar #'lsp--symbol-to-imenu-elem (cdr nested-alist))))
+      (seq-group-by #'lsp--get-symbol-type symbols))))
+
+(defun lsp-enable-imenu ()
+  (setq-local imenu-create-index-function #'lsp--imenu-create-index))
+
+(provide 'lsp-imenu)
+;;; lsp-imenu.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/lsp-mode-20180827.344/lsp-imenu.elc b/configs/shared/emacs/.emacs.d/elpa/lsp-mode-20180827.344/lsp-imenu.elc
new file mode 100644
index 0000000000..8ed3dc976c
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/lsp-mode-20180827.344/lsp-imenu.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/lsp-mode-20180827.344/lsp-io.el b/configs/shared/emacs/.emacs.d/elpa/lsp-mode-20180827.344/lsp-io.el
new file mode 100644
index 0000000000..2204aa4faa
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/lsp-mode-20180827.344/lsp-io.el
@@ -0,0 +1,350 @@
+;; Copyright (C) 2016-2018  Vibhav Pant <vibhavp@gmail.com> -*- lexical-binding: t -*-
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Code:
+
+(require 'json)
+(require 'cl-lib)
+(require 'lsp-common)
+(require 'lsp-notifications)
+(require 'pcase)
+(require 'subr-x)
+
+;; vibhavp: Should we use a lower value (5)?
+(defcustom lsp-response-timeout 10
+  "Number of seconds to wait for a response from the language server before timing out."
+  :type 'number
+  :group 'lsp-mode)
+
+(defun lsp--send-wait (message proc parser)
+  "Send MESSAGE to PROC and wait for output from the process."
+  (when lsp-print-io
+    (let ((inhibit-message t))
+      (message "lsp--stdio-wait: %s" message)))
+  (when (memq (process-status proc) '(stop exit closed failed nil))
+    (error "%s: Cannot communicate with the process (%s)" (process-name proc)
+      (process-status proc)))
+  (process-send-string proc message)
+  (with-local-quit
+    (let* ((send-time (time-to-seconds (current-time)))
+            ;; max time by which we must get a response
+           (expected-time (+ send-time lsp-response-timeout)))
+      (while (lsp--parser-waiting-for-response parser)
+        ;; Wait for expected-time - current-time
+        (accept-process-output proc (- expected-time (time-to-seconds (current-time))))
+        ;; We have timed out when expected-time < (current-time)
+        (when (< expected-time (time-to-seconds (current-time)))
+          (signal 'lsp-timed-out-error nil))))))
+
+(defun lsp--send-no-wait (message proc)
+  "Send MESSAGE to PROC without waiting for further output."
+  (when lsp-print-io
+    (let ((inhibit-message t))
+      (message "lsp--send-no-wait: %s" message)))
+  (when (memq (process-status proc) '(stop exit closed failed nil))
+    (error "%s: Cannot communicate with the process (%s)" (process-name proc)
+           (process-status proc)))
+  (process-send-string proc message))
+
+(cl-defstruct lsp--parser
+  (waiting-for-response nil)
+  (response-result nil)
+  (headers '()) ;; alist of headers
+  (body nil) ;; message body
+  (reading-body nil) ;; If non-nil, reading body
+  (body-length nil) ;; length of current message body
+  (body-received 0) ;; amount of current message body currently stored in 'body'
+  (leftovers nil) ;; Leftover data from previous chunk; to be processed
+
+  (queued-notifications nil) ;; Unused field
+  (queued-requests nil)
+
+  (workspace nil) ;; the workspace
+  )
+
+(define-error 'lsp-parse-error
+  "Error parsing message from language server" 'lsp-error)
+(define-error 'lsp-unknown-message-type
+  "Unknown message type" '(lsp-error lsp-parse-error))
+(define-error 'lsp-unknown-json-rpc-version
+  "Unknown JSON-RPC protocol version" '(lsp-error lsp-parse-error))
+(define-error 'lsp-no-content-length
+  "Content-Length header missing in message" '(lsp-error lsp-parse-error))
+(define-error 'lsp-invalid-header-name
+  "Invalid header name" '(lsp-error lsp-parse-error))
+
+;;  id  method
+;;   x    x     request
+;;   x    .     response
+;;   .    x     notification
+
+(defun lsp--get-message-type (json-data)
+  "Get the message type from JSON-DATA."
+  (when (not (string= (gethash "jsonrpc" json-data "") "2.0"))
+    (signal 'lsp-unknown-json-rpc-version (list (gethash "jsonrpc" json-data))))
+  (if (gethash "id" json-data nil)
+      (if (gethash "error" json-data nil)
+          'response-error
+        (if (gethash "method" json-data nil)
+            'request
+          'response))
+    (if (gethash "method" json-data nil)
+      'notification
+      (signal 'lsp-unknown-message-type (list json-data)))))
+
+(defun lsp--default-message-handler (workspace params)
+  (lsp--window-show-message params workspace))
+
+(defconst lsp--default-notification-handlers
+  #s(hash-table
+     test equal
+     data
+     ("window/showMessage" lsp--default-message-handler
+      "window/logMessage" lsp--default-message-handler
+      "textDocument/publishDiagnostics" (lambda (w p) (lsp--on-diagnostics p w))
+      "textDocument/diagnosticsEnd" ignore
+      "textDocument/diagnosticsBegin" ignore)))
+
+(defun lsp--on-notification (p notification)
+  "Call the appropriate handler for NOTIFICATION."
+  (let* ((params (gethash "params" notification))
+         (client (lsp--workspace-client (lsp--parser-workspace p)))
+         (method (gethash "method" notification))
+         (handler (gethash method
+                           (lsp--client-notification-handlers client)
+                           (gethash method lsp--default-notification-handlers))))
+    (if handler
+        (funcall handler (lsp--parser-workspace p) params)
+      (lsp-warn "Unknown method: %s" method))))
+
+(defun lsp--on-request (p request)
+  "Call the appropriate handler for REQUEST, and send the return value to the server."
+  (let ((params (gethash "params" request))
+         (client (lsp--workspace-client (lsp--parser-workspace p)))
+         (process (lsp--workspace-proc (lsp--parser-workspace p)))
+         (empty-response (lsp--make-response (gethash "id" request) nil nil))
+         handler response)
+    (setq response
+      (pcase (gethash "method" request)
+        ("client/registerCapability"
+          (dolist (reg (gethash "registrations" params))
+            (lsp--server-register-capability reg))
+          empty-response)
+        ("window/showMessageRequest"
+         (let ((choice (lsp--window-show-message-request params)))
+           (lsp--make-response (gethash "id" request)
+                               `(:title ,choice)
+                               nil)))
+        ("client/unregisterCapability"
+          (dolist (unreg (gethash "unregisterations" params))
+            (lsp--server-unregister-capability unreg))
+          empty-response)
+        ("workspace/applyEdit"
+          (lsp--workspace-apply-edit-handler
+            (lsp--parser-workspace p) params)
+          empty-response)
+        (other
+          (setq handler (gethash other (lsp--client-request-handlers client) nil))
+          (if (not handler)
+            (progn
+              (lsp-warn "Unknown request method: %s" other)
+              empty-response)
+            (lsp--make-response (gethash "id" request)
+              (funcall handler (lsp--parser-workspace p) params) nil)))))
+    ;; Send response to the server.
+    (lsp--send-no-wait (lsp--make-message response) process)))
+
+(defconst lsp--errors
+  '((-32700 "Parse Error")
+    (-32600 "Invalid Request")
+    (-32601 "Method not Found")
+    (-32602 "Invalid Parameters")
+    (-32603 "Internal Error")
+    (-32099 "Server Start Error")
+    (-32000 "Server End Error")
+    (-32002 "Server Not Initialized")
+    (-32001 "Unknown Error Code")
+    (-32800 "Request Cancelled"))
+  "alist of error codes to user friendly strings.")
+
+(defconst lsp--silent-errors '(-32800)
+  "Error codes that are okay to not notify the user about")
+
+(defun lsp--error-string (err)
+  "Format ERR as a user friendly string."
+  (let ((code (gethash "code" err))
+        (message (gethash "message" err)))
+    (format "Error from the Language Server: %s (%s)"
+            message
+            (or (car (alist-get code lsp--errors)) "Unknown error"))))
+
+(defun lsp--get-body-length (headers)
+  (let ((content-length (cdr (assoc "Content-Length" headers))))
+    (if content-length
+        (string-to-number content-length)
+
+      ;; This usually means either the server our our parser is
+      ;; screwed up with a previous Content-Length
+      (error "No Content-Length header"))))
+
+(defun lsp--parse-header (s)
+  "Parse string S as a LSP (KEY . VAL) header."
+  (let ((pos (string-match "\:" s))
+        key val)
+    (unless pos
+      (signal 'lsp-invalid-header-name (list s)))
+    (setq key (substring s 0 pos)
+          val (substring s (+ 2 pos)))
+    (when (string-equal key "Content-Length")
+      (cl-assert (cl-loop for c being the elements of val
+                          when (or (> c ?9) (< c ?0)) return nil
+                          finally return t)
+                 nil (format "Invalid Content-Length value: %s" val)))
+    (cons key val)))
+
+(defun lsp--parser-reset (p)
+  (setf
+   (lsp--parser-leftovers p) ""
+   (lsp--parser-body-length p) nil
+   (lsp--parser-body-received p) nil
+   (lsp--parser-headers p) '()
+   (lsp--parser-body p) nil
+   (lsp--parser-reading-body p) nil))
+
+(define-inline lsp--read-json (str)
+  (inline-quote
+    (let* ((json-array-type 'list)
+            (json-object-type 'hash-table)
+            (json-false nil))
+      (json-read-from-string ,str))))
+
+(defun lsp--parser-on-message (p msg)
+  "Called when the parser reads a complete message from the server."
+  (let* ((json-data (lsp--read-json msg))
+          (id (gethash "id" json-data nil))
+          (client (lsp--workspace-client (lsp--parser-workspace p)))
+          callback)
+    (pcase (lsp--get-message-type json-data)
+      ('response
+        (cl-assert id)
+        (setq callback (gethash (if (stringp id)
+                                  (string-to-number id)
+                                  id)
+                         (lsp--client-response-handlers client)
+                         nil))
+        (if callback
+          (progn (funcall callback (gethash "result" json-data nil))
+            (remhash id (lsp--client-response-handlers client)))
+          (setf (lsp--parser-response-result p)
+            (and json-data (gethash "result" json-data nil))
+            (lsp--parser-waiting-for-response p) nil)))
+      ('response-error
+        (let* ((err (gethash "error" json-data nil))
+               (code (gethash "code" err nil)))
+          (when (and json-data
+                     (not (memq code lsp--silent-errors)))
+            (message (lsp--error-string err))))
+        (setf (lsp--parser-response-result p) nil
+          (lsp--parser-waiting-for-response p) nil))
+      ('notification (lsp--on-notification p json-data))
+      ('request      (lsp--on-request p json-data)))))
+
+(defun lsp--parser-read (p output)
+  (cl-assert (lsp--parser-workspace p) nil "Parser workspace cannot be nil.")
+  (let ((messages '())
+        (chunk (concat (lsp--parser-leftovers p) output)))
+    (while (not (string-empty-p chunk))
+      (if (not (lsp--parser-reading-body p))
+          ;; Read headers
+          (let* ((body-sep-pos (string-match-p "\r\n\r\n" chunk)))
+            (if body-sep-pos
+                ;; We've got all the headers, handle them all at once:
+                (let* ((header-raw (substring chunk 0 body-sep-pos))
+                       (content (substring chunk (+ body-sep-pos 4)))
+                       (headers
+                        (mapcar 'lsp--parse-header
+                                (split-string header-raw "\r\n")))
+                       (body-length (lsp--get-body-length headers)))
+                  (setf
+                   (lsp--parser-headers p) headers
+                   (lsp--parser-reading-body p) t
+                   (lsp--parser-body-length p) body-length
+                   (lsp--parser-body-received p) 0
+                   (lsp--parser-body p) (make-string body-length ?\0)
+                   (lsp--parser-leftovers p) nil)
+                  (setq chunk content))
+
+              ;; Haven't found the end of the headers yet. Save everything
+              ;; for when the next chunk arrives and await further input.
+              (setf (lsp--parser-leftovers p) chunk)
+              (setq chunk "")))
+
+        ;; Read body
+        (let* ((total-body-length (lsp--parser-body-length p))
+               (received-body-length (lsp--parser-body-received p))
+               (chunk-length (string-bytes chunk))
+               (left-to-receive (- total-body-length received-body-length))
+               (this-body
+                (substring chunk 0 (min left-to-receive chunk-length)))
+               (leftovers (substring chunk (string-bytes this-body))))
+          (store-substring (lsp--parser-body p) received-body-length this-body)
+          (setf (lsp--parser-body-received p) (+ (lsp--parser-body-received p)
+                                                 (string-bytes this-body)))
+          (when (>= chunk-length left-to-receive)
+            ;; TODO: keep track of the Content-Type header, if
+            ;; present, and use its value instead of just defaulting
+            ;; to utf-8
+            (push (decode-coding-string (lsp--parser-body p) 'utf-8) messages)
+            (lsp--parser-reset p))
+
+          (setq chunk leftovers))))
+    (nreverse messages)))
+
+(defun lsp--json-pretty-print (msg)
+  "Convert json MSG string to pretty printed json string."
+  (let ((json-encoding-pretty-print t))
+    (json-encode (json-read-from-string msg))))
+
+(defun lsp--parser-make-filter (p ignore-regexps)
+  #'(lambda (_proc output)
+      (when (cl-loop for r in ignore-regexps
+                     ;; check if the output is to be ignored or not
+                     ;; TODO: Would this ever result in false positives?
+                     when (string-match r output) return nil
+                     finally return t)
+        (let ((messages
+               (condition-case err
+                   (lsp--parser-read p output)
+                 (error
+                  (progn
+                    (lsp--parser-reset p)
+                    (setf (lsp--parser-response-result p) nil
+                          (lsp--parser-waiting-for-response p) nil)
+                    (error "Error parsing language server output: %s" err))))))
+
+          (dolist (m messages)
+            (when lsp-print-io
+              (let ((inhibit-message t))
+                (message "Output from language server: %s" (lsp--json-pretty-print m))))
+            (lsp--parser-on-message p m))))))
+
+(declare-function lsp--client-notification-handlers "lsp-methods" (client))
+(declare-function lsp--client-request-handlers "lsp-methods" (client))
+(declare-function lsp--workspace-client "lsp-methods" (workspace))
+(declare-function lsp--workspace-apply-edit-handler "lsp-methods" (workspace params))
+(declare-function lsp--window-show-message-request "lsp-notifications" (params))
+
+(provide 'lsp-io)
+;;; lsp-io.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/lsp-mode-20180827.344/lsp-io.elc b/configs/shared/emacs/.emacs.d/elpa/lsp-mode-20180827.344/lsp-io.elc
new file mode 100644
index 0000000000..98db8fe27a
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/lsp-mode-20180827.344/lsp-io.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/lsp-mode-20180827.344/lsp-methods.el b/configs/shared/emacs/.emacs.d/elpa/lsp-mode-20180827.344/lsp-methods.el
new file mode 100644
index 0000000000..4c4dd94429
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/lsp-mode-20180827.344/lsp-methods.el
@@ -0,0 +1,2204 @@
+;; Copyright (C) 2016-2018  Vibhav Pant <vibhavp@gmail.com>  -*- lexical-binding: t -*-
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+(require 'cl-lib)
+(require 'json)
+(require 'xref)
+(require 'subr-x)
+(require 'widget)
+(require 'lsp-io)
+(require 'lsp-common)
+(require 'pcase)
+(require 'inline)
+(require 'em-glob)
+
+(defconst lsp--file-change-type
+  `((created . 1)
+    (changed . 2)
+    (deleted . 3)))
+
+;; A ‘lsp--client’ object describes the client-side behavior of a language
+;; server.  It is used to start individual server processes, each of which is
+;; represented by a ‘lsp--workspace’ object.  Client objects are normally
+;; created using ‘lsp-define-stdio-client’ or ‘lsp-define-tcp-client’.  Each
+;; workspace refers to exactly one client, but there can be multiple workspaces
+;; for a single client.
+(cl-defstruct lsp--client
+  ;; ‘language-id’ is a function that receives a buffer as a single argument
+  ;; and should return the language identifier for that buffer.  See
+  ;; https://microsoft.github.io/language-server-protocol/specification#textdocumentitem
+  ;; for a list of language identifiers.  Also consult the documentation for
+  ;; the language server represented by this client to find out what language
+  ;; identifiers it supports or expects.
+  (language-id nil :read-only t)
+
+  ;; send-async and send-sync are unused field, but haven't been
+  ;; removed so as to avoid breaking byte-compiled clients.
+  ;; FIXME: We shouldn’t need to take binary compatibility into account,
+  ;; especially since the ‘lsp--client’ structure is internal.  These fields
+  ;; should just be removed.
+  (send-sync nil :read-only t)
+  (send-async nil :read-only t)
+
+  ;; FIXME: This field is apparently unused and should be removed.
+  (type nil :read-only t)
+
+  ;; ‘new-connection’ is a function that should start a language server process
+  ;; and return a cons (COMMAND-PROCESS . COMMUNICATION-PROCESS).
+  ;; COMMAND-PROCESS must be a process object representing the server process
+  ;; just started.  COMMUNICATION-PROCESS must be a process (including pipe and
+  ;; network processes) that ‘lsp-mode’ uses to communicate with the language
+  ;; server using the language server protocol.  COMMAND-PROCESS and
+  ;; COMMUNICATION-PROCESS may be the same process; in that case
+  ;; ‘new-connection’ may also return that process as a single
+  ;; object. ‘new-connection’ is called with two arguments, FILTER and
+  ;; SENTINEL.  FILTER should be used as process filter for
+  ;; COMMUNICATION-PROCESS, and SENTINEL should be used as process sentinel for
+  ;; COMMAND-PROCESS.
+  (new-connection nil :read-only t)
+
+  ;; ‘stderr’ is the name of a buffer to write the standard error to.
+  ;; FIXME: ‘stderr’ should be the actual buffer, and it should be a field of
+  ;; the ‘lsp--workspace’.
+  (stderr nil :read-only t)
+
+  ;; ‘get-root’ is a function that should return the workspace root directory
+  ;; for the current buffer.  It may return either a directory name or a
+  ;; directory file name.  The ‘get-root’ function is called without arguments.
+  ;; ‘lsp-mode’ will start one server process per client and root directory.
+  ;; It passes the root directory to the ‘initialize’ method of the language
+  ;; server; see
+  ;; https://microsoft.github.io/language-server-protocol/specification#initialize.
+  ;; Also consult the documentation of your language server for information
+  ;; about what it expects as workspace root.
+  (get-root nil :read-only t)
+
+  ;; ‘ignore-regexps’ is a list of regexps.  When a data packet from the
+  ;; language server matches any of these regexps, it will be ignored.  This is
+  ;; intended for dealing with language servers that output non-protocol data.
+  (ignore-regexps nil :read-only t)
+
+  ;; ‘ignore-messages’ is a list of regexps.  When a message from the language
+  ;; server matches any of these regexps, it will be ignored.  This is useful
+  ;; for filtering out unwanted messages; such as servers that send nonstandard
+  ;; message types, or extraneous log messages.
+  (ignore-messages nil :read-only t)
+
+  ;; ‘notification-handlers’ is a hash table mapping notification method names
+  ;; (strings) to functions handling the respective notifications.  Upon
+  ;; receiving a notification, ‘lsp-mode’ will call the associated handler
+  ;; function passing two arguments, the ‘lsp--workspace’ object and the
+  ;; deserialized notification parameters.
+  (notification-handlers (make-hash-table :test 'equal) :read-only t)
+
+  ;; ‘request-handlers’ is a hash table mapping request method names
+  ;; (strings) to functions handling the respective notifications.  Upon
+  ;; receiving a request, ‘lsp-mode’ will call the associated handler function
+  ;; passing two arguments, the ‘lsp--workspace’ object and the deserialized
+  ;; request parameters.
+  (request-handlers (make-hash-table :test 'equal) :read-only t)
+
+  ;; ‘response-handlers’ is a hash table mapping integral JSON-RPC request
+  ;; identifiers for pending asynchronous requests to functions handling the
+  ;; respective responses.  Upon receiving a response from the language server,
+  ;; ‘lsp-mode’ will call the associated response handler function with a
+  ;; single argument, the deserialized response parameters.
+  (response-handlers (make-hash-table :test 'eql) :read-only t)
+
+  ;; ‘string-renderers’ is an alist mapping MarkedString language identifiers
+  ;; (see
+  ;; https://microsoft.github.io/language-server-protocol/specification#textDocument_hover)
+  ;; to functions that can render the respective languages.  The rendering
+  ;; functions are called with a single argument, the MarkedString value.  They
+  ;; should return a propertized string with the rendered output.
+  (string-renderers '())
+  ;; ‘last-id’ is the last JSON-RPC identifier used.
+  ;; FIXME: ‘last-id’ should be in ‘lsp--workspace’.
+  (last-id 0)
+
+  ;; Function to enable the client for the current buffer, called without
+  ;; arguments.
+  (enable-function nil :read-only t)
+
+  ;; ‘prefix-function’ is called for getting the prefix for completion.
+  ;; The function takes no parameter and returns a cons (start . end) representing
+  ;; the start and end bounds of the prefix. If it's not set, the client uses a
+  ;; default prefix function."
+  (prefix-function nil :read-only t)
+
+  ;; Contains mapping of scheme to the function that is going to be used to load
+  ;; the file.
+  (uri-handlers (make-hash-table :test #'equal) :read-only t)
+  ;; ‘action-handlers’ is a hash table mapping action to a handler function. It
+  ;; can be used in `lsp-execute-code-action' to determine whether the action
+  ;; current client is interested in executing the action instead of sending it
+  ;; to the server.
+  (action-handlers (make-hash-table :test 'equal) :read-only t)
+
+  ;; ‘default-renderer’ is the renderer that is going to be used when there is
+  ;; no concrete "language" specified for the current MarkedString. (see
+  ;; https://microsoft.github.io/language-server-protocol/specification#textDocument_hover)
+  (default-renderer nil))
+
+(cl-defstruct lsp--registered-capability
+  (id "" :type string)
+  (method " " :type string)
+  (options nil))
+
+;; A ‘lsp--workspace’ object represents exactly one language server process.
+(cl-defstruct lsp--workspace
+  ;; ‘parser’ is a ‘lsp--parser’ object used to parse messages for this
+  ;; workspace.  Parsers are not shared between workspaces.
+  (parser nil :read-only t)
+
+  ;; ‘file-versions’ is a hashtable of files "owned" by the workspace.  It maps
+  ;; file names to file versions.  See
+  ;; https://microsoft.github.io/language-server-protocol/specification#versionedtextdocumentidentifier.
+  (file-versions nil :read-only t)
+
+  ;; ‘server-capabilities’ is a hash table of the language server capabilities.
+  ;; It is the hash table representation of a LSP ServerCapabilities structure;
+  ;; cf. https://microsoft.github.io/language-server-protocol/specification#initialize.
+  (server-capabilities nil)
+
+  ;; ‘registered-server-capabilities’ is a list of hash tables that represent
+  ;; dynamically-registered Registration objects.  See
+  ;; https://microsoft.github.io/language-server-protocol/specification#client_registerCapability.
+  (registered-server-capabilities nil)
+
+  ;; ‘root’ is a directory name or a directory file name for the workspace
+  ;; root.  ‘lsp-mode’ passes this directory to the ‘initialize’ method of the
+  ;; language server; see
+  ;; https://microsoft.github.io/language-server-protocol/specification#initialize.
+  (root nil :ready-only t)
+
+  ;; ‘client’ is the ‘lsp--client’ object associated with this workspace.
+  (client nil :read-only t)
+
+  ;; FIXME: ‘change-timer-disabled’ is unused and should be removed.
+  (change-timer-disabled nil)
+
+  ;; ‘proc’ is a process object; it may represent a regular process, a pipe, or
+  ;; a network connection.  ‘lsp-mode’ communicates with ‘proc’ using the
+  ;; language server protocol.  ‘proc’ corresponds to the COMMUNICATION-PROCESS
+  ;; element of the return value of the client’s ‘get-root’ field, which see.
+  (proc nil)
+
+  ;; ‘proc’ is a process object; it must represent a regular process, not a
+  ;; pipe or network process.  It represents the actual server process that
+  ;; corresponds to this workspace.  ‘cmd-proc’ corresponds to the
+  ;; COMMAND-PROCESS element of the return value of the client’s ‘get-root’
+  ;; field, which see.
+  (cmd-proc nil)
+
+  ;; ‘buffers’ is a list of buffers associated with this workspace.
+  (buffers nil)
+
+  ;; ‘highlight-overlays’ is a hash table mapping buffers to a list of overlays
+  ;; used for highlighting the symbol under point.
+  (highlight-overlays (make-hash-table :test 'eq) :read-only t)
+
+  ;; Extra client capabilities provided by third-party packages using
+  ;; `lsp-register-client-capabilities'. It's value is an alist of (PACKAGE-NAME
+  ;; . CAPS), where PACKAGE-NAME is a symbol of the third-party package name,
+  ;; and CAPS is either a plist of the client capabilities, or a function that
+  ;; takes no argument and returns a plist of the client capabilities or nil.")
+  (extra-client-capabilities nil)
+
+  ;; Workspace status
+  (status nil)
+
+  ;; ‘metadata’ is a generic storage for workspace specific data. It is
+  ;; accessed via `lsp-workspace-set-metadata' and `lsp-workspace-set-metadata'
+  (metadata (make-hash-table :test 'equal))
+
+  ;; contains all the file notification watches that have been created for the
+  ;; current workspace in format filePath->file notification handle.
+  (watches (make-hash-table :test 'equal)))
+
+(defvar lsp--workspaces (make-hash-table :test #'equal)
+  "Table of known workspaces, indexed by the project root directory.")
+
+(defvar lsp--ignored-workspace-roots (make-hash-table :test #'equal)
+  "Table of project roots which should not have a workspace,
+indexed by the project root directory.
+
+This is populated when the user declines to open a workspace
+for a file in the workspace.")
+
+(defcustom lsp-render-markdown-markup-content nil
+  "Function to be use for rendering MarkupContent.
+
+It should take two arguments - a string denoting the type of markup content
+and a string containing the text to be rendered.  The returned value should
+be a string that may be fontified/propertized.
+
+When nil, MarkupContent is rendered as plain text."
+  :type 'function
+  :group 'lsp-mode)
+
+(defcustom lsp-before-initialize-hook nil
+  "List of functions to be called before a Language Server has been initialized
+for a new workspace."
+  :type 'hook
+  :group 'lsp-mode)
+
+(defcustom lsp-after-initialize-hook nil
+  "List of functions to be called after a Language Server has been initialized
+for a new workspace."
+  :type 'hook
+  :group 'lsp-mode)
+
+(defcustom lsp-before-open-hook nil
+  "List of functions to be called before a new file with LSP support is opened."
+  :type 'hook
+  :group 'lsp-mode)
+
+(defcustom lsp-after-open-hook nil
+  "List of functions to be called after a new file with LSP support is opened."
+  :type 'hook
+  :group 'lsp-mode)
+
+(defvar lsp--sync-methods
+  '((0 . none)
+    (1 . full)
+    (2 . incremental)))
+(defvar-local lsp--server-sync-method nil
+  "Sync method recommended by the server.")
+
+;;;###autoload
+(defgroup lsp-mode nil
+  "Customization group for ‘lsp-mode’."
+  :group 'tools)
+
+;;;###autoload
+(defgroup lsp-faces nil
+  "Faces for ‘lsp-mode’."
+  :group 'lsp-mode)
+
+;;;###autoload
+(defcustom lsp-document-sync-method nil
+  "How to sync the document with the language server."
+  :type '(choice (const :tag "Documents should not be synced at all." 'none)
+                 (const :tag "Documents are synced by always sending the full content of the document." 'full)
+                 (const :tag "Documents are synced by always sending incremental changes to the document." 'incremental)
+                 (const :tag "Use the method recommended by the language server." nil))
+  :group 'lsp-mode)
+
+;;;###autoload
+(defcustom lsp-project-blacklist nil
+  "A list of project directory regexps for which LSP shouldn't be initialized.
+LSP should be initialized if the given project root matches one pattern in the
+whitelist, or does not match any pattern in the blacklist."
+  :type '(repeat regexp)
+  :group 'lsp-mode)
+
+(defcustom lsp-project-whitelist nil
+  "A list of project directory regexps for which LSP should be initialized."
+  :type '(repeat regexp)
+  :group 'lsp-mode)
+
+;;;###autoload
+(defcustom lsp-enable-eldoc t
+  "Enable `eldoc-mode' integration."
+  :type 'boolean
+  :group 'lsp-mode)
+
+;;;###autoload
+(defcustom lsp-eldoc-render-all t
+  "Define whether all of the returned by document/onHover will be displayed.
+
+If `lsp-markup-display-all' is set to nil `eldoc' will show only
+the symbol information."
+  :type 'boolean
+  :group 'lsp-mode)
+
+;;;###autoload
+(defcustom lsp-highlight-symbol-at-point t
+  "Highlight the symbol under the point."
+  :type 'boolean
+  :group 'lsp-mode)
+
+;;;###autoload
+(defcustom lsp-enable-codeaction t
+  "Enable code action processing."
+  :type 'boolean
+  :group 'lsp-mode)
+
+;;;###autoload
+(defcustom lsp-enable-completion-at-point t
+  "Enable `completion-at-point' integration."
+  :type 'boolean
+  :group 'lsp-mode)
+
+;;;###autoload
+(defcustom lsp-enable-xref t
+  "Enable xref integration."
+  :type 'boolean
+  :group 'lsp-mode)
+
+;;;###autoload
+(defcustom lsp-enable-indentation t
+  "Indent regions using the file formatting functionality provided by the language server."
+  :type 'boolean
+  :group 'lsp-mode)
+
+;;;###autoload
+(defcustom lsp-before-save-edits t
+  "If non-nil, `lsp-mode' will apply edits suggested by the language server
+before saving a document."
+  :type 'boolean
+  :group 'lsp-mode)
+
+;;;###autoload
+(defcustom lsp-hover-text-function 'lsp--text-document-hover-string
+  "The LSP method to use to display text on hover."
+  :type '(choice (function :tag "textDocument/hover"
+                           lsp--text-document-hover-string)
+                 (function :tag "textDocument/signatureHelp"
+                           lsp--text-document-signature-help))
+  :group 'lsp-mode)
+
+;;;###autoload
+(defface lsp-face-highlight-textual
+  '((((background dark))  :background "saddle brown")
+    (((background light)) :background "yellow"))
+  "Face used for textual occurances of symbols."
+  :group 'lsp-faces)
+
+;;;###autoload
+(defface lsp-face-highlight-read
+  '((((background dark))  :background "firebrick")
+    (((background light)) :background "red"))
+  "Face used for highlighting symbols being read."
+  :group 'lsp-faces)
+
+;;;###autoload
+(defface lsp-face-highlight-write
+  '((((background dark))  :background "sea green")
+     (((background light)) :background "green"))
+  "Face used for highlighting symbols being written to."
+  :group 'lsp-faces)
+
+(defun lsp-client-register-uri-handler (client scheme handler)
+  (cl-check-type client lsp--client)
+  (cl-check-type scheme string)
+  (cl-check-type handler function)
+  (puthash scheme handler (lsp--client-uri-handlers client)))
+
+(defun lsp-client-on-notification (client method callback)
+  (cl-check-type client lsp--client)
+  (cl-check-type method string)
+  (cl-check-type callback function)
+  (puthash method callback (lsp--client-notification-handlers client)))
+
+(defun lsp-client-on-request (client method callback)
+  (cl-check-type client lsp--client)
+  (cl-check-type method string)
+  (cl-check-type callback function)
+  (puthash method callback (lsp--client-request-handlers client)))
+
+(defun lsp-client-on-action (client method callback)
+  (cl-check-type client lsp--client)
+  (cl-check-type method string)
+  (cl-check-type callback function)
+  (puthash method callback (lsp--client-action-handlers client)))
+
+(defun lsp-workspace-set-metadata (key value &optional workspace)
+  "Associate KEY with VALUE in the WORKSPACE metadata.
+If WORKSPACE is not provided current workspace will be used."
+  (puthash key value (lsp--workspace-metadata (or workspace lsp--cur-workspace))))
+
+(defun lsp-workspace-get-metadata (key &optional workspace)
+  "Lookup KEY in WORKSPACE metadata.
+If WORKSPACE is not provided current workspace will be used."
+  (gethash key (lsp--workspace-metadata (or workspace lsp--cur-workspace))))
+
+(define-inline lsp--make-request (method &optional params)
+  "Create request body for method METHOD and parameters PARAMS."
+  (inline-quote
+    (plist-put (lsp--make-notification ,method ,params)
+      :id (cl-incf (lsp--client-last-id (lsp--workspace-client lsp--cur-workspace))))))
+
+(defun lsp-make-request (method &optional params)
+  "Create request body for method METHOD and parameters PARAMS."
+  (lsp--make-request method params))
+
+(defun lsp--make-response-error (code message data)
+  (cl-check-type code number)
+  (cl-check-type message string)
+  `(:code ,code :message ,message :data ,data))
+
+(defun lsp--make-response (id result error)
+  (cl-check-type error list)
+  `(:jsonrpc "2.0" :id ,id :result ,result :error ,error))
+
+(define-inline lsp--make-notification (method &optional params)
+  "Create notification body for method METHOD and parameters PARAMS."
+  (inline-quote
+    (progn (cl-check-type ,method string)
+      (list :jsonrpc "2.0" :method ,method :params ,params))))
+
+;; Define non-inline public aliases to avoid breaking binary compatibility.
+(defun lsp-make-notification (method &optional params)
+  "Create notification body for method METHOD and parameters PARAMS."
+  (lsp--make-notification method params))
+
+(define-inline lsp--make-message (params)
+  "Create a LSP message from PARAMS, after encoding it to a JSON string."
+  (inline-quote
+    (let* ((json-encoding-pretty-print lsp-print-io)
+           (json-false :json-false)
+           (body (json-encode ,params)))
+      (format "Content-Length: %d\r\n\r\n%s" (string-bytes body) body))))
+
+(define-inline lsp--send-notification (body)
+  "Send BODY as a notification to the language server."
+  (inline-quote
+    (lsp--send-no-wait
+      (lsp--make-message ,body)
+      (lsp--workspace-proc lsp--cur-workspace))))
+
+(defun lsp-send-notification (body)
+  "Send BODY as a notification to the language server."
+  (lsp--send-notification body))
+
+(define-inline lsp--cur-workspace-check ()
+  (inline-quote
+    (progn
+      (cl-assert lsp--cur-workspace nil
+        "No language server is associated with this buffer.")
+      (cl-assert (lsp--workspace-p lsp--cur-workspace)))))
+
+(define-inline lsp--cur-parser ()
+  (inline-quote (lsp--workspace-parser lsp--cur-workspace)))
+
+(defun lsp--send-request (body &optional no-wait)
+  "Send BODY as a request to the language server, get the response.
+If NO-WAIT is non-nil, don't synchronously wait for a response."
+  (let* ((parser (lsp--cur-parser))
+          (message (lsp--make-message body))
+          (process (lsp--workspace-proc lsp--cur-workspace)))
+    (setf (lsp--parser-waiting-for-response parser) (not no-wait))
+    (if no-wait
+      (lsp--send-no-wait message process)
+      (lsp--send-wait message process parser))
+    (when (not no-wait)
+      (prog1 (lsp--parser-response-result parser)
+        (setf (lsp--parser-response-result parser) nil)))))
+
+(defalias 'lsp-send-request 'lsp--send-request
+  "Send BODY as a request to the language server and return the response synchronously.
+
+\n(fn BODY)")
+
+(defun lsp--send-request-async (body callback)
+  "Send BODY as a request to the language server, and call CALLBACK with
+the response recevied from the server asynchronously."
+  (let ((client (lsp--workspace-client lsp--cur-workspace))
+        (id (plist-get body :id)))
+    (cl-assert id nil "body missing id field")
+    (puthash id callback (lsp--client-response-handlers client))
+    (lsp--send-no-wait (lsp--make-message body)
+      (lsp--workspace-proc lsp--cur-workspace))
+    body))
+
+(defalias 'lsp-send-request-async 'lsp--send-request-async)
+
+(define-inline lsp--inc-cur-file-version ()
+  (inline-quote (cl-incf (gethash (current-buffer)
+                           (lsp--workspace-file-versions lsp--cur-workspace)))))
+
+(define-inline lsp--cur-file-version ()
+  "Return the file version number.  If INC, increment it before."
+  (inline-quote
+    (gethash (current-buffer) (lsp--workspace-file-versions lsp--cur-workspace))))
+
+(define-inline lsp--make-text-document-item ()
+  "Make TextDocumentItem for the currently opened file.
+
+interface TextDocumentItem {
+    uri: string; // The text document's URI
+    languageId: string; // The text document's language identifier.
+    version: number;
+    text: string;
+}"
+  (inline-quote
+    (let ((language-id-fn (lsp--client-language-id (lsp--workspace-client lsp--cur-workspace))))
+      (list :uri (lsp--buffer-uri)
+	      :languageId (funcall language-id-fn (current-buffer))
+	      :version (lsp--cur-file-version)
+	      :text (buffer-substring-no-properties (point-min) (point-max))))))
+
+;; Clean up the entire state of lsp mode when Emacs is killed, to get rid of any
+;; pending language servers.
+(add-hook 'kill-emacs-hook #'lsp--global-teardown)
+
+(defun lsp--global-teardown ()
+  (with-demoted-errors "Error in ‘lsp--global-teardown’: %S"
+    (maphash (lambda (_k value) (lsp--teardown-workspace value)) lsp--workspaces)))
+
+(defun lsp--teardown-workspace (workspace)
+  (setq lsp--cur-workspace workspace)
+  (lsp--shutdown-cur-workspace))
+
+(defun lsp--shutdown-cur-workspace ()
+  "Shut down the language server process for ‘lsp--cur-workspace’."
+  (with-demoted-errors "LSP error: %S"
+    (lsp--send-request (lsp--make-request "shutdown" (make-hash-table)) t)
+    (lsp--send-notification (lsp--make-notification "exit" nil)))
+  (lsp--uninitialize-workspace))
+
+(defun lsp--uninitialize-workspace ()
+  "When a workspace is shut down, by request or from just
+disappearing, unset all the variables related to it."
+  (lsp-kill-watch (lsp--workspace-watches lsp--cur-workspace))
+
+  (let (proc
+        (root (lsp--workspace-root lsp--cur-workspace)))
+    (with-current-buffer (current-buffer)
+      (setq proc (lsp--workspace-proc lsp--cur-workspace))
+      (if (process-live-p proc)
+        (kill-process (lsp--workspace-proc lsp--cur-workspace)))
+      (setq lsp--cur-workspace nil)
+      (lsp--unset-variables)
+      (kill-local-variable 'lsp--cur-workspace))
+    (remhash root lsp--workspaces)))
+
+(defun lsp-restart-workspace ()
+  "Shut down and then restart the current workspace.
+This involves uninitializing each of the buffers associated with
+the workspace, closing the process managing communication with
+the client, and then starting up again."
+  (interactive)
+  (when (and (lsp-mode) (buffer-file-name) lsp--cur-workspace)
+    (let ((old-buffers (lsp--workspace-buffers lsp--cur-workspace))
+           (restart (lsp--client-enable-function (lsp--workspace-client lsp--cur-workspace)))
+           (proc (lsp--workspace-proc lsp--cur-workspace)))
+      (lsp--remove-cur-overlays)
+      ;; Shut down the LSP mode for each buffer in the workspace
+      (dolist (buffer old-buffers)
+        (with-current-buffer buffer
+          (lsp--text-document-did-close)
+          (setq lsp--cur-workspace nil)
+          (lsp-mode -1)))
+
+      ;; Let the process actually shut down
+      (while (process-live-p proc)
+        (accept-process-output proc))
+
+      ;; Re-enable LSP mode for each buffer
+      (dolist (buffer old-buffers)
+        (with-current-buffer buffer
+          (funcall restart))))))
+
+;; NOTE: Possibly make this function subject to a setting, if older LSP servers
+;; are unhappy
+(defun lsp--client-capabilities ()
+  "Return the client capabilites."
+  (apply #'lsp--merge-plists
+    `(:workspace    ,(lsp--client-workspace-capabilities)
+       :textDocument ,(lsp--client-textdocument-capabilities))
+    (seq-map (lambda (extra-capabilities-cons)
+               (let* ((package-name (car extra-capabilities-cons))
+                       (value (cdr extra-capabilities-cons))
+                       (capabilities (if (functionp value) (funcall value)
+                                       value)))
+                 (if (and capabilities (not (listp capabilities)))
+                   (progn
+                     (message "Capabilities provided by %s are not a plist: %s" package-name value)
+                     nil)
+                   capabilities)))
+      (lsp--workspace-extra-client-capabilities lsp--cur-workspace))))
+
+(defun lsp--merge-plists (first &rest rest)
+  "Deeply merge plists.
+
+FIRST is the plist to be merged into. The rest of the arguments
+can be either plists or nil. The non-nil plists in the rest of
+the arguments will be merged into FIRST.
+
+Return the merged plist."
+  (cl-check-type first list)
+  (seq-each
+    (lambda (pl) (setq first (lsp--merge-two-plists first pl)))
+    rest)
+  first)
+
+(defun lsp--merge-two-plists (first second)
+  "Deeply merge two plists.
+
+All values in SECOND are merged into FIRST.  FIRST can be nil or
+a plist.  SECOND must be a plist.
+
+Return the merged plist."
+  (when second
+    (if (not (listp second))
+      (warn "Cannot merge non-list value into a plist. The value is %s" second)
+      (cl-loop for (key second-value) on second
+        collect (progn
+                  (let ((first-value (plist-get first key))
+                         merged-value)
+                    (cond
+                      ((null second-value)) ; do nothing
+                      ((null first-value)
+                        (if (listp second-value)
+                          ;; Deep copy second-value so that the original value won't
+                          ;; be modified.
+                          (setq merged-value
+                            (lsp--merge-two-plists nil second-value)))
+                        (setq merged-value second-value))
+                      ((and (listp first-value) (listp second-value))
+                        (setq merged-value (lsp--merge-two-plists first-value second-value)))
+                      ;; Otherwise, the first value is a leaf entry and should
+                      ;; not be overridden.
+                      )
+                    (when merged-value
+                      (setq first (plist-put first key merged-value))))))))
+  first)
+
+(defun lsp--server-register-capability (reg)
+  (lsp--cur-workspace-check)
+  (let ((method (gethash "method" reg)))
+    (push
+      (make-lsp--registered-capability
+        :id (gethash "id" reg)
+        :method method
+        :options (gethash "registerOptions" reg))
+      (lsp--workspace-registered-server-capabilities lsp--cur-workspace))))
+
+(defun lsp--server-unregister-capability (unreg)
+  (let* ((id (gethash "id" unreg))
+          (fn (lambda (e) (equal (lsp--registered-capability-id e) id))))
+    (setf (lsp--workspace-registered-server-capabilities lsp--cur-workspace)
+      (seq-remove fn
+        (lsp--workspace-registered-server-capabilities lsp--cur-workspace)))))
+
+(defun lsp--client-workspace-capabilities ()
+  "Client Workspace capabilities according to LSP."
+  `(:applyEdit t
+     :executeCommand (:dynamicRegistration t)))
+
+(defun lsp--client-textdocument-capabilities ()
+  "Client Text document capabilities according to LSP."
+  `(:synchronization (:willSave t :didSave t :willSaveWaitUntil t)
+                     :symbol (:symbolKind (:valueSet ,(cl-coerce (cl-loop for kind from 1 to 25 collect kind) 'vector)))
+                     :formatting (:dynamicRegistration t)
+                     :codeAction (:dynamicRegistration t)))
+
+(defun lsp-register-client-capabilities (package-name caps)
+  "Register extra client capabilities for the current workspace.
+
+This function must be called before the initialize request is
+sent.  It's recommended to to call it in the
+`lsp-before-initialize-hook'.
+
+PACKAGE name is the symbol of the name of the package that
+registers the capabilities.  CAPS is either a plist of the
+capabilities, or a function that takes no argument and return a
+plist of the client capabilties or nil.
+
+Registered capabilities are merged into the default capabilities
+before sending to the server via the initialize request.  If two
+packages provide different values for the same leaf capability
+entry, the value is set to the one that registers later.  Default
+leaf capability entries can not be overwritten."
+  (lsp--cur-workspace-check)
+  (cl-check-type package-name symbolp)
+  (cl-check-type caps (or list function))
+  (let ((extra-client-capabilities
+          (lsp--workspace-extra-client-capabilities lsp--cur-workspace)))
+    (if (alist-get package-name extra-client-capabilities)
+        (message "%s has already registered client capabilities" package-name)
+      (push `(,package-name . ,caps)
+        (lsp--workspace-extra-client-capabilities lsp--cur-workspace)))))
+
+(defun lsp-unregister-client-capabilities (package-name)
+  "Unregister extra capabilities provided by PACKAGE-NAME for the current workspace.
+
+PACKAGE-NAME is a symbol of the name of the package that has
+registered client capabilities by calling
+`lsp-register-client-capabilities'."
+  (lsp--cur-workspace-check)
+  (cl-check-type package-name symbol)
+  (let ((extra-client-capabilities
+          (lsp--workspace-extra-client-capabilities lsp--cur-workspace)))
+    (setf (lsp--workspace-extra-client-capabilities lsp--cur-workspace)
+      (assq-delete-all package-name extra-client-capabilities))))
+
+(define-inline lsp--server-capabilities ()
+  "Return the capabilities of the language server associated with the buffer."
+  (inline-quote (lsp--workspace-server-capabilities lsp--cur-workspace)))
+
+(defun lsp--server-has-sync-options-p ()
+  "Return whether the server has a TextDocumentSyncOptions object in
+ServerCapabilities.textDocumentSync."
+  (hash-table-p (gethash "textDocumentSync" (lsp--server-capabilities))))
+
+(defun lsp--send-open-close-p ()
+  "Return whether open and close notifications should be sent to the server."
+  (let ((sync (gethash "textDocumentSync" (lsp--server-capabilities))))
+    (and (hash-table-p sync)
+      (gethash "openClose" sync))))
+
+(defun lsp--send-will-save-p ()
+  "Return whether will save notifications should be sent to the server."
+  (let ((sync (gethash "textDocumentSync" (lsp--server-capabilities))))
+    (and (hash-table-p sync)
+      (gethash "willSave" sync))))
+
+(defun lsp--send-will-save-wait-until-p ()
+  "Return whether will save wait until notifications should be sent to the server."
+  (let ((sync (gethash "textDocumentSync" (lsp--server-capabilities))))
+      (and (hash-table-p sync)
+        (gethash "willSaveWaitUntil" sync))))
+
+(defun lsp--save-include-text-p ()
+  "Return whether save notifications should include the text document's contents."
+  (let ((sync (gethash "textDocumentSync" (lsp--server-capabilities))))
+    (and (hash-table-p sync)
+      (hash-table-p (gethash "save" sync nil))
+      (gethash "includeText" (gethash "save" sync)))))
+
+(defun lsp--set-sync-method ()
+  (let* ((sync (gethash "textDocumentSync" (lsp--server-capabilities)))
+          (kind (if (hash-table-p sync) (gethash "change" sync) sync))
+          (method (alist-get kind lsp--sync-methods)))
+    (setq lsp--server-sync-method (or lsp-document-sync-method
+                                    method))))
+
+(defun lsp--workspace-apply-edit-handler (_workspace params)
+  (lsp--apply-workspace-edit (gethash "edit" params)))
+
+(defun lsp--make-sentinel (workspace)
+  (cl-check-type workspace lsp--workspace)
+  (lambda (process exit-str)
+    (let ((status (process-status process)))
+      (when (memq status '(exit signal))
+        ;; Server has exited.  Uninitialize all buffer-local state for this
+        ;; workspace.
+        (message "%s: %s has exited (%s)"
+                 (lsp--workspace-root workspace)
+                 (process-name (lsp--workspace-proc workspace))
+                 (string-trim-right exit-str))
+        (dolist (buf (lsp--workspace-buffers workspace))
+          (with-current-buffer buf
+            (lsp--uninitialize-workspace)))
+        ;; Kill standard error buffer only if the process exited normally.
+        ;; Leave it intact otherwise for debugging purposes.
+        (when (and (eq status 'exit) (zerop (process-exit-status process)))
+          ;; FIXME: The client structure should store the standard error
+          ;; buffer, not its name.
+          ;; FIXME: Probably the standard error buffer should be per workspace,
+          ;; not per client.
+          (let ((stderr (get-buffer (lsp--client-stderr
+                                     (lsp--workspace-client workspace)))))
+            (when (buffer-live-p stderr)
+              (kill-buffer stderr))))))))
+
+(defun lsp--should-start-p (root)
+  "Consult `lsp-project-blacklist' and `lsp-project-whitelist' to
+determine if a server should be started for the given ROOT
+directory."
+  (or
+    (cl-some (lambda (p) (string-match-p p root))
+      lsp-project-whitelist)
+    (cl-notany (lambda (p) (string-match-p p root))
+      lsp-project-blacklist)))
+
+(defun lsp--start (client &optional extra-init-params)
+  (when lsp--cur-workspace
+    (user-error "LSP mode is already enabled for this buffer"))
+  (cl-assert client)
+  (let* ((root (file-truename (funcall (lsp--client-get-root client))))
+         (workspace (gethash root lsp--workspaces))
+         new-conn response init-params
+         parser proc cmd-proc)
+    (if workspace
+        (progn
+          (setq lsp--cur-workspace workspace)
+          (lsp-mode 1))
+
+      (setf
+       parser (make-lsp--parser)
+       lsp--cur-workspace (make-lsp--workspace
+                           :parser parser
+                           :file-versions (make-hash-table :test 'equal)
+                           :root root
+                           :client client)
+       (lsp--parser-workspace parser) lsp--cur-workspace
+       new-conn (funcall
+                 (lsp--client-new-connection client)
+                 (lsp--parser-make-filter parser (lsp--client-ignore-regexps client))
+                 (lsp--make-sentinel lsp--cur-workspace))
+       ;; the command line process invoked
+       cmd-proc (if (consp new-conn) (car new-conn) new-conn)
+       ;; the process we actually communicate with
+       proc (if (consp new-conn) (cdr new-conn) new-conn)
+
+       (lsp--workspace-proc lsp--cur-workspace) proc
+       (lsp--workspace-cmd-proc lsp--cur-workspace) cmd-proc)
+
+      (puthash root lsp--cur-workspace lsp--workspaces)
+      (lsp-mode 1)
+      (run-hooks 'lsp-before-initialize-hook)
+      (setq init-params
+            `(:processId ,(emacs-pid)
+                         :rootPath ,root
+                         :rootUri ,(lsp--path-to-uri root)
+                         :capabilities ,(lsp--client-capabilities)
+                         :initializationOptions ,(if (functionp extra-init-params)
+                                                     (funcall extra-init-params lsp--cur-workspace)
+                                                   extra-init-params)))
+      (setf response (lsp--send-request
+                      (lsp--make-request "initialize" init-params)))
+      (unless response
+        (signal 'lsp-empty-response-error (list "initialize")))
+      (setf (lsp--workspace-server-capabilities lsp--cur-workspace)
+            (gethash "capabilities" response))
+      ;; Version 3.0 now sends an "initialized" notification to allow registration
+      ;; of server capabilities
+      (lsp--send-notification (lsp--make-notification "initialized" (make-hash-table)))
+      (run-hooks 'lsp-after-initialize-hook))
+    (lsp--text-document-did-open)))
+
+(defun lsp--text-document-did-open ()
+  (run-hooks 'lsp-before-open-hook)
+  (puthash (current-buffer) 0 (lsp--workspace-file-versions lsp--cur-workspace))
+  (push (current-buffer) (lsp--workspace-buffers lsp--cur-workspace))
+  (lsp--send-notification (lsp--make-notification
+                           "textDocument/didOpen"
+                           `(:textDocument ,(lsp--make-text-document-item))))
+
+  (add-hook 'after-save-hook #'lsp-on-save nil t)
+  (add-hook 'kill-buffer-hook #'lsp--text-document-did-close nil t)
+
+  (when lsp-enable-eldoc
+    ;; XXX: The documentation for `eldoc-documentation-function' suggests
+    ;; using `add-function' for modifying its value, use that instead?
+    (setq-local eldoc-documentation-function #'lsp--on-hover)
+    (eldoc-mode 1))
+
+  (when (and lsp-enable-indentation
+             (lsp--capability "documentRangeFormattingProvider"))
+    (setq-local indent-region-function #'lsp-format-region))
+
+  (when (and lsp-enable-xref
+             (lsp--capability "referencesProvider")
+             (lsp--capability "definitionProvider"))
+    (setq-local xref-backend-functions (list #'lsp--xref-backend)))
+
+  (when (and lsp-enable-completion-at-point (lsp--capability "completionProvider"))
+    (setq-local completion-at-point-functions nil)
+    (add-hook 'completion-at-point-functions #'lsp-completion-at-point nil t))
+
+  ;; Make sure the hook is local (last param) otherwise we see all changes for all buffers
+  (add-hook 'before-change-functions #'lsp-before-change nil t)
+  (add-hook 'after-change-functions #'lsp-on-change nil t)
+  (add-hook 'after-revert-hook #'lsp-on-revert nil t)
+  (add-hook 'before-save-hook #'lsp--before-save nil t)
+  (add-hook 'auto-save-hook #'lsp--on-auto-save nil t)
+  (lsp--set-sync-method)
+  (run-hooks 'lsp-after-open-hook))
+
+(define-inline lsp--text-document-identifier ()
+  "Make TextDocumentIdentifier.
+
+interface TextDocumentIdentifier {
+    uri: string;
+}"
+  (inline-quote (list :uri (lsp--buffer-uri))))
+
+(define-inline lsp--versioned-text-document-identifier ()
+  "Make VersionedTextDocumentIdentifier.
+
+interface VersionedTextDocumentIdentifier extends TextDocumentIdentifier {
+    version: number;
+}"
+  (inline-quote (plist-put (lsp--text-document-identifier)
+                  :version (lsp--cur-file-version))))
+
+(define-inline lsp--position (line char)
+  "Make a Position object for the given LINE and CHAR.
+
+interface Position {
+    line: number;
+    character: number;
+}"
+  (inline-quote (list :line ,line :character ,char)))
+
+(define-inline lsp--cur-line ()
+  (inline-quote (1- (line-number-at-pos))))
+
+(define-inline lsp--cur-column ()
+  (inline-quote (- (point) (line-beginning-position))))
+
+(define-inline lsp--cur-position ()
+  "Make a Position object for the current point."
+  (inline-quote
+   (save-restriction
+     (widen)
+     (lsp--position (lsp--cur-line) (lsp--cur-column)))))
+
+(defun lsp--point-to-position (point)
+  "Convert POINT to Position."
+  (save-excursion
+    (goto-char point)
+    (lsp--cur-position)))
+
+(define-inline lsp--position-p (p)
+  (inline-quote
+    (and (numberp (plist-get ,p :line)) (numberp (plist-get ,p :character)))))
+
+(define-inline lsp--range (start end)
+  "Make Range body from START and END.
+
+interface Range {
+     start: Position;
+     end: Position;
+ }"
+  ;; make sure start and end are Position objects
+  (inline-quote
+    (progn
+      (cl-check-type ,start (satisfies lsp--position-p))
+      (cl-check-type ,end (satisfies lsp--position-p))
+      (list :start ,start :end ,end))))
+
+(define-inline lsp--region-to-range (start end)
+  "Make Range object for the current region."
+  (inline-quote (lsp--range (lsp--point-to-position ,start)
+                  (lsp--point-to-position ,end))))
+
+(defun lsp--current-region-or-pos ()
+  "If the region is active return that, else get the point."
+  (if (use-region-p)
+      (lsp--region-to-range (region-beginning) (region-end))
+    (lsp--region-to-range (point) (point))))
+
+(defun lsp--get-start-position ()
+  "Get the start of the region if active, else current point."
+  (let ((pos (if (use-region-p)
+                 (region-beginning)
+               (point))))
+    (lsp-point-to-position pos)))
+
+(defun lsp--get-end-position ()
+  "Get the end of the region if active, else current point."
+  (let ((pos (if (use-region-p)
+                 (region-end)
+               (point))))
+    (lsp-point-to-position pos)))
+
+(define-inline lsp--range-start-line (range)
+  "Return the start line for a given LSP range, in LSP coordinates"
+  (inline-quote (plist-get (plist-get ,range :start) :line)))
+
+(define-inline lsp--range-end-line (range)
+  "Return the end line for a given LSP range, in LSP coordinates"
+  (inline-quote (plist-get (plist-get ,range :end) :line)))
+
+(defun lsp--apply-workspace-edit (edit)
+  "Apply the WorkspaceEdit object EDIT.
+
+interface WorkspaceEdit {
+  changes?: { [uri: string]: TextEdit[]; };
+  documentChanges?: TextDocumentEdit[];
+}"
+  (let ((changes (gethash "changes" edit))
+         (document-changes (gethash "documentChanges" edit)))
+    (if document-changes
+      (mapc #'lsp--apply-text-document-edit document-changes)
+
+      (when (hash-table-p changes)
+        (maphash
+          (lambda (uri text-edits)
+            (let ((filename (lsp--uri-to-path uri)))
+              (with-current-buffer (find-file-noselect filename)
+                (lsp--apply-text-edits text-edits))))
+          changes)))))
+
+(defun lsp--apply-text-document-edit (edit)
+  "Apply the TextDocumentEdit object EDIT.
+If the file is not being visited by any buffer, it is opened with
+`find-file-noselect'.
+Because lsp-mode does not store previous document versions, the edit is only
+applied if the version of the textDocument matches the version of the
+corresponding file.
+
+interface TextDocumentEdit {
+  textDocument: VersionedTextDocumentIdentifier;
+  edits: TextEdit[];
+}"
+  (let* ((ident (gethash "textDocument" edit))
+          (filename (lsp--uri-to-path (gethash "uri" ident)))
+          (version (gethash "version" ident)))
+    (with-current-buffer (find-file-noselect filename)
+      (when (and version (= version (lsp--cur-file-version)))
+        (lsp--apply-text-edits (gethash "edits" edit))))))
+
+(defun lsp--text-edit-sort-predicate (e1 e2)
+  (let ((start1 (lsp--position-to-point (gethash "start" (gethash "range" e1))))
+          (start2 (lsp--position-to-point (gethash "start" (gethash "range" e2)))))
+    (if (= start1 start2)
+      (let ((end1 (lsp--position-to-point (gethash "end" (gethash "range" e1))))
+             (end2 (lsp--position-to-point (gethash "end" (gethash "range" e2)))))
+        (> end1 end2))
+
+      (> start1 start2))))
+
+(define-inline lsp--apply-text-edits (edits)
+  "Apply the edits described in the TextEdit[] object in EDITS."
+  (inline-quote
+    ;; We sort text edits so as to apply edits that modify earlier parts of the
+    ;; document first. Furthermore, because the LSP spec dictates that:
+    ;; "If multiple inserts have the same position, the order in the array
+    ;; defines which edit to apply first."
+    ;; We reverse the initial list to make sure that the order among edits with
+    ;; the same position is preserved.
+
+    (mapc #'lsp--apply-text-edit (sort (nreverse ,edits) #'lsp--text-edit-sort-predicate))))
+
+(defun lsp--apply-text-edit (text-edit)
+  "Apply the edits described in the TextEdit object in TEXT-EDIT."
+  (let* ((range (gethash "range" text-edit))
+         (start-point (lsp--position-to-point (gethash "start" range)))
+         (end-point (lsp--position-to-point (gethash "end" range))))
+    (save-excursion
+      (goto-char start-point)
+      (delete-region start-point end-point)
+      (insert (gethash "newText" text-edit)))))
+
+(define-inline lsp--capability (cap &optional capabilities)
+  "Get the value of capability CAP.  If CAPABILITIES is non-nil, use them instead."
+  (inline-quote (gethash ,cap (or ,capabilities (lsp--server-capabilities) (make-hash-table)))))
+
+(define-inline lsp--registered-capability (method)
+  (inline-quote
+   (seq-find (lambda (reg) (equal (lsp--registered-capability-method reg) ,method))
+             (lsp--workspace-registered-server-capabilities lsp--cur-workspace)
+             nil)))
+
+(define-inline lsp--registered-capability-by-id (id)
+  (inline-quote
+   (seq-find (lambda (reg) (equal (lsp--registered-capability-id reg) ,id))
+             (lsp--workspace-registered-server-capabilities lsp--cur-workspace)
+             nil)))
+
+(defvar-local lsp--before-change-vals nil
+  "Store the positions from the `lsp-before-change' function
+  call, for validation and use in the `lsp-on-change' function.")
+
+(defun lsp--text-document-content-change-event (start end length)
+  "Make a TextDocumentContentChangeEvent body for START to END, of length LENGTH."
+  ;; So (47 54 0) means add    7 chars starting at pos 47
+  ;; must become
+  ;;   {"range":{"start":{"line":5,"character":6}
+  ;;             ,"end" :{"line":5,"character":6}}
+  ;;             ,"rangeLength":0
+  ;;             ,"text":"\nbb = 5"}
+  ;;
+  ;; And (47 47 7) means delete 7 chars starting at pos 47
+  ;; must become
+  ;;   {"range":{"start":{"line":6,"character":0}
+  ;;            ,"end"  :{"line":7,"character":0}}
+  ;;            ,"rangeLength":7
+  ;;            ,"text":""}
+  ;;
+  ;; (208 221 3) means delete 3 chars starting at pos 208, and replace them with
+  ;; 13 chars. So it must become
+  ;;   {"range":{"start":{"line":5,"character":8}
+  ;;             ,"end" :{"line":5,"character":11}}
+  ;;             ,"rangeLength":3
+  ;;             ,"text":"new-chars-xxx"}
+  ;;
+
+  ;; Adding text:
+  ;;   lsp-before-change:(start,end)=(33,33)
+  ;;   lsp-on-change:(start,end,length)=(33,34,0)
+  ;;
+  ;; Changing text:
+  ;;   lsp-before-change:(start,end)=(208,211)
+  ;;   lsp-on-change:(start,end,length)=(208,221,3)
+  ;;
+  ;; Deleting text:
+  ;;   lsp-before-change:(start,end)=(19,27)
+  ;;   lsp-on-change:(start,end,length)=(19,19,8)
+
+  (if (eq length 0)
+    ;; Adding something only, work from start only
+    `(:range ,(lsp--range (lsp--point-to-position start)
+                (lsp--point-to-position start))
+       :rangeLength 0
+       :text ,(buffer-substring-no-properties start end))
+
+    (if (eq start end)
+      ;; Deleting something only
+      (if (lsp--bracketed-change-p start end length)
+        ;; The before-change value is bracketed, use it
+        `(:range ,(lsp--range (lsp--point-to-position start)
+                    (plist-get lsp--before-change-vals :end-pos))
+           :rangeLength ,length
+           :text "")
+        ;; If the change is not bracketed, send a full change event instead.
+        (lsp--full-change-event))
+
+      ;; Deleting some things, adding others
+      (if (lsp--bracketed-change-p start end length)
+        ;; The before-change value is valid, use it
+        `(:range ,(lsp--range (lsp--point-to-position start)
+                    (plist-get lsp--before-change-vals :end-pos))
+           :rangeLength ,length
+           :text ,(buffer-substring-no-properties start end))
+        (lsp--full-change-event)))))
+
+
+;; TODO: Add tests for this function.
+(defun lsp--bracketed-change-p (start _end length)
+  "If the before and after positions are the same, and the length
+is the size of the start range, we are probably good."
+  (and (eq start (plist-get lsp--before-change-vals :start) )
+       (eq length (- (plist-get lsp--before-change-vals :end)
+                     (plist-get lsp--before-change-vals :start)))))
+
+;; Observed from vscode for applying a diff replacing one line with
+;; another. Emacs on-change shows this as a delete followed by an
+;; add.
+
+;; 2017-04-22 17:43:59 [ThreadId 11] DEBUG haskell-lsp - ---> {"jsonrpc":"2.0","method":"textDocument/didChange","params":
+;; {"textDocument":{"uri":"file:///home/alanz/tmp/haskell-hie-test-project/src/Foo.hs","version":2}
+;; ,"contentChanges":[{"range":{"start":{"line":7,"character":0}
+;;                             ,"end":  {"line":7,"character":8}}
+;;                     ,"rangeLength":8
+;;                     ,"text":"baz ="}]}}
+
+
+(defun lsp--full-change-event ()
+  (save-restriction
+    (widen)
+    `(:text ,(buffer-substring-no-properties (point-min) (point-max)))))
+
+(defun lsp-before-change (start end)
+  "Executed before a file is changed.
+Added to `before-change-functions'."
+  ;; Note:
+  ;;
+  ;; This variable holds a list of functions to call when Emacs is about to
+  ;; modify a buffer. Each function gets two arguments, the beginning and end of
+  ;; the region that is about to change, represented as integers. The buffer
+  ;; that is about to change is always the current buffer when the function is
+  ;; called.
+  ;;
+  ;; WARNING:
+  ;;
+  ;; Do not expect the before-change hooks and the after-change hooks be called
+  ;; in balanced pairs around each buffer change. Also don't expect the
+  ;; before-change hooks to be called for every chunk of text Emacs is about to
+  ;; delete. These hooks are provided on the assumption that Lisp programs will
+  ;; use either before- or the after-change hooks, but not both, and the
+  ;; boundaries of the region where the changes happen might include more than
+  ;; just the actual changed text, or even lump together several changes done
+  ;; piecemeal.
+  ;; (message "lsp-before-change:(start,end)=(%s,%s)" start end)
+  (with-demoted-errors "Error in ‘lsp-before-change’: %S"
+    (setq lsp--before-change-vals
+          (list :start start
+                :end end
+                :start-pos (lsp--point-to-position start)
+                :end-pos (lsp--point-to-position end)))))
+
+(defun lsp-on-change (start end length)
+  "Executed when a file is changed.
+Added to `after-change-functions'."
+  ;; Note:
+  ;;
+  ;; Each function receives three arguments: the beginning and end of the region
+  ;; just changed, and the length of the text that existed before the change.
+  ;; All three arguments are integers. The buffer that has been changed is
+  ;; always the current buffer when the function is called.
+  ;;
+  ;; The length of the old text is the difference between the buffer positions
+  ;; before and after that text as it was before the change. As for the
+  ;; changed text, its length is simply the difference between the first two
+  ;; arguments.
+  ;;
+  ;; So (47 54 0) means add    7 chars starting at pos 47
+  ;; So (47 47 7) means delete 7 chars starting at pos 47
+  ;; (message "lsp-on-change:(start,end,length)=(%s,%s,%s)" start end length)
+  ;; (message "lsp-on-change:(lsp--before-change-vals)=%s" lsp--before-change-vals)
+  (with-demoted-errors "Error in ‘lsp-on-change’: %S"
+    (save-match-data
+      ;; A (revert-buffer) call with the 'preserve-modes parameter (eg, as done
+      ;; by auto-revert-mode) will cause this hander to get called with a nil
+      ;; buffer-file-name. We need the buffer-file-name to send notifications;
+      ;; so we skip handling revert-buffer-caused changes and instead handle
+      ;; reverts separately in lsp-on-revert
+      (when (and lsp--cur-workspace (not revert-buffer-in-progress-p))
+        (lsp--inc-cur-file-version)
+        (unless (eq lsp--server-sync-method 'none)
+          (lsp--send-notification
+           (lsp--make-notification
+            "textDocument/didChange"
+            `(:textDocument
+              ,(lsp--versioned-text-document-identifier)
+              :contentChanges
+              ,(pcase lsp--server-sync-method
+                 ('incremental (vector (lsp--text-document-content-change-event
+                                        start end length)))
+                 ('full (vector (lsp--full-change-event))))))))))))
+
+(defun lsp-on-revert ()
+  "Executed when a file is reverted.
+Added to `after-revert-hook'."
+  (let ((n (buffer-size))
+        (revert-buffer-in-progress-p nil))
+    (lsp-on-change 0 n n)))
+
+(defun lsp--text-document-did-close ()
+  "Executed when the file is closed, added to `kill-buffer-hook'."
+  (when lsp--cur-workspace
+    (with-demoted-errors "Error on ‘lsp--text-document-did-close’: %S"
+      (let ((file-versions (lsp--workspace-file-versions lsp--cur-workspace))
+            (old-buffers (lsp--workspace-buffers lsp--cur-workspace)))
+        ;; remove buffer from the current workspace's list of buffers
+        ;; do a sanity check first
+        (when (memq (current-buffer) old-buffers)
+          (setf (lsp--workspace-buffers lsp--cur-workspace)
+                (delq (current-buffer) old-buffers))
+
+          (remhash (current-buffer) file-versions)
+          (with-demoted-errors "Error sending didClose notification in ‘lsp--text-document-did-close’: %S"
+            (lsp--send-notification
+             (lsp--make-notification
+              "textDocument/didClose"
+              `(:textDocument ,(lsp--versioned-text-document-identifier)))))
+          (when (= 0 (hash-table-count file-versions))
+            (lsp--shutdown-cur-workspace)))))))
+
+(define-inline lsp--will-save-text-document-params (reason)
+  (cl-check-type reason number)
+  (inline-quote
+    (list :textDocument (lsp--text-document-identifier)
+      :reason ,reason)))
+
+(defun lsp--before-save ()
+  (when lsp--cur-workspace
+    (with-demoted-errors "Error in ‘lsp--before-save’: %S"
+      (let ((params (lsp--will-save-text-document-params 1)))
+        (when (lsp--send-will-save-p)
+          (lsp--send-notification
+            (lsp--make-notification "textDocument/willSave" params)))
+        (when (and (lsp--send-will-save-wait-until-p) lsp-before-save-edits)
+          (lsp--apply-text-edits
+           (lsp--send-request (lsp--make-request
+                               "textDocument/willSaveWaitUntil" params))))))))
+
+(defun lsp--on-auto-save ()
+  (when (and lsp--cur-workspace
+          (lsp--send-will-save-p))
+    (with-demoted-errors "Error in ‘lsp--on-auto-save’: %S"
+      (lsp--send-notification
+        (lsp--make-notification
+          "textDocument/willSave" (lsp--will-save-text-document-params 2))))))
+
+(defun lsp--text-document-did-save ()
+  "Executed when the file is closed, added to `after-save-hook''."
+  (when lsp--cur-workspace
+    (with-demoted-errors "Error on ‘lsp--text-document-did-save: %S’"
+      (lsp--send-notification
+       (lsp--make-notification
+        "textDocument/didSave"
+         `(:textDocument ,(lsp--versioned-text-document-identifier)
+                         :text ,(if (lsp--save-include-text-p)
+                                    (save-excursion
+                                      (widen)
+                                      (buffer-substring-no-properties (point-min) (point-max)))
+                                  nil)))))))
+
+(define-inline lsp--text-document-position-params (&optional identifier position)
+  "Make TextDocumentPositionParams for the current point in the current document.
+If IDENTIFIER and POSITION are non-nil, they will be used as the document identifier
+and the position respectively."
+  (inline-quote (list :textDocument (or ,identifier (lsp--text-document-identifier))
+                      :position (or ,position (lsp--cur-position)))))
+
+(define-inline lsp--text-document-code-action-params ()
+  "Make CodeActionParams for the current region in the current document."
+  (inline-quote (list :textDocument (lsp--text-document-identifier)
+                  :range (lsp--current-region-or-pos)
+                  :context (list :diagnostics (lsp--cur-line-diagnotics)))))
+
+(defun lsp--cur-line-diagnotics ()
+  "Return any diagnostics that apply to the current line."
+  (let* ((diags (gethash buffer-file-name lsp--diagnostics nil))
+         (range (lsp--current-region-or-pos))
+         (start-line (lsp--range-start-line range))
+         (end-line (lsp--range-end-line range))
+         (diags-in-range (cl-remove-if-not
+                          (lambda (diag)
+                            (let ((line (lsp-diagnostic-line diag)))
+                              (and (>= line start-line) (<= line end-line))))
+                          diags)))
+    (cl-coerce (mapcar #'lsp-diagnostic-original diags-in-range) 'vector)))
+
+(defconst lsp--completion-item-kind
+  `(
+    (1 . "Text")
+    (2 . "Method")
+    (3 . "Function")
+    (4 . "Constructor")
+    (5 . "Field")
+    (6 . "Variable")
+    (7 . "Class")
+    (8 . "Interface")
+    (9 . "Module")
+    (10 . "Property")
+    (11 . "Unit")
+    (12 . "Value")
+    (13 . "Enum")
+    (14 . "Keyword")
+    (15 . "Snippet")
+    (16 . "Color")
+    (17 . "File")
+    (18 . "Reference")))
+
+(defun lsp--gethash (key table &optional dflt)
+  "Look up KEY in TABLE and return its associated value,
+unless KEY not found or its value is falsy, when it returns DFLT.
+DFLT defaults to nil.
+
+Needed for completion request fallback behavior for the fields
+'sortText', 'filterText', and 'insertText' as described here:
+
+https://microsoft.github.io/language-server-protocol/specification#textDocument_completion"
+
+  (let ((result (gethash key table dflt)))
+    (when (member result '(nil "" 0 :json-false))
+      (setq result dflt))
+    result))
+
+(defun lsp--make-completion-item (item)
+  (propertize (lsp--gethash "insertText" item (gethash "label" item ""))
+              'lsp-completion-item
+              item))
+
+(defun lsp--annotate (item)
+  (let* ((table (plist-get (text-properties-at 0 item) 'lsp-completion-item))
+         (detail (gethash "detail" table nil))
+         (kind (alist-get (gethash "kind" table nil) lsp--completion-item-kind)))
+    (concat
+     " "
+     detail
+     (when kind " ")
+     (when kind (format "(%s)" kind)))))
+
+(defun lsp--sort-string (c)
+  (lsp--gethash "sortText" c (gethash "label" c "")))
+
+(defun lsp--sort-completions (completions)
+  (sort completions (lambda (c1 c2)
+                      (string-lessp
+                        (lsp--sort-string c1)
+                        (lsp--sort-string c2)))))
+
+(defun lsp--default-prefix-function ()
+  (bounds-of-thing-at-point 'symbol))
+
+(defun lsp--get-completions ()
+  (with-demoted-errors "Error in ‘lsp--get-completions’: %S"
+    (let* ((prefix-function (or (lsp--client-prefix-function
+                                  (lsp--workspace-client lsp--cur-workspace))
+                             #'lsp--default-prefix-function))
+            (bounds (funcall prefix-function)))
+      (list
+       (if bounds (car bounds) (point))
+       (if bounds (cdr bounds) (point))
+       (completion-table-dynamic
+        #'(lambda (_)
+            ;; *we* don't need to know the string being completed
+            ;; the language server does all the work by itself
+            (let* ((resp (lsp--send-request
+                          (lsp--make-request
+                           "textDocument/completion"
+                           (lsp--text-document-position-params))))
+                   (items (cond
+                           ((null resp) nil)
+                           ((hash-table-p resp) (gethash "items" resp nil))
+                           ((sequencep resp) resp))))
+              (mapcar #'lsp--make-completion-item items))))
+       :annotation-function #'lsp--annotate
+       :display-sort-function #'lsp--sort-completions))))
+
+(defun lsp--resolve-completion (item)
+  (lsp--cur-workspace-check)
+  (cl-assert item nil "Completion item must not be nil")
+  (if (gethash "resolveProvider" (lsp--capability "completionProvider"))
+    (lsp--send-request
+      (lsp--make-request
+        "completionItem/resolve"
+        item))
+    item))
+
+(defun lsp--extract-line-from-buffer (pos)
+  "Return the line pointed to by POS (a Position object) in the current buffer."
+  (let* ((point (lsp--position-to-point pos))
+         (inhibit-field-text-motion t))
+    (save-excursion
+      (goto-char point)
+      (buffer-substring-no-properties (line-beginning-position)
+                                      (line-end-position)))))
+
+(defun lsp--xref-make-item (filename location)
+  "Return a xref-item from a LOCATION in FILENAME."
+  (let* ((range (gethash "range" location))
+         (pos-start (gethash "start" range))
+         (pos-end (gethash "end" range))
+         (line (lsp--extract-line-from-buffer pos-start))
+         (start (gethash "character" pos-start))
+         (end (gethash "character" pos-end))
+         (len (length line)))
+    (add-face-text-property (max (min start len) 0)
+                            (max (min end len) 0)
+                            'highlight t line)
+    ;; LINE is nil when FILENAME is not being current visited by any buffer.
+    (xref-make (or line filename)
+               (xref-make-file-location filename
+                                        (1+ (gethash "line" pos-start))
+                                        (gethash "character" pos-start)))))
+
+(defun lsp--get-xrefs-in-file (file)
+  "Return all references that contain a file.
+FILE is a cons where its car is the filename and the cdr is a list of Locations
+within the file.  We open and/or create the file/buffer only once for all
+references.  The function returns a list of `xref-item'."
+  (let* ((filename (car file))
+         (visiting (find-buffer-visiting filename))
+         (fn (lambda (loc) (lsp--xref-make-item filename loc))))
+    (if visiting
+        (with-current-buffer visiting
+          (mapcar fn (cdr file)))
+      (when (file-readable-p filename)
+        (with-temp-buffer
+          (insert-file-contents-literally filename)
+          (mapcar fn (cdr file)))))))
+
+(defun lsp--locations-to-xref-items (locations)
+  "Return a list of `xref-item' from LOCATIONS.
+LOCATIONS is an array of Location objects:
+
+interface Location {
+  uri: DocumentUri;
+  range: Range;
+}"
+  (when locations
+    (let* ((fn (lambda (loc) (lsp--uri-to-path (gethash "uri" loc))))
+            ;; locations-by-file is an alist of the form
+            ;; ((FILENAME . LOCATIONS)...), where FILENAME is a string of the
+            ;; actual file name, and LOCATIONS is a list of Location objects
+            ;; pointing to Ranges inside that file.
+            (locations-by-file (seq-group-by fn locations))
+            ;; items-by-file is a list of list of xref-item
+            (items-by-file (mapcar #'lsp--get-xrefs-in-file locations-by-file)))
+      ;; flatten the list
+      (apply #'append items-by-file))))
+
+(defun lsp--get-definitions ()
+  "Get definition of the current symbol under point.
+Returns xref-item(s)."
+  (let ((defs (lsp--send-request (lsp--make-request
+                                  "textDocument/definition"
+                                   (lsp--text-document-position-params)))))
+    ;; textDocument/definition returns Location | Location[]
+    (lsp--locations-to-xref-items (if (listp defs) defs (list defs)))))
+
+(defun lsp--make-reference-params (&optional td-position include-declaration)
+  "Make a ReferenceParam object.
+If TD-POSITION is non-nil, use it as TextDocumentPositionParams object instead.
+If INCLUDE-DECLARATION is non-nil, request the server to include declarations."
+  (let ((json-false :json-false))
+    (plist-put (or td-position (lsp--text-document-position-params))
+      :context `(:includeDeclaration ,(or include-declaration json-false)))))
+
+(defun lsp--get-references ()
+  "Get all references for the symbol under point.
+Returns xref-item(s)."
+  (let ((refs  (lsp--send-request (lsp--make-request
+                                   "textDocument/references"
+                                   (lsp--make-reference-params)))))
+    (lsp--locations-to-xref-items refs)))
+
+(defun lsp--cancel-request (id)
+  (lsp--cur-workspace-check)
+  (cl-check-type id (or number string))
+  (let ((response-handlers (lsp--client-response-handlers (lsp--workspace-client
+                                                            lsp--cur-workspace))))
+    (remhash id response-handlers)
+    (lsp--send-notification (lsp--make-notification "$/cancelRequest"
+                              `(:id ,id)))))
+
+(defun lsp--on-hover ()
+  ;; This function is used as ‘eldoc-documentation-function’, so it’s important
+  ;; that it doesn’t fail.
+  (with-demoted-errors "Error in ‘lsp--on-hover’: %S"
+    (when (and (lsp--capability "documentHighlightProvider")
+               lsp-highlight-symbol-at-point)
+      (lsp-symbol-highlight))
+    (when (and (or (lsp--capability "codeActionProvider")
+                   (lsp--registered-capability "textDocument/codeAction"))
+               lsp-enable-codeaction)
+      (lsp--text-document-code-action))
+    (when (and (lsp--capability "hoverProvider") lsp-enable-eldoc)
+      (funcall lsp-hover-text-function))))
+
+(defun lsp-describe-thing-at-point ()
+  "Display the full documentation of the thing at point."
+  (interactive)
+  (lsp--cur-workspace-check)
+  (let* ((client (lsp--workspace-client lsp--cur-workspace))
+         (contents (gethash "contents" (lsp--send-request
+                                        (lsp--make-request "textDocument/hover"
+                                                           (lsp--text-document-position-params))))))
+    (pop-to-buffer
+     (with-current-buffer (get-buffer-create "*lsp-help*")
+       (let ((inhibit-read-only t))
+         (erase-buffer)
+         (insert (lsp--render-on-hover-content contents client t))
+         (goto-char (point-min))
+         (view-mode t)
+         (current-buffer))))))
+
+(defvar-local lsp--cur-hover-request-id nil)
+
+(defun lsp--text-document-hover-string ()
+  "interface Hover {
+    contents: MarkedString | MarkedString[];
+    range?: Range;
+}
+
+type MarkedString = string | { language: string; value: string };"
+  (lsp--cur-workspace-check)
+  (when lsp--cur-hover-request-id
+    (lsp--cancel-request lsp--cur-hover-request-id))
+  (let* ((client (lsp--workspace-client lsp--cur-workspace))
+          bounds body)
+    (when (symbol-at-point)
+      (setq bounds (bounds-of-thing-at-point 'symbol)
+        body (lsp--send-request-async (lsp--make-request "textDocument/hover"
+                                        (lsp--text-document-position-params))
+               (lsp--make-hover-callback client (car bounds) (cdr bounds)
+                 (current-buffer)))
+        lsp--cur-hover-request-id (plist-get body :id))
+      (cl-assert (integerp lsp--cur-hover-request-id)))))
+
+(defun lsp--render-markup-content-1 (kind content)
+  (if (functionp lsp-render-markdown-markup-content)
+    (let ((out (funcall lsp-render-markdown-markup-content kind content)))
+      (cl-assert (stringp out) t
+        "value returned by lsp-render-markdown-markup-content should be a string")
+      out)
+    content))
+
+(defun lsp--render-markup-content (content)
+  "Render MarkupContent object CONTENT.
+
+export interface MarkupContent {
+        kind: MarkupKind;
+        value: string;
+}"
+  (let ((kind (gethash "kind" content))
+        (content (gethash "value" content)))
+    (lsp--render-markup-content-1 kind content)))
+
+(define-inline lsp--point-is-within-bounds-p (start end)
+  "Return whether the current point is within START and END."
+  (inline-quote
+    (let ((p (point)))
+      (and (>= p ,start) (<= p ,end)))))
+
+(define-inline lsp--markup-content-p (obj)
+  (inline-letevals (obj)
+    (inline-quote (and (hash-table-p ,obj)
+                    (gethash "kind" ,obj nil) (gethash "value" ,obj nil)))))
+
+(defun lsp--render-on-hover-content (contents client render-all)
+  "Render the content received from 'document/onHover' request.
+
+CLIENT - client to use.
+CONTENTS  - MarkedString | MarkedString[] | MarkupContent
+RENDER-ALL if set to nil render only the first element from CONTENTS."
+  (let ((renderers (lsp--client-string-renderers client))
+        (default-client-renderer (lsp--client-default-renderer client)))
+    (string-join
+     (mapcar
+      (lambda (e)
+        (let (renderer)
+          (cond
+           ;; hash table, language renderer set
+           ((and (hash-table-p e)
+                 (setq renderer
+                       (if-let (language (gethash "language" e))
+                           (cdr (assoc-string language renderers))
+                         default-client-renderer)))
+            (when (gethash "value" e nil)
+              (funcall renderer (gethash "value" e))))
+
+           ;; hash table - workspace renderer not set
+           ;; trying to render using global renderer
+           ((lsp--markup-content-p e) (lsp--render-markup-content e))
+
+           ;; hash table - anything other has failed
+           ((hash-table-p e) (gethash "value" e nil))
+
+           ;; string, default workspace renderer set
+           (default-client-renderer (funcall default-client-renderer  e))
+
+           ;; no rendering
+           (t e))))
+      (if (listp contents)
+          (if render-all
+              contents
+            (list (car contents)))
+        (list contents)))
+     "\n")))
+
+;; start and end are the bounds of the symbol at point
+(defun lsp--make-hover-callback (client start end buffer)
+  (lambda (hover)
+    (with-current-buffer buffer
+      (setq lsp--cur-hover-request-id nil))
+    (when (and hover
+               (lsp--point-is-within-bounds-p start end)
+               (eq (current-buffer) buffer) (eldoc-display-message-p))
+      (let ((contents (gethash "contents" hover)))
+        (when contents
+          (eldoc-message (lsp--render-on-hover-content contents
+                                                       client
+                                                       lsp-eldoc-render-all)))))))
+
+(defun lsp-provide-marked-string-renderer (client language renderer)
+  (cl-check-type language string)
+  (cl-check-type renderer function)
+  (setf (alist-get language (lsp--client-string-renderers client)) renderer))
+
+(defun lsp-provide-default-marked-string-renderer (client renderer)
+  "Set the RENDERER for CLIENT.
+
+It will be used when no language has been specified in document/onHover result."
+  (cl-check-type renderer function)
+  (setf (lsp--client-default-renderer client) renderer))
+
+(defun lsp-info-under-point ()
+  "Show relevant documentation for the thing under point."
+  (interactive)
+  (lsp--text-document-hover-string))
+
+(defvar-local lsp--current-signature-help-request-id nil)
+
+(defun lsp--text-document-signature-help ()
+  "interface SignatureHelp {
+signatures: SignatureInformation[];
+activeSignature?: number;
+activeParameter?: number;
+};
+
+interface SignatureInformation {
+label: string;
+documentation?: string | MarkupContent;
+parameters?: ParameterInformation[];
+};
+
+interface ParameterInformation {
+label: string;
+documentation?: string | MarkupContent;
+};
+
+interface MarkupContent {
+kind: MarkupKind;
+value: string;
+};
+
+type MarkupKind = 'plaintext' | 'markdown';"
+  (lsp--cur-workspace-check)
+  (when lsp--current-signature-help-request-id
+    (lsp--cancel-request lsp--current-signature-help-request-id))
+  (let (bounds body)
+    (when (symbol-at-point)
+      (setq bounds (bounds-of-thing-at-point 'symbol)
+            body (lsp--send-request-async
+                  (lsp--make-request "textDocument/signatureHelp"
+                                     (lsp--text-document-position-params))
+                  (lsp--make-text-document-signature-help-callback
+                   (car bounds) (cdr bounds) (current-buffer)))
+            lsp--current-signature-help-request-id (plist-get body :id))
+      (cl-assert (integerp lsp--current-signature-help-request-id)))))
+
+(defun lsp--make-text-document-signature-help-callback (start end buffer)
+  (lambda (signature-help)
+    (with-current-buffer buffer
+      (setq lsp--current-signature-help-request-id nil))
+    (when (and signature-help
+               (lsp--point-is-within-bounds-p start end)
+               (eq (current-buffer) buffer) (eldoc-display-message-p))
+      (let* ((active-signature-number
+              (or (gethash "activeSignature" signature-help) 0))
+             (active-signature (nth
+                                active-signature-number
+                                (gethash "signatures" signature-help))))
+        (when active-signature
+          (eldoc-message (gethash "label" active-signature)))))))
+
+;; NOTE: the code actions cannot currently be applied. There is some non-GNU
+;; code to do this in the lsp-haskell module. We still need a GNU version, here.
+;; PRs accepted.
+(defvar-local lsp-code-actions nil
+  "Code actions for the buffer.")
+
+(defvar-local lsp-code-action-params nil
+  "The last code action params.")
+
+(defun lsp--text-document-code-action ()
+  "Request code action to automatically fix issues reported by
+the diagnostics."
+  (lsp--cur-workspace-check)
+  (unless (or (lsp--capability "codeActionProvider")
+              (lsp--registered-capability "textDocument/codeAction"))
+    (signal 'lsp-capability-not-supported (list "codeActionProvider")))
+  (let ((params (lsp--text-document-code-action-params)))
+    (lsp--send-request-async
+     (lsp--make-request "textDocument/codeAction" params)
+     (lambda (actions)
+       (lsp--set-code-action-params (current-buffer) actions params)))))
+
+(defun lsp--command-get-title (cmd)
+  "Given a Command object CMD, get the title.
+If title is nil, return the name for the command handler."
+  (gethash "title" cmd (gethash "command" cmd)))
+
+(defun lsp--set-code-action-params (buf actions params)
+  "Update set `lsp-code-actions' to ACTIONS and `lsp-code-action-params' to PARAMS in BUF."
+  (when (buffer-live-p buf)
+    (with-current-buffer buf
+      (when (equal params (lsp--text-document-code-action-params))
+        (setq lsp-code-actions actions)
+        (setq lsp-code-action-params params)))))
+
+(defun lsp--command-p (cmd)
+  (and (cl-typep cmd 'hash-table)
+    (cl-typep (gethash "title" cmd) 'string)
+    (cl-typep (gethash "command" cmd) 'string)))
+
+(defun lsp--select-action (actions)
+  "Select an action to execute from ACTIONS."
+  (if actions
+      (let ((name->action (mapcar (lambda (a)
+                                    (list (lsp--command-get-title a) a))
+                                  actions)))
+        (cadr (assoc
+               (completing-read "Select code action: " name->action)
+               name->action)))
+    (error "No actions to select from")))
+
+(defun lsp-get-or-calculate-code-actions ()
+  "Get or calculate the current code actions.
+
+The method will either retrieve the current code actions or it will calculate the actual one."
+  (let ((current-code-action-params (lsp--text-document-code-action-params)))
+    (when (not (equal current-code-action-params lsp-code-action-params))
+      (let* ((request-params (lsp--make-request
+                             "textDocument/codeAction"
+                             (lsp--text-document-code-action-params)))
+             (actions (lsp--send-request request-params)))
+        (setq lsp-code-action-params current-code-action-params)
+        (lsp--set-code-action-params (current-buffer)
+                                     actions
+                                     current-code-action-params)))
+    lsp-code-actions))
+
+(defun lsp-execute-code-action (action)
+  "Execute code action ACTION.
+
+If ACTION is not set it will be selected from `lsp-code-actions'."
+  (interactive (list
+                (lsp--select-action (lsp-get-or-calculate-code-actions))))
+  (lsp--cur-workspace-check)
+  (let* ((command (gethash "command" action))
+         (action-handler (gethash command
+                                  (lsp--client-action-handlers
+                                   (lsp--workspace-client lsp--cur-workspace)))))
+    (if action-handler
+        (funcall action-handler action)
+      (lsp--execute-command action))))
+
+(defvar-local lsp-code-lenses nil
+  "A list of code lenses computed for the buffer.")
+
+(defun lsp--update-code-lenses (&optional callback)
+  "Update the list of code lenses for the current buffer.
+Optionally, CALLBACK is a function that accepts a single argument, the code lens object."
+  (lsp--cur-workspace-check)
+  (when callback
+    (cl-check-type callback function))
+  (when (gethash "codeLensProvider" (lsp--server-capabilities))
+    (lsp--send-request-async (lsp--make-request "textDocument/codeLens"
+                               `(:textDocument ,(lsp--text-document-identifier)))
+      (let ((buf (current-buffer)))
+        #'(lambda (lenses)
+            (with-current-buffer buf
+              (setq lsp-code-lenses lenses)
+              (when callback
+                (funcall callback lenses))))))))
+
+(defun lsp--make-document-formatting-options ()
+  (let ((json-false :json-false))
+    `(:tabSize ,tab-width :insertSpaces
+               ,(if indent-tabs-mode json-false t))))
+
+(defun lsp--make-document-formatting-params ()
+  `(:textDocument ,(lsp--text-document-identifier)
+                  :options ,(lsp--make-document-formatting-options)))
+
+(defun lsp-format-buffer ()
+  "Ask the server to format this document."
+  (interactive "*")
+  (unless (or (lsp--capability "documentFormattingProvider")
+              (lsp--registered-capability "textDocument/formatting"))
+    (signal 'lsp-capability-not-supported (list "documentFormattingProvider")))
+  (let ((edits (lsp--send-request (lsp--make-request
+                                   "textDocument/formatting"
+                                   (lsp--make-document-formatting-params)))))
+    (if (fboundp 'replace-buffer-contents)
+        (let ((current-buffer (current-buffer)))
+          (with-temp-buffer
+            (insert-buffer-substring-no-properties current-buffer)
+            (lsp--apply-text-edits edits)
+            (let ((temp-buffer (current-buffer)))
+              (with-current-buffer current-buffer
+                (replace-buffer-contents temp-buffer)))))
+      (let ((point (point))
+            (w-start (window-start)))
+        (lsp--apply-text-edits edits)
+        (goto-char point)
+        (goto-char (line-beginning-position))
+        (set-window-start (selected-window) w-start)))))
+
+(defun lsp--make-document-range-formatting-params (start end)
+  "Make DocumentRangeFormattingParams for selected region.
+interface DocumentRangeFormattingParams {
+    textDocument: TextDocumentIdentifier;
+    range: Range;
+    options: FormattingOptions;
+}"
+  (plist-put (lsp--make-document-formatting-params)
+             :range (lsp--region-to-range start end)))
+
+(defconst lsp--highlight-kind-face
+  '((1 . lsp-face-highlight-textual)
+    (2 . lsp-face-highlight-read)
+    (3 . lsp-face-highlight-write)))
+
+(defun lsp--remove-cur-overlays ()
+  (let ((overlays (lsp--workspace-highlight-overlays lsp--cur-workspace))
+         (buf (current-buffer)))
+    (dolist (overlay (gethash buf overlays))
+      (delete-overlay overlay))
+    (remhash buf overlays)))
+
+(defun lsp-symbol-highlight ()
+  "Highlight all relevant references to the symbol under point."
+  (interactive)
+  (lsp--send-request-async (lsp--make-request "textDocument/documentHighlight"
+                             (lsp--text-document-position-params))
+    (lsp--make-symbol-highlight-callback (current-buffer))))
+
+(defun lsp--make-symbol-highlight-callback (buf)
+  "Create a callback to process the reply of a
+'textDocument/documentHightlight' message for the buffer BUF.
+A reference is highlighted only if it is visible in a window."
+  (cl-check-type buf buffer)
+  (lambda (highlights)
+    (with-current-buffer buf
+      (lsp--remove-cur-overlays)
+      (when (and highlights (/= (length highlights) 0))
+        (let* ((windows-on-buffer (get-buffer-window-list nil nil 'visible))
+               (overlays (lsp--workspace-highlight-overlays lsp--cur-workspace))
+               (buf-overlays (gethash (current-buffer) overlays))
+               wins-visible-pos)
+          (save-restriction
+            (widen)
+            ;; Save visible portions of the buffer
+            (dolist (win windows-on-buffer)
+              (let* ((win-start (window-start win))
+                     (win-end (window-end win)))
+                (push (cons (1- (line-number-at-pos win-start))
+                            (1+ (line-number-at-pos win-end)))
+                      wins-visible-pos)))
+            (dolist (highlight highlights)
+              (let* ((range (gethash "range" highlight nil))
+                     (kind (gethash "kind" highlight 1))
+                     (start (gethash "start" range))
+                     (end (gethash "end" range))
+                     overlay)
+                (dolist (win wins-visible-pos)
+                  (let* ((start-window (car win))
+                         (end-window (cdr win)))
+                    ;; Make the overlay only if the reference is visible
+                    (when (and (> (1+ (gethash "line" start)) start-window)
+                               (< (1+ (gethash "line" end)) end-window))
+                      (setq overlay (make-overlay (lsp--position-to-point start)
+                                                  (lsp--position-to-point end)))
+                      (overlay-put overlay 'face
+                                   (cdr (assq kind lsp--highlight-kind-face)))
+                      (push overlay buf-overlays)
+                      (puthash (current-buffer) buf-overlays overlays))))))))))))
+
+(defconst lsp--symbol-kind
+  '((1 . "File")
+     (2 . "Module")
+     (3 . "Namespace")
+     (4 . "Package")
+     (5 . "Class")
+     (6 . "Method")
+     (7 . "Property")
+     (8 . "Field")
+     (9 . "Constructor"),
+     (10 . "Enum")
+     (11 . "Interface")
+     (12 . "Function")
+     (13 . "Variable")
+     (14 . "Constant")
+     (15 . "String")
+     (16 . "Number")
+     (17 . "Boolean")
+     (18 . "Array")
+     (19 . "Object")
+     (20 . "Key")
+     (21 . "Null")
+     (22 . "Enum Member")
+     (23 . "Struct")
+     (24 . "Event")
+     (25 . "Operator")
+     (26 . "Type Parameter")))
+
+(defun lsp--symbol-information-to-xref (symbol)
+  "Return a `xref-item' from SYMBOL information."
+  (let* ((location (gethash "location" symbol))
+         (uri (gethash "uri" location))
+         (range (gethash "range" location))
+         (start (gethash "start" range)))
+    (xref-make (format "[%s] %s"
+                       (alist-get (gethash "kind" symbol) lsp--symbol-kind)
+                       (gethash "name" symbol))
+               (xref-make-file-location (lsp--uri-to-path uri)
+                                        (1+ (gethash "line" start))
+                                        (gethash "character" start)))))
+
+(defun lsp-format-region (s e)
+  (let ((edits (lsp--send-request (lsp--make-request
+                                   "textDocument/rangeFormatting"
+                                   (lsp--make-document-range-formatting-params s e)))))
+    (lsp--apply-text-edits edits)))
+
+(defun lsp--location-to-td-position (location)
+  "Convert LOCATION to a TextDocumentPositionParams object."
+  `(:textDocument (:uri ,(gethash "uri" location))
+                  :position ,(gethash "start" (gethash "range" location))))
+
+(defun lsp--symbol-info-to-identifier (symbol)
+  (let ((td-params (lsp--location-to-td-position (gethash "location" symbol))))
+    (propertize (gethash "name" symbol)
+      'ref-params (lsp--make-reference-params td-params)
+      'def-params td-params)))
+
+(defun lsp--get-document-symbols ()
+  (lsp--cur-workspace-check)
+  (lsp--send-request (lsp--make-request
+                       "textDocument/documentSymbol"
+                       `(:textDocument ,(lsp--text-document-identifier)))))
+
+(defun lsp--xref-backend () 'xref-lsp)
+
+(cl-defmethod xref-backend-identifier-at-point ((_backend (eql xref-lsp)))
+  (propertize (symbol-name (symbol-at-point))
+              'def-params (lsp--text-document-position-params)
+              'ref-params (lsp--make-reference-params)))
+
+(cl-defmethod xref-backend-identifier-completion-table ((_backend (eql xref-lsp)))
+  (let ((json-false :json-false)
+        (symbols (lsp--get-document-symbols)))
+    (mapcar #'lsp--symbol-info-to-identifier symbols)))
+
+;; (cl-defmethod xref-backend-identifier-completion-table ((_backend (eql xref-lsp)))
+;;   nil)
+
+(cl-defmethod xref-backend-definitions ((_backend (eql xref-lsp)) identifier)
+  (let* ((maybeparams (get-text-property 0 'def-params identifier))
+         ;; In some modes (such as haskell-mode), xref-find-definitions gets
+         ;; called directly without applying the properties expected here. So we
+         ;; must test if the properties are present, and if not use the current
+         ;; point location.
+         (params (if (null maybeparams)
+                     (lsp--text-document-position-params)
+                   maybeparams))
+         (defs (lsp--send-request (lsp--make-request
+                                   "textDocument/definition"
+                                   params))))
+    (lsp--locations-to-xref-items (if (listp defs) defs (list defs)))))
+
+(cl-defmethod xref-backend-references ((_backend (eql xref-lsp)) identifier)
+  (let* ((properties (text-properties-at 0 identifier))
+         (params (plist-get properties 'ref-params))
+         (refs (lsp--send-request (lsp--make-request
+                                   "textDocument/references"
+                                   (or params (lsp--make-reference-params))))))
+    (lsp--locations-to-xref-items refs)))
+
+(cl-defmethod xref-backend-apropos ((_backend (eql xref-lsp)) pattern)
+  (let ((symbols (lsp--send-request (lsp--make-request
+                                     "workspace/symbol"
+                                     `(:query ,pattern)))))
+    (mapcar 'lsp--symbol-information-to-xref symbols)))
+
+(defun lsp--make-document-rename-params (newname)
+  "Make DocumentRangeFormattingParams for selected region.
+interface RenameParams {
+    textDocument: TextDocumentIdentifier;
+    position: Position;
+    newName: string;
+}"
+  `(:position ,(lsp--cur-position)
+              :textDocument ,(lsp--text-document-identifier)
+              :newName ,newname))
+
+(defun lsp-rename (newname)
+  "Rename the symbol (and all references to it) under point to NEWNAME."
+  (interactive (list (read-string "Rename to: " (thing-at-point 'symbol))))
+  (lsp--cur-workspace-check)
+  (unless (lsp--capability "renameProvider")
+    (signal 'lsp-capability-not-supported (list "renameProvider")))
+  (let ((edits (lsp--send-request (lsp--make-request
+                                   "textDocument/rename"
+                                   (lsp--make-document-rename-params newname)))))
+    (when edits
+      (lsp--apply-workspace-edit edits))))
+
+(defun lsp-find-custom (method &optional extra)
+  "Send request named METHOD and get cross references of the symbol under point.
+EXTRA is a plist of extra parameters."
+  (let ((loc (lsp--send-request
+              (lsp--make-request method
+                                 (append (lsp--text-document-position-params) extra)))))
+    (if loc
+        (xref--show-xrefs
+         (lsp--locations-to-xref-items (if (listp loc) loc (list loc))) nil)
+      (message "Not found for: %s" (thing-at-point 'symbol t)))))
+
+(defun lsp-goto-implementation ()
+  "Resolve, and go to the implementation(s) of the symbol under point."
+  (interactive)
+  (lsp--cur-workspace-check)
+  (unless (lsp--capability "implementationProvider")
+    (signal 'lsp-capability-not-supported (list "implementationProvider")))
+  (lsp-find-custom "textDocument/implementation"))
+
+(defun lsp-goto-type-definition ()
+  "Resolve, and go to the type definition(s) of the symbol under point."
+  (interactive)
+  (lsp--cur-workspace-check)
+  (unless (lsp--capability "typeDefinitionProvider")
+    (signal 'lsp-capability-not-supported (list "typeDefinitionProvider")))
+  (lsp-find-custom "textDocument/typeDefinition"))
+
+(define-inline lsp--execute-command (command)
+  "Given a COMMAND returned from the server, create and send a
+'workspace/executeCommand' message."
+  (inline-letevals (command)
+    (inline-quote
+      (progn
+        (cl-check-type ,command (satisfies lsp--command-p))
+        (lsp--send-execute-command
+          (gethash "command" ,command)
+          (gethash "arguments" ,command nil))))))
+
+(defun lsp--send-execute-command (command &optional args)
+  "Create and send a 'workspace/executeCommand' message having
+command COMMAND and optionsl ARGS"
+  (lsp--cur-workspace-check)
+  (unless (lsp--capability "executeCommandProvider")
+    (signal 'lsp-capability-not-supported (list "executeCommandProvider")))
+  (lsp--send-request
+   (lsp--make-request
+    "workspace/executeCommand"
+    (lsp--make-execute-command-params command args))))
+
+(defun lsp--make-execute-command-params (cmd &optional args)
+  (if args
+      (list :command cmd :arguments args)
+    (list :command cmd)))
+
+(defalias 'lsp-point-to-position #'lsp--point-to-position)
+(defalias 'lsp-get-start-position #'lsp--get-start-position)
+(defalias 'lsp-get-end-position #'lsp--get-end-position)
+(defalias 'lsp-text-document-identifier #'lsp--text-document-identifier)
+(defalias 'lsp-send-execute-command #'lsp--send-execute-command)
+(defalias 'lsp-on-open #'lsp--text-document-did-open)
+(defalias 'lsp-on-save #'lsp--text-document-did-save)
+;; (defalias 'lsp-on-change #'lsp--text-document-did-change)
+(defalias 'lsp-completion-at-point #'lsp--get-completions)
+
+(defun lsp--unset-variables ()
+  (when lsp-enable-eldoc
+    (setq-local eldoc-documentation-function 'ignore))
+  (when lsp-enable-xref
+    (setq-local xref-backend-functions nil))
+  (when lsp-enable-completion-at-point
+    (remove-hook 'completion-at-point-functions #'lsp-completion-at-point t))
+  (remove-hook 'after-change-functions #'lsp-on-change t)
+  (remove-hook 'after-revert-hook #'lsp-on-revert t)
+  (remove-hook 'before-change-functions #'lsp-before-change t))
+
+(defun lsp--set-configuration (settings)
+  "Set the configuration for the lsp server."
+  (lsp--send-notification (lsp--make-notification
+                           "workspace/didChangeConfiguration"
+                           `(:settings , settings))))
+
+(defun lsp-workspace-register-watch (to-watch &optional workspace)
+  "Monitor for file change and trigger workspace/didChangeConfiguration.
+
+TO-WATCH is a list of the directories and regexp in the following format:
+'((root-dir1 (glob-pattern1 glob-pattern2))
+  (root-dir2 (glob-pattern3 glob-pattern4)))
+
+If WORKSPACE is not specified the `lsp--cur-workspace' will be used."
+  (setq workspace (or workspace lsp--cur-workspace))
+  (let ((watches (lsp--workspace-watches workspace)))
+    (cl-loop for (dir glob-patterns) in to-watch do
+      (lsp-create-watch
+        dir
+        (mapcar 'eshell-glob-regexp glob-patterns)
+        (lambda (event)
+          (let ((lsp--cur-workspace workspace))
+            (lsp-send-notification
+              (lsp-make-notification
+                "workspace/didChangeWatchedFiles"
+                (list :changes
+                  (list
+                    :type (alist-get (cadr event) lsp--file-change-type)
+                    :uri (lsp--path-to-uri (caddr event))))))))
+        watches))))
+
+(declare-function lsp-mode "lsp-mode" (&optional arg))
+
+(provide 'lsp-methods)
+;;; lsp-methods.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/lsp-mode-20180827.344/lsp-methods.elc b/configs/shared/emacs/.emacs.d/elpa/lsp-mode-20180827.344/lsp-methods.elc
new file mode 100644
index 0000000000..b77ff833a5
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/lsp-mode-20180827.344/lsp-methods.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/lsp-mode-20180827.344/lsp-mode-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/lsp-mode-20180827.344/lsp-mode-autoloads.el
new file mode 100644
index 0000000000..896390530b
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/lsp-mode-20180827.344/lsp-mode-autoloads.el
@@ -0,0 +1,108 @@
+;;; lsp-mode-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "lsp-methods" "lsp-methods.el" (23428 20482
+;;;;;;  431812 870000))
+;;; Generated autoloads from lsp-methods.el
+
+(let ((loads (get 'lsp-mode 'custom-loads))) (if (member '"lsp-methods" loads) nil (put 'lsp-mode 'custom-loads (cons '"lsp-methods" loads))))
+
+(let ((loads (get 'lsp-faces 'custom-loads))) (if (member '"lsp-methods" loads) nil (put 'lsp-faces 'custom-loads (cons '"lsp-methods" loads))))
+
+(defvar lsp-document-sync-method nil "\
+How to sync the document with the language server.")
+
+(custom-autoload 'lsp-document-sync-method "lsp-methods" t)
+
+(defvar lsp-project-blacklist nil "\
+A list of project directory regexps for which LSP shouldn't be initialized.
+LSP should be initialized if the given project root matches one pattern in the
+whitelist, or does not match any pattern in the blacklist.")
+
+(custom-autoload 'lsp-project-blacklist "lsp-methods" t)
+
+(defvar lsp-enable-eldoc t "\
+Enable `eldoc-mode' integration.")
+
+(custom-autoload 'lsp-enable-eldoc "lsp-methods" t)
+
+(defvar lsp-eldoc-render-all t "\
+Define whether all of the returned by document/onHover will be displayed.
+
+If `lsp-markup-display-all' is set to nil `eldoc' will show only
+the symbol information.")
+
+(custom-autoload 'lsp-eldoc-render-all "lsp-methods" t)
+
+(defvar lsp-highlight-symbol-at-point t "\
+Highlight the symbol under the point.")
+
+(custom-autoload 'lsp-highlight-symbol-at-point "lsp-methods" t)
+
+(defvar lsp-enable-codeaction t "\
+Enable code action processing.")
+
+(custom-autoload 'lsp-enable-codeaction "lsp-methods" t)
+
+(defvar lsp-enable-completion-at-point t "\
+Enable `completion-at-point' integration.")
+
+(custom-autoload 'lsp-enable-completion-at-point "lsp-methods" t)
+
+(defvar lsp-enable-xref t "\
+Enable xref integration.")
+
+(custom-autoload 'lsp-enable-xref "lsp-methods" t)
+
+(defvar lsp-enable-indentation t "\
+Indent regions using the file formatting functionality provided by the language server.")
+
+(custom-autoload 'lsp-enable-indentation "lsp-methods" t)
+
+(defvar lsp-before-save-edits t "\
+If non-nil, `lsp-mode' will apply edits suggested by the language server
+before saving a document.")
+
+(custom-autoload 'lsp-before-save-edits "lsp-methods" t)
+
+(defvar lsp-hover-text-function 'lsp--text-document-hover-string "\
+The LSP method to use to display text on hover.")
+
+(custom-autoload 'lsp-hover-text-function "lsp-methods" t)
+
+(defface lsp-face-highlight-textual '((((background dark)) :background "saddle brown") (((background light)) :background "yellow")) "\
+Face used for textual occurances of symbols." :group (quote lsp-faces))
+
+(defface lsp-face-highlight-read '((((background dark)) :background "firebrick") (((background light)) :background "red")) "\
+Face used for highlighting symbols being read." :group (quote lsp-faces))
+
+(defface lsp-face-highlight-write '((((background dark)) :background "sea green") (((background light)) :background "green")) "\
+Face used for highlighting symbols being written to." :group (quote lsp-faces))
+
+;;;***
+
+;;;### (autoloads nil "lsp-mode" "lsp-mode.el" (23428 20482 436449
+;;;;;;  152000))
+;;; Generated autoloads from lsp-mode.el
+
+(autoload 'lsp-mode "lsp-mode" "\
+
+
+\(fn &optional ARG)" t nil)
+
+;;;***
+
+;;;### (autoloads nil nil ("lsp-common.el" "lsp-flycheck.el" "lsp-imenu.el"
+;;;;;;  "lsp-io.el" "lsp-mode-pkg.el" "lsp-notifications.el") (23428
+;;;;;;  20482 439731 790000))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; lsp-mode-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/lsp-mode-20180827.344/lsp-mode-pkg.el b/configs/shared/emacs/.emacs.d/elpa/lsp-mode-20180827.344/lsp-mode-pkg.el
new file mode 100644
index 0000000000..232852a8c8
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/lsp-mode-20180827.344/lsp-mode-pkg.el
@@ -0,0 +1,10 @@
+(define-package "lsp-mode" "20180827.344" "Minor mode for interacting with Language Servers"
+  '((emacs "25.1"))
+  :authors
+  '(("Vibhav Pant" . "vibhavp@gmail.com"))
+  :maintainer
+  '("Vibhav Pant" . "vibhavp@gmail.com")
+  :url "https://github.com/emacs-lsp/lsp-mode")
+;; Local Variables:
+;; no-byte-compile: t
+;; End:
diff --git a/configs/shared/emacs/.emacs.d/elpa/lsp-mode-20180827.344/lsp-mode.el b/configs/shared/emacs/.emacs.d/elpa/lsp-mode-20180827.344/lsp-mode.el
new file mode 100644
index 0000000000..2a7e4b25b5
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/lsp-mode-20180827.344/lsp-mode.el
@@ -0,0 +1,401 @@
+;;; lsp-mode.el --- Minor mode for interacting with Language Servers -*- lexical-binding: t -*-
+
+;; Copyright (C) 2016-2018  Vibhav Pant <vibhavp@gmail.com>
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;; Author: Vibhav Pant <vibhavp@gmail.com>
+;; URL: https://github.com/emacs-lsp/lsp-mode
+;; Package-Requires: ((emacs "25.1"))
+;; Version: 4.2
+
+;;; Commentary:
+
+;;; Code:
+
+(require 'lsp-methods)
+(require 'lsp-io)
+(require 'cl-lib)
+(require 'network-stream)
+
+(defvar lsp-version-support "3.0"
+  "This is the version of the Language Server Protocol currently supported by ‘lsp-mode’.")
+
+;;;###autoload
+(define-minor-mode lsp-mode ""
+  nil nil nil
+  :lighter (:eval (lsp-mode-line))
+  :group 'lsp-mode)
+
+(defun lsp--make-stdio-connection (name command command-fn stderr)
+  (lambda (filter sentinel)
+    (let* ((command (if command-fn (funcall command-fn) command))
+           (final-command (if (consp command) command (list command))))
+      (unless (executable-find (nth 0 final-command))
+        (error (format "Couldn't find executable %s" (nth 0 final-command))))
+      (let ((proc (make-process
+                    :name name
+                    :connection-type 'pipe
+                    :coding 'no-conversion
+                    :command final-command
+                    :filter filter
+                    :sentinel sentinel
+                    :stderr stderr
+                    :noquery t)))
+        ;; TODO: This is redundant with :noquery above, but due to a
+        ;; bug pre-Emacs 26 it is still needed
+        ;; https://debbugs.gnu.org/cgi/bugreport.cgi?bug=30031
+        (set-process-query-on-exit-flag (get-buffer-process (get-buffer stderr)) nil)
+        proc))))
+
+(defun lsp--make-tcp-connection (name command command-fn host port stderr)
+  (lambda (filter sentinel)
+    (let* ((command (if command-fn (funcall command-fn) command))
+            (final-command (if (consp command) command (list command)))
+            proc tcp-proc)
+      (unless (executable-find (nth 0 final-command))
+        (error (format "Couldn't find executable %s" (nth 0 final-command))))
+      (setq proc (make-process
+                   :name name
+                   :connection-type 'pipe
+                   :coding 'no-conversion
+                   :command final-command
+                   :sentinel sentinel
+                   :stderr stderr
+                   :noquery t)
+        tcp-proc (open-network-stream (concat name " TCP connection")
+                   nil host port
+                   :type 'plain))
+      ;; TODO: Same :noquery issue (see above)
+      (set-process-query-on-exit-flag (get-buffer-process (get-buffer stderr)) nil)
+      (set-process-query-on-exit-flag tcp-proc nil)
+      (set-process-filter tcp-proc filter)
+      (cons proc tcp-proc))))
+
+(cl-defmacro lsp-define-whitelist-add (name get-root
+                                               &key docstring)
+  "Define a function to add the project root for the current buffer to the whitleist.
+NAME is the base name for the command.
+GET-ROOT is the language-specific function to determine the project root for the current buffer."
+  (let ((whitelist-add      (intern (format "%s-whitelist-add" name)))
+        (enable-interactive (intern (format "%s-enable" name))))
+    `(defun ,whitelist-add ()
+       ,docstring
+       (interactive)
+       (let ((root (funcall ,get-root)))
+         (customize-save-variable 'lsp-project-whitelist
+           (add-to-list 'lsp-project-whitelist (lsp--as-regex root)))
+         (,enable-interactive)))))
+
+(cl-defmacro lsp-define-whitelist-remove (name get-root
+                                            &key docstring)
+  "Define a function to remove the project root for the current buffer from the whitleist.
+NAME is the base name for the command.
+GET-ROOT is the language-specific function to determine the project root for the current buffer."
+  (let ((whitelist-remove (intern (format "%s-whitelist-remove" name))))
+    `(defun ,whitelist-remove ()
+       ,docstring
+       (interactive)
+       (let ((root (funcall ,get-root)))
+         (customize-save-variable 'lsp-project-whitelist
+           (remove (lsp--as-regex root) lsp-project-whitelist))))))
+
+(defun lsp--as-regex (root)
+  "Convert the directory path in ROOT to an equivalent regex."
+  (concat "^" (regexp-quote root) "$"))
+
+(cl-defmacro lsp-define-stdio-client (name language-id get-root command
+                                       &key docstring
+                                       language-id-fn
+                                       command-fn
+                                       ignore-regexps
+                                       ignore-messages
+                                       extra-init-params
+                                       initialize
+                                       prefix-function)
+  "Define a LSP client using stdio.
+NAME is the symbol to use for the name of the client.
+LANGUAGE-ID is the language id to be used when communication with
+the Language Server.  COMMAND is the command to run.
+
+Optional arguments:
+`:docstring' is an optional docstring used for the entrypoint function created by
+`lsp-define-stdio-client'.
+
+`:ignore-regexps' is a list of regexps.  When a data packet from the LSP server
+ matches any of these regexps, it will be ignored.  This is intended for dealing
+ with LSP servers that output non-protocol data.
+
+`:ignore-messages' is a list of regexps.  When a message from the LSP server
+ matches any of these regexps, it will be ignored.  This is useful for filtering
+ out unwanted messages; such as servers that send nonstandard message types, or
+ extraneous `logMessage's.
+
+`:command-fn' is a function that returns the command string/list to be used to
+ launch the language server. If non-nil, COMMAND is ignored.
+
+`:language-id-fn' is a function that returns the language-id string to be used
+ while opening a new file. If non-nil, LANGUAGE-ID is ignored.
+
+`:extra-init-params' is a plist that specifies any (optional)
+ initializeOptions parameters required by the LSP server. A function taking
+ a single argument (LSP workspace) and returning a plist is also accepted.
+
+`:initialize' is a function called when the client is initialized. It takes a
+ single argument, the newly created client.
+
+`:prefix-function' is a function called for getting the prefix for completion.
+ The function takes no parameter and returns a cons (start . end) representing
+ the start and end bounds of the prefix. If it's not set, the client uses a
+ default prefix function."
+  (cl-check-type name symbol)
+  (let ((enable-name (intern (format "%s-enable" name))))
+    `(progn
+       (lsp-define-whitelist-add ,name ,get-root)
+       (lsp-define-whitelist-remove ,name ,get-root)
+       (defun ,enable-name ()
+         ,docstring
+         (interactive)
+         (lsp--enable-stdio-client ',name
+           :language-id ,language-id
+           :language-id-fn ,language-id-fn
+           :root-directory-fn ,get-root
+           :command ,command
+           :command-fn ,command-fn
+           :ignore-regexps ,ignore-regexps
+           :ignore-messages ,ignore-messages
+           :extra-init-params ,extra-init-params
+           :initialize-fn ,initialize
+           :enable-function (function ,enable-name)
+           :prefix-function ,prefix-function)))))
+
+(cl-defun lsp--enable-stdio-client (name &key language-id language-id-fn
+                                         root-directory-fn command command-fn
+                                         ignore-regexps ignore-messages
+                                         extra-init-params initialize-fn
+                                         enable-function
+                                         prefix-function)
+  (cl-check-type name symbol)
+  (cl-check-type language-id (or null string))
+  (cl-check-type language-id-fn (or null function))
+  (cl-check-type root-directory-fn (or null function))
+  (cl-check-type command list)
+  (cl-check-type command-fn (or null function))
+  (cl-check-type ignore-regexps list)
+  (cl-check-type ignore-messages list)
+  (cl-check-type extra-init-params (or list function))
+  (cl-check-type initialize-fn (or null function))
+  ;; (cl-check-type enable-function function)
+  (cl-check-type prefix-function (or null function))
+  (when (and (not lsp-mode) (buffer-file-name))
+    (let* ((stderr (generate-new-buffer-name
+                    (concat "*" (symbol-name name) " stderr*")))
+           (client (make-lsp--client
+                    :language-id (or language-id-fn (lambda (_) language-id))
+                    :new-connection (lsp--make-stdio-connection
+                                     (symbol-name name)
+                                     command
+                                     command-fn
+                                     stderr)
+                    :stderr stderr
+                    :get-root root-directory-fn
+                    :ignore-regexps ignore-regexps
+                    :ignore-messages ignore-messages
+                    :enable-function enable-function
+                    :prefix-function prefix-function)))
+      (when initialize-fn
+        (funcall initialize-fn client))
+      (let ((root (funcall (lsp--client-get-root client))))
+        (if (lsp--should-start-p root)
+            (lsp--start client extra-init-params)
+          (message "Not initializing project %s" root))))))
+
+(cl-defmacro lsp-define-tcp-client (name language-id get-root command host port
+                                     &key docstring
+                                     language-id-fn
+                                     command-fn
+                                     ignore-regexps
+                                     ignore-messages
+                                     extra-init-params
+                                     initialize
+                                     prefix-function)
+  "Define a LSP client using TCP.
+NAME is the symbol to use for the name of the client.
+LANGUAGE-ID is the language id to be used when communication with
+the Language Server.  COMMAND is the command to run.  HOST is the
+host address.  PORT is the port number.
+
+Optional arguments:
+`:ignore-regexps' is a list of regexps.  When a data packet from the LSP server
+ matches any of these regexps, it will be ignored.  This is intended for dealing
+ with LSP servers that output non-protocol data.
+
+`:ignore-messages' is a list of regexps.  When a message from the LSP server
+ matches any of these regexps, it will be ignored.  This is useful for filtering
+ out unwanted messages; such as servers that send nonstandard message types, or
+ extraneous `logMessage's.
+
+`:command-fn' is a function that returns the command string/list to be used to
+ launch the language server. If non-nil, COMMAND is ignored.
+
+`:language-id-fn' is a function that returns the language-id string to be used
+ while opening a new file. If non-nil, LANGUAGE-ID is ignored.
+
+`:extra-init-params' is a plist that specifies any (optional)
+ initializeOptions parameters required by the LSP server. A function taking
+ a single argument (LSP workspace) and returning a plist is also accepted.
+
+`:initialize' is a function called when the client is initialized. It takes a
+  single argument, the newly created client.
+
+`:prefix-function' is a function called for getting the prefix for completion.
+ The function takes no parameter and returns a cons (start . end) representing
+ the start and end bounds of the prefix. If it's not set, the client uses a
+ default prefix function."
+  (cl-check-type name symbol)
+  (let ((enable-name (intern (format "%s-enable" name))))
+    `(progn
+       (lsp-define-whitelist-add ,name ,get-root)
+       (lsp-define-whitelist-remove ,name ,get-root)
+       (defun ,enable-name ()
+         ,docstring
+         (interactive)
+         (lsp--enable-tcp-client ',name
+           :language-id ,language-id
+           :language-id-fn ,language-id-fn
+           :root-directory-fn ,get-root
+           :command ,command
+           :command-fn ,command-fn
+           :host ,host
+           :port ,port
+           :ignore-regexps ,ignore-regexps
+           :ignore-messages ,ignore-messages
+           :extra-init-params ,extra-init-params
+           :initialize-fn ,initialize
+           :enable-function (function ,enable-name)
+           :prefix-function ,prefix-function)))))
+
+(cl-defun lsp--enable-tcp-client (name &key language-id language-id-fn
+                                       root-directory-fn command command-fn
+                                       host port
+                                       ignore-regexps ignore-messages
+                                       extra-init-params initialize-fn
+                                       enable-function
+                                       prefix-function)
+  (cl-check-type name symbol)
+  (cl-check-type language-id (or null string))
+  (cl-check-type language-id-fn (or null function))
+  (cl-check-type root-directory-fn (or null function))
+  (cl-check-type command list)
+  (cl-check-type command-fn (or null function))
+  (cl-check-type host string)
+  (cl-check-type port (integer 1 #xFFFF))
+  (cl-check-type ignore-regexps list)
+  (cl-check-type ignore-messages list)
+  (cl-check-type extra-init-params (or list function))
+  (cl-check-type initialize-fn (or null function))
+  (cl-check-type prefix-function (or null function))
+  (when (and (not lsp-mode) (buffer-file-name))
+    (let* ((stderr (generate-new-buffer-name
+                    (concat "*" (symbol-name name) " stderr*")))
+           (client (make-lsp--client
+                    :language-id (or language-id-fn (lambda (_) language-id))
+                    :new-connection (lsp--make-tcp-connection
+                                     (symbol-name name)
+                                     command
+                                     command-fn
+                                     host port
+                                     stderr)
+                    :stderr stderr
+                    :get-root root-directory-fn
+                    :ignore-regexps ignore-regexps
+                    :ignore-messages ignore-messages
+                    :enable-function enable-function
+                    :prefix-function prefix-function)))
+      (when initialize-fn
+        (funcall initialize-fn client))
+      (let ((root (funcall (lsp--client-get-root client))))
+        (if (lsp--should-start-p root)
+            (lsp--start client extra-init-params)
+          (message "Not initializing project %s" root))))))
+
+(defvar-local lsp-status nil
+  "The current status of the LSP server.")
+
+(defun lsp-workspace-status (status-string &optional workspace)
+  "Set current workspace status to STATUS-STRING.
+If WORKSPACE is not specified defaults to lsp--cur-workspace."
+  (setf (lsp--workspace-status (or workspace lsp--cur-workspace)) status-string))
+
+(defun lsp-mode-line ()
+  "Construct the mode line text."
+  (concat " LSP" lsp-status (lsp--workspace-status lsp--cur-workspace)))
+
+(defconst lsp--sync-type
+  `((0 . "None")
+    (1 . "Full Document")
+    (2 . "Incremental Changes")))
+
+(defconst lsp--capabilities
+  `(("textDocumentSync" . ("Document sync method" .
+                           ((0 . "None")
+                            (1 . "Send full contents")
+                            (2 . "Send incremental changes."))))
+    ("hoverProvider" . ("The server provides hover support" . boolean))
+    ("completionProvider" . ("The server provides completion support" . boolean))
+    ("signatureHelpProvider" . ("The server provides signature help support" . boolean))
+    ("definitionProvider" . ("The server provides goto definition support" . boolean))
+    ("typeDefinitionProvider" . ("The server provides goto type definition support" . boolean))
+    ("implementationProvider" . ("The server provides goto implementation support" . boolean))
+    ("referencesProvider" . ("The server provides references support" . boolean))
+    (("documentHighlightProvider" . ("The server provides document highlight support." . boolean)))
+    ("documentSymbolProvider" . ("The server provides file symbol support" . boolean))
+    ("workspaceSymbolProvider" . ("The server provides project symbol support" . boolean))
+    ("codeActionProvider" . ("The server provides code actions" . boolean))
+    ("codeLensProvider" . ("The server provides code lens" . boolean))
+    ("documentFormattingProvider" . ("The server provides file formatting" . boolean))
+    ("documentOnTypeFormattingProvider" . ("The server provides on-type formatting" . boolean))
+    ("documentLinkProvider" . ("The server provides document link support" . boolean))
+    ("executeCommandProvider" . ("The server provides command execution support" . boolean))
+    (("documentRangeFormattingProvider" . ("The server provides region formatting" . boolean)))
+    (("renameProvider" . ("The server provides rename support" . boolean)))))
+
+(defun lsp--cap-str (cap)
+  (let* ((elem (assoc cap lsp--capabilities))
+         (desc (cadr elem))
+         (type (cddr elem))
+         (value (gethash cap (lsp--server-capabilities))))
+    (when (and elem desc type value)
+      (concat desc (cond
+                    ((listp type) (concat ": " (cdr (assoc value type))))) "\n"))))
+
+(defun lsp-capabilities ()
+  "View all capabilities for the language server associated with this buffer."
+  (interactive)
+  (unless lsp--cur-workspace
+    (user-error "No language server is associated with this buffer"))
+  (let ((str (mapconcat #'lsp--cap-str (reverse (hash-table-keys
+                                                 (lsp--server-capabilities))) ""))
+        (buffer-name (generate-new-buffer-name "lsp-capabilities"))
+        )
+    (get-buffer-create buffer-name)
+    (with-current-buffer buffer-name
+      (view-mode -1)
+      (erase-buffer)
+      (insert str)
+      (view-mode 1))
+    (switch-to-buffer buffer-name)))
+
+(provide 'lsp-mode)
+;;; lsp-mode.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/lsp-mode-20180827.344/lsp-mode.elc b/configs/shared/emacs/.emacs.d/elpa/lsp-mode-20180827.344/lsp-mode.elc
new file mode 100644
index 0000000000..00e15cc55a
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/lsp-mode-20180827.344/lsp-mode.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/lsp-mode-20180827.344/lsp-notifications.el b/configs/shared/emacs/.emacs.d/elpa/lsp-mode-20180827.344/lsp-notifications.el
new file mode 100644
index 0000000000..82935a5ac9
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/lsp-mode-20180827.344/lsp-notifications.el
@@ -0,0 +1,117 @@
+;; Copyright (C) 2016-2018  Vibhav Pant <vibhavp@gmail.com>  -*- lexical-binding: t -*-
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Code:
+
+(require 'lsp-common)
+(require 'cl-lib)
+(require 'subr-x)
+
+(defcustom lsp-inhibit-message nil
+  "If non-nil, inhibit the message echo via `inhibit-message'."
+  :type 'boolean
+  :group 'lsp-mode)
+
+(defun lsp--window-show-message (params &optional workspace)
+  "Send the server's messages to message, inhibit if `lsp-inhibit-message' is set,
+or the message matches one of this client's :ignore-messages"
+  (let* ((inhibit-message (or inhibit-message lsp-inhibit-message))
+         (message (gethash "message" params))
+         (client (lsp--workspace-client workspace)))
+    (when (or (not client)
+              (cl-notany (lambda (r) (string-match-p r message))
+                         (lsp--client-ignore-messages client)))
+      (message "%s" (lsp--propertize message (gethash "type" params))))))
+
+(defun lsp--window-show-message-request (params)
+  "Display a message request to the user and send the user's
+selection back to the server."
+  (let* ((type (gethash "type" params))
+         (message (lsp--propertize (gethash "message" params) type))
+         (choices (mapcar (lambda (choice) (gethash "title" choice))
+                          (gethash "actions" params))))
+    (if choices
+        (completing-read (concat message " ") choices nil t)
+      (message message))))
+
+(defcustom lsp-after-diagnostics-hook nil
+  "Hooks to run after diagnostics are received from the language
+server and put in `lsp--diagnostics'."
+  :type 'hook
+  :group 'lsp-mode)
+
+(defvar lsp--diagnostics (make-hash-table :test 'equal)
+  "Hash table storing the diagnostics per file.")
+
+(cl-defstruct lsp-diagnostic
+  (range nil :read-only t)
+  ;; range has the form (:start (:line N :column N) :end (:line N :column N) )
+  ;; where N are zero-indexed numbers
+  (line nil :read-only t)
+  (column nil :read-only t)
+  (severity nil :read-only t) ;; 1 - error, 2 - warning, 3 - information, 4 - hint
+  (code nil :read-only t) ;; the diagnostic's code
+  (source nil :read-only t) ;;
+  (message nil :read-only t) ;; diagnostic's message
+  (original nil :read-only t) ;; original diagnostic from LSP, kept for when it
+  ;; needs to be sent back in e.g. codeAction
+  ;; context.
+  )
+
+(defun lsp--make-diag (diag)
+  "Make a `lsp-diagnostic' from DIAG."
+  (let* ((range (gethash "range" diag))
+         (start (gethash "start" range))
+         (end (gethash "end" range))
+         (message (gethash "message" diag))
+         (source (gethash "source" diag)))
+    (make-lsp-diagnostic
+     :range (list :start (list :line   (gethash "line" start)
+                               :column (gethash "character" start))
+                  :end   (list :line   (gethash "line" end)
+                               :column (gethash "character" end)))
+     :line (gethash "line" start)
+     :column (gethash "character" start)
+     :severity (gethash "severity" diag)
+     :code (gethash "code" diag)
+     :source (gethash "source" diag)
+     :message (if source (format "%s: %s" source message) message)
+     :original diag)))
+
+(defun lsp--equal-files (f1 f2)
+  (and f1 f2
+       (string-equal (file-truename f1) (file-truename f2))))
+
+(defun lsp--on-diagnostics (params workspace)
+  "Callback for textDocument/publishDiagnostics.
+interface PublishDiagnosticsParams {
+    uri: string;
+    diagnostics: Diagnostic[];
+}"
+  (let ((file (lsp--uri-to-path (gethash "uri" params)))
+        (diagnostics (gethash "diagnostics" params)) buffer)
+    (setq buffer (cl-loop for buffer in (lsp--workspace-buffers workspace)
+                          when (lsp--equal-files (buffer-file-name buffer) file)
+                          return buffer
+                          finally return nil))
+    (when buffer
+      (puthash file (mapcar #'lsp--make-diag diagnostics) lsp--diagnostics)
+      (with-current-buffer buffer
+        (run-hooks 'lsp-after-diagnostics-hook)))))
+
+(declare-function lsp--workspace-buffers "lsp-methods" (workspace))
+
+(provide 'lsp-notifications)
+;;; lsp-notifications.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/lsp-mode-20180827.344/lsp-notifications.elc b/configs/shared/emacs/.emacs.d/elpa/lsp-mode-20180827.344/lsp-notifications.elc
new file mode 100644
index 0000000000..e10013ca02
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/lsp-mode-20180827.344/lsp-notifications.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/lsp-ui-20180619.251/lsp-ui-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/lsp-ui-20180619.251/lsp-ui-autoloads.el
new file mode 100644
index 0000000000..2ec1da5e3d
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/lsp-ui-20180619.251/lsp-ui-autoloads.el
@@ -0,0 +1,32 @@
+;;; lsp-ui-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "lsp-ui" "lsp-ui.el" (23428 20493 246694 908000))
+;;; Generated autoloads from lsp-ui.el
+
+(autoload 'lsp-ui-mode "lsp-ui" "\
+Toggle language server UI mode on or off.
+‘lsp-ui-mode’ is a minor mode that contains a series of useful UI
+integrations for ‘lsp-mode’.  With a prefix argument ARG, enable
+language server UI mode if ARG is positive, and disable it
+otherwise.  If called from Lisp, enable the mode if ARG is
+omitted or nil, and toggle it if ARG is ‘toggle’.
+
+\(fn &optional ARG)" t nil)
+
+;;;***
+
+;;;### (autoloads nil nil ("lsp-ui-doc.el" "lsp-ui-flycheck.el" "lsp-ui-imenu.el"
+;;;;;;  "lsp-ui-peek.el" "lsp-ui-pkg.el" "lsp-ui-sideline.el") (23428
+;;;;;;  20493 250920 356000))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; lsp-ui-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/lsp-ui-20180619.251/lsp-ui-doc.el b/configs/shared/emacs/.emacs.d/elpa/lsp-ui-20180619.251/lsp-ui-doc.el
new file mode 100644
index 0000000000..e31d106631
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/lsp-ui-20180619.251/lsp-ui-doc.el
@@ -0,0 +1,651 @@
+;;; lsp-ui-doc.el --- Lsp-Ui-Doc  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 Sebastien Chapuis
+
+;; Author: Sebastien Chapuis <sebastien@chapu.is>
+;; URL: https://github.com/emacs-lsp/lsp-ui
+;; Keywords: lsp, ui
+
+;;; License
+;;
+;; This program 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, or (at your option)
+;; any later version.
+
+;; This program 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 this program; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+;; Floor, Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+;;
+;; Show documentation of the symbol at point in a child frame
+
+;;; Code:
+
+(require 'lsp-mode)
+(require 'dash)
+(require 'dash-functional)
+(require 'markdown-mode)
+
+(defgroup lsp-ui-doc nil
+  "Display informations of the current line."
+  :group 'tools
+  :group 'convenience
+  :group 'lsp-ui
+  :link '(custom-manual "(lsp-ui-doc) Top")
+  :link '(info-link "(lsp-ui-doc) Customizing"))
+
+(defcustom lsp-ui-doc-enable t
+  "Whether or not to enable lsp-ui-doc."
+  :type 'boolean
+  :group 'lsp-ui)
+
+(defcustom lsp-ui-doc-header nil
+  "Whether or not to enable the header which display the symbol string."
+  :type 'boolean
+  :group 'lsp-ui-doc)
+
+(defcustom lsp-ui-doc-include-signature nil
+  "Whether or not to include the object signature/type in the frame."
+  :type 'boolean
+  :group 'lsp-ui-doc)
+
+(defcustom lsp-ui-doc-position 'top
+  "Where to display the doc."
+  :type '(choice (const :tag "Top" top)
+                 (const :tag "Bottom" bottom)
+                 (const :tag "At point" at-point))
+  :group 'lsp-ui-doc)
+
+(defcustom lsp-ui-doc-border "white"
+  "Border color of the frame."
+  :type 'color
+  :group 'lsp-ui-doc)
+
+(defcustom lsp-ui-doc-max-width 150
+  "Maximum number of columns of the frame."
+  :type 'integer
+  :group 'lsp-ui-doc)
+
+(defcustom lsp-ui-doc-max-height 30
+  "Maximum number of lines in the frame."
+  :type 'integer
+  :group 'lsp-ui-doc)
+
+(defcustom lsp-ui-doc-use-childframe t
+  "Whether to display documentation in a child-frame or the current frame.
+Child frames requires GNU/Emacs version >= 26 and graphical frames."
+  :type 'boolean
+  :group 'lsp-ui-doc)
+
+(defface lsp-ui-doc-background
+  '((((background light)) :background "#b3b3b3")
+    (t :background "#272A36"))
+  "Background color of the documentation.
+Only the `background' is used in this face."
+  :group 'lsp-ui-doc)
+
+(defface lsp-ui-doc-header
+  '((t :foreground "black"
+       :background "deep sky blue"))
+  "Face used on the header."
+  :group 'lsp-ui-doc)
+
+(defface lsp-ui-doc-url
+  '((t :inherit link))
+  "Face used on links."
+  :group 'lsp-ui-doc)
+
+(defvar lsp-ui-doc-frame-parameters
+  '((left . -1)
+    (no-accept-focus . t)
+    (no-focus-on-map . t)
+    (min-width  . 0)
+    (width  . 0)
+    (min-height  . 0)
+    (height  . 0)
+    (internal-border-width . 1)
+    (vertical-scroll-bars . nil)
+    (horizontal-scroll-bars . nil)
+    (right-fringe . 0)
+    (menu-bar-lines . 0)
+    (tool-bar-lines . 0)
+    (line-spacing . 0)
+    (unsplittable . t)
+    (undecorated . t)
+    (top . -1)
+    (visibility . nil)
+    (mouse-wheel-frame . nil)
+    (no-other-frame . t)
+    (cursor-type . nil)
+    (inhibit-double-buffering . t)
+    (drag-internal-border . t)
+    (no-special-glyphs . t)
+    (desktop-dont-save . t))
+  "Frame parameters used to create the frame.")
+
+(defvar lsp-ui-doc-render-function nil
+  "Function called to format the documentation.
+The function takes a string as parameter and should return a string.
+If this variable is nil (the default), the documentation will be rendered
+as markdown.")
+
+(defvar lsp-ui-doc-custom-markup-modes
+  '((rust-mode "no_run" "rust,no_run" "rust,ignore" "rust,should_panic"))
+  "Mode to uses with markdown code blocks.
+They are added to `markdown-code-lang-modes'")
+
+(defvar lsp-ui-doc-frame-hook nil
+  "Hooks run on child-frame creation.
+The functions receive 2 parameters: the frame and its window.")
+
+(defvar-local lsp-ui-doc--bounds nil)
+(defvar-local lsp-ui-doc--string-eldoc nil)
+
+(declare-function lsp-ui-sideline--get-renderer 'lsp-ui-sideline)
+
+;; Avoid warning with emacs < 26
+(declare-function display-buffer-in-child-frame "window.el")
+
+(defvar-local lsp-ui-doc--parent-vars nil
+  "Variables from the parents frame that we want to access in the child.
+Because some variables are buffer local.")
+
+(defvar-local lsp-ui-doc--inline-ov nil
+  "Overlay used to display the documentation in the buffer.")
+
+(defmacro lsp-ui-doc--with-buffer (&rest body)
+  "Execute BODY in the lsp-ui-doc buffer."
+  `(let ((parent-vars (list :buffer (current-buffer)
+                            :window (get-buffer-window)
+                            :workspace-root (when lsp--cur-workspace
+                                              (lsp--workspace-root lsp--cur-workspace)))))
+     (with-current-buffer (get-buffer-create (lsp-ui-doc--make-buffer-name))
+       (setq lsp-ui-doc--parent-vars parent-vars)
+       (prog1 (let ((buffer-read-only nil))
+                ,@body)
+         (setq buffer-read-only t)))))
+
+(defmacro lsp-ui-doc--get-parent (var)
+  "Return VAR in `lsp-ui-doc--parent-vars'."
+  `(plist-get lsp-ui-doc--parent-vars ,var))
+
+(defmacro lsp-ui-doc--set-frame (frame)
+  "Set the frame parameter ‘lsp-ui-doc-frame’ to FRAME."
+  `(set-frame-parameter nil 'lsp-ui-doc-frame ,frame))
+
+(defmacro lsp-ui-doc--get-frame ()
+  "Return the child frame."
+  `(frame-parameter nil 'lsp-ui-doc-frame))
+
+(defun lsp-ui-doc--make-buffer-name ()
+  "Construct the buffer name, it should be unique for each frame."
+  (concat " *lsp-ui-doc-"
+          (or (frame-parameter nil 'window-id)
+              (frame-parameter nil 'name))
+          "*"))
+
+(defun lsp-ui-doc--set-eldoc (marked-string)
+  (when marked-string
+    (let ((string (lsp-ui-doc--extract-marked-string marked-string)))
+      (setq lsp-ui-doc--string-eldoc string))))
+
+(defun lsp-ui-doc--eldoc (&rest _)
+  (when (and (lsp--capability "documentHighlightProvider")
+             lsp-highlight-symbol-at-point)
+    (lsp-symbol-highlight))
+  lsp-ui-doc--string-eldoc)
+
+;; ‘markdown-fontify-code-block-default-mode’ isn’t yet available in
+;; Markdown 2.3.
+(defvar markdown-fontify-code-block-default-mode)
+
+(defun lsp-ui-doc--setup-markdown (mode)
+  "Setup the ‘markdown-mode’ in the frame.
+MODE is the mode used in the parent frame."
+  (make-local-variable 'markdown-code-lang-modes)
+  (dolist (mark (alist-get mode lsp-ui-doc-custom-markup-modes))
+    (add-to-list 'markdown-code-lang-modes (cons mark mode)))
+  (setq-local markdown-fontify-code-blocks-natively t)
+  (setq-local markdown-fontify-code-block-default-mode mode)
+  (setq-local markdown-hide-markup t))
+
+(defun lsp-ui-doc--extract-marked-string (marked-string)
+  "Render the MARKED-STRING."
+  (string-trim-right
+   (let* ((string (if (stringp marked-string)
+                      marked-string
+                    (gethash "value" marked-string)))
+          (with-lang (hash-table-p marked-string))
+          (language (and with-lang (gethash "language" marked-string)))
+          (render-fn (if with-lang (lsp-ui-sideline--get-renderer language)
+                       (and (functionp lsp-ui-doc-render-function)
+                            lsp-ui-doc-render-function)))
+          (mode major-mode))
+     (if render-fn
+         (funcall render-fn string)
+       (with-temp-buffer
+         (insert string)
+         (delay-mode-hooks
+           (let ((inhibit-message t))
+             (funcall (cond ((and with-lang (string= "text" language)) 'text-mode)
+                            ((fboundp 'gfm-view-mode) 'gfm-view-mode)
+                            (t 'markdown-mode))))
+           (when (derived-mode-p 'markdown-mode)
+             (lsp-ui-doc--setup-markdown mode))
+           (ignore-errors
+             (font-lock-ensure)))
+         (buffer-string))))))
+
+(defun lsp-ui-doc--filter-marked-string (list-marked-string)
+  (let ((groups (--separate (and (hash-table-p it)
+                                 (lsp-ui-sideline--get-renderer (gethash "language" it)))
+                            list-marked-string)))
+    (lsp-ui-doc--set-eldoc (caar groups))
+    (if lsp-ui-doc-include-signature
+        list-marked-string
+      (cadr groups))))
+
+(defun lsp-ui-doc--extract (contents)
+  "Extract the documentation from CONTENTS.
+CONTENTS can be differents type of values:
+MarkedString | MarkedString[] | MarkupContent (as defined in the LSP).
+We don't extract the string that `lps-line' is already displaying."
+  (when contents
+    (cond
+     ((stringp contents) contents)
+     ((listp contents) ;; MarkedString[]
+      (mapconcat 'lsp-ui-doc--extract-marked-string
+                 (lsp-ui-doc--filter-marked-string contents)
+                 "\n\n"
+                 ;; (propertize "\n\n" 'face '(:height 0.4))
+                 ))
+     ((gethash "kind" contents) (gethash "value" contents)) ;; MarkupContent
+     ((gethash "language" contents) ;; MarkedString
+      (lsp-ui-doc--extract-marked-string contents)))))
+
+(defun lsp-ui-doc--make-request ()
+  "Request the documentation to the LS."
+  (when (and (bound-and-true-p lsp--cur-workspace)
+             (not (bound-and-true-p lsp-ui-peek-mode)))
+    (if (symbol-at-point)
+        (let ((bounds (bounds-of-thing-at-point 'symbol)))
+          (unless (equal lsp-ui-doc--bounds bounds)
+            (lsp--send-request-async (lsp--make-request "textDocument/hover"
+                                                        (lsp--text-document-position-params))
+                                     (lambda (hover)
+                                       (lsp-ui-doc--callback hover bounds (current-buffer))
+                                       ))))
+      (setq lsp-ui-doc--string-eldoc nil)
+      (lsp-ui-doc--hide-frame))))
+
+(defun lsp-ui-doc--callback (hover bounds buffer)
+  "Process the received documentation.
+HOVER is the doc returned by the LS.
+BOUNDS are points of the symbol that have been requested.
+BUFFER is the buffer where the request has been made."
+  (if (and hover
+           (lsp--point-is-within-bounds-p (car bounds) (cdr bounds))
+           (equal buffer (current-buffer)))
+      (let ((doc (lsp-ui-doc--extract (gethash "contents" hover))))
+        (setq lsp-ui-doc--bounds bounds)
+        (lsp-ui-doc--display (thing-at-point 'symbol t) doc))
+    (setq lsp-ui-doc--string-eldoc nil)
+    (lsp-ui-doc--hide-frame)))
+
+(defun lsp-ui-doc--hide-frame ()
+  "Hide the frame."
+  (setq lsp-ui-doc--bounds nil)
+  (when (overlayp lsp-ui-doc--inline-ov)
+    (delete-overlay lsp-ui-doc--inline-ov))
+  (when (lsp-ui-doc--get-frame)
+    (lsp-ui-doc--with-buffer
+     (erase-buffer))
+    (make-frame-invisible (lsp-ui-doc--get-frame))))
+
+(defun lsp-ui-doc--buffer-width ()
+  "Calcul the max width of the buffer."
+  (lsp-ui-doc--with-buffer
+   (save-excursion
+     (let ((max 0))
+       (goto-char (point-min))
+       (while (not (eobp))
+         (let* ((len (- (line-end-position) (line-beginning-position))))
+           (when (> len max)
+             (setq max len)))
+         (forward-line 1))
+       max))))
+
+(defun lsp-ui-doc--line-height (&optional line)
+  "Return the pos-y of the LINE on screen, in pixel."
+  (nth 2 (or (window-line-height line)
+             (and (redisplay t)
+                  (window-line-height line)))))
+
+(defun lsp-ui-doc--sideline-pos-y ()
+  (-> (when (bound-and-true-p lsp-ui-sideline--occupied-lines)
+        (-min lsp-ui-sideline--occupied-lines))
+      (line-number-at-pos)
+      (lsp-ui-doc--line-height)))
+
+(defun lsp-ui-doc--resize-buffer ()
+  "If the buffer's width is larger than the current frame, resize it."
+  (let* ((frame-width (frame-width))
+         (fill-column (min lsp-ui-doc-max-width (- frame-width 5))))
+    (when (> (lsp-ui-doc--buffer-width) (min lsp-ui-doc-max-width frame-width))
+      (lsp-ui-doc--with-buffer
+       (fill-region (point-min) (point-max))))))
+
+(defun lsp-ui-doc--next-to-side-window-p nil
+  "Return non-nil if the window on the left is a side window."
+  (let* ((win (window-at 0 0))
+         (left (window-left (selected-window))))
+    (and (not (eq win (selected-window)))
+         (or (not left) (eq win left))
+         (eq (window-parameter win 'window-side) 'left))))
+
+(defun lsp-ui-doc--mv-at-point (frame height start-x start-y)
+  "Move the FRAME at point.
+HEIGHT is the child frame height.
+START-X is the position x of the current window.
+START-Y is the position y of the current window."
+  (-let* (((x . y) (--> (bounds-of-thing-at-point 'symbol)
+                        (nth 2 (posn-at-point (car it)))))
+          (mode-line-y (lsp-ui-doc--line-height 'mode-line))
+          (char-height (frame-char-height))
+          (y (or (and (> y (/ mode-line-y 2))
+                      (<= (- mode-line-y y) (+ char-height height))
+                      (> (- y height) 0)
+                      (- y height))
+                 (+ y char-height))))
+    (set-frame-position frame (+ x start-x) (+ y start-y))))
+
+(defun lsp-ui-doc--move-frame (frame)
+  "Place our FRAME on screen."
+  (lsp-ui-doc--resize-buffer)
+  (-let* (((left top _right _bottom) (window-edges nil nil nil t))
+          (window (frame-root-window frame))
+          ((width . height) (window-text-pixel-size window nil nil 10000 10000 t))
+          (width (+ width (* (frame-char-width frame) 1))) ;; margins
+          (char-h (frame-char-height))
+          (height (min (- (* lsp-ui-doc-max-height char-h) (/ char-h 2)) height))
+          (frame-resize-pixelwise t))
+    (set-frame-size frame width height t)
+    (if (eq lsp-ui-doc-position 'at-point)
+        (lsp-ui-doc--mv-at-point frame height left top)
+      (set-frame-position frame
+                          (if (and (>= left (+ width 10 (frame-char-width)))
+                                   (not (lsp-ui-doc--next-to-side-window-p)))
+                              10
+                            (- (frame-pixel-width) width 10 (frame-char-width)))
+                          (pcase lsp-ui-doc-position
+                            ('top (+ top 10))
+                            ('bottom (- (lsp-ui-doc--line-height 'mode-line)
+                                        height
+                                        10)))))))
+
+(defun lsp-ui-doc--visit-file (filename)
+  "Visit FILENAME in the parent frame."
+  (-some->> (find-file-noselect filename)
+            (set-window-buffer (lsp-ui-doc--get-parent :window))))
+
+(defun lsp-ui-doc--put-click (bounds fn)
+  "Add text properties on text to make it clickable.
+The text delimiters are BOUNDS.
+FN is the function to call on click."
+  (let ((map (make-sparse-keymap)))
+    (define-key map [down-mouse-1] fn)
+    (put-text-property (car bounds) (cdr bounds) 'keymap map)
+    (put-text-property (car bounds) (cdr bounds) 'mouse-face
+                       (list :inherit 'lsp-ui-doc-url
+                             :box (list :line-width -1
+                                        :color (face-foreground 'lsp-ui-doc-url))))
+    (add-face-text-property (car bounds) (cdr bounds) 'lsp-ui-doc-url)))
+
+(defun lsp-ui-doc--make-clickable-link ()
+  "Find paths and urls in the buffer and make them clickable."
+  (goto-char (point-min))
+  (save-excursion
+    (while (not (eobp))
+      ;;; TODO:
+      ;;;  Search path in the whole buffer.
+      ;;;  For now, it searches only on beginning of lines.
+      (-when-let* ((filename (thing-at-point 'filename))
+                   (path (if (file-readable-p filename) filename
+                           (let ((full (concat (lsp-ui-doc--get-parent :workspace-root)
+                                               filename)))
+                             (and (file-readable-p full)
+                                  full)))))
+        (lsp-ui-doc--put-click (or (bounds-of-thing-at-point 'filename)
+                                   (bounds-of-thing-at-point 'url))
+                               (lambda () (interactive)
+                                 (lsp-ui-doc--visit-file path))))
+      (forward-line 1))
+    (goto-char (point-min))
+    (condition-case nil
+        (while (search-forward-regexp "http[s]?://")
+          (lsp-ui-doc--put-click (or (thing-at-point-bounds-of-url-at-point)
+                                     (bounds-of-thing-at-point 'filename))
+                                 'browse-url-at-mouse))
+      (search-failed nil))))
+
+(defun lsp-ui-doc--render-buffer (string symbol)
+  "Set the buffer with STRING."
+  (lsp-ui-doc--with-buffer
+   (erase-buffer)
+   (let ((inline-p (lsp-ui-doc--inline-p)))
+     (insert (concat (unless inline-p (propertize "\n" 'face '(:height 0.2)))
+                     (-> (replace-regexp-in-string "`\\([\n]+\\)" "" string)
+                         (string-trim-right))
+                     (unless inline-p (propertize "\n\n" 'face '(:height 0.3))))))
+   (lsp-ui-doc--make-clickable-link)
+   (setq-local face-remapping-alist `((header-line lsp-ui-doc-header)))
+   (setq-local window-min-height 1)
+   (setq header-line-format (when lsp-ui-doc-header (concat " " symbol))
+         mode-line-format nil
+         cursor-type nil)))
+
+(defun lsp-ui-doc--inline-height ()
+  (lsp-ui-doc--with-buffer
+   (length (split-string (buffer-string) "\n"))))
+
+(defun lsp-ui-doc--remove-invisibles (string)
+  "Remove invisible characters in STRING."
+  (let* ((start (text-property-not-all 0 (length string) 'invisible nil string)))
+    (while start
+      (setq string (concat (substring string 0 start)
+                           (-some->> (next-single-property-change start 'invisible string)
+                                     (substring string))))
+      (setq start (text-property-not-all 0 (length string) 'invisible nil string)))
+    string))
+
+(defvar-local lsp-ui-doc--inline-width nil)
+
+(defun lsp-ui-doc--inline-window-width nil
+  (- (min (window-text-width)
+          (window-body-width))
+     (if (bound-and-true-p display-line-numbers-mode)
+         (+ 2 (line-number-display-width))
+       0)
+     1))
+
+(defun lsp-ui-doc--inline-zip (s1 s2)
+  (let* ((width (lsp-ui-doc--inline-window-width))
+         (max-s1 (- width lsp-ui-doc--inline-width 2)))
+    (truncate-string-to-width
+     (concat (truncate-string-to-width s1 max-s1 nil ?\s) s2)
+     width nil ?\s)))
+
+(defun lsp-ui-doc--inline-padding (string len)
+  (let ((string (concat " " string (make-string (- len (string-width string)) ?\s) " ")))
+    (add-face-text-property 0 (length string) (list :background (face-background 'lsp-ui-doc-background nil t)) t string)
+    string))
+
+(defun lsp-ui-doc--inline-faking-frame (doc-strings)
+  (let* ((len-max (-max-by '> (-map 'string-width doc-strings))))
+    (setq lsp-ui-doc--inline-width len-max)
+    (--map (lsp-ui-doc--inline-padding it len-max) doc-strings)))
+
+(defun lsp-ui-doc--inline-untab (string)
+  (replace-regexp-in-string "\t" (make-string tab-width ?\s) string nil t))
+
+(defun lsp-ui-doc--inline-merge (strings)
+  (let* ((buffer-strings (-> (lsp-ui-doc--inline-untab strings)
+                             (lsp-ui-doc--remove-invisibles)
+                             (split-string "\n")))
+         (doc-strings (-> (lsp-ui-doc--with-buffer (buffer-string))
+                          (lsp-ui-doc--inline-untab)
+                          (lsp-ui-doc--remove-invisibles)
+                          (split-string "\n")))
+         (merged (--> (lsp-ui-doc--inline-faking-frame doc-strings)
+                      (-zip-with 'lsp-ui-doc--inline-zip buffer-strings it)
+                      (string-join it "\n")
+                      (concat it "\n"))))
+    (add-face-text-property 0 (length merged) 'default t merged)
+    merged))
+
+(defun lsp-ui-doc--inline-pos-at (start lines)
+  "Calcul the position at START + forward n LINES."
+  (save-excursion (goto-char start)
+                  (forward-line lines)
+                  (point)))
+
+(defun lsp-ui-doc--inline-pos (height)
+  "Return a cons of positions where to place the doc.
+HEIGHT is the documentation number of lines."
+  (let* ((w-start (window-start))
+         (w-end (lsp-ui-doc--inline-pos-at w-start (window-body-height)))
+         (ov-end (lsp-ui-doc--inline-pos-at w-start height)))
+    (cond
+     ;; Display on top ?
+     ((< (lsp-ui-doc--inline-pos-at ov-end 1) (point))
+      (cons w-start ov-end))
+     ;; Display at the bottom ?
+     ((>= (lsp-ui-doc--inline-pos-at w-end (- height))
+          (lsp-ui-doc--inline-pos-at (point) 2))
+      (cons (lsp-ui-doc--inline-pos-at w-end (- height))
+            w-end))
+     ;; The doc is too long to display it fixed to the bottom ?
+     ;; Then display 2 lines after `point'
+     ;; The end of the documentation won't be visible in the window
+     (t (cons (lsp-ui-doc--inline-pos-at (point) 2)
+              (lsp-ui-doc--inline-pos-at (point) (+ height 2)))))))
+
+(defun lsp-ui-doc--inline ()
+  "Display the doc in the buffer."
+  (-let* ((height (lsp-ui-doc--inline-height))
+          ((start . end) (lsp-ui-doc--inline-pos height))
+          (buffer-string (buffer-substring start end))
+          (ov (if (overlayp lsp-ui-doc--inline-ov) lsp-ui-doc--inline-ov
+                (setq lsp-ui-doc--inline-ov (make-overlay start end)))))
+    (move-overlay ov start end)
+    (overlay-put ov 'display (lsp-ui-doc--inline-merge buffer-string))
+    (overlay-put ov 'lsp-ui-doc-inline t)
+    (overlay-put ov 'window (selected-window))))
+
+(defun lsp-ui-doc--inline-p ()
+  "Return non-nil when the documentation should be display without a child frame."
+  (or (not lsp-ui-doc-use-childframe)
+      (not (display-graphic-p))
+      (not (fboundp 'display-buffer-in-child-frame))))
+
+(defun lsp-ui-doc--display (symbol string)
+  "Display the documentation."
+  (if (or (null string) (string-empty-p string))
+      (lsp-ui-doc--hide-frame)
+    (lsp-ui-doc--render-buffer string symbol)
+    (if (lsp-ui-doc--inline-p)
+        (lsp-ui-doc--inline)
+      (unless (frame-live-p (lsp-ui-doc--get-frame))
+        (lsp-ui-doc--set-frame (lsp-ui-doc--make-frame)))
+      (lsp-ui-doc--move-frame (lsp-ui-doc--get-frame))
+      (unless (frame-visible-p (lsp-ui-doc--get-frame))
+        (make-frame-visible (lsp-ui-doc--get-frame))))))
+
+(defun lsp-ui-doc--make-frame ()
+  "Create the child frame and return it."
+  (lsp-ui-doc--delete-frame)
+  (let* ((after-make-frame-functions nil)
+         (before-make-frame-hook nil)
+         (name-buffer (lsp-ui-doc--make-buffer-name))
+         (buffer (get-buffer name-buffer))
+         (params (append lsp-ui-doc-frame-parameters
+                         `((default-minibuffer-frame . ,(selected-frame))
+                           (minibuffer . ,(minibuffer-window))
+                           (left-fringe . ,(frame-char-width))
+                           (background-color . ,(face-background 'lsp-ui-doc-background nil t)))))
+         (window (display-buffer-in-child-frame
+                  buffer
+                  `((child-frame-parameters . ,params))))
+         (frame (window-frame window)))
+    (set-frame-parameter nil 'lsp-ui-doc-buffer buffer)
+    (set-window-dedicated-p window t)
+    (redirect-frame-focus frame (frame-parent frame))
+    (set-face-background 'internal-border lsp-ui-doc-border frame)
+    (run-hook-with-args 'lsp-ui-doc-frame-hook frame window)
+    frame))
+
+(defun lsp-ui-doc--delete-frame ()
+  "Delete the child frame if it exists."
+  (-when-let (frame (lsp-ui-doc--get-frame))
+    (delete-frame frame)
+    (lsp-ui-doc--set-frame nil)))
+
+(defadvice select-window (after lsp-ui-doc--select-window activate)
+  "Delete the child frame if window changes."
+  (unless (equal (ad-get-arg 0) (selected-window))
+    (lsp-ui-doc--hide-frame)))
+
+(advice-add 'load-theme :before (lambda (&rest _) (lsp-ui-doc--delete-frame)))
+(add-hook 'window-configuration-change-hook #'lsp-ui-doc--hide-frame)
+
+(defun lsp-ui-doc-enable-eldoc ()
+  (setq-local eldoc-documentation-function 'lsp-ui-doc--eldoc))
+
+(defun lsp-ui-doc--on-delete (frame)
+  "Function called when a FRAME is deleted."
+  (-some--> (frame-parameter frame 'lsp-ui-doc-buffer)
+            (get-buffer it)
+            (and (buffer-live-p it) it)
+            (kill-buffer it)))
+
+(define-minor-mode lsp-ui-doc-mode
+  "Minor mode for showing hover information in child frame."
+  :init-value nil
+  :group lsp-ui-doc
+  (cond
+   (lsp-ui-doc-mode
+    (progn
+      (with-eval-after-load 'frameset
+        ;; The documentation frame can’t be properly restored.  Especially
+        ;; ‘desktop-save’ will misbehave and save a bogus string "Unprintable
+        ;; entity" in the desktop file.  Therefore we have to prevent
+        ;; ‘frameset-save’ from saving the parameter.
+        (unless (assq 'lsp-ui-doc-frame frameset-filter-alist)
+          ;; Copy the variable first.  See the documentation of
+          ;; ‘frameset-filter-alist’ for explanation.
+          (cl-callf copy-tree frameset-filter-alist)
+          (push '(lsp-ui-doc-frame . :never) frameset-filter-alist)))
+      (add-hook 'lsp-after-open-hook 'lsp-ui-doc-enable-eldoc nil t)
+      (add-hook 'post-command-hook 'lsp-ui-doc--make-request nil t)
+      (add-hook 'delete-frame-functions 'lsp-ui-doc--on-delete nil t)))
+   (t
+    (remove-hook 'delete-frame-functions 'lsp-ui-doc--on-delete t)
+    (remove-hook 'post-command-hook 'lsp-ui-doc--make-request t)
+    (remove-hook 'lsp-after-open-hook 'lsp-ui-doc-enable-eldoc t)
+    (setq-local eldoc-documentation-function 'lsp--on-hover))))
+
+(defun lsp-ui-doc-enable (enable)
+  "Enable/disable ‘lsp-ui-doc-mode’.
+It is supposed to be called from `lsp-ui--toggle'"
+  (lsp-ui-doc-mode (if enable 1 -1)))
+
+(provide 'lsp-ui-doc)
+;;; lsp-ui-doc.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/lsp-ui-20180619.251/lsp-ui-doc.elc b/configs/shared/emacs/.emacs.d/elpa/lsp-ui-20180619.251/lsp-ui-doc.elc
new file mode 100644
index 0000000000..c4bd817825
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/lsp-ui-20180619.251/lsp-ui-doc.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/lsp-ui-20180619.251/lsp-ui-flycheck.el b/configs/shared/emacs/.emacs.d/elpa/lsp-ui-20180619.251/lsp-ui-flycheck.el
new file mode 100644
index 0000000000..d6397d0740
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/lsp-ui-20180619.251/lsp-ui-flycheck.el
@@ -0,0 +1,235 @@
+;;; lsp-ui-flycheck.el --- Flycheck support for lsp-mode -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2017  fmdkdd
+;; URL: https://github.com/emacs-lsp/lsp-ui
+;; Keywords: lsp, ui
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Flycheck integration for lsp-mode.  To enable, put this in your config:
+;; (require 'lsp-ui-flycheck)
+;; (with-eval-after-load 'lsp-mode
+;;   (add-hook 'lsp-after-open-hook (lambda () (lsp-ui-flycheck-enable 1))))
+
+;;; Code:
+
+(require 'lsp-notifications)
+(require 'lsp-mode)
+(require 'flycheck)
+(require 'pcase)
+(require 'dash)
+
+(defgroup lsp-ui-flycheck nil
+  "The LSP extension to display syntax checking."
+  :group 'tools
+  :group 'convenience
+  :group 'lsp-ui
+  :link '(custom-manual "(lsp-ui-flycheck) Top")
+  :link '(info-link "(lsp-ui-flycheck) Customizing"))
+
+(defcustom lsp-ui-flycheck-enable t
+  "Whether or not to enable ‘lsp-ui-flycheck’."
+  :type 'boolean
+  :group 'lsp-ui)
+
+(defcustom lsp-ui-flycheck-live-reporting t
+  "If non-nil, diagnostics in buffer will be reported as soon as possible.
+Typically, on every keystroke.
+If nil, diagnostics will be reported according to `flycheck-check-syntax-automatically'."
+  :type 'boolean
+  :group 'lsp-ui-flycheck)
+
+(defcustom lsp-ui-flycheck-list-position 'bottom
+  "Position where `lsp-ui-flycheck-list' will show diagnostics for the whole workspace."
+  :type '(choice (const :tag "Bottom" bottom)
+                 (const :tag "Right" right))
+  :group 'lsp-ui-flycheck)
+
+(defvar-local lsp-ui-flycheck-list--buffer nil)
+
+(defun lsp-ui-flycheck-list--post-command ()
+  (when (eobp)
+    (forward-line -1)))
+
+(defun lsp-ui-flycheck-list--update (window workspace)
+  (let ((buffer-read-only nil)
+        (lsp--cur-workspace workspace))
+    (erase-buffer)
+    (remove-overlays)
+    (maphash (lambda (file diagnostic)
+               (when diagnostic
+                 (overlay-put
+                  (make-overlay (point) (point))
+                  'after-string
+                  (concat (propertize "\n" 'face '(:height 0.2))
+                          (propertize (lsp-ui--workspace-path file)
+                                      'face 'dired-directory)
+                          (propertize "\n" 'face '(:height 0.2)))))
+               (dolist (diag diagnostic)
+                 (let* ((message (or (lsp-diagnostic-message diag) "???"))
+                        (severity (or (lsp-diagnostic-severity diag) 1))
+                        (line (or (lsp-diagnostic-line diag) 1))
+                        (face (cond ((= severity 1) 'error)
+                                    ((= severity 2) 'warning)
+                                    (t 'success)))
+                        (text (concat (propertize (number-to-string line) 'face face)
+                                      ": "
+                                      (car (split-string message "\n")))))
+                   (add-text-properties 0 (length text) `(diag ,diag file ,file window ,window) text)
+                   (insert (concat text "\n")))))
+             lsp--diagnostics))
+  (if (= (point) 1)
+      (overlay-put (make-overlay 1 1)
+                   'after-string "No diagnostic available\n")
+    (goto-char 1))
+  (lsp-ui-flycheck-list-mode))
+
+(defun lsp-ui-flycheck-list ()
+  "List all the diagnostics in the whole workspace."
+  (interactive)
+  (let ((buffer (get-buffer-create "*lsp-diagnostics*"))
+        (workspace lsp--cur-workspace)
+        (window (selected-window)))
+    (with-current-buffer buffer
+      (lsp-ui-flycheck-list--update window workspace))
+    (add-hook 'lsp-after-diagnostics-hook 'lsp-ui-flycheck-list--refresh nil t)
+    (setq lsp-ui-flycheck-list--buffer buffer)
+    (let ((win (display-buffer-in-side-window
+                buffer `((side . ,lsp-ui-flycheck-list-position) (slot . 5) (window-width . 0.20)))))
+      (set-window-dedicated-p win t)
+      (select-window win)
+      (fit-window-to-buffer nil nil 10))))
+
+(defun lsp-ui-flycheck-list--refresh ()
+  (let ((workspace lsp--cur-workspace)
+        (current-window (selected-window)))
+    (when (and (buffer-live-p lsp-ui-flycheck-list--buffer)
+               (get-buffer-window lsp-ui-flycheck-list--buffer)
+               workspace)
+      (with-selected-window (get-buffer-window lsp-ui-flycheck-list--buffer)
+        (lsp-ui-flycheck-list--update current-window workspace)
+        (fit-window-to-buffer nil nil 10)))))
+
+(defun lsp-ui-flycheck-list--open ()
+  (-when-let* ((diag (get-text-property (point) 'diag))
+               (file (get-text-property (point) 'file))
+               (window (get-text-property (point) 'window))
+               (line (lsp-diagnostic-line diag))
+               (column (lsp-diagnostic-column diag))
+               (marker (with-current-buffer
+                           (or (get-file-buffer file)
+                               (find-file-noselect file))
+                         (save-restriction
+                           (widen)
+                           (save-excursion
+                             (goto-char 1)
+                             (forward-line line)
+                             (forward-char column)
+                             (point-marker))))))
+    (set-window-buffer window (marker-buffer marker) t)
+    (with-selected-window window
+      (goto-char marker)
+      (recenter)
+      (pulse-momentary-highlight-one-line (marker-position marker) 'next-error))
+    window))
+
+(defun lsp-ui-flycheck-list--view ()
+  (interactive)
+  (lsp-ui-flycheck-list--open))
+
+(defun lsp-ui-flycheck-list--visit ()
+  (interactive)
+  (select-window (lsp-ui-flycheck-list--open)))
+
+(defun lsp-ui-flycheck-list--quit ()
+  (interactive)
+  (kill-buffer))
+
+(defvar lsp-ui-flycheck-list-mode-map nil
+  "Keymap for ‘lsp-ui-flycheck-list-mode’.")
+(unless lsp-ui-flycheck-list-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "q") 'lsp-ui-flycheck-list--quit)
+    (define-key map (kbd "<return>") 'lsp-ui-flycheck-list--view)
+    (define-key map (kbd "<M-return>") 'lsp-ui-flycheck-list--visit)
+    (setq lsp-ui-flycheck-list-mode-map map)))
+
+(define-derived-mode lsp-ui-flycheck-list-mode special-mode "lsp-ui-flycheck-list"
+  "Mode showing flycheck diagnostics for the whole workspace."
+  (setq truncate-lines t)
+  (setq mode-line-format nil)
+  (add-hook 'post-command-hook 'lsp-ui-flycheck-list--post-command nil t))
+
+(defun lsp-ui-flycheck--start (checker callback)
+  "Start an LSP syntax check with CHECKER.
+
+CALLBACK is the status callback passed by Flycheck."
+  ;; Turn all errors from lsp--diagnostics for the current buffer into
+  ;; flycheck-error objects and pass them immediately to the callback
+  (let ((errors))
+    (dolist (diag (or (gethash buffer-file-name lsp--diagnostics)
+                      (gethash (file-truename buffer-file-name) lsp--diagnostics)))
+      (push (flycheck-error-new
+             :buffer (current-buffer)
+             :checker checker
+             :filename buffer-file-name
+             :line (1+ (lsp-diagnostic-line diag))
+             :column (1+ (lsp-diagnostic-column diag))
+             :message (lsp-diagnostic-message diag)
+             :level (pcase (lsp-diagnostic-severity diag)
+                      (1 'error)
+                      (2 'warning)
+                      (_ 'info))
+             :id (lsp-diagnostic-code diag))
+            errors))
+    (funcall callback 'finished errors)))
+
+(flycheck-define-generic-checker 'lsp-ui
+  "A syntax checker using the Language Server Protocol (RLS)
+provided by lsp-mode.
+
+See https://github.com/emacs-lsp/lsp-mode."
+  :start #'lsp-ui-flycheck--start
+  :modes '(python-mode) ; Need a default mode
+  :predicate (lambda () lsp-mode)
+  :error-explainer (lambda (e) (flycheck-error-message e)))
+
+(defun lsp-ui-flycheck-add-mode (mode)
+  "Add MODE as a valid major mode for the lsp checker."
+  (unless (flycheck-checker-supports-major-mode-p 'lsp-ui mode)
+    (flycheck-add-mode 'lsp-ui mode)))
+
+(defun lsp-ui-flycheck--report nil
+  (and flycheck-mode
+       lsp-ui-flycheck-live-reporting
+       (flycheck-buffer)))
+
+;; FIXME: Provide a way to disable lsp-ui-flycheck
+(defun lsp-ui-flycheck-enable (_)
+  "Enable flycheck integration for the current buffer."
+  (when lsp-ui-flycheck-live-reporting
+    (setq-local flycheck-check-syntax-automatically nil))
+  (setq-local flycheck-checker 'lsp-ui)
+  (lsp-ui-flycheck-add-mode major-mode)
+  (add-to-list 'flycheck-checkers 'lsp-ui)
+  (add-hook 'lsp-after-diagnostics-hook 'lsp-ui-flycheck--report nil t))
+
+;; lsp-ui.el loads lsp-ui-flycheck.el, so we can’t ‘require’ lsp-ui.
+;; FIXME: Remove this cyclic dependency.
+(declare-function lsp-ui--workspace-path "lsp-ui" (path))
+
+(provide 'lsp-ui-flycheck)
+;;; lsp-ui-flycheck.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/lsp-ui-20180619.251/lsp-ui-flycheck.elc b/configs/shared/emacs/.emacs.d/elpa/lsp-ui-20180619.251/lsp-ui-flycheck.elc
new file mode 100644
index 0000000000..e34b417648
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/lsp-ui-20180619.251/lsp-ui-flycheck.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/lsp-ui-20180619.251/lsp-ui-imenu.el b/configs/shared/emacs/.emacs.d/elpa/lsp-ui-20180619.251/lsp-ui-imenu.el
new file mode 100644
index 0000000000..d7005e878e
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/lsp-ui-20180619.251/lsp-ui-imenu.el
@@ -0,0 +1,241 @@
+;;; lsp-ui-imenu.el --- Lsp-Ui-Imenu  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2018 Sebastien Chapuis
+
+;; Author: Sebastien Chapuis <sebastien@chapu.is>
+;; URL: https://github.com/emacs-lsp/lsp-ui
+;; Keywords: lsp, ui
+
+;;; License
+;;
+;; This program 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, or (at your option)
+;; any later version.
+
+;; This program 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 this program; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+;; Floor, Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+;;
+;; Show imenu entries
+;; Call the function `lsp-ui-imenu'
+;;
+;; (define-key lsp-ui-mode-map (kbd "C-c l") 'lsp-ui-imenu)
+;;
+
+;;; Code:
+
+(require 'lsp-mode)
+(require 'lsp-imenu)
+(require 'dash)
+
+(defgroup lsp-ui-imenu nil
+  "Display imenu entries."
+  :group 'tools
+  :group 'convenience
+  :group 'lsp-ui
+  :link '(custom-manual "(lsp-ui-imenu) Top")
+  :link '(info-link "(lsp-ui-imenu) Customizing"))
+
+(defcustom lsp-ui-imenu-enable t
+  "Whether or not to enable ‘lsp-ui-imenu’."
+  :type 'boolean
+  :group 'lsp-ui)
+
+(defcustom lsp-ui-imenu-kind-position 'top
+  "Where to show the entries kind."
+  :type '(choice (const :tag "Top" top)
+                 (const :tag "Left" left))
+  :group 'lsp-ui-imenu)
+
+(defcustom lsp-ui-imenu-colors '("deep sky blue" "green3")
+  "Color list to cycle through for entry groups."
+  :type '(repeat color)
+  :group 'lsp-ui-menu)
+
+(declare-function imenu--make-index-alist 'imenu)
+(declare-function imenu--subalist-p 'imenu)
+(defvar imenu--index-alist)
+
+(defun lsp-ui-imenu--pad (s len color &optional no-bar)
+  (let ((n (- len (length s))))
+    (propertize (concat (make-string n ?\s) s (unless no-bar " ┃ "))
+                'face `(:foreground ,color))))
+
+(defun lsp-ui-imenu--get-color (index)
+  (nth (mod index (length lsp-ui-imenu-colors)) lsp-ui-imenu-colors))
+
+(defun lsp-ui-imenu--make-line (title index padding entry color-index)
+  (let* ((color (lsp-ui-imenu--get-color color-index))
+         (prefix (if (and (= index 0) (eq lsp-ui-imenu-kind-position 'left)) title " "))
+         (text (concat (lsp-ui-imenu--pad prefix padding color)
+                       (propertize (car entry) 'face 'default)
+                       "\n"))
+         (len (length text)))
+    (add-text-properties 0 len `(index ,index title ,title marker ,(cdr entry) padding ,padding) text)
+    text))
+
+(defvar-local lsp-ui-imenu-ov nil)
+
+(defun lsp-ui-imenu--make-ov nil
+  (or (and (overlayp lsp-ui-imenu-ov) lsp-ui-imenu-ov)
+      (setq lsp-ui-imenu-ov (make-overlay 1 1))))
+
+(defun lsp-ui-imenu--post-command nil
+  (when (eobp)
+    (forward-line -1))
+  (-when-let (padding (get-char-property (point) 'padding))
+    (goto-char (+ 3 (line-beginning-position) padding)))
+  (when (eq lsp-ui-imenu-kind-position 'left)
+    (save-excursion
+      (when (overlayp lsp-ui-imenu-ov)
+        (overlay-put lsp-ui-imenu-ov 'display nil))
+      (redisplay)
+      (goto-char (window-start))
+      (if (not (= (get-text-property (point) 'index) 0))
+          (let* ((ov (lsp-ui-imenu--make-ov))
+                 (padding (get-text-property (point) 'padding))
+                 (title (get-text-property (point) 'title))
+                 (text (buffer-substring (+ (line-beginning-position) padding) (line-end-position))))
+            (move-overlay ov (line-beginning-position) (line-end-position))
+            (overlay-put ov 'display `(string ,(concat (let ((n (- padding (length title))))
+                                                         (propertize (concat (make-string n ?\s) title)))
+                                                       text))))
+        (when (overlayp lsp-ui-imenu-ov)
+          (delete-overlay lsp-ui-imenu-ov))))))
+
+(defvar lsp-ui-imenu--origin nil)
+
+(defun lsp-ui-imenu--put-separator nil
+  (let ((ov (make-overlay (point) (point))))
+    (overlay-put ov 'after-string (propertize "\n" 'face '(:height 0.6)))))
+
+(defun lsp-ui-imenu--put-kind (title padding color-index)
+  (when (eq lsp-ui-imenu-kind-position 'top)
+    (let ((ov (make-overlay (point) (point)))
+          (color (lsp-ui-imenu--get-color color-index)))
+      (overlay-put
+       ov 'after-string
+       (concat (lsp-ui-imenu--pad " " padding color t)
+               "\n"
+               title
+               (propertize "\n" 'face '(:height 1)))))))
+
+(defun lsp-ui-imenu nil
+  (interactive)
+  (setq lsp-ui-imenu--origin (current-buffer))
+  (imenu--make-index-alist)
+  (let ((list imenu--index-alist))
+    (with-current-buffer (get-buffer-create "*lsp-ui-imenu*")
+      (let* ((padding (or (and (eq lsp-ui-imenu-kind-position 'top) 1)
+                          (--> (-filter 'imenu--subalist-p list)
+                               (--map (length (car it)) it)
+                               (-max (or it '(1))))))
+             (grouped-by-subs (-partition-by 'imenu--subalist-p list))
+             (color-index 0)
+             buffer-read-only)
+        (remove-overlays)
+        (erase-buffer)
+        (lsp-ui-imenu--put-separator)
+        (dolist (group grouped-by-subs)
+          (if (imenu--subalist-p (car group))
+              (dolist (kind group)
+                (-let* (((title . entries) kind))
+                  (lsp-ui-imenu--put-kind title padding color-index)
+                  (--each-indexed entries
+                    (insert (lsp-ui-imenu--make-line title it-index padding it color-index)))
+                  (lsp-ui-imenu--put-separator)
+                  (setq color-index (1+ color-index))))
+            (--each-indexed group
+              (insert (lsp-ui-imenu--make-line " " it-index padding it color-index)))
+            (lsp-ui-imenu--put-separator)
+            (setq color-index (1+ color-index))))
+        (lsp-ui-imenu-mode)
+        (setq mode-line-format '(:eval (lsp-ui-imenu--win-separator)))
+        (goto-char 1)
+        (add-hook 'post-command-hook 'lsp-ui-imenu--post-command nil t)
+        ))
+    (let ((win (display-buffer-in-side-window (get-buffer "*lsp-ui-imenu*") '((side . right))))
+          (fit-window-to-buffer-horizontally t))
+      (set-window-margins win 1)
+      (select-window win)
+      (set-window-start win 1)
+      (set-window-dedicated-p win t)
+      (let ((fit-window-to-buffer-horizontally 'only))
+        (fit-window-to-buffer win))
+      (window-resize win 3 t))))
+
+(defun lsp-ui-imenu--win-separator ()
+  (when (and (window-combined-p)
+             (window-next-sibling)
+             (= (window-bottom-divider-width) 0))
+    (propertize (make-string (window-total-width) ?\─) 'face 'window-divider)))
+
+(defun lsp-ui-imenu--kill nil
+  (interactive)
+  (kill-buffer-and-window))
+
+(defun lsp-ui-imenu--jump (direction)
+  (let ((current (get-text-property (point) 'title)))
+    (forward-line direction)
+    (while (and current
+                (not (= (line-number-at-pos) 1))
+                (equal current (get-text-property (point) 'title)))
+      (forward-line direction))))
+
+(defun lsp-ui-imenu--next-kind nil
+  (interactive)
+  (lsp-ui-imenu--jump 1))
+
+(defun lsp-ui-imenu--prev-kind nil
+  (interactive)
+  (lsp-ui-imenu--jump -1)
+  (while (not (= (get-text-property (point) 'index) 0))
+    (forward-line -1)))
+
+(defun lsp-ui-imenu--visit nil
+  (interactive)
+  (let ((marker (get-text-property (point) 'marker)))
+    (select-window (get-buffer-window lsp-ui-imenu--origin))
+    (goto-char marker)
+    (pulse-momentary-highlight-one-line (point) 'next-error)))
+
+(defun lsp-ui-imenu--view nil
+  (interactive)
+  (let ((marker (get-text-property (point) 'marker)))
+    (with-selected-window (get-buffer-window lsp-ui-imenu--origin)
+      (goto-char marker)
+      (recenter)
+      (pulse-momentary-highlight-one-line (point) 'next-error))))
+
+(defvar lsp-ui-imenu-mode-map nil
+  "Keymap for ‘lsp-ui-peek-mode’.")
+(unless lsp-ui-imenu-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "q") 'lsp-ui-imenu--kill)
+    (define-key map (kbd "<right>") 'lsp-ui-imenu--next-kind)
+    (define-key map (kbd "<left>") 'lsp-ui-imenu--prev-kind)
+    (define-key map (kbd "<return>") 'lsp-ui-imenu--view)
+    (define-key map (kbd "<M-return>") 'lsp-ui-imenu--visit)
+    (setq lsp-ui-imenu-mode-map map)))
+
+(define-derived-mode lsp-ui-imenu-mode special-mode "lsp-ui-imenu"
+  "Mode showing imenu entries.")
+
+(defun lsp-ui-imenu-enable (enable)
+  (if enable
+      (lsp-enable-imenu)
+    (when (eq imenu-create-index-function 'lsp--imenu-create-index)
+      (setq imenu-create-index-function
+            'imenu-default-create-index-function))))
+
+(provide 'lsp-ui-imenu)
+;;; lsp-ui-imenu.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/lsp-ui-20180619.251/lsp-ui-imenu.elc b/configs/shared/emacs/.emacs.d/elpa/lsp-ui-20180619.251/lsp-ui-imenu.elc
new file mode 100644
index 0000000000..d351a80ddf
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/lsp-ui-20180619.251/lsp-ui-imenu.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/lsp-ui-20180619.251/lsp-ui-peek.el b/configs/shared/emacs/.emacs.d/elpa/lsp-ui-20180619.251/lsp-ui-peek.el
new file mode 100644
index 0000000000..f9823b8d0f
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/lsp-ui-20180619.251/lsp-ui-peek.el
@@ -0,0 +1,731 @@
+;;; lsp-ui-peek.el --- Lsp-Ui-Peek  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 Sebastien Chapuis
+
+;; Author: Sebastien Chapuis <sebastien@chapu.is>
+;; URL: https://github.com/emacs-lsp/lsp-ui
+;; Keywords: lsp, ui
+;; Version: 0.0.1
+
+;;; License
+;;
+;; This program 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, or (at your option)
+;; any later version.
+
+;; This program 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 this program; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+;; Floor, Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+;;
+;; Load this file and execute `lsp-ui-peek-find-references'
+;; on a symbol to find its references
+;; or `lsp-ui-peek-find-definitions'.
+;; Type 'q' to close the window.
+;;
+
+;;; Code:
+
+(require 'lsp-mode)
+(require 'xref)
+(require 'dash)
+
+(defgroup lsp-ui-peek nil
+  "Improve version of xref with peek feature."
+  :group 'tools
+  :group 'convenience
+  :group 'lsp-ui
+  :link '(custom-manual "(lsp-ui-peek) Top")
+  :link '(info-link "(lsp-ui-peek) Customizing"))
+
+(defcustom lsp-ui-peek-enable t
+  "Whether or not to enable ‘lsp-ui-peek’."
+  :type 'boolean
+  :group 'lsp-ui)
+
+(defcustom lsp-ui-peek-peek-height 20
+  "Height of the peek code."
+  :type 'integer
+  :group 'lsp-ui-peek)
+
+(defcustom lsp-ui-peek-list-width 50
+  "Width of the right panel."
+  :type 'integer
+  :group 'lsp-ui-peek)
+
+(defcustom lsp-ui-peek-fontify 'on-demand
+  "Whether to fontify chunks of code (use semantics colors).
+WARNING: 'always can heavily slow the processing when `lsp-ui-peek-expand-function'
+expands more than 1 file.  It is recommended to keeps the default value of
+`lsp-ui-peek-expand-function' when this variable is 'always."
+  :type '(choice (const :tag "Never" never)
+                 (const :tag "On demand" on-demand)
+                 (const :tag "Always" always))
+  :group 'lsp-ui-peek)
+
+(defcustom lsp-ui-peek-always-show nil
+  "Show the peek view even if there is only 1 cross reference.
+By default, the peek view isn't shown if there is 1 xref."
+  :type 'boolean
+  :group 'lsp-ui-peek)
+
+(defface lsp-ui-peek-peek
+  '((((background light)) :background "light gray")
+    (t :background "#031A25"))
+  "Face used for the peek."
+  :group 'lsp-ui-peek)
+
+(defface lsp-ui-peek-list
+  '((((background light)) :background "light gray")
+    (t :background "#181818"))
+  "Face used to list references."
+  :group 'lsp-ui-peek)
+
+(defface lsp-ui-peek-filename
+  '((((background light)) :foreground "red")
+    (t :foreground "dark orange"))
+  "Face used for the filename's reference in the list."
+  :group 'lsp-ui-peek)
+
+(defface lsp-ui-peek-line-number
+  '((t :foreground "grey25"))
+  "Line number face."
+  :group 'lsp-ui-peek)
+
+(defface lsp-ui-peek-highlight
+  '((((background light)) :background "dim gray"
+     :foreground "white"
+     :distant-foreground "black")
+    (t :background "white"
+       :foreground "black"
+       :distant-foreground "white"
+       :box (:line-width -1 :color "white")))
+  "Face used to highlight the reference/definition.
+Do not use box, underline or overline prop.  If you want to use
+box, use a negative value for its width.  Those properties deform
+the whole overlay."
+  :group 'lsp-ui-peek)
+
+(defface lsp-ui-peek-header
+  '((((background light)) :background "grey30" :foreground "white")
+    (t :background "white" :foreground "black"))
+  "Face used for the headers."
+  :group 'lsp-ui-peek)
+
+(defface lsp-ui-peek-footer
+  '((t :inherit lsp-ui-peek-header))
+  "Face used for the footers.  Only the background of this face is used."
+  :group 'lsp-ui-peek)
+
+(defface lsp-ui-peek-selection
+  '((((background light)) :background "grey30" :foreground "white")
+    (t :background "white" :foreground "black"))
+  "Face used for the current selection.
+Do not use box, underline or overline prop.  If you want to use
+box, use a negative value for its width.  Those properties
+deform the whole overlay."
+  :group 'lsp-ui-peek)
+
+(defvar lsp-ui-peek-expand-function 'lsp-ui-peek--expand-buffer
+  "A function used to determinate which file(s) to expand in the list of xrefs.
+The function takes one parameter: a list of cons where the car is the
+filename and the cdr is the number of references in that file.
+It should returns a list of filenames to expand.
+WARNING: If you change this variable and expand more than 1 file, it is
+recommended to set `lsp-ui-peek-fontify' to 'never or 'on-demand, otherwise it
+will cause performances issues.")
+
+(defvar-local lsp-ui-peek--overlay nil)
+(defvar-local lsp-ui-peek--list nil)
+(defvar-local lsp-ui-peek--last-xref nil)
+(defvar-local lsp-ui-peek--selection 0)
+(defvar-local lsp-ui-peek--offset 0)
+(defvar-local lsp-ui-peek--size-list 0)
+(defvar-local lsp-ui-peek--win-start nil)
+(defvar-local lsp-ui-peek--kind nil)
+(defvar-local lsp-ui-peek--deactivate-keymap-fn nil)
+
+(defvar lsp-ui-peek--jumps (make-hash-table)
+  "Hashtable which stores all jumps on a per window basis.")
+
+(defvar evil--jumps-window-jumps)  ; defined in evil-jumps.el
+
+(defmacro lsp-ui-peek--with-evil-jumps (&rest body)
+  "Make `evil-jumps.el' commands work on `lsp-ui-peek--jumps'."
+  (declare (indent 1))
+  `(let ((evil--jumps-window-jumps lsp-ui-peek--jumps))
+     ,@body))
+
+(with-eval-after-load 'evil-jumps
+  ;; We need to jump through some hoops to prevent the byte-compiler from
+  ;; compiling this code.  We can’t compile the code without requiring
+  ;; ‘evil-macros’.
+  (eval '(progn
+          (evil-define-motion lsp-ui-peek-jump-backward (count)
+            (lsp-ui-peek--with-evil-jumps
+             (evil--jump-backward count)
+             (run-hooks 'xref-after-return-hook)))
+          (evil-define-motion lsp-ui-peek-jump-forward (count)
+            (lsp-ui-peek--with-evil-jumps
+             (evil--jump-forward count)
+             (run-hooks 'xref-after-return-hook))))
+        t))
+
+(defmacro lsp-ui-peek--prop (prop &optional string)
+  `(get-text-property 0 ,prop (or ,string (lsp-ui-peek--get-text-selection) "")))
+
+(defmacro lsp-ui-peek--add-prop (prop &optional string)
+  `(let ((obj (or ,string (lsp-ui-peek--get-text-selection))))
+     (add-text-properties 0 (length obj) ,prop obj)
+     obj))
+
+(defun lsp-ui-peek--truncate (len s)
+  (if (> (string-width s) len)
+      (format "%s.." (substring s 0 (- len 2)))
+    s))
+
+(defun lsp-ui-peek--get-text-selection (&optional n)
+  (nth (or n lsp-ui-peek--selection)
+       (--remove (get-text-property 0 'lsp-ui-peek-hidden it) lsp-ui-peek--list)))
+
+(defun lsp-ui-peek--get-selection ()
+  (get-text-property 0 'lsp-ui-peek (or (lsp-ui-peek--get-text-selection) "")))
+
+(defun lsp-ui-peek--visual-index ()
+  (- lsp-ui-peek--selection lsp-ui-peek--offset))
+
+(defun lsp-ui-peek--make-line (index src)
+  (-let* (((s1 . s2) src)
+          (len-s1 (length s1))
+          (len-s2 (length s2))
+          (on-selection (= (1+ (lsp-ui-peek--visual-index)) index))
+          (face-left (if (= index 0) 'lsp-ui-peek-header 'lsp-ui-peek-peek))
+          (face-right (cond (on-selection 'lsp-ui-peek-selection)
+                            ((= index 0) 'lsp-ui-peek-header)
+                            (t 'lsp-ui-peek-list))))
+    (when on-selection
+      (setq s2 (copy-sequence s2))
+      (add-face-text-property 0 len-s2 face-right nil s2))
+    (unless (get-text-property 0 'lsp-ui-peek-faced s2)
+      (add-face-text-property 0 len-s2 face-right t s2)
+      (add-text-properties 0 len-s2 '(lsp-ui-peek-faced t) s2)
+      (add-face-text-property 0 len-s2 'default t s2))
+    (add-face-text-property 0 len-s1 face-left t s1)
+    (add-face-text-property 0 len-s1 'default t s1)
+    (concat
+     s1
+     (propertize "_" 'face face-left 'display `(space :align-to (- right-fringe ,(1+ lsp-ui-peek-list-width))))
+     " "
+     s2
+     (propertize "_" 'face face-right 'display `(space :align-to (- right-fringe 1)))
+     (propertize "\n" 'face face-right))))
+
+(defun lsp-ui-peek--adjust (width strings)
+  (-let* (((s1 . s2) strings))
+    (cons (lsp-ui-peek--truncate (- width (1+ lsp-ui-peek-list-width)) s1)
+          (lsp-ui-peek--truncate (- lsp-ui-peek-list-width 2) s2))))
+
+(defun lsp-ui-peek--make-footer ()
+  ;; Character-only terminals don't support characters of different height
+  (when (display-graphic-p)
+    (list
+     (concat
+      (propertize " "
+                  'face `(:background ,(face-background 'lsp-ui-peek-footer nil t) :height 1)
+                  'display `(space :align-to (- right-fringe ,(1+ lsp-ui-peek-list-width))))
+      (propertize " " 'face '(:height 1)
+                  'display `(space :align-to (- right-fringe ,lsp-ui-peek-list-width)))
+      (propertize " "
+                  'face `(:background ,(face-background 'lsp-ui-peek-footer nil t) :height 1)
+                  'display `(space :align-to (- right-fringe 0)))
+      (propertize "\n" 'face '(:height 1))
+      (propertize "\n" 'face '(:height 0.5))))))
+
+(defun lsp-ui-peek--peek-new (src1 src2)
+  (-let* ((win-width (window-text-width))
+          (string (-some--> (-zip-fill "" src1 src2)
+                            (--map (lsp-ui-peek--adjust win-width it) it)
+                            (-map-indexed 'lsp-ui-peek--make-line it)
+                            (-concat it (lsp-ui-peek--make-footer))))
+          (next-line (line-beginning-position 2))
+          (ov (or (when (overlayp lsp-ui-peek--overlay) lsp-ui-peek--overlay)
+                  (make-overlay next-line next-line))))
+    (setq lsp-ui-peek--overlay ov)
+    (overlay-put ov 'after-string (mapconcat 'identity string ""))
+    (overlay-put ov 'display-line-numbers-disable t)
+    (overlay-put ov 'window (get-buffer-window))))
+
+(defun lsp-ui-peek--expand-buffer (files)
+  (if (--any? (equal (car it) buffer-file-name) files)
+      (list buffer-file-name)
+    (list (caar files))))
+
+(defun lsp-ui-peek--expand (xrefs)
+  (let* ((to-expand (->> (--map (cons (plist-get it :file) (plist-get it :count)) xrefs)
+                         (funcall lsp-ui-peek-expand-function)))
+         first)
+    (while (nth lsp-ui-peek--selection lsp-ui-peek--list)
+      (when (and (lsp-ui-peek--prop 'xrefs)
+                 (member (lsp-ui-peek--prop 'file) to-expand))
+        (unless first
+          (setq first (1+ lsp-ui-peek--selection)))
+        (lsp-ui-peek--toggle-file t))
+      (setq lsp-ui-peek--selection (1+ lsp-ui-peek--selection)))
+    (setq lsp-ui-peek--selection (or first 0))
+    (lsp-ui-peek--recenter)))
+
+(defun lsp-ui-peek--show (xrefs)
+  "Create a window to list references/defintions.
+XREFS is a list of references/definitions."
+  (setq lsp-ui-peek--win-start (window-start)
+        lsp-ui-peek--selection 0
+        lsp-ui-peek--offset 0
+        lsp-ui-peek--size-list 0
+        lsp-ui-peek--list nil)
+  (when (eq (logand lsp-ui-peek-peek-height 1) 1)
+    (setq lsp-ui-peek-peek-height (1+ lsp-ui-peek-peek-height)))
+  (when (< (- (line-number-at-pos (window-end)) (line-number-at-pos))
+           (+ lsp-ui-peek-peek-height 3))
+    (recenter 15))
+  (setq xrefs (--sort (string< (plist-get it :file) (plist-get other :file)) xrefs))
+  (--each xrefs
+    (-let* (((&plist :file filename :xrefs xrefs :count count) it)
+            (len-str (number-to-string count)))
+      (setq lsp-ui-peek--size-list (+ lsp-ui-peek--size-list count))
+      (push (concat (propertize (lsp-ui--workspace-path filename)
+                                'face 'lsp-ui-peek-filename
+                                'file filename
+                                'xrefs xrefs)
+                    (propertize " " 'display `(space :align-to (- right-fringe ,(1+ (length len-str)))))
+                    (propertize len-str 'face 'lsp-ui-peek-filename))
+            lsp-ui-peek--list)))
+  (setq lsp-ui-peek--list (nreverse lsp-ui-peek--list))
+  (lsp-ui-peek--expand xrefs)
+  (lsp-ui-peek--peek))
+
+(defun lsp-ui-peek--recenter ()
+  (let ((half-height (/ lsp-ui-peek-peek-height 2)))
+    (when (> lsp-ui-peek--selection half-height)
+      (setq lsp-ui-peek--offset (- lsp-ui-peek--selection (1- half-height))))))
+
+(defun lsp-ui-peek--fill (min-len list)
+  (let ((len (length list)))
+    (if (< len min-len)
+        (append list (-repeat (- min-len len) ""))
+      list)))
+
+(defun lsp-ui-peek--render (major string)
+  (with-temp-buffer
+    (insert string)
+    (delay-mode-hooks
+      (let ((inhibit-message t))
+        (funcall major))
+      (ignore-errors
+        (font-lock-ensure)))
+    (buffer-string)))
+
+(defun lsp-ui-peek--peek ()
+  "Show reference's chunk of code."
+  (-let* ((xref (lsp-ui-peek--get-selection))
+          ((&plist :file file :chunk chunk) (or xref lsp-ui-peek--last-xref))
+          (header (concat " " (lsp-ui--workspace-path file) "\n"))
+          (header2 (format " %s %s" lsp-ui-peek--size-list (symbol-name lsp-ui-peek--kind)))
+          (ref-view (--> chunk
+                         (if (eq lsp-ui-peek-fontify 'on-demand)
+                             (lsp-ui-peek--render major-mode it)
+                           chunk)
+                         (subst-char-in-string ?\t ?\s it)
+                         (concat header it)
+                         (split-string it "\n")))
+          (list-refs (->> lsp-ui-peek--list
+                          (--remove (lsp-ui-peek--prop 'lsp-ui-peek-hidden it))
+                          (-drop lsp-ui-peek--offset)
+                          (-take (1- lsp-ui-peek-peek-height))
+                          (lsp-ui-peek--fill (1- lsp-ui-peek-peek-height))
+                          (-concat (list header2)))))
+    (setq lsp-ui-peek--last-xref (or xref lsp-ui-peek--last-xref))
+    (lsp-ui-peek--peek-new ref-view list-refs)))
+
+(defun lsp-ui-peek--toggle-text-prop (s)
+  (let ((state (lsp-ui-peek--prop 'lsp-ui-peek-hidden s)))
+    (lsp-ui-peek--add-prop `(lsp-ui-peek-hidden ,(not state)) s)))
+
+(defun lsp-ui-peek--toggle-hidden (file)
+  (setq lsp-ui-peek--list
+        (--map-when (string= (plist-get (lsp-ui-peek--prop 'lsp-ui-peek it) :file) file)
+                    (prog1 it (lsp-ui-peek--toggle-text-prop it))
+                    lsp-ui-peek--list)))
+
+(defun lsp-ui-peek--remove-hidden (file)
+  (setq lsp-ui-peek--list
+        (--map-when (string= (plist-get (lsp-ui-peek--prop 'lsp-ui-peek it) :file) file)
+                    (prog1 it (lsp-ui-peek--add-prop '(lsp-ui-peek-hidden nil) it))
+                    lsp-ui-peek--list)))
+
+(defun lsp-ui-peek--make-ref-line (xref)
+  (-let* (((&plist :summary summary :line line :file file) xref)
+          (string (format "%-3s %s"
+                          (propertize (number-to-string (1+ line))
+                                      'face 'lsp-ui-peek-line-number)
+                          (string-trim summary))))
+    (lsp-ui-peek--add-prop `(lsp-ui-peek ,xref file ,file) string)))
+
+(defun lsp-ui-peek--insert-xrefs (xrefs filename index)
+  (setq lsp-ui-peek--list (--> (lsp-ui-peek--get-xrefs-in-file (cons filename xrefs))
+                               (-map 'lsp-ui-peek--make-ref-line it)
+                               (-insert-at (1+ index) it lsp-ui-peek--list)
+                               (-flatten it)))
+  (lsp-ui-peek--add-prop '(xrefs nil)))
+
+(defun lsp-ui-peek--toggle-file (&optional no-update)
+  (interactive)
+  (-if-let* ((xrefs (lsp-ui-peek--prop 'xrefs))
+             (filename (lsp-ui-peek--prop 'file))
+             (index (--find-index (equal (lsp-ui-peek--prop 'file it) filename)
+                                  lsp-ui-peek--list)))
+      (lsp-ui-peek--insert-xrefs xrefs filename index)
+    (let ((file (lsp-ui-peek--prop 'file)))
+      (lsp-ui-peek--toggle-hidden file)
+      (while (not (equal file (lsp-ui-peek--prop 'file)))
+        (lsp-ui-peek--select-prev t))))
+  (unless no-update
+    (lsp-ui-peek--peek)))
+
+(defun lsp-ui-peek--select (index)
+  (setq lsp-ui-peek--selection (+ lsp-ui-peek--selection index)))
+
+(defun lsp-ui-peek--select-next (&optional no-update)
+  (interactive)
+  (when (lsp-ui-peek--get-text-selection (1+ lsp-ui-peek--selection))
+    (lsp-ui-peek--select 1)
+    (while (> (lsp-ui-peek--visual-index) (- lsp-ui-peek-peek-height 2))
+      (setq lsp-ui-peek--offset (1+ lsp-ui-peek--offset)))
+    (unless no-update
+      (lsp-ui-peek--peek))))
+
+(defun lsp-ui-peek--select-prev (&optional no-update)
+  (interactive)
+  (when (> lsp-ui-peek--selection 0)
+    (lsp-ui-peek--select -1)
+    (while (< (lsp-ui-peek--visual-index) 0)
+      (setq lsp-ui-peek--offset (1- lsp-ui-peek--offset))))
+  (unless no-update
+    (lsp-ui-peek--peek)))
+
+(defun lsp-ui-peek--skip-refs (fn)
+  (let ((last-file (lsp-ui-peek--prop 'file))
+        last-selection)
+    (when (lsp-ui-peek--get-selection)
+      (while (and (equal (lsp-ui-peek--prop 'file) last-file)
+                  (not (equal last-selection lsp-ui-peek--selection)))
+        (setq last-selection lsp-ui-peek--selection)
+        (funcall fn t)))))
+
+(defun lsp-ui-peek--select-prev-file ()
+  (interactive)
+  (if (not (lsp-ui-peek--get-selection))
+      (lsp-ui-peek--select-prev)
+    (lsp-ui-peek--skip-refs 'lsp-ui-peek--select-prev)
+    (when (lsp-ui-peek--get-selection)
+      (lsp-ui-peek--skip-refs 'lsp-ui-peek--select-prev)
+      (unless (= lsp-ui-peek--selection 0)
+        (lsp-ui-peek--select-next t))))
+  (if (lsp-ui-peek--prop 'xrefs)
+      (lsp-ui-peek--toggle-file)
+    (lsp-ui-peek--remove-hidden (lsp-ui-peek--prop 'file)))
+  (lsp-ui-peek--select-next t)
+  (lsp-ui-peek--recenter)
+  (lsp-ui-peek--peek))
+
+(defun lsp-ui-peek--select-next-file ()
+  (interactive)
+  (lsp-ui-peek--skip-refs 'lsp-ui-peek--select-next)
+  (if (lsp-ui-peek--prop 'xrefs)
+      (lsp-ui-peek--toggle-file)
+    (lsp-ui-peek--remove-hidden (lsp-ui-peek--prop 'file)))
+  (lsp-ui-peek--select-next t)
+  (lsp-ui-peek--recenter)
+  (lsp-ui-peek--peek))
+
+(defun lsp-ui-peek--peek-hide ()
+  "Hide the chunk of code and restore previous state."
+  (when (overlayp lsp-ui-peek--overlay)
+    (delete-overlay lsp-ui-peek--overlay))
+  (setq lsp-ui-peek--overlay nil
+        lsp-ui-peek--last-xref nil)
+  (set-window-start (get-buffer-window) lsp-ui-peek--win-start))
+
+(defun lsp-ui-peek--deactivate-keymap ()
+  "Deactivate keymap."
+  (-when-let (fn lsp-ui-peek--deactivate-keymap-fn)
+    (setq lsp-ui-peek--deactivate-keymap-fn nil)
+    (funcall fn)))
+
+(defun lsp-ui-peek--goto-xref (&optional x other-window)
+  "Go to a reference/definition."
+  (interactive)
+  (-if-let (xref (or x (lsp-ui-peek--get-selection)))
+      (-let (((&plist :file file :line line :column column) xref)
+             (buffer (current-buffer)))
+        (if (not (file-readable-p file))
+            (user-error "File not readable: %s" file)
+          (setq lsp-ui-peek--win-start nil)
+          (lsp-ui-peek--abort)
+          (let ((marker (with-current-buffer
+                            (or (get-file-buffer file)
+                                (find-file-noselect file))
+                          (save-restriction
+                            (widen)
+                            (save-excursion
+                              ;; When we jump to a file with line/column unspecified,
+                              ;; we do not want to move the point if the buffer exists.
+                              ;; We interpret line=column=0 differently here.
+                              (when (> (+ line column) 0)
+                                (goto-char 1)
+                                (forward-line line)
+                                (forward-char column))
+                              (point-marker)))))
+                (current-workspace lsp--cur-workspace))
+            (if other-window
+                (pop-to-buffer (marker-buffer marker) t)
+              (switch-to-buffer (marker-buffer marker)))
+            (with-current-buffer buffer
+              (lsp-ui-peek-mode -1))
+            (unless lsp--cur-workspace
+              (setq lsp--cur-workspace current-workspace))
+            (unless lsp-mode
+              (lsp-mode 1)
+              (lsp-on-open))
+            (goto-char marker)
+            (run-hooks 'xref-after-jump-hook))))
+    (lsp-ui-peek--toggle-file)))
+
+(defun lsp-ui-peek--goto-xref-other-window ()
+  (interactive)
+  (lsp-ui-peek--goto-xref nil t))
+
+(defvar lsp-ui-peek-mode-map nil
+  "Keymap for ‘lsp-ui-peek-mode’.")
+(unless lsp-ui-peek-mode-map
+  (let ((map (make-sparse-keymap)))
+    (suppress-keymap map t)
+    (define-key map "\e\e\e" 'lsp-ui-peek--abort)
+    (define-key map "\C-g" 'lsp-ui-peek--abort)
+    (define-key map (kbd "M-n") 'lsp-ui-peek--select-next-file)
+    (define-key map (kbd "<right>") 'lsp-ui-peek--select-next-file)
+    (define-key map (kbd "M-p") 'lsp-ui-peek--select-prev-file)
+    (define-key map (kbd "<left>") 'lsp-ui-peek--select-prev-file)
+    (define-key map (kbd "C-n") 'lsp-ui-peek--select-next)
+    (define-key map (kbd "n") 'lsp-ui-peek--select-next)
+    (define-key map (kbd "<down>") 'lsp-ui-peek--select-next)
+    (define-key map (kbd "C-p") 'lsp-ui-peek--select-prev)
+    (define-key map (kbd "p") 'lsp-ui-peek--select-prev)
+    (define-key map (kbd "<up>") 'lsp-ui-peek--select-prev)
+    (define-key map (kbd "TAB") 'lsp-ui-peek--toggle-file)
+    (define-key map (kbd "q") 'lsp-ui-peek--abort)
+    (define-key map (kbd "RET") 'lsp-ui-peek--goto-xref)
+    (define-key map (kbd "M-RET") 'lsp-ui-peek--goto-xref-other-window)
+    (setq lsp-ui-peek-mode-map map)))
+
+(defun lsp-ui-peek--disable ()
+  "Do not call this function, call `lsp-ui-peek--abort' instead."
+  (when (bound-and-true-p lsp-ui-peek-mode)
+    (lsp-ui-peek-mode -1)
+    (lsp-ui-peek--peek-hide)))
+
+(defun lsp-ui-peek--abort ()
+  (interactive)
+  ;; The timer fixes https://github.com/emacs-lsp/lsp-ui/issues/33
+  (run-with-idle-timer 0 nil 'lsp-ui-peek--disable))
+
+(define-minor-mode lsp-ui-peek-mode
+  "Mode for lsp-ui-peek."
+  :init-value nil
+  (if lsp-ui-peek-mode
+      (setq lsp-ui-peek--deactivate-keymap-fn (set-transient-map lsp-ui-peek-mode-map t 'lsp-ui-peek--abort))
+    (lsp-ui-peek--deactivate-keymap)
+    (lsp-ui-peek--peek-hide)))
+
+(defun lsp-ui-peek--find-xrefs (input kind &optional request param)
+  "Find INPUT references.
+KIND is ‘references’, ‘definitions’ or a custom kind."
+  (setq lsp-ui-peek--kind kind)
+  (let ((xrefs (lsp-ui-peek--get-references kind request param)))
+    (unless xrefs
+      (user-error "No %s found for: %s" (symbol-name kind) input))
+    (xref-push-marker-stack)
+    (when (featurep 'evil-jumps)
+      (lsp-ui-peek--with-evil-jumps (evil-set-jump)))
+    (if (and (not lsp-ui-peek-always-show)
+             (not (cdr xrefs))
+             (= (length (plist-get (car xrefs) :xrefs)) 1))
+        (-let* ((xref (car (plist-get (car xrefs) :xrefs)))
+                ((&hash "uri" file "range" range) xref)
+                ((&hash "line" line "character" col) (gethash "start" range))
+                (file (lsp--uri-to-path file)))
+          (lsp-ui-peek--goto-xref `(:file ,file :line ,line :column ,col)))
+      (lsp-ui-peek-mode)
+      (lsp-ui-peek--show xrefs))))
+
+(defun lsp-ui-peek-find-references ()
+  "Find references to the IDENTIFIER at point."
+  (interactive)
+  (lsp-ui-peek--find-xrefs (symbol-at-point)
+                           'references
+                           "textDocument/references"
+                           (lsp--make-reference-params)))
+
+(defun lsp-ui-peek-find-definitions ()
+  "Find definitions to the IDENTIFIER at point."
+  (interactive)
+  (lsp-ui-peek--find-xrefs (symbol-at-point)
+                           'definitions
+                           "textDocument/definition"))
+
+(defun lsp-ui-peek-find-implementation ()
+  "Find implementation locations of the symbol at point."
+  (interactive)
+  (lsp-ui-peek--find-xrefs (symbol-at-point)
+                           'implementation
+                           "textDocument/implementation"))
+
+(defun lsp-ui-peek-find-workspace-symbol (pattern)
+  "Find symbols in the worskpace.
+The symbols are found matching PATTERN."
+  (interactive (list (read-string "workspace/symbol: "
+                                  nil 'xref--read-pattern-history)))
+  (lsp-ui-peek--find-xrefs pattern
+                           'symbols
+                           "workspace/symbol"
+                           (list :query pattern)))
+
+(defun lsp-ui-peek-find-custom (kind request &optional param)
+  "Find custom references.
+KIND is a symbol to name the references (definition, reference, ..).
+REQUEST is the method string to send the the language server.
+PARAM is the method parameter.  If nil, it default to TextDocumentPositionParams."
+  (lsp-ui-peek--find-xrefs (symbol-at-point) kind request param))
+
+(defun lsp-ui-peek--extract-chunk-from-buffer (pos start end)
+  "Return the chunk of code pointed to by POS (a Position object) in the current buffer.
+START and END are delimiters."
+  (let* ((point (lsp--position-to-point pos))
+         (inhibit-field-text-motion t)
+         (line-start (1+ (- 1 (/ lsp-ui-peek-peek-height 2))))
+         (line-end (/ lsp-ui-peek-peek-height 2)))
+    (save-excursion
+      (goto-char point)
+      (let* ((before (buffer-substring (line-beginning-position line-start) (line-beginning-position)))
+             (line (buffer-substring (line-beginning-position) (line-end-position)))
+             (after (buffer-substring (line-end-position) (line-end-position line-end)))
+             (len (length line)))
+        (add-face-text-property (max (min start len) 0)
+                                (max (min end len) 0)
+                                'lsp-ui-peek-highlight t line)
+        `(,line . ,(concat before line after))))))
+
+(defun lsp-ui-peek--xref-make-item (filename location)
+  "Return an item from a LOCATION in FILENAME.
+LOCATION can be either a LSP Location or SymbolInformation."
+  ;; TODO: Read more informations from SymbolInformation.
+  ;;       For now, only the location is used.
+  (-let* ((location (or (gethash "location" location) location))
+          (range (gethash "range" location))
+          ((&hash "start" pos-start "end" pos-end) range)
+          (start (gethash "character" pos-start))
+          (end (gethash "character" pos-end))
+          ((line . chunk) (lsp-ui-peek--extract-chunk-from-buffer pos-start start end)))
+    (list :summary (or line filename)
+          :chunk (or chunk filename)
+          :file filename
+          :line (gethash "line" pos-start)
+          :column start
+          :len (- end start))))
+
+(defun lsp-ui-peek--fontify-buffer (filename)
+  (when (eq lsp-ui-peek-fontify 'always)
+    (unless buffer-file-name
+      (make-local-variable 'delay-mode-hooks)
+      (let ((buffer-file-name filename)
+            (enable-local-variables nil)
+            (inhibit-message t)
+            (delay-mode-hooks t))
+        (set-auto-mode)))
+    (font-lock-ensure)))
+
+(defun lsp-ui-peek--get-xrefs-in-file (file)
+  "Return all references that contain a file.
+FILE is a cons where its car is the filename and the cdr is a list of Locations
+within the file.  We open and/or create the file/buffer only once for all
+references.  The function returns a list of `ls-xref-item'."
+  (let* ((filename (car file))
+         (visiting (find-buffer-visiting filename))
+         (fn (lambda (loc) (lsp-ui-peek--xref-make-item filename loc))))
+    (cond
+     (visiting
+      (with-temp-buffer
+        (insert-buffer-substring-no-properties visiting)
+        (lsp-ui-peek--fontify-buffer filename)
+        (mapcar fn (cdr file))))
+     ((file-readable-p filename)
+      (with-temp-buffer
+        (insert-file-contents-literally filename)
+        (lsp-ui-peek--fontify-buffer filename)
+        (mapcar fn (cdr file))))
+     (t (user-error "Cannot read %s" filename)))))
+
+(defun lsp-ui-peek--get-xrefs-list (file)
+  "Return a list of xrefs in FILE."
+  (-let* (((filename . xrefs) file))
+    `(:file ,filename :xrefs ,xrefs :count ,(length xrefs))))
+
+(defun lsp-ui-peek--locations-to-xref-items (locations)
+  "Return a list of list of item from LOCATIONS.
+LOCATIONS is an array of Location objects:
+
+interface Location {
+	uri: DocumentUri;
+	range: Range;
+}"
+  (-some--> (lambda (loc) (lsp--uri-to-path (gethash "uri" (or (gethash "location" loc) loc))))
+            (seq-group-by it locations)
+            (mapcar #'lsp-ui-peek--get-xrefs-list it)))
+
+(defun lsp-ui-peek--to-sequence (maybe-sequence)
+  "If maybe-sequence is not a sequence, wraps it into a single-element sequence."
+  (if (sequencep maybe-sequence) maybe-sequence (list maybe-sequence)))
+
+(defun lsp-ui-peek--get-references (_kind request &optional param)
+  "Get all references/definitions for the symbol under point.
+Returns item(s)."
+  (-some->> (lsp--send-request (lsp--make-request
+                                request
+                                (or param (lsp--text-document-position-params))))
+            ;; Language servers may return a single LOCATION instead of a sequence of them.
+            (lsp-ui-peek--to-sequence)
+            (lsp-ui-peek--locations-to-xref-items)
+            (-filter 'identity)))
+
+(defvar lsp-ui-mode-map)
+
+(defun lsp-ui-peek-enable (_enable)
+  (interactive)
+  (unless (bound-and-true-p lsp-ui-mode-map)
+    (user-error "Please load lsp-ui before trying to enable lsp-ui-peek")))
+
+;; lsp-ui.el loads lsp-ui-peek.el, so we can’t ‘require’ lsp-ui.
+;; FIXME: Remove this cyclic dependency.
+(declare-function lsp-ui--workspace-path "lsp-ui" (path))
+
+(declare-function evil-set-jump "evil-jumps.el" (&optional pos))
+
+(provide 'lsp-ui-peek)
+;;; lsp-ui-peek.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/lsp-ui-20180619.251/lsp-ui-peek.elc b/configs/shared/emacs/.emacs.d/elpa/lsp-ui-20180619.251/lsp-ui-peek.elc
new file mode 100644
index 0000000000..4a28d35c69
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/lsp-ui-20180619.251/lsp-ui-peek.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/lsp-ui-20180619.251/lsp-ui-pkg.el b/configs/shared/emacs/.emacs.d/elpa/lsp-ui-20180619.251/lsp-ui-pkg.el
new file mode 100644
index 0000000000..dd2e8c8dd0
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/lsp-ui-20180619.251/lsp-ui-pkg.el
@@ -0,0 +1,17 @@
+(define-package "lsp-ui" "20180619.251" "UI modules for lsp-mode"
+  '((emacs "25.1")
+    (dash "2.13")
+    (dash-functional "1.2.0")
+    (flycheck "31")
+    (lsp-mode "4.0")
+    (markdown-mode "2.3"))
+  :keywords
+  '("lsp")
+  :authors
+  '(("Tobias Pisani" . "topisani@hamsterpoison.com"))
+  :maintainer
+  '("Tobias Pisani" . "topisani@hamsterpoison.com")
+  :url "https://github.com/emacs-lsp/lsp-ui")
+;; Local Variables:
+;; no-byte-compile: t
+;; End:
diff --git a/configs/shared/emacs/.emacs.d/elpa/lsp-ui-20180619.251/lsp-ui-sideline.el b/configs/shared/emacs/.emacs.d/elpa/lsp-ui-20180619.251/lsp-ui-sideline.el
new file mode 100644
index 0000000000..49d766a6f5
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/lsp-ui-20180619.251/lsp-ui-sideline.el
@@ -0,0 +1,505 @@
+;;; lsp-ui-sideline.el --- Lsp-Ui-Sideline  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2017 Sebastien Chapuis
+
+;; Author: Sebastien Chapuis <sebastien@chapu.is>
+;; URL: https://github.com/emacs-lsp/lsp-ui
+;; Keywords: lsp, ui
+
+;;; License
+;;
+;; This program 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, or (at your option)
+;; any later version.
+
+;; This program 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 this program; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+;; Floor, Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+;;
+;; Utility to show informations of the current line
+
+;;; Code:
+
+(require 'lsp-mode)
+(require 'flycheck)
+(require 'dash)
+
+(defgroup lsp-ui-sideline nil
+  "Display informations of the current line."
+  :group 'tools
+  :group 'convenience
+  :group 'lsp-ui
+  :link '(custom-manual "(lsp-ui-sideline) Top")
+  :link '(info-link "(lsp-ui-sideline) Customizing"))
+
+(defcustom lsp-ui-sideline-enable t
+  "Whether or not to enable ‘lsp-ui-sideline’."
+  :type 'boolean
+  :group 'lsp-ui)
+
+(defcustom lsp-ui-sideline-ignore-duplicate nil
+  "Control to ignore duplicates when there is a same symbol with the same contents."
+  :type 'boolean
+  :group 'lsp-ui-sideline)
+
+(defcustom lsp-ui-sideline-show-symbol t
+  "When t, show the symbol name on the right of the information."
+  :type 'boolean
+  :group 'lsp-ui-sideline)
+
+(defcustom lsp-ui-sideline-show-hover t
+  "Whether to show hover messages in sideline."
+  :type 'boolean
+  :group 'lsp-ui-sideline)
+
+(defcustom lsp-ui-sideline-show-flycheck t
+  "Whether to show flycheck messages in sideline."
+  :type 'boolean
+  :group 'lsp-ui-sideline)
+
+(defcustom lsp-ui-sideline-show-code-actions t
+  "Whether to show code actions in sideline."
+  :type 'boolean
+  :group 'lsp-ui-sideline)
+
+(defcustom lsp-ui-sideline-update-mode 'line
+  "Define the mode for updating sideline information.
+
+When set to `line' the information will be updated when user
+changes current line otherwise the information will be updated
+when user changes current point."
+  :type '(choice (const line)
+                 (const point))
+  :group 'lsp-ui-sideline)
+
+(defcustom lsp-ui-sideline-delay 0.2
+  "Number of seconds to wait before showing sideline."
+  :type 'number
+  :group 'lsp-ui-sideline)
+
+(defvar lsp-ui-sideline-code-actions-prefix ""
+  "Prefix to insert before the code action title.
+This can be used to insert, for example, an unicode character: 💡")
+
+(defvar-local lsp-ui-sideline--ovs nil
+  "Overlays used by `lsp-ui-sideline'.")
+
+(defvar-local lsp-ui-sideline--occupied-lines nil
+  "List of lines occupied by an overlay of `lsp-ui-sideline'.")
+
+(defvar-local lsp-ui-sideline--tag nil
+  "Tag marking where the last operation was based.
+It is used to know when the cursor has changed of line or point.")
+
+(defvar-local lsp-ui-sideline--last-width nil
+  "Value of window's width on the last operation.
+It is used to know when the window has changed of width.")
+
+(defvar-local lsp-ui-sideline--timer nil)
+
+(defface lsp-ui-sideline-symbol
+  '((t :foreground "grey"
+       :box (:line-width -1 :color "grey")
+       :height 0.99))
+  "Face used to highlight symbols."
+  :group 'lsp-ui-sideline)
+
+(defface lsp-ui-sideline-current-symbol
+  '((t :foreground "white"
+       :weight ultra-bold
+       :box (:line-width -1 :color "white")
+       :height 0.99))
+  "Face used to highlight the symbol on point."
+  :group 'lsp-ui-sideline)
+
+(defface lsp-ui-sideline-code-action
+  '((t :foreground "yellow"))
+  "Face used to highlight code action text."
+  :group 'lsp-ui-sideline)
+
+(defface lsp-ui-sideline-symbol-info
+  '((t :slant italic :height 0.99))
+  "Face used to highlight the symbols informations (LSP hover)."
+  :group 'lsp-ui-sideline)
+
+(defface lsp-ui-sideline-global
+  '((t))
+  "Face which apply to all overlays.
+This face have a low priority over the others."
+  :group 'lsp-ui-sideline)
+
+(defun lsp-ui-sideline--calc-space (win-width str-len index)
+  "Calcul whether there is enough space on line.
+If there is enough space, it returns the point of the last
+character on the line.
+
+WIN-WIDTH is the window width.
+STR-LEN is the string size.
+INDEX is the line number (relative to the current line)."
+  (let ((eol (line-end-position index)))
+    (unless (member eol lsp-ui-sideline--occupied-lines)
+      (save-excursion
+        (goto-char eol)
+        (when (>= (- win-width (current-column)) str-len)
+          eol)))))
+
+(defun lsp-ui-sideline--find-line (str-len &optional up)
+  "Find a line where the string can be inserted.
+It loops on the nexts lines to find enough space.
+Returns the point of the last character on the line.
+
+WIN-WIDTH is the window width.
+STR-LEN is the string size.
+if UP is non-nil, it loops on the previous lines.."
+  (let ((win-width (lsp-ui-sideline--window-width))
+        (index 1) pos)
+    (while (and (null pos) (<= (abs index) 30))
+      (setq index (if up (1- index) (1+ index)))
+      (setq pos (lsp-ui-sideline--calc-space win-width str-len index)))
+    (when pos (push pos lsp-ui-sideline--occupied-lines))
+    (if (or (equal pos (point-min))
+            (and up (null pos)))
+        (lsp-ui-sideline--find-line str-len)
+      pos)))
+
+(defun lsp-ui-sideline--delete-ov ()
+  "Delete overlays."
+  (seq-do 'delete-overlay lsp-ui-sideline--ovs)
+  (setq lsp-ui-sideline--ovs nil))
+
+(defun lsp-ui-sideline--get-renderer (language)
+  "Return a function to fontify a string in LANGUAGE."
+  (thread-last lsp--cur-workspace
+    lsp--workspace-client
+    lsp--client-string-renderers
+    (assoc-string language)
+    cdr))
+
+(defun lsp-ui-sideline--get-language ()
+  "Return the language of the buffer."
+  (thread-first lsp--cur-workspace
+    lsp--workspace-client
+    lsp--client-language-id
+    (funcall (current-buffer))))
+
+(defun lsp-ui-sideline--extract-info (contents)
+  "Extract the line to print from CONTENTS.
+CONTENTS can be differents type of values:
+MarkedString | MarkedString[] | MarkupContent (as defined in the LSP).
+We prioritize string with a language (which is probably a type or a
+function signature)."
+  (when contents
+    (cond
+     ((stringp contents) contents)
+     ((listp contents) ;; MarkedString[]
+      (--first (and (hash-table-p it)
+                    (lsp-ui-sideline--get-renderer (gethash "language" it)))
+               contents))
+     ((gethash "kind" contents) (gethash "value" contents)) ;; MarkupContent
+     ((gethash "language" contents) ;; MarkedString
+      (and (lsp-ui-sideline--get-renderer (gethash "language" contents))
+           (gethash "value" contents))))))
+
+(defun lsp-ui-sideline--format-info (marked-string)
+  "Format MARKED-STRING.
+If the string has a language, we fontify it with the function provided
+by `lsp-mode'.
+MARKED-STRING is the string returned by `lsp-ui-sideline--extract-info'."
+  (when marked-string
+    (when (hash-table-p marked-string)
+      (let* ((language (gethash "language" marked-string))
+             (value (gethash "value" marked-string))
+             (renderer (lsp-ui-sideline--get-renderer language)))
+        (setq marked-string (if (and (functionp renderer) value)
+                                (funcall renderer value)
+                              value))))
+    (add-face-text-property 0 (length marked-string) 'lsp-ui-sideline-symbol-info nil marked-string)
+    (add-face-text-property 0 (length marked-string) 'default t marked-string)
+    (replace-regexp-in-string "[\n\t ]+" " " marked-string)))
+
+(defun lsp-ui-sideline--align (&rest lengths)
+  (+ (apply '+ lengths)
+     (if (display-graphic-p) 1 2)))
+
+(defun lsp-ui-sideline--make-display-string (info symbol current)
+  "Make final string to display on buffer.
+INFO is the information to display.
+SYMBOL is the symbol associated to the info.
+CURRENT is non-nil when the point is on the symbol."
+  (let* ((face (if current 'lsp-ui-sideline-current-symbol 'lsp-ui-sideline-symbol))
+         (str (if lsp-ui-sideline-show-symbol
+                  (concat info " " (propertize (concat " " symbol " ") 'face face))
+                info))
+         (len (length str))
+         (margin (lsp-ui-sideline--margin-width)))
+    (add-face-text-property 0 len 'lsp-ui-sideline-global nil str)
+    (concat
+     (propertize " " 'display `(space :align-to (- right-fringe ,(lsp-ui-sideline--align len margin))))
+     str)))
+
+(defun lsp-ui-sideline--check-duplicate (symbol info)
+  (not (when lsp-ui-sideline-ignore-duplicate
+         (--any (and (string= (overlay-get it 'symbol) symbol)
+                     (string= (overlay-get it 'info) info))
+                lsp-ui-sideline--ovs))))
+
+(defun lsp-ui-sideline--margin-width ()
+  (+ (if fringes-outside-margins right-margin-width 0)
+     (or (and (boundp 'fringe-mode)
+              (consp fringe-mode)
+              (or (equal (car fringe-mode) 0)
+                  (equal (cdr fringe-mode) 0))
+              1)
+         0)
+     (if (bound-and-true-p display-line-numbers-mode)
+         (+ 2 (line-number-display-width))
+       0)))
+
+(defun lsp-ui-sideline--window-width ()
+  (- (min (window-text-width) (window-body-width))
+     (lsp-ui-sideline--margin-width)))
+
+(defun lsp-ui-sideline--push-info (symbol tag bounds info)
+  (when (and (= tag (lsp-ui-sideline--calculate-tag))
+             (not (lsp-ui-sideline--stop-p)))
+    (let* ((info (concat (thread-first (gethash "contents" info)
+                           lsp-ui-sideline--extract-info
+                           lsp-ui-sideline--format-info)))
+           (current (and (>= (point) (car bounds)) (<= (point) (cdr bounds)))))
+      (when (and (> (length info) 0)
+                 (lsp-ui-sideline--check-duplicate symbol info))
+        (let* ((final-string (lsp-ui-sideline--make-display-string info symbol current))
+               (pos-ov (lsp-ui-sideline--find-line (length final-string)))
+               (ov (when pos-ov (make-overlay pos-ov pos-ov))))
+          (when pos-ov
+            (overlay-put ov 'info info)
+            (overlay-put ov 'symbol symbol)
+            (overlay-put ov 'bounds bounds)
+            (overlay-put ov 'current current)
+            (overlay-put ov 'after-string final-string)
+            (overlay-put ov 'window (get-buffer-window))
+            (push ov lsp-ui-sideline--ovs)))))))
+
+(defun lsp-ui-sideline--toggle-current (ov current)
+  "Toggle the OV face according to CURRENT."
+  (let* ((info (overlay-get ov 'info))
+         (symbol (overlay-get ov 'symbol))
+         (string (lsp-ui-sideline--make-display-string info symbol current)))
+    (overlay-put ov 'current current)
+    (overlay-put ov 'after-string string)))
+
+(defun lsp-ui-sideline--highlight-current (point)
+  "Update the symbol's face according to POINT."
+  (dolist (ov lsp-ui-sideline--ovs)
+    (let* ((bounds (overlay-get ov 'bounds))
+           (start (car bounds))
+           (end (cdr bounds)))
+      (if (and bounds (>= point start) (<= point end))
+          (unless (overlay-get ov 'current)
+            (lsp-ui-sideline--toggle-current ov t))
+        (when (overlay-get ov 'current)
+          (lsp-ui-sideline--toggle-current ov nil))))))
+
+(defun lsp-ui-sideline--flycheck ()
+  "Show flycheck message(s)."
+  (let ((bol (line-beginning-position))
+        (eol (line-end-position)))
+    (dolist (e (flycheck-overlay-errors-in bol (1+ eol)))
+      (let* ((message (--> (flycheck-error-format-message-and-id e)
+                           (car (split-string it "\n"))
+                           (replace-regexp-in-string "[\n\t ]+" " " it)))
+             (len (length message))
+             (level (flycheck-error-level e))
+             (face (if (eq level 'info) 'success level))
+             (margin (lsp-ui-sideline--margin-width))
+             (message (progn (add-face-text-property 0 len 'lsp-ui-sideline-global nil message)
+                             (add-face-text-property 0 len face nil message)
+                             message))
+             (string (concat (propertize " " 'display `(space :align-to (- right-fringe ,(lsp-ui-sideline--align len margin))))
+                             message))
+             (pos-ov (lsp-ui-sideline--find-line len t))
+             (ov (and pos-ov (make-overlay pos-ov pos-ov))))
+        (when pos-ov
+          (overlay-put ov 'after-string string)
+          (push ov lsp-ui-sideline--ovs))))))
+
+(defvar-local lsp-ui-sideline--code-actions nil)
+
+(defun lsp-ui-sideline-apply-code-actions nil
+  "Choose and apply code action(s) on the current line."
+  (interactive)
+  (unless lsp-ui-sideline--code-actions
+    (user-error "No code actions on the current line"))
+  (let* ((actions lsp-ui-sideline--code-actions)
+         (title (completing-read "Apply: " (--map (gethash "title" it) actions)
+                                 nil t))
+         (action (--first (equal (gethash "title" it) title) actions)))
+    (unless action
+      (error "Fail to apply action"))
+    (lsp-execute-code-action action)))
+
+(defun lsp-ui-sideline--code-actions (actions)
+  "Show code ACTIONS."
+  (setq lsp-ui-sideline--code-actions actions)
+  (dolist (action actions)
+    (-let* ((title (->> (gethash "title" action)
+                        (replace-regexp-in-string "[\n\t ]+" " ")
+                        (concat lsp-ui-sideline-code-actions-prefix)))
+            (margin (lsp-ui-sideline--margin-width))
+            (keymap (let ((map (make-sparse-keymap)))
+                      (define-key map [down-mouse-1] (lambda () (interactive)
+                                                       (save-excursion
+                                                         (lsp-execute-code-action action))))
+                      map))
+            (len (length title))
+            (title (progn (add-face-text-property 0 len 'lsp-ui-sideline-global nil title)
+                          (add-face-text-property 0 len 'lsp-ui-sideline-code-action nil title)
+                          (add-text-properties 0 len `(keymap ,keymap mouse-face highlight) title)
+                          title))
+            (string (concat (propertize " " 'display `(space :align-to (- right-fringe ,(lsp-ui-sideline--align len margin))))
+                            title))
+            (pos-ov (lsp-ui-sideline--find-line (1+ (length title)) t))
+            (ov (and pos-ov (make-overlay pos-ov pos-ov))))
+      (when pos-ov
+        (overlay-put ov 'after-string string)
+        (push ov lsp-ui-sideline--ovs)))))
+
+(defun lsp-ui-sideline--calculate-tag()
+  "Calculate the tag used to determinie whether to update sideline information."
+  (if (equal lsp-ui-sideline-update-mode 'line)
+      (line-number-at-pos)
+    (point)))
+
+(defun lsp-ui-sideline--run ()
+  "Show informations (flycheck + lsp).
+It loops on the symbols of the current line and request information
+to the language server."
+  (lsp-ui-sideline--delete-ov)
+  (when (and lsp--cur-workspace
+             buffer-file-name)
+    (let ((eol (line-end-position))
+          (bol (line-beginning-position))
+          (tag (lsp-ui-sideline--calculate-tag))
+          (line-widen (save-restriction (widen) (line-number-at-pos)))
+          (doc-id (lsp--text-document-identifier)))
+      (save-excursion
+        (setq lsp-ui-sideline--occupied-lines nil
+              lsp-ui-sideline--tag tag
+              lsp-ui-sideline--last-width (window-text-width))
+        (when lsp-ui-sideline-show-flycheck
+          (lsp-ui-sideline--flycheck))
+        (when (and lsp-ui-sideline-show-code-actions (lsp--capability "codeActionProvider"))
+          (lsp--send-request-async (lsp--make-request
+                                    "textDocument/codeAction"
+                                    (if (equal lsp-ui-sideline-update-mode 'line)
+                                        (list :textDocument doc-id
+                                              :range (lsp--region-to-range bol eol)
+                                              :context (list :diagnostics (lsp--cur-line-diagnotics)))
+                                      (lsp--text-document-code-action-params)))
+                                   #'lsp-ui-sideline--code-actions))
+        ;; Go through all symbols and request hover information.  Note that the symbols are
+        ;; traversed backwards as `forward-symbol' with a positive argument will jump just past the
+        ;; current symbol.  By going from the end of the line towards the front, point will be placed
+        ;; at the beginning of each symbol.  As the requests are first collected in a list before
+        ;; being processed they are still sent in order from left to right.
+        (when (and lsp-ui-sideline-show-hover (lsp--capability "hoverProvider"))
+          (let ((symbols))
+            (goto-char eol)
+            (while (and (> (point) bol)
+                        (progn (forward-symbol -1)
+                               (>= (point) bol)))
+              (let* ((symbol (thing-at-point 'symbol t))
+                     (bounds (bounds-of-thing-at-point 'symbol))
+                     (parsing-state (syntax-ppss))
+                     (in-string (nth 3 parsing-state))
+                     (outside-comment (eq (nth 4 parsing-state) nil)))
+                ;; Skip strings and comments
+                (when (and symbol (not in-string) outside-comment)
+                  (push (list symbol tag bounds (lsp--position (1- line-widen) (- (point) bol))) symbols))))
+            (dolist (entry symbols)
+              (-let [(symbol tag bounds position) entry]
+                (lsp--send-request-async
+                 (lsp--make-request
+                  "textDocument/hover"
+                  (list :textDocument doc-id :position position))
+                 (lambda (info) (if info (lsp-ui-sideline--push-info symbol tag bounds info))))))))))))
+
+(defun lsp-ui-sideline--stop-p ()
+  "Return non-nil if the sideline should not be display."
+  (or (region-active-p)
+      (bound-and-true-p company-pseudo-tooltip-overlay)
+      (bound-and-true-p lsp-ui-peek--overlay)))
+
+(defun lsp-ui-sideline--hide-before-company (command)
+  "Disable the sideline before company's overlay appears.
+COMMAND is `company-pseudo-tooltip-frontend' parameter."
+  (when (memq command '(post-command update))
+    (lsp-ui-sideline--delete-ov)
+    (setq lsp-ui-sideline--tag nil)))
+
+(defun lsp-ui-sideline ()
+  "Show informations of the current line."
+  (if (lsp-ui-sideline--stop-p)
+      (progn (setq lsp-ui-sideline--tag nil)
+             (lsp-ui-sideline--delete-ov))
+    (if (and (equal (lsp-ui-sideline--calculate-tag) lsp-ui-sideline--tag)
+             (equal (window-text-width) lsp-ui-sideline--last-width))
+        (lsp-ui-sideline--highlight-current (point))
+      (lsp-ui-sideline--delete-ov)
+      (when lsp-ui-sideline--timer
+        (cancel-timer lsp-ui-sideline--timer))
+      (let ((buf (current-buffer)))
+        (setq lsp-ui-sideline--timer
+              (run-with-idle-timer lsp-ui-sideline-delay
+                                   nil
+                                   (lambda ()
+                                     ;; run lsp-ui only if current-buffer is the same.
+                                     (when (equal buf (current-buffer))
+                                       (lsp-ui-sideline--run)))))))))
+
+(defun lsp-ui-sideline-toggle-symbols-info ()
+  "Toggle display of symbols informations.
+This does not toggle display of flycheck diagnostics or code actions."
+  (interactive)
+  (when (bound-and-true-p lsp-ui-sideline-mode)
+    (setq lsp-ui-sideline-show-hover
+          (not lsp-ui-sideline-show-hover))
+    (lsp-ui-sideline--run)))
+
+(defun lsp-ui-sideline--diagnostics-changed ()
+  "Handler for flycheck notifications."
+  (setq lsp-ui-sideline--tag nil)
+  (lsp-ui-sideline))
+
+(define-minor-mode lsp-ui-sideline-mode
+  "Minor mode for showing information of current line."
+  :init-value nil
+  :group lsp-ui-sideline
+  (cond
+   (lsp-ui-sideline-mode
+    (add-hook 'post-command-hook 'lsp-ui-sideline nil t)
+    (advice-add 'company-pseudo-tooltip-frontend :before 'lsp-ui-sideline--hide-before-company)
+    (add-hook 'lsp-after-diagnostics-hook 'lsp-ui-sideline--diagnostics-changed nil t)
+    (setq-local flycheck-display-errors-function nil))
+   (t
+    (setq lsp-ui-sideline--tag nil)
+    (advice-remove 'company-pseudo-tooltip-frontend 'lsp-ui-sideline--hide-before-company)
+    (lsp-ui-sideline--delete-ov)
+    (remove-hook 'lsp-after-diagnostics-hook 'lsp-ui-sideline--diagnostics-changed)
+    (remove-hook 'post-command-hook 'lsp-ui-sideline t))))
+
+(defun lsp-ui-sideline-enable (enable)
+  "Enable/disable `lsp-ui-sideline-mode'."
+  (lsp-ui-sideline-mode (if enable 1 -1)))
+
+(provide 'lsp-ui-sideline)
+;;; lsp-ui-sideline.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/lsp-ui-20180619.251/lsp-ui-sideline.elc b/configs/shared/emacs/.emacs.d/elpa/lsp-ui-20180619.251/lsp-ui-sideline.elc
new file mode 100644
index 0000000000..5591772830
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/lsp-ui-20180619.251/lsp-ui-sideline.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/lsp-ui-20180619.251/lsp-ui.el b/configs/shared/emacs/.emacs.d/elpa/lsp-ui-20180619.251/lsp-ui.el
new file mode 100644
index 0000000000..d56dd34d57
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/lsp-ui-20180619.251/lsp-ui.el
@@ -0,0 +1,165 @@
+;;; lsp-ui.el --- UI modules for lsp-mode            -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2017 Tobias Pisani
+
+;; Author:  Tobias Pisani <topisani@hamsterpoison.com>
+;; Keywords: lsp
+;; URL: https://github.com/emacs-lsp/lsp-ui
+;; Package-Requires: ((emacs "25.1") (dash "2.13") (dash-functional "1.2.0") (flycheck "31") (lsp-mode "4.0") (markdown-mode "2.3"))
+;; Version: 0.0.1
+
+;; Permission is hereby granted, free of charge, to any person obtaining a copy
+;; of this software and associated documentation files (the "Software"), to deal
+;; in the Software without restriction, including without limitation the rights
+;; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+;; copies of the Software, and to permit persons to whom the Software is
+;; furnished to do so, subject to the following conditions:
+
+;; The above copyright notice and this permission notice shall be included in
+;; all copies or substantial portions of the Software.
+
+;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+;; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+;; SOFTWARE.
+
+;;; Commentary:
+
+;; lsp-ui contains a series of useful UI integrations for lsp-mode, like
+;; flycheck support and code lenses.
+
+;;; Code:
+
+(defgroup lsp-ui nil
+  "‘lsp-ui’ contains a series of useful UI integrations for ‘lsp-mode’."
+  :group 'tools
+  :group 'convenience
+  :link '(custom-manual "(lsp-ui) Top")
+  :link '(info-link "(lsp-ui) Customizing"))
+
+(require 'lsp-ui-sideline)
+(require 'lsp-ui-peek)
+(require 'lsp-ui-flycheck)
+(require 'lsp-ui-imenu)
+(require 'lsp-ui-doc)
+
+(defun lsp-ui-peek--render (major string)
+  (with-temp-buffer
+    (insert string)
+    (delay-mode-hooks
+      (let ((inhibit-message t))
+        (funcall major))
+      (ignore-errors
+        (font-lock-ensure)))
+    (buffer-string))
+  )
+
+
+(defun lsp-ui--workspace-path (path)
+  "Return the PATH relative to the workspace.
+If the PATH is not in the workspace, it returns the original PATH."
+  (let* ((path (file-truename path))
+         (root (lsp--workspace-root lsp--cur-workspace))
+         (in-workspace (string-prefix-p root path)))
+    (if in-workspace
+        (substring path (length root))
+      path)))
+
+(defun lsp-ui--toggle (enable)
+  (dolist (feature '(lsp-ui-flycheck lsp-ui-peek lsp-ui-sideline lsp-ui-doc lsp-ui-imenu))
+    (let* ((sym (intern-soft (concat (symbol-name feature) "-enable")))
+           (value (symbol-value sym))
+           (fn (symbol-function sym)))
+      (when (and (or value (not enable))
+                 (functionp fn))
+        (funcall fn enable)))))
+
+(defvar lsp-ui-mode-map (make-sparse-keymap))
+
+;;;###autoload
+(define-minor-mode lsp-ui-mode
+  "Toggle language server UI mode on or off.
+‘lsp-ui-mode’ is a minor mode that contains a series of useful UI
+integrations for ‘lsp-mode’.  With a prefix argument ARG, enable
+language server UI mode if ARG is positive, and disable it
+otherwise.  If called from Lisp, enable the mode if ARG is
+omitted or nil, and toggle it if ARG is ‘toggle’."
+  :init-value nil
+  :group lsp-ui
+  :keymap lsp-ui-mode-map
+  (lsp-ui--toggle lsp-ui-mode))
+
+;; The request is delegated to xref-backend-apropos defined in lsp-mode.
+;; xref-find-apropos does similar job but is less appealing because it splits and
+;; regex quotes the pattern. The language server likely knows more about how
+;; to do fuzzy matching.
+(defun lsp-ui-find-workspace-symbol (pattern)
+  "List project-wide symbols matching the query string PATTERN."
+  (interactive (list (read-string
+                      "workspace/symbol: "
+                      nil 'xref--read-pattern-history)))
+  (xref--find-xrefs pattern 'apropos pattern nil))
+
+(defun lsp-ui--location< (x y)
+  "Compares two triples X and Y.
+Both should have the form (FILENAME LINE COLUMN)."
+  (if (not (string= (car x) (car y)))
+      (string< (car x) (car y))
+    (if (not (= (cadr x) (cadr y)))
+        (< (cadr x) (cadr y))
+      (< (caddr x) (caddr y)))))
+
+(defun lsp-ui--reference-triples (filter-fn)
+  "Return references as a list of (FILENAME LINE COLUMN) triples."
+  (let ((refs (lsp--send-request (lsp--make-request
+                                  "textDocument/references"
+                                  (lsp--make-reference-params)))))
+    (sort
+     (mapcar
+      (lambda (ref)
+        (-let* (((&hash "uri" uri "range" range) ref)
+                ((&hash "line" line "character" col) (gethash "start" range)))
+          (list (lsp--uri-to-path uri) line col)))
+      (if filter-fn (--filter (funcall filter-fn it) refs) refs))
+     #'lsp-ui--location<)))
+
+;; TODO Make it efficient
+(defun lsp-ui-find-next-reference (&optional filter-fn)
+  "Find next reference of the symbol at point."
+  (interactive)
+  (let* ((cur (list buffer-file-name (lsp--cur-line) (lsp--cur-column)))
+         (refs (lsp-ui--reference-triples filter-fn))
+         (idx -1)
+         (res (-first (lambda (ref) (cl-incf idx) (lsp-ui--location< cur ref)) refs)))
+    (if res
+        (progn
+         (find-file (car res))
+         (goto-char 1)
+         (forward-line (cadr res))
+         (forward-char (caddr res))
+         (cons idx (length refs)))
+      (cons 0 0))))
+
+;; TODO Make it efficient
+(defun lsp-ui-find-prev-reference (&optional filter-fn)
+  "Find previous reference of the symbol at point."
+  (interactive)
+  (let* ((cur (list buffer-file-name (lsp--cur-line) (lsp--cur-column)))
+         (refs (lsp-ui--reference-triples filter-fn))
+         (idx -1)
+         (res (-last (lambda (ref) (and (lsp-ui--location< ref cur) (cl-incf idx))) refs)))
+    (if res
+        (progn
+          (find-file (car res))
+          (goto-char 1)
+          (forward-line (cadr res))
+          (forward-char (caddr res))
+          (cons idx (length refs)))
+      (cons 0 0))))
+
+
+(provide 'lsp-ui)
+;;; lsp-ui.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/lsp-ui-20180619.251/lsp-ui.elc b/configs/shared/emacs/.emacs.d/elpa/lsp-ui-20180619.251/lsp-ui.elc
new file mode 100644
index 0000000000..531f9ff19c
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/lsp-ui-20180619.251/lsp-ui.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/AUTHORS.md b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/AUTHORS.md
new file mode 100644
index 0000000000..c750c0c3d3
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/AUTHORS.md
@@ -0,0 +1,303 @@
+Authors
+=======
+
+The following people have contributed to Magit, including the
+libraries `git-commit.el`, `magit-popup.el`, and `with-editor.el`
+which are distributed as separate Elpa packages.
+
+For statistics see https://magit.vc/stats/authors.html.
+
+Names below are sorted alphabetically.
+
+Author
+------
+
+- Marius Vollmer <marius.vollmer@gmail.com>
+
+Maintainer
+----------
+
+- Jonas Bernoulli <jonas@bernoul.li>
+
+Developers
+----------
+
+- Kyle Meyer <kyle@kyleam.com>
+- Noam Postavsky <npostavs@users.sourceforge.net>
+
+Retired Maintainers and Developers
+----------------------------------
+
+- Nicolas Dudebout <nicolas.dudebout@gatech.edu>
+- Peter J. Weisberg <pj@irregularexpressions.net>
+- Pieter Praet <pieter@praet.org>
+- Phil Jackson <phil@shellarchive.co.uk>
+- Rémi Vanicat <vanicat@debian.org>
+- Yann Hodique <yann.hodique@gmail.com>
+
+Contributors
+------------
+
+- Aaron Culich <aculich@gmail.com>
+- Aaron Madlon-Kay <aaron@madlon-kay.com>
+- Abdo Roig-Maranges <abdo.roig@gmail.com>
+- Adam Benanti <0entropy@protonmail.com>
+- Adam Porter <adam@alphapapa.net>
+- Adam Spiers <emacs@adamspiers.org>
+- Adeodato Simó <dato@net.com.org.es>
+- Ævar Arnfjörð Bjarmason <avarab@gmail.com>
+- Alan Falloon <alan.falloon@gmail.com>
+- Alban Gruin <alban@pa1ch.fr>
+- Aleksey Uimanov <s9gf4ult@gmail.com>
+- Alexander Gramiak <fice-t@protonmail.com>
+- Alex Dunn <adunn@ucsb.edu>
+- Alexey Voinov <alexey.v.voinov@gmail.com>
+- Alex Kost <alezost@gmail.com>
+- Alex Ott <alexott@gmail.com>
+- Allen <darkfeline@felesatra.moe>
+- Allen Li <darkfeline@felesatra.moe>
+- Andreas Fuchs <asf@boinkor.net>
+- Andreas Liljeqvist <andreas.liljeqvist@robacks.se>
+- Andreas Rottmann <a.rottmann@gmx.at>
+- Andrei Chițu <andrei.chitu1@gmail.com>
+- Andrew Kirkpatrick <andrew.kirkpatrick@adelaide.edu.au>
+- Andrew Schwartzmeyer <andrew@schwartzmeyer.com>
+- Andrey Smirnov <andrew.smirnov@gmail.com>
+- Andriy Kmit' <dev@madand.net>
+- Andy Sawyer <git@pureabstract.org>
+- Barak A. Pearlmutter <barak+git@pearlmutter.net>
+- Bar Magal <bmagamb@gmail.com>
+- Bart Bakker <bart@thesoftwarecraft.com>
+- Basil L. Contovounesios <contovob@tcd.ie>
+- Bastian Beischer <beischer@physik.rwth-aachen.de>
+- Ben North <ben@redfrontdoor.org>
+- Ben Walton <bwalton@artsci.utoronto.ca>
+- Bradley Wright <brad@intranation.com>
+- Brandon W Maister <quodlibetor@gmail.com>
+- Brian Warner <warner@lothar.com>
+- Bryan Shell <bryan.shell@orbitz.com>
+- Buster Copley <buster@buster.me.uk>
+- Carl Lieberman <liebermancarl@gmail.com>
+- Chillar Anand <anand21nanda@gmail.com>
+- Chris Bernard <cebernard@gmail.com>
+- Chris Done <chrisdone@gmail.com>
+- Chris LaRose <cjlarose@gmail.com>
+- Chris Moore <dooglus@gmail.com>
+- Chris Ring <chris@ringthis.com>
+- Chris Shoemaker <chris@mojotech.com>
+- Christian Dietrich <christian.dietrich@informatik.uni-erlangen.de>
+- Christian Kluge <ckfrakturfreak@web.de>
+- Christophe Junke <junke.christophe@gmail.com>
+- Christopher Monsanto <chris@monsan.to>
+- Cornelius Mika <cornelius.mika@gmail.com>
+- Craig Andera <candera@wangdera.com>
+- Dale Hagglund <dale.hagglund@gmail.com>
+- Damien Cassou <damien@cassou.me>
+- Dan Erikson <derikson3@gmail.com>
+- Daniel Brockman <daniel@gointeractive.se>
+- Daniel Farina <drfarina@acm.org>
+- Daniel Gröber <daniel@dps.uibk.ac.at>
+- Daniel Hackney <dan@haxney.org>
+- Daniel Kraus <daniel@kraus.my>
+- Daniel Mai <daniel@danielmai.net>
+- Dan LaManna <dan.lamanna@gmail.com>
+- Dato Simó <dato@net.com.org.es>
+- David Abrahams <dave@boostpro.com>
+- David Ellison <davide@voicebox.com>
+- David Hull <david.hull@openx.com>
+- David L. Rager <ragerdl@gmail.com>
+- David Wallin <david.wallin@gmail.com>
+- Dean Kariniemi <8913263+d3k4r@users.noreply.github.com>
+- Dennis Paskorz <dennis@walltowall.com>
+- Divye Kapoor <divye@google.com>
+- Dominique Quatravaux <domq@google.com>
+- Duianto Vebotci <vebotci@openmailbox.org>
+- Eli Barzilay <eli@barzilay.org>
+- Eric Davis <ed@npri.org>
+- Eric Schulte <schulte.eric@gmail.com>
+- Erik Anderson <erikbpanderson@gmail.com>
+- Evgkeni Sampelnikof <esabof@gmail.com>
+- Eyal Lotem <eyal.lotem@gmail.com>
+- Fabian Wiget <fabacino@gmail.com>
+- Felix Geller <fgeller@gmail.com>
+- Feng Li <fengli@blackmagicdesign.com>
+- Florian Ragwitz <rafl@debian.org>
+- Fritz Grabo <fritz.grabo@gmail.com>
+- Fritz Stelzer <brotzeitmacher@gmail.com>
+- Geoff Shannon <geoffpshannon@gmail.com>
+- George Kadianakis <desnacked@gmail.com>
+- Graham Clark <grclark@gmail.com>
+- Graham Dobbins <gdobbins@protonmail.com>
+- Greg A. Woods <woods@planix.com>
+- Greg Lucas <greg@glucas.net>
+- Greg Sexton <gregsexton@gmail.com>
+- Guillaume Martres <smarter@ubuntu.com>
+- Hannu Koivisto <azure@iki.fi>
+- Hans-Peter Deifel <hpdeifel@gmx.de>
+- Ian Eure <ian.eure@gmail.com>
+- Ingo Lohmar <i.lohmar@gmail.com>
+- Ioan-Adrian Ratiu <adi@adirat.com>
+- Ivan Brennan <ivan.brennan@gmail.com>
+- Jan Tatarik <jan.tatarik@xing.com>
+- Jasper St. Pierre <jstpierre@mecheye.net>
+- Jeff Bellegarde <jbellegarde@whitepages.com>
+- Jeff Dairiki <dairiki@dairiki.org>
+- Jeremy Meng <yumeng@microsoft.com>
+- Jesse Alama <jesse.alama@gmail.com>
+- Jim Blandy <jimb@red-bean.com>
+- Joakim Jalap <JOJA@stoneridge.com>
+- Johann Klähn <kljohann@gmail.com>
+- John Mastro <john.b.mastro@gmail.com>
+- John Wiegley <johnw@newartisans.com>
+- Jonas Bernoulli <jonas@bernoul.li>
+- Jonathan Leech-Pepin <jonathan.leechpepin@gmail.com>
+- Jonathan Roes <jroes@jroes.net>
+- Jon Vanderwijk <jonathn@github.com>
+- Jordan Greenberg <jordan@softwareslave.com>
+- Josiah Schwab <jschwab@gmail.com>
+- Julien Danjou <julien@danjou.info>
+- Justin Burkett <justin@burkett.cc>
+- Justin Caratzas <justin.caratzas@gmail.com>
+- Justin Guenther <jguenther@gmail.com>
+- Justin Thomas <justin.thomas1@gmail.com>
+- Kan-Ru Chen <kanru@kanru.info>
+- Kenny Ballou <kballou@devnulllabs.io>
+- Keshav Kini <keshav.kini@gmail.com>
+- Kévin Le Gouguec <kevin.legouguec@gmail.com>
+- Kimberly Wolk <kimwolk@hotmail.com>
+- Kyle Meyer <kyle@kyleam.com>
+- Laurent Laffont <laurent.laffont@gmail.com>
+- Laverne Schrock <laverne@schrock.email>
+- Leandro Facchinetti <me@leafac.com>
+- Lele Gaifax <lele@metapensiero.it>
+- Leo Liu <sdl.web@gmail.com>
+- Leonardo Etcheverry <leo@kalio.net>
+- Lingchao Xin <douglarek@users.noreply.github.com>
+- Li-Yun Chang <michael142536@gmail.com>
+- Lluís Vilanova <vilanova@ac.upc.edu>
+- Loic Dachary <loic@dachary.org>
+- Luís Oliveira <luismbo@gmail.com>
+- Luke Amdor <luke.amdor@gmail.com>
+- Manuel Vázquez Acosta <mva.led@gmail.com>
+- Marcel Wolf <mwolf@ml1.net>
+- Marc Herbert <marc.herbert@gmail.com>
+- Marcin Bachry <hegel666@gmail.com>
+- Marco Craveiro <marco.craveiro@gmail.com>
+- Marco Wahl <marcowahlsoft@gmail.com>
+- Marc Sherry <msherry@gmail.com>
+- Marian Schubert <marian.schubert@gmail.com>
+- Mario Rodas <marsam@users.noreply.github.com>
+- Marius Vollmer <marius.vollmer@gmail.com>
+- Mark Hepburn <Mark.Hepburn@csiro.au>
+- Mark Karpov <markkarpov@opmbx.org>
+- Mark Oteiza <mvoteiza@udel.edu>
+- Matthew Fluet <matthew.fluet@gmail.com>
+- Matthieu Hauglustaine <matt.hauglustaine@gmail.com>
+- Matus Goljer <dota.keys@gmail.com>
+- Michael Fogleman <michaelwfogleman@gmail.com>
+- Michael Griffiths <mikey@cich.li>
+- Michael Heerdegen <michael_heerdegen@web.de>
+- Michal Sojka <sojkam1@fel.cvut.cz>
+- Miles Bader <miles@gnu.org>
+- Miloš Mošić <mosic.milos@gmail.com>
+- Mitchel Humpherys <mitch.special@gmail.com>
+- Moritz Bunkus <moritz@bunkus.org>
+- Natalie Weizenbaum <nex342@gmail.com>
+- Nguyễn Tuấn Anh <ubolonton@gmail.com>
+- Nic Ferier <nic@ferrier.me.uk>
+- Nick Alcock <nick.alcock@oracle.com>
+- Nick Alexander <nalexander@mozilla.com>
+- Nick Dimiduk <ndimiduk@gmail.com>
+- Nicklas Lindgren <nili@gulmohar.se>
+- Nicolas Dudebout <nicolas.dudebout@gatech.edu>
+- Nicolas Petton <nicolas@petton.fr>
+- Nicolas Richard <theonewiththeevillook@yahoo.fr>
+- Nikolay Martynov <mar.kolya@gmail.com>
+- Noam Postavsky <npostavs@users.sourceforge.net>
+- Ole Arndt <oliver.arndt@cegedim.com>
+- Oleh Krehel <ohwoeowho@gmail.com>
+- Orivej Desh <orivej@gmx.fr>
+- Óscar Fuentes <ofv@wanadoo.es>
+- Paul Stadig <paul@stadig.name>
+- Pavel Holejsovsky <pavel.holejsovsky@upek.com>
+- Pekka Pessi <nospam@pessi.fi>
+- Peter Eisentraut <peter@eisentraut.org>
+- Peter Jaros <peter.a.jaros@gmail.com>
+- Peter J. Weisberg <pj@irregularexpressions.net>
+- Peter Vasil <mail@petervasil.net>
+- Philippe Vaucher <philippe.vaucher@gmail.com>
+- Philipp Haselwarter <philipp@haselwarter.org>
+- Philipp Stephani <phst@google.com>
+- Philip Weaver <philip.weaver@gmail.com>
+- Phil Jackson <phil@shellarchive.co.uk>
+- Phil Sainty <phil@catalyst.net.nz>
+- Pieter Praet <pieter@praet.org>
+- Prathamesh Sonpatki <csonpatki@gmail.com>
+- rabio <rabiodev@o2.pl>
+- Radon Rosborough <radon.neon@gmail.com>
+- Rafael Laboissiere <rafael@laboissiere.net>
+- Raimon Grau <raimon@3scale.net>
+- Ramkumar Ramachandra <artagnon@gmail.com>
+- Remco van 't Veer <rwvtveer@xs4all.nl>
+- Rémi Vanicat <vanicat@debian.org>
+- René Stadler <mail@renestadler.de>
+- Richard Kim <emacs18@gmail.com>
+- Robert Boone <robo4288@gmail.com>
+- Robin Green <greenrd@greenrd.org>
+- Roger Crew <crew@cs.stanford.edu>
+- Romain Francoise <romain@orebokech.com>
+- Ron Parker <rparker@a123systems.com>
+- Roy Crihfield <rscrihf@gmail.com>
+- Rüdiger Sonderfeld <ruediger@c-plusplus.net>
+- Russell Black <black.russell@gmail.com>
+- Ryan C. Thompson <rct@thompsonclan.org>
+- Samuel Bronson <naesten@gmail.com>
+- Samuel W. Flint <swflint@flintfam.org>
+- Sanjoy Das <sanjoy@playingwithpointers.com>
+- Sean Allred <code@seanallred.com>
+- Sean Bryant <sbryant@hackinggibsons.com>
+- Sean Whitton <spwhitton@spwhitton.name>
+- Sebastian Wiesner <lunaryorn@gmail.com>
+- Sébastien Gross <seb@chezwam.org>
+- Seong-Kook Shin <cinsky@gmail.com>
+- Sergey Pashinin <sergey@pashinin.com>
+- Sergey Vinokurov <serg.foo@gmail.com>
+- Servilio Afre Puentes <afrepues@mcmaster.ca>
+- Silent Sphere <silentsphere110@gmail.com>
+- Štěpán Němec <stepnem@gmail.com>
+- Steven Chow <steve@myfreestuffapp.com>
+- Steven E. Harris <seh@panix.com>
+- Steven Thomas <sthomas314@gmail.com>
+- Steven Vancoillie <steven.vancoillie@runbox.com>
+- Steve Purcell <steve@sanityinc.com>
+- Suhail Shergill <suhailshergill@gmail.com>
+- Sylvain Rousseau <thisirs@gmail.com>
+- Syohei Yoshida <syohex@gmail.com>
+- Takafumi Arakaki <aka.tkf@gmail.com>
+- Teemu Likonen <tlikonen@iki.fi>
+- Teruki Shigitani <teruki.shigitani@gmail.com>
+- Thierry Volpiatto <thierry.volpiatto@gmail.com>
+- Thomas A Caswell <tcaswell@gmail.com>
+- Thomas Frössman <thomasf@jossystem.se>
+- Thomas Jost <thomas.jost@gmail.com>
+- Thomas Riccardi <riccardi.thomas@gmail.com>
+- Tibor Simko <tibor.simko@cern.ch>
+- Timo Juhani Lindfors <timo.lindfors@iki.fi>
+- Tim Perkins <tprk77@gmail.com>
+- Tim Wraight <tim@wraight.net>
+- Ting-Yu Lin <aethanyc@gmail.com>
+- Tom Feist <shabble@metavore.org>
+- Tunc Uzlu <bb2020@users.noreply.github.com>
+- Vineet Naik <vineet@helpshift.com>
+- Vladimir Panteleev <git@thecybershadow.net>
+- Wei Huang <weih@opera.com>
+- Wilfred Hughes <me@wilfred.me.uk>
+- Win Treese <treese@acm.org>
+- Wouter Bolsterlee <wouter@bolsterl.ee>
+- Xavier Noria <fxn@hashref.com>
+- Xu Chunyang <mail@xuchunyang.me>
+- Yann Hodique <yann.hodique@gmail.com>
+- York Zhao <gtdplatform@gmail.com>
+- Yuichi Higashi <aaa707b@gmail.com>
+- Yuri Khan <yurivkhan@gmail.com>
+- Zach Latta <zach@zachlatta.com>
diff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/LICENSE b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/LICENSE
new file mode 100644
index 0000000000..4432540474
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/LICENSE
@@ -0,0 +1,676 @@
+
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.  We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors.  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights.  Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received.  You must make sure that they, too, receive
+or can get the source code.  And you must show them these terms so they
+know their rights.
+
+  Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+  For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software.  For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+  Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so.  This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software.  The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable.  Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products.  If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+  Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary.  To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+		       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+ 
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+  
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Use with the GNU Affero General Public License.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+		     END OF TERMS AND CONDITIONS
+
+	    How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program 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.
+
+    This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+    <program>  Copyright (C) <year>  <name of author>
+    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+  The GNU General Public License does not permit incorporating your program
+into proprietary programs.  If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.  But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
+
diff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/dir b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/dir
new file mode 100644
index 0000000000..5fec543970
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/dir
@@ -0,0 +1,18 @@
+This is the file .../info/dir, which contains the
+topmost node of the Info hierarchy, called (dir)Top.
+The first time you invoke Info you start off looking at this node.
+
+File: dir,	Node: Top	This is the top of the INFO tree
+
+  This (the Directory node) gives a menu of major topics.
+  Typing "q" exits, "?" lists all Info commands, "d" returns here,
+  "h" gives a primer for first-timers,
+  "mEmacs<Return>" visits the Emacs manual, etc.
+
+  In Emacs, you can click mouse button 2 on a menu item or cross reference
+  to select it.
+
+* Menu:
+
+Emacs
+* Magit: (magit).               Using Git from Emacs with Magit.
diff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/git-rebase.el b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/git-rebase.el
new file mode 100644
index 0000000000..63f50a8a32
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/git-rebase.el
@@ -0,0 +1,592 @@
+;;; git-rebase.el --- Edit Git rebase files  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2010-2018  The Magit Project Contributors
+;;
+;; You should have received a copy of the AUTHORS.md file which
+;; lists all contributors.  If not, see http://magit.vc/authors.
+
+;; Author: Phil Jackson <phil@shellarchive.co.uk>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; This file is not part of GNU Emacs.
+
+;; This file 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, or (at your option)
+;; any later version.
+
+;; This file 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 this file.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This package assists the user in editing the list of commits to be
+;; rewritten during an interactive rebase.
+
+;; When the user initiates an interactive rebase, e.g. using "r e" in
+;; a Magit buffer or on the command line using "git rebase -i REV",
+;; Git invokes the `$GIT_SEQUENCE_EDITOR' (or if that is undefined
+;; `$GIT_EDITOR' or even `$EDITOR') letting the user rearrange, drop,
+;; reword, edit, and squash commits.
+
+;; This package provides the major-mode `git-rebase-mode' which makes
+;; doing so much more fun, by making the buffer more colorful and
+;; providing the following commands:
+;;
+;;   C-c C-c  Tell Git to make it happen.
+;;   C-c C-k  Tell Git that you changed your mind, i.e. abort.
+;;
+;;   p        Move point to previous line.
+;;   n        Move point to next line.
+;;
+;;   M-p      Move the commit at point up.
+;;   M-n      Move the commit at point down.
+;;
+;;   k        Drop the commit at point.
+;;   c        Don't drop the commit at point.
+;;   r        Change the message of the commit at point.
+;;   e        Edit the commit at point.
+;;   s        Squash the commit at point, into the one above.
+;;   f        Like "s" but don't also edit the commit message.
+;;   x        Add a script to be run with the commit at point
+;;            being checked out.
+;;   z        Add noop action at point.
+;;
+;;   SPC      Show the commit at point in another buffer.
+;;   RET      Show the commit at point in another buffer and
+;;            select its window.
+;;   C-/      Undo last change.
+
+;; You should probably also read the `git-rebase' manpage.
+
+;;; Code:
+
+(require 'dash)
+(require 'easymenu)
+(require 'server)
+(require 'with-editor)
+(require 'magit)
+
+(and (require 'async-bytecomp nil t)
+     (memq 'magit (bound-and-true-p async-bytecomp-allowed-packages))
+     (fboundp 'async-bytecomp-package-mode)
+     (async-bytecomp-package-mode 1))
+
+(eval-when-compile (require 'recentf))
+
+;;; Options
+;;;; Variables
+
+(defgroup git-rebase nil
+  "Edit Git rebase sequences."
+  :link '(info-link "(magit)Editing Rebase Sequences")
+  :group 'tools)
+
+(defcustom git-rebase-auto-advance t
+  "Whether to move to next line after changing a line."
+  :group 'git-rebase
+  :type 'boolean)
+
+(defcustom git-rebase-show-instructions t
+  "Whether to show usage instructions inside the rebase buffer."
+  :group 'git-rebase
+  :type 'boolean)
+
+(defcustom git-rebase-confirm-cancel t
+  "Whether confirmation is required to cancel."
+  :group 'git-rebase
+  :type 'boolean)
+
+;;;; Faces
+
+(defgroup git-rebase-faces nil
+  "Faces used by Git-Rebase mode."
+  :group 'faces
+  :group 'git-rebase)
+
+(defface git-rebase-hash '((t (:inherit magit-hash)))
+  "Face for commit hashes."
+  :group 'git-rebase-faces)
+
+(defface git-rebase-description nil
+  "Face for commit descriptions."
+  :group 'git-rebase-faces)
+
+(defface git-rebase-killed-action
+  '((t (:inherit font-lock-comment-face :strike-through t)))
+  "Face for commented action and exec lines."
+  :group 'git-rebase-faces)
+
+(defface git-rebase-comment-hash
+  '((t (:inherit git-rebase-hash :weight bold)))
+  "Face for commit hashes in commit message comments."
+  :group 'git-rebase-faces)
+
+(defface git-rebase-comment-heading
+  '((t :inherit font-lock-keyword-face))
+  "Face for headings in rebase message comments."
+  :group 'git-commit-faces)
+
+;;; Keymaps
+
+(defvar git-rebase-mode-map
+  (let ((map (make-sparse-keymap)))
+    (set-keymap-parent map special-mode-map)
+    (cond ((featurep 'jkl)
+           (define-key map [return]    'git-rebase-show-commit)
+           (define-key map (kbd   "i") 'git-rebase-backward-line)
+           (define-key map (kbd   "k") 'forward-line)
+           (define-key map (kbd "M-i") 'git-rebase-move-line-up)
+           (define-key map (kbd "M-k") 'git-rebase-move-line-down)
+           (define-key map (kbd   "p") 'git-rebase-pick)
+           (define-key map (kbd   ",") 'git-rebase-kill-line))
+          (t
+           (define-key map (kbd "C-m") 'git-rebase-show-commit)
+           (define-key map (kbd   "p") 'git-rebase-backward-line)
+           (define-key map (kbd   "n") 'forward-line)
+           (define-key map (kbd "M-p") 'git-rebase-move-line-up)
+           (define-key map (kbd "M-n") 'git-rebase-move-line-down)
+           (define-key map (kbd   "c") 'git-rebase-pick)
+           (define-key map (kbd   "k") 'git-rebase-kill-line)
+           (define-key map (kbd "C-k") 'git-rebase-kill-line)))
+    (define-key map (kbd "e") 'git-rebase-edit)
+    (define-key map (kbd "m") 'git-rebase-edit)
+    (define-key map (kbd "f") 'git-rebase-fixup)
+    (define-key map (kbd "q") 'undefined)
+    (define-key map (kbd "r") 'git-rebase-reword)
+    (define-key map (kbd "w") 'git-rebase-reword)
+    (define-key map (kbd "s") 'git-rebase-squash)
+    (define-key map (kbd "x") 'git-rebase-exec)
+    (define-key map (kbd "y") 'git-rebase-insert)
+    (define-key map (kbd "z") 'git-rebase-noop)
+    (define-key map (kbd "SPC")     'git-rebase-show-or-scroll-up)
+    (define-key map (kbd "DEL")     'git-rebase-show-or-scroll-down)
+    (define-key map (kbd "C-x C-t") 'git-rebase-move-line-up)
+    (define-key map [M-up]          'git-rebase-move-line-up)
+    (define-key map [M-down]        'git-rebase-move-line-down)
+    (define-key map [remap undo]    'git-rebase-undo)
+    map)
+  "Keymap for Git-Rebase mode.")
+
+(cond ((featurep 'jkl)
+       (put 'git-rebase-reword       :advertised-binding "r")
+       (put 'git-rebase-move-line-up :advertised-binding (kbd "M-i"))
+       (put 'git-rebase-kill-line    :advertised-binding ","))
+      (t
+       (put 'git-rebase-reword       :advertised-binding "r")
+       (put 'git-rebase-move-line-up :advertised-binding (kbd "M-p"))
+       (put 'git-rebase-kill-line    :advertised-binding "k")))
+
+(easy-menu-define git-rebase-mode-menu git-rebase-mode-map
+  "Git-Rebase mode menu"
+  '("Rebase"
+    ["Pick" git-rebase-pick t]
+    ["Reword" git-rebase-reword t]
+    ["Edit" git-rebase-edit t]
+    ["Squash" git-rebase-squash t]
+    ["Fixup" git-rebase-fixup t]
+    ["Kill" git-rebase-kill-line t]
+    ["Noop" git-rebase-noop t]
+    ["Execute" git-rebase-exec t]
+    ["Move Down" git-rebase-move-line-down t]
+    ["Move Up" git-rebase-move-line-up t]
+    "---"
+    ["Cancel" with-editor-cancel t]
+    ["Finish" with-editor-finish t]))
+
+(defvar git-rebase-command-descriptions
+  '((with-editor-finish           . "tell Git to make it happen")
+    (with-editor-cancel           . "tell Git that you changed your mind, i.e. abort")
+    (git-rebase-backward-line     . "move point to previous line")
+    (forward-line                 . "move point to next line")
+    (git-rebase-move-line-up      . "move the commit at point up")
+    (git-rebase-move-line-down    . "move the commit at point down")
+    (git-rebase-show-or-scroll-up . "show the commit at point in another buffer")
+    (git-rebase-show-commit
+     . "show the commit at point in another buffer and select its window")
+    (undo                         . "undo last change")
+    (git-rebase-kill-line         . "drop the commit at point")
+    (git-rebase-insert            . "insert a line for an arbitrary commit")
+    (git-rebase-noop              . "add noop action at point")))
+
+;;; Commands
+
+(defun git-rebase-pick ()
+  "Use commit on current line."
+  (interactive)
+  (git-rebase-set-action "pick"))
+
+(defun git-rebase-reword ()
+  "Edit message of commit on current line."
+  (interactive)
+  (git-rebase-set-action "reword"))
+
+(defun git-rebase-edit ()
+  "Stop at the commit on the current line."
+  (interactive)
+  (git-rebase-set-action "edit"))
+
+(defun git-rebase-squash ()
+  "Meld commit on current line into previous commit, edit message."
+  (interactive)
+  (git-rebase-set-action "squash"))
+
+(defun git-rebase-fixup ()
+  "Meld commit on current line into previous commit, discard its message."
+  (interactive)
+  (git-rebase-set-action "fixup"))
+
+(defvar-local git-rebase-line nil)
+(defvar-local git-rebase-comment-re nil)
+
+(defun git-rebase-set-action (action)
+  (goto-char (line-beginning-position))
+  (if (and (looking-at git-rebase-line)
+           (not (string-match-p "\\(e\\|exec\\|noop\\)$" (match-string 1))))
+      (let ((inhibit-read-only t))
+        (replace-match action t t nil 1)
+        (when git-rebase-auto-advance
+          (forward-line)))
+    (ding)))
+
+(defun git-rebase-line-p (&optional pos)
+  (save-excursion
+    (when pos (goto-char pos))
+    (goto-char (line-beginning-position))
+    (looking-at-p git-rebase-line)))
+
+(defun git-rebase-region-bounds ()
+  (when (use-region-p)
+    (let ((beg (save-excursion (goto-char (region-beginning))
+                               (line-beginning-position)))
+          (end (save-excursion (goto-char (region-end))
+                               (line-end-position))))
+      (when (and (git-rebase-line-p beg)
+                 (git-rebase-line-p end))
+        (list beg (1+ end))))))
+
+(defun git-rebase-move-line-down (n)
+  "Move the current commit (or command) N lines down.
+If N is negative, move the commit up instead.  With an active
+region, move all the lines that the region touches, not just the
+current line."
+  (interactive "p")
+  (pcase-let* ((`(,beg ,end)
+                (or (git-rebase-region-bounds)
+                    (list (line-beginning-position)
+                          (1+ (line-end-position)))))
+               (pt-offset (- (point) beg))
+               (mark-offset (and mark-active (- (mark) beg))))
+    (save-restriction
+      (narrow-to-region
+       (point-min)
+       (1+ (save-excursion
+             (goto-char (point-min))
+             (while (re-search-forward git-rebase-line nil t))
+             (point))))
+      (if (or (and (< n 0) (= beg (point-min)))
+              (and (> n 0) (= end (point-max)))
+              (> end (point-max)))
+          (ding)
+        (goto-char (if (< n 0) beg end))
+        (forward-line n)
+        (atomic-change-group
+          (let ((inhibit-read-only t))
+            (insert (delete-and-extract-region beg end)))
+          (let ((new-beg (- (point) (- end beg))))
+            (when (use-region-p)
+              (setq deactivate-mark nil)
+              (set-mark (+ new-beg mark-offset)))
+            (goto-char (+ new-beg pt-offset))))))))
+
+(defun git-rebase-move-line-up (n)
+  "Move the current commit (or command) N lines up.
+If N is negative, move the commit down instead.  With an active
+region, move all the lines that the region touches, not just the
+current line."
+  (interactive "p")
+  (git-rebase-move-line-down (- n)))
+
+(defun git-rebase-highlight-region (start end window rol)
+  (let ((inhibit-read-only t)
+        (deactivate-mark nil)
+        (bounds (git-rebase-region-bounds)))
+    (mapc #'delete-overlay magit-section-highlight-overlays)
+    (when bounds
+      (magit-section-make-overlay (car bounds) (cadr bounds)
+                                  'magit-section-heading-selection))
+    (if (and bounds (not magit-keep-region-overlay))
+        (funcall (default-value 'redisplay-unhighlight-region-function) rol)
+      (funcall (default-value 'redisplay-highlight-region-function)
+               start end window rol))))
+
+(defun git-rebase-unhighlight-region (rol)
+  (mapc #'delete-overlay magit-section-highlight-overlays)
+  (funcall (default-value 'redisplay-unhighlight-region-function) rol))
+
+(defun git-rebase-kill-line ()
+  "Kill the current action line."
+  (interactive)
+  (goto-char (line-beginning-position))
+  (when (and (looking-at git-rebase-line)
+             (not (eq (char-after) (string-to-char comment-start))))
+    (let ((inhibit-read-only t))
+      (insert comment-start)
+      (insert " "))
+    (when git-rebase-auto-advance
+      (forward-line))))
+
+(defun git-rebase-insert (rev)
+  "Read an arbitrary commit and insert it below current line."
+  (interactive (list (magit-read-branch-or-commit "Insert revision")))
+  (forward-line)
+  (--if-let (magit-rev-format "%h %s" rev)
+      (let ((inhibit-read-only t))
+        (insert "pick " it ?\n))
+    (user-error "Unknown revision")))
+
+(defun git-rebase-exec (arg)
+  "Insert a shell command to be run after the proceeding commit.
+
+If there already is such a command on the current line, then edit
+that instead.  With a prefix argument insert a new command even
+when there already is one on the current line.  With empty input
+remove the command on the current line, if any."
+  (interactive "P")
+  (let ((inhibit-read-only t) initial command)
+    (unless arg
+      (goto-char (line-beginning-position))
+      (when (looking-at (concat git-rebase-comment-re "?"
+                                "\\(e\\|exec\\) \\(.*\\)"))
+        (setq initial (match-string-no-properties 2))))
+    (setq command (read-shell-command "Execute: " initial))
+    (pcase (list command initial)
+      (`("" nil) (ding))
+      (`(""  ,_)
+       (delete-region (match-beginning 0) (1+ (match-end 0))))
+      (`(,_ nil)
+       (forward-line)
+       (insert (concat "exec " command "\n"))
+       (unless git-rebase-auto-advance
+         (forward-line -1)))
+      (_
+       (replace-match (concat "exec " command) t t)
+       (if git-rebase-auto-advance
+           (forward-line)
+         (goto-char (line-beginning-position)))))))
+
+(defun git-rebase-noop (&optional arg)
+  "Add noop action at point.
+
+If the current line already contains a a noop action, leave it
+unchanged.  If there is a commented noop action present, remove
+the comment.  Otherwise add a new noop action.  With a prefix
+argument insert a new noop action regardless what is already
+present on the current line.
+
+A noop action can be used to make git perform a rebase even if
+no commits are selected.  Without the noop action present, git
+would see an empty file and therefore do nothing."
+  (interactive "P")
+  (goto-char (line-beginning-position))
+  ;; The extra space at the end is only there to make the action
+  ;; consistent with the others (action argument). This keeps
+  ;; the regexp `git-rebase-line' from getting complicated.
+  (let ((noop-string "noop \n"))
+    (when (or arg (not (looking-at noop-string)))
+      (let ((inhibit-read-only t))
+        (if (and (not arg)
+                 (looking-at (concat comment-start noop-string)))
+            (delete-char 1)
+          (insert noop-string))))))
+
+(defun git-rebase-undo (&optional arg)
+  "Undo some previous changes.
+Like `undo' but works in read-only buffers."
+  (interactive "P")
+  (let ((inhibit-read-only t))
+    (undo arg)))
+
+(defun git-rebase--show-commit (&optional scroll)
+  (let ((disable-magit-save-buffers t))
+    (save-excursion
+      (goto-char (line-beginning-position))
+      (--if-let (and (looking-at git-rebase-line)
+                     (match-string 2))
+          (pcase scroll
+            (`up   (magit-diff-show-or-scroll-up))
+            (`down (magit-diff-show-or-scroll-down))
+            (_     (apply #'magit-show-commit it (magit-diff-arguments))))
+        (ding)))))
+
+(defun git-rebase-show-commit ()
+  "Show the commit on the current line if any."
+  (interactive)
+  (git-rebase--show-commit))
+
+(defun git-rebase-show-or-scroll-up ()
+  "Update the commit buffer for commit on current line.
+
+Either show the commit at point in the appropriate buffer, or if
+that buffer is already being displayed in the current frame and
+contains information about that commit, then instead scroll the
+buffer up."
+  (interactive)
+  (git-rebase--show-commit 'up))
+
+(defun git-rebase-show-or-scroll-down ()
+  "Update the commit buffer for commit on current line.
+
+Either show the commit at point in the appropriate buffer, or if
+that buffer is already being displayed in the current frame and
+contains information about that commit, then instead scroll the
+buffer down."
+  (interactive)
+  (git-rebase--show-commit 'down))
+
+(defun git-rebase-backward-line (&optional n)
+  "Move N lines backward (forward if N is negative).
+Like `forward-line' but go into the opposite direction."
+  (interactive "p")
+  (forward-line (- (or n 1))))
+
+;;; Mode
+
+;;;###autoload
+(define-derived-mode git-rebase-mode special-mode "Git Rebase"
+  "Major mode for editing of a Git rebase file.
+
+Rebase files are generated when you run 'git rebase -i' or run
+`magit-interactive-rebase'.  They describe how Git should perform
+the rebase.  See the documentation for git-rebase (e.g., by
+running 'man git-rebase' at the command line) for details."
+  :group 'git-rebase
+  (setq comment-start (or (magit-get "core.commentChar") "#"))
+  (setq git-rebase-comment-re (concat "^" (regexp-quote comment-start)))
+  (setq git-rebase-line
+        (concat "^\\(" (regexp-quote comment-start) "? *"
+                "\\(?:[fprse]\\|pick\\|reword\\|edit\\|squash\\|fixup\\|exec\\|noop\\)\\) "
+                "\\(?:\\([^ \n]+\\) \\(.*\\)\\)?"))
+  (setq font-lock-defaults (list (git-rebase-mode-font-lock-keywords) t t))
+  (unless git-rebase-show-instructions
+    (let ((inhibit-read-only t))
+      (flush-lines git-rebase-comment-re)))
+  (unless with-editor-mode
+    ;; Maybe already enabled when using `shell-command' or an Emacs shell.
+    (with-editor-mode 1))
+  (when git-rebase-confirm-cancel
+    (add-hook 'with-editor-cancel-query-functions
+              'git-rebase-cancel-confirm nil t))
+  (setq-local redisplay-highlight-region-function 'git-rebase-highlight-region)
+  (setq-local redisplay-unhighlight-region-function 'git-rebase-unhighlight-region)
+  (add-hook 'with-editor-pre-cancel-hook  'git-rebase-autostash-save  nil t)
+  (add-hook 'with-editor-post-cancel-hook 'git-rebase-autostash-apply nil t)
+  (setq imenu-prev-index-position-function
+        #'magit-imenu--rebase-prev-index-position-function)
+  (setq imenu-extract-index-name-function
+        #'magit-imenu--rebase-extract-index-name-function)
+  (when (boundp 'save-place)
+    (setq save-place nil)))
+
+(defun git-rebase-cancel-confirm (force)
+  (or (not (buffer-modified-p))
+      force
+      (magit-confirm 'abort-rebase "Abort this rebase" nil 'noabort)))
+
+(defun git-rebase-autostash-save ()
+  (--when-let (magit-file-line (magit-git-dir "rebase-merge/autostash"))
+    (push (cons 'stash it) with-editor-cancel-alist)))
+
+(defun git-rebase-autostash-apply ()
+  (--when-let (cdr (assq 'stash with-editor-cancel-alist))
+    (magit-stash-apply it)))
+
+(defun git-rebase-match-comment-line (limit)
+  (re-search-forward (concat git-rebase-comment-re ".*") limit t))
+
+(defun git-rebase-mode-font-lock-keywords ()
+  "Font lock keywords for Git-Rebase mode."
+  (let ((action-re "\
+\\([efprs]\\|pick\\|reword\\|edit\\|squash\\|fixup\\) \\([^ \n]+\\) \\(.*\\)"))
+    `((,(concat "^" action-re)
+       (1 'font-lock-keyword-face)
+       (2 'git-rebase-hash)
+       (3 'git-rebase-description))
+      ("^\\(exec\\) \\(.*\\)"
+       (1 'font-lock-keyword-face)
+       (2 'git-rebase-description))
+      ("^\\(noop\\)"
+       (1 'font-lock-keyword-face))
+      (git-rebase-match-comment-line 0 'font-lock-comment-face)
+      (,(concat git-rebase-comment-re " *" action-re)
+       0 'git-rebase-killed-action t)
+      ("\\[[^[]*\\]"
+       0 'magit-keyword t)
+      (,(format "^%s Rebase \\([^ ]*\\) onto \\([^ ]*\\)" comment-start)
+       (1 'git-rebase-comment-hash t)
+       (2 'git-rebase-comment-hash t))
+      (,(format "^%s \\(Commands:\\)" comment-start)
+       (1 'git-rebase-comment-heading t)))))
+
+(defun git-rebase-mode-show-keybindings ()
+  "Modify the \"Commands:\" section of the comment Git generates
+at the bottom of the file so that in place of the one-letter
+abbreviation for the command, it shows the command's keybinding.
+By default, this is the same except for the \"pick\" command."
+  (let ((inhibit-read-only t))
+    (save-excursion
+      (goto-char (point-min))
+      (when (and git-rebase-show-instructions
+                 (re-search-forward
+                  (concat git-rebase-comment-re "\\s-+p, pick")
+                  nil t))
+        (goto-char (line-beginning-position))
+        (pcase-dolist (`(,cmd . ,desc) git-rebase-command-descriptions)
+          (insert (format "%s %-8s %s\n"
+                          comment-start
+                          (substitute-command-keys (format "\\[%s]" cmd))
+                          desc)))
+        (while (re-search-forward (concat git-rebase-comment-re
+                                          "\\(  ?\\)\\([^\n,],\\) "
+                                          "\\([^\n ]+\\) ")
+                                  nil t)
+          (let ((cmd (intern (concat "git-rebase-" (match-string 3)))))
+            (if (not (fboundp cmd))
+                (delete-region (line-beginning-position) (1+ (line-end-position)))
+              (replace-match " " t t nil 1)
+              (replace-match
+               (format "%-8s"
+                       (mapconcat #'key-description
+                                  (--remove (eq (elt it 0) 'menu-bar)
+                                            (reverse (where-is-internal cmd)))
+                                  ", "))
+               t t nil 2))))))))
+
+(add-hook 'git-rebase-mode-hook 'git-rebase-mode-show-keybindings t)
+
+(defun git-rebase-mode-disable-before-save-hook ()
+  (set (make-local-variable 'before-save-hook) nil))
+
+(add-hook 'git-rebase-mode-hook 'git-rebase-mode-disable-before-save-hook)
+
+;;;###autoload
+(defconst git-rebase-filename-regexp "/git-rebase-todo\\'")
+;;;###autoload
+(add-to-list 'auto-mode-alist
+             (cons git-rebase-filename-regexp 'git-rebase-mode))
+
+(add-to-list 'with-editor-server-window-alist
+             (cons git-rebase-filename-regexp 'switch-to-buffer))
+
+(eval-after-load 'recentf
+  '(add-to-list 'recentf-exclude git-rebase-filename-regexp))
+
+(add-to-list 'with-editor-file-name-history-exclude git-rebase-filename-regexp)
+
+(provide 'git-rebase)
+;;; git-rebase.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/git-rebase.elc b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/git-rebase.elc
new file mode 100644
index 0000000000..165b943991
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/git-rebase.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-apply.el b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-apply.el
new file mode 100644
index 0000000000..55dbb2e288
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-apply.el
@@ -0,0 +1,641 @@
+;;; magit-apply.el --- apply Git diffs  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2010-2018  The Magit Project Contributors
+;;
+;; You should have received a copy of the AUTHORS.md file which
+;; lists all contributors.  If not, see http://magit.vc/authors.
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; Magit 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, or (at your option)
+;; any later version.
+;;
+;; Magit 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 Magit.  If not, see http://www.gnu.org/licenses.
+
+;;; Commentary:
+
+;; This library implements commands for applying Git diffs or parts
+;; of such a diff.  The supported "apply variants" are apply, stage,
+;; unstage, discard, and reverse - more than Git itself knows about,
+;; at least at the porcelain level.
+
+;;; Code:
+
+(require 'magit-core)
+(require 'magit-diff)
+(require 'magit-wip)
+
+;; For `magit-apply'
+(declare-function magit-am-popup "magit-sequence" (&optional arg))
+(declare-function magit-patch-apply-popup "magit-files" (&optional arg))
+;; For `magit-discard-files'
+(declare-function magit-checkout-stage "magit-merge" (file arg))
+(declare-function magit-checkout-read-stage "magit-merge" (file))
+(defvar auto-revert-verbose)
+;; For `magit-stage-untracked'
+(declare-function magit-submodule-add "magit-submodule"
+                  (url &optional path name args))
+(declare-function magit-submodule-read-name-for-path "magit-submodule"
+                  (path &optional prefer-short))
+(declare-function borg--maybe-absorb-gitdir "borg" (pkg))
+(declare-function borg--sort-submodule-sections "borg" (file))
+(defvar borg-user-emacs-directory)
+
+;;; Options
+
+(defcustom magit-delete-by-moving-to-trash t
+  "Whether Magit uses the system's trash can.
+
+You should absolutely not disable this and also remove `discard'
+from `magit-no-confirm'.  You shouldn't do that even if you have
+all of the Magit-Wip modes enabled, because those modes do not
+track any files that are not tracked in the proper branch."
+  :package-version '(magit . "2.1.0")
+  :group 'magit-essentials
+  :type 'boolean)
+
+(defcustom magit-unstage-committed t
+  "Whether unstaging a committed change reverts it instead.
+
+A committed change cannot be unstaged, because staging and
+unstaging are actions that are concerned with the differences
+between the index and the working tree, not with committed
+changes.
+
+If this option is non-nil (the default), then typing \"u\"
+\(`magit-unstage') on a committed change, causes it to be
+reversed in the index but not the working tree.  For more
+information see command `magit-reverse-in-index'."
+  :package-version '(magit . "2.4.1")
+  :group 'magit-commands
+  :type 'boolean)
+
+(defcustom magit-reverse-atomically nil
+  "Whether to reverse changes atomically.
+
+If some changes can be reversed while others cannot, then nothing
+is reversed if the value of this option is non-nil.  But when it
+is nil, then the changes that can be reversed are reversed and
+for the other changes diff files are created that contain the
+rejected reversals."
+  :package-version '(magit . "2.7.0")
+  :group 'magit-commands
+  :type 'boolean)
+
+;;; Commands
+;;;; Apply
+
+(defun magit-apply (&rest args)
+  "Apply the change at point to the working tree.
+With a prefix argument fallback to a 3-way merge.  Doing
+so causes the change to be applied to the index as well."
+  (interactive (and current-prefix-arg (list "--3way")))
+  (--when-let (magit-apply--get-selection)
+    (pcase (list (magit-diff-type) (magit-diff-scope))
+      (`(,(or `unstaged `staged) ,_)
+       (user-error "Change is already in the working tree"))
+      (`(untracked ,(or `file `files))
+       (magit-am-popup))
+      (`(,_ region) (magit-apply-region it args))
+      (`(,_   hunk) (magit-apply-hunk   it args))
+      (`(,_  hunks) (magit-apply-hunks  it args))
+      (`(rebase-sequence file) (magit-patch-apply-popup))
+      (`(,_   file) (magit-apply-diff   it args))
+      (`(,_  files) (magit-apply-diffs  it args)))))
+
+(defun magit-apply--section-content (section)
+  (buffer-substring-no-properties (if (magit-hunk-section-p section)
+                                      (oref section start)
+                                    (oref section content))
+                                  (oref section end)))
+
+(defun magit-apply-diffs (sections &rest args)
+  (setq sections (magit-apply--get-diffs sections))
+  (magit-apply-patch sections args
+                     (mapconcat
+                      (lambda (s)
+                        (concat (magit-diff-file-header s)
+                                (magit-apply--section-content s)))
+                      sections "")))
+
+(defun magit-apply-diff (section &rest args)
+  (setq section (car (magit-apply--get-diffs (list section))))
+  (magit-apply-patch section args
+                     (concat (magit-diff-file-header section)
+                             (magit-apply--section-content section))))
+
+(defun magit-apply-hunks (sections &rest args)
+  (let ((section (oref (car sections) parent)))
+    (when (string-match "^diff --cc" (oref section value))
+      (user-error "Cannot un-/stage resolution hunks.  Stage the whole file"))
+    (magit-apply-patch section args
+                       (concat (oref section header)
+                               (mapconcat 'magit-apply--section-content
+                                          sections "")))))
+
+(defun magit-apply-hunk (section &rest args)
+  (when (string-match "^diff --cc" (magit-section-parent-value section))
+    (user-error "Cannot un-/stage resolution hunks.  Stage the whole file"))
+  (magit-apply-patch (oref section parent) args
+                     (concat (magit-diff-file-header section)
+                             (magit-apply--section-content section))))
+
+(defun magit-apply-region (section &rest args)
+  (unless (magit-diff-context-p)
+    (user-error "Not enough context to apply region.  Increase the context"))
+  (when (string-match "^diff --cc" (magit-section-parent-value section))
+    (user-error "Cannot un-/stage resolution hunks.  Stage the whole file"))
+  (magit-apply-patch (oref section parent) args
+                     (concat (magit-diff-file-header section)
+                             (magit-diff-hunk-region-patch section args))))
+
+(defun magit-apply-patch (section:s args patch)
+  (let* ((files (if (atom section:s)
+                    (list (oref section:s value))
+                  (--map (oref it value) section:s)))
+         (command (symbol-name this-command))
+         (command (if (and command (string-match "^magit-\\([^-]+\\)" command))
+                      (match-string 1 command)
+                    "apply")))
+    (when (and magit-wip-before-change-mode (not inhibit-magit-refresh))
+      (magit-wip-commit-before-change files (concat " before " command)))
+    (with-temp-buffer
+      (insert patch)
+      (magit-run-git-with-input
+       "apply" args "-p0"
+       (unless (magit-diff-context-p) "--unidiff-zero")
+       "--ignore-space-change" "-"))
+    (unless inhibit-magit-refresh
+      (when magit-wip-after-apply-mode
+        (magit-wip-commit-after-apply files (concat " after " command)))
+      (magit-refresh))))
+
+(defun magit-apply--get-selection ()
+  (or (magit-region-sections '(hunk file) t)
+      (let ((section (magit-current-section)))
+        (pcase (oref section type)
+          ((or `hunk `file) section)
+          ((or `staged `unstaged `untracked
+               `stashed-index `stashed-worktree `stashed-untracked)
+           (oref section children))
+          (_ (user-error "Cannot apply this, it's not a change"))))))
+
+(defun magit-apply--get-diffs (sections)
+  (magit-section-case
+    ([file diffstat]
+     (--map (or (magit-get-section
+                 (append `((file . ,(oref it value)))
+                         (magit-section-ident magit-root-section)))
+                (error "Cannot get required diff headers"))
+            sections))
+    (t sections)))
+
+(defun magit-apply--diff-ignores-whitespace-p ()
+  (and (cl-intersection (if (derived-mode-p 'magit-diff-mode)
+                            (nth 2 magit-refresh-args)
+                          magit-diff-section-arguments)
+                        '("--ignore-space-at-eol"
+                          "--ignore-space-change"
+                          "--ignore-all-space"
+                          "--ignore-blank-lines")
+                        :test #'equal)
+       t))
+
+;;;; Stage
+
+(defun magit-stage (&optional intent)
+  "Add the change at point to the staging area.
+With a prefix argument, INTENT, and an untracked file (or files)
+at point, stage the file but not its content."
+  (interactive "P")
+  (--if-let (and (derived-mode-p 'magit-mode) (magit-apply--get-selection))
+      (pcase (list (magit-diff-type)
+                   (magit-diff-scope)
+                   (magit-apply--diff-ignores-whitespace-p))
+        (`(untracked     ,_  ,_) (magit-stage-untracked intent))
+        (`(unstaged  region  ,_) (magit-apply-region it "--cached"))
+        (`(unstaged    hunk  ,_) (magit-apply-hunk   it "--cached"))
+        (`(unstaged   hunks  ,_) (magit-apply-hunks  it "--cached"))
+        (`(unstaged    file   t) (magit-apply-diff   it "--cached"))
+        (`(unstaged   files   t) (magit-apply-diffs  it "--cached"))
+        (`(unstaged    list   t) (magit-apply-diffs  it "--cached"))
+        (`(unstaged    file nil) (magit-stage-1 "-u" (list (oref it value))))
+        (`(unstaged   files nil) (magit-stage-1 "-u" (magit-region-values nil t)))
+        (`(unstaged    list nil) (magit-stage-modified))
+        (`(staged        ,_  ,_) (user-error "Already staged"))
+        (`(committed     ,_  ,_) (user-error "Cannot stage committed changes"))
+        (`(undefined     ,_  ,_) (user-error "Cannot stage this change")))
+    (call-interactively 'magit-stage-file)))
+
+;;;###autoload
+(defun magit-stage-file (file)
+  "Stage all changes to FILE.
+With a prefix argument or when there is no file at point ask for
+the file to be staged.  Otherwise stage the file at point without
+requiring confirmation."
+  (interactive
+   (let* ((atpoint (magit-section-when (file)))
+          (current (magit-file-relative-name))
+          (choices (nconc (magit-unstaged-files)
+                          (magit-untracked-files)))
+          (default (car (member (or atpoint current) choices))))
+     (list (if (or current-prefix-arg (not default))
+               (magit-completing-read "Stage file" choices
+                                      nil t nil nil default)
+             default))))
+  (magit-with-toplevel
+    (magit-stage-1 nil (list file))))
+
+;;;###autoload
+(defun magit-stage-modified (&optional all)
+  "Stage all changes to files modified in the worktree.
+Stage all new content of tracked files and remove tracked files
+that no longer exist in the working tree from the index also.
+With a prefix argument also stage previously untracked (but not
+ignored) files."
+  (interactive "P")
+  (when (magit-anything-staged-p)
+    (magit-confirm 'stage-all-changes))
+  (magit-with-toplevel
+    (magit-stage-1 (if all "--all" "-u"))))
+
+(defun magit-stage-1 (arg &optional files)
+  (magit-wip-commit-before-change files " before stage")
+  (magit-run-git "add" arg (if files (cons "--" files) "."))
+  (when magit-auto-revert-mode
+    (mapc #'magit-turn-on-auto-revert-mode-if-desired files))
+  (magit-wip-commit-after-apply files " after stage"))
+
+(defun magit-stage-untracked (&optional intent)
+  (let* ((section (magit-current-section))
+         (files (pcase (magit-diff-scope)
+                  (`file  (list (oref section value)))
+                  (`files (magit-region-values nil t))
+                  (`list  (magit-untracked-files))))
+         plain repos)
+    (dolist (file files)
+      (if (and (not (file-symlink-p file))
+               (magit-git-repo-p file t))
+          (push file repos)
+        (push file plain)))
+    (magit-wip-commit-before-change files " before stage")
+    (when plain
+      (magit-run-git "add" (and intent "--intent-to-add")
+                     "--" plain)
+      (when magit-auto-revert-mode
+        (mapc #'magit-turn-on-auto-revert-mode-if-desired plain)))
+    (dolist (repo repos)
+      (save-excursion
+        (goto-char (oref (magit-get-section
+                          `((file . ,repo) (untracked) (status)))
+                         start))
+        (let* ((topdir (magit-toplevel))
+               (package
+                (and (equal (bound-and-true-p borg-user-emacs-directory)
+                            topdir)
+                     (file-name-nondirectory (directory-file-name repo)))))
+          (magit-submodule-add
+           (let ((default-directory
+                   (file-name-as-directory (expand-file-name repo))))
+             (or (magit-get "remote" (magit-get-some-remote) "url")
+                 (concat (file-name-as-directory ".") repo)))
+           repo
+           (magit-submodule-read-name-for-path repo package))
+          (when package
+            (borg--sort-submodule-sections
+             (expand-file-name ".gitmodules" topdir))
+            (let ((default-directory borg-user-emacs-directory))
+              (borg--maybe-absorb-gitdir package))
+            (when (and (y-or-n-p
+                        (format "Also build and activate `%s' drone?" package))
+                       (fboundp 'borg-build)
+                       (fboundp 'borg-activate))
+              (borg-build package)
+              (borg-activate package))))))
+    (magit-wip-commit-after-apply files " after stage")))
+
+;;;; Unstage
+
+(defun magit-unstage ()
+  "Remove the change at point from the staging area."
+  (interactive)
+  (--when-let (magit-apply--get-selection)
+    (pcase (list (magit-diff-type)
+                 (magit-diff-scope)
+                 (magit-apply--diff-ignores-whitespace-p))
+      (`(untracked     ,_  ,_) (user-error "Cannot unstage untracked changes"))
+      (`(unstaged      ,_  ,_) (user-error "Already unstaged"))
+      (`(staged    region  ,_) (magit-apply-region it "--reverse" "--cached"))
+      (`(staged      hunk  ,_) (magit-apply-hunk   it "--reverse" "--cached"))
+      (`(staged     hunks  ,_) (magit-apply-hunks  it "--reverse" "--cached"))
+      (`(staged      file   t) (magit-apply-diff   it "--reverse" "--cached"))
+      (`(staged     files   t) (magit-apply-diffs  it "--reverse" "--cached"))
+      (`(staged      list   t) (magit-apply-diffs  it "--reverse" "--cached"))
+      (`(staged      file nil) (magit-unstage-1 (list (oref it value))))
+      (`(staged     files nil) (magit-unstage-1 (magit-region-values nil t)))
+      (`(staged      list nil) (magit-unstage-all))
+      (`(committed     ,_  ,_) (if magit-unstage-committed
+                                   (magit-reverse-in-index)
+                                 (user-error "Cannot unstage committed changes")))
+      (`(undefined     ,_  ,_) (user-error "Cannot unstage this change")))))
+
+;;;###autoload
+(defun magit-unstage-file (file)
+  "Unstage all changes to FILE.
+With a prefix argument or when there is no file at point ask for
+the file to be unstaged.  Otherwise unstage the file at point
+without requiring confirmation."
+  (interactive
+   (let* ((atpoint (magit-section-when (file)))
+          (current (magit-file-relative-name))
+          (choices (magit-staged-files))
+          (default (car (member (or atpoint current) choices))))
+     (list (if (or current-prefix-arg (not default))
+               (magit-completing-read "Unstage file" choices
+                                      nil t nil nil default)
+             default))))
+  (magit-with-toplevel
+    (magit-unstage-1 (list file))))
+
+(defun magit-unstage-1 (files)
+  (magit-wip-commit-before-change files " before unstage")
+  (if (magit-no-commit-p)
+      (magit-run-git "rm" "--cached" "--" files)
+    (magit-run-git "reset" "HEAD" "--" files))
+  (magit-wip-commit-after-apply files " after unstage"))
+
+;;;###autoload
+(defun magit-unstage-all ()
+  "Remove all changes from the staging area."
+  (interactive)
+  (when (or (magit-anything-unstaged-p)
+            (magit-untracked-files))
+    (magit-confirm 'unstage-all-changes))
+  (magit-wip-commit-before-change nil " before unstage")
+  (magit-run-git "reset" "HEAD" "--")
+  (magit-wip-commit-after-apply nil " after unstage"))
+
+;;;; Discard
+
+(defun magit-discard ()
+  "Remove the change at point."
+  (interactive)
+  (--when-let (magit-apply--get-selection)
+    (pcase (list (magit-diff-type) (magit-diff-scope))
+      (`(committed ,_) (user-error "Cannot discard committed changes"))
+      (`(undefined ,_) (user-error "Cannot discard this change"))
+      (`(,_    region) (magit-discard-region it))
+      (`(,_      hunk) (magit-discard-hunk   it))
+      (`(,_     hunks) (magit-discard-hunks  it))
+      (`(,_      file) (magit-discard-file   it))
+      (`(,_     files) (magit-discard-files  it))
+      (`(,_      list) (magit-discard-files  it)))))
+
+(defun magit-discard-region (section)
+  (magit-confirm 'discard "Discard region")
+  (magit-discard-apply section 'magit-apply-region))
+
+(defun magit-discard-hunk (section)
+  (magit-confirm 'discard "Discard hunk")
+  (magit-discard-apply section 'magit-apply-hunk))
+
+(defun magit-discard-apply (section apply)
+  (if (eq (magit-diff-type section) 'unstaged)
+      (funcall apply section "--reverse")
+    (if (magit-anything-unstaged-p
+         nil (if (magit-file-section-p section)
+                 (oref section value)
+               (magit-section-parent-value section)))
+        (progn (let ((inhibit-magit-refresh t))
+                 (funcall apply section "--reverse" "--cached")
+                 (funcall apply section "--reverse" "--reject"))
+               (magit-refresh))
+      (funcall apply section "--reverse" "--index"))))
+
+(defun magit-discard-hunks (sections)
+  (magit-confirm 'discard (format "Discard %s hunks from %s"
+                                  (length sections)
+                                  (magit-section-parent-value (car sections))))
+  (magit-discard-apply-n sections 'magit-apply-hunks))
+
+(defun magit-discard-apply-n (sections apply)
+  (let ((section (car sections)))
+    (if (eq (magit-diff-type section) 'unstaged)
+        (funcall apply sections "--reverse")
+      (if (magit-anything-unstaged-p
+           nil (if (magit-file-section-p section)
+                   (oref section value)
+                 (magit-section-parent-value section)))
+          (progn (let ((inhibit-magit-refresh t))
+                   (funcall apply sections "--reverse" "--cached")
+                   (funcall apply sections "--reverse" "--reject"))
+                 (magit-refresh))
+        (funcall apply sections "--reverse" "--index")))))
+
+(defun magit-discard-file (section)
+  (magit-discard-files (list section)))
+
+(defun magit-discard-files (sections)
+  (let ((auto-revert-verbose nil)
+        (type (magit-diff-type (car sections)))
+        (status (magit-file-status))
+        files delete resurrect rename discard discard-new resolve)
+    (dolist (section sections)
+      (let ((file (oref section value)))
+        (push file files)
+        (pcase (cons (pcase type
+                       (`staged ?X)
+                       (`unstaged ?Y)
+                       (`untracked ?Z))
+                     (cddr (assoc file status)))
+          (`(?Z) (dolist (f (magit-untracked-files nil file))
+                   (push f delete)))
+          ((or `(?Z ?? ??) `(?Z ?! ?!)) (push file delete))
+          ((or `(?Z ?D ? ) `(,_ ?D ?D)) (push file delete))
+          ((or `(,_ ?U ,_) `(,_ ,_ ?U)) (push file resolve))
+          (`(,_ ?A ?A)                  (push file resolve))
+          (`(?X ?M ,(or ?  ?M ?D)) (push section discard))
+          (`(?Y ,_         ?M    ) (push section discard))
+          (`(?X ?A         ?M    ) (push file discard-new))
+          (`(?X ?C         ?M    ) (push file discard-new))
+          (`(?X ?A ,(or ?     ?D)) (push file delete))
+          (`(?X ?C ,(or ?     ?D)) (push file delete))
+          (`(?X ?D ,(or ?  ?M   )) (push file resurrect))
+          (`(?Y ,_            ?D ) (push file resurrect))
+          (`(?X ?R ,(or ?  ?M ?D)) (push file rename)))))
+    (unwind-protect
+        (let ((inhibit-magit-refresh t))
+          (magit-wip-commit-before-change files " before discard")
+          (when resolve
+            (dolist (file (nreverse resolve))
+              (magit-checkout-stage file (magit-checkout-read-stage file))))
+          (when resurrect
+            (magit-discard-files--resurrect (nreverse resurrect)))
+          (when delete
+            (magit-discard-files--delete (nreverse delete) status))
+          (when rename
+            (magit-discard-files--rename (nreverse rename) status))
+          (when (or discard discard-new)
+            (magit-discard-files--discard (nreverse discard)
+                                          (nreverse discard-new)))
+          (magit-wip-commit-after-apply files " after discard"))
+      (magit-refresh))))
+
+(defun magit-discard-files--resurrect (files)
+  (magit-confirm-files 'resurrect files)
+  (if (eq (magit-diff-type) 'staged)
+      (magit-call-git "reset"  "--" files)
+    (magit-call-git "checkout" "--" files)))
+
+(defun magit-discard-files--delete (files status)
+  (magit-confirm-files (if magit-delete-by-moving-to-trash 'trash 'delete)
+                       files)
+  (let ((delete-by-moving-to-trash magit-delete-by-moving-to-trash))
+    (dolist (file files)
+      (if (memq (magit-diff-type) '(unstaged untracked))
+          (progn (dired-delete-file file dired-recursive-deletes
+                                    magit-delete-by-moving-to-trash)
+                 (dired-clean-up-after-deletion file))
+        (pcase (nth 3 (assoc file status))
+          (?  (delete-file file t)
+              (magit-call-git "rm" "--cached" "--" file))
+          (?M (let ((temp (magit-git-string "checkout-index" "--temp" file)))
+                (string-match
+                 (format "\\(.+?\\)\t%s" (regexp-quote file)) temp)
+                (rename-file (match-string 1 temp)
+                             (setq temp (concat file ".~{index}~")))
+                (delete-file temp t))
+              (magit-call-git "rm" "--cached" "--force" "--" file))
+          (?D (magit-call-git "checkout" "--" file)
+              (delete-file file t)
+              (magit-call-git "rm" "--cached" "--force" "--" file)))))))
+
+(defun magit-discard-files--rename (files status)
+  (magit-confirm 'rename "Undo rename %s" "Undo %i renames" nil
+    (mapcar (lambda (file)
+              (setq file (assoc file status))
+              (format "%s -> %s" (cadr file) (car file)))
+            files))
+  (dolist (file files)
+    (let ((orig (cadr (assoc file status))))
+      (if (file-exists-p file)
+          (progn
+            (--when-let (file-name-directory orig)
+              (make-directory it t))
+            (magit-call-git "mv" file orig))
+        (magit-call-git "rm" "--cached" "--" file)
+        (magit-call-git "reset" "--" orig)))))
+
+(defun magit-discard-files--discard (sections new-files)
+  (let ((files (--map (oref it value) sections)))
+    (magit-confirm-files 'discard (append files new-files)
+                         (format "Discard %s changes in" (magit-diff-type)))
+    (if (eq (magit-diff-type (car sections)) 'unstaged)
+        (magit-call-git "checkout" "--" files)
+      (when new-files
+        (magit-call-git "add"   "--" new-files)
+        (magit-call-git "reset" "--" new-files))
+      (let ((binaries (magit-staged-binary-files)))
+        (when binaries
+          (setq sections
+                (--remove (member (oref it value) binaries)
+                          sections)))
+        (cond ((= (length sections) 1)
+               (magit-discard-apply (car sections) 'magit-apply-diff))
+              (sections
+               (magit-discard-apply-n sections 'magit-apply-diffs)))
+        (when binaries
+          (let ((modified (magit-unstaged-files t)))
+            (setq binaries (--separate (member it modified) binaries)))
+          (when (cadr binaries)
+            (magit-call-git "reset" "--" (cadr binaries)))
+          (when (car binaries)
+            (user-error
+             (concat
+              "Cannot discard staged changes to binary files, "
+              "which also have unstaged changes.  Unstage instead."))))))))
+
+;;;; Reverse
+
+(defun magit-reverse (&rest args)
+  "Reverse the change at point in the working tree.
+With a prefix argument fallback to a 3-way merge.  Doing
+so causes the change to be applied to the index as well."
+  (interactive (and current-prefix-arg (list "--3way")))
+  (--when-let (magit-apply--get-selection)
+    (pcase (list (magit-diff-type) (magit-diff-scope))
+      (`(untracked ,_) (user-error "Cannot reverse untracked changes"))
+      (`(unstaged  ,_) (user-error "Cannot reverse unstaged changes"))
+      (`(,_    region) (magit-reverse-region it args))
+      (`(,_      hunk) (magit-reverse-hunk   it args))
+      (`(,_     hunks) (magit-reverse-hunks  it args))
+      (`(,_      file) (magit-reverse-file   it args))
+      (`(,_     files) (magit-reverse-files  it args))
+      (`(,_      list) (magit-reverse-files  it args)))))
+
+(defun magit-reverse-region (section args)
+  (magit-confirm 'reverse "Reverse region")
+  (magit-reverse-apply section 'magit-apply-region args))
+
+(defun magit-reverse-hunk (section args)
+  (magit-confirm 'reverse "Reverse hunk")
+  (magit-reverse-apply section 'magit-apply-hunk args))
+
+(defun magit-reverse-hunks (sections args)
+  (magit-confirm 'reverse
+    (format "Reverse %s hunks from %s"
+            (length sections)
+            (magit-section-parent-value (car sections))))
+  (magit-reverse-apply sections 'magit-apply-hunks args))
+
+(defun magit-reverse-file (section args)
+  (magit-reverse-files (list section) args))
+
+(defun magit-reverse-files (sections args)
+  (pcase-let ((`(,binaries ,sections)
+               (let ((bs (magit-staged-binary-files)))
+                 (--separate (member (oref it value) bs)
+                             sections))))
+    (magit-confirm-files 'reverse (--map (oref it value) sections))
+    (if (= (length sections) 1)
+        (magit-reverse-apply (car sections) 'magit-apply-diff args)
+      (magit-reverse-apply sections 'magit-apply-diffs args))
+    (when binaries
+      (user-error "Cannot reverse binary files"))))
+
+(defun magit-reverse-apply (section:s apply args)
+  (funcall apply section:s "--reverse" args
+           (and (not magit-reverse-atomically)
+                (not (member "--3way" args))
+                "--reject")))
+
+(defun magit-reverse-in-index (&rest args)
+  "Reverse the change at point in the index but not the working tree.
+
+Use this command to extract a change from `HEAD', while leaving
+it in the working tree, so that it can later be committed using
+a separate commit.  A typical workflow would be:
+
+0. Optionally make sure that there are no uncommitted changes.
+1. Visit the `HEAD' commit and navigate to the change that should
+   not have been included in that commit.
+2. Type \"u\" (`magit-unstage') to reverse it in the index.
+   This assumes that `magit-unstage-committed-changes' is non-nil.
+3. Type \"c e\" to extend `HEAD' with the staged changes,
+   including those that were already staged before.
+4. Optionally stage the remaining changes using \"s\" or \"S\"
+   and then type \"c c\" to create a new commit."
+  (interactive)
+  (magit-reverse (cons "--cached" args)))
+
+(provide 'magit-apply)
+;;; magit-apply.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-apply.elc b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-apply.elc
new file mode 100644
index 0000000000..3aad9c2d27
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-apply.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-autoloads.el
new file mode 100644
index 0000000000..41ad1b4dbc
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-autoloads.el
@@ -0,0 +1,2469 @@
+;;; magit-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "git-rebase" "git-rebase.el" (23377 61608 682226
+;;;;;;  374000))
+;;; Generated autoloads from git-rebase.el
+
+(autoload 'git-rebase-mode "git-rebase" "\
+Major mode for editing of a Git rebase file.
+
+Rebase files are generated when you run 'git rebase -i' or run
+`magit-interactive-rebase'.  They describe how Git should perform
+the rebase.  See the documentation for git-rebase (e.g., by
+running 'man git-rebase' at the command line) for details.
+
+\(fn)" t nil)
+
+(defconst git-rebase-filename-regexp "/git-rebase-todo\\'")
+
+(add-to-list 'auto-mode-alist (cons git-rebase-filename-regexp 'git-rebase-mode))
+
+;;;***
+
+;;;### (autoloads nil "magit" "magit.el" (23377 61608 721353 149000))
+;;; Generated autoloads from magit.el
+ (autoload 'magit-dispatch-popup "magit" nil t)
+ (autoload 'magit-run-popup "magit" nil t)
+
+(autoload 'magit-git-command "magit" "\
+Execute COMMAND asynchronously; display output.
+
+Interactively, prompt for COMMAND in the minibuffer. \"git \" is
+used as initial input, but can be deleted to run another command.
+
+With a prefix argument COMMAND is run in the top-level directory
+of the current working tree, otherwise in `default-directory'.
+
+\(fn COMMAND)" t nil)
+
+(autoload 'magit-git-command-topdir "magit" "\
+Execute COMMAND asynchronously; display output.
+
+Interactively, prompt for COMMAND in the minibuffer. \"git \" is
+used as initial input, but can be deleted to run another command.
+
+COMMAND is run in the top-level directory of the current
+working tree.
+
+\(fn COMMAND)" t nil)
+
+(autoload 'magit-shell-command "magit" "\
+Execute COMMAND asynchronously; display output.
+
+Interactively, prompt for COMMAND in the minibuffer.  With a
+prefix argument COMMAND is run in the top-level directory of
+the current working tree, otherwise in `default-directory'.
+
+\(fn COMMAND)" t nil)
+
+(autoload 'magit-shell-command-topdir "magit" "\
+Execute COMMAND asynchronously; display output.
+
+Interactively, prompt for COMMAND in the minibuffer.  COMMAND
+is run in the top-level directory of the current working tree.
+
+\(fn COMMAND)" t nil)
+
+(autoload 'magit-version "magit" "\
+Return the version of Magit currently in use.
+If optional argument PRINT-DEST is non-nil, output
+stream (interactively, the echo area, or the current buffer with
+a prefix argument), also print the used versions of Magit, Git,
+and Emacs to it.
+
+\(fn &optional PRINT-DEST)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "magit-apply" "magit-apply.el" (23377 61608
+;;;;;;  692068 460000))
+;;; Generated autoloads from magit-apply.el
+
+(autoload 'magit-stage-file "magit-apply" "\
+Stage all changes to FILE.
+With a prefix argument or when there is no file at point ask for
+the file to be staged.  Otherwise stage the file at point without
+requiring confirmation.
+
+\(fn FILE)" t nil)
+
+(autoload 'magit-stage-modified "magit-apply" "\
+Stage all changes to files modified in the worktree.
+Stage all new content of tracked files and remove tracked files
+that no longer exist in the working tree from the index also.
+With a prefix argument also stage previously untracked (but not
+ignored) files.
+
+\(fn &optional ALL)" t nil)
+
+(autoload 'magit-unstage-file "magit-apply" "\
+Unstage all changes to FILE.
+With a prefix argument or when there is no file at point ask for
+the file to be unstaged.  Otherwise unstage the file at point
+without requiring confirmation.
+
+\(fn FILE)" t nil)
+
+(autoload 'magit-unstage-all "magit-apply" "\
+Remove all changes from the staging area.
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "magit-autorevert" "magit-autorevert.el" (23377
+;;;;;;  61608 670889 566000))
+;;; Generated autoloads from magit-autorevert.el
+
+(defvar magit-auto-revert-mode (and (not global-auto-revert-mode) (not noninteractive)) "\
+Non-nil if Magit-Auto-Revert mode is enabled.
+See the `magit-auto-revert-mode' command
+for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `magit-auto-revert-mode'.")
+
+(custom-autoload 'magit-auto-revert-mode "magit-autorevert" nil)
+
+(autoload 'magit-auto-revert-mode "magit-autorevert" "\
+Toggle Auto-Revert mode in all buffers.
+With prefix ARG, enable Magit-Auto-Revert mode if ARG is positive;
+otherwise, disable it.  If called from Lisp, enable the mode if
+ARG is omitted or nil.
+
+Auto-Revert mode is enabled in all buffers where
+`magit-turn-on-auto-revert-mode-if-desired' would do it.
+See `auto-revert-mode' for more information on Auto-Revert mode.
+
+\(fn &optional ARG)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "magit-bisect" "magit-bisect.el" (23377 61608
+;;;;;;  690696 666000))
+;;; Generated autoloads from magit-bisect.el
+ (autoload 'magit-bisect-popup "magit-bisect" nil t)
+
+(autoload 'magit-bisect-start "magit-bisect" "\
+Start a bisect session.
+
+Bisecting a bug means to find the commit that introduced it.
+This command starts such a bisect session by asking for a know
+good and a bad commit.  To move the session forward use the
+other actions from the bisect popup (\\<magit-status-mode-map>\\[magit-bisect-popup]).
+
+\(fn BAD GOOD)" t nil)
+
+(autoload 'magit-bisect-reset "magit-bisect" "\
+After bisecting, cleanup bisection state and return to original `HEAD'.
+
+\(fn)" t nil)
+
+(autoload 'magit-bisect-good "magit-bisect" "\
+While bisecting, mark the current commit as good.
+Use this after you have asserted that the commit does not contain
+the bug in question.
+
+\(fn)" t nil)
+
+(autoload 'magit-bisect-bad "magit-bisect" "\
+While bisecting, mark the current commit as bad.
+Use this after you have asserted that the commit does contain the
+bug in question.
+
+\(fn)" t nil)
+
+(autoload 'magit-bisect-skip "magit-bisect" "\
+While bisecting, skip the current commit.
+Use this if for some reason the current commit is not a good one
+to test.  This command lets Git choose a different one.
+
+\(fn)" t nil)
+
+(autoload 'magit-bisect-run "magit-bisect" "\
+Bisect automatically by running commands after each step.
+
+Unlike `git bisect run' this can be used before bisecting has
+begun.  In that case it behaves like `git bisect start; git
+bisect run'.
+
+\(fn CMDLINE &optional BAD GOOD)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "magit-blame" "magit-blame.el" (23377 61608
+;;;;;;  718563 170000))
+;;; Generated autoloads from magit-blame.el
+
+(autoload 'magit-blame-echo "magit-blame" "\
+For each line show the revision in which it was added.
+Show the information about the chunk at point in the echo area
+when moving between chunks.  Unlike other blaming commands, do
+not turn on `read-only-mode'.
+
+\(fn)" t nil)
+
+(autoload 'magit-blame "magit-blame" "\
+For each line show the revision in which it was added.
+
+\(fn)" t nil)
+
+(autoload 'magit-blame-removal "magit-blame" "\
+For each line show the revision in which it was removed.
+
+\(fn)" t nil)
+
+(autoload 'magit-blame-reverse "magit-blame" "\
+For each line show the last revision in which it still exists.
+
+\(fn)" t nil)
+ (autoload 'magit-blame-popup "magit-blame" nil t)
+
+;;;***
+
+;;;### (autoloads nil "magit-bookmark" "magit-bookmark.el" (23377
+;;;;;;  61608 685037 931000))
+;;; Generated autoloads from magit-bookmark.el
+
+(autoload 'magit-bookmark--status-jump "magit-bookmark" "\
+Handle a Magit status BOOKMARK.
+
+\(fn BOOKMARK)" nil nil)
+
+(autoload 'magit-bookmark--status-make-record "magit-bookmark" "\
+Create a Magit status bookmark.
+
+\(fn)" nil nil)
+
+(autoload 'magit-bookmark--refs-jump "magit-bookmark" "\
+Handle a Magit refs BOOKMARK.
+
+\(fn BOOKMARK)" nil nil)
+
+(autoload 'magit-bookmark--refs-make-record "magit-bookmark" "\
+Create a Magit refs bookmark.
+
+\(fn)" nil nil)
+
+(autoload 'magit-bookmark--log-jump "magit-bookmark" "\
+Handle a Magit log BOOKMARK.
+
+\(fn BOOKMARK)" nil nil)
+
+(autoload 'magit-bookmark--log-make-record "magit-bookmark" "\
+Create a Magit log bookmark.
+
+\(fn)" nil nil)
+
+(autoload 'magit-bookmark--reflog-jump "magit-bookmark" "\
+Handle a Magit reflog BOOKMARK.
+
+\(fn BOOKMARK)" nil nil)
+
+(autoload 'magit-bookmark--reflog-make-record "magit-bookmark" "\
+Create a Magit reflog bookmark.
+
+\(fn)" nil nil)
+
+(autoload 'magit-bookmark--stashes-jump "magit-bookmark" "\
+Handle a Magit stash list BOOKMARK.
+
+\(fn BOOKMARK)" nil nil)
+
+(autoload 'magit-bookmark--stashes-make-record "magit-bookmark" "\
+Create a Magit stash list bookmark.
+
+\(fn)" nil nil)
+
+(autoload 'magit-bookmark--cherry-jump "magit-bookmark" "\
+Handle a Magit cherry BOOKMARK.
+
+\(fn BOOKMARK)" nil nil)
+
+(autoload 'magit-bookmark--cherry-make-record "magit-bookmark" "\
+Create a Magit cherry bookmark.
+
+\(fn)" nil nil)
+
+(autoload 'magit-bookmark--diff-jump "magit-bookmark" "\
+Handle a Magit diff BOOKMARK.
+
+\(fn BOOKMARK)" nil nil)
+
+(autoload 'magit-bookmark--diff-make-record "magit-bookmark" "\
+Create a Magit diff bookmark.
+
+\(fn)" nil nil)
+
+(autoload 'magit-bookmark--revision-jump "magit-bookmark" "\
+Handle a Magit revision BOOKMARK.
+
+\(fn BOOKMARK)" nil nil)
+
+(autoload 'magit-bookmark--revision-make-record "magit-bookmark" "\
+Create a Magit revision bookmark.
+
+\(fn)" nil nil)
+
+(autoload 'magit-bookmark--stash-jump "magit-bookmark" "\
+Handle a Magit stash BOOKMARK.
+
+\(fn BOOKMARK)" nil nil)
+
+(autoload 'magit-bookmark--stash-make-record "magit-bookmark" "\
+Create a Magit stash bookmark.
+
+\(fn)" nil nil)
+
+(autoload 'magit-bookmark--submodules-jump "magit-bookmark" "\
+Handle a Magit submodule list BOOKMARK.
+
+\(fn BOOKMARK)" nil nil)
+
+(autoload 'magit-bookmark--submodules-make-record "magit-bookmark" "\
+Create a Magit submodule list bookmark.
+
+\(fn)" nil nil)
+
+;;;***
+
+;;;### (autoloads nil "magit-branch" "magit-branch.el" (23377 61608
+;;;;;;  689244 500000))
+;;; Generated autoloads from magit-branch.el
+ (autoload 'magit-branch-popup "magit" nil t)
+
+(autoload 'magit-checkout "magit-branch" "\
+Checkout REVISION, updating the index and the working tree.
+If REVISION is a local branch, then that becomes the current
+branch.  If it is something else, then `HEAD' becomes detached.
+Checkout fails if the working tree or the staging area contain
+changes.
+
+\(git checkout REVISION).
+
+\(fn REVISION)" t nil)
+
+(autoload 'magit-branch "magit-branch" "\
+Create BRANCH at branch or revision START-POINT.
+
+\(git branch [ARGS] BRANCH START-POINT).
+
+\(fn BRANCH START-POINT &optional ARGS)" t nil)
+
+(autoload 'magit-branch-and-checkout "magit-branch" "\
+Create and checkout BRANCH at branch or revision START-POINT.
+
+\(git checkout [ARGS] -b BRANCH START-POINT).
+
+\(fn BRANCH START-POINT &optional ARGS)" t nil)
+
+(autoload 'magit-branch-or-checkout "magit-branch" "\
+Hybrid between `magit-checkout' and `magit-branch-and-checkout'.
+
+Ask the user for an existing branch or revision.  If the user
+input actually can be resolved as a branch or revision, then
+check that out, just like `magit-checkout' would.
+
+Otherwise create and checkout a new branch using the input as
+its name.  Before doing so read the starting-point for the new
+branch.  This is similar to what `magit-branch-and-checkout'
+does.
+
+\(fn ARG &optional START-POINT)" t nil)
+
+(autoload 'magit-branch-checkout "magit-branch" "\
+Checkout an existing or new local branch.
+
+Read a branch name from the user offering all local branches and
+a subset of remote branches as candidates.  Omit remote branches
+for which a local branch by the same name exists from the list
+of candidates.  The user can also enter a completely new branch
+name.
+
+- If the user selects an existing local branch, then check that
+  out.
+
+- If the user selects a remote branch, then create and checkout
+  a new local branch with the same name.  Configure the selected
+  remote branch as push target.
+
+- If the user enters a new branch name, then create and check
+  that out, after also reading the starting-point from the user.
+
+In the latter two cases the upstream is also set.  Whether it is
+set to the chosen START-POINT or something else depends on the
+value of `magit-branch-adjust-remote-upstream-alist', just like
+when using `magit-branch-and-checkout'.
+
+\(fn BRANCH &optional START-POINT)" t nil)
+
+(autoload 'magit-branch-orphan "magit-branch" "\
+Create and checkout an orphan BRANCH with contents from revision START-POINT.
+
+\(git checkout --orphan [ARGS] BRANCH START-POINT).
+
+\(fn BRANCH START-POINT &optional ARGS)" t nil)
+
+(autoload 'magit-branch-pull-request "magit-branch" "\
+Create and configure a new branch from a pull-request.
+Please see the manual for more information.
+
+\(fn PR)" t nil)
+
+(autoload 'magit-branch-spinoff "magit-branch" "\
+Create new branch from the unpushed commits.
+
+Create and checkout a new branch starting at and tracking the
+current branch.  That branch in turn is reset to the last commit
+it shares with its upstream.  If the current branch has no
+upstream or no unpushed commits, then the new branch is created
+anyway and the previously current branch is not touched.
+
+This is useful to create a feature branch after work has already
+began on the old branch (likely but not necessarily \"master\").
+
+If the current branch is a member of the value of option
+`magit-branch-prefer-remote-upstream' (which see), then the
+current branch will be used as the starting point as usual, but
+the upstream of the starting-point may be used as the upstream
+of the new branch, instead of the starting-point itself.
+
+If optional FROM is non-nil, then the source branch is reset
+to `FROM~', instead of to the last commit it shares with its
+upstream.  Interactively, FROM is only ever non-nil, if the
+region selects some commits, and among those commits, FROM is
+the commit that is the fewest commits ahead of the source
+branch.
+
+The commit at the other end of the selection actually does not
+matter, all commits between FROM and `HEAD' are moved to the new
+branch.  If FROM is not reachable from `HEAD' or is reachable
+from the source branch's upstream, then an error is raised.
+
+\(fn BRANCH &optional FROM &rest ARGS)" t nil)
+
+(autoload 'magit-branch-reset "magit-branch" "\
+Reset a branch to the tip of another branch or any other commit.
+
+When the branch being reset is the current branch, then do a
+hard reset.  If there are any uncommitted changes, then the user
+has to confirm the reset because those changes would be lost.
+
+This is useful when you have started work on a feature branch but
+realize it's all crap and want to start over.
+
+When resetting to another branch and a prefix argument is used,
+then also set the target branch as the upstream of the branch
+that is being reset.
+
+\(fn BRANCH TO &optional ARGS SET-UPSTREAM)" t nil)
+
+(autoload 'magit-branch-delete "magit-branch" "\
+Delete one or multiple branches.
+If the region marks multiple branches, then offer to delete
+those, otherwise prompt for a single branch to be deleted,
+defaulting to the branch at point.
+
+\(fn BRANCHES &optional FORCE)" t nil)
+
+(autoload 'magit-branch-rename "magit-branch" "\
+Rename the branch named OLD to NEW.
+
+With a prefix argument FORCE, rename even if a branch named NEW
+already exists.
+
+If `branch.OLD.pushRemote' is set, then unset it.  Depending on
+the value of `magit-branch-rename-push-target' (which see) maybe
+set `branch.NEW.pushRemote' and maybe rename the push-target on
+the remote.
+
+\(fn OLD NEW &optional FORCE)" t nil)
+
+(autoload 'magit-branch-shelve "magit-branch" "\
+Shelve a BRANCH.
+Rename \"refs/heads/BRANCH\" to \"refs/shelved/BRANCH\",
+and also rename the respective reflog file.
+
+\(fn BRANCH)" t nil)
+
+(autoload 'magit-branch-unshelve "magit-branch" "\
+Unshelve a BRANCH
+Rename \"refs/shelved/BRANCH\" to \"refs/heads/BRANCH\",
+and also rename the respective reflog file.
+
+\(fn BRANCH)" t nil)
+
+(autoload 'magit-branch-config-popup "magit-branch" "\
+Popup console for setting branch variables.
+
+\(fn BRANCH)" t nil)
+
+(autoload 'magit-edit-branch*description "magit-branch" "\
+Edit the description of the current branch.
+With a prefix argument edit the description of another branch.
+
+The description for the branch named NAME is stored in the Git
+variable `branch.<name>.description'.
+
+\(fn BRANCH)" t nil)
+
+(autoload 'magit-set-branch*merge/remote "magit-branch" "\
+Set or unset the upstream of the current branch.
+With a prefix argument do so for another branch.
+
+When the branch in question already has an upstream then simply
+unsets it.  Invoke this command again to set another upstream.
+
+Together the Git variables `branch.<name>.remote' and
+`branch.<name>.merge' define the upstream branch of the local
+branch named NAME.  The value of `branch.<name>.remote' is the
+name of the upstream remote.  The value of `branch.<name>.merge'
+is the full reference of the upstream branch, on the remote.
+
+Non-interactively, when UPSTREAM is non-nil, then always set it
+as the new upstream, regardless of whether another upstream was
+already set.  When nil, then always unset.
+
+\(fn BRANCH UPSTREAM)" t nil)
+
+(autoload 'magit-cycle-branch*rebase "magit-branch" "\
+Cycle the value of `branch.<name>.rebase' for the current branch.
+With a prefix argument cycle the value for another branch.
+
+The Git variables `branch.<name>.rebase' controls whether pulling
+into the branch named NAME is done by rebasing that branch onto
+the fetched branch or by merging that branch.
+
+When `true' then pulling is done by rebasing.
+When `false' then pulling is done by merging.
+
+When that variable is undefined then the value of `pull.rebase'
+is used instead.  It defaults to `false'.
+
+\(fn BRANCH)" t nil)
+
+(autoload 'magit-cycle-branch*pushRemote "magit-branch" "\
+Cycle the value of `branch.<name>.pushRemote' for the current branch.
+With a prefix argument cycle the value for another branch.
+
+The Git variable `branch.<name>.pushRemote' specifies the remote
+that the branch named NAME is usually pushed to.  The value has
+to be the name of an existing remote.
+
+If that variable is undefined, then the value of the Git variable
+`remote.pushDefault' is used instead, provided that it is defined,
+which by default it is not.
+
+\(fn BRANCH)" t nil)
+
+(autoload 'magit-cycle-pull\.rebase "magit-branch" "\
+Cycle the repository-local value of `pull.rebase'.
+
+The Git variable `pull.rebase' specifies whether pulling is done
+by rebasing or by merging.  It can be overwritten using the Git
+variable `branch.<name>.rebase'.
+
+When `true' then pulling is done by rebasing.
+When `false' (the default) then pulling is done by merging.
+
+\(fn)" t nil)
+
+(autoload 'magit-cycle-remote\.pushDefault "magit-branch" "\
+Cycle the repository-local value of `remote.pushDefault'.
+
+The Git variable `remote.pushDefault' specifies the remote that
+local branches are usually pushed to.  It can be overwritten
+using the Git variable `branch.<name>.pushRemote'.
+
+\(fn)" t nil)
+
+(autoload 'magit-cycle-branch*autoSetupMerge "magit-branch" "\
+Cycle the repository-local value of `branch.autoSetupMerge'.
+
+The Git variable `branch.autoSetupMerge' under what circumstances
+creating a branch (named NAME) should result in the variables
+`branch.<name>.merge' and `branch.<name>.remote' being set
+according to the starting point used to create the branch.  If
+the starting point isn't a branch, then these variables are never
+set.
+
+When `always' then the variables are set regardless of whether
+the starting point is a local or a remote branch.
+
+When `true' (the default) then the variable are set when the
+starting point is a remote branch, but not when it is a local
+branch.
+
+When `false' then the variables are never set.
+
+\(fn)" t nil)
+
+(autoload 'magit-cycle-branch*autoSetupRebase "magit-branch" "\
+Cycle the repository-local value of `branch.autoSetupRebase'.
+
+The Git variable `branch.autoSetupRebase' specifies whether
+creating a branch (named NAME) should result in the variable
+`branch.<name>.rebase' being set to `true'.
+
+When `always' then the variable is set regardless of whether the
+starting point is a local or a remote branch.
+
+When `local' then the variable are set when the starting point
+is a local branch, but not when it is a remote branch.
+
+When `remote' then the variable are set when the starting point
+is a remote branch, but not when it is a local branch.
+
+When `never' (the default) then the variable is never set.
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "magit-collab" "magit-collab.el" (23377 61608
+;;;;;;  713113 133000))
+;;; Generated autoloads from magit-collab.el
+
+(autoload 'magit-browse-pull-request "magit-collab" "\
+Visit pull-request PR using `browse-url'.
+
+Currently this only supports Github, but that restriction will
+be lifted eventually to support other Git forges.
+
+\(fn PR)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "magit-commit" "magit-commit.el" (23377 61608
+;;;;;;  672215 898000))
+;;; Generated autoloads from magit-commit.el
+
+(autoload 'magit-commit "magit-commit" "\
+Create a new commit on `HEAD'.
+With a prefix argument, amend to the commit at `HEAD' instead.
+
+\(git commit [--amend] ARGS)
+
+\(fn &optional ARGS)" t nil)
+
+(autoload 'magit-commit-amend "magit-commit" "\
+Amend the last commit.
+
+\(git commit --amend ARGS)
+
+\(fn &optional ARGS)" t nil)
+
+(autoload 'magit-commit-extend "magit-commit" "\
+Amend the last commit, without editing the message.
+
+With a prefix argument keep the committer date, otherwise change
+it.  The option `magit-commit-extend-override-date' can be used
+to inverse the meaning of the prefix argument.
+\(git commit
+--amend --no-edit)
+
+\(fn &optional ARGS OVERRIDE-DATE)" t nil)
+
+(autoload 'magit-commit-reword "magit-commit" "\
+Reword the last commit, ignoring staged changes.
+
+With a prefix argument keep the committer date, otherwise change
+it.  The option `magit-commit-reword-override-date' can be used
+to inverse the meaning of the prefix argument.
+
+Non-interactively respect the optional OVERRIDE-DATE argument
+and ignore the option.
+
+\(git commit --amend --only)
+
+\(fn &optional ARGS OVERRIDE-DATE)" t nil)
+
+(autoload 'magit-commit-fixup "magit-commit" "\
+Create a fixup commit.
+
+With a prefix argument the target COMMIT has to be confirmed.
+Otherwise the commit at point may be used without confirmation
+depending on the value of option `magit-commit-squash-confirm'.
+
+\(fn &optional COMMIT ARGS)" t nil)
+
+(autoload 'magit-commit-squash "magit-commit" "\
+Create a squash commit, without editing the squash message.
+
+With a prefix argument the target COMMIT has to be confirmed.
+Otherwise the commit at point may be used without confirmation
+depending on the value of option `magit-commit-squash-confirm'.
+
+\(fn &optional COMMIT ARGS)" t nil)
+
+(autoload 'magit-commit-augment "magit-commit" "\
+Create a squash commit, editing the squash message.
+
+With a prefix argument the target COMMIT has to be confirmed.
+Otherwise the commit at point may be used without confirmation
+depending on the value of option `magit-commit-squash-confirm'.
+
+\(fn &optional COMMIT ARGS)" t nil)
+
+(autoload 'magit-commit-instant-fixup "magit-commit" "\
+Create a fixup commit targeting COMMIT and instantly rebase.
+
+\(fn &optional COMMIT ARGS)" t nil)
+
+(autoload 'magit-commit-instant-squash "magit-commit" "\
+Create a squash commit targeting COMMIT and instantly rebase.
+
+\(fn &optional COMMIT ARGS)" t nil)
+
+(autoload 'magit-commit-reshelve "magit-commit" "\
+Change the committer date and possibly the author date of `HEAD'.
+
+If you are the author of `HEAD', then both dates are changed,
+otherwise only the committer date.  The current time is used
+as the initial minibuffer input and the original author (if
+that is you) or committer date is available as the previous
+history element.
+
+\(fn DATE)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "magit-diff" "magit-diff.el" (23377 61608 717182
+;;;;;;  47000))
+;;; Generated autoloads from magit-diff.el
+
+(autoload 'magit-diff-popup "magit-diff" "\
+Popup console for diff commands.
+
+\(fn ARG)" t nil)
+
+(autoload 'magit-diff-buffer-file-popup "magit-diff" "\
+Popup console for diff commands.
+
+This is a variant of `magit-diff-popup' which shows the same popup
+but which limits the diff to the file being visited in the current
+buffer.
+
+\(fn)" t nil)
+
+(autoload 'magit-diff-dwim "magit-diff" "\
+Show changes for the thing at point.
+
+\(fn &optional ARGS FILES)" t nil)
+
+(autoload 'magit-diff "magit-diff" "\
+Show differences between two commits.
+
+REV-OR-RANGE should be a range or a single revision.  If it is a
+revision, then show changes in the working tree relative to that
+revision.  If it is a range, but one side is omitted, then show
+changes relative to `HEAD'.
+
+If the region is active, use the revisions on the first and last
+line of the region as the two sides of the range.  With a prefix
+argument, instead of diffing the revisions, choose a revision to
+view changes along, starting at the common ancestor of both
+revisions (i.e., use a \"...\" range).
+
+\(fn REV-OR-RANGE &optional ARGS FILES)" t nil)
+
+(autoload 'magit-diff-working-tree "magit-diff" "\
+Show changes between the current working tree and the `HEAD' commit.
+With a prefix argument show changes between the working tree and
+a commit read from the minibuffer.
+
+\(fn &optional REV ARGS FILES)" t nil)
+
+(autoload 'magit-diff-staged "magit-diff" "\
+Show changes between the index and the `HEAD' commit.
+With a prefix argument show changes between the index and
+a commit read from the minibuffer.
+
+\(fn &optional REV ARGS FILES)" t nil)
+
+(autoload 'magit-diff-unstaged "magit-diff" "\
+Show changes between the working tree and the index.
+
+\(fn &optional ARGS FILES)" t nil)
+
+(autoload 'magit-diff-unmerged "magit-diff" "\
+Show changes that are being merged.
+
+\(fn &optional ARGS FILES)" t nil)
+
+(autoload 'magit-diff-while-committing "magit-diff" "\
+While committing, show the changes that are about to be committed.
+While amending, invoking the command again toggles between
+showing just the new changes or all the changes that will
+be committed.
+
+\(fn &optional ARGS)" t nil)
+
+(autoload 'magit-diff-buffer-file "magit-diff" "\
+Show diff for the blob or file visited in the current buffer.
+
+\(fn)" t nil)
+
+(autoload 'magit-diff-paths "magit-diff" "\
+Show changes between any two files on disk.
+
+\(fn A B)" t nil)
+
+(autoload 'magit-show-commit "magit-diff" "\
+Visit the revision at point in another buffer.
+If there is no revision at point or with a prefix argument prompt
+for a revision.
+
+\(fn REV &optional ARGS FILES MODULE)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "magit-ediff" "magit-ediff.el" (23377 61608
+;;;;;;  707096 621000))
+;;; Generated autoloads from magit-ediff.el
+ (autoload 'magit-ediff-popup "magit-ediff" nil t)
+
+(autoload 'magit-ediff-resolve "magit-ediff" "\
+Resolve outstanding conflicts in FILE using Ediff.
+FILE has to be relative to the top directory of the repository.
+
+In the rare event that you want to manually resolve all
+conflicts, including those already resolved by Git, use
+`ediff-merge-revisions-with-ancestor'.
+
+\(fn FILE)" t nil)
+
+(autoload 'magit-ediff-stage "magit-ediff" "\
+Stage and unstage changes to FILE using Ediff.
+FILE has to be relative to the top directory of the repository.
+
+\(fn FILE)" t nil)
+
+(autoload 'magit-ediff-compare "magit-ediff" "\
+Compare REVA:FILEA with REVB:FILEB using Ediff.
+
+FILEA and FILEB have to be relative to the top directory of the
+repository.  If REVA or REVB is nil, then this stands for the
+working tree state.
+
+If the region is active, use the revisions on the first and last
+line of the region.  With a prefix argument, instead of diffing
+the revisions, choose a revision to view changes along, starting
+at the common ancestor of both revisions (i.e., use a \"...\"
+range).
+
+\(fn REVA REVB FILEA FILEB)" t nil)
+
+(autoload 'magit-ediff-dwim "magit-ediff" "\
+Compare, stage, or resolve using Ediff.
+This command tries to guess what file, and what commit or range
+the user wants to compare, stage, or resolve using Ediff.  It
+might only be able to guess either the file, or range or commit,
+in which case the user is asked about the other.  It might not
+always guess right, in which case the appropriate `magit-ediff-*'
+command has to be used explicitly.  If it cannot read the user's
+mind at all, then it asks the user for a command to run.
+
+\(fn)" t nil)
+
+(autoload 'magit-ediff-show-staged "magit-ediff" "\
+Show staged changes using Ediff.
+
+This only allows looking at the changes; to stage, unstage,
+and discard changes using Ediff, use `magit-ediff-stage'.
+
+FILE must be relative to the top directory of the repository.
+
+\(fn FILE)" t nil)
+
+(autoload 'magit-ediff-show-unstaged "magit-ediff" "\
+Show unstaged changes using Ediff.
+
+This only allows looking at the changes; to stage, unstage,
+and discard changes using Ediff, use `magit-ediff-stage'.
+
+FILE must be relative to the top directory of the repository.
+
+\(fn FILE)" t nil)
+
+(autoload 'magit-ediff-show-working-tree "magit-ediff" "\
+Show changes between `HEAD' and working tree using Ediff.
+FILE must be relative to the top directory of the repository.
+
+\(fn FILE)" t nil)
+
+(autoload 'magit-ediff-show-commit "magit-ediff" "\
+Show changes introduced by COMMIT using Ediff.
+
+\(fn COMMIT)" t nil)
+
+(autoload 'magit-ediff-show-stash "magit-ediff" "\
+Show changes introduced by STASH using Ediff.
+`magit-ediff-show-stash-with-index' controls whether a
+three-buffer Ediff is used in order to distinguish changes in the
+stash that were staged.
+
+\(fn STASH)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "magit-extras" "magit-extras.el" (23377 61608
+;;;;;;  673781 218000))
+;;; Generated autoloads from magit-extras.el
+
+(autoload 'magit-run-git-gui "magit-extras" "\
+Run `git gui' for the current git repository.
+
+\(fn)" t nil)
+
+(autoload 'magit-run-git-gui-blame "magit-extras" "\
+Run `git gui blame' on the given FILENAME and COMMIT.
+Interactively run it for the current file and the `HEAD', with a
+prefix or when the current file cannot be determined let the user
+choose.  When the current buffer is visiting FILENAME instruct
+blame to center around the line point is on.
+
+\(fn COMMIT FILENAME &optional LINENUM)" t nil)
+
+(autoload 'magit-run-gitk "magit-extras" "\
+Run `gitk' in the current repository.
+
+\(fn)" t nil)
+
+(autoload 'magit-run-gitk-branches "magit-extras" "\
+Run `gitk --branches' in the current repository.
+
+\(fn)" t nil)
+
+(autoload 'magit-run-gitk-all "magit-extras" "\
+Run `gitk --all' in the current repository.
+
+\(fn)" t nil)
+
+(autoload 'ido-enter-magit-status "magit-extras" "\
+Drop into `magit-status' from file switching.
+
+To make this command available use something like:
+
+  (add-hook \\='ido-setup-hook
+            (lambda ()
+              (define-key ido-completion-map
+                (kbd \"C-x g\") \\='ido-enter-magit-status)))
+
+Starting with Emacs 25.1 the Ido keymaps are defined just once
+instead of every time Ido is invoked, so now you can modify it
+like pretty much every other keymap:
+
+  (define-key ido-common-completion-map
+    (kbd \"C-x g\") \\='ido-enter-magit-status)
+
+\(fn)" t nil)
+
+(autoload 'magit-dired-jump "magit-extras" "\
+Visit file at point using Dired.
+With a prefix argument, visit in another window.  If there
+is no file at point, then instead visit `default-directory'.
+
+\(fn &optional OTHER-WINDOW)" t nil)
+
+(autoload 'magit-dired-log "magit-extras" "\
+Show log for all marked files, or the current file.
+
+\(fn &optional FOLLOW)" t nil)
+
+(autoload 'magit-do-async-shell-command "magit-extras" "\
+Open FILE with `dired-do-async-shell-command'.
+Interactively, open the file at point.
+
+\(fn FILE)" t nil)
+
+(autoload 'magit-previous-line "magit-extras" "\
+Like `previous-line' but with Magit-specific shift-selection.
+
+Magit's selection mechanism is based on the region but selects an
+area that is larger than the region.  This causes `previous-line'
+when invoked while holding the shift key to move up one line and
+thereby select two lines.  When invoked inside a hunk body this
+command does not move point on the first invocation and thereby
+it only selects a single line.  Which inconsistency you prefer
+is a matter of preference.
+
+\(fn &optional ARG TRY-VSCROLL)" t nil)
+
+(function-put 'magit-previous-line 'interactive-only '"use `forward-line' with negative argument instead.")
+
+(autoload 'magit-next-line "magit-extras" "\
+Like `next-line' but with Magit-specific shift-selection.
+
+Magit's selection mechanism is based on the region but selects
+an area that is larger than the region.  This causes `next-line'
+when invoked while holding the shift key to move down one line
+and thereby select two lines.  When invoked inside a hunk body
+this command does not move point on the first invocation and
+thereby it only selects a single line.  Which inconsistency you
+prefer is a matter of preference.
+
+\(fn &optional ARG TRY-VSCROLL)" t nil)
+
+(function-put 'magit-next-line 'interactive-only 'forward-line)
+
+(autoload 'magit-clean "magit-extras" "\
+Remove untracked files from the working tree.
+With a prefix argument also remove ignored files,
+with two prefix arguments remove ignored files only.
+
+\(git clean -f -d [-x|-X])
+
+\(fn &optional ARG)" t nil)
+ (autoload 'magit-ignore-popup "extras" nil t)
+
+(autoload 'magit-gitignore "magit-extras" "\
+Instruct Git to ignore FILE-OR-PATTERN.
+With a prefix argument only ignore locally.
+
+\(fn FILE-OR-PATTERN &optional LOCAL)" t nil)
+
+(autoload 'magit-gitignore-locally "magit-extras" "\
+Instruct Git to locally ignore FILE-OR-PATTERN.
+
+\(fn FILE-OR-PATTERN)" t nil)
+
+(autoload 'magit-add-change-log-entry "magit-extras" "\
+Find change log file and add date entry and item for current change.
+This differs from `add-change-log-entry' (which see) in that
+it acts on the current hunk in a Magit buffer instead of on
+a position in a file-visiting buffer.
+
+\(fn &optional WHOAMI FILE-NAME OTHER-WINDOW)" t nil)
+
+(autoload 'magit-add-change-log-entry-other-window "magit-extras" "\
+Find change log file in other window and add entry and item.
+This differs from `add-change-log-entry-other-window' (which see)
+in that it acts on the current hunk in a Magit buffer instead of
+on a position in a file-visiting buffer.
+
+\(fn &optional WHOAMI FILE-NAME)" t nil)
+
+(autoload 'magit-edit-line-commit "magit-extras" "\
+Edit the commit that added the current line.
+
+With a prefix argument edit the commit that removes the line,
+if any.  The commit is determined using `git blame' and made
+editable using `git rebase --interactive' if it is reachable
+from `HEAD', or by checking out the commit (or a branch that
+points at it) otherwise.
+
+\(fn &optional TYPE)" t nil)
+
+(autoload 'magit-reshelve-since "magit-extras" "\
+Change the author and committer dates of the commits since REV.
+
+Ask the user for the first reachable commit whose dates should
+be changed.  The read the new date for that commit.  The initial
+minibuffer input and the previous history element offer good
+values.  The next commit will be created one minute later and so
+on.
+
+This command is only intended for interactive use and should only
+be used on highly rearranged and unpublished history.
+
+\(fn REV)" t nil)
+
+(autoload 'magit-copy-section-value "magit-extras" "\
+Save the value of the current section for later use.
+
+Save the section value to the `kill-ring', and, provided that
+the current section is a commit, branch, or tag section, push
+the (referenced) revision to the `magit-revision-stack' for use
+with `magit-pop-revision-stack'.
+
+When the current section is a branch or a tag, and a prefix
+argument is used, then save the revision at its tip to the
+`kill-ring' instead of the reference name.
+
+When the region is active, then save that to the `kill-ring',
+like `kill-ring-save' would, instead of behaving as described
+above.
+
+\(fn)" t nil)
+
+(autoload 'magit-copy-buffer-revision "magit-extras" "\
+Save the revision of the current buffer for later use.
+
+Save the revision shown in the current buffer to the `kill-ring'
+and push it to the `magit-revision-stack'.
+
+This command is mainly intended for use in `magit-revision-mode'
+buffers, the only buffers where it is always unambiguous exactly
+which revision should be saved.
+
+Most other Magit buffers usually show more than one revision, in
+some way or another, so this command has to select one of them,
+and that choice might not always be the one you think would have
+been the best pick.
+
+In such buffers it is often more useful to save the value of
+the current section instead, using `magit-copy-section-value'.
+
+When the region is active, then save that to the `kill-ring',
+like `kill-ring-save' would, instead of behaving as described
+above.
+
+\(fn)" t nil)
+
+(autoload 'magit-abort-dwim "magit-extras" "\
+Abort current operation.
+Depending on the context, this will abort a merge, a rebase, a
+patch application, a cherry-pick, a revert, or a bisect.
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "magit-files" "magit-files.el" (23377 61608
+;;;;;;  683612 956000))
+;;; Generated autoloads from magit-files.el
+
+(autoload 'magit-find-file "magit-files" "\
+View FILE from REV.
+Switch to a buffer visiting blob REV:FILE,
+creating one if none already exists.
+
+\(fn REV FILE)" t nil)
+
+(autoload 'magit-find-file-other-window "magit-files" "\
+View FILE from REV, in another window.
+Like `magit-find-file', but create a new window or reuse an
+existing one.
+
+\(fn REV FILE)" t nil)
+ (autoload 'magit-file-popup "magit" nil t)
+
+(defvar global-magit-file-mode t "\
+Non-nil if Global Magit-File mode is enabled.
+See the `global-magit-file-mode' command
+for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `global-magit-file-mode'.")
+
+(custom-autoload 'global-magit-file-mode "magit-files" nil)
+
+(autoload 'global-magit-file-mode "magit-files" "\
+Toggle Magit-File mode in all buffers.
+With prefix ARG, enable Global Magit-File mode if ARG is positive;
+otherwise, disable it.  If called from Lisp, enable the mode if
+ARG is omitted or nil.
+
+Magit-File mode is enabled in all buffers where
+`magit-file-mode-turn-on' would do it.
+See `magit-file-mode' for more information on Magit-File mode.
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'magit-file-checkout "magit-files" "\
+Checkout FILE from REV.
+
+\(fn REV FILE)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "magit-imenu" "magit-imenu.el" (23377 61608
+;;;;;;  705245 5000))
+;;; Generated autoloads from magit-imenu.el
+
+(autoload 'magit-imenu--log-prev-index-position-function "magit-imenu" "\
+Move point to previous line in current buffer.
+This function is used as a value for
+`imenu-prev-index-position-function'.
+
+\(fn)" nil nil)
+
+(autoload 'magit-imenu--log-extract-index-name-function "magit-imenu" "\
+Return imenu name for line at point.
+This function is used as a value for
+`imenu-extract-index-name-function'.  Point should be at the
+beginning of the line.
+
+\(fn)" nil nil)
+
+(autoload 'magit-imenu--diff-prev-index-position-function "magit-imenu" "\
+Move point to previous file line in current buffer.
+This function is used as a value for
+`imenu-prev-index-position-function'.
+
+\(fn)" nil nil)
+
+(autoload 'magit-imenu--diff-extract-index-name-function "magit-imenu" "\
+Return imenu name for line at point.
+This function is used as a value for
+`imenu-extract-index-name-function'.  Point should be at the
+beginning of the line.
+
+\(fn)" nil nil)
+
+(autoload 'magit-imenu--status-create-index-function "magit-imenu" "\
+Return an alist of all imenu entries in current buffer.
+This function is used as a value for
+`imenu-create-index-function'.
+
+\(fn)" nil nil)
+
+(autoload 'magit-imenu--refs-create-index-function "magit-imenu" "\
+Return an alist of all imenu entries in current buffer.
+This function is used as a value for
+`imenu-create-index-function'.
+
+\(fn)" nil nil)
+
+(autoload 'magit-imenu--cherry-create-index-function "magit-imenu" "\
+Return an alist of all imenu entries in current buffer.
+This function is used as a value for
+`imenu-create-index-function'.
+
+\(fn)" nil nil)
+
+(autoload 'magit-imenu--submodule-prev-index-position-function "magit-imenu" "\
+Move point to previous line in magit-submodule-list buffer.
+This function is used as a value for
+`imenu-prev-index-position-function'.
+
+\(fn)" nil nil)
+
+(autoload 'magit-imenu--submodule-extract-index-name-function "magit-imenu" "\
+Return imenu name for line at point.
+This function is used as a value for
+`imenu-extract-index-name-function'.  Point should be at the
+beginning of the line.
+
+\(fn)" nil nil)
+
+(autoload 'magit-imenu--repolist-prev-index-position-function "magit-imenu" "\
+Move point to previous line in magit-repolist buffer.
+This function is used as a value for
+`imenu-prev-index-position-function'.
+
+\(fn)" nil nil)
+
+(autoload 'magit-imenu--repolist-extract-index-name-function "magit-imenu" "\
+Return imenu name for line at point.
+This function is used as a value for
+`imenu-extract-index-name-function'.  Point should be at the
+beginning of the line.
+
+\(fn)" nil nil)
+
+(autoload 'magit-imenu--process-prev-index-position-function "magit-imenu" "\
+Move point to previous process in magit-process buffer.
+This function is used as a value for
+`imenu-prev-index-position-function'.
+
+\(fn)" nil nil)
+
+(autoload 'magit-imenu--process-extract-index-name-function "magit-imenu" "\
+Return imenu name for line at point.
+This function is used as a value for
+`imenu-extract-index-name-function'.  Point should be at the
+beginning of the line.
+
+\(fn)" nil nil)
+
+(autoload 'magit-imenu--rebase-prev-index-position-function "magit-imenu" "\
+Move point to previous commit in git-rebase buffer.
+This function is used as a value for
+`imenu-prev-index-position-function'.
+
+\(fn)" nil nil)
+
+(autoload 'magit-imenu--rebase-extract-index-name-function "magit-imenu" "\
+Return imenu name for line at point.
+This function is used as a value for
+`imenu-extract-index-name-function'.  Point should be at the
+beginning of the line.
+
+\(fn)" nil nil)
+
+;;;***
+
+;;;### (autoloads nil "magit-log" "magit-log.el" (23377 61608 709078
+;;;;;;  137000))
+;;; Generated autoloads from magit-log.el
+
+(autoload 'magit-log-buffer-file-popup "magit-log" "\
+Popup console for log commands.
+
+This is a variant of `magit-log-popup' which shows the same popup
+but which limits the log to the file being visited in the current
+buffer.
+
+\(fn)" t nil)
+
+(autoload 'magit-log-current "magit-log" "\
+Show log for the current branch.
+When `HEAD' is detached or with a prefix argument show log for
+one or more revs read from the minibuffer.
+
+\(fn REVS &optional ARGS FILES)" t nil)
+
+(autoload 'magit-log "magit-log" "\
+Show log for one or more revs read from the minibuffer.
+The user can input any revision or revisions separated by a
+space, or even ranges, but only branches and tags, and a
+representation of the commit at point, are available as
+completion candidates.
+
+\(fn REVS &optional ARGS FILES)" t nil)
+
+(autoload 'magit-log-head "magit-log" "\
+Show log for `HEAD'.
+
+\(fn &optional ARGS FILES)" t nil)
+
+(autoload 'magit-log-branches "magit-log" "\
+Show log for all local branches and `HEAD'.
+
+\(fn &optional ARGS FILES)" t nil)
+
+(autoload 'magit-log-all-branches "magit-log" "\
+Show log for all local and remote branches and `HEAD'.
+
+\(fn &optional ARGS FILES)" t nil)
+
+(autoload 'magit-log-all "magit-log" "\
+Show log for all references and `HEAD'.
+
+\(fn &optional ARGS FILES)" t nil)
+
+(autoload 'magit-log-buffer-file "magit-log" "\
+Show log for the blob or file visited in the current buffer.
+With a prefix argument or when `--follow' is part of
+`magit-log-arguments', then follow renames.  When the region is
+active, restrict the log to the lines that the region touches.
+
+\(fn &optional FOLLOW BEG END)" t nil)
+
+(autoload 'magit-log-trace-definition "magit-log" "\
+Show log for the definition at point.
+
+\(fn FILE FN REV)" t nil)
+
+(autoload 'magit-reflog-current "magit-log" "\
+Display the reflog of the current branch.
+
+\(fn)" t nil)
+
+(autoload 'magit-reflog "magit-log" "\
+Display the reflog of a branch.
+
+\(fn REF)" t nil)
+
+(autoload 'magit-reflog-head "magit-log" "\
+Display the `HEAD' reflog.
+
+\(fn)" t nil)
+
+(autoload 'magit-log-move-to-parent "magit-log" "\
+Move to the Nth parent of the current commit.
+
+\(fn &optional N)" t nil)
+
+(autoload 'magit-cherry "magit-log" "\
+Show commits in a branch that are not merged in the upstream branch.
+
+\(fn HEAD UPSTREAM)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "magit-merge" "magit-merge.el" (23377 61608
+;;;;;;  701204 423000))
+;;; Generated autoloads from magit-merge.el
+ (autoload 'magit-merge-popup "magit" nil t)
+
+(autoload 'magit-merge "magit-merge" "\
+Merge commit REV into the current branch; using default message.
+
+Unless there are conflicts or a prefix argument is used create a
+merge commit using a generic commit message and without letting
+the user inspect the result.  With a prefix argument pretend the
+merge failed to give the user the opportunity to inspect the
+merge.
+
+\(git merge --no-edit|--no-commit [ARGS] REV)
+
+\(fn REV &optional ARGS NOCOMMIT)" t nil)
+
+(autoload 'magit-merge-editmsg "magit-merge" "\
+Merge commit REV into the current branch; and edit message.
+Perform the merge and prepare a commit message but let the user
+edit it.
+
+\(git merge --edit --no-ff [ARGS] REV)
+
+\(fn REV &optional ARGS)" t nil)
+
+(autoload 'magit-merge-nocommit "magit-merge" "\
+Merge commit REV into the current branch; pretending it failed.
+Pretend the merge failed to give the user the opportunity to
+inspect the merge and change the commit message.
+
+\(git merge --no-commit --no-ff [ARGS] REV)
+
+\(fn REV &optional ARGS)" t nil)
+
+(autoload 'magit-merge-into "magit-merge" "\
+Merge the current branch into BRANCH and remove the former.
+
+Before merging, force push the source branch to its push-remote,
+provided the respective remote branch already exists, ensuring
+that the respective pull-request (if any) won't get stuck on some
+obsolete version of the commits that are being merged.  Finally
+if `magit-branch-pull-request' was used to create the merged
+branch, then also remove the respective remote branch.
+
+\(fn BRANCH &optional ARGS)" t nil)
+
+(autoload 'magit-merge-absorb "magit-merge" "\
+Merge BRANCH into the current branch and remove the former.
+
+Before merging, force push the source branch to its push-remote,
+provided the respective remote branch already exists, ensuring
+that the respective pull-request (if any) won't get stuck on some
+obsolete version of the commits that are being merged.  Finally
+if `magit-branch-pull-request' was used to create the merged
+branch, then also remove the respective remote branch.
+
+\(fn BRANCH &optional ARGS)" t nil)
+
+(autoload 'magit-merge-squash "magit-merge" "\
+Squash commit REV into the current branch; don't create a commit.
+
+\(git merge --squash REV)
+
+\(fn REV)" t nil)
+
+(autoload 'magit-merge-preview "magit-merge" "\
+Preview result of merging REV into the current branch.
+
+\(fn REV)" t nil)
+
+(autoload 'magit-merge-abort "magit-merge" "\
+Abort the current merge operation.
+
+\(git merge --abort)
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "magit-notes" "magit-notes.el" (23377 61608
+;;;;;;  732436 253000))
+;;; Generated autoloads from magit-notes.el
+ (autoload 'magit-notes-popup "magit" nil t)
+
+;;;***
+
+;;;### (autoloads nil "magit-refs" "magit-refs.el" (23377 61608 675161
+;;;;;;  442000))
+;;; Generated autoloads from magit-refs.el
+
+(autoload 'magit-show-refs-popup "magit-refs" "\
+Popup console for `magit-show-refs'.
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'magit-show-refs-head "magit-refs" "\
+List and compare references in a dedicated buffer.
+Refs are compared with `HEAD'.
+
+\(fn &optional ARGS)" t nil)
+
+(autoload 'magit-show-refs-current "magit-refs" "\
+List and compare references in a dedicated buffer.
+Refs are compared with the current branch or `HEAD' if
+it is detached.
+
+\(fn &optional ARGS)" t nil)
+
+(autoload 'magit-show-refs "magit-refs" "\
+List and compare references in a dedicated buffer.
+Refs are compared with a branch read from the user.
+
+\(fn &optional REF ARGS)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "magit-remote" "magit-remote.el" (23377 61608
+;;;;;;  726719 889000))
+;;; Generated autoloads from magit-remote.el
+
+(autoload 'magit-clone "magit-remote" "\
+Clone the REPOSITORY to DIRECTORY.
+Then show the status buffer for the new repository.
+
+\(fn REPOSITORY DIRECTORY)" t nil)
+ (autoload 'magit-remote-popup "magit-remote" nil t)
+
+(autoload 'magit-remote-add "magit-remote" "\
+Add a remote named REMOTE and fetch it.
+
+\(fn REMOTE URL &optional ARGS)" t nil)
+
+(autoload 'magit-remote-rename "magit-remote" "\
+Rename the remote named OLD to NEW.
+
+\(fn OLD NEW)" t nil)
+
+(autoload 'magit-remote-remove "magit-remote" "\
+Delete the remote named REMOTE.
+
+\(fn REMOTE)" t nil)
+
+(autoload 'magit-remote-prune "magit-remote" "\
+Remove stale remote-tracking branches for REMOTE.
+
+\(fn REMOTE)" t nil)
+
+(autoload 'magit-remote-prune-refspecs "magit-remote" "\
+Remove stale refspecs for REMOTE.
+
+A refspec is stale if there no longer exists at least one branch
+on the remote that would be fetched due to that refspec.  A stale
+refspec is problematic because its existence causes Git to refuse
+to fetch according to the remaining non-stale refspecs.
+
+If only stale refspecs remain, then offer to either delete the
+remote or to replace the stale refspecs with the default refspec.
+
+Also remove the remote-tracking branches that were created due to
+the now stale refspecs.  Other stale branches are not removed.
+
+\(fn REMOTE)" t nil)
+
+(autoload 'magit-remote-set-head "magit-remote" "\
+Set the local representation of REMOTE's default branch.
+Query REMOTE and set the symbolic-ref refs/remotes/<remote>/HEAD
+accordingly.  With a prefix argument query for the branch to be
+used, which allows you to select an incorrect value if you fancy
+doing that.
+
+\(fn REMOTE &optional BRANCH)" t nil)
+
+(autoload 'magit-remote-unset-head "magit-remote" "\
+Unset the local representation of REMOTE's default branch.
+Delete the symbolic-ref \"refs/remotes/<remote>/HEAD\".
+
+\(fn REMOTE)" t nil)
+
+(autoload 'magit-remote-config-popup "magit-remote" "\
+Popup console for setting remote variables.
+
+\(fn REMOTE)" t nil)
+ (autoload 'magit-fetch-popup "magit-remote" nil t)
+
+(autoload 'magit-fetch-from-pushremote "magit-remote" "\
+Fetch from the push-remote of the current branch.
+
+\(fn ARGS)" t nil)
+
+(autoload 'magit-fetch-from-upstream "magit-remote" "\
+Fetch from the upstream repository of the current branch.
+
+\(fn ARGS)" t nil)
+
+(autoload 'magit-fetch "magit-remote" "\
+Fetch from another repository.
+
+\(fn REMOTE ARGS)" t nil)
+
+(autoload 'magit-fetch-branch "magit-remote" "\
+Fetch a BRANCH from a REMOTE.
+
+\(fn REMOTE BRANCH ARGS)" t nil)
+
+(autoload 'magit-fetch-refspec "magit-remote" "\
+Fetch a REFSPEC from a REMOTE.
+
+\(fn REMOTE REFSPEC ARGS)" t nil)
+
+(autoload 'magit-fetch-all "magit-remote" "\
+Fetch from all remotes.
+
+\(fn ARGS)" t nil)
+
+(autoload 'magit-fetch-all-prune "magit-remote" "\
+Fetch from all remotes, and prune.
+Prune remote tracking branches for branches that have been
+removed on the respective remote.
+
+\(fn)" t nil)
+
+(autoload 'magit-fetch-all-no-prune "magit-remote" "\
+Fetch from all remotes.
+
+\(fn)" t nil)
+
+(autoload 'magit-fetch-modules "magit-remote" "\
+Fetch all submodules.
+
+Option `magit-fetch-modules-jobs' controls how many submodules
+are being fetched in parallel.  Also fetch the super-repository,
+because `git-fetch' does not support not doing that.  With a
+prefix argument fetch all remotes.
+
+\(fn &optional ALL)" t nil)
+ (autoload 'magit-pull-popup "magit-remote" nil t)
+ (autoload 'magit-pull-and-fetch-popup "magit-remote" nil t)
+
+(autoload 'magit-pull-from-pushremote "magit-remote" "\
+Pull from the push-remote of the current branch.
+
+\(fn ARGS)" t nil)
+
+(autoload 'magit-pull-from-upstream "magit-remote" "\
+Pull from the upstream of the current branch.
+
+\(fn ARGS)" t nil)
+
+(autoload 'magit-pull "magit-remote" "\
+Pull from a branch read in the minibuffer.
+
+\(fn SOURCE ARGS)" t nil)
+ (autoload 'magit-push-popup "magit-remote" nil t)
+
+(autoload 'magit-push-current-to-pushremote "magit-remote" "\
+Push the current branch to `branch.<name>.pushRemote'.
+If that variable is unset, then push to `remote.pushDefault'.
+
+When `magit-push-current-set-remote-if-missing' is non-nil and
+the push-remote is not configured, then read the push-remote from
+the user, set it, and then push to it.  With a prefix argument
+the push-remote can be changed before pushed to it.
+
+\(fn ARGS &optional PUSH-REMOTE)" t nil)
+
+(autoload 'magit-push-current-to-upstream "magit-remote" "\
+Push the current branch to its upstream branch.
+
+When `magit-push-current-set-remote-if-missing' is non-nil and
+the upstream is not configured, then read the upstream from the
+user, set it, and then push to it.  With a prefix argument the
+upstream can be changed before pushed to it.
+
+\(fn ARGS &optional UPSTREAM)" t nil)
+
+(autoload 'magit-push-current "magit-remote" "\
+Push the current branch to a branch read in the minibuffer.
+
+\(fn TARGET ARGS)" t nil)
+
+(autoload 'magit-push "magit-remote" "\
+Push an arbitrary branch or commit somewhere.
+Both the source and the target are read in the minibuffer.
+
+\(fn SOURCE TARGET ARGS)" t nil)
+
+(autoload 'magit-push-refspecs "magit-remote" "\
+Push one or multiple REFSPECS to a REMOTE.
+Both the REMOTE and the REFSPECS are read in the minibuffer.  To
+use multiple REFSPECS, separate them with commas.  Completion is
+only available for the part before the colon, or when no colon
+is used.
+
+\(fn REMOTE REFSPECS ARGS)" t nil)
+
+(autoload 'magit-push-matching "magit-remote" "\
+Push all matching branches to another repository.
+If multiple remotes exist, then read one from the user.
+If just one exists, use that without requiring confirmation.
+
+\(fn REMOTE &optional ARGS)" t nil)
+
+(autoload 'magit-push-tags "magit-remote" "\
+Push all tags to another repository.
+If only one remote exists, then push to that.  Otherwise prompt
+for a remote, offering the remote configured for the current
+branch as default.
+
+\(fn REMOTE &optional ARGS)" t nil)
+
+(autoload 'magit-push-tag "magit-remote" "\
+Push a tag to another repository.
+
+\(fn TAG REMOTE &optional ARGS)" t nil)
+
+(autoload 'magit-push-implicitly "magit-remote" "\
+Push somewhere without using an explicit refspec.
+
+This command simply runs \"git push -v [ARGS]\".  ARGS are the
+arguments specified in the popup buffer.  No explicit refspec
+arguments are used.  Instead the behavior depends on at least
+these Git variables: `push.default', `remote.pushDefault',
+`branch.<branch>.pushRemote', `branch.<branch>.remote',
+`branch.<branch>.merge', and `remote.<remote>.push'.
+
+To add this command to the push popup add this to your init file:
+
+  (with-eval-after-load \\='magit-remote
+    (magit-define-popup-action \\='magit-push-popup ?P
+      \\='magit-push-implicitly--desc
+      \\='magit-push-implicitly ?p t))
+
+The function `magit-push-implicitly--desc' attempts to predict
+what this command will do.  The value it returns is displayed in
+the popup buffer.
+
+\(fn ARGS)" t nil)
+
+(autoload 'magit-push-to-remote "magit-remote" "\
+Push to REMOTE without using an explicit refspec.
+The REMOTE is read in the minibuffer.
+
+This command simply runs \"git push -v [ARGS] REMOTE\".  ARGS
+are the arguments specified in the popup buffer.  No refspec
+arguments are used.  Instead the behavior depends on at least
+these Git variables: `push.default', `remote.pushDefault',
+`branch.<branch>.pushRemote', `branch.<branch>.remote',
+`branch.<branch>.merge', and `remote.<remote>.push'.
+
+To add this command to the push popup add this to your init file:
+
+  (with-eval-after-load \\='magit-remote
+    (magit-define-popup-action \\='magit-push-popup ?r
+      \\='magit-push-to-remote--desc
+      \\='magit-push-to-remote ?p t))
+
+\(fn REMOTE ARGS)" t nil)
+ (autoload 'magit-patch-popup "magit-remote" nil t)
+
+(autoload 'magit-format-patch "magit-remote" "\
+Create patches for the commits in RANGE.
+When a single commit is given for RANGE, create a patch for the
+changes introduced by that commit (unlike 'git format-patch'
+which creates patches for all commits that are reachable from
+`HEAD' but not from the specified commit).
+
+\(fn RANGE ARGS)" t nil)
+
+(autoload 'magit-request-pull "magit-remote" "\
+Request upstream to pull from you public repository.
+
+URL is the url of your publically accessible repository.
+START is a commit that already is in the upstream repository.
+END is the last commit, usually a branch name, which upstream
+is asked to pull.  START has to be reachable from that commit.
+
+\(fn URL START END)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "magit-repos" "magit-repos.el" (23377 61608
+;;;;;;  715863 1000))
+;;; Generated autoloads from magit-repos.el
+
+(autoload 'magit-list-repositories "magit-repos" "\
+Display a list of repositories.
+
+Use the options `magit-repository-directories' to control which
+repositories are displayed.
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "magit-reset" "magit-reset.el" (23377 61608
+;;;;;;  714563 432000))
+;;; Generated autoloads from magit-reset.el
+ (autoload 'magit-reset-popup "magit" nil t)
+
+(autoload 'magit-reset-index "magit-reset" "\
+Reset the index to COMMIT.
+Keep the head and working tree as-is, so if COMMIT refers to the
+head this effectively unstages all changes.
+
+\(git reset COMMIT .)
+
+\(fn COMMIT)" t nil)
+
+(autoload 'magit-reset "magit-reset" "\
+Reset the head and index to COMMIT, but not the working tree.
+With a prefix argument also reset the working tree.
+
+\(git reset --mixed|--hard COMMIT)
+
+\(fn COMMIT &optional HARD)" t nil)
+
+(autoload 'magit-reset-head "magit-reset" "\
+Reset the head and index to COMMIT, but not the working tree.
+
+\(git reset --mixed COMMIT)
+
+\(fn COMMIT)" t nil)
+
+(autoload 'magit-reset-soft "magit-reset" "\
+Reset the head to COMMIT, but not the index and working tree.
+
+\(git reset --soft REVISION)
+
+\(fn COMMIT)" t nil)
+
+(autoload 'magit-reset-hard "magit-reset" "\
+Reset the head, index, and working tree to COMMIT.
+
+\(git reset --hard REVISION)
+
+\(fn COMMIT)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "magit-sequence" "magit-sequence.el" (23377
+;;;;;;  61608 724035 531000))
+;;; Generated autoloads from magit-sequence.el
+
+(autoload 'magit-sequencer-continue "magit-sequence" "\
+Resume the current cherry-pick or revert sequence.
+
+\(fn)" t nil)
+
+(autoload 'magit-sequencer-skip "magit-sequence" "\
+Skip the stopped at commit during a cherry-pick or revert sequence.
+
+\(fn)" t nil)
+
+(autoload 'magit-sequencer-abort "magit-sequence" "\
+Abort the current cherry-pick or revert sequence.
+This discards all changes made since the sequence started.
+
+\(fn)" t nil)
+ (autoload 'magit-cherry-pick-popup "magit-sequence" nil t)
+
+(autoload 'magit-cherry-pick "magit-sequence" "\
+Copy COMMITS from another branch onto the current branch.
+Prompt for a commit, defaulting to the commit at point.  If
+the region selects multiple commits, then pick all of them,
+without prompting.
+
+\(fn COMMITS &optional ARGS)" t nil)
+
+(autoload 'magit-cherry-apply "magit-sequence" "\
+Apply the changes in COMMITS but do not commit them.
+Prompt for a commit, defaulting to the commit at point.  If
+the region selects multiple commits, then apply all of them,
+without prompting.
+
+\(fn COMMITS &optional ARGS)" t nil)
+
+(autoload 'magit-cherry-harvest "magit-sequence" "\
+Move COMMITS from another BRANCH onto the current branch.
+Remove the COMMITS from BRANCH and stay on the current branch.
+If a conflict occurs, then you have to fix that and finish the
+process manually.
+
+\(fn COMMITS BRANCH &optional ARGS)" t nil)
+
+(autoload 'magit-cherry-donate "magit-sequence" "\
+Move COMMITS from the current branch onto another existing BRANCH.
+Remove COMMITS from the current branch and stay on that branch.
+If a conflict occurs, then you have to fix that and finish the
+process manually.
+
+\(fn COMMITS BRANCH &optional ARGS)" t nil)
+
+(autoload 'magit-cherry-spinout "magit-sequence" "\
+Move COMMITS from the current branch onto a new BRANCH.
+Remove COMMITS from the current branch and stay on that branch.
+If a conflict occurs, then you have to fix that and finish the
+process manually.
+
+\(fn COMMITS BRANCH START-POINT &optional ARGS)" t nil)
+
+(autoload 'magit-cherry-spinoff "magit-sequence" "\
+Move COMMITS from the current branch onto a new BRANCH.
+Remove COMMITS from the current branch and checkout BRANCH.
+If a conflict occurs, then you have to fix that and finish
+the process manually.
+
+\(fn COMMITS BRANCH START-POINT &optional ARGS)" t nil)
+ (autoload 'magit-revert-popup "magit-sequence" nil t)
+
+(autoload 'magit-revert "magit-sequence" "\
+Revert COMMIT by creating a new commit.
+Prompt for a commit, defaulting to the commit at point.  If
+the region selects multiple commits, then revert all of them,
+without prompting.
+
+\(fn COMMIT &optional ARGS)" t nil)
+
+(autoload 'magit-revert-no-commit "magit-sequence" "\
+Revert COMMIT by applying it in reverse to the worktree.
+Prompt for a commit, defaulting to the commit at point.  If
+the region selects multiple commits, then revert all of them,
+without prompting.
+
+\(fn COMMIT &optional ARGS)" t nil)
+ (autoload 'magit-am-popup "magit-sequence" nil t)
+
+(autoload 'magit-am-apply-patches "magit-sequence" "\
+Apply the patches FILES.
+
+\(fn &optional FILES ARGS)" t nil)
+
+(autoload 'magit-am-apply-maildir "magit-sequence" "\
+Apply the patches from MAILDIR.
+
+\(fn &optional MAILDIR ARGS)" t nil)
+
+(autoload 'magit-am-continue "magit-sequence" "\
+Resume the current patch applying sequence.
+
+\(fn)" t nil)
+
+(autoload 'magit-am-skip "magit-sequence" "\
+Skip the stopped at patch during a patch applying sequence.
+
+\(fn)" t nil)
+
+(autoload 'magit-am-abort "magit-sequence" "\
+Abort the current patch applying sequence.
+This discards all changes made since the sequence started.
+
+\(fn)" t nil)
+ (autoload 'magit-rebase-popup "magit-sequence" nil t)
+
+(autoload 'magit-rebase-onto-pushremote "magit-sequence" "\
+Rebase the current branch onto `branch.<name>.pushRemote'.
+If that variable is unset, then rebase onto `remote.pushDefault'.
+
+\(fn ARGS)" t nil)
+
+(autoload 'magit-rebase-onto-upstream "magit-sequence" "\
+Rebase the current branch onto its upstream branch.
+
+\(fn ARGS)" t nil)
+
+(autoload 'magit-rebase "magit-sequence" "\
+Rebase the current branch onto a branch read in the minibuffer.
+All commits that are reachable from `HEAD' but not from the
+selected branch TARGET are being rebased.
+
+\(fn TARGET ARGS)" t nil)
+
+(autoload 'magit-rebase-subset "magit-sequence" "\
+Rebase a subset of the current branch's history onto a new base.
+Rebase commits from START to `HEAD' onto NEWBASE.
+START has to be selected from a list of recent commits.
+
+\(fn NEWBASE START ARGS)" t nil)
+
+(autoload 'magit-rebase-interactive "magit-sequence" "\
+Start an interactive rebase sequence.
+
+\(fn COMMIT ARGS)" t nil)
+
+(autoload 'magit-rebase-autosquash "magit-sequence" "\
+Combine squash and fixup commits with their intended targets.
+
+\(fn ARGS)" t nil)
+
+(autoload 'magit-rebase-edit-commit "magit-sequence" "\
+Edit a single older commit using rebase.
+
+\(fn COMMIT ARGS)" t nil)
+
+(autoload 'magit-rebase-reword-commit "magit-sequence" "\
+Reword a single older commit using rebase.
+
+\(fn COMMIT ARGS)" t nil)
+
+(autoload 'magit-rebase-remove-commit "magit-sequence" "\
+Remove a single older commit using rebase.
+
+\(fn COMMIT ARGS)" t nil)
+
+(autoload 'magit-rebase-continue "magit-sequence" "\
+Restart the current rebasing operation.
+In some cases this pops up a commit message buffer for you do
+edit.  With a prefix argument the old message is reused as-is.
+
+\(fn &optional NOEDIT)" t nil)
+
+(autoload 'magit-rebase-skip "magit-sequence" "\
+Skip the current commit and restart the current rebase operation.
+
+\(fn)" t nil)
+
+(autoload 'magit-rebase-edit "magit-sequence" "\
+Edit the todo list of the current rebase operation.
+
+\(fn)" t nil)
+
+(autoload 'magit-rebase-abort "magit-sequence" "\
+Abort the current rebase operation, restoring the original branch.
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "magit-stash" "magit-stash.el" (23377 61608
+;;;;;;  699236 274000))
+;;; Generated autoloads from magit-stash.el
+ (autoload 'magit-stash-popup "magit-stash" nil t)
+
+(autoload 'magit-stash "magit-stash" "\
+Create a stash of the index and working tree.
+Untracked files are included according to popup arguments.
+One prefix argument is equivalent to `--include-untracked'
+while two prefix arguments are equivalent to `--all'.
+
+\(fn MESSAGE &optional INCLUDE-UNTRACKED)" t nil)
+
+(autoload 'magit-stash-index "magit-stash" "\
+Create a stash of the index only.
+Unstaged and untracked changes are not stashed.  The stashed
+changes are applied in reverse to both the index and the
+worktree.  This command can fail when the worktree is not clean.
+Applying the resulting stash has the inverse effect.
+
+\(fn MESSAGE)" t nil)
+
+(autoload 'magit-stash-worktree "magit-stash" "\
+Create a stash of unstaged changes in the working tree.
+Untracked files are included according to popup arguments.
+One prefix argument is equivalent to `--include-untracked'
+while two prefix arguments are equivalent to `--all'.
+
+\(fn MESSAGE &optional INCLUDE-UNTRACKED)" t nil)
+
+(autoload 'magit-stash-keep-index "magit-stash" "\
+Create a stash of the index and working tree, keeping index intact.
+Untracked files are included according to popup arguments.
+One prefix argument is equivalent to `--include-untracked'
+while two prefix arguments are equivalent to `--all'.
+
+\(fn MESSAGE &optional INCLUDE-UNTRACKED)" t nil)
+
+(autoload 'magit-snapshot "magit-stash" "\
+Create a snapshot of the index and working tree.
+Untracked files are included according to popup arguments.
+One prefix argument is equivalent to `--include-untracked'
+while two prefix arguments are equivalent to `--all'.
+
+\(fn &optional INCLUDE-UNTRACKED)" t nil)
+
+(autoload 'magit-snapshot-index "magit-stash" "\
+Create a snapshot of the index only.
+Unstaged and untracked changes are not stashed.
+
+\(fn)" t nil)
+
+(autoload 'magit-snapshot-worktree "magit-stash" "\
+Create a snapshot of unstaged changes in the working tree.
+Untracked files are included according to popup arguments.
+One prefix argument is equivalent to `--include-untracked'
+while two prefix arguments are equivalent to `--all'.
+
+\(fn &optional INCLUDE-UNTRACKED)" t nil)
+
+(autoload 'magit-stash-apply "magit-stash" "\
+Apply a stash to the working tree.
+Try to preserve the stash index.  If that fails because there
+are staged changes, apply without preserving the stash index.
+
+\(fn STASH)" t nil)
+
+(autoload 'magit-stash-drop "magit-stash" "\
+Remove a stash from the stash list.
+When the region is active offer to drop all contained stashes.
+
+\(fn STASH)" t nil)
+
+(autoload 'magit-stash-clear "magit-stash" "\
+Remove all stashes saved in REF's reflog by deleting REF.
+
+\(fn REF)" t nil)
+
+(autoload 'magit-stash-branch "magit-stash" "\
+Create and checkout a new BRANCH from STASH.
+
+\(fn STASH BRANCH)" t nil)
+
+(autoload 'magit-stash-branch-here "magit-stash" "\
+Create and checkout a new BRANCH and apply STASH.
+The branch is created using `magit-branch', using the current
+branch or `HEAD' as the string-point.
+
+\(fn STASH BRANCH)" t nil)
+
+(autoload 'magit-stash-format-patch "magit-stash" "\
+Create a patch from STASH
+
+\(fn STASH)" t nil)
+
+(autoload 'magit-stash-list "magit-stash" "\
+List all stashes in a buffer.
+
+\(fn)" t nil)
+
+(autoload 'magit-stash-show "magit-stash" "\
+Show all diffs of a stash in a buffer.
+
+\(fn STASH &optional ARGS FILES)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "magit-status" "magit-status.el" (23377 61608
+;;;;;;  711141 472000))
+;;; Generated autoloads from magit-status.el
+
+(autoload 'magit-init "magit-status" "\
+Initialize a Git repository, then show its status.
+
+If the directory is below an existing repository, then the user
+has to confirm that a new one should be created inside.  If the
+directory is the root of the existing repository, then the user
+has to confirm that it should be reinitialized.
+
+Non-interactively DIRECTORY is (re-)initialized unconditionally.
+
+\(fn DIRECTORY)" t nil)
+
+(autoload 'magit-status "magit-status" "\
+Show the status of the current Git repository in a buffer.
+With a prefix argument prompt for a repository to be shown.
+With two prefix arguments prompt for an arbitrary directory.
+If that directory isn't the root of an existing repository,
+then offer to initialize it as a new repository.
+
+\(fn &optional DIRECTORY CACHE)" t nil)
+
+(autoload 'magit-status-internal "magit-status" "\
+
+
+\(fn DIRECTORY)" nil nil)
+
+;;;***
+
+;;;### (autoloads nil "magit-submodule" "magit-submodule.el" (23377
+;;;;;;  61608 733955 282000))
+;;; Generated autoloads from magit-submodule.el
+ (autoload 'magit-submodule-popup "magit-submodule" nil t)
+
+(autoload 'magit-submodule-add "magit-submodule" "\
+Add the repository at URL as a module.
+
+Optional PATH is the path to the module relative to the root of
+the superproject.  If it is nil, then the path is determined
+based on the URL.  Optional NAME is the name of the module.  If
+it is nil, then PATH also becomes the name.
+
+\(fn URL &optional PATH NAME ARGS)" t nil)
+
+(autoload 'magit-submodule-read-name-for-path "magit-submodule" "\
+
+
+\(fn PATH &optional PREFER-SHORT)" nil nil)
+
+(autoload 'magit-submodule-register "magit-submodule" "\
+Register MODULES.
+
+With a prefix argument act on all suitable modules.  Otherwise,
+if the region selects modules, then act on those.  Otherwise, if
+there is a module at point, then act on that.  Otherwise read a
+single module from the user.
+
+\(fn MODULES)" t nil)
+
+(autoload 'magit-submodule-populate "magit-submodule" "\
+Create MODULES working directories, checking out the recorded commits.
+
+With a prefix argument act on all suitable modules.  Otherwise,
+if the region selects modules, then act on those.  Otherwise, if
+there is a module at point, then act on that.  Otherwise read a
+single module from the user.
+
+\(fn MODULES)" t nil)
+
+(autoload 'magit-submodule-update "magit-submodule" "\
+Update MODULES by checking out the recorded commits.
+
+With a prefix argument act on all suitable modules.  Otherwise,
+if the region selects modules, then act on those.  Otherwise, if
+there is a module at point, then act on that.  Otherwise read a
+single module from the user.
+
+\(fn MODULES ARGS)" t nil)
+
+(autoload 'magit-submodule-synchronize "magit-submodule" "\
+Synchronize url configuration of MODULES.
+
+With a prefix argument act on all suitable modules.  Otherwise,
+if the region selects modules, then act on those.  Otherwise, if
+there is a module at point, then act on that.  Otherwise read a
+single module from the user.
+
+\(fn MODULES ARGS)" t nil)
+
+(autoload 'magit-submodule-unpopulate "magit-submodule" "\
+Remove working directories of MODULES.
+
+With a prefix argument act on all suitable modules.  Otherwise,
+if the region selects modules, then act on those.  Otherwise, if
+there is a module at point, then act on that.  Otherwise read a
+single module from the user.
+
+\(fn MODULES ARGS)" t nil)
+
+(autoload 'magit-insert-modules "magit-submodule" "\
+Insert submodule sections.
+Hook `magit-module-sections-hook' controls which module sections
+are inserted, and option `magit-module-sections-nested' controls
+whether they are wrapped in an additional section.
+
+\(fn)" nil nil)
+
+(autoload 'magit-insert-modules-overview "magit-submodule" "\
+Insert sections for all modules.
+For each section insert the path and the output of `git describe --tags',
+or, failing that, the abbreviated HEAD commit hash.
+
+\(fn)" nil nil)
+
+(autoload 'magit-insert-modules-unpulled-from-upstream "magit-submodule" "\
+Insert sections for modules that haven't been pulled from the upstream.
+These sections can be expanded to show the respective commits.
+
+\(fn)" nil nil)
+
+(autoload 'magit-insert-modules-unpulled-from-pushremote "magit-submodule" "\
+Insert sections for modules that haven't been pulled from the push-remote.
+These sections can be expanded to show the respective commits.
+
+\(fn)" nil nil)
+
+(autoload 'magit-insert-modules-unpushed-to-upstream "magit-submodule" "\
+Insert sections for modules that haven't been pushed to the upstream.
+These sections can be expanded to show the respective commits.
+
+\(fn)" nil nil)
+
+(autoload 'magit-insert-modules-unpushed-to-pushremote "magit-submodule" "\
+Insert sections for modules that haven't been pushed to the push-remote.
+These sections can be expanded to show the respective commits.
+
+\(fn)" nil nil)
+
+(autoload 'magit-list-submodules "magit-submodule" "\
+Display a list of the current repository's submodules.
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "magit-subtree" "magit-subtree.el" (23377 61608
+;;;;;;  686421 225000))
+;;; Generated autoloads from magit-subtree.el
+ (autoload 'magit-subtree-popup "magit-subtree" nil t)
+
+(autoload 'magit-subtree-add "magit-subtree" "\
+Add REF from REPOSITORY as a new subtree at PREFIX.
+
+\(fn PREFIX REPOSITORY REF ARGS)" t nil)
+
+(autoload 'magit-subtree-add-commit "magit-subtree" "\
+Add COMMIT as a new subtree at PREFIX.
+
+\(fn PREFIX COMMIT ARGS)" t nil)
+
+(autoload 'magit-subtree-merge "magit-subtree" "\
+Merge COMMIT into the PREFIX subtree.
+
+\(fn PREFIX COMMIT ARGS)" t nil)
+
+(autoload 'magit-subtree-pull "magit-subtree" "\
+Pull REF from REPOSITORY into the PREFIX subtree.
+
+\(fn PREFIX REPOSITORY REF ARGS)" t nil)
+
+(autoload 'magit-subtree-push "magit-subtree" "\
+Extract the history of the subtree PREFIX and push it to REF on REPOSITORY.
+
+\(fn PREFIX REPOSITORY REF ARGS)" t nil)
+
+(autoload 'magit-subtree-split "magit-subtree" "\
+Extract the history of the subtree PREFIX.
+
+\(fn PREFIX COMMIT ARGS)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "magit-tag" "magit-tag.el" (23377 61608 697324
+;;;;;;  819000))
+;;; Generated autoloads from magit-tag.el
+ (autoload 'magit-tag-popup "magit" nil t)
+
+(autoload 'magit-tag "magit-tag" "\
+Create a new tag with the given NAME at REV.
+With a prefix argument annotate the tag.
+
+\(git tag [--annotate] NAME REV)
+
+\(fn NAME REV &optional ARGS)" t nil)
+
+(autoload 'magit-tag-delete "magit-tag" "\
+Delete one or more tags.
+If the region marks multiple tags (and nothing else), then offer
+to delete those, otherwise prompt for a single tag to be deleted,
+defaulting to the tag at point.
+
+\(git tag -d TAGS)
+
+\(fn TAGS)" t nil)
+
+(autoload 'magit-tag-prune "magit-tag" "\
+Offer to delete tags missing locally from REMOTE, and vice versa.
+
+\(fn TAGS REMOTE-TAGS REMOTE)" t nil)
+
+(autoload 'magit-tag-release "magit-tag" "\
+Create an opinionated release tag.
+
+Assume version tags that match \"\\\\`v?[0-9]\\\\(\\\\.[0-9]\\\\)*\\\\'\".
+Prompt for the name of the new tag using the highest existing tag
+as initial input and call \"git tag --annotate --sign -m MSG\" TAG,
+regardless of whether these arguments are enabled in the popup.
+Given a TAG \"v1.2.3\" and a repository \"/path/to/foo-bar\", the
+MESSAGE would be \"Foo-Bar 1.2.3\".
+
+Because it is so opinionated, this command is not available from
+the tag popup by default.
+
+\(fn TAG)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "magit-utils" "magit-utils.el" (23377 61608
+;;;;;;  669551 135000))
+;;; Generated autoloads from magit-utils.el
+
+(autoload 'magit-emacs-Q-command "magit-utils" "\
+Show a shell command that runs an uncustomized Emacs with only Magit loaded.
+See info node `(magit)Debugging Tools' for more information.
+
+\(fn)" t nil)
+
+(autoload 'Info-follow-nearest-node--magit-gitman "magit-utils" "\
+
+
+\(fn FN &optional FORK)" nil nil)
+
+(advice-add 'Info-follow-nearest-node :around 'Info-follow-nearest-node--magit-gitman)
+
+(autoload 'org-man-export--magit-gitman "magit-utils" "\
+
+
+\(fn FN LINK DESCRIPTION FORMAT)" nil nil)
+
+(advice-add 'org-man-export :around 'org-man-export--magit-gitman)
+
+;;;***
+
+;;;### (autoloads nil "magit-wip" "magit-wip.el" (23377 61608 678037
+;;;;;;  61000))
+;;; Generated autoloads from magit-wip.el
+
+(defvar magit-wip-after-save-mode nil "\
+Non-nil if Magit-Wip-After-Save mode is enabled.
+See the `magit-wip-after-save-mode' command
+for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `magit-wip-after-save-mode'.")
+
+(custom-autoload 'magit-wip-after-save-mode "magit-wip" nil)
+
+(autoload 'magit-wip-after-save-mode "magit-wip" "\
+Toggle Magit-Wip-After-Save-Local mode in all buffers.
+With prefix ARG, enable Magit-Wip-After-Save mode if ARG is positive;
+otherwise, disable it.  If called from Lisp, enable the mode if
+ARG is omitted or nil.
+
+Magit-Wip-After-Save-Local mode is enabled in all buffers where
+`magit-wip-after-save-local-mode-turn-on' would do it.
+See `magit-wip-after-save-local-mode' for more information on Magit-Wip-After-Save-Local mode.
+
+\(fn &optional ARG)" t nil)
+
+(defvar magit-wip-after-apply-mode nil "\
+Non-nil if Magit-Wip-After-Apply mode is enabled.
+See the `magit-wip-after-apply-mode' command
+for a description of this minor mode.")
+
+(custom-autoload 'magit-wip-after-apply-mode "magit-wip" nil)
+
+(autoload 'magit-wip-after-apply-mode "magit-wip" "\
+Commit to work-in-progress refs.
+
+After applying a change using any \"apply variant\"
+command (apply, stage, unstage, discard, and reverse) commit the
+affected files to the current wip refs.  For each branch there
+may be two wip refs; one contains snapshots of the files as found
+in the worktree and the other contains snapshots of the entries
+in the index.
+
+\(fn &optional ARG)" t nil)
+
+(defvar magit-wip-before-change-mode nil "\
+Non-nil if Magit-Wip-Before-Change mode is enabled.
+See the `magit-wip-before-change-mode' command
+for a description of this minor mode.")
+
+(custom-autoload 'magit-wip-before-change-mode "magit-wip" nil)
+
+(autoload 'magit-wip-before-change-mode "magit-wip" "\
+Commit to work-in-progress refs before certain destructive changes.
+
+Before invoking a revert command or an \"apply variant\"
+command (apply, stage, unstage, discard, and reverse) commit the
+affected tracked files to the current wip refs.  For each branch
+there may be two wip refs; one contains snapshots of the files
+as found in the worktree and the other contains snapshots of the
+entries in the index.
+
+Only changes to files which could potentially be affected by the
+command which is about to be called are committed.
+
+\(fn &optional ARG)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "magit-worktree" "magit-worktree.el" (23377
+;;;;;;  61608 729696 5000))
+;;; Generated autoloads from magit-worktree.el
+ (autoload 'magit-worktree-popup "magit-worktree" nil t)
+
+(autoload 'magit-worktree-checkout "magit-worktree" "\
+Checkout BRANCH in a new worktree at PATH.
+
+\(fn PATH BRANCH)" t nil)
+
+(autoload 'magit-worktree-branch "magit-worktree" "\
+Create a new BRANCH and check it out in a new worktree at PATH.
+
+\(fn PATH BRANCH START-POINT &optional FORCE)" t nil)
+
+;;;***
+
+;;;### (autoloads nil nil ("magit-core.el" "magit-git.el" "magit-margin.el"
+;;;;;;  "magit-mode.el" "magit-obsolete.el" "magit-pkg.el" "magit-process.el"
+;;;;;;  "magit-section.el") (23377 61608 728148 510000))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; magit-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-autorevert.el b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-autorevert.el
new file mode 100644
index 0000000000..4a5fd619c4
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-autorevert.el
@@ -0,0 +1,260 @@
+;;; magit-autorevert.el --- revert buffers when files in repository change  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2010-2018  The Magit Project Contributors
+;;
+;; You should have received a copy of the AUTHORS.md file which
+;; lists all contributors.  If not, see http://magit.vc/authors.
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; Magit 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, or (at your option)
+;; any later version.
+;;
+;; Magit 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 Magit.  If not, see http://www.gnu.org/licenses.
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'dash)
+
+(require 'magit-git)
+
+(require 'autorevert)
+
+;;; Options
+
+(defgroup magit-auto-revert nil
+  "Revert buffers when files in repository change."
+  :link '(custom-group-link auto-revert)
+  :link '(info-link "(magit)Automatic Reverting of File-Visiting Buffers")
+  :group 'auto-revert
+  :group 'magit-essentials
+  :group 'magit-modes)
+
+(defcustom auto-revert-buffer-list-filter nil
+  "Filter that determines which buffers `auto-revert-buffers' reverts.
+
+This option is provided by `magit', which also redefines
+`auto-revert-buffers' to respect it.  Magit users who do not turn
+on the local mode `auto-revert-mode' themselves, are best served
+by setting the value to `magit-auto-revert-repository-buffers-p'.
+
+However the default is nil, to not disturb users who do use the
+local mode directly.  If you experience delays when running Magit
+commands, then you should consider using one of the predicates
+provided by Magit - especially if you also use Tramp.
+
+Users who do turn on `auto-revert-mode' in buffers in which Magit
+doesn't do that for them, should likely not use any filter.
+Users who turn on `global-auto-revert-mode', do not have to worry
+about this option, because it is disregarded if the global mode
+is enabled."
+  :package-version '(magit . "2.4.2")
+  :group 'auto-revert
+  :group 'magit-auto-revert
+  :group 'magit-related
+  :type '(radio (const :tag "no filter" nil)
+                (function-item magit-auto-revert-buffer-p)
+                (function-item magit-auto-revert-repository-buffer-p)
+                function))
+
+(defcustom magit-auto-revert-tracked-only t
+  "Whether `magit-auto-revert-mode' only reverts tracked files."
+  :package-version '(magit . "2.4.0")
+  :group 'magit-auto-revert
+  :type 'boolean
+  :set (lambda (var val)
+         (set var val)
+         (when (and (bound-and-true-p magit-auto-revert-mode)
+                    (featurep 'magit-autorevert))
+           (magit-auto-revert-mode -1)
+           (magit-auto-revert-mode))))
+
+(defcustom magit-auto-revert-immediately t
+  "Whether Magit reverts buffers immediately.
+
+If this is non-nil and either `global-auto-revert-mode' or
+`magit-auto-revert-mode' is enabled, then Magit immediately
+reverts buffers by explicitly calling `auto-revert-buffers'
+after running git for side-effects.
+
+If `auto-revert-use-notify' is non-nil (and file notifications
+are actually supported), then `magit-auto-revert-immediately'
+does not have to be non-nil, because the reverts happen
+immediately anyway.
+
+If `magit-auto-revert-immediately' and `auto-revert-use-notify'
+are both nil, then reverts happen after `auto-revert-interval'
+seconds of user inactivity.  That is not desirable."
+  :package-version '(magit . "2.4.0")
+  :group 'magit-auto-revert
+  :type 'boolean)
+
+;;; Mode
+
+(defun magit-turn-on-auto-revert-mode-if-desired (&optional file)
+  (if file
+      (--when-let (find-buffer-visiting file)
+        (with-current-buffer it
+          (magit-turn-on-auto-revert-mode-if-desired)))
+    (when (and buffer-file-name
+               (file-readable-p buffer-file-name)
+               (magit-toplevel)
+               (or (not magit-auto-revert-tracked-only)
+                   (magit-file-tracked-p buffer-file-name))
+               (not auto-revert-mode)         ; see #3014
+               (not global-auto-revert-mode)) ; see #3460
+      (auto-revert-mode 1))))
+
+;;;###autoload
+(define-globalized-minor-mode magit-auto-revert-mode auto-revert-mode
+  magit-turn-on-auto-revert-mode-if-desired
+  :package-version '(magit . "2.4.0")
+  :link '(info-link "(magit)Automatic Reverting of File-Visiting Buffers")
+  :group 'magit-auto-revert
+  :group 'magit-essentials
+  ;; - When `global-auto-revert-mode' is enabled, then this mode is
+  ;;   redundant.
+  ;; - In all other cases enable the mode because if buffers are not
+  ;;   automatically reverted that would make many very common tasks
+  ;;   much more cumbersome.
+  ;; - When `magit-revert-buffers' is nil, then the user has opted out
+  ;;   of the automatic reverts while a very old implementation was
+  ;;   still in use.  We continued to respect that setting for another
+  ;;   two and a half years, but no longer do so now.
+  :init-value (and (not global-auto-revert-mode)
+                   (not noninteractive)))
+;; - Unfortunately `:init-value t' only sets the value of the mode
+;;   variable but does not cause the mode function to be called.
+;; - I don't think it works like this on purpose, but since one usually
+;;   should not enable global modes by default, it is understandable.
+;; - If the user has set the variable `magit-auto-revert-mode' to nil
+;;   after loading magit (instead of doing so before loading magit or
+;;   by using the function), then we should still respect that setting.
+;; - If the user has set the obsolete variable `magit-revert-buffers'
+;;   to nil before or after loading magit, then we should still respect
+;;   that setting.
+;; - If the user sets one of these variables after loading magit and
+;;   after `after-init-hook' has run, then that won't have an effect
+;;   and there is nothing we can do about it.
+(defun magit-auto-revert-mode--init-kludge ()
+  "This is an internal kludge to be used on `after-init-hook'.
+Do not use this function elsewhere, and don't remove it from
+the `after-init-hook'.  For more information see the comments
+and code surrounding the definition of this function."
+  (if magit-auto-revert-mode
+      (let ((start (current-time)))
+        (magit-message "Turning on magit-auto-revert-mode...")
+        (magit-auto-revert-mode 1)
+        (magit-message
+         "Turning on magit-auto-revert-mode...done%s"
+         (let ((elapsed (float-time (time-subtract (current-time) start))))
+           (if (> elapsed 0.2)
+               (format " (%.3fs, %s buffers checked)" elapsed
+                       (length (buffer-list)))
+             ""))))
+    (magit-auto-revert-mode -1)))
+(if after-init-time
+    ;; Since `after-init-hook' has already been
+    ;; run, turn the mode on or off right now.
+    (magit-auto-revert-mode--init-kludge)
+  ;; By the time the init file has been fully loaded the
+  ;; values of the relevant variables might have changed.
+  (add-hook 'after-init-hook #'magit-auto-revert-mode--init-kludge t))
+
+(put 'magit-auto-revert-mode 'function-documentation
+     "Toggle Magit Auto Revert mode.
+With a prefix argument ARG, enable Magit Auto Revert mode if ARG
+is positive, and disable it otherwise.  If called from Lisp,
+enable the mode if ARG is omitted or nil.
+
+Magit Auto Revert mode is a global minor mode that reverts
+buffers associated with a file that is located inside a Git
+repository when the file changes on disk.  Use `auto-revert-mode'
+to revert a particular buffer.  Or use `global-auto-revert-mode'
+to revert all file-visiting buffers, not just those that visit
+a file located inside a Git repository.
+
+This global mode works by turning on the buffer-local mode
+`auto-revert-mode' at the time a buffer is first created.  The
+local mode is turned on if the visited file is being tracked in
+a Git repository at the time when the buffer is created.
+
+If `magit-auto-revert-tracked-only' is non-nil (the default),
+then only tracked files are reverted.  But if you stage a
+previously untracked file using `magit-stage', then this mode
+notices that.
+
+Unlike `global-auto-revert-mode', this mode never reverts any
+buffers that are not visiting files.
+
+The behavior of this mode can be customized using the options
+in the `autorevert' and `magit-autorevert' groups.
+
+This function calls the hook `magit-auto-revert-mode-hook'.")
+
+(defun magit-auto-revert-buffers ()
+  (when (and magit-auto-revert-immediately
+             (or global-auto-revert-mode
+                 (and magit-auto-revert-mode auto-revert-buffer-list)))
+    (let ((auto-revert-buffer-list-filter
+           (or auto-revert-buffer-list-filter
+               'magit-auto-revert-repository-buffer-p)))
+      (auto-revert-buffers))))
+
+(defvar magit-auto-revert-toplevel nil)
+
+(when (< emacs-major-version 25)
+  (defvar auto-revert-buffers-counter 1
+    "Incremented each time `auto-revert-buffers' is called"))
+
+(defun magit-auto-revert-buffer-p (buffer)
+  "Return t if BUFFER visits a file inside the current repository.
+The current repository is the one in which `default-directory' is
+located.  If there is no current repository, then return t for
+any BUFFER."
+  (magit-auto-revert-repository-buffer-p buffer t))
+
+(defun magit-auto-revert-repository-buffer-p (buffer &optional fallback)
+  "Return t if BUFFER visits a file inside the current repository.
+The current repository is the one in which `default-directory' is
+located.  If there is no current repository, then return FALLBACK
+\(which defaults to nil) for any BUFFER."
+  ;; Call `magit-toplevel' just once per cycle.
+  (unless (and magit-auto-revert-toplevel
+               (= (cdr magit-auto-revert-toplevel)
+                  auto-revert-buffers-counter))
+    (setq magit-auto-revert-toplevel
+          (cons (or (magit-toplevel) 'no-repo)
+                auto-revert-buffers-counter)))
+  (let ((top (car magit-auto-revert-toplevel)))
+    (if (eq top 'no-repo)
+        fallback
+      (let ((dir (with-current-buffer buffer default-directory)))
+        (and (equal (file-remote-p dir)
+                    (file-remote-p top))
+             ;; ^ `tramp-handle-file-in-directory-p' lacks this optimization.
+             (file-in-directory-p dir top))))))
+
+(defun auto-revert-buffers--buffer-list-filter ()
+  (when (< emacs-major-version 25)
+    (cl-incf auto-revert-buffers-counter))
+  (when auto-revert-buffer-list-filter
+    (setq auto-revert-buffer-list
+          (--filter auto-revert-buffer-list-filter
+                    auto-revert-buffer-list))))
+
+(advice-add 'auto-revert-buffers :before
+            'auto-revert-buffers--buffer-list-filter)
+
+(provide 'magit-autorevert)
+;;; magit-autorevert.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-autorevert.elc b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-autorevert.elc
new file mode 100644
index 0000000000..37ad644981
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-autorevert.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-bisect.el b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-bisect.el
new file mode 100644
index 0000000000..c6280712df
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-bisect.el
@@ -0,0 +1,210 @@
+;;; magit-bisect.el --- bisect support for Magit  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2011-2018  The Magit Project Contributors
+;;
+;; You should have received a copy of the AUTHORS.md file which
+;; lists all contributors.  If not, see http://magit.vc/authors.
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; Magit 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, or (at your option)
+;; any later version.
+;;
+;; Magit 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 Magit.  If not, see http://www.gnu.org/licenses.
+
+;;; Commentary:
+
+;; Use a binary search to find the commit that introduced a bug.
+
+;;; Code:
+
+(require 'magit)
+
+;;; Options
+
+(defcustom magit-bisect-show-graph t
+  "Whether to use `--graph' in the log showing commits yet to be bisected."
+  :package-version '(magit . "2.8.0")
+  :group 'magit-status
+  :type 'boolean)
+
+(defface magit-bisect-good
+  '((t :foreground "DarkOliveGreen"))
+  "Face for good bisect revisions."
+  :group 'magit-faces)
+
+(defface magit-bisect-skip
+  '((t :foreground "DarkGoldenrod"))
+  "Face for skipped bisect revisions."
+  :group 'magit-faces)
+
+(defface magit-bisect-bad
+  '((t :foreground "IndianRed4"))
+  "Face for bad bisect revisions."
+  :group 'magit-faces)
+
+;;; Commands
+
+;;;###autoload (autoload 'magit-bisect-popup "magit-bisect" nil t)
+(magit-define-popup magit-bisect-popup
+  "Popup console for bisect commands."
+  :man-page "git-bisect"
+  :actions            '((?B "Start"        magit-bisect-start)
+                        (?s "Start script" magit-bisect-run))
+  :sequence-actions   '((?b "Bad"          magit-bisect-bad)
+                        (?g "Good"         magit-bisect-good)
+                        (?k "Skip"         magit-bisect-skip)
+                        (?r "Reset"        magit-bisect-reset)
+                        (?s "Run script"   magit-bisect-run))
+  :sequence-predicate 'magit-bisect-in-progress-p)
+
+;;;###autoload
+(defun magit-bisect-start (bad good)
+  "Start a bisect session.
+
+Bisecting a bug means to find the commit that introduced it.
+This command starts such a bisect session by asking for a know
+good and a bad commit.  To move the session forward use the
+other actions from the bisect popup (\
+\\<magit-status-mode-map>\\[magit-bisect-popup])."
+  (interactive (if (magit-bisect-in-progress-p)
+                   (user-error "Already bisecting")
+                 (magit-bisect-start-read-args)))
+  (magit-git-bisect "start" (list bad good) t))
+
+(defun magit-bisect-start-read-args ()
+  (let  ((b (magit-read-branch-or-commit "Start bisect with bad revision")))
+    (list b (magit-read-other-branch-or-commit "Good revision" b))))
+
+;;;###autoload
+(defun magit-bisect-reset ()
+  "After bisecting, cleanup bisection state and return to original `HEAD'."
+  (interactive)
+  (magit-confirm 'reset-bisect)
+  (magit-run-git "bisect" "reset")
+  (ignore-errors (delete-file (magit-git-dir "BISECT_CMD_OUTPUT"))))
+
+;;;###autoload
+(defun magit-bisect-good ()
+  "While bisecting, mark the current commit as good.
+Use this after you have asserted that the commit does not contain
+the bug in question."
+  (interactive)
+  (magit-git-bisect "good"))
+
+;;;###autoload
+(defun magit-bisect-bad ()
+  "While bisecting, mark the current commit as bad.
+Use this after you have asserted that the commit does contain the
+bug in question."
+  (interactive)
+  (magit-git-bisect "bad"))
+
+;;;###autoload
+(defun magit-bisect-skip ()
+  "While bisecting, skip the current commit.
+Use this if for some reason the current commit is not a good one
+to test.  This command lets Git choose a different one."
+  (interactive)
+  (magit-git-bisect "skip"))
+
+;;;###autoload
+(defun magit-bisect-run (cmdline &optional bad good)
+  "Bisect automatically by running commands after each step.
+
+Unlike `git bisect run' this can be used before bisecting has
+begun.  In that case it behaves like `git bisect start; git
+bisect run'."
+  (interactive (let ((args (and (not (magit-bisect-in-progress-p))
+                                (magit-bisect-start-read-args))))
+                 (cons (read-shell-command "Bisect shell command: ") args)))
+  (when (and bad good)
+    (magit-bisect-start bad good))
+  (magit-git-bisect "run" (list shell-file-name shell-command-switch cmdline)))
+
+(defun magit-git-bisect (subcommand &optional args no-assert)
+  (unless (or no-assert (magit-bisect-in-progress-p))
+    (user-error "Not bisecting"))
+  (magit-with-toplevel
+    (magit-run-git-with-logfile
+     (magit-git-dir "BISECT_CMD_OUTPUT") "bisect" subcommand args)))
+
+;;; Sections
+
+(defun magit-bisect-in-progress-p ()
+  (file-exists-p (magit-git-dir "BISECT_LOG")))
+
+(defun magit-insert-bisect-output ()
+  "While bisecting, insert section with output from `git bisect'."
+  (when (magit-bisect-in-progress-p)
+    (let* ((lines
+            (or (magit-file-lines (magit-git-dir "BISECT_CMD_OUTPUT"))
+                (list "Bisecting: (no saved bisect output)"
+                      "It appears you have invoked `git bisect' from a shell."
+                      "There is nothing wrong with that, we just cannot display"
+                      "anything useful here.  Consult the shell output instead.")))
+           (done-re "^\\([a-z0-9]\\{40\\}\\) is the first bad commit$")
+           (bad-line (or (and (string-match done-re (car lines))
+                              (pop lines))
+                         (--first (string-match done-re it) lines))))
+      (magit-insert-section ((eval (if bad-line 'commit 'bisect-output))
+                             (and bad-line (match-string 1 bad-line)))
+        (magit-insert-heading
+          (propertize (or bad-line (pop lines))
+                      'face 'magit-section-heading))
+        (dolist (line lines)
+          (insert line "\n"))))
+    (insert "\n")))
+
+(defun magit-insert-bisect-rest ()
+  "While bisecting, insert section visualizing the bisect state."
+  (when (magit-bisect-in-progress-p)
+    (magit-insert-section (bisect-view)
+      (magit-insert-heading "Bisect Rest:")
+      (magit-git-wash (apply-partially 'magit-log-wash-log 'bisect-vis)
+        "bisect" "visualize" "git" "log"
+        "--format=%h%d%x00%s" "--decorate=full"
+        (and magit-bisect-show-graph "--graph")))))
+
+(defun magit-insert-bisect-log ()
+  "While bisecting, insert section logging bisect progress."
+  (when (magit-bisect-in-progress-p)
+    (magit-insert-section (bisect-log)
+      (magit-insert-heading "Bisect Log:")
+      (magit-git-wash #'magit-wash-bisect-log "bisect" "log")
+      (insert ?\n))))
+
+(defun magit-wash-bisect-log (_args)
+  (let (beg)
+    (while (progn (setq beg (point-marker))
+                  (re-search-forward "^\\(git bisect [^\n]+\n\\)" nil t))
+      (magit-bind-match-strings (heading) nil
+        (magit-delete-match)
+        (save-restriction
+          (narrow-to-region beg (point))
+          (goto-char (point-min))
+          (magit-insert-section (bisect-item heading t)
+            (insert (propertize heading 'face 'magit-section-secondary-heading))
+            (magit-insert-heading)
+            (magit-wash-sequence
+             (apply-partially 'magit-log-wash-rev 'bisect-log
+                              (magit-abbrev-length)))
+            (insert ?\n)))))
+    (when (re-search-forward
+           "# first bad commit: \\[\\([a-z0-9]\\{40\\}\\)\\] [^\n]+\n" nil t)
+      (magit-bind-match-strings (hash) nil
+        (magit-delete-match)
+        (magit-insert-section (bisect-item)
+          (insert hash " is the first bad commit\n"))))))
+
+(provide 'magit-bisect)
+;;; magit-bisect.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-bisect.elc b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-bisect.elc
new file mode 100644
index 0000000000..d6cc50dce1
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-bisect.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-blame.el b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-blame.el
new file mode 100644
index 0000000000..6712153262
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-blame.el
@@ -0,0 +1,926 @@
+;;; magit-blame.el --- blame support for Magit  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2012-2018  The Magit Project Contributors
+;;
+;; You should have received a copy of the AUTHORS.md file which
+;; lists all contributors.  If not, see http://magit.vc/authors.
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; Magit 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, or (at your option)
+;; any later version.
+;;
+;; Magit 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 Magit.  If not, see http://www.gnu.org/licenses.
+
+;;; Commentary:
+
+;; Annotates each line in file-visiting buffer with information from
+;; the revision which last modified the line.
+
+;;; Code:
+
+(require 'magit)
+
+;;; Options
+
+(defgroup magit-blame nil
+  "Blame support for Magit."
+  :link '(info-link "(magit)Blaming")
+  :group 'magit-modes)
+
+(defcustom magit-blame-styles
+  '((headings
+     (heading-format   . "%-20a %C %s\n"))
+    (margin
+     (margin-format    . (" %s%f" " %C %a" " %H"))
+     (margin-width     . 42)
+     (margin-face      . magit-blame-margin)
+     (margin-body-face . (magit-blame-dimmed)))
+    (highlight
+     (highlight-face   . magit-blame-highlight))
+    (lines
+     (show-lines       . t)))
+  "List of styles used to visualize blame information.
+
+Each entry has the form (IDENT (KEY . VALUE)...).  IDENT has
+to be a symbol uniquely identifing the style.  The following
+KEYs are recognized:
+
+ `show-lines'
+    Whether to prefix each chunk of lines with a thin line.
+    This has no effect if `heading-format' is non-nil.
+ `highlight-face'
+    Face used to highlight the first line of each chunk.
+    If this is nil, then those lines are not highlighted.
+ `heading-format'
+    String specifing the information to be shown above each
+    chunk of lines.  It must end with a newline character.
+ `margin-format'
+    String specifing the information to be shown in the left
+    buffer margin.  It must NOT end with a newline character.
+    This can also be a list of formats used for the lines at
+    the same positions within the chunk.  If the chunk has
+    more lines than formats are specified, then the last is
+    repeated.
+ `margin-width'
+    Width of the margin, provided `margin-format' is non-nil.
+ `margin-face'
+    Face used in the margin, provided `margin-format' is
+    non-nil.  This face is used in combination with the faces
+    that are specific to the used %-specs.  If this is nil,
+    then `magit-blame-margin' is used.
+ `margin-body-face'
+    Face used in the margin for all but first line of a chunk.
+    This face is used in combination with the faces that are
+    specific to the used %-specs.  This can also be a list of
+    faces (usually one face), in which case only these faces
+    are used and the %-spec faces are ignored.  A good value
+    might be `(magit-blame-dimmed)'.  If this is nil, then
+    the same face as for the first line is used.
+
+The following %-specs can be used in `heading-format' and
+`margin-format':
+
+  %H    hash              using face `magit-blame-hash'
+  %s    summary           using face `magit-blame-summary'
+  %a    author            using face `magit-blame-name'
+  %A    author time       using face `magit-blame-date'
+  %c    committer         using face `magit-blame-name'
+  %C    committer time    using face `magit-blame-date'
+
+Additionally if `margin-format' ends with %f, then the string
+that is displayed in the margin is made at least `margin-width'
+characters wide, which may be desirable if the used face sets
+the background color.
+
+The style used in the current buffer can be cycled from the blame
+popup.  Blame commands (except `magit-blame-echo') use the first
+style as the initial style when beginning to blame in a buffer."
+  :package-version '(magit . "2.13.0")
+  :group 'magit-blame
+  :type 'string)
+
+(defcustom magit-blame-echo-style 'lines
+  "The blame visualization style used by `magit-blame-echo'.
+A symbol that has to be used as the identifier for one of the
+styles defined in `magit-blame-styles'."
+  :package-version '(magit . "2.13.0")
+  :group 'magit-blame
+  :type 'symbol)
+
+(defcustom magit-blame-time-format "%F %H:%M"
+  "Format for time strings in blame headings."
+  :group 'magit-blame
+  :type 'string)
+
+(defcustom magit-blame-read-only t
+  "Whether to initially make the blamed buffer read-only."
+  :package-version '(magit . "2.13.0")
+  :group 'magit-blame
+  :type 'boolean)
+
+(defcustom magit-blame-disable-modes '(fci-mode yascroll-bar-mode)
+  "List of modes not compatible with Magit-Blame mode.
+This modes are turned off when Magit-Blame mode is turned on,
+and then turned on again when turning off the latter."
+  :group 'magit-blame
+  :type '(repeat (symbol :tag "Mode")))
+
+(defcustom magit-blame-mode-lighter " Blame"
+  "The mode-line lighter of the Magit-Blame mode."
+  :group 'magit-blame
+  :type '(choice (const :tag "No lighter" "") string))
+
+(defcustom magit-blame-goto-chunk-hook
+  '(magit-blame-maybe-update-revision-buffer
+    magit-blame-maybe-show-message)
+  "Hook run after point entered another chunk."
+  :package-version '(magit . "2.13.0")
+  :group 'magit-blame
+  :type 'hook
+  :get 'magit-hook-custom-get
+  :options '(magit-blame-maybe-update-revision-buffer
+             magit-blame-maybe-show-message))
+
+;;; Faces
+
+(defface magit-blame-highlight
+  '((((class color) (background light))
+     :background "grey80"
+     :foreground "black")
+    (((class color) (background dark))
+     :background "grey25"
+     :foreground "white"))
+  "Face used for highlighting when blaming.
+Also see option `magit-blame-styles'."
+  :group 'magit-faces)
+
+(defface magit-blame-margin
+  '((t :inherit magit-blame-highlight
+       :weight normal
+       :slant normal))
+  "Face used for the blame margin by default when blaming.
+Also see option `magit-blame-styles'."
+  :group 'magit-faces)
+
+(defface magit-blame-dimmed
+  '((t :inherit magit-dimmed
+       :weight normal
+       :slant normal))
+  "Face used for the blame margin in some cases when blaming.
+Also see option `magit-blame-styles'."
+  :group 'magit-faces)
+
+(defface magit-blame-heading
+  '((t :inherit magit-blame-highlight
+       :weight normal
+       :slant normal))
+  "Face used for blame headings by default when blaming.
+Also see option `magit-blame-styles'."
+  :group 'magit-faces)
+
+(defface magit-blame-summary nil
+  "Face used for commit summaries when blaming."
+  :group 'magit-faces)
+
+(defface magit-blame-hash nil
+  "Face used for commit hashes when blaming."
+  :group 'magit-faces)
+
+(defface magit-blame-name nil
+  "Face used for author and committer names when blaming."
+  :group 'magit-faces)
+
+(defface magit-blame-date nil
+  "Face used for dates when blaming."
+  :group 'magit-faces)
+
+;;; Chunks
+
+(defclass magit-blame-chunk ()
+  (;; <orig-rev> <orig-line> <final-line> <num-lines>
+   (orig-rev   :initarg :orig-rev)
+   (orig-line  :initarg :orig-line)
+   (final-line :initarg :final-line)
+   (num-lines  :initarg :num-lines)
+   ;; previous <prev-rev> <prev-file>
+   (prev-rev   :initform nil)
+   (prev-file  :initform nil)
+   ;; filename <orig-file>
+   (orig-file)))
+
+(defun magit-current-blame-chunk (&optional type)
+  (or (and (not (and type (not (eq type magit-blame-type))))
+           (magit-blame-chunk-at (point)))
+      (and type
+           (let ((rev  (or magit-buffer-refname magit-buffer-revision))
+                 (file (magit-file-relative-name nil (not magit-buffer-file-name)))
+                 (line (format "%i,+1" (line-number-at-pos))))
+             (unless file
+               (error "Buffer does not visit a tracked file"))
+             (with-temp-buffer
+               (magit-with-toplevel
+                 (magit-git-insert
+                  "blame" "--porcelain"
+                  (if (memq magit-blame-type '(final removal))
+                      (cons "--reverse" (magit-blame-arguments))
+                    (magit-blame-arguments))
+                  "-L" line rev "--" file)
+                 (goto-char (point-min))
+                 (car (magit-blame--parse-chunk type))))))))
+
+(defun magit-blame-chunk-at (pos)
+  (--any (overlay-get it 'magit-blame-chunk)
+         (overlays-at pos)))
+
+(defun magit-blame--overlay-at (&optional pos key)
+  (unless pos
+    (setq pos (point)))
+  (--first (overlay-get it (or key 'magit-blame-chunk))
+           (nconc (overlays-at pos)
+                  (overlays-in pos pos))))
+
+;;; Keymaps
+
+(defvar magit-blame-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "C-c C-q") 'magit-blame-quit)
+    map)
+  "Keymap for `magit-blame-mode'.
+Note that most blaming key bindings are defined
+in `magit-blame-read-only-mode-map' instead.")
+
+(defvar magit-blame-read-only-mode-map
+  (let ((map (make-sparse-keymap)))
+    (cond ((featurep 'jkl)
+           (define-key map [return]    'magit-show-commit)
+           (define-key map (kbd   "i") 'magit-blame-previous-chunk)
+           (define-key map (kbd   "I") 'magit-blame-previous-chunk-same-commit)
+           (define-key map (kbd   "k") 'magit-blame-next-chunk)
+           (define-key map (kbd   "K") 'magit-blame-next-chunk-same-commit)
+           (define-key map (kbd   "j") 'magit-blame)
+           (define-key map (kbd   "l") 'magit-blame-removal)
+           (define-key map (kbd   "f") 'magit-blame-reverse)
+           (define-key map (kbd   "b") 'magit-blame-popup))
+          (t
+           (define-key map (kbd "C-m") 'magit-show-commit)
+           (define-key map (kbd   "p") 'magit-blame-previous-chunk)
+           (define-key map (kbd   "P") 'magit-blame-previous-chunk-same-commit)
+           (define-key map (kbd   "n") 'magit-blame-next-chunk)
+           (define-key map (kbd   "N") 'magit-blame-next-chunk-same-commit)
+           (define-key map (kbd   "b") 'magit-blame)
+           (define-key map (kbd   "r") 'magit-blame-removal)
+           (define-key map (kbd   "f") 'magit-blame-reverse)
+           (define-key map (kbd   "B") 'magit-blame-popup)))
+    (define-key map (kbd   "c") 'magit-blame-cycle-style)
+    (define-key map (kbd   "q") 'magit-blame-quit)
+    (define-key map (kbd "M-w") 'magit-blame-copy-hash)
+    (define-key map (kbd "SPC") 'magit-diff-show-or-scroll-up)
+    (define-key map (kbd "DEL") 'magit-diff-show-or-scroll-down)
+    map)
+  "Keymap for `magit-blame-read-only-mode'.")
+
+;;; Modes
+;;;; Variables
+
+(defvar-local magit-blame-buffer-read-only nil)
+(defvar-local magit-blame-cache nil)
+(defvar-local magit-blame-disabled-modes nil)
+(defvar-local magit-blame-process nil)
+(defvar-local magit-blame-recursive-p nil)
+(defvar-local magit-blame-type nil)
+(defvar-local magit-blame-separator nil)
+(defvar-local magit-blame-previous-chunk nil)
+
+(defvar-local magit-blame--style nil)
+
+(defsubst magit-blame--style-get (key)
+  (cdr (assoc key (cdr magit-blame--style))))
+
+;;;; Base Mode
+
+(define-minor-mode magit-blame-mode
+  "Display blame information inline."
+  :lighter magit-blame-mode-lighter
+  (cond (magit-blame-mode
+         (when (called-interactively-p 'any)
+           (setq magit-blame-mode nil)
+           (user-error
+            (concat "Don't call `magit-blame-mode' directly; "
+                    "instead use `magit-blame' or `magit-blame-popup'")))
+         (add-hook 'after-save-hook     'magit-blame--run t t)
+         (add-hook 'post-command-hook   'magit-blame-goto-chunk-hook t t)
+         (add-hook 'before-revert-hook  'magit-blame--remove-overlays t t)
+         (add-hook 'after-revert-hook   'magit-blame--run t t)
+         (add-hook 'read-only-mode-hook 'magit-blame-toggle-read-only t t)
+         (setq magit-blame-buffer-read-only buffer-read-only)
+         (when (or magit-blame-read-only magit-buffer-file-name)
+           (read-only-mode 1))
+         (dolist (mode magit-blame-disable-modes)
+           (when (and (boundp mode) (symbol-value mode))
+             (funcall mode -1)
+             (push mode magit-blame-disabled-modes)))
+         (setq magit-blame-separator (magit-blame--format-separator))
+         (unless magit-blame--style
+           (setq magit-blame--style (car magit-blame-styles)))
+         (magit-blame--update-margin))
+        (t
+         (when (process-live-p magit-blame-process)
+           (kill-process magit-blame-process)
+           (while magit-blame-process
+             (sit-for 0.01))) ; avoid racing the sentinal
+         (remove-hook 'after-save-hook     'magit-blame--run t)
+         (remove-hook 'post-command-hook   'magit-blame-goto-chunk-hook t)
+         (remove-hook 'before-revert-hook  'magit-blame--remove-overlays t)
+         (remove-hook 'after-revert-hook   'magit-blame--run t)
+         (remove-hook 'read-only-mode-hook 'magit-blame-toggle-read-only t)
+         (unless magit-blame-buffer-read-only
+           (read-only-mode -1))
+         (magit-blame-read-only-mode -1)
+         (dolist (mode magit-blame-disabled-modes)
+           (funcall mode 1))
+         (kill-local-variable 'magit-blame-disabled-modes)
+         (kill-local-variable 'magit-blame-type)
+         (kill-local-variable 'magit-blame--style)
+         (magit-blame--update-margin)
+         (magit-blame--remove-overlays))))
+
+(defun magit-blame-goto-chunk-hook ()
+  (let ((chunk (magit-blame-chunk-at (point))))
+    (when (cl-typep chunk 'magit-blame-chunk)
+      (unless (eq chunk magit-blame-previous-chunk)
+        (run-hooks 'magit-blame-goto-chunk-hook))
+      (setq magit-blame-previous-chunk chunk))))
+
+(defun magit-blame-toggle-read-only ()
+  (magit-blame-read-only-mode (if buffer-read-only 1 -1)))
+
+;;;; Read-Only Mode
+
+(define-minor-mode magit-blame-read-only-mode
+  "Provide keybindings for Magit-Blame mode.
+
+This minor-mode provides the key bindings for Magit-Blame mode,
+but only when Read-Only mode is also enabled because these key
+bindings would otherwise conflict badly with regular bindings.
+
+When both Magit-Blame mode and Read-Only mode are enabled, then
+this mode gets automatically enabled too and when one of these
+modes is toggled, then this mode also gets toggled automatically.
+
+\\{magit-blame-read-only-mode-map}")
+
+;;;; Kludges
+
+(defun magit-blame-put-keymap-before-view-mode ()
+  "Put `magit-blame-read-only-mode' ahead of `view-mode' in `minor-mode-map-alist'."
+  (--when-let (assq 'magit-blame-read-only-mode
+                    (cl-member 'view-mode minor-mode-map-alist :key #'car))
+    (setq minor-mode-map-alist
+          (cons it (delq it minor-mode-map-alist))))
+  (remove-hook 'view-mode-hook #'magit-blame-put-keymap-before-view-mode))
+
+(add-hook 'view-mode-hook #'magit-blame-put-keymap-before-view-mode)
+
+;;; Process
+
+(defun magit-blame--run ()
+  (magit-with-toplevel
+    (unless magit-blame-mode
+      (magit-blame-mode 1))
+    (message "Blaming...")
+    (magit-blame-run-process
+     (or magit-buffer-refname magit-buffer-revision)
+     (magit-file-relative-name nil (not magit-buffer-file-name))
+     (if (memq magit-blame-type '(final removal))
+         (cons "--reverse" (magit-blame-arguments))
+       (magit-blame-arguments))
+     (list (line-number-at-pos (window-start))
+           (line-number-at-pos (1- (window-end nil t)))))
+    (set-process-sentinel magit-this-process
+                          'magit-blame-process-quickstart-sentinel)))
+
+(defun magit-blame-run-process (revision file args &optional lines)
+  (let ((process (magit-parse-git-async
+                  "blame" "--incremental" args
+                  (and lines (list "-L" (apply #'format "%s,%s" lines)))
+                  revision "--" file)))
+    (set-process-filter   process 'magit-blame-process-filter)
+    (set-process-sentinel process 'magit-blame-process-sentinel)
+    (process-put process 'arguments (list revision file args))
+    (setq magit-blame-cache (make-hash-table :test 'equal))
+    (setq magit-blame-process process)))
+
+(defun magit-blame-process-quickstart-sentinel (process event)
+  (when (memq (process-status process) '(exit signal))
+    (magit-blame-process-sentinel process event t)
+    (magit-blame-assert-buffer process)
+    (with-current-buffer (process-get process 'command-buf)
+      (when magit-blame-mode
+        (let ((default-directory (magit-toplevel)))
+          (apply #'magit-blame-run-process
+                 (process-get process 'arguments)))))))
+
+(defun magit-blame-process-sentinel (process _event &optional quiet)
+  (let ((status (process-status process)))
+    (when (memq status '(exit signal))
+      (kill-buffer (process-buffer process))
+      (if (and (eq status 'exit)
+               (zerop (process-exit-status process)))
+          (unless quiet
+            (message "Blaming...done"))
+        (magit-blame-assert-buffer process)
+        (with-current-buffer (process-get process 'command-buf)
+          (if magit-blame-mode
+              (progn (magit-blame-mode -1)
+                     (message "Blaming...failed"))
+            (message "Blaming...aborted"))))
+      (kill-local-variable 'magit-blame-process))))
+
+(defun magit-blame-process-filter (process string)
+  (internal-default-process-filter process string)
+  (let ((buf  (process-get process 'command-buf))
+        (pos  (process-get process 'parsed))
+        (mark (process-mark process))
+        type cache)
+    (with-current-buffer buf
+      (setq type  magit-blame-type)
+      (setq cache magit-blame-cache))
+    (with-current-buffer (process-buffer process)
+      (goto-char pos)
+      (while (and (< (point) mark)
+                  (save-excursion (re-search-forward "^filename .+\n" nil t)))
+        (pcase-let* ((`(,chunk ,revinfo)
+                      (magit-blame--parse-chunk type))
+                     (rev (oref chunk orig-rev)))
+          (if revinfo
+              (puthash rev revinfo cache)
+            (setq revinfo
+                  (or (gethash rev cache)
+                      (puthash rev (magit-blame--commit-alist rev) cache))))
+          (magit-blame--make-overlays buf chunk revinfo))
+        (process-put process 'parsed (point))))))
+
+(defun magit-blame--parse-chunk (type)
+  (let (chunk revinfo)
+    (looking-at "^\\(.\\{40\\}\\) \\([0-9]+\\) \\([0-9]+\\) \\([0-9]+\\)")
+    (with-slots (orig-rev orig-file prev-rev prev-file)
+        (setq chunk (magit-blame-chunk
+                     :orig-rev                     (match-string 1)
+                     :orig-line  (string-to-number (match-string 2))
+                     :final-line (string-to-number (match-string 3))
+                     :num-lines  (string-to-number (match-string 4))))
+      (forward-line)
+      (let (done)
+        (while (not done)
+          (cond ((looking-at "^filename \\(.+\\)")
+                 (setq done t)
+                 (setf orig-file (match-string 1)))
+                ((looking-at "^previous \\(.\\{40\\}\\) \\(.+\\)")
+                 (setf prev-rev  (match-string 1))
+                 (setf prev-file (match-string 2)))
+                ((looking-at "^\\([^ ]+\\) \\(.+\\)")
+                 (push (cons (match-string 1)
+                             (match-string 2)) revinfo)))
+          (forward-line)))
+      (when (and (eq type 'removal) prev-rev)
+        (cl-rotatef orig-rev  prev-rev)
+        (cl-rotatef orig-file prev-file)
+        (setq revinfo nil)))
+    (list chunk revinfo)))
+
+(defun magit-blame--commit-alist (rev)
+  (cl-mapcar 'cons
+             '("summary"
+               "author" "author-time" "author-tz"
+               "committer" "committer-time" "committer-tz")
+             (split-string (magit-rev-format "%s\v%an\v%ad\v%cn\v%cd" rev
+                                             "--date=format:%s\v%z")
+                           "\v")))
+
+(defun magit-blame-assert-buffer (process)
+  (unless (buffer-live-p (process-get process 'command-buf))
+    (kill-process process)
+    (user-error "Buffer being blamed has been killed")))
+
+;;; Display
+
+(defun magit-blame--make-overlays (buf chunk revinfo)
+  (with-current-buffer buf
+    (save-excursion
+      (save-restriction
+        (widen)
+        (goto-char (point-min))
+        (forward-line (1- (oref chunk final-line)))
+        (let ((beg (point))
+              (end (save-excursion
+                     (forward-line (oref chunk num-lines))
+                     (point))))
+          (magit-blame--remove-overlays beg end)
+          (magit-blame--make-margin-overlays chunk revinfo beg end)
+          (magit-blame--make-heading-overlay chunk revinfo beg end)
+          (magit-blame--make-highlight-overlay   chunk beg))))))
+
+(defun magit-blame--make-margin-overlays (chunk revinfo _beg end)
+  (save-excursion
+    (let ((line 0))
+      (while (< (point) end)
+        (magit-blame--make-margin-overlay chunk revinfo line)
+        (forward-line)
+        (cl-incf line)))))
+
+(defun magit-blame--make-margin-overlay (chunk revinfo line)
+  (let* ((end (line-end-position))
+         ;; If possible avoid putting this on the first character
+         ;; of the line to avoid a conflict with the line overlay.
+         (beg (min (1+ (line-beginning-position)) end))
+         (ov  (make-overlay beg end)))
+    (overlay-put ov 'magit-blame-chunk chunk)
+    (overlay-put ov 'magit-blame-revinfo revinfo)
+    (overlay-put ov 'magit-blame-margin line)
+    (magit-blame--update-margin-overlay ov)))
+
+(defun magit-blame--make-heading-overlay (chunk revinfo beg end)
+  (let ((ov (make-overlay beg end)))
+    (overlay-put ov 'magit-blame-chunk chunk)
+    (overlay-put ov 'magit-blame-revinfo revinfo)
+    (overlay-put ov 'magit-blame-heading t)
+    (magit-blame--update-heading-overlay ov)))
+
+(defun magit-blame--make-highlight-overlay (chunk beg)
+  (let ((ov (make-overlay beg (1+ (line-end-position)))))
+    (overlay-put ov 'magit-blame-chunk chunk)
+    (overlay-put ov 'magit-blame-highlight t)
+    (magit-blame--update-highlight-overlay ov)))
+
+(defun magit-blame--update-margin ()
+  (setq left-margin-width (or (magit-blame--style-get 'margin-width) 0))
+  (set-window-buffer (selected-window) (current-buffer)))
+
+(defun magit-blame--update-overlays ()
+  (save-restriction
+    (widen)
+    (dolist (ov (overlays-in (point-min) (point-max)))
+      (cond ((overlay-get ov 'magit-blame-heading)
+             (magit-blame--update-heading-overlay ov))
+            ((overlay-get ov 'magit-blame-margin)
+             (magit-blame--update-margin-overlay ov))
+            ((overlay-get ov 'magit-blame-highlight)
+             (magit-blame--update-highlight-overlay ov))))))
+
+(defun magit-blame--update-margin-overlay (ov)
+  (overlay-put
+   ov 'before-string
+   (and (magit-blame--style-get 'margin-width)
+        (propertize
+         "o" 'display
+         (list (list 'margin 'left-margin)
+               (let ((line   (overlay-get ov 'magit-blame-margin))
+                     (format (magit-blame--style-get 'margin-format))
+                     (face   (magit-blame--style-get 'margin-face)))
+                 (magit-blame--format-string
+                  ov
+                  (or (and (atom format)
+                           format)
+                      (nth line format)
+                      (car (last format)))
+                  (or (and (not (zerop line))
+                           (magit-blame--style-get 'margin-body-face))
+                      face
+                      'magit-blame-margin))))))))
+
+(defun magit-blame--update-heading-overlay (ov)
+  (overlay-put
+   ov 'before-string
+   (--if-let (magit-blame--style-get 'heading-format)
+       (magit-blame--format-string ov it 'magit-blame-heading)
+     (and (magit-blame--style-get 'show-lines)
+          (or (not (magit-blame--style-get 'margin-format))
+              (save-excursion
+                (goto-char (overlay-start ov))
+                ;; Special case of the special case described in
+                ;; `magit-blame--make-margin-overlay'.  For empty
+                ;; lines it is not possible to show both overlays
+                ;; without the line being to high.
+                (not (= (point) (line-end-position)))))
+          magit-blame-separator))))
+
+(defun magit-blame--update-highlight-overlay (ov)
+  (overlay-put ov 'face (magit-blame--style-get 'highlight-face)))
+
+(defun magit-blame--format-string (ov format face)
+  (let* ((chunk   (overlay-get ov 'magit-blame-chunk))
+         (revinfo (overlay-get ov 'magit-blame-revinfo))
+         (key     (list format face))
+         (string  (cdr (assoc key revinfo))))
+    (unless string
+      (setq string
+            (and format
+                 (magit-blame--format-string-1 (oref chunk orig-rev)
+                                               revinfo format face)))
+      (nconc revinfo (list (cons key string))))
+    string))
+
+(defun magit-blame--format-string-1 (rev revinfo format face)
+  (let ((str
+         (if (equal rev "0000000000000000000000000000000000000000")
+             (propertize (concat (if (string-prefix-p "\s" format) "\s" "")
+                                 "Not Yet Committed"
+                                 (if (string-suffix-p "\n" format) "\n" ""))
+                         'face face)
+           (magit--format-spec
+            (propertize format 'face face)
+            (cl-flet* ((p0 (s f)
+                           (propertize s 'face (if face
+                                                   (if (listp face)
+                                                       face
+                                                     (list f face))
+                                                 f)))
+                       (p1 (k f)
+                           (p0 (cdr (assoc k revinfo)) f))
+                       (p2 (k1 k2 f)
+                           (p0 (magit-blame--format-time-string
+                                (cdr (assoc k1 revinfo))
+                                (cdr (assoc k2 revinfo)))
+                               f)))
+              `((?H . ,(p0 rev         'magit-blame-hash))
+                (?s . ,(p1 "summary"   'magit-blame-summary))
+                (?a . ,(p1 "author"    'magit-blame-name))
+                (?c . ,(p1 "committer" 'magit-blame-name))
+                (?A . ,(p2 "author-time"    "author-tz"    'magit-blame-date))
+                (?C . ,(p2 "committer-time" "committer-tz" 'magit-blame-date))
+                (?f . "")))))))
+    (if-let ((width (and (string-suffix-p "%f" format)
+                         (magit-blame--style-get 'margin-width))))
+        (concat str
+                (propertize (make-string (max 0 (- width (length str))) ?\s)
+                            'face face))
+      str)))
+
+(defun magit-blame--format-separator ()
+  (propertize
+   (concat (propertize "\s" 'display '(space :height (2)))
+           (propertize "\n" 'line-height t))
+   'face (list :background
+               (face-attribute 'magit-blame-heading :background nil t))))
+
+(defun magit-blame--format-time-string (time tz)
+  (let* ((time-format (or (magit-blame--style-get 'time-format)
+                          magit-blame-time-format))
+         (tz-in-second (and (not (version< emacs-version "25"))
+                            (string-match "%z" time-format)
+                            (car (last (parse-time-string tz))))))
+    (format-time-string time-format
+                        (seconds-to-time (string-to-number time))
+                        tz-in-second)))
+
+(defun magit-blame--remove-overlays (&optional beg end)
+  (save-restriction
+    (widen)
+    (dolist (ov (overlays-in (or beg (point-min))
+                             (or end (point-max))))
+      (when (overlay-get ov 'magit-blame-chunk)
+        (delete-overlay ov)))))
+
+(defun magit-blame-maybe-show-message ()
+  (when (magit-blame--style-get 'show-message)
+    (let ((message-log-max 0))
+      (if-let ((msg (cdr (assq 'heading
+                               (gethash (oref (magit-current-blame-chunk)
+                                              orig-rev)
+                                        magit-blame-cache)))))
+          (progn (setq msg (substring msg 0 -1))
+                 (set-text-properties 0 (length msg) nil msg)
+                 (message msg))
+        (message "Commit data not available yet.  Still blaming.")))))
+
+;;; Commands
+
+;;;###autoload
+(defun magit-blame-echo ()
+  "For each line show the revision in which it was added.
+Show the information about the chunk at point in the echo area
+when moving between chunks.  Unlike other blaming commands, do
+not turn on `read-only-mode'."
+  (interactive)
+  (when magit-buffer-file-name
+    (user-error "Blob buffers aren't supported"))
+  (setq-local magit-blame--style
+              (assq magit-blame-echo-style magit-blame-styles))
+  (setq-local magit-blame-disable-modes
+              (cons 'eldoc-mode magit-blame-disable-modes))
+  (if (not magit-blame-mode)
+      (let ((magit-blame-read-only nil))
+        (magit-blame))
+    (read-only-mode -1)
+    (magit-blame--update-overlays)))
+
+;;;###autoload
+(defun magit-blame ()
+  "For each line show the revision in which it was added."
+  (interactive)
+  (magit-blame--pre-blame-assert 'addition)
+  (magit-blame--pre-blame-setup  'addition)
+  (magit-blame--run))
+
+;;;###autoload
+(defun magit-blame-removal ()
+  "For each line show the revision in which it was removed."
+  (interactive)
+  (unless magit-buffer-file-name
+    (user-error "Only blob buffers can be blamed in reverse"))
+  (magit-blame--pre-blame-assert 'removal)
+  (magit-blame--pre-blame-setup  'removal)
+  (magit-blame--run))
+
+;;;###autoload
+(defun magit-blame-reverse ()
+  "For each line show the last revision in which it still exists."
+  (interactive)
+  (unless magit-buffer-file-name
+    (user-error "Only blob buffers can be blamed in reverse"))
+  (magit-blame--pre-blame-assert 'final)
+  (magit-blame--pre-blame-setup  'final)
+  (magit-blame--run))
+
+(defun magit-blame--pre-blame-assert (type)
+  (unless (magit-toplevel)
+    (magit--not-inside-repository-error))
+  (if (and magit-blame-mode
+           (eq type magit-blame-type))
+      (if-let ((chunk (magit-current-blame-chunk)))
+          (unless (oref chunk prev-rev)
+            (user-error "Chunk has no further history"))
+        (user-error "Commit data not available yet.  Still blaming."))
+    (unless (magit-file-relative-name nil (not magit-buffer-file-name))
+      (if buffer-file-name
+          (user-error "Buffer isn't visiting a tracked file")
+        (user-error "Buffer isn't visiting a file")))))
+
+(defun magit-blame--pre-blame-setup (type)
+  (when magit-blame-mode
+    (if (eq type magit-blame-type)
+        (let ((style magit-blame--style))
+          (magit-blame-visit-other-file)
+          (setq-local magit-blame--style style)
+          (setq-local magit-blame-recursive-p t)
+          ;; Set window-start for the benefit of quickstart.
+          (redisplay))
+      (magit-blame--remove-overlays)))
+  (setq magit-blame-type type))
+
+(defun magit-blame-visit-other-file ()
+  "Visit another blob related to the current chunk."
+  (interactive)
+  (with-slots (prev-rev prev-file orig-line)
+      (magit-current-blame-chunk)
+    (unless prev-rev
+      (user-error "Chunk has no further history"))
+    (magit-with-toplevel
+      (magit-find-file prev-rev prev-file))
+    ;; TODO Adjust line like magit-diff-visit-file.
+    (goto-char (point-min))
+    (forward-line (1- orig-line))))
+
+(defun magit-blame-visit-file ()
+  "Visit the blob related to the current chunk."
+  (interactive)
+  (with-slots (orig-rev orig-file orig-line)
+      (magit-current-blame-chunk)
+    (magit-with-toplevel
+      (magit-find-file orig-rev orig-file))
+    (goto-char (point-min))
+    (forward-line (1- orig-line))))
+
+(defun magit-blame-quit ()
+  "Turn off Magit-Blame mode.
+If the buffer was created during a recursive blame,
+then also kill the buffer."
+  (interactive)
+  (magit-blame-mode -1)
+  (when magit-blame-recursive-p
+    (kill-buffer)))
+
+(defun magit-blame-next-chunk ()
+  "Move to the next chunk."
+  (interactive)
+  (--if-let (next-single-char-property-change (point) 'magit-blame-chunk)
+      (goto-char it)
+    (user-error "No more chunks")))
+
+(defun magit-blame-previous-chunk ()
+  "Move to the previous chunk."
+  (interactive)
+  (--if-let (previous-single-char-property-change (point) 'magit-blame-chunk)
+      (goto-char it)
+    (user-error "No more chunks")))
+
+(defun magit-blame-next-chunk-same-commit (&optional previous)
+  "Move to the next chunk from the same commit.\n\n(fn)"
+  (interactive)
+  (if-let ((rev (oref (magit-current-blame-chunk) orig-rev)))
+      (let ((pos (point)) ov)
+        (save-excursion
+          (while (and (not ov)
+                      (not (= pos (if previous (point-min) (point-max))))
+                      (setq pos (funcall
+                                 (if previous
+                                     'previous-single-char-property-change
+                                   'next-single-char-property-change)
+                                 pos 'magit-blame-chunk)))
+            (--when-let (magit-blame--overlay-at pos)
+              (when (equal (oref (magit-blame-chunk-at pos) orig-rev) rev)
+                (setq ov it)))))
+        (if ov
+            (goto-char (overlay-start ov))
+          (user-error "No more chunks from same commit")))
+    (user-error "This chunk hasn't been blamed yet")))
+
+(defun magit-blame-previous-chunk-same-commit ()
+  "Move to the previous chunk from the same commit."
+  (interactive)
+  (magit-blame-next-chunk-same-commit 'previous-single-char-property-change))
+
+(defun magit-blame-cycle-style ()
+  "Change how blame information is visualized.
+Cycle through the elements of option `magit-blame-styles'."
+  (interactive)
+  (setq magit-blame--style
+        (or (cadr (cl-member (car magit-blame--style)
+                             magit-blame-styles :key #'car))
+            (car magit-blame-styles)))
+  (magit-blame--update-margin)
+  (magit-blame--update-overlays))
+
+(defun magit-blame-copy-hash ()
+  "Save hash of the current chunk's commit to the kill ring.
+
+When the region is active, then save the region's content
+instead of the hash, like `kill-ring-save' would."
+  (interactive)
+  (if (use-region-p)
+      (copy-region-as-kill nil nil 'region)
+    (kill-new (message "%s" (oref (magit-current-blame-chunk) orig-rev)))))
+
+;;; Popup
+
+;;;###autoload (autoload 'magit-blame-popup "magit-blame" nil t)
+(magit-define-popup magit-blame-popup
+  "Popup console for blame commands."
+  :man-page "git-blame"
+  :switches '((?w "Ignore whitespace" "-w")
+              (?r "Do not treat root commits as boundaries" "--root"))
+  :options  '((?M "Detect lines moved or copied within a file" "-M")
+              (?C "Detect lines moved or copied between files" "-C"))
+  :actions  '("Actions"
+              (?b "Show commits adding lines" magit-blame)
+              (?r (lambda ()
+                    (with-current-buffer magit-pre-popup-buffer
+                      (and (not buffer-file-name)
+                           (propertize "Show commits removing lines"
+                                       'face 'default))))
+                  magit-blame-removal)
+              (?f (lambda ()
+                    (with-current-buffer magit-pre-popup-buffer
+                      (and (not buffer-file-name)
+                           (propertize "Show last commits that still have lines"
+                                       'face 'default))))
+                  magit-blame-reverse)
+              (lambda ()
+                (and (with-current-buffer magit-pre-popup-buffer
+                       magit-blame-mode)
+                     (propertize "Refresh" 'face 'magit-popup-heading)))
+              (?c "Cycle style" magit-blame-cycle-style))
+  :default-arguments '("-w")
+  :max-action-columns 1
+  :default-action 'magit-blame)
+
+;;; Utilities
+
+(defun magit-blame-maybe-update-revision-buffer ()
+  (unless magit--update-revision-buffer
+    (setq magit--update-revision-buffer nil)
+    (when-let ((chunk  (magit-current-blame-chunk))
+               (commit (oref chunk orig-rev))
+               (buffer (magit-mode-get-buffer 'magit-revision-mode nil t)))
+      (setq magit--update-revision-buffer (list commit buffer))
+      (run-with-idle-timer
+       magit-update-other-window-delay nil
+       (lambda ()
+         (pcase-let ((`(,rev ,buf) magit--update-revision-buffer))
+           (setq magit--update-revision-buffer nil)
+           (when (buffer-live-p buf)
+             (let ((magit-display-buffer-noselect t))
+               (apply #'magit-show-commit rev (magit-diff-arguments))))))))))
+
+(provide 'magit-blame)
+;;; magit-blame.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-blame.elc b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-blame.elc
new file mode 100644
index 0000000000..ccb3ce7342
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-blame.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-bookmark.el b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-bookmark.el
new file mode 100644
index 0000000000..a2156a4162
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-bookmark.el
@@ -0,0 +1,366 @@
+;;; magit-bookmark.el --- bookmark support for Magit  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2010-2018  The Magit Project Contributors
+;;
+;; You should have received a copy of the AUTHORS.md file which
+;; lists all contributors.  If not, see http://magit.vc/authors.
+
+;; Author: Yuri Khan <yuri.v.khan@gmail.com>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; Magit 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, or (at your option)
+;; any later version.
+;;
+;; Magit 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 Magit.  If not, see http://www.gnu.org/licenses.
+
+;;; Commentary:
+
+;; Support for bookmarks for most Magit buffers.
+
+;;; Code:
+
+(require 'magit)
+(require 'bookmark)
+
+;;; Supporting primitives
+
+(defun magit-bookmark--jump (bookmark fn &rest args)
+  "Handle a Magit BOOKMARK.
+
+This function will:
+
+1. Bind `default-directory' to the repository root directory
+   stored in the `filename' bookmark property.
+2. Invoke the function FN with ARGS as arguments.  This needs to
+   restore the buffer.
+3. Restore the expanded/collapsed status of top level sections
+   and the point position."
+  (declare (indent 2))
+  (let* ((default-directory (bookmark-get-filename bookmark)))
+    (if default-directory
+        (apply fn args)
+      (signal 'bookmark-error-no-filename (list 'stringp default-directory)))
+    (when (derived-mode-p 'magit-mode)
+      (when-let ((hidden-sections (bookmark-prop-get bookmark
+                                                     'magit-hidden-sections)))
+        (dolist (child (oref magit-root-section children))
+          (if (member (cons (oref child type)
+                            (oref child value))
+                      hidden-sections)
+              (magit-section-hide child)
+            (magit-section-show child)))))
+    (--when-let (bookmark-get-position bookmark)
+      (goto-char it))
+    (--when-let (bookmark-get-front-context-string bookmark)
+      (when (search-forward it (point-max) t)
+        (goto-char (match-beginning 0))))
+    (--when-let (bookmark-get-rear-context-string bookmark)
+      (when (search-backward it (point-min) t)
+        (goto-char (match-end 0))))
+    nil))
+
+(defun magit-bookmark--make-record (mode handler &optional make-props)
+  "Create a Magit bookmark.
+
+MODE specifies the expected major mode of current buffer.
+
+HANDLER should be a function that will be used to restore this
+buffer.
+
+MAKE-PROPS should be either nil or a function that will be called
+with `magit-refresh-args' as the argument list, and may return an
+alist whose every element has the form (PROP . VALUE) and
+specifies additional properties to store in the bookmark."
+  (declare (indent 1))
+  (unless (eq major-mode mode)
+    (user-error "Not in a %s buffer" mode))
+  (let ((bookmark (bookmark-make-record-default 'no-file)))
+    (bookmark-prop-set bookmark 'handler handler)
+    (bookmark-set-filename bookmark (magit-toplevel))
+    (when (derived-mode-p 'magit-mode)
+      (bookmark-prop-set
+       bookmark 'magit-hidden-sections
+       (--map (cons (oref it type)
+                    (oref it value))
+              (--filter (oref it hidden)
+                        (oref magit-root-section children)))))
+    (when make-props
+      (pcase-dolist (`(,prop . ,value) (apply make-props magit-refresh-args))
+        (bookmark-prop-set bookmark prop value)))
+    bookmark))
+
+;;; Status
+
+;;;###autoload
+(defun magit-bookmark--status-jump (bookmark)
+  "Handle a Magit status BOOKMARK."
+  (magit-bookmark--jump bookmark
+      (lambda () (magit-status-internal default-directory))))
+
+;;;###autoload
+(defun magit-bookmark--status-make-record ()
+  "Create a Magit status bookmark."
+  (magit-bookmark--make-record 'magit-status-mode
+    #'magit-bookmark--status-jump))
+
+;;; Refs
+
+;;;###autoload
+(defun magit-bookmark--refs-jump (bookmark)
+  "Handle a Magit refs BOOKMARK."
+  (magit-bookmark--jump bookmark #'magit-show-refs
+    (bookmark-prop-get bookmark 'magit-refs)
+    (bookmark-prop-get bookmark 'magit-args)))
+
+;;;###autoload
+(defun magit-bookmark--refs-make-record ()
+  "Create a Magit refs bookmark."
+  (magit-bookmark--make-record 'magit-refs-mode
+    #'magit-bookmark--refs-jump
+    (lambda (refs args)
+      `((magit-refs . ,refs)
+        (magit-args . ,args)))))
+
+;;; Log
+
+;;;###autoload
+(defun magit-bookmark--log-jump (bookmark)
+  "Handle a Magit log BOOKMARK."
+  (magit-bookmark--jump bookmark #'magit-log
+    (bookmark-prop-get bookmark 'magit-revs)
+    (bookmark-prop-get bookmark 'magit-args)
+    (bookmark-prop-get bookmark 'magit-files)))
+
+(defun magit-bookmark--log-make-name (buffer-name revs _args files)
+  "Generate the default name for a log bookmark."
+  (concat
+   buffer-name " " (mapconcat #'identity revs " ")
+   (and files
+        (concat " touching " (mapconcat #'identity files " ")))))
+
+;;;###autoload
+(defun magit-bookmark--log-make-record ()
+  "Create a Magit log bookmark."
+  (magit-bookmark--make-record 'magit-log-mode
+    #'magit-bookmark--log-jump
+    (lambda (revs args files)
+      `((defaults    . (,(magit-bookmark--log-make-name
+                          (buffer-name) revs args files)))
+        (magit-revs  . ,revs)
+        (magit-args  . ,args)
+        (magit-files . ,files)))))
+
+;;; Reflog
+
+;;;###autoload
+(defun magit-bookmark--reflog-jump (bookmark)
+  "Handle a Magit reflog BOOKMARK."
+  (magit-bookmark--jump bookmark
+      (lambda ()
+        (let ((magit-reflog-arguments (bookmark-prop-get bookmark 'magit-args)))
+          (magit-reflog (bookmark-prop-get bookmark 'magit-ref))))))
+
+(defun magit-bookmark--reflog-make-name (buffer-name ref)
+  "Generate the default name for a reflog bookmark."
+  (concat buffer-name " " ref))
+
+;;;###autoload
+(defun magit-bookmark--reflog-make-record ()
+  "Create a Magit reflog bookmark."
+  (magit-bookmark--make-record 'magit-reflog-mode
+    #'magit-bookmark--reflog-jump
+    (lambda (ref args)
+      `((defaults   . (,(magit-bookmark--reflog-make-name (buffer-name) ref)))
+        (magit-ref  . ,ref)
+        (magit-args . ,args)))))
+
+;;; Stashes
+
+;;;###autoload
+(defun magit-bookmark--stashes-jump (bookmark)
+  "Handle a Magit stash list BOOKMARK."
+  (magit-bookmark--jump bookmark #'magit-stash-list))
+
+;;;###autoload
+(defun magit-bookmark--stashes-make-record ()
+  "Create a Magit stash list bookmark."
+  (magit-bookmark--make-record 'magit-stashes-mode
+    #'magit-bookmark--stashes-jump))
+
+;;; Cherry
+
+;;;###autoload
+(defun magit-bookmark--cherry-jump (bookmark)
+  "Handle a Magit cherry BOOKMARK."
+  (magit-bookmark--jump bookmark #'magit-cherry
+    (bookmark-prop-get bookmark 'magit-head)
+    (bookmark-prop-get bookmark 'magit-upstream)))
+
+(defun magit-bookmark--cherry-make-name (buffer-name head upstream)
+  "Generate the default name for a cherry bookmark."
+  (concat buffer-name " " head " upstream " upstream))
+
+;;;###autoload
+(defun magit-bookmark--cherry-make-record ()
+  "Create a Magit cherry bookmark."
+  (magit-bookmark--make-record 'magit-cherry-mode
+    #'magit-bookmark--cherry-jump
+    (lambda (upstream head)
+      `((defaults       . (,(magit-bookmark--cherry-make-name
+                             (buffer-name) head upstream)))
+        (magit-head     . ,head)
+        (magit-upstream . ,upstream)))))
+
+;;; Diff
+
+;;;###autoload
+(defun magit-bookmark--diff-jump (bookmark)
+  "Handle a Magit diff BOOKMARK."
+  (magit-bookmark--jump bookmark #'magit-diff-setup
+    (bookmark-prop-get bookmark 'magit-rev-or-range)
+    (bookmark-prop-get bookmark 'magit-const)
+    (bookmark-prop-get bookmark 'magit-args)
+    (bookmark-prop-get bookmark 'magit-files)))
+
+(defun magit-bookmark--resolve (rev-or-range)
+  "Return REV-OR-RANGE with ref names resolved to commit hashes."
+  (pcase (magit-git-lines "rev-parse" rev-or-range)
+    (`(,rev)
+     (magit-rev-abbrev rev))
+    ((and `(,rev1 ,rev2)
+          (guard (/= ?^ (aref rev1 0)))
+          (guard (=  ?^ (aref rev2 0))))
+     (concat (magit-rev-abbrev (substring rev2 1))
+             ".."
+             (magit-rev-abbrev rev1)))
+    ((and `(,rev1 ,rev2 ,rev3)
+          (guard (/= ?^ (aref rev1 0)))
+          (guard (/= ?^ (aref rev2 0)))
+          (guard (=  ?^ (aref rev3 0))))
+     (ignore rev3)
+     (concat (magit-rev-abbrev rev1)
+             "..."
+             (magit-rev-abbrev rev2)))
+    (_
+     rev-or-range)))
+
+(defun magit-bookmark--diff-make-name
+    (buffer-name rev-or-range const _args files)
+  "Generate a default name for a diff bookmark."
+  (if (member "--no-index" const)
+      (apply #'format "*magit-diff %s %s" files)
+    (concat buffer-name " "
+            (cond (rev-or-range)
+                  ((member "--cached" const) "staged")
+                  (t                       "unstaged"))
+            (when files
+              (concat " in " (mapconcat #'identity files ", "))))))
+
+;;;###autoload
+(defun magit-bookmark--diff-make-record ()
+  "Create a Magit diff bookmark."
+  (magit-bookmark--make-record 'magit-diff-mode
+    #'magit-bookmark--diff-jump
+    (lambda (rev-or-range const args files)
+      (let ((resolved (magit-bookmark--resolve rev-or-range)))
+        `((defaults           . (,(magit-bookmark--diff-make-name
+                                   (buffer-name) resolved const args files)))
+          (magit-rev-or-range . ,resolved)
+          (magit-const        . ,const)
+          (magit-args         . ,args)
+          (magit-files        . ,files))))))
+
+;;; Revision
+
+;;;###autoload
+(defun magit-bookmark--revision-jump (bookmark)
+  "Handle a Magit revision BOOKMARK."
+  (magit-bookmark--jump bookmark #'magit-show-commit
+    (bookmark-prop-get bookmark 'magit-rev)
+    (bookmark-prop-get bookmark 'args)
+    (bookmark-prop-get bookmark 'files)))
+
+(defun magit-bookmark--revision-make-name (buffer-name rev _args files)
+  "Generate a default name for a revision bookmark."
+  (let ((subject (magit-rev-format "%s" rev)))
+    (concat buffer-name " "
+            (magit-rev-abbrev rev)
+            (cond (files   (concat " " (mapconcat #'identity files " ")))
+                  (subject (concat " " subject))))))
+
+;;;###autoload
+(defun magit-bookmark--revision-make-record ()
+  "Create a Magit revision bookmark."
+  ;; magit-refresh-args stores the revision in relative form.
+  ;; For bookmarks, the exact hash is more appropriate.
+  (magit-bookmark--make-record 'magit-revision-mode
+    #'magit-bookmark--revision-jump
+    (lambda (_rev _ args files)
+      `((defaults    . (,(magit-bookmark--revision-make-name
+                          (buffer-name) magit-buffer-revision-hash
+                          args files)))
+        (magit-rev   . ,magit-buffer-revision-hash)
+        (magit-args  . ,args)
+        (magit-files . ,files)))))
+
+;;; Stash
+
+;;;###autoload
+(defun magit-bookmark--stash-jump (bookmark)
+  "Handle a Magit stash BOOKMARK."
+  (magit-bookmark--jump bookmark #'magit-stash-show
+    (bookmark-prop-get bookmark 'magit-stash)
+    (bookmark-prop-get bookmark 'magit-args)
+    (bookmark-prop-get bookmark 'magit-files)))
+
+(defun magit-bookmark--stash-make-name (buffer-name stash _args files)
+  "Generate the default name for a stash bookmark."
+  (concat buffer-name " " stash " "
+          (if files
+              (mapconcat #'identity files " ")
+            (magit-rev-format "%s" stash))))
+
+;;;###autoload
+(defun magit-bookmark--stash-make-record ()
+  "Create a Magit stash bookmark."
+  (magit-bookmark--make-record 'magit-stash-mode
+    #'magit-bookmark--stash-jump
+    (lambda (stash _ args files)
+      `((defaults    . (,(magit-bookmark--stash-make-name
+                          (buffer-name)
+                          (magit-rev-abbrev magit-buffer-revision-hash)
+                          args files)))
+        (magit-stash . ,magit-buffer-revision-hash)
+        (magit-args  . ,args)
+        (magit-files . ,files)
+        (magit-hidden-sections
+         . ,(--map `(,(oref it type)
+                     . ,(replace-regexp-in-string (regexp-quote stash)
+                                                  magit-buffer-revision-hash
+                                                  (oref it value)))
+                   (--filter (oref it hidden)
+                             (oref magit-root-section children))))))))
+
+;;; Submodules
+
+;;;###autoload
+(defun magit-bookmark--submodules-jump (bookmark)
+  "Handle a Magit submodule list BOOKMARK."
+  (magit-bookmark--jump bookmark #'magit-list-submodules))
+
+;;;###autoload
+(defun magit-bookmark--submodules-make-record ()
+  "Create a Magit submodule list bookmark."
+  (magit-bookmark--make-record 'magit-submodule-list-mode
+    #'magit-bookmark--submodules-jump))
+
+(provide 'magit-bookmark)
+;;; magit-bookmark.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-bookmark.elc b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-bookmark.elc
new file mode 100644
index 0000000000..68accf2ab1
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-bookmark.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-branch.el b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-branch.el
new file mode 100644
index 0000000000..ef9c55408b
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-branch.el
@@ -0,0 +1,1081 @@
+;;; magit-branch.el --- branch support  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2010-2018  The Magit Project Contributors
+;;
+;; You should have received a copy of the AUTHORS.md file which
+;; lists all contributors.  If not, see http://magit.vc/authors.
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; Magit 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, or (at your option)
+;; any later version.
+;;
+;; Magit 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 Magit.  If not, see http://www.gnu.org/licenses.
+
+;;; Commentary:
+
+;; This library implements support for branches.  It defines popups
+;; and commands for creating, checking out, manipulating, and
+;; configuring branches.  Commands defined here are mainly concerned
+;; with branches as pointers, commands that deal with what a branch
+;; points at, are defined elsewhere.
+
+;;; Code:
+
+(require 'magit)
+(require 'magit-collab)
+(require 'magit-reset)
+
+;;; Options
+
+(defcustom magit-branch-read-upstream-first t
+  "Whether to read upstream before name of new branch when creating a branch.
+
+`nil'      Read the branch name first.
+`t'        Read the upstream first.
+`fallback' Read the upstream first, but if it turns out that the chosen
+           value is not a valid upstream (because it cannot be resolved
+           as an existing revision), then treat it as the name of the
+           new branch and continue by reading the upstream next."
+  :package-version '(magit . "2.2.0")
+  :group 'magit-commands
+  :type '(choice (const :tag "read branch name first" nil)
+                 (const :tag "read upstream first" t)
+                 (const :tag "read upstream first, with fallback" fallback)))
+
+(defcustom magit-branch-prefer-remote-upstream nil
+  "Whether to favor remote upstreams when creating new branches.
+
+When a new branch is created, then the branch, commit, or stash
+at point is suggested as the default starting point of the new
+branch, or if there is no such revision at point the current
+branch.  In either case the user may choose another starting
+point.
+
+If the chosen starting point is a branch, then it may also be set
+as the upstream of the new branch, depending on the value of the
+Git variable `branch.autoSetupMerge'.  By default this is done
+for remote branches, but not for local branches.
+
+You might prefer to always use some remote branch as upstream.
+If the chosen starting point is (1) a local branch, (2) whose
+name matches a member of the value of this option, (3) the
+upstream of that local branch is a remote branch with the same
+name, and (4) that remote branch can be fast-forwarded to the
+local branch, then the chosen branch is used as starting point,
+but its own upstream is used as the upstream of the new branch.
+
+Members of this option's value are treated as branch names that
+have to match exactly unless they contain a character that makes
+them invalid as a branch name.  Recommended characters to use
+to trigger interpretation as a regexp are \"*\" and \"^\".  Some
+other characters which you might expect to be invalid, actually
+are not, e.g. \".+$\" are all perfectly valid.  More precisely,
+if `git check-ref-format --branch STRING' exits with a non-zero
+status, then treat STRING as a regexp.
+
+Assuming the chosen branch matches these conditions you would end
+up with with e.g.:
+
+  feature --upstream--> origin/master
+
+instead of
+
+  feature --upstream--> master --upstream--> origin/master
+
+Which you prefer is a matter of personal preference.  If you do
+prefer the former, then you should add branches such as \"master\",
+\"next\", and \"maint\" to the value of this options."
+  :package-version '(magit . "2.4.0")
+  :group 'magit-commands
+  :type '(repeat string))
+
+(defcustom magit-branch-adjust-remote-upstream-alist nil
+  "Alist of upstreams to be used when branching from remote branches.
+
+When creating a local branch from an ephemeral branch located
+on a remote, e.g. a feature or hotfix branch, then that remote
+branch should usually not be used as the upstream branch, since
+the push-remote already allows accessing it and having both the
+upstream and the push-remote reference the same related branch
+would be wasteful.  Instead a branch like \"maint\" or \"master\"
+should be used as the upstream.
+
+This option allows specifing the branch that should be used as
+the upstream when branching certain remote branches.  The value
+is an alist of the form ((UPSTREAM . RULE)...).  The first
+matching element is used, the following elements are ignored.
+
+UPSTREAM is the branch to be used as the upstream for branches
+specified by RULE.  It can be a local or a remote branch.
+
+RULE can either be a regular expression, matching branches whose
+upstream should be the one specified by UPSTREAM.  Or it can be
+a list of the only branches that should *not* use UPSTREAM; all
+other branches will.  Matching is done after stripping the remote
+part of the name of the branch that is being branched from.
+
+If you use a finite set of non-ephemeral branches across all your
+repositories, then you might use something like:
+
+  ((\"origin/master\" \"master\" \"next\" \"maint\"))
+
+Or if the names of all your ephemeral branches contain a slash,
+at least in some repositories, then a good value could be:
+
+  ((\"origin/master\" . \"/\"))
+
+Of course you can also fine-tune:
+
+  ((\"origin/maint\" . \"\\`hotfix/\")
+   (\"origin/master\" . \"\\`feature/\"))
+
+If you use remote branches as UPSTREAM, then you might also want
+to set `magit-branch-prefer-remote-upstream' to a non-nil value.
+However, I recommend that you use local branches as UPSTREAM."
+  :package-version '(magit . "2.9.0")
+  :group 'magit-commands
+  :type '(repeat (cons (string :tag "Use upstream")
+                       (choice :tag "for branches"
+                               (regexp :tag "matching")
+                               (repeat :tag "except"
+                                       (string :tag "branch"))))))
+
+(defcustom magit-branch-rename-push-target t
+  "Whether the push-remote setup is preserved when renaming a branch.
+
+The command `magit-branch-rename' renames a branch named OLD to
+NEW.  This option controls how much of the push-remote setup is
+preserved when doing so.
+
+When nil, then preserve nothing and unset `branch.OLD.pushRemote'.
+
+When `local-only', then first set `branch.NEW.pushRemote' to the
+  same value as `branch.OLD.pushRemote', provided the latter is
+  actually set and unless the former already has another value.
+
+When t, then rename the branch named OLD on the remote specified
+  by `branch.OLD.pushRemote' to NEW, provided OLD exists on that
+  remote and unless NEW already exists on the remote.
+
+When `github-only', then behave like `t' if the remote points to
+  a repository on Github, otherwise like `local-only'."
+  :group 'magit-commands
+  :type '(choice
+          (const :tag "Don't preserve push-remote setup" nil)
+          (const :tag "Preserve push-remote setup" local-only)
+          (const :tag "... and rename corresponding branch on remote" t)
+          (const :tag "... but only if remote is on Github" github-only)))
+
+(defcustom magit-branch-popup-show-variables t
+  "Whether the `magit-branch-popup' shows Git variables.
+This defaults to t to avoid changing key bindings.  When set to
+nil, no variables are displayed directly in this popup, instead
+the sub-popup `magit-branch-config-popup' has to be used to view
+and change branch related variables."
+  :package-version '(magit . "2.7.0")
+  :group 'magit-commands
+  :type 'boolean)
+
+(defcustom magit-published-branches '("origin/master")
+  "List of branches that are considered to be published."
+  :package-version '(magit . "2.13.0")
+  :group 'magit-commands
+  :type '(repeat string))
+
+;;; Branch Popup
+
+(defvar magit-branch-config-variables)
+
+;;;###autoload (autoload 'magit-branch-popup "magit" nil t)
+(magit-define-popup magit-branch-popup
+  "Popup console for branch commands."
+  :man-page "git-branch"
+  :variables (lambda ()
+               (and magit-branch-popup-show-variables
+                    magit-branch-config-variables))
+  :actions '((?b "Checkout"              magit-checkout) nil
+             (?C "Configure..."          magit-branch-config-popup)
+             (?l "Checkout local branch" magit-branch-checkout)
+             (?s "Create new spin-off"   magit-branch-spinoff)
+             (?m "Rename"                magit-branch-rename)
+             (?c "Checkout new branch"   magit-branch-and-checkout)
+             (?n "Create new branch"     magit-branch)
+             (?x "Reset"                 magit-branch-reset)
+             (?y "Checkout pull-request"    magit-checkout-pull-request)
+             (?Y "Create from pull-request" magit-branch-pull-request)
+             (?k "Delete"                   magit-branch-delete)
+             (?w "Checkout new worktree" magit-worktree-checkout)
+             (?W "Create new worktree"   magit-worktree-branch))
+  :default-action 'magit-checkout
+  :max-action-columns 3
+  :setup-function 'magit-branch-popup-setup)
+
+(defun magit-branch-popup-setup (val def)
+  (magit-popup-default-setup val def)
+  (use-local-map (copy-keymap magit-popup-mode-map))
+  (dolist (ev (-filter #'magit-popup-event-p (magit-popup-get :variables)))
+    (local-set-key (vector (magit-popup-event-key ev))
+                   'magit-invoke-popup-action)))
+
+;;; Branch Commands
+
+;;;###autoload
+(defun magit-checkout (revision)
+  "Checkout REVISION, updating the index and the working tree.
+If REVISION is a local branch, then that becomes the current
+branch.  If it is something else, then `HEAD' becomes detached.
+Checkout fails if the working tree or the staging area contain
+changes.
+\n(git checkout REVISION)."
+  (interactive (list (magit-read-other-branch-or-commit "Checkout")))
+  (when (string-match "\\`heads/\\(.+\\)" revision)
+    (setq revision (match-string 1 revision)))
+  (magit-run-git "checkout" revision))
+
+;;;###autoload
+(defun magit-branch (branch start-point &optional args)
+  "Create BRANCH at branch or revision START-POINT.
+\n(git branch [ARGS] BRANCH START-POINT)."
+  (interactive (magit-branch-read-args "Create branch"))
+  (magit-call-git "branch" args branch start-point)
+  (magit-branch-maybe-adjust-upstream branch start-point)
+  (magit-refresh))
+
+;;;###autoload
+(defun magit-branch-and-checkout (branch start-point &optional args)
+  "Create and checkout BRANCH at branch or revision START-POINT.
+\n(git checkout [ARGS] -b BRANCH START-POINT)."
+  (interactive (magit-branch-read-args "Create and checkout branch"))
+  (if (string-match-p "^stash@{[0-9]+}$" start-point)
+      (magit-run-git "stash" "branch" branch start-point)
+    (magit-call-git "checkout" args "-b" branch start-point)
+    (magit-branch-maybe-adjust-upstream branch start-point)
+    (magit-refresh)))
+
+;;;###autoload
+(defun magit-branch-or-checkout (arg &optional start-point)
+  "Hybrid between `magit-checkout' and `magit-branch-and-checkout'.
+
+Ask the user for an existing branch or revision.  If the user
+input actually can be resolved as a branch or revision, then
+check that out, just like `magit-checkout' would.
+
+Otherwise create and checkout a new branch using the input as
+its name.  Before doing so read the starting-point for the new
+branch.  This is similar to what `magit-branch-and-checkout'
+does."
+  (interactive
+   (let ((arg (magit-read-other-branch-or-commit "Checkout")))
+     (list arg
+           (and (not (magit-rev-verify-commit arg))
+                (magit-read-starting-point "Create and checkout branch" arg)))))
+  (when (string-match "\\`heads/\\(.+\\)" arg)
+    (setq arg (match-string 1 arg)))
+  (if start-point
+      (magit-branch-and-checkout arg start-point (magit-branch-arguments))
+    (magit-checkout arg)))
+
+;;;###autoload
+(defun magit-branch-checkout (branch &optional start-point)
+  "Checkout an existing or new local branch.
+
+Read a branch name from the user offering all local branches and
+a subset of remote branches as candidates.  Omit remote branches
+for which a local branch by the same name exists from the list
+of candidates.  The user can also enter a completely new branch
+name.
+
+- If the user selects an existing local branch, then check that
+  out.
+
+- If the user selects a remote branch, then create and checkout
+  a new local branch with the same name.  Configure the selected
+  remote branch as push target.
+
+- If the user enters a new branch name, then create and check
+  that out, after also reading the starting-point from the user.
+
+In the latter two cases the upstream is also set.  Whether it is
+set to the chosen START-POINT or something else depends on the
+value of `magit-branch-adjust-remote-upstream-alist', just like
+when using `magit-branch-and-checkout'."
+  (interactive
+   (let* ((current (magit-get-current-branch))
+          (local   (magit-list-local-branch-names))
+          (remote  (--filter (and (string-match "[^/]+/" it)
+                                  (not (member (substring it (match-end 0))
+                                               (cons "HEAD" local))))
+                             (magit-list-remote-branch-names)))
+          (choices (nconc (delete current local) remote))
+          (atpoint (magit-branch-at-point))
+          (choice  (magit-completing-read
+                    "Checkout branch" choices
+                    nil nil nil 'magit-revision-history
+                    (or (car (member atpoint choices))
+                        (and atpoint
+                             (car (member (and (string-match "[^/]+/" atpoint)
+                                               (substring atpoint (match-end 0)))
+                                          choices)))))))
+     (cond ((member choice remote)
+            (list (and (string-match "[^/]+/" choice)
+                       (substring choice (match-end 0)))
+                  choice))
+           ((member choice local)
+            (list choice))
+           (t
+            (list choice (magit-read-starting-point "Create" choice))))))
+  (if (not start-point)
+      (magit-checkout branch)
+    (when (magit-anything-modified-p)
+      (user-error "Cannot checkout when there are uncommitted changes"))
+    (magit-branch-and-checkout branch start-point (magit-branch-arguments))
+    (when (magit-remote-branch-p start-point)
+      (pcase-let ((`(,remote . ,remote-branch)
+                   (magit-split-branch-name start-point)))
+        (when (and (equal branch remote-branch)
+                   (not (equal remote (magit-get "remote.pushDefault"))))
+          (magit-set remote "branch" branch "pushRemote"))))))
+
+(defun magit-branch-maybe-adjust-upstream (branch start-point)
+  (--when-let
+      (or (and (magit-get-upstream-branch branch)
+               (magit-get-indirect-upstream-branch start-point))
+          (and (magit-remote-branch-p start-point)
+               (let ((name (cdr (magit-split-branch-name start-point))))
+                 (car (--first (if (listp (cdr it))
+                                   (not (member name (cdr it)))
+                                 (string-match-p (cdr it) name))
+                               magit-branch-adjust-remote-upstream-alist)))))
+    (magit-call-git "branch" (concat "--set-upstream-to=" it) branch)))
+
+;;;###autoload
+(defun magit-branch-orphan (branch start-point &optional args)
+  "Create and checkout an orphan BRANCH with contents from revision START-POINT.
+\n(git checkout --orphan [ARGS] BRANCH START-POINT)."
+  (interactive (magit-branch-read-args "Create and checkout orphan branch"))
+  (magit-run-git "checkout" "--orphan" args branch start-point))
+
+;;;###autoload
+(defun magit-branch-pull-request (pr)
+  "Create and configure a new branch from a pull-request.
+Please see the manual for more information."
+  (interactive (list (magit-read-pull-request "Branch pull request")))
+  (let-alist pr
+    (let* ((upstream (or (--first (magit--github-url-equal
+                                   (magit-get "remote" it "url")
+                                   .base.repo.ssh_url)
+                                  (magit-list-remotes))
+                         (user-error
+                          "Upstream repository %s not available as a remote"
+                          .base.repo.ssh_url)))
+           (upstream-url (magit-get "remote" upstream "url"))
+           (remote .head.repo.owner.login)
+           (branch (magit--pullreq-branch pr t))
+           (pr-branch .head.ref))
+      (if (magit--pullreq-from-upstream-p pr)
+          (let ((tracking (concat upstream "/" pr-branch)))
+            (unless (magit-branch-p tracking)
+              (magit-call-git "fetch" upstream))
+            (let ((inhibit-magit-refresh t))
+              (magit-branch branch tracking))
+            (magit-set upstream "branch" branch "pushRemote")
+            (magit-set upstream "branch" branch "pullRequestRemote"))
+        (if (magit-remote-p remote)
+            (let ((url   (magit-get     "remote" remote "url"))
+                  (fetch (magit-get-all "remote" remote "fetch")))
+              (unless (magit--github-url-equal url .head.repo.ssh_url)
+                (user-error
+                 "Remote `%s' already exists but does not point to %s"
+                 remote url))
+              (unless (member (format "+refs/heads/*:refs/remotes/%s/*" remote)
+                              fetch)
+                (magit-call-git "remote" "set-branches"
+                                "--add" remote pr-branch)
+                (magit-call-git "fetch" remote)))
+          (magit-call-git
+           "remote" "add" "-f" "--no-tags"
+           "-t" pr-branch remote
+           (cond ((or (string-prefix-p "git@" upstream-url)
+                      (string-prefix-p "ssh://git@" upstream-url))
+                  .head.repo.ssh_url)
+                 ((string-prefix-p "https://" upstream-url)
+                  .head.repo.clone_url)
+                 ((string-prefix-p "git://" upstream-url)
+                  .head.repo.git_url)
+                 (t (error "%s has an unexpected format" upstream-url)))))
+        (magit-call-git "branch" branch (concat remote "/" pr-branch))
+        (if (or .locked (not (equal branch pr-branch)))
+            (magit-set upstream "branch" branch "pushRemote")
+          (magit-set remote "branch" branch "pushRemote"))
+        (magit-set remote "branch" branch "pullRequestRemote"))
+      (magit-set "true" "branch" branch "rebase")
+      (magit-call-git "branch" branch
+                      (concat "--set-upstream-to="
+                              (if magit-branch-prefer-remote-upstream
+                                  (concat upstream "/" .base.ref)
+                                .base.ref)))
+      (magit-set (number-to-string .number) "branch" branch "pullRequest")
+      (magit-set .title                     "branch" branch "description")
+      (magit-refresh)
+      branch)))
+
+(defun magit-checkout-pull-request (pr)
+  "Create, configure and checkout a new branch from a pull-request.
+Please see the manual for more information."
+  (interactive (list (magit-read-pull-request "Checkout pull request")))
+  (magit-checkout
+   (let ((inhibit-magit-refresh t))
+     (magit-branch-pull-request pr))))
+
+(defun magit-branch-read-args (prompt)
+  (let ((args (magit-branch-arguments)))
+    (if magit-branch-read-upstream-first
+        (let ((choice (magit-read-starting-point prompt)))
+          (if (magit-rev-verify choice)
+              (list (magit-read-string-ns
+                     (if magit-completing-read--silent-default
+                         (format "%s (starting at `%s')" prompt choice)
+                       "Name for new branch")
+                     (let ((def (mapconcat #'identity
+                                           (cdr (split-string choice "/"))
+                                           "/")))
+                       (and (member choice (magit-list-remote-branch-names))
+                            (not (member def (magit-list-local-branch-names)))
+                            def)))
+                    choice args)
+            (if (eq magit-branch-read-upstream-first 'fallback)
+                (list choice (magit-read-starting-point prompt choice) args)
+              (user-error "Not a valid starting-point: %s" choice))))
+      (let ((branch (magit-read-string-ns (concat prompt " named"))))
+        (list branch
+              (magit-read-starting-point prompt branch)
+              args)))))
+
+;;;###autoload
+(defun magit-branch-spinoff (branch &optional from &rest args)
+  "Create new branch from the unpushed commits.
+
+Create and checkout a new branch starting at and tracking the
+current branch.  That branch in turn is reset to the last commit
+it shares with its upstream.  If the current branch has no
+upstream or no unpushed commits, then the new branch is created
+anyway and the previously current branch is not touched.
+
+This is useful to create a feature branch after work has already
+began on the old branch (likely but not necessarily \"master\").
+
+If the current branch is a member of the value of option
+`magit-branch-prefer-remote-upstream' (which see), then the
+current branch will be used as the starting point as usual, but
+the upstream of the starting-point may be used as the upstream
+of the new branch, instead of the starting-point itself.
+
+If optional FROM is non-nil, then the source branch is reset
+to `FROM~', instead of to the last commit it shares with its
+upstream.  Interactively, FROM is only ever non-nil, if the
+region selects some commits, and among those commits, FROM is
+the commit that is the fewest commits ahead of the source
+branch.
+
+The commit at the other end of the selection actually does not
+matter, all commits between FROM and `HEAD' are moved to the new
+branch.  If FROM is not reachable from `HEAD' or is reachable
+from the source branch's upstream, then an error is raised."
+  (interactive (list (magit-read-string-ns "Spin off branch")
+                     (car (last (magit-region-values 'commit)))
+                     (magit-branch-arguments)))
+  (when (magit-branch-p branch)
+    (user-error "Cannot spin off %s.  It already exists" branch))
+  (if-let ((current (magit-get-current-branch)))
+      (let ((tracked (magit-get-upstream-branch current))
+            base)
+        (when from
+          (unless (magit-rev-ancestor-p from current)
+            (user-error "Cannot spin off %s.  %s is not reachable from %s"
+                        branch from current))
+          (when (and tracked
+                     (magit-rev-ancestor-p from tracked))
+            (user-error "Cannot spin off %s.  %s is ancestor of upstream %s"
+                        branch from tracked)))
+        (let ((magit-process-raise-error t))
+          (magit-call-git "checkout" args "-b" branch current))
+        (--when-let (magit-get-indirect-upstream-branch current)
+          (magit-call-git "branch" "--set-upstream-to" it branch))
+        (when (and tracked
+                   (setq base
+                         (if from
+                             (concat from "^")
+                           (magit-git-string "merge-base" current tracked)))
+                   (not (magit-rev-eq base current)))
+          (magit-call-git "update-ref" "-m"
+                          (format "reset: moving to %s" base)
+                          (concat "refs/heads/" current) base))
+        (magit-refresh))
+    (magit-run-git "checkout" "-b" branch)))
+
+;;;###autoload
+(defun magit-branch-reset (branch to &optional args set-upstream)
+  "Reset a branch to the tip of another branch or any other commit.
+
+When the branch being reset is the current branch, then do a
+hard reset.  If there are any uncommitted changes, then the user
+has to confirm the reset because those changes would be lost.
+
+This is useful when you have started work on a feature branch but
+realize it's all crap and want to start over.
+
+When resetting to another branch and a prefix argument is used,
+then also set the target branch as the upstream of the branch
+that is being reset."
+  (interactive
+   (let* ((atpoint (magit-local-branch-at-point))
+          (branch  (magit-read-local-branch "Reset branch" atpoint)))
+     (list branch
+           (magit-completing-read (format "Reset %s to" branch)
+                                  (delete branch (magit-list-branch-names))
+                                  nil nil nil 'magit-revision-history
+                                  (or (and (not (equal branch atpoint)) atpoint)
+                                      (magit-get-upstream-branch branch)))
+           (magit-branch-arguments)
+           current-prefix-arg)))
+  (unless (member "--force" args)
+    (setq args (cons "--force" args)))
+  (if (equal branch (magit-get-current-branch))
+      (if (and (magit-anything-modified-p)
+               (not (yes-or-no-p "Uncommitted changes will be lost.  Proceed? ")))
+          (user-error "Abort")
+        (magit-reset-hard to)
+        (when (and set-upstream (magit-branch-p to))
+          (magit-set-branch*merge/remote branch to)))
+    (magit-branch branch to args)))
+
+;;;###autoload
+(defun magit-branch-delete (branches &optional force)
+  "Delete one or multiple branches.
+If the region marks multiple branches, then offer to delete
+those, otherwise prompt for a single branch to be deleted,
+defaulting to the branch at point."
+  ;; One would expect this to be a command as simple as, for example,
+  ;; `magit-branch-rename'; but it turns out everyone wants to squeeze
+  ;; a bit of extra functionality into this one, including myself.
+  (interactive
+   (let ((branches (magit-region-values 'branch t))
+         (force current-prefix-arg))
+     (if (> (length branches) 1)
+         (magit-confirm t nil "Delete %i branches" nil branches)
+       (setq branches
+             (list (magit-read-branch-prefer-other
+                    (if force "Force delete branch" "Delete branch")))))
+     (unless force
+       (when-let ((unmerged (-remove #'magit-branch-merged-p branches)))
+         (if (magit-confirm 'delete-unmerged-branch
+               "Delete unmerged branch %s"
+               "Delete %i unmerged branches"
+               'noabort unmerged)
+             (setq force branches)
+           (or (setq branches (-difference branches unmerged))
+               (user-error "Abort")))))
+     (list branches force)))
+  (let* ((refs (mapcar #'magit-ref-fullname branches))
+         (ambiguous (--remove it refs)))
+    (when ambiguous
+      (user-error
+       "%s ambiguous.  Please cleanup using git directly."
+       (let ((len (length ambiguous)))
+         (cond
+          ((= len 1)
+           (format "%s is" (-first #'magit-ref-ambiguous-p branches)))
+          ((= len (length refs))
+           (format "These %s names are" len))
+          (t
+           (format "%s of these names are" len))))))
+    (cond
+     ((string-match "^refs/remotes/\\([^/]+\\)" (car refs))
+      (let* ((remote (match-string 1 (car refs)))
+             (offset (1+ (length remote))))
+        ;; Assume the branches actually still exists on the remote.
+        (magit-run-git-async
+         "push" remote (--map (concat ":" (substring it offset)) branches))
+        ;; If that is not the case, then this deletes the tracking branches.
+        (set-process-sentinel
+         magit-this-process
+         (apply-partially 'magit-delete-remote-branch-sentinel refs))))
+     ((> (length branches) 1)
+      (setq branches (delete (magit-get-current-branch) branches))
+      (mapc 'magit-branch-maybe-delete-pr-remote branches)
+      (mapc 'magit-branch-unset-pushRemote branches)
+      (magit-run-git "branch" (if force "-D" "-d") branches))
+     (t ; And now for something completely different.
+      (let* ((branch (car branches))
+             (prompt (format "Branch %s is checked out.  " branch)))
+        (when (equal branch (magit-get-current-branch))
+          (pcase (if (or (equal branch "master")
+                         (not (magit-rev-verify "master")))
+                     (magit-read-char-case prompt nil
+                       (?d "[d]etach HEAD & delete" 'detach)
+                       (?a "[a]bort"                'abort))
+                   (magit-read-char-case prompt nil
+                     (?d "[d]etach HEAD & delete"     'detach)
+                     (?c "[c]heckout master & delete" 'master)
+                     (?a "[a]bort"                    'abort)))
+            (`detach (unless (or (equal force '(4))
+                                 (member branch force)
+                                 (magit-branch-merged-p branch t))
+                       (magit-confirm 'delete-unmerged-branch
+                         "Delete unmerged branch %s" ""
+                         nil (list branch)))
+                     (magit-call-git "checkout" "--detach"))
+            (`master (unless (or (equal force '(4))
+                                 (member branch force)
+                                 (magit-branch-merged-p branch "master"))
+                       (magit-confirm 'delete-unmerged-branch
+                         "Delete unmerged branch %s" ""
+                         nil (list branch)))
+                     (magit-call-git "checkout" "master"))
+            (`abort  (user-error "Abort")))
+          (setq force t))
+        (magit-branch-maybe-delete-pr-remote branch)
+        (magit-branch-unset-pushRemote branch)
+        (magit-run-git "branch" (if force "-D" "-d") branch))))))
+
+(put 'magit-branch-delete 'interactive-only t)
+
+(defun magit-branch-maybe-delete-pr-remote (branch)
+  (when-let ((remote (magit-get "branch" branch "pullRequestRemote")))
+    (let* ((variable (format "remote.%s.fetch" remote))
+           (refspecs (magit-get-all variable)))
+      (unless (member (format "+refs/heads/*:refs/remotes/%s/*" remote)
+                      refspecs)
+        (let ((refspec
+               (if (equal (magit-get "branch" branch "pushRemote") remote)
+                   (format "+refs/heads/%s:refs/remotes/%s/%s"
+                           branch remote branch)
+                 (let ((merge (magit-get "branch" branch "merge")))
+                   (and merge
+                        (string-prefix-p "refs/heads/" merge)
+                        (setq merge (substring merge 11))
+                        (format "+refs/heads/%s:refs/remotes/%s/%s"
+                                merge remote merge))))))
+          (when (member refspec refspecs)
+            (if (and (= (length refspecs) 1)
+                     (magit-confirm 'delete-pr-remote
+                       (format "Also delete remote %s (%s)" remote
+                               "no pull-request branch remains")))
+                (magit-call-git "remote" "rm" remote)
+              (magit-call-git "config" "--unset" variable
+                              (regexp-quote refspec)))))))))
+
+(defun magit-branch-unset-pushRemote (branch)
+  (magit-set nil "branch" branch "pushRemote"))
+
+(defun magit-delete-remote-branch-sentinel (refs process event)
+  (when (memq (process-status process) '(exit signal))
+    (if (= (process-exit-status process) 0)
+        (magit-process-sentinel process event)
+      (if-let ((rest (-filter #'magit-ref-exists-p refs)))
+          (progn
+            (process-put process 'inhibit-refresh t)
+            (magit-process-sentinel process event)
+            (setq magit-this-error nil)
+            (message "Some remote branches no longer exist.  %s"
+                     "Deleting just the local tracking refs instead...")
+            (dolist (ref rest)
+              (magit-call-git "update-ref" "-d" ref))
+            (magit-refresh)
+            (message "Deleting local remote-tracking refs...done"))
+        (magit-process-sentinel process event)))))
+
+;;;###autoload
+(defun magit-branch-rename (old new &optional force)
+  "Rename the branch named OLD to NEW.
+
+With a prefix argument FORCE, rename even if a branch named NEW
+already exists.
+
+If `branch.OLD.pushRemote' is set, then unset it.  Depending on
+the value of `magit-branch-rename-push-target' (which see) maybe
+set `branch.NEW.pushRemote' and maybe rename the push-target on
+the remote."
+  (interactive
+   (let ((branch (magit-read-local-branch "Rename branch")))
+     (list branch
+           (magit-read-string-ns (format "Rename branch '%s' to" branch)
+                                 nil 'magit-revision-history)
+           current-prefix-arg)))
+  (when (string-match "\\`heads/\\(.+\\)" old)
+    (setq old (match-string 1 old)))
+  (when (equal old new)
+    (user-error "Old and new branch names are the same"))
+  (magit-call-git "branch" (if force "-M" "-m") old new)
+  (when magit-branch-rename-push-target
+    (let ((remote (magit-get-push-remote old))
+          (old-specific (magit-get "branch" old "pushRemote"))
+          (new-specific (magit-get "branch" new "pushRemote")))
+      (when (and old-specific (or force (not new-specific)))
+        ;; Keep the target setting branch specific, even if that is
+        ;; redundant.  But if a branch by the same name existed before
+        ;; and the rename isn't forced, then do not change a leftover
+        ;; setting.  Such a leftover setting may or may not conform to
+        ;; what we expect here...
+        (magit-set old-specific "branch" new "pushRemote"))
+      (when (and (equal (magit-get-push-remote new) remote)
+                 ;; ...and if it does not, then we must abort.
+                 (not (eq magit-branch-rename-push-target 'local-only))
+                 (or (not (eq magit-branch-rename-push-target 'github-only))
+                     (magit--github-remote-p remote)))
+        (let ((old-target (magit-get-push-branch old t))
+              (new-target (magit-get-push-branch new t)))
+          (when (and old-target (not new-target))
+            ;; Rename on (i.e. within) the remote, but only if the
+            ;; destination ref doesn't exist yet.  If that ref already
+            ;; exists, then it probably is of some value and we better
+            ;; not touch it.  Ignore what the local ref points at,
+            ;; i.e. if the local and the remote ref didn't point at
+            ;; the same commit before the rename then keep it that way.
+            (magit-call-git "push" "-v"
+                            (magit-get-push-remote new)
+                            (format "%s:refs/heads/%s" old-target new)
+                            (format ":refs/heads/%s" old)))))))
+  (magit-branch-unset-pushRemote old)
+  (magit-refresh))
+
+;;;###autoload
+(defun magit-branch-shelve (branch)
+  "Shelve a BRANCH.
+Rename \"refs/heads/BRANCH\" to \"refs/shelved/BRANCH\",
+and also rename the respective reflog file."
+  (interactive (list (magit-read-other-local-branch "Shelve branch")))
+  (let ((old (concat "refs/heads/"   branch))
+        (new (concat "refs/shelved/" branch)))
+    (magit-git "update-ref" new old "")
+    (magit--rename-reflog-file old new)
+    (magit-branch-unset-pushRemote branch)
+    (magit-run-git "branch" "-D" branch)))
+
+;;;###autoload
+(defun magit-branch-unshelve (branch)
+  "Unshelve a BRANCH
+Rename \"refs/shelved/BRANCH\" to \"refs/heads/BRANCH\",
+and also rename the respective reflog file."
+  (interactive
+   (list (magit-completing-read
+          "Unshelve branch"
+          (--map (substring it 8)
+                 (magit-list-refnames "refs/shelved"))
+          nil t)))
+  (let ((old (concat "refs/shelved/" branch))
+        (new (concat "refs/heads/"   branch)))
+    (magit-git "update-ref" new old "")
+    (magit--rename-reflog-file old new)
+    (magit-run-git "update-ref" "-d" old)))
+
+(defun magit--rename-reflog-file (old new)
+  (let ((old (magit-git-dir (concat "logs/" old)))
+        (new (magit-git-dir (concat "logs/" new))))
+    (when (file-exists-p old)
+      (make-directory (file-name-directory new) t)
+      (rename-file old new t))))
+
+;;; Config Popup
+
+(defvar magit-branch-config-branch nil)
+
+;;;###autoload
+(defun magit-branch-config-popup (branch)
+  "Popup console for setting branch variables."
+  (interactive
+   (list (if (or current-prefix-arg
+                 (and (eq magit-current-popup 'magit-branch-popup)
+                      magit-branch-popup-show-variables))
+             (magit-read-local-branch "Configure branch")
+           (magit-get-current-branch))))
+  (let ((magit-branch-config-branch branch))
+    (magit-invoke-popup 'magit-branch-config-popup nil nil)))
+
+(defvar magit-branch-config-variables
+  '((lambda ()
+      (concat
+       (propertize "Configure " 'face 'magit-popup-heading)
+       (propertize (magit-branch-config-branch) 'face 'magit-branch-local)))
+    (?d "branch.%s.description"
+        magit-edit-branch*description
+        magit-format-branch*description)
+    (?u "branch.%s.merge"
+        magit-set-branch*merge/remote
+        magit-format-branch*merge/remote)
+    (?r "branch.%s.rebase"
+        magit-cycle-branch*rebase
+        magit-format-branch*rebase)
+    (?p "branch.%s.pushRemote"
+        magit-cycle-branch*pushRemote
+        magit-format-branch*pushRemote)
+    "Configure repository defaults"
+    (?\M-r "pull.rebase"
+           magit-cycle-pull.rebase
+           magit-format-pull.rebase)
+    (?\M-p "remote.pushDefault"
+           magit-cycle-remote.pushDefault
+           magit-format-remote.pushDefault)
+    "Configure branch creation"
+    (?U "branch.autoSetupMerge"
+        magit-cycle-branch*autoSetupMerge
+        magit-format-branch*autoSetupMerge)
+    (?R "branch.autoSetupRebase"
+        magit-cycle-branch*autoSetupRebase
+        magit-format-branch*autoSetupRebase)))
+
+(defvar magit-branch-config-popup
+  `(:man-page "git-branch"
+    :variables ,magit-branch-config-variables
+    :setup-function magit-branch-config-popup-setup))
+
+(defun magit-branch-config-popup-setup (val def)
+  (magit-popup-default-setup val def)
+  (setq-local magit-branch-config-branch magit-branch-config-branch)
+  (use-local-map (copy-keymap magit-popup-mode-map))
+  (dolist (ev (-filter #'magit-popup-event-p (magit-popup-get :variables)))
+    (local-set-key (vector (magit-popup-event-key ev))
+                   'magit-invoke-popup-action)))
+
+(defun magit-branch-config-branch (&optional prompt)
+  (if prompt
+      (or (and (not current-prefix-arg)
+               (or magit-branch-config-branch
+                   (magit-get-current-branch)))
+          (magit-read-local-branch prompt))
+    (or magit-branch-config-branch
+        (magit-get-current-branch)
+        "<name>")))
+
+;;; Config Commands and Inserters
+
+;;;###autoload
+(defun magit-edit-branch*description (branch)
+  "Edit the description of the current branch.
+With a prefix argument edit the description of another branch.
+
+The description for the branch named NAME is stored in the Git
+variable `branch.<name>.description'."
+  (interactive (list (magit-branch-config-branch "Edit branch description")))
+  (magit-run-git-with-editor "branch" "--edit-description" branch))
+
+(defun magit-edit-branch*description-check-buffers ()
+  (and buffer-file-name
+       (string-match-p "/\\(BRANCH\\|EDIT\\)_DESCRIPTION\\'" buffer-file-name)
+       (add-hook 'with-editor-post-finish-hook
+                 (lambda ()
+                   (when (derived-mode-p 'magit-popup-mode)
+                     (magit-refresh-popup-buffer)))
+                 nil t)))
+
+(add-hook 'find-file-hook 'magit-edit-branch*description-check-buffers)
+
+(defun magit-format-branch*description ()
+  (let* ((branch (magit-branch-config-branch))
+         (width (+ (length branch) 19))
+         (var (format "branch.%s.description" branch)))
+    (concat var " " (make-string (- width (length var)) ?\s)
+            (if-let ((value (magit-get var)))
+                (propertize (car (split-string value "\n"))
+                            'face 'magit-popup-option-value)
+              (propertize "unset" 'face 'magit-popup-disabled-argument)))))
+
+;;;###autoload
+(defun magit-set-branch*merge/remote (branch upstream)
+  "Set or unset the upstream of the current branch.
+With a prefix argument do so for another branch.
+
+When the branch in question already has an upstream then simply
+unsets it.  Invoke this command again to set another upstream.
+
+Together the Git variables `branch.<name>.remote' and
+`branch.<name>.merge' define the upstream branch of the local
+branch named NAME.  The value of `branch.<name>.remote' is the
+name of the upstream remote.  The value of `branch.<name>.merge'
+is the full reference of the upstream branch, on the remote.
+
+Non-interactively, when UPSTREAM is non-nil, then always set it
+as the new upstream, regardless of whether another upstream was
+already set.  When nil, then always unset."
+  (interactive
+   (let ((branch (magit-branch-config-branch "Change upstream of branch")))
+     (list branch (and (not (magit-get-upstream-branch branch))
+                       (magit-read-upstream-branch branch)))))
+  (if upstream
+      (pcase-let ((`(,remote . ,merge) (magit-split-branch-name upstream)))
+        (setf (magit-get (format "branch.%s.remote" branch)) remote)
+        (setf (magit-get (format "branch.%s.merge"  branch))
+              (concat "refs/heads/" merge)))
+    (magit-call-git "branch" "--unset-upstream" branch))
+  (when (called-interactively-p 'any)
+    (magit-refresh)))
+
+(defun magit-format-branch*merge/remote ()
+  (let* ((branch (magit-branch-config-branch))
+         (width (+ (length branch) 20))
+         (varM (format "branch.%s.merge" branch))
+         (varR (format "branch.%s.remote" branch))
+         (face (if (equal (magit-get varR) ".")
+                   'magit-branch-local
+                 'magit-branch-remote)))
+    (concat varM (make-string (- width (length varM)) ?\s)
+            (if-let ((value (magit-get varM)))
+                (propertize value 'face face)
+              (propertize "unset" 'face 'magit-popup-disabled-argument))
+            "\n   " varR (make-string (- width (length varR)) ?\s)
+            (if-let ((value (magit-get varR)))
+                (propertize value 'face face)
+              (propertize "unset" 'face 'magit-popup-disabled-argument)))))
+
+;;;###autoload
+(defun magit-cycle-branch*rebase (branch)
+  "Cycle the value of `branch.<name>.rebase' for the current branch.
+With a prefix argument cycle the value for another branch.
+
+The Git variables `branch.<name>.rebase' controls whether pulling
+into the branch named NAME is done by rebasing that branch onto
+the fetched branch or by merging that branch.
+
+When `true' then pulling is done by rebasing.
+When `false' then pulling is done by merging.
+
+When that variable is undefined then the value of `pull.rebase'
+is used instead.  It defaults to `false'."
+  (interactive (list (magit-branch-config-branch
+                      "Cycle branch.<name>.rebase for")))
+  (magit--set-popup-variable (format "branch.%s.rebase" branch)
+                             '("true" "false")
+                             "false" "pull.rebase"))
+
+(defun magit-format-branch*rebase ()
+  (let ((branch (magit-branch-config-branch)))
+    (magit--format-popup-variable:choices
+     (format "branch.%s.rebase" branch)
+     '("true" "false")
+     "false" "pull.rebase"
+     (+ (length branch) 20))))
+
+;;;###autoload
+(defun magit-cycle-branch*pushRemote (branch)
+  "Cycle the value of `branch.<name>.pushRemote' for the current branch.
+With a prefix argument cycle the value for another branch.
+
+The Git variable `branch.<name>.pushRemote' specifies the remote
+that the branch named NAME is usually pushed to.  The value has
+to be the name of an existing remote.
+
+If that variable is undefined, then the value of the Git variable
+`remote.pushDefault' is used instead, provided that it is defined,
+which by default it is not."
+  (interactive (list (magit-branch-config-branch
+                      "Cycle branch.<name>.pushRemote for")))
+  (magit--set-popup-variable (format "branch.%s.pushRemote" branch)
+                             (magit-list-remotes)
+                             "remote.pushDefault"))
+
+(defun magit-format-branch*pushRemote ()
+  (let ((branch (magit-branch-config-branch)))
+    (magit--format-popup-variable:choices
+     (format "branch.%s.pushRemote" branch)
+     (magit-list-remotes)
+     nil "remote.pushDefault"
+     (+ (length branch) 20))))
+
+;;;###autoload
+(defun magit-cycle-pull.rebase ()
+  "Cycle the repository-local value of `pull.rebase'.
+
+The Git variable `pull.rebase' specifies whether pulling is done
+by rebasing or by merging.  It can be overwritten using the Git
+variable `branch.<name>.rebase'.
+
+When `true' then pulling is done by rebasing.
+When `false' (the default) then pulling is done by merging."
+  (interactive)
+  (magit--set-popup-variable "pull.rebase" '("true" "false") "false"))
+
+(defun magit-format-pull.rebase ()
+  (magit--format-popup-variable:choices
+   "pull.rebase" '("true" "false") "false" nil 19))
+
+;;;###autoload
+(defun magit-cycle-remote.pushDefault ()
+  "Cycle the repository-local value of `remote.pushDefault'.
+
+The Git variable `remote.pushDefault' specifies the remote that
+local branches are usually pushed to.  It can be overwritten
+using the Git variable `branch.<name>.pushRemote'."
+  (interactive)
+  (magit--set-popup-variable "remote.pushDefault" (magit-list-remotes)))
+
+(defun magit-format-remote.pushDefault ()
+  (magit--format-popup-variable:choices
+   "remote.pushDefault" (magit-list-remotes) nil nil 19))
+
+;;;###autoload
+(defun magit-cycle-branch*autoSetupMerge ()
+  "Cycle the repository-local value of `branch.autoSetupMerge'.
+
+The Git variable `branch.autoSetupMerge' under what circumstances
+creating a branch (named NAME) should result in the variables
+`branch.<name>.merge' and `branch.<name>.remote' being set
+according to the starting point used to create the branch.  If
+the starting point isn't a branch, then these variables are never
+set.
+
+When `always' then the variables are set regardless of whether
+the starting point is a local or a remote branch.
+
+When `true' (the default) then the variable are set when the
+starting point is a remote branch, but not when it is a local
+branch.
+
+When `false' then the variables are never set."
+  (interactive)
+  (magit--set-popup-variable "branch.autoSetupMerge"
+                             '("always" "true" "false") "true"))
+
+(defun magit-format-branch*autoSetupMerge ()
+  (magit--format-popup-variable:choices
+   "branch.autoSetupMerge" '("always" "true" "false") "true" nil 23))
+
+;;;###autoload
+(defun magit-cycle-branch*autoSetupRebase ()
+  "Cycle the repository-local value of `branch.autoSetupRebase'.
+
+The Git variable `branch.autoSetupRebase' specifies whether
+creating a branch (named NAME) should result in the variable
+`branch.<name>.rebase' being set to `true'.
+
+When `always' then the variable is set regardless of whether the
+starting point is a local or a remote branch.
+
+When `local' then the variable are set when the starting point
+is a local branch, but not when it is a remote branch.
+
+When `remote' then the variable are set when the starting point
+is a remote branch, but not when it is a local branch.
+
+When `never' (the default) then the variable is never set."
+  (interactive)
+  (magit--set-popup-variable "branch.autoSetupRebase"
+                             '("always" "local" "remote" "never") "never"))
+
+(defun magit-format-branch*autoSetupRebase ()
+  (magit--format-popup-variable:choices
+   "branch.autoSetupRebase"
+   '("always" "local" "remote" "never")
+   "never" nil 23))
+
+(provide 'magit-branch)
+;;; magit-branch.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-branch.elc b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-branch.elc
new file mode 100644
index 0000000000..c04be82837
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-branch.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-collab.el b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-collab.el
new file mode 100644
index 0000000000..7c4b1a2671
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-collab.el
@@ -0,0 +1,171 @@
+;;; magit-collab.el --- collaboration tools       -*- lexical-binding: t -*-
+
+;; Copyright (C) 2010-2018  The Magit Project Contributors
+;;
+;; You should have received a copy of the AUTHORS.md file which
+;; lists all contributors.  If not, see http://magit.vc/authors.
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; Magit 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, or (at your option)
+;; any later version.
+;;
+;; Magit 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 Magit.  If not, see http://www.gnu.org/licenses.
+
+;;; Commentary:
+
+;; This library implements various collaboration tools.  These tools
+;; are only early incarnation -- implementing collaboration tools is
+;; a top priority for future development.
+
+;; Currently these tools (including `magit-branch-pull-request', which
+;; is defined elsewhere) only support Github, but support for other
+;; Git forges as well as mailing list based collaboration is in
+;; planning.
+
+;;; Code:
+
+(require 'magit)
+(require 'ghub)
+
+;;; Variables
+
+(defvar magit-github-token-scopes '(repo)
+  "The Github API scopes needed by Magit.
+
+`repo' is the only required scope.  Without this scope none of
+Magit's features that use the API work.  Instead of this scope
+you could use `public_repo' if you are only interested in public
+repositories.
+
+`repo' Grants read/write access to code, commit statuses,
+  invitations, collaborators, adding team memberships, and
+  deployment statuses for public and private repositories
+  and organizations.
+
+`public_repo' Grants read/write access to code, commit statuses,
+  collaborators, and deployment statuses for public repositories
+  and organizations. Also required for starring public
+  repositories.")
+
+;;; Commands
+
+;;;###autoload
+(defun magit-browse-pull-request (pr)
+  "Visit pull-request PR using `browse-url'.
+
+Currently this only supports Github, but that restriction will
+be lifted eventually to support other Git forges."
+  (interactive (list (magit-read-pull-request "Visit pull request")))
+  (browse-url (format "https://github.com/%s/pull/%s"
+                      (--> pr
+                           (cdr (assq 'base it))
+                           (cdr (assq 'repo it))
+                           (cdr (assq 'full_name it)))
+                      (cdr (assq 'number pr)))))
+
+;;; Utilities
+
+(defun magit-read-pull-request (prompt)
+  "Read a pull request from the user, prompting with PROMPT.
+Return the Git forge's API response.  Currently this function
+only supports Github, but that will change eventually."
+  (let* ((origin (magit-upstream-repository))
+         (id     (magit--forge-id origin))
+         (fmtfun (lambda (pull-request)
+                   (format "%s  %s"
+                           (cdr (assq 'number pull-request))
+                           (cdr (assq 'title  pull-request)))))
+         (prs    (ghub-get (format "/repos/%s/pulls" id) nil :auth 'magit))
+         (choice (magit-completing-read
+                  prompt (mapcar fmtfun prs) nil nil nil nil
+                  (let ((default (thing-at-point 'github-pull-request)))
+                    (and default (funcall fmtfun default)))))
+         (number (and (string-match "\\([0-9]+\\)" choice)
+                      (string-to-number (match-string 1 choice)))))
+    (and number
+         ;; Don't reuse the pr from the list, it lacks some information
+         ;; that is only returned when requesting a single pr.  #3371
+         (ghub-get (format "/repos/%s/pulls/%s" id number)
+                   nil :auth 'magit))))
+
+(defun magit-upstream-repository ()
+  "Return the remote name of the upstream repository.
+
+If the Git variable `magit.upstream' is set, then return its
+value.  Otherwise return \"origin\".  If the remote does not
+exist, then raise an error."
+  (let ((remote (or (magit-get "magit.upstream") "origin")))
+    (unless (magit-remote-p remote)
+      (error "No remote named `%s' exists (consider setting `magit.upstream')"
+             remote))
+    (unless (magit--github-remote-p remote)
+      (error "Currently only Github is supported"))
+    remote))
+
+(defun magit--forge-id (remote)
+  (let ((url (magit-get "remote" remote "url")))
+    (and (string-match "\\([^:/]+/[^/]+?\\)\\(?:\\.git\\)?\\'" url)
+         (match-string 1 url))))
+
+(defconst magit--github-url-regexp "\
+\\`\\(?:git://\\|git@\\|ssh://git@\\|https://\\)\
+\\(.*?\\)[/:]\
+\\(\\([^:/]+\\)/\\([^/]+?\\)\\)\
+\\(?:\\.git\\)?\\'")
+
+(defun magit--github-url-p (url)
+  (save-match-data
+    (and url
+         (string-match magit--github-url-regexp url)
+         (let ((host (match-string 1 url)))
+           ;; Match values like "github.com-as-someone", which are
+           ;; translated to just "github.com" according to settings
+           ;; in "~/.ssh/config".  Theoretically this could result
+           ;; in false-positives, but that's rather unlikely.  #3392
+           (and (or (string-match-p (regexp-quote "github.com") host)
+                    (string-match-p (regexp-quote (ghub--host)) host))
+                host)))))
+
+(defun magit--github-remote-p (remote)
+  (or (--when-let (magit-git-string "remote" "get-url" "--push" remote)
+        (magit--github-url-p it))
+      (--when-let (magit-git-string "remote" "get-url" "--all" remote)
+        (magit--github-url-p it))))
+
+(defun magit--github-url-equal (r1 r2)
+  (or (equal r1 r2)
+      (save-match-data
+        (let ((n1 (and (string-match magit--github-url-regexp r1)
+                       (match-string 2 r1)))
+              (n2 (and (string-match magit--github-url-regexp r2)
+                       (match-string 2 r2))))
+          (and n1 n2 (equal n1 n2))))))
+
+(defun magit--pullreq-from-upstream-p (pr)
+  (let-alist pr
+    (equal .head.repo.full_name
+           .base.repo.full_name)))
+
+(defun magit--pullreq-branch (pr &optional assert-new)
+  (let-alist pr
+    (let ((branch .head.ref))
+      (when (and (not (magit--pullreq-from-upstream-p pr))
+                 (or (not .maintainer_can_modify)
+                     (magit-branch-p branch)))
+        (setq branch (format "pr-%s" .number)))
+      (when (and assert-new (magit-branch-p branch))
+        (user-error "Branch `%s' already exists" branch))
+      branch)))
+
+(provide 'magit-collab)
+;;; magit-collab.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-collab.elc b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-collab.elc
new file mode 100644
index 0000000000..f4ffdc0348
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-collab.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-commit.el b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-commit.el
new file mode 100644
index 0000000000..a1720e746d
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-commit.el
@@ -0,0 +1,485 @@
+;;; magit-commit.el --- create Git commits  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2008-2018  The Magit Project Contributors
+;;
+;; You should have received a copy of the AUTHORS.md file which
+;; lists all contributors.  If not, see http://magit.vc/authors.
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; Magit 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, or (at your option)
+;; any later version.
+;;
+;; Magit 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 Magit.  If not, see http://www.gnu.org/licenses.
+
+;;; Commentary:
+
+;; This library implements commands for creating Git commits.  These
+;; commands just initiate the commit, support for writing the commit
+;; messages is implemented in `git-commit.el'.
+
+;;; Code:
+
+(require 'magit)
+(require 'magit-sequence)
+
+(eval-when-compile (require 'epa)) ; for `epa-protocol'
+(eval-when-compile (require 'epg))
+
+;;; Options
+
+(defcustom magit-commit-arguments nil
+  "The arguments used when committing."
+  :group 'magit-git-arguments
+  :type '(repeat (string :tag "Argument")))
+
+(defcustom magit-commit-ask-to-stage 'verbose
+  "Whether to ask to stage all unstaged changes when committing and nothing is staged."
+  :package-version '(magit . "2.3.0")
+  :group 'magit-commands
+  :type '(choice (const :tag "Ask showing diff" verbose)
+                 (const :tag "Ask" t)
+                 (const :tag "Don't ask" nil)))
+
+(defcustom magit-commit-show-diff t
+  "Whether the relevant diff is automatically shown when committing."
+  :package-version '(magit . "2.3.0")
+  :group 'magit-commands
+  :type 'boolean)
+
+(defcustom magit-commit-extend-override-date t
+  "Whether using `magit-commit-extend' changes the committer date."
+  :package-version '(magit . "2.3.0")
+  :group 'magit-commands
+  :type 'boolean)
+
+(defcustom magit-commit-reword-override-date t
+  "Whether using `magit-commit-reword' changes the committer date."
+  :package-version '(magit . "2.3.0")
+  :group 'magit-commands
+  :type 'boolean)
+
+(defcustom magit-commit-squash-confirm t
+  "Whether the commit targeted by squash and fixup has to be confirmed.
+When non-nil then the commit at point (if any) is used as default
+choice, otherwise it has to be confirmed.  This option only
+affects `magit-commit-squash' and `magit-commit-fixup'.  The
+\"instant\" variants always require confirmation because making
+an error while using those is harder to recover from."
+  :package-version '(magit . "2.1.0")
+  :group 'magit-commands
+  :type 'boolean)
+
+;;; Popup
+
+(defun magit-commit-popup (&optional arg)
+  "Popup console for commit commands."
+  (interactive "P")
+  (--if-let (magit-commit-message-buffer)
+      (switch-to-buffer it)
+    (magit-invoke-popup 'magit-commit-popup nil arg)))
+
+(defvar magit-commit-popup
+  '(:variable magit-commit-arguments
+    :man-page "git-commit"
+    :switches ((?a "Stage all modified and deleted files"   "--all")
+               (?e "Allow empty commit"                     "--allow-empty")
+               (?v "Show diff of changes to be committed"   "--verbose")
+               (?h "Disable hooks"                          "--no-verify")
+               (?s "Add Signed-off-by line"                 "--signoff")
+               (?R "Claim authorship and reset author date" "--reset-author"))
+    :options  ((?A "Override the author"  "--author=")
+               (?S "Sign using gpg"       "--gpg-sign=" magit-read-gpg-secret-key)
+               (?C "Reuse commit message" "--reuse-message="
+                   magit-read-reuse-message))
+    :actions  ((?c "Commit"         magit-commit)
+               (?e "Extend"         magit-commit-extend)
+               (?f "Fixup"          magit-commit-fixup)
+               (?F "Instant Fixup"  magit-commit-instant-fixup) nil
+               (?w "Reword"         magit-commit-reword)
+               (?s "Squash"         magit-commit-squash)
+               (?S "Instant Squash" magit-commit-instant-squash) nil
+               (?a "Amend"          magit-commit-amend)
+               (?A "Augment"        magit-commit-augment))
+    :max-action-columns 4
+    :default-action magit-commit))
+
+(magit-define-popup-keys-deferred 'magit-commit-popup)
+
+(defun magit-commit-arguments nil
+  (if (eq magit-current-popup 'magit-commit-popup)
+      magit-current-popup-args
+    magit-commit-arguments))
+
+(defvar magit-gpg-secret-key-hist nil)
+
+(defun magit-read-gpg-secret-key (prompt &optional _initial-input)
+  (require 'epa)
+  (let ((keys (--map (concat (epg-sub-key-id (car (epg-key-sub-key-list it)))
+                             " "
+                             (when-let ((id-obj (car (epg-key-user-id-list it))))
+                               (let ((id-str (epg-user-id-string id-obj)))
+                                 (if (stringp id-str)
+                                     id-str
+                                   (epg-decode-dn id-obj)))))
+                     (epg-list-keys (epg-make-context epa-protocol) nil t))))
+    (car (split-string (magit-completing-read
+                        prompt keys nil nil nil 'magit-gpg-secret-key-hist
+                        (car (or magit-gpg-secret-key-hist keys)))
+                       " "))))
+
+(defun magit-read-reuse-message (prompt &optional default)
+  (magit-completing-read prompt (magit-list-refnames)
+                         nil nil nil 'magit-revision-history
+                         (or default
+                             (and (magit-rev-verify "ORIG_HEAD")
+                                  "ORIG_HEAD"))))
+
+;;; Commands
+
+;;;###autoload
+(defun magit-commit (&optional args)
+  "Create a new commit on `HEAD'.
+With a prefix argument, amend to the commit at `HEAD' instead.
+\n(git commit [--amend] ARGS)"
+  (interactive (if current-prefix-arg
+                   (list (cons "--amend" (magit-commit-arguments)))
+                 (list (magit-commit-arguments))))
+  (when (member "--all" args)
+    (setq this-command 'magit-commit-all))
+  (when (setq args (magit-commit-assert args))
+    (let ((default-directory (magit-toplevel)))
+      (magit-run-git-with-editor "commit" args))))
+
+;;;###autoload
+(defun magit-commit-amend (&optional args)
+  "Amend the last commit.
+\n(git commit --amend ARGS)"
+  (interactive (list (magit-commit-arguments)))
+  (magit-commit-amend-assert)
+  (magit-run-git-with-editor "commit" "--amend" args))
+
+;;;###autoload
+(defun magit-commit-extend (&optional args override-date)
+  "Amend the last commit, without editing the message.
+
+With a prefix argument keep the committer date, otherwise change
+it.  The option `magit-commit-extend-override-date' can be used
+to inverse the meaning of the prefix argument.  \n(git commit
+--amend --no-edit)"
+  (interactive (list (magit-commit-arguments)
+                     (if current-prefix-arg
+                         (not magit-commit-extend-override-date)
+                       magit-commit-extend-override-date)))
+  (when (setq args (magit-commit-assert args (not override-date)))
+    (magit-commit-amend-assert)
+    (let ((process-environment process-environment))
+      (unless override-date
+        (push (magit-rev-format "GIT_COMMITTER_DATE=%cD") process-environment))
+      (magit-run-git-with-editor "commit" "--amend" "--no-edit" args))))
+
+;;;###autoload
+(defun magit-commit-reword (&optional args override-date)
+  "Reword the last commit, ignoring staged changes.
+
+With a prefix argument keep the committer date, otherwise change
+it.  The option `magit-commit-reword-override-date' can be used
+to inverse the meaning of the prefix argument.
+
+Non-interactively respect the optional OVERRIDE-DATE argument
+and ignore the option.
+\n(git commit --amend --only)"
+  (interactive (list (magit-commit-arguments)
+                     (if current-prefix-arg
+                         (not magit-commit-reword-override-date)
+                       magit-commit-reword-override-date)))
+  (magit-commit-amend-assert)
+  (let ((process-environment process-environment))
+    (unless override-date
+      (push (magit-rev-format "GIT_COMMITTER_DATE=%cD") process-environment))
+    (magit-run-git-with-editor "commit" "--amend" "--only" args)))
+
+;;;###autoload
+(defun magit-commit-fixup (&optional commit args)
+  "Create a fixup commit.
+
+With a prefix argument the target COMMIT has to be confirmed.
+Otherwise the commit at point may be used without confirmation
+depending on the value of option `magit-commit-squash-confirm'."
+  (interactive (list (magit-commit-at-point)
+                     (magit-commit-arguments)))
+  (magit-commit-squash-internal "--fixup" commit args))
+
+;;;###autoload
+(defun magit-commit-squash (&optional commit args)
+  "Create a squash commit, without editing the squash message.
+
+With a prefix argument the target COMMIT has to be confirmed.
+Otherwise the commit at point may be used without confirmation
+depending on the value of option `magit-commit-squash-confirm'."
+  (interactive (list (magit-commit-at-point)
+                     (magit-commit-arguments)))
+  (magit-commit-squash-internal "--squash" commit args))
+
+;;;###autoload
+(defun magit-commit-augment (&optional commit args)
+  "Create a squash commit, editing the squash message.
+
+With a prefix argument the target COMMIT has to be confirmed.
+Otherwise the commit at point may be used without confirmation
+depending on the value of option `magit-commit-squash-confirm'."
+  (interactive (list (magit-commit-at-point)
+                     (magit-commit-arguments)))
+  (magit-commit-squash-internal "--squash" commit args nil t))
+
+;;;###autoload
+(defun magit-commit-instant-fixup (&optional commit args)
+  "Create a fixup commit targeting COMMIT and instantly rebase."
+  (interactive (list (magit-commit-at-point)
+                     (magit-commit-arguments)))
+  (magit-commit-squash-internal "--fixup" commit args t))
+
+;;;###autoload
+(defun magit-commit-instant-squash (&optional commit args)
+  "Create a squash commit targeting COMMIT and instantly rebase."
+  (interactive (list (magit-commit-at-point)
+                     (magit-commit-arguments)))
+  (magit-commit-squash-internal "--squash" commit args t))
+
+(defun magit-commit-squash-internal
+    (option commit &optional args rebase edit confirmed)
+  (when-let ((args (magit-commit-assert args t)))
+    (when commit
+      (when (and rebase (not (magit-rev-ancestor-p commit "HEAD")))
+        (magit-read-char-case
+            (format "%s isn't an ancestor of HEAD.  " commit) nil
+          (?c "[c]reate without rebasing" (setq rebase nil))
+          (?s "[s]elect other"            (setq commit nil))
+          (?a "[a]bort"                   (user-error "Quit")))))
+    (when commit
+      (setq commit (magit-rebase-interactive-assert commit t)))
+    (if (and commit
+             (or confirmed
+                 (not (or rebase
+                          current-prefix-arg
+                          magit-commit-squash-confirm))))
+        (let ((magit-commit-show-diff nil))
+          (push (concat option "=" commit) args)
+          (unless edit
+            (push "--no-edit" args))
+          (if rebase
+              (magit-with-editor
+                (magit-call-git
+                 "commit" "--no-gpg-sign"
+                 (-remove-first
+                  (apply-partially #'string-match-p "\\`--gpg-sign=")
+                  args)))
+            (magit-run-git-with-editor "commit" args))
+          t) ; The commit was created; used by below lambda.
+      (magit-log-select
+        (lambda (commit)
+          (when (and (magit-commit-squash-internal option commit args
+                                                   rebase edit t)
+                     rebase)
+            (magit-commit-amend-assert commit)
+            (magit-rebase-interactive-1 commit
+                (list "--autosquash" "--autostash")
+              "" "true" nil t)))
+        (format "Type %%p on a commit to %s into it,"
+                (substring option 2))
+        nil nil (list "--graph"))
+      (when magit-commit-show-diff
+        (let ((magit-display-buffer-noselect t))
+          (apply #'magit-diff-staged nil (magit-diff-arguments)))))))
+
+(defun magit-commit-amend-assert (&optional commit)
+  (--when-let (magit-list-publishing-branches commit)
+    (let ((m1 "This commit has already been published to ")
+          (m2 ".\nDo you really want to modify it"))
+      (magit-confirm 'amend-published
+        (concat m1 "%s" m2)
+        (concat m1 "%i public branches" m2)
+        nil it))))
+
+(defun magit-commit-assert (args &optional strict)
+  (cond
+   ((or (magit-anything-staged-p)
+        (and (magit-anything-unstaged-p)
+             ;; ^ Everything of nothing is still nothing.
+             (member "--all" args))
+        (and (not strict)
+             ;; ^ For amend variants that don't make sense otherwise.
+             (or (member "--amend" args)
+                 (member "--allow-empty" args))))
+    (or args (list "--")))
+   ((and (magit-rebase-in-progress-p)
+         (not (magit-anything-unstaged-p))
+         (y-or-n-p "Nothing staged.  Continue in-progress rebase? "))
+    (magit-run-git-sequencer "rebase" "--continue")
+    nil)
+   ((and (file-exists-p (magit-git-dir "MERGE_MSG"))
+         (not (magit-anything-unstaged-p)))
+    (or args (list "--")))
+   ((not (magit-anything-unstaged-p))
+    (user-error "Nothing staged (or unstaged)"))
+   (magit-commit-ask-to-stage
+    (when (eq magit-commit-ask-to-stage 'verbose)
+      (magit-diff-unstaged))
+    (prog1 (when (y-or-n-p "Nothing staged.  Stage and commit all unstaged changes? ")
+             (magit-run-git "add" "-u" ".")
+             (or args (list "--")))
+      (when (and (eq magit-commit-ask-to-stage 'verbose)
+                 (derived-mode-p 'magit-diff-mode))
+        (magit-mode-bury-buffer))))
+   (t
+    (user-error "Nothing staged"))))
+
+(defvar magit--reshelve-history nil)
+
+;;;###autoload
+(defun magit-commit-reshelve (date)
+  "Change the committer date and possibly the author date of `HEAD'.
+
+If you are the author of `HEAD', then both dates are changed,
+otherwise only the committer date.  The current time is used
+as the initial minibuffer input and the original author (if
+that is you) or committer date is available as the previous
+history element."
+  (interactive
+   (let ((author-p (magit-rev-author-p "HEAD")))
+     (push (magit-rev-format (if author-p "%ad" "%cd") "HEAD"
+                             (concat "--date=format:%F %T %z"))
+           magit--reshelve-history)
+     (list (read-string (if author-p
+                            "Change author and committer dates to: "
+                          "Change committer date to: ")
+                        (cons (format-time-string "%F %T %z") 17)
+                        'magit--reshelve-history))))
+  (let ((process-environment process-environment))
+    (push (concat "GIT_COMMITTER_DATE=" date) process-environment)
+    (magit-run-git "commit" "--amend" "--no-edit"
+                   (and (magit-rev-author-p "HEAD")
+                        (concat "--date=" date)))))
+
+;;; Pending Diff
+
+(defun magit-commit-diff ()
+  (when (and git-commit-mode magit-commit-show-diff)
+    (when-let ((diff-buffer (magit-mode-get-buffer 'magit-diff-mode)))
+      ;; This window just started displaying the commit message
+      ;; buffer.  Without this that buffer would immediately be
+      ;; replaced with the diff buffer.  See #2632.
+      (unrecord-window-buffer nil diff-buffer))
+    (condition-case nil
+        (let ((args (car (magit-diff-arguments)))
+              (magit-inhibit-save-previous-winconf 'unset)
+              (magit-display-buffer-noselect t)
+              (inhibit-quit nil))
+          (message "Diffing changes to be committed (C-g to abort diffing)")
+          (if-let ((fn (cl-case last-command
+                         (magit-commit
+                          (apply-partially 'magit-diff-staged nil))
+                         (magit-commit-all
+                          (apply-partially 'magit-diff-working-tree nil))
+                         ((magit-commit-amend
+                           magit-commit-reword
+                           magit-rebase-reword-commit)
+                          'magit-diff-while-amending))))
+              (funcall fn args)
+            (if (magit-anything-staged-p)
+                (magit-diff-staged nil args)
+              (magit-diff-while-amending args))))
+      (quit))))
+
+;; Mention `magit-diff-while-committing' because that's
+;; always what I search for when I try to find this line.
+(add-hook 'server-switch-hook 'magit-commit-diff)
+
+(add-to-list 'with-editor-server-window-alist
+             (cons git-commit-filename-regexp 'switch-to-buffer))
+
+;;; Message Utilities
+
+(defun magit-commit-message-buffer ()
+  (let* ((find-file-visit-truename t) ; git uses truename of COMMIT_EDITMSG
+         (topdir (magit-toplevel)))
+    (--first (equal topdir (with-current-buffer it
+                             (and git-commit-mode (magit-toplevel))))
+             (append (buffer-list (selected-frame))
+                     (buffer-list)))))
+
+(defvar magit-commit-add-log-insert-function 'magit-commit-add-log-insert
+  "Used by `magit-commit-add-log' to insert a single entry.")
+
+(defun magit-commit-add-log ()
+  "Add a stub for the current change into the commit message buffer.
+If no commit is in progress, then initiate it.  Use the function
+specified by variable `magit-commit-add-log-insert-function' to
+actually insert the entry."
+  (interactive)
+  (let ((hunk (magit-section-when 'hunk it))
+        (log (magit-commit-message-buffer)) buf pos)
+    (save-window-excursion
+      (call-interactively #'magit-diff-visit-file)
+      (setq buf (current-buffer))
+      (setq pos (point)))
+    (unless log
+      (unless (magit-commit-assert nil)
+        (user-error "Abort"))
+      (magit-commit)
+      (while (not (setq log (magit-commit-message-buffer)))
+        (sit-for 0.01)))
+    (save-excursion
+      (with-current-buffer buf
+        (goto-char pos)
+        (funcall magit-commit-add-log-insert-function log
+                 (magit-file-relative-name)
+                 (and hunk (add-log-current-defun)))))))
+
+(defun magit-commit-add-log-insert (buffer file defun)
+  (with-current-buffer buffer
+    (undo-boundary)
+    (goto-char (point-max))
+    (while (re-search-backward (concat "^" comment-start) nil t))
+    (save-restriction
+      (narrow-to-region (point-min) (point))
+      (cond ((re-search-backward (format "* %s\\(?: (\\([^)]+\\))\\)?: " file)
+                                 nil t)
+             (when (equal (match-string 1) defun)
+               (setq defun nil))
+             (re-search-forward ": "))
+            (t
+             (when (re-search-backward "^[\\*(].+\n" nil t)
+               (goto-char (match-end 0)))
+             (while (re-search-forward "^[^\\*\n].*\n" nil t))
+             (if defun
+                 (progn (insert (format "* %s (%s): \n" file defun))
+                        (setq defun nil))
+               (insert (format "* %s: \n" file)))
+             (backward-char)
+             (unless (looking-at "\n[\n\\']")
+               (insert ?\n)
+               (backward-char))))
+      (when defun
+        (forward-line)
+        (let ((limit (save-excursion
+                       (and (re-search-forward "^\\*" nil t)
+                            (point)))))
+          (unless (or (looking-back (format "(%s): " defun)
+                                    (line-beginning-position))
+                      (re-search-forward (format "^(%s): " defun) limit t))
+            (while (re-search-forward "^[^\\*\n].*\n" limit t))
+            (insert (format "(%s): \n" defun))
+            (backward-char)))))))
+
+(provide 'magit-commit)
+;;; magit-commit.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-commit.elc b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-commit.elc
new file mode 100644
index 0000000000..1c0430bdc1
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-commit.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-core.el b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-core.el
new file mode 100644
index 0000000000..106186eae4
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-core.el
@@ -0,0 +1,132 @@
+;;; magit-core.el --- core functionality  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2010-2018  The Magit Project Contributors
+;;
+;; You should have received a copy of the AUTHORS.md file which
+;; lists all contributors.  If not, see http://magit.vc/authors.
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; Magit 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, or (at your option)
+;; any later version.
+;;
+;; Magit 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 Magit.  If not, see http://www.gnu.org/licenses.
+
+;;; Commentary:
+
+;; This library requires several other libraries, so that yet other
+;; libraries can just require this one, instead of having to require
+;; all the other ones.  In other words this separates the low-level
+;; stuff from the rest.  It also defines some Custom groups.
+
+;;; Code:
+
+(require 'magit-popup)
+(require 'magit-utils)
+(require 'magit-section)
+(require 'magit-git)
+(require 'magit-mode)
+(require 'magit-margin)
+(require 'magit-process)
+(require 'magit-autorevert)
+
+(defgroup magit nil
+  "Controlling Git from Emacs."
+  :link '(url-link "https://magit.vc")
+  :link '(info-link "(magit)FAQ")
+  :link '(info-link "(magit)")
+  :group 'tools)
+
+(defgroup magit-essentials nil
+  "Options that every Magit user should briefly think about.
+
+Each of these options falls into one or more of these categories:
+
+* Options that affect Magit's behavior in fundamental ways.
+* Options that affect safety.
+* Options that affect performance.
+* Options that are of a personal nature."
+  :link '(info-link "(magit)Essential Settings")
+  :group 'magit)
+
+(defgroup magit-miscellaneous nil
+  "Miscellanous Magit options."
+  :group 'magit)
+
+(defgroup magit-commands nil
+  "Options controlling behavior of certain commands."
+  :group 'magit)
+
+(defgroup magit-git-arguments nil
+  "Options controlling what arguments are passed to Git.
+
+Most of these options can be set using the respective popup,
+and it is recommended that you do that because then you can
+be certain that Magit supports the arguments that you select.
+
+An option `magit-NAME-argument' specifies the arguments that
+are enabled by default by the popup `magit-NAME-popup'."
+  :link '(info-link "(magit-popup)Customizing Existing Popups")
+  :link '(info-link "(magit-popup)Usage")
+  :group 'magit-commands)
+
+(defgroup magit-modes nil
+  "Modes used or provided by Magit."
+  :group 'magit)
+
+(defgroup magit-buffers nil
+  "Options concerning Magit buffers."
+  :link '(info-link "(magit)Modes and Buffers")
+  :group 'magit)
+
+(defgroup magit-refresh nil
+  "Options controlling how Magit buffers are refreshed."
+  :link '(info-link "(magit)Automatic Refreshing of Magit Buffers")
+  :group 'magit
+  :group 'magit-buffers)
+
+(defgroup magit-faces nil
+  "Faces used by Magit."
+  :group 'magit
+  :group 'faces)
+
+(defgroup magit-extensions nil
+  "Extensions to Magit."
+  :group 'magit)
+
+(custom-add-to-group 'magit-modes   'magit-popup       'custom-group)
+(custom-add-to-group 'magit-faces   'magit-popup-faces 'custom-group)
+(custom-add-to-group 'magit-modes   'git-commit        'custom-group)
+(custom-add-to-group 'magit-faces   'git-commit-faces  'custom-group)
+(custom-add-to-group 'magit-modes   'git-rebase        'custom-group)
+(custom-add-to-group 'magit-faces   'git-rebase-faces  'custom-group)
+(custom-add-to-group 'magit-process 'with-editor       'custom-group)
+
+(defgroup magit-related nil
+  "Options that are relevant to Magit but that are defined elsewhere."
+  :link '(custom-group-link vc)
+  :link '(custom-group-link smerge)
+  :link '(custom-group-link ediff)
+  :link '(custom-group-link auto-revert)
+  :group 'magit
+  :group 'magit-extensions
+  :group 'magit-essentials)
+
+(custom-add-to-group 'magit-related     'auto-revert-check-vc-info 'custom-variable)
+(custom-add-to-group 'magit-auto-revert 'auto-revert-check-vc-info 'custom-variable)
+
+(custom-add-to-group 'magit-related 'ediff-window-setup-function 'custom-variable)
+(custom-add-to-group 'magit-related 'smerge-refine-ignore-whitespace 'custom-variable)
+(custom-add-to-group 'magit-related 'vc-follow-symlinks 'custom-variable)
+
+(provide 'magit-core)
+;;; magit-core.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-core.elc b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-core.elc
new file mode 100644
index 0000000000..c68aff302d
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-core.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-diff.el b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-diff.el
new file mode 100644
index 0000000000..4d8d7bd77c
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-diff.el
@@ -0,0 +1,2747 @@
+;;; magit-diff.el --- inspect Git diffs  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2010-2018  The Magit Project Contributors
+;;
+;; You should have received a copy of the AUTHORS.md file which
+;; lists all contributors.  If not, see http://magit.vc/authors.
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; Magit 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, or (at your option)
+;; any later version.
+;;
+;; Magit 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 Magit.  If not, see http://www.gnu.org/licenses.
+
+;;; Commentary:
+
+;; This library implements support for looking at Git diffs and
+;; commits.
+
+;;; Code:
+
+(require 'git-commit)
+(require 'magit-core)
+
+;; For `magit-diff-popup'
+(declare-function magit-stash-show "magit-stash" (stash &optional args files))
+;; For `magit-diff-visit-file'
+(declare-function dired-jump "dired-x" (&optional other-window file-name))
+(declare-function magit-find-file-noselect "magit-files" (rev file))
+(declare-function magit-status-internal "magit-status" (directory))
+;; For `magit-diff-while-committing'
+(declare-function magit-commit-message-buffer "magit-commit" ())
+;; For `magit-insert-revision-gravatar'
+(defvar gravatar-size)
+;; For `magit-show-commit' and `magit-diff-show-or-scroll'
+(declare-function magit-current-blame-chunk "magit-blame" ())
+(eval-when-compile
+  (cl-pushnew 'orig-rev eieio--known-slot-names))
+(declare-function magit-blame-mode "magit-blame" (&optional arg))
+(defvar magit-blame-mode)
+(defvar git-rebase-line)
+;; For `magit-diff-unmerged'
+(declare-function magit-merge-in-progress-p "magit-merge" ())
+(declare-function magit--merge-range "magit-merge" (&optional head))
+
+(require 'diff-mode)
+(require 'smerge-mode)
+
+(defvar bookmark-make-record-function)
+
+;;; Options
+;;;; Diff Mode
+
+(defgroup magit-diff nil
+  "Inspect and manipulate Git diffs."
+  :link '(info-link "(magit)Diffing")
+  :group 'magit-modes)
+
+(defcustom magit-diff-mode-hook nil
+  "Hook run after entering Magit-Diff mode."
+  :group 'magit-diff
+  :type 'hook)
+
+(defcustom magit-diff-arguments '("--stat" "--no-ext-diff")
+  "The diff arguments used in buffers whose mode derives from `magit-diff-mode'."
+  :group 'magit-git-arguments
+  :group 'magit-diff
+  :type '(repeat (string :tag "Argument")))
+
+(defcustom magit-diff-sections-hook
+  '(magit-insert-diff
+    magit-insert-xref-buttons)
+  "Hook run to insert sections into a `magit-diff-mode' buffer."
+  :package-version '(magit . "2.3.0")
+  :group 'magit-diff
+  :type 'hook)
+
+(defcustom magit-diff-expansion-threshold 60
+  "After how many seconds not to expand anymore diffs.
+
+Except in status buffers, diffs are usually start out fully
+expanded.  Because that can take a long time, all diffs that
+haven't been fontified during a refresh before the threshold
+defined here are instead displayed with their bodies collapsed.
+
+Note that this can cause sections that were previously expanded
+to be collapsed.  So you should not pick a very low value here.
+
+The hook function `magit-diff-expansion-threshold' has to be a
+member of `magit-section-set-visibility-hook' for this option
+to have any effect."
+  :package-version '(magit . "2.9.0")
+  :group 'magit-diff
+  :type 'float)
+
+(defcustom magit-diff-highlight-hunk-body t
+  "Whether to highlight bodies of selected hunk sections.
+This only has an effect if `magit-diff-highlight' is a
+member of `magit-section-highlight-hook', which see."
+  :package-version '(magit . "2.1.0")
+  :group 'magit-diff
+  :type 'boolean)
+
+(defcustom magit-diff-highlight-hunk-region-functions
+  '(magit-diff-highlight-hunk-region-dim-outside
+    magit-diff-highlight-hunk-region-using-overlays)
+  "The functions used to highlight the hunk-internal region.
+
+`magit-diff-highlight-hunk-region-dim-outside' overlays the outside
+of the hunk internal selection with a face that causes the added and
+removed lines to have the same background color as context lines.
+This function should not be removed from the value of this option.
+
+`magit-diff-highlight-hunk-region-using-overlays' and
+`magit-diff-highlight-hunk-region-using-underline' emphasize the
+region by placing delimiting horizonal lines before and after it.
+The underline variant was implemented because Eli said that is
+how we should do it.  However the overlay variant actually works
+better.  Also see https://github.com/magit/magit/issues/2758.
+
+Instead of, or in addition to, using delimiting horizontal lines,
+to emphasize the boundaries, you may which to emphasize the text
+itself, using `magit-diff-highlight-hunk-region-using-face'.
+
+In terminal frames it's not possible to draw lines as the overlay
+and underline variants normally do, so there they fall back to
+calling the face function instead."
+  :package-version '(magit . "2.9.0")
+  :set-after '(magit-diff-show-lines-boundaries)
+  :group 'magit-diff
+  :type 'hook
+  :options '(magit-diff-highlight-hunk-region-dim-outside
+             magit-diff-highlight-hunk-region-using-underline
+             magit-diff-highlight-hunk-region-using-overlays
+             magit-diff-highlight-hunk-region-using-face))
+
+(defcustom magit-diff-unmarked-lines-keep-foreground t
+  "Whether `magit-diff-highlight-hunk-region-dim-outside' preserves foreground.
+When this is set to nil, then that function only adjusts the
+foreground color but added and removed lines outside the region
+keep their distinct foreground colors."
+  :package-version '(magit . "2.9.0")
+  :group 'magit-diff
+  :type 'boolean)
+
+(defcustom magit-diff-refine-hunk nil
+  "Whether to show word-granularity differences within diff hunks.
+
+nil    never show fine differences.
+t      show fine differences for the current diff hunk only.
+`all'  show fine differences for all displayed diff hunks."
+  :group 'magit-diff
+  :safe (lambda (val) (memq val '(nil t all)))
+  :type '(choice (const :tag "Never" nil)
+                 (const :tag "Current" t)
+                 (const :tag "All" all)))
+
+(put 'magit-diff-refine-hunk 'permanent-local t)
+
+(defcustom magit-diff-adjust-tab-width nil
+  "Whether to adjust the width of tabs in diffs.
+
+Determining the correct width can be expensive if it requires
+opening large and/or many files, so the widths are cached in
+the variable `magit-diff--tab-width-cache'.  Set that to nil
+to invalidate the cache.
+
+nil       Never ajust tab width.  Use `tab-width's value from
+          the Magit buffer itself instead.
+
+t         If the corresponding file-visiting buffer exits, then
+          use `tab-width's value from that buffer.  Doing this is
+          cheap, so this value is used even if a corresponding
+          cache entry exists.
+
+`always'  If there is no such buffer, then temporarily visit the
+          file to determine the value.
+
+NUMBER    Like `always', but don't visit files larger than NUMBER
+          bytes."
+  :package-version '(magit . "2.12.0")
+  :group 'magit-diff
+  :type '(choice (const :tag "Never" nil)
+                 (const :tag "If file-visiting buffer exists" t)
+                 (const :tag "... or file isn't larger than bytes" all)
+                 (const :tag "Always" always)))
+
+(defcustom magit-diff-paint-whitespace t
+  "Specify where to highlight whitespace errors.
+See `magit-diff-highlight-trailing',
+`magit-diff-highlight-indentation'.  The symbol t means in all
+diffs, `status' means only in the status buffer, and nil means
+nowhere."
+  :group 'magit-diff
+  :safe (lambda (val) (memq val '(t nil status)))
+  :type '(choice (const :tag "Always" t)
+                 (const :tag "Never" nil)
+                 (const :tag "In status buffer" status)))
+
+(defcustom magit-diff-highlight-trailing t
+  "Whether to highlight whitespace at the end of a line in diffs.
+Used only when `magit-diff-paint-whitespace' is non-nil."
+  :group 'magit-diff
+  :safe 'booleanp
+  :type 'boolean)
+
+(defcustom magit-diff-highlight-indentation nil
+  "Highlight the \"wrong\" indentation style.
+Used only when `magit-diff-paint-whitespace' is non-nil.
+
+The value is a list of cons cells.  The car is a regular
+expression, and the cdr is the value that applies to repositories
+whose directory matches the regular expression.  If more than one
+element matches, then the *last* element in the list applies.
+The default value should therefore come first in the list.
+
+If the value is `tabs', highlight indentation with tabs.  If the
+value is an integer, highlight indentation with at least that
+many spaces.  Otherwise, highlight neither."
+  :group 'magit-diff
+  :type `(repeat (cons (string :tag "Directory regexp")
+                       (choice (const :tag "Tabs" tabs)
+                               (integer :tag "Spaces" :value ,tab-width)
+                               (const :tag "Neither" nil)))))
+
+(defcustom magit-diff-hide-trailing-cr-characters
+  (and (memq system-type '(ms-dos windows-nt)) t)
+  "Whether to hide ^M characters at the end of a line in diffs."
+  :package-version '(magit . "2.6.0")
+  :group 'magit-diff
+  :type 'boolean)
+
+(defcustom magit-diff-visit-previous-blob t
+  "Whether `magit-diff-visit-file' may visit the previous blob.
+
+When this is t and point is on a removed line in a diff for a
+committed change, then `magit-diff-visit-file' visits the blob
+from the last revision which still had that line.
+
+Currently this is only supported for committed changes, for
+staged and unstaged changes `magit-diff-visit-file' always
+visits the file in the working tree."
+  :package-version '(magit . "2.9.0")
+  :group 'magit-diff
+  :type 'boolean)
+
+(defcustom magit-diff-highlight-keywords t
+  "Whether to highlight bracketed keywords in commit messages."
+  :package-version '(magit . "2.12.0")
+  :group 'magit-diff
+  :type 'boolean)
+
+;;;; File Diff
+
+(defcustom magit-diff-buffer-file-locked t
+  "Whether `magit-diff-buffer-file' uses a dedicated buffer."
+  :package-version '(magit . "2.7.0")
+  :group 'magit-commands
+  :group 'magit-diff
+  :type 'boolean)
+
+;;;; Revision Mode
+
+(defgroup magit-revision nil
+  "Inspect and manipulate Git commits."
+  :link '(info-link "(magit)Revision Buffer")
+  :group 'magit-modes)
+
+(defcustom magit-revision-mode-hook '(bug-reference-mode)
+  "Hook run after entering Magit-Revision mode."
+  :group 'magit-revision
+  :type 'hook
+  :options '(bug-reference-mode))
+
+(defcustom magit-revision-sections-hook
+  '(magit-insert-revision-tag
+    magit-insert-revision-headers
+    magit-insert-revision-message
+    magit-insert-revision-notes
+    magit-insert-revision-diff
+    magit-insert-xref-buttons)
+  "Hook run to insert sections into a `magit-revision-mode' buffer."
+  :package-version '(magit . "2.3.0")
+  :group 'magit-revision
+  :type 'hook)
+
+(defcustom magit-revision-headers-format "\
+Author:     %aN <%aE>
+AuthorDate: %ad
+Commit:     %cN <%cE>
+CommitDate: %cd
+"
+  "Format string used to insert headers in revision buffers.
+
+All headers in revision buffers are inserted by the section
+inserter `magit-insert-revision-headers'.  Some of the headers
+are created by calling `git show --format=FORMAT' where FORMAT
+is the format specified here.  Other headers are hard coded or
+subject to option `magit-revision-insert-related-refs'."
+  :package-version '(magit . "2.3.0")
+  :group 'magit-revision
+  :type 'string)
+
+(defcustom magit-revision-insert-related-refs t
+  "Whether to show related refs in revision buffers."
+  :package-version '(magit . "2.1.0")
+  :group 'magit-revision
+  :type 'boolean)
+
+(defcustom magit-revision-use-hash-sections 'quicker
+  "Whether to turn hashes inside the commit message into sections.
+
+If non-nil, then hashes inside the commit message are turned into
+`commit' sections.  There is a trade off to be made between
+performance and reliability:
+
+- `slow' calls git for every word to be absolutely sure.
+- `quick' skips words less than seven characters long.
+- `quicker' additionally skips words that don't contain a number.
+- `quickest' uses all words that are at least seven characters
+  long and which contain at least one number as well as at least
+  one letter.
+
+If nil, then no hashes are turned into sections, but you can
+still visit the commit at point using \"RET\"."
+  :package-version '(magit . "2.12.0")
+  :group 'magit-revision
+  :type '(choice (const :tag "Use sections, quickest" quickest)
+                 (const :tag "Use sections, quicker" quicker)
+                 (const :tag "Use sections, quick" quick)
+                 (const :tag "Use sections, slow" slow)
+                 (const :tag "Don't use sections" nil)))
+
+(defcustom magit-revision-show-gravatars nil
+  "Whether to show gravatar images in revision buffers.
+
+If non-nil, then the value has to be a cons-cell which specifies
+where the gravatar images for the author and/or the committer are
+inserted inside the text that was previously inserted according
+to `magit-revision-header-format'.
+
+Both cells are regular expressions.  The car specifies where to
+insert the author gravatar image.  The top half of the image is
+inserted right after the matched text, the bottom half on the
+next line at the same offset.  The cdr specifies where to insert
+the committer image, accordingly.  Either the car or the cdr may
+be nil."
+  :package-version '(magit . "2.3.0")
+  :group 'magit-revision
+  :type '(choice (const :tag "Don't show gravatars" nil)
+                 (cons  :tag "Show gravatars"
+                        (regexp :tag "Author regexp"    "^Author:     ")
+                        (regexp :tag "Committer regexp" "^Commit:     "))))
+
+(defcustom magit-revision-use-gravatar-kludge nil
+  "Whether to work around a bug which affects display of gravatars.
+
+Gravatar images are spliced into two halves which are then
+displayed on separate lines.  On OS X the splicing has a bug in
+some Emacs builds, which causes the top and bottom halves to be
+interchanged.  Enabling this option works around this issue by
+interchanging the halves once more, which cancels out the effect
+of the bug.
+
+See https://github.com/magit/magit/issues/2265
+and https://debbugs.gnu.org/cgi/bugreport.cgi?bug=7847.
+
+Starting with Emacs 26.1 this kludge should not be required for
+any build."
+  :package-version '(magit . "2.3.0")
+  :group 'magit-revision
+  :type 'boolean)
+
+;;;; Diff Sections
+
+(defcustom magit-diff-section-arguments '("--no-ext-diff")
+  "The diff arguments used in buffers that show other things besides diffs."
+  :group 'magit-git-arguments
+  :group 'magit-diff
+  :group 'magit-status
+  :type '(repeat (string :tag "Argument")))
+
+(put 'magit-diff-section-arguments 'permanent-local t)
+
+;;; Faces
+
+(defface magit-diff-file-heading
+  '((t :weight bold))
+  "Face for diff file headings."
+  :group 'magit-faces)
+
+(defface magit-diff-file-heading-highlight
+  '((t :inherit (magit-section-highlight)))
+  "Face for current diff file headings."
+  :group 'magit-faces)
+
+(defface magit-diff-file-heading-selection
+  '((((class color) (background light))
+     :inherit magit-diff-file-heading-highlight
+     :foreground "salmon4")
+    (((class color) (background dark))
+     :inherit magit-diff-file-heading-highlight
+     :foreground "LightSalmon3"))
+  "Face for selected diff file headings."
+  :group 'magit-faces)
+
+(defface magit-diff-hunk-heading
+  '((((class color) (background light))
+     :background "grey80"
+     :foreground "grey30")
+    (((class color) (background dark))
+     :background "grey25"
+     :foreground "grey70"))
+  "Face for diff hunk headings."
+  :group 'magit-faces)
+
+(defface magit-diff-hunk-heading-highlight
+  '((((class color) (background light))
+     :background "grey75"
+     :foreground "grey30")
+    (((class color) (background dark))
+     :background "grey35"
+     :foreground "grey70"))
+  "Face for current diff hunk headings."
+  :group 'magit-faces)
+
+(defface magit-diff-hunk-heading-selection
+  '((((class color) (background light))
+     :inherit magit-diff-hunk-heading-highlight
+     :foreground "salmon4")
+    (((class color) (background dark))
+     :inherit magit-diff-hunk-heading-highlight
+     :foreground "LightSalmon3"))
+  "Face for selected diff hunk headings."
+  :group 'magit-faces)
+
+(defface magit-diff-hunk-region
+  '((t :inherit bold))
+  "Face used by `magit-diff-highlight-hunk-region-using-face'.
+
+This face is overlayed over text that uses other hunk faces,
+and those normally set the foreground and background colors.
+The `:foreground' and especially the `:background' properties
+should be avoided here.  Setting the latter would cause the
+lose of information.  Good properties to set here are `:weight'
+and `:slant'."
+  :group 'magit-faces)
+
+(defface magit-diff-lines-heading
+  '((((class color) (background light))
+     :inherit magit-diff-hunk-heading-highlight
+     :background "LightSalmon3")
+    (((class color) (background dark))
+     :inherit magit-diff-hunk-heading-highlight
+     :foreground "grey80"
+     :background "salmon4"))
+  "Face for diff hunk heading when lines are marked."
+  :group 'magit-faces)
+
+(defface magit-diff-lines-boundary
+  '((t :inherit magit-diff-lines-heading))
+  "Face for boundary of marked lines in diff hunk."
+  :group 'magit-faces)
+
+(defface magit-diff-conflict-heading
+  '((t :inherit magit-diff-hunk-heading))
+  "Face for conflict markers."
+  :group 'magit-faces)
+
+(defface magit-diff-added
+  '((((class color) (background light))
+     :background "#ddffdd"
+     :foreground "#22aa22")
+    (((class color) (background dark))
+     :background "#335533"
+     :foreground "#ddffdd"))
+  "Face for lines in a diff that have been added."
+  :group 'magit-faces)
+
+(defface magit-diff-removed
+ '((((class color) (background light))
+    :background "#ffdddd"
+    :foreground "#aa2222")
+   (((class color) (background dark))
+    :background "#553333"
+    :foreground "#ffdddd"))
+  "Face for lines in a diff that have been removed."
+  :group 'magit-faces)
+
+(defface magit-diff-our
+  '((t :inherit magit-diff-removed))
+  "Face for lines in a diff for our side in a conflict."
+  :group 'magit-faces)
+
+(defface magit-diff-base
+  '((((class color) (background light))
+     :background "#ffffcc"
+     :foreground "#aaaa11")
+    (((class color) (background dark))
+     :background "#555522"
+     :foreground "#ffffcc"))
+  "Face for lines in a diff for the base side in a conflict."
+  :group 'magit-faces)
+
+(defface magit-diff-their
+  '((t :inherit magit-diff-added))
+  "Face for lines in a diff for their side in a conflict."
+  :group 'magit-faces)
+
+(defface magit-diff-context
+  '((((class color) (background light)) :foreground "grey50")
+    (((class color) (background  dark)) :foreground "grey70"))
+  "Face for lines in a diff that are unchanged."
+  :group 'magit-faces)
+
+(defface magit-diff-added-highlight
+  '((((class color) (background light))
+     :background "#cceecc"
+     :foreground "#22aa22")
+    (((class color) (background dark))
+     :background "#336633"
+     :foreground "#cceecc"))
+  "Face for lines in a diff that have been added."
+  :group 'magit-faces)
+
+(defface magit-diff-removed-highlight
+  '((((class color) (background light))
+     :background "#eecccc"
+     :foreground "#aa2222")
+    (((class color) (background dark))
+     :background "#663333"
+     :foreground "#eecccc"))
+  "Face for lines in a diff that have been removed."
+  :group 'magit-faces)
+
+(defface magit-diff-our-highlight
+  '((t :inherit magit-diff-removed-highlight))
+  "Face for lines in a diff for our side in a conflict."
+  :group 'magit-faces)
+
+(defface magit-diff-base-highlight
+  '((((class color) (background light))
+     :background "#eeeebb"
+     :foreground "#aaaa11")
+    (((class color) (background dark))
+     :background "#666622"
+     :foreground "#eeeebb"))
+  "Face for lines in a diff for the base side in a conflict."
+  :group 'magit-faces)
+
+(defface magit-diff-their-highlight
+  '((t :inherit magit-diff-added-highlight))
+  "Face for lines in a diff for their side in a conflict."
+  :group 'magit-faces)
+
+(defface magit-diff-context-highlight
+  '((((class color) (background light))
+     :background "grey95"
+     :foreground "grey50")
+    (((class color) (background dark))
+     :background "grey20"
+     :foreground "grey70"))
+  "Face for lines in a diff that have been removed."
+  :group 'magit-faces)
+
+(defface magit-diff-whitespace-warning
+  '((t :inherit trailing-whitespace))
+  "Face for highlighting whitespace errors added lines."
+  :group 'magit-faces)
+
+(defface magit-diffstat-added
+  '((((class color) (background light)) :foreground "#22aa22")
+    (((class color) (background  dark)) :foreground "#448844"))
+  "Face for plus sign in diffstat."
+  :group 'magit-faces)
+
+(defface magit-diffstat-removed
+  '((((class color) (background light)) :foreground "#aa2222")
+    (((class color) (background  dark)) :foreground "#aa4444"))
+  "Face for minus sign in diffstat."
+  :group 'magit-faces)
+
+;;; Commands
+;;;; Diff popups
+
+(defconst magit-diff-popup-common
+  '(:variable magit-diff-arguments
+    :man-page "git-diff"
+    :options  ((?f "Limit to files" "-- " magit-read-files)
+               (?u "Context lines"  "-U")
+               (?m "Detect renames" "-M")
+               (?c "Detect copies"  "-C")
+               (?a "Diff algorithm" "--diff-algorithm="
+                   magit-diff-select-algorithm))))
+
+(defvar magit-diff-popup
+  `(,@magit-diff-popup-common
+    :switches ((?f "Show surrounding functions"     "--function-context")
+               (?b "Ignore whitespace changes"      "--ignore-space-change")
+               (?w "Ignore all whitespace"          "--ignore-all-space")
+               (?x "Disallow external diff drivers" "--no-ext-diff")
+               (?s "Show stats"                     "--stat"))
+    :actions  ((?d "Dwim"          magit-diff-dwim)
+               (?u "Diff unstaged" magit-diff-unstaged)
+               (?c "Show commit"   magit-show-commit)
+               (?r "Diff range"    magit-diff)
+               (?s "Diff staged"   magit-diff-staged)
+               (?t "Show stash"    magit-stash-show)
+               (?p "Diff paths"    magit-diff-paths)
+               (?w "Diff worktree" magit-diff-working-tree))
+    :default-action magit-diff-dwim
+    :max-action-columns 3))
+
+(defvar magit-diff-refresh-popup
+  `(,@magit-diff-popup-common
+    :switches ((?f "Show surrounding functions"     "--function-context")
+               (?b "Ignore whitespace changes"      "--ignore-space-change")
+               (?w "Ignore all whitespace"          "--ignore-all-space")
+               (?x "Disallow external diff drivers" "--no-ext-diff"))
+    :actions  ((?g "Refresh"                magit-diff-refresh)
+               (?t "Toggle hunk refinement" magit-diff-toggle-refine-hunk)
+               (?s "Set defaults"           magit-diff-set-default-arguments)
+               (?F "Toggle file filter"     magit-diff-toggle-file-filter)
+               (?w "Save defaults"          magit-diff-save-default-arguments))
+    :max-action-columns 2))
+
+(defvar magit-diff-mode-refresh-popup
+  `(,@magit-diff-popup-common
+    :switches ((?f "Show surrounding functions"     "--function-context")
+               (?b "Ignore whitespace changes"      "--ignore-space-change")
+               (?w "Ignore all whitespace"          "--ignore-all-space")
+               (?x "Disallow external diff drivers" "--no-ext-diff")
+               (?s "Show stats"                     "--stat"))
+    :actions  ((?g "Refresh"                magit-diff-refresh)
+               (?t "Toggle hunk refinement" magit-diff-toggle-refine-hunk)
+               (?s "Set defaults"           magit-diff-set-default-arguments)
+               (?r "Switch range type"      magit-diff-switch-range-type)
+               (?w "Save defaults"          magit-diff-save-default-arguments)
+               (?f "Flip revisions"         magit-diff-flip-revs) nil
+               (?F "Toggle file filter"     magit-diff-toggle-file-filter))
+    :max-action-columns 2))
+
+(defvar magit-revision-mode-refresh-popup
+  `(,@magit-diff-popup-common
+    :switches ((?f "Show surrounding functions"     "--function-context")
+               (?b "Ignore whitespace changes"      "--ignore-space-change")
+               (?w "Ignore all whitespace"          "--ignore-all-space")
+               (?x "Disallow external diff drivers" "--no-ext-diff")
+               (?s "Show stats"                     "--stat"))
+    :actions  ((?g "Refresh"                magit-diff-refresh)
+               (?t "Toggle hunk refinement" magit-diff-toggle-refine-hunk)
+               (?s "Set defaults"           magit-diff-set-default-arguments)
+               (?F "Toggle file filter"     magit-diff-toggle-file-filter)
+               (?w "Save defaults"          magit-diff-save-default-arguments))
+    :max-action-columns 2))
+
+(magit-define-popup-keys-deferred 'magit-diff-popup)
+(magit-define-popup-keys-deferred 'magit-diff-refresh-popup)
+(magit-define-popup-keys-deferred 'magit-diff-mode-refresh-popup)
+(magit-define-popup-keys-deferred 'magit-revision-mode-refresh-popup)
+
+(defvar magit-diff-section-file-args nil)
+(put 'magit-diff-section-file-args 'permanent-local t)
+(put 'magit-diff-section-file-args 'safe-local-variable
+     (lambda (val)
+       (and (listp val)
+            (-all-p #'stringp val))))
+
+(defun magit-diff-get-buffer-args ()
+  (cond ((and magit-use-sticky-arguments
+              (derived-mode-p 'magit-diff-mode))
+         (list (nth 2 magit-refresh-args)
+               (nth 3 magit-refresh-args)))
+        ((and (eq magit-use-sticky-arguments t)
+              (--when-let (magit-mode-get-buffer 'magit-diff-mode)
+                (with-current-buffer it
+                  (list (nth 2 magit-refresh-args)
+                        (nth 3 magit-refresh-args))))))
+        (t
+         (list (default-value 'magit-diff-arguments) nil))))
+
+(defun magit-diff-arguments (&optional refresh)
+  (cond ((memq magit-current-popup '(magit-diff-popup magit-diff-refresh-popup))
+         (magit-popup-export-file-args magit-current-popup-args))
+        ((and refresh (not (derived-mode-p 'magit-diff-mode)))
+         (list magit-diff-section-arguments
+               magit-diff-section-file-args))
+        (t
+         (magit-diff-get-buffer-args))))
+
+;;;###autoload
+(defun magit-diff-popup (arg)
+  "Popup console for diff commands."
+  (interactive "P")
+  (let ((magit-diff-arguments
+         ;; We cannot possibly know what suffix command the user is
+         ;; about to invoke, so we also don't know from which buffer
+         ;; we should get the current values.  However it is much
+         ;; more likely that we will end up updating the diff buffer,
+         ;; and we therefore use the value from that buffer.
+         (apply #'magit-popup-import-file-args (magit-diff-get-buffer-args))))
+    (magit-invoke-popup 'magit-diff-popup nil arg)))
+
+;;;###autoload
+(defun magit-diff-buffer-file-popup ()
+  "Popup console for diff commands.
+
+This is a variant of `magit-diff-popup' which shows the same popup
+but which limits the diff to the file being visited in the current
+buffer."
+  (interactive)
+  (if-let ((file (magit-file-relative-name)))
+      (let ((magit-diff-arguments
+             (magit-popup-import-file-args
+              (if-let ((buffer (magit-mode-get-buffer 'magit-diff-mode)))
+                  (with-current-buffer buffer
+                    (nth 3 magit-refresh-args))
+                (default-value 'magit-diff-arguments))
+              (list file))))
+        (magit-invoke-popup 'magit-diff-popup nil nil))
+    (user-error "Buffer isn't visiting a file")))
+
+(defun magit-diff-refresh-popup (arg)
+  "Popup console for changing diff arguments in the current buffer."
+  (interactive "P")
+  (let ((magit-diff-refresh-popup
+         (pcase major-mode
+           (`magit-revision-mode magit-revision-mode-refresh-popup)
+           (`magit-diff-mode     magit-diff-mode-refresh-popup)
+           (_                    magit-diff-refresh-popup)))
+        (magit-diff-arguments
+         (if (derived-mode-p 'magit-diff-mode)
+             (magit-popup-import-file-args (nth 2 magit-refresh-args)
+                                           (nth 3 magit-refresh-args))
+           (magit-popup-import-file-args magit-diff-section-arguments
+                                         magit-diff-section-file-args))))
+    (magit-invoke-popup 'magit-diff-refresh-popup nil arg)))
+
+(defun magit-diff-select-algorithm (&rest _ignore)
+  (magit-read-char-case nil t
+    (?d "[d]efault"   "default")
+    (?m "[m]inimal"   "minimal")
+    (?p "[p]atience"  "patience")
+    (?h "[h]istogram" "histogram")))
+
+;;;; Diff commands
+
+;;;###autoload
+(defun magit-diff-dwim (&optional args files)
+  "Show changes for the thing at point."
+  (interactive (magit-diff-arguments))
+  (pcase (magit-diff--dwim)
+    (`unmerged (magit-diff-unmerged args files))
+    (`unstaged (magit-diff-unstaged args files))
+    (`staged
+     (let ((file (magit-file-at-point)))
+       (if (and file (equal (cddr (car (magit-file-status file))) '(?D ?U)))
+           ;; File was deleted by us and modified by them.  Show the latter.
+           (magit-diff-unmerged args (list file))
+         (magit-diff-staged nil args files))))
+    (`(commit . ,value)
+     (magit-diff (format "%s^..%s" value value) args files))
+    (`(stash  . ,value) (magit-stash-show value args))
+    ((and range (pred stringp))
+     (magit-diff range args files))
+    (_
+     (call-interactively #'magit-diff))))
+
+(defun magit-diff--dwim ()
+  "Return information for performing DWIM diff.
+
+The information can be in three forms:
+1. TYPE
+   A symbol describing a type of diff where no additional information
+   is needed to generate the diff.  Currently, this includes `staged',
+   `unstaged' and `unmerged'.
+2. (TYPE . VALUE)
+   Like #1 but the diff requires additional information, which is
+   given by VALUE.  Currently, this includes `commit' and `stash',
+   where VALUE is the given commit or stash, respectively.
+3. RANGE
+   A string indicating a diff range.
+
+If no DWIM context is found, nil is returned."
+  (cond
+   ((--when-let (magit-region-values '(commit branch) t)
+      (deactivate-mark)
+      (concat (car (last it)) ".." (car it))))
+   (magit-buffer-refname
+    (cons 'commit magit-buffer-refname))
+   ((derived-mode-p 'magit-stash-mode)
+    (cons 'commit
+          (magit-section-case
+            (commit (oref it value))
+            (file (-> it
+                      (oref parent)
+                      (oref value)))
+            (hunk (-> it
+                      (oref parent)
+                      (oref parent)
+                      (oref value))))))
+   ((derived-mode-p 'magit-revision-mode)
+    (cons 'commit (car magit-refresh-args)))
+   ((derived-mode-p 'magit-diff-mode)
+    (nth 0 magit-refresh-args))
+   (t
+    (magit-section-case
+      ([* unstaged] 'unstaged)
+      ([* staged] 'staged)
+      (unmerged 'unmerged)
+      (unpushed (oref it value))
+      (unpulled (oref it value))
+      (branch (let ((current (magit-get-current-branch))
+                    (atpoint (oref it value)))
+                (if (equal atpoint current)
+                    (--if-let (magit-get-upstream-branch)
+                        (format "%s...%s" it current)
+                      (if (magit-anything-modified-p)
+                          current
+                        (cons 'commit current)))
+                  (format "%s...%s"
+                          (or current "HEAD")
+                          atpoint))))
+      (commit (cons 'commit (oref it value)))
+      (stash (cons 'stash (oref it value)))))))
+
+(defun magit-diff-read-range-or-commit (prompt &optional secondary-default mbase)
+  "Read range or revision with special diff range treatment.
+If MBASE is non-nil, prompt for which rev to place at the end of
+a \"revA...revB\" range.  Otherwise, always construct
+\"revA..revB\" range."
+  (--if-let (magit-region-values '(commit branch) t)
+      (let ((revA (car (last it)))
+            (revB (car it)))
+        (deactivate-mark)
+        (if mbase
+            (let ((base (magit-git-string "merge-base" revA revB)))
+              (cond
+               ((string= (magit-rev-parse revA) base)
+                (format "%s..%s" revA revB))
+               ((string= (magit-rev-parse revB) base)
+                (format "%s..%s" revB revA))
+               (t
+                (let ((main (magit-completing-read "View changes along"
+                                                   (list revA revB)
+                                                   nil t nil nil revB)))
+                  (format "%s...%s"
+                          (if (string= main revB) revA revB) main)))))
+          (format "%s..%s" revA revB)))
+    (magit-read-range prompt
+                      (or (pcase (magit-diff--dwim)
+                            (`(commit . ,value)
+                             (format "%s^..%s" value value))
+                            ((and range (pred stringp))
+                             range))
+                          secondary-default
+                          (magit-get-current-branch)))))
+
+(defun magit-diff-setup (rev-or-range const args files)
+  (require 'magit)
+  (magit-mode-setup #'magit-diff-mode rev-or-range const args files))
+
+;;;###autoload
+(defun magit-diff (rev-or-range &optional args files)
+  "Show differences between two commits.
+
+REV-OR-RANGE should be a range or a single revision.  If it is a
+revision, then show changes in the working tree relative to that
+revision.  If it is a range, but one side is omitted, then show
+changes relative to `HEAD'.
+
+If the region is active, use the revisions on the first and last
+line of the region as the two sides of the range.  With a prefix
+argument, instead of diffing the revisions, choose a revision to
+view changes along, starting at the common ancestor of both
+revisions (i.e., use a \"...\" range)."
+  (interactive (cons (magit-diff-read-range-or-commit "Diff for range"
+                                                      nil current-prefix-arg)
+                     (magit-diff-arguments)))
+  (magit-diff-setup rev-or-range nil args files))
+
+;;;###autoload
+(defun magit-diff-working-tree (&optional rev args files)
+  "Show changes between the current working tree and the `HEAD' commit.
+With a prefix argument show changes between the working tree and
+a commit read from the minibuffer."
+  (interactive
+   (cons (and current-prefix-arg
+              (magit-read-branch-or-commit "Diff working tree and commit"))
+         (magit-diff-arguments)))
+  (magit-diff-setup (or rev "HEAD") nil args files))
+
+;;;###autoload
+(defun magit-diff-staged (&optional rev args files)
+  "Show changes between the index and the `HEAD' commit.
+With a prefix argument show changes between the index and
+a commit read from the minibuffer."
+  (interactive
+   (cons (and current-prefix-arg
+              (magit-read-branch-or-commit "Diff index and commit"))
+         (magit-diff-arguments)))
+  (magit-diff-setup rev (list "--cached") args files))
+
+;;;###autoload
+(defun magit-diff-unstaged (&optional args files)
+  "Show changes between the working tree and the index."
+  (interactive (magit-diff-arguments))
+  (magit-diff-setup nil nil args files))
+
+;;;###autoload
+(defun magit-diff-unmerged (&optional args files)
+  "Show changes that are being merged."
+  (interactive (magit-diff-arguments))
+  (unless (magit-merge-in-progress-p)
+    (user-error "No merge is in progress"))
+  (magit-diff-setup (magit--merge-range) nil args files))
+
+;;;###autoload
+(defun magit-diff-while-committing (&optional args)
+  "While committing, show the changes that are about to be committed.
+While amending, invoking the command again toggles between
+showing just the new changes or all the changes that will
+be committed."
+  (interactive (list (car (magit-diff-arguments))))
+  (unless (magit-commit-message-buffer)
+    (user-error "No commit in progress"))
+  (let ((magit-display-buffer-noselect t)
+        (diff-buf (magit-mode-get-buffer 'magit-diff-mode)))
+    (if (and diff-buf
+             (get-buffer-window diff-buf))
+        (with-current-buffer diff-buf
+          (pcase-let ((`(,rev ,arg . ,_) magit-refresh-args))
+            (cond ((and (equal rev "HEAD^")
+                        (equal arg '("--cached")))
+                   (magit-diff-staged nil args))
+                  ((and (equal rev nil)
+                        (equal arg '("--cached")))
+                   (magit-diff-while-amending args))
+                  ((magit-anything-staged-p)
+                   (magit-diff-staged nil args))
+                  (t
+                   (magit-diff-while-amending args)))))
+      (if (magit-anything-staged-p)
+          (magit-diff-staged nil args)
+        (magit-diff-while-amending args)))))
+
+(define-key git-commit-mode-map
+  (kbd "C-c C-d") 'magit-diff-while-committing)
+
+(defun magit-diff-while-amending (&optional args)
+  (magit-diff-setup "HEAD^" (list "--cached") args nil))
+
+;;;###autoload
+(defun magit-diff-buffer-file ()
+  "Show diff for the blob or file visited in the current buffer."
+  (interactive)
+  (require 'magit)
+  (if-let ((file (magit-file-relative-name)))
+      (magit-mode-setup-internal #'magit-diff-mode
+                                 (list (or magit-buffer-refname
+                                           (magit-get-current-branch)
+                                           "HEAD")
+                                       nil
+                                       (cadr (magit-diff-arguments))
+                                       (list file))
+                                 magit-diff-buffer-file-locked)
+    (user-error "Buffer isn't visiting a file")))
+
+;;;###autoload
+(defun magit-diff-paths (a b)
+  "Show changes between any two files on disk."
+  (interactive (list (read-file-name "First file: " nil nil t)
+                     (read-file-name "Second file: " nil nil t)))
+  (magit-diff-setup nil (list "--no-index")
+                    nil (list (magit-convert-filename-for-git
+                               (expand-file-name a))
+                              (magit-convert-filename-for-git
+                               (expand-file-name b)))))
+
+(defvar-local magit-buffer-revision-hash nil)
+
+(defun magit-show-commit--arguments ()
+  (pcase-let ((`(,args ,diff-files) (magit-diff-arguments)))
+    (list args (if (derived-mode-p 'magit-log-mode)
+                   (and (not (member "--follow" (nth 1 magit-refresh-args)))
+                        (nth 2 magit-refresh-args))
+                 diff-files))))
+
+;;;###autoload
+(defun magit-show-commit (rev &optional args files module)
+  "Visit the revision at point in another buffer.
+If there is no revision at point or with a prefix argument prompt
+for a revision."
+  (interactive
+   (let* ((mcommit (magit-section-when module-commit))
+          (atpoint (or (and (bound-and-true-p magit-blame-mode)
+                            (oref (magit-current-blame-chunk) orig-rev))
+                       mcommit
+                       (magit-branch-or-commit-at-point))))
+     (nconc (cons (or (and (not current-prefix-arg) atpoint)
+                      (magit-read-branch-or-commit "Show commit" atpoint))
+                  (magit-show-commit--arguments))
+            (and mcommit (list (magit-section-parent-value
+                                (magit-current-section)))))))
+  (require 'magit)
+  (magit-with-toplevel
+    (when module
+      (setq default-directory
+            (expand-file-name (file-name-as-directory module))))
+    (unless (magit-rev-verify-commit rev)
+      (user-error "%s is not a commit" rev))
+    (magit-mode-setup #'magit-revision-mode rev nil args files)))
+
+;;;; Setting commands
+
+(defun magit-diff-refresh (args files)
+  "Set the local diff arguments for the current buffer."
+  (interactive (magit-diff-arguments t))
+  (cond ((derived-mode-p 'magit-diff-mode)
+         (setcdr (cdr magit-refresh-args) (list args files)))
+        (t
+         (setq-local magit-diff-section-arguments args)
+         (setq-local magit-diff-section-file-args files)))
+  (magit-refresh))
+
+(defun magit-diff-set-default-arguments (args files)
+  "Set the global diff arguments for the current buffer."
+  (interactive (magit-diff-arguments t))
+  (cond ((derived-mode-p 'magit-diff-mode)
+         (customize-set-variable 'magit-diff-arguments args)
+         (setcdr (cdr magit-refresh-args) (list args files)))
+        (t
+         (customize-set-variable 'magit-diff-section-arguments args)
+         (kill-local-variable 'magit-diff-section-arguments)
+         (kill-local-variable 'magit-diff-section-file-args)))
+  (magit-refresh))
+
+(defun magit-diff-save-default-arguments (args files)
+  "Set and save the global diff arguments for the current buffer."
+  (interactive (magit-diff-arguments t))
+  (cond ((derived-mode-p 'magit-diff-mode)
+         (customize-save-variable 'magit-diff-arguments args)
+         (setcdr (cdr magit-refresh-args) (list args files)))
+        (t
+         (customize-save-variable 'magit-diff-section-arguments args)
+         (kill-local-variable 'magit-diff-section-arguments)
+         (kill-local-variable 'magit-diff-section-file-args)))
+  (magit-refresh))
+
+(defun magit-diff-switch-range-type ()
+  "Convert diff range type.
+Change \"revA..revB\" to \"revB...revA\", or vice versa."
+  (interactive)
+  (let ((range (car magit-refresh-args)))
+    (if (and range
+             (derived-mode-p 'magit-diff-mode)
+             (string-match magit-range-re range))
+        (progn
+          (setcar magit-refresh-args
+                  (concat (match-string 1 range)
+                          (if (string= (match-string 2 range) "..")
+                              "..."
+                            "..")
+                          (match-string 3 range)))
+          (magit-refresh))
+      (user-error "No range to change"))))
+
+(defun magit-diff-flip-revs ()
+  "Swap revisions in diff range.
+Change \"revA..revB\" to \"revB..revA\"."
+  (interactive)
+  (let ((range (car magit-refresh-args)))
+    (if (and range
+             (derived-mode-p 'magit-diff-mode)
+             (string-match magit-range-re range))
+        (progn
+          (setcar magit-refresh-args
+                  (concat (match-string 3 range)
+                          (match-string 2 range)
+                          (match-string 1 range)))
+          (magit-refresh))
+      (user-error "No range to swap"))))
+
+(defvar-local magit-diff--last-file-args nil)
+(defun magit-diff--toggle-file-args (files)
+  (cond (files
+         (setq magit-diff--last-file-args files)
+               nil)
+        (magit-diff--last-file-args)
+        (t
+         (user-error "No diff file filter to toggle"))))
+
+(defun magit-diff-toggle-file-filter ()
+  "Toggle the file restriction of the current buffer's diffs.
+If the current buffer's mode is derived from `magit-log-mode',
+toggle the file restriction in the repository's revision buffer
+instead."
+  (interactive)
+  (--if-let (and (derived-mode-p 'magit-log-mode)
+                 (magit-mode-get-buffer 'magit-revision-mode))
+      (with-current-buffer it
+        (setf (nth 3 magit-refresh-args)
+              (magit-diff--toggle-file-args (nth 3 magit-refresh-args)))
+        (magit-refresh))
+    (if (derived-mode-p 'magit-diff-mode)
+        (setf (nth 3 magit-refresh-args)
+              (magit-diff--toggle-file-args (nth 3 magit-refresh-args)))
+      (setq-local magit-diff-section-file-args
+                  (magit-diff--toggle-file-args magit-diff-section-file-args)))
+    (magit-refresh)))
+
+(defun magit-diff-less-context (&optional count)
+  "Decrease the context for diff hunks by COUNT lines."
+  (interactive "p")
+  (magit-diff-set-context `(lambda (cur) (max 0 (- (or cur 0) ,count)))))
+
+(defun magit-diff-more-context (&optional count)
+  "Increase the context for diff hunks by COUNT lines."
+  (interactive "p")
+  (magit-diff-set-context `(lambda (cur) (+ (or cur 0) ,count))))
+
+(defun magit-diff-default-context ()
+  "Reset context for diff hunks to the default height."
+  (interactive)
+  (magit-diff-set-context #'ignore))
+
+(defun magit-diff-set-context (fn)
+  (let* ((def (--if-let (magit-get "diff.context") (string-to-number it) 3))
+         (val (car (magit-diff-arguments t)))
+         (arg (--first (string-match "^-U\\([0-9]+\\)?$" it) val))
+         (num (--if-let (and arg (match-string 1 arg)) (string-to-number it) def))
+         (val (delete arg val))
+         (num (funcall fn num))
+         (arg (and num (not (= num def)) (format "-U%i" num)))
+         (val (if arg (cons arg val) val)))
+    (if (derived-mode-p 'magit-diff-mode)
+        (setcar (cddr magit-refresh-args) val)
+      (setq magit-diff-section-arguments val)))
+  (magit-refresh))
+
+(defun magit-diff-context-p ()
+  (--if-let (--first (string-match "^-U\\([0-9]+\\)$" it)
+                     (car (magit-diff-arguments t)))
+      (not (equal "-U0" it))
+    t))
+
+(defun magit-diff-toggle-refine-hunk (&optional style)
+  "Turn diff-hunk refining on or off.
+
+If hunk refining is currently on, then hunk refining is turned off.
+If hunk refining is off, then hunk refining is turned on, in
+`selected' mode (only the currently selected hunk is refined).
+
+With a prefix argument, the \"third choice\" is used instead:
+If hunk refining is currently on, then refining is kept on, but
+the refining mode (`selected' or `all') is switched.
+If hunk refining is off, then hunk refining is turned on, in
+`all' mode (all hunks refined).
+
+Customize variable `magit-diff-refine-hunk' to change the default mode."
+  (interactive "P")
+  (setq-local magit-diff-refine-hunk
+              (if style
+                  (if (eq magit-diff-refine-hunk 'all) t 'all)
+                (not magit-diff-refine-hunk)))
+  (magit-diff-update-hunk-refinement))
+
+;;;; Visit commands
+
+(defun magit-diff-visit-file
+    (file &optional other-window force-worktree display-fn)
+  "From a diff, visit the corresponding file at the appropriate position.
+
+If the diff shows changes in the worktree, the index, or `HEAD',
+then visit the actual file.  Otherwise, when the diff is about an
+older commit or a range, then visit the appropriate blob.
+
+If point is on a removed line, then visit the blob for the first
+parent of the commit which removed that line, i.e. the last
+commit where that line still existed.  Otherwise visit the blob
+for the commit whose changes are being shown.
+
+Interactively, when the file or blob to be displayed is already
+being displayed in another window of the same frame, then just
+select that window and adjust point.  Otherwise, or with a prefix
+argument, display the buffer in another window.  The meaning of
+the prefix argument can be inverted or further modified using the
+option `magit-display-file-buffer-function'.
+
+Non-interactively the optional OTHER-WINDOW argument is taken
+literally.  DISPLAY-FN can be used to specify the display
+function explicitly, in which case OTHER-WINDOW is ignored.
+
+The optional FORCE-WORKTREE means to force visiting the worktree
+version of the file.  To do this interactively use the command
+`magit-diff-visit-file-worktree' instead."
+  (interactive (list (--if-let (magit-file-at-point)
+                         (expand-file-name it)
+                       (user-error "No file at point"))
+                     current-prefix-arg))
+  (if (magit-file-accessible-directory-p file)
+      (magit-diff-visit-directory file other-window)
+    (let* ((hunk (magit-diff-visit--hunk))
+           (last (and magit-diff-visit-previous-blob
+                      (not force-worktree)
+                      (magit-section-match 'hunk)
+                      (save-excursion
+                        (goto-char (line-beginning-position))
+                        (looking-at "-"))))
+           (line (and hunk (magit-diff-hunk-line   hunk)))
+           (col  (and hunk (magit-diff-hunk-column hunk last)))
+           (rev  (if last
+                     (magit-diff-visit--range-beginning)
+                   (magit-diff-visit--range-end)))
+           (buf  (if (and (not force-worktree)
+                          (stringp rev))
+                     (magit-find-file-noselect rev file)
+                   (or (get-file-buffer file)
+                       (find-file-noselect file)))))
+      (cond ((called-interactively-p 'any)
+             (magit-display-file-buffer buf))
+            (display-fn
+             (funcall display-fn buf))
+            ((or other-window (get-buffer-window buf))
+             (switch-to-buffer-other-window buf))
+            (t
+             (pop-to-buffer buf)))
+      (with-selected-window
+          (or (get-buffer-window buf 'visible)
+              (error "File buffer is not visible"))
+        (when line
+          (setq line
+                (cond ((eq rev 'staged)
+                       (apply 'magit-diff-visit--offset file nil line))
+                      ((and force-worktree
+                            (stringp rev))
+                       (apply 'magit-diff-visit--offset file rev line))
+                      (t
+                       (apply '+ line))))
+          (let ((pos (save-restriction
+                       (widen)
+                       (goto-char (point-min))
+                       (forward-line (1- line))
+                       (move-to-column col)
+                       (point))))
+            (unless (<= (point-min) pos (point-max))
+              (widen)
+              (goto-char pos))))
+        (when (magit-anything-unmerged-p file)
+          (smerge-start-session))
+        (run-hooks 'magit-diff-visit-file-hook)))))
+
+(defun magit-diff-visit-file-other-window (file)
+  "From a diff, visit the corresponding file at the appropriate position.
+The file is shown in another window.
+
+If the diff shows changes in the worktree, the index, or `HEAD',
+then visit the actual file.  Otherwise, when the diff is about an
+older commit or a range, then visit the appropriate blob.
+
+If point is on a removed line, then visit the blob for the first
+parent of the commit which removed that line, i.e. the last
+commit where that line still existed.  Otherwise visit the blob
+for the commit whose changes are being shown."
+  (interactive (list (--if-let (magit-file-at-point)
+                         (expand-file-name it)
+                       (user-error "No file at point"))))
+  (magit-diff-visit-file file t))
+
+(defvar magit-display-file-buffer-function
+  'magit-display-file-buffer-traditional
+  "The function used by `magit-diff-visit-file' to display blob buffers.
+
+Other commands such as `magit-find-file' do not use this
+function.  Instead they use high-level functions to select the
+window to be used to display the buffer.  This variable and the
+related functions are an experimental feature and should be
+treated as such.")
+
+(defun magit-display-file-buffer (buffer)
+  (funcall magit-display-file-buffer-function buffer))
+
+(defun magit-display-file-buffer-traditional (buffer)
+  "Display BUFFER in the current window.
+With a prefix argument display it in another window.
+Option `magit-display-file-buffer-function' controls
+whether `magit-diff-visit-file' uses this function."
+  (if (or current-prefix-arg (get-buffer-window buffer))
+      (pop-to-buffer buffer)
+    (switch-to-buffer buffer)))
+
+(defun magit-display-file-buffer-other-window (buffer)
+  "Display BUFFER in another window.
+With a prefix argument display it in the current window.
+Option `magit-display-file-buffer-function' controls
+whether `magit-diff-visit-file' uses this function."
+  (if (or current-prefix-arg (get-buffer-window buffer))
+      (switch-to-buffer buffer)
+    (pop-to-buffer buffer)))
+
+(defun magit-diff-visit-file-worktree (file &optional other-window)
+  "From a diff, visit the corresponding file at the appropriate position.
+
+When the file is already being displayed in another window of the
+same frame, then just select that window and adjust point.  With
+a prefix argument also display in another window.
+
+The actual file in the worktree is visited. The positions in the
+hunk headers get less useful the \"older\" the changes are, and
+as a result, jumping to the appropriate position gets less
+reliable.
+
+Also see `magit-diff-visit-file' which visits the respective
+blob, unless the diff shows changes in the worktree, the index,
+or `HEAD'."
+  (interactive (list (or (magit-file-at-point)
+                         (user-error "No file at point"))
+                     current-prefix-arg))
+  (magit-diff-visit-file file other-window t))
+
+(defun magit-diff-visit--range-end ()
+  (let ((rev (magit-diff--dwim)))
+    (if (symbolp rev)
+        rev
+      (setq rev (if (consp rev)
+                    (cdr rev)
+                  (cdr (magit-split-range rev))))
+      (if (magit-rev-head-p rev)
+          'unstaged
+        rev))))
+
+(defun magit-diff-visit--range-beginning ()
+  (let ((rev (magit-diff--dwim)))
+    (cond ((consp rev)
+           (concat (cdr rev) "^"))
+          ((stringp rev)
+           (car (magit-split-range rev)))
+          (t
+           rev))))
+
+(defun magit-diff-visit--hunk ()
+  (when-let ((scope (magit-diff-scope)))
+    (let ((section (magit-current-section)))
+      (cl-case scope
+        ((file files)
+         (setq section (car (oref section children))))
+        (list
+         (setq section (car (oref section children)))
+         (when section
+           (setq section (car (oref section children))))))
+      (and
+       ;; Unmerged files appear in the list of staged changes
+       ;; but unlike in the list of unstaged changes no diffs
+       ;; are shown here.  In that case `section' is nil.
+       section
+       ;; Currently the `hunk' type is also abused for file
+       ;; mode changes, which we are not interested in here.
+       ;; Such sections have no value.
+       (oref section value)
+       section))))
+
+(defun magit-diff-visit--offset (file rev hunk-start line-offset)
+  (let ((offset 0))
+    (with-temp-buffer
+      (save-excursion
+        (magit-with-toplevel
+          (magit-git-insert "diff" rev "--" file)))
+      (catch 'found
+        (while (re-search-forward
+                "^@@ -\\([0-9]+\\),\\([0-9]+\\) \\+\\([0-9]+\\),\\([0-9]+\\) @@"
+                nil t)
+          (let* ((abeg (string-to-number (match-string 1)))
+                 (alen (string-to-number (match-string 2)))
+                 (bbeg (string-to-number (match-string 3)))
+                 (blen (string-to-number (match-string 4)))
+                 (aend (+ abeg alen))
+                 (bend (+ bbeg blen))
+                 (hend (+ hunk-start line-offset)))
+            (if (<= abeg hunk-start)
+                (if (or (>= aend hend)
+                        (>= bend hend))
+                    (let ((line 0))
+                      (while (<= line alen)
+                        (forward-line 1)
+                        (cl-incf line)
+                        (cond ((looking-at "^\\+") (cl-incf offset))
+                              ((looking-at "^-")   (cl-decf offset)))))
+                  (cl-incf offset (- blen alen)))
+              (throw 'found nil))))))
+    (+ hunk-start line-offset offset)))
+
+(defun magit-diff-hunk-line (section)
+  (let* ((value  (oref section value))
+         (prefix (- (length value) 2))
+         (cpos   (marker-position (oref section content)))
+         (stop   (line-number-at-pos))
+         (cstart (save-excursion (goto-char cpos)
+                                 (line-number-at-pos)))
+         (prior  (and (= (length value) 3)
+                      (save-excursion (goto-char (line-beginning-position))
+                                      (looking-at "-"))))
+         (offset 0)
+         (line   (if prior
+                     (cadr value)
+                   (car (last value)))))
+    (string-match (format "^%s\\([0-9]+\\)" (if prior "-" "\\+")) line)
+    (setq line (string-to-number (match-string 1 line)))
+    (when (> cstart stop)
+      (save-excursion
+        (goto-char cpos)
+        (re-search-forward "^[-+]")
+        (setq stop (line-number-at-pos))))
+    (save-excursion
+      (goto-char cpos)
+      (while (< (line-number-at-pos) stop)
+        (unless (string-match-p
+                 (if prior "\\+" "-")
+                 (buffer-substring (point) (+ (point) prefix)))
+          (cl-incf offset))
+        (forward-line)))
+    (list line offset)))
+
+(defun magit-diff-hunk-column (section visit-beginning)
+  (if (or (< (point)
+             (oref section content))
+          (and (not visit-beginning)
+               (save-excursion (beginning-of-line) (looking-at-p "-"))))
+      0
+    (max 0 (- (+ (current-column) 2)
+              (length (oref section value))))))
+
+(defun magit-diff-visit-directory (directory &optional other-window)
+  (if (equal (magit-toplevel directory)
+             (magit-toplevel))
+      (dired-jump other-window (concat directory "/."))
+    (let ((display-buffer-overriding-action
+           (if other-window
+               '(nil (inhibit-same-window t))
+             '(display-buffer-same-window))))
+      (magit-status-internal directory))))
+
+;;;; Scroll commands
+
+(defun magit-diff-show-or-scroll-up ()
+  "Update the commit or diff buffer for the thing at point.
+
+Either show the commit or stash at point in the appropriate
+buffer, or if that buffer is already being displayed in the
+current frame and contains information about that commit or
+stash, then instead scroll the buffer up.  If there is no
+commit or stash at point, then prompt for a commit."
+  (interactive)
+  (magit-diff-show-or-scroll 'scroll-up))
+
+(defun magit-diff-show-or-scroll-down ()
+  "Update the commit or diff buffer for the thing at point.
+
+Either show the commit or stash at point in the appropriate
+buffer, or if that buffer is already being displayed in the
+current frame and contains information about that commit or
+stash, then instead scroll the buffer down.  If there is no
+commit or stash at point, then prompt for a commit."
+  (interactive)
+  (magit-diff-show-or-scroll 'scroll-down))
+
+(defun magit-diff-show-or-scroll (fn)
+  (let (rev cmd buf win)
+    (cond
+     (magit-blame-mode
+      (setq rev (oref (magit-current-blame-chunk) orig-rev))
+      (setq cmd 'magit-show-commit)
+      (setq buf (magit-mode-get-buffer 'magit-revision-mode)))
+     ((derived-mode-p 'git-rebase-mode)
+      (save-excursion
+        (goto-char (line-beginning-position))
+        (--if-let (and git-rebase-line
+                       (looking-at git-rebase-line)
+                       (match-string 2))
+            (progn (setq rev it)
+                   (setq cmd 'magit-show-commit)
+                   (setq buf (magit-mode-get-buffer 'magit-revision-mode)))
+          (user-error "No commit on this line"))))
+     (t
+      (magit-section-case
+        (branch
+         (setq rev (magit-ref-maybe-qualify (oref it value)))
+         (setq cmd 'magit-show-commit)
+         (setq buf (magit-mode-get-buffer 'magit-revision-mode)))
+        (commit
+         (setq rev (oref it value))
+         (setq cmd 'magit-show-commit)
+         (setq buf (magit-mode-get-buffer 'magit-revision-mode)))
+        (stash
+         (setq rev (oref it value))
+         (setq cmd 'magit-stash-show)
+         (setq buf (magit-mode-get-buffer 'magit-stash-mode))))))
+    (if rev
+        (if (and buf
+                 (setq win (get-buffer-window buf))
+                 (with-current-buffer buf
+                   (and (equal rev (car magit-refresh-args))
+                        (equal (magit-rev-parse rev)
+                               magit-buffer-revision-hash))))
+            (with-selected-window win
+              (condition-case nil
+                  (funcall fn)
+                (error
+                 (goto-char (pcase fn
+                              (`scroll-up   (point-min))
+                              (`scroll-down (point-max)))))))
+          (let ((magit-display-buffer-noselect t))
+            (if (eq cmd 'magit-show-commit)
+                (apply #'magit-show-commit rev (magit-show-commit--arguments))
+              (funcall cmd rev))))
+      (call-interactively #'magit-show-commit))))
+
+;;; Diff Mode
+
+(defvar magit-diff-mode-map
+  (let ((map (make-sparse-keymap)))
+    (set-keymap-parent map magit-mode-map)
+    (define-key map "\C-c\C-d" 'magit-diff-while-committing)
+    (define-key map "\C-c\C-b" 'magit-go-backward)
+    (define-key map "\C-c\C-f" 'magit-go-forward)
+    (define-key map "\s" 'scroll-up)
+    (define-key map "\d" 'scroll-down)
+    (define-key map "j" 'magit-jump-to-diffstat-or-diff)
+    (define-key map [remap write-file] 'magit-patch-save)
+    map)
+  "Keymap for `magit-diff-mode'.")
+
+(define-derived-mode magit-diff-mode magit-mode "Magit Diff"
+  "Mode for looking at a Git diff.
+
+This mode is documented in info node `(magit)Diff Buffer'.
+
+\\<magit-mode-map>\
+Type \\[magit-refresh] to refresh the current buffer.
+Type \\[magit-section-toggle] to expand or hide the section at point.
+Type \\[magit-visit-thing] to visit the hunk or file at point.
+
+Staging and applying changes is documented in info node
+`(magit)Staging and Unstaging' and info node `(magit)Applying'.
+
+\\<magit-hunk-section-map>Type \
+\\[magit-apply] to apply the change at point, \
+\\[magit-stage] to stage,
+\\[magit-unstage] to unstage, \
+\\[magit-discard] to discard, or \
+\\[magit-reverse] to reverse it.
+
+\\{magit-diff-mode-map}"
+  :group 'magit-diff
+  (hack-dir-local-variables-non-file-buffer)
+  (setq imenu-prev-index-position-function
+        'magit-imenu--diff-prev-index-position-function)
+  (setq imenu-extract-index-name-function
+        'magit-imenu--diff-extract-index-name-function)
+  (setq-local bookmark-make-record-function
+              'magit-bookmark--diff-make-record))
+
+(defun magit-diff-refresh-buffer (rev-or-range const _args files)
+  "Refresh the current `magit-diff-mode' buffer.
+
+In such buffers the buffer-local value of `magit-refresh-args'
+has the same form as the arguments of this function.  The value
+is set in `magit-mode-setup'."
+  (magit-set-header-line-format
+   (if (member "--no-index" const)
+       (apply #'format "Differences between %s and %s" files)
+     (concat (if rev-or-range
+                 (if (string-match-p "\\(\\.\\.\\|\\^-\\)"
+                                     rev-or-range)
+                     (format "Changes in %s" rev-or-range)
+                   (format "Changes from %s to working tree" rev-or-range))
+               (if (member "--cached" const)
+                   "Staged changes"
+                 "Unstaged changes"))
+             (pcase (length files)
+               (0)
+               (1 (concat " in file " (car files)))
+               (_ (concat " in files "
+                          (mapconcat #'identity files ", ")))))))
+  (magit-insert-section (diffbuf)
+    (run-hook-with-args 'magit-diff-sections-hook rev-or-range)))
+
+(defun magit-insert-diff (rev-or-range)
+  "Insert the diff into this `magit-diff-mode' buffer."
+  (let ((magit-git-global-arguments
+         (remove "--literal-pathspecs" magit-git-global-arguments)))
+    (magit-git-wash #'magit-diff-wash-diffs
+      "diff" rev-or-range "-p" "--no-prefix"
+      (and (member "--stat" (nth 2 magit-refresh-args)) "--numstat")
+      (nth 1 magit-refresh-args)
+      (nth 2 magit-refresh-args) "--"
+      (nth 3 magit-refresh-args))))
+
+(defvar magit-file-section-map
+  (let ((map (make-sparse-keymap)))
+    (unless (featurep 'jkl)
+      (define-key map (kbd "C-j") 'magit-diff-visit-file-worktree))
+    (define-key map [C-return] 'magit-diff-visit-file-worktree)
+    (define-key map [remap magit-visit-thing]      'magit-diff-visit-file)
+    (define-key map [remap magit-delete-thing]     'magit-discard)
+    (define-key map [remap magit-revert-no-commit] 'magit-reverse)
+    (define-key map "a" 'magit-apply)
+    (define-key map "C" 'magit-commit-add-log)
+    (define-key map "s" 'magit-stage)
+    (define-key map "u" 'magit-unstage)
+    (define-key map "&" 'magit-do-async-shell-command)
+    (define-key map "\C-c\C-t" 'magit-diff-trace-definition)
+    (define-key map "\C-c\C-e" 'magit-diff-edit-hunk-commit)
+    map)
+  "Keymap for `file' sections.")
+
+(defvar magit-hunk-section-map
+  (let ((map (make-sparse-keymap)))
+    (unless (featurep 'jkl)
+      (define-key map (kbd "C-j") 'magit-diff-visit-file-worktree))
+    (define-key map [C-return] 'magit-diff-visit-file-worktree)
+    (define-key map [remap magit-visit-thing]      'magit-diff-visit-file)
+    (define-key map [remap magit-delete-thing]     'magit-discard)
+    (define-key map [remap magit-revert-no-commit] 'magit-reverse)
+    (define-key map "a" 'magit-apply)
+    (define-key map "C" 'magit-commit-add-log)
+    (define-key map "s" 'magit-stage)
+    (define-key map "u" 'magit-unstage)
+    (define-key map "&" 'magit-do-async-shell-command)
+    (define-key map "\C-c\C-t" 'magit-diff-trace-definition)
+    (define-key map "\C-c\C-e" 'magit-diff-edit-hunk-commit)
+    map)
+  "Keymap for `hunk' sections.")
+
+(defconst magit-diff-headline-re
+  (concat "^\\(@@@?\\|diff\\|Submodule\\|"
+          "\\* Unmerged path\\|merged\\|changed in both\\|"
+          "added in remote\\|removed in remote\\)"))
+
+(defconst magit-diff-statline-re
+  (concat "^ ?"
+          "\\(.*\\)"     ; file
+          "\\( +| +\\)"  ; separator
+          "\\([0-9]+\\|Bin\\(?: +[0-9]+ -> [0-9]+ bytes\\)?$\\) ?"
+          "\\(\\+*\\)"   ; add
+          "\\(-*\\)$"))  ; del
+
+(defun magit-diff-wash-diffs (args &optional limit)
+  (when (member "--stat" args)
+    (magit-diff-wash-diffstat))
+  (when (re-search-forward magit-diff-headline-re limit t)
+    (goto-char (line-beginning-position))
+    (magit-wash-sequence (apply-partially 'magit-diff-wash-diff args))
+    (insert ?\n)))
+
+(defun magit-jump-to-diffstat-or-diff ()
+  "Jump to the diffstat or diff.
+When point is on a file inside the diffstat section, then jump
+to the respective diff section, otherwise jump to the diffstat
+section or a child thereof."
+  (interactive)
+  (--if-let (magit-get-section
+             (append (magit-section-case
+                       ([file diffstat] `((file . ,(oref it value))))
+                       (file `((file . ,(oref it value)) (diffstat)))
+                       (t '((diffstat))))
+                     (magit-section-ident magit-root-section)))
+      (magit-section-goto it)
+    (user-error "No diffstat in this buffer")))
+
+(defun magit-diff-wash-diffstat ()
+  (let (heading (beg (point)))
+    (when (re-search-forward "^ ?\\([0-9]+ +files? change[^\n]*\n\\)" nil t)
+      (setq heading (match-string 1))
+      (magit-delete-match)
+      (goto-char beg)
+      (magit-insert-section (diffstat)
+        (insert (propertize heading 'face 'magit-diff-file-heading))
+        (magit-insert-heading)
+        (let (files)
+          (while (looking-at "^[-0-9]+\t[-0-9]+\t\\(.+\\)$")
+            (push (magit-decode-git-path
+                   (let ((f (match-string 1)))
+                     (if (string-match " => " f)
+                         (substring f (match-end 0))
+                       f)))
+                  files)
+            (magit-delete-line))
+          (setq files (nreverse files))
+          (while (looking-at magit-diff-statline-re)
+            (magit-bind-match-strings (file sep cnt add del) nil
+              (magit-delete-line)
+              (when (string-match " +$" file)
+                (setq sep (concat (match-string 0 file) sep))
+                (setq file (substring file 0 (match-beginning 0))))
+              (let ((le (length file)) ld)
+                (setq file (magit-decode-git-path file))
+                (setq ld (length file))
+                (when (> le ld)
+                  (setq sep (concat (make-string (- le ld) ?\s) sep))))
+              (magit-insert-section (file (pop files))
+                (insert (propertize file 'face 'magit-filename) sep cnt " ")
+                (when add
+                  (insert (propertize add 'face 'magit-diffstat-added)))
+                (when del
+                  (insert (propertize del 'face 'magit-diffstat-removed)))
+                (insert "\n")))))
+        (if (looking-at "^$") (forward-line) (insert "\n"))))))
+
+(defun magit-diff-wash-diff (args)
+  (cond
+   ((looking-at "^Submodule")
+    (magit-diff-wash-submodule))
+   ((looking-at "^\\* Unmerged path \\(.*\\)")
+    (let ((file (magit-decode-git-path (match-string 1))))
+      (magit-delete-line)
+      (unless (and (derived-mode-p 'magit-status-mode)
+                   (not (member "--cached" args)))
+        (magit-insert-section (file file)
+          (insert (propertize
+                   (format "unmerged   %s%s" file
+                           (pcase (cddr (car (magit-file-status file)))
+                             (`(?D ?D) " (both deleted)")
+                             (`(?D ?U) " (deleted by us)")
+                             (`(?U ?D) " (deleted by them)")
+                             (`(?A ?A) " (both added)")
+                             (`(?A ?U) " (added by us)")
+                             (`(?U ?A) " (added by them)")
+                             (`(?U ?U) "")))
+                   'face 'magit-diff-file-heading))
+          (insert ?\n))))
+    t)
+   ((looking-at (concat "^\\(merged\\|changed in both\\|"
+                        "added in remote\\|removed in remote\\)"))
+    (let ((status (pcase (match-string 1)
+                    ("merged" "merged")
+                    ("changed in both" "conflict")
+                    ("added in remote" "new file")
+                    ("removed in remote" "deleted")))
+          file orig base modes)
+      (magit-delete-line)
+      (while (looking-at
+              "^  \\([^ ]+\\) +[0-9]\\{6\\} \\([a-z0-9]\\{40\\}\\) \\(.+\\)$")
+        (magit-bind-match-strings (side _blob name) nil
+          (pcase side
+            ("result" (setq file name))
+            ("our"    (setq orig name))
+            ("their"  (setq file name))
+            ("base"   (setq base name))))
+        (magit-delete-line))
+      (when orig (setq orig (magit-decode-git-path orig)))
+      (when file (setq file (magit-decode-git-path file)))
+      (magit-diff-insert-file-section (or file base) orig status modes nil)))
+   ((looking-at
+     "^diff --\\(?:\\(git\\) \\(?:\\(.+?\\) \\2\\)?\\|\\(cc\\|combined\\) \\(.+\\)\\)")
+    (let ((status (cond ((equal (match-string 1) "git")        "modified")
+                        ((derived-mode-p 'magit-revision-mode) "resolved")
+                        (t                                     "unmerged")))
+          (file (or (match-string 2) (match-string 4)))
+          (beg (point))
+          orig header modes)
+      (save-excursion
+        (forward-line 1)
+        (setq header (buffer-substring
+                      beg (if (re-search-forward magit-diff-headline-re nil t)
+                              (match-beginning 0)
+                            (point-max)))))
+      (magit-delete-line)
+      (while (not (or (eobp) (looking-at magit-diff-headline-re)))
+        (if (looking-at "^old mode \\([^\n]+\\)\nnew mode \\([^\n]+\\)\n")
+            (progn (setq modes (match-string 0))
+                   (magit-delete-match))
+          (cond
+           ((looking-at "^--- \\([^/].*?\\)\t?$") ; i.e. not /dev/null
+            (setq orig (match-string 1)))
+           ((looking-at "^\\+\\+\\+ \\([^/].*?\\)\t?$")
+            (setq file (match-string 1)))
+           ((looking-at "^\\(copy\\|rename\\) from \\(.+\\)$")
+            (setq orig (match-string 2)))
+           ((looking-at "^\\(copy\\|rename\\) to \\(.+\\)$")
+            (setq file (match-string 2))
+            (setq status (if (equal (match-string 1) "copy") "new file" "renamed")))
+           ((looking-at "^\\(new file\\|deleted\\)")
+            (setq status (match-string 1))))
+          (magit-delete-line)))
+      (when orig
+        (setq orig (magit-decode-git-path orig)))
+      (setq file (magit-decode-git-path file))
+      ;; KLUDGE `git-log' ignores `--no-prefix' when `-L' is used.
+      (when (and (derived-mode-p 'magit-log-mode)
+                 (--first (string-match-p "\\`-L" it)
+                          (nth 1 magit-refresh-args)))
+        (setq file (substring file 2))
+        (when orig
+          (setq orig (substring orig 2))))
+      (magit-diff-insert-file-section file orig status modes header)))))
+
+(defun magit-diff-insert-file-section (file orig status modes header)
+  (magit-insert-section section
+    (file file (or (equal status "deleted")
+                   (derived-mode-p 'magit-status-mode)))
+    (insert (propertize (format "%-10s %s\n" status
+                                (if (or (not orig) (equal orig file))
+                                    file
+                                  (format "%s -> %s" orig file)))
+                        'face 'magit-diff-file-heading))
+    (magit-insert-heading)
+    (unless (equal orig file)
+      (oset section source orig))
+    (oset section header header)
+    (when modes
+      (magit-insert-section (hunk)
+        (insert modes)))
+    (magit-wash-sequence #'magit-diff-wash-hunk)))
+
+(defun magit-diff-wash-submodule ()
+  ;; See `show_submodule_summary' in submodule.c and "this" commit.
+  (when (looking-at "^Submodule \\([^ ]+\\)")
+    (let ((module (match-string 1))
+          untracked modified)
+      (when (looking-at "^Submodule [^ ]+ contains untracked content$")
+        (magit-delete-line)
+        (setq untracked t))
+      (when (looking-at "^Submodule [^ ]+ contains modified content$")
+        (magit-delete-line)
+        (setq modified t))
+      (cond
+       ((and (looking-at "^Submodule \\([^ ]+\\) \\([^ :]+\\)\\( (rewind)\\)?:$")
+             (equal (match-string 1) module))
+        (magit-bind-match-strings (_module range rewind) nil
+          (magit-delete-line)
+          (while (looking-at "^  \\([<>]\\) \\(.+\\)$")
+            (magit-delete-line))
+          (when rewind
+            (setq range (replace-regexp-in-string "[^.]\\(\\.\\.\\)[^.]"
+                                                  "..." range t t 1)))
+          (magit-insert-section (file module t)
+            (magit-insert-heading
+              (concat (propertize (concat "modified   " module)
+                                  'face 'magit-diff-file-heading)
+                      " ("
+                      (cond (rewind "rewind")
+                            ((string-match-p "\\.\\.\\." range) "non-ff")
+                            (t "new commits"))
+                      (and (or modified untracked)
+                           (concat ", "
+                                   (and modified "modified")
+                                   (and modified untracked " and ")
+                                   (and untracked "untracked")
+                                   " content"))
+                      ")"))
+            (let ((default-directory
+                    (file-name-as-directory
+                     (expand-file-name module (magit-toplevel)))))
+              (magit-git-wash (apply-partially 'magit-log-wash-log 'module)
+                "log" "--oneline" "--left-right" range)
+              (delete-char -1)))))
+       ((and (looking-at "^Submodule \\([^ ]+\\) \\([^ ]+\\) (\\([^)]+\\))$")
+             (equal (match-string 1) module))
+        (magit-bind-match-strings (_module _range msg) nil
+          (magit-delete-line)
+          (magit-insert-section (file module)
+            (magit-insert-heading
+              (concat (propertize (concat "submodule  " module)
+                                  'face 'magit-diff-file-heading)
+                      " (" msg ")")))))
+       (t
+        (magit-insert-section (file module)
+          (magit-insert-heading
+            (concat (propertize (concat "modified   " module)
+                                'face 'magit-diff-file-heading)
+                    " ("
+                    (and modified "modified")
+                    (and modified untracked " and ")
+                    (and untracked "untracked")
+                    " content)"))))))))
+
+(defun magit-diff-wash-hunk ()
+  (when (looking-at "^@\\{2,\\} \\(.+?\\) @\\{2,\\}\\(?: \\(.*\\)\\)?")
+    (let ((heading (match-string 0))
+          (value (cons (match-string 2) (split-string (match-string 1)))))
+      (magit-delete-line)
+      (magit-insert-section it (hunk value)
+        (insert (propertize (concat heading "\n") 'face 'magit-diff-hunk-heading))
+        (magit-insert-heading)
+        (while (not (or (eobp) (looking-at "^[^-+\s\\]")))
+          (forward-line))
+        (oset it end (point))
+        (oset it washer 'magit-diff-paint-hunk)))
+    t))
+
+(defun magit-diff-expansion-threshold (section)
+  "Keep new diff sections collapsed if washing takes too long."
+  (and (magit-file-section-p section)
+       (> (float-time (time-subtract (current-time) magit-refresh-start-time))
+          magit-diff-expansion-threshold)
+       'hide))
+
+;;; Revision Mode
+
+(define-derived-mode magit-revision-mode magit-diff-mode "Magit Rev"
+  "Mode for looking at a Git commit.
+
+This mode is documented in info node `(magit)Revision Buffer'.
+
+\\<magit-mode-map>\
+Type \\[magit-refresh] to refresh the current buffer.
+Type \\[magit-section-toggle] to expand or hide the section at point.
+Type \\[magit-visit-thing] to visit the hunk or file at point.
+
+Staging and applying changes is documented in info node
+`(magit)Staging and Unstaging' and info node `(magit)Applying'.
+
+\\<magit-hunk-section-map>Type \
+\\[magit-apply] to apply the change at point, \
+\\[magit-stage] to stage,
+\\[magit-unstage] to unstage, \
+\\[magit-discard] to discard, or \
+\\[magit-reverse] to reverse it.
+
+\\{magit-revision-mode-map}"
+  :group 'magit-revision
+  (hack-dir-local-variables-non-file-buffer)
+  (setq-local bookmark-make-record-function
+              'magit-bookmark--revision-make-record))
+
+(defun magit-revision-refresh-buffer (rev __const _args files)
+  (magit-set-header-line-format
+   (concat (capitalize (magit-object-type rev))
+           " "
+           rev
+           (pcase (length files)
+             (0)
+             (1 (concat " limited to file " (car files)))
+             (_ (concat " limited to files "
+                        (mapconcat #'identity files ", "))))))
+  (setq magit-buffer-revision-hash (magit-rev-parse rev))
+  (magit-insert-section (commitbuf)
+    (run-hook-with-args 'magit-revision-sections-hook rev)))
+
+(defun magit-insert-revision-diff (rev)
+  "Insert the diff into this `magit-revision-mode' buffer."
+  (let ((magit-git-global-arguments
+         (remove "--literal-pathspecs" magit-git-global-arguments)))
+    ;; Before v2.2.0, "--format=" did not mean "no output".
+    ;; Instead the default format was used.  So use "--format=%n"
+    ;; and then delete the empty lines.
+    (magit-git-wash (lambda (args)
+                      (delete-region (point) (progn (forward-line 3) (point)))
+                      (magit-diff-wash-diffs args))
+      "show" "-p" "--cc" "--format=%n" "--no-prefix"
+      (and (member "--stat" (nth 2 magit-refresh-args)) "--numstat")
+      (nth 2 magit-refresh-args) (concat rev "^{commit}") "--"
+      (nth 3 magit-refresh-args))))
+
+(defun magit-insert-revision-tag (rev)
+  "Insert tag message and headers into a revision buffer.
+This function only inserts anything when `magit-show-commit' is
+called with a tag as argument, when that is called with a commit
+or a ref which is not a branch, then it inserts nothing."
+  (when (equal (magit-object-type rev) "tag")
+    (magit-insert-section (taginfo)
+      (let ((beg (point)))
+        ;; "git verify-tag -v" would output what we need, but the gpg
+        ;; output is send to stderr and we have no control over the
+        ;; order in which stdout and stderr are inserted, which would
+        ;; make parsing hard.  We are forced to use "git cat-file tag"
+        ;; instead, which inserts the signature instead of verifying
+        ;; it.  We remove that later and then insert the verification
+        ;; output using "git verify-tag" (without the "-v").
+        (magit-git-insert "cat-file" "tag" rev)
+        (goto-char beg)
+        (forward-line 3)
+        (delete-region beg (point)))
+      (looking-at "^tagger \\([^<]+\\) <\\([^>]+\\)")
+      (let ((heading (format "Tagger: %s <%s>"
+                             (match-string 1)
+                             (match-string 2))))
+        (magit-delete-line)
+        (insert (propertize heading 'face 'magit-section-secondary-heading)))
+      (magit-insert-heading)
+      (if (re-search-forward "-----BEGIN PGP SIGNATURE-----" nil t)
+          (progn
+            (let ((beg (match-beginning 0)))
+              (re-search-forward "-----END PGP SIGNATURE-----")
+              (delete-region beg (point)))
+            (insert ?\n)
+            (process-file magit-git-executable nil t nil "verify-tag" rev))
+        (goto-char (point-max)))
+      (insert ?\n))))
+
+(defvar magit-commit-message-section-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map [remap magit-visit-thing] 'magit-show-commit)
+    map)
+  "Keymap for `commit-message' sections.")
+
+(defun magit-insert-revision-message (rev)
+  "Insert the commit message into a revision buffer."
+  (magit-insert-section (commit-message)
+    (let ((beg (point)))
+      (magit-rev-insert-format "%B" rev)
+      (if (= (point) (+ beg 2))
+          (progn (backward-delete-char 2)
+                 (insert "(no message)\n"))
+        (goto-char beg)
+        (save-excursion
+          (while (search-forward "\r\n" nil t) ; Remove trailing CRs.
+            (delete-region (match-beginning 0) (1+ (match-beginning 0)))))
+        (when magit-revision-use-hash-sections
+          (save-excursion
+            (while (not (eobp))
+              (re-search-forward "\\_<" nil 'move)
+              (let ((beg (point)))
+                (re-search-forward "\\_>" nil t)
+                (when (> (point) beg)
+                  (let ((text (buffer-substring-no-properties beg (point))))
+                    (when (pcase magit-revision-use-hash-sections
+                            (`quickest ; false negatives and positives
+                             (and (>= (length text) 7)
+                                  (string-match-p "[0-9]" text)
+                                  (string-match-p "[a-z]" text)))
+                            (`quicker  ; false negatives (number-less hashes)
+                             (and (>= (length text) 7)
+                                  (string-match-p "[0-9]" text)
+                                  (magit-rev-verify-commit text)))
+                            (`quick    ; false negatives (short hashes)
+                             (and (>= (length text) 7)
+                                  (magit-rev-verify-commit text)))
+                            (`slow
+                             (magit-rev-verify-commit text)))
+                      (put-text-property beg (point) 'face 'magit-hash)
+                      (let ((end (point)))
+                        (goto-char beg)
+                        (magit-insert-section (commit text)
+                          (goto-char end))))))))))
+        (save-excursion
+          (forward-line)
+          (put-text-property beg (point) 'face 'magit-section-secondary-heading)
+          (magit-insert-heading))
+        (when magit-diff-highlight-keywords
+          (save-excursion
+            (while (re-search-forward "\\[[^[]*\\]" nil t)
+              (put-text-property (match-beginning 0)
+                                 (match-end 0)
+                                 'face 'magit-keyword))))
+        (goto-char (point-max))))))
+
+(defun magit-insert-revision-notes (rev)
+  "Insert commit notes into a revision buffer."
+  (let* ((var "core.notesRef")
+         (def (or (magit-get var) "refs/notes/commits")))
+    (dolist (ref (or (magit-list-active-notes-refs)))
+      (magit-insert-section (notes ref (not (equal ref def)))
+        (let ((beg (point)))
+          (magit-git-insert "-c" (concat "core.notesRef=" ref)
+                            "notes" "show" rev)
+          (if (= (point) beg)
+              (magit-cancel-section)
+            (goto-char beg)
+            (end-of-line)
+            (put-text-property beg (point) 'face 'magit-section-secondary-heading)
+            (insert (format " (%s)"
+                            (propertize (if (string-prefix-p "refs/notes/" ref)
+                                            (substring ref 11)
+                                          ref)
+                                        'face 'magit-refname)))
+            (magit-insert-heading)
+            (goto-char (point-max))
+            (insert ?\n)))))))
+
+(defun magit-insert-revision-headers (rev)
+  "Insert headers about the commit into a revision buffer."
+  (magit-insert-section (headers)
+    ;; Before v2.2.0, "%D" was not supported.
+    (--when-let (magit-rev-format "%d" rev "--decorate=full")
+      (insert (magit-format-ref-labels it) ?\s))
+    (insert (propertize (magit-rev-parse (concat rev "^{commit}"))
+                        'face 'magit-hash))
+    (magit-insert-heading)
+    (let ((beg (point)))
+      (magit-rev-insert-format magit-revision-headers-format rev)
+      (magit-insert-revision-gravatars rev beg))
+    (when magit-revision-insert-related-refs
+      (dolist (parent (magit-commit-parents rev))
+        (magit-insert-section (commit parent)
+          (let ((line (magit-rev-format "%h %s" parent)))
+            (string-match "^\\([^ ]+\\) \\(.*\\)" line)
+            (magit-bind-match-strings (hash msg) line
+              (insert "Parent:     ")
+              (insert (propertize hash 'face 'magit-hash))
+              (insert " " msg "\n")))))
+      (when-let ((merged (magit-list-merged-branches rev)))
+        (insert "Merged:    ")
+        (let (branch)
+          (while (and (< (+ (- (point) (line-beginning-position))
+                            (length (car merged)) 9)
+                         (window-width))
+                      (setq branch (pop merged)))
+            (insert ?\s)
+            (magit-insert-section (branch branch)
+              (insert (propertize branch 'face 'magit-branch-local)))))
+        (when merged
+          (insert (format " (%s more)" (length merged))))
+        (insert ?\n))
+      (when-let ((containing (magit-list-containing-branches rev)))
+        (insert "Containing:")
+        (let (branch)
+          (while (and (< (+ (- (point) (line-beginning-position))
+                            (length (car containing)) 9)
+                         (window-width))
+                      (setq branch (pop containing)))
+            (insert ?\s)
+            (magit-insert-section (branch branch)
+              (insert (propertize branch 'face 'magit-branch-local)))))
+        (when containing
+          (insert (format " (%s more)" (length containing))))
+        (insert ?\n))
+      (when-let ((follows (magit-get-current-tag rev t)))
+        (let ((tag (car  follows))
+              (cnt (cadr follows)))
+          (magit-insert-section (tag tag)
+            (insert (format "Follows:    %s (%s)\n"
+                            (propertize tag 'face 'magit-tag)
+                            (propertize (number-to-string cnt)
+                                        'face 'magit-branch-local))))))
+      (when-let ((precedes (magit-get-next-tag rev t)))
+        (let ((tag (car  precedes))
+              (cnt (cadr precedes)))
+          (magit-insert-section (tag tag)
+            (insert (format "Precedes:   %s (%s)\n"
+                            (propertize tag 'face 'magit-tag)
+                            (propertize (number-to-string cnt)
+                                        'face 'magit-tag))))))
+      (insert ?\n))))
+
+(defun magit-insert-revision-gravatars (rev beg)
+  (when (and magit-revision-show-gravatars
+             (window-system))
+    (require 'gravatar)
+    (pcase-let ((`(,author . ,committer) magit-revision-show-gravatars))
+      (--when-let (magit-rev-format "%aE" rev)
+        (magit-insert-revision-gravatar beg rev it author))
+      (--when-let (magit-rev-format "%cE" rev)
+        (magit-insert-revision-gravatar beg rev it committer)))))
+
+(defun magit-insert-revision-gravatar (beg rev email regexp)
+  (save-excursion
+    (goto-char beg)
+    (when (re-search-forward regexp nil t)
+      (let* ((column   (length (match-string 0)))
+             (font-obj (query-font (font-at (point) (get-buffer-window))))
+             (size     (* 2 (+ (aref font-obj 4)
+                               (aref font-obj 5))))
+             (align-to (+ column
+                          (ceiling (/ size (aref font-obj 7) 1.0))
+                          1))
+             (gravatar-size (- size 2)))
+        (gravatar-retrieve email 'magit-insert-revision-gravatar-cb
+                           (list rev (point-marker) align-to column))))))
+
+(defun magit-insert-revision-gravatar-cb (image rev marker align-to column)
+  (unless (eq image 'error)
+    (when-let ((buffer (marker-buffer marker)))
+      (with-current-buffer buffer
+        (save-excursion
+          (goto-char marker)
+          ;; The buffer might display another revision by now or
+          ;; it might have been refreshed, in which case another
+          ;; process might already have inserted the image.
+          (when (and (equal rev (car magit-refresh-args))
+                     (not (eq (car-safe
+                               (car-safe
+                                (get-text-property (point) 'display)))
+                              'image)))
+            (let ((top `((,@image :ascent center :relief 1)
+                         (slice 0.0 0.0 1.0 0.5)))
+                  (bot `((,@image :ascent center :relief 1)
+                         (slice 0.0 0.5 1.0 1.0)))
+                  (align `((space :align-to ,align-to))))
+              (when magit-revision-use-gravatar-kludge
+                (cl-rotatef top bot))
+              (let ((inhibit-read-only t))
+                (insert (propertize " " 'display top))
+                (insert (propertize " " 'display align))
+                (forward-line)
+                (forward-char column)
+                (insert (propertize " " 'display bot))
+                (insert (propertize " " 'display align))))))))))
+
+;;; Diff Sections
+
+(defvar magit-unstaged-section-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map [remap magit-visit-thing]  'magit-diff-unstaged)
+    (define-key map [remap magit-delete-thing] 'magit-discard)
+    (define-key map "s" 'magit-stage)
+    (define-key map "u" 'magit-unstage)
+    map)
+  "Keymap for the `unstaged' section.")
+
+(magit-define-section-jumper magit-jump-to-unstaged "Unstaged changes" unstaged)
+
+(defun magit-insert-unstaged-changes ()
+  "Insert section showing unstaged changes."
+  (magit-insert-section (unstaged)
+    (magit-insert-heading "Unstaged changes:")
+    (magit-git-wash #'magit-diff-wash-diffs
+      "diff" magit-diff-section-arguments "--no-prefix"
+      "--" magit-diff-section-file-args)))
+
+(defvar magit-staged-section-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map [remap magit-visit-thing]      'magit-diff-staged)
+    (define-key map [remap magit-delete-thing]     'magit-discard)
+    (define-key map [remap magit-revert-no-commit] 'magit-reverse)
+    (define-key map "s" 'magit-stage)
+    (define-key map "u" 'magit-unstage)
+    map)
+  "Keymap for the `staged' section.")
+
+(magit-define-section-jumper magit-jump-to-staged "Staged changes" staged)
+
+(defun magit-insert-staged-changes ()
+  "Insert section showing staged changes."
+  ;; Avoid listing all files as deleted when visiting a bare repo.
+  (unless (magit-bare-repo-p)
+    (magit-insert-section (staged)
+      (magit-insert-heading "Staged changes:")
+      (magit-git-wash #'magit-diff-wash-diffs
+        "diff" "--cached" magit-diff-section-arguments "--no-prefix"
+        "--" magit-diff-section-file-args))))
+
+;;; Diff Type
+
+(defun magit-diff-type (&optional section)
+  "Return the diff type of SECTION.
+
+The returned type is one of the symbols `staged', `unstaged',
+`committed', or `undefined'.  This type serves a similar purpose
+as the general type common to all sections (which is stored in
+the `type' slot of the corresponding `magit-section' struct) but
+takes additional information into account.  When the SECTION
+isn't related to diffs and the buffer containing it also isn't
+a diff-only buffer, then return nil.
+
+Currently the type can also be one of `tracked' and `untracked'
+but these values are not handled explicitly everywhere they
+should be and a possible fix could be to just return nil here.
+
+The section has to be a `diff' or `hunk' section, or a section
+whose children are of type `diff'.  If optional SECTION is nil,
+return the diff type for the current section.  In buffers whose
+major mode is `magit-diff-mode' SECTION is ignored and the type
+is determined using other means.  In `magit-revision-mode'
+buffers the type is always `committed'.
+
+Do not confuse this with `magit-diff-scope' (which see)."
+  (--when-let (or section (magit-current-section))
+    (cond ((derived-mode-p 'magit-revision-mode 'magit-stash-mode) 'committed)
+          ((derived-mode-p 'magit-diff-mode)
+           (let ((range (nth 0 magit-refresh-args))
+                 (const (nth 1 magit-refresh-args)))
+             (cond ((member "--no-index" const) 'undefined)
+                   ((not range)
+                    (if (member "--cached" const)
+                        'staged
+                      'unstaged))
+                   ((member "--cached" const)
+                    (if (magit-rev-head-p range)
+                        'staged
+                      'undefined)) ; i.e. committed and staged
+                   (t 'committed))))
+          ((derived-mode-p 'magit-status-mode)
+           (let ((stype (oref it type)))
+             (if (memq stype '(staged unstaged tracked untracked))
+                 stype
+               (pcase stype
+                 (`file (let* ((parent (oref it parent))
+                               (type   (oref parent type)))
+                          (if (eq type 'file)
+                              (magit-diff-type parent)
+                            type)))
+                 (`hunk (-> it
+                            (oref parent)
+                            (oref parent)
+                            (oref type)))))))
+          ((derived-mode-p 'magit-log-mode)
+           (if (or (and (magit-section-match 'commit section)
+                        (oref section children))
+                   (magit-section-match [* file commit] section))
+               'committed
+           'undefined))
+          (t 'undefined))))
+
+(cl-defun magit-diff-scope (&optional (section nil ssection) strict)
+  "Return the diff scope of SECTION or the selected section(s).
+
+A diff's \"scope\" describes what part of a diff is selected, it is
+a symbol, one of `region', `hunk', `hunks', `file', `files', or
+`list'.  Do not confuse this with the diff \"type\", as returned by
+`magit-diff-type'.
+
+If optional SECTION is non-nil, then return the scope of that,
+ignoring the sections selected by the region.  Otherwise return
+the scope of the current section, or if the region is active and
+selects a valid group of diff related sections, the type of these
+sections, i.e. `hunks' or `files'.  If SECTION, or if that is nil
+the current section, is a `hunk' section; and the region region
+starts and ends inside the body of a that section, then the type
+is `region'.  If the region is empty after a mouse click, then
+`hunk' is returned instead of `region'.
+
+If optional STRICT is non-nil, then return nil if the diff type of
+the section at point is `untracked' or the section at point is not
+actually a `diff' but a `diffstat' section."
+  (let ((siblings (and (not ssection) (magit-region-sections nil t))))
+    (setq section (or section (car siblings) (magit-current-section)))
+    (when (and section
+               (or (not strict)
+                   (and (not (eq (magit-diff-type section) 'untracked))
+                        (not (eq (--when-let (oref section parent)
+                                   (oref it type))
+                                 'diffstat)))))
+      (pcase (list (oref section type)
+                   (and siblings t)
+                   (magit-diff-use-hunk-region-p)
+                   ssection)
+        (`(hunk nil   t  ,_)
+         (if (magit-section-internal-region-p section) 'region 'hunk))
+        (`(hunk   t   t nil) 'hunks)
+        (`(hunk  ,_  ,_  ,_) 'hunk)
+        (`(file   t   t nil) 'files)
+        (`(file  ,_  ,_  ,_) 'file)
+        (`(,(or `staged `unstaged `untracked)
+           nil ,_ ,_) 'list)))))
+
+(defun magit-diff-use-hunk-region-p ()
+  (and (region-active-p)
+       (not (and (if (version< emacs-version "25.1")
+                     (eq this-command 'mouse-drag-region)
+                   ;; TODO implement this from first principals
+                   ;; currently it's trial-and-error
+                   (or (eq this-command 'mouse-drag-region)
+                       (eq last-command 'mouse-drag-region)
+                       ;; When another window was previously
+                       ;; selected then the last-command is
+                       ;; some byte-code function.
+                       (byte-code-function-p last-command)))
+                 (eq (region-end) (region-beginning))))))
+
+;;; Diff Highlight
+
+(defun magit-diff-unhighlight (section selection)
+  "Remove the highlighting of the diff-related SECTION."
+  (when (magit-hunk-section-p section)
+    (magit-diff-paint-hunk section selection nil)
+    t))
+
+(defun magit-diff-highlight (section selection)
+  "Highlight the diff-related SECTION.
+If SECTION is not a diff-related section, then do nothing and
+return nil.  If SELECTION is non-nil, then it is a list of sections
+selected by the region, including SECTION.  All of these sections
+are highlighted."
+  (if (and (magit-section-match 'commit section)
+           (oref section children))
+      (progn (if selection
+                 (dolist (section selection)
+                   (magit-diff-highlight-list section selection))
+               (magit-diff-highlight-list section))
+             t)
+    (when-let ((scope (magit-diff-scope section t)))
+      (cond ((eq scope 'region)
+             (magit-diff-paint-hunk section selection t))
+            (selection
+             (dolist (section selection)
+               (magit-diff-highlight-recursive section selection)))
+            (t
+             (magit-diff-highlight-recursive section)))
+      t)))
+
+(defun magit-diff-highlight-recursive (section &optional selection)
+  (pcase (magit-diff-scope section)
+    (`list (magit-diff-highlight-list section selection))
+    (`file (magit-diff-highlight-file section selection))
+    (`hunk (magit-diff-highlight-heading section selection)
+           (magit-diff-paint-hunk section selection t))
+    (_     (magit-section-highlight section nil))))
+
+(defun magit-diff-highlight-list (section &optional selection)
+  (let ((beg (oref section start))
+        (cnt (oref section content))
+        (end (oref section end)))
+    (when (or (eq this-command 'mouse-drag-region)
+              (not selection))
+      (unless (and (region-active-p)
+                   (<= (region-beginning) beg))
+        (magit-section-make-overlay beg cnt 'magit-section-highlight))
+      (unless (oref section hidden)
+        (dolist (child (oref section children))
+          (when (or (eq this-command 'mouse-drag-region)
+                    (not (and (region-active-p)
+                              (<= (region-beginning)
+                                  (oref child start)))))
+            (magit-diff-highlight-recursive child selection)))))
+    (when magit-diff-highlight-hunk-body
+      (magit-section-make-overlay (1- end) end 'magit-section-highlight))))
+
+(defun magit-diff-highlight-file (section &optional selection)
+  (magit-diff-highlight-heading section selection)
+  (unless (oref section hidden)
+    (dolist (child (oref section children))
+      (magit-diff-highlight-recursive child selection))))
+
+(defun magit-diff-highlight-heading (section &optional selection)
+  (magit-section-make-overlay
+   (oref section start)
+   (or (oref section content)
+       (oref section end))
+   (pcase (list (oref section type)
+                (and (member section selection)
+                     (not (eq this-command 'mouse-drag-region))))
+     (`(file   t) 'magit-diff-file-heading-selection)
+     (`(file nil) 'magit-diff-file-heading-highlight)
+     (`(hunk   t) 'magit-diff-hunk-heading-selection)
+     (`(hunk nil) 'magit-diff-hunk-heading-highlight))))
+
+;;; Hunk Paint
+
+(cl-defun magit-diff-paint-hunk
+    (section &optional selection
+             (highlight (magit-section-selected-p section selection)))
+  (let (paint)
+    (unless magit-diff-highlight-hunk-body
+      (setq highlight nil))
+    (cond (highlight
+           (unless (oref section hidden)
+             (add-to-list 'magit-section-highlighted-sections section)
+             (cond ((memq section magit-section-unhighlight-sections)
+                    (setq magit-section-unhighlight-sections
+                          (delq section magit-section-unhighlight-sections)))
+                   (magit-diff-highlight-hunk-body
+                    (setq paint t)))))
+          (t
+           (cond ((and (oref section hidden)
+                       (memq section magit-section-unhighlight-sections))
+                  (add-to-list 'magit-section-highlighted-sections section)
+                  (setq magit-section-unhighlight-sections
+                        (delq section magit-section-unhighlight-sections)))
+                 (t
+                  (setq paint t)))))
+    (when paint
+      (save-excursion
+        (goto-char (oref section start))
+        (let ((end (oref section end))
+              (merging (looking-at "@@@"))
+              (stage nil)
+              (tab-width (magit-diff-tab-width
+                          (magit-section-parent-value section))))
+          (forward-line)
+          (while (< (point) end)
+            (when (and magit-diff-hide-trailing-cr-characters
+                       (char-equal ?\r (char-before (line-end-position))))
+              (put-text-property (1- (line-end-position)) (line-end-position)
+                                 'invisible t))
+            (put-text-property
+             (point) (1+ (line-end-position)) 'face
+             (cond
+              ((looking-at "^\\+\\+?\\([<=|>]\\)\\{7\\}")
+               (setq stage (pcase (list (match-string 1) highlight)
+                             (`("<" nil) 'magit-diff-our)
+                             (`("<"   t) 'magit-diff-our-highlight)
+                             (`("|" nil) 'magit-diff-base)
+                             (`("|"   t) 'magit-diff-base-highlight)
+                             (`("=" nil) 'magit-diff-their)
+                             (`("="   t) 'magit-diff-their-highlight)
+                             (`(">" nil) nil)))
+               'magit-diff-conflict-heading)
+              ((looking-at (if merging "^\\(\\+\\| \\+\\)" "^\\+"))
+               (magit-diff-paint-tab merging tab-width)
+               (magit-diff-paint-whitespace merging)
+               (or stage
+                   (if highlight 'magit-diff-added-highlight 'magit-diff-added)))
+              ((looking-at (if merging "^\\(-\\| -\\)" "^-"))
+               (magit-diff-paint-tab merging tab-width)
+               (if highlight 'magit-diff-removed-highlight 'magit-diff-removed))
+              (t
+               (magit-diff-paint-tab merging tab-width)
+               (if highlight 'magit-diff-context-highlight 'magit-diff-context))))
+            (forward-line))))))
+  (magit-diff-update-hunk-refinement section))
+
+(defvar magit-diff--tab-width-cache nil)
+
+(defun magit-diff-tab-width (file)
+  (setq file (expand-file-name file))
+  (cl-flet ((cache (value)
+                   (let ((elt (assoc file magit-diff--tab-width-cache)))
+                     (if elt
+                         (setcdr elt value)
+                       (setq magit-diff--tab-width-cache
+                             (cons (cons file value)
+                                   magit-diff--tab-width-cache))))
+                   value))
+    (cond
+     ((not magit-diff-adjust-tab-width)
+      tab-width)
+     ((--when-let (find-buffer-visiting file)
+        (cache (buffer-local-value 'tab-width it))))
+     ((--when-let (assoc file magit-diff--tab-width-cache)
+        (or (cdr it)
+            tab-width)))
+     ((or (eq magit-diff-adjust-tab-width 'always)
+          (and (numberp magit-diff-adjust-tab-width)
+               (>= magit-diff-adjust-tab-width
+                   (nth 7 (file-attributes file)))))
+      (cache (buffer-local-value 'tab-width (find-file-noselect file))))
+     (t
+      (cache nil)
+      tab-width))))
+
+(defun magit-diff-paint-tab (merging width)
+  (save-excursion
+    (forward-char (if merging 2 1))
+    (while (= (char-after) ?\t)
+      (put-text-property (point) (1+ (point))
+                         'display (list (list 'space :width width)))
+      (forward-char))))
+
+(defun magit-diff-paint-whitespace (merging)
+  (when (and magit-diff-paint-whitespace
+             (or (derived-mode-p 'magit-status-mode)
+                 (not (eq magit-diff-paint-whitespace 'status))))
+    (let ((prefix (if merging "^[-\\+\s]\\{2\\}" "^[-\\+]"))
+          (indent
+           (if (local-variable-p 'magit-diff-highlight-indentation)
+               magit-diff-highlight-indentation
+             (setq-local
+              magit-diff-highlight-indentation
+              (cdr (--first (string-match-p (car it) default-directory)
+                            (nreverse
+                             (default-value
+                               'magit-diff-highlight-indentation))))))))
+      (when (and magit-diff-highlight-trailing
+                 (looking-at (concat prefix ".*?\\([ \t]+\\)$")))
+        (let ((ov (make-overlay (match-beginning 1) (match-end 1) nil t)))
+          (overlay-put ov 'face 'magit-diff-whitespace-warning)
+          (overlay-put ov 'evaporate t)))
+      (when (or (and (eq indent 'tabs)
+                     (looking-at (concat prefix "\\( *\t[ \t]*\\)")))
+                (and (integerp indent)
+                     (looking-at (format "%s\\([ \t]* \\{%s,\\}[ \t]*\\)"
+                                         prefix indent))))
+        (let ((ov (make-overlay (match-beginning 1) (match-end 1) nil t)))
+          (overlay-put ov 'face 'magit-diff-whitespace-warning)
+          (overlay-put ov 'evaporate t))))))
+
+(defun magit-diff-update-hunk-refinement (&optional section)
+  (if section
+      (unless (oref section hidden)
+        (pcase (list magit-diff-refine-hunk
+                     (oref section refined)
+                     (eq section (magit-current-section)))
+          ((or `(all nil ,_) `(t nil t))
+           (oset section refined t)
+           (save-excursion
+             (goto-char (oref section start))
+             ;; `diff-refine-hunk' does not handle combined diffs.
+             (unless (looking-at "@@@")
+               ;; Avoid fsyncing many small temp files
+               (let ((write-region-inhibit-fsync t))
+                 (diff-refine-hunk)))))
+          ((or `(nil t ,_) `(t t nil))
+           (oset section refined nil)
+           (remove-overlays (oref section start)
+                            (oref section end)
+                            'diff-mode 'fine))))
+    (cl-labels ((recurse (section)
+                         (if (magit-section-match 'hunk section)
+                             (magit-diff-update-hunk-refinement section)
+                           (dolist (child (oref section children))
+                             (recurse child)))))
+      (recurse magit-root-section))))
+
+
+;;; Hunk Region
+
+(defun magit-diff-hunk-region-beginning ()
+  (save-excursion (goto-char (region-beginning))
+                  (line-beginning-position)))
+
+(defun magit-diff-hunk-region-end ()
+  (save-excursion (goto-char (region-end))
+                  (line-end-position)))
+
+(defun magit-diff-update-hunk-region (section)
+  "Highlight the hunk-internal region if any."
+  (when (eq (magit-diff-scope section t) 'region)
+    (magit-diff--make-hunk-overlay
+     (oref section start)
+     (1- (oref section content))
+     'face 'magit-diff-lines-heading
+     'display (magit-diff-hunk-region-header section)
+     'after-string (magit-diff--hunk-after-string 'magit-diff-lines-heading))
+    (run-hook-with-args 'magit-diff-highlight-hunk-region-functions section)
+    t))
+
+(defun magit-diff-highlight-hunk-region-dim-outside (section)
+  "Dim the parts of the hunk that are outside the hunk-internal region.
+This is done by using the same foreground and background color
+for added and removed lines as for context lines."
+  (let ((face (if magit-diff-highlight-hunk-body
+                  'magit-diff-context-highlight
+                'magit-diff-context)))
+    (when magit-diff-unmarked-lines-keep-foreground
+      (setq face (list :background (face-attribute face :background))))
+    (magit-diff--make-hunk-overlay (oref section content)
+                                   (magit-diff-hunk-region-beginning)
+                                   'face face
+                                   'priority 2)
+    (magit-diff--make-hunk-overlay (1+ (magit-diff-hunk-region-end))
+                                   (oref section end)
+                                   'face face
+                                   'priority 2)))
+
+(defun magit-diff-highlight-hunk-region-using-face (_section)
+  "Highlight the hunk-internal region by making it bold.
+Or rather highlight using the face `magit-diff-hunk-region', though
+changing only the `:weight' and/or `:slant' is recommended for that
+face."
+  (magit-diff--make-hunk-overlay (magit-diff-hunk-region-beginning)
+                                 (1+ (magit-diff-hunk-region-end))
+                                 'face 'magit-diff-hunk-region))
+
+(defun magit-diff-highlight-hunk-region-using-overlays (section)
+  "Emphasize the hunk-internal region using delimiting horizontal lines.
+This is implemented as single-pixel newlines places inside overlays."
+  (if (window-system)
+      (let ((beg (magit-diff-hunk-region-beginning))
+            (end (magit-diff-hunk-region-end))
+            (str (propertize
+                  (concat (propertize "\s" 'display '(space :height (1)))
+                          (propertize "\n" 'line-height t))
+                  'face 'magit-diff-lines-boundary)))
+        (magit-diff--make-hunk-overlay beg (1+ beg) 'before-string str)
+        (magit-diff--make-hunk-overlay end (1+ end) 'after-string  str))
+    (magit-diff-highlight-hunk-region-using-face section)))
+
+(defun magit-diff-highlight-hunk-region-using-underline (section)
+  "Emphasize the hunk-internal region using delimiting horizontal lines.
+This is implemented by overlining and underlining the first and
+last (visual) lines of the region."
+  (if (window-system)
+      (let* ((beg (magit-diff-hunk-region-beginning))
+             (end (magit-diff-hunk-region-end))
+             (beg-eol (save-excursion (goto-char beg)
+                                      (end-of-visual-line)
+                                      (point)))
+             (end-bol (save-excursion (goto-char end)
+                                      (beginning-of-visual-line)
+                                      (point)))
+             (color (face-background 'magit-diff-lines-boundary nil t)))
+        (cl-flet ((ln (b e &rest face)
+                      (magit-diff--make-hunk-overlay
+                       b e 'face face 'after-string
+                       (magit-diff--hunk-after-string face))))
+          (if (= beg end-bol)
+              (ln beg beg-eol :overline color :underline color)
+            (ln beg beg-eol :overline color)
+            (ln end-bol end :underline color))))
+    (magit-diff-highlight-hunk-region-using-face section)))
+
+(defun magit-diff--make-hunk-overlay (start end &rest args)
+  (let ((ov (make-overlay start end nil t)))
+    (overlay-put ov 'evaporate t)
+    (while args (overlay-put ov (pop args) (pop args)))
+    (push ov magit-region-overlays)
+    ov))
+
+(defun magit-diff--hunk-after-string (face)
+  (propertize "\s"
+              'face face
+              'display (list 'space :align-to
+                             `(+ (0 . right)
+                                 ,(min (window-hscroll)
+                                       (- (line-end-position)
+                                          (line-beginning-position)))))
+              ;; This prevents the cursor from being rendered at the
+              ;; edge of the window.
+              'cursor t))
+
+;;; Hunk Utilities
+
+(defun magit-diff-inside-hunk-body-p ()
+  "Return non-nil if point is inside the body of a hunk."
+  (and (magit-section-match 'hunk)
+       (> (point)
+          (oref (magit-current-section) content))))
+
+;;; Diff Extract
+
+(defun magit-diff-file-header (section)
+  (when (magit-hunk-section-p section)
+    (setq section (oref section parent)))
+  (when (magit-file-section-p section)
+    (oref section header)))
+
+(defun magit-diff-hunk-region-header (section)
+  (let ((patch (magit-diff-hunk-region-patch section)))
+    (string-match "\n" patch)
+    (substring patch 0 (1- (match-end 0)))))
+
+(defun magit-diff-hunk-region-patch (section &optional args)
+  (let ((op (if (member "--reverse" args) "+" "-"))
+        (sbeg (oref section start))
+        (rbeg (magit-diff-hunk-region-beginning))
+        (rend (region-end))
+        (send (oref section end))
+        (patch nil))
+    (save-excursion
+      (goto-char sbeg)
+      (while (< (point) send)
+        (looking-at "\\(.\\)\\([^\n]*\n\\)")
+        (cond ((or (string-match-p "[@ ]" (match-string-no-properties 1))
+                   (and (>= (point) rbeg)
+                        (<= (point) rend)))
+               (push (match-string-no-properties 0) patch))
+              ((equal op (match-string-no-properties 1))
+               (push (concat " " (match-string-no-properties 2)) patch)))
+        (forward-line)))
+    (with-temp-buffer
+      (insert (mapconcat 'identity (reverse patch) ""))
+      (diff-fixup-modifs (point-min) (point-max))
+      (setq patch (buffer-string)))
+    patch))
+
+(provide 'magit-diff)
+;;; magit-diff.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-diff.elc b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-diff.elc
new file mode 100644
index 0000000000..468726be98
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-diff.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-ediff.el b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-ediff.el
new file mode 100644
index 0000000000..7e0716beef
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-ediff.el
@@ -0,0 +1,509 @@
+;;; magit-ediff.el --- Ediff extension for Magit  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2010-2018  The Magit Project Contributors
+;;
+;; You should have received a copy of the AUTHORS.md file which
+;; lists all contributors.  If not, see http://magit.vc/authors.
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; Magit 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, or (at your option)
+;; any later version.
+;;
+;; Magit 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 Magit.  If not, see http://www.gnu.org/licenses.
+
+;;; Commentary:
+
+;; This library provides basic support for Ediff.
+
+;;; Code:
+
+(require 'magit)
+
+(require 'ediff)
+(require 'smerge-mode)
+
+(defvar smerge-ediff-buf)
+(defvar smerge-ediff-windows)
+
+;;; Options
+
+(defgroup magit-ediff nil
+  "Ediff support for Magit."
+  :link '(info-link "(magit)Ediffing")
+  :group 'magit-extensions)
+
+(defcustom magit-ediff-quit-hook
+  '(magit-ediff-cleanup-auxiliary-buffers
+    magit-ediff-restore-previous-winconf)
+  "Hooks to run after finishing Ediff, when that was invoked using Magit.
+The hooks are run in the Ediff control buffer.  This is similar
+to `ediff-quit-hook' but takes the needs of Magit into account.
+The `ediff-quit-hook' is ignored by Ediff sessions which were
+invoked using Magit."
+  :package-version '(magit . "2.2.0")
+  :group 'magit-ediff
+  :type 'hook
+  :get 'magit-hook-custom-get
+  :options '(magit-ediff-cleanup-auxiliary-buffers
+             magit-ediff-restore-previous-winconf))
+
+(defcustom magit-ediff-dwim-show-on-hunks nil
+  "Whether `magit-ediff-dwim' runs show variants on hunks.
+If non-nil, `magit-ediff-show-staged' or
+`magit-ediff-show-unstaged' are called based on what section the
+hunk is in.  Otherwise, `magit-ediff-dwim' runs
+`magit-ediff-stage' when point is on an uncommitted hunk."
+  :package-version '(magit . "2.2.0")
+  :group 'magit-ediff
+  :type 'boolean)
+
+(defcustom magit-ediff-show-stash-with-index t
+  "Whether `magit-ediff-show-stash' shows the state of the index.
+
+If non-nil, use a third Ediff buffer to distinguish which changes
+in the stash were staged.  In cases where the stash contains no
+staged changes, fall back to a two-buffer Ediff.
+
+More specifically, a stash is a merge commit, stash@{N}, with
+potentially three parents.
+
+* stash@{N}^1 represents the `HEAD' commit at the time the stash
+  was created.
+
+* stash@{N}^2 records any changes that were staged when the stash
+  was made.
+
+* stash@{N}^3, if it exists, contains files that were untracked
+  when stashing.
+
+If this option is non-nil, `magit-ediff-show-stash' will run
+Ediff on a file using three buffers: one for stash@{N}, another
+for stash@{N}^1, and a third for stash@{N}^2.
+
+Otherwise, Ediff uses two buffers, comparing
+stash@{N}^1..stash@{N}.  Along with any unstaged changes, changes
+in the index commit, stash@{N}^2, will be shown in this
+comparison unless they conflicted with changes in the working
+tree at the time of stashing."
+  :package-version '(magit . "2.6.0")
+  :group 'magit-ediff
+  :type 'boolean)
+
+;;; Commands
+
+(defvar magit-ediff-previous-winconf nil)
+
+;;;###autoload (autoload 'magit-ediff-popup "magit-ediff" nil t)
+(magit-define-popup magit-ediff-popup
+  "Popup console for ediff commands."
+  :actions '((?E "Dwim"          magit-ediff-dwim)
+             (?u "Show unstaged" magit-ediff-show-unstaged)
+             (?s "Stage"         magit-ediff-stage)
+             (?i "Show staged"   magit-ediff-show-staged)
+             (?m "Resolve"       magit-ediff-resolve)
+             (?w "Show worktree" magit-ediff-show-working-tree)
+             (?r "Diff range"    magit-ediff-compare)
+             (?c "Show commit"   magit-ediff-show-commit) nil
+             (?z "Show stash"    magit-ediff-show-stash))
+  :max-action-columns 2)
+
+;;;###autoload
+(defun magit-ediff-resolve (file)
+  "Resolve outstanding conflicts in FILE using Ediff.
+FILE has to be relative to the top directory of the repository.
+
+In the rare event that you want to manually resolve all
+conflicts, including those already resolved by Git, use
+`ediff-merge-revisions-with-ancestor'."
+  (interactive
+   (let ((current  (magit-current-file))
+         (unmerged (magit-unmerged-files)))
+     (unless unmerged
+       (user-error "There are no unresolved conflicts"))
+     (list (magit-completing-read "Resolve file" unmerged nil t nil nil
+                                  (car (member current unmerged))))))
+  (magit-with-toplevel
+    (with-current-buffer (find-file-noselect file)
+      (smerge-ediff)
+      (setq-local
+       ediff-quit-hook
+       (lambda ()
+         (let ((bufC ediff-buffer-C)
+               (bufS smerge-ediff-buf))
+           (with-current-buffer bufS
+             (when (yes-or-no-p (format "Conflict resolution finished; save %s? "
+                                        buffer-file-name))
+               (erase-buffer)
+               (insert-buffer-substring bufC)
+               (save-buffer))))
+         (when (buffer-live-p ediff-buffer-A) (kill-buffer ediff-buffer-A))
+         (when (buffer-live-p ediff-buffer-B) (kill-buffer ediff-buffer-B))
+         (when (buffer-live-p ediff-buffer-C) (kill-buffer ediff-buffer-C))
+         (when (buffer-live-p ediff-ancestor-buffer)
+           (kill-buffer ediff-ancestor-buffer))
+         (let ((magit-ediff-previous-winconf smerge-ediff-windows))
+           (run-hooks 'magit-ediff-quit-hook)))))))
+
+;;;###autoload
+(defun magit-ediff-stage (file)
+  "Stage and unstage changes to FILE using Ediff.
+FILE has to be relative to the top directory of the repository."
+  (interactive
+   (list (magit-completing-read "Selectively stage file"
+                                (magit-tracked-files) nil nil nil nil
+                                (magit-current-file))))
+  (magit-with-toplevel
+    (let* ((conf (current-window-configuration))
+           (bufA (magit-get-revision-buffer "HEAD" file))
+           (bufB (get-buffer (concat file ".~{index}~")))
+           (bufBrw (and bufB (with-current-buffer bufB (not buffer-read-only))))
+           (bufC (get-file-buffer file))
+           (fileBufC (or bufC (find-file-noselect file)))
+           (coding-system-for-read
+            (with-current-buffer fileBufC buffer-file-coding-system)))
+      (ediff-buffers3
+       (or bufA (magit-find-file-noselect "HEAD" file))
+       (with-current-buffer (magit-find-file-index-noselect file t)
+         (setq buffer-read-only nil)
+         (current-buffer))
+       fileBufC
+       `((lambda ()
+           (setq-local
+            ediff-quit-hook
+            (lambda ()
+              (and (buffer-live-p ediff-buffer-B)
+                   (buffer-modified-p ediff-buffer-B)
+                   (with-current-buffer ediff-buffer-B
+                     (magit-update-index)))
+              (and (buffer-live-p ediff-buffer-C)
+                   (buffer-modified-p ediff-buffer-C)
+                   (with-current-buffer ediff-buffer-C
+                     (when (y-or-n-p
+                            (format "Save file %s? " buffer-file-name))
+                       (save-buffer))))
+              ,@(unless bufA '((ediff-kill-buffer-carefully ediff-buffer-A)))
+              ,@(if bufB
+                    (unless bufBrw '((with-current-buffer ediff-buffer-B
+                                       (setq buffer-read-only t))))
+                  '((ediff-kill-buffer-carefully ediff-buffer-B)))
+              ,@(unless bufC '((ediff-kill-buffer-carefully ediff-buffer-C)))
+              (let ((magit-ediff-previous-winconf ,conf))
+                (run-hooks 'magit-ediff-quit-hook))))))
+       'ediff-buffers3))))
+
+;;;###autoload
+(defun magit-ediff-compare (revA revB fileA fileB)
+  "Compare REVA:FILEA with REVB:FILEB using Ediff.
+
+FILEA and FILEB have to be relative to the top directory of the
+repository.  If REVA or REVB is nil, then this stands for the
+working tree state.
+
+If the region is active, use the revisions on the first and last
+line of the region.  With a prefix argument, instead of diffing
+the revisions, choose a revision to view changes along, starting
+at the common ancestor of both revisions (i.e., use a \"...\"
+range)."
+  (interactive
+   (pcase-let ((`(,revA ,revB) (magit-ediff-compare--read-revisions
+                                nil current-prefix-arg)))
+     (nconc (list revA revB)
+            (magit-ediff-read-files revA revB))))
+  (magit-with-toplevel
+    (let ((conf (current-window-configuration))
+          (bufA (if revA
+                    (magit-get-revision-buffer revA fileA)
+                  (get-file-buffer fileA)))
+          (bufB (if revB
+                    (magit-get-revision-buffer revB fileB)
+                  (get-file-buffer fileB))))
+      (ediff-buffers
+       (or bufA (if revA
+                    (magit-find-file-noselect revA fileA)
+                  (find-file-noselect fileA)))
+       (or bufB (if revB
+                    (magit-find-file-noselect revB fileB)
+                  (find-file-noselect fileB)))
+       `((lambda ()
+           (setq-local
+            ediff-quit-hook
+            (lambda ()
+              ,@(unless bufA '((ediff-kill-buffer-carefully ediff-buffer-A)))
+              ,@(unless bufB '((ediff-kill-buffer-carefully ediff-buffer-B)))
+              (let ((magit-ediff-previous-winconf ,conf))
+                (run-hooks 'magit-ediff-quit-hook))))))
+       'ediff-revision))))
+
+(defun magit-ediff-compare--read-revisions (&optional arg mbase)
+  (let ((input (or arg (magit-diff-read-range-or-commit
+                        "Compare range or commit"
+                        nil mbase))))
+    (--if-let (magit-split-range input)
+        (-cons-to-list it)
+      (list input nil))))
+
+(defun magit-ediff-read-files (revA revB &optional fileB)
+  "Read file in REVB, return it and the corresponding file in REVA.
+When FILEB is non-nil, use this as REVB's file instead of
+prompting for it."
+  (unless fileB
+    (setq fileB (magit-read-file-choice
+                 (format "File to compare between %s and %s"
+                         revA (or revB "the working tree"))
+                 (magit-changed-files revA revB)
+                 (format "No changed files between %s and %s"
+                         revA (or revB "the working tree")))))
+  (list (or (car (member fileB (magit-revision-files revA)))
+            (cdr (assoc fileB (magit-renamed-files revB revA)))
+            (magit-read-file-choice
+             (format "File in %s to compare with %s in %s"
+                     revA fileB (or revB "the working tree"))
+             (magit-changed-files revB revA)
+             (format "No files have changed between %s and %s"
+                     revA revB)))
+        fileB))
+
+;;;###autoload
+(defun magit-ediff-dwim ()
+  "Compare, stage, or resolve using Ediff.
+This command tries to guess what file, and what commit or range
+the user wants to compare, stage, or resolve using Ediff.  It
+might only be able to guess either the file, or range or commit,
+in which case the user is asked about the other.  It might not
+always guess right, in which case the appropriate `magit-ediff-*'
+command has to be used explicitly.  If it cannot read the user's
+mind at all, then it asks the user for a command to run."
+  (interactive)
+  (magit-section-case
+    (hunk (save-excursion
+            (goto-char (oref (oref it parent) start))
+            (magit-ediff-dwim)))
+    (t
+     (let ((range (magit-diff--dwim))
+           (file (magit-current-file))
+           command revA revB)
+       (pcase range
+         ((and (guard (not magit-ediff-dwim-show-on-hunks))
+               (or `unstaged `staged))
+          (setq command (if (magit-anything-unmerged-p)
+                            #'magit-ediff-resolve
+                          #'magit-ediff-stage)))
+         (`unstaged (setq command #'magit-ediff-show-unstaged))
+         (`staged (setq command #'magit-ediff-show-staged))
+         (`(commit . ,value)
+          (setq command #'magit-ediff-show-commit)
+          (setq revB value))
+         (`(stash . ,value)
+          (setq command #'magit-ediff-show-stash)
+          (setq revB value))
+         ((pred stringp)
+          (pcase-let ((`(,a ,b) (magit-ediff-compare--read-revisions range)))
+            (setq command #'magit-ediff-compare)
+            (setq revA a)
+            (setq revB b)))
+         (_
+          (when (derived-mode-p 'magit-diff-mode)
+            (pcase (magit-diff-type)
+              (`committed (pcase-let ((`(,a ,b)
+                                       (magit-ediff-compare--read-revisions
+                                        (car magit-refresh-args))))
+                            (setq revA a)
+                            (setq revB b)))
+              ((guard (not magit-ediff-dwim-show-on-hunks))
+               (setq command #'magit-ediff-stage))
+              (`unstaged  (setq command #'magit-ediff-show-unstaged))
+              (`staged    (setq command #'magit-ediff-show-staged))
+              (`undefined (setq command nil))
+              (_          (setq command nil))))))
+       (cond ((not command)
+              (call-interactively
+               (magit-read-char-case
+                   "Failed to read your mind; do you want to " t
+                 (?c "[c]ommit"  'magit-ediff-show-commit)
+                 (?r "[r]ange"   'magit-ediff-compare)
+                 (?s "[s]tage"   'magit-ediff-stage)
+                 (?v "resol[v]e" 'magit-ediff-resolve))))
+             ((eq command 'magit-ediff-compare)
+              (apply 'magit-ediff-compare revA revB
+                     (magit-ediff-read-files revA revB file)))
+             ((eq command 'magit-ediff-show-commit)
+              (magit-ediff-show-commit revB))
+             ((eq command 'magit-ediff-show-stash)
+              (magit-ediff-show-stash revB))
+             (file
+              (funcall command file))
+             (t
+              (call-interactively command)))))))
+
+;;;###autoload
+(defun magit-ediff-show-staged (file)
+  "Show staged changes using Ediff.
+
+This only allows looking at the changes; to stage, unstage,
+and discard changes using Ediff, use `magit-ediff-stage'.
+
+FILE must be relative to the top directory of the repository."
+  (interactive
+   (list (magit-read-file-choice "Show staged changes for file"
+                                 (magit-staged-files)
+                                 "No staged files")))
+  (let ((conf (current-window-configuration))
+        (bufA (magit-get-revision-buffer "HEAD" file))
+        (bufB (get-buffer (concat file ".~{index}~"))))
+    (ediff-buffers
+     (or bufA (magit-find-file-noselect "HEAD" file))
+     (or bufB (magit-find-file-index-noselect file t))
+     `((lambda ()
+         (setq-local
+          ediff-quit-hook
+          (lambda ()
+            ,@(unless bufA '((ediff-kill-buffer-carefully ediff-buffer-A)))
+            ,@(unless bufB '((ediff-kill-buffer-carefully ediff-buffer-B)))
+            (let ((magit-ediff-previous-winconf ,conf))
+              (run-hooks 'magit-ediff-quit-hook))))))
+     'ediff-buffers)))
+
+;;;###autoload
+(defun magit-ediff-show-unstaged (file)
+  "Show unstaged changes using Ediff.
+
+This only allows looking at the changes; to stage, unstage,
+and discard changes using Ediff, use `magit-ediff-stage'.
+
+FILE must be relative to the top directory of the repository."
+  (interactive
+   (list (magit-read-file-choice "Show unstaged changes for file"
+                                 (magit-unstaged-files)
+                                 "No unstaged files")))
+  (magit-with-toplevel
+    (let ((conf (current-window-configuration))
+          (bufA (get-buffer (concat file ".~{index}~")))
+          (bufB (get-file-buffer file)))
+      (ediff-buffers
+       (or bufA (magit-find-file-index-noselect file t))
+       (or bufB (find-file-noselect file))
+       `((lambda ()
+           (setq-local
+            ediff-quit-hook
+            (lambda ()
+              ,@(unless bufA '((ediff-kill-buffer-carefully ediff-buffer-A)))
+              ,@(unless bufB '((ediff-kill-buffer-carefully ediff-buffer-B)))
+              (let ((magit-ediff-previous-winconf ,conf))
+                (run-hooks 'magit-ediff-quit-hook))))))
+       'ediff-buffers))))
+
+;;;###autoload
+(defun magit-ediff-show-working-tree (file)
+  "Show changes between `HEAD' and working tree using Ediff.
+FILE must be relative to the top directory of the repository."
+  (interactive
+   (list (magit-read-file-choice "Show changes in file"
+                                 (magit-changed-files "HEAD")
+                                 "No changed files")))
+  (magit-with-toplevel
+    (let ((conf (current-window-configuration))
+          (bufA (magit-get-revision-buffer "HEAD" file))
+          (bufB (get-file-buffer file)))
+      (ediff-buffers
+       (or bufA (magit-find-file-noselect "HEAD" file))
+       (or bufB (find-file-noselect file))
+       `((lambda ()
+           (setq-local
+            ediff-quit-hook
+            (lambda ()
+              ,@(unless bufA '((ediff-kill-buffer-carefully ediff-buffer-A)))
+              ,@(unless bufB '((ediff-kill-buffer-carefully ediff-buffer-B)))
+              (let ((magit-ediff-previous-winconf ,conf))
+                (run-hooks 'magit-ediff-quit-hook))))))
+       'ediff-buffers))))
+
+;;;###autoload
+(defun magit-ediff-show-commit (commit)
+  "Show changes introduced by COMMIT using Ediff."
+  (interactive (list (magit-read-branch-or-commit "Revision")))
+  (let ((revA (concat commit "^"))
+        (revB commit))
+    (apply #'magit-ediff-compare
+           revA revB
+           (magit-ediff-read-files revA revB (magit-current-file)))))
+
+;;;###autoload
+(defun magit-ediff-show-stash (stash)
+  "Show changes introduced by STASH using Ediff.
+`magit-ediff-show-stash-with-index' controls whether a
+three-buffer Ediff is used in order to distinguish changes in the
+stash that were staged."
+  (interactive (list (magit-read-stash "Stash")))
+  (pcase-let* ((revA (concat stash "^1"))
+               (revB (concat stash "^2"))
+               (revC stash)
+               (`(,fileA ,fileC) (magit-ediff-read-files revA revC))
+               (fileB fileC))
+    (if (and magit-ediff-show-stash-with-index
+             (member fileA (magit-changed-files revB revA)))
+        (let ((conf (current-window-configuration))
+              (bufA (magit-get-revision-buffer revA fileA))
+              (bufB (magit-get-revision-buffer revB fileB))
+              (bufC (magit-get-revision-buffer revC fileC)))
+          (ediff-buffers3
+           (or bufA (magit-find-file-noselect revA fileA))
+           (or bufB (magit-find-file-noselect revB fileB))
+           (or bufC (magit-find-file-noselect revC fileC))
+           `((lambda ()
+               (setq-local
+                ediff-quit-hook
+                (lambda ()
+                  ,@(unless bufA
+                      '((ediff-kill-buffer-carefully ediff-buffer-A)))
+                  ,@(unless bufB
+                      '((ediff-kill-buffer-carefully ediff-buffer-B)))
+                  ,@(unless bufC
+                      '((ediff-kill-buffer-carefully ediff-buffer-C)))
+                  (let ((magit-ediff-previous-winconf ,conf))
+                    (run-hooks 'magit-ediff-quit-hook))))))
+           'ediff-buffers3))
+      (magit-ediff-compare revA revC fileA fileC))))
+
+(defun magit-ediff-cleanup-auxiliary-buffers ()
+  (let* ((ctl-buf ediff-control-buffer)
+         (ctl-win (ediff-get-visible-buffer-window ctl-buf))
+         (ctl-frm ediff-control-frame)
+         (main-frame (cond ((window-live-p ediff-window-A)
+                            (window-frame ediff-window-A))
+                           ((window-live-p ediff-window-B)
+                            (window-frame ediff-window-B)))))
+    (ediff-kill-buffer-carefully ediff-diff-buffer)
+    (ediff-kill-buffer-carefully ediff-custom-diff-buffer)
+    (ediff-kill-buffer-carefully ediff-fine-diff-buffer)
+    (ediff-kill-buffer-carefully ediff-tmp-buffer)
+    (ediff-kill-buffer-carefully ediff-error-buffer)
+    (ediff-kill-buffer-carefully ediff-msg-buffer)
+    (ediff-kill-buffer-carefully ediff-debug-buffer)
+    (when (boundp 'ediff-patch-diagnostics)
+      (ediff-kill-buffer-carefully ediff-patch-diagnostics))
+    (cond ((and (ediff-window-display-p)
+                (frame-live-p ctl-frm))
+           (delete-frame ctl-frm))
+          ((window-live-p ctl-win)
+           (delete-window ctl-win)))
+    (unless (ediff-multiframe-setup-p)
+      (ediff-kill-bottom-toolbar))
+    (ediff-kill-buffer-carefully ctl-buf)
+    (when (frame-live-p main-frame)
+      (select-frame main-frame))))
+
+(defun magit-ediff-restore-previous-winconf ()
+  (set-window-configuration magit-ediff-previous-winconf))
+
+(provide 'magit-ediff)
+;;; magit-ediff.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-ediff.elc b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-ediff.elc
new file mode 100644
index 0000000000..eba6373890
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-ediff.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-extras.el b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-extras.el
new file mode 100644
index 0000000000..344537b84f
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-extras.el
@@ -0,0 +1,700 @@
+;;; magit-extras.el --- additional functionality for Magit  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2008-2018  The Magit Project Contributors
+;;
+;; You should have received a copy of the AUTHORS.md file which
+;; lists all contributors.  If not, see http://magit.vc/authors.
+
+;; Magit 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, or (at your option)
+;; any later version.
+;;
+;; Magit 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 Magit.  If not, see http://www.gnu.org/licenses.
+
+;;; Commentary:
+
+;; Additional functionality for Magit.
+
+;;; Code:
+
+(require 'magit)
+
+(declare-function dired-read-shell-command "dired-aux" (prompt arg files))
+
+(defgroup magit-extras nil
+  "Additional functionality for Magit."
+  :group 'magit-extensions)
+
+;;; External Tools
+
+(defcustom magit-gitk-executable
+  (or (and (eq system-type 'windows-nt)
+           (let ((exe (magit-git-string
+                       "-c" "alias.X=!x() { which \"$1\" | cygpath -mf -; }; x"
+                       "X" "gitk.exe")))
+             (and exe (file-executable-p exe) exe)))
+      (executable-find "gitk") "gitk")
+  "The Gitk executable."
+  :group 'magit-extras
+  :set-after '(magit-git-executable)
+  :type 'string)
+
+;;;###autoload
+(defun magit-run-git-gui ()
+  "Run `git gui' for the current git repository."
+  (interactive)
+  (magit-with-toplevel
+    (magit-process-file magit-git-executable nil 0 nil "gui")))
+
+;;;###autoload
+(defun magit-run-git-gui-blame (commit filename &optional linenum)
+  "Run `git gui blame' on the given FILENAME and COMMIT.
+Interactively run it for the current file and the `HEAD', with a
+prefix or when the current file cannot be determined let the user
+choose.  When the current buffer is visiting FILENAME instruct
+blame to center around the line point is on."
+  (interactive
+   (let (revision filename)
+     (when (or current-prefix-arg
+               (not (setq revision "HEAD"
+                          filename (magit-file-relative-name nil 'tracked))))
+       (setq revision (magit-read-branch-or-commit "Blame from revision"))
+       (setq filename (magit-read-file-from-rev revision "Blame file")))
+     (list revision filename
+           (and (equal filename
+                       (ignore-errors
+                         (magit-file-relative-name buffer-file-name)))
+                (line-number-at-pos)))))
+  (magit-with-toplevel
+    (apply #'magit-process-file magit-git-executable nil 0 nil "gui" "blame"
+           `(,@(and linenum (list (format "--line=%d" linenum)))
+             ,commit
+             ,filename))))
+
+;;;###autoload
+(defun magit-run-gitk ()
+  "Run `gitk' in the current repository."
+  (interactive)
+  (magit-process-file magit-gitk-executable nil 0))
+
+;;;###autoload
+(defun magit-run-gitk-branches ()
+  "Run `gitk --branches' in the current repository."
+  (interactive)
+  (magit-process-file magit-gitk-executable nil 0 nil "--branches"))
+
+;;;###autoload
+(defun magit-run-gitk-all ()
+  "Run `gitk --all' in the current repository."
+  (interactive)
+  (magit-process-file magit-gitk-executable nil 0 nil "--all"))
+
+;;; Emacs Tools
+
+;;;###autoload
+(defun ido-enter-magit-status ()
+  "Drop into `magit-status' from file switching.
+
+To make this command available use something like:
+
+  (add-hook \\='ido-setup-hook
+            (lambda ()
+              (define-key ido-completion-map
+                (kbd \"C-x g\") \\='ido-enter-magit-status)))
+
+Starting with Emacs 25.1 the Ido keymaps are defined just once
+instead of every time Ido is invoked, so now you can modify it
+like pretty much every other keymap:
+
+  (define-key ido-common-completion-map
+    (kbd \"C-x g\") \\='ido-enter-magit-status)"
+  (interactive)
+  (with-no-warnings ; FIXME these are internal variables
+    (setq ido-exit 'fallback fallback 'magit-status))
+  (exit-minibuffer))
+
+;;;###autoload
+(defun magit-dired-jump (&optional other-window)
+  "Visit file at point using Dired.
+With a prefix argument, visit in another window.  If there
+is no file at point, then instead visit `default-directory'."
+  (interactive "P")
+  (dired-jump other-window
+              (when-let ((file (magit-file-at-point)))
+                (expand-file-name (if (file-directory-p file)
+                                      (file-name-as-directory file)
+                                    file)))))
+
+;;;###autoload
+(defun magit-dired-log (&optional follow)
+  "Show log for all marked files, or the current file."
+  (interactive "P")
+  (if-let ((topdir (magit-toplevel default-directory)))
+      (let ((args (car (magit-log-arguments)))
+            (files (dired-get-marked-files nil nil #'magit-file-tracked-p)))
+        (unless files
+          (user-error "No marked file is being tracked by Git"))
+        (when (and follow
+                   (not (member "--follow" args))
+                   (not (cdr files)))
+          (push "--follow" args))
+        (magit-mode-setup-internal
+         #'magit-log-mode
+         (list (list (or (magit-get-current-branch) "HEAD"))
+               args
+               (let ((default-directory topdir))
+                 (mapcar #'file-relative-name files)))
+         magit-log-buffer-file-locked))
+    (magit--not-inside-repository-error)))
+
+;;;###autoload
+(defun magit-do-async-shell-command (file)
+  "Open FILE with `dired-do-async-shell-command'.
+Interactively, open the file at point."
+  (interactive (list (or (magit-file-at-point)
+                         (completing-read "Act on file: "
+                                          (magit-list-files)))))
+  (require 'dired-aux)
+  (dired-do-async-shell-command
+   (dired-read-shell-command "& on %s: " current-prefix-arg (list file))
+   nil (list file)))
+
+;;; Shift Selection
+
+(defun magit--turn-on-shift-select-mode-p ()
+  (and shift-select-mode
+       this-command-keys-shift-translated
+       (not mark-active)
+       (not (eq (car-safe transient-mark-mode) 'only))))
+
+;;;###autoload
+(defun magit-previous-line (&optional arg try-vscroll)
+  "Like `previous-line' but with Magit-specific shift-selection.
+
+Magit's selection mechanism is based on the region but selects an
+area that is larger than the region.  This causes `previous-line'
+when invoked while holding the shift key to move up one line and
+thereby select two lines.  When invoked inside a hunk body this
+command does not move point on the first invocation and thereby
+it only selects a single line.  Which inconsistency you prefer
+is a matter of preference."
+  (declare (interactive-only
+            "use `forward-line' with negative argument instead."))
+  (interactive "p\np")
+  (unless arg (setq arg 1))
+  (let ((stay (or (magit-diff-inside-hunk-body-p)
+                  (magit-section-position-in-heading-p))))
+    (if (and stay (= arg 1) (magit--turn-on-shift-select-mode-p))
+        (push-mark nil nil t)
+      (with-no-warnings
+        (handle-shift-selection)
+        (previous-line (if stay (max (1- arg) 1) arg) try-vscroll)))))
+
+;;;###autoload
+(defun magit-next-line (&optional arg try-vscroll)
+  "Like `next-line' but with Magit-specific shift-selection.
+
+Magit's selection mechanism is based on the region but selects
+an area that is larger than the region.  This causes `next-line'
+when invoked while holding the shift key to move down one line
+and thereby select two lines.  When invoked inside a hunk body
+this command does not move point on the first invocation and
+thereby it only selects a single line.  Which inconsistency you
+prefer is a matter of preference."
+  (declare (interactive-only forward-line))
+  (interactive "p\np")
+  (unless arg (setq arg 1))
+  (let ((stay (or (magit-diff-inside-hunk-body-p)
+                  (magit-section-position-in-heading-p))))
+    (if (and stay (= arg 1) (magit--turn-on-shift-select-mode-p))
+        (push-mark nil nil t)
+      (with-no-warnings
+        (handle-shift-selection)
+        (next-line (if stay (max (1- arg) 1) arg) try-vscroll)))))
+
+;;; Clean
+
+;;;###autoload
+(defun magit-clean (&optional arg)
+  "Remove untracked files from the working tree.
+With a prefix argument also remove ignored files,
+with two prefix arguments remove ignored files only.
+\n(git clean -f -d [-x|-X])"
+  (interactive "p")
+  (when (yes-or-no-p (format "Remove %s files? "
+                             (pcase arg
+                               (1 "untracked")
+                               (4 "untracked and ignored")
+                               (_ "ignored"))))
+    (magit-wip-commit-before-change)
+    (magit-run-git "clean" "-f" "-d" (pcase arg (4 "-x") (16 "-X")))))
+
+(put 'magit-clean 'disabled t)
+
+;;; Gitignore
+
+;;;###autoload (autoload 'magit-ignore-popup "extras" nil t)
+(magit-define-popup magit-gitignore-popup
+  "Popup console for gitignore commands."
+  :man-page "gitignore"
+  :actions '((?l "ignore locally"  magit-gitignore-locally)
+             (?g "ignore globally" magit-gitignore))
+  :max-action-columns 1)
+
+;;;###autoload
+(defun magit-gitignore (file-or-pattern &optional local)
+  "Instruct Git to ignore FILE-OR-PATTERN.
+With a prefix argument only ignore locally."
+  (interactive (list (magit-gitignore-read-pattern current-prefix-arg)
+                     current-prefix-arg))
+  (let ((gitignore
+         (if local
+             (magit-git-dir (convert-standard-filename "info/exclude"))
+           (expand-file-name ".gitignore" (magit-toplevel)))))
+    (make-directory (file-name-directory gitignore) t)
+    (with-temp-buffer
+      (when (file-exists-p gitignore)
+        (insert-file-contents gitignore))
+      (goto-char (point-max))
+      (unless (bolp)
+        (insert "\n"))
+      (insert (replace-regexp-in-string "\\(\\\\*\\)" "\\1\\1" file-or-pattern))
+      (insert "\n")
+      (write-region nil nil gitignore))
+    (if local
+        (magit-refresh)
+      (magit-run-git "add" ".gitignore"))))
+
+;;;###autoload
+(defun magit-gitignore-locally (file-or-pattern)
+  "Instruct Git to locally ignore FILE-OR-PATTERN."
+  (interactive (list (magit-gitignore-read-pattern t)))
+  (magit-gitignore file-or-pattern t))
+
+(defun magit-gitignore-read-pattern (local)
+  (let* ((default (magit-current-file))
+         (choices
+          (delete-dups
+           (--mapcat
+            (cons (concat "/" it)
+                  (when-let ((ext (file-name-extension it)))
+                    (list (concat "/" (file-name-directory "foo") "*." ext)
+                          (concat "*." ext))))
+            (magit-untracked-files)))))
+    (when default
+      (setq default (concat "/" default))
+      (unless (member default choices)
+        (setq default (concat "*." (file-name-extension default)))
+        (unless (member default choices)
+          (setq default nil))))
+    (magit-completing-read (concat "File or pattern to ignore"
+                                   (and local " locally"))
+                           choices nil nil nil nil default)))
+
+;;; ChangeLog
+
+;;;###autoload
+(defun magit-add-change-log-entry (&optional whoami file-name other-window)
+  "Find change log file and add date entry and item for current change.
+This differs from `add-change-log-entry' (which see) in that
+it acts on the current hunk in a Magit buffer instead of on
+a position in a file-visiting buffer."
+  (interactive (list current-prefix-arg
+                     (prompt-for-change-log-name)))
+  (let (buf pos)
+    (save-window-excursion
+      (call-interactively #'magit-diff-visit-file)
+      (setq buf (current-buffer))
+      (setq pos (point)))
+    (save-excursion
+      (with-current-buffer buf
+        (goto-char pos)
+        (add-change-log-entry whoami file-name other-window)))))
+
+;;;###autoload
+(defun magit-add-change-log-entry-other-window (&optional whoami file-name)
+  "Find change log file in other window and add entry and item.
+This differs from `add-change-log-entry-other-window' (which see)
+in that it acts on the current hunk in a Magit buffer instead of
+on a position in a file-visiting buffer."
+  (interactive (and current-prefix-arg
+                    (list current-prefix-arg
+                          (prompt-for-change-log-name))))
+  (magit-add-change-log-entry whoami file-name t))
+
+;;; Edit Line Commit
+
+;;;###autoload
+(defun magit-edit-line-commit (&optional type)
+  "Edit the commit that added the current line.
+
+With a prefix argument edit the commit that removes the line,
+if any.  The commit is determined using `git blame' and made
+editable using `git rebase --interactive' if it is reachable
+from `HEAD', or by checking out the commit (or a branch that
+points at it) otherwise."
+  (interactive (list (and current-prefix-arg 'removal)))
+  (let* ((chunk (magit-current-blame-chunk (or type 'addition)))
+         (rev   (oref chunk orig-rev)))
+    (if (equal rev "0000000000000000000000000000000000000000")
+        (message "This line has not been committed yet")
+      (let ((rebase (magit-rev-ancestor-p rev "HEAD"))
+            (file   (expand-file-name (oref chunk orig-file)
+                                      (magit-toplevel))))
+        (if rebase
+            (let ((magit--rebase-published-symbol 'edit-published))
+              (magit-rebase-edit-commit rev (magit-rebase-arguments)))
+          (magit-checkout (or (magit-rev-branch rev) rev)))
+        (unless (and buffer-file-name
+                     (file-equal-p file buffer-file-name))
+          (let ((blame-type (and magit-blame-mode magit-blame-type)))
+            (if rebase
+                (set-process-sentinel
+                 magit-this-process
+                 (lambda (process event)
+                   (magit-sequencer-process-sentinel process event)
+                   (when (eq (process-status process) 'exit)
+                     (find-file file)
+                     (when blame-type
+                       (magit-blame--pre-blame-setup blame-type)
+                       (magit-blame--run)))))
+              (find-file file)
+              (when blame-type
+                (magit-blame--pre-blame-setup blame-type)
+                (magit-blame--run)))))))))
+
+(put 'magit-edit-line-commit 'disabled t)
+
+(defun magit-diff-edit-hunk-commit ()
+  "From a hunk, edit the respective commit and visit the file.
+
+First visit the file being modified by the hunk at the correct
+location using `magit-diff-visit-file'.  This actually visits a
+blob.  When point is on a diff header, not within an individual
+hunk, then this visits the blob the first hunk is about.
+
+Then invoke `magit-edit-line-commit', which uses an interactive
+rebase to make the commit editable, or if that is not possible
+because the commit is not reachable from `HEAD' by checking out
+that commit directly.  This also causes the actual worktree file
+to be visited.
+
+Neither the blob nor the file buffer are killed when finishing
+the rebase.  If that is undesirable, then it might be better to
+use `magit-rebase-edit-command' instead of this command."
+  (interactive)
+  (let ((magit-diff-visit-previous-blob nil))
+    (magit-diff-visit-file (--if-let (magit-file-at-point)
+                               (expand-file-name it)
+                             (user-error "No file at point"))
+                           nil 'switch-to-buffer))
+  (magit-edit-line-commit))
+
+(put 'magit-diff-edit-hunk-commit 'disabled t)
+
+;;; Reshelve
+
+;;;###autoload
+(defun magit-reshelve-since (rev)
+  "Change the author and committer dates of the commits since REV.
+
+Ask the user for the first reachable commit whose dates should
+be changed.  The read the new date for that commit.  The initial
+minibuffer input and the previous history element offer good
+values.  The next commit will be created one minute later and so
+on.
+
+This command is only intended for interactive use and should only
+be used on highly rearranged and unpublished history."
+  (interactive (list nil))
+  (cond
+   ((not rev)
+    (let ((backup (concat "refs/original/refs/heads/"
+                          (magit-get-current-branch))))
+      (when (and (magit-ref-p backup)
+                 (not (magit-y-or-n-p
+                       "Backup ref %s already exists.  Override? " backup)))
+        (user-error "Abort")))
+    (magit-log-select 'magit-reshelve-since
+      "Type %p on a commit to reshelve it and the commits above it,"))
+   (t
+    (cl-flet ((adjust (time offset)
+                      (format-time-string
+                       "%F %T %z"
+                       (+ (floor time)
+                          (* offset 60)
+                          (- (car (decode-time time)))))))
+      (let* ((start (concat rev "^"))
+             (range (concat start ".." (magit-get-current-branch)))
+             (time-rev (adjust (float-time (string-to-number
+                                            (magit-rev-format "%at" start)))
+                               1))
+             (time-now (adjust (float-time)
+                               (- (string-to-number
+                                   (magit-git-string "rev-list" "--count"
+                                                     range))))))
+        (push time-rev magit--reshelve-history)
+        (let ((date (floor
+                     (float-time
+                      (date-to-time
+                       (read-string "Date for first commit: "
+                                    time-now 'magit--reshelve-history))))))
+          (magit-with-toplevel
+            (magit-run-git-async
+             "filter-branch" "--force" "--env-filter"
+             (format "case $GIT_COMMIT in %s\nesac"
+                     (mapconcat (lambda (rev)
+                                  (prog1 (format "%s) \
+export GIT_AUTHOR_DATE=\"%s\"; \
+export GIT_COMMITTER_DATE=\"%s\";;" rev date date)
+                                    (cl-incf date 60)))
+                                (magit-git-lines "rev-list" "--reverse"
+                                                 range)
+                                " "))
+             range "--")
+            (set-process-sentinel
+             magit-this-process
+             (lambda (process event)
+               (when (memq (process-status process) '(exit signal))
+                 (if (> (process-exit-status process) 0)
+                     (magit-process-sentinel process event)
+                   (process-put process 'inhibit-refresh t)
+                   (magit-process-sentinel process event)
+                   (magit-run-git "update-ref" "-d"
+                                  (concat "refs/original/refs/heads/"
+                                          (magit-get-current-branch))))))))))))))
+
+;;; Revision Stack
+
+(defvar magit-revision-stack nil)
+
+(defcustom magit-pop-revision-stack-format
+  '("[%N: %h] " "%N: %H\n   %s\n" "\\[\\([0-9]+\\)[]:]")
+  "Control how `magit-pop-revision-stack' inserts a revision.
+
+The command `magit-pop-revision-stack' inserts a representation
+of the revision last pushed to the `magit-revision-stack' into
+the current buffer.  It inserts text at point and/or near the end
+of the buffer, and removes the consumed revision from the stack.
+
+The entries on the stack have the format (HASH TOPLEVEL) and this
+option has the format (POINT-FORMAT EOB-FORMAT INDEX-REGEXP), all
+of which may be nil or a string (though either one of EOB-FORMAT
+or POINT-FORMAT should be a string, and if INDEX-REGEXP is
+non-nil, then the two formats should be too).
+
+First INDEX-REGEXP is used to find the previously inserted entry,
+by searching backward from point.  The first submatch must match
+the index number.  That number is incremented by one, and becomes
+the index number of the entry to be inserted.  If you don't want
+to number the inserted revisions, then use nil for INDEX-REGEXP.
+
+If INDEX-REGEXP is non-nil, then both POINT-FORMAT and EOB-FORMAT
+should contain \"%N\", which is replaced with the number that was
+determined in the previous step.
+
+Both formats, if non-nil and after removing %N, are then expanded
+using `git show --format=FORMAT ...' inside TOPLEVEL.
+
+The expansion of POINT-FORMAT is inserted at point, and the
+expansion of EOB-FORMAT is inserted at the end of the buffer (if
+the buffer ends with a comment, then it is inserted right before
+that)."
+  :package-version '(magit . "2.3.0")
+  :group 'magit-commands
+  :type '(list (choice (string :tag "Insert at point format")
+                       (cons (string :tag "Insert at point format")
+                             (repeat (string :tag "Argument to git show")))
+                       (const :tag "Don't insert at point" nil))
+               (choice (string :tag "Insert at eob format")
+                       (cons (string :tag "Insert at eob format")
+                             (repeat (string :tag "Argument to git show")))
+                       (const :tag "Don't insert at eob" nil))
+               (choice (regexp :tag "Find index regexp")
+                       (const :tag "Don't number entries" nil))))
+
+(defun magit-pop-revision-stack (rev toplevel)
+  "Insert a representation of a revision into the current buffer.
+
+Pop a revision from the `magit-revision-stack' and insert it into
+the current buffer according to `magit-pop-revision-stack-format'.
+Revisions can be put on the stack using `magit-copy-section-value'
+and `magit-copy-buffer-revision'.
+
+If the stack is empty or with a prefix argument, instead read a
+revision in the minibuffer.  By using the minibuffer history this
+allows selecting an item which was popped earlier or to insert an
+arbitrary reference or revision without first pushing it onto the
+stack.
+
+When reading the revision from the minibuffer, then it might not
+be possible to guess the correct repository.  When this command
+is called inside a repository (e.g. while composing a commit
+message), then that repository is used.  Otherwise (e.g. while
+composing an email) then the repository recorded for the top
+element of the stack is used (even though we insert another
+revision).  If not called inside a repository and with an empty
+stack, or with two prefix arguments, then read the repository in
+the minibuffer too."
+  (interactive
+   (if (or current-prefix-arg (not magit-revision-stack))
+       (let ((default-directory
+               (or (and (not (= (prefix-numeric-value current-prefix-arg) 16))
+                        (or (magit-toplevel)
+                            (cadr (car magit-revision-stack))))
+                   (magit-read-repository))))
+         (list (magit-read-branch-or-commit "Insert revision")
+               default-directory))
+     (push (caar magit-revision-stack) magit-revision-history)
+     (pop magit-revision-stack)))
+  (if rev
+      (pcase-let ((`(,pnt-format ,eob-format ,idx-format)
+                   magit-pop-revision-stack-format))
+        (let ((default-directory toplevel)
+              (idx (and idx-format
+                        (save-excursion
+                          (if (re-search-backward idx-format nil t)
+                              (number-to-string
+                               (1+ (string-to-number (match-string 1))))
+                            "1"))))
+              pnt-args eob-args)
+          (when (listp pnt-format)
+            (setq pnt-args (cdr pnt-format))
+            (setq pnt-format (car pnt-format)))
+          (when (listp eob-format)
+            (setq eob-args (cdr eob-format))
+            (setq eob-format (car eob-format)))
+          (when pnt-format
+            (when idx-format
+              (setq pnt-format
+                    (replace-regexp-in-string "%N" idx pnt-format t t)))
+            (magit-rev-insert-format pnt-format rev pnt-args)
+            (backward-delete-char 1))
+          (when eob-format
+            (when idx-format
+              (setq eob-format
+                    (replace-regexp-in-string "%N" idx eob-format t t)))
+            (save-excursion
+              (goto-char (point-max))
+              (skip-syntax-backward ">s-")
+              (beginning-of-line)
+              (if (and comment-start (looking-at comment-start))
+                  (while (looking-at comment-start)
+                    (forward-line -1))
+                (forward-line)
+                (unless (= (current-column) 0)
+                  (insert ?\n)))
+              (insert ?\n)
+              (magit-rev-insert-format eob-format rev eob-args)
+              (backward-delete-char 1)))))
+    (user-error "Revision stack is empty")))
+
+(define-key git-commit-mode-map
+  (kbd "C-c C-w") 'magit-pop-revision-stack)
+
+;;;###autoload
+(defun magit-copy-section-value ()
+  "Save the value of the current section for later use.
+
+Save the section value to the `kill-ring', and, provided that
+the current section is a commit, branch, or tag section, push
+the (referenced) revision to the `magit-revision-stack' for use
+with `magit-pop-revision-stack'.
+
+When the current section is a branch or a tag, and a prefix
+argument is used, then save the revision at its tip to the
+`kill-ring' instead of the reference name.
+
+When the region is active, then save that to the `kill-ring',
+like `kill-ring-save' would, instead of behaving as described
+above."
+  (interactive)
+  (if (use-region-p)
+      (copy-region-as-kill nil nil 'region)
+    (when-let ((section (magit-current-section))
+               (value (oref section value)))
+      (magit-section-case
+        ((branch commit module-commit tag)
+         (let ((default-directory default-directory) ref)
+           (magit-section-case
+             ((branch tag)
+              (setq ref value))
+             (module-commit
+              (setq default-directory
+                    (file-name-as-directory
+                     (expand-file-name (magit-section-parent-value section)
+                                       (magit-toplevel))))))
+           (setq value (magit-rev-parse value))
+           (push (list value default-directory) magit-revision-stack)
+           (kill-new (message "%s" (or (and current-prefix-arg ref)
+                                       value)))))
+        (t (kill-new (message "%s" value)))))))
+
+;;;###autoload
+(defun magit-copy-buffer-revision ()
+  "Save the revision of the current buffer for later use.
+
+Save the revision shown in the current buffer to the `kill-ring'
+and push it to the `magit-revision-stack'.
+
+This command is mainly intended for use in `magit-revision-mode'
+buffers, the only buffers where it is always unambiguous exactly
+which revision should be saved.
+
+Most other Magit buffers usually show more than one revision, in
+some way or another, so this command has to select one of them,
+and that choice might not always be the one you think would have
+been the best pick.
+
+In such buffers it is often more useful to save the value of
+the current section instead, using `magit-copy-section-value'.
+
+When the region is active, then save that to the `kill-ring',
+like `kill-ring-save' would, instead of behaving as described
+above."
+  (interactive)
+  (if (use-region-p)
+      (copy-region-as-kill nil nil 'region)
+    (when-let ((rev (cond ((memq major-mode '(magit-cherry-mode
+                                              magit-log-select-mode
+                                              magit-reflog-mode
+                                              magit-refs-mode
+                                              magit-revision-mode
+                                              magit-stash-mode
+                                              magit-stashes-mode))
+                           (car magit-refresh-args))
+                          ((memq major-mode '(magit-diff-mode
+                                              magit-log-mode))
+                           (let ((r (caar magit-refresh-args)))
+                             (if (string-match "\\.\\.\\.?\\(.+\\)" r)
+                                 (match-string 1 r)
+                               r)))
+                          ((eq major-mode 'magit-status-mode) "HEAD"))))
+      (when (magit-rev-verify-commit rev)
+        (setq rev (magit-rev-parse rev))
+        (push (list rev default-directory) magit-revision-stack)
+        (kill-new (message "%s" rev))))))
+
+;;; Miscellaneous
+
+;;;###autoload
+(defun magit-abort-dwim ()
+  "Abort current operation.
+Depending on the context, this will abort a merge, a rebase, a
+patch application, a cherry-pick, a revert, or a bisect."
+  (interactive)
+  (cond ((magit-merge-in-progress-p)     (magit-merge-abort))
+        ((magit-rebase-in-progress-p)    (magit-rebase-abort))
+        ((magit-am-in-progress-p)        (magit-am-abort))
+        ((magit-sequencer-in-progress-p) (magit-sequencer-abort))
+        ((magit-bisect-in-progress-p)    (magit-bisect-reset))))
+
+(provide 'magit-extras)
+;;; magit-extras.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-extras.elc b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-extras.elc
new file mode 100644
index 0000000000..9312a2a5a5
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-extras.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-files.el b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-files.el
new file mode 100644
index 0000000000..b77791a94e
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-files.el
@@ -0,0 +1,562 @@
+;;; magit-files.el --- finding files  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2010-2018  The Magit Project Contributors
+;;
+;; You should have received a copy of the AUTHORS.md file which
+;; lists all contributors.  If not, see http://magit.vc/authors.
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; Magit 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, or (at your option)
+;; any later version.
+;;
+;; Magit 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 Magit.  If not, see http://www.gnu.org/licenses.
+
+;;; Commentary:
+
+;; This library implements support for finding blobs, staged files,
+;; and Git configuration files.  It also implements modes useful in
+;; buffers visiting files and blobs, and the commands used by those
+;; modes.
+
+;;; Code:
+
+(require 'magit)
+
+;;; Find Blob
+
+(defvar magit-find-file-hook nil)
+(add-hook 'magit-find-file-hook #'magit-blob-mode)
+
+;;;###autoload
+(defun magit-find-file (rev file)
+  "View FILE from REV.
+Switch to a buffer visiting blob REV:FILE,
+creating one if none already exists."
+  (interactive (magit-find-file-read-args "Find file"))
+  (switch-to-buffer (magit-find-file-noselect rev file)))
+
+;;;###autoload
+(defun magit-find-file-other-window (rev file)
+  "View FILE from REV, in another window.
+Like `magit-find-file', but create a new window or reuse an
+existing one."
+  (interactive (magit-find-file-read-args "Find file in other window"))
+  (switch-to-buffer-other-window (magit-find-file-noselect rev file)))
+
+(defun magit-find-file-read-args (prompt)
+  (let  ((rev (magit-read-branch-or-commit "Find file from revision")))
+    (list rev (magit-read-file-from-rev rev prompt))))
+
+(defun magit-find-file-noselect (rev file)
+  "Read FILE from REV into a buffer and return the buffer.
+FILE must be relative to the top directory of the repository."
+  (magit-find-file-noselect-1 rev file 'magit-find-file-hook))
+
+(defun magit-find-file-noselect-1 (rev file hookvar &optional revert)
+  "Read FILE from REV into a buffer and return the buffer.
+FILE must be relative to the top directory of the repository.
+An empty REV stands for index."
+  (let ((topdir (magit-toplevel)))
+    (when (file-name-absolute-p file)
+      (setq file (file-relative-name file topdir)))
+    (with-current-buffer (magit-get-revision-buffer-create rev file)
+      (when (or (not magit-buffer-file-name)
+                (if (eq revert 'ask-revert)
+                    (y-or-n-p (format "%s already exists; revert it? "
+                                      (buffer-name))))
+                revert)
+        (setq magit-buffer-revision
+              (if (string= rev "") "{index}" (magit-rev-format "%H" rev)))
+        (setq magit-buffer-refname rev)
+        (setq magit-buffer-file-name (expand-file-name file topdir))
+        (setq default-directory
+              (let ((dir (file-name-directory magit-buffer-file-name)))
+                (if (file-exists-p dir) dir topdir)))
+        (setq-local revert-buffer-function #'magit-revert-rev-file-buffer)
+        (revert-buffer t t)
+        (run-hooks hookvar))
+      (current-buffer))))
+
+(defun magit-get-revision-buffer-create (rev file)
+  (magit-get-revision-buffer rev file t))
+
+(defun magit-get-revision-buffer (rev file &optional create)
+  (funcall (if create 'get-buffer-create 'get-buffer)
+           (format "%s.~%s~" file (if (equal rev "") "index"
+                                    (subst-char-in-string ?/ ?_ rev)))))
+
+(defun magit-revert-rev-file-buffer (_ignore-auto noconfirm)
+  (when (or noconfirm
+            (and (not (buffer-modified-p))
+                 (catch 'found
+                   (dolist (regexp revert-without-query)
+                     (when (string-match regexp magit-buffer-file-name)
+                       (throw 'found t)))))
+            (yes-or-no-p (format "Revert buffer from git %s? "
+                                 (if (equal magit-buffer-refname "") "{index}"
+                                   (concat "revision " magit-buffer-refname)))))
+    (let* ((inhibit-read-only t)
+           (default-directory (magit-toplevel))
+           (file (file-relative-name magit-buffer-file-name))
+           (coding-system-for-read (or coding-system-for-read 'undecided)))
+      (erase-buffer)
+      (magit-git-insert "cat-file" "-p" (concat magit-buffer-refname ":" file))
+      (setq buffer-file-coding-system last-coding-system-used))
+    (let ((buffer-file-name magit-buffer-file-name)
+          (after-change-major-mode-hook
+           (remq 'global-diff-hl-mode-enable-in-buffers
+                 after-change-major-mode-hook)))
+      (normal-mode t))
+    (setq buffer-read-only t)
+    (set-buffer-modified-p nil)
+    (goto-char (point-min))))
+
+;;; Find Index
+
+(defvar magit-find-index-hook nil)
+
+(defun magit-find-file-index-noselect (file &optional revert)
+  "Read FILE from the index into a buffer and return the buffer.
+FILE must to be relative to the top directory of the repository."
+  (magit-find-file-noselect-1 "" file 'magit-find-index-hook
+                              (or revert 'ask-revert)))
+
+(defun magit-update-index ()
+  "Update the index with the contents of the current buffer.
+The current buffer has to be visiting a file in the index, which
+is done using `magit-find-index-noselect'."
+  (interactive)
+  (let ((file (magit-file-relative-name)))
+    (unless (equal magit-buffer-refname "")
+      (user-error "%s isn't visiting the index" file))
+    (if (y-or-n-p (format "Update index with contents of %s" (buffer-name)))
+        (let ((index (make-temp-file "index"))
+              (buffer (current-buffer)))
+          (when magit-wip-before-change-mode
+            (magit-wip-commit-before-change (list file) " before un-/stage"))
+          (let ((coding-system-for-write buffer-file-coding-system))
+            (with-temp-file index
+              (insert-buffer-substring buffer)))
+          (magit-with-toplevel
+            (magit-call-git "update-index" "--cacheinfo"
+                            (substring (magit-git-string "ls-files" "-s" file)
+                                       0 6)
+                            (magit-git-string "hash-object" "-t" "blob" "-w"
+                                              (concat "--path=" file)
+                                              "--" index)
+                            file))
+          (set-buffer-modified-p nil)
+          (when magit-wip-after-apply-mode
+            (magit-wip-commit-after-apply (list file) " after un-/stage")))
+      (message "Abort")))
+  (--when-let (magit-mode-get-buffer 'magit-status-mode)
+    (with-current-buffer it (magit-refresh)))
+  t)
+
+;;; Find Config File
+
+(defun magit-find-git-config-file (filename &optional wildcards)
+  "Edit a file located in the current repository's git directory.
+
+When \".git\", located at the root of the working tree, is a
+regular file, then that makes it cumbersome to open a file
+located in the actual git directory.
+
+This command is like `find-file', except that it temporarily
+binds `default-directory' to the actual git directory, while
+reading the FILENAME."
+  (interactive
+   (let ((default-directory (magit-git-dir)))
+     (find-file-read-args "Find file: "
+                          (confirm-nonexistent-file-or-buffer))))
+  (find-file filename wildcards))
+
+(defun magit-find-git-config-file-other-window (filename &optional wildcards)
+  "Edit a file located in the current repository's git directory, in another window.
+
+When \".git\", located at the root of the working tree, is a
+regular file, then that makes it cumbersome to open a file
+located in the actual git directory.
+
+This command is like `find-file-other-window', except that it
+temporarily binds `default-directory' to the actual git
+directory, while reading the FILENAME."
+  (interactive
+   (let ((default-directory (magit-git-dir)))
+     (find-file-read-args "Find file in other window: "
+                          (confirm-nonexistent-file-or-buffer))))
+  (find-file-other-window filename wildcards))
+
+(defun magit-find-git-config-file-other-frame (filename &optional wildcards)
+  "Edit a file located in the current repository's git directory, in another frame.
+
+When \".git\", located at the root of the working tree, is a
+regular file, then that makes it cumbersome to open a file
+located in the actual git directory.
+
+This command is like `find-file-other-frame', except that it
+temporarily binds `default-directory' to the actual git
+directory, while reading the FILENAME."
+  (interactive
+   (let ((default-directory (magit-git-dir)))
+     (find-file-read-args "Find file in other frame: "
+                          (confirm-nonexistent-file-or-buffer))))
+  (find-file-other-frame filename wildcards))
+
+;;; File Mode
+
+(defvar magit-file-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map "\C-xg"    'magit-status)
+    (define-key map "\C-x\M-g" 'magit-dispatch-popup)
+    (define-key map "\C-c\M-g" 'magit-file-popup)
+    map)
+  "Keymap for `magit-file-mode'.")
+
+;;;###autoload (autoload 'magit-file-popup "magit" nil t)
+(magit-define-popup magit-file-popup
+  "Popup console for Magit commands in file-visiting buffers."
+  :actions '((?s "Stage"     magit-stage-file)
+             (?D "Diff..."   magit-diff-buffer-file-popup)
+             (?L "Log..."    magit-log-buffer-file-popup)
+             (?B "Blame..."  magit-blame-popup) nil
+             (?u "Unstage"   magit-unstage-file)
+             (?d "Diff"      magit-diff-buffer-file)
+             (?l "Log"       magit-log-buffer-file)
+             (?b "Blame"     magit-blame)
+             (?p "Prev blob" magit-blob-previous)
+             (?c "Commit"    magit-commit-popup) nil
+             (?t "Trace"     magit-log-trace-definition)
+             (?r (lambda ()
+                   (with-current-buffer magit-pre-popup-buffer
+                     (and (not buffer-file-name)
+                          (propertize "...removal" 'face 'default))))
+                 magit-blame-removal)
+             (?n "Next blob" magit-blob-next)
+             (?e "Edit line" magit-edit-line-commit)
+             nil nil
+             (?f (lambda ()
+                   (with-current-buffer magit-pre-popup-buffer
+                     (and (not buffer-file-name)
+                          (propertize "...reverse" 'face 'default))))
+                 magit-blame-reverse)
+             nil)
+  :max-action-columns 5)
+
+(defvar magit-file-mode-lighter "")
+
+(define-minor-mode magit-file-mode
+  "Enable some Magit features in a file-visiting buffer.
+
+Currently this only adds the following key bindings.
+\n\\{magit-file-mode-map}"
+  :package-version '(magit . "2.2.0")
+  :lighter magit-file-mode-lighter
+  :keymap  magit-file-mode-map)
+
+(defun magit-file-mode-turn-on ()
+  (and buffer-file-name
+       (magit-inside-worktree-p t)
+       (magit-file-mode)))
+
+;;;###autoload
+(define-globalized-minor-mode global-magit-file-mode
+  magit-file-mode magit-file-mode-turn-on
+  :package-version '(magit . "2.13.0")
+  :link '(info-link "(magit)Minor Mode for Buffers Visiting Files")
+  :group 'magit-essentials
+  :group 'magit-modes
+  :init-value t)
+;; Unfortunately `:init-value t' only sets the value of the mode
+;; variable but does not cause the mode function to be called, and we
+;; cannot use `:initialize' to call that explicitly because the option
+;; is defined before the functions, so we have to do it here.
+(cl-eval-when (load)
+  (when global-magit-file-mode
+    (global-magit-file-mode 1)))
+
+;;; Blob Mode
+
+(defvar magit-blob-mode-map
+  (let ((map (make-sparse-keymap)))
+    (cond ((featurep 'jkl)
+           (define-key map "i" 'magit-blob-previous)
+           (define-key map "k" 'magit-blob-next)
+           (define-key map "j" 'magit-blame)
+           (define-key map "l" 'magit-blame-removal)
+           (define-key map "f" 'magit-blame-reverse))
+          (t
+           (define-key map "p" 'magit-blob-previous)
+           (define-key map "n" 'magit-blob-next)
+           (define-key map "b" 'magit-blame)
+           (define-key map "r" 'magit-blame-removal)
+           (define-key map "f" 'magit-blame-reverse)))
+    (define-key map "q" 'magit-kill-this-buffer)
+    map)
+  "Keymap for `magit-blob-mode'.")
+
+(define-minor-mode magit-blob-mode
+  "Enable some Magit features in blob-visiting buffers.
+
+Currently this only adds the following key bindings.
+\n\\{magit-blob-mode-map}"
+  :package-version '(magit . "2.3.0"))
+
+(defun magit-blob-next ()
+  "Visit the next blob which modified the current file."
+  (interactive)
+  (if magit-buffer-file-name
+      (magit-blob-visit (or (magit-blob-successor magit-buffer-revision
+                                                  magit-buffer-file-name)
+                            magit-buffer-file-name)
+                        (line-number-at-pos))
+    (if (buffer-file-name (buffer-base-buffer))
+        (user-error "You have reached the end of time")
+      (user-error "Buffer isn't visiting a file or blob"))))
+
+(defun magit-blob-previous ()
+  "Visit the previous blob which modified the current file."
+  (interactive)
+  (if-let ((file (or magit-buffer-file-name
+                     (buffer-file-name (buffer-base-buffer)))))
+      (--if-let (magit-blob-ancestor magit-buffer-revision file)
+          (magit-blob-visit it (line-number-at-pos))
+        (user-error "You have reached the beginning of time"))
+    (user-error "Buffer isn't visiting a file or blob")))
+
+(defun magit-blob-visit (blob-or-file line)
+  (if (stringp blob-or-file)
+      (find-file blob-or-file)
+    (pcase-let ((`(,rev ,file) blob-or-file))
+      (magit-find-file rev file)
+      (apply #'message "%s (%s %s ago)"
+             (magit-rev-format "%s" rev)
+             (magit--age (magit-rev-format "%ct" rev)))))
+  (goto-char (point-min))
+  (forward-line (1- line)))
+
+(defun magit-blob-ancestor (rev file)
+  (let ((lines (magit-with-toplevel
+                 (magit-git-lines "log" "-2" "--format=%H" "--name-only"
+                                  "--follow" (or rev "HEAD") "--" file))))
+    (if rev (cddr lines) (butlast lines 2))))
+
+(defun magit-blob-successor (rev file)
+  (let ((lines (magit-with-toplevel
+                 (magit-git-lines "log" "--format=%H" "--name-only" "--follow"
+                                  "HEAD" "--" file))))
+    (catch 'found
+      (while lines
+        (if (equal (nth 2 lines) rev)
+            (throw 'found (list (nth 0 lines) (nth 1 lines)))
+          (setq lines (nthcdr 2 lines)))))))
+
+;;; File Commands
+
+(defun magit-file-rename (file newname)
+  "Rename the FILE to NEWNAME.
+If FILE isn't tracked in Git, fallback to using `rename-file'."
+  (interactive
+   (let* ((file (magit-read-file "Rename file"))
+          (newname (read-file-name (format "Rename %s to file: " file)
+                                   (expand-file-name (file-name-directory file)))))
+     (list (expand-file-name file (magit-toplevel))
+           (expand-file-name newname))))
+  (if (magit-file-tracked-p (magit-convert-filename-for-git file))
+      (let ((oldbuf (get-file-buffer file)))
+        (when (and oldbuf (buffer-modified-p oldbuf))
+          (user-error "Save %s before moving it" file))
+        (when (file-exists-p newname)
+          (user-error "%s already exists" newname))
+        (magit-run-git "mv"
+                       (magit-convert-filename-for-git file)
+                       (magit-convert-filename-for-git newname))
+        (when oldbuf
+          (with-current-buffer oldbuf
+            (let ((buffer-read-only buffer-read-only))
+              (set-visited-file-name newname))
+            (if (fboundp 'vc-refresh-state)
+                (vc-refresh-state)
+              (with-no-warnings
+                (vc-find-file-hook))))))
+    (rename-file file newname current-prefix-arg)
+    (magit-refresh)))
+
+(defun magit-file-untrack (files &optional force)
+  "Untrack the selected FILES or one file read in the minibuffer.
+
+With a prefix argument FORCE do so even when the files have
+staged as well as unstaged changes."
+  (interactive (list (or (--if-let (magit-region-values 'file t)
+                             (progn
+                               (unless (magit-file-tracked-p (car it))
+                                 (user-error "Already untracked"))
+                               (magit-confirm-files 'untrack it "Untrack"))
+                           (list (magit-read-tracked-file "Untrack file"))))
+                     current-prefix-arg))
+  (magit-run-git "rm" "--cached" (and force "--force") "--" files))
+
+(defun magit-file-delete (files &optional force)
+  "Delete the selected FILES or one file read in the minibuffer.
+
+With a prefix argument FORCE do so even when the files have
+uncommitted changes.  When the files aren't being tracked in
+Git, then fallback to using `delete-file'."
+  (interactive (list (--if-let (magit-region-values 'file t)
+                         (magit-confirm-files 'delete it "Delete")
+                       (list (magit-read-file "Delete file")))
+                     current-prefix-arg))
+  (if (magit-file-tracked-p (car files))
+      (magit-call-git "rm" (and force "--force") "--" files)
+    (let ((topdir (magit-toplevel)))
+      (dolist (file files)
+        (delete-file (expand-file-name file topdir) t))))
+  (magit-refresh))
+
+;;;###autoload
+(defun magit-file-checkout (rev file)
+  "Checkout FILE from REV."
+  (interactive
+   (let ((rev (magit-read-branch-or-commit
+               "Checkout from revision" magit-buffer-revision)))
+     (list rev (magit-read-file-from-rev rev "Checkout file"))))
+  (magit-with-toplevel
+    (magit-run-git "checkout" rev "--" file)))
+
+;;; Read File
+
+(defvar magit-read-file-hist nil)
+
+(defun magit-read-file-from-rev (rev prompt &optional default)
+  (let ((files (magit-revision-files rev)))
+    (magit-completing-read
+     prompt files nil t nil 'magit-read-file-hist
+     (car (member (or default (magit-current-file)) files)))))
+
+(defun magit-read-file (prompt &optional tracked-only)
+  (let ((choices (nconc (magit-list-files)
+                        (unless tracked-only (magit-untracked-files)))))
+    (magit-completing-read prompt choices nil t nil nil
+                           (car (member (or (magit-section-when (file submodule))
+                                            (magit-file-relative-name
+                                             nil tracked-only))
+                                        choices)))))
+
+(defun magit-read-tracked-file (prompt)
+  (magit-read-file prompt t))
+
+(defun magit-read-file-choice (prompt files &optional error default)
+  "Read file from FILES.
+
+If FILES has only one member, return that instead of prompting.
+If FILES has no members, give a user error.  ERROR can be given
+to provide a more informative error.
+
+If DEFAULT is non-nil, use this as the default value instead of
+`magit-current-file'."
+  (pcase (length files)
+    (0 (user-error (or error "No file choices")))
+    (1 (car files))
+    (_ (magit-completing-read
+        prompt files nil t nil 'magit-read-file-hist
+        (car (member (or default (magit-current-file)) files))))))
+
+(defun magit-read-changed-file (rev-or-range prompt &optional default)
+  (magit-read-file-choice
+   prompt
+   (magit-changed-files rev-or-range)
+   default
+   (concat "No file changed in " rev-or-range)))
+
+(defun magit-read-files (prompt initial-contents)
+  (mapconcat 'identity
+             (completing-read-multiple (or prompt "File,s: ")
+                                       (magit-list-files)
+                                       nil nil initial-contents) ","))
+
+;;; Patch File
+
+(defcustom magit-patch-save-arguments '(exclude "--stat")
+  "Arguments used by `magit-patch-save-arguments' (which see)"
+  :package-version '(magit . "2.12.0")
+  :group 'magit-diff
+  :type '(choice (const :tag "use buffer arguments" buffer)
+                 (cons :tag "use buffer arguments except"
+                       (const :format "" exclude)
+                       (repeat :format "%v%i\n"
+                               (string :tag "Argument")))
+                 (repeat :tag "use constant arguments"
+                         (string :tag "Argument"))))
+
+(magit-define-popup magit-patch-apply-popup
+  "Popup console for applying a patch file."
+  :man-page "git-apply"
+  :switches '((?i "Also apply to index"     "--index")
+              (?c "Only apply to index"     "--cached")
+              (?3 "Fall back on 3way merge" "--3way"))
+  :actions  '((?a "Apply patch" magit-patch-apply))
+  :default-action 'magit-patch-apply)
+
+(defun magit-patch-apply (file &rest args)
+  "Apply the patch file FILE."
+  (interactive (list (expand-file-name
+                      (read-file-name "Apply patch: "
+                                      default-directory nil nil
+                                      (--when-let (magit-file-at-point)
+                                        (file-relative-name it))))
+                     (magit-patch-apply-arguments)))
+  (magit-run-git "apply" args "--" (magit-convert-filename-for-git file)))
+
+(defun magit-patch-save (file &optional arg)
+  "Write current diff into patch FILE.
+
+What arguments are used to create the patch depends on the value
+of `magit-patch-save-arguments' and whether a prefix argument is
+used.
+
+If the value is the symbol `buffer', then use the same arguments
+as the buffer.  With a prefix argument use no arguments.
+
+If the value is a list beginning with the symbol `exclude', then
+use the same arguments as the buffer except for those matched by
+entries in the cdr of the list.  The comparison is done using
+`string-prefix-p'.  With a prefix argument use the same arguments
+as the buffer.
+
+If the value is a list of strings (including the empty list),
+then use those arguments.  With a prefix argument use the same
+arguments as the buffer.
+
+Of course the arguments that are required to actually show the
+same differences as those shown in the buffer are always used."
+  (interactive (list (read-file-name "Write patch file: " default-directory)
+                     current-prefix-arg))
+  (unless (derived-mode-p 'magit-diff-mode)
+    (user-error "Only diff buffers can be saved as patches"))
+  (pcase-let ((`(,rev ,const ,args ,files) magit-refresh-args))
+    (when (derived-mode-p 'magit-revision-mode)
+      (setq rev (format "%s~..%s" rev rev)))
+    (cond ((eq magit-patch-save-arguments 'buffer)
+           (when arg
+             (setq args nil)))
+          ((eq (car-safe magit-patch-save-arguments) 'exclude)
+           (unless arg
+             (setq args (-difference args (cdr magit-patch-save-arguments)))))
+          ((not arg)
+           (setq args magit-patch-save-arguments)))
+    (with-temp-file file
+      (magit-git-insert "diff" rev "-p" const args "--" files)))
+  (magit-refresh))
+
+(provide 'magit-files)
+;;; magit-files.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-files.elc b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-files.elc
new file mode 100644
index 0000000000..f51699096b
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-files.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-git.el b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-git.el
new file mode 100644
index 0000000000..da91870bae
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-git.el
@@ -0,0 +1,2107 @@
+;;; magit-git.el --- Git functionality  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2010-2018  The Magit Project Contributors
+;;
+;; You should have received a copy of the AUTHORS.md file which
+;; lists all contributors.  If not, see http://magit.vc/authors.
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; Magit 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, or (at your option)
+;; any later version.
+;;
+;; Magit 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 Magit.  If not, see http://www.gnu.org/licenses.
+
+;;; Commentary:
+
+;; This library implements wrappers for various Git plumbing commands.
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'dash)
+
+(require 'magit-popup)
+(require 'magit-utils)
+(require 'magit-section)
+
+(declare-function magit-call-git "magit-process" (&rest args))
+(declare-function magit-maybe-make-margin-overlay "magit-margin" ())
+(declare-function magit-process-buffer "magit-process" (&optional nodisplay))
+(declare-function magit-process-file "magit-process" (&rest args))
+(declare-function magit-process-insert-section "magit-process"
+                  (pwe program args &optional errcode errlog))
+(declare-function magit-refresh "magit-mode" ())
+(defvar magit-process-error-message-regexps)
+(defvar magit-refresh-args) ; from `magit-mode' for `magit-current-file'
+(defvar magit-branch-prefer-remote-upstream)
+(defvar magit-published-branches)
+
+(defvar magit-tramp-process-environment nil)
+
+;;; Options
+
+;; For now this is shared between `magit-process' and `magit-git'.
+(defgroup magit-process nil
+  "Git and other external processes used by Magit."
+  :group 'magit)
+
+(defvar magit-git-environment
+  (list (format "INSIDE_EMACS=%s,magit" emacs-version))
+  "Prepended to `process-environment' while running git.")
+
+(defcustom magit-git-output-coding-system
+  (and (eq system-type 'windows-nt) 'utf-8)
+  "Coding system for receiving output from Git.
+
+If non-nil, the Git config value `i18n.logOutputEncoding' should
+be set via `magit-git-global-arguments' to value consistent with
+this."
+  :package-version '(magit . "2.9.0")
+  :group 'magit-process
+  :type '(choice (coding-system :tag "Coding system to decode Git output")
+                 (const :tag "Use system default" nil)))
+
+(defvar magit-git-w32-path-hack nil
+  "Alist of (EXE . (PATHENTRY)).
+This specifies what additional PATH setting needs to be added to
+the environment in order to run the non-wrapper git executables
+successfully.")
+
+(defcustom magit-git-executable
+  ;; Git might be installed in a different location on a remote, so
+  ;; it is better not to use the full path to the executable, except
+  ;; on Window were we would otherwise end up using one one of the
+  ;; wrappers "cmd/git.exe" or "cmd/git.cmd", which are much slower
+  ;; than using "bin/git.exe" directly.
+  (or (and (eq system-type 'windows-nt)
+           (--when-let (executable-find "git")
+             (or (ignore-errors
+                   ;; Git for Windows 2.x provides cygpath so we can
+                   ;; ask it for native paths.  Using an upper case
+                   ;; alias makes this fail on 1.x (which is good,
+                   ;; because we would not want to end up using some
+                   ;; other cygpath).
+                   (let* ((core-exe
+                           (car
+                            (process-lines
+                             it "-c"
+                             "alias.X=!x() { which \"$1\" | cygpath -mf -; }; x"
+                             "X" "git")))
+                          (hack-entry (assoc core-exe magit-git-w32-path-hack))
+                          ;; Running the libexec/git-core executable
+                          ;; requires some extra PATH entries.
+                          (path-hack
+                           (list (concat "PATH="
+                                         (car (process-lines
+                                               it "-c"
+                                               "alias.P=!cygpath -wp \"$PATH\""
+                                               "P"))))))
+                     ;; The defcustom STANDARD expression can be
+                     ;; evaluated many times, so make sure it is
+                     ;; idempotent.
+                     (if hack-entry
+                         (setcdr hack-entry path-hack)
+                       (push (cons core-exe path-hack) magit-git-w32-path-hack))
+                     core-exe))
+                 ;; For 1.x, we search for bin/ next to cmd/.
+                 (let ((alt (directory-file-name (file-name-directory it))))
+                   (if (and (equal (file-name-nondirectory alt) "cmd")
+                            (setq alt (expand-file-name
+                                       (convert-standard-filename "bin/git.exe")
+                                       (file-name-directory alt)))
+                            (file-executable-p alt))
+                       alt
+                     it)))))
+      "git")
+  "The Git executable used by Magit."
+  :group 'magit-process
+  :type 'string)
+
+(defcustom magit-git-global-arguments
+  `("--no-pager" "--literal-pathspecs" "-c" "core.preloadindex=true"
+    "-c" "log.showSignature=false"
+    ,@(and (eq system-type 'windows-nt)
+           (list "-c" "i18n.logOutputEncoding=UTF-8")))
+  "Global Git arguments.
+
+The arguments set here are used every time the git executable is
+run as a subprocess.  They are placed right after the executable
+itself and before the git command - as in `git HERE... COMMAND
+REST'.  See the manpage `git(1)' for valid arguments.
+
+Be careful what you add here, especially if you are using Tramp
+to connect to servers with ancient Git versions.  Never remove
+anything that is part of the default value, unless you really
+know what you are doing.  And think very hard before adding
+something; it will be used every time Magit runs Git for any
+purpose."
+  :package-version '(magit . "2.9.0")
+  :group 'magit-git-arguments
+  :group 'magit-process
+  :type '(repeat string))
+
+(defvar magit-git-debug nil
+  "Whether to enable additional reporting of git errors.
+
+Magit basically calls git for one of these two reasons: for
+side-effects or to do something with its standard output.
+
+When git is run for side-effects then its output, including error
+messages, go into the process buffer which is shown when using \
+\\<magit-status-mode-map>\\[magit-process].
+
+When git's output is consumed in some way, then it would be too
+expensive to also insert it into this buffer, but when this
+option is non-nil and git returns with a non-zero exit status,
+then at least its standard error is inserted into this buffer.
+
+This is only intended for debugging purposes.  Do not enable this
+permanently, that would negatively affect performance.")
+
+
+(defcustom magit-prefer-remote-upstream nil
+  "Whether to favor remote branches when reading the upstream branch.
+
+This controls whether commands that read a branch from the user
+and then set it as the upstream branch, offer a local or a remote
+branch as default completion candidate, when they have the choice.
+
+This affects all commands that use `magit-read-upstream-branch'
+or `magit-read-starting-point', which includes all commands that
+change the upstream and many which create new branches."
+  :package-version '(magit . "2.4.2")
+  :group 'magit-commands
+  :type 'boolean)
+
+(defcustom magit-list-refs-sortby nil
+  "How to sort the ref collection in the prompt.
+
+This affects commands that read a ref.  More specifically, it
+controls the order of refs returned by `magit-list-refs', which
+is called by functions like `magit-list-branch-names' to generate
+the collection of refs.  By default, refs are sorted according to
+their full refname (i.e., 'refs/...').
+
+Any value accepted by the `--sort' flag of `git for-each-ref' can
+be used.  For example, \"-creatordate\" places refs with more
+recent committer or tagger dates earlier in the list.  A list of
+strings can also be given in order to pass multiple sort keys to
+`git for-each-ref'.
+
+Note that, depending on the completion framework you use, this
+may not be sufficient to change the order in which the refs are
+displayed.  It only controls the order of the collection passed
+to `magit-completing-read' or, for commands that support reading
+multiple strings, `read-from-minibuffer'.  The completion
+framework ultimately determines how the collection is displayed."
+  :package-version '(magit . "2.11.0")
+  :group 'magit-miscellanous
+  :type '(choice string (repeat string)))
+
+;;; Git
+
+(defvar magit--refresh-cache nil)
+
+(defmacro magit--with-refresh-cache (key &rest body)
+  (declare (indent 1) (debug (form body)))
+  (let ((k (cl-gensym)))
+    `(if magit--refresh-cache
+         (let ((,k ,key))
+           (--if-let (assoc ,k (cdr magit--refresh-cache))
+               (progn (cl-incf (caar magit--refresh-cache))
+                      (cdr it))
+             (cl-incf (cdar magit--refresh-cache))
+             (let ((value ,(macroexp-progn body)))
+               (push (cons ,k value)
+                     (cdr magit--refresh-cache))
+               value)))
+       ,@body)))
+
+(defmacro magit-with-editor (&rest body)
+  "Like `with-editor' but let-bind some more variables."
+  (declare (indent 0) (debug (body)))
+  `(let ((magit-process-popup-time -1)
+         ;; The user may have customized `shell-file-name' to
+         ;; something which results in `w32-shell-dos-semantics' nil
+         ;; (which changes the quoting style used by
+         ;; `shell-quote-argument'), but Git for Windows expects shell
+         ;; quoting in the dos style.
+         (shell-file-name (if (and (eq system-type 'windows-nt)
+                                   ;; If we have Cygwin mount points,
+                                   ;; the git flavor is cygwin, so dos
+                                   ;; shell quoting is probably wrong.
+                                   (not magit-cygwin-mount-points))
+                              "cmdproxy"
+                            shell-file-name)))
+     (with-editor "GIT_EDITOR"
+       ,@body)))
+
+(defun magit-process-git-arguments (args)
+  "Prepare ARGS for a function that invokes Git.
+
+Magit has many specialized functions for running Git; they all
+pass arguments through this function before handing them to Git,
+to do the following.
+
+* Flatten ARGS, removing nil arguments.
+* Prepend `magit-git-global-arguments' to ARGS.
+* On w32 systems, encode to `w32-ansi-code-page'."
+  (setq args (append magit-git-global-arguments (-flatten args)))
+  (if (and (eq system-type 'windows-nt) (boundp 'w32-ansi-code-page))
+      ;; On w32, the process arguments *must* be encoded in the
+      ;; current code-page (see #3250).
+      (mapcar (lambda (arg)
+                (encode-coding-string
+                 arg (intern (format "cp%d" w32-ansi-code-page))))
+              args)
+    args))
+
+(defun magit-git-exit-code (&rest args)
+  "Execute Git with ARGS, returning its exit code."
+  (apply #'magit-process-file magit-git-executable nil nil nil
+         (magit-process-git-arguments args)))
+
+(defun magit-git-success (&rest args)
+  "Execute Git with ARGS, returning t if its exit code is 0."
+  (= (magit-git-exit-code args) 0))
+
+(defun magit-git-failure (&rest args)
+  "Execute Git with ARGS, returning t if its exit code is 1."
+  (= (magit-git-exit-code args) 1))
+
+(defun magit-git-str (&rest args)
+  "Execute Git with ARGS, returning the first line of its output.
+If there is no output, return nil.  If the output begins with a
+newline, return an empty string.  Like `magit-git-string' but
+ignore `magit-git-debug'."
+  (setq args (-flatten args))
+  (magit--with-refresh-cache (cons default-directory args)
+    (with-temp-buffer
+      (apply #'magit-process-file magit-git-executable nil (list t nil) nil
+             (magit-process-git-arguments args))
+      (unless (bobp)
+        (goto-char (point-min))
+        (buffer-substring-no-properties (point) (line-end-position))))))
+
+(defun magit-git-output (&rest args)
+  "Execute Git with ARGS, returning its output."
+  (setq args (-flatten args))
+  (magit--with-refresh-cache (cons default-directory args)
+    (with-temp-buffer
+      (apply #'magit-process-file magit-git-executable nil (list t nil) nil
+             (magit-process-git-arguments args))
+      (buffer-substring-no-properties (point-min) (point-max)))))
+
+(define-error 'magit-invalid-git-boolean "Not a Git boolean")
+
+(defun magit-git-true (&rest args)
+  "Execute Git with ARGS, returning t if it prints \"true\".
+If it prints \"false\", then return nil.  For any other output
+signal `magit-invalid-git-boolean'."
+  (pcase (magit-git-output args)
+    ((or "true"  "true\n")  t)
+    ((or "false" "false\n") nil)
+    (output (signal 'magit-invalid-git-boolean output))))
+
+(defun magit-git-false (&rest args)
+  "Execute Git with ARGS, returning t if it prints \"false\".
+If it prints \"true\", then return nil.  For any other output
+signal `magit-invalid-git-boolean'."
+  (pcase (magit-git-output args)
+    ((or "true"  "true\n")  nil)
+    ((or "false" "false\n") t)
+    (output (signal 'magit-invalid-git-boolean output))))
+
+(defun magit-git-insert (&rest args)
+  "Execute Git with ARGS, inserting its output at point.
+If Git exits with a non-zero exit status, then show a message and
+add a section in the respective process buffer."
+  (setq args (magit-process-git-arguments args))
+  (if magit-git-debug
+      (let (log)
+        (unwind-protect
+            (progn
+              (setq log (make-temp-file "magit-stderr"))
+              (delete-file log)
+              (let ((exit (apply #'magit-process-file magit-git-executable
+                                 nil (list t log) nil args)))
+                (when (> exit 0)
+                  (let ((msg "Git failed"))
+                    (when (file-exists-p log)
+                      (setq msg (with-temp-buffer
+                                  (insert-file-contents log)
+                                  (goto-char (point-max))
+                                  (cond
+                                   ((functionp magit-git-debug)
+                                    (funcall magit-git-debug (buffer-string)))
+                                   ((run-hook-wrapped
+                                     'magit-process-error-message-regexps
+                                     (lambda (re) (re-search-backward re nil t)))
+                                    (match-string-no-properties 1)))))
+                      (let ((magit-git-debug nil))
+                        (with-current-buffer (magit-process-buffer t)
+                          (magit-process-insert-section default-directory
+                                                        magit-git-executable
+                                                        args exit log))))
+                    (message "%s" msg)))
+                exit))
+          (ignore-errors (delete-file log))))
+    (apply #'magit-process-file magit-git-executable
+           nil (list t nil) nil args)))
+
+(defun magit-git-string (&rest args)
+  "Execute Git with ARGS, returning the first line of its output.
+If there is no output, return nil.  If the output begins with a
+newline, return an empty string."
+  (setq args (-flatten args))
+  (magit--with-refresh-cache (cons default-directory args)
+    (with-temp-buffer
+      (apply #'magit-git-insert args)
+      (unless (bobp)
+        (goto-char (point-min))
+        (buffer-substring-no-properties (point) (line-end-position))))))
+
+(defun magit-git-lines (&rest args)
+  "Execute Git with ARGS, returning its output as a list of lines.
+Empty lines anywhere in the output are omitted.
+
+If Git exits with a non-zero exit status, then report show a
+message and add a section in the respective process buffer."
+  (with-temp-buffer
+    (apply #'magit-git-insert args)
+    (split-string (buffer-string) "\n" t)))
+
+(defun magit-git-items (&rest args)
+  "Execute Git with ARGS, returning its null-separated output as a list.
+Empty items anywhere in the output are omitted.
+
+If Git exits with a non-zero exit status, then report show a
+message and add a section in the respective process buffer."
+  (with-temp-buffer
+    (apply #'magit-git-insert args)
+    (split-string (buffer-string) "\0" t)))
+
+(defun magit-git-wash (washer &rest args)
+  "Execute Git with ARGS, inserting washed output at point.
+Actually first insert the raw output at point.  If there is no
+output, call `magit-cancel-section'.  Otherwise temporarily narrow
+the buffer to the inserted text, move to its beginning, and then
+call function WASHER with ARGS as its sole argument."
+  (declare (indent 1))
+  (let ((beg (point)))
+    (setq args (-flatten args))
+    (magit-git-insert args)
+    (if (= (point) beg)
+        (magit-cancel-section)
+      (unless (bolp)
+        (insert "\n"))
+      (save-restriction
+        (narrow-to-region beg (point))
+        (goto-char beg)
+        (funcall washer args))
+      (when (or (= (point) beg)
+                (= (point) (1+ beg)))
+        (magit-cancel-section))
+      (magit-maybe-make-margin-overlay))))
+
+(defun magit-git-version (&optional raw)
+  (--when-let (let (magit-git-global-arguments)
+                (ignore-errors (substring (magit-git-string "version") 12)))
+    (if raw it (and (string-match "^\\([0-9]+\\.[0-9]+\\.[0-9]+\\)" it)
+                    (match-string 1 it)))))
+
+;;; Files
+
+(defun magit--safe-default-directory (&optional file)
+  (catch 'unsafe-default-dir
+    (let ((dir (file-name-as-directory
+                (expand-file-name (or file default-directory))))
+          (previous nil))
+      (while (not (magit-file-accessible-directory-p dir))
+        (setq dir (file-name-directory (directory-file-name dir)))
+        (when (equal dir previous)
+          (throw 'unsafe-default-dir nil))
+        (setq previous dir))
+      dir)))
+
+(defmacro magit--with-safe-default-directory (file &rest body)
+  (declare (indent 1) (debug (form body)))
+  `(when-let ((default-directory (magit--safe-default-directory ,file)))
+     ,@body))
+
+(defun magit-git-dir (&optional path)
+  "Return absolute path to the control directory of the current repository.
+
+All symlinks are followed.  If optional PATH is non-nil, then
+it has to be a path relative to the control directory and its
+absolute path is returned."
+  (magit--with-refresh-cache (list default-directory 'magit-git-dir path)
+    (magit--with-safe-default-directory nil
+      (when-let ((dir (magit-rev-parse-safe "--git-dir")))
+        (setq dir (file-name-as-directory (magit-expand-git-file-name dir)))
+        (unless (file-remote-p dir)
+          (setq dir (concat (file-remote-p default-directory) dir)))
+        (if path (expand-file-name (convert-standard-filename path) dir) dir)))))
+
+(defvar magit--separated-gitdirs nil)
+
+(defun magit--record-separated-gitdir ()
+  (let ((topdir (magit-toplevel))
+        (gitdir (magit-git-dir)))
+    ;; We want to delete the entry for `topdir' here, rather than within
+    ;; (unless ...), in case a `--separate-git-dir' repository was switched to
+    ;; the standard structure (i.e., "topdir/.git/").
+    (setq magit--separated-gitdirs (cl-delete topdir
+                                            magit--separated-gitdirs
+                                            :key #'car :test #'equal))
+    (unless (equal (file-name-as-directory (expand-file-name ".git" topdir))
+                   gitdir)
+      (push (cons topdir gitdir) magit--separated-gitdirs))))
+
+(defun magit-toplevel (&optional directory)
+  "Return the absolute path to the toplevel of the current repository.
+
+From within the working tree or control directory of a repository
+return the absolute path to the toplevel directory of the working
+tree.  As a special case, from within a bare repository return
+the control directory instead.  When called outside a repository
+then return nil.
+
+When optional DIRECTORY is non-nil then return the toplevel for
+that directory instead of the one for `default-directory'.
+
+Try to respect the option `find-file-visit-truename', i.e.  when
+the value of that option is nil, then avoid needlessly returning
+the truename.  When a symlink to a sub-directory of the working
+tree is involved, or when called from within a sub-directory of
+the gitdir or from the toplevel of a gitdir, which itself is not
+located within the working tree, then it is not possible to avoid
+returning the truename."
+  (magit--with-refresh-cache
+      (cons (or directory default-directory) 'magit-toplevel)
+    (magit--with-safe-default-directory directory
+      (if-let ((topdir (magit-rev-parse-safe "--show-toplevel")))
+          (let (updir)
+            (setq topdir (magit-expand-git-file-name topdir))
+            (if (and
+                 ;; Always honor these settings.
+                 (not find-file-visit-truename)
+                 (not (getenv "GIT_WORK_TREE"))
+                 ;; `--show-cdup' is the relative path to the toplevel
+                 ;; from `(file-truename default-directory)'.  Here we
+                 ;; pretend it is relative to `default-directory', and
+                 ;; go to that directory.  Then we check whether
+                 ;; `--show-toplevel' still returns the same value and
+                 ;; whether `--show-cdup' now is the empty string.  If
+                 ;; both is the case, then we are at the toplevel of
+                 ;; the same working tree, but also avoided needlessly
+                 ;; following any symlinks.
+                 (progn
+                   (setq updir (file-name-as-directory
+                                (magit-rev-parse-safe "--show-cdup")))
+                   (setq updir (if (file-name-absolute-p updir)
+                                   (concat (file-remote-p default-directory) updir)
+                                 (expand-file-name updir)))
+                   (let ((default-directory updir))
+                     (and (string-equal (magit-rev-parse-safe "--show-cdup") "")
+                          (--when-let (magit-rev-parse-safe "--show-toplevel")
+                            (string-equal (magit-expand-git-file-name it)
+                                          topdir))))))
+                updir
+              (concat (file-remote-p default-directory)
+                      (file-name-as-directory topdir))))
+        (when-let ((gitdir (magit-rev-parse-safe "--git-dir")))
+          (setq gitdir (file-name-as-directory
+                        (if (file-name-absolute-p gitdir)
+                            ;; We might have followed a symlink.
+                            (concat (file-remote-p default-directory)
+                                    (magit-expand-git-file-name gitdir))
+                          (expand-file-name gitdir))))
+          (if (magit-bare-repo-p)
+              gitdir
+            (let* ((link (expand-file-name "gitdir" gitdir))
+                   (wtree (and (file-exists-p link)
+                               (magit-file-line link))))
+              (cond
+               ((and wtree
+                     ;; Ignore .git/gitdir files that result from a
+                     ;; Git bug.  See #2364.
+                     (not (equal wtree ".git")))
+                ;; Return the linked working tree.
+                (file-name-directory wtree))
+               ;; The working directory may not be the parent directory of
+               ;; .git if it was set up with `git init --separate-git-dir'.
+               ;; See #2955.
+               ((car (rassoc gitdir magit--separated-gitdirs)))
+               (t
+                ;; Step outside the control directory to enter the working tree.
+                (file-name-directory (directory-file-name gitdir)))))))))))
+
+(defmacro magit-with-toplevel (&rest body)
+  (declare (indent defun) (debug (body)))
+  (let ((toplevel (cl-gensym "toplevel")))
+    `(let ((,toplevel (magit-toplevel)))
+       (if ,toplevel
+           (let ((default-directory ,toplevel))
+             ,@body)
+         (magit--not-inside-repository-error)))))
+
+(define-error 'magit-outside-git-repo "Not inside Git repository")
+(define-error 'magit-git-executable-not-found
+  "Git executable cannot be found (see https://magit.vc/goto/e6a78ed2)")
+
+(defun magit--not-inside-repository-error ()
+  (if (executable-find magit-git-executable)
+      (signal 'magit-outside-git-repo default-directory)
+    (signal 'magit-git-executable-not-found magit-git-executable)))
+
+(defun magit-inside-gitdir-p (&optioal noerror)
+  "Return t if `default-directory' is below the repository directory.
+If it is below the working directory, then return nil.
+If it isn't below either, then signal an error unless NOERROR
+is non-nil, in which case return nil."
+  (and (magit--assert-default-directory noerror)
+       ;; Below a repository directory that is not located below the
+       ;; working directory "git rev-parse --is-inside-git-dir" prints
+       ;; "false", which is wrong.
+       (let ((gitdir (magit-git-dir)))
+         (cond (gitdir (file-in-directory-p default-directory gitdir))
+               (noerror nil)
+               (t (signal 'magit-outside-git-repo default-directory))))))
+
+(defun magit-inside-worktree-p (&optional noerror)
+  "Return t if `default-directory' is below the working directory.
+If it is below the repository directory, then return nil.
+If it isn't below either, then signal an error unless NOERROR
+is non-nil, in which case return nil."
+  (and (magit--assert-default-directory noerror)
+       (condition-case nil
+           (magit-rev-parse-true "--is-inside-work-tree")
+         (magit-invalid-git-boolean
+          (and (not noerror)
+               (signal 'magit-outside-git-repo default-directory))))))
+
+(defun magit-bare-repo-p (&optional noerror)
+  "Return t if the current repository is bare.
+If it is non-bare, then return nil.  If `default-directory'
+isn't below a Git repository, then signal an error unless
+NOERROR is non-nil, in which case return nil."
+  (and (magit--assert-default-directory noerror)
+       (condition-case nil
+           (magit-rev-parse-true "--is-bare-repository")
+         (magit-invalid-git-boolean
+          (and (not noerror)
+               (signal 'magit-outside-git-repo default-directory))))))
+
+(defun magit--assert-default-directory (&optional noerror)
+  (or (file-directory-p default-directory)
+      (and (not noerror)
+           (let ((exists (file-exists-p default-directory)))
+	     (signal (if exists 'file-error 'file-missing)
+		     (list "Running git in directory"
+		           (if exists
+                               "Not a directory"
+                             "No such file or directory")
+		           default-directory))))))
+
+(defun magit-git-repo-p (directory &optional non-bare)
+  "Return t if DIRECTORY is a Git repository.
+When optional NON-BARE is non-nil also return nil if DIRECTORY is
+a bare repository."
+  (and (file-directory-p directory) ; Avoid archives, see #3397.
+       (or (file-regular-p (expand-file-name ".git" directory))
+           (file-directory-p (expand-file-name ".git" directory))
+           (and (not non-bare)
+                (file-regular-p (expand-file-name "HEAD" directory))
+                (file-directory-p (expand-file-name "refs" directory))
+                (file-directory-p (expand-file-name "objects" directory))))))
+
+(defvar-local magit-buffer-revision  nil)
+(defvar-local magit-buffer-refname   nil)
+(defvar-local magit-buffer-file-name nil)
+(put 'magit-buffer-revision  'permanent-local t)
+(put 'magit-buffer-refname   'permanent-local t)
+(put 'magit-buffer-file-name 'permanent-local t)
+
+(defun magit-file-relative-name (&optional file tracked)
+  "Return the path of FILE relative to the repository root.
+
+If optional FILE is nil or omitted, return the relative path of
+the file being visited in the current buffer, if any, else nil.
+If the file is not inside a Git repository, then return nil.
+
+If TRACKED is non-nil, return the path only if it matches a
+tracked file."
+  (unless file
+    (with-current-buffer (or (buffer-base-buffer)
+                             (current-buffer))
+      (setq file (or magit-buffer-file-name buffer-file-name
+                     (and (derived-mode-p 'dired-mode) default-directory)))))
+  (when (and file (or (not tracked)
+                      (magit-file-tracked-p (file-relative-name file))))
+    (--when-let (magit-toplevel
+                 (magit--safe-default-directory
+                  (directory-file-name (file-name-directory file))))
+      (file-relative-name file it))))
+
+(defun magit-file-tracked-p (file)
+  (magit-git-success "ls-files" "--error-unmatch" file))
+
+(defun magit-list-files (&rest args)
+  (apply #'magit-git-items "ls-files" "-z" "--full-name" args))
+
+(defun magit-tracked-files ()
+  (magit-list-files "--cached"))
+
+(defun magit-untracked-files (&optional all files)
+  (magit-list-files "--other" (unless all "--exclude-standard") "--" files))
+
+(defun magit-unstaged-files (&optional nomodules files)
+  (magit-git-items "diff-files" "-z" "--name-only"
+                   (and nomodules "--ignore-submodules")
+                   "--" files))
+
+(defun magit-staged-files (&optional nomodules files)
+  (magit-git-items "diff-index" "-z" "--name-only" "--cached"
+                   (and nomodules "--ignore-submodules")
+                   (magit-headish) "--" files))
+
+(defun magit-staged-binary-files ()
+  (--mapcat (and (string-match "^-\t-\t\\(.+\\)" it)
+                 (list (match-string 1 it)))
+            (magit-git-items "diff" "-z" "--cached"
+                             "--numstat" "--ignore-submodules")))
+
+(defun magit-unmerged-files ()
+  (magit-git-items "diff-files" "-z" "--name-only" "--diff-filter=U"))
+
+(defun magit-ignored-files ()
+  (magit-git-items "ls-files" "-z" "--others" "--ignored"
+                   "--exclude-standard" "--directory"))
+
+(defun magit-revision-files (rev)
+  (magit-with-toplevel
+    (magit-git-items "ls-tree" "-z" "-r" "--name-only" rev)))
+
+(defun magit-changed-files (rev-or-range &optional other-rev)
+  "Return list of files the have changed between two revisions.
+If OTHER-REV is non-nil, REV-OR-RANGE should be a revision, not a
+range.  Otherwise, it can be any revision or range accepted by
+\"git diff\" (i.e., <rev>, <revA>..<revB>, or <revA>...<revB>)."
+  (magit-with-toplevel
+    (magit-git-items "diff" "-z" "--name-only" rev-or-range other-rev)))
+
+(defun magit-renamed-files (revA revB)
+  (--map (cons (nth 1 it) (nth 2 it))
+         (-partition 3 (magit-git-items
+                        "diff-tree" "-r" "--diff-filter=R" "-z" "-M"
+                        revA revB))))
+
+(defun magit-file-status (&rest args)
+  (with-temp-buffer
+    (save-excursion (magit-git-insert "status" "-z" args))
+    (let ((pos (point)) status)
+      (while (> (skip-chars-forward "[:print:]") 0)
+        (let ((x (char-after     pos))
+              (y (char-after (1+ pos)))
+              (file (buffer-substring (+ pos 3) (point))))
+          (forward-char)
+          (if (memq x '(?R ?C))
+              (progn
+                (setq pos (point))
+                (skip-chars-forward "[:print:]")
+                (push (list file (buffer-substring pos (point)) x y) status)
+                (forward-char))
+            (push (list file nil x y) status)))
+        (setq pos (point)))
+      status)))
+
+(defcustom magit-cygwin-mount-points
+  (when (eq system-type 'windows-nt)
+    (cl-sort (--map (if (string-match "^\\(.*\\) on \\(.*\\) type" it)
+                        (cons (file-name-as-directory (match-string 2 it))
+                              (file-name-as-directory (match-string 1 it)))
+                      (lwarn '(magit) :error
+                             "Failed to parse Cygwin mount: %S" it))
+                    ;; If --exec-path is not a native Windows path,
+                    ;; then we probably have a cygwin git.
+                    (let ((process-environment
+                           (append magit-git-environment process-environment)))
+                      (and (not (string-match-p
+                                 "\\`[a-zA-Z]:"
+                                 (car (process-lines
+                                       magit-git-executable "--exec-path"))))
+                           (ignore-errors (process-lines "mount")))))
+             #'> :key (pcase-lambda (`(,cyg . ,_win)) (length cyg))))
+  "Alist of (CYGWIN . WIN32) directory names.
+Sorted from longest to shortest CYGWIN name."
+  :package-version '(magit . "2.3.0")
+  :group 'magit-process
+  :type '(alist :key-type string :value-type directory))
+
+(defun magit-expand-git-file-name (filename)
+  (unless (file-name-absolute-p filename)
+    (setq filename (expand-file-name filename)))
+  (-if-let ((cyg . win)
+            (cl-assoc filename magit-cygwin-mount-points
+                      :test (lambda (f cyg) (string-prefix-p cyg f))))
+      (concat win (substring filename (length cyg)))
+    filename))
+
+(defun magit-convert-filename-for-git (filename)
+  "Convert FILENAME so that it can be passed to git.
+1. If it's a remote filename, then remove the remote part.
+2. Deal with an `windows-nt' Emacs vs. Cygwin Git incompatibility."
+  (if (file-name-absolute-p filename)
+      (-if-let ((cyg . win)
+                (cl-rassoc filename magit-cygwin-mount-points
+                           :test (lambda (f win) (string-prefix-p win f))))
+          (concat cyg (substring filename (length win)))
+        (or (file-remote-p filename 'localname)
+            filename))
+    filename))
+
+(defun magit-decode-git-path (path)
+  (if (eq (aref path 0) ?\")
+      (decode-coding-string (read path)
+                            (or magit-git-output-coding-system
+                                (car default-process-coding-system))
+                            t)
+    path))
+
+(defun magit-file-at-point ()
+  (magit-section-case
+    (file (oref it value))
+    (hunk (magit-section-parent-value it))))
+
+(defun magit-current-file ()
+  (or (magit-file-relative-name)
+      (magit-file-at-point)
+      (and (derived-mode-p 'magit-log-mode)
+           (car (nth 2 magit-refresh-args)))))
+
+;;; Predicates
+
+(defun magit-no-commit-p ()
+  "Return t if there is no commit in the current Git repository."
+  (not (magit-rev-verify "HEAD")))
+
+(defun magit-merge-commit-p (commit)
+  "Return t if COMMIT is a merge commit."
+  (> (length (magit-commit-parents commit)) 1))
+
+(defun magit-anything-staged-p (&optional ignore-submodules &rest files)
+  "Return t if there are any staged changes.
+If optional FILES is non-nil, then only changes to those files
+are considered."
+  (magit-git-failure "diff" "--quiet" "--cached"
+                     (and ignore-submodules "--ignore-submodules")
+                     "--" files))
+
+(defun magit-anything-unstaged-p (&optional ignore-submodules &rest files)
+  "Return t if there are any unstaged changes.
+If optional FILES is non-nil, then only changes to those files
+are considered."
+  (magit-git-failure "diff" "--quiet"
+                     (and ignore-submodules "--ignore-submodules")
+                     "--" files))
+
+(defun magit-anything-modified-p (&optional ignore-submodules &rest files)
+  "Return t if there are any staged or unstaged changes.
+If optional FILES is non-nil, then only changes to those files
+are considered."
+  (or (apply 'magit-anything-staged-p   ignore-submodules files)
+      (apply 'magit-anything-unstaged-p ignore-submodules files)))
+
+(defun magit-anything-unmerged-p (&rest files)
+  "Return t if there are any merge conflicts.
+If optional FILES is non-nil, then only conflicts in those files
+are considered."
+  (and (magit-git-string "ls-files" "--unmerged" files) t))
+
+(defun magit-module-worktree-p (module)
+  (magit-with-toplevel
+    (file-exists-p (expand-file-name (expand-file-name ".git" module)))))
+
+(defun magit-module-no-worktree-p (module)
+  (not (magit-module-worktree-p module)))
+
+;;; Revisions and References
+
+(defun magit-rev-parse (&rest args)
+  "Execute `git rev-parse ARGS', returning first line of output.
+If there is no output, return nil."
+  (apply #'magit-git-string "rev-parse" args))
+
+(defun magit-rev-parse-safe (&rest args)
+  "Execute `git rev-parse ARGS', returning first line of output.
+If there is no output, return nil.  Like `magit-rev-parse' but
+ignore `magit-git-debug'."
+  (apply #'magit-git-str "rev-parse" args))
+
+(defun magit-rev-parse-true (&rest args)
+  "Execute `git rev-parse ARGS', returning t if it prints \"true\".
+If it prints \"false\", then return nil.  For any other output
+signal an error."
+  (magit-git-true "rev-parse" args))
+
+(defun magit-rev-parse-false (&rest args)
+  "Execute `git rev-parse ARGS', returning t if it prints \"false\".
+If it prints \"true\", then return nil.  For any other output
+signal an error."
+  (magit-git-false "rev-parse" args))
+
+(defun magit-rev-parse-p (&rest args)
+  "Execute `git rev-parse ARGS', returning t if it prints \"true\".
+Return t if the first (and usually only) output line is the
+string \"true\", otherwise return nil."
+  (equal (magit-git-str "rev-parse" args) "true"))
+
+(defun magit-rev-verify (rev)
+  (magit-rev-parse-safe "--verify" rev))
+
+(defun magit-rev-verify-commit (rev)
+  "Return full hash for REV if it names an existing commit."
+  (magit-rev-verify (concat rev "^{commit}")))
+
+(defun magit-rev-equal (a b)
+  (magit-git-success "diff" "--quiet" a b))
+
+(defun magit-rev-eq (a b)
+  (equal (magit-rev-verify a)
+         (magit-rev-verify b)))
+
+(defun magit-rev-ancestor-p (a b)
+  "Return non-nil if commit A is an ancestor of commit B."
+  (magit-git-success "merge-base" "--is-ancestor" a b))
+
+(defun magit-rev-head-p (rev)
+  (or (equal rev "HEAD")
+      (and rev
+           (not (string-match-p "\\.\\." rev))
+           (equal (magit-rev-parse rev)
+                  (magit-rev-parse "HEAD")))))
+
+(defun magit-rev-author-p (rev)
+  "Return t if the user is the author of REV.
+More precisely return t if `user.name' is equal to the author
+name of REV and/or `user.email' is equal to the author email
+of REV."
+  (or (equal (magit-get "user.name")  (magit-rev-format "%an" rev))
+      (equal (magit-get "user.email") (magit-rev-format "%ae" rev))))
+
+(defun magit-rev-name (rev &optional pattern)
+  "Return a symbolic name for REV.
+PATTERN is passed to the `--refs' flag of `git-name-rev' and can
+be used to limit the result to a matching ref.  When structured
+as \"refs/<subdir>/*\", PATTERN is taken as a namespace.  In this
+case, the name returned by `git-name-rev' is discarded if it
+corresponds to a ref outside of the namespace."
+  (--when-let (magit-git-string "name-rev" "--name-only" "--no-undefined"
+                                (and pattern (concat "--refs=" pattern))
+                                rev)
+    ;; We can't use name-rev's --exclude to filter out "*/PATTERN"
+    ;; because --exclude wasn't added until Git v2.13.0.
+    (if (and pattern
+             (string-match-p "\\`refs/[^/]+/\\*\\'" pattern))
+        (let ((namespace (substring pattern 0 -1)))
+          (unless (and (string-match-p namespace it)
+                       (not (magit-rev-verify (concat namespace it))))
+            it))
+      it)))
+
+(defun magit-rev-branch (rev)
+  (--when-let (magit-rev-name rev "refs/heads/*")
+    (unless (string-match-p "[~^]" it) it)))
+
+(defun magit-get-shortname (rev)
+  (let* ((fn (apply-partially 'magit-rev-name rev))
+         (name (or (funcall fn "refs/tags/*")
+                   (funcall fn "refs/heads/*")
+                   (funcall fn "refs/remotes/*"))))
+    (cond ((not name)
+           (magit-rev-parse "--short" rev))
+          ((string-match "^\\(?:tags\\|remotes\\)/\\(.+\\)" name)
+           (if (magit-ref-ambiguous-p (match-string 1 name))
+               name
+             (match-string 1 name)))
+          (t (magit-ref-maybe-qualify name)))))
+
+(defun magit-name-branch (rev &optional lax)
+  (or (magit-name-local-branch rev)
+      (magit-name-remote-branch rev)
+      (and lax (or (magit-name-local-branch rev t)
+                   (magit-name-remote-branch rev t)))))
+
+(defun magit-name-local-branch (rev &optional lax)
+  (--when-let (magit-rev-name rev "refs/heads/*")
+    (and (or lax (not (string-match-p "[~^]" it))) it)))
+
+(defun magit-name-remote-branch (rev &optional lax)
+  (--when-let (magit-rev-name rev "refs/remotes/*")
+    (and (or lax (not (string-match-p "[~^]" it)))
+         (substring it 8))))
+
+(defun magit-name-tag (rev &optional lax)
+  (--when-let (magit-rev-name rev "refs/tags/*")
+    (and (or lax (not (string-match-p "[~^]" it)))
+         (substring it 5))))
+
+(defun magit-ref-fullname (name)
+  "Return fully qualified refname for NAME.
+If NAME is ambiguous, return nil.  NAME may include suffixes such
+as \"^1\" and \"~3\".  "
+  (save-match-data
+    (if (string-match "\\`\\([^^~]+\\)\\(.*\\)" name)
+        (--when-let (magit-rev-parse "--symbolic-full-name"
+                                     (match-string 1 name))
+          (concat it (match-string 2 name)))
+      (error "`name' has an unrecognized format"))))
+
+(defun magit-ref-ambiguous-p (name)
+  (not (magit-ref-fullname name)))
+
+(cl-defun magit-ref-maybe-qualify (name &optional (prefix "heads/"))
+  "If NAME is ambiguous, prepend PREFIX to it."
+  (concat (and (magit-ref-ambiguous-p name)
+               prefix)
+          name))
+
+(defun magit-ref-exists-p (ref)
+  (magit-git-success "show-ref" "--verify" ref))
+
+(defun magit-ref-equal (a b)
+  "Return t if the refs A and B are `equal'.
+A symbolic-ref pointing to some ref, is `equal' to that ref,
+as are two symbolic-refs pointing to the same ref."
+  (equal (magit-ref-fullname a)
+         (magit-ref-fullname b)))
+
+(defun magit-ref-eq (a b)
+  "Return t if the refs A and B are `eq'.
+A symbolic-ref is `eq' to itself, but not to the ref it points
+to, or to some other symbolic-ref that points to the same ref."
+  (let ((symbolic-a (magit-symbolic-ref-p a))
+        (symbolic-b (magit-symbolic-ref-p b)))
+    (or (and symbolic-a
+             symbolic-b
+             (equal a b))
+        (and (not symbolic-a)
+             (not symbolic-b)
+             (magit-ref-equal a b)))))
+
+(defun magit-headish ()
+  "Return \"HEAD\" or if that doesn't exist the hash of the empty tree."
+  (if (magit-no-commit-p)
+      (magit-git-string "mktree")
+    "HEAD"))
+
+(defun magit-branch-at-point ()
+  (magit-section-case
+    (branch (oref it value))
+    (commit (magit-name-branch (oref it value)))))
+
+(defun magit-local-branch-at-point ()
+  (magit-section-case
+    (branch (let ((branch (magit-ref-maybe-qualify (oref it value))))
+              (when (member branch (magit-list-local-branch-names))
+                branch)))
+    (commit (magit-name-local-branch (oref it value)))))
+
+(defun magit-remote-branch-at-point ()
+  (magit-section-case
+    (branch (let ((branch (oref it value)))
+              (when (member branch (magit-list-remote-branch-names))
+                branch)))
+    (commit (magit-name-remote-branch (oref it value)))))
+
+(defun magit-commit-at-point ()
+  (or (magit-section-when commit)
+      (and (derived-mode-p 'magit-revision-mode)
+           (car magit-refresh-args))))
+
+(defun magit-branch-or-commit-at-point ()
+  (or magit-buffer-refname
+      (magit-section-case
+        (branch (magit-ref-maybe-qualify (oref it value)))
+        (commit (let ((rev (oref it value)))
+                  (or (magit-name-branch rev)
+                      (magit-get-shortname rev)
+                      rev)))
+        (tag (magit-ref-maybe-qualify (oref it value) "tags/")))
+      (thing-at-point 'git-revision t)
+      (and (derived-mode-p 'magit-revision-mode
+                           'magit-merge-preview-mode)
+           (car magit-refresh-args))))
+
+(defun magit-tag-at-point ()
+  (magit-section-case
+    (tag    (oref it value))
+    (commit (magit-name-tag (oref it value)))))
+
+(defun magit-stash-at-point ()
+  (magit-section-when stash))
+
+(defun magit-remote-at-point ()
+  (magit-section-case
+    (remote (oref it value))
+    (branch (magit-section-parent-value it))))
+
+(defun magit-module-at-point (&optional predicate)
+  (magit-section-when
+      '(submodule
+        [file modules-unpulled-from-upstream]
+        [file modules-unpulled-from-pushremote]
+        [file modules-unpushed-to-upstream]
+        [file modules-unpushed-to-pushremote])
+    (let ((module (oref it value)))
+      (and (or (not predicate)
+               (funcall predicate module))
+           module))))
+
+(defun magit-get-current-branch ()
+  "Return the refname of the currently checked out branch.
+Return nil if no branch is currently checked out."
+  (magit-git-string "symbolic-ref" "--short" "HEAD"))
+
+(defvar magit-get-previous-branch-timeout 0.5
+  "Maximum time to spend in `magit-get-previous-branch'.
+Given as a number of seconds.")
+
+(defun magit-get-previous-branch ()
+  "Return the refname of the previously checked out branch.
+Return nil if no branch can be found in the `HEAD' reflog
+which is different from the current branch and still exists.
+The amount of time spent searching is limited by
+`magit-get-previous-branch-timeout'."
+  (let ((t0 (float-time))
+        (current (magit-get-current-branch))
+        (i 1) prev)
+    (while (if (> (- (float-time) t0) magit-get-previous-branch-timeout)
+               (setq prev nil) ;; Timed out.
+             (and (setq prev (magit-rev-verify (format "@{-%i}" i)))
+                  (or (not (setq prev (magit-rev-branch prev)))
+                      (equal prev current))))
+      (cl-incf i))
+    prev))
+
+(defun magit-get-upstream-ref (&optional branch)
+  (and (or branch (setq branch (magit-get-current-branch)))
+       (let ((remote (magit-get "branch" branch "remote"))
+             (merge  (magit-get "branch" branch "merge")))
+         (when (and remote merge)
+           (cond ((string-equal remote ".") merge)
+                 ((string-prefix-p "refs/heads/" merge)
+                  (concat "refs/remotes/" remote "/" (substring merge 11))))))))
+
+(defun magit-get-upstream-branch (&optional branch verify)
+  (and (or branch (setq branch (magit-get-current-branch)))
+       (when-let ((remote (magit-get "branch" branch "remote"))
+                  (merge  (magit-get "branch" branch "merge")))
+         (and (string-prefix-p "refs/heads/" merge)
+              (let* ((upstream (substring merge 11))
+                     (upstream
+                      (cond ((string-equal remote ".")
+                             (propertize upstream 'face 'magit-branch-local))
+                            ((string-match-p "[@:]" remote)
+                             (propertize (concat remote " " upstream)
+                                         'face 'magit-branch-remote))
+                            (t
+                             (propertize (concat remote "/" upstream)
+                                         'face 'magit-branch-remote)))))
+                (and (or (not verify)
+                         (magit-rev-verify upstream))
+                     upstream))))))
+
+(defun magit-get-indirect-upstream-branch (branch &optional force)
+  (let ((remote (magit-get "branch" branch "remote")))
+    (and remote (not (equal remote "."))
+         ;; The user has opted in...
+         (or force
+             (--any (if (magit-git-success "check-ref-format" "--branch" it)
+                        (equal it branch)
+                      (string-match-p it branch))
+                    magit-branch-prefer-remote-upstream))
+         ;; and local BRANCH tracks a remote branch...
+         (let ((upstream (magit-get-upstream-branch branch)))
+           ;; whose upstream...
+           (and upstream
+                ;; has the same name as BRANCH and...
+                (equal (substring upstream (1+ (length remote))) branch)
+                ;; and can be fast-forwarded to BRANCH.
+                (magit-rev-ancestor-p upstream branch)
+                upstream)))))
+
+(defun magit-get-upstream-remote (&optional branch)
+  (and (or branch (setq branch (magit-get-current-branch)))
+       (magit-get "branch" branch "remote")))
+
+(defun magit-get-push-remote (&optional branch)
+  (or (and (or branch (setq branch (magit-get-current-branch)))
+           (magit-get "branch" branch "pushRemote"))
+      (magit-get "remote.pushDefault")))
+
+(defun magit-get-push-branch (&optional branch verify)
+  (and (or branch (setq branch (magit-get-current-branch)))
+       (when-let ((remote (magit-get-push-remote branch))
+                  (push-branch (concat remote "/" branch)))
+         (and (or (not verify)
+                  (magit-rev-verify push-branch))
+              push-branch))))
+
+(defun magit-get-@{push}-branch (&optional branch)
+  (let ((ref (magit-rev-parse "--symbolic-full-name"
+                              (concat branch "@{push}"))))
+    (when (and ref (string-prefix-p "refs/remotes/" ref))
+      (substring ref 13))))
+
+(defun magit-get-remote (&optional branch)
+  (when (or branch (setq branch (magit-get-current-branch)))
+    (let ((remote (magit-get "branch" branch "remote")))
+      (unless (equal remote ".")
+        remote))))
+
+(defun magit-get-some-remote (&optional branch)
+  (or (magit-get-remote branch)
+      (and (magit-branch-p "master")
+           (magit-get-remote "master"))
+      (let ((remotes (magit-list-remotes)))
+        (or (car (member "origin" remotes))
+            (car remotes)))))
+
+(defun magit-branch-merged-p (branch &optional target)
+  "Return non-nil if BRANCH is merged into its upstream and TARGET.
+
+TARGET defaults to the current branch.  If `HEAD' is detached and
+TARGET is nil, then always return nil.  As a special case, if
+TARGET is t, then return non-nil if BRANCH is merged into any one
+of the other local branches.
+
+If, and only if, BRANCH has an upstream, then only return non-nil
+if BRANCH is merged into both TARGET (as described above) as well
+as into its upstream."
+  (and (--if-let (and (magit-branch-p branch)
+                      (magit-get-upstream-branch branch))
+           (magit-git-success "merge-base" "--is-ancestor" branch it)
+         t)
+       (if (eq target t)
+           (delete (magit-name-local-branch branch)
+                   (magit-list-containing-branches branch))
+         (--when-let (or target (magit-get-current-branch))
+           (magit-git-success "merge-base" "--is-ancestor" branch it)))))
+
+(defun magit-split-branch-name (branch)
+  (cond ((member branch (magit-list-local-branch-names))
+         (cons "." branch))
+        ((string-match " " branch)
+         (pcase-let ((`(,url ,branch) (split-string branch " ")))
+           (cons url branch)))
+        ((string-match "/" branch)
+         (let ((remote (substring branch 0 (match-beginning 0))))
+           (if (save-match-data (member remote (magit-list-remotes)))
+               (cons remote (substring branch (match-end 0)))
+             (error "Invalid branch name %s" branch))))))
+
+(defun magit-get-current-tag (&optional rev with-distance)
+  "Return the closest tag reachable from REV.
+
+If optional REV is nil, then default to `HEAD'.
+If optional WITH-DISTANCE is non-nil then return (TAG COMMITS),
+if it is `dirty' return (TAG COMMIT DIRTY). COMMITS is the number
+of commits in `HEAD' but not in TAG and DIRTY is t if there are
+uncommitted changes, nil otherwise."
+  (--when-let (magit-git-str "describe" "--long" "--tags"
+                             (and (eq with-distance 'dirty) "--dirty") rev)
+    (save-match-data
+      (string-match
+       "\\(.+\\)-\\(?:0[0-9]*\\|\\([0-9]+\\)\\)-g[0-9a-z]+\\(-dirty\\)?$" it)
+      (if with-distance
+          `(,(match-string 1 it)
+            ,(string-to-number (or (match-string 2 it) "0"))
+            ,@(and (match-string 3 it) (list t)))
+        (match-string 1 it)))))
+
+(defun magit-get-next-tag (&optional rev with-distance)
+  "Return the closest tag from which REV is reachable.
+
+If optional REV is nil, then default to `HEAD'.
+If no such tag can be found or if the distance is 0 (in which
+case it is the current tag, not the next), return nil instead.
+If optional WITH-DISTANCE is non-nil, then return (TAG COMMITS)
+where COMMITS is the number of commits in TAG but not in REV."
+  (--when-let (magit-git-str "describe" "--contains" (or rev "HEAD"))
+    (save-match-data
+      (when (string-match "^[^^~]+" it)
+        (setq it (match-string 0 it))
+        (unless (equal it (magit-get-current-tag rev))
+          (if with-distance
+              (list it (car (magit-rev-diff-count it rev)))
+            it))))))
+
+(defvar magit-list-refs-namespaces
+  '("refs/heads" "refs/remotes" "refs/tags" "refs/pull"))
+
+(defun magit-list-refs (&optional namespaces format sortby)
+  "Return list of references.
+
+When NAMESPACES is non-nil, list refs from these namespaces
+rather than those from `magit-list-refs-namespaces'.
+
+FORMAT is passed to the `--format' flag of `git for-each-ref'
+and defaults to \"%(refname)\".  If the format is \"%(refname)\"
+or \"%(refname:short)\", then drop the symbolic-ref \"HEAD\".
+
+SORTBY is a key or list of keys to pass to the `--sort' flag of
+`git for-each-ref'.  When nil, use `magit-list-refs-sortby'"
+  (unless format
+    (setq format "%(refname)"))
+  (let ((refs (magit-git-lines "for-each-ref"
+                               (concat "--format=" format)
+                               (--map (concat "--sort=" it)
+                                      (pcase (or sortby magit-list-refs-sortby)
+                                        ((and val (pred stringp)) (list val))
+                                        ((and val (pred listp)) val)))
+                               (or namespaces magit-list-refs-namespaces))))
+    (if (member format '("%(refname)" "%(refname:short)"))
+        (--remove (string-match-p "\\(\\`\\|/\\)HEAD\\'" it) refs)
+      refs)))
+
+(defun magit-list-branches ()
+  (magit-list-refs (list "refs/heads" "refs/remotes")))
+
+(defun magit-list-local-branches ()
+  (magit-list-refs "refs/heads"))
+
+(defun magit-list-remote-branches (&optional remote)
+  (magit-list-refs (concat "refs/remotes/" remote)))
+
+(defun magit-list-related-branches (relation &optional commit arg)
+  (--remove (string-match-p "\\(\\`(HEAD\\|HEAD -> \\)" it)
+            (--map (substring it 2)
+                   (magit-git-lines "branch" arg relation commit))))
+
+(defun magit-list-containing-branches (&optional commit arg)
+  (magit-list-related-branches "--contains" commit arg))
+
+(defun magit-list-publishing-branches (&optional commit)
+  (--filter (magit-rev-ancestor-p commit it)
+            magit-published-branches))
+
+(defun magit-list-merged-branches (&optional commit arg)
+  (magit-list-related-branches "--merged" commit arg))
+
+(defun magit-list-unmerged-branches (&optional commit arg)
+  (magit-list-related-branches "--no-merged" commit arg))
+
+(defun magit-list-unmerged-to-upstream-branches ()
+  (--filter (when-let ((upstream (magit-get-upstream-branch it)))
+              (member it (magit-list-unmerged-branches upstream)))
+            (magit-list-local-branch-names)))
+
+(defun magit-list-branches-pointing-at (commit)
+  (let ((re (format "\\`%s refs/\\(heads\\|remotes\\)/\\(.*\\)\\'"
+                   (magit-rev-verify commit))))
+    (--keep (and (string-match re it)
+                 (let ((name (match-string 2 it)))
+                   (and (not (string-suffix-p "HEAD" name))
+                        name)))
+            (magit-git-lines "show-ref"))))
+
+(defun magit-list-refnames (&optional namespaces)
+  (magit-list-refs namespaces "%(refname:short)"))
+
+(defun magit-list-branch-names ()
+  (magit-list-refnames (list "refs/heads" "refs/remotes")))
+
+(defun magit-list-local-branch-names ()
+  (magit-list-refnames "refs/heads"))
+
+(defun magit-list-remote-branch-names (&optional remote relative)
+  (if (and remote relative)
+      (let ((regexp (format "^refs/remotes/%s/\\(.+\\)" remote)))
+        (--mapcat (when (string-match regexp it)
+                    (list (match-string 1 it)))
+                  (magit-list-remote-branches remote)))
+    (magit-list-refnames (concat "refs/remotes/" remote))))
+
+(defun magit-format-refs (format &rest args)
+  (let ((lines (magit-git-lines
+                "for-each-ref" (concat "--format=" format)
+                (or args (list "refs/heads" "refs/remotes" "refs/tags")))))
+    (if (string-match-p "\f" format)
+        (--map (split-string it "\f") lines)
+      lines)))
+
+(defun magit-list-remotes ()
+  (magit-git-lines "remote"))
+
+(defun magit-list-tags ()
+  (magit-git-lines "tag"))
+
+(defun magit-list-stashes (&optional format)
+  (magit-git-lines "stash" "list" (concat "--format=" (or format "%gd"))))
+
+(defun magit-list-active-notes-refs ()
+  "Return notes refs according to `core.notesRef' and `notes.displayRef'."
+  (magit-git-lines "for-each-ref" "--format=%(refname)"
+                   (or (magit-get "core.notesRef") "refs/notes/commits")
+                   (magit-get-all "notes.displayRef")))
+
+(defun magit-list-notes-refnames ()
+  (--map (substring it 6) (magit-list-refnames "refs/notes")))
+
+(defun magit-remote-list-tags (remote)
+  (--keep (and (not (string-match-p "\\^{}$" it))
+               (substring it 51))
+          (magit-git-lines "ls-remote" "--tags" remote)))
+
+(defun magit-remote-list-branches (remote)
+  (--keep (and (not (string-match-p "\\^{}$" it))
+               (substring it 52))
+          (magit-git-lines "ls-remote" "--heads" remote)))
+
+(defun magit-remote-list-refs (remote)
+  (--keep (and (not (string-match-p "\\^{}$" it))
+               (substring it 41))
+          (magit-git-lines "ls-remote" remote)))
+
+(defun magit-list-module-paths ()
+  (--mapcat (and (string-match "^160000 [0-9a-z]\\{40\\} 0\t\\(.+\\)$" it)
+                 (list (match-string 1 it)))
+            (magit-git-items "ls-files" "-z" "--stage")))
+
+(defun magit-get-submodule-name (path)
+  "Return the name of the submodule at PATH.
+PATH has to be relative to the super-repository."
+  (cadr (split-string
+         (car (or (magit-git-items
+                   "config" "-z"
+                   "-f" (expand-file-name ".gitmodules" (magit-toplevel))
+                   "--get-regexp" "^submodule\\..*\\.path$"
+                   (concat "^" (regexp-quote (directory-file-name path)) "$"))
+                  (error "No such submodule `%s'" path)))
+         "\n")))
+
+(defun magit-list-worktrees ()
+  (let (worktrees worktree)
+    (dolist (line (let ((magit-git-global-arguments
+                         ;; KLUDGE At least in v2.8.3 this triggers a segfault.
+                         (remove "--no-pager" magit-git-global-arguments)))
+                    (magit-git-lines "worktree" "list" "--porcelain")))
+      (cond ((string-prefix-p "worktree" line)
+             (push (setq worktree (list (substring line 9) nil nil nil))
+                   worktrees))
+            ((string-equal line "bare")
+             (let* ((default-directory (car worktree))
+                    (wt (and (not (magit-get-boolean "core.bare"))
+                             (magit-get "core.worktree"))))
+               (if (and wt (file-exists-p (expand-file-name wt)))
+                   (progn (setf (nth 0 worktree) (expand-file-name wt))
+                          (setf (nth 2 worktree) (magit-rev-parse "HEAD"))
+                          (setf (nth 3 worktree) (magit-get-current-branch)))
+                 (setf (nth 1 worktree) t))))
+            ((string-prefix-p "HEAD" line)
+             (setf (nth 2 worktree) (substring line 5)))
+            ((string-prefix-p "branch" line)
+             (setf (nth 3 worktree) (substring line 18)))
+            ((string-equal line "detached"))))
+    (nreverse worktrees)))
+
+(defun magit-symbolic-ref-p (name)
+  (magit-git-success "symbolic-ref" "--quiet" name))
+
+(defun magit-ref-p (rev)
+  (or (car (member rev (magit-list-refs)))
+      (car (member rev (magit-list-refnames)))))
+
+(defun magit-branch-p (rev)
+  (or (car (member rev (magit-list-branches)))
+      (car (member rev (magit-list-branch-names)))))
+
+(defun magit-local-branch-p (rev)
+  (or (car (member rev (magit-list-local-branches)))
+      (car (member rev (magit-list-local-branch-names)))))
+
+(defun magit-remote-branch-p (rev)
+  (or (car (member rev (magit-list-remote-branches)))
+      (car (member rev (magit-list-remote-branch-names)))))
+
+(defun magit-branch-set-face (branch)
+  (propertize branch 'face (if (magit-local-branch-p branch)
+                               'magit-branch-local
+                             'magit-branch-remote)))
+
+(defun magit-tag-p (rev)
+  (car (member rev (magit-list-tags))))
+
+(defun magit-remote-p (string)
+  (car (member string (magit-list-remotes))))
+
+(defun magit-rev-diff-count (a b)
+  "Return the commits in A but not B and vice versa.
+Return a list of two integers: (A>B B>A)."
+  (mapcar 'string-to-number
+          (split-string (magit-git-string "rev-list"
+                                          "--count" "--left-right"
+                                          (concat a "..." b))
+                        "\t")))
+
+(defun magit-abbrev-length ()
+  (--if-let (magit-get "core.abbrev")
+      (string-to-number it)
+    ;; Guess the length git will be using based on an example
+    ;; abbreviation.  Actually HEAD's abbreviation might be an
+    ;; outlier, so use the shorter of the abbreviations for two
+    ;; commits.  When a commit does not exist, then fall back
+    ;; to the default of 7.  See #3034.
+    (min (--if-let (magit-rev-parse "--short" "HEAD")  (length it) 7)
+         (--if-let (magit-rev-parse "--short" "HEAD~") (length it) 7))))
+
+(defun magit-abbrev-arg (&optional arg)
+  (format "--%s=%d" (or arg "abbrev") (magit-abbrev-length)))
+
+(defun magit-rev-abbrev (rev)
+  (magit-rev-parse (magit-abbrev-arg "short") rev))
+
+(defun magit-commit-children (commit &optional args)
+  (mapcar #'car
+          (--filter (member commit (cdr it))
+                    (--map (split-string it " ")
+                           (magit-git-lines
+                            "log" "--format=%H %P"
+                            (or args (list "--branches" "--tags" "--remotes"))
+                            "--not" commit)))))
+
+(defun magit-commit-parents (commit)
+  (--when-let (magit-git-string "rev-list" "-1" "--parents" commit)
+    (cdr (split-string it))))
+
+(defun magit-patch-id (rev)
+  (with-temp-buffer
+    (magit-process-file
+     shell-file-name nil '(t nil) nil shell-command-switch
+     (let ((exec (shell-quote-argument magit-git-executable)))
+       (format "%s diff-tree -u %s | %s patch-id" exec rev exec)))
+    (car (split-string (buffer-string)))))
+
+(defun magit-rev-format (format &optional rev args)
+  (let ((str (magit-git-string "show" "--no-patch"
+                               (concat "--format=" format) args
+                               (if rev (concat rev "^{commit}") "HEAD") "--")))
+    (unless (string-equal str "")
+      str)))
+
+(defun magit-rev-insert-format (format &optional rev args)
+  (magit-git-insert "show" "--no-patch"
+                    (concat "--format=" format) args
+                    (if rev (concat rev "^{commit}") "HEAD") "--"))
+
+(defun magit-format-rev-summary (rev)
+  (--when-let (magit-rev-format "%h %s" rev)
+    (string-match " " it)
+    (put-text-property 0 (match-beginning 0) 'face 'magit-hash it)
+    it))
+
+(defvar magit-ref-namespaces
+  '(("\\`HEAD\\'"                  . magit-head)
+    ("\\`refs/tags/\\(.+\\)"       . magit-tag)
+    ("\\`refs/heads/\\(.+\\)"      . magit-branch-local)
+    ("\\`refs/remotes/\\(.+\\)"    . magit-branch-remote)
+    ("\\`refs/bisect/\\(bad\\)"    . magit-bisect-bad)
+    ("\\`refs/bisect/\\(skip.*\\)" . magit-bisect-skip)
+    ("\\`refs/bisect/\\(good.*\\)" . magit-bisect-good)
+    ("\\`refs/stash$"              . magit-refname-stash)
+    ("\\`refs/wip/\\(.+\\)"        . magit-refname-wip)
+    ("\\`refs/pullreqs/\\(.+\\)"   . magit-refname-pullreq)
+    ("\\`\\(bad\\):"               . magit-bisect-bad)
+    ("\\`\\(skip\\):"              . magit-bisect-skip)
+    ("\\`\\(good\\):"              . magit-bisect-good)
+    ("\\`\\(.+\\)"                 . magit-refname))
+  "How refs are formatted for display.
+
+Each entry controls how a certain type of ref is displayed, and
+has the form (REGEXP . FACE).  REGEXP is a regular expression
+used to match full refs.  The first entry whose REGEXP matches
+the reference is used.  The first regexp submatch becomes the
+\"label\" that represents the ref and is propertized with FONT.")
+
+(defun magit-format-ref-labels (string)
+  ;; To support Git <2.2.0, we remove the surrounding parentheses here
+  ;; rather than specifying that STRING should be generated with Git's
+  ;; "%D" placeholder.
+  (setq string (->> string
+                    (replace-regexp-in-string "\\`\\s-*(" "")
+                    (replace-regexp-in-string ")\\s-*\\'" "")))
+  (save-match-data
+    (let ((regexp "\\(, \\|tag: \\|HEAD -> \\)")
+          names)
+      (if (and (derived-mode-p 'magit-log-mode)
+               (member "--simplify-by-decoration" (cadr magit-refresh-args)))
+          (let ((branches (magit-list-local-branch-names))
+                (re (format "^%s/.+" (regexp-opt (magit-list-remotes)))))
+            (setq names
+                  (--map (cond ((string-equal it "HEAD")     it)
+                               ((string-prefix-p "refs/" it) it)
+                               ((member it branches) (concat "refs/heads/" it))
+                               ((string-match re it) (concat "refs/remotes/" it))
+                               (t                    (concat "refs/" it)))
+                         (split-string
+                          (replace-regexp-in-string "tag: " "refs/tags/" string)
+                          regexp t))))
+        (setq names (split-string string regexp t)))
+      (let (state head tags branches remotes other combined)
+        (dolist (ref names)
+          (let* ((face (cdr (--first (string-match (car it) ref)
+                                     magit-ref-namespaces)))
+                 (name (propertize (or (match-string 1 ref) ref) 'face face)))
+            (cl-case face
+              ((magit-bisect-bad magit-bisect-skip magit-bisect-good)
+               (setq state name))
+              (magit-head
+               (setq head (propertize "@" 'face 'magit-head)))
+              (magit-tag            (push name tags))
+              (magit-branch-local   (push name branches))
+              (magit-branch-remote  (push name remotes))
+              (t                    (push name other)))))
+        (setq remotes
+              (-keep
+               (lambda (name)
+                 (if (string-match "\\`\\([^/]*\\)/\\(.*\\)\\'" name)
+                     (let ((r (match-string 1 name))
+                           (b (match-string 2 name)))
+                       (and (not (equal b "HEAD"))
+                            (if (equal (concat "refs/remotes/" name)
+                                       (magit-git-string
+                                        "symbolic-ref"
+                                        (format "refs/remotes/%s/HEAD" r)))
+                                (propertize name
+                                            'face 'magit-branch-remote-head)
+                              name)))
+                   name))
+               remotes))
+        (dolist (name branches)
+          (let ((push (car (member (magit-get-push-branch name) remotes))))
+            (when push
+              (setq remotes (delete push remotes))
+              (string-match "^[^/]*/" push)
+              (setq push (substring push 0 (match-end 0))))
+            (if (equal name (magit-get-current-branch))
+                (setq head
+                      (concat push
+                              (propertize name 'face 'magit-branch-current)))
+              (push (concat push name) combined))))
+        (mapconcat #'identity
+                   (-flatten `(,state
+                               ,head
+                               ,@(nreverse tags)
+                               ,@(nreverse combined)
+                               ,@(nreverse remotes)
+                               ,@other))
+                   " ")))))
+
+(defun magit-object-type (object)
+  (magit-git-string "cat-file" "-t" object))
+
+(defmacro magit-with-blob (commit file &rest body)
+  (declare (indent 2)
+           (debug (form form body)))
+  `(with-temp-buffer
+     (let ((buffer-file-name ,file))
+       (save-excursion
+         (magit-git-insert "cat-file" "-p"
+                           (concat ,commit ":" buffer-file-name)))
+       (decode-coding-inserted-region
+        (point-min) (point-max) buffer-file-name t nil nil t)
+       ,@body)))
+
+(defmacro magit-with-temp-index (tree arg &rest body)
+  (declare (indent 2) (debug (form form body)))
+  (let ((file (cl-gensym "file")))
+    `(let ((magit--refresh-cache nil)
+           (,file (magit-convert-filename-for-git
+                   (make-temp-name (magit-git-dir "index.magit.")))))
+       (unwind-protect
+           (progn (--when-let ,tree
+                    (or (magit-git-success "read-tree" ,arg it
+                                           (concat "--index-output=" ,file))
+                        (error "Cannot read tree %s" it)))
+                  (if (file-remote-p default-directory)
+                      (let ((magit-tramp-process-environment
+                             (cons (concat "GIT_INDEX_FILE=" ,file)
+                                   magit-tramp-process-environment)))
+                        ,@body)
+                    (let ((process-environment
+                           (cons (concat "GIT_INDEX_FILE=" ,file)
+                                 process-environment)))
+                      ,@body)))
+         (ignore-errors
+           (delete-file (concat (file-remote-p default-directory) ,file)))))))
+
+(defun magit-commit-tree (message &optional tree &rest parents)
+  (magit-git-string "commit-tree" "--no-gpg-sign" "-m" message
+                    (--mapcat (list "-p" it) (delq nil parents))
+                    (or tree
+                        (magit-git-string "write-tree")
+                        (error "Cannot write tree"))))
+
+(defun magit-commit-worktree (message &optional arg &rest other-parents)
+  (magit-with-temp-index "HEAD" arg
+    (and (magit-update-files (magit-unstaged-files))
+         (apply #'magit-commit-tree message nil "HEAD" other-parents))))
+
+(defun magit-update-files (files)
+  (magit-git-success "update-index" "--add" "--remove" "--" files))
+
+(defun magit-update-ref (ref message rev &optional stashish)
+  (let ((magit--refresh-cache nil))
+    (or (if (not (version< (magit-git-version) "2.6.0"))
+            (zerop (magit-call-git "update-ref" "--create-reflog"
+                                   "-m" message ref rev
+                                   (or (magit-rev-verify ref) "")))
+          ;; `--create-reflog' didn't exist before v2.6.0
+          (let ((oldrev  (magit-rev-verify ref))
+                (logfile (magit-git-dir (concat "logs/" ref))))
+            (unless (file-exists-p logfile)
+              (when oldrev
+                (magit-git-success "update-ref" "-d" ref oldrev))
+              (make-directory (file-name-directory logfile) t)
+              (with-temp-file logfile)
+              (when (and oldrev (not stashish))
+                (magit-git-success "update-ref" "-m" "enable reflog"
+                                   ref oldrev ""))))
+          (magit-git-success "update-ref" "-m" message ref rev
+                             (or (magit-rev-verify ref) "")))
+        (error "Cannot update %s with %s" ref rev))))
+
+(defconst magit-range-re
+  (concat "\\`\\([^ \t]*[^.]\\)?"       ; revA
+          "\\(\\.\\.\\.?\\)"            ; range marker
+          "\\([^.][^ \t]*\\)?\\'"))     ; revB
+
+(defun magit-split-range (range)
+  (and (string-match magit-range-re range)
+       (let ((beg (or (match-string 1 range) "HEAD"))
+             (end (or (match-string 3 range) "HEAD")))
+         (cons (if (string-equal (match-string 2 range) "...")
+                   (magit-git-string "merge-base" beg end)
+                 beg)
+               end))))
+
+(defvar magit-thingatpt--git-revision-chars "-./[:alnum:]@{}^~!"
+  "Characters allowable in filenames, excluding space and colon.")
+
+(put 'git-revision 'end-op
+     (lambda ()
+       (re-search-forward
+        (concat "\\=[" magit-thingatpt--git-revision-chars "]*")
+        nil t)))
+
+(put 'git-revision 'beginning-op
+     (lambda ()
+       (if (re-search-backward
+            (concat "[^" magit-thingatpt--git-revision-chars "]") nil t)
+           (forward-char)
+         (goto-char (point-min)))))
+
+(put 'git-revision 'thing-at-point 'magit-thingatpt--git-revision)
+
+(defun magit-thingatpt--git-revision ()
+  (--when-let (bounds-of-thing-at-point 'git-revision)
+    (let ((text (buffer-substring-no-properties (car it) (cdr it))))
+      (and (magit-rev-verify-commit text) text))))
+
+;;; Completion
+
+(defvar magit-revision-history nil)
+
+(defun magit-read-branch (prompt &optional secondary-default)
+  (magit-completing-read prompt (magit-list-branch-names)
+                         nil t nil 'magit-revision-history
+                         (or (magit-branch-at-point)
+                             secondary-default
+                             (magit-get-current-branch))))
+
+(defun magit-read-branch-or-commit (prompt &optional secondary-default)
+  (or (magit-completing-read prompt (cons "HEAD" (magit-list-refnames))
+                             nil nil nil 'magit-revision-history
+                             (or (magit-branch-or-commit-at-point)
+                                 secondary-default
+                                 (magit-get-current-branch)))
+      (user-error "Nothing selected")))
+
+(defun magit-read-range-or-commit (prompt &optional secondary-default)
+  (magit-read-range
+   prompt
+   (or (--when-let (magit-region-values '(commit branch) t)
+         (deactivate-mark)
+         (concat (car (last it)) ".." (car it)))
+       (magit-branch-or-commit-at-point)
+       secondary-default
+       (magit-get-current-branch))))
+
+(defun magit-read-range (prompt &optional default)
+  (magit-completing-read-multiple prompt
+                                  (magit-list-refnames)
+                                  "\\.\\.\\.?"
+                                  default 'magit-revision-history))
+
+(defun magit-read-remote-branch
+    (prompt &optional remote default local-branch require-match)
+  (let ((choice (magit-completing-read
+                 prompt
+                 (-union (and local-branch
+                              (if remote
+                                  (concat remote "/" local-branch)
+                                (--map (concat it "/" local-branch)
+                                       (magit-list-remotes))))
+                         (magit-list-remote-branch-names remote t))
+                 nil require-match nil 'magit-revision-history default)))
+    (if (or remote (string-match "\\`\\([^/]+\\)/\\(.+\\)" choice))
+        choice
+      (user-error "`%s' doesn't have the form REMOTE/BRANCH" choice))))
+
+(defun magit-read-refspec (prompt remote)
+  (magit-completing-read prompt
+                         (prog2 (message "Determining available refs...")
+                             (magit-remote-list-refs remote)
+                           (message "Determining available refs...done"))))
+
+(defun magit-read-local-branch (prompt &optional secondary-default)
+  (magit-completing-read prompt (magit-list-local-branch-names)
+                         nil t nil 'magit-revision-history
+                         (or (magit-local-branch-at-point)
+                             secondary-default
+                             (magit-get-current-branch))))
+
+(defun magit-read-local-branch-or-commit (prompt)
+  (let ((branches (magit-list-local-branch-names))
+        (commit (magit-commit-at-point)))
+    (or (magit-completing-read prompt
+                               (if commit (cons commit branches) branches)
+                               nil nil nil 'magit-revision-history
+                               (or (magit-local-branch-at-point) commit))
+                     (user-error "Nothing selected"))))
+
+(defun magit-read-local-branch-or-ref (prompt &optional secondary-default)
+  (magit-completing-read prompt (nconc (magit-list-local-branch-names)
+                                       (magit-list-refs "refs/"))
+                         nil t nil 'magit-revision-history
+                         (or (magit-local-branch-at-point)
+                             secondary-default
+                             (magit-get-current-branch))))
+
+(defun magit-read-other-branch
+    (prompt &optional exclude secondary-default no-require-match)
+  (let* ((current (magit-get-current-branch))
+         (atpoint (magit-branch-at-point))
+         (exclude (or exclude current))
+         (default (or (and (not (equal atpoint exclude)) atpoint)
+                      (and (not (equal current exclude)) current)
+                      secondary-default
+                      (magit-get-previous-branch))))
+    (magit-completing-read prompt (delete exclude (magit-list-branch-names))
+                           nil (not no-require-match)
+                           nil 'magit-revision-history default)))
+
+(defun magit-read-other-branch-or-commit
+    (prompt &optional exclude secondary-default)
+  (let* ((current (magit-get-current-branch))
+         (atpoint (magit-branch-or-commit-at-point))
+         (exclude (or exclude current))
+         (default (or (and (not (equal atpoint exclude)) atpoint)
+                      (and (not (equal current exclude)) current)
+                      secondary-default
+                      (magit-get-previous-branch))))
+    (or (magit-completing-read prompt (delete exclude (magit-list-refnames))
+                               nil nil nil 'magit-revision-history default)
+        (user-error "Nothing selected"))))
+
+(defun magit-read-other-local-branch
+    (prompt &optional exclude secondary-default no-require-match)
+  (let* ((current (magit-get-current-branch))
+         (atpoint (magit-local-branch-at-point))
+         (exclude (or exclude current))
+         (default (or (and (not (equal atpoint exclude)) atpoint)
+                      (and (not (equal current exclude)) current)
+                      secondary-default
+                      (magit-get-previous-branch))))
+    (magit-completing-read prompt
+                           (delete exclude (magit-list-local-branch-names))
+                           nil (not no-require-match)
+                           nil 'magit-revision-history default)))
+
+(defun magit-read-branch-prefer-other (prompt)
+  (let* ((current (magit-get-current-branch))
+         (commit  (magit-commit-at-point))
+         (atpoint (and commit (magit-list-branches-pointing-at commit))))
+    (magit-completing-read prompt (magit-list-branch-names)
+                           nil t nil 'magit-revision-history
+                           (or (magit-section-when 'branch)
+                               (and (not (cdr atpoint)) (car atpoint))
+                               (--first (not (equal it current)) atpoint)
+                               (magit-get-previous-branch)
+                               (car atpoint)))))
+
+(cl-defun magit-read-upstream-branch
+    (&optional (branch (magit-get-current-branch)) prompt)
+  (magit-completing-read
+   (or prompt (format "Change upstream of %s to" branch))
+   (-union (--map (concat it "/" branch)
+                  (magit-list-remotes))
+           (delete branch (magit-list-branch-names)))
+   nil nil nil 'magit-revision-history
+   (or (let ((r (magit-remote-branch-at-point))
+             (l (magit-branch-at-point)))
+         (when (and l (equal l branch))
+           (setq l nil))
+         (if magit-prefer-remote-upstream (or r l) (or l r)))
+       (let ((r (magit-branch-p "origin/master"))
+             (l (and (not (equal branch "master"))
+                     (magit-branch-p "master"))))
+         (if magit-prefer-remote-upstream (or r l) (or l r)))
+       (let ((previous (magit-get-previous-branch)))
+         (and (not (equal previous branch)) previous)))))
+
+(defun magit-read-starting-point (prompt &optional branch)
+  (or (magit-completing-read
+       (concat prompt
+               (and branch
+                    (if (bound-and-true-p ivy-mode)
+                        ;; Ivy-mode strips faces from prompt.
+                        (format  " `%s'" branch)
+                      (concat " "
+                              (propertize branch 'face 'magit-branch-local))))
+               " starting at")
+       (nconc (list "HEAD")
+              (magit-list-refnames)
+              (directory-files (magit-git-dir) nil "_HEAD\\'"))
+       nil nil nil 'magit-revision-history
+       (magit--default-starting-point))
+      (user-error "Nothing selected")))
+
+(defun magit--default-starting-point ()
+  (or (let ((r (magit-remote-branch-at-point))
+            (l (magit-local-branch-at-point)))
+        (if magit-prefer-remote-upstream (or r l) (or l r)))
+      (magit-commit-at-point)
+      (magit-stash-at-point)
+      (magit-get-current-branch)))
+
+(defun magit-read-tag (prompt &optional require-match)
+  (magit-completing-read prompt (magit-list-tags) nil
+                         require-match nil 'magit-revision-history
+                         (magit-tag-at-point)))
+
+(defun magit-read-stash (prompt)
+  (let ((stashes (magit-list-stashes)))
+    (magit-completing-read prompt stashes nil t nil nil
+                           (magit-stash-at-point)
+                           (car stashes))))
+
+(defun magit-read-remote (prompt &optional default use-only)
+  (let ((remotes (magit-list-remotes)))
+    (if (and use-only (= (length remotes) 1))
+        (car remotes)
+      (magit-completing-read prompt remotes
+                             nil t nil nil
+                             (or default
+                                 (magit-remote-at-point)
+                                 (magit-get-remote))))))
+
+(defun magit-read-remote-or-url (prompt &optional default)
+  (magit-completing-read prompt
+                         (nconc (magit-list-remotes)
+                                (list "https://" "git://" "git@"))
+                         nil nil nil nil
+                         (or default
+                             (magit-remote-at-point)
+                             (magit-get-remote))))
+
+(defun magit-read-module-path (prompt &optional predicate)
+  (magit-completing-read prompt (magit-list-module-paths)
+                         predicate t nil nil
+                         (magit-module-at-point predicate)))
+
+(defun magit-module-confirm (verb &optional predicate)
+  (let (modules)
+    (if current-prefix-arg
+        (progn
+          (setq modules (magit-list-module-paths))
+          (when predicate
+            (setq modules (-filter predicate modules)))
+          (unless modules
+            (if predicate
+                (user-error "No modules satisfying %s available" predicate)
+              (user-error "No modules available"))))
+      (setq modules (magit-region-values
+                     '(submodule
+                       [file modules-unpulled-from-upstream]
+                       [file modules-unpulled-from-pushremote]
+                       [file modules-unpushed-to-upstream]
+                       [file modules-unpushed-to-pushremote])))
+      (when modules
+        (when predicate
+          (setq modules (-filter predicate modules)))
+        (unless modules
+          (user-error "No modules satisfying %s selected" predicate))))
+    (if (> (length modules) 1)
+        (magit-confirm t nil (format "%s %%i modules" verb) nil modules)
+      (list (magit-read-module-path (format "%s module" verb) predicate)))))
+
+;;; Variables
+
+(defun magit-config-get-from-cached-list (key)
+  (gethash
+   ;; `git config --list' downcases first and last components of the key.
+   (--> key
+        (replace-regexp-in-string "\\`[^.]+" #'downcase it t t)
+        (replace-regexp-in-string "[^.]+\\'" #'downcase it t t))
+   (magit--with-refresh-cache (cons (magit-toplevel) 'config)
+     (let ((configs (make-hash-table :test 'equal)))
+       (dolist (conf (magit-git-items "config" "--list" "-z"))
+         (let* ((nl-pos (cl-position ?\n conf))
+                (key (substring conf 0 nl-pos))
+                (val (if nl-pos (substring conf (1+ nl-pos)) "")))
+           (puthash key (nconc (gethash key configs) (list val)) configs)))
+       configs))))
+
+(defun magit-get (&rest keys)
+  "Return the value of the Git variable specified by KEYS."
+  (car (last (apply 'magit-get-all keys))))
+
+(defun magit-get-all (&rest keys)
+  "Return all values of the Git variable specified by KEYS."
+  (let ((magit-git-debug nil)
+        (arg (and (or (null (car keys))
+                      (string-prefix-p "--" (car keys)))
+                  (pop keys)))
+        (key (mapconcat 'identity keys ".")))
+    (if (and magit--refresh-cache (not arg))
+        (magit-config-get-from-cached-list key)
+      (magit-git-items "config" arg "-z" "--get-all" key))))
+
+(defun magit-get-boolean (&rest keys)
+  "Return the boolean value of the Git variable specified by KEYS."
+  (let ((key (mapconcat 'identity keys ".")))
+    (if magit--refresh-cache
+        (equal "true" (car (last (magit-config-get-from-cached-list key))))
+      (equal (magit-git-str "config" "--bool" key) "true"))))
+
+(defun magit-set (value &rest keys)
+  "Set the value of the Git variable specified by KEYS to VALUE."
+  (let ((arg (and (or (null (car keys))
+                      (string-prefix-p "--" (car keys)))
+                  (pop keys)))
+        (key (mapconcat 'identity keys ".")))
+    (if value
+        (magit-git-success "config" arg key value)
+      (magit-git-success "config" arg "--unset" key))
+    value))
+
+(gv-define-setter magit-get (val &rest keys)
+  `(magit-set ,val ,@keys))
+
+(defun magit-set-all (values &rest keys)
+  "Set all values of the Git variable specified by KEYS to VALUES."
+  (let ((arg (and (or (null (car keys))
+                      (string-prefix-p "--" (car keys)))
+                  (pop keys)))
+        (var (mapconcat 'identity keys ".")))
+    (when (magit-get var)
+      (magit-call-git "config" arg "--unset-all" var))
+    (dolist (v values)
+      (magit-call-git "config" arg "--add" var v))))
+
+;;;; Variables in Popups
+
+(defun magit--format-popup-variable:value (variable width &optional global)
+  (concat variable
+          (make-string (max 1 (- width 3 (length variable))) ?\s)
+          (if-let ((value (magit-get (and global "--global") variable)))
+              (propertize value 'face 'magit-popup-option-value)
+            (propertize "unset" 'face 'magit-popup-disabled-argument))))
+
+(defun magit--format-popup-variable:values (variable width &optional global)
+  (concat variable
+          (make-string (max 1 (- width 3 (length variable))) ?\s)
+          (if-let ((values (magit-get-all (and global "--global") variable)))
+              (concat
+               (propertize (car values) 'face 'magit-popup-option-value)
+               (mapconcat
+                (lambda (value)
+                  (concat "\n" (make-string width ?\s)
+                          (propertize value
+                                      'face 'magit-popup-option-value)))
+                (cdr values) ""))
+            (propertize "unset" 'face 'magit-popup-disabled-argument))))
+
+(defun magit--set-popup-variable
+    (variable choices &optional default other)
+  (magit-set (--if-let (magit-git-string "config" "--local" variable)
+                 (cadr (member it choices))
+               (car choices))
+             variable)
+  (magit-with-pre-popup-buffer
+    (magit-refresh))
+  (message "%s %s" variable
+           (magit--format-popup-variable:choices*
+            variable choices default other)))
+
+(defun magit--format-popup-variable:choices
+    (variable choices &optional default other width)
+  (concat variable
+          (if width (make-string (- width (length variable)) ?\s) " ")
+          (magit--format-popup-variable:choices*
+           variable choices default other)))
+
+(defun magit--format-popup-variable:choices*
+    (variable choices &optional default other)
+  (let ((local  (magit-git-string "config" "--local"  variable))
+        (global (magit-git-string "config" "--global" variable)))
+    (when other
+      (setq other (--when-let (magit-get other)
+                    (concat other ":" it))))
+    (concat
+     (propertize "[" 'face 'magit-popup-disabled-argument)
+     (mapconcat
+      (lambda (choice)
+        (propertize choice 'face (if (equal choice local)
+                                     'magit-popup-option-value
+                                   'magit-popup-disabled-argument)))
+      choices
+      (propertize "|" 'face 'magit-popup-disabled-argument))
+     (when (or global other default)
+       (concat
+        (propertize "|" 'face 'magit-popup-disabled-argument)
+        (cond (global
+               (propertize (concat "global:" global)
+                           'face (cond (local
+                                        'magit-popup-disabled-argument)
+                                       ((member global choices)
+                                        'magit-popup-option-value)
+                                       (t
+                                        'font-lock-warning-face))))
+              (other
+               (propertize other
+                           'face (if local
+                                     'magit-popup-disabled-argument
+                                   'magit-popup-option-value)))
+              (default
+               (propertize (concat "default:" default)
+                           'face (if local
+                                     'magit-popup-disabled-argument
+                                   'magit-popup-option-value))))))
+     (propertize "]" 'face 'magit-popup-disabled-argument))))
+
+(provide 'magit-git)
+;;; magit-git.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-git.elc b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-git.elc
new file mode 100644
index 0000000000..7ec00ad7f4
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-git.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-imenu.el b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-imenu.el
new file mode 100644
index 0000000000..6434f9f3c8
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-imenu.el
@@ -0,0 +1,241 @@
+;;; magit-imenu.el --- Integrate Imenu in magit major modes  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2010-2018  The Magit Project Contributors
+;;
+;; You should have received a copy of the AUTHORS.md file which
+;; lists all contributors.  If not, see http://magit.vc/authors.
+
+;; Author: Damien Cassou <damien@cassou.me>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; Magit 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, or (at your option)
+;; any later version.
+;;
+;; Magit 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 Magit.  If not, see http://www.gnu.org/licenses.
+
+;;; Commentary:
+
+;; Emacs' major modes can facilitate navigation in their buffers by
+;; supporting Imenu.  In such major modes, launching Imenu (M-x imenu)
+;; makes Emacs display a list of items (e.g., function definitions in
+;; a programming major mode).  Selecting an item from this list moves
+;; point to this item.
+
+;; magit-imenu.el adds Imenu support to every major mode in Magit
+
+;;; Code:
+
+(eval-when-compile (require 'subr-x))
+
+(require 'magit)
+(require 'git-rebase)
+
+(defun magit-imenu--index-function (entry-types menu-types)
+  "Return an alist of imenu entries in current buffer.
+
+ENTRY-TYPES is a list of section types to be selected through
+`imenu'.
+
+MENU-TYPES is a list of section types containing elements of
+ENTRY-TYPES.  Elements of MENU-TYPES are are used to categories
+elements of ENTRY-TYPES.
+
+This function is used as a helper for functions set as
+`imenu-create-index-function'."
+  (let ((entries (make-hash-table :test 'equal)))
+    (goto-char (point-max))
+    (while (magit-section--backward-find
+            (lambda ()
+              (let* ((section (magit-current-section))
+                     (type (oref section type))
+                     (parent (oref section parent))
+                     (parent-type (oref parent type)))
+                (and (-contains-p entry-types type)
+                     (-contains-p menu-types parent-type)))))
+      (let* ((section (magit-current-section))
+             (name (buffer-substring-no-properties
+                    (line-beginning-position)
+                    (line-end-position)))
+             (parent (oref section parent))
+             (parent-title (buffer-substring-no-properties
+                            (oref parent start)
+                            (1- (oref parent content)))))
+        (puthash parent-title
+                 (cons (cons name (point))
+                       (gethash parent-title entries (list)))
+                 entries)))
+    (mapcar (lambda (menu-title)
+              (cons menu-title (gethash menu-title entries)))
+            (hash-table-keys entries))))
+
+;;; Log mode
+
+;;;###autoload
+(defun magit-imenu--log-prev-index-position-function ()
+  "Move point to previous line in current buffer.
+This function is used as a value for
+`imenu-prev-index-position-function'."
+  (magit-section--backward-find
+   (lambda ()
+     (-contains-p '(commit stash)
+                  (oref (magit-current-section) type)))))
+
+;;;###autoload
+(defun magit-imenu--log-extract-index-name-function ()
+  "Return imenu name for line at point.
+This function is used as a value for
+`imenu-extract-index-name-function'.  Point should be at the
+beginning of the line."
+  (save-match-data
+    (looking-at "\\([^ ]+\\)[ *|]+\\(.+\\)$")
+    (format "%s: %s"
+            (match-string-no-properties 1)
+            (match-string-no-properties 2))))
+
+;;; Diff mode
+
+;;;###autoload
+(defun magit-imenu--diff-prev-index-position-function ()
+  "Move point to previous file line in current buffer.
+This function is used as a value for
+`imenu-prev-index-position-function'."
+  (magit-section--backward-find
+   (lambda ()
+     (let ((section (magit-current-section)))
+       (and (magit-file-section-p section)
+            (not (equal (oref (oref section parent) type)
+                        'diffstat)))))))
+
+;;;###autoload
+(defun magit-imenu--diff-extract-index-name-function ()
+  "Return imenu name for line at point.
+This function is used as a value for
+`imenu-extract-index-name-function'.  Point should be at the
+beginning of the line."
+  (buffer-substring-no-properties (line-beginning-position)
+                                  (line-end-position)))
+
+;;; Status mode
+
+;;;###autoload
+(defun magit-imenu--status-create-index-function ()
+  "Return an alist of all imenu entries in current buffer.
+This function is used as a value for
+`imenu-create-index-function'."
+  (magit-imenu--index-function
+   '(file commit stash)
+   '(unpushed unstaged unpulled untracked staged stashes)))
+
+;;;; Refs mode
+
+;;;###autoload
+(defun magit-imenu--refs-create-index-function ()
+  "Return an alist of all imenu entries in current buffer.
+This function is used as a value for
+`imenu-create-index-function'."
+  (magit-imenu--index-function
+   '(branch commit tag)
+   '(local remote tags)))
+
+;;;; Cherry mode
+
+;;;###autoload
+(defun magit-imenu--cherry-create-index-function ()
+  "Return an alist of all imenu entries in current buffer.
+This function is used as a value for
+`imenu-create-index-function'."
+  (magit-imenu--index-function
+   '(commit)
+   '(cherries)))
+
+;;;; Submodule list mode
+
+;;;###autoload
+(defun magit-imenu--submodule-prev-index-position-function ()
+  "Move point to previous line in magit-submodule-list buffer.
+This function is used as a value for
+`imenu-prev-index-position-function'."
+  (unless (bobp)
+    (forward-line -1)))
+
+;;;###autoload
+(defun magit-imenu--submodule-extract-index-name-function ()
+  "Return imenu name for line at point.
+This function is used as a value for
+`imenu-extract-index-name-function'.  Point should be at the
+beginning of the line."
+  (elt (tabulated-list-get-entry) 0))
+
+;;;; Repolist mode
+
+;;;###autoload
+(defun magit-imenu--repolist-prev-index-position-function ()
+  "Move point to previous line in magit-repolist buffer.
+This function is used as a value for
+`imenu-prev-index-position-function'."
+  (unless (bobp)
+    (forward-line -1)))
+
+;;;###autoload
+(defun magit-imenu--repolist-extract-index-name-function ()
+  "Return imenu name for line at point.
+This function is used as a value for
+`imenu-extract-index-name-function'.  Point should be at the
+beginning of the line."
+  (let ((entry (tabulated-list-get-entry)))
+    (format "%s (%s)"
+            (elt entry 0)
+            (elt entry (1- (length entry))))))
+
+;;;; Process mode
+
+;;;###autoload
+(defun magit-imenu--process-prev-index-position-function ()
+  "Move point to previous process in magit-process buffer.
+This function is used as a value for
+`imenu-prev-index-position-function'."
+  (magit-section--backward-find
+   (lambda ()
+     (eq (oref (magit-current-section) type) 'process))))
+
+;;;###autoload
+(defun magit-imenu--process-extract-index-name-function ()
+  "Return imenu name for line at point.
+This function is used as a value for
+`imenu-extract-index-name-function'.  Point should be at the
+beginning of the line."
+  (buffer-substring-no-properties (line-beginning-position)
+                                  (line-end-position)))
+
+;;;; Rebase mode
+
+;;;###autoload
+(defun magit-imenu--rebase-prev-index-position-function ()
+  "Move point to previous commit in git-rebase buffer.
+This function is used as a value for
+`imenu-prev-index-position-function'."
+  (catch 'found
+    (while (not (bobp))
+      (git-rebase-backward-line)
+      (when (git-rebase-line-p)
+        (throw 'found t)))))
+
+;;;###autoload
+(defun magit-imenu--rebase-extract-index-name-function ()
+  "Return imenu name for line at point.
+This function is used as a value for
+`imenu-extract-index-name-function'.  Point should be at the
+beginning of the line."
+  (buffer-substring-no-properties (line-beginning-position)
+                                  (line-end-position)))
+
+(provide 'magit-imenu)
+;;; magit-imenu.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-imenu.elc b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-imenu.elc
new file mode 100644
index 0000000000..b1897a7b56
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-imenu.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-log.el b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-log.el
new file mode 100644
index 0000000000..b3b0254287
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-log.el
@@ -0,0 +1,1675 @@
+;;; magit-log.el --- inspect Git history  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2010-2018  The Magit Project Contributors
+;;
+;; You should have received a copy of the AUTHORS.md file which
+;; lists all contributors.  If not, see http://magit.vc/authors.
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; Magit 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, or (at your option)
+;; any later version.
+;;
+;; Magit 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 Magit.  If not, see http://www.gnu.org/licenses.
+
+;;; Commentary:
+
+;; This library implements support for looking at Git logs, including
+;; special logs like reflogs and cherry-logs, as well as for selecting
+;; a commit from a log.
+
+;;; Code:
+
+(require 'magit-core)
+(require 'magit-diff)
+
+(declare-function magit-blob-visit "magit-files" (blob-or-file line))
+(declare-function magit-insert-head-branch-header "magit-status"
+                  (&optional branch))
+(declare-function magit-insert-upstream-branch-header "magit-status"
+                  (&optional branch pull keyword))
+(declare-function magit-read-file-from-rev "magit-files"
+                  (rev prompt &optional default))
+(declare-function magit-show-commit "magit-diff"
+                  (arg1 &optional arg2 arg3 arg4))
+(defvar magit-refs-focus-column-width)
+(defvar magit-refs-margin)
+(defvar magit-refs-show-commit-count)
+(defvar magit-buffer-margin)
+(defvar magit-status-margin)
+(defvar magit-status-sections-hook)
+
+(require 'ansi-color)
+(require 'crm)
+(require 'which-func)
+
+(defvar bookmark-make-record-function)
+
+;;; Options
+;;;; Log Mode
+
+(defgroup magit-log nil
+  "Inspect and manipulate Git history."
+  :link '(info-link "(magit)Logging")
+  :group 'magit-modes)
+
+(defcustom magit-log-mode-hook nil
+  "Hook run after entering Magit-Log mode."
+  :group 'magit-log
+  :type 'hook)
+
+(defcustom magit-log-arguments '("-n256" "--graph" "--decorate")
+  "The log arguments used in `magit-log-mode' buffers."
+  :package-version '(magit . "2.3.0")
+  :group 'magit-git-arguments
+  :group 'magit-log
+  :type '(repeat (string :tag "Argument")))
+
+(defcustom magit-log-remove-graph-args '("--follow" "--grep" "-G" "-S" "-L")
+  "The log arguments that cause the `--graph' argument to be dropped."
+  :package-version '(magit . "2.3.0")
+  :group 'magit-log
+  :type '(repeat (string :tag "Argument"))
+  :options '("--follow" "--grep" "-G" "-S" "-L"))
+
+(defcustom magit-log-revision-headers-format "\
+%+b
+Author:    %aN <%aE>
+Committer: %cN <%cE>"
+  "Additional format string used with the `++header' argument."
+  :package-version '(magit . "2.3.0")
+  :group 'magit-log
+  :type 'string)
+
+(defcustom magit-log-auto-more nil
+  "Insert more log entries automatically when moving past the last entry.
+Only considered when moving past the last entry with
+`magit-goto-*-section' commands."
+  :group 'magit-log
+  :type 'boolean)
+
+(defcustom magit-log-margin '(t age magit-log-margin-width t 18)
+  "Format of the margin in `magit-log-mode' buffers.
+
+The value has the form (INIT STYLE WIDTH AUTHOR AUTHOR-WIDTH).
+
+If INIT is non-nil, then the margin is shown initially.
+STYLE controls how to format the committer date.  It can be one
+  of `age' (to show the age of the commit), `age-abbreviated' (to
+  abbreviate the time unit to a character), or a string (suitable
+  for `format-time-string') to show the actual date.
+WIDTH controls the width of the margin.  This exists for forward
+  compatibility and currently the value should not be changed.
+AUTHOR controls whether the name of the author is also shown by
+  default.
+AUTHOR-WIDTH has to be an integer.  When the name of the author
+  is shown, then this specifies how much space is used to do so."
+  :package-version '(magit . "2.9.0")
+  :group 'magit-log
+  :group 'magit-margin
+  :type magit-log-margin--custom-type
+  :initialize 'magit-custom-initialize-reset
+  :set (apply-partially #'magit-margin-set-variable 'magit-log-mode))
+
+(defcustom magit-log-show-refname-after-summary nil
+  "Whether to show refnames after commit summaries.
+This is useful if you use really long branch names."
+  :package-version '(magit . "2.2.0")
+  :group 'magit-log
+  :type 'boolean)
+
+(defcustom magit-log-highlight-keywords t
+  "Whether to highlight bracketed keywords in commit summaries."
+  :package-version '(magit . "2.12.0")
+  :group 'magit-log
+  :type 'boolean)
+
+(defcustom magit-log-header-line-function 'magit-log-header-line-sentence
+  "Function used to generate text shown in header line of log buffers."
+  :package-version '(magit . "2.12.0")
+  :group 'magit-log
+  :type '(choice (function-item magit-log-header-line-arguments)
+                 (function-item magit-log-header-line-sentence)
+                 function))
+
+(defface magit-log-graph
+  '((((class color) (background light)) :foreground "grey30")
+    (((class color) (background  dark)) :foreground "grey80"))
+  "Face for the graph part of the log output."
+  :group 'magit-faces)
+
+(defface magit-log-author
+  '((((class color) (background light)) :foreground "firebrick")
+    (((class color) (background  dark)) :foreground "tomato"))
+  "Face for the author part of the log output."
+  :group 'magit-faces)
+
+(defface magit-log-date
+  '((((class color) (background light)) :foreground "grey30")
+    (((class color) (background  dark)) :foreground "grey80"))
+  "Face for the date part of the log output."
+  :group 'magit-faces)
+
+(defface magit-header-line-log-select
+  '((t :inherit bold))
+  "Face for the `header-line' in `magit-log-select-mode'."
+  :group 'magit-faces)
+
+;;;; File Log
+
+(defcustom magit-log-buffer-file-locked t
+  "Whether `magit-log-buffer-file' uses a dedicated buffer."
+  :package-version '(magit . "2.7.0")
+  :group 'magit-commands
+  :group 'magit-log
+  :type 'boolean)
+
+;;;; Select Mode
+
+(defcustom magit-log-select-arguments '("-n256" "--decorate")
+  "The log arguments used in `magit-log-select-mode' buffers."
+  :package-version '(magit . "2.3.0")
+  :group 'magit-log
+  :type '(repeat (string :tag "Argument")))
+
+(defcustom magit-log-select-show-usage 'both
+  "Whether to show usage information when selecting a commit from a log.
+The message can be shown in the `echo-area' or the `header-line', or in
+`both' places.  If the value isn't one of these symbols, then it should
+be nil, in which case no usage information is shown."
+  :package-version '(magit . "2.1.0")
+  :group 'magit-log
+  :type '(choice (const :tag "in echo-area" echo-area)
+                 (const :tag "in header-line" header-line)
+                 (const :tag "in both places" both)
+                 (const :tag "nowhere")))
+
+(defcustom magit-log-select-margin
+  (list (nth 0 magit-log-margin)
+        (nth 1 magit-log-margin)
+        'magit-log-margin-width t
+        (nth 4 magit-log-margin))
+  "Format of the margin in `magit-log-select-mode' buffers.
+
+The value has the form (INIT STYLE WIDTH AUTHOR AUTHOR-WIDTH).
+
+If INIT is non-nil, then the margin is shown initially.
+STYLE controls how to format the committer date.  It can be one
+  of `age' (to show the age of the commit), `age-abbreviated' (to
+  abbreviate the time unit to a character), or a string (suitable
+  for `format-time-string') to show the actual date.
+WIDTH controls the width of the margin.  This exists for forward
+  compatibility and currently the value should not be changed.
+AUTHOR controls whether the name of the author is also shown by
+  default.
+AUTHOR-WIDTH has to be an integer.  When the name of the author
+  is shown, then this specifies how much space is used to do so."
+  :package-version '(magit . "2.9.0")
+  :group 'magit-log
+  :group 'magit-margin
+  :type magit-log-margin--custom-type
+  :initialize 'magit-custom-initialize-reset
+  :set-after '(magit-log-margin)
+  :set (apply-partially #'magit-margin-set-variable 'magit-log-select-mode))
+
+;;;; Cherry Mode
+
+(defcustom magit-cherry-sections-hook
+  '(magit-insert-cherry-headers
+    magit-insert-cherry-commits)
+  "Hook run to insert sections into the cherry buffer."
+  :package-version '(magit . "2.1.0")
+  :group 'magit-log
+  :type 'hook)
+
+(defcustom magit-cherry-margin
+  (list (nth 0 magit-log-margin)
+        (nth 1 magit-log-margin)
+        'magit-log-margin-width t
+        (nth 4 magit-log-margin))
+  "Format of the margin in `magit-cherry-mode' buffers.
+
+The value has the form (INIT STYLE WIDTH AUTHOR AUTHOR-WIDTH).
+
+If INIT is non-nil, then the margin is shown initially.
+STYLE controls how to format the committer date.  It can be one
+  of `age' (to show the age of the commit), `age-abbreviated' (to
+  abbreviate the time unit to a character), or a string (suitable
+  for `format-time-string') to show the actual date.
+WIDTH controls the width of the margin.  This exists for forward
+  compatibility and currently the value should not be changed.
+AUTHOR controls whether the name of the author is also shown by
+  default.
+AUTHOR-WIDTH has to be an integer.  When the name of the author
+  is shown, then this specifies how much space is used to do so."
+  :package-version '(magit . "2.9.0")
+  :group 'magit-log
+  :group 'magit-margin
+  :type magit-log-margin--custom-type
+  :initialize 'magit-custom-initialize-reset
+  :set-after '(magit-log-margin)
+  :set (apply-partially #'magit-margin-set-variable 'magit-cherry-mode))
+
+;;;; Reflog Mode
+
+(defcustom magit-reflog-arguments '("-n256")
+  "The log arguments used in `magit-reflog-mode' buffers."
+  :package-version '(magit . "2.3.0")
+  :group 'magit-git-arguments
+  :type '(repeat (string :tag "Argument")))
+
+(defcustom magit-reflog-margin
+  (list (nth 0 magit-log-margin)
+        (nth 1 magit-log-margin)
+        'magit-log-margin-width nil
+        (nth 4 magit-log-margin))
+  "Format of the margin in `magit-reflog-mode' buffers.
+
+The value has the form (INIT STYLE WIDTH AUTHOR AUTHOR-WIDTH).
+
+If INIT is non-nil, then the margin is shown initially.
+STYLE controls how to format the committer date.  It can be one
+  of `age' (to show the age of the commit), `age-abbreviated' (to
+  abbreviate the time unit to a character), or a string (suitable
+  for `format-time-string') to show the actual date.
+WIDTH controls the width of the margin.  This exists for forward
+  compatibility and currently the value should not be changed.
+AUTHOR controls whether the name of the author is also shown by
+  default.
+AUTHOR-WIDTH has to be an integer.  When the name of the author
+  is shown, then this specifies how much space is used to do so."
+  :package-version '(magit . "2.9.0")
+  :group 'magit-log
+  :group 'magit-margin
+  :type magit-log-margin--custom-type
+  :initialize 'magit-custom-initialize-reset
+  :set-after '(magit-log-margin)
+  :set (apply-partially #'magit-margin-set-variable 'magit-reflog-mode))
+
+(defface magit-reflog-commit '((t :foreground "green"))
+  "Face for commit commands in reflogs."
+  :group 'magit-faces)
+
+(defface magit-reflog-amend '((t :foreground "magenta"))
+  "Face for amend commands in reflogs."
+  :group 'magit-faces)
+
+(defface magit-reflog-merge '((t :foreground "green"))
+  "Face for merge, checkout and branch commands in reflogs."
+  :group 'magit-faces)
+
+(defface magit-reflog-checkout '((t :foreground "blue"))
+  "Face for checkout commands in reflogs."
+  :group 'magit-faces)
+
+(defface magit-reflog-reset '((t :foreground "red"))
+  "Face for reset commands in reflogs."
+  :group 'magit-faces)
+
+(defface magit-reflog-rebase '((t :foreground "magenta"))
+  "Face for rebase commands in reflogs."
+  :group 'magit-faces)
+
+(defface magit-reflog-cherry-pick '((t :foreground "green"))
+  "Face for cherry-pick commands in reflogs."
+  :group 'magit-faces)
+
+(defface magit-reflog-remote '((t :foreground "cyan"))
+  "Face for pull and clone commands in reflogs."
+  :group 'magit-faces)
+
+(defface magit-reflog-other '((t :foreground "cyan"))
+  "Face for other commands in reflogs."
+  :group 'magit-faces)
+
+;;;; Log Sections
+
+(defcustom magit-log-section-commit-count 10
+  "How many recent commits to show in certain log sections.
+How many recent commits `magit-insert-recent-commits' and
+`magit-insert-unpulled-from-upstream-or-recent' (provided
+the upstream isn't ahead of the current branch) show."
+  :package-version '(magit . "2.1.0")
+  :group 'magit-status
+  :type 'number)
+
+(defcustom magit-log-section-arguments '("-n256" "--decorate")
+  "The log arguments used in buffers that show other things besides logs."
+  :package-version '(magit . "2.4.0")
+  :group 'magit-git-arguments
+  :group 'magit-log
+  :group 'magit-status
+  :type '(repeat (string :tag "Argument")))
+
+;;; Commands
+;;;; Popups
+
+(defvar magit-log-popup
+  '(:variable magit-log-arguments
+    :man-page "git-log"
+    :switches ((?g "Show graph"              "--graph")
+               (?c "Show graph in color"     "--color")
+               (?d "Show refnames"           "--decorate")
+               (?S "Show signatures"         "--show-signature")
+               (?u "Show diffs"              "--patch")
+               (?s "Show diffstats"          "--stat")
+               (?h "Show header"             "++header" magit-log++header)
+               (?r "Show in reverse order"   "--reverse")
+               (?D "Simplify by decoration"  "--simplify-by-decoration")
+               (?f "Follow renames when showing single-file log" "--follow"))
+    :options  ((?n "Limit number of commits" "-n")
+               (?f "Limit to files"          "-- " magit-read-files)
+               (?a "Limit to author"         "--author=")
+               (?o "Order commits by"        "++order=" magit-log-select-order)
+               (?g "Search messages"         "--grep=")
+               (?G "Search changes"          "-G")
+               (?S "Search occurrences"      "-S")
+               (?L "Trace line evolution"    "-L" magit-read-file-trace))
+    :actions  ((?l "Log current"             magit-log-current)
+               (?L "Log local branches"      magit-log-branches)
+               (?r "Reflog current"          magit-reflog-current)
+               (?o "Log other"               magit-log)
+               (?b "Log all branches"        magit-log-all-branches)
+               (?O "Reflog other"            magit-reflog)
+               (?h "Log HEAD"                magit-log-head)
+               (?a "Log all references"      magit-log-all)
+               (?H "Reflog HEAD"             magit-reflog-head))
+    :default-action magit-log-current
+    :max-action-columns 3))
+
+(defvar magit-log-mode-refresh-popup
+  '(:variable magit-log-arguments
+    :man-page "git-log"
+    :switches ((?g "Show graph"              "--graph")
+               (?c "Show graph in color"     "--color")
+               (?d "Show refnames"           "--decorate")
+               (?S "Show signatures"         "--show-signature")
+               (?u "Show diffs"              "--patch")
+               (?s "Show diffstats"          "--stat")
+               (?r "Show in reverse order"   "--reverse")
+               (?D "Simplify by decoration"  "--simplify-by-decoration")
+               (?f "Follow renames when showing single-file log" "--follow"))
+    :options  ((?n "Limit number of commits" "-n")
+               (?f "Limit to files"          "-- " magit-read-files)
+               (?a "Limit to author"         "--author=")
+               (?o "Order commits by"        "++order=" magit-log-select-order)
+               (?g "Search messages"         "--grep=")
+               (?G "Search changes"          "-G")
+               (?S "Search occurrences"      "-S")
+               (?L "Trace line evolution"    "-L" magit-read-file-trace))
+    :actions  ((?g "Refresh"       magit-log-refresh)
+               (?L "Toggle margin" magit-toggle-margin)
+               (?s "Set defaults"  magit-log-set-default-arguments) nil
+               (?w "Save defaults" magit-log-save-default-arguments))
+    :max-action-columns 2))
+
+(defvar magit-reflog-mode-refresh-popup
+  '(:variable magit-reflog-arguments
+    :man-page "git-reflog"
+    :options  ((?n "Limit number of commits" "-n"))))
+
+(defvar magit-log-refresh-popup
+  '(:variable magit-log-arguments
+    :man-page "git-log"
+    :switches ((?g "Show graph"          "--graph")
+               (?c "Show graph in color" "--color")
+               (?d "Show refnames"       "--decorate"))
+    :options  ((?n "Limit number of commits" "-n")
+               (?o "Order commits by"        "++order=" magit-log-select-order))
+    :actions  ("Refresh"
+               (?g "buffer"                   magit-log-refresh)
+               (?s "buffer and set defaults"  magit-log-set-default-arguments)
+               (?w "buffer and save defaults" magit-log-save-default-arguments)
+               "Margin"
+               (?L "toggle visibility" magit-toggle-margin)
+               (?l "cycle style"       magit-cycle-margin-style)
+               (?d "toggle details"    magit-toggle-margin-details))
+    :max-action-columns 1))
+
+(magit-define-popup-keys-deferred 'magit-log-popup)
+(magit-define-popup-keys-deferred 'magit-log-mode-refresh-popup)
+(magit-define-popup-keys-deferred 'magit-log-refresh-popup)
+
+(defun magit-read-file-trace (&rest _ignored)
+  (let ((file  (magit-read-file-from-rev "HEAD" "File"))
+        (trace (magit-read-string "Trace")))
+    (if (string-match
+         "^\\(/.+/\\|:[^:]+\\|[0-9]+,[-+]?[0-9]+\\)\\(:\\)?$" trace)
+        (concat trace (or (match-string 2 trace) ":") file)
+      (user-error "Trace is invalid, see man git-log"))))
+
+(defun magit-log-select-order (&rest _ignored)
+  "Set one `--<value>-order' option in Git log.
+This encompasses the options `--author-date-order',
+`--date-order', and `--topo-order'."
+  (magit-read-char-case "Order commits by " t
+    (?t "[t]opography"     "topo")
+    (?a "[a]uthor date"    "author-date")
+    (?c "[c]ommitter date" "date")))
+
+;; This is a dummy procedure used to show help in `magit-log-popup'.
+(defun magit-log++header ()
+  "Insert a header after each revision summary in Git log.
+Customize `magit-log-revision-headers-format' to change this
+header."
+  nil)
+
+(defun magit-log-get-buffer-args ()
+  (cond ((and magit-use-sticky-arguments
+              (derived-mode-p 'magit-log-mode))
+         (list (nth 1 magit-refresh-args)
+               (nth 2 magit-refresh-args)))
+        ((and (eq magit-use-sticky-arguments t)
+              (--when-let (magit-mode-get-buffer 'magit-log-mode)
+                (with-current-buffer it
+                  (list (nth 1 magit-refresh-args)
+                        (nth 2 magit-refresh-args))))))
+        (t
+         (list (default-value 'magit-log-arguments) nil))))
+
+(defun magit-log-arguments (&optional refresh)
+  (cond ((memq magit-current-popup
+               '(magit-log-popup magit-log-refresh-popup))
+         (magit-popup-export-file-args magit-current-popup-args))
+        ((and refresh (not (derived-mode-p 'magit-log-mode)))
+         (list magit-log-section-arguments nil))
+        (t
+         (magit-log-get-buffer-args))))
+
+(defun magit-log-popup (arg)
+  "Popup console for log commands."
+  (interactive "P")
+  (let ((magit-log-refresh-popup
+         (pcase major-mode
+           (`magit-log-mode magit-log-mode-refresh-popup)
+           (_               magit-log-refresh-popup)))
+        (magit-log-arguments
+         (apply #'magit-popup-import-file-args (magit-log-get-buffer-args))))
+    (magit-invoke-popup 'magit-log-popup nil arg)))
+
+;;;###autoload
+(defun magit-log-buffer-file-popup ()
+  "Popup console for log commands.
+
+This is a variant of `magit-log-popup' which shows the same popup
+but which limits the log to the file being visited in the current
+buffer."
+  (interactive)
+  (if-let ((file (magit-file-relative-name)))
+      (let ((magit-log-arguments
+             (magit-popup-import-file-args
+              (if-let ((buffer (magit-mode-get-buffer 'magit-log-mode)))
+                  (with-current-buffer buffer
+                    (nth 2 magit-refresh-args))
+                (default-value 'magit-log-arguments))
+              (list file))))
+        (magit-invoke-popup 'magit-log-popup nil nil))
+    (user-error "Buffer isn't visiting a file")))
+
+(defun magit-log-refresh-popup (arg)
+  "Popup console for changing log arguments in the current buffer."
+  (interactive "P")
+  (magit-log-refresh-assert)
+  (let ((magit-log-refresh-popup
+         (cond ((derived-mode-p 'magit-log-select-mode)
+                magit-log-refresh-popup)
+               ((derived-mode-p 'magit-log-mode)
+                (let ((def (copy-sequence magit-log-refresh-popup)))
+                  (plist-put def :switches (plist-get magit-log-popup :switches))
+                  (plist-put def :options  (plist-get magit-log-popup :options))
+                  def))
+               (t
+                magit-log-refresh-popup)))
+        (magit-log-arguments
+         (cond ((derived-mode-p 'magit-log-select-mode)
+                (cadr magit-refresh-args))
+               ((derived-mode-p 'magit-log-mode)
+                (magit-popup-import-file-args (nth 1 magit-refresh-args)
+                                              (nth 2 magit-refresh-args)))
+               (t
+                magit-log-section-arguments))))
+    (magit-invoke-popup 'magit-log-refresh-popup nil arg)))
+
+;;;; Refresh Commands
+
+(defun magit-log-refresh (args files)
+  "Set the local log arguments for the current buffer."
+  (interactive (magit-log-arguments t))
+  (magit-log-refresh-assert)
+  (cond ((derived-mode-p 'magit-log-select-mode)
+         (setcar (cdr magit-refresh-args) args))
+        ((derived-mode-p 'magit-log-mode)
+         (setcdr magit-refresh-args (list args files)))
+        (t
+         (setq-local magit-log-section-arguments args)))
+  (magit-refresh))
+
+(defun magit-log-set-default-arguments (args files)
+  "Set the global log arguments for the current buffer."
+  (interactive (magit-log-arguments t))
+  (magit-log-refresh-assert)
+  (cond ((derived-mode-p 'magit-log-select-mode)
+         (customize-set-variable 'magit-log-select-arguments args)
+         (setcar (cdr magit-refresh-args) args))
+        ((derived-mode-p 'magit-log-mode)
+         (customize-set-variable 'magit-log-arguments args)
+         (setcdr magit-refresh-args (list args files)))
+        (t
+         (customize-set-variable 'magit-log-section-arguments args)
+         (kill-local-variable    'magit-log-section-arguments)))
+  (magit-refresh))
+
+(defun magit-log-save-default-arguments (args files)
+  "Set and save the global log arguments for the current buffer."
+  (interactive (magit-log-arguments t))
+  (magit-log-refresh-assert)
+  (cond ((derived-mode-p 'magit-log-select-mode)
+         (customize-save-variable 'magit-log-select-arguments args)
+         (setcar (cdr magit-refresh-args) args))
+        ((derived-mode-p 'magit-log-mode)
+         (customize-save-variable 'magit-log-arguments args)
+         (setcdr magit-refresh-args (list args files)))
+        (t
+         (customize-save-variable 'magit-log-section-arguments args)
+         (kill-local-variable     'magit-log-section-arguments)))
+  (magit-refresh))
+
+(defun magit-log-refresh-assert ()
+  (cond ((derived-mode-p 'magit-reflog-mode)
+         (user-error "Cannot change log arguments in reflog buffers"))
+        ((derived-mode-p 'magit-cherry-mode)
+         (user-error "Cannot change log arguments in cherry buffers"))))
+
+;;;; Log Commands
+
+(defvar magit-log-read-revs-map
+  (let ((map (make-sparse-keymap)))
+    (set-keymap-parent map crm-local-completion-map)
+    (define-key map "\s" 'self-insert-command)
+    map))
+
+(defun magit-log-read-revs (&optional use-current)
+  (or (and use-current (--when-let (magit-get-current-branch) (list it)))
+      (let ((collection `(,@(and (file-exists-p (magit-git-dir "FETCH_HEAD"))
+                                 (list "FETCH_HEAD"))
+                          ,@(magit-list-refnames))))
+        (split-string
+         (magit-completing-read-multiple "Log rev,s" collection
+                                         "\\(\\.\\.\\.?\\|[, ]\\)"
+                                         (or (magit-branch-or-commit-at-point)
+                                             (unless use-current
+                                               (magit-get-previous-branch)))
+                                         'magit-revision-history
+                                         magit-log-read-revs-map)
+         "[, ]" t))))
+
+;;;###autoload
+(defun magit-log-current (revs &optional args files)
+  "Show log for the current branch.
+When `HEAD' is detached or with a prefix argument show log for
+one or more revs read from the minibuffer."
+  (interactive (cons (magit-log-read-revs t)
+                     (magit-log-arguments)))
+  (magit-log revs args files))
+
+;;;###autoload
+(defun magit-log (revs &optional args files)
+  "Show log for one or more revs read from the minibuffer.
+The user can input any revision or revisions separated by a
+space, or even ranges, but only branches and tags, and a
+representation of the commit at point, are available as
+completion candidates."
+  (interactive (cons (magit-log-read-revs)
+                     (magit-log-arguments)))
+  (require 'magit)
+  (magit-mode-setup #'magit-log-mode revs args files)
+  (magit-log-goto-same-commit))
+
+;;;###autoload
+(defun magit-log-head (&optional args files)
+  "Show log for `HEAD'."
+  (interactive (magit-log-arguments))
+  (magit-log (list "HEAD") args files))
+
+;;;###autoload
+(defun magit-log-branches (&optional args files)
+  "Show log for all local branches and `HEAD'."
+  (interactive (magit-log-arguments))
+  (magit-log (if (magit-get-current-branch)
+                 (list "--branches")
+               (list "HEAD" "--branches"))
+             args files))
+
+;;;###autoload
+(defun magit-log-all-branches (&optional args files)
+  "Show log for all local and remote branches and `HEAD'."
+  (interactive (magit-log-arguments))
+  (magit-log (if (magit-get-current-branch)
+                 (list "--branches" "--remotes")
+               (list "HEAD" "--branches" "--remotes"))
+             args files))
+
+;;;###autoload
+(defun magit-log-all (&optional args files)
+  "Show log for all references and `HEAD'."
+  (interactive (magit-log-arguments))
+  (magit-log (if (magit-get-current-branch)
+                 (list "--all")
+               (list "HEAD" "--all"))
+             args files))
+
+;;;###autoload
+(defun magit-log-buffer-file (&optional follow beg end)
+  "Show log for the blob or file visited in the current buffer.
+With a prefix argument or when `--follow' is part of
+`magit-log-arguments', then follow renames.  When the region is
+active, restrict the log to the lines that the region touches."
+  (interactive
+   (cons current-prefix-arg
+         (and (region-active-p)
+              (magit-file-relative-name)
+              (save-restriction
+                (widen)
+                (list (line-number-at-pos (region-beginning))
+                      (line-number-at-pos
+                       (let ((end (region-end)))
+                         (if (char-after end)
+                             end
+                           ;; Ensure that we don't get the line number
+                           ;; of a trailing newline.
+                           (1- end)))))))))
+  (require 'magit)
+  (if-let ((file (magit-file-relative-name)))
+      (magit-mode-setup-internal
+       #'magit-log-mode
+       (list (list (or magit-buffer-refname
+                       (magit-get-current-branch)
+                       "HEAD"))
+             (let ((args (car (magit-log-arguments))))
+               (when (and follow (not (member "--follow" args)))
+                 (push "--follow" args))
+               (when (and (file-regular-p
+                           (expand-file-name file (magit-toplevel)))
+                          beg end)
+                 (setq args (cons (format "-L%s,%s:%s" beg end file)
+                                  (cl-delete "-L" args :test
+                                             'string-prefix-p)))
+                 (setq file nil))
+               args)
+             (and file (list file)))
+       magit-log-buffer-file-locked)
+    (user-error "Buffer isn't visiting a file"))
+  (magit-log-goto-same-commit))
+
+;;;###autoload
+(defun magit-log-trace-definition (file fn rev)
+  "Show log for the definition at point."
+  (interactive (list (or (magit-file-relative-name)
+                         (user-error "Buffer isn't visiting a file"))
+                     (which-function)
+                     (or magit-buffer-refname
+                         (magit-get-current-branch)
+                         "HEAD")))
+  (require 'magit)
+  (magit-mode-setup-internal
+   #'magit-log-mode
+   (list (list rev)
+         (cons (format "-L:%s:%s" fn file)
+               (cl-delete "-L" (car (magit-log-arguments))
+                          :test 'string-prefix-p))
+         nil)
+   magit-log-buffer-file-locked)
+  (magit-log-goto-same-commit))
+
+(defun magit-diff-trace-definition ()
+  "Show log for the definition at point in a diff."
+  (interactive)
+  (let (buf pos)
+    (save-window-excursion
+      (call-interactively #'magit-diff-visit-file)
+      (setq buf (current-buffer))
+      (setq pos (point)))
+    (save-excursion
+      (with-current-buffer buf
+        (goto-char pos)
+        (call-interactively #'magit-log-trace-definition)))))
+
+;;;###autoload
+(defun magit-reflog-current ()
+  "Display the reflog of the current branch."
+  (interactive)
+  (magit-reflog (magit-get-current-branch)))
+
+;;;###autoload
+(defun magit-reflog (ref)
+  "Display the reflog of a branch."
+  (interactive (list (magit-read-local-branch-or-ref "Show reflog for")))
+  (require 'magit)
+  (magit-mode-setup #'magit-reflog-mode ref magit-reflog-arguments))
+
+;;;###autoload
+(defun magit-reflog-head ()
+  "Display the `HEAD' reflog."
+  (interactive)
+  (magit-reflog "HEAD"))
+
+;;;; Limit Commands
+
+(defun magit-log-toggle-commit-limit ()
+  "Toggle the number of commits the current log buffer is limited to.
+If the number of commits is currently limited, then remove that
+limit.  Otherwise set it to 256."
+  (interactive)
+  (magit-log-set-commit-limit (lambda (&rest _) nil)))
+
+(defun magit-log-double-commit-limit ()
+  "Double the number of commits the current log buffer is limited to."
+  (interactive)
+  (magit-log-set-commit-limit '*))
+
+(defun magit-log-half-commit-limit ()
+  "Half the number of commits the current log buffer is limited to."
+  (interactive)
+  (magit-log-set-commit-limit '/))
+
+(defun magit-log-set-commit-limit (fn)
+  (let* ((val (car (magit-log-arguments t)))
+         (arg (--first (string-match "^-n\\([0-9]+\\)?$" it) val))
+         (num (and arg (string-to-number (match-string 1 arg))))
+         (num (if num (funcall fn num 2) 256)))
+    (setq val (delete arg val))
+    (setcar (cdr magit-refresh-args)
+            (if (and num (> num 0))
+                (cons (format "-n%i" num) val)
+              val)))
+  (magit-refresh))
+
+(defun magit-log-get-commit-limit ()
+  (--when-let (--first (string-match "^-n\\([0-9]+\\)?$" it)
+                       (car (magit-log-arguments t)))
+    (string-to-number (match-string 1 it))))
+
+;;;; Other Commands
+
+(defun magit-log-bury-buffer (&optional arg)
+  "Bury the current buffer or the revision buffer in the same frame.
+Like `magit-mode-bury-buffer' (which see) but with a negative
+prefix argument instead bury the revision buffer, provided it
+is displayed in the current frame."
+  (interactive "p")
+  (if (< arg 0)
+      (let* ((buf (magit-mode-get-buffer 'magit-revision-mode))
+             (win (and buf (get-buffer-window buf (selected-frame)))))
+        (if win
+            (with-selected-window win
+              (with-current-buffer buf
+                (magit-mode-bury-buffer (> (abs arg) 1))))
+          (user-error "No revision buffer in this frame")))
+    (magit-mode-bury-buffer (> arg 1))))
+
+;;;###autoload
+(defun magit-log-move-to-parent (&optional n)
+  "Move to the Nth parent of the current commit."
+  (interactive "p")
+  (when (derived-mode-p 'magit-log-mode)
+    (magit-section-when commit
+      (let ((parent-rev (format "%s^%s" (oref it value) (or n 1))))
+        (if-let ((parent-hash (magit-rev-parse "--short" parent-rev)))
+            (if-let ((section (--first (equal (oref it value)
+                                              parent-hash)
+                                       (magit-section-siblings it 'next))))
+                (magit-section-goto section)
+              (user-error
+               (substitute-command-keys
+                (concat "Parent " parent-hash " not found.  Try typing "
+                        "\\[magit-log-double-commit-limit] first"))))
+          (user-error "Parent %s does not exist" parent-rev))))))
+
+;;; Log Mode
+
+(defvar magit-log-mode-map
+  (let ((map (make-sparse-keymap)))
+    (set-keymap-parent map magit-mode-map)
+    (define-key map "\C-c\C-b" 'magit-go-backward)
+    (define-key map "\C-c\C-f" 'magit-go-forward)
+    (define-key map "\C-c\C-n" 'magit-log-move-to-parent)
+    (define-key map "=" 'magit-log-toggle-commit-limit)
+    (define-key map "+" 'magit-log-double-commit-limit)
+    (define-key map "-" 'magit-log-half-commit-limit)
+    (define-key map "q" 'magit-log-bury-buffer)
+    map)
+  "Keymap for `magit-log-mode'.")
+
+(define-derived-mode magit-log-mode magit-mode "Magit Log"
+  "Mode for looking at Git log.
+
+This mode is documented in info node `(magit)Log Buffer'.
+
+\\<magit-mode-map>\
+Type \\[magit-refresh] to refresh the current buffer.
+Type \\[magit-visit-thing] or \\[magit-diff-show-or-scroll-up] \
+to visit the commit at point.
+
+Type \\[magit-branch-popup] to see available branch commands.
+Type \\[magit-merge-popup] to merge the branch or commit at point.
+Type \\[magit-cherry-pick-popup] to apply the commit at point.
+Type \\[magit-reset] to reset `HEAD' to the commit at point.
+
+\\{magit-log-mode-map}"
+  :group 'magit-log
+  (hack-dir-local-variables-non-file-buffer)
+  (setq imenu-prev-index-position-function
+        'magit-imenu--log-prev-index-position-function)
+  (setq imenu-extract-index-name-function
+        'magit-imenu--log-extract-index-name-function)
+  (setq-local bookmark-make-record-function
+              'magit-bookmark--log-make-record))
+
+(defvar magit-log-disable-graph-hack-args
+  '("-G" "--grep" "--author")
+  "Arguments which disable the graph speedup hack.")
+
+(defun magit-log-refresh-buffer (revs args files)
+  (magit-set-header-line-format
+   (funcall magit-log-header-line-function revs args files))
+  (if (= (length files) 1)
+      (unless (magit-file-tracked-p (car files))
+        (setq args (cons "--full-history" args)))
+    (setq args (remove "--follow" args)))
+  (when (--any-p (string-match-p
+                  (concat "^" (regexp-opt magit-log-remove-graph-args)) it)
+                 args)
+    (setq args (remove "--graph" args)))
+  (unless (member "--graph" args)
+    (setq args (remove "--color" args)))
+  (when-let ((limit (magit-log-get-commit-limit))
+             (limit (* 2 limit)) ; increase odds for complete graph
+             (count (and (= (length revs) 1)
+                         (> limit 1024) ; otherwise it's fast enough
+                         (setq revs (car revs))
+                         (not (string-match-p "\\.\\." revs))
+                         (not (member revs '("--all" "--branches")))
+                         (-none-p (lambda (arg)
+                                    (--any-p (string-prefix-p it arg)
+                                             magit-log-disable-graph-hack-args))
+                                  args)
+                         (magit-git-string "rev-list" "--count"
+                                           "--first-parent" args revs))))
+    (setq revs (if (< (string-to-number count) limit)
+                   revs
+                 (format "%s~%s..%s" revs limit revs))))
+  (magit-insert-section (logbuf)
+    (magit-insert-log revs args files)))
+
+(defun magit-log-header-line-arguments (revs args files)
+  "Return string describing some of the used arguments."
+  (mapconcat (lambda (arg)
+               (if (string-match-p " " arg)
+                   (prin1 arg)
+                 arg))
+             `("git" "log" ,@args ,@revs "--" ,@files)
+             " "))
+
+(defun magit-log-header-line-sentence (revs args files)
+  "Return string containing all arguments."
+  (concat "Commits in "
+          (mapconcat #'identity revs " ")
+          (and (member "--reverse" args)
+               " in reverse")
+          (and files (concat " touching "
+                             (mapconcat 'identity files " ")))
+          (--some (and (string-prefix-p "-L" it)
+                       (concat " " it))
+                  args)))
+
+(defun magit-insert-log (revs &optional args files)
+  "Insert a log section.
+Do not add this to a hook variable."
+  (let ((magit-git-global-arguments
+         (remove "--literal-pathspecs" magit-git-global-arguments)))
+    (magit-git-wash (apply-partially #'magit-log-wash-log 'log)
+      "log"
+      (format "--format=%%h%s%%x00%s%%x00%%aN%%x00%%at%%x00%%s%s"
+              (if (member "--decorate" args) "%d" "")
+              (if (member "--show-signature" args)
+                  (progn (setq args (remove "--show-signature" args)) "%G?")
+                "")
+              (if (member "++header" args)
+                  (if (member "--graph" (setq args (remove "++header" args)))
+                      (concat "\n" magit-log-revision-headers-format "\n")
+                    (concat "\n" magit-log-revision-headers-format "\n"))
+                ""))
+      (progn
+        (--when-let (--first (string-match "^\\+\\+order=\\(.+\\)$" it) args)
+          (setq args (cons (format "--%s-order" (match-string 1 it))
+                           (remove it args))))
+        (when (member "--decorate" args)
+          (setq args (cons "--decorate=full" (remove "--decorate" args))))
+        (when (member "--reverse" args)
+          (setq args (remove "--graph" args)))
+        args)
+      "--use-mailmap" "--no-prefix" revs "--" files)))
+
+(defvar magit-commit-section-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map [remap magit-visit-thing] 'magit-show-commit)
+    (define-key map "a" 'magit-cherry-apply)
+    map)
+  "Keymap for `commit' sections.")
+
+(defvar magit-module-commit-section-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map [remap magit-visit-thing] 'magit-show-commit)
+    map)
+  "Keymap for `module-commit' sections.")
+
+(defconst magit-log-heading-re
+  (concat "^"
+          "\\(?4:[-_/|\\*o. ]*\\)"                 ; graph
+          "\\(?1:[0-9a-fA-F]+\\)"                  ; sha1
+          "\\(?3:[^\0\n]+)\\)?\0"                  ; refs
+          "\\(?7:[BGUXYREN]\\)?\0"                 ; gpg
+          "\\(?5:[^\0\n]*\\)\0"                    ; author
+          "\\(?6:[^\0\n]+\\)\0"                    ; date
+          "\\(?2:.*\\)$"))                         ; msg
+
+(defconst magit-log-cherry-re
+  (concat "^"
+          "\\(?8:[-+]\\) "                         ; cherry
+          "\\(?1:[0-9a-fA-F]+\\) "                 ; sha1
+          "\\(?2:.*\\)$"))                         ; msg
+
+(defconst magit-log-module-re
+  (concat "^"
+          "\\(?:\\(?11:[<>]\\) \\)?"               ; side
+          "\\(?1:[0-9a-fA-F]+\\) "                 ; sha1
+          "\\(?2:.*\\)$"))                         ; msg
+
+(defconst magit-log-bisect-vis-re
+  (concat "^"
+          "\\(?4:[-_/|\\*o. ]*\\)"                 ; graph
+          "\\(?1:[0-9a-fA-F]+\\)"                  ; sha1
+          "\\(?3:[^\0\n]+)\\)?\0"                  ; refs
+          "\\(?2:.*\\)$"))                         ; msg
+
+(defconst magit-log-bisect-log-re
+  (concat "^# "
+          "\\(?3:bad:\\|skip:\\|good:\\) "         ; "refs"
+          "\\[\\(?1:[^]\n]+\\)\\] "                ; sha1
+          "\\(?2:.*\\)$"))                         ; msg
+
+(defconst magit-log-reflog-re
+  (concat "^"
+          "\\(?1:[^\0\n]+\\)\0"                    ; sha1
+          "\\(?5:[^\0\n]*\\)\0"                    ; author
+          "\\(?:\\(?:[^@\n]+@{\\(?6:[^}\n]+\\)}\0" ; date
+          "\\(?10:merge \\|autosave \\|restart \\|[^:\n]+: \\)?" ; refsub
+          "\\(?2:.*\\)?\\)\\|\0\\)$"))             ; msg
+
+(defconst magit-reflog-subject-re
+  (concat "\\(?1:[^ ]+\\) ?"                       ; command
+          "\\(?2:\\(?: ?-[^ ]+\\)+\\)?"            ; option
+          "\\(?: ?(\\(?3:[^)]+\\))\\)?"))          ; type
+
+(defconst magit-log-stash-re
+  (concat "^"
+          "\\(?1:[^\0\n]+\\)\0"                    ; "sha1"
+          "\\(?5:[^\0\n]*\\)\0"                    ; author
+          "\\(?6:[^\0\n]+\\)\0"                    ; date
+          "\\(?2:.*\\)$"))                         ; msg
+
+(defvar magit-log-count nil)
+
+(defvar magit-log-format-message-function 'magit-log-propertize-keywords)
+
+(defun magit-log-wash-log (style args)
+  (setq args (-flatten args))
+  (when (and (member "--graph" args)
+             (member "--color" args))
+    (let ((ansi-color-apply-face-function
+           (lambda (beg end face)
+             (put-text-property beg end 'font-lock-face
+                                (or face 'magit-log-graph)))))
+      (ansi-color-apply-on-region (point-min) (point-max))))
+  (when (eq style 'cherry)
+    (reverse-region (point-min) (point-max)))
+  (let ((magit-log-count 0))
+    (magit-wash-sequence (apply-partially 'magit-log-wash-rev style
+                                          (magit-abbrev-length)))
+    (if (derived-mode-p 'magit-log-mode)
+        (when (eq magit-log-count (magit-log-get-commit-limit))
+          (magit-insert-section (longer)
+            (insert-text-button
+             (substitute-command-keys
+              (format "Type \\<%s>\\[%s] to show more history"
+                      'magit-log-mode-map
+                      'magit-log-double-commit-limit))
+             'action (lambda (_button)
+                       (magit-log-double-commit-limit))
+             'follow-link t
+             'mouse-face 'magit-section-highlight)))
+      (insert ?\n))))
+
+(cl-defun magit-log-wash-rev (style abbrev)
+  (when (derived-mode-p 'magit-log-mode)
+    (cl-incf magit-log-count))
+  (looking-at (pcase style
+                (`log        magit-log-heading-re)
+                (`cherry     magit-log-cherry-re)
+                (`module     magit-log-module-re)
+                (`reflog     magit-log-reflog-re)
+                (`stash      magit-log-stash-re)
+                (`bisect-vis magit-log-bisect-vis-re)
+                (`bisect-log magit-log-bisect-log-re)))
+  (magit-bind-match-strings
+      (hash msg refs graph author date gpg cherry _ refsub side) nil
+    (setq msg (substring-no-properties msg))
+    (when refs
+      (setq refs (substring-no-properties refs)))
+    (let ((align (or (eq style 'cherry)
+                     (not (member "--stat" (cadr magit-refresh-args)))))
+          (non-graph-re (if (eq style 'bisect-vis)
+                            magit-log-bisect-vis-re
+                          magit-log-heading-re)))
+      (magit-delete-line)
+      ;; If the reflog entries have been pruned, the output of `git
+      ;; reflog show' includes a partial line that refers to the hash
+      ;; of the youngest expired reflog entry.
+      (when (and (eq style 'reflog) (not date))
+        (cl-return-from magit-log-wash-rev t))
+      (magit-insert-section section (commit hash)
+        (pcase style
+          (`stash      (oset section type 'stash))
+          (`module     (oset section type 'module-commit))
+          (`bisect-log (setq hash (magit-rev-parse "--short" hash))))
+        (when cherry
+          (when (and (derived-mode-p 'magit-refs-mode)
+                     magit-refs-show-commit-count)
+            (insert (make-string (1- magit-refs-focus-column-width) ?\s)))
+          (insert (propertize cherry 'face (if (string= cherry "-")
+                                               'magit-cherry-equivalent
+                                             'magit-cherry-unmatched)))
+          (insert ?\s))
+        (when side
+          (insert (propertize side 'face (if (string= side "<")
+                                             'magit-cherry-equivalent
+                                           'magit-cherry-unmatched)))
+          (insert ?\s))
+        (when align
+          (insert (propertize hash 'face 'magit-hash) ?\s))
+        (when graph
+          (insert graph))
+        (unless align
+          (insert (propertize hash 'face 'magit-hash) ?\s))
+        (when (and refs (not magit-log-show-refname-after-summary))
+          (insert (magit-format-ref-labels refs) ?\s))
+        (when (eq style 'reflog)
+          (insert (format "%-2s " (1- magit-log-count)))
+          (when refsub
+            (insert (magit-reflog-format-subject
+                     (substring refsub 0 (if (string-match-p ":" refsub) -2 -1))))))
+        (when msg
+          (when gpg
+            (setq msg (propertize msg 'face
+                                  (pcase (aref gpg 0)
+                                    (?G 'magit-signature-good)
+                                    (?B 'magit-signature-bad)
+                                    (?U 'magit-signature-untrusted)
+                                    (?X 'magit-signature-expired)
+                                    (?Y 'magit-signature-expired-key)
+                                    (?R 'magit-signature-revoked)
+                                    (?E 'magit-signature-error)))))
+          (insert (funcall magit-log-format-message-function hash msg)))
+        (when (and refs magit-log-show-refname-after-summary)
+          (insert ?\s)
+          (insert (magit-format-ref-labels refs)))
+        (insert ?\n)
+        (when (memq style '(log reflog stash))
+          (goto-char (line-beginning-position))
+          (when (and refsub
+                     (string-match "\\`\\([^ ]\\) \\+\\(..\\)\\(..\\)" date))
+            (setq date (+ (string-to-number (match-string 1 date))
+                          (* (string-to-number (match-string 2 date)) 60 60)
+                          (* (string-to-number (match-string 3 date)) 60))))
+          (save-excursion
+            (backward-char)
+            (magit-log-format-margin author date)))
+        (when (and (eq style 'cherry)
+                   (magit-buffer-margin-p))
+          (save-excursion
+            (backward-char)
+            (apply #'magit-log-format-margin
+                   (split-string (magit-rev-format "%aN%x00%ct" hash) "\0"))))
+        (when (and graph
+                   (not (eobp))
+                   (not (looking-at non-graph-re)))
+          (when (looking-at "")
+            (magit-insert-heading)
+            (delete-char 1)
+            (magit-insert-section (commit-header)
+              (forward-line)
+              (magit-insert-heading)
+              (re-search-forward "")
+              (backward-delete-char 1)
+              (forward-char)
+              (insert ?\n))
+            (delete-char 1))
+          (if (looking-at "^\\(---\\|\n\s\\|\ndiff\\)")
+              (let ((limit (save-excursion
+                             (and (re-search-forward non-graph-re nil t)
+                                  (match-beginning 0)))))
+                (unless (oref magit-insert-section--current content)
+                  (magit-insert-heading))
+                (delete-char (if (looking-at "\n") 1 4))
+                (magit-diff-wash-diffs (list "--stat") limit))
+            (when align
+              (setq align (make-string (1+ abbrev) ? )))
+            (when (and (not (eobp)) (not (looking-at non-graph-re)))
+              (when align
+                (setq align (make-string (1+ abbrev) ? )))
+              (while (and (not (eobp)) (not (looking-at non-graph-re)))
+                (when align
+                  (save-excursion (insert align)))
+                (magit-make-margin-overlay)
+                (forward-line))
+              ;; When `--format' is used and its value isn't one of the
+              ;; predefined formats, then `git-log' does not insert a
+              ;; separator line.
+              (save-excursion
+                (forward-line -1)
+                (looking-at "[-_/|\\*o. ]*"))
+              (setq graph (match-string 0))
+              (unless (string-match-p "[/\\]" graph)
+                (insert graph ?\n))))))))
+  t)
+
+(defun magit-log-propertize-keywords (_rev msg)
+  (let ((start 0))
+    (when (string-match "^\\(squash\\|fixup\\)! " msg start)
+      (setq start (match-end 0))
+      (put-text-property (match-beginning 0)
+                         (match-end 0)
+                         'face 'magit-keyword-squash msg))
+    (while (string-match "\\[[^[]*\\]" msg start)
+      (setq start (match-end 0))
+      (when magit-log-highlight-keywords
+        (put-text-property (match-beginning 0)
+                           (match-end 0)
+                           'face 'magit-keyword msg))))
+  msg)
+
+(defun magit-log-maybe-show-more-commits (section)
+  "When point is at the end of a log buffer, insert more commits.
+
+Log buffers end with a button \"Type + to show more history\".
+When the use of a section movement command puts point on that
+button, then automatically show more commits, without the user
+having to press \"+\".
+
+This function is called by `magit-section-movement-hook' and
+exists mostly for backward compatibility reasons."
+  (when (and (eq (oref section type) 'longer)
+             magit-log-auto-more)
+    (magit-log-double-commit-limit)
+    (forward-line -1)
+    (magit-section-forward)))
+
+(defvar magit--update-revision-buffer nil)
+
+(defun magit-log-maybe-update-revision-buffer (&optional _)
+  "When moving in the log buffer, update the revision buffer.
+If there is no revision buffer in the same frame, then do nothing."
+  (when (derived-mode-p 'magit-log-mode)
+    (magit-log-maybe-update-revision-buffer-1)))
+
+(defun magit-log-maybe-update-revision-buffer-1 ()
+  (unless magit--update-revision-buffer
+    (when-let ((commit (magit-section-when 'commit))
+               (buffer (magit-mode-get-buffer 'magit-revision-mode nil t)))
+      (setq magit--update-revision-buffer (list commit buffer))
+      (run-with-idle-timer
+       magit-update-other-window-delay nil
+       (let ((args (magit-show-commit--arguments)))
+         (lambda ()
+           (pcase-let ((`(,rev ,buf) magit--update-revision-buffer))
+             (setq magit--update-revision-buffer nil)
+             (when (buffer-live-p buf)
+               (let ((magit-display-buffer-noselect t))
+                 (apply #'magit-show-commit rev args))))
+           (setq magit--update-revision-buffer nil)))))))
+
+(defvar magit--update-blob-buffer nil)
+
+(defun magit-log-maybe-update-blob-buffer (&optional _)
+  "When moving in the log buffer, update the blob buffer.
+If there is no blob buffer in the same frame, then do nothing."
+  (when (derived-mode-p 'magit-log-mode)
+    (magit-log-maybe-update-blob-buffer-1)))
+
+(defun magit-log-maybe-update-blob-buffer-1 ()
+  (unless magit--update-revision-buffer
+    (when-let ((commit (magit-section-when 'commit))
+               (buffer (--first (with-current-buffer it magit-buffer-revision)
+                                (mapcar #'window-buffer (window-list)))))
+        (setq magit--update-blob-buffer (list commit buffer))
+        (run-with-idle-timer
+         magit-update-other-window-delay nil
+         (lambda ()
+           (pcase-let ((`(,rev ,buf) magit--update-blob-buffer))
+             (setq magit--update-blob-buffer nil)
+             (when (buffer-live-p buf)
+               (save-excursion
+                 (with-selected-window (get-buffer-window buf)
+                   (with-current-buffer buf
+                     (magit-blob-visit (list (magit-rev-parse rev)
+                                             (magit-file-relative-name
+                                              magit-buffer-file-name))
+                                       (line-number-at-pos))))))))))))
+
+(defun magit-log-goto-same-commit ()
+  (when-let ((prev magit-previous-section)
+             (rev  (cond ((magit-section-match 'commit prev)
+                          (oref prev value))
+                         ((magit-section-match 'branch prev)
+                          (magit-rev-format "%h" (oref prev value)))))
+             (same (--first (equal (oref it value) rev)
+                            (oref magit-root-section children))))
+    (goto-char (oref same start))))
+
+;;; Log Margin
+
+(defun magit-log-format-margin (author date)
+  (when-let ((option (magit-margin-option)))
+    (pcase-let ((`(,_ ,style ,width ,details ,details-width)
+                 (or magit-buffer-margin
+                     (symbol-value option))))
+      (magit-make-margin-overlay
+       (concat (and details
+                    (concat (propertize (truncate-string-to-width
+                                         (or author "")
+                                         details-width
+                                         nil ?\s (make-string 1 magit-ellipsis))
+                                        'face 'magit-log-author)
+                            " "))
+               (propertize
+                (if (stringp style)
+                    (format-time-string
+                     style
+                     (seconds-to-time (string-to-number date)))
+                  (pcase-let* ((abbr (eq style 'age-abbreviated))
+                               (`(,cnt ,unit) (magit--age date abbr)))
+                    (format (format (if abbr "%%2i%%-%ic" "%%2i %%-%is")
+                                    (- width (if details (1+ details-width) 0)))
+                            cnt unit)))
+                'face 'magit-log-date))))))
+
+(defun magit-log-margin-width (style details details-width)
+  (+ (if details (1+ details-width) 0)
+     (if (stringp style)
+         (length (format-time-string style))
+       (+ 2 ; two digits
+          1 ; trailing space
+          (if (eq style 'age-abbreviated)
+              1  ; single character
+            (+ 1 ; gap after digits
+               (apply #'max (--map (max (length (nth 1 it))
+                                        (length (nth 2 it)))
+                                   magit--age-spec))))))))
+
+;;; Select Mode
+
+(defvar magit-log-select-mode-map
+  (let ((map (make-sparse-keymap)))
+    (set-keymap-parent map magit-log-mode-map)
+    (define-key map "\C-c\C-b" 'undefined)
+    (define-key map "\C-c\C-f" 'undefined)
+    (define-key map "."        'magit-log-select-pick)
+    (define-key map "e"        'magit-log-select-pick)
+    (define-key map "\C-c\C-c" 'magit-log-select-pick)
+    (define-key map "q"        'magit-log-select-quit)
+    (define-key map "\C-c\C-k" 'magit-log-select-quit)
+    map)
+  "Keymap for `magit-log-select-mode'.")
+
+(put 'magit-log-select-pick :advertised-binding [?\C-c ?\C-c])
+(put 'magit-log-select-quit :advertised-binding [?\C-c ?\C-k])
+
+(define-derived-mode magit-log-select-mode magit-log-mode "Magit Select"
+  "Mode for selecting a commit from history.
+
+This mode is documented in info node `(magit)Select from Log'.
+
+\\<magit-mode-map>\
+Type \\[magit-refresh] to refresh the current buffer.
+Type \\[magit-visit-thing] or \\[magit-diff-show-or-scroll-up] \
+to visit the commit at point.
+
+\\<magit-log-select-mode-map>\
+Type \\[magit-log-select-pick] to select the commit at point.
+Type \\[magit-log-select-quit] to abort without selecting a commit."
+  :group 'magit-log
+  (hack-dir-local-variables-non-file-buffer))
+
+(defun magit-log-select-refresh-buffer (rev args)
+  (magit-insert-section (logbuf)
+    (magit-insert-log rev args)))
+
+(defvar-local magit-log-select-pick-function nil)
+(defvar-local magit-log-select-quit-function nil)
+
+(defun magit-log-select (pick &optional msg quit branch args)
+  (declare (indent defun))
+  (magit-mode-setup #'magit-log-select-mode
+                    (or branch (magit-get-current-branch) "HEAD")
+                    (append args magit-log-select-arguments))
+  (magit-log-goto-same-commit)
+  (setq magit-log-select-pick-function pick)
+  (setq magit-log-select-quit-function quit)
+  (when magit-log-select-show-usage
+    (let ((pick (propertize (substitute-command-keys
+                             "\\[magit-log-select-pick]")
+                            'face
+                            'magit-header-line-key))
+          (quit (propertize (substitute-command-keys
+                             "\\[magit-log-select-quit]")
+                            'face
+                            'magit-header-line-key)))
+      (setq msg (format-spec
+                 (if msg
+                     (if (string-suffix-p "," msg)
+                         (concat msg " or %q to abort")
+                       msg)
+                   "Type %p to select commit at point, or %q to abort")
+                 `((?p . ,pick)
+                   (?q . ,quit)))))
+    (add-face-text-property 0 (length msg) 'magit-header-line-log-select t msg)
+    (when (memq magit-log-select-show-usage '(both header-line))
+      (magit-set-header-line-format msg))
+    (when (memq magit-log-select-show-usage '(both echo-area))
+      (message "%s" (substring-no-properties msg)))))
+
+(defun magit-log-select-pick ()
+  "Select the commit at point and act on it.
+Call `magit-log-select-pick-function' with the selected
+commit as argument."
+  (interactive)
+  (let ((fun magit-log-select-pick-function)
+        (rev (magit-commit-at-point)))
+    (magit-mode-bury-buffer 'kill)
+    (funcall fun rev)))
+
+(defun magit-log-select-quit ()
+  "Abort selecting a commit, don't act on any commit."
+  (interactive)
+  (magit-mode-bury-buffer 'kill)
+  (when magit-log-select-quit-function
+    (funcall magit-log-select-quit-function)))
+
+;;; Cherry Mode
+
+(defvar magit-cherry-mode-map
+  (let ((map (make-sparse-keymap)))
+    (set-keymap-parent map magit-mode-map)
+    (define-key map "q" 'magit-log-bury-buffer)
+    (define-key map "L" 'magit-margin-popup)
+    map)
+  "Keymap for `magit-cherry-mode'.")
+
+(define-derived-mode magit-cherry-mode magit-mode "Magit Cherry"
+  "Mode for looking at commits not merged upstream.
+
+\\<magit-mode-map>\
+Type \\[magit-refresh] to refresh the current buffer.
+Type \\[magit-visit-thing] or \\[magit-diff-show-or-scroll-up] \
+to visit the commit at point.
+
+Type \\[magit-cherry-pick-popup] to apply the commit at point.
+
+\\{magit-cherry-mode-map}"
+  :group 'magit-log
+  (hack-dir-local-variables-non-file-buffer)
+  (setq imenu-create-index-function
+        'magit-imenu--cherry-create-index-function)
+  (setq-local bookmark-make-record-function
+              'magit-bookmark--cherry-make-record))
+
+;;;###autoload
+(defun magit-cherry (head upstream)
+  "Show commits in a branch that are not merged in the upstream branch."
+  (interactive
+   (let  ((head (magit-read-branch "Cherry head")))
+     (list head (magit-read-other-branch "Cherry upstream" head
+                                         (magit-get-upstream-branch head)))))
+  (require 'magit)
+  (magit-mode-setup #'magit-cherry-mode upstream head))
+
+(defun magit-cherry-refresh-buffer (_upstream _head)
+  (magit-insert-section (cherry)
+    (run-hooks 'magit-cherry-sections-hook)))
+
+(defun magit-insert-cherry-headers ()
+  "Insert headers appropriate for `magit-cherry-mode' buffers."
+  (magit-insert-head-branch-header (nth 1 magit-refresh-args))
+  (magit-insert-upstream-branch-header (nth 1 magit-refresh-args)
+                                       (nth 0 magit-refresh-args)
+                                       "Upstream: ")
+  (insert ?\n))
+
+(defun magit-insert-cherry-commits ()
+  "Insert commit sections into a `magit-cherry-mode' buffer."
+  (magit-insert-section (cherries)
+    (magit-insert-heading "Cherry commits:")
+    (magit-git-wash (apply-partially 'magit-log-wash-log 'cherry)
+      "cherry" "-v" "--abbrev" magit-refresh-args)))
+
+;;; Reflog Mode
+
+(defvar magit-reflog-mode-map
+  (let ((map (make-sparse-keymap)))
+    (set-keymap-parent map magit-log-mode-map)
+    (define-key map "L" 'magit-margin-popup)
+    map)
+  "Keymap for `magit-reflog-mode'.")
+
+(define-derived-mode magit-reflog-mode magit-log-mode "Magit Reflog"
+  "Mode for looking at Git reflog.
+
+This mode is documented in info node `(magit)Reflog'.
+
+\\<magit-mode-map>\
+Type \\[magit-refresh] to refresh the current buffer.
+Type \\[magit-visit-thing] or \\[magit-diff-show-or-scroll-up] \
+to visit the commit at point.
+
+Type \\[magit-cherry-pick-popup] to apply the commit at point.
+Type \\[magit-reset] to reset `HEAD' to the commit at point.
+
+\\{magit-reflog-mode-map}"
+  :group 'magit-log
+  (hack-dir-local-variables-non-file-buffer)
+  (setq-local bookmark-make-record-function
+              'magit-bookmark--reflog-make-record))
+
+(defun magit-reflog-refresh-buffer (ref args)
+  (magit-set-header-line-format (concat "Reflog for " ref))
+  (magit-insert-section (reflogbuf)
+    (magit-git-wash (apply-partially 'magit-log-wash-log 'reflog)
+      "reflog" "show" "--format=%h%x00%aN%x00%gd%x00%gs" "--date=raw"
+      args ref "--")))
+
+(defvar magit-reflog-labels
+  '(("commit"      . magit-reflog-commit)
+    ("amend"       . magit-reflog-amend)
+    ("merge"       . magit-reflog-merge)
+    ("checkout"    . magit-reflog-checkout)
+    ("branch"      . magit-reflog-checkout)
+    ("reset"       . magit-reflog-reset)
+    ("rebase"      . magit-reflog-rebase)
+    ("cherry-pick" . magit-reflog-cherry-pick)
+    ("initial"     . magit-reflog-commit)
+    ("pull"        . magit-reflog-remote)
+    ("clone"       . magit-reflog-remote)
+    ("autosave"    . magit-reflog-commit)
+    ("restart"     . magit-reflog-reset)))
+
+(defun magit-reflog-format-subject (subject)
+  (let* ((match (string-match magit-reflog-subject-re subject))
+         (command (and match (match-string 1 subject)))
+         (option  (and match (match-string 2 subject)))
+         (type    (and match (match-string 3 subject)))
+         (label (if (string= command "commit")
+                    (or type command)
+                  command))
+         (text (if (string= command "commit")
+                   label
+                 (mapconcat #'identity
+                            (delq nil (list command option type))
+                            " "))))
+    (format "%-16s "
+            (propertize text 'face
+                        (or (cdr (assoc label magit-reflog-labels))
+                            'magit-reflog-other)))))
+
+;;; Log Sections
+;;;; Standard Log Sections
+
+(defvar magit-unpulled-section-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map [remap magit-visit-thing] 'magit-diff-dwim)
+    map)
+  "Keymap for `unpulled' sections.")
+
+(magit-define-section-jumper magit-jump-to-unpulled-from-upstream
+  "Unpulled from @{upstream}" unpulled "..@{upstream}")
+
+(defun magit-insert-unpulled-from-upstream ()
+  "Insert commits that haven't been pulled from the upstream yet."
+  (when (magit-git-success "rev-parse" "@{upstream}")
+    (magit-insert-section (unpulled "..@{upstream}" t)
+      (magit-insert-heading
+        (format (propertize "Unpulled from %s:" 'face 'magit-section-heading)
+                (magit-get-upstream-branch)))
+      (magit-insert-log "..@{upstream}" magit-log-section-arguments))))
+
+(magit-define-section-jumper magit-jump-to-unpulled-from-pushremote
+  "Unpulled from <push-remote>" unpulled
+  (concat ".." (magit-get-push-branch)))
+
+(defun magit-insert-unpulled-from-pushremote ()
+  "Insert commits that haven't been pulled from the push-remote yet."
+  (--when-let (magit-get-push-branch)
+    (unless (and (equal (magit-rev-name it)
+                        (magit-rev-name "@{upstream}"))
+                 (or (memq 'magit-insert-unpulled-from-upstream
+                           magit-status-sections-hook)
+                     (memq 'magit-insert-unpulled-from-upstream-or-recent
+                           magit-status-sections-hook)))
+      (magit-insert-section (unpulled (concat ".." it) t)
+        (magit-insert-heading
+          (format (propertize "Unpulled from %s:" 'face 'magit-section-heading)
+                  (propertize it 'face 'magit-branch-remote)))
+        (magit-insert-log (concat ".." it) magit-log-section-arguments)))))
+
+(defvar magit-unpushed-section-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map [remap magit-visit-thing] 'magit-diff-dwim)
+    map)
+  "Keymap for `unpushed' sections.")
+
+(magit-define-section-jumper magit-jump-to-unpushed-to-upstream
+  "Unpushed to @{upstream}" unpushed "@{upstream}..")
+
+(defun magit-insert-unpushed-to-upstream-or-recent ()
+  "Insert section showing unpushed or other recent commits.
+If an upstream is configured for the current branch and it is
+behind of the current branch, then show the commits that have
+not yet been pushed into the upstream branch.  If no upstream is
+configured or if the upstream is not behind of the current branch,
+then show the last `magit-log-section-commit-count' commits."
+  (let ((upstream (magit-rev-parse "@{upstream}")))
+    (if (or (not upstream)
+            (magit-rev-ancestor-p "HEAD" upstream))
+        (magit-insert-recent-commits 'unpushed "@{upstream}..")
+      (magit-insert-unpushed-to-upstream))))
+
+(defun magit-insert-unpushed-to-upstream ()
+  "Insert commits that haven't been pushed to the upstream yet."
+  (when (magit-git-success "rev-parse" "@{upstream}")
+    (magit-insert-section (unpushed "@{upstream}..")
+      (magit-insert-heading
+        (format (propertize "Unmerged into %s:" 'face 'magit-section-heading)
+                (magit-get-upstream-branch)))
+      (magit-insert-log "@{upstream}.." magit-log-section-arguments))))
+
+(defun magit-insert-recent-commits (&optional type value)
+  "Insert section showing recent commits.
+Show the last `magit-log-section-commit-count' commits."
+  (let* ((start (format "HEAD~%s" magit-log-section-commit-count))
+         (range (and (magit-rev-verify start)
+                     (concat start "..HEAD"))))
+    (magit-insert-section ((eval (or type 'recent))
+                           (or value range)
+                           t)
+      (magit-insert-heading "Recent commits")
+      (magit-insert-log range
+                        (cons (format "-n%d" magit-log-section-commit-count)
+                              (--remove (string-prefix-p "-n" it)
+                                        magit-log-section-arguments))))))
+
+(magit-define-section-jumper magit-jump-to-unpushed-to-pushremote
+  "Unpushed to <push-remote>" unpushed
+  (concat (magit-get-push-branch) ".."))
+
+(defun magit-insert-unpushed-to-pushremote ()
+  "Insert commits that haven't been pushed to the push-remote yet."
+  (--when-let (magit-get-push-branch)
+    (unless (and (equal (magit-rev-name it)
+                        (magit-rev-name "@{upstream}"))
+                 (or (memq 'magit-insert-unpushed-to-upstream
+                           magit-status-sections-hook)
+                     (memq 'magit-insert-unpushed-to-upstream-or-recent
+                           magit-status-sections-hook)))
+      (magit-insert-section (unpushed (concat it "..") t)
+        (magit-insert-heading
+          (format (propertize "Unpushed to %s:" 'face 'magit-section-heading)
+                  (propertize it 'face 'magit-branch-remote)))
+        (magit-insert-log (concat it "..") magit-log-section-arguments)))))
+
+;;;; Auxiliary Log Sections
+
+(defun magit-insert-unpulled-cherries ()
+  "Insert section showing unpulled commits.
+Like `magit-insert-unpulled-from-upstream' but prefix each commit
+which has not been applied yet (i.e. a commit with a patch-id
+not shared with any local commit) with \"+\", and all others with
+\"-\"."
+  (when (magit-git-success "rev-parse" "@{upstream}")
+    (magit-insert-section (unpulled "..@{upstream}")
+      (magit-insert-heading "Unpulled commits:")
+      (magit-git-wash (apply-partially 'magit-log-wash-log 'cherry)
+        "cherry" "-v" (magit-abbrev-arg)
+        (magit-get-current-branch) "@{upstream}"))))
+
+(defun magit-insert-unpushed-cherries ()
+  "Insert section showing unpushed commits.
+Like `magit-insert-unpushed-to-upstream' but prefix each commit
+which has not been applied to upstream yet (i.e. a commit with
+a patch-id not shared with any upstream commit) with \"+\", and
+all others with \"-\"."
+  (when (magit-git-success "rev-parse" "@{upstream}")
+    (magit-insert-section (unpushed "@{upstream}..")
+      (magit-insert-heading "Unpushed commits:")
+      (magit-git-wash (apply-partially 'magit-log-wash-log 'cherry)
+        "cherry" "-v" (magit-abbrev-arg) "@{upstream}"))))
+
+(provide 'magit-log)
+;;; magit-log.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-log.elc b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-log.elc
new file mode 100644
index 0000000000..a9bb75b45f
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-log.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-margin.el b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-margin.el
new file mode 100644
index 0000000000..4210d96929
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-margin.el
@@ -0,0 +1,237 @@
+;;; magit-margin.el --- margins in Magit buffers  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2010-2018  The Magit Project Contributors
+;;
+;; You should have received a copy of the AUTHORS.md file which
+;; lists all contributors.  If not, see http://magit.vc/authors.
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; Magit 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, or (at your option)
+;; any later version.
+;;
+;; Magit 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 Magit.  If not, see http://www.gnu.org/licenses.
+
+;;; Commentary:
+
+;; This library implements support for showing additional information
+;; in the margins of Magit buffers.  Currently this is only used for
+;; commits, for which the committer date or age, and optionally the
+;; author name are shown.
+
+;;; Code:
+
+(require 'dash)
+
+(require 'magit-section)
+(require 'magit-mode)
+
+(defgroup magit-margin nil
+  "Information Magit displays in the margin.
+
+You can change the STYLE and AUTHOR-WIDTH of all `magit-*-margin'
+options to the same values by customizing `magit-log-margin'
+*before* `magit' is loaded.  If you do that, then the respective
+values for the other options will default to what you have set
+for that variable.  Likewise if you set `magit-log-margin's INIT
+to nil, then that is used in the default of all other options.  But
+setting it to t, i.e. re-enforcing the default for that option,
+does not carry to other options."
+  :link '(info-link "(magit)Log Margin")
+  :group 'magit-log)
+
+(defvar-local magit-buffer-margin nil)
+(put 'magit-buffer-margin 'permanent-local t)
+
+(defvar-local magit-set-buffer-margin-refresh nil)
+
+(defvar magit--age-spec)
+
+;;; Commands
+
+(magit-define-popup magit-margin-popup
+  "Popup console for changing appearance of the margin."
+  :actions '("Margin"
+             (?L "Toggle visibility" magit-toggle-margin)
+             (?l "Cycle style"       magit-cycle-margin-style)
+             (?d "Toggle details"    magit-toggle-margin-details)
+             (lambda ()
+               (and (with-current-buffer magit-pre-popup-buffer
+                      (derived-mode-p 'magit-refs-mode))
+                    (propertize "Left edge" 'face 'magit-popup-heading)))
+             (?v "Change verbosity" magit-refs-set-show-commit-count))
+  :max-action-columns 1)
+
+(defun magit-toggle-margin ()
+  "Show or hide the Magit margin."
+  (interactive)
+  (unless (magit-margin-option)
+    (user-error "Magit margin isn't supported in this buffer"))
+  (setcar magit-buffer-margin (not (magit-buffer-margin-p)))
+  (magit-set-buffer-margin))
+
+(defun magit-cycle-margin-style ()
+  "Cycle style used for the Magit margin."
+  (interactive)
+  (unless (magit-margin-option)
+    (user-error "Magit margin isn't supported in this buffer"))
+  ;; This is only suitable for commit margins (there are not others).
+  (setf (cadr magit-buffer-margin)
+        (pcase (cadr magit-buffer-margin)
+          (`age 'age-abbreviated)
+          (`age-abbreviated
+           (let ((default (cadr (symbol-value (magit-margin-option)))))
+             (if (stringp default) default "%Y-%m-%d %H:%M ")))
+          (_ 'age)))
+  (magit-set-buffer-margin nil t))
+
+(defun magit-toggle-margin-details ()
+  "Show or hide details in the Magit margin."
+  (interactive)
+  (unless (magit-margin-option)
+    (user-error "Magit margin isn't supported in this buffer"))
+  (setf (nth 3 magit-buffer-margin)
+        (not (nth 3 magit-buffer-margin)))
+  (magit-set-buffer-margin nil t))
+
+;;; Core
+
+(defun magit-buffer-margin-p ()
+  (car magit-buffer-margin))
+
+(defun magit-margin-option ()
+  (pcase major-mode
+    (`magit-cherry-mode     'magit-cherry-margin)
+    (`magit-log-mode        'magit-log-margin)
+    (`magit-log-select-mode 'magit-log-select-margin)
+    (`magit-reflog-mode     'magit-reflog-margin)
+    (`magit-refs-mode       'magit-refs-margin)
+    (`magit-stashes-mode    'magit-stashes-margin)
+    (`magit-status-mode     'magit-status-margin)))
+
+(defun magit-set-buffer-margin (&optional reset refresh)
+  (when-let ((option (magit-margin-option)))
+    (let* ((default (symbol-value option))
+           (default-width (nth 2 default)))
+      (when (or reset (not magit-buffer-margin))
+        (setq magit-buffer-margin (copy-sequence default)))
+      (pcase-let ((`(,enable ,style ,_width ,details ,details-width)
+                   magit-buffer-margin))
+        (when (functionp default-width)
+          (setf (nth 2 magit-buffer-margin)
+                (funcall default-width style details details-width)))
+        (dolist (window (get-buffer-window-list nil nil 0))
+          (with-selected-window window
+            (magit-set-window-margin window)
+            (if enable
+                (add-hook  'window-configuration-change-hook
+                           'magit-set-window-margin nil t)
+              (remove-hook 'window-configuration-change-hook
+                           'magit-set-window-margin t))))
+        (when (and enable (or refresh magit-set-buffer-margin-refresh))
+          (magit-refresh-buffer))))))
+
+(defun magit-set-window-margin (&optional window)
+  (when (or window (setq window (get-buffer-window)))
+    (with-selected-window window
+      (set-window-margins nil (car (window-margins))
+                          (and (magit-buffer-margin-p)
+                               (nth 2 magit-buffer-margin))))))
+
+(defun magit-make-margin-overlay (&optional string previous-line)
+  (if previous-line
+      (save-excursion
+        (forward-line -1)
+        (magit-make-margin-overlay string))
+    ;; Don't put the overlay on the complete line to work around #1880.
+    (let ((o (make-overlay (1+ (line-beginning-position))
+                           (line-end-position)
+                           nil t)))
+      (overlay-put o 'evaporate t)
+      (overlay-put o 'before-string
+                   (propertize "o" 'display
+                               (list (list 'margin 'right-margin)
+                                     (or string " ")))))))
+
+(defun magit-maybe-make-margin-overlay ()
+  (when (or (magit-section-match
+             '(unpulled unpushed recent stashes local cherries)
+             magit-insert-section--current)
+            (and (eq major-mode 'magit-refs-mode)
+                 (magit-section-match
+                  '(remote commit tags)
+                  magit-insert-section--current)))
+    (magit-make-margin-overlay nil t)))
+
+;;; Custom Support
+
+(defun magit-margin-set-variable (mode symbol value)
+  (set-default symbol value)
+  (message "Updating margins in %s buffers..." mode)
+  (dolist (buffer (buffer-list))
+    (with-current-buffer buffer
+      (when (eq major-mode mode)
+        (magit-set-buffer-margin t)
+        (magit-refresh))))
+  (message "Updating margins in %s buffers...done" mode))
+
+(defconst magit-log-margin--custom-type
+  '(list (boolean :tag "Show margin initially")
+         (choice  :tag "Show committer"
+                  (string :tag "date using time-format" "%Y-%m-%d %H:%M ")
+                  (const  :tag "date's age" age)
+                  (const  :tag "date's age (abbreviated)" age-abbreviated))
+         (const   :tag "Calculate width using magit-log-margin-width"
+                  magit-log-margin-width)
+         (boolean :tag "Show author name by default")
+         (integer :tag "Show author name using width")))
+
+;;; Time Utilities
+
+(defvar magit--age-spec
+  `((?Y "year"   "years"   ,(round (* 60 60 24 365.2425)))
+    (?M "month"  "months"  ,(round (* 60 60 24 30.436875)))
+    (?w "week"   "weeks"   ,(* 60 60 24 7))
+    (?d "day"    "days"    ,(* 60 60 24))
+    (?h "hour"   "hours"   ,(* 60 60))
+    (?m "minute" "minutes" 60)
+    (?s "second" "seconds" 1))
+  "Time units used when formatting relative commit ages.
+
+The value is a list of time units, beginning with the longest.
+Each element has the form (CHAR UNIT UNITS SECONDS).  UNIT is the
+time unit, UNITS is the plural of that unit.  CHAR is a character
+abbreviation.  And SECONDS is the number of seconds in one UNIT.
+
+This is defined as a variable to make it possible to use time
+units for a language other than English.  It is not defined
+as an option, because most other parts of Magit are always in
+English.")
+
+(defun magit--age (date &optional abbreviate)
+  (cl-labels ((fn (age spec)
+                  (pcase-let ((`(,char ,unit ,units ,weight) (car spec)))
+                    (let ((cnt (round (/ age weight 1.0))))
+                      (if (or (not (cdr spec))
+                              (>= (/ age weight) 1))
+                          (list cnt (cond (abbreviate char)
+                                          ((= cnt 1) unit)
+                                          (t units)))
+                        (fn age (cdr spec)))))))
+    (fn (abs (- (float-time)
+                (if (stringp date)
+                    (string-to-number date)
+                  date)))
+        magit--age-spec)))
+
+(provide 'magit-margin)
+;;; magit-margin.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-margin.elc b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-margin.elc
new file mode 100644
index 0000000000..8214d2b9c4
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-margin.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-merge.el b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-merge.el
new file mode 100644
index 0000000000..3c065c5ecf
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-merge.el
@@ -0,0 +1,278 @@
+;;; magit-merge.el --- merge functionality  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2010-2018  The Magit Project Contributors
+;;
+;; You should have received a copy of the AUTHORS.md file which
+;; lists all contributors.  If not, see http://magit.vc/authors.
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; Magit 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, or (at your option)
+;; any later version.
+;;
+;; Magit 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 Magit.  If not, see http://www.gnu.org/licenses.
+
+;;; Commentary:
+
+;; This library implements merge commands.
+
+;;; Code:
+
+(require 'magit)
+
+;;; Commands
+
+;;;###autoload (autoload 'magit-merge-popup "magit" nil t)
+(magit-define-popup magit-merge-popup
+  "Popup console for merge commands."
+  :man-page "git-merge"
+  :switches '((?f "Fast-forward only" "--ff-only")
+              (?n "No fast-forward"   "--no-ff"))
+  :options  '((?s "Strategy" "--strategy="))
+  :actions  '((?m "Merge"                  magit-merge)
+              (?p "Preview merge"          magit-merge-preview)
+              (?e "Merge and edit message" magit-merge-editmsg) nil
+              (?n "Merge but don't commit" magit-merge-nocommit)
+              (?s "Squash merge"           magit-merge-squash)
+              (?a "Absorb"                 magit-merge-absorb)
+              (?i "Merge into"             magit-merge-into))
+  :sequence-actions   '((?m "Commit merge" magit-commit)
+                        (?a "Abort merge"  magit-merge-abort))
+  :sequence-predicate 'magit-merge-in-progress-p
+  :default-action 'magit-merge
+  :max-action-columns 2)
+
+;;;###autoload
+(defun magit-merge (rev &optional args nocommit)
+  "Merge commit REV into the current branch; using default message.
+
+Unless there are conflicts or a prefix argument is used create a
+merge commit using a generic commit message and without letting
+the user inspect the result.  With a prefix argument pretend the
+merge failed to give the user the opportunity to inspect the
+merge.
+
+\(git merge --no-edit|--no-commit [ARGS] REV)"
+  (interactive (list (magit-read-other-branch-or-commit "Merge")
+                     (magit-merge-arguments)
+                     current-prefix-arg))
+  (magit-merge-assert)
+  (magit-run-git-async "merge" (if nocommit "--no-commit" "--no-edit") args rev))
+
+;;;###autoload
+(defun magit-merge-editmsg (rev &optional args)
+  "Merge commit REV into the current branch; and edit message.
+Perform the merge and prepare a commit message but let the user
+edit it.
+\n(git merge --edit --no-ff [ARGS] REV)"
+  (interactive (list (magit-read-other-branch-or-commit "Merge")
+                     (magit-merge-arguments)))
+  (magit-merge-assert)
+  (cl-pushnew "--no-ff" args :test #'equal)
+  (apply #'magit-run-git-with-editor "merge" "--edit"
+         (append args (list rev))))
+
+;;;###autoload
+(defun magit-merge-nocommit (rev &optional args)
+  "Merge commit REV into the current branch; pretending it failed.
+Pretend the merge failed to give the user the opportunity to
+inspect the merge and change the commit message.
+\n(git merge --no-commit --no-ff [ARGS] REV)"
+  (interactive (list (magit-read-other-branch-or-commit "Merge")
+                     (magit-merge-arguments)))
+  (magit-merge-assert)
+  (cl-pushnew "--no-ff" args :test #'equal)
+  (magit-run-git-async "merge" "--no-commit" args rev))
+
+;;;###autoload
+(defun magit-merge-into (branch &optional args)
+  "Merge the current branch into BRANCH and remove the former.
+
+Before merging, force push the source branch to its push-remote,
+provided the respective remote branch already exists, ensuring
+that the respective pull-request (if any) won't get stuck on some
+obsolete version of the commits that are being merged.  Finally
+if `magit-branch-pull-request' was used to create the merged
+branch, then also remove the respective remote branch."
+  (interactive (list (magit-read-other-local-branch
+                      (format "Merge `%s' into" (magit-get-current-branch))
+                      nil
+                      (let ((branch (cdr (magit-split-branch-name
+                                          (magit-get-upstream-branch)))))
+                        (and (magit-branch-p branch) branch)))
+                     (magit-merge-arguments)))
+  (let ((current (magit-get-current-branch)))
+    (when (zerop (magit-call-git "checkout" branch))
+      (magit--merge-absort current args))))
+
+;;;###autoload
+(defun magit-merge-absorb (branch &optional args)
+  "Merge BRANCH into the current branch and remove the former.
+
+Before merging, force push the source branch to its push-remote,
+provided the respective remote branch already exists, ensuring
+that the respective pull-request (if any) won't get stuck on some
+obsolete version of the commits that are being merged.  Finally
+if `magit-branch-pull-request' was used to create the merged
+branch, then also remove the respective remote branch."
+  (interactive (list (magit-read-other-local-branch "Absorb branch")
+                     (magit-merge-arguments)))
+  (magit--merge-absort branch args))
+
+(defun magit--merge-absort (branch args)
+  (when (equal branch "master")
+    (unless (yes-or-no-p
+             "Do you really wanto to merge `master' into another branch? ")
+      (user-error "Abort")))
+  (if-let ((target (magit-get-push-branch branch t)))
+      (progn
+        (magit-git-push branch target (list "--force-with-lease"))
+        (set-process-sentinel
+         magit-this-process
+         (lambda (process event)
+           (when (memq (process-status process) '(exit signal))
+             (if (not (zerop (process-exit-status process)))
+                 (magit-process-sentinel process event)
+               (process-put process 'inhibit-refresh t)
+               (magit-process-sentinel process event)
+               (magit--merge-absort-1 branch args))))))
+    (magit--merge-absort-1 branch args)))
+
+(defun magit--merge-absort-1 (branch args)
+  (magit-run-git-async "merge" args "--no-edit" branch)
+  (set-process-sentinel
+   magit-this-process
+   (lambda (process event)
+     (when (memq (process-status process) '(exit signal))
+       (if (> (process-exit-status process) 0)
+           (magit-process-sentinel process event)
+         (process-put process 'inhibit-refresh t)
+         (magit-process-sentinel process event)
+         (magit-branch-maybe-delete-pr-remote branch)
+         (magit-branch-unset-pushRemote branch)
+         (magit-run-git "branch" "-D" branch))))))
+
+;;;###autoload
+(defun magit-merge-squash (rev)
+  "Squash commit REV into the current branch; don't create a commit.
+\n(git merge --squash REV)"
+  (interactive (list (magit-read-other-branch-or-commit "Squash")))
+  (magit-merge-assert)
+  (magit-run-git-async "merge" "--squash" rev))
+
+;;;###autoload
+(defun magit-merge-preview (rev)
+  "Preview result of merging REV into the current branch."
+  (interactive (list (magit-read-other-branch-or-commit "Preview merge")))
+  (magit-mode-setup #'magit-merge-preview-mode rev))
+
+(define-derived-mode magit-merge-preview-mode magit-diff-mode "Magit Merge"
+  "Mode for previewing a merge."
+  :group 'magit-diff
+  (hack-dir-local-variables-non-file-buffer))
+
+(defun magit-merge-preview-refresh-buffer (rev)
+  (let* ((branch (magit-get-current-branch))
+         (head (or branch (magit-rev-verify "HEAD"))))
+    (magit-set-header-line-format (format "Preview merge of %s into %s"
+                                          rev
+                                          (or branch "HEAD")))
+    (magit-insert-section (diffbuf)
+      (magit-git-wash #'magit-diff-wash-diffs
+        "merge-tree" (magit-git-string "merge-base" head rev) head rev))))
+
+;;;###autoload
+(defun magit-merge-abort ()
+  "Abort the current merge operation.
+\n(git merge --abort)"
+  (interactive)
+  (unless (file-exists-p (magit-git-dir "MERGE_HEAD"))
+    (user-error "No merge in progress"))
+  (magit-confirm 'abort-merge)
+  (magit-run-git-async "merge" "--abort"))
+
+(defun magit-checkout-stage (file arg)
+  "During a conflict checkout and stage side, or restore conflict."
+  (interactive
+   (let ((file (magit-completing-read "Checkout file"
+                                      (magit-tracked-files) nil nil nil
+                                      'magit-read-file-hist
+                                      (magit-current-file))))
+     (cond ((member file (magit-unmerged-files))
+            (list file (magit-checkout-read-stage file)))
+           ((yes-or-no-p (format "Restore conflicts in %s? " file))
+            (list file "--merge"))
+           (t
+            (user-error "Quit")))))
+  (pcase (cons arg (cddr (car (magit-file-status file))))
+    ((or `("--ours"   ?D ,_)
+         `("--theirs" ,_ ?D))
+     (magit-run-git "rm" "--" file))
+    (_ (if (equal arg "--merge")
+           ;; This fails if the file was deleted on one
+           ;; side.  And we cannot do anything about it.
+           (magit-run-git "checkout" "--merge" "--" file)
+         (magit-call-git "checkout" arg "--" file)
+         (magit-run-git "add" "-u" "--" file)))))
+
+;;; Utilities
+
+(defun magit-merge-in-progress-p ()
+  (file-exists-p (magit-git-dir "MERGE_HEAD")))
+
+(defun magit--merge-range (&optional head)
+  (unless head
+    (setq head (magit-get-shortname
+                (car (magit-file-lines (magit-git-dir "MERGE_HEAD"))))))
+  (and head
+       (concat (magit-git-string "merge-base" "--octopus" "HEAD" head)
+               ".." head)))
+
+(defun magit-merge-assert ()
+  (or (not (magit-anything-modified-p t))
+      (magit-confirm 'merge-dirty
+        "Merging with dirty worktree is risky.  Continue")))
+
+(defun magit-checkout-read-stage (file)
+  (magit-read-char-case (format "For %s checkout: " file) t
+    (?o "[o]ur stage"   "--ours")
+    (?t "[t]heir stage" "--theirs")
+    (?c "[c]onflict"    "--merge")))
+
+;;; Sections
+
+(defvar magit-unmerged-section-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map [remap magit-visit-thing] 'magit-diff-dwim)
+    map)
+  "Keymap for `unmerged' sections.")
+
+(defun magit-insert-merge-log ()
+  "Insert section for the on-going merge.
+Display the heads that are being merged.
+If no merge is in progress, do nothing."
+  (when (magit-merge-in-progress-p)
+    (let* ((heads (mapcar #'magit-get-shortname
+                          (magit-file-lines (magit-git-dir "MERGE_HEAD"))))
+           (range (magit--merge-range (car heads))))
+      (magit-insert-section (unmerged range)
+        (magit-insert-heading
+          (format "Merging %s:" (mapconcat #'identity heads ", ")))
+        (magit-insert-log
+         range
+         (let ((args magit-log-section-arguments))
+           (unless (member "--decorate=full" magit-log-section-arguments)
+             (push "--decorate=full" args))
+           args))))))
+
+(provide 'magit-merge)
+;;; magit-merge.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-merge.elc b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-merge.elc
new file mode 100644
index 0000000000..f8ef12a8ac
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-merge.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-mode.el b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-mode.el
new file mode 100644
index 0000000000..22dced2f6f
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-mode.el
@@ -0,0 +1,1360 @@
+;;; magit-mode.el --- create and refresh Magit buffers  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2010-2018  The Magit Project Contributors
+;;
+;; You should have received a copy of the AUTHORS.md file which
+;; lists all contributors.  If not, see http://magit.vc/authors.
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; Magit 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, or (at your option)
+;; any later version.
+;;
+;; Magit 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 Magit.  If not, see http://www.gnu.org/licenses.
+
+;;; Commentary:
+
+;; This library implements the abstract major-mode `magit-mode' from
+;; which almost all other Magit major-modes derive.  The code in here
+;; is mostly concerned with creating and refreshing Magit buffers.
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'dash)
+
+(require 'magit-section)
+(require 'magit-git)
+(require 'magit-popup)
+
+;; For `magit-display-buffer-fullcolumn-most-v1' from `git-commit'
+(defvar git-commit-mode)
+;; For `magit-xref-insert-buttons' from `magit'
+(defvar magit-diff-show-xref-buttons)
+(defvar magit-revision-show-xref-buttons)
+;; For `magit-refresh' and `magit-refresh-all'
+(declare-function magit-auto-revert-buffers "magit-autorevert" ())
+;; For `magit-refresh-buffer'
+(declare-function magit-process-unset-mode-line-error-status "magit-process" ())
+
+(require 'format-spec)
+(require 'help-mode)
+
+;;; Options
+
+(defcustom magit-mode-hook
+  '(magit-load-config-extensions
+    magit-xref-setup)
+  "Hook run when entering a mode derived from Magit mode."
+  :group 'magit-modes
+  :type 'hook
+  :options '(magit-load-config-extensions
+             magit-xref-setup
+             bug-reference-mode))
+
+(defcustom magit-mode-setup-hook
+  '(magit-maybe-save-repository-buffers
+    magit-set-buffer-margin)
+  "Hook run by `magit-mode-setup'.
+
+This is run right after displaying the buffer and right before
+generating or updating its content.  `magit-mode-hook' and other,
+more specific, `magit-mode-*-hook's on the other hand are run
+right before displaying the buffer.  Usually one of these hooks
+should be used instead of this one."
+  :package-version '(magit . "2.3.0")
+  :group 'magit-modes
+  :type 'hook
+  :options '(magit-maybe-save-repository-buffers
+             magit-set-buffer-margin))
+
+(defcustom magit-pre-refresh-hook '(magit-maybe-save-repository-buffers)
+  "Hook run before refreshing in `magit-refresh'.
+
+This hook, or `magit-post-refresh-hook', should be used
+for functions that are not tied to a particular buffer.
+
+To run a function with a particular buffer current, use
+`magit-refresh-buffer-hook' and use `derived-mode-p'
+inside your function."
+  :package-version '(magit . "2.4.0")
+  :group 'magit-refresh
+  :type 'hook
+  :options '(magit-maybe-save-repository-buffers))
+
+(defcustom magit-post-refresh-hook nil
+  "Hook run after refreshing in `magit-refresh'.
+
+This hook, or `magit-pre-refresh-hook', should be used
+for functions that are not tied to a particular buffer.
+
+To run a function with a particular buffer current, use
+`magit-refresh-buffer-hook' and use `derived-mode-p'
+inside your function."
+  :package-version '(magit . "2.4.0")
+  :group 'magit-refresh
+  :type 'hook)
+
+(defcustom magit-display-buffer-function 'magit-display-buffer-traditional
+  "The function used display a Magit buffer.
+
+All Magit buffers (buffers whose major-modes derive from
+`magit-mode') are displayed using `magit-display-buffer',
+which in turn uses the function specified here."
+  :package-version '(magit . "2.3.0")
+  :group 'magit-buffers
+  :type '(radio (function-item magit-display-buffer-traditional)
+                (function-item magit-display-buffer-same-window-except-diff-v1)
+                (function-item magit-display-buffer-fullframe-status-v1)
+                (function-item magit-display-buffer-fullframe-status-topleft-v1)
+                (function-item magit-display-buffer-fullcolumn-most-v1)
+                (function-item display-buffer)
+                (function :tag "Function")))
+
+(defcustom magit-pre-display-buffer-hook '(magit-save-window-configuration)
+  "Hook run by `magit-display-buffer' before displaying the buffer."
+  :package-version '(magit . "2.3.0")
+  :group 'magit-buffers
+  :type 'hook
+  :get 'magit-hook-custom-get
+  :options '(magit-save-window-configuration))
+
+(defcustom magit-post-display-buffer-hook '(magit-maybe-set-dedicated)
+  "Hook run by `magit-display-buffer' after displaying the buffer."
+  :package-version '(magit . "2.3.0")
+  :group 'magit-buffers
+  :type 'hook
+  :get 'magit-hook-custom-get
+  :options '(magit-maybe-set-dedicated))
+
+(defcustom magit-generate-buffer-name-function
+  'magit-generate-buffer-name-default-function
+  "The function used to generate the name for a Magit buffer."
+  :package-version '(magit . "2.3.0")
+  :group 'magit-buffers
+  :type '(radio (function-item magit-generate-buffer-name-default-function)
+                (function :tag "Function")))
+
+(defcustom magit-buffer-name-format "%x%M%v: %t%x"
+  "The format string used to name Magit buffers.
+
+The following %-sequences are supported:
+
+`%m' The name of the major-mode, but with the `-mode' suffix
+     removed.
+
+`%M' Like \"%m\" but abbreviate `magit-status-mode' as `magit'.
+
+`%v' The value the buffer is locked to, in parentheses, or an
+     empty string if the buffer is not locked to a value.
+
+`%V' Like \"%v\", but the string is prefixed with a space, unless
+     it is an empty string.
+
+`%t' The top-level directory of the working tree of the
+     repository, or if `magit-uniquify-buffer-names' is non-nil
+     an abbreviation of that.
+
+`%x' If `magit-uniquify-buffer-names' is nil \"*\", otherwise the
+     empty string.  Due to limitations of the `uniquify' package,
+     buffer names must end with the path.
+
+`%T' Obsolete, use \"%t%x\" instead.  Like \"%t\", but append an
+     asterisk if and only if `magit-uniquify-buffer-names' is nil.
+
+The value should always contain \"%m\" or \"%M\", \"%v\" or
+\"%V\", and \"%t\" (or the obsolete \"%T\").
+
+If `magit-uniquify-buffer-names' is non-nil, then the value must
+end with \"%t\" or \"%t%x\" (or the obsolete \"%T\").  See issue
+#2841.
+
+This is used by `magit-generate-buffer-name-default-function'.
+If another `magit-generate-buffer-name-function' is used, then
+it may not respect this option, or on the contrary it may
+support additional %-sequences."
+  :package-version '(magit . "2.12.0")
+  :group 'magit-buffers
+  :type 'string)
+
+(defcustom magit-uniquify-buffer-names t
+  "Whether to uniquify the names of Magit buffers."
+  :package-version '(magit . "2.3.0")
+  :group 'magit-buffers
+  :type 'boolean)
+
+(defcustom magit-bury-buffer-function 'magit-restore-window-configuration
+  "The function used to bury or kill the current Magit buffer."
+  :package-version '(magit . "2.3.0")
+  :group 'magit-buffers
+  :type '(radio (function-item quit-window)
+                (function-item magit-mode-quit-window)
+                (function-item magit-restore-window-configuration)
+                (function :tag "Function")))
+
+(defcustom magit-use-sticky-arguments t
+  "How to reuse arguments from existing diff and log buffers.
+
+nil       Always use the default value of the variable
+          `magit-log-arguments' for log commands.  Likewise,
+          always use the default value of the variable
+          `magit-diff-arguments' for diff command calls.
+
+current   If the mode of the current buffer is derived from
+          `magit-log-mode' or `magit-diff-mode', reuse the
+          arguments from that buffer instead of those given by
+          the variable `magit-log-arguments' or
+          `magit-diff-arguments', respectively.
+
+t         Like `current', but if the mode of the current buffer
+          is not derived from `magit-log-mode' or
+          `magit-diff-mode', use the arguments from the current
+          repository's active (i.e. non-locked) `magit-log-mode'
+          or `magit-diff-mode' buffer, respectively, if it
+          exists.
+
+          Note that commands that generate a
+          `magit-revision-mode' or `magit-stash-mode' buffer will
+          also collect their diff arguments from the active
+          `magit-diff-mode' buffer.
+
+In general, there is a separation between the \"sticky\"
+arguments for log and diff buffers, but there is one special
+case: if the current buffer is a log buffer,
+`magit-show-commit' (considered a diff command) uses the file
+filter from the log buffer."
+  :package-version '(magit . "2.11.0")
+  :group 'magit-buffers
+  :type '(choice (const :tag "disabled" nil)
+                 (const :tag "sticky for current" current)
+                 (const :tag "sticky" t)))
+
+(defcustom magit-region-highlight-hook
+  '(magit-section-update-region magit-diff-update-hunk-region)
+  "Functions used to highlight the region.
+
+Each function is run with the current section as only argument
+until one of them returns non-nil.  If all functions return nil,
+then fall back to regular region highlighting."
+  :package-version '(magit . "2.1.0")
+  :group 'magit-refresh
+  :type 'hook
+  :options '(magit-section-update-region magit-diff-update-hunk-region))
+
+(defcustom magit-refresh-verbose nil
+  "Whether to revert Magit buffers verbosely."
+  :package-version '(magit . "2.1.0")
+  :group 'magit-refresh
+  :type 'boolean)
+
+(defcustom magit-refresh-buffer-hook nil
+  "Normal hook for `magit-refresh-buffer' to run after refreshing."
+  :package-version '(magit . "2.1.0")
+  :group 'magit-refresh
+  :type 'hook)
+
+(defcustom magit-refresh-status-buffer t
+  "Whether the status buffer is refreshed after running git.
+
+When this is non-nil, then the status buffer is automatically
+refreshed after running git for side-effects, in addition to the
+current Magit buffer, which is always refreshed automatically.
+
+Only set this to nil after exhausting all other options to
+improve performance."
+  :package-version '(magit . "2.4.0")
+  :group 'magit-refresh
+  :group 'magit-status
+  :type 'boolean)
+
+(defcustom magit-save-repository-buffers t
+  "Whether to save file-visiting buffers when appropriate.
+
+If non-nil, then all modified file-visiting buffers belonging
+to the current repository may be saved before running Magit
+commands and before creating or refreshing Magit buffers.
+If `dontask', then this is done without user intervention, for
+any other non-nil value the user has to confirm each save.
+
+The default is t to avoid surprises, but `dontask' is the
+recommended value."
+  :group 'magit-essentials
+  :group 'magit-buffers
+  :type '(choice (const :tag "Never" nil)
+                 (const :tag "Ask" t)
+                 (const :tag "Save without asking" dontask)))
+
+(defcustom magit-keep-region-overlay nil
+  "Whether to keep the region overlay when there is a valid selection.
+
+By default Magit removes the regular region overlay if, and only
+if, that region constitutes a valid selection as understood by
+Magit commands.  Otherwise it does not remove that overlay, and
+the region looks like it would in other buffers.
+
+There are two types of such valid selections: hunk-internal
+regions and regions that select two or more sibling sections.
+In such cases Magit removes the region overlay and instead
+highlights a slightly larger range.  All text (for hunk-internal
+regions) or the headings of all sections (for sibling selections)
+that are inside that range (not just inside the region) are acted
+on by commands such as the staging command.  This buffer range
+begins at the beginning of the line on which the region begins
+and ends at the end of the line on which the region ends.
+
+Because Magit acts on this larger range and not the region, it is
+actually quite important to visualize that larger range.  If we
+don't do that, then one might think that these commands act on
+the region instead.  If you want to *also* visualize the region,
+then set this option to t.  But please note that when the region
+does *not* constitute a valid selection, then the region is
+*always* visualized as usual, and that it is usually under such
+circumstances that you want to use a non-magit command to act on
+the region.
+
+Besides keeping the region overlay, setting this option to t also
+causes all face properties, except for `:foreground', to be
+ignored for the faces used to highlight headings of selected
+sections.  This avoids the worst conflicts that result from
+displaying the region and the selection overlays at the same
+time.  We are not interested in dealing with other conflicts.
+In fact we *already* provide a way to avoid all of these
+conflicts: *not* changing the value of this option.
+
+It should be clear by now that we consider it a mistake to set
+this to display the region when the Magit selection is also
+visualized, but since it has been requested a few times and
+because it doesn't cost much to offer this option we do so.
+However that might change.  If the existence of this option
+starts complicating other things, then it will be removed."
+  :package-version '(magit . "2.3.0")
+  :group 'magit-miscellaneous
+  :type 'boolean)
+
+;;; Magit Mode
+
+(defvar magit-mode-map
+  (let ((map (make-keymap)))
+    (suppress-keymap map t)
+    (cond ((featurep 'jkl)
+           (define-key map   [return]  'magit-visit-thing)
+           (define-key map [C-return]  'magit-dired-jump)
+           (define-key map   [tab]     'magit-section-toggle)
+           (define-key map [C-tab]     'magit-section-cycle)
+           (define-key map [M-tab]     'magit-section-cycle-diffs)
+           (define-key map [S-tab]     'magit-section-cycle-global)
+           (define-key map (kbd "M-o") 'magit-section-up)
+           (define-key map (kbd   "i") 'magit-section-backward)
+           (define-key map (kbd   "k") 'magit-section-forward)
+           (define-key map (kbd "M-i") 'magit-section-backward-sibling)
+           (define-key map (kbd "M-k") 'magit-section-forward-sibling)
+           (define-key map (kbd   "p") 'magit-push-popup)
+           (define-key map (kbd   ",") 'magit-delete-thing)
+           (define-key map (kbd   ";") 'magit-file-untrack)
+           (define-key map (kbd "C-c C-i") 'magit-gitignore-popup))
+          (t
+           (define-key map [C-return]  'magit-visit-thing)
+           (define-key map (kbd "C-m") 'magit-visit-thing)
+           (define-key map (kbd "C-M-i") 'magit-dired-jump)
+           (define-key map (kbd "C-i") 'magit-section-toggle)
+           (define-key map [C-tab]     'magit-section-cycle)
+           (define-key map [M-tab]     'magit-section-cycle-diffs)
+           ;; [backtab] is the most portable binding for Shift+Tab.
+           (define-key map [backtab]   'magit-section-cycle-global)
+           (define-key map (kbd   "^") 'magit-section-up)
+           (define-key map (kbd   "p") 'magit-section-backward)
+           (define-key map (kbd   "n") 'magit-section-forward)
+           (define-key map (kbd "M-p") 'magit-section-backward-sibling)
+           (define-key map (kbd "M-n") 'magit-section-forward-sibling)
+           (define-key map (kbd   "P") 'magit-push-popup)
+           (define-key map (kbd   "k") 'magit-delete-thing)
+           (define-key map (kbd   "K") 'magit-file-untrack)
+           (define-key map (kbd   "i") 'magit-gitignore)
+           (define-key map (kbd   "I") 'magit-gitignore-popup)))
+    (define-key map (kbd "SPC") 'magit-diff-show-or-scroll-up)
+    (define-key map (kbd "DEL") 'magit-diff-show-or-scroll-down)
+    (define-key map "+"         'magit-diff-more-context)
+    (define-key map "-"         'magit-diff-less-context)
+    (define-key map "0"         'magit-diff-default-context)
+    (define-key map "1"         'magit-section-show-level-1)
+    (define-key map "2"         'magit-section-show-level-2)
+    (define-key map "3"         'magit-section-show-level-3)
+    (define-key map "4"         'magit-section-show-level-4)
+    (define-key map (kbd "M-1") 'magit-section-show-level-1-all)
+    (define-key map (kbd "M-2") 'magit-section-show-level-2-all)
+    (define-key map (kbd "M-3") 'magit-section-show-level-3-all)
+    (define-key map (kbd "M-4") 'magit-section-show-level-4-all)
+    (define-key map "$" 'magit-process-buffer)
+    (define-key map "%" 'magit-worktree-popup)
+    (define-key map "a" 'magit-cherry-apply)
+    (define-key map "A" 'magit-cherry-pick-popup)
+    (define-key map "b" 'magit-branch-popup)
+    (define-key map "B" 'magit-bisect-popup)
+    (define-key map "c" 'magit-commit-popup)
+    (define-key map "d" 'magit-diff-popup)
+    (define-key map "D" 'magit-diff-refresh-popup)
+    (define-key map "e" 'magit-ediff-dwim)
+    (define-key map "E" 'magit-ediff-popup)
+    (define-key map "f" 'magit-fetch-popup)
+    (define-key map "F" 'magit-pull-popup)
+    (define-key map "g" 'magit-refresh)
+    (define-key map "G" 'magit-refresh-all)
+    (define-key map "h" 'magit-dispatch-popup)
+    (define-key map "?" 'magit-dispatch-popup)
+    (define-key map "l" 'magit-log-popup)
+    (define-key map "L" 'magit-log-refresh-popup)
+    (define-key map "m" 'magit-merge-popup)
+    (define-key map "M" 'magit-remote-popup)
+    (define-key map "o" 'magit-submodule-popup)
+    (define-key map "O" 'magit-subtree-popup)
+    (define-key map "q" 'magit-mode-bury-buffer)
+    (define-key map "r" 'magit-rebase-popup)
+    (define-key map "R" 'magit-file-rename)
+    (define-key map "t" 'magit-tag-popup)
+    (define-key map "T" 'magit-notes-popup)
+    (define-key map "s" 'magit-stage-file)
+    (define-key map "S" 'magit-stage-modified)
+    (define-key map "u" 'magit-unstage-file)
+    (define-key map "U" 'magit-unstage-all)
+    (define-key map "v" 'magit-revert-no-commit)
+    (define-key map "V" 'magit-revert-popup)
+    (define-key map "w" 'magit-am-popup)
+    (define-key map "W" 'magit-patch-popup)
+    (define-key map "x" 'magit-reset)
+    (define-key map "X" 'magit-reset-popup)
+    (define-key map "y" 'magit-show-refs-popup)
+    (define-key map "Y" 'magit-cherry)
+    (define-key map "z" 'magit-stash-popup)
+    (define-key map "Z" 'magit-stash-popup)
+    (define-key map ":" 'magit-git-command)
+    (define-key map "!" 'magit-run-popup)
+    (define-key map (kbd "C-c C-b") 'magit-browse-thing)
+    (define-key map (kbd "C-c C-c") 'magit-dispatch-popup)
+    (define-key map (kbd "C-c C-e") 'magit-dispatch-popup)
+    (define-key map (kbd "C-x a")   'magit-add-change-log-entry)
+    (define-key map (kbd "C-x 4 a") 'magit-add-change-log-entry-other-window)
+    (define-key map (kbd "C-w")     'magit-copy-section-value)
+    (define-key map (kbd "M-w")     'magit-copy-buffer-revision)
+    (define-key map [remap evil-previous-line] 'evil-previous-visual-line)
+    (define-key map [remap evil-next-line] 'evil-next-visual-line)
+    map)
+  "Parent keymap for all keymaps of modes derived from `magit-mode'.")
+
+(defun magit-delete-thing ()
+  "This is a placeholder command.
+Where applicable, section-specific keymaps bind another command
+which deletes the thing at point."
+  (interactive)
+  (user-error "There is no thing at point that could be deleted"))
+
+(defun magit-visit-thing ()
+  "This is a placeholder command.
+Where applicable, section-specific keymaps bind another command
+which visits the thing at point."
+  (interactive)
+  (if (eq magit-current-popup 'magit-dispatch-popup)
+      (progn (setq magit-current-popup nil)
+             (call-interactively (key-binding (this-command-keys))))
+    (user-error "There is no thing at point that could be visited")))
+
+(defun magit-browse-thing ()
+  "This is a placeholder command.
+Where applicable, section-specific keymaps bind another command
+which visits the thing at point using `browse-url'."
+  (interactive)
+  (user-error "There is no thing at point that could be browsed"))
+
+(easy-menu-define magit-mode-menu magit-mode-map
+  "Magit menu"
+  '("Magit"
+    ["Refresh" magit-refresh t]
+    ["Refresh all" magit-refresh-all t]
+    "---"
+    ["Stage" magit-stage t]
+    ["Stage modified" magit-stage-modified t]
+    ["Unstage" magit-unstage t]
+    ["Reset index" magit-reset-index t]
+    ["Commit" magit-commit-popup t]
+    ["Add log entry" magit-commit-add-log t]
+    ["Tag" magit-tag t]
+    "---"
+    ["Diff working tree" magit-diff-working-tree t]
+    ["Diff" magit-diff t]
+    ("Log"
+     ["Log" magit-log t]
+     ["Reflog" magit-reflog t]
+     ["Extended..." magit-log-popup t])
+    "---"
+    ["Cherry pick" magit-cherry-pick t]
+    ["Revert commit" magit-revert-popup t]
+    "---"
+    ["Ignore" magit-gitignore t]
+    ["Ignore locally" magit-gitignore-locally t]
+    ["Discard" magit-discard t]
+    ["Reset head" magit-reset-head t]
+    ["Stash" magit-stash t]
+    ["Snapshot" magit-snapshot t]
+    "---"
+    ["Branch..." magit-checkout t]
+    ["Merge" magit-merge t]
+    ["Ediff resolve" magit-ediff-resolve t]
+    ["Rebase..." magit-rebase-popup t]
+    "---"
+    ["Push" magit-push t]
+    ["Pull" magit-pull t]
+    ["Remote update" magit-fetch-all t]
+    ("Submodule"
+     ["Submodule update" magit-submodule-update t]
+     ["Submodule update and init" magit-submodule-setup t]
+     ["Submodule init" magit-submodule-init t]
+     ["Submodule sync" magit-submodule-sync t])
+    "---"
+    ("Extensions")
+    "---"
+    ["Display Git output" magit-process-buffer t]
+    ["Quit Magit" magit-mode-bury-buffer t]))
+
+(defun magit-load-config-extensions ()
+  "Load Magit extensions that are defined at the Git config layer."
+  (dolist (ext (magit-get-all "magit.extension"))
+    (let ((sym (intern (format "magit-%s-mode" ext))))
+      (when (fboundp sym)
+        (funcall sym 1)))))
+
+(define-derived-mode magit-mode special-mode "Magit"
+  "Parent major mode from which Magit major modes inherit.
+
+Magit is documented in info node `(magit)'."
+  :group 'magit-modes
+  (buffer-disable-undo)
+  (setq truncate-lines t)
+  (setq buffer-read-only t)
+  (setq-local line-move-visual t) ; see #1771
+  (setq show-trailing-whitespace nil)
+  (setq list-buffers-directory (abbreviate-file-name default-directory))
+  (hack-dir-local-variables-non-file-buffer)
+  (make-local-variable 'text-property-default-nonsticky)
+  (push (cons 'keymap t) text-property-default-nonsticky)
+  (add-hook 'post-command-hook #'magit-section-update-highlight t t)
+  (add-hook 'deactivate-mark-hook #'magit-section-update-highlight t t)
+  (setq-local redisplay-highlight-region-function 'magit-highlight-region)
+  (setq-local redisplay-unhighlight-region-function 'magit-unhighlight-region)
+  (when (bound-and-true-p global-linum-mode)
+    (linum-mode -1))
+  (when (and (fboundp 'nlinum-mode)
+             (bound-and-true-p global-nlinum-mode))
+    (nlinum-mode -1))
+  (when (and (fboundp 'display-line-numbers-mode)
+             (bound-and-true-p global-display-line-numbers-mode))
+    (display-line-numbers-mode -1))
+  (add-hook 'kill-buffer-hook 'magit-preserve-section-visibility-cache))
+
+(defvar-local magit-region-overlays nil)
+
+(defun magit-delete-region-overlays ()
+  (mapc #'delete-overlay magit-region-overlays)
+  (setq magit-region-overlays nil))
+
+(defun magit-highlight-region (start end window rol)
+  (magit-delete-region-overlays)
+  (if (and (run-hook-with-args-until-success 'magit-region-highlight-hook
+                                             (magit-current-section))
+           (not magit-keep-region-overlay)
+           (not (= (line-number-at-pos start)
+                   (line-number-at-pos end)))
+           ;; (not (eq (car-safe last-command-event) 'mouse-movement))
+           )
+      (funcall (default-value 'redisplay-unhighlight-region-function) rol)
+    (funcall (default-value 'redisplay-highlight-region-function)
+             start end window rol)))
+
+(defun magit-unhighlight-region (rol)
+  (setq magit-section-highlighted-section nil)
+  (magit-delete-region-overlays)
+  (funcall (default-value 'redisplay-unhighlight-region-function) rol))
+
+(defvar-local magit-refresh-args nil
+  "The arguments used to refresh the current buffer.")
+(put 'magit-refresh-args 'permanent-local t)
+
+(defvar-local magit-previous-section nil)
+(put 'magit-previous-section 'permanent-local t)
+
+(defun magit-mode-setup (mode &rest args)
+  "Setup up a MODE buffer using ARGS to generate its content."
+  (magit-mode-setup-internal mode args))
+
+(defun magit-mode-setup-internal (mode args &optional locked)
+  "Setup up a MODE buffer using ARGS to generate its content.
+When optional LOCKED is non-nil, then create a buffer that is
+locked to its value, which is derived from MODE and ARGS."
+  (let ((buffer (magit-mode-get-buffer
+                 mode t nil
+                 (and locked (magit-buffer-lock-value mode args))))
+        (section (magit-current-section)))
+    (with-current-buffer buffer
+      (setq magit-previous-section section)
+      (setq magit-refresh-args args)
+      (funcall mode))
+    (magit-display-buffer buffer)
+    (with-current-buffer buffer
+      (run-hooks 'magit-mode-setup-hook)
+      (magit-refresh-buffer))))
+
+(defvar magit-display-buffer-noselect nil
+  "If non-nil, then `magit-display-buffer' doesn't call `select-window'.")
+
+(defun magit-display-buffer (buffer)
+  "Display BUFFER in some window and maybe select it.
+
+Display the buffer using `magit-display-buffer-function' and
+then, unless `magit-display-buffer-noselect' is non-nil, select
+the window which was used to display the buffer.
+
+Also run the hooks `magit-pre-display-buffer-hook'
+and `magit-post-display-buffer-hook'."
+  (with-current-buffer buffer
+    (run-hooks 'magit-pre-display-buffer-hook))
+  (let ((window (funcall magit-display-buffer-function buffer)))
+    (unless magit-display-buffer-noselect
+      (select-frame-set-input-focus
+       (window-frame
+        (select-window window)))))
+  (with-current-buffer buffer
+    (run-hooks 'magit-post-display-buffer-hook)))
+
+(defun magit-display-buffer-traditional (buffer)
+  "Display BUFFER the way this has traditionally been done."
+  (display-buffer
+   buffer (if (and (derived-mode-p 'magit-mode)
+                   (not (memq (with-current-buffer buffer major-mode)
+                              '(magit-process-mode
+                                magit-revision-mode
+                                magit-diff-mode
+                                magit-stash-mode
+                                magit-status-mode))))
+              '(display-buffer-same-window)
+            nil))) ; display in another window
+
+(defun magit-display-buffer-same-window-except-diff-v1 (buffer)
+  "Display BUFFER in the selected window except for some modes.
+If a buffer's `major-mode' derives from `magit-diff-mode' or
+`magit-process-mode', display it in another window.  Display all
+other buffers in the selected window."
+  (display-buffer
+   buffer (if (with-current-buffer buffer
+                (derived-mode-p 'magit-diff-mode 'magit-process-mode))
+              nil  ; display in another window
+            '(display-buffer-same-window))))
+
+(defun magit--display-buffer-fullframe (buffer alist)
+  (when-let ((window (or (display-buffer-reuse-window buffer alist)
+                         (display-buffer-same-window buffer alist)
+                         (display-buffer-pop-up-window buffer alist)
+                         (display-buffer-use-some-window buffer alist))))
+    (delete-other-windows window)
+    window))
+
+(defun magit-display-buffer-fullframe-status-v1 (buffer)
+  "Display BUFFER, filling entire frame if BUFFER is a status buffer.
+Otherwise, behave like `magit-display-buffer-traditional'."
+  (if (eq (with-current-buffer buffer major-mode)
+          'magit-status-mode)
+      (display-buffer buffer '(magit--display-buffer-fullframe))
+    (magit-display-buffer-traditional buffer)))
+
+(defun magit--display-buffer-topleft (buffer alist)
+  (or (display-buffer-reuse-window buffer alist)
+      (when-let ((window2 (display-buffer-pop-up-window buffer alist)))
+        (let ((window1 (get-buffer-window))
+              (buffer1 (current-buffer))
+              (buffer2 (window-buffer window2))
+              (w2-quit-restore (window-parameter window2 'quit-restore)))
+          (set-window-buffer window1 buffer2)
+          (set-window-buffer window2 buffer1)
+          (select-window window2)
+          ;; Swap some window state that `magit-mode-quit-window' and
+          ;; `quit-restore-window' inspect.
+          (set-window-prev-buffers window2 (cdr (window-prev-buffers window1)))
+          (set-window-prev-buffers window1 nil)
+          (set-window-parameter window2 'magit-dedicated
+                                (window-parameter window1 'magit-dedicated))
+          (set-window-parameter window1 'magit-dedicated t)
+          (set-window-parameter window1 'quit-restore
+                                (list 'window 'window
+                                      (nth 2 w2-quit-restore)
+                                      (nth 3 w2-quit-restore)))
+          (set-window-parameter window2 'quit-restore nil)
+          window1))))
+
+(defun magit-display-buffer-fullframe-status-topleft-v1 (buffer)
+  "Display BUFFER, filling entire frame if BUFFER is a status buffer.
+When BUFFER derives from `magit-diff-mode' or
+`magit-process-mode', try to display BUFFER to the top or left of
+the current buffer rather than to the bottom or right, as
+`magit-display-buffer-fullframe-status-v1' would.  Whether the
+split is made vertically or horizontally is determined by
+`split-window-preferred-function'."
+  (display-buffer
+   buffer
+   (cond ((eq (with-current-buffer buffer major-mode)
+              'magit-status-mode)
+          '(magit--display-buffer-fullframe))
+         ((with-current-buffer buffer
+            (derived-mode-p 'magit-diff-mode 'magit-process-mode))
+          '(magit--display-buffer-topleft))
+         (t
+          '(display-buffer-same-window)))))
+
+(defun magit--display-buffer-fullcolumn (buffer alist)
+  (when-let ((window (or (display-buffer-reuse-window buffer alist)
+                         (display-buffer-same-window buffer alist)
+                         (display-buffer-below-selected buffer alist))))
+    (delete-other-windows-vertically window)
+    window))
+
+(defun magit-display-buffer-fullcolumn-most-v1 (buffer)
+  "Display BUFFER using the full column except in some cases.
+For most cases where BUFFER's `major-mode' derives from
+`magit-mode', display it in the selected window and grow that
+window to the full height of the frame, deleting other windows in
+that column as necessary.  However, display BUFFER in another
+window if 1) BUFFER's mode derives from `magit-process-mode', or
+2) BUFFER's mode derives from `magit-diff-mode', provided that
+the mode of the current buffer derives from `magit-log-mode' or
+`magit-cherry-mode'."
+  (display-buffer
+   buffer
+   (cond ((and (or git-commit-mode
+                   (derived-mode-p 'magit-log-mode 'magit-cherry-mode))
+               (with-current-buffer buffer
+                 (derived-mode-p 'magit-diff-mode)))
+          nil)
+         ((with-current-buffer buffer
+            (derived-mode-p 'magit-process-mode))
+          nil)
+         (t
+          '(magit--display-buffer-fullcolumn)))))
+
+(defun magit-maybe-set-dedicated ()
+  "Mark the selected window as dedicated if appropriate.
+
+If a new window was created to display the buffer, then remember
+that fact.  That information is used by `magit-mode-quit-window',
+to determine whether the window should be deleted when its last
+Magit buffer is buried."
+  (let ((window (get-buffer-window (current-buffer))))
+    (when (and (window-live-p window)
+               (not (window-prev-buffers window)))
+      (set-window-parameter window 'magit-dedicated t))))
+
+(defvar-local magit--default-directory nil
+  "Value of `default-directory' when buffer is generated.
+This exists to prevent a let-bound `default-directory' from
+tricking `magit-mode-get-buffer' or `magit-mode-get-buffers' into
+thinking a buffer belongs to a repo that it doesn't.")
+(put 'magit--default-directory 'permanent-local t)
+
+(defun magit-mode-get-buffers ()
+  (let ((topdir (magit-toplevel)))
+    (--filter (with-current-buffer it
+                (and (derived-mode-p 'magit-mode)
+                     (equal magit--default-directory topdir)))
+              (buffer-list))))
+
+(defvar-local magit-buffer-locked-p nil)
+(put 'magit-buffer-locked-p 'permanent-local t)
+
+(defun magit-mode-get-buffer (mode &optional create frame value)
+  (if-let ((topdir (magit-toplevel)))
+      (or (--first (with-current-buffer it
+                     (and (eq major-mode mode)
+                          (equal magit--default-directory topdir)
+                          (if value
+                              (and magit-buffer-locked-p
+                                   (equal (magit-buffer-lock-value) value))
+                            (not magit-buffer-locked-p))))
+                   (if frame
+                       (mapcar #'window-buffer
+                               (window-list (unless (eq frame t) frame)))
+                     (buffer-list)))
+          (and create
+               (let ((default-directory topdir))
+                 (magit-generate-new-buffer mode value))))
+    (magit--not-inside-repository-error)))
+
+(defun magit-generate-new-buffer (mode &optional value)
+  (let* ((name (funcall magit-generate-buffer-name-function mode value))
+         (buffer (generate-new-buffer name)))
+    (with-current-buffer buffer
+      (setq magit--default-directory default-directory)
+      (setq magit-buffer-locked-p (and value t))
+      (magit-restore-section-visibility-cache mode))
+    (when magit-uniquify-buffer-names
+      (add-to-list 'uniquify-list-buffers-directory-modes mode)
+      (with-current-buffer buffer
+        (setq list-buffers-directory (abbreviate-file-name default-directory)))
+      (let ((uniquify-buffer-name-style
+             (if (memq uniquify-buffer-name-style '(nil forward))
+                 'post-forward-angle-brackets
+               uniquify-buffer-name-style)))
+        (uniquify-rationalize-file-buffer-names
+         name (file-name-directory (directory-file-name default-directory))
+         buffer)))
+    buffer))
+
+(defun magit-generate-buffer-name-default-function (mode &optional value)
+  "Generate buffer name for a MODE buffer in the current repository.
+The returned name is based on `magit-buffer-name-format' and
+takes `magit-uniquify-buffer-names' and VALUE, if non-nil, into
+account."
+  (let ((m (substring (symbol-name mode) 0 -5))
+        (v (and value (format "%s" (if (listp value) value (list value)))))
+        (n (if magit-uniquify-buffer-names
+               (file-name-nondirectory
+                (directory-file-name default-directory))
+             (abbreviate-file-name default-directory))))
+    (format-spec
+     magit-buffer-name-format
+     `((?m . ,m)
+       (?M . ,(if (eq mode 'magit-status-mode) "magit" m))
+       (?v . ,(or v ""))
+       (?V . ,(if v (concat " " v) ""))
+       (?t . ,n)
+       (?x . ,(if magit-uniquify-buffer-names "" "*"))
+       (?T . ,(if magit-uniquify-buffer-names n (concat n "*")))))))
+
+(defun magit-toggle-buffer-lock ()
+  "Lock the current buffer to its value or unlock it.
+
+Locking a buffer to its value prevents it from being reused to
+display another value.  The name of a locked buffer contains its
+value, which allows telling it apart from other locked buffers
+and the unlocked buffer.
+
+Not all Magit buffers can be locked to their values, for example
+it wouldn't make sense to lock a status buffer.
+
+There can only be a single unlocked buffer using a certain
+major-mode per repository.  So when a buffer is being unlocked
+and another unlocked buffer already exists for that mode and
+repository, then the former buffer is instead deleted and the
+latter is displayed in its place."
+  (interactive)
+  (if magit-buffer-locked-p
+      (if-let ((unlocked (magit-mode-get-buffer major-mode)))
+          (let ((locked (current-buffer)))
+            (switch-to-buffer unlocked nil t)
+            (kill-buffer locked))
+        (setq magit-buffer-locked-p nil)
+        (rename-buffer (funcall magit-generate-buffer-name-function
+                                major-mode)))
+    (if-let ((value (magit-buffer-lock-value)))
+        (if-let ((locked (magit-mode-get-buffer major-mode nil nil value)))
+            (let ((unlocked (current-buffer)))
+              (switch-to-buffer locked nil t)
+              (kill-buffer unlocked))
+          (setq magit-buffer-locked-p t)
+          (rename-buffer (funcall magit-generate-buffer-name-function
+                                  major-mode value)))
+      (user-error "Buffer has no value it could be locked to"))))
+
+(defvar magit-buffer-lock-functions nil
+  "Provide buffer-locking support for third-party modes.
+An alist of symbols to functions.
+
+The symbol must be the major-mode the locked buffer will have.
+
+The function must take a list of arguments and return a value
+that identifies the buffer (i.e., its 'lock value').  If the
+third-party mode is invoked as
+
+    (magit-mode-setup-internal #\\='my-mode \\='(1 2 3) t)
+
+the function will be invoked as
+
+    (apply lock-func \\='(1 2 3))
+
+if the cons (my-mode . lock-func) is in this list.
+
+This variable is intended for third-party extensions;
+`magit-buffer-lock-value' implements all built-in behavior.
+
+See also `magit-toggle-buffer-lock'.")
+
+(cl-defun magit-buffer-lock-value
+    (&optional (mode major-mode)
+               (args magit-refresh-args))
+  "Find an appropriate buffer lock value for MODE under ARGS.
+See also `magit-buffer-lock-functions'."
+  (cl-case mode
+    (magit-cherry-mode
+     (pcase-let ((`(,upstream ,head) args))
+       (concat head ".." upstream)))
+    (magit-diff-mode
+     (pcase-let ((`(,rev-or-range ,const ,_args ,files) args))
+       (nconc (cons (or rev-or-range
+                        (if (member "--cached" const)
+                            (progn (setq const (delete "--cached" const))
+                                   'staged)
+                          'unstaged))
+                    const)
+              (and files (cons "--" files)))))
+    (magit-log-mode
+     (pcase-let ((`(,revs ,_args ,files) args))
+       (if (and revs files)
+           (append revs (cons "--" files))
+         (append revs files))))
+    (magit-refs-mode
+     (pcase-let ((`(,ref ,args) args))
+       (cons (or ref "HEAD") args)))
+    (magit-revision-mode
+     (pcase-let ((`(,rev ,_const ,_args ,files) args))
+       (if files (cons rev files) (list rev))))
+    ((magit-reflog-mode   ; (ref ~args)
+      magit-stash-mode    ; (stash _const _args _files)
+      magit-stashes-mode) ; (ref)
+     (car args))
+    (t
+     (--when-let (cdr (assq mode magit-buffer-lock-functions))
+       (apply it args)))))
+
+(defun magit-mode-bury-buffer (&optional kill-buffer)
+  "Bury the current buffer.
+With a prefix argument, kill the buffer instead.
+This is done using `magit-bury-buffer-function'."
+  (interactive "P")
+  (funcall magit-bury-buffer-function kill-buffer))
+
+(defun magit-mode-quit-window (kill-buffer)
+  "Quit the selected window and bury its buffer.
+
+This behaves similar to `quit-window', but when the window
+was originally created to display a Magit buffer and the
+current buffer is the last remaining Magit buffer that was
+ever displayed in the selected window, then delete that
+window."
+  (if (or (one-window-p)
+          (--first (let ((buffer (car it)))
+                     (and (not (eq buffer (current-buffer)))
+                          (buffer-live-p buffer)
+                          (or (not (window-parameter nil 'magit-dedicated))
+                              (with-current-buffer buffer
+                                (derived-mode-p 'magit-mode
+                                                'magit-process-mode)))))
+                   (window-prev-buffers)))
+      (quit-window kill-buffer)
+    (let ((window (selected-window)))
+      (quit-window kill-buffer)
+      (when (window-live-p window)
+        (delete-window window)))))
+
+;;; Refresh Magit Buffers
+
+(defvar inhibit-magit-refresh nil)
+
+(defun magit-refresh ()
+  "Refresh some buffers belonging to the current repository.
+
+Refresh the current buffer if its major mode derives from
+`magit-mode', and refresh the corresponding status buffer.
+
+Run hooks `magit-pre-refresh-hook' and `magit-post-refresh-hook'."
+  (interactive)
+  (unless inhibit-magit-refresh
+    (unwind-protect
+        (let ((start (current-time))
+              (magit--refresh-cache (or magit--refresh-cache
+                                        (list (cons 0 0)))))
+          (when magit-refresh-verbose
+            (message "Refreshing magit..."))
+          (magit-run-hook-with-benchmark 'magit-pre-refresh-hook)
+          (when (derived-mode-p 'magit-mode)
+            (magit-refresh-buffer))
+          (--when-let (and magit-refresh-status-buffer
+                           (not (derived-mode-p 'magit-status-mode))
+                           (magit-mode-get-buffer 'magit-status-mode))
+            (with-current-buffer it
+              (magit-refresh-buffer)))
+          (magit-auto-revert-buffers)
+          (magit-run-hook-with-benchmark 'magit-post-refresh-hook)
+          (when magit-refresh-verbose
+            (message "Refreshing magit...done (%.3fs, cached %s/%s)"
+                     (float-time (time-subtract (current-time) start))
+                     (caar magit--refresh-cache)
+                     (+ (caar magit--refresh-cache)
+                        (cdar magit--refresh-cache)))))
+      (run-hooks 'magit-unwind-refresh-hook))))
+
+(defun magit-refresh-all ()
+  "Refresh all buffers belonging to the current repository.
+
+Refresh all Magit buffers belonging to the current repository,
+and revert buffers that visit files located inside the current
+repository.
+
+Run hooks `magit-pre-refresh-hook' and `magit-post-refresh-hook'."
+  (interactive)
+  (magit-run-hook-with-benchmark 'magit-pre-refresh-hook)
+  (dolist (buffer (magit-mode-get-buffers))
+    (with-current-buffer buffer (magit-refresh-buffer)))
+  (magit-auto-revert-buffers)
+  (magit-run-hook-with-benchmark 'magit-post-refresh-hook))
+
+(defvar-local magit-refresh-start-time nil)
+
+(defun magit-refresh-buffer ()
+  "Refresh the current Magit buffer."
+  (setq magit-refresh-start-time (current-time))
+  (let ((refresh (intern (format "%s-refresh-buffer"
+                                 (substring (symbol-name major-mode) 0 -5))))
+        (magit--refresh-cache (or magit--refresh-cache (list (cons 0 0)))))
+    (when (functionp refresh)
+      (when magit-refresh-verbose
+        (message "Refreshing buffer `%s'..." (buffer-name)))
+      (let* ((buffer (current-buffer))
+             (windows
+              (--mapcat (with-selected-window it
+                          (with-current-buffer buffer
+                            (when-let ((section (magit-current-section)))
+                              (list
+                               (nconc (list it section)
+                                      (magit-refresh-get-relative-position))))))
+                        (or (get-buffer-window-list buffer nil t)
+                            (list (selected-window))))))
+        (deactivate-mark)
+        (setq magit-section-highlight-overlays nil)
+        (setq magit-section-highlighted-section nil)
+        (setq magit-section-highlighted-sections nil)
+        (setq magit-section-unhighlight-sections nil)
+        (magit-process-unset-mode-line-error-status)
+        (let ((inhibit-read-only t))
+          (erase-buffer)
+          (save-excursion
+            (apply refresh magit-refresh-args)))
+        (dolist (window windows)
+          (with-selected-window (car window)
+            (with-current-buffer buffer
+              (apply #'magit-section-goto-successor (cdr window)))))
+        (run-hooks 'magit-refresh-buffer-hook)
+        (magit-section-update-highlight)
+        (set-buffer-modified-p nil))
+      (when magit-refresh-verbose
+        (message "Refreshing buffer `%s'...done (%.3fs)" (buffer-name)
+                 (float-time (time-subtract (current-time)
+                                            magit-refresh-start-time)))))))
+
+(defun magit-refresh-get-relative-position ()
+  (when-let ((section (magit-current-section)))
+    (let ((start (oref section start)))
+      (list (count-lines start (point))
+            (- (point) (line-beginning-position))
+            (and (magit-hunk-section-p section)
+                 (region-active-p)
+                 (progn (goto-char (line-beginning-position))
+                        (when  (looking-at "^[-+]") (forward-line))
+                        (while (looking-at "^[ @]") (forward-line))
+                        (let ((beg (point)))
+                          (cond ((looking-at "^[-+]")
+                                 (forward-line)
+                                 (while (looking-at "^[-+]") (forward-line))
+                                 (while (looking-at "^ ")    (forward-line))
+                                 (forward-line -1)
+                                 (regexp-quote (buffer-substring-no-properties
+                                                beg (line-end-position))))
+                                (t t)))))))))
+
+;;; Save File-Visiting Buffers
+
+(defvar disable-magit-save-buffers nil)
+
+(defun magit-pre-command-hook ()
+  (setq disable-magit-save-buffers nil))
+(add-hook 'pre-command-hook #'magit-pre-command-hook)
+
+(defvar magit-after-save-refresh-buffers nil)
+
+(defun magit-after-save-refresh-buffers ()
+  (dolist (buffer magit-after-save-refresh-buffers)
+    (when (buffer-live-p buffer)
+      (with-current-buffer buffer
+        (magit-refresh-buffer))))
+  (setq magit-after-save-refresh-buffers nil)
+  (remove-hook 'post-command-hook 'magit-after-save-refresh-buffers))
+
+(defun magit-after-save-refresh-status ()
+  "Refresh the status buffer of the current repository.
+
+This function is intended to be added to `after-save-hook'.
+
+If the status buffer does not exist or the file being visited in
+the current buffer isn't inside the working tree of a repository,
+then do nothing.
+
+Note that refreshing a Magit buffer is done by re-creating its
+contents from scratch, which can be slow in large repositories.
+If you are not satisfied with Magit's performance, then you
+should obviously not add this function to that hook."
+  (when (and (not disable-magit-save-buffers)
+             (magit-inside-worktree-p t))
+    (--when-let (ignore-errors (magit-mode-get-buffer 'magit-status-mode))
+      (add-to-list 'magit-after-save-refresh-buffers it)
+      (add-hook 'post-command-hook 'magit-after-save-refresh-buffers))))
+
+(defun magit-maybe-save-repository-buffers ()
+  "Maybe save file-visiting buffers belonging to the current repository.
+Do so if `magit-save-repository-buffers' is non-nil.  You should
+not remove this from any hooks, instead set that variable to nil
+if you so desire."
+  (when (and magit-save-repository-buffers
+             (not disable-magit-save-buffers))
+    (setq disable-magit-save-buffers t)
+    (let ((msg (current-message)))
+      (magit-save-repository-buffers
+       (eq magit-save-repository-buffers 'dontask))
+      (when (and msg
+                 (current-message)
+                 (not (equal msg (current-message))))
+        (message "%s" msg)))))
+
+(add-hook 'magit-pre-refresh-hook #'magit-maybe-save-repository-buffers)
+(add-hook 'magit-pre-call-git-hook #'magit-maybe-save-repository-buffers)
+(add-hook 'magit-pre-start-git-hook #'magit-maybe-save-repository-buffers)
+
+(defvar-local magit-inhibit-refresh-save nil)
+
+(defun magit-save-repository-buffers (&optional arg)
+  "Save file-visiting buffers belonging to the current repository.
+After any buffer where `buffer-save-without-query' is non-nil
+is saved without asking, the user is asked about each modified
+buffer which visits a file in the current repository.  Optional
+argument (the prefix) non-nil means save all with no questions."
+  (interactive "P")
+  (when-let ((topdir (magit-rev-parse-safe "--show-toplevel")))
+    (let ((remote (file-remote-p topdir))
+          (save-some-buffers-action-alist
+           `((?Y (lambda (buffer)
+                   (with-current-buffer buffer
+                     (setq buffer-save-without-query t)
+                     (save-buffer)))
+                 "to save the current buffer and remember choice")
+             (?N (lambda (buffer)
+                   (with-current-buffer buffer
+                     (setq magit-inhibit-refresh-save t)))
+                 "to skip the current buffer and remember choice")
+             ,@save-some-buffers-action-alist)))
+      (save-some-buffers
+       arg (lambda ()
+             (and (not magit-inhibit-refresh-save)
+                  buffer-file-name
+                  (file-exists-p (file-name-directory buffer-file-name))
+                  ;; Avoid needlessly connecting to unrelated remotes.
+                  (equal (file-remote-p buffer-file-name)
+                         remote)
+                  (string-prefix-p topdir (file-truename buffer-file-name))
+                  (equal (magit-rev-parse-safe "--show-toplevel")
+                         topdir)))))))
+
+;;; Restore Window Configuration
+
+(defvar magit-inhibit-save-previous-winconf nil)
+
+(defvar-local magit-previous-window-configuration nil)
+(put 'magit-previous-window-configuration 'permanent-local t)
+
+(defun magit-save-window-configuration ()
+  "Save the current window configuration.
+
+Later, when the buffer is buried, it may be restored by
+`magit-restore-window-configuration'."
+  (if magit-inhibit-save-previous-winconf
+      (when (eq magit-inhibit-save-previous-winconf 'unset)
+        (setq magit-previous-window-configuration nil))
+    (unless (get-buffer-window (current-buffer) (selected-frame))
+      (setq magit-previous-window-configuration
+            (current-window-configuration)))))
+
+(defun magit-restore-window-configuration (&optional kill-buffer)
+  "Bury or kill the current buffer and restore previous window configuration."
+  (let ((winconf magit-previous-window-configuration)
+        (buffer (current-buffer))
+        (frame (selected-frame)))
+    (quit-window kill-buffer (selected-window))
+    (when (and winconf (equal frame (window-configuration-frame winconf)))
+      (set-window-configuration winconf)
+      (when (buffer-live-p buffer)
+        (with-current-buffer buffer
+          (setq magit-previous-window-configuration nil))))))
+
+;;; Buffer History
+
+(defun magit-go-backward ()
+  "Move backward in current buffer's history."
+  (interactive)
+  (if help-xref-stack
+      (help-xref-go-back (current-buffer))
+    (user-error "No previous entry in buffer's history")))
+
+(defun magit-go-forward ()
+  "Move forward in current buffer's history."
+  (interactive)
+  (if help-xref-forward-stack
+      (help-xref-go-forward (current-buffer))
+    (user-error "No next entry in buffer's history")))
+
+(defun magit-insert-xref-buttons (&optional _)
+  "Insert xref buttons."
+  (when (or help-xref-stack help-xref-forward-stack)
+    (when help-xref-stack
+      (magit-xref-insert-button help-back-label 'magit-xref-backward))
+    (when help-xref-forward-stack
+      (when help-xref-stack
+        (insert " "))
+      (magit-xref-insert-button help-forward-label 'magit-xref-forward))))
+
+(defun magit-xref-insert-button (label type)
+  (magit-insert-section (button label)
+    (insert-text-button label 'type type
+                        'help-args (list (current-buffer)))))
+
+(define-button-type 'magit-xref-backward
+  :supertype 'help-back
+  'mouse-face 'magit-section-highlight
+  'help-echo (purecopy "mouse-2, RET: go back to previous history entry"))
+
+(define-button-type 'magit-xref-forward
+  :supertype 'help-forward
+  'mouse-face 'magit-section-highlight
+  'help-echo (purecopy "mouse-2, RET: go back to next history entry"))
+
+(defun magit-xref-setup ()
+  "Insert backward/forward buttons if the major-mode supports it.
+Currently `magit-log-mode', `magit-reflog-mode',
+`magit-diff-mode', and `magit-revision-mode' support it"
+  (when (memq major-mode '(magit-log-mode
+                           magit-reflog-mode
+                           magit-diff-mode
+                           magit-revision-mode))
+    (when help-xref-stack-item
+      (push (cons (point) help-xref-stack-item) help-xref-stack)
+      (setq help-xref-forward-stack nil))
+    (when (called-interactively-p 'interactive)
+      (--when-let (nthcdr 10 help-xref-stack)
+        (setcdr it nil)))
+    (setq help-xref-stack-item
+          `(magit-xref-restore ,default-directory ,@magit-refresh-args))))
+
+(defun magit-xref-restore (&rest args)
+  (magit-xref-setup)
+  (setq default-directory  (car args))
+  (setq magit-refresh-args (cdr args))
+  (magit-refresh-buffer))
+
+;;; Repository-Local Cache
+
+(defvar magit-repository-local-cache nil
+  "Alist mapping `magit-toplevel' paths to alists of key/value pairs.")
+
+(defun magit-repository-local-repository ()
+  "Return the key for the current repository."
+  (or (bound-and-true-p magit--default-directory)
+      (magit-toplevel)))
+
+(defun magit-repository-local-set (key value &optional repository)
+  "Set the repository-local VALUE for KEY.
+
+Unless specified, REPOSITORY is the current buffer's repository.
+
+If REPOSITORY is nil (meaning there is no current repository),
+then the value is not cached, and we return nil."
+  (let* ((repokey (or repository (magit-repository-local-repository)))
+         (cache (assoc repokey magit-repository-local-cache)))
+    ;; Don't cache values for a nil REPOSITORY, as the 'set' and 'get'
+    ;; calls for some KEY may happen in unrelated contexts.
+    (when repokey
+      (if cache
+          (let ((keyvalue (assoc key (cdr cache))))
+            (if keyvalue
+                ;; Update pre-existing value for key.
+                (setcdr keyvalue value)
+              ;; No such key in repository-local cache.
+              (push (cons key value) (cdr cache))))
+        ;; No cache for this repository.
+        (push (cons repokey (list (cons key value)))
+              magit-repository-local-cache)))))
+
+(defun magit-repository-local-exists-p (key &optional repository)
+  "Non-nil when a repository-local value exists for KEY.
+
+Returns a (KEY . value) cons cell.
+
+The KEY is matched using `equal'.
+
+Unless specified, REPOSITORY is the current buffer's repository."
+  (let* ((repokey (or repository (magit-repository-local-repository)))
+         (cache (assoc repokey magit-repository-local-cache)))
+    (and cache
+         (assoc key (cdr cache)))))
+
+(defun magit-repository-local-get (key &optional default repository)
+  "Return the repository-local value for KEY.
+
+Return DEFAULT if no value for KEY exists.
+
+The KEY is matched using `equal'.
+
+Unless specified, REPOSITORY is the current buffer's repository."
+  (let ((keyvalue (magit-repository-local-exists-p key repository)))
+    (if keyvalue
+        (cdr keyvalue)
+      default)))
+
+(defun magit-repository-local-delete (key &optional repository)
+  "Delete the repository-local value for KEY.
+
+Unless specified, REPOSITORY is the current buffer's repository."
+  (let* ((repokey (or repository (magit-repository-local-repository)))
+         (cache (assoc repokey magit-repository-local-cache)))
+    (when cache
+      ;; There is no `assoc-delete-all'.
+      (setf (cdr cache)
+            (cl-delete key (cdr cache) :key #'car :test #'equal)))))
+
+(defun magit-zap-caches ()
+  "Zap caches for the current repository.
+Remove the repository's entry from `magit-repository-cache'
+and set `magit-section-visibility-cache' to nil in all of the
+repository's Magit buffers."
+  (interactive)
+  (magit-with-toplevel
+    (setq magit-repository-local-cache
+          (cl-delete default-directory
+                     magit-repository-local-cache
+                     :key #'car :test #'equal)))
+  (dolist (buffer (magit-mode-get-buffers))
+    (with-current-buffer buffer
+      (setq magit-section-visibility-cache nil))))
+
+;;; Utilities
+
+(defun magit-run-hook-with-benchmark (hook)
+  (when hook
+    (if magit-refresh-verbose
+        (let ((start (current-time)))
+          (message "Running %s..." hook)
+          (run-hooks hook)
+          (message "Running %s...done (%.3fs)" hook
+                   (float-time (time-subtract (current-time) start))))
+      (run-hooks hook))))
+
+(provide 'magit-mode)
+;;; magit-mode.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-mode.elc b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-mode.elc
new file mode 100644
index 0000000000..82bef7695c
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-mode.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-notes.el b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-notes.el
new file mode 100644
index 0000000000..79b2fa5314
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-notes.el
@@ -0,0 +1,201 @@
+;;; magit-notes.el --- notes support  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2010-2018  The Magit Project Contributors
+;;
+;; You should have received a copy of the AUTHORS.md file which
+;; lists all contributors.  If not, see http://magit.vc/authors.
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; Magit 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, or (at your option)
+;; any later version.
+;;
+;; Magit 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 Magit.  If not, see http://www.gnu.org/licenses.
+
+;;; Commentary:
+
+;; This library implements support for `git-notes'.
+
+;;; Code:
+
+(require 'magit)
+
+;;; Popup
+
+;;;###autoload (autoload 'magit-notes-popup "magit" nil t)
+(magit-define-popup magit-notes-popup
+  "Popup console for notes commands."
+  :man-page "git-notes"
+  :variables '("Configure local settings"
+               (?c "core.notesRef"
+                   magit-set-core.notesRef
+                   magit-format-core.notesRef)
+               (?d "notes.displayRef"
+                   magit-set-notes.displayRef
+                   magit-format-notes.displayRef)
+               "Configure global settings"
+               (?C "core.notesRef"
+                   magit-set-global-core.notesRef
+                   magit-format-global-core.notesRef)
+               (?D "notes.displayRef"
+                   magit-set-global-notes.displayRef
+                   magit-format-global-notes.displayRef))
+  :switches '("Switch for prune"
+              (?n "Dry run"          "--dry-run"))
+  :options  '("Option for edit and remove"
+              (?r "Manipulate ref"   "--ref=" magit-notes-popup-read-ref)
+              "Option for merge"
+              (?s "Merge strategy"   "--strategy="))
+  :actions  '((?T "Edit"             magit-notes-edit)
+              (?r "Remove"           magit-notes-remove)
+              (?m "Merge"            magit-notes-merge)
+              (?p "Prune"            magit-notes-prune))
+  :sequence-actions '((?c "Commit merge" magit-notes-merge-commit)
+                      (?a "Abort merge"  magit-notes-merge-abort))
+  :sequence-predicate 'magit-notes-merging-p
+  :default-action 'magit-notes-edit)
+
+(defun magit-notes-merging-p ()
+  (let ((dir (magit-git-dir "NOTES_MERGE_WORKTREE")))
+    (and (file-directory-p dir)
+         (directory-files dir nil "^[^.]"))))
+
+(defun magit-format-core.notesRef ()
+  (magit--format-popup-variable:value "core.notesRef" 22))
+
+(defun magit-format-notes.displayRef ()
+  (magit--format-popup-variable:values "notes.displayRef" 22))
+
+(defun magit-format-global-core.notesRef ()
+  (magit--format-popup-variable:value "core.notesRef" 22 t))
+
+(defun magit-format-global-notes.displayRef ()
+  (magit--format-popup-variable:values "notes.displayRef" 22 t))
+
+;;; Commands
+
+(defun magit-notes-edit (commit &optional ref)
+  "Edit the note attached to COMMIT.
+REF is the notes ref used to store the notes.
+
+Interactively or when optional REF is nil use the value of Git
+variable `core.notesRef' or \"refs/notes/commits\" if that is
+undefined."
+  (interactive (magit-notes-read-args "Edit notes"))
+  (magit-run-git-with-editor "notes" (and ref (concat "--ref=" ref))
+                             "edit" commit))
+
+(defun magit-notes-remove (commit &optional ref)
+  "Remove the note attached to COMMIT.
+REF is the notes ref from which the note is removed.
+
+Interactively or when optional REF is nil use the value of Git
+variable `core.notesRef' or \"refs/notes/commits\" if that is
+undefined."
+  (interactive (magit-notes-read-args "Remove notes"))
+  (magit-run-git-with-editor "notes" (and ref (concat "--ref=" ref))
+                             "remove" commit))
+
+(defun magit-notes-merge (ref)
+  "Merge the notes ref REF into the current notes ref.
+
+The current notes ref is the value of Git variable
+`core.notesRef' or \"refs/notes/commits\" if that is undefined.
+
+When there are conflicts, then they have to be resolved in the
+temporary worktree \".git/NOTES_MERGE_WORKTREE\".  When
+done use `magit-notes-merge-commit' to finish.  To abort
+use `magit-notes-merge-abort'."
+  (interactive (list (magit-read-string-ns "Merge reference")))
+  (magit-run-git-with-editor "notes" "merge" ref))
+
+(defun magit-notes-merge-commit ()
+  "Commit the current notes ref merge.
+Also see `magit-notes-merge'."
+  (interactive)
+  (magit-run-git-with-editor "notes" "merge" "--commit"))
+
+(defun magit-notes-merge-abort ()
+  "Abort the current notes ref merge.
+Also see `magit-notes-merge'."
+  (interactive)
+  (magit-run-git-with-editor "notes" "merge" "--abort"))
+
+(defun magit-notes-prune (&optional dry-run)
+  "Remove notes about unreachable commits."
+  (interactive (list (and (member "--dry-run" (magit-notes-arguments)) t)))
+  (when dry-run
+    (magit-process-buffer))
+  (magit-run-git-with-editor "notes" "prune" (and dry-run "--dry-run")))
+
+(defun magit-set-core.notesRef (ref)
+  "Set the local value of `core.notesRef' to REF."
+  (interactive (list (magit-notes-read-ref "Set local core.notesRef")))
+  (magit-set ref "core.notesRef")
+  (magit-with-pre-popup-buffer
+    (magit-refresh)))
+
+(defun magit-set-global-core.notesRef (ref)
+  "Set the global value of `core.notesRef' to REF."
+  (interactive (list (magit-notes-read-ref "Set global core.notesRef")))
+  (magit-set ref "--global" "core.notesRef")
+  (magit-with-pre-popup-buffer
+    (magit-refresh)))
+
+(defun magit-set-notes.displayRef (refs)
+  "Set the local values of `notes.displayRef' to REFS."
+  (interactive (list (magit-notes-read-refs "Set local notes.displayRef")))
+  (magit-set-all refs "notes.displayRef")
+  (magit-with-pre-popup-buffer
+    (magit-refresh)))
+
+(defun magit-set-global-notes.displayRef (refs)
+  "Set the global values of `notes.displayRef' to REFS."
+  (interactive (list (magit-notes-read-refs "Set global notes.displayRef")))
+  (magit-set-all refs "--global" "notes.displayRef")
+  (magit-with-pre-popup-buffer
+    (magit-refresh)))
+
+(defun magit-notes-read-ref (prompt)
+  (--when-let (magit-completing-read
+               prompt (magit-list-notes-refnames) nil nil
+               (--when-let (magit-get "core.notesRef")
+                 (if (string-prefix-p "refs/notes/" it)
+                     (substring it 11)
+                   it)))
+    (if (string-prefix-p "refs/" it)
+        it
+      (concat "refs/notes/" it))))
+
+(defun magit-notes-read-refs (prompt)
+  (mapcar (lambda (ref)
+            (if (string-prefix-p "refs/" ref)
+                ref
+              (concat "refs/notes/" ref)))
+          (completing-read-multiple
+           (concat prompt ": ")
+           (magit-list-notes-refnames) nil nil
+           (mapconcat (lambda (ref)
+                        (if (string-prefix-p "refs/notes/" ref)
+                            (substring ref 11)
+                          ref))
+                      (magit-get-all "notes.displayRef")
+                      ","))))
+
+(defun magit-notes-read-args (prompt)
+ (list (magit-read-branch-or-commit prompt (magit-stash-at-point))
+       (--when-let (--first (string-match "^--ref=\\(.+\\)" it)
+                            (magit-notes-arguments))
+         (match-string 1 it))))
+
+(provide 'magit-notes)
+;;; magit-notes.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-notes.elc b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-notes.elc
new file mode 100644
index 0000000000..763dcff44f
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-notes.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-obsolete.el b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-obsolete.el
new file mode 100644
index 0000000000..57ab7c090f
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-obsolete.el
@@ -0,0 +1,33 @@
+;;; magit-obsolete.el --- obsolete definitions  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2010-2018  The Magit Project Contributors
+;;
+;; You should have received a copy of the AUTHORS.md file which
+;; lists all contributors.  If not, see http://magit.vc/authors.
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; Magit 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, or (at your option)
+;; any later version.
+;;
+;; Magit 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 Magit.  If not, see http://www.gnu.org/licenses.
+
+;;; Commentary:
+
+;; This library defines aliases for obsolete variables and functions.
+
+;;; Code:
+
+(require 'magit)
+
+(provide 'magit-obsolete)
+;;; magit-obsolete.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-obsolete.elc b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-obsolete.elc
new file mode 100644
index 0000000000..a53f23629c
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-obsolete.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-pkg.el b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-pkg.el
new file mode 100644
index 0000000000..6f12d65d4f
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-pkg.el
@@ -0,0 +1,11 @@
+(define-package "magit" "20180719.1904" "A Git porcelain inside Emacs."
+  '((emacs "25.1")
+    (async "20180527")
+    (dash "20180413")
+    (ghub "20180417")
+    (git-commit "20180602")
+    (magit-popup "20180509")
+    (with-editor "20180414")))
+;; Local Variables:
+;; no-byte-compile: t
+;; End:
diff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-process.el b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-process.el
new file mode 100644
index 0000000000..4be163b43d
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-process.el
@@ -0,0 +1,1099 @@
+;;; magit-process.el --- process functionality  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2010-2018  The Magit Project Contributors
+;;
+;; You should have received a copy of the AUTHORS.md file which
+;; lists all contributors.  If not, see http://magit.vc/authors.
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; Magit 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, or (at your option)
+;; any later version.
+;;
+;; Magit 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 Magit.  If not, see http://www.gnu.org/licenses.
+
+;;; Commentary:
+
+;; This library implements the tools used to run Git for side-effects.
+
+;; Note that the functions used to run Git and then consume its
+;; output, are defined in `magit-git.el'.  There's a bit of overlap
+;; though.
+
+;;; Code:
+
+(require 'ansi-color)
+(require 'cl-lib)
+(require 'dash)
+
+(require 'with-editor)
+(require 'magit-utils)
+(require 'magit-section)
+(require 'magit-git)
+(require 'magit-mode)
+
+(declare-function auth-source-search "auth-source"
+                  (&rest spec &key max require create delete &allow-other-keys))
+
+;;; Options
+
+(defcustom magit-process-connection-type (not (eq system-type 'cygwin))
+  "Connection type used for the Git process.
+
+If nil, use pipes: this is usually more efficient, and works on Cygwin.
+If t, use ptys: this enables Magit to prompt for passphrases when needed."
+  :group 'magit-process
+  :type '(choice (const :tag "pipe" nil)
+                 (const :tag "pty" t)))
+
+(defcustom magit-need-cygwin-noglob
+  (and (eq system-type 'windows-nt)
+       (with-temp-buffer
+         (let ((process-environment
+                (append magit-git-environment process-environment)))
+           (condition-case e
+               (process-file magit-git-executable
+                             nil (current-buffer) nil
+                             "-c" "alias.echo=!echo" "echo" "x{0}")
+             (file-error
+              (lwarn 'magit-process :warning
+                     "Could not run Git: %S" e))))
+         (equal "x0\n" (buffer-string))))
+  "Whether to use a workaround for Cygwin's globbing behavior.
+
+If non-nil, add environment variables to `process-environment' to
+prevent the git.exe distributed by Cygwin and MSYS2 from
+attempting to perform glob expansion when called from a native
+Windows build of Emacs.  See #2246."
+  :package-version '(magit . "2.3.0")
+  :group 'magit-process
+  :type '(choice (const :tag "Yes" t)
+                 (const :tag "No" nil)))
+
+(defcustom magit-process-popup-time -1
+  "Popup the process buffer if a command takes longer than this many seconds."
+  :group 'magit-process
+  :type '(choice (const :tag "Never" -1)
+                 (const :tag "Immediately" 0)
+                 (integer :tag "After this many seconds")))
+
+(defcustom magit-process-log-max 32
+  "Maximum number of sections to keep in a process log buffer.
+When adding a new section would go beyond the limit set here,
+then the older half of the sections are remove.  Sections that
+belong to processes that are still running are never removed.
+When this is nil, no sections are ever removed."
+  :package-version '(magit . "2.1.0")
+  :group 'magit-process
+  :type '(choice (const :tag "Never remove old sections" nil) integer))
+
+(defcustom magit-process-error-tooltip-max-lines 20
+  "The number of lines for `magit-process-error-lines' to return.
+
+These are displayed in a tooltip for `mode-line-process' errors.
+
+If `magit-process-error-tooltip-max-lines' is nil, the tooltip
+displays the text of `magit-process-error-summary' instead."
+  :package-version '(magit . "2.12.0")
+  :group 'magit-process
+  :type '(choice (const :tag "Use summary line" nil)
+                 integer))
+
+(defcustom magit-credential-cache-daemon-socket
+  (--some (pcase-let ((`(,prog . ,args) (split-string it)))
+            (if (and prog
+                     (string-match-p
+                      "\\`\\(?:\\(?:/.*/\\)?git-credential-\\)?cache\\'" prog))
+                (or (cl-loop for (opt val) on args
+                             if (string= opt "--socket")
+                             return val)
+                    (expand-file-name "~/.git-credential-cache/socket"))))
+          ;; Note: `magit-process-file' is not yet defined when
+          ;; evaluating this form, so we use `process-lines'.
+          (ignore-errors
+            (let ((process-environment
+                   (append magit-git-environment process-environment)))
+              (process-lines magit-git-executable
+                             "config" "--get-all" "credential.helper"))))
+  "If non-nil, start a credential cache daemon using this socket.
+
+When using Git's cache credential helper in the normal way, Emacs
+sends a SIGHUP to the credential daemon after the git subprocess
+has exited, causing the daemon to also quit.  This can be avoided
+by starting the `git-credential-cache--daemon' process directly
+from Emacs.
+
+The function `magit-maybe-start-credential-cache-daemon' takes
+care of starting the daemon if necessary, using the value of this
+option as the socket.  If this option is nil, then it does not
+start any daemon.  Likewise if another daemon is already running,
+then it starts no new daemon.  This function has to be a member
+of the hook variable `magit-credential-hook' for this to work.
+If an error occurs while starting the daemon, most likely because
+the necessary executable is missing, then the function removes
+itself from the hook, to avoid further futile attempts."
+  :package-version '(magit . "2.3.0")
+  :group 'magit-process
+  :type '(choice (file  :tag "Socket")
+                 (const :tag "Don't start a cache daemon" nil)))
+
+(defcustom magit-process-yes-or-no-prompt-regexp
+  " [\[(]\\([Yy]\\(?:es\\)?\\)[/|]\\([Nn]o?\\)[\])] ?[?:] ?$"
+  "Regexp matching Yes-or-No prompts of Git and its subprocesses."
+  :package-version '(magit . "2.1.0")
+  :group 'magit-process
+  :type 'regexp)
+
+(defcustom magit-process-password-prompt-regexps
+  '("^\\(Enter \\)?[Pp]assphrase\\( for \\(RSA \\)?key '.*'\\)?: ?$"
+    ;; match-group 99 is used to identify a host
+    "^\\(Enter \\)?[Pp]assword\\( for '\\(?99:.*\\)'\\)?: ?$"
+    "^.*'s password: ?$"
+    "^Yubikey for .*: ?$"
+    "^Enter PIN for .*: ?$")
+  "List of regexps matching password prompts of Git and its subprocesses.
+Also see `magit-process-find-password-functions'."
+  :package-version '(magit . "2.8.0")
+  :group 'magit-process
+  :type '(repeat (regexp)))
+
+(defcustom magit-process-find-password-functions nil
+  "List of functions to try in sequence to get a password.
+
+These functions may be called when git asks for a password, which
+is detected using `magit-process-password-prompt-regexps'.  They
+are called if and only if matching the prompt resulted in the
+value of the 99th submatch to be non-nil.  Therefore users can
+control for which prompts these functions should be called by
+putting the host name in the 99th submatch, or not.
+
+If the functions are called, then they are called in the order
+given, with the host name as only argument, until one of them
+returns non-nil.  If they are not called or none of them returns
+non-nil, then the password is read from the user instead."
+  :package-version '(magit . "2.3.0")
+  :group 'magit-process
+  :type 'hook
+  :options '(magit-process-password-auth-source))
+
+(defcustom magit-process-username-prompt-regexps
+  '("^Username for '.*': ?$")
+  "List of regexps matching username prompts of Git and its subprocesses."
+  :package-version '(magit . "2.1.0")
+  :group 'magit-process
+  :type '(repeat (regexp)))
+
+(defcustom magit-process-ensure-unix-line-ending t
+  "Whether Magit should ensure a unix coding system when talking to Git."
+  :package-version '(magit . "2.6.0")
+  :group 'magit-process
+  :type 'boolean)
+
+(defcustom magit-process-display-mode-line-error t
+  "Whether Magit should retain and highlight process errors in the mode line."
+  :package-version '(magit . "2.12.0")
+  :group 'magit-process
+  :type 'boolean)
+
+(defface magit-process-ok
+  '((t :inherit magit-section-heading :foreground "green"))
+  "Face for zero exit-status."
+  :group 'magit-faces)
+
+(defface magit-process-ng
+  '((t :inherit magit-section-heading :foreground "red"))
+  "Face for non-zero exit-status."
+  :group 'magit-faces)
+
+(defface magit-mode-line-process
+  '((t :inherit mode-line-emphasis))
+  "Face for `mode-line-process' status when Git is running for side-effects."
+  :group 'magit-faces)
+
+(defface magit-mode-line-process-error
+  '((t :inherit error))
+  "Face for `mode-line-process' error status.
+
+Used when `magit-process-display-mode-line-error' is non-nil."
+  :group 'magit-faces)
+
+;;; Process Mode
+
+(defvar magit-process-mode-map
+  (let ((map (make-sparse-keymap)))
+    (set-keymap-parent map magit-mode-map)
+    map)
+  "Keymap for `magit-process-mode'.")
+
+(define-derived-mode magit-process-mode magit-mode "Magit Process"
+  "Mode for looking at Git process output."
+  :group 'magit-process
+  (hack-dir-local-variables-non-file-buffer)
+  (setq imenu-prev-index-position-function
+        'magit-imenu--process-prev-index-position-function)
+  (setq imenu-extract-index-name-function
+        'magit-imenu--process-extract-index-name-function))
+
+(defun magit-process-buffer (&optional nodisplay)
+  "Display the current repository's process buffer.
+
+If that buffer doesn't exist yet, then create it.
+Non-interactively return the buffer and unless
+optional NODISPLAY is non-nil also display it."
+  (interactive)
+  (let ((topdir (magit-toplevel)))
+    (unless topdir
+      (magit--with-safe-default-directory nil
+        (setq topdir default-directory)
+        (let (prev)
+          (while (not (equal topdir prev))
+            (setq prev topdir)
+            (setq topdir (file-name-directory (directory-file-name topdir)))))))
+    (let ((buffer (or (--first (with-current-buffer it
+                                 (and (eq major-mode 'magit-process-mode)
+                                      (equal default-directory topdir)))
+                               (buffer-list))
+                      (let ((default-directory topdir))
+                        (magit-generate-new-buffer 'magit-process-mode)))))
+      (with-current-buffer buffer
+        (if magit-root-section
+            (when magit-process-log-max
+              (magit-process-truncate-log))
+          (magit-process-mode)
+          (let ((inhibit-read-only t)
+                (magit-insert-section--parent  nil)
+                (magit-insert-section--oldroot nil))
+            (make-local-variable 'text-property-default-nonsticky)
+            (magit-insert-section (processbuf)
+              (insert "\n")))))
+      (unless nodisplay
+        (magit-display-buffer buffer))
+      buffer)))
+
+(defun magit-process-kill ()
+  "Kill the process at point."
+  (interactive)
+  (magit-section-when process
+    (let ((process (oref it value)))
+      (unless (eq (process-status process) 'run)
+        (user-error "Process isn't running"))
+      (magit-confirm 'kill-process)
+      (kill-process process))))
+
+;;; Synchronous Processes
+
+(defvar magit-process-raise-error nil)
+
+(defun magit-git (&rest args)
+  "Call Git synchronously in a separate process, for side-effects.
+
+Option `magit-git-executable' specifies the Git executable.
+The arguments ARGS specify arguments to Git, they are flattened
+before use.
+
+Process output goes into a new section in the buffer returned by
+`magit-process-buffer'.  If Git exits with a non-zero status,
+then raise an error."
+  (let ((magit-process-raise-error t))
+    (magit-call-git args)))
+
+(defun magit-run-git (&rest args)
+  "Call Git synchronously in a separate process, and refresh.
+
+Option `magit-git-executable' specifies the Git executable and
+option `magit-git-global-arguments' specifies constant arguments.
+The arguments ARGS specify arguments to Git, they are flattened
+before use.
+
+After Git returns, the current buffer (if it is a Magit buffer)
+as well as the current repository's status buffer are refreshed.
+
+Process output goes into a new section in the buffer returned by
+`magit-process-buffer'."
+  (let ((magit--refresh-cache (list (cons 0 0))))
+    (magit-call-git args)
+    (when (member (car args) '("init" "clone"))
+      ;; Creating a new repository invalidates the cache.
+      (setq magit--refresh-cache nil))
+    (magit-refresh)))
+
+(defvar magit-pre-call-git-hook nil)
+
+(defun magit-call-git (&rest args)
+  "Call Git synchronously in a separate process.
+
+Option `magit-git-executable' specifies the Git executable and
+option `magit-git-global-arguments' specifies constant arguments.
+The arguments ARGS specify arguments to Git, they are flattened
+before use.
+
+Process output goes into a new section in the buffer returned by
+`magit-process-buffer'."
+  (run-hooks 'magit-pre-call-git-hook)
+  (let ((default-process-coding-system (magit--process-coding-system)))
+    (apply #'magit-call-process magit-git-executable
+           (magit-process-git-arguments args))))
+
+(defun magit-call-process (program &rest args)
+  "Call PROGRAM synchronously in a separate process.
+Process output goes into a new section in the buffer returned by
+`magit-process-buffer'."
+  (pcase-let ((`(,process-buf . ,section)
+               (magit-process-setup program args)))
+    (magit-process-finish
+     (let ((inhibit-read-only t))
+       (apply #'magit-process-file program nil process-buf nil args))
+     process-buf (current-buffer) default-directory section)))
+
+(defun magit-process-file (process &optional infile buffer display &rest args)
+  "Process files synchronously in a separate process.
+Identical to `process-file' but temporarily enable Cygwin's
+\"noglob\" option during the call and ensure unix eol
+conversion."
+  (let ((process-environment (magit-process-environment))
+        (default-process-coding-system (magit--process-coding-system)))
+    (apply #'process-file process infile buffer display args)))
+
+(defun magit-process-environment ()
+  ;; The various w32 hacks are only applicable when running on the
+  ;; local machine.  As of Emacs 25.1, a local binding of
+  ;; process-environment different from the top-level value affects
+  ;; the environment used in
+  ;; tramp-sh-handle-{start-file-process,process-file}.
+  (let ((local (not (file-remote-p default-directory))))
+    (append magit-git-environment
+            (and local
+                 (cdr (assoc magit-git-executable magit-git-w32-path-hack)))
+            (and local magit-need-cygwin-noglob
+                 (mapcar (lambda (var)
+                           (concat var "=" (--if-let (getenv var)
+                                               (concat it " noglob")
+                                             "noglob")))
+                         '("CYGWIN" "MSYS")))
+            process-environment)))
+
+(defvar magit-this-process nil)
+
+(defun magit-run-git-with-input (&rest args)
+  "Call Git in a separate process.
+ARGS is flattened and then used as arguments to Git.
+
+The current buffer's content is used as the process' standard
+input.
+
+Option `magit-git-executable' specifies the Git executable and
+option `magit-git-global-arguments' specifies constant arguments.
+The remaining arguments ARGS specify arguments to Git, they are
+flattened before use."
+  (declare (indent 1))
+  (when (eq system-type 'windows-nt)
+    ;; On w32, git expects UTF-8 encoded input, ignore any user
+    ;; configuration telling us otherwise (see #3250).
+    (encode-coding-region (point-min) (point-max) 'utf-8-unix))
+  (if (file-remote-p default-directory)
+      ;; We lack `process-file-region', so fall back to asynch +
+      ;; waiting in remote case.
+      (progn
+        (magit-start-git (current-buffer) args)
+        (while (and magit-this-process
+                    (eq (process-status magit-this-process) 'run))
+          (sleep-for 0.005)))
+    (run-hooks 'magit-pre-call-git-hook)
+    (pcase-let* ((process-environment (magit-process-environment))
+                 (default-process-coding-system (magit--process-coding-system))
+                 (flat-args (magit-process-git-arguments args))
+                 (`(,process-buf . ,section)
+                  (magit-process-setup magit-git-executable flat-args))
+                 (inhibit-read-only t))
+      (magit-process-finish
+       (apply #'call-process-region (point-min) (point-max)
+              magit-git-executable nil process-buf nil flat-args)
+       process-buf nil default-directory section))))
+
+(defun magit-run-git-with-logfile (file &rest args)
+  "Call Git in a separate process and log its output to FILE.
+This function might have a short halflive."
+  (apply #'magit-process-file magit-git-executable nil `(:file ,file) nil
+         (magit-process-git-arguments args))
+  (magit-refresh))
+
+;;; Asynchronous Processes
+
+(defun magit-run-git-async (&rest args)
+  "Start Git, prepare for refresh, and return the process object.
+ARGS is flattened and then used as arguments to Git.
+
+Display the command line arguments in the echo area.
+
+After Git returns some buffers are refreshed: the buffer that was
+current when this function was called (if it is a Magit buffer
+and still alive), as well as the respective Magit status buffer.
+
+See `magit-start-process' for more information."
+  (message "Running %s %s" magit-git-executable
+           (let ((m (mapconcat #'identity (-flatten args) " ")))
+             (remove-list-of-text-properties 0 (length m) '(face) m)
+             m))
+  (magit-start-git nil args))
+
+(defun magit-run-git-with-editor (&rest args)
+  "Export GIT_EDITOR and start Git.
+Also prepare for refresh and return the process object.
+ARGS is flattened and then used as arguments to Git.
+
+Display the command line arguments in the echo area.
+
+After Git returns some buffers are refreshed: the buffer that was
+current when this function was called (if it is a Magit buffer
+and still alive), as well as the respective Magit status buffer.
+
+See `magit-start-process' and `with-editor' for more information."
+  (magit--record-separated-gitdir)
+  (magit-with-editor (magit-run-git-async args)))
+
+(defun magit-run-git-sequencer (&rest args)
+  "Export GIT_EDITOR and start Git.
+Also prepare for refresh and return the process object.
+ARGS is flattened and then used as arguments to Git.
+
+Display the command line arguments in the echo area.
+
+After Git returns some buffers are refreshed: the buffer that was
+current when this function was called (if it is a Magit buffer
+and still alive), as well as the respective Magit status buffer.
+If the sequence stops at a commit, make the section representing
+that commit the current section by moving `point' there.
+
+See `magit-start-process' and `with-editor' for more information."
+  (apply #'magit-run-git-with-editor args)
+  (set-process-sentinel magit-this-process #'magit-sequencer-process-sentinel)
+  magit-this-process)
+
+(defvar magit-pre-start-git-hook nil)
+
+(defun magit-start-git (input &rest args)
+  "Start Git, prepare for refresh, and return the process object.
+
+If INPUT is non-nil, it has to be a buffer or the name of an
+existing buffer.  The buffer content becomes the processes
+standard input.
+
+Option `magit-git-executable' specifies the Git executable and
+option `magit-git-global-arguments' specifies constant arguments.
+The remaining arguments ARGS specify arguments to Git, they are
+flattened before use.
+
+After Git returns some buffers are refreshed: the buffer that was
+current when this function was called (if it is a Magit buffer
+and still alive), as well as the respective Magit status buffer.
+
+See `magit-start-process' for more information."
+  (run-hooks 'magit-pre-start-git-hook)
+  (let ((default-process-coding-system (magit--process-coding-system)))
+    (apply #'magit-start-process magit-git-executable input
+           (magit-process-git-arguments args))))
+
+(defun magit-start-process (program &optional input &rest args)
+  "Start PROGRAM, prepare for refresh, and return the process object.
+
+If optional argument INPUT is non-nil, it has to be a buffer or
+the name of an existing buffer.  The buffer content becomes the
+processes standard input.
+
+The process is started using `start-file-process' and then setup
+to use the sentinel `magit-process-sentinel' and the filter
+`magit-process-filter'.  Information required by these functions
+is stored in the process object.  When this function returns the
+process has not started to run yet so it is possible to override
+the sentinel and filter.
+
+After the process returns, `magit-process-sentinel' refreshes the
+buffer that was current when `magit-start-process' was called (if
+it is a Magit buffer and still alive), as well as the respective
+Magit status buffer."
+  (pcase-let*
+      ((`(,process-buf . ,section)
+        (magit-process-setup program args))
+       (process
+        (let ((process-connection-type
+               ;; Don't use a pty, because it would set icrnl
+               ;; which would modify the input (issue #20).
+               (and (not input) magit-process-connection-type))
+              (process-environment (magit-process-environment))
+              (default-process-coding-system (magit--process-coding-system)))
+          (apply #'start-file-process
+                 (file-name-nondirectory program)
+                 process-buf program args))))
+    (with-editor-set-process-filter process #'magit-process-filter)
+    (set-process-sentinel process #'magit-process-sentinel)
+    (set-process-buffer   process process-buf)
+    (when (eq system-type 'windows-nt)
+      ;; On w32, git expects UTF-8 encoded input, ignore any user
+      ;; configuration telling us otherwise.
+      (set-process-coding-system process 'utf-8-unix))
+    (process-put process 'section section)
+    (process-put process 'command-buf (current-buffer))
+    (process-put process 'default-dir default-directory)
+    (when inhibit-magit-refresh
+      (process-put process 'inhibit-refresh t))
+    (oset section process process)
+    (with-current-buffer process-buf
+      (set-marker (process-mark process) (point)))
+    (when input
+      (with-current-buffer input
+        (process-send-region process (point-min) (point-max))
+        (process-send-eof    process)))
+    (setq magit-this-process process)
+    (oset section value process)
+    (magit-process-display-buffer process)
+    process))
+
+(defun magit-parse-git-async (&rest args)
+  (setq args (magit-process-git-arguments args))
+  (let ((command-buf (current-buffer))
+        (process-buf (generate-new-buffer " *temp*"))
+        (toplevel (magit-toplevel)))
+    (with-current-buffer process-buf
+      (setq default-directory toplevel)
+      (let ((process
+             (let ((process-connection-type nil)
+                   (process-environment (magit-process-environment))
+                   (default-process-coding-system
+                     (magit--process-coding-system)))
+               (apply #'start-file-process "git" process-buf
+                      magit-git-executable args))))
+        (process-put process 'command-buf command-buf)
+        (process-put process 'parsed (point))
+        (setq magit-this-process process)
+        process))))
+
+;;; Process Internals
+
+(defun magit-process-setup (program args)
+  (magit-process-set-mode-line program args)
+  (let ((pwd default-directory)
+        (buf (magit-process-buffer t)))
+    (cons buf (with-current-buffer buf
+                (prog1 (magit-process-insert-section pwd program args nil nil)
+                  (backward-char 1))))))
+
+(defun magit-process-insert-section (pwd program args &optional errcode errlog)
+  (let ((inhibit-read-only t)
+        (magit-insert-section--parent magit-root-section)
+        (magit-insert-section--oldroot nil))
+    (goto-char (1- (point-max)))
+    (magit-insert-section (process)
+      (insert (if errcode
+                  (format "%3s " (propertize (number-to-string errcode)
+                                             'face 'magit-process-ng))
+                "run "))
+      (unless (equal (expand-file-name pwd)
+                     (expand-file-name default-directory))
+        (insert (file-relative-name pwd default-directory) ?\s))
+      (cond
+       ((and args (equal program magit-git-executable))
+        (setq args (-split-at (length magit-git-global-arguments) args))
+        (insert (propertize program 'face 'magit-section-heading) " ")
+        (insert (propertize (char-to-string magit-ellipsis)
+                            'face 'magit-section-heading
+                            'help-echo (mapconcat #'identity (car args) " ")))
+        (insert " ")
+        (insert (propertize (mapconcat #'shell-quote-argument (cadr args) " ")
+                            'face 'magit-section-heading)))
+       ((and args (equal program shell-file-name))
+        (insert (propertize (cadr args) 'face 'magit-section-heading)))
+       (t
+        (insert (propertize program 'face 'magit-section-heading) " ")
+        (insert (propertize (mapconcat #'shell-quote-argument args " ")
+                            'face 'magit-section-heading))))
+      (magit-insert-heading)
+      (when errlog
+        (insert-file-contents errlog)
+        (goto-char (1- (point-max))))
+      (insert "\n"))))
+
+(defun magit-process-truncate-log ()
+  (let* ((head nil)
+         (tail (oref magit-root-section children))
+         (count (length tail)))
+    (when (> (1+ count) magit-process-log-max)
+      (while (and (cdr tail)
+                  (> count (/ magit-process-log-max 2)))
+        (let* ((inhibit-read-only t)
+               (section (car tail))
+               (process (oref section process)))
+          (cond ((not process))
+                ((memq (process-status process) '(exit signal))
+                 (delete-region (oref section start)
+                                (1+ (oref section end)))
+                 (cl-decf count))
+                (t
+                 (push section head))))
+        (pop tail))
+      (oset magit-root-section children
+            (nconc (reverse head) tail)))))
+
+(defun magit-process-sentinel (process event)
+  "Default sentinel used by `magit-start-process'."
+  (when (memq (process-status process) '(exit signal))
+    (setq event (substring event 0 -1))
+    (when (string-match "^finished" event)
+      (message (concat (capitalize (process-name process)) " finished")))
+    (magit-process-finish process)
+    (when (eq process magit-this-process)
+      (setq magit-this-process nil))
+    (unless (process-get process 'inhibit-refresh)
+      (let ((command-buf (process-get process 'command-buf)))
+        (if (buffer-live-p command-buf)
+            (with-current-buffer command-buf
+              (magit-refresh))
+          (with-temp-buffer
+            (setq default-directory (process-get process 'default-dir))
+            (magit-refresh)))))))
+
+(defun magit-sequencer-process-sentinel (process event)
+  "Special sentinel used by `magit-run-git-sequencer'."
+  (when (memq (process-status process) '(exit signal))
+    (magit-process-sentinel process event)
+    (when-let ((process-buf (process-buffer process)))
+      (when (buffer-live-p process-buf)
+        (when-let ((status-buf (with-current-buffer process-buf
+                                 (magit-mode-get-buffer 'magit-status-mode))))
+          (with-current-buffer status-buf
+            (--when-let
+                (magit-get-section
+                 `((commit . ,(magit-rev-parse "HEAD"))
+                   (,(pcase (car (cadr (-split-at
+                                        (1+ (length magit-git-global-arguments))
+                                        (process-command process))))
+                       ((or "rebase" "am")   'rebase-sequence)
+                       ((or "cherry-pick" "revert") 'sequence)))
+                   (status)))
+              (goto-char (oref it start))
+              (magit-section-update-highlight))))))))
+
+(defun magit-process-filter (proc string)
+  "Default filter used by `magit-start-process'."
+  (with-current-buffer (process-buffer proc)
+    (let ((inhibit-read-only t))
+      (magit-process-yes-or-no-prompt proc string)
+      (magit-process-username-prompt  proc string)
+      (magit-process-password-prompt  proc string)
+      (goto-char (process-mark proc))
+      (setq string (propertize string 'magit-section
+                               (process-get proc 'section)))
+      ;; Find last ^M in string.  If one was found, ignore
+      ;; everything before it and delete the current line.
+      (let ((ret-pos (length string)))
+        (while (and (>= (cl-decf ret-pos) 0)
+                    (/= ?\r (aref string ret-pos))))
+        (if (< ret-pos 0)
+            (insert string)
+          (delete-region (line-beginning-position) (point))
+          (insert (substring string (1+ ret-pos)))))
+      (set-marker (process-mark proc) (point)))))
+
+(defmacro magit-process-kill-on-abort (proc &rest body)
+  (declare (indent 1) (debug (form body)))
+  (let ((map (cl-gensym)))
+    `(let ((,map (make-sparse-keymap)))
+       (set-keymap-parent ,map minibuffer-local-map)
+       (define-key ,map "\C-g"
+         (lambda ()
+           (interactive)
+           (ignore-errors (kill-process ,proc))
+           (abort-recursive-edit)))
+       (let ((minibuffer-local-map ,map))
+         ,@body))))
+
+(defun magit-process-yes-or-no-prompt (process string)
+  "Forward Yes-or-No prompts to the user."
+  (when-let ((beg (string-match magit-process-yes-or-no-prompt-regexp string)))
+    (let ((max-mini-window-height 30))
+      (process-send-string
+       process
+       (downcase
+        (concat
+         (match-string
+          (if (save-match-data
+                (magit-process-kill-on-abort process
+                  (yes-or-no-p (substring string 0 beg)))) 1 2)
+          string)
+         "\n"))))))
+
+(defun magit-process-password-auth-source (key)
+  "Use `auth-source-search' to get a password.
+If found, return the password.  Otherwise, return nil."
+  (require 'auth-source)
+  (let ((secret (plist-get (car (auth-source-search :max 1 :host key
+                                                    :require '(:host)))
+                           :secret)))
+    (if (functionp secret)
+        (funcall secret)
+      secret)))
+
+(defun magit-process-password-prompt (process string)
+  "Find a password based on prompt STRING and send it to git.
+Use `magit-process-password-prompt-regexps' to find a known
+prompt.  If and only if one is found, then call functions in
+`magit-process-find-password-functions' until one of them returns
+the password.  If all function return nil, then read the password
+from the user."
+  (--when-let (magit-process-match-prompt
+               magit-process-password-prompt-regexps string)
+    (process-send-string
+     process (magit-process-kill-on-abort process
+               (concat (or (--when-let (match-string 99 string)
+                             (run-hook-with-args-until-success
+                              'magit-process-find-password-functions it))
+                           (read-passwd it))
+                       "\n")))))
+
+(defun magit-process-username-prompt (process string)
+  "Forward username prompts to the user."
+  (--when-let (magit-process-match-prompt
+               magit-process-username-prompt-regexps string)
+    (process-send-string
+     process (magit-process-kill-on-abort process
+               (concat (read-string it nil nil (user-login-name)) "\n")))))
+
+(defun magit-process-match-prompt (prompts string)
+  "Match STRING against PROMPTS and set match data.
+Return the matched string suffixed with \": \", if needed."
+  (when (--any-p (string-match it string) prompts)
+    (let ((prompt (match-string 0 string)))
+      (cond ((string-suffix-p ": " prompt) prompt)
+            ((string-suffix-p ":"  prompt) (concat prompt " "))
+            (t                             (concat prompt ": "))))))
+
+(defun magit--process-coding-system ()
+  (let ((fro (or magit-git-output-coding-system
+                 (car default-process-coding-system)))
+        (to (cdr default-process-coding-system)))
+    (if magit-process-ensure-unix-line-ending
+        (cons (coding-system-change-eol-conversion fro 'unix)
+              (coding-system-change-eol-conversion to 'unix))
+      (cons fro to))))
+
+(defvar magit-credential-hook nil
+  "Hook run before Git needs credentials.")
+
+(defvar magit-credential-cache-daemon-process nil)
+
+(defun magit-maybe-start-credential-cache-daemon ()
+  "Maybe start a `git-credential-cache--daemon' process.
+
+If such a process is already running or if the value of option
+`magit-credential-cache-daemon-socket' is nil, then do nothing.
+Otherwise start the process passing the value of that options
+as argument."
+  (unless (or (not magit-credential-cache-daemon-socket)
+              (process-live-p magit-credential-cache-daemon-process)
+              (memq magit-credential-cache-daemon-process
+                    (list-system-processes)))
+    (setq magit-credential-cache-daemon-process
+          (or (--first (let* ((attr (process-attributes it))
+                              (comm (cdr (assq 'comm attr)))
+                              (user (cdr (assq 'user attr))))
+                         (and (string= comm "git-credential-cache--daemon")
+                              (string= user user-login-name)))
+                       (list-system-processes))
+              (condition-case nil
+                  (start-process "git-credential-cache--daemon"
+                                 " *git-credential-cache--daemon*"
+                                 magit-git-executable
+                                 "credential-cache--daemon"
+                                 magit-credential-cache-daemon-socket)
+                ;; Some Git implementations (e.g. Windows) won't have
+                ;; this program; if we fail the first time, stop trying.
+                ((debug error)
+                 (remove-hook 'magit-credential-hook
+                              #'magit-maybe-start-credential-cache-daemon)))))))
+
+(add-hook 'magit-credential-hook #'magit-maybe-start-credential-cache-daemon)
+
+(defun tramp-sh-handle-start-file-process--magit-tramp-process-environment
+    (fn name buffer program &rest args)
+  (if magit-tramp-process-environment
+      (apply fn name buffer
+             (car magit-tramp-process-environment)
+             (append (cdr magit-tramp-process-environment)
+                     (cons program args)))
+    (apply fn name buffer program args)))
+
+(advice-add 'tramp-sh-handle-start-file-process :around
+            'tramp-sh-handle-start-file-process--magit-tramp-process-environment)
+
+(defun tramp-sh-handle-process-file--magit-tramp-process-environment
+    (fn program &optional infile destination display &rest args)
+  (if magit-tramp-process-environment
+      (apply fn "env" infile destination display
+             (append magit-tramp-process-environment
+                     (cons program args)))
+    (apply fn program infile destination display args)))
+
+(advice-add 'tramp-sh-handle-process-file :around
+            'tramp-sh-handle-process-file--magit-tramp-process-environment)
+
+(defvar magit-mode-line-process-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "<mode-line> <mouse-1>")
+      'magit-process-buffer)
+    map)
+  "Keymap for `mode-line-process'.")
+
+(defun magit-process-set-mode-line (program args)
+  "Display the git command (sans arguments) in the mode line."
+  (when (equal program magit-git-executable)
+    (setq args (nthcdr (length magit-git-global-arguments) args)))
+  (let ((str (concat " " (propertize
+                          (concat program (and args (concat " " (car args))))
+                          'mouse-face 'highlight
+                          'keymap magit-mode-line-process-map
+                          'help-echo "mouse-1: Show process buffer"
+                          'face 'magit-mode-line-process))))
+    (magit-repository-local-set 'mode-line-process str)
+    (dolist (buf (magit-mode-get-buffers))
+      (with-current-buffer buf
+        (setq mode-line-process str)))
+    (force-mode-line-update t)))
+
+(defun magit-process-set-mode-line-error-status (&optional error str)
+  "Apply an error face to the string set by `magit-process-set-mode-line'.
+
+If ERROR is supplied, include it in the `mode-line-process' tooltip.
+
+If STR is supplied, it replaces the `mode-line-process' text."
+  (setq str (or str (magit-repository-local-get 'mode-line-process)))
+  (when str
+    (setq error (format "%smouse-1: Show process buffer"
+                        (if (stringp error)
+                            (concat error "\n\n")
+                          "")))
+    (setq str (concat " " (propertize
+                           (substring-no-properties str 1)
+                           'mouse-face 'highlight
+                           'keymap magit-mode-line-process-map
+                           'help-echo error
+                           'face 'magit-mode-line-process-error)))
+    (magit-repository-local-set 'mode-line-process str)
+    (dolist (buf (magit-mode-get-buffers))
+      (with-current-buffer buf
+        (setq mode-line-process str)))
+    (force-mode-line-update t)
+    ;; We remove any error status from the mode line when a magit
+    ;; buffer is refreshed (see `magit-refresh-buffer'), but we must
+    ;; ensure that we ignore any refreshes during the remainder of the
+    ;; current command -- otherwise a newly-set error status would be
+    ;; removed before it was seen.  We set a flag which prevents the
+    ;; status from being removed prior to the next command, so that
+    ;; the error status is guaranteed to remain visible until then.
+    (let ((repokey (magit-repository-local-repository)))
+      ;; The following closure captures the repokey value, and is
+      ;; added to `pre-command-hook'.
+      (cl-labels ((enable-magit-process-unset-mode-line
+                   () ;; Remove ourself from the hook variable, so
+                      ;; that we only run once.
+                   (remove-hook 'pre-command-hook
+                                #'enable-magit-process-unset-mode-line)
+                   ;; Clear the inhibit flag for the repository in
+                   ;; which we set it.
+                   (magit-repository-local-set
+                    'inhibit-magit-process-unset-mode-line nil repokey)))
+        ;; Set the inhibit flag until the next command is invoked.
+        (magit-repository-local-set
+         'inhibit-magit-process-unset-mode-line t repokey)
+        (add-hook 'pre-command-hook
+                  #'enable-magit-process-unset-mode-line)))))
+
+(defun magit-process-unset-mode-line-error-status ()
+  "Remove any current error status from the mode line."
+  (let ((status (or mode-line-process
+                    (magit-repository-local-get 'mode-line-process))))
+    (when (and status
+               (eq (get-text-property 1 'face status)
+                   'magit-mode-line-process-error))
+      (magit-process-unset-mode-line))))
+
+(defun magit-process-unset-mode-line ()
+  "Remove the git command from the mode line."
+  (unless (magit-repository-local-get 'inhibit-magit-process-unset-mode-line)
+    (magit-repository-local-set 'mode-line-process nil)
+    (dolist (buf (magit-mode-get-buffers))
+      (with-current-buffer buf (setq mode-line-process nil)))
+    (force-mode-line-update t)))
+
+(defvar magit-process-error-message-regexps
+  (list "^\\*ERROR\\*: Canceled by user$"
+        "^\\(?:error\\|fatal\\|git\\): \\(.*\\)$"
+        "^\\(Cannot rebase:.*\\)$"))
+
+(define-error 'magit-git-error "Git error")
+
+(defun magit-process-error-summary (process-buf section)
+  "A one-line error summary from the given SECTION."
+  (or (and (buffer-live-p process-buf)
+           (with-current-buffer process-buf
+             (and (oref section content)
+                  (save-excursion
+                    (goto-char (oref section end))
+                    (run-hook-wrapped
+                     'magit-process-error-message-regexps
+                     (lambda (re)
+                       (save-excursion
+                         (and (re-search-backward
+                               re (oref section start) t)
+                              (or (match-string-no-properties 1)
+                                  (and (not magit-process-raise-error)
+                                       'suppressed))))))))))
+      "Git failed"))
+
+(defun magit-process-error-tooltip (process-buf section)
+  "Returns the text from SECTION of the PROCESS-BUF buffer.
+
+Limited by `magit-process-error-tooltip-max-lines'."
+  (and (integerp magit-process-error-tooltip-max-lines)
+       (> magit-process-error-tooltip-max-lines 0)
+       (buffer-live-p process-buf)
+       (with-current-buffer process-buf
+         (save-excursion
+           (goto-char (or (oref section content)
+                          (oref section start)))
+           (buffer-substring-no-properties
+            (point)
+            (save-excursion
+              (forward-line magit-process-error-tooltip-max-lines)
+              (goto-char
+               (if (> (point) (oref section end))
+                   (oref section end)
+                 (point)))
+              ;; Remove any trailing whitespace.
+              (when (re-search-backward "[^[:space:]\n]"
+                                        (oref section start) t)
+                (forward-char 1))
+              (point)))))))
+
+(defvar-local magit-this-error nil)
+
+(defvar magit-process-finish-apply-ansi-colors nil)
+
+(defun magit-process-finish (arg &optional process-buf command-buf
+                                 default-dir section)
+  (unless (integerp arg)
+    (setq process-buf (process-buffer arg))
+    (setq command-buf (process-get arg 'command-buf))
+    (setq default-dir (process-get arg 'default-dir))
+    (setq section     (process-get arg 'section))
+    (setq arg         (process-exit-status arg)))
+  (when (fboundp 'dired-uncache)
+    (dired-uncache default-dir))
+  (when (buffer-live-p process-buf)
+    (with-current-buffer process-buf
+      (let ((inhibit-read-only t)
+            (marker (oref section start)))
+        (goto-char marker)
+        (save-excursion
+          (delete-char 3)
+          (set-marker-insertion-type marker nil)
+          (insert (propertize (format "%3s" arg)
+                              'magit-section section
+                              'face (if (= arg 0)
+                                        'magit-process-ok
+                                      'magit-process-ng)))
+          (set-marker-insertion-type marker t))
+        (when magit-process-finish-apply-ansi-colors
+          (ansi-color-apply-on-region (oref section content)
+                                      (oref section end)))
+        (if (= (oref section end)
+               (+ (line-end-position) 2))
+            (save-excursion
+              (goto-char (1+ (line-end-position)))
+              (delete-char -1)
+              (oset section content nil))
+          (let ((buf (magit-process-buffer t)))
+            (when (and (= arg 0)
+                       (not (--any-p (eq (window-buffer it) buf)
+                                     (window-list))))
+              (magit-section-hide section)))))))
+  (if (= arg 0)
+      ;; Unset the `mode-line-process' value upon success.
+      (magit-process-unset-mode-line)
+    ;; Otherwise process the error.
+    (let ((msg (magit-process-error-summary process-buf section)))
+      ;; Change `mode-line-process' to an error face upon failure.
+      (if magit-process-display-mode-line-error
+          (magit-process-set-mode-line-error-status
+           (or (magit-process-error-tooltip process-buf section)
+               msg))
+        (magit-process-unset-mode-line))
+      ;; Either signal the error, or else display the error summary in
+      ;; the status buffer and with a message in the echo area.
+      (cond
+       (magit-process-raise-error
+        (signal 'magit-git-error (list (format "%s (in %s)" msg default-dir))))
+       ((not (eq msg 'suppressed))
+        (when (buffer-live-p process-buf)
+          (with-current-buffer process-buf
+            (when-let ((status-buf (magit-mode-get-buffer 'magit-status-mode)))
+              (with-current-buffer status-buf
+                (setq magit-this-error msg)))))
+        (message "%s ... [%s buffer %s for details]" msg
+                 (if-let ((key (and (buffer-live-p command-buf)
+                                    (with-current-buffer command-buf
+                                      (car (where-is-internal
+                                            'magit-process-buffer))))))
+                     (format "Hit %s to see" (key-description key))
+                   "See")
+                 (buffer-name process-buf))))))
+  arg)
+
+(defun magit-process-display-buffer (process)
+  (when (process-live-p process)
+    (let ((buf (process-buffer process)))
+      (cond ((not (buffer-live-p buf)))
+            ((= magit-process-popup-time 0)
+             (if (minibufferp)
+                 (switch-to-buffer-other-window buf)
+               (pop-to-buffer buf)))
+            ((> magit-process-popup-time 0)
+             (run-with-timer magit-process-popup-time nil
+                             (lambda (p)
+                               (when (eq (process-status p) 'run)
+                                 (let ((buf (process-buffer p)))
+                                   (when (buffer-live-p buf)
+                                     (if (minibufferp)
+                                         (switch-to-buffer-other-window buf)
+                                       (pop-to-buffer buf))))))
+                             process))))))
+
+(defun magit--log-action (summary line list)
+  (let (heading lines)
+    (if (cdr list)
+        (progn (setq heading (funcall summary list))
+               (setq lines (mapcar line list)))
+      (setq heading (funcall line (car list))))
+    (with-current-buffer (magit-process-buffer t)
+      (goto-char (1- (point-max)))
+      (let ((inhibit-read-only t))
+        (magit-insert-section (message)
+          (magit-insert-heading (concat "  * " heading))
+          (when lines
+            (dolist (line lines)
+              (insert line "\n"))
+            (insert "\n"))))
+      (let ((inhibit-message t))
+        (when heading
+          (setq lines (cons heading lines)))
+        (message (mapconcat #'identity lines "\n"))))))
+
+(provide 'magit-process)
+;;; magit-process.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-process.elc b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-process.elc
new file mode 100644
index 0000000000..be53ea65c9
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-process.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-refs.el b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-refs.el
new file mode 100644
index 0000000000..8a8635c93a
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-refs.el
@@ -0,0 +1,747 @@
+;;; magit-refs.el --- listing references  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2010-2018  The Magit Project Contributors
+;;
+;; You should have received a copy of the AUTHORS.md file which
+;; lists all contributors.  If not, see http://magit.vc/authors.
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; Magit 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, or (at your option)
+;; any later version.
+;;
+;; Magit 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 Magit.  If not, see http://www.gnu.org/licenses.
+
+;;; Commentary:
+
+;; This library implements support for listing references in a buffer.
+
+;;; Code:
+
+(require 'magit)
+
+(defvar bookmark-make-record-function)
+
+;;; Options
+
+(defgroup magit-refs nil
+  "Inspect and manipulate Git branches and tags."
+  :link '(info-link "(magit)References Buffer")
+  :group 'magit-modes)
+
+(defcustom magit-refs-mode-hook nil
+  "Hook run after entering Magit-Refs mode."
+  :package-version '(magit . "2.1.0")
+  :group 'magit-refs
+  :type 'hook)
+
+(defcustom magit-refs-sections-hook
+  '(magit-insert-error-header
+    magit-insert-branch-description
+    magit-insert-local-branches
+    magit-insert-remote-branches
+    magit-insert-tags)
+  "Hook run to insert sections into a references buffer."
+  :package-version '(magit . "2.1.0")
+  :group 'magit-refs
+  :type 'hook)
+
+(defcustom magit-refs-show-commit-count nil
+  "Whether to show commit counts in Magit-Refs mode buffers.
+
+all    Show counts for branches and tags.
+branch Show counts for branches only.
+nil    Never show counts.
+
+To change the value in an existing buffer use the command
+`magit-refs-show-commit-count'"
+  :package-version '(magit . "2.1.0")
+  :group 'magit-refs
+  :safe (lambda (val) (memq val '(all branch nil)))
+  :type '(choice (const all    :tag "For branches and tags")
+                 (const branch :tag "For branches only")
+                 (const nil    :tag "Never")))
+(put 'magit-refs-show-commit-count 'safe-local-variable 'symbolp)
+(put 'magit-refs-show-commit-count 'permanent-local t)
+
+(defcustom magit-refs-pad-commit-counts nil
+  "Whether to pad all counts on all sides in `magit-refs-mode' buffers.
+
+If this is nil, then some commit counts are displayed right next
+to one of the branches that appear next to the count, without any
+space in between.  This might look bad if the branch name faces
+look too similar to `magit-dimmed'.
+
+If this is non-nil, then spaces are placed on both sides of all
+commit counts."
+  :package-version '(magit . "2.12.0")
+  :group 'magit-refs
+  :type 'boolean)
+
+(defvar magit-refs-show-push-remote nil
+  "Whether to show the push-remotes of local branches.
+Also show the commits that the local branch is ahead and behind
+the push-target.  Unfortunately there is a bug in Git that makes
+this useless (the commits ahead and behind the upstream are
+shown), so this isn't enabled yet.")
+
+(defcustom magit-refs-show-remote-prefix nil
+  "Whether to show the remote prefix in lists of remote branches.
+
+This is redundant because the name of the remote is already shown
+in the heading preceeding the list of its branches."
+  :package-version '(magit . "2.12.0")
+  :group 'magit-refs
+  :type 'boolean)
+
+(defcustom magit-refs-margin
+  (list nil
+        (nth 1 magit-log-margin)
+        'magit-log-margin-width nil
+        (nth 4 magit-log-margin))
+  "Format of the margin in `magit-refs-mode' buffers.
+
+The value has the form (INIT STYLE WIDTH AUTHOR AUTHOR-WIDTH).
+
+If INIT is non-nil, then the margin is shown initially.
+STYLE controls how to format the committer date.  It can be one
+  of `age' (to show the age of the commit), `age-abbreviated' (to
+  abbreviate the time unit to a character), or a string (suitable
+  for `format-time-string') to show the actual date.
+WIDTH controls the width of the margin.  This exists for forward
+  compatibility and currently the value should not be changed.
+AUTHOR controls whether the name of the author is also shown by
+  default.
+AUTHOR-WIDTH has to be an integer.  When the name of the author
+  is shown, then this specifies how much space is used to do so."
+  :package-version '(magit . "2.9.0")
+  :group 'magit-refs
+  :group 'magit-margin
+  :safe (lambda (val) (memq val '(all branch nil)))
+  :type magit-log-margin--custom-type
+  :initialize 'magit-custom-initialize-reset
+  :set-after '(magit-log-margin)
+  :set (apply-partially #'magit-margin-set-variable 'magit-refs-mode))
+
+(defcustom magit-refs-margin-for-tags nil
+  "Whether to show information about tags in the margin.
+
+This is disabled by default because it is slow if there are many
+tags."
+  :package-version '(magit . "2.9.0")
+  :group 'magit-refs
+  :group 'magit-margin
+  :type 'boolean)
+
+(defcustom magit-refs-primary-column-width (cons 16 32)
+  "Width of the focus column in `magit-refs-mode' buffers.
+
+The primary column is the column that contains the name of the
+branch that the current row is about.
+
+If this is an integer, then the column is that many columns wide.
+Otherwise it has to be a cons-cell of two integers.  The first
+specifies the minimal width, the second the maximal width.  In that
+case the actual width is determined using the length of the names
+of the shown local branches.  (Remote branches and tags are not
+taken into account when calculating to optimal width.)"
+  :package-version '(magit . "2.12.0")
+  :group 'magit-refs
+  :type '(choice (integer :tag "Constant wide")
+                 (cons    :tag "Wide constrains"
+                          (integer :tag "Minimum")
+                          (integer :tag "Maximum"))))
+
+(defcustom magit-refs-focus-column-width 5
+  "Width of the focus column in `magit-refs-mode' buffers.
+
+The focus column is the first column, which marks one
+branch (usually the current branch) as the focused branch using
+\"*\" or \"@\".  For each other reference, this column optionally
+shows how many commits it is ahead of the focused branch and \"<\", or
+if it isn't ahead then the commits it is behind and \">\", or if it
+isn't behind either, then a \"=\".
+
+This column may also display only \"*\" or \"@\" for the focused
+branch, in which case this option is ignored.  Use \"L v\" to
+change the verbosity of this column."
+  :package-version '(magit . "2.12.0")
+  :group 'magit-refs
+  :type 'integer)
+
+(defcustom magit-refs-filter-alist nil
+  "Alist controlling which refs are omitted from `magit-refs-mode' buffers.
+
+All keys are tried in order until one matches.  Then its value
+is used and subsequent elements are ignored.  If the value is
+non-nil, then the reference is displayed, otherwise it is not.
+If no element matches, then the reference is displayed.
+
+A key can either be a regular expression that the refname has
+to match, or a function that takes the refname as only argument
+and returns a boolean.  Contrary to how they are displayed in
+the buffer, for comparison each tag begins with \"tags/\" and
+each remote branch with \"<remote>/\"."
+  :package-version '(magit . "2.12.0")
+  :group 'magit-refs
+  :type '(alist :key-type   (choice  :tag "Key" regexp function)
+                :value-type (boolean :tag "Value"
+                                     :on  "show (non-nil)"
+                                     :off "omit (nil)")))
+
+(defcustom magit-visit-ref-behavior nil
+  "Control how `magit-visit-ref' behaves in `magit-refs-mode' buffers.
+
+By default `magit-visit-ref' behaves like `magit-show-commit',
+in all buffers, including `magit-refs-mode' buffers.  When the
+type of the section at point is `commit' then \"RET\" is bound to
+`magit-show-commit', and when the type is either `branch' or
+`tag' then it is bound to `magit-visit-ref'.
+
+\"RET\" is one of Magit's most essential keys and at least by
+default it should behave consistently across all of Magit,
+especially because users quickly learn that it does something
+very harmless; it shows more information about the thing at point
+in another buffer.
+
+However \"RET\" used to behave differently in `magit-refs-mode'
+buffers, doing surprising things, some of which cannot really be
+described as \"visit this thing\".  If you have grown accustomed
+to such inconsistent, but to you useful, behavior, then you can
+restore that by adding one or more of the below symbols to the
+value of this option.  But keep in mind that by doing so you
+don't only introduce inconsistencies, you also lose some
+functionality and might have to resort to `M-x magit-show-commit'
+to get it back.
+
+`magit-visit-ref' looks for these symbols in the order in which
+they are described here.  If the presence of a symbol applies to
+the current situation, then the symbols that follow do not affect
+the outcome.
+
+`focus-on-ref'
+
+  With a prefix argument update the buffer to show commit counts
+  and lists of cherry commits relative to the reference at point
+  instead of relative to the current buffer or `HEAD'.
+
+  Instead of adding this symbol, consider pressing \"C-u y o RET\".
+
+`create-branch'
+
+  If point is on a remote branch, then create a new local branch
+  with the same name, use the remote branch as its upstream, and
+  then check out the local branch.
+
+  Instead of adding this symbol, consider pressing \"b c RET RET\",
+  like you would do in other buffers.
+
+`checkout-any'
+
+  Check out the reference at point.  If that reference is a tag
+  or a remote branch, then this results in a detached `HEAD'.
+
+  Instead of adding this symbol, consider pressing \"b b RET\",
+  like you would do in other buffers.
+
+`checkout-branch'
+
+  Check out the local branch at point.
+
+  Instead of adding this symbol, consider pressing \"b b RET\",
+  like you would do in other buffers."
+  :package-version '(magit . "2.9.0")
+  :group 'magit-refs
+  :group 'magit-commands
+  :options '(focus-on-ref create-branch checkout-any checkout-branch)
+  :type '(list :convert-widget custom-hook-convert-widget))
+
+;;; Mode
+
+(defvar magit-refs-mode-map
+  (let ((map (make-sparse-keymap)))
+    (set-keymap-parent map magit-mode-map)
+    (define-key map "\C-y" 'magit-refs-set-show-commit-count)
+    (define-key map "L"    'magit-margin-popup)
+    map)
+  "Keymap for `magit-refs-mode'.")
+
+(define-derived-mode magit-refs-mode magit-mode "Magit Refs"
+  "Mode which lists and compares references.
+
+This mode is documented in info node `(magit)References Buffer'.
+
+\\<magit-mode-map>\
+Type \\[magit-refresh] to refresh the current buffer.
+Type \\[magit-section-toggle] to expand or hide the section at point.
+Type \\[magit-visit-thing] or \\[magit-diff-show-or-scroll-up] \
+to visit the commit or branch at point.
+
+Type \\[magit-branch-popup] to see available branch commands.
+Type \\[magit-merge-popup] to merge the branch or commit at point.
+Type \\[magit-cherry-pick-popup] to apply the commit at point.
+Type \\[magit-reset] to reset `HEAD' to the commit at point.
+
+\\{magit-refs-mode-map}"
+  :group 'magit-refs
+  (hack-dir-local-variables-non-file-buffer)
+  (setq imenu-create-index-function
+        #'magit-imenu--refs-create-index-function)
+  (setq-local bookmark-make-record-function
+              #'magit-bookmark--refs-make-record))
+
+(defun magit-refs-refresh-buffer (ref &optional args)
+  (setq magit-set-buffer-margin-refresh (not (magit-buffer-margin-p)))
+  (unless ref
+    (setq ref "HEAD"))
+  (unless (magit-rev-verify ref)
+    (setq magit-refs-show-commit-count nil))
+  (magit-set-header-line-format
+   (format "%s %s" ref (mapconcat #'identity args " ")))
+  (magit-insert-section (branchbuf)
+    (run-hooks 'magit-refs-sections-hook))
+  (add-hook 'kill-buffer-hook 'magit-preserve-section-visibility-cache))
+
+;;; Commands
+
+(defcustom magit-show-refs-arguments nil
+  "The arguments used in `magit-refs-mode' buffers."
+  :group 'magit-git-arguments
+  :group 'magit-refs
+  :type '(repeat (string :tag "Argument")))
+
+(defvar magit-show-refs-popup
+  (list
+   :variable 'magit-show-refs-arguments
+   :man-page "git-branch"
+   :switches '((?m "Merged to HEAD"            "--merged")
+               (?M "Merged to master"          "--merged=master")
+               (?n "Not merged to HEAD"        "--no-merged")
+               (?N "Not merged to master"      "--no-merged=master"))
+   :options  '((?c "Contains"   "--contains="  magit-read-branch-or-commit)
+               (?m "Merged"     "--merged="    magit-read-branch-or-commit)
+               (?n "Not merged" "--no-merged=" magit-read-branch-or-commit)
+               (?s "Sort"       "--sort="      magit-read-ref-sort))
+   :actions  '((?y "Show refs, comparing them with HEAD"
+                   magit-show-refs-head)
+               (?c "Show refs, comparing them with current branch"
+                   magit-show-refs-current)
+               (?o "Show refs, comparing them with other branch"
+                   magit-show-refs))
+   :default-action 'magit-show-refs-head
+   :max-action-columns 1
+   :use-prefix (lambda ()
+                 (if (derived-mode-p 'magit-refs-mode)
+                     (if current-prefix-arg 'popup 'default)
+                   'popup))))
+
+(magit-define-popup-keys-deferred 'magit-show-refs-popup)
+
+(defun magit-read-ref-sort (prompt initial-input)
+  (magit-completing-read prompt
+                         '("-committerdate" "-authordate"
+                           "committerdate" "authordate")
+                         nil nil initial-input))
+
+(defun magit-show-refs-get-buffer-args ()
+  (cond ((and magit-use-sticky-arguments
+              (derived-mode-p 'magit-refs-mode))
+         (cadr magit-refresh-args))
+        ((and (eq magit-use-sticky-arguments t)
+              (--when-let (magit-mode-get-buffer 'magit-refs-mode)
+                (with-current-buffer it
+                  (cadr magit-refresh-args)))))
+        (t
+         (default-value 'magit-show-refs-arguments))))
+
+(defun magit-show-refs-arguments ()
+  (if (eq magit-current-popup 'magit-show-refs-popup)
+      magit-current-popup-args
+    (magit-show-refs-get-buffer-args)))
+
+;;;###autoload
+(defun magit-show-refs-popup (&optional arg)
+  "Popup console for `magit-show-refs'."
+  (interactive "P")
+  (let ((magit-show-refs-arguments (magit-show-refs-get-buffer-args)))
+    (magit-invoke-popup 'magit-show-refs-popup nil arg)))
+
+;;;###autoload
+(defun magit-show-refs-head (&optional args)
+  "List and compare references in a dedicated buffer.
+Refs are compared with `HEAD'."
+  (interactive (list (magit-show-refs-arguments)))
+  (magit-show-refs nil args))
+
+;;;###autoload
+(defun magit-show-refs-current (&optional args)
+  "List and compare references in a dedicated buffer.
+Refs are compared with the current branch or `HEAD' if
+it is detached."
+  (interactive (list (magit-show-refs-arguments)))
+  (magit-show-refs (magit-get-current-branch) args))
+
+;;;###autoload
+(defun magit-show-refs (&optional ref args)
+  "List and compare references in a dedicated buffer.
+Refs are compared with a branch read from the user."
+  (interactive (list (magit-read-other-branch "Compare with")
+                     (magit-show-refs-arguments)))
+  (magit-mode-setup #'magit-refs-mode ref args))
+
+(defun magit-refs-set-show-commit-count ()
+  "Change for which refs the commit count is shown."
+  (interactive)
+  (setq-local magit-refs-show-commit-count
+              (magit-read-char-case "Show commit counts for " nil
+                (?a "[a]ll refs" 'all)
+                (?b "[b]ranches only" t)
+                (?n "[n]othing" nil)))
+  (magit-refresh))
+
+(defun magit-visit-ref ()
+  "Visit the reference or revision at point in another buffer.
+If there is no revision at point or with a prefix argument prompt
+for a revision.
+
+This command behaves just like `magit-show-commit', except if
+point is on a reference in a `magit-refs-mode' buffer (a buffer
+listing branches and tags), in which case the behavior may be
+different, but only if you have customized the option
+`magit-visit-ref-behavior' (which see)."
+  (interactive)
+  (if (and (derived-mode-p 'magit-refs-mode)
+           (magit-section-match '(branch tag)))
+      (let ((ref (oref (magit-current-section) value)))
+        (cond (current-prefix-arg
+               (cond ((memq 'focus-on-ref magit-visit-ref-behavior)
+                      (magit-show-refs ref))
+                     (magit-visit-ref-behavior
+                      ;; Don't prompt for commit to visit.
+                      (let ((current-prefix-arg nil))
+                        (call-interactively #'magit-show-commit)))))
+              ((and (memq 'create-branch magit-visit-ref-behavior)
+                    (magit-section-match [branch remote]))
+               (let ((branch (cdr (magit-split-branch-name ref))))
+                 (if (magit-branch-p branch)
+                     (if (magit-rev-eq branch ref)
+                         (magit-call-git "checkout" branch)
+                       (setq branch (propertize branch 'face 'magit-branch-local))
+                       (setq ref (propertize ref 'face 'magit-branch-remote))
+                       (pcase (prog1 (read-char-choice (format (propertize "\
+Branch %s already exists.
+  [c]heckout %s as-is
+  [r]reset %s to %s and checkout %s
+  [a]bort " 'face 'minibuffer-prompt) branch branch branch ref branch)
+                                                       '(?c ?r ?a))
+                                (message "")) ; otherwise prompt sticks
+                         (?c (magit-call-git "checkout" branch))
+                         (?r (magit-call-git "checkout" "-B" branch ref))
+                         (?a (user-error "Abort"))))
+                   (magit-call-git "checkout" "-b" branch ref))
+                 (setcar magit-refresh-args branch)
+                 (magit-refresh)))
+              ((or (memq 'checkout-any magit-visit-ref-behavior)
+                   (and (memq 'checkout-branch magit-visit-ref-behavior)
+                        (magit-section-match [branch local])))
+               (magit-call-git "checkout" ref)
+               (setcar magit-refresh-args ref)
+               (magit-refresh))
+              (t
+               (call-interactively #'magit-show-commit))))
+    (call-interactively #'magit-show-commit)))
+
+;;; Sections
+
+(defvar magit-remote-section-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map [remap magit-delete-thing] 'magit-remote-remove)
+    (define-key map "R"                        'magit-remote-rename)
+    map)
+  "Keymap for `remote' sections.")
+
+(defvar magit-branch-section-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map [remap magit-visit-thing]  'magit-visit-ref)
+    (define-key map [remap magit-delete-thing] 'magit-branch-delete)
+    (define-key map "R"                        'magit-branch-rename)
+    map)
+  "Keymap for `branch' sections.")
+
+(defvar magit-tag-section-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map [remap magit-visit-thing]  'magit-visit-ref)
+    (define-key map [remap magit-delete-thing] 'magit-tag-delete)
+    map)
+  "Keymap for `tag' sections.")
+
+(defun magit-insert-branch-description ()
+  "Insert header containing the description of the current branch.
+Insert a header line with the name and description of the
+current branch.  The description is taken from the Git variable
+`branch.<NAME>.description'; if that is undefined then no header
+line is inserted at all."
+  (when-let ((branch (magit-get-current-branch))
+             (desc (magit-get "branch" branch "description"))
+             (desc (split-string desc "\n")))
+    (when (equal (car (last desc)) "")
+      (setq desc (butlast desc)))
+    (magit-insert-section (branchdesc branch t)
+      (magit-insert-heading branch ": " (car desc))
+      (when (cdr desc)
+        (insert (mapconcat 'identity (cdr desc) "\n"))
+        (insert "\n\n")))))
+
+(defun magit-insert-tags ()
+  "Insert sections showing all tags."
+  (when-let ((tags (magit-git-lines "tag" "--list" "-n"
+                                    (cadr magit-refresh-args))))
+    (let ((_head (magit-rev-parse "HEAD")))
+      (magit-insert-section (tags)
+        (magit-insert-heading "Tags:")
+        (dolist (tag tags)
+          (string-match "^\\([^ \t]+\\)[ \t]+\\([^ \t\n].*\\)?" tag)
+          (let ((tag (match-string 1 tag))
+                (msg (match-string 2 tag)))
+            (when (magit-refs--insert-refname-p tag)
+              (magit-insert-section section (tag tag t)
+                (magit-insert-heading
+                  (magit-refs--format-focus-column tag 'tag)
+                  (propertize tag 'face 'magit-tag)
+                  (make-string (max 1 (- magit-refs-primary-column-width
+                                         (length tag)))
+                               ?\s)
+                  (and msg (magit-log-propertize-keywords nil msg)))
+                (when (and magit-refs-margin-for-tags (magit-buffer-margin-p))
+                  (magit-refs--format-margin tag))
+                (magit-refs--insert-cherry-commits tag section)))))
+        (insert ?\n)
+        (magit-make-margin-overlay nil t)))))
+
+(defun magit-insert-remote-branches ()
+  "Insert sections showing all remote-tracking branches."
+  (dolist (remote (magit-list-remotes))
+    (magit-insert-section (remote remote)
+      (magit-insert-heading
+        (let ((pull (magit-get "remote" remote "url"))
+              (push (magit-get "remote" remote "pushurl")))
+          (format (propertize "Remote %s (%s):" 'face 'magit-section-heading)
+                  (propertize remote 'face 'magit-branch-remote)
+                  (concat pull (and pull push ", ") push))))
+      (let (head)
+        (dolist (line (magit-git-lines "for-each-ref" "--format=\
+%(symref:short)%00%(refname:short)%00%(subject)"
+                                       (concat "refs/remotes/" remote)
+                                       (cadr magit-refresh-args)))
+          (pcase-let ((`(,head-branch ,branch ,msg)
+                       (-replace "" nil (split-string line "\0"))))
+            (if head-branch
+                (progn (cl-assert (equal branch (concat remote "/HEAD")))
+                       (setq head head-branch))
+              (when (magit-refs--insert-refname-p branch)
+                (magit-insert-section section (branch branch t)
+                  (let ((headp (equal branch head))
+                        (abbrev (if magit-refs-show-remote-prefix
+                                    branch
+                                  (substring branch (1+ (length remote))))))
+                    (magit-insert-heading
+                      (magit-refs--format-focus-column branch)
+                      (propertize abbrev 'face
+                                  (if headp
+                                      'magit-branch-remote-head
+                                    'magit-branch-remote))
+                      (make-string (max 1 (- magit-refs-primary-column-width
+                                             (length abbrev)))
+                                   ?\s)
+                      (and msg (magit-log-propertize-keywords nil msg))))
+                  (when (magit-buffer-margin-p)
+                    (magit-refs--format-margin branch))
+                  (magit-refs--insert-cherry-commits branch section)))))))
+      (insert ?\n)
+      (magit-make-margin-overlay nil t))))
+
+(defun magit-insert-local-branches ()
+  "Insert sections showing all local branches."
+  (magit-insert-section (local nil)
+    (magit-insert-heading "Branches:")
+    (dolist (line (magit-refs--format-local-branches))
+      (pcase-let ((`(,branch . ,strings) line))
+        (magit-insert-section section
+          ((eval (if branch 'branch 'commit))
+           (or branch (magit-rev-parse "HEAD"))
+           t)
+          (apply #'magit-insert-heading strings)
+          (when (magit-buffer-margin-p)
+            (magit-refs--format-margin branch))
+          (magit-refs--insert-cherry-commits branch section))))
+    (insert ?\n)
+    (magit-make-margin-overlay nil t)))
+
+(defun magit-refs--format-local-branches ()
+  (let ((lines (-keep 'magit-refs--format-local-branch
+                      (magit-git-lines
+                       "for-each-ref"
+                       (concat "--format=\
+%(HEAD)%00%(refname:short)%00\
+%(upstream:short)%00%(upstream)%00%(upstream:track)%00"
+                               (if magit-refs-show-push-remote "\
+%(push:remotename)%00%(push)%00%(push:track)%00%(subject)"
+                                 "%00%00%00%(subject)"))
+                       "refs/heads"
+                       (cadr magit-refresh-args)))))
+    (unless (magit-get-current-branch)
+      (push (magit-refs--format-local-branch
+             (concat "*\0\0\0\0\0\0\0" (magit-rev-format "%s")))
+            lines))
+    (setq-local magit-refs-primary-column-width
+                (let ((def (default-value 'magit-refs-primary-column-width)))
+                  (if (atom def)
+                      def
+                    (pcase-let ((`(,min . ,max) def))
+                      (min max (apply #'max min (mapcar #'car lines)))))))
+    (mapcar (pcase-lambda (`(,_ ,branch ,focus ,branch-desc ,u:ahead ,p:ahead
+                                ,u:behind ,upstream ,p:behind ,push ,msg))
+              (list branch focus branch-desc u:ahead p:ahead
+                    (make-string (max 1 (- magit-refs-primary-column-width
+                                           (length (concat branch-desc
+                                                           u:ahead
+                                                           p:ahead
+                                                           u:behind))))
+                                 ?\s)
+                    u:behind upstream p:behind push
+                    msg))
+            lines)))
+
+(defun magit-refs--format-local-branch (line)
+  (pcase-let ((`(,head ,branch ,upstream ,u:ref ,u:track
+                       ,push ,p:ref ,p:track ,msg)
+               (-replace "" nil (split-string line "\0"))))
+    (when (or (not branch)
+              (magit-refs--insert-refname-p branch))
+      (let* ((headp (equal head "*"))
+             (pushp (and push
+                         magit-refs-show-push-remote
+                         (magit-rev-verify p:ref)
+                         (not (equal p:ref u:ref))))
+             (branch-desc (propertize (or branch "(detached)")
+                                      'face (if (and headp branch)
+                                                'magit-branch-current
+                                              'magit-branch-local)))
+             (u:ahead  (and u:track
+                            (string-match "ahead \\([0-9]+\\)" u:track)
+                            (propertize
+                             (concat (and magit-refs-pad-commit-counts " ")
+                                     (match-string 1 u:track)
+                                     ">")
+                             'face 'magit-dimmed)))
+             (u:behind (and u:track
+                            (string-match "behind \\([0-9]+\\)" u:track)
+                            (propertize
+                             (concat "<"
+                                     (match-string 1 u:track)
+                                     (and magit-refs-pad-commit-counts " "))
+                             'face 'magit-dimmed)))
+             (p:ahead  (and pushp p:track
+                            (string-match "ahead \\([0-9]+\\)" p:track)
+                            (propertize
+                             (concat (match-string 1 p:track)
+                                     ">"
+                                     (and magit-refs-pad-commit-counts " "))
+                             'face 'magit-branch-remote)))
+             (p:behind (and pushp p:track
+                            (string-match "behind \\([0-9]+\\)" p:track)
+                            (propertize
+                             (concat "<"
+                                     (match-string 1 p:track)
+                                     (and magit-refs-pad-commit-counts " "))
+                             'face 'magit-dimmed))))
+        (list (1+ (length (concat branch-desc u:ahead p:ahead u:behind)))
+              branch
+              (magit-refs--format-focus-column branch headp)
+              branch-desc u:ahead p:ahead u:behind
+              (and upstream
+                   (concat (propertize
+                            upstream 'face
+                            (cond ((equal u:track "[gone]")
+                                   'error)
+                                  ((string-prefix-p "refs/heads/" u:ref)
+                                   'magit-branch-local)
+                                  (t
+                                   'magit-branch-remote)))
+                           " "))
+              (and pushp
+                   (concat p:behind
+                           (propertize push 'face 'magit-branch-remote)
+                           " "))
+              (and msg (magit-log-propertize-keywords nil msg)))))))
+
+(defun magit-refs--format-focus-column (ref &optional type)
+  (let ((focus (car magit-refresh-args))
+        (width (if magit-refs-show-commit-count
+                   magit-refs-focus-column-width
+                 1)))
+    (format
+     (format "%%%ss " width)
+     (cond ((or (equal ref focus)
+                (and (eq type t)
+                     (eq focus nil)))
+            (propertize (concat (if focus "@" "*")
+                                (make-string (1- width) ?\s))
+                        'face 'magit-section-heading))
+           ((if (eq type 'tag)
+                (eq magit-refs-show-commit-count 'all)
+              magit-refs-show-commit-count)
+            (pcase-let ((`(,behind ,ahead)
+                         (magit-rev-diff-count
+                          (or (car magit-refresh-args) "HEAD")
+                          ref)))
+              (propertize
+               (cond ((> ahead  0) (concat "<" (number-to-string ahead)))
+                     ((> behind 0) (concat (number-to-string behind) ">"))
+                     (t "="))
+               'face 'magit-dimmed)))
+           (t "")))))
+
+(defun magit-refs--insert-refname-p (refname)
+  (--if-let (-first (pcase-lambda (`(,key . ,_))
+                      (if (functionp key)
+                          (funcall key refname)
+                        (string-match-p key refname)))
+                    magit-refs-filter-alist)
+      (cdr it)
+    t))
+
+(defun magit-refs--insert-cherry-commits (ref section)
+  (if (oref section hidden)
+      (oset section washer
+            (apply-partially #'magit-refs--insert-cherry-commits-1 ref section))
+    (magit-refs--insert-cherry-commits-1 ref section)))
+
+(defun magit-refs--insert-cherry-commits-1 (ref _section)
+  (let ((start (point))
+        (magit-insert-section--current nil))
+    (magit-git-wash (apply-partially 'magit-log-wash-log 'cherry)
+      "cherry" "-v" (magit-abbrev-arg)
+      (or (car magit-refresh-args) "HEAD")
+      ref magit-refresh-args)
+    (unless (= (point) start)
+      (magit-make-margin-overlay nil t))))
+
+(defun magit-refs--format-margin (commit)
+  (save-excursion
+    (goto-char (line-beginning-position 0))
+    (let ((line (magit-rev-format "%ct%cN" commit)))
+      (magit-log-format-margin (substring line 10)
+                               (substring line 0 10)))))
+
+(provide 'magit-refs)
+;;; magit-refs.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-refs.elc b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-refs.elc
new file mode 100644
index 0000000000..4c2f0db8eb
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-refs.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-remote.el b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-remote.el
new file mode 100644
index 0000000000..7541f6e270
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-remote.el
@@ -0,0 +1,1052 @@
+;;; magit-remote.el --- transfer Git commits  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2008-2018  The Magit Project Contributors
+;;
+;; You should have received a copy of the AUTHORS.md file which
+;; lists all contributors.  If not, see http://magit.vc/authors.
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; Magit 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, or (at your option)
+;; any later version.
+;;
+;; Magit 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 Magit.  If not, see http://www.gnu.org/licenses.
+
+;;; Commentary:
+
+;; This library implements support for interacting with remote
+;; repositories.  Commands for cloning, fetching, pulling, and
+;; pushing are defined here.
+
+;;; Code:
+
+(require 'magit)
+
+;;; Options
+
+(defcustom magit-fetch-modules-jobs 4
+  "Number of submodules to fetch in parallel.
+Ignored for Git versions before v2.8.0."
+  :package-version '(magit . "2.12.0")
+  :group 'magit-commands
+  :type '(choice (const :tag "one at a time" nil) number))
+
+;;; Clone
+
+(defcustom magit-clone-set-remote-head nil
+  "Whether cloning creates the symbolic-ref `<remote>/HEAD'."
+  :package-version '(magit . "2.4.2")
+  :group 'magit-commands
+  :type 'boolean)
+
+(defcustom magit-clone-set-remote.pushDefault 'ask
+  "Whether to set the value of `remote.pushDefault' after cloning.
+
+If t, then set without asking.  If nil, then don't set.  If
+`ask', then ask."
+  :package-version '(magit . "2.4.0")
+  :group 'magit-commands
+  :type '(choice (const :tag "set" t)
+                 (const :tag "ask" ask)
+                 (const :tag "don't set" nil)))
+
+;;;###autoload
+(defun magit-clone (repository directory)
+  "Clone the REPOSITORY to DIRECTORY.
+Then show the status buffer for the new repository."
+  (interactive
+   (let  ((url (magit-read-string-ns "Clone repository")))
+     (list url (read-directory-name
+                "Clone to: " nil nil nil
+                (and (string-match "\\([^/:]+?\\)\\(/?\\.git\\)?$" url)
+                     (match-string 1 url))))))
+  (setq directory (file-name-as-directory (expand-file-name directory)))
+  (magit-run-git-async "clone" repository
+                       (magit-convert-filename-for-git directory))
+  ;; Don't refresh the buffer we're calling from.
+  (process-put magit-this-process 'inhibit-refresh t)
+  (set-process-sentinel
+   magit-this-process
+   (lambda (process event)
+     (when (memq (process-status process) '(exit signal))
+       (let ((magit-process-raise-error t))
+         (magit-process-sentinel process event)))
+     (when (and (eq (process-status process) 'exit)
+                (= (process-exit-status process) 0))
+       (let ((default-directory directory))
+         (when (or (eq  magit-clone-set-remote.pushDefault t)
+                   (and magit-clone-set-remote.pushDefault
+                        (y-or-n-p "Set `remote.pushDefault' to \"origin\"? ")))
+           (setf (magit-get "remote.pushDefault") "origin"))
+         (unless magit-clone-set-remote-head
+           (magit-remote-unset-head "origin")))
+       (with-current-buffer (process-get process 'command-buf)
+         (magit-status-internal directory))))))
+
+;;; Remote
+;;;; Options
+
+(defcustom magit-remote-add-set-remote.pushDefault 'ask-if-unset
+  "Whether to set the value of `remote.pushDefault' after adding a remote.
+
+If `ask', then always ask.  If `ask-if-unset', then ask, but only
+if the variable isn't set already.  If nil, then don't ever set.
+If the value is a string, then set without asking, provided that
+the name of the added remote is equal to that string and the
+variable isn't already set."
+  :package-version '(magit . "2.4.0")
+  :group 'magit-commands
+  :type '(choice (const  :tag "ask if unset" ask-if-unset)
+                 (const  :tag "always ask" ask)
+                 (string :tag "set if named")
+                 (const  :tag "don't set")))
+
+(defcustom magit-remote-popup-show-variables t
+  "Whether the `magit-remote-popup' shows Git variables.
+When set to nil, no variables are displayed directly in this
+popup, instead the sub-popup `magit-remote-config-popup' has
+to be used to view and change remote related variables."
+  :package-version '(magit . "2.12.0")
+  :group 'magit-commands
+  :type 'boolean)
+
+;;;; Popup
+
+(defvar magit-remote-config-variables)
+
+;;;###autoload (autoload 'magit-remote-popup "magit-remote" nil t)
+(magit-define-popup magit-remote-popup
+  "Popup console for remote commands."
+  :man-page "git-remote"
+  :default-arguments '("-f")
+  :variables (lambda ()
+               (and magit-remote-popup-show-variables
+                    magit-remote-config-variables))
+  :switches '("Switches for add"
+              (?f "Fetch after add" "-f"))
+  :actions  '((?a "Add"                  magit-remote-add)
+              (?C "Configure..."         magit-remote-config-popup)
+              (?r "Rename"               magit-remote-rename)
+              (?p "Prune stale branches" magit-remote-prune)
+              (?k "Remove"               magit-remote-remove)
+              (?P "Prune stale refspecs" magit-remote-prune-refspecs))
+  :max-action-columns 2)
+
+;;;; Commands
+
+(defun magit-read-url (prompt &optional initial-input)
+  (let ((url (magit-read-string-ns prompt initial-input)))
+    (if (string-prefix-p "~" url)
+        (expand-file-name url)
+      url)))
+
+;;;###autoload
+(defun magit-remote-add (remote url &optional args)
+  "Add a remote named REMOTE and fetch it."
+  (interactive (list (magit-read-string-ns "Remote name")
+                     (magit-read-url "Remote url")
+                     (magit-remote-arguments)))
+  (if (pcase (list magit-remote-add-set-remote.pushDefault
+                   (magit-get "remote.pushDefault"))
+        (`(,(pred stringp) ,_) t)
+        ((or `(ask ,_) `(ask-if-unset nil))
+         (y-or-n-p (format "Set `remote.pushDefault' to \"%s\"? " remote))))
+      (progn (magit-call-git "remote" "add" args remote url)
+             (setf (magit-get "remote.pushDefault") remote)
+             (magit-refresh))
+    (magit-run-git-async "remote" "add" args remote url)))
+
+;;;###autoload
+(defun magit-remote-rename (old new)
+  "Rename the remote named OLD to NEW."
+  (interactive
+   (let  ((remote (magit-read-remote "Rename remote")))
+     (list remote (magit-read-string-ns (format "Rename %s to" remote)))))
+  (unless (string= old new)
+    (magit-call-git "remote" "rename" old new)
+    (magit-remote--cleanup-push-variables old new)
+    (magit-refresh)))
+
+;;;###autoload
+(defun magit-remote-remove (remote)
+  "Delete the remote named REMOTE."
+  (interactive (list (magit-read-remote "Delete remote")))
+  (magit-call-git "remote" "rm" remote)
+  (magit-remote--cleanup-push-variables remote)
+  (magit-refresh))
+
+(defun magit-remote--cleanup-push-variables (remote &optional new-name)
+  (magit-with-toplevel
+    (when (equal (magit-get "remote.pushDefault") remote)
+      (magit-set new-name "remote.pushDefault"))
+    (dolist (var (magit-git-lines "config" "--name-only"
+                                  "--get-regexp" "^branch\.[^.]*\.pushRemote"
+                                  (format "^%s$" remote)))
+      (magit-call-git "config" (and (not new-name) "--unset") var new-name))))
+
+(defconst magit--refspec-re "\\`\\(\\+\\)?\\([^:]+\\):\\(.*\\)\\'")
+
+;;;###autoload
+(defun magit-remote-prune (remote)
+  "Remove stale remote-tracking branches for REMOTE."
+  (interactive (list (magit-read-remote "Prune stale branches of remote")))
+  (magit-run-git-async "remote" "prune" remote))
+
+;;;###autoload
+(defun magit-remote-prune-refspecs (remote)
+  "Remove stale refspecs for REMOTE.
+
+A refspec is stale if there no longer exists at least one branch
+on the remote that would be fetched due to that refspec.  A stale
+refspec is problematic because its existence causes Git to refuse
+to fetch according to the remaining non-stale refspecs.
+
+If only stale refspecs remain, then offer to either delete the
+remote or to replace the stale refspecs with the default refspec.
+
+Also remove the remote-tracking branches that were created due to
+the now stale refspecs.  Other stale branches are not removed."
+  (interactive (list (magit-read-remote "Prune refspecs of remote")))
+  (let* ((tracking-refs (magit-list-remote-branches remote))
+         (remote-refs (magit-remote-list-refs remote))
+         (variable (format "remote.%s.fetch" remote))
+         (refspecs (magit-get-all variable))
+         stale)
+    (dolist (refspec refspecs)
+      (when (string-match magit--refspec-re refspec)
+        (let ((theirs (match-string 2 refspec))
+              (ours   (match-string 3 refspec)))
+          (unless (if (string-match "\\*" theirs)
+                      (let ((re (replace-match ".*" t t theirs)))
+                        (--some (string-match-p re it) remote-refs))
+                    (member theirs remote-refs))
+            (push (cons refspec
+                        (if (string-match "\\*" ours)
+                            (let ((re (replace-match ".*" t t ours)))
+                              (--filter (string-match-p re it) tracking-refs))
+                          (list (car (member ours tracking-refs)))))
+                  stale)))))
+    (if (not stale)
+        (message "No stale refspecs for remote %S" remote)
+      (if (= (length stale)
+             (length refspecs))
+          (magit-read-char-case
+              (format "All of %s's refspecs are stale.  " remote) nil
+            (?s "replace with [d]efault refspec"
+                (magit-set-all
+                 (list (format "+refs/heads/*:refs/remotes/%s/*" remote))
+                 variable))
+            (?r "[r]emove remote"
+                (magit-call-git "remote" "rm" remote))
+            (?a "or [a]abort"
+                (user-error "Abort")))
+        (if (if (= (length stale) 1)
+                (pcase-let ((`(,refspec . ,refs) (car stale)))
+                  (magit-confirm 'prune-stale-refspecs
+                    (format "Prune stale refspec %s and branch %%s" refspec)
+                    (format "Prune stale refspec %s and %%i branches" refspec)
+                    nil refs))
+              (magit-confirm 'prune-stale-refspecs nil
+                (format "Prune %%i stale refspecs and %i branches"
+                        (length (cl-mapcan (lambda (s) (copy-sequence (cdr s)))
+                                           stale)))
+                nil
+                (mapcar (pcase-lambda (`(,refspec . ,refs))
+                          (concat refspec "\n"
+                                  (mapconcat (lambda (b) (concat "  " b))
+                                             refs "\n")))
+                        stale)))
+            (pcase-dolist (`(,refspec . ,refs) stale)
+              (magit-call-git "config" "--unset" variable
+                              (regexp-quote refspec))
+              (magit--log-action
+               (lambda (refs)
+                 (format "Deleting %i branches" (length refs)))
+               (lambda (ref)
+                 (format "Deleting branch %s (was %s)" ref
+                         (magit-rev-parse "--short" ref)))
+               refs)
+              (dolist (ref refs)
+                (magit-call-git "update-ref" "-d" ref)))
+          (user-error "Abort")))
+      (magit-refresh))))
+
+;;;###autoload
+(defun magit-remote-set-head (remote &optional branch)
+  "Set the local representation of REMOTE's default branch.
+Query REMOTE and set the symbolic-ref refs/remotes/<remote>/HEAD
+accordingly.  With a prefix argument query for the branch to be
+used, which allows you to select an incorrect value if you fancy
+doing that."
+  (interactive
+   (let  ((remote (magit-read-remote "Set HEAD for remote")))
+     (list remote
+           (and current-prefix-arg
+                (magit-read-remote-branch (format "Set %s/HEAD to" remote)
+                                          remote nil nil t)))))
+  (magit-run-git "remote" "set-head" remote (or branch "--auto")))
+
+;;;###autoload
+(defun magit-remote-unset-head (remote)
+  "Unset the local representation of REMOTE's default branch.
+Delete the symbolic-ref \"refs/remotes/<remote>/HEAD\"."
+  (interactive (list (magit-read-remote "Unset HEAD for remote")))
+  (magit-run-git "remote" "set-head" remote "--delete"))
+
+;;;; Config Popup
+
+(defvar magit-remote-config--remote nil)
+
+;;;###autoload
+(defun magit-remote-config-popup (remote)
+  "Popup console for setting remote variables."
+  (interactive
+   (list (if (or current-prefix-arg
+                 (and (eq magit-current-popup 'magit-remote-popup)
+                      magit-remote-popup-show-variables))
+             (magit-read-remote "Configure remote")
+           (magit-remote-config--remote-1))))
+  (let ((magit-remote-config--remote remote))
+    (magit-invoke-popup 'magit-remote-config-popup nil nil)))
+
+(defvar magit-remote-config-variables
+  '((lambda ()
+      (concat
+       (propertize "Configure " 'face 'magit-popup-heading)
+       (propertize (magit-remote-config--remote) 'face 'magit-branch-remote)))
+    (?u "remote.%s.url"
+        magit-set-remote*url
+        magit-format-remote*url)
+    (?U "remote.%s.fetch"
+        magit-set-remote*fetch
+        magit-format-remote*fetch)
+    (?s "remote.%s.pushurl"
+        magit-set-remote*pushurl
+        magit-format-remote*pushurl)
+    (?S "remote.%s.push"
+        magit-set-remote*push
+        magit-format-remote*push)
+    (?O "remote.%s.tagOpt"
+        magit-cycle-remote*tagOpt
+        magit-format-remote*tagOpt)))
+
+(defvar magit-remote-config-popup
+  `(:man-page "git-remote"
+    :variables ,magit-remote-config-variables
+    :setup-function magit-remote-config-popup-setup))
+
+(defun magit-remote-config-popup-setup (val def)
+  (magit-popup-default-setup val def)
+  (setq-local magit-remote-config--remote magit-remote-config--remote))
+
+(defun magit-remote-config--remote (&optional prompt)
+  (if prompt
+      (or (and (not current-prefix-arg)
+               (or magit-remote-config--remote
+                   (magit-remote-config--remote-1)))
+          (magit-read-remote prompt))
+    (or magit-remote-config--remote
+        (magit-remote-config--remote-1)
+        "<name>")))
+
+(defun magit-remote-config--remote-1 ()
+  (let ((remote (magit-get-upstream-remote)))
+    (if (or (not remote)
+            (equal remote "."))
+        (and (magit-remote-p "origin") "origin")
+      remote)))
+
+;;;; Config Commands and Inserters
+
+(defun magit-set-remote*url (remote urls)
+  "Set the variable `url' for the remote named REMOTE to URLS."
+  (interactive (magit-remote-config--read-args "url" "Urls: "))
+  (magit-remote-config--set-url remote "url" urls))
+
+(defun magit-set-remote*fetch (remote values)
+  "Set the variable `fetch' for the remote named REMOTE to VALUES."
+  (interactive (magit-remote-config--read-args "fetch" "Fetch specs: "))
+  (magit-set-all values "remote" remote "fetch")
+  (magit-refresh))
+
+(defun magit-set-remote*pushurl (remote urls)
+  "Set the variable `pushurl' for the remote named REMOTE to URLS."
+  (interactive (magit-remote-config--read-args "pushurl" "Urls: "))
+  (magit-remote-config--set-url remote "pushurl" urls "--push"))
+
+(defun magit-set-remote*push (remote values)
+  "Set the variable `push' for the remote named REMOTE to VALUES."
+  (interactive (magit-remote-config--read-args "push" "Push specs: "))
+  (magit-set-all values "remote" remote "push")
+  (magit-refresh))
+
+(defun magit-cycle-remote*tagOpt (remote)
+  (interactive (list (magit-remote-config--remote)))
+  (magit--set-popup-variable (format "remote.%s.tagOpt" remote)
+                             '("--no-tags" "--tags") nil))
+
+(defun magit-format-remote*url ()
+  (magit-remote-config--format-variable "url"))
+
+(defun magit-format-remote*fetch ()
+  (magit-remote-config--format-variable "fetch"))
+
+(defun magit-format-remote*pushurl ()
+  (magit-remote-config--format-variable "pushurl"))
+
+(defun magit-format-remote*push ()
+  (magit-remote-config--format-variable "push"))
+
+(defun magit-format-remote*tagOpt ()
+  (let ((remote (magit-remote-config--remote)))
+    (magit--format-popup-variable:choices
+     (format "remote.%s.tagOpts" remote)
+     '("--no-tags" "--tags") nil nil
+     (+ (length remote) 16))))
+
+(defun magit-remote-config--read-args (var prompt)
+  (let* ((remote (magit-remote-config--remote (format "Set `%s' of remote" var)))
+         (value (magit-get-all "remote" remote var)))
+    (list remote
+          (mapcar (lambda (url)
+                    (if (string-prefix-p "~" url)
+                        (expand-file-name url)
+                      url))
+                  (completing-read-multiple
+                   prompt nil nil nil
+                   (and value (mapconcat #'identity value ",")))))))
+
+(defun magit-remote-config--set-url (remote var values &optional arg)
+  (let ((old (magit-get-all "remote" remote var)))
+    (dolist (v (-difference values old))
+      (magit-call-git "remote" "set-url" arg "--add" remote v))
+    (dolist (v (-difference old values))
+      (magit-call-git "remote" "set-url" arg "--delete" remote
+                      (concat "^" (regexp-quote v) "$"))))
+  (magit-refresh))
+
+(defun magit-remote-config--format-variable (variable)
+  (magit--format-popup-variable:values
+   (format "remote.%s.%s" (magit-remote-config--remote) variable)
+   25))
+
+;;; Fetch
+
+;;;###autoload (autoload 'magit-fetch-popup "magit-remote" nil t)
+(magit-define-popup magit-fetch-popup
+  "Popup console for fetch commands."
+  :man-page "git-fetch"
+  :switches '((?p "Prune deleted branches" "--prune"))
+  :actions  '("Configure"
+              (?C "variables..."           magit-branch-config-popup)
+              "Fetch from"
+              (?p magit-get-push-remote    magit-fetch-from-pushremote)
+              (?u magit-get-remote         magit-fetch-from-upstream)
+              (?e "elsewhere"              magit-fetch)
+              (?a "all remotes"            magit-fetch-all)
+              "Fetch"
+              (?o "another branch"         magit-fetch-branch)
+              (?r "explicit refspec"       magit-fetch-refspec)
+              (?m "submodules"             magit-fetch-modules))
+  :default-action 'magit-fetch
+  :max-action-columns 1)
+
+(defun magit-git-fetch (remote args)
+  (run-hooks 'magit-credential-hook)
+  (magit-run-git-async "fetch" remote args))
+
+;;;###autoload
+(defun magit-fetch-from-pushremote (args)
+  "Fetch from the push-remote of the current branch."
+  (interactive (list (magit-fetch-arguments)))
+  (--if-let (magit-get-push-remote)
+      (magit-git-fetch it args)
+    (--if-let (magit-get-current-branch)
+        (user-error "No push-remote is configured for %s" it)
+      (user-error "No branch is checked out"))))
+
+;;;###autoload
+(defun magit-fetch-from-upstream (args)
+  "Fetch from the upstream repository of the current branch."
+  (interactive (list (magit-fetch-arguments)))
+  (--if-let (magit-get-remote)
+      (magit-git-fetch it args)
+    (--if-let (magit-get-current-branch)
+        (user-error "No upstream is configured for %s" it)
+      (user-error "No branch is checked out"))))
+
+;;;###autoload
+(defun magit-fetch (remote args)
+  "Fetch from another repository."
+  (interactive (list (magit-read-remote "Fetch remote")
+                     (magit-fetch-arguments)))
+  (magit-git-fetch remote args))
+
+;;;###autoload
+(defun magit-fetch-branch (remote branch args)
+  "Fetch a BRANCH from a REMOTE."
+  (interactive
+   (let ((remote (magit-read-remote-or-url "Fetch from remote or url")))
+     (list remote
+           (magit-read-remote-branch "Fetch branch" remote)
+           (magit-fetch-arguments))))
+  (magit-git-fetch remote (cons branch args)))
+
+;;;###autoload
+(defun magit-fetch-refspec (remote refspec args)
+  "Fetch a REFSPEC from a REMOTE."
+  (interactive
+   (let ((remote (magit-read-remote-or-url "Fetch from remote or url")))
+     (list remote
+           (magit-read-refspec "Fetch using refspec" remote)
+           (magit-fetch-arguments))))
+  (magit-git-fetch remote (cons refspec args)))
+
+;;;###autoload
+(defun magit-fetch-all (args)
+  "Fetch from all remotes."
+  (interactive (list (cl-intersection (magit-fetch-arguments)
+                                      (list "--verbose" "--prune")
+                                      :test #'equal)))
+  (run-hooks 'magit-credential-hook)
+  (magit-run-git-async "remote" "update" args))
+
+;;;###autoload
+(defun magit-fetch-all-prune ()
+  "Fetch from all remotes, and prune.
+Prune remote tracking branches for branches that have been
+removed on the respective remote."
+  (interactive)
+  (run-hooks 'magit-credential-hook)
+  (magit-run-git-async "remote" "update" "--prune"))
+
+;;;###autoload
+(defun magit-fetch-all-no-prune ()
+  "Fetch from all remotes."
+  (interactive)
+  (run-hooks 'magit-credential-hook)
+  (magit-run-git-async "remote" "update"))
+
+;;;###autoload
+(defun magit-fetch-modules (&optional all)
+  "Fetch all submodules.
+
+Option `magit-fetch-modules-jobs' controls how many submodules
+are being fetched in parallel.  Also fetch the super-repository,
+because `git-fetch' does not support not doing that.  With a
+prefix argument fetch all remotes."
+  (interactive "P")
+  (magit-with-toplevel
+    (magit-run-git-async
+     "fetch" "--verbose" "--recurse-submodules"
+     (and magit-fetch-modules-jobs
+          (version<= "2.8.0" (magit-git-version))
+          (list "-j" (number-to-string magit-fetch-modules-jobs)))
+     (and all "--all"))))
+
+;;; Pull
+
+;;;###autoload (autoload 'magit-pull-popup "magit-remote" nil t)
+(magit-define-popup magit-pull-popup
+  "Popup console for pull commands."
+  :man-page "git-pull"
+  :variables '("Configure"
+               (?r "branch.%s.rebase"
+                   magit-cycle-branch*rebase
+                   magit-pull-format-branch*rebase)
+               (?C "variables..." magit-branch-config-popup))
+  :actions '((lambda ()
+               (--if-let (magit-get-current-branch)
+                   (concat
+                    (propertize "Pull into " 'face 'magit-popup-heading)
+                    (propertize it           'face 'magit-branch-local)
+                    (propertize " from"      'face 'magit-popup-heading))
+                 (propertize "Pull from" 'face 'magit-popup-heading)))
+             (?p magit-get-push-branch     magit-pull-from-pushremote)
+             (?u magit-get-upstream-branch magit-pull-from-upstream)
+             (?e "elsewhere"               magit-pull))
+  :default-action 'magit-pull
+  :max-action-columns 1)
+
+;;;###autoload (autoload 'magit-pull-and-fetch-popup "magit-remote" nil t)
+(magit-define-popup magit-pull-and-fetch-popup
+  "Popup console for pull and fetch commands.
+
+This popup is intended as a replacement for the separate popups
+`magit-pull-popup' and `magit-fetch-popup'.  To use it, add this
+to your init file:
+
+  (with-eval-after-load \\='magit-remote
+    (define-key magit-mode-map \"f\" \\='magit-pull-and-fetch-popup)
+    (define-key magit-mode-map \"F\" nil))
+
+The combined popup does not offer all commands and arguments
+available from the individual popups.  Instead of the argument
+`--prune' and the command `magit-fetch-all' it uses two commands
+`magit-fetch-prune' and `magit-fetch-no-prune'.  And the commands
+`magit-fetch-from-pushremote' and `magit-fetch-from-upstream' are
+missing.  To add them use something like:
+
+  (with-eval-after-load \\='magit-remote
+    (magit-define-popup-action \\='magit-pull-and-fetch-popup ?U
+      \\='magit-get-upstream-branch
+      \\='magit-fetch-from-upstream-remote ?F)
+    (magit-define-popup-action \\='magit-pull-and-fetch-popup ?P
+      \\='magit-get-push-branch
+      \\='magit-fetch-from-push-remote ?F))"
+  :man-page "git-pull"
+  :variables '("Configure"
+               (?r "branch.%s.rebase"
+                   magit-cycle-branch*rebase
+                   magit-pull-format-branch*rebase)
+               (?C "variables..." magit-branch-config-popup))
+  :actions '((lambda ()
+               (--if-let (magit-get-current-branch)
+                   (concat
+                    (propertize "Pull into " 'face 'magit-popup-heading)
+                    (propertize it           'face 'magit-branch-local)
+                    (propertize " from"      'face 'magit-popup-heading))
+                 (propertize "Pull from" 'face 'magit-popup-heading)))
+             (?p magit-get-push-branch     magit-pull-from-pushremote)
+             (?u magit-get-upstream-branch magit-pull-from-upstream)
+             (?e "elsewhere"               magit-pull)
+             "Fetch from"
+             (?f "remotes"           magit-fetch-all-no-prune)
+             (?F "remotes and prune" magit-fetch-all-prune)
+             "Fetch"
+             (?o "another branch"    magit-fetch-branch)
+             (?s "explicit refspec"  magit-fetch-refspec)
+             (?m "submodules"        magit-fetch-modules))
+  :default-action 'magit-fetch
+  :max-action-columns 1)
+
+(defun magit-pull-format-branch*rebase ()
+  (magit--format-popup-variable:choices
+   (format "branch.%s.rebase" (or (magit-get-current-branch) "<name>"))
+   '("true" "false")
+   "false" "pull.rebase"))
+
+(defun magit-git-pull (source args)
+  (run-hooks 'magit-credential-hook)
+  (pcase-let ((`(,remote . ,branch)
+               (magit-split-branch-name source)))
+    (magit-run-git-with-editor "pull" args remote branch)))
+
+;;;###autoload
+(defun magit-pull-from-pushremote (args)
+  "Pull from the push-remote of the current branch."
+  (interactive (list (magit-pull-arguments)))
+  (--if-let (magit-get-push-branch)
+      (magit-git-pull it args)
+    (--if-let (magit-get-current-branch)
+        (user-error "No push-remote is configured for %s" it)
+      (user-error "No branch is checked out"))))
+
+;;;###autoload
+(defun magit-pull-from-upstream (args)
+  "Pull from the upstream of the current branch."
+  (interactive (list (magit-pull-arguments)))
+  (--if-let (magit-get-upstream-branch)
+      (progn (run-hooks 'magit-credential-hook)
+             (magit-run-git-with-editor
+              "pull" args (car (magit-split-branch-name it))))
+    (--if-let (magit-get-current-branch)
+        (user-error "No upstream is configured for %s" it)
+      (user-error "No branch is checked out"))))
+
+;;;###autoload
+(defun magit-pull (source args)
+  "Pull from a branch read in the minibuffer."
+  (interactive (list (magit-read-remote-branch "Pull" nil nil nil t)
+                     (magit-pull-arguments)))
+  (magit-git-pull source args))
+
+;;; Push
+
+(defcustom magit-push-current-set-remote-if-missing t
+  "Whether to configure missing remotes before pushing.
+
+When nil, then the command `magit-push-current-to-pushremote' and
+`magit-push-current-to-upstream' do not appear in the push popup
+if the push-remote resp. upstream is not configured.  If the user
+invokes one of these commands anyway, then it raises an error.
+
+When non-nil, then these commands always appear in the push
+popup.  But if the required configuration is missing, then they
+do appear in a way that indicates that this is the case.  If the
+user invokes one of them, then it asks for the necessary
+configuration, stores the configuration, and then uses it to push
+a first time.
+
+This option also affects whether the argument `--set-upstream' is
+available in the popup.  If the value is t, then that argument is
+redundant.  But note that changing the value of this option does
+not take affect immediately, the argument will only be added or
+removed after restarting Emacs."
+  :package-version '(magit . "2.6.0")
+  :group 'magit-commands
+  :type '(choice (const :tag "don't set" nil)
+                 (const :tag "set branch.<name>.pushRemote" t)
+                 (const :tag "set remote.pushDefault" default)))
+
+;;;###autoload (autoload 'magit-push-popup "magit-remote" nil t)
+(magit-define-popup magit-push-popup
+  "Popup console for push commands."
+  :man-page "git-push"
+  :switches `((?f "Force with lease" "--force-with-lease")
+              (?F "Force"            "--force")
+              (?h "Disable hooks"    "--no-verify")
+              (?d "Dry run"          "--dry-run")
+              ,@(and (not magit-push-current-set-remote-if-missing)
+                     '((?u "Set upstream"  "--set-upstream"))))
+  :actions '("Configure"
+             (?C "variables..."      magit-branch-config-popup)
+             (lambda ()
+               (--when-let (magit-get-current-branch)
+                 (concat (propertize "Push " 'face 'magit-popup-heading)
+                         (propertize it      'face 'magit-branch-local)
+                         (propertize " to"   'face 'magit-popup-heading))))
+             (?p magit--push-current-to-pushremote-desc
+                 magit-push-current-to-pushremote)
+             (?u magit--push-current-to-upstream-desc
+                 magit-push-current-to-upstream)
+             (?e "elsewhere\n"       magit-push-current)
+             "Push"
+             (?o "another branch"    magit-push)
+             (?T "a tag"             magit-push-tag)
+             (?r "explicit refspecs" magit-push-refspecs)
+             (?t "all tags"          magit-push-tags)
+             (?m "matching branches" magit-push-matching))
+  :max-action-columns 2)
+
+(defun magit-git-push (branch target args)
+  (run-hooks 'magit-credential-hook)
+  (pcase-let ((`(,remote . ,target)
+               (magit-split-branch-name target)))
+    (magit-run-git-async "push" "-v" args remote
+                         (format "%s:refs/heads/%s" branch target))))
+
+;;;###autoload
+(defun magit-push-current-to-pushremote (args &optional push-remote)
+  "Push the current branch to `branch.<name>.pushRemote'.
+If that variable is unset, then push to `remote.pushDefault'.
+
+When `magit-push-current-set-remote-if-missing' is non-nil and
+the push-remote is not configured, then read the push-remote from
+the user, set it, and then push to it.  With a prefix argument
+the push-remote can be changed before pushed to it."
+  (interactive
+   (list (magit-push-arguments)
+         (and (magit--push-current-set-pushremote-p current-prefix-arg)
+              (magit-read-remote
+               (if (eq magit-push-current-set-remote-if-missing 'default)
+                   "Set `remote.pushDefault' and push there"
+                 (format "Set `branch.%s.pushRemote' and push there"
+                         (magit-get-current-branch)))))))
+  (--if-let (magit-get-current-branch)
+      (progn (when push-remote
+               (setf (magit-get
+                      (if (eq magit-push-current-set-remote-if-missing 'default)
+                          "remote.pushDefault"
+                        (format "branch.%s.pushRemote" it)))
+                     push-remote))
+             (if-let ((remote (magit-get-push-remote it)))
+                 (if (member remote (magit-list-remotes))
+                     (magit-git-push it (concat remote "/" it) args)
+                   (user-error "Remote `%s' doesn't exist" remote))
+               (user-error "No push-remote is configured for %s" it)))
+    (user-error "No branch is checked out")))
+
+(defun magit--push-current-set-pushremote-p (&optional change)
+  (and (or change
+           (and magit-push-current-set-remote-if-missing
+                (not (magit-get-push-remote))))
+       (magit-get-current-branch)))
+
+(defun magit--push-current-to-pushremote-desc ()
+  (--if-let (magit-get-push-branch)
+      (concat (magit-branch-set-face it) "\n")
+    (and (magit--push-current-set-pushremote-p)
+         (concat
+          (propertize (if (eq magit-push-current-set-remote-if-missing 'default)
+                          "pushDefault"
+                        "pushRemote")
+                      'face 'bold)
+          ", after setting that\n"))))
+
+;;;###autoload
+(defun magit-push-current-to-upstream (args &optional upstream)
+  "Push the current branch to its upstream branch.
+
+When `magit-push-current-set-remote-if-missing' is non-nil and
+the upstream is not configured, then read the upstream from the
+user, set it, and then push to it.  With a prefix argument the
+upstream can be changed before pushed to it."
+  (interactive
+   (list (magit-push-arguments)
+         (and (magit--push-current-set-upstream-p current-prefix-arg)
+              (magit-read-upstream-branch))))
+  (--if-let (magit-get-current-branch)
+      (progn
+        (when upstream
+          (magit-set-branch*merge/remote it upstream))
+        (if-let ((target (magit-get-upstream-branch it)))
+            (magit-git-push it target args)
+          (user-error "No upstream is configured for %s" it)))
+    (user-error "No branch is checked out")))
+
+(defun magit--push-current-set-upstream-p (&optional change)
+  (and (or change
+           (and magit-push-current-set-remote-if-missing
+                (not (magit-get-upstream-branch))))
+       (magit-get-current-branch)))
+
+(defun magit--push-current-to-upstream-desc ()
+  (--if-let (magit-get-upstream-branch)
+      (concat (magit-branch-set-face it) "\n")
+    (and (magit--push-current-set-upstream-p)
+         (concat (propertize "@{upstream}" 'face 'bold)
+                 ", after setting that\n"))))
+
+;;;###autoload
+(defun magit-push-current (target args)
+  "Push the current branch to a branch read in the minibuffer."
+  (interactive
+   (--if-let (magit-get-current-branch)
+       (list (magit-read-remote-branch (format "Push %s to" it)
+                                       nil nil it 'confirm)
+             (magit-push-arguments))
+     (user-error "No branch is checked out")))
+  (magit-git-push (magit-get-current-branch) target args))
+
+;;;###autoload
+(defun magit-push (source target args)
+  "Push an arbitrary branch or commit somewhere.
+Both the source and the target are read in the minibuffer."
+  (interactive
+   (let ((source (magit-read-local-branch-or-commit "Push")))
+     (list source
+           (magit-read-remote-branch
+            (format "Push %s to" source) nil
+            (if (magit-local-branch-p source)
+                (or (magit-get-push-branch source)
+                    (magit-get-upstream-branch source))
+              (and (magit-rev-ancestor-p source "HEAD")
+                   (or (magit-get-push-branch)
+                       (magit-get-upstream-branch))))
+            source 'confirm)
+           (magit-push-arguments))))
+  (magit-git-push source target args))
+
+(defvar magit-push-refspecs-history nil)
+
+;;;###autoload
+(defun magit-push-refspecs (remote refspecs args)
+  "Push one or multiple REFSPECS to a REMOTE.
+Both the REMOTE and the REFSPECS are read in the minibuffer.  To
+use multiple REFSPECS, separate them with commas.  Completion is
+only available for the part before the colon, or when no colon
+is used."
+  (interactive
+   (list (magit-read-remote "Push to remote")
+         (split-string (magit-completing-read-multiple
+                        "Push refspec,s"
+                        (cons "HEAD" (magit-list-local-branch-names))
+                        nil nil 'magit-push-refspecs-history)
+                       crm-default-separator t)
+         (magit-push-arguments)))
+  (run-hooks 'magit-credential-hook)
+  (magit-run-git-async "push" "-v" args remote refspecs))
+
+;;;###autoload
+(defun magit-push-matching (remote &optional args)
+  "Push all matching branches to another repository.
+If multiple remotes exist, then read one from the user.
+If just one exists, use that without requiring confirmation."
+  (interactive (list (magit-read-remote "Push matching branches to" nil t)
+                     (magit-push-arguments)))
+  (run-hooks 'magit-credential-hook)
+  (magit-run-git-async "push" "-v" args remote ":"))
+
+;;;###autoload
+(defun magit-push-tags (remote &optional args)
+  "Push all tags to another repository.
+If only one remote exists, then push to that.  Otherwise prompt
+for a remote, offering the remote configured for the current
+branch as default."
+  (interactive (list (magit-read-remote "Push tags to remote" nil t)
+                     (magit-push-arguments)))
+  (run-hooks 'magit-credential-hook)
+  (magit-run-git-async "push" remote "--tags" args))
+
+;;;###autoload
+(defun magit-push-tag (tag remote &optional args)
+  "Push a tag to another repository."
+  (interactive
+   (let  ((tag (magit-read-tag "Push tag")))
+     (list tag (magit-read-remote (format "Push %s to remote" tag) nil t)
+           (magit-push-arguments))))
+  (run-hooks 'magit-credential-hook)
+  (magit-run-git-async "push" remote tag args))
+
+;;;###autoload
+(defun magit-push-implicitly (args)
+  "Push somewhere without using an explicit refspec.
+
+This command simply runs \"git push -v [ARGS]\".  ARGS are the
+arguments specified in the popup buffer.  No explicit refspec
+arguments are used.  Instead the behavior depends on at least
+these Git variables: `push.default', `remote.pushDefault',
+`branch.<branch>.pushRemote', `branch.<branch>.remote',
+`branch.<branch>.merge', and `remote.<remote>.push'.
+
+To add this command to the push popup add this to your init file:
+
+  (with-eval-after-load \\='magit-remote
+    (magit-define-popup-action \\='magit-push-popup ?P
+      \\='magit-push-implicitly--desc
+      \\='magit-push-implicitly ?p t))
+
+The function `magit-push-implicitly--desc' attempts to predict
+what this command will do.  The value it returns is displayed in
+the popup buffer."
+  (interactive (list (magit-push-arguments)))
+  (run-hooks 'magit-credential-hook)
+  (magit-run-git-async "push" "-v" args))
+
+(defun magit-push-implicitly--desc ()
+  (let ((default (magit-get "push.default")))
+    (unless (equal default "nothing")
+      (or (when-let ((remote (or (magit-get-remote)
+                                 (magit-remote-p "origin")))
+                     (refspec (magit-get "remote" remote "push")))
+            (format "%s using %s"
+                    (propertize remote  'face 'magit-branch-remote)
+                    (propertize refspec 'face 'bold)))
+          (--when-let (and (not (magit-get-push-branch))
+                           (magit-get-upstream-branch))
+            (format "%s aka %s\n"
+                    (magit-branch-set-face it)
+                    (propertize "@{upstream}" 'face 'bold)))
+          (--when-let (magit-get-push-branch)
+            (format "%s aka %s\n"
+                    (magit-branch-set-face it)
+                    (propertize "pushRemote" 'face 'bold)))
+          (--when-let (magit-get-@{push}-branch)
+            (format "%s aka %s\n"
+                    (magit-branch-set-face it)
+                    (propertize "@{push}" 'face 'bold)))
+          (format "using %s (%s is %s)\n"
+                  (propertize "git push"     'face 'bold)
+                  (propertize "push.default" 'face 'bold)
+                  (propertize default        'face 'bold))))))
+
+;;;###autoload
+(defun magit-push-to-remote (remote args)
+  "Push to REMOTE without using an explicit refspec.
+The REMOTE is read in the minibuffer.
+
+This command simply runs \"git push -v [ARGS] REMOTE\".  ARGS
+are the arguments specified in the popup buffer.  No refspec
+arguments are used.  Instead the behavior depends on at least
+these Git variables: `push.default', `remote.pushDefault',
+`branch.<branch>.pushRemote', `branch.<branch>.remote',
+`branch.<branch>.merge', and `remote.<remote>.push'.
+
+To add this command to the push popup add this to your init file:
+
+  (with-eval-after-load \\='magit-remote
+    (magit-define-popup-action \\='magit-push-popup ?r
+      \\='magit-push-to-remote--desc
+      \\='magit-push-to-remote ?p t))"
+  (interactive (list (magit-read-remote "Push to remote")
+                     (magit-push-arguments)))
+  (run-hooks 'magit-credential-hook)
+  (magit-run-git-async "push" "-v" args remote))
+
+(defun magit-push-to-remote--desc ()
+  (format "using %s\n" (propertize "git push <remote>" 'face 'bold)))
+
+;;; Email
+
+;;;###autoload (autoload 'magit-patch-popup "magit-remote" nil t)
+(magit-define-popup magit-patch-popup
+  "Popup console for patch commands."
+  :man-page "git-format-patch"
+  :switches '("Switches for formatting patches"
+              (?l "Add cover letter" "--cover-letter"))
+  :options  '("Options for formatting patches"
+              (?f "From"             "--from=")
+              (?t "To"               "--to=")
+              (?c "CC"               "--cc=")
+              (?r "In reply to"      "--in-reply-to=")
+              (?P "Subject Prefix"   "--subject-prefix=")
+              (?v "Reroll count"     "--reroll-count=")
+              (?s "Thread style"     "--thread=")
+              (?U "Context lines"    "-U")
+              (?M "Detect renames"   "-M")
+              (?C "Detect copies"    "-C")
+              (?A "Diff algorithm"   "--diff-algorithm="
+                  magit-diff-select-algorithm)
+              (?o "Output directory" "--output-directory="))
+  :actions  '((?p "Format patches"   magit-format-patch)
+              (?r "Request pull"     magit-request-pull))
+  :default-action 'magit-format-patch)
+
+;;;###autoload
+(defun magit-format-patch (range args)
+  "Create patches for the commits in RANGE.
+When a single commit is given for RANGE, create a patch for the
+changes introduced by that commit (unlike 'git format-patch'
+which creates patches for all commits that are reachable from
+`HEAD' but not from the specified commit)."
+  (interactive
+   (list (if-let ((revs (magit-region-values 'commit t)))
+             (concat (car (last revs)) "^.." (car revs))
+           (let ((range (magit-read-range-or-commit "Format range or commit")))
+             (if (string-match-p "\\.\\." range)
+                 range
+               (format "%s~..%s" range range))))
+         (magit-patch-arguments)))
+  (magit-call-git "format-patch" range args)
+  (when (member "--cover-letter" args)
+    (find-file
+     (expand-file-name
+      "0000-cover-letter.patch"
+      (let ((topdir (magit-toplevel)))
+        (or (--some (and (string-match "--output-directory=\\(.+\\)" it)
+                         (expand-file-name (match-string 1 it) topdir))
+                    args)
+            topdir))))))
+
+;;;###autoload
+(defun magit-request-pull (url start end)
+  "Request upstream to pull from you public repository.
+
+URL is the url of your publically accessible repository.
+START is a commit that already is in the upstream repository.
+END is the last commit, usually a branch name, which upstream
+is asked to pull.  START has to be reachable from that commit."
+  (interactive
+   (list (magit-get "remote" (magit-read-remote "Remote") "url")
+         (magit-read-branch-or-commit "Start" (magit-get-upstream-branch))
+         (magit-read-branch-or-commit "End")))
+  (let ((dir default-directory))
+    ;; mu4e changes default-directory
+    (compose-mail)
+    (setq default-directory dir))
+  (message-goto-body)
+  (magit-git-insert "request-pull" start url end)
+  (set-buffer-modified-p nil))
+
+(provide 'magit-remote)
+;;; magit-remote.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-remote.elc b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-remote.elc
new file mode 100644
index 0000000000..2622d6e23b
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-remote.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-repos.el b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-repos.el
new file mode 100644
index 0000000000..39b4d095f1
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-repos.el
@@ -0,0 +1,304 @@
+;;; magit-repos.el --- listing repositories  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2010-2018  The Magit Project Contributors
+;;
+;; You should have received a copy of the AUTHORS.md file which
+;; lists all contributors.  If not, see http://magit.vc/authors.
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; Magit 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, or (at your option)
+;; any later version.
+;;
+;; Magit 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 Magit.  If not, see http://www.gnu.org/licenses.
+
+;;; Commentary:
+
+;; This library implements support for listing repositories.  This
+;; includes getting a Lisp list of known repositories as well as a
+;; mode for listing repositories in a buffer.
+
+;;; Code:
+
+(require 'magit-core)
+
+(declare-function magit-status-internal "magit-status" (directory))
+
+(defvar x-stretch-cursor)
+
+;;; Options
+
+(defcustom magit-repository-directories nil
+  "List of directories that are or contain Git repositories.
+
+Each element has the form (DIRECTORY . DEPTH).  DIRECTORY has
+to be a directory or a directory file-name, a string.  DEPTH,
+an integer, specifies the maximum depth to look for Git
+repositories.  If it is 0, then only add DIRECTORY itself."
+  :package-version '(magit . "2.8.0")
+  :group 'magit-essentials
+  :type '(repeat (cons directory (integer :tag "Depth"))))
+
+(defgroup magit-repolist nil
+  "List repositories in a buffer."
+  :link '(info-link "(magit)Repository List")
+  :group 'magit-modes)
+
+(defcustom magit-repolist-mode-hook '(hl-line-mode)
+  "Hook run after entering Magit-Repolist mode."
+  :package-version '(magit . "2.9.0")
+  :group 'magit-repolist
+  :type 'hook
+  :get 'magit-hook-custom-get
+  :options '(hl-line-mode))
+
+(defcustom magit-repolist-columns
+  '(("Name"    25 magit-repolist-column-ident nil)
+    ("Version" 25 magit-repolist-column-version nil)
+    ("B<U"      3 magit-repolist-column-unpulled-from-upstream
+     ((:right-align t)
+      (:help-echo "Upstream changes not in branch")))
+    ("B>U"      3 magit-repolist-column-unpushed-to-upstream
+     ((:right-align t)
+      (:help-echo "Local changes not in upstream")))
+    ("Path"    99 magit-repolist-column-path nil))
+  "List of columns displayed by `magit-list-repositories'.
+
+Each element has the form (HEADER WIDTH FORMAT PROPS).
+
+HEADER is the string displayed in the header.  WIDTH is the width
+of the column.  FORMAT is a function that is called with one
+argument, the repository identification (usually its basename),
+and with `default-directory' bound to the toplevel of its working
+tree.  It has to return a string to be inserted or nil.  PROPS is
+an alist that supports the keys `:right-align' and `:pad-right'.
+Some entries also use `:help-echo', but `tabulated-list' does not
+actually support that yet."
+  :package-version '(magit . "2.12.0")
+  :group 'magit-repolist
+  :type `(repeat (list :tag "Column"
+                       (string   :tag "Header Label")
+                       (integer  :tag "Column Width")
+                       (function :tag "Inserter Function")
+                       (repeat   :tag "Properties"
+                                 (list (choice :tag "Property"
+                                               (const :right-align)
+                                               (const :pad-right)
+                                               (symbol))
+                                       (sexp   :tag "Value"))))))
+
+
+;;; List Repositories
+;;;; Command
+;;;###autoload
+(defun magit-list-repositories ()
+  "Display a list of repositories.
+
+Use the options `magit-repository-directories' to control which
+repositories are displayed."
+  (interactive)
+  (if magit-repository-directories
+      (with-current-buffer (get-buffer-create "*Magit Repositories*")
+        (magit-repolist-mode)
+        (magit-repolist-refresh)
+        (tabulated-list-print)
+        (switch-to-buffer (current-buffer)))
+    (message "You need to customize `magit-repository-directories' %s"
+             "before you can list repositories")))
+
+;;;; Mode
+
+(defvar magit-repolist-mode-map
+  (let ((map (make-sparse-keymap)))
+    (set-keymap-parent map tabulated-list-mode-map)
+    (define-key map (if (featurep 'jkl) [return] (kbd "C-m"))
+      'magit-repolist-status)
+    map)
+  "Local keymap for Magit-Repolist mode buffers.")
+
+(defun magit-repolist-status (&optional _button)
+  "Show the status for the repository at point."
+  (interactive)
+  (--if-let (tabulated-list-get-id)
+      (magit-status-internal (expand-file-name it))
+    (user-error "There is no repository at point")))
+
+(define-derived-mode magit-repolist-mode tabulated-list-mode "Repos"
+  "Major mode for browsing a list of Git repositories."
+  (setq x-stretch-cursor        nil)
+  (setq tabulated-list-padding  0)
+  (setq tabulated-list-sort-key (cons "Path" nil))
+  (setq tabulated-list-format
+        (vconcat (mapcar (pcase-lambda (`(,title ,width ,_fn ,props))
+                           (nconc (list title width t)
+                                  (-flatten props)))
+                         magit-repolist-columns)))
+  (tabulated-list-init-header)
+  (add-hook 'tabulated-list-revert-hook 'magit-repolist-refresh nil t)
+  (setq imenu-prev-index-position-function
+        'magit-imenu--repolist-prev-index-position-function)
+  (setq imenu-extract-index-name-function
+        'magit-imenu--repolist-extract-index-name-function))
+
+(defun magit-repolist-refresh ()
+  (setq tabulated-list-entries
+        (mapcar (pcase-lambda (`(,id . ,path))
+                  (let ((default-directory path))
+                    (list path
+                          (vconcat (--map (or (funcall (nth 2 it) id) "")
+                                          magit-repolist-columns)))))
+                (magit-list-repos-uniquify
+                 (--map (cons (file-name-nondirectory (directory-file-name it))
+                              it)
+                        (magit-list-repos))))))
+
+;;;; Columns
+
+(defun magit-repolist-column-ident (id)
+  "Insert the identification of the repository.
+Usually this is just its basename."
+  id)
+
+(defun magit-repolist-column-path (_id)
+  "Insert the absolute path of the repository."
+  (abbreviate-file-name default-directory))
+
+(defun magit-repolist-column-version (_id)
+  "Insert a description of the repository's `HEAD' revision."
+  (let ((v (or (magit-git-string "describe" "--tags")
+               ;; If there are no tags, use the date in MELPA format.
+               (magit-git-string "show" "--no-patch" "--format=%cd-g%h"
+                                 "--date=format:%Y%m%d.%H%M"))))
+    (if (and v (string-match-p "\\`[0-9]" v))
+        (concat " " v)
+      v)))
+
+(defun magit-repolist-column-branch (_id)
+  "Insert the current branch."
+  (magit-get-current-branch))
+
+(defun magit-repolist-column-upstream (_id)
+  "Insert the upstream branch of the current branch."
+  (magit-get-upstream-branch))
+
+(defun magit-repolist-column-dirty (_id)
+  "Insert a letter if there are uncommitted changes.
+
+Show N if there is at least one untracked file.
+Show U if there is at least one unstaged file.
+Show S if there is at least one staged file.
+Only one letter is shown, the first that applies."
+  (cond ((magit-untracked-files) "N")
+        ((magit-unstaged-files)  "U")
+        ((magit-staged-files)    "S")))
+
+(defun magit-repolist-column-unpulled-from-upstream (_id)
+  "Insert number of upstream commits not in the current branch."
+  (--when-let (magit-get-upstream-branch nil t)
+    (let ((n (cadr (magit-rev-diff-count "HEAD" it))))
+      (propertize (number-to-string n) 'face (if (> n 0) 'bold 'shadow)))))
+
+(defun magit-repolist-column-unpulled-from-pushremote (_id)
+  "Insert number of commits in the push branch but not the current branch."
+  (--when-let (magit-get-push-branch nil t)
+    (let ((n (cadr (magit-rev-diff-count "HEAD" it))))
+      (propertize (number-to-string n) 'face (if (> n 0) 'bold 'shadow)))))
+
+(defun magit-repolist-column-unpushed-to-upstream (_id)
+  "Insert number of commits in the current branch but not its upstream."
+  (--when-let (magit-get-upstream-branch nil t)
+    (let ((n (car (magit-rev-diff-count "HEAD" it))))
+      (propertize (number-to-string n) 'face (if (> n 0) 'bold 'shadow)))))
+
+(defun magit-repolist-column-unpushed-to-pushremote (_id)
+  "Insert number of commits in the current branch but not its push branch."
+  (--when-let (magit-get-push-branch nil t)
+    (let ((n (car (magit-rev-diff-count "HEAD" it))))
+      (propertize (number-to-string n) 'face (if (> n 0) 'bold 'shadow)))))
+
+(defun magit-repolist-column-branches (_id)
+  "Insert number of branches."
+  (let ((n (length (magit-list-local-branches))))
+    (propertize (number-to-string n) 'face (if (> n 1) 'bold 'shadow))))
+
+(defun magit-repolist-column-stashes (_id)
+  "Insert number of stashes."
+  (let ((n (length (magit-list-stashes))))
+    (propertize (number-to-string n) 'face (if (> n 0) 'bold 'shadow))))
+
+;;; Read Repository
+
+(defun magit-read-repository (&optional read-directory-name)
+  "Read a Git repository in the minibuffer, with completion.
+
+The completion choices are the basenames of top-levels of
+repositories found in the directories specified by option
+`magit-repository-directories'.  In case of name conflicts
+the basenames are prefixed with the name of the respective
+parent directories.  The returned value is the actual path
+to the selected repository.
+
+With prefix argument simply read a directory name using
+`read-directory-name'."
+  (if (and (not read-directory-name) magit-repository-directories)
+      (let* ((repos (magit-list-repos-uniquify
+                     (--map (cons (file-name-nondirectory
+                                   (directory-file-name it))
+                                  it)
+                            (magit-list-repos))))
+             (reply (magit-completing-read "Git repository" repos)))
+        (file-name-as-directory
+         (or (cdr (assoc reply repos))
+             (if (file-directory-p reply)
+                 (expand-file-name reply)
+               (user-error "Not a repository or a directory: %s" reply)))))
+    (file-name-as-directory
+     (read-directory-name "Git repository: "
+                          (or (magit-toplevel) default-directory)))))
+
+(defun magit-list-repos ()
+  (cl-mapcan (pcase-lambda (`(,dir . ,depth))
+               (magit-list-repos-1 dir depth))
+             magit-repository-directories))
+
+(defun magit-list-repos-1 (directory depth)
+  (cond ((file-readable-p (expand-file-name ".git" directory))
+         (list directory))
+        ((and (> depth 0) (magit-file-accessible-directory-p directory))
+         (--mapcat (and (file-directory-p it)
+                        (magit-list-repos-1 it (1- depth)))
+                   (directory-files directory t
+                                    directory-files-no-dot-files-regexp t)))))
+
+(defun magit-list-repos-uniquify (alist)
+  (let (result (dict (make-hash-table :test 'equal)))
+    (dolist (a (delete-dups alist))
+      (puthash (car a) (cons (cdr a) (gethash (car a) dict)) dict))
+    (maphash
+     (lambda (key value)
+       (if (= (length value) 1)
+           (push (cons key (car value)) result)
+         (setq result
+               (append result
+                       (magit-list-repos-uniquify
+                        (--map (cons (concat
+                                      key "\\"
+                                      (file-name-nondirectory
+                                       (directory-file-name
+                                        (substring it 0 (- (1+ (length key)))))))
+                                     it)
+                               value))))))
+     dict)
+    result))
+
+(provide 'magit-repos)
+;;; magit-repos.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-repos.elc b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-repos.elc
new file mode 100644
index 0000000000..43513e84e8
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-repos.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-reset.el b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-reset.el
new file mode 100644
index 0000000000..1f56cf8c68
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-reset.el
@@ -0,0 +1,113 @@
+;;; magit-reset.el --- reset fuctionality  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2010-2018  The Magit Project Contributors
+;;
+;; You should have received a copy of the AUTHORS.md file which
+;; lists all contributors.  If not, see http://magit.vc/authors.
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; Magit 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, or (at your option)
+;; any later version.
+;;
+;; Magit 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 Magit.  If not, see http://www.gnu.org/licenses.
+
+;;; Commentary:
+
+;; This library implements reset commands.
+
+;;; Code:
+
+(require 'magit)
+
+;;;###autoload (autoload 'magit-reset-popup "magit" nil t)
+(magit-define-popup magit-reset-popup
+  "Popup console for reset commands."
+  :man-page "git-reset"
+  :actions '((?m "reset mixed  (HEAD and index)"         magit-reset-head)
+             (?s "reset soft   (HEAD only)"              magit-reset-soft)
+             (?h "reset hard   (HEAD, index, and files)" magit-reset-hard)
+             (?i "reset index  (index only)"             magit-reset-index) nil
+             (?f "reset a file"                          magit-file-checkout))
+  :max-action-columns 1)
+
+;;;###autoload
+(defun magit-reset-index (commit)
+  "Reset the index to COMMIT.
+Keep the head and working tree as-is, so if COMMIT refers to the
+head this effectively unstages all changes.
+\n(git reset COMMIT .)"
+  (interactive (list (magit-read-branch-or-commit "Reset index to")))
+  (magit-reset-internal nil commit "."))
+
+;;;###autoload
+(defun magit-reset (commit &optional hard)
+  "Reset the head and index to COMMIT, but not the working tree.
+With a prefix argument also reset the working tree.
+\n(git reset --mixed|--hard COMMIT)"
+  (interactive (list (magit-reset-read-branch-or-commit
+                      (if current-prefix-arg
+                          (concat (propertize "Hard" 'face 'bold)
+                                  " reset %s to")
+                        "Reset %s to"))
+                     current-prefix-arg))
+  (magit-reset-internal (if hard "--hard" "--mixed") commit))
+
+;;;###autoload
+(defun magit-reset-head (commit)
+  "Reset the head and index to COMMIT, but not the working tree.
+\n(git reset --mixed COMMIT)"
+  (interactive (list (magit-reset-read-branch-or-commit "Reset %s to")))
+  (magit-reset-internal "--mixed" commit))
+
+;;;###autoload
+(defun magit-reset-soft (commit)
+  "Reset the head to COMMIT, but not the index and working tree.
+\n(git reset --soft REVISION)"
+  (interactive (list (magit-reset-read-branch-or-commit "Soft reset %s to")))
+  (magit-reset-internal "--soft" commit))
+
+;;;###autoload
+(defun magit-reset-hard (commit)
+  "Reset the head, index, and working tree to COMMIT.
+\n(git reset --hard REVISION)"
+  (interactive (list (magit-reset-read-branch-or-commit
+                      (concat (propertize "Hard" 'face 'bold)
+                              " reset %s to"))))
+  (magit-reset-internal "--hard" commit))
+
+(defun magit-reset-read-branch-or-commit (prompt)
+  "Prompt for and return a ref to reset HEAD to.
+
+PROMPT is a format string, where either the current branch name
+or \"detached head\" will be substituted for %s."
+  (magit-read-branch-or-commit
+   (format prompt (or (magit-get-current-branch) "detached head"))))
+
+(defun magit-reset-internal (arg commit &optional path)
+  (when (and (not (member arg '("--hard" nil)))
+             (equal (magit-rev-parse commit)
+                    (magit-rev-parse "HEAD~")))
+    (with-temp-buffer
+      (magit-git-insert "show" "-s" "--format=%B" "HEAD")
+      (when git-commit-major-mode
+        (funcall git-commit-major-mode))
+      (git-commit-setup-font-lock)
+      (git-commit-save-message)))
+  (let ((cmd (if (and (equal commit "HEAD") (not arg)) "unstage" "reset")))
+    (magit-wip-commit-before-change nil (concat " before " cmd))
+    (magit-run-git "reset" arg commit "--" path)
+    (when (equal cmd "unstage")
+      (magit-wip-commit-after-apply nil " after unstage"))))
+
+(provide 'magit-reset)
+;;; magit-reset.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-reset.elc b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-reset.elc
new file mode 100644
index 0000000000..c33e3b356a
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-reset.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-section.el b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-section.el
new file mode 100644
index 0000000000..139ac48662
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-section.el
@@ -0,0 +1,1327 @@
+;;; magit-section.el --- section functionality  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2010-2018  The Magit Project Contributors
+;;
+;; You should have received a copy of the AUTHORS.md file which
+;; lists all contributors.  If not, see http://magit.vc/authors.
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; Magit 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, or (at your option)
+;; any later version.
+;;
+;; Magit 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 Magit.  If not, see http://www.gnu.org/licenses.
+
+;;; Commentary:
+
+;; This library implements "sections" as used in all Magit buffers.
+;; If you have used Magit before, then you probably know what that
+;; means, otherwise think "read-only Org-Mode for Git", kinda.
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'dash)
+(require 'eieio)
+
+(require 'magit-utils)
+
+(declare-function magit-maybe-make-margin-overlay "magit-margin" ())
+(declare-function magit-repository-local-get "magit-mode"
+                  (key &optional default repository))
+(declare-function magit-repository-local-set "magit-mode"
+                  (key value &optional repository))
+(defvar magit-keep-region-overlay)
+
+;;; Options
+
+(defgroup magit-section nil
+  "Expandable sections."
+  :link '(info-link "(magit)Sections")
+  :group 'magit)
+
+(defcustom magit-section-show-child-count t
+  "Whether to append the number of children to section headings.
+This only applies to sections for which doing so makes sense."
+  :package-version '(magit . "2.1.0")
+  :group 'magit-section
+  :type 'boolean)
+
+(defcustom magit-section-movement-hook
+  '(magit-hunk-set-window-start
+    magit-log-maybe-update-revision-buffer
+    magit-log-maybe-show-more-commits)
+  "Hook run by `magit-section-goto'.
+That function in turn is used by all section movement commands."
+  :package-version '(magit . "2.3.0")
+  :group 'magit-section
+  :type 'hook
+  :options '(magit-hunk-set-window-start
+             magit-status-maybe-update-revision-buffer
+             magit-status-maybe-update-blob-buffer
+             magit-log-maybe-update-revision-buffer
+             magit-log-maybe-update-blob-buffer
+             magit-log-maybe-show-more-commits))
+
+(defcustom magit-section-highlight-hook
+  '(magit-diff-highlight
+    magit-section-highlight
+    magit-section-highlight-selection)
+  "Functions used to highlight the current section.
+Each function is run with the current section as only argument
+until one of them returns non-nil."
+  :package-version '(magit . "2.1.0")
+  :group 'magit-section
+  :type 'hook
+  :options '(magit-diff-highlight
+             magit-section-highlight
+             magit-section-highlight-selection))
+
+(defcustom magit-section-unhighlight-hook
+  '(magit-diff-unhighlight)
+  "Functions used to unhighlight the previously current section.
+Each function is run with the current section as only argument
+until one of them returns non-nil.  Most sections are properly
+unhighlighted without requiring a specialized unhighlighter,
+diff-related sections being the only exception."
+  :package-version '(magit . "2.1.0")
+  :group 'magit-section
+  :type 'hook
+  :options '(magit-diff-unhighlight))
+
+(defcustom magit-section-set-visibility-hook
+  '(magit-diff-expansion-threshold
+    magit-section-cached-visibility)
+  "Hook used to set the initial visibility of a section.
+Stop at the first function that returns non-nil.  The returned
+value should be `show', `hide' or nil.  If no function returns
+non-nil, determine the visibility as usual, i.e. use the
+hardcoded section specific default (see `magit-insert-section')."
+  :package-version '(magit . "2.4.0")
+  :group 'magit-section
+  :type 'hook
+  :options '(magit-diff-expansion-threshold
+             magit-section-cached-visibility))
+
+(defcustom magit-section-cache-visibility t
+  "Whether to cache visibility of sections.
+
+Sections always retain their visibility state when they are being
+recreated during a refresh.  But if a section disappears and then
+later reappears again, then this option controls whether this is
+the case.
+
+If t, then cache the visibility of all sections.  If a list of
+section types, then only do so for matching sections.  If nil,
+then don't do so for any sections."
+  :package-version '(magit . "2.12.0")
+  :group 'magit-section
+  :type '(choice (const  :tag "Don't cache visibility" nil)
+                 (const  :tag "Cache visibility of all sections" t)
+                 (repeat :tag "Cache visibility for section types" symbol)))
+
+(defcustom magit-section-initial-visibility-alist nil
+  "Alist controlling the initial visibility of sections.
+
+Each element maps a section type or lineage to the initial
+visibility state for such sections.  The state has to be one of
+`show' or `hide', or a function that returns one of these symbols.
+A function is called with the section as the only argument.
+
+Use the command `magit-describe-section' to determine a section's
+lineage or type.  The vector in the output is the section lineage
+and the type is the first element of that vector.  Wildcards can
+be used, see `magit-section-match'.
+
+Currently this option is only used to override hardcoded defaults,
+but in the future it will also be used set the defaults."
+  :package-version '(magit . "2.12.0")
+  :group 'magit-section
+  :type '(alist :key-type (sexp :tag "Section type/lineage")
+                :value-type (choice (const hide)
+                                    (const show)
+                                    function)))
+
+(defface magit-section-highlight
+  '((((class color) (background light)) :background "grey95")
+    (((class color) (background  dark)) :background "grey20"))
+  "Face for highlighting the current section."
+  :group 'magit-faces)
+
+(defface magit-section-heading
+  '((((class color) (background light)) :foreground "DarkGoldenrod4" :weight bold)
+    (((class color) (background  dark)) :foreground "LightGoldenrod2" :weight bold))
+  "Face for section headings."
+  :group 'magit-faces)
+
+(defface magit-section-secondary-heading '((t :weight bold))
+  "Face for section headings of some secondary headings."
+  :group 'magit-faces)
+
+(defface magit-section-heading-selection
+  '((((class color) (background light)) :foreground "salmon4")
+    (((class color) (background  dark)) :foreground "LightSalmon3"))
+  "Face for selected section headings."
+  :group 'magit-faces)
+
+;;; Core
+
+(defclass magit-section ()
+  ((type     :initform nil :initarg :type)
+   (value    :initform nil :initarg :value)
+   (start    :initform nil :initarg :start)
+   (content  :initform nil)
+   (end      :initform nil)
+   (hidden   :initform nil)
+   (washer   :initform nil)
+   (process  :initform nil)
+   (parent   :initform nil :initarg :parent)
+   (children :initform nil)))
+
+(defclass magit-file-section (magit-section)
+  ((source   :initform nil)
+   (header   :initform nil)))
+
+(defclass magit-hunk-section (magit-section)
+  ((refined  :initform nil)))
+
+(defvar-local magit-root-section nil
+  "The root section in the current buffer.
+All other sections are descendants of this section.  The value
+of this variable is set by `magit-insert-section' and you should
+never modify it.")
+(put 'magit-root-section 'permanent-local t)
+
+(defun magit-current-section ()
+  "Return the section at point."
+  (or (get-text-property (point) 'magit-section) magit-root-section))
+
+(defun magit-section-ident (section)
+  "Return an unique identifier for SECTION.
+The return value has the form ((TYPE . VALUE)...)."
+  (with-slots (type value parent) section
+    (cons (cons type
+                (cond ((not (memq type '(unpulled unpushed))) value)
+                      ((string-match-p "@{upstream}" value) value)
+                      ;; Unfortunately Git chokes on "@{push}" when
+                      ;; the value of `push.default' does not allow a
+                      ;; 1:1 mapping.  Arbitrary commands may consult
+                      ;; the section value so we cannot use "@{push}".
+                      ;; But `unpushed' and `unpulled' sections should
+                      ;; keep their identity when switching branches
+                      ;; so we have to use another value here.
+                      ((string-match-p "\\`\\.\\." value) "..@{push}")
+                      (t "@{push}..")))
+          (and parent
+               (magit-section-ident parent)))))
+
+(defun magit-get-section (ident &optional root)
+  "Return the section identified by IDENT.
+IDENT has to be a list as returned by `magit-section-ident'."
+  (setq ident (reverse ident))
+  (let ((section (or root magit-root-section)))
+    (when (eq (car (pop ident))
+              (oref section type))
+      (while (and ident
+                  (setq section
+                        (--first
+                         (and (eq    (caar ident) (oref it type))
+                              (equal (cdar ident) (oref it value)))
+                         (oref section children))))
+        (pop ident))
+      section)))
+
+(defun magit-section-lineage (section)
+  "Return the lineage of SECTION.
+The return value has the form [TYPE...]."
+  (apply #'vector (mapcar #'car (magit-section-ident section))))
+
+(defvar magit-insert-section--current nil "For internal use only.")
+(defvar magit-insert-section--parent  nil "For internal use only.")
+(defvar magit-insert-section--oldroot nil "For internal use only.")
+
+;;; Commands
+;;;; Movement
+
+(defun magit-section-forward ()
+  "Move to the beginning of the next visible section."
+  (interactive)
+  (if (eobp)
+      (user-error "No next section")
+    (let ((section (magit-current-section)))
+      (if (oref section parent)
+          (let ((next (and (not (oref section hidden))
+                           (not (= (oref section end)
+                                   (1+ (point))))
+                           (car (oref section children)))))
+            (while (and section (not next))
+              (unless (setq next (car (magit-section-siblings section 'next)))
+                (setq section (oref section parent))))
+            (if next
+                (magit-section-goto next)
+              (user-error "No next section")))
+        (magit-section-goto 1)))))
+
+(defun magit-section-backward ()
+  "Move to the beginning of the current or the previous visible section.
+When point is at the beginning of a section then move to the
+beginning of the previous visible section.  Otherwise move to
+the beginning of the current section."
+  (interactive)
+  (if (bobp)
+      (user-error "No previous section")
+    (let ((section (magit-current-section)) children)
+      (cond
+       ((and (= (point)
+                (1- (oref section end)))
+             (setq children (oref section children)))
+        (magit-section-goto (car (last children))))
+       ((and (oref section parent)
+             (not (= (point)
+                     (oref section start))))
+        (magit-section-goto section))
+       (t
+        (let ((prev (car (magit-section-siblings section 'prev))))
+          (if prev
+              (while (and (not (oref prev hidden))
+                          (setq children (oref prev children)))
+                (setq prev (car (last children))))
+            (setq prev (oref section parent)))
+          (cond (prev
+                 (magit-section-goto prev))
+                ((oref section parent)
+                 (user-error "No previous section"))
+                ;; Eob special cases.
+                ((not (get-text-property (1- (point)) 'invisible))
+                 (magit-section-goto -1))
+                (t
+                 (goto-char (previous-single-property-change
+                             (1- (point)) 'invisible))
+                 (forward-line -1)
+                 (magit-section-goto (magit-current-section))))))))))
+
+(defun magit-section-up ()
+  "Move to the beginning of the parent section."
+  (interactive)
+  (--if-let (oref (magit-current-section) parent)
+      (magit-section-goto it)
+    (user-error "No parent section")))
+
+(defun magit-section-forward-sibling ()
+  "Move to the beginning of the next sibling section.
+If there is no next sibling section, then move to the parent."
+  (interactive)
+  (let ((current (magit-current-section)))
+    (if (oref current parent)
+        (--if-let (car (magit-section-siblings current 'next))
+            (magit-section-goto it)
+          (magit-section-forward))
+      (magit-section-goto 1))))
+
+(defun magit-section-backward-sibling ()
+  "Move to the beginning of the previous sibling section.
+If there is no previous sibling section, then move to the parent."
+  (interactive)
+  (let ((current (magit-current-section)))
+    (if (oref current parent)
+        (--if-let (car (magit-section-siblings current 'prev))
+            (magit-section-goto it)
+          (magit-section-backward))
+      (magit-section-goto -1))))
+
+(defun magit-section-goto (arg)
+  (if (integerp arg)
+      (progn (forward-line arg)
+             (setq arg (magit-current-section)))
+    (goto-char (oref arg start)))
+  (run-hook-with-args 'magit-section-movement-hook arg))
+
+(defun magit-section-set-window-start (section)
+  "Ensure the beginning of SECTION is visible."
+  (unless (pos-visible-in-window-p (oref section end))
+    (set-window-start (selected-window) (oref section start))))
+
+(defun magit-hunk-set-window-start (section)
+  "When SECTION is a `hunk', ensure that its beginning is visible.
+It the SECTION has a different type, then do nothing."
+  (when (magit-hunk-section-p section)
+    (magit-section-set-window-start section)))
+
+(defmacro magit-define-section-jumper (name heading type &optional value)
+  "Define an interactive function to go some section.
+Together TYPE and VALUE identify the section.
+HEADING is the displayed heading of the section."
+  (declare (indent defun))
+  `(defun ,name (&optional expand) ,(format "\
+Jump to the section \"%s\".
+With a prefix argument also expand it." heading)
+     (interactive "P")
+     (--if-let (magit-get-section
+                (cons (cons ',type ,value)
+                      (magit-section-ident magit-root-section)))
+         (progn (goto-char (oref it start))
+                (when expand
+                  (with-local-quit (magit-section-show it))
+                  (recenter 0)))
+       (message ,(format "Section \"%s\" wasn't found" heading)))))
+
+;;;; Visibility
+
+(defun magit-section-show (section)
+  "Show the body of the current section."
+  (interactive (list (magit-current-section)))
+  (oset section hidden nil)
+  (when-let ((washer (oref section washer)))
+    (oset section washer nil)
+    (let ((inhibit-read-only t)
+          (magit-insert-section--parent section)
+          (content (oref section content)))
+      (save-excursion
+        (if (and content (< content (oref section end)))
+            (funcall washer section) ; already partially washed (hunk)
+          (goto-char (oref section end))
+          (oset section content (point-marker))
+          (funcall washer)
+          (oset section end (point-marker)))))
+    (magit-section-update-highlight))
+  (when-let ((beg (oref section content)))
+    (remove-overlays beg (oref section end) 'invisible t))
+  (magit-section-maybe-cache-visibility section)
+  (dolist (child (oref section children))
+    (if (oref child hidden)
+        (magit-section-hide child)
+      (magit-section-show child))))
+
+(defun magit-section-hide (section)
+  "Hide the body of the current section."
+  (interactive (list (magit-current-section)))
+  (if (eq section magit-root-section)
+      (user-error "Cannot hide root section")
+    (oset section hidden t)
+    (when-let ((beg (oref section content)))
+      (let ((end (oref section end)))
+        (remove-overlays beg end 'invisible t)
+        (let ((o (make-overlay beg end)))
+          (overlay-put o 'evaporate t)
+          (overlay-put o 'invisible t))))
+    (magit-section-maybe-cache-visibility section)))
+
+(defun magit-section-toggle (section)
+  "Toggle visibility of the body of the current section."
+  (interactive (list (magit-current-section)))
+  (if (eq section magit-root-section)
+      (user-error "Cannot hide root section")
+    (goto-char (oref section start))
+    (if (oref section hidden)
+        (magit-section-show section)
+      (magit-section-hide section))))
+
+(defun magit-section-toggle-children (section)
+  "Toggle visibility of bodies of children of the current section."
+  (interactive (list (magit-current-section)))
+  (goto-char (oref section start))
+  (let* ((children (oref section children))
+         (show (--any-p (oref it hidden) children)))
+    (dolist (c children)
+      (oset c hidden show)))
+  (magit-section-show section))
+
+(defun magit-section-show-children (section &optional depth)
+  "Recursively show the bodies of children of the current section.
+With a prefix argument show children that deep and hide deeper
+children."
+  (interactive (list (magit-current-section)))
+  (magit-section-show-children-1 section depth)
+  (magit-section-show section))
+
+(defun magit-section-show-children-1 (section &optional depth)
+  (dolist (child (oref section children))
+    (oset child hidden nil)
+    (if depth
+        (if (> depth 0)
+            (magit-section-show-children-1 child (1- depth))
+          (magit-section-hide child))
+      (magit-section-show-children-1 child))))
+
+(defun magit-section-hide-children (section)
+  "Recursively hide the bodies of children of the current section."
+  (interactive (list (magit-current-section)))
+  (mapc 'magit-section-hide (oref section children)))
+
+(defun magit-section-show-headings (section)
+  "Recursively show headings of children of the current section.
+Only show the headings, previously shown text-only bodies are
+hidden."
+  (interactive (list (magit-current-section)))
+  (magit-section-show-headings-1 section)
+  (magit-section-show section))
+
+(defun magit-section-show-headings-1 (section)
+  (dolist (child (oref section children))
+    (oset child hidden nil)
+    (when (or (oref child children)
+              (not (oref child content)))
+      (magit-section-show-headings-1 child))))
+
+(defun magit-section-cycle (section)
+  "Cycle visibility of current section and its children."
+  (interactive (list (magit-current-section)))
+  (goto-char (oref section start))
+  (if (oref section hidden)
+      (progn (magit-section-show section)
+             (magit-section-hide-children section))
+    (let ((children (oref section children)))
+      (cond ((and (--any-p (oref it hidden)   children)
+                  (--any-p (oref it children) children))
+             (magit-section-show-headings section))
+            ((-any-p 'magit-section-hidden-body children)
+             (magit-section-show-children section))
+            (t
+             (magit-section-hide section))))))
+
+(defun magit-section-cycle-global ()
+  "Cycle visibility of all sections in the current buffer."
+  (interactive)
+  (let ((children (oref magit-root-section children)))
+    (cond ((and (--any-p (oref it hidden)   children)
+                (--any-p (oref it children) children))
+           (magit-section-show-headings magit-root-section))
+          ((-any-p 'magit-section-hidden-body children)
+           (magit-section-show-children magit-root-section))
+          (t
+           (mapc 'magit-section-hide children)))))
+
+(defun magit-section-cycle-diffs ()
+  "Cycle visibility of diff-related sections in the current buffer."
+  (interactive)
+  (when-let ((sections
+              (cond ((derived-mode-p 'magit-status-mode)
+                     (--mapcat
+                      (when it
+                        (when (oref it hidden)
+                          (magit-section-show it))
+                        (oref it children))
+                      (list (magit-get-section '((staged)   (status)))
+                            (magit-get-section '((unstaged) (status))))))
+                    ((derived-mode-p 'magit-diff-mode)
+                     (-filter #'magit-file-section-p
+                              (oref magit-root-section children))))))
+    (if (--any-p (oref it hidden) sections)
+        (dolist (s sections)
+          (magit-section-show s)
+          (magit-section-hide-children s))
+      (let ((children (--mapcat (oref it children) sections)))
+        (cond ((and (--any-p (oref it hidden)   children)
+                    (--any-p (oref it children) children))
+               (mapc 'magit-section-show-headings sections))
+              ((-any-p 'magit-section-hidden-body children)
+               (mapc 'magit-section-show-children sections))
+              (t
+               (mapc 'magit-section-hide sections)))))))
+
+(defun magit-section-hidden-body (section &optional pred)
+  (--if-let (oref section children)
+      (funcall (or pred '-any-p) 'magit-section-hidden-body it)
+    (and (oref section content)
+         (oref section hidden))))
+
+(defun magit-section-invisible-p (section)
+  "Return t if the SECTION's body is invisible.
+When the body of an ancestor of SECTION is collapsed then
+SECTION's body (and heading) obviously cannot be visible."
+  (or (oref section hidden)
+      (--when-let (oref section parent)
+        (magit-section-invisible-p it))))
+
+(defun magit-section-show-level (level)
+  "Show surrounding sections up to LEVEL.
+If LEVEL is negative, show up to the absolute value.
+Sections at higher levels are hidden."
+  (if (< level 0)
+      (let ((s (magit-current-section)))
+        (setq level (- level))
+        (while (> (1- (length (magit-section-ident s))) level)
+          (setq s (oref s parent))
+          (goto-char (oref s start)))
+        (magit-section-show-children magit-root-section (1- level)))
+    (cl-do* ((s (magit-current-section)
+                (oref s parent))
+             (i (1- (length (magit-section-ident s)))
+                (cl-decf i)))
+        ((cond ((< i level) (magit-section-show-children s (- level i 1)) t)
+               ((= i level) (magit-section-hide s) t))
+         (magit-section-goto s)))))
+
+(defun magit-section-show-level-1 ()
+  "Show surrounding sections on first level."
+  (interactive)
+  (magit-section-show-level 1))
+
+(defun magit-section-show-level-1-all ()
+  "Show all sections on first level."
+  (interactive)
+  (magit-section-show-level -1))
+
+(defun magit-section-show-level-2 ()
+  "Show surrounding sections up to second level."
+  (interactive)
+  (magit-section-show-level 2))
+
+(defun magit-section-show-level-2-all ()
+  "Show all sections up to second level."
+  (interactive)
+  (magit-section-show-level -2))
+
+(defun magit-section-show-level-3 ()
+  "Show surrounding sections up to third level."
+  (interactive)
+  (magit-section-show-level 3))
+
+(defun magit-section-show-level-3-all ()
+  "Show all sections up to third level."
+  (interactive)
+  (magit-section-show-level -3))
+
+(defun magit-section-show-level-4 ()
+  "Show surrounding sections up to fourth level."
+  (interactive)
+  (magit-section-show-level 4))
+
+(defun magit-section-show-level-4-all ()
+  "Show all sections up to fourth level."
+  (interactive)
+  (magit-section-show-level -4))
+
+;;;; Auxiliary
+
+(defun magit-describe-section ()
+  "Show information about the section at point.
+This command is intended for debugging purposes."
+  (interactive)
+  (let ((section (magit-current-section)))
+    (message "%S %S %s-%s"
+             (oref section value)
+             (magit-section-lineage section)
+             (marker-position (oref section start))
+             (marker-position (oref section end)))))
+
+;;; Match
+
+(cl-defun magit-section-match
+    (condition &optional (section (magit-current-section)))
+  "Return t if SECTION matches CONDITION.
+
+SECTION defaults to the section at point.  If SECTION is not
+specified and there also is no section at point, then return
+nil.
+
+CONDITION can take the following forms:
+  (CONDITION...)  matches if any of the CONDITIONs matches.
+  [TYPE...]       matches if the first TYPE matches the type
+                  of the section, the second matches that of
+                  its parent, and so on.
+  [* TYPE...]     matches sections that match [TYPE...] and
+                  also recursively all their child sections.
+  TYPE            matches sections of TYPE regardless of the
+                  types of the parent sections.
+
+Each TYPE is a symbol.  Note that it is not necessary to specify
+all TYPEs up to the root section as printed by
+`magit-describe-type', unless of course you want to be that
+precise."
+  (and section
+       (magit-section-match-1 condition
+                              (mapcar #'car (magit-section-ident section)))))
+
+(defun magit-section-match-1 (condition type-list)
+  (if (listp condition)
+      (--first (magit-section-match-1 it type-list) condition)
+    (magit-section-match-2 (if (symbolp condition)
+                               (list condition)
+                             (append condition nil))
+                           type-list)))
+
+(defun magit-section-match-2 (l1 l2)
+  (or (null l1)
+      (if (eq (car l1) '*)
+          (or (magit-section-match-2 (cdr l1) l2)
+              (and l2
+                   (magit-section-match-2 l1 (cdr l2))))
+        (and l2
+             (equal (car l1) (car l2))
+             (magit-section-match-2 (cdr l1) (cdr l2))))))
+
+(defmacro magit-section-when (condition &rest body)
+  "If the section at point matches CONDITION, evaluate BODY.
+
+If the section matches, then evaluate BODY forms sequentially
+with `it' bound to the section and return the value of the last
+form.  If there are no BODY forms, then return the value of the
+section.  If the section does not match or if there is no section
+at point, then return nil.
+
+See `magit-section-match' for the forms CONDITION can take."
+  (declare (indent 1)
+           (debug (sexp body)))
+  `(--when-let (magit-current-section)
+     ;; Quoting CONDITION here often leads to double-quotes, which
+     ;; isn't an issue because `magit-section-match-1' implicitly
+     ;; deals with that.  We shouldn't force users of this function
+     ;; to not quote CONDITION because that would needlessly break
+     ;; backward compatibility.
+     (when (magit-section-match ',condition it)
+       ,@(or body '((oref it value))))))
+
+(defmacro magit-section-case (&rest clauses)
+  "Choose among clauses on the type of the section at point.
+
+Each clause looks like (CONDITION BODY...).  The type of the
+section is compared against each CONDITION; the BODY forms of the
+first match are evaluated sequentially and the value of the last
+form is returned.  Inside BODY the symbol `it' is bound to the
+section at point.  If no clause succeeds or if there is no
+section at point, return nil.
+
+See `magit-section-match' for the forms CONDITION can take.
+Additionally a CONDITION of t is allowed in the final clause, and
+matches if no other CONDITION match, even if there is no section
+at point."
+  (declare (indent 0)
+           (debug (&rest (sexp body))))
+  (let ((lineage (cl-gensym "lineage")))
+    `(let* ((it (magit-current-section))
+            (,lineage (and it (append (magit-section-lineage it) nil))))
+       (cond ,@(mapcar (lambda (clause)
+                         `(,(or (eq (car clause) t)
+                                `(and it (magit-section-match-1
+                                          ',(car clause) ,lineage)))
+                           ,@(cdr clause)))
+                       clauses)))))
+
+(defun magit-section-match-assoc (section alist)
+  "Return the value associated with SECTION's type or lineage in ALIST."
+  (let ((ident (mapcar #'car (magit-section-ident section))))
+    (-some (pcase-lambda (`(,key . ,val))
+             (and (magit-section-match-1 key ident) val))
+           alist)))
+
+;;; Create
+
+(defvar magit-insert-section-hook nil
+  "Hook run after `magit-insert-section's BODY.
+Avoid using this hook and only ever do so if you know
+what you are doing and are sure there is no other way.")
+
+(defmacro magit-insert-section (&rest args)
+  "Insert a section at point.
+
+TYPE is the section type, a symbol.  Many commands that act on
+the current section behave differently depending on that type.
+Also if a variable `magit-TYPE-section-map' exists, then use
+that as the text-property `keymap' of all text belonging to the
+section (but this may be overwritten in subsections).  TYPE can
+also have the form `(eval FORM)' in which case FORM is evaluated
+at runtime.
+
+Optional VALUE is the value of the section, usually a string
+that is required when acting on the section.
+
+When optional HIDE is non-nil collapse the section body by
+default, i.e. when first creating the section, but not when
+refreshing the buffer.  Else expand it by default.  This can be
+overwritten using `magit-section-set-visibility-hook'.  When a
+section is recreated during a refresh, then the visibility of
+predecessor is inherited and HIDE is ignored (but the hook is
+still honored).
+
+BODY is any number of forms that actually insert the section's
+heading and body.  Optional NAME, if specified, has to be a
+symbol, which is then bound to the struct of the section being
+inserted.
+
+Before BODY is evaluated the `start' of the section object is set
+to the value of `point' and after BODY was evaluated its `end' is
+set to the new value of `point'; BODY is responsible for moving
+`point' forward.
+
+If it turns out inside BODY that the section is empty, then
+`magit-cancel-section' can be used to abort and remove all traces
+of the partially inserted section.  This can happen when creating
+a section by washing Git's output and Git didn't actually output
+anything this time around.
+
+\(fn [NAME] (TYPE &optional VALUE HIDE) &rest BODY)"
+  (declare (indent defun)
+           (debug ([&optional symbolp]
+                   (&or [("eval" symbolp) &optional form form]
+                        [symbolp &optional form form])
+                   body)))
+  (let ((tp (cl-gensym "type"))
+        (s* (and (symbolp (car args))
+                 (pop args)))
+        (s  (cl-gensym "section")))
+    `(let* ((,tp ,(let ((type (nth 0 (car args))))
+                    (if (eq (car-safe type) 'eval)
+                        (cadr type)
+                      `',type)))
+            (,s (funcall (pcase ,tp
+                           (`file 'magit-file-section)
+                           (`hunk 'magit-hunk-section)
+                           (_     'magit-section))
+                         :type ,tp
+                         :value ,(nth 1 (car args))
+                         :start (point-marker)
+                         :parent magit-insert-section--parent)))
+       (oset ,s hidden
+             (if-let ((value (run-hook-with-args-until-success
+                              'magit-section-set-visibility-hook ,s)))
+                 (eq value 'hide)
+               (if-let ((incarnation (and magit-insert-section--oldroot
+                                          (magit-get-section
+                                           (magit-section-ident ,s)
+                                           magit-insert-section--oldroot))))
+                   (oref incarnation hidden)
+                 (if-let ((value (magit-section-match-assoc
+                                  ,s magit-section-initial-visibility-alist)))
+                     (progn
+                       (when (functionp value)
+                         (setq value (funcall value ,s)))
+                       (eq value 'hide))
+                   ,(nth 2 (car args))))))
+       (let ((magit-insert-section--current ,s)
+             (magit-insert-section--parent  ,s)
+             (magit-insert-section--oldroot
+              (or magit-insert-section--oldroot
+                  (unless magit-insert-section--parent
+                    (prog1 magit-root-section
+                      (setq magit-root-section ,s))))))
+         (catch 'cancel-section
+           ,@(if s*
+                 `((let ((,s* ,s))
+                     ,@(cdr args)))
+               (cdr args))
+           (run-hooks 'magit-insert-section-hook)
+           (magit-insert-child-count ,s)
+           (set-marker-insertion-type (oref ,s start) t)
+           (let* ((end (oset ,s end (point-marker)))
+                  (map (intern (format "magit-%s-section-map" (oref ,s type))))
+                  (map (and (boundp map) (symbol-value map))))
+             (save-excursion
+               (goto-char (oref ,s start))
+               (while (< (point) end)
+                 (let ((next (or (next-single-property-change
+                                  (point) 'magit-section)
+                                 end)))
+                   (unless (get-text-property (point) 'magit-section)
+                     (put-text-property (point) next 'magit-section ,s)
+                     (when map
+                       (put-text-property (point) next 'keymap map)))
+                   (goto-char next)))))
+           (if (eq ,s magit-root-section)
+               (let ((magit-section-cache-visibility nil))
+                 (magit-section-show ,s))
+             (oset (oref ,s parent) children
+                   (nconc (oref (oref ,s parent) children)
+                          (list ,s)))))
+         ,s))))
+
+(defun magit-cancel-section ()
+  (when magit-insert-section--current
+    (if (not (oref magit-insert-section--current parent))
+        (insert "(empty)\n")
+      (delete-region (oref magit-insert-section--current start)
+                     (point))
+      (setq magit-insert-section--current nil)
+      (throw 'cancel-section nil))))
+
+(defun magit-insert-heading (&rest args)
+  "Insert the heading for the section currently being inserted.
+
+This function should only be used inside `magit-insert-section'.
+
+When called without any arguments, then just set the `content'
+slot of the object representing the section being inserted to
+a marker at `point'.  The section should only contain a single
+line when this function is used like this.
+
+When called with arguments ARGS, which have to be strings, or
+nil, then insert those strings at point.  The section should not
+contain any text before this happens and afterwards it should
+again only contain a single line.  If the `face' property is set
+anywhere inside any of these strings, then insert all of them
+unchanged.  Otherwise use the `magit-section-heading' face for
+all inserted text.
+
+The `content' property of the section struct is the end of the
+heading (which lasts from `start' to `content') and the beginning
+of the the body (which lasts from `content' to `end').  If the
+value of `content' is nil, then the section has no heading and
+its body cannot be collapsed.  If a section does have a heading,
+then its height must be exactly one line, including a trailing
+newline character.  This isn't enforced, you are responsible for
+getting it right.  The only exception is that this function does
+insert a newline character if necessary."
+  (declare (indent defun))
+  (when args
+    (let ((heading (apply #'concat args)))
+      (insert (if (text-property-not-all 0 (length heading) 'face nil heading)
+                  heading
+                (propertize heading 'face 'magit-section-heading)))))
+  (unless (bolp)
+    (insert ?\n))
+  (magit-maybe-make-margin-overlay)
+  (oset magit-insert-section--current content (point-marker)))
+
+(defvar magit-insert-headers--hook nil "For internal use only.")
+(defvar magit-insert-headers--beginning nil "For internal use only.")
+
+(defun magit-insert-headers (hooks)
+  (let ((magit-insert-section-hook
+         (cons 'magit-insert-remaining-headers
+               (if (listp magit-insert-section-hook)
+                   magit-insert-section-hook
+                 (list magit-insert-section-hook))))
+        (magit-insert-headers--hook hooks)
+        wrapper)
+    (setq magit-insert-headers--beginning (point))
+    (while (and (setq wrapper (pop magit-insert-headers--hook))
+                (= (point) magit-insert-headers--beginning))
+      (funcall wrapper))))
+
+(defun magit-insert-remaining-headers ()
+  (if (= (point) magit-insert-headers--beginning)
+      (magit-cancel-section)
+    (magit-insert-heading)
+    (remove-hook 'magit-insert-section-hook 'magit-insert-remaining-headers)
+    (mapc #'funcall magit-insert-headers--hook)
+    (insert "\n")))
+
+(defun magit-insert-child-count (section)
+  "Modify SECTION's heading to contain number of child sections.
+
+If `magit-section-show-child-count' is non-nil and the SECTION
+has children and its heading ends with \":\", then replace that
+with \" (N)\", where N is the number of child sections.
+
+This function is called by `magit-insert-section' after that has
+evaluated its BODY.  Admittedly that's a bit of a hack."
+  ;; This has to be fast, not pretty!
+  (let (content count)
+    (when (and magit-section-show-child-count
+               (setq count (length (oref section children)))
+               (> count 0)
+               (setq content (oref section content))
+               (eq (char-before (1- content)) ?:))
+      (save-excursion
+        (goto-char (- content 2))
+        (insert (format " (%s)" count))
+        (delete-char 1)))))
+
+;;; Update
+
+(defvar-local magit-section-highlight-overlays nil)
+(defvar-local magit-section-highlighted-section nil)
+(defvar-local magit-section-highlighted-sections nil)
+(defvar-local magit-section-unhighlight-sections nil)
+
+(defun magit-section-update-region (_)
+  "When the region is a valid section-selection, highlight them all."
+  ;; At least that's what it does conceptually.  In actuality it just
+  ;; returns a list of those sections, and it doesn't even matter if
+  ;; this is a member of `magit-region-highlight-hook'.  It probably
+  ;; should be removed, but I want to make sure before removing it.
+  (magit-region-sections))
+
+(defun magit-section-update-highlight ()
+  (let ((section (magit-current-section)))
+    (unless (eq section magit-section-highlighted-section)
+      (let ((inhibit-read-only t)
+            (deactivate-mark nil)
+            (selection (magit-region-sections)))
+        (mapc #'delete-overlay magit-section-highlight-overlays)
+        (setq magit-section-highlight-overlays nil)
+        (setq magit-section-unhighlight-sections
+              magit-section-highlighted-sections)
+        (setq magit-section-highlighted-sections nil)
+        (unless (eq section magit-root-section)
+          (run-hook-with-args-until-success
+           'magit-section-highlight-hook section selection))
+        (dolist (s magit-section-unhighlight-sections)
+          (run-hook-with-args-until-success
+           'magit-section-unhighlight-hook s selection))
+        (restore-buffer-modified-p nil)
+        (unless (eq magit-section-highlighted-section section)
+          (setq magit-section-highlighted-section
+                (and (not (oref section hidden))
+                     section))))
+      (when (version< emacs-version "25.1")
+        (setq deactivate-mark nil)))))
+
+(defun magit-section-highlight (section selection)
+  "Highlight SECTION and if non-nil all sections in SELECTION.
+This function works for any section but produces undesirable
+effects for diff related sections, which by default are
+highlighted using `magit-diff-highlight'.  Return t."
+  (cond (selection
+         (magit-section-make-overlay (oref (car selection) start)
+                                     (oref (car (last selection)) end)
+                                     'magit-section-highlight)
+         (magit-section-highlight-selection nil selection))
+        (t
+         (magit-section-make-overlay (oref section start)
+                                     (oref section end)
+                                     'magit-section-highlight)))
+  t)
+
+(defun magit-section-highlight-selection (_ selection)
+  "Highlight the section-selection region.
+If SELECTION is non-nil, then it is a list of sections selected by
+the region.  The headings of these sections are then highlighted.
+
+This is a fallback for people who don't want to highlight the
+current section and therefore removed `magit-section-highlight'
+from `magit-section-highlight-hook'.
+
+This function is necessary to ensure that a representation of
+such a region is visible.  If neither of these functions were
+part of the hook variable, then such a region would be
+invisible."
+  (when (and selection
+             (not (and (eq this-command 'mouse-drag-region))))
+    (dolist (section selection)
+      (magit-section-make-overlay (oref section start)
+                                  (or (oref section content)
+                                      (oref section end))
+                                  'magit-section-heading-selection))
+    t))
+
+(defun magit-section-make-overlay (start end face)
+  ;; Yes, this doesn't belong here.  But the alternative of
+  ;; spreading this hack across the code base is even worse.
+  (when (and magit-keep-region-overlay
+             (memq face '(magit-section-heading-selection
+                          magit-diff-file-heading-selection
+                          magit-diff-hunk-heading-selection)))
+    (setq face (list :foreground (face-foreground face))))
+  (let ((ov (make-overlay start end nil t)))
+    (overlay-put ov 'face face)
+    (overlay-put ov 'evaporate t)
+    (push ov magit-section-highlight-overlays)
+    ov))
+
+(defun magit-section-goto-successor (section line char arg)
+  (let ((ident (magit-section-ident section)))
+    (--if-let (magit-get-section ident)
+        (let ((start (oref it start)))
+          (goto-char start)
+          (unless (eq it magit-root-section)
+            (ignore-errors
+              (forward-line line)
+              (forward-char char))
+            (unless (eq (magit-current-section) it)
+              (goto-char start))))
+      (or (and (magit-hunk-section-p section)
+               (when-let ((parent (magit-get-section
+                                   (magit-section-ident
+                                    (oref section parent)))))
+                 (let* ((children (oref parent children))
+                        (siblings (magit-section-siblings section 'prev))
+                        (previous (nth (length siblings) children)))
+                   (if (not arg)
+                       (--when-let (or previous (car (last children)))
+                         (magit-section-goto it)
+                         t)
+                     (when previous
+                       (magit-section-goto previous))
+                     (if (and (stringp arg)
+                              (re-search-forward arg (oref parent end) t))
+                         (goto-char (match-beginning 0))
+                       (goto-char (oref (car (last children)) end))
+                       (forward-line -1)
+                       (while (looking-at "^ ")    (forward-line -1))
+                       (while (looking-at "^[-+]") (forward-line -1))
+                       (forward-line))))))
+          (goto-char (--if-let (magit-section-goto-successor-1 section)
+                         (if (eq (oref it type) 'button)
+                             (point-min)
+                           (oref it start))
+                       (point-min)))))))
+
+(defun magit-section-goto-successor-1 (section)
+  (or (--when-let (pcase (oref section type)
+                    (`staged 'unstaged)
+                    (`unstaged 'staged)
+                    (`unpushed 'unpulled)
+                    (`unpulled 'unpushed))
+        (magit-get-section `((,it) (status))))
+      (--when-let (car (magit-section-siblings section 'next))
+        (magit-get-section (magit-section-ident it)))
+      (--when-let (car (magit-section-siblings section 'prev))
+        (magit-get-section (magit-section-ident it)))
+      (--when-let (oref section parent)
+        (or (magit-get-section (magit-section-ident it))
+            (magit-section-goto-successor-1 it)))))
+
+;;; Visibility
+
+(defvar-local magit-section-visibility-cache nil)
+(put 'magit-section-visibility-cache 'permanent-local t)
+
+(defun magit-section-cached-visibility (section)
+  "Set SECTION's visibility to the cached value."
+  (cdr (assoc (magit-section-ident section)
+              magit-section-visibility-cache)))
+
+(cl-defun magit-section-cache-visibility
+    (&optional (section magit-insert-section--current))
+  ;; Emacs 25's `alist-get' lacks TESTFN.
+  (let* ((id  (magit-section-ident section))
+         (elt (assoc id magit-section-visibility-cache))
+         (val (if (oref section hidden) 'hide 'show)))
+    (if elt
+        (setcdr elt val)
+      (push (cons id val) magit-section-visibility-cache))))
+
+(cl-defun magit-section-maybe-cache-visibility
+    (&optional (section magit-insert-section--current))
+  (when (or (eq magit-section-cache-visibility t)
+            (memq (oref section type)
+                  magit-section-cache-visibility))
+    (magit-section-cache-visibility section)))
+
+(defun magit-preserve-section-visibility-cache ()
+  (when (derived-mode-p 'magit-status-mode 'magit-refs-mode)
+    (magit-repository-local-set
+     (cons major-mode 'magit-section-visibility-cache)
+     magit-section-visibility-cache)))
+
+(defun magit-restore-section-visibility-cache (mode)
+  (setq magit-section-visibility-cache
+        (magit-repository-local-get
+         (cons mode 'magit-section-visibility-cache))))
+
+;;; Utilities
+
+(cl-defun magit-section-selected-p (section &optional (selection nil sselection))
+  (and (not (eq section magit-root-section))
+       (or  (eq section (magit-current-section))
+            (memq section (if sselection
+                              selection
+                            (setq selection (magit-region-sections))))
+            (--when-let (oref section parent)
+              (magit-section-selected-p it selection)))))
+
+(defun magit-section-parent-value (section)
+  (when-let ((parent (oref section parent)))
+    (oref parent value)))
+
+(defun magit-section-siblings (section &optional direction)
+  "Return a list of the sibling sections of SECTION.
+
+If optional DIRECTION is `prev', then return siblings that come
+before SECTION.  If it is `next', then return siblings that come
+after SECTION.  For all other values, return all siblings
+excluding SECTION itself."
+  (when-let ((parent (oref section parent)))
+    (let ((siblings (oref parent children)))
+      (pcase direction
+        (`prev  (cdr (member section (reverse siblings))))
+        (`next  (cdr (member section siblings)))
+        (_      (remq section siblings))))))
+
+(defun magit-region-values (&optional types multiple)
+  "Return a list of the values of the selected sections.
+
+Also see `magit-region-sections' whose doc-string explains when a
+region is a valid section selection.  If the region is not active
+or is not a valid section selection, then return nil.  If optional
+TYPES is non-nil then the selection not only has to be valid; the
+types of all selected sections additionally have to match one of
+TYPES, or nil is returned."
+  (--map (oref it value)
+         (magit-region-sections types multiple)))
+
+(defun magit-region-sections (&optional types multiple)
+  "Return a list of the selected sections.
+
+When the region is active and constitutes a valid section
+selection, then return a list of all selected sections.  This is
+the case when the region begins in the heading of a section and
+ends in the heading of the same section or in that of a sibling
+section.  If optional MULTIPLE is non-nil, then the region cannot
+begin and end in the same section.
+
+When the selection is not valid, then return nil.  In this case,
+most commands that can act on the selected sections will instead
+act on the section at point.
+
+When the region looks like it would in any other buffer then
+the selection is invalid.  When the selection is valid then the
+region uses the `magit-section-highlight' face.  This does not
+apply to diffs where things get a bit more complicated, but even
+here if the region looks like it usually does, then that's not
+a valid selection as far as this function is concerned.
+
+If optional TYPES is non-nil, then the selection not only has to
+be valid; the types of all selected sections additionally have
+to match one of TYPES, or nil is returned.  TYPES can also be a
+single type, instead of a list of types."
+  (when (region-active-p)
+    (let* ((rbeg (region-beginning))
+           (rend (region-end))
+           (sbeg (get-text-property rbeg 'magit-section))
+           (send (get-text-property rend 'magit-section)))
+      (when (and send
+                 (not (eq send magit-root-section))
+                 (not (and multiple (eq send sbeg))))
+        (let ((siblings (cons sbeg (magit-section-siblings sbeg 'next)))
+              sections)
+          (when (and (memq send siblings)
+                     (magit-section-position-in-heading-p sbeg rbeg)
+                     (magit-section-position-in-heading-p send rend))
+            (while siblings
+              (push (car siblings) sections)
+              (when (eq (pop siblings) send)
+                (setq siblings nil)))
+            (setq sections (nreverse sections))
+            (when (and types (symbolp types))
+              (setq types (list types)))
+            (when (or (not types)
+                      (--all-p (memq (oref it type) types) sections))
+              sections)))))))
+
+(defun magit-section-position-in-heading-p (&optional section pos)
+  "Return t if POSITION is inside the heading of SECTION.
+POSITION defaults to point and SECTION defaults to the
+current section."
+  (unless section
+    (setq section (magit-current-section)))
+  (unless pos
+    (setq pos (point)))
+  (and section
+       (>= pos (oref section start))
+       (<  pos (or (oref section content)
+                   (oref section end)))
+       t))
+
+(defun magit-section-internal-region-p (&optional section)
+  "Return t if the region is active and inside SECTION's body.
+If optional SECTION is nil, use the current section."
+  (and (region-active-p)
+       (or section (setq section (magit-current-section)))
+       (let ((beg (get-text-property (region-beginning) 'magit-section)))
+         (and (eq beg (get-text-property   (region-end) 'magit-section))
+              (eq beg section)))
+       (not (or (magit-section-position-in-heading-p section (region-beginning))
+                (magit-section-position-in-heading-p section (region-end))))
+       t))
+
+(defun magit-section--backward-protected ()
+  "Move to the beginning of the current or the previous visible section.
+Same as `magit-section-backward' but for non-interactive use.
+Suppress `magit-section-movement-hook', and return a boolean to
+indicate whether a section was found, instead of raising an error
+if not."
+  (condition-case nil
+      (let ((magit-section-movement-hook nil))
+        (magit-section-backward)
+        t)
+    (user-error nil)))
+
+(defun magit-section--backward-find (predicate)
+  "Move to the first previous section satisfying PREDICATE.
+PREDICATE does not take any parameter and should not move
+point."
+  (let (found)
+    (while (and (setq found (magit-section--backward-protected))
+                (not (funcall predicate))))
+    found))
+
+(defun magit-wash-sequence (function)
+  "Repeatedly call FUNCTION until it returns nil or eob is reached.
+FUNCTION has to move point forward or return nil."
+  (while (and (not (eobp)) (funcall function))))
+
+(defun magit-add-section-hook (hook function &optional at append local)
+  "Add to the value of section hook HOOK the function FUNCTION.
+
+Add FUNCTION at the beginning of the hook list unless optional
+APPEND is non-nil, in which case FUNCTION is added at the end.
+If FUNCTION already is a member, then move it to the new location.
+
+If optional AT is non-nil and a member of the hook list, then
+add FUNCTION next to that instead.  Add before or after AT, or
+replace AT with FUNCTION depending on APPEND.  If APPEND is the
+symbol `replace', then replace AT with FUNCTION.  For any other
+non-nil value place FUNCTION right after AT.  If nil, then place
+FUNCTION right before AT.  If FUNCTION already is a member of the
+list but AT is not, then leave FUNCTION where ever it already is.
+
+If optional LOCAL is non-nil, then modify the hook's buffer-local
+value rather than its global value.  This makes the hook local by
+copying the default value.  That copy is then modified.
+
+HOOK should be a symbol.  If HOOK is void, it is first set to nil.
+HOOK's value must not be a single hook function.  FUNCTION should
+be a function that takes no arguments and inserts one or multiple
+sections at point, moving point forward.  FUNCTION may choose not
+to insert its section(s), when doing so would not make sense.  It
+should not be abused for other side-effects.  To remove FUNCTION
+again use `remove-hook'."
+  (unless (boundp hook)
+    (error "Cannot add function to undefined hook variable %s" hook))
+  (or (default-boundp hook) (set-default hook nil))
+  (let ((value (if local
+                   (if (local-variable-p hook)
+                       (symbol-value hook)
+                     (unless (local-variable-if-set-p hook)
+                       (make-local-variable hook))
+                     (copy-sequence (default-value hook)))
+                 (default-value hook))))
+    (if at
+        (when (setq at (member at value))
+          (setq value (delq function value))
+          (cond ((eq append 'replace)
+                 (setcar at function))
+                (append
+                 (push function (cdr at)))
+                (t
+                 (push (car at) (cdr at))
+                 (setcar at function))))
+      (setq value (delq function value)))
+    (unless (member function value)
+      (setq value (if append
+                      (append value (list function))
+                    (cons function value))))
+    (when (eq append 'replace)
+      (setq value (delq at value)))
+    (if local
+        (set hook value)
+      (set-default hook value))))
+
+(defun magit-run-section-hook (hook)
+  "Run HOOK, warning about invalid entries."
+  (--if-let (-remove #'functionp (symbol-value hook))
+      (progn
+        (message "`%s' contains entries that are no longer valid.
+%s\nUsing standard value instead.  Please re-configure hook variable."
+                 hook
+                 (mapconcat (lambda (sym) (format "  `%s'" sym)) it "\n"))
+        (sit-for 5)
+        (defvar magit--hook-standard-value nil)
+        (let ((magit--hook-standard-value
+               (eval (car (get hook 'standard-value)))))
+          (run-hooks 'magit---hook-standard-value)))
+    (run-hooks hook)))
+
+(provide 'magit-section)
+;;; magit-section.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-section.elc b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-section.elc
new file mode 100644
index 0000000000..9f412ab219
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-section.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-sequence.el b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-sequence.el
new file mode 100644
index 0000000000..8af8b25544
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-sequence.el
@@ -0,0 +1,901 @@
+;;; magit-sequence.el --- history manipulation in Magit  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2011-2018  The Magit Project Contributors
+;;
+;; You should have received a copy of the AUTHORS.md file which
+;; lists all contributors.  If not, see http://magit.vc/authors.
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; Magit 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, or (at your option)
+;; any later version.
+;;
+;; Magit 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 Magit.  If not, see http://www.gnu.org/licenses.
+
+;;; Commentary:
+
+;; Support for Git commands that replay commits and help the user make
+;; changes along the way.  Supports `cherry-pick', `revert', `rebase',
+;; `rebase--interactive' and `am'.
+
+;;; Code:
+
+(require 'magit)
+
+;;; Options
+;;;; Faces
+
+(defface magit-sequence-pick
+  '((t :inherit default))
+  "Face used in sequence sections."
+  :group 'magit-faces)
+
+(defface magit-sequence-stop
+  '((((class color) (background light)) :foreground "DarkOliveGreen4")
+    (((class color) (background dark))  :foreground "DarkSeaGreen2"))
+  "Face used in sequence sections."
+  :group 'magit-faces)
+
+(defface magit-sequence-part
+  '((((class color) (background light)) :foreground "Goldenrod4")
+    (((class color) (background dark))  :foreground "LightGoldenrod2"))
+  "Face used in sequence sections."
+  :group 'magit-faces)
+
+(defface magit-sequence-head
+  '((((class color) (background light)) :foreground "SkyBlue4")
+    (((class color) (background dark))  :foreground "LightSkyBlue1"))
+  "Face used in sequence sections."
+  :group 'magit-faces)
+
+(defface magit-sequence-drop
+  '((((class color) (background light)) :foreground "IndianRed")
+    (((class color) (background dark))  :foreground "IndianRed"))
+  "Face used in sequence sections."
+  :group 'magit-faces)
+
+(defface magit-sequence-done
+  '((t :inherit magit-hash))
+  "Face used in sequence sections."
+  :group 'magit-faces)
+
+(defface magit-sequence-onto
+  '((t :inherit magit-sequence-done))
+  "Face used in sequence sections."
+  :group 'magit-faces)
+
+(defface magit-sequence-exec
+  '((t :inherit magit-hash))
+  "Face used in sequence sections."
+  :group 'magit-faces)
+
+;;; Common
+
+;;;###autoload
+(defun magit-sequencer-continue ()
+  "Resume the current cherry-pick or revert sequence."
+  (interactive)
+  (if (magit-sequencer-in-progress-p)
+      (if (magit-anything-unstaged-p t)
+          (user-error "Cannot continue due to unstaged changes")
+        (magit-run-git-sequencer
+         (if (magit-revert-in-progress-p) "revert" "cherry-pick") "--continue"))
+    (user-error "No cherry-pick or revert in progress")))
+
+;;;###autoload
+(defun magit-sequencer-skip ()
+  "Skip the stopped at commit during a cherry-pick or revert sequence."
+  (interactive)
+  (if (magit-sequencer-in-progress-p)
+      (progn (magit-call-git "reset" "--hard")
+             (magit-sequencer-continue))
+    (user-error "No cherry-pick or revert in progress")))
+
+;;;###autoload
+(defun magit-sequencer-abort ()
+  "Abort the current cherry-pick or revert sequence.
+This discards all changes made since the sequence started."
+  (interactive)
+  (if (magit-sequencer-in-progress-p)
+      (magit-run-git-sequencer
+       (if (magit-revert-in-progress-p) "revert" "cherry-pick") "--abort")
+    (user-error "No cherry-pick or revert in progress")))
+
+(defun magit-sequencer-in-progress-p ()
+  (or (magit-cherry-pick-in-progress-p)
+      (magit-revert-in-progress-p)))
+
+;;; Cherry-Pick
+
+;;;###autoload (autoload 'magit-cherry-pick-popup "magit-sequence" nil t)
+(magit-define-popup magit-cherry-pick-popup
+  "Popup console for cherry-pick commands."
+  :man-page "git-cherry-pick"
+  :switches '((?s "Add Signed-off-by lines"            "--signoff")
+              (?e "Edit commit messages"               "--edit")
+              (?x "Reference cherry in commit message" "-x")
+              (?F "Attempt fast-forward"               "--ff"))
+  :options  '((?s "Strategy"                        "--strategy=")
+              (?m "Replay merge relative to parent" "--mainline="))
+  :actions  '("Apply here"
+              (?A "Pick"    magit-cherry-pick)
+              (?a "Apply"   magit-cherry-apply)
+              (?h "Harvest" magit-cherry-harvest)
+              "Apply elsewhere"
+              (?d "Donate"  magit-cherry-donate)
+              (?n "Spinout" magit-cherry-spinout)
+              (?s "Spinoff" magit-cherry-spinoff))
+  :sequence-actions '((?A "Continue" magit-sequencer-continue)
+                      (?s "Skip"     magit-sequencer-skip)
+                      (?a "Abort"    magit-sequencer-abort))
+  :sequence-predicate 'magit-sequencer-in-progress-p
+  :default-arguments '("--ff"))
+
+(defun magit-cherry-pick-read-args (prompt)
+  (list (or (nreverse (magit-region-values 'commit))
+            (magit-read-other-branch-or-commit prompt))
+        (magit-cherry-pick-arguments)))
+
+(defun magit--cherry-move-read-args (verb away fn)
+  (declare (indent defun))
+   (let ((commits (or (nreverse (magit-region-values 'commit))
+                      (list (funcall (if away
+                                         'magit-read-branch-or-commit
+                                       'magit-read-other-branch-or-commit)
+                                     (format "%s cherry" (capitalize verb))))))
+         (current (magit-get-current-branch)))
+     (unless current
+       (user-error "Cannot %s cherries while HEAD is detached" verb))
+     (let ((reachable (magit-rev-ancestor-p (car commits) current))
+           (msg "Cannot %s cherries that %s reachable from HEAD"))
+       (pcase (list away reachable)
+         (`(nil t) (user-error msg verb "are"))
+         (`(t nil) (user-error msg verb "are not"))))
+     `(,commits
+       ,@(funcall fn commits)
+       ,(magit-cherry-pick-arguments))))
+
+(defun magit--cherry-spinoff-read-args (verb)
+  (magit--cherry-move-read-args verb t
+    (lambda (commits)
+      (butlast (magit-branch-read-args
+                (format "Create branch from %s cherries" commits))))))
+
+;;;###autoload
+(defun magit-cherry-pick (commits &optional args)
+  "Copy COMMITS from another branch onto the current branch.
+Prompt for a commit, defaulting to the commit at point.  If
+the region selects multiple commits, then pick all of them,
+without prompting."
+  (interactive (magit-cherry-pick-read-args "Cherry-pick"))
+  (magit--cherry-pick commits args))
+
+;;;###autoload
+(defun magit-cherry-apply (commits &optional args)
+  "Apply the changes in COMMITS but do not commit them.
+Prompt for a commit, defaulting to the commit at point.  If
+the region selects multiple commits, then apply all of them,
+without prompting."
+  (interactive (magit-cherry-pick-read-args "Apply changes from commit"))
+  (magit--cherry-pick commits (cons "--no-commit" (remove "--ff" args))))
+
+;;;###autoload
+(defun magit-cherry-harvest (commits branch &optional args)
+  "Move COMMITS from another BRANCH onto the current branch.
+Remove the COMMITS from BRANCH and stay on the current branch.
+If a conflict occurs, then you have to fix that and finish the
+process manually."
+  (interactive
+   (magit--cherry-move-read-args "harvest" nil
+     (lambda (commits)
+       (list (let ((branches (magit-list-containing-branches (car commits))))
+               (pcase (length branches)
+                 (0 nil)
+                 (1 (car branches))
+                 (_ (magit-completing-read
+                     (format "Remove %s cherries from branch" (length commits))
+                     branches nil t))))))))
+  (magit--cherry-move commits branch (magit-get-current-branch) args nil t))
+
+;;;###autoload
+(defun magit-cherry-donate (commits branch &optional args)
+  "Move COMMITS from the current branch onto another existing BRANCH.
+Remove COMMITS from the current branch and stay on that branch.
+If a conflict occurs, then you have to fix that and finish the
+process manually."
+  (interactive
+   (magit--cherry-move-read-args "donate" t
+     (lambda (commits)
+       (list (magit-read-other-branch (format "Move %s cherries to branch"
+                                              (length commits)))))))
+  (magit--cherry-move commits (magit-get-current-branch) branch args))
+
+;;;###autoload
+(defun magit-cherry-spinout (commits branch start-point &optional args)
+  "Move COMMITS from the current branch onto a new BRANCH.
+Remove COMMITS from the current branch and stay on that branch.
+If a conflict occurs, then you have to fix that and finish the
+process manually."
+  (interactive (magit--cherry-spinoff-read-args "spinout"))
+  (magit--cherry-move commits (magit-get-current-branch) branch args
+                      start-point))
+
+;;;###autoload
+(defun magit-cherry-spinoff (commits branch start-point &optional args)
+  "Move COMMITS from the current branch onto a new BRANCH.
+Remove COMMITS from the current branch and checkout BRANCH.
+If a conflict occurs, then you have to fix that and finish
+the process manually."
+  (interactive (magit--cherry-spinoff-read-args "spinoff"))
+  (magit--cherry-move commits (magit-get-current-branch) branch args
+                      start-point t))
+
+(defun magit--cherry-move (commits src dst args
+                                   &optional start-point checkout-dst)
+  (let ((current (magit-get-current-branch)))
+    (unless (magit-branch-p dst)
+      (let ((magit-process-raise-error t))
+        (magit-call-git "branch" dst start-point))
+      (--when-let (magit-get-indirect-upstream-branch start-point)
+        (magit-call-git "branch" "--set-upstream-to" it dst)))
+    (unless (equal dst current)
+      (let ((magit-process-raise-error t))
+        (magit-call-git "checkout" dst)))
+    (if (not src) ; harvest only
+        (magit--cherry-pick commits args)
+      (let ((tip (car (last commits)))
+            (keep (concat (car commits) "^")))
+        (magit--cherry-pick commits args)
+        (set-process-sentinel
+         magit-this-process
+         (lambda (process event)
+           (when (memq (process-status process) '(exit signal))
+             (if (> (process-exit-status process) 0)
+                 (magit-process-sentinel process event)
+               (process-put process 'inhibit-refresh t)
+               (magit-process-sentinel process event)
+               (cond
+                ((magit-rev-equal tip src)
+                 (magit-call-git "update-ref"
+                                 "-m" (format "reset: moving to %s" keep)
+                                 (magit-ref-fullname src)
+                                 keep tip)
+                 (if (not checkout-dst)
+                     (magit-run-git "checkout" src)
+                   (magit-refresh)))
+                (t
+                 (magit-call-git "checkout" src)
+                 (let ((process-environment process-environment))
+                   (push (format "%s=perl -i -ne '/^pick (%s)/ or print'"
+                                 "GIT_SEQUENCE_EDITOR"
+                                 (mapconcat #'magit-rev-abbrev commits "|"))
+                         process-environment)
+                   (magit-run-git-sequencer "rebase" "-i" keep))
+                 (when checkout-dst
+                   (set-process-sentinel
+                    magit-this-process
+                    (lambda (process event)
+                      (when (memq (process-status process) '(exit signal))
+                        (if (> (process-exit-status process) 0)
+                            (magit-process-sentinel process event)
+                          (process-put process 'inhibit-refresh t)
+                          (magit-process-sentinel process event)
+                          (magit-run-git "checkout" dst))))))))))))))))
+
+(defun magit--cherry-pick (commits args &optional revert)
+  (let ((command (if revert "revert" "cherry-pick")))
+    (when (stringp commits)
+      (setq commits (if (string-match-p "\\.\\." commits)
+                        (split-string commits "\\.\\.")
+                      (list commits))))
+    (magit-run-git-sequencer
+     (if revert "revert" "cherry-pick")
+     (pcase-let ((`(,merge ,non-merge)
+                  (-separate 'magit-merge-commit-p commits)))
+       (cond
+        ((not merge)
+         (--remove (string-prefix-p "--mainline=" it) args))
+        (non-merge
+         (user-error "Cannot %s merge and non-merge commits at once"
+                     command))
+        ((--first (string-prefix-p "--mainline=" it) args)
+         args)
+        (t
+         (cons (format "--mainline=%s"
+                       (read-number "Replay merges relative to parent: "))
+               args))))
+     commits)))
+
+(defun magit-cherry-pick-in-progress-p ()
+  ;; .git/sequencer/todo does not exist when there is only one commit left.
+  (file-exists-p (magit-git-dir "CHERRY_PICK_HEAD")))
+
+;;; Revert
+
+;;;###autoload (autoload 'magit-revert-popup "magit-sequence" nil t)
+(magit-define-popup magit-revert-popup
+  "Popup console for revert commands."
+  :man-page "git-revert"
+  :switches '((?s "Add Signed-off-by lines"   "--signoff")
+              (?e "Edit commit message"       "--edit")
+              (?E "Don't edit commit message" "--no-edit"))
+  :options  '((?s "Strategy"       "--strategy=")
+              (?S "Sign using gpg" "--gpg-sign=" magit-read-gpg-secret-key)
+              (?m "Replay merge relative to parent" "--mainline="))
+  :actions  '((?V "Revert commit(s)" magit-revert)
+              (?v "Revert changes"   magit-revert-no-commit))
+  :sequence-actions '((?V "Continue" magit-sequencer-continue)
+                      (?s "Skip"     magit-sequencer-skip)
+                      (?a "Abort"    magit-sequencer-abort))
+  :sequence-predicate 'magit-sequencer-in-progress-p
+  :default-arguments '("--edit"))
+
+(defun magit-revert-read-args (prompt)
+  (list (or (magit-region-values 'commit)
+            (magit-read-branch-or-commit prompt))
+        (magit-revert-arguments)))
+
+;;;###autoload
+(defun magit-revert (commit &optional args)
+  "Revert COMMIT by creating a new commit.
+Prompt for a commit, defaulting to the commit at point.  If
+the region selects multiple commits, then revert all of them,
+without prompting."
+  (interactive (magit-revert-read-args "Revert commit"))
+  (magit--cherry-pick commit args t))
+
+;;;###autoload
+(defun magit-revert-no-commit (commit &optional args)
+  "Revert COMMIT by applying it in reverse to the worktree.
+Prompt for a commit, defaulting to the commit at point.  If
+the region selects multiple commits, then revert all of them,
+without prompting."
+  (interactive (magit-revert-read-args "Revert changes"))
+  (magit--cherry-pick commit (cons "--no-commit" args) t))
+
+(defun magit-revert-in-progress-p ()
+  ;; .git/sequencer/todo does not exist when there is only one commit left.
+  (file-exists-p (magit-git-dir "REVERT_HEAD")))
+
+;;; Patch
+
+;;;###autoload (autoload 'magit-am-popup "magit-sequence" nil t)
+(magit-define-popup magit-am-popup
+  "Popup console for mailbox commands."
+  :man-page "git-am"
+  :switches '((?3 "Fall back on 3way merge"           "--3way")
+              (?s "Add Signed-off-by lines"           "--signoff")
+              (?c "Remove text before scissors line"  "--scissors")
+              (?k "Inhibit removal of email cruft"    "--keep")
+              (?b "Limit removal of email cruft"      "--keep-non-patch")
+              (?d "Use author date as committer date"
+                  "--committer-date-is-author-date")
+              (?D "Use committer date as author date" "--ignore-date"))
+  :options  '((?p "Remove leading slashes from paths" "-p"
+                  magit-popup-read-number))
+  :actions  '((?m "Apply maildir"     magit-am-apply-maildir)
+              (?w "Apply patches"     magit-am-apply-patches)
+              (?a "Apply plain patch" magit-patch-apply-popup))
+  :default-arguments '("--3way")
+  :default-actions 'magit-am-apply-patches
+  :max-action-columns 1
+  :sequence-actions '((?w "Continue" magit-am-continue)
+                      (?s "Skip"     magit-am-skip)
+                      (?a "Abort"    magit-am-abort))
+  :sequence-predicate 'magit-am-in-progress-p)
+
+;;;###autoload
+(defun magit-am-apply-patches (&optional files args)
+  "Apply the patches FILES."
+  (interactive (list (or (magit-region-values 'file)
+                         (list (let ((default (magit-file-at-point)))
+                                 (read-file-name
+                                  (if default
+                                      (format "Apply patch (%s): " default)
+                                    "Apply patch: ")
+                                  nil default))))
+                     (magit-am-arguments)))
+  (magit-run-git-sequencer "am" args "--"
+                           (--map (magit-convert-filename-for-git
+                                   (expand-file-name it))
+                                  files)))
+
+;;;###autoload
+(defun magit-am-apply-maildir (&optional maildir args)
+  "Apply the patches from MAILDIR."
+  (interactive (list (read-file-name "Apply mbox or Maildir: ")
+                     (magit-am-arguments)))
+  (magit-run-git-sequencer "am" args (magit-convert-filename-for-git
+                                      (expand-file-name maildir))))
+
+;;;###autoload
+(defun magit-am-continue ()
+  "Resume the current patch applying sequence."
+  (interactive)
+  (if (magit-am-in-progress-p)
+      (if (magit-anything-unstaged-p t)
+          (error "Cannot continue due to unstaged changes")
+        (magit-run-git-sequencer "am" "--continue"))
+    (user-error "Not applying any patches")))
+
+;;;###autoload
+(defun magit-am-skip ()
+  "Skip the stopped at patch during a patch applying sequence."
+  (interactive)
+  (if (magit-am-in-progress-p)
+      (magit-run-git-sequencer "am" "--skip")
+    (user-error "Not applying any patches")))
+
+;;;###autoload
+(defun magit-am-abort ()
+  "Abort the current patch applying sequence.
+This discards all changes made since the sequence started."
+  (interactive)
+  (if (magit-am-in-progress-p)
+      (magit-run-git "am" "--abort")
+    (user-error "Not applying any patches")))
+
+(defun magit-am-in-progress-p ()
+  (file-exists-p (magit-git-dir "rebase-apply/applying")))
+
+;;; Rebase
+
+;;;###autoload (autoload 'magit-rebase-popup "magit-sequence" nil t)
+(magit-define-popup magit-rebase-popup
+  "Key menu for rebasing."
+  :man-page "git-rebase"
+  :switches '((?k "Keep empty commits"       "--keep-empty")
+              (?p "Preserve merges"          "--preserve-merges")
+              (?c "Lie about committer date" "--committer-date-is-author-date")
+              (?a "Autosquash"               "--autosquash")
+              (?A "Autostash"                "--autostash")
+              (?i "Interactive"              "--interactive")
+              (?h "Disable hooks"            "--no-verify"))
+  :actions  '((lambda ()
+                (concat (propertize "Rebase " 'face 'magit-popup-heading)
+                        (propertize (or (magit-get-current-branch) "HEAD")
+                                    'face 'magit-branch-local)
+                        (propertize " onto" 'face 'magit-popup-heading)))
+              (?p (lambda ()
+                    (--when-let (magit-get-push-branch) (concat it "\n")))
+                  magit-rebase-onto-pushremote)
+              (?u (lambda ()
+                    (--when-let (magit-get-upstream-branch) (concat it "\n")))
+                  magit-rebase-onto-upstream)
+              (?e "elsewhere"               magit-rebase)
+              "Rebase"
+              (?i "interactively"      magit-rebase-interactive)
+              (?m "to modify a commit" magit-rebase-edit-commit)
+              (?s "a subset"           magit-rebase-subset)
+              (?w "to reword a commit" magit-rebase-reword-commit) nil
+              (?k "to remove a commit" magit-rebase-remove-commit) nil
+              (?f "to autosquash"      magit-rebase-autosquash))
+  :sequence-actions '((?r "Continue" magit-rebase-continue)
+                      (?s "Skip"     magit-rebase-skip)
+                      (?e "Edit"     magit-rebase-edit)
+                      (?a "Abort"    magit-rebase-abort))
+  :sequence-predicate 'magit-rebase-in-progress-p
+  :max-action-columns 2)
+
+(defun magit-git-rebase (target args)
+  (magit-run-git-sequencer "rebase" target args))
+
+;;;###autoload
+(defun magit-rebase-onto-pushremote (args)
+  "Rebase the current branch onto `branch.<name>.pushRemote'.
+If that variable is unset, then rebase onto `remote.pushDefault'."
+  (interactive (list (magit-rebase-arguments)))
+  (--if-let (magit-get-current-branch)
+      (if-let ((remote (magit-get-push-remote it)))
+          (if (member remote (magit-list-remotes))
+              (magit-git-rebase (concat remote "/" it) args)
+            (user-error "Remote `%s' doesn't exist" remote))
+        (user-error "No push-remote is configured for %s" it))
+    (user-error "No branch is checked out")))
+
+;;;###autoload
+(defun magit-rebase-onto-upstream (args)
+  "Rebase the current branch onto its upstream branch."
+  (interactive (list (magit-rebase-arguments)))
+  (--if-let (magit-get-current-branch)
+      (if-let ((target (magit-get-upstream-branch it)))
+          (magit-git-rebase target args)
+        (user-error "No upstream is configured for %s" it))
+    (user-error "No branch is checked out")))
+
+;;;###autoload
+(defun magit-rebase (target args)
+  "Rebase the current branch onto a branch read in the minibuffer.
+All commits that are reachable from `HEAD' but not from the
+selected branch TARGET are being rebased."
+  (interactive (list (magit-read-other-branch-or-commit "Rebase onto")
+                     (magit-rebase-arguments)))
+  (message "Rebasing...")
+  (magit-git-rebase target args)
+  (message "Rebasing...done"))
+
+;;;###autoload
+(defun magit-rebase-subset (newbase start args)
+  "Rebase a subset of the current branch's history onto a new base.
+Rebase commits from START to `HEAD' onto NEWBASE.
+START has to be selected from a list of recent commits."
+  (interactive (list (magit-read-other-branch-or-commit
+                      "Rebase subset onto" nil
+                      (magit-get-upstream-branch))
+                     nil
+                     (magit-rebase-arguments)))
+  (if start
+      (progn (message "Rebasing...")
+             (magit-run-git-sequencer "rebase" "--onto" newbase start args)
+             (message "Rebasing...done"))
+    (magit-log-select
+      `(lambda (commit)
+         (magit-rebase-subset ,newbase (concat commit "^") (list ,@args)))
+      (concat "Type %p on a commit to rebase it "
+              "and commits above it onto " newbase ","))))
+
+(defun magit-rebase-interactive-1
+    (commit args message &optional editor delay-edit-confirm noassert confirm)
+  (declare (indent 2))
+  (when commit
+    (if (eq commit :merge-base)
+        (setq commit (--if-let (magit-get-upstream-branch)
+                         (magit-git-string "merge-base" it "HEAD")
+                       nil))
+      (unless (magit-rev-ancestor-p commit "HEAD")
+        (user-error "%s isn't an ancestor of HEAD" commit))
+      (if (magit-commit-parents commit)
+          (setq commit (concat commit "^"))
+        (setq args (cons "--root" args)))))
+  (when (and commit (not noassert))
+    (setq commit (magit-rebase-interactive-assert commit delay-edit-confirm)))
+  (if (and commit (not confirm))
+      (let ((process-environment process-environment))
+        (when editor
+          (push (concat "GIT_SEQUENCE_EDITOR=" editor) process-environment))
+        (magit-run-git-sequencer "rebase" "-i" args
+                                 (unless (member "--root" args) commit)))
+    (magit-log-select
+      `(lambda (commit)
+         (magit-rebase-interactive-1 commit (list ,@args)
+           ,message ,editor ,delay-edit-confirm ,noassert))
+      message)))
+
+(defvar magit--rebase-published-symbol nil)
+(defvar magit--rebase-public-edit-confirmed nil)
+
+(defun magit-rebase-interactive-assert (since &optional delay-edit-confirm)
+  (let* ((commit (if (string-suffix-p "^" since)
+                     ;; If SINCE is "REV^", then the user selected
+                     ;; "REV", which is the first commit that will
+                     ;; be replaced. (from^..to] <=> [from..to].
+                     (substring since 0 -1)
+                   ;; The "--root" argument is being used.
+                   since))
+         (branches (magit-list-publishing-branches commit)))
+    (setq magit--rebase-public-edit-confirmed
+          (delete (magit-toplevel) magit--rebase-public-edit-confirmed))
+    (when (and branches
+               (or (not delay-edit-confirm)
+                   ;; The user might have stopped at a published commit
+                   ;; merely to add new commits *after* it.  Try not to
+                   ;; ask users whether they really want to edit public
+                   ;; commits, when they don't actually intend to do so.
+                   (not (--all-p (magit-rev-equal it commit) branches))))
+      (let ((m1 "Some of these commits have already been published to ")
+            (m2 ".\nDo you really want to modify them"))
+        (magit-confirm (or magit--rebase-published-symbol 'rebase-published)
+          (concat m1 "%s" m2)
+          (concat m1 "%i public branches" m2)
+          nil branches))
+      (push (magit-toplevel) magit--rebase-public-edit-confirmed)))
+  (if (magit-git-lines "rev-list" "--merges" (concat since "..HEAD"))
+      (magit-read-char-case "Proceed despite merge in rebase range?  " nil
+        (?c "[c]ontinue" since)
+        (?s "[s]elect other" nil)
+        (?a "[a]bort" (user-error "Quit")))
+    since))
+
+;;;###autoload
+(defun magit-rebase-interactive (commit args)
+  "Start an interactive rebase sequence."
+  (interactive (list (magit-commit-at-point)
+                     (magit-rebase-arguments)))
+  (magit-rebase-interactive-1 commit args
+    "Type %p on a commit to rebase it and all commits above it,"
+    nil t))
+
+;;;###autoload
+(defun magit-rebase-autosquash (args)
+  "Combine squash and fixup commits with their intended targets."
+  (interactive (list (magit-rebase-arguments)))
+  (magit-rebase-interactive-1 :merge-base (cons "--autosquash" args)
+    "Type %p on a commit to squash into it and then rebase as necessary,"
+    "true" nil t))
+
+;;;###autoload
+(defun magit-rebase-edit-commit (commit args)
+  "Edit a single older commit using rebase."
+  (interactive (list (magit-commit-at-point)
+                     (magit-rebase-arguments)))
+  (magit-rebase-interactive-1 commit args
+    "Type %p on a commit to edit it,"
+    "perl -i -p -e '++$x if not $x and s/^pick/edit/'"
+    t))
+
+;;;###autoload
+(defun magit-rebase-reword-commit (commit args)
+  "Reword a single older commit using rebase."
+  (interactive (list (magit-commit-at-point)
+                     (magit-rebase-arguments)))
+  (magit-rebase-interactive-1 commit args
+    "Type %p on a commit to reword its message,"
+    "perl -i -p -e '++$x if not $x and s/^pick/reword/'"))
+
+;;;###autoload
+(defun magit-rebase-remove-commit (commit args)
+  "Remove a single older commit using rebase."
+  (interactive (list (magit-commit-at-point)
+                     (magit-rebase-arguments)))
+  (magit-rebase-interactive-1 commit args
+    "Type %p on a commit to remove it,"
+    "perl -i -p -e '++$x if not $x and s/^pick/# pick/'"
+    nil nil t))
+
+;;;###autoload
+(defun magit-rebase-continue (&optional noedit)
+  "Restart the current rebasing operation.
+In some cases this pops up a commit message buffer for you do
+edit.  With a prefix argument the old message is reused as-is."
+  (interactive "P")
+  (if (magit-rebase-in-progress-p)
+      (if (magit-anything-unstaged-p t)
+          (user-error "Cannot continue rebase with unstaged changes")
+        (when (and (magit-anything-staged-p)
+                   (file-exists-p (magit-git-dir "rebase-merge"))
+                   (not (member (magit-toplevel)
+                                magit--rebase-public-edit-confirmed)))
+          (magit-commit-amend-assert))
+        (if noedit
+            (let ((process-environment process-environment))
+              (push "GIT_EDITOR=true" process-environment)
+              (magit-run-git-async "rebase" "--continue")
+              (set-process-sentinel magit-this-process
+                                    #'magit-sequencer-process-sentinel)
+              magit-this-process)
+          (magit-run-git-sequencer "rebase" "--continue")))
+    (user-error "No rebase in progress")))
+
+;;;###autoload
+(defun magit-rebase-skip ()
+  "Skip the current commit and restart the current rebase operation."
+  (interactive)
+  (unless (magit-rebase-in-progress-p)
+    (user-error "No rebase in progress"))
+  (magit-run-git-sequencer "rebase" "--skip"))
+
+;;;###autoload
+(defun magit-rebase-edit ()
+  "Edit the todo list of the current rebase operation."
+  (interactive)
+  (unless (magit-rebase-in-progress-p)
+    (user-error "No rebase in progress"))
+  (magit-run-git-sequencer "rebase" "--edit-todo"))
+
+;;;###autoload
+(defun magit-rebase-abort ()
+  "Abort the current rebase operation, restoring the original branch."
+  (interactive)
+  (unless (magit-rebase-in-progress-p)
+    (user-error "No rebase in progress"))
+  (magit-confirm 'abort-rebase "Abort this rebase")
+  (magit-run-git "rebase" "--abort"))
+
+(defun magit-rebase-in-progress-p ()
+  "Return t if a rebase is in progress."
+  (or (file-exists-p (magit-git-dir "rebase-merge"))
+      (file-exists-p (magit-git-dir "rebase-apply/onto"))))
+
+;;; Sections
+
+(defun magit-insert-sequencer-sequence ()
+  "Insert section for the on-going cherry-pick or revert sequence.
+If no such sequence is in progress, do nothing."
+  (let ((picking (magit-cherry-pick-in-progress-p)))
+    (when (or picking (magit-revert-in-progress-p))
+      (magit-insert-section (sequence)
+        (magit-insert-heading (if picking "Cherry Picking" "Reverting"))
+        (when-let ((lines
+                    (cdr (magit-file-lines (magit-git-dir "sequencer/todo")))))
+          (dolist (line (nreverse lines))
+            (when (string-match
+                   "^\\(pick\\|revert\\) \\([^ ]+\\) \\(.*\\)$" line)
+              (magit-bind-match-strings (cmd hash msg) line
+                (magit-insert-section (commit hash)
+                  (insert (propertize cmd 'face 'magit-sequence-pick)
+                          " " (propertize hash 'face 'magit-hash)
+                          " " msg "\n"))))))
+        (magit-sequence-insert-sequence
+         (magit-file-line (magit-git-dir (if picking
+                                             "CHERRY_PICK_HEAD"
+                                           "REVERT_HEAD")))
+         (magit-file-line (magit-git-dir "sequencer/head")))
+        (insert "\n")))))
+
+(defun magit-insert-am-sequence ()
+  "Insert section for the on-going patch applying sequence.
+If no such sequence is in progress, do nothing."
+  (when (magit-am-in-progress-p)
+    (magit-insert-section (rebase-sequence)
+      (magit-insert-heading "Applying patches")
+      (let ((patches (nreverse (magit-rebase-patches)))
+            patch commit)
+        (while patches
+          (setq patch (pop patches))
+          (setq commit (magit-rev-verify-commit
+                        (cadr (split-string (magit-file-line patch)))))
+          (cond ((and commit patches)
+                 (magit-sequence-insert-commit
+                  "pick" commit 'magit-sequence-pick))
+                (patches
+                 (magit-sequence-insert-am-patch
+                  "pick" patch 'magit-sequence-pick))
+                (commit
+                 (magit-sequence-insert-sequence commit "ORIG_HEAD"))
+                (t
+                 (magit-sequence-insert-am-patch
+                  "stop" patch 'magit-sequence-stop)
+                 (magit-sequence-insert-sequence nil "ORIG_HEAD")))))
+      (insert ?\n))))
+
+(defun magit-sequence-insert-am-patch (type patch face)
+  (magit-insert-section (file patch)
+    (let ((title
+           (with-temp-buffer
+             (insert-file-contents patch nil nil 4096)
+             (unless (re-search-forward "^Subject: " nil t)
+               (goto-char (point-min)))
+             (buffer-substring (point) (line-end-position)))))
+      (insert (propertize type 'face face)
+              ?\s (propertize (file-name-nondirectory patch) 'face 'magit-hash)
+              ?\s title
+              ?\n))))
+
+(defun magit-insert-rebase-sequence ()
+  "Insert section for the on-going rebase sequence.
+If no such sequence is in progress, do nothing."
+  (when (magit-rebase-in-progress-p)
+    (let* ((interactive (file-directory-p (magit-git-dir "rebase-merge")))
+           (dir  (if interactive "rebase-merge/" "rebase-apply/"))
+           (name (-> (concat dir "head-name") magit-git-dir magit-file-line))
+           (onto (-> (concat dir "onto")      magit-git-dir magit-file-line))
+           (onto (or (magit-rev-name onto name)
+                     (magit-rev-name onto "refs/heads/*") onto))
+           (name (or (magit-rev-name name "refs/heads/*") name)))
+      (magit-insert-section (rebase-sequence)
+        (magit-insert-heading (format "Rebasing %s onto %s" name onto))
+        (if interactive
+            (magit-rebase-insert-merge-sequence onto)
+          (magit-rebase-insert-apply-sequence onto))
+        (insert ?\n)))))
+
+(defun magit-rebase-insert-merge-sequence (onto)
+  (let (exec)
+    (dolist (line (nreverse
+                   (magit-file-lines
+                    (magit-git-dir "rebase-merge/git-rebase-todo"))))
+      (cond ((string-prefix-p "exec" line)
+             (setq exec (substring line 5)))
+            ((string-match (format "^\\([^%c ]+\\) \\([^ ]+\\) .*$"
+                                   (string-to-char
+                                    (or (magit-get "core.commentChar") "#")))
+                           line)
+             (magit-bind-match-strings (action hash) line
+               (unless (equal action "exec")
+                 (magit-sequence-insert-commit
+                  action hash 'magit-sequence-pick exec)))
+             (setq exec nil)))))
+  (magit-sequence-insert-sequence
+   (magit-file-line (magit-git-dir "rebase-merge/stopped-sha"))
+   onto
+   (--when-let (magit-file-lines (magit-git-dir "rebase-merge/done"))
+     (cadr (split-string (car (last it)))))))
+
+(defun magit-rebase-insert-apply-sequence (onto)
+  (let ((rewritten
+         (--map (car (split-string it))
+                (magit-file-lines (magit-git-dir "rebase-apply/rewritten"))))
+        (stop (magit-file-line (magit-git-dir "rebase-apply/original-commit"))))
+    (dolist (patch (nreverse (cdr (magit-rebase-patches))))
+      (let ((hash (cadr (split-string (magit-file-line patch)))))
+        (unless (or (member hash rewritten)
+                    (equal hash stop))
+          (magit-sequence-insert-commit "pick" hash 'magit-sequence-pick)))))
+  (magit-sequence-insert-sequence
+   (magit-file-line (magit-git-dir "rebase-apply/original-commit"))
+   onto))
+
+(defun magit-rebase-patches ()
+  (directory-files (magit-git-dir "rebase-apply") t "^[0-9]\\{4\\}$"))
+
+(defun magit-sequence-insert-sequence (stop onto &optional orig)
+  (let ((head (magit-rev-parse "HEAD")) done)
+    (setq onto (if onto (magit-rev-parse onto) head))
+    (setq done (magit-git-lines "log" "--format=%H" (concat onto "..HEAD")))
+    (when (and stop (not (member stop done)))
+      (let ((id (magit-patch-id stop)))
+        (--if-let (--first (equal (magit-patch-id it) id) done)
+            (setq stop it)
+          (cond
+           ((--first (magit-rev-equal it stop) done)
+            ;; The commit's testament has been executed.
+            (magit-sequence-insert-commit "void" stop 'magit-sequence-drop))
+           ;; The faith of the commit is still undecided...
+           ((magit-anything-unmerged-p)
+            ;; ...and time travel isn't for the faint of heart.
+            (magit-sequence-insert-commit "join" stop 'magit-sequence-part))
+           ((magit-anything-modified-p t)
+            ;; ...and the dust hasn't settled yet...
+            (magit-sequence-insert-commit
+             (let* ((magit--refresh-cache nil)
+                    (staged   (magit-commit-tree "oO" nil "HEAD"))
+                    (unstaged (magit-commit-worktree "oO" "--reset")))
+               (cond
+                ;; ...but we could end up at the same tree just by committing.
+                ((or (magit-rev-equal staged   stop)
+                     (magit-rev-equal unstaged stop)) "goal")
+                ;; ...but the changes are still there, untainted.
+                ((or (equal (magit-patch-id staged)   id)
+                     (equal (magit-patch-id unstaged) id)) "same")
+                ;; ...and some changes are gone and/or others were added.
+                (t "work")))
+             stop 'magit-sequence-part))
+           ;; The commit is definitely gone...
+           ((--first (magit-rev-equal it stop) done)
+            ;; ...but all of its changes are still in effect.
+            (magit-sequence-insert-commit "poof" stop 'magit-sequence-drop))
+           (t
+            ;; ...and some changes are gone and/or other changes were added.
+            (magit-sequence-insert-commit "gone" stop 'magit-sequence-drop)))
+          (setq stop nil))))
+    (dolist (rev done)
+      (apply 'magit-sequence-insert-commit
+             (cond ((equal rev stop)
+                    ;; ...but its reincarnation lives on.
+                    ;; Or it didn't die in the first place.
+                    (list (if (and (equal rev head)
+                                   (equal (magit-patch-id rev)
+                                          (magit-patch-id orig)))
+                              "stop" ; We haven't done anything yet.
+                            "like")  ; There are new commits.
+                          rev (if (equal rev head)
+                                  'magit-sequence-head
+                                'magit-sequence-stop)))
+                   ((equal rev head)
+                    (list "done" rev 'magit-sequence-head))
+                   (t
+                    (list "done" rev 'magit-sequence-done)))))
+    (magit-sequence-insert-commit "onto" onto
+                                (if (equal onto head)
+                                    'magit-sequence-head
+                                  'magit-sequence-onto))))
+
+(defun magit-sequence-insert-commit (type hash face &optional exec)
+  (magit-insert-section (commit hash)
+    (magit-insert-heading
+      (concat (propertize type 'face face)    "\s"
+              (magit-format-rev-summary hash) "\n"))
+    (when exec
+      (insert (propertize "exec" 'face 'magit-sequence-onto) "\s" exec "\n"))))
+
+(provide 'magit-sequence)
+;;; magit-sequence.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-sequence.elc b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-sequence.elc
new file mode 100644
index 0000000000..28e7bc2773
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-sequence.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-stash.el b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-stash.el
new file mode 100644
index 0000000000..9f4ea5a3dc
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-stash.el
@@ -0,0 +1,492 @@
+;;; magit-stash.el --- stash support for Magit  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2008-2018  The Magit Project Contributors
+;;
+;; You should have received a copy of the AUTHORS.md file which
+;; lists all contributors.  If not, see http://magit.vc/authors.
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; Magit 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, or (at your option)
+;; any later version.
+;;
+;; Magit 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 Magit.  If not, see http://www.gnu.org/licenses.
+
+;;; Commentary:
+
+;; Support for Git stashes.
+
+;;; Code:
+
+(require 'magit)
+
+(defvar bookmark-make-record-function)
+
+;;; Options
+
+(defgroup magit-stash nil
+  "List stashes and show stash diffs."
+  :group 'magit-modes)
+
+;;;; Diff options
+
+(defcustom magit-stash-sections-hook
+  '(magit-insert-stash-notes
+    magit-insert-stash-worktree
+    magit-insert-stash-index
+    magit-insert-stash-untracked)
+  "Hook run to insert sections into stash diff buffers."
+  :package-version '(magit . "2.1.0")
+  :group 'magit-stash
+  :type 'hook)
+
+;;;; Log options
+
+(defcustom magit-stashes-margin
+  (list (nth 0 magit-log-margin)
+        (nth 1 magit-log-margin)
+        'magit-log-margin-width nil
+        (nth 4 magit-log-margin))
+  "Format of the margin in `magit-stashes-mode' buffers.
+
+The value has the form (INIT STYLE WIDTH AUTHOR AUTHOR-WIDTH).
+
+If INIT is non-nil, then the margin is shown initially.
+STYLE controls how to format the committer date.  It can be one
+  of `age' (to show the age of the commit), `age-abbreviated' (to
+  abbreviate the time unit to a character), or a string (suitable
+  for `format-time-string') to show the actual date.
+WIDTH controls the width of the margin.  This exists for forward
+  compatibility and currently the value should not be changed.
+AUTHOR controls whether the name of the author is also shown by
+  default.
+AUTHOR-WIDTH has to be an integer.  When the name of the author
+  is shown, then this specifies how much space is used to do so."
+  :package-version '(magit . "2.9.0")
+  :group 'magit-stash
+  :group 'magit-margin
+  :type magit-log-margin--custom-type
+  :initialize 'magit-custom-initialize-reset
+  :set-after '(magit-log-margin)
+  :set (apply-partially #'magit-margin-set-variable 'magit-stashes-mode))
+
+;;; Commands
+
+;;;###autoload (autoload 'magit-stash-popup "magit-stash" nil t)
+(magit-define-popup magit-stash-popup
+  "Popup console for stash commands."
+  :man-page "git-stash"
+  :switches '((?u "Also save untracked files" "--include-untracked")
+              (?a "Also save untracked and ignored files" "--all"))
+  :actions  '((?z "Save"               magit-stash)
+              (?Z "Snapshot"           magit-snapshot)
+              (?p "Pop"                magit-stash-pop)
+              (?i "Save index"         magit-stash-index)
+              (?I "Snapshot index"     magit-snapshot-index)
+              (?a "Apply"              magit-stash-apply)
+              (?w "Save worktree"      magit-stash-worktree)
+              (?W "Snapshot worktree"  magit-snapshot-worktree)
+              (?l "List"               magit-stash-list)
+              (?x "Save keeping index" magit-stash-keep-index)
+              (?r "Snapshot to wipref" magit-wip-commit)
+              (?v "Show"               magit-stash-show)
+              (?b "Branch"             magit-stash-branch)
+              (?k "Drop"               magit-stash-drop) nil
+              (?B "Branch here"        magit-stash-branch-here) nil nil
+              (?f "Format patch"       magit-stash-format-patch))
+  :default-action 'magit-stash
+  :max-action-columns 3)
+
+;;;###autoload
+(defun magit-stash (message &optional include-untracked)
+  "Create a stash of the index and working tree.
+Untracked files are included according to popup arguments.
+One prefix argument is equivalent to `--include-untracked'
+while two prefix arguments are equivalent to `--all'."
+  (interactive (magit-stash-read-args))
+  (magit-stash-save message t t include-untracked t))
+
+;;;###autoload
+(defun magit-stash-index (message)
+  "Create a stash of the index only.
+Unstaged and untracked changes are not stashed.  The stashed
+changes are applied in reverse to both the index and the
+worktree.  This command can fail when the worktree is not clean.
+Applying the resulting stash has the inverse effect."
+  (interactive (list (magit-stash-read-message)))
+  (magit-stash-save message t nil nil t 'worktree))
+
+;;;###autoload
+(defun magit-stash-worktree (message &optional include-untracked)
+  "Create a stash of unstaged changes in the working tree.
+Untracked files are included according to popup arguments.
+One prefix argument is equivalent to `--include-untracked'
+while two prefix arguments are equivalent to `--all'."
+  (interactive (magit-stash-read-args))
+  (magit-stash-save message nil t include-untracked t 'index))
+
+;;;###autoload
+(defun magit-stash-keep-index (message &optional include-untracked)
+  "Create a stash of the index and working tree, keeping index intact.
+Untracked files are included according to popup arguments.
+One prefix argument is equivalent to `--include-untracked'
+while two prefix arguments are equivalent to `--all'."
+  (interactive (magit-stash-read-args))
+  (magit-stash-save message t t include-untracked t 'index))
+
+(defun magit-stash-read-args ()
+  (list (magit-stash-read-message)
+        (magit-stash-read-untracked)))
+
+(defun magit-stash-read-untracked ()
+  (let ((prefix (prefix-numeric-value current-prefix-arg))
+        (args   (magit-stash-arguments)))
+    (cond ((or (= prefix 16) (member "--all" args)) 'all)
+          ((or (= prefix  4) (member "--include-untracked" args)) t))))
+
+(defun magit-stash-read-message ()
+  (let* ((default (format "On %s: "
+                          (or (magit-get-current-branch) "(no branch)")))
+         (input (magit-read-string "Stash message" default)))
+    (if (equal input default)
+        (concat default (magit-rev-format "%h %s"))
+      input)))
+
+;;;###autoload
+(defun magit-snapshot (&optional include-untracked)
+  "Create a snapshot of the index and working tree.
+Untracked files are included according to popup arguments.
+One prefix argument is equivalent to `--include-untracked'
+while two prefix arguments are equivalent to `--all'."
+  (interactive (magit-snapshot-read-args))
+  (magit-snapshot-save t t include-untracked t))
+
+;;;###autoload
+(defun magit-snapshot-index ()
+  "Create a snapshot of the index only.
+Unstaged and untracked changes are not stashed."
+  (interactive)
+  (magit-snapshot-save t nil nil t))
+
+;;;###autoload
+(defun magit-snapshot-worktree (&optional include-untracked)
+  "Create a snapshot of unstaged changes in the working tree.
+Untracked files are included according to popup arguments.
+One prefix argument is equivalent to `--include-untracked'
+while two prefix arguments are equivalent to `--all'."
+  (interactive (magit-snapshot-read-args))
+  (magit-snapshot-save nil t include-untracked t))
+
+(defun magit-snapshot-read-args ()
+  (list (magit-stash-read-untracked)))
+
+(defun magit-snapshot-save (index worktree untracked &optional refresh)
+  (magit-stash-save (concat "WIP on " (magit-stash-summary))
+                    index worktree untracked refresh t))
+
+;;;###autoload
+(defun magit-stash-apply (stash)
+  "Apply a stash to the working tree.
+Try to preserve the stash index.  If that fails because there
+are staged changes, apply without preserving the stash index."
+  (interactive (list (magit-read-stash "Apply stash")))
+  (if (= (magit-call-git "stash" "apply" "--index" stash) 0)
+      (magit-refresh)
+    (magit-run-git "stash" "apply" stash)))
+
+(defun magit-stash-pop (stash)
+  "Apply a stash to the working tree and remove it from stash list.
+Try to preserve the stash index.  If that fails because there
+are staged changes, apply without preserving the stash index
+and forgo removing the stash."
+  (interactive (list (magit-read-stash "Pop stash")))
+  (if (= (magit-call-git "stash" "apply" "--index" stash) 0)
+      (magit-stash-drop stash)
+    (magit-run-git "stash" "apply" stash)))
+
+;;;###autoload
+(defun magit-stash-drop (stash)
+  "Remove a stash from the stash list.
+When the region is active offer to drop all contained stashes."
+  (interactive (list (--if-let (magit-region-values 'stash)
+                         (magit-confirm t nil "Drop %i stashes" nil it)
+                       (magit-read-stash "Drop stash"))))
+  (dolist (stash (if (listp stash)
+                     (nreverse (prog1 stash (setq stash (car stash))))
+                   (list stash)))
+    (message "Deleted refs/%s (was %s)" stash
+             (magit-rev-parse "--short" stash))
+    (magit-call-git "rev-parse" stash)
+    (magit-call-git "reflog" "delete" "--updateref" "--rewrite" stash))
+  (when-let ((ref (and (string-match "\\(.+\\)@{[0-9]+}$" stash)
+                       (match-string 1 stash))))
+    (unless (string-match "^refs/" ref)
+      (setq ref (concat "refs/" ref)))
+    (unless (magit-rev-verify (concat ref "@{0}"))
+      (magit-run-git "update-ref" "-d" ref)))
+  (magit-refresh))
+
+;;;###autoload
+(defun magit-stash-clear (ref)
+  "Remove all stashes saved in REF's reflog by deleting REF."
+  (interactive (let ((ref (or (magit-section-when 'stashes) "refs/stash")))
+                 (magit-confirm t (format "Drop all stashes in %s" ref))
+                 (list ref)))
+  (magit-run-git "update-ref" "-d" ref))
+
+;;;###autoload
+(defun magit-stash-branch (stash branch)
+  "Create and checkout a new BRANCH from STASH."
+  (interactive (list (magit-read-stash "Branch stash")
+                     (magit-read-string-ns "Branch name")))
+  (magit-run-git "stash" "branch" branch stash))
+
+;;;###autoload
+(defun magit-stash-branch-here (stash branch)
+  "Create and checkout a new BRANCH and apply STASH.
+The branch is created using `magit-branch', using the current
+branch or `HEAD' as the string-point."
+  (interactive (list (magit-read-stash "Branch stash")
+                     (magit-read-string-ns "Branch name")))
+  (let ((inhibit-magit-refresh t))
+    (magit-branch branch (or (magit-get-current-branch) "HEAD")))
+  (magit-stash-apply stash))
+
+;;;###autoload
+(defun magit-stash-format-patch (stash)
+  "Create a patch from STASH"
+  (interactive (list (magit-read-stash "Create patch from stash")))
+  (with-temp-file (magit-rev-format "0001-%f.patch" stash)
+    (magit-git-insert "stash" "show" "-p" stash))
+  (magit-refresh))
+
+;;; Plumbing
+
+(defun magit-stash-save (message index worktree untracked
+                                 &optional refresh keep noerror ref)
+  (if (or (and index     (magit-staged-files t))
+          (and worktree  (magit-unstaged-files t))
+          (and untracked (magit-untracked-files (eq untracked 'all))))
+      (magit-with-toplevel
+        (magit-stash-store message (or ref "refs/stash")
+                           (magit-stash-create message index worktree untracked))
+        (if (eq keep 'worktree)
+            (with-temp-buffer
+              (magit-git-insert "diff" "--cached")
+              (magit-run-git-with-input
+               "apply" "--reverse" "--cached" "--ignore-space-change" "-")
+              (magit-run-git-with-input
+               "apply" "--reverse" "--ignore-space-change" "-"))
+          (unless (eq keep t)
+            (if (eq keep 'index)
+                (magit-call-git "checkout" "--" ".")
+              (magit-call-git "reset" "--hard" "HEAD"))
+            (when untracked
+              (magit-call-git "clean" "--force" "-d"
+                              (and (eq untracked 'all) "-x")))))
+        (when refresh
+          (magit-refresh)))
+    (unless noerror
+      (user-error "No %s changes to save" (cond ((not index)  "unstaged")
+                                                ((not worktree) "staged")
+                                                (t "local"))))))
+
+(defun magit-stash-store (message ref commit)
+  (magit-update-ref ref message commit t))
+
+(defun magit-stash-create (message index worktree untracked)
+  (unless (magit-rev-parse "--verify" "HEAD")
+    (error "You do not have the initial commit yet"))
+  (let ((magit-git-global-arguments (nconc (list "-c" "commit.gpgsign=false")
+                                           magit-git-global-arguments))
+        (default-directory (magit-toplevel))
+        (summary (magit-stash-summary))
+        (head "HEAD"))
+    (when (and worktree (not index))
+      (setq head (or (magit-commit-tree "pre-stash index" nil "HEAD")
+                     (error "Cannot save the current index state"))))
+    (or (setq index (magit-commit-tree (concat "index on " summary) nil head))
+        (error "Cannot save the current index state"))
+    (and untracked
+         (setq untracked (magit-untracked-files (eq untracked 'all)))
+         (setq untracked (magit-with-temp-index nil nil
+                           (or (and (magit-update-files untracked)
+                                    (magit-commit-tree
+                                     (concat "untracked files on " summary)))
+                               (error "Cannot save the untracked files")))))
+    (magit-with-temp-index index "-m"
+      (when worktree
+        (or (magit-update-files (magit-git-items "diff" "-z" "--name-only" head))
+            (error "Cannot save the current worktree state")))
+      (or (magit-commit-tree message nil head index untracked)
+          (error "Cannot save the current worktree state")))))
+
+(defun magit-stash-summary ()
+  (concat (or (magit-get-current-branch) "(no branch)")
+          ": " (magit-rev-format "%h %s")))
+
+;;; Sections
+
+(defvar magit-stashes-section-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map [remap magit-delete-thing] 'magit-stash-clear)
+    map)
+  "Keymap for `stashes' section.")
+
+(defvar magit-stash-section-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map [remap magit-visit-thing]  'magit-stash-show)
+    (define-key map [remap magit-delete-thing] 'magit-stash-drop)
+    (define-key map "a"  'magit-stash-apply)
+    (define-key map "A"  'magit-stash-pop)
+    map)
+  "Keymap for `stash' sections.")
+
+(magit-define-section-jumper magit-jump-to-stashes
+  "Stashes" stashes "refs/stash")
+
+(cl-defun magit-insert-stashes (&optional (ref   "refs/stash")
+                                          (heading "Stashes:"))
+  "Insert `stashes' section showing reflog for \"refs/stash\".
+If optional REF is non-nil, show reflog for that instead.
+If optional HEADING is non-nil, use that as section heading
+instead of \"Stashes:\"."
+  (let ((verified (magit-rev-verify ref))
+        (autostash
+         (and (magit-rebase-in-progress-p)
+              (magit-file-line
+               (magit-git-dir
+                (-> (if (file-directory-p (magit-git-dir "rebase-merge"))
+                        "rebase-merge/autostash"
+                      "rebase-apply/autostash")))))))
+    (when (or autostash verified)
+      (magit-insert-section (stashes ref)
+        (magit-insert-heading heading)
+        (when autostash
+          (pcase-let ((`(,author ,date ,msg)
+                       (split-string
+                        (car (magit-git-lines
+                              "show" "-q" "--format=%aN%x00%at%x00%s"
+                              autostash))
+                        "\0")))
+            (magit-insert-section (stash autostash)
+              (insert (propertize "AUTOSTASH" 'face 'magit-hash))
+              (insert " " msg "\n")
+              (save-excursion
+                (backward-char)
+                (magit-log-format-margin author date)))))
+        (if verified
+            (magit-git-wash (apply-partially 'magit-log-wash-log 'stash)
+              "reflog" "--format=%gd%x00%aN%x00%at%x00%gs" ref)
+          (insert ?\n)
+          (save-excursion
+            (backward-char)
+            (magit-make-margin-overlay)))))))
+
+;;; List Stashes
+
+;;;###autoload
+(defun magit-stash-list ()
+  "List all stashes in a buffer."
+  (interactive)
+  (magit-mode-setup #'magit-stashes-mode "refs/stash"))
+
+(define-derived-mode magit-stashes-mode magit-reflog-mode "Magit Stashes"
+  "Mode for looking at lists of stashes."
+  :group 'magit-log
+  (hack-dir-local-variables-non-file-buffer)
+  (setq-local bookmark-make-record-function
+              #'magit-bookmark--stashes-make-record))
+
+(cl-defun magit-stashes-refresh-buffer (ref)
+  (magit-insert-section (stashesbuf)
+    (magit-insert-heading (if (equal ref "refs/stash")
+                              "Stashes:"
+                            (format "Stashes [%s]:" ref)))
+    (magit-git-wash (apply-partially 'magit-log-wash-log 'stash)
+      "reflog" "--format=%gd%x00%aN%x00%at%x00%gs" ref)))
+
+;;; Show Stash
+
+;;;###autoload
+(defun magit-stash-show (stash &optional args files)
+  "Show all diffs of a stash in a buffer."
+  (interactive (cons (or (and (not current-prefix-arg)
+                              (magit-stash-at-point))
+                         (magit-read-stash "Show stash"))
+                     (pcase-let ((`(,args ,files) (magit-diff-arguments)))
+                       (list (delete "--stat" args) files))))
+  (magit-mode-setup #'magit-stash-mode stash nil args files))
+
+(define-derived-mode magit-stash-mode magit-diff-mode "Magit Stash"
+  "Mode for looking at individual stashes."
+  :group 'magit-diff
+  (hack-dir-local-variables-non-file-buffer)
+  (setq-local bookmark-make-record-function
+              #'magit-bookmark--stash-make-record))
+
+(defun magit-stash-refresh-buffer (stash _const _args _files)
+  (magit-set-header-line-format
+   (concat (propertize (capitalize stash) 'face 'magit-section-heading)
+           " "
+           (magit-rev-format "%s" stash)))
+  (setq magit-buffer-revision-hash (magit-rev-parse stash))
+  (magit-insert-section (stash)
+    (run-hooks 'magit-stash-sections-hook)))
+
+(defun magit-stash-insert-section (commit range message &optional files)
+  (magit-insert-section (commit commit)
+    (magit-insert-heading message)
+    (magit-git-wash #'magit-diff-wash-diffs
+      "diff" range "-p" "--no-prefix"
+      (nth 2 magit-refresh-args)
+      "--" (or files (nth 3 magit-refresh-args)))))
+
+(defun magit-insert-stash-notes ()
+  "Insert section showing notes for a stash.
+This shows the notes for stash@{N} but not for the other commits
+that make up the stash."
+  (magit-insert-section section (note)
+    (magit-insert-heading "Notes")
+    (magit-git-insert "notes" "show" (car magit-refresh-args))
+    (if (= (point)
+           (oref section content))
+        (magit-cancel-section)
+      (insert "\n"))))
+
+(defun magit-insert-stash-index ()
+  "Insert section showing staged changes of the stash."
+  (let ((stash (car magit-refresh-args)))
+    (magit-stash-insert-section (format "%s^2" stash)
+                                (format "%s^..%s^2" stash stash)
+                                "Staged")))
+
+(defun magit-insert-stash-worktree ()
+  "Insert section showing unstaged changes of the stash."
+  (let ((stash (car magit-refresh-args)))
+    (magit-stash-insert-section stash
+                                (format "%s^2..%s" stash stash)
+                                "Unstaged")))
+
+(defun magit-insert-stash-untracked ()
+  "Insert section showing the untracked files commit of the stash."
+  (let ((stash (car magit-refresh-args))
+        (rev   (concat (car magit-refresh-args) "^3")))
+    (when (magit-rev-verify rev)
+      (magit-stash-insert-section (format "%s^3" stash)
+                                  (format "%s^..%s^3" stash stash)
+                                  "Untracked files"
+                                  (magit-git-items "ls-tree" "-z" "--name-only"
+                                                   "-r" "--full-tree" rev)))))
+
+(provide 'magit-stash)
+;;; magit-stash.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-stash.elc b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-stash.elc
new file mode 100644
index 0000000000..b8a2df115c
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-stash.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-status.el b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-status.el
new file mode 100644
index 0000000000..85be23b473
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-status.el
@@ -0,0 +1,567 @@
+;;; magit-status.el --- the grand overview  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2010-2018  The Magit Project Contributors
+;;
+;; You should have received a copy of the AUTHORS.md file which
+;; lists all contributors.  If not, see http://magit.vc/authors.
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; Magit 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, or (at your option)
+;; any later version.
+;;
+;; Magit 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 Magit.  If not, see http://www.gnu.org/licenses.
+
+;;; Commentary:
+
+;; This library implements the status buffer.
+
+;;; Code:
+
+(require 'magit)
+
+(eval-when-compile (require 'subr-x))
+
+(defvar bookmark-make-record-function)
+
+;;; Options
+
+(defgroup magit-status nil
+  "Inspect and manipulate Git repositories."
+  :link '(info-link "(magit)Status Buffer")
+  :group 'magit-modes)
+
+(defcustom magit-status-mode-hook nil
+  "Hook run after entering Magit-Status mode."
+  :group 'magit-status
+  :type 'hook)
+
+(defcustom magit-status-headers-hook
+  '(magit-insert-error-header
+    magit-insert-diff-filter-header
+    magit-insert-head-branch-header
+    magit-insert-upstream-branch-header
+    magit-insert-push-branch-header
+    magit-insert-tags-header)
+  "Hook run to insert headers into the status buffer.
+
+This hook is run by `magit-insert-status-headers', which in turn
+has to be a member of `magit-status-sections-hook' to be used at
+all."
+  :package-version '(magit . "2.1.0")
+  :group 'magit-status
+  :type 'hook
+  :options '(magit-insert-error-header
+             magit-insert-diff-filter-header
+             magit-insert-repo-header
+             magit-insert-remote-header
+             magit-insert-head-branch-header
+             magit-insert-upstream-branch-header
+             magit-insert-push-branch-header
+             magit-insert-tags-header))
+
+(defcustom magit-status-sections-hook
+  '(magit-insert-status-headers
+    magit-insert-merge-log
+    magit-insert-rebase-sequence
+    magit-insert-am-sequence
+    magit-insert-sequencer-sequence
+    magit-insert-bisect-output
+    magit-insert-bisect-rest
+    magit-insert-bisect-log
+    magit-insert-untracked-files
+    magit-insert-unstaged-changes
+    magit-insert-staged-changes
+    magit-insert-stashes
+    magit-insert-unpushed-to-pushremote
+    magit-insert-unpushed-to-upstream-or-recent
+    magit-insert-unpulled-from-pushremote
+    magit-insert-unpulled-from-upstream)
+  "Hook run to insert sections into a status buffer."
+  :package-version '(magit . "2.12.0")
+  :group 'magit-status
+  :type 'hook)
+
+(defcustom magit-status-show-hashes-in-headers nil
+  "Whether headers in the status buffer show hashes.
+The functions which respect this option are
+`magit-insert-head-branch-header',
+`magit-insert-upstream-branch-header', and
+`magit-insert-push-branch-header'."
+  :package-version '(magit . "2.4.0")
+  :group 'magit-status
+  :type 'boolean)
+
+(defcustom magit-status-margin
+  (list nil
+        (nth 1 magit-log-margin)
+        'magit-log-margin-width nil
+        (nth 4 magit-log-margin))
+  "Format of the margin in `magit-status-mode' buffers.
+
+The value has the form (INIT STYLE WIDTH AUTHOR AUTHOR-WIDTH).
+
+If INIT is non-nil, then the margin is shown initially.
+STYLE controls how to format the committer date.  It can be one
+  of `age' (to show the age of the commit), `age-abbreviated' (to
+  abbreviate the time unit to a character), or a string (suitable
+  for `format-time-string') to show the actual date.
+WIDTH controls the width of the margin.  This exists for forward
+  compatibility and currently the value should not be changed.
+AUTHOR controls whether the name of the author is also shown by
+  default.
+AUTHOR-WIDTH has to be an integer.  When the name of the author
+  is shown, then this specifies how much space is used to do so."
+  :package-version '(magit . "2.9.0")
+  :group 'magit-status
+  :group 'magit-margin
+  :type magit-log-margin--custom-type
+  :initialize 'magit-custom-initialize-reset
+  :set-after '(magit-log-margin)
+  :set (apply-partially #'magit-margin-set-variable 'magit-status-mode))
+
+;;; Commands
+
+;;;###autoload
+(defun magit-init (directory)
+  "Initialize a Git repository, then show its status.
+
+If the directory is below an existing repository, then the user
+has to confirm that a new one should be created inside.  If the
+directory is the root of the existing repository, then the user
+has to confirm that it should be reinitialized.
+
+Non-interactively DIRECTORY is (re-)initialized unconditionally."
+  (interactive
+   (let ((directory (file-name-as-directory
+                     (expand-file-name
+                      (read-directory-name "Create repository in: ")))))
+     (when-let ((toplevel (magit-toplevel directory)))
+       (setq toplevel (expand-file-name toplevel))
+       (unless (y-or-n-p (if (file-equal-p toplevel directory)
+                             (format "Reinitialize existing repository %s? "
+                                     directory)
+                           (format "%s is a repository.  Create another in %s? "
+                                   toplevel directory)))
+         (user-error "Abort")))
+     (list directory)))
+  ;; `git init' does not understand the meaning of "~"!
+  (magit-call-git "init" (magit-convert-filename-for-git
+                          (expand-file-name directory)))
+  (magit-status-internal directory))
+
+;;;###autoload
+(defun magit-status (&optional directory cache)
+  "Show the status of the current Git repository in a buffer.
+With a prefix argument prompt for a repository to be shown.
+With two prefix arguments prompt for an arbitrary directory.
+If that directory isn't the root of an existing repository,
+then offer to initialize it as a new repository."
+  (interactive
+   (let ((magit--refresh-cache (list (cons 0 0))))
+     (list (and (or current-prefix-arg (not (magit-toplevel)))
+                (magit-read-repository
+                 (>= (prefix-numeric-value current-prefix-arg) 16)))
+           magit--refresh-cache)))
+  (let ((magit--refresh-cache (or cache (list (cons 0 0)))))
+    (if directory
+        (let ((toplevel (magit-toplevel directory)))
+          (setq directory (file-name-as-directory
+                           (expand-file-name directory)))
+          (if (and toplevel (file-equal-p directory toplevel))
+              (magit-status-internal directory)
+            (when (y-or-n-p
+                   (if toplevel
+                       (format "%s is a repository.  Create another in %s? "
+                               toplevel directory)
+                     (format "Create repository in %s? " directory)))
+              ;; Creating a new repository will invalidate cached
+              ;; values.
+              (setq magit--refresh-cache nil)
+              (magit-init directory))))
+      (magit-status-internal default-directory))))
+
+(put 'magit-status 'interactive-only 'magit-status-internal)
+
+(defalias 'magit 'magit-status
+  "An alias for `magit-status' for better discoverability.
+
+Instead of invoking this alias for `magit-status' using
+\"M-x magit RET\", you should bind a key to `magit-status'
+and read the info node `(magit)Getting Started', which
+also contains other useful hints.")
+
+;;;###autoload
+(defun magit-status-internal (directory)
+  (magit--tramp-asserts directory)
+  (let ((default-directory directory))
+    (magit-mode-setup #'magit-status-mode)))
+
+(defvar magit--remotes-using-recent-git nil)
+
+(defun magit--tramp-asserts (directory)
+  (when-let ((remote (file-remote-p directory)))
+    (unless (member remote magit--remotes-using-recent-git)
+      (if-let ((version (let ((default-directory directory))
+                          (magit-git-version))))
+          (if (version<= magit--minimal-git version)
+              (push version magit--remotes-using-recent-git)
+            (display-warning 'magit (format "\
+Magit requires Git >= %s, but on %s the version is %s.
+
+If multiple Git versions are installed on the host, then the
+problem might be that TRAMP uses the wrong executable.
+
+First check the value of `magit-git-executable'.  Its value is
+used when running git locally as well as when running it on a
+remote host.  The default value is \"git\", except on Windows
+where an absolute path is used for performance reasons.
+
+If the value already is just \"git\" but TRAMP never-the-less
+doesn't use the correct executable, then consult the info node
+`(tramp)Remote programs'.\n" magit--minimal-git remote version) :error))
+        (display-warning 'magit (format "\
+Magit cannot find Git on %s.
+
+First check the value of `magit-git-executable'.  Its value is
+used when running git locally as well as when running it on a
+remote host.  The default value is \"git\", except on Windows
+where an absolute path is used for performance reasons.
+
+If the value already is just \"git\" but TRAMP never-the-less
+doesn't find the executable, then consult the info node
+`(tramp)Remote programs'.\n" remote) :error)))))
+
+;;; Mode
+
+(defvar magit-status-mode-map
+  (let ((map (make-sparse-keymap)))
+    (set-keymap-parent map magit-mode-map)
+    (define-key map "jz" 'magit-jump-to-stashes)
+    (define-key map "jt" 'magit-jump-to-tracked)
+    (define-key map "jn" 'magit-jump-to-untracked)
+    (define-key map "ju" 'magit-jump-to-unstaged)
+    (define-key map "js" 'magit-jump-to-staged)
+    (define-key map "jfu" 'magit-jump-to-unpulled-from-upstream)
+    (define-key map "jfp" 'magit-jump-to-unpulled-from-pushremote)
+    (define-key map "jpu" 'magit-jump-to-unpushed-to-upstream)
+    (define-key map "jpp" 'magit-jump-to-unpushed-to-pushremote)
+    (define-key map [remap dired-jump] 'magit-dired-jump)
+    map)
+  "Keymap for `magit-status-mode'.")
+
+(define-derived-mode magit-status-mode magit-mode "Magit"
+  "Mode for looking at Git status.
+
+This mode is documented in info node `(magit)Status Buffer'.
+
+\\<magit-mode-map>\
+Type \\[magit-refresh] to refresh the current buffer.
+Type \\[magit-section-toggle] to expand or hide the section at point.
+Type \\[magit-visit-thing] to visit the change or commit at point.
+
+Type \\[magit-dispatch-popup] to see available prefix popups.
+
+Staging and applying changes is documented in info node
+`(magit)Staging and Unstaging' and info node `(magit)Applying'.
+
+\\<magit-hunk-section-map>Type \
+\\[magit-apply] to apply the change at point, \
+\\[magit-stage] to stage,
+\\[magit-unstage] to unstage, \
+\\[magit-discard] to discard, or \
+\\[magit-reverse] to reverse it.
+
+\\<magit-status-mode-map>\
+Type \\[magit-commit-popup] to create a commit.
+
+\\{magit-status-mode-map}"
+  :group 'magit-status
+  (hack-dir-local-variables-non-file-buffer)
+  (setq imenu-create-index-function
+        'magit-imenu--status-create-index-function)
+  (setq-local bookmark-make-record-function
+              #'magit-bookmark--status-make-record))
+
+(defun magit-status-refresh-buffer ()
+  (magit-git-exit-code "update-index" "--refresh")
+  (magit-insert-section (status)
+    (magit-run-section-hook 'magit-status-sections-hook)))
+
+(defun magit-status-maybe-update-revision-buffer (&optional _)
+  "When moving in the status buffer, update the revision buffer.
+If there is no revision buffer in the same frame, then do nothing."
+  (when (derived-mode-p 'magit-status-mode)
+    (magit-log-maybe-update-revision-buffer-1)))
+
+(defun magit-status-maybe-update-blob-buffer (&optional _)
+  "When moving in the status buffer, update the blob buffer.
+If there is no blob buffer in the same frame, then do nothing."
+  (when (derived-mode-p 'magit-status-mode)
+    (magit-log-maybe-update-blob-buffer-1)))
+
+;;; Sections
+;;;; Special Headers
+
+(defun magit-insert-status-headers ()
+  "Insert header sections appropriate for `magit-status-mode' buffers.
+The sections are inserted by running the functions on the hook
+`magit-status-headers-hook'."
+  (if (magit-rev-verify "HEAD")
+      (magit-insert-headers magit-status-headers-hook)
+    (insert "In the beginning there was darkness\n\n")))
+
+(defvar magit-error-section-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map [remap magit-visit-thing] 'magit-process-buffer)
+    map)
+  "Keymap for `error' sections.")
+
+(defun magit-insert-error-header ()
+  "Insert the message about the Git error that just occured.
+
+This function is only aware of the last error that occur when Git
+was run for side-effects.  If, for example, an error occurs while
+generating a diff, then that error won't be inserted.  Refreshing
+the status buffer causes this section to disappear again."
+  (when magit-this-error
+    (magit-insert-section (error 'git)
+      (insert (propertize (format "%-10s" "GitError! ")
+                          'face 'magit-section-heading))
+      (insert (propertize magit-this-error 'face 'font-lock-warning-face))
+      (when-let ((key (car (where-is-internal 'magit-process-buffer))))
+        (insert (format "  [Type `%s' for details]" (key-description key))))
+      (insert ?\n))
+    (setq magit-this-error nil)))
+
+(defun magit-insert-diff-filter-header ()
+  "Insert a header line showing the effective diff filters."
+  (when magit-diff-section-file-args
+    (magit-insert-section (filter 'diff)
+      (insert (propertize (format "%-10s" "Filter! ")
+                          'face 'magit-section-heading))
+      (insert (mapconcat #'identity magit-diff-section-file-args " "))
+      (insert ?\n))))
+
+;;;; Reference Headers
+
+(cl-defun magit-insert-head-branch-header
+    (&optional (branch (magit-get-current-branch)))
+  "Insert a header line about BRANCH.
+When BRANCH is nil, use the current branch or, if none, the
+detached `HEAD'."
+  (let ((output (magit-rev-format "%h %s" (or branch "HEAD"))))
+    (string-match "^\\([^ ]+\\) \\(.*\\)" output)
+    (magit-bind-match-strings (commit summary) output
+      (if branch
+          (magit-insert-section (branch branch)
+            (insert (format "%-10s" "Head: "))
+            (when magit-status-show-hashes-in-headers
+              (insert (propertize commit 'face 'magit-hash) ?\s))
+            (insert (propertize branch 'face 'magit-branch-local))
+            (insert ?\s)
+            (insert (funcall magit-log-format-message-function branch summary))
+            (insert ?\n))
+        (magit-insert-section (commit commit)
+          (insert (format "%-10s" "Head: "))
+          (insert (propertize commit 'face 'magit-hash))
+          (insert ?\s summary ?\n))))))
+
+(cl-defun magit-insert-upstream-branch-header
+    (&optional (branch (magit-get-current-branch))
+               (pull   (magit-get-upstream-branch branch))
+               keyword)
+  "Insert a header line about branch usually pulled into current branch."
+  (when pull
+    (magit-insert-section (branch pull)
+      (let ((rebase (magit-get "branch" branch "rebase")))
+        (pcase rebase
+          ("true")
+          ("false" (setq rebase nil))
+          (_       (setq rebase (magit-get-boolean "pull.rebase"))))
+        (insert (format "%-10s" (or keyword (if rebase "Rebase: " "Merge: ")))))
+      (--when-let (and magit-status-show-hashes-in-headers
+                       (not (string-match-p " " pull))
+                       (magit-rev-format "%h" pull))
+        (insert (propertize it 'face 'magit-hash) " "))
+      (if (string-match-p " " pull)
+          (pcase-let ((`(,url ,branch) (split-string pull " ")))
+            (insert branch " from " url " "))
+        (insert pull " ")
+        (--if-let (and (magit-rev-verify pull)
+                       (magit-rev-format "%s" pull))
+            (insert (funcall magit-log-format-message-function pull it))
+          (insert (propertize "is missing" 'face 'font-lock-warning-face))))
+      (insert ?\n))))
+
+(cl-defun magit-insert-push-branch-header
+    (&optional (branch (magit-get-current-branch))
+               (push   (magit-get-push-branch branch)))
+  "Insert a header line about the branch the current branch is pushed to."
+  (when push
+    (magit-insert-section (branch push)
+      (insert (format "%-10s" "Push: "))
+      (--when-let (and magit-status-show-hashes-in-headers
+                       (magit-rev-format "%h" push))
+        (insert (propertize it 'face 'magit-hash) ?\s))
+      (insert (propertize push 'face 'magit-branch-remote) ?\s)
+      (--if-let (and (magit-rev-verify push)
+                     (magit-rev-format "%s" push))
+          (insert (funcall magit-log-format-message-function push it))
+        (insert (propertize "is missing" 'face 'font-lock-warning-face)))
+      (insert ?\n))))
+
+(defun magit-insert-tags-header ()
+  "Insert a header line about the current and/or next tag."
+  (let* ((this-tag (magit-get-current-tag nil t))
+         (next-tag (magit-get-next-tag nil t))
+         (this-cnt (cadr this-tag))
+         (next-cnt (cadr next-tag))
+         (this-tag (car this-tag))
+         (next-tag (car next-tag))
+         (both-tags (and this-tag next-tag t)))
+    (when (or this-tag next-tag)
+      (magit-insert-section (tag (or this-tag next-tag))
+        (insert (format "%-10s" (if both-tags "Tags: " "Tag: ")))
+        (cl-flet ((insert-count
+                   (tag count face)
+                   (insert (concat (propertize tag 'face 'magit-tag)
+                                   (and (> count 0)
+                                        (format " (%s)"
+                                                (propertize (format "%s" count)
+                                                            'face face)))))))
+          (when this-tag  (insert-count this-tag this-cnt 'magit-branch-local))
+          (when both-tags (insert ", "))
+          (when next-tag  (insert-count next-tag next-cnt 'magit-tag)))
+        (insert ?\n)))))
+
+;;;; Auxiliary Headers
+
+(defun magit-insert-user-header ()
+  "Insert a header line about the current user."
+  (let ((name  (magit-get "user.name"))
+        (email (magit-get "user.email")))
+    (when (and name email)
+      (magit-insert-section (user name)
+        (insert (format "%-10s" "User: "))
+        (insert (propertize name 'face 'magit-log-author))
+        (insert " <" email ">\n")))))
+
+(defun magit-insert-repo-header ()
+  "Insert a header line showing the path to the repository top-level."
+  (let ((topdir (magit-toplevel)))
+    (magit-insert-section (repo topdir)
+      (insert (format "%-10s%s\n" "Repo: " (abbreviate-file-name topdir))))))
+
+(defun magit-insert-remote-header ()
+  "Insert a header line about the remote of the current branch.
+
+If no remote is configured for the current branch, then fall back
+showing the \"origin\" remote, or if that does not exist the first
+remote in alphabetic order."
+  (when-let ((name (magit-get-some-remote))
+             ;; Under certain configurations it's possible for url
+             ;; to be nil, when name is not, see #2858.
+             (url (magit-get "remote" name "url")))
+    (magit-insert-section (remote name)
+      (insert (format "%-10s" "Remote: "))
+      (insert (propertize name 'face 'magit-branch-remote) ?\s)
+      (insert url ?\n))))
+
+;;;; File Sections
+
+(defvar magit-untracked-section-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map [remap magit-delete-thing] 'magit-discard)
+    (define-key map "s" 'magit-stage)
+    map)
+  "Keymap for the `untracked' section.")
+
+(magit-define-section-jumper magit-jump-to-untracked "Untracked files" untracked)
+
+(defun magit-insert-untracked-files ()
+  "Maybe insert a list or tree of untracked files.
+
+Do so depending on the value of `status.showUntrackedFiles'.
+Note that even if the value is `all', Magit still initially
+only shows directories.  But the directory sections can then
+be expanded using \"TAB\".
+
+If the first element of `magit-diff-section-arguments' is a
+directory, then limit the list to files below that.  The value
+value of that variable can be set using \"D = f DIRECTORY RET g\"."
+  (let* ((show (or (magit-get "status.showUntrackedFiles") "normal"))
+         (base (car magit-diff-section-file-args))
+         (base (and base (file-directory-p base) base)))
+    (unless (equal show "no")
+      (if (equal show "all")
+          (when-let ((files (magit-untracked-files nil base)))
+            (magit-insert-section (untracked)
+              (magit-insert-heading "Untracked files:")
+              (magit-insert-files files base)
+              (insert ?\n)))
+        (when-let ((files (--mapcat (and (eq (aref it 0) ??)
+                                         (list (substring it 3)))
+                                    (magit-git-items "status" "-z" "--porcelain"
+                                                     "--" base))))
+          (magit-insert-section (untracked)
+            (magit-insert-heading "Untracked files:")
+            (dolist (file files)
+              (magit-insert-section (file file)
+                (insert (propertize file 'face 'magit-filename) ?\n)))
+            (insert ?\n)))))))
+
+(magit-define-section-jumper magit-jump-to-tracked "Tracked files" tracked)
+
+(defun magit-insert-tracked-files ()
+  "Insert a tree of tracked files.
+
+If the first element of `magit-diff-section-arguments' is a
+directory, then limit the list to files below that.  The value
+value of that variable can be set using \"D = f DIRECTORY RET g\"."
+  (when-let ((files (magit-list-files)))
+    (let* ((base (car magit-diff-section-file-args))
+           (base (and base (file-directory-p base) base)))
+      (magit-insert-section (tracked nil t)
+        (magit-insert-heading "Tracked files:")
+        (magit-insert-files files base)
+        (insert ?\n)))))
+
+(defun magit-insert-ignored-files ()
+  "Insert a tree of ignored files.
+
+If the first element of `magit-diff-section-arguments' is a
+directory, then limit the list to files below that.  The value
+of that variable can be set using \"D = f DIRECTORY RET g\"."
+  (when-let ((files (magit-ignored-files)))
+    (let* ((base (car magit-diff-section-file-args))
+           (base (and base (file-directory-p base) base)))
+      (magit-insert-section (tracked nil t)
+        (magit-insert-heading "Ignored files:")
+        (magit-insert-files files base)
+        (insert ?\n)))))
+
+(defun magit-insert-files (files directory)
+  (while (and files (string-prefix-p (or directory "") (car files)))
+    (let ((dir (file-name-directory (car files))))
+      (if (equal dir directory)
+          (let ((file (pop files)))
+            (magit-insert-section (file file)
+              (insert (propertize file 'face 'magit-filename) ?\n)))
+        (magit-insert-section (file dir t)
+          (insert (propertize dir 'file 'magit-filename) ?\n)
+          (magit-insert-heading)
+          (setq files (magit-insert-files files dir))))))
+  files)
+
+(provide 'magit-status)
+;;; magit-status.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-status.elc b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-status.elc
new file mode 100644
index 0000000000..cb8fb63e7b
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-status.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-submodule.el b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-submodule.el
new file mode 100644
index 0000000000..875b6294c2
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-submodule.el
@@ -0,0 +1,498 @@
+;;; magit-submodule.el --- submodule support for Magit  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2011-2018  The Magit Project Contributors
+;;
+;; You should have received a copy of the AUTHORS.md file which
+;; lists all contributors.  If not, see http://magit.vc/authors.
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; Magit 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, or (at your option)
+;; any later version.
+;;
+;; Magit 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 Magit.  If not, see http://www.gnu.org/licenses.
+
+;;; Code:
+
+(require 'magit)
+
+(defvar x-stretch-cursor)
+(defvar bookmark-make-record-function)
+
+;;; Options
+
+(defcustom magit-module-sections-hook
+  '(magit-insert-modules-overview
+    magit-insert-modules-unpulled-from-upstream
+    magit-insert-modules-unpulled-from-pushremote
+    magit-insert-modules-unpushed-to-upstream
+    magit-insert-modules-unpushed-to-pushremote)
+  "Hook run by `magit-insert-modules'.
+
+That function isn't part of `magit-status-sections-hook's default
+value, so you have to add it yourself for this hook to have any
+effect."
+  :package-version '(magit . "2.11.0")
+  :group 'magit-status
+  :type 'hook)
+
+(defcustom magit-module-sections-nested t
+  "Whether `magit-insert-modules' wraps inserted sections.
+
+If this is non-nil, then only a single top-level section
+is inserted.  If it is nil, then all sections listed in
+`magit-module-sections-hook' become top-level sections."
+  :package-version '(magit . "2.11.0")
+  :group 'magit-status
+  :type 'boolean)
+
+(defcustom magit-submodule-list-mode-hook '(hl-line-mode)
+  "Hook run after entering Magit-Submodule-List mode."
+  :package-version '(magit . "2.9.0")
+  :group 'magit-repolist
+  :type 'hook
+  :get 'magit-hook-custom-get
+  :options '(hl-line-mode))
+
+(defcustom magit-submodule-list-columns
+  '(("Path"     25 magit-modulelist-column-path   nil)
+    ("Version"  25 magit-repolist-column-version  nil)
+    ("Branch"   20 magit-repolist-column-branch   nil)
+    ("B<U" 3 magit-repolist-column-unpulled-from-upstream   ((:right-align t)))
+    ("B>U" 3 magit-repolist-column-unpushed-to-upstream     ((:right-align t)))
+    ("B<P" 3 magit-repolist-column-unpulled-from-pushremote ((:right-align t)))
+    ("B>P" 3 magit-repolist-column-unpushed-to-pushremote   ((:right-align t)))
+    ("B"   3 magit-repolist-column-branches                 ((:right-align t)))
+    ("S"   3 magit-repolist-column-stashes                  ((:right-align t))))
+  "List of columns displayed by `magit-list-submodules'.
+
+Each element has the form (HEADER WIDTH FORMAT PROPS).
+
+HEADER is the string displayed in the header.  WIDTH is the width
+of the column.  FORMAT is a function that is called with one
+argument, the repository identification (usually its basename),
+and with `default-directory' bound to the toplevel of its working
+tree.  It has to return a string to be inserted or nil.  PROPS is
+an alist that supports the keys `:right-align' and `:pad-right'."
+  :package-version '(magit . "2.8.0")
+  :group 'magit-repolist-mode
+  :type `(repeat (list :tag "Column"
+                       (string   :tag "Header Label")
+                       (integer  :tag "Column Width")
+                       (function :tag "Inserter Function")
+                       (repeat   :tag "Properties"
+                                 (list (choice :tag "Property"
+                                               (const :right-align)
+                                               (const :pad-right)
+                                               (symbol))
+                                       (sexp   :tag "Value"))))))
+
+;;; Popup
+
+;;;###autoload (autoload 'magit-submodule-popup "magit-submodule" nil t)
+(magit-define-popup magit-submodule-popup
+  "Popup console for submodule commands."
+  :man-page "git-submodule"
+  :switches '((?f "Force"            "--force")
+              (?r "Recursive"        "--recursive")
+              (?N "Do not fetch"     "--no-fetch")
+              (?C "Checkout tip"     "--checkout")
+              (?R "Rebase onto tip"  "--rebase")
+              (?M "Merge tip"        "--merge")
+              (?U "Use upstream tip" "--remote"))
+  :actions
+  '((?a "Add            git submodule add [--force]"
+        magit-submodule-add)
+    (?r "Register       git submodule init"
+        magit-submodule-register)
+    (?p "Populate       git submodule update --init"
+        magit-submodule-populate)
+    (?u "Update         git submodule update [--force] [--no-fetch]
+                     [--remote] [--recursive] [--checkout|--rebase|--merge]"
+        magit-submodule-update)
+    (?s "Synchronize    git submodule sync [--recursive]"
+        magit-submodule-synchronize)
+    (?d "Unpopulate     git submodule deinit [--force]"
+        magit-submodule-unpopulate)
+    nil
+    (?l "List all modules"  magit-list-submodules)
+    (?f "Fetch all modules" magit-fetch-modules))
+  :max-action-columns 1)
+
+(defun magit-submodule-filtered-arguments (&rest filters)
+  (--filter (and (member it filters) it)
+            (magit-submodule-arguments)))
+
+;;;###autoload
+(defun magit-submodule-add (url &optional path name args)
+  "Add the repository at URL as a module.
+
+Optional PATH is the path to the module relative to the root of
+the superproject.  If it is nil, then the path is determined
+based on the URL.  Optional NAME is the name of the module.  If
+it is nil, then PATH also becomes the name."
+  (interactive
+   (magit-with-toplevel
+     (let* ((url (magit-read-string-ns "Add submodule (remote url)"))
+            (path (let ((read-file-name-function
+                         (if (or (eq read-file-name-function 'ido-read-file-name)
+                                 (advice-function-member-p
+                                  'ido-read-file-name
+                                  read-file-name-function))
+                             ;; The Ido variant doesn't work properly here.
+                             #'read-file-name-default
+                           read-file-name-function)))
+                    (directory-file-name
+                     (file-relative-name
+                      (read-directory-name
+                       "Add submodules at path: " nil nil nil
+                       (and (string-match "\\([^./]+\\)\\(\\.git\\)?$" url)
+                            (match-string 1 url))))))))
+       (list url
+             (directory-file-name path)
+             (magit-submodule-read-name-for-path path)
+             (magit-submodule-filtered-arguments "--force")))))
+  (magit-with-toplevel
+    (magit-call-git "submodule" "add" (and name (list "--name" name))
+                    args "--" url path)
+    (unless (version< (magit-git-version) "2.11.0")
+      (magit-call-git "submodule" "absorbgitdirs" path))
+    (magit-refresh)))
+
+;;;###autoload
+(defun magit-submodule-read-name-for-path (path &optional prefer-short)
+  (let* ((path (directory-file-name (file-relative-name path)))
+         (name (file-name-nondirectory path)))
+    (push (if prefer-short path name) minibuffer-history)
+    (magit-read-string-ns
+     "Submodule name" nil (cons 'minibuffer-history 2)
+     (or (--keep (pcase-let ((`(,var ,val) (split-string it "=")))
+                   (and (equal val path)
+                        (cadr (split-string var "\\."))))
+                 (magit-git-lines "config" "--list" "-f" ".gitmodules"))
+         (if prefer-short name path)))))
+
+;;;###autoload
+(defun magit-submodule-register (modules)
+  "Register MODULES.
+
+With a prefix argument act on all suitable modules.  Otherwise,
+if the region selects modules, then act on those.  Otherwise, if
+there is a module at point, then act on that.  Otherwise read a
+single module from the user."
+  ;; This command and the underlying "git submodule init" do NOT
+  ;; "initialize" modules.  They merely "register" modules in the
+  ;; super-projects $GIT_DIR/config file, the purpose of which is to
+  ;; allow users to change such values before actually initializing
+  ;; the modules.
+  (interactive
+   (list (magit-module-confirm "Register" 'magit-module-no-worktree-p)))
+  (magit-with-toplevel
+    (magit-run-git-async "submodule" "init" "--" modules)))
+
+;;;###autoload
+(defun magit-submodule-populate (modules)
+  "Create MODULES working directories, checking out the recorded commits.
+
+With a prefix argument act on all suitable modules.  Otherwise,
+if the region selects modules, then act on those.  Otherwise, if
+there is a module at point, then act on that.  Otherwise read a
+single module from the user."
+  ;; This is the command that actually "initializes" modules.
+  ;; A module is initialized when it has a working directory,
+  ;; a gitlink, and a .gitmodules entry.
+  (interactive
+   (list (magit-module-confirm "Populate" 'magit-module-no-worktree-p)))
+  (magit-with-toplevel
+    (magit-run-git-async "submodule" "update" "--init" "--" modules)))
+
+;;;###autoload
+(defun magit-submodule-update (modules args)
+  "Update MODULES by checking out the recorded commits.
+
+With a prefix argument act on all suitable modules.  Otherwise,
+if the region selects modules, then act on those.  Otherwise, if
+there is a module at point, then act on that.  Otherwise read a
+single module from the user."
+  ;; Unlike `git-submodule's `update' command ours can only update
+  ;; "initialized" modules by checking out other commits but not
+  ;; "initialize" modules by creating the working directories.
+  ;; To do the latter we provide the "setup" command.
+  (interactive
+   (list (magit-module-confirm "Update" 'magit-module-worktree-p)
+         (magit-submodule-filtered-arguments
+          "--force" "--remote" "--recursive" "--checkout" "--rebase" "--merge"
+          "--no-fetch")))
+  (magit-with-toplevel
+    (magit-run-git-async "submodule" "update" args "--" modules)))
+
+;;;###autoload
+(defun magit-submodule-synchronize (modules args)
+  "Synchronize url configuration of MODULES.
+
+With a prefix argument act on all suitable modules.  Otherwise,
+if the region selects modules, then act on those.  Otherwise, if
+there is a module at point, then act on that.  Otherwise read a
+single module from the user."
+  (interactive
+   (list (magit-module-confirm "Synchronize" 'magit-module-worktree-p)
+         (magit-submodule-filtered-arguments "--recursive")))
+  (magit-with-toplevel
+    (magit-run-git-async "submodule" "sync" args "--" modules)))
+
+;;;###autoload
+(defun magit-submodule-unpopulate (modules args)
+  "Remove working directories of MODULES.
+
+With a prefix argument act on all suitable modules.  Otherwise,
+if the region selects modules, then act on those.  Otherwise, if
+there is a module at point, then act on that.  Otherwise read a
+single module from the user."
+  ;; Even though a package is "uninitialized" (it has no worktree)
+  ;; the super-projects $GIT_DIR/config may never-the-less set the
+  ;; module's url.  This may happen if you `deinit' and then `init'
+  ;; to register (NOT initialize).  Because the purpose of `deinit'
+  ;; is to remove the working directory AND to remove the url, this
+  ;; command does not limit itself to modules that have no working
+  ;; directory.
+  (interactive
+   (list (magit-module-confirm "Unpopulate")
+         (magit-submodule-filtered-arguments "--force")))
+  (magit-with-toplevel
+    (magit-run-git-async "submodule" "deinit" args "--" modules)))
+
+;;; Sections
+
+;;;###autoload
+(defun magit-insert-modules ()
+  "Insert submodule sections.
+Hook `magit-module-sections-hook' controls which module sections
+are inserted, and option `magit-module-sections-nested' controls
+whether they are wrapped in an additional section."
+  (when-let ((modules (magit-list-module-paths)))
+    (if magit-module-sections-nested
+        (magit-insert-section section (submodules nil t)
+          (magit-insert-heading
+            (format "%s (%s)"
+                    (propertize "Modules" 'face 'magit-section-heading)
+                    (length modules)))
+          (if (oref section hidden)
+              (oset section washer 'magit--insert-modules)
+            (magit--insert-modules)))
+      (magit--insert-modules))))
+
+(defun magit--insert-modules (&optional _section)
+  (magit-run-section-hook 'magit-module-sections-hook))
+
+;;;###autoload
+(defun magit-insert-modules-overview ()
+  "Insert sections for all modules.
+For each section insert the path and the output of `git describe --tags',
+or, failing that, the abbreviated HEAD commit hash."
+  (when-let ((modules (magit-list-module-paths)))
+    (magit-insert-section section (submodules nil t)
+      (magit-insert-heading
+        (format "%s (%s)"
+                (propertize "Modules overview" 'face 'magit-section-heading)
+                (length modules)))
+      (if (oref section hidden)
+          (oset section washer 'magit--insert-modules-overview)
+        (magit--insert-modules-overview)))))
+
+(defvar magit-modules-overview-align-numbers t)
+
+(defun magit--insert-modules-overview (&optional _section)
+  (magit-with-toplevel
+    (let* ((modules (magit-list-module-paths))
+           (path-format (format "%%-%is "
+                                (min (apply 'max (mapcar 'length modules))
+                                     (/ (window-width) 2))))
+           (branch-format (format "%%-%is " (min 25 (/ (window-width) 3)))))
+      (dolist (module modules)
+        (let ((default-directory
+                (expand-file-name (file-name-as-directory module))))
+          (magit-insert-section (submodule module t)
+            (insert (propertize (format path-format module)
+                                'face 'magit-diff-file-heading))
+            (if (not (file-exists-p ".git"))
+                (insert "(unpopulated)")
+              (insert (format branch-format
+                              (--if-let (magit-get-current-branch)
+                                  (propertize it 'face 'magit-branch-local)
+                                (propertize "(detached)" 'face 'warning))))
+              (--if-let (magit-git-string "describe" "--tags")
+                  (progn (when (and magit-modules-overview-align-numbers
+                                    (string-match-p "\\`[0-9]" it))
+                           (insert ?\s))
+                         (insert (propertize it 'face 'magit-tag)))
+                (--when-let (magit-rev-format "%h")
+                  (insert (propertize it 'face 'magit-hash)))))
+            (insert ?\n))))))
+  (insert ?\n))
+
+(defvar magit-submodules-section-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map [remap magit-visit-thing] 'magit-list-submodules)
+    map)
+  "Keymap for `submodules' sections.")
+
+(defvar magit-submodule-section-map
+  (let ((map (make-sparse-keymap)))
+    (unless (featurep 'jkl)
+      (define-key map "\C-j"   'magit-submodule-visit))
+    (define-key map [C-return] 'magit-submodule-visit)
+    (define-key map [remap magit-visit-thing]  'magit-submodule-visit)
+    (define-key map [remap magit-delete-thing] 'magit-submodule-deinit)
+    (define-key map "K" 'magit-file-untrack)
+    (define-key map "R" 'magit-file-rename)
+    map)
+  "Keymap for `submodule' sections.")
+
+(defun magit-submodule-visit (module &optional other-window)
+  "Visit MODULE by calling `magit-status' on it.
+Offer to initialize MODULE if it's not checked out yet.
+With a prefix argument, visit in another window."
+  (interactive (list (or (magit-section-when submodule)
+                         (magit-read-module-path "Visit module"))
+                     current-prefix-arg))
+  (magit-with-toplevel
+    (let ((path (expand-file-name module)))
+      (if (and (not (file-exists-p (expand-file-name ".git" module)))
+               (not (y-or-n-p (format "Initialize submodule '%s' first?"
+                                      module))))
+          (when (file-exists-p path)
+            (dired-jump other-window (concat path "/.")))
+        (magit-run-git-async "submodule" "update" "--init" "--" module)
+        (set-process-sentinel
+         magit-this-process
+         (lambda (process event)
+           (let ((magit-process-raise-error t))
+             (magit-process-sentinel process event))
+           (when (and (eq (process-status      process) 'exit)
+                      (=  (process-exit-status process) 0))
+             (magit-diff-visit-directory path other-window))))))))
+
+;;;###autoload
+(defun magit-insert-modules-unpulled-from-upstream ()
+  "Insert sections for modules that haven't been pulled from the upstream.
+These sections can be expanded to show the respective commits."
+  (magit--insert-modules-logs "Modules unpulled from @{upstream}"
+                              'modules-unpulled-from-upstream
+                              "HEAD..@{upstream}"))
+
+;;;###autoload
+(defun magit-insert-modules-unpulled-from-pushremote ()
+  "Insert sections for modules that haven't been pulled from the push-remote.
+These sections can be expanded to show the respective commits."
+  (magit--insert-modules-logs "Modules unpulled from ${push}"
+                              'modules-unpulled-from-pushremote
+                              "HEAD..@{push}"))
+
+;;;###autoload
+(defun magit-insert-modules-unpushed-to-upstream ()
+  "Insert sections for modules that haven't been pushed to the upstream.
+These sections can be expanded to show the respective commits."
+  (magit--insert-modules-logs "Modules unmerged into @{upstream}"
+                              'modules-unpushed-to-upstream
+                              "@{upstream}..HEAD"))
+
+;;;###autoload
+(defun magit-insert-modules-unpushed-to-pushremote ()
+  "Insert sections for modules that haven't been pushed to the push-remote.
+These sections can be expanded to show the respective commits."
+  (magit--insert-modules-logs "Modules unpushed to @{push}"
+                              'modules-unpushed-to-pushremote
+                              "${push}..HEAD"))
+
+(defun magit--insert-modules-logs (heading type range)
+  "For internal use, don't add to a hook."
+  (when-let ((modules (magit-list-module-paths)))
+    (magit-insert-section section ((eval type) nil t)
+      (string-match "\\`\\(.+\\) \\([^ ]+\\)\\'" heading)
+      (magit-insert-heading
+        (concat
+         (propertize (match-string 1 heading) 'face 'magit-section-heading) " "
+         (propertize (match-string 2 heading) 'face 'magit-branch-remote) ":"))
+      (magit-with-toplevel
+        (dolist (module modules)
+          (when (magit-module-worktree-p module)
+            (let ((default-directory
+                    (expand-file-name (file-name-as-directory module))))
+              (when (magit-file-accessible-directory-p default-directory)
+                (magit-insert-section sec (file module t)
+                  (magit-insert-heading
+                    (concat (propertize module 'face 'magit-diff-file-heading) ":"))
+                  (magit-git-wash (apply-partially 'magit-log-wash-log 'module)
+                    "-c" "push.default=current" "log" "--oneline" range)
+                  (when (> (point)
+                           (oref sec content))
+                    (delete-char -1))))))))
+      (if (> (point)
+             (oref section content))
+          (insert ?\n)
+        (magit-cancel-section)))))
+
+;;; List
+
+;;;###autoload
+(defun magit-list-submodules ()
+  "Display a list of the current repository's submodules."
+  (interactive)
+  (magit-display-buffer (magit-mode-get-buffer 'magit-submodule-list-mode t))
+  (magit-submodule-list-mode)
+  (magit-submodule-list-refresh)
+  (tabulated-list-print))
+
+(defvar magit-submodule-list-mode-map
+  (let ((map (make-sparse-keymap)))
+    (set-keymap-parent map magit-repolist-mode-map)
+    map)
+  "Local keymap for Magit-Submodule-List mode buffers.")
+
+(define-derived-mode magit-submodule-list-mode tabulated-list-mode "Modules"
+  "Major mode for browsing a list of Git submodules."
+  :group 'magit-repolist-mode
+  (setq x-stretch-cursor        nil)
+  (setq tabulated-list-padding  0)
+  (setq tabulated-list-sort-key (cons "Path" nil))
+  (setq tabulated-list-format
+        (vconcat (mapcar (pcase-lambda (`(,title ,width ,_fn ,props))
+                           (nconc (list title width t)
+                                  (-flatten props)))
+                         magit-submodule-list-columns)))
+  (tabulated-list-init-header)
+  (add-hook 'tabulated-list-revert-hook 'magit-submodule-list-refresh nil t)
+  (setq imenu-prev-index-position-function
+        #'magit-imenu--submodule-prev-index-position-function)
+  (setq imenu-extract-index-name-function
+        #'magit-imenu--submodule-extract-index-name-function)
+  (setq-local bookmark-make-record-function
+              #'magit-bookmark--submodules-make-record))
+
+(defun magit-submodule-list-refresh ()
+  (setq tabulated-list-entries
+        (-keep (lambda (module)
+                 (let ((default-directory
+                         (expand-file-name (file-name-as-directory module))))
+                   (and (file-exists-p ".git")
+                        (list module
+                              (vconcat
+                               (--map (or (funcall (nth 2 it) module) "")
+                                      magit-submodule-list-columns))))))
+               (magit-list-module-paths))))
+
+(defun magit-modulelist-column-path (path)
+  "Insert the relative path of the submodule."
+  path)
+
+(provide 'magit-submodule)
+;;; magit-submodule.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-submodule.elc b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-submodule.elc
new file mode 100644
index 0000000000..424f1e7289
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-submodule.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-subtree.el b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-subtree.el
new file mode 100644
index 0000000000..b31d0d8b5f
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-subtree.el
@@ -0,0 +1,146 @@
+;;; magit-subtree.el --- subtree support for Magit  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2011-2018  The Magit Project Contributors
+;;
+;; You should have received a copy of the AUTHORS.md file which
+;; lists all contributors.  If not, see http://magit.vc/authors.
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; Magit 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, or (at your option)
+;; any later version.
+;;
+;; Magit 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 Magit.  If not, see http://www.gnu.org/licenses.
+
+;;; Code:
+
+(require 'magit)
+
+;;; Popup
+
+;;;###autoload (autoload 'magit-subtree-popup "magit-subtree" nil t)
+(magit-define-popup magit-subtree-popup
+  "Popup console for subtree commands."
+  :man-page "git-subtree"
+  :switches '("Switches for add, merge, push, and pull"
+              (?s "Squash" "--squash")
+              "Switches for split"
+              (?i "Ignore joins" "--ignore-joins")
+              (?j "Rejoin"       "--rejoin"))
+  :options  '("Options"
+              (?p "Prefix" "--prefix=" magit-subtree-read-prefix)
+              "Options for add, merge, and pull"
+              (?m "Message" "--message=")
+              "Options for split"
+              (?a "Annotate" "--annotate=")
+              (?b "Branch"   "--branch=")
+              (?o "Onto"     "--onto=" magit-read-branch-or-commit))
+  :actions  '((?a "Add"        magit-subtree-add)
+              (?m "Merge"      magit-subtree-merge)
+              (?p "Push"       magit-subtree-push)
+              (?c "Add commit" magit-subtree-add-commit)
+              (?f "Pull"       magit-subtree-pull)
+              (?s "Split"      magit-subtree-split))
+  :max-action-columns 3)
+
+(defun magit-subtree-read-prefix (prompt &optional default)
+  (let* ((insert-default-directory nil)
+         (topdir (magit-toplevel))
+         (prefix (read-directory-name (concat prompt ": ") topdir default)))
+    (if (file-name-absolute-p prefix)
+        ;; At least `ido-mode's variant is not compatible.
+        (if (string-prefix-p topdir prefix)
+            (file-relative-name prefix topdir)
+          (user-error "%s isn't inside the repository at %s" prefix topdir))
+      prefix)))
+
+;;; Commands
+
+(defun magit-subtree-prefix (prompt)
+  (--if-let (--first (string-prefix-p "--prefix=" it)
+                     (magit-subtree-arguments))
+      (substring it 9)
+    (magit-subtree-read-prefix prompt)))
+
+(defun magit-subtree-args ()
+  (-filter (lambda (arg)
+             (if (eq this-command 'magit-subtree-split)
+                 (or (equal arg "--ignore-joins")
+                     (equal arg "--rejoin")
+                     (string-prefix-p "--annotate=" arg)
+                     (string-prefix-p "--branch=" arg)
+                     (string-prefix-p "--onto=" arg))
+               (or (equal arg "--squash")
+                   (and (string-prefix-p "--message=" arg)
+                        (not (eq this-command 'magit-subtree-push))))))
+           (magit-subtree-arguments)))
+
+(defun magit-git-subtree (subcmd prefix &rest args)
+  (magit-run-git-async "subtree" subcmd (concat "--prefix=" prefix) args))
+
+;;;###autoload
+(defun magit-subtree-add (prefix repository ref args)
+  "Add REF from REPOSITORY as a new subtree at PREFIX."
+  (interactive
+   (cons (magit-subtree-prefix "Add subtree")
+         (let ((remote (magit-read-remote-or-url "From repository")))
+           (list remote
+                 (magit-read-refspec "Ref" remote)
+                 (magit-subtree-args)))))
+  (magit-git-subtree "add" prefix args repository ref))
+
+;;;###autoload
+(defun magit-subtree-add-commit (prefix commit args)
+  "Add COMMIT as a new subtree at PREFIX."
+  (interactive (list (magit-subtree-prefix "Add subtree")
+                     (magit-read-string-ns "Commit")
+                     (magit-subtree-args)))
+  (magit-git-subtree "add" prefix args commit))
+
+;;;###autoload
+(defun magit-subtree-merge (prefix commit args)
+  "Merge COMMIT into the PREFIX subtree."
+  (interactive (list (magit-subtree-prefix "Merge into subtree")
+                     (magit-read-string-ns "Commit")
+                     (magit-subtree-args)))
+  (magit-git-subtree "merge" prefix args commit))
+
+;;;###autoload
+(defun magit-subtree-pull (prefix repository ref args)
+  "Pull REF from REPOSITORY into the PREFIX subtree."
+  (interactive
+   (cons (magit-subtree-prefix "Pull into subtree")
+         (let ((remote (magit-read-remote-or-url "From repository")))
+           (list remote
+                 (magit-read-refspec "Ref" remote)
+                 (magit-subtree-args)))))
+  (magit-git-subtree "pull" prefix args repository ref))
+
+;;;###autoload
+(defun magit-subtree-push (prefix repository ref args)
+  "Extract the history of the subtree PREFIX and push it to REF on REPOSITORY."
+  (interactive (list (magit-subtree-prefix "Push subtree")
+                     (magit-read-remote-or-url "To repository")
+                     (magit-read-string-ns "To reference")
+                     (magit-subtree-args)))
+  (magit-git-subtree "push" prefix args repository ref))
+
+;;;###autoload
+(defun magit-subtree-split (prefix commit args)
+  "Extract the history of the subtree PREFIX."
+  (interactive (list (magit-subtree-prefix "Split subtree")
+                     (magit-read-string-ns "Commit")
+                     (magit-subtree-args)))
+  (magit-git-subtree "split" prefix args commit))
+
+(provide 'magit-subtree)
+;;; magit-subtree.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-subtree.elc b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-subtree.elc
new file mode 100644
index 0000000000..312ddee3ef
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-subtree.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-tag.el b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-tag.el
new file mode 100644
index 0000000000..1153e2ca42
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-tag.el
@@ -0,0 +1,132 @@
+;;; magit-tag.el --- tag functionality  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2010-2018  The Magit Project Contributors
+;;
+;; You should have received a copy of the AUTHORS.md file which
+;; lists all contributors.  If not, see http://magit.vc/authors.
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; Magit 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, or (at your option)
+;; any later version.
+;;
+;; Magit 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 Magit.  If not, see http://www.gnu.org/licenses.
+
+;;; Commentary:
+
+;; This library implements tag commands.
+
+;;; Code:
+
+(require 'magit)
+
+;;;###autoload (autoload 'magit-tag-popup "magit" nil t)
+(magit-define-popup magit-tag-popup
+  "Popup console for tag commands."
+  :man-page "git-tag"
+  :switches '((?a "Annotate" "--annotate")
+              (?f "Force"    "--force")
+              (?s "Sign"     "--sign"))
+  :options  '((?f "Sign"     "--local-user=" magit-read-gpg-secret-key))
+  :actions  '((?t "Create"   magit-tag)
+              (?k "Delete"   magit-tag-delete)
+              (?p "Prune"    magit-tag-prune))
+  :default-action 'magit-tag)
+
+;;;###autoload
+(defun magit-tag (name rev &optional args)
+  "Create a new tag with the given NAME at REV.
+With a prefix argument annotate the tag.
+\n(git tag [--annotate] NAME REV)"
+  (interactive (list (magit-read-tag "Tag name")
+                     (magit-read-branch-or-commit "Place tag on")
+                     (let ((args (magit-tag-arguments)))
+                       (when current-prefix-arg
+                         (cl-pushnew "--annotate" args))
+                       args)))
+  (magit-run-git-with-editor "tag" args name rev))
+
+;;;###autoload
+(defun magit-tag-delete (tags)
+  "Delete one or more tags.
+If the region marks multiple tags (and nothing else), then offer
+to delete those, otherwise prompt for a single tag to be deleted,
+defaulting to the tag at point.
+\n(git tag -d TAGS)"
+  (interactive (list (--if-let (magit-region-values 'tag)
+                         (magit-confirm t nil "Delete %i tags" nil it)
+                       (magit-read-tag "Delete tag" t))))
+  (magit-run-git "tag" "-d" tags))
+
+;;;###autoload
+(defun magit-tag-prune (tags remote-tags remote)
+  "Offer to delete tags missing locally from REMOTE, and vice versa."
+  (interactive
+   (let* ((remote (magit-read-remote "Prune tags using remote"))
+          (tags   (magit-list-tags))
+          (rtags  (prog2 (message "Determining remote tags...")
+                      (magit-remote-list-tags remote)
+                    (message "Determining remote tags...done")))
+          (ltags  (-difference tags rtags))
+          (rtags  (-difference rtags tags)))
+     (unless (or ltags rtags)
+       (message "Same tags exist locally and remotely"))
+     (unless (magit-confirm t
+               "Delete %s locally"
+               "Delete %i tags locally"
+               'noabort ltags)
+       (setq ltags nil))
+     (unless (magit-confirm t
+               "Delete %s from remote"
+               "Delete %i tags from remote"
+               'noabort rtags)
+       (setq rtags nil))
+     (list ltags rtags remote)))
+  (when tags
+    (magit-call-git "tag" "-d" tags))
+  (when remote-tags
+    (magit-run-git-async "push" remote (--map (concat ":" it) remote-tags))))
+
+;;;###autoload
+(defun magit-tag-release (tag)
+  "Create an opinionated release tag.
+
+Assume version tags that match \"\\\\`v?[0-9]\\\\(\\\\.[0-9]\\\\)*\\\\'\".
+Prompt for the name of the new tag using the highest existing tag
+as initial input and call \"git tag --annotate --sign -m MSG\" TAG,
+regardless of whether these arguments are enabled in the popup.
+Given a TAG \"v1.2.3\" and a repository \"/path/to/foo-bar\", the
+MESSAGE would be \"Foo-Bar 1.2.3\".
+
+Because it is so opinionated, this command is not available from
+the tag popup by default."
+  (interactive
+   (list (read-string "Create tag: "
+                      (car (nreverse
+                            (cl-sort (magit-list-tags) #'version<
+                                     :key (lambda (tag)
+                                            (if (string-prefix-p "v" tag)
+                                                (substring tag 1)
+                                              tag))))))))
+  (magit-run-git
+   "tag" "--annotate" "--sign"
+   "-m" (format "%s %s"
+                (capitalize (file-name-nondirectory
+                             (directory-file-name (magit-toplevel))))
+                (if (string-prefix-p "v" tag)
+                    (substring tag 1)
+                  tag))
+   tag)
+  (magit-show-refs))
+
+(provide 'magit-tag)
+;;; magit-tag.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-tag.elc b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-tag.elc
new file mode 100644
index 0000000000..a55308eb01
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-tag.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-utils.el b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-utils.el
new file mode 100644
index 0000000000..b46d7bf747
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-utils.el
@@ -0,0 +1,971 @@
+;;; magit-utils.el --- various utilities  -*- lexical-binding: t; coding: utf-8 -*-
+
+;; Copyright (C) 2010-2018  The Magit Project Contributors
+;;
+;; You should have received a copy of the AUTHORS.md file which
+;; lists all contributors.  If not, see http://magit.vc/authors.
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; Contains code from GNU Emacs https://www.gnu.org/software/emacs,
+;; released under the GNU General Public License version 3 or later.
+
+;; Magit 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, or (at your option)
+;; any later version.
+;;
+;; Magit 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 Magit.  If not, see http://www.gnu.org/licenses.
+
+;;; Commentary:
+
+;; This library defines several utility functions used by several
+;; other libraries which cannot depend on one another (because
+;; circular dependencies are not good).  Luckily most (all) of these
+;; functions have very little (nothing) to do with Git, so we not only
+;; have to do this, it even makes sense.
+
+;; Unfortunately there are also some options which are used by several
+;; libraries which cannot depend on one another, they are defined here
+;; too.
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'dash)
+(require 'subr-x)
+
+(require 'crm)
+
+(eval-when-compile (require 'ido))
+(declare-function ido-completing-read+ "ido-completing-read+"
+                  (prompt collection &optional predicate
+                          require-match initial-input
+                          hist def inherit-input-method))
+(declare-function Info-get-token "info" (pos start all &optional errorstring))
+
+(eval-when-compile (require 'vc-git))
+(declare-function vc-git--run-command-string "vc-git" (file &rest args))
+
+(defvar magit-wip-before-change-mode)
+
+;;; Options
+
+(defcustom magit-completing-read-function 'magit-builtin-completing-read
+  "Function to be called when requesting input from the user.
+
+If you have enabled `ivy-mode' or `helm-mode', then you don't
+have to customize this option; `magit-builtin-completing-read'
+will work just fine.  However, if you use Ido completion, then
+you do have to use `magit-ido-completion-read', because Ido is
+less well behaved than the former, more modern alternatives.
+
+If you would like to use Ivy or Helm completion with Magit but
+not enable the respective modes globally, then customize this
+option to use `ivy-completing-read' or
+`helm--completing-read-default'.  If you choose to use
+`ivy-completing-read', note that the items may always be shown in
+alphabetical order, depending on your version of Ivy."
+  :group 'magit-essentials
+  :type '(radio (function-item magit-builtin-completing-read)
+                (function-item magit-ido-completing-read)
+                (function-item ivy-completing-read)
+                (function-item helm--completing-read-default)
+                (function :tag "Other function")))
+
+(defcustom magit-dwim-selection
+  '((magit-stash-apply        nil t)
+    (magit-stash-branch       nil t)
+    (magit-stash-branch-here  nil t)
+    (magit-stash-format-patch nil t)
+    (magit-stash-drop         nil ask)
+    (magit-stash-pop          nil ask))
+  "When not to offer alternatives and ask for confirmation.
+
+Many commands by default ask the user to select from a list of
+possible candidates.  They do so even when there is a thing at
+point that they can act on, which is then offered as the default.
+
+This option can be used to tell certain commands to use the thing
+at point instead of asking the user to select a candidate to act
+on, with or without confirmation.
+
+The value has the form ((COMMAND nil|PROMPT DEFAULT)...).
+
+- COMMAND is the command that should not prompt for a choice.
+  To have an effect, the command has to use the function
+  `magit-completing-read' or a utility function which in turn uses
+  that function.
+
+- If the command uses `magit-completing-read' multiple times, then
+  PROMPT can be used to only affect one of these uses.  PROMPT, if
+  non-nil, is a regular expression that is used to match against
+  the PROMPT argument passed to `magit-completing-read'.
+
+- DEFAULT specifies how to use the default.  If it is t, then
+  the DEFAULT argument passed to `magit-completing-read' is used
+  without confirmation.  If it is `ask', then the user is given
+  a chance to abort.  DEFAULT can also be nil, in which case the
+  entry has no effect."
+  :package-version '(magit . "2.12.0")
+  :group 'magit-commands
+  :type '(repeat
+          (list (symbol :tag "Command") ; It might not be fboundp yet.
+                (choice (const  :tag "for all prompts" nil)
+                        (regexp :tag "for prompts matching regexp"))
+                (choice (const  :tag "offer other choices" nil)
+                        (const  :tag "require confirmation" ask)
+                        (const  :tag "use default without confirmation" t)))))
+
+(defconst magit--confirm-actions
+  '((const reverse)           (const discard)
+    (const rename)            (const resurrect)
+    (const untrack)           (const trash)
+    (const delete)            (const abort-rebase)
+    (const abort-merge)       (const merge-dirty)
+    (const drop-stashes)      (const resect-bisect)
+    (const kill-process)      (const delete-unmerged-branch)
+    (const delete-pr-branch)
+    (const stage-all-changes) (const unstage-all-changes)
+    (const safe-with-wip)))
+
+(defcustom magit-no-confirm nil
+  "A list of symbols for actions Magit should not confirm, or t.
+
+Many potentially dangerous commands by default ask the user for
+confirmation.  Each of the below symbols stands for an action
+which, when invoked unintentionally or without being fully aware
+of the consequences, could lead to tears.  In many cases there
+are several commands that perform variations of a certain action,
+so we don't use the command names but more generic symbols.
+
+Applying changes:
+
+  `discard' Discarding one or more changes (i.e. hunks or the
+  complete diff for a file) loses that change, obviously.
+
+  `reverse' Reverting one or more changes can usually be undone
+  by reverting the reversion.
+
+  `stage-all-changes', `unstage-all-changes' When there are both
+  staged and unstaged changes, then un-/staging everything would
+  destroy that distinction.  Of course that also applies when
+  un-/staging a single change, but then less is lost and one does
+  that so often that having to confirm every time would be
+  unacceptable.
+
+Files:
+
+  `delete' When a file that isn't yet tracked by Git is deleted
+  then it is completely lost, not just the last changes.  Very
+  dangerous.
+
+  `trash' Instead of deleting a file it can also be move to the
+  system trash.  Obviously much less dangerous than deleting it.
+
+  Also see option `magit-delete-by-moving-to-trash'.
+
+  `resurrect' A deleted file can easily be resurrected by
+  \"deleting\" the deletion, which is done using the same command
+  that was used to delete the same file in the first place.
+
+  `untrack' Untracking a file can be undone by tracking it again.
+
+  `rename' Renaming a file can easily be undone.
+
+Sequences:
+
+  `reset-bisect' Aborting (known to Git as \"resetting\") a
+  bisect operation loses all information collected so far.
+
+  `abort-rebase' Aborting a rebase throws away all already
+  modified commits, but it's possible to restore those from the
+  reflog.
+
+  `abort-merge' Aborting a merge throws away all conflict
+  resolutions which has already been carried out by the user.
+
+  `merge-dirty' Merging with a dirty worktree can make it hard to
+  go back to the state before the merge was initiated.
+
+References:
+
+  `delete-unmerged-branch' Once a branch has been deleted it can
+  only be restored using low-level recovery tools provided by
+  Git.  And even then the reflog is gone.  The user always has
+  to confirm the deletion of a branch by accepting the default
+  choice (or selecting another branch), but when a branch has
+  not been merged yet, also make sure the user is aware of that.
+
+  `delete-pr-branch' When deleting a branch that was created from
+  a pull request and if no other branches still exist on that
+  remote, then `magit-branch-delete' offers to delete the remote
+  as well.  This should be safe because it only happens if no
+  other refs exist in the remotes namespace, and you can recreate
+  the remote if necessary.
+
+  `drop-stashes' Dropping a stash is dangerous because Git stores
+  stashes in the reflog.  Once a stash is removed, there is no
+  going back without using low-level recovery tools provided by
+  Git.  When a single stash is dropped, then the user always has
+  to confirm by accepting the default (or selecting another).
+  This action only concerns the deletion of multiple stashes at
+  once.
+
+Edit published history:
+
+  Without adding these symbols here, you will be warned before
+  editing commits that have already been pushed to one of the
+  branches listed in `magit-published-branches'.
+
+  `amend-published' Affects most commands that amend to \"HEAD\".
+
+  `rebase-published' Affects commands that perform interactive
+  rebases.  This includes commands from the commit popup that
+  modify a commit other than \"HEAD\", namely the various fixup
+  and squash variants.
+
+  `edit-published' Affects the commands `magit-edit-line-commit'
+  and `magit-diff-edit-hunk-commit'.  These two commands make
+  it quite easy to accidentally edit a published commit, so you
+  should think twice before configuring them not to ask for
+  confirmation.
+
+  To disable confirmation completely, add all three symbols here
+  or set `magit-published-branches' to nil.
+
+Various:
+
+  `kill-process' There seldom is a reason to kill a process.
+
+Global settings:
+
+  Instead of adding all of the above symbols to the value of this
+  option you can also set it to the atom `t', which has the same
+  effect as adding all of the above symbols.  Doing that most
+  certainly is a bad idea, especially because other symbols might
+  be added in the future.  So even if you don't want to be asked
+  for confirmation for any of these actions, you are still better
+  of adding all of the respective symbols individually.
+
+  When `magit-wip-before-change-mode' is enabled then these actions
+  can fairly easily be undone: `discard', `reverse',
+  `stage-all-changes', and `unstage-all-changes'.  If and only if
+  this mode is enabled, then `safe-with-wip' has the same effect
+  as adding all of these symbols individually."
+  :package-version '(magit . "2.1.0")
+  :group 'magit-essentials
+  :group 'magit-commands
+  :type `(choice (const :tag "Always require confirmation" nil)
+                 (const :tag "Never require confirmation" t)
+                 (set   :tag "Require confirmation only for"
+                        ,@magit--confirm-actions)))
+
+(defcustom magit-slow-confirm '(drop-stashes)
+  "Whether to ask user \"y or n\" or \"yes or no\" questions.
+
+When this is nil, then `y-or-n-p' is used when the user has to
+confirm a potentially destructive action.  When this is t, then
+`yes-or-no-p' is used instead.  If this is a list of symbols
+identifying actions, then `yes-or-no-p' is used for those,
+`y-or-no-p' for all others.  The list of actions is the same as
+for `magit-no-confirm' (which see)."
+  :package-version '(magit . "2.9.0")
+  :group 'magit-miscellaneous
+  :type `(choice (const :tag "Always ask \"yes or no\" questions" t)
+                 (const :tag "Always ask \"y or n\" questions" nil)
+                 (set   :tag "Ask \"yes or no\" questions only for"
+                        ,@magit--confirm-actions)))
+
+(defcustom magit-no-message nil
+  "A list of messages Magit should not display.
+
+Magit displays most echo area messages using `message', but a few
+are displayed using `magit-message' instead, which takes the same
+arguments as the former, FORMAT-STRING and ARGS.  `magit-message'
+forgoes printing a message if any member of this list is a prefix
+of the respective FORMAT-STRING.
+
+If Magit prints a message which causes you grief, then please
+first investigate whether there is another option which can be
+used to suppress it.  If that is not the case, then ask the Magit
+maintainers to start using `magit-message' instead of `message'
+in that case.  We are not proactively replacing all uses of
+`message' with `magit-message', just in case someone *might* find
+some of these messages useless.
+
+Messages which can currently be suppressed using this option are:
+* \"Turning on magit-auto-revert-mode...\""
+  :package-version '(magit . "2.8.0")
+  :group 'magit-miscellaneous
+  :type '(repeat string))
+
+(defcustom magit-ellipsis ?…
+  "Character used to abbreviate text.
+
+Currently this is used to abbreviate author names in the margin
+and in process buffers to elide `magit-git-global-arguments'."
+  :package-version '(magit . "2.1.0")
+  :group 'magit-miscellaneous
+  :type 'character)
+
+(defcustom magit-update-other-window-delay 0.2
+  "Delay before automatically updating the other window.
+
+When moving around in certain buffers, then certain other
+buffers, which are being displayed in another window, may
+optionally be updated to display information about the
+section at point.
+
+When holding down a key to move by more than just one section,
+then that would update that buffer for each section on the way.
+To prevent that, updating the revision buffer is delayed, and
+this option controls for how long.  For optimal experience you
+might have to adjust this delay and/or the keyboard repeat rate
+and delay of your graphical environment or operating system."
+  :package-version '(magit . "2.3.0")
+  :group 'magit-miscellaneous
+  :type 'number)
+
+(defcustom magit-view-git-manual-method 'info
+  "How links to Git documentation are followed from Magit's Info manuals.
+
+`info'  Follow the link to the node in the `gitman' Info manual
+        as usual.  Unfortunately that manual is not installed by
+        default on some platforms, and when it is then the nodes
+        look worse than the actual manpages.
+
+`man'   View the respective man-page using the `man' package.
+
+`woman' View the respective man-page using the `woman' package."
+  :package-version '(magit . "2.9.0")
+  :group 'magit-miscellaneous
+  :type '(choice (const :tag "view info manual" info)
+                 (const :tag "view manpage using `man'" man)
+                 (const :tag "view manpage using `woman'" woman)))
+
+;;; User Input
+
+(defvar helm-completion-in-region-default-sort-fn)
+(defvar ivy-sort-functions-alist)
+
+(defvar magit-completing-read--silent-default nil)
+
+(defun magit-completing-read (prompt collection &optional
+                                     predicate require-match initial-input
+                                     hist def fallback)
+  "Read a choice in the minibuffer, or use the default choice.
+
+This is the function that Magit commands use when they need the
+user to select a single thing to act on.  The arguments have the
+same meaning as for `completing-read', except for FALLBACK, which
+is unique to this function and is described below.
+
+Instead of asking the user to choose from a list of possible
+candidates, this function may instead just return the default
+specified by DEF, with or without requiring user confirmation.
+Whether that is the case depends on PROMPT, `this-command' and
+`magit-dwim-selection'.  See the documentation of the latter for
+more information.
+
+If it does use the default without the user even having to
+confirm that, then `magit-completing-read--silent-default' is set
+to t, otherwise nil.
+
+If it does read a value in the minibuffer, then this function
+acts similarly to `completing-read', except for the following:
+
+- If REQUIRE-MATCH is nil and the user exits without a choice,
+  then nil is returned instead of an empty string.
+
+- If REQUIRE-MATCH is non-nil and the users exits without a
+  choice, an user-error is raised.
+
+- FALLBACK specifies a secondary default that is only used if
+  the primary default DEF is nil.  The secondary default is not
+  subject to `magit-dwim-selection' — if DEF is nil but FALLBACK
+  is not, then this function always asks the user to choose a
+  candidate, just as if both defaults were nil.
+
+- \": \" is appended to PROMPT.
+
+- PROMPT is modified to end with \" (default DEF|FALLBACK): \"
+  provided that DEF or FALLBACK is non-nil, that neither
+  `ivy-mode' nor `helm-mode' is enabled, and that
+  `magit-completing-read-function' is set to its default value of
+  `magit-builtin-completing-read'."
+  (setq magit-completing-read--silent-default nil)
+  (if-let ((dwim (and def
+                      (nth 2 (-first (pcase-lambda (`(,cmd ,re ,_))
+                                       (and (eq this-command cmd)
+                                            (or (not re)
+                                                (string-match-p re prompt))))
+                                     magit-dwim-selection)))))
+      (if (eq dwim 'ask)
+          (if (y-or-n-p (format "%s %s? " prompt def))
+              def
+            (user-error "Abort"))
+        (setq magit-completing-read--silent-default t)
+        def)
+    (unless def
+      (setq def fallback))
+    (let ((reply (funcall magit-completing-read-function
+                          (concat prompt ": ")
+                          (if (and def (not (member def collection)))
+                              (cons def collection)
+                            collection)
+                          predicate
+                          require-match initial-input hist def)))
+      (if (string= reply "")
+          (if require-match
+              (user-error "Nothing selected")
+            nil)
+        reply))))
+
+(defun magit--completion-table (collection)
+  (lambda (string pred action)
+    (if (eq action 'metadata)
+        '(metadata (display-sort-function . identity))
+      (complete-with-action action collection string pred))))
+
+(defvar ivy-sort-functions-alist)
+
+(defun magit-builtin-completing-read
+  (prompt choices &optional predicate require-match initial-input hist def)
+  "Magit wrapper for standard `completing-read' function."
+  (unless (or (bound-and-true-p helm-mode)
+              (bound-and-true-p ivy-mode))
+    (setq prompt (magit-prompt-with-default prompt def))
+    (setq choices (magit--completion-table choices)))
+  (cl-letf (((symbol-function 'completion-pcm--all-completions)
+             #'magit-completion-pcm--all-completions))
+    (let ((ivy-sort-functions-alist nil))
+      (completing-read prompt choices
+                       predicate require-match
+                       initial-input hist def))))
+
+(defun magit-completing-read-multiple
+  (prompt choices &optional sep default hist keymap)
+  "Read multiple items from CHOICES, separated by SEP.
+
+Set up the `crm' variables needed to read multiple values with
+`read-from-minibuffer'.
+
+SEP is a regexp matching characters that can separate choices.
+When SEP is nil, it defaults to `crm-default-separator'.
+DEFAULT, HIST, and KEYMAP are passed to `read-from-minibuffer'.
+When KEYMAP is nil, it defaults to `crm-local-completion-map'.
+
+Unlike `completing-read-multiple', the return value is not split
+into a list."
+  (let* ((crm-separator (or sep crm-default-separator))
+         (crm-completion-table (magit--completion-table choices))
+         (choose-completion-string-functions
+          '(crm--choose-completion-string))
+         (minibuffer-completion-table #'crm--collection-fn)
+         (minibuffer-completion-confirm t)
+         (helm-completion-in-region-default-sort-fn nil)
+         (input
+          (cl-letf (((symbol-function 'completion-pcm--all-completions)
+                     #'magit-completion-pcm--all-completions))
+            (read-from-minibuffer
+             (concat prompt (and default (format " (%s)" default)) ": ")
+             nil (or keymap crm-local-completion-map)
+             nil hist default))))
+    (when (string-equal input "")
+      (or (setq input default)
+          (user-error "Nothing selected")))
+    input))
+
+(defun magit-ido-completing-read
+  (prompt choices &optional predicate require-match initial-input hist def)
+  "Ido-based `completing-read' almost-replacement.
+
+Unfortunately `ido-completing-read' is not suitable as a
+drop-in replacement for `completing-read', instead we use
+`ido-completing-read+' from the third-party package by the
+same name."
+  (if (require 'ido-completing-read+ nil t)
+      (ido-completing-read+ prompt choices predicate require-match
+                            initial-input hist def)
+    (display-warning 'magit "ido-completing-read+ is not installed
+
+To use Ido completion with Magit you need to install the
+third-party `ido-completing-read+' packages.  Falling
+back to built-in `completing-read' for now." :error)
+    (magit-builtin-completing-read prompt choices predicate require-match
+                                   initial-input hist def)))
+
+(defun magit-prompt-with-default (prompt def)
+  (if (and def (> (length prompt) 2)
+           (string-equal ": " (substring prompt -2)))
+      (format "%s (default %s): " (substring prompt 0 -2) def)
+    prompt))
+
+(defvar magit-minibuffer-local-ns-map
+  (let ((map (make-sparse-keymap)))
+    (set-keymap-parent map minibuffer-local-map)
+    (define-key map "\s" 'magit-whitespace-disallowed)
+    (define-key map "\t" 'magit-whitespace-disallowed)
+    map))
+
+(defun magit-whitespace-disallowed ()
+  "Beep to tell the user that whitespace is not allowed."
+  (interactive)
+  (ding)
+  (message "Whitespace isn't allowed here")
+  (setq defining-kbd-macro nil)
+  (force-mode-line-update))
+
+(defun magit-read-string (prompt &optional initial-input history default-value
+                                 inherit-input-method no-whitespace)
+  "Read a string from the minibuffer, prompting with string PROMPT.
+
+This is similar to `read-string', but
+* empty input is only allowed if DEFAULT-VALUE is non-nil in
+  which case that is returned,
+* whitespace is not allowed and leading and trailing whitespace is
+  removed automatically if NO-WHITESPACE is non-nil,
+* \": \" is appended to PROMPT, and
+* an invalid DEFAULT-VALUE is silently ignored."
+  (when default-value
+    (when (consp default-value)
+      (setq default-value (car default-value)))
+    (unless (stringp default-value)
+      (setq default-value nil)))
+  (let* ((minibuffer-completion-table nil)
+         (val (read-from-minibuffer
+               (magit-prompt-with-default (concat prompt ": ") default-value)
+               initial-input (and no-whitespace magit-minibuffer-local-ns-map)
+               nil history default-value inherit-input-method))
+         (trim (lambda (regexp string)
+                 (save-match-data
+                   (if (string-match regexp string)
+                       (replace-match "" t t string)
+                     string)))))
+    (when (and (string= val "") default-value)
+      (setq val default-value))
+    (when no-whitespace
+      (setq val (funcall trim "\\`\\(?:[ \t\n\r]+\\)"
+                         (funcall trim "\\(?:[ \t\n\r]+\\)\\'" val))))
+    (cond ((string= val "")
+           (user-error "Need non-empty input"))
+          ((and no-whitespace (string-match-p "[\s\t\n]" val))
+           (user-error "Input contains whitespace"))
+          (t val))))
+
+(defun magit-read-string-ns (prompt &optional initial-input history
+                                    default-value inherit-input-method)
+  "Call `magit-read-string' with non-nil NO-WHITESPACE."
+  (magit-read-string prompt initial-input history default-value
+                     inherit-input-method t))
+
+(defmacro magit-read-char-case (prompt verbose &rest clauses)
+  (declare (indent 2)
+           (debug (form form &rest (characterp form body))))
+  `(pcase (read-char-choice
+           (concat ,prompt
+                   ,(concat (mapconcat 'cadr clauses ", ")
+                            (and verbose ", or [C-g] to abort") " "))
+           ',(mapcar 'car clauses))
+     ,@(--map `(,(car it) ,@(cddr it)) clauses)))
+
+(defun magit-y-or-n-p (prompt &optional action)
+  "Ask user a \"y or n\" or a \"yes or no\" question using PROMPT.
+Which kind of question is used depends on whether
+ACTION is a member of option `magit-slow-confirm'."
+  (if (or (eq magit-slow-confirm t)
+          (and action (member action magit-slow-confirm)))
+      (yes-or-no-p prompt)
+    (y-or-n-p prompt)))
+
+(defvar magit--no-confirm-alist
+  '((safe-with-wip magit-wip-before-change-mode
+                   discard reverse stage-all-changes unstage-all-changes)))
+
+(cl-defun magit-confirm (action &optional prompt prompt-n noabort
+                                (items nil sitems))
+  (declare (indent defun))
+  (setq prompt-n (format (concat (or prompt-n prompt) "? ") (length items)))
+  (setq prompt   (format (concat (or prompt (magit-confirm-make-prompt action))
+                                 "? ")
+                         (car items)))
+  (or (cond ((and (not (eq action t))
+                  (or (eq magit-no-confirm t)
+                      (memq action magit-no-confirm)
+                      (cl-member-if (pcase-lambda (`(,key ,var . ,sub))
+                                      (and (memq key magit-no-confirm)
+                                           (memq action sub)
+                                           (or (not var)
+                                               (and (boundp var)
+                                                    (symbol-value var)))))
+                                    magit--no-confirm-alist)))
+             (or (not sitems) items))
+            ((not sitems)
+             (magit-y-or-n-p prompt action))
+            ((= (length items) 1)
+             (and (magit-y-or-n-p prompt action) items))
+            ((> (length items) 1)
+             (and (magit-y-or-n-p (concat (mapconcat #'identity items "\n")
+                                          "\n\n" prompt-n)
+                                  action)
+                  items)))
+      (if noabort nil (user-error "Abort"))))
+
+(defun magit-confirm-files (action files &optional prompt)
+  (when files
+    (unless prompt
+      (setq prompt (magit-confirm-make-prompt action)))
+    (magit-confirm action
+      (concat prompt " %s")
+      (concat prompt " %i files")
+      nil files)))
+
+(defun magit-confirm-make-prompt (action)
+  (let ((prompt (symbol-name action)))
+    (replace-regexp-in-string
+     "-" " " (concat (upcase (substring prompt 0 1)) (substring prompt 1)))))
+
+;;; Debug Utilities
+
+;;;###autoload
+(defun magit-emacs-Q-command ()
+  "Show a shell command that runs an uncustomized Emacs with only Magit loaded.
+See info node `(magit)Debugging Tools' for more information."
+  (interactive)
+  (let ((cmd (mapconcat
+              #'shell-quote-argument
+              `(,(concat invocation-directory invocation-name)
+                "-Q" "--eval" "(setq debug-on-error t)"
+                ,@(cl-mapcan
+                   (lambda (dir) (list "-L" dir))
+                   (delete-dups
+                    (mapcar (lambda (lib)
+                              (file-name-directory (locate-library lib)))
+                            '("magit" "magit-popup" "with-editor"
+                              "git-commit" "dash" "ghub"))))
+                ;; Avoid Emacs bug#16406 by using full path.
+                "-l" ,(file-name-sans-extension (locate-library "magit")))
+              " ")))
+    (message "Uncustomized Magit command saved to kill-ring, %s"
+             "please run it in a terminal.")
+    (kill-new cmd)))
+
+;;; Text Utilities
+
+(defmacro magit-bind-match-strings (varlist string &rest body)
+  "Bind variables to submatches according to VARLIST then evaluate BODY.
+Bind the symbols in VARLIST to submatches of the current match
+data, starting with 1 and incrementing by 1 for each symbol.  If
+the last match was against a string, then that has to be provided
+as STRING."
+  (declare (indent 2) (debug (listp form body)))
+  (let ((s (cl-gensym "string"))
+        (i 0))
+    `(let ((,s ,string))
+       (let ,(save-match-data
+               (--map (list it (list 'match-string (cl-incf i) s)) varlist))
+         ,@body))))
+
+(defun magit-delete-line ()
+  "Delete the rest of the current line."
+  (delete-region (point) (1+ (line-end-position))))
+
+(defun magit-delete-match (&optional num)
+  "Delete text matched by last search.
+If optional NUM is specified, only delete that subexpression."
+  (delete-region (match-beginning (or num 0))
+                 (match-end (or num 0))))
+
+(defun magit-file-line (file)
+  "Return the first line of FILE as a string."
+  (when (file-regular-p file)
+    (with-temp-buffer
+      (insert-file-contents file)
+      (buffer-substring-no-properties (point-min)
+                                      (line-end-position)))))
+
+(defun magit-file-lines (file &optional keep-empty-lines)
+  "Return a list of strings containing one element per line in FILE.
+Unless optional argument KEEP-EMPTY-LINES is t, trim all empty lines."
+  (when (file-regular-p file)
+    (with-temp-buffer
+      (insert-file-contents file)
+      (split-string (buffer-string) "\n" (not keep-empty-lines)))))
+
+(defun magit-set-header-line-format (string)
+  "Set the header-line using STRING.
+Propertize STRING with the `magit-header-line' face if no face is
+present, and pad the left and right sides of STRING equally such
+that it will align with the text area."
+  (let* ((header-line
+          (concat (propertize " "
+                              'display
+                              '(space :align-to 0))
+                  string
+                  (propertize
+                   " "
+                   'display
+                   `(space :width (+ left-fringe
+                                     left-margin
+                                     ,@(and (eq (car (window-current-scroll-bars))
+                                                'left)
+                                            '(scroll-bar)))))))
+         (len (length header-line)))
+    (setq header-line-format
+          (if (text-property-not-all 0 len 'face nil header-line)
+              (let ((face (get-text-property 0 'face string)))
+                (when (and (atom face)
+                           (magit-face-property-all face string))
+                  (add-face-text-property 0 1 face nil header-line)
+                  (add-face-text-property (1- len) len face nil header-line))
+                header-line)
+            (propertize header-line
+                        'face
+                        'magit-header-line)))))
+
+(defun magit-face-property-all (face string)
+  "Return non-nil if FACE is present in all of STRING."
+  (cl-loop for pos = 0 then (next-single-property-change pos 'face string)
+           unless pos
+             return t
+           for current = (get-text-property pos 'face string)
+           unless (if (consp current)
+                      (memq face current)
+                    (eq face current))
+             return nil))
+
+(defun magit--format-spec (format specification)
+  "Like `format-spec' but preserve text properties in SPECIFICATION."
+  (with-temp-buffer
+    (insert format)
+    (goto-char (point-min))
+    (while (search-forward "%" nil t)
+      (cond
+       ;; Quoted percent sign.
+       ((eq (char-after) ?%)
+        (delete-char 1))
+       ;; Valid format spec.
+       ((looking-at "\\([-0-9.]*\\)\\([a-zA-Z]\\)")
+        (let* ((num (match-string 1))
+               (spec (string-to-char (match-string 2)))
+               (val (assq spec specification)))
+          (unless val
+            (error "Invalid format character: `%%%c'" spec))
+          (setq val (cdr val))
+          ;; Pad result to desired length.
+          (let ((text (format (concat "%" num "s") val)))
+            ;; Insert first, to preserve text properties.
+            (if (next-property-change 0 (concat " " text))
+                ;; If the inserted text has properties, then preserve those.
+                (insert text)
+              ;; Otherwise preserve FORMAT's properties, like `format-spec'.
+              (insert-and-inherit text))
+            ;; Delete the specifier body.
+            (delete-region (+ (match-beginning 0) (length text))
+                           (+ (match-end 0) (length text)))
+            ;; Delete the percent sign.
+            (delete-region (1- (match-beginning 0)) (match-beginning 0)))))
+       ;; Signal an error on bogus format strings.
+       (t
+        (error "Invalid format string"))))
+    (buffer-string)))
+
+;;; Missing from Emacs
+
+(defun magit-kill-this-buffer ()
+  "Kill the current buffer."
+  (interactive)
+  (kill-buffer (current-buffer)))
+
+;;; Kludges for Emacs Bugs
+
+(defun magit-file-accessible-directory-p (filename)
+  "Like `file-accessible-directory-p' but work around an Apple bug.
+See http://debbugs.gnu.org/cgi/bugreport.cgi?bug=21573#17
+and https://github.com/magit/magit/issues/2295."
+  (and (file-directory-p filename)
+       (file-accessible-directory-p filename)))
+
+(when (version<= "25.1" emacs-version)
+  (with-eval-after-load 'vc-git
+    (defun vc-git-conflicted-files (directory)
+      "Return the list of files with conflicts in DIRECTORY."
+      (let* ((status
+              (vc-git--run-command-string directory "diff-files"
+                                          "--name-status"))
+             (lines (when status (split-string status "\n" 'omit-nulls)))
+             files)
+        (dolist (line lines files)
+          (when (string-match "\\([ MADRCU?!]\\)[ \t]+\\(.+\\)" line)
+            (let ((state (match-string 1 line))
+                  (file (match-string 2 line)))
+              (when (equal state "U")
+                (push (expand-file-name file directory) files)))))))))
+
+;; `completion-pcm--all-completions' reverses the completion list.  To
+;; preserve the order of our pre-sorted completions, we'll temporarily
+;; override it with the function below.  bug#24676
+(defun magit-completion-pcm--all-completions (prefix pattern table pred)
+  (if (completion-pcm--pattern-trivial-p pattern)
+      (all-completions (concat prefix (car pattern)) table pred)
+    (let* ((regex (completion-pcm--pattern->regex pattern))
+           (case-fold-search completion-ignore-case)
+           (completion-regexp-list (cons regex completion-regexp-list))
+           (compl (all-completions
+                   (concat prefix
+                           (if (stringp (car pattern)) (car pattern) ""))
+                   table pred)))
+      (if (not (functionp table))
+          compl
+        (let ((poss ()))
+          (dolist (c compl)
+            (when (string-match-p regex c) (push c poss)))
+          ;; This `nreverse' call is the only code change made to the
+          ;; `completion-pcm--all-completions' that shipped with Emacs 25.1.
+          (nreverse poss))))))
+
+;;; Kludges for Incompatible Modes
+
+(defvar whitespace-mode)
+
+(defun whitespace-dont-turn-on-in-magit-mode (fn)
+  "Prevent `whitespace-mode' from being turned on in Magit buffers.
+
+Because `whitespace-mode' uses font-lock and Magit does not, they
+are not compatible.  Therefore you cannot turn on that minor-mode
+in Magit buffers.  If you try to enable it anyway, then this
+advice prevents that.
+
+If the reason the attempt is made is that `global-whitespace-mode'
+is enabled, then that is done silently.  However if you call the local
+minor-mode interactively, then that results in an error.
+
+See `magit-diff-paint-whitespace' for an alternative."
+  (if (not (derived-mode-p 'magit-mode))
+      (funcall fn)
+    (setq whitespace-mode nil)
+    (when (eq this-command 'whitespace-mode)
+      (user-error
+       "Whitespace mode NOT enabled because it is not compatible with Magit"))))
+
+(advice-add 'whitespace-turn-on :around
+            'whitespace-dont-turn-on-in-magit-mode)
+
+;;; Kludges for Custom
+
+(defun magit-custom-initialize-reset (symbol exp)
+  "Initialize SYMBOL based on EXP.
+Set the symbol, using `set-default' (unlike
+`custom-initialize-reset' which uses the `:set' function if any.)
+The value is either the symbol's current value
+ (as obtained using the `:get' function), if any,
+or the value in the symbol's `saved-value' property if any,
+or (last of all) the value of EXP."
+  (set-default-toplevel-value
+   symbol
+   (condition-case nil
+       (let ((def (default-toplevel-value symbol))
+             (getter (get symbol 'custom-get)))
+         (if getter (funcall getter symbol) def))
+     (error
+      (eval (let ((sv (get symbol 'saved-value)))
+              (if sv (car sv) exp)))))))
+
+(defun magit-hook-custom-get (symbol)
+  (if (symbol-file symbol 'defvar)
+      (default-toplevel-value symbol)
+    ;;
+    ;; Called by `custom-initialize-reset' on behalf of `symbol's
+    ;; `defcustom', which is being evaluated for the first time to
+    ;; set the initial value, but there's already a default value,
+    ;; which most likely was established by one or more `add-hook'
+    ;; calls.
+    ;;
+    ;; We combine the `standard-value' and the current value, while
+    ;; preserving the order established by `:options', and return
+    ;; the result of that to be used as the "initial" default value.
+    ;;
+    (let ((standard (eval (car (get symbol 'standard-value))))
+          (current (default-toplevel-value symbol))
+          (value nil))
+      (dolist (fn (get symbol 'custom-options))
+        (when (or (memq fn standard)
+                  (memq fn current))
+          (push fn value)))
+      (dolist (fn current)
+        (unless (memq fn value)
+          (push fn value)))
+      (nreverse value))))
+
+;;; Kludges for Info Manuals
+
+;;;###autoload
+(defun Info-follow-nearest-node--magit-gitman (fn &optional fork)
+  (if magit-view-git-manual-method
+      (let ((node (Info-get-token
+                   (point) "\\*note[ \n\t]+"
+                   "\\*note[ \n\t]+\\([^:]*\\):\\(:\\|[ \n\t]*(\\)?")))
+        (if (and node (string-match "^(gitman)\\(.+\\)" node))
+            (pcase magit-view-git-manual-method
+              (`man   (require 'man)
+                      (man (match-string 1 node)))
+              (`woman (require 'woman)
+                      (woman (match-string 1 node)))
+              (_
+               (user-error "Invalid value for `magit-view-git-documentation'")))
+          (funcall fn fork)))
+    (funcall fn fork)))
+
+;;;###autoload
+(advice-add 'Info-follow-nearest-node :around
+            'Info-follow-nearest-node--magit-gitman)
+
+;;;###autoload
+(defun org-man-export--magit-gitman (fn link description format)
+  (if (and (eq format 'texinfo)
+           (string-match-p "\\`git" link))
+      (replace-regexp-in-string "%s" link "
+@ifinfo
+@ref{%s,,,gitman,}.
+@end ifinfo
+@ifhtml
+@html
+the <a href=\"http://git-scm.com/docs/%s\">%s(1)</a> manpage.
+@end html
+@end ifhtml
+@iftex
+the %s(1) manpage.
+@end iftex
+")
+    (funcall fn link description format)))
+
+;;;###autoload
+(advice-add 'org-man-export :around
+            'org-man-export--magit-gitman)
+
+;;; Miscellaneous
+
+(defun magit-message (format-string &rest args)
+  "Display a message at the bottom of the screen, or not.
+Like `message', except that if the users configured option
+`magit-no-message' to prevent the message corresponding to
+FORMAT-STRING to be displayed, then don't."
+  (unless (--first (string-prefix-p it format-string) magit-no-message)
+    (apply #'message format-string args)))
+
+(defun magit-msg (format-string &rest args)
+  "Display a message at the bottom of the screen, but don't log it.
+Like `message', except that `message-log-max' is bound to nil."
+  (let ((message-log-max nil))
+    (apply #'message format-string args)))
+
+(provide 'magit-utils)
+;;; magit-utils.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-utils.elc b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-utils.elc
new file mode 100644
index 0000000000..f9ca175574
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-utils.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-wip.el b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-wip.el
new file mode 100644
index 0000000000..228434b952
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-wip.el
@@ -0,0 +1,286 @@
+;;; magit-wip.el --- commit snapshots to work-in-progress refs  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2010-2018  The Magit Project Contributors
+;;
+;; You should have received a copy of the AUTHORS.md file which
+;; lists all contributors.  If not, see http://magit.vc/authors.
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; Magit 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, or (at your option)
+;; any later version.
+;;
+;; Magit 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 Magit.  If not, see http://www.gnu.org/licenses.
+
+;;; Commentary:
+
+;; This library defines tree global modes which automatically commit
+;; snapshots to branch-specific work-in-progress refs before and after
+;; making changes, and two commands which can be used to do so on
+;; demand.
+
+;;; Code:
+
+(require 'magit-core)
+(require 'magit-log)
+
+;;; Options
+
+(defgroup magit-wip nil
+  "Automatically commit to work-in-progress refs."
+  :link '(info-link "(magit)Wip Modes")
+  :group 'magit-modes
+  :group 'magit-essentials)
+
+(defcustom magit-wip-after-save-local-mode-lighter " sWip"
+  "Lighter for Magit-Wip-After-Save-Local mode."
+  :package-version '(magit . "2.1.0")
+  :group 'magit-wip
+  :type 'string)
+
+(defcustom magit-wip-after-apply-mode-lighter " aWip"
+  "Lighter for Magit-Wip-After-Apply mode."
+  :package-version '(magit . "2.1.0")
+  :group 'magit-wip
+  :type 'string)
+
+(defcustom magit-wip-before-change-mode-lighter " cWip"
+  "Lighter for Magit-Wip-Before-Change mode."
+  :package-version '(magit . "2.1.0")
+  :group 'magit-wip
+  :type 'string)
+
+(defcustom magit-wip-namespace "refs/wip/"
+  "Namespace used for work-in-progress refs.
+The wip refs are named \"<namespace/>index/<branchref>\"
+and \"<namespace/>wtree/<branchref>\".  When snapshots
+are created while the `HEAD' is detached then \"HEAD\"
+is used as `branch-ref'."
+  :package-version '(magit . "2.1.0")
+  :group 'magit-wip
+  :type 'string)
+
+;;; Modes
+
+(define-minor-mode magit-wip-after-save-local-mode
+  "After saving, also commit to a worktree work-in-progress ref.
+
+After saving the current file-visiting buffer this mode also
+commits the changes to the worktree work-in-progress ref for
+the current branch.
+
+This mode should be enabled globally by turning on the globalized
+variant `magit-wip-after-save-mode'."
+  :package-version '(magit . "2.1.0")
+  :lighter magit-wip-after-save-local-mode-lighter
+  (if magit-wip-after-save-local-mode
+      (if (and buffer-file-name (magit-inside-worktree-p t))
+          (add-hook 'after-save-hook 'magit-wip-commit-buffer-file t t)
+        (setq magit-wip-after-save-local-mode nil)
+        (user-error "Need a worktree and a file"))
+    (remove-hook 'after-save-hook 'magit-wip-commit-buffer-file t)))
+
+(defun magit-wip-after-save-local-mode-turn-on ()
+  (and buffer-file-name
+       (magit-inside-worktree-p t)
+       (magit-file-tracked-p buffer-file-name)
+       (magit-wip-after-save-local-mode)))
+
+;;;###autoload
+(define-globalized-minor-mode magit-wip-after-save-mode
+  magit-wip-after-save-local-mode magit-wip-after-save-local-mode-turn-on
+  :package-version '(magit . "2.1.0")
+  :group 'magit-wip)
+
+(defun magit-wip-commit-buffer-file ()
+  "Commit visited file to a worktree work-in-progress ref.
+
+Also see `magit-wip-after-save-mode' which calls this function
+automatically whenever a buffer visiting a tracked file is saved."
+  (interactive)
+  (--when-let (magit-wip-get-ref)
+    (magit-with-toplevel
+      (let ((file (file-relative-name buffer-file-name)))
+        (magit-wip-commit-worktree
+         it (list file) (if (called-interactively-p 'any)
+                            (format "wip-save %s after save" file)
+                          (format "autosave %s after save" file)))))))
+
+;;;###autoload
+(define-minor-mode magit-wip-after-apply-mode
+  "Commit to work-in-progress refs.
+
+After applying a change using any \"apply variant\"
+command (apply, stage, unstage, discard, and reverse) commit the
+affected files to the current wip refs.  For each branch there
+may be two wip refs; one contains snapshots of the files as found
+in the worktree and the other contains snapshots of the entries
+in the index."
+  :package-version '(magit . "2.1.0")
+  :group 'magit-wip
+  :lighter magit-wip-after-apply-mode-lighter
+  :global t)
+
+(defun magit-wip-commit-after-apply (&optional files msg)
+  (when magit-wip-after-apply-mode
+    (magit-wip-commit files msg)))
+
+;;;###autoload
+(define-minor-mode magit-wip-before-change-mode
+  "Commit to work-in-progress refs before certain destructive changes.
+
+Before invoking a revert command or an \"apply variant\"
+command (apply, stage, unstage, discard, and reverse) commit the
+affected tracked files to the current wip refs.  For each branch
+there may be two wip refs; one contains snapshots of the files
+as found in the worktree and the other contains snapshots of the
+entries in the index.
+
+Only changes to files which could potentially be affected by the
+command which is about to be called are committed."
+  :package-version '(magit . "2.1.0")
+  :group 'magit-wip
+  :lighter magit-wip-before-change-mode-lighter
+  :global t)
+
+(defun magit-wip-commit-before-change (&optional files msg)
+  (when magit-wip-before-change-mode
+    (magit-with-toplevel
+      (magit-wip-commit files msg))))
+
+;;; Core
+
+(defun magit-wip-commit (&optional files msg)
+  "Commit all tracked files to the work-in-progress refs.
+
+Interactively, commit all changes to all tracked files using
+a generic commit message.  With a prefix-argument the commit
+message is read in the minibuffer.
+
+Non-interactively, only commit changes to FILES using MSG as
+commit message."
+  (interactive (list nil (if current-prefix-arg
+                             (magit-read-string "Wip commit message")
+                           "wip-save tracked files")))
+  (--when-let (magit-wip-get-ref)
+    (magit-wip-commit-index it files msg)
+    (magit-wip-commit-worktree it files msg)))
+
+(defun magit-wip-commit-index (ref files msg &optional cached-only)
+  (let* ((wipref (concat magit-wip-namespace "index/" ref))
+         (parent (magit-wip-get-parent ref wipref)))
+    (when (magit-git-failure "diff-index" "--quiet"
+                             (and cached-only "--cached")
+                             parent "--" files)
+      (magit-wip-update-wipref wipref (magit-git-string "write-tree")
+                               parent files msg "index"))))
+
+(defun magit-wip-commit-worktree (ref files msg)
+  (let* ((wipref (concat magit-wip-namespace "wtree/" ref))
+         (parent (magit-wip-get-parent ref wipref))
+         (tree (magit-with-temp-index parent "--reset"
+                 (if files
+                     (magit-call-git "add" "--" files)
+                   (magit-with-toplevel
+                     (magit-call-git "add" "-u" ".")))
+                 (magit-git-string "write-tree"))))
+    (when (magit-git-failure "diff-tree" "--quiet" parent tree "--" files)
+      (magit-wip-update-wipref wipref tree parent files msg "worktree"))))
+
+(defun magit-wip-update-wipref (wipref tree parent files msg start-msg)
+  (let ((len (length files)))
+    (unless (and msg (not (= (aref msg 0) ?\s)))
+      (setq msg (concat
+                 (cond ((= len 0) "autosave tracked files")
+                       ((> len 1) (format "autosave %s files" len))
+                       (t (concat "autosave "
+                                  (file-relative-name (car files)
+                                                      (magit-toplevel)))))
+                 msg)))
+    (unless (equal parent wipref)
+      (setq start-msg (concat "restart autosaving " start-msg))
+      (magit-update-ref wipref start-msg
+                        (magit-git-string "commit-tree" "--no-gpg-sign"
+                                          "-p" parent "-m" start-msg
+                                          (concat parent "^{tree}")))
+      (setq parent wipref))
+    (magit-update-ref wipref msg
+                      (magit-git-string "commit-tree" "--no-gpg-sign"
+                                        "-p" parent "-m" msg tree))))
+
+(defun magit-wip-get-ref ()
+  (let ((ref (or (magit-git-string "symbolic-ref" "HEAD") "HEAD")))
+    (when (magit-rev-verify ref)
+      ref)))
+
+(defun magit-wip-get-parent (ref wipref)
+  (if (and (magit-rev-verify wipref)
+           (equal (magit-git-string "merge-base" wipref ref)
+                  (magit-rev-verify ref)))
+      wipref
+    ref))
+
+;;; Log
+
+(defun magit-wip-log-current (branch args files count)
+  "Show log for the current branch and its wip refs.
+With a negative prefix argument only show the worktree wip ref.
+The absolute numeric value of the prefix argument controls how
+many \"branches\" of each wip ref are shown."
+  (interactive
+   (nconc (list (or (magit-get-current-branch) "HEAD"))
+          (magit-log-arguments)
+          (list (prefix-numeric-value current-prefix-arg))))
+  (magit-wip-log branch args files count))
+
+(defun magit-wip-log (branch args files count)
+  "Show log for a branch and its wip refs.
+With a negative prefix argument only show the worktree wip ref.
+The absolute numeric value of the prefix argument controls how
+many \"branches\" of each wip ref are shown."
+  (interactive
+   (nconc (list (magit-completing-read
+                 "Log branch and its wip refs"
+                 (-snoc (magit-list-local-branch-names) "HEAD")
+                 nil t nil 'magit-revision-history
+                 (or (magit-branch-at-point)
+                     (magit-get-current-branch)
+                     "HEAD")))
+          (magit-log-arguments)
+          (list (prefix-numeric-value current-prefix-arg))))
+  (unless (equal branch "HEAD")
+    (setq branch (concat "refs/heads/" branch)))
+  (magit-log (nconc (list branch)
+                    (magit-wip-log-get-tips
+                     (concat magit-wip-namespace "wtree/" branch)
+                     (abs count))
+                    (and (>= count 0)
+                         (magit-wip-log-get-tips
+                          (concat magit-wip-namespace "index/" branch)
+                          (abs count))))
+             args files))
+
+(defun magit-wip-log-get-tips (wipref count)
+  (when-let ((reflog (magit-git-lines "reflog" wipref)))
+    (let (tips)
+      (while (and reflog (> count 1))
+        (setq reflog (cl-member "^[^ ]+ [^:]+: restart autosaving"
+                                reflog :test #'string-match-p))
+        (when (and (cadr reflog)
+                   (string-match "^[^ ]+ \\([^:]+\\)" (cadr reflog)))
+          (push (match-string 1 (cadr reflog)) tips))
+        (setq reflog (cddr reflog))
+        (cl-decf count))
+      (cons wipref (nreverse tips)))))
+
+(provide 'magit-wip)
+;;; magit-wip.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-wip.elc b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-wip.elc
new file mode 100644
index 0000000000..81bce5c006
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-wip.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-worktree.el b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-worktree.el
new file mode 100644
index 0000000000..a0b94a94c8
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-worktree.el
@@ -0,0 +1,173 @@
+;;; magit-worktree.el --- worktree support  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2010-2018  The Magit Project Contributors
+;;
+;; You should have received a copy of the AUTHORS.md file which
+;; lists all contributors.  If not, see http://magit.vc/authors.
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; Magit 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, or (at your option)
+;; any later version.
+;;
+;; Magit 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 Magit.  If not, see http://www.gnu.org/licenses.
+
+;;; Commentary:
+
+;; This library implements support for `git-worktree'.
+
+;;; Code:
+
+(require 'magit)
+
+;;; Commands
+
+;;;###autoload (autoload 'magit-worktree-popup "magit-worktree" nil t)
+(magit-define-popup magit-worktree-popup
+  "Popup console for worktree commands."
+  :man-page "git-worktree"
+  :actions  '((?b "Create new worktree"            magit-worktree-checkout)
+              (?c "Create new branch and worktree" magit-worktree-branch)
+              (?p "Create new worktree from pull-request"
+                  magit-worktree-checkout-pull-request)
+              (?k "Delete worktree"                magit-worktree-delete)
+              (?g "Show status for worktree"       magit-worktree-status))
+  :max-action-columns 1)
+
+;;;###autoload
+(defun magit-worktree-checkout (path branch)
+  "Checkout BRANCH in a new worktree at PATH."
+  (interactive
+   (let ((branch (magit-read-local-branch-or-commit "Checkout")))
+     (list (read-directory-name (format "Checkout %s in new worktree: " branch))
+           branch)))
+  (magit-run-git "worktree" "add" (expand-file-name path) branch)
+  (magit-diff-visit-directory path))
+
+(defun magit-worktree-checkout-pull-request (path pr)
+  "Create, configure and checkout a new worktree from a pull-request.
+This is like `magit-checkout-pull-request', except that it
+also creates a new worktree. Please see the manual for more
+information."
+  (interactive
+   (let ((pr (magit-read-pull-request "Checkout pull request")))
+     (let-alist pr
+       (let ((path (let ((branch (magit--pullreq-branch pr t)))
+                     (read-directory-name
+                      (format "Checkout #%s as `%s' in new worktree: "
+                              .number branch)
+                      (file-name-directory
+                       (directory-file-name default-directory))
+                      nil nil
+                      (if (string-match-p "\\`pr-[0-9]+\\'" branch)
+                          (number-to-string .number)
+                        (format "%s-%s" .number .head.ref))))))
+         (when (equal path "")
+           (user-error "The empty string isn't a valid path"))
+         (list path pr)))))
+  (when (and (file-exists-p path)
+             (not (and (file-directory-p path)
+                       (= (length (directory-files "/tmp/testing/")) 2))))
+    (user-error "%s already exists and isn't empty" path))
+  (magit-worktree-checkout path
+                           (let ((inhibit-magit-refresh t))
+                             (magit-branch-pull-request pr))))
+
+;;;###autoload
+(defun magit-worktree-branch (path branch start-point &optional force)
+  "Create a new BRANCH and check it out in a new worktree at PATH."
+  (interactive
+   `(,(read-directory-name "Create worktree: ")
+     ,@(butlast (magit-branch-read-args "Create and checkout branch"))
+     ,current-prefix-arg))
+  (magit-run-git "worktree" "add" (if force "-B" "-b")
+                 branch (expand-file-name path) start-point)
+  (magit-diff-visit-directory path))
+
+(defun magit-worktree-delete (worktree)
+  "Delete a worktree, defaulting to the worktree at point.
+The primary worktree cannot be deleted."
+  (interactive
+   (list (magit-completing-read "Delete worktree"
+                                (cdr (magit-list-worktrees))
+                                nil t nil nil
+                                (magit-section-when (worktree)))))
+  (if (file-directory-p (expand-file-name ".git" worktree))
+      (user-error "Deleting %s would delete the shared .git directory" worktree)
+    (let ((primary (file-name-as-directory (caar (magit-list-worktrees)))))
+      (magit-confirm-files (if magit-delete-by-moving-to-trash 'trash 'delete)
+                           (list "worktree"))
+      (when (file-exists-p worktree)
+        (let ((delete-by-moving-to-trash magit-delete-by-moving-to-trash))
+          (delete-directory worktree t magit-delete-by-moving-to-trash)))
+      (if (file-exists-p default-directory)
+          (magit-run-git "worktree" "prune")
+        (let ((default-directory primary))
+          (magit-run-git "worktree" "prune"))
+        (when (derived-mode-p 'magit-status-mode)
+          (kill-buffer)
+          (magit-status-internal primary))))))
+
+(defun magit-worktree-status (worktree)
+  "Show the status for the worktree at point.
+If there is no worktree at point, then read one in the
+minibuffer.  If the worktree at point is the one whose
+status is already being displayed in the current buffer,
+then show it in Dired instead."
+  (interactive
+   (list (or (magit-section-when (worktree))
+             (magit-completing-read
+              "Show status for worktree"
+              (cl-delete (directory-file-name (magit-toplevel))
+                         (magit-list-worktrees)
+                         :test #'equal :key #'car)))))
+  (magit-diff-visit-directory worktree))
+
+;;; Sections
+
+(defvar magit-worktree-section-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map [remap magit-visit-thing]  'magit-worktree-status)
+    (define-key map [remap magit-delete-thing] 'magit-worktree-delete)
+    map)
+  "Keymap for `worktree' sections.")
+
+(defun magit-insert-worktrees ()
+  "Insert sections for all worktrees.
+If there is only one worktree, then insert nothing."
+  (let ((worktrees (magit-list-worktrees)))
+    (when (> (length worktrees) 1)
+      (magit-insert-section (worktrees)
+        (magit-insert-heading "Worktrees:")
+        (let* ((cols
+                (mapcar (pcase-lambda (`(,path ,barep ,commit ,branch))
+                          (cons (cond
+                                 (branch (propertize branch
+                                                     'face 'magit-branch-local))
+                                 (commit (propertize (magit-rev-abbrev commit)
+                                                     'face 'magit-hash))
+                                 (barep  "(bare)"))
+                                path))
+                        worktrees))
+               (align (1+ (-max (--map (string-width (car it)) cols)))))
+          (pcase-dolist (`(,head . ,path) cols)
+            (magit-insert-section (worktree path)
+              (insert head)
+              (indent-to align)
+              (insert (let ((r (file-relative-name path))
+                            (a (abbreviate-file-name path)))
+                        (if (< (string-width r) (string-width a)) r a)))
+              (insert ?\n))))
+        (insert ?\n)))))
+
+(provide 'magit-worktree)
+;;; magit-worktree.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-worktree.elc b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-worktree.elc
new file mode 100644
index 0000000000..b8dbc10e9f
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit-worktree.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit.el b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit.el
new file mode 100644
index 0000000000..e307aacd31
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit.el
@@ -0,0 +1,616 @@
+;;; magit.el --- A Git porcelain inside Emacs  -*- lexical-binding: t; coding: utf-8 -*-
+
+;; Copyright (C) 2008-2018  The Magit Project Contributors
+;;
+;; You should have received a copy of the AUTHORS.md file which
+;; lists all contributors.  If not, see http://magit.vc/authors.
+
+;; Author: Marius Vollmer <marius.vollmer@gmail.com>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+;;	Kyle Meyer        <kyle@kyleam.com>
+;;	Noam Postavsky    <npostavs@users.sourceforge.net>
+;; Former-Maintainers:
+;;	Nicolas Dudebout  <nicolas.dudebout@gatech.edu>
+;;	Peter J. Weisberg <pj@irregularexpressions.net>
+;;	Phil Jackson      <phil@shellarchive.co.uk>
+;;	Rémi Vanicat      <vanicat@debian.org>
+;;	Yann Hodique      <yann.hodique@gmail.com>
+
+;; Keywords: git tools vc
+;; Homepage: https://github.com/magit/magit
+
+;; Magit requires at least GNU Emacs 25.1 and Git 1.9.4.
+
+;; Magit 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, or (at your option)
+;; any later version.
+;;
+;; Magit 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 Magit.  If not, see http://www.gnu.org/licenses.
+
+;;; Commentary:
+
+;; Magit is an interface to the version control system Git,
+;; implemented as an Emacs package.  Magit aspires to be a complete
+;; Git porcelain.  While we cannot (yet) claim, that Magit wraps and
+;; improves upon each and every Git command, it is complete enough to
+;; allow even experienced Git users to perform almost all of their
+;; daily version control tasks directly from within Emacs.  While many
+;; fine Git clients exist, only Magit and Git itself deserve to be
+;; called porcelains.
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'dash)
+
+(require 'with-editor)
+(require 'git-commit)
+(require 'magit-core)
+(require 'magit-diff)
+(require 'magit-apply)
+(require 'magit-log)
+(require 'magit-repos)
+
+(require 'format-spec)
+(require 'package nil t) ; used in `magit-version'
+
+(defconst magit--minimal-git "1.9.4")
+(defconst magit--minimal-emacs "25.1")
+
+;;; Faces
+
+(defface magit-header-line
+  '((t :inherit magit-section-heading))
+  "Face for the `header-line' in some Magit modes.
+Note that some modes, such as `magit-log-select-mode', have their
+own faces for the `header-line', or for parts of the
+`header-line'."
+  :group 'magit-faces)
+
+(defface magit-header-line-key
+  '((t :inherit magit-popup-key))
+  "Face for keys in the `header-line'."
+  :group 'magit-faces)
+
+(defface magit-dimmed
+  '((((class color) (background light)) :foreground "grey50")
+    (((class color) (background  dark)) :foreground "grey50"))
+  "Face for text that shouldn't stand out."
+  :group 'magit-faces)
+
+(defface magit-hash
+  '((((class color) (background light)) :foreground "grey60")
+    (((class color) (background  dark)) :foreground "grey40"))
+  "Face for the sha1 part of the log output."
+  :group 'magit-faces)
+
+(defface magit-tag
+  '((((class color) (background light)) :foreground "Goldenrod4")
+    (((class color) (background  dark)) :foreground "LightGoldenrod2"))
+  "Face for tag labels shown in log buffer."
+  :group 'magit-faces)
+
+(defface magit-branch-remote
+  '((((class color) (background light)) :foreground "DarkOliveGreen4")
+    (((class color) (background  dark)) :foreground "DarkSeaGreen2"))
+  "Face for remote branch head labels shown in log buffer."
+  :group 'magit-faces)
+
+(defface magit-branch-remote-head
+  '((((class color) (background light)) :inherit magit-branch-remote :box t)
+    (((class color) (background  dark)) :inherit magit-branch-remote :box t))
+  "Face for current branch."
+  :group 'magit-faces)
+
+(defface magit-branch-local
+  '((((class color) (background light)) :foreground "SkyBlue4")
+    (((class color) (background  dark)) :foreground "LightSkyBlue1"))
+  "Face for local branches."
+  :group 'magit-faces)
+
+(defface magit-branch-current
+  '((((class color) (background light)) :inherit magit-branch-local :box t)
+    (((class color) (background  dark)) :inherit magit-branch-local :box t))
+  "Face for current branch."
+  :group 'magit-faces)
+
+(defface magit-head
+  '((((class color) (background light)) :inherit magit-branch-local)
+    (((class color) (background  dark)) :inherit magit-branch-local))
+  "Face for the symbolic ref `HEAD'."
+  :group 'magit-faces)
+
+(defface magit-refname
+  '((((class color) (background light)) :foreground "grey30")
+    (((class color) (background  dark)) :foreground "grey80"))
+  "Face for refnames without a dedicated face."
+  :group 'magit-faces)
+
+(defface magit-refname-stash
+  '((t :inherit magit-refname))
+  "Face for stash refnames."
+  :group 'magit-faces)
+
+(defface magit-refname-wip
+  '((t :inherit magit-refname))
+  "Face for wip refnames."
+  :group 'magit-faces)
+
+(defface magit-refname-pullreq
+  '((t :inherit magit-refname))
+  "Face for pullreq refnames."
+  :group 'magit-faces)
+
+(defface magit-keyword
+  '((t :inherit font-lock-string-face))
+  "Face for parts of commit messages inside brackets."
+  :group 'magit-faces)
+
+(defface magit-keyword-squash
+  '((t :inherit font-lock-warning-face))
+  "Face for squash! and fixup! keywords in commit messages."
+  :group 'magit-faces)
+
+(defface magit-signature-good
+  '((t :foreground "green"))
+  "Face for good signatures."
+  :group 'magit-faces)
+
+(defface magit-signature-bad
+  '((t :foreground "red" :weight bold))
+  "Face for bad signatures."
+  :group 'magit-faces)
+
+(defface magit-signature-untrusted
+  '((t :foreground "cyan"))
+  "Face for good untrusted signatures."
+  :group 'magit-faces)
+
+(defface magit-signature-expired
+  '((t :foreground "orange"))
+  "Face for signatures that have expired."
+  :group 'magit-faces)
+
+(defface magit-signature-expired-key
+  '((t :inherit magit-signature-expired))
+  "Face for signatures made by an expired key."
+  :group 'magit-faces)
+
+(defface magit-signature-revoked
+  '((t :foreground "violet red"))
+  "Face for signatures made by a revoked key."
+  :group 'magit-faces)
+
+(defface magit-signature-error
+  '((t :foreground "firebrick3"))
+  "Face for signatures that cannot be checked (e.g. missing key)."
+  :group 'magit-faces)
+
+(defface magit-cherry-unmatched
+  '((t :foreground "cyan"))
+  "Face for unmatched cherry commits."
+  :group 'magit-faces)
+
+(defface magit-cherry-equivalent
+  '((t :foreground "magenta"))
+  "Face for equivalent cherry commits."
+  :group 'magit-faces)
+
+(defface magit-filename
+  '((t :weight normal))
+  "Face for filenames."
+  :group 'magit-faces)
+
+;;; Dispatch Popup
+
+;;;###autoload (autoload 'magit-dispatch-popup "magit" nil t)
+(magit-define-popup magit-dispatch-popup
+  "Popup console for dispatching other popups."
+  :actions '("Popup and dwim commands"
+             (?A "Cherry-picking"  magit-cherry-pick-popup)
+             (?b "Branching"       magit-branch-popup)
+             (?B "Bisecting"       magit-bisect-popup)
+             (?c "Committing"      magit-commit-popup)
+             (?d "Diffing"         magit-diff-popup)
+             (?D "Change diffs"    magit-diff-refresh-popup)
+             (?e "Ediff dwimming"  magit-ediff-dwim)
+             (?E "Ediffing"        magit-ediff-popup)
+             (?f "Fetching"        magit-fetch-popup)
+             (?F "Pulling"         magit-pull-popup)
+             (?l "Logging"         magit-log-popup)
+             (?L "Change logs"     magit-log-refresh-popup)
+             (?m "Merging"         magit-merge-popup)
+             (?M "Remoting"        magit-remote-popup)
+             (?o "Submodules"      magit-submodule-popup)
+             (?O "Subtrees"        magit-subtree-popup)
+             (?P "Pushing"         magit-push-popup)
+             (?r "Rebasing"        magit-rebase-popup)
+             (?t "Tagging"         magit-tag-popup)
+             (?T "Notes"           magit-notes-popup)
+             (?V "Reverting"       magit-revert-popup)
+             (?w "Apply patches"   magit-am-popup)
+             (?W "Format patches"  magit-patch-popup)
+             (?X "Resetting"       magit-reset-popup)
+             (?y "Show Refs"       magit-show-refs-popup)
+             (?z "Stashing"        magit-stash-popup)
+             (?! "Running"         magit-run-popup)
+             (?% "Worktree"        magit-worktree-popup)
+             (lambda ()
+               (and (with-current-buffer magit-pre-popup-buffer
+                      (derived-mode-p 'magit-mode))
+                    (propertize "Applying changes" 'face 'magit-popup-heading)))
+             (?a "Apply"           magit-apply)
+             (?s "Stage"           magit-stage)
+             (?u "Unstage"         magit-unstage)
+             (?v "Reverse"         magit-reverse)
+             (?S "Stage all"       magit-stage-modified)
+             (?U "Unstage all"     magit-unstage-all)
+             (?k "Discard"         magit-discard)
+             (lambda ()
+               (and (with-current-buffer magit-pre-popup-buffer
+                      (derived-mode-p 'magit-mode))
+                    (propertize "Essential commands" 'face 'magit-popup-heading)))
+             (?g  "    refresh current buffer"   magit-refresh)
+             ;; These bindings only work because of :setup-function.
+             (?\t   "  toggle section at point"  magit-section-toggle)
+             (?\r   "  visit thing at point"     magit-visit-thing)
+             ;; This binding has no effect and only appears to do
+             ;; so because it is identical to the global binding.
+             ("C-h m" "show all key bindings"    describe-mode))
+  :setup-function 'magit-dispatch-popup-setup
+  :max-action-columns (lambda (heading)
+                        (pcase heading
+                          ("Popup and dwim commands" 4)
+                          ("Applying changes" 3)
+                          ("Essential commands" 1))))
+
+(defvar magit-dispatch-popup-map
+  (let ((map (make-sparse-keymap)))
+    (set-keymap-parent map magit-popup-mode-map)
+    (cond ((featurep 'jkl)
+           (define-key map [tab]    'magit-invoke-popup-action)
+           (define-key map [return] 'magit-invoke-popup-action))
+          (t
+           (define-key map (kbd "C-i") 'magit-invoke-popup-action)
+           (define-key map (kbd "C-m") 'magit-invoke-popup-action)))
+    map)
+  "Keymap used by `magit-dispatch-popup'.")
+
+(defun magit-dispatch-popup-setup (val def)
+  (magit-popup-default-setup val def)
+  (use-local-map magit-dispatch-popup-map)
+  ;; This is necessary for users (i.e. me) who have broken the
+  ;; connection between C-i (aka TAB) and tab, and C-m (aka RET)
+  ;; and return.
+  (magit-popup-put
+   :actions (nconc (magit-popup-get :actions)
+                   (list (make-magit-popup-event :key 'tab
+                                                 :fun 'magit-section-toggle)
+                         (make-magit-popup-event :key 'return
+                                                 :fun 'magit-visit-thing)))))
+
+;;; Git Popup
+
+(defcustom magit-shell-command-verbose-prompt t
+  "Whether to show the working directory when reading a command.
+This affects `magit-git-command', `magit-git-command-topdir',
+`magit-shell-command', and `magit-shell-command-topdir'."
+  :package-version '(magit . "2.11.0")
+  :group 'magit-commands
+  :type 'boolean)
+
+(defvar magit-git-command-history nil)
+
+;;;###autoload (autoload 'magit-run-popup "magit" nil t)
+(magit-define-popup magit-run-popup
+  "Popup console for running raw Git commands."
+  :actions '((?! "Git Subcommand (in topdir)" magit-git-command-topdir)
+             (?k "Gitk"                       magit-run-gitk)
+             (?p "Git Subcommand (in pwd)"    magit-git-command)
+             (?a "Gitk --all"                 magit-run-gitk-all)
+             (?s "Shell command (in topdir)"  magit-shell-command-topdir)
+             (?b "Gitk --branches"            magit-run-gitk-branches)
+             (?S "Shell command (in pwd)"     magit-shell-command)
+             (?g "Git Gui"                    magit-run-git-gui))
+  :default-action 'magit-git-command
+  :max-action-columns 2)
+
+;;;###autoload
+(defun magit-git-command (command)
+  "Execute COMMAND asynchronously; display output.
+
+Interactively, prompt for COMMAND in the minibuffer. \"git \" is
+used as initial input, but can be deleted to run another command.
+
+With a prefix argument COMMAND is run in the top-level directory
+of the current working tree, otherwise in `default-directory'."
+  (interactive (list (magit-read-shell-command nil "git ")))
+  (magit--shell-command command))
+
+;;;###autoload
+(defun magit-git-command-topdir (command)
+  "Execute COMMAND asynchronously; display output.
+
+Interactively, prompt for COMMAND in the minibuffer. \"git \" is
+used as initial input, but can be deleted to run another command.
+
+COMMAND is run in the top-level directory of the current
+working tree."
+  (interactive (list (magit-read-shell-command t "git ")))
+  (magit--shell-command command (magit-toplevel)))
+
+;;;###autoload
+(defun magit-shell-command (command)
+  "Execute COMMAND asynchronously; display output.
+
+Interactively, prompt for COMMAND in the minibuffer.  With a
+prefix argument COMMAND is run in the top-level directory of
+the current working tree, otherwise in `default-directory'."
+  (interactive (list (magit-read-shell-command)))
+  (magit--shell-command command))
+
+;;;###autoload
+(defun magit-shell-command-topdir (command)
+  "Execute COMMAND asynchronously; display output.
+
+Interactively, prompt for COMMAND in the minibuffer.  COMMAND
+is run in the top-level directory of the current working tree."
+  (interactive (list (magit-read-shell-command t)))
+  (magit--shell-command command (magit-toplevel)))
+
+(defun magit--shell-command (command &optional directory)
+  (let ((default-directory (or directory default-directory))
+        (process-environment process-environment))
+    (push "GIT_PAGER=cat" process-environment)
+    (magit-start-process shell-file-name nil
+                         shell-command-switch command))
+  (magit-process-buffer))
+
+(defun magit-read-shell-command (&optional toplevel initial-input)
+  (let ((dir (abbreviate-file-name
+              (if (or toplevel current-prefix-arg)
+                  (or (magit-toplevel)
+                      (magit--not-inside-repository-error))
+                default-directory))))
+    (read-shell-command (if magit-shell-command-verbose-prompt
+                            (format "Async shell command in %s: " dir)
+                          "Async shell command: ")
+                        initial-input 'magit-git-command-history)))
+
+;;; Font-Lock Keywords
+
+(defconst magit-font-lock-keywords
+  (eval-when-compile
+    `((,(concat "(\\(magit-define-section-jumper\\)\\_>"
+                "[ \t'\(]*"
+                "\\(\\(?:\\sw\\|\\s_\\)+\\)?")
+       (1 'font-lock-keyword-face)
+       (2 'font-lock-function-name-face nil t))
+      (,(concat "(" (regexp-opt '("magit-insert-section"
+                                  "magit-section-case"
+                                  "magit-section-when"
+                                  "magit-bind-match-strings"
+                                  "magit-with-temp-index"
+                                  "magit-with-blob"
+                                  "magit-with-toplevel") t)
+                "\\_>")
+       . 1))))
+
+(font-lock-add-keywords 'emacs-lisp-mode magit-font-lock-keywords)
+
+;;; Version
+
+(defvar magit-version 'undefined
+  "The version of Magit that you're using.
+Use the function by the same name instead of this variable.")
+
+;;;###autoload
+(defun magit-version (&optional print-dest)
+  "Return the version of Magit currently in use.
+If optional argument PRINT-DEST is non-nil, output
+stream (interactively, the echo area, or the current buffer with
+a prefix argument), also print the used versions of Magit, Git,
+and Emacs to it."
+  (interactive (list (if current-prefix-arg (current-buffer) t)))
+  (let ((magit-git-global-arguments nil)
+        (toplib (or load-file-name buffer-file-name))
+        debug)
+    (unless (and toplib
+                 (equal (file-name-nondirectory toplib) "magit.el"))
+      (setq toplib (locate-library "magit.el")))
+    (setq toplib (and toplib (file-chase-links toplib)))
+    (push toplib debug)
+    (when toplib
+      (let* ((topdir (file-name-directory toplib))
+             (gitdir (expand-file-name
+                      ".git" (file-name-directory
+                              (directory-file-name topdir))))
+             (static (locate-library "magit-version.el" nil (list topdir)))
+             (static (and static (file-chase-links static))))
+        (or (progn
+              (push 'repo debug)
+              (when (and (file-exists-p gitdir)
+                         ;; It is a repo, but is it the Magit repo?
+                         (file-exists-p
+                          (expand-file-name "../lisp/magit.el" gitdir)))
+                (push t debug)
+                ;; Inside the repo the version file should only exist
+                ;; while running make.
+                (when (and static (not noninteractive))
+                  (ignore-errors (delete-file static)))
+                (setq magit-version
+                      (let ((default-directory topdir))
+                        (magit-git-string "describe" "--tags" "--dirty")))))
+            (progn
+              (push 'static debug)
+              (when (and static (file-exists-p static))
+                (push t debug)
+                (load-file static)
+                magit-version))
+            (when (featurep 'package)
+              (push 'elpa debug)
+              (ignore-errors
+                (--when-let (assq 'magit package-alist)
+                  (push t debug)
+                  (setq magit-version
+                        (and (fboundp 'package-desc-version)
+                             (package-version-join
+                              (package-desc-version (cadr it))))))))
+            (progn
+              (push 'debug debug)
+              (let ((dirname (file-name-nondirectory
+                              (directory-file-name topdir))))
+                (when (string-match "\\`magit-\\([0-9]\\{8\\}\\.[0-9]*\\)"
+                                    dirname)
+                  (setq magit-version (match-string 1 dirname))))))))
+    (if (stringp magit-version)
+        (when print-dest
+          (princ (format "Magit %s, Git %s, Emacs %s, %s"
+                         (or magit-version "(unknown)")
+                         (or (let ((magit-git-debug
+                                    (lambda (err)
+                                      (display-warning '(magit git)
+                                                       err :error))))
+                               (magit-git-version t))
+                             "(unknown)")
+                         emacs-version
+                         system-type)
+                 print-dest))
+      (setq debug (reverse debug))
+      (setq magit-version 'error)
+      (when magit-version
+        (push magit-version debug))
+      (unless (equal (getenv "TRAVIS") "true")
+        ;; The repository is a sparse clone.
+        (message "Cannot determine Magit's version %S" debug)))
+    magit-version))
+
+;;; Debugging Tools
+
+(defun magit-debug-git-executable ()
+  "Display a buffer with information about `magit-git-executable'.
+See info node `(magit)Debugging Tools' for more information."
+  (interactive)
+  (with-current-buffer (get-buffer-create "*magit-git-debug*")
+    (pop-to-buffer (current-buffer))
+    (erase-buffer)
+    (insert (concat
+             (format "magit-git-executable: %S" magit-git-executable)
+             (and (not (file-name-absolute-p magit-git-executable))
+                  (format " [%S]" (executable-find magit-git-executable)))
+             (format " (%s)\n"
+                     (let* ((errmsg nil)
+                            (magit-git-debug (lambda (err) (setq errmsg err))))
+                       (or (magit-git-version t) errmsg)))))
+    (insert (format "exec-path: %S\n" exec-path))
+    (--when-let (cl-set-difference
+                 (-filter #'file-exists-p (remq nil (parse-colon-path
+                                                     (getenv "PATH"))))
+                 (-filter #'file-exists-p (remq nil exec-path))
+                 :test #'file-equal-p)
+      (insert (format "  entries in PATH, but not in exec-path: %S\n" it)))
+    (dolist (execdir exec-path)
+      (insert (format "  %s (%s)\n" execdir (car (file-attributes execdir))))
+      (when (file-directory-p execdir)
+        (dolist (exec (directory-files
+                       execdir t (concat
+                                  "\\`git" (regexp-opt exec-suffixes) "\\'")))
+          (insert (format "    %s (%s)\n" exec
+                          (let* ((magit-git-executable exec)
+                                 (errmsg nil)
+                                 (magit-git-debug (lambda (err) (setq errmsg err))))
+                            (or (magit-git-version t) errmsg)))))))))
+
+;;; Startup Asserts
+
+(defun magit-startup-asserts ()
+  (when-let ((val (getenv "GIT_DIR")))
+    (setenv "GIT_DIR")
+    (message "Magit unset $GIT_DIR (was %S).  See \
+https://github.com/magit/magit/wiki/Don't-set-$GIT_DIR-and-alike" val))
+  (when-let ((val (getenv "GIT_WORK_TREE")))
+    (setenv "GIT_WORK_TREE")
+    (message "Magit unset $GIT_WORK_TREE (was %S).  See \
+https://github.com/magit/magit/wiki/Don't-set-$GIT_DIR-and-alike" val))
+  (let ((version (magit-git-version)))
+    (when (and version
+               (version< version magit--minimal-git)
+               (not (equal (getenv "TRAVIS") "true")))
+      (display-warning 'magit (format "\
+Magit requires Git >= %s, you are using %s.
+
+If this comes as a surprise to you, because you do actually have
+a newer version installed, then that probably means that the
+older version happens to appear earlier on the `$PATH'.  If you
+always start Emacs from a shell, then that can be fixed in the
+shell's init file.  If you start Emacs by clicking on an icon,
+or using some sort of application launcher, then you probably
+have to adjust the environment as seen by graphical interface.
+For X11 something like ~/.xinitrc should work.
+
+If you use Tramp to work inside remote Git repositories, then you
+have to make sure a suitable Git is used on the remote machines
+too.\n" magit--minimal-git version) :error)))
+  (when (version< emacs-version magit--minimal-emacs)
+    (display-warning 'magit (format "\
+Magit requires Emacs >= %s, you are using %s.
+
+If this comes as a surprise to you, because you do actually have
+a newer version installed, then that probably means that the
+older version happens to appear earlier on the `$PATH'.  If you
+always start Emacs from a shell, then that can be fixed in the
+shell's init file.  If you start Emacs by clicking on an icon,
+or using some sort of application launcher, then you probably
+have to adjust the environment as seen by graphical interface.
+For X11 something like ~/.xinitrc should work.\n"
+                                    magit--minimal-emacs emacs-version)
+                     :error)))
+
+;;; Loading Libraries
+
+(provide 'magit)
+
+(cl-eval-when (load eval)
+  (require 'magit-status)
+  (require 'magit-refs)
+  (require 'magit-files)
+  (require 'magit-collab)
+  (require 'magit-reset)
+  (require 'magit-branch)
+  (require 'magit-merge)
+  (require 'magit-tag)
+  (require 'magit-worktree)
+  (require 'magit-notes)
+  (require 'magit-sequence)
+  (require 'magit-commit)
+  (require 'magit-remote)
+  (require 'magit-bisect)
+  (require 'magit-stash)
+  (require 'magit-blame)
+  (require 'magit-obsolete)
+  (unless (load "magit-autoloads" t t)
+    (require 'magit-submodule)
+    (require 'magit-subtree)
+    (require 'magit-ediff)
+    (require 'magit-extras)
+    (require 'git-rebase)
+    (require 'magit-imenu)
+    (require 'magit-bookmark)))
+
+(eval-after-load 'bookmark
+  '(require 'magit-bookmark))
+
+(if after-init-time
+    (progn (magit-startup-asserts)
+           (magit-version))
+  (add-hook 'after-init-hook #'magit-startup-asserts t)
+  (add-hook 'after-init-hook #'magit-version t))
+
+;;; magit.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit.elc b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit.elc
new file mode 100644
index 0000000000..87658babfe
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit.info b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit.info
new file mode 100644
index 0000000000..3c0df930d8
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit.info
@@ -0,0 +1,182 @@
+This is magit.info, produced by makeinfo version 6.1 from magit.texi.
+
+     Copyright (C) 2015-2018 Jonas Bernoulli <jonas@bernoul.li>
+
+     You can redistribute this document 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.
+
+     This document 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.
+INFO-DIR-SECTION Emacs
+START-INFO-DIR-ENTRY
+* Magit: (magit).       Using Git from Emacs with Magit.
+END-INFO-DIR-ENTRY
+
+
+Indirect:
+magit.info-1: 753
+magit.info-2: 302698
+
+Tag Table:
+(Indirect)
+Node: Top753
+Node: Introduction6121
+Node: Installation10844
+Node: Installing from an Elpa Archive11184
+Node: Installing from the Git Repository12287
+Node: Post-Installation Tasks15040
+Node: Getting Started16325
+Node: Interface Concepts21672
+Node: Modes and Buffers22004
+Node: Switching Buffers23749
+Node: Naming Buffers28292
+Node: Quitting Windows31599
+Node: Automatic Refreshing of Magit Buffers33231
+Node: Automatic Saving of File-Visiting Buffers35999
+Node: Automatic Reverting of File-Visiting Buffers37184
+Node: Risk of Reverting Automatically42180
+Node: Sections44563
+Node: Section Movement45504
+Node: Section Visibility49601
+Node: Section Hooks54453
+Node: Section Types and Values56738
+Node: Section Options58008
+Node: Popup Buffers and Prefix Commands58480
+Node: Completion Confirmation and the Selection60861
+Node: Action Confirmation61298
+Node: Completion and Confirmation68644
+Node: The Selection71830
+Node: The hunk-internal region74729
+Node: Support for Completion Frameworks75818
+Node: Additional Completion Options80634
+Node: Running Git81233
+Node: Viewing Git Output81506
+Node: Git Process Status82639
+Node: Running Git Manually83604
+Node: Git Executable86006
+Node: Global Git Arguments88288
+Node: Inspecting89094
+Node: Status Buffer90241
+Node: Status Sections93005
+Node: Status Header Sections97808
+Node: Status Module Sections100438
+Node: Status Options102943
+Node: Repository List104697
+Node: Logging106855
+Node: Refreshing Logs109302
+Node: Log Buffer110687
+Node: Log Margin114482
+Node: Select from Log117122
+Node: Reflog119226
+Node: Cherries120743
+Node: Diffing122470
+Node: Refreshing Diffs125417
+Node: Diff Buffer128908
+Node: Diff Options133246
+Node: Revision Buffer137521
+Node: Ediffing140059
+Node: References Buffer143655
+Node: References Sections153420
+Node: Bisecting154281
+Node: Visiting Blobs156019
+Node: Blaming156529
+Node: Manipulating162304
+Node: Repository Setup162620
+Node: Staging and Unstaging163660
+Node: Staging from File-Visiting Buffers167741
+Node: Applying168909
+Node: Committing170802
+Node: Initiating a Commit171385
+Node: Editing Commit Messages174706
+Node: Branching185102
+Node: The Two Remotes185332
+Node: The Branch Popup187949
+Node: The Branch Config Popup205002
+Node: Auxillary Branch Commands210943
+Node: Merging212046
+Node: Resolving Conflicts215971
+Node: Rebasing220972
+Node: Editing Rebase Sequences225129
+Node: Information About In-Progress Rebase228159
+Ref: Information About In-Progress Rebase-Footnote-1236908
+Node: Cherry Picking237504
+Node: Reverting241756
+Node: Resetting243119
+Node: Stashing244536
+Node: Transferring249049
+Node: Remotes249287
+Node: The Remote Popup249443
+Node: The Remote Config Popup252911
+Node: Fetching254567
+Node: Pulling255923
+Node: Pushing256759
+Node: Creating and Sending Patches261494
+Node: Applying Patches262331
+Node: Miscellaneous263917
+Node: Tagging264233
+Node: Notes265574
+Node: Submodules267885
+Node: Listing Submodules268099
+Node: Submodule Popup270023
+Node: Subtree272476
+Node: Worktree273716
+Node: Common Commands274926
+Node: Wip Modes276673
+Node: Minor Mode for Buffers Visiting Files283470
+Node: Minor Mode for Buffers Visiting Blobs288877
+Node: Customizing289690
+Node: Per-Repository Configuration291358
+Node: Essential Settings293007
+Node: Safety293331
+Node: Performance295096
+Node: Microsoft Windows Performance302698
+Node: MacOS Performance303889
+Ref: MacOS Performance-Footnote-1305125
+Ref: MacOS Performance-Footnote-2305207
+Ref: MacOS Performance-Footnote-3305267
+Node: Plumbing305433
+Node: Calling Git306256
+Node: Getting a Value from Git307781
+Node: Calling Git for Effect310867
+Node: Section Plumbing317387
+Node: Creating Sections317615
+Node: Section Selection321515
+Node: Matching Sections323195
+Node: Refreshing Buffers328631
+Node: Conventions331773
+Node: Theming Faces331965
+Node: FAQ340080
+Node: FAQ - How to ...?340522
+Node: How to show git's output?340882
+Node: How to install the gitman info manual?341636
+Node: How to show diffs for gpg-encrypted files?342606
+Node: How does branching and pushing work?343202
+Node: Can Magit be used as ediff-version-control-package?343565
+Node: FAQ - Issues and Errors345554
+Node: Magit is slow346339
+Node: I changed several thousand files at once and now Magit is unusable346553
+Node: I am having problems committing347282
+Node: I am using MS Windows and cannot push with Magit347763
+Node: I am using OS X and SOMETHING works in shell but not in Magit348380
+Node: Diffs contain control sequences349186
+Node: Expanding a file to show the diff causes it to disappear350260
+Node: Point is wrong in the COMMIT_EDITMSG buffer350811
+Node: The mode-line information isn't always up-to-date351857
+Node: A branch and tag sharing the same name breaks SOMETHING352939
+Node: My Git hooks work on the command-line but not inside Magit353827
+Node: Debugging Tools354591
+Node: Keystroke Index356468
+Node: Command Index388335
+Node: Function Index423062
+Node: Variable Index438443
+
+End Tag Table
+
+
+Local Variables:
+coding: utf-8
+End:
diff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit.info-1 b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit.info-1
new file mode 100644
index 0000000000..c9c1382888
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit.info-1
@@ -0,0 +1,7844 @@
+This is magit.info, produced by makeinfo version 6.1 from magit.texi.
+
+     Copyright (C) 2015-2018 Jonas Bernoulli <jonas@bernoul.li>
+
+     You can redistribute this document 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.
+
+     This document 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.
+INFO-DIR-SECTION Emacs
+START-INFO-DIR-ENTRY
+* Magit: (magit).       Using Git from Emacs with Magit.
+END-INFO-DIR-ENTRY
+
+
+File: magit.info,  Node: Top,  Next: Introduction,  Up: (dir)
+
+Magit User Manual
+*****************
+
+Magit is an interface to the version control system Git, implemented as
+an Emacs package.  Magit aspires to be a complete Git porcelain.  While
+we cannot (yet) claim that Magit wraps and improves upon each and every
+Git command, it is complete enough to allow even experienced Git users
+to perform almost all of their daily version control tasks directly from
+within Emacs.  While many fine Git clients exist, only Magit and Git
+itself deserve to be called porcelains.
+
+This manual is for Magit version 2.13.0 (2.13.0-69-gbc8b275e+1).
+
+     Copyright (C) 2015-2018 Jonas Bernoulli <jonas@bernoul.li>
+
+     You can redistribute this document 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.
+
+     This document 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.
+
+* Menu:
+
+* Introduction::
+* Installation::
+* Getting Started::
+* Interface Concepts::
+* Inspecting::
+* Manipulating::
+* Transferring::
+* Miscellaneous::
+* Customizing::
+* Plumbing::
+* FAQ::
+* Debugging Tools::
+* Keystroke Index::
+* Command Index::
+* Function Index::
+* Variable Index::
+
+— The Detailed Node Listing —
+
+Installation
+
+* Installing from an Elpa Archive::
+* Installing from the Git Repository::
+* Post-Installation Tasks::
+
+Interface Concepts
+
+* Modes and Buffers::
+* Sections::
+* Popup Buffers and Prefix Commands::
+* Completion, Confirmation and the Selection: Completion Confirmation and the Selection. 
+* Running Git::
+
+Modes and Buffers
+
+* Switching Buffers::
+* Naming Buffers::
+* Quitting Windows::
+* Automatic Refreshing of Magit Buffers::
+* Automatic Saving of File-Visiting Buffers::
+* Automatic Reverting of File-Visiting Buffers::
+
+
+Sections
+
+* Section Movement::
+* Section Visibility::
+* Section Hooks::
+* Section Types and Values::
+* Section Options::
+
+
+Completion, Confirmation and the Selection
+
+* Action Confirmation::
+* Completion and Confirmation::
+* The Selection::
+* The hunk-internal region::
+* Support for Completion Frameworks::
+* Additional Completion Options::
+
+
+Running Git
+
+* Viewing Git Output::
+* Git Process Status::
+* Running Git Manually::
+* Git Executable::
+* Global Git Arguments::
+
+
+Inspecting
+
+* Status Buffer::
+* Repository List::
+* Logging::
+* Diffing::
+* Ediffing::
+* References Buffer::
+* Bisecting::
+* Visiting Blobs::
+* Blaming::
+
+Status Buffer
+
+* Status Sections::
+* Status Header Sections::
+* Status Module Sections::
+* Status Options::
+
+
+Logging
+
+* Refreshing Logs::
+* Log Buffer::
+* Log Margin::
+* Select from Log::
+* Reflog::
+* Cherries::
+
+
+Diffing
+
+* Refreshing Diffs::
+* Diff Buffer::
+* Diff Options::
+* Revision Buffer::
+
+
+References Buffer
+
+* References Sections::
+
+
+Manipulating
+
+* Repository Setup::
+* Staging and Unstaging::
+* Applying::
+* Committing::
+* Branching::
+* Merging::
+* Resolving Conflicts::
+* Rebasing::
+* Cherry Picking::
+* Resetting::
+* Stashing::
+
+Staging and Unstaging
+
+* Staging from File-Visiting Buffers::
+
+
+Committing
+
+* Initiating a Commit::
+* Editing Commit Messages::
+
+
+Branching
+
+* The Two Remotes::
+* The Branch Popup::
+* The Branch Config Popup::
+* Auxillary Branch Commands::
+
+
+Rebasing
+
+* Editing Rebase Sequences::
+* Information About In-Progress Rebase::
+
+
+Cherry Picking
+
+* Reverting::
+
+
+Transferring
+
+* Remotes::
+* Fetching::
+* Pulling::
+* Pushing::
+* Creating and Sending Patches::
+* Applying Patches::
+
+Remotes
+
+* The Remote Popup::
+* The Remote Config Popup::
+
+
+Miscellaneous
+
+* Tagging::
+* Notes::
+* Submodules::
+* Subtree::
+* Worktree::
+* Common Commands::
+* Wip Modes::
+* Minor Mode for Buffers Visiting Files::
+* Minor Mode for Buffers Visiting Blobs::
+
+Submodules
+
+* Listing Submodules::
+* Submodule Popup::
+
+
+Customizing
+
+* Per-Repository Configuration::
+* Essential Settings::
+
+Essential Settings
+
+* Safety::
+* Performance::
+
+
+Plumbing
+
+* Calling Git::
+* Section Plumbing::
+* Refreshing Buffers::
+* Conventions::
+
+Calling Git
+
+* Getting a Value from Git::
+* Calling Git for Effect::
+
+
+Section Plumbing
+
+* Creating Sections::
+* Section Selection::
+* Matching Sections::
+
+
+Conventions
+
+* Theming Faces::
+
+
+FAQ
+
+* FAQ - How to ...?::
+* FAQ - Issues and Errors::
+
+FAQ - How to ...?
+
+* How to show git's output?::
+* How to install the gitman info manual?::
+* How to show diffs for gpg-encrypted files?::
+* How does branching and pushing work?::
+* Can Magit be used as ediff-version-control-package?::
+
+
+FAQ - Issues and Errors
+
+* Magit is slow::
+* I changed several thousand files at once and now Magit is unusable::
+* I am having problems committing::
+* I am using MS Windows and cannot push with Magit::
+* I am using OS X and SOMETHING works in shell, but not in Magit: I am using OS X and SOMETHING works in shell but not in Magit. 
+* Diffs contain control sequences::
+* Expanding a file to show the diff causes it to disappear::
+* Point is wrong in the COMMIT_EDITMSG buffer::
+* The mode-line information isn't always up-to-date::
+* A branch and tag sharing the same name breaks SOMETHING::
+* My Git hooks work on the command-line but not inside Magit::
+
+
+
+
+File: magit.info,  Node: Introduction,  Next: Installation,  Prev: Top,  Up: Top
+
+1 Introduction
+**************
+
+Magit is an interface to the version control system Git, implemented as
+an Emacs package.  Magit aspires to be a complete Git porcelain.  While
+we cannot (yet) claim that Magit wraps and improves upon each and every
+Git command, it is complete enough to allow even experienced Git users
+to perform almost all of their daily version control tasks directly from
+within Emacs.  While many fine Git clients exist, only Magit and Git
+itself deserve to be called porcelains.
+
+   Staging and otherwise applying changes is one of the most important
+features in a Git porcelain and here Magit outshines anything else,
+including Git itself.  Git’s own staging interface (‘git add --patch’)
+is so cumbersome that many users only use it in exceptional cases.  In
+Magit staging a hunk or even just part of a hunk is as trivial as
+staging all changes made to a file.
+
+   The most visible part of Magit’s interface is the status buffer,
+which displays information about the current repository.  Its content is
+created by running several Git commands and making their output
+actionable.  Among other things, it displays information about the
+current branch, lists unpulled and unpushed changes and contains
+sections displaying the staged and unstaged changes.  That might sound
+noisy, but, since sections are collapsible, it’s not.
+
+   To stage or unstage a change one places the cursor on the change and
+then types ‘s’ or ‘u’.  The change can be a file or a hunk, or when the
+region is active (i.e.  when there is a selection) several files or
+hunks, or even just part of a hunk.  The change or changes that these
+commands - and many others - would act on are highlighted.
+
+   Magit also implements several other "apply variants" in addition to
+staging and unstaging.  One can discard or reverse a change, or apply it
+to the working tree.  Git’s own porcelain only supports this for staging
+and unstaging and you would have to do something like ‘git diff ... |
+??? | git apply ...’ to discard, revert, or apply a single hunk on the
+command line.  In fact that’s exactly what Magit does internally (which
+is what lead to the term "apply variants").
+
+   Magit isn’t just for Git experts, but it does assume some prior
+experience with Git as well as Emacs.  That being said, many users have
+reported that using Magit was what finally taught them what Git is
+capable of and how to use it to its fullest.  Other users wished they
+had switched to Emacs sooner so that they would have gotten their hands
+on Magit earlier.
+
+   While one has to know the basic features of Emacs to be able to make
+full use of Magit, acquiring just enough Emacs skills doesn’t take long
+and is worth it, even for users who prefer other editors.  Vim users are
+advised to give Evil (https://bitbucket.org/lyro/evil/wiki/Home), the
+"Extensible VI Layer for Emacs", and Spacemacs
+(https://github.com/syl20bnr/spacemacs), an "Emacs starter-kit focused
+on Evil" a try.
+
+   Magit provides a consistent and efficient Git porcelain.  After a
+short learning period, you will be able to perform most of your daily
+version control tasks faster than you would on the command line.  You
+will likely also start using features that seemed too daunting in the
+past.
+
+   Magit fully embraces Git.  It exposes many advanced features using a
+simple but flexible interface instead of only wrapping the trivial ones
+like many GUI clients do.  Of course Magit supports logging, cloning,
+pushing, and other commands that usually don’t fail in spectacular ways;
+but it also supports tasks that often cannot be completed in a single
+step.  Magit fully supports tasks such as merging, rebasing,
+cherry-picking, reverting, and blaming by not only providing a command
+to initiate these tasks but also by displaying context sensitive
+information along the way and providing commands that are useful for
+resolving conflicts and resuming the sequence after doing so.
+
+   Magit wraps and in many cases improves upon at least the following
+Git porcelain commands: ‘add’, ‘am’, ‘bisect’, ‘blame’, ‘branch’,
+‘checkout’, ‘cherry’, ‘cherry-pick’, ‘clean’, ‘clone’, ‘commit’,
+‘config’, ‘describe’, ‘diff’, ‘fetch’, ‘format-patch’, ‘init’, ‘log’,
+‘merge’, ‘merge-tree’, ‘mv’, ‘notes’, ‘pull’, ‘rebase’, ‘reflog’,
+‘remote’, ‘request-pull’, ‘reset’, ‘revert’, ‘rm’, ‘show’, ‘stash’,
+‘submodule’, ‘subtree’, ‘tag’, and ‘worktree.’ Many more Magit porcelain
+commands are implemented on top of Git plumbing commands.
+
+
+File: magit.info,  Node: Installation,  Next: Getting Started,  Prev: Introduction,  Up: Top
+
+2 Installation
+**************
+
+Magit can be installed using Emacs’ package manager or manually from its
+development repository.
+
+* Menu:
+
+* Installing from an Elpa Archive::
+* Installing from the Git Repository::
+* Post-Installation Tasks::
+
+
+File: magit.info,  Node: Installing from an Elpa Archive,  Next: Installing from the Git Repository,  Up: Installation
+
+2.1 Installing from an Elpa Archive
+===================================
+
+Magit is available from Melpa and Melpa-Stable.  If you haven’t used
+Emacs’ package manager before, then it is high time you familiarize
+yourself with it by reading the documentation in the Emacs manual, see
+*note (emacs)Packages::.  Then add one of the archives to
+‘package-archives’:
+
+   • To use Melpa:
+
+     (require 'package)
+     (add-to-list 'package-archives
+                  '("melpa" . "http://melpa.org/packages/") t)
+
+   • To use Melpa-Stable:
+
+     (require 'package)
+     (add-to-list 'package-archives
+                  '("melpa-stable" . "http://stable.melpa.org/packages/") t)
+
+   Once you have added your preferred archive, you need to update the
+local package list using:
+
+     M-x package-refresh-contents RET
+
+   Once you have done that, you can install Magit and its dependencies
+using:
+
+     M-x package-install RET magit RET
+
+   Now see *note Post-Installation Tasks::.
+
+
+File: magit.info,  Node: Installing from the Git Repository,  Next: Post-Installation Tasks,  Prev: Installing from an Elpa Archive,  Up: Installation
+
+2.2 Installing from the Git Repository
+======================================
+
+Magit depends on the ‘dash’, ‘magit-popup’, ‘ghub’ and ‘with-editor’
+libraries which are available from Melpa and Melpa-Stable.  Install them
+using ‘M-x package-install RET <package> RET’.  Of course you may also
+install them manually from their development repository.
+
+   (An ancient release of Magit is also available from Marmalade, but no
+new versions will be uploaded.  Marmalade is unmaintained — its
+maintainer has stopped responding to support requests from package
+authors or even just to create new accounts so that new authors can
+upload their packages in the first place.)
+
+   Then clone the Magit repository:
+
+     $ git clone https://github.com/magit/magit.git ~/.emacs.d/site-lisp/magit
+     $ cd ~/.emacs.d/site-lisp/magit
+
+   Then compile the libraries and generate the info manuals:
+
+     $ make
+
+   If you haven’t installed ‘dash’, ‘magit-popup’, ‘ghub’ and
+‘with-editor’ from Melpa or at ‘/path/to/magit/../<package>’, then you
+have to tell ‘make’ where to find them.  To do so create the file
+‘/path/to/magit/config.mk’ with the following content before running
+‘make’:
+
+     LOAD_PATH  = -L /path/to/magit/lisp
+     LOAD_PATH += -L /path/to/dash
+     LOAD_PATH += -L /path/to/magit-popup
+     LOAD_PATH += -L /path/to/ghub
+     LOAD_PATH += -L /path/to/with-editor
+
+   Finally add this to your init file:
+
+     (add-to-list 'load-path "~/.emacs.d/site-lisp/magit/lisp")
+     (require 'magit)
+
+     (with-eval-after-load 'info
+       (info-initialize)
+       (add-to-list 'Info-directory-list
+                    "~/.emacs.d/site-lisp/magit/Documentation/"))
+
+   Note that you have to add the ‘lisp’ subdirectory to the ‘load-path’,
+not the top-level of the repository, and that elements of ‘load-path’
+should not end with a slash, while those of ‘Info-directory-list’
+should.
+
+   Instead of requiring the feature ‘magit’, you could load just the
+autoload definitions, by loading the file ‘magit-autoloads.el’.
+
+     (load "/path/to/magit/lisp/magit-autoloads")
+
+   Instead of running Magit directly from the repository by adding that
+to the ‘load-path’, you might want to instead install it in some other
+directory using ‘sudo make install’ and setting ‘load-path’ accordingly.
+
+   To update Magit use:
+
+     $ git pull
+     $ make
+
+   At times it might be necessary to run ‘make clean all’ instead.
+
+   To view all available targets use ‘make help’.
+
+   Now see *note Post-Installation Tasks::.
+
+
+File: magit.info,  Node: Post-Installation Tasks,  Prev: Installing from the Git Repository,  Up: Installation
+
+2.3 Post-Installation Tasks
+===========================
+
+After installing Magit you should verify that you are indeed using the
+Magit, Git, and Emacs releases you think you are using.  It’s best to
+restart Emacs before doing so, to make sure you are not using an
+outdated value for ‘load-path’.
+
+     M-x magit-version RET
+
+   should display something like
+
+     Magit 2.8.0, Git 2.10.2, Emacs 25.1.1, gnu/linux
+
+   Then you might also want to read about options that many users likely
+want to customize.  See *note Essential Settings::.
+
+   To be able to follow cross references to Git manpages found in this
+manual, you might also have to manually install the ‘gitman’ info
+manual, or advice ‘Info-follow-nearest-node’ to instead open the actual
+manpage.  See *note How to install the gitman info manual?::.
+
+   If you are completely new to Magit then see *note Getting Started::.
+
+   If you run into problems, then please see the *note FAQ::.  Also see
+the *note Debugging Tools::.
+
+   And last but not least please consider making a donation, to ensure
+that I can keep working on Magit.  See <https://magit.vc/donations>.
+for various donation options.
+
+
+File: magit.info,  Node: Getting Started,  Next: Interface Concepts,  Prev: Installation,  Up: Top
+
+3 Getting Started
+*****************
+
+This short tutorial describes the most essential features that many
+Magitians use on a daily basis.  It only scratches the surface but
+should be enough to get you started.
+
+   IMPORTANT: It is safest if you clone some repository just for this
+tutorial.  Alternatively you can use an existing local repository, but
+if you do that, then you should commit all uncommitted changes before
+proceeding.
+
+   To display information about the current Git repository, type ‘M-x
+magit-status RET’.  You will be using this command a lot, and should
+therefore give it a global key binding.  This is what we recommend:
+
+     (global-set-key (kbd "C-x g") 'magit-status)
+
+   Most Magit commands are commonly invoked from the status buffer.  It
+can be considered the primary interface for interacting with Git using
+Magit.  Many other Magit buffers may exist at a given time, but they are
+often created from this buffer.
+
+   Depending on what state your repository is in, this buffer may
+contain sections titled "Staged changes", "Unstaged changes", "Unmerged
+into origin/master", "Unpushed to origin/master", and many others.
+
+   Since we are starting from a safe state, which you can easily return
+to (by doing a ‘git reset --hard PRE-MAGIT-STATE’), there currently are
+not staged or unstaged changes.  Edit some files and save the changes.
+Then go back to the status buffer, while at the same time refreshing it,
+by typing ‘C-x g’.  (When the status buffer, or any Magit buffer for
+that matter, is the current buffer, then you can also use just ‘g’ to
+refresh it).
+
+   Move between sections using ‘p’ and ‘n’.  Note that the bodies of
+some sections are hidden.  Type ‘TAB’ to expand or collapse the section
+at point.  You can also use ‘C-tab’ to cycle the visibility of the
+current section and its children.  Move to a file section inside the
+section named "Unstaged changes" and type ‘s’ to stage the changes you
+have made to that file.  That file now appears under "Staged changes".
+
+   Magit can stage and unstage individual hunks, not just complete
+files.  Move to the file you have just staged, expand it using ‘TAB’,
+move to one of the hunks using ‘n’, and unstage just that by typing ‘u’.
+Note how the staging (‘s’) and unstaging (‘u’) commands operate on the
+change at point.  Many other commands behave the same way.
+
+   You can also un-/stage just part of a hunk.  Inside the body of a
+hunk section (move there using ‘C-n’), set the mark using ‘C-SPC’ and
+move down until some added and/or removed lines fall inside the region
+but not all of them.  Again type ‘s’ to stage.
+
+   It is also possible to un-/stage multiple files at once.  Move to a
+file section, type ‘C-SPC’, move to the next file using ‘n’, and then
+‘s’ to stage both files.  Note that both the mark and point have to be
+on the headings of sibling sections for this to work.  If the region
+looks like it does in other buffers, then it doesn’t select Magit
+sections that can be acted on as a unit.
+
+   And then of course you want to commit your changes.  Type ‘c’.  This
+shows the committing popup buffer featuring various commit variants and
+arguments that can be passed to ‘git commit’.  Do not worry about those
+for now.  We want to create a "normal" commit, which is done by typing
+‘c’ again.
+
+   Now two new buffers appear.  One is for writing the commit message,
+the other shows a diff with the changes that you are about to committed.
+Write a message and then type ‘C-c C-c’ to actually create the commit.
+
+   You probably don’t want to push the commit you just created because
+you just committed some random changes, but if that is not the case you
+could push it by typing ‘P’ to bring up the push popup and then ‘p’ to
+push to a branch with the same name as the local branch onto the remote
+configured as the push-remote.  (If the push-remote is not configured
+yet, then you would first be prompted for the remote to push to.)
+
+   So far we have mentioned the commit, push, and log popups.  These are
+probably among the popups you will be using the most, but many others
+exist.  To show a popup that lists all other popups (as well as the
+various apply commands and some other fundamental commands), type ‘h’.
+Try a few.
+
+   The key bindings in that popup correspond to the bindings in Magit
+buffers, including but not limited to the status buffer.  So you could
+type ‘h d’ to bring up the diff popup, but once you remember that "d"
+stands for "diff", you would usually do so by just typing ‘d’.  But the
+"popup of popups" is useful even once you have memorized all the
+bindings, as it can provide easy access to Magit commands from non-Magit
+buffers.  You should create a global key binding for this command too:
+
+     (global-set-key (kbd "C-x M-g") 'magit-dispatch-popup)
+
+   In the same vein, you might also want to enable
+‘global-magit-file-mode’ to get some more Magit key bindings in regular
+file-visiting buffers (see *note Minor Mode for Buffers Visiting
+Files::).
+
+   It is not necessary that you do so now, but if you stick with Magit,
+then it is highly recommended that you read the next section too.
+
+
+File: magit.info,  Node: Interface Concepts,  Next: Inspecting,  Prev: Getting Started,  Up: Top
+
+4 Interface Concepts
+********************
+
+* Menu:
+
+* Modes and Buffers::
+* Sections::
+* Popup Buffers and Prefix Commands::
+* Completion, Confirmation and the Selection: Completion Confirmation and the Selection. 
+* Running Git::
+
+
+File: magit.info,  Node: Modes and Buffers,  Next: Sections,  Up: Interface Concepts
+
+4.1 Modes and Buffers
+=====================
+
+Magit provides several major-modes.  For each of these modes there
+usually exists only one buffer per repository.  Separate modes and thus
+buffers exist for commits, diffs, logs, and some other things.
+
+   Besides these special purpose buffers, there also exists an overview
+buffer, called the *status buffer*.  Its usually from this buffer that
+the user invokes Git commands, or creates or visits other buffers.
+
+   In this manual we often speak about "Magit buffers".  By that we mean
+buffers whose major-modes derive from ‘magit-mode’.
+
+‘M-x magit-toggle-buffer-lock’     (‘magit-toggle-buffer-lock’)
+
+     This command locks the current buffer to its value or if the buffer
+     is already locked, then it unlocks it.
+
+     Locking a buffer to its value prevents it from being reused to
+     display another value.  The name of a locked buffer contains its
+     value, which allows telling it apart from other locked buffers and
+     the unlocked buffer.
+
+     Not all Magit buffers can be locked to their values, for example it
+     wouldn’t make sense to lock a status buffer.
+
+     There can only be a single unlocked buffer using a certain
+     major-mode per repository.  So when a buffer is being unlocked and
+     another unlocked buffer already exists for that mode and
+     repository, then the former buffer is instead deleted and the
+     latter is displayed in its place.
+
+* Menu:
+
+* Switching Buffers::
+* Naming Buffers::
+* Quitting Windows::
+* Automatic Refreshing of Magit Buffers::
+* Automatic Saving of File-Visiting Buffers::
+* Automatic Reverting of File-Visiting Buffers::
+
+
+File: magit.info,  Node: Switching Buffers,  Next: Naming Buffers,  Up: Modes and Buffers
+
+4.1.1 Switching Buffers
+-----------------------
+
+ -- Function: magit-display-buffer buffer
+
+     This function is a wrapper around ‘display-buffer’ and is used to
+     display any Magit buffer.  It displays BUFFER in some window and,
+     unlike ‘display-buffer’, also selects that window, provided
+     ‘magit-display-buffer-noselect’ is ‘nil’.  It also runs the hooks
+     mentioned below.
+
+ -- Variable: magit-display-buffer-noselect
+
+     When this is non-nil, then ‘magit-display-buffer’ only displays the
+     buffer but forgoes also selecting the window.  This variable should
+     not be set globally, it is only intended to be let-bound, by code
+     that automatically updates "the other window".  This is used for
+     example when the revision buffer is updated when you move inside
+     the log buffer.
+
+ -- User Option: magit-display-buffer-function
+
+     The function specified here is called by ‘magit-display-buffer’
+     with one argument, a buffer, to actually display that buffer.  This
+     function should call ‘display-buffer’ with that buffer as first and
+     a list of display actions as second argument.
+
+     Magit provides several functions, listed below, that are suitable
+     values for this option.  If you want to use different rules, then a
+     good way of doing that is to start with a copy of one of these
+     functions and then adjust it to your needs.
+
+     Instead of using a wrapper around ‘display-buffer’, that function
+     itself can be used here, in which case the display actions have to
+     be specified by adding them to ‘display-buffer-alist’ instead.
+
+     To learn about display actions, see *note (elisp)Choosing a Window
+     for Display::.
+
+ -- Function: magit-display-buffer-traditional buffer
+
+     This function is the current default value of the option
+     ‘magit-display-buffer-function’.  Before that option and this
+     function were added, the behavior was hard-coded in many places all
+     over the code base but now all the rules are contained in this one
+     function (except for the "noselect" special case mentioned above).
+
+ -- Function: magit-display-buffer-same-window-except-diff-v1
+
+     This function displays most buffers in the currently selected
+     window.  If a buffer’s mode derives from ‘magit-diff-mode’ or
+     ‘magit-process-mode’, it is displayed in another window.
+
+ -- Function: magit-display-buffer-fullframe-status-v1
+
+     This function fills the entire frame when displaying a status
+     buffer.  Otherwise, it behaves like
+     ‘magit-display-buffer-traditional’.
+
+ -- Function: magit-display-buffer-fullframe-status-topleft-v1
+
+     This function fills the entire frame when displaying a status
+     buffer.  It behaves like ‘magit-display-buffer-fullframe-status-v1’
+     except that it displays buffers that derive from ‘magit-diff-mode’
+     or ‘magit-process-mode’ to the top or left of the current buffer
+     rather than to the bottom or right.  As a result, Magit buffers
+     tend to pop up on the same side as they would if
+     ‘magit-display-buffer-traditional’ were in use.
+
+ -- Function: magit-display-buffer-fullcolumn-most-v1
+
+     This function displays most buffers so that they fill the entire
+     height of the frame.  However, the buffer is displayed in another
+     window if (1) the buffer’s mode derives from ‘magit-process-mode’,
+     or (2) the buffer’s mode derives from ‘magit-diff-mode’, provided
+     that the mode of the current buffer derives from ‘magit-log-mode’
+     or ‘magit-cherry-mode’.
+
+ -- User Option: magit-pre-display-buffer-hook
+
+     This hook is run by ‘magit-display-buffer’ before displaying the
+     buffer.
+
+ -- Function: magit-save-window-configuration
+
+     This function saves the current window configuration.  Later when
+     the buffer is buried, it may be restored by
+     ‘magit-restore-window-configuration’.
+
+ -- User Option: magit-post-display-buffer-hook
+
+     This hook is run by ‘magit-display-buffer’ after displaying the
+     buffer.
+
+ -- Function: magit-maybe-set-dedicated
+
+     This function remembers if a new window had to be created to
+     display the buffer, or whether an existing window was reused.  This
+     information is later used by ‘magit-mode-quit-window’, to determine
+     whether the window should be deleted when its last Magit buffer is
+     buried.
+
+
+File: magit.info,  Node: Naming Buffers,  Next: Quitting Windows,  Prev: Switching Buffers,  Up: Modes and Buffers
+
+4.1.2 Naming Buffers
+--------------------
+
+ -- User Option: magit-generate-buffer-name-function
+
+     The function used to generate the names of Magit buffers.
+
+     Such a function should take the options
+     ‘magit-uniquify-buffer-names’ as well as ‘magit-buffer-name-format’
+     into account.  If it doesn’t, then should be clearly stated in the
+     doc-string.  And if it supports %-sequences beyond those mentioned
+     in the doc-string of the option ‘magit-buffer-name-format’, then
+     its own doc-string should describe the additions.
+
+ -- Function: magit-generate-buffer-name-default-function mode
+
+     This function returns a buffer name suitable for a buffer whose
+     major-mode is MODE and which shows information about the repository
+     in which ‘default-directory’ is located.
+
+     This function uses ‘magit-buffer-name-format’ and supporting all of
+     the %-sequences mentioned the documentation of that option.  It
+     also respects the option ‘magit-uniquify-buffer-names’.
+
+ -- User Option: magit-buffer-name-format
+
+     The format string used to name Magit buffers.
+
+     At least the following %-sequences are supported:
+
+        • ‘%m’
+
+          The name of the major-mode, but with the ‘-mode’ suffix
+          removed.
+
+        • ‘%M’
+
+          Like ‘%m’ but abbreviate ‘magit-status-mode’ as ‘magit’.
+
+        • ‘%v’
+
+          The value the buffer is locked to, in parentheses, or an empty
+          string if the buffer is not locked to a value.
+
+        • ‘%V’
+
+          Like ‘%v’, but the string is prefixed with a space, unless it
+          is an empty string.
+
+        • ‘%t’
+
+          The top-level directory of the working tree of the repository,
+          or if ‘magit-uniquify-buffer-names’ is non-nil an abbreviation
+          of that.
+
+        • ‘%x’
+
+          If ‘magit-uniquify-buffer-names’ is nil "*", otherwise the
+          empty string.  Due to limitations of the ‘uniquify’ package,
+          buffer names must end with the path.
+
+        • ‘%T’
+
+          Obsolete, use "%t%x" instead.  Like ‘%t’, but append an
+          asterisk if and only if ‘magit-uniquify-buffer-names’ is nil.
+
+     The value should always contain ‘%m’ or ‘%M’, ‘%v’ or ‘%V’, and
+     ‘%t’ (or the obsolete ‘%T’).  If ‘magit-uniquify-buffer-names’ is
+     non-nil, then the value must end with ‘%t’ or ‘%t%x’ (or the
+     obsolete ‘%T’).  See issue #2841.
+
+ -- User Option: magit-uniquify-buffer-names
+
+     This option controls whether the names of Magit buffers are
+     uniquified.  If the names are not being uniquified, then they
+     contain the full path of the top-level of the working tree of the
+     corresponding repository.  If they are being uniquified, then they
+     end with the basename of the top-level, or if that would conflict
+     with the name used for other buffers, then the names of all these
+     buffers are adjusted until they no longer conflict.
+
+     This is done using the ‘uniquify’ package; customize its options to
+     control how buffer names are uniquified.
+
+
+File: magit.info,  Node: Quitting Windows,  Next: Automatic Refreshing of Magit Buffers,  Prev: Naming Buffers,  Up: Modes and Buffers
+
+4.1.3 Quitting Windows
+----------------------
+
+‘q’     (‘magit-mode-bury-buffer’)
+
+     This command buries the current Magit buffer.  With a prefix
+     argument, it instead kills the buffer.
+
+ -- User Option: magit-bury-buffer-function
+
+     The function used to actually bury or kill the current buffer.
+
+     ‘magit-mode-bury-buffer’ calls this function with one argument.  If
+     the argument is non-nil, then the function has to kill the current
+     buffer.  Otherwise it has to bury it alive.  The default value
+     currently is ‘magit-restore-window-configuration’.
+
+ -- Function: magit-restore-window-configuration kill-buffer
+
+     Bury or kill the current buffer using ‘quit-window’, which is
+     called with KILL-BUFFER as first and the selected window as second
+     argument.
+
+     Then restore the window configuration that existed right before the
+     current buffer was displayed in the selected frame.  Unfortunately
+     that also means that point gets adjusted in all the buffers, which
+     are being displayed in the selected frame.
+
+ -- Function: magit-mode-quit-window kill-buffer
+
+     Bury or kill the current buffer using ‘quit-window’, which is
+     called with KILL-BUFFER as first and the selected window as second
+     argument.
+
+     Then, if the window was originally created to display a Magit
+     buffer and the buried buffer was the last remaining Magit buffer
+     that was ever displayed in the window, then that is deleted.
+
+
+File: magit.info,  Node: Automatic Refreshing of Magit Buffers,  Next: Automatic Saving of File-Visiting Buffers,  Prev: Quitting Windows,  Up: Modes and Buffers
+
+4.1.4 Automatic Refreshing of Magit Buffers
+-------------------------------------------
+
+After running a command which may change the state of the current
+repository, the current Magit buffer and the corresponding status buffer
+are refreshed.  The status buffer may optionally be automatically
+refreshed whenever a buffer is saved to a file inside the respective
+repository.
+
+   Automatically refreshing Magit buffers ensures that the displayed
+information is up-to-date most of the time but can lead to a noticeable
+delay in big repositories.  Other Magit buffers are not refreshed to
+keep the delay to a minimum and also because doing so can sometimes be
+undesirable.
+
+   Buffers can also be refreshed explicitly, which is useful in buffers
+that weren’t current during the last refresh and after changes were made
+to the repository outside of Magit.
+
+‘g’     (‘magit-refresh’)
+
+     This command refreshes the current buffer if its major mode derives
+     from ‘magit-mode’ as well as the corresponding status buffer.
+
+     If the option ‘magit-revert-buffers’ calls for it, then it also
+     reverts all unmodified buffers that visit files being tracked in
+     the current repository.
+
+‘G’     (‘magit-refresh-all’)
+
+     This command refreshes all Magit buffers belonging to the current
+     repository and also reverts all unmodified buffers that visit files
+     being tracked in the current repository.
+
+     The file-visiting buffers are always reverted, even if
+     ‘magit-revert-buffers’ is nil.
+
+ -- User Option: magit-refresh-buffer-hook
+
+     This hook is run in each Magit buffer that was refreshed during the
+     current refresh - normally the current buffer and the status
+     buffer.
+
+ -- User Option: magit-refresh-status-buffer
+
+     When this option is non-nil, then the status buffer is
+     automatically refreshed after running git for side-effects, in
+     addition to the current Magit buffer, which is always refreshed
+     automatically.
+
+     Only set this to nil after exhausting all other options to improve
+     performance.
+
+ -- Function: magit-after-save-refresh-status
+
+     This function is intended to be added to ‘after-save-hook’.  After
+     doing that the corresponding status buffer is refreshed whenever a
+     buffer is saved to a file inside a repository.
+
+     Note that refreshing a Magit buffer is done by re-creating its
+     contents from scratch, which can be slow in large repositories.  If
+     you are not satisfied with Magit’s performance, then you should
+     obviously not add this function to that hook.
+
+
+File: magit.info,  Node: Automatic Saving of File-Visiting Buffers,  Next: Automatic Reverting of File-Visiting Buffers,  Prev: Automatic Refreshing of Magit Buffers,  Up: Modes and Buffers
+
+4.1.5 Automatic Saving of File-Visiting Buffers
+-----------------------------------------------
+
+File-visiting buffers are by default saved at certain points in time.
+This doesn’t guarantee that Magit buffers are always up-to-date, but,
+provided one only edits files by editing them in Emacs and uses only
+Magit to interact with Git, one can be fairly confident.  When in doubt
+or after outside changes, type ‘g’ (‘magit-refresh’) to save and refresh
+explicitly.
+
+ -- User Option: magit-save-repository-buffers
+
+     This option controls whether file-visiting buffers are saved before
+     certain events.
+
+     If this is non-nil then all modified file-visiting buffers
+     belonging to the current repository may be saved before running
+     commands, before creating new Magit buffers, and before explicitly
+     refreshing such buffers.  If this is ‘dontask’ then this is done
+     without user intervention.  If it is ‘t’ then the user has to
+     confirm each save.
+
+
+File: magit.info,  Node: Automatic Reverting of File-Visiting Buffers,  Prev: Automatic Saving of File-Visiting Buffers,  Up: Modes and Buffers
+
+4.1.6 Automatic Reverting of File-Visiting Buffers
+--------------------------------------------------
+
+By default Magit automatically reverts buffers that are visiting files
+that are being tracked in a Git repository, after they have changed on
+disk.  When using Magit one often changes files on disk by running git,
+i.e.  "outside Emacs", making this a rather important feature.
+
+   For example, if you discard a change in the status buffer, then that
+is done by running ‘git apply --reverse ...’, and Emacs considers the
+file to have "changed on disk".  If Magit did not automatically revert
+the buffer, then you would have to type ‘M-x revert-buffer RET RET’ in
+the visiting buffer before you could continue making changes.
+
+ -- User Option: magit-auto-revert-mode
+
+     When this mode is enabled, then buffers that visit tracked files,
+     are automatically reverted after the visited files changed on disk.
+
+ -- User Option: global-auto-revert-mode
+
+     When this mode is enabled, then any file-visiting buffer is
+     automatically reverted after the visited file changed on disk.
+
+     If you like buffers that visit tracked files to be automatically
+     reverted, then you might also like any buffer to be reverted, not
+     just those visiting tracked files.  If that is the case, then
+     enable this mode _instead of_ ‘magit-auto-revert-mode’.
+
+ -- User Option: magit-auto-revert-immediately
+
+     This option controls whether Magit reverts buffers immediately.
+
+     If this is non-nil and either ‘global-auto-revert-mode’ or
+     ‘magit-auto-revert-mode’ is enabled, then Magit immediately reverts
+     buffers by explicitly calling ‘auto-revert-buffers’ after running
+     git for side-effects.
+
+     If ‘auto-revert-use-notify’ is non-nil (and file notifications are
+     actually supported), then ‘magit-auto-revert-immediately’ does not
+     have to be non-nil, because the reverts happen immediately anyway.
+
+     If ‘magit-auto-revert-immediately’ and ‘auto-revert-use-notify’ are
+     both ‘nil’, then reverts happen after ‘auto-revert-interval’
+     seconds of user inactivity.  That is not desirable.
+
+ -- User Option: auto-revert-use-notify
+
+     This option controls whether file notification functions should be
+     used.  Note that this variable unfortunately defaults to ‘t’ even
+     on systems on which file notifications cannot be used.
+
+ -- User Option: magit-auto-revert-tracked-only
+
+     This option controls whether ‘magit-auto-revert-mode’ only reverts
+     tracked files or all files that are located inside Git
+     repositories, including untracked files and files located inside
+     Git’s control directory.
+
+ -- Command: auto-revert-mode
+
+     The global mode ‘magit-auto-revert-mode’ works by turning on this
+     local mode in the appropriate buffers (but
+     ‘global-auto-revert-mode’ is implemented differently).  You can
+     also turn it on or off manually, which might be necessary if Magit
+     does not notice that a previously untracked file now is being
+     tracked or vice-versa.
+
+ -- User Option: auto-revert-stop-on-user-input
+
+     This option controls whether the arrival of user input suspends the
+     automatic reverts for ‘auto-revert-interval’ seconds.
+
+ -- User Option: auto-revert-interval
+
+     This option controls for how many seconds Emacs waits before
+     resuming suspended reverts.
+
+ -- User Option: auto-revert-buffer-list-filter
+
+     This option specifies an additional filter used by
+     ‘auto-revert-buffers’ to determine whether a buffer should be
+     reverted or not.
+
+     This option is provided by ‘magit’, which also redefines
+     ‘auto-revert-buffers’ to respect it.  Magit users who do not turn
+     on the local mode ‘auto-revert-mode’ themselves, are best served by
+     setting the value to ‘magit-auto-revert-repository-buffers-p’.
+
+     However the default is nil, to not disturb users who do use the
+     local mode directly.  If you experience delays when running Magit
+     commands, then you should consider using one of the predicates
+     provided by Magit - especially if you also use Tramp.
+
+     Users who do turn on ‘auto-revert-mode’ in buffers in which Magit
+     doesn’t do that for them, should likely not use any filter.  Users
+     who turn on ‘global-auto-revert-mode’, do not have to worry about
+     this option, because it is disregarded if the global mode is
+     enabled.
+
+ -- User Option: auto-revert-verbose
+
+     This option controls whether Emacs reports when a buffer has been
+     reverted.
+
+   The options with the ‘auto-revert-’ prefix are located in the Custom
+group named ‘auto-revert’.  The other, magit-specific, options are
+located in the ‘magit’ group.
+
+* Menu:
+
+* Risk of Reverting Automatically::
+
+
+File: magit.info,  Node: Risk of Reverting Automatically,  Up: Automatic Reverting of File-Visiting Buffers
+
+Risk of Reverting Automatically
+...............................
+
+For the vast majority users automatically reverting file-visiting
+buffers after they have changed on disk is harmless.
+
+   If a buffer is modified (i.e.  it contains changes that haven’t been
+saved yet), then Emacs would refuse to automatically revert it.  If you
+save a previously modified buffer, then that results in what is seen by
+Git as an uncommitted change.  Git would then refuse to carry out any
+commands that would cause these changes to be lost.  In other words, if
+there is anything that could be lost, then either Git or Emacs would
+refuse to discard the changes.
+
+   However if you do use file-visiting buffers as a sort of ad hoc
+"staging area", then the automatic reverts could potentially cause data
+loss.  So far I have only heard from one user who uses such a workflow.
+
+   An example: You visit some file in a buffer, edit it, and save the
+changes.  Then, outside of Emacs (or at least not using Magit or by
+saving the buffer) you change the file on disk again.  At this point the
+buffer is the only place where the intermediate version still exists.
+You have saved the changes to disk, but that has since been overwritten.
+Meanwhile Emacs considers the buffer to be unmodified (because you have
+not made any changes to it since you last saved it to the visited file)
+and therefore would not object to it being automatically reverted.  At
+this point an Auto-Revert mode would kick in.  It would check whether
+the buffer is modified and since that is not the case it would revert
+it.  The intermediate version would be lost.  (Actually you could still
+get it back using the ‘undo’ command.)
+
+   If your workflow depends on Emacs preserving the intermediate version
+in the buffer, then you have to disable all Auto-Revert modes.  But
+please consider that such a workflow would be dangerous even without
+using an Auto-Revert mode, and should therefore be avoided.  If Emacs
+crashed or if you quit Emacs by mistake, then you would also lose the
+buffer content.  There would be no autosave file still containing the
+intermediate version (because that was deleted when you saved the
+buffer) and you would not be asked whether you want to save the buffer
+(because it isn’t modified).
+
+
+File: magit.info,  Node: Sections,  Next: Popup Buffers and Prefix Commands,  Prev: Modes and Buffers,  Up: Interface Concepts
+
+4.2 Sections
+============
+
+Magit buffers are organized into nested sections, which can be collapsed
+and expanded, similar to how sections are handled in Org mode.  Each
+section also has a type, and some sections also have a value.  For each
+section type there can also be a local keymap, shared by all sections of
+that type.
+
+   Taking advantage of the section value and type, many commands operate
+on the current section, or when the region is active and selects
+sections of the same type, all of the selected sections.  Commands that
+only make sense for a particular section type (as opposed to just
+behaving differently depending on the type) are usually bound in section
+type keymaps.
+
+* Menu:
+
+* Section Movement::
+* Section Visibility::
+* Section Hooks::
+* Section Types and Values::
+* Section Options::
+
+
+File: magit.info,  Node: Section Movement,  Next: Section Visibility,  Up: Sections
+
+4.2.1 Section Movement
+----------------------
+
+To move within a section use the usual keys (‘C-p’, ‘C-n’, ‘C-b’, ‘C-f’
+etc), whose global bindings are not shadowed.  To move to another
+section use the following commands.
+
+‘p’     (‘magit-section-backward’)
+
+     When not at the beginning of a section, then move to the beginning
+     of the current section.  At the beginning of a section, instead
+     move to the beginning of the previous visible section.
+
+‘n’     (‘magit-section-forward’)
+
+     Move to the beginning of the next visible section.
+
+‘M-p’     (‘magit-section-backward-siblings’)
+
+     Move to the beginning of the previous sibling section.  If there is
+     no previous sibling section, then move to the parent section
+     instead.
+
+‘M-n’     (‘magit-section-forward-siblings’)
+
+     Move to the beginning of the next sibling section.  If there is no
+     next sibling section, then move to the parent section instead.
+
+‘^’     (‘magit-section-up’)
+
+     Move to the beginning of the parent of the current section.
+
+   The above commands all call the hook ‘magit-section-movement-hook’.
+Any of the functions listed below can be used as members of this hook.
+
+ -- Variable: magit-section-movement-hook
+
+     This hook is run by all of the above movement commands, after
+     arriving at the destination.
+
+ -- Function: magit-hunk-set-window-start
+
+     This hook function ensures that the beginning of the current
+     section is visible, provided it is a ‘hunk’ section.  Otherwise, it
+     does nothing.  This function is a member of the hook’s default
+     value.
+
+ -- Function: magit-section-set-window-start
+
+     This hook function ensures that the beginning of the current
+     section is visible, regardless of the section’s type.  If you add
+     this to ‘magit-section-movement-hook’, then you must remove the
+     hunk-only variant in turn.
+
+ -- Function: magit-log-maybe-show-more-commits
+
+     This hook function only has an effect in log buffers, and ‘point’
+     is on the "show more" section.  If that is the case, then it
+     doubles the number of commits that are being shown.  This function
+     is a member of the hook’s default value.
+
+ -- Function: magit-log-maybe-update-revision-buffer
+
+     When moving inside a log buffer, then this function updates the
+     revision buffer, provided it is already being displayed in another
+     window of the same frame.  This function is a member of the hook’s
+     default value.
+
+ -- Function: magit-log-maybe-update-blob-buffer
+
+     When moving inside a log buffer and another window of the same
+     frame displays a blob buffer, then this function instead displays
+     the blob buffer for the commit at point in that window.
+
+ -- Function: magit-status-maybe-update-revision-buffer
+
+     When moving inside a status buffer, then this function updates the
+     revision buffer, provided it is already being displayed in another
+     window of the same frame.
+
+ -- Function: magit-status-maybe-update-blob-buffer
+
+     When moving inside a status buffer and another window of the same
+     frame displays a blob buffer, then this function instead displays
+     the blob buffer for the commit at point in that window.
+
+ -- User Option: magit-update-other-window-delay
+
+     Delay before automatically updating the other window.
+
+     When moving around in certain buffers, then certain other buffers,
+     which are being displayed in another window, may optionally be
+     updated to display information about the section at point.
+
+     When holding down a key to move by more than just one section, then
+     that would update that buffer for each section on the way.  To
+     prevent that, updating the revision buffer is delayed, and this
+     option controls for how long.  For optimal experience you might
+     have to adjust this delay and/or the keyboard repeat rate and delay
+     of your graphical environment or operating system.
+
+
+File: magit.info,  Node: Section Visibility,  Next: Section Hooks,  Prev: Section Movement,  Up: Sections
+
+4.2.2 Section Visibility
+------------------------
+
+Magit provides many commands for changing the visibility of sections,
+but all you need to get started are the next two.
+
+‘TAB’     (‘magit-section-toggle’)
+
+     Toggle the visibility of the body of the current section.
+
+‘C-<tab>’     (‘magit-section-cycle’)
+
+     Cycle the visibility of current section and its children.
+
+‘M-<tab>’     (‘magit-section-cycle-diffs’)
+
+     Cycle the visibility of diff-related sections in the current
+     buffer.
+
+‘S-<tab>’     (‘magit-section-cycle-global’)
+
+     Cycle the visibility of all sections in the current buffer.
+
+‘1’     (‘magit-section-show-level-1’)
+‘2’     (‘magit-section-show-level-2’)
+‘3’     (‘magit-section-show-level-3’)
+‘4’     (‘magit-section-show-level-4’)
+
+     Show sections surrounding the current section up to level N.
+
+‘M-1’     (‘magit-section-show-level-1-all’)
+‘M-2’     (‘magit-section-show-level-2-all’)
+‘M-3’     (‘magit-section-show-level-3-all’)
+‘M-4’     (‘magit-section-show-level-4-all’)
+
+     Show all sections up to level N.
+
+   Some functions, which are used to implement the above commands, are
+also exposed as commands themselves.  By default no keys are bound to
+these commands, as they are generally perceived to be much less useful.
+But your mileage may vary.
+
+ -- Command: magit-section-show
+
+     Show the body of the current section.
+
+ -- Command: magit-section-hide
+
+     Hide the body of the current section.
+
+ -- Command: magit-section-show-headings
+
+     Recursively show headings of children of the current section.  Only
+     show the headings.  Previously shown text-only bodies are hidden.
+
+ -- Command: magit-section-show-children
+
+     Recursively show the bodies of children of the current section.
+     With a prefix argument show children down to the level of the
+     current section, and hide deeper children.
+
+ -- Command: magit-section-hide-children
+
+     Recursively hide the bodies of children of the current section.
+
+ -- Command: magit-section-toggle-children
+
+     Toggle visibility of bodies of children of the current section.
+
+   When a buffer is first created then some sections are shown expanded
+while others are not.  This is hard coded.  When a buffer is refreshed
+then the previous visibility is preserved.  The initial visibility of
+certain sections can also be overwritten using the hook
+‘magit-section-set-visibility-hook’.
+
+ -- User Option: magit-section-initial-visibility-alist
+
+     This options can be used to override the initial visibility of
+     sections.  In the future it will also be used to define the
+     defaults, but currently a section’s default is still hardcoded.
+
+     The value is an alist.  Each element maps a section type or lineage
+     to the initial visibility state for such sections.  The state has
+     to be one of ‘show’ or ‘hide’, or a function that returns one of
+     these symbols.  A function is called with the section as the only
+     argument.
+
+     Use the command ‘magit-describe-section’ to determine a section’s
+     lineage or type.  The vector in the output is the section lineage
+     and the type is the first element of that vector.  Wildcards can be
+     used, see ‘magit-section-match’.
+
+ -- User Option: magit-section-cache-visibility
+
+     This option controls for which sections the previous visibility
+     state should be restored if a section disappears and later appears
+     again.  The value is a boolean or a list of section types.  If t,
+     then the visibility of all sections is cached.  Otherwise this is
+     only done for sections whose type matches one of the listed types.
+
+     This requires that the function ‘magit-section-cached-visibility’
+     is a member of ‘magit-section-set-visibility-hook’.
+
+ -- Variable: magit-section-set-visibility-hook
+
+     This hook is run when first creating a buffer and also when
+     refreshing an existing buffer, and is used to determine the
+     visibility of the section currently being inserted.
+
+     Each function is called with one argument, the section being
+     inserted.  It should return ‘hide’ or ‘show’, or to leave the
+     visibility undefined ‘nil’.  If no function decides on the
+     visibility and the buffer is being refreshed, then the visibility
+     is preserved; or if the buffer is being created, then the hard
+     coded default is used.
+
+     Usually this should only be used to set the initial visibility but
+     not during refreshes.  If ‘magit-insert-section--oldroot’ is
+     non-nil, then the buffer is being refreshed and these functions
+     should immediately return ‘nil’.
+
+
+File: magit.info,  Node: Section Hooks,  Next: Section Types and Values,  Prev: Section Visibility,  Up: Sections
+
+4.2.3 Section Hooks
+-------------------
+
+Which sections are inserted into certain buffers is controlled with
+hooks.  This includes the status and the refs buffers.  For other
+buffers, e.g.  log, diff, and revision buffers, this is not possible.
+
+   For buffers whose sections can be customized by the user, a hook
+variable called ‘magit-TYPE-sections-hook’ exists.  This hook should be
+changed using ‘magit-add-section-hook’.  Avoid using ‘add-hooks’ or the
+Custom interface.
+
+   The various available section hook variables are described later in
+this manual along with the appropriate "section inserter functions".
+
+ -- Function: magit-add-section-hook hook function &optional at append
+          local
+
+     Add the function FUNCTION to the value of section hook HOOK.
+
+     Add FUNCTION at the beginning of the hook list unless optional
+     APPEND is non-nil, in which case FUNCTION is added at the end.  If
+     FUNCTION already is a member then move it to the new location.
+
+     If optional AT is non-nil and a member of the hook list, then add
+     FUNCTION next to that instead.  Add before or after AT, or replace
+     AT with FUNCTION depending on APPEND.  If APPEND is the symbol
+     ‘replace’, then replace AT with FUNCTION.  For any other non-nil
+     value place FUNCTION right after AT.  If nil, then place FUNCTION
+     right before AT.  If FUNCTION already is a member of the list but
+     AT is not, then leave FUNCTION where ever it already is.
+
+     If optional LOCAL is non-nil, then modify the hook’s buffer-local
+     value rather than its global value.  This makes the hook local by
+     copying the default value.  That copy is then modified.
+
+     HOOK should be a symbol.  If HOOK is void, it is first set to nil.
+     HOOK’s value must not be a single hook function.  FUNCTION should
+     be a function that takes no arguments and inserts one or multiple
+     sections at point, moving point forward.  FUNCTION may choose not
+     to insert its section(s), when doing so would not make sense.  It
+     should not be abused for other side-effects.
+
+   To remove a function from a section hook, use ‘remove-hook’.
+
+
+File: magit.info,  Node: Section Types and Values,  Next: Section Options,  Prev: Section Hooks,  Up: Sections
+
+4.2.4 Section Types and Values
+------------------------------
+
+Each section has a type, for example ‘hunk’, ‘file’, and ‘commit’.
+Instances of certain section types also have a value.  The value of a
+section of type ‘file’, for example, is a file name.
+
+   Users usually do not have to worry about a section’s type and value,
+but knowing them can be handy at times.
+
+‘M-x magit-describe-section’     (‘magit-describe-section’)
+
+     Show information about the section at point in the echo area, as
+     "VALUE [TYPE PARENT-TYPE...] BEGINNING-END".
+
+   Many commands behave differently depending on the type of the section
+at point and/or somehow consume the value of that section.  But that is
+only one of the reasons why the same key may do something different,
+depending on what section is current.
+
+   Additionally for each section type a keymap *might* be defined, named
+‘magit-TYPE-section-map’.  That keymap is used as text property keymap
+of all text belonging to any section of the respective type.  If such a
+map does not exist for a certain type, then you can define it yourself,
+and it will automatically be used.
+
+
+File: magit.info,  Node: Section Options,  Prev: Section Types and Values,  Up: Sections
+
+4.2.5 Section Options
+---------------------
+
+This section describes options that have an effect on more than just a
+certain type of sections.  As you can see there are not many of those.
+
+ -- User Option: magit-section-show-child-count
+
+     Whether to append the number of children to section headings.  This
+     only affects sections that could benefit from this information.
+
+
+File: magit.info,  Node: Popup Buffers and Prefix Commands,  Next: Completion Confirmation and the Selection,  Prev: Sections,  Up: Interface Concepts
+
+4.3 Popup Buffers and Prefix Commands
+=====================================
+
+Many Magit commands are implemented using *popup buffers*.  First the
+user invokes a *popup* or *prefix* command, which causes a popup buffer
+with the available *infix* arguments and *suffix* commands to be
+displayed.  The user then optionally toggles/sets some arguments and
+finally invokes one of the suffix commands.
+
+   This is implemented in the library ‘magit-popup’.  Earlier releases
+used the library ‘magit-key-mode’.  A future release will switch to a
+yet-to-be-written successor, which will likely be named ‘transient’.
+
+   Because ‘magit-popup’ can also be used by other packages without
+having to depend on all of Magit, it is documented in its own manual.
+See *note (magit-popup)Top::.
+
+‘C-c C-c’     (‘magit-dispatch-popup’)
+
+     This popup command shows a buffer featuring all other Magit popup
+     commands as well as some other commands that are not popup commands
+     themselves.
+
+   This command is also, or especially, useful outside Magit buffers, so
+you should setup a global binding:
+
+     (global-set-key (kbd "C-x M-g") 'magit-dispatch-popup)
+
+   Most popups set their initial arguments according to the
+corresponding ‘magit-*-arguments’ variable.  Two popups, the log and
+diff popups (see *note Logging:: and *note Diffing::), may behave a bit
+differently, depending on the value of ‘magit-use-sticky-arguments’.
+
+ -- User Option: magit-use-sticky-arguments
+
+     This option controls how diff and log commands reuse arguments from
+     existing buffers.
+
+     When ‘t’ (the default value), the log or diff popup reuses the
+     arguments from the current repository’s log or diff buffer,
+     respectively.  When no log or diff buffer exists for the current
+     repository, these popups use the default value of
+     ‘magit-log-arguments’ or ‘magit-diff-arguments’.
+
+     When ‘current’, log and diff popups will only reuse the arguments
+     if the current buffer is derived from ‘magit-log-mode’ or
+     ‘magit-diff-mode’, respectively.
+
+     When ‘nil’, the default value of ‘magit-log-arguments’ or
+     ‘magit-diff-arguments’ is always used.
+
+
+File: magit.info,  Node: Completion Confirmation and the Selection,  Next: Running Git,  Prev: Popup Buffers and Prefix Commands,  Up: Interface Concepts
+
+4.4 Completion, Confirmation and the Selection
+==============================================
+
+* Menu:
+
+* Action Confirmation::
+* Completion and Confirmation::
+* The Selection::
+* The hunk-internal region::
+* Support for Completion Frameworks::
+* Additional Completion Options::
+
+
+File: magit.info,  Node: Action Confirmation,  Next: Completion and Confirmation,  Up: Completion Confirmation and the Selection
+
+4.4.1 Action Confirmation
+-------------------------
+
+By default many actions that could potentially lead to data loss have to
+be confirmed.  This includes many very common actions, so this can
+quickly become annoying.  Many of these actions can be undone and if you
+have thought about how to undo certain mistakes, then it should be safe
+to disable confirmation for the respective actions.
+
+   The option ‘magit-no-confirm’ can be used to tell Magit to perform
+certain actions without the user having to confirm them.  Note that
+while this option can only be used to disable confirmation for a
+specific set of actions, the next section explains another way of
+telling Magit to ask fewer questions.
+
+ -- User Option: magit-no-confirm
+
+     The value of this option is a list of symbols, representing actions
+     that do not have to be confirmed by the user before being carried
+     out.
+
+     By default many potentially dangerous commands ask the user for
+     confirmation.  Each of the below symbols stands for an action
+     which, when invoked unintentionally or without being fully aware of
+     the consequences, could lead to tears.  In many cases there are
+     several commands that perform variations of a certain action, so we
+     don’t use the command names but more generic symbols.
+
+        • Applying changes:
+
+             • ‘discard’ Discarding one or more changes (i.e.  hunks or
+               the complete diff for a file) loses that change,
+               obviously.
+
+             • ‘reverse’ Reverting one or more changes can usually be
+               undone by reverting the reversion.
+
+             • ‘stage-all-changes’, ‘unstage-all-changes’ When there are
+               both staged and unstaged changes, then un-/staging
+               everything would destroy that distinction.  Of course
+               that also applies when un-/staging a single change, but
+               then less is lost and one does that so often that having
+               to confirm every time would be unacceptable.
+
+        • Files:
+
+             • ‘delete’ When a file that isn’t yet tracked by Git is
+               deleted, then it is completely lost, not just the last
+               changes.  Very dangerous.
+
+             • ‘trash’ Instead of deleting a file it can also be move to
+               the system trash.  Obviously much less dangerous than
+               deleting it.
+
+               Also see option ‘magit-delete-by-moving-to-trash’.
+
+             • ‘resurrect’ A deleted file can easily be resurrected by
+               "deleting" the deletion, which is done using the same
+               command that was used to delete the same file in the
+               first place.
+
+             • ‘untrack’ Untracking a file can be undone by tracking it
+               again.
+
+             • ‘rename’ Renaming a file can easily be undone.
+
+        • Sequences:
+
+             • ‘reset-bisect’ Aborting (known to Git as "resetting") a
+               bisect operation loses all information collected so far.
+
+             • ‘abort-rebase’ Aborting a rebase throws away all already
+               modified commits, but it’s possible to restore those from
+               the reflog.
+
+             • ‘abort-merge’ Aborting a merge throws away all conflict
+               resolutions which have already been carried out by the
+               user.
+
+             • ‘merge-dirty’ Merging with a dirty worktree can make it
+               hard to go back to the state before the merge was
+               initiated.
+
+        • References:
+
+             • ‘delete-unmerged-branch’ Once a branch has been deleted,
+               it can only be restored using low-level recovery tools
+               provided by Git.  And even then the reflog is gone.  The
+               user always has to confirm the deletion of a branch by
+               accepting the default choice (or selecting another
+               branch), but when a branch has not been merged yet, also
+               make sure the user is aware of that.
+
+             • ‘delete-pr-branch’ When deleting a branch that was
+               created from a pull request and if no other branches
+               still exist on that remote, then ‘magit-branch-delete’
+               offers to delete the remote as well.  This should be safe
+               because it only happens if no other refs exist in the
+               remotes namespace, and you can recreate the remote if
+               necessary.
+
+             • ‘drop-stashes’ Dropping a stash is dangerous because Git
+               stores stashes in the reflog.  Once a stash is removed,
+               there is no going back without using low-level recovery
+               tools provided by Git.  When a single stash is dropped,
+               then the user always has to confirm by accepting the
+               default (or selecting another).  This action only
+               concerns the deletion of multiple stashes at once.
+
+        • Edit published history:
+
+          Without adding these symbols here, you will be warned before
+          editing commits that have already been pushed to one of the
+          branches listed in ‘magit-published-branches’.
+
+             • ‘amend-published’ Affects most commands that amend to
+               "HEAD".
+
+             • ‘rebase-published’ Affects commands that perform
+               interactive rebases.  This includes commands from the
+               commit popup that modify a commit other than "HEAD",
+               namely the various fixup and squash variants.
+
+             • ‘edit-published’ Affects the commands
+               ‘magit-edit-line-commit’ and
+               ‘magit-diff-edit-hunk-commit’.  These two commands make
+               it quite easy to accidentally edit a published commit, so
+               you should think twice before configuring them not to ask
+               for confirmation.
+
+          To disable confirmation completely, add all three symbols here
+          or set ‘magit-published-branches’ to ‘nil’.
+
+        • Various:
+
+             • ‘kill-process’ There seldom is a reason to kill a
+               process.
+
+        • Global settings:
+
+          Instead of adding all of the above symbols to the value of
+          this option, you can also set it to the atom ‘t’, which has
+          the same effect as adding all of the above symbols.  Doing
+          that most certainly is a bad idea, especially because other
+          symbols might be added in the future.  So even if you don’t
+          want to be asked for confirmation for any of these actions,
+          you are still better of adding all of the respective symbols
+          individually.
+
+          When ‘magit-wip-before-change-mode’ is enabled, then the
+          following actions can be undone fairly easily: ‘discard’,
+          ‘reverse’, ‘stage-all-changes’, and ‘unstage-all-changes’.  If
+          and only if this mode is enabled, then ‘safe-with-wip’ has the
+          same effect as adding all of these symbols individually.
+
+
+File: magit.info,  Node: Completion and Confirmation,  Next: The Selection,  Prev: Action Confirmation,  Up: Completion Confirmation and the Selection
+
+4.4.2 Completion and Confirmation
+---------------------------------
+
+Many Magit commands ask the user to select from a list of possible
+things to act on, while offering the most likely choice as the default.
+For many of these commands the default is the thing at point, provided
+that it actually is a valid thing to act on.  For many commands that act
+on a branch, the current branch serves as the default if there is no
+branch at point.
+
+   These commands combine asking for confirmation and asking for a
+target to act on into a single action.  The user can confirm the default
+target using ‘RET’ or abort using ‘C-g’.  This is similar to a
+‘y-or-n-p’ prompt, but the keys to confirm or abort differ.
+
+   At the same time the user is also given the opportunity to select
+another target, which is useful because for some commands and/or in some
+situations you might want to select the action before selecting the
+target by moving to it.
+
+   However you might find that for some commands you always want to use
+the default target, if any, or even that you want the command to act on
+the default without requiring any confirmation at all.  The option
+‘magit-dwim-selection’ can be used to configure certain commands to that
+effect.
+
+   Note that when the region is active then many commands act on the
+things that are selected using a mechanism based on the region, in many
+cases after asking for confirmation.  This region-based mechanism is
+called the "selection" and is described in detail in the next section.
+When a selection exists that is valid for the invoked command, then that
+command never offers to act on something else, and whether it asks for
+confirmation is not controlled by this option.
+
+   Also note that Magit asks for confirmation of certain actions that
+are not coupled with completion (or the selection).  Such dialogs are
+also not affected by this option and are described in the previous
+section.
+
+ -- User Option: magit-dwim-selection
+
+   This option can be used to tell certain commands to use the thing at
+point instead of asking the user to select a candidate to act on, with
+or without confirmation.
+
+   The value has the form ‘((COMMAND nil|PROMPT DEFAULT)...)’.
+
+   • COMMAND is the command that should not prompt for a choice.  To
+     have an effect, the command has to use the function
+     ‘magit-completing-read’ or a utility function which in turn uses
+     that function.
+
+   • If the command uses ‘magit-completing-read’ multiple times, then
+     PROMPT can be used to only affect one of these uses.  PROMPT, if
+     non-nil, is a regular expression that is used to match against the
+     PROMPT argument passed to ‘magit-completing-read’.
+
+   • DEFAULT specifies how to use the default.  If it is ‘t’, then the
+     DEFAULT argument passed to ‘magit-completing-read’ is used without
+     confirmation.  If it is ‘ask’, then the user is given a chance to
+     abort.  DEFAULT can also be ‘nil’, in which case the entry has no
+     effect.
+
+
+File: magit.info,  Node: The Selection,  Next: The hunk-internal region,  Prev: Completion and Confirmation,  Up: Completion Confirmation and the Selection
+
+4.4.3 The Selection
+-------------------
+
+If the region is active, then many Magit commands act on the things that
+are selected using a mechanism based on the region instead of one single
+thing.  When the region is not active, then these commands act on the
+thing at point or read a single thing to act on.  This is described in
+the previous section — this section only covers how multiple things are
+selected, how that is visualized, and how certain commands behave when
+that is the case.
+
+   Magit’s mechanism for selecting multiple things, or rather sections
+that represent these things, is based on the Emacs region, but the area
+that Magit considers to be selected is typically larger than the region
+and additional restrictions apply.
+
+   Magit makes a distinction between a region that qualifies as forming
+a valid Magit selection and a region that does not.  If the region does
+not qualify, then it is displayed as it is in other Emacs buffers.  If
+the region does qualify as a Magit selection, then the selection is
+always visualized, while the region itself is only visualized if it
+begins and ends on the same line.
+
+   For a region to qualify as a Magit selection, it must begin in the
+heading of one section and end in the heading of a sibling section.
+Note that if the end of the region is at the very beginning of section
+heading (i.e.  at the very beginning of a line) then that section is
+considered to be *inside* the selection.
+
+   This is not consistent with how the region is normally treated in
+Emacs — if the region ends at the beginning of a line, then that line is
+outside the region.  Due to how Magit visualizes the selection, it
+should be obvious that this difference exists.
+
+   Not every command acts on every valid selection.  Some commands do
+not even consider the location of point, others may act on the section
+at point but not support acting on the selection, and even commands that
+do support the selection of course only do so if it selects things that
+they can act on.
+
+   This is the main reason why the selection must include the section at
+point.  Even if a selection exists, the invoked command may disregard
+it, in which case it may act on the current section only.  It is much
+safer to only act on the current section but not the other selected
+sections than it is to act on the current section *instead* of the
+selected sections.  The latter would be much more surprising and if the
+current section always is part of the selection, then that cannot
+happen.
+
+ -- Variable: magit-keep-region-overlay
+
+     This variable controls whether the region is visualized as usual
+     even when a valid Magit selection or a hunk-internal region exists.
+     See the doc-string for more information.
+
+
+File: magit.info,  Node: The hunk-internal region,  Next: Support for Completion Frameworks,  Prev: The Selection,  Up: Completion Confirmation and the Selection
+
+4.4.4 The hunk-internal region
+------------------------------
+
+Somewhat related to the Magit selection described in the previous
+section is the hunk-internal region.
+
+   Like the selection, the hunk-internal region is based on the Emacs
+region but causes that region to not be visualized as it would in other
+Emacs buffers, and includes the line on which the region ends even if it
+ends at the very beginning of that line.
+
+   Unlike the selection, which is based on a region that must begin in
+the heading of one section and ends in the section of a sibling section,
+the hunk-internal region must begin inside the *body* of a hunk section
+and end in the body of the *same* section.
+
+   The hunk-internal region is honored by "apply" commands, which can,
+among other targets, act on a hunk.  If the hunk-internal region is
+active, then such commands act only on the marked part of the hunk
+instead of on the complete hunk.
+
+
+File: magit.info,  Node: Support for Completion Frameworks,  Next: Additional Completion Options,  Prev: The hunk-internal region,  Up: Completion Confirmation and the Selection
+
+4.4.5 Support for Completion Frameworks
+---------------------------------------
+
+The built-in option ‘completing-read-function’ specifies the low-level
+function used by ‘completing-read’ to ask a user to select from a list
+of choices.  Its default value is ‘completing-read-default’.
+Alternative completion frameworks typically activate themselves by
+substituting their own implementation.
+
+   Mostly for historic reasons Magit provides a similar option named
+‘magit-completing-read-function’, which only controls the low-level
+function used by ‘magit-completing-read’.  This option also makes it
+possible to use a different completing mechanism for Magit than for the
+rest of Emacs, but doing that is not recommend.
+
+   You most likely don’t have to customize the magit-specific option to
+use an alternative completion framework.  For example, if you enable
+‘ivy-mode’, then Magit will respect that, and if you enable ‘helm-mode’,
+then you are done too.
+
+   However if you want to use Ido, then ‘ido-mode’ won’t do the trick.
+You will also have to install the ‘ido-completing-read+’ package and use
+‘magit-ido-completing-read’ as ‘magit-completing-read-function’.
+
+ -- User Option: magit-completing-read-function
+
+     The value of this variable is the low-level function used to
+     perform completion by code that uses ‘magit-completing-read’ (as
+     opposed to the built-in ‘completing-read’).
+
+     The default value, ‘magit-builtin-completing-read’, is suitable for
+     the standard completion mechanism, ‘ivy-mode’, and ‘helm-mode’ at
+     least.
+
+     The built-in ‘completing-read’ and ‘completing-read-default’ are
+     *not* suitable to be used here.  ‘magit-builtin-completing-read’
+     performs some additional work, and any function used in its place
+     has to do the same.
+
+ -- Function: magit-builtin-completing-read prompt choices &optional
+          predicate require-match initial-input hist def
+
+     This function performs completion using the built-in
+     ‘completion-read’ and does some additional magit-specific work.
+
+ -- Function: magit-ido-completing-read prompt choices &optional
+          predicate require-match initial-input hist def
+
+     This function performs completion using ‘ido-completing-read+’ from
+     the package by the same name (which you have to explicitly install)
+     and does some additional magit-specific work.
+
+     We have to use ‘ido-completing-read+’ instead of the
+     ‘ido-completing-read’ that comes with Ido itself, because the
+     latter, while intended as a drop-in replacement, cannot serve that
+     purpose because it violates too many of the implicit conventions.
+
+ -- Function: magit-completing-read prompt choices &optional predicate
+          require-match initial-input hist def fallback
+
+     This is the function that Magit commands use when they need the
+     user to select a single thing to act on.  The arguments have the
+     same meaning as for ‘completing-read’, except for FALLBACK, which
+     is unique to this function and is described below.
+
+     Instead of asking the user to choose from a list of possible
+     candidates, this function may just return the default specified by
+     DEF, with or without requiring user confirmation.  Whether that is
+     the case depends on PROMPT, ‘this-command’ and
+     ‘magit-dwim-selection’.  See the documentation of the latter for
+     more information.
+
+     If it does read a value in the minibuffer, then this function acts
+     similar to ‘completing-read’, except for the following:
+
+        • If REQUIRE-MATCH is ‘nil’ and the user exits without a choice,
+          then ‘nil’ is returned instead of an empty string.
+
+        • If REQUIRE-MATCH is non-nil and the users exits without a
+          choice, an user-error is raised.
+
+        • FALLBACK specifies a secondary default that is only used if
+          the primary default DEF is ‘nil’.  The secondary default is
+          not subject to ‘magit-dwim-selection’ — if DEF is ‘nil’ but
+          FALLBACK is not, then this function always asks the user to
+          choose a candidate, just as if both defaults were ‘nil’.
+
+        • ": " is appended to PROMPT.
+
+        • PROMPT is modified to end with \" (default DEF|FALLBACK): \"
+          provided that DEF or FALLBACK is non-nil, that neither
+          ‘ivy-mode’ nor ‘helm-mode’ is enabled, and that
+          ‘magit-completing-read-function’ is set to its default value
+          of ‘magit-builtin-completing-read’.
+
+
+File: magit.info,  Node: Additional Completion Options,  Prev: Support for Completion Frameworks,  Up: Completion Confirmation and the Selection
+
+4.4.6 Additional Completion Options
+-----------------------------------
+
+ -- User Option: magit-list-refs-sortby
+
+     For many commands that read a ref or refs from the user, the value
+     of this option can be used to control the order of the refs.  Valid
+     values include any key accepted by the ‘--sort’ flag of ‘git
+     for-each-ref’.  By default, refs are sorted alphabetically by their
+     full name (e.g., "refs/heads/master").
+
+
+File: magit.info,  Node: Running Git,  Prev: Completion Confirmation and the Selection,  Up: Interface Concepts
+
+4.5 Running Git
+===============
+
+* Menu:
+
+* Viewing Git Output::
+* Git Process Status::
+* Running Git Manually::
+* Git Executable::
+* Global Git Arguments::
+
+
+File: magit.info,  Node: Viewing Git Output,  Next: Git Process Status,  Up: Running Git
+
+4.5.1 Viewing Git Output
+------------------------
+
+Magit runs Git either for side-effects (e.g.  when pushing) or to get
+some value (e.g.  the name of the current branch).
+
+   When Git is run for side-effects, the process output is logged in a
+per-repository log buffer, which can be consulted using the
+‘magit-process’ command when things don’t go as expected.
+
+   The output/errors for up to ‘magit-process-log-max’ Git commands are
+retained.
+
+‘$’     (‘magit-process’)
+
+     This commands displays the process buffer for the current
+     repository.
+
+   Inside that buffer, the usual key bindings for navigating and showing
+sections are available.  There is one additional command.
+
+‘k’     (‘magit-process-kill’)
+
+     This command kills the process represented by the section at point.
+
+ -- User Option: magit-git-debug
+
+     When this is non-nil then the output of all calls to git are logged
+     in the process buffer.  This is useful when debugging, otherwise it
+     just negatively affects performance.
+
+
+File: magit.info,  Node: Git Process Status,  Next: Running Git Manually,  Prev: Viewing Git Output,  Up: Running Git
+
+4.5.2 Git Process Status
+------------------------
+
+When a Git process is running for side-effects, Magit displays an
+indicator in the mode line, using the ‘magit-mode-line-process’ face.
+
+   If the Git process exits successfully, the process indicator is
+removed from the mode line immediately.
+
+   In the case of a Git error, the process indicator is not removed, but
+is instead highlighted with the ‘magit-mode-line-process-error’ face,
+and the error details from the process buffer are provided as a tooltip
+for mouse users.  This error indicator persists in the mode line until
+the next magit buffer refresh.
+
+   If you do not wish process errors to be indicated in the mode line,
+customize the ‘magit-process-display-mode-line-error’ user option.
+
+   Process errors are additionally indicated at the top of the status
+buffer.
+
+
+File: magit.info,  Node: Running Git Manually,  Next: Git Executable,  Prev: Git Process Status,  Up: Running Git
+
+4.5.3 Running Git Manually
+--------------------------
+
+While Magit provides many Emacs commands to interact with Git, it does
+not cover everything.  In those cases your existing Git knowledge will
+come in handy.  Magit provides some commands for running arbitrary Git
+commands by typing them into the minibuffer, instead of having to switch
+to a shell.
+
+‘!’     (‘magit-run-popup’)
+
+     Shows the popup buffer featuring the below suffix commands.
+
+‘! !’     (‘magit-git-command-topdir’)
+
+     This command reads a command from the user and executes it in the
+     top-level directory of the current working tree.
+
+     The string "git " is used as initial input when prompting the user
+     for the command.  It can be removed to run another command.
+
+‘! p’     (‘magit-git-command’)
+
+     This command reads a command from the user and executes it in
+     ‘default-directory’.  With a prefix argument the command is
+     executed in the top-level directory of the current working tree
+     instead.
+
+     The string "git " is used as initial input when prompting the user
+     for the command.  It can be removed to run another command.
+
+‘! s’     (‘magit-shell-command-topdir’)
+
+     This command reads a command from the user and executes it in the
+     top-level directory of the current working tree.
+
+‘! S’     (‘magit-shell-command’)
+
+     This command reads a command from the user and executes it in
+     ‘default-directory’.  With a prefix argument the command is
+     executed in the top-level directory of the current working tree
+     instead.
+
+ -- User Option: magit-shell-command-verbose-prompt
+
+     Whether the prompt, used by the the above commands when reading a
+     shell command, shows the directory in which it will be run.
+
+   These suffix commands start external gui tools.
+
+‘! k’     (‘magit-run-gitk’)
+
+     This command runs ‘gitk’ in the current repository.
+
+‘! a’     (‘magit-run-gitk-all’)
+
+     This command runs ‘gitk --all’ in the current repository.
+
+‘! b’     (‘magit-run-gitk-branches’)
+
+     This command runs ‘gitk --branches’ in the current repository.
+
+‘! g’     (‘magit-run-git-gui’)
+
+     This command runs ‘git gui’ in the current repository.
+
+
+File: magit.info,  Node: Git Executable,  Next: Global Git Arguments,  Prev: Running Git Manually,  Up: Running Git
+
+4.5.4 Git Executable
+--------------------
+
+Except on MS Windows, Magit defaults to running Git without specifying
+the path to the git executable.  Instead the first executable found by
+Emacs on ‘exec-path’ is used (whose value in turn is set based on the
+value of the environment variable ‘$PATH’ when Emacs was started).
+
+   This has the advantage that it continues to work even when using
+Tramp to connect to a remote machine on which the executable is found in
+a different place.  The downside is that if you have multiple versions
+of Git installed, then you might end up using another version than the
+one you think you are using.
+
+‘M-x magit-version’     (‘magit-version’)
+
+     This command shows the currently used versions of Magit, Git, and
+     Emacs in the echo area.  Non-interactively this just returns the
+     Magit version.
+
+   When the ‘system-type’ is ‘windows-nt’, then ‘magit-git-executable’
+is set to an absolute path when Magit is first loaded.  This is
+necessary because Git on that platform comes with several wrapper
+scripts for the actual git binary, which are also placed on ‘$PATH’, and
+using one of these wrappers instead of the binary would degrade
+performance horribly.
+
+   If Magit doesn’t find the correct executable then you *can* work
+around that by setting ‘magit-git-executable’ to an absolute path.  But
+note that doing so is a kludge.  It is better to make sure the order in
+the environment variable ‘$PATH’ is correct, and that Emacs is started
+with that environment in effect.  The command
+‘magit-debug-git-executable’ can be useful to find out where Emacs is
+searching for git.  If you have to connect from Windows to a non-Windows
+machine, then you must change the value to "git".
+
+ -- User Option: magit-git-executable
+
+     The git executable used by Magit, either the full path to the
+     executable or the string "git" to let Emacs find the executable
+     itself, using the standard mechanism for doing such things.
+
+‘M-x magit-debug-git-executable’     (‘magit-debug-git-executable’)
+
+     Display a buffer with information about ‘magit-git-executable’.
+
+
+File: magit.info,  Node: Global Git Arguments,  Prev: Git Executable,  Up: Running Git
+
+4.5.5 Global Git Arguments
+--------------------------
+
+ -- User Option: magit-git-global-arguments
+
+     The arguments set here are used every time the git executable is
+     run as a subprocess.  They are placed right after the executable
+     itself and before the git command - as in ‘git HERE... COMMAND
+     REST’.  For valid arguments see *note (gitman)git::.
+
+     Be careful what you add here, especially if you are using Tramp to
+     connect to servers with ancient Git versions.  Never remove
+     anything that is part of the default value, unless you really know
+     what you are doing.  And think very hard before adding something;
+     it will be used every time Magit runs Git for any purpose.
+
+
+File: magit.info,  Node: Inspecting,  Next: Manipulating,  Prev: Interface Concepts,  Up: Top
+
+5 Inspecting
+************
+
+The functionality provided by Magit can be roughly divided into three
+groups: inspecting existing data, manipulating existing data or adding
+new data, and transferring data.  Of course that is a rather crude
+distinction that often falls short, but it’s more useful than no
+distinction at all.  This section is concerned with inspecting data, the
+next two with manipulating and transferring it.  Then follows a section
+about miscellaneous functionality, which cannot easily be fit into this
+distinction.
+
+   Of course other distinctions make sense too, e.g.  Git’s distinction
+between porcelain and plumbing commands, which for the most part is
+equivalent to Emacs’ distinction between interactive commands and
+non-interactive functions.  All of the sections mentioned before are
+mainly concerned with the porcelain – Magit’s plumbing layer is
+described later.
+
+* Menu:
+
+* Status Buffer::
+* Repository List::
+* Logging::
+* Diffing::
+* Ediffing::
+* References Buffer::
+* Bisecting::
+* Visiting Blobs::
+* Blaming::
+
+
+File: magit.info,  Node: Status Buffer,  Next: Repository List,  Up: Inspecting
+
+5.1 Status Buffer
+=================
+
+While other Magit buffers contain e.g.  one particular diff or one
+particular log, the status buffer contains the diffs for staged and
+unstaged changes, logs for unpushed and unpulled commits, lists of
+stashes and untracked files, and information related to the current
+branch.
+
+   During certain incomplete operations – for example when a merge
+resulted in a conflict – additional information is displayed that helps
+proceeding with or aborting the operation.
+
+   The command ‘magit-status’ displays the status buffer belonging to
+the current repository in another window.  This command is used so often
+that it should be bound globally.  We recommend using ‘C-x g’:
+
+     (global-set-key (kbd "C-x g") 'magit-status)
+
+‘C-x g’     (‘magit-status’)
+
+     Show the status of the current Git repository in a buffer.  With a
+     prefix argument prompt for a repository to be shown.  With two
+     prefix arguments prompt for an arbitrary directory.  If that
+     directory isn’t the root of an existing repository, then offer to
+     initialize it as a new repository.
+
+ -- User Option: magit-repository-directories
+
+     List of directories that are Git repositories or contain Git
+     repositories.
+
+     Each element has the form ‘(DIRECTORY . DEPTH)’.  DIRECTORY has to
+     be a directory or a directory file-name, a string.  DEPTH, an
+     integer, specifies the maximum depth to look for Git repositories.
+     If it is 0, then only add DIRECTORY itself.
+
+ -- User Option: magit-repository-directories-depth
+
+     The maximum depth to look for Git repositories.  This option is
+     obsolete and only used for elements of the option
+     ‘magit-repository-directories’ (which see) that don’t specify the
+     depth directly.
+
+ -- Command: ido-enter-magit-status
+
+     From an Ido prompt used to open a file, instead drop into
+     ‘magit-status’.  This is similar to ‘ido-magic-delete-char’, which,
+     despite its name, usually causes a Dired buffer to be created.
+
+     To make this command available, use something like:
+
+          (add-hook 'ido-setup-hook
+                    (lambda ()
+                      (define-key ido-completion-map
+                        (kbd \"C-x g\") 'ido-enter-magit-status)))
+
+     Starting with Emacs 25.1 the Ido keymaps are defined just once
+     instead of every time Ido is invoked, so now you can modify it like
+     pretty much every other keymap:
+
+          (define-key ido-common-completion-map
+            (kbd \"C-x g\") 'ido-enter-magit-status)
+
+* Menu:
+
+* Status Sections::
+* Status Header Sections::
+* Status Module Sections::
+* Status Options::
+
+
+File: magit.info,  Node: Status Sections,  Next: Status Header Sections,  Up: Status Buffer
+
+5.1.1 Status Sections
+---------------------
+
+The contents of status buffers is controlled using the hook
+‘magit-status-sections-hook’.  See *note Section Hooks:: to learn about
+such hooks and how to customize them.
+
+ -- User Option: magit-status-sections-hook
+
+     Hook run to insert sections into a status buffer.
+
+   The first function on that hook by default is
+‘magit-insert-status-headers’; it is described in the next section.  By
+default the following functions are also members of that hook:
+
+ -- Function: magit-insert-merge-log
+
+     Insert section for the on-going merge.  Display the heads that are
+     being merged.  If no merge is in progress, do nothing.
+
+ -- Function: magit-insert-rebase-sequence
+
+     Insert section for the on-going rebase sequence.  If no such
+     sequence is in progress, do nothing.
+
+ -- Function: magit-insert-am-sequence
+
+     Insert section for the on-going patch applying sequence.  If no
+     such sequence is in progress, do nothing.
+
+ -- Function: magit-insert-sequencer-sequence
+
+     Insert section for the on-going cherry-pick or revert sequence.  If
+     no such sequence is in progress, do nothing.
+
+ -- Function: magit-insert-bisect-output
+
+     While bisecting, insert section with output from ‘git bisect’.
+
+ -- Function: magit-insert-bisect-rest
+
+     While bisecting, insert section visualizing the bisect state.
+
+ -- Function: magit-insert-bisect-log
+
+     While bisecting, insert section logging bisect progress.
+
+ -- Function: magit-insert-untracked-files
+
+     Maybe insert a list or tree of untracked files.
+
+     Do so depending on the value of ‘status.showUntrackedFiles’.  Note
+     that even if the value is ‘all’, Magit still initially only shows
+     directories.  But the directory sections can then be expanded using
+     ‘TAB’.
+
+ -- Function: magit-insert-unstaged-changes
+
+     Insert section showing unstaged changes.
+
+ -- Function: magit-insert-staged-changes
+
+     Insert section showing staged changes.
+
+ -- Function: magit-insert-stashes &optional ref heading
+
+     Insert the ‘stashes’ section showing reflog for "refs/stash".  If
+     optional REF is non-nil show reflog for that instead.  If optional
+     HEADING is non-nil use that as section heading instead of
+     "Stashes:".
+
+ -- Function: magit-insert-unpulled-from-upstream
+
+     Insert section showing commits that haven’t been pulled from the
+     upstream branch yet.
+
+ -- Function: magit-insert-unpulled-from-pushremote
+
+     Insert section showing commits that haven’t been pulled from the
+     push-remote branch yet.
+
+ -- Function: magit-insert-unpushed-to-upstream
+
+     Insert section showing commits that haven’t been pushed to the
+     upstream yet.
+
+ -- Function: magit-insert-unpushed-to-pushremote
+
+     Insert section showing commits that haven’t been pushed to the
+     push-remote yet.
+
+   The following functions can also be added to the above hook:
+
+ -- Function: magit-insert-tracked-files
+
+     Insert a tree of tracked files.
+
+ -- Function: magit-insert-ignored-files
+
+     Insert a tree of ignored files.
+
+     If the first element of ‘magit-diff-section-arguments’ is a
+     directory, then limit the list to files below that.  The value of
+     that variable can be set using ‘D = f <DIRECTORY> RET g’.
+
+ -- Function: magit-insert-unpulled-or-recent-commits
+
+     Insert section showing unpulled or recent commits.  If an upstream
+     is configured for the current branch and it is ahead of the current
+     branch, then show the missing commits.  Otherwise, show the last
+     ‘magit-log-section-commit-count’ commits.
+
+ -- Function: magit-insert-recent-commits
+
+     Insert section showing the last ‘magit-log-section-commit-count’
+     commits.
+
+ -- User Option: magit-log-section-commit-count
+
+     How many recent commits ‘magit-insert-recent-commits’ and
+     ‘magit-insert-unpulled-or-recent-commits’ (provided there are no
+     unpulled commits) show.
+
+ -- Function: magit-insert-unpulled-cherries
+
+     Insert section showing unpulled commits.  Like
+     ‘magit-insert-unpulled-commits’ but prefix each commit that has not
+     been applied yet (i.e.  a commit with a patch-id not shared with
+     any local commit) with "+", and all others with "-".
+
+ -- Function: magit-insert-unpushed-cherries
+
+     Insert section showing unpushed commits.  Like
+     ‘magit-insert-unpushed-commits’ but prefix each commit which has
+     not been applied to upstream yet (i.e.  a commit with a patch-id
+     not shared with any upstream commit) with "+" and all others with
+     "-".
+
+   See *note References Buffer:: for some more section inserters, which
+could be used here.
+
+
+File: magit.info,  Node: Status Header Sections,  Next: Status Module Sections,  Prev: Status Sections,  Up: Status Buffer
+
+5.1.2 Status Header Sections
+----------------------------
+
+The contents of status buffers is controlled using the hook
+‘magit-status-sections-hook’ (see *note Status Sections::).
+
+   By default ‘magit-insert-status-headers’ is the first member of that
+hook variable.
+
+ -- Function: magit-insert-status-headers
+
+     Insert headers sections appropriate for ‘magit-status-mode’
+     buffers.  The sections are inserted by running the functions on the
+     hook ‘magit-status-headers-hook’.
+
+ -- User Option: magit-status-headers-hook
+
+     Hook run to insert headers sections into the status buffer.
+
+     This hook is run by ‘magit-insert-status-headers’, which in turn
+     has to be a member of ‘magit-status-sections-hook’ to be used at
+     all.
+
+   By default the following functions are members of the above hook:
+
+ -- Function: magit-insert-error-header
+
+     Insert a header line showing the message about the Git error that
+     just occurred.
+
+     This function is only aware of the last error that occur when Git
+     was run for side-effects.  If, for example, an error occurs while
+     generating a diff, then that error won’t be inserted.  Refreshing
+     the status buffer causes this section to disappear again.
+
+ -- Function: magit-insert-diff-filter-header
+
+     Insert a header line showing the effective diff filters.
+
+ -- Function: magit-insert-head-branch-header
+
+     Insert a header line about the current branch or detached ‘HEAD’.
+
+ -- Function: magit-insert-upstream-branch-header
+
+     Insert a header line about the branch that is usually pulled into
+     the current branch.
+
+ -- Function: magit-insert-push-branch-header
+
+     Insert a header line about the branch that the current branch is
+     usually pushed to.
+
+ -- Function: magit-insert-tags-header
+
+     Insert a header line about the current and/or next tag, along with
+     the number of commits between the tag and ‘HEAD’.
+
+   The following functions can also be added to the above hook:
+
+ -- Function: magit-insert-repo-header
+
+     Insert a header line showing the path to the repository top-level.
+
+ -- Function: magit-insert-remote-header
+
+     Insert a header line about the remote of the current branch.
+
+     If no remote is configured for the current branch, then fall back
+     showing the "origin" remote, or if that does not exist the first
+     remote in alphabetic order.
+
+ -- Function: magit-insert-user-header
+
+     Insert a header line about the current user.
+
+
+File: magit.info,  Node: Status Module Sections,  Next: Status Options,  Prev: Status Header Sections,  Up: Status Buffer
+
+5.1.3 Status Module Sections
+----------------------------
+
+The contents of status buffers is controlled using the hook
+‘magit-status-sections-hook’ (see *note Status Sections::).
+
+   By default ‘magit-insert-modules’ is _not_ a member of that hook
+variable.
+
+ -- Function: magit-insert-modules
+
+     Insert submodule sections.
+
+     Hook ‘magit-module-sections-hook’ controls which module sections
+     are inserted, and option ‘magit-module-sections-nested’ controls
+     whether they are wrapped in an additional section.
+
+ -- User Option: magit-module-sections-hook
+
+     Hook run by ‘magit-insert-modules’.
+
+ -- User Option: magit-module-sections-nested
+
+     This option controls whether ‘magit-insert-modules’ wraps inserted
+     sections in an additional section.
+
+     If this is non-nil, then only a single top-level section is
+     inserted.  If it is nil, then all sections listed in
+     ‘magit-module-sections-hook’ become top-level sections.
+
+ -- Function: magit-insert-modules-overview
+
+     Insert sections for all submodules.  For each section insert the
+     path, the branch, and the output of ‘git describe --tags’, or,
+     failing that, the abbreviated HEAD commit hash.
+
+     Press ‘RET’ on such a submodule section to show its own status
+     buffer.  Press ‘RET’ on the "Modules" section to display a list of
+     submodules in a separate buffer.  This shows additional information
+     not displayed in the super-repository’s status buffer.
+
+ -- Function: magit-insert-modules-unpulled-from-upstream
+
+     Insert sections for modules that haven’t been pulled from the
+     upstream yet.  These sections can be expanded to show the
+     respective commits.
+
+ -- Function: magit-insert-modules-unpulled-from-pushremote
+
+     Insert sections for modules that haven’t been pulled from the
+     push-remote yet.  These sections can be expanded to show the
+     respective commits.
+
+ -- Function: magit-insert-modules-unpushed-to-upstream
+
+     Insert sections for modules that haven’t been pushed to the
+     upstream yet.  These sections can be expanded to show the
+     respective commits.
+
+ -- Function: magit-insert-modules-unpushed-to-pushremote
+
+     Insert sections for modules that haven’t been pushed to the
+     push-remote yet.  These sections can be expanded to show the
+     respective commits.
+
+
+File: magit.info,  Node: Status Options,  Prev: Status Module Sections,  Up: Status Buffer
+
+5.1.4 Status Options
+--------------------
+
+ -- User Option: magit-status-refresh-hook
+
+     Hook run after a status buffer has been refreshed.
+
+ -- User Option: magit-status-margin
+
+     This option specifies whether the margin is initially shown in
+     Magit-Status mode buffers and how it is formatted.
+
+     The value has the form ‘(INIT STYLE WIDTH AUTHOR AUTHOR-WIDTH)’.
+
+        • If INIT is non-nil, then the margin is shown initially.
+
+        • STYLE controls how to format the committer date.  It can be
+          one of ‘age’ (to show the age of the commit),
+          ‘age-abbreviated’ (to abbreviate the time unit to a
+          character), or a string (suitable for ‘format-time-string’) to
+          show the actual date.
+
+        • WIDTH controls the width of the margin.  This exists for
+          forward compatibility and currently the value should not be
+          changed.
+
+        • AUTHOR controls whether the name of the author is also shown
+          by default.
+
+        • AUTHOR-WIDTH has to be an integer.  When the name of the
+          author is shown, then this specifies how much space is used to
+          do so.
+
+ -- User Option: magit-log-section-args
+
+     Additional Git arguments used when creating log sections.  Only
+     ‘--graph’, ‘--decorate’, and ‘--show-signature’ are supported.
+     This option is only a temporary kludge and will be removed.
+
+     Note that due to an issue in Git the use of ‘--graph’ is very slow
+     with long histories, so you probably don’t want to add this here.
+
+   Also see the proceeding section for more options concerning status
+buffers.
+
+
+File: magit.info,  Node: Repository List,  Next: Logging,  Prev: Status Buffer,  Up: Inspecting
+
+5.2 Repository List
+===================
+
+ -- Command: magit-list-repositories
+
+     This command displays a list of repositories in a separate buffer.
+
+     The options ‘magit-repository-directories’ and
+     ‘magit-repository-directories-depth’ control which repositories are
+     displayed.
+
+ -- User Option: magit-repolist-columns
+
+     This option controls what columns are displayed by the command
+     ‘magit-list-repositories’ and how they are displayed.
+
+     Each element has the form ‘(HEADER WIDTH FORMAT PROPS)’.
+
+     HEADER is the string displayed in the header.  WIDTH is the width
+     of the column.  FORMAT is a function that is called with one
+     argument, the repository identification (usually its basename), and
+     with ‘default-directory’ bound to the toplevel of its working tree.
+     It has to return a string to be inserted or nil.  PROPS is an alist
+     that supports the keys ‘:right-align’ and ‘:pad-right’.
+
+   The following functions can be added to the above option:
+
+ -- Function: magit-repolist-column-ident
+
+     This function inserts the identification of the repository.
+     Usually this is just its basename.
+
+ -- Function: magit-repolist-column-path
+
+     This function inserts the absolute path of the repository.
+
+ -- Function: magit-repolist-column-version
+
+     This function inserts a description of the repository’s ‘HEAD’
+     revision.
+
+ -- Function: magit-repolist-column-unpulled-from-upstream
+
+     This function inserts the number of upstream commits not in the
+     current branch.
+
+ -- Function: magit-repolist-column-unpulled-from-pushremote
+
+     This function inserts the number of commits in the push branch but
+     not the current branch.
+
+ -- Function: magit-repolist-column-unpushed-to-upstream
+
+     This function inserts the number of commits in the current branch
+     but not its upstream.
+
+ -- Function: magit-repolist-column-unpushed-to-pushremote
+
+     This function inserts the number of commits in the current branch
+     but not its push branch.
+
+
+File: magit.info,  Node: Logging,  Next: Diffing,  Prev: Repository List,  Up: Inspecting
+
+5.3 Logging
+===========
+
+The status buffer contains logs for the unpushed and unpulled commits,
+but that obviously isn’t enough.  The prefix command ‘magit-log-popup’,
+on ‘l’, features several suffix commands, which show a specific log in a
+separate log buffer.
+
+   Like other popups, the log popup also features several arguments that
+can be changed before invoking one of the suffix commands.  However, in
+the case of the log popup, these arguments may be taken from those
+currently in use in the current repository’s log buffer, depending on
+the value of ‘magit-use-sticky-arguments’ (see *note Popup Buffers and
+Prefix Commands::).
+
+   For information about the various arguments, see *note
+(gitman)git-log::.
+
+   The switch ‘++order=VALUE’ is converted to one of
+‘--author-date-order’, ‘--date-order’, or ‘--topo-order’ before being
+passed to ‘git log’.
+
+   The log popup also features several reflog commands.  See *note
+Reflog::.
+
+‘l’     (‘magit-log-popup’)
+
+     This prefix command shows the following suffix commands along with
+     the appropriate infix arguments in a popup buffer.
+
+‘l l’     (‘magit-log-current’)
+
+     Show log for the current branch.  When ‘HEAD’ is detached or with a
+     prefix argument, show log for one or more revs read from the
+     minibuffer.
+
+‘l o’     (‘magit-log’)
+
+     Show log for one or more revs read from the minibuffer.  The user
+     can input any revision or revisions separated by a space, or even
+     ranges, but only branches, tags, and a representation of the commit
+     at point are available as completion candidates.
+
+‘l h’     (‘magit-log-head’)
+
+     Show log for ‘HEAD’.
+
+‘l L’     (‘magit-log-branches’)
+
+     Show log for all local branches and ‘HEAD’.
+
+‘l b’     (‘magit-log-all-branches’)
+
+     Show log for all local and remote branches and ‘HEAD’.
+
+‘l a’     (‘magit-log-all’)
+
+     Show log for all references and ‘HEAD’.
+
+   Two additional commands that show the log for the file or blob that
+is being visited in the current buffer exists, see *note Minor Mode for
+Buffers Visiting Files::.  The command ‘magit-cherry’ also shows a log,
+see *note Cherries::.
+
+* Menu:
+
+* Refreshing Logs::
+* Log Buffer::
+* Log Margin::
+* Select from Log::
+* Reflog::
+* Cherries::
+
+
+File: magit.info,  Node: Refreshing Logs,  Next: Log Buffer,  Up: Logging
+
+5.3.1 Refreshing Logs
+---------------------
+
+The prefix command ‘magit-log-refresh-popup’, on ‘L’, can be used to
+change the log arguments used in the current buffer, without changing
+which log is shown.  This works in dedicated log buffers, but also in
+the status buffer.
+
+‘L’     (‘magit-log-refresh-popup’)
+
+     This prefix command shows the following suffix commands along with
+     the appropriate infix arguments in a popup buffer.
+
+‘L g’     (‘magit-log-refresh’)
+
+     This suffix command sets the local log arguments for the current
+     buffer.
+
+‘L s’     (‘magit-log-set-default-arguments’)
+
+     This suffix command sets the default log arguments for buffers of
+     the same type as that of the current buffer.  Other existing
+     buffers of the same type are not affected because their local
+     values have already been initialized.
+
+‘L w’     (‘magit-log-save-default-arguments’)
+
+     This suffix command sets the default log arguments for buffers of
+     the same type as that of the current buffer, and saves the value
+     for future sessions.  Other existing buffers of the same type are
+     not affected because their local values have already been
+     initialized.
+
+‘L t’     (‘magit-toggle-margin’)
+
+     Show or hide the margin.
+
+
+File: magit.info,  Node: Log Buffer,  Next: Log Margin,  Prev: Refreshing Logs,  Up: Logging
+
+5.3.2 Log Buffer
+----------------
+
+‘L’     (‘magit-log-refresh-popup’)
+
+     This prefix command shows the following suffix commands along with
+     the appropriate infix arguments in a popup buffer.  See *note
+     Refreshing Logs::.
+
+‘q’     (‘magit-log-bury-buffer’)
+
+     Bury the current buffer or the revision buffer in the same frame.
+     Like ‘magit-mode-bury-buffer’ (which see) but with a negative
+     prefix argument instead bury the revision buffer, provided it is
+     displayed in the current frame.
+
+‘C-c C-b’     (‘magit-go-backward’)
+
+     Move backward in current buffer’s history.
+
+‘C-c C-f’     (‘magit-go-forward’)
+
+     Move forward in current buffer’s history.
+
+‘C-c C-n’     (‘magit-log-move-to-parent’)
+
+     Move to a parent of the current commit.  By default, this is the
+     first parent, but a numeric prefix can be used to specify another
+     parent.
+
+‘SPC’     (‘magit-diff-show-or-scroll-up’)
+
+     Update the commit or diff buffer for the thing at point.
+
+     Either show the commit or stash at point in the appropriate buffer,
+     or if that buffer is already being displayed in the current frame
+     and contains information about that commit or stash, then instead
+     scroll the buffer up.  If there is no commit or stash at point,
+     then prompt for a commit.
+
+‘DEL’     (‘magit-diff-show-or-scroll-down’)
+
+     Update the commit or diff buffer for the thing at point.
+
+     Either show the commit or stash at point in the appropriate buffer,
+     or if that buffer is already being displayed in the current frame
+     and contains information about that commit or stash, then instead
+     scroll the buffer down.  If there is no commit or stash at point,
+     then prompt for a commit.
+
+‘=’     (‘magit-log-toggle-commit-limit’)
+
+     Toggle the number of commits the current log buffer is limited to.
+     If the number of commits is currently limited, then remove that
+     limit.  Otherwise set it to 256.
+
+‘+’     (‘magit-log-double-commit-limit’)
+
+     Double the number of commits the current log buffer is limited to.
+
+‘-’     (‘magit-log-half-commit-limit’)
+
+     Half the number of commits the current log buffer is limited to.
+
+ -- User Option: magit-log-auto-more
+
+     Insert more log entries automatically when moving past the last
+     entry.  Only considered when moving past the last entry with
+     ‘magit-goto-*-section’ commands.
+
+ -- User Option: magit-log-show-refname-after-summary
+
+     Whether to show the refnames after the commit summaries.  This is
+     useful if you use really long branch names.
+
+   Magit displays references in logs a bit differently from how Git does
+it.
+
+   Local branches are blue and remote branches are green.  Of course
+that depends on the used theme, as do the colors used for other types of
+references.  The current branch has a box around it, as do remote
+branches that are their respective remote’s ‘HEAD’ branch.
+
+   If a local branch and its push-target point at the same commit, then
+their names are combined to preserve space and to make that relationship
+visible.  For example:
+
+     origin/feature
+     [green][blue-]
+
+     instead of
+
+     feature origin/feature
+     [blue-] [green-------]
+
+   Also note that while the popup features the ‘--show-signature’
+argument, that won’t actually be used when enabled, because Magit
+defaults to use just one line per commit.  Instead the commit colorized
+to indicate the validity of the signed commit object, using the faces
+named ‘magit-signature-*’ (which see).
+
+   For a description of ‘magit-log-margin’ see *note Log Margin::.
+
+
+File: magit.info,  Node: Log Margin,  Next: Select from Log,  Prev: Log Buffer,  Up: Logging
+
+5.3.3 Log Margin
+----------------
+
+In buffers which show one or more logs, it is possible to show
+additional information about each commit in the margin.  The options
+used to configure the margin are named ‘magit-INFIX-margin’, where INFIX
+is the same as in the respective major-mode ‘magit-INFIX-mode’.  In
+regular log buffers that would be ‘magit-log-margin’.
+
+ -- User Option: magit-log-margin
+
+     This option specifies whether the margin is initially shown in
+     Magit-Log mode buffers and how it is formatted.
+
+     The value has the form ‘(INIT STYLE WIDTH AUTHOR AUTHOR-WIDTH)’.
+
+        • If INIT is non-nil, then the margin is shown initially.
+
+        • STYLE controls how to format the committer date.  It can be
+          one of ‘age’ (to show the age of the commit),
+          ‘age-abbreviated’ (to abbreviate the time unit to a
+          character), or a string (suitable for ‘format-time-string’) to
+          show the actual date.
+
+        • WIDTH controls the width of the margin.  This exists for
+          forward compatibility and currently the value should not be
+          changed.
+
+        • AUTHOR controls whether the name of the author is also shown
+          by default.
+
+        • AUTHOR-WIDTH has to be an integer.  When the name of the
+          author is shown, then this specifies how much space is used to
+          do so.
+
+   You can change the STYLE and AUTHOR-WIDTH of all ‘magit-INFIX-margin’
+options to the same values by customizing ‘magit-log-margin’ *before*
+‘magit’ is loaded.  If you do that, then the respective values for the
+other options will default to what you have set for that variable.
+Likewise if you set INIT in ‘magit-log-margin’ to ‘nil’, then that is
+used in the default of all other options.  But setting it to ‘t’, i.e.
+re-enforcing the default for that option, does not carry to other
+options.
+
+‘L’     (‘magit-margin-popup’)
+
+     This prefix command features the following commands for changing
+     the appearance of the margin.
+
+   In some buffers that support the margin, "L" is bound to
+‘magit-log-refresh-popup’, but that popup features the same commands,
+and then some other unrelated commands.
+
+‘L L’     (‘magit-toggle-margin’)
+
+     This command shows or hides the margin.
+
+‘L l’     (‘magit-cycle-margin-style’)
+
+     This command cycles the style used for the margin.
+
+‘L d’     (‘magit-toggle-margin-details’)
+
+     This command shows or hides details in the margin.
+
+
+File: magit.info,  Node: Select from Log,  Next: Reflog,  Prev: Log Margin,  Up: Logging
+
+5.3.4 Select from Log
+---------------------
+
+When the user has to select a recent commit that is reachable from
+‘HEAD’, using regular completion would be inconvenient (because most
+humans cannot remember hashes or "HEAD~5", at least not without double
+checking).  Instead a log buffer is used to select the commit, which has
+the advantage that commits are presented in order and with the commit
+message.
+
+   Such selection logs are used when selecting the beginning of a rebase
+and when selecting the commit to be squashed into.
+
+   In addition to the key bindings available in all log buffers, the
+following additional key bindings are available in selection log
+buffers:
+
+‘C-c C-c’     (‘magit-log-select-pick’)
+
+     Select the commit at point and act on it.  Call
+     ‘magit-log-select-pick-function’ with the selected commit as
+     argument.
+
+‘C-c C-k’     (‘magit-log-select-quit’)
+
+     Abort selecting a commit, don’t act on any commit.
+
+ -- User Option: magit-log-select-margin
+
+     This option specifies whether the margin is initially shown in
+     Magit-Log-Select mode buffers and how it is formatted.
+
+     The value has the form ‘(INIT STYLE WIDTH AUTHOR AUTHOR-WIDTH)’.
+
+        • If INIT is non-nil, then the margin is shown initially.
+
+        • STYLE controls how to format the committer date.  It can be
+          one of ‘age’ (to show the age of the commit),
+          ‘age-abbreviated’ (to abbreviate the time unit to a
+          character), or a string (suitable for ‘format-time-string’) to
+          show the actual date.
+
+        • WIDTH controls the width of the margin.  This exists for
+          forward compatibility and currently the value should not be
+          changed.
+
+        • AUTHOR controls whether the name of the author is also shown
+          by default.
+
+        • AUTHOR-WIDTH has to be an integer.  When the name of the
+          author is shown, then this specifies how much space is used to
+          do so.
+
+
+File: magit.info,  Node: Reflog,  Next: Cherries,  Prev: Select from Log,  Up: Logging
+
+5.3.5 Reflog
+------------
+
+Also see *note (gitman)git-reflog::.
+
+   These reflog commands are available from the log popup.  See *note
+Logging::.
+
+‘l r’     (‘magit-reflog-current’)
+
+     Display the reflog of the current branch.
+
+‘l O’     (‘magit-reflog-other’)
+
+     Display the reflog of a branch.
+
+‘l H’     (‘magit-reflog-head’)
+
+     Display the ‘HEAD’ reflog.
+
+ -- User Option: magit-reflog-margin
+
+     This option specifies whether the margin is initially shown in
+     Magit-Reflog mode buffers and how it is formatted.
+
+     The value has the form ‘(INIT STYLE WIDTH AUTHOR AUTHOR-WIDTH)’.
+
+        • If INIT is non-nil, then the margin is shown initially.
+
+        • STYLE controls how to format the committer date.  It can be
+          one of ‘age’ (to show the age of the commit),
+          ‘age-abbreviated’ (to abbreviate the time unit to a
+          character), or a string (suitable for ‘format-time-string’) to
+          show the actual date.
+
+        • WIDTH controls the width of the margin.  This exists for
+          forward compatibility and currently the value should not be
+          changed.
+
+        • AUTHOR controls whether the name of the author is also shown
+          by default.
+
+        • AUTHOR-WIDTH has to be an integer.  When the name of the
+          author is shown, then this specifies how much space is used to
+          do so.
+
+
+File: magit.info,  Node: Cherries,  Prev: Reflog,  Up: Logging
+
+5.3.6 Cherries
+--------------
+
+Cherries are commits that haven’t been applied upstream (yet), and are
+usually visualized using a log.  Each commit is prefixed with ‘-’ if it
+has an equivalent in the upstream and ‘+’ if it does not, i.e.  if it is
+a cherry.
+
+   The command ‘magit-cherry’ shows cherries for a single branch, but
+the references buffer (see *note References Buffer::) can show cherries
+for multiple "upstreams" at once.
+
+   Also see *note (gitman)git-reflog::.
+
+‘Y’     (‘magit-cherry’)
+
+     Show commits that are in a certain branch but that have not been
+     merged in the upstream branch.
+
+ -- User Option: magit-cherry-margin
+
+     This option specifies whether the margin is initially shown in
+     Magit-Cherry mode buffers and how it is formatted.
+
+     The value has the form ‘(INIT STYLE WIDTH AUTHOR AUTHOR-WIDTH)’.
+
+        • If INIT is non-nil, then the margin is shown initially.
+
+        • STYLE controls how to format the committer date.  It can be
+          one of ‘age’ (to show the age of the commit),
+          ‘age-abbreviated’ (to abbreviate the time unit to a
+          character), or a string (suitable for ‘format-time-string’) to
+          show the actual date.
+
+        • WIDTH controls the width of the margin.  This exists for
+          forward compatibility and currently the value should not be
+          changed.
+
+        • AUTHOR controls whether the name of the author is also shown
+          by default.
+
+        • AUTHOR-WIDTH has to be an integer.  When the name of the
+          author is shown, then this specifies how much space is used to
+          do so.
+
+
+File: magit.info,  Node: Diffing,  Next: Ediffing,  Prev: Logging,  Up: Inspecting
+
+5.4 Diffing
+===========
+
+The status buffer contains diffs for the staged and unstaged commits,
+but that obviously isn’t enough.  The prefix command ‘magit-diff-popup’,
+on ‘d’, features several suffix commands, which show a specific diff in
+a separate diff buffer.
+
+   Like other popups, the diff popup also features several arguments
+that can be changed before invoking one of the suffix commands.
+However, in the case of the diff popup, these arguments may be taken
+from those currently in use in the current repository’s log buffer,
+depending on the value of ‘magit-use-sticky-arguments’ (see *note Popup
+Buffers and Prefix Commands::).
+
+   Also see *note (gitman)git-diff::.
+
+‘d’     (‘magit-diff-popup’)
+
+     This prefix command shows the following suffix commands along with
+     the appropriate infix arguments in a popup buffer.
+
+‘d d’     (‘magit-diff-dwim’)
+
+     Show changes for the thing at point.
+
+‘d r’     (‘magit-diff’)
+
+     Show differences between two commits.
+
+     RANGE should be a range (A..B or A...B) but can also be a single
+     commit.  If one side of the range is omitted, then it defaults to
+     ‘HEAD’.  If just a commit is given, then changes in the working
+     tree relative to that commit are shown.
+
+     If the region is active, use the revisions on the first and last
+     line of the region.  With a prefix argument, instead of diffing the
+     revisions, choose a revision to view changes along, starting at the
+     common ancestor of both revisions (i.e., use a "..." range).
+
+‘d w’     (‘magit-diff-working-tree’)
+
+     Show changes between the current working tree and the ‘HEAD’
+     commit.  With a prefix argument show changes between the working
+     tree and a commit read from the minibuffer.
+
+‘d s’     (‘magit-diff-staged’)
+
+     Show changes between the index and the ‘HEAD’ commit.  With a
+     prefix argument show changes between the index and a commit read
+     from the minibuffer.
+
+‘d u’     (‘magit-diff-unstaged’)
+
+     Show changes between the working tree and the index.
+
+‘d p’     (‘magit-diff-paths’)
+
+     Show changes between any two files on disk.
+
+   All of the above suffix commands update the repository’s diff buffer.
+The diff popup also features two commands which show differences in
+another buffer:
+
+‘d c’     (‘magit-show-commit’)
+
+     Show the commit at point.  If there is no commit at point or with a
+     prefix argument, prompt for a commit.
+
+‘d t’     (‘magit-stash-show’)
+
+     Show all diffs of a stash in a buffer.
+
+   Two additional commands that show the diff for the file or blob that
+is being visited in the current buffer exists, see *note Minor Mode for
+Buffers Visiting Files::.
+
+* Menu:
+
+* Refreshing Diffs::
+* Diff Buffer::
+* Diff Options::
+* Revision Buffer::
+
+
+File: magit.info,  Node: Refreshing Diffs,  Next: Diff Buffer,  Up: Diffing
+
+5.4.1 Refreshing Diffs
+----------------------
+
+The prefix command ‘magit-diff-refresh-popup’, on ‘D’, can be used to
+change the diff arguments used in the current buffer, without changing
+which diff is shown.  This works in dedicated diff buffers, but also in
+the status buffer.
+
+‘D’     (‘magit-diff-refresh-popup’)
+
+     This prefix command shows the following suffix commands along with
+     the appropriate infix arguments in a popup buffer.
+
+‘D g’     (‘magit-diff-refresh’)
+
+     This suffix command sets the local diff arguments for the current
+     buffer.
+
+‘D s’     (‘magit-diff-set-default-arguments’)
+
+     This suffix command sets the default diff arguments for buffers of
+     the same type as that of the current buffer.  Other existing
+     buffers of the same type are not affected because their local
+     values have already been initialized.
+
+‘D w’     (‘magit-diff-save-default-arguments’)
+
+     This suffix command sets the default diff arguments for buffers of
+     the same type as that of the current buffer, and saves the value
+     for future sessions.  Other existing buffers of the same type are
+     not affected because their local values have already been
+     initialized.
+
+‘D t’     (‘magit-diff-toggle-refine-hunk’)
+
+     This command toggles hunk refinement on or off.
+
+‘D r’     (‘magit-diff-switch-range-type’)
+
+     This command converts the diff range type from "revA..revB" to
+     "revB...revA", or vice versa.
+
+‘D f’     (‘magit-diff-flip-revs’)
+
+     This command swaps revisions in the diff range from "revA..revB" to
+     "revB..revA", or vice versa.
+
+‘D F’     (‘magit-diff-toggle-file-filter’)
+
+     This command toggles the file restriction of the diffs in the
+     current buffer, allowing you to quickly switch between viewing all
+     the changes in the commit and the restricted subset.  As a special
+     case, when this command is called from a log buffer, it toggles the
+     file restriction in the repository’s revision buffer, which is
+     useful when you display a revision from a log buffer that is
+     restricted to a file or files.
+
+   In addition to the above popup, which allows changing any of the
+supported arguments, there also exist some commands which change a
+particular argument.
+
+‘-’     (‘magit-diff-less-context’)
+
+     This command decreases the context for diff hunks by COUNT lines.
+
+‘+’     (‘magit-diff-more-context’)
+
+     This command increases the context for diff hunks by COUNT lines.
+
+‘0’     (‘magit-diff-default-context’)
+
+     This command resets the context for diff hunks to the default
+     height.
+
+   The following commands quickly change what diff is being displayed
+without having to using one of the diff popups.
+
+‘C-c C-d’     (‘magit-diff-while-committing’)
+
+     While committing, this command shows the changes that are about to
+     be committed.  While amending, invoking the command again toggles
+     between showing just the new changes or all the changes that will
+     be committed.
+
+     This binding is available in the diff buffer as well as the commit
+     message buffer.
+
+‘C-c C-b’     (‘magit-go-backward’)
+
+     This command moves backward in current buffer’s history.
+
+‘C-c C-f’     (‘magit-go-forward’)
+
+     This command moves forward in current buffer’s history.
+
+
+File: magit.info,  Node: Diff Buffer,  Next: Diff Options,  Prev: Refreshing Diffs,  Up: Diffing
+
+5.4.2 Diff Buffer
+-----------------
+
+These commands are available in diff buffers.
+
+‘RET’     (‘magit-diff-visit-file’)
+
+     From a diff, visit the corresponding file at the appropriate
+     position.
+
+     If the diff shows changes in the worktree, the index, or ‘HEAD’,
+     then visit the actual file.  Otherwise, when the diff is about an
+     older commit or a range, then visit the appropriate blob.
+
+     If point is on a removed line, then visit the blob for the first
+     parent of the commit which removed that line, i.e.  the last commit
+     where that line still existed.  Otherwise visit the blob for the
+     commit whose changes are being shown.
+
+     Interactively, when the file or blob to be displayed is already
+     being displayed in another window of the same frame, then just
+     select that window and adjust point.  Otherwise, or with a prefix
+     argument, display the buffer in another window.  The meaning of the
+     prefix argument can be inverted or further modified using the
+     option ‘magit-display-file-buffer-function’.
+
+     Non-interactively the optional OTHER-WINDOW argument is taken
+     literally.  DISPLAY-FN can be used to specify the display function
+     explicitly, in which case OTHER-WINDOW is ignored.
+
+     The optional FORCE-WORKTREE means to force visiting the worktree
+     version of the file.  To do this interactively use the command
+     ‘magit-diff-visit-file-worktree’ instead.
+
+ -- User Option: magit-diff-visit-previous-blob
+
+     This option controls whether ‘magit-diff-visit-file’ may visit the
+     previous blob.  When this is ‘t’ and point is on a removed line in
+     a diff for a committed change, then ‘magit-diff-visit-file’ visits
+     the blob from the last revision which still had that line.
+
+     Currently this is only supported for committed changes, for staged
+     and unstaged changes ‘magit-diff-visit-file’ always visits the file
+     in the working tree.
+
+‘C-<return>’     (‘magit-diff-visit-file-worktree’)
+
+     From a diff, visit the corresponding file at the appropriate
+     position.
+
+     When the file is already being displayed in another window of the
+     same frame, then just select that window and adjust point.  With a
+     prefix argument also display in another window.
+
+     The actual file in the worktree is visited.  The positions in the
+     hunk headers get less useful the "older" the changes are, and as a
+     result, jumping to the appropriate position gets less reliable.
+
+     Also see ‘magit-diff-visit-file’, which visits the respective blob,
+     unless the diff shows changes in the worktree, the index, or
+     ‘HEAD’.
+
+ -- Command: magit-diff-visit-file-other-window
+
+     From a diff, visit the corresponding file at the appropriate
+     position in another window.
+
+‘C-c C-t’     (‘magit-diff-trace-definition’)
+
+     From a diff, show log for the definition at point.
+
+‘C-c C-e’     (‘magit-diff-edit-hunk-commit’)
+
+     From a hunk, edit the respective commit and visit the file.
+
+     First visit the file being modified by the hunk at the correct
+     location using ‘magit-diff-visit-file’.  This actually visits a
+     blob.  When point is on a diff header, not within an individual
+     hunk, then this visits the blob the first hunk is about.
+
+     Then invoke ‘magit-edit-line-commit’, which uses an interactive
+     rebase to make the commit editable, or if that is not possible
+     because the commit is not reachable from ‘HEAD’ by checking out
+     that commit directly.  This also causes the actual worktree file to
+     be visited.
+
+     Neither the blob nor the file buffer are killed when finishing the
+     rebase.  If that is undesirable, then it might be better to use
+     ‘magit-rebase-edit-command’ instead of this command.
+
+‘j’     (‘magit-jump-to-diffstat-or-diff’)
+
+     Jump to the diffstat or diff.  When point is on a file inside the
+     diffstat section, then jump to the respective diff section.
+     Otherwise, jump to the diffstat section or a child thereof.
+
+‘SPC’     (‘scroll-up’)
+
+     Scroll text upward.
+
+‘DEL’     (‘scroll-down’)
+
+     Scroll text downward.
+
+
+File: magit.info,  Node: Diff Options,  Next: Revision Buffer,  Prev: Diff Buffer,  Up: Diffing
+
+5.4.3 Diff Options
+------------------
+
+ -- User Option: magit-diff-refine-hunk
+
+     Whether to show word-granularity differences within diff hunks.
+
+        • ‘nil’ never show fine differences.
+
+        • ‘t’ show fine differences for the current diff hunk only.
+
+        • ‘all’ show fine differences for all displayed diff hunks.
+
+ -- User Option: magit-diff-adjust-tab-width
+
+     Whether to adjust the width of tabs in diffs.
+
+     Determining the correct width can be expensive if it requires
+     opening large and/or many files, so the widths are cached in the
+     variable ‘magit-diff--tab-width-cache’.  Set that to nil to
+     invalidate the cache.
+
+        • ‘nil’ Never ajust tab width.  Use ‘tab-width’s value from the
+          Magit buffer itself instead.
+
+        • ‘t’ If the corresponding file-visiting buffer exits, then use
+          ‘tab-width’’s value from that buffer.  Doing this is cheap, so
+          this value is used even if a corresponding cache entry exists.
+
+        • ‘always’ If there is no such buffer, then temporarily visit
+          the file to determine the value.
+
+        • NUMBER Like ‘always’, but don’t visit files larger than NUMBER
+          bytes.
+
+ -- User Option: magit-diff-paint-whitespace
+
+     Specify where to highlight whitespace errors.
+
+     See ‘magit-diff-highlight-trailing’,
+     ‘magit-diff-highlight-indentation’.  The symbol ‘t’ means in all
+     diffs, ‘status’ means only in the status buffer, and nil means
+     nowhere.
+
+ -- User Option: magit-diff-highlight-trailing
+
+     Whether to highlight whitespace at the end of a line in diffs.
+     Used only when ‘magit-diff-paint-whitespace’ is non-nil.
+
+ -- User Option: magit-diff-highlight-indentation
+
+     Highlight the "wrong" indentation style.  Used only when
+     ‘magit-diff-paint-whitespace’ is non-nil.
+
+     The value is a list of cons cells.  The car is a regular
+     expression, and the cdr is the value that applies to repositories
+     whose directory matches the regular expression.  If more than one
+     element matches, then the *last* element in the list applies.  The
+     default value should therefore come first in the list.
+
+     If the value is ‘tabs’, highlight indentation with tabs.  If the
+     value is an integer, highlight indentation with at least that many
+     spaces.  Otherwise, highlight neither.
+
+ -- User Option: magit-diff-hide-trailing-cr-characters
+
+     Whether to hide ^M characters at the end of a line in diffs.
+
+ -- User Option: magit-diff-highlight-hunk-region-functions
+
+     This option specifies the functions used to highlight the
+     hunk-internal region.
+
+     ‘magit-diff-highlight-hunk-region-dim-outside’ overlays the outside
+     of the hunk internal selection with a face that causes the added
+     and removed lines to have the same background color as context
+     lines.  This function should not be removed from the value of this
+     option.
+
+     ‘magit-diff-highlight-hunk-region-using-overlays’ and
+     ‘magit-diff-highlight-hunk-region-using-underline’ emphasize the
+     region by placing delimiting horizontal lines before and after it.
+     Both of these functions have glitches which cannot be fixed due to
+     limitations of Emacs’ display engine.  For more information see
+     <https://github.com/magit/magit/issues/2758> ff.
+
+     Instead of, or in addition to, using delimiting horizontal lines,
+     to emphasize the boundaries, you may which to emphasize the text
+     itself, using ‘magit-diff-highlight-hunk-region-using-face’.
+
+     In terminal frames it’s not possible to draw lines as the overlay
+     and underline variants normally do, so there they fall back to
+     calling the face function instead.
+
+ -- User Option: magit-diff-unmarked-lines-keep-foreground
+
+     This option controls whether added and removed lines outside the
+     hunk-internal region only lose their distinct background color or
+     also the foreground color.  Whether the outside of the region is
+     dimmed at all depends on
+     ‘magit-diff-highlight-hunk-region-functions’.
+
+
+File: magit.info,  Node: Revision Buffer,  Prev: Diff Options,  Up: Diffing
+
+5.4.4 Revision Buffer
+---------------------
+
+ -- User Option: magit-revision-insert-related-refs
+
+     Whether to show related refs in revision buffers.
+
+ -- User Option: magit-revision-show-gravatar
+
+     Whether to show gravatar images in revision buffers.
+
+     If non-nil, then the value has to be a cons-cell which specifies
+     where the gravatar images for the author and/or the committer are
+     inserted inside the text that was previously inserted according to
+     ‘magit-revision-header-format’.
+
+     Both cells are regular expressions.  The car specifies where to
+     insert the author gravatar image.  The top half of the image is
+     inserted right after the matched text, the bottom half on the next
+     line at the same offset.  The cdr specifies where to insert the
+     committer image, accordingly.  Either the car or the cdr may be
+     nil.
+
+ -- User Option: magit-revision-use-hash-sections
+
+     Whether to turn hashes inside the commit message into sections.
+
+     If non-nil, then hashes inside the commit message are turned into
+     ‘commit’ sections.  There is a trade off to be made between
+     performance and reliability:
+
+        • ‘slow’ calls git for every word to be absolutely sure.
+
+        • ‘quick’ skips words less than seven characters long.
+
+        • ‘quicker’ additionally skips words that don’t contain a
+          number.
+
+        • ‘quickest’ uses all words that are at least seven characters
+          long and which contain at least one number as well as at least
+          one letter.
+
+     If nil, then no hashes are turned into sections, but you can still
+     visit the commit at point using "RET".
+
+   The diffs shown in the revision buffer may be automatically
+restricted to a subset of the changed files.  If the revision buffer is
+displayed from a log buffer, the revision buffer will share the same
+file restriction as that log buffer (also see the command
+‘magit-diff-toggle-file-filter’).  Note, however, that the log’s file
+restriction will be ignored when ‘magit-log-arguments’ includes
+‘--follow’.  In this case, the ‘-u’ argument of the log popup can be
+used to show the file-restricted diffs inline.
+
+   If the revision buffer is not displayed from a log buffer, the file
+restriction is determined by the file restriction in the repository’s
+diff buffer, if it exists, and the value of the option
+‘magit-use-sticky-arguments’.
+
+
+File: magit.info,  Node: Ediffing,  Next: References Buffer,  Prev: Diffing,  Up: Inspecting
+
+5.5 Ediffing
+============
+
+This section describes how to enter Ediff from Magit buffers.  For
+information on how to use Ediff itself, see *note (ediff)Top::.
+
+‘e’     (‘magit-ediff-dwim’)
+
+     Compare, stage, or resolve using Ediff.
+
+     This command tries to guess what file, and what commit or range the
+     user wants to compare, stage, or resolve using Ediff.  It might
+     only be able to guess either the file, or range/commit, in which
+     case the user is asked about the other.  It might not always guess
+     right, in which case the appropriate ‘magit-ediff-*’ command has to
+     be used explicitly.  If it cannot read the user’s mind at all, then
+     it asks the user for a command to run.
+
+‘E’     (‘magit-ediff-popup’)
+
+     This prefix command shows the following suffix commands in a popup
+     buffer.
+
+‘E r’     (‘magit-ediff-compare’)
+
+     Compare two revisions of a file using Ediff.
+
+     If the region is active, use the revisions on the first and last
+     line of the region.  With a prefix argument, instead of diffing the
+     revisions, choose a revision to view changes along, starting at the
+     common ancestor of both revisions (i.e., use a "..." range).
+
+‘E m’     (‘magit-ediff-resolve’)
+
+     Resolve outstanding conflicts in a file using Ediff, defaulting to
+     the file at point.
+
+     Provided that the value of ‘merge.conflictstyle’ is ‘diff3’, you
+     can view the file’s merge-base revision using ‘/’ in the Ediff
+     control buffer.
+
+     In the rare event that you want to manually resolve all conflicts,
+     including those already resolved by Git, use
+     ‘ediff-merge-revisions-with-ancestor’.
+
+‘E s’     (‘magit-ediff-stage’)
+
+     Stage and unstage changes to a file using Ediff, defaulting to the
+     file at point.
+
+‘E u’     (‘magit-ediff-show-unstaged’)
+
+     Show unstaged changes to a file using Ediff.
+
+‘E i’     (‘magit-ediff-show-staged’)
+
+     Show staged changes to a file using Ediff.
+
+‘E w’     (‘magit-ediff-show-working-tree’)
+
+     Show changes in a file between ‘HEAD’ and working tree using Ediff.
+
+‘E c’     (‘magit-ediff-show-commit’)
+
+     Show changes to a file introduced by a commit using Ediff.
+
+‘E z’     (‘magit-ediff-show-stash’)
+
+     Show changes to a file introduced by a stash using Ediff.
+
+ -- User Option: magit-ediff-dwim-show-on-hunks
+
+     This option controls what command ‘magit-ediff-dwim’ calls when
+     point is on uncommitted hunks.  When nil, always run
+     ‘magit-ediff-stage’.  Otherwise, use ‘magit-ediff-show-staged’ and
+     ‘magit-ediff-show-unstaged’ to show staged and unstaged changes,
+     respectively.
+
+ -- User Option: magit-ediff-show-stash-with-index
+
+     This option controls whether ‘magit-ediff-show-stash’ includes a
+     buffer containing the file’s state in the index at the time the
+     stash was created.  This makes it possible to tell which changes in
+     the stash were staged.
+
+ -- User Option: magit-ediff-quit-hook
+
+     This hook is run after quitting an Ediff session that was created
+     using a Magit command.  The hook functions are run inside the Ediff
+     control buffer, and should not change the current buffer.
+
+     This is similar to ‘ediff-quit-hook’ but takes the needs of Magit
+     into account.  The regular ‘ediff-quit-hook’ is ignored by Ediff
+     sessions that were created using a Magit command.
+
+
+File: magit.info,  Node: References Buffer,  Next: Bisecting,  Prev: Ediffing,  Up: Inspecting
+
+5.6 References Buffer
+=====================
+
+‘y’     (‘magit-show-refs-popup’)
+
+     List and compare references in a dedicated buffer.  By default all
+     refs are compared with ‘HEAD’, but with a prefix argument this
+     command instead acts as a prefix command and shows the following
+     suffix commands along with the appropriate infix arguments in a
+     popup buffer.
+
+‘y y’     (‘magit-show-refs-head’)
+
+     List and compare references in a dedicated buffer.  Refs are
+     compared with ‘HEAD’.
+
+‘y c’     (‘magit-show-refs-current’)
+
+     List and compare references in a dedicated buffer.  Refs are
+     compared with the current branch or ‘HEAD’ if it is detached.
+
+‘y o’     (‘magit-show-refs’)
+
+     List and compare references in a dedicated buffer.  Refs are
+     compared with a branch read from the user.
+
+ -- User Option: magit-refs-show-commit-count
+
+     Whether to show commit counts in Magit-Refs mode buffers.
+
+        • ‘all’ Show counts for branches and tags.
+
+        • ‘branch’ Show counts for branches only.
+
+        • ‘nil’ Never show counts.
+
+     The default is ‘nil’ because anything else can be very expensive.
+
+ -- User Option: magit-refs-pad-commit-counts
+
+     Whether to pad all commit counts on all sides in Magit-Refs mode
+     buffers.
+
+     If this is nil, then some commit counts are displayed right next to
+     one of the branches that appear next to the count, without any
+     space in between.  This might look bad if the branch name faces
+     look too similar to ‘magit-dimmed’.
+
+     If this is non-nil, then spaces are placed on both sides of all
+     commit counts.
+
+ -- User Option: magit-refs-show-remote-prefix
+
+     Whether to show the remote prefix in lists of remote branches.
+
+     Showing the prefix is redundant because the name of the remote is
+     already shown in the heading preceeding the list of its branches.
+
+ -- User Option: magit-refs-primary-column-width
+
+     Width of the primary column in ‘magit-refs-mode’ buffers.  The
+     primary column is the column that contains the name of the branch
+     that the current row is about.
+
+     If this is an integer, then the column is that many columns wide.
+     Otherwise it has to be a cons-cell of two integers.  The first
+     specifies the minimal width, the second the maximal width.  In that
+     case the actual width is determined using the length of the names
+     of the shown local branches.  (Remote branches and tags are not
+     taken into account when calculating to optimal width.)
+
+ -- User Option: magit-refs-focus-column-width
+
+     Width of the focus column in ‘magit-refs-mode’ buffers.
+
+     The focus column is the first column, which marks one branch
+     (usually the current branch) as the focused branch using ‘*’ or
+     ‘@’.  For each other reference, this column optionally shows how
+     many commits it is ahead of the focused branch and ‘<’, or if it
+     isn’t ahead then the commits it is behind and ‘>’, or if it isn’t
+     behind either, then a ‘=’.
+
+     This column may also display only ‘*’ or ‘@’ for the focused
+     branch, in which case this option is ignored.  Use ‘L v’ to change
+     the verbosity of this column.
+
+ -- User Option: magit-refs-margin
+
+     This option specifies whether the margin is initially shown in
+     Magit-Refs mode buffers and how it is formatted.
+
+     The value has the form ‘(INIT STYLE WIDTH AUTHOR AUTHOR-WIDTH)’.
+
+        • If INIT is non-nil, then the margin is shown initially.
+
+        • STYLE controls how to format the committer date.  It can be
+          one of ‘age’ (to show the age of the commit),
+          ‘age-abbreviated’ (to abbreviate the time unit to a
+          character), or a string (suitable for ‘format-time-string’) to
+          show the actual date.
+
+        • WIDTH controls the width of the margin.  This exists for
+          forward compatibility and currently the value should not be
+          changed.
+
+        • AUTHOR controls whether the name of the author is also shown
+          by default.
+
+        • AUTHOR-WIDTH has to be an integer.  When the name of the
+          author is shown, then this specifies how much space is used to
+          do so.
+
+ -- User Option: magit-refs-margin-for-tags
+
+     This option specifies whether to show information about tags in the
+     margin.  This is disabled by default because it is slow if there
+     are many tags.
+
+   The following variables control how individual refs are displayed.
+If you change one of these variables (especially the "%c" part), then
+you should also change the others to keep things aligned.  The following
+%-sequences are supported:
+
+   • ‘%a’ Number of commits this ref has over the one we compare to.
+
+   • ‘%b’ Number of commits the ref we compare to has over this one.
+
+   • ‘%c’ Number of commits this ref has over the one we compare to.
+     For the ref which all other refs are compared this is instead "@",
+     if it is the current branch, or "#" otherwise.
+
+   • ‘%C’ For the ref which all other refs are compared this is "@", if
+     it is the current branch, or "#" otherwise.  For all other refs "
+     ".
+
+   • ‘%h’ Hash of this ref’s tip.
+
+   • ‘%m’ Commit summary of the tip of this ref.
+
+   • ‘%n’ Name of this ref.
+
+   • ‘%u’ Upstream of this local branch.
+
+   • ‘%U’ Upstream of this local branch and additional local vs.
+     upstream information.
+
+ -- User Option: magit-refs-filter-alist
+
+     This alist controls which tags and branches are omitted from being
+     displayed in ‘magit-refs-mode’ buffers.  If it is ‘nil’, then all
+     refs are displayed (subject to ‘magit-refs-sections-hook’).
+
+     All keys are tried in order until one matches.  Then its value is
+     used and subsequent elements are ignored.  If the value is non-nil,
+     then the reference is displayed, otherwise it is not.  If no
+     element matches, then the reference is displayed.
+
+     A key can either be a regular expression that the refname has to
+     match, or a function that takes the refname as only argument and
+     returns a boolean.  Contrary to how they are displayed in the
+     buffer, for comparison each tag begins with "tags/" and each remote
+     branch with "<remote>/".
+
+‘RET’     (‘magit-visit-ref’)
+
+     This command visits the reference or revision at point in another
+     buffer.  If there is no revision at point or with a prefix argument
+     then it prompts for a revision.
+
+     This command behaves just like ‘magit-show-commit’ as described
+     above, except if point is on a reference in a ‘magit-refs-mode’
+     buffer, in which case the behavior may be different, but only if
+     you have customized the option ‘magit-visit-ref-behavior’.
+
+ -- User Option: magit-visit-ref-behavior
+
+     This option controls how ‘magit-visit-ref’ behaves in
+     ‘magit-refs-mode’ buffers.
+
+     By default ‘magit-visit-ref’ behaves like ‘magit-show-commit’, in
+     all buffers, including ‘magit-refs-mode’ buffers.  When the type of
+     the section at point is ‘commit’ then "RET" is bound to
+     ‘magit-show-commit’, and when the type is either ‘branch’ or ‘tag’
+     then it is bound to ‘magit-visit-ref’.
+
+     "RET" is one of Magit’s most essential keys and at least by default
+     it should behave consistently across all of Magit, especially
+     because users quickly learn that it does something very harmless;
+     it shows more information about the thing at point in another
+     buffer.
+
+     However "RET" used to behave differently in ‘magit-refs-mode’
+     buffers, doing surprising things, some of which cannot really be
+     described as "visit this thing".  If you’ve grown accustomed this
+     behavior, you can restore it by adding one or more of the below
+     symbols to the value of this option.  But keep in mind that by
+     doing so you don’t only introduce inconsistencies, you also lose
+     some functionality and might have to resort to ‘M-x
+     magit-show-commit’ to get it back.
+
+     ‘magit-visit-ref’ looks for these symbols in the order in which
+     they are described here.  If the presence of a symbol applies to
+     the current situation, then the symbols that follow do not affect
+     the outcome.
+
+        • ‘focus-on-ref’
+
+          With a prefix argument update the buffer to show commit counts
+          and lists of cherry commits relative to the reference at point
+          instead of relative to the current buffer or ‘HEAD’.
+
+          Instead of adding this symbol, consider pressing "C-u y o
+          RET".
+
+        • ‘create-branch’
+
+          If point is on a remote branch, then create a new local branch
+          with the same name, use the remote branch as its upstream, and
+          then check out the local branch.
+
+          Instead of adding this symbol, consider pressing "b c RET
+          RET", like you would do in other buffers.
+
+        • ‘checkout-any’
+
+          Check out the reference at point.  If that reference is a tag
+          or a remote branch, then this results in a detached ‘HEAD’.
+
+          Instead of adding this symbol, consider pressing "b b RET",
+          like you would do in other buffers.
+
+        • ‘checkout-branch’
+
+          Check out the local branch at point.
+
+          Instead of adding this symbol, consider pressing "b b RET",
+          like you would do in other buffers.
+
+* Menu:
+
+* References Sections::
+
+
+File: magit.info,  Node: References Sections,  Up: References Buffer
+
+5.6.1 References Sections
+-------------------------
+
+The contents of references buffers is controlled using the hook
+‘magit-refs-sections-hook’.  See *note Section Hooks:: to learn about
+such hooks and how to customize them.  All of the below functions are
+members of the default value.  Note that it makes much less sense to
+customize this hook than it does for the respective hook used for the
+status buffer.
+
+ -- User Option: magit-refs-sections-hook
+
+     Hook run to insert sections into a references buffer.
+
+ -- Function: magit-insert-local-branches
+
+     Insert sections showing all local branches.
+
+ -- Function: magit-insert-remote-branches
+
+     Insert sections showing all remote-tracking branches.
+
+ -- Function: magit-insert-tags
+
+     Insert sections showing all tags.
+
+
+File: magit.info,  Node: Bisecting,  Next: Visiting Blobs,  Prev: References Buffer,  Up: Inspecting
+
+5.7 Bisecting
+=============
+
+Also see *note (gitman)git-bisect::.
+
+‘B’     (‘magit-bisect-popup’)
+
+     This prefix command shows the following suffix commands in a popup
+     buffer.
+
+   When bisecting is not in progress, then the popup buffer features the
+following commands.
+
+‘B B’     (‘magit-bisect-start’)
+
+     Start a bisect session.
+
+     Bisecting a bug means to find the commit that introduced it.  This
+     command starts such a bisect session by asking for a known good and
+     a bad commit.
+
+‘B s’     (‘magit-bisect-run’)
+
+     Bisect automatically by running commands after each step.
+
+   When bisecting is in progress, then the popup buffer features these
+commands instead.
+
+‘B b’     (‘magit-bisect-bad’)
+
+     Mark the current commit as bad.  Use this after you have asserted
+     that the commit does contain the bug in question.
+
+‘B g’     (‘magit-bisect-good’)
+
+     Mark the current commit as good.  Use this after you have asserted
+     that the commit does not contain the bug in question.
+
+‘B k’     (‘magit-bisect-skip’)
+
+     Skip the current commit.  Use this if for some reason the current
+     commit is not a good one to test.  This command lets Git choose a
+     different one.
+
+‘B r’     (‘magit-bisect-reset’)
+
+     After bisecting, cleanup bisection state and return to original
+     ‘HEAD’.
+
+   By default the status buffer shows information about the ongoing
+bisect session.
+
+ -- User Option: magit-bisect-show-graph
+
+     This option controls whether a graph is displayed for the log of
+     commits that still have to be bisected.
+
+
+File: magit.info,  Node: Visiting Blobs,  Next: Blaming,  Prev: Bisecting,  Up: Inspecting
+
+5.8 Visiting Blobs
+==================
+
+‘M-x magit-find-file’     (‘magit-find-file’)
+
+     View FILE from REV.  Switch to a buffer visiting blob REV:FILE,
+     creating one if none already exists.
+
+‘M-x magit-find-file-other-window’     (‘magit-find-file-other-window’)
+
+     View FILE from REV, in another window.  Like ‘magit-find-file’, but
+     create a new window or reuse an existing one.
+
+
+File: magit.info,  Node: Blaming,  Prev: Visiting Blobs,  Up: Inspecting
+
+5.9 Blaming
+===========
+
+Also see *note (gitman)git-blame::.
+
+   To start blaming you can use ‘M-x’ in a file-visiting buffer to
+invoke one of the following commands.  You can also invoke these
+commands using the blame popup, which is available on ‘b’ in
+file-visiting buffers that already contain blame information and, also
+on ‘b’, in all blob-visiting buffers.  You can also enter the blame
+popup from the file popup, which is available on ‘C-c M-g’, provided
+‘magit-file-mode’ is enabled, see *note Minor Mode for Buffers Visiting
+Files::.
+
+ -- Command: magit-blame
+
+     This command augments each line or chunk of lines in the current
+     file- or blob-visiting buffer with information about what commits
+     last touched these lines.
+
+     If the buffer visits a revision of that file, then history up to
+     that revision is considered.  Otherwise, the file’s full history is
+     considered, including uncommitted changes.
+
+     If Magit-Blame mode is already turned on in the current buffer then
+     blaming is done recursively, by visiting REVISION:FILE (using
+     ‘magit-find-file’), where REVISION is a parent of the revision that
+     added the current line or chunk of lines.
+
+ -- Command: magit-blame-echo
+
+     This command is like ‘magit-blame’ except that it doesn’t turn on
+     ‘read-only-mode’ and that it initially uses the visualization style
+     specified by option ‘magit-blame-echo-style’.
+
+ -- Command: magit-blame-removal
+
+     This command augments each line or chunk of lines in the current
+     blob-visiting buffer with information about the revision that
+     removes it.  It cannot be used in file-visiting buffers.
+
+     Like ‘magit-blame’, this command can be used recursively.
+
+ -- Command: magit-blame-reverse
+
+     This command augments each line or chunk of lines in the current
+     file- or blob-visiting buffer with information about the last
+     revision in which a line still existed.
+
+     Like ‘magit-blame’, this command can be used recursively.
+
+   The following key bindings are available when Magit-Blame mode is
+enabled and Read-Only mode is not enabled.  These commands are also
+available in other buffers; here only the behavior is described that is
+relevant in file-visiting buffers that are being blamed.
+
+‘RET’     (‘magit-show-commit’)
+
+     This command shows the commit that last touched the line at point.
+
+‘SPC’     (‘magit-diff-show-or-scroll-up’)
+
+     This command updates the commit buffer.
+
+     This either shows the commit that last touched the line at point in
+     the appropriate buffer, or if that buffer is already being
+     displayed in the current frame and if that buffer contains
+     information about that commit, then the buffer is scrolled up
+     instead.
+
+‘DEL’     (‘magit-diff-show-or-scroll-down’)
+
+     This command updates the commit buffer.
+
+     This either shows the commit that last touched the line at point in
+     the appropriate buffer, or if that buffer is already being
+     displayed in the current frame and if that buffer contains
+     information about that commit, then the buffer is scrolled down
+     instead.
+
+   The following key bindings are available when Magit-Blame mode is
+enabled and Read-Only mode is not enabled.
+
+‘b’     (‘magit-blame-popup’)
+
+     This prefix command shows the above suffix command along with the
+     appropriate infix arguments in a popup buffer.
+
+‘n’     (‘magit-blame-next-chunk’)
+
+     This command moves to the next chunk.
+
+‘N’     (‘magit-blame-next-chunk-same-commit’)
+
+     This command moves to the next chunk from the same commit.
+
+‘p’     (‘magit-blame-previous-chunk’)
+
+     This command moves to the previous chunk.
+
+‘P’     (‘magit-blame-previous-chunk-same-commit’)
+
+     This command moves to the previous chunk from the same commit.
+
+‘q’     (‘magit-blame-quit’)
+
+     This command turns off Magit-Blame mode.  If the buffer was created
+     during a recursive blame, then it also kills the buffer.
+
+‘M-w’     (‘magit-blame-copy-hash’)
+
+     This command saves the hash of the current chunk’s commit to the
+     kill ring.
+
+     When the region is active, the command saves the region’s content
+     instead of the hash, like ‘kill-ring-save’ would.
+
+‘c’     (‘magit-blame-cycle-style’)
+
+     This command changes how blame information is visualized in the
+     current buffer by cycling through the styles specified using the
+     option ‘magit-blame-styles’.
+
+   Blaming is also controlled using the following options.
+
+ -- User Option: magit-blame-styles
+
+     This option defines a list of styles used to visualize blame
+     information.  For now see its doc-string to learn more.
+
+ -- User Option: magit-blame-echo-style
+
+     This option specifies the blame visualization style used by the
+     command ‘magit-blame-echo’.  This must be a symbol that is used as
+     the identifier for one of the styles defined in
+     ‘magit-blame-styles’.
+
+ -- User Option: magit-blame-time-format
+
+     This option specifies the format string used to display times when
+     showing blame information.
+
+ -- User Option: magit-blame-read-only
+
+     This option controls whether blaming a buffer also makes
+     temporarily read-only.
+
+ -- User Option: magit-blame-disable-modes
+
+     This option lists incompatible minor-modes that should be disabled
+     temporarily when a buffer contains blame information.  They are
+     enabled again when the buffer no longer shows blame information.
+
+ -- User Option: magit-blame-goto-chunk-hook
+
+     This hook is run when moving between chunks.
+
+
+File: magit.info,  Node: Manipulating,  Next: Transferring,  Prev: Inspecting,  Up: Top
+
+6 Manipulating
+**************
+
+* Menu:
+
+* Repository Setup::
+* Staging and Unstaging::
+* Applying::
+* Committing::
+* Branching::
+* Merging::
+* Resolving Conflicts::
+* Rebasing::
+* Cherry Picking::
+* Resetting::
+* Stashing::
+
+
+File: magit.info,  Node: Repository Setup,  Next: Staging and Unstaging,  Up: Manipulating
+
+6.1 Repository Setup
+====================
+
+‘M-x magit-init’     (‘magit-init’)
+
+     This command initializes a repository and then shows the status
+     buffer for the new repository.
+
+     If the directory is below an existing repository, then the user has
+     to confirm that a new one should be created inside.  If the
+     directory is the root of the existing repository, then the user has
+     to confirm that it should be reinitialized.
+
+‘M-x magit-clone’     (‘magit-clone’)
+
+     This command clones a repository and then shows the status buffer
+     for the new repository.
+
+     The user is queried for a remote url and a local directory.
+
+ -- User Option: magit-clone-set-remote.pushDefault
+
+     Whether to set the value of ‘remote.pushDefault’ after cloning.
+
+     If ‘t’, then set without asking.  If ‘nil’, then don’t set.  If
+     ‘ask’, then ask the user every time she clones a repository.
+
+
+File: magit.info,  Node: Staging and Unstaging,  Next: Applying,  Prev: Repository Setup,  Up: Manipulating
+
+6.2 Staging and Unstaging
+=========================
+
+Like Git, Magit can of course stage and unstage complete files.  Unlike
+Git, it also allows users to gracefully un-/stage individual hunks and
+even just part of a hunk.  To stage individual hunks and parts of hunks
+using Git directly, one has to use the very modal and rather clumsy
+interface of a ‘git add --interactive’ session.
+
+   With Magit, on the other hand, one can un-/stage individual hunks by
+just moving point into the respective section inside a diff displayed in
+the status buffer or a separate diff buffer and typing ‘s’ or ‘u’.  To
+operate on just parts of a hunk, mark the changes that should be
+un-/staged using the region and then press the same key that would be
+used to un-/stage.  To stage multiple files or hunks at once use a
+region that starts inside the heading of such a section and ends inside
+the heading of a sibling section of the same type.
+
+   Besides staging and unstaging, Magit also provides several other
+"apply variants" that can also operate on a file, multiple files at
+once, a hunk, multiple hunks at once, and on parts of a hunk.  These
+apply variants are described in the next section.
+
+   You can also use Ediff to stage and unstage.  See *note Ediffing::.
+
+‘s’     (‘magit-stage’)
+
+     Add the change at point to the staging area.
+
+     With a prefix argument and an untracked file (or files) at point,
+     stage the file but not its content.  This makes it possible to
+     stage only a subset of the new file’s changes.
+
+‘S’     (‘magit-stage-modified’)
+
+     Stage all changes to files modified in the worktree.  Stage all new
+     content of tracked files and remove tracked files that no longer
+     exist in the working tree from the index also.  With a prefix
+     argument also stage previously untracked (but not ignored) files.
+
+‘u’     (‘magit-unstage’)
+
+     Remove the change at point from the staging area.
+
+     Only staged changes can be unstaged.  But by default this command
+     performs an action that is somewhat similar to unstaging, when it
+     is called on a committed change: it reverses the change in the
+     index but not in the working tree.
+
+‘U’     (‘magit-unstage-all’)
+
+     Remove all changes from the staging area.
+
+ -- User Option: magit-unstage-committed
+
+     This option controls whether ‘magit-unstage’ "unstages" committed
+     changes by reversing them in the index but not the working tree.
+     The alternative is to raise an error.
+
+‘M-x magit-reverse-in-index’     (‘magit-reverse-in-index’)
+
+     This command reverses the committed change at point in the index
+     but not the working tree.  By default no key is bound directly to
+     this command, but it is indirectly called when ‘u’
+     (‘magit-unstage’) is pressed on a committed change.
+
+     This allows extracting a change from ‘HEAD’, while leaving it in
+     the working tree, so that it can later be committed using a
+     separate commit.  A typical workflow would be:
+
+        • Optionally make sure that there are no uncommitted changes.
+
+        • Visit the ‘HEAD’ commit and navigate to the change that should
+          not have been included in that commit.
+
+        • Type ‘u’ (‘magit-unstage’) to reverse it in the index.  This
+          assumes that ‘magit-unstage-committed-changes’ is non-nil.
+
+        • Type ‘c e’ to extend ‘HEAD’ with the staged changes, including
+          those that were already staged before.
+
+        • Optionally stage the remaining changes using ‘s’ or ‘S’ and
+          then type ‘c c’ to create a new commit.
+
+‘M-x magit-reset-index’     (‘magit-reset-index’)
+
+     Reset the index to some commit.  The commit is read from the user
+     and defaults to the commit at point.  If there is no commit at
+     point, then it defaults to ‘HEAD’.
+
+* Menu:
+
+* Staging from File-Visiting Buffers::
+
+
+File: magit.info,  Node: Staging from File-Visiting Buffers,  Up: Staging and Unstaging
+
+6.2.1 Staging from File-Visiting Buffers
+----------------------------------------
+
+Fine-grained un-/staging has to be done from the status or a diff
+buffer, but it’s also possible to un-/stage all changes made to the file
+visited in the current buffer right from inside that buffer.
+
+‘M-x magit-stage-file’     (‘magit-stage-file’)
+
+     When invoked inside a file-visiting buffer, then stage all changes
+     to that file.  In a Magit buffer, stage the file at point if any.
+     Otherwise prompt for a file to be staged.  With a prefix argument
+     always prompt the user for a file, even in a file-visiting buffer
+     or when there is a file section at point.
+
+‘M-x magit-unstage-file’     (‘magit-unstage-file’)
+
+     When invoked inside a file-visiting buffer, then unstage all
+     changes to that file.  In a Magit buffer, unstage the file at point
+     if any.  Otherwise prompt for a file to be unstaged.  With a prefix
+     argument always prompt the user for a file, even in a file-visiting
+     buffer or when there is a file section at point.
+
+
+File: magit.info,  Node: Applying,  Next: Committing,  Prev: Staging and Unstaging,  Up: Manipulating
+
+6.3 Applying
+============
+
+Magit provides several "apply variants": stage, unstage, discard,
+reverse, and "regular apply".  At least when operating on a hunk they
+are all implemented using ‘git apply’, which is why they are called
+"apply variants".
+
+   • Stage.  Apply a change from the working tree to the index.  The
+     change also remains in the working tree.
+
+   • Unstage.  Remove a change from the index.  The change remains in
+     the working tree.
+
+   • Discard.  On a staged change, remove it from the working tree and
+     the index.  On an unstaged change, remove it from the working tree
+     only.
+
+   • Reverse.  Reverse a change in the working tree.  Both committed and
+     staged changes can be reversed.  Unstaged changes cannot be
+     reversed.  Discard them instead.
+
+   • Apply.  Apply a change to the working tree.  Both committed and
+     staged changes can be applied.  Unstaged changes cannot be applied
+     - as they already have been applied.
+
+   The previous section described the staging and unstaging commands.
+What follows are the commands which implement the remaining apply
+variants.
+
+‘a’     (‘magit-apply’)
+
+     Apply the change at point to the working tree.
+
+     With a prefix argument fallback to a 3-way merge.  Doing so causes
+     the change to be applied to the index as well.
+
+‘k’     (‘magit-discard’)
+
+     Remove the change at point from the working tree.
+
+‘v’     (‘magit-reverse’)
+
+     Reverse the change at point in the working tree.
+
+     With a prefix argument fallback to a 3-way merge.  Doing so causes
+     the change to be applied to the index as well.
+
+   With a prefix argument all apply variants attempt a 3-way merge when
+appropriate (i.e.  when ‘git apply’ is used internally).
+
+
+File: magit.info,  Node: Committing,  Next: Branching,  Prev: Applying,  Up: Manipulating
+
+6.4 Committing
+==============
+
+When the user initiates a commit, Magit calls ‘git commit’ without any
+arguments, so Git has to get it from the user.  It creates the file
+‘.git/COMMIT_EDITMSG’ and then opens that file in an editor.  Magit
+arranges for that editor to be the Emacsclient.  Once the user finishes
+the editing session, the Emacsclient exits and Git creates the commit
+using the file’s content as message.
+
+* Menu:
+
+* Initiating a Commit::
+* Editing Commit Messages::
+
+
+File: magit.info,  Node: Initiating a Commit,  Next: Editing Commit Messages,  Up: Committing
+
+6.4.1 Initiating a Commit
+-------------------------
+
+Also see *note (gitman)git-commit::.
+
+‘c’     (‘magit-commit-popup’)
+
+     This prefix command shows the following suffix commands along with
+     the appropriate infix arguments in a popup buffer.
+
+‘c c’     (‘magit-commit’)
+
+     Create a new commit on ‘HEAD’.  With a prefix argument amend to the
+     commit at ‘HEAD’ instead.
+
+‘c a’     (‘magit-commit-amend’)
+
+     Amend the last commit.
+
+‘c e’     (‘magit-commit-extend’)
+
+     Amend the last commit, without editing the message.  With a prefix
+     argument keep the committer date, otherwise change it.  The option
+     ‘magit-commit-extend-override-date’ can be used to inverse the
+     meaning of the prefix argument.
+
+     Non-interactively respect the optional OVERRIDE-DATE argument and
+     ignore the option.
+
+‘c w’     (‘magit-commit-reword’)
+
+     Reword the last commit, ignoring staged changes.  With a prefix
+     argument keep the committer date, otherwise change it.  The option
+     ‘magit-commit-reword-override-date’ can be used to inverse the
+     meaning of the prefix argument.
+
+     Non-interactively respect the optional OVERRIDE-DATE argument and
+     ignore the option.
+
+‘c f’     (‘magit-commit-fixup’)
+
+     Create a fixup commit.
+
+     With a prefix argument the target commit has to be confirmed.
+     Otherwise the commit at point may be used without confirmation
+     depending on the value of option ‘magit-commit-squash-confirm’.
+
+‘c F’     (‘magit-commit-instant-fixup’)
+
+     Create a fixup commit and instantly rebase.
+
+‘c s’     (‘magit-commit-squash’)
+
+     Create a squash commit, without editing the squash message.
+
+     With a prefix argument the target commit has to be confirmed.
+     Otherwise the commit at point may be used without confirmation
+     depending on the value of option ‘magit-commit-squash-confirm’.
+
+‘c S’     (‘magit-commit-instant-squash’)
+
+     Create a squash commit and instantly rebase.
+
+‘c A’     (‘magit-commit-augment’)
+
+     Create a squash commit, editing the squash message.
+
+     With a prefix argument the target commit has to be confirmed.
+     Otherwise the commit at point may be used without confirmation
+     depending on the value of option ‘magit-commit-squash-confirm’.
+
+ -- User Option: magit-commit-ask-to-stage
+
+     Whether to ask to stage all unstaged changes when committing and
+     nothing is staged.
+
+ -- User Option: magit-commit-extend-override-date
+
+     Whether using ‘magit-commit-extend’ changes the committer date.
+
+ -- User Option: magit-commit-reword-override-date
+
+     Whether using ‘magit-commit-reword’ changes the committer date.
+
+ -- User Option: magit-commit-squash-confirm
+
+     Whether the commit targeted by squash and fixup has to be
+     confirmed.  When non-nil then the commit at point (if any) is used
+     as default choice.  Otherwise it has to be confirmed.  This option
+     only affects ‘magit-commit-squash’ and ‘magit-commit-fixup’.  The
+     "instant" variants always require confirmation because making an
+     error while using those is harder to recover from.
+
+
+File: magit.info,  Node: Editing Commit Messages,  Prev: Initiating a Commit,  Up: Committing
+
+6.4.2 Editing Commit Messages
+-----------------------------
+
+After initiating a commit as described in the previous section, two new
+buffers appear.  One shows the changes that are about to committed,
+while the other is used to write the message.  All regular editing
+commands are available in the commit message buffer.  This section only
+describes the additional commands.
+
+   Commit messages are edited in an edit session - in the background Git
+is waiting for the editor, in our case the Emacsclient, to save the
+commit message in a file (in most cases ‘.git/COMMIT_EDITMSG’) and then
+return.  If the Emacsclient returns with a non-zero exit status then Git
+does not create the commit.  So the most important commands are those
+for finishing and aborting the commit.
+
+‘C-c C-c’     (‘with-editor-finish’)
+
+     Finish the current editing session by returning with exit code 0.
+     Git then creates the commit using the message it finds in the file.
+
+‘C-c C-k’     (‘with-editor-cancel’)
+
+     Cancel the current editing session by returning with exit code 1.
+     Git then cancels the commit, but leaves the file untouched.
+
+   In addition to being used by Git, these messages may also be stored
+in a ring that persists until Emacs is closed.  By default the message
+is stored at the beginning and the end of an edit session (regardless of
+whether the session is finished successfully or was canceled).  It is
+sometimes useful to bring back messages from that ring.
+
+‘C-c M-s’     (‘git-commit-save-message’)
+
+     Save the current buffer content to the commit message ring.
+
+‘M-p’     (‘git-commit-prev-message’)
+
+     Cycle backward through the commit message ring, after saving the
+     current message to the ring.  With a numeric prefix ARG, go back
+     ARG comments.
+
+‘M-n’     (‘git-commit-next-message’)
+
+     Cycle forward through the commit message ring, after saving the
+     current message to the ring.  With a numeric prefix ARG, go back
+     ARG comments.
+
+   By default the diff for the changes that are about to be committed
+are automatically shown when invoking the commit.  When amending to an
+existing commit it may be useful to show either the changes that are
+about to be added to that commit or to show those changes together with
+those that are already committed.
+
+‘C-c C-d’     (‘magit-diff-while-committing’)
+
+     While committing, show the changes that are about to be committed.
+     While amending, invoking the command again toggles between showing
+     just the new changes or all the changes that will be committed.
+
+‘C-c C-w’     (‘magit-pop-revision-stack’)
+
+     This command inserts a representation of a revision into the
+     current buffer.  It can be used inside buffers used to write commit
+     messages but also in other buffers such as buffers used to edit
+     emails or ChangeLog files.
+
+     By default this command pops the revision which was last added to
+     the ‘magit-revision-stack’ and inserts it into the current buffer
+     according to ‘magit-pop-revision-stack-format’.  Revisions can be
+     put on the stack using ‘magit-copy-section-value’ and
+     ‘magit-copy-buffer-revision’.
+
+     If the stack is empty or with a prefix argument it instead reads a
+     revision in the minibuffer.  By using the minibuffer history this
+     allows selecting an item which was popped earlier or to insert an
+     arbitrary reference or revision without first pushing it onto the
+     stack.
+
+     When reading the revision from the minibuffer, then it might not be
+     possible to guess the correct repository.  When this command is
+     called inside a repository (e.g.  while composing a commit
+     message), then that repository is used.  Otherwise (e.g.  while
+     composing an email) then the repository recorded for the top
+     element of the stack is used (even though we insert another
+     revision).  If not called inside a repository and with an empty
+     stack, or with two prefix arguments, then read the repository in
+     the minibuffer too.
+
+ -- User Option: magit-pop-revision-stack-format
+
+     This option controls how the command ‘magit-pop-revision-stack’
+     inserts a revision into the current buffer.
+
+     The entries on the stack have the format ‘(HASH TOPLEVEL)’ and this
+     option has the format ‘(POINT-FORMAT EOB-FORMAT INDEX-REGEXP)’, all
+     of which may be nil or a string (though either one of EOB-FORMAT or
+     POINT-FORMAT should be a string, and if INDEX-REGEXP is non-nil,
+     then the two formats should be too).
+
+     First INDEX-REGEXP is used to find the previously inserted entry,
+     by searching backward from point.  The first submatch must match
+     the index number.  That number is incremented by one, and becomes
+     the index number of the entry to be inserted.  If you don’t want to
+     number the inserted revisions, then use nil for INDEX-REGEXP.
+
+     If INDEX-REGEXP is non-nil then both POINT-FORMAT and EOB-FORMAT
+     should contain \"%N\", which is replaced with the number that was
+     determined in the previous step.
+
+     Both formats, if non-nil and after removing %N, are then expanded
+     using ‘git show –format=FORMAT ...’ inside TOPLEVEL.
+
+     The expansion of POINT-FORMAT is inserted at point, and the
+     expansion of EOB-FORMAT is inserted at the end of the buffer (if
+     the buffer ends with a comment, then it is inserted right before
+     that).
+
+   Some projects use pseudo headers in commit messages.  Magit colorizes
+such headers and provides some commands to insert such headers.
+
+ -- User Option: git-commit-known-pseudo-headers
+
+     A list of Git pseudo headers to be highlighted.
+
+‘C-c C-a’     (‘git-commit-ack’)
+
+     Insert a header acknowledging that you have looked at the commit.
+
+‘C-c C-r’     (‘git-commit-review’)
+
+     Insert a header acknowledging that you have reviewed the commit.
+
+‘C-c C-s’     (‘git-commit-signoff’)
+
+     Insert a header to sign off the commit.
+
+‘C-c C-t’     (‘git-commit-test’)
+
+     Insert a header acknowledging that you have tested the commit.
+
+‘C-c C-o’     (‘git-commit-cc’)
+
+     Insert a header mentioning someone who might be interested.
+
+‘C-c C-p’     (‘git-commit-reported’)
+
+     Insert a header mentioning the person who reported the issue being
+     fixed by the commit.
+
+‘C-c C-i’     (‘git-commit-suggested’)
+
+     Insert a header mentioning the person who suggested the change.
+
+   ‘git-commit-mode’ is a minor mode that is only used to establish the
+above key bindings.  This allows using an arbitrary major mode when
+editing the commit message.  It’s even possible to use a different major
+mode in different repositories, which is useful when different projects
+impose different commit message conventions.
+
+ -- User Option: git-commit-major-mode
+
+     The value of this option is the major mode used to edit Git commit
+     messages.
+
+   Because ‘git-commit-mode’ is a minor mode, we don’t use its mode hook
+to setup the buffer, except for the key bindings.  All other setup
+happens in the function ‘git-commit-setup’, which among other things
+runs the hook ‘git-commit-setup-hook’.  The following functions are
+suitable for that hook.
+
+ -- User Option: git-commit-setup-hook
+
+     Hook run at the end of ‘git-commit-setup’.
+
+ -- Function: magit-revert-buffers &optional force
+
+     Revert unmodified file-visiting buffers of the current repository.
+
+     If either ‘magit-revert-buffers’ is non-nil and
+     ‘inhibit-magit-revert’ is nil, or if optional FORCE is non-nil,
+     then revert all unmodified buffers that visit files being tracked
+     in the current repository.
+
+ -- Function: git-commit-save-message
+
+     Save the current buffer content to the commit message ring.
+
+ -- Function: git-commit-setup-changelog-support
+
+     After this function is called, ChangeLog entries are treated as
+     paragraphs.
+
+ -- Function: git-commit-turn-on-auto-fill
+
+     Turn on ‘auto-fill-mode’ and set ‘fill-column’ to the value of
+     ‘git-commit-fill-column’.
+
+ -- Function: git-commit-turn-on-flyspell
+
+     Turn on Flyspell mode.  Also prevent comments from being checked
+     and finally check current non-comment text.
+
+ -- Function: git-commit-propertize-diff
+
+     Propertize the diff shown inside the commit message buffer.  Git
+     inserts such diffs into the commit message template when the
+     ‘--verbose’ argument is used.  Magit’s commit popup by default does
+     not offer that argument because the diff that is shown in a
+     separate buffer is more useful.  But some users disagree, which is
+     why this function exists.
+
+ -- Function: with-editor-usage-message
+
+     Show usage information in the echo area.
+
+   Magit also helps with writing *good* commit messages by complaining
+when certain rules are violated.
+
+ -- User Option: git-commit-summary-max-length
+
+     The intended maximal length of the summary line of commit messages.
+     Characters beyond this column are colorized to indicate that this
+     preference has been violated.
+
+ -- User Option: git-commit-fill-column
+
+     Column beyond which automatic line-wrapping should happen in commit
+     message buffers.
+
+ -- User Option: git-commit-finish-query-functions
+
+     List of functions called to query before performing commit.
+
+     The commit message buffer is current while the functions are
+     called.  If any of them returns nil, then the commit is not
+     performed and the buffer is not killed.  The user should then fix
+     the issue and try again.
+
+     The functions are called with one argument.  If it is non-nil then
+     that indicates that the user used a prefix argument to force
+     finishing the session despite issues.  Functions should usually
+     honor this wish and return non-nil.
+
+ -- Function: git-commit-check-style-conventions
+
+     Check for violations of certain basic style conventions.  For each
+     violation ask the user if she wants to proceed anyway.  This makes
+     sure the summary line isn’t too long and that the second line is
+     empty.
+
+   To show no diff while committing remove ‘magit-commit-diff’ from
+‘server-switch-hook’.
+
+
+File: magit.info,  Node: Branching,  Next: Merging,  Prev: Committing,  Up: Manipulating
+
+6.5 Branching
+=============
+
+* Menu:
+
+* The Two Remotes::
+* The Branch Popup::
+* The Branch Config Popup::
+* Auxillary Branch Commands::
+
+
+File: magit.info,  Node: The Two Remotes,  Next: The Branch Popup,  Up: Branching
+
+6.5.1 The Two Remotes
+---------------------
+
+The upstream branch of some local branch is the branch into which the
+commits on that local branch should eventually be merged, usually
+something like ‘origin/master’.  For the ‘master’ branch itself the
+upstream branch and the branch it is being pushed to, are usually the
+same remote branch.  But for a feature branch the upstream branch and
+the branch it is being pushed to should differ.
+
+   The commits on feature branches too should _eventually_ end up in a
+remote branch such as ‘origin/master’ or ‘origin/maint’.  Such a branch
+should therefore be used as the upstream.  But feature branches
+shouldn’t be pushed directly to such branches.  Instead a feature branch
+‘my-feature’ is usually pushed to ‘my-fork/my-feature’ or if you are a
+contributor ‘origin/my-feature’.  After the new feature has been
+reviewed, the maintainer merges the feature into ‘master’.  And finally
+‘master’ (not ‘my-feature’ itself) is pushed to ‘origin/master’.
+
+   But new features seldom are perfect on the first try, and so feature
+branches usually have to be reviewed, improved, and re-pushed several
+times.  Pushing should therefore be easy to do, and for that reason many
+Git users have concluded that it is best to use the remote branch to
+which the local feature branch is being pushed as its upstream.
+
+   But luckily Git has long ago gained support for a push-remote which
+can be configured separately from the upstream branch, using the
+variables ‘branch.<name>.pushRemote’ and ‘remote.pushDefault’.  So we no
+longer have to choose which of the two remotes should be used as "the
+remote".
+
+   Each of the fetching, pulling, and pushing popups features three
+commands that act on the current branch and some other branch.  Of
+these, ‘p’ is bound to a command which acts on the push-remote, ‘u’ is
+bound to a command which acts on the upstream, and ‘e’ is bound to a
+command which acts on any other branch.  The status buffer shows
+unpushed and unpulled commits for both the push-remote and the upstream.
+
+   It’s fairly simple to configure these two remotes.  The values of all
+the variables that are related to fetching, pulling, and pushing (as
+well as some other branch-related variables) can be inspected and
+changed using the popup ‘magit-branch-config-popup’, which is a
+sub-popup of many popups that deal with branches.  It is also possible
+to set the push-remote or upstream while pushing (see *note Pushing::).
+
+
+File: magit.info,  Node: The Branch Popup,  Next: The Branch Config Popup,  Prev: The Two Remotes,  Up: Branching
+
+6.5.2 The Branch Popup
+----------------------
+
+The popup ‘magit-branch-popup’ is used to create and checkout branches,
+and to make changes to existing branches.  It is not used to fetch,
+pull, merge, rebase, or push branches, i.e.  this popup deals with
+branches themselves, not with the commits reachable from them.  Those
+features are available from separate popups.
+
+‘b’     (‘magit-branch-popup’)
+
+     This prefix command shows the following suffix commands in a popup
+     buffer.
+
+     By default it also displays the values of some branch-related Git
+     variables and allows changing their values, just like the
+     specialized ‘magit-branch-config-popup’ does.
+
+ -- User Option: magit-branch-popup-show-variables
+
+     Whether the ‘magit-branch-popup’ shows Git variables.  This
+     defaults to t to avoid changing key bindings.  When set to nil, no
+     variables are displayed directly in this popup, and the sub-popup
+     ‘magit-branch-config-popup’ has to be used instead to view and
+     change branch related variables.
+
+‘b C’     (‘magit-branch-config-popup’)
+
+     This command shows branch related variables in a separate popup.
+     By default this asks the user for which branch the variables should
+     be shown.  When ‘magit-branch-popup-show-variables’ is ‘nil’, then
+     it shows the variables for the current branch, unless a prefix
+     argument is used.
+
+‘b b’     (‘magit-checkout’)
+
+     Checkout a revision read in the minibuffer and defaulting to the
+     branch or arbitrary revision at point.  If the revision is a local
+     branch then that becomes the current branch.  If it is something
+     else then ‘HEAD’ becomes detached.  Checkout fails if the working
+     tree or the staging area contain changes.
+
+‘b n’     (‘magit-branch’)
+
+     Create a new branch.  The user is asked for a branch or arbitrary
+     revision to use as the starting point of the new branch.  When a
+     branch name is provided, then that becomes the upstream branch of
+     the new branch.  The name of the new branch is also read in the
+     minibuffer.
+
+     Also see option ‘magit-branch-prefer-remote-upstream’.
+
+‘b c’     (‘magit-branch-and-checkout’)
+
+     This command creates a new branch like ‘magit-branch’, but then
+     also checks it out.
+
+     Also see option ‘magit-branch-prefer-remote-upstream’.
+
+‘b l’     (‘magit-branch-checkout’)
+
+     This command checks out an existing or new local branch.  It reads
+     a branch name from the user offering all local branches and a
+     subset of remote branches as candidates.  Remote branches for which
+     a local branch by the same name exists are omitted from the list of
+     candidates.  The user can also enter a completely new branch name.
+
+        • If the user selects an existing local branch, then that is
+          checked out.
+
+        • If the user selects a remote branch, then it creates and
+          checks out a new local branch with the same name, and
+          configures the selected remote branch as the push target.
+
+        • If the user enters a new branch name, then it creates and
+          checks that out, after also reading the starting-point from
+          the user.
+
+     In the latter two cases the upstream is also set.  Whether it is
+     set to the chosen starting point or something else depends on the
+     value of ‘magit-branch-adjust-remote-upstream-alist’.
+
+‘b s’     (‘magit-branch-spinoff’)
+
+     This command creates and checks out a new branch starting at and
+     tracking the current branch.  That branch in turn is reset to the
+     last commit it shares with its upstream.  If the current branch has
+     no upstream or no unpushed commits, then the new branch is created
+     anyway and the previously current branch is not touched.
+
+     This is useful to create a feature branch after work has already
+     began on the old branch (likely but not necessarily "master").
+
+     If the current branch is a member of the value of option
+     ‘magit-branch-prefer-remote-upstream’ (which see), then the current
+     branch will be used as the starting point as usual, but the
+     upstream of the starting-point may be used as the upstream of the
+     new branch, instead of the starting-point itself.
+
+     If optional FROM is non-nil, then the source branch is reset to
+     ‘FROM~’, instead of to the last commit it shares with its upstream.
+     Interactively, FROM is only ever non-nil, if the region selects
+     some commits, and among those commits, FROM is the commit that is
+     the fewest commits ahead of the source branch.
+
+     The commit at the other end of the selection actually does not
+     matter, all commits between FROM and ‘HEAD’ are moved to the new
+     branch.  If FROM is not reachable from ‘HEAD’ or is reachable from
+     the source branch’s upstream, then an error is raised.
+
+‘b Y’     (‘magit-branch-pull-request’)
+
+     This command creates and configures a new branch from a Github
+     pull-request, creating and configuring a new remote if necessary.
+
+     The name of the local branch is the same as the name of the remote
+     branch that you are being asked to merge, unless the contributor
+     could not be bother to properly name the branch before opening the
+     pull-request.  The most likely such case is when you are being
+     asked to merge something like "fork/master" into "origin/master".
+     In such cases the local branch will be named "pr-N", where ‘N’ is
+     the pull-request number.
+
+     These variables are always set by this command:
+
+        • ‘branch.<name>.pullRequest’ is set to the pull-request number.
+
+        • ‘branch.<name>.pullRequestRemote’ is set to the remote on
+          which the pull-request branch is located.
+
+        • ‘branch.<name>.pushRemote’ is set to the same remote as
+          ‘branch.<name>.pullRequestRemote’ if that is possible,
+          otherwise it is set to the upstream remote.
+
+        • ‘branch.<name>.description’ is set to the pull-request title.
+
+        • ‘branch.<name>.rebase’ is set to ‘true’ because there should
+          be no merge commits among the commits in a pull-request.
+
+     This command also configures the upstream and the push-remote of
+     the local branch that it creates.
+
+     The branch against which the pull-request was opened, is always
+     used as the upstream.  This makes it easy to see what commits you
+     are being asked to merge in the section titled something like
+     "Unmerged into origin/master".
+
+     Like for other commands that create a branch it depends on the
+     option ‘magit-branch-prefer-remote-upstream’ whether the remote
+     branch itself or the respective local branch is used as the
+     upstream, so this section may also be titled e.g.  "Unmerged into
+     master".
+
+     When necessary and possible, then the remote pull-request branch is
+     configured to be used as the push-target.  This makes it easy to
+     see what further changes the contributor has made since you last
+     reviewed their changes in the section titled something like
+     "Unpulled from origin/new-feature" or "Unpulled from
+     fork/new-feature".
+
+        • If the pull-request branch is located in the upstream
+          repository, then you probably have set ‘remote.pushDefault’ to
+          that repository.  However some users like to set that variable
+          to their personal fork, even if they have push access to the
+          upstream, so ‘branch.<name>.pushRemote’ is set anyway.
+
+        • If the pull-request branch is located inside a fork, then you
+          are usually able to push to that branch, because Github by
+          default allows the recipient of a pull-request to push to the
+          remote pull-request branch even if it is located in a fork.
+          The contributor has to explicitly disable this.
+
+             • If you are not allowed to push to the pull-request branch
+               on the fork, then a branch by the same name located in
+               the upstream repository is configured as the push-target.
+
+             • A — sadly rather common — special case is when the
+               contributor didn’t bother to use a dedicated branch for
+               the pull-request.
+
+               The most likely such case is when you are being asked to
+               merge something like "fork/master" into "origin/master".
+               The special push permission mentioned above is never
+               granted for the branch that is the repository’s default
+               branch, and that would almost certainly be the case in
+               this scenario.
+
+               To enable you to easily push somewhere anyway, the local
+               branch is named "pr-N" (where ‘N’ is the pull-request
+               number) and the upstream repository is used as the
+               push-remote.
+
+             • Finally, if you are allowed to push to the pull-request
+               branch and the contributor had the foresight to use a
+               dedicated branch, then the fork is configured as the
+               push-remote.
+
+          The push-remote is configured using
+          ‘branch.<name>.pushRemote’, even if the used value is
+          identical to that of ‘remote.pushDefault’, just in case you
+          change the value of the latter later on.  Additionally the
+          variable ‘branch.<name>.pullRequestRemote’ is set to the
+          remote on which the pull-request branch is located.
+
+     When you later delete the local pull-request branch, then you are
+     offered to also delete the corresponding remote, provided it is not
+     the upstream remote and that the tracking branch that corresponds
+     to the deleted branch is the only remaining tracked branch.  If you
+     don’t confirm, then only the tracking branch itself is deleted in
+     addition to the local branch.
+
+     Do not delete the tracking branch instead of the local branch.  The
+     cleanup mentioned in the previous paragraph is not performed if you
+     do that.
+
+‘b y’     (‘magit-checkout-pull-request’)
+
+     This command creates and configures a new branch from a pull
+     request, the same way ‘magit-branch-pull-request’ does.
+     Additionally it checks out the new branch.
+
+‘b x’     (‘magit-branch-reset’)
+
+     This command resets a branch, defaulting to the branch at point, to
+     the tip of another branch or any other commit.
+
+     When the branch being reset is the current branch, then a hard
+     reset is performed.  If there are any uncommitted changes, then the
+     user has to confirm the reset because those changes would be lost.
+
+     This is useful when you have started work on a feature branch but
+     realize it’s all crap and want to start over.
+
+     When resetting to another branch and a prefix argument is used,
+     then the target branch is set as the upstream of the branch that is
+     being reset.
+
+‘b k’     (‘magit-branch-delete’)
+
+     Delete one or multiple branches.  If the region marks multiple
+     branches, then offer to delete those.  Otherwise, prompt for a
+     single branch to be deleted, defaulting to the branch at point.
+
+‘b r’     (‘magit-branch-rename’)
+
+     Rename a branch.  The branch and the new name are read in the
+     minibuffer.  With prefix argument the branch is renamed even if
+     that name conflicts with an existing branch.
+
+ -- User Option: magit-branch-read-upstream-first
+
+     When creating a branch, whether to read the upstream branch before
+     the name of the branch that is to be created.  The default is
+     ‘nil’, and I recommend you leave it at that.
+
+ -- User Option: magit-branch-prefer-remote-upstream
+
+     This option specifies whether remote upstreams are favored over
+     local upstreams when creating new branches.
+
+     When a new branch is created, then the branch, commit, or stash at
+     point is suggested as the starting point of the new branch, or if
+     there is no such revision at point the current branch.  In either
+     case the user may choose another starting point.
+
+     If the chosen starting point is a branch, then it may also be set
+     as the upstream of the new branch, depending on the value of the
+     Git variable ‘branch.autoSetupMerge’.  By default this is done for
+     remote branches, but not for local branches.
+
+     You might prefer to always use some remote branch as upstream.  If
+     the chosen starting point is (1) a local branch, (2) whose name
+     matches a member of the value of this option, (3) the upstream of
+     that local branch is a remote branch with the same name, and (4)
+     that remote branch can be fast-forwarded to the local branch, then
+     the chosen branch is used as starting point, but its own upstream
+     is used as the upstream of the new branch.
+
+     Members of this option’s value are treated as branch names that
+     have to match exactly unless they contain a character that makes
+     them invalid as a branch name.  Recommended characters to use to
+     trigger interpretation as a regexp are "*" and "^".  Some other
+     characters which you might expect to be invalid, actually are not,
+     e.g.  ".+$" are all perfectly valid.  More precisely, if ‘git
+     check-ref-format –branch STRING’ exits with a non-zero status, then
+     treat STRING as a regexp.
+
+     Assuming the chosen branch matches these conditions you would end
+     up with with e.g.:
+
+          feature --upstream--> origin/master
+
+     instead of
+
+          feature --upstream--> master --upstream--> origin/master
+
+     Which you prefer is a matter of personal preference.  If you do
+     prefer the former, then you should add branches such as ‘master’,
+     ‘next’, and ‘maint’ to the value of this options.
+
+ -- User Option: magit-branch-adjust-remote-upstream-alist
+
+     The value of this option is an alist of branches to be used as the
+     upstream when branching a remote branch.
+
+     When creating a local branch from an ephemeral branch located on a
+     remote, e.g.  a feature or hotfix branch, then that remote branch
+     should usually not be used as the upstream branch, since the
+     push-remote already allows accessing it and having both the
+     upstream and the push-remote reference the same related branch
+     would be wasteful.  Instead a branch like "maint" or "master"
+     should be used as the upstream.
+
+     This option allows specifying the branch that should be used as the
+     upstream when branching certain remote branches.  The value is an
+     alist of the form ‘((UPSTREAM . RULE)...)’.  The first matching
+     element is used, the following elements are ignored.
+
+     UPSTREAM is the branch to be used as the upstream for branches
+     specified by RULE.  It can be a local or a remote branch.
+
+     RULE can either be a regular expression, matching branches whose
+     upstream should be the one specified by UPSTREAM.  Or it can be a
+     list of the only branches that should *not* use UPSTREAM; all other
+     branches will.  Matching is done after stripping the remote part of
+     the name of the branch that is being branched from.
+
+     If you use a finite set of non-ephemeral branches across all your
+     repositories, then you might use something like:
+
+          (("origin/master" "master" "next" "maint"))
+
+     Or if the names of all your ephemeral branches contain a slash, at
+     least in some repositories, then a good value could be:
+
+          (("origin/master" . "/"))
+
+     Of course you can also fine-tune:
+
+          (("origin/maint" . "\\`hotfix/")
+           ("origin/master" . "\\`feature/"))
+
+ -- Command: magit-branch-orphan
+
+     This command creates and checks out a new orphan branch with
+     contents from a given revision.
+
+ -- Command: magit-branch-or-checkout
+
+     This command is a hybrid between ‘magit-checkout’ and
+     ‘magit-branch-and-checkout’ and is intended as a replacement for
+     the former in ‘magit-branch-popup’.
+
+     It first asks the user for an existing branch or revision.  If the
+     user input actually can be resolved as a branch or revision, then
+     it checks that out, just like ‘magit-checkout’ would.
+
+     Otherwise it creates and checks out a new branch using the input as
+     its name.  Before doing so it reads the starting-point for the new
+     branch.  This is similar to what ‘magit-branch-and-checkout’ does.
+
+     To use this command instead of ‘magit-checkout’ add this to your
+     init file:
+
+          (magit-remove-popup-key 'magit-branch-popup :action ?b)
+          (magit-define-popup-action 'magit-branch-popup
+            ?b "Checkout" 'magit-branch-or-checkout
+            'magit-branch t)
+
+
+File: magit.info,  Node: The Branch Config Popup,  Next: Auxillary Branch Commands,  Prev: The Branch Popup,  Up: Branching
+
+6.5.3 The Branch Config Popup
+-----------------------------
+
+ -- Command: magit-branch-config-popup
+
+     This prefix command shows the following branch-related Git
+     variables in a popup buffer.  The values can be changed from that
+     buffer.
+
+     This popup is a sub-popup of several popups that deal with
+     branches, including ‘magit-branch-popup’, ‘magit-pull-popup’,
+     ‘magit-fetch-popup’, ‘magit-pull-and-fetch-popup’, and
+     ‘magit-push-popup’.  In all of these popups "C" is bound to this
+     popup.
+
+   The following variables are used to configure a specific branch.  The
+values are being displayed for the current branch (if any).  To change
+the value for another branch invoke ‘magit-branch-config-popup’ with a
+prefix argument.
+
+ -- Variable: branch.NAME.merge
+
+     Together with ‘branch.NAME.remote’ this variable defines the
+     upstream branch of the local branch named NAME.  The value of this
+     variable is the full reference of the upstream _branch_.
+
+ -- Variable: branch.NAME.remote
+
+     Together with ‘branch.NAME.merge’ this variable defines the
+     upstream branch of the local branch named NAME.  The value of this
+     variable is the name of the upstream _remote_.
+
+ -- Variable: branch.NAME.rebase
+
+     This variable controls whether pulling into the branch named NAME
+     is done by rebasing or by merging the fetched branch.
+
+        • When ‘true’ then pulling is done by rebasing.
+
+        • When ‘false’ then pulling is done by merging.
+
+        • When undefined then the value of ‘pull.rebase’ is used.  The
+          default of that variable is ‘false’.
+
+ -- Variable: branch.NAME.pushRemote
+
+     This variable specifies the remote that the branch named NAME is
+     usually pushed to.  The value has to be the name of an existing
+     remote.
+
+     It is not possible to specify the name of _branch_ to push the
+     local branch to.  The name of the remote branch is always the same
+     as the name of the local branch.
+
+     If this variable is undefined but ‘remote.pushDefault’ is defined,
+     then the value of the latter is used.  By default
+     ‘remote.pushDefault’ is undefined.
+
+ -- Variable: branch.NAME.description
+
+     This variable can be used to describe the branch named NAME.  That
+     description is used e.g.  when turning the branch into a series of
+     patches.
+
+   The following variables specify defaults which are used if the above
+branch-specific variables are not set.
+
+ -- Variable: pull.rebase
+
+     This variable specifies whether pulling is done by rebasing or by
+     merging.  It can be overwritten using ‘branch.NAME.rebase’.
+
+        • When ‘true’ then pulling is done by rebasing.
+
+        • When ‘false’ (the default) then pulling is done by merging.
+
+     Since it is never a good idea to merge the upstream branch into a
+     feature or hotfix branch and most branches are such branches, you
+     should consider setting this to ‘true’, and ‘branch.master.rebase’
+     to ‘false’.
+
+ -- Variable: remote.pushDefault
+
+     This variable specifies what remote the local branches are usually
+     pushed to.  This can be overwritten per branch using
+     ‘branch.NAME.pushRemote’.
+
+   The following variables are used during the creation of a branch and
+control whether the various branch-specific variables are automatically
+set at this time.
+
+ -- Variable: branch.autoSetupMerge
+
+     This variable specifies under what circumstances creating a branch
+     NAME should result in the variables ‘branch.NAME.merge’ and
+     ‘branch.NAME.remote’ being set according to the starting point used
+     to create the branch.  If the starting point isn’t a branch, then
+     these variables are never set.
+
+        • When ‘always’ then the variables are set regardless of whether
+          the starting point is a local or a remote branch.
+
+        • When ‘true’ (the default) then the variables are set when the
+          starting point is a remote branch, but not when it is a local
+          branch.
+
+        • When ‘false’ then the variables are never set.
+
+ -- Variable: branch.autoSetupRebase
+
+     This variable specifies whether creating a branch NAME should
+     result in the variable ‘branch.NAME.rebase’ being set to ‘true’.
+
+        • When ‘always’ then the variable is set regardless of whether
+          the starting point is a local or a remote branch.
+
+        • When ‘local’ then the variable are set when the starting point
+          is a local branch, but not when it is a remote branch.
+
+        • When ‘remote’ then the variable are set when the starting
+          point is a remote branch, but not when it is a local branch.
+
+        • When ‘never’ (the default) then the variable is never set.
+
+   Note that the respective commands always change the repository-local
+values.  If you want to change the global value, which is used when the
+local value is undefined, then you have to do so on the command line,
+e.g.:
+
+     git config --global remote.autoSetupMerge always
+
+   For more information about these variables you should also see
+
+   *note (gitman)git-config::.  Also see *note (gitman)git-branch::.  ,
+*note (gitman)git-checkout::.  and *note Pushing::.
+
+ -- User Option: magit-prefer-remote-upstream
+
+     This option controls whether commands that read a branch from the
+     user and then set it as the upstream branch, offer a local or a
+     remote branch as default completion candidate, when they have the
+     choice.
+
+     This affects all commands that use ‘magit-read-upstream-branch’ or
+     ‘magit-read-starting-point’, which includes all commands that
+     change the upstream and many which create new branches.
+
+
+File: magit.info,  Node: Auxillary Branch Commands,  Prev: The Branch Config Popup,  Up: Branching
+
+6.5.4 Auxillary Branch Commands
+-------------------------------
+
+These commands are not available from the branch popup by default.
+
+ -- Command: magit-branch-shelve
+
+     This command shelve a branch.  This is done by deleting the branch,
+     and creating a new reference "refs/shelved/BRANCH-NAME" pointing at
+     the same commit as the branch pointed at.  If the deleted branch
+     had a reflog, then that is preserved as the reflog of the new
+     reference.
+
+     This is useful if you want to move a branch out of sight, but are
+     not ready to completely discard it yet.
+
+ -- Command: magit-branch-unshelve
+
+     This command unshelve a branch that was previously shelved using
+     ‘magit-branch-shelve’.  This is done by deleting the reference
+     "refs/shelved/BRANCH-NAME" and creating a branch "BRANCH-NAME"
+     pointing at the same commit as the deleted reference pointed at.
+     If the deleted reference had a reflog, then that is restored as the
+     reflog of the branch.
+
+
+File: magit.info,  Node: Merging,  Next: Resolving Conflicts,  Prev: Branching,  Up: Manipulating
+
+6.6 Merging
+===========
+
+Also see *note (gitman)git-merge::.  For information on how to resolve
+merge conflicts see the next section.
+
+‘m’     (‘magit-merge-popup’)
+
+     This prefix command shows the following suffix commands along with
+     the appropriate infix arguments in a popup buffer.
+
+   When no merge is in progress, then the popup buffer features the
+following commands.
+
+‘m m’     (‘magit-merge’)
+
+     This command merges another branch or an arbitrary revision into
+     the current branch.  The branch or revision to be merged is read in
+     the minibuffer and defaults to the branch at point.
+
+     Unless there are conflicts or a prefix argument is used, then the
+     resulting merge commit uses a generic commit message, and the user
+     does not get a chance to inspect or change it before the commit is
+     created.  With a prefix argument this does not actually create the
+     merge commit, which makes it possible to inspect how conflicts were
+     resolved and to adjust the commit message.
+
+‘m e’     (‘magit-merge-editmsg’)
+
+     This command merges another branch or an arbitrary revision into
+     the current branch and opens a commit message buffer, so that the
+     user can make adjustments.  The commit is not actually created
+     until the user finishes with ‘C-c C-c’.
+
+‘m n’     (‘magit-merge-nocommit’)
+
+     This command merges another branch or an arbitrary revision into
+     the current branch, but does not actually create the merge commit.
+     The user can then further adjust the merge, even when automatic
+     conflict resolution succeeded and/or adjust the commit message.
+
+‘m a’     (‘magit-merge-absorb’)
+
+     This command merges another local branch into the current branch
+     and then removes the former.
+
+     Before the source branch is merged, it is first force pushed to its
+     push-remote, provided the respective remote branch already exists.
+     This ensures that the respective pull-request (if any) won’t get
+     stuck on some obsolete version of the commits that are being
+     merged.  Finally, if ‘magit-branch-pull-request’ was used to create
+     the merged branch, then the respective remote branch is also
+     removed.
+
+‘m i’     (‘magit-merge-into’)
+
+     This command merges the current branch into another local branch
+     and then removes the former.  The latter becomes the new current
+     branch.
+
+     Before the source branch is merged, it is first force pushed to its
+     push-remote, provided the respective remote branch already exists.
+     This ensures that the respective pull-request (if any) won’t get
+     stuck on some obsolete version of the commits that are being
+     merged.  Finally, if ‘magit-branch-pull-request’ was used to create
+     the merged branch, then the respective remote branch is also
+     removed.
+
+‘m s’     (‘magit-merge-squash’)
+
+     This command squashes the changes introduced by another branch or
+     an arbitrary revision into the current branch.  This only applies
+     the changes made by the squashed commits.  No information is
+     preserved that would allow creating an actual merge commit.
+     Instead of this command you should probably use a command from the
+     apply popup.
+
+‘m p’     (‘magit-merge-preview’)
+
+     This command shows a preview of merging another branch or an
+     arbitrary revision into the current branch.
+
+   When a merge is in progress, then the popup buffer features these
+commands instead.
+
+‘m m’     (‘magit-merge’)
+
+     After the user resolved conflicts, this command proceeds with the
+     merge.  If some conflicts weren’t resolved, then this command
+     fails.
+
+‘m a’     (‘magit-merge-abort’)
+
+     This command aborts the current merge operation.
+
+
+File: magit.info,  Node: Resolving Conflicts,  Next: Rebasing,  Prev: Merging,  Up: Manipulating
+
+6.7 Resolving Conflicts
+=======================
+
+When merging branches (or otherwise combining or changing history)
+conflicts can occur.  If you edited two completely different parts of
+the same file in two branches and then merge one of these branches into
+the other, then Git can resolve that on its own, but if you edit the
+same area of a file, then a human is required to decide how the two
+versions, or "sides of the conflict", are to be combined into one.
+
+   Here we can only provide a brief introduction to the subject and
+point you toward some tools that can help.  If you are new to this, then
+please also consult Git’s own documentation as well as other resources.
+
+   If a file has conflicts and Git cannot resolve them by itself, then
+it puts both versions into the affected file along with special markers
+whose purpose is to denote the boundaries of the unresolved part of the
+file and between the different versions.  These boundary lines begin
+with the strings consisting of six times the same character, one of ‘<’,
+‘|’, ‘=’ and ‘>’ and are followed by information about the source of the
+respective versions, e.g.:
+
+     <<<<<<< HEAD
+     Take the blue pill.
+     =======
+     Take the red pill.
+     >>>>>>> feature
+
+   In this case you have chosen to take the red pill on one branch and
+on another you picked the blue pill.  Now that you are merging these two
+diverging branches, Git cannot possibly know which pill you want to
+take.
+
+   To resolve that conflict you have to create a version of the affected
+area of the file by keeping only one of the sides, possibly by editing
+it in order to bring in the changes from the other side, remove the
+other versions as well as the markers, and then stage the result.  A
+possible resolution might be:
+
+     Take both pills.
+
+   Often it is useful to see not only the two sides of the conflict but
+also the "original" version from before the same area of the file was
+modified twice on different branches.  Instruct Git to insert that
+version as well by running this command once:
+
+     git config --global merge.conflictStyle diff3
+
+   The above conflict might then have looked like this:
+
+     <<<<<<< HEAD
+     Take the blue pill.
+     ||||||| merged common ancestors
+     Take either the blue or the red pill, but not both.
+     =======
+     Take the red pill.
+     >>>>>>> feature
+
+   If that were the case, then the above conflict resolution would not
+have been correct, which demonstrates why seeing the original version
+alongside the conflicting versions can be useful.
+
+   You can perform the conflict resolution completely by hand, but Emacs
+also provides some packages that help in the process: Smerge, Ediff
+(*note (ediff)Top::), and Emerge (*note (emacs)Emerge::).  Magit does
+not provide its own tools for conflict resolution, but it does make
+using Smerge and Ediff more convenient.  (Ediff supersedes Emerge, so
+you probably don’t want to use the latter anyway.)
+
+   In the Magit status buffer, files with unresolved conflicts are
+listed in the "Unstaged changes" and/or "Staged changes" sections.  They
+are prefixed with the word "unmerged", which in this context essentially
+is a synonym for "unresolved".
+
+   Pressing ‘RET’ while point is on such a file section shows a buffer
+visiting that file, turns on ‘smerge-mode’ in that buffer, and places
+point inside the first area with conflicts.  You should then resolve
+that conflict using regular edit commands and/or Smerge commands.
+
+   Unfortunately Smerge does not have a manual, but you can get a list
+of commands and binding ‘C-c ^ C-h’ and press ‘RET’ while point is on a
+command name to read its documentation.
+
+   Normally you would edit one version and then tell Smerge to keep only
+that version.  Use ‘C-c ^ m’ (‘smerge-keep-mine’) to keep the ‘HEAD’
+version or ‘C-c ^ o’ (‘smerge-keep-other’) to keep the version that
+follows "|||||||".  Then use ‘C-c ^ n’ to move to the next conflicting
+area in the same file.  Once you are done resolving conflicts, return to
+the Magit status buffer.  The file should now be shown as "modified", no
+longer as "unmerged", because Smerge automatically stages the file when
+you save the buffer after resolving the last conflict.
+
+   Alternatively you could use Ediff, which uses separate buffers for
+the different versions of the file.  To resolve conflicts in a file
+using Ediff press ‘e’ while point is on such a file in the status
+buffer.
+
+   Ediff can be used for other purposes as well.  For more information
+on how to enter Ediff from Magit, see *note Ediffing::.  Explaining how
+to use Ediff is beyond the scope of this manual, instead see *note
+(ediff)Top::.
+
+   If you are unsure whether you should Smerge or Ediff, then use the
+former.  It is much easier to understand and use, and except for truly
+complex conflicts, the latter is usually overkill.
+
+
+File: magit.info,  Node: Rebasing,  Next: Cherry Picking,  Prev: Resolving Conflicts,  Up: Manipulating
+
+6.8 Rebasing
+============
+
+Also see *note (gitman)git-rebase::.  For information on how to resolve
+conflicts that occur during rebases see the preceding section.
+
+‘r’     (‘magit-rebase-popup’)
+
+     This prefix command shows the following suffix commands along with
+     the appropriate infix arguments in a popup buffer.
+
+   When no rebase is in progress, then the popup buffer features the
+following commands.
+
+   Using one of these commands _starts_ a rebase sequence.  Git might
+then stop somewhere along the way, either because you told it to do so,
+or because applying a commit failed due to a conflict.  When that
+happens, then the status buffer shows information about the rebase
+sequence which is in progress in a section similar to a log section.
+See *note Information About In-Progress Rebase::.
+
+‘r p’     (‘magit-rebase-onto-pushremote’)
+
+     Rebase the current branch onto ‘branch.<name>.pushRemote’.  If that
+     variable is unset, then rebase onto ‘remote.pushDefault’.
+
+‘r u’     (‘magit-rebase-onto-upstream’)
+
+     Rebase the current branch onto its upstream branch.
+
+‘r e’     (‘magit-rebase’)
+
+     Rebase the current branch onto a branch read in the minibuffer.
+     All commits that are reachable from head but not from the selected
+     branch TARGET are being rebased."
+
+‘r s’     (‘magit-rebase-subset’)
+
+     Start a non-interactive rebase sequence with commits from START to
+     ‘HEAD’ onto NEWBASE.  START has to be selected from a list of
+     recent commits.
+
+   By default Magit uses the ‘--autostash’ argument, which causes
+uncommitted changes to be stored in a stash before the rebase begins.
+These changes are restored after the rebase completes and if possible
+the stash is removed.  If the stash does not apply cleanly, then the
+stash is not removed.  In case something goes wrong when resolving the
+conflicts, this allows you to start over.
+
+   Even though one of the actions is dedicated to interactive rebases,
+the popup also features the infix argument ‘--interactive’.  This can be
+used to turn one of the other, non-interactive rebase variants into an
+interactive rebase.
+
+   For example if you want to clean up a feature branch and at the same
+time rebase it onto ‘master’, then you could use ‘r-iu’.  But we
+recommend that you instead do that in two steps.  First use ‘ri’ to
+cleanup the feature branch, and then in a second step ‘ru’ to rebase it
+onto ‘master’.  That way if things turn out to be more complicated than
+you thought and/or you make a mistake and have to start over, then you
+only have to redo half the work.
+
+   Explicitly enabling ‘--interactive’ won’t have an effect on the
+following commands as they always use that argument anyway, even if it
+is not enabled in the popup.
+
+‘r i’     (‘magit-rebase-interactive’)
+
+     Start an interactive rebase sequence.
+
+‘r f’     (‘magit-rebase-autosquash’)
+
+     Combine squash and fixup commits with their intended targets.
+
+‘r m’     (‘magit-rebase-edit-commit’)
+
+     Edit a single older commit using rebase.
+
+‘r w’     (‘magit-rebase-reword-commit’)
+
+     Reword a single older commit using rebase.
+
+‘r k’     (‘magit-rebase-remove-commit’)
+
+     Remove a single older commit using rebase.
+
+   When a rebase is in progress, then the popup buffer features these
+commands instead.
+
+‘r r’     (‘magit-rebase-continue’)
+
+     Restart the current rebasing operation.
+
+     In some cases this pops up a commit message buffer for you do edit.
+     With a prefix argument the old message is reused as-is.
+
+‘r s’     (‘magit-rebase-skip’)
+
+     Skip the current commit and restart the current rebase operation.
+
+‘r e’     (‘magit-rebase-edit’)
+
+     Edit the todo list of the current rebase operation.
+
+‘r a’     (‘magit-rebase-abort’)
+
+     Abort the current rebase operation, restoring the original branch.
+
+* Menu:
+
+* Editing Rebase Sequences::
+* Information About In-Progress Rebase::
+
+
+File: magit.info,  Node: Editing Rebase Sequences,  Next: Information About In-Progress Rebase,  Up: Rebasing
+
+6.8.1 Editing Rebase Sequences
+------------------------------
+
+‘C-c C-c’     (‘with-editor-finish’)
+
+     Finish the current editing session by returning with exit code 0.
+     Git then uses the rebase instructions it finds in the file.
+
+‘C-c C-k’     (‘with-editor-cancel’)
+
+     Cancel the current editing session by returning with exit code 1.
+     Git then forgoes starting the rebase sequence.
+
+‘RET’     (‘git-rebase-show-commit’)
+
+     Show the commit on the current line in another buffer and select
+     that buffer.
+
+‘SPC’     (‘git-rebase-show-or-scroll-up’)
+
+     Show the commit on the current line in another buffer without
+     selecting that buffer.  If the revision buffer is already visible
+     in another window of the current frame, then instead scroll that
+     window up.
+
+‘DEL’     (‘git-rebase-show-or-scroll-down’)
+
+     Show the commit on the current line in another buffer without
+     selecting that buffer.  If the revision buffer is already visible
+     in another window of the current frame, then instead scroll that
+     window down.
+
+‘p’     (‘git-rebase-backward-line’)
+
+     Move to previous line.
+
+‘n’     (‘forward-line’)
+
+     Move to next line.
+
+‘M-p’     (‘git-rebase-move-line-up’)
+
+     Move the current commit (or command) up.
+
+‘M-n’     (‘git-rebase-move-line-down’)
+
+     Move the current commit (or command) down.
+
+‘r’     (‘git-rebase-reword’)
+
+     Edit message of commit on current line.
+
+‘e’     (‘git-rebase-edit’)
+
+     Stop at the commit on the current line.
+
+‘s’     (‘git-rebase-squash’)
+
+     Meld commit on current line into previous commit, and edit message.
+
+‘f’     (‘git-rebase-fixup’)
+
+     Meld commit on current line into previous commit, discarding the
+     current commit’s message.
+
+‘k’     (‘git-rebase-kill-line’)
+
+     Kill the current action line.
+
+‘c’     (‘git-rebase-pick’)
+
+     Use commit on current line.
+
+‘x’     (‘git-rebase-exec’)
+
+     Insert a shell command to be run after the proceeding commit.
+
+     If there already is such a command on the current line, then edit
+     that instead.  With a prefix argument insert a new command even
+     when there already is one on the current line.  With empty input
+     remove the command on the current line, if any.
+
+‘y’     (‘git-rebase-insert’)
+
+     Read an arbitrary commit and insert it below current line.
+
+‘C-x u’     (‘git-rebase-undo’)
+
+     Undo some previous changes.  Like ‘undo’ but works in read-only
+     buffers.
+
+ -- User Option: git-rebase-auto-advance
+
+     Whether to move to next line after changing a line.
+
+ -- User Option: git-rebase-show-instructions
+
+     Whether to show usage instructions inside the rebase buffer.
+
+ -- User Option: git-rebase-confirm-cancel
+
+     Whether confirmation is required to cancel.
+
+
+File: magit.info,  Node: Information About In-Progress Rebase,  Prev: Editing Rebase Sequences,  Up: Rebasing
+
+6.8.2 Information About In-Progress Rebase
+------------------------------------------
+
+While a rebase sequence is in progress, the status buffer features a
+section that lists the commits that have already been applied as well as
+the commits that still have to be applied.
+
+   The commits are split in two halves.  When rebase stops at a commit,
+either because the user has to deal with a conflict or because s/he
+explicitly requested that rebase stops at that commit, then point is
+placed on the commit that separates the two groups, i.e.  on ‘HEAD’.
+The commits above it have not been applied yet, while the ‘HEAD’ and the
+commits below it have already been applied.  In between these two groups
+of applied and yet-to-be applied commits, there sometimes is a commit
+which has been dropped.
+
+   Each commit is prefixed with a word and these words are additionally
+shown in different colors to indicate the status of the commits.
+
+   The following colors are used:
+
+   • Yellow commits have not been applied yet.
+
+   • Gray commits have already been applied.
+
+   • The blue commit is the ‘HEAD’ commit.
+
+   • The green commit is the commit the rebase sequence stopped at.  If
+     this is the same commit as ‘HEAD’ (e.g.  because you haven’t done
+     anything yet after rebase stopped at the commit, then this commit
+     is shown in blue, not green).  There can only be a green *and* a
+     blue commit at the same time, if you create one or more new commits
+     after rebase stops at a commit.
+
+   • Red commits have been dropped.  They are shown for reference only,
+     e.g.  to make it easier to diff.
+
+   Of course these colors are subject to the color-theme in use.
+
+   The following words are used:
+
+   • Commits prefixed with ‘pick’, ‘reword’, ‘edit’, ‘squash’, and
+     ‘fixup’ have not been applied yet.  These words have the same
+     meaning here as they do in the buffer used to edit the rebase
+     sequence.  See *note Editing Rebase Sequences::.
+
+   • Commits prefixed with ‘done’ and ‘onto’ have already been applied.
+     It is possible for such a commit to be the ‘HEAD’, in which case it
+     is blue.  Otherwise it is grey.
+
+        • The commit prefixed with ‘onto’ is the commit on top of which
+          all the other commits are being re-applied.  This commit
+          itself did not have to be re-applied, it is the commit rebase
+          did rewind to before starting to re-apply other commits.
+
+        • Commits prefixed with ‘done’ have already been re-applied.
+          This includes commits that have been re-applied but also new
+          commits that you have created during the rebase.
+
+   • All other commits, those not prefixed with any of the above words,
+     are in some way related to the commit at which rebase stopped.
+
+     To determine whether a commit is related to the stopped-at commit
+     their hashes, trees and patch-ids (1) are being compared.  The
+     commit message is not used for this purpose.
+
+     Generally speaking commits that are related to the stopped-at
+     commit can have any of the used colors, though not all color/word
+     combinations are possible.
+
+     Words used for stopped-at commits are:
+
+        • When a commit is prefixed with ‘void’, then that indicates
+          that Magit knows for sure that all the changes in that commit
+          have been applied using several new commits.  This commit is
+          no longer reachable from ‘HEAD’, and it also isn’t one of the
+          commits that will be applied when resuming the session.
+
+        • When a commit is prefixed with ‘join’, then that indicates
+          that the rebase sequence stopped at that commit due to a
+          conflict - you now have to join (merge) the changes with what
+          has already been applied.  In a sense this is the commit
+          rebase stopped at, but while its effect is already in the
+          index and in the worktree (with conflict markers), the commit
+          itself has not actually been applied yet (it isn’t the
+          ‘HEAD’).  So it is shown in yellow, like the other commits
+          that still have to be applied.
+
+        • When a commit is prefixed with ‘stop’ or a _blue_ or _green_
+          ‘same’, then that indicates that rebase stopped at this
+          commit, that it is still applied or has been applied again,
+          and that at least its patch-id is unchanged.
+
+             • When a commit is prefixed with ‘stop’, then that
+               indicates that rebase stopped at that commit because you
+               requested that earlier, and its patch-id is unchanged.
+               It might even still be the exact same commit.
+
+             • When a commit is prefixed with a _blue_ or _green_
+               ‘same’, then that indicates that while its tree or hash
+               changed, its patch-id did not.  If it is blue, then it is
+               the ‘HEAD’ commit (as always for blue).  When it is
+               green, then it no longer is ‘HEAD’ because other commit
+               have been created since (but before continuing the
+               rebase).
+
+        • When a commit is prefixed with ‘goal’, a _yellow_ ‘same,’ or
+          ‘work’, then that indicates that rebase applied that commit
+          but that you then reset ‘HEAD’ to an earlier commit (likely to
+          split it up into multiple commits), and that there are some
+          uncommitted changes remaining which likely (but not
+          necessarily) originate from that commit.
+
+             • When a commit is prefixed with ‘goal’, then that
+               indicates that it is still possible to create a new
+               commit with the exact same tree (the "goal") without
+               manually editing any files, by committing the index, or
+               by staging all changes and then committing that.  This is
+               the case when the original tree still exists in the index
+               or worktree in untainted form.
+
+             • When a commit is prefixed with a yellow ‘same’, then that
+               indicates that it is no longer possible to create a
+               commit with the exact same tree, but that it is still
+               possible to create a commit with the same patch-id.  This
+               would be the case if you created a new commit with other
+               changes, but the changes from the original commit still
+               exist in the index or working tree in untainted form.
+
+             • When a commit is prefixed with ‘work’, then that
+               indicates that you reset ‘HEAD’ to an earlier commit, and
+               that there are some staged and/or unstaged changes
+               (likely, but not necessarily) originating from that
+               commit.  However it is no longer possible to create a new
+               commit with the same tree or at least the same patch-id
+               because you have already made other changes.
+
+        • When a commit is prefixed with ‘poof’ or ‘gone’, then that
+          indicates that rebase applied that commit but that you then
+          reset ‘HEAD’ to an earlier commit (likely to split it up into
+          multiple commits), and that there are no uncommitted changes.
+
+             • When a commit is prefixed with ‘poof’, then that
+               indicates that it is no longer reachable from ‘HEAD’, but
+               that it has been replaced with one or more commits, which
+               together have the exact same effect.
+
+             • When a commit is prefixed with ‘gone’, then that
+               indicates that it is no longer reachable from ‘HEAD’ and
+               that we also cannot determine whether its changes are
+               still in effect in one or more new commits.  They might
+               be, but if so, then there must also be other changes
+               which makes it impossible to know for sure.
+
+   Do not worry if you do not fully understand the above.  That’s okay,
+you will acquire a good enough understanding through practice.
+
+   For other sequence operations such as cherry-picking, a similar
+section is displayed, but they lack some of the features described
+above, due to limitations in the git commands used to implement them.
+Most importantly these sequences only support "picking" a commit but not
+other actions such as "rewording", and they do not keep track of the
+commits which have already been applied.
+
+   ---------- Footnotes ----------
+
+   (1) The patch-id is a hash of the _changes_ introduced by a commit.
+It differs from the hash of the commit itself, which is a hash of the
+result of applying that change (i.e.  the resulting trees and blobs) as
+well as author and committer information, the commit message, and the
+hashes of the parents of the commit.  The patch-id hash on the other
+hand is created only from the added and removed lines, even line numbers
+and whitespace changes are ignored when calculating this hash.  The
+patch-ids of two commits can be used to answer the question "Do these
+commits make the same change?".
+
+
+File: magit.info,  Node: Cherry Picking,  Next: Resetting,  Prev: Rebasing,  Up: Manipulating
+
+6.9 Cherry Picking
+==================
+
+Also see *note (gitman)git-cherry-pick::.
+
+‘A’     (‘magit-cherry-pick-popup’)
+
+     This prefix command shows the following suffix commands along with
+     the appropriate infix arguments in a popup buffer.
+
+   When no cherry-pick or revert is in progress, then the popup buffer
+features the following commands.
+
+‘A A’     (‘magit-cherry-pick’)
+
+     This command copies COMMITS from another branch onto the current
+     branch.  If the region selects multiple commits, then those are
+     copied, without prompting.  Otherwise the user is prompted for a
+     commit or range, defaulting to the commit at point.
+
+‘A a’     (‘magit-cherry-apply’)
+
+     This command applies the changes in COMMITS from another branch
+     onto the current branch.  If the region selects multiple commits,
+     then those are used, without prompting.  Otherwise the user is
+     prompted for a commit or range, defaulting to the commit at point.
+
+     This command also has a top-level binding, which can be invoked
+     without using the popup by typing ‘a’ at the top-level.
+
+   The following commands not only apply some commits to some branch,
+but also remove them from some other branch.  The removal is performed
+using either ‘git-update-ref’ or if necessary ‘git-rebase’.  Both
+applying commits as well as removing them using ‘git-rebase’ can lead to
+conflicts.  If that happens, then these commands abort and you not only
+have to resolve the conflicts but also finish the process the same way
+you would have to if these commands didn’t exist at all.
+
+‘A h’     (‘magit-cherry-harvest’)
+
+     This command moves the selected COMMITS that must be located on
+     another BRANCH onto the current branch instead, removing them from
+     the former.  When this command succeeds, then the same branch is
+     current as before.
+
+     Applying the commits on the current branch or removing them from
+     the other branch can lead to conflicts.  When that happens, then
+     this command stops and you have to resolve the conflicts and then
+     finish the process manually.
+
+‘A d’     (‘magit-cherry-donate’)
+
+     This command moves the selected COMMITS from the current branch
+     onto another existing BRANCH, removing them from the former.  When
+     this command succeeds, then the same branch is current as before.
+
+     Applying the commits on the other branch or removing them from the
+     current branch can lead to conflicts.  When that happens, then this
+     command stops and you have to resolve the conflicts and then finish
+     the process manually.
+
+‘A n’     (‘magit-cherry-spinout’)
+
+     This command moves the selected COMMITS from the current branch
+     onto a new branch BRANCH, removing them from the former.  When this
+     command succeeds, then the same branch is current as before.
+
+     Applying the commits on the other branch or removing them from the
+     current branch can lead to conflicts.  When that happens, then this
+     command stops and you have to resolve the conflicts and then finish
+     the process manually.
+
+‘A s’     (‘magit-cherry-spinoff’)
+
+     This command moves the selected COMMITS from the current branch
+     onto a new branch BRANCH, removing them from the former.  When this
+     command succeeds, then the new branch is checked out.
+
+     Applying the commits on the other branch or removing them from the
+     current branch can lead to conflicts.  When that happens, then this
+     command stops and you have to resolve the conflicts and then finish
+     the process manually.
+
+   When a cherry-pick or revert is in progress, then the popup buffer
+features these commands instead.
+
+‘A A’     (‘magit-sequence-continue’)
+
+     Resume the current cherry-pick or revert sequence.
+
+‘A s’     (‘magit-sequence-skip’)
+
+     Skip the stopped at commit during a cherry-pick or revert sequence.
+
+‘A a’     (‘magit-sequence-abort’)
+
+     Abort the current cherry-pick or revert sequence.  This discards
+     all changes made since the sequence started.
+
+* Menu:
+
+* Reverting::
+
+
+File: magit.info,  Node: Reverting,  Up: Cherry Picking
+
+6.9.1 Reverting
+---------------
+
+‘V’     (‘magit-revert-popup’)
+
+     This prefix command shows the following suffix commands along with
+     the appropriate infix arguments in a popup buffer.
+
+   When no cherry-pick or revert is in progress, then the popup buffer
+features the following commands.
+
+‘V V’     (‘magit-revert’)
+
+     Revert a commit by creating a new commit.  Prompt for a commit,
+     defaulting to the commit at point.  If the region selects multiple
+     commits, then revert all of them, without prompting.
+
+‘V v’     (‘magit-revert-no-commit’)
+
+     Revert a commit by applying it in reverse to the working tree.
+     Prompt for a commit, defaulting to the commit at point.  If the
+     region selects multiple commits, then revert all of them, without
+     prompting.
+
+   When a cherry-pick or revert is in progress, then the popup buffer
+features these commands instead.
+
+‘V A’     (‘magit-sequence-continue’)
+
+     Resume the current cherry-pick or revert sequence.
+
+‘V s’     (‘magit-sequence-skip’)
+
+     Skip the stopped at commit during a cherry-pick or revert sequence.
+
+‘V a’     (‘magit-sequence-abort’)
+
+     Abort the current cherry-pick or revert sequence.  This discards
+     all changes made since the sequence started.
+
+
+File: magit.info,  Node: Resetting,  Next: Stashing,  Prev: Cherry Picking,  Up: Manipulating
+
+6.10 Resetting
+==============
+
+Also see *note (gitman)git-reset::.
+
+‘x’     (‘magit-reset’)
+
+     Reset the head and index to some commit read from the user and
+     defaulting to the commit at point.  The working tree is kept as-is.
+     With a prefix argument also reset the working tree.
+
+‘X m’     (‘magit-reset-head’)
+
+     Reset the ‘HEAD’ and index to some commit read from the user and
+     defaulting to the commit at point.  The working tree is kept as-is.
+
+‘X s’     (‘magit-reset-soft’)
+
+     Reset the ‘HEAD’ to some commit read from the user and defaulting
+     to the commit at point.  The index and the working tree are kept
+     as-is.
+
+‘X h’     (‘magit-reset-hard’)
+
+     Reset the ‘HEAD’, index, and working tree to some commit read from
+     the user and defaulting to the commit at point.
+
+‘X i’     (‘magit-reset-index’)
+
+     Reset the index to some commit read from the user and defaulting to
+     the commit at point.  Keep the ‘HEAD’ and working tree as-is, so if
+     the commit refers to the ‘HEAD’, then this effectively unstages all
+     changes.
+
+‘X f’     (‘magit-file-checkout’)
+
+     Update file in the working tree and index to the contents from a
+     revision.  Both the revision and file are read from the user.
+
+
+File: magit.info,  Node: Stashing,  Prev: Resetting,  Up: Manipulating
+
+6.11 Stashing
+=============
+
+Also see *note (gitman)git-stash::.
+
+‘z’     (‘magit-stash-popup’)
+
+     This prefix command shows the following suffix commands along with
+     the appropriate infix arguments in a popup buffer.
+
+‘z z’     (‘magit-stash’)
+
+     Create a stash of the index and working tree.  Untracked files are
+     included according to popup arguments.  One prefix argument is
+     equivalent to ‘--include-untracked’ while two prefix arguments are
+     equivalent to ‘--all’.
+
+‘z i’     (‘magit-stash-index’)
+
+     Create a stash of the index only.  Unstaged and untracked changes
+     are not stashed.
+
+‘z w’     (‘magit-stash-worktree’)
+
+     Create a stash of unstaged changes in the working tree.  Untracked
+     files are included according to popup arguments.  One prefix
+     argument is equivalent to ‘--include-untracked’ while two prefix
+     arguments are equivalent to ‘--all’.
+
+‘z x’     (‘magit-stash-keep-index’)
+
+     Create a stash of the index and working tree, keeping index intact.
+     Untracked files are included according to popup arguments.  One
+     prefix argument is equivalent to ‘--include-untracked’ while two
+     prefix arguments are equivalent to ‘--all’.
+
+‘z Z’     (‘magit-snapshot’)
+
+     Create a snapshot of the index and working tree.  Untracked files
+     are included according to popup arguments.  One prefix argument is
+     equivalent to ‘--include-untracked’ while two prefix arguments are
+     equivalent to ‘--all’.
+
+‘z I’     (‘magit-snapshot-index’)
+
+     Create a snapshot of the index only.  Unstaged and untracked
+     changes are not stashed.
+
+‘z W’     (‘magit-snapshot-worktree’)
+
+     Create a snapshot of unstaged changes in the working tree.
+     Untracked files are included according to popup arguments.  One
+     prefix argument is equivalent to ‘--include-untracked’ while two
+     prefix arguments are equivalent to ‘--all’-.
+
+‘z a’     (‘magit-stash-apply’)
+
+     Apply a stash to the working tree.  Try to preserve the stash
+     index.  If that fails because there are staged changes, apply
+     without preserving the stash index.
+
+‘z p’     (‘magit-stash-pop’)
+
+     Apply a stash to the working tree and remove it from stash list.
+     Try to preserve the stash index.  If that fails because there are
+     staged changes, apply without preserving the stash index and forgo
+     removing the stash.
+
+‘z k’     (‘magit-stash-drop’)
+
+     Remove a stash from the stash list.  When the region is active,
+     offer to drop all contained stashes.
+
+‘z v’     (‘magit-stash-show’)
+
+     Show all diffs of a stash in a buffer.
+
+‘z b’     (‘magit-stash-branch’)
+
+     Create and checkout a new BRANCH from STASH.  The branch starts at
+     the commit that was current when the stash was created.
+
+‘z B’     (‘magit-stash-branch-here’)
+
+     Create and checkout a new BRANCH using ‘magit-branch’ with the
+     current branch or ‘HEAD’ as the starting-point.  Then apply STASH,
+     dropping it if it applies cleanly.
+
+‘z f’     (‘magit-stash-format-patch’)
+
+     Create a patch from STASH.
+
+‘k’     (‘magit-stash-clear’)
+
+     Remove all stashes saved in REF’s reflog by deleting REF.
+
+‘z l’     (‘magit-stash-list’)
+
+     List all stashes in a buffer.
+
+ -- User Option: magit-stashes-margin
+
+     This option specifies whether the margin is initially shown in
+     stashes buffers and how it is formatted.
+
+     The value has the form ‘(INIT STYLE WIDTH AUTHOR AUTHOR-WIDTH)’.
+
+        • If INIT is non-nil, then the margin is shown initially.
+
+        • STYLE controls how to format the committer date.  It can be
+          one of ‘age’ (to show the age of the commit),
+          ‘age-abbreviated’ (to abbreviate the time unit to a
+          character), or a string (suitable for ‘format-time-string’) to
+          show the actual date.
+
+        • WIDTH controls the width of the margin.  This exists for
+          forward compatibility and currently the value should not be
+          changed.
+
+        • AUTHOR controls whether the name of the author is also shown
+          by default.
+
+        • AUTHOR-WIDTH has to be an integer.  When the name of the
+          author is shown, then this specifies how much space is used to
+          do so.
+
+
+File: magit.info,  Node: Transferring,  Next: Miscellaneous,  Prev: Manipulating,  Up: Top
+
+7 Transferring
+**************
+
+* Menu:
+
+* Remotes::
+* Fetching::
+* Pulling::
+* Pushing::
+* Creating and Sending Patches::
+* Applying Patches::
+
+
+File: magit.info,  Node: Remotes,  Next: Fetching,  Up: Transferring
+
+7.1 Remotes
+===========
+
+* Menu:
+
+* The Remote Popup::
+* The Remote Config Popup::
+
+
+File: magit.info,  Node: The Remote Popup,  Next: The Remote Config Popup,  Up: Remotes
+
+7.1.1 The Remote Popup
+----------------------
+
+The popup ‘magit-remote-popup’ is used to add remotes and to make
+changes to existing remotes.  This popup only deals with remotes
+themselves, not with branches or the transfer of commits.  Those
+features are available from separate popups.
+
+   Also see *note (gitman)git-remote::.
+
+‘M’     (‘magit-remote-popup’)
+
+     This prefix command shows the following suffix commands along with
+     the appropriate infix arguments in a popup buffer.
+
+ -- User Option: magit-remote-popup-show-variables
+
+     This option controls whether the ‘magit-remote-popup’ shows remote
+     related Git variables.  When set to nil, no variables are displayed
+     directly in this popup, and the sub-popup
+     ‘magit-remote-config-popup’ has to be used instead to view and
+     change remote related variables.
+
+‘M C’     (‘magit-remote-config-popup’)
+
+     This command shows remote related variables in a separate popup.
+     By default this asks the user for which remote the variables should
+     be shown.  When ‘magit-remote-popup-show-variables’ is ‘nil’, then
+     it shows the variables for the upstream of the current branch or
+     "origin" it that branch has no remote upstream.  To select another
+     remote use a prefix argument.
+
+‘M a’     (‘magit-remote-add’)
+
+     This command add a remote and fetches it.  The remote name and url
+     are read in the minibuffer.
+
+‘M r’     (‘magit-remote-rename’)
+
+     This command renames a remote.  Both the old and the new names are
+     read in the minibuffer.
+
+‘M u’     (‘magit-remote-set-url’)
+
+     This command changes the url of a remote.  Both the remote and the
+     new url are read in the minibuffer.
+
+‘M k’     (‘magit-remote-remove’)
+
+     This command deletes a remote, read in the minibuffer.
+
+‘M p’     (‘magit-remote-prune’)
+
+     This command removes stale remote-tracking branches for a remote
+     read in the minibuffer.
+
+‘M P’     (‘magit-remote-prune-refspecs’)
+
+     This command removes stale refspecs for a remote read in the
+     minibuffer.
+
+     A refspec is stale if there no longer exists at least one branch on
+     the remote that would be fetched due to that refspec.  A stale
+     refspec is problematic because its existence causes Git to refuse
+     to fetch according to the remaining non-stale refspecs.
+
+     If only stale refspecs remain, then this command offers to either
+     delete the remote or to replace the stale refspecs with the default
+     refspec ("+refs/heads/*:refs/remotes/REMOTE/*").
+
+     This command also removes the remote-tracking branches that were
+     created due to the now stale refspecs.  Other stale branches are
+     not removed.
+
+ -- User Option: magit-remote-add-set-remote.pushDefault
+
+     This option controls whether the user is asked whether they want to
+     set ‘remote.pushDefault’ after adding a remote.
+
+     If ‘ask’, then users is always ask.  If ‘ask-if-unset’, then the
+     user is only if the variable isn’t set already.  If ‘nil’, then the
+     user isn’t asked and the variable isn’t set.  If the value is a
+     string, then the variable is set without the user being asked,
+     provided that the name of the added remote is equal to that string
+     and the variable isn’t already set.
+
+
+File: magit.info,  Node: The Remote Config Popup,  Prev: The Remote Popup,  Up: Remotes
+
+7.1.2 The Remote Config Popup
+-----------------------------
+
+ -- Command: magit-remote-config-popup
+
+     This prefix command shows the following remote-related Git
+     variables in a popup buffer.  The values can be changed from that
+     buffer.
+
+     This popup is a sub-popup of the ‘magit-remote-popup’ in which "C"
+     is bound to this popup.
+
+   The following variables are used to configure a specific remote.  The
+values are being displayed for the upstream remote of the current
+branch.  To change the value for another remote invoke
+‘magit-remote-config-popup’ with a prefix argument.
+
+ -- Variable: remote.NAME.url
+
+     This variable specifies the url of the remote named NAME.  It can
+     have multiple values.
+
+ -- Variable: remote.NAME.fetch
+
+     The refspec used when fetching from the remote named NAME.  It can
+     have multiple values.
+
+ -- Variable: remote.NAME.pushurl
+
+     This variable specifies the url used for fetching from the remote
+     named NAME.  If it is not specified, then ‘remote.NAME.url’ is used
+     instead.  It can have multiple values.
+
+ -- Variable: remote.NAME.push
+
+     The refspec used when pushing to the remote named NAME.  It can
+     have multiple values.
+
+ -- Variable: remote.NAME.tagOpts
+
+     This variable specifies what tags are fetched by default.  If the
+     value is ‘--no-tags’ then no tags are fetched.  If the value is
+     ‘--tags’, then all tags are fetched.  If this variable has not
+     value, then only tags are fetched that are reachable from fetched
+     branches.
+
+
+File: magit.info,  Node: Fetching,  Next: Pulling,  Prev: Remotes,  Up: Transferring
+
+7.2 Fetching
+============
+
+For information about the differences between the _upstream_ and the
+_push-remote_, see *note Branching::.
+
+   Also see *note (gitman)git-fetch::.
+
+‘f’     (‘magit-fetch-popup’)
+
+     This prefix command shows the following suffix commands along with
+     the appropriate infix arguments in a popup buffer.
+
+‘f p’     (‘magit-fetch-from-pushremote’)
+
+     Fetch from the push-remote of the current branch.
+
+‘f u’     (‘magit-fetch-from-upstream’)
+
+     Fetch from the upstream of the current branch.
+
+‘f e’     (‘magit-fetch’)
+
+     Fetch from another repository.
+
+‘f o’     (‘magit-fetch-branch’)
+
+     Fetch a branch from a remote, both of which are read from the
+     minibuffer.
+
+‘f r’     (‘magit-fetch-refspec’)
+
+     Fetch from a remote using an explicit refspec, both of which are
+     read from the minibuffer.
+
+‘f a’     (‘magit-fetch-all’)
+
+     Fetch from all remotes.
+
+‘f m’     (‘magit-submodule-fetch’)
+
+     Fetch all submodules.  With a prefix argument fetch all remotes of
+     all submodules.
+
+   Instead of using one popup for fetching and another for pulling, you
+could also use ‘magit-pull-and-fetch-popup’.  See its doc-string for
+more information.
+
+
+File: magit.info,  Node: Pulling,  Next: Pushing,  Prev: Fetching,  Up: Transferring
+
+7.3 Pulling
+===========
+
+For information about the differences between the _upstream_ and the
+_push-remote_, see *note Branching::.
+
+   Also see *note (gitman)git-pull::.
+
+‘F’     (‘magit-pull-popup’)
+
+     This prefix command shows the following suffix commands in a popup
+     buffer.
+
+‘F p’     (‘magit-pull-from-pushremote’)
+
+     Pull from the push-remote of the current branch.
+
+‘F u’     (‘magit-pull-from-upstream’)
+
+     Pull from the upstream of the current branch.
+
+‘F e’     (‘magit-pull’)
+
+     Pull from a branch read in the minibuffer.
+
+   Instead of using one popup for fetching and another for pulling, you
+could also use ‘magit-pull-and-fetch-popup’.  See its doc-string for
+more information.
+
+
+File: magit.info,  Node: Pushing,  Next: Creating and Sending Patches,  Prev: Pulling,  Up: Transferring
+
+7.4 Pushing
+===========
+
+For information about the differences between the _upstream_ and the
+_push-remote_, see *note Branching::.
+
+   Also see *note (gitman)git-push::.
+
+‘P’     (‘magit-push-popup’)
+
+     This prefix command shows the following suffix commands along with
+     the appropriate infix arguments in a popup buffer.
+
+‘P p’     (‘magit-push-current-to-pushremote’)
+
+     Push the current branch to ‘branch.<name>.pushRemote’ or if that is
+     unset to ‘remote.pushDefault’.
+
+     When ‘magit-push-current-set-remote-if-missing’ is non-nil and the
+     push-remote is not configured, then read the push-remote from the
+     user, set it, and then push to it.  With a prefix argument the
+     push-remote can be changed before pushed to it.
+
+‘P u’     (‘magit-push-current-to-upstream’)
+
+     Push the current branch to its upstream branch.
+
+     When ‘magit-push-current-set-remote-if-missing’ is non-nil and the
+     push-remote is not configured, then read the upstream from the
+     user, set it, and then push to it.  With a prefix argument the
+     push-remote can be changed before pushed to it.
+
+‘P e’     (‘magit-push-current’)
+
+     Push the current branch to a branch read in the minibuffer.
+
+‘P o’     (‘magit-push’)
+
+     Push an arbitrary branch or commit somewhere.  Both the source and
+     the target are read in the minibuffer.
+
+‘P r’     (‘magit-push-refspecs’)
+
+     Push one or multiple refspecs to a remote, both of which are read
+     in the minibuffer.
+
+     To use multiple refspecs, separate them with commas.  Completion is
+     only available for the part before the colon, or when no colon is
+     used.
+
+‘P m’     (‘magit-push-matching’)
+
+     Push all matching branches to another repository.  If multiple
+     remotes exit, then read one from the user.  If just one exists, use
+     that without requiring confirmation.
+
+‘P t’     (‘magit-push-tags’)
+
+     Push all tags to another repository.  If only one remote exists,
+     then push to that.  Otherwise prompt for a remote, offering the
+     remote configured for the current branch as default.
+
+‘P T’     (‘magit-push-tag’)
+
+     Push a tag to another repository.
+
+   Two more push commands exist, which by default are not available from
+the push popup.  See their doc-strings for instructions on how to add
+them to the popup.
+
+ -- Command: magit-push-implicitly args
+
+     Push somewhere without using an explicit refspec.
+
+     This command simply runs ‘git push -v [ARGS]’.  ARGS are the
+     arguments specified in the popup buffer.  No explicit refspec
+     arguments are used.  Instead the behavior depends on at least these
+     Git variables: ‘push.default’, ‘remote.pushDefault’,
+     ‘branch.<branch>.pushRemote’, ‘branch.<branch>.remote’,
+     ‘branch.<branch>.merge’, and ‘remote.<remote>.push’.
+
+ -- Command: magit-push-to-remote remote args
+
+     Push to the remote REMOTE without using an explicit refspec.  The
+     remote is read in the minibuffer.
+
+     This command simply runs ‘git push -v [ARGS] REMOTE’.  ARGS are the
+     arguments specified in the popup buffer.  No refspec arguments are
+     used.  Instead the behavior depends on at least these Git
+     variables: ‘push.default’, ‘remote.pushDefault’,
+     ‘branch.<branch>.pushRemote’, ‘branch.<branch>.remote’,
+     ‘branch.<branch>.merge’, and ‘remote.<remote>.push’.
+
+ -- User Option: magit-push-current-set-remote-if-missing
+
+     This option controls whether missing remotes are configured before
+     pushing.
+
+     When ‘nil’, then the command ‘magit-push-current-to-pushremote’ and
+     ‘magit-push-current-to-upstream’ do not appear in the push popup if
+     the push-remote resp.  upstream is not configured.  If the user
+     invokes one of these commands anyway, then it raises an error.
+
+     When ‘non-nil’, then these commands always appear in the push
+     popup.  But if the required configuration is missing, then they do
+     appear in a way that indicates that this is the case.  If the user
+     invokes one of them, then it asks for the necessary configuration,
+     stores the configuration, and then uses it to push a first time.
+
+     This option also affects whether the argument ‘--set-upstream’ is
+     available in the popup.  If the value is ‘non-nil’, then that
+     argument is redundant.  But note that changing the value of this
+     option does not take affect immediately, the argument will only be
+     added or removed after restarting Emacs.
+
+
+File: magit.info,  Node: Creating and Sending Patches,  Next: Applying Patches,  Prev: Pushing,  Up: Transferring
+
+7.5 Creating and Sending Patches
+================================
+
+‘W’     (‘magit-patch-popup’)
+
+     This prefix command shows the following suffix commands along with
+     the appropriate infix arguments in a popup buffer.
+
+‘W p’     (‘magit-format-patch’)
+
+     Create patches for a set commits.  If the region marks commits,
+     then create patches for those.  Otherwise prompt for a range or a
+     single commit, defaulting to the commit at point.
+
+‘W r’     (‘magit-request-pull’)
+
+     Request that upstream pulls from your public repository.
+
+   It is also possible to save a plain patch file by using ‘C-x C-w’
+inside a ‘magit-diff-mode’ or ‘magit-revision-mode’ buffer.
+
+
+File: magit.info,  Node: Applying Patches,  Prev: Creating and Sending Patches,  Up: Transferring
+
+7.6 Applying Patches
+====================
+
+Also see *note (gitman)git-am::.  and *note (gitman)git-apply::.
+
+‘w’     (‘magit-am-popup’)
+
+     This prefix command shows the following suffix commands along with
+     the appropriate infix arguments in a popup buffer.
+
+‘w w’     (‘magit-am-apply-patches’)
+
+     Apply one or more patches.  If the region marks files, then apply
+     those patches.  Otherwise read a file name in the minibuffer
+     defaulting to the file at point.
+
+‘w m’     (‘magit-am-apply-maildir’)
+
+     Apply the patches from a maildir.
+
+   When an "am" operation is in progress, then the popup buffer features
+these commands instead.
+
+‘w w’     (‘magit-am-continue’)
+
+     Resume the current patch applying sequence.
+
+‘w s’     (‘magit-am-skip’)
+
+     Skip the stopped at patch during a patch applying sequence.
+
+‘w a’     (‘magit-am-abort’)
+
+     Abort the current patch applying sequence.  This discards all
+     changes made since the sequence started.
+
+   In addition to the commands listed at the top, the "am" popup also
+has a binding for the related "patch" popup.
+
+‘w a’     (‘magit-patch-apply-popup’)
+
+     This prefix command shows the following suffix commands along with
+     the appropriate infix arguments in a popup buffer.
+
+‘w a a’     (‘magit-patch-apply’)
+
+     This command applies a simple patch file, which may not contain any
+     Git metadata in addition to the actual diff.
+
+
+File: magit.info,  Node: Miscellaneous,  Next: Customizing,  Prev: Transferring,  Up: Top
+
+8 Miscellaneous
+***************
+
+* Menu:
+
+* Tagging::
+* Notes::
+* Submodules::
+* Subtree::
+* Worktree::
+* Common Commands::
+* Wip Modes::
+* Minor Mode for Buffers Visiting Files::
+* Minor Mode for Buffers Visiting Blobs::
+
+
+File: magit.info,  Node: Tagging,  Next: Notes,  Up: Miscellaneous
+
+8.1 Tagging
+===========
+
+Also see *note (gitman)git-tag::.
+
+‘t’     (‘magit-tag-popup’)
+
+     This prefix command shows the following suffix commands along with
+     the appropriate infix arguments in a popup buffer.
+
+‘t t’     (‘magit-tag’)
+
+     Create a new tag with the given NAME at REV.  With a prefix
+     argument annotate the tag.
+
+‘t k’     (‘magit-tag-delete’)
+
+     Delete one or more tags.  If the region marks multiple tags (and
+     nothing else), then offer to delete those.  Otherwise, prompt for a
+     single tag to be deleted, defaulting to the tag at point.
+
+‘t p’     (‘magit-tag-prune’)
+
+     Offer to delete tags missing locally from REMOTE, and vice versa.
+
+ -- Command: magit-tag-release
+
+     Create an opinionated release tag.
+
+     Assume version tags that match "\\‘v?[0-9]\*\\’".  Prompt for the
+     name of the new tag using the highest existing tag as initial input
+     and call "git tag –annotate –sign -m MSG" TAG, regardless of
+     whether these arguments are enabled in the popup.  Given a TAG
+     "v1.2.3" and a repository "/path/to/foo-bar", the MESSAGE would be
+     "Foo-Bar 1.2.3".
+
+     Because it is so opinionated, this command is not available from
+     the tag popup by default.
+
+
+File: magit.info,  Node: Notes,  Next: Submodules,  Prev: Tagging,  Up: Miscellaneous
+
+8.2 Notes
+=========
+
+Also see *note (gitman)git-notes::.
+
+‘T’     (‘magit-notes-popup’)
+
+     This prefix command shows the following suffix commands along with
+     the appropriate infix arguments in a popup buffer.
+
+‘T T’     (‘magit-notes-edit’)
+
+     Edit the note attached to a commit, defaulting to the commit at
+     point.
+
+     By default use the value of Git variable ‘core.notesRef’ or
+     "refs/notes/commits" if that is undefined.
+
+‘T r’     (‘magit-notes-remove’)
+
+     Remove the note attached to a commit, defaulting to the commit at
+     point.
+
+     By default use the value of Git variable ‘core.notesRef’ or
+     "refs/notes/commits" if that is undefined.
+
+‘T p’     (‘magit-notes-prune’)
+
+     Remove notes about unreachable commits.
+
+   It is possible to merge one note ref into another.  That may result
+in conflicts which have to resolved in the temporary worktree
+".git/NOTES_MERGE_WORKTREE".
+
+‘T m’     (‘magit-notes-merge’)
+
+     Merge the notes of a ref read from the user into the current notes
+     ref.  The current notes ref is the value of Git variable
+     ‘core.notesRef’ or "refs/notes/commits" if that is undefined.
+
+   When a notes merge is in progress then the popup features the
+following suffix commands, instead of those listed above.
+
+‘T c’     (‘magit-notes-merge-commit’)
+
+     Commit the current notes ref merge, after manually resolving
+     conflicts.
+
+‘T a’     (‘magit-notes-merge-abort’)
+
+     Abort the current notes ref merge.
+
+   The following variables control what notes reference ‘magit-notes-*’,
+‘git notes’ and ‘git show’ act on and display.  Both the local and
+global values are displayed and can be modified.
+
+ -- Variable: core.notesRef
+
+     This variable specifies the notes ref that is displayed by default
+     and which commands act on by default.
+
+ -- Variable: notes.displayRef
+
+     This variable specifies additional notes ref to be displayed in
+     addition to the ref specified by ‘core.notesRef’.  It can have
+     multiple values and may end with ‘*’ to display all refs in the
+     ‘refs/notes/’ namespace (or ‘**’ if some names contain slashes).
+
+
+File: magit.info,  Node: Submodules,  Next: Subtree,  Prev: Notes,  Up: Miscellaneous
+
+8.3 Submodules
+==============
+
+Also see *note (gitman)git-submodule::.
+
+* Menu:
+
+* Listing Submodules::
+* Submodule Popup::
+
+
+File: magit.info,  Node: Listing Submodules,  Next: Submodule Popup,  Up: Submodules
+
+8.3.1 Listing Submodules
+------------------------
+
+The command ‘magit-list-submodules’ displays a list of the current
+repository’s submodules in a separate buffer.  It’s also possible to
+display information about submodules directly in the status buffer of
+the super-repository by adding ‘magit-insert-submodules’ to the hook
+‘magit-status-sections-hook’ as described in *note Status Module
+Sections::.
+
+ -- Command: magit-list-submodules
+
+     This command displays a list of the current repository’s submodules
+     in a separate buffer.
+
+     It can be invoked by pressing ‘RET’ on the section titled
+     "Modules".
+
+ -- User Option: magit-submodule-list-columns
+
+     This option controls what columns are displayed by the command
+     ‘magit-list-submodules’ and how they are displayed.
+
+     Each element has the form ‘(HEADER WIDTH FORMAT PROPS)’.
+
+     HEADER is the string displayed in the header.  WIDTH is the width
+     of the column.  FORMAT is a function that is called with one
+     argument, the repository identification (usually its basename), and
+     with ‘default-directory’ bound to the toplevel of its working tree.
+     It has to return a string to be inserted or nil.  PROPS is an alist
+     that supports the keys ‘:right-align’ and ‘:pad-right’.
+
+ -- Function: magit-insert-submodules
+
+     Insert sections for all submodules.  For each section insert the
+     path, the branch, and the output of ‘git describe --tags’, or,
+     failing that, the abbreviated HEAD commit hash.
+
+     Press ‘RET’ on such a submodule section to show its own status
+     buffer.  Press ‘RET’ on the "Modules" section to display a list of
+     submodules in a separate buffer.  This shows additional information
+     not displayed in the super-repository’s status buffer.
+
+
+File: magit.info,  Node: Submodule Popup,  Prev: Listing Submodules,  Up: Submodules
+
+8.3.2 Submodule Popup
+---------------------
+
+‘o’     (‘magit-submodule-popup’)
+
+     This prefix command shows the following suffix commands along with
+     the appropriate infix arguments in a popup buffer.
+
+   Some of the below commands default to act on the modules that are
+selected using the region.  For brevity their description talk about
+"the selected modules", but if no modules are selected, then they act on
+the current module instead, or if point isn’t on a module, then the read
+a single module to act on.  With a prefix argument these commands ignore
+the selection and the current module and instead act on all suitable
+modules.
+
+‘o a’     (‘magit-submodule-add’)
+
+     This commands adds the repository at URL as a module.  Optional
+     PATH is the path to the module relative to the root of the
+     super-project.  If it is nil then the path is determined based on
+     URL.
+
+‘o r’     (‘magit-submodule-register’)
+
+     This command registers the selected modules by copying their urls
+     from ".gitmodules" to "$GIT_DIR/config".  These values can then be
+     edited before running ‘magit-submodule-populate’.  If you don’t
+     need to edit any urls, then use the latter directly.
+
+‘o p’     (‘magit-submodule-populate’)
+
+     This command creates the working directory or directories of the
+     selected modules, checking out the recorded commits.
+
+‘o u’     (‘magit-submodule-update’)
+
+     This command updates the selected modules checking out the recorded
+     commits.
+
+‘o s’     (‘magit-submodule-synchronize’)
+
+     This command synchronizes the urls of the selected modules, copying
+     the values from ".gitmodules" to the ".git/config" of the
+     super-project as well those of the modules.
+
+‘o d’     (‘magit-submodule-unpopulate’)
+
+     This command removes the working directory of the selected modules.
+
+‘o l’     (‘magit-list-submodules’)
+
+     This command displays a list of the current repository’s modules.
+
+‘o f’     (‘magit-fetch-modules’)
+
+     This command fetches all modules.
+
+     Option ‘magit-fetch-modules-jobs’ controls how many submodules are
+     being fetched in parallel.  Also fetch the super-repository,
+     because ‘git fetch’ does not support not doing that.  With a prefix
+     argument fetch all remotes.
+
+
+File: magit.info,  Node: Subtree,  Next: Worktree,  Prev: Submodules,  Up: Miscellaneous
+
+8.4 Subtree
+===========
+
+Also see *note (gitman)git-subtree::.
+
+‘O’     (‘magit-tree-popup’)
+
+     This prefix command shows the following suffix commands along with
+     the appropriate infix arguments in a popup buffer.
+
+   Most infix arguments only apply to some of the ‘git subtree’
+subcommands.  When an argument that does not apply to the invoked
+command is set, then it is silently ignored.
+
+   When the ‘--prefix’ argument is set in the popup buffer, then that is
+used.  Otherwise the prefix is read in the minibuffer.
+
+‘O a’     (‘magit-subtree-add’)
+
+     Add COMMIT from REPOSITORY as a new subtree at PREFIX.
+
+‘O c’     (‘magit-subtree-add-commit’)
+
+     Add COMMIT as a new subtree at PREFIX.
+
+‘O m’     (‘magit-subtree-merge’)
+
+     Merge COMMIT into the PREFIX subtree.
+
+‘O f’     (‘magit-subtree-pull’)
+
+     Pull COMMIT from REPOSITORY into the PREFIX subtree.
+
+‘O p’     (‘magit-subtree-push’)
+
+     Extract the history of the subtree PREFIX and push it to REF on
+     REPOSITORY.
+
+‘O s’     (‘magit-subtree-split’)
+
+     Extract the history of the subtree PREFIX.
+
+
+File: magit.info,  Node: Worktree,  Next: Common Commands,  Prev: Subtree,  Up: Miscellaneous
+
+8.5 Worktree
+============
+
+Also see *note (gitman)git-worktree::.
+
+‘%’     (‘magit-worktree-popup’)
+
+     This prefix command shows the following suffix commands in a popup
+     buffer.
+
+‘% b’     (‘magit-worktree-checkout’)
+
+     Checkout BRANCH in a new worktree at PATH.
+
+‘% c’     (‘magit-worktree-branch’)
+
+     Create a new BRANCH and check it out in a new worktree at PATH.
+
+‘% p’     (‘magit-worktree-checkout-pull-request’)
+
+     Create, configure and checkout a new worktree from a pull-request.
+
+     This is like ‘magit-checkout-pull-request’ (which see) except that
+     it also creates a new worktree.
+
+‘% k’     (‘magit-worktree-delete’)
+
+     Delete a worktree, defaulting to the worktree at point.  The
+     primary worktree cannot be deleted.
+
+‘% g’     (‘magit-worktree-status’)
+
+     Show the status for the worktree at point.
+
+     If there is no worktree at point, then read one in the minibuffer.
+     If the worktree at point is the one whose status is already being
+     displayed in the current buffer, then show it in Dired instead.
+
+
+File: magit.info,  Node: Common Commands,  Next: Wip Modes,  Prev: Worktree,  Up: Miscellaneous
+
+8.6 Common Commands
+===================
+
+These are some of the commands that can be used in all buffers whose
+major-modes derive from ‘magit-mode’.  There are other common commands
+beside the ones below, but these didn’t fit well anywhere else.
+
+‘M-w’     (‘magit-copy-section-value’)
+
+     This command saves the value of the current section to the
+     ‘kill-ring’, and, provided that the current section is a commit,
+     branch, or tag section, it also pushes the (referenced) revision to
+     the ‘magit-revision-stack’.
+
+     When the current section is a branch or a tag, and a prefix
+     argument is used, then it saves the revision at its tip to the
+     ‘kill-ring’ instead of the reference name.
+
+‘C-w’     (‘magit-copy-buffer-revision’)
+
+     This command saves the revision being displayed in the current
+     buffer to the ‘kill-ring’ and also pushes it to the
+     ‘magit-revision-stack’.  It is mainly intended for use in
+     ‘magit-revision-mode’ buffers, the only buffers where it is always
+     unambiguous exactly which revision should be saved.
+
+     Most other Magit buffers usually show more than one revision, in
+     some way or another, so this command has to select one of them, and
+     that choice might not always be the one you think would have been
+     the best pick.
+
+   Outside of Magit ‘M-w’ and ‘C-w’ are usually bound to
+‘kill-ring-save’ and ‘kill-region’, and these commands would also be
+useful in Magit buffers.  Therefore when the region is active, then both
+of these commands behave like ‘kill-ring-save’ instead of as described
+above.
+
+
+File: magit.info,  Node: Wip Modes,  Next: Minor Mode for Buffers Visiting Files,  Prev: Common Commands,  Up: Miscellaneous
+
+8.7 Wip Modes
+=============
+
+Git keeps *committed* changes around long enough for users to recover
+changes they have accidentally deleted.  It does so by not garbage
+collecting any committed but no longer referenced objects for a certain
+period of time, by default 30 days.
+
+   But Git does *not* keep track of *uncommitted* changes in the working
+tree and not even the index (the staging area).  Because Magit makes it
+so convenient to modify uncommitted changes, it also makes it easy to
+shoot yourself in the foot in the process.
+
+   For that reason Magit provides three global modes that save *tracked*
+files to work-in-progress references after or before certain actions.
+(Untracked files are never saved and these modes also only work after
+the first commit has been created).
+
+   Two separate work-in-progress references are used to track the state
+of the index and of the working tree: "refs/wip/index/<branchref>" and
+"refs/wip/wtree/<branchref>", where ‘<branchref>’ is the full ref of the
+current branch, e.g.  "refs/heads/master".  When the ‘HEAD’ is detached
+then "HEAD" is in place of ‘<branchref>’.
+
+   Checking out another branch (or detaching ‘HEAD’) causes the use of
+different wip refs for subsequent changes, but the old refs are not
+deleted.
+
+   Creating a commit and then making a change causes the wip refs to be
+recreated to fork from the new commit.  But the old commits on the wip
+refs are not lost.  They are still available from the reflog.  To make
+it easier to see when the fork point of a wip ref was changed, an
+additional commit with the message "restart autosaving" is created on it
+(‘xxO’ commits below are such boundary commits).
+
+   Starting with
+
+           BI0---BI1    refs/wip/index/refs/heads/master
+          /
+     A---B              refs/heads/master
+          \
+           BW0---BW1    refs/wip/wtree/refs/heads/master
+
+   and committing the staged changes and editing and saving a file would
+result in
+
+           BI0---BI1        refs/wip/index/refs/heads/master
+          /
+     A---B---C              refs/heads/master
+          \   \
+           \   CW0---CW1    refs/wip/wtree/refs/heads/master
+            \
+             BW0---BW1      refs/wip/wtree/refs/heads/master@{2}
+
+   The fork-point of the index wip ref is not changed until some change
+is being staged.  Likewise just checking out a branch or creating a
+commit does not change the fork-point of the working tree wip ref.  The
+fork-points are not adjusted until there actually is a change that
+should be committed to the respective wip ref.
+
+   To view the log for a branch and its wip refs use the commands
+‘magit-wip-log’ and ‘magit-wip-log-current’.  You should use ‘--graph’
+when using these commands.  Alternatively you can use the reflog to show
+all commits that ever existed on a wip ref.  You can then recover lost
+changes from the commits shown in the log or reflog.
+
+ -- Command: magit-wip-log
+
+     This command shows the log for a branch and its wip refs.
+
+     With a negative prefix argument only the worktree wip ref is shown.
+     The absolute numeric value of the prefix argument controls how many
+     "branches" of each wip ref are shown.
+
+ -- Command: magit-wip-log-current
+
+     This command shows the log for the current branch and its wip refs.
+
+     With a negative prefix argument only the worktree wip ref is shown.
+     The absolute numeric value of the prefix argument controls how many
+     "branches" of each wip ref are shown.
+
+   There exists a total of three global modes that save to the wip refs,
+which might seem excessive, but allows fine tuning of when exactly
+changes are being committed to the wip refs.  Enabling all modes makes
+it less likely that a change slips through the cracks.
+
+   Setting the following variables directly does not take effect; either
+customize them or call the respective mode function.
+
+ -- User Option: magit-wip-after-save-mode
+
+     When this mode is enabled, then saving a buffer that visits a file
+     tracked in a Git repository causes its current state to be
+     committed to the working tree wip ref for the current branch.
+
+ -- User Option: magit-wip-after-apply-mode
+
+     When this mode is enabled, then applying (i.e.  staging, unstaging,
+     discarding, reversing, and regularly applying) a change to a file
+     tracked in a Git repository causes its current state to be
+     committed to the index and/or working tree wip refs for the current
+     branch.
+
+   If you only ever edit files using Emacs and only ever interact with
+Git using Magit, then the above two modes should be enough to protect
+each and every change from accidental loss.  In practice nobody does
+that.  So an additional mode exists that does commit to the wip refs
+before making changes that could cause the loss of earlier changes.
+
+ -- User Option: magit-wip-before-change-mode
+
+     When this mode is enabled, then certain commands commit the
+     existing changes to the files they are about to make changes to.
+
+   Note that even if you enable all three modes this won’t give you
+perfect protection.  The most likely scenario for losing changes despite
+the use of these modes is making a change outside Emacs and then
+destroying it also outside Emacs.  In such a scenario, Magit, being an
+Emacs package, didn’t get the opportunity to keep you from shooting
+yourself in the foot.
+
+   When you are unsure whether Magit did commit a change to the wip
+refs, then you can explicitly request that all changes to all tracked
+files are being committed.
+
+‘M-x magit-wip-commit’     (‘magit-wip-commit’)
+
+     This command commits all changes to all tracked files to the index
+     and working tree work-in-progress refs.  Like the modes described
+     above, it does not commit untracked files, but it does check all
+     tracked files for changes.  Use this command when you suspect that
+     the modes might have overlooked a change made outside Emacs/Magit.
+
+ -- User Option: magit-wip-after-save-local-mode-lighter
+
+     Mode-line lighter for ‘magit-wip-after-save-local-mode’.
+
+ -- User Option: magit-wip-after-apply-mode-lighter
+
+     Mode-line lighter for ‘magit-wip-after-apply-mode’.
+
+ -- User Option: magit-wip-before-change-mode-lighter
+
+     Mode-line lighter for ‘magit-wip-before-change-mode’.
+
+ -- User Option: magit-wip-namespace
+
+     The namespace used for work-in-progress refs.  It has to end with a
+     slash.  The wip refs are named "<namespace>index/<branchref>" and
+     "<namespace>wtree/<branchref>".  When snapshots are created while
+     the ‘HEAD’ is detached then "HEAD" is used in place of
+     ‘<branchref>’.
+
+
+File: magit.info,  Node: Minor Mode for Buffers Visiting Files,  Next: Minor Mode for Buffers Visiting Blobs,  Prev: Wip Modes,  Up: Miscellaneous
+
+8.8 Minor Mode for Buffers Visiting Files
+=========================================
+
+The ‘magit-file-mode’ enables certain Magit features in file-visiting
+buffers belonging to a Git repository.  It should be enabled globally
+using ‘global-magit-file-mode’.  Currently this mode only establishes a
+few key bindings, but this might be extended in the future.
+
+ -- User Option: magit-file-mode
+
+     Whether to establish certain Magit key bindings in all
+     file-visiting buffers belonging to a Git repository.  This
+     establishes the bindings suggested in *note Getting Started:: (but
+     only for file-visiting buffers), and additionally binds ‘C-c M-g’
+     to ‘magit-file-popup’.
+
+‘C-c M-g’     (‘magit-file-popup’)
+
+     This prefix command shows a popup buffer featuring suffix commands
+     that operate on the file being visited in the current buffer.
+
+‘C-c M-g s’     (‘magit-stage-file’)
+
+     Stage all changes to the file being visited in the current buffer.
+
+‘C-c M-g u’     (‘magit-unstage-file’)
+
+     Unstage all changes to the file being visited in the current
+     buffer.
+
+‘C-c M-g c’     (‘magit-commit-popup’)
+
+     This prefix command shows suffix commands along with the
+     appropriate infix arguments in a popup buffer.  See *note
+     Initiating a Commit::.
+
+‘C-c M-g D’     (‘magit-diff-buffer-file-popup’)
+
+     This prefix command shows the same suffix commands and infix
+     arguments in a popup buffer as ‘magit-diff-popup’.  But this
+     variant has to be called from a file-visiting buffer and the
+     visited file is automatically used in the popup to limit the diff
+     to that file.
+
+‘C-c M-g d’     (‘magit-diff-buffer-file’)
+
+     This command shows the diff for the file of blob that the current
+     buffer visits.
+
+ -- User Option: magit-diff-buffer-file-locked
+
+     This option controls whether ‘magit-diff-buffer-file’ uses a
+     dedicated buffer.  See *note Modes and Buffers::.
+
+‘C-c M-g L’     (‘magit-log-buffer-file-popup’)
+
+     This prefix command shows the same suffix commands and infix
+     arguments in a popup buffer as ‘magit-log-popup’.  But this variant
+     has to be called from a file-visiting buffer and the visited file
+     is automatically used in the popup to limit the log to that file.
+
+‘C-c M-g l’     (‘magit-log-buffer-file’)
+
+     This command shows the log for the file of blob that the current
+     buffer visits.  Renames are followed when a prefix argument is used
+     or when ‘--follow’ is part of ‘magit-log-arguments’.  When the
+     region is active, the log is restricted to the selected line range.
+
+‘C-c M-g t’     (‘magit-log-trace-definition’)
+
+     This command shows the log for the definition at point.
+
+ -- User Option: magit-log-buffer-file-locked
+
+     This option controls whether ‘magit-log-buffer-file’ uses a
+     dedicated buffer.  See *note Modes and Buffers::.
+
+‘C-c M-g B’     (‘magit-blame-popup’)
+
+     This prefix command shows all blaming suffix command along with the
+     appropriate infix arguments in a popup buffer.  See *note
+     Blaming::.
+
+‘C-c M-g b’     (‘magit-blame’)
+
+     This command shows for each line the revision in which it was
+     added.
+
+‘C-c M-g r’     (‘magit-blame-removal’)
+
+     This command shows for each line the revision in which it was
+     removed.  This command is only available in blob-visiting buffers.
+
+‘C-c M-g f’     (‘magit-blame-reverse’)
+
+     This command shows for each line the last revision in which it
+     still exists.  This command is only available in blob-visiting
+     buffers.
+
+‘C-c M-g e’     (‘magit-edit-line-commit’)
+
+     This command makes the commit editable that added the current line.
+
+     With a prefix argument it makes the commit editable that removes
+     the line, if any.  The commit is determined using ‘git blame’ and
+     made editable using ‘git rebase --interactive’ if it is reachable
+     from ‘HEAD’, or by checking out the commit (or a branch that points
+     at it) otherwise.
+
+‘C-c M-g p’     (‘magit-blob-previous’)
+
+     Visit the previous blob which modified the current file.
+
+   There are a few additional commands that operate on a single file but
+are not available from the file popup by default:
+
+ -- Command: magit-file-rename
+
+     This command renames a file read from the user.
+
+ -- Command: magit-file-delete
+
+     This command deletes a file read from the user.
+
+ -- Command: magit-file-untrack
+
+     This command untracks a file read from the user.
+
+ -- Command: magit-file-checkout
+
+     This command updates a file in the working tree and index to the
+     contents from a revision.  Both the revision and file are read from
+     the user.
+
+   You could add them to the popup like so:
+
+     (magit-define-popup-action 'magit-file-popup
+       ?R "Rename file" 'magit-file-rename)
+     (magit-define-popup-action 'magit-file-popup
+       ?K "Delete file" 'magit-file-delete)
+     (magit-define-popup-action 'magit-file-popup
+       ?U "Untrack file" 'magit-file-untrack)
+     (magit-define-popup-action 'magit-file-popup
+       ?C "Checkout file" 'magit-file-checkout)
+
+
+File: magit.info,  Node: Minor Mode for Buffers Visiting Blobs,  Prev: Minor Mode for Buffers Visiting Files,  Up: Miscellaneous
+
+8.9 Minor Mode for Buffers Visiting Blobs
+=========================================
+
+The ‘magit-blob-mode’ enables certain Magit features in blob-visiting
+buffers.  Such buffers can be created using ‘magit-find-file’ and some
+of the commands mentioned below, which also take care of turning on this
+minor mode.  Currently this mode only establishes a few key bindings,
+but this might be extended.
+
+‘p’     (‘magit-blob-previous’)
+
+     Visit the previous blob which modified the current file.
+
+‘n’     (‘magit-blob-next’)
+
+     Visit the next blob which modified the current file.
+
+‘q’     (‘magit-kill-this-buffer’)
+
+     Kill the current buffer.
+
+
+File: magit.info,  Node: Customizing,  Next: Plumbing,  Prev: Miscellaneous,  Up: Top
+
+9 Customizing
+*************
+
+Both Git and Emacs are highly customizable.  Magit is both a Git
+porcelain as well as an Emacs package, so it makes sense to customize it
+using both Git variables as well as Emacs options.  However this
+flexibility doesn’t come without problems, including but not limited to
+the following.
+
+   • Some Git variables automatically have an effect in Magit without
+     requiring any explicit support.  Sometimes that is desirable - in
+     other cases, it breaks Magit.
+
+     When a certain Git setting breaks Magit but you want to keep using
+     that setting on the command line, then that can be accomplished by
+     overriding the value for Magit only by appending something like
+     ‘("-c" "some.variable=compatible-value")’ to
+     ‘magit-git-global-arguments’.
+
+   • Certain settings like ‘fetch.prune=true’ are respected by Magit
+     commands (because they simply call the respective Git command) but
+     their value is not reflected in the respective popup buffers.  In
+     this case the ‘--prune’ argument in ‘magit-fetch-popup’ might be
+     active or inactive depending on the value of
+     ‘magit-fetch-arguments’ only, but that doesn’t keep the Git
+     variable from being honored by the suffix commands anyway.  So
+     pruning might happen despite the ‘--prune’ arguments being
+     displayed in a way that seems to indicate that no pruning will
+     happen.
+
+   I intend to address these and similar issues in a future release.
+
+* Menu:
+
+* Per-Repository Configuration::
+* Essential Settings::
+
+
+File: magit.info,  Node: Per-Repository Configuration,  Next: Essential Settings,  Up: Customizing
+
+9.1 Per-Repository Configuration
+================================
+
+Magit can be configured on a per-repository level using both Git
+variables as well as Emacs options.
+
+   To set a Git variable for one repository only, simply set it in
+‘/path/to/repo/.git/config’ instead of ‘$HOME/.gitconfig’ or
+‘/etc/gitconfig’.  See *note (gitman)git-config::.
+
+   Similarly, Emacs options can be set for one repository only by
+editing ‘/path/to/repo/.dir-locals.el’.  See *note (emacs)Directory
+Variables::.  For example to disable automatic refreshes of
+file-visiting buffers in just one huge repository use this:
+
+   • ‘/path/to/huge/repo/.dir-locals.el’
+
+          ((nil . ((magit-refresh-buffers . nil))))
+
+   If you want to apply the same settings to several, but not all,
+repositories then keeping the repository-local config files in sync
+would quickly become annoying.  To avoid that you can create config
+files for certain classes of repositories (e.g.  "huge repositories")
+and then include those files in the per-repository config files.  For
+example:
+
+   • ‘/path/to/huge/repo/.git/config’
+
+          [include]
+                  path = /path/to/huge-gitconfig
+
+   • ‘/path/to/huge-gitconfig’
+
+          [status]
+                  showUntrackedFiles = no
+
+   • ‘$HOME/.emacs.d/init.el’
+
+          (dir-locals-set-class-variables 'huge-git-repository
+             '((nil . ((magit-refresh-buffers . nil)))))
+
+          (dir-locals-set-directory-class
+             "/path/to/huge/repo/" 'huge-git-repository)
+
+
+File: magit.info,  Node: Essential Settings,  Prev: Per-Repository Configuration,  Up: Customizing
+
+9.2 Essential Settings
+======================
+
+The next two sections list and discuss several variables that many users
+might want to customize, for safety and/or performance reasons.
+
+* Menu:
+
+* Safety::
+* Performance::
+
+
+File: magit.info,  Node: Safety,  Next: Performance,  Up: Essential Settings
+
+9.2.1 Safety
+------------
+
+This section discusses various variables that you might want to change
+(or *not* change) for safety reasons.
+
+   Git keeps *committed* changes around long enough for users to recover
+changes they have accidentally been deleted.  It does not do the same
+for *uncommitted* changes in the working tree and not even the index
+(the staging area).  Because Magit makes it so easy to modify
+uncommitted changes, it also makes it easy to shoot yourself in the foot
+in the process.  For that reason Magit provides three global modes that
+save *tracked* files to work-in-progress references after or before
+certain actions.  See *note Wip Modes::.
+
+   These modes are not enabled by default because of performance
+concerns.  Instead a lot of potentially destructive commands require
+confirmation every time they are used.  In many cases this can be
+disabled by adding a symbol to ‘magit-no-confirm’ (see *note Completion
+and Confirmation::).  If you enable the various wip modes then you
+should add ‘safe-with-wip’ to this list.
+
+   Similarly it isn’t necessary to require confirmation before moving a
+file to the system trash - if you trashed a file by mistake then you can
+recover it from the there.  Option ‘magit-delete-by-moving-to-trash’
+controls whether the system trash is used, which is the case by default.
+Nevertheless, ‘trash’ isn’t a member of ‘magit-no-confirm’ - you might
+want to change that.
+
+   By default buffers visiting files are automatically reverted when the
+visited file changes on disk.  This isn’t as risky as it might seem, but
+to make an informed decision you should see *note Risk of Reverting
+Automatically::.
+
+
+File: magit.info,  Node: Performance,  Prev: Safety,  Up: Essential Settings
+
+9.2.2 Performance
+-----------------
+
+After Magit has run ‘git’ for side-effects, it also refreshes the
+current Magit buffer and the respective status buffer.  This is
+necessary because otherwise outdated information might be displayed
+without the user noticing.  Magit buffers are updated by recreating
+their content from scratch, which makes updating simpler and less
+error-prone, but also more costly.  Keeping it simple and just
+re-creating everything from scratch is an old design decision and
+departing from that will require major refactoring.
+
+   I plan to do that in time for the next major release.  I also intend
+to create logs and diffs asynchronously, which should also help a lot
+but also requires major refactoring.
+
+   Meanwhile you can tell Magit to only automatically refresh the
+current Magit buffer, but not the status buffer.  If you do that, then
+the status buffer is only refreshed automatically if it is the current
+buffer.
+
+     (setq magit-refresh-status-buffer nil)
+
+   You should also check whether any third-party packages have added
+anything to ‘magit-refresh-buffer-hook’, ‘magit-status-refresh-hook’,
+‘magit-pre-refresh-hook’, and ‘magit-post-refresh-hook’.  If so, then
+check whether those additions impact performance significantly.  Setting
+‘magit-refresh-verbose’ and then inspecting the output in the
+‘*Messages*’ buffer, should help doing so.
+
+   Magit also reverts buffers for visited files located inside the
+current repository when the visited file changes on disk.  That is
+implemented on top of ‘auto-revert-mode’ from the built-in library
+‘autorevert’.  To figure out whether that impacts performance, check
+whether performance is significantly worse, when many buffers exist
+and/or when some buffers visit files using TRAMP.  If so, then this
+should help.
+
+     (setq auto-revert-buffer-list-filter
+           'magit-auto-revert-repository-buffers-p)
+
+   For alternative approaches see *note Automatic Reverting of
+File-Visiting Buffers::.
+
+   If you have enabled any features that are disabled by default, then
+you should check whether they impact performance significantly.  It’s
+likely that they were not enabled by default because it is known that
+they reduce performance at least in large repositories.
+
+   If performance is only slow inside certain unusually large
+repositories, then you might want to disable certain features on a
+per-repository or per-repository-class basis only.  See *note
+Per-Repository Configuration::.
+
+* Menu:
+
+* Microsoft Windows Performance::
+* MacOS Performance::
+
+Log Performance
+...............
+
+When showing logs, Magit limits the number of commits initially shown in
+the hope that this avoids unnecessary work.  When using ‘--graph’ is
+used, then this unfortunately does not have the desired effect for large
+histories.  Junio, Git’s maintainer, said on the git mailing list
+(<http://www.spinics.net/lists/git/msg232230.html>): "‘--graph’ wants to
+compute the whole history and the max-count only affects the output
+phase after ‘--graph’ does its computation".
+
+   In other words, it’s not that Git is slow at outputting the
+differences, or that Magit is slow at parsing the output - the problem
+is that Git first goes outside and has a smoke.
+
+   We actually work around this issue by limiting the number of commits
+not only by using ‘-<N>’ but by also using a range.  But unfortunately
+that’s not always possible.
+
+   In repositories with more than a few thousand commits ‘--graph’
+should never be a member of ‘magit-log-section-arguments’.  That
+variable is used in the status buffer which is refreshed every time you
+run any Magit command.
+
+   Using ‘--color --graph’ is even slower.  Magit uses code that is part
+of Emacs to turn control characters into faces.  That code is pretty
+slow and this is quite noticeable when showing a log with many branches
+and merges.  For that reason ‘--color’ is not enabled by default
+anymore.  Consider leaving it at that.
+
+Diff Performance
+................
+
+If diffs are slow, then consider turning off some optional diff features
+by setting all or some of the following variables to ‘nil’:
+‘magit-diff-highlight-indentation’, ‘magit-diff-highlight-trailing’,
+‘magit-diff-paint-whitespace’, ‘magit-diff-highlight-hunk-body’, and
+‘magit-diff-refine-hunk’.
+
+   When showing a commit instead of some arbitrary diff, then some
+additional information is displayed.  Calculating this information can
+be quite expensive given certain circumstances.  If looking at a commit
+using ‘magit-revision-mode’ takes considerably more time than looking at
+the same commit in ‘magit-diff-mode’, then consider setting
+‘magit-revision-insert-related-refs’ to ‘nil’.
+
+Refs Buffer Performance
+.......................
+
+When refreshing the "references buffer" is slow, then that’s usually
+because several hundred refs are being displayed.  The best way to
+address that is to display fewer refs, obviously.
+
+   If you are not, or only mildly, interested in seeing the list of
+tags, then start by not displaying them:
+
+     (remove-hook 'magit-refs-sections-hook 'magit-insert-tags)
+
+   Then you should also make sure that the listed remote branches
+actually all exist.  You can do so by pruning branches which no longer
+exist using ‘f-pa’.
+
+Committing Performance
+......................
+
+When you initiate a commit, then Magit by default automatically shows a
+diff of the changes you are about to commit.  For large commits this can
+take a long time, which is especially distracting when you are
+committing large amounts of generated data which you don’t actually
+intend to inspect before committing.  This behavior can be turned off
+using:
+
+     (remove-hook 'server-switch-hook 'magit-commit-diff)
+
+   Then you can type ‘C-c C-d’ to show the diff when you actually want
+to see it, but only then.  Alternatively you can leave the hook alone
+and just type ‘C-g’ in those cases when it takes too long to generate
+the diff.  If you do that, then you will end up with a broken diff
+buffer, but doing it this way has the advantage that you usually get to
+see the diff, which is useful because it increases the odds that you
+spot potential issues.
+
+The Built-In VC Package
+.......................
+
+Emacs comes with a version control interface called "VC", see *note
+(emacs)Version Control::.  It is enabled be default, and if you don’t
+use it in addition to Magit, then you should disable it to keep it from
+performing unnecessary work:
+
+     (setq vc-handled-backends nil)
+
+   You can also disable its use for Git but keep using it when using
+another version control system:
+
+     (setq vc-handled-backends (delq 'Git vc-handled-backends))
+
diff --git a/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit.info-2 b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit.info-2
new file mode 100644
index 0000000000..4db03f0304
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-20180719.1904/magit.info-2
@@ -0,0 +1,2600 @@
+This is magit.info, produced by makeinfo version 6.1 from magit.texi.
+
+     Copyright (C) 2015-2018 Jonas Bernoulli <jonas@bernoul.li>
+
+     You can redistribute this document 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.
+
+     This document 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.
+INFO-DIR-SECTION Emacs
+START-INFO-DIR-ENTRY
+* Magit: (magit).       Using Git from Emacs with Magit.
+END-INFO-DIR-ENTRY
+
+
+File: magit.info,  Node: Microsoft Windows Performance,  Next: MacOS Performance,  Up: Performance
+
+Microsoft Windows Performance
+.............................
+
+In order to update the status buffer, ‘git’ has to be run a few dozen
+times.  That is problematic on Microsoft Windows, because that operating
+system is exceptionally slow at starting processes.  Sadly this is an
+issue that can only be fixed by Microsoft itself, and they don’t appear
+to be particularly interested in doing so.
+
+   Beside the subprocess issue, there are also other Windows-specific
+performance issues.  Some of these have workarounds.  The maintainers of
+"Git for Windows" try to improve performance on Windows.  Always use the
+latest release in order to benefit from the latest performance tweaks.
+Magit too tries to work around some Windows-specific issues.
+
+   According to some sources, setting the following Git variables can
+also help.
+
+     git config --global core.preloadindex true   # default since v2.1
+     git config --global core.fscache true        # default since v2.8
+     git config --global gc.auto 256
+
+   You should also check whether an anti-virus program is affecting
+performance.
+
+
+File: magit.info,  Node: MacOS Performance,  Prev: Microsoft Windows Performance,  Up: Performance
+
+MacOS Performance
+.................
+
+On macOS Emacs currently creates child processes using ‘fork’.  It
+appears that this also copies GUI resources.  The result is that forking
+takes about 30 times as long on Darwin than on Linux.  And because Magit
+starts many ‘git’ processes even when doing simple things, that makes
+quite a difference.
+
+   On the ‘master’ branch Emacs now uses ‘vfork’ when possible, like
+this was already done on Linux, and now child creation only takes about
+twice as long on Darwin.  See (1) for more information.
+
+   Nobody knows when the changes on the ‘master’ branch will be released
+as ‘26.1’, but it is still a long way off.  You might want to get your
+hands on this change before then.  The easiest way to get a patched
+Emacs is to install the ‘emacs-plus’ formula (2) using ‘homebrew’.  The
+change has been backported, so you get it not only when using ‘--HEAD’,
+but also when using ‘--devel’ or when installing the latest release (by
+not using a version argument).
+
+   Alternatively you can apply the backport (3) manually.
+
+   ---------- Footnotes ----------
+
+   (1) 
+<https://lists.gnu.org/archive/html/bug-gnu-emacs/2017-04/msg00201.html>
+
+   (2) <https://github.com/d12frosted/homebrew-emacs-plus>
+
+   (3) 
+<https://gist.githubusercontent.com/aaronjensen/f45894ddf431ecbff78b1bcf533d3e6b/raw/6a5cd7f57341aba673234348d8b0d2e776f86719/Emacs-25-OS-X-use-vfork.patch>
+
+
+File: magit.info,  Node: Plumbing,  Next: FAQ,  Prev: Customizing,  Up: Top
+
+10 Plumbing
+***********
+
+The following sections describe how to use several of Magit’s core
+abstractions to extend Magit itself or implement a separate extension.
+
+   A few of the low-level features used by Magit have been factored out
+into separate libraries/packages, so that they can be used by other
+packages, without having to depend on Magit.  These libraries are
+described in separate manuals, see *note (with-editor)Top:: and *note
+(magit-popup)Top::.
+
+   If you are trying to find an unused key that you can bind to a
+command provided by your own Magit extension, then checkout
+<https://github.com/magit/magit/wiki/Plugin-Dispatch-Key-Registry>.
+
+* Menu:
+
+* Calling Git::
+* Section Plumbing::
+* Refreshing Buffers::
+* Conventions::
+
+
+File: magit.info,  Node: Calling Git,  Next: Section Plumbing,  Up: Plumbing
+
+10.1 Calling Git
+================
+
+Magit provides many specialized functions for calling Git.  All of these
+functions are defined in either ‘magit-git.el’ or ‘magit-process.el’ and
+have one of the prefixes ‘magit-run-’, ‘magit-call-’, ‘magit-start-’, or
+‘magit-git-’ (which is also used for other things).
+
+   All of these functions accept an indefinite number of arguments,
+which are strings that specify command line arguments for Git (or in
+some cases an arbitrary executable).  These arguments are flattened
+before being passed on to the executable; so instead of strings they can
+also be lists of strings and arguments that are ‘nil’ are silently
+dropped.  Some of these functions also require a single mandatory
+argument before these command line arguments.
+
+   Roughly speaking, these functions run Git either to get some value or
+for side-effects.  The functions that return a value are useful to
+collect the information necessary to populate a Magit buffer, while the
+others are used to implement Magit commands.
+
+   The functions in the value-only group always run synchronously, and
+they never trigger a refresh.  The function in the side-effect group can
+be further divided into subgroups depending on whether they run Git
+synchronously or asynchronously, and depending on whether they trigger a
+refresh when the executable has finished.
+
+* Menu:
+
+* Getting a Value from Git::
+* Calling Git for Effect::
+
+
+File: magit.info,  Node: Getting a Value from Git,  Next: Calling Git for Effect,  Up: Calling Git
+
+10.1.1 Getting a Value from Git
+-------------------------------
+
+These functions run Git in order to get a value, an exit status, or
+output.  Of course you could also use them to run Git commands that have
+side-effects, but that should be avoided.
+
+ -- Function: magit-git-exit-code &rest args
+
+     Executes git with ARGS and returns its exit code.
+
+ -- Function: magit-git-success &rest args
+
+     Executes git with ARGS and returns ‘t’ if the exit code is ‘0’,
+     ‘nil’ otherwise.
+
+ -- Function: magit-git-failure &rest args
+
+     Executes git with ARGS and returns ‘t’ if the exit code is ‘1’,
+     ‘nil’ otherwise.
+
+ -- Function: magit-git-true &rest args
+
+     Executes git with ARGS and returns ‘t’ if the first line printed by
+     git is the string "true", ‘nil’ otherwise.
+
+ -- Function: magit-git-false &rest args
+
+     Executes git with ARGS and returns ‘t’ if the first line printed by
+     git is the string "false", ‘nil’ otherwise.
+
+ -- Function: magit-git-insert &rest args
+
+     Executes git with ARGS and inserts its output at point.
+
+ -- Function: magit-git-string &rest args
+
+     Executes git with ARGS and returns the first line of its output.
+     If there is no output or if it begins with a newline character,
+     then this returns ‘nil’.
+
+ -- Function: magit-git-lines &rest args
+
+     Executes git with ARGS and returns its output as a list of lines.
+     Empty lines anywhere in the output are omitted.
+
+ -- Function: magit-git-items &rest args
+
+     Executes git with ARGS and returns its null-separated output as a
+     list.  Empty items anywhere in the output are omitted.
+
+     If the value of option ‘magit-git-debug’ is non-nil and git exits
+     with a non-zero exit status, then warn about that in the echo area
+     and add a section containing git’s standard error in the current
+     repository’s process buffer.
+
+   If an error occurs when using one of the above functions, then that
+is usually due to a bug, i.e.  using an argument which is not actually
+supported.  Such errors are usually not reported, but when they occur we
+need to be able to debug them.
+
+ -- User Option: magit-git-debug
+
+     Whether to report errors that occur when using ‘magit-git-insert’,
+     ‘magit-git-string’, ‘magit-git-lines’, or ‘magit-git-items’.  This
+     does not actually raise an error.  Instead a message is shown in
+     the echo area, and git’s standard error is insert into a new
+     section in the current repository’s process buffer.
+
+ -- Function: magit-git-str &rest args
+
+     This is a variant of ‘magit-git-string’ that ignores the option
+     ‘magit-git-debug’.  It is mainly intended to be used while handling
+     errors in functions that do respect that option.  Using such a
+     function while handing an error could cause yet another error and
+     therefore lead to an infinite recursion.  You probably won’t ever
+     need to use this function.
+
+
+File: magit.info,  Node: Calling Git for Effect,  Prev: Getting a Value from Git,  Up: Calling Git
+
+10.1.2 Calling Git for Effect
+-----------------------------
+
+These functions are used to run git to produce some effect.  Most Magit
+commands that actually run git do so by using such a function.
+
+   Because we do not need to consume git’s output when using these
+functions, their output is instead logged into a per-repository buffer,
+which can be shown using ‘$’ from a Magit buffer or ‘M-x magit-process’
+elsewhere.
+
+   These functions can have an effect in two distinct ways.  Firstly,
+running git may change something, i.e.  create or push a new commit.
+Secondly, that change may require that Magit buffers are refreshed to
+reflect the changed state of the repository.  But refreshing isn’t
+always desirable, so only some of these functions do perform such a
+refresh after git has returned.
+
+   Sometimes it is useful to run git asynchronously.  For example, when
+the user has just initiated a push, then there is no reason to make her
+wait until that has completed.  In other cases it makes sense to wait
+for git to complete before letting the user do something else.  For
+example after staging a change it is useful to wait until after the
+refresh because that also automatically moves to the next change.
+
+ -- Function: magit-call-git &rest args
+
+     Calls git synchronously with ARGS.
+
+ -- Function: magit-call-process program &rest args
+
+     Calls PROGRAM synchronously with ARGS.
+
+ -- Function: magit-run-git &rest args
+
+     Calls git synchronously with ARGS and then refreshes.
+
+ -- Function: magit-run-git-with-input input &rest args
+
+     Calls git synchronously with ARGS and sends it INPUT on standard
+     input.
+
+     INPUT should be a buffer or the name of an existing buffer.  The
+     content of that buffer is used as the process’ standard input.
+     After the process returns a refresh is performed.
+
+     As a special case, INPUT may also be nil.  In that case the content
+     of the current buffer is used as standard input and *no* refresh is
+     performed.
+
+     This function actually runs git asynchronously.  But then it waits
+     for the process to return, so the function itself is synchronous.
+
+ -- Function: magit-run-git-with-logfile file &rest args
+
+     Calls git synchronously with ARGS.  The process’ output is saved in
+     FILE.  This is rarely useful and so this function might be removed
+     in the future.
+
+     This function actually runs git asynchronously.  But then it waits
+     for the process to return, so the function itself is synchronous.
+
+ -- Function: magit-git &rest args
+
+     Calls git synchronously with ARGS for side-effects only.  This
+     function does not refresh the buffer.
+
+ -- Function: magit-git-wash washer &rest args
+
+     Execute Git with ARGS, inserting washed output at point.  Actually
+     first insert the raw output at point.  If there is no output call
+     ‘magit-cancel-section’.  Otherwise temporarily narrow the buffer to
+     the inserted text, move to its beginning, and then call function
+     WASHER with ARGS as its sole argument.
+
+   And now for the asynchronous variants.
+
+ -- Function: magit-run-git-async &rest args
+
+     Start Git, prepare for refresh, and return the process object.
+     ARGS is flattened and then used as arguments to Git.
+
+     Display the command line arguments in the echo area.
+
+     After Git returns some buffers are refreshed: the buffer that was
+     current when this function was called (if it is a Magit buffer and
+     still alive), as well as the respective Magit status buffer.
+     Unmodified buffers visiting files that are tracked in the current
+     repository are reverted if ‘magit-revert-buffers’ is non-nil.
+
+ -- Function: magit-run-git-with-editor &rest args
+
+     Export GIT_EDITOR and start Git.  Also prepare for refresh and
+     return the process object.  ARGS is flattened and then used as
+     arguments to Git.
+
+     Display the command line arguments in the echo area.
+
+     After Git returns some buffers are refreshed: the buffer that was
+     current when this function was called (if it is a Magit buffer and
+     still alive), as well as the respective Magit status buffer.
+
+ -- Function: magit-start-git &rest args
+
+     Start Git, prepare for refresh, and return the process object.
+
+     If INPUT is non-nil, it has to be a buffer or the name of an
+     existing buffer.  The buffer content becomes the processes standard
+     input.
+
+     Option ‘magit-git-executable’ specifies the Git executable and
+     option ‘magit-git-global-arguments’ specifies constant arguments.
+     The remaining arguments ARGS specify arguments to Git.  They are
+     flattened before use.
+
+     After Git returns, some buffers are refreshed: the buffer that was
+     current when this function was called (if it is a Magit buffer and
+     still alive), as well as the respective Magit status buffer.
+     Unmodified buffers visiting files that are tracked in the current
+     repository are reverted if ‘magit-revert-buffers’ is non-nil.
+
+ -- Function: magit-start-process &rest args
+
+     Start PROGRAM, prepare for refresh, and return the process object.
+
+     If optional argument INPUT is non-nil, it has to be a buffer or the
+     name of an existing buffer.  The buffer content becomes the
+     processes standard input.
+
+     The process is started using ‘start-file-process’ and then setup to
+     use the sentinel ‘magit-process-sentinel’ and the filter
+     ‘magit-process-filter’.  Information required by these functions is
+     stored in the process object.  When this function returns the
+     process has not started to run yet so it is possible to override
+     the sentinel and filter.
+
+     After the process returns, ‘magit-process-sentinel’ refreshes the
+     buffer that was current when ‘magit-start-process’ was called (if
+     it is a Magit buffer and still alive), as well as the respective
+     Magit status buffer.  Unmodified buffers visiting files that are
+     tracked in the current repository are reverted if
+     ‘magit-revert-buffers’ is non-nil.
+
+ -- Variable: magit-this-process
+
+     The child process which is about to start.  This can be used to
+     change the filter and sentinel.
+
+ -- Variable: magit-process-raise-error
+
+     When this is non-nil, then ‘magit-process-sentinel’ raises an error
+     if git exits with a non-zero exit status.  For debugging purposes.
+
+
+File: magit.info,  Node: Section Plumbing,  Next: Refreshing Buffers,  Prev: Calling Git,  Up: Plumbing
+
+10.2 Section Plumbing
+=====================
+
+* Menu:
+
+* Creating Sections::
+* Section Selection::
+* Matching Sections::
+
+
+File: magit.info,  Node: Creating Sections,  Next: Section Selection,  Up: Section Plumbing
+
+10.2.1 Creating Sections
+------------------------
+
+ -- Macro: magit-insert-section &rest args
+
+     Insert a section at point.
+
+     TYPE is the section type, a symbol.  Many commands that act on the
+     current section behave differently depending on that type.  Also if
+     a variable ‘magit-TYPE-section-map’ exists, then use that as the
+     text-property ‘keymap’ of all text belonging to the section (but
+     this may be overwritten in subsections).  TYPE can also have the
+     form ‘(eval FORM)’ in which case FORM is evaluated at runtime.
+
+     Optional VALUE is the value of the section, usually a string that
+     is required when acting on the section.
+
+     When optional HIDE is non-nil collapse the section body by default,
+     i.e.  when first creating the section, but not when refreshing the
+     buffer.  Otherwise, expand it by default.  This can be overwritten
+     using ‘magit-section-set-visibility-hook’.  When a section is
+     recreated during a refresh, then the visibility of predecessor is
+     inherited and HIDE is ignored (but the hook is still honored).
+
+     BODY is any number of forms that actually insert the section’s
+     heading and body.  Optional NAME, if specified, has to be a symbol,
+     which is then bound to the struct of the section being inserted.
+
+     Before BODY is evaluated the ‘start’ of the section object is set
+     to the value of ‘point’ and after BODY was evaluated its ‘end’ is
+     set to the new value of ‘point’; BODY is responsible for moving
+     ‘point’ forward.
+
+     If it turns out inside BODY that the section is empty, then
+     ‘magit-cancel-section’ can be used to abort and remove all traces
+     of the partially inserted section.  This can happen when creating a
+     section by washing Git’s output and Git didn’t actually output
+     anything this time around.
+
+ -- Function: magit-insert-heading &rest args
+
+     Insert the heading for the section currently being inserted.
+
+     This function should only be used inside ‘magit-insert-section’.
+
+     When called without any arguments, then just set the ‘content’ slot
+     of the object representing the section being inserted to a marker
+     at ‘point’.  The section should only contain a single line when
+     this function is used like this.
+
+     When called with arguments ARGS, which have to be strings, then
+     insert those strings at point.  The section should not contain any
+     text before this happens and afterwards it should again only
+     contain a single line.  If the ‘face’ property is set anywhere
+     inside any of these strings, then insert all of them unchanged.
+     Otherwise use the ‘magit-section-heading’ face for all inserted
+     text.
+
+     The ‘content’ property of the section struct is the end of the
+     heading (which lasts from ‘start’ to ‘content’) and the beginning
+     of the body (which lasts from ‘content’ to ‘end’).  If the value of
+     ‘content’ is nil, then the section has no heading and its body
+     cannot be collapsed.  If a section does have a heading then its
+     height must be exactly one line, including a trailing newline
+     character.  This isn’t enforced; you are responsible for getting it
+     right.  The only exception is that this function does insert a
+     newline character if necessary.
+
+ -- Function: magit-cancel-section
+
+     Cancel the section currently being inserted.  This exits the
+     innermost call to ‘magit-insert-section’ and removes all traces of
+     what has already happened inside that call.
+
+ -- Function: magit-define-section-jumper sym title &optional value
+
+     Define an interactive function to go to section SYM.  TITLE is the
+     displayed title of the section.
+
+
+File: magit.info,  Node: Section Selection,  Next: Matching Sections,  Prev: Creating Sections,  Up: Section Plumbing
+
+10.2.2 Section Selection
+------------------------
+
+ -- Function: magit-current-section
+
+     Return the section at point.
+
+ -- Function: magit-region-sections
+
+     Return a list of the selected sections.
+
+     When the region is active and constitutes a valid section
+     selection, then return a list of all selected sections.  This is
+     the case when the region begins in the heading of a section and
+     ends in the heading of a sibling of that first section.  When the
+     selection is not valid then return nil.  Most commands that can act
+     on the selected sections, then instead just act on the current
+     section, the one point is in.
+
+     When the region looks like it would in any other buffer then the
+     selection is invalid.  When the selection is valid then the region
+     uses the ‘magit-section-highlight’.  This does not apply to diffs
+     where things get a bit more complicated, but even here if the
+     region looks like it usually does, then that’s not a valid
+     selection as far as this function is concerned.
+
+ -- Function: magit-region-values &rest types
+
+     Return a list of the values of the selected sections.
+
+     Also see ‘magit-region-sections’ whose doc-string explains when a
+     region is a valid section selection.  If the region is not active
+     or is not a valid section selection, then return nil.  If optional
+     TYPES is non-nil then the selection not only has to be valid; the
+     types of all selected sections additionally have to match one of
+     TYPES, or nil is returned.
+
+
+File: magit.info,  Node: Matching Sections,  Prev: Section Selection,  Up: Section Plumbing
+
+10.2.3 Matching Sections
+------------------------
+
+‘M-x magit-describe-section’     (‘magit-describe-section’)
+
+     Show information about the section at point.  This command is
+     intended for debugging purposes.
+
+ -- Function: magit-section-ident
+
+     Return an unique identifier for SECTION.  The return value has the
+     form ‘((TYPE . VALUE)...)’.
+
+ -- Function: magit-get-section
+
+     Return the section identified by IDENT.  IDENT has to be a list as
+     returned by ‘magit-section-ident’.
+
+ -- Function: magit-section-match condition &optional section
+
+     Return ‘t’ if SECTION matches CONDITION.  SECTION defaults to the
+     section at point.  If SECTION is not specified and there also is no
+     section at point, then return ‘nil’.
+
+     CONDITION can take the following forms:
+        • ‘(CONDITION...)’
+
+          matches if any of the CONDITIONs matches.
+
+        • ‘[TYPE...]’
+
+          matches if the first TYPE matches the type of the section, the
+          second matches that of its parent, and so on.
+
+        • ‘[* TYPE...]’
+
+          matches sections that match [TYPE...] and also recursively all
+          their child sections.
+
+        • ‘TYPE’
+
+          matches sections of TYPE regardless of the types of the parent
+          sections.
+
+     Each TYPE is a symbol.  Note that it is not necessary to specify
+     all TYPEs up to the root section as printed by
+     ‘magit-describe-type’, unless of course you want to be that
+     precise.
+
+ -- Function: magit-section-when condition &rest body
+
+     If the section at point matches CONDITION evaluate BODY.
+
+     If the section matches, then evaluate BODY forms sequentially with
+     ‘it’ bound to the section and return the value of the last form.
+     If there are no BODY forms, then return the value of the section.
+     If the section does not match or if there is no section at point
+     then return nil.
+
+     See ‘magit-section-match’ for the forms CONDITION can take.
+
+ -- Function: magit-section-case &rest clauses
+
+     Choose among clauses on the type of the section at point.
+
+     Each clause looks like (CONDITION BODY...).  The type of the
+     section is compared against each CONDITION; the BODY forms of the
+     first match are evaluated sequentially and the value of the last
+     form is returned.  Inside BODY the symbol ‘it’ is bound to the
+     section at point.  If no clause succeeds or if there is no section
+     at point return nil.
+
+     See ‘magit-section-match’ for the forms CONDITION can take.
+     Additionally a CONDITION of t is allowed in the final clause and
+     matches if no other CONDITION match, even if there is no section at
+     point.
+
+ -- Variable: magit-root-section
+
+     The root section in the current buffer.  All other sections are
+     descendants of this section.  The value of this variable is set by
+     ‘magit-insert-section’ and you should never modify it.
+
+   For diff related sections a few additional tools exist.
+
+ -- Function: magit-diff-type &optional section
+
+     Return the diff type of SECTION.
+
+     The returned type is one of the symbols ‘staged’, ‘unstaged’,
+     ‘committed’, or ‘undefined’.  This type serves a similar purpose as
+     the general type common to all sections (which is stored in the
+     ‘type’ slot of the corresponding ‘magit-section’ struct) but takes
+     additional information into account.  When the SECTION isn’t
+     related to diffs and the buffer containing it also isn’t a
+     diff-only buffer, then return nil.
+
+     Currently the type can also be one of ‘tracked’ and ‘untracked’,
+     but these values are not handled explicitly in every place they
+     should be.  A possible fix could be to just return nil here.
+
+     The section has to be a ‘diff’ or ‘hunk’ section, or a section
+     whose children are of type ‘diff’.  If optional SECTION is nil,
+     return the diff type for the current section.  In buffers whose
+     major mode is ‘magit-diff-mode’ SECTION is ignored and the type is
+     determined using other means.  In ‘magit-revision-mode’ buffers the
+     type is always ‘committed’.
+
+ -- Function: magit-diff-scope &optional section strict
+
+     Return the diff scope of SECTION or the selected section(s).
+
+     A diff’s "scope" describes what part of a diff is selected, it is a
+     symbol, one of ‘region’, ‘hunk’, ‘hunks’, ‘file’, ‘files’, or
+     ‘list’.  Do not confuse this with the diff "type", as returned by
+     ‘magit-diff-type’.
+
+     If optional SECTION is non-nil, then return the scope of that,
+     ignoring the sections selected by the region.  Otherwise return the
+     scope of the current section, or if the region is active and
+     selects a valid group of diff related sections, the type of these
+     sections, i.e.  ‘hunks’ or ‘files’.  If SECTION (or if the current
+     section that is nil) is a ‘hunk’ section and the region starts and
+     ends inside the body of a that section, then the type is ‘region’.
+
+     If optional STRICT is non-nil then return nil if the diff type of
+     the section at point is ‘untracked’ or the section at point is not
+     actually a ‘diff’ but a ‘diffstat’ section.
+
+
+File: magit.info,  Node: Refreshing Buffers,  Next: Conventions,  Prev: Section Plumbing,  Up: Plumbing
+
+10.3 Refreshing Buffers
+=======================
+
+All commands that create a new Magit buffer or change what is being
+displayed in an existing buffer do so by calling ‘magit-mode-setup’.
+Among other things, that function sets the buffer local values of
+‘default-directory’ (to the top-level of the repository),
+‘magit-refresh-function’, and ‘magit-refresh-args’.
+
+   Buffers are refreshed by calling the function that is the local value
+of ‘magit-refresh-function’ (a function named ‘magit-*-refresh-buffer’,
+where ‘*’ may be something like ‘diff’) with the value of
+‘magit-refresh-args’ as arguments.
+
+ -- Macro: magit-mode-setup buffer switch-func mode refresh-func
+          &optional refresh-args
+
+     This function displays and selects BUFFER, turns on MODE, and
+     refreshes a first time.
+
+     This function displays and optionally selects BUFFER by calling
+     ‘magit-mode-display-buffer’ with BUFFER, MODE and SWITCH-FUNC as
+     arguments.  Then it sets the local value of
+     ‘magit-refresh-function’ to REFRESH-FUNC and that of
+     ‘magit-refresh-args’ to REFRESH-ARGS.  Finally it creates the
+     buffer content by calling REFRESH-FUNC with REFRESH-ARGS as
+     arguments.
+
+     All arguments are evaluated before switching to BUFFER.
+
+ -- Function: magit-mode-display-buffer buffer mode &optional
+          switch-function
+
+     This function display BUFFER in some window and select it.  BUFFER
+     may be a buffer or a string, the name of a buffer.  The buffer is
+     returned.
+
+     Unless BUFFER is already displayed in the selected frame, store the
+     previous window configuration as a buffer local value, so that it
+     can later be restored by ‘magit-mode-bury-buffer’.
+
+     The buffer is displayed and selected using SWITCH-FUNCTION.  If
+     that is ‘nil’ then ‘pop-to-buffer’ is used if the current buffer’s
+     major mode derives from ‘magit-mode’.  Otherwise ‘switch-to-buffer’
+     is used.
+
+ -- Variable: magit-refresh-function
+
+     The value of this buffer-local variable is the function used to
+     refresh the current buffer.  It is called with ‘magit-refresh-args’
+     as arguments.
+
+ -- Variable: magit-refresh-args
+
+     The list of arguments used by ‘magit-refresh-function’ to refresh
+     the current buffer.  ‘magit-refresh-function’ is called with these
+     arguments.
+
+     The value is usually set using ‘magit-mode-setup’, but in some
+     cases it’s also useful to provide commands which can change the
+     value.  For example, the ‘magit-diff-refresh-popup’ can be used to
+     change any of the arguments used to display the diff, without
+     having to specify again which differences should be shown.
+     ‘magit-diff-more-context’, ‘magit-diff-less-context’, and
+     ‘magit-diff-default-context’ change just the ‘-U<N>’ argument.  In
+     both case this is done by changing the value of this variable and
+     then calling this ‘magit-refresh-function’.
+
+
+File: magit.info,  Node: Conventions,  Prev: Refreshing Buffers,  Up: Plumbing
+
+10.4 Conventions
+================
+
+Also see *note Completion and Confirmation::.
+
+* Menu:
+
+* Theming Faces::
+
+
+File: magit.info,  Node: Theming Faces,  Up: Conventions
+
+10.4.1 Theming Faces
+--------------------
+
+The default theme uses blue for local branches, green for remote
+branches, and goldenrod (brownish yellow) for tags.  When creating a new
+theme, you should probably follow that example.  If your theme already
+uses other colors, then stick to that.
+
+   In older releases these reference faces used to have a background
+color and a box around them.  The basic default faces no longer do so,
+to make Magit buffers much less noisy, and you should follow that
+example at least with regards to boxes.  (Boxes were used in the past to
+work around a conflict between the highlighting overlay and text
+property backgrounds.  That’s no longer necessary because highlighting
+no longer causes other background colors to disappear.)  Alternatively
+you can keep the background color and/or box, but then have to take
+special care to adjust ‘magit-branch-current’ accordingly.  By default
+it looks mostly like ‘magit-branch-local’, but with a box (by default
+the former is the only face that uses a box, exactly so that it sticks
+out).  If the former also uses a box, then you have to make sure that it
+differs in some other way from the latter.
+
+   The most difficult faces to theme are those related to diffs,
+headings, highlighting, and the region.  There are faces that fall into
+all four groups - expect to spend some time getting this right.
+
+   The ‘region’ face in the default theme, in both the light and dark
+variants, as well as in many other themes, distributed with Emacs or by
+third-parties, is very ugly.  It is common to use a background color
+that really sticks out, which is ugly but if that were the only problem
+then it would be acceptable.  Unfortunately many themes also set the
+foreground color, which ensures that all text within the region is
+readable.  Without doing that there might be cases where some foreground
+color is too close to the region background color to still be readable.
+But it also means that text within the region loses all syntax
+highlighting.
+
+   I consider the work that went into getting the ‘region’ face right to
+be a good indicator for the general quality of a theme.  My
+recommendation for the ‘region’ face is this: use a background color
+slightly different from the background color of the ‘default’ face, and
+do not set the foreground color at all.  So for a light theme you might
+use a light (possibly tinted) gray as the background color of ‘default’
+and a somewhat darker gray for the background of ‘region’.  That should
+usually be enough to not collide with the foreground color of any other
+face.  But if some other faces also set a light gray as background
+color, then you should also make sure it doesn’t collide with those (in
+some cases it might be acceptable though).
+
+   Magit only uses the ‘region’ face when the region is "invalid" by its
+own definition.  In a Magit buffer the region is used to either select
+multiple sibling sections, so that commands which support it act on all
+of these sections instead of just the current section, or to select
+lines within a single hunk section.  In all other cases, the section is
+considered invalid and Magit won’t act on it.  But such invalid sections
+happen, either because the user has not moved point enough yet to make
+it valid or because she wants to use a non-magit command to act on the
+region, e.g.  ‘kill-region’.
+
+   So using the regular ‘region’ face for invalid sections is a feature.
+It tells the user that Magit won’t be able to act on it.  It’s
+acceptable if that face looks a bit odd and even (but less so) if it
+collides with the background colors of section headings and other things
+that have a background color.
+
+   Magit highlights the current section.  If a section has subsections,
+then all of them are highlighted.  This is done using faces that have
+"highlight" in their names.  For most sections,
+‘magit-section-highlight’ is used for both the body and the heading.
+Like the ‘region’ face, it should only set the background color to
+something similar to that of ‘default’.  The highlight background color
+must be different from both the ‘region’ background color and the
+‘default’ background color.
+
+   For diff related sections Magit uses various faces to highlight
+different parts of the selected section(s).  Note that hunk headings,
+unlike all other section headings, by default have a background color,
+because it is useful to have very visible separators between hunks.
+That face ‘magit-diff-hunk-heading’, should be different from both
+‘magit-diff-hunk-heading-highlight’ and ‘magit-section-highlight’, as
+well as from ‘magit-diff-context’ and ‘magit-diff-context-highlight’.
+By default we do that by changing the foreground color.  Changing the
+background color would lead to complications, and there are already
+enough we cannot get around.  (Also note that it is generally a good
+idea for section headings to always be bold, but only for sections that
+have subsections).
+
+   When there is a valid region selecting diff-related sibling sections,
+i.e.  multiple files or hunks, then the bodies of all these sections use
+the respective highlight faces, but additionally the headings instead
+use one of the faces ‘magit-diff-file-heading-selection’ or
+‘magit-diff-hunk-heading-selection’.  These faces have to be different
+from the regular highlight variants to provide explicit visual
+indication that the region is active.
+
+   When theming diff related faces, start by setting the option
+‘magit-diff-refine-hunk’ to ‘all’.  You might personally prefer to only
+refine the current hunk or not use hunk refinement at all, but some of
+the users of your theme want all hunks to be refined, so you have to
+cater to that.
+
+   (Also turn on ‘magit-diff-highlight-indentation’,
+‘magit-diff-highlight-trailing’, and ‘magit-diff-paint-whitespace’; and
+insert some whitespace errors into the code you use for testing.)
+
+   For e.g.  "added lines" you have to adjust three faces:
+‘magit-diff-added’, ‘magit-diff-added-highlight’, and
+‘smerge-refined-added’.  Make sure that the latter works well with both
+of the former, as well as ‘smerge-other’ and ‘diff-added’.  Then do the
+same for the removed lines, context lines, lines added by us, and lines
+added by them.  Also make sure the respective added, removed, and
+context faces use approximately the same saturation for both the
+highlighted and unhighlighted variants.  Also make sure the file and
+diff headings work nicely with context lines (e.g.  make them look
+different).  Line faces should set both the foreground and the
+background color.  For example, for added lines use two different
+greens.
+
+   It’s best if the foreground color of both the highlighted and the
+unhighlighted variants are the same, so you will need to have to find a
+color that works well on the highlight and unhighlighted background, the
+refine background, and the highlight context background.  When there is
+an hunk internal region, then the added- and removed-lines background
+color is used only within that region.  Outside the region the
+highlighted context background color is used.  This makes it easier to
+see what is being staged.  With an hunk internal region the hunk heading
+is shown using ‘magit-diff-hunk-heading-selection’, and so are the thin
+lines that are added around the lines that fall within the region.  The
+background color of that has to be distinct enough from the various
+other involved background colors.
+
+   Nobody said this would be easy.  If your theme restricts itself to a
+certain set of colors, then you should make an exception here.
+Otherwise it would be impossible to make the diffs look good in each and
+every variation.  Actually you might want to just stick to the default
+definitions for these faces.  You have been warned.  Also please note
+that if you do not get this right, this will in some cases look to users
+like bugs in Magit - so please do it right or not at all.
+
+
+File: magit.info,  Node: FAQ,  Next: Debugging Tools,  Prev: Plumbing,  Up: Top
+
+Appendix A FAQ
+**************
+
+The next two nodes lists frequently asked questions.  For a list of
+frequently *and recently* asked questions, i.e.  questions that haven’t
+made it into the manual yet, see
+<https://github.com/magit/magit/wiki/FAQ>.
+
+   Please also use the *note Debugging Tools::.
+
+* Menu:
+
+* FAQ - How to ...?::
+* FAQ - Issues and Errors::
+
+
+File: magit.info,  Node: FAQ - How to ...?,  Next: FAQ - Issues and Errors,  Up: FAQ
+
+A.1 FAQ - How to ...?
+=====================
+
+* Menu:
+
+* How to show git's output?::
+* How to install the gitman info manual?::
+* How to show diffs for gpg-encrypted files?::
+* How does branching and pushing work?::
+* Can Magit be used as ediff-version-control-package?::
+
+
+File: magit.info,  Node: How to show git's output?,  Next: How to install the gitman info manual?,  Up: FAQ - How to ...?
+
+A.1.1 How to show git’s output?
+-------------------------------
+
+To show the output of recently run git commands, press ‘$’ (or, if that
+isn’t available, ‘M-x magit-process-buffer’).  This will show a buffer
+containing a section per git invocation; as always press ‘TAB’ to expand
+or collapse them.
+
+   By default, git’s output is only inserted into the process buffer if
+it is run for side-effects.  When the output is consumed in some way,
+also inserting it into the process buffer would be too expensive.  For
+debugging purposes, it’s possible to do so anyway by setting
+‘magit-git-debug’ to ‘t’.
+
+
+File: magit.info,  Node: How to install the gitman info manual?,  Next: How to show diffs for gpg-encrypted files?,  Prev: How to show git's output?,  Up: FAQ - How to ...?
+
+A.1.2 How to install the gitman info manual?
+--------------------------------------------
+
+Git’s manpages can be exported as an info manual called ‘gitman’.
+Magit’s own info manual links to nodes in that manual instead of the
+actual manpages because Info doesn’t support linking to manpages.
+
+   Unfortunately some distributions do not install the ‘gitman’ manual
+by default and you will have to install a separate documentation package
+to get it.
+
+   Magit patches Info adding the ability to visit links to the ‘gitman’
+Info manual by instead viewing the respective manpage.  If you prefer
+that approach, then set the value of ‘magit-view-git-manual-method’ to
+one of the supported packages ‘man’ or ‘woman’, e.g.:
+
+     (setq magit-view-git-manual-method 'man)
+
+
+File: magit.info,  Node: How to show diffs for gpg-encrypted files?,  Next: How does branching and pushing work?,  Prev: How to install the gitman info manual?,  Up: FAQ - How to ...?
+
+A.1.3 How to show diffs for gpg-encrypted files?
+------------------------------------------------
+
+Git supports showing diffs for encrypted files, but has to be told to do
+so.  Since Magit just uses Git to get the diffs, configuring Git also
+affects the diffs displayed inside Magit.
+
+     git config --global diff.gpg.textconv "gpg --no-tty --decrypt"
+     echo "*.gpg filter=gpg diff=gpg" > .gitattributes
+
+
+File: magit.info,  Node: How does branching and pushing work?,  Next: Can Magit be used as ediff-version-control-package?,  Prev: How to show diffs for gpg-encrypted files?,  Up: FAQ - How to ...?
+
+A.1.4 How does branching and pushing work?
+------------------------------------------
+
+Please see *note Branching:: and
+<http://emacsair.me/2016/01/17/magit-2.4>
+
+
+File: magit.info,  Node: Can Magit be used as ediff-version-control-package?,  Prev: How does branching and pushing work?,  Up: FAQ - How to ...?
+
+A.1.5 Can Magit be used as ‘ediff-version-control-package’?
+-----------------------------------------------------------
+
+No, it cannot.  For that to work the functions ‘ediff-magit-internal’
+and ‘ediff-magit-merge-internal’ would have to be implemented, and they
+are not.  These two functions are only used by the three commands
+‘ediff-revision’, ‘ediff-merge-revisions-with-ancestor’, and
+‘ediff-merge-revisions’.
+
+   These commands only delegate the task of populating buffers with
+certain revisions to the "internal" functions.  The equally important
+task of determining which revisions are to be compared/merged is not
+delegated.  Instead this is done without any support whatsoever from the
+version control package/system - meaning that the user has to enter the
+revisions explicitly.  Instead of implementing ‘ediff-magit-internal’ we
+provide ‘magit-ediff-compare’, which handles both tasks like it is 2005.
+
+   The other commands ‘ediff-merge-revisions’ and
+‘ediff-merge-revisions-with-ancestor’ are normally not what you want
+when using a modern version control system like Git.  Instead of letting
+the user resolve only those conflicts which Git could not resolve on its
+own, they throw away all work done by Git and then expect the user to
+manually merge all conflicts, including those that had already been
+resolved.  That made sense back in the days when version control systems
+couldn’t merge (or so I have been told), but not anymore.  Once in a
+blue moon you might actually want to see all conflicts, in which case
+you *can* use these commands, which then use ‘ediff-vc-merge-internal’.
+So we don’t actually have to implement ‘ediff-magit-merge-internal’.
+Instead we provide the more useful command ‘magit-ediff-resolve’ which
+only shows yet-to-be resolved conflicts.
+
+
+File: magit.info,  Node: FAQ - Issues and Errors,  Prev: FAQ - How to ...?,  Up: FAQ
+
+A.2 FAQ - Issues and Errors
+===========================
+
+* Menu:
+
+* Magit is slow::
+* I changed several thousand files at once and now Magit is unusable::
+* I am having problems committing::
+* I am using MS Windows and cannot push with Magit::
+* I am using OS X and SOMETHING works in shell, but not in Magit: I am using OS X and SOMETHING works in shell but not in Magit. 
+* Diffs contain control sequences::
+* Expanding a file to show the diff causes it to disappear::
+* Point is wrong in the COMMIT_EDITMSG buffer::
+* The mode-line information isn't always up-to-date::
+* A branch and tag sharing the same name breaks SOMETHING::
+* My Git hooks work on the command-line but not inside Magit::
+
+
+File: magit.info,  Node: Magit is slow,  Next: I changed several thousand files at once and now Magit is unusable,  Up: FAQ - Issues and Errors
+
+A.2.1 Magit is slow
+-------------------
+
+See *note Performance::.
+
+
+File: magit.info,  Node: I changed several thousand files at once and now Magit is unusable,  Next: I am having problems committing,  Prev: Magit is slow,  Up: FAQ - Issues and Errors
+
+A.2.2 I changed several thousand files at once and now Magit is unusable
+------------------------------------------------------------------------
+
+Magit is *currently* not expected to work under such conditions.  It
+sure would be nice if it did, and v2.5 will hopefully be a big step into
+that direction.  But it might take until v3.1 to accomplish fully
+satisfactory performance, because that requires some heavy refactoring.
+
+   But for now we recommend you use the command line to complete this
+one commit.  Also see *note Performance::.
+
+
+File: magit.info,  Node: I am having problems committing,  Next: I am using MS Windows and cannot push with Magit,  Prev: I changed several thousand files at once and now Magit is unusable,  Up: FAQ - Issues and Errors
+
+A.2.3 I am having problems committing
+-------------------------------------
+
+That likely means that Magit is having problems finding an appropriate
+emacsclient executable.  See *note (with-editor)Configuring
+With-Editor:: and *note (with-editor)Debugging::.
+
+
+File: magit.info,  Node: I am using MS Windows and cannot push with Magit,  Next: I am using OS X and SOMETHING works in shell but not in Magit,  Prev: I am having problems committing,  Up: FAQ - Issues and Errors
+
+A.2.4 I am using MS Windows and cannot push with Magit
+------------------------------------------------------
+
+It’s almost certain that Magit is only incidental to this issue.  It is
+much more likely that this is a configuration issue, even if you can
+push on the command line.
+
+   Detailed setup instructions can be found at
+<https://github.com/magit/magit/wiki/Pushing-with-Magit-from-Windows>.
+
+
+File: magit.info,  Node: I am using OS X and SOMETHING works in shell but not in Magit,  Next: Diffs contain control sequences,  Prev: I am using MS Windows and cannot push with Magit,  Up: FAQ - Issues and Errors
+
+A.2.5 I am using OS X and SOMETHING works in shell, but not in Magit
+--------------------------------------------------------------------
+
+This usually occurs because Emacs doesn’t have the same environment
+variables as your shell.  Try installing and configuring
+<https://github.com/purcell/exec-path-from-shell>.  By default it
+synchronizes ‘$PATH’, which helps Magit find the same ‘git’ as the one
+you are using on the shell.
+
+   If SOMETHING is "passphrase caching with gpg-agent for commit and/or
+tag signing", then you’ll also need to synchronize ‘$GPG_AGENT_INFO’.
+
+
+File: magit.info,  Node: Diffs contain control sequences,  Next: Expanding a file to show the diff causes it to disappear,  Prev: I am using OS X and SOMETHING works in shell but not in Magit,  Up: FAQ - Issues and Errors
+
+A.2.6 Diffs contain control sequences
+-------------------------------------
+
+This happens when you configure Git to always color diffs and/or all of
+its output.  The valid values for relevant Git variables ‘color.ui’ and
+‘color.diff’ are ‘false’, ‘true’ and ‘always’, and the default is
+‘true’.  You should leave it that because then you get colorful output
+in terminals but git’s output is consumed by something else, then no
+colors are used.
+
+   If you actually use some other tool which expects that requires that
+you force git to output control sequences (which is highly unlikely),
+then you can override these settings just for Magit by using:
+
+     (setq magit-git-global-arguments
+           (nconc magit-git-global-arguments
+                  '("-c" "color.ui=false"
+                    "-c" "color.diff=false")))
+
+
+File: magit.info,  Node: Expanding a file to show the diff causes it to disappear,  Next: Point is wrong in the COMMIT_EDITMSG buffer,  Prev: Diffs contain control sequences,  Up: FAQ - Issues and Errors
+
+A.2.7 Expanding a file to show the diff causes it to disappear
+--------------------------------------------------------------
+
+This is probably caused by a change of a ‘diff.*’ Git variable.  You
+probably set that variable for a reason, and should therefore only undo
+that setting in Magit by customizing ‘magit-git-global-arguments’.
+
+
+File: magit.info,  Node: Point is wrong in the COMMIT_EDITMSG buffer,  Next: The mode-line information isn't always up-to-date,  Prev: Expanding a file to show the diff causes it to disappear,  Up: FAQ - Issues and Errors
+
+A.2.8 Point is wrong in the ‘COMMIT_EDITMSG’ buffer
+---------------------------------------------------
+
+Neither Magit nor ‘git-commit‘ fiddle with point in the buffer used to
+write commit messages, so something else must be doing it.
+
+   You have probably globally enabled a mode which does restore point in
+file-visiting buffers.  It might be a bit surprising, but when you write
+a commit message, then you are actually editing a file.
+
+   So you have to figure out which package is doing.  ‘saveplace’,
+‘pointback’, and ‘session’ are likely candidates.  These snippets might
+help:
+
+     (setq session-name-disable-regexp "\\(?:\\`'\\.git/[A-Z_]+\\'\\)")
+
+     (with-eval-after-load 'pointback
+       (lambda ()
+         (when (or git-commit-mode git-rebase-mode)
+           (pointback-mode -1))))
+
+
+File: magit.info,  Node: The mode-line information isn't always up-to-date,  Next: A branch and tag sharing the same name breaks SOMETHING,  Prev: Point is wrong in the COMMIT_EDITMSG buffer,  Up: FAQ - Issues and Errors
+
+A.2.9 The mode-line information isn’t always up-to-date
+-------------------------------------------------------
+
+Magit is not responsible for the version control information that is
+being displayed in the mode-line and looks something like ‘Git-master’.
+The built-in "Version Control" package, also known as "VC", updates that
+information, and can be told to do so more often:
+
+     (setq auto-revert-check-vc-info t)
+
+   But doing so isn’t good for performance.  For more (overly
+optimistic) information see *note (emacs)VC Mode Line::.
+
+   If you don’t really care about seeing that information in the
+mode-line, but just don’t want to see _incorrect_ information, then
+consider disabling VC when using Git:
+
+     (setq vc-handled-backends (delq 'Git vc-handled-backends))
+
+   Or to disable it completely:
+
+     (setq vc-handled-backends nil)
+
+
+File: magit.info,  Node: A branch and tag sharing the same name breaks SOMETHING,  Next: My Git hooks work on the command-line but not inside Magit,  Prev: The mode-line information isn't always up-to-date,  Up: FAQ - Issues and Errors
+
+A.2.10 A branch and tag sharing the same name breaks SOMETHING
+--------------------------------------------------------------
+
+Or more generally, ambiguous refnames break SOMETHING.
+
+   Magit assumes that refs are named non-ambiguously across the
+"refs/heads/", "refs/tags/", and "refs/remotes/" namespaces (i.e., all
+the names remain unique when those prefixes are stripped).  We consider
+ambiguous refnames unsupported and recommend that you use a
+non-ambiguous naming scheme.  However, if you do work with a repository
+that has ambiguous refnames, please report any issues you encounter so
+that we can investigate whether there is a simple fix.
+
+
+File: magit.info,  Node: My Git hooks work on the command-line but not inside Magit,  Prev: A branch and tag sharing the same name breaks SOMETHING,  Up: FAQ - Issues and Errors
+
+A.2.11 My Git hooks work on the command-line but not inside Magit
+-----------------------------------------------------------------
+
+When Magit calls ‘git’ it adds a few global arguments including
+‘--literal-pathspecs’ and the ‘git’ process started by Magit then passes
+that setting on to other ‘git’ process it starts itself.  It does so by
+setting the environment variable ‘GIT_LITERAL_PATHSPECS’, not by calling
+subprocesses with the ‘--literal-pathspecs’.  You can therefore override
+this setting in hook scripts using ‘unset GIT_LITERAL_PATHSPECS’.
+
+
+File: magit.info,  Node: Debugging Tools,  Next: Keystroke Index,  Prev: FAQ,  Up: Top
+
+B Debugging Tools
+*****************
+
+Magit and its dependencies provide a few debugging tools, and we
+appreciate it very much if you use those tools before reporting an
+issue.  Please include all relevant output when reporting an issue.
+
+‘M-x magit-version’     (‘magit-version’)
+
+     This command shows the currently used versions of Magit, Git, and
+     Emacs in the echo area.  Non-interactively this just returns the
+     Magit version.
+
+‘M-x magit-emacs-Q-command’     (‘magit-emacs-Q-command’)
+
+     This command shows a debugging shell command in the echo area and
+     adds it to the kill ring.  Paste that command into a shell an run
+     it.
+
+     This shell command starts ‘emacs’ with only ‘magit’ and its
+     dependencies loaded.  Neither your configuration nor other
+     installed packages are loaded.  This makes it easier to determine
+     whether some issue lays with Magit or something else.
+
+     If you run Magit from its Git repository, then you should be able
+     to use ‘make emacs-Q’ instead of the output of this command.
+
+‘M-x magit-debug-git-executable’     (‘magit-debug-git-executable’)
+
+     This command displays a buffer containing information about the
+     available and used ‘git’ executable(s), and can be useful when
+     investigating ‘exec-path’ issues.
+
+     Also see *note Git Executable::.
+
+‘M-x with-editor-debug’     (‘with-editor-debug’)
+
+     This command displays a buffer containing information about the
+     available and used ‘git’ executable(s), and can be useful when
+     investigating why Magit (or rather ‘with-editor’) cannot find an
+     appropriate ‘emacsclient’ executable.
+
+     Also see *note (with-editor)Debugging::.
+
+   Please also see the *note FAQ::.
+
+
+File: magit.info,  Node: Keystroke Index,  Next: Command Index,  Prev: Debugging Tools,  Up: Top
+
+Appendix C Keystroke Index
+**************************
+
+
+* Menu:
+
+* !:                                     Running Git Manually.
+                                                              (line  12)
+* ! !:                                   Running Git Manually.
+                                                              (line  16)
+* ! a:                                   Running Git Manually.
+                                                              (line  57)
+* ! b:                                   Running Git Manually.
+                                                              (line  61)
+* ! g:                                   Running Git Manually.
+                                                              (line  65)
+* ! k:                                   Running Git Manually.
+                                                              (line  53)
+* ! p:                                   Running Git Manually.
+                                                              (line  24)
+* ! s:                                   Running Git Manually.
+                                                              (line  34)
+* ! S:                                   Running Git Manually.
+                                                              (line  39)
+* $:                                     Viewing Git Output.  (line  16)
+* %:                                     Worktree.            (line   8)
+* % b:                                   Worktree.            (line  13)
+* % c:                                   Worktree.            (line  17)
+* % g:                                   Worktree.            (line  33)
+* % k:                                   Worktree.            (line  28)
+* % p:                                   Worktree.            (line  21)
+* +:                                     Log Buffer.          (line  59)
+* + <1>:                                 Refreshing Diffs.    (line  68)
+* -:                                     Log Buffer.          (line  63)
+* - <1>:                                 Refreshing Diffs.    (line  64)
+* 0:                                     Refreshing Diffs.    (line  72)
+* 1:                                     Section Visibility.  (line  26)
+* 2:                                     Section Visibility.  (line  27)
+* 3:                                     Section Visibility.  (line  28)
+* 4:                                     Section Visibility.  (line  29)
+* =:                                     Log Buffer.          (line  53)
+* ^:                                     Section Movement.    (line  31)
+* a:                                     Applying.            (line  33)
+* A:                                     Cherry Picking.      (line   8)
+* A A:                                   Cherry Picking.      (line  16)
+* A a:                                   Cherry Picking.      (line  23)
+* A A <1>:                               Cherry Picking.      (line  89)
+* A a <1>:                               Cherry Picking.      (line  97)
+* A d:                                   Cherry Picking.      (line  53)
+* A h:                                   Cherry Picking.      (line  41)
+* A n:                                   Cherry Picking.      (line  64)
+* A s:                                   Cherry Picking.      (line  75)
+* A s <1>:                               Cherry Picking.      (line  93)
+* B:                                     Bisecting.           (line   8)
+* b:                                     Blaming.             (line  86)
+* b <1>:                                 The Branch Popup.    (line  12)
+* B B:                                   Bisecting.           (line  16)
+* B b:                                   Bisecting.           (line  31)
+* b b:                                   The Branch Popup.    (line  37)
+* b C:                                   The Branch Popup.    (line  29)
+* b c:                                   The Branch Popup.    (line  55)
+* B g:                                   Bisecting.           (line  36)
+* B k:                                   Bisecting.           (line  41)
+* b k:                                   The Branch Popup.    (line 240)
+* b l:                                   The Branch Popup.    (line  62)
+* b n:                                   The Branch Popup.    (line  45)
+* B r:                                   Bisecting.           (line  47)
+* b r:                                   The Branch Popup.    (line 246)
+* B s:                                   Bisecting.           (line  24)
+* b s:                                   The Branch Popup.    (line  85)
+* b x:                                   The Branch Popup.    (line 224)
+* b Y:                                   The Branch Popup.    (line 113)
+* b y:                                   The Branch Popup.    (line 218)
+* c:                                     Blaming.             (line 120)
+* c <1>:                                 Initiating a Commit. (line   8)
+* c <2>:                                 Editing Rebase Sequences.
+                                                              (line  72)
+* c a:                                   Initiating a Commit. (line  18)
+* c A:                                   Initiating a Commit. (line  66)
+* c c:                                   Initiating a Commit. (line  13)
+* c e:                                   Initiating a Commit. (line  22)
+* c f:                                   Initiating a Commit. (line  42)
+* c F:                                   Initiating a Commit. (line  50)
+* c s:                                   Initiating a Commit. (line  54)
+* c S:                                   Initiating a Commit. (line  62)
+* c w:                                   Initiating a Commit. (line  32)
+* C-<return>:                            Diff Buffer.         (line  48)
+* C-<tab>:                               Section Visibility.  (line  13)
+* C-c C-a:                               Editing Commit Messages.
+                                                              (line 128)
+* C-c C-b:                               Log Buffer.          (line  19)
+* C-c C-b <1>:                           Refreshing Diffs.    (line  90)
+* C-c C-c:                               Popup Buffers and Prefix Commands.
+                                                              (line  20)
+* C-c C-c <1>:                           Select from Log.     (line  20)
+* C-c C-c <2>:                           Editing Commit Messages.
+                                                              (line  19)
+* C-c C-c <3>:                           Editing Rebase Sequences.
+                                                              (line   6)
+* C-c C-d:                               Refreshing Diffs.    (line  80)
+* C-c C-d <1>:                           Editing Commit Messages.
+                                                              (line  57)
+* C-c C-e:                               Diff Buffer.         (line  74)
+* C-c C-f:                               Log Buffer.          (line  23)
+* C-c C-f <1>:                           Refreshing Diffs.    (line  94)
+* C-c C-i:                               Editing Commit Messages.
+                                                              (line 153)
+* C-c C-k:                               Select from Log.     (line  26)
+* C-c C-k <1>:                           Editing Commit Messages.
+                                                              (line  24)
+* C-c C-k <2>:                           Editing Rebase Sequences.
+                                                              (line  11)
+* C-c C-n:                               Log Buffer.          (line  27)
+* C-c C-o:                               Editing Commit Messages.
+                                                              (line 144)
+* C-c C-p:                               Editing Commit Messages.
+                                                              (line 148)
+* C-c C-r:                               Editing Commit Messages.
+                                                              (line 132)
+* C-c C-s:                               Editing Commit Messages.
+                                                              (line 136)
+* C-c C-t:                               Diff Buffer.         (line  70)
+* C-c C-t <1>:                           Editing Commit Messages.
+                                                              (line 140)
+* C-c C-w:                               Editing Commit Messages.
+                                                              (line  63)
+* C-c M-g:                               Minor Mode for Buffers Visiting Files.
+                                                              (line  19)
+* C-c M-g B:                             Minor Mode for Buffers Visiting Files.
+                                                              (line  80)
+* C-c M-g b:                             Minor Mode for Buffers Visiting Files.
+                                                              (line  86)
+* C-c M-g c:                             Minor Mode for Buffers Visiting Files.
+                                                              (line  33)
+* C-c M-g D:                             Minor Mode for Buffers Visiting Files.
+                                                              (line  39)
+* C-c M-g d:                             Minor Mode for Buffers Visiting Files.
+                                                              (line  47)
+* C-c M-g e:                             Minor Mode for Buffers Visiting Files.
+                                                              (line 102)
+* C-c M-g f:                             Minor Mode for Buffers Visiting Files.
+                                                              (line  96)
+* C-c M-g L:                             Minor Mode for Buffers Visiting Files.
+                                                              (line  57)
+* C-c M-g l:                             Minor Mode for Buffers Visiting Files.
+                                                              (line  64)
+* C-c M-g p:                             Minor Mode for Buffers Visiting Files.
+                                                              (line 112)
+* C-c M-g r:                             Minor Mode for Buffers Visiting Files.
+                                                              (line  91)
+* C-c M-g s:                             Minor Mode for Buffers Visiting Files.
+                                                              (line  24)
+* C-c M-g t:                             Minor Mode for Buffers Visiting Files.
+                                                              (line  71)
+* C-c M-g u:                             Minor Mode for Buffers Visiting Files.
+                                                              (line  28)
+* C-c M-s:                               Editing Commit Messages.
+                                                              (line  35)
+* C-w:                                   Common Commands.     (line  21)
+* C-x g:                                 Status Buffer.       (line  22)
+* C-x u:                                 Editing Rebase Sequences.
+                                                              (line  89)
+* d:                                     Diffing.             (line  20)
+* D:                                     Refreshing Diffs.    (line  11)
+* d c:                                   Diffing.             (line  67)
+* d d:                                   Diffing.             (line  25)
+* D f:                                   Refreshing Diffs.    (line  45)
+* D F:                                   Refreshing Diffs.    (line  50)
+* D g:                                   Refreshing Diffs.    (line  16)
+* d p:                                   Diffing.             (line  59)
+* d r:                                   Diffing.             (line  29)
+* D r:                                   Refreshing Diffs.    (line  40)
+* d s:                                   Diffing.             (line  49)
+* D s:                                   Refreshing Diffs.    (line  21)
+* d t:                                   Diffing.             (line  72)
+* D t:                                   Refreshing Diffs.    (line  36)
+* d u:                                   Diffing.             (line  55)
+* d w:                                   Diffing.             (line  43)
+* D w:                                   Refreshing Diffs.    (line  28)
+* DEL:                                   Log Buffer.          (line  43)
+* DEL <1>:                               Diff Buffer.         (line 103)
+* DEL <2>:                               Blaming.             (line  73)
+* DEL <3>:                               Editing Rebase Sequences.
+                                                              (line  28)
+* e:                                     Ediffing.            (line   9)
+* E:                                     Ediffing.            (line  21)
+* e <1>:                                 Editing Rebase Sequences.
+                                                              (line  55)
+* E c:                                   Ediffing.            (line  65)
+* E i:                                   Ediffing.            (line  57)
+* E m:                                   Ediffing.            (line  35)
+* E r:                                   Ediffing.            (line  26)
+* E s:                                   Ediffing.            (line  48)
+* E u:                                   Ediffing.            (line  53)
+* E w:                                   Ediffing.            (line  61)
+* E z:                                   Ediffing.            (line  69)
+* f:                                     Editing Rebase Sequences.
+                                                              (line  63)
+* f <1>:                                 Fetching.            (line  11)
+* F:                                     Pulling.             (line  11)
+* f a:                                   Fetching.            (line  38)
+* f e:                                   Fetching.            (line  24)
+* F e:                                   Pulling.             (line  24)
+* f m:                                   Fetching.            (line  42)
+* f o:                                   Fetching.            (line  28)
+* f p:                                   Fetching.            (line  16)
+* F p:                                   Pulling.             (line  16)
+* f r:                                   Fetching.            (line  33)
+* f u:                                   Fetching.            (line  20)
+* F u:                                   Pulling.             (line  20)
+* g:                                     Automatic Refreshing of Magit Buffers.
+                                                              (line  22)
+* G:                                     Automatic Refreshing of Magit Buffers.
+                                                              (line  31)
+* j:                                     Diff Buffer.         (line  93)
+* k:                                     Viewing Git Output.  (line  24)
+* k <1>:                                 Applying.            (line  40)
+* k <2>:                                 Editing Rebase Sequences.
+                                                              (line  68)
+* k <3>:                                 Stashing.            (line  95)
+* l:                                     Logging.             (line  28)
+* L:                                     Refreshing Logs.     (line  11)
+* L <1>:                                 Log Buffer.          (line   6)
+* L <2>:                                 Log Margin.          (line  47)
+* l a:                                   Logging.             (line  58)
+* l b:                                   Logging.             (line  54)
+* L d:                                   Log Margin.          (line  64)
+* L g:                                   Refreshing Logs.     (line  16)
+* l h:                                   Logging.             (line  46)
+* l H:                                   Reflog.              (line  19)
+* l l:                                   Logging.             (line  33)
+* l L:                                   Logging.             (line  50)
+* L L:                                   Log Margin.          (line  56)
+* L l:                                   Log Margin.          (line  60)
+* l o:                                   Logging.             (line  39)
+* l O:                                   Reflog.              (line  15)
+* l r:                                   Reflog.              (line  11)
+* L s:                                   Refreshing Logs.     (line  21)
+* L t:                                   Refreshing Logs.     (line  36)
+* L w:                                   Refreshing Logs.     (line  28)
+* m:                                     Merging.             (line   9)
+* M:                                     The Remote Popup.    (line  13)
+* m a:                                   Merging.             (line  44)
+* m a <1>:                               Merging.             (line  94)
+* M a:                                   The Remote Popup.    (line  35)
+* M C:                                   The Remote Popup.    (line  26)
+* m e:                                   Merging.             (line  30)
+* m i:                                   Merging.             (line  57)
+* M k:                                   The Remote Popup.    (line  50)
+* m m:                                   Merging.             (line  17)
+* m m <1>:                               Merging.             (line  88)
+* m n:                                   Merging.             (line  37)
+* m p:                                   Merging.             (line  80)
+* M p:                                   The Remote Popup.    (line  54)
+* M P:                                   The Remote Popup.    (line  59)
+* M r:                                   The Remote Popup.    (line  40)
+* m s:                                   Merging.             (line  71)
+* M u:                                   The Remote Popup.    (line  45)
+* M-1:                                   Section Visibility.  (line  33)
+* M-2:                                   Section Visibility.  (line  34)
+* M-3:                                   Section Visibility.  (line  35)
+* M-4:                                   Section Visibility.  (line  36)
+* M-<tab>:                               Section Visibility.  (line  17)
+* M-n:                                   Section Movement.    (line  26)
+* M-n <1>:                               Editing Commit Messages.
+                                                              (line  45)
+* M-n <2>:                               Editing Rebase Sequences.
+                                                              (line  47)
+* M-p:                                   Section Movement.    (line  20)
+* M-p <1>:                               Editing Commit Messages.
+                                                              (line  39)
+* M-p <2>:                               Editing Rebase Sequences.
+                                                              (line  43)
+* M-w:                                   Blaming.             (line 112)
+* M-w <1>:                               Common Commands.     (line  10)
+* M-x magit-clone:                       Repository Setup.    (line  16)
+* M-x magit-debug-git-executable:        Git Executable.      (line  45)
+* M-x magit-debug-git-executable <1>:    Debugging Tools.     (line  30)
+* M-x magit-describe-section:            Section Types and Values.
+                                                              (line  13)
+* M-x magit-describe-section <1>:        Matching Sections.   (line   6)
+* M-x magit-emacs-Q-command:             Debugging Tools.     (line  16)
+* M-x magit-find-file:                   Visiting Blobs.      (line   6)
+* M-x magit-find-file-other-window:      Visiting Blobs.      (line  11)
+* M-x magit-init:                        Repository Setup.    (line   6)
+* M-x magit-reset-index:                 Staging and Unstaging.
+                                                              (line  87)
+* M-x magit-reverse-in-index:            Staging and Unstaging.
+                                                              (line  62)
+* M-x magit-stage-file:                  Staging from File-Visiting Buffers.
+                                                              (line  10)
+* M-x magit-toggle-buffer-lock:          Modes and Buffers.   (line  17)
+* M-x magit-unstage-file:                Staging from File-Visiting Buffers.
+                                                              (line  18)
+* M-x magit-version:                     Git Executable.      (line  17)
+* M-x magit-version <1>:                 Debugging Tools.     (line  10)
+* M-x magit-wip-commit:                  Wip Modes.           (line 129)
+* M-x with-editor-debug:                 Debugging Tools.     (line  38)
+* n:                                     Section Movement.    (line  16)
+* n <1>:                                 Blaming.             (line  91)
+* N:                                     Blaming.             (line  95)
+* n <2>:                                 Editing Rebase Sequences.
+                                                              (line  39)
+* n <3>:                                 Minor Mode for Buffers Visiting Blobs.
+                                                              (line  16)
+* o:                                     Submodule Popup.     (line   6)
+* O:                                     Subtree.             (line   8)
+* o a:                                   Submodule Popup.     (line  19)
+* O a:                                   Subtree.             (line  20)
+* O c:                                   Subtree.             (line  24)
+* o d:                                   Submodule Popup.     (line  49)
+* o f:                                   Submodule Popup.     (line  57)
+* O f:                                   Subtree.             (line  32)
+* o l:                                   Submodule Popup.     (line  53)
+* O m:                                   Subtree.             (line  28)
+* o p:                                   Submodule Popup.     (line  33)
+* O p:                                   Subtree.             (line  36)
+* o r:                                   Submodule Popup.     (line  26)
+* o s:                                   Submodule Popup.     (line  43)
+* O s:                                   Subtree.             (line  41)
+* o u:                                   Submodule Popup.     (line  38)
+* p:                                     Section Movement.    (line  10)
+* p <1>:                                 Blaming.             (line  99)
+* P:                                     Blaming.             (line 103)
+* p <2>:                                 Editing Rebase Sequences.
+                                                              (line  35)
+* P <1>:                                 Pushing.             (line  11)
+* p <3>:                                 Minor Mode for Buffers Visiting Blobs.
+                                                              (line  12)
+* P e:                                   Pushing.             (line  35)
+* P m:                                   Pushing.             (line  53)
+* P o:                                   Pushing.             (line  39)
+* P p:                                   Pushing.             (line  16)
+* P r:                                   Pushing.             (line  44)
+* P t:                                   Pushing.             (line  59)
+* P T:                                   Pushing.             (line  65)
+* P u:                                   Pushing.             (line  26)
+* q:                                     Quitting Windows.    (line   6)
+* q <1>:                                 Log Buffer.          (line  12)
+* q <2>:                                 Blaming.             (line 107)
+* q <3>:                                 Minor Mode for Buffers Visiting Blobs.
+                                                              (line  20)
+* r:                                     Rebasing.            (line   9)
+* r <1>:                                 Editing Rebase Sequences.
+                                                              (line  51)
+* r a:                                   Rebasing.            (line 107)
+* r e:                                   Rebasing.            (line  33)
+* r e <1>:                               Rebasing.            (line 103)
+* r f:                                   Rebasing.            (line  73)
+* r i:                                   Rebasing.            (line  69)
+* r k:                                   Rebasing.            (line  85)
+* r m:                                   Rebasing.            (line  77)
+* r p:                                   Rebasing.            (line  24)
+* r r:                                   Rebasing.            (line  92)
+* r s:                                   Rebasing.            (line  39)
+* r s <1>:                               Rebasing.            (line  99)
+* r u:                                   Rebasing.            (line  29)
+* r w:                                   Rebasing.            (line  81)
+* RET:                                   Diff Buffer.         (line   8)
+* RET <1>:                               References Buffer.   (line 166)
+* RET <2>:                               Blaming.             (line  59)
+* RET <3>:                               Editing Rebase Sequences.
+                                                              (line  16)
+* s:                                     Staging and Unstaging.
+                                                              (line  28)
+* S:                                     Staging and Unstaging.
+                                                              (line  36)
+* s <1>:                                 Editing Rebase Sequences.
+                                                              (line  59)
+* S-<tab>:                               Section Visibility.  (line  22)
+* SPC:                                   Log Buffer.          (line  33)
+* SPC <1>:                               Diff Buffer.         (line  99)
+* SPC <2>:                               Blaming.             (line  63)
+* SPC <3>:                               Editing Rebase Sequences.
+                                                              (line  21)
+* t:                                     Tagging.             (line   8)
+* T:                                     Notes.               (line   8)
+* T a:                                   Notes.               (line  51)
+* T c:                                   Notes.               (line  46)
+* t k:                                   Tagging.             (line  18)
+* T m:                                   Notes.               (line  37)
+* t p:                                   Tagging.             (line  24)
+* T p:                                   Notes.               (line  29)
+* T r:                                   Notes.               (line  21)
+* t t:                                   Tagging.             (line  13)
+* T T:                                   Notes.               (line  13)
+* TAB:                                   Section Visibility.  (line   9)
+* u:                                     Staging and Unstaging.
+                                                              (line  43)
+* U:                                     Staging and Unstaging.
+                                                              (line  52)
+* v:                                     Applying.            (line  44)
+* V:                                     Reverting.           (line   6)
+* V A:                                   Reverting.           (line  30)
+* V a:                                   Reverting.           (line  38)
+* V s:                                   Reverting.           (line  34)
+* V V:                                   Reverting.           (line  14)
+* V v:                                   Reverting.           (line  20)
+* W:                                     Creating and Sending Patches.
+                                                              (line   6)
+* w:                                     Applying Patches.    (line   8)
+* w a:                                   Applying Patches.    (line  34)
+* w a <1>:                               Applying Patches.    (line  42)
+* w a a:                                 Applying Patches.    (line  47)
+* w m:                                   Applying Patches.    (line  19)
+* W p:                                   Creating and Sending Patches.
+                                                              (line  11)
+* W r:                                   Creating and Sending Patches.
+                                                              (line  17)
+* w s:                                   Applying Patches.    (line  30)
+* w w:                                   Applying Patches.    (line  13)
+* w w <1>:                               Applying Patches.    (line  26)
+* x:                                     Editing Rebase Sequences.
+                                                              (line  76)
+* x <1>:                                 Resetting.           (line   8)
+* X f:                                   Resetting.           (line  37)
+* X h:                                   Resetting.           (line  25)
+* X i:                                   Resetting.           (line  30)
+* X m:                                   Resetting.           (line  14)
+* X s:                                   Resetting.           (line  19)
+* Y:                                     Cherries.            (line  17)
+* y:                                     References Buffer.   (line   6)
+* y <1>:                                 Editing Rebase Sequences.
+                                                              (line  85)
+* y c:                                   References Buffer.   (line  19)
+* y o:                                   References Buffer.   (line  24)
+* y y:                                   References Buffer.   (line  14)
+* z:                                     Stashing.            (line   8)
+* z a:                                   Stashing.            (line  58)
+* z b:                                   Stashing.            (line  80)
+* z B:                                   Stashing.            (line  85)
+* z f:                                   Stashing.            (line  91)
+* z i:                                   Stashing.            (line  20)
+* z I:                                   Stashing.            (line  46)
+* z k:                                   Stashing.            (line  71)
+* z l:                                   Stashing.            (line  99)
+* z p:                                   Stashing.            (line  64)
+* z v:                                   Stashing.            (line  76)
+* z w:                                   Stashing.            (line  25)
+* z W:                                   Stashing.            (line  51)
+* z x:                                   Stashing.            (line  32)
+* z z:                                   Stashing.            (line  13)
+* z Z:                                   Stashing.            (line  39)
+
+
+File: magit.info,  Node: Command Index,  Next: Function Index,  Prev: Keystroke Index,  Up: Top
+
+Appendix D Command Index
+************************
+
+
+* Menu:
+
+* auto-revert-mode:                      Automatic Reverting of File-Visiting Buffers.
+                                                              (line  62)
+* forward-line:                          Editing Rebase Sequences.
+                                                              (line  39)
+* git-commit-ack:                        Editing Commit Messages.
+                                                              (line 128)
+* git-commit-cc:                         Editing Commit Messages.
+                                                              (line 144)
+* git-commit-next-message:               Editing Commit Messages.
+                                                              (line  45)
+* git-commit-prev-message:               Editing Commit Messages.
+                                                              (line  39)
+* git-commit-reported:                   Editing Commit Messages.
+                                                              (line 148)
+* git-commit-review:                     Editing Commit Messages.
+                                                              (line 132)
+* git-commit-save-message:               Editing Commit Messages.
+                                                              (line  35)
+* git-commit-signoff:                    Editing Commit Messages.
+                                                              (line 136)
+* git-commit-suggested:                  Editing Commit Messages.
+                                                              (line 153)
+* git-commit-test:                       Editing Commit Messages.
+                                                              (line 140)
+* git-rebase-backward-line:              Editing Rebase Sequences.
+                                                              (line  35)
+* git-rebase-edit:                       Editing Rebase Sequences.
+                                                              (line  55)
+* git-rebase-exec:                       Editing Rebase Sequences.
+                                                              (line  76)
+* git-rebase-fixup:                      Editing Rebase Sequences.
+                                                              (line  63)
+* git-rebase-insert:                     Editing Rebase Sequences.
+                                                              (line  85)
+* git-rebase-kill-line:                  Editing Rebase Sequences.
+                                                              (line  68)
+* git-rebase-move-line-down:             Editing Rebase Sequences.
+                                                              (line  47)
+* git-rebase-move-line-up:               Editing Rebase Sequences.
+                                                              (line  43)
+* git-rebase-pick:                       Editing Rebase Sequences.
+                                                              (line  72)
+* git-rebase-reword:                     Editing Rebase Sequences.
+                                                              (line  51)
+* git-rebase-show-commit:                Editing Rebase Sequences.
+                                                              (line  16)
+* git-rebase-show-or-scroll-down:        Editing Rebase Sequences.
+                                                              (line  28)
+* git-rebase-show-or-scroll-up:          Editing Rebase Sequences.
+                                                              (line  21)
+* git-rebase-squash:                     Editing Rebase Sequences.
+                                                              (line  59)
+* git-rebase-undo:                       Editing Rebase Sequences.
+                                                              (line  89)
+* ido-enter-magit-status:                Status Buffer.       (line  47)
+* magit-am-abort:                        Applying Patches.    (line  34)
+* magit-am-apply-maildir:                Applying Patches.    (line  19)
+* magit-am-apply-patches:                Applying Patches.    (line  13)
+* magit-am-continue:                     Applying Patches.    (line  26)
+* magit-am-popup:                        Applying Patches.    (line   8)
+* magit-am-skip:                         Applying Patches.    (line  30)
+* magit-apply:                           Applying.            (line  33)
+* magit-bisect-bad:                      Bisecting.           (line  31)
+* magit-bisect-good:                     Bisecting.           (line  36)
+* magit-bisect-popup:                    Bisecting.           (line   8)
+* magit-bisect-reset:                    Bisecting.           (line  47)
+* magit-bisect-run:                      Bisecting.           (line  24)
+* magit-bisect-skip:                     Bisecting.           (line  41)
+* magit-bisect-start:                    Bisecting.           (line  16)
+* magit-blame:                           Blaming.             (line  17)
+* magit-blame <1>:                       Minor Mode for Buffers Visiting Files.
+                                                              (line  86)
+* magit-blame-copy-hash:                 Blaming.             (line 112)
+* magit-blame-cycle-style:               Blaming.             (line 120)
+* magit-blame-echo:                      Blaming.             (line  32)
+* magit-blame-next-chunk:                Blaming.             (line  91)
+* magit-blame-next-chunk-same-commit:    Blaming.             (line  95)
+* magit-blame-popup:                     Blaming.             (line  86)
+* magit-blame-popup <1>:                 Minor Mode for Buffers Visiting Files.
+                                                              (line  80)
+* magit-blame-previous-chunk:            Blaming.             (line  99)
+* magit-blame-previous-chunk-same-commit: Blaming.            (line 103)
+* magit-blame-quit:                      Blaming.             (line 107)
+* magit-blame-removal:                   Blaming.             (line  38)
+* magit-blame-removal <1>:               Minor Mode for Buffers Visiting Files.
+                                                              (line  91)
+* magit-blame-reverse:                   Blaming.             (line  46)
+* magit-blame-reverse <1>:               Minor Mode for Buffers Visiting Files.
+                                                              (line  96)
+* magit-blob-next:                       Minor Mode for Buffers Visiting Blobs.
+                                                              (line  16)
+* magit-blob-previous:                   Minor Mode for Buffers Visiting Files.
+                                                              (line 112)
+* magit-blob-previous <1>:               Minor Mode for Buffers Visiting Blobs.
+                                                              (line  12)
+* magit-branch:                          The Branch Popup.    (line  45)
+* magit-branch-and-checkout:             The Branch Popup.    (line  55)
+* magit-branch-checkout:                 The Branch Popup.    (line  62)
+* magit-branch-config-popup:             The Branch Popup.    (line  29)
+* magit-branch-config-popup <1>:         The Branch Config Popup.
+                                                              (line   6)
+* magit-branch-delete:                   The Branch Popup.    (line 240)
+* magit-branch-or-checkout:              The Branch Popup.    (line 350)
+* magit-branch-orphan:                   The Branch Popup.    (line 345)
+* magit-branch-popup:                    The Branch Popup.    (line  12)
+* magit-branch-pull-request:             The Branch Popup.    (line 113)
+* magit-branch-rename:                   The Branch Popup.    (line 246)
+* magit-branch-reset:                    The Branch Popup.    (line 224)
+* magit-branch-shelve:                   Auxillary Branch Commands.
+                                                              (line   8)
+* magit-branch-spinoff:                  The Branch Popup.    (line  85)
+* magit-branch-unshelve:                 Auxillary Branch Commands.
+                                                              (line  19)
+* magit-checkout:                        The Branch Popup.    (line  37)
+* magit-checkout-pull-request:           The Branch Popup.    (line 218)
+* magit-cherry:                          Cherries.            (line  17)
+* magit-cherry-apply:                    Cherry Picking.      (line  23)
+* magit-cherry-donate:                   Cherry Picking.      (line  53)
+* magit-cherry-harvest:                  Cherry Picking.      (line  41)
+* magit-cherry-pick:                     Cherry Picking.      (line  16)
+* magit-cherry-pick-popup:               Cherry Picking.      (line   8)
+* magit-cherry-spinoff:                  Cherry Picking.      (line  75)
+* magit-cherry-spinout:                  Cherry Picking.      (line  64)
+* magit-clone:                           Repository Setup.    (line  16)
+* magit-commit:                          Initiating a Commit. (line  13)
+* magit-commit-amend:                    Initiating a Commit. (line  18)
+* magit-commit-augment:                  Initiating a Commit. (line  66)
+* magit-commit-extend:                   Initiating a Commit. (line  22)
+* magit-commit-fixup:                    Initiating a Commit. (line  42)
+* magit-commit-instant-fixup:            Initiating a Commit. (line  50)
+* magit-commit-instant-squash:           Initiating a Commit. (line  62)
+* magit-commit-popup:                    Initiating a Commit. (line   8)
+* magit-commit-popup <1>:                Minor Mode for Buffers Visiting Files.
+                                                              (line  33)
+* magit-commit-reword:                   Initiating a Commit. (line  32)
+* magit-commit-squash:                   Initiating a Commit. (line  54)
+* magit-copy-buffer-revision:            Common Commands.     (line  21)
+* magit-copy-section-value:              Common Commands.     (line  10)
+* magit-cycle-margin-style:              Log Margin.          (line  60)
+* magit-debug-git-executable:            Git Executable.      (line  45)
+* magit-debug-git-executable <1>:        Debugging Tools.     (line  30)
+* magit-describe-section:                Section Types and Values.
+                                                              (line  13)
+* magit-describe-section <1>:            Matching Sections.   (line   6)
+* magit-diff:                            Diffing.             (line  29)
+* magit-diff-buffer-file:                Minor Mode for Buffers Visiting Files.
+                                                              (line  47)
+* magit-diff-buffer-file-popup:          Minor Mode for Buffers Visiting Files.
+                                                              (line  39)
+* magit-diff-default-context:            Refreshing Diffs.    (line  72)
+* magit-diff-dwim:                       Diffing.             (line  25)
+* magit-diff-edit-hunk-commit:           Diff Buffer.         (line  74)
+* magit-diff-flip-revs:                  Refreshing Diffs.    (line  45)
+* magit-diff-less-context:               Refreshing Diffs.    (line  64)
+* magit-diff-more-context:               Refreshing Diffs.    (line  68)
+* magit-diff-paths:                      Diffing.             (line  59)
+* magit-diff-popup:                      Diffing.             (line  20)
+* magit-diff-refresh:                    Refreshing Diffs.    (line  16)
+* magit-diff-refresh-popup:              Refreshing Diffs.    (line  11)
+* magit-diff-save-default-arguments:     Refreshing Diffs.    (line  28)
+* magit-diff-set-default-arguments:      Refreshing Diffs.    (line  21)
+* magit-diff-show-or-scroll-down:        Log Buffer.          (line  43)
+* magit-diff-show-or-scroll-down <1>:    Blaming.             (line  73)
+* magit-diff-show-or-scroll-up:          Log Buffer.          (line  33)
+* magit-diff-show-or-scroll-up <1>:      Blaming.             (line  63)
+* magit-diff-staged:                     Diffing.             (line  49)
+* magit-diff-switch-range-type:          Refreshing Diffs.    (line  40)
+* magit-diff-toggle-file-filter:         Refreshing Diffs.    (line  50)
+* magit-diff-toggle-refine-hunk:         Refreshing Diffs.    (line  36)
+* magit-diff-trace-definition:           Diff Buffer.         (line  70)
+* magit-diff-unstaged:                   Diffing.             (line  55)
+* magit-diff-visit-file:                 Diff Buffer.         (line   8)
+* magit-diff-visit-file-other-window:    Diff Buffer.         (line  65)
+* magit-diff-visit-file-worktree:        Diff Buffer.         (line  48)
+* magit-diff-while-committing:           Refreshing Diffs.    (line  80)
+* magit-diff-while-committing <1>:       Editing Commit Messages.
+                                                              (line  57)
+* magit-diff-working-tree:               Diffing.             (line  43)
+* magit-discard:                         Applying.            (line  40)
+* magit-dispatch-popup:                  Popup Buffers and Prefix Commands.
+                                                              (line  20)
+* magit-ediff-compare:                   Ediffing.            (line  26)
+* magit-ediff-dwim:                      Ediffing.            (line   9)
+* magit-ediff-popup:                     Ediffing.            (line  21)
+* magit-ediff-resolve:                   Ediffing.            (line  35)
+* magit-ediff-show-commit:               Ediffing.            (line  65)
+* magit-ediff-show-staged:               Ediffing.            (line  57)
+* magit-ediff-show-stash:                Ediffing.            (line  69)
+* magit-ediff-show-unstaged:             Ediffing.            (line  53)
+* magit-ediff-show-working-tree:         Ediffing.            (line  61)
+* magit-ediff-stage:                     Ediffing.            (line  48)
+* magit-edit-line-commit:                Minor Mode for Buffers Visiting Files.
+                                                              (line 102)
+* magit-emacs-Q-command:                 Debugging Tools.     (line  16)
+* magit-fetch:                           Fetching.            (line  24)
+* magit-fetch-all:                       Fetching.            (line  38)
+* magit-fetch-branch:                    Fetching.            (line  28)
+* magit-fetch-from-pushremote:           Fetching.            (line  16)
+* magit-fetch-from-upstream:             Fetching.            (line  20)
+* magit-fetch-modules:                   Submodule Popup.     (line  57)
+* magit-fetch-popup:                     Fetching.            (line  11)
+* magit-fetch-refspec:                   Fetching.            (line  33)
+* magit-file-checkout:                   Resetting.           (line  37)
+* magit-file-checkout <1>:               Minor Mode for Buffers Visiting Files.
+                                                              (line 131)
+* magit-file-delete:                     Minor Mode for Buffers Visiting Files.
+                                                              (line 123)
+* magit-file-popup:                      Minor Mode for Buffers Visiting Files.
+                                                              (line  19)
+* magit-file-rename:                     Minor Mode for Buffers Visiting Files.
+                                                              (line 119)
+* magit-file-untrack:                    Minor Mode for Buffers Visiting Files.
+                                                              (line 127)
+* magit-find-file:                       Visiting Blobs.      (line   6)
+* magit-find-file-other-window:          Visiting Blobs.      (line  11)
+* magit-format-patch:                    Creating and Sending Patches.
+                                                              (line  11)
+* magit-git-command:                     Running Git Manually.
+                                                              (line  24)
+* magit-git-command-topdir:              Running Git Manually.
+                                                              (line  16)
+* magit-go-backward:                     Log Buffer.          (line  19)
+* magit-go-backward <1>:                 Refreshing Diffs.    (line  90)
+* magit-go-forward:                      Log Buffer.          (line  23)
+* magit-go-forward <1>:                  Refreshing Diffs.    (line  94)
+* magit-init:                            Repository Setup.    (line   6)
+* magit-jump-to-diffstat-or-diff:        Diff Buffer.         (line  93)
+* magit-kill-this-buffer:                Minor Mode for Buffers Visiting Blobs.
+                                                              (line  20)
+* magit-list-repositories:               Repository List.     (line   6)
+* magit-list-submodules:                 Listing Submodules.  (line  13)
+* magit-list-submodules <1>:             Submodule Popup.     (line  53)
+* magit-log:                             Logging.             (line  39)
+* magit-log-all:                         Logging.             (line  58)
+* magit-log-all-branches:                Logging.             (line  54)
+* magit-log-branches:                    Logging.             (line  50)
+* magit-log-buffer-file:                 Minor Mode for Buffers Visiting Files.
+                                                              (line  64)
+* magit-log-buffer-file-popup:           Minor Mode for Buffers Visiting Files.
+                                                              (line  57)
+* magit-log-bury-buffer:                 Log Buffer.          (line  12)
+* magit-log-current:                     Logging.             (line  33)
+* magit-log-double-commit-limit:         Log Buffer.          (line  59)
+* magit-log-half-commit-limit:           Log Buffer.          (line  63)
+* magit-log-head:                        Logging.             (line  46)
+* magit-log-move-to-parent:              Log Buffer.          (line  27)
+* magit-log-popup:                       Logging.             (line  28)
+* magit-log-refresh:                     Refreshing Logs.     (line  16)
+* magit-log-refresh-popup:               Refreshing Logs.     (line  11)
+* magit-log-refresh-popup <1>:           Log Buffer.          (line   6)
+* magit-log-save-default-arguments:      Refreshing Logs.     (line  28)
+* magit-log-select-pick:                 Select from Log.     (line  20)
+* magit-log-select-quit:                 Select from Log.     (line  26)
+* magit-log-set-default-arguments:       Refreshing Logs.     (line  21)
+* magit-log-toggle-commit-limit:         Log Buffer.          (line  53)
+* magit-log-trace-definition:            Minor Mode for Buffers Visiting Files.
+                                                              (line  71)
+* magit-margin-popup:                    Log Margin.          (line  47)
+* magit-merge:                           Merging.             (line  17)
+* magit-merge <1>:                       Merging.             (line  88)
+* magit-merge-abort:                     Merging.             (line  94)
+* magit-merge-absorb:                    Merging.             (line  44)
+* magit-merge-editmsg:                   Merging.             (line  30)
+* magit-merge-into:                      Merging.             (line  57)
+* magit-merge-nocommit:                  Merging.             (line  37)
+* magit-merge-popup:                     Merging.             (line   9)
+* magit-merge-preview:                   Merging.             (line  80)
+* magit-merge-squash:                    Merging.             (line  71)
+* magit-mode-bury-buffer:                Quitting Windows.    (line   6)
+* magit-notes-edit:                      Notes.               (line  13)
+* magit-notes-merge:                     Notes.               (line  37)
+* magit-notes-merge-abort:               Notes.               (line  51)
+* magit-notes-merge-commit:              Notes.               (line  46)
+* magit-notes-popup:                     Notes.               (line   8)
+* magit-notes-prune:                     Notes.               (line  29)
+* magit-notes-remove:                    Notes.               (line  21)
+* magit-patch-apply:                     Applying Patches.    (line  47)
+* magit-patch-apply-popup:               Applying Patches.    (line  42)
+* magit-patch-popup:                     Creating and Sending Patches.
+                                                              (line   6)
+* magit-pop-revision-stack:              Editing Commit Messages.
+                                                              (line  63)
+* magit-process:                         Viewing Git Output.  (line  16)
+* magit-process-kill:                    Viewing Git Output.  (line  24)
+* magit-pull:                            Pulling.             (line  24)
+* magit-pull-from-pushremote:            Pulling.             (line  16)
+* magit-pull-from-upstream:              Pulling.             (line  20)
+* magit-pull-popup:                      Pulling.             (line  11)
+* magit-push:                            Pushing.             (line  39)
+* magit-push-current:                    Pushing.             (line  35)
+* magit-push-current-to-pushremote:      Pushing.             (line  16)
+* magit-push-current-to-upstream:        Pushing.             (line  26)
+* magit-push-implicitly args:            Pushing.             (line  73)
+* magit-push-matching:                   Pushing.             (line  53)
+* magit-push-popup:                      Pushing.             (line  11)
+* magit-push-refspecs:                   Pushing.             (line  44)
+* magit-push-tag:                        Pushing.             (line  65)
+* magit-push-tags:                       Pushing.             (line  59)
+* magit-push-to-remote remote args:      Pushing.             (line  84)
+* magit-rebase:                          Rebasing.            (line  33)
+* magit-rebase-abort:                    Rebasing.            (line 107)
+* magit-rebase-autosquash:               Rebasing.            (line  73)
+* magit-rebase-continue:                 Rebasing.            (line  92)
+* magit-rebase-edit:                     Rebasing.            (line 103)
+* magit-rebase-edit-commit:              Rebasing.            (line  77)
+* magit-rebase-interactive:              Rebasing.            (line  69)
+* magit-rebase-onto-pushremote:          Rebasing.            (line  24)
+* magit-rebase-onto-upstream:            Rebasing.            (line  29)
+* magit-rebase-popup:                    Rebasing.            (line   9)
+* magit-rebase-remove-commit:            Rebasing.            (line  85)
+* magit-rebase-reword-commit:            Rebasing.            (line  81)
+* magit-rebase-skip:                     Rebasing.            (line  99)
+* magit-rebase-subset:                   Rebasing.            (line  39)
+* magit-reflog-current:                  Reflog.              (line  11)
+* magit-reflog-head:                     Reflog.              (line  19)
+* magit-reflog-other:                    Reflog.              (line  15)
+* magit-refresh:                         Automatic Refreshing of Magit Buffers.
+                                                              (line  22)
+* magit-refresh-all:                     Automatic Refreshing of Magit Buffers.
+                                                              (line  31)
+* magit-remote-add:                      The Remote Popup.    (line  35)
+* magit-remote-config-popup:             The Remote Popup.    (line  26)
+* magit-remote-config-popup <1>:         The Remote Config Popup.
+                                                              (line   6)
+* magit-remote-popup:                    The Remote Popup.    (line  13)
+* magit-remote-prune:                    The Remote Popup.    (line  54)
+* magit-remote-prune-refspecs:           The Remote Popup.    (line  59)
+* magit-remote-remove:                   The Remote Popup.    (line  50)
+* magit-remote-rename:                   The Remote Popup.    (line  40)
+* magit-remote-set-url:                  The Remote Popup.    (line  45)
+* magit-request-pull:                    Creating and Sending Patches.
+                                                              (line  17)
+* magit-reset:                           Resetting.           (line   8)
+* magit-reset-hard:                      Resetting.           (line  25)
+* magit-reset-head:                      Resetting.           (line  14)
+* magit-reset-index:                     Staging and Unstaging.
+                                                              (line  87)
+* magit-reset-index <1>:                 Resetting.           (line  30)
+* magit-reset-soft:                      Resetting.           (line  19)
+* magit-reverse:                         Applying.            (line  44)
+* magit-reverse-in-index:                Staging and Unstaging.
+                                                              (line  62)
+* magit-revert:                          Reverting.           (line  14)
+* magit-revert-no-commit:                Reverting.           (line  20)
+* magit-revert-popup:                    Reverting.           (line   6)
+* magit-run-git-gui:                     Running Git Manually.
+                                                              (line  65)
+* magit-run-gitk:                        Running Git Manually.
+                                                              (line  53)
+* magit-run-gitk-all:                    Running Git Manually.
+                                                              (line  57)
+* magit-run-gitk-branches:               Running Git Manually.
+                                                              (line  61)
+* magit-run-popup:                       Running Git Manually.
+                                                              (line  12)
+* magit-section-backward:                Section Movement.    (line  10)
+* magit-section-backward-siblings:       Section Movement.    (line  20)
+* magit-section-cycle:                   Section Visibility.  (line  13)
+* magit-section-cycle-diffs:             Section Visibility.  (line  17)
+* magit-section-cycle-global:            Section Visibility.  (line  22)
+* magit-section-forward:                 Section Movement.    (line  16)
+* magit-section-forward-siblings:        Section Movement.    (line  26)
+* magit-section-hide:                    Section Visibility.  (line  49)
+* magit-section-hide-children:           Section Visibility.  (line  64)
+* magit-section-show:                    Section Visibility.  (line  45)
+* magit-section-show-children:           Section Visibility.  (line  58)
+* magit-section-show-headings:           Section Visibility.  (line  53)
+* magit-section-show-level-1:            Section Visibility.  (line  26)
+* magit-section-show-level-1-all:        Section Visibility.  (line  33)
+* magit-section-show-level-2:            Section Visibility.  (line  27)
+* magit-section-show-level-2-all:        Section Visibility.  (line  34)
+* magit-section-show-level-3:            Section Visibility.  (line  28)
+* magit-section-show-level-3-all:        Section Visibility.  (line  35)
+* magit-section-show-level-4:            Section Visibility.  (line  29)
+* magit-section-show-level-4-all:        Section Visibility.  (line  36)
+* magit-section-toggle:                  Section Visibility.  (line   9)
+* magit-section-toggle-children:         Section Visibility.  (line  68)
+* magit-section-up:                      Section Movement.    (line  31)
+* magit-sequence-abort:                  Cherry Picking.      (line  97)
+* magit-sequence-abort <1>:              Reverting.           (line  38)
+* magit-sequence-continue:               Cherry Picking.      (line  89)
+* magit-sequence-continue <1>:           Reverting.           (line  30)
+* magit-sequence-skip:                   Cherry Picking.      (line  93)
+* magit-sequence-skip <1>:               Reverting.           (line  34)
+* magit-shell-command:                   Running Git Manually.
+                                                              (line  39)
+* magit-shell-command-topdir:            Running Git Manually.
+                                                              (line  34)
+* magit-show-commit:                     Diffing.             (line  67)
+* magit-show-commit <1>:                 Blaming.             (line  59)
+* magit-show-refs:                       References Buffer.   (line  24)
+* magit-show-refs-current:               References Buffer.   (line  19)
+* magit-show-refs-head:                  References Buffer.   (line  14)
+* magit-show-refs-popup:                 References Buffer.   (line   6)
+* magit-snapshot:                        Stashing.            (line  39)
+* magit-snapshot-index:                  Stashing.            (line  46)
+* magit-snapshot-worktree:               Stashing.            (line  51)
+* magit-stage:                           Staging and Unstaging.
+                                                              (line  28)
+* magit-stage-file:                      Staging from File-Visiting Buffers.
+                                                              (line  10)
+* magit-stage-file <1>:                  Minor Mode for Buffers Visiting Files.
+                                                              (line  24)
+* magit-stage-modified:                  Staging and Unstaging.
+                                                              (line  36)
+* magit-stash:                           Stashing.            (line  13)
+* magit-stash-apply:                     Stashing.            (line  58)
+* magit-stash-branch:                    Stashing.            (line  80)
+* magit-stash-branch-here:               Stashing.            (line  85)
+* magit-stash-clear:                     Stashing.            (line  95)
+* magit-stash-drop:                      Stashing.            (line  71)
+* magit-stash-format-patch:              Stashing.            (line  91)
+* magit-stash-index:                     Stashing.            (line  20)
+* magit-stash-keep-index:                Stashing.            (line  32)
+* magit-stash-list:                      Stashing.            (line  99)
+* magit-stash-pop:                       Stashing.            (line  64)
+* magit-stash-popup:                     Stashing.            (line   8)
+* magit-stash-show:                      Diffing.             (line  72)
+* magit-stash-show <1>:                  Stashing.            (line  76)
+* magit-stash-worktree:                  Stashing.            (line  25)
+* magit-status:                          Status Buffer.       (line  22)
+* magit-submodule-add:                   Submodule Popup.     (line  19)
+* magit-submodule-fetch:                 Fetching.            (line  42)
+* magit-submodule-populate:              Submodule Popup.     (line  33)
+* magit-submodule-popup:                 Submodule Popup.     (line   6)
+* magit-submodule-register:              Submodule Popup.     (line  26)
+* magit-submodule-synchronize:           Submodule Popup.     (line  43)
+* magit-submodule-unpopulate:            Submodule Popup.     (line  49)
+* magit-submodule-update:                Submodule Popup.     (line  38)
+* magit-subtree-add:                     Subtree.             (line  20)
+* magit-subtree-add-commit:              Subtree.             (line  24)
+* magit-subtree-merge:                   Subtree.             (line  28)
+* magit-subtree-pull:                    Subtree.             (line  32)
+* magit-subtree-push:                    Subtree.             (line  36)
+* magit-subtree-split:                   Subtree.             (line  41)
+* magit-tag:                             Tagging.             (line  13)
+* magit-tag-delete:                      Tagging.             (line  18)
+* magit-tag-popup:                       Tagging.             (line   8)
+* magit-tag-prune:                       Tagging.             (line  24)
+* magit-tag-release:                     Tagging.             (line  28)
+* magit-toggle-buffer-lock:              Modes and Buffers.   (line  17)
+* magit-toggle-margin:                   Refreshing Logs.     (line  36)
+* magit-toggle-margin <1>:               Log Margin.          (line  56)
+* magit-toggle-margin-details:           Log Margin.          (line  64)
+* magit-tree-popup:                      Subtree.             (line   8)
+* magit-unstage:                         Staging and Unstaging.
+                                                              (line  43)
+* magit-unstage-all:                     Staging and Unstaging.
+                                                              (line  52)
+* magit-unstage-file:                    Staging from File-Visiting Buffers.
+                                                              (line  18)
+* magit-unstage-file <1>:                Minor Mode for Buffers Visiting Files.
+                                                              (line  28)
+* magit-version:                         Git Executable.      (line  17)
+* magit-version <1>:                     Debugging Tools.     (line  10)
+* magit-visit-ref:                       References Buffer.   (line 166)
+* magit-wip-commit:                      Wip Modes.           (line 129)
+* magit-wip-log:                         Wip Modes.           (line  69)
+* magit-wip-log-current:                 Wip Modes.           (line  77)
+* magit-worktree-branch:                 Worktree.            (line  17)
+* magit-worktree-checkout:               Worktree.            (line  13)
+* magit-worktree-checkout-pull-request:  Worktree.            (line  21)
+* magit-worktree-delete:                 Worktree.            (line  28)
+* magit-worktree-popup:                  Worktree.            (line   8)
+* magit-worktree-status:                 Worktree.            (line  33)
+* scroll-down:                           Diff Buffer.         (line 103)
+* scroll-up:                             Diff Buffer.         (line  99)
+* with-editor-cancel:                    Editing Commit Messages.
+                                                              (line  24)
+* with-editor-cancel <1>:                Editing Rebase Sequences.
+                                                              (line  11)
+* with-editor-debug:                     Debugging Tools.     (line  38)
+* with-editor-finish:                    Editing Commit Messages.
+                                                              (line  19)
+* with-editor-finish <1>:                Editing Rebase Sequences.
+                                                              (line   6)
+
+
+File: magit.info,  Node: Function Index,  Next: Variable Index,  Prev: Command Index,  Up: Top
+
+Appendix E Function Index
+*************************
+
+
+* Menu:
+
+* auto-revert-mode:                      Automatic Reverting of File-Visiting Buffers.
+                                                              (line  62)
+* git-commit-check-style-conventions:    Editing Commit Messages.
+                                                              (line 247)
+* git-commit-propertize-diff:            Editing Commit Messages.
+                                                              (line 206)
+* git-commit-save-message:               Editing Commit Messages.
+                                                              (line 187)
+* git-commit-setup-changelog-support:    Editing Commit Messages.
+                                                              (line 191)
+* git-commit-turn-on-auto-fill:          Editing Commit Messages.
+                                                              (line 196)
+* git-commit-turn-on-flyspell:           Editing Commit Messages.
+                                                              (line 201)
+* ido-enter-magit-status:                Status Buffer.       (line  47)
+* magit-add-section-hook:                Section Hooks.       (line  18)
+* magit-after-save-refresh-status:       Automatic Refreshing of Magit Buffers.
+                                                              (line  56)
+* magit-blame:                           Blaming.             (line  17)
+* magit-blame-echo:                      Blaming.             (line  32)
+* magit-blame-removal:                   Blaming.             (line  38)
+* magit-blame-reverse:                   Blaming.             (line  46)
+* magit-branch-config-popup:             The Branch Config Popup.
+                                                              (line   6)
+* magit-branch-or-checkout:              The Branch Popup.    (line 350)
+* magit-branch-orphan:                   The Branch Popup.    (line 345)
+* magit-branch-shelve:                   Auxillary Branch Commands.
+                                                              (line   8)
+* magit-branch-unshelve:                 Auxillary Branch Commands.
+                                                              (line  19)
+* magit-builtin-completing-read:         Support for Completion Frameworks.
+                                                              (line  42)
+* magit-call-git:                        Calling Git for Effect.
+                                                              (line  28)
+* magit-call-process:                    Calling Git for Effect.
+                                                              (line  32)
+* magit-cancel-section:                  Creating Sections.   (line  71)
+* magit-completing-read:                 Support for Completion Frameworks.
+                                                              (line  60)
+* magit-current-section:                 Section Selection.   (line   6)
+* magit-define-section-jumper:           Creating Sections.   (line  77)
+* magit-diff-scope:                      Matching Sections.   (line 111)
+* magit-diff-type:                       Matching Sections.   (line  88)
+* magit-diff-visit-file-other-window:    Diff Buffer.         (line  65)
+* magit-display-buffer:                  Switching Buffers.   (line   6)
+* magit-display-buffer-fullcolumn-most-v1: Switching Buffers. (line  72)
+* magit-display-buffer-fullframe-status-topleft-v1: Switching Buffers.
+                                                              (line  62)
+* magit-display-buffer-fullframe-status-v1: Switching Buffers.
+                                                              (line  56)
+* magit-display-buffer-same-window-except-diff-v1: Switching Buffers.
+                                                              (line  50)
+* magit-display-buffer-traditional:      Switching Buffers.   (line  42)
+* magit-file-checkout:                   Minor Mode for Buffers Visiting Files.
+                                                              (line 131)
+* magit-file-delete:                     Minor Mode for Buffers Visiting Files.
+                                                              (line 123)
+* magit-file-rename:                     Minor Mode for Buffers Visiting Files.
+                                                              (line 119)
+* magit-file-untrack:                    Minor Mode for Buffers Visiting Files.
+                                                              (line 127)
+* magit-generate-buffer-name-default-function: Naming Buffers.
+                                                              (line  17)
+* magit-get-section:                     Matching Sections.   (line  16)
+* magit-git:                             Calling Git for Effect.
+                                                              (line  65)
+* magit-git-exit-code:                   Getting a Value from Git.
+                                                              (line  10)
+* magit-git-failure:                     Getting a Value from Git.
+                                                              (line  19)
+* magit-git-false:                       Getting a Value from Git.
+                                                              (line  29)
+* magit-git-insert:                      Getting a Value from Git.
+                                                              (line  34)
+* magit-git-items:                       Getting a Value from Git.
+                                                              (line  49)
+* magit-git-lines:                       Getting a Value from Git.
+                                                              (line  44)
+* magit-git-str:                         Getting a Value from Git.
+                                                              (line  72)
+* magit-git-string:                      Getting a Value from Git.
+                                                              (line  38)
+* magit-git-success:                     Getting a Value from Git.
+                                                              (line  14)
+* magit-git-true:                        Getting a Value from Git.
+                                                              (line  24)
+* magit-git-wash:                        Calling Git for Effect.
+                                                              (line  70)
+* magit-hunk-set-window-start:           Section Movement.    (line  43)
+* magit-ido-completing-read:             Support for Completion Frameworks.
+                                                              (line  48)
+* magit-insert-am-sequence:              Status Sections.     (line  28)
+* magit-insert-bisect-log:               Status Sections.     (line  46)
+* magit-insert-bisect-output:            Status Sections.     (line  38)
+* magit-insert-bisect-rest:              Status Sections.     (line  42)
+* magit-insert-diff-filter-header:       Status Header Sections.
+                                                              (line  38)
+* magit-insert-error-header:             Status Header Sections.
+                                                              (line  28)
+* magit-insert-head-branch-header:       Status Header Sections.
+                                                              (line  42)
+* magit-insert-heading:                  Creating Sections.   (line  42)
+* magit-insert-ignored-files:            Status Sections.     (line 100)
+* magit-insert-local-branches:           References Sections. (line  17)
+* magit-insert-merge-log:                Status Sections.     (line  18)
+* magit-insert-modules:                  Status Module Sections.
+                                                              (line  12)
+* magit-insert-modules-overview:         Status Module Sections.
+                                                              (line  33)
+* magit-insert-modules-unpulled-from-pushremote: Status Module Sections.
+                                                              (line  50)
+* magit-insert-modules-unpulled-from-upstream: Status Module Sections.
+                                                              (line  44)
+* magit-insert-modules-unpushed-to-pushremote: Status Module Sections.
+                                                              (line  62)
+* magit-insert-modules-unpushed-to-upstream: Status Module Sections.
+                                                              (line  56)
+* magit-insert-push-branch-header:       Status Header Sections.
+                                                              (line  51)
+* magit-insert-rebase-sequence:          Status Sections.     (line  23)
+* magit-insert-recent-commits:           Status Sections.     (line 115)
+* magit-insert-remote-branches:          References Sections. (line  21)
+* magit-insert-remote-header:            Status Header Sections.
+                                                              (line  67)
+* magit-insert-repo-header:              Status Header Sections.
+                                                              (line  63)
+* magit-insert-section:                  Creating Sections.   (line   6)
+* magit-insert-sequencer-sequence:       Status Sections.     (line  33)
+* magit-insert-staged-changes:           Status Sections.     (line  63)
+* magit-insert-stashes:                  Status Sections.     (line  67)
+* magit-insert-status-headers:           Status Header Sections.
+                                                              (line  12)
+* magit-insert-submodules:               Listing Submodules.  (line  35)
+* magit-insert-tags:                     References Sections. (line  25)
+* magit-insert-tags-header:              Status Header Sections.
+                                                              (line  56)
+* magit-insert-tracked-files:            Status Sections.     (line  96)
+* magit-insert-unpulled-cherries:        Status Sections.     (line 126)
+* magit-insert-unpulled-from-pushremote: Status Sections.     (line  79)
+* magit-insert-unpulled-from-upstream:   Status Sections.     (line  74)
+* magit-insert-unpulled-or-recent-commits: Status Sections.   (line 108)
+* magit-insert-unpushed-cherries:        Status Sections.     (line 133)
+* magit-insert-unpushed-to-pushremote:   Status Sections.     (line  89)
+* magit-insert-unpushed-to-upstream:     Status Sections.     (line  84)
+* magit-insert-unstaged-changes:         Status Sections.     (line  59)
+* magit-insert-untracked-files:          Status Sections.     (line  50)
+* magit-insert-upstream-branch-header:   Status Header Sections.
+                                                              (line  46)
+* magit-insert-user-header:              Status Header Sections.
+                                                              (line  75)
+* magit-list-repositories:               Repository List.     (line   6)
+* magit-list-submodules:                 Listing Submodules.  (line  13)
+* magit-log-maybe-show-more-commits:     Section Movement.    (line  57)
+* magit-log-maybe-update-blob-buffer:    Section Movement.    (line  71)
+* magit-log-maybe-update-revision-buffer: Section Movement.   (line  64)
+* magit-maybe-set-dedicated:             Switching Buffers.   (line  97)
+* magit-mode-display-buffer:             Refreshing Buffers.  (line  33)
+* magit-mode-quit-window:                Quitting Windows.    (line  31)
+* magit-mode-setup:                      Refreshing Buffers.  (line  17)
+* magit-push-implicitly:                 Pushing.             (line  73)
+* magit-push-to-remote:                  Pushing.             (line  84)
+* magit-region-sections:                 Section Selection.   (line  10)
+* magit-region-values:                   Section Selection.   (line  29)
+* magit-remote-config-popup:             The Remote Config Popup.
+                                                              (line   6)
+* magit-repolist-column-ident:           Repository List.     (line  30)
+* magit-repolist-column-path:            Repository List.     (line  35)
+* magit-repolist-column-unpulled-from-pushremote: Repository List.
+                                                              (line  49)
+* magit-repolist-column-unpulled-from-upstream: Repository List.
+                                                              (line  44)
+* magit-repolist-column-unpushed-to-pushremote: Repository List.
+                                                              (line  59)
+* magit-repolist-column-unpushed-to-upstream: Repository List.
+                                                              (line  54)
+* magit-repolist-column-version:         Repository List.     (line  39)
+* magit-restore-window-configuration:    Quitting Windows.    (line  20)
+* magit-revert-buffers:                  Editing Commit Messages.
+                                                              (line 178)
+* magit-run-git:                         Calling Git for Effect.
+                                                              (line  36)
+* magit-run-git-async:                   Calling Git for Effect.
+                                                              (line  80)
+* magit-run-git-with-editor:             Calling Git for Effect.
+                                                              (line  93)
+* magit-run-git-with-input:              Calling Git for Effect.
+                                                              (line  40)
+* magit-run-git-with-logfile:            Calling Git for Effect.
+                                                              (line  56)
+* magit-save-window-configuration:       Switching Buffers.   (line  86)
+* magit-section-case:                    Matching Sections.   (line  64)
+* magit-section-hide:                    Section Visibility.  (line  49)
+* magit-section-hide-children:           Section Visibility.  (line  64)
+* magit-section-ident:                   Matching Sections.   (line  11)
+* magit-section-match:                   Matching Sections.   (line  21)
+* magit-section-set-window-start:        Section Movement.    (line  50)
+* magit-section-show:                    Section Visibility.  (line  45)
+* magit-section-show-children:           Section Visibility.  (line  58)
+* magit-section-show-headings:           Section Visibility.  (line  53)
+* magit-section-toggle-children:         Section Visibility.  (line  68)
+* magit-section-when:                    Matching Sections.   (line  52)
+* magit-start-git:                       Calling Git for Effect.
+                                                              (line 105)
+* magit-start-process:                   Calling Git for Effect.
+                                                              (line 124)
+* magit-status-maybe-update-blob-buffer: Section Movement.    (line  83)
+* magit-status-maybe-update-revision-buffer: Section Movement.
+                                                              (line  77)
+* magit-tag-release:                     Tagging.             (line  28)
+* magit-wip-log:                         Wip Modes.           (line  69)
+* magit-wip-log-current:                 Wip Modes.           (line  77)
+* with-editor-usage-message:             Editing Commit Messages.
+                                                              (line 215)
+
+
+File: magit.info,  Node: Variable Index,  Prev: Function Index,  Up: Top
+
+Appendix F Variable Index
+*************************
+
+
+* Menu:
+
+* auto-revert-buffer-list-filter:        Automatic Reverting of File-Visiting Buffers.
+                                                              (line  81)
+* auto-revert-interval:                  Automatic Reverting of File-Visiting Buffers.
+                                                              (line  76)
+* auto-revert-stop-on-user-input:        Automatic Reverting of File-Visiting Buffers.
+                                                              (line  71)
+* auto-revert-use-notify:                Automatic Reverting of File-Visiting Buffers.
+                                                              (line  49)
+* auto-revert-verbose:                   Automatic Reverting of File-Visiting Buffers.
+                                                              (line 103)
+* branch.autoSetupMerge:                 The Branch Config Popup.
+                                                              (line  94)
+* branch.autoSetupRebase:                The Branch Config Popup.
+                                                              (line 111)
+* branch.NAME.description:               The Branch Config Popup.
+                                                              (line  61)
+* branch.NAME.merge:                     The Branch Config Popup.
+                                                              (line  23)
+* branch.NAME.pushRemote:                The Branch Config Popup.
+                                                              (line  47)
+* branch.NAME.rebase:                    The Branch Config Popup.
+                                                              (line  35)
+* branch.NAME.remote:                    The Branch Config Popup.
+                                                              (line  29)
+* core.notesRef:                         Notes.               (line  59)
+* git-commit-fill-column:                Editing Commit Messages.
+                                                              (line 228)
+* git-commit-finish-query-functions:     Editing Commit Messages.
+                                                              (line 233)
+* git-commit-known-pseudo-headers:       Editing Commit Messages.
+                                                              (line 124)
+* git-commit-major-mode:                 Editing Commit Messages.
+                                                              (line 163)
+* git-commit-setup-hook:                 Editing Commit Messages.
+                                                              (line 174)
+* git-commit-summary-max-length:         Editing Commit Messages.
+                                                              (line 222)
+* git-rebase-auto-advance:               Editing Rebase Sequences.
+                                                              (line  94)
+* git-rebase-confirm-cancel:             Editing Rebase Sequences.
+                                                              (line 102)
+* git-rebase-show-instructions:          Editing Rebase Sequences.
+                                                              (line  98)
+* global-auto-revert-mode:               Automatic Reverting of File-Visiting Buffers.
+                                                              (line  22)
+* magit-auto-revert-immediately:         Automatic Reverting of File-Visiting Buffers.
+                                                              (line  32)
+* magit-auto-revert-mode:                Automatic Reverting of File-Visiting Buffers.
+                                                              (line  17)
+* magit-auto-revert-tracked-only:        Automatic Reverting of File-Visiting Buffers.
+                                                              (line  55)
+* magit-bisect-show-graph:               Bisecting.           (line  55)
+* magit-blame-disable-modes:             Blaming.             (line 150)
+* magit-blame-echo-style:                Blaming.             (line 133)
+* magit-blame-goto-chunk-hook:           Blaming.             (line 156)
+* magit-blame-read-only:                 Blaming.             (line 145)
+* magit-blame-styles:                    Blaming.             (line 128)
+* magit-blame-time-format:               Blaming.             (line 140)
+* magit-branch-adjust-remote-upstream-alist: The Branch Popup.
+                                                              (line 303)
+* magit-branch-popup-show-variables:     The Branch Popup.    (line  21)
+* magit-branch-prefer-remote-upstream:   The Branch Popup.    (line 258)
+* magit-branch-read-upstream-first:      The Branch Popup.    (line 252)
+* magit-buffer-name-format:              Naming Buffers.      (line  27)
+* magit-bury-buffer-function:            Quitting Windows.    (line  11)
+* magit-cherry-margin:                   Cherries.            (line  22)
+* magit-clone-set-remote.pushDefault:    Repository Setup.    (line  23)
+* magit-commit-ask-to-stage:             Initiating a Commit. (line  74)
+* magit-commit-extend-override-date:     Initiating a Commit. (line  79)
+* magit-commit-reword-override-date:     Initiating a Commit. (line  83)
+* magit-commit-squash-confirm:           Initiating a Commit. (line  87)
+* magit-completing-read-function:        Support for Completion Frameworks.
+                                                              (line  27)
+* magit-diff-adjust-tab-width:           Diff Options.        (line  16)
+* magit-diff-buffer-file-locked:         Minor Mode for Buffers Visiting Files.
+                                                              (line  52)
+* magit-diff-hide-trailing-cr-characters: Diff Options.       (line  67)
+* magit-diff-highlight-hunk-region-functions: Diff Options.   (line  71)
+* magit-diff-highlight-indentation:      Diff Options.        (line  52)
+* magit-diff-highlight-trailing:         Diff Options.        (line  47)
+* magit-diff-paint-whitespace:           Diff Options.        (line  38)
+* magit-diff-refine-hunk:                Diff Options.        (line   6)
+* magit-diff-unmarked-lines-keep-foreground: Diff Options.    (line  97)
+* magit-diff-visit-previous-blob:        Diff Buffer.         (line  37)
+* magit-display-buffer-function:         Switching Buffers.   (line  23)
+* magit-display-buffer-noselect:         Switching Buffers.   (line  14)
+* magit-dwim-selection:                  Completion and Confirmation.
+                                                              (line  42)
+* magit-ediff-dwim-show-on-hunks:        Ediffing.            (line  73)
+* magit-ediff-quit-hook:                 Ediffing.            (line  88)
+* magit-ediff-show-stash-with-index:     Ediffing.            (line  81)
+* magit-file-mode:                       Minor Mode for Buffers Visiting Files.
+                                                              (line  11)
+* magit-generate-buffer-name-function:   Naming Buffers.      (line   6)
+* magit-git-debug:                       Viewing Git Output.  (line  28)
+* magit-git-debug <1>:                   Getting a Value from Git.
+                                                              (line  64)
+* magit-git-executable:                  Git Executable.      (line  39)
+* magit-git-global-arguments:            Global Git Arguments.
+                                                              (line   6)
+* magit-keep-region-overlay:             The Selection.       (line  52)
+* magit-list-refs-sortby:                Additional Completion Options.
+                                                              (line   6)
+* magit-log-auto-more:                   Log Buffer.          (line  67)
+* magit-log-buffer-file-locked:          Minor Mode for Buffers Visiting Files.
+                                                              (line  75)
+* magit-log-margin:                      Log Margin.          (line  12)
+* magit-log-section-args:                Status Options.      (line  36)
+* magit-log-section-commit-count:        Status Sections.     (line 120)
+* magit-log-select-margin:               Select from Log.     (line  30)
+* magit-log-show-refname-after-summary:  Log Buffer.          (line  73)
+* magit-module-sections-hook:            Status Module Sections.
+                                                              (line  20)
+* magit-module-sections-nested:          Status Module Sections.
+                                                              (line  24)
+* magit-no-confirm:                      Action Confirmation. (line  18)
+* magit-pop-revision-stack-format:       Editing Commit Messages.
+                                                              (line  92)
+* magit-post-display-buffer-hook:        Switching Buffers.   (line  92)
+* magit-pre-display-buffer-hook:         Switching Buffers.   (line  81)
+* magit-prefer-remote-upstream:          The Branch Config Popup.
+                                                              (line 139)
+* magit-process-raise-error:             Calling Git for Effect.
+                                                              (line 151)
+* magit-push-current-set-remote-if-missing: Pushing.          (line  96)
+* magit-reflog-margin:                   Reflog.              (line  23)
+* magit-refresh-args:                    Refreshing Buffers.  (line  55)
+* magit-refresh-buffer-hook:             Automatic Refreshing of Magit Buffers.
+                                                              (line  40)
+* magit-refresh-function:                Refreshing Buffers.  (line  49)
+* magit-refresh-status-buffer:           Automatic Refreshing of Magit Buffers.
+                                                              (line  46)
+* magit-refs-filter-alist:               References Buffer.   (line 149)
+* magit-refs-focus-column-width:         References Buffer.   (line  74)
+* magit-refs-margin:                     References Buffer.   (line  89)
+* magit-refs-margin-for-tags:            References Buffer.   (line 115)
+* magit-refs-pad-commit-counts:          References Buffer.   (line  41)
+* magit-refs-primary-column-width:       References Buffer.   (line  61)
+* magit-refs-sections-hook:              References Sections. (line  13)
+* magit-refs-show-commit-count:          References Buffer.   (line  29)
+* magit-refs-show-remote-prefix:         References Buffer.   (line  54)
+* magit-remote-add-set-remote.pushDefault: The Remote Popup.  (line  77)
+* magit-remote-popup-show-variables:     The Remote Popup.    (line  18)
+* magit-repolist-columns:                Repository List.     (line  14)
+* magit-repository-directories:          Status Buffer.       (line  30)
+* magit-repository-directories-depth:    Status Buffer.       (line  40)
+* magit-revision-insert-related-refs:    Revision Buffer.     (line   6)
+* magit-revision-show-gravatar:          Revision Buffer.     (line  10)
+* magit-revision-use-hash-sections:      Revision Buffer.     (line  26)
+* magit-root-section:                    Matching Sections.   (line  80)
+* magit-save-repository-buffers:         Automatic Saving of File-Visiting Buffers.
+                                                              (line  13)
+* magit-section-cache-visibility:        Section Visibility.  (line  95)
+* magit-section-initial-visibility-alist: Section Visibility. (line  78)
+* magit-section-movement-hook:           Section Movement.    (line  38)
+* magit-section-set-visibility-hook:     Section Visibility.  (line 106)
+* magit-section-show-child-count:        Section Options.     (line   9)
+* magit-shell-command-verbose-prompt:    Running Git Manually.
+                                                              (line  46)
+* magit-stashes-margin:                  Stashing.            (line 103)
+* magit-status-headers-hook:             Status Header Sections.
+                                                              (line  18)
+* magit-status-margin:                   Status Options.      (line  10)
+* magit-status-refresh-hook:             Status Options.      (line   6)
+* magit-status-sections-hook:            Status Sections.     (line  10)
+* magit-submodule-list-columns:          Listing Submodules.  (line  21)
+* magit-this-process:                    Calling Git for Effect.
+                                                              (line 146)
+* magit-uniquify-buffer-names:           Naming Buffers.      (line  74)
+* magit-unstage-committed:               Staging and Unstaging.
+                                                              (line  56)
+* magit-update-other-window-delay:       Section Movement.    (line  89)
+* magit-use-sticky-arguments:            Popup Buffers and Prefix Commands.
+                                                              (line  36)
+* magit-visit-ref-behavior:              References Buffer.   (line 177)
+* magit-wip-after-apply-mode:            Wip Modes.           (line  99)
+* magit-wip-after-apply-mode-lighter:    Wip Modes.           (line 141)
+* magit-wip-after-save-local-mode-lighter: Wip Modes.         (line 137)
+* magit-wip-after-save-mode:             Wip Modes.           (line  93)
+* magit-wip-before-change-mode:          Wip Modes.           (line 113)
+* magit-wip-before-change-mode-lighter:  Wip Modes.           (line 145)
+* magit-wip-namespace:                   Wip Modes.           (line 149)
+* notes.displayRef:                      Notes.               (line  64)
+* pull.rebase:                           The Branch Config Popup.
+                                                              (line  70)
+* remote.NAME.fetch:                     The Remote Config Popup.
+                                                              (line  25)
+* remote.NAME.push:                      The Remote Config Popup.
+                                                              (line  36)
+* remote.NAME.pushurl:                   The Remote Config Popup.
+                                                              (line  30)
+* remote.NAME.tagOpts:                   The Remote Config Popup.
+                                                              (line  41)
+* remote.NAME.url:                       The Remote Config Popup.
+                                                              (line  20)
+* remote.pushDefault:                    The Branch Config Popup.
+                                                              (line  84)
+
diff --git a/configs/shared/emacs/.emacs.d/elpa/magit-popup-20180618.1602/dir b/configs/shared/emacs/.emacs.d/elpa/magit-popup-20180618.1602/dir
new file mode 100644
index 0000000000..c276dafb5e
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-popup-20180618.1602/dir
@@ -0,0 +1,18 @@
+This is the file .../info/dir, which contains the
+topmost node of the Info hierarchy, called (dir)Top.
+The first time you invoke Info you start off looking at this node.
+
+File: dir,	Node: Top	This is the top of the INFO tree
+
+  This (the Directory node) gives a menu of major topics.
+  Typing "q" exits, "?" lists all Info commands, "d" returns here,
+  "h" gives a primer for first-timers,
+  "mEmacs<Return>" visits the Emacs manual, etc.
+
+  In Emacs, you can click mouse button 2 on a menu item or cross reference
+  to select it.
+
+* Menu:
+
+Emacs
+* Magit-Popup: (magit-popup).   Infix arguments with feedback.
diff --git a/configs/shared/emacs/.emacs.d/elpa/magit-popup-20180618.1602/magit-popup-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/magit-popup-20180618.1602/magit-popup-autoloads.el
new file mode 100644
index 0000000000..02e930bfce
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-popup-20180618.1602/magit-popup-autoloads.el
@@ -0,0 +1,16 @@
+;;; magit-popup-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil nil ("magit-popup-pkg.el" "magit-popup.el")
+;;;;;;  (23377 61606 782020 725000))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; magit-popup-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/magit-popup-20180618.1602/magit-popup-pkg.el b/configs/shared/emacs/.emacs.d/elpa/magit-popup-20180618.1602/magit-popup-pkg.el
new file mode 100644
index 0000000000..cd14d1ee82
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-popup-20180618.1602/magit-popup-pkg.el
@@ -0,0 +1,10 @@
+(define-package "magit-popup" "20180618.1602" "Define prefix-infix-suffix command combos"
+  '((emacs "24.4")
+    (async "1.9.2")
+    (dash "2.13.0"))
+  :keywords
+  '("bindings")
+  :url "https://github.com/magit/magit-popup")
+;; Local Variables:
+;; no-byte-compile: t
+;; End:
diff --git a/configs/shared/emacs/.emacs.d/elpa/magit-popup-20180618.1602/magit-popup.el b/configs/shared/emacs/.emacs.d/elpa/magit-popup-20180618.1602/magit-popup.el
new file mode 100644
index 0000000000..5378842d5a
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-popup-20180618.1602/magit-popup.el
@@ -0,0 +1,1366 @@
+;;; magit-popup.el --- Define prefix-infix-suffix command combos  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2010-2018  The Magit Project Contributors
+;;
+;; You should have received a copy of the AUTHORS.md file which
+;; lists all contributors.  If not, see http://magit.vc/authors.
+
+;; This library was inspired by and replaces library `magit-key-mode',
+;; which was written by Phil Jackson <phil@shellarchive.co.uk> and is
+;; distributed under the GNU General Public License version 3 or later.
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; Package-Requires: ((emacs "24.4") (async "1.9.2") (dash "2.13.0"))
+;; Keywords: bindings
+;; Homepage: https://github.com/magit/magit-popup
+
+;; Magit-Popup 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, or (at your option)
+;; any later version.
+;;
+;; Magit-Popup 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 Magit-Popup.  If not, see http://www.gnu.org/licenses.
+
+;;; Commentary:
+
+;; This package implements a generic interface for toggling switches
+;; and setting options and then invoking an Emacs command which does
+;; something with these arguments.  The prototypical use is for the
+;; command to call an external process, passing on the arguments as
+;; command line arguments.  But this is only one of many possible
+;; uses (though the one this library is optimized for).
+
+;; With the Emacs concept of "prefix arguments" in mind this could be
+;; described as "infix arguments with feedback in a buffer".
+
+;; Commands that set the prefix argument for the subsequent command do
+;; not limit what that next command could be.  But entering a command
+;; console popup does limit the selection to the commands defined for
+;; that popup, and so we use the term "infix" instead of "prefix".
+
+;;; Code:
+
+(require 'button)
+(require 'cl-lib)
+(require 'dash)
+(require 'format-spec)
+(eval-when-compile (require 'subr-x))
+
+(and (require 'async-bytecomp nil t)
+     (cl-intersection '(all magit)
+                      (bound-and-true-p async-bytecomp-allowed-packages))
+     (fboundp 'async-bytecomp-package-mode)
+     (async-bytecomp-package-mode 1))
+
+(declare-function info 'info)
+(declare-function Man-find-section 'man)
+(declare-function Man-next-section 'man)
+
+;; For branch actions.
+(declare-function magit-branch-set-face 'magit-git)
+
+;;; Settings
+;;;; Custom Groups
+
+(defgroup magit-popup nil
+  "Infix arguments with a popup as feedback."
+  :link '(info-link "(magit-popup)")
+  :group 'bindings)
+
+(defgroup magit-popup-faces nil
+  "Faces used by Magit-Popup."
+  :group 'magit-popup)
+
+;;;; Custom Options
+
+(defcustom magit-popup-display-buffer-action '((display-buffer-below-selected))
+  "The action used to display a popup buffer.
+
+Popup buffers are displayed using `display-buffer' with the value
+of this option as ACTION argument.  You can also set this to nil
+and instead add an entry to `display-buffer-alist'."
+  :package-version '(magit-popup . "2.4.0")
+  :group 'magit-popup
+  :type 'sexp)
+
+(defcustom magit-popup-manpage-package
+  (if (memq system-type '(windows-nt ms-dos)) 'woman 'man)
+  "The package used to display manpages.
+One of `man' or `woman'."
+  :group 'magit-popup
+  :type '(choice (const man) (const woman)))
+
+(defcustom magit-popup-show-help-echo t
+  "Show usage information in the echo area."
+  :group 'magit-popup
+  :type 'boolean)
+
+(defcustom magit-popup-show-common-commands nil
+  "Whether to initially show section with commands common to all popups.
+This section can also be toggled temporarily using \
+\\<magit-popup-mode-map>\\[magit-popup-toggle-show-common-commands]."
+  :package-version '(magit-popup . "2.9.0")
+  :group 'magit-popup
+  :type 'boolean)
+
+(defcustom magit-popup-use-prefix-argument 'default
+  "Control how prefix arguments affect infix argument popups.
+
+This option controls the effect that the use of a prefix argument
+before entering a popup has.
+
+`default'  With a prefix argument directly invoke the popup's
+           default action (an Emacs command), instead of bringing
+           up the popup.
+
+`popup'    With a prefix argument bring up the popup, otherwise
+           directly invoke the popup's default action.
+
+`nil'      Ignore prefix arguments."
+  :group 'magit-popup
+  :type '(choice
+          (const :tag "Call default action instead of showing popup" default)
+          (const :tag "Show popup instead of calling default action" popup)
+          (const :tag "Ignore prefix argument" nil)))
+
+;;;; Custom Faces
+
+(defface magit-popup-heading
+  '((t :inherit font-lock-keyword-face))
+  "Face for key mode header lines."
+  :group 'magit-popup-faces)
+
+(defface magit-popup-key
+  '((t :inherit font-lock-builtin-face))
+  "Face for key mode buttons."
+  :group 'magit-popup-faces)
+
+(defface magit-popup-argument
+  '((t :inherit font-lock-warning-face))
+  "Face used to display enabled arguments in popups."
+  :group 'magit-popup-faces)
+
+(defface magit-popup-disabled-argument
+  '((t :inherit shadow))
+  "Face used to display disabled arguments in popups."
+  :group 'magit-popup-faces)
+
+(defface magit-popup-option-value
+  '((t :inherit font-lock-string-face))
+  "Face used to display option values in popups."
+  :group 'magit-popup-faces)
+
+;;;; Keymap
+
+(defvar magit-popup-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map [remap self-insert-command] 'magit-invoke-popup-action)
+    (define-key map (kbd "- <t>")               'magit-invoke-popup-switch)
+    (define-key map (kbd "= <t>")               'magit-invoke-popup-option)
+    (define-key map (kbd "C-g")     'magit-popup-quit)
+    (define-key map (kbd "?")       'magit-popup-help)
+    (define-key map (kbd "C-h k")   'magit-popup-help)
+    (define-key map (kbd "C-h i")   'magit-popup-info)
+    (define-key map (kbd "C-t")     'magit-popup-toggle-show-common-commands)
+    (define-key map (kbd "C-c C-c") 'magit-popup-set-default-arguments)
+    (define-key map (kbd "C-x C-s") 'magit-popup-save-default-arguments)
+    (cond ((featurep 'jkl)
+           (define-key map (kbd "C-p") 'universal-argument)
+           (define-key map [return]    'push-button)
+           (define-key map (kbd "C-i") 'backward-button)
+           (define-key map (kbd "C-k") 'forward-button))
+          (t
+           (define-key map (kbd "C-m") 'push-button)
+           (define-key map (kbd "DEL") 'backward-button)
+           (define-key map (kbd "C-p") 'backward-button)
+           (define-key map (kbd "C-i") 'forward-button)
+           (define-key map (kbd "C-n") 'forward-button)))
+    map)
+  "Keymap for `magit-popup-mode'.
+
+\\<magit-popup-mode-map>\
+This keymap contains bindings common to all popups.  A section
+listing these commands can be shown or hidden using \
+\\[magit-popup-toggle-show-common-commands].
+
+The prefix used to toggle any switch can be changed by binding
+another key to `magit-invoke-popup-switch'.  Likewise binding
+another key to `magit-invoke-popup-option' changes the prefixed
+used to set any option.  The two prefixes have to be different.
+If you change these bindings, you should also change the `prefix'
+property of the button types `magit-popup-switch-button' and
+`magit-popup-option-button'.
+
+If you change any other binding, then you might have to also edit
+`magit-popup-common-commands' for things to align correctly in
+the section listing these commands.
+
+Never bind an alphabetic character in this keymap or you might
+make it impossible to invoke certain actions.")
+
+(defvar magit-popup-common-commands
+  '(("Set defaults"          magit-popup-set-default-arguments)
+    ("View popup manual"     magit-popup-info)
+    ("Toggle this section"   magit-popup-toggle-show-common-commands)
+    ("Save defaults"         magit-popup-save-default-arguments)
+    ("    Popup help prefix" magit-popup-help)
+    ("Abort"                 magit-popup-quit)))
+
+;;;; Buttons
+
+(define-button-type 'magit-popup-button
+  'face nil
+  'action (lambda (button)
+            (funcall (button-get button 'function)
+                     (button-get button 'event))))
+
+(define-button-type 'magit-popup-switch-button
+  'supertype 'magit-popup-button
+  'function  'magit-invoke-popup-switch
+  'property  :switches
+  'heading   "Switches\n"
+  'formatter 'magit-popup-format-argument-button
+  'format    " %k %d (%a)"
+  'prefix    ?-
+  'maxcols   1)
+
+(define-button-type 'magit-popup-option-button
+  'supertype 'magit-popup-button
+  'function  'magit-invoke-popup-option
+  'property  :options
+  'heading   "Options\n"
+  'formatter 'magit-popup-format-argument-button
+  'format    " %k %d (%a%v)"
+  'prefix    ?=
+  'maxcols   1)
+
+(define-button-type 'magit-popup-variable-button
+  'supertype 'magit-popup-button
+  'function  'magit-invoke-popup-action
+  'property  :variables
+  'heading   "Variables\n"
+  'formatter 'magit-popup-format-variable-button
+  'format    " %k %d"
+  'prefix    nil
+  'maxcols   1)
+
+(define-button-type 'magit-popup-action-button
+  'supertype 'magit-popup-button
+  'function  'magit-invoke-popup-action
+  'property  :actions
+  'heading   "Actions\n"
+  'formatter 'magit-popup-format-action-button
+  'format    " %k %d"
+  'prefix    nil
+  'maxcols   :max-action-columns)
+
+(define-button-type 'magit-popup-command-button
+  'supertype 'magit-popup-action-button
+  'formatter 'magit-popup-format-command-button
+  'action    (lambda (button)
+               (let ((command (button-get button 'function)))
+                 (unless (eq command 'push-button)
+                   (call-interactively command)))))
+
+(define-button-type 'magit-popup-internal-command-button
+  'supertype 'magit-popup-command-button
+  'heading   "Common Commands\n"
+  'maxcols   3)
+
+;;; Events
+
+(defvar-local magit-this-popup nil
+  "The popup which is currently active.
+This is intended for internal use only.
+Don't confuse this with `magit-current-popup'.")
+
+(defvar-local magit-this-popup-events nil
+  "The events known to the active popup.
+This is intended for internal use only.
+Don't confuse this with `magit-current-popup-args'.")
+
+(defvar-local magit-previous-popup nil)
+
+(defvar-local magit-pre-popup-buffer nil
+  "The buffer that was current before invoking the active popup.")
+
+(defun magit-popup-get (prop)
+  "While a popup is active, get the value of PROP."
+  (if (memq prop '(:switches :options :variables :actions))
+      (plist-get magit-this-popup-events prop)
+    (plist-get (symbol-value magit-this-popup) prop)))
+
+(defun magit-popup-put (prop val)
+  "While a popup is active, set the value of PROP to VAL."
+  (if (memq prop '(:switches :options :variables :actions))
+      (setq magit-this-popup-events
+            (plist-put magit-this-popup-events prop val))
+    (error "Property %s isn't supported" prop)))
+
+(defvar magit-current-popup nil
+  "The popup from which this editing command was invoked.
+
+Use this inside the `interactive' form of a popup aware command
+to determine whether it was invoked from a popup and if so from
+which popup.  If the current command was invoked without the use
+of a popup, then this is nil.")
+
+(defvar magit-current-popup-action nil
+  "The popup action now being executed.")
+
+(defvar magit-current-popup-args nil
+  "The value of the popup arguments for this editing command.
+
+If the current command was invoked from a popup, then this is
+a list of strings of all the set switches and options.  This
+includes arguments which are set by default not only those
+explicitly set during this invocation.
+
+When the value is nil, then that can be because no argument is
+set, or because the current command wasn't invoked from a popup;
+consult `magit-current-popup' to tell the difference.
+
+Generally it is better to use `NAME-arguments', which is created
+by `magit-define-popup', instead of this variable or the function
+by the same name, because `NAME-argument' uses the default value
+for the arguments when the editing command is invoked directly
+instead of from a popup.  When the command is bound in several
+popups that might not be feasible though.")
+
+(defun magit-current-popup-args (&rest filter)
+  "Return the value of the popup arguments for this editing command.
+
+The value is the same as that of the variable by the same name
+\(which see), except that FILTER is applied.  FILTER is a list
+of regexps; only arguments that match one of them are returned.
+The first element of FILTER may also be `:not' in which case
+only arguments that don't match any of the regexps are returned,
+or `:only' which doesn't change the behaviour."
+  (let ((-compare-fn (lambda (a b) (magit-popup-arg-match b a))))
+    (-filter (if (eq (car filter) :not)
+                 (lambda (arg) (not (-contains-p (cdr filter) arg)))
+               (when (eq (car filter) :only)
+                 (pop filter))
+               (lambda (arg) (-contains-p filter arg)))
+             magit-current-popup-args)))
+
+(defvar magit-current-pre-popup-buffer nil
+  "The buffer that was current before invoking the active popup.
+This is bound when invoking an action or variable.")
+
+(defmacro magit-with-pre-popup-buffer (&rest body)
+  "Execute the forms in BODY in the buffer that current before the popup.
+If `magit-current-pre-popup-buffer' is non-nil use that, else if
+`magit-pre-popup-buffer' is non-nil use that, otherwise (when no
+popup is involved) execute the forms in the current buffer."
+  (declare (indent 0))
+  `(--if-let (or magit-current-pre-popup-buffer magit-pre-popup-buffer)
+       (with-current-buffer it ,@body)
+     ,@body))
+
+(defun magit-popup-arg-match (pattern string)
+  (if (or (string-match-p "=$" pattern)
+          (string-match-p "^-[A-Z]$" pattern))
+      (string-match (format "^%s\\(.*\\)$" pattern) string)
+    (string-equal string pattern)))
+
+(cl-defstruct magit-popup-event key dsc arg fun use val)
+
+(defun magit-popup-event-keydsc (ev)
+  (let ((key (magit-popup-event-key ev)))
+    (key-description (if (vectorp key) key (vector key)))))
+
+(defun magit-popup-lookup (event type)
+  (--first (equal (magit-popup-event-key it) event)
+           (-filter 'magit-popup-event-p (magit-popup-get type))))
+
+(defun magit-popup-get-args ()
+  (--mapcat (when (and (magit-popup-event-p it)
+                       (magit-popup-event-use it))
+              (list (format "%s%s"
+                            (magit-popup-event-arg it)
+                            (or (magit-popup-event-val it) ""))))
+            (append (magit-popup-get :switches)
+                    (magit-popup-get :options))))
+
+(defmacro magit-popup-convert-events (def form)
+  (declare (indent 1) (debug (form form)))
+  `(--map (if (or (null it) (stringp it) (functionp it)) it ,form) ,def))
+
+(defun magit-popup-convert-switches (val def)
+  (magit-popup-convert-events def
+    (let ((a (nth 2 it)))
+      (make-magit-popup-event
+       :key (car it) :dsc (cadr it) :arg a
+       :use (and (member a val) t)
+       ;; For arguments implemented in lisp, this function's
+       ;; doc-string is used by `magit-popup-help'.  That is
+       ;; the only thing it is used for.
+       :fun (and (string-prefix-p "\+\+" a) (nth 3 it))))))
+
+(defun magit-popup-convert-options (val def)
+  (magit-popup-convert-events def
+    (let* ((a (nth 2 it))
+           (r (format "^%s\\(.*\\)" a))
+           (v (--first (string-match r it) val)))
+      (make-magit-popup-event
+       :key (car it)  :dsc (cadr it) :arg a
+       :use (and v t) :val (and v (match-string 1 v))
+       :fun (or (nth 3 it) 'read-from-minibuffer)))))
+
+(defun magit-popup-convert-variables (_val def)
+  (magit-popup-convert-events def
+    (make-magit-popup-event
+     :key (car it) :dsc (cadr it) :fun (nth 2 it) :arg (nth 3 it))))
+
+(defun magit-popup-convert-actions (_val def)
+  (magit-popup-convert-events def
+    (make-magit-popup-event
+     :key (car it) :dsc (cadr it) :fun (nth 2 it))))
+
+;;; Define
+
+(defmacro magit-define-popup (name doc &rest args)
+  "Define a popup command named NAME.
+
+NAME should begin with the package prefix and by convention end
+with `-popup'.  That name is used for the actual command as well
+as for a variable used internally.  DOC is used as the doc-string
+of that command.
+
+Also define an option and a function named `SHORTNAME-arguments',
+where SHORTNAME is NAME with the trailing `-popup' removed.  The
+name of this option and this function can be overwritten using
+the optional argument OPTION, but that is rarely advisable. As a
+special case if OPTION is specified but nil, do not define this
+option and this function at all.
+
+The option `SHORTNAME-arguments' holds the default value for the
+popup arguments.  It can be customized from within the popup or
+using the Custom interface.
+
+The function `SHORTNAME-arguments' is a wrapper around the
+variable `magit-current-popup-args', both of which are intended
+to be used inside the `interactive' form of commands commonly
+invoked from the popup `NAME'.  When such a command is invoked
+from that popup, then the function `SHORTNAME-arguments' returns
+the value of the variable `magit-current-popup-args'; however
+when the command is invoked directly, then it returns the default
+value of the variable `SHORTNAME-arguments'.
+
+Optional argument GROUP specifies the Custom group into which the
+option is placed.  If omitted, then the option is placed into some
+group the same way it is done when directly using `defcustom' and
+omitting the group, except when NAME begins with \"magit-\", in
+which case the group `magit-git-arguments' is used.
+
+Optional argument MODE is deprecated, instead use the keyword
+arguments `:setup-function' and/or `:refresh-function'.  If MODE
+is non-nil, then it specifies the mode used by the popup buffer,
+instead of the default, which is `magit-popup-mode'.
+
+The remaining arguments should have the form
+
+    [KEYWORD VALUE]...
+
+The following keywords are meaningful (and by convention are
+usually specified in that order):
+
+`:actions'
+  The actions which can be invoked from the popup.  VALUE is a
+  list whose members have the form (KEY DESC COMMAND), see
+  `magit-define-popup-action' for details.
+
+  Actions are regular Emacs commands, which usually have an
+  `interactive' form setup to consume the values of the popup
+  `:switches' and `:options' when invoked from the corresponding
+  popup, else when invoked as the default action or directly
+  without using the popup, the default value of the variable
+  `SHORTNAME-arguments'.  This is usually done by calling the
+  function `SHORTNAME-arguments'.
+
+  Members of VALUE may also be strings and functions, assuming
+  the first member is a string or function.  In that case the
+  members are split into sections and these special elements are
+  used as headings.  If such an element is a function then it is
+  called with no arguments and must return either a string, which
+  is used as the heading, or nil, in which case the section is
+  not inserted.
+
+  Members of VALUE may also be nil.  This should only be used
+  together with `:max-action-columns' and allows having gaps in
+  the action grid, which can help arranging actions sensibly.
+
+`:default-action'
+  The default action of the popup which is used directly instead
+  of displaying the popup buffer, when the popup is invoked with
+  a prefix argument.  Also see `magit-popup-use-prefix-argument'
+  and `:use-prefix', which can be used to inverse the meaning of
+  the prefix argument.
+
+`:use-prefix'
+  Controls when to display the popup buffer and when to invoke
+  the default action (if any) directly.  This overrides the
+  global default set using `magit-popup-use-prefix-argument'.
+  The value, if specified, should be one of `default' or `popup',
+  or a function that is called with no arguments and returns one
+  of these symbols.
+
+`:max-action-columns'
+  The maximum number of actions to display on a single line, a
+  number or a function that returns a number and takes the name
+  of the section currently being inserted as argument.  If there
+  isn't enough room to display as many columns as specified here,
+  then fewer are used.
+
+`:switches'
+  The popup arguments which can be toggled on and off.  VALUE
+  is a list whose members have the form (KEY DESC SWITCH), see
+  `magit-define-popup-switch' for details.
+
+  Members of VALUE may also be strings and functions, assuming
+  the first member is a string or function.  In that case the
+  members are split into sections and these special elements are
+  used as headings.  If such an element is a function then it is
+  called with no arguments and must return either a string, which
+  is used as the heading, or nil, in which case the section is
+  not inserted.
+
+`:options'
+  The popup arguments which take a value, as in \"--opt=OPTVAL\".
+  VALUE is a list whose members have the form (KEY DESC OPTION
+  READER), see `magit-define-popup-option' for details.
+
+  Members of VALUE may also be strings and functions, assuming
+  the first member is a string or function.  In that case the
+  members are split into sections and these special elements are
+  used as headings.  If such an element is a function then it is
+  called with no arguments and must return either a string, which
+  is used as the heading, or nil, in which case the section is
+  not inserted.
+
+`:default-arguments'
+  The default arguments, a list of switches (which are then
+  enabled by default) and options with there default values, as
+  in \"--OPT=OPTVAL\".
+
+`:variables'
+
+  Git variables which can be set from the popup.  VALUE is a list
+  whose members have the form (KEY DESC COMMAND FORMATTER), see
+  `magit-define-popup-variable' for details.
+
+  Members of VALUE may also be strings and functions, assuming
+  the first member is a string or function.  In that case the
+  members are split into sections and these special elements are
+  used as headings.  If such an element is a function then it is
+  called with no arguments and must return either a string, which
+  is used as the heading, or nil, in which case the section is
+  not inserted.
+
+  Members of VALUE may also be actions as described above for
+  `:actions'.
+
+  VALUE may also be a function that returns a list as describe
+  above.
+
+`:sequence-predicate'
+  When this function returns non-nil, then the popup uses
+  `:sequence-actions' instead of `:actions', and does not show
+  the `:switches' and `:options'.
+
+`:sequence-actions'
+  The actions which can be invoked from the popup, when
+  `:sequence-predicate' returns non-nil.
+
+`:setup-function'
+  When this function is specified, then it is used instead of
+  `magit-popup-default-setup'.
+
+`:refresh-function'
+  When this function is specified, then it is used instead of
+  calling `magit-popup-insert-section' three times with symbols
+  `magit-popup-switch-button', `magit-popup-option-button', and
+  finally `magit-popup-action-button' as argument.
+
+`:man-page'
+  The name of the manpage to be displayed when the user requests
+  help for a switch or argument.
+
+\(fn NAME DOC [GROUP [MODE [OPTION]]] :KEYWORD VALUE...)"
+  (declare (indent defun) (doc-string 2))
+  (let* ((str  (symbol-name name))
+         (grp  (if (keywordp (car args))
+                   (and (string-prefix-p "magit-" str) ''magit-git-arguments)
+                 (pop args)))
+         (mode (and (not (keywordp (car args))) (pop args)))
+         (opt  (if (keywordp (car args))
+                   (intern (concat (if (string-suffix-p "-popup" str)
+                                       (substring str 0 -6)
+                                     str)
+                                   "-arguments"))
+                 (eval (pop args)))))
+    `(progn
+       (defun ,name (&optional arg) ,doc
+         (interactive "P")
+         (magit-invoke-popup ',name ,mode arg))
+       (defvar ,name
+         (list :variable ',opt ,@args))
+       (magit-define-popup-keys-deferred ',name)
+       ,@(when opt
+           `((defcustom ,opt (plist-get ,name :default-arguments)
+               ""
+               ,@(and grp (list :group grp))
+               :type '(repeat (string :tag "Argument")))
+             (defun ,opt ()
+               (if (eq magit-current-popup ',name)
+                   magit-current-popup-args
+                 ,opt))
+             (put ',opt 'definition-name ',name))))))
+
+(defun magit-define-popup-switch (popup key desc switch
+                                        &optional enable at prepend)
+  "In POPUP, define KEY as SWITCH.
+
+POPUP is a popup command defined using `magit-define-popup'.
+SWITCH is a string representing an argument that takes no value.
+KEY is a character representing the second event in the sequence
+of keystrokes used to toggle the argument.  (The first event, the
+prefix, is shared among all switches, defaults to -, and can be
+changed in `magit-popup-mode-keymap').
+
+DESC is a string describing the purpose of the argument, it is
+displayed in the popup.
+
+If optional ENABLE is non-nil, then the switch is on by default.
+
+SWITCH is inserted after all other switches already defined for
+POPUP, unless optional PREPEND is non-nil, in which case it is
+placed first.  If optional AT is non-nil, then it should be the
+KEY of another switch already defined for POPUP, the argument
+is then placed before or after AT, depending on PREPEND."
+  (declare (indent defun))
+  (magit-define-popup-key popup :switches key
+    (list desc switch enable) at prepend))
+
+(defun magit-define-popup-option (popup key desc option
+                                        &optional reader value at prepend)
+  "In POPUP, define KEY as OPTION.
+
+POPUP is a popup command defined using `magit-define-popup'.
+OPTION is a string representing an argument that takes a value.
+KEY is a character representing the second event in the sequence
+of keystrokes used to set the argument's value.  (The first
+event, the prefix, is shared among all options, defaults to =,
+and can be changed in `magit-popup-mode-keymap').
+
+DESC is a string describing the purpose of the argument, it is
+displayed in the popup.
+
+If optional VALUE is non-nil then the option is on by default,
+and VALUE is its default value.
+
+READER is used to read a value from the user when the option is
+invoked and does not currently have a value.  It should take one
+argument and use it as the prompt.  If this is nil, then
+`read-from-minibuffer' is used.
+
+OPTION is inserted after all other options already defined for
+POPUP, unless optional PREPEND is non-nil, in which case it is
+placed first.  If optional AT is non-nil, then it should be the
+KEY of another option already defined for POPUP, the argument
+is then placed before or after AT, depending on PREPEND."
+  (declare (indent defun))
+  (magit-define-popup-key popup :options key
+    (list desc option reader value) at prepend))
+
+(defun magit-define-popup-variable (popup key desc command formatter
+                                          &optional at prepend)
+  "In POPUP, define KEY as COMMAND.
+
+POPUP is a popup command defined using `magit-define-popup'.
+COMMAND is a command which calls `magit-popup-set-variable'.
+FORMATTER is a function which calls `magit-popup-format-variable'.
+These two functions have to be called with the same arguments.
+
+KEY is a character representing the event used interactively call
+the COMMAND.
+
+DESC is the variable or a representation thereof.  It's not
+actually used for anything.
+
+COMMAND is inserted after all other commands already defined for
+POPUP, unless optional PREPEND is non-nil, in which case it is
+placed first.  If optional AT is non-nil, then it should be the
+KEY of another command already defined for POPUP, the command
+is then placed before or after AT, depending on PREPEND."
+  (declare (indent defun))
+  (magit-define-popup-key popup :variables key
+    (list desc command formatter) at prepend))
+
+(defun magit-define-popup-action (popup key desc command
+                                        &optional at prepend)
+  "In POPUP, define KEY as COMMAND.
+
+POPUP is a popup command defined using `magit-define-popup'.
+COMMAND can be any command but should usually consume the popup
+arguments in its `interactive' form.
+KEY is a character representing the event used invoke the action,
+i.e. to interactively call the COMMAND.
+
+DESC is a string describing the purpose of the action, it is
+displayed in the popup.
+
+COMMAND is inserted after all other commands already defined for
+POPUP, unless optional PREPEND is non-nil, in which case it is
+placed first.  If optional AT is non-nil, then it should be the
+KEY of another command already defined for POPUP, the command
+is then placed before or after AT, depending on PREPEND."
+  (declare (indent defun))
+  (magit-define-popup-key popup :actions key
+    (list desc command) at prepend))
+
+(defun magit-define-popup-sequence-action
+    (popup key desc command &optional at prepend)
+  "Like `magit-define-popup-action' but for `:sequence-action'."
+  (declare (indent defun))
+  (magit-define-popup-key popup :sequence-actions key
+    (list desc command) at prepend))
+
+(defconst magit-popup-type-plural-alist
+  '((:switch . :switches)
+    (:option . :options)
+    (:variable . :variables)
+    (:action . :actions)
+    (:sequence-action . :sequence-actions)))
+
+(defun magit-popup-pluralize-type (type)
+  (or (cdr (assq type magit-popup-type-plural-alist))
+      type))
+
+(defun magit-define-popup-key
+    (popup type key def &optional at prepend)
+  "In POPUP, define KEY as an action, switch, or option.
+It's better to use one of the specialized functions
+  `magit-define-popup-action',
+  `magit-define-popup-sequence-action',
+  `magit-define-popup-switch',
+  `magit-define-popup-option', or
+  `magit-define-popup-variable'."
+  (declare (indent defun))
+  (setq type (magit-popup-pluralize-type type))
+  (if (memq type '(:switches :options :variables :actions :sequence-actions))
+      (if (boundp popup)
+          (let* ((plist (symbol-value popup))
+                 (value (plist-get plist type))
+                 (elt   (assoc key value)))
+            (if elt
+                (setcdr elt def)
+              (setq elt (cons key def)))
+            (if at
+                (when (setq at (cl-member at value :key 'car-safe :test 'equal))
+                  (setq value (cl-delete key value :key 'car-safe :test 'equal))
+                  (if prepend
+                      (progn (push (car at) (cdr at))
+                             (setcar at elt))
+                    (push elt (cdr at))))
+              (setq value (cl-delete key value :key 'car-safe :test 'equal)))
+            (unless (assoc key value)
+              (setq value (if prepend
+                              (cons elt value)
+                            (append value (list elt)))))
+            (set popup (plist-put plist type value)))
+        (push (list type key def at prepend)
+              (get popup 'magit-popup-deferred)))
+    (error "Unknown popup event type: %s" type)))
+
+(defun magit-define-popup-keys-deferred (popup)
+  (dolist (args (get popup 'magit-popup-deferred))
+    (condition-case err
+        (apply #'magit-define-popup-key popup args)
+      ((debug error)
+       (display-warning 'magit (error-message-string err) :error))))
+  (put popup 'magit-popup-deferred nil))
+
+(defun magit-change-popup-key (popup type from to)
+  "In POPUP, bind TO to what FROM was bound to.
+TYPE is one of `:action', `:sequence-action', `:switch', or
+`:option'.  Bind TO and unbind FROM, both are characters."
+  (--if-let (assoc from (plist-get (symbol-value popup)
+                                   (magit-popup-pluralize-type type)))
+      (setcar it to)
+    (message "magit-change-popup-key: FROM key %c is unbound" from)))
+
+(defun magit-remove-popup-key (popup type key)
+  "In POPUP, remove KEY's binding of TYPE.
+POPUP is a popup command defined using `magit-define-popup'.
+TYPE is one of `:action', `:sequence-action', `:switch', or
+`:option'.  KEY is the character which is to be unbound."
+  (setq type (magit-popup-pluralize-type type))
+  (let* ((plist (symbol-value popup))
+         (alist (plist-get plist type))
+         (value (assoc key alist)))
+    (set popup (plist-put plist type (delete value alist)))))
+
+;;; Invoke
+
+(defvar-local magit-popup-previous-winconf nil)
+
+(defun magit-invoke-popup (popup mode arg)
+  (let* ((def     (symbol-value popup))
+         (val     (symbol-value (plist-get def :variable)))
+         (default (plist-get def :default-action))
+         (local   (plist-get def :use-prefix))
+         (local   (if (functionp local)
+                      (funcall local)
+                    local))
+         (use-prefix (or local magit-popup-use-prefix-argument)))
+    (cond
+     ((or (and (eq use-prefix 'default) arg)
+          (and (eq use-prefix 'popup) (not arg)))
+      (if default
+          (let ((magit-current-popup (list popup 'default))
+                (magit-current-popup-args
+                 (let ((magit-this-popup popup)
+                       (magit-this-popup-events nil))
+                   (magit-popup-default-setup val def)
+                   (magit-popup-get-args))))
+            (when (and arg (listp arg))
+              (setq current-prefix-arg (and (not (= (car arg) 4))
+                                            (list (/ (car arg) 4)))))
+            (call-interactively default))
+        (message "%s has no default action; showing popup instead." popup)
+        (magit-popup-mode-setup popup mode)))
+     ((memq use-prefix '(default popup nil))
+      (magit-popup-mode-setup popup mode)
+      (when magit-popup-show-help-echo
+        (message
+         (format
+          "[%s] show common commands, [%s] describe events, [%s] show manual"
+          (propertize "C-t"   'face 'magit-popup-key)
+          (propertize "?"     'face 'magit-popup-key)
+          (propertize "C-h i" 'face 'magit-popup-key)))))
+     (local
+      (error "Invalid :use-prefix popup property value: %s" use-prefix))
+     (t
+      (error "Invalid magit-popup-use-prefix-argument value: %s" use-prefix)))))
+
+(defun magit-invoke-popup-switch (event)
+  (interactive (list last-command-event))
+  (--if-let (magit-popup-lookup event :switches)
+      (progn
+        (setf (magit-popup-event-use it)
+              (not (magit-popup-event-use it)))
+        (magit-refresh-popup-buffer))
+    (user-error "%c isn't bound to any switch" event)))
+
+(defun magit-invoke-popup-option (event)
+  (interactive (list last-command-event))
+  (--if-let (magit-popup-lookup event :options)
+      (progn
+        (if (magit-popup-event-use it)
+            (setf (magit-popup-event-use it) nil)
+          (let* ((arg (magit-popup-event-arg it))
+                 (val (funcall
+                       (magit-popup-event-fun it)
+                       (concat arg (unless (string-match-p "=$" arg) ": "))
+                       (magit-popup-event-val it))))
+            (setf (magit-popup-event-use it) t)
+            (setf (magit-popup-event-val it) val)))
+        (magit-refresh-popup-buffer))
+    (user-error "%c isn't bound to any option" event)))
+
+(defun magit-invoke-popup-action (event)
+  (interactive (list last-command-event))
+  (let ((action   (magit-popup-lookup event :actions))
+        (variable (magit-popup-lookup event :variables)))
+    (when (and variable (not (magit-popup-event-arg variable)))
+      (setq action variable)
+      (setq variable nil))
+    (cond ((or action variable)
+           (let* ((magit-current-popup magit-this-popup)
+                  (magit-current-popup-args (magit-popup-get-args))
+                  (magit-current-pre-popup-buffer magit-pre-popup-buffer)
+                  (command (magit-popup-event-fun (or action variable)))
+                  (magit-current-popup-action command))
+             (when action
+               (magit-popup-quit))
+             (setq this-command command)
+             (call-interactively command)
+             (unless action
+               (magit-refresh-popup-buffer))))
+          ((eq event ?q)
+           (magit-popup-quit)
+           (when magit-previous-popup
+             (magit-popup-mode-setup magit-previous-popup nil)))
+          (t
+           (user-error "%c isn't bound to any action" event)))))
+
+(defun magit-popup-quit ()
+  "Quit the current popup command without invoking an action."
+  (interactive)
+  (let ((winconf magit-popup-previous-winconf))
+    (if (derived-mode-p 'magit-popup-mode)
+        (kill-buffer)
+      (magit-popup-help-mode -1)
+      (kill-local-variable 'magit-popup-previous-winconf))
+    (when winconf
+      (set-window-configuration winconf))))
+
+(defun magit-popup-read-number (prompt &optional default)
+  "Like `read-number' but DEFAULT may be a numeric string."
+  (read-number prompt (if (stringp default)
+                          (string-to-number default)
+                        default)))
+
+;;; Save
+
+(defun magit-popup-set-default-arguments (arg)
+  "Set default value for the arguments for the current popup.
+Then close the popup without invoking an action; unless a prefix
+argument is used in which case the popup remains open.
+
+For a popup named `NAME-popup' that usually means setting the
+value of the custom option `NAME-arguments'."
+  (interactive "P")
+  (-if-let (var (magit-popup-get :variable))
+      (progn (customize-set-variable var (magit-popup-get-args))
+             (unless arg (magit-popup-quit)))
+    (user-error "Nothing to set")))
+
+(defun magit-popup-save-default-arguments (arg)
+  "Save default value for the arguments for the current popup.
+Then close the popup without invoking an action; unless a prefix
+argument is used in which case the popup remains open.
+
+For a popup named `NAME-popup' that usually means saving the
+value of the custom option `NAME-arguments'."
+  (interactive "P")
+  (-if-let (var (magit-popup-get :variable))
+      (progn (customize-save-variable var (magit-popup-get-args))
+             (unless arg (magit-popup-quit)))
+    (user-error "Nothing to save")))
+
+;;; Help
+
+(defun magit-popup-toggle-show-common-commands ()
+  "Show or hide an additional section with common commands.
+The commands listed in this section are common to all popups
+and are defined in `magit-popup-mode-map' (which see)."
+  (interactive)
+  (setq magit-popup-show-common-commands
+        (not magit-popup-show-common-commands))
+  (magit-refresh-popup-buffer)
+  (fit-window-to-buffer))
+
+(defun magit-popup-help ()
+  "Show help for the argument or action at point."
+  (interactive)
+  (let* ((man (magit-popup-get :man-page))
+         (key (read-key-sequence
+               (concat "Describe key" (and man " (? for manpage)") ": ")))
+         (int (aref key (1- (length key))))
+         (def (or (lookup-key (current-local-map)  key t)
+                  (lookup-key (current-global-map) key))))
+    (pcase def
+      (`magit-invoke-popup-switch
+       (--if-let (magit-popup-lookup int :switches)
+           (if (and (string-prefix-p "++" (magit-popup-event-arg it))
+                    (magit-popup-event-fun it))
+               (magit-popup-describe-function (magit-popup-event-fun it))
+             (magit-popup-manpage man it))
+         (user-error "%c isn't bound to any switch" int)))
+      (`magit-invoke-popup-option
+       (--if-let (magit-popup-lookup int :options)
+           (if (and (string-prefix-p "++" (magit-popup-event-arg it))
+                    (magit-popup-event-fun it))
+               (magit-popup-describe-function (magit-popup-event-fun it))
+             (magit-popup-manpage man it))
+         (user-error "%c isn't bound to any option" int)))
+      (`magit-popup-help
+       (magit-popup-manpage man nil))
+      ((or `self-insert-command
+           `magit-invoke-popup-action)
+       (setq def (or (magit-popup-lookup int :actions)
+                     (magit-popup-lookup int :variables)))
+       (if def
+           (magit-popup-describe-function (magit-popup-event-fun def))
+         (ding)
+         (message nil)))
+      (`nil (ding)
+            (message nil))
+      (_    (magit-popup-describe-function def)))))
+
+(defun magit-popup-manpage (topic arg)
+  (unless topic
+    (user-error "No man page associated with %s"
+                (magit-popup-get :man-page)))
+  (when arg
+    (setq arg (magit-popup-event-arg arg))
+    (when (string-prefix-p "--" arg)
+      ;; handle '--' option and the '--[no-]' shorthand
+      (setq arg (cond ((string= "-- " arg)
+                       "\\(?:\\[--\\] \\)?<[^[:space:]]+>\\.\\.\\.")
+                      ((string-prefix-p "--no-" arg)
+                       (concat "--"
+                               "\\[?no-\\]?"
+                               (substring arg 5)))
+                      (t
+                       (concat "--"
+                               "\\(?:\\[no-\\]\\)?"
+                               (substring arg 2)))))))
+  (let ((winconf (current-window-configuration)) buffer)
+    (pcase magit-popup-manpage-package
+      (`woman (delete-other-windows)
+              (split-window-below)
+              (with-no-warnings ; display-buffer-function is obsolete
+                (let ((display-buffer-alist nil)
+                      (display-buffer-function nil)
+                      (display-buffer-overriding-action nil))
+                  (woman topic)))
+              (setq buffer (current-buffer)))
+      (`man   (cl-letf (((symbol-function #'fboundp) (lambda (_) nil)))
+                (setq buffer (man topic)))
+              (delete-other-windows)
+              (split-window-below)
+              (set-window-buffer (selected-window) buffer)))
+    (with-current-buffer buffer
+      (setq magit-popup-previous-winconf winconf)
+      (magit-popup-help-mode)
+      (fit-window-to-buffer (next-window))
+      (if (and arg
+               (Man-find-section "OPTIONS")
+               (let ((case-fold-search nil)
+                     ;; This matches preceding/proceeding options.
+                     ;; Options such as '-a', '-S[<keyid>]', and
+                     ;; '--grep=<pattern>' are matched by this regex
+                     ;; without the shy group. The '. ' in the shy
+                     ;; group is for options such as '-m
+                     ;; parent-number', and the '-[^[:space:]]+ ' is
+                     ;; for options such as '--mainline parent-number'
+                     (others "-\\(?:. \\|-[^[:space:]]+ \\)?[^[:space:]]+"))
+                 (re-search-forward
+                  ;; should start with whitespace, and may have any
+                  ;; number of options before/after
+                  (format "^[\t\s]+\\(?:%s, \\)*?\\(?1:%s\\)%s\\(?:, %s\\)*$"
+                          others
+                          ;; options don't necessarily end in an '='
+                          ;; (e.g., '--gpg-sign[=<keyid>]')
+                          (string-remove-suffix "=" arg)
+                          ;; Simple options don't end in an '='.
+                          ;; Splitting this into 2 cases should make
+                          ;; getting false positives less likely.
+                          (if (string-suffix-p "=" arg)
+                              ;; [^[:space:]]*[^.[:space:]] matches
+                              ;; the option value, which is usually
+                              ;; after the option name and either '='
+                              ;; or '[='. The value can't end in a
+                              ;; period, as that means it's being used
+                              ;; at the end of a sentence. The space
+                              ;; is for options such as '--mainline
+                              ;; parent-number'.
+                              "\\(?: \\|\\[?=\\)[^[:space:]]*[^.[:space:]]"
+                            ;; Either this doesn't match anything
+                            ;; (e.g., '-a'), or the option is followed
+                            ;; by a value delimited by a '[', '<', or
+                            ;; ':'. A space might appear before this
+                            ;; value, as in '-f <file>'. The space
+                            ;; alternative is for options such as '-m
+                            ;; parent-number'.
+                            "\\(?:\\(?: \\| ?[\\[<:]\\)[^[:space:]]*[^.[:space:]]\\)?")
+                          others)
+                  nil
+                  t)))
+          (goto-char (match-beginning 1))
+        (goto-char (point-min))))))
+
+(defun magit-popup-describe-function (function)
+  (let ((winconf (current-window-configuration)))
+    (delete-other-windows)
+    (split-window-below)
+    (other-window 1)
+    (with-no-warnings ; display-buffer-function is obsolete
+      (let ((display-buffer-alist '(("" display-buffer-use-some-window)))
+            (display-buffer-function nil)
+            (display-buffer-overriding-action nil)
+            (help-window-select nil))
+        (describe-function function)))
+    (fit-window-to-buffer)
+    (other-window 1)
+    (setq magit-popup-previous-winconf winconf)
+    (magit-popup-help-mode)))
+
+(defun magit-popup-info ()
+  "Show the popup manual."
+  (interactive)
+  (let ((winconf (current-window-configuration)))
+    (delete-other-windows)
+    (split-window-below)
+    (info "(magit-popup.info)Usage")
+    (magit-popup-help-mode)
+    (setq magit-popup-previous-winconf winconf))
+  (magit-popup-help-mode)
+  (fit-window-to-buffer (next-window)))
+
+(define-minor-mode magit-popup-help-mode
+  "Auxiliary minor mode used to restore previous window configuration.
+When some sort of help buffer is created from within a popup,
+then this minor mode is turned on in that buffer, so that when
+the user quits it, the previous window configuration is also
+restored."
+  :keymap '(([remap Man-quit]    . magit-popup-quit)
+            ([remap Info-exit]   . magit-popup-quit)
+            ([remap quit-window] . magit-popup-quit)))
+
+;;; Modes
+
+(define-derived-mode magit-popup-mode fundamental-mode "MagitPopup"
+  "Major mode for infix argument popups."
+  :mode 'magit-popup
+  (setq truncate-lines t)
+  (setq buffer-read-only t)
+  (setq-local scroll-margin 0)
+  (setq-local magit-popup-show-common-commands magit-popup-show-common-commands)
+  (hack-dir-local-variables-non-file-buffer))
+
+(put 'magit-popup-mode 'mode-class 'special)
+
+(defun magit-popup-default-setup (val def)
+  (if (--when-let (magit-popup-get :sequence-predicate)
+        (funcall it))
+      (magit-popup-put :actions (magit-popup-convert-actions
+                                 val (magit-popup-get :sequence-actions)))
+    (let ((vars (plist-get def :variables)))
+      (when (functionp vars)
+        (setq vars (funcall vars)))
+      (when vars
+        (magit-popup-put :variables (magit-popup-convert-variables val vars))))
+    (magit-popup-put :switches (magit-popup-convert-switches
+                                val (plist-get def :switches)))
+    (magit-popup-put :options  (magit-popup-convert-options
+                                val (plist-get def :options)))
+    (magit-popup-put :actions  (magit-popup-convert-actions
+                                val (plist-get def :actions)))))
+
+(defun magit-popup-mode-setup (popup mode)
+  (setq magit-previous-popup magit-current-popup)
+  (let ((val (symbol-value (plist-get (symbol-value popup) :variable)))
+        (def (symbol-value popup))
+        (buf (current-buffer)))
+    (magit-popup-mode-display-buffer (get-buffer-create
+                                      (format "*%s*" popup))
+                                     (or mode 'magit-popup-mode))
+    (setq magit-this-popup popup)
+    (setq magit-pre-popup-buffer buf)
+    (if (bound-and-true-p magit-popup-setup-hook) ; obsolete
+        (run-hook-with-args 'magit-popup-setup-hook val def)
+      (funcall (or (magit-popup-get :setup-function)
+                   'magit-popup-default-setup)
+               val def)))
+  (magit-refresh-popup-buffer)
+  (fit-window-to-buffer nil nil (line-number-at-pos (point-max))))
+
+(defun magit-popup-mode-display-buffer (buffer mode)
+  (let ((winconf (current-window-configuration)))
+    (select-window (display-buffer buffer magit-popup-display-buffer-action))
+    (funcall mode)
+    (setq magit-popup-previous-winconf winconf)))
+
+(defvar magit-refresh-popup-buffer-hook nil
+  "Hook run by `magit-refresh-popup-buffer'.
+
+The hook is run right after inserting the representation of the
+popup events but before optionally inserting the representation
+of events shared by all popups and before point is adjusted.")
+
+(defun magit-refresh-popup-buffer ()
+  (let* ((inhibit-read-only t)
+         (button (button-at (point)))
+         (prefix (and button (button-get button 'prefix)))
+         (event  (and button (button-get button 'event))))
+    (erase-buffer)
+    (save-excursion
+      (--if-let (magit-popup-get :refresh-function)
+          (funcall it)
+        (magit-popup-insert-section 'magit-popup-variable-button)
+        (magit-popup-insert-section 'magit-popup-switch-button)
+        (magit-popup-insert-section 'magit-popup-option-button)
+        (magit-popup-insert-section 'magit-popup-action-button))
+      (run-hooks 'magit-refresh-popup-buffer-hook)
+      (when magit-popup-show-common-commands
+        (magit-popup-insert-command-section
+         'magit-popup-internal-command-button
+         magit-popup-common-commands)))
+    (set-buffer-modified-p nil)
+    (when event
+      (while (and (ignore-errors (forward-button 1))
+                  (let ((b (button-at (point))))
+                    (or (not (equal (button-get b 'prefix) prefix))
+                        (not (equal (button-get b 'event)  event)))))))))
+
+;;; Draw
+
+(defvar magit-popup-min-padding 3
+  "Minimal amount of whitespace between columns in popup buffers.")
+
+(defun magit-popup-insert-section (type &optional spec heading)
+  (if (not spec)
+      (progn (setq spec (magit-popup-get (button-type-get type 'property)))
+             (when spec
+               (if (or (stringp (car spec))
+                       (functionp (car spec)))
+                   (--each (--partition-by-header
+                            (or (stringp it) (functionp it))
+                            spec)
+                     (magit-popup-insert-section type (cdr it) (car it)))
+                 (magit-popup-insert-section type spec))))
+    (let* ((formatter (button-type-get type 'formatter))
+           (items (mapcar (lambda (ev)
+                            (and ev (or (funcall formatter type ev) '(""))))
+                          (or spec (magit-popup-get
+                                    (button-type-get type 'property)))))
+           (maxcols (button-type-get type 'maxcols))
+           (pred (magit-popup-get :sequence-predicate)))
+      (when items
+        (if (functionp heading)
+            (when (setq heading (funcall heading))
+              (insert heading ?\n))
+          (unless heading
+            (setq heading (button-type-get type 'heading)))
+          (insert (propertize heading 'face 'magit-popup-heading))
+          (unless (string-match "\n$" heading)
+            (insert "\n")))
+        (if (and pred (funcall pred))
+            (setq maxcols nil)
+          (cl-typecase maxcols
+            (keyword (setq maxcols (magit-popup-get maxcols)))
+            (symbol  (setq maxcols (symbol-value maxcols)))))
+        (when (functionp maxcols)
+          (setq maxcols (funcall maxcols heading)))
+        (when heading
+          (let ((colwidth
+                 (+ (apply 'max (mapcar (lambda (e) (length (car e))) items))
+                    magit-popup-min-padding)))
+            (dolist (item items)
+              (unless (bolp)
+                (let ((padding (- colwidth (% (current-column) colwidth))))
+                  (if (and (< (+ (current-column) padding colwidth)
+                              (window-width))
+                           (< (ceiling (/ (current-column) (* colwidth 1.0)))
+                              (or maxcols 1000)))
+                      (insert (make-string padding ?\s))
+                    (insert "\n"))))
+              (unless (equal item '(""))
+                (if item
+                    (apply 'insert-button item)
+                  (insert ?\s)))))
+          (insert (if (= (char-before) ?\n) "\n" "\n\n")))))))
+
+(defun magit-popup-format-argument-button (type ev)
+  (list (format-spec
+         (button-type-get type 'format)
+         `((?k . ,(propertize (concat
+                               (--when-let (button-type-get type 'prefix)
+                                 (char-to-string it))
+                               (magit-popup-event-keydsc ev))
+                              'face 'magit-popup-key))
+           (?d . ,(magit-popup-event-dsc ev))
+           (?a . ,(propertize (magit-popup-event-arg ev)
+                              'face (if (magit-popup-event-use ev)
+                                        'magit-popup-argument
+                                      'magit-popup-disabled-argument)))
+           (?v . ,(let ((val (magit-popup-event-val ev)))
+                    (if (and (magit-popup-event-use ev)
+                             (not (equal val "")))
+                        (propertize (format "\"%s\"" val)
+                                    'face 'magit-popup-option-value)
+                      "")))))
+        'type type 'event (magit-popup-event-key ev)))
+
+(defun magit-popup-format-variable-button (type ev)
+  (if (not (magit-popup-event-arg ev))
+      (magit-popup-format-action-button 'magit-popup-action-button ev)
+    (list (format-spec
+           (button-type-get type 'format)
+           `((?k . ,(propertize (magit-popup-event-keydsc ev)
+                                'face 'magit-popup-key))
+             (?d . ,(funcall (magit-popup-event-arg ev)))))
+          'type type 'event (magit-popup-event-key ev))))
+
+(defun magit-popup-format-action-button (type ev)
+  (let* ((cmd (magit-popup-event-fun ev))
+         (dsc (magit-popup-event-dsc ev))
+         (fun (and (functionp dsc) dsc)))
+    (unless (and disabled-command-function
+                 (symbolp cmd)
+                 (get cmd 'disabled))
+      (when fun
+        (setq dsc
+              (-when-let (branch (funcall fun))
+                (if (text-property-not-all 0 (length branch) 'face nil branch)
+                    branch
+                  (magit-branch-set-face branch)))))
+      (when dsc
+        (list (format-spec
+               (button-type-get type 'format)
+               `((?k . ,(propertize (magit-popup-event-keydsc ev)
+                                    'face 'magit-popup-key))
+                 (?d . ,dsc)
+                 (?D . ,(if (and (not fun)
+                                 (eq cmd (magit-popup-get :default-action)))
+                            (propertize dsc 'face 'bold)
+                          dsc))))
+              'type type 'event (magit-popup-event-key ev))))))
+
+(defun magit-popup-insert-command-section (type spec)
+  (magit-popup-insert-section
+   type (mapcar (lambda (elt)
+                  (list (car (where-is-internal (cadr elt)
+                                                (current-local-map)))
+                        (car elt)))
+                spec)))
+
+(defun magit-popup-format-command-button (type elt)
+  (nconc (magit-popup-format-action-button
+          type (make-magit-popup-event :key (car  elt)
+                                       :dsc (cadr elt)))
+         (list 'function (lookup-key (current-local-map) (car elt)))))
+
+;;; Utilities
+
+(defun magit-popup-import-file-args (args files)
+  (if files
+      (cons (concat "-- " (mapconcat #'identity files ",")) args)
+    args))
+
+(defun magit-popup-export-file-args (args)
+  (let ((files (--first (string-prefix-p "-- " it) args)))
+    (when files
+      (setq args  (remove files args))
+      (setq files (split-string (substring files 3) ",")))
+    (list args files)))
+
+(defconst magit-popup-font-lock-keywords
+  (eval-when-compile
+    `((,(concat "(\\(magit-define-popup\\)\\_>"
+                "[ \t'\(]*"
+                "\\(\\(?:\\sw\\|\\s_\\)+\\)?")
+       (1 'font-lock-keyword-face)
+       (2 'font-lock-function-name-face nil t)))))
+
+(font-lock-add-keywords 'emacs-lisp-mode magit-popup-font-lock-keywords)
+
+;;; _
+(provide 'magit-popup)
+;; Local Variables:
+;; indent-tabs-mode: nil
+;; End:
+;;; magit-popup.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/magit-popup-20180618.1602/magit-popup.elc b/configs/shared/emacs/.emacs.d/elpa/magit-popup-20180618.1602/magit-popup.elc
new file mode 100644
index 0000000000..70b5367986
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-popup-20180618.1602/magit-popup.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/magit-popup-20180618.1602/magit-popup.info b/configs/shared/emacs/.emacs.d/elpa/magit-popup-20180618.1602/magit-popup.info
new file mode 100644
index 0000000000..835c816193
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/magit-popup-20180618.1602/magit-popup.info
@@ -0,0 +1,740 @@
+This is magit-popup.info, produced by makeinfo version 6.1 from
+magit-popup.texi.
+
+     Copyright (C) 2015-2018 Jonas Bernoulli <jonas@bernoul.li>
+
+     You can redistribute this document 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.
+
+     This document 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.
+INFO-DIR-SECTION Emacs
+START-INFO-DIR-ENTRY
+* Magit-Popup: (magit-popup). Infix arguments with feedback.
+END-INFO-DIR-ENTRY
+
+
+File: magit-popup.info,  Node: Top,  Next: Introduction,  Up: (dir)
+
+Magit-Popup User Manual
+***********************
+
+Taking inspiration from regular prefix commands and prefix arguments,
+this library implements a similar abstraction; a new kind of prefix
+command that is associated with a specific set of infix arguments and
+suffix commands.
+
+This manual is for Magit-Popup version 2.12.3 (v2.12.3-3-g60ff82a+1).
+
+     Copyright (C) 2015-2018 Jonas Bernoulli <jonas@bernoul.li>
+
+     You can redistribute this document 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.
+
+     This document 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.
+
+* Menu:
+
+* Introduction::
+* Usage::
+* Defining Prefix and Suffix Commands::
+
+— The Detailed Node Listing —
+
+Usage
+
+* Customizing Existing Popups::
+* Other Options::
+
+Defining Prefix and Suffix Commands
+
+* Defining Prefix Commands::
+* Defining Suffix Commands::
+
+
+
+File: magit-popup.info,  Node: Introduction,  Next: Usage,  Prev: Top,  Up: Top
+
+1 Introduction
+**************
+
+Taking inspiration from regular prefix commands and prefix arguments,
+this library implements a similar abstraction; a new kind of prefix
+command that is associated with a specific set of infix arguments and
+suffix commands.
+
+   Invoking such a prefix command displays a popup buffer which lists
+the associated infix arguments and suffix commands.  In that buffer each
+argument is prefixed with the key sequence that can be used to toggle it
+or change its value.  Likewise each suffix command is prefixed with the
+key used to invoke it.  Such a popup buffer might look like this:
+
+     ,-----------------------------------------
+     |Switches
+     | -l Show graph (--graph)
+     | -d Show refnames (--decorate)
+     |
+     |Options
+     | =m Search messages (--grep="popup")
+     | =p Search patches (-G)
+     |
+     |Action
+     | l Show log for current branch
+     | o Show log for another branch
+     '-----------------------------------------
+
+   The user could then for example type ‘-l’ to toggle the ‘--graph’
+*switch* (when it is on then it is shown in green, otherwise in gray),
+or ‘=m’ to change the value of the *option* ‘--grep’.
+
+   Once all arguments are as desired one invokes a suffix command, which
+causes the popup buffer to disappear.  The suffix command should then
+retrieve the infix arguments in its ‘interactive’ form like this is done
+for prefix arguments.
+
+   While such "prefix-infix-suffix" combos were inspired by regular
+prefix commands and prefix arguments, they are also quite different.
+This should illustrate the most basic differences:
+
+   • A regular prefix command
+
+                  /- command1
+          prefix --- command2
+                  \- command3
+
+   • Prefix arguments
+
+                   /- command1
+          C-u ... --- command2
+                   \- well any command
+
+   • A Prefix-Infix-Suffix combo
+
+                   /- argument1 -\ /- suffix1
+          prefix----- argument2 --+-- suffix2
+                 ^ \- argument3 -/
+                 |        |
+                 '--------'
+              (refresh buffer)
+
+   This library was written as a replacement for ‘magit-key-mode’, which
+was used in Magit releases before 2.1.0.  It is used to implement all
+"popups" in the current Magit release but a future release will switch
+to yet another implementation.
+
+   This library does not depend on any other Magit libraries and it is
+distributed as a separate package, which makes it possible to use it in
+packages that are not related to Magit.  But keep in mind that it will
+be deprecated eventually.
+
+
+File: magit-popup.info,  Node: Usage,  Next: Defining Prefix and Suffix Commands,  Prev: Introduction,  Up: Top
+
+2 Usage
+*******
+
+Every popup buffers created with a prefix command contains a section
+named "Actions" listing the available suffix commands.  Most buffers
+also contain a "Switches" and/or an "Options" section which list the two
+types of infix arguments separately.
+
+   Switches are arguments that can be toggled on or off.  When a switch
+is active then it is shown in color, when it is off then it is shown in
+gray (of course the details depend on the color theme in use).
+
+   Options are arguments that have a value.  When an option has a value
+then that is shown after the option itself.  Because for some options
+the empty string is a valid value, options are additionally colorized
+like switches to indicate whether they are active or not.
+
+   The events bound to suffix commands are always single alphabetic
+characters.  The bindings for arguments are always two events long.  For
+switches the first key is always ‘-’, for options it is always ‘=’.  The
+second key is always an alphabetic character.
+
+   By default popup buffers also feature a section listing commands
+common to all popups.  To avoid conflicts with suffix commands, the
+bindings of these common commands are not alphabetic characters.  This
+section is shown by default so that documentation-resistant users get a
+chance to notice them.
+
+ -- User Option: magit-popup-show-common-commands
+
+     This option controls whether the section that lists the commands
+     that are common to all popups is initially shown.
+
+     By default this is not the case, but note that you can temporarily
+     show this section using ‘C-t’, which therefore is the only common
+     command you actually have to memorize.
+
+‘C-t’     (‘magit-popup-toggle-show-common-commands’)
+
+     Show or hide the section listing the commands shared by all popups.
+
+‘C-g’     (‘magit-popup-quit’)
+
+     Quit popup buffer without invoking a suffix command.
+
+   Without further action, setting arguments only affects the next
+suffix command.  Invoking the same prefix command again resets the
+arguments to their default value, but the defaults can be changed
+directly from the popup buffer itself.  For a prefix command named
+‘NAME-popup’ the default values are stored as the value of the custom
+option named ‘NAME-arguments’.  While this option can be customized
+using the Custom interface, it is better to do so directly from the
+popup buffer.
+
+‘C-c C-c’     (‘magit-popup-set-default-arguments’)
+
+     This sets the default value for the arguments for the current
+     popup.
+
+     Then the popup buffer is closed without invoking a suffix command;
+     unless a prefix argument is used in which case the popup remains
+     open.
+
+‘C-x C-s’     (‘magit-popup-save-default-arguments’)
+
+     This sets the default value for the arguments for the current popup
+     and saves it for future Emacs sessions.
+
+     Then the popup buffer is closed without invoking an action; unless
+     a prefix argument is used in which case the popup remains open.
+
+   It is also possible to add additional arguments and commands to an
+existing popup, but that cannot be done directly from the popup (or the
+Custom interface).  See *note Customizing Existing Popups::.
+
+   Documentation about a popup’s arguments and commands can be shown
+directly from the popup.
+
+‘C-h i’     (‘magit-popup-info’)
+
+     Show this manual.
+
+‘?’     (‘magit-popup-help’)
+
+     This command reads a key sequence and then shows the documentation
+     of the argument or command that sequence is bound to.  In other
+     words type the same keys that you would use to invoke the argument
+     or command, but prefix the sequence with ‘?’.
+
+     For suffix commands this shows the doc-string.  For arguments this
+     command can only show something for popups that have an associated
+     man-page.  If the man-page is set, then this command displays it in
+     a separate buffer and puts point on the entry about the argument in
+     question.
+
+     The buffer which is used to display the documentation is selected.
+     Simply press ‘q’ to leave that buffer and restore the old window
+     configuration.
+
+   While it isn’t very useful, it is possible to move around in a popup
+buffer using ‘C-p’ and ‘C-n’, and to invoke the argument or command at
+point using ‘RET’.  But it is much more efficient to use the dedicated
+key bindings instead, so these commands are not listed in popup buffers
+along with the other common commands.
+
+* Menu:
+
+* Customizing Existing Popups::
+* Other Options::
+
+
+File: magit-popup.info,  Node: Customizing Existing Popups,  Next: Other Options,  Up: Usage
+
+2.1 Customizing Existing Popups
+===============================
+
+It is possible to define additional infix arguments and suffix commands
+to an existing popup using the following functions.
+
+   You can find some examples which use the below commands at
+<https://github.com/magit/magit/wiki/Additional-proposed-infix-arguments-and-suffix-commands>.
+
+ -- Function: magit-define-popup-switch popup key desc switch &optional
+          enable at prepend
+
+     In POPUP, define KEY as SWITCH.
+
+     POPUP is a popup command defined using ‘magit-define-popup’.
+     SWITCH is a string representing an argument that takes no value.
+     KEY is a character representing the second event in the sequence of
+     keystrokes used to toggle the argument.  (The first event, the
+     prefix, is shared among all switches, defaults to ‘-’, and can be
+     changed in ‘magit-popup-mode-keymap’).
+
+     DESC is a string describing the purpose of the argument, it is
+     displayed in the popup.
+
+     If optional ENABLE is non-nil then the switch is on by default.
+
+     SWITCH is inserted after all other switches already defined for
+     POPUP, unless optional PREPEND is non-nil, in which case it is
+     placed first.  If optional AT is non-nil then it should be the KEY
+     of another switch already defined for POPUP, the argument is then
+     placed before or after AT, depending on PREPEND.
+
+ -- Function: magit-define-popup-option popup key desc option &optional
+          reader value at prepend
+
+     In POPUP, define KEY as OPTION.
+
+     POPUP is a popup command defined using ‘magit-define-popup’.
+     OPTION is a string representing an argument that takes a value.
+     KEY is a character representing the second event in the sequence of
+     keystrokes used to set the argument’s value.  (The first event, the
+     prefix, is shared among all options, defaults to ‘=’, and can be
+     changed in ‘magit-popup-mode-keymap’).
+
+     DESC is a string describing the purpose of the argument, it is
+     displayed in the popup.
+
+     If optional VALUE is non-nil then the option is on by default, and
+     VALUE is its default value.
+
+     READER is used to read a value from the user when the option is
+     invoked and does not currently have a value.  It should take one
+     argument and use it as the prompt.  If this is nil, then
+     ‘read-from-minibuffer’ is used.
+
+     OPTION is inserted after all other options already defined for
+     POPUP, unless optional PREPEND is non-nil, in which case it is
+     placed first.  If optional AT is non-nil then it should be the KEY
+     of another option already defined for POPUP, the argument is then
+     placed before or after AT, depending on PREPEND.
+
+ -- Function: magit-define-popup-action popup key desc command &optional
+          at prepend
+
+     In POPUP, define KEY as COMMAND.
+
+     POPUP is a popup command defined using ‘magit-define-popup’.
+     COMMAND can be any command but should usually consume the popup
+     arguments in its ‘interactive’ form.  KEY is a character
+     representing the event used invoke the action, i.e.  to
+     interactively call the COMMAND.
+
+     DESC is a string describing the purpose of the action, it is
+     displayed in the popup.
+
+     COMMAND is inserted after all other commands already defined for
+     POPUP, unless optional PREPEND is non-nil, in which case it is
+     placed first.  If optional AT is non-nil then it should be the KEY
+     of another command already defined for POPUP, the command is then
+     placed before or after AT, depending on PREPEND.
+
+ -- Function: magit-define-popup-sequence-action popup key desc command
+          &optional at prepend
+
+     Like ‘magit-define-popup-action’, but modifies the value of the
+     ‘:sequence-actions’ property instead of ‘:actions’.
+
+ -- Function: magit-define-popup-variable popup key desc command
+          formatter &optional at prepend
+
+     In POPUP, define KEY as COMMAND.
+
+     POPUP is a popup command defined using ‘magit-define-popup’.
+     COMMAND is a command which calls ‘magit-popup-set-variable’.
+     FORMATTER is a function which calls ‘magit-popup-format-variable’.
+     These two functions have to be called with the same arguments.
+
+     KEY is a character representing the event used interactively call
+     the COMMAND.
+
+     DESC is the variable or a representation thereof.  It’s not
+     actually used for anything.
+
+     COMMAND is inserted after all other commands already defined for
+     POPUP, unless optional PREPEND is non-nil, in which case it is
+     placed first.  If optional AT is non-nil then it should be the KEY
+     of another command already defined for POPUP, the command is then
+     placed before or after AT, depending on PREPEND."
+
+ -- Function: magit-change-popup-key popup type from to
+
+     In POPUP, bind TO to what FROM was bound to.  TYPE is one of
+     ‘:action’, ‘:sequence-action’, ‘:switch’, or ‘:option’.  Bind TO
+     and unbind FROM, both are characters.
+
+ -- Function: magit-remove-popup-key popup type key
+
+     In POPUP, remove KEY’s binding of TYPE.  POPUP is a popup command
+     defined using ‘magit-define-popup’.  TYPE is one of ‘:action’,
+     ‘:sequence-action’, ‘:switch’, or ‘:option’.  KEY is the character
+     which is to be unbound.
+
+   It is also possible to change other aspects of a popup by setting a
+property using ‘plist-put’.  See *note Defining Prefix Commands:: for
+valid properties.  The most likely change Magit users might want to make
+is:
+
+     (plist-put magit-show-refs-popup :use-prefix nil)
+
+
+File: magit-popup.info,  Node: Other Options,  Prev: Customizing Existing Popups,  Up: Usage
+
+2.2 Other Options
+=================
+
+ -- User Option: magit-popup-use-prefix-argument
+
+     This option controls the effect that the use of a prefix argument
+     before entering a popup has.
+
+        • ‘default’
+
+          With a prefix argument directly invoke the popup’s default
+          action (an Emacs command), instead of bringing up the popup.
+
+        • ‘popup’
+
+          With a prefix argument bring up the popup, otherwise directly
+          invoke the popup’s default action.
+
+        • ‘nil’
+
+          Ignore prefix arguments.
+
+     This option can be overridden for individual popups.
+     ‘magit-show-refs-popup’ for example defaults to invoking the
+     default action directly.  It only shows the popup buffer when a
+     prefix argument is used.  See *note Customizing Existing Popups::.
+
+ -- User Option: magit-popup-manpage-package
+
+     The Emacs package used to display man-pages, one of ‘man’ or
+     ‘woman’.
+
+ -- User Option: magit-popup-display-buffer-action
+
+     The option controls how the window used to display a popup buffer
+     is created.  Popup buffers are displayed using ‘display-buffer’
+     with the value of this option as ACTION argument.  You can also set
+     this to nil and instead add an entry to ‘display-buffer-alist’.
+
+   To emphasize the default action by making it bold use this:
+
+     (button-type-put 'magit-popup-action-button 'format " %k %D")
+
+
+File: magit-popup.info,  Node: Defining Prefix and Suffix Commands,  Prev: Usage,  Up: Top
+
+3 Defining Prefix and Suffix Commands
+*************************************
+
+If you write an extension for Magit then you should use this library now
+and later when ‘transient’ is released port to that.
+
+   If you are considering using this library to define popups for
+packages not related to Magit, then keep in mind that it will be
+superseded eventually.  Once ‘transient’ has been released I will only
+fix bugs in ‘magit-popup’ but not implement any new features.
+
+   Also consider using ‘hydra’ instead.  To some extend ‘magit-popup’
+and ‘hydra’ are similar but have a different focus.  The main purpose of
+‘magit-popup’ is to pass infix arguments to suffix commands.  If all you
+need is a command dispatcher then you are better of using ‘hydra’.  Of
+course ‘hydra’ may also be a better fit not only because of the features
+it lacks, but also because of the features it provides, which are in
+turn missing from ‘magit-popup’.
+
+   Here is an example of how one defines a prefix command along with its
+infix arguments, and then also one of its suffix commands.
+
+     ;;;###autoload (autoload 'magit-tag-popup "magit" nil t)
+     (magit-define-popup magit-tag-popup
+       "Show popup buffer featuring tagging commands."
+       'magit-commands
+       :man-page "git-tag"
+       :switches '((?a "Annotate" "--annotate")
+                   (?s "Sign"     "--sign")
+                   (?f "Force"    "--force"))
+       :actions  '((?t "Create"   magit-tag)
+                   (?k "Delete"   magit-tag-delete)
+                   (?p "Prune"    magit-tag-prune))
+       :default-action 'magit-tag)
+
+     ;;;###autoload
+     (defun magit-tag (name rev &optional args)
+       "Create a new tag with the given NAME at REV."
+       (interactive (list (magit-read-tag "Tag name")
+                          (magit-read-branch-or-commit "Place tag on")
+                          (magit-tag-arguments)))
+       (magit-run-git-with-editor "tag" args name rev))
+
+* Menu:
+
+* Defining Prefix Commands::
+* Defining Suffix Commands::
+
+
+File: magit-popup.info,  Node: Defining Prefix Commands,  Next: Defining Suffix Commands,  Up: Defining Prefix and Suffix Commands
+
+3.1 Defining Prefix Commands
+============================
+
+Prefix commands and their infix arguments are defined using the macro
+‘magit-define-popup’.  The key bindings and descriptions of suffix
+commands are also defined using that macro, but the actual interactive
+commands have to be defined separately using plain ‘defun’.
+
+ -- Macro: magit-define-popup name doc [group [mode [option]]] :keyword
+          value...
+
+     This macro defines a popup named NAME.  The NAME should begin with
+     the package prefix and by convention end with ‘-popup’, it is used
+     as the name of the command which shows the popup and for an
+     internal variable (whose value is used to store information about
+     the popup and should not be accessed directly).  DOC is the
+     doc-string of the popup command.
+
+     This macro also defines an option and a function both named
+     ‘SHORTNAME-arguments’, where SHORTNAME is NAME with the trailing
+     ‘-popup’ removed.  The name of this option and this function can be
+     overwritten using the optional argument OPTION, but that is rarely
+     advisable.  As a special case if OPTION is specified but ‘nil’,
+     then this option and this function are not defined at all, which is
+     useful for popups that are used as simple dispatchers that offer no
+     arguments.
+
+     The option ‘SHORTNAME-arguments’ holds the value for the popup
+     arguments.  It can be customized from within the popup or using the
+     Custom interface.  It can also have a buffer local value in any
+     non-popup buffer.  The local value for the buffer from which the
+     popup command was invoked, can be set from within the popup buffer.
+
+     The function ‘SHORTNAME-arguments’ returns the currently effective
+     value of the variable by the same name.  See below for more
+     information.
+
+     Optional argument GROUP specifies the Custom group into which the
+     option is placed.  If omitted then the option is placed into some
+     group the same way it is done when directly using ‘defcustom’ and
+     omitting the group, except when NAME begins with "magit-", in which
+     case the group ‘magit-git-arguments’ is used.
+
+     The optional argument MODE specifies the mode used by the popup
+     buffer.  If it is omitted or ‘nil’ then ‘magit-popup-mode’ is used.
+
+     The remaining arguments should have the form ‘[KEYWORD VALUE]...’.
+
+     The following keywords are meaningful (and by convention are
+     usually specified in that order):
+
+        • ‘:actions’
+
+          The actions which can be invoked from the popup.  VALUE is a
+          list whose members have the form (KEY DESC COMMAND), see
+          ‘magit-define-popup-action’ for details.
+
+          Actions are regular Emacs commands, which usually have an
+          ‘interactive’ form setup to consume the values of the popup
+          ‘:switches’ and ‘:options’ when invoked from the corresponding
+          popup, else when invoked as the default action or directly
+          without using the popup, the default value of the variable
+          ‘SHORTNAME-arguments’.  This is usually done by calling the
+          function ‘SHORTNAME-arguments’.
+
+          Members of VALUE may also be strings and functions, assuming
+          the first member is a string or function.  In that case the
+          members are split into sections and these special elements are
+          used as headings.  If such an element is a function then it is
+          called with no arguments and must return either a string,
+          which is used as the heading, or nil, in which case the
+          section is not inserted.
+
+          Members of VALUE may also be nil.  This should only be used
+          together with ‘:max-action-columns’ and allows having gaps in
+          the action grit, which can help arranging actions sensibly.
+
+        • ‘:default-action’
+
+          The default action of the popup which is used directly instead
+          of displaying the popup buffer, when the popup is invoked with
+          a prefix argument.  Also see ‘magit-popup-use-prefix-argument’
+          and ‘:use-prefix’, which can be used to inverse the meaning of
+          the prefix argument.
+
+        • ‘:use-prefix’
+
+          Controls when to display the popup buffer and when to invoke
+          the default action (if any) directly.  This overrides the
+          global default set using ‘magit-popup-use-prefix-argument’.
+          The value, if specified, should be one of ‘default’ or
+          ‘prefix’, or a function that is called with no arguments and
+          returns one of these symbols.
+
+        • ‘:max-action-columns’
+
+          The maximum number of actions to display on a single line, a
+          number or a function that return a number and takes the name
+          of the section currently being inserted as argument.  If there
+          isn’t enough room to display as many columns as specified
+          here, then fewer are used.
+
+        • ‘:switches’
+
+          The popup arguments which can be toggled on and off.  VALUE is
+          a list whose members have the form ‘(KEY DESC SWITCH)’, see
+          ‘magit-define-popup-switch’ for details.
+
+          Members of VALUE may also be strings and functions, assuming
+          the first member is a string or function.  In that case the
+          members are split into sections and these special elements are
+          used as headings.  If such an element is a function then it is
+          called with no arguments and must return either a string,
+          which is used as the heading, or nil, in which case the
+          section is not inserted.
+
+        • ‘:options’
+
+          The popup arguments which take a value, as in "–opt~OPTVAL".
+          VALUE is a list whose members have the form ‘(KEY DESC OPTION
+          READER)’, see ‘magit-define-popup-option’ for details.
+
+          Members of VALUE may also be strings and functions, assuming
+          the first member is a string or function.  In that case the
+          members are split into sections and these special elements are
+          used as headings.  If such an element is a function then it is
+          called with no arguments and must return either a string,
+          which is used as the heading, or nil, in which case the
+          section is not inserted.
+
+        • ‘:default-arguments’
+
+          The default arguments, a list of switches (which are then
+          enabled by default) and options with there default values, as
+          in ‘"--OPT=OPTVAL"’.
+
+        • ‘:variables’
+
+          Git variables which can be set from the popup.  VALUE is a
+          list whose members have the form ‘(KEY DESC COMMAND
+          FORMATTER)’, see ‘magit-define-popup-variable’ for details.
+
+          Members of VALUE may also be strings and functions, assuming
+          the first member is a string or function.  In that case the
+          members are split into sections and these special elements are
+          used as headings.  If such an element is a function then it is
+          called with no arguments and must return either a string,
+          which is used as the heading, or nil, in which case the
+          section is not inserted.
+
+          Members of VALUE may also be actions as described above for
+          ‘:actions’.
+
+          VALUE may also be a function that returns a list as describe
+          above.
+
+        • ‘:sequence-predicate’
+
+          When this function returns non-nil, then the popup uses
+          ‘:sequence-actions’ instead of ‘:actions’, and does not show
+          the ‘:switches’ and ‘:options’.
+
+        • ‘:sequence-actions’
+
+          The actions which can be invoked from the popup, when
+          ‘:sequence-predicate’ returns non-nil.
+
+        • ‘:setup-function’
+
+          When this function is specified, then it is used instead of
+          ‘magit-popup-default-setup’.
+
+        • ‘:refresh-function’
+
+          When this function is specified, then it is used instead of
+          calling ‘magit-popup-insert-section’ three times with symbols
+          ‘magit-popup-switch-button’, ‘magit-popup-option-button’, and
+          finally ‘magit-popup-action-button’ as argument.
+
+        • ‘:man-page’
+
+          The name of the manpage to be displayed when the user requests
+          help for an argument.
+
+
+File: magit-popup.info,  Node: Defining Suffix Commands,  Prev: Defining Prefix Commands,  Up: Defining Prefix and Suffix Commands
+
+3.2 Defining Suffix Commands
+============================
+
+Commands intended to be invoked from a particular popup should determine
+the currently effective arguments by calling the function
+‘SHORTNAME-arguments’ inside their ‘interactive’ form.  This function is
+created by the ‘magit-define-popup’ macro.  For a popup named
+‘prefix-foo-popup’ the name of this function is ‘prefix-foo-arguments’.
+
+   When the command was invoked as an action in the respective popup,
+then this function returns the arguments that were set in the popup.
+Otherwise when the command was invoked as the default of the popup (by
+calling the popup command with a prefix argument), or without using the
+popup command at all, then this function returns the buffer-local or
+global value of the variable ‘SHORTNAME-arguments’.
+
+   Internally arguments are handled as a list of strings.  This might
+not be appropriate for the intended use inside commands, or it might be
+necessary to manipulate that list somehow, i.e.  to split "–ARG=VAL"
+into "–ARG""VAL". This should be done by advising or redefining the
+function ‘SHORTNAME-arguments’.
+
+   Internally ‘SHORNAME-arguments’ used following variables and
+function.  Except when redefining the former, you should not use these
+directly.
+
+ -- Variable: magit-current-popup
+
+     The popup from which this editing command was invoked.
+
+ -- Variable: magit-current-popup-args
+
+     The value of the popup arguments for this editing command.
+
+     If the current command was invoked from a popup, then this is a
+     list of strings of all the set switches and options.  This includes
+     arguments which are set by default not only those explicitly set
+     during this invocation.
+
+     When the value is nil, then that can be because no argument is set,
+     or because the current command wasn’t invoked from a popup at all.
+
+ -- Function: magit-current-popup-args &rest args
+
+     This function returns the value of the popup arguments for this
+     editing command.  The value is the same as that of the variable by
+     the same name, except that FILTER is applied.  FILTER is a list of
+     regexps; only arguments that match one of them are returned.  The
+     first element of FILTER may also be ‘:not’ in which case only
+     arguments that don’t match any of the regexps are returned, or
+     ‘:only’ which doesn’t change the behavior.
+
+
+
+Tag Table:
+Node: Top769
+Node: Introduction2015
+Node: Usage4714
+Node: Customizing Existing Popups9411
+Node: Other Options15158
+Node: Defining Prefix and Suffix Commands16701
+Node: Defining Prefix Commands18853
+Node: Defining Suffix Commands27552
+
+End Tag Table
+
+
+Local Variables:
+coding: utf-8
+End:
diff --git a/configs/shared/emacs/.emacs.d/elpa/markdown-mode-20180707.555/markdown-mode-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/markdown-mode-20180707.555/markdown-mode-autoloads.el
new file mode 100644
index 0000000000..16cd6722d2
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/markdown-mode-20180707.555/markdown-mode-autoloads.el
@@ -0,0 +1,46 @@
+;;; markdown-mode-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "markdown-mode" "markdown-mode.el" (23377 60993
+;;;;;;  760407 404000))
+;;; Generated autoloads from markdown-mode.el
+
+(autoload 'markdown-mode "markdown-mode" "\
+Major mode for editing Markdown files.
+
+\(fn)" t nil)
+
+(add-to-list 'auto-mode-alist '("\\.markdown\\'" . markdown-mode))
+
+(add-to-list 'auto-mode-alist '("\\.md\\'" . markdown-mode))
+
+(autoload 'gfm-mode "markdown-mode" "\
+Major mode for editing GitHub Flavored Markdown files.
+
+\(fn)" t nil)
+
+(autoload 'markdown-view-mode "markdown-mode" "\
+Major mode for viewing Markdown content.
+
+\(fn)" t nil)
+
+(autoload 'gfm-view-mode "markdown-mode" "\
+Major mode for viewing GitHub Flavored Markdown content.
+
+\(fn)" t nil)
+
+(autoload 'markdown-live-preview-mode "markdown-mode" "\
+Toggle native previewing on save for a specific markdown file.
+
+\(fn &optional ARG)" t nil)
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; markdown-mode-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/markdown-mode-20180707.555/markdown-mode-pkg.el b/configs/shared/emacs/.emacs.d/elpa/markdown-mode-20180707.555/markdown-mode-pkg.el
new file mode 100644
index 0000000000..3adb2b3185
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/markdown-mode-20180707.555/markdown-mode-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "markdown-mode" "20180707.555" "Major mode for Markdown-formatted text" '((emacs "24.4") (cl-lib "0.5")))
diff --git a/configs/shared/emacs/.emacs.d/elpa/markdown-mode-20180707.555/markdown-mode.el b/configs/shared/emacs/.emacs.d/elpa/markdown-mode-20180707.555/markdown-mode.el
new file mode 100644
index 0000000000..5039b8fe4e
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/markdown-mode-20180707.555/markdown-mode.el
@@ -0,0 +1,9612 @@
+;;; markdown-mode.el --- Major mode for Markdown-formatted text -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2007-2017 Jason R. Blevins and markdown-mode
+;; contributors (see the commit log for details).
+
+;; Author: Jason R. Blevins <jblevins@xbeta.org>
+;; Maintainer: Jason R. Blevins <jblevins@xbeta.org>
+;; Created: May 24, 2007
+;; Version: 2.4-dev
+;; Package-Version: 20180707.555
+;; Package-Requires: ((emacs "24.4") (cl-lib "0.5"))
+;; Keywords: Markdown, GitHub Flavored Markdown, itex
+;; URL: https://jblevins.org/projects/markdown-mode/
+
+;; This file is not part of GNU Emacs.
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; See the README.md file for details.
+
+
+;;; Code:
+
+(require 'easymenu)
+(require 'outline)
+(require 'thingatpt)
+(require 'cl-lib)
+(require 'url-parse)
+(require 'button)
+(require 'color)
+(require 'rx)
+
+(defvar jit-lock-start)
+(defvar jit-lock-end)
+(defvar flyspell-generic-check-word-predicate)
+
+(declare-function eww-open-file "eww")
+(declare-function url-path-and-query "url-parse")
+
+
+;;; Constants =================================================================
+
+(defconst markdown-mode-version "2.4-dev"
+  "Markdown mode version number.")
+
+(defconst markdown-output-buffer-name "*markdown-output*"
+  "Name of temporary buffer for markdown command output.")
+
+
+;;; Global Variables ==========================================================
+
+(defvar markdown-reference-label-history nil
+  "History of used reference labels.")
+
+(defvar markdown-live-preview-mode nil
+  "Sentinel variable for command `markdown-live-preview-mode'.")
+
+(defvar markdown-gfm-language-history nil
+  "History list of languages used in the current buffer in GFM code blocks.")
+
+
+;;; Customizable Variables ====================================================
+
+(defvar markdown-mode-hook nil
+  "Hook run when entering Markdown mode.")
+
+(defvar markdown-before-export-hook nil
+  "Hook run before running Markdown to export XHTML output.
+The hook may modify the buffer, which will be restored to it's
+original state after exporting is complete.")
+
+(defvar markdown-after-export-hook nil
+  "Hook run after XHTML output has been saved.
+Any changes to the output buffer made by this hook will be saved.")
+
+(defgroup markdown nil
+  "Major mode for editing text files in Markdown format."
+  :prefix "markdown-"
+  :group 'text
+  :link '(url-link "https://jblevins.org/projects/markdown-mode/"))
+
+(defcustom markdown-command "markdown"
+  "Command to run markdown."
+  :group 'markdown
+  :type '(choice (string :tag "Shell command") function))
+
+(defcustom markdown-command-needs-filename nil
+  "Set to non-nil if `markdown-command' does not accept input from stdin.
+Instead, it will be passed a filename as the final command line
+option.  As a result, you will only be able to run Markdown from
+buffers which are visiting a file."
+  :group 'markdown
+  :type 'boolean)
+
+(defcustom markdown-open-command nil
+  "Command used for opening Markdown files directly.
+For example, a standalone Markdown previewer.  This command will
+be called with a single argument: the filename of the current
+buffer.  It can also be a function, which will be called without
+arguments."
+  :group 'markdown
+  :type '(choice file function (const :tag "None" nil)))
+
+(defcustom markdown-hr-strings
+  '("-------------------------------------------------------------------------------"
+    "* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *"
+    "---------------------------------------"
+    "* * * * * * * * * * * * * * * * * * * *"
+    "---------"
+    "* * * * *")
+  "Strings to use when inserting horizontal rules.
+The first string in the list will be the default when inserting a
+horizontal rule.  Strings should be listed in decreasing order of
+prominence (as in headings from level one to six) for use with
+promotion and demotion functions."
+  :group 'markdown
+  :type '(repeat string))
+
+(defcustom markdown-bold-underscore nil
+  "Use two underscores when inserting bold text instead of two asterisks."
+  :group 'markdown
+  :type 'boolean)
+
+(defcustom markdown-italic-underscore nil
+  "Use underscores when inserting italic text instead of asterisks."
+  :group 'markdown
+  :type 'boolean)
+
+(defcustom markdown-marginalize-headers nil
+  "When non-nil, put opening atx header markup in a left margin.
+
+This setting goes well with `markdown-asymmetric-header'.  But
+sadly it conflicts with `linum-mode' since they both use the
+same margin."
+  :group 'markdown
+  :type 'boolean
+  :safe 'booleanp
+  :package-version '(markdown-mode . "2.4"))
+
+(defcustom markdown-marginalize-headers-margin-width 6
+  "Character width of margin used for marginalized headers.
+The default value is based on there being six heading levels
+defined by Markdown and HTML.  Increasing this produces extra
+whitespace on the left.  Decreasing it may be preferred when
+fewer than six nested heading levels are used."
+  :group 'markdown
+  :type 'natnump
+  :safe 'natnump
+  :package-version '(markdown-mode . "2.4"))
+
+(defcustom markdown-asymmetric-header nil
+  "Determines if atx header style will be asymmetric.
+Set to a non-nil value to use asymmetric header styling, placing
+header markup only at the beginning of the line. By default,
+balanced markup will be inserted at the beginning and end of the
+line around the header title."
+  :group 'markdown
+  :type 'boolean)
+
+(defcustom markdown-indent-function 'markdown-indent-line
+  "Function to use to indent."
+  :group 'markdown
+  :type 'function)
+
+(defcustom markdown-indent-on-enter t
+  "Determines indentation behavior when pressing \\[newline].
+Possible settings are nil, t, and 'indent-and-new-item.
+
+When non-nil, pressing \\[newline] will call `newline-and-indent'
+to indent the following line according to the context using
+`markdown-indent-function'.  In this case, note that
+\\[electric-newline-and-maybe-indent] can still be used to insert
+a newline without indentation.
+
+When set to 'indent-and-new-item and the point is in a list item
+when \\[newline] is pressed, the list will be continued on the next
+line, where a new item will be inserted.
+
+When set to nil, simply call `newline' as usual.  In this case,
+you can still indent lines using \\[markdown-cycle] and continue
+lists with \\[markdown-insert-list-item].
+
+Note that this assumes the variable `electric-indent-mode' is
+non-nil (enabled).  When it is *disabled*, the behavior of
+\\[newline] and `\\[electric-newline-and-maybe-indent]' are
+reversed."
+  :group 'markdown
+  :type '(choice (const :tag "Don't automatically indent" nil)
+                 (const :tag "Automatically indent" t)
+                 (const :tag "Automatically indent and insert new list items" indent-and-new-item)))
+
+(defcustom markdown-enable-wiki-links nil
+  "Syntax highlighting for wiki links.
+Set this to a non-nil value to turn on wiki link support by default.
+Support can be toggled later using the `markdown-toggle-wiki-links'
+function or \\[markdown-toggle-wiki-links]."
+  :group 'markdown
+  :type 'boolean
+  :safe 'booleanp
+  :package-version '(markdown-mode . "2.2"))
+
+(defcustom markdown-wiki-link-alias-first t
+  "When non-nil, treat aliased wiki links like [[alias text|PageName]].
+Otherwise, they will be treated as [[PageName|alias text]]."
+  :group 'markdown
+  :type 'boolean
+  :safe 'booleanp)
+
+(defcustom markdown-wiki-link-search-subdirectories nil
+  "When non-nil, search for wiki link targets in subdirectories.
+This is the default search behavior for GitHub and is
+automatically set to t in `gfm-mode'."
+  :group 'markdown
+  :type 'boolean
+  :safe 'booleanp
+  :package-version '(markdown-mode . "2.2"))
+
+(defcustom markdown-wiki-link-search-parent-directories nil
+  "When non-nil, search for wiki link targets in parent directories.
+This is the default search behavior of Ikiwiki."
+  :group 'markdown
+  :type 'boolean
+  :safe 'booleanp
+  :package-version '(markdown-mode . "2.2"))
+
+(defcustom markdown-wiki-link-fontify-missing nil
+  "When non-nil, change wiki link face according to existence of target files.
+This is expensive because it requires checking for the file each time the buffer
+changes or the user switches windows.  It is disabled by default because it may
+cause lag when typing on slower machines."
+  :group 'markdown
+  :type 'boolean
+  :safe 'booleanp
+  :package-version '(markdown-mode . "2.2"))
+
+(defcustom markdown-uri-types
+  '("acap" "cid" "data" "dav" "fax" "file" "ftp"
+    "gopher" "http" "https" "imap" "ldap" "mailto"
+    "mid" "message" "modem" "news" "nfs" "nntp"
+    "pop" "prospero" "rtsp" "service" "sip" "tel"
+    "telnet" "tip" "urn" "vemmi" "wais")
+  "Link types for syntax highlighting of URIs."
+  :group 'markdown
+  :type '(repeat (string :tag "URI scheme")))
+
+(defcustom markdown-url-compose-char
+  '(?∞ ?… ?⋯ ?# ?★ ?⚓)
+  "Placeholder character for hidden URLs.
+This may be a single character or a list of characters. In case
+of a list, the first one that satisfies `char-displayable-p' will
+be used."
+  :type '(choice
+          (character :tag "Single URL replacement character")
+          (repeat :tag "List of possible URL replacement characters"
+                  character))
+  :package-version '(markdown-mode . "2.3"))
+
+(defcustom markdown-blockquote-display-char
+  '("▌" "┃" ">")
+  "String to display when hiding blockquote markup.
+This may be a single string or a list of string. In case of a
+list, the first one that satisfies `char-displayable-p' will be
+used."
+  :type 'string
+  :type '(choice
+          (string :tag "Single blockquote display string")
+          (repeat :tag "List of possible blockquote display strings" string))
+  :package-version '(markdown-mode . "2.3"))
+
+(defcustom markdown-hr-display-char
+  '(?─ ?━ ?-)
+  "Character for hiding horizontal rule markup.
+This may be a single character or a list of characters.  In case
+of a list, the first one that satisfies `char-displayable-p' will
+be used."
+  :group 'markdown
+  :type '(choice
+          (character :tag "Single HR display character")
+          (repeat :tag "List of possible HR display characters" character))
+  :package-version '(markdown-mode . "2.3"))
+
+(defcustom markdown-definition-display-char
+  '(?⁘ ?⁙ ?≡ ?⌑ ?◊ ?:)
+  "Character for replacing definition list markup.
+This may be a single character or a list of characters.  In case
+of a list, the first one that satisfies `char-displayable-p' will
+be used."
+  :type '(choice
+          (character :tag "Single definition list character")
+          (repeat :tag "List of possible definition list characters" character))
+  :package-version '(markdown-mode . "2.3"))
+
+(defcustom markdown-enable-math nil
+  "Syntax highlighting for inline LaTeX and itex expressions.
+Set this to a non-nil value to turn on math support by default.
+Math support can be enabled, disabled, or toggled later using
+`markdown-toggle-math' or \\[markdown-toggle-math]."
+  :group 'markdown
+  :type 'boolean
+  :safe 'booleanp)
+(make-variable-buffer-local 'markdown-enable-math)
+
+(defcustom markdown-enable-html t
+  "Enable font-lock support for HTML tags and attributes."
+  :group 'markdown
+  :type 'boolean
+  :safe 'booleanp
+  :package-version '(markdown-mode . "2.4"))
+
+(defcustom markdown-css-paths nil
+  "URL of CSS file to link to in the output XHTML."
+  :group 'markdown
+  :type '(repeat (string :tag "CSS File Path")))
+
+(defcustom markdown-content-type ""
+  "Content type string for the http-equiv header in XHTML output.
+When set to a non-empty string, insert the http-equiv attribute.
+Otherwise, this attribute is omitted."
+  :group 'markdown
+  :type 'string)
+
+(defcustom markdown-coding-system nil
+  "Character set string for the http-equiv header in XHTML output.
+Defaults to `buffer-file-coding-system' (and falling back to
+`iso-8859-1' when not available).  Common settings are `utf-8'
+and `iso-latin-1'.  Use `list-coding-systems' for more choices."
+  :group 'markdown
+  :type 'coding-system)
+
+(defcustom markdown-export-kill-buffer t
+  "Kill output buffer after HTML export.
+When non-nil, kill the HTML output buffer after
+exporting with `markdown-export'."
+  :group 'markdown
+  :type 'boolean
+  :safe 'booleanp
+  :package-version '(markdown-mode . "2.4"))
+
+(defcustom markdown-xhtml-header-content ""
+  "Additional content to include in the XHTML <head> block."
+  :group 'markdown
+  :type 'string)
+
+(defcustom markdown-xhtml-body-preamble ""
+  "Content to include in the XHTML <body> block, before the output."
+  :group 'markdown
+  :type 'string
+  :safe 'stringp
+  :package-version '(markdown-mode . "2.4"))
+
+(defcustom markdown-xhtml-body-epilogue ""
+  "Content to include in the XHTML <body> block, after the output."
+  :group 'markdown
+  :type 'string
+  :safe 'stringp
+  :package-version '(markdown-mode . "2.4"))
+
+(defcustom markdown-xhtml-standalone-regexp
+  "^\\(<\\?xml\\|<!DOCTYPE\\|<html\\)"
+  "Regexp indicating whether `markdown-command' output is standalone XHTML."
+  :group 'markdown
+  :type 'regexp)
+
+(defcustom markdown-link-space-sub-char "_"
+  "Character to use instead of spaces when mapping wiki links to filenames."
+  :group 'markdown
+  :type 'string)
+
+(defcustom markdown-reference-location 'header
+  "Position where new reference definitions are inserted in the document."
+  :group 'markdown
+  :type '(choice (const :tag "At the end of the document" end)
+                 (const :tag "Immediately after the current block" immediately)
+                 (const :tag "At the end of the subtree" subtree)
+                 (const :tag "Before next header" header)))
+
+(defcustom markdown-footnote-location 'end
+  "Position where new footnotes are inserted in the document."
+  :group 'markdown
+  :type '(choice (const :tag "At the end of the document" end)
+                 (const :tag "Immediately after the current block" immediately)
+                 (const :tag "At the end of the subtree" subtree)
+                 (const :tag "Before next header" header)))
+
+(defcustom markdown-footnote-display '((raise 0.2) (height 0.8))
+  "Display specification for footnote markers and inline footnotes.
+By default, footnote text is reduced in size and raised.  Set to
+nil to disable this."
+  :group 'markdown
+  :type '(choice (sexp :tag "Display specification")
+                 (const :tag "Don't set display property" nil))
+  :package-version '(markdown-mode . "2.4"))
+
+(defcustom markdown-sub-superscript-display
+  '(((raise -0.3) (height 0.7)) . ((raise 0.3) (height 0.7)))
+  "Display specification for subscript and superscripts.
+The car is used for subscript, the cdr is used for superscripts."
+  :group 'markdown
+  :type '(cons (choice (sexp :tag "Subscript form")
+                       (const :tag "No lowering" nil))
+               (choice (sexp :tag "Superscript form")
+                       (const :tag "No raising" nil)))
+  :package-version '(markdown-mode . "2.4"))
+
+(defcustom markdown-unordered-list-item-prefix "  * "
+  "String inserted before unordered list items."
+  :group 'markdown
+  :type 'string)
+
+(defcustom markdown-nested-imenu-heading-index t
+  "Use nested or flat imenu heading index.
+A nested index may provide more natural browsing from the menu,
+but a flat list may allow for faster keyboard navigation via tab
+completion."
+  :group 'markdown
+  :type 'boolean
+  :safe 'booleanp
+  :package-version '(markdown-mode . "2.2"))
+
+(defcustom markdown-add-footnotes-to-imenu t
+  "Add footnotes to end of imenu heading index."
+  :group 'markdown
+  :type 'boolean
+  :safe 'booleanp
+  :package-version '(markdown-mode . "2.4"))
+
+(defcustom markdown-make-gfm-checkboxes-buttons t
+  "When non-nil, make GFM checkboxes into buttons."
+  :group 'markdown
+  :type 'boolean)
+
+(defcustom markdown-use-pandoc-style-yaml-metadata nil
+  "When non-nil, allow YAML metadata anywhere in the document."
+  :group 'markdown
+  :type 'boolean)
+
+(defcustom markdown-split-window-direction 'any
+  "Preference for splitting windows for static and live preview.
+The default value is 'any, which instructs Emacs to use
+`split-window-sensibly' to automatically choose how to split
+windows based on the values of `split-width-threshold' and
+`split-height-threshold' and the available windows.  To force
+vertically split (left and right) windows, set this to 'vertical
+or 'right.  To force horizontally split (top and bottom) windows,
+set this to 'horizontal or 'below."
+  :group 'markdown
+  :type '(choice (const :tag "Automatic" any)
+                 (const :tag "Right (vertical)" right)
+                 (const :tag "Below (horizontal)" below))
+  :package-version '(markdown-mode . "2.2"))
+
+(defcustom markdown-live-preview-window-function
+  'markdown-live-preview-window-eww
+  "Function to display preview of Markdown output within Emacs.
+Function must update the buffer containing the preview and return
+the buffer."
+  :group 'markdown
+  :type 'function)
+
+(defcustom markdown-live-preview-delete-export 'delete-on-destroy
+  "Delete exported HTML file when using `markdown-live-preview-export'.
+If set to 'delete-on-export, delete on every export. When set to
+'delete-on-destroy delete when quitting from command
+`markdown-live-preview-mode'. Never delete if set to nil."
+  :group 'markdown
+  :type '(choice
+          (const :tag "Delete on every export" delete-on-export)
+          (const :tag "Delete when quitting live preview" delete-on-destroy)
+          (const :tag "Never delete" nil)))
+
+(defcustom markdown-list-indent-width 4
+  "Depth of indentation for markdown lists.
+Used in `markdown-demote-list-item' and
+`markdown-promote-list-item'."
+  :group 'markdown
+  :type 'integer)
+
+(defcustom markdown-enable-prefix-prompts t
+  "Display prompts for certain prefix commands.
+Set to nil to disable these prompts."
+  :group 'markdown
+  :type 'boolean
+  :safe 'booleanp
+  :package-version '(markdown-mode . "2.3"))
+
+(defcustom markdown-gfm-additional-languages nil
+  "Extra languages made available when inserting GFM code blocks.
+Language strings must have be trimmed of whitespace and not
+contain any curly braces. They may be of arbitrary
+capitalization, though."
+  :group 'markdown
+  :type '(repeat (string :validate markdown-validate-language-string)))
+
+(defcustom markdown-gfm-use-electric-backquote t
+  "Use `markdown-electric-backquote' when backquote is hit three times."
+  :group 'markdown
+  :type 'boolean)
+
+(defcustom markdown-gfm-downcase-languages t
+  "If non-nil, downcase suggested languages.
+This applies to insertions done with
+`markdown-electric-backquote'."
+  :group 'markdown
+  :type 'boolean)
+
+(defcustom markdown-edit-code-block-default-mode 'normal-mode
+  "Default mode to use for editing code blocks.
+This mode is used when automatic detection fails, such as for GFM
+code blocks with no language specified."
+  :group 'markdown
+  :type '(choice function (const :tag "None" nil))
+  :package-version '(markdown-mode . "2.4"))
+
+(defcustom markdown-gfm-uppercase-checkbox nil
+  "If non-nil, use [X] for completed checkboxes, [x] otherwise."
+  :group 'markdown
+  :type 'boolean
+  :safe 'booleanp)
+
+(defcustom markdown-hide-urls nil
+  "Hide URLs of inline links and reference tags of reference links.
+Such URLs will be replaced by a single customizable
+character, defined by `markdown-url-compose-char', but are still part
+of the buffer.  Links can be edited interactively with
+\\[markdown-insert-link] or, for example, by deleting the final
+parenthesis to remove the invisibility property. You can also
+hover your mouse pointer over the link text to see the URL.
+Set this to a non-nil value to turn this feature on by default.
+You can interactively set the value of this variable by calling
+`markdown-toggle-url-hiding', pressing \\[markdown-toggle-url-hiding],
+or from the menu Markdown > Links & Images menu."
+  :group 'markdown
+  :type 'boolean
+  :safe 'booleanp
+  :package-version '(markdown-mode . "2.3"))
+(make-variable-buffer-local 'markdown-hide-urls)
+
+(defcustom markdown-translate-filename-function #'identity
+  "Function to use to translate filenames when following links.
+\\<markdown-mode-map>\\[markdown-follow-thing-at-point] and \\[markdown-follow-link-at-point]
+call this function with the filename as only argument whenever
+they encounter a filename (instead of a URL) to be visited and
+use its return value instead of the filename in the link.  For
+example, if absolute filenames are actually relative to a server
+root directory, you can set
+`markdown-translate-filename-function' to a function that
+prepends the root directory to the given filename."
+  :group 'markdown
+  :type 'function
+  :risky t
+  :package-version '(markdown-mode . "2.4"))
+
+(defcustom markdown-max-image-size nil
+  "Maximum width and height for displayed inline images.
+This variable may be nil or a cons cell (MAX-WIDTH . MAX-HEIGHT).
+When nil, use the actual size.  Otherwise, use ImageMagick to
+resize larger images to be of the given maximum dimensions.  This
+requires Emacs to be built with ImageMagick support."
+  :group 'markdown
+  :package-version '(markdown-mode . "2.4")
+  :type '(choice
+          (const :tag "Use actual image width" nil)
+          (cons (choice (sexp :tag "Maximum width in pixels")
+                        (const :tag "No maximum width" nil))
+                (choice (sexp :tag "Maximum height in pixels")
+                        (const :tag "No maximum height" nil)))))
+
+
+;;; Markdown-Specific `rx' Macro
+
+;; Based on python-rx from python.el.
+(eval-and-compile
+  (defconst markdown-rx-constituents
+    `((newline . ,(rx "\n"))
+      (indent . ,(rx (or (repeat 4 " ") "\t")))
+      (block-end . ,(rx (and (or (one-or-more (zero-or-more blank) "\n") line-end))))
+      (numeral . ,(rx (and (one-or-more (any "0-9#")) ".")))
+      (bullet . ,(rx (any "*+:-")))
+      (list-marker . ,(rx (or (and (one-or-more (any "0-9#")) ".")
+                              (any "*+:-"))))
+      (checkbox . ,(rx "[" (any " xX") "]")))
+    "Markdown-specific sexps for `markdown-rx'")
+
+  (defun markdown-rx-to-string (form &optional no-group)
+    "Markdown mode specialized `rx-to-string' function.
+This variant supports named Markdown expressions in FORM.
+NO-GROUP non-nil means don't put shy groups around the result."
+    (let ((rx-constituents (append markdown-rx-constituents rx-constituents)))
+      (rx-to-string form no-group)))
+
+  (defmacro markdown-rx (&rest regexps)
+    "Markdown mode specialized rx macro.
+This variant of `rx' supports common Markdown named REGEXPS."
+    (cond ((null regexps)
+           (error "No regexp"))
+          ((cdr regexps)
+           (markdown-rx-to-string `(and ,@regexps) t))
+          (t
+           (markdown-rx-to-string (car regexps) t)))))
+
+
+;;; Regular Expressions =======================================================
+
+(defconst markdown-regex-comment-start
+  "<!--"
+  "Regular expression matches HTML comment opening.")
+
+(defconst markdown-regex-comment-end
+  "--[ \t]*>"
+  "Regular expression matches HTML comment closing.")
+
+(defconst markdown-regex-link-inline
+  "\\(!\\)?\\(\\[\\)\\([^]^][^]]*\\|\\)\\(\\]\\)\\((\\)\\([^)]*?\\)\\(?:\\s-+\\(\"[^\"]*\"\\)\\)?\\()\\)"
+  "Regular expression for a [text](file) or an image link ![text](file).
+Group 1 matches the leading exclamation point (optional).
+Group 2 matches the opening square bracket.
+Group 3 matches the text inside the square brackets.
+Group 4 matches the closing square bracket.
+Group 5 matches the opening parenthesis.
+Group 6 matches the URL.
+Group 7 matches the title (optional).
+Group 8 matches the closing parenthesis.")
+
+(defconst markdown-regex-link-reference
+  "\\(!\\)?\\(\\[\\)\\([^]^][^]]*\\|\\)\\(\\]\\)[ ]?\\(\\[\\)\\([^]]*?\\)\\(\\]\\)"
+  "Regular expression for a reference link [text][id].
+Group 1 matches the leading exclamation point (optional).
+Group 2 matches the opening square bracket for the link text.
+Group 3 matches the text inside the square brackets.
+Group 4 matches the closing square bracket for the link text.
+Group 5 matches the opening square bracket for the reference label.
+Group 6 matches the reference label.
+Group 7 matches the closing square bracket for the reference label.")
+
+(defconst markdown-regex-reference-definition
+  "^ \\{0,3\\}\\(\\[\\)\\([^]\n]+?\\)\\(\\]\\)\\(:\\)\\s *\\(.*?\\)\\s *\\( \"[^\"]*\"$\\|$\\)"
+  "Regular expression for a reference definition.
+Group 1 matches the opening square bracket.
+Group 2 matches the reference label.
+Group 3 matches the closing square bracket.
+Group 4 matches the colon.
+Group 5 matches the URL.
+Group 6 matches the title attribute (optional).")
+
+(defconst markdown-regex-footnote
+  "\\(\\[\\^\\)\\(.+?\\)\\(\\]\\)"
+  "Regular expression for a footnote marker [^fn].
+Group 1 matches the opening square bracket and carat.
+Group 2 matches only the label, without the surrounding markup.
+Group 3 matches the closing square bracket.")
+
+(defconst markdown-regex-header
+  "^\\(?:\\([^\r\n\t -].*\\)\n\\(?:\\(=+\\)\\|\\(-+\\)\\)\\|\\(#+[ \t]+\\)\\(.*?\\)\\([ \t]*#*\\)\\)$"
+  "Regexp identifying Markdown headings.
+Group 1 matches the text of a setext heading.
+Group 2 matches the underline of a level-1 setext heading.
+Group 3 matches the underline of a level-2 setext heading.
+Group 4 matches the opening hash marks of an atx heading and whitespace.
+Group 5 matches the text, without surrounding whitespace, of an atx heading.
+Group 6 matches the closing whitespace and hash marks of an atx heading.")
+
+(defconst markdown-regex-header-setext
+  "^\\([^\r\n\t -].*\\)\n\\(=+\\|-+\\)$"
+  "Regular expression for generic setext-style (underline) headers.")
+
+(defconst markdown-regex-header-atx
+  "^\\(#+\\)[ \t]+\\(.*?\\)[ \t]*\\(#*\\)$"
+  "Regular expression for generic atx-style (hash mark) headers.")
+
+(defconst markdown-regex-hr
+  (rx line-start
+      (group (or (and (repeat 3 (and "*" (? " "))) (* (any "* ")))
+                 (and (repeat 3 (and "-" (? " "))) (* (any "- ")))
+                 (and (repeat 3 (and "_" (? " "))) (* (any "_ ")))))
+      line-end)
+  "Regular expression for matching Markdown horizontal rules.")
+
+(defconst markdown-regex-code
+  "\\(?:\\`\\|[^\\]\\)\\(\\(`+\\)\\(\\(?:.\\|\n[^\n]\\)*?[^`]\\)\\(\\2\\)\\)\\(?:[^`]\\|\\'\\)"
+  "Regular expression for matching inline code fragments.
+
+Group 1 matches the entire code fragment including the backquotes.
+Group 2 matches the opening backquotes.
+Group 3 matches the code fragment itself, without backquotes.
+Group 4 matches the closing backquotes.
+
+The leading, unnumbered group ensures that the leading backquote
+character is not escaped.
+The last group, also unnumbered, requires that the character
+following the code fragment is not a backquote.
+Note that \\(?:.\\|\n[^\n]\\) matches any character, including newlines,
+but not two newlines in a row.")
+
+(defconst markdown-regex-kbd
+  "\\(<kbd>\\)\\(\\(?:.\\|\n[^\n]\\)*?\\)\\(</kbd>\\)"
+  "Regular expression for matching <kbd> tags.
+Groups 1 and 3 match the opening and closing tags.
+Group 2 matches the key sequence.")
+
+(defconst markdown-regex-gfm-code-block-open
+  "^[[:blank:]]*\\(```\\)\\([[:blank:]]*{?[[:blank:]]*\\)\\([^[:space:]]+?\\)?\\(?:[[:blank:]]+\\(.+?\\)\\)?\\([[:blank:]]*}?[[:blank:]]*\\)$"
+  "Regular expression matching opening of GFM code blocks.
+Group 1 matches the opening three backquotes and any following whitespace.
+Group 2 matches the opening brace (optional) and surrounding whitespace.
+Group 3 matches the language identifier (optional).
+Group 4 matches the info string (optional).
+Group 5 matches the closing brace (optional), whitespace, and newline.
+Groups need to agree with `markdown-regex-tilde-fence-begin'.")
+
+(defconst markdown-regex-gfm-code-block-close
+ "^[[:blank:]]*\\(```\\)\\(\\s *?\\)$"
+ "Regular expression matching closing of GFM code blocks.
+Group 1 matches the closing three backquotes.
+Group 2 matches any whitespace and the final newline.")
+
+(defconst markdown-regex-pre
+  "^\\(    \\|\t\\).*$"
+  "Regular expression for matching preformatted text sections.")
+
+(defconst markdown-regex-list
+  (markdown-rx line-start
+               ;; 1. Leading whitespace
+               (group (* blank))
+               ;; 2. List marker: a numeral, bullet, or colon
+               (group list-marker)
+               ;; 3. Trailing whitespace
+               (group (+ blank))
+               ;; 4. Optional checkbox for GFM task list items
+               (opt (group (and checkbox (* blank)))))
+  "Regular expression for matching list items.")
+
+(defconst markdown-regex-bold
+  "\\(^\\|[^\\]\\)\\(\\([*_]\\{2\\}\\)\\([^ \n\t\\]\\|[^ \n\t]\\(?:.\\|\n[^\n]\\)*?[^\\ ]\\)\\(\\3\\)\\)"
+  "Regular expression for matching bold text.
+Group 1 matches the character before the opening asterisk or
+underscore, if any, ensuring that it is not a backslash escape.
+Group 2 matches the entire expression, including delimiters.
+Groups 3 and 5 matches the opening and closing delimiters.
+Group 4 matches the text inside the delimiters.")
+
+(defconst markdown-regex-italic
+  "\\(?:^\\|[^\\]\\)\\(\\([*_]\\)\\([^ \n\t\\]\\|[^ \n\t*]\\(?:.\\|\n[^\n]\\)*?[^\\ ]\\)\\(\\2\\)\\)"
+  "Regular expression for matching italic text.
+The leading unnumbered matches the character before the opening
+asterisk or underscore, if any, ensuring that it is not a
+backslash escape.
+Group 1 matches the entire expression, including delimiters.
+Groups 2 and 4 matches the opening and closing delimiters.
+Group 3 matches the text inside the delimiters.")
+
+(defconst markdown-regex-strike-through
+  "\\(^\\|[^\\]\\)\\(\\(~~\\)\\([^ \n\t\\]\\|[^ \n\t]\\(?:.\\|\n[^\n]\\)*?[^\\ ]\\)\\(~~\\)\\)"
+  "Regular expression for matching strike-through text.
+Group 1 matches the character before the opening tilde, if any,
+ensuring that it is not a backslash escape.
+Group 2 matches the entire expression, including delimiters.
+Groups 3 and 5 matches the opening and closing delimiters.
+Group 4 matches the text inside the delimiters.")
+
+(defconst markdown-regex-gfm-italic
+  "\\(?:^\\|\\s-\\)\\(\\([*_]\\)\\([^ \\]\\2\\|[^ ]\\(?:.\\|\n[^\n]\\)*?[^\\ ]\\)\\(\\2\\)\\)"
+  "Regular expression for matching italic text in GitHub Flavored Markdown.
+Underscores in words are not treated as special.
+Group 1 matches the entire expression, including delimiters.
+Groups 2 and 4 matches the opening and closing delimiters.
+Group 3 matches the text inside the delimiters.")
+
+(defconst markdown-regex-blockquote
+  "^[ \t]*\\([A-Z]?>\\)\\([ \t]*\\)\\(.*\\)$"
+  "Regular expression for matching blockquote lines.
+Also accounts for a potential capital letter preceding the angle
+bracket, for use with Leanpub blocks (asides, warnings, info
+blocks, etc.).
+Group 1 matches the leading angle bracket.
+Group 2 matches the separating whitespace.
+Group 3 matches the text.")
+
+(defconst markdown-regex-line-break
+  "[^ \n\t][ \t]*\\(  \\)$"
+  "Regular expression for matching line breaks.")
+
+(defconst markdown-regex-wiki-link
+  "\\(?:^\\|[^\\]\\)\\(\\(\\[\\[\\)\\([^]|]+\\)\\(?:\\(|\\)\\([^]]+\\)\\)?\\(\\]\\]\\)\\)"
+  "Regular expression for matching wiki links.
+This matches typical bracketed [[WikiLinks]] as well as 'aliased'
+wiki links of the form [[PageName|link text]].
+The meanings of the first and second components depend
+on the value of `markdown-wiki-link-alias-first'.
+
+Group 1 matches the entire link.
+Group 2 matches the opening square brackets.
+Group 3 matches the first component of the wiki link.
+Group 4 matches the pipe separator, when present.
+Group 5 matches the second component of the wiki link, when present.
+Group 6 matches the closing square brackets.")
+
+(defconst markdown-regex-uri
+  (concat "\\(" (regexp-opt markdown-uri-types) ":[^]\t\n\r<>,;() ]+\\)")
+  "Regular expression for matching inline URIs.")
+
+(defconst markdown-regex-angle-uri
+  (concat "\\(<\\)\\(" (regexp-opt markdown-uri-types) ":[^]\t\n\r<>,;()]+\\)\\(>\\)")
+  "Regular expression for matching inline URIs in angle brackets.")
+
+(defconst markdown-regex-email
+  "<\\(\\(?:\\sw\\|\\s_\\|\\s.\\)+@\\(?:\\sw\\|\\s_\\|\\s.\\)+\\)>"
+  "Regular expression for matching inline email addresses.")
+
+(defsubst markdown-make-regex-link-generic ()
+  "Make regular expression for matching any recognized link."
+  (concat "\\(?:" markdown-regex-link-inline
+          (when markdown-enable-wiki-links
+            (concat "\\|" markdown-regex-wiki-link))
+          "\\|" markdown-regex-link-reference
+          "\\|" markdown-regex-angle-uri "\\)"))
+
+(defconst markdown-regex-gfm-checkbox
+  " \\(\\[[ xX]\\]\\) "
+  "Regular expression for matching GFM checkboxes.
+Group 1 matches the text to become a button.")
+
+(defconst markdown-regex-blank-line
+  "^[[:blank:]]*$"
+  "Regular expression that matches a blank line.")
+
+(defconst markdown-regex-block-separator
+  "\n[\n\t\f ]*\n"
+  "Regular expression for matching block boundaries.")
+
+(defconst markdown-regex-block-separator-noindent
+  (concat "\\(\\`\\|\\(" markdown-regex-block-separator "\\)[^\n\t\f ]\\)")
+  "Regexp for block separators before lines with no indentation.")
+
+(defconst markdown-regex-math-inline-single
+  "\\(?:^\\|[^\\]\\)\\(\\$\\)\\(\\(?:[^\\$]\\|\\\\.\\)*\\)\\(\\$\\)"
+  "Regular expression for itex $..$ math mode expressions.
+Groups 1 and 3 match the opening and closing dollar signs.
+Group 2 matches the mathematical expression contained within.")
+
+(defconst markdown-regex-math-inline-double
+  "\\(?:^\\|[^\\]\\)\\(\\$\\$\\)\\(\\(?:[^\\$]\\|\\\\.\\)*\\)\\(\\$\\$\\)"
+  "Regular expression for itex $$..$$ math mode expressions.
+Groups 1 and 3 match opening and closing dollar signs.
+Group 2 matches the mathematical expression contained within.")
+
+(defconst markdown-regex-math-display
+  (rx line-start (* blank)
+      (group (group (repeat 1 2 "\\")) "[")
+      (group (*? anything))
+      (group (backref 2) "]")
+      line-end)
+  "Regular expression for \[..\] or \\[..\\] display math.
+Groups 1 and 4 match the opening and closing markup.
+Group 3 matches the mathematical expression contained within.
+Group 2 matches the opening slashes, and is used internally to
+match the closing slashes.")
+
+(defsubst markdown-make-tilde-fence-regex (num-tildes &optional end-of-line)
+  "Return regexp matching a tilde code fence at least NUM-TILDES long.
+END-OF-LINE is the regexp construct to indicate end of line; $ if
+missing."
+  (format "%s%d%s%s" "^[[:blank:]]*\\([~]\\{" num-tildes ",\\}\\)"
+          (or end-of-line "$")))
+
+(defconst markdown-regex-tilde-fence-begin
+  (markdown-make-tilde-fence-regex
+   3 "\\([[:blank:]]*{?\\)[[:blank:]]*\\([^[:space:]]+?\\)?\\(?:[[:blank:]]+\\(.+?\\)\\)?\\([[:blank:]]*}?[[:blank:]]*\\)$")
+  "Regular expression for matching tilde-fenced code blocks.
+Group 1 matches the opening tildes.
+Group 2 matches (optional) opening brace and surrounding whitespace.
+Group 3 matches the language identifier (optional).
+Group 4 matches the info string (optional).
+Group 5 matches the closing brace (optional) and any surrounding whitespace.
+Groups need to agree with `markdown-regex-gfm-code-block-open'.")
+
+(defconst markdown-regex-declarative-metadata
+  "^\\([[:alpha:]][[:alpha:] _-]*?\\)\\([:=][ \t]*\\)\\(.*\\)$"
+  "Regular expression for matching declarative metadata statements.
+This matches MultiMarkdown metadata as well as YAML and TOML
+assignments such as the following:
+
+    variable: value
+
+or
+
+    variable = value")
+
+(defconst markdown-regex-pandoc-metadata
+  "^\\(%\\)\\([ \t]*\\)\\(.*\\(?:\n[ \t]+.*\\)*\\)"
+  "Regular expression for matching Pandoc metadata.")
+
+(defconst markdown-regex-yaml-metadata-border
+  "\\(-\\{3\\}\\)$"
+  "Regular expression for matching YAML metadata.")
+
+(defconst markdown-regex-yaml-pandoc-metadata-end-border
+  "^\\(\\.\\{3\\}\\|\\-\\{3\\}\\)$"
+  "Regular expression for matching YAML metadata end borders.")
+
+(defsubst markdown-get-yaml-metadata-start-border ()
+  "Return YAML metadata start border depending upon whether Pandoc is used."
+  (concat
+   (if markdown-use-pandoc-style-yaml-metadata "^" "\\`")
+   markdown-regex-yaml-metadata-border))
+
+(defsubst markdown-get-yaml-metadata-end-border (_)
+  "Return YAML metadata end border depending upon whether Pandoc is used."
+  (if markdown-use-pandoc-style-yaml-metadata
+      markdown-regex-yaml-pandoc-metadata-end-border
+    markdown-regex-yaml-metadata-border))
+
+(defconst markdown-regex-inline-attributes
+  "[ \t]*\\({:?\\)[ \t]*\\(\\(#[[:alpha:]_.:-]+\\|\\.[[:alpha:]_.:-]+\\|\\w+=['\"]?[^\n'\"]*['\"]?\\),?[ \t]*\\)+\\(}\\)[ \t]*$"
+  "Regular expression for matching inline identifiers or attribute lists.
+Compatible with Pandoc, Python Markdown, PHP Markdown Extra, and Leanpub.")
+
+(defconst markdown-regex-leanpub-sections
+  (concat
+   "^\\({\\)\\("
+   (regexp-opt '("frontmatter" "mainmatter" "backmatter" "appendix" "pagebreak"))
+   "\\)\\(}\\)[ \t]*\n")
+  "Regular expression for Leanpub section markers and related syntax.")
+
+(defconst markdown-regex-sub-superscript
+  "\\(?:^\\|[^\\~^]\\)\\(\\([~^]\\)\\([[:alnum:]]+\\)\\(\\2\\)\\)"
+  "The regular expression matching a sub- or superscript.
+The leading un-numbered group matches the character before the
+opening tilde or carat, if any, ensuring that it is not a
+backslash escape, carat, or tilde.
+Group 1 matches the entire expression, including markup.
+Group 2 matches the opening markup--a tilde or carat.
+Group 3 matches the text inside the delimiters.
+Group 4 matches the closing markup--a tilde or carat.")
+
+(defconst markdown-regex-include
+  "^\\(<<\\)\\(?:\\(\\[\\)\\(.*\\)\\(\\]\\)\\)?\\(?:\\((\\)\\(.*\\)\\()\\)\\)?\\(?:\\({\\)\\(.*\\)\\(}\\)\\)?$"
+  "Regular expression matching common forms of include syntax.
+Marked 2, Leanpub, and other processors support some of these forms:
+
+<<[sections/section1.md]
+<<(folder/filename)
+<<[Code title](folder/filename)
+<<{folder/raw_file.html}
+
+Group 1 matches the opening two angle brackets.
+Groups 2-4 match the opening square bracket, the text inside,
+and the closing square bracket, respectively.
+Groups 5-7 match the opening parenthesis, the text inside, and
+the closing parenthesis.
+Groups 8-10 match the opening brace, the text inside, and the brace.")
+
+(defconst markdown-regex-pandoc-inline-footnote
+  "\\(\\^\\)\\(\\[\\)\\(\\(?:.\\|\n[^\n]\\)*?\\)\\(\\]\\)"
+  "Regular expression for Pandoc inline footnote^[footnote text].
+Group 1 matches the opening caret.
+Group 2 matches the opening square bracket.
+Group 3 matches the footnote text, without the surrounding markup.
+Group 4 matches the closing square bracket.")
+
+(defconst markdown-regex-html-attr
+  "\\(\\<[[:alpha:]:-]+\\>\\)\\(\\s-*\\(=\\)\\s-*\\(\".*?\"\\|'.*?'\\|[^'\">[:space:]]+\\)?\\)?"
+  "Regular expression for matching HTML attributes and values.
+Group 1 matches the attribute name.
+Group 2 matches the following whitespace, equals sign, and value, if any.
+Group 3 matches the equals sign, if any.
+Group 4 matches single-, double-, or un-quoted attribute values.")
+
+(defconst markdown-regex-html-tag
+  (concat "\\(</?\\)\\(\\w+\\)\\(\\(\\s-+" markdown-regex-html-attr
+          "\\)+\\s-*\\|\\s-*\\)\\(/?>\\)")
+  "Regular expression for matching HTML tags.
+Groups 1 and 9 match the beginning and ending angle brackets and slashes.
+Group 2 matches the tag name.
+Group 3 matches all attributes and whitespace following the tag name.")
+
+(defconst markdown-regex-html-entity
+  "\\(&#?[[:alnum:]]+;\\)"
+  "Regular expression for matching HTML entities.")
+
+
+;;; Syntax ====================================================================
+
+(defvar markdown--syntax-properties
+  (list 'markdown-tilde-fence-begin nil
+        'markdown-tilde-fence-end nil
+        'markdown-fenced-code nil
+        'markdown-yaml-metadata-begin nil
+        'markdown-yaml-metadata-end nil
+        'markdown-yaml-metadata-section nil
+        'markdown-gfm-block-begin nil
+        'markdown-gfm-block-end nil
+        'markdown-gfm-code nil
+        'markdown-list-item nil
+        'markdown-pre nil
+        'markdown-blockquote nil
+        'markdown-hr nil
+        'markdown-comment nil
+        'markdown-heading nil
+        'markdown-heading-1-setext nil
+        'markdown-heading-2-setext nil
+        'markdown-heading-1-atx nil
+        'markdown-heading-2-atx nil
+        'markdown-heading-3-atx nil
+        'markdown-heading-4-atx nil
+        'markdown-heading-5-atx nil
+        'markdown-heading-6-atx nil
+        'markdown-metadata-key nil
+        'markdown-metadata-value nil
+        'markdown-metadata-markup nil)
+  "Property list of all Markdown syntactic properties.")
+
+(defsubst markdown-in-comment-p (&optional pos)
+  "Return non-nil if POS is in a comment.
+If POS is not given, use point instead."
+  (get-text-property (or pos (point)) 'markdown-comment))
+
+(defun markdown-syntax-propertize-extend-region (start end)
+  "Extend START to END region to include an entire block of text.
+This helps improve syntax analysis for block constructs.
+Returns a cons (NEW-START . NEW-END) or nil if no adjustment should be made.
+Function is called repeatedly until it returns nil. For details, see
+`syntax-propertize-extend-region-functions'."
+  (save-match-data
+    (save-excursion
+      (let* ((new-start (progn (goto-char start)
+                               (skip-chars-forward "\n")
+                               (if (re-search-backward "\n\n" nil t)
+                                   (min start (match-end 0))
+                                 (point-min))))
+             (new-end (progn (goto-char end)
+                             (skip-chars-backward "\n")
+                             (if (re-search-forward "\n\n" nil t)
+                                 (max end (match-beginning 0))
+                               (point-max))))
+             (code-match (markdown-code-block-at-pos new-start))
+             (new-start (or (and code-match (cl-first code-match)) new-start))
+             (code-match (and (< end (point-max)) (markdown-code-block-at-pos end)))
+             (new-end (or (and code-match (cl-second code-match)) new-end)))
+        (unless (and (eq new-start start) (eq new-end end))
+          (cons new-start (min new-end (point-max))))))))
+
+(defun markdown-font-lock-extend-region-function (start end _)
+  "Used in `jit-lock-after-change-extend-region-functions'.
+Delegates to `markdown-syntax-propertize-extend-region'. START
+and END are the previous region to refontify."
+  (let ((res (markdown-syntax-propertize-extend-region start end)))
+    (when res
+      ;; syntax-propertize-function is not called when character at
+      ;; (point-max) is deleted, but font-lock-extend-region-functions
+      ;; are called.  Force a syntax property update in that case.
+      (when (= end (point-max))
+        ;; This function is called in a buffer modification hook.
+        ;; `markdown-syntax-propertize' doesn't save the match data,
+        ;; so we have to do it here.
+        (save-match-data
+          (markdown-syntax-propertize (car res) (cdr res))))
+      (setq jit-lock-start (car res)
+            jit-lock-end (cdr res)))))
+
+(defun markdown--cur-list-item-bounds ()
+  "Return a list describing the list item at point.
+Assumes that match data is set for `markdown-regex-list'.  See the
+documentation for `markdown-cur-list-item-bounds' for the format of
+the returned list."
+  (save-excursion
+    (let* ((begin (match-beginning 0))
+           (indent (length (match-string-no-properties 1)))
+           (nonlist-indent (- (match-end 3) (match-beginning 0)))
+           (marker (buffer-substring-no-properties
+                    (match-beginning 2) (match-end 3)))
+           (checkbox (match-string-no-properties 4))
+           (match (butlast (match-data t)))
+           (end (markdown-cur-list-item-end nonlist-indent)))
+      (list begin end indent nonlist-indent marker checkbox match))))
+
+(defun markdown--append-list-item-bounds (marker indent cur-bounds bounds)
+  "Update list item BOUNDS given list MARKER, block INDENT, and CUR-BOUNDS.
+Here, MARKER is a string representing the type of list and INDENT
+is an integer giving the indentation, in spaces, of the current
+block.  CUR-BOUNDS is a list of the form returned by
+`markdown-cur-list-item-bounds' and BOUNDS is a list of bounds
+values for parent list items.  When BOUNDS is nil, it means we are
+at baseline (not inside of a nested list)."
+  (let ((prev-indent (or (cl-third (car bounds)) 0)))
+    (cond
+     ;; New list item at baseline.
+     ((and marker (null bounds))
+      (list cur-bounds))
+     ;; List item with greater indentation (four or more spaces).
+     ;; Increase list level by consing CUR-BOUNDS onto BOUNDS.
+     ((and marker (>= indent (+ prev-indent 4)))
+      (cons cur-bounds bounds))
+     ;; List item with greater or equal indentation (less than four spaces).
+     ;; Keep list level the same by replacing the car of BOUNDS.
+     ((and marker (>= indent prev-indent))
+      (cons cur-bounds (cdr bounds)))
+     ;; Lesser indentation level.
+     ;; Pop appropriate number of elements off BOUNDS list (e.g., lesser
+     ;; indentation could move back more than one list level).  Note
+     ;; that this block need not be the beginning of list item.
+     ((< indent prev-indent)
+      (while (and (> (length bounds) 1)
+                  (setq prev-indent (cl-third (cadr bounds)))
+                  (< indent (+ prev-indent 4)))
+        (setq bounds (cdr bounds)))
+      (cons cur-bounds bounds))
+     ;; Otherwise, do nothing.
+     (t bounds))))
+
+(defun markdown-syntax-propertize-list-items (start end)
+  "Propertize list items from START to END.
+Stores nested list item information in the `markdown-list-item'
+text property to make later syntax analysis easier.  The value of
+this property is a list with elements of the form (begin . end)
+giving the bounds of the current and parent list items."
+  (save-excursion
+    (goto-char start)
+    (let (bounds level pre-regexp)
+      ;; Find a baseline point with zero list indentation
+      (markdown-search-backward-baseline)
+      ;; Search for all list items between baseline and END
+      (while (and (< (point) end)
+                  (re-search-forward markdown-regex-list end 'limit))
+        ;; Level of list nesting
+        (setq level (length bounds))
+        ;; Pre blocks need to be indented one level past the list level
+        (setq pre-regexp (format "^\\(    \\|\t\\)\\{%d\\}" (1+ level)))
+        (beginning-of-line)
+        (cond
+         ;; Reset at headings, horizontal rules, and top-level blank lines.
+         ;; Propertize baseline when in range.
+         ((markdown-new-baseline)
+          (setq bounds nil))
+         ;; Make sure this is not a line from a pre block
+         ((looking-at-p pre-regexp))
+         ;; If not, then update levels and propertize list item when in range.
+         (t
+          (let* ((indent (current-indentation))
+                 (cur-bounds (markdown--cur-list-item-bounds))
+                 (first (cl-first cur-bounds))
+                 (last (cl-second cur-bounds))
+                 (marker (cl-fifth cur-bounds)))
+            (setq bounds (markdown--append-list-item-bounds
+                          marker indent cur-bounds bounds))
+          (when (and (<= start (point)) (<= (point) end))
+            (put-text-property first last 'markdown-list-item bounds)))))
+        (end-of-line)))))
+
+(defun markdown-syntax-propertize-pre-blocks (start end)
+  "Match preformatted text blocks from START to END."
+  (save-excursion
+    (goto-char start)
+    (let ((levels (markdown-calculate-list-levels))
+          indent pre-regexp close-regexp open close)
+      (while (and (< (point) end) (not close))
+        ;; Search for a region with sufficient indentation
+        (if (null levels)
+            (setq indent 1)
+          (setq indent (1+ (length levels))))
+        (setq pre-regexp (format "^\\(    \\|\t\\)\\{%d\\}" indent))
+        (setq close-regexp (format "^\\(    \\|\t\\)\\{0,%d\\}\\([^ \t]\\)" (1- indent)))
+
+        (cond
+         ;; If not at the beginning of a line, move forward
+         ((not (bolp)) (forward-line))
+         ;; Move past blank lines
+         ((markdown-cur-line-blank-p) (forward-line))
+         ;; At headers and horizontal rules, reset levels
+         ((markdown-new-baseline) (forward-line) (setq levels nil))
+         ;; If the current line has sufficient indentation, mark out pre block
+         ;; The opening should be preceded by a blank line.
+         ((and (markdown-prev-line-blank) (looking-at pre-regexp))
+          (setq open (match-beginning 0))
+          (while (and (or (looking-at-p pre-regexp) (markdown-cur-line-blank-p))
+                      (not (eobp)))
+            (forward-line))
+          (skip-syntax-backward "-")
+          (setq close (point)))
+         ;; If current line has a list marker, update levels, move to end of block
+         ((looking-at markdown-regex-list)
+          (setq levels (markdown-update-list-levels
+                        (match-string 2) (current-indentation) levels))
+          (markdown-end-of-text-block))
+         ;; If this is the end of the indentation level, adjust levels accordingly.
+         ;; Only match end of indentation level if levels is not the empty list.
+         ((and (car levels) (looking-at-p close-regexp))
+          (setq levels (markdown-update-list-levels
+                        nil (current-indentation) levels))
+          (markdown-end-of-text-block))
+         (t (markdown-end-of-text-block))))
+
+      (when (and open close)
+        ;; Set text property data
+        (put-text-property open close 'markdown-pre (list open close))
+        ;; Recursively search again
+        (markdown-syntax-propertize-pre-blocks (point) end)))))
+
+(defconst markdown-fenced-block-pairs
+  `(((,markdown-regex-tilde-fence-begin markdown-tilde-fence-begin)
+     (markdown-make-tilde-fence-regex markdown-tilde-fence-end)
+     markdown-fenced-code)
+    ((markdown-get-yaml-metadata-start-border markdown-yaml-metadata-begin)
+     (markdown-get-yaml-metadata-end-border markdown-yaml-metadata-end)
+     markdown-yaml-metadata-section)
+    ((,markdown-regex-gfm-code-block-open markdown-gfm-block-begin)
+     (,markdown-regex-gfm-code-block-close markdown-gfm-block-end)
+     markdown-gfm-code))
+  "Mapping of regular expressions to \"fenced-block\" constructs.
+These constructs are distinguished by having a distinctive start
+and end pattern, both of which take up an entire line of text,
+but no special pattern to identify text within the fenced
+blocks (unlike blockquotes and indented-code sections).
+
+Each element within this list takes the form:
+
+  ((START-REGEX-OR-FUN START-PROPERTY)
+   (END-REGEX-OR-FUN END-PROPERTY)
+   MIDDLE-PROPERTY)
+
+Each *-REGEX-OR-FUN element can be a regular expression as a string, or a
+function which evaluates to same. Functions for START-REGEX-OR-FUN accept no
+arguments, but functions for END-REGEX-OR-FUN accept a single numerical argument
+which is the length of the first group of the START-REGEX-OR-FUN match, which
+can be ignored if unnecessary. `markdown-maybe-funcall-regexp' is used to
+evaluate these into \"real\" regexps.
+
+The *-PROPERTY elements are the text properties applied to each part of the
+block construct when it is matched using
+`markdown-syntax-propertize-fenced-block-constructs'. START-PROPERTY is applied
+to the text matching START-REGEX-OR-FUN, END-PROPERTY to END-REGEX-OR-FUN, and
+MIDDLE-PROPERTY to the text in between the two. The value of *-PROPERTY is the
+`match-data' when the regexp was matched to the text. In the case of
+MIDDLE-PROPERTY, the value is a false match data of the form '(begin end), with
+begin and end set to the edges of the \"middle\" text. This makes fontification
+easier.")
+
+(defun markdown-text-property-at-point (prop)
+  (get-text-property (point) prop))
+
+(defsubst markdown-maybe-funcall-regexp (object &optional arg)
+  (cond ((functionp object)
+         (if arg (funcall object arg) (funcall object)))
+        ((stringp object) object)
+        (t (error "Object cannot be turned into regex"))))
+
+(defsubst markdown-get-start-fence-regexp ()
+  "Return regexp to find all \"start\" sections of fenced block constructs.
+Which construct is actually contained in the match must be found separately."
+  (mapconcat
+   #'identity
+   (mapcar (lambda (entry) (markdown-maybe-funcall-regexp (caar entry)))
+           markdown-fenced-block-pairs)
+   "\\|"))
+
+(defun markdown-get-fenced-block-begin-properties ()
+  (cl-mapcar (lambda (entry) (cl-cadar entry)) markdown-fenced-block-pairs))
+
+(defun markdown-get-fenced-block-end-properties ()
+  (cl-mapcar (lambda (entry) (cl-cadadr entry)) markdown-fenced-block-pairs))
+
+(defun markdown-get-fenced-block-middle-properties ()
+  (cl-mapcar #'cl-third markdown-fenced-block-pairs))
+
+(defun markdown-find-previous-prop (prop &optional lim)
+  "Find previous place where property PROP is non-nil, up to LIM.
+Return a cons of (pos . property). pos is point if point contains
+non-nil PROP."
+  (let ((res
+         (if (get-text-property (point) prop) (point)
+           (previous-single-property-change
+            (point) prop nil (or lim (point-min))))))
+    (when (and (not (get-text-property res prop))
+               (> res (point-min))
+               (get-text-property (1- res) prop))
+      (cl-decf res))
+    (when (and res (get-text-property res prop)) (cons res prop))))
+
+(defun markdown-find-next-prop (prop &optional lim)
+  "Find next place where property PROP is non-nil, up to LIM.
+Return a cons of (POS . PROPERTY) where POS is point if point
+contains non-nil PROP."
+  (let ((res
+         (if (get-text-property (point) prop) (point)
+           (next-single-property-change
+            (point) prop nil (or lim (point-max))))))
+    (when (and res (get-text-property res prop)) (cons res prop))))
+
+(defun markdown-min-of-seq (map-fn seq)
+  "Apply MAP-FN to SEQ and return element of SEQ with minimum value of MAP-FN."
+  (cl-loop for el in seq
+           with min = 1.0e+INF          ; infinity
+           with min-el = nil
+           do (let ((res (funcall map-fn el)))
+                (when (< res min)
+                  (setq min res)
+                  (setq min-el el)))
+           finally return min-el))
+
+(defun markdown-max-of-seq (map-fn seq)
+  "Apply MAP-FN to SEQ and return element of SEQ with maximum value of MAP-FN."
+  (cl-loop for el in seq
+           with max = -1.0e+INF          ; negative infinity
+           with max-el = nil
+           do (let ((res (funcall map-fn el)))
+                (when (and res (> res max))
+                  (setq max res)
+                  (setq max-el el)))
+           finally return max-el))
+
+(defun markdown-find-previous-block ()
+  "Find previous block.
+Detect whether `markdown-syntax-propertize-fenced-block-constructs' was
+unable to propertize the entire block, but was able to propertize the beginning
+of the block. If so, return a cons of (pos . property) where the beginning of
+the block was propertized."
+  (let ((start-pt (point))
+        (closest-open
+         (markdown-max-of-seq
+          #'car
+          (cl-remove-if
+           #'null
+           (cl-mapcar
+            #'markdown-find-previous-prop
+            (markdown-get-fenced-block-begin-properties))))))
+    (when closest-open
+      (let* ((length-of-open-match
+              (let ((match-d
+                     (get-text-property (car closest-open) (cdr closest-open))))
+                (- (cl-fourth match-d) (cl-third match-d))))
+             (end-regexp
+              (markdown-maybe-funcall-regexp
+               (cl-caadr
+                (cl-find-if
+                 (lambda (entry) (eq (cl-cadar entry) (cdr closest-open)))
+                 markdown-fenced-block-pairs))
+               length-of-open-match))
+             (end-prop-loc
+              (save-excursion
+                (save-match-data
+                  (goto-char (car closest-open))
+                  (and (re-search-forward end-regexp start-pt t)
+                       (match-beginning 0))))))
+        (and (not end-prop-loc) closest-open)))))
+
+(defun markdown-get-fenced-block-from-start (prop)
+  "Return limits of an enclosing fenced block from its start, using PROP.
+Return value is a list usable as `match-data'."
+  (catch 'no-rest-of-block
+    (let* ((correct-entry
+            (cl-find-if
+             (lambda (entry) (eq (cl-cadar entry) prop))
+             markdown-fenced-block-pairs))
+           (begin-of-begin (cl-first (markdown-text-property-at-point prop)))
+           (middle-prop (cl-third correct-entry))
+           (end-prop (cl-cadadr correct-entry))
+           (end-of-end
+            (save-excursion
+              (goto-char (match-end 0))   ; end of begin
+              (unless (eobp) (forward-char))
+              (let ((mid-prop-v (markdown-text-property-at-point middle-prop)))
+                (if (not mid-prop-v)    ; no middle
+                    (progn
+                      ;; try to find end by advancing one
+                      (let ((end-prop-v
+                             (markdown-text-property-at-point end-prop)))
+                        (if end-prop-v (cl-second end-prop-v)
+                          (throw 'no-rest-of-block nil))))
+                  (set-match-data mid-prop-v)
+                  (goto-char (match-end 0))   ; end of middle
+                  (beginning-of-line)         ; into end
+                  (cl-second (markdown-text-property-at-point end-prop)))))))
+      (list begin-of-begin end-of-end))))
+
+(defun markdown-get-fenced-block-from-middle (prop)
+  "Return limits of an enclosing fenced block from its middle, using PROP.
+Return value is a list usable as `match-data'."
+  (let* ((correct-entry
+          (cl-find-if
+           (lambda (entry) (eq (cl-third entry) prop))
+           markdown-fenced-block-pairs))
+         (begin-prop (cl-cadar correct-entry))
+         (begin-of-begin
+          (save-excursion
+            (goto-char (match-beginning 0))
+            (unless (bobp) (forward-line -1))
+            (beginning-of-line)
+            (cl-first (markdown-text-property-at-point begin-prop))))
+         (end-prop (cl-cadadr correct-entry))
+         (end-of-end
+          (save-excursion
+            (goto-char (match-end 0))
+            (beginning-of-line)
+            (cl-second (markdown-text-property-at-point end-prop)))))
+    (list begin-of-begin end-of-end)))
+
+(defun markdown-get-fenced-block-from-end (prop)
+  "Return limits of an enclosing fenced block from its end, using PROP.
+Return value is a list usable as `match-data'."
+  (let* ((correct-entry
+          (cl-find-if
+           (lambda (entry) (eq (cl-cadadr entry) prop))
+           markdown-fenced-block-pairs))
+         (end-of-end (cl-second (markdown-text-property-at-point prop)))
+         (middle-prop (cl-third correct-entry))
+         (begin-prop (cl-cadar correct-entry))
+         (begin-of-begin
+          (save-excursion
+            (goto-char (match-beginning 0)) ; beginning of end
+            (unless (bobp) (backward-char)) ; into middle
+            (let ((mid-prop-v (markdown-text-property-at-point middle-prop)))
+              (if (not mid-prop-v)
+                  (progn
+                    (beginning-of-line)
+                    (cl-first (markdown-text-property-at-point begin-prop)))
+                (set-match-data mid-prop-v)
+                (goto-char (match-beginning 0))   ; beginning of middle
+                (unless (bobp) (forward-line -1)) ; into beginning
+                (beginning-of-line)
+                (cl-first (markdown-text-property-at-point begin-prop)))))))
+    (list begin-of-begin end-of-end)))
+
+(defun markdown-get-enclosing-fenced-block-construct (&optional pos)
+  "Get \"fake\" match data for block enclosing POS.
+Returns fake match data which encloses the start, middle, and end
+of the block construct enclosing POS, if it exists. Used in
+`markdown-code-block-at-pos'."
+  (save-excursion
+    (when pos (goto-char pos))
+    (beginning-of-line)
+    (car
+     (cl-remove-if
+      #'null
+      (cl-mapcar
+       (lambda (fun-and-prop)
+         (cl-destructuring-bind (fun prop) fun-and-prop
+           (when prop
+             (save-match-data
+               (set-match-data (markdown-text-property-at-point prop))
+               (funcall fun prop)))))
+       `((markdown-get-fenced-block-from-start
+          ,(cl-find-if
+            #'markdown-text-property-at-point
+            (markdown-get-fenced-block-begin-properties)))
+         (markdown-get-fenced-block-from-middle
+          ,(cl-find-if
+            #'markdown-text-property-at-point
+            (markdown-get-fenced-block-middle-properties)))
+         (markdown-get-fenced-block-from-end
+          ,(cl-find-if
+            #'markdown-text-property-at-point
+            (markdown-get-fenced-block-end-properties)))))))))
+
+(defun markdown-propertize-end-match (reg end fence-spec middle-begin)
+  "Get match for REG up to END, if exists, and propertize appropriately.
+FENCE-SPEC is an entry in `markdown-fenced-block-pairs' and
+MIDDLE-BEGIN is the start of the \"middle\" section of the block."
+  (when (re-search-forward reg end t)
+    (let ((close-begin (match-beginning 0)) ; Start of closing line.
+          (close-end (match-end 0))         ; End of closing line.
+          (close-data (match-data t)))      ; Match data for closing line.
+      ;; Propertize middle section of fenced block.
+      (put-text-property middle-begin close-begin
+                         (cl-third fence-spec)
+                         (list middle-begin close-begin))
+      ;; If the block is a YAML block, propertize the declarations inside
+      (markdown-syntax-propertize-yaml-metadata middle-begin close-begin)
+      ;; Propertize closing line of fenced block.
+      (put-text-property close-begin close-end
+                         (cl-cadadr fence-spec) close-data))))
+
+(defun markdown-syntax-propertize-fenced-block-constructs (start end)
+  "Propertize according to `markdown-fenced-block-pairs' from START to END.
+If unable to propertize an entire block (if the start of a block is within START
+and END, but the end of the block is not), propertize the start section of a
+block, then in a subsequent call propertize both middle and end by finding the
+start which was previously propertized."
+  (let ((start-reg (markdown-get-start-fence-regexp)))
+    (save-excursion
+      (goto-char start)
+      ;; start from previous unclosed block, if exists
+      (let ((prev-begin-block (markdown-find-previous-block)))
+        (when prev-begin-block
+          (let* ((correct-entry
+                  (cl-find-if (lambda (entry)
+                                (eq (cdr prev-begin-block) (cl-cadar entry)))
+                              markdown-fenced-block-pairs))
+                 (enclosed-text-start (1+ (car prev-begin-block)))
+                 (start-length
+                  (save-excursion
+                    (goto-char (car prev-begin-block))
+                    (string-match
+                     (markdown-maybe-funcall-regexp
+                      (caar correct-entry))
+                     (buffer-substring
+                      (point-at-bol) (point-at-eol)))
+                    (- (match-end 1) (match-beginning 1))))
+                 (end-reg (markdown-maybe-funcall-regexp
+                           (cl-caadr correct-entry) start-length)))
+            (markdown-propertize-end-match
+             end-reg end correct-entry enclosed-text-start))))
+      ;; find all new blocks within region
+      (while (re-search-forward start-reg end t)
+        ;; we assume the opening constructs take up (only) an entire line,
+        ;; so we re-check the current line
+        (let* ((cur-line (buffer-substring (point-at-bol) (point-at-eol)))
+               ;; find entry in `markdown-fenced-block-pairs' corresponding
+               ;; to regex which was matched
+               (correct-entry
+                (cl-find-if
+                 (lambda (fenced-pair)
+                   (string-match-p
+                    (markdown-maybe-funcall-regexp (caar fenced-pair))
+                    cur-line))
+                 markdown-fenced-block-pairs))
+               (enclosed-text-start
+                (save-excursion (1+ (point-at-eol))))
+               (end-reg
+                (markdown-maybe-funcall-regexp
+                 (cl-caadr correct-entry)
+                 (if (and (match-beginning 1) (match-end 1))
+                     (- (match-end 1) (match-beginning 1))
+                   0))))
+          ;; get correct match data
+          (save-excursion
+            (beginning-of-line)
+            (re-search-forward
+             (markdown-maybe-funcall-regexp (caar correct-entry))
+             (point-at-eol)))
+          ;; mark starting, even if ending is outside of region
+          (put-text-property (match-beginning 0) (match-end 0)
+                             (cl-cadar correct-entry) (match-data t))
+          (markdown-propertize-end-match
+           end-reg end correct-entry enclosed-text-start))))))
+
+(defun markdown-syntax-propertize-blockquotes (start end)
+  "Match blockquotes from START to END."
+  (save-excursion
+    (goto-char start)
+    (while (and (re-search-forward markdown-regex-blockquote end t)
+                (not (markdown-code-block-at-pos (match-beginning 0))))
+      (put-text-property (match-beginning 0) (match-end 0)
+                         'markdown-blockquote
+                         (match-data t)))))
+
+(defun markdown-syntax-propertize-hrs (start end)
+  "Match horizontal rules from START to END."
+  (save-excursion
+    (goto-char start)
+    (while (re-search-forward markdown-regex-hr end t)
+      (unless (or (markdown-on-heading-p)
+                  (markdown-code-block-at-point-p))
+        (put-text-property (match-beginning 0) (match-end 0)
+                           'markdown-hr
+                           (match-data t))))))
+
+(defun markdown-syntax-propertize-yaml-metadata (start end)
+  "Propertize elements inside YAML metadata blocks from START to END.
+Assumes region from START and END is already known to be the interior
+region of a YAML metadata block as propertized by
+`markdown-syntax-propertize-fenced-block-constructs'."
+  (save-excursion
+    (goto-char start)
+    (cl-loop
+     while (re-search-forward markdown-regex-declarative-metadata end t)
+     do (progn
+          (put-text-property (match-beginning 1) (match-end 1)
+                             'markdown-metadata-key (match-data t))
+          (put-text-property (match-beginning 2) (match-end 2)
+                             'markdown-metadata-markup (match-data t))
+          (put-text-property (match-beginning 3) (match-end 3)
+                             'markdown-metadata-value (match-data t))))))
+
+(defun markdown-syntax-propertize-headings (start end)
+  "Match headings of type SYMBOL with REGEX from START to END."
+  (goto-char start)
+  (while (re-search-forward markdown-regex-header end t)
+    (unless (markdown-code-block-at-pos (match-beginning 0))
+      (put-text-property
+       (match-beginning 0) (match-end 0) 'markdown-heading
+       (match-data t))
+      (put-text-property
+       (match-beginning 0) (match-end 0)
+       (cond ((match-string-no-properties 2) 'markdown-heading-1-setext)
+             ((match-string-no-properties 3) 'markdown-heading-2-setext)
+             (t (let ((atx-level (length (markdown-trim-whitespace
+                                          (match-string-no-properties 4)))))
+                  (intern (format "markdown-heading-%d-atx" atx-level)))))
+       (match-data t)))))
+
+(defun markdown-syntax-propertize-comments (start end)
+  "Match HTML comments from the START to END."
+  (let* ((in-comment (nth 4 (syntax-ppss))))
+    (goto-char start)
+    (cond
+     ;; Comment start
+     ((and (not in-comment)
+           (re-search-forward markdown-regex-comment-start end t)
+           (not (markdown-inline-code-at-point-p))
+           (not (markdown-code-block-at-point-p)))
+      (let ((open-beg (match-beginning 0)))
+        (put-text-property open-beg (1+ open-beg)
+                           'syntax-table (string-to-syntax "<"))
+        (markdown-syntax-propertize-comments
+         (min (1+ (match-end 0)) end (point-max)) end)))
+     ;; Comment end
+     ((and in-comment
+           (re-search-forward markdown-regex-comment-end end t))
+      (let ((comment-end (match-end 0))
+            (comment-begin (nth 8 (syntax-ppss))))
+        (put-text-property (1- comment-end) comment-end
+                           'syntax-table (string-to-syntax ">"))
+        ;; Remove any other text properties inside the comment
+        (remove-text-properties comment-begin comment-end
+                                markdown--syntax-properties)
+        (put-text-property comment-begin comment-end
+                           'markdown-comment (list comment-begin comment-end))
+        (markdown-syntax-propertize-comments
+         (min (1+ comment-end) end (point-max)) end)))
+     ;; Nothing found
+     (t nil))))
+
+(defun markdown-syntax-propertize (start end)
+  "Function used as `syntax-propertize-function'.
+START and END delimit region to propertize."
+  (with-silent-modifications
+    (save-excursion
+      (remove-text-properties start end markdown--syntax-properties)
+      (markdown-syntax-propertize-fenced-block-constructs start end)
+      (markdown-syntax-propertize-list-items start end)
+      (markdown-syntax-propertize-pre-blocks start end)
+      (markdown-syntax-propertize-blockquotes start end)
+      (markdown-syntax-propertize-headings start end)
+      (markdown-syntax-propertize-hrs start end)
+      (markdown-syntax-propertize-comments start end))))
+
+
+;;; Markup Hiding
+
+(defconst markdown-markup-properties
+  '(face markdown-markup-face invisible markdown-markup)
+  "List of properties and values to apply to markup.")
+
+(defconst markdown-language-keyword-properties
+  '(face markdown-language-keyword-face invisible markdown-markup)
+  "List of properties and values to apply to code block language names.")
+
+(defconst markdown-language-info-properties
+  '(face markdown-language-info-face invisible markdown-markup)
+  "List of properties and values to apply to code block language info strings.")
+
+(defconst markdown-include-title-properties
+  '(face markdown-link-title-face invisible markdown-markup)
+  "List of properties and values to apply to included code titles.")
+
+(defcustom markdown-hide-markup nil
+  "Determines whether markup in the buffer will be hidden.
+When set to nil, all markup is displayed in the buffer as it
+appears in the file.  An exception is when `markdown-hide-urls'
+is non-nil.
+Set this to a non-nil value to turn this feature on by default.
+You can interactively toggle the value of this variable with
+`markdown-toggle-markup-hiding', \\[markdown-toggle-markup-hiding],
+or from the Markdown > Show & Hide menu.
+
+Markup hiding works by adding text properties to positions in the
+buffer---either the `invisible' property or the `display' property
+in cases where alternative glyphs are used (e.g., list bullets).
+This does not, however, affect printing or other output.
+Functions such as `htmlfontify-buffer' and `ps-print-buffer' will
+not honor these text properties.  For printing, it would be better
+to first convert to HTML or PDF (e.g,. using Pandoc)."
+  :group 'markdown
+  :type 'boolean
+  :safe 'booleanp
+  :package-version '(markdown-mode . "2.3"))
+(make-variable-buffer-local 'markdown-hide-markup)
+
+(defun markdown-toggle-markup-hiding (&optional arg)
+  "Toggle the display or hiding of markup.
+With a prefix argument ARG, enable markup hiding if ARG is positive,
+and disable it otherwise.
+See `markdown-hide-markup' for additional details."
+  (interactive (list (or current-prefix-arg 'toggle)))
+  (setq markdown-hide-markup
+        (if (eq arg 'toggle)
+            (not markdown-hide-markup)
+          (> (prefix-numeric-value arg) 0)))
+  (if markdown-hide-markup
+      (progn (add-to-invisibility-spec 'markdown-markup)
+             (message "markdown-mode markup hiding enabled"))
+    (progn (remove-from-invisibility-spec 'markdown-markup)
+           (message "markdown-mode markup hiding disabled")))
+  (markdown-reload-extensions))
+
+
+;;; Font Lock =================================================================
+
+(require 'font-lock)
+
+(defvar markdown-italic-face 'markdown-italic-face
+  "Face name to use for italic text.")
+
+(defvar markdown-bold-face 'markdown-bold-face
+  "Face name to use for bold text.")
+
+(defvar markdown-strike-through-face 'markdown-strike-through-face
+  "Face name to use for strike-through text.")
+
+(defvar markdown-header-delimiter-face 'markdown-header-delimiter-face
+  "Face name to use as a base for header delimiters.")
+
+(defvar markdown-header-rule-face 'markdown-header-rule-face
+  "Face name to use as a base for header rules.")
+
+(defvar markdown-header-face 'markdown-header-face
+  "Face name to use as a base for headers.")
+
+(defvar markdown-header-face-1 'markdown-header-face-1
+  "Face name to use for level-1 headers.")
+
+(defvar markdown-header-face-2 'markdown-header-face-2
+  "Face name to use for level-2 headers.")
+
+(defvar markdown-header-face-3 'markdown-header-face-3
+  "Face name to use for level-3 headers.")
+
+(defvar markdown-header-face-4 'markdown-header-face-4
+  "Face name to use for level-4 headers.")
+
+(defvar markdown-header-face-5 'markdown-header-face-5
+  "Face name to use for level-5 headers.")
+
+(defvar markdown-header-face-6 'markdown-header-face-6
+  "Face name to use for level-6 headers.")
+
+(defvar markdown-inline-code-face 'markdown-inline-code-face
+  "Face name to use for inline code.")
+
+(defvar markdown-list-face 'markdown-list-face
+  "Face name to use for list markers.")
+
+(defvar markdown-blockquote-face 'markdown-blockquote-face
+  "Face name to use for blockquote.")
+
+(defvar markdown-pre-face 'markdown-pre-face
+  "Face name to use for preformatted text.")
+
+(defvar markdown-language-keyword-face 'markdown-language-keyword-face
+  "Face name to use for programming language identifiers.")
+
+(defvar markdown-language-info-face 'markdown-language-info-face
+  "Face name to use for programming info strings.")
+
+(defvar markdown-link-face 'markdown-link-face
+  "Face name to use for links.")
+
+(defvar markdown-missing-link-face 'markdown-missing-link-face
+  "Face name to use for links where the linked file does not exist.")
+
+(defvar markdown-reference-face 'markdown-reference-face
+  "Face name to use for reference.")
+
+(defvar markdown-footnote-marker-face 'markdown-footnote-marker-face
+  "Face name to use for footnote markers.")
+
+(defvar markdown-url-face 'markdown-url-face
+  "Face name to use for URLs.")
+
+(defvar markdown-link-title-face 'markdown-link-title-face
+  "Face name to use for reference link titles.")
+
+(defvar markdown-line-break-face 'markdown-line-break-face
+  "Face name to use for hard line breaks.")
+
+(defvar markdown-comment-face 'markdown-comment-face
+  "Face name to use for HTML comments.")
+
+(defvar markdown-math-face 'markdown-math-face
+  "Face name to use for LaTeX expressions.")
+
+(defvar markdown-metadata-key-face 'markdown-metadata-key-face
+  "Face name to use for metadata keys.")
+
+(defvar markdown-metadata-value-face 'markdown-metadata-value-face
+  "Face name to use for metadata values.")
+
+(defvar markdown-gfm-checkbox-face 'markdown-gfm-checkbox-face
+  "Face name to use for GFM checkboxes.")
+
+(defvar markdown-highlight-face 'markdown-highlight-face
+  "Face name to use for mouse highlighting.")
+
+(defvar markdown-markup-face 'markdown-markup-face
+  "Face name to use for markup elements.")
+
+(make-obsolete-variable 'markdown-italic-face "Use face name directly" "v2.4")
+(make-obsolete-variable 'markdown-bold-face "Use face name directly" "v2.4")
+(make-obsolete-variable 'markdown-strike-through-face "Use face name directly" "v2.4")
+(make-obsolete-variable 'markdown-header-delimiter-face "Use face name directly" "v2.4")
+(make-obsolete-variable 'markdown-header-rule-face "Use face name directly" "v2.4")
+(make-obsolete-variable 'markdown-header-face "Use face name directly" "v2.4")
+(make-obsolete-variable 'markdown-header-face-1 "Use face name directly" "v2.4")
+(make-obsolete-variable 'markdown-header-face-2 "Use face name directly" "v2.4")
+(make-obsolete-variable 'markdown-header-face-3 "Use face name directly" "v2.4")
+(make-obsolete-variable 'markdown-header-face-4 "Use face name directly" "v2.4")
+(make-obsolete-variable 'markdown-header-face-5 "Use face name directly" "v2.4")
+(make-obsolete-variable 'markdown-header-face-6 "Use face name directly" "v2.4")
+(make-obsolete-variable 'markdown-inline-code-face "Use face name directly" "v2.4")
+(make-obsolete-variable 'markdown-list-face "Use face name directly" "v2.4")
+(make-obsolete-variable 'markdown-blockquote-face "Use face name directly" "v2.4")
+(make-obsolete-variable 'markdown-pre-face "Use face name directly" "v2.4")
+(make-obsolete-variable 'markdown-language-keyword-face "Use face name directly" "v2.4")
+(make-obsolete-variable 'markdown-language-info-face "Use face name directly" "v2.4")
+(make-obsolete-variable 'markdown-link-face "Use face name directly" "v2.4")
+(make-obsolete-variable 'markdown-missing-link-face "Use face name directly" "v2.4")
+(make-obsolete-variable 'markdown-reference-face "Use face name directly" "v2.4")
+(make-obsolete-variable 'markdown-footnote-marker-face "Use face name directly" "v2.4")
+(make-obsolete-variable 'markdown-url-face "Use face name directly" "v2.4")
+(make-obsolete-variable 'markdown-link-title-face "Use face name directly" "v2.4")
+(make-obsolete-variable 'markdown-line-break-face "Use face name directly" "v2.4")
+(make-obsolete-variable 'markdown-comment-face "Use face name directly" "v2.4")
+(make-obsolete-variable 'markdown-math-face "Use face name directly" "v2.4")
+(make-obsolete-variable 'markdown-metadata-key-face "Use face name directly" "v2.4")
+(make-obsolete-variable 'markdown-metadata-value-face "Use face name directly" "v2.4")
+(make-obsolete-variable 'markdown-gfm-checkbox-face "Use face name directly" "v2.4")
+(make-obsolete-variable 'markdown-highlight-face "Use face name directly" "v2.4")
+(make-obsolete-variable 'markdown-markup-face "Use face name directly" "v2.4")
+
+(defgroup markdown-faces nil
+  "Faces used in Markdown Mode"
+  :group 'markdown
+  :group 'faces)
+
+(defface markdown-italic-face
+  '((t (:inherit italic)))
+  "Face for italic text."
+  :group 'markdown-faces)
+
+(defface markdown-bold-face
+  '((t (:inherit bold)))
+  "Face for bold text."
+  :group 'markdown-faces)
+
+(defface markdown-strike-through-face
+  '((t (:strike-through t)))
+  "Face for strike-through text."
+  :group 'markdown-faces)
+
+(defface markdown-markup-face
+  '((t (:inherit shadow :slant normal :weight normal)))
+  "Face for markup elements."
+  :group 'markdown-faces)
+
+(defface markdown-header-rule-face
+  '((t (:inherit markdown-markup-face)))
+  "Base face for headers rules."
+  :group 'markdown-faces)
+
+(defface markdown-header-delimiter-face
+  '((t (:inherit markdown-markup-face)))
+  "Base face for headers hash delimiter."
+  :group 'markdown-faces)
+
+(defface markdown-list-face
+  '((t (:inherit markdown-markup-face)))
+  "Face for list item markers."
+  :group 'markdown-faces)
+
+(defface markdown-blockquote-face
+  '((t (:inherit font-lock-doc-face)))
+  "Face for blockquote sections."
+  :group 'markdown-faces)
+
+(defface markdown-code-face
+  '((t (:inherit fixed-pitch)))
+  "Face for inline code, pre blocks, and fenced code blocks.
+This may be used, for example, to add a contrasting background to
+inline code fragments and code blocks."
+  :group 'markdown-faces)
+
+(defface markdown-inline-code-face
+  '((t (:inherit (markdown-code-face font-lock-constant-face))))
+  "Face for inline code."
+  :group 'markdown-faces)
+
+(defface markdown-pre-face
+  '((t (:inherit (markdown-code-face font-lock-constant-face))))
+  "Face for preformatted text."
+  :group 'markdown-faces)
+
+(defface markdown-table-face
+  '((t (:inherit (markdown-code-face))))
+  "Face for tables."
+  :group 'markdown-faces)
+
+(defface markdown-language-keyword-face
+  '((t (:inherit font-lock-type-face)))
+  "Face for programming language identifiers."
+  :group 'markdown-faces)
+
+(defface markdown-language-info-face
+  '((t (:inherit font-lock-string-face)))
+  "Face for programming language info strings."
+  :group 'markdown-faces)
+
+(defface markdown-link-face
+  '((t (:inherit link)))
+  "Face for links."
+  :group 'markdown-faces)
+
+(defface markdown-missing-link-face
+  '((t (:inherit font-lock-warning-face)))
+  "Face for missing links."
+  :group 'markdown-faces)
+
+(defface markdown-reference-face
+  '((t (:inherit markdown-markup-face)))
+  "Face for link references."
+  :group 'markdown-faces)
+
+(define-obsolete-face-alias 'markdown-footnote-face
+  'markdown-footnote-marker-face "v2.3")
+
+(defface markdown-footnote-marker-face
+  '((t (:inherit markdown-markup-face)))
+  "Face for footnote markers."
+  :group 'markdown-faces)
+
+(defface markdown-footnote-text-face
+  '((t (:inherit font-lock-comment-face)))
+  "Face for footnote text."
+  :group 'markdown-faces)
+
+(defface markdown-url-face
+  '((t (:inherit font-lock-string-face)))
+  "Face for URLs that are part of markup.
+For example, this applies to URLs in inline links:
+[link text](http://example.com/)."
+  :group 'markdown-faces)
+
+(defface markdown-plain-url-face
+  '((t (:inherit markdown-link-face)))
+  "Face for URLs that are also links.
+For example, this applies to plain angle bracket URLs:
+<http://example.com/>."
+  :group 'markdown-faces)
+
+(defface markdown-link-title-face
+  '((t (:inherit font-lock-comment-face)))
+  "Face for reference link titles."
+  :group 'markdown-faces)
+
+(defface markdown-line-break-face
+  '((t (:inherit font-lock-constant-face :underline t)))
+  "Face for hard line breaks."
+  :group 'markdown-faces)
+
+(defface markdown-comment-face
+  '((t (:inherit font-lock-comment-face)))
+  "Face for HTML comments."
+  :group 'markdown-faces)
+
+(defface markdown-math-face
+  '((t (:inherit font-lock-string-face)))
+  "Face for LaTeX expressions."
+  :group 'markdown-faces)
+
+(defface markdown-metadata-key-face
+  '((t (:inherit font-lock-variable-name-face)))
+  "Face for metadata keys."
+  :group 'markdown-faces)
+
+(defface markdown-metadata-value-face
+  '((t (:inherit font-lock-string-face)))
+  "Face for metadata values."
+  :group 'markdown-faces)
+
+(defface markdown-gfm-checkbox-face
+  '((t (:inherit font-lock-builtin-face)))
+  "Face for GFM checkboxes."
+  :group 'markdown-faces)
+
+(defface markdown-highlight-face
+  '((t (:inherit highlight)))
+  "Face for mouse highlighting."
+  :group 'markdown-faces)
+
+(defface markdown-hr-face
+  '((t (:inherit markdown-markup-face)))
+  "Face for horizontal rules."
+  :group 'markdown-faces)
+
+(defface markdown-html-tag-name-face
+  '((t (:inherit font-lock-type-face)))
+  "Face for HTML tag names."
+  :group 'markdown-faces)
+
+(defface markdown-html-tag-delimiter-face
+  '((t (:inherit markdown-markup-face)))
+  "Face for HTML tag delimiters."
+  :group 'markdown-faces)
+
+(defface markdown-html-attr-name-face
+  '((t (:inherit font-lock-variable-name-face)))
+  "Face for HTML attribute names."
+  :group 'markdown-faces)
+
+(defface markdown-html-attr-value-face
+  '((t (:inherit font-lock-string-face)))
+  "Face for HTML attribute values."
+  :group 'markdown-faces)
+
+(defface markdown-html-entity-face
+  '((t (:inherit font-lock-variable-name-face)))
+  "Face for HTML entities."
+  :group 'markdown-faces)
+
+(defcustom markdown-header-scaling nil
+  "Whether to use variable-height faces for headers.
+When non-nil, `markdown-header-face' will inherit from
+`variable-pitch' and the scaling values in
+`markdown-header-scaling-values' will be applied to
+headers of levels one through six respectively."
+  :type 'boolean
+  :initialize 'custom-initialize-default
+  :set (lambda (symbol value)
+         (set-default symbol value)
+         (markdown-update-header-faces value))
+  :group 'markdown-faces
+  :package-version '(markdown-mode . "2.2"))
+
+(defcustom markdown-header-scaling-values
+  '(2.0 1.7 1.4 1.1 1.0 1.0)
+  "List of scaling values for headers of level one through six.
+Used when `markdown-header-scaling' is non-nil."
+  :type 'list
+  :initialize 'custom-initialize-default
+  :set (lambda (symbol value)
+         (set-default symbol value)
+         (markdown-update-header-faces markdown-header-scaling value))
+  :group 'markdown-faces)
+
+(defun markdown-make-header-faces ()
+  "Build the faces used for Markdown headers."
+  (let ((inherit-faces '(font-lock-function-name-face)))
+    (when markdown-header-scaling
+      (setq inherit-faces (cons 'variable-pitch inherit-faces)))
+    (defface markdown-header-face
+      `((t (:inherit ,inherit-faces :weight bold)))
+      "Base face for headers."
+      :group 'markdown-faces))
+  (dotimes (num 6)
+    (let* ((num1 (1+ num))
+           (face-name (intern (format "markdown-header-face-%s" num1)))
+           (scale (if markdown-header-scaling
+                      (float (nth num markdown-header-scaling-values))
+                    1.0)))
+      (eval
+       `(defface ,face-name
+          '((t (:inherit markdown-header-face :height ,scale)))
+          (format "Face for level %s headers.
+You probably don't want to customize this face directly. Instead
+you can customize the base face `markdown-header-face' or the
+variable-height variable `markdown-header-scaling'." ,num1)
+          :group 'markdown-faces)))))
+
+(markdown-make-header-faces)
+
+(defun markdown-update-header-faces (&optional scaling scaling-values)
+  "Update header faces, depending on if header SCALING is desired.
+If so, use given list of SCALING-VALUES relative to the baseline
+size of `markdown-header-face'."
+  (dotimes (num 6)
+    (let* ((face-name (intern (format "markdown-header-face-%s" (1+ num))))
+           (scale (cond ((not scaling) 1.0)
+                        (scaling-values (float (nth num scaling-values)))
+                        (t (float (nth num markdown-header-scaling-values))))))
+      (unless (get face-name 'saved-face) ; Don't update customized faces
+        (set-face-attribute face-name nil :height scale)))))
+
+(defun markdown-syntactic-face (state)
+  "Return font-lock face for characters with given STATE.
+See `font-lock-syntactic-face-function' for details."
+  (let ((in-comment (nth 4 state)))
+    (cond
+     (in-comment 'markdown-comment-face)
+     (t nil))))
+
+(defcustom markdown-list-item-bullets
+  '("●" "◎" "○" "◆" "◇" "►" "•")
+  "List of bullets to use for unordered lists.
+It can contain any number of symbols, which will be repeated.
+Depending on your font, some reasonable choices are:
+♥ ● ◇ ✚ ✜ ☯ ◆ ♠ ♣ ♦ ❀ ◆ ◖ ▶ ► • ★ ▸."
+  :group 'markdown
+  :type '(repeat (string :tag "Bullet character"))
+  :package-version '(markdown-mode . "2.3"))
+
+(defun markdown--footnote-marker-properties ()
+  "Return a font-lock facespec expression for footnote marker text."
+  `(face markdown-footnote-marker-face
+         ,@(when markdown-hide-markup
+             `(display ,markdown-footnote-display))))
+
+(defun markdown--pandoc-inline-footnote-properties ()
+  "Return a font-lock facespec expression for Pandoc inline footnote text."
+  `(face markdown-footnote-text-face
+         ,@(when markdown-hide-markup
+             `(display ,markdown-footnote-display))))
+
+(defvar markdown-mode-font-lock-keywords
+  `((markdown-match-yaml-metadata-begin . ((1 'markdown-markup-face)))
+    (markdown-match-yaml-metadata-end . ((1 'markdown-markup-face)))
+    (markdown-match-yaml-metadata-key . ((1 'markdown-metadata-key-face)
+                                         (2 'markdown-markup-face)
+                                         (3 'markdown-metadata-value-face)))
+    (markdown-match-gfm-open-code-blocks . ((1 markdown-markup-properties)
+                                            (2 markdown-markup-properties nil t)
+                                            (3 markdown-language-keyword-properties nil t)
+                                            (4 markdown-language-info-properties nil t)
+                                            (5 markdown-markup-properties nil t)))
+    (markdown-match-gfm-close-code-blocks . ((0 markdown-markup-properties)))
+    (markdown-fontify-gfm-code-blocks)
+    (markdown-fontify-tables)
+    (markdown-match-fenced-start-code-block . ((1 markdown-markup-properties)
+                                               (2 markdown-markup-properties nil t)
+                                               (3 markdown-language-keyword-properties nil t)
+                                               (4 markdown-language-info-properties nil t)
+                                               (5 markdown-markup-properties nil t)))
+    (markdown-match-fenced-end-code-block . ((0 markdown-markup-properties)))
+    (markdown-fontify-fenced-code-blocks)
+    (markdown-match-pre-blocks . ((0 'markdown-pre-face)))
+    (markdown-fontify-headings)
+    (markdown-match-declarative-metadata . ((1 'markdown-metadata-key-face)
+                                              (2 'markdown-markup-face)
+                                              (3 'markdown-metadata-value-face)))
+    (markdown-match-pandoc-metadata . ((1 'markdown-markup-face)
+                                       (2 'markdown-markup-face)
+                                       (3 'markdown-metadata-value-face)))
+    (markdown-fontify-hrs)
+    (markdown-match-code . ((1 markdown-markup-properties prepend)
+                            (2 'markdown-inline-code-face prepend)
+                            (3 markdown-markup-properties prepend)))
+    (,markdown-regex-kbd . ((1 markdown-markup-properties)
+                            (2 'markdown-inline-code-face)
+                            (3 markdown-markup-properties)))
+    (markdown-fontify-angle-uris)
+    (,markdown-regex-email . 'markdown-plain-url-face)
+    (markdown-match-html-tag . ((1 'markdown-html-tag-delimiter-face t)
+                                (2 'markdown-html-tag-name-face t)
+                                (3 'markdown-html-tag-delimiter-face t)
+                                ;; Anchored matcher for HTML tag attributes
+                                (,markdown-regex-html-attr
+                                 ;; Before searching, move past tag
+                                 ;; name; set limit at tag close.
+                                 (progn
+                                   (goto-char (match-end 2)) (match-end 3))
+                                 nil
+                                 . ((1 'markdown-html-attr-name-face)
+                                    (3 'markdown-html-tag-delimiter-face nil t)
+                                    (4 'markdown-html-attr-value-face nil t)))))
+    (,markdown-regex-html-entity . 'markdown-html-entity-face)
+    (markdown-fontify-list-items)
+    (,markdown-regex-footnote . ((1 markdown-markup-properties)    ; [^
+                                 (2 (markdown--footnote-marker-properties)) ; label
+                                 (3 markdown-markup-properties)))  ; ]
+    (,markdown-regex-pandoc-inline-footnote . ((1 markdown-markup-properties)   ; ^
+                                               (2 markdown-markup-properties)   ; [
+                                               (3 (markdown--pandoc-inline-footnote-properties)) ; text
+                                               (4 markdown-markup-properties))) ; ]
+    (markdown-match-includes . ((1 markdown-markup-properties)
+                                (2 markdown-markup-properties nil t)
+                                (3 markdown-include-title-properties nil t)
+                                (4 markdown-markup-properties nil t)
+                                (5 markdown-markup-properties)
+                                (6 'markdown-url-face)
+                                (7 markdown-markup-properties)))
+    (markdown-fontify-inline-links)
+    (markdown-fontify-reference-links)
+    (,markdown-regex-reference-definition . ((1 'markdown-markup-face) ; [
+                                             (2 'markdown-reference-face) ; label
+                                             (3 'markdown-markup-face)    ; ]
+                                             (4 'markdown-markup-face)    ; :
+                                             (5 'markdown-url-face)       ; url
+                                             (6 'markdown-link-title-face))) ; "title" (optional)
+    (markdown-fontify-plain-uris)
+    ;; Math mode $..$
+    (markdown-match-math-single . ((1 'markdown-markup-face prepend)
+                                   (2 'markdown-math-face append)
+                                   (3 'markdown-markup-face prepend)))
+    ;; Math mode $$..$$
+    (markdown-match-math-double . ((1 'markdown-markup-face prepend)
+                                   (2 'markdown-math-face append)
+                                   (3 'markdown-markup-face prepend)))
+    ;; Math mode \[..\] and \\[..\\]
+    (markdown-match-math-display . ((1 'markdown-markup-face prepend)
+                                    (3 'markdown-math-face append)
+                                    (4 'markdown-markup-face prepend)))
+    (markdown-match-bold . ((1 markdown-markup-properties prepend)
+                            (2 'markdown-bold-face append)
+                            (3 markdown-markup-properties prepend)))
+    (markdown-match-italic . ((1 markdown-markup-properties prepend)
+                              (2 'markdown-italic-face append)
+                              (3 markdown-markup-properties prepend)))
+    (,markdown-regex-strike-through . ((3 markdown-markup-properties)
+                                       (4 'markdown-strike-through-face)
+                                       (5 markdown-markup-properties)))
+    (,markdown-regex-line-break . (1 'markdown-line-break-face prepend))
+    (markdown-fontify-sub-superscripts)
+    (markdown-match-inline-attributes . ((0 markdown-markup-properties prepend)))
+    (markdown-match-leanpub-sections . ((0 markdown-markup-properties)))
+    (markdown-fontify-blockquotes)
+    (markdown-match-wiki-link . ((0 'markdown-link-face prepend))))
+  "Syntax highlighting for Markdown files.")
+
+(define-obsolete-variable-alias
+ 'markdown-mode-font-lock-keywords-basic
+ 'markdown-mode-font-lock-keywords "v2.4")
+
+;; Footnotes
+(defvar markdown-footnote-counter 0
+  "Counter for footnote numbers.")
+(make-variable-buffer-local 'markdown-footnote-counter)
+
+(defconst markdown-footnote-chars
+  "[[:alnum:]-]"
+  "Regular expression matching any character that is allowed in a footnote identifier.")
+
+(defconst markdown-regex-footnote-definition
+  (concat "^ \\{0,3\\}\\[\\(\\^" markdown-footnote-chars "*?\\)\\]:\\(?:[ \t]+\\|$\\)")
+  "Regular expression matching a footnote definition, capturing the label.")
+
+
+;;; Compatibility =============================================================
+
+(defun markdown-replace-regexp-in-string (regexp rep string)
+  "Replace ocurrences of REGEXP with REP in STRING.
+This is a compatibility wrapper to provide `replace-regexp-in-string'
+in XEmacs 21."
+  (if (featurep 'xemacs)
+      (replace-in-string string regexp rep)
+    (replace-regexp-in-string regexp rep string)))
+
+;; `markdown-use-region-p' is a compatibility function which checks
+;; for an active region, with fallbacks for older Emacsen and XEmacs.
+(eval-and-compile
+  (cond
+   ;; Emacs 24 and newer
+   ((fboundp 'use-region-p)
+    (defalias 'markdown-use-region-p 'use-region-p))
+   ;; XEmacs
+   ((fboundp 'region-active-p)
+    (defalias 'markdown-use-region-p 'region-active-p))))
+
+;; Use new names for outline-mode functions in Emacs 25 and later.
+(eval-and-compile
+  (defalias 'markdown-hide-sublevels
+    (if (fboundp 'outline-hide-sublevels)
+        'outline-hide-sublevels
+      'hide-sublevels))
+  (defalias 'markdown-show-all
+    (if (fboundp 'outline-show-all)
+        'outline-show-all
+      'show-all))
+  (defalias 'markdown-hide-body
+    (if (fboundp 'outline-hide-body)
+        'outline-hide-body
+      'hide-body))
+  (defalias 'markdown-show-children
+    (if (fboundp 'outline-show-children)
+        'outline-show-children
+      'show-children))
+  (defalias 'markdown-show-subtree
+    (if (fboundp 'outline-show-subtree)
+        'outline-show-subtree
+      'show-subtree))
+  (defalias 'markdown-hide-subtree
+    (if (fboundp 'outline-hide-subtree)
+        'outline-hide-subtree
+      'hide-subtree)))
+
+;; Provide directory-name-p to Emacs 24
+(defsubst markdown-directory-name-p (name)
+  "Return non-nil if NAME ends with a directory separator character.
+Taken from `directory-name-p' from Emacs 25 and provided here for
+backwards compatibility."
+  (let ((len (length name))
+        (lastc ?.))
+    (if (> len 0)
+        (setq lastc (aref name (1- len))))
+    (or (= lastc ?/)
+        (and (memq system-type '(windows-nt ms-dos))
+             (= lastc ?\\)))))
+
+;; Provide a function to find files recursively in Emacs 24.
+(defalias 'markdown-directory-files-recursively
+  (if (fboundp 'directory-files-recursively)
+      'directory-files-recursively
+    (lambda (dir regexp)
+    "Return list of all files under DIR that have file names matching REGEXP.
+This function works recursively.  Files are returned in \"depth first\"
+order, and files from each directory are sorted in alphabetical order.
+Each file name appears in the returned list in its absolute form.
+Based on `directory-files-recursively' from Emacs 25 and provided
+here for backwards compatibility."
+  (let ((result nil)
+        (files nil)
+        ;; When DIR is "/", remote file names like "/method:" could
+        ;; also be offered.  We shall suppress them.
+        (tramp-mode (and tramp-mode (file-remote-p (expand-file-name dir)))))
+    (dolist (file (sort (file-name-all-completions "" dir)
+                        'string<))
+      (unless (member file '("./" "../"))
+        (if (markdown-directory-name-p file)
+            (let* ((leaf (substring file 0 (1- (length file))))
+                   (full-file (expand-file-name leaf dir)))
+              (setq result
+                    (nconc result (markdown-directory-files-recursively
+                                   full-file regexp))))
+          (when (string-match-p regexp file)
+            (push (expand-file-name file dir) files)))))
+    (nconc result (nreverse files))))))
+
+(defun markdown-flyspell-check-word-p ()
+  "Return t if `flyspell' should check word just before point.
+Used for `flyspell-generic-check-word-predicate'."
+  (save-excursion
+    (goto-char (1- (point)))
+    (not (or (markdown-code-block-at-point-p)
+             (markdown-inline-code-at-point-p)
+             (markdown-in-comment-p)
+             (let ((faces (get-text-property (point) 'face)))
+               (if (listp faces)
+                   (or (memq 'markdown-reference-face faces)
+                       (memq 'markdown-markup-face faces)
+                       (memq 'markdown-plain-url-face faces)
+                       (memq 'markdown-inline-code-face faces)
+                       (memq 'markdown-url-face faces))
+                 (memq faces '(markdown-reference-face
+                               markdown-markup-face
+                               markdown-plain-url-face
+                               markdown-inline-code-face
+                               markdown-url-face))))))))
+
+(defun markdown-font-lock-ensure ()
+  "Provide `font-lock-ensure' in Emacs 24."
+  (if (fboundp 'font-lock-ensure)
+      (font-lock-ensure)
+    (with-no-warnings
+      ;; Suppress warning about non-interactive use of
+      ;; `font-lock-fontify-buffer' in Emacs 25.
+      (font-lock-fontify-buffer))))
+
+
+;;; Markdown Parsing Functions ================================================
+
+(define-obsolete-function-alias
+  'markdown-cur-line-blank 'markdown-cur-line-blank-p "v2.4")
+(define-obsolete-function-alias
+  'markdown-next-line-blank 'markdown-next-line-blank-p "v2.4")
+
+(defun markdown-cur-line-blank-p ()
+  "Return t if the current line is blank and nil otherwise."
+  (save-excursion
+    (beginning-of-line)
+    (looking-at-p markdown-regex-blank-line)))
+
+(defun markdown-prev-line-blank ()
+  "Return t if the previous line is blank and nil otherwise.
+If we are at the first line, then consider the previous line to be blank."
+  (or (= (line-beginning-position) (point-min))
+      (save-excursion
+        (forward-line -1)
+        (looking-at markdown-regex-blank-line))))
+
+(defun markdown-prev-line-blank-p ()
+  "Like `markdown-prev-line-blank', but preserve `match-data'."
+  (save-match-data (markdown-prev-line-blank)))
+
+(defun markdown-next-line-blank-p ()
+  "Return t if the next line is blank and nil otherwise.
+If we are at the last line, then consider the next line to be blank."
+  (or (= (line-end-position) (point-max))
+      (save-excursion
+        (forward-line 1)
+        (markdown-cur-line-blank-p))))
+
+(defun markdown-prev-line-indent ()
+  "Return the number of leading whitespace characters in the previous line.
+Return 0 if the current line is the first line in the buffer."
+  (save-excursion
+    (if (= (line-beginning-position) (point-min))
+        0
+      (forward-line -1)
+      (current-indentation))))
+
+(defun markdown-next-line-indent ()
+  "Return the number of leading whitespace characters in the next line.
+Return 0 if line is the last line in the buffer."
+  (save-excursion
+    (if (= (line-end-position) (point-max))
+        0
+      (forward-line 1)
+      (current-indentation))))
+
+(defun markdown-new-baseline ()
+  "Determine if the current line begins a new baseline level.
+Assume point is positioned at beginning of line."
+  (or (looking-at markdown-regex-header)
+      (looking-at markdown-regex-hr)
+      (and (= (current-indentation) 0)
+           (not (looking-at markdown-regex-list))
+           (markdown-prev-line-blank))))
+
+(defun markdown-search-backward-baseline ()
+  "Search backward baseline point with no indentation and not a list item."
+  (end-of-line)
+  (let (stop)
+    (while (not (or stop (bobp)))
+      (re-search-backward markdown-regex-block-separator-noindent nil t)
+      (when (match-end 2)
+        (goto-char (match-end 2))
+        (cond
+         ((markdown-new-baseline)
+          (setq stop t))
+         ((looking-at-p markdown-regex-list)
+          (setq stop nil))
+         (t (setq stop t)))))))
+
+(defun markdown-update-list-levels (marker indent levels)
+  "Update list levels given list MARKER, block INDENT, and current LEVELS.
+Here, MARKER is a string representing the type of list, INDENT is an integer
+giving the indentation, in spaces, of the current block, and LEVELS is a
+list of the indentation levels of parent list items.  When LEVELS is nil,
+it means we are at baseline (not inside of a nested list)."
+  (cond
+   ;; New list item at baseline.
+   ((and marker (null levels))
+    (setq levels (list indent)))
+   ;; List item with greater indentation (four or more spaces).
+   ;; Increase list level.
+   ((and marker (>= indent (+ (car levels) 4)))
+    (setq levels (cons indent levels)))
+   ;; List item with greater or equal indentation (less than four spaces).
+   ;; Do not increase list level.
+   ((and marker (>= indent (car levels)))
+    levels)
+   ;; Lesser indentation level.
+   ;; Pop appropriate number of elements off LEVELS list (e.g., lesser
+   ;; indentation could move back more than one list level).  Note
+   ;; that this block need not be the beginning of list item.
+   ((< indent (car levels))
+    (while (and (> (length levels) 1)
+                (< indent (+ (cadr levels) 4)))
+      (setq levels (cdr levels)))
+    levels)
+   ;; Otherwise, do nothing.
+   (t levels)))
+
+(defun markdown-calculate-list-levels ()
+  "Calculate list levels at point.
+Return a list of the form (n1 n2 n3 ...) where n1 is the
+indentation of the deepest nested list item in the branch of
+the list at the point, n2 is the indentation of the parent
+list item, and so on.  The depth of the list item is therefore
+the length of the returned list.  If the point is not at or
+immediately  after a list item, return nil."
+  (save-excursion
+    (let ((first (point)) levels indent pre-regexp)
+      ;; Find a baseline point with zero list indentation
+      (markdown-search-backward-baseline)
+      ;; Search for all list items between baseline and LOC
+      (while (and (< (point) first)
+                  (re-search-forward markdown-regex-list first t))
+        (setq pre-regexp (format "^\\(    \\|\t\\)\\{%d\\}" (1+ (length levels))))
+        (beginning-of-line)
+        (cond
+         ;; Make sure this is not a header or hr
+         ((markdown-new-baseline) (setq levels nil))
+         ;; Make sure this is not a line from a pre block
+         ((looking-at-p pre-regexp))
+         ;; If not, then update levels
+         (t
+          (setq indent (current-indentation))
+          (setq levels (markdown-update-list-levels (match-string 2)
+                                                    indent levels))))
+        (end-of-line))
+      levels)))
+
+(defun markdown-prev-list-item (level)
+  "Search backward from point for a list item with indentation LEVEL.
+Set point to the beginning of the item, and return point, or nil
+upon failure."
+  (let (bounds indent prev)
+    (setq prev (point))
+    (forward-line -1)
+    (setq indent (current-indentation))
+    (while
+        (cond
+         ;; List item
+         ((and (looking-at-p markdown-regex-list)
+               (setq bounds (markdown-cur-list-item-bounds)))
+          (cond
+           ;; Stop and return point at item of equal indentation
+           ((= (nth 3 bounds) level)
+            (setq prev (point))
+            nil)
+           ;; Stop and return nil at item with lesser indentation
+           ((< (nth 3 bounds) level)
+            (setq prev nil)
+            nil)
+           ;; Stop at beginning of buffer
+           ((bobp) (setq prev nil))
+           ;; Continue at item with greater indentation
+           ((> (nth 3 bounds) level) t)))
+         ;; Stop at beginning of buffer
+         ((bobp) (setq prev nil))
+         ;; Continue if current line is blank
+         ((markdown-cur-line-blank-p) t)
+         ;; Continue while indentation is the same or greater
+         ((>= indent level) t)
+         ;; Stop if current indentation is less than list item
+         ;; and the next is blank
+         ((and (< indent level)
+               (markdown-next-line-blank-p))
+          (setq prev nil))
+         ;; Stop at a header
+         ((looking-at-p markdown-regex-header) (setq prev nil))
+         ;; Stop at a horizontal rule
+         ((looking-at-p markdown-regex-hr) (setq prev nil))
+         ;; Otherwise, continue.
+         (t t))
+      (forward-line -1)
+      (setq indent (current-indentation)))
+    prev))
+
+(defun markdown-next-list-item (level)
+  "Search forward from point for the next list item with indentation LEVEL.
+Set point to the beginning of the item, and return point, or nil
+upon failure."
+  (let (bounds indent next)
+    (setq next (point))
+    (if (looking-at markdown-regex-header-setext)
+        (goto-char (match-end 0)))
+    (forward-line)
+    (setq indent (current-indentation))
+    (while
+        (cond
+         ;; Stop at end of the buffer.
+         ((eobp) nil)
+         ;; Continue if the current line is blank
+         ((markdown-cur-line-blank-p) t)
+         ;; List item
+         ((and (looking-at-p markdown-regex-list)
+               (setq bounds (markdown-cur-list-item-bounds)))
+          (cond
+           ;; Continue at item with greater indentation
+           ((> (nth 3 bounds) level) t)
+           ;; Stop and return point at item of equal indentation
+           ((= (nth 3 bounds) level)
+            (setq next (point))
+            nil)
+           ;; Stop and return nil at item with lesser indentation
+           ((< (nth 3 bounds) level)
+            (setq next nil)
+            nil)))
+         ;; Continue while indentation is the same or greater
+         ((>= indent level) t)
+         ;; Stop if current indentation is less than list item
+         ;; and the previous line was blank.
+         ((and (< indent level)
+               (markdown-prev-line-blank-p))
+          (setq next nil))
+         ;; Stop at a header
+         ((looking-at-p markdown-regex-header) (setq next nil))
+         ;; Stop at a horizontal rule
+         ((looking-at-p markdown-regex-hr) (setq next nil))
+         ;; Otherwise, continue.
+         (t t))
+      (forward-line)
+      (setq indent (current-indentation)))
+    next))
+
+(defun markdown-cur-list-item-end (level)
+  "Move to end of list item with pre-marker indentation LEVEL.
+Return the point at the end when a list item was found at the
+original point.  If the point is not in a list item, do nothing."
+  (let (indent)
+    (forward-line)
+    (setq indent (current-indentation))
+    (while
+        (cond
+         ;; Stop at end of the buffer.
+         ((eobp) nil)
+         ;; Continue while indentation is the same or greater
+         ((>= indent level) t)
+         ;; Continue if the current line is blank
+         ((looking-at markdown-regex-blank-line) t)
+         ;; Stop if current indentation is less than list item
+         ;; and the previous line was blank.
+         ((and (< indent level)
+               (markdown-prev-line-blank))
+          nil)
+         ;; Stop at a new list items of the same or lesser
+         ;; indentation, headings, and horizontal rules.
+         ((looking-at (concat "\\(?:" markdown-regex-list
+                              "\\|" markdown-regex-header
+                              "\\|" markdown-regex-hr "\\)"))
+          nil)
+         ;; Otherwise, continue.
+         (t t))
+      (forward-line)
+      (setq indent (current-indentation)))
+    ;; Don't skip over whitespace for empty list items (marker and
+    ;; whitespace only), just move to end of whitespace.
+    (if (save-excursion
+          (beginning-of-line)
+          (looking-at (concat markdown-regex-list "[ \t]*$")))
+        (goto-char (match-end 3))
+      (skip-chars-backward " \t\n"))
+    (end-of-line)
+    (point)))
+
+(defun markdown-cur-list-item-bounds ()
+  "Return bounds for list item at point.
+Return a list of the following form:
+
+    (begin end indent nonlist-indent marker checkbox match)
+
+The named components are:
+
+  - begin: Position of beginning of list item, including leading indentation.
+  - end: Position of the end of the list item, including list item text.
+  - indent: Number of characters of indentation before list marker (an integer).
+  - nonlist-indent: Number characters of indentation, list
+    marker, and whitespace following list marker (an integer).
+  - marker: String containing the list marker and following whitespace
+            (e.g., \"- \" or \"* \").
+  - checkbox: String containing the GFM checkbox portion, if any,
+    including any trailing whitespace before the text
+    begins (e.g., \"[x] \").
+  - match: match data for markdown-regex-list
+
+As an example, for the following unordered list item
+
+   - item
+
+the returned list would be
+
+    (1 14 3 5 \"- \" nil (1 6 1 4 4 5 5 6))
+
+If the point is not inside a list item, return nil."
+  (car (get-text-property (point-at-bol) 'markdown-list-item)))
+
+(defun markdown-list-item-at-point-p ()
+  "Return t if there is a list item at the point and nil otherwise."
+  (save-match-data (markdown-cur-list-item-bounds)))
+
+(defun markdown-prev-list-item-bounds ()
+  "Return bounds of previous item in the same list of any level.
+The return value has the same form as that of
+`markdown-cur-list-item-bounds'."
+  (save-excursion
+    (let ((cur-bounds (markdown-cur-list-item-bounds))
+          (beginning-of-list (save-excursion (markdown-beginning-of-list)))
+          stop)
+      (when cur-bounds
+        (goto-char (nth 0 cur-bounds))
+        (while (and (not stop) (not (bobp))
+                    (re-search-backward markdown-regex-list
+                                        beginning-of-list t))
+          (unless (or (looking-at markdown-regex-hr)
+                      (markdown-code-block-at-point-p))
+            (setq stop (point))))
+        (markdown-cur-list-item-bounds)))))
+
+(defun markdown-next-list-item-bounds ()
+  "Return bounds of next item in the same list of any level.
+The return value has the same form as that of
+`markdown-cur-list-item-bounds'."
+  (save-excursion
+    (let ((cur-bounds (markdown-cur-list-item-bounds))
+          (end-of-list (save-excursion (markdown-end-of-list)))
+          stop)
+      (when cur-bounds
+        (goto-char (nth 0 cur-bounds))
+        (end-of-line)
+        (while (and (not stop) (not (eobp))
+                    (re-search-forward markdown-regex-list
+                                       end-of-list t))
+          (unless (or (looking-at markdown-regex-hr)
+                      (markdown-code-block-at-point-p))
+            (setq stop (point))))
+        (when stop
+          (markdown-cur-list-item-bounds))))))
+
+(defun markdown-beginning-of-list ()
+  "Move point to beginning of list at point, if any."
+  (interactive)
+  (let ((orig-point (point))
+        (list-begin (save-excursion
+                      (markdown-search-backward-baseline)
+                      ;; Stop at next list item, regardless of the indentation.
+                      (markdown-next-list-item (point-max))
+                      (when (looking-at markdown-regex-list)
+                        (point)))))
+    (when (and list-begin (<= list-begin orig-point))
+      (goto-char list-begin))))
+
+(defun markdown-end-of-list ()
+  "Move point to end of list at point, if any."
+  (interactive)
+  (let ((start (point))
+        (end (save-excursion
+               (when (markdown-beginning-of-list)
+                 ;; Items can't have nonlist-indent <= 1, so this
+                 ;; moves past all list items.
+                 (markdown-next-list-item 1)
+                 (skip-syntax-backward "-")
+                 (unless (eobp) (forward-char 1))
+                 (point)))))
+    (when (and end (>= end start))
+      (goto-char end))))
+
+(defun markdown-up-list ()
+  "Move point to beginning of parent list item."
+  (interactive)
+  (let ((cur-bounds (markdown-cur-list-item-bounds)))
+    (when cur-bounds
+      (markdown-prev-list-item (1- (nth 3 cur-bounds)))
+      (let ((up-bounds (markdown-cur-list-item-bounds)))
+        (when (and up-bounds (< (nth 3 up-bounds) (nth 3 cur-bounds)))
+          (point))))))
+
+(defun markdown-bounds-of-thing-at-point (thing)
+  "Call `bounds-of-thing-at-point' for THING with slight modifications.
+Does not include trailing newlines when THING is 'line.  Handles the
+end of buffer case by setting both endpoints equal to the value of
+`point-max', since an empty region will trigger empty markup insertion.
+Return bounds of form (beg . end) if THING is found, or nil otherwise."
+  (let* ((bounds (bounds-of-thing-at-point thing))
+         (a (car bounds))
+         (b (cdr bounds)))
+    (when bounds
+      (when (eq thing 'line)
+        (cond ((and (eobp) (markdown-cur-line-blank-p))
+               (setq a b))
+              ((char-equal (char-before b) ?\^J)
+               (setq b (1- b)))))
+      (cons a b))))
+
+(defun markdown-reference-definition (reference)
+  "Find out whether Markdown REFERENCE is defined.
+REFERENCE should not include the square brackets.
+When REFERENCE is defined, return a list of the form (text start end)
+containing the definition text itself followed by the start and end
+locations of the text.  Otherwise, return nil.
+Leave match data for `markdown-regex-reference-definition'
+intact additional processing."
+  (let ((reference (downcase reference)))
+    (save-excursion
+      (goto-char (point-min))
+      (catch 'found
+        (while (re-search-forward markdown-regex-reference-definition nil t)
+          (when (string= reference (downcase (match-string-no-properties 2)))
+            (throw 'found
+                   (list (match-string-no-properties 5)
+                         (match-beginning 5) (match-end 5)))))))))
+
+(defun markdown-get-defined-references ()
+  "Return all defined reference labels and their line numbers (not including square brackets)."
+  (save-excursion
+    (goto-char (point-min))
+    (let (refs)
+      (while (re-search-forward markdown-regex-reference-definition nil t)
+        (let ((target (match-string-no-properties 2)))
+          (cl-pushnew
+           (cons (downcase target)
+                 (markdown-line-number-at-pos (match-beginning 2)))
+           refs :test #'equal :key #'car)))
+      (reverse refs))))
+
+(defun markdown-get-used-uris ()
+  "Return a list of all used URIs in the buffer."
+  (save-excursion
+    (goto-char (point-min))
+    (let (uris)
+      (while (re-search-forward
+              (concat "\\(?:" markdown-regex-link-inline
+                      "\\|" markdown-regex-angle-uri
+                      "\\|" markdown-regex-uri
+                      "\\|" markdown-regex-email
+                      "\\)")
+              nil t)
+        (unless (or (markdown-inline-code-at-point-p)
+                    (markdown-code-block-at-point-p))
+          (cl-pushnew (or (match-string-no-properties 6)
+                          (match-string-no-properties 10)
+                          (match-string-no-properties 12)
+                          (match-string-no-properties 13))
+                      uris :test #'equal)))
+      (reverse uris))))
+
+(defun markdown-inline-code-at-pos (pos)
+  "Return non-nil if there is an inline code fragment at POS.
+Return nil otherwise.  Set match data according to
+`markdown-match-code' upon success.
+This function searches the block for a code fragment that
+contains the point using `markdown-match-code'.  We do this
+because `thing-at-point-looking-at' does not work reliably with
+`markdown-regex-code'.
+
+The match data is set as follows:
+Group 1 matches the opening backquotes.
+Group 2 matches the code fragment itself, without backquotes.
+Group 3 matches the closing backquotes."
+  (save-excursion
+    (goto-char pos)
+    (let ((old-point (point))
+          (end-of-block (progn (markdown-end-of-text-block) (point)))
+          found)
+      (markdown-beginning-of-text-block)
+      (while (and (markdown-match-code end-of-block)
+                  (setq found t)
+                  (< (match-end 0) old-point)))
+      (and found                              ; matched something
+           (<= (match-beginning 0) old-point) ; match contains old-point
+           (> (match-end 0) old-point)))))
+
+(defun markdown-inline-code-at-pos-p (pos)
+  "Return non-nil if there is an inline code fragment at POS.
+Like `markdown-inline-code-at-pos`, but preserves match data."
+  (save-match-data (markdown-inline-code-at-pos pos)))
+
+(defun markdown-inline-code-at-point ()
+  "Return non-nil if the point is at an inline code fragment.
+See `markdown-inline-code-at-pos' for details."
+  (markdown-inline-code-at-pos (point)))
+
+(defun markdown-inline-code-at-point-p ()
+  "Return non-nil if there is inline code at the point.
+This is a predicate function counterpart to
+`markdown-inline-code-at-point' which does not modify the match
+data.  See `markdown-code-block-at-point-p' for code blocks."
+  (save-match-data (markdown-inline-code-at-pos (point))))
+
+(make-obsolete 'markdown-code-at-point-p 'markdown-inline-code-at-point-p "v2.2")
+
+(defun markdown-code-block-at-pos (pos)
+  "Return match data list if there is a code block at POS.
+Uses text properties at the beginning of the line position.
+This includes pre blocks, tilde-fenced code blocks, and GFM
+quoted code blocks.  Return nil otherwise."
+  (setq pos (save-excursion (goto-char pos) (point-at-bol)))
+  (or (get-text-property pos 'markdown-pre)
+      (markdown-get-enclosing-fenced-block-construct pos)
+      ;; polymode removes text properties set by markdown-mode, so
+      ;; check if `poly-markdown-mode' is active and whether the
+      ;; `chunkmode' property is non-nil at POS.
+      (and (bound-and-true-p poly-markdown-mode)
+           (get-text-property pos 'chunkmode))))
+
+;; Function was renamed to emphasize that it does not modify match-data.
+(defalias 'markdown-code-block-at-point 'markdown-code-block-at-point-p)
+
+(defun markdown-code-block-at-point-p ()
+  "Return non-nil if there is a code block at the point.
+This includes pre blocks, tilde-fenced code blocks, and GFM
+quoted code blocks.  This function does not modify the match
+data.  See `markdown-inline-code-at-point-p' for inline code."
+  (save-match-data (markdown-code-block-at-pos (point))))
+
+(defun markdown-heading-at-point ()
+  "Return non-nil if there is a heading at the point.
+Set match data for `markdown-regex-header'."
+  (let ((match-data (get-text-property (point) 'markdown-heading)))
+    (when match-data
+      (set-match-data match-data)
+      t)))
+
+(defun markdown-pipe-at-bol-p ()
+  "Return non-nil if the line begins with a pipe symbol.
+This may be useful for tables and Pandoc's line_blocks extension."
+  (char-equal (char-after (point-at-bol)) ?|))
+
+
+;;; Markdown Font Lock Matching Functions =====================================
+
+(defun markdown-range-property-any (begin end prop prop-values)
+  "Return t if PROP from BEGIN to END is equal to one of the given PROP-VALUES.
+Also returns t if PROP is a list containing one of the PROP-VALUES.
+Return nil otherwise."
+  (let (props)
+    (catch 'found
+      (dolist (loc (number-sequence begin end))
+        (when (setq props (get-text-property loc prop))
+          (cond ((listp props)
+                 ;; props is a list, check for membership
+                 (dolist (val prop-values)
+                   (when (memq val props) (throw 'found loc))))
+                (t
+                 ;; props is a scalar, check for equality
+                 (dolist (val prop-values)
+                   (when (eq val props) (throw 'found loc))))))))))
+
+(defun markdown-range-properties-exist (begin end props)
+  (cl-loop
+   for loc in (number-sequence begin end)
+   with result = nil
+   while (not
+          (setq result
+                (cl-some (lambda (prop) (get-text-property loc prop)) props)))
+   finally return result))
+
+(defun markdown-match-inline-generic (regex last &optional faceless)
+  "Match inline REGEX from the point to LAST.
+When FACELESS is non-nil, do not return matches where faces have been applied."
+  (when (re-search-forward regex last t)
+    (let ((bounds (markdown-code-block-at-pos (match-beginning 1)))
+          (face (and faceless (text-property-not-all
+                               (match-beginning 0) (match-end 0) 'face nil))))
+      (cond
+       ;; In code block: move past it and recursively search again
+       (bounds
+        (when (< (goto-char (cl-second bounds)) last)
+          (markdown-match-inline-generic regex last faceless)))
+       ;; When faces are found in the match range, skip over the match and
+       ;; recursively search again.
+       (face
+        (when (< (goto-char (match-end 0)) last)
+          (markdown-match-inline-generic regex last faceless)))
+       ;; Keep match data and return t when in bounds.
+       (t
+        (<= (match-end 0) last))))))
+
+(defun markdown-match-code (last)
+  "Match inline code fragments from point to LAST."
+  (unless (bobp)
+    (backward-char 1))
+  (when (markdown-search-until-condition
+         (lambda ()
+           (and
+            ;; Advance point in case of failure, but without exceeding last.
+            (goto-char (min (1+ (match-beginning 1)) last))
+            (not (markdown-in-comment-p (match-beginning 1)))
+            (not (markdown-in-comment-p (match-end 1)))
+            (not (markdown-code-block-at-pos (match-beginning 1)))))
+         markdown-regex-code last t)
+      (set-match-data (list (match-beginning 1) (match-end 1)
+                            (match-beginning 2) (match-end 2)
+                            (match-beginning 3) (match-end 3)
+                            (match-beginning 4) (match-end 4)))
+      (goto-char (min (1+ (match-end 0)) last (point-max)))
+      t))
+
+(defun markdown-match-bold (last)
+  "Match inline bold from the point to LAST."
+  (when (markdown-match-inline-generic markdown-regex-bold last)
+    (let ((begin (match-beginning 2))
+          (end (match-end 2)))
+      (if (or (markdown-inline-code-at-pos-p begin)
+              (markdown-inline-code-at-pos-p end)
+              (markdown-in-comment-p)
+              (markdown-range-property-any
+               begin begin 'face '(markdown-url-face
+                                   markdown-plain-url-face))
+              (markdown-range-property-any
+               begin end 'face '(markdown-hr-face
+                                 markdown-math-face)))
+          (progn (goto-char (min (1+ begin) last))
+                 (when (< (point) last)
+                   (markdown-match-italic last)))
+        (set-match-data (list (match-beginning 2) (match-end 2)
+                              (match-beginning 3) (match-end 3)
+                              (match-beginning 4) (match-end 4)
+                              (match-beginning 5) (match-end 5)))
+        t))))
+
+(defun markdown-match-italic (last)
+  "Match inline italics from the point to LAST."
+  (let ((regex (if (memq major-mode '(gfm-mode gfm-view-mode))
+                   markdown-regex-gfm-italic markdown-regex-italic)))
+    (when (markdown-match-inline-generic regex last)
+      (let ((begin (match-beginning 1))
+            (end (match-end 1)))
+        (if (or (markdown-inline-code-at-pos-p begin)
+                (markdown-inline-code-at-pos-p end)
+                (markdown-in-comment-p)
+                (markdown-range-property-any
+                 begin begin 'face '(markdown-url-face
+                                     markdown-plain-url-face))
+                (markdown-range-property-any
+                 begin end 'face '(markdown-bold-face
+                                   markdown-list-face
+                                   markdown-hr-face
+                                   markdown-math-face)))
+            (progn (goto-char (min (1+ begin) last))
+                   (when (< (point) last)
+                     (markdown-match-italic last)))
+          (set-match-data (list (match-beginning 1) (match-end 1)
+                                (match-beginning 2) (match-end 2)
+                                (match-beginning 3) (match-end 3)
+                                (match-beginning 4) (match-end 4)))
+          t)))))
+
+(defun markdown-match-math-generic (regex last)
+  "Match REGEX from point to LAST.
+REGEX is either `markdown-regex-math-inline-single' for matching
+$..$ or `markdown-regex-math-inline-double' for matching $$..$$."
+  (when (and markdown-enable-math (markdown-match-inline-generic regex last))
+    (let ((begin (match-beginning 1)) (end (match-end 1)))
+      (prog1
+          (if (or (markdown-range-property-any
+                   begin end 'face
+                   '(markdown-inline-code-face markdown-bold-face))
+                  (markdown-range-properties-exist
+                   begin end
+                   (markdown-get-fenced-block-middle-properties)))
+              (markdown-match-math-generic regex last)
+            t)
+        (goto-char (1+ (match-end 0)))))))
+
+(defun markdown-match-list-items (last)
+  "Match list items from point to LAST."
+  (let* ((first (point))
+         (pos first)
+         (prop 'markdown-list-item)
+         (bounds (car (get-text-property pos prop))))
+    (while
+        (and (or (null (setq bounds (car (get-text-property pos prop))))
+                 (< (cl-first bounds) pos))
+             (< (point) last)
+             (setq pos (next-single-property-change pos prop nil last))
+             (goto-char pos)))
+    (when bounds
+      (set-match-data (cl-seventh bounds))
+      ;; Step at least one character beyond point. Otherwise
+      ;; `font-lock-fontify-keywords-region' infloops.
+      (goto-char (min (1+ (max (point-at-eol) first))
+                      (point-max)))
+      t)))
+
+(defun markdown-match-math-single (last)
+  "Match single quoted $..$ math from point to LAST."
+  (markdown-match-math-generic markdown-regex-math-inline-single last))
+
+(defun markdown-match-math-double (last)
+  "Match double quoted $$..$$ math from point to LAST."
+  (markdown-match-math-generic markdown-regex-math-inline-double last))
+
+(defun markdown-match-math-display (last)
+  "Match bracketed display math \[..\] and \\[..\\] from point to LAST."
+  (markdown-match-math-generic markdown-regex-math-display last))
+
+(defun markdown-match-propertized-text (property last)
+  "Match text with PROPERTY from point to LAST.
+Restore match data previously stored in PROPERTY."
+  (let ((saved (get-text-property (point) property))
+        pos)
+    (unless saved
+      (setq pos (next-single-property-change (point) property nil last))
+      (setq saved (get-text-property pos property)))
+    (when saved
+      (set-match-data saved)
+      ;; Step at least one character beyond point. Otherwise
+      ;; `font-lock-fontify-keywords-region' infloops.
+      (goto-char (min (1+ (max (match-end 0) (point)))
+                      (point-max)))
+      saved)))
+
+(defun markdown-match-pre-blocks (last)
+  "Match preformatted blocks from point to LAST.
+Use data stored in 'markdown-pre text property during syntax
+analysis."
+  (markdown-match-propertized-text 'markdown-pre last))
+
+(defun markdown-match-gfm-code-blocks (last)
+  "Match GFM quoted code blocks from point to LAST.
+Use data stored in 'markdown-gfm-code text property during syntax
+analysis."
+  (markdown-match-propertized-text 'markdown-gfm-code last))
+
+(defun markdown-match-gfm-open-code-blocks (last)
+  (markdown-match-propertized-text 'markdown-gfm-block-begin last))
+
+(defun markdown-match-gfm-close-code-blocks (last)
+  (markdown-match-propertized-text 'markdown-gfm-block-end last))
+
+(defun markdown-match-fenced-code-blocks (last)
+  "Match fenced code blocks from the point to LAST."
+  (markdown-match-propertized-text 'markdown-fenced-code last))
+
+(defun markdown-match-fenced-start-code-block (last)
+  (markdown-match-propertized-text 'markdown-tilde-fence-begin last))
+
+(defun markdown-match-fenced-end-code-block (last)
+  (markdown-match-propertized-text 'markdown-tilde-fence-end last))
+
+(defun markdown-match-blockquotes (last)
+  "Match blockquotes from point to LAST.
+Use data stored in 'markdown-blockquote text property during syntax
+analysis."
+  (markdown-match-propertized-text 'markdown-blockquote last))
+
+(defun markdown-match-hr (last)
+  "Match horizontal rules comments from the point to LAST."
+  (markdown-match-propertized-text 'markdown-hr last))
+
+(defun markdown-match-comments (last)
+  "Match HTML comments from the point to LAST."
+  (when (and (skip-syntax-forward "^<" last))
+    (let ((beg (point)))
+      (when (and (skip-syntax-forward "^>" last) (< (point) last))
+        (forward-char)
+        (set-match-data (list beg (point)))
+        t))))
+
+(defun markdown-match-generic-links (last ref)
+  "Match inline links from point to LAST.
+When REF is non-nil, match reference links instead of standard
+links with URLs.
+This function should only be used during font-lock, as it
+determines syntax based on the presence of faces for previously
+processed elements."
+  ;; Search for the next potential link (not in a code block).
+  (let ((prohibited-faces '(markdown-pre-face
+                            markdown-code-face
+                            markdown-inline-code-face
+                            markdown-comment-face))
+        found)
+    (while
+        (and (not found) (< (point) last)
+             (progn
+               ;; Clear match data to test for a match after functions returns.
+               (set-match-data nil)
+               ;; Preliminary regular expression search so we can return
+               ;; quickly upon failure.  This doesn't handle malformed links
+               ;; or nested square brackets well, so if it passes we back up
+               ;; continue with a more precise search.
+               (re-search-forward
+                (if ref
+                    markdown-regex-link-reference
+                  markdown-regex-link-inline)
+                last 'limit)))
+      ;; Keep searching if this is in a code block, inline code, or a
+      ;; comment, or if it is include syntax. The link text portion
+      ;; (group 3) may contain inline code or comments, but the
+      ;; markup, URL, and title should not be part of such elements.
+      (if (or (markdown-range-property-any
+               (match-beginning 0) (match-end 2) 'face prohibited-faces)
+              (markdown-range-property-any
+               (match-beginning 4) (match-end 0) 'face prohibited-faces)
+              (and (char-equal (char-after (point-at-bol)) ?<)
+                   (char-equal (char-after (1+ (point-at-bol))) ?<)))
+          (set-match-data nil)
+        (setq found t))))
+  ;; Match opening exclamation point (optional) and left bracket.
+  (when (match-beginning 2)
+    (let* ((bang (match-beginning 1))
+           (first-begin (match-beginning 2))
+           ;; Find end of block to prevent matching across blocks.
+           (end-of-block (save-excursion
+                           (progn
+                             (goto-char (match-beginning 2))
+                             (markdown-end-of-text-block)
+                             (point))))
+           ;; Move over balanced expressions to closing right bracket.
+           ;; Catch unbalanced expression errors and return nil.
+           (first-end (condition-case nil
+                           (and (goto-char first-begin)
+                                (scan-sexps (point) 1))
+                         (error nil)))
+           ;; Continue with point at CONT-POINT upon failure.
+           (cont-point (min (1+ first-begin) last))
+           second-begin second-end url-begin url-end
+           title-begin title-end)
+      ;; When bracket found, in range, and followed by a left paren/bracket...
+      (when (and first-end (< first-end end-of-block) (goto-char first-end)
+                 (char-equal (char-after (point)) (if ref ?\[ ?\()))
+        ;; Scan across balanced expressions for closing parenthesis/bracket.
+        (setq second-begin (point)
+              second-end (condition-case nil
+                            (scan-sexps (point) 1)
+                          (error nil)))
+        ;; Check that closing parenthesis/bracket is in range.
+        (if (and second-end (<= second-end end-of-block) (<= second-end last))
+            (progn
+              ;; Search for (optional) title inside closing parenthesis
+              (when (and (not ref) (search-forward "\"" second-end t))
+                (setq title-begin (1- (point))
+                      title-end (and (goto-char second-end)
+                                     (search-backward "\"" (1+ title-begin) t))
+                      title-end (and title-end (1+ title-end))))
+              ;; Store URL/reference range
+              (setq url-begin (1+ second-begin)
+                    url-end (1- (or title-begin second-end)))
+              ;; Set match data, move point beyond link, and return
+              (set-match-data
+               (list (or bang first-begin) second-end  ; 0 - all
+                     bang (and bang (1+ bang))         ; 1 - bang
+                     first-begin (1+ first-begin)      ; 2 - markup
+                     (1+ first-begin) (1- first-end)   ; 3 - link text
+                     (1- first-end) first-end          ; 4 - markup
+                     second-begin (1+ second-begin)    ; 5 - markup
+                     url-begin url-end                 ; 6 - url/reference
+                     title-begin title-end             ; 7 - title
+                     (1- second-end) second-end))      ; 8 - markup
+              ;; Nullify cont-point and leave point at end and
+              (setq cont-point nil)
+              (goto-char second-end))
+          ;; If no closing parenthesis in range, update continuation point
+          (setq cont-point (min end-of-block second-begin))))
+      (cond
+       ;; On failure, continue searching at cont-point
+       ((and cont-point (< cont-point last))
+        (goto-char cont-point)
+        (markdown-match-generic-links last ref))
+       ;; No more text, return nil
+       ((and cont-point (= cont-point last))
+        nil)
+       ;; Return t if a match occurred
+       (t t)))))
+
+(defun markdown-match-angle-uris (last)
+  "Match angle bracket URIs from point to LAST."
+  (when (markdown-match-inline-generic markdown-regex-angle-uri last)
+    (goto-char (1+ (match-end 0)))))
+
+(defun markdown-match-plain-uris (last)
+  "Match plain URIs from point to LAST."
+  (when (markdown-match-inline-generic markdown-regex-uri last t)
+    (goto-char (1+ (match-end 0)))))
+
+(defvar markdown-conditional-search-function #'re-search-forward
+  "Conditional search function used in `markdown-search-until-condition'.
+Made into a variable to allow for dynamic let-binding.")
+
+(defun markdown-search-until-condition (condition &rest args)
+  (let (ret)
+    (while (and (not ret) (apply markdown-conditional-search-function args))
+      (setq ret (funcall condition)))
+    ret))
+
+(defun markdown-match-generic-metadata (regexp last)
+  "Match metadata declarations specified by REGEXP from point to LAST.
+These declarations must appear inside a metadata block that begins at
+the beginning of the buffer and ends with a blank line (or the end of
+the buffer)."
+  (let* ((first (point))
+         (end-re "\n[ \t]*\n\\|\n\\'\\|\\'")
+         (block-begin (goto-char 1))
+         (block-end (re-search-forward end-re nil t)))
+    (if (and block-end (> first block-end))
+        ;; Don't match declarations if there is no metadata block or if
+        ;; the point is beyond the block.  Move point to point-max to
+        ;; prevent additional searches and return return nil since nothing
+        ;; was found.
+        (progn (goto-char (point-max)) nil)
+      ;; If a block was found that begins before LAST and ends after
+      ;; point, search for declarations inside it.  If the starting is
+      ;; before the beginning of the block, start there. Otherwise,
+      ;; move back to FIRST.
+      (goto-char (if (< first block-begin) block-begin first))
+      (if (re-search-forward regexp (min last block-end) t)
+          ;; If a metadata declaration is found, set match-data and return t.
+          (let ((key-beginning (match-beginning 1))
+                (key-end (match-end 1))
+                (markup-begin (match-beginning 2))
+                (markup-end (match-end 2))
+                (value-beginning (match-beginning 3)))
+            (set-match-data (list key-beginning (point) ; complete metadata
+                                  key-beginning key-end ; key
+                                  markup-begin markup-end ; markup
+                                  value-beginning (point))) ; value
+            t)
+        ;; Otherwise, move the point to last and return nil
+        (goto-char last)
+        nil))))
+
+(defun markdown-match-declarative-metadata (last)
+  "Match declarative metadata from the point to LAST."
+  (markdown-match-generic-metadata markdown-regex-declarative-metadata last))
+
+(defun markdown-match-pandoc-metadata (last)
+  "Match Pandoc metadata from the point to LAST."
+  (markdown-match-generic-metadata markdown-regex-pandoc-metadata last))
+
+(defun markdown-match-yaml-metadata-begin (last)
+  (markdown-match-propertized-text 'markdown-yaml-metadata-begin last))
+
+(defun markdown-match-yaml-metadata-end (last)
+  (markdown-match-propertized-text 'markdown-yaml-metadata-end last))
+
+(defun markdown-match-yaml-metadata-key (last)
+  (markdown-match-propertized-text 'markdown-metadata-key last))
+
+(defun markdown-match-wiki-link (last)
+  "Match wiki links from point to LAST."
+  (when (and markdown-enable-wiki-links
+             (not markdown-wiki-link-fontify-missing)
+             (markdown-match-inline-generic markdown-regex-wiki-link last))
+    (let ((begin (match-beginning 1)) (end (match-end 1)))
+      (if (or (markdown-in-comment-p begin)
+              (markdown-in-comment-p end)
+              (markdown-inline-code-at-pos-p begin)
+              (markdown-inline-code-at-pos-p end)
+              (markdown-code-block-at-pos begin))
+          (progn (goto-char (min (1+ begin) last))
+                 (when (< (point) last)
+                   (markdown-match-wiki-link last)))
+        (set-match-data (list begin end))
+        t))))
+
+(defun markdown-match-inline-attributes (last)
+  "Match inline attributes from point to LAST."
+  (when (markdown-match-inline-generic markdown-regex-inline-attributes last)
+    (unless (or (markdown-inline-code-at-pos-p (match-beginning 0))
+                (markdown-inline-code-at-pos-p (match-end 0))
+                (markdown-in-comment-p))
+      t)))
+
+(defun markdown-match-leanpub-sections (last)
+  "Match Leanpub section markers from point to LAST."
+  (when (markdown-match-inline-generic markdown-regex-leanpub-sections last)
+    (unless (or (markdown-inline-code-at-pos-p (match-beginning 0))
+                (markdown-inline-code-at-pos-p (match-end 0))
+                (markdown-in-comment-p))
+      t)))
+
+(defun markdown-match-includes (last)
+  "Match include statements from point to LAST.
+Sets match data for the following seven groups:
+Group 1: opening two angle brackets
+Group 2: opening title delimiter (optional)
+Group 3: title text (optional)
+Group 4: closing title delimiter (optional)
+Group 5: opening filename delimiter
+Group 6: filename
+Group 7: closing filename delimiter"
+  (when (markdown-match-inline-generic markdown-regex-include last)
+    (let ((valid (not (or (markdown-in-comment-p (match-beginning 0))
+                          (markdown-in-comment-p (match-end 0))
+                          (markdown-code-block-at-pos (match-beginning 0))))))
+      (cond
+       ;; Parentheses and maybe square brackets, but no curly braces:
+       ;; match optional title in square brackets and file in parentheses.
+       ((and valid (match-beginning 5)
+             (not (match-beginning 8)))
+        (set-match-data (list (match-beginning 1) (match-end 7)
+                              (match-beginning 1) (match-end 1)
+                              (match-beginning 2) (match-end 2)
+                              (match-beginning 3) (match-end 3)
+                              (match-beginning 4) (match-end 4)
+                              (match-beginning 5) (match-end 5)
+                              (match-beginning 6) (match-end 6)
+                              (match-beginning 7) (match-end 7))))
+       ;; Only square brackets present: match file in square brackets.
+       ((and valid (match-beginning 2)
+             (not (match-beginning 5))
+             (not (match-beginning 7)))
+        (set-match-data (list (match-beginning 1) (match-end 4)
+                              (match-beginning 1) (match-end 1)
+                              nil nil
+                              nil nil
+                              nil nil
+                              (match-beginning 2) (match-end 2)
+                              (match-beginning 3) (match-end 3)
+                              (match-beginning 4) (match-end 4))))
+       ;; Only curly braces present: match file in curly braces.
+       ((and valid (match-beginning 8)
+             (not (match-beginning 2))
+             (not (match-beginning 5)))
+        (set-match-data (list (match-beginning 1) (match-end 10)
+                              (match-beginning 1) (match-end 1)
+                              nil nil
+                              nil nil
+                              nil nil
+                              (match-beginning 8) (match-end 8)
+                              (match-beginning 9) (match-end 9)
+                              (match-beginning 10) (match-end 10))))
+       (t
+        ;; Not a valid match, move to next line and search again.
+        (forward-line)
+        (when (< (point) last)
+          (setq valid (markdown-match-includes last)))))
+      valid)))
+
+(defun markdown-match-html-tag (last)
+  "Match HTML tags from point to LAST."
+  (when (and markdown-enable-html
+             (markdown-match-inline-generic markdown-regex-html-tag last t))
+    (set-match-data (list (match-beginning 0) (match-end 0)
+                          (match-beginning 1) (match-end 1)
+                          (match-beginning 2) (match-end 2)
+                          (match-beginning 9) (match-end 9)))
+    t))
+
+
+;;; Markdown Font Fontification Functions =====================================
+
+(defun markdown--first-displayable (seq)
+  "Return the first displayable character or string in SEQ.
+SEQ may be an atom or a sequence."
+  (let ((seq (if (listp seq) seq (list seq))))
+    (cond ((stringp (car seq))
+           (cl-find-if
+            (lambda (str)
+              (and (mapcar #'char-displayable-p (string-to-list str))))
+            seq))
+          ((characterp (car seq))
+           (cl-find-if #'char-displayable-p seq)))))
+
+(defun markdown--marginalize-string (level)
+  "Generate atx markup string of given LEVEL for left margin."
+  (let ((margin-left-space-count
+         (- markdown-marginalize-headers-margin-width level)))
+    (concat (make-string margin-left-space-count ? )
+                           (make-string level ?#))))
+
+(defun markdown-marginalize-update-current ()
+  "Update the window configuration to create a left margin."
+  ;; Emacs 25 or later is needed for window-font-width and default-font-width.
+  (if (and (fboundp 'window-font-width) (fboundp 'default-font-width))
+      (let* ((header-delimiter-font-width
+              (window-font-width nil 'markdown-header-delimiter-face))
+             (margin-pixel-width (* markdown-marginalize-headers-margin-width
+                                    header-delimiter-font-width))
+             (margin-char-width (/ margin-pixel-width (default-font-width))))
+        (set-window-margins nil margin-char-width))
+    ;; As a fallback, simply set margin based on character count.
+    (set-window-margins nil markdown-marginalize-headers-margin-width)))
+
+(defun markdown-fontify-headings (last)
+  "Add text properties to headings from point to LAST."
+  (when (markdown-match-propertized-text 'markdown-heading last)
+    (let* ((level (markdown-outline-level))
+           (heading-face
+            (intern (format "markdown-header-face-%d" level)))
+           (heading-props `(face ,heading-face))
+           (left-markup-props
+            `(face markdown-header-delimiter-face
+                   ,@(cond
+                      (markdown-hide-markup
+                       `(display ""))
+                      (markdown-marginalize-headers
+                       `(display ((margin left-margin)
+                                  ,(markdown--marginalize-string level)))))))
+           (right-markup-props
+            `(face markdown-header-delimiter-face
+                   ,@(when markdown-hide-markup `(display ""))))
+           (rule-props `(face markdown-header-rule-face
+                              ,@(when markdown-hide-markup `(display "")))))
+      (if (match-end 1)
+          ;; Setext heading
+          (progn (add-text-properties
+                  (match-beginning 1) (match-end 1) heading-props)
+                 (if (= level 1)
+                     (add-text-properties
+                      (match-beginning 2) (match-end 2) rule-props)
+                   (add-text-properties
+                    (match-beginning 3) (match-end 3) rule-props)))
+        ;; atx heading
+        (add-text-properties
+         (match-beginning 4) (match-end 4) left-markup-props)
+        (add-text-properties
+         (match-beginning 5) (match-end 5) heading-props)
+        (when (match-end 6)
+          (add-text-properties
+           (match-beginning 6) (match-end 6) right-markup-props))))
+    t))
+
+(defun markdown-fontify-tables (last)
+  (when (and (re-search-forward "|" last t)
+             (markdown-table-at-point-p))
+    (font-lock-append-text-property
+     (line-beginning-position) (min (1+ (line-end-position)) (point-max))
+     'face 'markdown-table-face)
+    (forward-line 1)
+    t))
+
+(defun markdown-fontify-blockquotes (last)
+  "Apply font-lock properties to blockquotes from point to LAST."
+  (when (markdown-match-blockquotes last)
+    (let ((display-string
+           (markdown--first-displayable markdown-blockquote-display-char)))
+      (add-text-properties
+       (match-beginning 1) (match-end 1)
+       (if markdown-hide-markup
+           `(face markdown-blockquote-face display ,display-string)
+         `(face markdown-markup-face)))
+      (font-lock-append-text-property
+       (match-beginning 0) (match-end 0) 'face 'markdown-blockquote-face)
+      t)))
+
+(defun markdown-fontify-list-items (last)
+  "Apply font-lock properties to list markers from point to LAST."
+  (when (markdown-match-list-items last)
+    (let* ((indent (length (match-string-no-properties 1)))
+           (level (/ indent 4)) ;; level = 0, 1, 2, ...
+           (bullet (nth (mod level (length markdown-list-item-bullets))
+                        markdown-list-item-bullets)))
+      (add-text-properties
+       (match-beginning 2) (match-end 2) '(face markdown-list-face))
+      (when markdown-hide-markup
+        (cond
+         ;; Unordered lists
+         ((string-match-p "[\\*\\+-]" (match-string 2))
+          (add-text-properties
+           (match-beginning 2) (match-end 2) `(display ,bullet)))
+         ;; Definition lists
+         ((string-equal ":" (match-string 2))
+          (let ((display-string
+                 (char-to-string (markdown--first-displayable
+                                  markdown-definition-display-char))))
+            (add-text-properties (match-beginning 2) (match-end 2)
+                                 `(display ,display-string)))))))
+    t))
+
+(defun markdown-fontify-hrs (last)
+  "Add text properties to horizontal rules from point to LAST."
+  (when (markdown-match-hr last)
+    (let ((hr-char (markdown--first-displayable markdown-hr-display-char)))
+      (add-text-properties
+       (match-beginning 0) (match-end 0)
+       `(face markdown-hr-face
+              font-lock-multiline t
+              ,@(when (and markdown-hide-markup hr-char)
+                  `(display ,(make-string
+                              (window-body-width) hr-char)))))
+      t)))
+
+(defun markdown-fontify-sub-superscripts (last)
+  "Apply text properties to sub- and superscripts from point to LAST."
+  (when (markdown-search-until-condition
+         (lambda () (and (not (markdown-code-block-at-point-p))
+                         (not (markdown-inline-code-at-point-p))
+                         (not (markdown-in-comment-p))))
+         markdown-regex-sub-superscript last t)
+    (let* ((subscript-p (string= (match-string 2) "~"))
+           (props
+            (if subscript-p
+                (car markdown-sub-superscript-display)
+              (cdr markdown-sub-superscript-display)))
+           (mp (list 'face 'markdown-markup-face
+                     'invisible 'markdown-markup)))
+      (when markdown-hide-markup
+        (put-text-property (match-beginning 3) (match-end 3)
+                           'display props))
+      (add-text-properties (match-beginning 2) (match-end 2) mp)
+      (add-text-properties (match-beginning 4) (match-end 4) mp)
+      t)))
+
+
+;;; Syntax Table ==============================================================
+
+(defvar markdown-mode-syntax-table
+  (let ((tab (make-syntax-table text-mode-syntax-table)))
+    (modify-syntax-entry ?\" "." tab)
+    tab)
+  "Syntax table for `markdown-mode'.")
+
+
+;;; Element Insertion =========================================================
+
+(defun markdown-ensure-blank-line-before ()
+  "If previous line is not already blank, insert a blank line before point."
+  (unless (bolp) (insert "\n"))
+  (unless (or (bobp) (looking-back "\n\\s-*\n" nil)) (insert "\n")))
+
+(defun markdown-ensure-blank-line-after ()
+  "If following line is not already blank, insert a blank line after point.
+Return the point where it was originally."
+  (save-excursion
+    (unless (eolp) (insert "\n"))
+    (unless (or (eobp) (looking-at-p "\n\\s-*\n")) (insert "\n"))))
+
+(defun markdown-wrap-or-insert (s1 s2 &optional thing beg end)
+  "Insert the strings S1 and S2, wrapping around region or THING.
+If a region is specified by the optional BEG and END arguments,
+wrap the strings S1 and S2 around that region.
+If there is an active region, wrap the strings S1 and S2 around
+the region.  If there is not an active region but the point is at
+THING, wrap that thing (which defaults to word).  Otherwise, just
+insert S1 and S2 and place the point in between.  Return the
+bounds of the entire wrapped string, or nil if nothing was wrapped
+and S1 and S2 were only inserted."
+  (let (a b bounds new-point)
+    (cond
+     ;; Given region
+     ((and beg end)
+      (setq a beg
+            b end
+            new-point (+ (point) (length s1))))
+     ;; Active region
+     ((markdown-use-region-p)
+      (setq a (region-beginning)
+            b (region-end)
+            new-point (+ (point) (length s1))))
+     ;; Thing (word) at point
+     ((setq bounds (markdown-bounds-of-thing-at-point (or thing 'word)))
+      (setq a (car bounds)
+            b (cdr bounds)
+            new-point (+ (point) (length s1))))
+     ;; No active region and no word
+     (t
+      (setq a (point)
+            b (point))))
+    (goto-char b)
+    (insert s2)
+    (goto-char a)
+    (insert s1)
+    (when new-point (goto-char new-point))
+    (if (= a b)
+        nil
+      (setq b (+ b (length s1) (length s2)))
+      (cons a b))))
+
+(defun markdown-point-after-unwrap (cur prefix suffix)
+  "Return desired position of point after an unwrapping operation.
+CUR gives the position of the point before the operation.
+Additionally, two cons cells must be provided.  PREFIX gives the
+bounds of the prefix string and SUFFIX gives the bounds of the
+suffix string."
+  (cond ((< cur (cdr prefix)) (car prefix))
+        ((< cur (car suffix)) (- cur (- (cdr prefix) (car prefix))))
+        ((<= cur (cdr suffix))
+         (- cur (+ (- (cdr prefix) (car prefix))
+                   (- cur (car suffix)))))
+        (t cur)))
+
+(defun markdown-unwrap-thing-at-point (regexp all text)
+  "Remove prefix and suffix of thing at point and reposition the point.
+When the thing at point matches REGEXP, replace the subexpression
+ALL with the string in subexpression TEXT.  Reposition the point
+in an appropriate location accounting for the removal of prefix
+and suffix strings.  Return new bounds of string from group TEXT.
+When REGEXP is nil, assumes match data is already set."
+  (when (or (null regexp)
+            (thing-at-point-looking-at regexp))
+    (let ((cur (point))
+          (prefix (cons (match-beginning all) (match-beginning text)))
+          (suffix (cons (match-end text) (match-end all)))
+          (bounds (cons (match-beginning text) (match-end text))))
+      ;; Replace the thing at point
+      (replace-match (match-string text) t t nil all)
+      ;; Reposition the point
+      (goto-char (markdown-point-after-unwrap cur prefix suffix))
+      ;; Adjust bounds
+      (setq bounds (cons (car prefix)
+                         (- (cdr bounds) (- (cdr prefix) (car prefix))))))))
+
+(defun markdown-unwrap-things-in-region (beg end regexp all text)
+  "Remove prefix and suffix of all things in region from BEG to END.
+When a thing in the region matches REGEXP, replace the
+subexpression ALL with the string in subexpression TEXT.
+Return a cons cell containing updated bounds for the region."
+  (save-excursion
+    (goto-char beg)
+    (let ((removed 0) len-all len-text)
+      (while (re-search-forward regexp (- end removed) t)
+        (setq len-all (length (match-string-no-properties all)))
+        (setq len-text (length (match-string-no-properties text)))
+        (setq removed (+ removed (- len-all len-text)))
+        (replace-match (match-string text) t t nil all))
+      (cons beg (- end removed)))))
+
+(defun markdown-insert-hr (arg)
+  "Insert or replace a horizonal rule.
+By default, use the first element of `markdown-hr-strings'.  When
+ARG is non-nil, as when given a prefix, select a different
+element as follows.  When prefixed with \\[universal-argument],
+use the last element of `markdown-hr-strings' instead.  When
+prefixed with an integer from 1 to the length of
+`markdown-hr-strings', use the element in that position instead."
+  (interactive "*P")
+  (when (thing-at-point-looking-at markdown-regex-hr)
+    (delete-region (match-beginning 0) (match-end 0)))
+  (markdown-ensure-blank-line-before)
+  (cond ((equal arg '(4))
+         (insert (car (reverse markdown-hr-strings))))
+        ((and (integerp arg) (> arg 0)
+              (<= arg (length markdown-hr-strings)))
+         (insert (nth (1- arg) markdown-hr-strings)))
+        (t
+         (insert (car markdown-hr-strings))))
+  (markdown-ensure-blank-line-after))
+
+(defun markdown-insert-bold ()
+  "Insert markup to make a region or word bold.
+If there is an active region, make the region bold.  If the point
+is at a non-bold word, make the word bold.  If the point is at a
+bold word or phrase, remove the bold markup.  Otherwise, simply
+insert bold delimiters and place the point in between them."
+  (interactive)
+  (let ((delim (if markdown-bold-underscore "__" "**")))
+    (if (markdown-use-region-p)
+        ;; Active region
+        (let ((bounds (markdown-unwrap-things-in-region
+                       (region-beginning) (region-end)
+                       markdown-regex-bold 2 4)))
+          (markdown-wrap-or-insert delim delim nil (car bounds) (cdr bounds)))
+      ;; Bold markup removal, bold word at point, or empty markup insertion
+      (if (thing-at-point-looking-at markdown-regex-bold)
+          (markdown-unwrap-thing-at-point nil 2 4)
+        (markdown-wrap-or-insert delim delim 'word nil nil)))))
+
+(defun markdown-insert-italic ()
+  "Insert markup to make a region or word italic.
+If there is an active region, make the region italic.  If the point
+is at a non-italic word, make the word italic.  If the point is at an
+italic word or phrase, remove the italic markup.  Otherwise, simply
+insert italic delimiters and place the point in between them."
+  (interactive)
+  (let ((delim (if markdown-italic-underscore "_" "*")))
+    (if (markdown-use-region-p)
+        ;; Active region
+        (let ((bounds (markdown-unwrap-things-in-region
+                       (region-beginning) (region-end)
+                       markdown-regex-italic 1 3)))
+          (markdown-wrap-or-insert delim delim nil (car bounds) (cdr bounds)))
+      ;; Italic markup removal, italic word at point, or empty markup insertion
+      (if (thing-at-point-looking-at markdown-regex-italic)
+          (markdown-unwrap-thing-at-point nil 1 3)
+        (markdown-wrap-or-insert delim delim 'word nil nil)))))
+
+(defun markdown-insert-strike-through ()
+  "Insert markup to make a region or word strikethrough.
+If there is an active region, make the region strikethrough.  If the point
+is at a non-bold word, make the word strikethrough.  If the point is at a
+strikethrough word or phrase, remove the strikethrough markup.  Otherwise,
+simply insert bold delimiters and place the point in between them."
+  (interactive)
+  (let ((delim "~~"))
+    (if (markdown-use-region-p)
+        ;; Active region
+        (let ((bounds (markdown-unwrap-things-in-region
+                       (region-beginning) (region-end)
+                       markdown-regex-strike-through 2 4)))
+          (markdown-wrap-or-insert delim delim nil (car bounds) (cdr bounds)))
+      ;; Strikethrough markup removal, strikethrough word at point, or empty markup insertion
+      (if (thing-at-point-looking-at markdown-regex-strike-through)
+          (markdown-unwrap-thing-at-point nil 2 4)
+        (markdown-wrap-or-insert delim delim 'word nil nil)))))
+
+(defun markdown-insert-code ()
+  "Insert markup to make a region or word an inline code fragment.
+If there is an active region, make the region an inline code
+fragment.  If the point is at a word, make the word an inline
+code fragment.  Otherwise, simply insert code delimiters and
+place the point in between them."
+  (interactive)
+  (if (markdown-use-region-p)
+      ;; Active region
+      (let ((bounds (markdown-unwrap-things-in-region
+                     (region-beginning) (region-end)
+                     markdown-regex-code 1 3)))
+        (markdown-wrap-or-insert "`" "`" nil (car bounds) (cdr bounds)))
+    ;; Code markup removal, code markup for word, or empty markup insertion
+    (if (markdown-inline-code-at-point)
+        (markdown-unwrap-thing-at-point nil 0 2)
+      (markdown-wrap-or-insert "`" "`" 'word nil nil))))
+
+(defun markdown-insert-kbd ()
+  "Insert markup to wrap region or word in <kbd> tags.
+If there is an active region, use the region.  If the point is at
+a word, use the word.  Otherwise, simply insert <kbd> tags and
+place the point in between them."
+  (interactive)
+  (if (markdown-use-region-p)
+      ;; Active region
+      (let ((bounds (markdown-unwrap-things-in-region
+                     (region-beginning) (region-end)
+                     markdown-regex-kbd 0 2)))
+        (markdown-wrap-or-insert "<kbd>" "</kbd>" nil (car bounds) (cdr bounds)))
+    ;; Markup removal, markup for word, or empty markup insertion
+    (if (thing-at-point-looking-at markdown-regex-kbd)
+        (markdown-unwrap-thing-at-point nil 0 2)
+      (markdown-wrap-or-insert "<kbd>" "</kbd>" 'word nil nil))))
+
+(defun markdown-insert-inline-link (text url &optional title)
+  "Insert an inline link with TEXT pointing to URL.
+Optionally, the user can provide a TITLE."
+  (let ((cur (point)))
+    (setq title (and title (concat " \"" title "\"")))
+    (insert (concat "[" text "](" url title ")"))
+    (cond ((not text) (goto-char (+ 1 cur)))
+          ((not url) (goto-char (+ 3 (length text) cur))))))
+
+(defun markdown-insert-inline-image (text url &optional title)
+  "Insert an inline link with alt TEXT pointing to URL.
+Optionally, also provide a TITLE."
+  (let ((cur (point)))
+    (setq title (and title (concat " \"" title "\"")))
+    (insert (concat "![" text "](" url title ")"))
+    (cond ((not text) (goto-char (+ 2 cur)))
+          ((not url) (goto-char (+ 4 (length text) cur))))))
+
+(defun markdown-insert-reference-link (text label &optional url title)
+  "Insert a reference link and, optionally, a reference definition.
+The link TEXT will be inserted followed by the optional LABEL.
+If a URL is given, also insert a definition for the reference
+LABEL according to `markdown-reference-location'.  If a TITLE is
+given, it will be added to the end of the reference definition
+and will be used to populate the title attribute when converted
+to XHTML.  If URL is nil, insert only the link portion (for
+example, when a reference label is already defined)."
+  (insert (concat "[" text "][" label "]"))
+  (when url
+    (markdown-insert-reference-definition
+     (if (string-equal label "") text label)
+     url title)))
+
+(defun markdown-insert-reference-image (text label &optional url title)
+  "Insert a reference image and, optionally, a reference definition.
+The alt TEXT will be inserted followed by the optional LABEL.
+If a URL is given, also insert a definition for the reference
+LABEL according to `markdown-reference-location'.  If a TITLE is
+given, it will be added to the end of the reference definition
+and will be used to populate the title attribute when converted
+to XHTML.  If URL is nil, insert only the link portion (for
+example, when a reference label is already defined)."
+  (insert (concat "![" text "][" label "]"))
+  (when url
+    (markdown-insert-reference-definition
+     (if (string-equal label "") text label)
+     url title)))
+
+(defun markdown-insert-reference-definition (label &optional url title)
+  "Add definition for reference LABEL with URL and TITLE.
+LABEL is a Markdown reference label without square brackets.
+URL and TITLE are optional.  When given, the TITLE will
+be used to populate the title attribute when converted to XHTML."
+  ;; END specifies where to leave the point upon return
+  (let ((end (point)))
+    (cl-case markdown-reference-location
+      (end         (goto-char (point-max)))
+      (immediately (markdown-end-of-text-block))
+      (subtree     (markdown-end-of-subtree))
+      (header      (markdown-end-of-defun)))
+    ;; Skip backwards over local variables.  This logic is similar to the one
+    ;; used in ‘hack-local-variables’.
+    (when (and enable-local-variables (eobp))
+      (search-backward "\n\f" (max (- (point) 3000) (point-min)) :move)
+      (when (let ((case-fold-search t))
+              (search-forward "Local Variables:" nil :move))
+        (beginning-of-line 0)
+        (when (eq (char-before) ?\n) (backward-char))))
+    (unless (or (markdown-cur-line-blank-p)
+                (thing-at-point-looking-at markdown-regex-reference-definition))
+      (insert "\n"))
+    (insert "\n[" label "]: ")
+    (if url
+        (insert url)
+      ;; When no URL is given, leave point at END following the colon
+      (setq end (point)))
+    (when (> (length title) 0)
+      (insert " \"" title "\""))
+    (unless (looking-at-p "\n")
+      (insert "\n"))
+    (goto-char end)
+    (when url
+      (message
+       (markdown--substitute-command-keys
+        "Reference [%s] was defined, press \\[markdown-do] to jump there")
+       label))))
+
+(define-obsolete-function-alias
+  'markdown-insert-inline-link-dwim 'markdown-insert-link "v2.3")
+(define-obsolete-function-alias
+  'markdown-insert-reference-link-dwim 'markdown-insert-link "v2.3")
+
+(defun markdown--insert-link-or-image (image)
+  "Interactively insert new or update an existing link or image.
+When IMAGE is non-nil, insert an image.  Otherwise, insert a link.
+This is an internal function called by
+`markdown-insert-link' and `markdown-insert-image'."
+  (cl-multiple-value-bind (begin end text uri ref title)
+      (if (markdown-use-region-p)
+          ;; Use region as either link text or URL as appropriate.
+          (let ((region (buffer-substring-no-properties
+                         (region-beginning) (region-end))))
+            (if (string-match markdown-regex-uri region)
+                ;; Region contains a URL; use it as such.
+                (list (region-beginning) (region-end)
+                      nil (match-string 0 region) nil nil)
+              ;; Region doesn't contain a URL, so use it as text.
+              (list (region-beginning) (region-end)
+                    region nil nil nil)))
+        ;; Extract and use properties of existing link, if any.
+        (markdown-link-at-pos (point)))
+    (let* ((ref (when ref (concat "[" ref "]")))
+           (defined-refs (append
+                          (mapcar (lambda (ref) (concat "[" ref "]"))
+                                  (mapcar #'car (markdown-get-defined-references)))))
+           (used-uris (markdown-get-used-uris))
+           (uri-or-ref (completing-read
+                        "URL or [reference]: "
+                        (append defined-refs used-uris)
+                        nil nil (or uri ref)))
+           (ref (cond ((string-match "\\`\\[\\(.*\\)\\]\\'" uri-or-ref)
+                       (match-string 1 uri-or-ref))
+                      ((string-equal "" uri-or-ref)
+                       "")))
+           (uri (unless ref uri-or-ref))
+           (text-prompt (if image
+                            "Alt text: "
+                          (if ref
+                              "Link text: "
+                            "Link text (blank for plain URL): ")))
+           (text (read-string text-prompt text))
+           (text (if (= (length text) 0) nil text))
+           (plainp (and uri (not text)))
+           (implicitp (string-equal ref ""))
+           (ref (if implicitp text ref))
+           (definedp (and ref (markdown-reference-definition ref)))
+           (ref-url (unless (or uri definedp)
+                      (completing-read "Reference URL: " used-uris)))
+           (title (unless (or plainp definedp)
+                    (read-string "Title (tooltip text, optional): " title)))
+           (title (if (= (length title) 0) nil title)))
+      (when (and image implicitp)
+        (user-error "Reference required: implicit image references are invalid"))
+      (when (and begin end)
+        (delete-region begin end))
+      (cond
+       ((and (not image) uri text)
+        (markdown-insert-inline-link text uri title))
+       ((and image uri text)
+        (markdown-insert-inline-image text uri title))
+       ((and ref text)
+        (if image
+            (markdown-insert-reference-image text (unless implicitp ref) nil title)
+          (markdown-insert-reference-link text (unless implicitp ref) nil title))
+        (unless definedp
+          (markdown-insert-reference-definition ref ref-url title)))
+       ((and (not image) uri)
+        (markdown-insert-uri uri))))))
+
+(defun markdown-insert-link ()
+  "Insert new or update an existing link, with interactive prompts.
+If the point is at an existing link or URL, update the link text,
+URL, reference label, and/or title.  Otherwise, insert a new link.
+The type of link inserted (inline, reference, or plain URL)
+depends on which values are provided:
+
+*   If a URL and TEXT are given, insert an inline link: [TEXT](URL).
+*   If [REF] and TEXT are given, insert a reference link: [TEXT][REF].
+*   If only TEXT is given, insert an implicit reference link: [TEXT][].
+*   If only a URL is given, insert a plain link: <URL>.
+
+In other words, to create an implicit reference link, leave the
+URL prompt empty and to create a plain URL link, leave the link
+text empty.
+
+If there is an active region, use the text as the default URL, if
+it seems to be a URL, or link text value otherwise.
+
+If a given reference is not defined, this function will
+additionally prompt for the URL and optional title.  In this case,
+the reference definition is placed at the location determined by
+`markdown-reference-location'.
+
+Through updating the link, this function can be used to convert a
+link of one type (inline, reference, or plain) to another type by
+selectively adding or removing information via the prompts."
+  (interactive)
+  (markdown--insert-link-or-image nil))
+
+(defun markdown-insert-image ()
+  "Insert new or update an existing image, with interactive prompts.
+If the point is at an existing image, update the alt text, URL,
+reference label, and/or title. Otherwise, insert a new image.
+The type of image inserted (inline or reference) depends on which
+values are provided:
+
+*   If a URL and ALT-TEXT are given, insert an inline image:
+    ![ALT-TEXT](URL).
+*   If [REF] and ALT-TEXT are given, insert a reference image:
+    ![ALT-TEXT][REF].
+
+If there is an active region, use the text as the default URL, if
+it seems to be a URL, or alt text value otherwise.
+
+If a given reference is not defined, this function will
+additionally prompt for the URL and optional title.  In this case,
+the reference definition is placed at the location determined by
+`markdown-reference-location'.
+
+Through updating the image, this function can be used to convert an
+image of one type (inline or reference) to another type by
+selectively adding or removing information via the prompts."
+  (interactive)
+  (markdown--insert-link-or-image t))
+
+(defun markdown-insert-uri (&optional uri)
+  "Insert markup for an inline URI.
+If there is an active region, use it as the URI.  If the point is
+at a URI, wrap it with angle brackets.  If the point is at an
+inline URI, remove the angle brackets.  Otherwise, simply insert
+angle brackets place the point between them."
+  (interactive)
+  (if (markdown-use-region-p)
+      ;; Active region
+      (let ((bounds (markdown-unwrap-things-in-region
+                     (region-beginning) (region-end)
+                     markdown-regex-angle-uri 0 2)))
+        (markdown-wrap-or-insert "<" ">" nil (car bounds) (cdr bounds)))
+    ;; Markup removal, URI at point, new URI, or empty markup insertion
+    (if (thing-at-point-looking-at markdown-regex-angle-uri)
+        (markdown-unwrap-thing-at-point nil 0 2)
+      (if uri
+          (insert "<" uri ">")
+        (markdown-wrap-or-insert "<" ">" 'url nil nil)))))
+
+(defun markdown-insert-wiki-link ()
+  "Insert a wiki link of the form [[WikiLink]].
+If there is an active region, use the region as the link text.
+If the point is at a word, use the word as the link text.  If
+there is no active region and the point is not at word, simply
+insert link markup."
+  (interactive)
+  (if (markdown-use-region-p)
+      ;; Active region
+      (markdown-wrap-or-insert "[[" "]]" nil (region-beginning) (region-end))
+    ;; Markup removal, wiki link at at point, or empty markup insertion
+    (if (thing-at-point-looking-at markdown-regex-wiki-link)
+        (if (or markdown-wiki-link-alias-first
+                (null (match-string 5)))
+            (markdown-unwrap-thing-at-point nil 1 3)
+          (markdown-unwrap-thing-at-point nil 1 5))
+      (markdown-wrap-or-insert "[[" "]]"))))
+
+(defun markdown-remove-header ()
+  "Remove header markup if point is at a header.
+Return bounds of remaining header text if a header was removed
+and nil otherwise."
+  (interactive "*")
+  (or (markdown-unwrap-thing-at-point markdown-regex-header-atx 0 2)
+      (markdown-unwrap-thing-at-point markdown-regex-header-setext 0 1)))
+
+(defun markdown-insert-header (&optional level text setext)
+  "Insert or replace header markup.
+The level of the header is specified by LEVEL and header text is
+given by TEXT.  LEVEL must be an integer from 1 and 6, and the
+default value is 1.
+When TEXT is nil, the header text is obtained as follows.
+If there is an active region, it is used as the header text.
+Otherwise, the current line will be used as the header text.
+If there is not an active region and the point is at a header,
+remove the header markup and replace with level N header.
+Otherwise, insert empty header markup and place the point in
+between.
+The style of the header will be atx (hash marks) unless
+SETEXT is non-nil, in which case a setext-style (underlined)
+header will be inserted."
+  (interactive "p\nsHeader text: ")
+  (setq level (min (max (or level 1) 1) (if setext 2 6)))
+  ;; Determine header text if not given
+  (when (null text)
+    (if (markdown-use-region-p)
+        ;; Active region
+        (setq text (delete-and-extract-region (region-beginning) (region-end)))
+      ;; No active region
+      (markdown-remove-header)
+      (setq text (delete-and-extract-region
+                  (line-beginning-position) (line-end-position)))
+      (when (and setext (string-match-p "^[ \t]*$" text))
+        (setq text (read-string "Header text: "))))
+    (setq text (markdown-compress-whitespace-string text)))
+  ;; Insertion with given text
+  (markdown-ensure-blank-line-before)
+  (let (hdr)
+    (cond (setext
+           (setq hdr (make-string (string-width text) (if (= level 2) ?- ?=)))
+           (insert text "\n" hdr))
+          (t
+           (setq hdr (make-string level ?#))
+           (insert hdr " " text)
+           (when (null markdown-asymmetric-header) (insert " " hdr)))))
+  (markdown-ensure-blank-line-after)
+  ;; Leave point at end of text
+  (cond (setext
+         (backward-char (1+ (string-width text))))
+        ((null markdown-asymmetric-header)
+         (backward-char (1+ level)))))
+
+(defun markdown-insert-header-dwim (&optional arg setext)
+  "Insert or replace header markup.
+The level and type of the header are determined automatically by
+the type and level of the previous header, unless a prefix
+argument is given via ARG.
+With a numeric prefix valued 1 to 6, insert a header of the given
+level, with the type being determined automatically (note that
+only level 1 or 2 setext headers are possible).
+
+With a \\[universal-argument] prefix (i.e., when ARG is (4)),
+promote the heading by one level.
+With two \\[universal-argument] prefixes (i.e., when ARG is (16)),
+demote the heading by one level.
+When SETEXT is non-nil, prefer setext-style headers when
+possible (levels one and two).
+
+When there is an active region, use it for the header text.  When
+the point is at an existing header, change the type and level
+according to the rules above.
+Otherwise, if the line is not empty, create a header using the
+text on the current line as the header text.
+Finally, if the point is on a blank line, insert empty header
+markup (atx) or prompt for text (setext).
+See `markdown-insert-header' for more details about how the
+header text is determined."
+  (interactive "*P")
+  (let (level)
+    (save-excursion
+      (when (or (thing-at-point-looking-at markdown-regex-header)
+                (re-search-backward markdown-regex-header nil t))
+        ;; level of current or previous header
+        (setq level (markdown-outline-level))
+        ;; match group 1 indicates a setext header
+        (setq setext (match-end 1))))
+    ;; check prefix argument
+    (cond
+     ((and (equal arg '(4)) level (> level 1)) ;; C-u
+      (cl-decf level))
+     ((and (equal arg '(16)) level (< level 6)) ;; C-u C-u
+      (cl-incf level))
+     (arg ;; numeric prefix
+      (setq level (prefix-numeric-value arg))))
+    ;; setext headers must be level one or two
+    (and level (setq setext (and setext (<= level 2))))
+    ;; insert the heading
+    (markdown-insert-header level nil setext)))
+
+(defun markdown-insert-header-setext-dwim (&optional arg)
+  "Insert or replace header markup, with preference for setext.
+See `markdown-insert-header-dwim' for details, including how ARG is handled."
+  (interactive "*P")
+  (markdown-insert-header-dwim arg t))
+
+(defun markdown-insert-header-atx-1 ()
+  "Insert a first level atx-style (hash mark) header.
+See `markdown-insert-header'."
+  (interactive "*")
+  (markdown-insert-header 1 nil nil))
+
+(defun markdown-insert-header-atx-2 ()
+  "Insert a level two atx-style (hash mark) header.
+See `markdown-insert-header'."
+  (interactive "*")
+  (markdown-insert-header 2 nil nil))
+
+(defun markdown-insert-header-atx-3 ()
+  "Insert a level three atx-style (hash mark) header.
+See `markdown-insert-header'."
+  (interactive "*")
+  (markdown-insert-header 3 nil nil))
+
+(defun markdown-insert-header-atx-4 ()
+  "Insert a level four atx-style (hash mark) header.
+See `markdown-insert-header'."
+  (interactive "*")
+  (markdown-insert-header 4 nil nil))
+
+(defun markdown-insert-header-atx-5 ()
+  "Insert a level five atx-style (hash mark) header.
+See `markdown-insert-header'."
+  (interactive "*")
+  (markdown-insert-header 5 nil nil))
+
+(defun markdown-insert-header-atx-6 ()
+  "Insert a sixth level atx-style (hash mark) header.
+See `markdown-insert-header'."
+  (interactive "*")
+  (markdown-insert-header 6 nil nil))
+
+(defun markdown-insert-header-setext-1 ()
+  "Insert a setext-style (underlined) first-level header.
+See `markdown-insert-header'."
+  (interactive "*")
+  (markdown-insert-header 1 nil t))
+
+(defun markdown-insert-header-setext-2 ()
+  "Insert a setext-style (underlined) second-level header.
+See `markdown-insert-header'."
+  (interactive "*")
+  (markdown-insert-header 2 nil t))
+
+(defun markdown-blockquote-indentation (loc)
+  "Return string containing necessary indentation for a blockquote at LOC.
+Also see `markdown-pre-indentation'."
+  (save-excursion
+    (goto-char loc)
+    (let* ((list-level (length (markdown-calculate-list-levels)))
+           (indent ""))
+      (dotimes (_ list-level indent)
+        (setq indent (concat indent "    "))))))
+
+(defun markdown-insert-blockquote ()
+  "Start a blockquote section (or blockquote the region).
+If Transient Mark mode is on and a region is active, it is used as
+the blockquote text."
+  (interactive)
+  (if (markdown-use-region-p)
+      (markdown-blockquote-region (region-beginning) (region-end))
+    (markdown-ensure-blank-line-before)
+    (insert (markdown-blockquote-indentation (point)) "> ")
+    (markdown-ensure-blank-line-after)))
+
+(defun markdown-block-region (beg end prefix)
+  "Format the region using a block prefix.
+Arguments BEG and END specify the beginning and end of the
+region.  The characters PREFIX will appear at the beginning
+of each line."
+  (save-excursion
+    (let* ((end-marker (make-marker))
+           (beg-marker (make-marker))
+           (prefix-without-trailing-whitespace
+            (replace-regexp-in-string (rx (+ blank) eos) "" prefix)))
+      ;; Ensure blank line after and remove extra whitespace
+      (goto-char end)
+      (skip-syntax-backward "-")
+      (set-marker end-marker (point))
+      (delete-horizontal-space)
+      (markdown-ensure-blank-line-after)
+      ;; Ensure blank line before and remove extra whitespace
+      (goto-char beg)
+      (skip-syntax-forward "-")
+      (delete-horizontal-space)
+      (markdown-ensure-blank-line-before)
+      (set-marker beg-marker (point))
+      ;; Insert PREFIX before each line
+      (goto-char beg-marker)
+      (while (and (< (line-beginning-position) end-marker)
+                  (not (eobp)))
+        ;; Don’t insert trailing whitespace.
+        (insert (if (eolp) prefix-without-trailing-whitespace prefix))
+        (forward-line)))))
+
+(defun markdown-blockquote-region (beg end)
+  "Blockquote the region.
+Arguments BEG and END specify the beginning and end of the region."
+  (interactive "*r")
+  (markdown-block-region
+   beg end (concat (markdown-blockquote-indentation
+                    (max (point-min) (1- beg))) "> ")))
+
+(defun markdown-pre-indentation (loc)
+  "Return string containing necessary whitespace for a pre block at LOC.
+Also see `markdown-blockquote-indentation'."
+  (save-excursion
+    (goto-char loc)
+    (let* ((list-level (length (markdown-calculate-list-levels)))
+           indent)
+      (dotimes (_ (1+ list-level) indent)
+        (setq indent (concat indent "    "))))))
+
+(defun markdown-insert-pre ()
+  "Start a preformatted section (or apply to the region).
+If Transient Mark mode is on and a region is active, it is marked
+as preformatted text."
+  (interactive)
+  (if (markdown-use-region-p)
+      (markdown-pre-region (region-beginning) (region-end))
+    (markdown-ensure-blank-line-before)
+    (insert (markdown-pre-indentation (point)))
+    (markdown-ensure-blank-line-after)))
+
+(defun markdown-pre-region (beg end)
+  "Format the region as preformatted text.
+Arguments BEG and END specify the beginning and end of the region."
+  (interactive "*r")
+  (let ((indent (markdown-pre-indentation (max (point-min) (1- beg)))))
+    (markdown-block-region beg end indent)))
+
+(defun markdown-electric-backquote (arg)
+  "Insert a backquote.
+The numeric prefix argument ARG says how many times to repeat the insertion.
+Call `markdown-insert-gfm-code-block' interactively
+if three backquotes inserted at the beginning of line."
+  (interactive "*P")
+  (self-insert-command (prefix-numeric-value arg))
+  (when (and markdown-gfm-use-electric-backquote (looking-back "^```" nil))
+    (replace-match "")
+    (call-interactively #'markdown-insert-gfm-code-block)))
+
+(defconst markdown-gfm-recognized-languages
+  ;; To reproduce/update, evaluate the let-form in
+  ;; scripts/get-recognized-gfm-languages.el. that produces a single long sexp,
+  ;; but with appropriate use of a keyboard macro, indenting and filling it
+  ;; properly is pretty fast.
+  '("1C-Enterprise" "ABAP" "ABNF" "AGS-Script" "AMPL" "ANTLR"
+    "API-Blueprint" "APL" "ASN.1" "ASP" "ATS" "ActionScript" "Ada" "Agda"
+    "Alloy" "Alpine-Abuild" "Ant-Build-System" "ApacheConf" "Apex"
+    "Apollo-Guidance-Computer" "AppleScript" "Arc" "Arduino" "AsciiDoc"
+    "AspectJ" "Assembly" "Augeas" "AutoHotkey" "AutoIt" "Awk" "Batchfile"
+    "Befunge" "Bison" "BitBake" "Blade" "BlitzBasic" "BlitzMax" "Bluespec"
+    "Boo" "Brainfuck" "Brightscript" "Bro" "C#" "C++" "C-ObjDump"
+    "C2hs-Haskell" "CLIPS" "CMake" "COBOL" "COLLADA" "CSON" "CSS" "CSV"
+    "CWeb" "Cap'n-Proto" "CartoCSS" "Ceylon" "Chapel" "Charity" "ChucK"
+    "Cirru" "Clarion" "Clean" "Click" "Clojure" "Closure-Templates"
+    "CoffeeScript" "ColdFusion" "ColdFusion-CFC" "Common-Lisp"
+    "Component-Pascal" "Cool" "Coq" "Cpp-ObjDump" "Creole" "Crystal"
+    "Csound" "Csound-Document" "Csound-Score" "Cuda" "Cycript" "Cython"
+    "D-ObjDump" "DIGITAL-Command-Language" "DM" "DNS-Zone" "DTrace"
+    "Darcs-Patch" "Dart" "Diff" "Dockerfile" "Dogescript" "Dylan" "EBNF"
+    "ECL" "ECLiPSe" "EJS" "EQ" "Eagle" "Ecere-Projects" "Eiffel" "Elixir"
+    "Elm" "Emacs-Lisp" "EmberScript" "Erlang" "F#" "FLUX" "Factor" "Fancy"
+    "Fantom" "Filebench-WML" "Filterscript" "Formatted" "Forth" "Fortran"
+    "FreeMarker" "Frege" "G-code" "GAMS" "GAP" "GCC-Machine-Description"
+    "GDB" "GDScript" "GLSL" "GN" "Game-Maker-Language" "Genie" "Genshi"
+    "Gentoo-Ebuild" "Gentoo-Eclass" "Gettext-Catalog" "Gherkin" "Glyph"
+    "Gnuplot" "Go" "Golo" "Gosu" "Grace" "Gradle" "Grammatical-Framework"
+    "Graph-Modeling-Language" "GraphQL" "Graphviz-(DOT)" "Groovy"
+    "Groovy-Server-Pages" "HCL" "HLSL" "HTML" "HTML+Django" "HTML+ECR"
+    "HTML+EEX" "HTML+ERB" "HTML+PHP" "HTTP" "Hack" "Haml" "Handlebars"
+    "Harbour" "Haskell" "Haxe" "Hy" "HyPhy" "IDL" "IGOR-Pro" "INI"
+    "IRC-log" "Idris" "Inform-7" "Inno-Setup" "Io" "Ioke" "Isabelle"
+    "Isabelle-ROOT" "JFlex" "JSON" "JSON5" "JSONLD" "JSONiq" "JSX"
+    "Jasmin" "Java" "Java-Server-Pages" "JavaScript" "Jison" "Jison-Lex"
+    "Jolie" "Julia" "Jupyter-Notebook" "KRL" "KiCad" "Kit" "Kotlin" "LFE"
+    "LLVM" "LOLCODE" "LSL" "LabVIEW" "Lasso" "Latte" "Lean" "Less" "Lex"
+    "LilyPond" "Limbo" "Linker-Script" "Linux-Kernel-Module" "Liquid"
+    "Literate-Agda" "Literate-CoffeeScript" "Literate-Haskell"
+    "LiveScript" "Logos" "Logtalk" "LookML" "LoomScript" "Lua" "M4"
+    "M4Sugar" "MAXScript" "MQL4" "MQL5" "MTML" "MUF" "Makefile" "Mako"
+    "Markdown" "Marko" "Mask" "Mathematica" "Matlab" "Maven-POM" "Max"
+    "MediaWiki" "Mercury" "Meson" "Metal" "MiniD" "Mirah" "Modelica"
+    "Modula-2" "Module-Management-System" "Monkey" "Moocode" "MoonScript"
+    "Myghty" "NCL" "NL" "NSIS" "Nemerle" "NetLinx" "NetLinx+ERB" "NetLogo"
+    "NewLisp" "Nginx" "Nim" "Ninja" "Nit" "Nix" "Nu" "NumPy" "OCaml"
+    "ObjDump" "Objective-C" "Objective-C++" "Objective-J" "Omgrofl" "Opa"
+    "Opal" "OpenCL" "OpenEdge-ABL" "OpenRC-runscript" "OpenSCAD"
+    "OpenType-Feature-File" "Org" "Ox" "Oxygene" "Oz" "P4" "PAWN" "PHP"
+    "PLSQL" "PLpgSQL" "POV-Ray-SDL" "Pan" "Papyrus" "Parrot"
+    "Parrot-Assembly" "Parrot-Internal-Representation" "Pascal" "Pep8"
+    "Perl" "Perl6" "Pic" "Pickle" "PicoLisp" "PigLatin" "Pike" "Pod"
+    "PogoScript" "Pony" "PostScript" "PowerBuilder" "PowerShell"
+    "Processing" "Prolog" "Propeller-Spin" "Protocol-Buffer" "Public-Key"
+    "Pug" "Puppet" "Pure-Data" "PureBasic" "PureScript" "Python"
+    "Python-console" "Python-traceback" "QML" "QMake" "RAML" "RDoc"
+    "REALbasic" "REXX" "RHTML" "RMarkdown" "RPM-Spec" "RUNOFF" "Racket"
+    "Ragel" "Rascal" "Raw-token-data" "Reason" "Rebol" "Red" "Redcode"
+    "Regular-Expression" "Ren'Py" "RenderScript" "RobotFramework" "Roff"
+    "Rouge" "Ruby" "Rust" "SAS" "SCSS" "SMT" "SPARQL" "SQF" "SQL" "SQLPL"
+    "SRecode-Template" "STON" "SVG" "Sage" "SaltStack" "Sass" "Scala"
+    "Scaml" "Scheme" "Scilab" "Self" "ShaderLab" "Shell" "ShellSession"
+    "Shen" "Slash" "Slim" "Smali" "Smalltalk" "Smarty" "SourcePawn"
+    "Spline-Font-Database" "Squirrel" "Stan" "Standard-ML" "Stata"
+    "Stylus" "SubRip-Text" "Sublime-Text-Config" "SuperCollider" "Swift"
+    "SystemVerilog" "TI-Program" "TLA" "TOML" "TXL" "Tcl" "Tcsh" "TeX"
+    "Tea" "Terra" "Text" "Textile" "Thrift" "Turing" "Turtle" "Twig"
+    "Type-Language" "TypeScript" "Unified-Parallel-C" "Unity3D-Asset"
+    "Unix-Assembly" "Uno" "UnrealScript" "UrWeb" "VCL" "VHDL" "Vala"
+    "Verilog" "Vim-script" "Visual-Basic" "Volt" "Vue"
+    "Wavefront-Material" "Wavefront-Object" "Web-Ontology-Language"
+    "WebAssembly" "WebIDL" "World-of-Warcraft-Addon-Data" "X10" "XC"
+    "XCompose" "XML" "XPages" "XProc" "XQuery" "XS" "XSLT" "Xojo" "Xtend"
+    "YAML" "YANG" "Yacc" "Zephir" "Zimpl" "desktop" "eC" "edn" "fish"
+    "mupad" "nesC" "ooc" "reStructuredText" "wisp" "xBase")
+  "Language specifiers recognized by GitHub's syntax highlighting features.")
+
+(defvar markdown-gfm-used-languages nil
+  "Language names used in GFM code blocks.")
+(make-variable-buffer-local 'markdown-gfm-used-languages)
+
+(defun markdown-trim-whitespace (str)
+  (markdown-replace-regexp-in-string
+   "\\(?:[[:space:]\r\n]+\\'\\|\\`[[:space:]\r\n]+\\)" "" str))
+
+(defun markdown-clean-language-string (str)
+  (markdown-replace-regexp-in-string
+   "{\\.?\\|}" "" (markdown-trim-whitespace str)))
+
+(defun markdown-validate-language-string (widget)
+  (let ((str (widget-value widget)))
+    (unless (string= str (markdown-clean-language-string str))
+      (widget-put widget :error (format "Invalid language spec: '%s'" str))
+      widget)))
+
+(defun markdown-gfm-get-corpus ()
+  "Create corpus of recognized GFM code block languages for the given buffer."
+  (let ((given-corpus (append markdown-gfm-additional-languages
+                              markdown-gfm-recognized-languages)))
+    (append
+     markdown-gfm-used-languages
+     (if markdown-gfm-downcase-languages (cl-mapcar #'downcase given-corpus)
+       given-corpus))))
+
+(defun markdown-gfm-add-used-language (lang)
+  "Clean LANG and add to list of used languages."
+  (setq markdown-gfm-used-languages
+          (cons lang (remove lang markdown-gfm-used-languages))))
+
+(defcustom markdown-spaces-after-code-fence 1
+  "Number of space characters to insert after a code fence.
+\\<gfm-mode-map>\\[markdown-insert-gfm-code-block] inserts this many spaces between an
+opening code fence and an info string."
+  :group 'markdown
+  :type 'integer
+  :safe #'natnump
+  :package-version '(markdown-mode . "2.3"))
+
+(defun markdown-insert-gfm-code-block (&optional lang edit)
+  "Insert GFM code block for language LANG.
+If LANG is nil, the language will be queried from user.  If a
+region is active, wrap this region with the markup instead.  If
+the region boundaries are not on empty lines, these are added
+automatically in order to have the correct markup.  When EDIT is
+non-nil (e.g., when \\[universal-argument] is given), edit the
+code block in an indirect buffer after insertion."
+  (interactive
+   (list (let ((completion-ignore-case nil))
+           (condition-case nil
+               (markdown-clean-language-string
+                (completing-read
+                 "Programming language: "
+                 (markdown-gfm-get-corpus)
+                 nil 'confirm (car markdown-gfm-used-languages)
+                 'markdown-gfm-language-history))
+             (quit "")))
+         current-prefix-arg))
+  (unless (string= lang "") (markdown-gfm-add-used-language lang))
+  (when (> (length lang) 0)
+    (setq lang (concat (make-string markdown-spaces-after-code-fence ?\s)
+                       lang)))
+  (if (markdown-use-region-p)
+      (let* ((b (region-beginning)) (e (region-end)) end
+             (indent (progn (goto-char b) (current-indentation))))
+        (goto-char e)
+        ;; if we're on a blank line, don't newline, otherwise the ```
+        ;; should go on its own line
+        (unless (looking-back "\n" nil)
+          (newline))
+        (indent-to indent)
+        (insert "```")
+        (markdown-ensure-blank-line-after)
+        (setq end (point))
+        (goto-char b)
+        ;; if we're on a blank line, insert the quotes here, otherwise
+        ;; add a new line first
+        (unless (looking-at-p "\n")
+          (newline)
+          (forward-line -1))
+        (markdown-ensure-blank-line-before)
+        (indent-to indent)
+        (insert "```" lang)
+        (markdown-syntax-propertize-fenced-block-constructs (point-at-bol) end))
+    (let ((indent (current-indentation)) start-bol)
+      (delete-horizontal-space :backward-only)
+      (markdown-ensure-blank-line-before)
+      (indent-to indent)
+      (setq start-bol (point-at-bol))
+      (insert "```" lang "\n")
+      (indent-to indent)
+      (unless edit (insert ?\n))
+      (indent-to indent)
+      (insert "```")
+      (markdown-ensure-blank-line-after)
+      (markdown-syntax-propertize-fenced-block-constructs start-bol (point)))
+    (end-of-line 0)
+    (when edit (markdown-edit-code-block))))
+
+(defun markdown-code-block-lang (&optional pos-prop)
+  "Return the language name for a GFM or tilde fenced code block.
+The beginning of the block may be described by POS-PROP,
+a cons of (pos . prop) giving the position and property
+at the beginning of the block."
+  (or pos-prop
+      (setq pos-prop
+            (markdown-max-of-seq
+             #'car
+             (cl-remove-if
+              #'null
+              (cl-mapcar
+               #'markdown-find-previous-prop
+               (markdown-get-fenced-block-begin-properties))))))
+  (when pos-prop
+    (goto-char (car pos-prop))
+    (set-match-data (get-text-property (point) (cdr pos-prop)))
+    ;; Note: Hard-coded group number assumes tilde
+    ;; and GFM fenced code regexp groups agree.
+    (let ((begin (match-beginning 3))
+          (end (match-end 3)))
+      (when (and begin end)
+        ;; Fix language strings beginning with periods, like ".ruby".
+        (when (eq (char-after begin) ?.)
+          (setq begin (1+ begin)))
+        (buffer-substring-no-properties begin end)))))
+
+(defun markdown-gfm-parse-buffer-for-languages (&optional buffer)
+  (with-current-buffer (or buffer (current-buffer))
+    (save-excursion
+      (goto-char (point-min))
+      (cl-loop
+       with prop = 'markdown-gfm-block-begin
+       for pos-prop = (markdown-find-next-prop prop)
+       while pos-prop
+       for lang = (markdown-code-block-lang pos-prop)
+       do (progn (when lang (markdown-gfm-add-used-language lang))
+                 (goto-char (next-single-property-change (point) prop)))))))
+
+
+;;; Footnotes ==================================================================
+
+(defun markdown-footnote-counter-inc ()
+  "Increment `markdown-footnote-counter' and return the new value."
+  (when (= markdown-footnote-counter 0) ; hasn't been updated in this buffer yet.
+    (save-excursion
+      (goto-char (point-min))
+      (while (re-search-forward (concat "^\\[\\^\\(" markdown-footnote-chars "*?\\)\\]:")
+                                (point-max) t)
+        (let ((fn (string-to-number (match-string 1))))
+          (when (> fn markdown-footnote-counter)
+            (setq markdown-footnote-counter fn))))))
+  (cl-incf markdown-footnote-counter))
+
+(defun markdown-insert-footnote ()
+  "Insert footnote with a new number and move point to footnote definition."
+  (interactive)
+  (let ((fn (markdown-footnote-counter-inc)))
+    (insert (format "[^%d]" fn))
+    (markdown-footnote-text-find-new-location)
+    (markdown-ensure-blank-line-before)
+    (unless (markdown-cur-line-blank-p)
+      (insert "\n"))
+    (insert (format "[^%d]: " fn))
+    (markdown-ensure-blank-line-after)))
+
+(defun markdown-footnote-text-find-new-location ()
+  "Position the point at the proper location for a new footnote text."
+  (cond
+   ((eq markdown-footnote-location 'end) (goto-char (point-max)))
+   ((eq markdown-footnote-location 'immediately) (markdown-end-of-text-block))
+   ((eq markdown-footnote-location 'subtree) (markdown-end-of-subtree))
+   ((eq markdown-footnote-location 'header) (markdown-end-of-defun))))
+
+(defun markdown-footnote-kill ()
+  "Kill the footnote at point.
+The footnote text is killed (and added to the kill ring), the
+footnote marker is deleted.  Point has to be either at the
+footnote marker or in the footnote text."
+  (interactive)
+  (let ((marker-pos nil)
+        (skip-deleting-marker nil)
+        (starting-footnote-text-positions
+         (markdown-footnote-text-positions)))
+    (when starting-footnote-text-positions
+      ;; We're starting in footnote text, so mark our return position and jump
+      ;; to the marker if possible.
+      (let ((marker-pos (markdown-footnote-find-marker
+                         (cl-first starting-footnote-text-positions))))
+        (if marker-pos
+            (goto-char (1- marker-pos))
+          ;; If there isn't a marker, we still want to kill the text.
+          (setq skip-deleting-marker t))))
+    ;; Either we didn't start in the text, or we started in the text and jumped
+    ;; to the marker. We want to assume we're at the marker now and error if
+    ;; we're not.
+    (unless skip-deleting-marker
+      (let ((marker (markdown-footnote-delete-marker)))
+        (unless marker
+          (error "Not at a footnote"))
+        ;; Even if we knew the text position before, it changed when we deleted
+        ;; the label.
+        (setq marker-pos (cl-second marker))
+        (let ((new-text-pos (markdown-footnote-find-text (cl-first marker))))
+          (unless new-text-pos
+            (error "No text for footnote `%s'" (cl-first marker)))
+          (goto-char new-text-pos))))
+    (let ((pos (markdown-footnote-kill-text)))
+      (goto-char (if starting-footnote-text-positions
+                     pos
+                   marker-pos)))))
+
+(defun markdown-footnote-delete-marker ()
+  "Delete a footnote marker at point.
+Returns a list (ID START) containing the footnote ID and the
+start position of the marker before deletion.  If no footnote
+marker was deleted, this function returns NIL."
+  (let ((marker (markdown-footnote-marker-positions)))
+    (when marker
+      (delete-region (cl-second marker) (cl-third marker))
+      (butlast marker))))
+
+(defun markdown-footnote-kill-text ()
+  "Kill footnote text at point.
+Returns the start position of the footnote text before deletion,
+or NIL if point was not inside a footnote text.
+
+The killed text is placed in the kill ring (without the footnote
+number)."
+  (let ((fn (markdown-footnote-text-positions)))
+    (when fn
+      (let ((text (delete-and-extract-region (cl-second fn) (cl-third fn))))
+        (string-match (concat "\\[\\" (cl-first fn) "\\]:[[:space:]]*\\(\\(.*\n?\\)*\\)") text)
+        (kill-new (match-string 1 text))
+        (when (and (markdown-cur-line-blank-p)
+                   (markdown-prev-line-blank-p)
+                   (not (bobp)))
+          (delete-region (1- (point)) (point)))
+        (cl-second fn)))))
+
+(defun markdown-footnote-goto-text ()
+  "Jump to the text of the footnote at point."
+  (interactive)
+  (let ((fn (car (markdown-footnote-marker-positions))))
+    (unless fn
+      (user-error "Not at a footnote marker"))
+    (let ((new-pos (markdown-footnote-find-text fn)))
+      (unless new-pos
+        (error "No definition found for footnote `%s'" fn))
+      (goto-char new-pos))))
+
+(defun markdown-footnote-return ()
+  "Return from a footnote to its footnote number in the main text."
+  (interactive)
+  (let ((fn (save-excursion
+              (car (markdown-footnote-text-positions)))))
+    (unless fn
+      (user-error "Not in a footnote"))
+    (let ((new-pos (markdown-footnote-find-marker fn)))
+      (unless new-pos
+        (error "Footnote marker `%s' not found" fn))
+      (goto-char new-pos))))
+
+(defun markdown-footnote-find-marker (id)
+  "Find the location of the footnote marker with ID.
+The actual buffer position returned is the position directly
+following the marker's closing bracket.  If no marker is found,
+NIL is returned."
+  (save-excursion
+    (goto-char (point-min))
+    (when (re-search-forward (concat "\\[" id "\\]\\([^:]\\|\\'\\)") nil t)
+      (skip-chars-backward "^]")
+      (point))))
+
+(defun markdown-footnote-find-text (id)
+  "Find the location of the text of footnote ID.
+The actual buffer position returned is the position of the first
+character of the text, after the footnote's identifier.  If no
+footnote text is found, NIL is returned."
+  (save-excursion
+    (goto-char (point-min))
+    (when (re-search-forward (concat "^ \\{0,3\\}\\[" id "\\]:") nil t)
+      (skip-chars-forward "[ \t]")
+      (point))))
+
+(defun markdown-footnote-marker-positions ()
+  "Return the position and ID of the footnote marker point is on.
+The return value is a list (ID START END).  If point is not on a
+footnote, NIL is returned."
+  ;; first make sure we're at a footnote marker
+  (if (or (looking-back (concat "\\[\\^" markdown-footnote-chars "*\\]?") (line-beginning-position))
+          (looking-at-p (concat "\\[?\\^" markdown-footnote-chars "*?\\]")))
+      (save-excursion
+        ;; move point between [ and ^:
+        (if (looking-at-p "\\[")
+            (forward-char 1)
+          (skip-chars-backward "^["))
+        (looking-at (concat "\\(\\^" markdown-footnote-chars "*?\\)\\]"))
+        (list (match-string 1) (1- (match-beginning 1)) (1+ (match-end 1))))))
+
+(defun markdown-footnote-text-positions ()
+  "Return the start and end positions of the footnote text point is in.
+The exact return value is a list of three elements: (ID START END).
+The start position is the position of the opening bracket
+of the footnote id.  The end position is directly after the
+newline that ends the footnote.  If point is not in a footnote,
+NIL is returned instead."
+  (save-excursion
+    (let (result)
+      (move-beginning-of-line 1)
+      ;; Try to find the label. If we haven't found the label and we're at a blank
+      ;; or indented line, back up if possible.
+      (while (and
+              (not (and (looking-at markdown-regex-footnote-definition)
+                        (setq result (list (match-string 1) (point)))))
+              (and (not (bobp))
+                   (or (markdown-cur-line-blank-p)
+                       (>= (current-indentation) 4))))
+        (forward-line -1))
+      (when result
+        ;; Advance if there is a next line that is either blank or indented.
+        ;; (Need to check if we're on the last line, because
+        ;; markdown-next-line-blank-p returns true for last line in buffer.)
+        (while (and (/= (line-end-position) (point-max))
+                    (or (markdown-next-line-blank-p)
+                        (>= (markdown-next-line-indent) 4)))
+          (forward-line))
+        ;; Move back while the current line is blank.
+        (while (markdown-cur-line-blank-p)
+          (forward-line -1))
+        ;; Advance to capture this line and a single trailing newline (if there
+        ;; is one).
+        (forward-line)
+        (append result (list (point)))))))
+
+(defun markdown-get-defined-footnotes ()
+  "Return a list of all defined footnotes.
+Result is an alist of pairs (MARKER . LINE), where MARKER is the
+footnote marker, a string, and LINE is the line number containing
+the footnote definition.
+
+For example, suppose the following footnotes are defined at positions
+448 and 475:
+
+\[^1]: First footnote here.
+\[^marker]: Second footnote.
+
+Then the returned list is: ((\"^1\" . 478) (\"^marker\" . 475))"
+  (save-excursion
+    (goto-char (point-min))
+    (let (footnotes)
+      (while (markdown-search-until-condition
+              (lambda () (and (not (markdown-code-block-at-point-p))
+                              (not (markdown-inline-code-at-point-p))
+                              (not (markdown-in-comment-p))))
+              markdown-regex-footnote-definition nil t)
+        (let ((marker (match-string-no-properties 1))
+              (pos (match-beginning 0)))
+          (unless (zerop (length marker))
+            (cl-pushnew (cons marker pos) footnotes :test #'equal))))
+      (reverse footnotes))))
+
+
+;;; Element Removal ===========================================================
+
+(defun markdown-kill-thing-at-point ()
+  "Kill thing at point and add important text, without markup, to kill ring.
+Possible things to kill include (roughly in order of precedence):
+inline code, headers, horizonal rules, links (add link text to
+kill ring), images (add alt text to kill ring), angle uri, email
+addresses, bold, italics, reference definition (add URI to kill
+ring), footnote markers and text (kill both marker and text, add
+text to kill ring), and list items."
+  (interactive "*")
+  (let (val)
+    (cond
+     ;; Inline code
+     ((markdown-inline-code-at-point)
+      (kill-new (match-string 2))
+      (delete-region (match-beginning 0) (match-end 0)))
+     ;; ATX header
+     ((thing-at-point-looking-at markdown-regex-header-atx)
+      (kill-new (match-string 2))
+      (delete-region (match-beginning 0) (match-end 0)))
+     ;; Setext header
+     ((thing-at-point-looking-at markdown-regex-header-setext)
+      (kill-new (match-string 1))
+      (delete-region (match-beginning 0) (match-end 0)))
+     ;; Horizonal rule
+     ((thing-at-point-looking-at markdown-regex-hr)
+      (kill-new (match-string 0))
+      (delete-region (match-beginning 0) (match-end 0)))
+     ;; Inline link or image (add link or alt text to kill ring)
+     ((thing-at-point-looking-at markdown-regex-link-inline)
+      (kill-new (match-string 3))
+      (delete-region (match-beginning 0) (match-end 0)))
+     ;; Reference link or image (add link or alt text to kill ring)
+     ((thing-at-point-looking-at markdown-regex-link-reference)
+      (kill-new (match-string 3))
+      (delete-region (match-beginning 0) (match-end 0)))
+     ;; Angle URI (add URL to kill ring)
+     ((thing-at-point-looking-at markdown-regex-angle-uri)
+      (kill-new (match-string 2))
+      (delete-region (match-beginning 0) (match-end 0)))
+     ;; Email address in angle brackets (add email address to kill ring)
+     ((thing-at-point-looking-at markdown-regex-email)
+      (kill-new (match-string 1))
+      (delete-region (match-beginning 0) (match-end 0)))
+     ;; Wiki link (add alias text to kill ring)
+     ((and markdown-enable-wiki-links
+           (thing-at-point-looking-at markdown-regex-wiki-link))
+      (kill-new (markdown-wiki-link-alias))
+      (delete-region (match-beginning 1) (match-end 1)))
+     ;; Bold
+     ((thing-at-point-looking-at markdown-regex-bold)
+      (kill-new (match-string 4))
+      (delete-region (match-beginning 2) (match-end 2)))
+     ;; Italics
+     ((thing-at-point-looking-at markdown-regex-italic)
+      (kill-new (match-string 3))
+      (delete-region (match-beginning 1) (match-end 1)))
+     ;; Strikethrough
+     ((thing-at-point-looking-at markdown-regex-strike-through)
+      (kill-new (match-string 4))
+      (delete-region (match-beginning 2) (match-end 2)))
+     ;; Footnote marker (add footnote text to kill ring)
+     ((thing-at-point-looking-at markdown-regex-footnote)
+      (markdown-footnote-kill))
+     ;; Footnote text (add footnote text to kill ring)
+     ((setq val (markdown-footnote-text-positions))
+      (markdown-footnote-kill))
+     ;; Reference definition (add URL to kill ring)
+     ((thing-at-point-looking-at markdown-regex-reference-definition)
+      (kill-new (match-string 5))
+      (delete-region (match-beginning 0) (match-end 0)))
+     ;; List item
+     ((setq val (markdown-cur-list-item-bounds))
+      (kill-new (delete-and-extract-region (cl-first val) (cl-second val))))
+     (t
+      (user-error "Nothing found at point to kill")))))
+
+
+;;; Indentation ====================================================================
+
+(defun markdown-indent-find-next-position (cur-pos positions)
+  "Return the position after the index of CUR-POS in POSITIONS.
+Positions are calculated by `markdown-calc-indents'."
+  (while (and positions
+              (not (equal cur-pos (car positions))))
+    (setq positions (cdr positions)))
+  (or (cadr positions) 0))
+
+(define-obsolete-function-alias 'markdown-exdent-find-next-position
+  'markdown-outdent-find-next-position "v2.3")
+
+(defun markdown-outdent-find-next-position (cur-pos positions)
+  "Return the maximal element that precedes CUR-POS from POSITIONS.
+Positions are calculated by `markdown-calc-indents'."
+  (let ((result 0))
+    (dolist (i positions)
+      (when (< i cur-pos)
+        (setq result (max result i))))
+    result))
+
+(defun markdown-indent-line ()
+  "Indent the current line using some heuristics.
+If the _previous_ command was either `markdown-enter-key' or
+`markdown-cycle', then we should cycle to the next
+reasonable indentation position.  Otherwise, we could have been
+called directly by `markdown-enter-key', by an initial call of
+`markdown-cycle', or indirectly by `auto-fill-mode'.  In
+these cases, indent to the default position.
+Positions are calculated by `markdown-calc-indents'."
+  (interactive)
+  (let ((positions (markdown-calc-indents))
+        (point-pos (current-column))
+        (_ (back-to-indentation))
+        (cur-pos (current-column)))
+    (if (not (equal this-command 'markdown-cycle))
+        (indent-line-to (car positions))
+      (setq positions (sort (delete-dups positions) '<))
+      (let* ((next-pos (markdown-indent-find-next-position cur-pos positions))
+             (new-point-pos (max (+ point-pos (- next-pos cur-pos)) 0)))
+        (indent-line-to next-pos)
+        (move-to-column new-point-pos)))))
+
+(defun markdown-calc-indents ()
+  "Return a list of indentation columns to cycle through.
+The first element in the returned list should be considered the
+default indentation level.  This function does not worry about
+duplicate positions, which are handled up by calling functions."
+  (let (pos prev-line-pos positions)
+
+    ;; Indentation of previous line
+    (setq prev-line-pos (markdown-prev-line-indent))
+    (setq positions (cons prev-line-pos positions))
+
+    ;; Indentation of previous non-list-marker text
+    (when (setq pos (save-excursion
+                      (forward-line -1)
+                      (when (looking-at markdown-regex-list)
+                        (- (match-end 3) (match-beginning 0)))))
+      (setq positions (cons pos positions)))
+
+    ;; Indentation required for a pre block in current context
+    (setq pos (length (markdown-pre-indentation (point))))
+    (setq positions (cons pos positions))
+
+    ;; Indentation of the previous line + tab-width
+    (if prev-line-pos
+        (setq positions (cons (+ prev-line-pos tab-width) positions))
+      (setq positions (cons tab-width positions)))
+
+    ;; Indentation of the previous line - tab-width
+    (if (and prev-line-pos (> prev-line-pos tab-width))
+        (setq positions (cons (- prev-line-pos tab-width) positions)))
+
+    ;; Indentation of all preceeding list markers (when in a list)
+    (when (setq pos (markdown-calculate-list-levels))
+      (setq positions (append pos positions)))
+
+    ;; First column
+    (setq positions (cons 0 positions))
+
+    ;; Return reversed list
+    (reverse positions)))
+
+(defun markdown-enter-key ()
+  "Handle RET depending on the context.
+If the point is at a table, move to the next row.  Otherwise,
+indent according to value of `markdown-indent-on-enter'.
+When it is nil, simply call `newline'.  Otherwise, indent the next line
+following RET using `markdown-indent-line'.  Furthermore, when it
+is set to 'indent-and-new-item and the point is in a list item,
+start a new item with the same indentation. If the point is in an
+empty list item, remove it (so that pressing RET twice when in a
+list simply adds a blank line)."
+  (interactive)
+  (cond
+   ;; Table
+   ((markdown-table-at-point-p)
+    (call-interactively #'markdown-table-next-row))
+   ;; Indent non-table text
+   (markdown-indent-on-enter
+    (let (bounds)
+      (if (and (memq markdown-indent-on-enter '(indent-and-new-item))
+               (setq bounds (markdown-cur-list-item-bounds)))
+          (let ((beg (cl-first bounds))
+                (end (cl-second bounds))
+                (length (cl-fourth bounds)))
+            ;; Point is in a list item
+            (if (= (- end beg) length)
+                ;; Delete blank list
+                (progn
+                  (delete-region beg end)
+                  (newline)
+                  (markdown-indent-line))
+              (call-interactively #'markdown-insert-list-item)))
+        ;; Point is not in a list
+        (newline)
+        (markdown-indent-line))))
+   ;; Insert a raw newline
+   (t (newline))))
+
+(define-obsolete-function-alias 'markdown-exdent-or-delete
+  'markdown-outdent-or-delete "v2.3")
+
+(defun markdown-outdent-or-delete (arg)
+  "Handle BACKSPACE by cycling through indentation points.
+When BACKSPACE is pressed, if there is only whitespace
+before the current point, then outdent the line one level.
+Otherwise, do normal delete by repeating
+`backward-delete-char-untabify' ARG times."
+  (interactive "*p")
+  (if (use-region-p)
+      (backward-delete-char-untabify arg)
+    (let ((cur-pos (current-column))
+          (start-of-indention (save-excursion
+                                (back-to-indentation)
+                                (current-column)))
+          (positions (markdown-calc-indents)))
+      (if (and (> cur-pos 0) (= cur-pos start-of-indention))
+          (indent-line-to (markdown-outdent-find-next-position cur-pos positions))
+        (backward-delete-char-untabify arg)))))
+
+(defun markdown-find-leftmost-column (beg end)
+  "Find the leftmost column in the region from BEG to END."
+  (let ((mincol 1000))
+    (save-excursion
+      (goto-char beg)
+      (while (< (point) end)
+        (back-to-indentation)
+        (unless (looking-at-p "[ \t]*$")
+          (setq mincol (min mincol (current-column))))
+        (forward-line 1)
+        ))
+    mincol))
+
+(defun markdown-indent-region (beg end arg)
+  "Indent the region from BEG to END using some heuristics.
+When ARG is non-nil, outdent the region instead.
+See `markdown-indent-line' and `markdown-indent-line'."
+  (interactive "*r\nP")
+  (let* ((positions (sort (delete-dups (markdown-calc-indents)) '<))
+         (leftmostcol (markdown-find-leftmost-column beg end))
+         (next-pos (if arg
+                       (markdown-outdent-find-next-position leftmostcol positions)
+                     (markdown-indent-find-next-position leftmostcol positions))))
+    (indent-rigidly beg end (- next-pos leftmostcol))
+    (setq deactivate-mark nil)))
+
+(define-obsolete-function-alias 'markdown-exdent-region
+  'markdown-outdent-region "v2.3")
+
+(defun markdown-outdent-region (beg end)
+  "Call `markdown-indent-region' on region from BEG to END with prefix."
+  (interactive "*r")
+  (markdown-indent-region beg end t))
+
+
+;;; Markup Completion =========================================================
+
+(defconst markdown-complete-alist
+  '((markdown-regex-header-atx . markdown-complete-atx)
+    (markdown-regex-header-setext . markdown-complete-setext)
+    (markdown-regex-hr . markdown-complete-hr))
+  "Association list of form (regexp . function) for markup completion.")
+
+(defun markdown-incomplete-atx-p ()
+  "Return t if ATX header markup is incomplete and nil otherwise.
+Assumes match data is available for `markdown-regex-header-atx'.
+Checks that the number of trailing hash marks equals the number of leading
+hash marks, that there is only a single space before and after the text,
+and that there is no extraneous whitespace in the text."
+  (or
+   ;; Number of starting and ending hash marks differs
+   (not (= (length (match-string 1)) (length (match-string 3))))
+   ;; When the header text is not empty...
+   (and (> (length (match-string 2)) 0)
+        ;; ...if there are extra leading, trailing, or interior spaces
+        (or (not (= (match-beginning 2) (1+ (match-end 1))))
+            (not (= (match-beginning 3) (1+ (match-end 2))))
+            (string-match-p "[ \t\n]\\{2\\}" (match-string 2))))
+   ;; When the header text is empty...
+   (and (= (length (match-string 2)) 0)
+        ;; ...if there are too many or too few spaces
+        (not (= (match-beginning 3) (+ (match-end 1) 2))))))
+
+(defun markdown-complete-atx ()
+  "Complete and normalize ATX headers.
+Add or remove hash marks to the end of the header to match the
+beginning.  Ensure that there is only a single space between hash
+marks and header text.  Removes extraneous whitespace from header text.
+Assumes match data is available for `markdown-regex-header-atx'.
+Return nil if markup was complete and non-nil if markup was completed."
+  (when (markdown-incomplete-atx-p)
+    (let* ((new-marker (make-marker))
+           (new-marker (set-marker new-marker (match-end 2))))
+      ;; Hash marks and spacing at end
+      (goto-char (match-end 2))
+      (delete-region (match-end 2) (match-end 3))
+      (insert " " (match-string 1))
+      ;; Remove extraneous whitespace from title
+      (replace-match (markdown-compress-whitespace-string (match-string 2))
+                     t t nil 2)
+      ;; Spacing at beginning
+      (goto-char (match-end 1))
+      (delete-region (match-end 1) (match-beginning 2))
+      (insert " ")
+      ;; Leave point at end of text
+      (goto-char new-marker))))
+
+(defun markdown-incomplete-setext-p ()
+  "Return t if setext header markup is incomplete and nil otherwise.
+Assumes match data is available for `markdown-regex-header-setext'.
+Checks that length of underline matches text and that there is no
+extraneous whitespace in the text."
+  (or (not (= (length (match-string 1)) (length (match-string 2))))
+      (string-match-p "[ \t\n]\\{2\\}" (match-string 1))))
+
+(defun markdown-complete-setext ()
+  "Complete and normalize setext headers.
+Add or remove underline characters to match length of header
+text.  Removes extraneous whitespace from header text.  Assumes
+match data is available for `markdown-regex-header-setext'.
+Return nil if markup was complete and non-nil if markup was completed."
+  (when (markdown-incomplete-setext-p)
+    (let* ((text (markdown-compress-whitespace-string (match-string 1)))
+           (char (char-after (match-beginning 2)))
+           (level (if (char-equal char ?-) 2 1)))
+      (goto-char (match-beginning 0))
+      (delete-region (match-beginning 0) (match-end 0))
+      (markdown-insert-header level text t)
+      t)))
+
+(defun markdown-incomplete-hr-p ()
+  "Return non-nil if hr is not in `markdown-hr-strings' and nil otherwise.
+Assumes match data is available for `markdown-regex-hr'."
+  (not (member (match-string 0) markdown-hr-strings)))
+
+(defun markdown-complete-hr ()
+  "Complete horizontal rules.
+If horizontal rule string is a member of `markdown-hr-strings',
+do nothing.  Otherwise, replace with the car of
+`markdown-hr-strings'.
+Assumes match data is available for `markdown-regex-hr'.
+Return nil if markup was complete and non-nil if markup was completed."
+  (when (markdown-incomplete-hr-p)
+    (replace-match (car markdown-hr-strings))
+    t))
+
+(defun markdown-complete ()
+  "Complete markup of object near point or in region when active.
+Handle all objects in `markdown-complete-alist', in order.
+See `markdown-complete-at-point' and `markdown-complete-region'."
+  (interactive "*")
+  (if (markdown-use-region-p)
+      (markdown-complete-region (region-beginning) (region-end))
+    (markdown-complete-at-point)))
+
+(defun markdown-complete-at-point ()
+  "Complete markup of object near point.
+Handle all elements of `markdown-complete-alist' in order."
+  (interactive "*")
+  (let ((list markdown-complete-alist) found changed)
+    (while list
+      (let ((regexp (eval (caar list)))
+            (function (cdar list)))
+        (setq list (cdr list))
+        (when (thing-at-point-looking-at regexp)
+          (setq found t)
+          (setq changed (funcall function))
+          (setq list nil))))
+    (if found
+        (or changed (user-error "Markup at point is complete"))
+      (user-error "Nothing to complete at point"))))
+
+(defun markdown-complete-region (beg end)
+  "Complete markup of objects in region from BEG to END.
+Handle all objects in `markdown-complete-alist', in order.  Each
+match is checked to ensure that a previous regexp does not also
+match."
+  (interactive "*r")
+  (let ((end-marker (set-marker (make-marker) end))
+        previous)
+    (dolist (element markdown-complete-alist)
+      (let ((regexp (eval (car element)))
+            (function (cdr element)))
+        (goto-char beg)
+        (while (re-search-forward regexp end-marker 'limit)
+          (when (match-string 0)
+            ;; Make sure this is not a match for any of the preceding regexps.
+            ;; This prevents mistaking an HR for a Setext subheading.
+            (let (match)
+              (save-match-data
+                (dolist (prev-regexp previous)
+                  (or match (setq match (looking-back prev-regexp nil)))))
+              (unless match
+                (save-excursion (funcall function))))))
+        (cl-pushnew regexp previous :test #'equal)))
+    previous))
+
+(defun markdown-complete-buffer ()
+  "Complete markup for all objects in the current buffer."
+  (interactive "*")
+  (markdown-complete-region (point-min) (point-max)))
+
+
+;;; Markup Cycling ============================================================
+
+(defun markdown-cycle-atx (arg &optional remove)
+  "Cycle ATX header markup.
+Promote header (decrease level) when ARG is 1 and demote
+header (increase level) if arg is -1.  When REMOVE is non-nil,
+remove the header when the level reaches zero and stop cycling
+when it reaches six.  Otherwise, perform a proper cycling through
+levels one through six.  Assumes match data is available for
+`markdown-regex-header-atx'."
+  (let* ((old-level (length (match-string 1)))
+         (new-level (+ old-level arg))
+         (text (match-string 2)))
+    (when (not remove)
+      (setq new-level (% new-level 6))
+      (setq new-level (cond ((= new-level 0) 6)
+                            ((< new-level 0) (+ new-level 6))
+                            (t new-level))))
+    (cond
+     ((= new-level 0)
+      (markdown-unwrap-thing-at-point nil 0 2))
+     ((<= new-level 6)
+      (goto-char (match-beginning 0))
+      (delete-region (match-beginning 0) (match-end 0))
+      (markdown-insert-header new-level text nil)))))
+
+(defun markdown-cycle-setext (arg &optional remove)
+  "Cycle setext header markup.
+Promote header (increase level) when ARG is 1 and demote
+header (decrease level or remove) if arg is -1.  When demoting a
+level-two setext header, replace with a level-three atx header.
+When REMOVE is non-nil, remove the header when the level reaches
+zero.  Otherwise, cycle back to a level six atx header.  Assumes
+match data is available for `markdown-regex-header-setext'."
+  (let* ((char (char-after (match-beginning 2)))
+         (old-level (if (char-equal char ?=) 1 2))
+         (new-level (+ old-level arg)))
+    (when (and (not remove) (= new-level 0))
+      (setq new-level 6))
+    (cond
+     ((= new-level 0)
+      (markdown-unwrap-thing-at-point nil 0 1))
+     ((<= new-level 2)
+      (markdown-insert-header new-level nil t))
+     ((<= new-level 6)
+      (markdown-insert-header new-level nil nil)))))
+
+(defun markdown-cycle-hr (arg &optional remove)
+  "Cycle string used for horizontal rule from `markdown-hr-strings'.
+When ARG is 1, cycle forward (demote), and when ARG is -1, cycle
+backwards (promote).  When REMOVE is non-nil, remove the hr instead
+of cycling when the end of the list is reached.
+Assumes match data is available for `markdown-regex-hr'."
+  (let* ((strings (if (= arg -1)
+                      (reverse markdown-hr-strings)
+                    markdown-hr-strings))
+         (tail (member (match-string 0) strings))
+         (new (or (cadr tail)
+                  (if remove
+                      (if (= arg 1)
+                          ""
+                        (car tail))
+                    (car strings)))))
+    (replace-match new)))
+
+(defun markdown-cycle-bold ()
+  "Cycle bold markup between underscores and asterisks.
+Assumes match data is available for `markdown-regex-bold'."
+  (save-excursion
+    (let* ((old-delim (match-string 3))
+           (new-delim (if (string-equal old-delim "**") "__" "**")))
+      (replace-match new-delim t t nil 3)
+      (replace-match new-delim t t nil 5))))
+
+(defun markdown-cycle-italic ()
+  "Cycle italic markup between underscores and asterisks.
+Assumes match data is available for `markdown-regex-italic'."
+  (save-excursion
+    (let* ((old-delim (match-string 2))
+           (new-delim (if (string-equal old-delim "*") "_" "*")))
+      (replace-match new-delim t t nil 2)
+      (replace-match new-delim t t nil 4))))
+
+
+;;; Keymap ====================================================================
+
+(defun markdown--style-map-prompt ()
+  "Return a formatted prompt for Markdown markup insertion."
+  (when markdown-enable-prefix-prompts
+    (concat
+     "Markdown: "
+     (propertize "bold" 'face 'markdown-bold-face) ", "
+     (propertize "italic" 'face 'markdown-italic-face) ", "
+     (propertize "code" 'face 'markdown-inline-code-face) ", "
+     (propertize "C = GFM code" 'face 'markdown-code-face) ", "
+     (propertize "pre" 'face 'markdown-pre-face) ", "
+     (propertize "footnote" 'face 'markdown-footnote-text-face) ", "
+     (propertize "q = blockquote" 'face 'markdown-blockquote-face) ", "
+     (propertize "h & 1-6 = heading" 'face 'markdown-header-face) ", "
+     (propertize "- = hr" 'face 'markdown-hr-face) ", "
+     "C-h = more")))
+
+(defun markdown--command-map-prompt ()
+  "Return prompt for Markdown buffer-wide commands."
+  (when markdown-enable-prefix-prompts
+    (concat
+     "Command: "
+     (propertize "m" 'face 'markdown-bold-face) "arkdown, "
+     (propertize "p" 'face 'markdown-bold-face) "review, "
+     (propertize "o" 'face 'markdown-bold-face) "pen, "
+     (propertize "e" 'face 'markdown-bold-face) "xport, "
+     "export & pre" (propertize "v" 'face 'markdown-bold-face) "iew, "
+     (propertize "c" 'face 'markdown-bold-face) "heck refs, "
+     (propertize "u" 'face 'markdown-bold-face) "nused refs, "
+     "C-h = more")))
+
+(defvar markdown-mode-style-map
+  (let ((map (make-keymap (markdown--style-map-prompt))))
+    (define-key map (kbd "1") 'markdown-insert-header-atx-1)
+    (define-key map (kbd "2") 'markdown-insert-header-atx-2)
+    (define-key map (kbd "3") 'markdown-insert-header-atx-3)
+    (define-key map (kbd "4") 'markdown-insert-header-atx-4)
+    (define-key map (kbd "5") 'markdown-insert-header-atx-5)
+    (define-key map (kbd "6") 'markdown-insert-header-atx-6)
+    (define-key map (kbd "!") 'markdown-insert-header-setext-1)
+    (define-key map (kbd "@") 'markdown-insert-header-setext-2)
+    (define-key map (kbd "b") 'markdown-insert-bold)
+    (define-key map (kbd "c") 'markdown-insert-code)
+    (define-key map (kbd "C") 'markdown-insert-gfm-code-block)
+    (define-key map (kbd "f") 'markdown-insert-footnote)
+    (define-key map (kbd "h") 'markdown-insert-header-dwim)
+    (define-key map (kbd "H") 'markdown-insert-header-setext-dwim)
+    (define-key map (kbd "i") 'markdown-insert-italic)
+    (define-key map (kbd "k") 'markdown-insert-kbd)
+    (define-key map (kbd "l") 'markdown-insert-link)
+    (define-key map (kbd "p") 'markdown-insert-pre)
+    (define-key map (kbd "P") 'markdown-pre-region)
+    (define-key map (kbd "q") 'markdown-insert-blockquote)
+    (define-key map (kbd "s") 'markdown-insert-strike-through)
+    (define-key map (kbd "Q") 'markdown-blockquote-region)
+    (define-key map (kbd "w") 'markdown-insert-wiki-link)
+    (define-key map (kbd "-") 'markdown-insert-hr)
+    (define-key map (kbd "[") 'markdown-insert-gfm-checkbox)
+    ;; Deprecated keys that may be removed in a future version
+    (define-key map (kbd "e") 'markdown-insert-italic)
+    map)
+  "Keymap for Markdown text styling commands.")
+
+(defvar markdown-mode-command-map
+  (let ((map (make-keymap (markdown--command-map-prompt))))
+    (define-key map (kbd "m") 'markdown-other-window)
+    (define-key map (kbd "p") 'markdown-preview)
+    (define-key map (kbd "e") 'markdown-export)
+    (define-key map (kbd "v") 'markdown-export-and-preview)
+    (define-key map (kbd "o") 'markdown-open)
+    (define-key map (kbd "l") 'markdown-live-preview-mode)
+    (define-key map (kbd "w") 'markdown-kill-ring-save)
+    (define-key map (kbd "c") 'markdown-check-refs)
+    (define-key map (kbd "u") 'markdown-unused-refs)
+    (define-key map (kbd "n") 'markdown-cleanup-list-numbers)
+    (define-key map (kbd "]") 'markdown-complete-buffer)
+    (define-key map (kbd "^") 'markdown-table-sort-lines)
+    (define-key map (kbd "|") 'markdown-table-convert-region)
+    (define-key map (kbd "t") 'markdown-table-transpose)
+    map)
+  "Keymap for Markdown buffer-wide commands.")
+
+(defvar markdown-mode-map
+  (let ((map (make-keymap)))
+    ;; Markup insertion & removal
+    (define-key map (kbd "C-c C-s") markdown-mode-style-map)
+    (define-key map (kbd "C-c C-l") 'markdown-insert-link)
+    (define-key map (kbd "C-c C-k") 'markdown-kill-thing-at-point)
+    ;; Promotion, demotion, and cycling
+    (define-key map (kbd "C-c C--") 'markdown-promote)
+    (define-key map (kbd "C-c C-=") 'markdown-demote)
+    (define-key map (kbd "C-c C-]") 'markdown-complete)
+    ;; Following and doing things
+    (define-key map (kbd "C-c C-o") 'markdown-follow-thing-at-point)
+    (define-key map (kbd "C-c C-d") 'markdown-do)
+    (define-key map (kbd "C-c '") 'markdown-edit-code-block)
+    ;; Indentation
+    (define-key map (kbd "C-m") 'markdown-enter-key)
+    (define-key map (kbd "DEL") 'markdown-outdent-or-delete)
+    (define-key map (kbd "C-c >") 'markdown-indent-region)
+    (define-key map (kbd "C-c <") 'markdown-outdent-region)
+    ;; Visibility cycling
+    (define-key map (kbd "TAB") 'markdown-cycle)
+    (define-key map (kbd "<S-iso-lefttab>") 'markdown-shifttab)
+    (define-key map (kbd "<S-tab>")  'markdown-shifttab)
+    (define-key map (kbd "<backtab>") 'markdown-shifttab)
+    ;; Heading and list navigation
+    (define-key map (kbd "C-c C-n") 'markdown-outline-next)
+    (define-key map (kbd "C-c C-p") 'markdown-outline-previous)
+    (define-key map (kbd "C-c C-f") 'markdown-outline-next-same-level)
+    (define-key map (kbd "C-c C-b") 'markdown-outline-previous-same-level)
+    (define-key map (kbd "C-c C-u") 'markdown-outline-up)
+    ;; Buffer-wide commands
+    (define-key map (kbd "C-c C-c") markdown-mode-command-map)
+    ;; Subtree, list, and table editing
+    (define-key map (kbd "C-c <up>") 'markdown-move-up)
+    (define-key map (kbd "C-c <down>") 'markdown-move-down)
+    (define-key map (kbd "C-c <left>") 'markdown-promote)
+    (define-key map (kbd "C-c <right>") 'markdown-demote)
+    (define-key map (kbd "C-c S-<up>") 'markdown-table-delete-row)
+    (define-key map (kbd "C-c S-<down>") 'markdown-table-insert-row)
+    (define-key map (kbd "C-c S-<left>") 'markdown-table-delete-column)
+    (define-key map (kbd "C-c S-<right>") 'markdown-table-insert-column)
+    (define-key map (kbd "C-c C-M-h") 'markdown-mark-subtree)
+    (define-key map (kbd "C-x n s") 'markdown-narrow-to-subtree)
+    (define-key map (kbd "M-RET") 'markdown-insert-list-item)
+    (define-key map (kbd "C-c C-j") 'markdown-insert-list-item)
+    ;; Paragraphs (Markdown context aware)
+    (define-key map [remap backward-paragraph] 'markdown-backward-paragraph)
+    (define-key map [remap forward-paragraph] 'markdown-forward-paragraph)
+    (define-key map [remap mark-paragraph] 'markdown-mark-paragraph)
+    ;; Blocks (one or more paragraphs)
+    (define-key map (kbd "C-M-{") 'markdown-backward-block)
+    (define-key map (kbd "C-M-}") 'markdown-forward-block)
+    (define-key map (kbd "C-c M-h") 'markdown-mark-block)
+    (define-key map (kbd "C-x n b") 'markdown-narrow-to-block)
+    ;; Pages (top-level sections)
+    (define-key map [remap backward-page] 'markdown-backward-page)
+    (define-key map [remap forward-page] 'markdown-forward-page)
+    (define-key map [remap mark-page] 'markdown-mark-page)
+    (define-key map [remap narrow-to-page] 'markdown-narrow-to-page)
+    ;; Link Movement
+    (define-key map (kbd "M-n") 'markdown-next-link)
+    (define-key map (kbd "M-p") 'markdown-previous-link)
+    ;; Toggling functionality
+    (define-key map (kbd "C-c C-x C-e") 'markdown-toggle-math)
+    (define-key map (kbd "C-c C-x C-f") 'markdown-toggle-fontify-code-blocks-natively)
+    (define-key map (kbd "C-c C-x C-i") 'markdown-toggle-inline-images)
+    (define-key map (kbd "C-c C-x C-l") 'markdown-toggle-url-hiding)
+    (define-key map (kbd "C-c C-x C-m") 'markdown-toggle-markup-hiding)
+    ;; Alternative keys (in case of problems with the arrow keys)
+    (define-key map (kbd "C-c C-x u") 'markdown-move-up)
+    (define-key map (kbd "C-c C-x d") 'markdown-move-down)
+    (define-key map (kbd "C-c C-x l") 'markdown-promote)
+    (define-key map (kbd "C-c C-x r") 'markdown-demote)
+    ;; Deprecated keys that may be removed in a future version
+    (define-key map (kbd "C-c C-a L") 'markdown-insert-link) ;; C-c C-l
+    (define-key map (kbd "C-c C-a l") 'markdown-insert-link) ;; C-c C-l
+    (define-key map (kbd "C-c C-a r") 'markdown-insert-link) ;; C-c C-l
+    (define-key map (kbd "C-c C-a u") 'markdown-insert-uri) ;; C-c C-l
+    (define-key map (kbd "C-c C-a f") 'markdown-insert-footnote)
+    (define-key map (kbd "C-c C-a w") 'markdown-insert-wiki-link)
+    (define-key map (kbd "C-c C-t 1") 'markdown-insert-header-atx-1)
+    (define-key map (kbd "C-c C-t 2") 'markdown-insert-header-atx-2)
+    (define-key map (kbd "C-c C-t 3") 'markdown-insert-header-atx-3)
+    (define-key map (kbd "C-c C-t 4") 'markdown-insert-header-atx-4)
+    (define-key map (kbd "C-c C-t 5") 'markdown-insert-header-atx-5)
+    (define-key map (kbd "C-c C-t 6") 'markdown-insert-header-atx-6)
+    (define-key map (kbd "C-c C-t !") 'markdown-insert-header-setext-1)
+    (define-key map (kbd "C-c C-t @") 'markdown-insert-header-setext-2)
+    (define-key map (kbd "C-c C-t h") 'markdown-insert-header-dwim)
+    (define-key map (kbd "C-c C-t H") 'markdown-insert-header-setext-dwim)
+    (define-key map (kbd "C-c C-t s") 'markdown-insert-header-setext-2)
+    (define-key map (kbd "C-c C-t t") 'markdown-insert-header-setext-1)
+    (define-key map (kbd "C-c C-i") 'markdown-insert-image)
+    (define-key map (kbd "C-c C-x m") 'markdown-insert-list-item) ;; C-c C-j
+    (define-key map (kbd "C-c C-x C-x") 'markdown-toggle-gfm-checkbox) ;; C-c C-d
+    (define-key map (kbd "C-c -") 'markdown-insert-hr)
+    map)
+  "Keymap for Markdown major mode.")
+
+(defvar markdown-mode-mouse-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map [follow-link] 'mouse-face)
+    (define-key map [mouse-2] 'markdown-follow-link-at-point)
+    map)
+  "Keymap for following links with mouse.")
+
+(defvar gfm-mode-map
+  (let ((map (make-sparse-keymap)))
+    (set-keymap-parent map markdown-mode-map)
+    (define-key map (kbd "C-c C-s d") 'markdown-insert-strike-through)
+    (define-key map "`" 'markdown-electric-backquote)
+    map)
+  "Keymap for `gfm-mode'.
+See also `markdown-mode-map'.")
+
+
+;;; Menu ==================================================================
+
+(easy-menu-define markdown-mode-menu markdown-mode-map
+  "Menu for Markdown mode"
+  '("Markdown"
+    "---"
+    ("Movement"
+     ["Jump" markdown-do]
+     ["Follow Link" markdown-follow-thing-at-point]
+     ["Next Link" markdown-next-link]
+     ["Previous Link" markdown-previous-link]
+     "---"
+     ["Next Heading or List Item" markdown-outline-next]
+     ["Previous Heading or List Item" markdown-outline-previous]
+     ["Next at Same Level" markdown-outline-next-same-level]
+     ["Previous at Same Level" markdown-outline-previous-same-level]
+     ["Up to Parent" markdown-outline-up]
+     "---"
+     ["Forward Paragraph" markdown-forward-paragraph]
+     ["Backward Paragraph" markdown-backward-paragraph]
+     ["Forward Block" markdown-forward-block]
+     ["Backward Block" markdown-backward-block])
+    ("Show & Hide"
+     ["Cycle Heading Visibility" markdown-cycle
+      :enable (markdown-on-heading-p)]
+     ["Cycle Heading Visibility (Global)" markdown-shifttab]
+     "---"
+     ["Narrow to Region" narrow-to-region]
+     ["Narrow to Block" markdown-narrow-to-block]
+     ["Narrow to Section" narrow-to-defun]
+     ["Narrow to Subtree" markdown-narrow-to-subtree]
+     ["Widen" widen (buffer-narrowed-p)]
+     "---"
+     ["Toggle Markup Hiding" markdown-toggle-markup-hiding
+      :keys "C-c C-x C-m"
+      :style radio
+      :selected markdown-hide-markup])
+    "---"
+    ("Headings & Structure"
+     ["Automatic Heading" markdown-insert-header-dwim
+      :keys "C-c C-s h"]
+     ["Automatic Heading (Setext)" markdown-insert-header-setext-dwim
+      :keys "C-c C-s H"]
+     ("Specific Heading (atx)"
+      ["First Level atx" markdown-insert-header-atx-1
+       :keys "C-c C-s 1"]
+      ["Second Level atx" markdown-insert-header-atx-2
+       :keys "C-c C-s 2"]
+      ["Third Level atx" markdown-insert-header-atx-3
+       :keys "C-c C-s 3"]
+      ["Fourth Level atx" markdown-insert-header-atx-4
+       :keys "C-c C-s 4"]
+      ["Fifth Level atx" markdown-insert-header-atx-5
+       :keys "C-c C-s 5"]
+      ["Sixth Level atx" markdown-insert-header-atx-6
+       :keys "C-c C-s 6"])
+     ("Specific Heading (Setext)"
+      ["First Level Setext" markdown-insert-header-setext-1
+       :keys "C-c C-s !"]
+      ["Second Level Setext" markdown-insert-header-setext-2
+       :keys "C-c C-s @"])
+     ["Horizontal Rule" markdown-insert-hr
+      :keys "C-c C-s -"]
+     "---"
+     ["Move Subtree Up" markdown-move-up
+      :keys "C-c <up>"]
+     ["Move Subtree Down" markdown-move-down
+      :keys "C-c <down>"]
+     ["Promote Subtree" markdown-promote
+      :keys "C-c <left>"]
+     ["Demote Subtree" markdown-demote
+      :keys "C-c <right>"])
+    ("Region & Mark"
+     ["Indent Region" markdown-indent-region]
+     ["Outdent Region" markdown-outdent-region]
+     "--"
+     ["Mark Paragraph" mark-paragraph]
+     ["Mark Block" markdown-mark-block]
+     ["Mark Section" mark-defun]
+     ["Mark Subtree" markdown-mark-subtree])
+    ("Tables"
+     ["Move Row Up" markdown-move-up
+      :enable (markdown-table-at-point-p)
+      :keys "C-c <up>"]
+     ["Move Row Down" markdown-move-down
+      :enable (markdown-table-at-point-p)
+      :keys "C-c <down>"]
+     ["Move Column Left" markdown-demote
+      :enable (markdown-table-at-point-p)
+      :keys "C-c <left>"]
+     ["Move Column Right" markdown-promote
+      :enable (markdown-table-at-point-p)
+      :keys "C-c <right>"]
+     ["Delete Row" markdown-table-delete-row
+      :enable (markdown-table-at-point-p)]
+     ["Insert Row" markdown-table-insert-row
+      :enable (markdown-table-at-point-p)]
+     ["Delete Column" markdown-table-delete-column
+      :enable (markdown-table-at-point-p)]
+     ["Insert Column" markdown-table-insert-column
+      :enable (markdown-table-at-point-p)]
+     "--"
+     ["Convert Region to Table" markdown-table-convert-region]
+     ["Sort Table Lines" markdown-table-sort-lines
+      :enable (markdown-table-at-point-p)]
+     ["Transpose Table" markdown-table-transpose
+      :enable (markdown-table-at-point-p)])
+    ("Lists"
+     ["Insert List Item" markdown-insert-list-item]
+     ["Move Subtree Up" markdown-move-up
+      :keys "C-c <up>"]
+     ["Move Subtree Down" markdown-move-down
+      :keys "C-c <down>"]
+     ["Indent Subtree" markdown-demote
+      :keys "C-c <right>"]
+     ["Outdent Subtree" markdown-promote
+      :keys "C-c <left>"]
+     ["Renumber List" markdown-cleanup-list-numbers]
+     ["Insert Task List Item" markdown-insert-gfm-checkbox
+      :keys "C-c C-x ["]
+     ["Toggle Task List Item" markdown-toggle-gfm-checkbox
+      :enable (markdown-gfm-task-list-item-at-point)
+      :keys "C-c C-d"])
+    ("Links & Images"
+     ["Insert Link" markdown-insert-link]
+     ["Insert Image" markdown-insert-image]
+     ["Insert Footnote" markdown-insert-footnote
+      :keys "C-c C-s f"]
+     ["Insert Wiki Link" markdown-insert-wiki-link
+      :keys "C-c C-s w"]
+     "---"
+     ["Check References" markdown-check-refs]
+     ["Find Unused References" markdown-unused-refs]
+     ["Toggle URL Hiding" markdown-toggle-url-hiding
+      :style radio
+      :selected markdown-hide-urls]
+     ["Toggle Inline Images" markdown-toggle-inline-images
+      :keys "C-c C-x C-i"
+      :style radio
+      :selected markdown-inline-image-overlays]
+     ["Toggle Wiki Links" markdown-toggle-wiki-links
+      :style radio
+      :selected markdown-enable-wiki-links])
+    ("Styles"
+     ["Bold" markdown-insert-bold]
+     ["Italic" markdown-insert-italic]
+     ["Code" markdown-insert-code]
+     ["Strikethrough" markdown-insert-strike-through]
+     ["Keyboard" markdown-insert-kbd]
+     "---"
+     ["Blockquote" markdown-insert-blockquote]
+     ["Preformatted" markdown-insert-pre]
+     ["GFM Code Block" markdown-insert-gfm-code-block]
+     ["Edit Code Block" markdown-edit-code-block
+      :enable (markdown-code-block-at-point-p)]
+     "---"
+     ["Blockquote Region" markdown-blockquote-region]
+     ["Preformatted Region" markdown-pre-region]
+     "---"
+     ["Fontify Code Blocks Natively"
+      markdown-toggle-fontify-code-blocks-natively
+      :style radio
+      :selected markdown-fontify-code-blocks-natively]
+     ["LaTeX Math Support" markdown-toggle-math
+      :style radio
+      :selected markdown-enable-math])
+    "---"
+    ("Preview & Export"
+     ["Compile" markdown-other-window]
+     ["Preview" markdown-preview]
+     ["Export" markdown-export]
+     ["Export & View" markdown-export-and-preview]
+     ["Open" markdown-open]
+     ["Live Export" markdown-live-preview-mode
+      :style radio
+      :selected markdown-live-preview-mode]
+     ["Kill ring save" markdown-kill-ring-save])
+    ("Markup Completion and Cycling"
+     ["Complete Markup" markdown-complete]
+     ["Promote Element" markdown-promote
+      :keys "C-c C--"]
+     ["Demote Element" markdown-demote
+      :keys "C-c C-="])
+    "---"
+    ["Kill Element" markdown-kill-thing-at-point]
+    "---"
+    ("Documentation"
+     ["Version" markdown-show-version]
+     ["Homepage" markdown-mode-info]
+     ["Describe Mode" (describe-function 'markdown-mode)]
+     ["Guide" (browse-url "https://leanpub.com/markdown-mode")])))
+
+
+;;; imenu =====================================================================
+
+(defun markdown-imenu-create-nested-index ()
+  "Create and return a nested imenu index alist for the current buffer.
+See `imenu-create-index-function' and `imenu--index-alist' for details."
+  (let* ((root '(nil . nil))
+         cur-alist
+         (cur-level 0)
+         (empty-heading "-")
+         (self-heading ".")
+         hashes pos level heading)
+    (save-excursion
+      ;; Headings
+      (goto-char (point-min))
+      (while (re-search-forward markdown-regex-header (point-max) t)
+        (unless (markdown-code-block-at-point-p)
+          (cond
+           ((match-string-no-properties 2) ;; level 1 setext
+            (setq heading (match-string-no-properties 1))
+            (setq pos (match-beginning 1)
+                  level 1))
+           ((match-string-no-properties 3) ;; level 2 setext
+            (setq heading (match-string-no-properties 1))
+            (setq pos (match-beginning 1)
+                  level 2))
+           ((setq hashes (markdown-trim-whitespace
+                          (match-string-no-properties 4)))
+            (setq heading (match-string-no-properties 5)
+                  pos (match-beginning 4)
+                  level (length hashes))))
+          (let ((alist (list (cons heading pos))))
+            (cond
+             ((= cur-level level)       ; new sibling
+              (setcdr cur-alist alist)
+              (setq cur-alist alist))
+             ((< cur-level level)       ; first child
+              (dotimes (_ (- level cur-level 1))
+                (setq alist (list (cons empty-heading alist))))
+              (if cur-alist
+                  (let* ((parent (car cur-alist))
+                         (self-pos (cdr parent)))
+                    (setcdr parent (cons (cons self-heading self-pos) alist)))
+                (setcdr root alist))    ; primogenitor
+              (setq cur-alist alist)
+              (setq cur-level level))
+             (t                         ; new sibling of an ancestor
+              (let ((sibling-alist (last (cdr root))))
+                (dotimes (_ (1- level))
+                  (setq sibling-alist (last (cdar sibling-alist))))
+                (setcdr sibling-alist alist)
+                (setq cur-alist alist))
+              (setq cur-level level))))))
+      ;; Footnotes
+      (let ((fn (markdown-get-defined-footnotes)))
+        (if (or (zerop (length fn))
+                (null markdown-add-footnotes-to-imenu))
+            (cdr root)
+          (nconc (cdr root) (list (cons "Footnotes" fn))))))))
+
+(defun markdown-imenu-create-flat-index ()
+  "Create and return a flat imenu index alist for the current buffer.
+See `imenu-create-index-function' and `imenu--index-alist' for details."
+  (let* ((empty-heading "-") index heading pos)
+    (save-excursion
+      ;; Headings
+      (goto-char (point-min))
+      (while (re-search-forward markdown-regex-header (point-max) t)
+        (when (and (not (markdown-code-block-at-point-p))
+                   (not (markdown-text-property-at-point 'markdown-yaml-metadata-begin)))
+          (cond
+           ((setq heading (match-string-no-properties 1))
+            (setq pos (match-beginning 1)))
+           ((setq heading (match-string-no-properties 5))
+            (setq pos (match-beginning 4))))
+          (or (> (length heading) 0)
+              (setq heading empty-heading))
+          (setq index (append index (list (cons heading pos))))))
+      ;; Footnotes
+      (when markdown-add-footnotes-to-imenu
+        (nconc index (markdown-get-defined-footnotes)))
+      index)))
+
+
+;;; References ================================================================
+
+(defun markdown-reference-goto-definition ()
+  "Jump to the definition of the reference at point or create it."
+  (interactive)
+  (when (thing-at-point-looking-at markdown-regex-link-reference)
+    (let* ((text (match-string-no-properties 3))
+           (reference (match-string-no-properties 6))
+           (target (downcase (if (string= reference "") text reference)))
+           (loc (cadr (save-match-data (markdown-reference-definition target)))))
+      (if loc
+          (goto-char loc)
+        (goto-char (match-beginning 0))
+        (markdown-insert-reference-definition target)))))
+
+(defun markdown-reference-find-links (reference)
+  "Return a list of all links for REFERENCE.
+REFERENCE should not include the surrounding square brackets.
+Elements of the list have the form (text start line), where
+text is the link text, start is the location at the beginning of
+the link, and line is the line number on which the link appears."
+  (let* ((ref-quote (regexp-quote reference))
+         (regexp (format "!?\\(?:\\[\\(%s\\)\\][ ]?\\[\\]\\|\\[\\([^]]+?\\)\\][ ]?\\[%s\\]\\)"
+                         ref-quote ref-quote))
+         links)
+    (save-excursion
+      (goto-char (point-min))
+      (while (re-search-forward regexp nil t)
+        (let* ((text (or (match-string-no-properties 1)
+                         (match-string-no-properties 2)))
+               (start (match-beginning 0))
+               (line (markdown-line-number-at-pos)))
+          (cl-pushnew (list text start line) links :test #'equal))))
+    links))
+
+(defmacro markdown-for-all-refs (f)
+  `(let ((result))
+     (save-excursion
+       (goto-char (point-min))
+       (while
+           (re-search-forward markdown-regex-link-reference nil t)
+         (let* ((text (match-string-no-properties 3))
+                (reference (match-string-no-properties 6))
+                (target (downcase (if (string= reference "") text reference))))
+          (,f text target result))))
+     (reverse result)))
+
+(defmacro markdown-collect-always (_ target result)
+  `(cl-pushnew ,target ,result :test #'equal))
+
+(defmacro markdown-collect-undefined (text target result)
+  `(unless (markdown-reference-definition target)
+     (let ((entry (assoc ,target ,result)))
+       (if (not entry)
+           (cl-pushnew
+            (cons ,target (list (cons ,text (markdown-line-number-at-pos))))
+            ,result :test #'equal)
+         (setcdr entry
+                 (append (cdr entry) (list (cons ,text (markdown-line-number-at-pos)))))))))
+
+(defun markdown-get-all-refs ()
+  "Return a list of all Markdown references."
+  (markdown-for-all-refs markdown-collect-always))
+
+(defun markdown-get-undefined-refs ()
+  "Return a list of undefined Markdown references.
+Result is an alist of pairs (reference . occurrences), where
+occurrences is itself another alist of pairs (label . line-number).
+For example, an alist corresponding to [Nice editor][Emacs] at line 12,
+\[GNU Emacs][Emacs] at line 45 and [manual][elisp] at line 127 is
+\((\"emacs\" (\"Nice editor\" . 12) (\"GNU Emacs\" . 45)) (\"elisp\" (\"manual\" . 127)))."
+  (markdown-for-all-refs markdown-collect-undefined))
+
+(defun markdown-get-unused-refs ()
+  (cl-sort
+   (cl-set-difference
+    (markdown-get-defined-references) (markdown-get-all-refs)
+    :test (lambda (e1 e2) (equal (car e1) e2)))
+   #'< :key #'cdr))
+
+(defmacro defun-markdown-buffer (name docstring)
+  "Define a function to name and return a buffer.
+
+By convention, NAME must be a name of a string constant with
+%buffer% placeholder used to name the buffer, and will also be
+used as a name of the function defined.
+
+DOCSTRING will be used as the first part of the docstring."
+  `(defun ,name (&optional buffer-name)
+     ,(concat docstring "\n\nBUFFER-NAME is the name of the main buffer being visited.")
+     (or buffer-name (setq buffer-name (buffer-name)))
+     (let ((refbuf (get-buffer-create (markdown-replace-regexp-in-string
+                                       "%buffer%" buffer-name
+                                       ,name))))
+       (with-current-buffer refbuf
+         (when view-mode
+           (View-exit-and-edit))
+         (use-local-map button-buffer-map)
+         (erase-buffer))
+       refbuf)))
+
+(defconst markdown-reference-check-buffer
+  "*Undefined references for %buffer%*"
+  "Pattern for name of buffer for listing undefined references.
+The string %buffer% will be replaced by the corresponding
+`markdown-mode' buffer name.")
+
+(defun-markdown-buffer
+  markdown-reference-check-buffer
+  "Name and return buffer for reference checking.")
+
+(defconst markdown-unused-references-buffer
+  "*Unused references for %buffer%*"
+  "Pattern for name of buffer for listing unused references.
+The string %buffer% will be replaced by the corresponding
+`markdown-mode' buffer name.")
+
+(defun-markdown-buffer
+  markdown-unused-references-buffer
+  "Name and return buffer for unused reference checking.")
+
+(defconst markdown-reference-links-buffer
+  "*Reference links for %buffer%*"
+  "Pattern for name of buffer for listing references.
+The string %buffer% will be replaced by the corresponding buffer name.")
+
+(defun-markdown-buffer
+  markdown-reference-links-buffer
+  "Name, setup, and return a buffer for listing links.")
+
+;; Add an empty Markdown reference definition to buffer
+;; specified in the 'target-buffer property.  The reference name is
+;; the button's label.
+(define-button-type 'markdown-undefined-reference-button
+  'help-echo "mouse-1, RET: create definition for undefined reference"
+  'follow-link t
+  'face 'bold
+  'action (lambda (b)
+            (let ((buffer (button-get b 'target-buffer))
+                  (line (button-get b 'target-line))
+                  (label (button-label b)))
+              (switch-to-buffer-other-window buffer)
+              (goto-char (point-min))
+              (forward-line line)
+              (markdown-insert-reference-definition label)
+              (markdown-check-refs t))))
+
+;; Jump to line in buffer specified by 'target-buffer property.
+;; Line number is button's 'target-line property.
+(define-button-type 'markdown-goto-line-button
+  'help-echo "mouse-1, RET: go to line"
+  'follow-link t
+  'face 'italic
+  'action (lambda (b)
+            (switch-to-buffer-other-window (button-get b 'target-buffer))
+            ;; use call-interactively to silence compiler
+            (let ((current-prefix-arg (button-get b 'target-line)))
+              (call-interactively 'goto-line))))
+
+;; Kill a line in buffer specified by 'target-buffer property.
+;; Line number is button's 'target-line property.
+(define-button-type 'markdown-kill-line-button
+  'help-echo "mouse-1, RET: kill line"
+  'follow-link t
+  'face 'italic
+  'action (lambda (b)
+            (switch-to-buffer-other-window (button-get b 'target-buffer))
+            ;; use call-interactively to silence compiler
+            (let ((current-prefix-arg (button-get b 'target-line)))
+              (call-interactively 'goto-line))
+            (kill-line 1)
+            (markdown-unused-refs t)))
+
+;; Jumps to a particular link at location given by 'target-char
+;; property in buffer given by 'target-buffer property.
+(define-button-type 'markdown-location-button
+  'help-echo "mouse-1, RET: jump to location of link"
+  'follow-link t
+  'face 'bold
+  'action (lambda (b)
+            (let ((target (button-get b 'target-buffer))
+                  (loc (button-get b 'target-char)))
+              (kill-buffer-and-window)
+              (switch-to-buffer target)
+              (goto-char loc))))
+
+(defun markdown-insert-undefined-reference-button (reference oldbuf)
+  "Insert a button for creating REFERENCE in buffer OLDBUF.
+REFERENCE should be a list of the form (reference . occurrences),
+as returned by `markdown-get-undefined-refs'."
+  (let ((label (car reference)))
+    ;; Create a reference button
+    (insert-button label
+                   :type 'markdown-undefined-reference-button
+                   'target-buffer oldbuf
+                   'target-line (cdr (car (cdr reference))))
+    (insert " (")
+    (dolist (occurrence (cdr reference))
+      (let ((line (cdr occurrence)))
+        ;; Create a line number button
+        (insert-button (number-to-string line)
+                       :type 'markdown-goto-line-button
+                       'target-buffer oldbuf
+                       'target-line line)
+        (insert " ")))
+    (delete-char -1)
+    (insert ")")
+    (newline)))
+
+(defun markdown-insert-unused-reference-button (reference oldbuf)
+  "Insert a button for creating REFERENCE in buffer OLDBUF.
+REFERENCE must be a pair of (ref . line-number)."
+  (let ((label (car reference))
+        (line (cdr reference)))
+    ;; Create a reference button
+    (insert-button label
+                   :type 'markdown-goto-line-button
+                   'face 'bold
+                   'target-buffer oldbuf
+                   'target-line line)
+    (insert (format " (%d) [" line))
+    (insert-button "X"
+                   :type 'markdown-kill-line-button
+                   'face 'bold
+                   'target-buffer oldbuf
+                   'target-line line)
+    (insert "]")
+    (newline)))
+
+(defun markdown-insert-link-button (link oldbuf)
+  "Insert a button for jumping to LINK in buffer OLDBUF.
+LINK should be a list of the form (text char line) containing
+the link text, location, and line number."
+  (let ((label (cl-first link))
+        (char (cl-second link))
+        (line (cl-third link)))
+    ;; Create a reference button
+    (insert-button label
+                   :type 'markdown-location-button
+                   'target-buffer oldbuf
+                   'target-char char)
+    (insert (format " (line %d)\n" line))))
+
+(defun markdown-reference-goto-link (&optional reference)
+  "Jump to the location of the first use of REFERENCE."
+  (interactive)
+  (unless reference
+    (if (thing-at-point-looking-at markdown-regex-reference-definition)
+        (setq reference (match-string-no-properties 2))
+      (user-error "No reference definition at point")))
+  (let ((links (markdown-reference-find-links reference)))
+    (cond ((= (length links) 1)
+           (goto-char (cadr (car links))))
+          ((> (length links) 1)
+           (let ((oldbuf (current-buffer))
+                 (linkbuf (markdown-reference-links-buffer)))
+             (with-current-buffer linkbuf
+               (insert "Links using reference " reference ":\n\n")
+               (dolist (link (reverse links))
+                 (markdown-insert-link-button link oldbuf)))
+             (view-buffer-other-window linkbuf)
+             (goto-char (point-min))
+             (forward-line 2)))
+          (t
+           (error "No links for reference %s" reference)))))
+
+(defmacro defun-markdown-ref-checker
+    (name docstring checker-function buffer-function none-message buffer-header insert-reference)
+  "Define a function NAME acting on result of CHECKER-FUNCTION.
+
+DOCSTRING is used as a docstring for the defined function.
+
+BUFFER-FUNCTION should name and return an auxiliary buffer to put
+results in.
+
+NONE-MESSAGE is used when CHECKER-FUNCTION returns no results.
+
+BUFFER-HEADER is put into the auxiliary buffer first, followed by
+calling INSERT-REFERENCE for each element in the list returned by
+CHECKER-FUNCTION."
+  `(defun ,name (&optional silent)
+     ,(concat
+       docstring
+       "\n\nIf SILENT is non-nil, do not message anything when no
+such references found.")
+     (interactive "P")
+     (when (not (memq major-mode '(markdown-mode gfm-mode)))
+       (user-error "Not available in current mode"))
+     (let ((oldbuf (current-buffer))
+           (refs (,checker-function))
+           (refbuf (,buffer-function)))
+       (if (null refs)
+           (progn
+             (when (not silent)
+               (message ,none-message))
+             (kill-buffer refbuf))
+         (with-current-buffer refbuf
+           (insert ,buffer-header)
+           (dolist (ref refs)
+             (,insert-reference ref oldbuf))
+           (view-buffer-other-window refbuf)
+           (goto-char (point-min))
+           (forward-line 2))))))
+
+(defun-markdown-ref-checker
+  markdown-check-refs
+  "Show all undefined Markdown references in current `markdown-mode' buffer.
+
+Links which have empty reference definitions are considered to be
+defined."
+  markdown-get-undefined-refs
+  markdown-reference-check-buffer
+  "No undefined references found"
+  "The following references are undefined:\n\n"
+  markdown-insert-undefined-reference-button)
+
+
+(defun-markdown-ref-checker
+  markdown-unused-refs
+  "Show all unused Markdown references in current `markdown-mode' buffer."
+  markdown-get-unused-refs
+  markdown-unused-references-buffer
+  "No unused references found"
+  "The following references are unused:\n\n"
+  markdown-insert-unused-reference-button)
+
+
+
+;;; Lists =====================================================================
+
+(defun markdown-insert-list-item (&optional arg)
+  "Insert a new list item.
+If the point is inside unordered list, insert a bullet mark.  If
+the point is inside ordered list, insert the next number followed
+by a period.  Use the previous list item to determine the amount
+of whitespace to place before and after list markers.
+
+With a \\[universal-argument] prefix (i.e., when ARG is (4)),
+decrease the indentation by one level.
+
+With two \\[universal-argument] prefixes (i.e., when ARG is (16)),
+increase the indentation by one level."
+  (interactive "p")
+  (let (bounds cur-indent marker indent new-indent new-loc)
+    (save-match-data
+      ;; Look for a list item on current or previous non-blank line
+      (save-excursion
+        (while (and (not (setq bounds (markdown-cur-list-item-bounds)))
+                    (not (bobp))
+                    (markdown-cur-line-blank-p))
+          (forward-line -1)))
+      (when bounds
+        (cond ((save-excursion
+                 (skip-chars-backward " \t")
+                 (looking-at-p markdown-regex-list))
+               (beginning-of-line)
+               (insert "\n")
+               (forward-line -1))
+              ((not (markdown-cur-line-blank-p))
+               (newline)))
+        (setq new-loc (point)))
+      ;; Look ahead for a list item on next non-blank line
+      (unless bounds
+        (save-excursion
+          (while (and (null bounds)
+                      (not (eobp))
+                      (markdown-cur-line-blank-p))
+            (forward-line)
+            (setq bounds (markdown-cur-list-item-bounds))))
+        (when bounds
+          (setq new-loc (point))
+          (unless (markdown-cur-line-blank-p)
+            (newline))))
+      (if (not bounds)
+          ;; When not in a list, start a new unordered one
+          (progn
+            (unless (markdown-cur-line-blank-p)
+              (insert "\n"))
+            (insert markdown-unordered-list-item-prefix))
+        ;; Compute indentation and marker for new list item
+        (setq cur-indent (nth 2 bounds))
+        (setq marker (nth 4 bounds))
+        ;; If current item is a GFM checkbox, insert new unchecked checkbox.
+        (when (nth 5 bounds)
+          (setq marker
+                (concat marker
+                        (replace-regexp-in-string "[Xx]" " " (nth 5 bounds)))))
+        (cond
+         ;; Dedent: decrement indentation, find previous marker.
+         ((= arg 4)
+          (setq indent (max (- cur-indent 4) 0))
+          (let ((prev-bounds
+                 (save-excursion
+                   (goto-char (nth 0 bounds))
+                   (when (markdown-up-list)
+                     (markdown-cur-list-item-bounds)))))
+            (when prev-bounds
+              (setq marker (nth 4 prev-bounds)))))
+         ;; Indent: increment indentation by 4, use same marker.
+         ((= arg 16) (setq indent (+ cur-indent 4)))
+         ;; Same level: keep current indentation and marker.
+         (t (setq indent cur-indent)))
+        (setq new-indent (make-string indent 32))
+        (goto-char new-loc)
+        (cond
+         ;; Ordered list
+         ((string-match-p "[0-9]" marker)
+          (if (= arg 16) ;; starting a new column indented one more level
+              (insert (concat new-indent "1. "))
+            ;; Don't use previous match-data
+            (set-match-data nil)
+            ;; travel up to the last item and pick the correct number.  If
+            ;; the argument was nil, "new-indent = cur-indent" is the same,
+            ;; so we don't need special treatment. Neat.
+            (save-excursion
+              (while (and (not (looking-at (concat new-indent "\\([0-9]+\\)\\(\\.[ \t]*\\)")))
+                          (>= (forward-line -1) 0))))
+            (let* ((old-prefix (match-string 1))
+                   (old-spacing (match-string 2))
+                   (new-prefix (if old-prefix
+                                   (int-to-string (1+ (string-to-number old-prefix)))
+                                 "1"))
+                   (space-adjust (- (length old-prefix) (length new-prefix)))
+                   (new-spacing (if (and (match-string 2)
+                                         (not (string-match-p "\t" old-spacing))
+                                         (< space-adjust 0)
+                                         (> space-adjust (- 1 (length (match-string 2)))))
+                                    (substring (match-string 2) 0 space-adjust)
+                                  (or old-spacing ". "))))
+              (insert (concat new-indent new-prefix new-spacing)))))
+         ;; Unordered list, GFM task list, or ordered list with hash mark
+         ((string-match-p "[\\*\\+-]\\|#\\." marker)
+          (insert new-indent marker))))
+      ;; Propertize the newly inserted list item now
+      (markdown-syntax-propertize-list-items (point-at-bol) (point-at-eol)))))
+
+(defun markdown-move-list-item-up ()
+  "Move the current list item up in the list when possible.
+In nested lists, move child items with the parent item."
+  (interactive)
+  (let (cur prev old)
+    (when (setq cur (markdown-cur-list-item-bounds))
+      (setq old (point))
+      (goto-char (nth 0 cur))
+      (if (markdown-prev-list-item (nth 3 cur))
+          (progn
+            (setq prev (markdown-cur-list-item-bounds))
+            (condition-case nil
+                (progn
+                  (transpose-regions (nth 0 prev) (nth 1 prev)
+                                     (nth 0 cur) (nth 1 cur) t)
+                  (goto-char (+ (nth 0 prev) (- old (nth 0 cur)))))
+              ;; Catch error in case regions overlap.
+              (error (goto-char old))))
+        (goto-char old)))))
+
+(defun markdown-move-list-item-down ()
+  "Move the current list item down in the list when possible.
+In nested lists, move child items with the parent item."
+  (interactive)
+  (let (cur next old)
+    (when (setq cur (markdown-cur-list-item-bounds))
+      (setq old (point))
+      (if (markdown-next-list-item (nth 3 cur))
+          (progn
+            (setq next (markdown-cur-list-item-bounds))
+            (condition-case nil
+                (progn
+                  (transpose-regions (nth 0 cur) (nth 1 cur)
+                                     (nth 0 next) (nth 1 next) nil)
+                  (goto-char (+ old (- (nth 1 next) (nth 1 cur)))))
+              ;; Catch error in case regions overlap.
+              (error (goto-char old))))
+        (goto-char old)))))
+
+(defun markdown-demote-list-item (&optional bounds)
+  "Indent (or demote) the current list item.
+Optionally, BOUNDS of the current list item may be provided if available.
+In nested lists, demote child items as well."
+  (interactive)
+  (when (or bounds (setq bounds (markdown-cur-list-item-bounds)))
+    (save-excursion
+      (let* ((item-start (set-marker (make-marker) (nth 0 bounds)))
+             (item-end (set-marker (make-marker) (nth 1 bounds)))
+             (list-start (progn (markdown-beginning-of-list)
+                                (set-marker (make-marker) (point))))
+             (list-end (progn (markdown-end-of-list)
+                              (set-marker (make-marker) (point)))))
+        (goto-char item-start)
+        (while (< (point) item-end)
+          (unless (markdown-cur-line-blank-p)
+            (insert (make-string markdown-list-indent-width ? )))
+          (forward-line))
+        (markdown-syntax-propertize-list-items list-start list-end)))))
+
+(defun markdown-promote-list-item (&optional bounds)
+  "Unindent (or promote) the current list item.
+Optionally, BOUNDS of the current list item may be provided if available.
+In nested lists, demote child items as well."
+  (interactive)
+  (when (or bounds (setq bounds (markdown-cur-list-item-bounds)))
+    (save-excursion
+      (save-match-data
+        (let ((item-start (set-marker (make-marker) (nth 0 bounds)))
+              (item-end (set-marker (make-marker) (nth 1 bounds)))
+              (list-start (progn (markdown-beginning-of-list)
+                                 (set-marker (make-marker) (point))))
+              (list-end (progn (markdown-end-of-list)
+                               (set-marker (make-marker) (point))))
+              num regexp)
+          (goto-char item-start)
+          (when (looking-at (format "^[ ]\\{1,%d\\}"
+                                    markdown-list-indent-width))
+            (setq num (- (match-end 0) (match-beginning 0)))
+            (setq regexp (format "^[ ]\\{1,%d\\}" num))
+            (while (and (< (point) item-end)
+                        (re-search-forward regexp item-end t))
+              (replace-match "" nil nil)
+              (forward-line))
+            (markdown-syntax-propertize-list-items list-start list-end)))))))
+
+(defun markdown-cleanup-list-numbers-level (&optional pfx)
+  "Update the numbering for level PFX (as a string of spaces).
+
+Assume that the previously found match was for a numbered item in
+a list."
+  (let ((cpfx pfx)
+        (idx 0)
+        (continue t)
+        (step t)
+        (sep nil))
+    (while (and continue (not (eobp)))
+      (setq step t)
+      (cond
+       ((looking-at "^\\([\s-]*\\)[0-9]+\\. ")
+        (setq cpfx (match-string-no-properties 1))
+        (cond
+         ((string= cpfx pfx)
+          (save-excursion
+            (replace-match
+             (concat pfx (number-to-string (setq idx (1+ idx))) ". ")))
+          (setq sep nil))
+         ;; indented a level
+         ((string< pfx cpfx)
+          (setq sep (markdown-cleanup-list-numbers-level cpfx))
+          (setq step nil))
+         ;; exit the loop
+         (t
+          (setq step nil)
+          (setq continue nil))))
+
+       ((looking-at "^\\([\s-]*\\)[^ \t\n\r].*$")
+        (setq cpfx (match-string-no-properties 1))
+        (cond
+         ;; reset if separated before
+         ((string= cpfx pfx) (when sep (setq idx 0)))
+         ((string< cpfx pfx)
+          (setq step nil)
+          (setq continue nil))))
+       (t (setq sep t)))
+
+      (when step
+        (beginning-of-line)
+        (setq continue (= (forward-line) 0))))
+    sep))
+
+(defun markdown-cleanup-list-numbers ()
+  "Update the numbering of ordered lists."
+  (interactive)
+  (save-excursion
+    (goto-char (point-min))
+    (markdown-cleanup-list-numbers-level "")))
+
+
+;;; Movement ==================================================================
+
+(defun markdown-beginning-of-defun (&optional arg)
+  "`beginning-of-defun-function' for Markdown.
+This is used to find the beginning of the defun and should behave
+like ‘beginning-of-defun’, returning non-nil if it found the
+beginning of a defun.  It moves the point backward, right before a
+heading which defines a defun.  When ARG is non-nil, repeat that
+many times.  When ARG is negative, move forward to the ARG-th
+following section."
+  (or arg (setq arg 1))
+  (when (< arg 0) (end-of-line))
+  ;; Adjust position for setext headings.
+  (when (and (thing-at-point-looking-at markdown-regex-header-setext)
+             (not (= (point) (match-beginning 0)))
+             (not (markdown-code-block-at-point-p)))
+    (goto-char (match-end 0)))
+  (let (found)
+    ;; Move backward with positive argument.
+    (while (and (not (bobp)) (> arg 0))
+      (setq found nil)
+      (while (and (not found)
+                  (not (bobp))
+                  (re-search-backward markdown-regex-header nil 'move))
+        (when (not (markdown-code-block-at-pos (match-beginning 0))))
+        (setq found (match-beginning 0)))
+      (setq arg (1- arg)))
+    ;; Move forward with negative argument.
+    (while (and (not (eobp)) (< arg 0))
+      (setq found nil)
+      (while (and (not found)
+                  (not (eobp))
+                  (re-search-forward markdown-regex-header nil 'move))
+        (when (not (markdown-code-block-at-pos (match-beginning 0))))
+        (setq found (match-beginning 0)))
+      (setq arg (1+ arg)))
+    (when found
+      (beginning-of-line)
+      t)))
+
+(defun markdown-end-of-defun ()
+  "`end-of-defun-function’ for Markdown.
+This is used to find the end of the defun at point.
+It is called with no argument, right after calling ‘beginning-of-defun-raw’,
+so it can assume that point is at the beginning of the defun body.
+It should move point to the first position after the defun."
+  (or (eobp) (forward-char 1))
+  (let (found)
+    (while (and (not found)
+                (not (eobp))
+                (re-search-forward markdown-regex-header nil 'move))
+      (when (not (markdown-code-block-at-pos (match-beginning 0)))
+        (setq found (match-beginning 0))))
+    (when found
+      (goto-char found)
+      (skip-syntax-backward "-"))))
+
+(make-obsolete 'markdown-beginning-of-block 'markdown-beginning-of-text-block "v2.2")
+
+(defun markdown-beginning-of-text-block ()
+  "Move backward to previous beginning of a plain text block.
+This function simply looks for blank lines without considering
+the surrounding context in light of Markdown syntax.  For that, see
+`markdown-backward-block'."
+  (interactive)
+  (let ((start (point)))
+    (if (re-search-backward markdown-regex-block-separator nil t)
+        (goto-char (match-end 0))
+      (goto-char (point-min)))
+    (when (and (= start (point)) (not (bobp)))
+      (forward-line -1)
+      (if (re-search-backward markdown-regex-block-separator nil t)
+          (goto-char (match-end 0))
+        (goto-char (point-min))))))
+
+(make-obsolete 'markdown-end-of-block 'markdown-end-of-text-block "v2.2")
+
+(defun markdown-end-of-text-block ()
+  "Move forward to next beginning of a plain text block.
+This function simply looks for blank lines without considering
+the surrounding context in light of Markdown syntax.  For that, see
+`markdown-forward-block'."
+  (interactive)
+  (beginning-of-line)
+  (skip-chars-forward " \t\n")
+  (when (= (point) (point-min))
+    (forward-char))
+  (if (re-search-forward markdown-regex-block-separator nil t)
+      (goto-char (match-end 0))
+    (goto-char (point-max)))
+  (skip-chars-backward " \t\n")
+  (forward-line))
+
+(defun markdown-backward-paragraph (&optional arg)
+  "Move the point to the start of the current paragraph.
+With argument ARG, do it ARG times; a negative argument ARG = -N
+means move forward N blocks."
+  (interactive "^p")
+  (or arg (setq arg 1))
+  (if (< arg 0)
+      (markdown-forward-paragraph (- arg))
+    (dotimes (_ arg)
+      ;; Skip over whitespace in between paragraphs when moving backward.
+      (skip-chars-backward " \t\n")
+      (beginning-of-line)
+      ;; Skip over code block endings.
+      (when (markdown-range-properties-exist
+            (point-at-bol) (point-at-eol)
+            '(markdown-gfm-block-end
+              markdown-tilde-fence-end))
+        (forward-line -1))
+      ;; Skip over blank lines inside blockquotes.
+      (while (and (not (eobp))
+                  (looking-at markdown-regex-blockquote)
+                  (= (length (match-string 3)) 0))
+        (forward-line -1))
+      ;; Proceed forward based on the type of block of paragraph.
+      (let (bounds skip)
+        (cond
+         ;; Blockquotes
+         ((looking-at markdown-regex-blockquote)
+          (while (and (not (bobp))
+                      (looking-at markdown-regex-blockquote)
+                      (> (length (match-string 3)) 0)) ;; not blank
+            (forward-line -1))
+          (forward-line))
+         ;; List items
+         ((setq bounds (markdown-cur-list-item-bounds))
+          (goto-char (nth 0 bounds)))
+         ;; Other
+         (t
+          (while (and (not (bobp))
+                      (not skip)
+                      (not (markdown-cur-line-blank-p))
+                      (not (looking-at markdown-regex-blockquote))
+                      (not (markdown-range-properties-exist
+                            (point-at-bol) (point-at-eol)
+                            '(markdown-gfm-block-end
+                              markdown-tilde-fence-end))))
+            (setq skip (markdown-range-properties-exist
+                            (point-at-bol) (point-at-eol)
+                            '(markdown-gfm-block-begin
+                              markdown-tilde-fence-begin)))
+            (forward-line -1))
+          (unless (bobp)
+            (forward-line 1))))))))
+
+(defun markdown-forward-paragraph (&optional arg)
+  "Move forward to the next end of a paragraph.
+With argument ARG, do it ARG times; a negative argument ARG = -N
+means move backward N blocks."
+  (interactive "^p")
+  (or arg (setq arg 1))
+  (if (< arg 0)
+      (markdown-backward-paragraph (- arg))
+    (dotimes (_ arg)
+      ;; Skip whitespace in between paragraphs.
+      (when (markdown-cur-line-blank-p)
+        (skip-syntax-forward "-")
+        (beginning-of-line))
+      ;; Proceed forward based on the type of block.
+      (let (bounds skip)
+        (cond
+         ;; Blockquotes
+         ((looking-at markdown-regex-blockquote)
+          ;; Skip over blank lines inside blockquotes.
+          (while (and (not (eobp))
+                      (looking-at markdown-regex-blockquote)
+                      (= (length (match-string 3)) 0))
+            (forward-line))
+          ;; Move to end of quoted text block
+          (while (and (not (eobp))
+                      (looking-at markdown-regex-blockquote)
+                      (> (length (match-string 3)) 0)) ;; not blank
+            (forward-line)))
+         ;; List items
+         ((and (markdown-cur-list-item-bounds)
+               (setq bounds (markdown-next-list-item-bounds)))
+          (goto-char (nth 0 bounds)))
+         ;; Other
+         (t
+          (forward-line)
+          (while (and (not (eobp))
+                      (not skip)
+                      (not (markdown-cur-line-blank-p))
+                      (not (looking-at markdown-regex-blockquote))
+                      (not (markdown-range-properties-exist
+                            (point-at-bol) (point-at-eol)
+                            '(markdown-gfm-block-begin
+                              markdown-tilde-fence-begin))))
+            (setq skip (markdown-range-properties-exist
+                        (point-at-bol) (point-at-eol)
+                        '(markdown-gfm-block-end
+                          markdown-tilde-fence-end)))
+            (forward-line))))))))
+
+(defun markdown-backward-block (&optional arg)
+  "Move the point to the start of the current Markdown block.
+Moves across complete code blocks, list items, and blockquotes,
+but otherwise stops at blank lines, headers, and horizontal
+rules.  With argument ARG, do it ARG times; a negative argument
+ARG = -N means move forward N blocks."
+  (interactive "^p")
+  (or arg (setq arg 1))
+  (if (< arg 0)
+      (markdown-forward-block (- arg))
+    (dotimes (_ arg)
+      ;; Skip over whitespace in between blocks when moving backward,
+      ;; unless at a block boundary with no whitespace.
+      (skip-syntax-backward "-")
+      (beginning-of-line)
+      ;; Proceed forward based on the type of block.
+      (cond
+       ;; Code blocks
+       ((and (markdown-code-block-at-pos (point)) ;; this line
+             (markdown-code-block-at-pos (point-at-bol 0))) ;; previous line
+        (forward-line -1)
+        (while (and (markdown-code-block-at-point-p) (not (bobp)))
+          (forward-line -1))
+        (forward-line))
+       ;; Headings
+       ((markdown-heading-at-point)
+        (goto-char (match-beginning 0)))
+       ;; Horizontal rules
+       ((looking-at markdown-regex-hr))
+       ;; Blockquotes
+       ((looking-at markdown-regex-blockquote)
+        (forward-line -1)
+        (while (and (looking-at markdown-regex-blockquote)
+                    (not (bobp)))
+          (forward-line -1))
+        (forward-line))
+       ;; List items
+       ((markdown-cur-list-item-bounds)
+        (markdown-beginning-of-list))
+       ;; Other
+       (t
+        ;; Move forward in case it is a one line regular paragraph.
+        (unless (markdown-next-line-blank-p)
+          (forward-line))
+        (unless (markdown-prev-line-blank-p)
+          (markdown-backward-paragraph)))))))
+
+(defun markdown-forward-block (&optional arg)
+  "Move forward to the next end of a Markdown block.
+Moves across complete code blocks, list items, and blockquotes,
+but otherwise stops at blank lines, headers, and horizontal
+rules.  With argument ARG, do it ARG times; a negative argument
+ARG = -N means move backward N blocks."
+  (interactive "^p")
+  (or arg (setq arg 1))
+  (if (< arg 0)
+      (markdown-backward-block (- arg))
+    (dotimes (_ arg)
+      ;; Skip over whitespace in between blocks when moving forward.
+      (if (markdown-cur-line-blank-p)
+          (skip-syntax-forward "-")
+        (beginning-of-line))
+      ;; Proceed forward based on the type of block.
+      (cond
+       ;; Code blocks
+       ((markdown-code-block-at-point-p)
+        (forward-line)
+        (while (and (markdown-code-block-at-point-p) (not (eobp)))
+          (forward-line)))
+       ;; Headings
+       ((looking-at markdown-regex-header)
+        (goto-char (or (match-end 4) (match-end 2) (match-end 3)))
+        (forward-line))
+       ;; Horizontal rules
+       ((looking-at markdown-regex-hr)
+        (forward-line))
+       ;; Blockquotes
+       ((looking-at markdown-regex-blockquote)
+        (forward-line)
+        (while (and (looking-at markdown-regex-blockquote) (not (eobp)))
+          (forward-line)))
+       ;; List items
+       ((markdown-cur-list-item-bounds)
+        (markdown-end-of-list)
+        (forward-line))
+       ;; Other
+       (t (markdown-forward-paragraph))))
+    (skip-syntax-backward "-")
+    (unless (eobp)
+      (forward-char 1))))
+
+(defun markdown-backward-page (&optional count)
+  "Move backward to boundary of the current toplevel section.
+With COUNT, repeat, or go forward if negative."
+  (interactive "p")
+  (or count (setq count 1))
+  (if (< count 0)
+      (markdown-forward-page (- count))
+    (skip-syntax-backward "-")
+    (or (markdown-back-to-heading-over-code-block t t)
+        (goto-char (point-min)))
+    (when (looking-at markdown-regex-header)
+      (let ((level (markdown-outline-level)))
+        (when (> level 1) (markdown-up-heading level))
+        (when (> count 1)
+          (condition-case nil
+              (markdown-backward-same-level (1- count))
+            (error (goto-char (point-min)))))))))
+
+(defun markdown-forward-page (&optional count)
+  "Move forward to boundary of the current toplevel section.
+With COUNT, repeat, or go backward if negative."
+  (interactive "p")
+  (or count (setq count 1))
+  (if (< count 0)
+      (markdown-backward-page (- count))
+    (if (markdown-back-to-heading-over-code-block t t)
+        (let ((level (markdown-outline-level)))
+          (when (> level 1) (markdown-up-heading level))
+          (condition-case nil
+              (markdown-forward-same-level count)
+            (error (goto-char (point-max)))))
+      (markdown-next-visible-heading 1))))
+
+(defun markdown-next-link ()
+  "Jump to next inline, reference, or wiki link.
+If successful, return point.  Otherwise, return nil.
+See `markdown-wiki-link-p' and `markdown-previous-wiki-link'."
+  (interactive)
+  (let ((opoint (point)))
+    (when (or (markdown-link-p) (markdown-wiki-link-p))
+      ;; At a link already, move past it.
+      (goto-char (+ (match-end 0) 1)))
+    ;; Search for the next wiki link and move to the beginning.
+    (while (and (re-search-forward (markdown-make-regex-link-generic) nil t)
+                (markdown-code-block-at-point-p)
+                (< (point) (point-max))))
+    (if (and (not (eq (point) opoint))
+             (or (markdown-link-p) (markdown-wiki-link-p)))
+        ;; Group 1 will move past non-escape character in wiki link regexp.
+        ;; Go to beginning of group zero for all other link types.
+        (goto-char (or (match-beginning 1) (match-beginning 0)))
+      (goto-char opoint)
+      nil)))
+
+(defun markdown-previous-link ()
+  "Jump to previous wiki link.
+If successful, return point.  Otherwise, return nil.
+See `markdown-wiki-link-p' and `markdown-next-wiki-link'."
+  (interactive)
+  (let ((opoint (point)))
+    (while (and (re-search-backward (markdown-make-regex-link-generic) nil t)
+                (markdown-code-block-at-point-p)
+                (> (point) (point-min))))
+    (if (and (not (eq (point) opoint))
+             (or (markdown-link-p) (markdown-wiki-link-p)))
+        (goto-char (or (match-beginning 1) (match-beginning 0)))
+      (goto-char opoint)
+      nil)))
+
+
+;;; Outline ===================================================================
+
+(defun markdown-move-heading-common (move-fn &optional arg adjust)
+  "Wrapper for `outline-mode' functions to skip false positives.
+MOVE-FN is a function and ARG is its argument. For example,
+headings inside preformatted code blocks may match
+`outline-regexp' but should not be considered as headings.
+When ADJUST is non-nil, adjust the point for interactive calls
+to avoid leaving the point at invisible markup.  This adjustment
+generally should only be done for interactive calls, since other
+functions may expect the point to be at the beginning of the
+regular expression."
+  (let ((prev -1) (start (point)))
+    (if arg (funcall move-fn arg) (funcall move-fn))
+    (while (and (/= prev (point)) (markdown-code-block-at-point-p))
+      (setq prev (point))
+      (if arg (funcall move-fn arg) (funcall move-fn)))
+    ;; Adjust point for setext headings and invisible text.
+    (save-match-data
+      (when (and adjust (thing-at-point-looking-at markdown-regex-header))
+        (if markdown-hide-markup
+            ;; Move to beginning of heading text if markup is hidden.
+            (goto-char (or (match-beginning 1) (match-beginning 5)))
+          ;; Move to beginning of markup otherwise.
+          (goto-char (or (match-beginning 1) (match-beginning 4))))))
+    (if (= (point) start) nil (point))))
+
+(defun markdown-next-visible-heading (arg)
+  "Move to the next visible heading line of any level.
+With argument, repeats or can move backward if negative. ARG is
+passed to `outline-next-visible-heading'."
+  (interactive "p")
+  (markdown-move-heading-common #'outline-next-visible-heading arg 'adjust))
+
+(defun markdown-previous-visible-heading (arg)
+  "Move to the previous visible heading line of any level.
+With argument, repeats or can move backward if negative. ARG is
+passed to `outline-previous-visible-heading'."
+  (interactive "p")
+  (markdown-move-heading-common #'outline-previous-visible-heading arg 'adjust))
+
+(defun markdown-next-heading ()
+  "Move to the next heading line of any level."
+  (markdown-move-heading-common #'outline-next-heading))
+
+(defun markdown-previous-heading ()
+  "Move to the previous heading line of any level."
+  (markdown-move-heading-common #'outline-previous-heading))
+
+(defun markdown-back-to-heading-over-code-block (&optional invisible-ok no-error)
+  "Move back to the beginning of the previous heading.
+Returns t if the point is at a heading, the location if a heading
+was found, and nil otherwise.
+Only visible heading lines are considered, unless INVISIBLE-OK is
+non-nil.  Throw an error if there is no previous heading unless
+NO-ERROR is non-nil.
+Leaves match data intact for `markdown-regex-header'."
+  (beginning-of-line)
+  (or (and (markdown-heading-at-point)
+           (not (markdown-code-block-at-point-p)))
+      (let (found)
+        (save-excursion
+          (while (and (not found)
+                      (re-search-backward markdown-regex-header nil t))
+            (when (and (or invisible-ok (not (outline-invisible-p)))
+                       (not (markdown-code-block-at-point-p)))
+              (setq found (point))))
+          (if (not found)
+              (unless no-error (user-error "Before first heading"))
+            (setq found (point))))
+        (when found (goto-char found)))))
+
+(defun markdown-forward-same-level (arg)
+  "Move forward to the ARG'th heading at same level as this one.
+Stop at the first and last headings of a superior heading."
+  (interactive "p")
+  (markdown-back-to-heading-over-code-block)
+  (markdown-move-heading-common #'outline-forward-same-level arg 'adjust))
+
+(defun markdown-backward-same-level (arg)
+  "Move backward to the ARG'th heading at same level as this one.
+Stop at the first and last headings of a superior heading."
+  (interactive "p")
+  (markdown-back-to-heading-over-code-block)
+  (while (> arg 0)
+    (let ((point-to-move-to
+           (save-excursion
+             (markdown-move-heading-common #'outline-get-last-sibling nil 'adjust))))
+      (if point-to-move-to
+          (progn
+            (goto-char point-to-move-to)
+            (setq arg (1- arg)))
+        (user-error "No previous same-level heading")))))
+
+(defun markdown-up-heading (arg)
+  "Move to the visible heading line of which the present line is a subheading.
+With argument, move up ARG levels."
+  (interactive "p")
+  (and (called-interactively-p 'any)
+       (not (eq last-command 'markdown-up-heading)) (push-mark))
+  (markdown-move-heading-common #'outline-up-heading arg 'adjust))
+
+(defun markdown-back-to-heading (&optional invisible-ok)
+  "Move to previous heading line, or beg of this line if it's a heading.
+Only visible heading lines are considered, unless INVISIBLE-OK is non-nil."
+  (markdown-move-heading-common #'outline-back-to-heading invisible-ok))
+
+(defalias 'markdown-end-of-heading 'outline-end-of-heading)
+
+(defun markdown-on-heading-p ()
+  "Return non-nil if point is on a heading line."
+  (get-text-property (point-at-bol) 'markdown-heading))
+
+(defun markdown-end-of-subtree (&optional invisible-OK)
+  "Move to the end of the current subtree.
+Only visible heading lines are considered, unless INVISIBLE-OK is
+non-nil.
+Derived from `org-end-of-subtree'."
+  (markdown-back-to-heading invisible-OK)
+  (let ((first t)
+        (level (markdown-outline-level)))
+    (while (and (not (eobp))
+                (or first (> (markdown-outline-level) level)))
+      (setq first nil)
+      (markdown-next-heading))
+    (if (memq (preceding-char) '(?\n ?\^M))
+        (progn
+          ;; Go to end of line before heading
+          (forward-char -1)
+          (if (memq (preceding-char) '(?\n ?\^M))
+              ;; leave blank line before heading
+              (forward-char -1)))))
+  (point))
+
+(defun markdown-outline-fix-visibility ()
+  "Hide any false positive headings that should not be shown.
+For example, headings inside preformatted code blocks may match
+`outline-regexp' but should not be shown as headings when cycling.
+Also, the ending --- line in metadata blocks appears to be a
+setext header, but should not be folded."
+  (save-excursion
+    (goto-char (point-min))
+    ;; Unhide any false positives in metadata blocks
+    (when (markdown-text-property-at-point 'markdown-yaml-metadata-begin)
+      (let ((body (progn (forward-line)
+                         (markdown-text-property-at-point
+                          'markdown-yaml-metadata-section))))
+        (when body
+          (let ((end (progn (goto-char (cl-second body))
+                            (markdown-text-property-at-point
+                             'markdown-yaml-metadata-end))))
+            (outline-flag-region (point-min) (1+ (cl-second end)) nil)))))
+    ;; Hide any false positives in code blocks
+    (unless (outline-on-heading-p)
+      (outline-next-visible-heading 1))
+    (while (< (point) (point-max))
+      (when (markdown-code-block-at-point-p)
+        (outline-flag-region (1- (point-at-bol)) (point-at-eol) t))
+      (outline-next-visible-heading 1))))
+
+(defvar markdown-cycle-global-status 1)
+(defvar markdown-cycle-subtree-status nil)
+
+(defun markdown-next-preface ()
+  (let (finish)
+    (while (and (not finish) (re-search-forward (concat "\n\\(?:" outline-regexp "\\)")
+                                                nil 'move))
+      (unless (markdown-code-block-at-point-p)
+        (goto-char (match-beginning 0))
+        (setq finish t))))
+  (when (and (bolp) (or outline-blank-line (eobp)) (not (bobp)))
+    (forward-char -1)))
+
+(defun markdown-show-entry ()
+  (save-excursion
+    (outline-back-to-heading t)
+    (outline-flag-region (1- (point))
+                         (progn
+                           (markdown-next-preface)
+                           (if (= 1 (- (point-max) (point)))
+                               (point-max)
+                             (point)))
+                         nil)))
+
+;; This function was originally derived from `org-cycle' from org.el.
+(defun markdown-cycle (&optional arg)
+  "Visibility cycling for Markdown mode.
+If ARG is t, perform global visibility cycling.  If the point is
+at an atx-style header, cycle visibility of the corresponding
+subtree.  Otherwise, indent the current line or insert a tab,
+as appropriate, by calling `indent-for-tab-command'."
+  (interactive "P")
+  (cond
+
+   ;; Global cycling
+   ((eq arg t)
+    (cond
+     ;; Move from overview to contents
+     ((and (eq last-command this-command)
+           (eq markdown-cycle-global-status 2))
+      (markdown-hide-sublevels 1)
+      (message "CONTENTS")
+      (setq markdown-cycle-global-status 3)
+      (markdown-outline-fix-visibility))
+     ;; Move from contents to all
+     ((and (eq last-command this-command)
+           (eq markdown-cycle-global-status 3))
+      (markdown-show-all)
+      (message "SHOW ALL")
+      (setq markdown-cycle-global-status 1))
+     ;; Defaults to overview
+     (t
+      (markdown-hide-body)
+      (message "OVERVIEW")
+      (setq markdown-cycle-global-status 2)
+      (markdown-outline-fix-visibility))))
+
+   ;; At a heading: rotate between three different views
+   ((save-excursion (beginning-of-line 1) (markdown-on-heading-p))
+    (markdown-back-to-heading)
+    (let ((goal-column 0) eoh eol eos)
+      ;; Determine boundaries
+      (save-excursion
+        (markdown-back-to-heading)
+        (save-excursion
+          (beginning-of-line 2)
+          (while (and (not (eobp)) ;; this is like `next-line'
+                      (get-char-property (1- (point)) 'invisible))
+            (beginning-of-line 2)) (setq eol (point)))
+        (markdown-end-of-heading)   (setq eoh (point))
+        (markdown-end-of-subtree t)
+        (skip-chars-forward " \t\n")
+        (beginning-of-line 1) ; in case this is an item
+        (setq eos (1- (point))))
+      ;; Find out what to do next and set `this-command'
+      (cond
+       ;; Nothing is hidden behind this heading
+       ((= eos eoh)
+        (message "EMPTY ENTRY")
+        (setq markdown-cycle-subtree-status nil))
+       ;; Entire subtree is hidden in one line: open it
+       ((>= eol eos)
+        (markdown-show-entry)
+        (markdown-show-children)
+        (message "CHILDREN")
+        (setq markdown-cycle-subtree-status 'children))
+       ;; We just showed the children, now show everything.
+       ((and (eq last-command this-command)
+             (eq markdown-cycle-subtree-status 'children))
+        (markdown-show-subtree)
+        (message "SUBTREE")
+        (setq markdown-cycle-subtree-status 'subtree))
+       ;; Default action: hide the subtree.
+       (t
+        (markdown-hide-subtree)
+        (message "FOLDED")
+        (setq markdown-cycle-subtree-status 'folded)))))
+
+   ;; In a table, move forward by one cell
+   ((markdown-table-at-point-p)
+    (call-interactively #'markdown-table-forward-cell))
+
+   ;; Otherwise, indent as appropriate
+   (t
+    (indent-for-tab-command))))
+
+(defun markdown-shifttab ()
+  "Handle S-TAB keybinding based on context.
+When in a table, move backward one cell.
+Otherwise, cycle global heading visibility by calling
+`markdown-cycle' with argument t."
+  (interactive)
+  (cond ((markdown-table-at-point-p)
+         (call-interactively #'markdown-table-backward-cell))
+        (t (markdown-cycle t))))
+
+(defun markdown-outline-level ()
+  "Return the depth to which a statement is nested in the outline."
+  (cond
+   ((and (match-beginning 0)
+         (markdown-code-block-at-pos (match-beginning 0)))
+    7) ;; Only 6 header levels are defined.
+   ((match-end 2) 1)
+   ((match-end 3) 2)
+   ((match-end 4)
+    (length (markdown-trim-whitespace (match-string-no-properties 4))))))
+
+(defun markdown-promote-subtree (&optional arg)
+  "Promote the current subtree of ATX headings.
+Note that Markdown does not support heading levels higher than
+six and therefore level-six headings will not be promoted
+further. If ARG is non-nil promote the heading, otherwise
+demote."
+  (interactive "*P")
+  (save-excursion
+    (when (and (or (thing-at-point-looking-at markdown-regex-header-atx)
+                   (re-search-backward markdown-regex-header-atx nil t))
+               (not (markdown-code-block-at-point-p)))
+      (let ((level (length (match-string 1)))
+            (promote-or-demote (if arg 1 -1))
+            (remove 't))
+        (markdown-cycle-atx promote-or-demote remove)
+        (catch 'end-of-subtree
+          (while (and (markdown-next-heading)
+                      (looking-at markdown-regex-header-atx))
+            ;; Exit if this not a higher level heading; promote otherwise.
+            (if (and (looking-at markdown-regex-header-atx)
+                     (<= (length (match-string-no-properties 1)) level))
+                (throw 'end-of-subtree nil)
+              (markdown-cycle-atx promote-or-demote remove))))))))
+
+(defun markdown-demote-subtree ()
+  "Demote the current subtree of ATX headings."
+  (interactive)
+  (markdown-promote-subtree t))
+
+(defun markdown-move-subtree-up ()
+  "Move the current subtree of ATX headings up."
+  (interactive)
+  (outline-move-subtree-up 1))
+
+(defun markdown-move-subtree-down ()
+  "Move the current subtree of ATX headings down."
+  (interactive)
+  (outline-move-subtree-down 1))
+
+(defun markdown-outline-next ()
+  "Move to next list item, when in a list, or next visible heading."
+  (interactive)
+  (let ((bounds (markdown-next-list-item-bounds)))
+    (if bounds
+        (goto-char (nth 0 bounds))
+      (markdown-next-visible-heading 1))))
+
+(defun markdown-outline-previous ()
+  "Move to previous list item, when in a list, or previous visible heading."
+  (interactive)
+  (let ((bounds (markdown-prev-list-item-bounds)))
+    (if bounds
+        (goto-char (nth 0 bounds))
+      (markdown-previous-visible-heading 1))))
+
+(defun markdown-outline-next-same-level ()
+  "Move to next list item or heading of same level."
+  (interactive)
+  (let ((bounds (markdown-cur-list-item-bounds)))
+    (if bounds
+        (markdown-next-list-item (nth 3 bounds))
+      (markdown-forward-same-level 1))))
+
+(defun markdown-outline-previous-same-level ()
+  "Move to previous list item or heading of same level."
+  (interactive)
+  (let ((bounds (markdown-cur-list-item-bounds)))
+    (if bounds
+        (markdown-prev-list-item (nth 3 bounds))
+      (markdown-backward-same-level 1))))
+
+(defun markdown-outline-up ()
+  "Move to previous list item, when in a list, or next heading."
+  (interactive)
+  (unless (markdown-up-list)
+    (markdown-up-heading 1)))
+
+
+;;; Marking and Narrowing =====================================================
+
+(defun markdown-mark-paragraph ()
+  "Put mark at end of this block, point at beginning.
+The block marked is the one that contains point or follows point.
+
+Interactively, if this command is repeated or (in Transient Mark
+mode) if the mark is active, it marks the next block after the
+ones already marked."
+  (interactive)
+  (if (or (and (eq last-command this-command) (mark t))
+          (and transient-mark-mode mark-active))
+      (set-mark
+       (save-excursion
+         (goto-char (mark))
+         (markdown-forward-paragraph)
+         (point)))
+    (let ((beginning-of-defun-function 'markdown-backward-paragraph)
+          (end-of-defun-function 'markdown-forward-paragraph))
+      (mark-defun))))
+
+(defun markdown-mark-block ()
+  "Put mark at end of this block, point at beginning.
+The block marked is the one that contains point or follows point.
+
+Interactively, if this command is repeated or (in Transient Mark
+mode) if the mark is active, it marks the next block after the
+ones already marked."
+  (interactive)
+  (if (or (and (eq last-command this-command) (mark t))
+          (and transient-mark-mode mark-active))
+      (set-mark
+       (save-excursion
+         (goto-char (mark))
+         (markdown-forward-block)
+         (point)))
+    (let ((beginning-of-defun-function 'markdown-backward-block)
+          (end-of-defun-function 'markdown-forward-block))
+      (mark-defun))))
+
+(defun markdown-narrow-to-block ()
+  "Make text outside current block invisible.
+The current block is the one that contains point or follows point."
+  (interactive)
+  (let ((beginning-of-defun-function 'markdown-backward-block)
+        (end-of-defun-function 'markdown-forward-block))
+    (narrow-to-defun)))
+
+(defun markdown-mark-text-block ()
+  "Put mark at end of this plain text block, point at beginning.
+The block marked is the one that contains point or follows point.
+
+Interactively, if this command is repeated or (in Transient Mark
+mode) if the mark is active, it marks the next block after the
+ones already marked."
+  (interactive)
+  (if (or (and (eq last-command this-command) (mark t))
+          (and transient-mark-mode mark-active))
+      (set-mark
+       (save-excursion
+         (goto-char (mark))
+         (markdown-end-of-text-block)
+         (point)))
+    (let ((beginning-of-defun-function 'markdown-beginning-of-text-block)
+          (end-of-defun-function 'markdown-end-of-text-block))
+      (mark-defun))))
+
+(defun markdown-mark-page ()
+  "Put mark at end of this top level section, point at beginning.
+The top level section marked is the one that contains point or
+follows point.
+
+Interactively, if this command is repeated or (in Transient Mark
+mode) if the mark is active, it marks the next page after the
+ones already marked."
+  (interactive)
+  (if (or (and (eq last-command this-command) (mark t))
+          (and transient-mark-mode mark-active))
+      (set-mark
+       (save-excursion
+         (goto-char (mark))
+         (markdown-forward-page)
+         (point)))
+    (let ((beginning-of-defun-function 'markdown-backward-page)
+          (end-of-defun-function 'markdown-forward-page))
+      (mark-defun))))
+
+(defun markdown-narrow-to-page ()
+  "Make text outside current top level section invisible.
+The current section is the one that contains point or follows point."
+  (interactive)
+  (let ((beginning-of-defun-function 'markdown-backward-page)
+        (end-of-defun-function 'markdown-forward-page))
+    (narrow-to-defun)))
+
+(defun markdown-mark-subtree ()
+  "Mark the current subtree.
+This puts point at the start of the current subtree, and mark at the end."
+  (interactive)
+  (let ((beg))
+    (if (markdown-heading-at-point)
+        (beginning-of-line)
+      (markdown-previous-visible-heading 1))
+    (setq beg (point))
+    (markdown-end-of-subtree)
+    (push-mark (point) nil t)
+    (goto-char beg)))
+
+(defun markdown-narrow-to-subtree ()
+  "Narrow buffer to the current subtree."
+  (interactive)
+  (save-excursion
+    (save-match-data
+      (narrow-to-region
+       (progn (markdown-back-to-heading-over-code-block t) (point))
+       (progn (markdown-end-of-subtree)
+          (if (and (markdown-heading-at-point) (not (eobp)))
+          (backward-char 1))
+          (point))))))
+
+
+;;; Generic Structure Editing, Completion, and Cycling Commands ===============
+
+(defun markdown-move-up ()
+  "Move thing at point up.
+When in a list item, call `markdown-move-list-item-up'.
+When in a table, call `markdown-table-move-row-up'.
+Otherwise, move the current heading subtree up with
+`markdown-move-subtree-up'."
+  (interactive)
+  (cond
+   ((markdown-list-item-at-point-p)
+    (call-interactively #'markdown-move-list-item-up))
+   ((markdown-table-at-point-p)
+    (call-interactively #'markdown-table-move-row-up))
+   (t
+    (call-interactively #'markdown-move-subtree-up))))
+
+(defun markdown-move-down ()
+  "Move thing at point down.
+When in a list item, call `markdown-move-list-item-down'.
+Otherwise, move the current heading subtree up with
+`markdown-move-subtree-down'."
+  (interactive)
+  (cond
+   ((markdown-list-item-at-point-p)
+    (call-interactively #'markdown-move-list-item-down))
+   ((markdown-table-at-point-p)
+    (call-interactively #'markdown-table-move-row-down))
+   (t
+    (call-interactively #'markdown-move-subtree-down))))
+
+(defun markdown-promote ()
+  "Promote or move element at point to the left.
+Depending on the context, this function will promote a heading or
+list item at the point, move a table column to the left, or cycle
+markup."
+  (interactive)
+  (let (bounds)
+    (cond
+     ;; Promote atx heading subtree
+     ((thing-at-point-looking-at markdown-regex-header-atx)
+      (markdown-promote-subtree))
+     ;; Promote setext heading
+     ((thing-at-point-looking-at markdown-regex-header-setext)
+      (markdown-cycle-setext -1))
+     ;; Promote horizonal rule
+     ((thing-at-point-looking-at markdown-regex-hr)
+      (markdown-cycle-hr -1))
+     ;; Promote list item
+     ((setq bounds (markdown-cur-list-item-bounds))
+      (markdown-promote-list-item bounds))
+     ;; Move table column to the left
+     ((markdown-table-at-point-p)
+      (call-interactively #'markdown-table-move-column-left))
+     ;; Promote bold
+     ((thing-at-point-looking-at markdown-regex-bold)
+      (markdown-cycle-bold))
+     ;; Promote italic
+     ((thing-at-point-looking-at markdown-regex-italic)
+      (markdown-cycle-italic))
+     (t
+      (user-error "Nothing to promote at point")))))
+
+(defun markdown-demote ()
+  "Demote or move element at point to the right.
+Depending on the context, this function will demote a heading or
+list item at the point, move a table column to the right, or cycle
+or remove markup."
+  (interactive)
+  (let (bounds)
+    (cond
+     ;; Demote atx heading subtree
+     ((thing-at-point-looking-at markdown-regex-header-atx)
+      (markdown-demote-subtree))
+     ;; Demote setext heading
+     ((thing-at-point-looking-at markdown-regex-header-setext)
+      (markdown-cycle-setext 1))
+     ;; Demote horizonal rule
+     ((thing-at-point-looking-at markdown-regex-hr)
+      (markdown-cycle-hr 1))
+     ;; Demote list item
+     ((setq bounds (markdown-cur-list-item-bounds))
+      (markdown-demote-list-item bounds))
+     ;; Move table column to the right
+     ((markdown-table-at-point-p)
+      (call-interactively #'markdown-table-move-column-right))
+     ;; Demote bold
+     ((thing-at-point-looking-at markdown-regex-bold)
+      (markdown-cycle-bold))
+     ;; Demote italic
+     ((thing-at-point-looking-at markdown-regex-italic)
+      (markdown-cycle-italic))
+     (t
+      (user-error "Nothing to demote at point")))))
+
+
+;;; Commands ==================================================================
+
+(defun markdown (&optional output-buffer-name)
+  "Run `markdown-command' on buffer, sending output to OUTPUT-BUFFER-NAME.
+The output buffer name defaults to `markdown-output-buffer-name'.
+Return the name of the output buffer used."
+  (interactive)
+  (save-window-excursion
+    (let ((begin-region)
+          (end-region))
+      (if (markdown-use-region-p)
+          (setq begin-region (region-beginning)
+                end-region (region-end))
+        (setq begin-region (point-min)
+              end-region (point-max)))
+
+      (unless output-buffer-name
+        (setq output-buffer-name markdown-output-buffer-name))
+      (let ((exit-code
+             (cond
+              ;; Handle case when `markdown-command' does not read from stdin
+              ((and (stringp markdown-command) markdown-command-needs-filename)
+               (if (not buffer-file-name)
+                   (user-error "Must be visiting a file")
+                 ;; Don’t use ‘shell-command’ because it’s not guaranteed to
+                 ;; return the exit code of the process.
+                 (shell-command-on-region
+                  ;; Pass an empty region so that stdin is empty.
+                  (point) (point)
+                  (concat markdown-command " "
+                          (shell-quote-argument buffer-file-name))
+                  output-buffer-name)))
+              ;; Pass region to `markdown-command' via stdin
+              (t
+               (let ((buf (get-buffer-create output-buffer-name)))
+                 (with-current-buffer buf
+                   (setq buffer-read-only nil)
+                   (erase-buffer))
+                 (if (stringp markdown-command)
+                     (call-process-region begin-region end-region
+                                          shell-file-name nil buf nil
+                                          shell-command-switch markdown-command)
+                   (funcall markdown-command begin-region end-region buf)
+                   ;; If the ‘markdown-command’ function didn’t signal an
+                   ;; error, assume it succeeded by binding ‘exit-code’ to 0.
+                   0))))))
+        ;; The exit code can be a signal description string, so don’t use ‘=’
+        ;; or ‘zerop’.
+        (unless (eq exit-code 0)
+          (user-error "%s failed with exit code %s"
+                      markdown-command exit-code))))
+    output-buffer-name))
+
+(defun markdown-standalone (&optional output-buffer-name)
+  "Special function to provide standalone HTML output.
+Insert the output in the buffer named OUTPUT-BUFFER-NAME."
+  (interactive)
+  (setq output-buffer-name (markdown output-buffer-name))
+  (with-current-buffer output-buffer-name
+    (set-buffer output-buffer-name)
+    (unless (markdown-output-standalone-p)
+      (markdown-add-xhtml-header-and-footer output-buffer-name))
+    (goto-char (point-min))
+    (html-mode))
+  output-buffer-name)
+
+(defun markdown-other-window (&optional output-buffer-name)
+  "Run `markdown-command' on current buffer and display in other window.
+When OUTPUT-BUFFER-NAME is given, insert the output in the buffer with
+that name."
+  (interactive)
+  (markdown-display-buffer-other-window
+   (markdown-standalone output-buffer-name)))
+
+(defun markdown-output-standalone-p ()
+  "Determine whether `markdown-command' output is standalone XHTML.
+Standalone XHTML output is identified by an occurrence of
+`markdown-xhtml-standalone-regexp' in the first five lines of output."
+  (save-excursion
+    (goto-char (point-min))
+    (save-match-data
+      (re-search-forward
+       markdown-xhtml-standalone-regexp
+       (save-excursion (goto-char (point-min)) (forward-line 4) (point))
+       t))))
+
+(defun markdown-stylesheet-link-string (stylesheet-path)
+  (concat "<link rel=\"stylesheet\" type=\"text/css\" media=\"all\" href=\""
+          stylesheet-path
+          "\"  />"))
+
+(defun markdown-add-xhtml-header-and-footer (title)
+  "Wrap XHTML header and footer with given TITLE around current buffer."
+  (goto-char (point-min))
+  (insert "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"
+          "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"\n"
+          "\t\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n\n"
+          "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n\n"
+          "<head>\n<title>")
+  (insert title)
+  (insert "</title>\n")
+  (when (> (length markdown-content-type) 0)
+    (insert
+     (format
+      "<meta http-equiv=\"Content-Type\" content=\"%s;charset=%s\"/>\n"
+      markdown-content-type
+      (or (and markdown-coding-system
+               (fboundp 'coding-system-get)
+               (coding-system-get markdown-coding-system
+                                  'mime-charset))
+          (and (fboundp 'coding-system-get)
+               (coding-system-get buffer-file-coding-system
+                                  'mime-charset))
+          "iso-8859-1"))))
+  (if (> (length markdown-css-paths) 0)
+      (insert (mapconcat #'markdown-stylesheet-link-string
+                         markdown-css-paths "\n")))
+  (when (> (length markdown-xhtml-header-content) 0)
+    (insert markdown-xhtml-header-content))
+  (insert "\n</head>\n\n"
+          "<body>\n\n")
+  (when (> (length markdown-xhtml-body-preamble) 0)
+    (insert markdown-xhtml-body-preamble "\n"))
+  (goto-char (point-max))
+  (when (> (length markdown-xhtml-body-epilogue) 0)
+    (insert "\n" markdown-xhtml-body-epilogue))
+  (insert "\n"
+          "</body>\n"
+          "</html>\n"))
+
+(defun markdown-preview (&optional output-buffer-name)
+  "Run `markdown-command' on the current buffer and view output in browser.
+When OUTPUT-BUFFER-NAME is given, insert the output in the buffer with
+that name."
+  (interactive)
+  (browse-url-of-buffer
+   (markdown-standalone (or output-buffer-name markdown-output-buffer-name))))
+
+(defun markdown-export-file-name (&optional extension)
+  "Attempt to generate a filename for Markdown output.
+The file extension will be EXTENSION if given, or .html by default.
+If the current buffer is visiting a file, we construct a new
+output filename based on that filename.  Otherwise, return nil."
+  (when (buffer-file-name)
+    (unless extension
+      (setq extension ".html"))
+    (let ((candidate
+           (concat
+            (cond
+             ((buffer-file-name)
+              (file-name-sans-extension (buffer-file-name)))
+             (t (buffer-name)))
+            extension)))
+      (cond
+       ((equal candidate (buffer-file-name))
+        (concat candidate extension))
+       (t
+        candidate)))))
+
+(defun markdown-export (&optional output-file)
+  "Run Markdown on the current buffer, save to file, and return the filename.
+If OUTPUT-FILE is given, use that as the filename.  Otherwise, use the filename
+generated by `markdown-export-file-name', which will be constructed using the
+current filename, but with the extension removed and replaced with .html."
+  (interactive)
+  (unless output-file
+    (setq output-file (markdown-export-file-name ".html")))
+  (when output-file
+    (let* ((init-buf (current-buffer))
+           (init-point (point))
+           (init-buf-string (buffer-string))
+           (output-buffer (find-file-noselect output-file))
+           (output-buffer-name (buffer-name output-buffer)))
+      (run-hooks 'markdown-before-export-hook)
+      (markdown-standalone output-buffer-name)
+      (with-current-buffer output-buffer
+        (run-hooks 'markdown-after-export-hook)
+        (save-buffer)
+        (when markdown-export-kill-buffer (kill-buffer)))
+      ;; if modified, restore initial buffer
+      (when (buffer-modified-p init-buf)
+        (erase-buffer)
+        (insert init-buf-string)
+        (save-buffer)
+        (goto-char init-point))
+      output-file)))
+
+(defun markdown-export-and-preview ()
+  "Export to XHTML using `markdown-export' and browse the resulting file."
+  (interactive)
+  (browse-url-of-file (markdown-export)))
+
+(defvar markdown-live-preview-buffer nil
+  "Buffer used to preview markdown output in `markdown-live-preview-export'.")
+(make-variable-buffer-local 'markdown-live-preview-buffer)
+
+(defvar markdown-live-preview-source-buffer nil
+  "Source buffer from which current buffer was generated.
+This is the inverse of `markdown-live-preview-buffer'.")
+(make-variable-buffer-local 'markdown-live-preview-source-buffer)
+
+(defvar markdown-live-preview-currently-exporting nil)
+
+(defun markdown-live-preview-get-filename ()
+  "Standardize the filename exported by `markdown-live-preview-export'."
+  (markdown-export-file-name ".html"))
+
+(defun markdown-live-preview-window-eww (file)
+  "Preview FILE with eww.
+To be used with `markdown-live-preview-window-function'."
+  (if (require 'eww nil t)
+      (progn
+        (eww-open-file file)
+        (get-buffer "*eww*"))
+    (error "EWW is not present or not loaded on this version of Emacs")))
+
+(defun markdown-visual-lines-between-points (beg end)
+  (save-excursion
+    (goto-char beg)
+    (cl-loop with count = 0
+             while (progn (end-of-visual-line)
+                          (and (< (point) end) (line-move-visual 1 t)))
+             do (cl-incf count)
+             finally return count)))
+
+(defun markdown-live-preview-window-serialize (buf)
+  "Get window point and scroll data for all windows displaying BUF."
+  (when (buffer-live-p buf)
+    (with-current-buffer buf
+      (mapcar
+       (lambda (win)
+         (with-selected-window win
+           (let* ((start (window-start))
+                  (pt (window-point))
+                  (pt-or-sym (cond ((= pt (point-min)) 'min)
+                                   ((= pt (point-max)) 'max)
+                                   (t pt)))
+                  (diff (markdown-visual-lines-between-points
+                         start pt)))
+             (list win pt-or-sym diff))))
+       (get-buffer-window-list buf)))))
+
+(defun markdown-get-point-back-lines (pt num-lines)
+  (save-excursion
+    (goto-char pt)
+    (line-move-visual (- num-lines) t)
+    ;; in testing, can occasionally overshoot the number of lines to traverse
+    (let ((actual-num-lines (markdown-visual-lines-between-points (point) pt)))
+      (when (> actual-num-lines num-lines)
+        (line-move-visual (- actual-num-lines num-lines) t)))
+    (point)))
+
+(defun markdown-live-preview-window-deserialize (window-posns)
+  "Apply window point and scroll data from WINDOW-POSNS.
+WINDOW-POSNS is provided by `markdown-live-preview-window-serialize'."
+  (cl-destructuring-bind (win pt-or-sym diff) window-posns
+    (when (window-live-p win)
+      (with-current-buffer markdown-live-preview-buffer
+        (set-window-buffer win (current-buffer))
+        (cl-destructuring-bind (actual-pt actual-diff)
+            (cl-case pt-or-sym
+              (min (list (point-min) 0))
+              (max (list (point-max) diff))
+              (t   (list pt-or-sym diff)))
+          (set-window-start
+           win (markdown-get-point-back-lines actual-pt actual-diff))
+          (set-window-point win actual-pt))))))
+
+(defun markdown-live-preview-export ()
+  "Export to XHTML using `markdown-export'.
+Browse the resulting file within Emacs using
+`markdown-live-preview-window-function' Return the buffer
+displaying the rendered output."
+  (interactive)
+  (let ((filename (markdown-live-preview-get-filename)))
+    (when filename
+      (let* ((markdown-live-preview-currently-exporting t)
+             (cur-buf (current-buffer))
+             (export-file (markdown-export filename))
+             ;; get positions in all windows currently displaying output buffer
+             (window-data
+              (markdown-live-preview-window-serialize
+               markdown-live-preview-buffer)))
+        (save-window-excursion
+          (let ((output-buffer
+                 (funcall markdown-live-preview-window-function export-file)))
+            (with-current-buffer output-buffer
+              (setq markdown-live-preview-source-buffer cur-buf)
+              (add-hook 'kill-buffer-hook
+                        #'markdown-live-preview-remove-on-kill t t))
+            (with-current-buffer cur-buf
+              (setq markdown-live-preview-buffer output-buffer))))
+        (with-current-buffer cur-buf
+          ;; reset all windows displaying output buffer to where they were,
+          ;; now with the new output
+          (mapc #'markdown-live-preview-window-deserialize window-data)
+          ;; delete html editing buffer
+          (let ((buf (get-file-buffer export-file))) (when buf (kill-buffer buf)))
+          (when (and export-file (file-exists-p export-file)
+                     (eq markdown-live-preview-delete-export
+                         'delete-on-export))
+            (delete-file export-file))
+          markdown-live-preview-buffer)))))
+
+(defun markdown-live-preview-remove ()
+  (when (buffer-live-p markdown-live-preview-buffer)
+    (kill-buffer markdown-live-preview-buffer))
+  (setq markdown-live-preview-buffer nil)
+  ;; if set to 'delete-on-export, the output has already been deleted
+  (when (eq markdown-live-preview-delete-export 'delete-on-destroy)
+    (let ((outfile-name (markdown-live-preview-get-filename)))
+      (when (and outfile-name (file-exists-p outfile-name))
+        (delete-file outfile-name)))))
+
+(defun markdown-get-other-window ()
+  "Find another window to display preview or output content."
+  (cond
+   ((memq markdown-split-window-direction '(vertical below))
+    (or (window-in-direction 'below) (split-window-vertically)))
+   ((memq markdown-split-window-direction '(horizontal right))
+    (or (window-in-direction 'right) (split-window-horizontally)))
+   (t (split-window-sensibly (get-buffer-window)))))
+
+(defun markdown-display-buffer-other-window (buf)
+  "Display preview or output buffer BUF in another window."
+  (let ((cur-buf (current-buffer))
+        (window (markdown-get-other-window)))
+    (set-window-buffer window buf)
+    (set-buffer cur-buf)))
+
+(defun markdown-live-preview-if-markdown ()
+  (when (and (derived-mode-p 'markdown-mode)
+             markdown-live-preview-mode)
+    (unless markdown-live-preview-currently-exporting
+      (if (buffer-live-p markdown-live-preview-buffer)
+          (markdown-live-preview-export)
+        (markdown-display-buffer-other-window
+         (markdown-live-preview-export))))))
+
+(defun markdown-live-preview-remove-on-kill ()
+  (cond ((and (derived-mode-p 'markdown-mode)
+              markdown-live-preview-mode)
+         (markdown-live-preview-remove))
+        (markdown-live-preview-source-buffer
+         (with-current-buffer markdown-live-preview-source-buffer
+           (setq markdown-live-preview-buffer nil))
+         (setq markdown-live-preview-source-buffer nil))))
+
+(defun markdown-live-preview-switch-to-output ()
+  "Switch to output buffer."
+  (interactive)
+  "Turn on `markdown-live-preview-mode' if not already on, and switch to its
+output buffer in another window."
+  (if markdown-live-preview-mode
+      (markdown-display-buffer-other-window (markdown-live-preview-export)))
+    (markdown-live-preview-mode))
+
+(defun markdown-live-preview-re-export ()
+  "Re export source buffer."
+  (interactive)
+  "If the current buffer is a buffer displaying the exported version of a
+`markdown-live-preview-mode' buffer, call `markdown-live-preview-export' and
+update this buffer's contents."
+  (when markdown-live-preview-source-buffer
+    (with-current-buffer markdown-live-preview-source-buffer
+      (markdown-live-preview-export))))
+
+(defun markdown-open ()
+  "Open file for the current buffer with `markdown-open-command'."
+  (interactive)
+  (unless markdown-open-command
+    (user-error "Variable `markdown-open-command' must be set"))
+  (if (stringp markdown-open-command)
+      (if (not buffer-file-name)
+          (user-error "Must be visiting a file")
+        (save-buffer)
+        (let ((exit-code (call-process markdown-open-command nil nil nil
+                                       buffer-file-name)))
+          ;; The exit code can be a signal description string, so don’t use ‘=’
+          ;; or ‘zerop’.
+          (unless (eq exit-code 0)
+            (user-error "%s failed with exit code %s"
+                        markdown-open-command exit-code))))
+    (funcall markdown-open-command))
+  nil)
+
+(defun markdown-kill-ring-save ()
+  "Run Markdown on file and store output in the kill ring."
+  (interactive)
+  (save-window-excursion
+    (markdown)
+    (with-current-buffer markdown-output-buffer-name
+      (kill-ring-save (point-min) (point-max)))))
+
+
+;;; Links =====================================================================
+
+(defun markdown-link-p ()
+  "Return non-nil when `point' is at a non-wiki link.
+See `markdown-wiki-link-p' for more information."
+  (let ((case-fold-search nil))
+    (and (not (markdown-wiki-link-p))
+         (not (markdown-code-block-at-point-p))
+         (or (thing-at-point-looking-at markdown-regex-link-inline)
+             (thing-at-point-looking-at markdown-regex-link-reference)
+             (thing-at-point-looking-at markdown-regex-uri)
+             (thing-at-point-looking-at markdown-regex-angle-uri)))))
+
+(make-obsolete 'markdown-link-link 'markdown-link-url "v2.3")
+
+(defun markdown-link-at-pos (pos)
+  "Return properties of link or image at position POS.
+Value is a list of elements describing the link:
+ 0. beginning position
+ 1. end position
+ 2. link text
+ 3. URL
+ 4. reference label
+ 5. title text
+ 6. bang (nil or \"!\")"
+  (save-excursion
+    (goto-char pos)
+    (let (begin end text url reference title bang)
+      (cond
+       ;; Inline or reference image or link at point.
+       ((or (thing-at-point-looking-at markdown-regex-link-inline)
+            (thing-at-point-looking-at markdown-regex-link-reference))
+        (setq bang (match-string-no-properties 1)
+              begin (match-beginning 0)
+              end (match-end 0)
+              text (match-string-no-properties 3))
+        (if (char-equal (char-after (match-beginning 5)) ?\[)
+            ;; Reference link
+            (setq reference (match-string-no-properties 6))
+          ;; Inline link
+          (setq url (match-string-no-properties 6))
+          (when (match-end 7)
+            (setq title (substring (match-string-no-properties 7) 1 -1)))))
+       ;; Angle bracket URI at point.
+       ((thing-at-point-looking-at markdown-regex-angle-uri)
+        (setq begin (match-beginning 0)
+              end (match-end 0)
+              url (match-string-no-properties 2)))
+       ;; Plain URI at point.
+       ((thing-at-point-looking-at markdown-regex-uri)
+        (setq begin (match-beginning 0)
+              end (match-end 0)
+              url (match-string-no-properties 1))))
+      (list begin end text url reference title bang))))
+
+(defun markdown-link-url ()
+  "Return the URL part of the regular (non-wiki) link at point.
+Works with both inline and reference style links, and with images.
+If point is not at a link or the link reference is not defined
+returns nil."
+  (let* ((values (markdown-link-at-pos (point)))
+         (text (nth 2 values))
+         (url (nth 3 values))
+         (ref (nth 4 values)))
+    (or url (and ref (car (markdown-reference-definition
+                           (downcase (if (string= ref "") text ref))))))))
+
+(defun markdown-follow-link-at-point ()
+  "Open the current non-wiki link.
+If the link is a complete URL, open in browser with `browse-url'.
+Otherwise, open with `find-file' after stripping anchor and/or query string.
+Translate filenames using `markdown-filename-translate-function'."
+  (interactive)
+  (if (markdown-link-p)
+      (let* ((url (markdown-link-url))
+             (struct (url-generic-parse-url url))
+             (full (url-fullness struct))
+             (file url))
+        ;; Parse URL, determine fullness, strip query string
+        (if (fboundp 'url-path-and-query)
+            (setq file (car (url-path-and-query struct)))
+          (when (and (setq file (url-filename struct))
+                     (string-match "\\?" file))
+            (setq file (substring file 0 (match-beginning 0)))))
+        ;; Open full URLs in browser, files in Emacs
+        (if full
+            (browse-url url)
+          (when (and file (> (length file) 0))
+            (find-file (funcall markdown-translate-filename-function file)))))
+    (user-error "Point is not at a Markdown link or URL")))
+
+(defun markdown-fontify-inline-links (last)
+  "Add text properties to next inline link from point to LAST."
+  (when (markdown-match-generic-links last nil)
+    (let* ((link-start (match-beginning 3))
+           (link-end (match-end 3))
+           (url-start (match-beginning 6))
+           (url-end (match-end 6))
+           (url (match-string-no-properties 6))
+           (title-start (match-beginning 7))
+           (title-end (match-end 7))
+           (title (match-string-no-properties 7))
+           ;; Markup part
+           (mp (list 'face 'markdown-markup-face
+                     'invisible 'markdown-markup
+                     'rear-nonsticky t
+                     'font-lock-multiline t))
+           ;; Link part (without face)
+           (lp (list 'keymap markdown-mode-mouse-map
+                     'mouse-face 'markdown-highlight-face
+                     'font-lock-multiline t
+                     'help-echo (if title (concat title "\n" url) url)))
+           ;; URL part
+           (up (list 'keymap markdown-mode-mouse-map
+                     'face 'markdown-url-face
+                     'invisible 'markdown-markup
+                     'mouse-face 'markdown-highlight-face
+                     'font-lock-multiline t))
+           ;; URL composition character
+           (url-char (markdown--first-displayable markdown-url-compose-char))
+           ;; Title part
+           (tp (list 'face 'markdown-link-title-face
+                     'invisible 'markdown-markup
+                     'font-lock-multiline t)))
+      (dolist (g '(1 2 4 5 8))
+        (when (match-end g)
+          (add-text-properties (match-beginning g) (match-end g) mp)))
+      ;; Preserve existing faces applied to link part (e.g., inline code)
+      (when link-start
+        (add-text-properties link-start link-end lp)
+        (add-face-text-property link-start link-end
+                                'markdown-link-face 'append))
+      (when url-start (add-text-properties url-start url-end up))
+      (when title-start (add-text-properties url-end title-end tp))
+      (when (and markdown-hide-urls url-start)
+        (compose-region url-start (or title-end url-end) url-char))
+      t)))
+
+(defun markdown-fontify-reference-links (last)
+  "Add text properties to next reference link from point to LAST."
+  (when (markdown-match-generic-links last t)
+    (let* ((link-start (match-beginning 3))
+           (link-end (match-end 3))
+           (ref-start (match-beginning 6))
+           (ref-end (match-end 6))
+           ;; Markup part
+           (mp (list 'face 'markdown-markup-face
+                     'invisible 'markdown-markup
+                     'rear-nonsticky t
+                     'font-lock-multiline t))
+           ;; Link part
+           (lp (list 'keymap markdown-mode-mouse-map
+                     'face 'markdown-link-face
+                     'mouse-face 'markdown-highlight-face
+                     'font-lock-multiline t
+                     'help-echo (lambda (_ __ pos)
+                                  (save-match-data
+                                    (save-excursion
+                                      (goto-char pos)
+                                      (or (markdown-link-url)
+                                          "Undefined reference"))))))
+           ;; URL composition character
+           (url-char (markdown--first-displayable markdown-url-compose-char))
+           ;; Reference part
+           (rp (list 'face 'markdown-reference-face
+                     'invisible 'markdown-markup
+                     'font-lock-multiline t)))
+      (dolist (g '(1 2 4 5 8))
+        (when (match-end g)
+          (add-text-properties (match-beginning g) (match-end g) mp)))
+      (when link-start (add-text-properties link-start link-end lp))
+      (when ref-start (add-text-properties ref-start ref-end rp)
+            (when (and markdown-hide-urls (> (- ref-end ref-start) 2))
+              (compose-region ref-start ref-end url-char)))
+      t)))
+
+(defun markdown-fontify-angle-uris (last)
+  "Add text properties to angle URIs from point to LAST."
+  (when (markdown-match-angle-uris last)
+    (let* ((url-start (match-beginning 2))
+           (url-end (match-end 2))
+           ;; Markup part
+           (mp (list 'face 'markdown-markup-face
+                     'invisible 'markdown-markup
+                     'rear-nonsticky t
+                     'font-lock-multiline t))
+           ;; URI part
+           (up (list 'keymap markdown-mode-mouse-map
+                     'face 'markdown-plain-url-face
+                     'mouse-face 'markdown-highlight-face
+                     'font-lock-multiline t)))
+      (dolist (g '(1 3))
+        (add-text-properties (match-beginning g) (match-end g) mp))
+      (add-text-properties url-start url-end up)
+      t)))
+
+(defun markdown-fontify-plain-uris (last)
+  "Add text properties to plain URLs from point to LAST."
+  (when (markdown-match-plain-uris last)
+    (let* ((start (match-beginning 0))
+           (end (match-end 0))
+           (props (list 'keymap markdown-mode-mouse-map
+                        'face 'markdown-plain-url-face
+                        'mouse-face 'markdown-highlight-face
+                        'rear-nonsticky t
+                        'font-lock-multiline t)))
+      (add-text-properties start end props)
+      t)))
+
+(defun markdown-toggle-url-hiding (&optional arg)
+  "Toggle the display or hiding of URLs.
+With a prefix argument ARG, enable URL hiding if ARG is positive,
+and disable it otherwise."
+  (interactive (list (or current-prefix-arg 'toggle)))
+  (setq markdown-hide-urls
+        (if (eq arg 'toggle)
+            (not markdown-hide-urls)
+          (> (prefix-numeric-value arg) 0)))
+  (if markdown-hide-urls
+      (message "markdown-mode URL hiding enabled")
+    (message "markdown-mode URL hiding disabled"))
+  (markdown-reload-extensions))
+
+
+;;; Wiki Links ================================================================
+
+(defun markdown-wiki-link-p ()
+  "Return non-nil if wiki links are enabled and `point' is at a true wiki link.
+A true wiki link name matches `markdown-regex-wiki-link' but does
+not match the current file name after conversion.  This modifies
+the data returned by `match-data'.  Note that the potential wiki
+link name must be available via `match-string'."
+  (when markdown-enable-wiki-links
+    (let ((case-fold-search nil))
+      (and (thing-at-point-looking-at markdown-regex-wiki-link)
+           (not (markdown-code-block-at-point-p))
+           (or (not buffer-file-name)
+               (not (string-equal (buffer-file-name)
+                                  (markdown-convert-wiki-link-to-filename
+                                   (markdown-wiki-link-link)))))))))
+
+(defun markdown-wiki-link-link ()
+  "Return the link part of the wiki link using current match data.
+The location of the link component depends on the value of
+`markdown-wiki-link-alias-first'."
+  (if markdown-wiki-link-alias-first
+      (or (match-string-no-properties 5) (match-string-no-properties 3))
+    (match-string-no-properties 3)))
+
+(defun markdown-wiki-link-alias ()
+  "Return the alias or text part of the wiki link using current match data.
+The location of the alias component depends on the value of
+`markdown-wiki-link-alias-first'."
+  (if markdown-wiki-link-alias-first
+      (match-string-no-properties 3)
+    (or (match-string-no-properties 5) (match-string-no-properties 3))))
+
+(defun markdown-convert-wiki-link-to-filename (name)
+  "Generate a filename from the wiki link NAME.
+Spaces in NAME are replaced with `markdown-link-space-sub-char'.
+When in `gfm-mode', follow GitHub's conventions where [[Test Test]]
+and [[test test]] both map to Test-test.ext.  Look in the current
+directory first, then in subdirectories if
+`markdown-wiki-link-search-subdirectories' is non-nil, and then
+in parent directories if
+`markdown-wiki-link-search-parent-directories' is non-nil."
+  (let* ((basename (markdown-replace-regexp-in-string
+                    "[[:space:]\n]" markdown-link-space-sub-char name))
+         (basename (if (memq major-mode '(gfm-mode gfm-view-mode))
+                       (concat (upcase (substring basename 0 1))
+                               (downcase (substring basename 1 nil)))
+                     basename))
+         directory extension default candidates dir)
+    (when buffer-file-name
+      (setq directory (file-name-directory buffer-file-name)
+            extension (file-name-extension buffer-file-name)))
+    (setq default (concat basename
+                          (when extension (concat "." extension))))
+    (cond
+     ;; Look in current directory first.
+     ((or (null buffer-file-name)
+          (file-exists-p default))
+      default)
+     ;; Possibly search in subdirectories, next.
+     ((and markdown-wiki-link-search-subdirectories
+           (setq candidates
+                 (markdown-directory-files-recursively
+                  directory (concat "^" default "$"))))
+      (car candidates))
+     ;; Possibly search in parent directories as a last resort.
+     ((and markdown-wiki-link-search-parent-directories
+           (setq dir (locate-dominating-file directory default)))
+      (concat dir default))
+     ;; If nothing is found, return default in current directory.
+     (t default))))
+
+(defun markdown-follow-wiki-link (name &optional other)
+  "Follow the wiki link NAME.
+Convert the name to a file name and call `find-file'.  Ensure that
+the new buffer remains in `markdown-mode'.  Open the link in another
+window when OTHER is non-nil."
+  (let ((filename (markdown-convert-wiki-link-to-filename name))
+        (wp (when buffer-file-name
+              (file-name-directory buffer-file-name))))
+    (if (not wp)
+        (user-error "Must be visiting a file")
+      (when other (other-window 1))
+      (let ((default-directory wp))
+        (find-file filename)))
+    (when (not (eq major-mode 'markdown-mode))
+      (markdown-mode))))
+
+(defun markdown-follow-wiki-link-at-point (&optional arg)
+  "Find Wiki Link at point.
+With prefix argument ARG, open the file in other window.
+See `markdown-wiki-link-p' and `markdown-follow-wiki-link'."
+  (interactive "P")
+  (if (markdown-wiki-link-p)
+      (markdown-follow-wiki-link (markdown-wiki-link-link) arg)
+    (user-error "Point is not at a Wiki Link")))
+
+(defun markdown-highlight-wiki-link (from to face)
+  "Highlight the wiki link in the region between FROM and TO using FACE."
+  (put-text-property from to 'font-lock-face face))
+
+(defun markdown-unfontify-region-wiki-links (from to)
+  "Remove wiki link faces from the region specified by FROM and TO."
+  (interactive "*r")
+  (let ((modified (buffer-modified-p)))
+    (remove-text-properties from to '(font-lock-face markdown-link-face))
+    (remove-text-properties from to '(font-lock-face markdown-missing-link-face))
+    ;; remove-text-properties marks the buffer modified in emacs 24.3,
+    ;; undo that if it wasn't originally marked modified
+    (set-buffer-modified-p modified)))
+
+(defun markdown-fontify-region-wiki-links (from to)
+  "Search region given by FROM and TO for wiki links and fontify them.
+If a wiki link is found check to see if the backing file exists
+and highlight accordingly."
+  (goto-char from)
+  (save-match-data
+    (while (re-search-forward markdown-regex-wiki-link to t)
+      (when (not (markdown-code-block-at-point-p))
+        (let ((highlight-beginning (match-beginning 1))
+              (highlight-end (match-end 1))
+              (file-name
+               (markdown-convert-wiki-link-to-filename
+                (markdown-wiki-link-link))))
+          (if (condition-case nil (file-exists-p file-name) (error nil))
+              (markdown-highlight-wiki-link
+               highlight-beginning highlight-end 'markdown-link-face)
+            (markdown-highlight-wiki-link
+             highlight-beginning highlight-end 'markdown-missing-link-face)))))))
+
+(defun markdown-extend-changed-region (from to)
+  "Extend region given by FROM and TO so that we can fontify all links.
+The region is extended to the first newline before and the first
+newline after."
+  ;; start looking for the first new line before 'from
+  (goto-char from)
+  (re-search-backward "\n" nil t)
+  (let ((new-from (point-min))
+        (new-to (point-max)))
+    (if (not (= (point) from))
+        (setq new-from (point)))
+    ;; do the same thing for the first new line after 'to
+    (goto-char to)
+    (re-search-forward "\n" nil t)
+    (if (not (= (point) to))
+        (setq new-to (point)))
+    (cl-values new-from new-to)))
+
+(defun markdown-check-change-for-wiki-link (from to)
+  "Check region between FROM and TO for wiki links and re-fontify as needed."
+  (interactive "*r")
+  (let* ((modified (buffer-modified-p))
+         (buffer-undo-list t)
+         (inhibit-read-only t)
+         (inhibit-point-motion-hooks t)
+         deactivate-mark
+         buffer-file-truename)
+    (unwind-protect
+        (save-excursion
+          (save-match-data
+            (save-restriction
+              ;; Extend the region to fontify so that it starts
+              ;; and ends at safe places.
+              (cl-multiple-value-bind (new-from new-to)
+                  (markdown-extend-changed-region from to)
+                (goto-char new-from)
+                ;; Only refontify when the range contains text with a
+                ;; wiki link face or if the wiki link regexp matches.
+                (when (or (markdown-range-property-any
+                           new-from new-to 'font-lock-face
+                           '(markdown-link-face markdown-missing-link-face))
+                          (re-search-forward
+                           markdown-regex-wiki-link new-to t))
+                  ;; Unfontify existing fontification (start from scratch)
+                  (markdown-unfontify-region-wiki-links new-from new-to)
+                  ;; Now do the fontification.
+                  (markdown-fontify-region-wiki-links new-from new-to))))))
+      (and (not modified)
+           (buffer-modified-p)
+           (set-buffer-modified-p nil)))))
+
+(defun markdown-check-change-for-wiki-link-after-change (from to _)
+    "Check region between FROM and TO for wiki links and re-fontify as needed.
+Designed to be used with the `after-change-functions' hook."
+  (markdown-check-change-for-wiki-link from to))
+
+(defun markdown-fontify-buffer-wiki-links ()
+  "Refontify all wiki links in the buffer."
+  (interactive)
+  (markdown-check-change-for-wiki-link (point-min) (point-max)))
+
+(defun markdown-toggle-wiki-links (&optional arg)
+  "Toggle support for wiki links.
+With a prefix argument ARG, enable wiki link support if ARG is positive,
+and disable it otherwise."
+  (interactive (list (or current-prefix-arg 'toggle)))
+  (setq markdown-enable-wiki-links
+        (if (eq arg 'toggle)
+            (not markdown-enable-wiki-links)
+          (> (prefix-numeric-value arg) 0)))
+  (if markdown-enable-wiki-links
+      (message "markdown-mode wiki link support enabled")
+    (message "markdown-mode wiki link support disabled"))
+  (markdown-reload-extensions))
+
+(defun markdown-setup-wiki-link-hooks ()
+  "Add or remove hooks for fontifying wiki links.
+These are only enabled when `markdown-wiki-link-fontify-missing' is non-nil."
+  ;; Anytime text changes make sure it gets fontified correctly
+  (if (and markdown-enable-wiki-links
+           markdown-wiki-link-fontify-missing)
+      (add-hook 'after-change-functions
+                'markdown-check-change-for-wiki-link-after-change t t)
+    (remove-hook 'after-change-functions
+                 'markdown-check-change-for-wiki-link-after-change t))
+  ;; If we left the buffer there is a really good chance we were
+  ;; creating one of the wiki link documents. Make sure we get
+  ;; refontified when we come back.
+  (if (and markdown-enable-wiki-links
+           markdown-wiki-link-fontify-missing)
+      (progn
+        (add-hook 'window-configuration-change-hook
+                  'markdown-fontify-buffer-wiki-links t t)
+        (markdown-fontify-buffer-wiki-links))
+    (remove-hook 'window-configuration-change-hook
+                 'markdown-fontify-buffer-wiki-links t)
+  (markdown-unfontify-region-wiki-links (point-min) (point-max))))
+
+
+;;; Following & Doing =========================================================
+
+(defun markdown-follow-thing-at-point (arg)
+  "Follow thing at point if possible, such as a reference link or wiki link.
+Opens inline and reference links in a browser.  Opens wiki links
+to other files in the current window, or the another window if
+ARG is non-nil.
+See `markdown-follow-link-at-point' and
+`markdown-follow-wiki-link-at-point'."
+  (interactive "P")
+  (cond ((markdown-link-p)
+         (markdown-follow-link-at-point))
+        ((markdown-wiki-link-p)
+         (markdown-follow-wiki-link-at-point arg))
+        (t
+         (user-error "Nothing to follow at point"))))
+
+(make-obsolete 'markdown-jump 'markdown-do "v2.3")
+
+(defun markdown-do ()
+  "Do something sensible based on context at point.
+Jumps between reference links and definitions; between footnote
+markers and footnote text."
+  (interactive)
+  (cond
+   ;; Footnote definition
+   ((markdown-footnote-text-positions)
+    (markdown-footnote-return))
+   ;; Footnote marker
+   ((markdown-footnote-marker-positions)
+    (markdown-footnote-goto-text))
+   ;; Reference link
+   ((thing-at-point-looking-at markdown-regex-link-reference)
+    (markdown-reference-goto-definition))
+   ;; Reference definition
+   ((thing-at-point-looking-at markdown-regex-reference-definition)
+    (markdown-reference-goto-link (match-string-no-properties 2)))
+   ;; GFM task list item
+   ((markdown-gfm-task-list-item-at-point)
+    (markdown-toggle-gfm-checkbox))
+   ;; Align table
+   ((markdown-table-at-point-p)
+    (call-interactively #'markdown-table-align))
+   ;; Otherwise
+   (t
+    (markdown-insert-gfm-checkbox))))
+
+
+;;; Miscellaneous =============================================================
+
+(defun markdown-compress-whitespace-string (str)
+  "Compress whitespace in STR and return result.
+Leading and trailing whitespace is removed.  Sequences of multiple
+spaces, tabs, and newlines are replaced with single spaces."
+  (markdown-replace-regexp-in-string "\\(^[ \t\n]+\\|[ \t\n]+$\\)" ""
+                            (markdown-replace-regexp-in-string "[ \t\n]+" " " str)))
+
+(defun markdown--substitute-command-keys (string)
+  "Like `substitute-command-keys' but, but prefers control characters.
+First pass STRING to `substitute-command-keys' and then
+substitute `C-i` for `TAB` and `C-m` for `RET`."
+  (replace-regexp-in-string
+   "\\<TAB\\>" "C-i"
+   (replace-regexp-in-string
+    "\\<RET\\>" "C-m" (substitute-command-keys string) t) t))
+
+(defun markdown-line-number-at-pos (&optional pos)
+  "Return (narrowed) buffer line number at position POS.
+If POS is nil, use current buffer location.
+This is an exact copy of `line-number-at-pos' for use in emacs21."
+  (let ((opoint (or pos (point))) start)
+    (save-excursion
+      (goto-char (point-min))
+      (setq start (point))
+      (goto-char opoint)
+      (forward-line 0)
+      (1+ (count-lines start (point))))))
+
+(defun markdown-inside-link-p ()
+  "Return t if point is within a link."
+  (save-match-data
+    (thing-at-point-looking-at (markdown-make-regex-link-generic))))
+
+(defun markdown-line-is-reference-definition-p ()
+  "Return whether the current line is a (non-footnote) reference defition."
+  (save-excursion
+    (move-beginning-of-line 1)
+    (and (looking-at-p markdown-regex-reference-definition)
+         (not (looking-at-p "[ \t]*\\[^")))))
+
+(defun markdown-adaptive-fill-function ()
+  "Return prefix for filling paragraph or nil if not determined."
+  (cond
+   ;; List item inside blockquote
+   ((looking-at "^[ \t]*>[ \t]*\\(\\(?:[0-9]+\\|#\\)\\.\\|[*+:-]\\)[ \t]+")
+    (markdown-replace-regexp-in-string
+     "[0-9\\.*+-]" " " (match-string-no-properties 0)))
+   ;; Blockquote
+   ((looking-at markdown-regex-blockquote)
+    (buffer-substring-no-properties (match-beginning 0) (match-end 2)))
+   ;; List items
+   ((looking-at markdown-regex-list)
+    (match-string-no-properties 0))
+   ;; Footnote definition
+   ((looking-at-p markdown-regex-footnote-definition)
+    "    ") ; four spaces
+   ;; No match
+   (t nil)))
+
+(defun markdown-fill-paragraph (&optional justify)
+  "Fill paragraph at or after point.
+This function is like \\[fill-paragraph], but it skips Markdown
+code blocks.  If the point is in a code block, or just before one,
+do not fill.  Otherwise, call `fill-paragraph' as usual. If
+JUSTIFY is non-nil, justify text as well.  Since this function
+handles filling itself, it always returns t so that
+`fill-paragraph' doesn't run."
+  (interactive "P")
+  (unless (or (markdown-code-block-at-point-p)
+              (save-excursion
+                (back-to-indentation)
+                (skip-syntax-forward "-")
+                (markdown-code-block-at-point-p)))
+    (fill-paragraph justify))
+  t)
+
+(make-obsolete 'markdown-fill-forward-paragraph-function
+               'markdown-fill-forward-paragraph "v2.3")
+
+(defun markdown-fill-forward-paragraph (&optional arg)
+  "Function used by `fill-paragraph' to move over ARG paragraphs.
+This is a `fill-forward-paragraph-function' for `markdown-mode'.
+It is called with a single argument specifying the number of
+paragraphs to move.  Just like `forward-paragraph', it should
+return the number of paragraphs left to move."
+  (or arg (setq arg 1))
+  (if (> arg 0)
+      ;; With positive ARG, move across ARG non-code-block paragraphs,
+      ;; one at a time.  When passing a code block, don't decrement ARG.
+      (while (and (not (eobp))
+                  (> arg 0)
+                  (= (forward-paragraph 1) 0)
+                  (or (markdown-code-block-at-pos (point-at-bol 0))
+                      (setq arg (1- arg)))))
+    ;; Move backward by one paragraph with negative ARG (always -1).
+    (let ((start (point)))
+      (setq arg (forward-paragraph arg))
+      (while (and (not (eobp))
+                  (progn (move-to-left-margin) (not (eobp)))
+                  (looking-at-p paragraph-separate))
+        (forward-line 1))
+      (cond
+       ;; Move point past whitespace following list marker.
+       ((looking-at markdown-regex-list)
+        (goto-char (match-end 0)))
+       ;; Move point past whitespace following pipe at beginning of line
+       ;; to handle Pandoc line blocks.
+       ((looking-at "^|\\s-*")
+        (goto-char (match-end 0)))
+       ;; Return point if the paragraph passed was a code block.
+       ((markdown-code-block-at-pos (point-at-bol 2))
+        (goto-char start)))))
+  arg)
+
+(defun markdown--inhibit-electric-quote ()
+  "Function added to `electric-quote-inhibit-functions'.
+Return non-nil if the quote has been inserted inside a code block
+or span."
+  (let ((pos (1- (point))))
+    (or (markdown-inline-code-at-pos pos)
+        (markdown-code-block-at-pos pos))))
+
+
+;;; Extension Framework =======================================================
+
+(defun markdown-reload-extensions ()
+  "Check settings, update font-lock keywords and hooks, and re-fontify buffer."
+  (interactive)
+  (when (member major-mode
+                '(markdown-mode markdown-view-mode gfm-mode gfm-view-mode))
+    ;; Refontify buffer
+    (if (eval-when-compile (fboundp 'font-lock-flush))
+        ;; Use font-lock-flush in Emacs >= 25.1
+        (font-lock-flush)
+      ;; Backwards compatibility for Emacs 24.3-24.5
+      (when (and font-lock-mode (fboundp 'font-lock-refresh-defaults))
+        (font-lock-refresh-defaults)))
+    ;; Add or remove hooks related to extensions
+    (markdown-setup-wiki-link-hooks)))
+
+(defun markdown-handle-local-variables ()
+  "Run in `hack-local-variables-hook' to update font lock rules.
+Checks to see if there is actually a ‘markdown-mode’ file local variable
+before regenerating font-lock rules for extensions."
+  (when (and (boundp 'file-local-variables-alist)
+             (or (assoc 'markdown-enable-wiki-links file-local-variables-alist)
+                 (assoc 'markdown-enable-math file-local-variables-alist)))
+    (when (assoc 'markdown-enable-math file-local-variables-alist)
+      (markdown-toggle-math markdown-enable-math))
+    (markdown-reload-extensions)))
+
+
+;;; Math Support ==============================================================
+
+(make-obsolete 'markdown-enable-math 'markdown-toggle-math "v2.1")
+
+(defconst markdown-mode-font-lock-keywords-math
+  (list
+   ;; Equation reference (eq:foo)
+   '("\\((eq:\\)\\([[:alnum:]:_]+\\)\\()\\)" . ((1 markdown-markup-face)
+                                                (2 markdown-reference-face)
+                                                (3 markdown-markup-face)))
+   ;; Equation reference \eqref{foo}
+   '("\\(\\\\eqref{\\)\\([[:alnum:]:_]+\\)\\(}\\)" . ((1 markdown-markup-face)
+                                                      (2 markdown-reference-face)
+                                                      (3 markdown-markup-face))))
+  "Font lock keywords to add and remove when toggling math support.")
+
+(defun markdown-toggle-math (&optional arg)
+  "Toggle support for inline and display LaTeX math expressions.
+With a prefix argument ARG, enable math mode if ARG is positive,
+and disable it otherwise.  If called from Lisp, enable the mode
+if ARG is omitted or nil."
+  (interactive (list (or current-prefix-arg 'toggle)))
+  (setq markdown-enable-math
+        (if (eq arg 'toggle)
+            (not markdown-enable-math)
+          (> (prefix-numeric-value arg) 0)))
+  (if markdown-enable-math
+      (progn
+        (font-lock-add-keywords
+         'markdown-mode markdown-mode-font-lock-keywords-math)
+        (message "markdown-mode math support enabled"))
+    (font-lock-remove-keywords
+     'markdown-mode markdown-mode-font-lock-keywords-math)
+    (message "markdown-mode math support disabled"))
+  (markdown-reload-extensions))
+
+
+;;; GFM Checkboxes ============================================================
+
+(define-button-type 'markdown-gfm-checkbox-button
+  'follow-link t
+  'face 'markdown-gfm-checkbox-face
+  'mouse-face 'markdown-highlight-face
+  'action #'markdown-toggle-gfm-checkbox-button)
+
+(defun markdown-gfm-task-list-item-at-point (&optional bounds)
+  "Return non-nil if there is a GFM task list item at the point.
+Optionally, the list item BOUNDS may be given if available, as
+returned by `markdown-cur-list-item-bounds'.  When a task list item
+is found, the return value is the same value returned by
+`markdown-cur-list-item-bounds'."
+  (unless bounds
+    (setq bounds (markdown-cur-list-item-bounds)))
+  (> (length (nth 5 bounds)) 0))
+
+(defun markdown-insert-gfm-checkbox ()
+  "Add GFM checkbox at point.
+Returns t if added.
+Returns nil if non-applicable."
+  (interactive)
+    (let ((bounds (markdown-cur-list-item-bounds)))
+      (if bounds
+          (unless (cl-sixth bounds)
+            (let ((pos (+ (cl-first bounds) (cl-fourth bounds)))
+                  (markup "[ ] "))
+              (if (< pos (point))
+                  (save-excursion
+                    (goto-char pos)
+                    (insert markup))
+                (goto-char pos)
+                (insert markup))
+              (syntax-propertize (+ (cl-second bounds) 4))
+              t))
+        (unless (save-excursion
+                  (back-to-indentation)
+                  (or (markdown-list-item-at-point-p)
+                      (markdown-heading-at-point)
+                      (markdown-in-comment-p)
+                      (markdown-code-block-at-point-p)))
+          (let ((pos (save-excursion
+                       (back-to-indentation)
+                       (point)))
+                (markup (concat (or (save-excursion
+                                      (beginning-of-line 0)
+                                      (cl-fifth (markdown-cur-list-item-bounds)))
+                                    markdown-unordered-list-item-prefix)
+                                "[ ] ")))
+            (if (< pos (point))
+                (save-excursion
+                  (goto-char pos)
+                  (insert markup))
+              (goto-char pos)
+              (insert markup))
+            (syntax-propertize (point-at-eol))
+            t)))))
+
+(defun markdown-toggle-gfm-checkbox ()
+  "Toggle GFM checkbox at point.
+Returns the resulting status as a string, either \"[x]\" or \"[ ]\".
+Returns nil if there is no task list item at the point."
+  (interactive)
+  (save-match-data
+    (save-excursion
+      (let ((bounds (markdown-cur-list-item-bounds)))
+        (when bounds
+          ;; Move to beginning of task list item
+          (goto-char (cl-first bounds))
+          ;; Advance to column of first non-whitespace after marker
+          (forward-char (cl-fourth bounds))
+          (cond ((looking-at "\\[ \\]")
+                 (replace-match
+                  (if markdown-gfm-uppercase-checkbox "[X]" "[x]")
+                  nil t)
+                 (match-string-no-properties 0))
+                ((looking-at "\\[[xX]\\]")
+                 (replace-match "[ ]" nil t)
+                 (match-string-no-properties 0))))))))
+
+(defun markdown-toggle-gfm-checkbox-button (button)
+  "Toggle GFM checkbox BUTTON on click."
+  (save-match-data
+    (save-excursion
+      (goto-char (button-start button))
+      (markdown-toggle-gfm-checkbox))))
+
+(defun markdown-make-gfm-checkboxes-buttons (start end)
+  "Make GFM checkboxes buttons in region between START and END."
+  (save-excursion
+    (goto-char start)
+    (let ((case-fold-search t))
+      (save-excursion
+        (while (re-search-forward markdown-regex-gfm-checkbox end t)
+          (make-button (match-beginning 1) (match-end 1)
+                       :type 'markdown-gfm-checkbox-button))))))
+
+;; Called when any modification is made to buffer text.
+(defun markdown-gfm-checkbox-after-change-function (beg end _)
+  "Add to `after-change-functions' to setup GFM checkboxes as buttons.
+BEG and END are the limits of scanned region."
+  (save-excursion
+    (save-match-data
+      ;; Rescan between start of line from `beg' and start of line after `end'.
+      (markdown-make-gfm-checkboxes-buttons
+       (progn (goto-char beg) (beginning-of-line) (point))
+       (progn (goto-char end) (forward-line 1) (point))))))
+
+(defun markdown-remove-gfm-checkbox-overlays ()
+  "Remove all GFM checkbox overlays in buffer."
+  (save-excursion
+    (save-restriction
+      (widen)
+      (remove-overlays nil nil 'face 'markdown-gfm-checkbox-face))))
+
+
+;;; Display inline image =================================================
+
+(defvar markdown-inline-image-overlays nil)
+(make-variable-buffer-local 'markdown-inline-image-overlays)
+
+(defun markdown-remove-inline-images ()
+  "Remove inline image overlays from image links in the buffer.
+This can be toggled with `markdown-toggle-inline-images'
+or \\[markdown-toggle-inline-images]."
+  (interactive)
+  (mapc #'delete-overlay markdown-inline-image-overlays)
+  (setq markdown-inline-image-overlays nil))
+
+(defun markdown-display-inline-images ()
+  "Add inline image overlays to image links in the buffer.
+This can be toggled with `markdown-toggle-inline-images'
+or \\[markdown-toggle-inline-images]."
+  (interactive)
+  (unless (display-images-p)
+    (error "Cannot show images"))
+  (save-excursion
+    (save-restriction
+      (widen)
+      (goto-char (point-min))
+      (while (re-search-forward markdown-regex-link-inline nil t)
+        (let ((start (match-beginning 0))
+              (imagep (match-beginning 1))
+              (end (match-end 0))
+              (file (match-string-no-properties 6)))
+          (when (and imagep
+                     (not (zerop (length file)))
+		     (file-exists-p file))
+            (let* ((abspath (if (file-name-absolute-p file)
+                                file
+                              (concat default-directory file)))
+                   (image
+                    (if (and markdown-max-image-size
+                             (image-type-available-p 'imagemagick))
+                        (create-image
+                         abspath 'imagemagick nil
+                         :max-width (car markdown-max-image-size)
+                         :max-height (cdr markdown-max-image-size))
+                      (create-image abspath))))
+              (when image
+                (let ((ov (make-overlay start end)))
+                  (overlay-put ov 'display image)
+                  (overlay-put ov 'face 'default)
+                  (push ov markdown-inline-image-overlays))))))))))
+
+(defun markdown-toggle-inline-images ()
+  "Toggle inline image overlays in the buffer."
+  (interactive)
+  (if markdown-inline-image-overlays
+      (markdown-remove-inline-images)
+    (markdown-display-inline-images)))
+
+
+;;; GFM Code Block Fontification ==============================================
+
+(defcustom markdown-fontify-code-blocks-natively nil
+  "When non-nil, fontify code in code blocks using the native major mode.
+This only works for fenced code blocks where the language is
+specified where we can automatically determine the appropriate
+mode to use.  The language to mode mapping may be customized by
+setting the variable `markdown-code-lang-modes'."
+  :group 'markdown
+  :type 'boolean
+  :safe 'booleanp
+  :package-version '(markdown-mode . "2.3"))
+
+(defcustom markdown-fontify-code-block-default-mode nil
+  "Default mode to use to fontify code blocks.
+This mode is used when automatic detection fails, such as for GFM
+code blocks with no language specified."
+  :group 'markdown
+  :type '(choice function (const :tag "None" nil))
+  :package-version '(markdown-mode . "2.4"))
+
+(defun markdown-toggle-fontify-code-blocks-natively (&optional arg)
+  "Toggle the native fontification of code blocks.
+With a prefix argument ARG, enable if ARG is positive,
+and disable otherwise."
+  (interactive (list (or current-prefix-arg 'toggle)))
+  (setq markdown-fontify-code-blocks-natively
+        (if (eq arg 'toggle)
+            (not markdown-fontify-code-blocks-natively)
+          (> (prefix-numeric-value arg) 0)))
+  (if markdown-fontify-code-blocks-natively
+      (message "markdown-mode native code block fontification enabled")
+    (message "markdown-mode native code block fontification disabled"))
+  (markdown-reload-extensions))
+
+;; This is based on `org-src-lang-modes' from org-src.el
+(defcustom markdown-code-lang-modes
+  '(("ocaml" . tuareg-mode) ("elisp" . emacs-lisp-mode) ("ditaa" . artist-mode)
+    ("asymptote" . asy-mode) ("dot" . fundamental-mode) ("sqlite" . sql-mode)
+    ("calc" . fundamental-mode) ("C" . c-mode) ("cpp" . c++-mode)
+    ("C++" . c++-mode) ("screen" . shell-script-mode) ("shell" . sh-mode)
+    ("bash" . sh-mode))
+  "Alist mapping languages to their major mode.
+The key is the language name, the value is the major mode.  For
+many languages this is simple, but for language where this is not
+the case, this variable provides a way to simplify things on the
+user side.  For example, there is no ocaml-mode in Emacs, but the
+mode to use is `tuareg-mode'."
+  :group 'markdown
+  :type '(repeat
+          (cons
+           (string "Language name")
+           (symbol "Major mode")))
+  :package-version '(markdown-mode . "2.3"))
+
+(defun markdown-get-lang-mode (lang)
+  "Return major mode that should be used for LANG.
+LANG is a string, and the returned major mode is a symbol."
+  (cl-find-if
+   'fboundp
+   (list (cdr (assoc lang markdown-code-lang-modes))
+         (cdr (assoc (downcase lang) markdown-code-lang-modes))
+         (intern (concat lang "-mode"))
+         (intern (concat (downcase lang) "-mode")))))
+
+(defun markdown-fontify-code-blocks-generic (matcher last)
+  "Add text properties to next code block from point to LAST.
+Use matching function MATCHER."
+  (when (funcall matcher last)
+    (save-excursion
+      (save-match-data
+        (let* ((start (match-beginning 0))
+               (end (match-end 0))
+               ;; Find positions outside opening and closing backquotes.
+               (bol-prev (progn (goto-char start)
+                                (if (bolp) (point-at-bol 0) (point-at-bol))))
+               (eol-next (progn (goto-char end)
+                                (if (bolp) (point-at-bol 2) (point-at-bol 3))))
+               lang)
+          (if (and markdown-fontify-code-blocks-natively
+                   (or (setq lang (markdown-code-block-lang))
+                       markdown-fontify-code-block-default-mode))
+              (markdown-fontify-code-block-natively lang start end)
+            (add-text-properties start end '(face markdown-pre-face)))
+          ;; Set background for block as well as opening and closing lines.
+          (font-lock-append-text-property
+           bol-prev eol-next 'face 'markdown-code-face)
+          ;; Set invisible property for lines before and after, including newline.
+          (add-text-properties bol-prev start '(invisible markdown-markup))
+          (add-text-properties end eol-next '(invisible markdown-markup)))))
+    t))
+
+(defun markdown-fontify-gfm-code-blocks (last)
+  "Add text properties to next GFM code block from point to LAST."
+  (markdown-fontify-code-blocks-generic 'markdown-match-gfm-code-blocks last))
+
+(defun markdown-fontify-fenced-code-blocks (last)
+  "Add text properties to next tilde fenced code block from point to LAST."
+  (markdown-fontify-code-blocks-generic 'markdown-match-fenced-code-blocks last))
+
+;; Based on `org-src-font-lock-fontify-block' from org-src.el.
+(defun markdown-fontify-code-block-natively (lang start end)
+  "Fontify given GFM or fenced code block.
+This function is called by Emacs for automatic fontification when
+`markdown-fontify-code-blocks-natively' is non-nil.  LANG is the
+language used in the block. START and END specify the block
+position."
+  (let ((lang-mode (if lang (markdown-get-lang-mode lang)
+                     markdown-fontify-code-block-default-mode)))
+    (when (fboundp lang-mode)
+      (let ((string (buffer-substring-no-properties start end))
+            (modified (buffer-modified-p))
+            (markdown-buffer (current-buffer)) pos next)
+        (remove-text-properties start end '(face nil))
+        (with-current-buffer
+            (get-buffer-create
+             (concat " markdown-code-fontification:" (symbol-name lang-mode)))
+          ;; Make sure that modification hooks are not inhibited in
+          ;; the org-src-fontification buffer in case we're called
+          ;; from `jit-lock-function' (Bug#25132).
+          (let ((inhibit-modification-hooks nil))
+            (delete-region (point-min) (point-max))
+            (insert string " ")) ;; so there's a final property change
+          (unless (eq major-mode lang-mode) (funcall lang-mode))
+          (markdown-font-lock-ensure)
+          (setq pos (point-min))
+          (while (setq next (next-single-property-change pos 'face))
+            (let ((val (get-text-property pos 'face)))
+              (when val
+                (put-text-property
+                 (+ start (1- pos)) (1- (+ start next)) 'face
+                 val markdown-buffer)))
+            (setq pos next)))
+        (add-text-properties
+         start end
+         '(font-lock-fontified t fontified t font-lock-multiline t))
+        (set-buffer-modified-p modified)))))
+
+(require 'edit-indirect nil t)
+(defvar edit-indirect-guess-mode-function)
+(defvar edit-indirect-after-commit-functions)
+
+(defun markdown--edit-indirect-after-commit-function (_beg end)
+  "Ensure trailing newlines at the END of code blocks."
+  (goto-char end)
+  (unless (eq (char-before) ?\n)
+    (insert "\n")))
+
+(defun markdown-edit-code-block ()
+  "Edit Markdown code block in an indirect buffer."
+  (interactive)
+  (save-excursion
+    (if (fboundp 'edit-indirect-region)
+        (let* ((bounds (markdown-get-enclosing-fenced-block-construct))
+               (begin (and bounds (goto-char (nth 0 bounds)) (point-at-bol 2)))
+               (end (and bounds (goto-char (nth 1 bounds)) (point-at-bol 1))))
+          (if (and begin end)
+              (let* ((lang (markdown-code-block-lang))
+                     (mode (or (and lang (markdown-get-lang-mode lang))
+                               markdown-edit-code-block-default-mode))
+                     (edit-indirect-guess-mode-function
+                      (lambda (_parent-buffer _beg _end)
+                        (funcall mode))))
+                (edit-indirect-region begin end 'display-buffer))
+            (user-error "Not inside a GFM or tilde fenced code block")))
+      (when (y-or-n-p "Package edit-indirect needed to edit code blocks. Install it now? ")
+        (progn (package-refresh-contents)
+               (package-install 'edit-indirect)
+               (markdown-edit-code-block))))))
+
+
+;;; Table Editing
+
+;; These functions were originally adapted from `org-table.el'.
+
+;; General helper functions
+
+(defmacro markdown--with-gensyms (symbols &rest body)
+  (declare (debug (sexp body)) (indent 1))
+  `(let ,(mapcar (lambda (s)
+                   `(,s (make-symbol (concat "--" (symbol-name ',s)))))
+                 symbols)
+     ,@body))
+
+(defun markdown--split-string (string &optional separators)
+  "Splits STRING into substrings at SEPARATORS.
+SEPARATORS is a regular expression. If nil it defaults to
+`split-string-default-separators'. This version returns no empty
+strings if there are matches at the beginning and end of string."
+  (let ((start 0) notfirst list)
+    (while (and (string-match
+                 (or separators split-string-default-separators)
+                 string
+                 (if (and notfirst
+                          (= start (match-beginning 0))
+                          (< start (length string)))
+                     (1+ start) start))
+                (< (match-beginning 0) (length string)))
+      (setq notfirst t)
+      (or (eq (match-beginning 0) 0)
+          (and (eq (match-beginning 0) (match-end 0))
+               (eq (match-beginning 0) start))
+          (push (substring string start (match-beginning 0)) list))
+      (setq start (match-end 0)))
+    (or (eq start (length string))
+        (push (substring string start) list))
+    (nreverse list)))
+
+(defun markdown--string-width (s)
+  "Return width of string S.
+This version ignores characters with invisibility property
+`markdown-markup'."
+  (let (b)
+    (when (or (eq t buffer-invisibility-spec)
+              (member 'markdown-markup buffer-invisibility-spec))
+      (while (setq b (text-property-any
+                      0 (length s)
+                      'invisible 'markdown-markup s))
+        (setq s (concat
+                 (substring s 0 b)
+                 (substring s (or (next-single-property-change
+                                   b 'invisible s)
+                                  (length s))))))))
+  (string-width s))
+
+(defun markdown--remove-invisible-markup (s)
+  "Remove Markdown markup from string S.
+This version removes characters with invisibility property
+`markdown-markup'."
+  (let (b)
+    (while (setq b (text-property-any
+                    0 (length s)
+                    'invisible 'markdown-markup s))
+      (setq s (concat
+               (substring s 0 b)
+               (substring s (or (next-single-property-change
+                                 b 'invisible s)
+                                (length s)))))))
+  s)
+
+;; Functions for maintaining tables
+
+(defvar markdown-table-at-point-p-function nil
+  "Function to decide if point is inside a table.
+
+The indirection serves to differentiate between standard markdown
+tables and gfm tables which are less strict about the markup.")
+
+(defconst markdown-table-line-regexp "^[ \t]*|"
+  "Regexp matching any line inside a table.")
+
+(defconst markdown-table-hline-regexp "^[ \t]*|[-:]"
+  "Regexp matching hline inside a table.")
+
+(defconst markdown-table-dline-regexp "^[ \t]*|[^-:]"
+  "Regexp matching dline inside a table.")
+
+(defun markdown-table-at-point-p ()
+  "Return non-nil when point is inside a table."
+  (if (functionp markdown-table-at-point-p-function)
+      (funcall markdown-table-at-point-p-function)
+    (markdown--table-at-point-p)))
+
+(defun markdown--table-at-point-p ()
+  "Return non-nil when point is inside a table."
+  (save-excursion
+    (beginning-of-line)
+    (and (looking-at-p markdown-table-line-regexp)
+         (not (markdown-code-block-at-point-p)))))
+
+(defconst gfm-table-line-regexp "^.?*|"
+  "Regexp matching any line inside a table.")
+
+(defconst gfm-table-hline-regexp "^-+\\(|-\\)+"
+  "Regexp matching hline inside a table.")
+
+;; GFM simplified tables syntax is as follows:
+;; - A header line for the column names, this is any text
+;;   separated by `|'.
+;; - Followed by a string -|-|- ..., the number of dashes is optional
+;;   but must be higher than 1. The number of separators should match
+;;   the number of columns.
+;; - Followed by the rows of data, which has the same format as the
+;;   header line.
+;; Example:
+;;
+;; foo | bar
+;; ------|---------
+;; bar | baz
+;; bar | baz
+(defun gfm--table-at-point-p ()
+  "Return non-nil when point is inside a gfm-compatible table."
+  (or (markdown--table-at-point-p)
+      (save-excursion
+        (beginning-of-line)
+        (when (looking-at-p gfm-table-line-regexp)
+          ;; we might be at the first line of the table, check if the
+          ;; line below is the hline
+          (or (save-excursion
+                (forward-line 1)
+                (looking-at-p gfm-table-hline-regexp))
+              ;; go up to find the header
+              (catch 'done
+                (while (looking-at-p gfm-table-line-regexp)
+                  (cond
+                   ((looking-at-p gfm-table-hline-regexp)
+                    (throw 'done t))
+                   ((bobp)
+                    (throw 'done nil)))
+                  (forward-line -1))
+                nil))))))
+
+(defun markdown-table-hline-at-point-p ()
+  "Return non-nil when point is on a hline in a table.
+This function assumes point is on a table."
+  (save-excursion
+    (beginning-of-line)
+    (looking-at-p markdown-table-hline-regexp)))
+
+(defun markdown-table-begin ()
+  "Find the beginning of the table and return its position.
+This function assumes point is on a table."
+  (save-excursion
+    (while (and (not (bobp))
+                (markdown-table-at-point-p))
+      (forward-line -1))
+    (unless (eobp)
+      (forward-line 1))
+    (point)))
+
+(defun markdown-table-end ()
+  "Find the end of the table and return its position.
+This function assumes point is on a table."
+  (save-excursion
+    (while (and (not (eobp))
+                (markdown-table-at-point-p))
+      (forward-line 1))
+    (point)))
+
+(defun markdown-table-get-dline ()
+  "Return index of the table data line at point.
+This function assumes point is on a table."
+  (let ((pos (point)) (end (markdown-table-end)) (cnt 0))
+    (save-excursion
+      (goto-char (markdown-table-begin))
+      (while (and (re-search-forward
+                   markdown-table-dline-regexp end t)
+                  (setq cnt (1+ cnt))
+                  (< (point-at-eol) pos))))
+    cnt))
+
+(defun markdown-table-get-column ()
+  "Return table column at point.
+This function assumes point is on a table."
+  (let ((pos (point)) (cnt 0))
+    (save-excursion
+      (beginning-of-line)
+      (while (search-forward "|" pos t) (setq cnt (1+ cnt))))
+    cnt))
+
+(defun markdown-table-get-cell (&optional n)
+  "Return the content of the cell in column N of current row.
+N defaults to column at point. This function assumes point is on
+a table."
+  (and n (markdown-table-goto-column n))
+  (skip-chars-backward "^|\n") (backward-char 1)
+  (if (looking-at "|[^|\r\n]*")
+      (let* ((pos (match-beginning 0))
+             (val (buffer-substring (1+ pos) (match-end 0))))
+        (goto-char (min (point-at-eol) (+ 2 pos)))
+        ;; Trim whitespaces
+        (setq val (replace-regexp-in-string "\\`[ \t]+" "" val)
+              val (replace-regexp-in-string "[ \t]+\\'" "" val)))
+    (forward-char 1) ""))
+
+(defun markdown-table-goto-dline (n)
+  "Go to the Nth data line in the table at point.
+Return t when the line exists, nil otherwise. This function
+assumes point is on a table."
+  (goto-char (markdown-table-begin))
+  (let ((end (markdown-table-end)) (cnt 0))
+    (while (and (re-search-forward
+                 markdown-table-dline-regexp end t)
+                (< (setq cnt (1+ cnt)) n)))
+    (= cnt n)))
+
+(defun markdown-table-goto-column (n &optional on-delim)
+  "Go to the Nth column in the table line at point.
+With optional argument ON-DELIM, stop with point before the left
+delimiter of the cell. If there are less than N cells, just go
+beyond the last delimiter. This function assumes point is on a
+table."
+  (beginning-of-line 1)
+  (when (> n 0)
+    (while (and (> (setq n (1- n)) -1)
+                (search-forward "|" (point-at-eol) t)))
+    (if on-delim
+        (backward-char 1)
+      (when (looking-at " ") (forward-char 1)))))
+
+(defmacro markdown-table-save-cell (&rest body)
+  "Save cell at point, execute BODY and restore cell.
+This function assumes point is on a table."
+  (declare (debug (body)))
+  (markdown--with-gensyms (line column)
+    `(let ((,line (copy-marker (line-beginning-position)))
+           (,column (markdown-table-get-column)))
+       (unwind-protect
+           (progn ,@body)
+         (goto-char ,line)
+         (markdown-table-goto-column ,column)
+         (set-marker ,line nil)))))
+
+(defun markdown-table-blank-line (s)
+  "Convert a table line S into a line with blank cells."
+  (if (string-match "^[ \t]*|-" s)
+      (setq s (mapconcat
+               (lambda (x) (if (member x '(?| ?+)) "|" " "))
+               s ""))
+    (while (string-match "|\\([ \t]*?[^ \t\r\n|][^\r\n|]*\\)|" s)
+      (setq s (replace-match
+               (concat "|" (make-string (length (match-string 1 s)) ?\ ) "|")
+               t t s)))
+    s))
+
+(defun markdown-table-colfmt (fmtspec)
+  "Process column alignment specifier FMTSPEC for tables."
+  (when (stringp fmtspec)
+    (mapcar (lambda (x)
+              (cond ((string-match-p "^:.*:$" x) 'c)
+                    ((string-match-p "^:"     x) 'l)
+                    ((string-match-p ":$"     x) 'r)
+                    (t 'd)))
+            (markdown--split-string fmtspec "\\s-*|\\s-*"))))
+
+(defun markdown-table-align ()
+  "Align table at point.
+This function assumes point is on a table."
+  (interactive)
+  (let ((begin (markdown-table-begin))
+        (end (copy-marker (markdown-table-end))))
+    (markdown-table-save-cell
+     (goto-char begin)
+     (let* (fmtspec
+            ;; Store table indent
+            (indent (progn (looking-at "[ \t]*") (match-string 0)))
+            ;; Split table in lines and save column format specifier
+            (lines (mapcar (lambda (l)
+                             (if (string-match-p "\\`[ \t]*|[-:]" l)
+                                 (progn (setq fmtspec (or fmtspec l)) nil) l))
+                           (markdown--split-string (buffer-substring begin end) "\n")))
+            ;; Split lines in cells
+            (cells (mapcar (lambda (l) (markdown--split-string l "\\s-*|\\s-*"))
+                           (remq nil lines)))
+            ;; Calculate maximum number of cells in a line
+            (maxcells (if cells
+                          (apply #'max (mapcar #'length cells))
+                        (user-error "Empty table")))
+            ;; Empty cells to fill short lines
+            (emptycells (make-list maxcells "")) maxwidths)
+       ;; Calculate maximum width for each column
+       (dotimes (i maxcells)
+         (let ((column (mapcar (lambda (x) (or (nth i x) "")) cells)))
+           (push (apply #'max 1 (mapcar #'markdown--string-width column))
+                 maxwidths)))
+       (setq maxwidths (nreverse maxwidths))
+       ;; Process column format specifier
+       (setq fmtspec (markdown-table-colfmt fmtspec))
+       ;; Compute formats needed for output of table lines
+       (let ((hfmt (concat indent "|"))
+             (rfmt (concat indent "|"))
+             hfmt1 rfmt1 fmt)
+         (dolist (width maxwidths (setq hfmt (concat (substring hfmt 0 -1) "|")))
+           (setq fmt (pop fmtspec))
+           (cond ((equal fmt 'l) (setq hfmt1 ":%s-|" rfmt1 " %%-%ds |"))
+                 ((equal fmt 'r) (setq hfmt1 "-%s:|" rfmt1  " %%%ds |"))
+                 ((equal fmt 'c) (setq hfmt1 ":%s:|" rfmt1 " %%-%ds |"))
+                 (t              (setq hfmt1 "-%s-|" rfmt1 " %%-%ds |")))
+           (setq rfmt (concat rfmt (format rfmt1 width)))
+           (setq hfmt (concat hfmt (format hfmt1 (make-string width ?-)))))
+         ;; Replace modified lines only
+         (dolist (line lines)
+           (let ((line (if line
+                           (apply #'format rfmt (append (pop cells) emptycells))
+                         hfmt))
+                 (previous (buffer-substring (point) (line-end-position))))
+             (if (equal previous line)
+                 (forward-line)
+               (insert line "\n")
+               (delete-region (point) (line-beginning-position 2))))))
+       (set-marker end nil)))))
+
+(defun markdown-table-insert-row (&optional arg)
+  "Insert a new row above the row at point into the table.
+With optional argument ARG, insert below the current row."
+  (interactive "P")
+  (unless (markdown-table-at-point-p)
+    (user-error "Not at a table"))
+  (let* ((line (buffer-substring
+                (line-beginning-position) (line-end-position)))
+         (new (markdown-table-blank-line line)))
+    (beginning-of-line (if arg 2 1))
+    (unless (bolp) (insert "\n"))
+    (insert-before-markers new "\n")
+    (beginning-of-line 0)
+    (re-search-forward "| ?" (line-end-position) t)))
+
+(defun markdown-table-delete-row ()
+  "Delete row or horizontal line at point from the table."
+  (interactive)
+  (unless (markdown-table-at-point-p)
+    (user-error "Not at a table"))
+  (let ((col (current-column)))
+    (kill-region (point-at-bol)
+                 (min (1+ (point-at-eol)) (point-max)))
+    (unless (markdown-table-at-point-p) (beginning-of-line 0))
+    (move-to-column col)))
+
+(defun markdown-table-move-row (&optional up)
+  "Move table line at point down.
+With optional argument UP, move it up."
+  (interactive "P")
+  (unless (markdown-table-at-point-p)
+    (user-error "Not at a table"))
+  (let* ((col (current-column)) (pos (point))
+         (tonew (if up 0 2)) txt)
+    (beginning-of-line tonew)
+    (unless (markdown-table-at-point-p)
+      (goto-char pos) (user-error "Cannot move row further"))
+    (goto-char pos) (beginning-of-line 1) (setq pos (point))
+    (setq txt (buffer-substring (point) (1+ (point-at-eol))))
+    (delete-region (point) (1+ (point-at-eol)))
+    (beginning-of-line tonew)
+    (insert txt) (beginning-of-line 0)
+    (move-to-column col)))
+
+(defun markdown-table-move-row-up ()
+  "Move table row at point up."
+  (interactive)
+  (markdown-table-move-row 'up))
+
+(defun markdown-table-move-row-down ()
+  "Move table row at point down."
+  (interactive)
+  (markdown-table-move-row nil))
+
+(defun markdown-table-insert-column ()
+  "Insert a new table column."
+  (interactive)
+  (unless (markdown-table-at-point-p)
+    (user-error "Not at a table"))
+  (let* ((col (max 1 (markdown-table-get-column)))
+         (begin (markdown-table-begin))
+         (end (copy-marker (markdown-table-end))))
+    (markdown-table-save-cell
+     (goto-char begin)
+     (while (< (point) end)
+       (markdown-table-goto-column col t)
+       (if (markdown-table-hline-at-point-p)
+           (insert "|---")
+         (insert "|   "))
+       (forward-line)))
+    (set-marker end nil)
+    (markdown-table-align)))
+
+(defun markdown-table-delete-column ()
+  "Delete column at point from table."
+  (interactive)
+  (unless (markdown-table-at-point-p)
+    (user-error "Not at a table"))
+  (let ((col (markdown-table-get-column))
+        (begin (markdown-table-begin))
+        (end (copy-marker (markdown-table-end))))
+    (markdown-table-save-cell
+     (goto-char begin)
+     (while (< (point) end)
+       (markdown-table-goto-column col t)
+       (and (looking-at "|[^|\n]+|")
+            (replace-match "|"))
+       (forward-line)))
+    (set-marker end nil)
+    (markdown-table-goto-column (max 1 (1- col)))
+    (markdown-table-align)))
+
+(defun markdown-table-move-column (&optional left)
+  "Move table column at point to the right.
+With optional argument LEFT, move it to the left."
+  (interactive "P")
+  (unless (markdown-table-at-point-p)
+    (user-error "Not at a table"))
+  (let* ((col (markdown-table-get-column))
+         (col1 (if left (1- col) col))
+         (colpos (if left (1- col) (1+ col)))
+         (begin (markdown-table-begin))
+         (end (copy-marker (markdown-table-end))))
+    (when (and left (= col 1))
+      (user-error "Cannot move column further left"))
+    (when (and (not left) (looking-at "[^|\n]*|[^|\n]*$"))
+      (user-error "Cannot move column further right"))
+    (markdown-table-save-cell
+     (goto-char begin)
+     (while (< (point) end)
+       (markdown-table-goto-column col1 t)
+       (when (looking-at "|\\([^|\n]+\\)|\\([^|\n]+\\)|")
+         (replace-match "|\\2|\\1|"))
+       (forward-line)))
+    (set-marker end nil)
+    (markdown-table-goto-column colpos)
+    (markdown-table-align)))
+
+(defun markdown-table-move-column-left ()
+  "Move table column at point to the left."
+  (interactive)
+  (markdown-table-move-column 'left))
+
+(defun markdown-table-move-column-right ()
+  "Move table column at point to the right."
+  (interactive)
+  (markdown-table-move-column nil))
+
+(defun markdown-table-next-row ()
+  "Go to the next row (same column) in the table.
+Create new table lines if required."
+  (interactive)
+  (unless (markdown-table-at-point-p)
+    (user-error "Not at a table"))
+  (if (or (looking-at "[ \t]*$")
+          (save-excursion (skip-chars-backward " \t") (bolp)))
+      (newline)
+    (markdown-table-align)
+    (let ((col (markdown-table-get-column)))
+      (beginning-of-line 2)
+      (if (or (not (markdown-table-at-point-p))
+              (markdown-table-hline-at-point-p))
+          (progn
+            (beginning-of-line 0)
+            (markdown-table-insert-row 'below)))
+      (markdown-table-goto-column col)
+      (skip-chars-backward "^|\n\r")
+      (when (looking-at " ") (forward-char 1)))))
+
+(defun markdown-table-forward-cell ()
+  "Go to the next cell in the table.
+Create new table lines if required."
+  (interactive)
+  (unless (markdown-table-at-point-p)
+    (user-error "Not at a table"))
+  (markdown-table-align)
+  (let ((end (markdown-table-end)))
+    (when (markdown-table-hline-at-point-p) (end-of-line 1))
+    (condition-case nil
+        (progn
+          (re-search-forward "|" end)
+          (if (looking-at "[ \t]*$")
+              (re-search-forward "|" end))
+          (if (and (looking-at "[-:]")
+                   (re-search-forward "^[ \t]*|\\([^-:]\\)" end t))
+              (goto-char (match-beginning 1)))
+          (if (looking-at "[-:]")
+              (progn
+                (beginning-of-line 0)
+                (markdown-table-insert-row 'below))
+            (when (looking-at " ") (forward-char 1))))
+      (error (markdown-table-insert-row 'below)))))
+
+(defun markdown-table-backward-cell ()
+  "Go to the previous cell in the table."
+  (interactive)
+  (unless (markdown-table-at-point-p)
+    (user-error "Not at a table"))
+  (markdown-table-align)
+  (when (markdown-table-hline-at-point-p) (end-of-line 1))
+  (condition-case nil
+      (progn
+        (re-search-backward "|" (markdown-table-begin))
+        (re-search-backward "|" (markdown-table-begin)))
+    (error (user-error "Cannot move to previous table cell")))
+  (while (looking-at "|\\([-:]\\|[ \t]*$\\)")
+    (re-search-backward "|" (markdown-table-begin)))
+  (when (looking-at "| ?") (goto-char (match-end 0))))
+
+(defun markdown-table-transpose ()
+  "Transpose table at point.
+Horizontal separator lines will be eliminated."
+  (interactive)
+  (unless (markdown-table-at-point-p)
+    (user-error "Not at a table"))
+  (let* ((table (buffer-substring-no-properties
+                 (markdown-table-begin) (markdown-table-end)))
+         ;; Convert table to a Lisp structure
+         (table (delq nil
+                      (mapcar
+                       (lambda (x)
+                         (unless (string-match-p
+                                  markdown-table-hline-regexp x)
+                           (markdown--split-string x "\\s-*|\\s-*")))
+                       (markdown--split-string table "[ \t]*\n[ \t]*"))))
+         (dline_old (markdown-table-get-dline))
+         (col_old (markdown-table-get-column))
+         (contents (mapcar (lambda (_)
+                             (let ((tp table))
+                               (mapcar
+                                (lambda (_)
+                                  (prog1
+                                      (pop (car tp))
+                                    (setq tp (cdr tp))))
+                                table)))
+                           (car table))))
+    (goto-char (markdown-table-begin))
+    (re-search-forward "|") (backward-char)
+    (delete-region (point) (markdown-table-end))
+    (insert (mapconcat
+             (lambda(x)
+               (concat "| " (mapconcat 'identity x " | " ) "  |\n"))
+             contents ""))
+    (markdown-table-goto-dline col_old)
+    (markdown-table-goto-column dline_old))
+  (markdown-table-align))
+
+(defun markdown-table-sort-lines (&optional sorting-type)
+  "Sort table lines according to the column at point.
+
+The position of point indicates the column to be used for
+sorting, and the range of lines is the range between the nearest
+horizontal separator lines, or the entire table of no such lines
+exist. If point is before the first column, user will be prompted
+for the sorting column. If there is an active region, the mark
+specifies the first line and the sorting column, while point
+should be in the last line to be included into the sorting.
+
+The command then prompts for the sorting type which can be
+alphabetically or numerically. Sorting in reverse order is also
+possible.
+
+If SORTING-TYPE is specified when this function is called from a
+Lisp program, no prompting will take place. SORTING-TYPE must be
+a character, any of (?a ?A ?n ?N) where the capital letters
+indicate that sorting should be done in reverse order."
+  (interactive)
+  (unless (markdown-table-at-point-p)
+    (user-error "Not at a table"))
+  ;; Set sorting type and column used for sorting
+  (let ((column (let ((c (markdown-table-get-column)))
+                  (cond ((> c 0) c)
+                        ((called-interactively-p 'any)
+                         (read-number "Use column N for sorting: "))
+                        (t 1))))
+        (sorting-type
+         (or sorting-type
+             (read-char-exclusive
+              "Sort type: [a]lpha [n]umeric (A/N means reversed): "))))
+    (save-restriction
+      ;; Narrow buffer to appropriate sorting area
+      (if (region-active-p)
+          (narrow-to-region
+           (save-excursion
+             (progn
+               (goto-char (region-beginning)) (line-beginning-position)))
+           (save-excursion
+             (progn
+               (goto-char (region-end)) (line-end-position))))
+        (let ((start (markdown-table-begin))
+              (end (markdown-table-end)))
+          (narrow-to-region
+           (save-excursion
+             (if (re-search-backward
+                  markdown-table-hline-regexp start t)
+                 (line-beginning-position 2)
+               start))
+           (if (save-excursion (re-search-forward
+                                markdown-table-hline-regexp end t))
+               (match-beginning 0)
+             end))))
+      ;; Determine arguments for `sort-subr'
+      (let* ((extract-key-from-cell
+              (cl-case sorting-type
+                ((?a ?A) #'markdown--remove-invisible-markup) ;; #'identity)
+                ((?n ?N) #'string-to-number)
+                (t (user-error "Invalid sorting type: %c" sorting-type))))
+             (predicate
+              (cl-case sorting-type
+                ((?n ?N) #'<)
+                ((?a ?A) #'string<))))
+        ;; Sort selected area
+        (goto-char (point-min))
+        (sort-subr (memq sorting-type '(?A ?N))
+                   (lambda ()
+                     (forward-line)
+                     (while (and (not (eobp))
+                                 (not (looking-at
+                                       markdown-table-dline-regexp)))
+                       (forward-line)))
+                   #'end-of-line
+                   (lambda ()
+                     (funcall extract-key-from-cell
+                              (markdown-table-get-cell column)))
+                   nil
+                   predicate)
+        (goto-char (point-min))))))
+
+(defun markdown-table-convert-region (begin end &optional separator)
+  "Convert region from BEGIN to END to table with SEPARATOR.
+
+If every line contains at least one TAB character, the function
+assumes that the material is tab separated (TSV). If every line
+contains a comma, comma-separated values (CSV) are assumed. If
+not, lines are split at whitespace into cells.
+
+You can use a prefix argument to force a specific separator:
+\\[universal-argument] once forces CSV, \\[universal-argument]
+twice forces TAB, and \\[universal-argument] three times will
+prompt for a regular expression to match the separator, and a
+numeric argument N indicates that at least N consecutive
+spaces, or alternatively a TAB should be used as the separator."
+
+  (interactive "r\nP")
+  (let* ((begin (min begin end)) (end (max begin end)) re)
+    (goto-char begin) (beginning-of-line 1)
+    (setq begin (point-marker))
+    (goto-char end)
+    (if (bolp) (backward-char 1) (end-of-line 1))
+    (setq end (point-marker))
+    (when (equal separator '(64))
+      (setq separator (read-regexp "Regexp for cell separator: ")))
+    (unless separator
+      ;; Get the right cell separator
+      (goto-char begin)
+      (setq separator
+            (cond
+             ((not (re-search-forward "^[^\n\t]+$" end t)) '(16))
+             ((not (re-search-forward "^[^\n,]+$" end t)) '(4))
+             (t 1))))
+    (goto-char begin)
+    (if (equal separator '(4))
+        ;; Parse CSV
+        (while (< (point) end)
+          (cond
+           ((looking-at "^") (insert "| "))
+           ((looking-at "[ \t]*$") (replace-match " |") (beginning-of-line 2))
+           ((looking-at "[ \t]*\"\\([^\"\n]*\\)\"")
+            (replace-match "\\1") (if (looking-at "\"") (insert "\"")))
+           ((looking-at "[^,\n]+") (goto-char (match-end 0)))
+           ((looking-at "[ \t]*,") (replace-match " | "))
+           (t (beginning-of-line 2))))
+      (setq re
+            (cond
+             ((equal separator '(4))  "^\\|\"?[ \t]*,[ \t]*\"?")
+             ((equal separator '(16)) "^\\|\t")
+             ((integerp separator)
+              (if (< separator 1)
+                  (user-error "Cell separator must contain one or more spaces")
+                (format "^ *\\| *\t *\\| \\{%d,\\}" separator)))
+             ((stringp separator) (format "^ *\\|%s" separator))
+             (t (error "Invalid cell separator"))))
+      (while (re-search-forward re end t) (replace-match "| " t t)))
+    (goto-char begin)
+    (markdown-table-align)))
+
+
+;;; ElDoc Support
+
+(defun markdown-eldoc-function ()
+  "Return a helpful string when appropriate based on context.
+* Report URL when point is at a hidden URL.
+* Report language name when point is a code block with hidden markup."
+  (cond
+   ;; Hidden URL or reference for inline link
+   ((and (or (thing-at-point-looking-at markdown-regex-link-inline)
+             (thing-at-point-looking-at markdown-regex-link-reference))
+         (or markdown-hide-urls markdown-hide-markup))
+    (let* ((imagep (string-equal (match-string 1) "!"))
+           (edit-keys (markdown--substitute-command-keys
+                       (if imagep
+                           "\\[markdown-insert-image]"
+                         "\\[markdown-insert-link]")))
+           (edit-str (propertize edit-keys 'face 'font-lock-constant-face))
+           (referencep (string-equal (match-string 5) "["))
+           (object (if referencep "reference" "URL")))
+      (format "Hidden %s (%s to edit): %s" object edit-str
+              (if referencep
+                  (concat
+                   (propertize "[" 'face 'markdown-markup-face)
+                   (propertize (match-string-no-properties 6)
+                               'face 'markdown-reference-face)
+                   (propertize "]" 'face 'markdown-markup-face))
+                (propertize (match-string-no-properties 6)
+                            'face 'markdown-url-face)))))
+   ;; Hidden language name for fenced code blocks
+   ((and (markdown-code-block-at-point-p)
+         (not (get-text-property (point) 'markdown-pre))
+         markdown-hide-markup)
+    (let ((lang (save-excursion (markdown-code-block-lang))))
+      (unless lang (setq lang "[unspecified]"))
+      (format "Hidden code block language: %s (%s to toggle markup)"
+              (propertize lang 'face 'markdown-language-keyword-face)
+              (markdown--substitute-command-keys
+               "\\[markdown-toggle-markup-hiding]"))))))
+
+
+;;; Mode Definition  ==========================================================
+
+(defun markdown-show-version ()
+  "Show the version number in the minibuffer."
+  (interactive)
+  (message "markdown-mode, version %s" markdown-mode-version))
+
+(defun markdown-mode-info ()
+  "Open the `markdown-mode' homepage."
+  (interactive)
+  (browse-url "https://jblevins.org/projects/markdown-mode/"))
+
+;;;###autoload
+(define-derived-mode markdown-mode text-mode "Markdown"
+  "Major mode for editing Markdown files."
+  ;; Natural Markdown tab width
+  (setq tab-width 4)
+  ;; Comments
+  (setq-local comment-start "<!-- ")
+  (setq-local comment-end " -->")
+  (setq-local comment-start-skip "<!--[ \t]*")
+  (setq-local comment-column 0)
+  (setq-local comment-auto-fill-only-comments nil)
+  (setq-local comment-use-syntax t)
+  ;; Syntax
+  (add-hook 'syntax-propertize-extend-region-functions
+            #'markdown-syntax-propertize-extend-region)
+  (add-hook 'jit-lock-after-change-extend-region-functions
+            #'markdown-font-lock-extend-region-function t t)
+  (setq-local syntax-propertize-function #'markdown-syntax-propertize)
+  (syntax-propertize (point-max)) ;; Propertize before hooks run, etc.
+  ;; Font lock.
+  (setq font-lock-defaults
+        '(markdown-mode-font-lock-keywords
+          nil nil nil nil
+          (font-lock-multiline . t)
+          (font-lock-syntactic-face-function . markdown-syntactic-face)
+          (font-lock-extra-managed-props
+           . (composition display invisible rear-nonsticky
+                          keymap help-echo mouse-face))))
+  (if markdown-hide-markup
+      (add-to-invisibility-spec 'markdown-markup)
+    (remove-from-invisibility-spec 'markdown-markup))
+  ;; Wiki links
+  (markdown-setup-wiki-link-hooks)
+  ;; Math mode
+  (when markdown-enable-math (markdown-toggle-math t))
+  ;; Add a buffer-local hook to reload after file-local variables are read
+  (add-hook 'hack-local-variables-hook #'markdown-handle-local-variables nil t)
+  ;; For imenu support
+  (setq imenu-create-index-function
+        (if markdown-nested-imenu-heading-index
+            #'markdown-imenu-create-nested-index
+          #'markdown-imenu-create-flat-index))
+  ;; For menu support in XEmacs
+  (easy-menu-add markdown-mode-menu markdown-mode-map)
+  ;; Defun movement
+  (setq-local beginning-of-defun-function #'markdown-beginning-of-defun)
+  (setq-local end-of-defun-function #'markdown-end-of-defun)
+  ;; Paragraph filling
+  (setq-local fill-paragraph-function #'markdown-fill-paragraph)
+  (setq-local paragraph-start
+              ;; Should match start of lines that start or separate paragraphs
+              (mapconcat #'identity
+                         '(
+                           "\f" ; starts with a literal line-feed
+                           "[ \t\f]*$" ; space-only line
+                           "\\(?:[ \t]*>\\)+[ \t\f]*$"; empty line in blockquote
+                           "[ \t]*[*+-][ \t]+" ; unordered list item
+                           "[ \t]*\\(?:[0-9]+\\|#\\)\\.[ \t]+" ; ordered list item
+                           "[ \t]*\\[\\S-*\\]:[ \t]+" ; link ref def
+                           "[ \t]*:[ \t]+" ; definition
+                           "^|" ; table or Pandoc line block
+                           )
+                         "\\|"))
+  (setq-local paragraph-separate
+              ;; Should match lines that separate paragraphs without being
+              ;; part of any paragraph:
+              (mapconcat #'identity
+                         '("[ \t\f]*$" ; space-only line
+                           "\\(?:[ \t]*>\\)+[ \t\f]*$"; empty line in blockquote
+                           ;; The following is not ideal, but the Fill customization
+                           ;; options really only handle paragraph-starting prefixes,
+                           ;; not paragraph-ending suffixes:
+                           ".*  $" ; line ending in two spaces
+                           "^#+"
+                           "[ \t]*\\[\\^\\S-*\\]:[ \t]*$") ; just the start of a footnote def
+                         "\\|"))
+  (setq-local adaptive-fill-first-line-regexp "\\`[ \t]*[A-Z]?>[ \t]*?\\'")
+  (setq-local adaptive-fill-regexp "\\s-*")
+  (setq-local adaptive-fill-function #'markdown-adaptive-fill-function)
+  (setq-local fill-forward-paragraph-function #'markdown-fill-forward-paragraph)
+  ;; Outline mode
+  (setq-local outline-regexp markdown-regex-header)
+  (setq-local outline-level #'markdown-outline-level)
+  ;; Cause use of ellipses for invisible text.
+  (add-to-invisibility-spec '(outline . t))
+  ;; ElDoc support
+  (if (eval-when-compile (fboundp 'add-function))
+      (add-function :before-until (local 'eldoc-documentation-function)
+                    #'markdown-eldoc-function)
+    (setq-local eldoc-documentation-function #'markdown-eldoc-function))
+  ;; Inhibiting line-breaking:
+  ;; Separating out each condition into a separate function so that users can
+  ;; override if desired (with remove-hook)
+  (add-hook 'fill-nobreak-predicate
+            #'markdown-line-is-reference-definition-p nil t)
+  (add-hook 'fill-nobreak-predicate
+            #'markdown-pipe-at-bol-p nil t)
+
+  ;; Indentation
+  (setq-local indent-line-function markdown-indent-function)
+
+  ;; Flyspell
+  (setq-local flyspell-generic-check-word-predicate
+              #'markdown-flyspell-check-word-p)
+
+  ;; Electric quoting
+  (add-hook 'electric-quote-inhibit-functions
+            #'markdown--inhibit-electric-quote nil :local)
+
+  ;; Backwards compatibility with markdown-css-path
+  (when (boundp 'markdown-css-path)
+    (warn "markdown-css-path is deprecated, see markdown-css-paths.")
+    (add-to-list 'markdown-css-paths markdown-css-path))
+
+  ;; Prepare hooks for XEmacs compatibility
+  (when (featurep 'xemacs)
+    (make-local-hook 'after-change-functions)
+    (make-local-hook 'font-lock-extend-region-functions)
+    (make-local-hook 'window-configuration-change-hook))
+
+  ;; Make checkboxes buttons
+  (when markdown-make-gfm-checkboxes-buttons
+    (markdown-make-gfm-checkboxes-buttons (point-min) (point-max))
+    (add-hook 'after-change-functions #'markdown-gfm-checkbox-after-change-function t t)
+    (add-hook 'change-major-mode-hook #'markdown-remove-gfm-checkbox-overlays t t))
+
+  ;; edit-indirect
+  (add-hook 'edit-indirect-after-commit-functions
+            #'markdown--edit-indirect-after-commit-function
+            nil 'local)
+
+  ;; Marginalized headings
+  (when markdown-marginalize-headers
+    (add-hook 'window-configuration-change-hook
+              #'markdown-marginalize-update-current nil t))
+
+  ;; add live preview export hook
+  (add-hook 'after-save-hook #'markdown-live-preview-if-markdown t t)
+  (add-hook 'kill-buffer-hook #'markdown-live-preview-remove-on-kill t t))
+
+;;;###autoload
+(add-to-list 'auto-mode-alist '("\\.markdown\\'" . markdown-mode))
+;;;###autoload
+(add-to-list 'auto-mode-alist '("\\.md\\'" . markdown-mode))
+
+
+;;; GitHub Flavored Markdown Mode  ============================================
+
+(defvar gfm-mode-hook nil
+  "Hook run when entering GFM mode.")
+
+;;;###autoload
+(define-derived-mode gfm-mode markdown-mode "GFM"
+  "Major mode for editing GitHub Flavored Markdown files."
+  (setq markdown-link-space-sub-char "-")
+  (setq markdown-wiki-link-search-subdirectories t)
+  (setq-local markdown-table-at-point-p-function 'gfm--table-at-point-p)
+  (markdown-gfm-parse-buffer-for-languages))
+
+(define-obsolete-variable-alias
+ 'gfm-font-lock-keywords
+ 'markdown-mode-font-lock-keywords "v2.4")
+
+
+;;; Viewing modes
+
+(defcustom markdown-hide-markup-in-view-modes t
+  "Enable hidden markup mode in `markdown-view-mode' and `gfm-view-mode'."
+  :group 'markdown
+  :type 'boolean
+  :safe 'booleanp)
+
+(defvar markdown-view-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "p") #'markdown-outline-previous)
+    (define-key map (kbd "n") #'markdown-outline-next)
+    (define-key map (kbd "f") #'markdown-outline-next-same-level)
+    (define-key map (kbd "b") #'markdown-outline-previous-same-level)
+    (define-key map (kbd "u") #'markdown-outline-up)
+    (define-key map (kbd "DEL") #'scroll-down-command)
+    (define-key map (kbd "SPC") #'scroll-up-command)
+    (define-key map (kbd ">") #'end-of-buffer)
+    (define-key map (kbd "<") #'beginning-of-buffer)
+    (define-key map (kbd "q") #'kill-this-buffer)
+    (define-key map (kbd "?") #'describe-mode)
+    map)
+  "Keymap for `markdown-view-mode'.")
+
+;;;###autoload
+(define-derived-mode markdown-view-mode markdown-mode "Markdown-View"
+  "Major mode for viewing Markdown content."
+  (setq-local markdown-hide-markup markdown-hide-markup-in-view-modes)
+  (read-only-mode 1))
+
+(defvar gfm-view-mode-map
+  markdown-view-mode-map
+  "Keymap for `gfm-view-mode'.")
+
+;;;###autoload
+(define-derived-mode gfm-view-mode gfm-mode "GFM-View"
+  "Major mode for viewing GitHub Flavored Markdown content."
+  (setq-local markdown-hide-markup markdown-hide-markup-in-view-modes)
+  (read-only-mode 1))
+
+
+;;; Live Preview Mode  ============================================
+;;;###autoload
+(define-minor-mode markdown-live-preview-mode
+  "Toggle native previewing on save for a specific markdown file."
+  :lighter " MD-Preview"
+  (if markdown-live-preview-mode
+      (if (markdown-live-preview-get-filename)
+          (markdown-display-buffer-other-window (markdown-live-preview-export))
+        (markdown-live-preview-mode -1)
+        (user-error "Buffer %s does not visit a file" (current-buffer)))
+    (markdown-live-preview-remove)))
+
+
+(provide 'markdown-mode)
+
+;; Local Variables:
+;; indent-tabs-mode: nil
+;; coding: utf-8
+;; End:
+;;; markdown-mode.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/markdown-mode-20180707.555/markdown-mode.elc b/configs/shared/emacs/.emacs.d/elpa/markdown-mode-20180707.555/markdown-mode.elc
new file mode 100644
index 0000000000..b71ef6c960
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/markdown-mode-20180707.555/markdown-mode.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/memoize-20180614.1230/memoize-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/memoize-20180614.1230/memoize-autoloads.el
new file mode 100644
index 0000000000..bf3913e1d1
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/memoize-20180614.1230/memoize-autoloads.el
@@ -0,0 +1,15 @@
+;;; memoize-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil nil ("memoize.el") (23377 61284 592486 442000))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; memoize-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/memoize-20180614.1230/memoize-pkg.el b/configs/shared/emacs/.emacs.d/elpa/memoize-20180614.1230/memoize-pkg.el
new file mode 100644
index 0000000000..4b541d8d43
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/memoize-20180614.1230/memoize-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "memoize" "20180614.1230" "Memoization functions" 'nil)
diff --git a/configs/shared/emacs/.emacs.d/elpa/memoize-20180614.1230/memoize.el b/configs/shared/emacs/.emacs.d/elpa/memoize-20180614.1230/memoize.el
new file mode 100644
index 0000000000..d45c5e4029
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/memoize-20180614.1230/memoize.el
@@ -0,0 +1,189 @@
+;;; memoize.el --- Memoization functions -*- lexical-binding: t; -*-
+
+;; This is free and unencumbered software released into the public domain.
+
+;; Author: Christopher Wellons <mosquitopsu@gmail.com>
+;; URL: https://github.com/skeeto/emacs-memoize
+;; Package-Version: 20180614.1230
+;; Version: 1.1
+
+;;; Commentary:
+
+;; `memoize' accepts a symbol or a function. When given a symbol, the
+;; symbol's function definition is memoized and installed overtop of
+;; the original function definition. When given a function, it returns
+;; a memoized version of that function.
+
+;;     (memoize 'my-expensive-function)
+
+;; `defmemoize' defines a memoized function directly, behaving just
+;; like `defun'.
+
+;;     (defmemoize my-expensive-function (x)
+;;       (if (zerop n)
+;;           1
+;;         (* n (my-expensive-function (1- n)))))
+
+;; Memoizing an interactive function will render that function
+;; non-interactive. It would be easy to fix this problem when it comes
+;; to non-byte-compiled functions, but recovering the interactive
+;; definition from a byte-compiled function is more complex than I
+;; care to deal with. Besides, interactive functions are always used
+;; for their side effects anyway.
+
+;; There's no way to memoize nil returns, but why would your expensive
+;; functions do all that work just to return nil? :-)
+
+;; Memoization takes up memory, which should be freed at some point.
+;; Because of this, all memoization has a timeout from when the last
+;; access was. The default timeout is set by
+;; `memoize-default-timeout'.  It can be overriden by using the
+;; `memoize' function, but the `defmemoize' macro will always just use
+;; the default timeout.
+
+;; If you wait to byte-compile the function until *after* it is
+;; memoized then the function and memoization wrapper both get
+;; compiled at once, so there's no special reason to do them
+;; separately. But there really isn't much advantage to compiling the
+;; memoization wrapper anyway.
+
+;;; Code:
+
+(require 'cl-lib)
+
+(defvar memoize-default-timeout "2 hours"
+  "The amount of time after which to remove a memoization.
+This represents the time after last use of the memoization after
+which the value is expired. Setting this to nil means to never
+expire, which will cause a memory leak, but may be acceptable for
+very careful uses.")
+
+(defun memoize (func &optional timeout)
+  "Memoize FUNC: a closure, lambda, or symbol.
+
+If argument is a symbol then install the memoized function over
+the original function. The TIMEOUT value, a timeout string as
+used by `run-at-time' will determine when the value expires, and
+will apply after the last access (unless another access
+happens)."
+  (cl-typecase func
+    (symbol
+     (when (get func :memoize-original-function)
+       (user-error "%s is already memoized" func))
+     (put func :memoize-original-documentation (documentation func))
+     (put func 'function-documentation
+          (concat (documentation func) " (memoized)"))
+     (put func :memoize-original-function (symbol-function func))
+     (fset func (memoize--wrap (symbol-function func) timeout))
+     func)
+    (function (memoize--wrap func timeout))))
+
+(defun memoize-restore (func)
+  "Restore the original, non-memoized definition of FUNC.
+FUNC should be a symbol which has been memoized with `memoize'."
+  (unless (get func :memoize-original-function)
+    (user-error "%s is not memoized" func))
+  (fset func (get func :memoize-original-function))
+  (put func :memoize-original-function nil)
+  (put func 'function-documentation
+       (get func :memoize-original-documentation))
+  (put func :memoize-original-documentation nil))
+
+(defun memoize--wrap (func timeout)
+  "Return the memoized version of FUNC.
+TIMEOUT specifies how long the values last from last access. A
+nil timeout will cause the values to never expire, which will
+cause a memory leak as memoize is use, so use the nil value with
+care."
+  (let ((table (make-hash-table :test 'equal))
+        (timeouts (make-hash-table :test 'equal)))
+    (lambda (&rest args)
+      (let ((value (gethash args table)))
+        (unwind-protect
+            (or value (puthash args (apply func args) table))
+          (let ((existing-timer (gethash args timeouts))
+                (timeout-to-use (or timeout memoize-default-timeout)))
+            (when existing-timer
+              (cancel-timer existing-timer))
+            (when timeout-to-use
+              (puthash args
+                       (run-at-time timeout-to-use nil
+                                    (lambda ()
+                                      (remhash args table))) timeouts))))))))
+
+(defmacro defmemoize (name arglist &rest body)
+  "Create a memoize'd function. NAME, ARGLIST, DOCSTRING and BODY
+have the same meaning as in `defun'."
+  (declare (indent defun))
+  `(progn
+     (defun ,name ,arglist
+       ,@body)
+     (memoize (quote ,name))))
+
+(defun memoize-by-buffer-contents (func)
+    "Memoize the given function by buffer contents.
+If argument is a symbol then install the memoized function over
+the original function."
+  (cl-typecase func
+    (symbol
+     (put func 'function-documentation
+          (concat (documentation func) " (memoized by buffer contents)"))
+     (fset func (memoize-by-buffer-contents--wrap (symbol-function func)))
+     func)
+    (function (memoize-by-buffer-contents--wrap func))))
+
+(defun memoize-by-buffer-contents--wrap (func)
+  "Return the memoization based on the buffer contents of FUNC.
+
+This form of memoization will be based off the current buffer
+contents. A different memoization is stored for all buffer
+contents, although old contents and no-longer-existant buffers
+will get garbage collected."
+  ;; We need 3 tables here to properly garbage collect. First is the
+  ;; table for the memoization itself, `memoization-table'. It holds a
+  ;; cons of the content hash and the function arguments.
+  ;;
+  ;; Buffer contents change often, though, so we want these entries to
+  ;; be automatically garbage collected when the buffer changes or the
+  ;; buffer goes away. To keep the entries around, we need to tie the
+  ;; content hash to the buffer, so that the content hash string
+  ;; doesn't go away until the buffer does. We do that with the
+  ;; `buffer-to-contents-table'.
+  ;;
+  ;; But even if the buffer content does change, we need to expire the
+  ;; memoization entries for that particular buffer content. So we
+  ;; have a `contents-to-memoization-table' that we use to tie the
+  ;; content hash to the memoization conses used as keys in the
+  ;; `memoization-table'.
+  ;;
+  ;; If a buffer's value changes, we make sure the next time we put a
+  ;; new value at the `buffer-to-contents-table', which causes the
+  ;; hash string to disappear. This causes the hash-string to
+  ;; disappear from the `contents-to-memoization-table', which causes
+  ;; the memoizations based on that content string to disappear from
+  ;; the `memoization-table'.
+  (let ((memoization-table (make-hash-table :test 'equal :weakness 'key))
+        (buffer-to-contents-table (make-hash-table :weakness 'key))
+        (contents-to-memoization-table (make-hash-table :weakness 'key)))
+    (lambda (&rest args)
+      (let* ((bufhash (secure-hash 'md5 (buffer-string)))
+             (memokey (cons bufhash args))
+             (value (gethash memokey memoization-table)))
+        (or value
+            (progn
+              (puthash (current-buffer) bufhash buffer-to-contents-table)
+              (puthash bufhash memokey contents-to-memoization-table)
+              (puthash memokey (apply func args) memoization-table)))))))
+
+(defmacro defmemoize-by-buffer-contents (name arglist &rest body)
+  "Create a memoize'd-by-buffer-contents function. NAME, ARGLIST,
+DOCSTRING and BODY have the same meaning as in `defun'."
+  (declare (indent defun))
+  `(progn
+     (defun ,name ,arglist
+       ,@body)
+     (memoize-by-buffer-contents (quote ,name))))
+
+(provide 'memoize)
+
+;;; memoize.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/memoize-20180614.1230/memoize.elc b/configs/shared/emacs/.emacs.d/elpa/memoize-20180614.1230/memoize.elc
new file mode 100644
index 0000000000..06dcbbfff9
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/memoize-20180614.1230/memoize.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-build.el b/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-build.el
new file mode 100644
index 0000000000..df85a676d6
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-build.el
@@ -0,0 +1,32 @@
+;;; nix-build.el -- run nix commands in Emacs -*- lexical-binding: t -*-
+
+;; Author: Matthew Bauer <mjbauer95@gmail.com>
+;; Homepage: https://github.com/NixOS/nix-mode
+;; Keywords: nix
+
+;; This file is NOT part of GNU Emacs.
+
+;;; Commentary:
+
+;;; Code:
+
+(require 'nix)
+(require 'nix-search)
+
+(defun nix-build (&optional file attr)
+  "Run nix-build in a compilation buffer.
+FILE the file to parse.
+ATTR the attribute to build."
+  (interactive (list (nix-read-file) nil))
+  (unless attr (setq attr (nix-read-attr file)))
+
+  (setq compile-command (format "%s %s -A '%s'" nix-build-executable
+				file attr))
+  (setq-default compilation-directory default-directory)
+  (compilation-start compile-command nil
+		     (apply-partially (lambda (attr _)
+					(format "*nix-build*<%s>" attr))
+				      attr)))
+
+(provide 'nix-build)
+;;; nix-build.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-build.elc b/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-build.elc
new file mode 100644
index 0000000000..1f0ed82959
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-build.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-drv-mode.el b/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-drv-mode.el
new file mode 100644
index 0000000000..b9e184270f
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-drv-mode.el
@@ -0,0 +1,48 @@
+;;; nix-drv-mode.el --- Major mode for viewing .drv files
+
+;; Maintainer: Matthew Bauer <mjbauer95@gmail.com>
+;; Homepage: https://github.com/NixOS/nix-mode
+;; Version: 1.2.1
+;; Keywords: nix, languages, tools, unix
+;; Package-Requires: ((emacs "24.3"))
+
+;; This file is NOT part of GNU Emacs.
+
+;;; Commentary:
+
+;; A major mode for viewing Nix derivations (.drv files). See the Nix
+;; manual for more information available at
+;; https://nixos.org/nix/manual/.
+
+;;; Code:
+
+(require 'json-mode)
+(require 'nix)
+
+(defvar-local nix-drv-mode nil)
+
+;;;###autoload
+(defun nix-drv-mode ()
+  "Pretty print Nix’s .drv files."
+  (interactive)
+  (when (string-match (format "^%s/" nix-store-dir) (buffer-file-name))
+    (if nix-drv-mode
+        (progn
+          (erase-buffer)
+          (insert-file-contents (buffer-file-name))
+          (setq nix-drv-mode nil)
+          (set-buffer-modified-p nil)
+          (read-only-mode nil))
+      (let ((inhibit-read-only t))
+        (setq nix-drv-mode t)
+        (erase-buffer)
+        (insert (shell-command-to-string
+                 (format "%s show-derivation \"%s\""
+		         nix-executable
+		         (buffer-file-name))))
+        (json-mode)
+        (set-buffer-modified-p nil)
+        (read-only-mode 1)))))
+
+(provide 'nix-drv-mode)
+;;; nix-drv-mode.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-drv-mode.elc b/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-drv-mode.elc
new file mode 100644
index 0000000000..43eab55d29
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-drv-mode.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-edit.el b/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-edit.el
new file mode 100644
index 0000000000..3e5c255f34
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-edit.el
@@ -0,0 +1,37 @@
+;;; nix-edit.el -- run nix commands in Emacs -*- lexical-binding: t -*-
+
+;; Author: Matthew Bauer <mjbauer95@gmail.com>
+;; Homepage: https://github.com/NixOS/nix-mode
+;; Keywords: nix
+
+;; This file is NOT part of GNU Emacs.
+
+;;; Commentary:
+
+;;; Code:
+
+(require 'nix)
+(require 'nix-search)
+
+(defun nix-edit (&optional file attr)
+  "Open the nix log.
+FILE the nix file to load from.
+ATTR the attribute to find in nix expressions."
+  (interactive (list (nix-read-file) nil))
+  (unless attr (setq attr (nix-read-attr file)))
+
+  (let ((stdout (generate-new-buffer "nix-edit"))
+        (process-environment (cons "EDITOR=echo" process-environment))
+	result)
+    (call-process nix-executable nil (list stdout nil) nil
+		  "edit" "-f" file attr)
+    (with-current-buffer stdout
+      (when (eq (buffer-size) 0)
+	(error
+	 "Error: nix edit failed to produce any output"))
+      (setq result (substring (buffer-string) 0 (- (buffer-size) 1))))
+    (kill-buffer stdout)
+    (find-file result)))
+
+(provide 'nix-edit)
+;;; nix-edit.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-edit.elc b/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-edit.elc
new file mode 100644
index 0000000000..474ed1fe99
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-edit.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-format.el b/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-format.el
new file mode 100644
index 0000000000..e9a65a6a41
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-format.el
@@ -0,0 +1,35 @@
+;;; nix-format.el --- Nix formatter -*- lexical-binding: t -*-
+
+;; This file is NOT part of GNU Emacs.
+
+;;; Commentary:
+
+;;; Code:
+
+(defcustom nix-nixfmt-bin "nixfmt"
+  "Path to nixfmt executable."
+  :group 'nix
+  :type 'string)
+
+(defun nix--format-call (buf)
+  "Format BUF using nixfmt."
+  (with-current-buffer (get-buffer-create "*nixfmt*")
+    (erase-buffer)
+    (insert-buffer-substring buf)
+    (if (zerop (call-process-region (point-min) (point-max) nix-nixfmt-bin t t nil))
+        (progn
+          (if (not (string= (buffer-string) (with-current-buffer buf (buffer-string))))
+              (copy-to-buffer buf (point-min) (point-max)))
+          (kill-buffer))
+      (error "Nixfmt failed, see *nixfmt* buffer for details"))))
+
+(defun nix-format-buffer ()
+  "Format the current buffer using nixfmt."
+  (interactive)
+  (unless (executable-find nix-nixfmt-bin)
+    (error "Could not locate executable \"%s\"" nix-nixfmt-bin))
+  (nix--format-call (current-buffer))
+  (message "Formatted buffer with nixfmt."))
+
+(provide 'nix-format)
+;;; nix-format.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-format.elc b/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-format.elc
new file mode 100644
index 0000000000..8183f8f4b8
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-format.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-instantiate.el b/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-instantiate.el
new file mode 100644
index 0000000000..899ec9790b
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-instantiate.el
@@ -0,0 +1,104 @@
+;;; nix-instantiate.el -- run nix commands in Emacs -*- lexical-binding: t -*-
+
+;; Author: Matthew Bauer <mjbauer95@gmail.com>
+;; Homepage: https://github.com/NixOS/nix-mode
+;; Keywords: nix
+
+;; This file is NOT part of GNU Emacs.
+
+;;; Commentary:
+
+;;; Code:
+
+(require 'nix)
+(require 'json)
+
+(defun nix-instantiate--parsed (drv)
+  "Get the parsed version of the .drv file.
+DRV file to load from."
+  (let ((stdout (generate-new-buffer "nix show-derivation"))
+	result)
+    (call-process nix-executable nil (list stdout nil) nil
+		  "show-derivation" drv)
+    (setq result
+	  (cdar (with-current-buffer stdout
+		  (when (eq (buffer-size) 0)
+		    (error "Nix’s show-derivation %s failed to produce any output"
+			   drv))
+		  (goto-char (point-min))
+		  (json-read))))
+    (kill-buffer stdout)
+    result))
+
+(defun nix-instantiate (nix-file &optional attribute parse)
+  "Run nix-instantiate on a Nix expression.
+NIX-FILE the file to instantiate.
+ATTRIBUTE an attribute of the Nix file to use.
+PARSE whether to parse nix-instantiate output."
+  (interactive (list (read-file-name "Nix file: ") nil t))
+
+  (let ((stdout (generate-new-buffer "nix-instantiate"))
+	result)
+    (if attribute
+	(call-process nix-instantiate-executable nil (list stdout nil) nil
+		      nix-file "-A" attribute)
+      (call-process nix-instantiate-executable nil (list stdout nil) nil
+		    nix-file))
+    (with-current-buffer stdout
+      (when (eq (buffer-size) 0)
+	(error
+	 "Error: nix-instantiate %s failed to produce any output"
+	 nix-file))
+      (setq result (substring (buffer-string) 0 (- (buffer-size) 1)))
+      (when parse
+	(setq result (nix-instantiate--parsed result))))
+    (kill-buffer stdout)
+    result))
+
+(defvar nix-instantiate--running-processes nil)
+
+(defun nix-instantiate--sentinel (prop err proc event)
+  "Make a nix-instantiate process.
+PROP the prop name of nix-instantiate--running-processes.
+ERR the error buffer.
+PROC the process that has been run.
+EVENT the event that was fired."
+  (when (string= event "finished\n")
+    (with-current-buffer (process-buffer proc)
+      (unless (eq (buffer-size) 0)
+	(let ((drv (nix-instantiate--parsed
+		    (substring (buffer-string) 0 (- (buffer-size) 1)))))
+	  (dolist
+	      (callback (lax-plist-get nix-instantiate--running-processes prop))
+	    (funcall callback drv)))))
+    (setq nix-instantiate--running-processes
+	  (lax-plist-put nix-instantiate--running-processes prop nil)))
+  (unless (process-live-p proc)
+    (kill-buffer (process-buffer proc))
+    (kill-buffer err)))
+
+(defun nix-instantiate-async (callback nix-file &optional attribute)
+  "Run nix-instantiate on a Nix expression, asynchronously.
+CALLBACK the function to call when instantiate completes.
+NIX-FILE the file to instantiate
+ATTRIBUTE an attribute of the Nix file to use."
+  (setq nix-file (expand-file-name nix-file))
+  (let* ((prop (if attribute
+		   (expand-file-name attribute nix-file) nix-file))
+	 (data (lax-plist-get nix-instantiate--running-processes prop))
+	 (stdout (generate-new-buffer "nix-instantiate"))
+	 (stderr (generate-new-buffer "nix-instantiate error")))
+    (setq nix-instantiate--running-processes
+	  (lax-plist-put nix-instantiate--running-processes
+			 prop (cons callback data)))
+    (make-process
+     :name "nix-instantiate"
+     :buffer stdout
+     :command (append (list nix-instantiate-executable nix-file)
+		      (when attribute (list "-A" attribute)))
+     :noquery t
+     :sentinel (apply-partially 'nix-instantiate--sentinel prop stderr)
+     :stderr stderr)))
+
+(provide 'nix-instantiate)
+;;; nix-instantiate.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-instantiate.elc b/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-instantiate.elc
new file mode 100644
index 0000000000..ef8c7fd20d
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-instantiate.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-log.el b/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-log.el
new file mode 100644
index 0000000000..192ab3170e
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-log.el
@@ -0,0 +1,36 @@
+;;; nix-log.el -- run nix commands in Emacs -*- lexical-binding: t -*-
+
+;; Author: Matthew Bauer <mjbauer95@gmail.com>
+;; Homepage: https://github.com/NixOS/nix-mode
+;; Keywords: nix
+
+;; This file is NOT part of GNU Emacs.
+
+;;; Commentary:
+
+;;; Code:
+
+(require 'nix)
+(require 'nix-search)
+(require 'nix-instantiate)
+
+(defun nix-log (file attr)
+  "Open the nix log.
+FILE nix file to parse.
+ATTR attribute to load the log of."
+  (interactive (list (nix-read-file) nil))
+  (unless attr (setq attr (nix-read-attr file)))
+
+  (let* ((drv-file (nix-instantiate file attr))
+         (drv-name (progn
+                     (string-match (format "^%s/\\(.*\\)$" nix-store-dir) drv-file)
+                     (match-string 1 drv-file)))
+         (log-file (format "%s/log/nix/drvs/%s/%s.bz2"
+                           nix-state-dir
+                           (substring drv-name 0 2) drv-name)))
+    (if (file-exists-p log-file)
+        (find-file log-file)
+      (error "No log is available for derivation"))))
+
+(provide 'nix-log)
+;;; nix-log.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-log.elc b/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-log.elc
new file mode 100644
index 0000000000..ca73de44c9
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-log.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-mode-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-mode-autoloads.el
new file mode 100644
index 0000000000..79b762d46d
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-mode-autoloads.el
@@ -0,0 +1,190 @@
+;;; nix-mode-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "nix" "nix.el" (23430 41818 774263 912000))
+;;; Generated autoloads from nix.el
+
+(autoload 'pcomplete/nix "nix" "\
+Completion for the nix command.
+
+\(fn)" nil nil)
+
+;;;***
+
+;;;### (autoloads nil "nix-drv-mode" "nix-drv-mode.el" (23430 41818
+;;;;;;  763128 639000))
+;;; Generated autoloads from nix-drv-mode.el
+
+(autoload 'nix-drv-mode "nix-drv-mode" "\
+Pretty print Nix’s .drv files.
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "nix-mode" "nix-mode.el" (23430 41818 769555
+;;;;;;  1000))
+;;; Generated autoloads from nix-mode.el
+
+(autoload 'nix-indent-line "nix-mode" "\
+Indent current line in a Nix expression.
+
+\(fn)" t nil)
+
+(autoload 'nix-mode "nix-mode" "\
+Major mode for editing Nix expressions.
+
+The following commands may be useful:
+
+  '\\[newline-and-indent]'
+    Insert a newline and move the cursor to align with the previous
+    non-empty line.
+
+  '\\[fill-paragraph]'
+    Refill a paragraph so that all lines are at most `fill-column'
+    lines long.  This should do the right thing for comments beginning
+    with `#'.  However, this command doesn't work properly yet if the
+    comment is adjacent to code (i.e., no intervening empty lines).
+    In that case, select the text to be refilled and use
+    `\\[fill-region]' instead.
+
+The hook `nix-mode-hook' is run when Nix mode is started.
+
+\\{nix-mode-map}
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "nix-prettify-mode" "nix-prettify-mode.el"
+;;;;;;  (23430 41818 767901 837000))
+;;; Generated autoloads from nix-prettify-mode.el
+
+(autoload 'nix-prettify-mode "nix-prettify-mode" "\
+Toggle Nix Prettify mode.
+
+With a prefix argument ARG, enable Nix Prettify mode if ARG is
+positive, and disable it otherwise.  If called from Lisp, enable
+the mode if ARG is omitted or nil.
+
+When Nix Prettify mode is enabled, hash-parts of the Nix store
+file names (see `nix-prettify-regexp') are prettified,
+i.e. displayed as `nix-prettify-char' character.  This mode can
+be enabled programmatically using hooks:
+
+  (add-hook 'shell-mode-hook 'nix-prettify-mode)
+
+It is possible to enable the mode in any buffer, however not any
+buffer's highlighting may survive after adding new elements to
+`font-lock-keywords' (see `nix-prettify-special-modes' for
+details).
+
+Also you can use `global-nix-prettify-mode' to enable Nix
+Prettify mode for all modes that support font-locking.
+
+\(fn &optional ARG)" t nil)
+
+(defvar nix-prettify-global-mode nil "\
+Non-nil if Nix-Prettify-Global mode is enabled.
+See the `nix-prettify-global-mode' command
+for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `nix-prettify-global-mode'.")
+
+(custom-autoload 'nix-prettify-global-mode "nix-prettify-mode" nil)
+
+(autoload 'nix-prettify-global-mode "nix-prettify-mode" "\
+Toggle Nix-Prettify mode in all buffers.
+With prefix ARG, enable Nix-Prettify-Global mode if ARG is positive;
+otherwise, disable it.  If called from Lisp, enable the mode if
+ARG is omitted or nil.
+
+Nix-Prettify mode is enabled in all buffers where
+`nix-prettify-turn-on' would do it.
+See `nix-prettify-mode' for more information on Nix-Prettify mode.
+
+\(fn &optional ARG)" t nil)
+
+(define-obsolete-function-alias 'global-nix-prettify-mode 'nix-prettify-global-mode)
+
+;;;***
+
+;;;### (autoloads nil "nix-repl" "nix-repl.el" (23430 41818 771127
+;;;;;;  391000))
+;;; Generated autoloads from nix-repl.el
+
+(autoload 'nix-repl "nix-repl" "\
+Load the Nix-REPL.
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "nix-search" "nix-search.el" (23430 41818 761247
+;;;;;;  123000))
+;;; Generated autoloads from nix-search.el
+
+(autoload 'nix-search "nix-search" "\
+Run nix search.
+SEARCH a search term to use.
+FILE a Nix expression to search in.
+
+\(fn &optional SEARCH FILE)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "nix-shell" "nix-shell.el" (23430 41818 778535
+;;;;;;  603000))
+;;; Generated autoloads from nix-shell.el
+
+(autoload 'nix-shell-unpack "nix-shell" "\
+Run Nix’s unpackPhase.
+FILE is the file to unpack from.
+ATTR is the attribute to unpack.
+
+\(fn FILE ATTR)" t nil)
+
+(autoload 'nix-shell-configure "nix-shell" "\
+Run Nix’s configurePhase.
+FILE is the file to configure from.
+ATTR is the attribute to configure.
+
+\(fn FILE ATTR)" t nil)
+
+(autoload 'nix-shell-build "nix-shell" "\
+Run Nix’s buildPhase.
+FILE is the file to build from.
+ATTR is the attribute to build.
+
+\(fn FILE ATTR)" t nil)
+
+(autoload 'nix-shell-with-string "nix-shell" "\
+A nix-shell emulator in Emacs from a string.
+STRING the nix expression to use.
+
+\(fn STRING)" nil nil)
+
+(autoload 'nix-shell "nix-shell" "\
+A nix-shell emulator in Emacs.
+FILE the file to instantiate.
+ATTR an attribute of the Nix file to use.
+
+\(fn FILE &optional ATTR)" t nil)
+
+;;;***
+
+;;;### (autoloads nil nil ("nix-build.el" "nix-edit.el" "nix-format.el"
+;;;;;;  "nix-instantiate.el" "nix-log.el" "nix-mode-pkg.el" "nix-shebang.el"
+;;;;;;  "nix-store.el") (23430 41818 781257 265000))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; nix-mode-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-mode-pkg.el b/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-mode-pkg.el
new file mode 100644
index 0000000000..4a75d4c57f
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-mode-pkg.el
@@ -0,0 +1,10 @@
+(define-package "nix-mode" "20180822.214" "Major mode for editing .nix files"
+  '((emacs "24.3"))
+  :keywords
+  '("nix" "languages" "tools" "unix")
+  :maintainer
+  '("Matthew Bauer" . "mjbauer95@gmail.com")
+  :url "https://github.com/NixOS/nix-mode")
+;; Local Variables:
+;; no-byte-compile: t
+;; End:
diff --git a/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-mode.el b/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-mode.el
new file mode 100644
index 0000000000..ea29241184
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-mode.el
@@ -0,0 +1,510 @@
+;;; nix-mode.el --- Major mode for editing .nix files -*- lexical-binding: t -*-
+
+;; Maintainer: Matthew Bauer <mjbauer95@gmail.com>
+;; Homepage: https://github.com/NixOS/nix-mode
+;; Version: 1.2.1
+;; Keywords: nix, languages, tools, unix
+;; Package-Requires: ((emacs "24.3"))
+
+;; This file is NOT part of GNU Emacs.
+
+;;; Commentary:
+
+;; A major mode for editing Nix expressions (.nix files).  See the Nix manual
+;; for more information available at https://nixos.org/nix/manual/.
+
+;;; Code:
+
+(require 'nix)
+(require 'nix-format)
+(require 'nix-shebang)
+(require 'nix-shell)
+(require 'nix-repl)
+
+(defgroup nix-mode nil
+  "Nix mode customizations"
+  :group 'nix)
+
+(defcustom nix-indent-function 'indent-relative
+  "The function to use to indent.
+
+Valid functions for this are:
+
+- ‘indent-relative’
+- nix-indent-line (buggy)"
+  :group 'nix-mode
+  :type 'function)
+
+(defgroup nix-faces nil
+  "Nix faces."
+  :group 'nix-mode
+  :group 'faces)
+
+(defface nix-keyword-face
+  '((t :inherit font-lock-keyword-face))
+  "Face used to highlight Nix keywords."
+  :group 'nix-faces)
+
+(defface nix-keyword-warning-face
+  '((t :inherit font-lock-warning-face))
+  "Face used to highlight Nix warning keywords."
+  :group 'nix-faces)
+
+(defface nix-builtin-face
+  '((t :inherit font-lock-builtin-face))
+  "Face used to highlight Nix builtins."
+  :group 'nix-faces)
+
+(defface nix-constant-face
+  '((t :inherit font-lock-constant-face))
+  "Face used to highlight Nix constants."
+  :group 'nix-faces)
+
+(defface nix-attribute-face
+  '((t :inherit font-lock-variable-name-face))
+  "Face used to highlight Nix attributes."
+  :group 'nix-faces)
+
+(defface nix-antiquote-face
+  '((t :inherit font-lock-preprocessor-face))
+  "Face used to highlight Nix antiquotes."
+  :group 'nix-faces)
+
+(defvar nix-system-types
+  '("x86_64-linux" "i686-linux" "aarch64-linux" "x86_64-darwin")
+  "List of supported systems.")
+
+;;; Syntax coloring
+
+(defconst nix-keywords
+  '("if" "then"
+    "else" "with"
+    "let" "in"
+    "rec" "inherit"
+    "or"))
+
+(defconst nix-builtins
+  '("builtins" "baseNameOf"
+    "derivation" "dirOf"
+    "true" "false" "null"
+    "isNull" "toString"
+    "fetchTarball" "import"
+    "map" "removeAttrs"))
+
+(defconst nix-warning-keywords
+  '("assert" "abort" "throw"))
+
+(defconst nix-re-file-path
+  "[a-zA-Z0-9._\\+-]*\\(/[a-zA-Z0-9._\\+-]+\\)+")
+
+(defconst nix-re-url
+  "[a-zA-Z][a-zA-Z0-9\\+-\\.]*:[a-zA-Z0-9%/\\?:@&=\\+\\$,_\\.!~\\*'-]+")
+
+(defconst nix-re-bracket-path
+  "<[a-zA-Z0-9._\\+-]+\\(/[a-zA-Z0-9._\\+-]+\\)*>")
+
+(defconst nix-re-variable-assign
+  "\\<\\([a-zA-Z_][a-zA-Z0-9_'\-\.]*\\)[ \t]*=[^=]")
+
+(defconst nix-font-lock-keywords
+  `(
+    (,(regexp-opt nix-keywords 'symbols) 0 'nix-keyword-face)
+    (,(regexp-opt nix-warning-keywords 'symbols) 0 'nix-keyword-warning-face)
+    (,(regexp-opt nix-builtins 'symbols) 0 'nix-builtin-face)
+    (,nix-re-url 0 'nix-constant-face)
+    (,nix-re-file-path 0 'nix-constant-face)
+    (,nix-re-variable-assign 1 'nix-attribute-face)
+    (,nix-re-bracket-path 0 'nix-constant-face)
+    (nix--syntax-match-antiquote 0 'nix-antiquote-face t)
+    )
+  "Font lock keywords for nix.")
+
+(defconst nix--variable-char "[a-zA-Z0-9_'\-]")
+
+(defvar nix-mode-abbrev-table
+  (make-abbrev-table)
+  "Abbrev table for Nix mode.")
+
+(makunbound 'nix-mode-syntax-table)
+
+(defvar nix-mode-syntax-table
+  (let ((table (make-syntax-table)))
+    (modify-syntax-entry ?/ ". 14" table)
+    (modify-syntax-entry ?* ". 23" table)
+    (modify-syntax-entry ?# "< b" table)
+    (modify-syntax-entry ?\n "> b" table)
+    ;; We handle strings
+    (modify-syntax-entry ?\" "." table)
+    ;; We handle escapes
+    (modify-syntax-entry ?\\ "." table)
+    table)
+  "Syntax table for Nix mode.")
+
+(defun nix--syntax-match-antiquote (limit)
+  "Find antiquote within a Nix expression up to LIMIT."
+  (unless (> (point) limit)
+    (if (get-text-property (point) 'nix-syntax-antiquote)
+        (progn
+          (set-match-data (list (point) (1+ (point))))
+          (forward-char 1)
+          t)
+      (let ((pos (next-single-char-property-change (point) 'nix-syntax-antiquote
+                                                   nil limit)))
+        (when (and pos (not (> pos limit)))
+          (goto-char pos)
+          (let ((char (char-after pos)))
+            (pcase char
+              (`?{
+               (forward-char 1)
+               (set-match-data (list (1- pos) (point)))
+               t)
+              (`?}
+               (forward-char 1)
+               (set-match-data (list pos (point)))
+               t))))))))
+
+(defun nix--mark-string (pos string-type)
+  "Mark string as a Nix string.
+
+POS position of start of string
+STRING-TYPE type of string based off of Emacs syntax table types"
+  (put-text-property pos (1+ pos)
+                     'syntax-table (string-to-syntax "|"))
+  (put-text-property pos (1+ pos)
+                     'nix-string-type string-type))
+
+(defun nix--get-parse-state (pos)
+  "Get the result of `syntax-ppss' at POS."
+  (save-excursion (save-match-data (syntax-ppss pos))))
+
+(defun nix--get-string-type (parse-state)
+  "Get the type of string based on PARSE-STATE."
+  (let ((string-start (nth 8 parse-state)))
+    (and string-start (get-text-property string-start 'nix-string-type))))
+
+(defun nix--open-brace-string-type (parse-state)
+  "Determine if this is an open brace string type based on PARSE-STATE."
+  (let ((open-brace (nth 1 parse-state)))
+    (and open-brace (get-text-property open-brace 'nix-string-type))))
+
+(defun nix--open-brace-antiquote-p (parse-state)
+  "Determine if this is an open brace antiquote based on PARSE-STATE."
+  (let ((open-brace (nth 1 parse-state)))
+    (and open-brace (get-text-property open-brace 'nix-syntax-antiquote))))
+
+(defun nix--single-quotes ()
+  "Handle Nix single quotes."
+  (let* ((start (match-beginning 0))
+         (end (match-end 0))
+         (context (nix--get-parse-state start))
+         (string-type (nix--get-string-type context)))
+    (unless (or (equal string-type ?\")
+                (and (equal string-type nil)
+                     (< 1 start)
+                     (string-match-p nix--variable-char
+                                     (buffer-substring (1- start) start))))
+      (when (equal string-type nil)
+        (nix--mark-string start ?\')
+        (setq start (+ 2 start)))
+      (when (equal (mod (- end start) 3) 2)
+        (let ((str-peek (buffer-substring end (min (point-max) (+ 2 end)))))
+          (if (member str-peek '("${" "\\n" "\\r" "\\t"))
+              (goto-char (+ 2 end))
+            (nix--mark-string (1- end) ?\')))))))
+
+(defun nix--escaped-antiquote-dq-style ()
+  "Handle Nix escaped antiquote dq style."
+  (let* ((start (match-beginning 0))
+         (ps (nix--get-parse-state start))
+         (string-type (nix--get-string-type ps)))
+    (when (equal string-type ?\')
+      (nix--antiquote-open-at (1+ start) ?\'))))
+
+(defun nix--double-quotes ()
+  "Handle Nix double quotes."
+  (let* ((pos (match-beginning 0))
+         (ps (nix--get-parse-state pos))
+         (string-type (nix--get-string-type ps)))
+    (unless (equal string-type ?\')
+      (nix--mark-string pos ?\"))))
+
+(defun nix--antiquote-open-at (pos string-type)
+  "Handle Nix antiquote open at based on POS and STRING-TYPE."
+  (put-text-property pos (1+ pos)
+                     'syntax-table (string-to-syntax "|"))
+  (put-text-property pos (+ 2 pos)
+                     'nix-string-type string-type)
+  (put-text-property (1+ pos) (+ 2 pos)
+                     'nix-syntax-antiquote t))
+
+(defun nix--antiquote-open ()
+  "Handle Nix antiquote open."
+  (let* ((start (match-beginning 0))
+         (ps (nix--get-parse-state start))
+         (string-type (nix--get-string-type ps)))
+    (when string-type
+      (nix--antiquote-open-at start string-type))))
+
+(defun nix--antiquote-close-open ()
+  "Handle Nix antiquote close then open."
+  (let* ((start (match-beginning 0))
+         (ps (nix--get-parse-state start))
+         (string-type (nix--get-string-type ps)))
+    (if string-type
+        (nix--antiquote-open-at (1+ start) string-type)
+      (when (nix--open-brace-antiquote-p ps)
+        (let ((string-type (nix--open-brace-string-type ps)))
+          (put-text-property start (+ 3 start)
+                             'nix-string-type string-type)
+          (put-text-property start (1+ start)
+                             'nix-syntax-antiquote t)
+          (put-text-property (+ 2 start) (+ 3 start)
+                             'nix-syntax-antiquote t))))))
+
+(defun nix--antiquote-close ()
+  "Handle Nix antiquote close."
+  (let* ((start (match-beginning 0))
+         (ps (nix--get-parse-state start)))
+    (unless (nix--get-string-type ps)
+      (let ((string-type (nix--open-brace-string-type ps)))
+        (when string-type
+          (put-text-property start (1+ start)
+                             'nix-string-type string-type)
+          (put-text-property start (1+ start)
+                             'nix-syntax-antiquote t)
+          (let ((ahead (buffer-substring (1+ start) (min (point-max) (+ 5 start)))))
+            (pcase string-type
+              (`?\" (cond
+                     ((or (string-match "^\\\\\"" ahead)
+                          (string-match "^\\\\\\${" ahead))
+                      (nix--mark-string (1+ start) string-type)
+                      (goto-char (+ start (match-end 0) 1)))
+                     ((string-match-p "^\"" ahead)
+                      (goto-char (+ 2 start)))
+                     ((< (1+ start) (point-max))
+                      (nix--mark-string (1+ start) string-type)
+                      (goto-char (+ 2 start)))))
+              (`?\' (cond
+                     ((or (string-match "^'''" ahead)
+                          (string-match "^''\\${" ahead)
+                          (string-match "^''\\\\[nrt]" ahead))
+                      (nix--mark-string (1+ start) string-type)
+                      (goto-char (+ start (match-end 0) 1)))
+                     ((string-match-p "^''" ahead)
+                      (goto-char (+ 3 start)))
+                     ((< (1+ start) (point-max))
+                      (nix--mark-string (1+ start) string-type)
+                      (goto-char (+ 2 start))))))))))))
+
+(defun nix-syntax-propertize (start end)
+  "Special syntax properties for Nix from START to END."
+  (goto-char start)
+  (remove-text-properties start end
+                          '(syntax-table nil nix-string-type nil nix-syntax-antiquote nil))
+  (funcall
+   (syntax-propertize-rules
+    ("\\\\\\\\"
+     (0 nil))
+    ("\\\\\""
+     (0 nil))
+    ("\\\\\\${"
+     (0 (ignore (nix--escaped-antiquote-dq-style))))
+    ("'\\{2,\\}"
+     (0 (ignore (nix--single-quotes))))
+    ("}\\${"
+     (0 (ignore (nix--antiquote-close-open))))
+    ("\\${"
+     (0 (ignore (nix--antiquote-open))))
+    ("}"
+     (0 (ignore (nix--antiquote-close))))
+    ("\""
+     (0 (ignore (nix--double-quotes)))))
+   start end))
+
+;;; Indentation
+
+(defun nix--inside-string-or-comment ()
+  (or (nix--get-string-type (nix--get-parse-state (point)))
+      (nth 4 (syntax-ppss))))
+(defun nix-find-backward-matching-token ()
+  (cond
+   ((looking-at "in\\b")
+    (let ((counter 1))
+      (while (and (> counter 0) (re-search-backward "\\b\\(let\\|in\\)\\b" nil t))
+        (unless (nix--inside-string-or-comment)
+          (setq counter (cond ((looking-at "let") (- counter 1))
+                              ((looking-at "in") (+ counter 1))))
+          )
+        )
+      counter ))
+   ((looking-at "}")
+    (backward-up-list) t)
+   ((looking-at "]")
+    (backward-up-list) t)
+   ((looking-at ")")
+    (backward-up-list) t)
+   ))
+(defun nix-indent-to-backward-match ()
+  (let ((matching-indentation (save-excursion
+                                (beginning-of-line)
+                                (skip-chars-forward "[:space:]")
+                                (if (nix-find-backward-matching-token)
+                                    (current-indentation)))))
+    (when matching-indentation (indent-line-to matching-indentation) t))
+  )
+
+(defun nix-indent-find-BOL-expression-start ()
+  (beginning-of-line)
+  (let ((counter 1))
+    (while (and (> counter 0) (re-search-backward "\\(;\\|=\\|inherit\\|with\\b\\)" nil t))
+      (unless (nix--inside-string-or-comment)
+        (setq counter (cond ((looking-at "with\\|=\\|inherit") (- counter 1))
+                            ((looking-at ";") (+ counter 1))))
+        )
+      )
+      (when (/= counter 0) (goto-char (point-min))) t))
+
+(defun nix-indent-expression-start ()
+  (let ((matching-indentation (save-excursion (when (nix-indent-find-BOL-expression-start)
+                                                (current-indentation)))))
+    (when matching-indentation
+      (if (save-excursion (beginning-of-line)
+                          (skip-chars-forward "[:space:]")
+                          (looking-at "let\\|with\\|\\[\\|{\\|("))
+          (indent-line-to matching-indentation)
+        (indent-line-to (+ tab-width matching-indentation)))
+      t)))
+
+(defun nix-indent-prev-level ()
+  "Get the indent level of the previous line."
+  (save-excursion
+    (beginning-of-line)
+    (skip-chars-backward "\n[:space:]")
+    (current-indentation)))
+
+;;;###autoload
+(defun nix-indent-line ()
+  "Indent current line in a Nix expression."
+  (interactive)
+  (let ((end-of-indentation (save-excursion
+  (cond
+
+   ;; comment
+   ((save-excursion
+      (beginning-of-line)
+      (nth 4 (syntax-ppss)))
+    (indent-line-to (nix-indent-prev-level)))
+
+   ;; string
+   ((save-excursion
+      (beginning-of-line)
+      (nth 3 (syntax-ppss)))
+    (indent-line-to (+ (nix-indent-prev-level)
+                       (* tab-width (+ (if (save-excursion
+                                             (forward-line -1)
+                                             (end-of-line)
+                                             (skip-chars-backward "[:space:]")
+                                             (looking-back "''" 0)) 1 0)
+                                       (if (save-excursion
+                                             (beginning-of-line)
+                                             (skip-chars-forward
+                                              "[:space:]")
+                                             (looking-at "''")
+                                             ) -1 0)
+                                       )))))
+
+   ;; dedent '}', ']', ')' 'in'
+   ((nix-indent-to-backward-match))
+
+   ;; indent between = and ; + 2, or to 2
+   ((nix-indent-expression-start))
+
+   ;; else
+   (t
+      (indent-line-to (nix-indent-prev-level)))
+   )
+  (point))))
+    (when (> end-of-indentation (point)) (goto-char end-of-indentation)))
+  )
+
+;; Key maps
+
+(defvar nix-mode-menu (make-sparse-keymap "Nix")
+  "Menu for Nix mode.")
+
+(defvar nix-mode-map (make-sparse-keymap)
+  "Local keymap used for Nix mode.")
+
+(defun nix-create-keymap ()
+  "Create the keymap associated with the Nix mode."
+  )
+
+(defun nix-create-menu ()
+  "Create the Nix menu as shown in the menu bar."
+  (let ((m '("Nix"
+             ["Format buffer" nix-format-buffer t])
+           ))
+    (easy-menu-define ada-mode-menu nix-mode-map "Menu keymap for Nix mode" m)))
+
+(nix-create-keymap)
+(nix-create-menu)
+
+;;;###autoload
+(define-derived-mode nix-mode prog-mode "Nix"
+  "Major mode for editing Nix expressions.
+
+The following commands may be useful:
+
+  '\\[newline-and-indent]'
+    Insert a newline and move the cursor to align with the previous
+    non-empty line.
+
+  '\\[fill-paragraph]'
+    Refill a paragraph so that all lines are at most `fill-column'
+    lines long.  This should do the right thing for comments beginning
+    with `#'.  However, this command doesn't work properly yet if the
+    comment is adjacent to code (i.e., no intervening empty lines).
+    In that case, select the text to be refilled and use
+    `\\[fill-region]' instead.
+
+The hook `nix-mode-hook' is run when Nix mode is started.
+
+\\{nix-mode-map}
+"
+  :group 'nix-mode
+  :syntax-table nix-mode-syntax-table
+  :abbrev-table nix-mode-abbrev-table
+
+  ;; Disable hard tabs and set tab to 2 spaces
+  ;; Recommended by nixpkgs manual: https://nixos.org/nixpkgs/manual/#sec-syntax
+  (setq-local indent-tabs-mode nil)
+  (setq-local tab-width 2)
+  (setq-local electric-indent-chars '(?\n ?{ ?} ?\[ ?\] ?\( ?\)))
+
+  ;; Font lock support.
+  (setq-local font-lock-defaults '(nix-font-lock-keywords))
+
+  ;; Special syntax properties for Nix
+  (setq-local syntax-propertize-function 'nix-syntax-propertize)
+
+  ;; Look at text properties when parsing
+  (setq-local parse-sexp-lookup-properties t)
+
+  ;; Automatic indentation [C-j]
+  (setq-local indent-line-function nix-indent-function)
+
+  ;; Indenting of comments
+  (setq-local comment-start "# ")
+  (setq-local comment-end "")
+  (setq-local comment-start-skip "\\(^\\|\\s-\\);?#+ *")
+  (setq-local comment-multi-line t)
+
+  ;; Filling of comments
+  (setq-local adaptive-fill-mode t)
+  (setq-local paragraph-start "[ \t]*\\(#+[ \t]*\\)?$")
+  (setq-local paragraph-separate paragraph-start)
+
+  (easy-menu-add nix-mode-menu nix-mode-map))
+
+(provide 'nix-mode)
+;;; nix-mode.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-mode.elc b/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-mode.elc
new file mode 100644
index 0000000000..35f95a2176
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-mode.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-prettify-mode.el b/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-prettify-mode.el
new file mode 100644
index 0000000000..99fa9e270c
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-prettify-mode.el
@@ -0,0 +1,202 @@
+;;; nix-prettify.el -- Prettify Nix store file names  -*- lexical-binding: t -*-
+
+;; Copyright © 2014, 2015 Alex Kost <alezost@gmail.com>
+;; Modified by Matthew Bauer for use in nix-mode
+
+;; Author: Alex Kost
+;; Maintainer: Matthew Bauer <mjbauer95@gmail.com>
+;; Homepage: https://github.com/NixOS/nix-mode
+;; Version: 1.1
+;; Keywords: nix
+
+;; This file is NOT part of GNU Emacs.
+
+;;; Commentary:
+
+;; This package provides minor-mode for prettifying Nix store file
+;; names — i.e., after enabling `nix-prettify-mode',
+;; '/gnu/store/72f54nfp6g1hz873w8z3gfcah0h4nl9p-foo-0.1' names will be
+;; replaced with '/gnu/store/…-foo-0.1' in the current buffer.  There is
+;; also `global-nix-prettify-mode' for global prettifying.
+
+;; To install, add the following to your Emacs init file:
+;;
+;;   (add-to-list 'load-path "/path/to/dir-with-nix-prettify")
+;;   (autoload 'nix-prettify-mode "nix-prettify" nil t)
+;;   (autoload 'global-nix-prettify-mode "nix-prettify" nil t)
+
+;; If you want to enable/disable composition after "M-x font-lock-mode",
+;; use the following setting:
+;;
+;;   (setq font-lock-extra-managed-props
+;;         (cons 'composition font-lock-extra-managed-props))
+
+;; Credits:
+;;
+;; Thanks to Ludovic Courtès for the idea of this package.
+;;
+;; Thanks to the authors of `prettify-symbols-mode' (part of Emacs 24.4)
+;; and "pretty-symbols.el" <http://github.com/drothlis/pretty-symbols>
+;; for the code.  It helped to write this package.
+
+;;; Code:
+
+(defgroup nix-prettify nil
+  "Prettify Nix store file names."
+  :prefix "nix-prettify-"
+  :group 'nix
+  :group 'font-lock
+  :group 'convenience)
+
+(defcustom nix-prettify-char ?…
+  "Character used for prettifying."
+  :type 'character
+  :group 'nix-prettify)
+
+(defcustom nix-prettify-decompose-force nil
+  "If non-nil, remove any composition.
+
+By default, after disabling `nix-prettify-mode',
+compositions (prettifying names with `nix-prettify-char') are
+removed only from strings matching `nix-prettify-regexp', so
+that compositions created by other modes are left untouched.
+
+Set this variable to non-nil, if you want to remove any
+composition unconditionally (like variable `prettify-symbols-mode' does).
+Most likely it will do no harm and will make the process of
+disabling `nix-prettify-mode' a little faster."
+  :type 'boolean
+  :group 'nix-prettify)
+
+(defcustom nix-prettify-regexp
+  ;; The following file names / URLs should be abbreviated:
+
+  ;; /gnu/store/…-foo-0.1
+  ;; /nix/store/…-foo-0.1
+  ;; http://hydra.gnu.org/nar/…-foo-0.1
+  ;; http://hydra.gnu.org/log/…-foo-0.1
+
+  (rx "/" (or "store" "nar" "log") "/"
+      ;; Hash-parts do not include "e", "o", "u" and "t".  See base32Chars
+      ;; at <https://github.com/NixOS/nix/blob/master/src/libutil/hash.cc>
+      (group (= 32 (any "0-9" "a-d" "f-n" "p-s" "v-z"))))
+  "Regexp matching file names for prettifying.
+
+Disable `nix-prettify-mode' before modifying this variable and
+make sure to modify `nix-prettify-regexp-group' if needed.
+
+Example of a \"deeper\" prettifying:
+
+  (setq nix-prettify-regexp \"store/[[:alnum:]]\\\\\\={32\\\\}\"
+        nix-prettify-regexp-group 0)
+
+This will transform
+'/gnu/store/72f54nfp6g1hz873w8z3gfcah0h4nl9p-foo-0.1' into
+'/gnu/…-foo-0.1'"
+  :type 'regexp
+  :group 'nix-prettify)
+
+(defcustom nix-prettify-regexp-group 1
+  "Regexp group in `nix-prettify-regexp' for prettifying."
+  :type 'integer
+  :group 'nix-prettify)
+
+(defvar nix-prettify-special-modes
+  '(nix-info-mode ibuffer-mode)
+  "List of special modes that support font-locking.
+
+By default, \\[global-nix-prettify-mode] enables prettifying in
+all buffers except the ones where `font-lock-defaults' is
+nil (see Info node `(elisp) Font Lock Basics'), because it may
+break the existing highlighting.
+
+Modes from this list and all derived modes are exceptions
+\(`global-nix-prettify-mode' enables prettifying there).")
+
+(defvar nix-prettify-flush-function
+  (cond ((fboundp 'font-lock-flush) #'font-lock-flush)
+        ((fboundp 'jit-lock-refontify) #'jit-lock-refontify))
+  "Function used to refontify buffer.
+This function is called without arguments after
+enabling/disabling `nix-prettify-mode'.  If nil, do nothing.")
+
+(defun nix-prettify-compose ()
+  "Compose matching region in the current buffer."
+  (let ((beg (match-beginning nix-prettify-regexp-group))
+        (end (match-end       nix-prettify-regexp-group)))
+    (compose-region beg end nix-prettify-char 'decompose-region))
+  ;; Return nil because we're not adding any face property.
+  nil)
+
+(defun nix-prettify-decompose-buffer ()
+  "Remove file names compositions from the current buffer."
+  (with-silent-modifications
+    (let ((inhibit-read-only t))
+      (if nix-prettify-decompose-force
+          (remove-text-properties (point-min)
+                                  (point-max)
+                                  '(composition nil))
+        (nix-while-search nix-prettify-regexp
+          (remove-text-properties
+           (match-beginning nix-prettify-regexp-group)
+           (match-end       nix-prettify-regexp-group)
+           '(composition nil)))))))
+
+;;;###autoload
+(define-minor-mode nix-prettify-mode
+  "Toggle Nix Prettify mode.
+
+With a prefix argument ARG, enable Nix Prettify mode if ARG is
+positive, and disable it otherwise.  If called from Lisp, enable
+the mode if ARG is omitted or nil.
+
+When Nix Prettify mode is enabled, hash-parts of the Nix store
+file names (see `nix-prettify-regexp') are prettified,
+i.e. displayed as `nix-prettify-char' character.  This mode can
+be enabled programmatically using hooks:
+
+  (add-hook 'shell-mode-hook 'nix-prettify-mode)
+
+It is possible to enable the mode in any buffer, however not any
+buffer's highlighting may survive after adding new elements to
+`font-lock-keywords' (see `nix-prettify-special-modes' for
+details).
+
+Also you can use `global-nix-prettify-mode' to enable Nix
+Prettify mode for all modes that support font-locking."
+  :init-value nil
+  :lighter " …"
+  (let ((keywords `((,nix-prettify-regexp
+                     (,nix-prettify-regexp-group
+                      (nix-prettify-compose))))))
+    (if nix-prettify-mode
+        ;; Turn on.
+        (font-lock-add-keywords nil keywords)
+      ;; Turn off.
+      (font-lock-remove-keywords nil keywords)
+      (nix-prettify-decompose-buffer))
+    (and nix-prettify-flush-function
+         (funcall nix-prettify-flush-function))))
+
+(defun nix-prettify-supported-p ()
+  "Return non-nil, if the mode can be harmlessly enabled in current buffer."
+  (or font-lock-defaults
+      (apply #'derived-mode-p nix-prettify-special-modes)))
+
+(defun nix-prettify-turn-on ()
+  "Enable `nix-prettify-mode' in the current buffer if needed.
+See `nix-prettify-special-modes' for details."
+  (and (not nix-prettify-mode)
+       (nix-prettify-supported-p)
+       (nix-prettify-mode)))
+
+;;;###autoload
+(define-globalized-minor-mode nix-prettify-global-mode
+  nix-prettify-mode nix-prettify-turn-on)
+
+;;;###autoload
+(define-obsolete-function-alias 'global-nix-prettify-mode 'nix-prettify-global-mode)
+
+(provide 'nix-prettify-mode)
+
+;;; nix-prettify-mode.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-prettify-mode.elc b/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-prettify-mode.elc
new file mode 100644
index 0000000000..984617c7da
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-prettify-mode.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-repl.el b/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-repl.el
new file mode 100644
index 0000000000..79eeb78d03
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-repl.el
@@ -0,0 +1,112 @@
+;;; nix-repl.el --- Nix repl -*- lexical-binding: t -*-
+
+;; This file is NOT part of GNU Emacs.
+
+;;; Commentary:
+
+;;; Code:
+
+(defvar nix-prompt-regexp "nix-repl> ")
+
+(require 'comint)
+(require 'nix)
+
+(defgroup nix-repl nil
+  "nix-repl customizations"
+  :group 'nix)
+
+(defcustom nix-repl-executable-args '("repl")
+  "Arguments to provide to nix-repl."
+  :type 'list)
+
+(define-derived-mode nix-repl-mode comint-mode "Nix-REPL"
+  "Interactive prompt for Nix."
+  (setq-local comint-prompt-regexp nix-prompt-regexp)
+  (setq-local comint-prompt-read-only t))
+
+(defmacro nix--with-temp-process-filter (proc &rest body)
+  "Use temp process PROC filter on BODY."
+  (declare (indent defun))
+  `(let* ((buf (generate-new-buffer " *temp-process-output*"))
+          (proc-filter-saved (process-filter ,proc))
+          (proc-marker (with-current-buffer buf (point-marker))))
+     (set-process-filter ,proc (nix--process-filter buf proc-marker))
+     (unwind-protect
+         (with-current-buffer buf
+           ,@body)
+       (set-process-filter ,proc proc-filter-saved)
+       (kill-buffer buf))))
+
+;;;###autoload
+(defun nix-repl ()
+  "Load the Nix-REPL."
+  (interactive)
+  (pop-to-buffer-same-window
+   (get-buffer-create "*Nix-REPL*"))
+  (unless (comint-check-proc (current-buffer))
+    (nix--make-repl-in-buffer (current-buffer))
+    (nix-repl-mode)))
+
+(defalias 'nix-repl-show 'nix-repl)
+
+(defun nix--make-repl-in-buffer (buffer)
+  "Make Nix Repl in BUFFER."
+  (apply
+   'make-comint-in-buffer
+   (append `("Nix-REPL" ,buffer ,nix-executable nil)
+           nix-repl-executable-args)))
+
+(defun nix-get-completions (proc prefix)
+  "Get Nix completions from Nix-repl process PROC and based off of PREFIX."
+  (save-match-data
+    (nix--with-temp-process-filter proc
+                                   (goto-char (point-min))
+                                   (process-send-string proc (concat prefix "\t\"" (nix--char-with-ctrl ?a) "\"\n"))
+                                   (let ((i 0))
+                                     (while (and (< (setq i (1+ i)) 100)
+                                                 (not (search-forward-regexp "\"\\([^\"]*\\)\"[\n]*nix-repl>" nil t)))
+                                       (sleep-for 0.01))
+                                     (let ((new-prefix (match-string 1))
+                                           (start-compl (point)))
+                                       (if (string-suffix-p " " new-prefix)
+                                           (list (substring new-prefix 0 -1))
+                                         (process-send-string proc (concat new-prefix "\t\t" (nix--char-with-ctrl ?u) "\n"))
+                                         (goto-char start-compl)
+                                         (setq i 0)
+                                         (while (and (< (setq i (1+ i)) 100)
+                                                     (not (search-forward-regexp
+                                                           "[\n]+nix-repl>\\|Display all \\([0-9]+\\)" nil t)))
+                                           (sleep-for 0.01))
+                                         (if (match-string 1)
+                                             (progn
+                                               (process-send-string proc "n")
+                                               '())
+                                           (search-backward "\n" nil t)
+                                           (split-string (buffer-substring start-compl (1- (point)))))))))))
+
+(defun nix--send-repl (input &optional process mute)
+  "Send INPUT to PROCESS.
+
+MUTE if true then don’t alert user."
+  (let ((proc (or process (get-buffer-process (current-buffer)))))
+    (if mute
+        (nix--with-temp-process-filter proc
+                                       (process-send-string proc input))
+      (process-send-string proc input))))
+
+(defun nix--char-with-ctrl (char)
+  "Generate control character CHAR."
+  (char-to-string (logand #b10011111 char)))
+
+(defun nix--process-filter (buf marker)
+  "Process filter for Nix-rel buffer BUF at MARKER."
+  (lambda (_proc string)
+    (when (buffer-live-p buf)
+      (with-current-buffer buf
+        (save-excursion
+          (goto-char marker)
+          (insert string)
+          (set-marker marker (point)))))))
+
+(provide 'nix-repl)
+;;; nix-repl.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-repl.elc b/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-repl.elc
new file mode 100644
index 0000000000..a832106c2e
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-repl.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-search.el b/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-search.el
new file mode 100644
index 0000000000..85a1e837f2
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-search.el
@@ -0,0 +1,64 @@
+;;; nix-search.el -- run nix commands in Emacs -*- lexical-binding: t -*-
+
+;; Author: Matthew Bauer <mjbauer95@gmail.com>
+;; Homepage: https://github.com/NixOS/nix-mode
+;; Keywords: nix
+
+;; This file is NOT part of GNU Emacs.
+
+;;; Commentary:
+
+;;; Code:
+
+(require 'nix)
+(require 'nix-instantiate)
+(require 'nix-shell)
+(require 'json)
+
+;;;###autoload
+(defun nix-search (&optional search file)
+  "Run nix search.
+SEARCH a search term to use.
+FILE a Nix expression to search in."
+  (interactive)
+  (unless search (setq search ""))
+  (unless file (nix-read-file))
+
+  (let ((stdout (generate-new-buffer "nix search"))
+	result)
+    (call-process nix-executable nil (list stdout nil) nil
+		  "search" "--json" "-f" file search)
+    (with-current-buffer stdout
+      (when (eq (buffer-size) 0)
+	(error "Error: nix search %s failed to produce any output" search))
+      (goto-char (point-min))
+      (setq result (json-read)))
+    (kill-buffer stdout)
+    (when (called-interactively-p 'any)
+      (let ((display (generate-new-buffer "*nix search*")))
+	(with-current-buffer display
+	  (dolist (entry result)
+	    (widget-insert
+	     (format "attr: %s\nname: %s\nversion: %s\ndescription: %s\n\n"
+                     (car entry)
+		     (alist-get 'pkgName (cdr entry))
+		     (alist-get 'version (cdr entry))
+		     (alist-get 'description (cdr entry)))))
+	  )
+	(display-buffer display 'display-buffer-pop-up-window)))
+    (kill-buffer stdout)
+    result))
+
+(defun nix-search-read-attr (file)
+  "Read from a list of attributes.
+FILE the nix file to look in."
+  (let ((collection
+	 (sort (mapcar (lambda (x) (symbol-name (car x)))
+		       (nix-search "" file))
+	       'string<))
+	(read (cond ((fboundp 'ivy-read) 'ivy-read)
+		    (t 'completing-read))))
+    (funcall read "Attribute: " collection)))
+
+(provide 'nix-search)
+;;; nix-search.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-search.elc b/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-search.elc
new file mode 100644
index 0000000000..b5fa47b7d8
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-search.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-shebang.el b/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-shebang.el
new file mode 100644
index 0000000000..08cc1629dd
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-shebang.el
@@ -0,0 +1,47 @@
+;;; nix-shebang.el --- Handle nix shebang header -*- lexical-binding: t -*-
+
+;; Author: Matthew Bauer <mjbauer95@gmail.com>
+;; Homepage: https://github.com/NixOS/nix-mode
+;; Version: 1.2.1
+;; Keywords: nix, languages, tools, unix
+;; Package-Requires: ((emacs "24.3"))
+
+;; This file is NOT part of GNU Emacs.
+
+;;; Commentary:
+
+;; This detects file headers that look like:
+;; #!/usr/bin/env nix-shell
+;; #!nix-shell -i bash
+
+;; and correctly detects their file modes.
+
+;;; Code:
+
+(require 'files)
+
+(defvar nix-shebang-interpreter-regexp "#!\s*nix-shell -i \\([^ \t\n]+\\)"
+  "Regexp for nix-shell -i header.")
+
+(defun nix-shebang-get-interpreter ()
+  "Get interpreter string from nix-shell -i file."
+  (save-excursion
+    (goto-char (point-min))
+    (forward-line 1)
+    (when (looking-at nix-shebang-interpreter-regexp)
+      (match-string 1))))
+
+(defun nix-shebang-mode ()
+  "Detect and run file’s interpreter mode."
+  (let ((mode (nix-shebang-get-interpreter)))
+    (when mode
+      (funcall (assoc-default mode
+                              (mapcar (lambda (e)
+                                        (cons
+                                         (format "\\`%s\\'" (car e))
+                                         (cdr e)))
+                                      interpreter-mode-alist)
+                              #'string-match-p)))))
+
+(provide 'nix-shebang)
+;;; nix-shebang.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-shebang.elc b/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-shebang.elc
new file mode 100644
index 0000000000..2f2188235e
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-shebang.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-shell.el b/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-shell.el
new file mode 100644
index 0000000000..8f6da2b098
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-shell.el
@@ -0,0 +1,250 @@
+;;; nix-shell.el -- run nix commands in Emacs -*- lexical-binding: t -*-
+
+;; Author: Matthew Bauer <mjbauer95@gmail.com>
+;; Homepage: https://github.com/NixOS/nix-mode
+;; Keywords: nix
+
+;; This file is NOT part of GNU Emacs.
+
+;;; Commentary:
+
+;; To use this just run:
+
+;; M-x RET nix-shell RET
+
+;; This will give you some
+
+;;; Code:
+
+(require 'nix)
+(require 'nix-instantiate)
+(require 'nix-store)
+
+(defgroup nix-shell nil
+  "All nix-shell options."
+  :group 'nix)
+
+(defcustom nix-shell-inputs '(depsBuildBuild
+			      depsBuildBuildPropagated
+			      nativeBuildInputs
+			      propagatedNativeBuildInputs
+			      depsBuildTarget
+			      depsBuildTargetPropagated)
+  "List of inputs to collect for nix-shell."
+  :type 'list
+  :group 'nix-shell)
+
+(defcustom nix-shell-clear-environment nil
+  "Whether to clear the old ‘exec-path’ & environment.
+Similar to ‘--pure’ argument in command line nix-shell."
+  :type 'boolean
+  :group 'nix-shell)
+
+(defcustom nix-shell-auto-realise t
+  "Whether we can realise paths in the built .drv file."
+  :type 'boolean
+  :group 'nix-shell)
+
+(defcustom nix-file nil
+  "Nix file to build expressions from.
+Should only be set in dir-locals.el file."
+  :type 'stringp
+  :group 'nix-shell)
+
+(defcustom nix-attr nil
+  "Nix attribute path to use.
+Should only be set in dir-locals.el file."
+  :type 'stringp
+  :group 'nix-shell)
+
+;;;###autoload
+(defun nix-shell-unpack (file attr)
+  "Run Nix’s unpackPhase.
+FILE is the file to unpack from.
+ATTR is the attribute to unpack."
+  (interactive (list (nix-read-file) nil))
+  (unless attr (setq attr (nix-read-attr file)))
+
+  (nix-shell--run-phase "unpack" file attr))
+
+(defun nix-read-attr (_)
+  "Get nix attribute from user."
+  (read-string "Nix attr: "))
+
+(defun nix-read-file ()
+  "Get nix file from user."
+  (cond
+   (nix-file nix-file)
+   ((file-exists-p "shell.nix") "shell.nix")
+   ((file-exists-p "default.nix") "default.nix")
+   (t (read-file-name "Nix file: " nil "<nixpkgs>"))))
+
+;;;###autoload
+(defun nix-shell-configure (file attr)
+  "Run Nix’s configurePhase.
+FILE is the file to configure from.
+ATTR is the attribute to configure."
+  (interactive (list (nix-read-file) nil))
+  (unless attr (setq attr (nix-read-attr file)))
+
+  (nix-shell--run-phase "configure" file attr))
+
+;;;###autoload
+(defun nix-shell-build (file attr)
+  "Run Nix’s buildPhase.
+FILE is the file to build from.
+ATTR is the attribute to build."
+  (interactive (list (nix-read-file) nil))
+  (unless attr (setq attr (nix-read-attr file)))
+
+  (nix-shell--run-phase "build" file attr))
+
+(defun nix-shell--run-phase (phase file attr)
+  "Get source from a Nix derivation.
+PHASE phase to run.
+FILE used for base of Nix expresions.
+ATTR from NIX-FILE to get Nix expressions from."
+  (shell-command
+   (format "%s '%s' -A '%s' --run 'if [ -z \"$%sPhase\" ]; then eval %sPhase; else eval \"$%sPhase\"; fi' &"
+	   nix-shell-executable
+	   file attr phase phase phase)))
+
+(declare-function flycheck-buffer "flycheck")
+
+(defun nix-shell--callback (buffer drv)
+  "Run the nix-shell callback to setup the buffer.
+The BUFFER to run in.
+The DRV file to use."
+  (let* ((env (alist-get 'env drv))
+	 (stdenv (alist-get 'stdenv env))
+	 (system (alist-get 'system env))
+	 (inputs (remove nil
+			 (apply 'append
+				(mapcar (lambda (prop)
+					  (split-string (alist-get prop env)))
+					nix-shell-inputs)))))
+
+    ;; Prevent accidentally rebuilding the world.
+    (unless (file-directory-p stdenv)
+      (error
+       "Your stdenv at %s has not been built. Please run: nix-store -r %s"
+       stdenv stdenv))
+
+    ;; Make sure this .drv file can actually be built here.
+    (unless (string= system (nix-system))
+      (error
+       "Your system (%s) does not match .drv’s build system (%s)"
+       (nix-system) system))
+
+    (with-current-buffer buffer
+      (when nix-shell-clear-environment
+	(setq-local exec-path nil)
+	(setq-local eshell-path-env "")
+	;; (setq-local process-environment nil)
+	)
+
+      (dolist (input inputs)
+	(when (and (not (file-directory-p input))
+		   nix-shell-auto-realise)
+	  (nix-store-realise input))
+
+	(let ((bin (expand-file-name "bin" input))
+	      (man (expand-file-name "share/man" input))
+	      (include (expand-file-name "include" input)))
+	  (add-to-list 'exec-path bin)
+	  (setq-local eshell-path-env
+		      (format "%s:%s" bin eshell-path-env))
+	  (add-to-list 'woman-manpath man)
+	  (add-to-list 'ffap-c-path include)
+	  (add-to-list 'Man-header-file-path include)
+	  (add-to-list 'irony-additional-clang-options
+		       (format "-I%s" include))))
+
+      (when flycheck-mode
+	(flycheck-buffer))
+      )))
+
+(defun nix-shell-with-packages (packages &optional pkgs-file)
+  "Create a nix shell environment from the listed package.
+PACKAGES a list of packages to use.
+PKGS-FILE the Nix file to get the packages from."
+  (nix-instantiate-async (apply-partially 'nix-shell--callback
+					  (current-buffer))
+			 (nix-shell--with-packages-file packages pkgs-file)
+			 ))
+
+(defun nix-shell--with-packages-file (packages &optional pkgs-file)
+  "Get a .nix file from the packages list.
+PACKAGES to put in the .nix file.
+PKGS-FILE package set to pull from."
+  (unless pkgs-file (setq pkgs-file "<nixpkgs>"))
+  (let ((nix-file (make-temp-file "nix-shell" nil ".nix")))
+    (with-temp-file nix-file
+      (insert (format "with import %s { };\n" pkgs-file))
+      (insert "runCommandCC \"shell\" {\n")
+      (insert "	 nativeBuildInputs = [\n")
+      (mapc (lambda (x) (insert (format "	  %s\n" x))) packages)
+      (insert "	 ];\n")
+      (insert "} \"\"\n"))
+    nix-file))
+
+(defun nix-eshell-with-packages (packages &optional pkgs-file)
+  "Create an Eshell buffer that has the shell environment in it.
+PACKAGES a list of packages to pull in.
+PKGS-FILE a file to use to get the packages."
+  (let ((buffer (generate-new-buffer "*nix-eshell*")))
+    (pop-to-buffer-same-window buffer)
+
+    (setq-local nix-shell-clear-environment t)
+
+    (nix-shell--callback
+     (current-buffer)
+     (nix-instantiate
+      (nix-shell--with-packages-file packages pkgs-file) nil t))
+
+    (eshell-mode)
+    buffer))
+
+(defun nix-eshell (file &optional attr)
+  "Create an Eshell buffer that has the shell environment in it.
+FILE the .nix expression to create a shell for.
+ATTR attribute to instantiate in NIX-FILE."
+  (interactive (list (nix-read-file) nil))
+  (unless attr (setq attr (nix-read-attr nix-file)))
+
+  (let ((buffer (generate-new-buffer "*nix-eshell*")))
+    (pop-to-buffer-same-window buffer)
+
+    (setq-local nix-shell-clear-environment t)
+
+    (nix-shell--callback
+     (current-buffer)
+     (nix-instantiate file attr t))
+
+    (eshell-mode)
+    buffer))
+
+;;;###autoload
+(defun nix-shell-with-string (string)
+  "A nix-shell emulator in Emacs from a string.
+STRING the nix expression to use."
+  (let ((file (make-temp-file "nix-shell" nil ".nix")))
+    (with-temp-file file (insert string))
+    (nix-instantiate-async (apply-partially 'nix-shell--callback
+					    (current-buffer))
+			   file)))
+
+;;;###autoload
+(defun nix-shell (file &optional attr)
+  "A nix-shell emulator in Emacs.
+FILE the file to instantiate.
+ATTR an attribute of the Nix file to use."
+  (interactive (list (nix-read-file) nil))
+  (unless attr (setq attr (nix-read-attr file)))
+
+  (nix-instantiate-async (apply-partially 'nix-shell--callback
+					  (current-buffer))
+			 file attr))
+
+(provide 'nix-shell)
+;;; nix-shell.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-shell.elc b/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-shell.elc
new file mode 100644
index 0000000000..bf250a8bb8
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-shell.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-store.el b/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-store.el
new file mode 100644
index 0000000000..eeaecbb453
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-store.el
@@ -0,0 +1,25 @@
+;;; nix-store.el -- run nix commands in Emacs -*- lexical-binding: t -*-
+
+;; Author: Matthew Bauer <mjbauer95@gmail.com>
+;; Homepage: https://github.com/NixOS/nix-mode
+;; Keywords: nix
+
+;; This file is NOT part of GNU Emacs.
+
+;;; Commentary:
+
+;;; Code:
+
+(require 'nix)
+
+(defun nix-store-realise (path)
+  "Realise a path asynchronously.
+PATH the path within /nix/store to realise"
+  (make-process
+   :buffer nil
+   :command (list nix-store-executable "-r" path)
+   :noquery t
+   :name (format "*nix-store*<%s>" path)))
+
+(provide 'nix-store)
+;;; nix-store.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-store.elc b/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-store.elc
new file mode 100644
index 0000000000..f7fb690221
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix-store.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix.el b/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix.el
new file mode 100644
index 0000000000..3261e075b4
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix.el
@@ -0,0 +1,289 @@
+;;; nix.el -- run nix commands in Emacs -*- lexical-binding: t -*-
+
+;; Author: Matthew Bauer <mjbauer95@gmail.com>
+;; Homepage: https://github.com/NixOS/nix-mode
+;; Keywords: nix
+
+;; This file is NOT part of GNU Emacs.
+
+;;; Commentary:
+
+;; To use this just run:
+
+;; M-x RET nix-shell RET
+
+;; This will give you some
+
+;;; Code:
+
+(require 'pcomplete)
+
+(defgroup nix nil
+  "Nix-related customizations"
+  :group 'languages)
+
+(defcustom nix-executable (executable-find "nix")
+  "Nix executable location."
+  :group 'nix
+  :type 'string)
+
+(defcustom nix-build-executable (executable-find "nix-build")
+  "Nix-build executable location."
+  :group 'nix
+  :type 'string)
+
+(defcustom nix-instantiate-executable (executable-find "nix-instantiate")
+  "Nix executable location."
+  :group 'nix
+  :type 'string)
+
+(defcustom nix-store-executable (executable-find "nix-store")
+  "Nix executable location."
+  :group 'nix
+  :type 'string)
+
+(defcustom nix-shell-executable (executable-find "nix-shell")
+  "Location of ‘nix-shell’ executable."
+  :group 'nix
+  :type 'string)
+
+(defcustom nix-store-dir "/nix/store"
+  "Nix store directory."
+  :group 'nix
+  :type 'string)
+
+(defcustom nix-state-dir "/nix/var"
+  "Nix store directory."
+  :group 'nix
+  :type 'string)
+
+(defun nix-system ()
+  "Get the current system tuple."
+  (let ((stdout (generate-new-buffer "nix eval"))
+        result)
+    (call-process nix-executable nil (list stdout nil) nil
+		  "eval" "--raw" "(builtins.currentSystem)")
+    (with-current-buffer stdout (setq result (buffer-string)))
+    (kill-buffer stdout)
+    result))
+
+(defvar nix-commands
+  '("add-to-store"
+    "build"
+    "cat-nar"
+    "cat-store"
+    "copy"
+    "copy-sigs"
+    "dump-path"
+    "edit"
+    "eval"
+    "hash-file"
+    "hash-path"
+    "log"
+    "ls-nar"
+    "ls-store"
+    "optimise-store"
+    "path-info"
+    "ping-store"
+    "repl"
+    "run"
+    "search"
+    "show-config"
+    "show-derivation"
+    "sign-paths"
+    "to-base16"
+    "to-base32"
+    "to-base64"
+    "upgrade-nix"
+    "verify"
+    "why-depends"))
+
+(defvar nix-toplevel-options
+  '("-v"
+    "--verbose"
+    "-h"
+    "--help"
+    "--debug"
+    "--help-config"
+    "--option"
+    "--version"))
+
+(defvar nix-config-options
+  '("allowed-uris"
+    "allow-import-from-derivation"
+    "allow-new-priveleges"
+    "allowed-users"
+    "auto-optimise-store"
+    "builders"
+    "builders-use-substitutes"
+    "build-users-group"
+    "compress-build-log"
+    "connect-timeout"
+    "cores"
+    "extra-sandbox-paths"
+    "extra-substituters"
+    "fallback"
+    "fsync-metadata"
+    "hashed-mirrors"
+    "http-connections"
+    "keep-build-log"
+    "keep-derivations"
+    "keep-env-derivations"
+    "keep-outputs"
+    "max-build-log-size"
+    "max-jobs"
+    "max-silent-time"
+    "netrc-file"
+    "plugin-files"
+    "pre-build-hook"
+    "repeat"
+    "require-sigs"
+    "restrict-eval"
+    "sandbox"
+    "sandbox-dev-shm-size"
+    "sandbox-paths"
+    "secret-key-files"
+    "show-trace"
+    "substitute"
+    "substituters"
+    "system"
+    "timeout"
+    "trusted-public-keys"
+    "trusted-subtituters"
+    "trusted-users"))
+
+(defun nix--pcomplete-flags (options)
+  "Complete flags to the Nix command.
+OPTIONS a list of options to accept."
+  (while (pcomplete-match "^-" 0)
+    (pcomplete-here options)
+    (let ((last-arg (nth (1- pcomplete-index) pcomplete-args)))
+      (cond
+       ((string= "--option" last-arg)
+        (pcomplete-here nix-config-options)
+        (pcomplete-here))
+       ((or (string= "-f" last-arg) (string= "--file" last-arg))
+        (pcomplete-here (pcomplete-entries nil 'file-exists-p)))
+       ((or (string= "--arg" last-arg) (string= "--argstr" last-arg))
+        (pcomplete-here)
+        (pcomplete-here))
+       ((or (string= "-I" last-arg) (string= "--include" last-arg))
+        (pcomplete-here (pcomplete-entries nil 'file-exists-p)))
+       ((or (string= "-k" last-arg) (string= "--keep" last-arg))
+        (pcomplete-here))
+       ((or (string= "-u" last-arg) (string= "--unset" last-arg))
+        (pcomplete-here))
+       ((or (string= "-s" last-arg) (string= "--substituter" last-arg))
+        (pcomplete-here))))))
+
+;;;###autoload
+(defun pcomplete/nix ()
+  "Completion for the nix command."
+  (nix--pcomplete-flags nix-toplevel-options)
+  (pcomplete-here nix-commands)
+  (pcase (nth (1- pcomplete-index) pcomplete-args)
+    ("run"
+     (nix--pcomplete-flags
+      (append nix-toplevel-options '("--arg" "--argstr" "-c" "--command"
+                                     "-f" "--file" "-i" "-I" "--include"
+                                     "-k" "--keep" "-u" "--unset"))))
+    ("build"
+     (nix--pcomplete-flags
+      (append nix-toplevel-options '("--arg" "--argstr" "--dry-run"
+                                     "-f" "--file" "-I" "--include"
+                                     "--no-link" "-o" "--out-link"))))
+    ("add-to-store"
+     (nix--pcomplete-flags
+      (append nix-toplevel-options '("--dry-run" "-n" "--name"))))
+    ("copy"
+     (nix--pcomplete-flags
+      (append nix-toplevel-options '("--all" "--arg" "--argstr"
+                                     "-f" "--file" "--from"
+                                     "-I" "--include" "--no-check-sigs"
+                                     "--no-recursive" "-s" "--substitute"
+                                     "--to"))))
+    ("copy-sigs"
+     (nix--pcomplete-flags
+      (append nix-toplevel-options '("--all" "--arg" "--argstr"
+                                     "-f" "--file" "-I" "--include"
+                                     "-r" "--recursive" "-s" "--substituter"))))
+    ("dump-path"
+     (nix--pcomplete-flags
+      (append nix-toplevel-options '("--arg" "--argstr"
+                                     "-f" "--file" "-I" "--include"))))
+    ("edit"
+     (nix--pcomplete-flags
+      (append nix-toplevel-options '("--arg" "--argstr"
+                                     "-f" "--file" "-I" "--include"))))
+    ("eval"
+     (nix--pcomplete-flags
+      (append nix-toplevel-options '("--arg" "--argstr"
+                                     "-f" "--file" "-I" "--include"
+                                     "--json" "--raw"))))
+    ("hash-file"
+     (nix--pcomplete-flags
+      (append nix-toplevel-options '("--base16" "--base32"
+                                     "--base64" "--type"))))
+    ("hash-path"
+     (nix--pcomplete-flags
+      (append nix-toplevel-options '("--base16" "--base32"
+                                     "--base64" "--type"))))
+    ("log"
+     (nix--pcomplete-flags
+      (append nix-toplevel-options '("--arg" "--argstr"
+                                     "-f" "--file" "-I" "--include"
+                                     "--json" "--raw"))))
+    ("ls-nar"
+     (nix--pcomplete-flags
+      (append nix-toplevel-options '("-d" "--directory"
+                                     "--json" "-l" "--long"
+                                     "-R" "--recursive"))))
+    ("ls-store"
+     (nix--pcomplete-flags
+      (append nix-toplevel-options '("-d" "--directory"
+                                     "--json" "-l" "--long"
+                                     "-R" "--recursive"))))
+    ("repl"
+     (nix--pcomplete-flags
+      (append nix-toplevel-options '("--arg" "--argstr"
+                                     "-I" "--include"))))
+    ("search"
+     (nix--pcomplete-flags
+      (append nix-toplevel-options '("--arg" "--argstr"
+                                     "-f" "--file"
+                                     "-I" "--include"
+                                     "--json" "--no-cache"
+                                     "-u" "--update-cache"))))
+    ("show-config"
+     (nix--pcomplete-flags
+      (append nix-toplevel-options '("--json"))))
+    ("show-derivation"
+     (nix--pcomplete-flags
+      (append nix-toplevel-options '("--arg" "--argstr"
+                                     "-f" "--file"
+                                     "-I" "--include"
+                                     "-r" "--recursive"))))
+    ("sign-paths"
+     (nix--pcomplete-flags
+      (append nix-toplevel-options '("--all" "--arg" "--argstr"
+                                     "-f" "--file" "-I" "--include"
+                                     "-k" "--key-file" "-r" "--recursive"))))
+    ("upgrade-nix"
+     (nix--pcomplete-flags
+      (append nix-toplevel-options '("-p" "--profile"))))
+    ("verify"
+     (nix--pcomplete-flags
+      (append nix-toplevel-options '("--all" "--arg" "--argstr"
+                                     "-f" "--file" "-I" "--include"
+                                     "--no-contents" "--no-trust"
+                                     "-r" "--recursive" "-n" "--sigs-needed"
+                                     "-s" "--substuter"))))
+    ("why-depends"
+     (nix--pcomplete-flags
+      (append nix-toplevel-options '("-a" "--all" "--arg" "--argstr"
+                                     "-f" "--file" "-I" "--include"))))
+    (_ (nix--pcomplete-flags nix-toplevel-options)))
+  (pcomplete-here (pcomplete-entries)))
+
+(provide 'nix)
+;;; nix.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix.elc b/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix.elc
new file mode 100644
index 0000000000..9f0243b307
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/nix-mode-20180822.214/nix.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/oauth2-0.11.signed b/configs/shared/emacs/.emacs.d/elpa/oauth2-0.11.signed
new file mode 100644
index 0000000000..11e736432c
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/oauth2-0.11.signed
@@ -0,0 +1 @@
+Good signature from 474F05837FBDEF9B GNU ELPA Signing Agent <elpasign@elpa.gnu.org> (trust undefined) created at 2016-07-09T17:05:02-0400 using DSA
\ No newline at end of file
diff --git a/configs/shared/emacs/.emacs.d/elpa/oauth2-0.11/oauth2-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/oauth2-0.11/oauth2-autoloads.el
new file mode 100644
index 0000000000..1df3bc2b58
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/oauth2-0.11/oauth2-autoloads.el
@@ -0,0 +1,45 @@
+;;; oauth2-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "oauth2" "oauth2.el" (23377 60989 173073 292000))
+;;; Generated autoloads from oauth2.el
+
+(autoload 'oauth2-refresh-access "oauth2" "\
+Refresh OAuth access TOKEN.
+TOKEN should be obtained with `oauth2-request-access'.
+
+\(fn TOKEN)" nil nil)
+
+(autoload 'oauth2-auth "oauth2" "\
+Authenticate application via OAuth2.
+
+\(fn AUTH-URL TOKEN-URL CLIENT-ID CLIENT-SECRET &optional SCOPE STATE REDIRECT-URI)" nil nil)
+
+(autoload 'oauth2-auth-and-store "oauth2" "\
+Request access to a resource and store it using `plstore'.
+
+\(fn AUTH-URL TOKEN-URL RESOURCE-URL CLIENT-ID CLIENT-SECRET &optional REDIRECT-URI)" nil nil)
+
+(autoload 'oauth2-url-retrieve-synchronously "oauth2" "\
+Retrieve an URL synchronously using TOKEN to access it.
+TOKEN can be obtained with `oauth2-auth'.
+
+\(fn TOKEN URL &optional REQUEST-METHOD REQUEST-DATA REQUEST-EXTRA-HEADERS)" nil nil)
+
+(autoload 'oauth2-url-retrieve "oauth2" "\
+Retrieve an URL asynchronously using TOKEN to access it.
+TOKEN can be obtained with `oauth2-auth'.  CALLBACK gets called with CBARGS
+when finished.  See `url-retrieve'.
+
+\(fn TOKEN URL CALLBACK &optional CBARGS REQUEST-METHOD REQUEST-DATA REQUEST-EXTRA-HEADERS)" nil nil)
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; oauth2-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/oauth2-0.11/oauth2-pkg.el b/configs/shared/emacs/.emacs.d/elpa/oauth2-0.11/oauth2-pkg.el
new file mode 100644
index 0000000000..133716c561
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/oauth2-0.11/oauth2-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "oauth2" "0.11" "OAuth 2.0 Authorization Protocol" 'nil :url "http://elpa.gnu.org/packages/oauth2.html" :keywords '("comm"))
diff --git a/configs/shared/emacs/.emacs.d/elpa/oauth2-0.11/oauth2.el b/configs/shared/emacs/.emacs.d/elpa/oauth2-0.11/oauth2.el
new file mode 100644
index 0000000000..893754c700
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/oauth2-0.11/oauth2.el
@@ -0,0 +1,342 @@
+;;; oauth2.el --- OAuth 2.0 Authorization Protocol
+
+;; Copyright (C) 2011-2016 Free Software Foundation, Inc
+
+;; Author: Julien Danjou <julien@danjou.info>
+;; Version: 0.11
+;; Keywords: comm
+
+;; 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:
+
+;; Implementation of the OAuth 2.0 draft.
+;;
+;; The main entry point is `oauth2-auth-and-store' which will return a token
+;; structure.  This token structure can be then used with
+;; `oauth2-url-retrieve-synchronously' or `oauth2-url-retrieve' to retrieve
+;; any data that need OAuth authentication to be accessed.
+;;
+;; If the token needs to be refreshed, the code handles it automatically and
+;; store the new value of the access token.
+
+;;; Code:
+
+(eval-when-compile (require 'cl))
+(require 'plstore)
+(require 'json)
+(require 'url-http)
+
+(defun oauth2-request-authorization (auth-url client-id &optional scope state redirect-uri)
+  "Request OAuth authorization at AUTH-URL by launching `browse-url'.
+CLIENT-ID is the client id provided by the provider.
+It returns the code provided by the service."
+  (browse-url (concat auth-url
+                      (if (string-match-p "\?" auth-url) "&" "?")
+                      "client_id=" (url-hexify-string client-id)
+                      "&response_type=code"
+                      "&redirect_uri=" (url-hexify-string (or redirect-uri "urn:ietf:wg:oauth:2.0:oob"))
+                      (if scope (concat "&scope=" (url-hexify-string scope)) "")
+                      (if state (concat "&state=" (url-hexify-string state)) "")))
+  (read-string "Enter the code your browser displayed: "))
+
+(defun oauth2-request-access-parse ()
+  "Parse the result of an OAuth request."
+  (goto-char (point-min))
+  (when (search-forward-regexp "^$" nil t)
+    (json-read)))
+
+(defun oauth2-make-access-request (url data)
+  "Make an access request to URL using DATA in POST."
+  (let ((url-request-method "POST")
+        (url-request-data data)
+        (url-request-extra-headers
+         '(("Content-Type" . "application/x-www-form-urlencoded"))))
+    (with-current-buffer (url-retrieve-synchronously url)
+      (let ((data (oauth2-request-access-parse)))
+        (kill-buffer (current-buffer))
+        data))))
+
+(defstruct oauth2-token
+  plstore
+  plstore-id
+  client-id
+  client-secret
+  access-token
+  refresh-token
+  token-url
+  access-response)
+
+(defun oauth2-request-access (token-url client-id client-secret code &optional redirect-uri)
+  "Request OAuth access at TOKEN-URL.
+The CODE should be obtained with `oauth2-request-authorization'.
+Return an `oauth2-token' structure."
+  (when code
+    (let ((result
+           (oauth2-make-access-request
+            token-url
+            (concat
+             "client_id=" client-id
+             "&client_secret=" client-secret
+             "&code=" code
+             "&redirect_uri=" (url-hexify-string (or redirect-uri "urn:ietf:wg:oauth:2.0:oob"))
+             "&grant_type=authorization_code"))))
+      (make-oauth2-token :client-id client-id
+                         :client-secret client-secret
+                         :access-token (cdr (assoc 'access_token result))
+                         :refresh-token (cdr (assoc 'refresh_token result))
+                         :token-url token-url
+                         :access-response result))))
+
+;;;###autoload
+(defun oauth2-refresh-access (token)
+  "Refresh OAuth access TOKEN.
+TOKEN should be obtained with `oauth2-request-access'."
+  (setf (oauth2-token-access-token token)
+        (cdr (assoc 'access_token
+                    (oauth2-make-access-request
+                     (oauth2-token-token-url token)
+                     (concat "client_id=" (oauth2-token-client-id token)
+                             "&client_secret=" (oauth2-token-client-secret token)
+                             "&refresh_token=" (oauth2-token-refresh-token token)
+                             "&grant_type=refresh_token")))))
+  ;; If the token has a plstore, update it
+  (let ((plstore (oauth2-token-plstore token)))
+    (when plstore
+      (plstore-put plstore (oauth2-token-plstore-id token)
+                   nil `(:access-token
+                         ,(oauth2-token-access-token token)
+                         :refresh-token
+                         ,(oauth2-token-refresh-token token)
+                         :access-response
+                         ,(oauth2-token-access-response token)
+                         ))
+      (plstore-save plstore)))
+  token)
+
+;;;###autoload
+(defun oauth2-auth (auth-url token-url client-id client-secret &optional scope state redirect-uri)
+  "Authenticate application via OAuth2."
+  (oauth2-request-access
+   token-url
+   client-id
+   client-secret
+   (oauth2-request-authorization
+    auth-url client-id scope state redirect-uri)
+   redirect-uri))
+
+(defcustom oauth2-token-file (concat user-emacs-directory "oauth2.plstore")
+  "File path where store OAuth tokens."
+  :group 'oauth2
+  :type 'file)
+
+(defun oauth2-compute-id (auth-url token-url resource-url)
+  "Compute an unique id based on URLs.
+This allows to store the token in an unique way."
+  (secure-hash 'md5 (concat auth-url token-url resource-url)))
+
+;;;###autoload
+(defun oauth2-auth-and-store (auth-url token-url resource-url client-id client-secret &optional redirect-uri)
+  "Request access to a resource and store it using `plstore'."
+  ;; We store a MD5 sum of all URL
+  (let* ((plstore (plstore-open oauth2-token-file))
+         (id (oauth2-compute-id auth-url token-url resource-url))
+         (plist (cdr (plstore-get plstore id))))
+    ;; Check if we found something matching this access
+    (if plist
+        ;; We did, return the token object
+        (make-oauth2-token :plstore plstore
+                           :plstore-id id
+                           :client-id client-id
+                           :client-secret client-secret
+                           :access-token (plist-get plist :access-token)
+                           :refresh-token (plist-get plist :refresh-token)
+                           :token-url token-url
+                           :access-response (plist-get plist :access-response))
+      (let ((token (oauth2-auth auth-url token-url
+                                client-id client-secret resource-url nil redirect-uri)))
+        ;; Set the plstore
+        (setf (oauth2-token-plstore token) plstore)
+        (setf (oauth2-token-plstore-id token) id)
+        (plstore-put plstore id nil `(:access-token
+                                      ,(oauth2-token-access-token token)
+                                      :refresh-token
+                                      ,(oauth2-token-refresh-token token)
+                                      :access-response
+                                      ,(oauth2-token-access-response token)))
+        (plstore-save plstore)
+        token))))
+
+(defun oauth2-url-append-access-token (token url)
+  "Append access token to URL."
+  (concat url
+          (if (string-match-p "\?" url) "&" "?")
+          "access_token=" (oauth2-token-access-token token)))
+
+(defvar oauth--url-advice nil)
+(defvar oauth--token-data)
+
+(defun oauth2-authz-bearer-header (token)
+  "Return 'Authoriztions: Bearer' header with TOKEN."
+  (cons "Authorization" (format "Bearer %s" token)))
+
+(defun oauth2-extra-headers (extra-headers)
+  "Return EXTRA-HEADERS with 'Authorization: Bearer' added."
+  (cons (oauth2-authz-bearer-header (oauth2-token-access-token (car oauth--token-data)))
+        extra-headers))
+
+
+;; FIXME: We should change URL so that this can be done without an advice.
+(defadvice url-http-handle-authentication (around oauth-hack activate)
+  (if (not oauth--url-advice)
+      ad-do-it
+    (let ((url-request-method url-http-method)
+          (url-request-data url-http-data)
+          (url-request-extra-headers
+           (oauth2-extra-headers url-http-extra-headers))))
+    (oauth2-refresh-access (car oauth--token-data))
+    (url-retrieve-internal (cdr oauth--token-data)
+               url-callback-function
+               url-callback-arguments)
+    ;; This is to make `url' think it's done.
+    (when (boundp 'success) (setq success t)) ;For URL library in Emacs<24.4.
+    (setq ad-return-value t)))                ;For URL library in Emacs≥24.4.
+
+;;;###autoload
+(defun oauth2-url-retrieve-synchronously (token url &optional request-method request-data request-extra-headers)
+  "Retrieve an URL synchronously using TOKEN to access it.
+TOKEN can be obtained with `oauth2-auth'."
+  (let* ((oauth--token-data (cons token url)))
+    (let ((oauth--url-advice t)         ;Activate our advice.
+          (url-request-method request-method)
+          (url-request-data request-data)
+          (url-request-extra-headers
+           (oauth2-extra-headers request-extra-headers)))
+      (url-retrieve-synchronously url))))
+
+;;;###autoload
+(defun oauth2-url-retrieve (token url callback &optional
+                                  cbargs
+                                  request-method request-data request-extra-headers)
+  "Retrieve an URL asynchronously using TOKEN to access it.
+TOKEN can be obtained with `oauth2-auth'.  CALLBACK gets called with CBARGS
+when finished.  See `url-retrieve'."
+  ;; TODO add support for SILENT and INHIBIT-COOKIES.  How to handle this in `url-http-handle-authentication'.
+  (let* ((oauth--token-data (cons token url)))
+    (let ((oauth--url-advice t)         ;Activate our advice.
+          (url-request-method request-method)
+          (url-request-data request-data)
+          (url-request-extra-headers
+           (oauth2-extra-headers request-extra-headers)))
+      (url-retrieve url callback cbargs))))
+
+;;;; ChangeLog:
+
+;; 2016-07-09  Julien Danjou  <julien@danjou.info>
+;; 
+;; 	oauth2: send authentication token via Authorization header
+;; 
+;; 2014-01-28  Rüdiger Sonderfeld  <ruediger@c-plusplus.de>
+;; 
+;; 	oauth2.el: Add support for async retrieve.
+;; 
+;; 	* packages/oauth2/oauth2.el (oauth--tokens-need-renew): Remove.
+;; 	 (oauth--token-data): New variable.
+;; 	 (url-http-handle-authentication): Call `url-retrieve-internal'
+;; 	 directly instead of depending on `oauth--tokens-need-renew'.
+;; 	 (oauth2-url-retrieve-synchronously): Call `url-retrieve' once.
+;; 	 (oauth2-url-retrieve): New function.
+;; 
+;; 	Signed-off-by: Rüdiger Sonderfeld <ruediger@c-plusplus.de> 
+;; 	Signed-off-by: Julien Danjou <julien@danjou.info>
+;; 
+;; 2013-07-22  Stefan Monnier  <monnier@iro.umontreal.ca>
+;; 
+;; 	* oauth2.el: Only require CL at compile time and avoid flet.
+;; 	(success): Don't defvar.
+;; 	(oauth--url-advice, oauth--tokens-need-renew): New dynbind variables.
+;; 	(url-http-handle-authentication): Add advice.
+;; 	(oauth2-url-retrieve-synchronously): Use the advice instead of flet.
+;; 
+;; 2013-06-29  Julien Danjou  <julien@danjou.info>
+;; 
+;; 	oauth2: release 0.9, require url-http
+;; 
+;; 	This is needed so that the `flet' calls doesn't restore the overriden 
+;; 	function to an unbound one.
+;; 
+;; 	Signed-off-by: Julien Danjou <julien@danjou.info>
+;; 
+;; 2012-08-01  Julien Danjou  <julien@danjou.info>
+;; 
+;; 	oauth2: upgrade to 0.8, add missing require on cl
+;; 
+;; 2012-07-03  Julien Danjou  <julien@danjou.info>
+;; 
+;; 	oauth2: store access-reponse, bump versino to 0.7
+;; 
+;; 2012-06-25  Julien Danjou  <julien@danjou.info>
+;; 
+;; 	oauth2: add redirect-uri parameter, update to 0.6
+;; 
+;; 2012-05-29  Julien Danjou  <julien@danjou.info>
+;; 
+;; 	* packages/oauth2/oauth2.el: Revert fix URL double escaping, update to
+;; 	0.5
+;; 
+;; 2012-05-04  Julien Danjou  <julien@danjou.info>
+;; 
+;; 	* packages/oauth2/oauth2.el: Don't use aget, update to 0.4
+;; 
+;; 2012-04-19  Julien Danjou  <julien@danjou.info>
+;; 
+;; 	* packages/oauth2/oauth2.el: Fix URL double escaping, update to 0.3
+;; 
+;; 2011-12-20  Julien Danjou  <julien@danjou.info>
+;; 
+;; 	oauth2: update version 0.2
+;; 
+;; 	* oauth2: update version to 0.2
+;; 
+;; 2011-12-20  Julien Danjou  <julien@danjou.info>
+;; 
+;; 	oauth2: allow to use any HTTP request type
+;; 
+;; 	* oauth2: allow to use any HTTP request type
+;; 
+;; 2011-10-08  Julien Danjou  <julien@danjou.info>
+;; 
+;; 	* oauth2.el: Require json.
+;; 	 Fix compilation warning with success variable from url.el.
+;; 
+;; 2011-09-26  Julien Danjou  <julien@danjou.info>
+;; 
+;; 	* packages/oauth2/oauth2.el (oauth2-request-authorization): Add missing
+;; 	 calls to url-hexify-string.
+;; 
+;; 2011-09-26  Julien Danjou  <julien@danjou.info>
+;; 
+;; 	* packages/oauth2/oauth2.el: Reformat to avoid long lines.
+;; 
+;; 2011-09-23  Julien Danjou  <julien@danjou.info>
+;; 
+;; 	New package oauth2
+;; 
+
+
+(provide 'oauth2)
+
+;;; oauth2.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/oauth2-0.11/oauth2.elc b/configs/shared/emacs/.emacs.d/elpa/oauth2-0.11/oauth2.elc
new file mode 100644
index 0000000000..1a74d5e1a7
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/oauth2-0.11/oauth2.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/org-bullets-20171127.526/org-bullets-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/org-bullets-20171127.526/org-bullets-autoloads.el
new file mode 100644
index 0000000000..a10d87f671
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/org-bullets-20171127.526/org-bullets-autoloads.el
@@ -0,0 +1,22 @@
+;;; org-bullets-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "org-bullets" "org-bullets.el" (23377 61305
+;;;;;;  734407 586000))
+;;; Generated autoloads from org-bullets.el
+
+(autoload 'org-bullets-mode "org-bullets" "\
+Use UTF8 bullets in Org mode headings.
+
+\(fn &optional ARG)" t nil)
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; org-bullets-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/org-bullets-20171127.526/org-bullets-pkg.el b/configs/shared/emacs/.emacs.d/elpa/org-bullets-20171127.526/org-bullets-pkg.el
new file mode 100644
index 0000000000..26291d9daf
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/org-bullets-20171127.526/org-bullets-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "org-bullets" "20171127.526" "Show bullets in org-mode as UTF-8 characters" 'nil)
diff --git a/configs/shared/emacs/.emacs.d/elpa/org-bullets-20171127.526/org-bullets.el b/configs/shared/emacs/.emacs.d/elpa/org-bullets-20171127.526/org-bullets.el
new file mode 100644
index 0000000000..7238e81606
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/org-bullets-20171127.526/org-bullets.el
@@ -0,0 +1,143 @@
+;;; org-bullets.el --- Show bullets in org-mode as UTF-8 characters
+
+;; Version: 0.2.4
+;; Package-Version: 20171127.526
+;; Author: sabof
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+;; Homepage: https://github.com/emacsorphanage/org-bullets
+
+;; This file is NOT part of GNU Emacs.
+
+;; This file 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, or (at your option)
+;; any later version.
+
+;; This file 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.
+
+;; For a full copy of the GNU General Public License
+;; see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Show org-mode bullets as UTF-8 characters.
+
+;; Because the author is inactive, this package is currenlty being
+;; maintained at https://github.com/emacsorphanage/org-bullets.
+
+;;; Code:
+
+(defgroup org-bullets nil
+  "Display bullets as UTF-8 characters."
+  :group 'org-appearance)
+
+;; A nice collection of unicode bullets:
+;; http://nadeausoftware.com/articles/2007/11/latency_friendly_customized_bullets_using_unicode_characters
+(defcustom org-bullets-bullet-list
+  '(;;; Large
+    "◉"
+    "○"
+    "✸"
+    "✿"
+    ;; ♥ ● ◇ ✚ ✜ ☯ ◆ ♠ ♣ ♦ ☢ ❀ ◆ ◖ ▶
+    ;;; Small
+    ;; ► • ★ ▸
+    )
+  "List of bullets used in Org headings.
+It can contain any number of symbols, which will be repeated."
+  :group 'org-bullets
+  :type '(repeat (string :tag "Bullet character")))
+
+(defcustom org-bullets-face-name nil
+  "Face used for bullets in Org mode headings.
+If set to the name of a face, that face is used.
+Otherwise the face of the heading level is used."
+  :group 'org-bullets
+  :type 'symbol)
+
+(defvar org-bullets-bullet-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map [mouse-1] 'org-cycle)
+    (define-key map [mouse-2] 'org-bullets-set-point-and-cycle)
+    map)
+  "Mouse events for bullets.
+Should this be undesirable, one can remove them with
+
+\(setcdr org-bullets-bullet-map nil\)")
+
+(defun org-bullets-set-point-and-cycle (event)
+  "Set `point' and where the user clicked and call `org-cycle'."
+  (interactive "e")
+  (mouse-set-point e)
+  (org-cycle))
+
+(defun org-bullets-level-char (level)
+  (string-to-char
+   (nth (mod (1- level)
+             (length org-bullets-bullet-list))
+        org-bullets-bullet-list)))
+
+(defvar org-bullets--keywords
+  `(("^\\*+ "
+     (0 (let* ((level (- (match-end 0) (match-beginning 0) 1))
+               (is-inline-task
+                (and (boundp 'org-inlinetask-min-level)
+                     (>= level org-inlinetask-min-level))))
+          (compose-region (- (match-end 0) 2)
+                          (- (match-end 0) 1)
+                          (org-bullets-level-char level))
+          (when is-inline-task
+            (compose-region (- (match-end 0) 3)
+                            (- (match-end 0) 2)
+                            (org-bullets-level-char level)))
+          (when (facep org-bullets-face-name)
+            (put-text-property (- (match-end 0)
+                                  (if is-inline-task 3 2))
+                               (- (match-end 0) 1)
+                               'face
+                               org-bullets-face-name))
+          (put-text-property (match-beginning 0)
+                             (- (match-end 0) 2)
+                             'face (list :foreground
+                                         (face-attribute
+                                          'default :background)))
+          (put-text-property (match-beginning 0)
+                             (match-end 0)
+                             'keymap
+                             org-bullets-bullet-map)
+          nil)))))
+
+;;;###autoload
+(define-minor-mode org-bullets-mode
+  "Use UTF8 bullets in Org mode headings."
+  nil nil nil
+  (if org-bullets-mode
+      (progn
+        (font-lock-add-keywords nil org-bullets--keywords)
+        (org-bullets--fontify-buffer))
+    (save-excursion
+      (goto-char (point-min))
+      (font-lock-remove-keywords nil org-bullets--keywords)
+      (while (re-search-forward "^\\*+ " nil t)
+        (decompose-region (match-beginning 0) (match-end 0)))
+      (org-bullets--fontify-buffer))))
+
+(defun org-bullets--fontify-buffer ()
+  (when font-lock-mode
+    (if (and (fboundp 'font-lock-flush)
+             (fboundp 'font-lock-ensure))
+        (save-restriction
+          (widen)
+          (font-lock-flush)
+          (font-lock-ensure))
+      (with-no-warnings
+        (font-lock-fontify-buffer)))))
+
+(provide 'org-bullets)
+;; Local Variables:
+;; indent-tabs-mode: nil
+;; End:
+;;; org-bullets.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/org-bullets-20171127.526/org-bullets.elc b/configs/shared/emacs/.emacs.d/elpa/org-bullets-20171127.526/org-bullets.elc
new file mode 100644
index 0000000000..1bff61f7ae
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/org-bullets-20171127.526/org-bullets.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/paredit-20171126.1805/paredit-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/paredit-20171126.1805/paredit-autoloads.el
new file mode 100644
index 0000000000..9b9895e14a
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/paredit-20171126.1805/paredit-autoloads.el
@@ -0,0 +1,33 @@
+;;; paredit-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "paredit" "paredit.el" (23377 61263 887082
+;;;;;;  765000))
+;;; Generated autoloads from paredit.el
+
+(autoload 'paredit-mode "paredit" "\
+Minor mode for pseudo-structurally editing Lisp code.
+With a prefix argument, enable Paredit Mode even if there are
+  unbalanced parentheses in the buffer.
+Paredit behaves badly if parentheses are unbalanced, so exercise
+  caution when forcing Paredit Mode to be enabled, and consider
+  fixing unbalanced parentheses instead.
+\\<paredit-mode-map>
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'enable-paredit-mode "paredit" "\
+Turn on pseudo-structural editing of Lisp code.
+
+\(fn)" t nil)
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; paredit-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/paredit-20171126.1805/paredit-pkg.el b/configs/shared/emacs/.emacs.d/elpa/paredit-20171126.1805/paredit-pkg.el
new file mode 100644
index 0000000000..e054a843c8
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/paredit-20171126.1805/paredit-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "paredit" "20171126.1805" "minor mode for editing parentheses" 'nil)
diff --git a/configs/shared/emacs/.emacs.d/elpa/paredit-20171126.1805/paredit.el b/configs/shared/emacs/.emacs.d/elpa/paredit-20171126.1805/paredit.el
new file mode 100644
index 0000000000..9f2bdfb6a7
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/paredit-20171126.1805/paredit.el
@@ -0,0 +1,2929 @@
+;;; paredit.el --- minor mode for editing parentheses  -*- Mode: Emacs-Lisp -*-
+
+;; Copyright (C) 2005--2017 Taylor R. Campbell
+
+;; Author: Taylor R. Campbell <campbell+paredit@mumble.net>
+;; Version: 25beta
+;; Package-Version: 20171126.1805
+;; Created: 2005-07-31
+;; Keywords: lisp
+
+;; NOTE:  THIS IS A BETA VERSION OF PAREDIT.  USE AT YOUR OWN RISK.
+;; THIS FILE IS SUBJECT TO CHANGE, AND NOT SUITABLE FOR DISTRIBUTION
+;; BY PACKAGE MANAGERS SUCH AS APT, PKGSRC, MACPORTS, &C.
+
+;; Paredit 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.
+;;
+;; Paredit 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 paredit.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; The currently released version of paredit is available at
+;;;   <https://mumble.net/~campbell/emacs/paredit.el>.
+;;;
+;;; The latest beta version of paredit is available at
+;;;   <https://mumble.net/~campbell/emacs/paredit-beta.el>.
+;;;
+;;; The Git repository for paredit is available at
+;;;   <https://mumble.net/~campbell/git/paredit.git>
+;;;
+;;; Release notes are available at
+;;;   <https://mumble.net/~campbell/emacs/paredit.release>.
+
+;;; Install paredit by placing `paredit.el' in `/path/to/elisp', a
+;;; directory of your choice, and adding to your .emacs file:
+;;;
+;;;   (add-to-list 'load-path "/path/to/elisp")
+;;;   (autoload 'enable-paredit-mode "paredit"
+;;;     "Turn on pseudo-structural editing of Lisp code."
+;;;     t)
+;;;
+;;; Start Paredit Mode on the fly with `M-x enable-paredit-mode RET',
+;;; or always enable it in a major mode `M' (e.g., `lisp') with:
+;;;
+;;;   (add-hook 'M-mode-hook 'enable-paredit-mode)
+;;;
+;;; Customize paredit using `eval-after-load':
+;;;
+;;;   (eval-after-load 'paredit
+;;;     '(progn
+;;;        (define-key paredit-mode-map (kbd "ESC M-A-C-s-)")
+;;;          'paredit-dwim)))
+;;;
+;;; Send questions, bug reports, comments, feature suggestions, &c.,
+;;; via email to the author's surname at mumble.net.
+;;;
+;;; Paredit should run in GNU Emacs 21 or later and XEmacs 21.5.28 or
+;;; later.
+
+;;; The paredit minor mode, Paredit Mode, binds common character keys,
+;;; such as `(', `)', `"', and `\', to commands that carefully insert
+;;; S-expression structures in the buffer:
+;;;
+;;;   ( inserts `()', leaving the point in the middle;
+;;;   ) moves the point over the next closing delimiter;
+;;;   " inserts `""' if outside a string, or inserts an escaped
+;;;      double-quote if in the middle of a string, or moves over the
+;;;      closing double-quote if at the end of a string; and
+;;;   \ prompts for the character to escape, to avoid inserting lone
+;;;      backslashes that may break structure.
+;;;
+;;; In comments, these keys insert themselves.  If necessary, you can
+;;; insert these characters literally outside comments by pressing
+;;; `C-q' before these keys, in case a mistake has broken the
+;;; structure.
+;;;
+;;; These key bindings are designed so that when typing new code in
+;;; Paredit Mode, you can generally type exactly the same sequence of
+;;; keys you would have typed without Paredit Mode.
+;;;
+;;; Paredit Mode also binds common editing keys, such as `DEL', `C-d',
+;;; and `C-k', to commands that respect S-expression structures in the
+;;; buffer:
+;;;
+;;;   DEL deletes the previous character, unless it is a delimiter: DEL
+;;;        will move the point backward over a closing delimiter, and
+;;;        will delete a delimiter pair together if between an open and
+;;;        closing delimiter;
+;;;
+;;;   C-d deletes the next character in much the same manner; and
+;;;
+;;;   C-k kills all S-expressions that begin anywhere between the point
+;;;        and the end of the line or the closing delimiter of the
+;;;        enclosing list, whichever is first.
+;;;
+;;; If necessary, you can delete a character, kill a line, &c.,
+;;; irrespective of S-expression structure, by pressing `C-u' before
+;;; these keys, in case a mistake has broken the structure.
+;;;
+;;; Finally, Paredit Mode binds some keys to complex S-expression
+;;; editing operations.  For example, `C-<right>' makes the enclosing
+;;; list slurp up an S-expression to its right (here `|' denotes the
+;;; point):
+;;;
+;;;   (foo (bar | baz) quux)  C-<right>  (foo (bar | baz quux))
+;;;
+;;; Some paredit commands automatically reindent code.  When they do,
+;;; they try to indent as locally as possible, to avoid interfering
+;;; with any indentation you might have manually written.  Only the
+;;; advanced S-expression manipulation commands automatically reindent,
+;;; and only the forms that they immediately operated upon (and their
+;;; subforms).
+;;;
+;;; This code is written for clarity, not efficiency.  It frequently
+;;; walks over S-expressions redundantly.  If you have problems with
+;;; the time it takes to execute some of the commands, let me know.
+
+;;; This assumes Unix-style LF line endings.
+
+(defconst paredit-version 25)
+(defconst paredit-beta-p t)
+
+(eval-and-compile
+
+  (defun paredit-xemacs-p ()
+    ;; No idea where I got this definition from.  Edward O'Connor
+    ;; (hober in #emacs) suggested the current definition.
+    ;;   (and (boundp 'running-xemacs)
+    ;;        running-xemacs)
+    (featurep 'xemacs))
+
+  (defun paredit-gnu-emacs-p ()
+    ;++ This could probably be improved.
+    (not (paredit-xemacs-p)))
+
+  (defmacro xcond (&rest clauses)
+    "Exhaustive COND.
+Signal an error if no clause matches."
+    `(cond ,@clauses
+           (t (error "XCOND lost."))))
+
+  (defalias 'paredit-warn (if (fboundp 'warn) 'warn 'message))
+
+  (defvar paredit-sexp-error-type
+    (with-temp-buffer
+      (insert "(")
+      (condition-case condition
+          (backward-sexp)
+        (error (if (eq (car condition) 'error)
+                   (paredit-warn "%s%s%s%s%s"
+                                 "Paredit is unable to discriminate"
+                                 " S-expression parse errors from"
+                                 " other errors. "
+                                 " This may cause obscure problems. "
+                                 " Please upgrade Emacs."))
+               (car condition)))))
+
+  (defmacro paredit-handle-sexp-errors (body &rest handler)
+    `(condition-case ()
+         ,body
+       (,paredit-sexp-error-type ,@handler)))
+
+  (put 'paredit-handle-sexp-errors 'lisp-indent-function 1)
+
+  (defmacro paredit-ignore-sexp-errors (&rest body)
+    `(paredit-handle-sexp-errors (progn ,@body)
+       nil))
+
+  (put 'paredit-ignore-sexp-errors 'lisp-indent-function 0)
+
+  (defmacro paredit-preserving-column (&rest body)
+    "Evaluate BODY and restore point to former column, relative to code.
+Assumes BODY will change only indentation.
+If point was on code, it moves with the code.
+If point was on indentation, it stays in indentation."
+    (let ((column (make-symbol "column"))
+          (indentation (make-symbol "indentation")))
+      `(let ((,column (current-column))
+             (,indentation (paredit-current-indentation)))
+         (let ((value (progn ,@body)))
+           (paredit-restore-column ,column ,indentation)
+           value))))
+
+  (put 'paredit-preserving-column 'lisp-indent-function 0)
+
+  nil)
+
+;;;; Minor Mode Definition
+
+(defvar paredit-lighter " Paredit"
+  "Mode line lighter Paredit Mode.")
+
+(defvar paredit-mode-map (make-sparse-keymap)
+  "Keymap for the paredit minor mode.")
+
+(defvar paredit-override-check-parens-function
+  (lambda (condition) condition nil)
+  "Function to tell whether unbalanced text should inhibit Paredit Mode.")
+
+;;;###autoload
+(define-minor-mode paredit-mode
+  "Minor mode for pseudo-structurally editing Lisp code.
+With a prefix argument, enable Paredit Mode even if there are
+  unbalanced parentheses in the buffer.
+Paredit behaves badly if parentheses are unbalanced, so exercise
+  caution when forcing Paredit Mode to be enabled, and consider
+  fixing unbalanced parentheses instead.
+\\<paredit-mode-map>"
+  :lighter paredit-lighter
+  ;; Setting `paredit-mode' to false here aborts enabling Paredit Mode.
+  (if (and paredit-mode
+           (not current-prefix-arg))
+      (condition-case condition
+          (check-parens)
+        (error
+         (if (not (funcall paredit-override-check-parens-function condition))
+             (progn (setq paredit-mode nil)
+                    (signal (car condition) (cdr condition))))))))
+
+(defun paredit-override-check-parens-interactively (condition)
+  (y-or-n-p (format "Enable Paredit Mode despite condition %S? " condition)))
+
+;;;###autoload
+(defun enable-paredit-mode ()
+  "Turn on pseudo-structural editing of Lisp code."
+  (interactive)
+  (paredit-mode +1))
+
+(defun disable-paredit-mode ()
+  "Turn off pseudo-structural editing of Lisp code."
+  (interactive)
+  (paredit-mode -1))
+
+(defvar paredit-backward-delete-key
+  (xcond ((paredit-xemacs-p)    "BS")
+         ((paredit-gnu-emacs-p) "DEL")))
+
+(defvar paredit-forward-delete-keys
+  (xcond ((paredit-xemacs-p)    '("DEL"))
+         ((paredit-gnu-emacs-p) '("<delete>" "<deletechar>"))))
+
+;;;; Paredit Keys
+
+;;; Separating the definition and initialization of this variable
+;;; simplifies the development of paredit, since re-evaluating DEFVAR
+;;; forms doesn't actually do anything.
+
+(defvar paredit-commands nil
+  "List of paredit commands with their keys and examples.")
+
+;;; Each specifier is of the form:
+;;;   (key[s] function (example-input example-output) ...)
+;;; where key[s] is either a single string suitable for passing to KBD
+;;; or a list of such strings.  Entries in this list may also just be
+;;; strings, in which case they are headings for the next entries.
+
+(progn (setq paredit-commands
+ `(
+   "Basic Insertion Commands"
+   ("("         paredit-open-round
+                ("(a b |c d)"
+                 "(a b (|) c d)")
+                ("(foo \"bar |baz\" quux)"
+                 "(foo \"bar (|baz\" quux)"))
+   (")"         paredit-close-round
+                ("(a b |c   )" "(a b c)|")
+                ("; Hello,| world!"
+                 "; Hello,)| world!"))
+   ("M-)"       paredit-close-round-and-newline
+                ("(defun f (x|  ))"
+                 "(defun f (x)\n  |)")
+                ("; (Foo.|"
+                 "; (Foo.)|"))
+   ("["         paredit-open-square
+                ("(a b |c d)"
+                 "(a b [|] c d)")
+                ("(foo \"bar |baz\" quux)"
+                 "(foo \"bar [|baz\" quux)"))
+   ("]"         paredit-close-square
+                ("(define-key keymap [frob|  ] 'frobnicate)"
+                 "(define-key keymap [frob]| 'frobnicate)")
+                ("; [Bar.|"
+                 "; [Bar.]|"))
+
+   ("\""        paredit-doublequote
+                ("(frob grovel |full lexical)"
+                 "(frob grovel \"|\" full lexical)"
+                 "(frob grovel \"\"| full lexical)")
+                ("(foo \"bar |baz\" quux)"
+                 "(foo \"bar \\\"|baz\" quux)")
+                ("(frob grovel)   ; full |lexical"
+                 "(frob grovel)   ; full \"|lexical"))
+   ("M-\""      paredit-meta-doublequote
+                ("(foo \"bar |baz\" quux)"
+                 "(foo \"bar baz\"| quux)")
+                ("(foo |(bar #\\x \"baz \\\\ quux\") zot)"
+                 ,(concat "(foo \"|(bar #\\\\x \\\"baz \\\\"
+                          "\\\\ quux\\\")\" zot)")))
+   ("\\"        paredit-backslash
+                ("(string #|)\n  ; Character to escape: x"
+                 "(string #\\x|)")
+                ("\"foo|bar\"\n  ; Character to escape: \""
+                 "\"foo\\\"|bar\""))
+   (";"         paredit-semicolon
+                ("|(frob grovel)"
+                 ";|(frob grovel)")
+                ("(frob |grovel)"
+                 "(frob ;|grovel\n )")
+                ("(frob |grovel (bloit\n               zargh))"
+                 "(frob ;|grovel\n (bloit\n  zargh))")
+                ("(frob grovel)          |"
+                 "(frob grovel)          ;|"))
+   ("M-;"       paredit-comment-dwim
+                ("(foo |bar)   ; baz"
+                 "(foo bar)                               ; |baz")
+                ("(frob grovel)|"
+                 "(frob grovel)                           ;|")
+                ("(zot (foo bar)\n|\n     (baz quux))"
+                 "(zot (foo bar)\n     ;; |\n     (baz quux))")
+                ("(zot (foo bar) |(baz quux))"
+                 "(zot (foo bar)\n     ;; |\n     (baz quux))")
+                ("|(defun hello-world ...)"
+                 ";;; |\n(defun hello-world ...)"))
+
+   ("C-j"       paredit-newline
+                ("(let ((n (frobbotz))) |(display (+ n 1)\nport))"
+                 ,(concat "(let ((n (frobbotz)))"
+                          "\n  |(display (+ n 1)"
+                          "\n           port))")))
+
+   "Deleting & Killing"
+   (("C-d" ,@paredit-forward-delete-keys)
+                paredit-forward-delete
+                ("(quu|x \"zot\")" "(quu| \"zot\")")
+                ("(quux |\"zot\")"
+                 "(quux \"|zot\")"
+                 "(quux \"|ot\")")
+                ("(foo (|) bar)" "(foo | bar)")
+                ("|(foo bar)" "(|foo bar)"))
+   (,paredit-backward-delete-key
+                paredit-backward-delete
+                ("(\"zot\" q|uux)" "(\"zot\" |uux)")
+                ("(\"zot\"| quux)"
+                 "(\"zot|\" quux)"
+                 "(\"zo|\" quux)")
+                ("(foo (|) bar)" "(foo | bar)")
+                ("(foo bar)|" "(foo bar|)"))
+   ("C-k"       paredit-kill
+                ("(foo bar)|     ; Useless comment!"
+                 "(foo bar)|")
+                ("(|foo bar)     ; Useful comment!"
+                 "(|)     ; Useful comment!")
+                ("|(foo bar)     ; Useless line!"
+                 "|")
+                ("(foo \"|bar baz\"\n     quux)"
+                 "(foo \"|\"\n     quux)"))
+   ("M-d"       paredit-forward-kill-word
+                ("|(foo bar)    ; baz"
+                 "(| bar)    ; baz"
+                 "(|)    ; baz"
+                 "()    ;|")
+                (";;;| Frobnicate\n(defun frobnicate ...)"
+                 ";;;|\n(defun frobnicate ...)"
+                 ";;;\n(| frobnicate ...)"))
+   (,(concat "M-" paredit-backward-delete-key)
+                paredit-backward-kill-word
+                ("(foo bar)    ; baz\n(quux)|"
+                 "(foo bar)    ; baz\n(|)"
+                 "(foo bar)    ; |\n()"
+                 "(foo |)    ; \n()"
+                 "(|)    ; \n()"))
+
+   "Movement & Navigation"
+   ("C-M-f"     paredit-forward
+                ("(foo |(bar baz) quux)"
+                 "(foo (bar baz)| quux)")
+                ("(foo (bar)|)"
+                 "(foo (bar))|"))
+   ("C-M-b"     paredit-backward
+                ("(foo (bar baz)| quux)"
+                 "(foo |(bar baz) quux)")
+                ("(|(foo) bar)"
+                 "|((foo) bar)"))
+   ("C-M-u"     paredit-backward-up)
+   ("C-M-d"     paredit-forward-down)
+   ("C-M-p"     paredit-backward-down)  ; Built-in, these are FORWARD-
+   ("C-M-n"     paredit-forward-up)     ; & BACKWARD-LIST, which have
+                                        ; no need given C-M-f & C-M-b.
+
+   "Depth-Changing Commands"
+   ("M-("       paredit-wrap-round
+                ("(foo |bar baz)"
+                 "(foo (|bar) baz)"))
+   ("M-s"       paredit-splice-sexp
+                ("(foo (bar| baz) quux)"
+                 "(foo bar| baz quux)"))
+   (("M-<up>" "ESC <up>")
+                paredit-splice-sexp-killing-backward
+                ("(foo (let ((x 5)) |(sqrt n)) bar)"
+                 "(foo |(sqrt n) bar)"))
+   (("M-<down>" "ESC <down>")
+                paredit-splice-sexp-killing-forward
+                ("(a (b c| d e) f)"
+                 "(a b c| f)"))
+   ("M-r"       paredit-raise-sexp
+                ("(dynamic-wind in (lambda () |body) out)"
+                 "(dynamic-wind in |body out)"
+                 "|body"))
+   ("M-?"       paredit-convolute-sexp
+                ("(let ((x 5) (y 3)) (frob |(zwonk)) (wibblethwop))"
+                 "(frob |(let ((x 5) (y 3)) (zwonk) (wibblethwop)))"))
+
+   "Barfage & Slurpage"
+   (("C-)" "C-<right>")
+                paredit-forward-slurp-sexp
+                ("(foo (bar |baz) quux zot)"
+                 "(foo (bar |baz quux) zot)")
+                ("(a b ((c| d)) e f)"
+                 "(a b ((c| d) e) f)"))
+   (("C-}" "C-<left>")
+                paredit-forward-barf-sexp
+                ("(foo (bar |baz quux) zot)"
+                 "(foo (bar |baz) quux zot)"))
+   (("C-(" "C-M-<left>" "ESC C-<left>")
+                paredit-backward-slurp-sexp
+                ("(foo bar (baz| quux) zot)"
+                 "(foo (bar baz| quux) zot)")
+                ("(a b ((c| d)) e f)"
+                 "(a (b (c| d)) e f)"))
+   (("C-{" "C-M-<right>" "ESC C-<right>")
+                paredit-backward-barf-sexp
+                ("(foo (bar baz |quux) zot)"
+                 "(foo bar (baz |quux) zot)"))
+
+   "Miscellaneous Commands"
+   ("M-S"       paredit-split-sexp
+                ("(hello| world)"
+                 "(hello)| (world)")
+                ("\"Hello, |world!\""
+                 "\"Hello, \"| \"world!\""))
+   ("M-J"       paredit-join-sexps
+                ("(hello)| (world)"
+                 "(hello| world)")
+                ("\"Hello, \"| \"world!\""
+                 "\"Hello, |world!\"")
+                ("hello-\n|  world"
+                 "hello-|world"))
+   ("C-c C-M-l" paredit-recenter-on-sexp)
+   ("M-q"       paredit-reindent-defun)
+   ))
+       nil)                             ; end of PROGN
+
+;;;;; Command Examples
+
+(eval-and-compile
+  (defmacro paredit-do-commands (vars string-case &rest body)
+    (let ((spec     (nth 0 vars))
+          (keys     (nth 1 vars))
+          (fn       (nth 2 vars))
+          (examples (nth 3 vars)))
+      `(dolist (,spec paredit-commands)
+         (if (stringp ,spec)
+             ,string-case
+           (let ((,keys (let ((k (car ,spec)))
+                          (cond ((stringp k) (list k))
+                                ((listp k) k)
+                                (t (error "Invalid paredit command %s."
+                                          ,spec)))))
+                 (,fn (cadr ,spec))
+                 (,examples (cddr ,spec)))
+             ,@body)))))
+
+  (put 'paredit-do-commands 'lisp-indent-function 2))
+
+(defun paredit-define-keys ()
+  (paredit-do-commands (spec keys fn examples)
+      nil       ; string case
+    (dolist (key keys)
+      (define-key paredit-mode-map (read-kbd-macro key) fn))))
+
+(defun paredit-function-documentation (fn)
+  (let ((original-doc (get fn 'paredit-original-documentation))
+        (doc (documentation fn 'function-documentation)))
+    (or original-doc
+        (progn (put fn 'paredit-original-documentation doc)
+               doc))))
+
+(defun paredit-annotate-mode-with-examples ()
+  (let ((contents
+         (list (paredit-function-documentation 'paredit-mode))))
+    (paredit-do-commands (spec keys fn examples)
+        (push (concat "\n\n" spec "\n")
+              contents)
+      (let ((name (symbol-name fn)))
+        (if (string-match (symbol-name 'paredit-) name)
+            (push (concat "\n\n\\[" name "]\t" name
+                          (if examples
+                              (mapconcat (lambda (example)
+                                           (concat
+                                            "\n"
+                                            (mapconcat 'identity
+                                                       example
+                                                       "\n  --->\n")
+                                            "\n"))
+                                         examples
+                                         "")
+                              "\n  (no examples)\n"))
+                  contents))))
+    (put 'paredit-mode 'function-documentation
+         (apply 'concat (reverse contents))))
+  ;; PUT returns the huge string we just constructed, which we don't
+  ;; want it to return.
+  nil)
+
+(defun paredit-annotate-functions-with-examples ()
+  (paredit-do-commands (spec keys fn examples)
+      nil       ; string case
+    (put fn 'function-documentation
+         (concat (paredit-function-documentation fn)
+                 "\n\n\\<paredit-mode-map>\\[" (symbol-name fn) "]\n"
+                 (mapconcat (lambda (example)
+                              (concat "\n"
+                                      (mapconcat 'identity
+                                                 example
+                                                 "\n  ->\n")
+                                      "\n"))
+                            examples
+                            "")))))
+
+;;;;; HTML Examples
+
+(defun paredit-insert-html-examples ()
+  "Insert HTML for a paredit quick reference table."
+  (interactive)
+  (let ((insert-lines
+         (lambda (&rest lines) (dolist (line lines) (insert line) (newline))))
+        (initp nil))
+    (paredit-do-commands (spec keys fn examples)
+        (progn (if initp
+                   (funcall insert-lines "</table>")
+                   (setq initp t))
+               (funcall insert-lines (concat "<h3>" spec "</h3>"))
+               (funcall insert-lines "<table>"))
+      (let ((name (symbol-name fn))
+            (keys
+             (mapconcat (lambda (key)
+                          (concat "<tt>" (paredit-html-quote key) "</tt>"))
+                        keys
+                        ", ")))
+        (funcall insert-lines "<tr>")
+        (funcall insert-lines (concat "  <th align=\"left\">" keys "</th>"))
+        (funcall insert-lines (concat "  <th align=\"left\">" name "</th>"))
+        (funcall insert-lines "</tr>")
+        (funcall insert-lines
+                 "<tr><td colspan=\"2\"><table cellpadding=\"5\"><tr>")
+        (dolist (example examples)
+          (let ((prefix "<td><table border=\"1\"><tr><td><table><tr><td><pre>")
+                (examples
+                 (mapconcat 'paredit-html-quote
+                            example
+                            (concat "</pre></td></tr>"
+                                    "<tr><th>&darr;</th></tr>"
+                                    "<tr><td><pre>")))
+                (suffix "</pre></td></tr></table></td></tr></table></td>"))
+            (funcall insert-lines (concat prefix examples suffix))))
+        (funcall insert-lines "</tr></table></td></tr>")))
+    (funcall insert-lines "</table>")))
+
+(defun paredit-html-quote (string)
+  (with-temp-buffer
+    (dotimes (i (length string))
+      (insert (let ((c (elt string i)))
+                (cond ((eq c ?\<) "&lt;")
+                      ((eq c ?\>) "&gt;")
+                      ((eq c ?\&) "&amp;")
+                      ((eq c ?\') "&apos;")
+                      ((eq c ?\") "&quot;")
+                      (t c)))))
+    (buffer-string)))
+
+;;;; Delimiter Insertion
+
+(eval-and-compile
+  (defun paredit-conc-name (&rest strings)
+    (intern (apply 'concat strings)))
+
+  (defmacro define-paredit-pair (open close name)
+    `(progn
+       (defun ,(paredit-conc-name "paredit-open-" name) (&optional n)
+         ,(concat "Insert a balanced " name " pair.
+With a prefix argument N, put the closing " name " after N
+  S-expressions forward.
+If the region is active, `transient-mark-mode' is enabled, and the
+  region's start and end fall in the same parenthesis depth, insert a
+  " name " pair around the region.
+If in a string or a comment, insert a single " name ".
+If in a character literal, do nothing.  This prevents changing what was
+  in the character literal to a meaningful delimiter unintentionally.")
+         (interactive "P")
+         (cond ((or (paredit-in-string-p)
+                    (paredit-in-comment-p))
+                (insert ,open))
+               ((not (paredit-in-char-p))
+                (paredit-insert-pair n ,open ,close 'goto-char)
+                (save-excursion (backward-up-list) (indent-sexp)))))
+       (defun ,(paredit-conc-name "paredit-close-" name) ()
+         ,(concat "Move past one closing delimiter and reindent.
+\(Agnostic to the specific closing delimiter.)
+If in a string or comment, insert a single closing " name ".
+If in a character literal, do nothing.  This prevents changing what was
+  in the character literal to a meaningful delimiter unintentionally.")
+         (interactive)
+         (paredit-move-past-close ,close))
+       (defun ,(paredit-conc-name "paredit-close-" name "-and-newline") ()
+         ,(concat "Move past one closing delimiter, add a newline,"
+                  " and reindent.
+If there was a margin comment after the closing delimiter, preserve it
+  on the same line.")
+         (interactive)
+         (paredit-move-past-close-and-newline ,close))
+       (defun ,(paredit-conc-name "paredit-wrap-" name)
+           (&optional argument)
+         ,(concat "Wrap the following S-expression.
+See `paredit-wrap-sexp' for more details.")
+         (interactive "P")
+         (paredit-wrap-sexp argument ,open ,close))
+       (add-to-list 'paredit-wrap-commands
+                    ',(paredit-conc-name "paredit-wrap-" name)))))
+
+(defvar paredit-wrap-commands '(paredit-wrap-sexp)
+  "List of paredit commands that wrap S-expressions.
+Used by `paredit-yank-pop'; for internal paredit use only.")
+
+(define-paredit-pair ?\( ?\) "round")
+(define-paredit-pair ?\[ ?\] "square")
+(define-paredit-pair ?\{ ?\} "curly")
+(define-paredit-pair ?\< ?\> "angled")
+
+;;; Aliases for the old names.
+
+(defalias 'paredit-open-parenthesis 'paredit-open-round)
+(defalias 'paredit-close-parenthesis 'paredit-close-round)
+(defalias 'paredit-close-parenthesis-and-newline
+  'paredit-close-round-and-newline)
+
+(defalias 'paredit-open-bracket 'paredit-open-square)
+(defalias 'paredit-close-bracket 'paredit-close-square)
+(defalias 'paredit-close-bracket-and-newline
+  'paredit-close-square-and-newline)
+
+(defun paredit-move-past-close (close)
+  (paredit-move-past-close-and close
+    (lambda ()
+      (paredit-blink-paren-match nil))))
+
+(defun paredit-move-past-close-and-newline (close)
+  (paredit-move-past-close-and close
+    (lambda ()
+      (let ((comment.point (paredit-find-comment-on-line)))
+        (newline)
+        (if comment.point
+            (save-excursion
+              (forward-line -1)
+              (end-of-line)
+              (indent-to (cdr comment.point))
+              (insert (car comment.point)))))
+      (lisp-indent-line)
+      (paredit-ignore-sexp-errors (indent-sexp))
+      (paredit-blink-paren-match t))))
+
+(defun paredit-move-past-close-and (close if-moved)
+  (if (or (paredit-in-string-p)
+          (paredit-in-comment-p))
+      (insert close)
+    (if (paredit-in-char-p) (forward-char))
+    (paredit-move-past-close-and-reindent close)
+    (funcall if-moved)))
+
+(defun paredit-find-comment-on-line ()
+  "Find a margin comment on the current line.
+Return nil if there is no such comment or if there is anything but
+  whitespace until such a comment.
+If such a comment exists, delete the comment (including all leading
+  whitespace) and return a cons whose car is the comment as a string
+  and whose cdr is the point of the comment's initial semicolon,
+  relative to the start of the line."
+  (save-excursion
+    (paredit-skip-whitespace t (point-at-eol))
+    (and (eq ?\; (char-after))
+         (not (eq ?\; (char-after (1+ (point)))))
+         (not (or (paredit-in-string-p)
+                  (paredit-in-char-p)))
+         (let* ((start                  ;Move to before the semicolon.
+                 (progn (backward-char) (point)))
+                (comment
+                 (buffer-substring start (point-at-eol))))
+           (paredit-skip-whitespace nil (point-at-bol))
+           (delete-region (point) (point-at-eol))
+           (cons comment (- start (point-at-bol)))))))
+
+(defun paredit-insert-pair (n open close forward)
+  (let* ((regionp
+          (and (paredit-region-active-p)
+               (paredit-region-safe-for-insert-p)))
+         (end
+          (and regionp
+               (not n)
+               (prog1 (region-end) (goto-char (region-beginning))))))
+    (let ((spacep (paredit-space-for-delimiter-p nil open)))
+      (if spacep (insert " "))
+      (insert open)
+      (save-excursion
+        ;; Move past the desired region.
+        (cond (n
+               (funcall forward
+                        (paredit-scan-sexps-hack (point)
+                                                 (prefix-numeric-value n))))
+              (regionp
+               (funcall forward (+ end (if spacep 2 1)))))
+        ;; The string case can happen if we are inserting string
+        ;; delimiters.  The comment case may happen by moving to the
+        ;; end of a buffer that has a comment with no trailing newline.
+        (if (and (not (paredit-in-string-p))
+                 (paredit-in-comment-p))
+            (newline))
+        (insert close)
+        (if (paredit-space-for-delimiter-p t close)
+            (insert " "))))))
+
+;++ This needs a better name...
+
+(defun paredit-scan-sexps-hack (point n)
+  (save-excursion
+    (goto-char point)
+    (let ((direction (if (< 0 n) +1 -1))
+          (magnitude (abs n))
+          (count 0))
+      (catch 'exit
+        (while (< count magnitude)
+          (let ((p
+                 (paredit-handle-sexp-errors (scan-sexps (point) direction)
+                   nil)))
+            (if (not p) (throw 'exit nil))
+            (goto-char p))
+          (setq count (+ count 1)))))
+    (point)))
+
+(defun paredit-region-safe-for-insert-p ()
+  (save-excursion
+    (let ((beginning (region-beginning))
+          (end (region-end)))
+      (goto-char beginning)
+      (let* ((beginning-state (paredit-current-parse-state))
+             (end-state
+              (parse-partial-sexp beginning end nil nil beginning-state)))
+        (and (=  (nth 0 beginning-state)   ; 0. depth in parens
+                 (nth 0 end-state))
+             (eq (nth 3 beginning-state)   ; 3. non-nil if inside a
+                 (nth 3 end-state))        ;    string
+             (eq (nth 4 beginning-state)   ; 4. comment status, yada
+                 (nth 4 end-state))
+             (eq (nth 5 beginning-state)   ; 5. t if following char
+                 (nth 5 end-state)))))))   ;    quote
+
+(defvar paredit-space-for-delimiter-predicates nil
+  "List of predicates for whether to put space by delimiter at point.
+Each predicate is a function that is is applied to two arguments, ENDP
+  and DELIMITER, and that returns a boolean saying whether to put a
+  space next to the delimiter -- before/after the delimiter if ENDP is
+  false/true, respectively.
+If any predicate returns false, no space is inserted: every predicate
+  has veto power.
+Each predicate may assume that the point is not at the beginning/end of
+  the buffer, and that the point is preceded/followed by a word
+  constituent, symbol constituent, string quote, or delimiter matching
+  DELIMITER, if ENDP is false/true, respectively.
+Each predicate should examine only text before/after the point if ENDP is
+  false/true, respectively.")
+
+(defun paredit-space-for-delimiter-p (endp delimiter)
+  ;; If at the buffer limit, don't insert a space.  If there is a word,
+  ;; symbol, other quote, or non-matching parenthesis delimiter (i.e. a
+  ;; close when want an open the string or an open when we want to
+  ;; close the string), do insert a space.
+  (and (not (if endp (eobp) (bobp)))
+       (memq (char-syntax (if endp (char-after) (char-before)))
+             (list ?w ?_ ?\"
+                   (let ((matching (matching-paren delimiter)))
+                     (and matching (char-syntax matching)))
+                   (and (not endp)
+                        (eq ?\" (char-syntax delimiter))
+                        ?\) )))
+       (catch 'exit
+         (dolist (predicate paredit-space-for-delimiter-predicates)
+           (if (not (funcall predicate endp delimiter))
+               (throw 'exit nil)))
+         t)))
+
+(defun paredit-move-past-close-and-reindent (close)
+  (let ((open (paredit-missing-close)))
+    (if open
+        (if (eq close (matching-paren open))
+            (save-excursion
+              (message "Missing closing delimiter: %c" close)
+              (insert close))
+            (error "Mismatched missing closing delimiter: %c ... %c"
+                   open close))))
+  (up-list)
+  (if (catch 'return                    ; This CATCH returns T if it
+        (while t                        ; should delete leading spaces
+          (save-excursion               ; and NIL if not.
+            (let ((before-paren (1- (point))))
+              (back-to-indentation)
+              (cond ((not (eq (point) before-paren))
+                     ;; Can't call PAREDIT-DELETE-LEADING-WHITESPACE
+                     ;; here -- we must return from SAVE-EXCURSION
+                     ;; first.
+                     (throw 'return t))
+                    ((save-excursion (forward-line -1)
+                                     (end-of-line)
+                                     (paredit-in-comment-p))
+                     ;; Moving the closing delimiter any further
+                     ;; would put it into a comment, so we just
+                     ;; indent the closing delimiter where it is and
+                     ;; abort the loop, telling its continuation that
+                     ;; no leading whitespace should be deleted.
+                     (lisp-indent-line)
+                     (throw 'return nil))
+                    (t (delete-indentation)))))))
+      (paredit-delete-leading-whitespace)))
+
+(defun paredit-missing-close ()
+  (save-excursion
+    (paredit-handle-sexp-errors (backward-up-list)
+      (error "Not inside a list."))
+    (let ((open (char-after)))
+      (paredit-handle-sexp-errors (progn (forward-sexp) nil)
+        open))))
+
+(defun paredit-delete-leading-whitespace ()
+  ;; This assumes that we're on the closing delimiter already.
+  (save-excursion
+    (backward-char)
+    (while (let ((syn (char-syntax (char-before))))
+             (and (or (eq syn ?\ ) (eq syn ?-))     ; whitespace syntax
+                  ;; The above line is a perfect example of why the
+                  ;; following test is necessary.
+                  (not (paredit-in-char-p (1- (point))))))
+      (delete-char -1))))
+
+(defun paredit-blink-paren-match (another-line-p)
+  (if (and blink-matching-paren
+           (or (not show-paren-mode) another-line-p))
+      (paredit-ignore-sexp-errors
+        (save-excursion
+          (backward-sexp)
+          (forward-sexp)
+          ;; SHOW-PAREN-MODE inhibits any blinking, so we disable it
+          ;; locally here.
+          (let ((show-paren-mode nil))
+            (blink-matching-open))))))
+
+(defun paredit-doublequote (&optional n)
+  "Insert a pair of double-quotes.
+With a prefix argument N, wrap the following N S-expressions in
+  double-quotes, escaping intermediate characters if necessary.
+If the region is active, `transient-mark-mode' is enabled, and the
+  region's start and end fall in the same parenthesis depth, insert a
+  pair of double-quotes around the region, again escaping intermediate
+  characters if necessary.
+Inside a comment, insert a literal double-quote.
+At the end of a string, move past the closing double-quote.
+In the middle of a string, insert a backslash-escaped double-quote.
+If in a character literal, do nothing.  This prevents accidentally
+  changing a what was in the character literal to become a meaningful
+  delimiter unintentionally."
+  (interactive "P")
+  (cond ((paredit-in-string-p)
+         (if (eq (point) (- (paredit-enclosing-string-end) 1))
+             (forward-char)             ; Just move past the closing quote.
+           ;; Don't split a \x into an escaped backslash and a string end.
+           (if (paredit-in-string-escape-p) (forward-char))
+           (insert ?\\ ?\" )))
+        ((paredit-in-comment-p)
+         (insert ?\" ))
+        ((not (paredit-in-char-p))
+         (paredit-insert-pair n ?\" ?\" 'paredit-forward-for-quote))))
+
+(defun paredit-meta-doublequote (&optional n)
+  "Move to the end of the string.
+If not in a string, act as `paredit-doublequote'; if not prefix argument
+ is specified and the region is not active or `transient-mark-mode' is
+ disabled, the default is to wrap one S-expression, however, not zero."
+  (interactive "P")
+  (if (not (paredit-in-string-p))
+      (paredit-doublequote (or n (and (not (paredit-region-active-p)) 1)))
+      (goto-char (paredit-enclosing-string-end))))
+
+(defun paredit-meta-doublequote-and-newline (&optional n)
+  "Move to the end of the string, insert a newline, and indent.
+If not in a string, act as `paredit-doublequote'; if not prefix argument
+ is specified and the region is not active or `transient-mark-mode' is
+ disabled, the default is to wrap one S-expression, however, not zero."
+  (interactive "P")
+  (if (not (paredit-in-string-p))
+      (paredit-doublequote (or n (and (not (paredit-region-active-p)) 1)))
+      (progn (goto-char (paredit-enclosing-string-end))
+             (newline)
+             (lisp-indent-line)
+             (paredit-ignore-sexp-errors (indent-sexp)))))
+
+(defun paredit-forward-for-quote (end)
+  (let ((state (paredit-current-parse-state)))
+    (while (< (point) end)
+      (let ((new-state (parse-partial-sexp (point) (1+ (point))
+                                           nil nil state)))
+        (if (paredit-in-string-p new-state)
+            (if (not (paredit-in-string-escape-p))
+                (setq state new-state)
+              ;; Escape character: turn it into an escaped escape
+              ;; character by appending another backslash.
+              (insert ?\\ )
+              ;; Now the point is after both escapes, and we want to
+              ;; rescan from before the first one to after the second
+              ;; one.
+              (setq state
+                    (parse-partial-sexp (- (point) 2) (point)
+                                        nil nil state))
+              ;; Advance the end point, since we just inserted a new
+              ;; character.
+              (setq end (1+ end)))
+          ;; String: escape by inserting a backslash before the quote.
+          (backward-char)
+          (insert ?\\ )
+          ;; The point is now between the escape and the quote, and we
+          ;; want to rescan from before the escape to after the quote.
+          (setq state
+                (parse-partial-sexp (1- (point)) (1+ (point))
+                                    nil nil state))
+          ;; Advance the end point for the same reason as above.
+          (setq end (1+ end)))))))
+
+;;;; Escape Insertion
+
+(defun paredit-backslash ()
+  "Insert a backslash followed by a character to escape."
+  (interactive)
+  (cond ((paredit-in-string-p) (paredit-backslash-interactive))
+        ((paredit-in-comment-p) (insert ?\\))
+        ((paredit-in-char-p) (forward-char) (paredit-backslash-interactive))
+        (t (paredit-backslash-interactive))))
+
+(defun paredit-backslash-interactive ()
+  (insert ?\\ )
+  ;; Read a character to insert after the backslash.  If anything
+  ;; goes wrong -- the user hits delete (entering the rubout
+  ;; `character'), aborts with C-g, or enters non-character input
+  ;; -- then delete the backslash to avoid a dangling escape.
+  (let ((delete-p t))
+    (unwind-protect
+        (let ((char (read-char "Character to escape: " t)))
+          (if (not (eq char ?\^?))
+              (progn (message "Character to escape: %c" char)
+                     (insert char)
+                     (setq delete-p nil))))
+      (if delete-p
+          (progn (message "Deleting escape.")
+                 (delete-char -1))))))
+
+(defun paredit-newline ()
+  "Insert a newline and indent it.
+This is like `newline-and-indent', but it not only indents the line
+  that the point is on but also the S-expression following the point,
+  if there is one.
+Move forward one character first if on an escaped character.
+If in a string, just insert a literal newline.
+If in a comment and if followed by invalid structure, call
+  `indent-new-comment-line' to keep the invalid structure in a
+  comment."
+  (interactive)
+  (cond ((paredit-in-string-p)
+         (newline))
+        ((paredit-in-comment-p)
+         (if (paredit-region-ok-p (point) (point-at-eol))
+             (progn (newline-and-indent)
+                    (paredit-ignore-sexp-errors (indent-sexp)))
+             (indent-new-comment-line)))
+        (t
+         (if (paredit-in-char-p)
+             (forward-char))
+         (newline-and-indent)
+         ;; Indent the following S-expression, but don't signal an
+         ;; error if there's only a closing delimiter after the point.
+         (paredit-ignore-sexp-errors (indent-sexp)))))
+
+(defun paredit-reindent-defun (&optional argument)
+  "Reindent the definition that the point is on.
+If the point is in a string or a comment, fill the paragraph instead,
+  and with a prefix argument, justify as well."
+  (interactive "P")
+  (if (or (paredit-in-string-p)
+          (paredit-in-comment-p))
+      (lisp-fill-paragraph argument)
+    (paredit-preserving-column
+      (save-excursion
+        (end-of-defun)
+        (beginning-of-defun)
+        (indent-sexp)))))
+
+;;;; Comment Insertion
+
+(defun paredit-semicolon (&optional n)
+  "Insert a semicolon.
+With a prefix argument N, insert N semicolons.
+If in a string, do just that and nothing else.
+If in a character literal, move to the beginning of the character
+  literal before inserting the semicolon.
+If the enclosing list ends on the line after the point, break the line
+  after the last S-expression following the point.
+If a list begins on the line after the point but ends on a different
+  line, break the line after the last S-expression following the point
+  before the list."
+  (interactive "p")
+  (if (or (paredit-in-string-p) (paredit-in-comment-p))
+      (insert (make-string (or n 1) ?\; ))
+    (if (paredit-in-char-p)
+        (backward-char 2))
+    (let ((line-break-point (paredit-semicolon-find-line-break-point)))
+      (if line-break-point
+          (paredit-semicolon-with-line-break line-break-point (or n 1))
+          (insert (make-string (or n 1) ?\; ))))))
+
+(defun paredit-semicolon-find-line-break-point ()
+  (and (not (eolp))                   ;Implies (not (eobp)).
+       (let ((eol (point-at-eol)))
+         (save-excursion
+           (catch 'exit
+             (while t
+               (let ((line-break-point (point)))
+                 (cond ((paredit-handle-sexp-errors (progn (forward-sexp) t)
+                          nil)
+                        ;; Successfully advanced by an S-expression.
+                        ;; If that S-expression started on this line
+                        ;; and ended on another one, break here.
+                        (cond ((not (eq eol (point-at-eol)))
+                               (throw 'exit
+                                      (and (save-excursion
+                                             (backward-sexp)
+                                             (eq eol (point-at-eol)))
+                                           line-break-point)))
+                              ((eobp)
+                               (throw 'exit nil))))
+                       ((save-excursion
+                          (paredit-skip-whitespace t (point-at-eol))
+                          (or (eolp) (eobp) (eq (char-after) ?\;)))
+                        ;; Can't move further, but there's no closing
+                        ;; delimiter we're about to clobber -- either
+                        ;; it's on the next line or we're at the end of
+                        ;; the buffer.  Don't break the line.
+                        (throw 'exit nil))
+                       (t
+                        ;; Can't move because we hit a delimiter at the
+                        ;; end of this line.  Break here.
+                        (throw 'exit line-break-point))))))))))
+
+(defun paredit-semicolon-with-line-break (line-break-point n)
+  (let ((line-break-marker (make-marker)))
+    (set-marker line-break-marker line-break-point)
+    (set-marker-insertion-type line-break-marker t)
+    (insert (make-string (or n 1) ?\; ))
+    (save-excursion
+      (goto-char line-break-marker)
+      (set-marker line-break-marker nil)
+      (newline)
+      (lisp-indent-line)
+      ;; This step is redundant if we are inside a list, but even if we
+      ;; are at the top level, we want at least to indent whatever we
+      ;; bumped off the line.
+      (paredit-ignore-sexp-errors (indent-sexp))
+      (paredit-indent-sexps))))
+
+;;; This is all a horrible, horrible hack, primarily for GNU Emacs 21,
+;;; in which there is no `comment-or-uncomment-region'.
+
+(autoload 'comment-forward "newcomment")
+(autoload 'comment-normalize-vars "newcomment")
+(autoload 'comment-region "newcomment")
+(autoload 'comment-search-forward "newcomment")
+(autoload 'uncomment-region "newcomment")
+
+(defun paredit-initialize-comment-dwim ()
+  (require 'newcomment)
+  (if (not (fboundp 'comment-or-uncomment-region))
+      (defalias 'comment-or-uncomment-region
+        (lambda (beginning end &optional argument)
+          (interactive "*r\nP")
+          (if (save-excursion (goto-char beginning)
+                              (comment-forward (point-max))
+                              (<= end (point)))
+              (uncomment-region beginning end argument)
+              (comment-region beginning end argument)))))
+  (defalias 'paredit-initialize-comment-dwim 'comment-normalize-vars)
+  (comment-normalize-vars))
+
+(defun paredit-comment-dwim (&optional argument)
+  "Call the Lisp comment command you want (Do What I Mean).
+This is like `comment-dwim', but it is specialized for Lisp editing.
+If transient mark mode is enabled and the mark is active, comment or
+  uncomment the selected region, depending on whether it was entirely
+  commented not not already.
+If there is already a comment on the current line, with no prefix
+  argument, indent to that comment; with a prefix argument, kill that
+  comment.
+Otherwise, insert a comment appropriate for the context and ensure that
+  any code following the comment is moved to the next line.
+At the top level, where indentation is calculated to be at column 0,
+  insert a triple-semicolon comment; within code, where the indentation
+  is calculated to be non-zero, and on the line there is either no code
+  at all or code after the point, insert a double-semicolon comment;
+  and if the point is after all code on the line, insert a single-
+  semicolon margin comment at `comment-column'."
+  (interactive "*P")
+  (paredit-initialize-comment-dwim)
+  (cond ((paredit-region-active-p)
+         (comment-or-uncomment-region (region-beginning)
+                                      (region-end)
+                                      argument))
+        ((paredit-comment-on-line-p)
+         (if argument
+             (comment-kill (if (integerp argument) argument nil))
+             (comment-indent)))
+        (t (paredit-insert-comment))))
+
+(defun paredit-comment-on-line-p ()
+  "True if there is a comment on the line following point.
+This is expected to be called only in `paredit-comment-dwim'; do not
+  call it elsewhere."
+  (save-excursion
+    (beginning-of-line)
+    (let ((comment-p nil))
+      ;; Search forward for a comment beginning.  If there is one, set
+      ;; COMMENT-P to true; if not, it will be nil.
+      (while (progn
+               (setq comment-p          ;t -> no error
+                     (comment-search-forward (point-at-eol) t))
+               (and comment-p
+                    (or (paredit-in-string-p)
+                        (paredit-in-char-p (1- (point))))))
+        (forward-char))
+      comment-p)))
+
+(defun paredit-insert-comment ()
+  (let ((code-after-p
+         (save-excursion (paredit-skip-whitespace t (point-at-eol))
+                         (not (eolp))))
+        (code-before-p
+         (save-excursion (paredit-skip-whitespace nil (point-at-bol))
+                         (not (bolp)))))
+    (cond ((and (bolp)
+                (let ((indent
+                       (let ((indent (calculate-lisp-indent)))
+                         (if (consp indent) (car indent) indent))))
+                  (and indent (zerop indent))))
+           ;; Top-level comment
+           (if code-after-p (save-excursion (newline)))
+           (insert ";;; "))
+          ((or code-after-p (not code-before-p))
+           ;; Code comment
+           (if code-before-p
+               (newline-and-indent)
+               (lisp-indent-line))
+           (insert ";; ")
+           (if code-after-p
+               (save-excursion
+                 (newline)
+                 (lisp-indent-line)
+                 (paredit-indent-sexps))))
+          (t
+           ;; Margin comment
+           (indent-to comment-column 1) ; 1 -> force one leading space
+           (insert ?\; )))))
+
+;;;; Character Deletion
+
+(defun paredit-forward-delete (&optional argument)
+  "Delete a character forward or move forward over a delimiter.
+If on an opening S-expression delimiter, move forward into the
+  S-expression.
+If on a closing S-expression delimiter, refuse to delete unless the
+  S-expression is empty, in which case delete the whole S-expression.
+With a numeric prefix argument N, delete N characters forward.
+With a `C-u' prefix argument, simply delete a character forward,
+  without regard for delimiter balancing."
+  (interactive "P")
+  (cond ((or (consp argument) (eobp))
+         (delete-char +1))
+        ((integerp argument)
+         (if (< argument 0)
+             (paredit-backward-delete argument)
+             (while (> argument 0)
+               (paredit-forward-delete)
+               (setq argument (- argument 1)))))
+        ((paredit-in-string-p)
+         (paredit-forward-delete-in-string))
+        ((paredit-in-comment-p)
+         (paredit-forward-delete-in-comment))
+        ((paredit-in-char-p)            ; Escape -- delete both chars.
+         (delete-char -1)
+         (delete-char +1))
+        ((eq (char-after) ?\\ )         ; ditto
+         (delete-char +2))
+        ((let ((syn (char-syntax (char-after))))
+           (or (eq syn ?\( )
+               (eq syn ?\" )))
+         (if (save-excursion
+               (paredit-handle-sexp-errors (progn (forward-sexp) t)
+                 nil))
+             (forward-char)
+           (message "Deleting spurious opening delimiter.")
+           (delete-char +1)))
+        ((and (not (paredit-in-char-p (1- (point))))
+              (eq (char-syntax (char-after)) ?\) )
+              (eq (char-before) (matching-paren (char-after))))
+         (delete-char -1)               ; Empty list -- delete both
+         (delete-char +1))              ;   delimiters.
+        ((eq ?\; (char-after))
+         (paredit-forward-delete-comment-start))
+        ((eq (char-syntax (char-after)) ?\) )
+         (if (paredit-handle-sexp-errors
+                 (save-excursion (forward-char) (backward-sexp) t)
+               nil)
+             (message "End of list!")
+             (progn
+               (message "Deleting spurious closing delimiter.")
+               (delete-char +1))))
+        ;; Just delete a single character, if it's not a closing
+        ;; delimiter.  (The character literal case is already handled
+        ;; by now.)
+        (t (delete-char +1))))
+
+(defun paredit-forward-delete-in-string ()
+  (let ((start+end (paredit-string-start+end-points)))
+    (cond ((not (eq (point) (cdr start+end)))
+           ;; If it's not the close-quote, it's safe to delete.  But
+           ;; first handle the case that we're in a string escape.
+           (cond ((paredit-in-string-escape-p)
+                  ;; We're right after the backslash, so backward
+                  ;; delete it before deleting the escaped character.
+                  (delete-char -1))
+                 ((eq (char-after) ?\\ )
+                  ;; If we're not in a string escape, but we are on a
+                  ;; backslash, it must start the escape for the next
+                  ;; character, so delete the backslash before deleting
+                  ;; the next character.
+                  (delete-char +1)))
+           (delete-char +1))
+          ((eq (1- (point)) (car start+end))
+           ;; If it is the close-quote, delete only if we're also right
+           ;; past the open-quote (i.e. it's empty), and then delete
+           ;; both quotes.  Otherwise we refuse to delete it.
+           (delete-char -1)
+           (delete-char +1)))))
+
+(defun paredit-check-forward-delete-in-comment ()
+  ;; Point is in a comment, possibly at eol.  We are about to delete
+  ;; some characters forward; if we are at eol, we are about to delete
+  ;; the line break.  Refuse to do so if if moving the next line into
+  ;; the comment would break structure.
+  (if (eolp)
+      (let ((next-line-start (point-at-bol 2))
+            (next-line-end (point-at-eol 2)))
+        (paredit-check-region next-line-start next-line-end))))
+
+(defun paredit-forward-delete-in-comment ()
+  (paredit-check-forward-delete-in-comment)
+  (delete-char +1))
+
+(defun paredit-forward-delete-comment-start ()
+  ;; Point precedes a comment start (not at eol).  Refuse to delete a
+  ;; comment start if the comment contains unbalanced junk.
+  (paredit-check-region (+ (point) 1) (point-at-eol))
+  (delete-char +1))
+
+(defun paredit-backward-delete (&optional argument)
+  "Delete a character backward or move backward over a delimiter.
+If on a closing S-expression delimiter, move backward into the
+  S-expression.
+If on an opening S-expression delimiter, refuse to delete unless the
+  S-expression is empty, in which case delete the whole S-expression.
+With a numeric prefix argument N, delete N characters backward.
+With a `C-u' prefix argument, simply delete a character backward,
+  without regard for delimiter balancing."
+  (interactive "P")
+  (cond ((or (consp argument) (bobp))
+         ;++ Should this untabify?
+         (delete-char -1))
+        ((integerp argument)
+         (if (< argument 0)
+             (paredit-forward-delete (- 0 argument))
+             (while (> argument 0)
+               (paredit-backward-delete)
+               (setq argument (- argument 1)))))
+        ((paredit-in-string-p)
+         (paredit-backward-delete-in-string))
+        ((paredit-in-comment-p)
+         (paredit-backward-delete-in-comment))
+        ((paredit-in-char-p)            ; Escape -- delete both chars.
+         (delete-char -1)
+         (delete-char +1))
+        ((paredit-in-char-p (1- (point)))
+         (delete-char -2))              ; ditto
+        ((let ((syn (char-syntax (char-before))))
+           (or (eq syn ?\) )
+               (eq syn ?\" )))
+         (if (save-excursion
+               (paredit-handle-sexp-errors (progn (backward-sexp) t)
+                 nil))
+             (backward-char)
+           (message "Deleting spurious closing delimiter.")
+           (delete-char -1)))
+        ((and (eq (char-syntax (char-before)) ?\( )
+              (eq (char-after) (matching-paren (char-before))))
+         (delete-char -1)               ; Empty list -- delete both
+         (delete-char +1))              ;   delimiters.
+        ((bolp)
+         (paredit-backward-delete-maybe-comment-end))
+        ((eq (char-syntax (char-before)) ?\( )
+         (if (paredit-handle-sexp-errors
+                 (save-excursion (backward-char) (forward-sexp) t)
+               nil)
+             (message "Beginning of list!")
+             (progn
+               (message "Deleting spurious closing delimiter.")
+               (delete-char -1))))
+        ;; Delete it, unless it's an opening delimiter.  The case of
+        ;; character literals is already handled by now.
+        (t
+         ;; Turn off the @#&*&!^&(%^ botch in GNU Emacs 24 that changed
+         ;; `backward-delete-char' and `backward-delete-char-untabify'
+         ;; semantically so that they delete the region in transient
+         ;; mark mode.
+         (let ((delete-active-region nil))
+           (backward-delete-char-untabify +1)))))
+
+(defun paredit-backward-delete-in-string ()
+  (let ((start+end (paredit-string-start+end-points)))
+    (cond ((not (eq (1- (point)) (car start+end)))
+           ;; If it's not the open-quote, it's safe to delete.
+           (if (paredit-in-string-escape-p)
+               ;; If we're on a string escape, since we're about to
+               ;; delete the backslash, we must first delete the
+               ;; escaped char.
+               (delete-char +1))
+           (delete-char -1)
+           (if (paredit-in-string-escape-p)
+               ;; If, after deleting a character, we find ourselves in
+               ;; a string escape, we must have deleted the escaped
+               ;; character, and the backslash is behind the point, so
+               ;; backward delete it.
+               (delete-char -1)))
+          ((eq (point) (cdr start+end))
+           ;; If it is the open-quote, delete only if we're also right
+           ;; past the close-quote (i.e. it's empty), and then delete
+           ;; both quotes.  Otherwise we refuse to delete it.
+           (delete-char -1)
+           (delete-char +1)))))
+
+(defun paredit-backward-delete-in-comment ()
+  ;; Point is in a comment, possibly just after the comment start.
+  ;; Refuse to delete a comment start if the comment contains
+  ;; unbalanced junk.
+  (if (save-excursion
+        (backward-char)
+        ;; Must call `paredit-in-string-p' before
+        ;; `paredit-in-comment-p'.
+        (not (or (paredit-in-string-p) (paredit-in-comment-p))))
+      (paredit-check-region (point) (point-at-eol)))
+  (backward-delete-char-untabify +1))
+
+(defun paredit-backward-delete-maybe-comment-end ()
+  ;; Point is at bol, possibly just after a comment end (i.e., the
+  ;; previous line may have had a line comment).  Refuse to delete a
+  ;; comment end if moving the current line into the previous line's
+  ;; comment would break structure.
+  (if (save-excursion
+        (backward-char)
+        (and (not (paredit-in-string-p)) (paredit-in-comment-p)))
+      (paredit-check-region (point-at-eol) (point-at-bol)))
+  (delete-char -1))
+
+;;;; Killing
+
+(defun paredit-kill (&optional argument)
+  "Kill a line as if with `kill-line', but respecting delimiters.
+In a string, act exactly as `kill-line' but do not kill past the
+  closing string delimiter.
+On a line with no S-expressions on it starting after the point or
+  within a comment, act exactly as `kill-line'.
+Otherwise, kill all S-expressions that start after the point.
+With a `C-u' prefix argument, just do the standard `kill-line'.
+With a numeric prefix argument N, do `kill-line' that many times."
+  (interactive "P")
+  (cond (argument
+         (kill-line (if (integerp argument) argument 1)))
+        ((paredit-in-string-p)
+         (paredit-kill-line-in-string))
+        ((paredit-in-comment-p)
+         (paredit-kill-line-in-comment))
+        ((save-excursion (paredit-skip-whitespace t (point-at-eol))
+                         (or (eolp) (eq (char-after) ?\; )))
+         ;** Be careful about trailing backslashes.
+         (if (paredit-in-char-p)
+             (backward-char))
+         (kill-line))
+        (t (paredit-kill-sexps-on-line))))
+
+(defun paredit-kill-line-in-string ()
+  (if (save-excursion (paredit-skip-whitespace t (point-at-eol))
+                      (eolp))
+      (kill-line)
+    (save-excursion
+      ;; Be careful not to split an escape sequence.
+      (if (paredit-in-string-escape-p)
+          (backward-char))
+      (kill-region (point)
+                   (min (point-at-eol)
+                        (cdr (paredit-string-start+end-points)))))))
+
+(defun paredit-kill-line-in-comment ()
+  ;; The variable `kill-whole-line' is not relevant: the point is in a
+  ;; comment, and hence not at the beginning of the line.
+  (paredit-check-forward-delete-in-comment)
+  (kill-line))
+
+(defun paredit-kill-sexps-on-line ()
+  (if (paredit-in-char-p)               ; Move past the \ and prefix.
+      (backward-char 2))                ; (# in Scheme/CL, ? in elisp)
+  (let ((beginning (point))
+        (eol (point-at-eol)))
+    (let ((end-of-list-p (paredit-forward-sexps-to-kill beginning eol)))
+      ;; If we got to the end of the list and it's on the same line,
+      ;; move backward past the closing delimiter before killing.  (This
+      ;; allows something like killing the whitespace in (    ).)
+      (if end-of-list-p (progn (up-list) (backward-char)))
+      (if kill-whole-line
+          (paredit-kill-sexps-on-whole-line beginning)
+        (kill-region beginning
+                     ;; If all of the S-expressions were on one line,
+                     ;; i.e. we're still on that line after moving past
+                     ;; the last one, kill the whole line, including
+                     ;; any comments; otherwise just kill to the end of
+                     ;; the last S-expression we found.  Be sure,
+                     ;; though, not to kill any closing parentheses.
+                     (if (and (not end-of-list-p)
+                              (eq (point-at-eol) eol))
+                         eol
+                         (point)))))))
+
+;;; Please do not try to understand this code unless you have a VERY
+;;; good reason to do so.  I gave up trying to figure it out well
+;;; enough to explain it, long ago.
+
+(defun paredit-forward-sexps-to-kill (beginning eol)
+  (let ((end-of-list-p nil)
+        (firstp t))
+    ;; Move to the end of the last S-expression that started on this
+    ;; line, or to the closing delimiter if the last S-expression in
+    ;; this list is on the line.
+    (catch 'return
+      (while t
+        ;; This and the `kill-whole-line' business below fix a bug that
+        ;; inhibited any S-expression at the very end of the buffer
+        ;; (with no trailing newline) from being deleted.  It's a
+        ;; bizarre fix that I ought to document at some point, but I am
+        ;; too busy at the moment to do so.
+        (if (and kill-whole-line (eobp)) (throw 'return nil))
+        (save-excursion
+          (paredit-handle-sexp-errors (forward-sexp)
+            (up-list)
+            (setq end-of-list-p (eq (point-at-eol) eol))
+            (throw 'return nil))
+          (if (or (and (not firstp)
+                       (not kill-whole-line)
+                       (eobp))
+                  (paredit-handle-sexp-errors
+                      (progn (backward-sexp) nil)
+                    t)
+                  (not (eq (point-at-eol) eol)))
+              (throw 'return nil)))
+        (forward-sexp)
+        (if (and firstp
+                 (not kill-whole-line)
+                 (eobp))
+            (throw 'return nil))
+        (setq firstp nil)))
+    end-of-list-p))
+
+(defun paredit-kill-sexps-on-whole-line (beginning)
+  (kill-region beginning
+               (or (save-excursion     ; Delete trailing indentation...
+                     (paredit-skip-whitespace t)
+                     (and (not (eq (char-after) ?\; ))
+                          (point)))
+                   ;; ...or just use the point past the newline, if
+                   ;; we encounter a comment.
+                   (point-at-eol)))
+  (cond ((save-excursion (paredit-skip-whitespace nil (point-at-bol))
+                         (bolp))
+         ;; Nothing but indentation before the point, so indent it.
+         (lisp-indent-line))
+        ((eobp) nil)       ; Protect the CHAR-SYNTAX below against NIL.
+        ;; Insert a space to avoid invalid joining if necessary.
+        ((let ((syn-before (char-syntax (char-before)))
+               (syn-after  (char-syntax (char-after))))
+           (or (and (eq syn-before ?\) )            ; Separate opposing
+                    (eq syn-after  ?\( ))           ;   parentheses,
+               (and (eq syn-before ?\" )            ; string delimiter
+                    (eq syn-after  ?\" ))           ;   pairs,
+               (and (memq syn-before '(?_ ?w))      ; or word or symbol
+                    (memq syn-after  '(?_ ?w)))))   ;   constituents.
+         (insert " "))))
+
+;;;;; Killing Words
+
+;;; This is tricky and asymmetrical because backward parsing is
+;;; extraordinarily difficult or impossible, so we have to implement
+;;; killing in both directions by parsing forward.
+
+(defun paredit-forward-kill-word ()
+  "Kill a word forward, skipping over intervening delimiters."
+  (interactive)
+  (let ((beginning (point)))
+    (skip-syntax-forward " -")
+    (let* ((parse-state (paredit-current-parse-state))
+           (state (paredit-kill-word-state parse-state 'char-after)))
+      (while (not (or (eobp)
+                      (eq ?w (char-syntax (char-after)))))
+        (setq parse-state
+              (progn (forward-char 1) (paredit-current-parse-state))
+;;               (parse-partial-sexp (point) (1+ (point))
+;;                                   nil nil parse-state)
+              )
+        (let* ((old-state state)
+               (new-state
+                (paredit-kill-word-state parse-state 'char-after)))
+          (cond ((not (eq old-state new-state))
+                 (setq parse-state
+                       (paredit-kill-word-hack old-state
+                                               new-state
+                                               parse-state))
+                 (setq state
+                       (paredit-kill-word-state parse-state
+                                                'char-after))
+                 (setq beginning (point)))))))
+    (goto-char beginning)
+    (kill-word 1)))
+
+(defun paredit-backward-kill-word ()
+  "Kill a word backward, skipping over any intervening delimiters."
+  (interactive)
+  (if (not (or (bobp)
+               (eq (char-syntax (char-before)) ?w)))
+      (let ((end (point)))
+        (backward-word 1)
+        (forward-word 1)
+        (goto-char (min end (point)))
+        (let* ((parse-state (paredit-current-parse-state))
+               (state
+                (paredit-kill-word-state parse-state 'char-before)))
+          (while (and (< (point) end)
+                      (progn
+                        (setq parse-state
+                              (parse-partial-sexp (point) (1+ (point))
+                                                  nil nil parse-state))
+                        (or (eq state
+                                (paredit-kill-word-state parse-state
+                                                         'char-before))
+                            (progn (backward-char 1) nil)))))
+          (if (and (eq state 'comment)
+                   (eq ?\# (char-after (point)))
+                   (eq ?\| (char-before (point))))
+              (backward-char 1)))))
+  (backward-kill-word 1))
+
+;;;;;; Word-Killing Auxiliaries
+
+(defun paredit-kill-word-state (parse-state adjacent-char-fn)
+  (cond ((paredit-in-comment-p parse-state) 'comment)
+        ((paredit-in-string-p  parse-state) 'string)
+        ((memq (char-syntax (funcall adjacent-char-fn))
+               '(?\( ?\) ))
+         'delimiter)
+        (t 'other)))
+
+;;; This optionally advances the point past any comment delimiters that
+;;; should probably not be touched, based on the last state change and
+;;; the characters around the point.  It returns a new parse state,
+;;; starting from the PARSE-STATE parameter.
+
+(defun paredit-kill-word-hack (old-state new-state parse-state)
+  (cond ((and (not (eq old-state 'comment))
+              (not (eq new-state 'comment))
+              (not (paredit-in-string-escape-p))
+              (eq ?\# (char-before))
+              (eq ?\| (char-after)))
+         (forward-char 1)
+         (paredit-current-parse-state)
+;;          (parse-partial-sexp (point) (1+ (point))
+;;                              nil nil parse-state)
+         )
+        ((and (not (eq old-state 'comment))
+              (eq new-state 'comment)
+              (eq ?\; (char-before)))
+         (skip-chars-forward ";")
+         (paredit-current-parse-state)
+;;          (parse-partial-sexp (point) (save-excursion
+;;                                        (skip-chars-forward ";"))
+;;                              nil nil parse-state)
+         )
+        (t parse-state)))
+
+(defun paredit-copy-as-kill ()
+  "Save in the kill ring the region that `paredit-kill' would kill."
+  (interactive)
+  (cond ((paredit-in-string-p)
+         (paredit-copy-as-kill-in-string))
+        ((paredit-in-comment-p)
+         (copy-region-as-kill (point) (point-at-eol)))
+        ((save-excursion (paredit-skip-whitespace t (point-at-eol))
+                         (or (eolp) (eq (char-after) ?\; )))
+         ;** Be careful about trailing backslashes.
+         (save-excursion
+           (if (paredit-in-char-p)
+               (backward-char))
+           (copy-region-as-kill (point) (point-at-eol))))
+        (t (paredit-copy-sexps-as-kill))))
+
+(defun paredit-copy-as-kill-in-string ()
+  (save-excursion
+    (if (paredit-in-string-escape-p)
+        (backward-char))
+    (copy-region-as-kill (point)
+                         (min (point-at-eol)
+                              (cdr (paredit-string-start+end-points))))))
+
+(defun paredit-copy-sexps-as-kill ()
+  (save-excursion
+    (if (paredit-in-char-p)
+        (backward-char 2))
+    (let ((beginning (point))
+          (eol (point-at-eol)))
+      (let ((end-of-list-p (paredit-forward-sexps-to-kill beginning eol)))
+        (if end-of-list-p (progn (up-list) (backward-char)))
+        (copy-region-as-kill beginning
+                             (cond (kill-whole-line
+                                    (or (save-excursion
+                                          (paredit-skip-whitespace t)
+                                          (and (not (eq (char-after) ?\; ))
+                                               (point)))
+                                        (point-at-eol)))
+                                   ((and (not end-of-list-p)
+                                         (eq (point-at-eol) eol))
+                                    eol)
+                                   (t
+                                    (point))))))))
+
+;;;; Deleting Regions
+
+(defun paredit-delete-region (start end)
+  "Delete the text between point and mark, like `delete-region'.
+If that text is unbalanced, signal an error instead.
+With a prefix argument, skip the balance check."
+  (interactive "r")
+  (if (and start end (not current-prefix-arg))
+      (paredit-check-region-for-delete start end))
+  (setq this-command 'delete-region)
+  (delete-region start end))
+
+(defun paredit-kill-region (start end)
+  "Kill the text between point and mark, like `kill-region'.
+If that text is unbalanced, signal an error instead.
+With a prefix argument, skip the balance check."
+  (interactive "r")
+  (if (and start end (not current-prefix-arg))
+      (paredit-check-region-for-delete start end))
+  (setq this-command 'kill-region)
+  (kill-region start end))
+
+(defun paredit-check-region-for-delete (start end)
+  "Signal an error deleting text between START and END is unsafe."
+  (save-excursion
+    (goto-char start)
+    (let* ((start-state (paredit-current-parse-state))
+           (end-state (parse-partial-sexp start end nil nil start-state)))
+      (paredit-check-region-for-delete:depth start start-state end end-state)
+      (paredit-check-region-for-delete:string start start-state end end-state)
+      (paredit-check-region-for-delete:comment start start-state end end-state)
+      (paredit-check-region-for-delete:char-quote start start-state
+                                                  end end-state))))
+
+(defun paredit-check-region-for-delete:depth (start start-state end end-state)
+  (let ((start-depth (nth 0 start-state))
+        (end-depth (nth 0 end-state)))
+    (if (not (= start-depth end-depth))
+        (error "Mismatched parenthesis depth: %S at start, %S at end."
+               start-depth
+               end-depth))))
+
+(defun paredit-check-region-for-delete:string (start start-state end end-state)
+  (let ((start-string-p (nth 3 start-state))
+        (end-string-p (nth 3 end-state)))
+    (if (not (eq start-string-p end-string-p))
+        (error "Mismatched string state: start %sin string, end %sin string."
+               (if start-string-p "" "not ")
+               (if end-string-p "" "not ")))))
+
+(defun paredit-check-region-for-delete:comment
+    (start start-state end end-state)
+  (let ((start-comment-state (nth 4 start-state))
+        (end-comment-state (nth 4 end-state)))
+    (if (not (or (eq start-comment-state end-comment-state)
+                 ;; If we are moving text into or out of a line
+                 ;; comment, make sure that the text is balanced.  (The
+                 ;; comment state may be a number, not t or nil at all,
+                 ;; for nestable comments, which are not handled by
+                 ;; this heuristic (or any of paredit, really).)
+                 (and (or (and (eq start-comment-state nil)
+                               (eq end-comment-state t))
+                          (and (eq start-comment-state t)
+                               (eq end-comment-state nil)))
+                      (save-excursion
+                        (goto-char end)
+                        (paredit-region-ok-p (point) (point-at-eol))))))
+        (error "Mismatched comment state: %s"
+               (cond ((and (integerp start-comment-state)
+                           (integerp end-comment-state))
+                      (format "depth %S at start, depth %S at end."
+                              start-comment-state
+                              end-comment-state))
+                     ((integerp start-comment-state)
+                      "start in nested comment, end otherwise.")
+                     ((integerp end-comment-state)
+                      "end in nested comment, start otherwise.")
+                     (start-comment-state
+                      "start in comment, end not in comment.")
+                     (end-comment-state
+                      "end in comment, start not in comment.")
+                     (t
+                      (format "start %S, end %S."
+                              start-comment-state
+                              end-comment-state)))))))
+
+(defun paredit-check-region-for-delete:char-quote
+    (start start-state end end-state)
+  (let ((start-char-quote (nth 5 start-state))
+        (end-char-quote (nth 5 end-state)))
+    (if (not (eq start-char-quote end-char-quote))
+        (let ((phrase "character quotation"))
+          (error "Mismatched %s: start %sin %s, end %sin %s."
+                 phrase
+                 (if start-char-quote "" "not ")
+                 phrase
+                 (if end-char-quote "" "not ")
+                 phrase)))))
+
+;;;; Point Motion
+
+(eval-and-compile
+  (defmacro defun-motion (name bvl doc &rest body)
+    `(defun ,name ,bvl
+       ,doc
+       ,(xcond ((paredit-xemacs-p)
+                '(interactive "_"))
+               ((paredit-gnu-emacs-p)
+                ;++ Not sure this is sufficient for the `^'.
+                (if (fboundp 'handle-shift-selection)
+                    '(interactive "^p")
+                    '(interactive "p"))))
+       ,@body)))
+
+(defun-motion paredit-forward (&optional arg)
+  "Move forward an S-expression, or up an S-expression forward.
+If there are no more S-expressions in this one before the closing
+  delimiter, move past that closing delimiter; otherwise, move forward
+  past the S-expression following the point."
+  (let ((n (or arg 1)))
+    (cond ((< 0 n) (dotimes (i n)       (paredit-move-forward)))
+          ((< n 0) (dotimes (i (- n))   (paredit-move-backward))))))
+
+(defun-motion paredit-backward (&optional arg)
+  "Move backward an S-expression, or up an S-expression backward.
+If there are no more S-expressions in this one before the opening
+  delimiter, move past that opening delimiter backward; otherwise, move
+  move backward past the S-expression preceding the point."
+  (let ((n (or arg 1)))
+    (cond ((< 0 n) (dotimes (i n)       (paredit-move-backward)))
+          ((< n 0) (dotimes (i (- n))   (paredit-move-forward))))))
+
+(defun paredit-move-forward ()
+  (cond ((paredit-in-string-p)
+         (let ((end (paredit-enclosing-string-end)))
+           ;; `forward-sexp' and `up-list' may move into the next string
+           ;; in the buffer.  Don't do that; move out of the current one.
+           (if (paredit-handle-sexp-errors
+                   (progn (paredit-handle-sexp-errors (forward-sexp)
+                            (up-list))
+                          (<= end (point)))
+                 t)
+               (goto-char end))))
+        ((paredit-in-char-p)
+         (forward-char))
+        (t
+         (paredit-handle-sexp-errors (forward-sexp)
+           (up-list)))))
+
+(defun paredit-move-backward ()
+  (cond ((paredit-in-string-p)
+         (let ((start (paredit-enclosing-string-start)))
+           (if (paredit-handle-sexp-errors
+                   (progn (paredit-handle-sexp-errors (backward-sexp)
+                            (backward-up-list))
+                          (<= (point) start))
+                 t)
+               (goto-char start))))
+        ((paredit-in-char-p)
+         ;++ Corner case: a buffer of `\|x'.  What to do?
+         (backward-char 2))
+        (t
+         (paredit-handle-sexp-errors (backward-sexp)
+           (backward-up-list)))))
+
+;;;; Window Positioning
+
+(defalias 'paredit-recentre-on-sexp 'paredit-recenter-on-sexp)
+
+(defun paredit-recenter-on-sexp (&optional n)
+  "Recenter the screen on the S-expression following the point.
+With a prefix argument N, encompass all N S-expressions forward."
+  (interactive "P")
+  (let* ((p (point))
+         (end-point (progn (forward-sexp n) (point)))
+         (start-point (progn (goto-char end-point) (backward-sexp n) (point))))
+    ;; Point is at beginning of first S-expression.
+    (let ((p-visible nil) (start-visible nil))
+      (save-excursion
+        (forward-line (/ (count-lines start-point end-point) 2))
+        (recenter)
+        (setq p-visible (pos-visible-in-window-p p))
+        (setq start-visible (pos-visible-in-window-p start-point)))
+      (cond ((not start-visible)
+             ;; Implies (not p-visible).  Put the start at the top of
+             ;; the screen.
+             (recenter 0))
+            (p-visible
+             ;; Go back to p if we can.
+             (goto-char p))))))
+
+(defun paredit-recenter-on-defun ()
+  "Recenter the screen on the definition at point."
+  (interactive)
+  (save-excursion
+    (beginning-of-defun)
+    (paredit-recenter-on-sexp)))
+
+(defun paredit-focus-on-defun ()
+  "Moves display to the top of the definition at point."
+  (interactive)
+  (beginning-of-defun)
+  (recenter 0))
+
+;;;; Generalized Upward/Downward Motion
+
+(defun paredit-up/down (n vertical-direction)
+  (let ((horizontal-direction (if (< 0 n) +1 -1)))
+    (while (/= n 0)
+      (goto-char
+       (paredit-next-up/down-point horizontal-direction vertical-direction))
+      (setq n (- n horizontal-direction)))))
+
+(defun paredit-next-up/down-point (horizontal-direction vertical-direction)
+  (let ((state (paredit-current-parse-state))
+        (scan-lists
+         (lambda ()
+           (scan-lists (point) horizontal-direction vertical-direction))))
+    (cond ((paredit-in-string-p state)
+           (let ((start+end (paredit-string-start+end-points state)))
+             (if (< 0 vertical-direction)
+                 (if (< 0 horizontal-direction)
+                     (+ 1 (cdr start+end))
+                     (car start+end))
+                 ;; We could let the user try to descend into lists
+                 ;; within the string, but that would be asymmetric
+                 ;; with the up case, which rises out of the whole
+                 ;; string and not just out of a list within the
+                 ;; string, so this case will just be an error.
+                 (error "Can't descend further into string."))))
+          ((< 0 vertical-direction)
+           ;; When moving up, just try to rise up out of the list.
+           (or (funcall scan-lists)
+               (buffer-end horizontal-direction)))
+          ((< vertical-direction 0)
+           ;; When moving down, look for a string closer than a list,
+           ;; and use that if we find it.
+           (let* ((list-start
+                   (paredit-handle-sexp-errors (funcall scan-lists) nil))
+                  (string-start
+                   (paredit-find-next-string-start horizontal-direction
+                                                   list-start)))
+             (if (and string-start list-start)
+                 (if (< 0 horizontal-direction)
+                     (min string-start list-start)
+                     (max string-start list-start))
+                 (or string-start
+                     ;; Scan again: this is a kludgey way to report the
+                     ;; error if there really was one.
+                     (funcall scan-lists)
+                     (buffer-end horizontal-direction)))))
+          (t
+           (error "Vertical direction must be nonzero in `%s'."
+                  'paredit-up/down)))))
+
+(defun paredit-find-next-string-start (horizontal-direction limit)
+  (let ((buffer-limit-p (if (< 0 horizontal-direction) 'eobp 'bobp))
+        (next-char (if (< 0 horizontal-direction) 'char-after 'char-before))
+        (pastp (if (< 0 horizontal-direction) '> '<)))
+    (paredit-handle-sexp-errors
+        (save-excursion
+          (catch 'exit
+            (while t
+              (if (or (funcall buffer-limit-p)
+                      (and limit (funcall pastp (point) limit)))
+                  (throw 'exit nil))
+              (forward-sexp horizontal-direction)
+              (save-excursion
+                (backward-sexp horizontal-direction)
+                (if (eq ?\" (char-syntax (funcall next-char)))
+                    (throw 'exit (+ (point) horizontal-direction)))))))
+      nil)))
+
+(defun-motion paredit-forward-down (&optional argument)
+  "Move forward down into a list.
+With a positive argument, move forward down that many levels.
+With a negative argument, move backward down that many levels."
+  (paredit-up/down (or argument +1) -1))
+
+(defun-motion paredit-backward-up (&optional argument)
+  "Move backward up out of the enclosing list.
+With a positive argument, move backward up that many levels.
+With a negative argument, move forward up that many levels.
+If in a string initially, that counts as one level."
+  (paredit-up/down (- 0 (or argument +1)) +1))
+
+(defun-motion paredit-forward-up (&optional argument)
+  "Move forward up out of the enclosing list.
+With a positive argument, move forward up that many levels.
+With a negative argument, move backward up that many levels.
+If in a string initially, that counts as one level."
+  (paredit-up/down (or argument +1) +1))
+
+(defun-motion paredit-backward-down (&optional argument)
+  "Move backward down into a list.
+With a positive argument, move backward down that many levels.
+With a negative argument, move forward down that many levels."
+  (paredit-up/down (- 0 (or argument +1)) -1))
+
+;;;; Depth-Changing Commands:  Wrapping, Splicing, & Raising
+
+(defun paredit-wrap-sexp (&optional argument open close)
+  "Wrap the following S-expression.
+If a `C-u' prefix argument is given, wrap all S-expressions following
+  the point until the end of the buffer or of the enclosing list.
+If a numeric prefix argument N is given, wrap N S-expressions.
+Automatically indent the newly wrapped S-expression.
+As a special case, if the point is at the end of a list, simply insert
+  a parenthesis pair, rather than inserting a lone opening delimiter
+  and then signalling an error, in the interest of preserving
+  structure.
+By default OPEN and CLOSE are round delimiters."
+  (interactive "P")
+  (paredit-lose-if-not-in-sexp 'paredit-wrap-sexp)
+  (let ((open (or open ?\( ))
+        (close (or close ?\) )))
+    (paredit-handle-sexp-errors
+        ((lambda (n) (paredit-insert-pair n open close 'goto-char))
+         (cond ((integerp argument) argument)
+               ((consp argument) (paredit-count-sexps-forward))
+               ((paredit-region-active-p) nil)
+               (t 1)))
+      (insert close)
+      (backward-char)))
+  (save-excursion (backward-up-list) (indent-sexp)))
+
+(defun paredit-yank-pop (&optional argument)
+  "Replace just-yanked text with the next item in the kill ring.
+If this command follows a `yank', just run `yank-pop'.
+If this command follows a `paredit-wrap-sexp', or any other paredit
+  wrapping command (see `paredit-wrap-commands'), run `yank' and
+  reindent the enclosing S-expression.
+If this command is repeated, run `yank-pop' and reindent the enclosing
+  S-expression.
+
+The argument is passed on to `yank' or `yank-pop'; see their
+  documentation for details."
+  (interactive "*p")
+  (cond ((eq last-command 'yank)
+         (yank-pop argument))
+        ((memq last-command paredit-wrap-commands)
+         (yank argument)
+         ;; `yank' futzes with `this-command'.
+         (setq this-command 'paredit-yank-pop)
+         (save-excursion (backward-up-list) (indent-sexp)))
+        ((eq last-command 'paredit-yank-pop)
+         ;; Pretend we just did a `yank', so that we can use
+         ;; `yank-pop' without duplicating its definition.
+         (setq last-command 'yank)
+         (yank-pop argument)
+         ;; Return to our original state.
+         (setq last-command 'paredit-yank-pop)
+         (setq this-command 'paredit-yank-pop)
+         (save-excursion (backward-up-list) (indent-sexp)))
+        (t (error "Last command was not a yank or a wrap: %s" last-command))))
+
+(defun paredit-splice-sexp (&optional argument)
+  "Splice the list that the point is on by removing its delimiters.
+With a prefix argument as in `C-u', kill all S-expressions backward in
+  the current list before splicing all S-expressions forward into the
+  enclosing list.
+With two prefix arguments as in `C-u C-u', kill all S-expressions
+  forward in the current list before splicing all S-expressions
+  backward into the enclosing list.
+With a numerical prefix argument N, kill N S-expressions backward in
+  the current list before splicing the remaining S-expressions into the
+  enclosing list.  If N is negative, kill forward.
+Inside a string, unescape all backslashes, or signal an error if doing
+  so would invalidate the buffer's structure."
+  (interactive "P")
+  (if (paredit-in-string-p)
+      (paredit-splice-string argument)
+    (if (paredit-in-comment-p)
+        (error "Can't splice comment."))
+    (paredit-handle-sexp-errors (paredit-enclosing-list-start)
+      (error "Can't splice top level."))
+    (paredit-kill-surrounding-sexps-for-splice argument)
+    (let ((delete-start (paredit-enclosing-list-start))
+          (delete-end
+           (let ((limit
+                  (save-excursion
+                    (paredit-ignore-sexp-errors (forward-sexp) (backward-sexp))
+                    (point))))
+             (save-excursion
+               (backward-up-list)
+               (forward-char +1)
+               (paredit-skip-whitespace t limit)
+               (point)))))
+      (let ((end-marker (make-marker)))
+        (save-excursion
+          (up-list)
+          (delete-char -1)
+          (set-marker end-marker (point)))
+        (delete-region delete-start delete-end)
+        (paredit-splice-reindent delete-start (marker-position end-marker))))))
+
+(defun paredit-splice-reindent (start end)
+  (paredit-preserving-column
+    ;; If we changed the first subform of the enclosing list, we must
+    ;; reindent the whole enclosing list.
+    (if (paredit-handle-sexp-errors
+            (save-excursion
+              (backward-up-list)
+              (down-list)
+              (paredit-ignore-sexp-errors (forward-sexp))
+              (< start (point)))
+          nil)
+        (save-excursion (backward-up-list) (indent-sexp))
+        (paredit-indent-region start end))))
+
+(defun paredit-kill-surrounding-sexps-for-splice (argument)
+  (cond ((or (paredit-in-string-p)
+             (paredit-in-comment-p))
+         (error "Invalid context for splicing S-expressions."))
+        ((or (not argument) (eq argument 0)) nil)
+        ((or (numberp argument) (eq argument '-))
+         ;; Kill S-expressions before/after the point by saving the
+         ;; point, moving across them, and killing the region.
+         (let* ((argument (if (eq argument '-) -1 argument))
+                (saved (paredit-point-at-sexp-boundary (- argument))))
+           (goto-char saved)
+           (paredit-ignore-sexp-errors (backward-sexp argument))
+           (paredit-hack-kill-region saved (point))))
+        ((consp argument)
+         (let ((v (car argument)))
+           (if (= v 4)                  ;One `C-u'.
+               ;; Move backward until we hit the open paren; then
+               ;; kill that selected region.
+               (let ((end (point)))
+                 (paredit-ignore-sexp-errors
+                   (while (not (bobp))
+                     (backward-sexp)))
+                 (paredit-hack-kill-region (point) end))
+               ;; Move forward until we hit the close paren; then
+               ;; kill that selected region.
+               (let ((beginning (point)))
+                 (paredit-ignore-sexp-errors
+                   (while (not (eobp))
+                     (forward-sexp)))
+                 (paredit-hack-kill-region beginning (point))))))
+        (t (error "Bizarre prefix argument `%s'." argument))))
+
+(defun paredit-splice-sexp-killing-backward (&optional n)
+  "Splice the list the point is on by removing its delimiters, and
+  also kill all S-expressions before the point in the current list.
+With a prefix argument N, kill only the preceding N S-expressions."
+  (interactive "P")
+  (paredit-splice-sexp (if n
+                           (prefix-numeric-value n)
+                           '(4))))
+
+(defun paredit-splice-sexp-killing-forward (&optional n)
+  "Splice the list the point is on by removing its delimiters, and
+  also kill all S-expressions after the point in the current list.
+With a prefix argument N, kill only the following N S-expressions."
+  (interactive "P")
+  (paredit-splice-sexp (if n
+                           (- (prefix-numeric-value n))
+                           '(16))))
+
+(defun paredit-raise-sexp (&optional argument)
+  "Raise the following S-expression in a tree, deleting its siblings.
+With a prefix argument N, raise the following N S-expressions.  If N
+  is negative, raise the preceding N S-expressions.
+If the point is on an S-expression, such as a string or a symbol, not
+  between them, that S-expression is considered to follow the point."
+  (interactive "P")
+  (save-excursion
+    (cond ((paredit-in-string-p)
+           (goto-char (car (paredit-string-start+end-points))))
+          ((paredit-in-char-p)
+           (backward-sexp))
+          ((paredit-in-comment-p)
+           (error "No S-expression to raise in comment.")))
+    ;; Select the S-expressions we want to raise in a buffer substring.
+    (let* ((n (prefix-numeric-value argument))
+           (bound (scan-sexps (point) n))
+           (sexps
+            (if (< n 0)
+                (buffer-substring bound (paredit-point-at-sexp-end))
+                (buffer-substring (paredit-point-at-sexp-start) bound))))
+      ;; Move up to the list we're raising those S-expressions out of and
+      ;; delete it.
+      (backward-up-list)
+      (delete-region (point) (scan-sexps (point) 1))
+      (let* ((indent-start (point))
+             (indent-end (save-excursion (insert sexps) (point))))
+        ;; If the expression spans multiple lines, its indentation is
+        ;; probably broken, so reindent it -- but don't reindent
+        ;; anything that we didn't touch outside the expression.
+        ;;
+        ;; XXX What if the *column* of the starting point was preserved
+        ;; too?  Should we avoid reindenting in that case?
+        (if (not (eq (save-excursion (goto-char indent-start) (point-at-eol))
+                     (save-excursion (goto-char indent-end) (point-at-eol))))
+            (indent-region indent-start indent-end nil))))))
+
+;;; The effects of convolution on the surrounding whitespace are pretty
+;;; random.  If you have better suggestions, please let me know.
+
+(defun paredit-convolute-sexp (&optional n)
+  "Convolute S-expressions.
+Save the S-expressions preceding point and delete them.
+Splice the S-expressions following point.
+Wrap the enclosing list in a new list prefixed by the saved text.
+With a prefix argument N, move up N lists before wrapping."
+  (interactive "p")
+  (paredit-lose-if-not-in-sexp 'paredit-convolute-sexp)
+  ;; Make sure we can move up before destroying anything.
+  (save-excursion (backward-up-list n) (backward-up-list))
+  (let (open close)                     ;++ Is this a good idea?
+    (let ((prefix
+           (let ((end (point)))
+             (paredit-ignore-sexp-errors
+               (while (not (bobp)) (backward-sexp)))
+             (prog1 (buffer-substring (point) end)
+               (backward-up-list)
+               (save-excursion (forward-sexp)
+                               (setq close (char-before))
+                               (delete-char -1))
+               (setq open (char-after))
+               (delete-region (point) end)
+               ;; I'm not sure this makes sense...
+               (if (not (eolp)) (just-one-space))))))
+      (backward-up-list n)
+      (paredit-insert-pair 1 open close 'goto-char)
+      (insert prefix)
+      ;; I'm not sure this makes sense either...
+      (if (not (eolp)) (just-one-space))
+      (save-excursion
+        (backward-up-list)
+        (paredit-ignore-sexp-errors (indent-sexp))))))
+
+(defun paredit-splice-string (argument)
+  (let ((original-point (point))
+        (start+end (paredit-string-start+end-points)))
+    (let ((start (car start+end))
+          (end (cdr start+end)))
+      ;; START and END both lie before the respective quote
+      ;; characters, which we want to delete; thus we increment START
+      ;; by one to extract the string, and we increment END by one to
+      ;; delete the string.
+      (let* ((escaped-string
+              (cond ((not (consp argument))
+                     (buffer-substring (1+ start) end))
+                    ((= 4 (car argument))
+                     (buffer-substring original-point end))
+                    (t
+                     (buffer-substring (1+ start) original-point))))
+             (unescaped-string
+              (paredit-unescape-string escaped-string)))
+        (if (not unescaped-string)
+            (error "Unspliceable string.")
+          (save-excursion
+            (goto-char start)
+            (delete-region start (1+ end))
+            (insert unescaped-string))
+          (if (not (and (consp argument)
+                        (= 4 (car argument))))
+              (goto-char (- original-point 1))))))))
+
+(defun paredit-unescape-string (string)
+  (with-temp-buffer
+    (insert string)
+    (goto-char (point-min))
+    (while (and (not (eobp))
+                ;; nil -> no bound; t -> no errors.
+                (search-forward "\\" nil t))
+      (delete-char -1)
+      (forward-char))
+    (paredit-handle-sexp-errors
+        (progn (scan-sexps (point-min) (point-max))
+               (buffer-string))
+      nil)))
+
+;;;; Slurpage & Barfage
+
+(defun paredit-forward-slurp-sexp (&optional argument)
+  "Add the S-expression following the current list into that list
+  by moving the closing delimiter.
+Automatically reindent the newly slurped S-expression with respect to
+  its new enclosing form.
+If in a string, move the opening double-quote forward by one
+  S-expression and escape any intervening characters as necessary,
+  without altering any indentation or formatting."
+  (interactive "P")
+  (save-excursion
+    (cond ((paredit-in-comment-p)
+           (error "Invalid context for slurping S-expressions."))
+          ((numberp argument)
+           (if (< argument 0)
+               (paredit-forward-barf-sexp (- 0 argument))
+               (while (< 0 argument)
+                 (paredit-forward-slurp-sexp)
+                 (setq argument (- argument 1)))))
+          ((paredit-in-string-p)
+           ;; If there is anything to slurp into the string, take that.
+           ;; Otherwise, try to slurp into the enclosing list.
+           (if (save-excursion
+                 (goto-char (paredit-enclosing-string-end))
+                 (paredit-handle-sexp-errors (progn (forward-sexp) nil)
+                   t))
+               (progn
+                 (goto-char (paredit-enclosing-string-end))
+                 (paredit-forward-slurp-into-list argument))
+               (paredit-forward-slurp-into-string argument)))
+          (t
+           (paredit-forward-slurp-into-list argument)))))
+
+(defun paredit-forward-slurp-into-list (&optional argument)
+  (let ((nestedp nil))
+    (save-excursion
+      (up-list)                            ; Up to the end of the list to
+      (let ((close (char-before)))         ;   save and delete the closing
+        (delete-char -1)                   ;   delimiter.
+        (let ((start (point)))
+          (catch 'return                   ; Go to the end of the desired
+            (while t                       ;   S-expression, going up a
+              (paredit-handle-sexp-errors  ;   list if it's not in this,
+                  (progn (forward-sexp)
+                         (if argument
+                             (paredit-ignore-sexp-errors
+                               (while (not (eobp))
+                                 (forward-sexp))))
+                         (throw 'return nil))
+                (setq nestedp t)
+                (up-list)
+                (setq close                ; adjusting for mixed
+                      (prog1 (char-before) ;   delimiters as necessary,
+                        (delete-char -1)
+                        (insert close))))))
+          (insert close)                   ;  to insert that delimiter.
+          (indent-region start (point) nil))))
+    (if (and (not nestedp)
+             (eq (save-excursion (paredit-skip-whitespace nil) (point))
+                 (save-excursion (backward-up-list) (forward-char) (point)))
+             (eq (save-excursion (forward-sexp) (backward-sexp) (point))
+                 (save-excursion (paredit-skip-whitespace t) (point))))
+        (delete-region (save-excursion (paredit-skip-whitespace nil) (point))
+                       (save-excursion (paredit-skip-whitespace t) (point))))))
+
+(defun paredit-forward-slurp-into-string (&optional argument)
+  (let ((start (paredit-enclosing-string-start))
+        (end (paredit-enclosing-string-end)))
+    (goto-char end)
+    ;; Signal any errors that we might get first, before mucking with
+    ;; the buffer's contents.
+    (save-excursion (forward-sexp))
+    (let ((close (char-before)))
+      ;; Skip intervening whitespace if we're slurping into an empty
+      ;; string.  XXX What about nonempty strings?
+      (if (and (= (+ start 2) end)
+               (eq (save-excursion (paredit-skip-whitespace t) (point))
+                   (save-excursion (forward-sexp) (backward-sexp) (point))))
+          (delete-region (- (point) 1)
+                         (save-excursion (paredit-skip-whitespace t) (point)))
+          (delete-char -1))
+      (paredit-forward-for-quote
+       (save-excursion
+         (forward-sexp)
+         (if argument
+             (while (paredit-handle-sexp-errors (progn (forward-sexp) t) nil)))
+         (point)))
+      (insert close))))
+
+(defun paredit-forward-barf-sexp (&optional argument)
+  "Remove the last S-expression in the current list from that list
+  by moving the closing delimiter.
+Automatically reindent the newly barfed S-expression with respect to
+  its new enclosing form."
+  (interactive "P")
+  (paredit-lose-if-not-in-sexp 'paredit-forward-barf-sexp)
+  (if (and (numberp argument) (< argument 0))
+      (paredit-forward-slurp-sexp (- 0 argument))
+    (let ((start (point)) (end nil))
+      (save-excursion
+        (up-list)                       ; Up to the end of the list to
+        (let ((close (char-before)))    ;   save and delete the closing
+          (delete-char -1)              ;   delimiter.
+          (setq end (point))
+          (paredit-ignore-sexp-errors   ; Go back to where we want to
+            (if (or (not argument)      ;   insert the delimiter.
+                    (numberp argument))
+                (backward-sexp argument)
+                (while (paredit-handle-sexp-errors
+                           (save-excursion (backward-sexp) (<= start (point)))
+                         nil)
+                  (backward-sexp))))
+          (paredit-skip-whitespace nil) ; Skip leading whitespace.
+          (cond ((bobp)
+                 ;++ We'll have deleted the close, but there's no open.
+                 ;++ Is that OK?
+                 (error "Barfing all subexpressions with no open-paren?"))
+                ((paredit-in-comment-p) ; Don't put the close-paren in
+                 (newline)))            ;   a comment.
+          (insert close))
+        ;; Reindent all of the newly barfed S-expressions.  Start at the
+        ;; start of the first barfed S-expression, not at the close we
+        ;; just inserted.
+        (forward-sexp)
+        (backward-sexp)
+        (if (or (not argument) (numberp argument))
+            (paredit-forward-and-indent argument)
+            (indent-region (point) end))))))
+
+(defun paredit-backward-slurp-sexp (&optional argument)
+  "Add the S-expression preceding the current list into that list
+  by moving the closing delimiter.
+Automatically reindent the whole form into which new S-expression was
+  slurped.
+If in a string, move the opening double-quote backward by one
+  S-expression and escape any intervening characters as necessary,
+  without altering any indentation or formatting."
+  (interactive "P")
+  (save-excursion
+    (cond ((paredit-in-comment-p)
+           (error "Invalid context for slurping S-expressions."))
+          ((numberp argument)
+           (if (< argument 0)
+               (paredit-backward-barf-sexp (- 0 argument))
+               (while (< 0 argument)
+                 (paredit-backward-slurp-sexp)
+                 (setq argument (- argument 1)))))
+          ((paredit-in-string-p)
+           ;; If there is anything to slurp into the string, take that.
+           ;; Otherwise, try to slurp into the enclosing list.
+           (if (save-excursion
+                 (goto-char (paredit-enclosing-string-start))
+                 (paredit-handle-sexp-errors (progn (backward-sexp) nil)
+                   t))
+               (progn
+                 (goto-char (paredit-enclosing-string-start))
+                 (paredit-backward-slurp-into-list argument))
+               (paredit-backward-slurp-into-string argument)))
+          (t
+           (paredit-backward-slurp-into-list argument)))))
+
+(defun paredit-backward-slurp-into-list (&optional argument)
+  (let ((nestedp nil))
+    (save-excursion
+      (backward-up-list)
+      (let ((open (char-after)))
+        (delete-char +1)
+        (catch 'return
+          (while t
+            (paredit-handle-sexp-errors
+                (progn (backward-sexp)
+                       (if argument
+                           (paredit-ignore-sexp-errors
+                             (while (not (bobp))
+                               (backward-sexp))))
+                       (throw 'return nil))
+              (setq nestedp t)
+              (backward-up-list)
+              (setq open
+                    (prog1 (char-after)
+                      (save-excursion (insert open) (delete-char +1)))))))
+        (insert open))
+      ;; Reindent the line at the beginning of wherever we inserted the
+      ;; opening delimiter, and then indent the whole S-expression.
+      (backward-up-list)
+      (lisp-indent-line)
+      (indent-sexp))
+    ;; If we slurped into an empty list, don't leave dangling space:
+    ;; (foo |).
+    (if (and (not nestedp)
+             (eq (save-excursion (paredit-skip-whitespace nil) (point))
+                 (save-excursion (backward-sexp) (forward-sexp) (point)))
+             (eq (save-excursion (up-list) (backward-char) (point))
+                 (save-excursion (paredit-skip-whitespace t) (point))))
+        (delete-region (save-excursion (paredit-skip-whitespace nil) (point))
+                       (save-excursion (paredit-skip-whitespace t) (point))))))
+
+(defun paredit-backward-slurp-into-string (&optional argument)
+  (let ((start (paredit-enclosing-string-start))
+        (end (paredit-enclosing-string-end)))
+    (goto-char start)
+    ;; Signal any errors that we might get first, before mucking with
+    ;; the buffer's contents.
+    (save-excursion (backward-sexp))
+    (let ((open (char-after))
+          (target (point)))
+      ;; Skip intervening whitespace if we're slurping into an empty
+      ;; string.  XXX What about nonempty strings?
+      (if (and (= (+ start 2) end)
+               (eq (save-excursion (paredit-skip-whitespace nil) (point))
+                   (save-excursion (backward-sexp) (forward-sexp) (point))))
+          (delete-region (save-excursion (paredit-skip-whitespace nil) (point))
+                         (+ (point) 1))
+          (delete-char +1))
+      (backward-sexp)
+      (if argument
+          (paredit-ignore-sexp-errors
+            (while (not (bobp))
+              (backward-sexp))))
+      (insert open)
+      (paredit-forward-for-quote target))))
+
+(defun paredit-backward-barf-sexp (&optional argument)
+  "Remove the first S-expression in the current list from that list
+  by moving the closing delimiter.
+Automatically reindent the barfed S-expression and the form from which
+  it was barfed."
+  (interactive "P")
+  (paredit-lose-if-not-in-sexp 'paredit-backward-barf-sexp)
+  (if (and (numberp argument) (< argument 0))
+      (paredit-backward-slurp-sexp (- 0 argument))
+    (let ((end (make-marker)))
+      (set-marker end (point))
+      (save-excursion
+        (backward-up-list)
+        (let ((open (char-after)))
+          (delete-char +1)
+          (paredit-ignore-sexp-errors
+            (paredit-forward-and-indent
+             (if (or (not argument) (numberp argument))
+                 argument
+                 (let ((n 0))
+                   (save-excursion
+                     (while (paredit-handle-sexp-errors
+                                (save-excursion
+                                  (forward-sexp)
+                                  (<= (point) end))
+                              nil)
+                       (forward-sexp)
+                       (setq n (+ n 1))))
+                   n))))
+          (while (progn (paredit-skip-whitespace t) (eq (char-after) ?\; ))
+            (forward-line 1))
+          (if (eobp)
+              ;++ We'll have deleted the close, but there's no open.
+              ;++ Is that OK?
+              (error "Barfing all subexpressions with no close-paren?"))
+          ;** Don't use `insert' here.  Consider, e.g., barfing from
+          ;**   (foo|)
+          ;** and how `save-excursion' works.
+          (insert-before-markers open))
+        (backward-up-list)
+        (lisp-indent-line)
+        (indent-sexp)))))
+
+;;;; Splitting & Joining
+
+(defun paredit-split-sexp ()
+  "Split the list or string the point is on into two."
+  (interactive)
+  (cond ((paredit-in-string-p)
+         (insert "\"")
+         (save-excursion (insert " \"")))
+        ((or (paredit-in-comment-p)
+             (paredit-in-char-p))
+         (error "Invalid context for splitting S-expression."))
+        (t
+         (let ((open (save-excursion (backward-up-list) (char-after)))
+               (close (save-excursion (up-list) (char-before))))
+           (delete-horizontal-space)
+           (insert close)
+           (save-excursion
+             (insert ?\ )
+             (insert open)
+             (backward-char)
+             (indent-sexp))))))
+
+(defun paredit-join-sexps ()
+  "Join the S-expressions adjacent on either side of the point.
+Both must be lists, strings, or atoms; error if there is a mismatch."
+  (interactive)
+  (cond ((paredit-in-comment-p) (error "Can't join S-expressions in comment."))
+        ((paredit-in-string-p) (error "Nothing to join in a string."))
+        ((paredit-in-char-p) (error "Can't join characters.")))
+  (let ((left-point (paredit-point-at-sexp-end))
+        (right-point (paredit-point-at-sexp-start)))
+    (let ((left-char (char-before left-point))
+          (right-char (char-after right-point)))
+      (let ((left-syntax (char-syntax left-char))
+            (right-syntax (char-syntax right-char)))
+        (cond ((< right-point left-point)
+               (error "Can't join a datum with itself."))
+              ((and (eq left-syntax ?\) )
+                    (eq right-syntax ?\( )
+                    (eq left-char (matching-paren right-char))
+                    (eq right-char (matching-paren left-char)))
+               (paredit-join-lists-internal left-point right-point)
+               (paredit-preserving-column
+                 (save-excursion
+                   (backward-up-list)
+                   (indent-sexp))))
+              ((and (eq left-syntax ?\" )
+                    (eq right-syntax ?\" ))
+               ;; Delete any intermediate formatting.
+               (delete-region (1- left-point) (1+ right-point)))
+              ((and (memq left-syntax '(?w ?_)) ; Word or symbol
+                    (memq right-syntax '(?w ?_)))
+               (delete-region left-point right-point))
+              (t (error "Mismatched S-expressions to join.")))))))
+
+(defun paredit-join-lists-internal (left-point right-point)
+  (save-excursion
+    ;; Leave intermediate formatting alone.
+    (goto-char right-point)
+    (delete-char +1)
+    (goto-char left-point)
+    (delete-char -1)
+    ;; Kludge: Add an extra space in several conditions.
+    (if (or
+         ;; (foo)| ;x\n(bar) => (foo | ;x\nbar), not (foo|  ;x\nbar).
+         (and (not (eolp))
+              (save-excursion
+                (paredit-skip-whitespace t (point-at-eol))
+                (eq (char-after) ?\;)))
+         ;; (foo)|(bar) => (foo| bar), not (foo|bar).
+         (and (= left-point right-point)
+              (not (or (eq ?\  (char-syntax (char-before)))
+                       (eq ?\  (char-syntax (char-after)))))))
+        (insert ?\  ))))
+
+;++ How ought paredit-join to handle comments intervening symbols or strings?
+;++ Idea:
+;++
+;++   "foo"   |        ;bar
+;++   "baz"      ;quux
+;++
+;++ =>
+;++
+;++   "foo|baz"       ;bar
+;++              ;quux
+;++
+;++ The point should stay where it is relative to the comments, and the
+;++ the comments' columns should all be preserved, perhaps.  Hmmmm...
+;++ What about this?
+;++
+;++   "foo"           ;bar
+;++       |           ;baz
+;++   "quux"          ;zot
+
+;++ Should rename:
+;++     paredit-point-at-sexp-start     -> paredit-start-of-sexp-after-point
+;++     paredit-point-at-sexp-end       -> paredit-end-of-sexp-before-point
+
+;;;; Variations on the Lurid Theme
+
+;;; I haven't the imagination to concoct clever names for these.
+
+(defun paredit-add-to-previous-list ()
+  "Add the S-expression following point to the list preceding point."
+  (interactive)
+  (paredit-lose-if-not-in-sexp 'paredit-add-to-previous-list)
+  (save-excursion
+    (down-list -1)                      ;++ backward-down-list...
+    (paredit-forward-slurp-sexp)))
+
+(defun paredit-add-to-next-list ()
+  "Add the S-expression preceding point to the list following point.
+If no S-expression precedes point, move up the tree until one does."
+  (interactive)
+  (paredit-lose-if-not-in-sexp 'paredit-add-to-next-list)
+  (save-excursion
+    (down-list)
+    (paredit-backward-slurp-sexp)))
+
+(defun paredit-join-with-previous-list ()
+  "Join the list the point is on with the previous list in the buffer."
+  (interactive)
+  (paredit-lose-if-not-in-sexp 'paredit-join-with-previous-list)
+  (save-excursion
+    (while (paredit-handle-sexp-errors (save-excursion (backward-sexp) nil)
+             (backward-up-list)
+             t))
+    (paredit-join-sexps)))
+
+(defun paredit-join-with-next-list ()
+  "Join the list the point is on with the next list in the buffer."
+  (interactive)
+  (paredit-lose-if-not-in-sexp 'paredit-join-with-next-list)
+  (save-excursion
+    (while (paredit-handle-sexp-errors (save-excursion (forward-sexp) nil)
+             (up-list)
+             t))
+    (paredit-join-sexps)))
+
+;;;; Utilities
+
+(defun paredit-in-string-escape-p ()
+  "True if the point is on a character escape of a string.
+This is true only if the character is preceded by an odd number of
+  backslashes.
+This assumes that `paredit-in-string-p' has already returned true."
+  (let ((oddp nil))
+    (save-excursion
+      (while (eq (char-before) ?\\ )
+        (setq oddp (not oddp))
+        (backward-char)))
+    oddp))
+
+(defun paredit-in-char-p (&optional position)
+  "True if point is on a character escape outside a string."
+  (save-excursion
+    (goto-char (or position (point)))
+    (paredit-in-string-escape-p)))
+
+(defun paredit-skip-whitespace (trailing-p &optional limit)
+  "Skip past any whitespace, or until the point LIMIT is reached.
+If TRAILING-P is nil, skip leading whitespace; otherwise, skip trailing
+  whitespace."
+  (funcall (if trailing-p 'skip-chars-forward 'skip-chars-backward)
+           " \t\n"  ; This should skip using the syntax table, but LF
+           limit))    ; is a comment end, not newline, in Lisp mode.
+
+(defalias 'paredit-region-active-p
+  (xcond ((paredit-xemacs-p) 'region-active-p)
+         ((paredit-gnu-emacs-p)
+          (lambda ()
+            (and mark-active transient-mark-mode)))))
+
+(defun paredit-hack-kill-region (start end)
+  "Kill the region between START and END.
+Do not append to any current kill, and
+ do not let the next kill append to this one."
+  (interactive "r")                     ;Eh, why not?
+  ;; KILL-REGION sets THIS-COMMAND to tell the next kill that the last
+  ;; command was a kill.  It also checks LAST-COMMAND to see whether it
+  ;; should append.  If we bind these locally, any modifications to
+  ;; THIS-COMMAND will be masked, and it will not see LAST-COMMAND to
+  ;; indicate that it should append.
+  (let ((this-command nil)
+        (last-command nil))
+    (kill-region start end)))
+
+;;;;; Reindentation utilities
+
+;++ Should `paredit-indent-sexps' and `paredit-forward-and-indent' use
+;++ `paredit-indent-region' rather than `indent-region'?
+
+(defun paredit-indent-sexps ()
+  "If in a list, indent all following S-expressions in the list."
+  (let* ((start (point))
+         (end (paredit-handle-sexp-errors (progn (up-list) (point)) nil)))
+    (if end
+        (indent-region start end nil))))
+
+(defun paredit-forward-and-indent (&optional n)
+  "Move forward by N S-expressions, indenting them with `indent-region'."
+  (let ((start (point)))
+    (forward-sexp n)
+    (indent-region start (point) nil)))
+
+(defun paredit-indent-region (start end)
+  "Indent the region from START to END.
+Don't reindent the line starting at START, however."
+  (if (not (<= start end))
+      (error "Incorrectly related points: %S, %S" start end))
+  (save-excursion
+    (goto-char start)
+    (let ((bol (point-at-bol)))
+      ;; Skip all S-expressions that end on the starting line, but
+      ;; don't go past `end'.
+      (if (and (save-excursion (goto-char end) (not (eq bol (point-at-bol))))
+               (paredit-handle-sexp-errors
+                   (catch 'exit
+                     (while t
+                       (save-excursion
+                         (forward-sexp)
+                         (if (not (eq bol (point-at-bol)))
+                             (throw 'exit t))
+                         (if (not (< (point) end))
+                             (throw 'exit nil)))
+                       (forward-sexp)))
+                 nil))
+          (progn
+            ;; Point is still on the same line, but precedes an
+            ;; S-expression that ends on a different line.
+            (if (not (eq bol (point-at-bol)))
+                (error "Internal error -- we moved forward a line!"))
+            (goto-char (+ 1 (point-at-eol)))
+            (if (not (<= (point) end))
+                (error "Internal error -- we frobnitzed the garfnut!"))
+            (indent-region (point) end nil))))))
+
+;;;;; S-expression Parsing Utilities
+
+;++ These routines redundantly traverse S-expressions a great deal.
+;++ If performance issues arise, this whole section will probably have
+;++ to be refactored to preserve the state longer, like paredit.scm
+;++ does, rather than to traverse the definition N times for every key
+;++ stroke as it presently does.
+
+(defun paredit-current-parse-state ()
+  "Return parse state of point from beginning of defun."
+  (let ((point (point)))
+    (beginning-of-defun)
+    ;; Calling PARSE-PARTIAL-SEXP will advance the point to its second
+    ;; argument (unless parsing stops due to an error, but we assume it
+    ;; won't in paredit-mode).
+    (parse-partial-sexp (point) point)))
+
+(defun paredit-in-string-p (&optional state)
+  "True if the parse state is within a double-quote-delimited string.
+If no parse state is supplied, compute one from the beginning of the
+  defun to the point."
+  ;; 3. non-nil if inside a string (the terminator character, really)
+  (and (nth 3 (or state (paredit-current-parse-state)))
+       t))
+
+(defun paredit-string-start+end-points (&optional state)
+  "Return a cons of the points of open and close quotes of the string.
+The string is determined from the parse state STATE, or the parse state
+  from the beginning of the defun to the point.
+This assumes that `paredit-in-string-p' has already returned true, i.e.
+  that the point is already within a string."
+  (save-excursion
+    ;; 8. character address of start of comment or string; nil if not
+    ;;    in one
+    (let ((start (nth 8 (or state (paredit-current-parse-state)))))
+      (goto-char start)
+      (forward-sexp 1)
+      (cons start (1- (point))))))
+
+(defun paredit-enclosing-string-start ()
+  (car (paredit-string-start+end-points)))
+
+(defun paredit-enclosing-string-end ()
+  (+ 1 (cdr (paredit-string-start+end-points))))
+
+(defun paredit-enclosing-list-start ()
+  (save-excursion
+    (backward-up-list)
+    (point)))
+
+(defun paredit-enclosing-list-end ()
+  (save-excursion
+    (up-list)
+    (point)))
+
+(defun paredit-in-comment-p (&optional state)
+  "True if parse state STATE is within a comment.
+If no parse state is supplied, compute one from the beginning of the
+  defun to the point."
+  ;; 4. nil if outside a comment, t if inside a non-nestable comment,
+  ;;    else an integer (the current comment nesting)
+  (and (nth 4 (or state (paredit-current-parse-state)))
+       t))
+
+(defun paredit-prefix-numeric-value (argument)
+  ;++ Kludgerific.
+  (cond ((integerp argument) argument)
+        ((eq argument '-) -1)
+        ((consp argument)
+         (cond ((equal argument '(4)) (paredit-count-sexps-forward))   ;C-u
+               ((equal argument '(16)) (paredit-count-sexps-backward)) ;C-u C-u
+               (t (error "Invalid prefix argument: %S" argument))))
+        ((paredit-region-active-p)
+         (save-excursion
+           (save-restriction
+             (narrow-to-region (region-beginning) (region-end))
+             (cond ((= (point) (point-min)) (paredit-count-sexps-forward))
+                   ((= (point) (point-max)) (paredit-count-sexps-backward))
+                   (t
+                    (error "Point %S is not start or end of region: %S..%S"
+                           (point) (region-beginning) (region-end)))))))
+        (t 1)))
+
+(defun paredit-count-sexps-forward ()
+  (save-excursion
+    (let ((n 0) (p nil))                ;hurk
+      (paredit-ignore-sexp-errors
+        (while (setq p (scan-sexps (point) +1))
+          (goto-char p)
+          (setq n (+ n 1))))
+      n)))
+
+(defun paredit-count-sexps-backward ()
+  (save-excursion
+    (let ((n 0) (p nil))                ;hurk
+      (paredit-ignore-sexp-errors
+        (while (setq p (scan-sexps (point) -1))
+          (goto-char p)
+          (setq n (+ n 1))))
+      n)))
+
+(defun paredit-point-at-sexp-boundary (n)
+  (cond ((< n 0) (paredit-point-at-sexp-start))
+        ((= n 0) (point))
+        ((> n 0) (paredit-point-at-sexp-end))))
+
+(defun paredit-point-at-sexp-start ()
+  (save-excursion
+    (forward-sexp)
+    (backward-sexp)
+    (point)))
+
+(defun paredit-point-at-sexp-end ()
+  (save-excursion
+    (backward-sexp)
+    (forward-sexp)
+    (point)))
+
+(defun paredit-lose-if-not-in-sexp (command)
+  (if (or (paredit-in-string-p)
+          (paredit-in-comment-p)
+          (paredit-in-char-p))
+      (error "Invalid context for command `%s'." command)))
+
+(defun paredit-check-region (start end)
+  "Signal an error if text between `start' and `end' is unbalanced."
+  ;; `narrow-to-region' will move the point, so avoid calling it if we
+  ;; don't need to.  We don't want to use `save-excursion' because we
+  ;; want the point to move if `check-parens' reports an error.
+  (if (not (paredit-region-ok-p start end))
+      (save-restriction
+        (narrow-to-region start end)
+        (check-parens))))
+
+(defun paredit-region-ok-p (start end)
+  "Return true iff the region between `start' and `end' is balanced.
+This is independent of context -- it doesn't check what state the
+  text at `start' is in."
+  (save-excursion
+    (paredit-handle-sexp-errors
+        (progn
+          (save-restriction
+            (narrow-to-region start end)
+            (scan-sexps (point-min) (point-max)))
+          t)
+      nil)))
+
+(defun paredit-current-indentation ()
+  (save-excursion
+    (back-to-indentation)
+    (current-column)))
+
+(defun paredit-restore-column (column indentation)
+  ;; Preserve the point's position either in the indentation or in the
+  ;; code: if on code, move with the code; if in indentation, leave it
+  ;; in the indentation, either where it was (if still on indentation)
+  ;; or at the end of the indentation (if the code moved far enough
+  ;; left).
+  (let ((indentation* (paredit-current-indentation)))
+    (goto-char
+     (+ (point-at-bol)
+        (cond ((not (< column indentation))
+               (+ column (- indentation* indentation)))
+              ((<= indentation* column) indentation*)
+              (t column))))))
+
+;;;; Initialization
+
+(paredit-define-keys)
+(paredit-annotate-mode-with-examples)
+(paredit-annotate-functions-with-examples)
+
+(provide 'paredit)
+
+;;; Local Variables:
+;;; outline-regexp: "\n;;;;+"
+;;; End:
+
+;;; paredit.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/paredit-20171126.1805/paredit.elc b/configs/shared/emacs/.emacs.d/elpa/paredit-20171126.1805/paredit.elc
new file mode 100644
index 0000000000..f081a39c7c
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/paredit-20171126.1805/paredit.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/pcre2el-20161120.1303/pcre2el-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/pcre2el-20161120.1303/pcre2el-autoloads.el
new file mode 100644
index 0000000000..a34f0f958a
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/pcre2el-20161120.1303/pcre2el-autoloads.el
@@ -0,0 +1,217 @@
+;;; pcre2el-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "pcre2el" "pcre2el.el" (23377 61657 431322
+;;;;;;  853000))
+;;; Generated autoloads from pcre2el.el
+
+(defvar pcre-mode nil "\
+Non-nil if PCRE mode is enabled.
+See the `pcre-mode' command
+for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `pcre-mode'.")
+
+(custom-autoload 'pcre-mode "pcre2el" nil)
+
+(autoload 'pcre-mode "pcre2el" "\
+Use emulated PCRE syntax for regexps wherever possible.
+
+Advises the `interactive' specs of `read-regexp' and the
+following other functions so that they read PCRE syntax and
+translate to its Emacs equivalent:
+
+- `align-regexp'
+- `find-tag-regexp'
+- `sort-regexp-fields'
+- `isearch-message-prefix'
+- `ibuffer-do-replace-regexp'
+
+Also alters the behavior of `isearch-mode' when searching by regexp.
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'pcre-query-replace-regexp "pcre2el" "\
+Perform `query-replace-regexp' using PCRE syntax.
+
+Consider using `pcre-mode' instead of this function.
+
+\(fn)" t nil)
+
+(autoload 'rxt-elisp-to-pcre "pcre2el" "\
+Translate REGEXP, a regexp in Emacs Lisp syntax, to Perl-compatible syntax.
+
+Interactively, reads the regexp in one of three ways. With a
+prefix arg, reads from minibuffer without string escaping, like
+`query-replace-regexp'. Without a prefix arg, uses the text of
+the region if it is active. Otherwise, uses the result of
+evaluating the sexp before point (which might be a string regexp
+literal or an expression that produces a string).
+
+Displays the translated PCRE regexp in the echo area and copies
+it to the kill ring.
+
+Emacs regexp features such as syntax classes which cannot be
+translated to PCRE will cause an error.
+
+\(fn REGEXP)" t nil)
+
+(autoload 'rxt-elisp-to-rx "pcre2el" "\
+Translate REGEXP, a regexp in Emacs Lisp syntax, to `rx' syntax.
+
+See `rxt-elisp-to-pcre' for a description of the interactive
+behavior and `rx' for documentation of the S-expression based
+regexp syntax.
+
+\(fn REGEXP)" t nil)
+
+(autoload 'rxt-elisp-to-strings "pcre2el" "\
+Return a list of all strings matched by REGEXP, an Emacs Lisp regexp.
+
+See `rxt-elisp-to-pcre' for a description of the interactive behavior.
+
+This is useful primarily for getting back the original list of
+strings from a regexp generated by `regexp-opt', but it will work
+with any regexp without unbounded quantifiers (*, +, {2, } and so
+on).
+
+Throws an error if REGEXP contains any infinite quantifiers.
+
+\(fn REGEXP)" t nil)
+
+(autoload 'rxt-toggle-elisp-rx "pcre2el" "\
+Toggle the regexp near point between Elisp string and rx syntax.
+
+\(fn)" t nil)
+
+(autoload 'rxt-pcre-to-elisp "pcre2el" "\
+Translate PCRE, a regexp in Perl-compatible syntax, to Emacs Lisp.
+
+Interactively, uses the contents of the region if it is active,
+otherwise reads from the minibuffer. Prints the Emacs translation
+in the echo area and copies it to the kill ring.
+
+PCRE regexp features that cannot be translated into Emacs syntax
+will cause an error. See the commentary section of pcre2el.el for
+more details.
+
+\(fn PCRE &optional FLAGS)" t nil)
+
+(defalias 'pcre-to-elisp 'rxt-pcre-to-elisp)
+
+(autoload 'rxt-pcre-to-rx "pcre2el" "\
+Translate PCRE, a regexp in Perl-compatible syntax, to `rx' syntax.
+
+See `rxt-pcre-to-elisp' for a description of the interactive behavior.
+
+\(fn PCRE &optional FLAGS)" t nil)
+
+(autoload 'rxt-pcre-to-strings "pcre2el" "\
+Return a list of all strings matched by PCRE, a Perl-compatible regexp.
+
+See `rxt-elisp-to-pcre' for a description of the interactive
+behavior and `rxt-elisp-to-strings' for why this might be useful.
+
+Throws an error if PCRE contains any infinite quantifiers.
+
+\(fn PCRE &optional FLAGS)" t nil)
+
+(autoload 'rxt-explain-elisp "pcre2el" "\
+Insert the pretty-printed `rx' syntax for REGEXP in a new buffer.
+
+REGEXP is a regular expression in Emacs Lisp syntax. See
+`rxt-elisp-to-pcre' for a description of how REGEXP is read
+interactively.
+
+\(fn REGEXP)" t nil)
+
+(autoload 'rxt-explain-pcre "pcre2el" "\
+Insert the pretty-printed `rx' syntax for REGEXP in a new buffer.
+
+REGEXP is a regular expression in PCRE syntax. See
+`rxt-pcre-to-elisp' for a description of how REGEXP is read
+interactively.
+
+\(fn REGEXP &optional FLAGS)" t nil)
+
+(autoload 'rxt-quote-pcre "pcre2el" "\
+Return a PCRE regexp which matches TEXT literally.
+
+Any PCRE metacharacters in TEXT will be quoted with a backslash.
+
+\(fn TEXT)" nil nil)
+
+(autoload 'rxt-explain "pcre2el" "\
+Pop up a buffer with pretty-printed `rx' syntax for the regex at point.
+
+Chooses regex syntax to read based on current major mode, calling
+`rxt-explain-elisp' if buffer is in `emacs-lisp-mode' or
+`lisp-interaction-mode', or `rxt-explain-pcre' otherwise.
+
+\(fn)" t nil)
+
+(autoload 'rxt-convert-syntax "pcre2el" "\
+Convert regex at point to other kind of syntax, depending on major mode.
+
+For buffers in `emacs-lisp-mode' or `lisp-interaction-mode',
+calls `rxt-elisp-to-pcre' to convert to PCRE syntax. Otherwise,
+calls `rxt-pcre-to-elisp' to convert to Emacs syntax.
+
+The converted syntax is displayed in the echo area and copied to
+the kill ring; see the two functions named above for details.
+
+\(fn)" t nil)
+
+(autoload 'rxt-convert-to-rx "pcre2el" "\
+Convert regex at point to RX syntax. Chooses Emacs or PCRE syntax by major mode.
+
+\(fn)" t nil)
+
+(autoload 'rxt-convert-to-strings "pcre2el" "\
+Convert regex at point to RX syntax. Chooses Emacs or PCRE syntax by major mode.
+
+\(fn)" t nil)
+
+(autoload 'rxt-mode "pcre2el" "\
+Regex translation utilities.
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'turn-on-rxt-mode "pcre2el" "\
+Turn on `rxt-mode' in the current buffer.
+
+\(fn)" t nil)
+
+(defvar rxt-global-mode nil "\
+Non-nil if Rxt-Global mode is enabled.
+See the `rxt-global-mode' command
+for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `rxt-global-mode'.")
+
+(custom-autoload 'rxt-global-mode "pcre2el" nil)
+
+(autoload 'rxt-global-mode "pcre2el" "\
+Toggle Rxt mode in all buffers.
+With prefix ARG, enable Rxt-Global mode if ARG is positive;
+otherwise, disable it.  If called from Lisp, enable the mode if
+ARG is omitted or nil.
+
+Rxt mode is enabled in all buffers where
+`turn-on-rxt-mode' would do it.
+See `rxt-mode' for more information on Rxt mode.
+
+\(fn &optional ARG)" t nil)
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; pcre2el-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/pcre2el-20161120.1303/pcre2el-pkg.el b/configs/shared/emacs/.emacs.d/elpa/pcre2el-20161120.1303/pcre2el-pkg.el
new file mode 100644
index 0000000000..d21a132456
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/pcre2el-20161120.1303/pcre2el-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "pcre2el" "20161120.1303" "regexp syntax converter" '((emacs "24") (cl-lib "0.3")))
diff --git a/configs/shared/emacs/.emacs.d/elpa/pcre2el-20161120.1303/pcre2el.el b/configs/shared/emacs/.emacs.d/elpa/pcre2el-20161120.1303/pcre2el.el
new file mode 100644
index 0000000000..e4f925c623
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/pcre2el-20161120.1303/pcre2el.el
@@ -0,0 +1,3157 @@
+;;; pcre2el.el --- regexp syntax converter -*- lexical-binding: t -*-
+
+;; Copyright (C) 2012-2015 Jon Oddie <jonxfield@gmail.com>
+
+;; Author:			joddie <jonxfield at gmail.com>
+;; Hacked additionally by:	opensource at hardakers dot net
+;; Created:			14 Feb 2012
+;; Updated:			13 December 2015
+;; Version:                     1.8
+;; Package-Version: 20161120.1303
+;; Url:                         https://github.com/joddie/pcre2el
+;; Package-Requires:            ((emacs "24") (cl-lib "0.3"))
+
+;; This file is NOT part of GNU Emacs.
+
+;; This program 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.
+;;
+;; This program 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 this program.  If not, see `http://www.gnu.org/licenses/'.
+
+;; This file incorporates work covered by the following copyright and
+;; permission notice:
+;;
+;; Copyright (c) 1993-2002 Richard Kelsey and Jonathan Rees
+;; Copyright (c) 1994-2002 by Olin Shivers and Brian D. Carlstrom.
+;; Copyright (c) 1999-2002 by Martin Gasbichler.
+;; Copyright (c) 2001-2002 by Michael Sperber.
+;; All rights reserved.
+;;
+;; Redistribution and use in source and binary forms, with or without
+;; modification, are permitted provided that the following conditions
+;; are met: 1. Redistributions of source code must retain the above
+;; copyright notice, this list of conditions and the following
+;; disclaimer. 2. Redistributions in binary form must reproduce the
+;; above copyright notice, this list of conditions and the following
+;; disclaimer in the documentation and/or other materials provided
+;; with the distribution. 3. The name of the authors may not be used
+;; to endorse or promote products derived from this software without
+;; specific prior written permission.
+;;
+;; THIS SOFTWARE IS PROVIDED BY THE AUTHORS "AS IS" AND ANY EXPRESS OR
+;; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+;; ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
+;; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+;; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+;;; Commentary:
+
+;; 1 Overview
+;; ==========
+
+;;   `pcre2el' or `rxt' (RegeXp Translator or RegeXp Tools) is a utility
+;;   for working with regular expressions in Emacs, based on a
+;;   recursive-descent parser for regexp syntax. In addition to converting
+;;   (a subset of) PCRE syntax into its Emacs equivalent, it can do the
+;;   following:
+
+;;   - convert Emacs syntax to PCRE
+;;   - convert either syntax to `rx', an S-expression based regexp syntax
+;;   - untangle complex regexps by showing the parse tree in `rx' form and
+;;     highlighting the corresponding chunks of code
+;;   - show the complete list of strings (productions) matching a regexp,
+;;     provided the list is finite
+;;   - provide live font-locking of regexp syntax (so far only for Elisp
+;;     buffers -- other modes on the TODO list)
+
+
+;; 2 Usage
+;; =======
+
+;;   Enable `rxt-mode' or its global equivalent `rxt-global-mode' to get
+;;   the default key-bindings. There are three sets of commands: commands
+;;   that take a PCRE regexp, commands which take an Emacs regexp, and
+;;   commands that try to do the right thing based on the current
+;;   mode. Currently, this means Emacs syntax in `emacs-lisp-mode' and
+;;   `lisp-interaction-mode', and PCRE syntax everywhere else.
+
+;;   The default key bindings all begin with `C-c /' and have a mnemonic
+;;   structure: `C-c / <source> <target>', or just `C-c / <target>' for the
+;;   "do what I mean" commands. The complete list of key bindings is given
+;;   here and explained in more detail below:
+
+;;   - "Do-what-I-mean" commands:
+;;     `C-c / /': `rxt-explain'
+;;     `C-c / c': `rxt-convert-syntax'
+;;     `C-c / x': `rxt-convert-to-rx'
+;;     `C-c / '': `rxt-convert-to-strings'
+
+;;   - Commands that work on a PCRE regexp:
+;;     `C-c / p e': `rxt-pcre-to-elisp'
+;;     `C-c / %': `pcre-query-replace-regexp'
+;;     `C-c / p x': `rxt-pcre-to-rx'
+;;     `C-c / p '': `rxt-pcre-to-strings'
+;;     `C-c / p /': `rxt-explain-pcre'
+
+;;   - Commands that work on an Emacs regexp:
+;;     `C-c / e /': `rxt-explain-elisp'
+;;     `C-c / e p': `rxt-elisp-to-pcre'
+;;     `C-c / e x': `rxt-elisp-to-rx'
+;;     `C-c / e '': `rxt-elisp-to-strings'
+;;     `C-c / e t': `rxt-toggle-elisp-rx'
+;;     `C-c / t': `rxt-toggle-elisp-rx'
+
+
+;; 2.1 Interactive input and output
+;; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+;;   When used interactively, the conversion commands can read a regexp
+;;   either from the current buffer or from the minibuffer. The output is
+;;   displayed in the minibuffer and copied to the kill-ring.
+
+;;   - When called with a prefix argument (`C-u'), they read a regular
+;;     expression from the minibuffer literally, without further processing
+;;     -- meaning there's no need to double the backslashes if it's an
+;;     Emacs regexp.  This is the same way commands like
+;;     `query-replace-regexp' read input.
+
+;;   - When the region is active, they use they the region contents, again
+;;     literally (without any translation of string syntax).
+
+;;   - With neither a prefix arg nor an active region, the behavior depends
+;;     on whether the command expects an Emacs regexp or a PCRE one.
+
+;;     Commands that take an Emacs regexp behave like `C-x C-e': they
+;;     evaluate the sexp before point (which could be simply a string
+;;     literal) and use its value. This is designed for use in Elisp
+;;     buffers. As a special case, if point is *inside* a string, it's
+;;     first moved to the string end, so in practice they should work as
+;;     long as point is somewhere within the regexp literal.
+
+;;     Commands that take a PCRE regexp try to read a Perl-style delimited
+;;     regex literal *after* point in the current buffer, including its
+;;     flags. For example, putting point before the `m' in the following
+;;     example and doing `C-c / p e' (`rxt-pcre-to-elisp') displays
+;;     `\(?:bar\|foo\)', correctly stripping out the whitespace and
+;;     comment:
+
+;;     ,----
+;;     | $x =~ m/  foo   |  (?# comment) bar /x
+;;     `----
+
+;;     The PCRE reader currently only works with `/ ... /' delimiters. It
+;;     will ignore any preceding `m', `s', or `qr' operator, as well as the
+;;     replacement part of an `s' construction.
+
+;;     Readers for other PCRE-using languages are on the TODO list.
+
+;;   The translation functions display their result in the minibuffer and
+;;   copy it to the kill ring. When translating something into Elisp
+;;   syntax, you might need to use the result either literally (e.g. for
+;;   interactive input to a command like `query-replace-regexp'), or as a
+;;   string to paste into Lisp code.  To allow both uses,
+;;   `rxt-pcre-to-elisp' copies both versions successively to the
+;;   kill-ring. The literal regexp without string quoting is the top
+;;   element of the kill-ring, while the Lisp string is the
+;;   second-from-top. You can paste the literal regexp somewhere by doing
+;;   `C-y', or the Lisp string by `C-y M-y'.
+
+
+;; 2.2 Syntax conversion commands
+;; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+;;   `rxt-convert-syntax' (`C-c / c') converts between Emacs and PCRE
+;;   syntax, depending on the major mode in effect when called.
+;;   Alternatively, you can specify the conversion direction explicitly by
+;;   using either `rxt-pcre-to-elisp' (`C-c / p e') or `rxt-elisp-to-pcre'
+;;   (`C-c / e p').
+
+;;   Similarly, `rxt-convert-to-rx' (`C-c / x') converts either kind of
+;;   syntax to `rx' form, while `rxt-convert-pcre-to-rx' (`C-c / p x') and
+;;   `rxt-convert-elisp-to-rx' (`C-c / e x') convert to `rx' from a
+;;   specified source type.
+
+;;   In Elisp buffers, you can use `rxt-toggle-elisp-rx' (`C-c / t' or `C-c
+;;   / e t') to switch the regexp at point back and forth between string
+;;   and `rx' syntax. Point should either be within an `rx' or
+;;   `rx-to-string' form or a string literal for this to work.
+
+
+;; 2.3 PCRE mode (experimental)
+;; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+;;   If you want to use emulated PCRE regexp syntax in all Emacs commands,
+;;   try `pcre-mode', which uses Emacs's advice system to make all commands
+;;   that read regexps using the minibuffer use emulated PCRE syntax.  It
+;;   should also work with Isearch.
+
+;;   This feature is still fairly experimental.  It may fail to work or do
+;;   the wrong thing with certain commands.  Please report bugs.
+
+;;   `pcre-query-replace-regexp' was originally defined to do query-replace
+;;   using emulated PCRE regexps, and is now made somewhat obsolete by
+;;   `pcre-mode'.  It is bound to `C-c / %' by default, by analogy with
+;;   `M-%'.  Put the following in your `.emacs' if you want to use
+;;   PCRE-style query replacement everywhere:
+
+;;   ,----
+;;   | (global-set-key [(meta %)] 'pcre-query-replace-regexp)
+;;   `----
+
+;; 2.5 Explain regexps
+;; ~~~~~~~~~~~~~~~~~~~
+
+;;   When syntax-highlighting isn't enough to untangle some gnarly regexp
+;;   you find in the wild, try the 'explain' commands: `rxt-explain' (`C-c
+;;   / /'), `rxt-explain-pcre' (`C-c / p') and `rxt-explain-elisp' (`C-c /
+;;   e'). These display the original regexp along with its pretty-printed
+;;   `rx' equivalent in a new buffer.  Moving point around either in the
+;;   original regexp or the `rx' translation highlights corresponding
+;;   pieces of syntax, which can aid in seeing things like the scope of
+;;   quantifiers.
+
+;;   I call them "explain" commands because the `rx' form is close to a
+;;   plain syntax tree, and this plus the wordiness of the operators
+;;   usually helps to clarify what is going on.  People who dislike Lisp
+;;   syntax might disagree with this assessment.
+
+
+;; 2.6 Generate all matching strings (productions)
+;; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+;;   Occasionally you come across a regexp which is designed to match a
+;;   finite set of strings, e.g. a set of keywords, and it would be useful
+;;   to recover the original set. (In Emacs you can generate such regexps
+;;   using `regexp-opt'). The commands `rxt-convert-to-strings' (`C-c /
+;;   ′'), `rxt-pcre-to-strings' (`C-c / p ′') or `rxt-elisp-to-strings'
+;;   (`C-c / e ′') accomplish this by generating all the matching strings
+;;   ("productions") of a regexp.  (The productions are copied to the kill
+;;   ring as a Lisp list).
+
+;;   An example in Lisp code:
+
+;;   ,----
+;;   | (regexp-opt '("cat" "caterpillar" "catatonic"))
+;;   |    ;; => "\\(?:cat\\(?:atonic\\|erpillar\\)?\\)"
+;;   | (rxt-elisp-to-strings "\\(?:cat\\(?:atonic\\|erpillar\\)?\\)")
+;;   |     ;; => '("cat" "caterpillar" "catatonic")
+;;   `----
+
+;;   For obvious reasons, these commands only work with regexps that don't
+;;   include any unbounded quantifiers like `+' or `*'. They also can't
+;;   enumerate all the characters that match a named character class like
+;;   `[[:alnum:]]'. In either case they will give a (hopefully meaningful)
+;;   error message. Due to the nature of permutations, it's still possible
+;;   for a finite regexp to generate a huge number of productions, which
+;;   will eat memory and slow down your Emacs. Be ready with `C-g' if
+;;   necessary.
+
+
+;; 2.7 RE-Builder support
+;; ~~~~~~~~~~~~~~~~~~~~~~
+
+;;   The Emacs RE-Builder is a useful visual tool which allows using
+;;   several different built-in syntaxes via `reb-change-syntax' (`C-c
+;;   TAB'). It supports Elisp read and literal syntax and `rx', but it can
+;;   only convert from the symbolic forms to Elisp, not the other way. This
+;;   package hacks the RE-Builder to also work with emulated PCRE syntax,
+;;   and to convert transparently between Elisp, PCRE and rx syntaxes. PCRE
+;;   mode reads a delimited Perl-like literal of the form `/ ... /', and it
+;;   should correctly support using the `x' and `s' flags.
+
+
+;; 2.8 Use from Lisp
+;; ~~~~~~~~~~~~~~~~~
+
+;;   Example of using the conversion functions:
+;;   ,----
+;;   | (rxt-pcre-to-elisp "(abc|def)\\w+\\d+")
+;;   |    ;; => "\\(\\(?:abc\\|def\\)\\)[_[:alnum:]]+[[:digit:]]+"
+;;   `----
+
+;;   All the conversion functions take a single string argument, the regexp
+;;   to translate:
+
+;;   - `rxt-pcre-to-elisp'
+;;   - `rxt-pcre-to-rx'
+;;   - `rxt-pcre-to-strings'
+;;   - `rxt-elisp-to-pcre'
+;;   - `rxt-elisp-to-rx'
+;;   - `rxt-elisp-to-strings'
+
+
+;; 3 Bugs and Limitations
+;; ======================
+
+;; 3.1 Limitations on PCRE syntax
+;; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+;;   PCRE has a complicated syntax and semantics, only some of which can be
+;;   translated into Elisp. The following subset of PCRE should be
+;;   correctly parsed and converted:
+
+;;   - parenthesis grouping `( .. )', including shy matches `(?: ... )'
+;;   - backreferences (various syntaxes), but only up to 9 per expression
+;;   - alternation `|'
+;;   - greedy and non-greedy quantifiers `*', `*?', `+', `+?', `?' and `??'
+;;           (all of which are the same in Elisp as in PCRE)
+;;   - numerical quantifiers `{M,N}'
+;;   - beginning/end of string `\A', `\Z'
+;;   - string quoting `\Q .. \E'
+;;   - word boundaries `\b', `\B' (these are the same in Elisp)
+;;   - single character escapes `\a', `\c', `\e', `\f', `\n', `\r', `\t',
+;;     `\x', and `\octal digits' (but see below about non-ASCII characters)
+;;   - character classes `[...]' including Posix escapes
+;;   - character classes `\d', `\D', `\h', `\H', `\s', `\S', `\v', `\V'
+;;           both within character class brackets and outside
+;;   - word and non-word characters `\w' and `\W' (Emacs has the same
+;;           syntax, but its meaning is different)
+;;   - `s' (single line) and `x' (extended syntax) flags, in regexp
+;;     literals, or set within the expression via `(?xs-xs)' or `(?xs-xs:
+;;     .... )' syntax
+;;   - comments `(?# ... )'
+
+;;   Most of the more esoteric PCRE features can't really be supported by
+;;   simple translation to Elisp regexps. These include the different
+;;   lookaround assertions, conditionals, and the "backtracking control
+;;   verbs" `(* ...)' . OTOH, there are a few other syntaxes which are
+;;   currently unsupported and possibly could be:
+
+;;   - `\L', `\U', `\l', `\u' case modifiers
+;;   - `\g{...}' backreferences
+
+
+;; 3.2 Other limitations
+;; ~~~~~~~~~~~~~~~~~~~~~
+
+;;   - The order of alternatives and characters in char classes sometimes
+;;     gets shifted around, which is annoying.
+;;   - Although the string parser tries to interpret PCRE's octal and
+;;     hexadecimal escapes correctly, there are problems with matching
+;;     8-bit characters that I don't use enough to properly understand,
+;;     e.g.:
+;;     ,----
+;;     | (string-match-p (rxt-pcre-to-elisp "\\377") "\377") => nil
+;;     `----
+;;     A fix for this would be welcome.
+
+;;   - Most of PCRE's rules for how `^', `\A', `$' and `\Z' interact with
+;;     newlines are not implemented, since they seem less relevant to
+;;     Emacs's buffer-oriented rather than line-oriented model.  However,
+;;     the different meanings of the `.' metacharacter *are* implemented
+;;     (it matches newlines with the `/s' flag, but not otherwise).
+
+;;   - Not currently namespace clean (both `rxt-' and a couple of `pcre-'
+;;     functions).
+
+
+;; 3.3 TODO:
+;; ~~~~~~~~~
+
+;;   - Python-specific extensions to PCRE?
+;;   - Language-specific stuff to enable regexp font-locking and explaining
+;;     in different modes. Each language would need two functions, which
+;;     could be kept in an alist:
+
+;;     1. A function to read PCRE regexps, taking the string syntax into
+;;        account. E.g., Python has single-quoted, double-quoted and raw
+;;        strings, each with different quoting rules.  PHP has the kind of
+;;        belt-and-suspenders solution you would expect: regexps are in
+;;        strings, /and/ you have to include the `/ ...  /' delimiters!
+;;        Duh.
+
+;;     2. A function to copy faces back from the parsed string to the
+;;        original buffer text. This has to recognize any escape sequences
+;;        so they can be treated as a single character.
+
+
+;; 4 Internal details
+;; ==================
+
+;;   `rxt' defines an internal syntax tree representation of regular
+;;   expressions, parsers for Elisp and PCRE syntax, and 'unparsers'
+;;   to convert the internal representation to PCRE or `rx' syntax.
+;;   Converting from the internal representation to Emacs syntax is
+;;   done by converting to `rx' form and passing it to `rx-to-string'.
+;;   See `rxt-parse-re', `rxt-adt->pcre', and `rxt-adt->rx' for
+;;   details.
+
+;;   This code is partially based on Olin Shivers' reference SRE
+;;   implementation in scsh, although it is simplified in some respects and
+;;   extended in others. See `scsh/re.scm', `scsh/spencer.scm' and
+;;   `scsh/posixstr.scm' in the `scsh' source tree for details. In
+;;   particular, `pcre2el' steals the idea of an abstract data type for
+;;   regular expressions and the general structure of the string regexp
+;;   parser and unparser. The data types for character sets are extended in
+;;   order to support symbolic translation between character set
+;;   expressions without assuming a small (Latin1) character set. The
+;;   string parser is also extended to parse a bigger variety of
+;;   constructions, including POSIX character classes and various Emacs and
+;;   Perl regexp assertions. Otherwise, only the bare minimum of scsh's
+;;   abstract data type is implemented.
+
+
+;; 5 Soapbox
+;; =========
+
+;;   Emacs regexps have their annoyances, but it is worth getting used to
+;;   them. The Emacs assertions for word boundaries, symbol boundaries, and
+;;   syntax classes depending on the syntax of the mode in effect are
+;;   especially useful. (PCRE has `\b' for word-boundary, but AFAIK it
+;;   doesn't have separate assertions for beginning-of-word and
+;;   end-of-word). Other things that might be done with huge regexps in
+;;   other languages can be expressed more understandably in Elisp using
+;;   combinations of `save-excursion' with the various searches (regexp,
+;;   literal, skip-syntax-forward, sexp-movement functions, etc.).
+
+;;   There's not much point in using `rxt-pcre-to-elisp' to use PCRE
+;;   notation in a Lisp program you're going to maintain, since you still
+;;   have to double all the backslashes.  Better to just use the converted
+;;   result (or better yet, the `rx' form).
+
+
+;; 6 History and acknowledgments
+;; =============================
+
+;;   This was originally created out of an answer to a stackoverflow
+;;   question:
+;;   [http://stackoverflow.com/questions/9118183/elisp-mechanism-for-converting-pcre-regexps-to-emacs-regexps]
+
+;;   Thanks to:
+
+;;   - Wes Hardaker (hardaker) for the initial inspiration and subsequent
+;;     hacking
+;;   - priyadarshan for requesting RX support
+;;   - Daniel Colascione (dcolascione) for a patch to support Emacs's
+;;     explicitly-numbered match groups
+;;   - Aaron Meurer (asmeurer) for requesting Isearch support
+;;   - Philippe Vaucher (silex) for a patch to support `ibuffer-do-replace-regexp'
+;;     in PCRE mode
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'rx)
+(require 're-builder)
+(require 'advice)
+(require 'ring)
+(require 'pcase)
+
+;;; Customization group
+(defgroup rxt nil
+  "Regex syntax converter and utilities."
+  :version 1.2
+  :group 'tools
+  :group 'lisp
+  :link '(emacs-commentary-link :tag "commentary" "pcre2el.el")
+  :link '(emacs-library-link :tag "lisp file" "pcre2el.el")
+  :link '(url-link :tag "web page" "https://github.com/joddie/pcre2el"))
+
+(defface rxt-highlight-face
+  '((((min-colors 16581375) (background light)) :background "#eee8d5")
+    (((min-colors 16581375) (background dark)) :background "#222222"))
+  "Face for highlighting corresponding regex syntax in `rxt-explain' buffers."
+  :group 'rxt)
+
+(defcustom rxt-verbose-rx-translation nil
+  "Non-nil if `rxt-pcre-to-rx' and `rxt-elisp-to-rx' should use verbose `rx' primitives.
+
+Verbose primitives are things like `line-start' instead of `bol',
+etc."
+  :group 'rxt
+  :type 'boolean)
+
+(defcustom rxt-explain-verbosely t
+  "Non-nil if `rxt-explain-elisp' and `rxt-explain-pcre' should use verbose `rx' primitives.
+
+This overrides the value of `rxt-verbose-rx-translation' for
+these commands only."
+  :group 'rxt
+  :type 'boolean)
+
+
+;;;; Macros and functions for writing interactive input and output
+
+;; Macros for handling return values.  If called interactively,
+;; display the value in the echo area and copy it to the kill ring,
+;; otherwise just return the value.  PCREs are copied as unquoted
+;; strings for yanking into Perl, JS, etc.  `rx' forms and other sexps
+;; are copied as `read'-able literals for yanking into Elisp buffers.
+;; Emacs regexps are copied twice: once as an unquoted value for
+;; interactive use, and once as a readable string literal for yanking
+;; into Elisp buffers.
+(defmacro rxt-return-pcre (expr)
+  (let ((value (make-symbol "value")))
+    `(let ((,value ,expr))
+       (when (called-interactively-p 'any)
+         (rxt--kill-pcre ,value))
+       ,value)))
+
+(defmacro rxt-return-sexp (expr)
+  (let ((value (make-symbol "value")))
+    `(let ((,value ,expr))
+       (when (called-interactively-p 'any)
+         (rxt--kill-sexp ,value))
+       ,value)))
+
+(defmacro rxt-return-emacs-regexp (expr)
+  (let ((value (make-symbol "value")))
+    `(let ((,value ,expr))
+       (when (called-interactively-p 'any)
+         (rxt--kill-emacs-regexp ,value))
+       ,value)))
+
+(defun rxt--kill-sexp (value)
+  (let ((lisp-literal (prin1-to-string value)))
+    (message "%s" lisp-literal)
+    (kill-new lisp-literal)))
+
+(defun rxt--kill-pcre (value)
+  (message "%s" value)
+  (kill-new value))
+
+(defun rxt--kill-emacs-regexp (value)
+  (let ((lisp-literal (prin1-to-string value)))
+    (message "%s" value)
+    (kill-new lisp-literal)
+    (kill-new value)))
+
+;; Read an Elisp regexp interactively.
+;;
+;; Three possibilities:
+;;
+;; 1) With a prefix arg, reads literally from the minibuffer, w/o
+;; using string syntax -- just like query-replace-regexp, etc.
+;;
+;; 2) If the region is active, use the text of the region literally
+;; (again w/o string syntax)
+;;
+;; 3) Otherwise, eval the sexp before point (which might be a string
+;; literal or an expression) and use its value. Falls back to method
+;; (1) if this fails to produce a string value.
+;;
+(cl-defun rxt-interactive/elisp (&optional (prompt "Emacs regexp: "))
+  (list
+   (cond (current-prefix-arg
+          (read-string prompt))
+
+         ((use-region-p)
+          (buffer-substring-no-properties (region-beginning) (region-end)))
+
+         (t
+          (condition-case nil
+              (save-excursion
+                (while (nth 3 (syntax-ppss)) (forward-char))
+                (let ((re (eval (preceding-sexp))))
+                  (if (stringp re) re
+                    (read-string prompt))))
+            (error
+             (read-string prompt)))))))
+
+;; Read a PCRE regexp interactively.
+;;
+;; Three possibilities: As above, except that without prefix arg or
+;; active region, tries to read a delimited regexp literal like /.../,
+;; m/.../, or qr/.../ following point in the current buffer. Falls
+;; back to reading from minibuffer if that fails.
+;;
+;; Returns the regexp, with flags as text properties.
+;;
+;; TODO: Different delimiters
+(cl-defun rxt-interactive/pcre (&optional (prompt "PCRE regexp: "))
+  (list
+   (cond (current-prefix-arg
+          (rxt--read-pcre prompt))
+
+         ((use-region-p)
+          (buffer-substring-no-properties (region-beginning) (region-end)))
+
+         (t
+          (condition-case nil
+              (rxt-read-delimited-pcre)
+            (error                     ; Fall back to reading from minibuffer
+             (rxt--read-pcre prompt)))))
+   nil))
+
+(define-minor-mode rxt--read-pcre-mode
+    "Minor-mode with key-bindings for toggling PCRE flags.
+
+You should not normally call this directly.  It will be enabled
+in minibuffers for `read-regexp' and in the `re-builder' buffer
+when `pcre-mode' is active.  These bindings will also be added to
+`isearch-mode-map' in `pcre-mode'."
+  :initial nil
+  :lighter nil
+  :keymap
+  `((,(kbd "C-c s") . ,#'rxt--toggle-s-mode)
+    (,(kbd "C-c x") . ,#'rxt--toggle-x-mode)
+    (,(kbd "C-c i") . ,#'rxt--toggle-i-mode)))
+
+(defun rxt--read-pcre (prompt)
+  "Read a PCRE regexp for translation, together with option flags.
+
+The `s', `x', and `i' flags can be toggled using the following
+commands: \\<rxt--read-pcre-mode-map>
+
+\\[rxt--toggle-s-mode] : toggle `s' (single-line) mode
+\\[rxt--toggle-x-mode] : toggle `x' (extended) mode
+\\[rxt--toggle-i-mode] : toggle `i' (case-insensitive) mode
+
+In single-line mode, `.' will also match newlines.
+In extended mode, whitespace is ignored.
+
+Case-insensitive mode emulates matching without case,
+independently of Emacs's builtin `case-fold-search' setting.
+Note that this does not apply to backreferences."
+  (minibuffer-with-setup-hook #'rxt--read-pcre-mode
+    (read-from-minibuffer prompt)))
+
+(defun rxt--toggle-s-mode ()
+  "Toggle emulated PCRE single-line (s) flag."
+  (interactive)
+  (rxt--toggle-flag ?s))
+
+(defun rxt--toggle-x-mode ()
+  "Toggle emulated PCRE extended (x) flag."
+  (interactive)
+  (rxt--toggle-flag ?x))
+
+(defun rxt--toggle-i-mode ()
+  "Toggle emulated PCRE case-insensitive (i) flag."
+  (interactive)
+  (rxt--toggle-flag ?i))
+
+(defun rxt--toggle-flag (char)
+  "Toggle CHAR, a PCRE flag."
+  (cond
+    ((derived-mode-p 'reb-mode)         ; RE-Builder
+     (rxt--toggle-flag-re-builder char))
+    ((minibufferp)
+     (rxt--toggle-flag-minibuffer char))
+    (isearch-mode
+     (rxt--toggle-flag-isearch char))
+    (t
+     (error "Not in minibuffer, RE-Builder or isearch mode."))))
+
+(defun rxt--toggle-flag-re-builder (char)
+  (save-excursion
+    (goto-char (point-max))
+    (search-backward "/")
+    (forward-char)
+    (when (looking-at (rx (* (any ?i ?s ?x))))
+      (let ((inhibit-modification-hooks t))
+        (replace-match (rxt--xor-flags (match-string 0) char) t t))))
+  (reb-do-update))
+
+(defun rxt--toggle-flag-minibuffer (char)
+  (setf (buffer-substring (minibuffer-prompt-end) (point-max))
+        (rxt--toggle-flag-string (minibuffer-contents) char))
+  (when
+      (and (= (point) (minibuffer-prompt-end))
+           (looking-at (rx "(?" (group (+ (any ?i ?s ?x))) ")")))
+    (forward-sexp)))
+
+(defun rxt--toggle-flag-isearch (char)
+  (when isearch-regexp
+    (setq isearch-string
+          (rxt--toggle-flag-string isearch-string char))
+    (setq isearch-message
+          (mapconcat #'isearch-text-char-description isearch-string ""))
+    (isearch-search-and-update)))
+
+(defun rxt--toggle-flag-string (string char)
+  (if (string-match (rx string-start "(?" (group (+ (any ?i ?s ?x))) ")")
+                    string)
+      (let ((flags (rxt--xor-flags (match-string 1 string) char)))
+        (if (string= flags "")
+            (replace-match "" t t string)
+          (replace-match flags t t string 1)))
+    (format "(?%c)%s" char string)))
+
+(defun rxt--xor-flags (flags char)
+  (concat
+   (sort
+    (cl-set-exclusive-or (string-to-list flags) (list char))
+    #'<)))
+
+
+;;;; Minor mode for using emulated PCRE syntax
+
+(defvar pcre-old-isearch-search-fun-function nil
+  "Original value of `isearch-search-fun-function' before entering `pcre-mode.'
+
+This function is wrapped by `pcre-isearch-search-fun-function'
+and restored on exit from `pcre-mode'.")
+(make-variable-buffer-local 'pcre-old-isearch-search-fun-function)
+
+(defvar pcre-old-isearch-key-bindings nil
+  "Alist of key-bindings to restore in `isearch-mode-map' on exiting `pcre-mode'.")
+
+;;;###autoload
+(define-minor-mode pcre-mode
+  "Use emulated PCRE syntax for regexps wherever possible.
+
+Advises the `interactive' specs of `read-regexp' and the
+following other functions so that they read PCRE syntax and
+translate to its Emacs equivalent:
+
+- `align-regexp'
+- `find-tag-regexp'
+- `sort-regexp-fields'
+- `isearch-message-prefix'
+- `ibuffer-do-replace-regexp'
+
+Also alters the behavior of `isearch-mode' when searching by regexp."
+  nil " PCRE"
+  nil
+  :global t
+
+  (if pcre-mode
+      ;; Enabling
+      (progn
+        ;; Enable advice
+        (ad-enable-regexp "pcre-mode")
+        ;; Set up isearch hooks
+        (add-hook 'isearch-mode-hook #'pcre-isearch-mode-hook)
+        (add-hook 'isearch-mode-end-hook #'pcre-isearch-mode-end-hook)
+        ;; Add the keybindings of `rxt--read-pcre-mode-map' to
+        ;; `isearch-mode-map' (so that they do not cause an exit from
+        ;; `isearch-mode'), and save any existing bindings for those
+        ;; keys to restore on exit from `pcre-mode'.
+        (setq pcre-old-isearch-key-bindings
+              (cl-loop for key being the key-seqs of rxt--read-pcre-mode-map
+                       for def = (lookup-key isearch-mode-map key)
+                       collect (cons (copy-sequence key)
+                                     (if (numberp def) nil def))))
+        (cl-loop for key being the key-seqs of rxt--read-pcre-mode-map
+                 using (key-bindings def)
+                 do (define-key isearch-mode-map key def)))
+
+    ;; Disable advice
+    (ad-disable-regexp "pcre-mode")
+    ;; Remove from isearch hooks
+    (remove-hook 'isearch-mode-hook #'pcre-isearch-mode-hook)
+    (remove-hook 'isearch-mode-end-hook #'pcre-isearch-mode-end-hook)
+    ;; Restore key-bindings
+    (cl-loop for (key . def) in pcre-old-isearch-key-bindings
+             do (define-key isearch-mode-map key def)))
+
+  ;; "Activating" advice re-computes the function definitions, which
+  ;; is necessary whether enabling or disabling
+  (ad-activate-regexp "pcre-mode"))
+
+;;; Cache of PCRE -> Elisp translations
+(defvar pcre-mode-cache-size 100
+  "Number of PCRE-to-Emacs translations to keep in the `pcre-mode' cache.")
+
+(defvar pcre-mode-cache (make-hash-table :test 'equal)
+  "Cache of PCRE-to-Emacs translations used in `pcre-mode'.
+
+Keys are PCRE regexps, values are their Emacs equivalents.")
+
+(defvar pcre-mode-reverse-cache (make-hash-table :test 'equal)
+  "Cache of original PCREs translated to Emacs syntax in `pcre-mode'.
+
+Keys are translated Emacs regexps, values are their original PCRE
+form.  This is used to display the original PCRE regexp in place
+of its translated form.")
+
+(defvar pcre-cache-ring (make-ring pcre-mode-cache-size)
+  "Ring of PCRE-to-Emacs translations used in `pcre-mode'.
+
+When the ring fills up, the oldest element is removed and the
+corresponding entries are deleted from the hash tables
+`pcre-mode-cache' and `pcre-mode-reverse-cache'.")
+
+(defun pcre-to-elisp/cached (pcre)
+  "Translate PCRE to Emacs syntax, caching both forms."
+  (or (gethash pcre pcre-mode-cache)
+      (let ((elisp (rxt-pcre-to-elisp pcre)))
+        (pcre-set-cache pcre elisp)
+        elisp)))
+
+(defun pcre-set-cache (pcre-regexp emacs-regexp)
+  "Add a PCRE-to-Emacs translation to the `pcre-mode' cache."
+  (when (and (not (zerop (length pcre-regexp)))
+             (not (zerop (length emacs-regexp)))
+             (not (gethash pcre-regexp pcre-mode-cache)))
+    (if (= (ring-length pcre-cache-ring) (ring-size pcre-cache-ring))
+        (let* ((old-item (ring-remove pcre-cache-ring))
+               (old-pcre (car old-item))
+               (old-emacs (cdr old-item)))
+          (remhash old-pcre pcre-mode-cache)
+          (remhash old-emacs pcre-mode-reverse-cache))
+      (puthash pcre-regexp emacs-regexp pcre-mode-cache)
+      (puthash emacs-regexp pcre-regexp pcre-mode-reverse-cache)
+      (ring-insert pcre-cache-ring (cons pcre-regexp emacs-regexp)))))
+
+;;; Isearch advice
+(defun pcre-isearch-mode-hook ()
+  (when (not (eq isearch-search-fun-function #'isearch-search-fun-default))
+    (message "Warning: pcre-mode overriding existing isearch function `%s'"
+             isearch-search-fun-function))
+  ;; Prevent an infinite loop, if a previous isearch in pcre-mode
+  ;; exited without restoring the original search function for some
+  ;; reason
+  (unless (eq isearch-search-fun-function #'pcre-isearch-search-fun-function)
+    (setq pcre-old-isearch-search-fun-function isearch-search-fun-function))
+  (set (make-local-variable 'isearch-search-fun-function)
+       #'pcre-isearch-search-fun-function))
+
+(defun pcre-isearch-mode-end-hook ()
+  (setq isearch-search-fun-function pcre-old-isearch-search-fun-function))
+
+(defun pcre-isearch-search-fun-function ()
+  "Enable isearching using emulated PCRE syntax.
+
+This is set as the value of `isearch-search-fun-function' when
+`pcre-mode' is enabled.  Returns a function which searches using
+emulated PCRE regexps when `isearch-regexp' is true."
+  (lambda (string bound noerror)
+    (let ((real-search-function
+           (funcall (or pcre-old-isearch-search-fun-function 'isearch-search-fun-default))))
+      (if (not isearch-regexp)
+          (funcall real-search-function string bound noerror)
+        ;; Raise an error if the regexp ends in an incomplete escape
+        ;; sequence (= odd number of backslashes).
+        ;; TODO: Perhaps this should really be handled in rxt-pcre-to-elisp?
+        (if (isearch-backslash string) (rxt-error "Trailing backslash"))
+        (funcall real-search-function
+                 (pcre-to-elisp/cached string) bound noerror)))))
+
+(defadvice isearch-message-prefix (after pcre-mode disable)
+  "Add \"PCRE\" to the Isearch message when searching by regexp in `pcre-mode'."
+  (when (and isearch-regexp
+             ;; Prevent an inaccurate message if our callback was
+             ;; removed somehow
+             (eq isearch-search-fun-function #'pcre-isearch-search-fun-function))
+    (let ((message ad-return-value))
+      ;; Some hackery to give replacement the same fontification as
+      ;; the original
+      (when
+          (let ((case-fold-search t)) (string-match "regexp" message))
+        (let* ((match (match-string 0 message))
+               (properties (text-properties-at 0 match))
+               (replacement (apply #'propertize "PCRE regexp" properties))
+               (new-message (replace-match replacement t t message)))
+          (setq ad-return-value new-message))))))
+
+(defadvice isearch-fallback
+  (before pcre-mode (want-backslash &optional allow-invalid to-barrier) disable)
+  "Hack to fall back correctly in `pcre-mode'. "
+  ;; A dirty hack to the internals of isearch.  Falling back to a
+  ;; previous match position is necessary when the (Emacs) regexp ends
+  ;; in "*", "?", "\{" or "\|": this is handled in
+  ;; `isearch-process-search-char' by calling `isearch-fallback' with
+  ;; `t' for the value of the first parameter, `want-backslash', in
+  ;; the last two cases.  With PCRE regexps, falling back should take
+  ;; place on "*", "?", "{" or "|", with no backslashes required.
+  ;; This advice handles the last two cases by unconditionally setting
+  ;; `want-backslash' to nil.
+  (ad-set-arg 0 nil))
+
+(defadvice isearch-edit-string
+    (around pcre-mode disable)
+  "Add PCRE mode-toggling keys to Isearch minibuffer in regexp mode."
+  (if isearch-regexp
+      (minibuffer-with-setup-hook
+          #'rxt--read-pcre-mode
+        ad-do-it)
+    ad-do-it))
+
+;;; evil-mode advice
+(defadvice evil-search-function
+    (around pcre-mode (forward regexp-p wrap) disable)
+  (if (and regexp-p (not isearch-mode))
+      (let ((real-search-function ad-do-it))
+        (setq ad-return-value
+              (pcre-decorate-search-function real-search-function)))
+    ad-do-it))
+
+(eval-after-load 'evil
+  '(when pcre-mode
+    (ad-enable-advice 'evil-search-function 'around 'pcre-mode)
+    (ad-activate 'evil-search-function)))
+
+(defun pcre-decorate-search-function (real-search-function)
+  (lambda (string &optional bound noerror count)
+    (funcall real-search-function
+             (pcre-to-elisp/cached string)
+             bound noerror count)))
+
+;;; Other hooks and defadvices
+
+;;;###autoload
+(defun pcre-query-replace-regexp ()
+  "Perform `query-replace-regexp' using PCRE syntax.
+
+Consider using `pcre-mode' instead of this function."
+  (interactive)
+  (let ((old-pcre-mode pcre-mode))
+    (unwind-protect
+        (progn
+          (pcre-mode +1)
+          (call-interactively #'query-replace-regexp))
+      (pcre-mode (if old-pcre-mode 1 0)))))
+
+
+(defadvice add-to-history
+  (before pcre-mode (history-var newelt &optional maxelt keep-all) disable)
+  "Add the original PCRE to query-replace history in `pcre-mode'."
+  (when (eq history-var query-replace-from-history-variable)
+    (let ((original (gethash newelt pcre-mode-reverse-cache)))
+      (when original
+        (ad-set-arg 1 original)))))
+
+(defadvice query-replace-descr
+  (before pcre-mode (from) disable)
+  "Use the original PCRE in Isearch prompts in `pcre-mode'."
+  (let ((original (gethash from pcre-mode-reverse-cache)))
+    (when original
+      (ad-set-arg 0 original))))
+
+;;; The `interactive' specs of the following functions are lifted
+;;; wholesale from the original built-ins, which see.
+(defadvice read-regexp
+  (around pcre-mode first (prompt &optional defaults history) disable)
+  "Read regexp using PCRE syntax and convert to Elisp equivalent."
+  (ad-set-arg 0 (concat "[PCRE] " prompt))
+  (minibuffer-with-setup-hook
+      #'rxt--read-pcre-mode
+    ad-do-it)
+  (setq ad-return-value
+        (pcre-to-elisp/cached ad-return-value)))
+
+(defadvice align-regexp
+  (before pcre-mode first (beg end regexp &optional group spacing repeat) disable)
+  "Read regexp using PCRE syntax and convert to Elisp equivalent."
+  (interactive
+   (append
+    (list (region-beginning) (region-end))
+    (if current-prefix-arg
+        (list (rxt-pcre-to-elisp
+               (read-string "Complex align using PCRE regexp: "
+                            "(\\s*)"))
+              (string-to-number
+               (read-string
+                "Parenthesis group to modify (justify if negative): " "1"))
+              (string-to-number
+               (read-string "Amount of spacing (or column if negative): "
+                            (number-to-string align-default-spacing)))
+              (y-or-n-p "Repeat throughout line? "))
+      (list (concat "\\(\\s-*\\)"
+                    (rxt-pcre-to-elisp
+                     (read-string "Align PCRE regexp: ")))
+            1 align-default-spacing nil)))))
+
+(defadvice ibuffer-do-replace-regexp
+  (before pcre-mode first (from-str to-str) disable)
+  "Read regexp using PCRE syntax and convert to Elisp equivalent."
+  (interactive
+   (let* ((from-str (read-from-minibuffer "[PCRE] Replace regexp: "))
+          (to-str (read-from-minibuffer (concat "[PCRE] Replace " from-str " with: "))))
+     (list (rxt-pcre-to-elisp from-str) to-str))))
+
+(defadvice find-tag-regexp
+  (before pcre-mode first (regexp &optional next-p other-window) disable)
+  "Read regexp using PCRE syntax and convert to Elisp equivalent.
+Perform `find-tag-regexp' using emulated PCRE regexp syntax."
+  (interactive
+   (let ((args (find-tag-interactive "[PCRE] Find tag regexp: " t)))
+     (list (rxt-pcre-to-elisp (nth 0 args))
+           (nth 1 args) (nth 2 args)))))
+
+(defadvice sort-regexp-fields
+  (before pcre-mode first (reverse record-regexp key-regexp beg end) disable)
+  "Read regexp using PCRE syntax and convert to Elisp equivalent."
+  (interactive "P\nsPCRE regexp specifying records to sort: \n\
+sPCRE regexp specifying key within record: \nr")
+  (ad-set-arg 1 (rxt-pcre-to-elisp (ad-get-arg 1)))
+  (ad-set-arg 2 (rxt-pcre-to-elisp (ad-get-arg 2))))
+
+
+
+;;; Commands that take Emacs-style regexps as input
+
+;;;###autoload
+(defun rxt-elisp-to-pcre (regexp)
+  "Translate REGEXP, a regexp in Emacs Lisp syntax, to Perl-compatible syntax.
+
+Interactively, reads the regexp in one of three ways. With a
+prefix arg, reads from minibuffer without string escaping, like
+`query-replace-regexp'. Without a prefix arg, uses the text of
+the region if it is active. Otherwise, uses the result of
+evaluating the sexp before point (which might be a string regexp
+literal or an expression that produces a string).
+
+Displays the translated PCRE regexp in the echo area and copies
+it to the kill ring.
+
+Emacs regexp features such as syntax classes which cannot be
+translated to PCRE will cause an error."
+  (interactive (rxt-interactive/elisp))
+  (rxt-return-pcre (rxt-adt->pcre (rxt-parse-elisp regexp))))
+
+;;;###autoload
+(defun rxt-elisp-to-rx (regexp)
+  "Translate REGEXP, a regexp in Emacs Lisp syntax, to `rx' syntax.
+
+See `rxt-elisp-to-pcre' for a description of the interactive
+behavior and `rx' for documentation of the S-expression based
+regexp syntax."
+  (interactive (rxt-interactive/elisp))
+  (rxt-return-sexp (rxt-adt->rx (rxt-parse-elisp regexp))))
+
+;;;###autoload
+(defun rxt-elisp-to-strings (regexp)
+  "Return a list of all strings matched by REGEXP, an Emacs Lisp regexp.
+
+See `rxt-elisp-to-pcre' for a description of the interactive behavior.
+
+This is useful primarily for getting back the original list of
+strings from a regexp generated by `regexp-opt', but it will work
+with any regexp without unbounded quantifiers (*, +, {2, } and so
+on).
+
+Throws an error if REGEXP contains any infinite quantifiers."
+  (interactive (rxt-interactive/elisp))
+  (rxt-return-sexp (rxt-adt->strings (rxt-parse-elisp regexp))))
+
+;;;###autoload
+(defun rxt-toggle-elisp-rx ()
+  "Toggle the regexp near point between Elisp string and rx syntax."
+  (interactive)
+  ;; First, position point before the regex form near point (either
+  ;; a string literal or a list beginning `rx' or `rx-to-string').
+  (let* ((context (syntax-ppss))
+         (string-start (nth 8 context)))
+    (cond (string-start (goto-char string-start))
+          ((looking-back "\"") (backward-sexp))
+          ((looking-at "\"") nil)
+          (t
+           ;; Search backwards, leaving point in place on error
+           (goto-char
+            (save-excursion
+              (skip-syntax-forward "-")
+              (while (not (looking-at
+                           (rx "(" (or "rx" "rx-to-string") symbol-end)))
+                (backward-up-list))
+              (point))))))
+
+  ;; Read and replace the regex following point
+  (let* ((regex (read (current-buffer)))
+         (print-escape-newlines t))
+    (save-excursion
+      (if (listp regex)
+          ;; Replace rx form with string value
+          (prin1 (eval regex) (current-buffer))
+        ;; Pretty-print rx form
+        (save-restriction
+          (let* ((start (point))
+                 (rx-syntax (rxt-elisp-to-rx regex))
+                 (rx-form
+                  (pcase rx-syntax
+                    (`(seq . ,rest) `(rx . ,rest))
+                    (form           `(rx ,form)))))
+            (rxt-print rx-form)
+            (narrow-to-region start (point)))
+          (pp-buffer)
+          ;; remove the extra newline that pp-buffer inserts
+          (goto-char (point-max))
+          (delete-region
+           (point)
+           (save-excursion (skip-chars-backward " \t\n") (point))))))
+    (kill-sexp -1)
+    (indent-pp-sexp)))
+
+
+
+;;; Commands that translate PCRE to other formats
+
+;;;###autoload
+(defun rxt-pcre-to-elisp (pcre &optional flags)
+  "Translate PCRE, a regexp in Perl-compatible syntax, to Emacs Lisp.
+
+Interactively, uses the contents of the region if it is active,
+otherwise reads from the minibuffer. Prints the Emacs translation
+in the echo area and copies it to the kill ring.
+
+PCRE regexp features that cannot be translated into Emacs syntax
+will cause an error. See the commentary section of pcre2el.el for
+more details."
+  (interactive (rxt-interactive/pcre))
+  (rxt-return-emacs-regexp
+   (rx-to-string
+    (rxt-pcre-to-rx (rxt--add-flags pcre flags))
+    t)))
+
+;;;###autoload
+(defalias 'pcre-to-elisp 'rxt-pcre-to-elisp)
+
+;;;###autoload
+(defun rxt-pcre-to-rx (pcre &optional flags)
+  "Translate PCRE, a regexp in Perl-compatible syntax, to `rx' syntax.
+
+See `rxt-pcre-to-elisp' for a description of the interactive behavior."
+  (interactive (rxt-interactive/pcre))
+  (rxt-return-sexp (rxt-adt->rx (rxt-parse-pcre (rxt--add-flags pcre flags)))))
+
+;;;###autoload
+(defun rxt-pcre-to-strings (pcre &optional flags)
+  "Return a list of all strings matched by PCRE, a Perl-compatible regexp.
+
+See `rxt-elisp-to-pcre' for a description of the interactive
+behavior and `rxt-elisp-to-strings' for why this might be useful.
+
+Throws an error if PCRE contains any infinite quantifiers."
+  (interactive (rxt-interactive/pcre))
+  (rxt-return-sexp (rxt-adt->strings (rxt-parse-pcre (rxt--add-flags pcre flags)))))
+
+(defun rxt--add-flags (pcre flags)
+  "Prepend FLAGS to PCRE."
+  (if (not (zerop (length flags)))
+      (concat "(?" flags ")" pcre)
+    pcre))
+
+
+;;; Regexp explaining functions to display pretty-printed rx syntax
+
+;; When the `rxt-explain' flag is non-nil, `rxt-adt->rx' records
+;; location information for each element of the generated `rx' form,
+;; allowing highlighting corresponding pieces of syntax at point.
+(defvar rxt-explain nil)
+
+(defvar rxt-highlight-overlays nil
+  "List of active location-highlighting overlays in rxt-help-mode buffer.")
+
+;;;###autoload
+(defun rxt-explain-elisp (regexp)
+  "Insert the pretty-printed `rx' syntax for REGEXP in a new buffer.
+
+REGEXP is a regular expression in Emacs Lisp syntax. See
+`rxt-elisp-to-pcre' for a description of how REGEXP is read
+interactively."
+  (interactive (rxt-interactive/elisp))
+  (let ((rxt-explain t)
+        (rxt-verbose-rx-translation rxt-explain-verbosely))
+    (rxt-pp-rx regexp (rxt-elisp-to-rx regexp))))
+
+;;;###autoload
+(defun rxt-explain-pcre (regexp &optional flags)
+  "Insert the pretty-printed `rx' syntax for REGEXP in a new buffer.
+
+REGEXP is a regular expression in PCRE syntax. See
+`rxt-pcre-to-elisp' for a description of how REGEXP is read
+interactively."
+  (interactive (rxt-interactive/pcre))
+  (let ((rxt-explain t)
+        (rxt-verbose-rx-translation rxt-explain-verbosely))
+    (rxt-pp-rx regexp (rxt-pcre-to-rx regexp flags))))
+
+;;;###autoload
+(defun rxt-quote-pcre (text)
+  "Return a PCRE regexp which matches TEXT literally.
+
+Any PCRE metacharacters in TEXT will be quoted with a backslash."
+  (rxt-adt->pcre (rxt-string text)))
+
+
+;;;; Commands that depend on the major mode in effect
+
+;; Macro: interactively call one of two functions depending on the
+;; major mode
+(defmacro rxt-mode-dispatch (elisp-function pcre-function)
+  `(if (memq major-mode '(emacs-lisp-mode lisp-interaction-mode))
+       (call-interactively #',elisp-function)
+     (call-interactively #',pcre-function)))
+
+;;;###autoload
+(defun rxt-explain ()
+  "Pop up a buffer with pretty-printed `rx' syntax for the regex at point.
+
+Chooses regex syntax to read based on current major mode, calling
+`rxt-explain-elisp' if buffer is in `emacs-lisp-mode' or
+`lisp-interaction-mode', or `rxt-explain-pcre' otherwise."
+  (interactive)
+  (rxt-mode-dispatch rxt-explain-elisp rxt-explain-pcre))
+
+;;;###autoload
+(defun rxt-convert-syntax ()
+  "Convert regex at point to other kind of syntax, depending on major mode.
+
+For buffers in `emacs-lisp-mode' or `lisp-interaction-mode',
+calls `rxt-elisp-to-pcre' to convert to PCRE syntax. Otherwise,
+calls `rxt-pcre-to-elisp' to convert to Emacs syntax.
+
+The converted syntax is displayed in the echo area and copied to
+the kill ring; see the two functions named above for details."
+  (interactive)
+  (rxt-mode-dispatch rxt-elisp-to-pcre rxt-pcre-to-elisp))
+
+;;;###autoload
+(defun rxt-convert-to-rx ()
+  "Convert regex at point to RX syntax. Chooses Emacs or PCRE syntax by major mode."
+  (interactive)
+  (rxt-mode-dispatch rxt-elisp-to-rx rxt-pcre-to-rx))
+
+;;;###autoload
+(defun rxt-convert-to-strings ()
+  "Convert regex at point to RX syntax. Chooses Emacs or PCRE syntax by major mode."
+  (interactive)
+  (rxt-mode-dispatch rxt-elisp-to-strings rxt-pcre-to-strings))
+
+
+
+;;; Minor mode and keybindings
+
+(defvar rxt-mode-map
+  (let ((map (make-sparse-keymap)))
+    ;; Generic
+    (define-key map (kbd "C-c / /") 'rxt-explain)
+    (define-key map (kbd "C-c / c") 'rxt-convert-syntax)
+    (define-key map (kbd "C-c / x") 'rxt-convert-to-rx)
+    (define-key map (kbd "C-c / '") 'rxt-convert-to-strings)
+
+    ;; From PCRE
+    (define-key map (kbd "C-c / p /") 'rxt-explain-pcre)
+    (define-key map (kbd "C-c / p e") 'rxt-pcre-to-elisp)
+    (define-key map (kbd "C-c / p x") 'rxt-pcre-to-rx)
+    (define-key map (kbd "C-c / p '") 'rxt-pcre-to-strings)
+
+    ;; From Elisp
+    (define-key map (kbd "C-c / e /") 'rxt-explain-elisp)
+    (define-key map (kbd "C-c / e p") 'rxt-elisp-to-pcre)
+    (define-key map (kbd "C-c / e x") 'rxt-elisp-to-rx)
+    (define-key map (kbd "C-c / e '") 'rxt-elisp-to-strings)
+    (define-key map (kbd "C-c / e t") 'rxt-toggle-elisp-rx)
+    (define-key map (kbd "C-c / t") 'rxt-toggle-elisp-rx)
+    
+    ;; Search
+    (define-key map (kbd "C-c / %") 'pcre-query-replace-regexp)
+
+    map)
+  "Keymap for `rxt-mode'.")
+
+;;;###autoload
+(define-minor-mode rxt-mode
+  "Regex translation utilities." nil nil)
+
+;;;###autoload
+(defun turn-on-rxt-mode ()
+  "Turn on `rxt-mode' in the current buffer."
+  (interactive)
+  (rxt-mode 1))
+
+;;;###autoload
+(define-globalized-minor-mode rxt-global-mode rxt-mode
+  turn-on-rxt-mode)
+
+
+;;;; Syntax explanations
+
+;; Major mode for displaying pretty-printed S-exp syntax
+(define-derived-mode rxt-help-mode emacs-lisp-mode "Regexp Explain"
+  (setq buffer-read-only t)
+  (add-hook 'post-command-hook 'rxt-highlight-text nil t)
+  (rxt-highlight-text))
+
+;; Hack: stop paredit-mode interfering with `rxt-print'
+(eval-when-compile (declare-function paredit-mode "paredit.el"))
+(add-hook 'rxt-help-mode-hook
+          (lambda ()
+            (if (and (boundp 'paredit-mode)
+                     paredit-mode)
+                (paredit-mode 0))))
+
+(define-key rxt-help-mode-map "q" 'quit-window)
+(define-key rxt-help-mode-map "z" 'kill-this-buffer)
+(define-key rxt-help-mode-map "n" 'next-line)
+(define-key rxt-help-mode-map "p" 'previous-line)
+(define-key rxt-help-mode-map "f" 'forward-list)
+(define-key rxt-help-mode-map "b" 'backward-list)
+(define-key rxt-help-mode-map "u" 'backward-up-list)
+(define-key rxt-help-mode-map "d" 'down-list)
+
+(defvar rxt--print-with-overlays nil)
+(defvar rxt--print-depth 0)
+
+(defconst rxt--print-char-alist
+  '((?\a . "\\a")
+    (?\b . "\\b")
+    (?\t . "\\t")
+    (?\n . "\\n")
+    (?\v . "\\v")
+    (?\f . "\\f")
+    (?\r . "\\r")
+    (?\e . "\\e")
+    (?\s . "\\s")
+    (?\\ . "\\\\")
+    (?\d . "\\d"))
+  "Alist of characters to print using an escape sequence in Elisp source.
+See (info \"(elisp) Basic Char Syntax\").")
+
+(defconst rxt--whitespace-display-regexp
+  (rx-to-string `(any ,@(mapcar #'car rxt--print-char-alist))))
+
+(defconst rxt--print-special-chars
+  '(?\( ?\) ?\\ ?\| ?\; ?\' ?\` ?\" ?\# ?\. ?\,)
+  "Characters which require a preceding backslash in Elisp source.
+See (info \"(elisp) Basic Char Syntax\").")
+
+(defun rxt-pp-rx (regexp rx)
+  "Display string regexp REGEXP with its `rx' form RX in an `rxt-help-mode' buffer."
+  (with-current-buffer (get-buffer-create "* Regexp Explain *")
+    (let ((print-escape-newlines t)
+          (inhibit-read-only t))
+      (erase-buffer)
+      (rxt-help-mode)
+      (insert (rxt--propertize-whitespace regexp))
+      (newline 2)
+      (save-excursion
+        (let ((sexp-begin (point))
+              (rxt--print-with-overlays t))
+          (rxt-print rx)
+          (narrow-to-region sexp-begin (point))
+          (pp-buffer)
+          (widen)))
+      (rxt-highlight-text))
+    (pop-to-buffer (current-buffer))))
+
+(cl-defun rxt-print (rx)
+  "Insert RX, an `rx' form, into the current buffer, optionally adding overlays.
+
+Similar to `print' or `prin1', but ensures that `rx' forms are
+printed readably, using character or integer syntax depending on
+context.
+
+If `rxt--print-with-overlays' is non-nil, also creates overlays linking
+elements of RX to their corresponding locations in the source
+string (see `rxt-explain-elisp', `rxt-explain-pcre' and
+`rxt--make-help-overlays')."
+  (let ((start (point)))
+    (cl-typecase rx
+      (cons
+       (pcase rx
+         (`(,(and (or `repeat `**) head)
+             ,(and (pred integerp) from)
+             ,(and (pred integerp) to)
+             . ,rest)
+           (insert (format "(%s %d %d" head from to))
+           (rxt--print-list-tail rest))
+         (`(,(and (or `repeat `= `>=) head)
+             ,(and (pred integerp) n)
+             . ,rest)
+           (insert (format "(%s %d" head n))
+           (rxt--print-list-tail rest))
+         (_
+          (rxt--print-list-tail rx t))))
+      (symbol
+       (cl-case rx
+         ;; `print' escapes the ? characters in the rx operators *?
+         ;; and +?, but this looks bad and is not strictly necessary:
+         ;; (eq (read "*?") (read "*\\?"))     => t
+         ;; (eq (read "+?") (read "+\\?"))     => t
+         ((*? +?) (insert (symbol-name rx)))
+         (t (prin1 rx (current-buffer)))))
+      (string
+       (insert (rxt--propertize-whitespace (prin1-to-string rx))))
+      (character
+       (cond
+         ((eq ?  rx)
+          (insert "?"))
+         ((memq rx rxt--print-special-chars)
+          (insert "?\\" rx))
+         ((assq rx rxt--print-char-alist)
+          (insert "?" (assoc-default rx rxt--print-char-alist)))
+         (t
+          (insert "?" (char-to-string rx)))))
+      (t
+       (prin1 rx (current-buffer))))
+    (when rxt--print-with-overlays
+      (rxt--make-help-overlays rx start (point)))))
+
+(defun rxt--print-list-tail (tail &optional open-paren)
+  (let ((rxt--print-depth (1+ rxt--print-depth)))
+    (let ((done nil))
+      (while (not done)
+        (cl-typecase tail
+          (null
+           (insert ")")
+           (setq done t))
+          (cons
+           (if open-paren
+               (progn
+                 (insert "(")
+                 (setq open-paren nil))
+             (insert " "))
+           (rxt-print (car tail))
+           (setq tail (cdr tail)))
+          (t
+           (insert " . ")
+           (rxt-print tail)
+           (insert ")")
+           (setq done t)))))))
+
+(defun rxt--make-help-overlays (rx start end)
+  (let ((location (rxt-location rx)))
+    (when (and location
+               (rxt-location-start location)
+               (rxt-location-end location))
+      (let* ((sexp-begin (copy-marker start t))
+             (sexp-end (copy-marker end))
+             (sexp-bounds (list sexp-begin sexp-end))
+
+             (source-begin (1+ (rxt-location-start location)))
+             (source-end   (1+ (rxt-location-end   location)))
+             (source-bounds (list source-begin source-end))
+
+             (bounds (list source-bounds sexp-bounds))
+
+             (sexp-ol (make-overlay sexp-begin sexp-end (current-buffer) t nil))
+             (source-ol (make-overlay source-begin source-end (current-buffer) t nil)))
+        (dolist (ol (list sexp-ol source-ol))
+          (overlay-put ol 'priority rxt--print-depth)
+          (overlay-put ol 'rxt-bounds bounds))))))
+
+(defun rxt--propertize-whitespace (string)
+  (let ((string (copy-sequence string))
+        (start 0))
+    (while (string-match rxt--whitespace-display-regexp string start)
+      (put-text-property (match-beginning 0) (match-end 0)
+                         'display
+                         (assoc-default (string-to-char (match-string 0 string))
+                                        rxt--print-char-alist)
+                         string)
+      (setq start (match-end 0)))
+    string))
+
+(defun rxt-highlight-text ()
+  "Highlight the regex syntax at point and its corresponding RX/string form."
+  (let ((all-bounds (get-char-property (point) 'rxt-bounds)))
+    (mapc #'delete-overlay rxt-highlight-overlays)
+    (setq rxt-highlight-overlays nil)
+    (dolist (bounds all-bounds)
+      (cl-destructuring-bind (begin end) bounds
+        (let ((overlay (make-overlay begin end)))
+          (push overlay rxt-highlight-overlays)
+          (overlay-put overlay 'face 'rxt-highlight-face))))))
+
+
+;;;; Error handling
+
+(if (fboundp 'define-error)
+    (define-error 'rxt-invalid-regexp "Invalid regexp" 'invalid-regexp)
+  (put 'rxt-invalid-regexp
+         'error-conditions
+         '(rxt-invalid-regexp invalid-regexp error))
+  (put 'rxt-invalid-regexp 'error-message "Invalid regexp"))
+
+(defun rxt-error (&rest format-args)
+  (signal 'rxt-invalid-regexp (list (apply #'format format-args))))
+
+
+;;;; Regexp syntax tree data type
+
+;; Base class from which other elements of the syntax-tree inherit
+(cl-defstruct rxt-syntax-tree)
+
+;; Struct representing the original source location
+(cl-defstruct rxt-location
+  source                                ; Either a string or a buffer
+  start end                             ; Offsets, 0- or 1-indexed as appropriate
+  )
+
+(defun rxt-location-text (location)
+  (if (not (rxt-location-p location))
+      nil
+    (let ((start  (rxt-location-start  location))
+          (end    (rxt-location-end    location))
+          (source (rxt-location-source location)))
+      (cond
+        ((buffer-live-p source)
+         (with-current-buffer source
+           (buffer-substring-no-properties start end)))
+        ((stringp source)
+         (substring source start end))
+        (t nil)))))
+
+;; Hash table mapping from syntax-tree elements to source locations.
+(defvar rxt-location-map (make-hash-table :weakness 'key))
+
+(defun rxt-location (object)
+  (gethash object rxt-location-map))
+
+(gv-define-setter rxt-location (value object)
+  `(puthash ,object ,value rxt-location-map))
+
+(defun rxt-source-text (object)
+  (rxt-location-text (rxt-location object)))
+
+(defun rxt-to-string (tree)
+  "Return a readable representation of TREE, a regex syntax-tree object."
+  (or (rxt-source-text tree)
+      (let ((print-level 1))
+        (prin1-to-string tree))))
+(defalias 'rxt-syntax-tree-readable 'rxt-to-string)
+
+;; FIXME
+(defvar rxt-pcre-case-fold nil)
+
+;; Literal string
+(cl-defstruct
+    (rxt-string
+      (:constructor rxt-string (chars &optional case-fold))
+      (:include rxt-syntax-tree))
+  chars
+  (case-fold rxt-pcre-case-fold))
+
+(defun rxt-empty-string ()
+  (rxt-string ""))
+
+(defun rxt-trivial-p (re)
+  (and (rxt-string-p re)
+       (equal (rxt-string-chars re) "")))
+
+;;; Other primitives
+(cl-defstruct (rxt-primitive
+               (:constructor rxt-primitive (pcre rx))
+               (:include rxt-syntax-tree))
+  pcre rx)
+
+(defun rxt-bos () (rxt-primitive "\\A" 'bos))
+(defun rxt-eos () (rxt-primitive "\\Z" 'eos))
+
+(defun rxt-bol () (rxt-primitive "^" 'bol))
+(defun rxt-eol () (rxt-primitive "$" 'eol))
+
+;; FIXME
+(defun rxt-anything () (rxt-primitive "." 'anything))
+(defun rxt-nonl () (rxt-primitive "." 'nonl))
+
+(defun rxt-word-boundary () (rxt-primitive "\\b" 'word-boundary))
+(defun rxt-not-word-boundary () (rxt-primitive "\\B" 'not-word-boundary))
+
+(defun rxt-wordchar () (rxt-primitive "\\w" 'wordchar))
+(defun rxt-not-wordchar () (rxt-primitive "\\W" 'not-wordchar))
+
+(defun rxt-symbol-start () (rxt-primitive nil 'symbol-start))
+(defun rxt-symbol-end () (rxt-primitive nil 'symbol-end))
+
+(defun rxt-bow () (rxt-primitive nil 'bow))
+(defun rxt-eow () (rxt-primitive nil 'eow))
+
+;;; Sequence
+(cl-defstruct
+    (rxt-seq
+     (:constructor make-rxt-seq (elts))
+     (:include rxt-syntax-tree))
+  elts)
+
+;; Slightly smart sequence constructor:
+;; - Flattens nested sequences
+;; - Drops trivial "" elements
+;; - Empty sequence => ""
+;; - Singleton sequence is reduced to its one element.
+(defun rxt-seq (&rest res)        ; Flatten nested seqs & drop ""'s.
+  (let ((res (rxt-seq-flatten res)))
+    (if (consp res)
+        (if (consp (cdr res))
+            (make-rxt-seq res) ; General case
+          (car res))           ; Singleton sequence
+      (rxt-empty-string))))      ; Empty seq -- ""
+
+(defun rxt-seq-flatten (res)
+  (if (consp res)
+      (let ((re (car res))
+            (tail (rxt-seq-flatten (cdr res))))
+        (cond ((rxt-seq-p re)           ; Flatten nested seqs
+               (append (rxt-seq-flatten (rxt-seq-elts re)) tail))
+              ((rxt-trivial-p re) tail) ; Drop trivial elts
+              ((and (rxt-string-p re)   ; Flatten strings
+                    (consp tail)
+                    (rxt-string-p (car tail)))
+               (cons
+                (rxt-string-concat re (car tail))
+                (cdr tail)))
+              (t (cons re tail))))
+    '()))
+
+(defun rxt-string-concat (str1 str2)
+  (if (not (eq (rxt-string-case-fold str1)
+               (rxt-string-case-fold str2)))
+      (make-rxt-seq (list str1 str2))
+    (let ((result
+           (rxt-string (concat (rxt-string-chars str1)
+                               (rxt-string-chars str2))
+                       (rxt-string-case-fold str1)))
+          (first (rxt-location str1))
+          (last  (rxt-location str2)))
+      (when (and first last)
+        (setf (rxt-location result)
+              (make-rxt-location :source (rxt-location-source first)
+                                 :start  (rxt-location-start first)
+                                 :end    (rxt-location-end last))))
+      result)))
+
+;;; Choice (alternation/union)
+(cl-defstruct
+    (rxt-choice
+     (:constructor make-rxt-choice (elts))
+     (:include rxt-syntax-tree))
+  elts)
+
+;;; The empty choice represents a regexp that never matches in any context
+(defvar rxt-empty (make-rxt-choice nil))
+(defun rxt-empty-p (re)
+  (or
+   (and (rxt-choice-p re)
+        (null (rxt-choice-elts re)))
+   (rxt-empty-char-set-p re)))
+
+(defun rxt-choice (&rest alternatives)
+  "Construct the alternation (union) of several regexps.
+
+ALTERNATIVES should be a list of `rxt-syntax-tree' objects.
+The return value is an `rxt-choice' object representing a regexp
+which matches any one of ALTERNATIVES, but simplified in the
+following ways:
+
+- If ALTERNATIVES contains only one element, it is returned unchanged.
+
+- All existing `rxt-choice' elements in ALTERNATIVES are replaced
+  by a flat list of their subexpressions: symbolically,
+  a|(b|(c|d)) is replaced by a|b|c|d
+
+- All character sets and single-character strings in ALTERNATIVES
+  are combined together into one or two character sets,
+  respecting case-folding behaviour."
+  (cl-destructuring-bind (other-elements char-set case-fold-char-set)
+      (rxt--simplify-alternatives alternatives)
+    (let ((simplified-alternatives
+           (append (if (not (rxt-empty-p char-set))
+                       (list char-set)
+                     '())
+                   (if (not (rxt-empty-p case-fold-char-set))
+                       (list case-fold-char-set)
+                     '())
+                   other-elements)))
+      (pcase simplified-alternatives
+        (`()
+          rxt-empty)
+        (`(,element)
+          element)
+        (_
+         (make-rxt-choice simplified-alternatives))))))
+
+(defun rxt--simplify-alternatives (alternatives)
+  "Simplify a set of regexp alternatives.
+
+ALTERNATIVES should be a list of `rxt-syntax-tree' objects to be combined
+into an `rxt-choice' structure.  The result is a three-element
+list (OTHER-ELEMENTS CHAR-SET CASE-FOLDED-CHAR-SET):
+
+- CHAR-SET is an `rxt-char-set-union' containing the union of all
+  case-sensitive character sets and single-character strings in
+  RES.
+
+- CASE-FOLDED-CHAR-SET is similar but combines all the
+  case-insensitive character sets and single-character strings.
+
+- OTHER-ELEMENTS is a list of all other elements, with all
+  `rxt-choice' structures replaced by a flat list of their
+  component subexpressions."
+  (if (null alternatives)
+      (list '()
+            (make-rxt-char-set-union :case-fold nil)
+            (make-rxt-char-set-union :case-fold t))
+    (let* ((re (car alternatives)))
+      (cl-destructuring-bind (tail char-set case-fold-char-set)
+          (rxt--simplify-alternatives (cdr alternatives))
+        (cond ((rxt-choice-p re)         ; Flatten nested choices
+               (list
+                (append (rxt-choice-elts re) tail)
+                char-set
+                case-fold-char-set))
+
+              ((rxt-empty-p re)          ; Drop empty re's.
+               (list tail char-set case-fold-char-set))
+
+              ((rxt-char-set-union-p re) ; Fold char sets together
+               (if (rxt-char-set-union-case-fold re)
+                   (list tail
+                         char-set
+                         (rxt-char-set-union case-fold-char-set re))
+                 (list tail
+                       (rxt-char-set-union char-set re)
+                       case-fold-char-set)))
+
+              ((and (rxt-string-p re)    ; Same for 1-char strings
+                    (= 1 (length (rxt-string-chars re))))
+               (if (rxt-string-case-fold re)
+                   (list tail
+                         char-set
+                         (rxt-char-set-union case-fold-char-set re))
+                 (list tail
+                       (rxt-char-set-union char-set re)
+                       case-fold-char-set)))
+
+              (t                         ; Otherwise.
+               (list (cons re tail) char-set case-fold-char-set)))))))
+
+;;; Repetition
+(cl-defstruct (rxt-repeat
+               (:include rxt-syntax-tree))
+  from to body greedy)
+
+(cl-defun rxt-repeat (from to body &optional (greedy t))
+  (if (equal to 0)
+      (rxt-empty-string)
+    (make-rxt-repeat :from from :to to
+                     :body body :greedy greedy)))
+
+;;; Submatch
+(cl-defstruct
+    (rxt-submatch
+     (:constructor rxt-submatch (body))
+     (:include rxt-syntax-tree))
+  body)
+
+;;; Numbered submatch (Emacs only)
+(cl-defstruct
+    (rxt-submatch-numbered
+     (:constructor rxt-submatch-numbered (n body))
+     (:include rxt-syntax-tree))
+  n
+  body)
+
+;;; Backreference
+(cl-defstruct
+    (rxt-backref
+     (:constructor rxt-backref (n))
+     (:include rxt-syntax-tree))
+  n)
+
+;;; Syntax classes (Emacs only)
+(cl-defstruct (rxt-syntax-class
+               (:include rxt-syntax-tree))
+  symbol)
+
+(defun rxt-syntax-class (symbol)
+  (if (assoc symbol rx-syntax)
+      (make-rxt-syntax-class :symbol symbol)
+    (rxt-error "Invalid syntax class symbol `%s'" symbol)))
+
+;;; Character categories (Emacs only)
+(cl-defstruct (rxt-char-category
+               (:include rxt-syntax-tree))
+  symbol)
+
+(defun rxt-char-category (symbol)
+  (if (assoc symbol rx-categories)
+      (make-rxt-char-category :symbol symbol)
+    (rxt-error "Invalid character category symbol `%s'" symbol)))
+
+
+;;; Char sets
+;; <rxt-char-set> ::= <rxt-char-set-union>
+;;                  | <rxt-char-set-negation>
+;;                  | <rxt-char-set-intersection>
+
+(cl-defstruct (rxt-char-set (:include rxt-syntax-tree)))
+
+;; An rxt-char-set-union represents the union of any number of
+;; characters, character ranges, and POSIX character classes: anything
+;; that can be represented in string notation as a class [ ... ]
+;; without the negation operator.
+(cl-defstruct (rxt-char-set-union
+                (:include rxt-char-set))
+  chars    ; list of single characters
+  ranges   ; list of ranges (from . to)
+  classes  ; list of character classes
+  (case-fold rxt-pcre-case-fold))
+
+;; Test for empty character set
+(defun rxt-empty-char-set-p (cset)
+  (and (rxt-char-set-union-p cset)
+       (null (rxt-char-set-union-chars cset))
+       (null (rxt-char-set-union-ranges cset))
+       (null (rxt-char-set-union-classes cset))))
+
+;; Simple union constructor
+(defun rxt-char-set-union (&rest items)
+  "Construct an regexp character set representing the union of ITEMS.
+
+Each element of ITEMS may be either: a character; a
+single-character string; a single-character `rxt-string' object;
+a cons, (FROM . TO) representing a range of characters; a symbol,
+representing a named character class; or an `rxt-char-set-union'
+object.  All `rxt-char-set-union' objects in ITEMS must have the
+same `case-fold' property."
+  (let ((chars '())
+        (ranges '())
+        (classes '())
+        (case-fold 'undetermined))
+    (dolist (item items)
+      (cl-etypecase item
+        (character
+         (push item chars))
+
+        (string
+         (cl-assert (= 1 (length item)))
+         (push (string-to-char item) chars))
+
+        (rxt-string
+         (cl-assert (= 1 (length (rxt-string-chars item))))
+         (push (string-to-char (rxt-string-chars item)) chars))
+
+        (cons                           ; range (from . to)
+         (cl-check-type (car item) character)
+         (cl-check-type (cdr item) character)
+         (push item ranges))
+
+        (symbol                         ; named character class
+         (push item classes))
+
+        (rxt-char-set-union
+         (if (eq case-fold 'undetermined)
+             (setq case-fold (rxt-char-set-union-case-fold item))
+           (unless (eq case-fold (rxt-char-set-union-case-fold item))
+             (error "Cannot construct union of char-sets with unlike case-fold setting: %S" item)))
+         (setq chars (nconc chars (rxt-char-set-union-chars item)))
+         (setq ranges (nconc ranges (rxt-char-set-union-ranges item)))
+         (setq classes (nconc classes (rxt-char-set-union-classes item))))))
+
+    (make-rxt-char-set-union :chars chars :ranges ranges :classes classes
+                             :case-fold (if (eq case-fold 'undetermined)
+                                            rxt-pcre-case-fold
+                                          case-fold))))
+
+(defun rxt--all-char-set-union-chars (char-set)
+  "Return a list of all characters in CHAR-SET."
+  (cl-assert (rxt-char-set-union-p char-set))
+  (append
+   (rxt-char-set-union-chars char-set)
+   (cl-loop for (start . end) in (rxt-char-set-union-ranges char-set)
+            nconc (cl-loop for char from start to end collect char))))
+
+(defun rxt--simplify-char-set (char-set &optional case-fold-p)
+  "Return a minimal char-set to match the same characters as CHAR-SET.
+
+With optional argument CASE-FOLD-P, return a char-set which
+emulates case-folding behaviour by including both uppercase and
+lowercase versions of all characters in CHAR-SET."
+  (cl-assert (rxt-char-set-union-p char-set))
+  (let* ((classes (rxt-char-set-union-classes char-set))
+         (all-chars
+          (if case-fold-p
+              (cl-loop for char in (rxt--all-char-set-union-chars char-set)
+                       nconc (list (upcase char) (downcase char)))
+            (rxt--all-char-set-union-chars char-set)))
+         (all-ranges
+          (rxt--extract-ranges (rxt--remove-redundant-chars all-chars classes))))
+    (let ((singletons nil)
+          (ranges nil))
+      (cl-loop for (start . end) in all-ranges
+               do
+               (cond ((= start end) (push start singletons))
+                     ((= (1+ start) end)
+                      (push start singletons)
+                      (push end singletons))
+                     (t (push (cons start end) ranges))))
+      (make-rxt-char-set-union :chars (nreverse singletons)
+                               :ranges (nreverse ranges)
+                               :classes classes
+                               :case-fold (if case-fold-p
+                                              nil
+                                            (rxt-char-set-union-case-fold char-set))))))
+
+(defun rxt--remove-redundant-chars (chars classes)
+  "Remove all characters which match a character class in CLASSES from CHARS."
+  (if (null classes)
+      chars
+    (string-to-list
+     (replace-regexp-in-string
+      (rx-to-string `(any ,@classes))
+      ""
+      (apply #'string chars)))))
+
+(defun rxt--extract-ranges (chars)
+  "Return a list of all contiguous ranges in CHARS.
+
+CHARS should be a list of characters (integers).  The return
+value is a list of conses (START . END) representing ranges, such
+that the union of all the ranges represents the same of
+characters as CHARS.
+
+Example:
+    (rxt--extract-ranges (list ?a ?b ?c ?q ?x ?y ?z))
+        => ((?a . ?c) (?q . ?q) (?x . ?z))"
+  (let ((array
+         (apply #'vector
+                (cl-remove-duplicates
+                 (sort (copy-sequence chars) #'<)))))
+    (cl-labels
+        ((recur (start end)
+           (if (< end start)
+               nil
+             (let ((min (aref array start))
+                   (max (aref array end)))
+               (if (= (- max min) (- end start))
+                   (list (cons min max))
+                 (let* ((split-point (/ (+ start end) 2))
+                        (left (recur start split-point))
+                        (right (recur (1+ split-point) end)))
+                   (merge left right))))))
+         (merge (left right)
+           (cond ((null left) right)
+                 ((null right) left)
+                 (t
+                  (let ((last-left (car (last left)))
+                        (first-right (car right)))
+                    (if (= (1+ (cdr last-left))
+                           (car first-right))
+                        (append (cl-subseq left 0 -1)
+                                (list
+                                 (cons (car last-left)
+                                       (cdr first-right)))
+                                (cl-subseq right 1))
+                      (append left right)))))))
+      (recur 0 (1- (length array))))))
+
+;;; Set complement of character set, syntax class, or character
+;;; category
+
+;; In general, all character sets that can be represented in string
+;; notation as [^ ... ] (but see `rxt-char-set-intersection', below), plus
+;; Emacs' \Sx and \Cx constructions.
+(cl-defstruct (rxt-char-set-negation
+               (:include rxt-char-set))
+  elt)
+
+(defun rxt-negate (char-set)
+  "Construct the logical complement (negation) of CHAR-SET.
+
+CHAR-SET may be any of the following types: `rxt-char-set-union',
+`rxt-syntax-class', `rxt-char-category', or `rxt-char-set-negation'."
+  (cl-etypecase char-set
+    ((or rxt-char-set-union rxt-syntax-class rxt-char-category)
+     (make-rxt-char-set-negation :elt char-set))
+
+    (rxt-char-set-negation
+     (rxt-char-set-negation-elt char-set))))
+
+;;; Intersections of char sets
+
+;; These are difficult to represent in general, but can be constructed
+;; in Perl using double negation; for example: [^\Wabc] means the set
+;; complement of [abc] with respect to the universe of "word
+;; characters": (& (~ (~ word)) (~ ("abc"))) == (& word (~ ("abc")))
+;; == (- word ("abc"))
+
+(cl-defstruct (rxt-char-set-intersection
+               (:include rxt-char-set))
+  elts)
+
+;; Intersection constructor
+(defun rxt-char-set-intersection (&rest charsets)
+  (let ((elts '())
+        (cmpl (make-rxt-char-set-union)))
+    (dolist (cset (rxt-int-flatten charsets))
+      (cond
+       ((rxt-char-set-negation-p cset)
+        ;; Fold negated charsets together: ~A & ~B = ~(A|B)
+        (setq cmpl (rxt-char-set-union cmpl (rxt-char-set-negation-elt cset))))
+
+       ((rxt-char-set-union-p cset)
+        (push cset elts))
+
+       (t
+        (rxt-error "Can't take intersection of non-character-set %S" cset))))
+
+    (if (null elts)
+        (rxt-negate cmpl)
+      (unless (rxt-empty-char-set-p cmpl)
+        (push (rxt-negate cmpl) elts))
+      (if (null (cdr elts))
+          (car elts)      ; singleton case
+        (make-rxt-char-set-intersection :elts elts)))))
+
+;; Constructor helper: flatten nested intersections
+(defun rxt-int-flatten (csets)
+  (if (consp csets)
+      (let ((cset (car csets))
+            (tail (rxt-int-flatten (cdr csets))))
+        (if (rxt-char-set-intersection-p cset)
+            (append (rxt-int-flatten (rxt-char-set-intersection-elts cset)) tail)
+          (cons cset tail)))
+    '()))
+
+
+
+;;;; Macros for building the parser
+
+(defmacro rxt-token-case (&rest cases)
+  "Consume a token at point and evaluate corresponding forms.
+
+CASES is a list of `cond'-like clauses, (REGEXP BODY ...) where
+the REGEXPs define possible tokens which may appear at point. The
+CASES are considered in order. For each case, if the text at
+point matches REGEXP, then point is moved to the end of the
+matched token, the corresponding BODY is evaluated and their
+value returned. The matched token is available within the BODY
+forms as (match-string 0).
+
+There can be a default case where REGEXP is `t', which evaluates
+the corresponding FORMS but does not move point.
+
+Returns `nil' if none of the CASES matches."
+  (declare (debug (&rest (sexp &rest form))))
+  `(cond
+     ,@(cl-loop for (token . action) in cases
+                collect
+                (if (eq token t)
+                    `(t ,@action)
+                  `((looking-at ,token)
+                    (goto-char (match-end 0))
+                    ,@action)))))
+
+(defmacro rxt-with-source-location (&rest body)
+  "Evaluate BODY and record source location information on its value. 
+
+BODY may evaluate to any kind of object, but its value should
+generally not be `eq' to any other object."
+  (declare (debug (&rest form)))
+  (let ((begin (make-symbol "begin"))
+        (value (make-symbol "value")))
+    `(let ((,begin (point))
+           (,value ,(macroexp-progn body)))
+       (setf (rxt-location ,value)
+             (make-rxt-location :source rxt-source-text-string
+                                :start  (1- ,begin)
+                                :end    (1- (point))))
+       ,value)))
+
+;; Read PCRE + flags
+(defun rxt-read-delimited-pcre ()
+  "Read a Perl-style delimited regexp and flags from the current buffer.
+
+Point should be before the regexp literal before calling
+this. Currently only regexps delimited by / ... / are supported.
+A preceding \"m\", \"qr\" or \"s\" will be ignored, as will the
+replacement string in an s/.../.../ construction.
+
+Returns two strings: the regexp and the flags."
+  (save-excursion
+    (skip-syntax-forward "-")
+
+    ;; Skip m, qr, s
+    (let ((is-subst (rxt-token-case
+                     ("s" t)
+                     ((rx (or "m" "qr")) nil))))
+
+      (when (not (looking-at "/"))
+        (error "Only Perl regexps delimited by slashes are supported"))
+      (let ((beg (match-end 0))
+            (delim (rx (not (any "\\"))
+                       (group "/"))))
+        (search-forward-regexp delim)
+        (let ((end (match-beginning 1)))
+          (when is-subst (search-forward-regexp delim))
+          (let ((pcre (buffer-substring-no-properties beg end)))
+            (rxt-token-case
+             ("[gimosx]*"
+              (rxt--add-flags pcre (match-string-no-properties 0))))))))))
+
+
+;;;; Elisp and PCRE string notation parser
+
+;;; Parser constants
+(defconst rxt-pcre-char-set-alist
+  `((?w .                               ; "word" characters
+        (?_ alnum))
+    (?d .                               ; digits
+        (digit))
+    (?h .                               ; horizontal whitespace
+        (#x0009 #x0020 #x00A0 #x1680 #x180E #x2000 #x2001 #x2002 #x2003
+                #x2004 #x2005 #x2006 #x2007 #x2008 #x2009 #x200A #x202F
+                #x205F #x3000))
+    (?s .                               ; whitespace
+        (9 10 12 13 32))
+    (?v .                               ; vertical whitespace
+        (#x000A #x000B #x000C #x000D #x0085 #x2028 #x2029))))
+
+(defconst rxt-pcre-named-classes-regexp
+  (rx "[:"
+      (submatch
+       (or "alnum" "alpha" "ascii" "blank" "cntrl" "digit" "graph" "lower"
+           "print" "punct" "space" "upper" "word" "xdigit"))
+      ":]"))
+
+(defconst rxt-elisp-named-classes-regexp
+  (rx "[:"
+      (submatch
+       (or "alnum" "alpha" "ascii" "blank" "cntrl" "digit" "graph" "lower"
+           "print" "punct" "space" "upper" "word" "xdigit"
+           "unibyte" "nonascii" "multibyte"))
+      ":]"))
+
+;;; The following dynamically bound variables control the operation of
+;;; the parser (see `rxt-parse-re'.)
+(defvar rxt-parse-pcre nil
+  "t if the rxt string parser is parsing PCRE syntax, nil for Elisp syntax.
+
+This should only be let-bound internally, never set otherwise.")
+
+(defvar rxt-pcre-extended-mode nil
+  "t if the rxt string parser is emulating PCRE's \"extended\" mode.
+
+In extended mode (indicated by /x in Perl/PCRE), whitespace
+outside of character classes and \\Q...\\E quoting is ignored,
+and a `#' character introduces a comment that extends to the end
+of line.")
+
+(defvar rxt-pcre-s-mode nil
+  "t if the rxt string parser is emulating PCRE's single-line \"/s\" mode.
+
+When /s is used, PCRE's \".\" matches newline characters, which
+otherwise it would not match.")
+
+(defvar rxt-pcre-case-fold nil
+  "non-nil to emulate PCRE's case-insensitive \"/i\" mode in translated regexps.")
+
+(defvar rxt-branch-end-regexp nil)
+(defvar rxt-choice-regexp nil)
+(defvar rxt-brace-begin-regexp nil)
+(defvar rxt-m-to-n-brace-regexp nil)
+(defvar rxt-m-to-?-brace-regexp nil)
+(defvar rxt-m-brace-regexp nil)
+(defvar rxt-named-classes-regexp nil)
+
+(defvar rxt-subgroup-count nil)
+(defvar rxt-source-text-string nil)
+
+(defun rxt-parse-pcre (re)
+  (rxt-parse-re re t))
+
+(defun rxt-parse-elisp (re)
+  (rxt-parse-re re nil))
+
+(defun rxt-parse-re (re pcre-p)
+  (let* ((rxt-parse-pcre pcre-p)
+         (rxt-pcre-extended-mode nil)
+         (rxt-pcre-s-mode        nil)
+         (rxt-pcre-case-fold     nil)
+
+         ;; Bind regexps to match syntax that differs between PCRE and
+         ;; Elisp only in the addition of a backslash "\"
+         (escape (if pcre-p "" "\\"))
+         (rxt-choice-regexp
+          (rx-to-string `(seq ,escape "|")))
+         (rxt-branch-end-regexp
+          (rx-to-string `(or buffer-end
+                             (seq ,escape (or "|" ")")))))
+         (rxt-brace-begin-regexp
+          (rx-to-string `(seq ,escape "{")))
+         (rxt-m-to-n-brace-regexp
+          (rx-to-string
+           `(seq
+             (submatch (* (any "0-9"))) "," (submatch (+ (any "0-9")))
+             ,escape "}")))
+         (rxt-m-to-?-brace-regexp
+          (rx-to-string
+           `(seq (submatch (+ (any "0-9"))) "," ,escape "}")))
+         (rxt-m-brace-regexp
+          (rx-to-string
+           `(seq (submatch (+ (any "0-9"))) ,escape "}")))
+
+         ;; Named character classes [: ... :] differ slightly
+         (rxt-named-classes-regexp
+          (if pcre-p
+              rxt-pcre-named-classes-regexp
+            rxt-elisp-named-classes-regexp))
+
+         (rxt-subgroup-count 0)
+         (case-fold-search nil))
+    (with-temp-buffer
+      (insert re)
+      (goto-char (point-min))
+      (let ((rxt-source-text-string re))
+        (rxt-parse-exp)))))
+
+;; Parse a complete regex: a number of branches separated by | or
+;; \|, as determined by `rxt-branch-end-regexp'.
+(defun rxt-parse-exp ()
+  ;; These variables are let-bound here because in PCRE mode they may
+  ;; be set internally by (?x) or (?s) constructions, whose scope
+  ;; lasts until the end of a sub-expression
+  (rxt-with-source-location
+   (let ((rxt-pcre-extended-mode rxt-pcre-extended-mode)
+         (rxt-pcre-s-mode rxt-pcre-s-mode)
+         (rxt-pcre-case-fold rxt-pcre-case-fold))
+     (if (eobp)
+         (rxt-seq)
+       (let ((branches '()))
+         (cl-block nil
+           (while t
+             (let ((branch (rxt-parse-branch)))
+               (push branch branches)
+               (rxt-token-case
+                (rxt-choice-regexp nil)
+                (t (cl-return (apply #'rxt-choice (reverse branches)))))))))))))
+
+;; Skip over whitespace and comments in PCRE extended mode
+(defun rxt-extended-skip ()
+  (when rxt-pcre-extended-mode
+    (skip-syntax-forward "-")
+    (while (looking-at "#")
+      (beginning-of-line 2)
+      (skip-syntax-forward "-"))))
+
+;; Parse a regexp "branch": a sequence of pieces
+(defun rxt-parse-branch ()
+  (rxt-extended-skip)
+  (rxt-with-source-location
+   (let ((pieces '())
+         (branch-start-p t))
+     (while (not (looking-at rxt-branch-end-regexp))
+       (push (rxt-parse-piece branch-start-p) pieces)
+       (setq branch-start-p nil))
+     (apply #'rxt-seq (reverse pieces)))))
+
+;; Parse a regexp "piece": an atom (`rxt-parse-atom') plus any
+;; following quantifiers
+(defun rxt-parse-piece (&optional branch-begin)
+  (rxt-extended-skip)
+  (rxt-with-source-location
+   (let ((atom (rxt-parse-atom branch-begin)))
+     (rxt-parse-quantifiers atom))))
+
+;; Parse any and all quantifiers after ATOM and return the quantified
+;; regexp, or ATOM unchanged if no quantifiers
+(defun rxt-parse-quantifiers (atom)
+  (catch 'done
+    (while (not (eobp))
+      (let ((atom1 (rxt-parse-quantifier atom)))
+        (if (eq atom1 atom)
+            (throw 'done t)
+          (setq atom atom1)))))
+  atom)
+
+;; Possibly parse a single quantifier after ATOM and return the
+;; quantified atom, or ATOM if no quantifier
+(defun rxt-parse-quantifier (atom)
+  (rxt-extended-skip)
+  (rxt-token-case
+   ((rx "*?") (rxt-repeat 0 nil atom nil))
+   ((rx "*")  (rxt-repeat 0 nil atom t))
+   ((rx "+?") (rxt-repeat 1 nil atom nil))
+   ((rx "+")  (rxt-repeat 1 nil atom t))
+   ((rx "??") (rxt-repeat 0 1 atom nil))
+   ((rx "?")  (rxt-repeat 0 1 atom t))
+   ;; Brace expression "{M,N}", "{M,}", "{M}"
+   (rxt-brace-begin-regexp
+    (cl-destructuring-bind (from to)
+        (rxt-parse-braces)
+      (rxt-repeat from to atom)))
+   ;; No quantifiers found
+   (t atom)))
+
+;; Parse a regexp atom, i.e. an element that binds to any following
+;; quantifiers. This includes characters, character classes,
+;; parenthesized groups, assertions, etc.
+(defun rxt-parse-atom (&optional branch-begin)
+  (if (eobp)
+      (rxt-error "Unexpected end of regular expression")
+    (if rxt-parse-pcre
+        (rxt-parse-atom/pcre)
+      (rxt-parse-atom/el branch-begin))))
+
+(defun rxt-parse-atom/common ()
+  (rxt-token-case
+   ((rx "[")   (rxt-parse-char-class))
+   ((rx "\\b") (rxt-word-boundary))
+   ((rx "\\B") (rxt-not-word-boundary))))
+
+(defun rxt-parse-atom/el (branch-begin)
+  (rxt-with-source-location
+   (or (rxt-parse-atom/common)
+       (rxt-token-case
+        ;; "." wildcard
+        ((rx ".") (rxt-nonl))
+        ;; "^" and "$" are metacharacters only at beginning or end of a
+        ;; branch in Elisp; elsewhere they are literals
+        ((rx "^")
+         (if branch-begin
+             (rxt-bol)
+           (rxt-string "^")))
+        ((rx "$")
+         (if (looking-at rxt-branch-end-regexp)
+             (rxt-eol)
+           (rxt-string "$")))
+        ;; Beginning & end of string, word, symbol
+        ((rx "\\`") (rxt-bos))
+        ((rx "\\'") (rxt-eos))
+        ((rx "\\<") (rxt-bow))
+        ((rx "\\>") (rxt-eow))
+        ((rx "\\_<") (rxt-symbol-start))
+        ((rx "\\_>") (rxt-symbol-end))
+        ;; Subgroup
+        ((rx "\\(") (rxt-parse-subgroup/el))
+        ;; Word/non-word characters (meaning depending on syntax table)
+        ((rx "\\w") (rxt-wordchar))
+        ((rx "\\W") (rxt-not-wordchar))
+        ;; Other syntax categories
+        ((rx "\\" (submatch (any ?S ?s)) (submatch nonl))
+         (let ((negated (string= (match-string 1) "S"))
+               (syntax
+                (car (rassoc (string-to-char (match-string 2))
+                              rx-syntax))))
+           (if syntax
+               (let ((re (rxt-syntax-class syntax)))
+                 (if negated (rxt-negate re) re))
+             (rxt-error "Invalid syntax class `\\%s'" (match-string 0)))))
+        ;; Character categories
+        ((rx "\\" (submatch (any ?C ?c)) (submatch nonl))
+         (let ((negated (string= (match-string 1) "C"))
+               (category
+                (car (rassoc (string-to-char (match-string 2))
+                             rx-categories))))
+           (if category
+               (let ((re (rxt-char-category category)))
+                 (if negated (rxt-negate re) re))
+             (rxt-error "Invalid character category `%s'" (match-string 0)))))
+        ;; Backreference
+        ((rx (seq "\\" (submatch (any "1-9"))))
+         (rxt-backref (string-to-number (match-string 1))))
+        ;; Other escaped characters
+        ((rx (seq "\\" (submatch nonl)))
+         (rxt-string (match-string 1)))
+        ;; Normal characters
+        ((rx (or "\n" nonl))
+         (rxt-string (match-string 0)))))))
+
+(defun rxt-parse-atom/pcre ()
+  (rxt-extended-skip)
+  (rxt-with-source-location
+   (or
+    ;; Is it an atom that's the same in Elisp?
+    (rxt-parse-atom/common)
+    ;; Is it common to PCRE regex and character class syntax?
+    (let ((char (rxt-parse-escapes/pcre)))
+      (and char
+           (rxt-string (char-to-string char))))
+    ;; Otherwise:
+    (rxt-token-case
+     ;; "." wildcard
+     ((rx ".")
+      (if rxt-pcre-s-mode
+          (rxt-anything)
+        (rxt-nonl)))
+     ;; Beginning & end of string/line
+     ((rx "^") (rxt-bol))
+     ((rx "$") (rxt-eol))
+     ((rx "\\A") (rxt-bos))
+     ((rx "\\Z") (rxt-eos))
+     ;; Subgroup
+     ((rx "(") (rxt-parse-subgroup/pcre))
+     ;; Metacharacter quoting
+     ((rx "\\Q")
+      ;; It would seem simple to take all the characters between \Q
+      ;; and \E and make an rxt-string, but \Q...\E isn't an atom:
+      ;; any quantifiers afterward should bind only to the last
+      ;; character, not the whole string.
+      (let ((begin (point)))
+        (search-forward "\\E" nil t)
+        (let* ((end (match-beginning 0))
+               (str (buffer-substring-no-properties begin (1- end)))
+               (char (char-to-string (char-before end))))
+          (rxt-seq (rxt-string str)
+                   (rxt-parse-quantifiers (rxt-string char))))))
+     ;; Pre-defined character sets
+     ((rx "\\" (submatch (any "d" "D" "h" "H" "s" "S" "v" "V" "w" "W")))
+      (rxt--pcre-char-set (string-to-char (match-string 1))))
+     ;; \ + digits: backreference or octal char?
+     ((rx "\\" (submatch (+ (any "0-9"))))
+      (let* ((digits (match-string 1))
+             (dec (string-to-number digits)))
+        ;; from "man pcrepattern": If the number is less than 10, or if
+        ;; there have been at least that many previous capturing left
+        ;; parentheses in the expression, the entire sequence is taken
+        ;; as a back reference.
+        (if (and (> dec 0)
+                 (or (< dec 10)
+                     (>= rxt-subgroup-count dec)))
+            (progn
+              (when rxt-pcre-case-fold
+                (display-warning
+                 'rxt "Backreferences with case-folding are handled poorly"))
+              (rxt-backref dec))
+          ;; from "man pcrepattern": if the decimal number is greater
+          ;; than 9 and there have not been that many capturing
+          ;; subpatterns, PCRE re-reads up to three octal digits
+          ;; following the backslash, and uses them to generate a data
+          ;; character. Any subsequent digits stand for themselves.
+          (goto-char (match-beginning 1))
+          (re-search-forward (rx (** 0 3 (any "0-7"))))
+          (rxt-string (char-to-string (string-to-number (match-string 0) 8))))))
+     ;; Other escaped characters
+     ((rx "\\" (submatch nonl)) (rxt-string (match-string 1)))
+     ;; Everything else
+     ((rx (or (any "\n") nonl)) (rxt-string (match-string 0)))))))
+
+(defun rxt-parse-escapes/pcre ()
+  "Consume a one-char PCRE escape at point and return its codepoint equivalent.
+
+Handles only those character escapes which have the same meaning
+in character classes as outside them."
+  (rxt-token-case
+   ((rx "\\a") #x07) ; bell
+   ((rx "\\e") #x1b) ; escape
+   ((rx "\\f") #x0c) ; formfeed
+   ((rx "\\n") #x0a) ; linefeed
+   ((rx "\\r") #x0d) ; carriage return
+   ((rx "\\t") #x09) ; tab
+   ;; Control character
+   ((rx "\\c" (submatch nonl))
+    ;; from `man pcrepattern':
+    ;; The precise effect of \cx is as follows: if x is a lower case
+    ;; letter, it is converted to upper case.  Then bit 6 of the
+    ;; character (hex 40) is inverted.
+    (logxor (string-to-char (upcase (match-string 1))) #x40))
+   ;; Hex escapes
+   ((rx "\\x" (submatch (** 1 2 (any "0-9" "A-Z" "a-z"))))
+    (string-to-number (match-string 1) 16))
+   ((rx "\\x{" (submatch (* (any "0-9" "A-Z" "a-z"))) "}")
+    (string-to-number (match-string 1) 16))))
+
+(defun rxt-parse-subgroup/pcre ()
+  (catch 'return
+    (let ((shy nil)
+          (extended-mode rxt-pcre-extended-mode)
+          (single-line-mode rxt-pcre-s-mode)
+          (case-fold rxt-pcre-case-fold))
+      (rxt-extended-skip)
+      ;; Check for special (? ..) and (* ...) syntax
+      (rxt-token-case
+       ((rx "?")                        ; (?
+        (rxt-token-case
+         ((rx ")")                      ; Empty group (?)
+          (throw 'return (rxt-empty-string)))
+         (":" (setq shy t))             ; Shy group (?:
+         ("#"                           ; Comment   (?#
+          (search-forward ")")
+          (throw 'return (rxt-empty-string)))
+         ((rx (or                       ; Flags     (?isx-isx
+               (seq (group (* (any "gimosx"))) "-" (group (+ (any "gimosx"))))
+               (seq (group (+ (any "gimosx"))))))
+          (let ((token (match-string 0))
+                (on (or (match-string 1) (match-string 3)))
+                (off (or (match-string 2) "")))
+            (if (cl-find ?x on)  (setq extended-mode t))
+            (if (cl-find ?s on)  (setq single-line-mode t))
+            (if (cl-find ?i on)  (setq case-fold t))
+            (if (cl-find ?x off) (setq extended-mode nil))
+            (if (cl-find ?s off) (setq single-line-mode nil))
+            (if (cl-find ?i off) (setq case-fold nil))
+            (when (string-match-p "[gmo]" token)
+              (display-warning
+               'rxt (format "Unhandled PCRE flags in (?%s" token))))
+          (rxt-token-case
+           (":" (setq shy t))        ; Shy group with flags (?isx-isx: ...
+           (")"                      ; Set flags (?isx-isx)
+            ;; Set flags for the remainder of the current subexpression
+            (setq rxt-pcre-extended-mode extended-mode
+                  rxt-pcre-s-mode single-line-mode
+                  rxt-pcre-case-fold case-fold)
+            (throw 'return (rxt-empty-string)))))
+         ;; Other constructions like (?=, (?!, etc. are not recognised
+         (t (rxt-error "Unrecognized PCRE extended construction `(?%c'"
+                       (char-after)))))
+
+       ;; No special (* ...) verbs are recognised
+       ((rx "*")
+        (let ((begin (point)))
+          (search-forward ")" nil 'go-to-end)
+          (rxt-error "Unrecognized PCRE extended construction `(*%s'"
+                     (buffer-substring begin (point))))))
+
+      ;; Parse the remainder of the subgroup
+      (unless shy (cl-incf rxt-subgroup-count))
+      (let* ((rxt-pcre-extended-mode extended-mode)
+             (rxt-pcre-s-mode single-line-mode)
+             (rxt-pcre-case-fold case-fold)
+             (rx (rxt-parse-exp)))
+        (rxt-extended-skip)
+        (rxt-token-case
+         (")" (if shy rx (rxt-submatch rx)))
+         (t (rxt-error "Subexpression missing close paren")))))))
+
+(defun rxt-parse-subgroup/el ()
+  (let ((kind
+         (rxt-token-case
+          ((rx "?:")
+           (cl-incf rxt-subgroup-count)
+           'shy)
+          ((rx "?" (group (+ (in "0-9"))) ":")
+           (let ((n (string-to-number (match-string 1))))
+             (when (< rxt-subgroup-count n)
+               (setf rxt-subgroup-count n))
+             n))
+          ((rx "?") ; Reserved
+           (rxt-error "Unknown match group sequence")))))
+    (let ((rx (rxt-parse-exp)))
+      (rxt-token-case
+       ((rx "\\)")
+        (cond ((eq kind 'shy) rx)
+              ((numberp kind)
+               (rxt-submatch-numbered kind rx))
+              (t (rxt-submatch rx))))
+       (t (rxt-error "Subexpression missing close paren"))))))
+
+(defun rxt-parse-braces ()
+  (rxt-token-case
+   (rxt-m-to-n-brace-regexp
+    (list (string-to-number (match-string 1))
+          (string-to-number (match-string 2))))
+   (rxt-m-to-?-brace-regexp
+    (list (string-to-number (match-string 1)) nil))
+   (rxt-m-brace-regexp
+    (let ((a (string-to-number (match-string 1))))
+      (list a a)))
+   (t
+    (let ((begin (point)))
+      (search-forward "}" nil 'go-to-end)
+      (rxt-error "Bad brace expression {%s"
+                 (buffer-substring-no-properties begin (point)))))))
+
+;; Parse a character set range [...]
+(defun rxt-parse-char-class ()
+  (when (eobp)
+    (rxt-error "Missing close right bracket in regexp"))
+  (rxt-with-source-location
+   (let* ((negated (rxt-token-case
+                    ((rx "^") t)
+                    (t nil)))
+          (begin (point))
+          (result
+           (if negated
+               (rxt-negate (rxt-char-set-union))
+             (rxt-char-set-union)))
+          (transformer
+           (if negated #'rxt-negate #'identity))
+          (builder
+           (if negated #'rxt-char-set-intersection #'rxt-choice)))
+     (catch 'done
+       (while t
+         (when (eobp)
+           (rxt-error "Missing close right bracket in regexp"))
+         (if (and (looking-at (rx "]"))
+                  (not (= (point) begin)))
+             (throw 'done result)
+           (let ((piece (funcall transformer (rxt-parse-char-class-piece))))
+             (setq result (funcall builder result piece))))))
+     (forward-char)                     ; Skip over closing "]"
+     result)))
+
+;; Parse a single character, a character range, or a posix class
+;; within a character set context.  Returns an `rxt-char-set'.
+(defun rxt-parse-char-class-piece ()
+  (let ((atom (rxt-parse-char-class-atom)))
+    (cl-typecase atom
+      (rxt-char-set                     ; return unchanged
+       atom)
+      (integer                          ; character: check for range
+       (let ((range-end (rxt-maybe-parse-range-end)))
+         (if range-end
+             (rxt-char-set-union (cons atom range-end))
+           (rxt-char-set-union atom))))
+      (t                                ; transform into character set
+       (rxt-char-set-union atom)))))
+
+;; Parse a single character or named class within a charset.
+;;
+;; Returns an integer (a character), a symbol (representing a named
+;; character class) or an `rxt-char-set' (for pre-defined character
+;; classes like \d, \W, etc.)
+(defun rxt-parse-char-class-atom ()
+  (or
+   ;; First, check for PCRE-specific backslash sequences
+   (and rxt-parse-pcre
+        (rxt-parse-char-class-atom/pcre))
+   ;; Char-class syntax
+   (rxt-token-case
+    ;; Named classes [:alnum:], ...
+    (rxt-named-classes-regexp
+     (intern (match-string 1)))
+    ;; Error on unknown posix-class-like syntax
+    ((rx "[:" (* (any "a-z")) ":]")
+     (rxt-error "Unknown posix character class `%s'" (match-string 0)))
+    ;; Error on [= ... ]= collation syntax
+    ((rx "[" (submatch (any "." "="))
+         (* (any "a-z")) (backref 1) "]")
+     (rxt-error "Unsupported collation syntax `%s'" (match-string 0)))
+    ;; Other characters stand for themselves
+    ((rx (or "\n" nonl))
+     (string-to-char (match-string 0))))))
+
+;; Parse backslash escapes inside PCRE character classes
+(defun rxt-parse-char-class-atom/pcre ()
+  (or (rxt-parse-escapes/pcre)
+      (rxt-token-case
+       ;; Backslash + digits => octal char
+       ((rx "\\" (submatch (** 1 3 (any "0-7"))))
+        (string-to-number (match-string 1) 8))
+       ;; Pre-defined character sets
+       ((rx "\\" (submatch (any "d" "D" "h" "H" "s" "S" "v" "V" "w" "W")))
+        (rxt--pcre-char-set (string-to-char (match-string 1))))
+       ;; "\b" inside character classes is a backspace
+       ((rx "\\b") ?\C-h)
+       ;; Ignore other escapes
+       ((rx "\\" (submatch nonl))
+        (string-to-char (match-string 1))))))
+
+;; Look for a range tail (the "-z" in "a-z") after parsing a single
+;; character within in a character set.  Returns either a character
+;; representing the range end, or nil.
+(defun rxt-maybe-parse-range-end ()
+  (let ((range-end nil) (end-position nil))
+    (when (looking-at (rx "-" (not (any "]"))))
+      (save-excursion
+        (forward-char)
+        (setq range-end (rxt-parse-char-class-atom)
+              end-position (point))))
+
+    (if (characterp range-end)
+        ;; This is a range: move point after it and return the ending character
+        (progn
+          (goto-char end-position)
+          range-end)
+      ;; Not a range.
+      nil)))
+
+;; Return the pre-defined PCRE char-set associated with CHAR: i.e. \d
+;; is digits, \D non-digits, \s space characters, etc.
+(defun rxt--pcre-char-set (char)
+  (let* ((base-char (downcase char))
+         (negated (/= char base-char))
+         (elements (assoc-default base-char rxt-pcre-char-set-alist))
+         (base-char-set (apply #'rxt-char-set-union elements)))
+    (if negated
+        (rxt-negate base-char-set)
+      base-char-set)))
+
+
+;;;; Unparser to `rx' syntax
+
+(defconst rxt-rx-verbose-equivalents
+  '((bol . line-start)
+    (eol . line-end)
+    (nonl . not-newline)
+    (bos . string-start)
+    (eos . string-end)
+    (bow . word-start)
+    (eow . word-end)
+    (seq . sequence))
+  "Alist of verbose equivalents for short `rx' primitives.")
+
+(defun rxt-rx-symbol (sym)
+  (if rxt-verbose-rx-translation
+      (or (assoc-default sym rxt-rx-verbose-equivalents)
+          sym)
+    sym))
+
+(defun rxt-adt->rx (re)
+  (let ((rx
+         (cl-typecase re
+          (rxt-primitive
+           (rxt-rx-symbol (rxt-primitive-rx re)))
+
+          (rxt-string
+           (if (or (not (rxt-string-case-fold re))
+                   (string= "" (rxt-string-chars re)))
+               (rxt-string-chars re)
+             `(seq
+               ,@(cl-loop for char across (rxt-string-chars re)
+                          collect `(any ,(upcase char) ,(downcase char))))))
+
+          (rxt-seq
+           `(seq ,@(mapcar #'rxt-adt->rx (rxt-seq-elts re))))
+
+          (rxt-choice
+           `(or ,@(mapcar #'rxt-adt->rx (rxt-choice-elts re))))
+
+          (rxt-submatch
+           (if (rxt-seq-p (rxt-submatch-body re))
+               `(submatch
+                 ,@(mapcar #'rxt-adt->rx (rxt-seq-elts (rxt-submatch-body re))))
+             `(submatch ,(rxt-adt->rx (rxt-submatch-body re)))))
+
+          (rxt-submatch-numbered
+           (if (rxt-seq-p (rxt-submatch-numbered-p re))
+               `(,(rxt-rx-symbol 'submatch-n)
+                  ,(rxt-submatch-numbered-n re)
+                  ,@(mapcar #'rxt-adt->rx
+                            (rxt-seq-elts
+                             (rxt-submatch-numbered-body re))))
+             `(,(rxt-rx-symbol 'submatch-n)
+                ,(rxt-submatch-numbered-n re)
+                ,(rxt-adt->rx (rxt-submatch-numbered-body re)))))
+
+          (rxt-backref
+           (let ((n (rxt-backref-n re)))
+             (if (<= n 9)
+                 `(backref ,(rxt-backref-n re))
+               (rxt-error "Too many backreferences (%s)" n))))
+
+          (rxt-syntax-class
+           `(syntax ,(rxt-syntax-class-symbol re)))
+
+          (rxt-char-category
+           `(category ,(rxt-char-category-symbol re)))
+
+          (rxt-repeat
+           (let ((from (rxt-repeat-from re))
+                 (to (rxt-repeat-to re))
+                 (greedy (rxt-repeat-greedy re))
+                 (body (rxt-adt->rx (rxt-repeat-body re))))
+             (if rxt-verbose-rx-translation
+                 (let ((rx
+                        (cond
+                          ((and (zerop from) (null to))
+                           `(zero-or-more ,body))
+                          ((and (equal from 1) (null to))
+                           `(one-or-more ,body))
+                          ((and (zerop from) (equal to 1))
+                           `(zero-or-one ,body))
+                          ((null to)
+                           `(>= ,from ,body))
+                          ((equal from to)
+                           `(repeat ,from ,body))
+                          (t
+                           `(** ,from ,to ,body)))))
+                   (if greedy
+                       (if rxt-explain
+                           rx           ; Readable but not strictly accurate. Fixme?
+                         `(maximal-match ,rx))
+                     `(minimal-match ,rx)))
+               (cond
+                 ((and (zerop from) (null to))
+                  `(,(if greedy '* '*?) ,body))
+                 ((and (equal from 1) (null to))
+                  `(,(if greedy '+ '+?) ,body))
+                 ((and (zerop from) (equal to 1))
+                  `(,(if greedy ? ??) ,body))
+                 ((null to)
+                  `(>= ,from ,body))
+                 ((equal from to)
+                  `(= ,from ,body))
+                 (t
+                  `(** ,from ,to ,body))))))
+
+          (rxt-char-set-union
+           (let* ((case-fold (rxt-char-set-union-case-fold re))
+                  (re (rxt--simplify-char-set re case-fold))
+                  (chars (rxt-char-set-union-chars re))
+                  (ranges (rxt-char-set-union-ranges re))
+                  (classes (rxt-char-set-union-classes re))
+                  (case-fold (rxt-char-set-union-case-fold re)))
+             (if (and (null chars) (null ranges) (= 1 (length classes)))
+                 (car classes)
+               `(any ,@chars ,@ranges ,@classes))))
+
+          (rxt-char-set-negation
+           `(not ,(rxt-adt->rx (rxt-char-set-negation-elt re))))
+
+          (t
+           (rxt-error "No RX translation of `%s'" (rxt-to-string re))))))
+
+    ;; Store source information on each fragment of the generated RX
+    ;; sexp for rxt-explain mode
+    (when rxt-explain
+      ;; Use gensyms to store unique source information for multiple
+      ;; occurrences of primitives like `bol'
+      (when (symbolp rx)
+        (setq rx (make-symbol (symbol-name rx))))
+      (setf (rxt-location rx) (rxt-location re)))
+    rx))
+
+
+;;;; 'Unparser' to PCRE notation
+
+;;; Based on scsh/posixstr.scm in scsh
+
+;; To ensure that the operator precedence in the generated regexp does
+;; what we want, we need to keep track of what kind of production is
+;; returned from each step. Therefore these functions return a string
+;; and a numeric "level" which lets the function using the generated
+;; regexp know whether it has to be parenthesized:
+;;
+;; 0: an already parenthesized expression
+;;
+;; 1: a "piece" binds to any succeeding quantifiers
+;;
+;; 2: a "branch", or concatenation of pieces, needs parenthesizing to
+;; bind to quantifiers
+;;
+;; 3: a "top", or alternation of branches, needs parenthesizing to
+;; bind to quantifiers or to concatenation
+;;
+;; This idea is stolen straight out of the scsh implementation.
+
+(defun rxt-adt->pcre (re)
+  (cl-destructuring-bind (s _) (rxt-adt->pcre/lev re) s))
+
+(defun rxt-adt->pcre/lev (re)
+  (cl-typecase re
+    (rxt-primitive
+     (let ((s (rxt-primitive-pcre re)))
+       (if s
+           (list s 1)
+         (rxt-error "No PCRE translation of `%s'" (rxt-to-string re)))))
+
+   (rxt-string (rxt-string->pcre re))
+   (rxt-seq (rxt-seq->pcre re))
+   (rxt-choice (rxt-choice->pcre re))
+   (rxt-submatch (rxt-submatch->pcre re))
+   (rxt-backref
+    (list (format "\\%d" (rxt-backref-n re)) 1))
+   (rxt-repeat (rxt-repeat->pcre re))
+
+   ((or rxt-char-set-union rxt-char-set-negation)
+    (rxt-char-set->pcre re))
+   
+   ;; FIXME
+   ;; ((rxt-char-set-intersection re) (rxt-char-set-intersection->pcre re))
+
+   (t
+    (rxt-error "No PCRE translation of `%s'" (rxt-to-string re)))))
+
+(defconst rxt-pcre-metachars (rx (any "\\^.$|()[]*+?{}")))
+(defconst rxt-pcre-charset-metachars (rx (any "]" "[" "\\" "^" "-")))
+
+(defun rxt-string->pcre (re)
+  (let ((chars (rxt-string-chars re)))
+    (list
+     (replace-regexp-in-string
+      rxt-pcre-metachars
+      "\\\\\\&" chars)
+     ;; A one-character string is a 'piece' (it binds to a following
+     ;; quantifier).  A longer string is a 'branch' (it has to be
+     ;; enclosed in parentheses to bind to a following quantifier).
+     (if (> (length chars) 1) 2 1))))
+
+(defun rxt-seq->pcre (re)
+  (let ((elts (rxt-seq-elts re)))
+    (if (null elts)
+        ""
+      (rxt-seq-elts->pcre elts))))
+
+(defun rxt-seq-elts->pcre (elts)
+  (cl-destructuring-bind
+      (s lev) (rxt-adt->pcre/lev (car elts))
+    (if (null (cdr elts))
+        (list s lev)
+      (cl-destructuring-bind
+          (s1 lev1) (rxt-seq-elts->pcre (cdr elts))
+        (list (concat (rxt-paren-if-necessary s lev)
+                      (rxt-paren-if-necessary s1 lev1))
+              2)))))
+
+(defun rxt-paren-if-necessary (s lev)
+  (if (< lev 3)
+      s
+    (concat "(?:" s ")")))
+
+(defun rxt-choice->pcre (re)
+  (let ((elts (rxt-choice-elts re)))
+    (if (null elts)
+        nil
+      (rxt-choice-elts->pcre elts))))
+
+(defun rxt-choice-elts->pcre (elts)
+  (cl-destructuring-bind
+      (s lev) (rxt-adt->pcre/lev (car elts))
+    (if (null (cdr elts))
+        (list s lev)
+      (cl-destructuring-bind
+          (s1 lev1) (rxt-choice-elts->pcre (cdr elts))
+        (list (concat s "|" s1) 3)))))
+
+(defun rxt-submatch->pcre (re)
+  (cl-destructuring-bind
+      (s lev) (rxt-adt->pcre/lev (rxt-submatch-body re))
+    (list (concat "(" s ")") 0)))
+
+(defun rxt-repeat->pcre (re)
+  (let ((from (rxt-repeat-from re))
+        (to (rxt-repeat-to re))
+        (body (rxt-repeat-body re))
+        (greedy (rxt-repeat-greedy re)))
+    (cl-destructuring-bind
+        (s lev) (rxt-adt->pcre/lev body)
+      (cond
+       ((and to (= from 1) (= to 1)) (list s lev))
+       ((and to (= from 0) (= to 0)) (list "" 2))
+       (t
+        (when (> lev 1)     ; parenthesize non-atoms
+          (setq s (concat "(?:" s ")")
+                lev 0))
+        (list (if to
+                  (cond ((and (= from 0) (= to 1))
+                         (concat s (if greedy "?" "??")))
+                        ((= from to)
+                         (concat s "{" (number-to-string to) "}"))
+                        (t
+                         (concat s "{" (number-to-string from)
+                                 "," (number-to-string to) "}")))
+                (cond ((= from 0)
+                       (concat s (if greedy "*" "*?")))
+                      ((= from 1)
+                       (concat s (if greedy "+" "+?")))
+                      (t (concat s "{" (number-to-string from) ",}"))))
+              1))))))
+
+(defun rxt-char-set->pcre (re)
+  (cond ((rxt-char-set-union-p re)
+         (list
+          (concat "[" (rxt-char-set->pcre/chars re) "]") 1))
+
+        ((rxt-char-set-negation-p re)
+         (let ((elt (rxt-char-set-negation-elt re)))
+           (if (rxt-char-set-union-p elt)
+               (list
+                (concat "[^" (rxt-char-set->pcre/chars elt) "]") 1)
+             (rxt-error "No PCRE translation of `%s'" (rxt-to-string elt)))))
+
+        (t
+         (rxt-error "Non-char-set in rxt-char-set->pcre: %s" re))))
+
+;; Fortunately, easier in PCRE than in POSIX!
+(defun rxt-char-set->pcre/chars (re)
+  (cl-flet
+      ((escape
+        (char)
+        (let ((s (char-to-string char)))
+          (cond ((string-match rxt-pcre-charset-metachars s)
+                 (concat "\\" s))
+
+                ((and (not (string= s " "))
+                      (string-match "[^[:graph:]]" s))
+                 (format "\\x{%x}" char))
+
+                (t s)))))
+
+    (let ((chars (rxt-char-set-union-chars re))
+          (ranges (rxt-char-set-union-ranges re))
+          (classes (rxt-char-set-union-classes re)))
+
+      (concat
+       (mapconcat #'escape chars "")
+       (mapconcat #'(lambda (rg)
+                      (format "%s-%s"
+                              (escape (car rg))
+                              (escape (cdr rg))))
+                  ranges "")
+       (mapconcat #'(lambda (class)
+                      (format "[:%s:]" class))
+                  classes "")))))
+
+
+;;;; Generate all productions of a finite regexp
+
+(defun rxt-adt->strings (re)
+  (cl-typecase re
+    (rxt-primitive
+     (list ""))
+    (rxt-string
+     (list (rxt-string-chars re)))
+    (rxt-seq
+     (rxt-seq-elts->strings (rxt-seq-elts re)))
+    (rxt-choice
+     (rxt-choice-elts->strings (rxt-choice-elts re)))
+    (rxt-submatch
+     (rxt-adt->strings (rxt-submatch-body re)))
+    (rxt-submatch-numbered
+     (rxt-adt->strings (rxt-submatch-numbered-body re)))
+    (rxt-repeat
+     (rxt-repeat->strings re))
+    (rxt-char-set-union
+     (rxt-char-set->strings re))
+    (t
+     (error "Can't generate productions of %s"
+            (rxt-syntax-tree-readable re)))))
+
+(defun rxt-concat-product (heads tails)
+  (cl-mapcan
+   (lambda (hs)
+     (mapcar
+      (lambda (ts) (concat hs ts))
+      tails))
+   heads))
+
+(defun rxt-seq-elts->strings (elts)
+  (if (null elts)
+      '("")
+    (let ((heads (rxt-adt->strings (car elts)))
+          (tails (rxt-seq-elts->strings (cdr elts))))
+      (rxt-concat-product heads tails))))
+
+(defun rxt-choice-elts->strings (elts)
+  (if (null elts)
+      '()
+    (append (rxt-adt->strings (car elts))
+            (rxt-choice-elts->strings (cdr elts)))))
+
+(defun rxt-repeat->strings (re)
+  (let ((from (rxt-repeat-from re))
+        (to (rxt-repeat-to re)))
+    (if (not to)
+        (error "Can't generate all productions of unbounded repeat \"%s\""
+               (rxt-syntax-tree-readable re))
+      (let ((strings (rxt-adt->strings (rxt-repeat-body re))))
+        (rxt-repeat-n-m->strings from to strings)))))
+
+(defun rxt-repeat-n-m->strings (from to strings)
+  (cond
+   ((zerop to) '(""))
+   ((= to from) (rxt-repeat-n->strings from strings))
+   (t           ; to > from
+    (let* ((strs-n (rxt-repeat-n->strings from strings))
+           (accum (cl-copy-list strs-n)))
+      (dotimes (i (- to from))
+        (setq strs-n (rxt-concat-product strs-n strings))
+        (setq accum (nconc accum strs-n)))
+      accum))))
+
+(defun rxt-repeat-n->strings (n strings)
+  ;; n > 1
+  (cond ((zerop n) '(""))
+        ((= n 1) strings)
+        (t
+         (rxt-concat-product
+          (rxt-repeat-n->strings (- n 1) strings)
+          strings))))
+
+(defun rxt-char-set->strings (re)
+  (if (rxt-char-set-union-classes re)
+      (error "Can't generate all productions of named character classes in \"%s\""
+             (rxt-syntax-tree-readable re))
+    (let ((chars (mapcar #'char-to-string (rxt-char-set-union-chars re))))
+      (dolist (range (rxt-char-set-union-ranges re))
+        (let ((end (cdr range)))
+          (cl-do ((i (car range) (+ i 1)))
+              ((> i end))
+            (push (char-to-string i) chars))))
+      chars)))
+
+
+;;;; RE-Builder hacks
+
+(defadvice reb-update-modestring
+  (after rxt () activate compile)
+  "This function is hacked for emulated PCRE syntax and regexp conversion."
+  (setq reb-mode-string
+        (concat
+         (format " (%s)" reb-re-syntax)
+         reb-mode-string))
+  (force-mode-line-update))
+
+(defadvice reb-change-syntax
+  (around rxt (&optional syntax) activate compile)
+  "This function is hacked for emulated PCRE syntax and regexp conversion."
+  (interactive
+   (list (intern
+          (completing-read (format "Select syntax (%s): " reb-re-syntax)
+                           '(read string pcre sregex rx)
+                           nil t "" nil (symbol-name reb-re-syntax)))))
+  (unless (memq syntax '(read string pcre lisp-re sregex rx))
+    (error "Invalid syntax: %s" syntax))
+  (let ((re-builder-buffer (get-buffer reb-buffer)))
+    (setq reb-re-syntax syntax)
+    (when re-builder-buffer
+      (with-current-buffer reb-target-buffer
+        (cl-case syntax
+          (rx
+           (let ((rx (rxt-elisp-to-rx reb-regexp)))
+             (setq reb-regexp-src
+                   (with-temp-buffer
+                     (insert "\n" "'")
+                     (rxt-print rx)
+                     (buffer-string)))))
+          (pcre
+           (setq reb-regexp-src (rxt-elisp-to-pcre reb-regexp)))))
+      (with-current-buffer re-builder-buffer
+        ;; Hack: prevent reb-auto-update from clobbering the
+        ;; reb-regexp-src we just set
+        (let ((inhibit-modification-hooks t))
+          (reb-initialize-buffer))
+        ;; Enable flag-toggling bindings for PCRE syntax
+        (rxt--re-builder-switch-pcre-mode)))))
+
+(defadvice reb-read-regexp
+  (around rxt () activate compile)
+  "This function is hacked for emulated PCRE syntax and regexp conversion."
+  (if (eq reb-re-syntax 'pcre)
+      (setq ad-return-value
+            (save-excursion
+              (goto-char (point-min))
+              (rxt-read-delimited-pcre)))
+    ad-do-it))
+
+(defadvice reb-insert-regexp
+  (around rxt () activate compile)
+  "This function is hacked for emulated PCRE syntax and regexp conversion."
+  (if (eq reb-re-syntax 'pcre)
+      (let ((src (reb-target-binding reb-regexp-src)))
+        (if src
+            (insert "\n/" (replace-regexp-in-string "/" "\\/" src t t) "/")
+          (insert "\n//")))
+    ad-do-it))
+
+(defadvice reb-cook-regexp
+  (around rxt (re) activate compile)
+  "This function is hacked for emulated PCRE syntax and regexp conversion."
+  (if (eq reb-re-syntax 'pcre)
+      (setq ad-return-value (rxt-pcre-to-elisp re))
+    ad-do-it))
+
+(defadvice reb-update-regexp
+  (around rxt () activate compile)
+  "This function is hacked for emulated PCRE syntax and regexp conversion."
+  (setq ad-return-value
+        (let* ((re-src (reb-read-regexp))
+               (re (reb-cook-regexp re-src)))
+          (with-current-buffer reb-target-buffer
+            (let ((oldre reb-regexp))
+              (prog1
+                  (not (string= oldre re))
+                (setq reb-regexp re)
+                ;; Update the source re if format requires translation
+                (when (or (reb-lisp-syntax-p) (eq reb-re-syntax 'pcre))
+                  (setq reb-regexp-src re-src))))))))
+
+(defun rxt--re-builder-switch-pcre-mode ()
+  (rxt--read-pcre-mode
+   (if (eq reb-re-syntax 'pcre) 1 0)))
+
+(add-hook 'reb-mode-hook #'rxt--re-builder-switch-pcre-mode)
+
+(provide 'rxt)
+(provide 'pcre2el)
+
+
+;;; pcre2el.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/pcre2el-20161120.1303/pcre2el.elc b/configs/shared/emacs/.emacs.d/elpa/pcre2el-20161120.1303/pcre2el.elc
new file mode 100644
index 0000000000..25a15b3ca0
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/pcre2el-20161120.1303/pcre2el.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/pkg-info-20150517.443/pkg-info-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/pkg-info-20150517.443/pkg-info-autoloads.el
new file mode 100644
index 0000000000..b92ce061f4
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/pkg-info-20150517.443/pkg-info-autoloads.el
@@ -0,0 +1,122 @@
+;;; pkg-info-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "pkg-info" "pkg-info.el" (23377 60991 854706
+;;;;;;  84000))
+;;; Generated autoloads from pkg-info.el
+
+(autoload 'pkg-info-library-original-version "pkg-info" "\
+Get the original version in the header of LIBRARY.
+
+The original version is stored in the X-Original-Version header.
+This header is added by the MELPA package archive to preserve
+upstream version numbers.
+
+LIBRARY is either a symbol denoting a named feature, or a library
+name as string.
+
+If SHOW is non-nil, show the version in the minibuffer.
+
+Return the version from the header of LIBRARY as list.  Signal an
+error if the LIBRARY was not found or had no X-Original-Version
+header.
+
+See Info node `(elisp)Library Headers' for more information
+about library headers.
+
+\(fn LIBRARY &optional SHOW)" t nil)
+
+(autoload 'pkg-info-library-version "pkg-info" "\
+Get the version in the header of LIBRARY.
+
+LIBRARY is either a symbol denoting a named feature, or a library
+name as string.
+
+If SHOW is non-nil, show the version in the minibuffer.
+
+Return the version from the header of LIBRARY as list.  Signal an
+error if the LIBRARY was not found or had no proper header.
+
+See Info node `(elisp)Library Headers' for more information
+about library headers.
+
+\(fn LIBRARY &optional SHOW)" t nil)
+
+(autoload 'pkg-info-defining-library-original-version "pkg-info" "\
+Get the original version of the library defining FUNCTION.
+
+The original version is stored in the X-Original-Version header.
+This header is added by the MELPA package archive to preserve
+upstream version numbers.
+
+If SHOW is non-nil, show the version in mini-buffer.
+
+This function is mainly intended to find the version of a major
+or minor mode, i.e.
+
+   (pkg-info-defining-library-version 'flycheck-mode)
+
+Return the version of the library defining FUNCTION.  Signal an
+error if FUNCTION is not a valid function, if its defining
+library was not found, or if the library had no proper version
+header.
+
+\(fn FUNCTION &optional SHOW)" t nil)
+
+(autoload 'pkg-info-defining-library-version "pkg-info" "\
+Get the version of the library defining FUNCTION.
+
+If SHOW is non-nil, show the version in mini-buffer.
+
+This function is mainly intended to find the version of a major
+or minor mode, i.e.
+
+   (pkg-info-defining-library-version 'flycheck-mode)
+
+Return the version of the library defining FUNCTION.  Signal an
+error if FUNCTION is not a valid function, if its defining
+library was not found, or if the library had no proper version
+header.
+
+\(fn FUNCTION &optional SHOW)" t nil)
+
+(autoload 'pkg-info-package-version "pkg-info" "\
+Get the version of an installed PACKAGE.
+
+If SHOW is non-nil, show the version in the minibuffer.
+
+Return the version as list, or nil if PACKAGE is not installed.
+
+\(fn PACKAGE &optional SHOW)" t nil)
+
+(autoload 'pkg-info-version-info "pkg-info" "\
+Obtain complete version info for LIBRARY and PACKAGE.
+
+LIBRARY is a symbol denoting a named feature, or a library name
+as string.  PACKAGE is a symbol denoting an ELPA package.  If
+omitted or nil, default to LIBRARY.
+
+If SHOW is non-nil, show the version in the minibuffer.
+
+When called interactively, prompt for LIBRARY.  When called
+interactively with prefix argument, prompt for PACKAGE as well.
+
+Return a string with complete version information for LIBRARY.
+This version information contains the version from the headers of
+LIBRARY, and the version of the installed PACKAGE, the LIBRARY is
+part of.  If PACKAGE is not installed, or if the PACKAGE version
+is the same as the LIBRARY version, do not include a package
+version.
+
+\(fn LIBRARY &optional PACKAGE SHOW)" t nil)
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; pkg-info-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/pkg-info-20150517.443/pkg-info-pkg.el b/configs/shared/emacs/.emacs.d/elpa/pkg-info-20150517.443/pkg-info-pkg.el
new file mode 100644
index 0000000000..60574bf3be
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/pkg-info-20150517.443/pkg-info-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "pkg-info" "20150517.443" "Information about packages" '((epl "0.8")))
diff --git a/configs/shared/emacs/.emacs.d/elpa/pkg-info-20150517.443/pkg-info.el b/configs/shared/emacs/.emacs.d/elpa/pkg-info-20150517.443/pkg-info.el
new file mode 100644
index 0000000000..98ecc15089
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/pkg-info-20150517.443/pkg-info.el
@@ -0,0 +1,331 @@
+;;; pkg-info.el --- Information about packages       -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2013-2015  Sebastian Wiesner <swiesner@lunaryorn.com>
+
+;; Author: Sebastian Wiesner <swiesner@lunaryorn.com>
+;; URL: https://github.com/lunaryorn/pkg-info.el
+;; Package-Version: 20150517.443
+;; Keywords: convenience
+;; Version: 0.7-cvs
+;; Package-Requires: ((epl "0.8"))
+
+;; This file is not part of GNU Emacs.
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This library extracts information from installed packages.
+
+;;;; Functions:
+
+;; `pkg-info-library-version' extracts the version from the header of a library.
+;;
+;; `pkg-info-defining-library-version' extracts the version from the header of a
+;;  library defining a function.
+;;
+;; `pkg-info-package-version' gets the version of an installed package.
+;;
+;; `pkg-info-format-version' formats a version list as human readable string.
+;;
+;; `pkg-info-version-info' returns complete version information for a specific
+;; package.
+;;
+;; `pkg-info-get-melpa-recipe' gets the MELPA recipe for a package.
+;;
+;; `pkg-info-get-melpa-fetcher' gets the fetcher used to build a package on
+;; MELPA.
+;;
+;; `pkg-info-wiki-package-p' determines whether a package was build from
+;; EmacsWiki on MELPA.
+
+;;; Code:
+
+(require 'epl)
+
+(require 'lisp-mnt)
+(require 'find-func)
+(require 'json)                         ; `json-read'
+(require 'url-http)                     ; `url-http-parse-response'
+
+(defvar url-http-end-of-headers)
+
+
+;;; Version information
+(defun pkg-info-format-version (version)
+  "Format VERSION as human-readable string.
+
+Return a human-readable string representing VERSION."
+  ;; XXX: Find a better, more flexible way of formatting?
+  (package-version-join version))
+
+(defsubst pkg-info--show-version-and-return (version show)
+  "Show and return VERSION.
+
+When SHOW is non-nil, show VERSION in minibuffer.
+
+Return VERSION."
+  (when show
+    (message (if (listp version) (pkg-info-format-version version) version)))
+  version)
+
+(defun pkg-info--read-library ()
+  "Read a library from minibuffer."
+  (completing-read "Load library: "
+                   (apply-partially 'locate-file-completion-table
+                                    load-path
+                                    (get-load-suffixes))))
+
+(defun pkg-info--read-function ()
+  "Read a function name from minibuffer."
+  (let ((input (completing-read "Function: " obarray #'boundp :require-match)))
+    (if (string= input "") nil (intern input))))
+
+(defun pkg-info--read-package ()
+  "Read a package name from minibuffer."
+  (let* ((installed (epl-installed-packages))
+         (names (sort (mapcar (lambda (pkg)
+                                (symbol-name (epl-package-name pkg)))
+                              installed)
+                      #'string<))
+         (default (car names)))
+    (completing-read "Installed package: " names nil 'require-match
+                     nil nil default)))
+
+(defun pkg-info-library-source (library)
+  "Get the source file of LIBRARY.
+
+LIBRARY is either a symbol denoting a named feature, or a library
+name as string.
+
+Return the source file of LIBRARY as string."
+  (find-library-name (if (symbolp library) (symbol-name library) library)))
+
+(defun pkg-info-defining-library (function)
+  "Get the source file of the library defining FUNCTION.
+
+FUNCTION is a function symbol.
+
+Return the file name of the library as string.  Signal an error
+if the library does not exist, or if the definition of FUNCTION
+was not found."
+  (unless (functionp function)
+    (signal 'wrong-type-argument (list 'functionp function)))
+  (let ((library (symbol-file function 'defun)))
+    (unless library
+      (error "Can't find definition of %s" function))
+    library))
+
+(defun pkg-info-x-original-version (file)
+  "Read the X-Original-Version header from FILE.
+
+Return the value as version list, or return nil if FILE lacks
+this header.  Signal an error, if the value of the header is not
+a valid version."
+  (let ((version-str (with-temp-buffer
+                       (insert-file-contents file)
+                       (lm-header "X-Original-Version"))))
+    (when version-str
+      (version-to-list version-str))))
+
+;;;###autoload
+(defun pkg-info-library-original-version (library &optional show)
+  "Get the original version in the header of LIBRARY.
+
+The original version is stored in the X-Original-Version header.
+This header is added by the MELPA package archive to preserve
+upstream version numbers.
+
+LIBRARY is either a symbol denoting a named feature, or a library
+name as string.
+
+If SHOW is non-nil, show the version in the minibuffer.
+
+Return the version from the header of LIBRARY as list.  Signal an
+error if the LIBRARY was not found or had no X-Original-Version
+header.
+
+See Info node `(elisp)Library Headers' for more information
+about library headers."
+  (interactive (list (pkg-info--read-library) t))
+  (let ((version (pkg-info-x-original-version
+                  (pkg-info-library-source library))))
+    (if version
+        (pkg-info--show-version-and-return version show)
+      (error "Library %s has no original version" library))))
+
+;;;###autoload
+(defun pkg-info-library-version (library &optional show)
+  "Get the version in the header of LIBRARY.
+
+LIBRARY is either a symbol denoting a named feature, or a library
+name as string.
+
+If SHOW is non-nil, show the version in the minibuffer.
+
+Return the version from the header of LIBRARY as list.  Signal an
+error if the LIBRARY was not found or had no proper header.
+
+See Info node `(elisp)Library Headers' for more information
+about library headers."
+  (interactive (list (pkg-info--read-library) t))
+  (let* ((source (pkg-info-library-source library))
+         (version (epl-package-version (epl-package-from-file source))))
+    (pkg-info--show-version-and-return version show)))
+
+;;;###autoload
+(defun pkg-info-defining-library-original-version (function &optional show)
+  "Get the original version of the library defining FUNCTION.
+
+The original version is stored in the X-Original-Version header.
+This header is added by the MELPA package archive to preserve
+upstream version numbers.
+
+If SHOW is non-nil, show the version in mini-buffer.
+
+This function is mainly intended to find the version of a major
+or minor mode, i.e.
+
+   (pkg-info-defining-library-version 'flycheck-mode)
+
+Return the version of the library defining FUNCTION.  Signal an
+error if FUNCTION is not a valid function, if its defining
+library was not found, or if the library had no proper version
+header."
+  (interactive (list (pkg-info--read-function) t))
+  (pkg-info-library-original-version (pkg-info-defining-library function) show))
+
+;;;###autoload
+(defun pkg-info-defining-library-version (function &optional show)
+  "Get the version of the library defining FUNCTION.
+
+If SHOW is non-nil, show the version in mini-buffer.
+
+This function is mainly intended to find the version of a major
+or minor mode, i.e.
+
+   (pkg-info-defining-library-version 'flycheck-mode)
+
+Return the version of the library defining FUNCTION.  Signal an
+error if FUNCTION is not a valid function, if its defining
+library was not found, or if the library had no proper version
+header."
+  (interactive (list (pkg-info--read-function) t))
+  (pkg-info-library-version (pkg-info-defining-library function) show))
+
+;;;###autoload
+(defun pkg-info-package-version (package &optional show)
+  "Get the version of an installed PACKAGE.
+
+If SHOW is non-nil, show the version in the minibuffer.
+
+Return the version as list, or nil if PACKAGE is not installed."
+  (interactive (list (pkg-info--read-package) t))
+  (let* ((name (if (stringp package) (intern package) package))
+         (package (car (epl-find-installed-packages name))))
+    (unless package
+      (error "Can't find installed package %s" name))
+    (pkg-info--show-version-and-return (epl-package-version package) show)))
+
+;;;###autoload
+(defun pkg-info-version-info (library &optional package show)
+  "Obtain complete version info for LIBRARY and PACKAGE.
+
+LIBRARY is a symbol denoting a named feature, or a library name
+as string.  PACKAGE is a symbol denoting an ELPA package.  If
+omitted or nil, default to LIBRARY.
+
+If SHOW is non-nil, show the version in the minibuffer.
+
+When called interactively, prompt for LIBRARY.  When called
+interactively with prefix argument, prompt for PACKAGE as well.
+
+Return a string with complete version information for LIBRARY.
+This version information contains the version from the headers of
+LIBRARY, and the version of the installed PACKAGE, the LIBRARY is
+part of.  If PACKAGE is not installed, or if the PACKAGE version
+is the same as the LIBRARY version, do not include a package
+version."
+  (interactive (list (pkg-info--read-library)
+                     (when current-prefix-arg
+                       (pkg-info--read-package))
+                     t))
+  (let* ((package (or package (if (stringp library) (intern library) library)))
+         (orig-version (condition-case nil
+                           (pkg-info-library-original-version library)
+                         (error nil)))
+         ;; If we have X-Original-Version, we assume that MELPA replaced the
+         ;; library version with its generated version, so we use the
+         ;; X-Original-Version header instead, and ignore the library version
+         ;; header
+         (lib-version (or orig-version (pkg-info-library-version library)))
+         (pkg-version (condition-case nil
+                          (pkg-info-package-version package)
+                        (error nil)))
+         (version (if (and pkg-version
+                           (not (version-list-= lib-version pkg-version)))
+                      (format "%s (package: %s)"
+                              (pkg-info-format-version lib-version)
+                              (pkg-info-format-version pkg-version))
+                    (pkg-info-format-version lib-version))))
+    (pkg-info--show-version-and-return version show)))
+
+(defconst pkg-info-melpa-recipe-url "http://melpa.org/recipes.json"
+  "The URL from which to fetch MELPA recipes.")
+
+(defvar pkg-info-melpa-recipes nil
+  "An alist of MELPA recipes.")
+
+(defun pkg-info-retrieve-melpa-recipes ()
+  "Retrieve MELPA recipes from MELPA archive."
+  (let ((buffer (url-retrieve-synchronously pkg-info-melpa-recipe-url)))
+    (with-current-buffer buffer
+      (unwind-protect
+          (let ((response-code (url-http-parse-response)))
+            (unless (equal response-code 200)
+              (error "Failed to retrieve MELPA recipes from %s (code %s)"
+                     pkg-info-melpa-recipe-url response-code))
+            (goto-char url-http-end-of-headers)
+            (json-read))
+        (when (and buffer (buffer-live-p buffer))
+          (kill-buffer buffer))))))
+
+(defun pkg-info-get-melpa-recipes ()
+  "Get MELPA recipes."
+  (setq pkg-info-melpa-recipes
+        (or pkg-info-melpa-recipes
+            (pkg-info-retrieve-melpa-recipes))))
+
+(defun pkg-info-get-melpa-recipe (package)
+  "Get the MELPA recipe for PACKAGE.
+
+Return nil if PACKAGE is not on MELPA."
+  (cdr (assq package (pkg-info-get-melpa-recipes))))
+
+(defun pkg-info-get-melpa-fetcher (package)
+  "Get the MELPA fetcher for PACKAGE."
+  (cdr (assq 'fetcher (pkg-info-get-melpa-recipe package))))
+
+(defun pkg-info-wiki-package-p (package)
+  "Determine whether PACKAGE is build from the EmacsWiki."
+  (equal (pkg-info-get-melpa-fetcher package) "wiki"))
+
+(provide 'pkg-info)
+
+;; Local Variables:
+;; indent-tabs-mode: nil
+;; coding: utf-8
+;; End:
+
+;;; pkg-info.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/pkg-info-20150517.443/pkg-info.elc b/configs/shared/emacs/.emacs.d/elpa/pkg-info-20150517.443/pkg-info.elc
new file mode 100644
index 0000000000..ba375aff75
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/pkg-info-20150517.443/pkg-info.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/prettier-js-20180108.2326/prettier-js-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/prettier-js-20180108.2326/prettier-js-autoloads.el
new file mode 100644
index 0000000000..64cdcd8779
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/prettier-js-20180108.2326/prettier-js-autoloads.el
@@ -0,0 +1,22 @@
+;;; prettier-js-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "prettier-js" "prettier-js.el" (23377 61676
+;;;;;;  556340 669000))
+;;; Generated autoloads from prettier-js.el
+
+(autoload 'prettier-js-mode "prettier-js" "\
+Runs prettier on file save when this mode is turned on
+
+\(fn &optional ARG)" t nil)
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; prettier-js-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/prettier-js-20180108.2326/prettier-js-pkg.el b/configs/shared/emacs/.emacs.d/elpa/prettier-js-20180108.2326/prettier-js-pkg.el
new file mode 100644
index 0000000000..cb874aaf2e
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/prettier-js-20180108.2326/prettier-js-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "prettier-js" "20180108.2326" "Minor mode to format JS code on file save" 'nil)
diff --git a/configs/shared/emacs/.emacs.d/elpa/prettier-js-20180108.2326/prettier-js.el b/configs/shared/emacs/.emacs.d/elpa/prettier-js-20180108.2326/prettier-js.el
new file mode 100644
index 0000000000..50b511ab75
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/prettier-js-20180108.2326/prettier-js.el
@@ -0,0 +1,214 @@
+;;; prettier-js.el --- Minor mode to format JS code on file save
+
+;; Version: 0.1.0
+;; Package-Version: 20180108.2326
+
+;; Copyright (c) 2014 The go-mode Authors. All rights reserved.
+;; Portions Copyright (c) 2015-present, Facebook, Inc. All rights reserved.
+
+;; Redistribution and use in source and binary forms, with or without
+;; modification, are permitted provided that the following conditions are
+;; met:
+
+;; * Redistributions of source code must retain the above copyright
+;; notice, this list of conditions and the following disclaimer.
+;; * Redistributions in binary form must reproduce the above
+;; copyright notice, this list of conditions and the following disclaimer
+;; in the documentation and/or other materials provided with the
+;; distribution.
+;; * Neither the name of the copyright holder nor the names of its
+;; contributors may be used to endorse or promote products derived from
+;; this software without specific prior written permission.
+
+;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+;; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+;; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+;; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+;; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+;; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+;; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+;; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+;; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+;; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+;; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.)
+
+;; Author: James Long and contributors
+;; Created: 10 January 2017
+;; Url: https://github.com/prettier/prettier-emacs
+;; Keywords: convenience wp edit js
+
+;; This file is not part of GNU Emacs.
+
+;;; Commentary:
+;; Formats your JavaScript code using 'prettier' on file save.
+
+;;; Code:
+
+(defgroup prettier-js nil
+  "Minor mode to format JS code on file save"
+  :group 'languages
+  :prefix "prettier-js"
+  :link '(url-link :tag "Repository" "https://github.com/prettier/prettier"))
+
+(defcustom prettier-js-command "prettier"
+  "The 'prettier' command."
+  :type 'string
+  :group 'prettier-js)
+
+(defcustom prettier-js-args '()
+  "List of args to send to prettier command."
+  :type '(repeat string)
+  :group 'prettier-js)
+
+(defcustom prettier-js-show-errors 'buffer
+    "Where to display prettier error output.
+It can either be displayed in its own buffer, in the echo area, or not at all.
+Please note that Emacs outputs to the echo area when writing
+files and will overwrite prettier's echo output if used from inside
+a `before-save-hook'."
+    :type '(choice
+            (const :tag "Own buffer" buffer)
+            (const :tag "Echo area" echo)
+            (const :tag "None" nil))
+      :group 'prettier-js)
+
+(defcustom prettier-js-width-mode nil
+  "Specify width when formatting buffer contents."
+  :type '(choice
+          (const :tag "Window width" window)
+          (const :tag "Fill column" fill)
+          (const :tag "None" nil))
+  :group 'prettier-js)
+
+(defun prettier-js--goto-line (line)
+  "Move cursor to line LINE."
+  (goto-char (point-min))
+    (forward-line (1- line)))
+
+(defun prettier-js--apply-rcs-patch (patch-buffer)
+  "Apply an RCS-formatted diff from PATCH-BUFFER to the current buffer."
+  (let ((target-buffer (current-buffer))
+        ;; Relative offset between buffer line numbers and line numbers
+        ;; in patch.
+        ;;
+        ;; Line numbers in the patch are based on the source file, so
+        ;; we have to keep an offset when making changes to the
+        ;; buffer.
+        ;;
+        ;; Appending lines decrements the offset (possibly making it
+        ;; negative), deleting lines increments it. This order
+        ;; simplifies the forward-line invocations.
+        (line-offset 0))
+    (save-excursion
+      (with-current-buffer patch-buffer
+        (goto-char (point-min))
+        (while (not (eobp))
+          (unless (looking-at "^\\([ad]\\)\\([0-9]+\\) \\([0-9]+\\)")
+            (error "Invalid rcs patch or internal error in prettier-js--apply-rcs-patch"))
+          (forward-line)
+          (let ((action (match-string 1))
+                (from (string-to-number (match-string 2)))
+                (len  (string-to-number (match-string 3))))
+            (cond
+             ((equal action "a")
+              (let ((start (point)))
+                (forward-line len)
+                (let ((text (buffer-substring start (point))))
+                  (with-current-buffer target-buffer
+                    (setq line-offset (- line-offset len))
+                    (goto-char (point-min))
+                    (forward-line (- from len line-offset))
+                    (insert text)))))
+             ((equal action "d")
+              (with-current-buffer target-buffer
+                (prettier-js--goto-line (- from line-offset))
+                (setq line-offset (+ line-offset len))
+                (let ((beg (point)))
+                  (forward-line len)
+                  (delete-region (point) beg))))
+             (t
+              (error "Invalid rcs patch or internal error in prettier-js--apply-rcs-patch")))))))))
+
+(defun prettier-js--process-errors (filename errorfile errbuf)
+  "Process errors for FILENAME, using an ERRORFILE and display the output in ERRBUF."
+  (with-current-buffer errbuf
+    (if (eq prettier-js-show-errors 'echo)
+        (progn
+          (message "%s" (buffer-string))
+          (prettier-js--kill-error-buffer errbuf))
+      (insert-file-contents errorfile nil nil nil)
+      ;; Convert the prettier stderr to something understood by the compilation mode.
+      (goto-char (point-min))
+      (insert "prettier errors:\n")
+      (while (search-forward-regexp "^stdin" nil t)
+        (replace-match (file-name-nondirectory filename)))
+      (compilation-mode)
+      (display-buffer errbuf))))
+
+(defun prettier-js--kill-error-buffer (errbuf)
+  "Kill buffer ERRBUF."
+  (let ((win (get-buffer-window errbuf)))
+    (if win
+        (quit-window t win)
+      (with-current-buffer errbuf
+        (erase-buffer))
+      (kill-buffer errbuf))))
+
+(defun prettier-js ()
+   "Format the current buffer according to the prettier tool."
+   (interactive)
+   (let* ((ext (file-name-extension buffer-file-name t))
+          (bufferfile (make-temp-file "prettier" nil ext))
+          (outputfile (make-temp-file "prettier" nil ext))
+          (errorfile (make-temp-file "prettier" nil ext))
+          (errbuf (if prettier-js-show-errors (get-buffer-create "*prettier errors*")))
+          (patchbuf (get-buffer-create "*prettier patch*"))
+          (coding-system-for-read 'utf-8)
+          (coding-system-for-write 'utf-8)
+          (width-args
+           (cond
+            ((equal prettier-js-width-mode 'window)
+             (list "--print-width" (number-to-string (window-body-width))))
+            ((equal prettier-js-width-mode 'fill)
+             (list "--print-width" (number-to-string fill-column)))
+            (t
+             '()))))
+     (unwind-protect
+         (save-restriction
+           (widen)
+           (write-region nil nil bufferfile)
+           (if errbuf
+               (with-current-buffer errbuf
+                 (setq buffer-read-only nil)
+                 (erase-buffer)))
+           (with-current-buffer patchbuf
+             (erase-buffer))
+           (if (zerop (apply 'call-process
+                             prettier-js-command bufferfile (list (list :file outputfile) errorfile)
+                             nil (append prettier-js-args width-args (list "--stdin" "--stdin-filepath" buffer-file-name))))
+               (progn
+                 (call-process-region (point-min) (point-max) "diff" nil patchbuf nil "-n" "--strip-trailing-cr" "-"
+                                      outputfile)
+                 (prettier-js--apply-rcs-patch patchbuf)
+                 (message "Applied prettier with args `%s'" prettier-js-args)
+                 (if errbuf (prettier-js--kill-error-buffer errbuf)))
+             (message "Could not apply prettier")
+             (if errbuf
+                 (prettier-js--process-errors (buffer-file-name) errorfile errbuf))
+             ))
+       (kill-buffer patchbuf)
+       (delete-file errorfile)
+       (delete-file bufferfile)
+       (delete-file outputfile))))
+
+;;;###autoload
+(define-minor-mode prettier-js-mode
+  "Runs prettier on file save when this mode is turned on"
+  :lighter " Prettier"
+  :global nil
+  (if prettier-js-mode
+      (add-hook 'before-save-hook 'prettier-js nil 'local)
+    (remove-hook 'before-save-hook 'prettier-js 'local)))
+
+(provide 'prettier-js)
+;;; prettier-js.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/prettier-js-20180108.2326/prettier-js.elc b/configs/shared/emacs/.emacs.d/elpa/prettier-js-20180108.2326/prettier-js.elc
new file mode 100644
index 0000000000..4cb435b12a
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/prettier-js-20180108.2326/prettier-js.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/projectile-20180711.102/projectile-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/projectile-20180711.102/projectile-autoloads.el
new file mode 100644
index 0000000000..2739cd1689
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/projectile-20180711.102/projectile-autoloads.el
@@ -0,0 +1,521 @@
+;;; projectile-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "projectile" "projectile.el" (23377 60992 72998
+;;;;;;  222000))
+;;; Generated autoloads from projectile.el
+
+(autoload 'projectile-version "projectile" "\
+Get the Projectile version as string.
+
+If called interactively or if SHOW-VERSION is non-nil, show the
+version in the echo area and the messages buffer.
+
+The returned string includes both, the version from package.el
+and the library version, if both a present and different.
+
+If the version number could not be determined, signal an error,
+if called interactively, or if SHOW-VERSION is non-nil, otherwise
+just return nil.
+
+\(fn &optional SHOW-VERSION)" t nil)
+
+(autoload 'projectile-invalidate-cache "projectile" "\
+Remove the current project's files from `projectile-projects-cache'.
+
+With a prefix argument ARG prompts for the name of the project whose cache
+to invalidate.
+
+\(fn ARG)" t nil)
+
+(autoload 'projectile-purge-file-from-cache "projectile" "\
+Purge FILE from the cache of the current project.
+
+\(fn FILE)" t nil)
+
+(autoload 'projectile-purge-dir-from-cache "projectile" "\
+Purge DIR from the cache of the current project.
+
+\(fn DIR)" t nil)
+
+(autoload 'projectile-cache-current-file "projectile" "\
+Add the currently visited file to the cache.
+
+\(fn)" t nil)
+
+(autoload 'projectile-discover-projects-in-directory "projectile" "\
+Discover any projects in DIRECTORY and add them to the projectile cache.
+This function is not recursive and only adds projects with roots
+at the top level of DIRECTORY.
+
+\(fn DIRECTORY)" t nil)
+
+(autoload 'projectile-switch-to-buffer "projectile" "\
+Switch to a project buffer.
+
+\(fn)" t nil)
+
+(autoload 'projectile-switch-to-buffer-other-window "projectile" "\
+Switch to a project buffer and show it in another window.
+
+\(fn)" t nil)
+
+(autoload 'projectile-switch-to-buffer-other-frame "projectile" "\
+Switch to a project buffer and show it in another window.
+
+\(fn)" t nil)
+
+(autoload 'projectile-display-buffer "projectile" "\
+Display a project buffer in another window without selecting it.
+
+\(fn)" t nil)
+
+(autoload 'projectile-project-buffers-other-buffer "projectile" "\
+Switch to the most recently selected buffer project buffer.
+Only buffers not visible in windows are returned.
+
+\(fn)" t nil)
+
+(autoload 'projectile-multi-occur "projectile" "\
+Do a `multi-occur' in the project's buffers.
+With a prefix argument, show NLINES of context.
+
+\(fn &optional NLINES)" t nil)
+
+(autoload 'projectile-find-other-file "projectile" "\
+Switch between files with the same name but different extensions.
+With FLEX-MATCHING, match any file that contains the base name of current file.
+Other file extensions can be customized with the variable `projectile-other-file-alist'.
+
+\(fn &optional FLEX-MATCHING)" t nil)
+
+(autoload 'projectile-find-other-file-other-window "projectile" "\
+Switch between files with the same name but different extensions in other window.
+With FLEX-MATCHING, match any file that contains the base name of current file.
+Other file extensions can be customized with the variable `projectile-other-file-alist'.
+
+\(fn &optional FLEX-MATCHING)" t nil)
+
+(autoload 'projectile-find-other-file-other-frame "projectile" "\
+Switch between files with the same name but different extensions in other window.
+With FLEX-MATCHING, match any file that contains the base name of current file.
+Other file extensions can be customized with the variable `projectile-other-file-alist'.
+
+\(fn &optional FLEX-MATCHING)" t nil)
+
+(autoload 'projectile-find-file-dwim "projectile" "\
+Jump to a project's files using completion based on context.
+
+With a prefix ARG invalidates the cache first.
+
+If point is on a filename, Projectile first tries to search for that
+file in project:
+
+- If it finds just a file, it switches to that file instantly.  This works even
+if the filename is incomplete, but there's only a single file in the current project
+that matches the filename at point.  For example, if there's only a single file named
+\"projectile/projectile.el\" but the current filename is \"projectile/proj\" (incomplete),
+`projectile-find-file-dwim' still switches to \"projectile/projectile.el\" immediately
+ because this is the only filename that matches.
+
+- If it finds a list of files, the list is displayed for selecting.  A list of
+files is displayed when a filename appears more than one in the project or the
+filename at point is a prefix of more than two files in a project.  For example,
+if `projectile-find-file-dwim' is executed on a filepath like \"projectile/\", it lists
+the content of that directory.  If it is executed on a partial filename like
+ \"projectile/a\", a list of files with character 'a' in that directory is presented.
+
+- If it finds nothing, display a list of all files in project for selecting.
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'projectile-find-file-dwim-other-window "projectile" "\
+Jump to a project's files using completion based on context in other window.
+
+With a prefix ARG invalidates the cache first.
+
+If point is on a filename, Projectile first tries to search for that
+file in project:
+
+- If it finds just a file, it switches to that file instantly.  This works even
+if the filename is incomplete, but there's only a single file in the current project
+that matches the filename at point.  For example, if there's only a single file named
+\"projectile/projectile.el\" but the current filename is \"projectile/proj\" (incomplete),
+`projectile-find-file-dwim-other-window' still switches to \"projectile/projectile.el\"
+immediately because this is the only filename that matches.
+
+- If it finds a list of files, the list is displayed for selecting.  A list of
+files is displayed when a filename appears more than one in the project or the
+filename at point is a prefix of more than two files in a project.  For example,
+if `projectile-find-file-dwim-other-window' is executed on a filepath like \"projectile/\", it lists
+the content of that directory.  If it is executed on a partial filename
+like \"projectile/a\", a list of files with character 'a' in that directory
+is presented.
+
+- If it finds nothing, display a list of all files in project for selecting.
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'projectile-find-file-dwim-other-frame "projectile" "\
+Jump to a project's files using completion based on context in other frame.
+
+With a prefix ARG invalidates the cache first.
+
+If point is on a filename, Projectile first tries to search for that
+file in project:
+
+- If it finds just a file, it switches to that file instantly.  This works even
+if the filename is incomplete, but there's only a single file in the current project
+that matches the filename at point.  For example, if there's only a single file named
+\"projectile/projectile.el\" but the current filename is \"projectile/proj\" (incomplete),
+`projectile-find-file-dwim-other-frame' still switches to \"projectile/projectile.el\"
+immediately because this is the only filename that matches.
+
+- If it finds a list of files, the list is displayed for selecting.  A list of
+files is displayed when a filename appears more than one in the project or the
+filename at point is a prefix of more than two files in a project.  For example,
+if `projectile-find-file-dwim-other-frame' is executed on a filepath like \"projectile/\", it lists
+the content of that directory.  If it is executed on a partial filename
+like \"projectile/a\", a list of files with character 'a' in that directory
+is presented.
+
+- If it finds nothing, display a list of all files in project for selecting.
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'projectile-find-file "projectile" "\
+Jump to a project's file using completion.
+With a prefix ARG invalidates the cache first.
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'projectile-find-file-other-window "projectile" "\
+Jump to a project's file using completion and show it in another window.
+
+With a prefix ARG invalidates the cache first.
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'projectile-find-file-other-frame "projectile" "\
+Jump to a project's file using completion and show it in another frame.
+
+With a prefix ARG invalidates the cache first.
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'projectile-find-dir "projectile" "\
+Jump to a project's directory using completion.
+
+With a prefix ARG invalidates the cache first.
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'projectile-find-dir-other-window "projectile" "\
+Jump to a project's directory in other window using completion.
+
+With a prefix ARG invalidates the cache first.
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'projectile-find-dir-other-frame "projectile" "\
+Jump to a project's directory in other window using completion.
+
+With a prefix ARG invalidates the cache first.
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'projectile-find-test-file "projectile" "\
+Jump to a project's test file using completion.
+
+With a prefix ARG invalidates the cache first.
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'projectile-project-info "projectile" "\
+Display info for current project.
+
+\(fn)" t nil)
+
+(autoload 'projectile-find-implementation-or-test-other-window "projectile" "\
+Open matching implementation or test file in other window.
+
+\(fn)" t nil)
+
+(autoload 'projectile-find-implementation-or-test-other-frame "projectile" "\
+Open matching implementation or test file in other frame.
+
+\(fn)" t nil)
+
+(autoload 'projectile-toggle-between-implementation-and-test "projectile" "\
+Toggle between an implementation file and its test file.
+
+\(fn)" t nil)
+
+(autoload 'projectile-grep "projectile" "\
+Perform rgrep in the project.
+
+With a prefix ARG asks for files (globbing-aware) which to grep in.
+With prefix ARG of `-' (such as `M--'), default the files (without prompt),
+to `projectile-grep-default-files'.
+
+With REGEXP given, don't query the user for a regexp.
+
+\(fn &optional REGEXP ARG)" t nil)
+
+(autoload 'projectile-ag "projectile" "\
+Run an ag search with SEARCH-TERM in the project.
+
+With an optional prefix argument ARG SEARCH-TERM is interpreted as a
+regular expression.
+
+\(fn SEARCH-TERM &optional ARG)" t nil)
+
+(autoload 'projectile-ripgrep "projectile" "\
+Run a Ripgrep search with `SEARCH-TERM' at current project root.
+
+SEARCH-TERM is a regexp.
+
+\(fn SEARCH-TERM)" t nil)
+
+(autoload 'projectile-regenerate-tags "projectile" "\
+Regenerate the project's [e|g]tags.
+
+\(fn)" t nil)
+
+(autoload 'projectile-find-tag "projectile" "\
+Find tag in project.
+
+\(fn)" t nil)
+
+(autoload 'projectile-run-command-in-root "projectile" "\
+Invoke `execute-extended-command' in the project's root.
+
+\(fn)" t nil)
+
+(autoload 'projectile-run-shell-command-in-root "projectile" "\
+Invoke `shell-command' in the project's root.
+
+\(fn)" t nil)
+
+(autoload 'projectile-run-async-shell-command-in-root "projectile" "\
+Invoke `async-shell-command' in the project's root.
+
+\(fn)" t nil)
+
+(autoload 'projectile-run-shell "projectile" "\
+Invoke `shell' in the project's root.
+
+\(fn)" t nil)
+
+(autoload 'projectile-run-eshell "projectile" "\
+Invoke `eshell' in the project's root.
+
+\(fn)" t nil)
+
+(autoload 'projectile-run-term "projectile" "\
+Invoke `term' in the project's root.
+
+\(fn PROGRAM)" t nil)
+
+(autoload 'projectile-replace "projectile" "\
+Replace literal string in project using non-regexp `tags-query-replace'.
+
+With a prefix argument ARG prompts you for a directory on which
+to run the replacement.
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'projectile-replace-regexp "projectile" "\
+Replace a regexp in the project using `tags-query-replace'.
+
+With a prefix argument ARG prompts you for a directory on which
+to run the replacement.
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'projectile-kill-buffers "projectile" "\
+Kill all project buffers.
+
+\(fn)" t nil)
+
+(autoload 'projectile-save-project-buffers "projectile" "\
+Save all project buffers.
+
+\(fn)" t nil)
+
+(autoload 'projectile-dired "projectile" "\
+Open `dired' at the root of the project.
+
+\(fn)" t nil)
+
+(autoload 'projectile-dired-other-window "projectile" "\
+Open `dired'  at the root of the project in another window.
+
+\(fn)" t nil)
+
+(autoload 'projectile-dired-other-frame "projectile" "\
+Open `dired' at the root of the project in another frame.
+
+\(fn)" t nil)
+
+(autoload 'projectile-vc "projectile" "\
+Open `vc-dir' at the root of the project.
+
+For git projects `magit-status-internal' is used if available.
+For hg projects `monky-status' is used if available.
+
+If PROJECT-ROOT is given, it is opened instead of the project
+root directory of the current buffer file.  If interactively
+called with a prefix argument, the user is prompted for a project
+directory to open.
+
+\(fn &optional PROJECT-ROOT)" t nil)
+
+(autoload 'projectile-recentf "projectile" "\
+Show a list of recently visited files in a project.
+
+\(fn)" t nil)
+
+(autoload 'projectile-configure-project "projectile" "\
+Run project configure command.
+
+Normally you'll be prompted for a compilation command, unless
+variable `compilation-read-command'.  You can force the prompt
+with a prefix ARG.
+
+\(fn ARG)" t nil)
+
+(autoload 'projectile-compile-project "projectile" "\
+Run project compilation command.
+
+Normally you'll be prompted for a compilation command, unless
+variable `compilation-read-command'.  You can force the prompt
+with a prefix ARG.
+
+\(fn ARG)" t nil)
+
+(autoload 'projectile-test-project "projectile" "\
+Run project test command.
+
+Normally you'll be prompted for a compilation command, unless
+variable `compilation-read-command'.  You can force the prompt
+with a prefix ARG.
+
+\(fn ARG)" t nil)
+
+(autoload 'projectile-run-project "projectile" "\
+Run project run command.
+
+Normally you'll be prompted for a compilation command, unless
+variable `compilation-read-command'.  You can force the prompt
+with a prefix ARG.
+
+\(fn ARG)" t nil)
+
+(autoload 'projectile-switch-project "projectile" "\
+Switch to a project we have visited before.
+Invokes the command referenced by `projectile-switch-project-action' on switch.
+With a prefix ARG invokes `projectile-commander' instead of
+`projectile-switch-project-action.'
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'projectile-switch-open-project "projectile" "\
+Switch to a project we have currently opened.
+Invokes the command referenced by `projectile-switch-project-action' on switch.
+With a prefix ARG invokes `projectile-commander' instead of
+`projectile-switch-project-action.'
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'projectile-find-file-in-directory "projectile" "\
+Jump to a file in a (maybe regular) DIRECTORY.
+
+This command will first prompt for the directory the file is in.
+
+\(fn &optional DIRECTORY)" t nil)
+
+(autoload 'projectile-find-file-in-known-projects "projectile" "\
+Jump to a file in any of the known projects.
+
+\(fn)" t nil)
+
+(autoload 'projectile-cleanup-known-projects "projectile" "\
+Remove known projects that don't exist anymore.
+
+\(fn)" t nil)
+
+(autoload 'projectile-clear-known-projects "projectile" "\
+Clear both `projectile-known-projects' and `projectile-known-projects-file'.
+
+\(fn)" t nil)
+
+(autoload 'projectile-remove-known-project "projectile" "\
+Remove PROJECT from the list of known projects.
+
+\(fn &optional PROJECT)" t nil)
+
+(autoload 'projectile-remove-current-project-from-known-projects "projectile" "\
+Remove the current project from the list of known projects.
+
+\(fn)" t nil)
+
+(autoload 'projectile-ibuffer "projectile" "\
+Open an IBuffer window showing all buffers in the current project.
+
+Let user choose another project when PREFIX is supplied.
+
+\(fn PREFIX)" t nil)
+
+(autoload 'projectile-commander "projectile" "\
+Execute a Projectile command with a single letter.
+The user is prompted for a single character indicating the action to invoke.
+The `?' character describes then
+available actions.
+
+See `def-projectile-commander-method' for defining new methods.
+
+\(fn)" t nil)
+
+(autoload 'projectile-edit-dir-locals "projectile" "\
+Edit or create a .dir-locals.el file of the project.
+
+\(fn)" t nil)
+
+(defvar projectile-mode nil "\
+Non-nil if Projectile mode is enabled.
+See the `projectile-mode' command
+for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `projectile-mode'.")
+
+(custom-autoload 'projectile-mode "projectile" nil)
+
+(autoload 'projectile-mode "projectile" "\
+Minor mode to assist project management and navigation.
+
+When called interactively, toggle `projectile-mode'.  With prefix
+ARG, enable `projectile-mode' if ARG is positive, otherwise disable
+it.
+
+When called from Lisp, enable `projectile-mode' if ARG is omitted,
+nil or positive.  If ARG is `toggle', toggle `projectile-mode'.
+Otherwise behave as if called interactively.
+
+\\{projectile-mode-map}
+
+\(fn &optional ARG)" t nil)
+
+(define-obsolete-function-alias 'projectile-global-mode 'projectile-mode "1.0")
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; projectile-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/projectile-20180711.102/projectile-pkg.el b/configs/shared/emacs/.emacs.d/elpa/projectile-20180711.102/projectile-pkg.el
new file mode 100644
index 0000000000..def27d6ac3
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/projectile-20180711.102/projectile-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "projectile" "20180711.102" "Manage and navigate projects in Emacs easily" '((emacs "25.1") (pkg-info "0.4")))
diff --git a/configs/shared/emacs/.emacs.d/elpa/projectile-20180711.102/projectile.el b/configs/shared/emacs/.emacs.d/elpa/projectile-20180711.102/projectile.el
new file mode 100644
index 0000000000..bd1b0f8428
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/projectile-20180711.102/projectile.el
@@ -0,0 +1,4000 @@
+;;; projectile.el --- Manage and navigate projects in Emacs easily -*- lexical-binding: t -*-
+
+;; Copyright © 2011-2018 Bozhidar Batsov <bozhidar@batsov.com>
+
+;; Author: Bozhidar Batsov <bozhidar@batsov.com>
+;; URL: https://github.com/bbatsov/projectile
+;; Package-Version: 20180711.102
+;; Keywords: project, convenience
+;; Version: 1.0.0-snapshot
+;; Package-Requires: ((emacs "25.1") (pkg-info "0.4"))
+
+;; This file is NOT part of GNU Emacs.
+
+;; This program 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, or (at your option)
+;; any later version.
+;;
+;; This program 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; see the file COPYING.  If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+;;
+;; This library provides easy project management and navigation.  The
+;; concept of a project is pretty basic - just a folder containing
+;; special file.  Currently git, mercurial and bazaar repos are
+;; considered projects by default.  If you want to mark a folder
+;; manually as a project just create an empty .projectile file in
+;; it.  See the README for more details.
+;;
+;;; Code:
+
+(require 'cl-lib)
+(require 'thingatpt)
+(require 'ibuffer)
+(require 'ibuf-ext)
+(require 'compile)
+(require 'grep)
+(require 'subr-x)
+
+(eval-when-compile
+  (defvar ag-ignore-list)
+  (defvar ggtags-completion-table)
+  (defvar tags-completion-table)
+  (defvar tags-loop-scan)
+  (defvar tags-loop-operate)
+  (defvar eshell-buffer-name)
+  (defvar explicit-shell-file-name))
+
+(declare-function ggtags-ensure-project "ggtags")
+(declare-function ggtags-update-tags "ggtags")
+(declare-function pkg-info-version-info "pkg-info")
+(declare-function tags-completion-table "etags")
+(declare-function make-term "term")
+(declare-function term-mode "term")
+(declare-function term-char-mode "term")
+
+(defvar grep-files-aliases)
+(defvar grep-find-ignored-directories)
+(defvar grep-find-ignored-files)
+
+
+;;; Customization
+(defgroup projectile nil
+  "Manage and navigate projects easily."
+  :group 'tools
+  :group 'convenience
+  :link '(url-link :tag "Github" "https://github.com/bbatsov/projectile")
+  :link '(url-link :tag "Online Manual" "https://projectile.readthedocs.io/")
+  :link '(emacs-commentary-link :tag "Commentary" "projectile"))
+
+(defcustom projectile-indexing-method (if (eq system-type 'windows-nt) 'native 'alien)
+  "Specifies the indexing method used by Projectile.
+
+There are two indexing methods - native and alien.
+
+The native method is implemented in Emacs Lisp (therefore it is
+native to Emacs).  Its advantage is that it is portable and will
+work everywhere that Emacs does.  Its disadvantage is that it is a
+bit slow (especially for large projects).  Generally it's a good
+idea to pair the native indexing method with caching.
+
+The alien indexing method uses external tools (e.g. git, find,
+etc) to speed up the indexing process.  The disadvantage of this
+method is that it's not well supported on Windows systems.
+
+By default alien indexing is the default on all operating
+systems, except Windows."
+  :group 'projectile
+  :type '(radio
+          (const :tag "Native" native)
+          (const :tag "Alien" alien)))
+
+(defcustom projectile-enable-caching (eq projectile-indexing-method 'native)
+  "When t enables project files caching.
+
+Project caching is automatically enabled by default if you're
+using the native indexing method."
+  :group 'projectile
+  :type 'boolean)
+
+(defcustom projectile-file-exists-local-cache-expire nil
+  "Number of seconds before file existence cache expires for a
+file on a local file system.
+
+ A value of nil disables this cache."
+
+  :group 'projectile
+  :type '(choice (const :tag "Disabled" nil)
+                 (integer :tag "Seconds")))
+
+(defcustom projectile-file-exists-remote-cache-expire (* 5 60)
+  "Number of seconds before file existence cache expires for a
+file on a remote file system such as tramp.
+
+ A value of nil disables this cache."
+  :group 'projectile
+  :type '(choice (const :tag "Disabled" nil)
+                 (integer :tag "Seconds")))
+
+(defcustom projectile-files-cache-expire nil
+  "Number of seconds before files list cache expires.
+
+ A value of nil means the cache never expires."
+  :group 'projectile
+  :type '(choice (const :tag "Disabled" nil)
+                 (integer :tag "Seconds")))
+
+(defcustom projectile-require-project-root t
+  "Require the presence of a project root to operate when true.
+Otherwise consider the current directory the project root."
+  :group 'projectile
+  :type 'boolean)
+
+(defcustom projectile-completion-system 'ido
+  "The completion system to be used by Projectile."
+  :group 'projectile
+  :type '(radio
+          (const :tag "Ido" ido)
+          (const :tag "Helm" helm)
+          (const :tag "Ivy" ivy)
+          (const :tag "Default" default)
+          (function :tag "Custom function")))
+
+(defcustom projectile-keymap-prefix (kbd "C-c p")
+  "Projectile keymap prefix."
+  :group 'projectile
+  :type 'string)
+
+(defcustom projectile-cache-file
+  (expand-file-name "projectile.cache" user-emacs-directory)
+  "The name of Projectile's cache file."
+  :group 'projectile
+  :type 'string)
+
+(defcustom projectile-tags-file-name "TAGS"
+  "The tags filename Projectile's going to use."
+  :group 'projectile
+  :type 'string)
+
+(defcustom projectile-tags-command "ctags -Re -f \"%s\" %s"
+  "The command Projectile's going to use to generate a TAGS file."
+  :group 'projectile
+  :type 'string)
+
+(defcustom projectile-tags-backend 'auto
+  "The tag backend that Projectile should use.
+
+If set to 'auto', `projectile-find-tag' will automatically choose
+which backend to use.  Preference order is ggtags -> xref
+-> etags-select -> `find-tag'.  Variable can also be set to specify which
+backend to use.  If selected backend is unavailable, fall back to
+`find-tag'.
+
+If this variable is set to 'auto' and ggtags is available, or if
+set to 'ggtags', then ggtags will be used for
+`projectile-regenerate-tags'.  For all other settings
+`projectile-tags-command' will be used."
+  :group 'projectile
+  :type '(radio
+          (const :tag "auto" auto)
+          (const :tag "xref" xref)
+          (const :tag "ggtags" ggtags)
+          (const :tag "etags" etags-select)
+          (const :tag "standard" find-tag))
+  :package-version '(projectile . "0.14.0"))
+
+(defcustom projectile-sort-order 'default
+  "The sort order used for a project's files."
+  :group 'projectile
+  :type '(radio
+          (const :tag "default" default)
+          (const :tag "recentf" recentf)
+          (const :tag "recently active" recently-active)
+          (const :tag "access time" access-time)
+          (const :tag "modification time" modification-time)))
+
+(defcustom projectile-verbose t
+  "Echo messages that are not errors."
+  :group 'projectile
+  :type 'boolean)
+
+(defcustom projectile-buffers-filter-function nil
+  "A function used to filter the buffers in `projectile-project-buffers'.
+
+The function should accept and return a list of Emacs buffers.
+Two example filter functions are shipped by default -
+`projectile-buffers-with-file' and
+`projectile-buffers-with-file-or-process'."
+  :group 'projectile
+  :type 'function)
+
+(defcustom projectile-project-name nil
+  "If this value is non-nil, it will be used as project name.
+
+It has precedence over function `projectile-project-name-function'."
+  :group 'projectile
+  :type 'string
+  :package-version '(projectile . "0.14.0"))
+
+(defcustom projectile-project-name-function 'projectile-default-project-name
+  "A function that receives the project-root and returns the project name.
+
+If variable `projectile-project-name' is non-nil, this function will not be used."
+  :group 'projectile
+  :type 'function
+  :package-version '(projectile . "0.14.0"))
+
+(defcustom projectile-project-root-files
+  '("rebar.config"       ; Rebar project file
+    "project.clj"        ; Leiningen project file
+    "build.boot"         ; Boot-clj project file
+    "deps.edn"           ; Clojure CLI project file
+    "SConstruct"         ; Scons project file
+    "pom.xml"            ; Maven project file
+    "build.sbt"          ; SBT project file
+    "gradlew"            ; Gradle wrapper script
+    "build.gradle"       ; Gradle project file
+    ".ensime"            ; Ensime configuration file
+    "Gemfile"            ; Bundler file
+    "requirements.txt"   ; Pip file
+    "setup.py"           ; Setuptools file
+    "tox.ini"            ; Tox file
+    "composer.json"      ; Composer project file
+    "Cargo.toml"         ; Cargo project file
+    "mix.exs"            ; Elixir mix project file
+    "stack.yaml"         ; Haskell's stack tool based project
+    "info.rkt"           ; Racket package description file
+    "DESCRIPTION"        ; R package description file
+    "TAGS"               ; etags/ctags are usually in the root of project
+    "GTAGS"              ; GNU Global tags
+    "configure.in"       ; autoconf old style
+    "configure.ac"       ; autoconf new style
+    "cscope.out"         ; cscope
+    )
+  "A list of files considered to mark the root of a project.
+The topmost match has precedence."
+  :group 'projectile
+  :type '(repeat string))
+
+(defcustom projectile-project-root-files-bottom-up
+  '(".projectile" ; projectile project marker
+    ".git"        ; Git VCS root dir
+    ".hg"         ; Mercurial VCS root dir
+    ".fslckout"   ; Fossil VCS root dir
+    "_FOSSIL_"    ; Fossil VCS root DB on Windows
+    ".bzr"        ; Bazaar VCS root dir
+    "_darcs"      ; Darcs VCS root dir
+    )
+  "A list of files considered to mark the root of a project.
+The bottommost (parentmost) match has precedence."
+  :group 'projectile
+  :type '(repeat string))
+
+(defcustom projectile-project-root-files-top-down-recurring
+  '(".svn" ; Svn VCS root dir
+    "CVS"  ; Csv VCS root dir
+    "Makefile")
+  "A list of files considered to mark the root of a project.
+The search starts at the top and descends down till a directory
+that contains a match file but its parent does not.  Thus, it's a
+bottommost match in the topmost sequence of directories
+containing a root file."
+  :group 'projectile
+  :type '(repeat string))
+
+(defcustom projectile-project-root-files-functions
+  '(projectile-root-local
+    projectile-root-bottom-up
+    projectile-root-top-down
+    projectile-root-top-down-recurring)
+  "A list of functions for finding project roots."
+  :group 'projectile
+  :type '(repeat function))
+
+(defcustom projectile-globally-ignored-files
+  (list projectile-tags-file-name)
+  "A list of files globally ignored by projectile."
+  :group 'projectile
+  :type '(repeat string))
+
+(defcustom projectile-globally-unignored-files nil
+  "A list of files globally unignored by projectile."
+  :group 'projectile
+  :type '(repeat string)
+  :package-version '(projectile . "0.14.0"))
+
+(defcustom projectile-globally-ignored-file-suffixes
+  nil
+  "A list of file suffixes globally ignored by projectile."
+  :group 'projectile
+  :type '(repeat string))
+
+(defcustom projectile-globally-ignored-directories
+  '(".idea"
+    ".ensime_cache"
+    ".eunit"
+    ".git"
+    ".hg"
+    ".fslckout"
+    "_FOSSIL_"
+    ".bzr"
+    "_darcs"
+    ".tox"
+    ".svn"
+    ".stack-work")
+  "A list of directories globally ignored by projectile."
+  :safe (lambda (x) (not (remq t (mapcar #'stringp x))))
+  :group 'projectile
+  :type '(repeat string))
+
+(defcustom projectile-globally-unignored-directories nil
+  "A list of directories globally unignored by projectile."
+  :group 'projectile
+  :type '(repeat string)
+  :package-version '(projectile . "0.14.0"))
+
+(defcustom projectile-globally-ignored-modes
+  '("erc-mode"
+    "help-mode"
+    "completion-list-mode"
+    "Buffer-menu-mode"
+    "gnus-.*-mode"
+    "occur-mode")
+  "A list of regular expressions for major modes ignored by projectile.
+
+If a buffer is using a given major mode, projectile will ignore
+it for functions working with buffers."
+  :group 'projectile
+  :type '(repeat string))
+
+(defcustom projectile-globally-ignored-buffers nil
+  "A list of buffer-names ignored by projectile.
+
+If a buffer is in the list projectile will ignore
+it for functions working with buffers."
+  :group 'projectile
+  :type '(repeat string)
+  :package-version '(projectile . "0.12.0"))
+
+(defcustom projectile-find-file-hook nil
+  "Hooks run when a file is opened with `projectile-find-file'."
+  :group 'projectile
+  :type 'hook)
+
+(defcustom projectile-find-dir-hook nil
+  "Hooks run when a directory is opened with `projectile-find-dir'."
+  :group 'projectile
+  :type 'hook)
+
+(defcustom projectile-switch-project-action 'projectile-find-file
+  "Action invoked after switching projects with `projectile-switch-project'.
+
+Any function that does not take arguments will do."
+  :group 'projectile
+  :type 'function)
+
+(defcustom projectile-find-dir-includes-top-level nil
+  "If true, add top-level dir to options offered by `projectile-find-dir'."
+  :group 'projectile
+  :type 'boolean)
+
+(defcustom projectile-use-git-grep nil
+  "If true, use `vc-git-grep' in git projects."
+  :group 'projectile
+  :type 'boolean)
+
+(defcustom projectile-grep-finished-hook nil
+  "Hooks run when `projectile-grep' finishes."
+  :group 'projectile
+  :type 'hook
+  :package-version '(projectile . "0.14.0"))
+
+(defcustom projectile-test-prefix-function 'projectile-test-prefix
+  "Function to find test files prefix based on PROJECT-TYPE."
+  :group 'projectile
+  :type 'function)
+
+(defcustom projectile-test-suffix-function 'projectile-test-suffix
+  "Function to find test files suffix based on PROJECT-TYPE."
+  :group 'projectile
+  :type 'function)
+
+
+;;; Idle Timer
+(defvar projectile-idle-timer nil
+  "The timer object created when `projectile-enable-idle-timer' is non-nil.")
+
+(defcustom projectile-idle-timer-seconds 30
+  "The idle period to use when `projectile-enable-idle-timer' is non-nil."
+  :group 'projectile
+  :type 'number)
+
+(defcustom projectile-idle-timer-hook '(projectile-regenerate-tags)
+  "The hook run when `projectile-enable-idle-timer' is non-nil."
+  :group 'projectile
+  :type '(repeat symbol))
+
+(defcustom projectile-enable-idle-timer nil
+  "Enables idle timer hook `projectile-idle-timer-functions'.
+
+When `projectile-enable-idle-timer' is non-nil, the hook
+`projectile-idle-timer-hook' is run each time Emacs has been idle
+for `projectile-idle-timer-seconds' seconds and we're in a
+project."
+  :group 'projectile
+  :set (lambda (symbol value)
+         (set symbol value)
+         (when projectile-idle-timer
+           (cancel-timer projectile-idle-timer))
+         (setq projectile-idle-timer nil)
+         (when projectile-enable-idle-timer
+           (setq projectile-idle-timer (run-with-idle-timer
+                                        projectile-idle-timer-seconds t
+                                        (lambda ()
+                                          (when (projectile-project-p)
+                                            (run-hooks 'projectile-idle-timer-hook)))))))
+  :type 'boolean)
+
+;;; Serialization
+(defun projectile-serialize (data filename)
+  "Serialize DATA to FILENAME.
+
+The saved data can be restored with `projectile-unserialize'."
+  (when (file-writable-p filename)
+    (with-temp-file filename
+      (insert (let (print-length) (prin1-to-string data))))))
+
+(defun projectile-unserialize (filename)
+  "Read data serialized by `projectile-serialize' from FILENAME."
+  (with-demoted-errors
+      "Error during file deserialization: %S"
+    (when (file-exists-p filename)
+      (with-temp-buffer
+        (insert-file-contents filename)
+        ;; this will blow up if the contents of the file aren't
+        ;; lisp data structures
+        (read (buffer-string))))))
+
+(defvar projectile-projects-cache nil
+  "A hashmap used to cache project file names to speed up related operations.")
+
+(defvar projectile-projects-cache-time nil
+  "A hashmap used to record when we populated `projectile-projects-cache'.")
+
+(defvar projectile-project-root-cache (make-hash-table :test 'equal)
+  "Cached value of function `projectile-project-root`.")
+
+(defvar projectile-project-type-cache (make-hash-table :test 'equal)
+  "A hashmap used to cache project type to speed up related operations.")
+
+(defvar projectile-known-projects nil
+  "List of locations where we have previously seen projects.
+The list of projects is ordered by the time they have been accessed.
+
+See also `projectile-remove-known-project',
+`projectile-cleanup-known-projects' and `projectile-clear-known-projects'.")
+
+(defvar projectile-known-projects-on-file nil
+  "List of known projects reference point.
+
+Contains a copy of `projectile-known-projects' when it was last
+synchronized with `projectile-known-projects-file'.")
+
+(defcustom projectile-known-projects-file
+  (expand-file-name "projectile-bookmarks.eld"
+                    user-emacs-directory)
+  "Name and location of the Projectile's known projects file."
+  :group 'projectile
+  :type 'string)
+
+(defcustom projectile-ignored-projects nil
+  "A list of projects not to be added to `projectile-known-projects'."
+  :group 'projectile
+  :type '(repeat :tag "Project list" directory)
+  :package-version '(projectile . "0.11.0"))
+
+(defcustom projectile-ignored-project-function nil
+  "Function to decide if a project is added to `projectile-known-projects'.
+
+Can be either nil, or a function that takes the truename of the
+project root as argument and returns non-nil if the project is to
+be ignored or nil otherwise.
+
+This function is only called if the project is not listed in
+`projectile-ignored-projects'.
+
+A suitable candidate would be `file-remote-p' to ignore remote
+projects."
+  :group 'projectile
+  :type '(choice
+          (const :tag "Nothing" nil)
+          (const :tag "Remote files" file-remote-p)
+          function)
+  :package-version '(projectile . "0.13.0"))
+
+(defcustom projectile-track-known-projects-automatically t
+  "Controls whether Projectile will automatically register known projects.
+
+When set to nil you'll have always add projects explicitly with
+`projectile-add-known-project'."
+  :group 'projectile
+  :type 'boolean
+  :package-version '(projectile . "1.0.0"))
+
+(defcustom projectile-project-search-path nil
+  "List of folders where projectile is automatically going to look for projects.
+You can think of something like $PATH, but for projects instead of executables.
+Examples of such paths might be ~/projects, ~/work, etc."
+  :group 'projectile
+  :type 'list
+  :package-version '(projectile . "1.0.0"))
+
+
+;;; Version information
+
+;;;###autoload
+(defun projectile-version (&optional show-version)
+  "Get the Projectile version as string.
+
+If called interactively or if SHOW-VERSION is non-nil, show the
+version in the echo area and the messages buffer.
+
+The returned string includes both, the version from package.el
+and the library version, if both a present and different.
+
+If the version number could not be determined, signal an error,
+if called interactively, or if SHOW-VERSION is non-nil, otherwise
+just return nil."
+  (interactive (list t))
+  (if (require 'pkg-info nil t)
+      (let ((version (pkg-info-version-info 'projectile)))
+        (when show-version
+          (message "Projectile %s" version))
+        version)
+    (error "Cannot determine version without package pkg-info")))
+
+
+;;; Caching
+(defvar projectile-file-exists-cache
+  (make-hash-table :test 'equal)
+  "Cached `projectile-file-exists-p' results.")
+
+(defvar projectile-file-exists-cache-timer nil
+  "Timer for scheduling`projectile-file-exists-cache-cleanup'.")
+
+(defun projectile-file-exists-cache-cleanup ()
+  "Removed timed out cache entries and reschedules or remove the
+timer if no more items are in the cache."
+  (let ((now (current-time)))
+    (maphash (lambda (key value)
+               (if (time-less-p (cdr value) now)
+                   (remhash key projectile-file-exists-cache)))
+             projectile-file-exists-cache)
+    (setq projectile-file-exists-cache-timer
+          (if (> (hash-table-count projectile-file-exists-cache) 0)
+              (run-with-timer 10 nil 'projectile-file-exists-cache-cleanup)))))
+
+(defun projectile-file-exists-p (filename)
+  "Return t if file FILENAME exist.
+A wrapper around `file-exists-p' with additional caching support."
+  (let* ((file-remote (file-remote-p filename))
+         (expire-seconds
+          (if file-remote
+              (and projectile-file-exists-remote-cache-expire
+                   (> projectile-file-exists-remote-cache-expire 0)
+                   projectile-file-exists-remote-cache-expire)
+            (and projectile-file-exists-local-cache-expire
+                 (> projectile-file-exists-local-cache-expire 0)
+                 projectile-file-exists-local-cache-expire)))
+         (remote-file-name-inhibit-cache (if expire-seconds
+                                             expire-seconds
+                                           remote-file-name-inhibit-cache)))
+    (if (not expire-seconds)
+        (file-exists-p filename)
+      (let* ((current-time (current-time))
+             (cached (gethash filename projectile-file-exists-cache))
+             (cached-value (if cached (car cached)))
+             (cached-expire (if cached (cdr cached)))
+             (cached-expired (if cached (time-less-p cached-expire current-time) t))
+             (value (or (and (not cached-expired) cached-value)
+                        (if (file-exists-p filename) 'found 'notfound))))
+        (when (or (not cached) cached-expired)
+          (puthash filename
+                   (cons value (time-add current-time (seconds-to-time expire-seconds)))
+                   projectile-file-exists-cache))
+        (unless projectile-file-exists-cache-timer
+          (setq projectile-file-exists-cache-timer
+                (run-with-timer 10 nil 'projectile-file-exists-cache-cleanup)))
+        (equal value 'found)))))
+
+;;;###autoload
+(defun projectile-invalidate-cache (arg)
+  "Remove the current project's files from `projectile-projects-cache'.
+
+With a prefix argument ARG prompts for the name of the project whose cache
+to invalidate."
+  (interactive "P")
+  (let ((project-root
+         (if arg
+             (completing-read "Remove cache for: "
+                              (projectile-hash-keys projectile-projects-cache))
+           (projectile-project-root))))
+    (setq projectile-project-root-cache (make-hash-table :test 'equal))
+    (remhash project-root projectile-project-type-cache)
+    (remhash project-root projectile-projects-cache)
+    (remhash project-root projectile-projects-cache-time)
+    (projectile-serialize-cache)
+    (when projectile-verbose
+      (message "Invalidated Projectile cache for %s."
+               (propertize project-root 'face 'font-lock-keyword-face))))
+  (when (fboundp 'recentf-cleanup)
+    (recentf-cleanup)))
+
+(defun projectile-time-seconds ()
+  "Return the number of seconds since the unix epoch."
+  (cl-destructuring-bind (high low _usec _psec) (current-time)
+    (+ (lsh high 16) low)))
+
+(defun projectile-cache-project (project files)
+  "Cache PROJECTs FILES.
+The cache is created both in memory and on the hard drive."
+  (when projectile-enable-caching
+    (puthash project files projectile-projects-cache)
+    (puthash project (projectile-time-seconds) projectile-projects-cache-time)
+    (projectile-serialize-cache)))
+
+;;;###autoload
+(defun projectile-purge-file-from-cache (file)
+  "Purge FILE from the cache of the current project."
+  (interactive
+   (list (projectile-completing-read
+          "Remove file from cache: "
+          (projectile-current-project-files))))
+  (let* ((project-root (projectile-project-root))
+         (project-cache (gethash project-root projectile-projects-cache)))
+    (if (projectile-file-cached-p file project-root)
+        (progn
+          (puthash project-root (remove file project-cache) projectile-projects-cache)
+          (projectile-serialize-cache)
+          (when projectile-verbose
+            (message "%s removed from cache" file)))
+      (error "%s is not in the cache" file))))
+
+;;;###autoload
+(defun projectile-purge-dir-from-cache (dir)
+  "Purge DIR from the cache of the current project."
+  (interactive
+   (list (projectile-completing-read
+          "Remove directory from cache: "
+          (projectile-current-project-dirs))))
+  (let* ((project-root (projectile-project-root))
+         (project-cache (gethash project-root projectile-projects-cache)))
+    (puthash project-root
+             (cl-remove-if (lambda (str) (string-prefix-p dir str)) project-cache)
+             projectile-projects-cache)))
+
+(defun projectile-file-cached-p (file project)
+  "Check if FILE is already in PROJECT cache."
+  (member file (gethash project projectile-projects-cache)))
+
+;;;###autoload
+(defun projectile-cache-current-file ()
+  "Add the currently visited file to the cache."
+  (interactive)
+  (let ((current-project (projectile-project-root)))
+    (when (and (buffer-file-name) (gethash (projectile-project-root) projectile-projects-cache))
+      (let* ((abs-current-file (file-truename (buffer-file-name)))
+             (current-file (file-relative-name abs-current-file current-project)))
+        (unless (or (projectile-file-cached-p current-file current-project)
+                    (projectile-ignored-directory-p (file-name-directory abs-current-file))
+                    (projectile-ignored-file-p abs-current-file))
+          (puthash current-project
+                   (cons current-file (gethash current-project projectile-projects-cache))
+                   projectile-projects-cache)
+          (projectile-serialize-cache)
+          (message "File %s added to project %s cache."
+                   (propertize current-file 'face 'font-lock-keyword-face)
+                   (propertize current-project 'face 'font-lock-keyword-face)))))))
+
+;; cache opened files automatically to reduce the need for cache invalidation
+(defun projectile-cache-files-find-file-hook ()
+  "Function for caching files with `find-file-hook'."
+  (let ((project-root (projectile-project-p)))
+    (when (and projectile-enable-caching
+               project-root
+               (not (projectile-ignored-project-p project-root)))
+      (projectile-cache-current-file))))
+
+(defun projectile-track-known-projects-find-file-hook ()
+  "Function for caching projects with `find-file-hook'."
+  (when (and projectile-track-known-projects-automatically (projectile-project-p))
+    (let ((known-projects (and (sequencep projectile-known-projects)
+                               (copy-sequence projectile-known-projects))))
+      (projectile-add-known-project (projectile-project-root))
+      (unless (equal known-projects projectile-known-projects)
+        (projectile-merge-known-projects)))))
+
+
+(defun projectile-maybe-invalidate-cache (force)
+  "Invalidate if FORCE or project's dirconfig newer than cache."
+  (when (or force (file-newer-than-file-p (projectile-dirconfig-file)
+                                          projectile-cache-file))
+    (projectile-invalidate-cache nil)))
+
+;;;###autoload
+(defun projectile-discover-projects-in-directory (directory)
+  "Discover any projects in DIRECTORY and add them to the projectile cache.
+This function is not recursive and only adds projects with roots
+at the top level of DIRECTORY."
+  (interactive
+   (list (read-directory-name "Starting directory: ")))
+  (let ((subdirs (directory-files directory t)))
+    (mapcar
+     (lambda (dir)
+       (when (and (file-directory-p dir)
+                  (not (member (file-name-nondirectory dir) '(".." "."))))
+         (let ((default-directory dir)
+               (projectile-cached-project-root dir))
+           (when (projectile-project-p)
+             (projectile-add-known-project (projectile-project-root))))))
+     subdirs)))
+
+(defun projectile-discover-projects-in-search-path ()
+  "Discover projects in `projectile-project-search-path'.
+Invoked automatically when `projectile-mode' is enabled."
+  (interactive)
+  (mapcar #'projectile-discover-projects-in-directory projectile-project-search-path))
+
+
+(defadvice delete-file (before purge-from-projectile-cache (filename &optional trash))
+  (if (and projectile-enable-caching (projectile-project-p))
+      (let* ((project-root (projectile-project-root))
+             (true-filename (file-truename filename))
+             (relative-filename (file-relative-name true-filename project-root)))
+        (if (projectile-file-cached-p relative-filename project-root)
+            (projectile-purge-file-from-cache relative-filename)))))
+
+
+;;; Project root related utilities
+(defun projectile-parent (path)
+  "Return the parent directory of PATH.
+PATH may be a file or directory and directory paths may end with a slash."
+  (directory-file-name (file-name-directory (directory-file-name (expand-file-name path)))))
+
+(defun projectile-locate-dominating-file (file name)
+  "Look up the directory hierarchy from FILE for a directory containing NAME.
+Stop at the first parent directory containing a file NAME,
+and return the directory.  Return nil if not found.
+Instead of a string, NAME can also be a predicate taking one argument
+\(a directory) and returning a non-nil value if that directory is the one for
+which we're looking."
+  ;; copied from files.el (stripped comments) emacs-24 bzr branch 2014-03-28 10:20
+  (setq file (abbreviate-file-name file))
+  (let ((root nil)
+        try)
+    (while (not (or root
+                    (null file)
+                    (string-match locate-dominating-stop-dir-regexp file)))
+      (setq try (if (stringp name)
+                    (projectile-file-exists-p (expand-file-name name file))
+                  (funcall name file)))
+      (cond (try (setq root file))
+            ((equal file (setq file (file-name-directory
+                                     (directory-file-name file))))
+             (setq file nil))))
+    (and root (expand-file-name (file-name-as-directory root)))))
+
+(defvar-local projectile-project-root nil
+  "Defines a custom Projectile project root.
+This is intended to be used as a file local variable.")
+
+(defun projectile-root-local (_dir)
+  "A simple wrapper around `projectile-project-root'."
+  projectile-project-root)
+
+(defun projectile-root-top-down (dir &optional list)
+  "Identify a project root in DIR by top-down search for files in LIST.
+If LIST is nil, use `projectile-project-root-files' instead.
+Return the first (topmost) matched directory or nil if not found."
+  (projectile-locate-dominating-file
+   dir
+   (lambda (dir)
+     (cl-find-if (lambda (f) (projectile-file-exists-p (expand-file-name f dir)))
+                 (or list projectile-project-root-files)))))
+
+(defun projectile-root-bottom-up (dir &optional list)
+  "Identify a project root in DIR by bottom-up search for files in LIST.
+If LIST is nil, use `projectile-project-root-files-bottom-up' instead.
+Return the first (bottommost) matched directory or nil if not found."
+  (cl-some (lambda (name) (projectile-locate-dominating-file dir name))
+           (or list projectile-project-root-files-bottom-up)))
+
+(defun projectile-root-top-down-recurring (dir &optional list)
+  "Identify a project root in DIR by recurring top-down search for files in LIST.
+If LIST is nil, use `projectile-project-root-files-top-down-recurring'
+instead.  Return the last (bottommost) matched directory in the
+topmost sequence of matched directories.  Nil otherwise."
+  (cl-some
+   (lambda (f)
+     (projectile-locate-dominating-file
+      dir
+      (lambda (dir)
+        (and (projectile-file-exists-p (expand-file-name f dir))
+             (or (string-match locate-dominating-stop-dir-regexp (projectile-parent dir))
+                 (not (projectile-file-exists-p (expand-file-name f (projectile-parent dir)))))))))
+   (or list projectile-project-root-files-top-down-recurring)))
+
+(defvar-local projectile-cached-project-root nil
+  "Cached root of the current Projectile project. If non-nil, it
+is used as the return value of `projectile-project-root' for
+performance (unless the variable `projectile-project-root' is
+also set). If nil, it is recalculated the next time
+`projectile-project-root' is called.
+
+This variable is reset automatically when Projectile detects that
+the `buffer-file-name' has changed. It can also be reset manually
+by calling `projectile-reset-cached-project-root'.")
+
+(defvar-local projectile-cached-buffer-file-name nil
+  "The last known value of `buffer-file-name' for the current
+buffer. This is used to detect a change in `buffer-file-name',
+which triggers a reset of `projectile-cached-project-root' and
+`projectile-cached-project-name'.")
+
+(defun projectile-project-root ()
+  "Retrieves the root directory of a project if available.
+The current directory is assumed to be the project's root otherwise.
+
+When not in project the behaviour of the function is controlled by
+`projectile-require-project-root'.  If it's set to nil the function
+will return the current directory, otherwise it'd raise an error."
+  ;; the cached value will be 'none in the case of no project root (this is to
+  ;; ensure it is not reevaluated each time when not inside a project) so use
+  ;; cl-subst to replace this 'none value with nil so a nil value is used
+  ;; instead
+  (or (cl-subst nil 'none
+                (or (and projectile-cached-buffer-file-name
+                         (equal projectile-cached-buffer-file-name (or buffer-file-name 'none))
+                         projectile-cached-project-root)
+                    (progn
+                      (setq projectile-cached-buffer-file-name (or buffer-file-name 'none))
+                      (setq projectile-cached-project-root
+                            ;; The `is-local' and `is-connected' variables are
+                            ;; used to fix the behavior where Emacs hangs
+                            ;; because of Projectile when you open a file over
+                            ;; TRAMP. It basically prevents Projectile from
+                            ;; trying to find information about files for which
+                            ;; it's not possible to get that information right
+                            ;; now.
+                            (or (let* ((dir default-directory)
+                                       (is-local (not (file-remote-p dir)))      ;; `true' if the file is local
+                                       (is-connected (file-remote-p dir nil t))) ;; `true' if the file is remote AND we are connected to the remote
+                                  (when (or is-local is-connected)
+                                    (cl-some
+                                     (lambda (func)
+                                       (let* ((cache-key (format "%s-%s" func dir))
+                                              (cache-value (gethash cache-key projectile-project-root-cache)))
+                                         (if (and cache-value (file-exists-p cache-value))
+                                             cache-value
+                                           (let ((value (funcall func (file-truename dir))))
+                                             (puthash cache-key value projectile-project-root-cache)
+                                             value))))
+                                     projectile-project-root-files-functions)))
+                                ;; set cached to none so is non-nil so we don't try
+                                ;; and look it up again
+                                'none)))))
+      (if projectile-require-project-root
+          (error "You're not in a project")
+        default-directory)))
+
+(defun projectile-file-truename (file-name)
+  "Return the truename of FILE-NAME.
+A thin wrapper around `file-truename' that handles nil."
+  (when file-name
+    (file-truename file-name)))
+
+(defun projectile-project-p ()
+  "Check if we're in a project."
+  (condition-case nil
+      (projectile-project-root)
+    (error nil)))
+
+(defun projectile-default-project-name (project-root)
+  "Default function used create project name to be displayed based on the value of PROJECT-ROOT."
+  (file-name-nondirectory (directory-file-name project-root)))
+
+(defvar-local projectile-cached-project-name nil
+  "Cached name of the current Projectile project. If non-nil, it
+is used as the return value of `projectile-project-name' for
+performance (unless the variable `projectile-project-name' is
+also set). If nil, it is recalculated the next time
+`projectile-project-name' is called.
+
+This variable is reset automatically when Projectile detects that
+the `buffer-file-name' has changed. It can also be reset manually
+by calling `projectile-reset-cached-project-name'.")
+
+(defun projectile-reset-cached-project-root ()
+  "Reset the value of `projectile-cached-project-root' to nil.
+
+This means that it is automatically recalculated the next time
+function `projectile-project-root' is called."
+  (interactive)
+  (setq projectile-cached-project-root nil))
+
+(defun projectile-reset-cached-project-name ()
+  "Reset the value of `projectile-cached-project-name' to nil.
+
+This means that it is automatically recalculated the next time
+function `projectile-project-name' is called."
+  (interactive)
+  (setq projectile-cached-project-name nil))
+
+(defun projectile-project-name ()
+  "Return project name."
+  (or projectile-project-name
+      (and projectile-cached-buffer-file-name
+           (equal projectile-cached-buffer-file-name buffer-file-name)
+           projectile-cached-project-name)
+      (progn
+        (setq projectile-cached-buffer-file-name buffer-file-name)
+        (setq projectile-cached-project-name
+              (let ((project-root
+                     (condition-case nil
+                         (projectile-project-root)
+                       (error nil))))
+                (if project-root
+                    (funcall projectile-project-name-function project-root)
+                  "-"))))))
+
+
+;;; Project indexing
+(defun projectile-get-project-directories ()
+  "Get the list of project directories that are of interest to the user."
+  (mapcar (lambda (subdir) (concat (projectile-project-root) subdir))
+          (or (nth 0 (projectile-parse-dirconfig-file)) '(""))))
+
+(defun projectile-dir-files (directory)
+  "List the files in DIRECTORY and in its sub-directories.
+Files are returned as relative paths to the project root."
+  ;; check for a cache hit first if caching is enabled
+  (let ((files-list (and projectile-enable-caching
+                         (gethash directory projectile-projects-cache)))
+        (root (projectile-project-root)))
+    ;; cache disabled or cache miss
+    (or files-list
+        (if (eq projectile-indexing-method 'native)
+            (projectile-dir-files-native root directory)
+          ;; use external tools to get the project files
+          (projectile-adjust-files (projectile-dir-files-external root directory))))))
+
+(defun projectile-dir-files-native (root directory)
+  "Get the files for ROOT under DIRECTORY using just Emacs Lisp."
+  (let ((progress-reporter
+         (make-progress-reporter
+          (format "Projectile is indexing %s"
+                  (propertize directory 'face 'font-lock-keyword-face)))))
+    ;; we need the files with paths relative to the project root
+    (mapcar (lambda (file) (file-relative-name file root))
+            (projectile-index-directory directory (projectile-filtering-patterns)
+                                        progress-reporter))))
+
+(defun projectile-dir-files-external (root directory)
+  "Get the files for ROOT under DIRECTORY using external tools."
+  (let ((default-directory directory))
+    (mapcar (lambda (file)
+              (file-relative-name (expand-file-name file directory) root))
+            (projectile-get-repo-files))))
+
+(defcustom projectile-git-command "git ls-files -zco --exclude-standard"
+  "Command used by projectile to get the files in a git project."
+  :group 'projectile
+  :type 'string)
+
+(defcustom projectile-git-submodule-command "git submodule --quiet foreach 'echo $path' | tr '\\n' '\\0'"
+  "Command used by projectile to list submodules of a given git repository.
+Set to nil to disable listing submodules contents."
+  :group 'projectile
+  :type 'string)
+
+(defcustom projectile-git-ignored-command "git ls-files -zcoi --exclude-standard"
+  "Command used by projectile to get the ignored files in a git project."
+  :group 'projectile
+  :type 'string
+  :package-version '(projectile . "0.14.0"))
+
+(defcustom projectile-hg-command "hg locate -f -0 -I ."
+  "Command used by projectile to get the files in a hg project."
+  :group 'projectile
+  :type 'string)
+
+(defcustom projectile-fossil-command (concat "fossil ls | "
+                                             (when (string-equal system-type
+                                                                 "windows-nt")
+                                               "dos2unix | ")
+                                             "tr '\\n' '\\0'")
+  "Command used by projectile to get the files in a fossil project."
+  :group 'projectile
+  :type 'string)
+
+(defcustom projectile-bzr-command "bzr ls -R --versioned -0"
+  "Command used by projectile to get the files in a bazaar project."
+  :group 'projectile
+  :type 'string)
+
+(defcustom projectile-darcs-command "darcs show files -0 . "
+  "Command used by projectile to get the files in a darcs project."
+  :group 'projectile
+  :type 'string)
+
+(defcustom projectile-svn-command "svn list -R . | grep -v '$/' | tr '\\n' '\\0'"
+  "Command used by projectile to get the files in a svn project."
+  :group 'projectile
+  :type 'string)
+
+(defcustom projectile-generic-command "find . -type f -print0"
+  "Command used by projectile to get the files in a generic project."
+  :group 'projectile
+  :type 'string)
+
+(defcustom projectile-vcs-dirty-state '("edited" "unregistered" "needs-update" "needs-merge" "unlocked-changes" "conflict")
+  "List of states checked by `projectile-browse-dirty-projects'.
+Possible checked states are:
+\"edited\", \"unregistered\", \"needs-update\", \"needs-merge\",
+\"unlocked-changes\" and \"conflict\",
+as defined in `vc.el'."
+  :group 'projectile
+  :type '(repeat (string))
+  :package-version '(projectile . "1.0.0"))
+
+(defun projectile-get-ext-command ()
+  "Determine which external command to invoke based on the project's VCS."
+  (let ((vcs (projectile-project-vcs)))
+    (cond
+     ((eq vcs 'git) projectile-git-command)
+     ((eq vcs 'hg) projectile-hg-command)
+     ((eq vcs 'fossil) projectile-fossil-command)
+     ((eq vcs 'bzr) projectile-bzr-command)
+     ((eq vcs 'darcs) projectile-darcs-command)
+     ((eq vcs 'svn) projectile-svn-command)
+     (t projectile-generic-command))))
+
+(defun projectile-get-sub-projects-command ()
+  (let ((vcs (projectile-project-vcs)))
+    (cond
+     ((eq vcs 'git) projectile-git-submodule-command)
+     (t ""))))
+
+(defun projectile-get-ext-ignored-command ()
+  "Determine which external command to invoke based on the project's VCS."
+  (let ((vcs (projectile-project-vcs)))
+    (cond
+     ((eq vcs 'git) projectile-git-ignored-command)
+     ;; TODO: Add support for other VCS
+     (t nil))))
+
+(defun projectile-flatten (lst)
+  "Take a nested list LST and return its contents as a single, flat list."
+  (if (and (listp lst) (listp (cdr lst)))
+      (cl-mapcan 'projectile-flatten lst)
+    (list lst)))
+
+(defun projectile-get-all-sub-projects (project)
+  "Get all sub-projects for a given project.
+
+PROJECT is base directory to start search recursively."
+  (let ((submodules (projectile-get-immediate-sub-projects project)))
+    (cond
+     ((null submodules)
+      nil)
+     (t
+      (nconc submodules (projectile-flatten
+                         ;; recursively get sub-projects of each sub-project
+                         (mapcar (lambda (s)
+                                   (projectile-get-all-sub-projects s)) submodules)))))))
+
+(defun projectile-get-immediate-sub-projects (path)
+  "Get immediate sub-projects for a given project without recursing.
+
+PATH is the vcs root or project root from which to start
+searching, and should end with an appropriate path delimiter, such as
+'/' or a '\\'.
+
+If the vcs get-sub-projects query returns results outside of path,
+they are excluded from the results of this function."
+  (let* ((default-directory path)
+         ;; search for sub-projects under current project `project'
+         (submodules (mapcar
+                      (lambda (s)
+                        (file-name-as-directory (expand-file-name s default-directory)))
+                      (projectile-files-via-ext-command (projectile-get-sub-projects-command))))
+         (project-child-folder-regex
+          (concat "\\`"
+                  (regexp-quote path))))
+
+    ;; If project root is inside of an VCS folder, but not actually an
+    ;; VCS root itself, submodules external to the project will be
+    ;; included in the VCS get sub-projects result. Let's remove them.
+    (cl-remove-if-not
+     (lambda (submodule)
+       (string-match-p project-child-folder-regex
+                       submodule))
+     submodules)))
+
+(defun projectile-get-sub-projects-files ()
+  "Get files from sub-projects recursively."
+  (projectile-flatten
+   (mapcar (lambda (s)
+             (let ((default-directory s))
+               (mapcar (lambda (f)
+                         (concat s f))
+                       (projectile-files-via-ext-command projectile-git-command))))
+           (condition-case nil
+               (projectile-get-all-sub-projects (projectile-project-root))
+             (error nil)))))
+
+(defun projectile-get-repo-files ()
+  "Get a list of the files in the project, including sub-projects."
+  (cond
+   ((eq (projectile-project-vcs) 'git)
+    (nconc (projectile-files-via-ext-command (projectile-get-ext-command))
+           (projectile-get-sub-projects-files)))
+   (t (projectile-files-via-ext-command (projectile-get-ext-command)))))
+
+(defun projectile-get-repo-ignored-files ()
+  "Get a list of the files ignored in the project."
+  (let ((cmd (projectile-get-ext-ignored-command)))
+    (when cmd
+      (projectile-files-via-ext-command cmd))))
+
+(defun projectile-get-repo-ignored-directory (dir)
+  "Get a list of the files ignored in the project in the directory DIR."
+  (let ((cmd (projectile-get-ext-ignored-command)))
+    (when cmd
+      (projectile-files-via-ext-command (concat cmd " " dir)))))
+
+(defun projectile-call-process-to-string (program &rest args)
+  "Invoke the executable PROGRAM with ARGS and return the output as a string."
+  (with-temp-buffer
+    (apply 'call-process program nil (current-buffer) nil args)
+    (buffer-string)))
+
+(defun projectile-shell-command-to-string (command)
+  "Try to run COMMAND without actually using a shell and return the output.
+
+The function `eshell-search-path' will be used to search the PATH
+environment variable for an appropriate executable using the text
+occuring before the first space.  If no executable is found,
+fallback to `shell-command-to-string'."
+  (cl-destructuring-bind
+      (the-command . args) (split-string command " ")
+    (let ((binary-path (eshell-search-path the-command)))
+      (if binary-path
+          (apply 'projectile-call-process-to-string binary-path args)
+        (shell-command-to-string command)))))
+
+(defun projectile-check-vcs-status (&optional PROJECT-PATH)
+  "Check the status of the current project.
+If PROJECT-PATH is a project, check this one instead."
+  (let* ((PROJECT-PATH (or PROJECT-PATH (projectile-project-root)))
+         (project-status nil))
+    (save-excursion
+      (vc-dir PROJECT-PATH)
+      ;; wait until vc-dir is done
+      (while (vc-dir-busy) (sleep-for 0 100))
+      ;; check for status
+      (save-excursion
+        (save-match-data
+          (dolist (check projectile-vcs-dirty-state)
+            (goto-char (point-min))
+            (when (search-forward check nil t)
+              (setq project-status (cons check project-status))))))
+      (kill-buffer)
+      project-status)))
+
+(defvar projectile-cached-dirty-projects-status nil
+  "Cache of the last dirty projects check.")
+
+(defun projectile-check-vcs-status-of-known-projects ()
+  "Return the list of dirty projects.
+The list is composed of sublists~: (project-path, project-status).
+Raise an error if their is no dirty project."
+  (save-window-excursion
+    (message "Checking for modifications in known projects...")
+    (let ((projects projectile-known-projects)
+          (status ()))
+      (dolist (project projects)
+        (when (and (projectile-keep-project-p project) (not (string= 'none (projectile-project-vcs project))))
+          (let ((tmp-status (projectile-check-vcs-status project)))
+            (when tmp-status
+              (setq status (cons (list project tmp-status) status))))))
+      (when (= (length status) 0)
+        (message "No dirty projects have been found"))
+      (setq projectile-cached-dirty-projects-status status)
+      status)))
+
+(defun projectile-browse-dirty-projects (&optional cached)
+  "Browse dirty version controlled projects.
+
+With a prefix argument, or if CACHED is non-nil, try to use the cached
+dirty project list."
+  (interactive "P")
+  (let ((status (if (and cached projectile-cached-dirty-projects-status)
+                    projectile-cached-dirty-projects-status
+                  (projectile-check-vcs-status-of-known-projects)))
+        (mod-proj nil))
+    (while (not (= (length status) 0))
+      (setq mod-proj (cons (car (pop status)) mod-proj)))
+    (projectile-completing-read "Select project: " mod-proj
+                                :action 'projectile-vc)))
+
+(defun projectile-files-via-ext-command (command)
+  "Get a list of relative file names in the project root by executing COMMAND."
+  (split-string (shell-command-to-string command) "\0" t))
+
+(defun projectile-index-directory (directory patterns progress-reporter)
+  "Index DIRECTORY taking into account PATTERNS.
+The function calls itself recursively until all sub-directories
+have been indexed.  The PROGRESS-REPORTER is updated while the
+function is executing."
+  (apply 'append
+         (mapcar
+          (lambda (f)
+            (unless (or (and patterns (projectile-ignored-rel-p f directory patterns))
+                        (member (file-name-nondirectory (directory-file-name f))
+                                '("." ".." ".svn" ".cvs")))
+              (progress-reporter-update progress-reporter)
+              (if (file-directory-p f)
+                  (unless (projectile-ignored-directory-p
+                           (file-name-as-directory f))
+                    (projectile-index-directory f patterns progress-reporter))
+                (unless (projectile-ignored-file-p f)
+                  (list f)))))
+          (directory-files directory t))))
+
+(defun projectile-adjust-files (files)
+  "First remove ignored files from FILES, then add back unignored files."
+  (projectile-add-unignored (projectile-remove-ignored files)))
+
+(defun projectile-remove-ignored (files)
+  "Remove ignored files and folders from FILES.
+
+If ignored directory prefixed with '*', then ignore all
+directories/subdirectories with matching filename,
+otherwise operates relative to project root."
+  (let ((ignored-files (projectile-ignored-files-rel))
+        (ignored-dirs (projectile-ignored-directories-rel)))
+    (cl-remove-if
+     (lambda (file)
+       (or (cl-some
+            (lambda (f)
+              (string= f (file-name-nondirectory file)))
+            ignored-files)
+           (cl-some
+            (lambda (dir)
+              ;; if the directory is prefixed with '*' then ignore all directories matching that name
+              (if (string-prefix-p "*" dir)
+                  ;; remove '*' and trailing slash from ignored directory name
+                  (let ((d (substring dir 1 (if (equal (substring dir -1) "/") -1 nil))))
+                    (cl-some
+                     (lambda (p)
+                       (string= d p))
+                     ;; split path by '/', remove empty strings, and check if any subdirs match name 'd'
+                     (delete "" (split-string (or (file-name-directory file) "") "/"))))
+                (string-prefix-p dir file)))
+            ignored-dirs)
+           (cl-some
+            (lambda (suf)
+              (string-suffix-p suf file t))
+            projectile-globally-ignored-file-suffixes)))
+     files)))
+
+(defun projectile-keep-ignored-files (files)
+  "Filter FILES to retain only those that are ignored."
+  (when files
+    (cl-remove-if-not
+     (lambda (file)
+       (cl-some (lambda (f) (string-prefix-p f file)) files))
+     (projectile-get-repo-ignored-files))))
+
+(defun projectile-keep-ignored-directories (directories)
+  "Get ignored files within each of DIRECTORIES."
+  (when directories
+    (let (result)
+      (dolist (dir directories result)
+        (setq result (append result
+                             (projectile-get-repo-ignored-directory dir))))
+      result)))
+
+(defun projectile-add-unignored (files)
+  "This adds unignored files to FILES.
+
+Useful because the VCS may not return ignored files at all.  In
+this case unignored files will be absent from FILES."
+  (let ((unignored-files (projectile-keep-ignored-files
+                          (projectile-unignored-files-rel)))
+        (unignored-paths (projectile-remove-ignored
+                          (projectile-keep-ignored-directories
+                           (projectile-unignored-directories-rel)))))
+    (append files unignored-files unignored-paths)))
+
+(defun projectile-buffers-with-file (buffers)
+  "Return only those BUFFERS backed by files."
+  (cl-remove-if-not (lambda (b) (buffer-file-name b)) buffers))
+
+(defun projectile-buffers-with-file-or-process (buffers)
+  "Return only those BUFFERS backed by files or processes."
+  (cl-remove-if-not (lambda (b) (or (buffer-file-name b)
+                                    (get-buffer-process b))) buffers))
+
+(defun projectile-project-buffers ()
+  "Get a list of project buffers."
+  (let* ((project-root (projectile-project-root))
+         (all-buffers (cl-remove-if-not
+                       (lambda (buffer)
+                         (projectile-project-buffer-p buffer project-root))
+                       (buffer-list))))
+    (if projectile-buffers-filter-function
+        (funcall projectile-buffers-filter-function all-buffers)
+      all-buffers)))
+
+(defun projectile-process-current-project-buffers (action)
+  "Process the current project's buffers using ACTION."
+  (let ((project-buffers (projectile-project-buffers)))
+    (dolist (buffer project-buffers)
+      (funcall action buffer))))
+
+(defun projectile-project-buffer-files ()
+  "Get a list of project buffer files."
+  (let ((project-root (projectile-project-root)))
+    (mapcar
+     (lambda (buffer)
+       (file-relative-name
+        (buffer-file-name buffer)
+        project-root))
+     (projectile-buffers-with-file
+      (projectile-project-buffers)))))
+
+(defun projectile-project-buffer-p (buffer project-root)
+  "Check if BUFFER is under PROJECT-ROOT."
+  (with-current-buffer buffer
+    (and (not (string-prefix-p " " (buffer-name buffer)))
+         (not (projectile-ignored-buffer-p buffer))
+         (string-equal (file-remote-p default-directory)
+                       (file-remote-p project-root))
+         (not (string-match-p "^http\\(s\\)?://" default-directory))
+         (string-prefix-p project-root (file-truename default-directory) (eq system-type 'windows-nt)))))
+
+(defun projectile-ignored-buffer-p (buffer)
+  "Check if BUFFER should be ignored."
+  (or
+   (member (buffer-name buffer) projectile-globally-ignored-buffers)
+   (with-current-buffer buffer
+     (cl-some
+      (lambda (mode)
+        (string-match-p (concat "^" mode "$")
+                        (symbol-name major-mode)))
+      projectile-globally-ignored-modes))))
+
+(defun projectile-difference (list1 list2)
+  (cl-remove-if
+   (lambda (x) (member x list2))
+   list1))
+
+(defun projectile-recently-active-files ()
+  "Get list of recently active files.
+
+Files are ordered by recently active buffers, and then recently
+opened through use of recentf."
+  (let ((project-buffer-files (projectile-project-buffer-files)))
+    (append project-buffer-files
+            (projectile-difference
+             (projectile-recentf-files)
+             project-buffer-files))))
+
+(defun projectile-project-buffer-names ()
+  "Get a list of project buffer names."
+  (mapcar #'buffer-name (projectile-project-buffers)))
+
+(defun projectile-prepend-project-name (string)
+  "Prepend the current project's name to STRING."
+  (format "[%s] %s" (projectile-project-name) string))
+
+(defun projectile-read-buffer-to-switch (prompt)
+  "Read the name of a buffer to switch to, prompting with PROMPT.
+
+This function excludes the current buffer from the offered
+choices."
+  (projectile-completing-read
+   prompt
+   (delete (buffer-name (current-buffer))
+           (projectile-project-buffer-names))))
+
+;;;###autoload
+(defun projectile-switch-to-buffer ()
+  "Switch to a project buffer."
+  (interactive)
+  (switch-to-buffer
+   (projectile-read-buffer-to-switch "Switch to buffer: ")))
+
+;;;###autoload
+(defun projectile-switch-to-buffer-other-window ()
+  "Switch to a project buffer and show it in another window."
+  (interactive)
+  (switch-to-buffer-other-window
+   (projectile-read-buffer-to-switch "Switch to buffer: ")))
+
+;;;###autoload
+(defun projectile-switch-to-buffer-other-frame ()
+  "Switch to a project buffer and show it in another window."
+  (interactive)
+  (switch-to-buffer-other-frame
+   (projectile-read-buffer-to-switch "Switch to buffer: ")))
+
+;;;###autoload
+(defun projectile-display-buffer ()
+  "Display a project buffer in another window without selecting it."
+  (interactive)
+  (display-buffer
+   (projectile-completing-read
+    "Display buffer: "
+    (projectile-project-buffer-names))))
+
+;;;###autoload
+(defun projectile-project-buffers-other-buffer ()
+  "Switch to the most recently selected buffer project buffer.
+Only buffers not visible in windows are returned."
+  (interactive)
+  (switch-to-buffer (car (projectile-project-buffers-non-visible))) nil t)
+
+(defun projectile-project-buffers-non-visible ()
+  "Get a list of non visible project buffers."
+  (cl-remove-if-not
+   (lambda (buffer)
+     (not (get-buffer-window buffer 'visible)))
+   (projectile-project-buffers)))
+
+;;;###autoload
+(defun projectile-multi-occur (&optional nlines)
+  "Do a `multi-occur' in the project's buffers.
+With a prefix argument, show NLINES of context."
+  (interactive "P")
+  (multi-occur (projectile-project-buffers)
+               (car (occur-read-primary-args))
+               nlines))
+
+(defun projectile-normalise-paths (patterns)
+  "Remove leading `/' from the elements of PATTERNS."
+  (delq nil (mapcar (lambda (pat) (and (string-prefix-p "/" pat)
+                                       ;; remove the leading /
+                                       (substring pat 1)))
+                    patterns)))
+
+(defun projectile-expand-paths (paths)
+  "Expand the elements of PATHS.
+
+Elements containing wildcards are expanded and spliced into the
+resulting paths.  The returned PATHS are absolute, based on the
+projectile project root."
+  (let ((default-directory (projectile-project-root)))
+    (projectile-flatten (mapcar
+                         (lambda (pattern)
+                           (or (file-expand-wildcards pattern t)
+                               (projectile-expand-root pattern)))
+                         paths))))
+
+(defun projectile-normalise-patterns (patterns)
+  "Remove paths from PATTERNS."
+  (cl-remove-if (lambda (pat) (string-prefix-p "/" pat)) patterns))
+
+(defun projectile-make-relative-to-root (files)
+  "Make FILES relative to the project root."
+  (let ((project-root (projectile-project-root)))
+    (mapcar (lambda (f) (file-relative-name f project-root)) files)))
+
+(defun projectile-ignored-directory-p (directory)
+  "Check if DIRECTORY should be ignored."
+  (member directory (projectile-ignored-directories)))
+
+(defun projectile-ignored-file-p (file)
+  "Check if FILE should be ignored."
+  (member file (projectile-ignored-files)))
+
+(defun projectile-check-pattern-p (file pattern)
+  "Check if FILE meets PATTERN."
+  (or (string-suffix-p (directory-file-name pattern)
+                       (directory-file-name file))
+      (member file (file-expand-wildcards pattern t))))
+
+(defun projectile-ignored-rel-p (file directory patterns)
+  "Check if FILE should be ignored relative to DIRECTORY
+according to PATTERNS: (ignored . unignored)"
+  (let ((default-directory directory))
+    (and (cl-some
+          (lambda (pat) (projectile-check-pattern-p file pat))
+          (car patterns))
+         (cl-notany
+          (lambda (pat) (projectile-check-pattern-p file pat))
+          (cdr patterns)))))
+
+(defun projectile-ignored-files ()
+  "Return list of ignored files."
+  (projectile-difference
+   (mapcar
+    #'projectile-expand-root
+    (append
+     projectile-globally-ignored-files
+     (projectile-project-ignored-files)))
+   (projectile-unignored-files)))
+
+(defun projectile-ignored-directories ()
+  "Return list of ignored directories."
+  (projectile-difference
+   (mapcar
+    #'file-name-as-directory
+    (mapcar
+     #'projectile-expand-root
+     (append
+      projectile-globally-ignored-directories
+      (projectile-project-ignored-directories))))
+   (projectile-unignored-directories)))
+
+(defun projectile-ignored-directories-rel ()
+  "Return list of ignored directories, relative to the root."
+  (projectile-make-relative-to-root (projectile-ignored-directories)))
+
+(defun projectile-ignored-files-rel ()
+  "Return list of ignored files, relative to the root."
+  (projectile-make-relative-to-root (projectile-ignored-files)))
+
+(defun projectile-project-ignored-files ()
+  "Return list of project ignored files.
+Unignored files are not included."
+  (cl-remove-if 'file-directory-p (projectile-project-ignored)))
+
+(defun projectile-project-ignored-directories ()
+  "Return list of project ignored directories.
+Unignored directories are not included."
+  (cl-remove-if-not 'file-directory-p (projectile-project-ignored)))
+
+(defun projectile-paths-to-ignore ()
+  "Return a list of ignored project paths."
+  (projectile-normalise-paths (nth 1 (projectile-parse-dirconfig-file))))
+
+(defun projectile-patterns-to-ignore ()
+  "Return a list of relative file patterns."
+  (projectile-normalise-patterns (nth 1 (projectile-parse-dirconfig-file))))
+
+(defun projectile-project-ignored ()
+  "Return list of project ignored files/directories.
+Unignored files/directories are not included."
+  (let ((paths (projectile-paths-to-ignore)))
+    (projectile-expand-paths paths)))
+
+(defun projectile-unignored-files ()
+  "Return list of unignored files."
+  (mapcar
+   #'projectile-expand-root
+   (append
+    projectile-globally-unignored-files
+    (projectile-project-unignored-files))))
+
+(defun projectile-unignored-directories ()
+  "Return list of unignored directories."
+  (mapcar
+   #'file-name-as-directory
+   (mapcar
+    #'projectile-expand-root
+    (append
+     projectile-globally-unignored-directories
+     (projectile-project-unignored-directories)))))
+
+(defun projectile-unignored-directories-rel ()
+  "Return list of unignored directories, relative to the root."
+  (projectile-make-relative-to-root (projectile-unignored-directories)))
+
+(defun projectile-unignored-files-rel ()
+  "Return list of unignored files, relative to the root."
+  (projectile-make-relative-to-root (projectile-unignored-files)))
+
+(defun projectile-project-unignored-files ()
+  "Return list of project unignored files."
+  (cl-remove-if 'file-directory-p (projectile-project-unignored)))
+
+(defun projectile-project-unignored-directories ()
+  "Return list of project unignored directories."
+  (cl-remove-if-not 'file-directory-p (projectile-project-unignored)))
+
+(defun projectile-paths-to-ensure ()
+  "Return a list of unignored project paths."
+  (projectile-normalise-paths (nth 2 (projectile-parse-dirconfig-file))))
+
+(defun projectile-files-to-ensure ()
+  (projectile-flatten (mapcar (lambda (pat) (file-expand-wildcards pat t))
+                              (projectile-patterns-to-ensure))))
+
+(defun projectile-patterns-to-ensure ()
+  "Return a list of relative file patterns."
+  (projectile-normalise-patterns (nth 2 (projectile-parse-dirconfig-file))))
+
+(defun projectile-filtering-patterns ()
+  (cons (projectile-patterns-to-ignore)
+        (projectile-patterns-to-ensure)))
+
+(defun projectile-project-unignored ()
+  "Return list of project ignored files/directories."
+  (delete-dups (append (projectile-expand-paths (projectile-paths-to-ensure))
+                       (projectile-expand-paths (projectile-files-to-ensure)))))
+
+
+(defun projectile-dirconfig-file ()
+  "Return the absolute path to the project's dirconfig file."
+  (expand-file-name ".projectile" (projectile-project-root)))
+
+(defun projectile-parse-dirconfig-file ()
+  "Parse project ignore file and return directories to ignore and keep.
+
+The return value will be a list of three elements, the car being
+the list of directories to keep, the cadr being the list of files
+or directories to ignore, and the caddr being the list of files
+or directories to ensure.
+
+Strings starting with + will be added to the list of directories
+to keep, and strings starting with - will be added to the list of
+directories to ignore.  For backward compatibility, without a
+prefix the string will be assumed to be an ignore string."
+  (let (keep ignore ensure (dirconfig (projectile-dirconfig-file)))
+    (when (projectile-file-exists-p dirconfig)
+      (with-temp-buffer
+        (insert-file-contents dirconfig)
+        (while (not (eobp))
+          (pcase (char-after)
+            (?+ (push (buffer-substring (1+ (point)) (line-end-position)) keep))
+            (?- (push (buffer-substring (1+ (point)) (line-end-position)) ignore))
+            (?! (push (buffer-substring (1+ (point)) (line-end-position)) ensure))
+            (_ (push (buffer-substring (point) (line-end-position)) ignore)))
+          (forward-line)))
+      (list (mapcar (lambda (f) (file-name-as-directory (string-trim f)))
+                    (delete "" (reverse keep)))
+            (mapcar #'string-trim
+                    (delete "" (reverse ignore)))
+            (mapcar #'string-trim
+                    (delete "" (reverse ensure)))))))
+
+(defun projectile-expand-root (name)
+  "Expand NAME to project root.
+
+Never use on many files since it's going to recalculate the
+project-root for every file."
+  (expand-file-name name (projectile-project-root)))
+
+(cl-defun projectile-completing-read (prompt choices &key initial-input action)
+  "Present a project tailored PROMPT with CHOICES."
+  (let ((prompt (projectile-prepend-project-name prompt))
+        res)
+    (setq res
+          (cond
+           ((eq projectile-completion-system 'ido)
+            (ido-completing-read prompt choices nil nil initial-input))
+           ((eq projectile-completion-system 'default)
+            (completing-read prompt choices nil nil initial-input))
+           ((eq projectile-completion-system 'helm)
+            (if (and (fboundp 'helm)
+                     (fboundp 'helm-make-source))
+                (helm :sources
+                      (helm-make-source "Projectile" 'helm-source-sync
+                        :candidates choices
+                        :action (if action
+                                    (prog1 action
+                                      (setq action nil))
+                                  #'identity))
+                      :prompt prompt
+                      :input initial-input
+                      :buffer "*helm-projectile*")
+              (user-error "Please install helm from \
+https://github.com/emacs-helm/helm")))
+           ((eq projectile-completion-system 'ivy)
+            (if (fboundp 'ivy-read)
+                (ivy-read prompt choices
+                          :initial-input initial-input
+                          :action (prog1 action
+                                    (setq action nil))
+                          :caller 'projectile-completing-read)
+              (user-error "Please install ivy from \
+https://github.com/abo-abo/swiper")))
+           (t (funcall projectile-completion-system prompt choices))))
+    (if action
+        (funcall action res)
+      res)))
+
+(defun projectile-current-project-files ()
+  "Return a list of files for the current project."
+  (let (files)
+    ;; If the cache is too stale, don't use it.
+    (when projectile-files-cache-expire
+      (let ((cache-time
+             (gethash (projectile-project-root) projectile-projects-cache-time)))
+        (when (or (null cache-time)
+                  (< (+ cache-time projectile-files-cache-expire)
+                     (projectile-time-seconds)))
+          (remhash (projectile-project-root) projectile-projects-cache)
+          (remhash (projectile-project-root) projectile-projects-cache-time))))
+
+    ;; Use the cache, if requested and available.
+    (when projectile-enable-caching
+      (setq files (gethash (projectile-project-root) projectile-projects-cache)))
+
+    ;; Calculate the list of files.
+    (when (null files)
+      (when projectile-enable-caching
+        (message "Projectile is initializing cache..."))
+      (setq files (cl-mapcan
+                   #'projectile-dir-files
+                   (projectile-get-project-directories)))
+
+      ;; Save the cached list.
+      (when projectile-enable-caching
+        (projectile-cache-project (projectile-project-root) files)))
+
+    (projectile-sort-files files)))
+
+(defun projectile-process-current-project-files (action)
+  "Process the current project's files using ACTION."
+  (let ((project-files (projectile-current-project-files))
+        (default-directory (projectile-project-root)))
+    (dolist (filename project-files)
+      (funcall action filename))))
+
+(defun projectile-current-project-dirs ()
+  "Return a list of dirs for the current project."
+  (delete-dups
+   (delq nil
+         (mapcar #'file-name-directory
+                 (projectile-current-project-files)))))
+
+(defun projectile-hash-keys (hash)
+  "Return a list of all HASH keys."
+  (let (allkeys)
+    (maphash (lambda (k _v) (setq allkeys (cons k allkeys))) hash)
+    allkeys))
+
+
+;;; Interactive commands
+(defcustom projectile-other-file-alist
+  '( ;; handle C/C++ extensions
+    ("cpp" . ("h" "hpp" "ipp"))
+    ("ipp" . ("h" "hpp" "cpp"))
+    ("hpp" . ("h" "ipp" "cpp" "cc"))
+    ("cxx" . ("h" "hxx" "ixx"))
+    ("ixx" . ("h" "hxx" "cxx"))
+    ("hxx" . ("h" "ixx" "cxx"))
+    ("c"   . ("h"))
+    ("m"   . ("h"))
+    ("mm"  . ("h"))
+    ("h"   . ("c" "cc" "cpp" "ipp" "hpp" "cxx" "ixx" "hxx" "m" "mm"))
+    ("cc"  . ("h" "hh" "hpp"))
+    ("hh"  . ("cc"))
+
+    ;; vertex shader and fragment shader extensions in glsl
+    ("vert" . ("frag"))
+    ("frag" . ("vert"))
+
+    ;; handle files with no extension
+    (nil    . ("lock" "gpg"))
+    ("lock" . (""))
+    ("gpg"  . (""))
+    )
+  "Alist of extensions for switching to file with the same name,
+  using other extensions based on the extension of current
+  file."
+  :type 'alist)
+
+(defun projectile--find-other-file (&optional flex-matching ff-variant)
+  "Switch between files with the same name but different extensions.
+With FLEX-MATCHING, match any file that contains the base name of current file.
+Other file extensions can be customized with the variable
+`projectile-other-file-alist'.  With FF-VARIANT set to a defun, use that
+instead of `find-file'.   A typical example of such a defun would be
+`find-file-other-window' or `find-file-other-frame'"
+  (let ((ff (or ff-variant #'find-file))
+        (other-files (projectile-get-other-files
+                      (buffer-file-name)
+                      (projectile-current-project-files)
+                      flex-matching)))
+    (if other-files
+        (let ((file-name (if (= (length other-files) 1)
+                             (car other-files)
+                           (projectile-completing-read "Switch to: "
+                                                       other-files))))
+          (funcall ff (expand-file-name file-name
+                                        (projectile-project-root))))
+      (error "No other file found"))))
+
+;;;###autoload
+(defun projectile-find-other-file (&optional flex-matching)
+  "Switch between files with the same name but different extensions.
+With FLEX-MATCHING, match any file that contains the base name of current file.
+Other file extensions can be customized with the variable `projectile-other-file-alist'."
+  (interactive "P")
+  (projectile--find-other-file flex-matching))
+
+;;;###autoload
+(defun projectile-find-other-file-other-window (&optional flex-matching)
+  "Switch between files with the same name but different extensions in other window.
+With FLEX-MATCHING, match any file that contains the base name of current file.
+Other file extensions can be customized with the variable `projectile-other-file-alist'."
+  (interactive "P")
+  (projectile--find-other-file flex-matching
+                               #'find-file-other-window))
+
+;;;###autoload
+(defun projectile-find-other-file-other-frame (&optional flex-matching)
+  "Switch between files with the same name but different extensions in other window.
+With FLEX-MATCHING, match any file that contains the base name of current file.
+Other file extensions can be customized with the variable `projectile-other-file-alist'."
+  (interactive "P")
+  (projectile--find-other-file flex-matching
+                               #'find-file-other-frame))
+
+(defun projectile--file-name-sans-extensions (file-name)
+  "Return FILE-NAME sans any extensions.
+The extensions, in a filename, are what follows the first '.', with the exception of a leading '.'"
+  (setq file-name (file-name-nondirectory file-name))
+  (substring file-name 0 (string-match "\\..*" file-name 1)))
+
+(defun projectile--file-name-extensions (file-name)
+  "Return FILE-NAME's extensions.
+The extensions, in a filename, are what follows the first '.', with the exception of a leading '.'"
+  ;;would it make sense to return nil instead of an empty string if no extensions are found?
+  (setq file-name (file-name-nondirectory file-name))
+  (let (extensions-start)
+    (substring file-name
+               (if (setq extensions-start (string-match "\\..*" file-name 1))
+                   (1+ extensions-start)
+                 (length file-name)))))
+
+(defun projectile-associated-file-name-extensions (file-name)
+  "Return projectile-other-file-extensions associated to FILE-NAME's extensions.
+If no associated other-file-extensions for the complete (nested) extension are found, remove subextensions from FILENAME's extensions until a match is found."
+  (let ((current-extensions (projectile--file-name-extensions (file-name-nondirectory file-name)))
+        associated-extensions)
+    (catch 'break
+      (while (not (string= "" current-extensions))
+        (if (setq associated-extensions (cdr (assoc current-extensions projectile-other-file-alist)))
+            (throw 'break associated-extensions))
+        (setq current-extensions (projectile--file-name-extensions current-extensions))))))
+
+(defun projectile-get-other-files (current-file project-file-list &optional flex-matching)
+  "Narrow to files with the same names but different extensions.
+Returns a list of possible files for users to choose.
+
+With FLEX-MATCHING, match any file that contains the base name of current file"
+  (let* ((file-ext-list (projectile-associated-file-name-extensions current-file))
+         (fulldirname (if (file-name-directory current-file)
+                          (file-name-directory current-file) "./"))
+         (dirname (file-name-nondirectory (directory-file-name fulldirname)))
+         (filename (projectile--file-name-sans-extensions current-file))
+         (file-list (mapcar (lambda (ext)
+                              (if flex-matching
+                                  (concat ".*" filename ".*" "\." ext "\\'")
+                                (concat "^" filename
+                                        (unless (equal ext "")
+                                          (concat "\." ext))
+                                        "\\'")))
+                            file-ext-list))
+         (candidates (cl-remove-if-not
+                      (lambda (project-file)
+                        (string-match filename project-file))
+                      project-file-list))
+         (candidates
+          (projectile-flatten (mapcar
+                               (lambda (file)
+                                 (cl-remove-if-not
+                                  (lambda (project-file)
+                                    (string-match file
+                                                  (concat (file-name-base project-file)
+                                                          (unless (equal (file-name-extension project-file) nil)
+                                                            (concat "\." (file-name-extension project-file))))))
+                                  candidates))
+                               file-list)))
+         (candidates
+          (cl-remove-if-not (lambda (file) (not (backup-file-name-p file))) candidates))
+         (candidates
+          (cl-sort (copy-sequence candidates)
+                   (lambda (file _)
+                     (let ((candidate-dirname (file-name-nondirectory (directory-file-name (file-name-directory file)))))
+                       (unless (equal fulldirname (file-name-directory file))
+                         (equal dirname candidate-dirname)))))))
+    candidates))
+
+(defun projectile-select-files (project-files &optional arg)
+  "Select a list of files based on filename at point.
+
+With a prefix ARG invalidates the cache first."
+  (projectile-maybe-invalidate-cache arg)
+  (let* ((file (if (region-active-p)
+                   (buffer-substring (region-beginning) (region-end))
+                 (or (thing-at-point 'filename) "")))
+         (file (if (string-match "\\.?\\./" file)
+                   (file-relative-name (file-truename file) (projectile-project-root))
+                 file))
+         (files (if file
+                    (cl-remove-if-not
+                     (lambda (project-file)
+                       (string-match file project-file))
+                     project-files)
+                  nil)))
+    files))
+
+(defun projectile--find-file-dwim (invalidate-cache &optional ff-variant)
+  "Jump to a project's files using completion based on context.
+
+With a INVALIDATE-CACHE invalidates the cache first.
+
+With FF-VARIANT set to a defun, use that instead of `find-file'.
+A typical example of such a defun would be `find-file-other-window' or
+`find-file-other-frame'
+
+Subroutine for `projectile-find-file-dwim' and
+`projectile-find-file-dwim-other-window'"
+  (let* ((project-files (projectile-current-project-files))
+         (files (projectile-select-files project-files invalidate-cache))
+         (file (cond ((= (length files) 1)
+                      (car files))
+                     ((> (length files) 1)
+                      (projectile-completing-read "Switch to: " files))
+                     (t
+                      (projectile-completing-read "Switch to: " project-files))))
+         (ff (or ff-variant #'find-file)))
+    (funcall ff (expand-file-name file (projectile-project-root)))
+    (run-hooks 'projectile-find-file-hook)))
+
+;;;###autoload
+(defun projectile-find-file-dwim (&optional arg)
+  "Jump to a project's files using completion based on context.
+
+With a prefix ARG invalidates the cache first.
+
+If point is on a filename, Projectile first tries to search for that
+file in project:
+
+- If it finds just a file, it switches to that file instantly.  This works even
+if the filename is incomplete, but there's only a single file in the current project
+that matches the filename at point.  For example, if there's only a single file named
+\"projectile/projectile.el\" but the current filename is \"projectile/proj\" (incomplete),
+`projectile-find-file-dwim' still switches to \"projectile/projectile.el\" immediately
+ because this is the only filename that matches.
+
+- If it finds a list of files, the list is displayed for selecting.  A list of
+files is displayed when a filename appears more than one in the project or the
+filename at point is a prefix of more than two files in a project.  For example,
+if `projectile-find-file-dwim' is executed on a filepath like \"projectile/\", it lists
+the content of that directory.  If it is executed on a partial filename like
+ \"projectile/a\", a list of files with character 'a' in that directory is presented.
+
+- If it finds nothing, display a list of all files in project for selecting."
+  (interactive "P")
+  (projectile--find-file-dwim arg))
+
+;;;###autoload
+(defun projectile-find-file-dwim-other-window (&optional arg)
+  "Jump to a project's files using completion based on context in other window.
+
+With a prefix ARG invalidates the cache first.
+
+If point is on a filename, Projectile first tries to search for that
+file in project:
+
+- If it finds just a file, it switches to that file instantly.  This works even
+if the filename is incomplete, but there's only a single file in the current project
+that matches the filename at point.  For example, if there's only a single file named
+\"projectile/projectile.el\" but the current filename is \"projectile/proj\" (incomplete),
+`projectile-find-file-dwim-other-window' still switches to \"projectile/projectile.el\"
+immediately because this is the only filename that matches.
+
+- If it finds a list of files, the list is displayed for selecting.  A list of
+files is displayed when a filename appears more than one in the project or the
+filename at point is a prefix of more than two files in a project.  For example,
+if `projectile-find-file-dwim-other-window' is executed on a filepath like \"projectile/\", it lists
+the content of that directory.  If it is executed on a partial filename
+like \"projectile/a\", a list of files with character 'a' in that directory
+is presented.
+
+- If it finds nothing, display a list of all files in project for selecting."
+  (interactive "P")
+  (projectile--find-file-dwim arg #'find-file-other-window))
+
+;;;###autoload
+(defun projectile-find-file-dwim-other-frame (&optional arg)
+  "Jump to a project's files using completion based on context in other frame.
+
+With a prefix ARG invalidates the cache first.
+
+If point is on a filename, Projectile first tries to search for that
+file in project:
+
+- If it finds just a file, it switches to that file instantly.  This works even
+if the filename is incomplete, but there's only a single file in the current project
+that matches the filename at point.  For example, if there's only a single file named
+\"projectile/projectile.el\" but the current filename is \"projectile/proj\" (incomplete),
+`projectile-find-file-dwim-other-frame' still switches to \"projectile/projectile.el\"
+immediately because this is the only filename that matches.
+
+- If it finds a list of files, the list is displayed for selecting.  A list of
+files is displayed when a filename appears more than one in the project or the
+filename at point is a prefix of more than two files in a project.  For example,
+if `projectile-find-file-dwim-other-frame' is executed on a filepath like \"projectile/\", it lists
+the content of that directory.  If it is executed on a partial filename
+like \"projectile/a\", a list of files with character 'a' in that directory
+is presented.
+
+- If it finds nothing, display a list of all files in project for selecting."
+  (interactive "P")
+  (projectile--find-file-dwim arg #'find-file-other-frame))
+
+(defun projectile--find-file (invalidate-cache &optional ff-variant)
+  "Jump to a project's file using completion.
+With INVALIDATE-CACHE invalidates the cache first.  With FF-VARIANT set to a
+defun, use that instead of `find-file'.   A typical example of such a defun
+would be `find-file-other-window' or `find-file-other-frame'"
+  (interactive "P")
+  (projectile-maybe-invalidate-cache invalidate-cache)
+  (let ((file (projectile-completing-read "Find file: "
+                                          (projectile-current-project-files)))
+        (ff (or ff-variant #'find-file)))
+    (funcall ff (expand-file-name file (projectile-project-root)))
+    (run-hooks 'projectile-find-file-hook)))
+
+;;;###autoload
+(defun projectile-find-file (&optional arg)
+  "Jump to a project's file using completion.
+With a prefix ARG invalidates the cache first."
+  (interactive "P")
+  (projectile--find-file arg))
+
+;;;###autoload
+(defun projectile-find-file-other-window (&optional arg)
+  "Jump to a project's file using completion and show it in another window.
+
+With a prefix ARG invalidates the cache first."
+  (interactive "P")
+  (projectile--find-file arg #'find-file-other-window))
+
+;;;###autoload
+(defun projectile-find-file-other-frame (&optional arg)
+  "Jump to a project's file using completion and show it in another frame.
+
+With a prefix ARG invalidates the cache first."
+  (interactive "P")
+  (projectile--find-file arg #'find-file-other-frame))
+
+(defun projectile-sort-files (files)
+  "Sort FILES according to `projectile-sort-order'."
+  (cl-case projectile-sort-order
+    (default files)
+    (recentf (projectile-sort-by-recentf-first files))
+    (recently-active (projectile-sort-by-recently-active-first files))
+    (modification-time (projectile-sort-by-modification-time files))
+    (access-time (projectile-sort-by-access-time files))))
+
+(defun projectile-sort-by-recentf-first (files)
+  "Sort FILES by a recent first scheme."
+  (let ((project-recentf-files (projectile-recentf-files)))
+    (append project-recentf-files
+            (projectile-difference files project-recentf-files))))
+
+(defun projectile-sort-by-recently-active-first (files)
+  "Sort FILES by most recently active buffers or opened files."
+  (let ((project-recently-active-files (projectile-recently-active-files)))
+    (append project-recently-active-files
+            (projectile-difference files project-recently-active-files))))
+
+(defun projectile-sort-by-modification-time (files)
+  "Sort FILES by modification time."
+  (let ((default-directory (projectile-project-root)))
+    (cl-sort
+     (copy-sequence files)
+     (lambda (file1 file2)
+       (let ((file1-mtime (nth 5 (file-attributes file1)))
+             (file2-mtime (nth 5 (file-attributes file2))))
+         (not (time-less-p file1-mtime file2-mtime)))))))
+
+(defun projectile-sort-by-access-time (files)
+  "Sort FILES by access time."
+  (let ((default-directory (projectile-project-root)))
+    (cl-sort
+     (copy-sequence files)
+     (lambda (file1 file2)
+       (let ((file1-atime (nth 4 (file-attributes file1)))
+             (file2-atime (nth 4 (file-attributes file2))))
+         (not (time-less-p file1-atime file2-atime)))))))
+
+(defun projectile--find-dir (invalidate-cache &optional dired-variant)
+  "Jump to a project's directory using completion.
+
+With INVALIDATE-CACHE invalidates the cache first.  With DIRED-VARIANT set to a
+defun, use that instead of `dired'.  A typical example of such a defun would be
+`dired-other-window' or `dired-other-frame'"
+  (projectile-maybe-invalidate-cache invalidate-cache)
+  (let ((dir (projectile-complete-dir))
+        (dired-v (or dired-variant #'dired)))
+    (funcall dired-v (expand-file-name dir (projectile-project-root)))
+    (run-hooks 'projectile-find-dir-hook)))
+
+;;;###autoload
+(defun projectile-find-dir (&optional arg)
+  "Jump to a project's directory using completion.
+
+With a prefix ARG invalidates the cache first."
+  (interactive "P")
+  (projectile--find-dir arg))
+
+;;;###autoload
+(defun projectile-find-dir-other-window (&optional arg)
+  "Jump to a project's directory in other window using completion.
+
+With a prefix ARG invalidates the cache first."
+  (interactive "P")
+  (projectile--find-dir arg #'dired-other-window))
+
+;;;###autoload
+(defun projectile-find-dir-other-frame (&optional arg)
+  "Jump to a project's directory in other window using completion.
+
+With a prefix ARG invalidates the cache first."
+  (interactive "P")
+  (projectile--find-dir arg #'dired-other-frame))
+
+(defun projectile-complete-dir ()
+  (projectile-completing-read
+   "Find dir: "
+   (if projectile-find-dir-includes-top-level
+       (append '("./") (projectile-current-project-dirs))
+     (projectile-current-project-dirs))))
+
+;;;###autoload
+(defun projectile-find-test-file (&optional arg)
+  "Jump to a project's test file using completion.
+
+With a prefix ARG invalidates the cache first."
+  (interactive "P")
+  (projectile-maybe-invalidate-cache arg)
+  (let ((file (projectile-completing-read "Find test file: "
+                                          (projectile-current-project-test-files))))
+    (find-file (expand-file-name file (projectile-project-root)))))
+
+(defun projectile-test-files (files)
+  "Return only the test FILES."
+  (cl-remove-if-not 'projectile-test-file-p files))
+
+(defun projectile-test-file-p (file)
+  "Check if FILE is a test file."
+  (or (cl-some (lambda (pat) (string-prefix-p pat (file-name-nondirectory file)))
+               (delq nil (list (funcall projectile-test-prefix-function (projectile-project-type)))))
+      (cl-some (lambda (pat) (string-suffix-p pat (file-name-sans-extension (file-name-nondirectory file))))
+               (delq nil (list (funcall projectile-test-suffix-function (projectile-project-type)))))))
+
+(defun projectile-current-project-test-files ()
+  "Return a list of test files for the current project."
+  (projectile-test-files (projectile-current-project-files)))
+
+(defvar projectile-project-types (make-hash-table)
+  "A hash table holding all project types that are known to Projectile.")
+
+(cl-defun projectile-register-project-type
+    (project-type marker-files &key compilation-dir configure compile test run test-suffix test-prefix src-dir test-dir)
+  "Register a project type with projectile.
+
+A project type is defined by PROJECT-TYPE, a set of MARKER-FILES,
+and optional keyword arguments:
+COMPILATION-DIR the directory to run the tests- and compilations in,
+CONFIGURE which specifies a command that configures the project
+          `%s' in the command will be substituted with (projectile-project-root)
+          before the command is run,
+COMPILE which specifies a command that builds the project,
+TEST which specified a command that tests the project,
+RUN which specifies a command that runs the project,
+TEST-SUFFIX which specifies test file suffix, and
+TEST-PREFIX which specifies test file prefix.
+SRC-DIR which specifies the path to the source relative to the project root.
+TEST-DIR which specifies the path to the tests relative to the project root."
+  (let ((project-plist (list 'marker-files marker-files
+                             'compilation-dir compilation-dir
+                             'configure-command configure
+                             'compile-command compile
+                             'test-command test
+                             'run-command run)))
+    ;; There is no way for the function to distinguish between an
+    ;; explicit argument of nil and an omitted argument. However, the
+    ;; body of the function is free to consider nil an abbreviation
+    ;; for some other meaningful value
+    (when test-suffix
+      (plist-put project-plist 'test-suffix test-suffix))
+    (when test-prefix
+      (plist-put project-plist 'test-prefix test-prefix))
+    (when src-dir
+      (plist-put project-plist 'src-dir src-dir))
+    (when test-dir
+      (plist-put project-plist 'test-dir test-dir))
+    (puthash project-type project-plist
+             projectile-project-types)))
+
+(defun projectile-cabal-project-p ()
+  "Check if a project contains *.cabal files but no stack.yaml file."
+  (and (projectile-verify-file-wildcard "*.cabal")
+       (not (projectile-verify-file "stack.yaml"))))
+
+(defun projectile-go-project-p ()
+  "Check if a project contains Go source files."
+  (cl-some
+   (lambda (file)
+     (string= (file-name-extension file) "go"))
+   (projectile-current-project-files)))
+
+(defcustom projectile-go-project-test-function #'projectile-go-project-p
+  "Function to determine if project's type is go."
+  :group 'projectile
+  :type 'function)
+
+(define-obsolete-variable-alias 'projectile-go-function 'projectile-go-project-test-function "1.0.0")
+
+;;; Project type registration
+;;
+;; Project type detection happens in a reverse order with respect to
+;; project type registration (invocations of `projectile-register-project-type').
+;;
+;; As function-based project type detection is pretty slow, so it
+;; should be tried at the end if everything else failed (meaning here
+;; it should be listed first).
+;;
+;; Ideally common project types should be checked earlier than exotic ones.
+
+;; Function-based detection project type
+(projectile-register-project-type 'haskell-cabal #'projectile-cabal-project-p
+                                  :compile "cabal build"
+                                  :test "cabal test"
+                                  :test-suffix "Spec")
+(projectile-register-project-type 'go projectile-go-project-test-function
+                                  :compile "go build ./..."
+                                  :test "go test ./..."
+                                  :test-suffix "_test")
+;; File-based detection project types
+(projectile-register-project-type 'emacs-cask '("Cask")
+                                  :compile "cask install"
+                                  :test-prefix "test-"
+                                  :test-suffix "-test")
+(projectile-register-project-type 'r '("DESCRIPTION")
+                                  :compile "R CMD INSTALL --with-keep.source ."
+                                  :test (concat "R CMD check -o " temporary-file-directory " ."))
+(projectile-register-project-type 'haskell-stack '("stack.yaml")
+                                  :compile "stack build"
+                                  :test "stack build --test"
+                                  :test-suffix "Spec")
+(projectile-register-project-type 'rust-cargo '("Cargo.toml")
+                                  :compile "cargo build"
+                                  :test "cargo test")
+(projectile-register-project-type 'racket '("info.rkt")
+                                  :test "raco test .")
+;; Universal
+(projectile-register-project-type 'scons '("SConstruct")
+                                  :compile "scons"
+                                  :test "scons test"
+                                  :test-suffix "test")
+(projectile-register-project-type 'meson '("meson.build")
+                                  :compilation-dir "build"
+                                  :configure "meson %s"
+                                  :compile "ninja"
+                                  :test "ninja test")
+(projectile-register-project-type 'nix '("default.nix")
+                                  :compile "nix-build"
+                                  :test "nix-build")
+;; Make & CMake
+(projectile-register-project-type 'make '("Makefile")
+                                  :compile "make"
+                                  :test "make test")
+(projectile-register-project-type 'cmake '("CMakeLists.txt")
+                                  :configure "cmake %s"
+                                  :compile "cmake --build ."
+                                  :test "ctest")
+;; PHP
+(projectile-register-project-type 'php-symfony '("composer.json" "app" "src" "vendor")
+                                  :compile "app/console server:run"
+                                  :test "phpunit -c app "
+                                  :test-suffix "Test")
+;; Erlang & Elixir
+(projectile-register-project-type 'rebar '("rebar.config")
+                                  :compile "rebar"
+                                  :test "rebar eunit"
+                                  :test-suffix "_SUITE")
+(projectile-register-project-type 'elixir '("mix.exs")
+                                  :compile "mix compile"
+                                  :src-dir "lib/"
+                                  :test "mix test"
+                                  :test-suffix "_test")
+;; JavaScript
+(projectile-register-project-type 'grunt '("Gruntfile.js")
+                                  :compile "grunt"
+                                  :test "grunt test")
+(projectile-register-project-type 'gulp '("gulpfile.js")
+                                  :compile "gulp"
+                                  :test "gulp test")
+(projectile-register-project-type 'npm '("package.json")
+                                  :compile "npm install"
+                                  :test "npm test")
+;; Angular
+(projectile-register-project-type 'angular '("angular.json" ".angular-cli.json")
+                                  :compile "ng build"
+                                  :run "ng serve"
+                                  :test "ng test")
+;; Python
+(projectile-register-project-type 'django '("manage.py")
+                                  :compile "python manage.py runserver"
+                                  :test "python manage.py test"
+                                  :test-prefix "test_")
+(projectile-register-project-type 'python-pip '("requirements.txt")
+                                  :compile "python setup.by build"
+                                  :test "python -m unittest discover"
+                                  :test-prefix "test_")
+(projectile-register-project-type 'python-pkg '("setup.py")
+                                  :compile "python setup.py build"
+                                  :test "python -m unittest discover"
+                                  :test-prefix "test_")
+(projectile-register-project-type 'python-tox '("tox.ini")
+                                  :compile "tox -r --notest"
+                                  :test "tox"
+                                  :test-prefix "test_")
+;; Java & friends
+(projectile-register-project-type 'maven '("pom.xml")
+                                  :compile "mvn clean install"
+                                  :test "mvn test"
+                                  :test-suffix "Test"
+                                  :src-dir "main/src/"
+                                  :test-dir "main/test/")
+(projectile-register-project-type 'gradle '("build.gradle")
+                                  :compile "gradle build"
+                                  :test "gradle test"
+                                  :test-suffix "Spec")
+(projectile-register-project-type 'gradlew '("gradlew")
+                                  :compile "./gradlew build"
+                                  :test "./gradlew test"
+                                  :test-suffix "Spec")
+(projectile-register-project-type 'grails '("application.properties" "grails-app")
+                                  :compile "grails package"
+                                  :test "grails test-app"
+                                  :test-suffix "Spec")
+(projectile-register-project-type 'sbt '("build.sbt")
+                                  :compile "sbt compile"
+                                  :test "sbt test"
+                                  :test-suffix "Spec")
+(projectile-register-project-type 'lein-test '("project.clj")
+                                  :compile "lein compile"
+                                  :test "lein test"
+                                  :test-suffix "_test")
+(projectile-register-project-type 'lein-midje '("project.clj" ".midje.clj")
+                                  :compile "lein compile"
+                                  :test "lein midje"
+                                  :test-prefix "t_")
+(projectile-register-project-type 'boot-clj '("build.boot")
+                                  :compile "boot aot"
+                                  :test "boot test"
+                                  :test-suffix "_test")
+(projectile-register-project-type 'clojure-cli '("deps.edn")
+                                  :test-suffix "_test")
+;; Ruby
+(projectile-register-project-type 'ruby-rspec '("Gemfile" "lib" "spec")
+                                  :compile "bundle exec rake"
+                                  :src-dir "lib/"
+                                  :test "bundle exec rspec"
+                                  :test-dir "spec/"
+                                  :test-suffix "_spec")
+(projectile-register-project-type 'ruby-test '("Gemfile" "lib" "test")
+                                  :compile"bundle exec rake"
+                                  :src-dir "lib/"
+                                  :test "bundle exec rake test"
+                                  :test-suffix "_test")
+;; Rails needs to be registered after npm, otherwise `package.json` makes it `npm`.
+;; https://github.com/bbatsov/projectile/pull/1191
+(projectile-register-project-type 'rails-test '("Gemfile" "app" "lib" "db" "config" "test")
+                                  :compile "bundle exec rails server"
+                                  :src-dir "lib/"
+                                  :test "bundle exec rake test"
+                                  :test-suffix "_test")
+(projectile-register-project-type 'rails-rspec '("Gemfile" "app" "lib" "db" "config" "spec")
+                                  :compile "bundle exec rails server"
+                                  :src-dir "lib/"
+                                  :test "bundle exec rspec"
+                                  :test-dir "spec/"
+                                  :test-suffix "_spec")
+
+(defvar-local projectile-project-type nil
+  "Buffer local var for overriding the auto-detected project type.
+Normally you'd set this from .dir-locals.el.")
+(put 'projectile-project-type 'safe-local-variable #'symbolp)
+
+(defun projectile-detect-project-type ()
+  "Detect the type of the current project.
+Fallsback to a generic project type when the type can't be determined."
+  (let ((project-type (or (cl-find-if
+                           (lambda (project-type)
+                             (let ((marker (plist-get (gethash project-type projectile-project-types) 'marker-files)))
+                               (if (listp marker)
+                                   (and (projectile-verify-files marker) project-type)
+                                 (and (funcall marker) project-type))))
+                           (projectile-hash-keys projectile-project-types))
+                          'generic)))
+    (puthash (projectile-project-root) project-type projectile-project-type-cache)
+    project-type))
+
+(defun projectile-project-type ()
+  "Determine the project's type based on its structure.
+
+The project type is cached for improved performance."
+  (if projectile-project-type
+      projectile-project-type
+    (let ((project-root (ignore-errors (projectile-project-root))))
+      (if project-root
+          (or (gethash project-root projectile-project-type-cache)
+              (projectile-detect-project-type))
+        ;; if we're not in a project we just return nil
+        nil))))
+
+;;;###autoload
+(defun projectile-project-info ()
+  "Display info for current project."
+  (interactive)
+  (message "Project dir: %s ## Project VCS: %s ## Project type: %s"
+           (projectile-project-root)
+           (projectile-project-vcs)
+           (projectile-project-type)))
+
+(defun projectile-verify-files (files)
+  "Check whether all FILES exist in the current project."
+  (cl-every #'projectile-verify-file files))
+
+(defun projectile-verify-file (file)
+  "Check whether FILE exists in the current project."
+  (file-exists-p (projectile-expand-root file)))
+
+(defun projectile-verify-file-wildcard (file)
+  "Check whether FILE exists in the current project.
+Expands wildcards using `file-expand-wildcards' before checking."
+  (file-expand-wildcards (projectile-expand-root file)))
+
+(defun projectile-project-vcs (&optional project-root)
+  "Determine the VCS used by the project if any.
+PROJECT-ROOT is the targeted directory.  If nil, use
+`projectile-project-root'."
+  (or project-root (setq project-root (projectile-project-root)))
+  (cond
+   ((projectile-file-exists-p (expand-file-name ".git" project-root)) 'git)
+   ((projectile-file-exists-p (expand-file-name ".hg" project-root)) 'hg)
+   ((projectile-file-exists-p (expand-file-name ".fslckout" project-root)) 'fossil)
+   ((projectile-file-exists-p (expand-file-name "_FOSSIL_" project-root)) 'fossil)
+   ((projectile-file-exists-p (expand-file-name ".bzr" project-root)) 'bzr)
+   ((projectile-file-exists-p (expand-file-name "_darcs" project-root)) 'darcs)
+   ((projectile-file-exists-p (expand-file-name ".svn" project-root)) 'svn)
+   ((projectile-locate-dominating-file project-root ".git") 'git)
+   ((projectile-locate-dominating-file project-root ".hg") 'hg)
+   ((projectile-locate-dominating-file project-root ".fslckout") 'fossil)
+   ((projectile-locate-dominating-file project-root "_FOSSIL_") 'fossil)
+   ((projectile-locate-dominating-file project-root ".bzr") 'bzr)
+   ((projectile-locate-dominating-file project-root "_darcs") 'darcs)
+   ((projectile-locate-dominating-file project-root ".svn") 'svn)
+   (t 'none)))
+
+(defun projectile--test-name-for-impl-name (impl-file-path)
+  "Determine the name of the test file for IMPL-FILE-PATH."
+  (let* ((project-type (projectile-project-type))
+         (impl-file-name (file-name-sans-extension (file-name-nondirectory impl-file-path)))
+         (impl-file-ext (file-name-extension impl-file-path))
+         (test-prefix (funcall projectile-test-prefix-function project-type))
+         (test-suffix (funcall projectile-test-suffix-function project-type)))
+    (cond
+     (test-prefix (concat test-prefix impl-file-name "." impl-file-ext))
+     (test-suffix (concat impl-file-name test-suffix "." impl-file-ext))
+     (t (error "Project type `%s' not supported!" project-type)))))
+
+(defun projectile-create-test-file-for (impl-file-path)
+  "Create a test file for IMPL-FILE-PATH."
+  (let* ((test-file (projectile--test-name-for-impl-name impl-file-path))
+         (project-root (projectile-project-root))
+         (relative-dir (file-name-directory (file-relative-name impl-file-path project-root)))
+         (src-dir-name (projectile-src-directory (projectile-project-type)))
+         (test-dir-name (projectile-test-directory (projectile-project-type)))
+         (test-dir (expand-file-name (replace-regexp-in-string src-dir-name test-dir-name relative-dir) project-root))
+         (test-path (expand-file-name test-file test-dir)))
+    (unless (file-exists-p test-path)
+      (progn (unless (file-exists-p test-dir)
+               (make-directory test-dir :create-parents))
+             test-path))))
+
+(defcustom projectile-create-missing-test-files nil
+  "During toggling, if non-nil enables creating test files if not found.
+
+When not-nil, every call to projectile-find-implementation-or-test-*
+creates test files if not found on the file system.  Defaults to nil.
+It assumes the test/ folder is at the same level as src/."
+  :group 'projectile
+  :type 'boolean)
+
+(defun projectile-find-implementation-or-test (file-name)
+  "Given a FILE-NAME return the matching implementation or test filename.
+
+If `projectile-create-missing-test-files' is non-nil, create the missing
+test file."
+  (unless file-name (error "The current buffer is not visiting a file"))
+  (if (projectile-test-file-p file-name)
+      ;; find the matching impl file
+      (let ((impl-file (projectile-find-matching-file file-name)))
+        (if impl-file
+            (projectile-expand-root impl-file)
+          (error
+           "No matching source file found for project type `%s'"
+           (projectile-project-type))))
+    ;; find the matching test file
+    (let ((test-file (projectile-find-matching-test file-name)))
+      (if test-file
+          (projectile-expand-root test-file)
+        (if projectile-create-missing-test-files
+            (projectile-create-test-file-for file-name)
+          (error "No matching test file found for project type `%s'"
+                 (projectile-project-type)))))))
+
+;;;###autoload
+(defun projectile-find-implementation-or-test-other-window ()
+  "Open matching implementation or test file in other window."
+  (interactive)
+  (find-file-other-window
+   (projectile-find-implementation-or-test (buffer-file-name))))
+
+;;;###autoload
+(defun projectile-find-implementation-or-test-other-frame ()
+  "Open matching implementation or test file in other frame."
+  (interactive)
+  (find-file-other-frame
+   (projectile-find-implementation-or-test (buffer-file-name))))
+
+;;;###autoload
+(defun projectile-toggle-between-implementation-and-test ()
+  "Toggle between an implementation file and its test file."
+  (interactive)
+  (find-file
+   (projectile-find-implementation-or-test (buffer-file-name))))
+
+
+(defun projectile-project-type-attribute (project-type key &optional default-value)
+  "Return the value of some PROJECT-TYPE attribute identified by KEY.
+Fallback to DEFAULT-VALUE for missing attributes."
+  (let ((project (gethash project-type projectile-project-types)))
+    (if (and project (plist-member project key))
+        (plist-get project key)
+      default-value)))
+
+(defun projectile-test-prefix (project-type)
+  "Find default test files prefix based on PROJECT-TYPE."
+  (projectile-project-type-attribute project-type 'test-prefix))
+
+(defun projectile-test-suffix (project-type)
+  "Find default test files suffix based on PROJECT-TYPE."
+  (projectile-project-type-attribute project-type 'test-suffix))
+
+(defun projectile-src-directory (project-type)
+  "Find default src directory based on PROJECT-TYPE."
+  (projectile-project-type-attribute project-type 'src-dir "src/"))
+
+(defun projectile-test-directory (project-type)
+  "Find default test directory based on PROJECT-TYPE."
+  (projectile-project-type-attribute project-type 'test-dir "test/"))
+
+(defun projectile-dirname-matching-count (a b)
+  "Count matching dirnames ascending file paths."
+  (setq a (reverse (split-string (or (file-name-directory a) "") "/" t))
+        b (reverse (split-string (or (file-name-directory b) "") "/" t)))
+  (let ((common 0))
+    (while (and a b (string-equal (pop a) (pop b)))
+      (setq common (1+ common)))
+    common))
+
+(defun projectile-group-file-candidates (file candidates)
+  "Group file candidates by dirname matching count."
+  (cl-sort (copy-sequence
+            (let (value result)
+              (while (setq value (pop candidates))
+                (let* ((key (projectile-dirname-matching-count file value))
+                       (kv (assoc key result)))
+                  (if kv
+                      (setcdr kv (cons value (cdr kv)))
+                    (push (list key value) result))))
+              (mapcar (lambda (x)
+                        (cons (car x) (nreverse (cdr x))))
+                      (nreverse result))))
+           (lambda (a b) (> (car a) (car b)))))
+
+(defun projectile-find-matching-test (file)
+  "Compute the name of the test matching FILE."
+  (let* ((basename (file-name-nondirectory (file-name-sans-extension file)))
+         (test-prefix (funcall projectile-test-prefix-function (projectile-project-type)))
+         (test-suffix (funcall projectile-test-suffix-function (projectile-project-type)))
+         (candidates
+          (cl-remove-if-not
+           (lambda (current-file)
+             (let ((name (file-name-nondirectory
+                          (file-name-sans-extension current-file))))
+               (or (when test-prefix
+                     (string-equal name (concat test-prefix basename)))
+                   (when test-suffix
+                     (string-equal name (concat basename test-suffix))))))
+           (projectile-current-project-files))))
+    (cond
+     ((null candidates) nil)
+     ((= (length candidates) 1) (car candidates))
+     (t (let ((grouped-candidates (projectile-group-file-candidates file candidates)))
+          (if (= (length (car grouped-candidates)) 2)
+              (car (last (car grouped-candidates)))
+            (projectile-completing-read
+             "Switch to: "
+             (apply 'append (mapcar 'cdr grouped-candidates)))))))))
+
+(defun projectile-find-matching-file (test-file)
+  "Compute the name of a file matching TEST-FILE."
+  (let* ((basename (file-name-nondirectory (file-name-sans-extension test-file)))
+         (test-prefix (funcall projectile-test-prefix-function (projectile-project-type)))
+         (test-suffix (funcall projectile-test-suffix-function (projectile-project-type)))
+         (candidates
+          (cl-remove-if-not
+           (lambda (current-file)
+             (let ((name (file-name-nondirectory
+                          (file-name-sans-extension current-file))))
+               (or (when test-prefix
+                     (string-equal (concat test-prefix name) basename))
+                   (when test-suffix
+                     (string-equal (concat name test-suffix) basename)))))
+           (projectile-current-project-files))))
+    (cond
+     ((null candidates) nil)
+     ((= (length candidates) 1) (car candidates))
+     (t (let ((grouped-candidates (projectile-group-file-candidates test-file candidates)))
+          (if (= (length (car grouped-candidates)) 2)
+              (car (last (car grouped-candidates)))
+            (projectile-completing-read
+             "Switch to: "
+             (apply 'append (mapcar 'cdr grouped-candidates)))))))))
+
+(defun projectile-grep-default-files ()
+  "Try to find a default pattern for `projectile-grep'.
+This is a subset of `grep-read-files', where either a matching entry from
+`grep-files-aliases' or file name extension pattern is returned."
+  (when buffer-file-name
+    (let* ((fn (file-name-nondirectory buffer-file-name))
+           (default-alias
+             (let ((aliases (remove (assoc "all" grep-files-aliases)
+                                    grep-files-aliases))
+                   alias)
+               (while aliases
+                 (setq alias (car aliases)
+                       aliases (cdr aliases))
+                 (if (string-match (mapconcat
+                                    #'wildcard-to-regexp
+                                    (split-string (cdr alias) nil t)
+                                    "\\|")
+                                   fn)
+                     (setq aliases nil)
+                   (setq alias nil)))
+               (cdr alias)))
+           (default-extension
+             (let ((ext (file-name-extension fn)))
+               (and ext (concat "*." ext)))))
+      (or default-alias default-extension))))
+
+(defun projectile--globally-ignored-file-suffixes-glob ()
+  "Return ignored file suffixes as a list of glob patterns."
+  (mapcar (lambda (pat) (concat "*" pat)) projectile-globally-ignored-file-suffixes))
+
+(defun projectile--read-search-string-with-default (prefix-label)
+  (let* ((prefix-label (projectile-prepend-project-name prefix-label))
+         (default-value (projectile-symbol-or-selection-at-point))
+         (default-label (if (or (not default-value)
+                                (string= default-value ""))
+                            ""
+                          (format " (default %s)" default-value))))
+    (read-string (format "%s%s: " prefix-label default-label) nil nil default-value)))
+
+;;;###autoload
+(defun projectile-grep (&optional regexp arg)
+  "Perform rgrep in the project.
+
+With a prefix ARG asks for files (globbing-aware) which to grep in.
+With prefix ARG of `-' (such as `M--'), default the files (without prompt),
+to `projectile-grep-default-files'.
+
+With REGEXP given, don't query the user for a regexp."
+  (interactive "i\nP")
+  (require 'grep) ;; for `rgrep'
+  (let* ((roots (projectile-get-project-directories))
+         (search-regexp (or regexp
+                            (projectile--read-search-string-with-default "Grep for")))
+         (files (and arg (or (and (equal current-prefix-arg '-)
+                                  (projectile-grep-default-files))
+                             (read-string (projectile-prepend-project-name "Grep in: ")
+                                          (projectile-grep-default-files))))))
+    (dolist (root-dir roots)
+      (require 'vc-git) ;; for `vc-git-grep'
+      ;; in git projects users have the option to use `vc-git-grep' instead of `rgrep'
+      (if (and (eq (projectile-project-vcs) 'git)
+               projectile-use-git-grep
+               (fboundp 'vc-git-grep))
+          (vc-git-grep search-regexp (or files "") root-dir)
+        ;; paths for find-grep should relative and without trailing /
+        (let ((grep-find-ignored-directories
+               (cl-union (mapcar (lambda (f) (directory-file-name (file-relative-name f root-dir)))
+                                 (projectile-ignored-directories))
+                         grep-find-ignored-directories))
+              (grep-find-ignored-files
+               (cl-union (append (mapcar (lambda (file)
+                                           (file-relative-name file root-dir))
+                                         (projectile-ignored-files))
+                                 (projectile--globally-ignored-file-suffixes-glob))
+                         grep-find-ignored-files)))
+          (grep-compute-defaults)
+          (rgrep search-regexp (or files "* .*") root-dir))))
+    (run-hooks 'projectile-grep-finished-hook)))
+
+;;;###autoload
+(defun projectile-ag (search-term &optional arg)
+  "Run an ag search with SEARCH-TERM in the project.
+
+With an optional prefix argument ARG SEARCH-TERM is interpreted as a
+regular expression."
+  (interactive
+   (list (projectile--read-search-string-with-default
+          (format "Ag %ssearch for" (if current-prefix-arg "regexp " "")))
+         current-prefix-arg))
+  (if (require 'ag nil 'noerror)
+      (let ((ag-command (if arg 'ag-regexp 'ag))
+            (ag-ignore-list (delq nil
+                                  (delete-dups
+                                   (append
+                                    ag-ignore-list
+                                    (projectile--globally-ignored-file-suffixes-glob)
+                                    ;; ag supports git ignore files directly
+                                    (unless (eq (projectile-project-vcs) 'git)
+                                      (append (projectile-ignored-files-rel)
+                                              (projectile-ignored-directories-rel)
+                                              grep-find-ignored-files
+                                              grep-find-ignored-directories
+                                              '()))))))
+            ;; reset the prefix arg, otherwise it will affect the ag-command
+            (current-prefix-arg nil))
+        (funcall ag-command search-term (projectile-project-root)))
+    (error "Package 'ag' is not available")))
+
+;;;###autoload
+(defun projectile-ripgrep (search-term)
+  "Run a Ripgrep search with `SEARCH-TERM' at current project root.
+
+SEARCH-TERM is a regexp."
+  (interactive (list (projectile--read-search-string-with-default
+                      "Ripgrep search for")))
+  (if (require 'ripgrep nil 'noerror)
+      (let ((args (mapcar (lambda (val) (concat "--glob !" val))
+                          (append projectile-globally-ignored-files
+                                  projectile-globally-ignored-directories))))
+        (ripgrep-regexp search-term
+                        (projectile-project-root)
+                        (if current-prefix-arg
+                            args
+                          (cons "--fixed-strings" args))))
+    (error "Package `ripgrep' is not available")))
+
+(defun projectile-tags-exclude-patterns ()
+  "Return a string with exclude patterns for ctags."
+  (mapconcat (lambda (pattern) (format "--exclude=\"%s\""
+                                       (directory-file-name pattern)))
+             (projectile-ignored-directories-rel) " "))
+
+;;;###autoload
+(defun projectile-regenerate-tags ()
+  "Regenerate the project's [e|g]tags."
+  (interactive)
+  (if (and (boundp 'ggtags-mode)
+           (memq projectile-tags-backend '(auto ggtags)))
+      (progn
+        (let* ((ggtags-project-root (projectile-project-root))
+               (default-directory ggtags-project-root))
+          (ggtags-ensure-project)
+          (ggtags-update-tags t)))
+    (let* ((project-root (projectile-project-root))
+           (tags-exclude (projectile-tags-exclude-patterns))
+           (default-directory project-root)
+           (tags-file (expand-file-name projectile-tags-file-name))
+           (command (format projectile-tags-command tags-file tags-exclude))
+           shell-output exit-code)
+      (with-temp-buffer
+        (setq exit-code
+              (call-process-shell-command command nil (current-buffer))
+              shell-output (string-trim
+                            (buffer-substring (point-min) (point-max)))))
+      (unless (zerop exit-code)
+        (error shell-output))
+      (visit-tags-table tags-file)
+      (message "Regenerated %s" tags-file))))
+
+(defun projectile-visit-project-tags-table ()
+  "Visit the current project's tags table."
+  (when (projectile-project-p)
+    (let ((tags-file (projectile-expand-root projectile-tags-file-name)))
+      (when (file-exists-p tags-file)
+        (with-demoted-errors "Error loading tags-file: %s"
+          (visit-tags-table tags-file t))))))
+
+(defun projectile-determine-find-tag-fn ()
+  "Determine which function to use for a call to `projectile-find-tag'."
+  (or
+   (cond
+    ((eq projectile-tags-backend 'auto)
+     (cond
+      ((fboundp 'ggtags-find-tag-dwim)
+       'ggtags-find-tag-dwim)
+      ((fboundp 'xref-find-definitions)
+       'xref-find-definitions)
+      ((fboundp 'etags-select-find-tag)
+       'etags-select-find-tag)))
+    ((eq projectile-tags-backend 'xref)
+     (when (fboundp 'xref-find-definitions)
+       'xref-find-definitions))
+    ((eq projectile-tags-backend 'ggtags)
+     (when (fboundp 'ggtags-find-tag-dwim)
+       'ggtags-find-tag-dwim))
+    ((eq projectile-tags-backend 'etags-select)
+     (when (fboundp 'etags-select-find-tag)
+       'etags-select-find-tag)))
+   'find-tag))
+
+;;;###autoload
+(defun projectile-find-tag ()
+  "Find tag in project."
+  (interactive)
+  (projectile-visit-project-tags-table)
+  ;; Auto-discover the user's preference for tags
+  (let ((find-tag-fn (projectile-determine-find-tag-fn)))
+    (call-interactively find-tag-fn)))
+
+(defmacro projectile-with-default-dir (dir &rest body)
+  "Invoke in DIR the BODY."
+  (declare (debug t) (indent 1))
+  `(let ((default-directory ,dir)
+         (projectile-cached-project-root nil))
+     ,@body))
+
+;;;###autoload
+(defun projectile-run-command-in-root ()
+  "Invoke `execute-extended-command' in the project's root."
+  (interactive)
+  (projectile-with-default-dir (projectile-project-root)
+    (call-interactively 'execute-extended-command)))
+
+;;;###autoload
+(defun projectile-run-shell-command-in-root ()
+  "Invoke `shell-command' in the project's root."
+  (interactive)
+  (projectile-with-default-dir (projectile-project-root)
+    (call-interactively 'shell-command)))
+
+;;;###autoload
+(defun projectile-run-async-shell-command-in-root ()
+  "Invoke `async-shell-command' in the project's root."
+  (interactive)
+  (projectile-with-default-dir (projectile-project-root)
+    (call-interactively 'async-shell-command)))
+
+;;;###autoload
+(defun projectile-run-shell ()
+  "Invoke `shell' in the project's root."
+  (interactive)
+  (projectile-with-default-dir (projectile-project-root)
+    (shell (concat "*shell " (projectile-project-name) "*"))))
+
+;;;###autoload
+(defun projectile-run-eshell ()
+  "Invoke `eshell' in the project's root."
+  (interactive)
+  (let ((eshell-buffer-name (concat "*eshell " (projectile-project-name) "*")))
+    (projectile-with-default-dir (projectile-project-root)
+      (eshell))))
+
+;;;###autoload
+(defun projectile-run-term (program)
+  "Invoke `term' in the project's root."
+  (interactive (list nil))
+  (let* ((term (concat "term " (projectile-project-name)))
+         (buffer (concat "*" term "*")))
+    (unless (get-buffer buffer)
+      (require 'term)
+      (let ((program (or program
+                         (read-from-minibuffer "Run program: "
+                                               (or explicit-shell-file-name
+                                                   (getenv "ESHELL")
+                                                   (getenv "SHELL")
+                                                   "/bin/sh")))))
+        (projectile-with-default-dir (projectile-project-root)
+          (set-buffer (make-term term program))
+          (term-mode)
+          (term-char-mode))))
+    (switch-to-buffer buffer)))
+
+(defun projectile-files-in-project-directory (directory)
+  "Return a list of files in DIRECTORY."
+  (let ((dir (file-relative-name (expand-file-name directory)
+                                 (projectile-project-root))))
+    (cl-remove-if-not
+     (lambda (f) (string-prefix-p dir f))
+     (projectile-current-project-files))))
+
+(defun projectile-unixy-system-p ()
+  "Check to see if unixy text utilities are installed."
+  (cl-every
+   (lambda (x) (executable-find x))
+   '("grep" "cut" "uniq")))
+
+(defun projectile-files-from-cmd (cmd directory)
+  "Use a grep-like CMD to search for files within DIRECTORY.
+
+CMD should include the necessary search params and should output
+equivalently to grep -HlI (only unique matching filenames).
+Returns a list of expanded filenames."
+  (let ((default-directory directory))
+    (mapcar (lambda (str)
+              (concat directory
+                      (if (string-prefix-p "./" str)
+                          (substring str 2)
+                        str)))
+            (split-string
+             (string-trim (shell-command-to-string cmd))
+             "\n+"
+             t))))
+
+(defun projectile-files-with-string (string directory)
+  "Return a list of all files containing STRING in DIRECTORY.
+
+Tries to use ag, ack, git-grep, and grep in that order.  If those
+are impossible (for instance on Windows), returns a list of all
+files in the project."
+  (if (projectile-unixy-system-p)
+      (let* ((search-term (shell-quote-argument string))
+             (cmd (cond ((executable-find "ag")
+                         (concat "ag --literal --nocolor --noheading -l -- "
+                                 search-term))
+                        ((executable-find "ack")
+                         (concat "ack --literal --noheading --nocolor -l -- "
+                                 search-term))
+                        ((and (executable-find "git")
+                              (eq (projectile-project-vcs) 'git))
+                         (concat "git grep -HlI " search-term))
+                        (t
+                         ;; -r: recursive
+                         ;; -H: show filename for each match
+                         ;; -l: show only file names with matches
+                         ;; -I: no binary files
+                         (format "grep -rHlI %s ." search-term)))))
+        (projectile-files-from-cmd cmd directory))
+    ;; we have to reject directories as a workaround to work with git submodules
+    (cl-remove-if
+     #'file-directory-p
+     (mapcar #'projectile-expand-root (projectile-dir-files directory)))))
+
+;;;###autoload
+(defun projectile-replace (&optional arg)
+  "Replace literal string in project using non-regexp `tags-query-replace'.
+
+With a prefix argument ARG prompts you for a directory on which
+to run the replacement."
+  (interactive "P")
+  (let* ((old-text (read-string
+                    (projectile-prepend-project-name "Replace: ")
+                    (projectile-symbol-or-selection-at-point)))
+         (new-text (read-string
+                    (projectile-prepend-project-name
+                     (format "Replace %s with: " old-text))))
+         (directory (if arg
+                        (file-name-as-directory
+                         (read-directory-name "Replace in directory: "))
+                      (projectile-project-root)))
+         (files (projectile-files-with-string old-text directory)))
+    ;; Adapted from `tags-query-replace' for literal strings (not regexp)
+    (setq tags-loop-scan `(let ,(unless (equal old-text (downcase old-text))
+                                  '((case-fold-search nil)))
+                            (if (search-forward ',old-text nil t)
+                                ;; When we find a match, move back to
+                                ;; the beginning of it so
+                                ;; perform-replace will see it.
+                                (goto-char (match-beginning 0))))
+          tags-loop-operate `(perform-replace ',old-text ',new-text t nil nil
+                                              nil multi-query-replace-map))
+    (tags-loop-continue (or (cons 'list files) t))))
+
+;;;###autoload
+(defun projectile-replace-regexp (&optional arg)
+  "Replace a regexp in the project using `tags-query-replace'.
+
+With a prefix argument ARG prompts you for a directory on which
+to run the replacement."
+  (interactive "P")
+  (let* ((old-text (read-string
+                    (projectile-prepend-project-name "Replace regexp: ")
+                    (projectile-symbol-or-selection-at-point)))
+         (new-text (read-string
+                    (projectile-prepend-project-name
+                     (format "Replace regexp %s with: " old-text))))
+         (directory (if arg
+                        (file-name-as-directory
+                         (read-directory-name "Replace regexp in directory: "))
+                      (projectile-project-root)))
+         (files
+          ;; We have to reject directories as a workaround to work with git submodules.
+          ;;
+          ;; We can't narrow the list of files with
+          ;; `projectile-files-with-string' because those regexp tools
+          ;; don't support Emacs regular expressions.
+          (cl-remove-if
+           #'file-directory-p
+           (mapcar #'projectile-expand-root (projectile-dir-files directory)))))
+    (tags-query-replace old-text new-text nil (cons 'list files))))
+
+(defun projectile-symbol-or-selection-at-point ()
+  "Get the symbol or selected text at point."
+  (if (use-region-p)
+      (buffer-substring-no-properties (region-beginning) (region-end))
+    (projectile-symbol-at-point)))
+
+(defun projectile-symbol-at-point ()
+  "Get the symbol at point and strip its properties."
+  (substring-no-properties (or (thing-at-point 'symbol) "")))
+
+;;;###autoload
+(defun projectile-kill-buffers ()
+  "Kill all project buffers."
+  (interactive)
+  (let ((name (projectile-project-name))
+        (buffers (projectile-project-buffers)))
+    (if (yes-or-no-p
+         (format "Are you sure you want to kill %d buffer(s) for '%s'? "
+                 (length buffers) name))
+        ;; we take care not to kill indirect buffers directly
+        ;; as we might encounter them after their base buffers are killed
+        (mapc #'kill-buffer (cl-remove-if 'buffer-base-buffer buffers)))))
+
+;;;###autoload
+(defun projectile-save-project-buffers ()
+  "Save all project buffers."
+  (interactive)
+  (dolist (buf (projectile-project-buffers))
+    (with-current-buffer buf
+      (when buffer-file-name
+        (save-buffer)))))
+
+;;;###autoload
+(defun projectile-dired ()
+  "Open `dired' at the root of the project."
+  (interactive)
+  (dired (projectile-project-root)))
+
+;;;###autoload
+(defun projectile-dired-other-window ()
+  "Open `dired'  at the root of the project in another window."
+  (interactive)
+  (dired-other-window (projectile-project-root)))
+
+;;;###autoload
+(defun projectile-dired-other-frame ()
+  "Open `dired' at the root of the project in another frame."
+  (interactive)
+  (dired-other-frame (projectile-project-root)))
+
+;;;###autoload
+(defun projectile-vc (&optional project-root)
+  "Open `vc-dir' at the root of the project.
+
+For git projects `magit-status-internal' is used if available.
+For hg projects `monky-status' is used if available.
+
+If PROJECT-ROOT is given, it is opened instead of the project
+root directory of the current buffer file.  If interactively
+called with a prefix argument, the user is prompted for a project
+directory to open."
+  (interactive (and current-prefix-arg
+                    (list
+                     (projectile-completing-read
+                      "Open project VC in: "
+                      projectile-known-projects))))
+  (or project-root (setq project-root (projectile-project-root)))
+  (let ((vcs (projectile-project-vcs project-root)))
+    (cl-case vcs
+      (git
+       (cond ((fboundp 'magit-status-internal)
+              (magit-status-internal project-root))
+             ((fboundp 'magit-status)
+              (with-no-warnings (magit-status project-root)))
+             (t
+              (vc-dir project-root))))
+      (hg
+       (if (fboundp 'monky-status)
+           (monky-status project-root)
+         (vc-dir project-root)))
+      (t (vc-dir project-root)))))
+
+;;;###autoload
+(defun projectile-recentf ()
+  "Show a list of recently visited files in a project."
+  (interactive)
+  (if (boundp 'recentf-list)
+      (find-file (projectile-expand-root
+                  (projectile-completing-read
+                   "Recently visited files: "
+                   (projectile-recentf-files))))
+    (message "recentf is not enabled")))
+
+(defun projectile-recentf-files ()
+  "Return a list of recently visited files in a project."
+  (and (boundp 'recentf-list)
+       (let ((project-root (projectile-project-root)))
+         (mapcar
+          (lambda (f) (file-relative-name f project-root))
+          (cl-remove-if-not
+           (lambda (f) (string-prefix-p project-root f))
+           recentf-list)))))
+
+(defun projectile-serialize-cache ()
+  "Serializes the memory cache to the hard drive."
+  (projectile-serialize projectile-projects-cache projectile-cache-file))
+
+(defvar projectile-configure-cmd-map
+  (make-hash-table :test 'equal)
+  "A mapping between projects and the last configure command used on them.")
+
+(defvar projectile-compilation-cmd-map
+  (make-hash-table :test 'equal)
+  "A mapping between projects and the last compilation command used on them.")
+
+(defvar projectile-test-cmd-map
+  (make-hash-table :test 'equal)
+  "A mapping between projects and the last test command used on them.")
+
+(defvar projectile-run-cmd-map
+  (make-hash-table :test 'equal)
+  "A mapping between projects and the last run command used on them.")
+
+(defvar projectile-project-configure-cmd nil
+  "The command to use with `projectile-configure-project'.
+It takes precedence over the default command for the project type when set.
+Should be set via .dir-locals.el.")
+
+(defvar projectile-project-compilation-cmd nil
+  "The command to use with `projectile-compile-project'.
+It takes precedence over the default command for the project type when set.
+Should be set via .dir-locals.el.")
+
+(defvar projectile-project-compilation-dir nil
+  "The directory to use with `projectile-compile-project'.
+The directory path is relative to the project root.
+Should be set via .dir-locals.el.")
+
+(defvar projectile-project-test-cmd nil
+  "The command to use with `projectile-test-project'.
+It takes precedence over the default command for the project type when set.
+Should be set via .dir-locals.el.")
+
+(defvar projectile-project-run-cmd nil
+  "The command to use with `projectile-run-project'.
+It takes precedence over the default command for the project type when set.
+Should be set via .dir-locals.el.")
+
+(defun projectile-default-configure-command (project-type)
+  "Retrieve default configure command for PROJECT-TYPE."
+  (plist-get (gethash project-type projectile-project-types) 'configure-command))
+
+(defun projectile-default-compilation-command (project-type)
+  "Retrieve default compilation command for PROJECT-TYPE."
+  (plist-get (gethash project-type projectile-project-types) 'compile-command))
+
+(defun projectile-default-compilation-dir (project-type)
+  "Retrieve default compilation directory for PROJECT-TYPE."
+  (plist-get (gethash project-type projectile-project-types) 'compilation-dir))
+
+(defun projectile-default-test-command (project-type)
+  "Retrieve default test command for PROJECT-TYPE."
+  (plist-get (gethash project-type projectile-project-types) 'test-command))
+
+(defun projectile-default-run-command (project-type)
+  "Retrieve default run command for PROJECT-TYPE."
+  (plist-get (gethash project-type projectile-project-types) 'run-command))
+
+(defun projectile-configure-command (compile-dir)
+  "Retrieve the configure command for COMPILE-DIR."
+  (or (gethash compile-dir projectile-configure-cmd-map)
+      projectile-project-configure-cmd
+      (let ((cmd-format-string (projectile-default-configure-command (projectile-project-type))))
+        (when cmd-format-string
+          (format cmd-format-string (projectile-project-root))))))
+
+(defun projectile-compilation-command (compile-dir)
+  "Retrieve the compilation command for COMPILE-DIR."
+  (or (gethash compile-dir projectile-compilation-cmd-map)
+      projectile-project-compilation-cmd
+      (projectile-default-compilation-command (projectile-project-type))))
+
+(defun projectile-test-command (compile-dir)
+  "Retrieve the test command for COMPILE-DIR."
+  (or (gethash compile-dir projectile-test-cmd-map)
+      projectile-project-test-cmd
+      (projectile-default-test-command (projectile-project-type))))
+
+(defun projectile-run-command (compile-dir)
+  "Retrieve the run command for COMPILE-DIR."
+  (or (gethash compile-dir projectile-run-cmd-map)
+      projectile-project-run-cmd
+      (projectile-default-run-command (projectile-project-type))))
+
+(defun projectile-read-command (prompt command)
+  "Adapted from `compilation-read-command'."
+  (read-shell-command prompt command
+                      (if (equal (car compile-history) command)
+                          '(compile-history . 1)
+                        'compile-history)))
+
+(defun projectile-compilation-dir ()
+  "Retrieve the compilation directory for this project."
+  (let* ((type (projectile-project-type))
+         (directory (or projectile-project-compilation-dir
+                        (projectile-default-compilation-dir type))))
+    (if directory
+        (file-truename
+         (concat (file-name-as-directory (projectile-project-root))
+                 (file-name-as-directory directory)))
+      (projectile-project-root))))
+
+(defun projectile-maybe-read-command (arg default-cmd prompt)
+  "Prompt user for command unless DEFAULT-CMD is an Elisp function."
+  (if (and (or (stringp default-cmd) (null default-cmd))
+           (or compilation-read-command arg))
+      (projectile-read-command prompt default-cmd)
+    default-cmd))
+
+(defun projectile-run-compilation (cmd)
+  "Run external or Elisp compilation command CMD."
+  (if (functionp cmd)
+      (funcall cmd)
+    (compile cmd)))
+
+(cl-defun projectile--run-project-cmd
+    (command command-map &key show-prompt prompt-prefix save-buffers)
+  "Run a project COMMAND, typically a test- or compile command.
+
+Cache the COMMAND for later use inside the hash-table COMMAND-MAP.
+
+Normally you'll be prompted for a compilation command, unless
+variable `compilation-read-command'.  You can force the prompt
+by setting SHOW-PROMPT.  The prompt will be prefixed with PROMPT-PREFIX.
+
+If SAVE-BUFFERS is non-nil save all projectile buffers before
+running the command."
+  (let* ((project-root (projectile-project-root))
+         (default-directory (projectile-compilation-dir))
+         (command (projectile-maybe-read-command show-prompt
+                                                 command
+                                                 prompt-prefix)))
+    (puthash default-directory command command-map)
+    (when save-buffers
+      (save-some-buffers (not compilation-ask-about-save)
+                         (lambda ()
+                           (projectile-project-buffer-p (current-buffer)
+                                                        project-root))))
+    (unless (file-directory-p default-directory)
+      (mkdir default-directory))
+    (projectile-run-compilation command)))
+
+;;;###autoload
+(defun projectile-configure-project (arg)
+  "Run project configure command.
+
+Normally you'll be prompted for a compilation command, unless
+variable `compilation-read-command'.  You can force the prompt
+with a prefix ARG."
+  (interactive "P")
+  (let ((command (projectile-configure-command (projectile-compilation-dir))))
+    (projectile--run-project-cmd command projectile-configure-cmd-map
+                                 :show-prompt arg
+                                 :prompt-prefix "Configure command: "
+                                 :save-buffers t)))
+
+;;;###autoload
+(defun projectile-compile-project (arg)
+  "Run project compilation command.
+
+Normally you'll be prompted for a compilation command, unless
+variable `compilation-read-command'.  You can force the prompt
+with a prefix ARG."
+  (interactive "P")
+  (let ((command (projectile-compilation-command (projectile-compilation-dir))))
+    (projectile--run-project-cmd command projectile-compilation-cmd-map
+                                 :show-prompt arg
+                                 :prompt-prefix "Compile command: "
+                                 :save-buffers t)))
+
+;;;###autoload
+(defun projectile-test-project (arg)
+  "Run project test command.
+
+Normally you'll be prompted for a compilation command, unless
+variable `compilation-read-command'.  You can force the prompt
+with a prefix ARG."
+  (interactive "P")
+  (let ((command (projectile-test-command (projectile-compilation-dir))))
+    (projectile--run-project-cmd command projectile-test-cmd-map
+                                 :show-prompt arg
+                                 :prompt-prefix "Test command: "
+                                 :save-buffers t)))
+
+;;;###autoload
+(defun projectile-run-project (arg)
+  "Run project run command.
+
+Normally you'll be prompted for a compilation command, unless
+variable `compilation-read-command'.  You can force the prompt
+with a prefix ARG."
+  (interactive "P")
+  (let ((command (projectile-run-command (projectile-compilation-dir))))
+    (projectile--run-project-cmd command projectile-run-cmd-map
+                                 :show-prompt arg
+                                 :prompt-prefix "Run command: ")))
+
+(defadvice compilation-find-file (around projectile-compilation-find-file)
+  "Try to find a buffer for FILENAME, if we cannot find it,
+fallback to the original function."
+  (let ((filename (ad-get-arg 1))
+        full-filename)
+    (ad-set-arg 1
+                (or
+                 (if (file-exists-p (expand-file-name filename))
+                     filename)
+                 ;; Try to find the filename using projectile
+                 (and (projectile-project-p)
+                      (let ((root (projectile-project-root))
+                            (dirs (cons "" (projectile-current-project-dirs))))
+                        (when (setq full-filename
+                                    (car (cl-remove-if-not
+                                          #'file-exists-p
+                                          (mapcar
+                                           (lambda (f)
+                                             (expand-file-name
+                                              filename
+                                              (expand-file-name f root)))
+                                           dirs))))
+                          full-filename)))
+                 ;; Fall back to the old argument
+                 filename))
+    ad-do-it))
+
+(defun projectile-open-projects ()
+  "Return a list of all open projects.
+An open project is a project with any open buffers."
+  (delete-dups
+   (delq nil
+         (mapcar (lambda (buffer)
+                   (with-current-buffer buffer
+                     (when (projectile-project-p)
+                       (abbreviate-file-name (projectile-project-root)))))
+                 (buffer-list)))))
+
+(defun projectile--remove-current-project (projects)
+  "Remove the current project (if any) from the list of PROJECTS."
+  (if (projectile-project-p)
+      (projectile-difference projects
+                             (list (abbreviate-file-name (projectile-project-root))))
+    projects))
+
+(defun projectile-relevant-known-projects ()
+  "Return a list of known projects except the current one (if present)."
+  (projectile--remove-current-project projectile-known-projects))
+
+(defun projectile-relevant-open-projects ()
+  "Return a list of open projects except the current one (if present)."
+  (projectile--remove-current-project (projectile-open-projects)))
+
+;;;###autoload
+(defun projectile-switch-project (&optional arg)
+  "Switch to a project we have visited before.
+Invokes the command referenced by `projectile-switch-project-action' on switch.
+With a prefix ARG invokes `projectile-commander' instead of
+`projectile-switch-project-action.'"
+  (interactive "P")
+  (let ((projects (projectile-relevant-known-projects)))
+    (if projects
+        (projectile-completing-read
+         "Switch to project: " projects
+         :action (lambda (project)
+                   (projectile-switch-project-by-name project arg)))
+      (user-error "There are no known projects"))))
+
+;;;###autoload
+(defun projectile-switch-open-project (&optional arg)
+  "Switch to a project we have currently opened.
+Invokes the command referenced by `projectile-switch-project-action' on switch.
+With a prefix ARG invokes `projectile-commander' instead of
+`projectile-switch-project-action.'"
+  (interactive "P")
+  (let ((projects (projectile-relevant-open-projects)))
+    (if projects
+        (projectile-switch-project-by-name
+         (projectile-completing-read "Switch to open project: " projects)
+         arg)
+      (user-error "There are no open projects"))))
+
+(defun projectile-switch-project-by-name (project-to-switch &optional arg)
+  "Switch to project by project name PROJECT-TO-SWITCH.
+Invokes the command referenced by `projectile-switch-project-action' on switch.
+With a prefix ARG invokes `projectile-commander' instead of
+`projectile-switch-project-action.'"
+  (let ((switch-project-action (if arg
+                                   'projectile-commander
+                                 projectile-switch-project-action)))
+    (run-hooks 'projectile-before-switch-project-hook)
+    (let ((default-directory project-to-switch))
+      ;; use a temporary buffer to load PROJECT-TO-SWITCH's dir-locals before calling SWITCH-PROJECT-ACTION
+      (with-temp-buffer
+        (hack-dir-local-variables-non-file-buffer))
+      ;; Normally the project name is determined from the current
+      ;; buffer. However, when we're switching projects, we want to
+      ;; show the name of the project being switched to, rather than
+      ;; the current project, in the minibuffer. This is a simple hack
+      ;; to tell the `projectile-project-name' function to ignore the
+      ;; current buffer and the caching mechanism, and just return the
+      ;; value of the `projectile-project-name' variable.  We also
+      ;; need to ignore the cached project-root value otherwise we end
+      ;; up still showing files from the current project rather than
+      ;; the new project
+      (let ((projectile-cached-project-root nil)
+            (projectile-project-name (funcall projectile-project-name-function
+                                              project-to-switch)))
+        (funcall switch-project-action)))
+    (run-hooks 'projectile-after-switch-project-hook)))
+
+;;;###autoload
+(defun projectile-find-file-in-directory (&optional directory)
+  "Jump to a file in a (maybe regular) DIRECTORY.
+
+This command will first prompt for the directory the file is in."
+  (interactive "DFind file in directory: ")
+  (let ((default-directory directory)
+        (projectile-require-project-root nil))
+    (if (projectile-project-p)
+        ;; target directory is in a project
+        (let ((file (projectile-completing-read "Find file: "
+                                                (projectile-dir-files directory))))
+          (find-file (expand-file-name file (projectile-project-root)))
+          (run-hooks 'projectile-find-file-hook))
+      ;; target directory is not in a project
+      (projectile-find-file))))
+
+(defun projectile-all-project-files ()
+  "Get a list of all files in all projects."
+  (cl-mapcan
+   (lambda (project)
+     (when (file-exists-p project)
+       (let ((default-directory project)
+             (projectile-cached-project-root nil))
+         (mapcar (lambda (file)
+                   (expand-file-name file project))
+                 (projectile-current-project-files)))))
+   projectile-known-projects))
+
+;;;###autoload
+(defun projectile-find-file-in-known-projects ()
+  "Jump to a file in any of the known projects."
+  (interactive)
+  (let ((projectile-require-project-root nil))
+    (find-file (projectile-completing-read "Find file in projects: " (projectile-all-project-files)))))
+
+(defcustom projectile-after-switch-project-hook nil
+  "Hooks run right after project is switched."
+  :group 'projectile
+  :type 'hook)
+
+(defcustom projectile-before-switch-project-hook nil
+  "Hooks run when right before project is switched."
+  :group 'projectile
+  :type 'hook)
+
+(defun projectile-keep-project-p (project)
+  "Determine whether we should cleanup (remove) PROJECT or not.
+
+It handles the case of remote projects as well.
+See `projectile-cleanup-known-projects'."
+  ;; Taken from from `recentf-keep-default-predicate'
+  (cond
+   ((file-remote-p project nil t) (file-readable-p project))
+   ((file-remote-p project))
+   ((file-readable-p project))))
+
+;;;###autoload
+(defun projectile-cleanup-known-projects ()
+  "Remove known projects that don't exist anymore."
+  (interactive)
+  (projectile-merge-known-projects)
+  (let ((projects-kept (cl-remove-if-not #'projectile-keep-project-p projectile-known-projects))
+        (projects-removed (cl-remove-if #'projectile-keep-project-p projectile-known-projects)))
+    (setq projectile-known-projects projects-kept)
+    (projectile-merge-known-projects)
+    (if projects-removed
+        (message "Projects removed: %s"
+                 (mapconcat #'identity projects-removed ", "))
+      (message "No projects needed to be removed."))))
+
+;;;###autoload
+(defun projectile-clear-known-projects ()
+  "Clear both `projectile-known-projects' and `projectile-known-projects-file'."
+  (interactive)
+  (setq projectile-known-projects nil)
+  (projectile-save-known-projects))
+
+;;;###autoload
+(defun projectile-remove-known-project (&optional project)
+  "Remove PROJECT from the list of known projects."
+  (interactive (list (projectile-completing-read
+                      "Remove from known projects: " projectile-known-projects
+                      :action 'projectile-remove-known-project)))
+  (unless (called-interactively-p 'any)
+    (setq projectile-known-projects
+          (cl-remove-if
+           (lambda (proj) (string= project proj))
+           projectile-known-projects))
+    (projectile-merge-known-projects)
+    (when projectile-verbose
+      (message "Project %s removed from the list of known projects." project))))
+
+;;;###autoload
+(defun projectile-remove-current-project-from-known-projects ()
+  "Remove the current project from the list of known projects."
+  (interactive)
+  (projectile-remove-known-project (abbreviate-file-name (projectile-project-root))))
+
+(defun projectile-ignored-projects ()
+  "A list of projects that should not be save in `projectile-known-projects'."
+  (mapcar #'file-truename projectile-ignored-projects))
+
+(defun projectile-ignored-project-p (project-root)
+  "Return t if PROJECT-ROOT should not be added to `projectile-known-projects'."
+  (or (member project-root (projectile-ignored-projects))
+      (and (functionp projectile-ignored-project-function)
+           (funcall projectile-ignored-project-function project-root))))
+
+(defun projectile-add-known-project (project-root)
+  "Add PROJECT-ROOT to the list of known projects."
+  (interactive (list (read-directory-name "Add to known projects: ")))
+  (unless (projectile-ignored-project-p project-root)
+    (setq projectile-known-projects
+          (delete-dups
+           (cons (file-name-as-directory (abbreviate-file-name project-root))
+                 projectile-known-projects)))))
+
+(defun projectile-load-known-projects ()
+  "Load saved projects from `projectile-known-projects-file'.
+Also set `projectile-known-projects'."
+  (setq projectile-known-projects
+        (projectile-unserialize projectile-known-projects-file))
+  (setq projectile-known-projects-on-file
+        (and (sequencep projectile-known-projects)
+             (copy-sequence projectile-known-projects))))
+
+;; load the known projects
+(projectile-load-known-projects)
+
+(defun projectile-save-known-projects ()
+  "Save PROJECTILE-KNOWN-PROJECTS to PROJECTILE-KNOWN-PROJECTS-FILE."
+  (projectile-serialize projectile-known-projects
+                        projectile-known-projects-file)
+  (setq projectile-known-projects-on-file
+        (and (sequencep projectile-known-projects)
+             (copy-sequence projectile-known-projects))))
+
+(defun projectile-merge-known-projects ()
+  "Merge any change from `projectile-known-projects-file' and save to disk.
+
+This enables multiple Emacs processes to make changes without
+overwriting each other's changes."
+  (let* ((known-now projectile-known-projects)
+         (known-on-last-sync projectile-known-projects-on-file)
+         (known-on-file
+          (projectile-unserialize projectile-known-projects-file))
+         (removed-after-sync (projectile-difference known-on-last-sync known-now))
+         (removed-in-other-process
+          (projectile-difference known-on-last-sync known-on-file))
+         (result (delete-dups
+                  (projectile-difference
+                   (append known-now known-on-file)
+                   (append removed-after-sync removed-in-other-process)))))
+    (setq projectile-known-projects result)
+    (projectile-save-known-projects)))
+
+(define-ibuffer-filter projectile-files
+    "Show Ibuffer with all buffers in the current project."
+  (:reader (read-directory-name "Project root: " (ignore-errors (projectile-project-root)))
+           :description nil)
+  (with-current-buffer buf
+    (equal (file-name-as-directory (expand-file-name qualifier))
+           (ignore-errors (projectile-project-root)))))
+
+(defun projectile-ibuffer-by-project (project-root)
+  "Open an IBuffer window showing all buffers in PROJECT-ROOT."
+  (let ((project-name (funcall projectile-project-name-function project-root)))
+    (ibuffer nil (format "*%s Buffers*" project-name)
+             (list (cons 'projectile-files project-root)))))
+
+;;;###autoload
+(defun projectile-ibuffer (prefix)
+  "Open an IBuffer window showing all buffers in the current project.
+
+Let user choose another project when PREFIX is supplied."
+  (interactive "p")
+  (let ((project-root (if (= prefix 4)
+                          (projectile-completing-read
+                           "Project name: "
+                           (projectile-relevant-known-projects))
+                        (projectile-project-root))))
+
+    (projectile-ibuffer-by-project project-root)))
+
+;;;; projectile-commander
+
+(defconst projectile-commander-help-buffer "*Commander Help*")
+
+(defvar projectile-commander-methods nil
+  "List of file-selection methods for the `projectile-commander' command.
+Each element is a list (KEY DESCRIPTION FUNCTION).
+DESCRIPTION is a one-line description of what the key selects.")
+
+;;;###autoload
+(defun projectile-commander ()
+  "Execute a Projectile command with a single letter.
+The user is prompted for a single character indicating the action to invoke.
+The `?' character describes then
+available actions.
+
+See `def-projectile-commander-method' for defining new methods."
+  (interactive)
+  (let* ((choices (mapcar #'car projectile-commander-methods))
+         (prompt (concat "Commander [" choices "]: "))
+         (ch (read-char-choice prompt choices))
+         (fn (nth 2 (assq ch projectile-commander-methods))))
+    (funcall fn)))
+
+(defmacro def-projectile-commander-method (key description &rest body)
+  "Define a new `projectile-commander' method.
+
+KEY is the key the user will enter to choose this method.
+
+DESCRIPTION is a one-line sentence describing how the method.
+
+BODY is a series of forms which are evaluated when the find
+is chosen."
+  (let ((method `(lambda ()
+                   ,@body)))
+    `(setq projectile-commander-methods
+           (cl-sort (copy-sequence
+                     (cons (list ,key ,description ,method)
+                           (assq-delete-all ,key projectile-commander-methods)))
+                    (lambda (a b) (< (car a) (car b)))))))
+
+(def-projectile-commander-method ?? "Commander help buffer."
+  (ignore-errors (kill-buffer projectile-commander-help-buffer))
+  (with-current-buffer (get-buffer-create projectile-commander-help-buffer)
+    (insert "Projectile Commander Methods:\n\n")
+    (dolist (met projectile-commander-methods)
+      (insert (format "%c:\t%s\n" (car met) (cadr met))))
+    (goto-char (point-min))
+    (help-mode)
+    (display-buffer (current-buffer) t))
+  (projectile-commander))
+
+(defun projectile-commander-bindings ()
+  (def-projectile-commander-method ?A
+    "Find ag on project."
+    (call-interactively 'projectile-ag))
+
+  (def-projectile-commander-method ?f
+    "Find file in project."
+    (projectile-find-file))
+
+  (def-projectile-commander-method ?T
+    "Find test file in project."
+    (projectile-find-test-file))
+
+  (def-projectile-commander-method ?b
+    "Switch to project buffer."
+    (projectile-switch-to-buffer))
+
+  (def-projectile-commander-method ?d
+    "Find directory in project."
+    (projectile-find-dir))
+
+  (def-projectile-commander-method ?D
+    "Open project root in dired."
+    (projectile-dired))
+
+  (def-projectile-commander-method ?v
+    "Open project root in vc-dir or magit."
+    (projectile-vc))
+
+  (def-projectile-commander-method ?V
+    "Browse dirty projects"
+    (projectile-browse-dirty-projects))
+
+  (def-projectile-commander-method ?r
+    "Replace a string in the project."
+    (projectile-replace))
+
+  (def-projectile-commander-method ?R
+    "Regenerate the project's [e|g]tags."
+    (projectile-regenerate-tags))
+
+  (def-projectile-commander-method ?g
+    "Run grep on project."
+    (projectile-grep))
+
+  (def-projectile-commander-method ?s
+    "Switch project."
+    (projectile-switch-project))
+
+  (def-projectile-commander-method ?o
+    "Run multi-occur on project buffers."
+    (projectile-multi-occur))
+
+  (def-projectile-commander-method ?j
+    "Find tag in project."
+    (projectile-find-tag))
+
+  (def-projectile-commander-method ?k
+    "Kill all project buffers."
+    (projectile-kill-buffers))
+
+  (def-projectile-commander-method ?e
+    "Find recently visited file in project."
+    (projectile-recentf)))
+
+(projectile-commander-bindings)
+
+(defun projectile-read-variable ()
+  "Prompt for a variable and return its name."
+  (completing-read "Variable: "
+                   obarray
+                   '(lambda (v)
+                      (and (boundp v) (not (keywordp v))))
+                   t))
+
+(define-skeleton projectile-skel-variable-cons
+  "Insert a variable-name and a value in a cons-cell."
+  "Value: "
+  "("
+  (projectile-read-variable)
+  " . "
+  str
+  ")")
+
+(define-skeleton projectile-skel-dir-locals
+  "Insert a .dir-locals.el template."
+  nil
+  "((nil . ("
+  ("" '(projectile-skel-variable-cons) \n)
+  resume:
+  ")))")
+
+;;;###autoload
+(defun projectile-edit-dir-locals ()
+  "Edit or create a .dir-locals.el file of the project."
+  (interactive)
+  (let ((file (expand-file-name ".dir-locals.el" (projectile-project-root))))
+    (find-file file)
+    (when (not (file-exists-p file))
+      (unwind-protect
+          (projectile-skel-dir-locals)
+        (save-buffer)))))
+
+;;; Minor mode
+(defvar projectile-command-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "4 a") #'projectile-find-other-file-other-window)
+    (define-key map (kbd "4 b") #'projectile-switch-to-buffer-other-window)
+    (define-key map (kbd "4 C-o") #'projectile-display-buffer)
+    (define-key map (kbd "4 d") #'projectile-find-dir-other-window)
+    (define-key map (kbd "4 D") #'projectile-dired-other-window)
+    (define-key map (kbd "4 f") #'projectile-find-file-other-window)
+    (define-key map (kbd "4 g") #'projectile-find-file-dwim-other-window)
+    (define-key map (kbd "4 t") #'projectile-find-implementation-or-test-other-window)
+    (define-key map (kbd "5 a") #'projectile-find-other-file-other-frame)
+    (define-key map (kbd "5 b") #'projectile-switch-to-buffer-other-frame)
+    (define-key map (kbd "5 d") #'projectile-find-dir-other-frame)
+    (define-key map (kbd "5 D") #'projectile-dired-other-frame)
+    (define-key map (kbd "5 f") #'projectile-find-file-other-frame)
+    (define-key map (kbd "5 g") #'projectile-find-file-dwim-other-frame)
+    (define-key map (kbd "5 t") #'projectile-find-implementation-or-test-other-frame)
+    (define-key map (kbd "!") #'projectile-run-shell-command-in-root)
+    (define-key map (kbd "&") #'projectile-run-async-shell-command-in-root)
+    (define-key map (kbd "a") #'projectile-find-other-file)
+    (define-key map (kbd "b") #'projectile-switch-to-buffer)
+    (define-key map (kbd "C") #'projectile-configure-project)
+    (define-key map (kbd "c") #'projectile-compile-project)
+    (define-key map (kbd "d") #'projectile-find-dir)
+    (define-key map (kbd "D") #'projectile-dired)
+    (define-key map (kbd "e") #'projectile-recentf)
+    (define-key map (kbd "E") #'projectile-edit-dir-locals)
+    (define-key map (kbd "f") #'projectile-find-file)
+    (define-key map (kbd "g") #'projectile-find-file-dwim)
+    (define-key map (kbd "F") #'projectile-find-file-in-known-projects)
+    (define-key map (kbd "i") #'projectile-invalidate-cache)
+    (define-key map (kbd "I") #'projectile-ibuffer)
+    (define-key map (kbd "j") #'projectile-find-tag)
+    (define-key map (kbd "k") #'projectile-kill-buffers)
+    (define-key map (kbd "l") #'projectile-find-file-in-directory)
+    (define-key map (kbd "m") #'projectile-commander)
+    (define-key map (kbd "o") #'projectile-multi-occur)
+    (define-key map (kbd "p") #'projectile-switch-project)
+    (define-key map (kbd "q") #'projectile-switch-open-project)
+    (define-key map (kbd "P") #'projectile-test-project)
+    (define-key map (kbd "r") #'projectile-replace)
+    (define-key map (kbd "R") #'projectile-regenerate-tags)
+    (define-key map (kbd "s g") #'projectile-grep)
+    (define-key map (kbd "s r") #'projectile-ripgrep)
+    (define-key map (kbd "s s") #'projectile-ag)
+    (define-key map (kbd "S") #'projectile-save-project-buffers)
+    (define-key map (kbd "t") #'projectile-toggle-between-implementation-and-test)
+    (define-key map (kbd "T") #'projectile-find-test-file)
+    (define-key map (kbd "u") #'projectile-run-project)
+    (define-key map (kbd "v") #'projectile-vc)
+    (define-key map (kbd "V") #'projectile-browse-dirty-projects)
+    (define-key map (kbd "x e") #'projectile-run-eshell)
+    (define-key map (kbd "x t") #'projectile-run-term)
+    (define-key map (kbd "x s") #'projectile-run-shell)
+    (define-key map (kbd "z") #'projectile-cache-current-file)
+    (define-key map (kbd "ESC") #'projectile-project-buffers-other-buffer)
+    map)
+  "Keymap for Projectile commands after `projectile-keymap-prefix'.")
+(fset 'projectile-command-map projectile-command-map)
+
+(defvar projectile-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map projectile-keymap-prefix 'projectile-command-map)
+    map)
+  "Keymap for Projectile mode.")
+
+(easy-menu-change
+ '("Tools") "Projectile"
+ '(["Find file" projectile-find-file]
+   ["Find file in known projects" projectile-find-file-in-known-projects]
+   ["Find test file" projectile-find-test-file]
+   ["Find directory" projectile-find-dir]
+   ["Find file in directory" projectile-find-file-in-directory]
+   ["Find other file" projectile-find-other-file]
+   ["Switch to buffer" projectile-switch-to-buffer]
+   ["Jump between implementation file and test file" projectile-toggle-between-implementation-and-test]
+   ["Kill project buffers" projectile-kill-buffers]
+   ["Recent files" projectile-recentf]
+   ["Edit .dir-locals.el" projectile-edit-dir-locals]
+   "--"
+   ["Open project in dired" projectile-dired]
+   ["Switch to project" projectile-switch-project]
+   ["Switch to open project" projectile-switch-open-project]
+   ["Discover projects in directory" projectile-discover-projects-in-directory]
+   ["Search in project (grep)" projectile-grep]
+   ["Search in project (ag)" projectile-ag]
+   ["Replace in project" projectile-replace]
+   ["Multi-occur in project" projectile-multi-occur]
+   ["Browse dirty projects" projectile-browse-dirty-projects]
+   "--"
+   ["Run shell" projectile-run-shell]
+   ["Run eshell" projectile-run-eshell]
+   ["Run term" projectile-run-term]
+   "--"
+   ["Cache current file" projectile-cache-current-file]
+   ["Invalidate cache" projectile-invalidate-cache]
+   ["Regenerate [e|g]tags" projectile-regenerate-tags]
+   "--"
+   ["Configure project" projectile-configure-project]
+   ["Compile project" projectile-compile-project]
+   ["Test project" projectile-test-project]
+   ["Run project" projectile-run-project]
+   "--"
+   ["Project info" projectile-project-info]
+   ["About" projectile-version])
+ "Search Files (Grep)...")
+
+(easy-menu-change '("Tools") "--" nil "Search Files (Grep)...")
+
+(defcustom projectile-mode-line
+  '(:eval (format " Projectile[%s]"
+                  (projectile-project-name)))
+  "Mode line lighter for Projectile.
+
+The value of this variable is a mode line template as in
+`mode-line-format'.  See Info Node `(elisp)Mode Line Format' for
+details about mode line templates.
+
+Customize this variable to change how Projectile displays its
+status in the mode line.  The default value displays the project
+name and type.  Set this variable to nil to disable the mode line
+entirely."
+  :group 'projectile
+  :type 'sexp
+  :risky t
+  :package-version '(projectile . "0.12.0"))
+
+(defun projectile-find-file-hook-function ()
+  "Called by `find-file-hook' when `projectile-mode' is on.
+
+The function does pretty much nothing when triggered on remote files
+as all the operations it normally performs are extremely slow over
+tramp."
+  (unless (file-remote-p default-directory)
+    (projectile-cache-files-find-file-hook)
+    (projectile-track-known-projects-find-file-hook)
+    (projectile-visit-project-tags-table)))
+
+;;;###autoload
+(define-minor-mode projectile-mode
+  "Minor mode to assist project management and navigation.
+
+When called interactively, toggle `projectile-mode'.  With prefix
+ARG, enable `projectile-mode' if ARG is positive, otherwise disable
+it.
+
+When called from Lisp, enable `projectile-mode' if ARG is omitted,
+nil or positive.  If ARG is `toggle', toggle `projectile-mode'.
+Otherwise behave as if called interactively.
+
+\\{projectile-mode-map}"
+  :lighter projectile-mode-line
+  :keymap projectile-mode-map
+  :group 'projectile
+  :require 'projectile
+  :global t
+  (cond
+   (projectile-mode
+    ;; initialize the projects cache if needed
+    (unless projectile-projects-cache
+      (setq projectile-projects-cache
+            (or (projectile-unserialize projectile-cache-file)
+                (make-hash-table :test 'equal))))
+    (unless projectile-projects-cache-time
+      (setq projectile-projects-cache-time
+            (make-hash-table :test 'equal)))
+    ;; update the list of known projects
+    (projectile-cleanup-known-projects)
+    (projectile-discover-projects-in-search-path)
+    (add-hook 'find-file-hook 'projectile-find-file-hook-function)
+    (add-hook 'projectile-find-dir-hook #'projectile-track-known-projects-find-file-hook t)
+    (add-hook 'dired-before-readin-hook #'projectile-track-known-projects-find-file-hook t t)
+    (ad-activate 'compilation-find-file)
+    (ad-activate 'delete-file))
+   (t
+    (remove-hook 'find-file-hook #'projectile-find-file-hook-function)
+    (remove-hook 'dired-before-readin-hook #'projectile-track-known-projects-find-file-hook t)
+    (ad-deactivate 'compilation-find-file)
+    (ad-deactivate 'delete-file))))
+
+;;;###autoload
+(define-obsolete-function-alias 'projectile-global-mode 'projectile-mode "1.0")
+
+(provide 'projectile)
+
+;; Local Variables:
+;; indent-tabs-mode: nil
+;; End:
+
+;;; projectile.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/projectile-20180711.102/projectile.elc b/configs/shared/emacs/.emacs.d/elpa/projectile-20180711.102/projectile.elc
new file mode 100644
index 0000000000..255afccfb8
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/projectile-20180711.102/projectile.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/quelpa-0.0.1/quelpa-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/quelpa-0.0.1/quelpa-autoloads.el
new file mode 100644
index 0000000000..0328f046cf
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/quelpa-0.0.1/quelpa-autoloads.el
@@ -0,0 +1,68 @@
+;;; quelpa-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "quelpa" "quelpa.el" (23377 60379 28502 112000))
+;;; Generated autoloads from quelpa.el
+
+(autoload 'quelpa-build-package "quelpa" "\
+Create PACKAGE-NAME with VERSION.
+
+The information in FILE-SPECS is used to gather files from
+SOURCE-DIR.
+
+The resulting package will be stored as a .el or .tar file in
+TARGET-DIR, depending on whether there are multiple files.
+
+Argument FILE-SPECS is a list of specs for source files, which
+should be relative to SOURCE-DIR.  The specs can be wildcards,
+and optionally specify different target paths.  They extended
+syntax is currently only documented in the MELPA README.  You can
+simply pass `quelpa-build-default-files-spec' in most cases.
+
+Returns the archive entry for the package.
+
+\(fn PACKAGE-NAME VERSION FILE-SPECS SOURCE-DIR TARGET-DIR)" nil nil)
+
+(autoload 'quelpa-expand-recipe "quelpa" "\
+Expand a given recipe name into full recipe.
+If called interactively, let the user choose a recipe name and
+insert the result into the current buffer.
+
+\(fn RECIPE-NAME)" t nil)
+
+(autoload 'quelpa-self-upgrade "quelpa" "\
+Upgrade quelpa itself.
+ARGS are additional options for the quelpa recipe.
+
+\(fn &optional ARGS)" t nil)
+
+(autoload 'quelpa-upgrade "quelpa" "\
+Upgrade all packages found in `quelpa-cache'.
+This provides an easy way to upgrade all the packages for which
+the `quelpa' command has been run in the current Emacs session.
+
+\(fn)" t nil)
+
+(autoload 'quelpa "quelpa" "\
+Build and install a package with quelpa.
+ARG can be a package name (symbol) or a melpa recipe (list).
+PLIST is a plist that may modify the build and/or fetch process.
+If called interactively, `quelpa' will prompt for a MELPA package
+to install.
+
+When `quelpa' is called interactively with a prefix argument (e.g
+C-u M-x quelpa) it will try to upgrade the given package even if
+the global var `quelpa-upgrade-p' is set to nil.
+
+\(fn ARG &rest PLIST)" t nil)
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; quelpa-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/quelpa-0.0.1/quelpa-pkg.el b/configs/shared/emacs/.emacs.d/elpa/quelpa-0.0.1/quelpa-pkg.el
new file mode 100644
index 0000000000..b0567774e3
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/quelpa-0.0.1/quelpa-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "quelpa" "0.0.1" "Emacs Lisp packages built directly from source" '((emacs "24.3")) :authors '(("steckerhalter")) :maintainer '("steckerhalter") :url "https://framagit.org/steckerhalter/quelpa")
diff --git a/configs/shared/emacs/.emacs.d/elpa/quelpa-0.0.1/quelpa.el b/configs/shared/emacs/.emacs.d/elpa/quelpa-0.0.1/quelpa.el
new file mode 100644
index 0000000000..0994a7cf76
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/quelpa-0.0.1/quelpa.el
@@ -0,0 +1,1799 @@
+;;; quelpa.el --- Emacs Lisp packages built directly from source
+
+;; Copyright 2014-2018, Steckerhalter
+;; Copyright 2014-2015, Vasilij Schneidermann <v.schneidermann@gmail.com>
+
+;; Author: steckerhalter
+;; URL: https://framagit.org/steckerhalter/quelpa
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "24.3"))
+;; Keywords: package management build source elpa
+
+;; This file is not part of GNU Emacs.
+
+;; This file 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, or (at your option)
+;; any later version.
+
+;; This file 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; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+
+;; Your personal local Emacs Lisp Package Archive (ELPA) with packages
+;; built on-the-fly directly from source.
+
+;; See the README for more info:
+;; https://framagit.org/steckerhalter/quelpa/blob/master/README.md
+
+;;; Requirements:
+
+;; Emacs 24.3.1
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'help-fns)
+(require 'url-parse)
+(require 'package)
+(require 'lisp-mnt)
+
+;; --- customs / variables ---------------------------------------------------
+
+(defgroup quelpa nil
+  "Build and install packages from source code"
+  :group 'package)
+
+(defcustom quelpa-upgrade-p nil
+  "When non-nil, `quelpa' will try to upgrade packages.
+The global value can be overridden for each package by supplying
+the `:upgrade' argument."
+  :group 'quelpa
+  :type 'boolean)
+
+(defcustom quelpa-stable-p nil
+  "When non-nil, try to build stable packages like MELPA does."
+  :group 'quelpa
+  :type 'boolean)
+
+(defcustom quelpa-verbose t
+  "When non-nil, `quelpa' prints log messages."
+  :group 'quelpa
+  :type 'boolean)
+
+(defcustom quelpa-before-hook nil
+  "List of functions to be called before quelpa."
+  :group 'quelpa
+  :type 'hook)
+
+(defcustom quelpa-after-hook nil
+  "List of functions to be called after quelpa."
+  :group 'quelpa
+  :type 'hook)
+
+(defcustom quelpa-dir (expand-file-name "quelpa" user-emacs-directory)
+  "Where quelpa builds and stores packages."
+  :group 'quelpa
+  :type 'string)
+
+(defcustom quelpa-melpa-dir (expand-file-name "melpa" quelpa-dir)
+  "Where the melpa repo cloned to."
+  :group 'quelpa
+  :type 'string)
+
+(defcustom quelpa-build-dir (expand-file-name "build" quelpa-dir)
+  "Where quelpa builds packages."
+  :group 'quelpa
+  :type 'string)
+
+(defcustom quelpa-packages-dir (expand-file-name "packages" quelpa-dir)
+  "Where quelpa puts built packages."
+  :group 'quelpa
+  :type 'string)
+
+(defcustom quelpa-melpa-recipe-stores (list (expand-file-name
+                                             "recipes"
+                                             quelpa-melpa-dir))
+  "Recipe stores where quelpa finds default recipes for packages.
+A store can either be a string pointing to a directory with
+recipe files or a list with recipes."
+  :group 'quelpa
+  :type '(repeat
+          (choice directory
+                  (repeat
+                   :tag "List of recipes"
+                   (restricted-sexp :tag "Recipe"
+                                    :match-alternatives (listp))))))
+
+(defcustom quelpa-persistent-cache-file (expand-file-name "cache" quelpa-dir)
+  "Location of the persistent cache file."
+  :group 'quelpa
+  :type 'string)
+
+(defcustom quelpa-persistent-cache-p t
+  "Non-nil when quelpa's cache is saved on and read from disk."
+  :group 'quelpa
+  :type 'boolean)
+
+(defcustom quelpa-checkout-melpa-p t
+  "If non-nil the MELPA git repo is cloned when quelpa is initialized."
+  :group 'quelpa
+  :type 'boolean)
+
+(defcustom quelpa-update-melpa-p t
+  "If non-nil the MELPA git repo is updated when quelpa is initialized.
+If nil the update is disabled and the repo is only updated on
+`quelpa-upgrade' or `quelpa-self-upgrade'."
+  :group 'quelpa
+  :type 'boolean)
+
+(defcustom quelpa-melpa-repo-url "https://github.com/melpa/melpa.git"
+  "The melpa git repository url."
+  :group 'quelpa
+  :type 'string)
+
+(defcustom quelpa-self-upgrade-p t
+  "If non-nil upgrade quelpa itself when doing a
+  `quelpa-upgrade', otherwise only upgrade the packages in the
+  quelpa cache."
+  :group 'quelpa
+  :type 'boolean)
+
+(defvar quelpa-initialized-p nil
+  "Non-nil when quelpa has been initialized.")
+
+(defvar quelpa-cache nil
+  "The `quelpa' command stores processed pkgs/recipes in the cache.")
+
+(defvar quelpa-recipe '(quelpa :url "https://framagit.org/steckerhalter/quelpa.git" :fetcher git)
+  "The recipe for quelpa.")
+
+;; --- compatibility for legacy `package.el' in Emacs 24.3  -------------------
+
+(defun quelpa-setup-package-structs ()
+  "Setup the struct `package-desc' when not available.
+`package-desc-from-legacy' is provided to convert the legacy
+vector desc into a valid PACKAGE-DESC."
+  (unless (functionp 'package-desc-p)
+    (cl-defstruct
+        (package-desc
+         (:constructor
+          ;; convert legacy package desc into PACKAGE-DESC
+          package-desc-from-legacy
+          (pkg-info kind
+                    &aux
+                    (name (intern (aref pkg-info 0)))
+                    (version (version-to-list (aref pkg-info 3)))
+                    (summary (if (string= (aref pkg-info 2) "")
+                                 "No description available."
+                               (aref pkg-info 2)))
+                    (reqs  (aref pkg-info 1))
+                    (kind kind))))
+      name
+      version
+      (summary "No description available.")
+      reqs
+      kind
+      archive
+      dir
+      extras
+      signed)))
+
+;; --- package building ------------------------------------------------------
+
+(defun quelpa-package-type (file)
+  "Determine the package type of FILE.
+Return `tar' for tarball packages, `single' for single file
+packages, or nil, if FILE is not a package."
+  (let ((ext (file-name-extension file)))
+    (cond
+     ((string= ext "tar") 'tar)
+     ((string= ext "el") 'single)
+     (:else nil))))
+
+(defun quelpa-get-package-desc (file)
+  "Extract and return the PACKAGE-DESC struct from FILE.
+On error return nil."
+  (let* ((kind (quelpa-package-type file))
+         (desc (with-demoted-errors "Error getting PACKAGE-DESC: %s"
+                 (with-temp-buffer
+                   (pcase kind
+                     (`single (insert-file-contents file)
+                              (package-buffer-info))
+                     (`tar (insert-file-contents-literally file)
+                           (tar-mode)
+                           (if (help-function-arglist 'package-tar-file-info)
+                               ;; legacy `package-tar-file-info' requires an arg
+                               (package-tar-file-info file)
+                             (with-no-warnings (package-tar-file-info)))))))))
+    (pcase desc
+      ((pred package-desc-p) desc)
+      ((pred vectorp) (package-desc-from-legacy desc kind)))))
+
+(defun quelpa-archive-file-name (archive-entry)
+  "Return the path of the file in which the package for ARCHIVE-ENTRY is stored."
+  (let* ((name (car archive-entry))
+         (pkg-info (cdr archive-entry))
+         (version (package-version-join (aref pkg-info 0)))
+         (flavour (aref pkg-info 3)))
+    (expand-file-name
+     (format "%s-%s.%s" name version (if (eq flavour 'single) "el" "tar"))
+     quelpa-packages-dir)))
+
+(defun quelpa-version>-p (name version)
+  "Return non-nil if VERSION of pkg with NAME is newer than what is currently installed."
+  (not (or (not version)
+           (let ((pkg-desc (cdr (assq name package-alist))))
+             (and pkg-desc
+                  (version-list-<=
+                   (version-to-list version)
+                   (if (functionp 'package-desc-vers)
+                       (package-desc-vers pkg-desc) ;old implementation
+                     (package-desc-version (car pkg-desc))))))
+           ;; Also check built-in packages.
+           (package-built-in-p name (version-to-list version)))))
+
+(defun quelpa-checkout (rcp dir)
+  "Return the version of the new package given a RCP.
+Return nil if the package is already installed and should not be upgraded."
+  (pcase-let ((`(,name . ,config) rcp)
+              (quelpa-build-stable quelpa-stable-p))
+    (unless (or (and (assq name package-alist) (not quelpa-upgrade-p))
+                (and (not config)
+                     (quelpa-message t "no recipe found for package `%s'" name)))
+      (let ((version (condition-case err
+                         (quelpa-build-checkout name config dir)
+                       (error "Failed to checkout `%s': `%s'"
+                              name (error-message-string err)))))
+        (when (quelpa-version>-p name version)
+          version)))))
+
+(defun quelpa-build (rcp)
+  "Build a package from the given recipe RCP.
+Uses the `package-build' library to get the source code and build
+an elpa compatible package in `quelpa-build-dir' storing it in
+`quelpa-packages-dir'. Return the path to the created file or nil
+if no action is necessary (like when the package is installed
+already and should not be upgraded etc)."
+  (let* ((name (car rcp))
+         (build-dir (expand-file-name (symbol-name name) quelpa-build-dir))
+         (version (quelpa-checkout rcp build-dir)))
+    (when version
+      (quelpa-archive-file-name
+       (quelpa-build-package (symbol-name name)
+                             version
+                             (quelpa-build--config-file-list (cdr rcp))
+                             build-dir
+                             quelpa-packages-dir)))))
+
+;; --- package-build.el integration ------------------------------------------
+
+(defun quelpa-file-version (file-path type version time-stamp)
+  "Return version of file at FILE-PATH."
+  (if (eq type 'directory)
+      time-stamp
+    (cl-letf* ((package-strip-rcs-id-orig (symbol-function 'package-strip-rcs-id))
+               ((symbol-function 'package-strip-rcs-id)
+                (lambda (str)
+                  (or (funcall package-strip-rcs-id-orig (lm-header "package-version"))
+                      (funcall package-strip-rcs-id-orig (lm-header "version"))
+                      "0"))))
+      (concat (mapconcat
+               #'number-to-string
+               (package-desc-version (quelpa-get-package-desc file-path)) ".")
+              (pcase version
+                (`original "")
+                (_ (concat "pre0." time-stamp)))))))
+
+(defun quelpa-directory-files (path)
+  "Return list of directory files from PATH recursively."
+  (let ((result '()))
+    (mapc
+     (lambda (file)
+       (if (file-directory-p file)
+           (progn
+             ;; When directory is not empty.
+             (when (cddr (directory-files file))
+               (dolist (subfile (quelpa-directory-files file))
+                 (add-to-list 'result subfile))))
+         (add-to-list 'result file)))
+     (mapcar
+      (lambda (file) (expand-file-name file path))
+      ;; Without first two entries because they are always "." and "..".
+      (cddr (directory-files path))))
+    result))
+
+(defun quelpa-expand-source-file-list (file-path config)
+  "Return list of source files from FILE-PATH corresponding to
+CONFIG."
+  (let ((source-files
+         (mapcar
+          (lambda (file) (expand-file-name file file-path))
+          (quelpa-build--expand-source-file-list file-path config))))
+    ;; Replace any directories in the source file list with the filenames of the
+    ;; files they contain (so that these files can subsequently be hashed).
+    (dolist (file source-files source-files)
+      (when (file-directory-p file)
+        (setq source-files (remove file source-files))
+        (setq source-files (append source-files
+                                   (quelpa-directory-files file)))))))
+
+(defun quelpa-slurp-file (file)
+  "Return the contents of FILE as a string, or nil if no such
+file exists."
+  (when (file-exists-p file)
+    (with-temp-buffer
+      (set-buffer-multibyte nil)
+      (setq-local buffer-file-coding-system 'binary)
+      (insert-file-contents-literally file)
+      (buffer-substring-no-properties (point-min) (point-max)))))
+
+(defun quelpa-check-hash (name config file-path dir &optional fetcher)
+  "Check if hash of FILE-PATH is different as in STAMP-FILE.
+If it is different save the new hash and timestamp to STAMP-FILE
+and return TIME-STAMP, otherwise return OLD-TIME-STAMP."
+  (unless (file-directory-p dir)
+    (make-directory dir))
+  (let* (files
+         hashes
+         new-stamp-info
+         new-content-hash
+         (time-stamp
+          (replace-regexp-in-string "\\.0+" "." (format-time-string "%Y%m%d.%H%M%S")))
+         (stamp-file (concat (expand-file-name (symbol-name name) dir) ".stamp"))
+         (old-stamp-info (quelpa-build--read-from-file stamp-file))
+         (old-content-hash (cdr old-stamp-info))
+         (old-time-stamp (car old-stamp-info))
+         (type (if (file-directory-p file-path) 'directory 'file))
+         (version (plist-get config :version)))
+
+    (if (not (file-exists-p file-path))
+        (error "`%s' does not exist" file-path)
+      (if (eq type 'directory)
+          (setq files (quelpa-expand-source-file-list file-path config)
+                hashes (mapcar
+                        (lambda (file)
+                          (secure-hash
+                           'sha1 (concat file (quelpa-slurp-file file)))) files)
+                new-content-hash (secure-hash 'sha1 (mapconcat 'identity hashes "")))
+        (setq new-content-hash (secure-hash 'sha1 (quelpa-slurp-file file-path)))))
+
+    (setq new-stamp-info (cons time-stamp new-content-hash))
+    (if (and old-content-hash
+             (string= new-content-hash old-content-hash))
+        (quelpa-file-version file-path type version old-time-stamp)
+      (unless (eq fetcher 'url)
+        (delete-directory dir t)
+        (make-directory dir)
+        (if (eq type 'file)
+            (copy-file file-path dir t t t t)
+          (copy-directory file-path dir t t t)))
+      (quelpa-build--dump new-stamp-info stamp-file)
+      (quelpa-file-version file-path type version time-stamp))))
+
+;; --- package-build fork ------------------------------------------
+
+(defcustom quelpa-build-verbose t
+  "When non-nil, then print additional progress information."
+  :type 'boolean)
+
+(defcustom quelpa-build-stable nil
+  "When non-nil, then try to build packages from versions-tagged code."
+  :type 'boolean)
+
+(defcustom quelpa-build-timeout-executable
+  (let ((prog (or (executable-find "timeout")
+                  (executable-find "gtimeout"))))
+    (when (and prog
+               (string-match-p "^ *-k"
+                               (shell-command-to-string (concat prog " --help"))))
+      prog))
+  "Path to a GNU coreutils \"timeout\" command if available.
+This must be a version which supports the \"-k\" option."
+  :type '(file :must-match t))
+
+(defcustom quelpa-build-timeout-secs 600
+  "Wait this many seconds for external processes to complete.
+
+If an external process takes longer than specified here to
+complete, then it is terminated.  This only has an effect
+if `quelpa-build-timeout-executable' is non-nil."
+  :type 'number)
+
+(defcustom quelpa-build-tar-executable
+  (or (executable-find "gtar")
+      (executable-find "tar"))
+  "Path to a (preferably GNU) tar command.
+Certain package names (e.g. \"@\") may not work properly with a BSD tar."
+  :type '(file :must-match t))
+
+(defcustom quelpa-build-version-regexp "^[rRvV]?\\(.*\\)$"
+  "Default pattern for matching valid version-strings within repository tags.
+The string in the capture group should be parsed as valid by `version-to-list'."
+  :type 'string)
+
+;;; Internal Variables
+
+(defconst quelpa-build-default-files-spec
+  '("*.el" "*.el.in" "dir"
+    "*.info" "*.texi" "*.texinfo"
+    "doc/dir" "doc/*.info" "doc/*.texi" "doc/*.texinfo"
+    (:exclude ".dir-locals.el" "test.el" "tests.el" "*-test.el" "*-tests.el"))
+  "Default value for :files attribute in recipes.")
+
+;;; Utilities
+
+(defun quelpa-build--message (format-string &rest args)
+  "Behave like `message' if `quelpa-build-verbose' is non-nil.
+Otherwise do nothing."
+  (when quelpa-build-verbose
+    (apply 'message format-string args)))
+
+(defun quelpa-build--slurp-file (file)
+  "Return the contents of FILE as a string, or nil if no such file exists."
+  (when (file-exists-p file)
+    (with-temp-buffer
+      (insert-file-contents file)
+      (buffer-substring-no-properties (point-min) (point-max)))))
+
+(defun quelpa-build--string-rtrim (str)
+  "Remove trailing whitespace from `STR'."
+  (replace-regexp-in-string "[ \t\n\r]+$" "" str))
+
+(defun quelpa-build--trim (str &optional chr)
+  "Return a copy of STR without any trailing CHR (or space if unspecified)."
+  (if (equal (elt str (1- (length str))) (or chr ? ))
+      (substring str 0 (1- (length str)))
+    str))
+
+;;; Version Handling
+
+(defun quelpa-build--valid-version (str &optional regexp)
+  "Apply to STR the REGEXP if defined, \
+then pass the string to `version-to-list' and return the result, \
+or nil if the version cannot be parsed."
+  (when (and regexp (string-match regexp str))
+    (setq str (match-string 1 str)))
+  (ignore-errors (version-to-list str)))
+
+(defun quelpa-build--parse-time (str)
+  "Parse STR as a time, and format as a YYYYMMDD.HHMM string."
+  ;; We remove zero-padding the HH portion, as it is lost
+  ;; when stored in the archive-contents
+  (setq str (substring-no-properties str))
+  (let ((time (date-to-time
+               (if (string-match "\
+^\\([0-9]\\{4\\}\\)/\\([0-9]\\{2\\}\\)/\\([0-9]\\{2\\}\\) \
+\\([0-9]\\{2\\}:[0-9]\\{2\\}:[0-9]\\{2\\}\\)$" str)
+                   (concat (match-string 1 str) "-" (match-string 2 str) "-"
+                           (match-string 3 str) " " (match-string 4 str))
+                 str))))
+    (concat (format-time-string "%Y%m%d." time)
+            (format "%d" (string-to-number (format-time-string "%H%M" time))))))
+
+(defun quelpa-build--find-parse-time (regexp &optional bound)
+  "Find REGEXP in current buffer and format as a time-based version string.
+An optional second argument bounds the search; it is a buffer
+position.  The match found must not end after that position."
+  (and (re-search-backward regexp bound t)
+       (quelpa-build--parse-time (match-string-no-properties 1))))
+
+(defun quelpa-build--find-parse-time-newest (regexp &optional bound)
+  "Find REGEXP in current buffer and format as a time-based version string.
+An optional second argument bounds the search; it is a buffer
+position.  The match found must not end after that position."
+  (save-match-data
+    (let (cur matches)
+      (while (setq cur (quelpa-build--find-parse-time regexp bound))
+        (push cur matches))
+      (car (nreverse (sort matches 'string<))))))
+
+(defun quelpa-build--find-version-newest (regexp &optional bound)
+  "Find the newest version matching REGEXP before point.
+An optional second argument bounds the search; it is a buffer
+position.  The match found must not before after that position."
+  (let ((tags (split-string
+               (buffer-substring-no-properties
+                (or bound (point-min)) (point))
+               "\n")))
+    (setq tags (append
+                (mapcar
+                 ;; Because the default `version-separator' is ".",
+                 ;; version-strings like "1_4_5" will be parsed
+                 ;; wrongly as (1 -4 4 -4 5), so we set
+                 ;; `version-separator' to "_" below and run again.
+                 (lambda (tag)
+                   (when (quelpa-build--valid-version tag regexp)
+                     (list (quelpa-build--valid-version tag regexp) tag)))
+                 tags)
+                (mapcar
+                 ;; Check for valid versions again, this time using
+                 ;; "_" as a separator instead of "." to catch
+                 ;; version-strings like "1_4_5".  Since "_" is
+                 ;; otherwise treated as a snapshot separator by
+                 ;; `version-regexp-alist', we don't have to worry
+                 ;; about the incorrect version list above—(1 -4 4 -4
+                 ;; 5)—since it will always be treated as older by
+                 ;; `version-list-<'.
+                 (lambda (tag)
+                   (let ((version-separator "_"))
+                     (when (quelpa-build--valid-version tag regexp)
+                       (list (quelpa-build--valid-version tag regexp) tag))))
+                 tags)))
+    (setq tags (cl-remove-if nil tags))
+    ;; Returns a list like ((0 1) ("v0.1")); the first element is used
+    ;; for comparison and for `package-version-join', and the second
+    ;; (the original tag) is used by git/hg/etc.
+    (car (nreverse (sort tags (lambda (v1 v2) (version-list-< (car v1) (car v2))))))))
+
+;;; Run Process
+
+(defun quelpa-build--run-process (dir command &rest args)
+  "In DIR (or `default-directory' if unset) run COMMAND with ARGS.
+Output is written to the current buffer."
+  (let ((default-directory (file-name-as-directory (or dir default-directory)))
+        (argv (nconc (unless (eq system-type 'windows-nt)
+                       (list "env" "LC_ALL=C"))
+                     (if quelpa-build-timeout-executable
+                         (nconc (list quelpa-build-timeout-executable
+                                      "-k" "60" (number-to-string
+                                                 quelpa-build-timeout-secs)
+                                      command)
+                                args)
+                       (cons command args)))))
+    (unless (file-directory-p default-directory)
+      (error "Can't run process in non-existent directory: %s" default-directory))
+    (let ((exit-code (apply 'process-file
+                            (car argv) nil (current-buffer) t
+                            (cdr argv))))
+      (or (zerop exit-code)
+          (error "Command '%s' exited with non-zero status %d: %s"
+                 argv exit-code (buffer-string))))))
+
+(defun quelpa-build--run-process-match (regexp dir prog &rest args)
+  "Run PROG with args and return the first match for REGEXP in its output.
+PROG is run in DIR, or if that is nil in `default-directory'."
+  (with-temp-buffer
+    (apply 'quelpa-build--run-process dir prog args)
+    (goto-char (point-min))
+    (re-search-forward regexp)
+    (match-string-no-properties 1)))
+
+;;; Checkout
+;;;; Common
+
+(defun quelpa-build-checkout (package-name config working-dir)
+  "Check out source for PACKAGE-NAME with CONFIG under WORKING-DIR.
+In turn, this function uses the :fetcher option in the CONFIG to
+choose a source-specific fetcher function, which it calls with
+the same arguments.
+
+Returns the package version as a string."
+  (let ((fetcher (plist-get config :fetcher)))
+    (quelpa-build--message "Fetcher: %s" fetcher)
+    (unless (eq fetcher 'wiki)
+      (quelpa-build--message "Source: %s\n"
+                             (or (plist-get config :repo)
+                                 (plist-get config :url))))
+    (funcall (intern (format "quelpa-build--checkout-%s" fetcher))
+             package-name config (file-name-as-directory working-dir))))
+
+(defun quelpa-build--princ-exists (dir)
+  "Print a message that the contents of DIR will be updated."
+  (quelpa-build--message "Updating %s" dir))
+
+(defun quelpa-build--princ-checkout (repo dir)
+  "Print a message that REPO will be checked out into DIR."
+  (quelpa-build--message "Cloning %s to %s" repo dir))
+
+;;;; Wiki
+
+(defvar quelpa-build--last-wiki-fetch-time 0
+  "The time at which an emacswiki URL was last requested.
+This is used to avoid exceeding the rate limit of 1 request per 2
+seconds; the server cuts off after 10 requests in 20 seconds.")
+
+(defvar quelpa-build--wiki-min-request-interval 3
+  "The shortest permissible interval between successive requests for Emacswiki URLs.")
+
+(defmacro quelpa-build--with-wiki-rate-limit (&rest body)
+  "Rate-limit BODY code passed to this macro to match EmacsWiki's rate limiting."
+  (let ((elapsed (cl-gensym)))
+    `(let ((,elapsed (- (float-time) quelpa-build--last-wiki-fetch-time)))
+       (when (< ,elapsed quelpa-build--wiki-min-request-interval)
+         (let ((wait (- quelpa-build--wiki-min-request-interval ,elapsed)))
+           (quelpa-build--message
+            "Waiting %.2f secs before hitting Emacswiki again" wait)
+           (sleep-for wait)))
+       (unwind-protect
+           (progn ,@body)
+         (setq quelpa-build--last-wiki-fetch-time (float-time))))))
+
+(require 'mm-decode)
+(defvar url-http-response-status)
+(defvar url-http-end-of-headers)
+
+(defun quelpa-build--url-copy-file (url newname &optional ok-if-already-exists)
+  "Copy URL to NEWNAME.  Both args must be strings.
+Returns the http request's header as a string.
+Like `url-copy-file', but it produces an error if the http response is not 200.
+Signals a `file-already-exists' error if file NEWNAME already exists,
+unless a third argument OK-IF-ALREADY-EXISTS is supplied and non-nil.
+A number as third arg means request confirmation if NEWNAME already exists."
+  (if (and (file-exists-p newname)
+           (not ok-if-already-exists))
+      (error "Opening output file: File already exists, %s" newname))
+  (let ((buffer (url-retrieve-synchronously url))
+        (headers nil)
+        (handle nil))
+    (if (not buffer)
+        (error "Opening input file: No such file or directory, %s" url))
+    (with-current-buffer buffer
+      (unless (= 200 url-http-response-status)
+        (error "HTTP error %s fetching %s" url-http-response-status url))
+      (setq handle (mm-dissect-buffer t))
+      (mail-narrow-to-head)
+      (setq headers (buffer-string)))
+    (mm-save-part-to-file handle newname)
+    (kill-buffer buffer)
+    (mm-destroy-parts handle)
+    headers))
+
+(defun quelpa-build--grab-wiki-file (filename)
+  "Download FILENAME from emacswiki, returning its last-modified time."
+  (let ((download-url
+         (format "https://www.emacswiki.org/emacs/download/%s" filename))
+        headers)
+    (quelpa-build--with-wiki-rate-limit
+     (setq headers (quelpa-build--url-copy-file download-url filename t)))
+    (when (zerop (nth 7 (file-attributes filename)))
+      (error "Wiki file %s was empty - has it been removed?" filename))
+    (quelpa-build--parse-time
+     (with-temp-buffer
+       (insert headers)
+       (mail-fetch-field "last-modified")))))
+
+(defun quelpa-build--checkout-wiki (name config dir)
+  "Checkout package NAME with config CONFIG from the EmacsWiki into DIR."
+  (unless quelpa-build-stable
+    (with-current-buffer (get-buffer-create "*quelpa-build-checkout*")
+      (unless (file-exists-p dir)
+        (make-directory dir))
+      (let ((files (or (plist-get config :files)
+                       (list (format "%s.el" name))))
+            (default-directory dir))
+        (car (nreverse (sort (mapcar 'quelpa-build--grab-wiki-file files)
+                             'string-lessp)))))))
+
+;;;; Darcs
+
+(defun quelpa-build--darcs-repo (dir)
+  "Get the current darcs repo for DIR."
+  (quelpa-build--run-process-match "Default Remote: \\(.*\\)"
+                                   dir "darcs" "show" "repo"))
+
+(defun quelpa-build--checkout-darcs (name config dir)
+  "Check package NAME with config CONFIG out of darcs into DIR."
+  (let ((repo (plist-get config :url)))
+    (with-current-buffer (get-buffer-create "*quelpa-build-checkout*")
+      (cond
+       ((and (file-exists-p (expand-file-name "_darcs" dir))
+             (string-equal (quelpa-build--darcs-repo dir) repo))
+        (quelpa-build--princ-exists dir)
+        (quelpa-build--run-process dir "darcs" "pull" "--all"))
+       (t
+        (when (file-exists-p dir)
+          (delete-directory dir t))
+        (quelpa-build--princ-checkout repo dir)
+        (quelpa-build--run-process nil "darcs" "get" repo dir)))
+      (if quelpa-build-stable
+          (let* ((min-bound (goto-char (point-max)))
+                 (tag-version
+                  (and (quelpa-build--run-process dir "darcs" "show" "tags")
+                       (or (quelpa-build--find-version-newest
+                            (or (plist-get config :version-regexp)
+                                quelpa-build-version-regexp)
+                            min-bound)
+                           (error "No valid stable versions found for %s" name)))))
+            (quelpa-build--run-process dir "darcs" "obliterate"
+                                       "--all" "--from-tag"
+                                       (cadr tag-version))
+            ;; Return the parsed version as a string
+            (package-version-join (car tag-version)))
+        (apply 'quelpa-build--run-process
+               dir "darcs" "changes" "--max-count" "1"
+               (quelpa-build--expand-source-file-list dir config))
+        (quelpa-build--find-parse-time "\
+\\([a-zA-Z]\\{3\\} [a-zA-Z]\\{3\\} \
+\\( \\|[0-9]\\)[0-9] [0-9]\\{2\\}:[0-9]\\{2\\}:[0-9]\\{2\\} \
+[A-Za-z]\\{3\\} [0-9]\\{4\\}\\)")))))
+
+;;;; Fossil
+
+(defun quelpa-build--fossil-repo (dir)
+  "Get the current fossil repo for DIR."
+  (quelpa-build--run-process-match "\\(.*\\)" dir "fossil" "remote-url"))
+
+(defun quelpa-build--checkout-fossil (name config dir)
+  "Check package NAME with config CONFIG out of fossil into DIR."
+  (unless quelpa-build-stable
+    (let ((repo (plist-get config :url)))
+      (with-current-buffer (get-buffer-create "*quelpa-build-checkout*")
+        (cond
+         ((and (or (file-exists-p (expand-file-name ".fslckout" dir))
+                   (file-exists-p (expand-file-name "_FOSSIL_" dir)))
+               (string-equal (quelpa-build--fossil-repo dir) repo))
+          (quelpa-build--princ-exists dir)
+          (quelpa-build--run-process dir "fossil" "update"))
+         (t
+          (when (file-exists-p dir)
+            (delete-directory dir t))
+          (quelpa-build--princ-checkout repo dir)
+          (make-directory dir)
+          (quelpa-build--run-process dir "fossil" "clone" repo "repo.fossil")
+          (quelpa-build--run-process dir "fossil" "open" "repo.fossil")))
+        (quelpa-build--run-process dir "fossil" "timeline" "-n" "1" "-t" "ci")
+        (or (quelpa-build--find-parse-time "\
+=== \\([0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\} ===\n\
+[0-9]\\{2\\}:[0-9]\\{2\\}:[0-9]\\{2\\}\\) ")
+            (error "No valid timestamps found!"))))))
+
+;;;; Svn
+
+(defun quelpa-build--svn-repo (dir)
+  "Get the current svn repo for DIR."
+  (quelpa-build--run-process-match "URL: \\(.*\\)" dir "svn" "info"))
+
+(defun quelpa-build--checkout-svn (name config dir)
+  "Check package NAME with config CONFIG out of svn into DIR."
+  (unless quelpa-build-stable
+    (with-current-buffer (get-buffer-create "*quelpa-build-checkout*")
+      (let ((repo (quelpa-build--trim (plist-get config :url) ?/))
+            (bound (goto-char (point-max))))
+        (cond
+         ((and (file-exists-p (expand-file-name ".svn" dir))
+               (string-equal (quelpa-build--svn-repo dir) repo))
+          (quelpa-build--princ-exists dir)
+          (quelpa-build--run-process dir "svn" "up"))
+         (t
+          (when (file-exists-p dir)
+            (delete-directory dir t))
+          (quelpa-build--princ-checkout repo dir)
+          (quelpa-build--run-process nil "svn" "checkout" repo dir)))
+        (apply 'quelpa-build--run-process dir "svn" "info"
+               (quelpa-build--expand-source-file-list dir config))
+        (or (quelpa-build--find-parse-time-newest "\
+Last Changed Date: \\([0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\} \
+[0-9]\\{2\\}:[0-9]\\{2\\}:[0-9]\\{2\\}\\( [+-][0-9]\\{4\\}\\)?\\)"
+                                                  bound)
+            (error "No valid timestamps found!"))))))
+
+;;;; Cvs
+
+(defun quelpa-build--cvs-repo (dir)
+  "Get the current CVS root and repository for DIR.
+
+Return a cons cell whose `car' is the root and whose `cdr' is the repository."
+  (apply 'cons
+         (mapcar (lambda (file)
+                   (quelpa-build--string-rtrim
+                    (quelpa-build--slurp-file (expand-file-name file dir))))
+                 '("CVS/Root" "CVS/Repository"))))
+
+(defun quelpa-build--checkout-cvs (name config dir)
+  "Check package NAME with config CONFIG out of cvs into DIR."
+  (unless quelpa-build-stable
+    (with-current-buffer (get-buffer-create "*quelpa-build-checkout*")
+      (let ((root (quelpa-build--trim (plist-get config :url) ?/))
+            (repo (or (plist-get config :module) (symbol-name name)))
+            (bound (goto-char (point-max)))
+            latest)
+        (cond
+         ((and (file-exists-p (expand-file-name "CVS" dir))
+               (equal (quelpa-build--cvs-repo dir) (cons root repo)))
+          (quelpa-build--princ-exists dir)
+          (quelpa-build--run-process dir "cvs" "update" "-dP"))
+         (t
+          (when (file-exists-p dir)
+            (delete-directory dir t))
+          (quelpa-build--princ-checkout (format "%s from %s" repo root) dir)
+          ;; CVS insists on relative paths as target directory for checkout (for
+          ;; whatever reason), and puts "CVS" directories into every subdirectory
+          ;; of the current working directory given in the target path. To get CVS
+          ;; to just write to DIR, we need to execute CVS from the parent
+          ;; directory of DIR, and specific DIR as relative path.  Hence all the
+          ;; following mucking around with paths.  CVS is really horrid.
+          (let ((dir (directory-file-name dir)))
+            (quelpa-build--run-process (file-name-directory dir)
+                                       "env" "TZ=UTC" "cvs" "-z3"
+                                       "-d" root "checkout"
+                                       "-d" (file-name-nondirectory dir)
+                                       repo))))
+        (apply 'quelpa-build--run-process dir "cvs" "log"
+               (quelpa-build--expand-source-file-list dir config))
+
+        ;; `cvs log` does not provide a way to view the previous N
+        ;; revisions, so instead of parsing the entire log we examine
+        ;; the Entries file, which looks like this:
+        ;;
+        ;; /.cvsignore/1.2/Thu Sep  1 12:42:02 2005//
+        ;; /CHANGES/1.1/Tue Oct  4 11:47:54 2005//
+        ;; /GNUmakefile/1.8/Tue Oct  4 11:47:54 2005//
+        ;; /Makefile/1.14/Tue Oct  4 11:47:54 2005//
+        ;;
+        (insert-file-contents (concat dir "/CVS/Entries"))
+        (setq latest
+              (car
+               (sort
+                (split-string (buffer-substring-no-properties (point) (point-max)) "\n")
+                (lambda (x y)
+                  (when (string-match "^\\/[^\\/]*\\/[^\\/]*\\/\\([^\\/]*\\)\\/\\/$" x)
+                    (setq x (quelpa-build--parse-time (match-string 1 x))))
+                  (when (string-match "^\\/[^\\/]*\\/[^\\/]*\\/\\([^\\/]*\\)\\/\\/$" y)
+                    (setq y (quelpa-build--parse-time (match-string 1 y))))
+                  (version-list-<= (quelpa-build--valid-version y)
+                                   (quelpa-build--valid-version x))))))
+        (when (string-match "^\\/[^\\/]*\\/[^\\/]*\\/\\([^\\/]*\\)\\/\\/$" latest)
+          (setq latest (match-string 1 latest)))
+        (or (quelpa-build--parse-time latest)
+            (error "No valid timestamps found!"))))))
+
+;;;; Git
+
+(defun quelpa-build--git-repo (dir)
+  "Get the current git repo for DIR."
+  (quelpa-build--run-process-match
+   "Fetch URL: \\(.*\\)" dir "git" "remote" "show" "-n" "origin"))
+
+(defun quelpa-build--checkout-git (name config dir)
+  "Check package NAME with config CONFIG out of git into DIR."
+  (let ((repo (plist-get config :url))
+        (commit (or (plist-get config :commit)
+                    (let ((branch (plist-get config :branch)))
+                      (when branch
+                        (concat "origin/" branch))))))
+    (with-current-buffer (get-buffer-create "*quelpa-build-checkout*")
+      (goto-char (point-max))
+      (cond
+       ((and (file-exists-p (expand-file-name ".git" dir))
+             (string-equal (quelpa-build--git-repo dir) repo))
+        (quelpa-build--princ-exists dir)
+        (quelpa-build--run-process dir "git" "fetch" "--all" "--tags"))
+       (t
+        (when (file-exists-p dir)
+          (delete-directory dir t))
+        (quelpa-build--princ-checkout repo dir)
+        (quelpa-build--run-process nil "git" "clone" repo dir)))
+      (if quelpa-build-stable
+          (let* ((min-bound (goto-char (point-max)))
+                 (tag-version
+                  (and (quelpa-build--run-process dir "git" "tag")
+                       (or (quelpa-build--find-version-newest
+                            (or (plist-get config :version-regexp)
+                                quelpa-build-version-regexp)
+                            min-bound)
+                           (error "No valid stable versions found for %s" name)))))
+            ;; Using reset --hard here to comply with what's used for
+            ;; unstable, but maybe this should be a checkout?
+            (quelpa-build--update-git-to-ref
+             dir (concat "tags/" (cadr tag-version)))
+            ;; Return the parsed version as a string
+            (package-version-join (car tag-version)))
+        (quelpa-build--update-git-to-ref
+         dir (or commit (concat "origin/" (quelpa-build--git-head-branch dir))))
+        (apply 'quelpa-build--run-process
+               dir "git" "log" "--first-parent" "-n1" "--pretty=format:'\%ci'"
+               (quelpa-build--expand-source-file-list dir config))
+        (quelpa-build--find-parse-time "\
+\\([0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\} \
+[0-9]\\{2\\}:[0-9]\\{2\\}:[0-9]\\{2\\}\\( [+-][0-9]\\{4\\}\\)?\\)")))))
+
+(defun quelpa-build--git-head-branch (dir)
+  "Get the current git repo for DIR."
+  (or (ignore-errors
+        (quelpa-build--run-process-match
+         "HEAD branch: \\(.*\\)" dir "git" "remote" "show" "origin"))
+      "master"))
+
+(defun quelpa-build--git-head-sha (dir)
+  "Get the current head SHA for DIR."
+  (ignore-errors
+    (quelpa-build--run-process-match
+     "\\(.*\\)" dir "git" "rev-parse" "HEAD")))
+
+(defun quelpa-build--update-git-to-ref (dir ref)
+  "Update the git repo in DIR so that HEAD is REF."
+  (quelpa-build--run-process dir "git" "reset" "--hard" ref)
+  (quelpa-build--run-process dir "git" "submodule" "sync" "--recursive")
+  (quelpa-build--run-process dir "git" "submodule" "update" "--init" "--recursive"))
+
+(defun quelpa-build--checkout-github (name config dir)
+  "Check package NAME with config CONFIG out of github into DIR."
+  (let ((url (format "https://github.com/%s.git" (plist-get config :repo))))
+    (quelpa-build--checkout-git name (plist-put (copy-sequence config) :url url) dir)))
+
+(defun quelpa-build--checkout-gitlab (name config dir)
+  "Check package NAME with config CONFIG out of gitlab into DIR."
+  (let ((url (format "https://gitlab.com/%s.git" (plist-get config :repo))))
+    (quelpa-build--checkout-git name (plist-put (copy-sequence config) :url url) dir)))
+
+;;;; Bzr
+
+(defun quelpa-build--bzr-repo (dir)
+  "Get the current bzr repo for DIR."
+  (quelpa-build--run-process-match "parent branch: \\(.*\\)" dir "bzr" "info"))
+
+(defun quelpa-build--checkout-bzr (name config dir)
+  "Check package NAME with config CONFIG out of bzr into DIR."
+  (let ((repo (quelpa-build--run-process-match
+               "\\(?:branch root\\|repository branch\\): \\(.*\\)"
+               nil "bzr" "info" (plist-get config :url))))
+    (with-current-buffer (get-buffer-create "*quelpa-build-checkout*")
+      (goto-char (point-max))
+      (cond
+       ((and (file-exists-p (expand-file-name ".bzr" dir))
+             (string-equal (quelpa-build--bzr-repo dir) repo))
+        (quelpa-build--princ-exists dir)
+        (quelpa-build--run-process dir "bzr" "merge" "--force"))
+       (t
+        (when (file-exists-p dir)
+          (delete-directory dir t))
+        (quelpa-build--princ-checkout repo dir)
+        (quelpa-build--run-process nil "bzr" "branch" repo dir)))
+      (if quelpa-build-stable
+          (let ((bound (goto-char (point-max)))
+                (regexp (or (plist-get config :version-regexp)
+                            quelpa-build-version-regexp))
+                tag-version)
+            (quelpa-build--run-process dir "bzr" "tags")
+            (goto-char bound)
+            (ignore-errors (while (re-search-forward "\\ +.*")
+                             (replace-match "")))
+            (setq tag-version
+                  (or (quelpa-build--find-version-newest regexp bound)
+                      (error "No valid stable versions found for %s" name)))
+            (quelpa-build--run-process dir
+                                       "bzr" "revert" "-r"
+                                       (concat "tag:" (cadr tag-version)))
+            ;; Return the parsed version as a string
+            (package-version-join (car tag-version)))
+        (apply 'quelpa-build--run-process dir "bzr" "log" "-l1"
+               (quelpa-build--expand-source-file-list dir config))
+        (quelpa-build--find-parse-time "\
+\\([0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\} \
+[0-9]\\{2\\}:[0-9]\\{2\\}:[0-9]\\{2\\}\\( [+-][0-9]\\{4\\}\\)?\\)")))))
+
+;;;; Hg
+
+(defun quelpa-build--hg-repo (dir)
+  "Get the current hg repo for DIR."
+  (quelpa-build--run-process-match "default = \\(.*\\)" dir "hg" "paths"))
+
+(defun quelpa-build--checkout-hg (name config dir)
+  "Check package NAME with config CONFIG out of hg into DIR."
+  (let ((repo (plist-get config :url)))
+    (with-current-buffer (get-buffer-create "*quelpa-build-checkout*")
+      (goto-char (point-max))
+      (cond
+       ((and (file-exists-p (expand-file-name ".hg" dir))
+             (string-equal (quelpa-build--hg-repo dir) repo))
+        (quelpa-build--princ-exists dir)
+        (quelpa-build--run-process dir "hg" "pull")
+        (quelpa-build--run-process dir "hg" "update"))
+       (t
+        (when (file-exists-p dir)
+          (delete-directory dir t))
+        (quelpa-build--princ-checkout repo dir)
+        (quelpa-build--run-process nil "hg" "clone" repo dir)))
+      (if quelpa-build-stable
+          (let ((min-bound (goto-char (point-max)))
+                (regexp (or (plist-get config :version-regexp)
+                            quelpa-build-version-regexp))
+                tag-version)
+            (quelpa-build--run-process dir "hg" "tags")
+            ;; The output of `hg tags` shows the ref of the tag as well
+            ;; as the tag itself, e.g.:
+            ;;
+            ;; tip                             1696:73ad80e8fea1
+            ;; 1.2.8                           1691:464af57fd2b7
+            ;;
+            ;; So here we remove that second column before passing the
+            ;; buffer contents to `quelpa-build--find-version-newest'.
+            ;; This isn't strictly necessary for Mercurial since the
+            ;; colon in "1691:464af57fd2b7" means that won't be parsed
+            ;; as a valid version-string, but it's an example of how to
+            ;; do it in case it's necessary elsewhere.
+            (goto-char min-bound)
+            (ignore-errors (while (re-search-forward "\\ +.*")
+                             (replace-match "")))
+            (setq tag-version
+                  (or (quelpa-build--find-version-newest regexp min-bound)
+                      (error "No valid stable versions found for %s" name)))
+            (quelpa-build--run-process dir "hg" "update" (cadr tag-version))
+            ;; Return the parsed version as a string
+            (package-version-join (car tag-version)))
+        (apply 'quelpa-build--run-process
+               dir "hg" "log" "--style" "compact" "-l1"
+               (quelpa-build--expand-source-file-list dir config))
+        (quelpa-build--find-parse-time "\
+\\([0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\} \
+[0-9]\\{2\\}:[0-9]\\{2\\}\\( [+-][0-9]\\{4\\}\\)?\\)")))))
+
+(defun quelpa-build--checkout-bitbucket (name config dir)
+  "Check package NAME with config CONFIG out of bitbucket into DIR."
+  (let ((url (format "https://bitbucket.com/%s" (plist-get config :repo))))
+    (quelpa-build--checkout-hg name (plist-put (copy-sequence config) :url url) dir)))
+
+;;; Utilities
+
+(defun quelpa-build--dump (data file &optional pretty-print)
+  "Write DATA to FILE as a Lisp sexp.
+Optionally PRETTY-PRINT the data."
+  (with-temp-file file
+    (quelpa-build--message "File: %s" file)
+    (if pretty-print
+        (pp data (current-buffer))
+      (print data (current-buffer)))))
+
+(defun quelpa-build--write-pkg-file (pkg-file pkg-info)
+  "Write PKG-FILE containing PKG-INFO."
+  (with-temp-file pkg-file
+    (pp
+     `(define-package
+        ,(aref pkg-info 0)
+        ,(aref pkg-info 3)
+        ,(aref pkg-info 2)
+        ',(mapcar
+           (lambda (elt)
+             (list (car elt)
+                   (package-version-join (cadr elt))))
+           (aref pkg-info 1))
+        ;; Append our extra information
+        ,@(cl-mapcan (lambda (entry)
+                       (let ((value (cdr entry)))
+                         (when (or (symbolp value) (listp value))
+                           ;; We must quote lists and symbols,
+                           ;; because Emacs 24.3 and earlier evaluate
+                           ;; the package information, which would
+                           ;; break for unquoted symbols or lists
+                           (setq value (list 'quote value)))
+                         (list (car entry) value)))
+                     (when (> (length pkg-info) 4)
+                       (aref pkg-info 4))))
+     (current-buffer))
+    (princ ";; Local Variables:\n;; no-byte-compile: t\n;; End:\n"
+           (current-buffer))))
+
+(defun quelpa-build--read-from-file (file)
+  "Read and return the Lisp data stored in FILE, or nil if no such file exists."
+  (when (file-exists-p file)
+    (car (read-from-string (quelpa-build--slurp-file file)))))
+
+(defun quelpa-build--create-tar (file dir &optional files)
+  "Create a tar FILE containing the contents of DIR, or just FILES if non-nil."
+  (when (eq system-type 'windows-nt)
+    (setq file (replace-regexp-in-string "^\\([a-z]\\):" "/\\1" file)))
+  (apply 'process-file
+         quelpa-build-tar-executable nil
+         (get-buffer-create "*quelpa-build-checkout*")
+         nil "-cvf"
+         file
+         "--exclude=.svn"
+         "--exclude=CVS"
+         "--exclude=.git"
+         "--exclude=_darcs"
+         "--exclude=.fslckout"
+         "--exclude=_FOSSIL_"
+         "--exclude=.bzr"
+         "--exclude=.hg"
+         (or (mapcar (lambda (fn) (concat dir "/" fn)) files) (list dir))))
+
+(defun quelpa-build--find-package-commentary (file-path)
+  "Get commentary section from FILE-PATH."
+  (when (file-exists-p file-path)
+    (with-temp-buffer
+      (insert-file-contents file-path)
+      (lm-commentary))))
+
+(defun quelpa-build--write-pkg-readme (target-dir commentary file-name)
+  "In TARGET-DIR, write COMMENTARY to a -readme.txt file prefixed with FILE-NAME."
+  (when commentary
+    (with-temp-buffer
+      (insert commentary)
+      ;; Adapted from `describe-package-1'.
+      (goto-char (point-min))
+      (save-excursion
+        (when (re-search-forward "^;;; Commentary:\n" nil t)
+          (replace-match ""))
+        (while (re-search-forward "^\\(;+ ?\\)" nil t)
+          (replace-match ""))
+        (goto-char (point-min))
+        (when (re-search-forward "\\`\\( *\n\\)+" nil t)
+          (replace-match "")))
+      (delete-trailing-whitespace)
+      (let ((coding-system-for-write buffer-file-coding-system))
+        (write-region nil nil
+                      (quelpa-build--readme-file-name target-dir file-name))))))
+
+(defun quelpa-build--readme-file-name (target-dir file-name)
+  "Name of the readme file in TARGET-DIR for the package FILE-NAME."
+  (expand-file-name (concat file-name "-readme.txt")
+                    target-dir))
+
+(defun quelpa-build--update-or-insert-version (version)
+  "Ensure current buffer has a \"Package-Version: VERSION\" header."
+  (goto-char (point-min))
+  (if (let ((case-fold-search t))
+        (re-search-forward "^;+* *Package-Version *: *" nil t))
+      (progn
+        (move-beginning-of-line nil)
+        (search-forward "V" nil t)
+        (backward-char)
+        (insert "X-Original-")
+        (move-beginning-of-line nil))
+    ;; Put the new header in a sensible place if we can
+    (re-search-forward "^;+* *\\(Version\\|Package-Requires\\|Keywords\\|URL\\) *:"
+                       nil t)
+    (forward-line))
+  (insert (format ";; Package-Version: %s" version))
+  (newline))
+
+(defun quelpa-build--ensure-ends-here-line (file-path)
+  "Add a 'FILE-PATH ends here' trailing line if missing."
+  (save-excursion
+    (goto-char (point-min))
+    (let ((trailer (concat ";;; "
+                           (file-name-nondirectory file-path)
+                           " ends here")))
+      (unless (search-forward trailer nil t)
+        (goto-char (point-max))
+        (newline)
+        (insert trailer)
+        (newline)))))
+
+(defun quelpa-build--get-package-info (file-path)
+  "Get a vector of package info from the docstrings in FILE-PATH."
+  (when (file-exists-p file-path)
+    (ignore-errors
+      (with-temp-buffer
+        (insert-file-contents file-path)
+        ;; next few lines are a hack for some packages that aren't
+        ;; commented properly.
+        (quelpa-build--update-or-insert-version "0")
+        (quelpa-build--ensure-ends-here-line file-path)
+        (cl-flet ((package-strip-rcs-id (str) "0"))
+          (quelpa-build--package-buffer-info-vec))))))
+
+(defun quelpa-build--get-pkg-file-info (file-path)
+  "Get a vector of package info from \"-pkg.el\" file FILE-PATH."
+  (when (file-exists-p file-path)
+    (let ((package-def (quelpa-build--read-from-file file-path)))
+      (if (eq 'define-package (car package-def))
+          (let* ((pkgfile-info (cdr package-def))
+                 (descr (nth 2 pkgfile-info))
+                 (rest-plist (cl-subseq pkgfile-info (min 4 (length pkgfile-info))))
+                 (extras (let (alist)
+                           (while rest-plist
+                             (unless (memq (car rest-plist) '(:kind :archive))
+                               (let ((value (cadr rest-plist)))
+                                 (when value
+                                   (push (cons (car rest-plist)
+                                               (if (eq (car-safe value) 'quote)
+                                                   (cadr value)
+                                                 value))
+                                         alist))))
+                             (setq rest-plist (cddr rest-plist)))
+                           alist)))
+            (when (string-match "[\r\n]" descr)
+              (error "Illegal multi-line package description in %s" file-path))
+            (vector
+             (nth 0 pkgfile-info)
+             (mapcar
+              (lambda (elt)
+                (unless (symbolp (car elt))
+                  (error "Invalid package name in dependency: %S" (car elt)))
+                (list (car elt) (version-to-list (cadr elt))))
+              (eval (nth 3 pkgfile-info)))
+             descr
+             (nth 1 pkgfile-info)
+             extras))
+        (error "No define-package found in %s" file-path)))))
+
+(defun quelpa-build--merge-package-info (pkg-info name version)
+  "Return a version of PKG-INFO updated with NAME, VERSION and info from CONFIG.
+If PKG-INFO is nil, an empty one is created."
+  (let ((merged (or (copy-sequence pkg-info)
+                    (vector name nil "No description available." version))))
+    (aset merged 0 name)
+    (aset merged 3 version)
+    merged))
+
+(defun quelpa-build--archive-entry (pkg-info type)
+  "Return the archive-contents cons cell for PKG-INFO and TYPE."
+  (let ((name (intern (aref pkg-info 0)))
+        (requires (aref pkg-info 1))
+        (desc (or (aref pkg-info 2) "No description available."))
+        (version (aref pkg-info 3))
+        (extras (and (> (length pkg-info) 4)
+                     (aref pkg-info 4))))
+    (cons name
+          (vector (version-to-list version)
+                  requires
+                  desc
+                  type
+                  extras))))
+
+;;; Recipes
+
+(defun quelpa-build-expand-file-specs (dir specs &optional subdir allow-empty)
+  "In DIR, expand SPECS, optionally under SUBDIR.
+The result is a list of (SOURCE . DEST), where SOURCE is a source
+file path and DEST is the relative path to which it should be copied.
+
+If the resulting list is empty, an error will be reported.  Pass t
+for ALLOW-EMPTY to prevent this error."
+  (let ((default-directory dir)
+        (prefix (if subdir (format "%s/" subdir) ""))
+        (lst))
+    (dolist (entry specs lst)
+      (setq lst
+            (if (consp entry)
+                (if (eq :exclude (car entry))
+                    (cl-nset-difference lst
+                                        (quelpa-build-expand-file-specs
+                                         dir (cdr entry) nil t)
+                                        :key 'car
+                                        :test 'equal)
+                  (nconc lst
+                         (quelpa-build-expand-file-specs
+                          dir
+                          (cdr entry)
+                          (concat prefix (car entry))
+                          t)))
+              (nconc
+               lst (mapcar (lambda (f)
+                             (let ((destname)))
+                             (cons f
+                                   (concat prefix
+                                           (replace-regexp-in-string
+                                            "\\.in\\'"
+                                            ""
+                                            (file-name-nondirectory f)))))
+                           (file-expand-wildcards entry))))))
+    (when (and (null lst) (not allow-empty))
+      (error "No matching file(s) found in %s: %s" dir specs))
+    lst))
+
+(defun quelpa-build--config-file-list (config)
+  "Get the :files spec from CONFIG, or return `quelpa-build-default-files-spec'."
+  (let ((file-list (plist-get config :files)))
+    (cond
+     ((null file-list)
+      quelpa-build-default-files-spec)
+     ((eq :defaults (car file-list))
+      (append quelpa-build-default-files-spec (cdr file-list)))
+     (t
+      file-list))))
+
+(defun quelpa-build--expand-source-file-list (dir config)
+  "Shorthand way to expand paths in DIR for source files listed in CONFIG."
+  (mapcar 'car
+          (quelpa-build-expand-file-specs
+           dir (quelpa-build--config-file-list config))))
+
+(defun quelpa-build--generate-info-files (files source-dir target-dir)
+  "Create .info files from any .texi files listed in FILES.
+
+The source and destination file paths are expanded in SOURCE-DIR
+and TARGET-DIR respectively.
+
+Any of the original .texi(nfo) files found in TARGET-DIR are
+deleted."
+  (dolist (spec files)
+    (let* ((source-file (car spec))
+           (source-path (expand-file-name source-file source-dir))
+           (dest-file (cdr spec))
+           (info-path (expand-file-name
+                       (concat (file-name-sans-extension dest-file) ".info")
+                       target-dir)))
+      (when (string-match ".texi\\(nfo\\)?$" source-file)
+        (when (not (file-exists-p info-path))
+          (with-current-buffer (get-buffer-create "*quelpa-build-info*")
+            (ignore-errors
+              (quelpa-build--run-process
+               (file-name-directory source-path)
+               "makeinfo"
+               source-path
+               "-o"
+               info-path)
+              (quelpa-build--message "Created %s" info-path))))
+        (quelpa-build--message "Removing %s"
+                               (expand-file-name dest-file target-dir))
+        (delete-file (expand-file-name dest-file target-dir))))))
+
+;;; Info Manuals
+
+(defun quelpa-build--generate-dir-file (files target-dir)
+  "Create dir file from any .info files listed in FILES in TARGET-DIR."
+  (dolist (spec files)
+    (let* ((source-file (car spec))
+           (dest-file (cdr spec))
+           (info-path (expand-file-name
+                       (concat (file-name-sans-extension dest-file) ".info")
+                       target-dir)))
+      (when (and (or (string-match ".info$" source-file)
+                     (string-match ".texi\\(nfo\\)?$" source-file))
+                 (file-exists-p info-path))
+        (with-current-buffer (get-buffer-create "*quelpa-build-info*")
+          (ignore-errors
+            (quelpa-build--run-process
+             nil
+             "install-info"
+             (concat "--dir=" (expand-file-name "dir" target-dir))
+             info-path)))))))
+
+;;; Utilities
+
+(defun quelpa-build--copy-package-files (files source-dir target-dir)
+  "Copy FILES from SOURCE-DIR to TARGET-DIR.
+FILES is a list of (SOURCE . DEST) relative filepath pairs."
+  (cl-loop for (source-file . dest-file) in files
+           do (quelpa-build--copy-file
+               (expand-file-name source-file source-dir)
+               (expand-file-name dest-file target-dir))))
+
+(defun quelpa-build--copy-file (file newname)
+  "Copy FILE to NEWNAME and create parent directories for NEWNAME if they don't exist."
+  (let ((newdir (file-name-directory newname)))
+    (unless (file-exists-p newdir)
+      (make-directory newdir t)))
+  (cond
+   ((file-regular-p file)
+    (quelpa-build--message "%s -> %s" file newname)
+    (copy-file file newname))
+   ((file-directory-p file)
+    (quelpa-build--message "%s => %s" file newname)
+    (copy-directory file newname))))
+
+(defun quelpa-build--find-source-file (target files)
+  "Search for source of TARGET in FILES."
+  (car (rassoc target files)))
+
+(defun quelpa-build--package-buffer-info-vec ()
+  "Return a vector of package info.
+`package-buffer-info' returns a vector in older Emacs versions,
+and a cl struct in Emacs HEAD.  This wrapper normalises the results."
+  (let ((desc (package-buffer-info))
+        (keywords (lm-keywords-list)))
+    (if (fboundp 'package-desc-create)
+        (let ((extras (package-desc-extras desc)))
+          (when (and keywords (not (assq :keywords extras)))
+            ;; Add keywords to package properties, if not already present
+            (push (cons :keywords keywords) extras))
+          (vector (package-desc-name desc)
+                  (package-desc-reqs desc)
+                  (package-desc-summary desc)
+                  (package-desc-version desc)
+                  extras))
+      ;; The regexp and the processing is taken from `lm-homepage' in Emacs 24.4
+      (let* ((page (lm-header "\\(?:x-\\)?\\(?:homepage\\|url\\)"))
+             (homepage (if (and page (string-match "^<.+>$" page))
+                           (substring page 1 -1)
+                         page))
+             extras)
+        (when keywords (push (cons :keywords keywords) extras))
+        (when homepage (push (cons :url homepage) extras))
+        (vector  (aref desc 0)
+                 (aref desc 1)
+                 (aref desc 2)
+                 (aref desc 3)
+                 extras)))))
+
+;;; Building
+
+;;;###autoload
+(defun quelpa-build-package (package-name version file-specs source-dir target-dir)
+  "Create PACKAGE-NAME with VERSION.
+
+The information in FILE-SPECS is used to gather files from
+SOURCE-DIR.
+
+The resulting package will be stored as a .el or .tar file in
+TARGET-DIR, depending on whether there are multiple files.
+
+Argument FILE-SPECS is a list of specs for source files, which
+should be relative to SOURCE-DIR.  The specs can be wildcards,
+and optionally specify different target paths.  They extended
+syntax is currently only documented in the MELPA README.  You can
+simply pass `quelpa-build-default-files-spec' in most cases.
+
+Returns the archive entry for the package."
+  (when (symbolp package-name)
+    (setq package-name (symbol-name package-name)))
+  (let ((files (quelpa-build-expand-file-specs source-dir file-specs)))
+    (unless (equal file-specs quelpa-build-default-files-spec)
+      (when (equal files (quelpa-build-expand-file-specs
+                          source-dir quelpa-build-default-files-spec nil t))
+        (quelpa-build--message "Note: %s :files spec is equivalent to the default."
+                               package-name)))
+    (cond
+     ((not version)
+      (error "Unable to check out repository for %s" package-name))
+     ((= 1 (length files))
+      (quelpa-build--build-single-file-package
+       package-name version (caar files) source-dir target-dir))
+     ((< 1 (length  files))
+      (quelpa-build--build-multi-file-package
+       package-name version files source-dir target-dir))
+     (t (error "Unable to find files matching recipe patterns")))))
+
+(defun quelpa-build--build-single-file-package
+    (package-name version file source-dir target-dir)
+  (let* ((pkg-source (expand-file-name file source-dir))
+         (pkg-target (expand-file-name
+                      (concat package-name "-" version ".el")
+                      target-dir))
+         (pkg-info (quelpa-build--merge-package-info
+                    (quelpa-build--get-package-info pkg-source)
+                    package-name
+                    version)))
+    (unless (string-equal (downcase (concat package-name ".el"))
+                          (downcase (file-name-nondirectory pkg-source)))
+      (error "Single file %s does not match package name %s"
+             (file-name-nondirectory pkg-source) package-name))
+    (if (file-exists-p pkg-target)
+        (quelpa-build--message "Skipping rebuild of %s" pkg-target)
+      (copy-file pkg-source pkg-target)
+      (let ((enable-local-variables nil)
+            (make-backup-files nil))
+        (with-temp-buffer
+          (insert-file-contents pkg-target)
+          (quelpa-build--update-or-insert-version version)
+          (quelpa-build--ensure-ends-here-line pkg-source)
+          (write-file pkg-target nil)
+          (condition-case err
+              (quelpa-build--package-buffer-info-vec)
+            (error
+             (quelpa-build--message "Warning: %S" err)))))
+
+      (quelpa-build--write-pkg-readme
+       target-dir
+       (quelpa-build--find-package-commentary pkg-source)
+       package-name))
+    (quelpa-build--archive-entry pkg-info 'single)))
+
+(defun quelpa-build--build-multi-file-package
+    (package-name version files source-dir target-dir)
+  (let ((tmp-dir (file-name-as-directory (make-temp-file package-name t))))
+    (unwind-protect
+        (let* ((pkg-dir-name (concat package-name "-" version))
+               (pkg-tmp-dir (expand-file-name pkg-dir-name tmp-dir))
+               (pkg-file (concat package-name "-pkg.el"))
+               (pkg-file-source (or (quelpa-build--find-source-file pkg-file files)
+                                    pkg-file))
+               (file-source (concat package-name ".el"))
+               (pkg-source (or (quelpa-build--find-source-file file-source files)
+                               file-source))
+               (pkg-info (quelpa-build--merge-package-info
+                          (let ((default-directory source-dir))
+                            (or (quelpa-build--get-pkg-file-info pkg-file-source)
+                                ;; some packages (like magit) provide name-pkg.el.in
+                                (quelpa-build--get-pkg-file-info
+                                 (expand-file-name (concat pkg-file ".in")
+                                                   (file-name-directory pkg-source)))
+                                (quelpa-build--get-package-info pkg-source)))
+                          package-name
+                          version)))
+          (quelpa-build--copy-package-files files source-dir pkg-tmp-dir)
+          (quelpa-build--write-pkg-file (expand-file-name
+                                         pkg-file
+                                         (file-name-as-directory pkg-tmp-dir))
+                                        pkg-info)
+
+          (quelpa-build--generate-info-files files source-dir pkg-tmp-dir)
+          (quelpa-build--generate-dir-file files pkg-tmp-dir)
+
+          (let ((default-directory tmp-dir))
+            (quelpa-build--create-tar
+             (expand-file-name (concat package-name "-" version ".tar")
+                               target-dir)
+             pkg-dir-name))
+
+          (let ((default-directory source-dir))
+            (quelpa-build--write-pkg-readme
+             target-dir
+             (quelpa-build--find-package-commentary pkg-source)
+             package-name))
+          (quelpa-build--archive-entry pkg-info 'tar))
+      (delete-directory tmp-dir t nil))))
+
+(defun quelpa-build--checkout-file (name config dir)
+  "Build according to a PATH with config CONFIG into DIR as NAME.
+Generic local file handler for package-build.el.
+
+Handles the following cases:
+
+local file:
+
+Installs a single-file package from a local file.  Use the :path
+attribute with a PATH like \"/path/to/file.el\".
+
+local directory:
+
+Installs a multi-file package from a local directory.  Use
+the :path attribute with a PATH like \"/path/to/dir\"."
+  (quelpa-check-hash name config (expand-file-name (plist-get config :path)) dir))
+
+(defun quelpa-build--checkout-url (name config dir)
+  "Build according to an URL with config CONFIG into DIR as NAME.
+Generic URL handler for package-build.el.
+
+Handles the following cases:
+
+local file:
+
+Installs a single-file package from a local file.  Use the :url
+attribute with an URL like \"file:///path/to/file.el\".
+
+remote file:
+
+Installs a single-file package from a remote file.  Use the :url
+attribute with an URL like \"http://domain.tld/path/to/file.el\"."
+  (let* ((url (plist-get config :url))
+         (remote-file-name (file-name-nondirectory
+                            (url-filename (url-generic-parse-url url))))
+         (local-path (expand-file-name remote-file-name dir))
+         (mm-attachment-file-modes (default-file-modes)))
+    (unless (string= (file-name-extension url) "el")
+      (error "<%s> does not end in .el" url))
+    (unless (file-directory-p dir)
+      (make-directory dir))
+    (url-copy-file url local-path t)
+    (quelpa-check-hash name config local-path dir 'url)))
+
+;; --- helpers ---------------------------------------------------------------
+
+(defun quelpa-message (wait format-string &rest args)
+  "Log a message with FORMAT-STRING and ARGS when `quelpa-verbose' is non-nil.
+If WAIT is nil don't wait after showing the message. If it is a
+number, wait so many seconds. If WAIT is t wait the default time.
+Return t in each case."
+  (when quelpa-verbose
+    (message "Quelpa: %s" (apply 'format format-string args))
+    (when (or (not noninteractive) wait) ; no wait if emacs is noninteractive
+      (sit-for (or (and (numberp wait) wait) 1.5) t)))
+  t)
+
+(defun quelpa-read-cache ()
+  "Read from `quelpa-persistent-cache-file' in `quelpa-cache'."
+  (when (and quelpa-persistent-cache-p
+             (file-exists-p quelpa-persistent-cache-file))
+    (with-temp-buffer
+      (insert-file-contents-literally quelpa-persistent-cache-file)
+      (setq quelpa-cache
+            (read (buffer-substring-no-properties (point-min) (point-max)))))))
+
+(defun quelpa-save-cache ()
+  "Write `quelpa-cache' to `quelpa-persistent-cache-file'."
+  (when quelpa-persistent-cache-p
+    (let (print-level print-length)
+      (with-temp-file quelpa-persistent-cache-file
+        (insert (prin1-to-string quelpa-cache))))))
+
+(defun quelpa-update-cache (cache-item)
+  ;; try removing existing recipes by name
+  (setq quelpa-cache (cl-remove (car cache-item)
+                                quelpa-cache :key #'car))
+  (push cache-item quelpa-cache)
+  (setq quelpa-cache
+        (cl-sort quelpa-cache #'string<
+                 :key (lambda (item) (symbol-name (car item))))))
+
+(defun quelpa-parse-stable (cache-item)
+  ;; in case :stable doesn't originate from PLIST, shadow the
+  ;; default value anyways
+  (when (plist-member (cdr cache-item) :stable)
+    (setq quelpa-stable-p (plist-get (cdr cache-item) :stable)))
+  (when (and quelpa-stable-p (not (plist-get (cdr cache-item) :stable)))
+    (setf (cdr (last cache-item)) '(:stable t))))
+
+(defun quelpa-checkout-melpa ()
+  "Fetch or update the melpa source code from Github.
+If there is no error return non-nil.
+If there is an error but melpa is already checked out return non-nil.
+If there is an error and no existing checkout return nil."
+  (or (and (null quelpa-update-melpa-p)
+           (file-exists-p (expand-file-name ".git" quelpa-melpa-dir)))
+      (condition-case err
+          (quelpa-build--checkout-git
+           'package-build
+           `(:url ,quelpa-melpa-repo-url :files ("*"))
+           quelpa-melpa-dir)
+        (error "failed to checkout melpa git repo: `%s'" (error-message-string err)))))
+
+(defun quelpa-get-melpa-recipe (name)
+  "Read recipe with NAME for melpa git checkout.
+Return the recipe if it exists, otherwise nil."
+  (cl-loop for store in quelpa-melpa-recipe-stores
+           if (stringp store)
+           for file = (assoc-string name (directory-files store nil "^[^\.]+"))
+           when file
+           return (with-temp-buffer
+                    (insert-file-contents-literally
+                     (expand-file-name file store))
+                    (read (buffer-string)))
+           else
+           for rcp = (assoc-string name store)
+           when rcp
+           return rcp))
+
+(defun quelpa-setup-p ()
+  "Setup what we need for quelpa.
+Return non-nil if quelpa has been initialized properly."
+  (catch 'quit
+    (dolist (dir (list quelpa-packages-dir quelpa-build-dir))
+      (unless (file-exists-p dir) (make-directory dir t)))
+    (unless quelpa-initialized-p
+      (quelpa-read-cache)
+      (quelpa-setup-package-structs)
+      (if quelpa-checkout-melpa-p
+          (unless (quelpa-checkout-melpa) (throw 'quit nil)))
+      (setq quelpa-initialized-p t))
+    t))
+
+(defun quelpa-shutdown ()
+  "Do things that need to be done after running quelpa."
+  (quelpa-save-cache)
+  ;; remove the packages dir because we are done with the built pkgs
+  (ignore-errors (delete-directory quelpa-packages-dir t)))
+
+(defun quelpa-arg-rcp (arg)
+  "Given recipe or package name, return an alist '(NAME . RCP).
+If RCP cannot be found it will be set to nil"
+  (pcase arg
+    (`(,a . nil) (quelpa-get-melpa-recipe (car arg)))
+    (`(,a . ,_) arg)
+    ((pred symbolp) (quelpa-get-melpa-recipe arg))))
+
+(defun quelpa-parse-plist (plist)
+  "Parse the optional PLIST argument of `quelpa'.
+Recognized keywords are:
+
+:upgrade
+
+If t, `quelpa' tries to do an upgrade.
+
+:stable
+
+If t, `quelpa' tries building the stable version of a package."
+  (while plist
+    (let ((key (car plist))
+          (value (cadr plist)))
+      (pcase key
+        (:upgrade (setq quelpa-upgrade-p value))
+        (:stable (setq quelpa-stable-p value))))
+    (setq plist (cddr plist))))
+
+(defun quelpa-package-install-file (file)
+  "Workaround problem with `package-install-file'.
+`package-install-file' uses `insert-file-contents-literally'
+which causes problems when the file inserted has crlf line
+endings (Windows). So here we replace that with
+`insert-file-contents' for non-tar files."
+  (if (eq system-type 'windows-nt)
+      (cl-letf* ((insert-file-contents-literally-orig
+                  (symbol-function 'insert-file-contents-literally))
+                 ((symbol-function 'insert-file-contents-literally)
+                  (lambda (file)
+                    (if (string-match "\\.tar\\'" file)
+                        (funcall insert-file-contents-literally-orig file)
+                      (insert-file-contents file)))))
+        (package-install-file file))
+    (package-install-file file)))
+
+(defun quelpa-package-install (arg)
+  "Build and install package from ARG (a recipe or package name).
+If the package has dependencies recursively call this function to
+install them."
+  (let* ((rcp (quelpa-arg-rcp arg))
+         (file (and rcp (quelpa-build rcp))))
+    (when file
+      (let* ((pkg-desc (quelpa-get-package-desc file))
+             (requires (package-desc-reqs pkg-desc)))
+        (when requires
+          (mapc (lambda (req)
+                  (unless (or (equal 'emacs (car req))
+                              (package-installed-p (car req) (cadr req)))
+                    (quelpa-package-install (car req))))
+                requires))
+        (quelpa-package-install-file file)))))
+
+(defun quelpa-interactive-candidate ()
+  "Query the user for a recipe and return the name."
+  (when (quelpa-setup-p)
+    (let  ((recipes (cl-loop
+                     for store in quelpa-melpa-recipe-stores
+                     if (stringp store)
+                     ;; this regexp matches all files except dotfiles
+                     append (directory-files store nil "^[^.].+$")
+                     else if (listp store)
+                     append store)))
+      (intern (completing-read "Choose MELPA recipe: "
+                               recipes nil t)))))
+
+;; --- public interface ------------------------------------------------------
+
+;;;###autoload
+(defun quelpa-expand-recipe (recipe-name)
+  "Expand a given recipe name into full recipe.
+If called interactively, let the user choose a recipe name and
+insert the result into the current buffer."
+  (interactive (list (quelpa-interactive-candidate)))
+  (when (quelpa-setup-p)
+    (let* ((recipe (quelpa-get-melpa-recipe recipe-name)))
+      (when recipe
+        (if (called-interactively-p 'any)
+            (prin1 recipe (current-buffer)))
+        recipe))))
+
+;;;###autoload
+(defun quelpa-self-upgrade (&optional args)
+  "Upgrade quelpa itself.
+ARGS are additional options for the quelpa recipe."
+  (interactive)
+  (when (quelpa-setup-p)
+    (quelpa (append quelpa-recipe args) :upgrade t)))
+
+;;;###autoload
+(defun quelpa-upgrade ()
+  "Upgrade all packages found in `quelpa-cache'.
+This provides an easy way to upgrade all the packages for which
+the `quelpa' command has been run in the current Emacs session."
+  (interactive)
+  (when (quelpa-setup-p)
+    (let ((quelpa-upgrade-p t))
+      (when quelpa-self-upgrade-p
+        (quelpa-self-upgrade))
+      (setq quelpa-cache
+            (cl-remove-if-not #'package-installed-p quelpa-cache :key #'car))
+      (mapc (lambda (item)
+              (when (package-installed-p (car (quelpa-arg-rcp item)))
+                (quelpa item)))
+            quelpa-cache))))
+
+;;;###autoload
+(defun quelpa (arg &rest plist)
+  "Build and install a package with quelpa.
+ARG can be a package name (symbol) or a melpa recipe (list).
+PLIST is a plist that may modify the build and/or fetch process.
+If called interactively, `quelpa' will prompt for a MELPA package
+to install.
+
+When `quelpa' is called interactively with a prefix argument (e.g
+C-u M-x quelpa) it will try to upgrade the given package even if
+the global var `quelpa-upgrade-p' is set to nil."
+
+  (interactive (list (quelpa-interactive-candidate)))
+  (run-hooks 'quelpa-before-hook)
+  (when (quelpa-setup-p) ;if init fails we do nothing
+    (let* ((quelpa-upgrade-p (if current-prefix-arg t quelpa-upgrade-p)) ;shadow `quelpa-upgrade-p'
+           (quelpa-stable-p quelpa-stable-p) ;shadow `quelpa-stable-p'
+           (cache-item (if (symbolp arg) (list arg) arg)))
+      (quelpa-parse-plist plist)
+      (quelpa-parse-stable cache-item)
+      (quelpa-package-install arg)
+      (quelpa-update-cache cache-item)))
+  (quelpa-shutdown)
+  (run-hooks 'quelpa-after-hook))
+
+(provide 'quelpa)
+
+;;; quelpa.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/quelpa-0.0.1/quelpa.elc b/configs/shared/emacs/.emacs.d/elpa/quelpa-0.0.1/quelpa.elc
new file mode 100644
index 0000000000..010c585bb8
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/quelpa-0.0.1/quelpa.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/quelpa-20180711.1638/bootstrap.el b/configs/shared/emacs/.emacs.d/elpa/quelpa-20180711.1638/bootstrap.el
new file mode 100644
index 0000000000..1e41c6577d
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/quelpa-20180711.1638/bootstrap.el
@@ -0,0 +1,32 @@
+;;; bootstrap.el --- Bootstrap quelpa.el
+
+;; Copyright 2014-2018, Steckerhalter
+
+;; Author: steckerhalter
+;; URL: https://framagit.org/steckerhalter/quelpa
+;; Version: 0.0.1
+;; License: https://framagit.org/steckerhalter/quelpa/LICENSE
+
+;; This file is not part of GNU Emacs.
+
+;;; Code:
+
+(require 'package)
+
+(defvar quelpa-ci-dir nil
+  "If non-nil, quelpa will not be loaded from the url but from the given dir.")
+
+;; `package' has to be initialized to install pkgs
+(package-initialize)
+
+(let ((temp-dir (make-temp-file "quelpa" t)))
+  (unless (require 'quelpa nil t)
+    (let ((file (or (when quelpa-ci-dir (concat quelpa-ci-dir "/quelpa.el"))
+                    (expand-file-name "quelpa.el" temp-dir))))
+      (unless quelpa-ci-dir
+        (url-copy-file "https://framagit.org/steckerhalter/quelpa/raw/master/quelpa.el" file t))
+      (package-install-file file)))
+
+  (delete-directory temp-dir t))
+
+;;; bootstrap.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/quelpa-20180711.1638/bootstrap.elc b/configs/shared/emacs/.emacs.d/elpa/quelpa-20180711.1638/bootstrap.elc
new file mode 100644
index 0000000000..9bef20457b
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/quelpa-20180711.1638/bootstrap.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/quelpa-20180711.1638/quelpa-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/quelpa-20180711.1638/quelpa-autoloads.el
new file mode 100644
index 0000000000..67e2caa291
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/quelpa-20180711.1638/quelpa-autoloads.el
@@ -0,0 +1,73 @@
+;;; quelpa-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "quelpa" "quelpa.el" (23377 60566 602757 87000))
+;;; Generated autoloads from quelpa.el
+
+(autoload 'quelpa-build-package "quelpa" "\
+Create PACKAGE-NAME with VERSION.
+
+The information in FILE-SPECS is used to gather files from
+SOURCE-DIR.
+
+The resulting package will be stored as a .el or .tar file in
+TARGET-DIR, depending on whether there are multiple files.
+
+Argument FILE-SPECS is a list of specs for source files, which
+should be relative to SOURCE-DIR.  The specs can be wildcards,
+and optionally specify different target paths.  They extended
+syntax is currently only documented in the MELPA README.  You can
+simply pass `quelpa-build-default-files-spec' in most cases.
+
+Returns the archive entry for the package.
+
+\(fn PACKAGE-NAME VERSION FILE-SPECS SOURCE-DIR TARGET-DIR)" nil nil)
+
+(autoload 'quelpa-expand-recipe "quelpa" "\
+Expand a given recipe name into full recipe.
+If called interactively, let the user choose a recipe name and
+insert the result into the current buffer.
+
+\(fn RECIPE-NAME)" t nil)
+
+(autoload 'quelpa-self-upgrade "quelpa" "\
+Upgrade quelpa itself.
+ARGS are additional options for the quelpa recipe.
+
+\(fn &optional ARGS)" t nil)
+
+(autoload 'quelpa-upgrade "quelpa" "\
+Upgrade all packages found in `quelpa-cache'.
+This provides an easy way to upgrade all the packages for which
+the `quelpa' command has been run in the current Emacs session.
+
+\(fn)" t nil)
+
+(autoload 'quelpa "quelpa" "\
+Build and install a package with quelpa.
+ARG can be a package name (symbol) or a melpa recipe (list).
+PLIST is a plist that may modify the build and/or fetch process.
+If called interactively, `quelpa' will prompt for a MELPA package
+to install.
+
+When `quelpa' is called interactively with a prefix argument (e.g
+C-u M-x quelpa) it will try to upgrade the given package even if
+the global var `quelpa-upgrade-p' is set to nil.
+
+\(fn ARG &rest PLIST)" t nil)
+
+;;;***
+
+;;;### (autoloads nil nil ("bootstrap.el" "quelpa-pkg.el") (23377
+;;;;;;  60566 606267 370000))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; quelpa-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/quelpa-20180711.1638/quelpa-pkg.el b/configs/shared/emacs/.emacs.d/elpa/quelpa-20180711.1638/quelpa-pkg.el
new file mode 100644
index 0000000000..45e0c421de
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/quelpa-20180711.1638/quelpa-pkg.el
@@ -0,0 +1,12 @@
+(define-package "quelpa" "20180711.1638" "Emacs Lisp packages built directly from source"
+  '((emacs "24.3"))
+  :keywords
+  '("package" "management" "build" "source" "elpa")
+  :authors
+  '(("steckerhalter"))
+  :maintainer
+  '("steckerhalter")
+  :url "https://framagit.org/steckerhalter/quelpa")
+;; Local Variables:
+;; no-byte-compile: t
+;; End:
diff --git a/configs/shared/emacs/.emacs.d/elpa/quelpa-20180711.1638/quelpa.el b/configs/shared/emacs/.emacs.d/elpa/quelpa-20180711.1638/quelpa.el
new file mode 100644
index 0000000000..0994a7cf76
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/quelpa-20180711.1638/quelpa.el
@@ -0,0 +1,1799 @@
+;;; quelpa.el --- Emacs Lisp packages built directly from source
+
+;; Copyright 2014-2018, Steckerhalter
+;; Copyright 2014-2015, Vasilij Schneidermann <v.schneidermann@gmail.com>
+
+;; Author: steckerhalter
+;; URL: https://framagit.org/steckerhalter/quelpa
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "24.3"))
+;; Keywords: package management build source elpa
+
+;; This file is not part of GNU Emacs.
+
+;; This file 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, or (at your option)
+;; any later version.
+
+;; This file 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; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+
+;; Your personal local Emacs Lisp Package Archive (ELPA) with packages
+;; built on-the-fly directly from source.
+
+;; See the README for more info:
+;; https://framagit.org/steckerhalter/quelpa/blob/master/README.md
+
+;;; Requirements:
+
+;; Emacs 24.3.1
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'help-fns)
+(require 'url-parse)
+(require 'package)
+(require 'lisp-mnt)
+
+;; --- customs / variables ---------------------------------------------------
+
+(defgroup quelpa nil
+  "Build and install packages from source code"
+  :group 'package)
+
+(defcustom quelpa-upgrade-p nil
+  "When non-nil, `quelpa' will try to upgrade packages.
+The global value can be overridden for each package by supplying
+the `:upgrade' argument."
+  :group 'quelpa
+  :type 'boolean)
+
+(defcustom quelpa-stable-p nil
+  "When non-nil, try to build stable packages like MELPA does."
+  :group 'quelpa
+  :type 'boolean)
+
+(defcustom quelpa-verbose t
+  "When non-nil, `quelpa' prints log messages."
+  :group 'quelpa
+  :type 'boolean)
+
+(defcustom quelpa-before-hook nil
+  "List of functions to be called before quelpa."
+  :group 'quelpa
+  :type 'hook)
+
+(defcustom quelpa-after-hook nil
+  "List of functions to be called after quelpa."
+  :group 'quelpa
+  :type 'hook)
+
+(defcustom quelpa-dir (expand-file-name "quelpa" user-emacs-directory)
+  "Where quelpa builds and stores packages."
+  :group 'quelpa
+  :type 'string)
+
+(defcustom quelpa-melpa-dir (expand-file-name "melpa" quelpa-dir)
+  "Where the melpa repo cloned to."
+  :group 'quelpa
+  :type 'string)
+
+(defcustom quelpa-build-dir (expand-file-name "build" quelpa-dir)
+  "Where quelpa builds packages."
+  :group 'quelpa
+  :type 'string)
+
+(defcustom quelpa-packages-dir (expand-file-name "packages" quelpa-dir)
+  "Where quelpa puts built packages."
+  :group 'quelpa
+  :type 'string)
+
+(defcustom quelpa-melpa-recipe-stores (list (expand-file-name
+                                             "recipes"
+                                             quelpa-melpa-dir))
+  "Recipe stores where quelpa finds default recipes for packages.
+A store can either be a string pointing to a directory with
+recipe files or a list with recipes."
+  :group 'quelpa
+  :type '(repeat
+          (choice directory
+                  (repeat
+                   :tag "List of recipes"
+                   (restricted-sexp :tag "Recipe"
+                                    :match-alternatives (listp))))))
+
+(defcustom quelpa-persistent-cache-file (expand-file-name "cache" quelpa-dir)
+  "Location of the persistent cache file."
+  :group 'quelpa
+  :type 'string)
+
+(defcustom quelpa-persistent-cache-p t
+  "Non-nil when quelpa's cache is saved on and read from disk."
+  :group 'quelpa
+  :type 'boolean)
+
+(defcustom quelpa-checkout-melpa-p t
+  "If non-nil the MELPA git repo is cloned when quelpa is initialized."
+  :group 'quelpa
+  :type 'boolean)
+
+(defcustom quelpa-update-melpa-p t
+  "If non-nil the MELPA git repo is updated when quelpa is initialized.
+If nil the update is disabled and the repo is only updated on
+`quelpa-upgrade' or `quelpa-self-upgrade'."
+  :group 'quelpa
+  :type 'boolean)
+
+(defcustom quelpa-melpa-repo-url "https://github.com/melpa/melpa.git"
+  "The melpa git repository url."
+  :group 'quelpa
+  :type 'string)
+
+(defcustom quelpa-self-upgrade-p t
+  "If non-nil upgrade quelpa itself when doing a
+  `quelpa-upgrade', otherwise only upgrade the packages in the
+  quelpa cache."
+  :group 'quelpa
+  :type 'boolean)
+
+(defvar quelpa-initialized-p nil
+  "Non-nil when quelpa has been initialized.")
+
+(defvar quelpa-cache nil
+  "The `quelpa' command stores processed pkgs/recipes in the cache.")
+
+(defvar quelpa-recipe '(quelpa :url "https://framagit.org/steckerhalter/quelpa.git" :fetcher git)
+  "The recipe for quelpa.")
+
+;; --- compatibility for legacy `package.el' in Emacs 24.3  -------------------
+
+(defun quelpa-setup-package-structs ()
+  "Setup the struct `package-desc' when not available.
+`package-desc-from-legacy' is provided to convert the legacy
+vector desc into a valid PACKAGE-DESC."
+  (unless (functionp 'package-desc-p)
+    (cl-defstruct
+        (package-desc
+         (:constructor
+          ;; convert legacy package desc into PACKAGE-DESC
+          package-desc-from-legacy
+          (pkg-info kind
+                    &aux
+                    (name (intern (aref pkg-info 0)))
+                    (version (version-to-list (aref pkg-info 3)))
+                    (summary (if (string= (aref pkg-info 2) "")
+                                 "No description available."
+                               (aref pkg-info 2)))
+                    (reqs  (aref pkg-info 1))
+                    (kind kind))))
+      name
+      version
+      (summary "No description available.")
+      reqs
+      kind
+      archive
+      dir
+      extras
+      signed)))
+
+;; --- package building ------------------------------------------------------
+
+(defun quelpa-package-type (file)
+  "Determine the package type of FILE.
+Return `tar' for tarball packages, `single' for single file
+packages, or nil, if FILE is not a package."
+  (let ((ext (file-name-extension file)))
+    (cond
+     ((string= ext "tar") 'tar)
+     ((string= ext "el") 'single)
+     (:else nil))))
+
+(defun quelpa-get-package-desc (file)
+  "Extract and return the PACKAGE-DESC struct from FILE.
+On error return nil."
+  (let* ((kind (quelpa-package-type file))
+         (desc (with-demoted-errors "Error getting PACKAGE-DESC: %s"
+                 (with-temp-buffer
+                   (pcase kind
+                     (`single (insert-file-contents file)
+                              (package-buffer-info))
+                     (`tar (insert-file-contents-literally file)
+                           (tar-mode)
+                           (if (help-function-arglist 'package-tar-file-info)
+                               ;; legacy `package-tar-file-info' requires an arg
+                               (package-tar-file-info file)
+                             (with-no-warnings (package-tar-file-info)))))))))
+    (pcase desc
+      ((pred package-desc-p) desc)
+      ((pred vectorp) (package-desc-from-legacy desc kind)))))
+
+(defun quelpa-archive-file-name (archive-entry)
+  "Return the path of the file in which the package for ARCHIVE-ENTRY is stored."
+  (let* ((name (car archive-entry))
+         (pkg-info (cdr archive-entry))
+         (version (package-version-join (aref pkg-info 0)))
+         (flavour (aref pkg-info 3)))
+    (expand-file-name
+     (format "%s-%s.%s" name version (if (eq flavour 'single) "el" "tar"))
+     quelpa-packages-dir)))
+
+(defun quelpa-version>-p (name version)
+  "Return non-nil if VERSION of pkg with NAME is newer than what is currently installed."
+  (not (or (not version)
+           (let ((pkg-desc (cdr (assq name package-alist))))
+             (and pkg-desc
+                  (version-list-<=
+                   (version-to-list version)
+                   (if (functionp 'package-desc-vers)
+                       (package-desc-vers pkg-desc) ;old implementation
+                     (package-desc-version (car pkg-desc))))))
+           ;; Also check built-in packages.
+           (package-built-in-p name (version-to-list version)))))
+
+(defun quelpa-checkout (rcp dir)
+  "Return the version of the new package given a RCP.
+Return nil if the package is already installed and should not be upgraded."
+  (pcase-let ((`(,name . ,config) rcp)
+              (quelpa-build-stable quelpa-stable-p))
+    (unless (or (and (assq name package-alist) (not quelpa-upgrade-p))
+                (and (not config)
+                     (quelpa-message t "no recipe found for package `%s'" name)))
+      (let ((version (condition-case err
+                         (quelpa-build-checkout name config dir)
+                       (error "Failed to checkout `%s': `%s'"
+                              name (error-message-string err)))))
+        (when (quelpa-version>-p name version)
+          version)))))
+
+(defun quelpa-build (rcp)
+  "Build a package from the given recipe RCP.
+Uses the `package-build' library to get the source code and build
+an elpa compatible package in `quelpa-build-dir' storing it in
+`quelpa-packages-dir'. Return the path to the created file or nil
+if no action is necessary (like when the package is installed
+already and should not be upgraded etc)."
+  (let* ((name (car rcp))
+         (build-dir (expand-file-name (symbol-name name) quelpa-build-dir))
+         (version (quelpa-checkout rcp build-dir)))
+    (when version
+      (quelpa-archive-file-name
+       (quelpa-build-package (symbol-name name)
+                             version
+                             (quelpa-build--config-file-list (cdr rcp))
+                             build-dir
+                             quelpa-packages-dir)))))
+
+;; --- package-build.el integration ------------------------------------------
+
+(defun quelpa-file-version (file-path type version time-stamp)
+  "Return version of file at FILE-PATH."
+  (if (eq type 'directory)
+      time-stamp
+    (cl-letf* ((package-strip-rcs-id-orig (symbol-function 'package-strip-rcs-id))
+               ((symbol-function 'package-strip-rcs-id)
+                (lambda (str)
+                  (or (funcall package-strip-rcs-id-orig (lm-header "package-version"))
+                      (funcall package-strip-rcs-id-orig (lm-header "version"))
+                      "0"))))
+      (concat (mapconcat
+               #'number-to-string
+               (package-desc-version (quelpa-get-package-desc file-path)) ".")
+              (pcase version
+                (`original "")
+                (_ (concat "pre0." time-stamp)))))))
+
+(defun quelpa-directory-files (path)
+  "Return list of directory files from PATH recursively."
+  (let ((result '()))
+    (mapc
+     (lambda (file)
+       (if (file-directory-p file)
+           (progn
+             ;; When directory is not empty.
+             (when (cddr (directory-files file))
+               (dolist (subfile (quelpa-directory-files file))
+                 (add-to-list 'result subfile))))
+         (add-to-list 'result file)))
+     (mapcar
+      (lambda (file) (expand-file-name file path))
+      ;; Without first two entries because they are always "." and "..".
+      (cddr (directory-files path))))
+    result))
+
+(defun quelpa-expand-source-file-list (file-path config)
+  "Return list of source files from FILE-PATH corresponding to
+CONFIG."
+  (let ((source-files
+         (mapcar
+          (lambda (file) (expand-file-name file file-path))
+          (quelpa-build--expand-source-file-list file-path config))))
+    ;; Replace any directories in the source file list with the filenames of the
+    ;; files they contain (so that these files can subsequently be hashed).
+    (dolist (file source-files source-files)
+      (when (file-directory-p file)
+        (setq source-files (remove file source-files))
+        (setq source-files (append source-files
+                                   (quelpa-directory-files file)))))))
+
+(defun quelpa-slurp-file (file)
+  "Return the contents of FILE as a string, or nil if no such
+file exists."
+  (when (file-exists-p file)
+    (with-temp-buffer
+      (set-buffer-multibyte nil)
+      (setq-local buffer-file-coding-system 'binary)
+      (insert-file-contents-literally file)
+      (buffer-substring-no-properties (point-min) (point-max)))))
+
+(defun quelpa-check-hash (name config file-path dir &optional fetcher)
+  "Check if hash of FILE-PATH is different as in STAMP-FILE.
+If it is different save the new hash and timestamp to STAMP-FILE
+and return TIME-STAMP, otherwise return OLD-TIME-STAMP."
+  (unless (file-directory-p dir)
+    (make-directory dir))
+  (let* (files
+         hashes
+         new-stamp-info
+         new-content-hash
+         (time-stamp
+          (replace-regexp-in-string "\\.0+" "." (format-time-string "%Y%m%d.%H%M%S")))
+         (stamp-file (concat (expand-file-name (symbol-name name) dir) ".stamp"))
+         (old-stamp-info (quelpa-build--read-from-file stamp-file))
+         (old-content-hash (cdr old-stamp-info))
+         (old-time-stamp (car old-stamp-info))
+         (type (if (file-directory-p file-path) 'directory 'file))
+         (version (plist-get config :version)))
+
+    (if (not (file-exists-p file-path))
+        (error "`%s' does not exist" file-path)
+      (if (eq type 'directory)
+          (setq files (quelpa-expand-source-file-list file-path config)
+                hashes (mapcar
+                        (lambda (file)
+                          (secure-hash
+                           'sha1 (concat file (quelpa-slurp-file file)))) files)
+                new-content-hash (secure-hash 'sha1 (mapconcat 'identity hashes "")))
+        (setq new-content-hash (secure-hash 'sha1 (quelpa-slurp-file file-path)))))
+
+    (setq new-stamp-info (cons time-stamp new-content-hash))
+    (if (and old-content-hash
+             (string= new-content-hash old-content-hash))
+        (quelpa-file-version file-path type version old-time-stamp)
+      (unless (eq fetcher 'url)
+        (delete-directory dir t)
+        (make-directory dir)
+        (if (eq type 'file)
+            (copy-file file-path dir t t t t)
+          (copy-directory file-path dir t t t)))
+      (quelpa-build--dump new-stamp-info stamp-file)
+      (quelpa-file-version file-path type version time-stamp))))
+
+;; --- package-build fork ------------------------------------------
+
+(defcustom quelpa-build-verbose t
+  "When non-nil, then print additional progress information."
+  :type 'boolean)
+
+(defcustom quelpa-build-stable nil
+  "When non-nil, then try to build packages from versions-tagged code."
+  :type 'boolean)
+
+(defcustom quelpa-build-timeout-executable
+  (let ((prog (or (executable-find "timeout")
+                  (executable-find "gtimeout"))))
+    (when (and prog
+               (string-match-p "^ *-k"
+                               (shell-command-to-string (concat prog " --help"))))
+      prog))
+  "Path to a GNU coreutils \"timeout\" command if available.
+This must be a version which supports the \"-k\" option."
+  :type '(file :must-match t))
+
+(defcustom quelpa-build-timeout-secs 600
+  "Wait this many seconds for external processes to complete.
+
+If an external process takes longer than specified here to
+complete, then it is terminated.  This only has an effect
+if `quelpa-build-timeout-executable' is non-nil."
+  :type 'number)
+
+(defcustom quelpa-build-tar-executable
+  (or (executable-find "gtar")
+      (executable-find "tar"))
+  "Path to a (preferably GNU) tar command.
+Certain package names (e.g. \"@\") may not work properly with a BSD tar."
+  :type '(file :must-match t))
+
+(defcustom quelpa-build-version-regexp "^[rRvV]?\\(.*\\)$"
+  "Default pattern for matching valid version-strings within repository tags.
+The string in the capture group should be parsed as valid by `version-to-list'."
+  :type 'string)
+
+;;; Internal Variables
+
+(defconst quelpa-build-default-files-spec
+  '("*.el" "*.el.in" "dir"
+    "*.info" "*.texi" "*.texinfo"
+    "doc/dir" "doc/*.info" "doc/*.texi" "doc/*.texinfo"
+    (:exclude ".dir-locals.el" "test.el" "tests.el" "*-test.el" "*-tests.el"))
+  "Default value for :files attribute in recipes.")
+
+;;; Utilities
+
+(defun quelpa-build--message (format-string &rest args)
+  "Behave like `message' if `quelpa-build-verbose' is non-nil.
+Otherwise do nothing."
+  (when quelpa-build-verbose
+    (apply 'message format-string args)))
+
+(defun quelpa-build--slurp-file (file)
+  "Return the contents of FILE as a string, or nil if no such file exists."
+  (when (file-exists-p file)
+    (with-temp-buffer
+      (insert-file-contents file)
+      (buffer-substring-no-properties (point-min) (point-max)))))
+
+(defun quelpa-build--string-rtrim (str)
+  "Remove trailing whitespace from `STR'."
+  (replace-regexp-in-string "[ \t\n\r]+$" "" str))
+
+(defun quelpa-build--trim (str &optional chr)
+  "Return a copy of STR without any trailing CHR (or space if unspecified)."
+  (if (equal (elt str (1- (length str))) (or chr ? ))
+      (substring str 0 (1- (length str)))
+    str))
+
+;;; Version Handling
+
+(defun quelpa-build--valid-version (str &optional regexp)
+  "Apply to STR the REGEXP if defined, \
+then pass the string to `version-to-list' and return the result, \
+or nil if the version cannot be parsed."
+  (when (and regexp (string-match regexp str))
+    (setq str (match-string 1 str)))
+  (ignore-errors (version-to-list str)))
+
+(defun quelpa-build--parse-time (str)
+  "Parse STR as a time, and format as a YYYYMMDD.HHMM string."
+  ;; We remove zero-padding the HH portion, as it is lost
+  ;; when stored in the archive-contents
+  (setq str (substring-no-properties str))
+  (let ((time (date-to-time
+               (if (string-match "\
+^\\([0-9]\\{4\\}\\)/\\([0-9]\\{2\\}\\)/\\([0-9]\\{2\\}\\) \
+\\([0-9]\\{2\\}:[0-9]\\{2\\}:[0-9]\\{2\\}\\)$" str)
+                   (concat (match-string 1 str) "-" (match-string 2 str) "-"
+                           (match-string 3 str) " " (match-string 4 str))
+                 str))))
+    (concat (format-time-string "%Y%m%d." time)
+            (format "%d" (string-to-number (format-time-string "%H%M" time))))))
+
+(defun quelpa-build--find-parse-time (regexp &optional bound)
+  "Find REGEXP in current buffer and format as a time-based version string.
+An optional second argument bounds the search; it is a buffer
+position.  The match found must not end after that position."
+  (and (re-search-backward regexp bound t)
+       (quelpa-build--parse-time (match-string-no-properties 1))))
+
+(defun quelpa-build--find-parse-time-newest (regexp &optional bound)
+  "Find REGEXP in current buffer and format as a time-based version string.
+An optional second argument bounds the search; it is a buffer
+position.  The match found must not end after that position."
+  (save-match-data
+    (let (cur matches)
+      (while (setq cur (quelpa-build--find-parse-time regexp bound))
+        (push cur matches))
+      (car (nreverse (sort matches 'string<))))))
+
+(defun quelpa-build--find-version-newest (regexp &optional bound)
+  "Find the newest version matching REGEXP before point.
+An optional second argument bounds the search; it is a buffer
+position.  The match found must not before after that position."
+  (let ((tags (split-string
+               (buffer-substring-no-properties
+                (or bound (point-min)) (point))
+               "\n")))
+    (setq tags (append
+                (mapcar
+                 ;; Because the default `version-separator' is ".",
+                 ;; version-strings like "1_4_5" will be parsed
+                 ;; wrongly as (1 -4 4 -4 5), so we set
+                 ;; `version-separator' to "_" below and run again.
+                 (lambda (tag)
+                   (when (quelpa-build--valid-version tag regexp)
+                     (list (quelpa-build--valid-version tag regexp) tag)))
+                 tags)
+                (mapcar
+                 ;; Check for valid versions again, this time using
+                 ;; "_" as a separator instead of "." to catch
+                 ;; version-strings like "1_4_5".  Since "_" is
+                 ;; otherwise treated as a snapshot separator by
+                 ;; `version-regexp-alist', we don't have to worry
+                 ;; about the incorrect version list above—(1 -4 4 -4
+                 ;; 5)—since it will always be treated as older by
+                 ;; `version-list-<'.
+                 (lambda (tag)
+                   (let ((version-separator "_"))
+                     (when (quelpa-build--valid-version tag regexp)
+                       (list (quelpa-build--valid-version tag regexp) tag))))
+                 tags)))
+    (setq tags (cl-remove-if nil tags))
+    ;; Returns a list like ((0 1) ("v0.1")); the first element is used
+    ;; for comparison and for `package-version-join', and the second
+    ;; (the original tag) is used by git/hg/etc.
+    (car (nreverse (sort tags (lambda (v1 v2) (version-list-< (car v1) (car v2))))))))
+
+;;; Run Process
+
+(defun quelpa-build--run-process (dir command &rest args)
+  "In DIR (or `default-directory' if unset) run COMMAND with ARGS.
+Output is written to the current buffer."
+  (let ((default-directory (file-name-as-directory (or dir default-directory)))
+        (argv (nconc (unless (eq system-type 'windows-nt)
+                       (list "env" "LC_ALL=C"))
+                     (if quelpa-build-timeout-executable
+                         (nconc (list quelpa-build-timeout-executable
+                                      "-k" "60" (number-to-string
+                                                 quelpa-build-timeout-secs)
+                                      command)
+                                args)
+                       (cons command args)))))
+    (unless (file-directory-p default-directory)
+      (error "Can't run process in non-existent directory: %s" default-directory))
+    (let ((exit-code (apply 'process-file
+                            (car argv) nil (current-buffer) t
+                            (cdr argv))))
+      (or (zerop exit-code)
+          (error "Command '%s' exited with non-zero status %d: %s"
+                 argv exit-code (buffer-string))))))
+
+(defun quelpa-build--run-process-match (regexp dir prog &rest args)
+  "Run PROG with args and return the first match for REGEXP in its output.
+PROG is run in DIR, or if that is nil in `default-directory'."
+  (with-temp-buffer
+    (apply 'quelpa-build--run-process dir prog args)
+    (goto-char (point-min))
+    (re-search-forward regexp)
+    (match-string-no-properties 1)))
+
+;;; Checkout
+;;;; Common
+
+(defun quelpa-build-checkout (package-name config working-dir)
+  "Check out source for PACKAGE-NAME with CONFIG under WORKING-DIR.
+In turn, this function uses the :fetcher option in the CONFIG to
+choose a source-specific fetcher function, which it calls with
+the same arguments.
+
+Returns the package version as a string."
+  (let ((fetcher (plist-get config :fetcher)))
+    (quelpa-build--message "Fetcher: %s" fetcher)
+    (unless (eq fetcher 'wiki)
+      (quelpa-build--message "Source: %s\n"
+                             (or (plist-get config :repo)
+                                 (plist-get config :url))))
+    (funcall (intern (format "quelpa-build--checkout-%s" fetcher))
+             package-name config (file-name-as-directory working-dir))))
+
+(defun quelpa-build--princ-exists (dir)
+  "Print a message that the contents of DIR will be updated."
+  (quelpa-build--message "Updating %s" dir))
+
+(defun quelpa-build--princ-checkout (repo dir)
+  "Print a message that REPO will be checked out into DIR."
+  (quelpa-build--message "Cloning %s to %s" repo dir))
+
+;;;; Wiki
+
+(defvar quelpa-build--last-wiki-fetch-time 0
+  "The time at which an emacswiki URL was last requested.
+This is used to avoid exceeding the rate limit of 1 request per 2
+seconds; the server cuts off after 10 requests in 20 seconds.")
+
+(defvar quelpa-build--wiki-min-request-interval 3
+  "The shortest permissible interval between successive requests for Emacswiki URLs.")
+
+(defmacro quelpa-build--with-wiki-rate-limit (&rest body)
+  "Rate-limit BODY code passed to this macro to match EmacsWiki's rate limiting."
+  (let ((elapsed (cl-gensym)))
+    `(let ((,elapsed (- (float-time) quelpa-build--last-wiki-fetch-time)))
+       (when (< ,elapsed quelpa-build--wiki-min-request-interval)
+         (let ((wait (- quelpa-build--wiki-min-request-interval ,elapsed)))
+           (quelpa-build--message
+            "Waiting %.2f secs before hitting Emacswiki again" wait)
+           (sleep-for wait)))
+       (unwind-protect
+           (progn ,@body)
+         (setq quelpa-build--last-wiki-fetch-time (float-time))))))
+
+(require 'mm-decode)
+(defvar url-http-response-status)
+(defvar url-http-end-of-headers)
+
+(defun quelpa-build--url-copy-file (url newname &optional ok-if-already-exists)
+  "Copy URL to NEWNAME.  Both args must be strings.
+Returns the http request's header as a string.
+Like `url-copy-file', but it produces an error if the http response is not 200.
+Signals a `file-already-exists' error if file NEWNAME already exists,
+unless a third argument OK-IF-ALREADY-EXISTS is supplied and non-nil.
+A number as third arg means request confirmation if NEWNAME already exists."
+  (if (and (file-exists-p newname)
+           (not ok-if-already-exists))
+      (error "Opening output file: File already exists, %s" newname))
+  (let ((buffer (url-retrieve-synchronously url))
+        (headers nil)
+        (handle nil))
+    (if (not buffer)
+        (error "Opening input file: No such file or directory, %s" url))
+    (with-current-buffer buffer
+      (unless (= 200 url-http-response-status)
+        (error "HTTP error %s fetching %s" url-http-response-status url))
+      (setq handle (mm-dissect-buffer t))
+      (mail-narrow-to-head)
+      (setq headers (buffer-string)))
+    (mm-save-part-to-file handle newname)
+    (kill-buffer buffer)
+    (mm-destroy-parts handle)
+    headers))
+
+(defun quelpa-build--grab-wiki-file (filename)
+  "Download FILENAME from emacswiki, returning its last-modified time."
+  (let ((download-url
+         (format "https://www.emacswiki.org/emacs/download/%s" filename))
+        headers)
+    (quelpa-build--with-wiki-rate-limit
+     (setq headers (quelpa-build--url-copy-file download-url filename t)))
+    (when (zerop (nth 7 (file-attributes filename)))
+      (error "Wiki file %s was empty - has it been removed?" filename))
+    (quelpa-build--parse-time
+     (with-temp-buffer
+       (insert headers)
+       (mail-fetch-field "last-modified")))))
+
+(defun quelpa-build--checkout-wiki (name config dir)
+  "Checkout package NAME with config CONFIG from the EmacsWiki into DIR."
+  (unless quelpa-build-stable
+    (with-current-buffer (get-buffer-create "*quelpa-build-checkout*")
+      (unless (file-exists-p dir)
+        (make-directory dir))
+      (let ((files (or (plist-get config :files)
+                       (list (format "%s.el" name))))
+            (default-directory dir))
+        (car (nreverse (sort (mapcar 'quelpa-build--grab-wiki-file files)
+                             'string-lessp)))))))
+
+;;;; Darcs
+
+(defun quelpa-build--darcs-repo (dir)
+  "Get the current darcs repo for DIR."
+  (quelpa-build--run-process-match "Default Remote: \\(.*\\)"
+                                   dir "darcs" "show" "repo"))
+
+(defun quelpa-build--checkout-darcs (name config dir)
+  "Check package NAME with config CONFIG out of darcs into DIR."
+  (let ((repo (plist-get config :url)))
+    (with-current-buffer (get-buffer-create "*quelpa-build-checkout*")
+      (cond
+       ((and (file-exists-p (expand-file-name "_darcs" dir))
+             (string-equal (quelpa-build--darcs-repo dir) repo))
+        (quelpa-build--princ-exists dir)
+        (quelpa-build--run-process dir "darcs" "pull" "--all"))
+       (t
+        (when (file-exists-p dir)
+          (delete-directory dir t))
+        (quelpa-build--princ-checkout repo dir)
+        (quelpa-build--run-process nil "darcs" "get" repo dir)))
+      (if quelpa-build-stable
+          (let* ((min-bound (goto-char (point-max)))
+                 (tag-version
+                  (and (quelpa-build--run-process dir "darcs" "show" "tags")
+                       (or (quelpa-build--find-version-newest
+                            (or (plist-get config :version-regexp)
+                                quelpa-build-version-regexp)
+                            min-bound)
+                           (error "No valid stable versions found for %s" name)))))
+            (quelpa-build--run-process dir "darcs" "obliterate"
+                                       "--all" "--from-tag"
+                                       (cadr tag-version))
+            ;; Return the parsed version as a string
+            (package-version-join (car tag-version)))
+        (apply 'quelpa-build--run-process
+               dir "darcs" "changes" "--max-count" "1"
+               (quelpa-build--expand-source-file-list dir config))
+        (quelpa-build--find-parse-time "\
+\\([a-zA-Z]\\{3\\} [a-zA-Z]\\{3\\} \
+\\( \\|[0-9]\\)[0-9] [0-9]\\{2\\}:[0-9]\\{2\\}:[0-9]\\{2\\} \
+[A-Za-z]\\{3\\} [0-9]\\{4\\}\\)")))))
+
+;;;; Fossil
+
+(defun quelpa-build--fossil-repo (dir)
+  "Get the current fossil repo for DIR."
+  (quelpa-build--run-process-match "\\(.*\\)" dir "fossil" "remote-url"))
+
+(defun quelpa-build--checkout-fossil (name config dir)
+  "Check package NAME with config CONFIG out of fossil into DIR."
+  (unless quelpa-build-stable
+    (let ((repo (plist-get config :url)))
+      (with-current-buffer (get-buffer-create "*quelpa-build-checkout*")
+        (cond
+         ((and (or (file-exists-p (expand-file-name ".fslckout" dir))
+                   (file-exists-p (expand-file-name "_FOSSIL_" dir)))
+               (string-equal (quelpa-build--fossil-repo dir) repo))
+          (quelpa-build--princ-exists dir)
+          (quelpa-build--run-process dir "fossil" "update"))
+         (t
+          (when (file-exists-p dir)
+            (delete-directory dir t))
+          (quelpa-build--princ-checkout repo dir)
+          (make-directory dir)
+          (quelpa-build--run-process dir "fossil" "clone" repo "repo.fossil")
+          (quelpa-build--run-process dir "fossil" "open" "repo.fossil")))
+        (quelpa-build--run-process dir "fossil" "timeline" "-n" "1" "-t" "ci")
+        (or (quelpa-build--find-parse-time "\
+=== \\([0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\} ===\n\
+[0-9]\\{2\\}:[0-9]\\{2\\}:[0-9]\\{2\\}\\) ")
+            (error "No valid timestamps found!"))))))
+
+;;;; Svn
+
+(defun quelpa-build--svn-repo (dir)
+  "Get the current svn repo for DIR."
+  (quelpa-build--run-process-match "URL: \\(.*\\)" dir "svn" "info"))
+
+(defun quelpa-build--checkout-svn (name config dir)
+  "Check package NAME with config CONFIG out of svn into DIR."
+  (unless quelpa-build-stable
+    (with-current-buffer (get-buffer-create "*quelpa-build-checkout*")
+      (let ((repo (quelpa-build--trim (plist-get config :url) ?/))
+            (bound (goto-char (point-max))))
+        (cond
+         ((and (file-exists-p (expand-file-name ".svn" dir))
+               (string-equal (quelpa-build--svn-repo dir) repo))
+          (quelpa-build--princ-exists dir)
+          (quelpa-build--run-process dir "svn" "up"))
+         (t
+          (when (file-exists-p dir)
+            (delete-directory dir t))
+          (quelpa-build--princ-checkout repo dir)
+          (quelpa-build--run-process nil "svn" "checkout" repo dir)))
+        (apply 'quelpa-build--run-process dir "svn" "info"
+               (quelpa-build--expand-source-file-list dir config))
+        (or (quelpa-build--find-parse-time-newest "\
+Last Changed Date: \\([0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\} \
+[0-9]\\{2\\}:[0-9]\\{2\\}:[0-9]\\{2\\}\\( [+-][0-9]\\{4\\}\\)?\\)"
+                                                  bound)
+            (error "No valid timestamps found!"))))))
+
+;;;; Cvs
+
+(defun quelpa-build--cvs-repo (dir)
+  "Get the current CVS root and repository for DIR.
+
+Return a cons cell whose `car' is the root and whose `cdr' is the repository."
+  (apply 'cons
+         (mapcar (lambda (file)
+                   (quelpa-build--string-rtrim
+                    (quelpa-build--slurp-file (expand-file-name file dir))))
+                 '("CVS/Root" "CVS/Repository"))))
+
+(defun quelpa-build--checkout-cvs (name config dir)
+  "Check package NAME with config CONFIG out of cvs into DIR."
+  (unless quelpa-build-stable
+    (with-current-buffer (get-buffer-create "*quelpa-build-checkout*")
+      (let ((root (quelpa-build--trim (plist-get config :url) ?/))
+            (repo (or (plist-get config :module) (symbol-name name)))
+            (bound (goto-char (point-max)))
+            latest)
+        (cond
+         ((and (file-exists-p (expand-file-name "CVS" dir))
+               (equal (quelpa-build--cvs-repo dir) (cons root repo)))
+          (quelpa-build--princ-exists dir)
+          (quelpa-build--run-process dir "cvs" "update" "-dP"))
+         (t
+          (when (file-exists-p dir)
+            (delete-directory dir t))
+          (quelpa-build--princ-checkout (format "%s from %s" repo root) dir)
+          ;; CVS insists on relative paths as target directory for checkout (for
+          ;; whatever reason), and puts "CVS" directories into every subdirectory
+          ;; of the current working directory given in the target path. To get CVS
+          ;; to just write to DIR, we need to execute CVS from the parent
+          ;; directory of DIR, and specific DIR as relative path.  Hence all the
+          ;; following mucking around with paths.  CVS is really horrid.
+          (let ((dir (directory-file-name dir)))
+            (quelpa-build--run-process (file-name-directory dir)
+                                       "env" "TZ=UTC" "cvs" "-z3"
+                                       "-d" root "checkout"
+                                       "-d" (file-name-nondirectory dir)
+                                       repo))))
+        (apply 'quelpa-build--run-process dir "cvs" "log"
+               (quelpa-build--expand-source-file-list dir config))
+
+        ;; `cvs log` does not provide a way to view the previous N
+        ;; revisions, so instead of parsing the entire log we examine
+        ;; the Entries file, which looks like this:
+        ;;
+        ;; /.cvsignore/1.2/Thu Sep  1 12:42:02 2005//
+        ;; /CHANGES/1.1/Tue Oct  4 11:47:54 2005//
+        ;; /GNUmakefile/1.8/Tue Oct  4 11:47:54 2005//
+        ;; /Makefile/1.14/Tue Oct  4 11:47:54 2005//
+        ;;
+        (insert-file-contents (concat dir "/CVS/Entries"))
+        (setq latest
+              (car
+               (sort
+                (split-string (buffer-substring-no-properties (point) (point-max)) "\n")
+                (lambda (x y)
+                  (when (string-match "^\\/[^\\/]*\\/[^\\/]*\\/\\([^\\/]*\\)\\/\\/$" x)
+                    (setq x (quelpa-build--parse-time (match-string 1 x))))
+                  (when (string-match "^\\/[^\\/]*\\/[^\\/]*\\/\\([^\\/]*\\)\\/\\/$" y)
+                    (setq y (quelpa-build--parse-time (match-string 1 y))))
+                  (version-list-<= (quelpa-build--valid-version y)
+                                   (quelpa-build--valid-version x))))))
+        (when (string-match "^\\/[^\\/]*\\/[^\\/]*\\/\\([^\\/]*\\)\\/\\/$" latest)
+          (setq latest (match-string 1 latest)))
+        (or (quelpa-build--parse-time latest)
+            (error "No valid timestamps found!"))))))
+
+;;;; Git
+
+(defun quelpa-build--git-repo (dir)
+  "Get the current git repo for DIR."
+  (quelpa-build--run-process-match
+   "Fetch URL: \\(.*\\)" dir "git" "remote" "show" "-n" "origin"))
+
+(defun quelpa-build--checkout-git (name config dir)
+  "Check package NAME with config CONFIG out of git into DIR."
+  (let ((repo (plist-get config :url))
+        (commit (or (plist-get config :commit)
+                    (let ((branch (plist-get config :branch)))
+                      (when branch
+                        (concat "origin/" branch))))))
+    (with-current-buffer (get-buffer-create "*quelpa-build-checkout*")
+      (goto-char (point-max))
+      (cond
+       ((and (file-exists-p (expand-file-name ".git" dir))
+             (string-equal (quelpa-build--git-repo dir) repo))
+        (quelpa-build--princ-exists dir)
+        (quelpa-build--run-process dir "git" "fetch" "--all" "--tags"))
+       (t
+        (when (file-exists-p dir)
+          (delete-directory dir t))
+        (quelpa-build--princ-checkout repo dir)
+        (quelpa-build--run-process nil "git" "clone" repo dir)))
+      (if quelpa-build-stable
+          (let* ((min-bound (goto-char (point-max)))
+                 (tag-version
+                  (and (quelpa-build--run-process dir "git" "tag")
+                       (or (quelpa-build--find-version-newest
+                            (or (plist-get config :version-regexp)
+                                quelpa-build-version-regexp)
+                            min-bound)
+                           (error "No valid stable versions found for %s" name)))))
+            ;; Using reset --hard here to comply with what's used for
+            ;; unstable, but maybe this should be a checkout?
+            (quelpa-build--update-git-to-ref
+             dir (concat "tags/" (cadr tag-version)))
+            ;; Return the parsed version as a string
+            (package-version-join (car tag-version)))
+        (quelpa-build--update-git-to-ref
+         dir (or commit (concat "origin/" (quelpa-build--git-head-branch dir))))
+        (apply 'quelpa-build--run-process
+               dir "git" "log" "--first-parent" "-n1" "--pretty=format:'\%ci'"
+               (quelpa-build--expand-source-file-list dir config))
+        (quelpa-build--find-parse-time "\
+\\([0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\} \
+[0-9]\\{2\\}:[0-9]\\{2\\}:[0-9]\\{2\\}\\( [+-][0-9]\\{4\\}\\)?\\)")))))
+
+(defun quelpa-build--git-head-branch (dir)
+  "Get the current git repo for DIR."
+  (or (ignore-errors
+        (quelpa-build--run-process-match
+         "HEAD branch: \\(.*\\)" dir "git" "remote" "show" "origin"))
+      "master"))
+
+(defun quelpa-build--git-head-sha (dir)
+  "Get the current head SHA for DIR."
+  (ignore-errors
+    (quelpa-build--run-process-match
+     "\\(.*\\)" dir "git" "rev-parse" "HEAD")))
+
+(defun quelpa-build--update-git-to-ref (dir ref)
+  "Update the git repo in DIR so that HEAD is REF."
+  (quelpa-build--run-process dir "git" "reset" "--hard" ref)
+  (quelpa-build--run-process dir "git" "submodule" "sync" "--recursive")
+  (quelpa-build--run-process dir "git" "submodule" "update" "--init" "--recursive"))
+
+(defun quelpa-build--checkout-github (name config dir)
+  "Check package NAME with config CONFIG out of github into DIR."
+  (let ((url (format "https://github.com/%s.git" (plist-get config :repo))))
+    (quelpa-build--checkout-git name (plist-put (copy-sequence config) :url url) dir)))
+
+(defun quelpa-build--checkout-gitlab (name config dir)
+  "Check package NAME with config CONFIG out of gitlab into DIR."
+  (let ((url (format "https://gitlab.com/%s.git" (plist-get config :repo))))
+    (quelpa-build--checkout-git name (plist-put (copy-sequence config) :url url) dir)))
+
+;;;; Bzr
+
+(defun quelpa-build--bzr-repo (dir)
+  "Get the current bzr repo for DIR."
+  (quelpa-build--run-process-match "parent branch: \\(.*\\)" dir "bzr" "info"))
+
+(defun quelpa-build--checkout-bzr (name config dir)
+  "Check package NAME with config CONFIG out of bzr into DIR."
+  (let ((repo (quelpa-build--run-process-match
+               "\\(?:branch root\\|repository branch\\): \\(.*\\)"
+               nil "bzr" "info" (plist-get config :url))))
+    (with-current-buffer (get-buffer-create "*quelpa-build-checkout*")
+      (goto-char (point-max))
+      (cond
+       ((and (file-exists-p (expand-file-name ".bzr" dir))
+             (string-equal (quelpa-build--bzr-repo dir) repo))
+        (quelpa-build--princ-exists dir)
+        (quelpa-build--run-process dir "bzr" "merge" "--force"))
+       (t
+        (when (file-exists-p dir)
+          (delete-directory dir t))
+        (quelpa-build--princ-checkout repo dir)
+        (quelpa-build--run-process nil "bzr" "branch" repo dir)))
+      (if quelpa-build-stable
+          (let ((bound (goto-char (point-max)))
+                (regexp (or (plist-get config :version-regexp)
+                            quelpa-build-version-regexp))
+                tag-version)
+            (quelpa-build--run-process dir "bzr" "tags")
+            (goto-char bound)
+            (ignore-errors (while (re-search-forward "\\ +.*")
+                             (replace-match "")))
+            (setq tag-version
+                  (or (quelpa-build--find-version-newest regexp bound)
+                      (error "No valid stable versions found for %s" name)))
+            (quelpa-build--run-process dir
+                                       "bzr" "revert" "-r"
+                                       (concat "tag:" (cadr tag-version)))
+            ;; Return the parsed version as a string
+            (package-version-join (car tag-version)))
+        (apply 'quelpa-build--run-process dir "bzr" "log" "-l1"
+               (quelpa-build--expand-source-file-list dir config))
+        (quelpa-build--find-parse-time "\
+\\([0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\} \
+[0-9]\\{2\\}:[0-9]\\{2\\}:[0-9]\\{2\\}\\( [+-][0-9]\\{4\\}\\)?\\)")))))
+
+;;;; Hg
+
+(defun quelpa-build--hg-repo (dir)
+  "Get the current hg repo for DIR."
+  (quelpa-build--run-process-match "default = \\(.*\\)" dir "hg" "paths"))
+
+(defun quelpa-build--checkout-hg (name config dir)
+  "Check package NAME with config CONFIG out of hg into DIR."
+  (let ((repo (plist-get config :url)))
+    (with-current-buffer (get-buffer-create "*quelpa-build-checkout*")
+      (goto-char (point-max))
+      (cond
+       ((and (file-exists-p (expand-file-name ".hg" dir))
+             (string-equal (quelpa-build--hg-repo dir) repo))
+        (quelpa-build--princ-exists dir)
+        (quelpa-build--run-process dir "hg" "pull")
+        (quelpa-build--run-process dir "hg" "update"))
+       (t
+        (when (file-exists-p dir)
+          (delete-directory dir t))
+        (quelpa-build--princ-checkout repo dir)
+        (quelpa-build--run-process nil "hg" "clone" repo dir)))
+      (if quelpa-build-stable
+          (let ((min-bound (goto-char (point-max)))
+                (regexp (or (plist-get config :version-regexp)
+                            quelpa-build-version-regexp))
+                tag-version)
+            (quelpa-build--run-process dir "hg" "tags")
+            ;; The output of `hg tags` shows the ref of the tag as well
+            ;; as the tag itself, e.g.:
+            ;;
+            ;; tip                             1696:73ad80e8fea1
+            ;; 1.2.8                           1691:464af57fd2b7
+            ;;
+            ;; So here we remove that second column before passing the
+            ;; buffer contents to `quelpa-build--find-version-newest'.
+            ;; This isn't strictly necessary for Mercurial since the
+            ;; colon in "1691:464af57fd2b7" means that won't be parsed
+            ;; as a valid version-string, but it's an example of how to
+            ;; do it in case it's necessary elsewhere.
+            (goto-char min-bound)
+            (ignore-errors (while (re-search-forward "\\ +.*")
+                             (replace-match "")))
+            (setq tag-version
+                  (or (quelpa-build--find-version-newest regexp min-bound)
+                      (error "No valid stable versions found for %s" name)))
+            (quelpa-build--run-process dir "hg" "update" (cadr tag-version))
+            ;; Return the parsed version as a string
+            (package-version-join (car tag-version)))
+        (apply 'quelpa-build--run-process
+               dir "hg" "log" "--style" "compact" "-l1"
+               (quelpa-build--expand-source-file-list dir config))
+        (quelpa-build--find-parse-time "\
+\\([0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\} \
+[0-9]\\{2\\}:[0-9]\\{2\\}\\( [+-][0-9]\\{4\\}\\)?\\)")))))
+
+(defun quelpa-build--checkout-bitbucket (name config dir)
+  "Check package NAME with config CONFIG out of bitbucket into DIR."
+  (let ((url (format "https://bitbucket.com/%s" (plist-get config :repo))))
+    (quelpa-build--checkout-hg name (plist-put (copy-sequence config) :url url) dir)))
+
+;;; Utilities
+
+(defun quelpa-build--dump (data file &optional pretty-print)
+  "Write DATA to FILE as a Lisp sexp.
+Optionally PRETTY-PRINT the data."
+  (with-temp-file file
+    (quelpa-build--message "File: %s" file)
+    (if pretty-print
+        (pp data (current-buffer))
+      (print data (current-buffer)))))
+
+(defun quelpa-build--write-pkg-file (pkg-file pkg-info)
+  "Write PKG-FILE containing PKG-INFO."
+  (with-temp-file pkg-file
+    (pp
+     `(define-package
+        ,(aref pkg-info 0)
+        ,(aref pkg-info 3)
+        ,(aref pkg-info 2)
+        ',(mapcar
+           (lambda (elt)
+             (list (car elt)
+                   (package-version-join (cadr elt))))
+           (aref pkg-info 1))
+        ;; Append our extra information
+        ,@(cl-mapcan (lambda (entry)
+                       (let ((value (cdr entry)))
+                         (when (or (symbolp value) (listp value))
+                           ;; We must quote lists and symbols,
+                           ;; because Emacs 24.3 and earlier evaluate
+                           ;; the package information, which would
+                           ;; break for unquoted symbols or lists
+                           (setq value (list 'quote value)))
+                         (list (car entry) value)))
+                     (when (> (length pkg-info) 4)
+                       (aref pkg-info 4))))
+     (current-buffer))
+    (princ ";; Local Variables:\n;; no-byte-compile: t\n;; End:\n"
+           (current-buffer))))
+
+(defun quelpa-build--read-from-file (file)
+  "Read and return the Lisp data stored in FILE, or nil if no such file exists."
+  (when (file-exists-p file)
+    (car (read-from-string (quelpa-build--slurp-file file)))))
+
+(defun quelpa-build--create-tar (file dir &optional files)
+  "Create a tar FILE containing the contents of DIR, or just FILES if non-nil."
+  (when (eq system-type 'windows-nt)
+    (setq file (replace-regexp-in-string "^\\([a-z]\\):" "/\\1" file)))
+  (apply 'process-file
+         quelpa-build-tar-executable nil
+         (get-buffer-create "*quelpa-build-checkout*")
+         nil "-cvf"
+         file
+         "--exclude=.svn"
+         "--exclude=CVS"
+         "--exclude=.git"
+         "--exclude=_darcs"
+         "--exclude=.fslckout"
+         "--exclude=_FOSSIL_"
+         "--exclude=.bzr"
+         "--exclude=.hg"
+         (or (mapcar (lambda (fn) (concat dir "/" fn)) files) (list dir))))
+
+(defun quelpa-build--find-package-commentary (file-path)
+  "Get commentary section from FILE-PATH."
+  (when (file-exists-p file-path)
+    (with-temp-buffer
+      (insert-file-contents file-path)
+      (lm-commentary))))
+
+(defun quelpa-build--write-pkg-readme (target-dir commentary file-name)
+  "In TARGET-DIR, write COMMENTARY to a -readme.txt file prefixed with FILE-NAME."
+  (when commentary
+    (with-temp-buffer
+      (insert commentary)
+      ;; Adapted from `describe-package-1'.
+      (goto-char (point-min))
+      (save-excursion
+        (when (re-search-forward "^;;; Commentary:\n" nil t)
+          (replace-match ""))
+        (while (re-search-forward "^\\(;+ ?\\)" nil t)
+          (replace-match ""))
+        (goto-char (point-min))
+        (when (re-search-forward "\\`\\( *\n\\)+" nil t)
+          (replace-match "")))
+      (delete-trailing-whitespace)
+      (let ((coding-system-for-write buffer-file-coding-system))
+        (write-region nil nil
+                      (quelpa-build--readme-file-name target-dir file-name))))))
+
+(defun quelpa-build--readme-file-name (target-dir file-name)
+  "Name of the readme file in TARGET-DIR for the package FILE-NAME."
+  (expand-file-name (concat file-name "-readme.txt")
+                    target-dir))
+
+(defun quelpa-build--update-or-insert-version (version)
+  "Ensure current buffer has a \"Package-Version: VERSION\" header."
+  (goto-char (point-min))
+  (if (let ((case-fold-search t))
+        (re-search-forward "^;+* *Package-Version *: *" nil t))
+      (progn
+        (move-beginning-of-line nil)
+        (search-forward "V" nil t)
+        (backward-char)
+        (insert "X-Original-")
+        (move-beginning-of-line nil))
+    ;; Put the new header in a sensible place if we can
+    (re-search-forward "^;+* *\\(Version\\|Package-Requires\\|Keywords\\|URL\\) *:"
+                       nil t)
+    (forward-line))
+  (insert (format ";; Package-Version: %s" version))
+  (newline))
+
+(defun quelpa-build--ensure-ends-here-line (file-path)
+  "Add a 'FILE-PATH ends here' trailing line if missing."
+  (save-excursion
+    (goto-char (point-min))
+    (let ((trailer (concat ";;; "
+                           (file-name-nondirectory file-path)
+                           " ends here")))
+      (unless (search-forward trailer nil t)
+        (goto-char (point-max))
+        (newline)
+        (insert trailer)
+        (newline)))))
+
+(defun quelpa-build--get-package-info (file-path)
+  "Get a vector of package info from the docstrings in FILE-PATH."
+  (when (file-exists-p file-path)
+    (ignore-errors
+      (with-temp-buffer
+        (insert-file-contents file-path)
+        ;; next few lines are a hack for some packages that aren't
+        ;; commented properly.
+        (quelpa-build--update-or-insert-version "0")
+        (quelpa-build--ensure-ends-here-line file-path)
+        (cl-flet ((package-strip-rcs-id (str) "0"))
+          (quelpa-build--package-buffer-info-vec))))))
+
+(defun quelpa-build--get-pkg-file-info (file-path)
+  "Get a vector of package info from \"-pkg.el\" file FILE-PATH."
+  (when (file-exists-p file-path)
+    (let ((package-def (quelpa-build--read-from-file file-path)))
+      (if (eq 'define-package (car package-def))
+          (let* ((pkgfile-info (cdr package-def))
+                 (descr (nth 2 pkgfile-info))
+                 (rest-plist (cl-subseq pkgfile-info (min 4 (length pkgfile-info))))
+                 (extras (let (alist)
+                           (while rest-plist
+                             (unless (memq (car rest-plist) '(:kind :archive))
+                               (let ((value (cadr rest-plist)))
+                                 (when value
+                                   (push (cons (car rest-plist)
+                                               (if (eq (car-safe value) 'quote)
+                                                   (cadr value)
+                                                 value))
+                                         alist))))
+                             (setq rest-plist (cddr rest-plist)))
+                           alist)))
+            (when (string-match "[\r\n]" descr)
+              (error "Illegal multi-line package description in %s" file-path))
+            (vector
+             (nth 0 pkgfile-info)
+             (mapcar
+              (lambda (elt)
+                (unless (symbolp (car elt))
+                  (error "Invalid package name in dependency: %S" (car elt)))
+                (list (car elt) (version-to-list (cadr elt))))
+              (eval (nth 3 pkgfile-info)))
+             descr
+             (nth 1 pkgfile-info)
+             extras))
+        (error "No define-package found in %s" file-path)))))
+
+(defun quelpa-build--merge-package-info (pkg-info name version)
+  "Return a version of PKG-INFO updated with NAME, VERSION and info from CONFIG.
+If PKG-INFO is nil, an empty one is created."
+  (let ((merged (or (copy-sequence pkg-info)
+                    (vector name nil "No description available." version))))
+    (aset merged 0 name)
+    (aset merged 3 version)
+    merged))
+
+(defun quelpa-build--archive-entry (pkg-info type)
+  "Return the archive-contents cons cell for PKG-INFO and TYPE."
+  (let ((name (intern (aref pkg-info 0)))
+        (requires (aref pkg-info 1))
+        (desc (or (aref pkg-info 2) "No description available."))
+        (version (aref pkg-info 3))
+        (extras (and (> (length pkg-info) 4)
+                     (aref pkg-info 4))))
+    (cons name
+          (vector (version-to-list version)
+                  requires
+                  desc
+                  type
+                  extras))))
+
+;;; Recipes
+
+(defun quelpa-build-expand-file-specs (dir specs &optional subdir allow-empty)
+  "In DIR, expand SPECS, optionally under SUBDIR.
+The result is a list of (SOURCE . DEST), where SOURCE is a source
+file path and DEST is the relative path to which it should be copied.
+
+If the resulting list is empty, an error will be reported.  Pass t
+for ALLOW-EMPTY to prevent this error."
+  (let ((default-directory dir)
+        (prefix (if subdir (format "%s/" subdir) ""))
+        (lst))
+    (dolist (entry specs lst)
+      (setq lst
+            (if (consp entry)
+                (if (eq :exclude (car entry))
+                    (cl-nset-difference lst
+                                        (quelpa-build-expand-file-specs
+                                         dir (cdr entry) nil t)
+                                        :key 'car
+                                        :test 'equal)
+                  (nconc lst
+                         (quelpa-build-expand-file-specs
+                          dir
+                          (cdr entry)
+                          (concat prefix (car entry))
+                          t)))
+              (nconc
+               lst (mapcar (lambda (f)
+                             (let ((destname)))
+                             (cons f
+                                   (concat prefix
+                                           (replace-regexp-in-string
+                                            "\\.in\\'"
+                                            ""
+                                            (file-name-nondirectory f)))))
+                           (file-expand-wildcards entry))))))
+    (when (and (null lst) (not allow-empty))
+      (error "No matching file(s) found in %s: %s" dir specs))
+    lst))
+
+(defun quelpa-build--config-file-list (config)
+  "Get the :files spec from CONFIG, or return `quelpa-build-default-files-spec'."
+  (let ((file-list (plist-get config :files)))
+    (cond
+     ((null file-list)
+      quelpa-build-default-files-spec)
+     ((eq :defaults (car file-list))
+      (append quelpa-build-default-files-spec (cdr file-list)))
+     (t
+      file-list))))
+
+(defun quelpa-build--expand-source-file-list (dir config)
+  "Shorthand way to expand paths in DIR for source files listed in CONFIG."
+  (mapcar 'car
+          (quelpa-build-expand-file-specs
+           dir (quelpa-build--config-file-list config))))
+
+(defun quelpa-build--generate-info-files (files source-dir target-dir)
+  "Create .info files from any .texi files listed in FILES.
+
+The source and destination file paths are expanded in SOURCE-DIR
+and TARGET-DIR respectively.
+
+Any of the original .texi(nfo) files found in TARGET-DIR are
+deleted."
+  (dolist (spec files)
+    (let* ((source-file (car spec))
+           (source-path (expand-file-name source-file source-dir))
+           (dest-file (cdr spec))
+           (info-path (expand-file-name
+                       (concat (file-name-sans-extension dest-file) ".info")
+                       target-dir)))
+      (when (string-match ".texi\\(nfo\\)?$" source-file)
+        (when (not (file-exists-p info-path))
+          (with-current-buffer (get-buffer-create "*quelpa-build-info*")
+            (ignore-errors
+              (quelpa-build--run-process
+               (file-name-directory source-path)
+               "makeinfo"
+               source-path
+               "-o"
+               info-path)
+              (quelpa-build--message "Created %s" info-path))))
+        (quelpa-build--message "Removing %s"
+                               (expand-file-name dest-file target-dir))
+        (delete-file (expand-file-name dest-file target-dir))))))
+
+;;; Info Manuals
+
+(defun quelpa-build--generate-dir-file (files target-dir)
+  "Create dir file from any .info files listed in FILES in TARGET-DIR."
+  (dolist (spec files)
+    (let* ((source-file (car spec))
+           (dest-file (cdr spec))
+           (info-path (expand-file-name
+                       (concat (file-name-sans-extension dest-file) ".info")
+                       target-dir)))
+      (when (and (or (string-match ".info$" source-file)
+                     (string-match ".texi\\(nfo\\)?$" source-file))
+                 (file-exists-p info-path))
+        (with-current-buffer (get-buffer-create "*quelpa-build-info*")
+          (ignore-errors
+            (quelpa-build--run-process
+             nil
+             "install-info"
+             (concat "--dir=" (expand-file-name "dir" target-dir))
+             info-path)))))))
+
+;;; Utilities
+
+(defun quelpa-build--copy-package-files (files source-dir target-dir)
+  "Copy FILES from SOURCE-DIR to TARGET-DIR.
+FILES is a list of (SOURCE . DEST) relative filepath pairs."
+  (cl-loop for (source-file . dest-file) in files
+           do (quelpa-build--copy-file
+               (expand-file-name source-file source-dir)
+               (expand-file-name dest-file target-dir))))
+
+(defun quelpa-build--copy-file (file newname)
+  "Copy FILE to NEWNAME and create parent directories for NEWNAME if they don't exist."
+  (let ((newdir (file-name-directory newname)))
+    (unless (file-exists-p newdir)
+      (make-directory newdir t)))
+  (cond
+   ((file-regular-p file)
+    (quelpa-build--message "%s -> %s" file newname)
+    (copy-file file newname))
+   ((file-directory-p file)
+    (quelpa-build--message "%s => %s" file newname)
+    (copy-directory file newname))))
+
+(defun quelpa-build--find-source-file (target files)
+  "Search for source of TARGET in FILES."
+  (car (rassoc target files)))
+
+(defun quelpa-build--package-buffer-info-vec ()
+  "Return a vector of package info.
+`package-buffer-info' returns a vector in older Emacs versions,
+and a cl struct in Emacs HEAD.  This wrapper normalises the results."
+  (let ((desc (package-buffer-info))
+        (keywords (lm-keywords-list)))
+    (if (fboundp 'package-desc-create)
+        (let ((extras (package-desc-extras desc)))
+          (when (and keywords (not (assq :keywords extras)))
+            ;; Add keywords to package properties, if not already present
+            (push (cons :keywords keywords) extras))
+          (vector (package-desc-name desc)
+                  (package-desc-reqs desc)
+                  (package-desc-summary desc)
+                  (package-desc-version desc)
+                  extras))
+      ;; The regexp and the processing is taken from `lm-homepage' in Emacs 24.4
+      (let* ((page (lm-header "\\(?:x-\\)?\\(?:homepage\\|url\\)"))
+             (homepage (if (and page (string-match "^<.+>$" page))
+                           (substring page 1 -1)
+                         page))
+             extras)
+        (when keywords (push (cons :keywords keywords) extras))
+        (when homepage (push (cons :url homepage) extras))
+        (vector  (aref desc 0)
+                 (aref desc 1)
+                 (aref desc 2)
+                 (aref desc 3)
+                 extras)))))
+
+;;; Building
+
+;;;###autoload
+(defun quelpa-build-package (package-name version file-specs source-dir target-dir)
+  "Create PACKAGE-NAME with VERSION.
+
+The information in FILE-SPECS is used to gather files from
+SOURCE-DIR.
+
+The resulting package will be stored as a .el or .tar file in
+TARGET-DIR, depending on whether there are multiple files.
+
+Argument FILE-SPECS is a list of specs for source files, which
+should be relative to SOURCE-DIR.  The specs can be wildcards,
+and optionally specify different target paths.  They extended
+syntax is currently only documented in the MELPA README.  You can
+simply pass `quelpa-build-default-files-spec' in most cases.
+
+Returns the archive entry for the package."
+  (when (symbolp package-name)
+    (setq package-name (symbol-name package-name)))
+  (let ((files (quelpa-build-expand-file-specs source-dir file-specs)))
+    (unless (equal file-specs quelpa-build-default-files-spec)
+      (when (equal files (quelpa-build-expand-file-specs
+                          source-dir quelpa-build-default-files-spec nil t))
+        (quelpa-build--message "Note: %s :files spec is equivalent to the default."
+                               package-name)))
+    (cond
+     ((not version)
+      (error "Unable to check out repository for %s" package-name))
+     ((= 1 (length files))
+      (quelpa-build--build-single-file-package
+       package-name version (caar files) source-dir target-dir))
+     ((< 1 (length  files))
+      (quelpa-build--build-multi-file-package
+       package-name version files source-dir target-dir))
+     (t (error "Unable to find files matching recipe patterns")))))
+
+(defun quelpa-build--build-single-file-package
+    (package-name version file source-dir target-dir)
+  (let* ((pkg-source (expand-file-name file source-dir))
+         (pkg-target (expand-file-name
+                      (concat package-name "-" version ".el")
+                      target-dir))
+         (pkg-info (quelpa-build--merge-package-info
+                    (quelpa-build--get-package-info pkg-source)
+                    package-name
+                    version)))
+    (unless (string-equal (downcase (concat package-name ".el"))
+                          (downcase (file-name-nondirectory pkg-source)))
+      (error "Single file %s does not match package name %s"
+             (file-name-nondirectory pkg-source) package-name))
+    (if (file-exists-p pkg-target)
+        (quelpa-build--message "Skipping rebuild of %s" pkg-target)
+      (copy-file pkg-source pkg-target)
+      (let ((enable-local-variables nil)
+            (make-backup-files nil))
+        (with-temp-buffer
+          (insert-file-contents pkg-target)
+          (quelpa-build--update-or-insert-version version)
+          (quelpa-build--ensure-ends-here-line pkg-source)
+          (write-file pkg-target nil)
+          (condition-case err
+              (quelpa-build--package-buffer-info-vec)
+            (error
+             (quelpa-build--message "Warning: %S" err)))))
+
+      (quelpa-build--write-pkg-readme
+       target-dir
+       (quelpa-build--find-package-commentary pkg-source)
+       package-name))
+    (quelpa-build--archive-entry pkg-info 'single)))
+
+(defun quelpa-build--build-multi-file-package
+    (package-name version files source-dir target-dir)
+  (let ((tmp-dir (file-name-as-directory (make-temp-file package-name t))))
+    (unwind-protect
+        (let* ((pkg-dir-name (concat package-name "-" version))
+               (pkg-tmp-dir (expand-file-name pkg-dir-name tmp-dir))
+               (pkg-file (concat package-name "-pkg.el"))
+               (pkg-file-source (or (quelpa-build--find-source-file pkg-file files)
+                                    pkg-file))
+               (file-source (concat package-name ".el"))
+               (pkg-source (or (quelpa-build--find-source-file file-source files)
+                               file-source))
+               (pkg-info (quelpa-build--merge-package-info
+                          (let ((default-directory source-dir))
+                            (or (quelpa-build--get-pkg-file-info pkg-file-source)
+                                ;; some packages (like magit) provide name-pkg.el.in
+                                (quelpa-build--get-pkg-file-info
+                                 (expand-file-name (concat pkg-file ".in")
+                                                   (file-name-directory pkg-source)))
+                                (quelpa-build--get-package-info pkg-source)))
+                          package-name
+                          version)))
+          (quelpa-build--copy-package-files files source-dir pkg-tmp-dir)
+          (quelpa-build--write-pkg-file (expand-file-name
+                                         pkg-file
+                                         (file-name-as-directory pkg-tmp-dir))
+                                        pkg-info)
+
+          (quelpa-build--generate-info-files files source-dir pkg-tmp-dir)
+          (quelpa-build--generate-dir-file files pkg-tmp-dir)
+
+          (let ((default-directory tmp-dir))
+            (quelpa-build--create-tar
+             (expand-file-name (concat package-name "-" version ".tar")
+                               target-dir)
+             pkg-dir-name))
+
+          (let ((default-directory source-dir))
+            (quelpa-build--write-pkg-readme
+             target-dir
+             (quelpa-build--find-package-commentary pkg-source)
+             package-name))
+          (quelpa-build--archive-entry pkg-info 'tar))
+      (delete-directory tmp-dir t nil))))
+
+(defun quelpa-build--checkout-file (name config dir)
+  "Build according to a PATH with config CONFIG into DIR as NAME.
+Generic local file handler for package-build.el.
+
+Handles the following cases:
+
+local file:
+
+Installs a single-file package from a local file.  Use the :path
+attribute with a PATH like \"/path/to/file.el\".
+
+local directory:
+
+Installs a multi-file package from a local directory.  Use
+the :path attribute with a PATH like \"/path/to/dir\"."
+  (quelpa-check-hash name config (expand-file-name (plist-get config :path)) dir))
+
+(defun quelpa-build--checkout-url (name config dir)
+  "Build according to an URL with config CONFIG into DIR as NAME.
+Generic URL handler for package-build.el.
+
+Handles the following cases:
+
+local file:
+
+Installs a single-file package from a local file.  Use the :url
+attribute with an URL like \"file:///path/to/file.el\".
+
+remote file:
+
+Installs a single-file package from a remote file.  Use the :url
+attribute with an URL like \"http://domain.tld/path/to/file.el\"."
+  (let* ((url (plist-get config :url))
+         (remote-file-name (file-name-nondirectory
+                            (url-filename (url-generic-parse-url url))))
+         (local-path (expand-file-name remote-file-name dir))
+         (mm-attachment-file-modes (default-file-modes)))
+    (unless (string= (file-name-extension url) "el")
+      (error "<%s> does not end in .el" url))
+    (unless (file-directory-p dir)
+      (make-directory dir))
+    (url-copy-file url local-path t)
+    (quelpa-check-hash name config local-path dir 'url)))
+
+;; --- helpers ---------------------------------------------------------------
+
+(defun quelpa-message (wait format-string &rest args)
+  "Log a message with FORMAT-STRING and ARGS when `quelpa-verbose' is non-nil.
+If WAIT is nil don't wait after showing the message. If it is a
+number, wait so many seconds. If WAIT is t wait the default time.
+Return t in each case."
+  (when quelpa-verbose
+    (message "Quelpa: %s" (apply 'format format-string args))
+    (when (or (not noninteractive) wait) ; no wait if emacs is noninteractive
+      (sit-for (or (and (numberp wait) wait) 1.5) t)))
+  t)
+
+(defun quelpa-read-cache ()
+  "Read from `quelpa-persistent-cache-file' in `quelpa-cache'."
+  (when (and quelpa-persistent-cache-p
+             (file-exists-p quelpa-persistent-cache-file))
+    (with-temp-buffer
+      (insert-file-contents-literally quelpa-persistent-cache-file)
+      (setq quelpa-cache
+            (read (buffer-substring-no-properties (point-min) (point-max)))))))
+
+(defun quelpa-save-cache ()
+  "Write `quelpa-cache' to `quelpa-persistent-cache-file'."
+  (when quelpa-persistent-cache-p
+    (let (print-level print-length)
+      (with-temp-file quelpa-persistent-cache-file
+        (insert (prin1-to-string quelpa-cache))))))
+
+(defun quelpa-update-cache (cache-item)
+  ;; try removing existing recipes by name
+  (setq quelpa-cache (cl-remove (car cache-item)
+                                quelpa-cache :key #'car))
+  (push cache-item quelpa-cache)
+  (setq quelpa-cache
+        (cl-sort quelpa-cache #'string<
+                 :key (lambda (item) (symbol-name (car item))))))
+
+(defun quelpa-parse-stable (cache-item)
+  ;; in case :stable doesn't originate from PLIST, shadow the
+  ;; default value anyways
+  (when (plist-member (cdr cache-item) :stable)
+    (setq quelpa-stable-p (plist-get (cdr cache-item) :stable)))
+  (when (and quelpa-stable-p (not (plist-get (cdr cache-item) :stable)))
+    (setf (cdr (last cache-item)) '(:stable t))))
+
+(defun quelpa-checkout-melpa ()
+  "Fetch or update the melpa source code from Github.
+If there is no error return non-nil.
+If there is an error but melpa is already checked out return non-nil.
+If there is an error and no existing checkout return nil."
+  (or (and (null quelpa-update-melpa-p)
+           (file-exists-p (expand-file-name ".git" quelpa-melpa-dir)))
+      (condition-case err
+          (quelpa-build--checkout-git
+           'package-build
+           `(:url ,quelpa-melpa-repo-url :files ("*"))
+           quelpa-melpa-dir)
+        (error "failed to checkout melpa git repo: `%s'" (error-message-string err)))))
+
+(defun quelpa-get-melpa-recipe (name)
+  "Read recipe with NAME for melpa git checkout.
+Return the recipe if it exists, otherwise nil."
+  (cl-loop for store in quelpa-melpa-recipe-stores
+           if (stringp store)
+           for file = (assoc-string name (directory-files store nil "^[^\.]+"))
+           when file
+           return (with-temp-buffer
+                    (insert-file-contents-literally
+                     (expand-file-name file store))
+                    (read (buffer-string)))
+           else
+           for rcp = (assoc-string name store)
+           when rcp
+           return rcp))
+
+(defun quelpa-setup-p ()
+  "Setup what we need for quelpa.
+Return non-nil if quelpa has been initialized properly."
+  (catch 'quit
+    (dolist (dir (list quelpa-packages-dir quelpa-build-dir))
+      (unless (file-exists-p dir) (make-directory dir t)))
+    (unless quelpa-initialized-p
+      (quelpa-read-cache)
+      (quelpa-setup-package-structs)
+      (if quelpa-checkout-melpa-p
+          (unless (quelpa-checkout-melpa) (throw 'quit nil)))
+      (setq quelpa-initialized-p t))
+    t))
+
+(defun quelpa-shutdown ()
+  "Do things that need to be done after running quelpa."
+  (quelpa-save-cache)
+  ;; remove the packages dir because we are done with the built pkgs
+  (ignore-errors (delete-directory quelpa-packages-dir t)))
+
+(defun quelpa-arg-rcp (arg)
+  "Given recipe or package name, return an alist '(NAME . RCP).
+If RCP cannot be found it will be set to nil"
+  (pcase arg
+    (`(,a . nil) (quelpa-get-melpa-recipe (car arg)))
+    (`(,a . ,_) arg)
+    ((pred symbolp) (quelpa-get-melpa-recipe arg))))
+
+(defun quelpa-parse-plist (plist)
+  "Parse the optional PLIST argument of `quelpa'.
+Recognized keywords are:
+
+:upgrade
+
+If t, `quelpa' tries to do an upgrade.
+
+:stable
+
+If t, `quelpa' tries building the stable version of a package."
+  (while plist
+    (let ((key (car plist))
+          (value (cadr plist)))
+      (pcase key
+        (:upgrade (setq quelpa-upgrade-p value))
+        (:stable (setq quelpa-stable-p value))))
+    (setq plist (cddr plist))))
+
+(defun quelpa-package-install-file (file)
+  "Workaround problem with `package-install-file'.
+`package-install-file' uses `insert-file-contents-literally'
+which causes problems when the file inserted has crlf line
+endings (Windows). So here we replace that with
+`insert-file-contents' for non-tar files."
+  (if (eq system-type 'windows-nt)
+      (cl-letf* ((insert-file-contents-literally-orig
+                  (symbol-function 'insert-file-contents-literally))
+                 ((symbol-function 'insert-file-contents-literally)
+                  (lambda (file)
+                    (if (string-match "\\.tar\\'" file)
+                        (funcall insert-file-contents-literally-orig file)
+                      (insert-file-contents file)))))
+        (package-install-file file))
+    (package-install-file file)))
+
+(defun quelpa-package-install (arg)
+  "Build and install package from ARG (a recipe or package name).
+If the package has dependencies recursively call this function to
+install them."
+  (let* ((rcp (quelpa-arg-rcp arg))
+         (file (and rcp (quelpa-build rcp))))
+    (when file
+      (let* ((pkg-desc (quelpa-get-package-desc file))
+             (requires (package-desc-reqs pkg-desc)))
+        (when requires
+          (mapc (lambda (req)
+                  (unless (or (equal 'emacs (car req))
+                              (package-installed-p (car req) (cadr req)))
+                    (quelpa-package-install (car req))))
+                requires))
+        (quelpa-package-install-file file)))))
+
+(defun quelpa-interactive-candidate ()
+  "Query the user for a recipe and return the name."
+  (when (quelpa-setup-p)
+    (let  ((recipes (cl-loop
+                     for store in quelpa-melpa-recipe-stores
+                     if (stringp store)
+                     ;; this regexp matches all files except dotfiles
+                     append (directory-files store nil "^[^.].+$")
+                     else if (listp store)
+                     append store)))
+      (intern (completing-read "Choose MELPA recipe: "
+                               recipes nil t)))))
+
+;; --- public interface ------------------------------------------------------
+
+;;;###autoload
+(defun quelpa-expand-recipe (recipe-name)
+  "Expand a given recipe name into full recipe.
+If called interactively, let the user choose a recipe name and
+insert the result into the current buffer."
+  (interactive (list (quelpa-interactive-candidate)))
+  (when (quelpa-setup-p)
+    (let* ((recipe (quelpa-get-melpa-recipe recipe-name)))
+      (when recipe
+        (if (called-interactively-p 'any)
+            (prin1 recipe (current-buffer)))
+        recipe))))
+
+;;;###autoload
+(defun quelpa-self-upgrade (&optional args)
+  "Upgrade quelpa itself.
+ARGS are additional options for the quelpa recipe."
+  (interactive)
+  (when (quelpa-setup-p)
+    (quelpa (append quelpa-recipe args) :upgrade t)))
+
+;;;###autoload
+(defun quelpa-upgrade ()
+  "Upgrade all packages found in `quelpa-cache'.
+This provides an easy way to upgrade all the packages for which
+the `quelpa' command has been run in the current Emacs session."
+  (interactive)
+  (when (quelpa-setup-p)
+    (let ((quelpa-upgrade-p t))
+      (when quelpa-self-upgrade-p
+        (quelpa-self-upgrade))
+      (setq quelpa-cache
+            (cl-remove-if-not #'package-installed-p quelpa-cache :key #'car))
+      (mapc (lambda (item)
+              (when (package-installed-p (car (quelpa-arg-rcp item)))
+                (quelpa item)))
+            quelpa-cache))))
+
+;;;###autoload
+(defun quelpa (arg &rest plist)
+  "Build and install a package with quelpa.
+ARG can be a package name (symbol) or a melpa recipe (list).
+PLIST is a plist that may modify the build and/or fetch process.
+If called interactively, `quelpa' will prompt for a MELPA package
+to install.
+
+When `quelpa' is called interactively with a prefix argument (e.g
+C-u M-x quelpa) it will try to upgrade the given package even if
+the global var `quelpa-upgrade-p' is set to nil."
+
+  (interactive (list (quelpa-interactive-candidate)))
+  (run-hooks 'quelpa-before-hook)
+  (when (quelpa-setup-p) ;if init fails we do nothing
+    (let* ((quelpa-upgrade-p (if current-prefix-arg t quelpa-upgrade-p)) ;shadow `quelpa-upgrade-p'
+           (quelpa-stable-p quelpa-stable-p) ;shadow `quelpa-stable-p'
+           (cache-item (if (symbolp arg) (list arg) arg)))
+      (quelpa-parse-plist plist)
+      (quelpa-parse-stable cache-item)
+      (quelpa-package-install arg)
+      (quelpa-update-cache cache-item)))
+  (quelpa-shutdown)
+  (run-hooks 'quelpa-after-hook))
+
+(provide 'quelpa)
+
+;;; quelpa.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/quelpa-20180711.1638/quelpa.elc b/configs/shared/emacs/.emacs.d/elpa/quelpa-20180711.1638/quelpa.elc
new file mode 100644
index 0000000000..010c585bb8
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/quelpa-20180711.1638/quelpa.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/quelpa-20180903.1313/bootstrap.el b/configs/shared/emacs/.emacs.d/elpa/quelpa-20180903.1313/bootstrap.el
new file mode 100644
index 0000000000..1e41c6577d
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/quelpa-20180903.1313/bootstrap.el
@@ -0,0 +1,32 @@
+;;; bootstrap.el --- Bootstrap quelpa.el
+
+;; Copyright 2014-2018, Steckerhalter
+
+;; Author: steckerhalter
+;; URL: https://framagit.org/steckerhalter/quelpa
+;; Version: 0.0.1
+;; License: https://framagit.org/steckerhalter/quelpa/LICENSE
+
+;; This file is not part of GNU Emacs.
+
+;;; Code:
+
+(require 'package)
+
+(defvar quelpa-ci-dir nil
+  "If non-nil, quelpa will not be loaded from the url but from the given dir.")
+
+;; `package' has to be initialized to install pkgs
+(package-initialize)
+
+(let ((temp-dir (make-temp-file "quelpa" t)))
+  (unless (require 'quelpa nil t)
+    (let ((file (or (when quelpa-ci-dir (concat quelpa-ci-dir "/quelpa.el"))
+                    (expand-file-name "quelpa.el" temp-dir))))
+      (unless quelpa-ci-dir
+        (url-copy-file "https://framagit.org/steckerhalter/quelpa/raw/master/quelpa.el" file t))
+      (package-install-file file)))
+
+  (delete-directory temp-dir t))
+
+;;; bootstrap.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/quelpa-20180903.1313/bootstrap.elc b/configs/shared/emacs/.emacs.d/elpa/quelpa-20180903.1313/bootstrap.elc
new file mode 100644
index 0000000000..9bef20457b
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/quelpa-20180903.1313/bootstrap.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/quelpa-20180903.1313/quelpa-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/quelpa-20180903.1313/quelpa-autoloads.el
new file mode 100644
index 0000000000..d67d6729d9
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/quelpa-20180903.1313/quelpa-autoloads.el
@@ -0,0 +1,73 @@
+;;; quelpa-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "quelpa" "quelpa.el" (23438 54750 469504 906000))
+;;; Generated autoloads from quelpa.el
+
+(autoload 'quelpa-build-package "quelpa" "\
+Create PACKAGE-NAME with VERSION.
+
+The information in FILE-SPECS is used to gather files from
+SOURCE-DIR.
+
+The resulting package will be stored as a .el or .tar file in
+TARGET-DIR, depending on whether there are multiple files.
+
+Argument FILE-SPECS is a list of specs for source files, which
+should be relative to SOURCE-DIR.  The specs can be wildcards,
+and optionally specify different target paths.  They extended
+syntax is currently only documented in the MELPA README.  You can
+simply pass `quelpa-build-default-files-spec' in most cases.
+
+Returns the archive entry for the package.
+
+\(fn PACKAGE-NAME VERSION FILE-SPECS SOURCE-DIR TARGET-DIR)" nil nil)
+
+(autoload 'quelpa-expand-recipe "quelpa" "\
+Expand a given recipe name into full recipe.
+If called interactively, let the user choose a recipe name and
+insert the result into the current buffer.
+
+\(fn RECIPE-NAME)" t nil)
+
+(autoload 'quelpa-self-upgrade "quelpa" "\
+Upgrade quelpa itself.
+ARGS are additional options for the quelpa recipe.
+
+\(fn &optional ARGS)" t nil)
+
+(autoload 'quelpa-upgrade "quelpa" "\
+Upgrade all packages found in `quelpa-cache'.
+This provides an easy way to upgrade all the packages for which
+the `quelpa' command has been run in the current Emacs session.
+
+\(fn)" t nil)
+
+(autoload 'quelpa "quelpa" "\
+Build and install a package with quelpa.
+ARG can be a package name (symbol) or a melpa recipe (list).
+PLIST is a plist that may modify the build and/or fetch process.
+If called interactively, `quelpa' will prompt for a MELPA package
+to install.
+
+When `quelpa' is called interactively with a prefix argument (e.g
+C-u M-x quelpa) it will try to upgrade the given package even if
+the global var `quelpa-upgrade-p' is set to nil.
+
+\(fn ARG &rest PLIST)" t nil)
+
+;;;***
+
+;;;### (autoloads nil nil ("bootstrap.el" "quelpa-pkg.el") (23438
+;;;;;;  54750 473300 416000))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; quelpa-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/quelpa-20180903.1313/quelpa-pkg.el b/configs/shared/emacs/.emacs.d/elpa/quelpa-20180903.1313/quelpa-pkg.el
new file mode 100644
index 0000000000..1b4dd58a57
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/quelpa-20180903.1313/quelpa-pkg.el
@@ -0,0 +1,12 @@
+(define-package "quelpa" "20180903.1313" "Emacs Lisp packages built directly from source"
+  '((emacs "24.3"))
+  :keywords
+  '("package" "management" "build" "source" "elpa")
+  :authors
+  '(("steckerhalter"))
+  :maintainer
+  '("steckerhalter")
+  :url "https://framagit.org/steckerhalter/quelpa")
+;; Local Variables:
+;; no-byte-compile: t
+;; End:
diff --git a/configs/shared/emacs/.emacs.d/elpa/quelpa-20180903.1313/quelpa.el b/configs/shared/emacs/.emacs.d/elpa/quelpa-20180903.1313/quelpa.el
new file mode 100644
index 0000000000..5a39359b13
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/quelpa-20180903.1313/quelpa.el
@@ -0,0 +1,1832 @@
+;;; quelpa.el --- Emacs Lisp packages built directly from source
+
+;; Copyright 2014-2018, Steckerhalter
+;; Copyright 2014-2015, Vasilij Schneidermann <v.schneidermann@gmail.com>
+
+;; Author: steckerhalter
+;; URL: https://framagit.org/steckerhalter/quelpa
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "24.3"))
+;; Keywords: package management build source elpa
+
+;; This file is not part of GNU Emacs.
+
+;; This file 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, or (at your option)
+;; any later version.
+
+;; This file 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; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+
+;; Your personal local Emacs Lisp Package Archive (ELPA) with packages
+;; built on-the-fly directly from source.
+
+;; See the README for more info:
+;; https://framagit.org/steckerhalter/quelpa/blob/master/README.md
+
+;;; Requirements:
+
+;; Emacs 24.3.1
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'help-fns)
+(require 'url-parse)
+(require 'package)
+(require 'lisp-mnt)
+
+;; --- customs / variables ---------------------------------------------------
+
+(defgroup quelpa nil
+  "Build and install packages from source code"
+  :group 'package)
+
+(defcustom quelpa-upgrade-p nil
+  "When non-nil, `quelpa' will try to upgrade packages.
+The global value can be overridden for each package by supplying
+the `:upgrade' argument."
+  :group 'quelpa
+  :type 'boolean)
+
+(defcustom quelpa-stable-p nil
+  "When non-nil, try to build stable packages like MELPA does."
+  :group 'quelpa
+  :type 'boolean)
+
+(defcustom quelpa-verbose t
+  "When non-nil, `quelpa' prints log messages."
+  :group 'quelpa
+  :type 'boolean)
+
+(defcustom quelpa-before-hook nil
+  "List of functions to be called before quelpa."
+  :group 'quelpa
+  :type 'hook)
+
+(defcustom quelpa-after-hook nil
+  "List of functions to be called after quelpa."
+  :group 'quelpa
+  :type 'hook)
+
+(defcustom quelpa-dir (expand-file-name "quelpa" user-emacs-directory)
+  "Where quelpa builds and stores packages."
+  :group 'quelpa
+  :type 'string)
+
+(defcustom quelpa-melpa-dir (expand-file-name "melpa" quelpa-dir)
+  "Where the melpa repo cloned to."
+  :group 'quelpa
+  :type 'string)
+
+(defcustom quelpa-build-dir (expand-file-name "build" quelpa-dir)
+  "Where quelpa builds packages."
+  :group 'quelpa
+  :type 'string)
+
+(defcustom quelpa-packages-dir (expand-file-name "packages" quelpa-dir)
+  "Where quelpa puts built packages."
+  :group 'quelpa
+  :type 'string)
+
+(defcustom quelpa-melpa-recipe-stores (list (expand-file-name
+                                             "recipes"
+                                             quelpa-melpa-dir))
+  "Recipe stores where quelpa finds default recipes for packages.
+A store can either be a string pointing to a directory with
+recipe files or a list with recipes."
+  :group 'quelpa
+  :type '(repeat
+          (choice directory
+                  (repeat
+                   :tag "List of recipes"
+                   (restricted-sexp :tag "Recipe"
+                                    :match-alternatives (listp))))))
+
+(defcustom quelpa-persistent-cache-file (expand-file-name "cache" quelpa-dir)
+  "Location of the persistent cache file."
+  :group 'quelpa
+  :type 'string)
+
+(defcustom quelpa-persistent-cache-p t
+  "Non-nil when quelpa's cache is saved on and read from disk."
+  :group 'quelpa
+  :type 'boolean)
+
+(defcustom quelpa-checkout-melpa-p t
+  "If non-nil the MELPA git repo is cloned when quelpa is initialized."
+  :group 'quelpa
+  :type 'boolean)
+
+(defcustom quelpa-update-melpa-p t
+  "If non-nil the MELPA git repo is updated when quelpa is initialized.
+If nil the update is disabled and the repo is only updated on
+`quelpa-upgrade' or `quelpa-self-upgrade'."
+  :group 'quelpa
+  :type 'boolean)
+
+(defcustom quelpa-melpa-repo-url "https://github.com/melpa/melpa.git"
+  "The melpa git repository url."
+  :group 'quelpa
+  :type 'string)
+
+(defcustom quelpa-self-upgrade-p t
+  "If non-nil upgrade quelpa itself when doing a
+  `quelpa-upgrade', otherwise only upgrade the packages in the
+  quelpa cache."
+  :group 'quelpa
+  :type 'boolean)
+
+(defvar quelpa-initialized-p nil
+  "Non-nil when quelpa has been initialized.")
+
+(defvar quelpa-cache nil
+  "The `quelpa' command stores processed pkgs/recipes in the cache.")
+
+(defvar quelpa-recipe '(quelpa :url "https://framagit.org/steckerhalter/quelpa.git" :fetcher git)
+  "The recipe for quelpa.")
+
+;; --- compatibility for legacy `package.el' in Emacs 24.3  -------------------
+
+(defun quelpa-setup-package-structs ()
+  "Setup the struct `package-desc' when not available.
+`package-desc-from-legacy' is provided to convert the legacy
+vector desc into a valid PACKAGE-DESC."
+  (unless (functionp 'package-desc-p)
+    (cl-defstruct
+        (package-desc
+         (:constructor
+          ;; convert legacy package desc into PACKAGE-DESC
+          package-desc-from-legacy
+          (pkg-info kind
+                    &aux
+                    (name (intern (aref pkg-info 0)))
+                    (version (version-to-list (aref pkg-info 3)))
+                    (summary (if (string= (aref pkg-info 2) "")
+                                 "No description available."
+                               (aref pkg-info 2)))
+                    (reqs  (aref pkg-info 1))
+                    (kind kind))))
+      name
+      version
+      (summary "No description available.")
+      reqs
+      kind
+      archive
+      dir
+      extras
+      signed)))
+
+;; --- package building ------------------------------------------------------
+
+(defun quelpa-package-type (file)
+  "Determine the package type of FILE.
+Return `tar' for tarball packages, `single' for single file
+packages, or nil, if FILE is not a package."
+  (let ((ext (file-name-extension file)))
+    (cond
+     ((string= ext "tar") 'tar)
+     ((string= ext "el") 'single)
+     (:else nil))))
+
+(defun quelpa-get-package-desc (file)
+  "Extract and return the PACKAGE-DESC struct from FILE.
+On error return nil."
+  (let* ((kind (quelpa-package-type file))
+         (desc (with-demoted-errors "Error getting PACKAGE-DESC: %s"
+                 (with-temp-buffer
+                   (pcase kind
+                     (`single (insert-file-contents file)
+                              (package-buffer-info))
+                     (`tar (insert-file-contents-literally file)
+                           (tar-mode)
+                           (if (help-function-arglist 'package-tar-file-info)
+                               ;; legacy `package-tar-file-info' requires an arg
+                               (package-tar-file-info file)
+                             (with-no-warnings (package-tar-file-info)))))))))
+    (pcase desc
+      ((pred package-desc-p) desc)
+      ((pred vectorp) (package-desc-from-legacy desc kind)))))
+
+(defun quelpa-archive-file-name (archive-entry)
+  "Return the path of the file in which the package for ARCHIVE-ENTRY is stored."
+  (let* ((name (car archive-entry))
+         (pkg-info (cdr archive-entry))
+         (version (package-version-join (aref pkg-info 0)))
+         (flavour (aref pkg-info 3)))
+    (expand-file-name
+     (format "%s-%s.%s" name version (if (eq flavour 'single) "el" "tar"))
+     quelpa-packages-dir)))
+
+(defun quelpa-version>-p (name version)
+  "Return non-nil if VERSION of pkg with NAME is newer than what is currently installed."
+  (not (or (not version)
+           (let ((pkg-desc (cdr (assq name package-alist))))
+             (and pkg-desc
+                  (version-list-<=
+                   (version-to-list version)
+                   (if (functionp 'package-desc-vers)
+                       (package-desc-vers pkg-desc) ;old implementation
+                     (package-desc-version (car pkg-desc))))))
+           ;; Also check built-in packages.
+           (package-built-in-p name (version-to-list version)))))
+
+(defun quelpa-checkout (rcp dir)
+  "Return the version of the new package given a RCP.
+Return nil if the package is already installed and should not be upgraded."
+  (pcase-let ((`(,name . ,config) rcp)
+              (quelpa-build-stable quelpa-stable-p))
+    (unless (or (and (assq name package-alist) (not quelpa-upgrade-p))
+                (and (not config)
+                     (quelpa-message t "no recipe found for package `%s'" name)))
+      (let ((version (condition-case err
+                         (quelpa-build-checkout name config dir)
+                       (error "Failed to checkout `%s': `%s'"
+                              name (error-message-string err)))))
+        (when (quelpa-version>-p name version)
+          version)))))
+
+(defun quelpa-build (rcp)
+  "Build a package from the given recipe RCP.
+Uses the `package-build' library to get the source code and build
+an elpa compatible package in `quelpa-build-dir' storing it in
+`quelpa-packages-dir'. Return the path to the created file or nil
+if no action is necessary (like when the package is installed
+already and should not be upgraded etc)."
+  (let* ((name (car rcp))
+         (build-dir (expand-file-name (symbol-name name) quelpa-build-dir))
+         (version (quelpa-checkout rcp build-dir)))
+    (when version
+      (quelpa-archive-file-name
+       (quelpa-build-package (symbol-name name)
+                             version
+                             (quelpa-build--config-file-list (cdr rcp))
+                             build-dir
+                             quelpa-packages-dir)))))
+
+;; --- package-build.el integration ------------------------------------------
+
+(defun quelpa-file-version (file-path type version time-stamp)
+  "Return version of file at FILE-PATH."
+  (if (eq type 'directory)
+      time-stamp
+    (cl-letf* ((package-strip-rcs-id-orig (symbol-function 'package-strip-rcs-id))
+               ((symbol-function 'package-strip-rcs-id)
+                (lambda (str)
+                  (or (funcall package-strip-rcs-id-orig (lm-header "package-version"))
+                      (funcall package-strip-rcs-id-orig (lm-header "version"))
+                      "0"))))
+      (concat (mapconcat
+               #'number-to-string
+               (package-desc-version (quelpa-get-package-desc file-path)) ".")
+              (pcase version
+                (`original "")
+                (_ (concat "pre0." time-stamp)))))))
+
+(defun quelpa-directory-files (path)
+  "Return list of directory files from PATH recursively."
+  (let ((result '()))
+    (mapc
+     (lambda (file)
+       (if (file-directory-p file)
+           (progn
+             ;; When directory is not empty.
+             (when (cddr (directory-files file))
+               (dolist (subfile (quelpa-directory-files file))
+                 (add-to-list 'result subfile))))
+         (add-to-list 'result file)))
+     (mapcar
+      (lambda (file) (expand-file-name file path))
+      ;; Without first two entries because they are always "." and "..".
+      (cddr (directory-files path))))
+    result))
+
+(defun quelpa-expand-source-file-list (file-path config)
+  "Return list of source files from FILE-PATH corresponding to
+CONFIG."
+  (let ((source-files
+         (mapcar
+          (lambda (file) (expand-file-name file file-path))
+          (quelpa-build--expand-source-file-list file-path config))))
+    ;; Replace any directories in the source file list with the filenames of the
+    ;; files they contain (so that these files can subsequently be hashed).
+    (dolist (file source-files source-files)
+      (when (file-directory-p file)
+        (setq source-files (remove file source-files))
+        (setq source-files (append source-files
+                                   (quelpa-directory-files file)))))))
+
+(defun quelpa-slurp-file (file)
+  "Return the contents of FILE as a string, or nil if no such
+file exists."
+  (when (file-exists-p file)
+    (with-temp-buffer
+      (set-buffer-multibyte nil)
+      (setq-local buffer-file-coding-system 'binary)
+      (insert-file-contents-literally file)
+      (buffer-substring-no-properties (point-min) (point-max)))))
+
+(defun quelpa-check-hash (name config file-path dir &optional fetcher)
+  "Check if hash of FILE-PATH is different as in STAMP-FILE.
+If it is different save the new hash and timestamp to STAMP-FILE
+and return TIME-STAMP, otherwise return OLD-TIME-STAMP."
+  (unless (file-directory-p dir)
+    (make-directory dir))
+  (let* (files
+         hashes
+         new-stamp-info
+         new-content-hash
+         (time-stamp
+          (replace-regexp-in-string "\\.0+" "." (format-time-string "%Y%m%d.%H%M%S")))
+         (stamp-file (concat (expand-file-name (symbol-name name) dir) ".stamp"))
+         (old-stamp-info (quelpa-build--read-from-file stamp-file))
+         (old-content-hash (cdr old-stamp-info))
+         (old-time-stamp (car old-stamp-info))
+         (type (if (file-directory-p file-path) 'directory 'file))
+         (version (plist-get config :version)))
+
+    (if (not (file-exists-p file-path))
+        (error "`%s' does not exist" file-path)
+      (if (eq type 'directory)
+          (setq files (quelpa-expand-source-file-list file-path config)
+                hashes (mapcar
+                        (lambda (file)
+                          (secure-hash
+                           'sha1 (concat file (quelpa-slurp-file file)))) files)
+                new-content-hash (secure-hash 'sha1 (mapconcat 'identity hashes "")))
+        (setq new-content-hash (secure-hash 'sha1 (quelpa-slurp-file file-path)))))
+
+    (setq new-stamp-info (cons time-stamp new-content-hash))
+    (if (and old-content-hash
+             (string= new-content-hash old-content-hash))
+        (quelpa-file-version file-path type version old-time-stamp)
+      (unless (eq fetcher 'url)
+        (delete-directory dir t)
+        (make-directory dir)
+        (if (eq type 'file)
+            (copy-file file-path dir t t t t)
+          (copy-directory file-path dir t t t)))
+      (quelpa-build--dump new-stamp-info stamp-file)
+      (quelpa-file-version file-path type version time-stamp))))
+
+;; --- package-build fork ------------------------------------------
+
+(defcustom quelpa-build-verbose t
+  "When non-nil, then print additional progress information."
+  :type 'boolean)
+
+(defcustom quelpa-build-stable nil
+  "When non-nil, then try to build packages from versions-tagged code."
+  :type 'boolean)
+
+(defcustom quelpa-build-timeout-executable
+  (let ((prog (or (executable-find "timeout")
+                  (executable-find "gtimeout"))))
+    (when (and prog
+               (string-match-p "^ *-k"
+                               (shell-command-to-string (concat prog " --help"))))
+      prog))
+  "Path to a GNU coreutils \"timeout\" command if available.
+This must be a version which supports the \"-k\" option."
+  :type '(file :must-match t))
+
+(defcustom quelpa-build-timeout-secs 600
+  "Wait this many seconds for external processes to complete.
+
+If an external process takes longer than specified here to
+complete, then it is terminated.  This only has an effect
+if `quelpa-build-timeout-executable' is non-nil."
+  :type 'number)
+
+(defcustom quelpa-build-tar-executable
+  (or (executable-find "gtar")
+      (executable-find "tar"))
+  "Path to a (preferably GNU) tar command.
+Certain package names (e.g. \"@\") may not work properly with a BSD tar."
+  :type '(file :must-match t))
+
+(defcustom quelpa-build-version-regexp "^[rRvV]?\\(.*\\)$"
+  "Default pattern for matching valid version-strings within repository tags.
+The string in the capture group should be parsed as valid by `version-to-list'."
+  :type 'string)
+
+;;; Internal Variables
+
+(defconst quelpa-build-default-files-spec
+  '("*.el" "*.el.in" "dir"
+    "*.info" "*.texi" "*.texinfo"
+    "doc/dir" "doc/*.info" "doc/*.texi" "doc/*.texinfo"
+    (:exclude ".dir-locals.el" "test.el" "tests.el" "*-test.el" "*-tests.el"))
+  "Default value for :files attribute in recipes.")
+
+;;; Utilities
+
+(defun quelpa-build--message (format-string &rest args)
+  "Behave like `message' if `quelpa-build-verbose' is non-nil.
+Otherwise do nothing."
+  (when quelpa-build-verbose
+    (apply 'message format-string args)))
+
+(defun quelpa-build--slurp-file (file)
+  "Return the contents of FILE as a string, or nil if no such file exists."
+  (when (file-exists-p file)
+    (with-temp-buffer
+      (insert-file-contents file)
+      (buffer-substring-no-properties (point-min) (point-max)))))
+
+(defun quelpa-build--string-rtrim (str)
+  "Remove trailing whitespace from `STR'."
+  (replace-regexp-in-string "[ \t\n\r]+$" "" str))
+
+(defun quelpa-build--trim (str &optional chr)
+  "Return a copy of STR without any trailing CHR (or space if unspecified)."
+  (if (equal (elt str (1- (length str))) (or chr ? ))
+      (substring str 0 (1- (length str)))
+    str))
+
+;;; Version Handling
+
+(defun quelpa-build--valid-version (str &optional regexp)
+  "Apply to STR the REGEXP if defined, \
+then pass the string to `version-to-list' and return the result, \
+or nil if the version cannot be parsed."
+  (when (and regexp (string-match regexp str))
+    (setq str (match-string 1 str)))
+  (ignore-errors (version-to-list str)))
+
+(defun quelpa-build--parse-time (str)
+  "Parse STR as a time, and format as a YYYYMMDD.HHMM string."
+  ;; We remove zero-padding the HH portion, as it is lost
+  ;; when stored in the archive-contents
+  (setq str (substring-no-properties str))
+  (let ((time (date-to-time
+               (if (string-match "\
+^\\([0-9]\\{4\\}\\)/\\([0-9]\\{2\\}\\)/\\([0-9]\\{2\\}\\) \
+\\([0-9]\\{2\\}:[0-9]\\{2\\}:[0-9]\\{2\\}\\)$" str)
+                   (concat (match-string 1 str) "-" (match-string 2 str) "-"
+                           (match-string 3 str) " " (match-string 4 str))
+                 str))))
+    (concat (format-time-string "%Y%m%d." time)
+            (format "%d" (string-to-number (format-time-string "%H%M" time))))))
+
+(defun quelpa-build--find-parse-time (regexp &optional bound)
+  "Find REGEXP in current buffer and format as a time-based version string.
+An optional second argument bounds the search; it is a buffer
+position.  The match found must not end after that position."
+  (and (re-search-backward regexp bound t)
+       (quelpa-build--parse-time (match-string-no-properties 1))))
+
+(defun quelpa-build--find-parse-time-newest (regexp &optional bound)
+  "Find REGEXP in current buffer and format as a time-based version string.
+An optional second argument bounds the search; it is a buffer
+position.  The match found must not end after that position."
+  (save-match-data
+    (let (cur matches)
+      (while (setq cur (quelpa-build--find-parse-time regexp bound))
+        (push cur matches))
+      (car (nreverse (sort matches 'string<))))))
+
+(defun quelpa-build--find-version-newest (regexp &optional bound)
+  "Find the newest version matching REGEXP before point.
+An optional second argument bounds the search; it is a buffer
+position.  The match found must not before after that position."
+  (let ((tags (split-string
+               (buffer-substring-no-properties
+                (or bound (point-min)) (point))
+               "\n")))
+    (setq tags (append
+                (mapcar
+                 ;; Because the default `version-separator' is ".",
+                 ;; version-strings like "1_4_5" will be parsed
+                 ;; wrongly as (1 -4 4 -4 5), so we set
+                 ;; `version-separator' to "_" below and run again.
+                 (lambda (tag)
+                   (when (quelpa-build--valid-version tag regexp)
+                     (list (quelpa-build--valid-version tag regexp) tag)))
+                 tags)
+                (mapcar
+                 ;; Check for valid versions again, this time using
+                 ;; "_" as a separator instead of "." to catch
+                 ;; version-strings like "1_4_5".  Since "_" is
+                 ;; otherwise treated as a snapshot separator by
+                 ;; `version-regexp-alist', we don't have to worry
+                 ;; about the incorrect version list above—(1 -4 4 -4
+                 ;; 5)—since it will always be treated as older by
+                 ;; `version-list-<'.
+                 (lambda (tag)
+                   (let ((version-separator "_"))
+                     (when (quelpa-build--valid-version tag regexp)
+                       (list (quelpa-build--valid-version tag regexp) tag))))
+                 tags)))
+    (setq tags (cl-remove-if nil tags))
+    ;; Returns a list like ((0 1) ("v0.1")); the first element is used
+    ;; for comparison and for `package-version-join', and the second
+    ;; (the original tag) is used by git/hg/etc.
+    (car (nreverse (sort tags (lambda (v1 v2) (version-list-< (car v1) (car v2))))))))
+
+;;; Run Process
+
+(defun quelpa-build--run-process (dir command &rest args)
+  "In DIR (or `default-directory' if unset) run COMMAND with ARGS.
+Output is written to the current buffer."
+  (let ((default-directory (file-name-as-directory (or dir default-directory)))
+        (argv (nconc (unless (eq system-type 'windows-nt)
+                       (list "env" "LC_ALL=C"))
+                     (if quelpa-build-timeout-executable
+                         (nconc (list quelpa-build-timeout-executable
+                                      "-k" "60" (number-to-string
+                                                 quelpa-build-timeout-secs)
+                                      command)
+                                args)
+                       (cons command args)))))
+    (unless (file-directory-p default-directory)
+      (error "Can't run process in non-existent directory: %s" default-directory))
+    (let ((exit-code (apply 'process-file
+                            (car argv) nil (current-buffer) t
+                            (cdr argv))))
+      (or (zerop exit-code)
+          (error "Command '%s' exited with non-zero status %d: %s"
+                 argv exit-code (buffer-string))))))
+
+(defun quelpa-build--run-process-match (regexp dir prog &rest args)
+  "Run PROG with args and return the first match for REGEXP in its output.
+PROG is run in DIR, or if that is nil in `default-directory'."
+  (with-temp-buffer
+    (apply 'quelpa-build--run-process dir prog args)
+    (goto-char (point-min))
+    (re-search-forward regexp)
+    (match-string-no-properties 1)))
+
+;;; Checkout
+;;;; Common
+
+(defun quelpa-build-checkout (package-name config working-dir)
+  "Check out source for PACKAGE-NAME with CONFIG under WORKING-DIR.
+In turn, this function uses the :fetcher option in the CONFIG to
+choose a source-specific fetcher function, which it calls with
+the same arguments.
+
+Returns the package version as a string."
+  (let ((fetcher (plist-get config :fetcher)))
+    (quelpa-build--message "Fetcher: %s" fetcher)
+    (unless (eq fetcher 'wiki)
+      (quelpa-build--message "Source: %s\n"
+                             (or (plist-get config :repo)
+                                 (plist-get config :url))))
+    (funcall (intern (format "quelpa-build--checkout-%s" fetcher))
+             package-name config (file-name-as-directory working-dir))))
+
+(defun quelpa-build--princ-exists (dir)
+  "Print a message that the contents of DIR will be updated."
+  (quelpa-build--message "Updating %s" dir))
+
+(defun quelpa-build--princ-checkout (repo dir)
+  "Print a message that REPO will be checked out into DIR."
+  (quelpa-build--message "Cloning %s to %s" repo dir))
+
+;;;; Wiki
+
+(defvar quelpa-build--last-wiki-fetch-time 0
+  "The time at which an emacswiki URL was last requested.
+This is used to avoid exceeding the rate limit of 1 request per 2
+seconds; the server cuts off after 10 requests in 20 seconds.")
+
+(defvar quelpa-build--wiki-min-request-interval 3
+  "The shortest permissible interval between successive requests for Emacswiki URLs.")
+
+(defmacro quelpa-build--with-wiki-rate-limit (&rest body)
+  "Rate-limit BODY code passed to this macro to match EmacsWiki's rate limiting."
+  (let ((elapsed (cl-gensym)))
+    `(let ((,elapsed (- (float-time) quelpa-build--last-wiki-fetch-time)))
+       (when (< ,elapsed quelpa-build--wiki-min-request-interval)
+         (let ((wait (- quelpa-build--wiki-min-request-interval ,elapsed)))
+           (quelpa-build--message
+            "Waiting %.2f secs before hitting Emacswiki again" wait)
+           (sleep-for wait)))
+       (unwind-protect
+           (progn ,@body)
+         (setq quelpa-build--last-wiki-fetch-time (float-time))))))
+
+(require 'mm-decode)
+(defvar url-http-response-status)
+(defvar url-http-end-of-headers)
+
+(defun quelpa-build--url-copy-file (url newname &optional ok-if-already-exists)
+  "Copy URL to NEWNAME.  Both args must be strings.
+Returns the http request's header as a string.
+Like `url-copy-file', but it produces an error if the http response is not 200.
+Signals a `file-already-exists' error if file NEWNAME already exists,
+unless a third argument OK-IF-ALREADY-EXISTS is supplied and non-nil.
+A number as third arg means request confirmation if NEWNAME already exists."
+  (if (and (file-exists-p newname)
+           (not ok-if-already-exists))
+      (error "Opening output file: File already exists, %s" newname))
+  (let ((buffer (url-retrieve-synchronously url))
+        (headers nil)
+        (handle nil))
+    (if (not buffer)
+        (error "Opening input file: No such file or directory, %s" url))
+    (with-current-buffer buffer
+      (unless (= 200 url-http-response-status)
+        (error "HTTP error %s fetching %s" url-http-response-status url))
+      (setq handle (mm-dissect-buffer t))
+      (mail-narrow-to-head)
+      (setq headers (buffer-string)))
+    (mm-save-part-to-file handle newname)
+    (kill-buffer buffer)
+    (mm-destroy-parts handle)
+    headers))
+
+(defun quelpa-build--grab-wiki-file (filename)
+  "Download FILENAME from emacswiki, returning its last-modified time."
+  (let ((download-url
+         (format "https://www.emacswiki.org/emacs/download/%s" filename))
+        headers)
+    (quelpa-build--with-wiki-rate-limit
+     (setq headers (quelpa-build--url-copy-file download-url filename t)))
+    (when (zerop (nth 7 (file-attributes filename)))
+      (error "Wiki file %s was empty - has it been removed?" filename))
+    (quelpa-build--parse-time
+     (with-temp-buffer
+       (insert headers)
+       (mail-fetch-field "last-modified")))))
+
+(defun quelpa-build--checkout-wiki (name config dir)
+  "Checkout package NAME with config CONFIG from the EmacsWiki into DIR."
+  (unless quelpa-build-stable
+    (with-current-buffer (get-buffer-create "*quelpa-build-checkout*")
+      (unless (file-exists-p dir)
+        (make-directory dir))
+      (let ((files (or (plist-get config :files)
+                       (list (format "%s.el" name))))
+            (default-directory dir))
+        (car (nreverse (sort (mapcar 'quelpa-build--grab-wiki-file files)
+                             'string-lessp)))))))
+
+;;;; Darcs
+
+(defun quelpa-build--darcs-repo (dir)
+  "Get the current darcs repo for DIR."
+  (quelpa-build--run-process-match "Default Remote: \\(.*\\)"
+                                   dir "darcs" "show" "repo"))
+
+(defun quelpa-build--checkout-darcs (name config dir)
+  "Check package NAME with config CONFIG out of darcs into DIR."
+  (let ((repo (plist-get config :url)))
+    (with-current-buffer (get-buffer-create "*quelpa-build-checkout*")
+      (cond
+       ((and (file-exists-p (expand-file-name "_darcs" dir))
+             (string-equal (quelpa-build--darcs-repo dir) repo))
+        (quelpa-build--princ-exists dir)
+        (quelpa-build--run-process dir "darcs" "pull" "--all"))
+       (t
+        (when (file-exists-p dir)
+          (delete-directory dir t))
+        (quelpa-build--princ-checkout repo dir)
+        (quelpa-build--run-process nil "darcs" "get" repo dir)))
+      (if quelpa-build-stable
+          (let* ((min-bound (goto-char (point-max)))
+                 (tag-version
+                  (and (quelpa-build--run-process dir "darcs" "show" "tags")
+                       (or (quelpa-build--find-version-newest
+                            (or (plist-get config :version-regexp)
+                                quelpa-build-version-regexp)
+                            min-bound)
+                           (error "No valid stable versions found for %s" name)))))
+            (quelpa-build--run-process dir "darcs" "obliterate"
+                                       "--all" "--from-tag"
+                                       (cadr tag-version))
+            ;; Return the parsed version as a string
+            (package-version-join (car tag-version)))
+        (apply 'quelpa-build--run-process
+               dir "darcs" "changes" "--max-count" "1"
+               (quelpa-build--expand-source-file-list dir config))
+        (quelpa-build--find-parse-time "\
+\\([a-zA-Z]\\{3\\} [a-zA-Z]\\{3\\} \
+\\( \\|[0-9]\\)[0-9] [0-9]\\{2\\}:[0-9]\\{2\\}:[0-9]\\{2\\} \
+[A-Za-z]\\{3\\} [0-9]\\{4\\}\\)")))))
+
+;;;; Fossil
+
+(defun quelpa-build--fossil-repo (dir)
+  "Get the current fossil repo for DIR."
+  (quelpa-build--run-process-match "\\(.*\\)" dir "fossil" "remote-url"))
+
+(defun quelpa-build--checkout-fossil (name config dir)
+  "Check package NAME with config CONFIG out of fossil into DIR."
+  (unless quelpa-build-stable
+    (let ((repo (plist-get config :url)))
+      (with-current-buffer (get-buffer-create "*quelpa-build-checkout*")
+        (cond
+         ((and (or (file-exists-p (expand-file-name ".fslckout" dir))
+                   (file-exists-p (expand-file-name "_FOSSIL_" dir)))
+               (string-equal (quelpa-build--fossil-repo dir) repo))
+          (quelpa-build--princ-exists dir)
+          (quelpa-build--run-process dir "fossil" "update"))
+         (t
+          (when (file-exists-p dir)
+            (delete-directory dir t))
+          (quelpa-build--princ-checkout repo dir)
+          (make-directory dir)
+          (quelpa-build--run-process dir "fossil" "clone" repo "repo.fossil")
+          (quelpa-build--run-process dir "fossil" "open" "repo.fossil")))
+        (quelpa-build--run-process dir "fossil" "timeline" "-n" "1" "-t" "ci")
+        (or (quelpa-build--find-parse-time "\
+=== \\([0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\} ===\n\
+[0-9]\\{2\\}:[0-9]\\{2\\}:[0-9]\\{2\\}\\) ")
+            (error "No valid timestamps found!"))))))
+
+;;;; Svn
+
+(defun quelpa-build--svn-repo (dir)
+  "Get the current svn repo for DIR."
+  (quelpa-build--run-process-match "URL: \\(.*\\)" dir "svn" "info"))
+
+(defun quelpa-build--checkout-svn (name config dir)
+  "Check package NAME with config CONFIG out of svn into DIR."
+  (unless quelpa-build-stable
+    (with-current-buffer (get-buffer-create "*quelpa-build-checkout*")
+      (let ((repo (quelpa-build--trim (plist-get config :url) ?/))
+            (bound (goto-char (point-max))))
+        (cond
+         ((and (file-exists-p (expand-file-name ".svn" dir))
+               (string-equal (quelpa-build--svn-repo dir) repo))
+          (quelpa-build--princ-exists dir)
+          (quelpa-build--run-process dir "svn" "up"))
+         (t
+          (when (file-exists-p dir)
+            (delete-directory dir t))
+          (quelpa-build--princ-checkout repo dir)
+          (quelpa-build--run-process nil "svn" "checkout" repo dir)))
+        (apply 'quelpa-build--run-process dir "svn" "info"
+               (quelpa-build--expand-source-file-list dir config))
+        (or (quelpa-build--find-parse-time-newest "\
+Last Changed Date: \\([0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\} \
+[0-9]\\{2\\}:[0-9]\\{2\\}:[0-9]\\{2\\}\\( [+-][0-9]\\{4\\}\\)?\\)"
+                                                  bound)
+            (error "No valid timestamps found!"))))))
+
+;;;; Cvs
+
+(defun quelpa-build--cvs-repo (dir)
+  "Get the current CVS root and repository for DIR.
+
+Return a cons cell whose `car' is the root and whose `cdr' is the repository."
+  (apply 'cons
+         (mapcar (lambda (file)
+                   (quelpa-build--string-rtrim
+                    (quelpa-build--slurp-file (expand-file-name file dir))))
+                 '("CVS/Root" "CVS/Repository"))))
+
+(defun quelpa-build--checkout-cvs (name config dir)
+  "Check package NAME with config CONFIG out of cvs into DIR."
+  (unless quelpa-build-stable
+    (with-current-buffer (get-buffer-create "*quelpa-build-checkout*")
+      (let ((root (quelpa-build--trim (plist-get config :url) ?/))
+            (repo (or (plist-get config :module) (symbol-name name)))
+            (bound (goto-char (point-max)))
+            latest)
+        (cond
+         ((and (file-exists-p (expand-file-name "CVS" dir))
+               (equal (quelpa-build--cvs-repo dir) (cons root repo)))
+          (quelpa-build--princ-exists dir)
+          (quelpa-build--run-process dir "cvs" "update" "-dP"))
+         (t
+          (when (file-exists-p dir)
+            (delete-directory dir t))
+          (quelpa-build--princ-checkout (format "%s from %s" repo root) dir)
+          ;; CVS insists on relative paths as target directory for checkout (for
+          ;; whatever reason), and puts "CVS" directories into every subdirectory
+          ;; of the current working directory given in the target path. To get CVS
+          ;; to just write to DIR, we need to execute CVS from the parent
+          ;; directory of DIR, and specific DIR as relative path.  Hence all the
+          ;; following mucking around with paths.  CVS is really horrid.
+          (let ((dir (directory-file-name dir)))
+            (quelpa-build--run-process (file-name-directory dir)
+                                       "env" "TZ=UTC" "cvs" "-z3"
+                                       "-d" root "checkout"
+                                       "-d" (file-name-nondirectory dir)
+                                       repo))))
+        (apply 'quelpa-build--run-process dir "cvs" "log"
+               (quelpa-build--expand-source-file-list dir config))
+
+        ;; `cvs log` does not provide a way to view the previous N
+        ;; revisions, so instead of parsing the entire log we examine
+        ;; the Entries file, which looks like this:
+        ;;
+        ;; /.cvsignore/1.2/Thu Sep  1 12:42:02 2005//
+        ;; /CHANGES/1.1/Tue Oct  4 11:47:54 2005//
+        ;; /GNUmakefile/1.8/Tue Oct  4 11:47:54 2005//
+        ;; /Makefile/1.14/Tue Oct  4 11:47:54 2005//
+        ;;
+        (insert-file-contents (concat dir "/CVS/Entries"))
+        (setq latest
+              (car
+               (sort
+                (split-string (buffer-substring-no-properties (point) (point-max)) "\n")
+                (lambda (x y)
+                  (when (string-match "^\\/[^\\/]*\\/[^\\/]*\\/\\([^\\/]*\\)\\/\\/$" x)
+                    (setq x (quelpa-build--parse-time (match-string 1 x))))
+                  (when (string-match "^\\/[^\\/]*\\/[^\\/]*\\/\\([^\\/]*\\)\\/\\/$" y)
+                    (setq y (quelpa-build--parse-time (match-string 1 y))))
+                  (version-list-<= (quelpa-build--valid-version y)
+                                   (quelpa-build--valid-version x))))))
+        (when (string-match "^\\/[^\\/]*\\/[^\\/]*\\/\\([^\\/]*\\)\\/\\/$" latest)
+          (setq latest (match-string 1 latest)))
+        (or (quelpa-build--parse-time latest)
+            (error "No valid timestamps found!"))))))
+
+;;;; Git
+
+(defun quelpa-build--git-repo (dir)
+  "Get the current git repo for DIR."
+  (quelpa-build--run-process-match
+   "Fetch URL: \\(.*\\)" dir "git" "remote" "show" "-n" "origin"))
+
+(defun quelpa-build--checkout-git (name config dir)
+  "Check package NAME with config CONFIG out of git into DIR."
+  (let ((repo (plist-get config :url))
+        (commit (or (plist-get config :commit)
+                    (let ((branch (plist-get config :branch)))
+                      (when branch
+                        (concat "origin/" branch))))))
+    (with-current-buffer (get-buffer-create "*quelpa-build-checkout*")
+      (goto-char (point-max))
+      (cond
+       ((and (file-exists-p (expand-file-name ".git" dir))
+             (string-equal (quelpa-build--git-repo dir) repo))
+        (quelpa-build--princ-exists dir)
+        (quelpa-build--run-process dir "git" "fetch" "--all" "--tags"))
+       (t
+        (when (file-exists-p dir)
+          (delete-directory dir t))
+        (quelpa-build--princ-checkout repo dir)
+        (quelpa-build--run-process nil "git" "clone" repo dir)))
+      (if quelpa-build-stable
+          (let* ((min-bound (goto-char (point-max)))
+                 (tag-version
+                  (and (quelpa-build--run-process dir "git" "tag")
+                       (or (quelpa-build--find-version-newest
+                            (or (plist-get config :version-regexp)
+                                quelpa-build-version-regexp)
+                            min-bound)
+                           (error "No valid stable versions found for %s" name)))))
+            ;; Using reset --hard here to comply with what's used for
+            ;; unstable, but maybe this should be a checkout?
+            (quelpa-build--update-git-to-ref
+             dir (concat "tags/" (cadr tag-version)))
+            ;; Return the parsed version as a string
+            (package-version-join (car tag-version)))
+        (quelpa-build--update-git-to-ref
+         dir (or commit (concat "origin/" (quelpa-build--git-head-branch dir))))
+        (apply 'quelpa-build--run-process
+               dir "git" "log" "--first-parent" "-n1" "--pretty=format:'\%ci'"
+               (quelpa-build--expand-source-file-list dir config))
+        (quelpa-build--find-parse-time "\
+\\([0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\} \
+[0-9]\\{2\\}:[0-9]\\{2\\}:[0-9]\\{2\\}\\( [+-][0-9]\\{4\\}\\)?\\)")))))
+
+(defun quelpa-build--git-head-branch (dir)
+  "Get the current git repo for DIR."
+  (or (ignore-errors
+        (quelpa-build--run-process-match
+         "HEAD branch: \\(.*\\)" dir "git" "remote" "show" "origin"))
+      "master"))
+
+(defun quelpa-build--git-head-sha (dir)
+  "Get the current head SHA for DIR."
+  (ignore-errors
+    (quelpa-build--run-process-match
+     "\\(.*\\)" dir "git" "rev-parse" "HEAD")))
+
+(defun quelpa-build--update-git-to-ref (dir ref)
+  "Update the git repo in DIR so that HEAD is REF."
+  (quelpa-build--run-process dir "git" "reset" "--hard" ref)
+  (quelpa-build--run-process dir "git" "submodule" "sync" "--recursive")
+  (quelpa-build--run-process dir "git" "submodule" "update" "--init" "--recursive"))
+
+(defun quelpa-build--checkout-github (name config dir)
+  "Check package NAME with config CONFIG out of github into DIR."
+  (let ((url (format "https://github.com/%s.git" (plist-get config :repo))))
+    (quelpa-build--checkout-git name (plist-put (copy-sequence config) :url url) dir)))
+
+(defun quelpa-build--checkout-gitlab (name config dir)
+  "Check package NAME with config CONFIG out of gitlab into DIR."
+  (let ((url (format "https://gitlab.com/%s.git" (plist-get config :repo))))
+    (quelpa-build--checkout-git name (plist-put (copy-sequence config) :url url) dir)))
+
+;;;; Bzr
+
+(defun quelpa-build--bzr-repo (dir)
+  "Get the current bzr repo for DIR."
+  (quelpa-build--run-process-match "parent branch: \\(.*\\)" dir "bzr" "info"))
+
+(defun quelpa-build--checkout-bzr (name config dir)
+  "Check package NAME with config CONFIG out of bzr into DIR."
+  (let ((repo (quelpa-build--run-process-match
+               "\\(?:branch root\\|repository branch\\): \\(.*\\)"
+               nil "bzr" "info" (plist-get config :url))))
+    (with-current-buffer (get-buffer-create "*quelpa-build-checkout*")
+      (goto-char (point-max))
+      (cond
+       ((and (file-exists-p (expand-file-name ".bzr" dir))
+             (string-equal (quelpa-build--bzr-repo dir) repo))
+        (quelpa-build--princ-exists dir)
+        (quelpa-build--run-process dir "bzr" "merge" "--force"))
+       (t
+        (when (file-exists-p dir)
+          (delete-directory dir t))
+        (quelpa-build--princ-checkout repo dir)
+        (quelpa-build--run-process nil "bzr" "branch" repo dir)))
+      (if quelpa-build-stable
+          (let ((bound (goto-char (point-max)))
+                (regexp (or (plist-get config :version-regexp)
+                            quelpa-build-version-regexp))
+                tag-version)
+            (quelpa-build--run-process dir "bzr" "tags")
+            (goto-char bound)
+            (ignore-errors (while (re-search-forward "\\ +.*")
+                             (replace-match "")))
+            (setq tag-version
+                  (or (quelpa-build--find-version-newest regexp bound)
+                      (error "No valid stable versions found for %s" name)))
+            (quelpa-build--run-process dir
+                                       "bzr" "revert" "-r"
+                                       (concat "tag:" (cadr tag-version)))
+            ;; Return the parsed version as a string
+            (package-version-join (car tag-version)))
+        (apply 'quelpa-build--run-process dir "bzr" "log" "-l1"
+               (quelpa-build--expand-source-file-list dir config))
+        (quelpa-build--find-parse-time "\
+\\([0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\} \
+[0-9]\\{2\\}:[0-9]\\{2\\}:[0-9]\\{2\\}\\( [+-][0-9]\\{4\\}\\)?\\)")))))
+
+;;;; Hg
+
+(defun quelpa-build--hg-repo (dir)
+  "Get the current hg repo for DIR."
+  (quelpa-build--run-process-match "default = \\(.*\\)" dir "hg" "paths"))
+
+(defun quelpa-build--checkout-hg (name config dir)
+  "Check package NAME with config CONFIG out of hg into DIR."
+  (let ((repo (plist-get config :url)))
+    (with-current-buffer (get-buffer-create "*quelpa-build-checkout*")
+      (goto-char (point-max))
+      (cond
+       ((and (file-exists-p (expand-file-name ".hg" dir))
+             (string-equal (quelpa-build--hg-repo dir) repo))
+        (quelpa-build--princ-exists dir)
+        (quelpa-build--run-process dir "hg" "pull")
+        (quelpa-build--run-process dir "hg" "update"))
+       (t
+        (when (file-exists-p dir)
+          (delete-directory dir t))
+        (quelpa-build--princ-checkout repo dir)
+        (quelpa-build--run-process nil "hg" "clone" repo dir)))
+      (if quelpa-build-stable
+          (let ((min-bound (goto-char (point-max)))
+                (regexp (or (plist-get config :version-regexp)
+                            quelpa-build-version-regexp))
+                tag-version)
+            (quelpa-build--run-process dir "hg" "tags")
+            ;; The output of `hg tags` shows the ref of the tag as well
+            ;; as the tag itself, e.g.:
+            ;;
+            ;; tip                             1696:73ad80e8fea1
+            ;; 1.2.8                           1691:464af57fd2b7
+            ;;
+            ;; So here we remove that second column before passing the
+            ;; buffer contents to `quelpa-build--find-version-newest'.
+            ;; This isn't strictly necessary for Mercurial since the
+            ;; colon in "1691:464af57fd2b7" means that won't be parsed
+            ;; as a valid version-string, but it's an example of how to
+            ;; do it in case it's necessary elsewhere.
+            (goto-char min-bound)
+            (ignore-errors (while (re-search-forward "\\ +.*")
+                             (replace-match "")))
+            (setq tag-version
+                  (or (quelpa-build--find-version-newest regexp min-bound)
+                      (error "No valid stable versions found for %s" name)))
+            (quelpa-build--run-process dir "hg" "update" (cadr tag-version))
+            ;; Return the parsed version as a string
+            (package-version-join (car tag-version)))
+        (apply 'quelpa-build--run-process
+               dir "hg" "log" "--style" "compact" "-l1"
+               (quelpa-build--expand-source-file-list dir config))
+        (quelpa-build--find-parse-time "\
+\\([0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\} \
+[0-9]\\{2\\}:[0-9]\\{2\\}\\( [+-][0-9]\\{4\\}\\)?\\)")))))
+
+(defun quelpa-build--checkout-bitbucket (name config dir)
+  "Check package NAME with config CONFIG out of bitbucket into DIR."
+  (let ((url (format "https://bitbucket.com/%s" (plist-get config :repo))))
+    (quelpa-build--checkout-hg name (plist-put (copy-sequence config) :url url) dir)))
+
+;;; Utilities
+
+(defun quelpa-build--dump (data file &optional pretty-print)
+  "Write DATA to FILE as a Lisp sexp.
+Optionally PRETTY-PRINT the data."
+  (with-temp-file file
+    (quelpa-build--message "File: %s" file)
+    (if pretty-print
+        (pp data (current-buffer))
+      (print data (current-buffer)))))
+
+(defun quelpa-build--write-pkg-file (pkg-file pkg-info)
+  "Write PKG-FILE containing PKG-INFO."
+  (with-temp-file pkg-file
+    (pp
+     `(define-package
+        ,(aref pkg-info 0)
+        ,(aref pkg-info 3)
+        ,(aref pkg-info 2)
+        ',(mapcar
+           (lambda (elt)
+             (list (car elt)
+                   (package-version-join (cadr elt))))
+           (aref pkg-info 1))
+        ;; Append our extra information
+        ,@(cl-mapcan (lambda (entry)
+                       (let ((value (cdr entry)))
+                         (when (or (symbolp value) (listp value))
+                           ;; We must quote lists and symbols,
+                           ;; because Emacs 24.3 and earlier evaluate
+                           ;; the package information, which would
+                           ;; break for unquoted symbols or lists
+                           (setq value (list 'quote value)))
+                         (list (car entry) value)))
+                     (when (> (length pkg-info) 4)
+                       (aref pkg-info 4))))
+     (current-buffer))
+    (princ ";; Local Variables:\n;; no-byte-compile: t\n;; End:\n"
+           (current-buffer))))
+
+(defun quelpa-build--read-from-file (file)
+  "Read and return the Lisp data stored in FILE, or nil if no such file exists."
+  (when (file-exists-p file)
+    (car (read-from-string (quelpa-build--slurp-file file)))))
+
+(defun quelpa-build--stage-files (pkg-label dir &optional files)
+  "Either return DIR or copy FILES into PKG-LABEL and return that"
+  (let* ((staging-dir (if files
+                          (make-temp-file "quelpa-build--stage-files" t)
+                        dir))
+         (default-directory staging-dir))
+    (when files
+      (mkdir pkg-label)
+      (setq staging-dir (file-name-as-directory (expand-file-name pkg-label default-directory)))
+      (mapc (lambda (fn)
+              "Copy FN into STAGING-DIR"
+              (let (fname (file-truename fn))
+                (copy-file fname staging-dir)))
+            files))
+    staging-dir))
+
+(defun quelpa-build--create-tar (file dir &optional files)
+  "Create a tar FILE containing the contents of DIR, or just FILES if non-nil."
+  (let* ((pkg-label (file-name-base file))
+         (dest-dir (file-name-directory (file-truename file)))
+         (dest-filename (file-name-nondirectory (file-truename file)))
+         (src-dir (file-relative-name (quelpa-build--stage-files pkg-label dir files) dest-dir))
+         (src-parent (file-relative-name (file-name-directory (directory-file-name src-dir))))
+         (default-directory dest-dir)
+         (result (apply 'process-file
+                        quelpa-build-tar-executable nil
+                        (get-buffer-create "*quelpa-build-checkout*")
+                        nil
+                        (concat "--directory=" src-parent)
+                        "-cvf"
+                        dest-filename
+                        "--exclude=.svn"
+                        "--exclude=CVS"
+                        "--exclude=.git"
+                        "--exclude=_darcs"
+                        "--exclude=.fslckout"
+                        "--exclude=_FOSSIL_"
+                        "--exclude=.bzr"
+                        "--exclude=.hg"
+                        (list (file-relative-name src-dir src-parent)))))
+    (cond ((eq result 1)
+           (display-warning 'quelpa
+                            (format "%s exited with return value 1: some files were changed while being archived."
+                                    quelpa-build-tar-executable))
+           result)
+          ((eq result 2)
+           (error "%s exited with return value 2: A fatal, unrecoverable error has occurred"
+                  quelpa-build-tar-executable))
+          ((eq result 0)
+           result)
+          ((t (error "Unknown return value %s" result))))))
+
+(defun quelpa-build--find-package-commentary (file-path)
+  "Get commentary section from FILE-PATH."
+  (when (file-exists-p file-path)
+    (with-temp-buffer
+      (insert-file-contents file-path)
+      (lm-commentary))))
+
+(defun quelpa-build--write-pkg-readme (target-dir commentary file-name)
+  "In TARGET-DIR, write COMMENTARY to a -readme.txt file prefixed with FILE-NAME."
+  (when commentary
+    (with-temp-buffer
+      (insert commentary)
+      ;; Adapted from `describe-package-1'.
+      (goto-char (point-min))
+      (save-excursion
+        (when (re-search-forward "^;;; Commentary:\n" nil t)
+          (replace-match ""))
+        (while (re-search-forward "^\\(;+ ?\\)" nil t)
+          (replace-match ""))
+        (goto-char (point-min))
+        (when (re-search-forward "\\`\\( *\n\\)+" nil t)
+          (replace-match "")))
+      (delete-trailing-whitespace)
+      (let ((coding-system-for-write buffer-file-coding-system))
+        (write-region nil nil
+                      (quelpa-build--readme-file-name target-dir file-name))))))
+
+(defun quelpa-build--readme-file-name (target-dir file-name)
+  "Name of the readme file in TARGET-DIR for the package FILE-NAME."
+  (expand-file-name (concat file-name "-readme.txt")
+                    target-dir))
+
+(defun quelpa-build--update-or-insert-version (version)
+  "Ensure current buffer has a \"Package-Version: VERSION\" header."
+  (goto-char (point-min))
+  (if (let ((case-fold-search t))
+        (re-search-forward "^;+* *Package-Version *: *" nil t))
+      (progn
+        (move-beginning-of-line nil)
+        (search-forward "V" nil t)
+        (backward-char)
+        (insert "X-Original-")
+        (move-beginning-of-line nil))
+    ;; Put the new header in a sensible place if we can
+    (re-search-forward "^;+* *\\(Version\\|Package-Requires\\|Keywords\\|URL\\) *:"
+                       nil t)
+    (forward-line))
+  (insert (format ";; Package-Version: %s" version))
+  (newline))
+
+(defun quelpa-build--ensure-ends-here-line (file-path)
+  "Add a 'FILE-PATH ends here' trailing line if missing."
+  (save-excursion
+    (goto-char (point-min))
+    (let ((trailer (concat ";;; "
+                           (file-name-nondirectory file-path)
+                           " ends here")))
+      (unless (search-forward trailer nil t)
+        (goto-char (point-max))
+        (newline)
+        (insert trailer)
+        (newline)))))
+
+(defun quelpa-build--get-package-info (file-path)
+  "Get a vector of package info from the docstrings in FILE-PATH."
+  (when (file-exists-p file-path)
+    (ignore-errors
+      (with-temp-buffer
+        (insert-file-contents file-path)
+        ;; next few lines are a hack for some packages that aren't
+        ;; commented properly.
+        (quelpa-build--update-or-insert-version "0")
+        (quelpa-build--ensure-ends-here-line file-path)
+        (cl-flet ((package-strip-rcs-id (str) "0"))
+          (quelpa-build--package-buffer-info-vec))))))
+
+(defun quelpa-build--get-pkg-file-info (file-path)
+  "Get a vector of package info from \"-pkg.el\" file FILE-PATH."
+  (when (file-exists-p file-path)
+    (let ((package-def (quelpa-build--read-from-file file-path)))
+      (if (eq 'define-package (car package-def))
+          (let* ((pkgfile-info (cdr package-def))
+                 (descr (nth 2 pkgfile-info))
+                 (rest-plist (cl-subseq pkgfile-info (min 4 (length pkgfile-info))))
+                 (extras (let (alist)
+                           (while rest-plist
+                             (unless (memq (car rest-plist) '(:kind :archive))
+                               (let ((value (cadr rest-plist)))
+                                 (when value
+                                   (push (cons (car rest-plist)
+                                               (if (eq (car-safe value) 'quote)
+                                                   (cadr value)
+                                                 value))
+                                         alist))))
+                             (setq rest-plist (cddr rest-plist)))
+                           alist)))
+            (when (string-match "[\r\n]" descr)
+              (error "Illegal multi-line package description in %s" file-path))
+            (vector
+             (nth 0 pkgfile-info)
+             (mapcar
+              (lambda (elt)
+                (unless (symbolp (car elt))
+                  (error "Invalid package name in dependency: %S" (car elt)))
+                (list (car elt) (version-to-list (cadr elt))))
+              (eval (nth 3 pkgfile-info)))
+             descr
+             (nth 1 pkgfile-info)
+             extras))
+        (error "No define-package found in %s" file-path)))))
+
+(defun quelpa-build--merge-package-info (pkg-info name version)
+  "Return a version of PKG-INFO updated with NAME, VERSION and info from CONFIG.
+If PKG-INFO is nil, an empty one is created."
+  (let ((merged (or (copy-sequence pkg-info)
+                    (vector name nil "No description available." version))))
+    (aset merged 0 name)
+    (aset merged 3 version)
+    merged))
+
+(defun quelpa-build--archive-entry (pkg-info type)
+  "Return the archive-contents cons cell for PKG-INFO and TYPE."
+  (let ((name (intern (aref pkg-info 0)))
+        (requires (aref pkg-info 1))
+        (desc (or (aref pkg-info 2) "No description available."))
+        (version (aref pkg-info 3))
+        (extras (and (> (length pkg-info) 4)
+                     (aref pkg-info 4))))
+    (cons name
+          (vector (version-to-list version)
+                  requires
+                  desc
+                  type
+                  extras))))
+
+;;; Recipes
+
+(defun quelpa-build-expand-file-specs (dir specs &optional subdir allow-empty)
+  "In DIR, expand SPECS, optionally under SUBDIR.
+The result is a list of (SOURCE . DEST), where SOURCE is a source
+file path and DEST is the relative path to which it should be copied.
+
+If the resulting list is empty, an error will be reported.  Pass t
+for ALLOW-EMPTY to prevent this error."
+  (let ((default-directory dir)
+        (prefix (if subdir (format "%s/" subdir) ""))
+        (lst))
+    (dolist (entry specs lst)
+      (setq lst
+            (if (consp entry)
+                (if (eq :exclude (car entry))
+                    (cl-nset-difference lst
+                                        (quelpa-build-expand-file-specs
+                                         dir (cdr entry) nil t)
+                                        :key 'car
+                                        :test 'equal)
+                  (nconc lst
+                         (quelpa-build-expand-file-specs
+                          dir
+                          (cdr entry)
+                          (concat prefix (car entry))
+                          t)))
+              (nconc
+               lst (mapcar (lambda (f)
+                             (let ((destname)))
+                             (cons f
+                                   (concat prefix
+                                           (replace-regexp-in-string
+                                            "\\.in\\'"
+                                            ""
+                                            (file-name-nondirectory f)))))
+                           (file-expand-wildcards entry))))))
+    (when (and (null lst) (not allow-empty))
+      (error "No matching file(s) found in %s: %s" dir specs))
+    lst))
+
+(defun quelpa-build--config-file-list (config)
+  "Get the :files spec from CONFIG, or return `quelpa-build-default-files-spec'."
+  (let ((file-list (plist-get config :files)))
+    (cond
+     ((null file-list)
+      quelpa-build-default-files-spec)
+     ((eq :defaults (car file-list))
+      (append quelpa-build-default-files-spec (cdr file-list)))
+     (t
+      file-list))))
+
+(defun quelpa-build--expand-source-file-list (dir config)
+  "Shorthand way to expand paths in DIR for source files listed in CONFIG."
+  (mapcar 'car
+          (quelpa-build-expand-file-specs
+           dir (quelpa-build--config-file-list config))))
+
+(defun quelpa-build--generate-info-files (files source-dir target-dir)
+  "Create .info files from any .texi files listed in FILES.
+
+The source and destination file paths are expanded in SOURCE-DIR
+and TARGET-DIR respectively.
+
+Any of the original .texi(nfo) files found in TARGET-DIR are
+deleted."
+  (dolist (spec files)
+    (let* ((source-file (car spec))
+           (source-path (expand-file-name source-file source-dir))
+           (dest-file (cdr spec))
+           (info-path (expand-file-name
+                       (concat (file-name-sans-extension dest-file) ".info")
+                       target-dir)))
+      (when (string-match ".texi\\(nfo\\)?$" source-file)
+        (when (not (file-exists-p info-path))
+          (with-current-buffer (get-buffer-create "*quelpa-build-info*")
+            (ignore-errors
+              (quelpa-build--run-process
+               (file-name-directory source-path)
+               "makeinfo"
+               source-path
+               "-o"
+               info-path)
+              (quelpa-build--message "Created %s" info-path))))
+        (quelpa-build--message "Removing %s"
+                               (expand-file-name dest-file target-dir))
+        (delete-file (expand-file-name dest-file target-dir))))))
+
+;;; Info Manuals
+
+(defun quelpa-build--generate-dir-file (files target-dir)
+  "Create dir file from any .info files listed in FILES in TARGET-DIR."
+  (dolist (spec files)
+    (let* ((source-file (car spec))
+           (dest-file (cdr spec))
+           (info-path (expand-file-name
+                       (concat (file-name-sans-extension dest-file) ".info")
+                       target-dir)))
+      (when (and (or (string-match ".info$" source-file)
+                     (string-match ".texi\\(nfo\\)?$" source-file))
+                 (file-exists-p info-path))
+        (with-current-buffer (get-buffer-create "*quelpa-build-info*")
+          (ignore-errors
+            (quelpa-build--run-process
+             nil
+             "install-info"
+             (concat "--dir=" (expand-file-name "dir" target-dir))
+             info-path)))))))
+
+;;; Utilities
+
+(defun quelpa-build--copy-package-files (files source-dir target-dir)
+  "Copy FILES from SOURCE-DIR to TARGET-DIR.
+FILES is a list of (SOURCE . DEST) relative filepath pairs."
+  (cl-loop for (source-file . dest-file) in files
+           do (quelpa-build--copy-file
+               (expand-file-name source-file source-dir)
+               (expand-file-name dest-file target-dir))))
+
+(defun quelpa-build--copy-file (file newname)
+  "Copy FILE to NEWNAME and create parent directories for NEWNAME if they don't exist."
+  (let ((newdir (file-name-directory newname)))
+    (unless (file-exists-p newdir)
+      (make-directory newdir t)))
+  (cond
+   ((file-regular-p file)
+    (quelpa-build--message "%s -> %s" file newname)
+    (copy-file file newname))
+   ((file-directory-p file)
+    (quelpa-build--message "%s => %s" file newname)
+    (copy-directory file newname))))
+
+(defun quelpa-build--find-source-file (target files)
+  "Search for source of TARGET in FILES."
+  (car (rassoc target files)))
+
+(defun quelpa-build--package-buffer-info-vec ()
+  "Return a vector of package info.
+`package-buffer-info' returns a vector in older Emacs versions,
+and a cl struct in Emacs HEAD.  This wrapper normalises the results."
+  (let ((desc (package-buffer-info))
+        (keywords (lm-keywords-list)))
+    (if (fboundp 'package-desc-create)
+        (let ((extras (package-desc-extras desc)))
+          (when (and keywords (not (assq :keywords extras)))
+            ;; Add keywords to package properties, if not already present
+            (push (cons :keywords keywords) extras))
+          (vector (package-desc-name desc)
+                  (package-desc-reqs desc)
+                  (package-desc-summary desc)
+                  (package-desc-version desc)
+                  extras))
+      ;; The regexp and the processing is taken from `lm-homepage' in Emacs 24.4
+      (let* ((page (lm-header "\\(?:x-\\)?\\(?:homepage\\|url\\)"))
+             (homepage (if (and page (string-match "^<.+>$" page))
+                           (substring page 1 -1)
+                         page))
+             extras)
+        (when keywords (push (cons :keywords keywords) extras))
+        (when homepage (push (cons :url homepage) extras))
+        (vector  (aref desc 0)
+                 (aref desc 1)
+                 (aref desc 2)
+                 (aref desc 3)
+                 extras)))))
+
+;;; Building
+
+;;;###autoload
+(defun quelpa-build-package (package-name version file-specs source-dir target-dir)
+  "Create PACKAGE-NAME with VERSION.
+
+The information in FILE-SPECS is used to gather files from
+SOURCE-DIR.
+
+The resulting package will be stored as a .el or .tar file in
+TARGET-DIR, depending on whether there are multiple files.
+
+Argument FILE-SPECS is a list of specs for source files, which
+should be relative to SOURCE-DIR.  The specs can be wildcards,
+and optionally specify different target paths.  They extended
+syntax is currently only documented in the MELPA README.  You can
+simply pass `quelpa-build-default-files-spec' in most cases.
+
+Returns the archive entry for the package."
+  (when (symbolp package-name)
+    (setq package-name (symbol-name package-name)))
+  (let ((files (quelpa-build-expand-file-specs source-dir file-specs)))
+    (unless (equal file-specs quelpa-build-default-files-spec)
+      (when (equal files (quelpa-build-expand-file-specs
+                          source-dir quelpa-build-default-files-spec nil t))
+        (quelpa-build--message "Note: %s :files spec is equivalent to the default."
+                               package-name)))
+    (cond
+     ((not version)
+      (error "Unable to check out repository for %s" package-name))
+     ((= 1 (length files))
+      (quelpa-build--build-single-file-package
+       package-name version (caar files) source-dir target-dir))
+     ((< 1 (length  files))
+      (quelpa-build--build-multi-file-package
+       package-name version files source-dir target-dir))
+     (t (error "Unable to find files matching recipe patterns")))))
+
+(defun quelpa-build--build-single-file-package
+    (package-name version file source-dir target-dir)
+  (let* ((pkg-source (expand-file-name file source-dir))
+         (pkg-target (expand-file-name
+                      (concat package-name "-" version ".el")
+                      target-dir))
+         (pkg-info (quelpa-build--merge-package-info
+                    (quelpa-build--get-package-info pkg-source)
+                    package-name
+                    version)))
+    (unless (string-equal (downcase (concat package-name ".el"))
+                          (downcase (file-name-nondirectory pkg-source)))
+      (error "Single file %s does not match package name %s"
+             (file-name-nondirectory pkg-source) package-name))
+    (if (file-exists-p pkg-target)
+        (quelpa-build--message "Skipping rebuild of %s" pkg-target)
+      (copy-file pkg-source pkg-target)
+      (let ((enable-local-variables nil)
+            (make-backup-files nil))
+        (with-temp-buffer
+          (insert-file-contents pkg-target)
+          (quelpa-build--update-or-insert-version version)
+          (quelpa-build--ensure-ends-here-line pkg-source)
+          (write-file pkg-target nil)
+          (condition-case err
+              (quelpa-build--package-buffer-info-vec)
+            (error
+             (quelpa-build--message "Warning: %S" err)))))
+
+      (quelpa-build--write-pkg-readme
+       target-dir
+       (quelpa-build--find-package-commentary pkg-source)
+       package-name))
+    (quelpa-build--archive-entry pkg-info 'single)))
+
+(defun quelpa-build--build-multi-file-package
+    (package-name version files source-dir target-dir)
+  (let ((tmp-dir (file-name-as-directory (make-temp-file package-name t))))
+    (unwind-protect
+        (let* ((pkg-dir-name (concat package-name "-" version))
+               (pkg-tmp-dir (expand-file-name pkg-dir-name tmp-dir))
+               (pkg-file (concat package-name "-pkg.el"))
+               (pkg-file-source (or (quelpa-build--find-source-file pkg-file files)
+                                    pkg-file))
+               (file-source (concat package-name ".el"))
+               (pkg-source (or (quelpa-build--find-source-file file-source files)
+                               file-source))
+               (pkg-info (quelpa-build--merge-package-info
+                          (let ((default-directory source-dir))
+                            (or (quelpa-build--get-pkg-file-info pkg-file-source)
+                                ;; some packages (like magit) provide name-pkg.el.in
+                                (quelpa-build--get-pkg-file-info
+                                 (expand-file-name (concat pkg-file ".in")
+                                                   (file-name-directory pkg-source)))
+                                (quelpa-build--get-package-info pkg-source)))
+                          package-name
+                          version)))
+          (quelpa-build--copy-package-files files source-dir pkg-tmp-dir)
+          (quelpa-build--write-pkg-file (expand-file-name
+                                         pkg-file
+                                         (file-name-as-directory pkg-tmp-dir))
+                                        pkg-info)
+
+          (quelpa-build--generate-info-files files source-dir pkg-tmp-dir)
+          (quelpa-build--generate-dir-file files pkg-tmp-dir)
+
+          (let ((default-directory tmp-dir))
+            (quelpa-build--create-tar
+             (expand-file-name (concat package-name "-" version ".tar")
+                               target-dir)
+             pkg-dir-name))
+
+          (let ((default-directory source-dir))
+            (quelpa-build--write-pkg-readme
+             target-dir
+             (quelpa-build--find-package-commentary pkg-source)
+             package-name))
+          (quelpa-build--archive-entry pkg-info 'tar))
+      (delete-directory tmp-dir t nil))))
+
+(defun quelpa-build--checkout-file (name config dir)
+  "Build according to a PATH with config CONFIG into DIR as NAME.
+Generic local file handler for package-build.el.
+
+Handles the following cases:
+
+local file:
+
+Installs a single-file package from a local file.  Use the :path
+attribute with a PATH like \"/path/to/file.el\".
+
+local directory:
+
+Installs a multi-file package from a local directory.  Use
+the :path attribute with a PATH like \"/path/to/dir\"."
+  (quelpa-check-hash name config (expand-file-name (plist-get config :path)) dir))
+
+(defun quelpa-build--checkout-url (name config dir)
+  "Build according to an URL with config CONFIG into DIR as NAME.
+Generic URL handler for package-build.el.
+
+Handles the following cases:
+
+local file:
+
+Installs a single-file package from a local file.  Use the :url
+attribute with an URL like \"file:///path/to/file.el\".
+
+remote file:
+
+Installs a single-file package from a remote file.  Use the :url
+attribute with an URL like \"http://domain.tld/path/to/file.el\"."
+  (let* ((url (plist-get config :url))
+         (remote-file-name (file-name-nondirectory
+                            (url-filename (url-generic-parse-url url))))
+         (local-path (expand-file-name remote-file-name dir))
+         (mm-attachment-file-modes (default-file-modes)))
+    (unless (string= (file-name-extension url) "el")
+      (error "<%s> does not end in .el" url))
+    (unless (file-directory-p dir)
+      (make-directory dir))
+    (url-copy-file url local-path t)
+    (quelpa-check-hash name config local-path dir 'url)))
+
+;; --- helpers ---------------------------------------------------------------
+
+(defun quelpa-message (wait format-string &rest args)
+  "Log a message with FORMAT-STRING and ARGS when `quelpa-verbose' is non-nil.
+If WAIT is nil don't wait after showing the message. If it is a
+number, wait so many seconds. If WAIT is t wait the default time.
+Return t in each case."
+  (when quelpa-verbose
+    (message "Quelpa: %s" (apply 'format format-string args))
+    (when (or (not noninteractive) wait) ; no wait if emacs is noninteractive
+      (sit-for (or (and (numberp wait) wait) 1.5) t)))
+  t)
+
+(defun quelpa-read-cache ()
+  "Read from `quelpa-persistent-cache-file' in `quelpa-cache'."
+  (when (and quelpa-persistent-cache-p
+             (file-exists-p quelpa-persistent-cache-file))
+    (with-temp-buffer
+      (insert-file-contents-literally quelpa-persistent-cache-file)
+      (setq quelpa-cache
+            (read (buffer-substring-no-properties (point-min) (point-max)))))))
+
+(defun quelpa-save-cache ()
+  "Write `quelpa-cache' to `quelpa-persistent-cache-file'."
+  (when quelpa-persistent-cache-p
+    (let (print-level print-length)
+      (with-temp-file quelpa-persistent-cache-file
+        (insert (prin1-to-string quelpa-cache))))))
+
+(defun quelpa-update-cache (cache-item)
+  ;; try removing existing recipes by name
+  (setq quelpa-cache (cl-remove (car cache-item)
+                                quelpa-cache :key #'car))
+  (push cache-item quelpa-cache)
+  (setq quelpa-cache
+        (cl-sort quelpa-cache #'string<
+                 :key (lambda (item) (symbol-name (car item))))))
+
+(defun quelpa-parse-stable (cache-item)
+  ;; in case :stable doesn't originate from PLIST, shadow the
+  ;; default value anyways
+  (when (plist-member (cdr cache-item) :stable)
+    (setq quelpa-stable-p (plist-get (cdr cache-item) :stable)))
+  (when (and quelpa-stable-p (not (plist-get (cdr cache-item) :stable)))
+    (setf (cdr (last cache-item)) '(:stable t))))
+
+(defun quelpa-checkout-melpa ()
+  "Fetch or update the melpa source code from Github.
+If there is no error return non-nil.
+If there is an error but melpa is already checked out return non-nil.
+If there is an error and no existing checkout return nil."
+  (or (and (null quelpa-update-melpa-p)
+           (file-exists-p (expand-file-name ".git" quelpa-melpa-dir)))
+      (condition-case err
+          (quelpa-build--checkout-git
+           'package-build
+           `(:url ,quelpa-melpa-repo-url :files ("*"))
+           quelpa-melpa-dir)
+        (error "failed to checkout melpa git repo: `%s'" (error-message-string err)))))
+
+(defun quelpa-get-melpa-recipe (name)
+  "Read recipe with NAME for melpa git checkout.
+Return the recipe if it exists, otherwise nil."
+  (cl-loop for store in quelpa-melpa-recipe-stores
+           if (stringp store)
+           for file = (assoc-string name (directory-files store nil "^[^\.]+"))
+           when file
+           return (with-temp-buffer
+                    (insert-file-contents-literally
+                     (expand-file-name file store))
+                    (read (buffer-string)))
+           else
+           for rcp = (assoc-string name store)
+           when rcp
+           return rcp))
+
+(defun quelpa-setup-p ()
+  "Setup what we need for quelpa.
+Return non-nil if quelpa has been initialized properly."
+  (catch 'quit
+    (dolist (dir (list quelpa-packages-dir quelpa-build-dir))
+      (unless (file-exists-p dir) (make-directory dir t)))
+    (unless quelpa-initialized-p
+      (quelpa-read-cache)
+      (quelpa-setup-package-structs)
+      (if quelpa-checkout-melpa-p
+          (unless (quelpa-checkout-melpa) (throw 'quit nil)))
+      (setq quelpa-initialized-p t))
+    t))
+
+(defun quelpa-shutdown ()
+  "Do things that need to be done after running quelpa."
+  (quelpa-save-cache)
+  ;; remove the packages dir because we are done with the built pkgs
+  (ignore-errors (delete-directory quelpa-packages-dir t)))
+
+(defun quelpa-arg-rcp (arg)
+  "Given recipe or package name, return an alist '(NAME . RCP).
+If RCP cannot be found it will be set to nil"
+  (pcase arg
+    (`(,a . nil) (quelpa-get-melpa-recipe (car arg)))
+    (`(,a . ,_) arg)
+    ((pred symbolp) (quelpa-get-melpa-recipe arg))))
+
+(defun quelpa-parse-plist (plist)
+  "Parse the optional PLIST argument of `quelpa'.
+Recognized keywords are:
+
+:upgrade
+
+If t, `quelpa' tries to do an upgrade.
+
+:stable
+
+If t, `quelpa' tries building the stable version of a package."
+  (while plist
+    (let ((key (car plist))
+          (value (cadr plist)))
+      (pcase key
+        (:upgrade (setq quelpa-upgrade-p value))
+        (:stable (setq quelpa-stable-p value))))
+    (setq plist (cddr plist))))
+
+(defun quelpa-package-install-file (file)
+  "Workaround problem with `package-install-file'.
+`package-install-file' uses `insert-file-contents-literally'
+which causes problems when the file inserted has crlf line
+endings (Windows). So here we replace that with
+`insert-file-contents' for non-tar files."
+  (if (eq system-type 'windows-nt)
+      (cl-letf* ((insert-file-contents-literally-orig
+                  (symbol-function 'insert-file-contents-literally))
+                 ((symbol-function 'insert-file-contents-literally)
+                  (lambda (file)
+                    (if (string-match "\\.tar\\'" file)
+                        (funcall insert-file-contents-literally-orig file)
+                      (insert-file-contents file)))))
+        (package-install-file file))
+    (package-install-file file)))
+
+(defun quelpa-package-install (arg)
+  "Build and install package from ARG (a recipe or package name).
+If the package has dependencies recursively call this function to
+install them."
+  (let* ((rcp (quelpa-arg-rcp arg))
+         (file (and rcp (quelpa-build rcp))))
+    (when file
+      (let* ((pkg-desc (quelpa-get-package-desc file))
+             (requires (package-desc-reqs pkg-desc)))
+        (when requires
+          (mapc (lambda (req)
+                  (unless (or (equal 'emacs (car req))
+                              (package-installed-p (car req) (cadr req)))
+                    (quelpa-package-install (car req))))
+                requires))
+        (quelpa-package-install-file file)))))
+
+(defun quelpa-interactive-candidate ()
+  "Query the user for a recipe and return the name."
+  (when (quelpa-setup-p)
+    (let  ((recipes (cl-loop
+                     for store in quelpa-melpa-recipe-stores
+                     if (stringp store)
+                     ;; this regexp matches all files except dotfiles
+                     append (directory-files store nil "^[^.].+$")
+                     else if (listp store)
+                     append store)))
+      (intern (completing-read "Choose MELPA recipe: "
+                               recipes nil t)))))
+
+;; --- public interface ------------------------------------------------------
+
+;;;###autoload
+(defun quelpa-expand-recipe (recipe-name)
+  "Expand a given recipe name into full recipe.
+If called interactively, let the user choose a recipe name and
+insert the result into the current buffer."
+  (interactive (list (quelpa-interactive-candidate)))
+  (when (quelpa-setup-p)
+    (let* ((recipe (quelpa-get-melpa-recipe recipe-name)))
+      (when recipe
+        (if (called-interactively-p 'any)
+            (prin1 recipe (current-buffer)))
+        recipe))))
+
+;;;###autoload
+(defun quelpa-self-upgrade (&optional args)
+  "Upgrade quelpa itself.
+ARGS are additional options for the quelpa recipe."
+  (interactive)
+  (when (quelpa-setup-p)
+    (quelpa (append quelpa-recipe args) :upgrade t)))
+
+;;;###autoload
+(defun quelpa-upgrade ()
+  "Upgrade all packages found in `quelpa-cache'.
+This provides an easy way to upgrade all the packages for which
+the `quelpa' command has been run in the current Emacs session."
+  (interactive)
+  (when (quelpa-setup-p)
+    (let ((quelpa-upgrade-p t))
+      (when quelpa-self-upgrade-p
+        (quelpa-self-upgrade))
+      (setq quelpa-cache
+            (cl-remove-if-not #'package-installed-p quelpa-cache :key #'car))
+      (mapc (lambda (item)
+              (when (package-installed-p (car (quelpa-arg-rcp item)))
+                (quelpa item)))
+            quelpa-cache))))
+
+;;;###autoload
+(defun quelpa (arg &rest plist)
+  "Build and install a package with quelpa.
+ARG can be a package name (symbol) or a melpa recipe (list).
+PLIST is a plist that may modify the build and/or fetch process.
+If called interactively, `quelpa' will prompt for a MELPA package
+to install.
+
+When `quelpa' is called interactively with a prefix argument (e.g
+C-u M-x quelpa) it will try to upgrade the given package even if
+the global var `quelpa-upgrade-p' is set to nil."
+
+  (interactive (list (quelpa-interactive-candidate)))
+  (run-hooks 'quelpa-before-hook)
+  (when (quelpa-setup-p) ;if init fails we do nothing
+    (let* ((quelpa-upgrade-p (if current-prefix-arg t quelpa-upgrade-p)) ;shadow `quelpa-upgrade-p'
+           (quelpa-stable-p quelpa-stable-p) ;shadow `quelpa-stable-p'
+           (cache-item (if (symbolp arg) (list arg) arg)))
+      (quelpa-parse-plist plist)
+      (quelpa-parse-stable cache-item)
+      (quelpa-package-install arg)
+      (quelpa-update-cache cache-item)))
+  (quelpa-shutdown)
+  (run-hooks 'quelpa-after-hook))
+
+(provide 'quelpa)
+
+;;; quelpa.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/quelpa-20180903.1313/quelpa.elc b/configs/shared/emacs/.emacs.d/elpa/quelpa-20180903.1313/quelpa.elc
new file mode 100644
index 0000000000..d7cf2c91aa
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/quelpa-20180903.1313/quelpa.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/quelpa-20180907.1832/bootstrap.el b/configs/shared/emacs/.emacs.d/elpa/quelpa-20180907.1832/bootstrap.el
new file mode 100644
index 0000000000..1e41c6577d
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/quelpa-20180907.1832/bootstrap.el
@@ -0,0 +1,32 @@
+;;; bootstrap.el --- Bootstrap quelpa.el
+
+;; Copyright 2014-2018, Steckerhalter
+
+;; Author: steckerhalter
+;; URL: https://framagit.org/steckerhalter/quelpa
+;; Version: 0.0.1
+;; License: https://framagit.org/steckerhalter/quelpa/LICENSE
+
+;; This file is not part of GNU Emacs.
+
+;;; Code:
+
+(require 'package)
+
+(defvar quelpa-ci-dir nil
+  "If non-nil, quelpa will not be loaded from the url but from the given dir.")
+
+;; `package' has to be initialized to install pkgs
+(package-initialize)
+
+(let ((temp-dir (make-temp-file "quelpa" t)))
+  (unless (require 'quelpa nil t)
+    (let ((file (or (when quelpa-ci-dir (concat quelpa-ci-dir "/quelpa.el"))
+                    (expand-file-name "quelpa.el" temp-dir))))
+      (unless quelpa-ci-dir
+        (url-copy-file "https://framagit.org/steckerhalter/quelpa/raw/master/quelpa.el" file t))
+      (package-install-file file)))
+
+  (delete-directory temp-dir t))
+
+;;; bootstrap.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/quelpa-20180907.1832/bootstrap.elc b/configs/shared/emacs/.emacs.d/elpa/quelpa-20180907.1832/bootstrap.elc
new file mode 100644
index 0000000000..9bef20457b
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/quelpa-20180907.1832/bootstrap.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/quelpa-20180907.1832/quelpa-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/quelpa-20180907.1832/quelpa-autoloads.el
new file mode 100644
index 0000000000..97dfe80aa1
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/quelpa-20180907.1832/quelpa-autoloads.el
@@ -0,0 +1,73 @@
+;;; quelpa-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "quelpa" "quelpa.el" (23445 50194 257845 416000))
+;;; Generated autoloads from quelpa.el
+
+(autoload 'quelpa-build-package "quelpa" "\
+Create PACKAGE-NAME with VERSION.
+
+The information in FILE-SPECS is used to gather files from
+SOURCE-DIR.
+
+The resulting package will be stored as a .el or .tar file in
+TARGET-DIR, depending on whether there are multiple files.
+
+Argument FILE-SPECS is a list of specs for source files, which
+should be relative to SOURCE-DIR.  The specs can be wildcards,
+and optionally specify different target paths.  They extended
+syntax is currently only documented in the MELPA README.  You can
+simply pass `quelpa-build-default-files-spec' in most cases.
+
+Returns the archive entry for the package.
+
+\(fn PACKAGE-NAME VERSION FILE-SPECS SOURCE-DIR TARGET-DIR)" nil nil)
+
+(autoload 'quelpa-expand-recipe "quelpa" "\
+Expand a given recipe name into full recipe.
+If called interactively, let the user choose a recipe name and
+insert the result into the current buffer.
+
+\(fn RECIPE-NAME)" t nil)
+
+(autoload 'quelpa-self-upgrade "quelpa" "\
+Upgrade quelpa itself.
+ARGS are additional options for the quelpa recipe.
+
+\(fn &optional ARGS)" t nil)
+
+(autoload 'quelpa-upgrade "quelpa" "\
+Upgrade all packages found in `quelpa-cache'.
+This provides an easy way to upgrade all the packages for which
+the `quelpa' command has been run in the current Emacs session.
+
+\(fn)" t nil)
+
+(autoload 'quelpa "quelpa" "\
+Build and install a package with quelpa.
+ARG can be a package name (symbol) or a melpa recipe (list).
+PLIST is a plist that may modify the build and/or fetch process.
+If called interactively, `quelpa' will prompt for a MELPA package
+to install.
+
+When `quelpa' is called interactively with a prefix argument (e.g
+C-u M-x quelpa) it will try to upgrade the given package even if
+the global var `quelpa-upgrade-p' is set to nil.
+
+\(fn ARG &rest PLIST)" t nil)
+
+;;;***
+
+;;;### (autoloads nil nil ("bootstrap.el" "quelpa-pkg.el") (23445
+;;;;;;  50194 261274 12000))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; quelpa-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/quelpa-20180907.1832/quelpa-pkg.el b/configs/shared/emacs/.emacs.d/elpa/quelpa-20180907.1832/quelpa-pkg.el
new file mode 100644
index 0000000000..30063d38a9
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/quelpa-20180907.1832/quelpa-pkg.el
@@ -0,0 +1,12 @@
+(define-package "quelpa" "20180907.1832" "Emacs Lisp packages built directly from source"
+  '((emacs "24.3"))
+  :keywords
+  '("package" "management" "build" "source" "elpa")
+  :authors
+  '(("steckerhalter"))
+  :maintainer
+  '("steckerhalter")
+  :url "https://framagit.org/steckerhalter/quelpa")
+;; Local Variables:
+;; no-byte-compile: t
+;; End:
diff --git a/configs/shared/emacs/.emacs.d/elpa/quelpa-20180907.1832/quelpa.el b/configs/shared/emacs/.emacs.d/elpa/quelpa-20180907.1832/quelpa.el
new file mode 100644
index 0000000000..0994a7cf76
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/quelpa-20180907.1832/quelpa.el
@@ -0,0 +1,1799 @@
+;;; quelpa.el --- Emacs Lisp packages built directly from source
+
+;; Copyright 2014-2018, Steckerhalter
+;; Copyright 2014-2015, Vasilij Schneidermann <v.schneidermann@gmail.com>
+
+;; Author: steckerhalter
+;; URL: https://framagit.org/steckerhalter/quelpa
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "24.3"))
+;; Keywords: package management build source elpa
+
+;; This file is not part of GNU Emacs.
+
+;; This file 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, or (at your option)
+;; any later version.
+
+;; This file 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; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+
+;; Your personal local Emacs Lisp Package Archive (ELPA) with packages
+;; built on-the-fly directly from source.
+
+;; See the README for more info:
+;; https://framagit.org/steckerhalter/quelpa/blob/master/README.md
+
+;;; Requirements:
+
+;; Emacs 24.3.1
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'help-fns)
+(require 'url-parse)
+(require 'package)
+(require 'lisp-mnt)
+
+;; --- customs / variables ---------------------------------------------------
+
+(defgroup quelpa nil
+  "Build and install packages from source code"
+  :group 'package)
+
+(defcustom quelpa-upgrade-p nil
+  "When non-nil, `quelpa' will try to upgrade packages.
+The global value can be overridden for each package by supplying
+the `:upgrade' argument."
+  :group 'quelpa
+  :type 'boolean)
+
+(defcustom quelpa-stable-p nil
+  "When non-nil, try to build stable packages like MELPA does."
+  :group 'quelpa
+  :type 'boolean)
+
+(defcustom quelpa-verbose t
+  "When non-nil, `quelpa' prints log messages."
+  :group 'quelpa
+  :type 'boolean)
+
+(defcustom quelpa-before-hook nil
+  "List of functions to be called before quelpa."
+  :group 'quelpa
+  :type 'hook)
+
+(defcustom quelpa-after-hook nil
+  "List of functions to be called after quelpa."
+  :group 'quelpa
+  :type 'hook)
+
+(defcustom quelpa-dir (expand-file-name "quelpa" user-emacs-directory)
+  "Where quelpa builds and stores packages."
+  :group 'quelpa
+  :type 'string)
+
+(defcustom quelpa-melpa-dir (expand-file-name "melpa" quelpa-dir)
+  "Where the melpa repo cloned to."
+  :group 'quelpa
+  :type 'string)
+
+(defcustom quelpa-build-dir (expand-file-name "build" quelpa-dir)
+  "Where quelpa builds packages."
+  :group 'quelpa
+  :type 'string)
+
+(defcustom quelpa-packages-dir (expand-file-name "packages" quelpa-dir)
+  "Where quelpa puts built packages."
+  :group 'quelpa
+  :type 'string)
+
+(defcustom quelpa-melpa-recipe-stores (list (expand-file-name
+                                             "recipes"
+                                             quelpa-melpa-dir))
+  "Recipe stores where quelpa finds default recipes for packages.
+A store can either be a string pointing to a directory with
+recipe files or a list with recipes."
+  :group 'quelpa
+  :type '(repeat
+          (choice directory
+                  (repeat
+                   :tag "List of recipes"
+                   (restricted-sexp :tag "Recipe"
+                                    :match-alternatives (listp))))))
+
+(defcustom quelpa-persistent-cache-file (expand-file-name "cache" quelpa-dir)
+  "Location of the persistent cache file."
+  :group 'quelpa
+  :type 'string)
+
+(defcustom quelpa-persistent-cache-p t
+  "Non-nil when quelpa's cache is saved on and read from disk."
+  :group 'quelpa
+  :type 'boolean)
+
+(defcustom quelpa-checkout-melpa-p t
+  "If non-nil the MELPA git repo is cloned when quelpa is initialized."
+  :group 'quelpa
+  :type 'boolean)
+
+(defcustom quelpa-update-melpa-p t
+  "If non-nil the MELPA git repo is updated when quelpa is initialized.
+If nil the update is disabled and the repo is only updated on
+`quelpa-upgrade' or `quelpa-self-upgrade'."
+  :group 'quelpa
+  :type 'boolean)
+
+(defcustom quelpa-melpa-repo-url "https://github.com/melpa/melpa.git"
+  "The melpa git repository url."
+  :group 'quelpa
+  :type 'string)
+
+(defcustom quelpa-self-upgrade-p t
+  "If non-nil upgrade quelpa itself when doing a
+  `quelpa-upgrade', otherwise only upgrade the packages in the
+  quelpa cache."
+  :group 'quelpa
+  :type 'boolean)
+
+(defvar quelpa-initialized-p nil
+  "Non-nil when quelpa has been initialized.")
+
+(defvar quelpa-cache nil
+  "The `quelpa' command stores processed pkgs/recipes in the cache.")
+
+(defvar quelpa-recipe '(quelpa :url "https://framagit.org/steckerhalter/quelpa.git" :fetcher git)
+  "The recipe for quelpa.")
+
+;; --- compatibility for legacy `package.el' in Emacs 24.3  -------------------
+
+(defun quelpa-setup-package-structs ()
+  "Setup the struct `package-desc' when not available.
+`package-desc-from-legacy' is provided to convert the legacy
+vector desc into a valid PACKAGE-DESC."
+  (unless (functionp 'package-desc-p)
+    (cl-defstruct
+        (package-desc
+         (:constructor
+          ;; convert legacy package desc into PACKAGE-DESC
+          package-desc-from-legacy
+          (pkg-info kind
+                    &aux
+                    (name (intern (aref pkg-info 0)))
+                    (version (version-to-list (aref pkg-info 3)))
+                    (summary (if (string= (aref pkg-info 2) "")
+                                 "No description available."
+                               (aref pkg-info 2)))
+                    (reqs  (aref pkg-info 1))
+                    (kind kind))))
+      name
+      version
+      (summary "No description available.")
+      reqs
+      kind
+      archive
+      dir
+      extras
+      signed)))
+
+;; --- package building ------------------------------------------------------
+
+(defun quelpa-package-type (file)
+  "Determine the package type of FILE.
+Return `tar' for tarball packages, `single' for single file
+packages, or nil, if FILE is not a package."
+  (let ((ext (file-name-extension file)))
+    (cond
+     ((string= ext "tar") 'tar)
+     ((string= ext "el") 'single)
+     (:else nil))))
+
+(defun quelpa-get-package-desc (file)
+  "Extract and return the PACKAGE-DESC struct from FILE.
+On error return nil."
+  (let* ((kind (quelpa-package-type file))
+         (desc (with-demoted-errors "Error getting PACKAGE-DESC: %s"
+                 (with-temp-buffer
+                   (pcase kind
+                     (`single (insert-file-contents file)
+                              (package-buffer-info))
+                     (`tar (insert-file-contents-literally file)
+                           (tar-mode)
+                           (if (help-function-arglist 'package-tar-file-info)
+                               ;; legacy `package-tar-file-info' requires an arg
+                               (package-tar-file-info file)
+                             (with-no-warnings (package-tar-file-info)))))))))
+    (pcase desc
+      ((pred package-desc-p) desc)
+      ((pred vectorp) (package-desc-from-legacy desc kind)))))
+
+(defun quelpa-archive-file-name (archive-entry)
+  "Return the path of the file in which the package for ARCHIVE-ENTRY is stored."
+  (let* ((name (car archive-entry))
+         (pkg-info (cdr archive-entry))
+         (version (package-version-join (aref pkg-info 0)))
+         (flavour (aref pkg-info 3)))
+    (expand-file-name
+     (format "%s-%s.%s" name version (if (eq flavour 'single) "el" "tar"))
+     quelpa-packages-dir)))
+
+(defun quelpa-version>-p (name version)
+  "Return non-nil if VERSION of pkg with NAME is newer than what is currently installed."
+  (not (or (not version)
+           (let ((pkg-desc (cdr (assq name package-alist))))
+             (and pkg-desc
+                  (version-list-<=
+                   (version-to-list version)
+                   (if (functionp 'package-desc-vers)
+                       (package-desc-vers pkg-desc) ;old implementation
+                     (package-desc-version (car pkg-desc))))))
+           ;; Also check built-in packages.
+           (package-built-in-p name (version-to-list version)))))
+
+(defun quelpa-checkout (rcp dir)
+  "Return the version of the new package given a RCP.
+Return nil if the package is already installed and should not be upgraded."
+  (pcase-let ((`(,name . ,config) rcp)
+              (quelpa-build-stable quelpa-stable-p))
+    (unless (or (and (assq name package-alist) (not quelpa-upgrade-p))
+                (and (not config)
+                     (quelpa-message t "no recipe found for package `%s'" name)))
+      (let ((version (condition-case err
+                         (quelpa-build-checkout name config dir)
+                       (error "Failed to checkout `%s': `%s'"
+                              name (error-message-string err)))))
+        (when (quelpa-version>-p name version)
+          version)))))
+
+(defun quelpa-build (rcp)
+  "Build a package from the given recipe RCP.
+Uses the `package-build' library to get the source code and build
+an elpa compatible package in `quelpa-build-dir' storing it in
+`quelpa-packages-dir'. Return the path to the created file or nil
+if no action is necessary (like when the package is installed
+already and should not be upgraded etc)."
+  (let* ((name (car rcp))
+         (build-dir (expand-file-name (symbol-name name) quelpa-build-dir))
+         (version (quelpa-checkout rcp build-dir)))
+    (when version
+      (quelpa-archive-file-name
+       (quelpa-build-package (symbol-name name)
+                             version
+                             (quelpa-build--config-file-list (cdr rcp))
+                             build-dir
+                             quelpa-packages-dir)))))
+
+;; --- package-build.el integration ------------------------------------------
+
+(defun quelpa-file-version (file-path type version time-stamp)
+  "Return version of file at FILE-PATH."
+  (if (eq type 'directory)
+      time-stamp
+    (cl-letf* ((package-strip-rcs-id-orig (symbol-function 'package-strip-rcs-id))
+               ((symbol-function 'package-strip-rcs-id)
+                (lambda (str)
+                  (or (funcall package-strip-rcs-id-orig (lm-header "package-version"))
+                      (funcall package-strip-rcs-id-orig (lm-header "version"))
+                      "0"))))
+      (concat (mapconcat
+               #'number-to-string
+               (package-desc-version (quelpa-get-package-desc file-path)) ".")
+              (pcase version
+                (`original "")
+                (_ (concat "pre0." time-stamp)))))))
+
+(defun quelpa-directory-files (path)
+  "Return list of directory files from PATH recursively."
+  (let ((result '()))
+    (mapc
+     (lambda (file)
+       (if (file-directory-p file)
+           (progn
+             ;; When directory is not empty.
+             (when (cddr (directory-files file))
+               (dolist (subfile (quelpa-directory-files file))
+                 (add-to-list 'result subfile))))
+         (add-to-list 'result file)))
+     (mapcar
+      (lambda (file) (expand-file-name file path))
+      ;; Without first two entries because they are always "." and "..".
+      (cddr (directory-files path))))
+    result))
+
+(defun quelpa-expand-source-file-list (file-path config)
+  "Return list of source files from FILE-PATH corresponding to
+CONFIG."
+  (let ((source-files
+         (mapcar
+          (lambda (file) (expand-file-name file file-path))
+          (quelpa-build--expand-source-file-list file-path config))))
+    ;; Replace any directories in the source file list with the filenames of the
+    ;; files they contain (so that these files can subsequently be hashed).
+    (dolist (file source-files source-files)
+      (when (file-directory-p file)
+        (setq source-files (remove file source-files))
+        (setq source-files (append source-files
+                                   (quelpa-directory-files file)))))))
+
+(defun quelpa-slurp-file (file)
+  "Return the contents of FILE as a string, or nil if no such
+file exists."
+  (when (file-exists-p file)
+    (with-temp-buffer
+      (set-buffer-multibyte nil)
+      (setq-local buffer-file-coding-system 'binary)
+      (insert-file-contents-literally file)
+      (buffer-substring-no-properties (point-min) (point-max)))))
+
+(defun quelpa-check-hash (name config file-path dir &optional fetcher)
+  "Check if hash of FILE-PATH is different as in STAMP-FILE.
+If it is different save the new hash and timestamp to STAMP-FILE
+and return TIME-STAMP, otherwise return OLD-TIME-STAMP."
+  (unless (file-directory-p dir)
+    (make-directory dir))
+  (let* (files
+         hashes
+         new-stamp-info
+         new-content-hash
+         (time-stamp
+          (replace-regexp-in-string "\\.0+" "." (format-time-string "%Y%m%d.%H%M%S")))
+         (stamp-file (concat (expand-file-name (symbol-name name) dir) ".stamp"))
+         (old-stamp-info (quelpa-build--read-from-file stamp-file))
+         (old-content-hash (cdr old-stamp-info))
+         (old-time-stamp (car old-stamp-info))
+         (type (if (file-directory-p file-path) 'directory 'file))
+         (version (plist-get config :version)))
+
+    (if (not (file-exists-p file-path))
+        (error "`%s' does not exist" file-path)
+      (if (eq type 'directory)
+          (setq files (quelpa-expand-source-file-list file-path config)
+                hashes (mapcar
+                        (lambda (file)
+                          (secure-hash
+                           'sha1 (concat file (quelpa-slurp-file file)))) files)
+                new-content-hash (secure-hash 'sha1 (mapconcat 'identity hashes "")))
+        (setq new-content-hash (secure-hash 'sha1 (quelpa-slurp-file file-path)))))
+
+    (setq new-stamp-info (cons time-stamp new-content-hash))
+    (if (and old-content-hash
+             (string= new-content-hash old-content-hash))
+        (quelpa-file-version file-path type version old-time-stamp)
+      (unless (eq fetcher 'url)
+        (delete-directory dir t)
+        (make-directory dir)
+        (if (eq type 'file)
+            (copy-file file-path dir t t t t)
+          (copy-directory file-path dir t t t)))
+      (quelpa-build--dump new-stamp-info stamp-file)
+      (quelpa-file-version file-path type version time-stamp))))
+
+;; --- package-build fork ------------------------------------------
+
+(defcustom quelpa-build-verbose t
+  "When non-nil, then print additional progress information."
+  :type 'boolean)
+
+(defcustom quelpa-build-stable nil
+  "When non-nil, then try to build packages from versions-tagged code."
+  :type 'boolean)
+
+(defcustom quelpa-build-timeout-executable
+  (let ((prog (or (executable-find "timeout")
+                  (executable-find "gtimeout"))))
+    (when (and prog
+               (string-match-p "^ *-k"
+                               (shell-command-to-string (concat prog " --help"))))
+      prog))
+  "Path to a GNU coreutils \"timeout\" command if available.
+This must be a version which supports the \"-k\" option."
+  :type '(file :must-match t))
+
+(defcustom quelpa-build-timeout-secs 600
+  "Wait this many seconds for external processes to complete.
+
+If an external process takes longer than specified here to
+complete, then it is terminated.  This only has an effect
+if `quelpa-build-timeout-executable' is non-nil."
+  :type 'number)
+
+(defcustom quelpa-build-tar-executable
+  (or (executable-find "gtar")
+      (executable-find "tar"))
+  "Path to a (preferably GNU) tar command.
+Certain package names (e.g. \"@\") may not work properly with a BSD tar."
+  :type '(file :must-match t))
+
+(defcustom quelpa-build-version-regexp "^[rRvV]?\\(.*\\)$"
+  "Default pattern for matching valid version-strings within repository tags.
+The string in the capture group should be parsed as valid by `version-to-list'."
+  :type 'string)
+
+;;; Internal Variables
+
+(defconst quelpa-build-default-files-spec
+  '("*.el" "*.el.in" "dir"
+    "*.info" "*.texi" "*.texinfo"
+    "doc/dir" "doc/*.info" "doc/*.texi" "doc/*.texinfo"
+    (:exclude ".dir-locals.el" "test.el" "tests.el" "*-test.el" "*-tests.el"))
+  "Default value for :files attribute in recipes.")
+
+;;; Utilities
+
+(defun quelpa-build--message (format-string &rest args)
+  "Behave like `message' if `quelpa-build-verbose' is non-nil.
+Otherwise do nothing."
+  (when quelpa-build-verbose
+    (apply 'message format-string args)))
+
+(defun quelpa-build--slurp-file (file)
+  "Return the contents of FILE as a string, or nil if no such file exists."
+  (when (file-exists-p file)
+    (with-temp-buffer
+      (insert-file-contents file)
+      (buffer-substring-no-properties (point-min) (point-max)))))
+
+(defun quelpa-build--string-rtrim (str)
+  "Remove trailing whitespace from `STR'."
+  (replace-regexp-in-string "[ \t\n\r]+$" "" str))
+
+(defun quelpa-build--trim (str &optional chr)
+  "Return a copy of STR without any trailing CHR (or space if unspecified)."
+  (if (equal (elt str (1- (length str))) (or chr ? ))
+      (substring str 0 (1- (length str)))
+    str))
+
+;;; Version Handling
+
+(defun quelpa-build--valid-version (str &optional regexp)
+  "Apply to STR the REGEXP if defined, \
+then pass the string to `version-to-list' and return the result, \
+or nil if the version cannot be parsed."
+  (when (and regexp (string-match regexp str))
+    (setq str (match-string 1 str)))
+  (ignore-errors (version-to-list str)))
+
+(defun quelpa-build--parse-time (str)
+  "Parse STR as a time, and format as a YYYYMMDD.HHMM string."
+  ;; We remove zero-padding the HH portion, as it is lost
+  ;; when stored in the archive-contents
+  (setq str (substring-no-properties str))
+  (let ((time (date-to-time
+               (if (string-match "\
+^\\([0-9]\\{4\\}\\)/\\([0-9]\\{2\\}\\)/\\([0-9]\\{2\\}\\) \
+\\([0-9]\\{2\\}:[0-9]\\{2\\}:[0-9]\\{2\\}\\)$" str)
+                   (concat (match-string 1 str) "-" (match-string 2 str) "-"
+                           (match-string 3 str) " " (match-string 4 str))
+                 str))))
+    (concat (format-time-string "%Y%m%d." time)
+            (format "%d" (string-to-number (format-time-string "%H%M" time))))))
+
+(defun quelpa-build--find-parse-time (regexp &optional bound)
+  "Find REGEXP in current buffer and format as a time-based version string.
+An optional second argument bounds the search; it is a buffer
+position.  The match found must not end after that position."
+  (and (re-search-backward regexp bound t)
+       (quelpa-build--parse-time (match-string-no-properties 1))))
+
+(defun quelpa-build--find-parse-time-newest (regexp &optional bound)
+  "Find REGEXP in current buffer and format as a time-based version string.
+An optional second argument bounds the search; it is a buffer
+position.  The match found must not end after that position."
+  (save-match-data
+    (let (cur matches)
+      (while (setq cur (quelpa-build--find-parse-time regexp bound))
+        (push cur matches))
+      (car (nreverse (sort matches 'string<))))))
+
+(defun quelpa-build--find-version-newest (regexp &optional bound)
+  "Find the newest version matching REGEXP before point.
+An optional second argument bounds the search; it is a buffer
+position.  The match found must not before after that position."
+  (let ((tags (split-string
+               (buffer-substring-no-properties
+                (or bound (point-min)) (point))
+               "\n")))
+    (setq tags (append
+                (mapcar
+                 ;; Because the default `version-separator' is ".",
+                 ;; version-strings like "1_4_5" will be parsed
+                 ;; wrongly as (1 -4 4 -4 5), so we set
+                 ;; `version-separator' to "_" below and run again.
+                 (lambda (tag)
+                   (when (quelpa-build--valid-version tag regexp)
+                     (list (quelpa-build--valid-version tag regexp) tag)))
+                 tags)
+                (mapcar
+                 ;; Check for valid versions again, this time using
+                 ;; "_" as a separator instead of "." to catch
+                 ;; version-strings like "1_4_5".  Since "_" is
+                 ;; otherwise treated as a snapshot separator by
+                 ;; `version-regexp-alist', we don't have to worry
+                 ;; about the incorrect version list above—(1 -4 4 -4
+                 ;; 5)—since it will always be treated as older by
+                 ;; `version-list-<'.
+                 (lambda (tag)
+                   (let ((version-separator "_"))
+                     (when (quelpa-build--valid-version tag regexp)
+                       (list (quelpa-build--valid-version tag regexp) tag))))
+                 tags)))
+    (setq tags (cl-remove-if nil tags))
+    ;; Returns a list like ((0 1) ("v0.1")); the first element is used
+    ;; for comparison and for `package-version-join', and the second
+    ;; (the original tag) is used by git/hg/etc.
+    (car (nreverse (sort tags (lambda (v1 v2) (version-list-< (car v1) (car v2))))))))
+
+;;; Run Process
+
+(defun quelpa-build--run-process (dir command &rest args)
+  "In DIR (or `default-directory' if unset) run COMMAND with ARGS.
+Output is written to the current buffer."
+  (let ((default-directory (file-name-as-directory (or dir default-directory)))
+        (argv (nconc (unless (eq system-type 'windows-nt)
+                       (list "env" "LC_ALL=C"))
+                     (if quelpa-build-timeout-executable
+                         (nconc (list quelpa-build-timeout-executable
+                                      "-k" "60" (number-to-string
+                                                 quelpa-build-timeout-secs)
+                                      command)
+                                args)
+                       (cons command args)))))
+    (unless (file-directory-p default-directory)
+      (error "Can't run process in non-existent directory: %s" default-directory))
+    (let ((exit-code (apply 'process-file
+                            (car argv) nil (current-buffer) t
+                            (cdr argv))))
+      (or (zerop exit-code)
+          (error "Command '%s' exited with non-zero status %d: %s"
+                 argv exit-code (buffer-string))))))
+
+(defun quelpa-build--run-process-match (regexp dir prog &rest args)
+  "Run PROG with args and return the first match for REGEXP in its output.
+PROG is run in DIR, or if that is nil in `default-directory'."
+  (with-temp-buffer
+    (apply 'quelpa-build--run-process dir prog args)
+    (goto-char (point-min))
+    (re-search-forward regexp)
+    (match-string-no-properties 1)))
+
+;;; Checkout
+;;;; Common
+
+(defun quelpa-build-checkout (package-name config working-dir)
+  "Check out source for PACKAGE-NAME with CONFIG under WORKING-DIR.
+In turn, this function uses the :fetcher option in the CONFIG to
+choose a source-specific fetcher function, which it calls with
+the same arguments.
+
+Returns the package version as a string."
+  (let ((fetcher (plist-get config :fetcher)))
+    (quelpa-build--message "Fetcher: %s" fetcher)
+    (unless (eq fetcher 'wiki)
+      (quelpa-build--message "Source: %s\n"
+                             (or (plist-get config :repo)
+                                 (plist-get config :url))))
+    (funcall (intern (format "quelpa-build--checkout-%s" fetcher))
+             package-name config (file-name-as-directory working-dir))))
+
+(defun quelpa-build--princ-exists (dir)
+  "Print a message that the contents of DIR will be updated."
+  (quelpa-build--message "Updating %s" dir))
+
+(defun quelpa-build--princ-checkout (repo dir)
+  "Print a message that REPO will be checked out into DIR."
+  (quelpa-build--message "Cloning %s to %s" repo dir))
+
+;;;; Wiki
+
+(defvar quelpa-build--last-wiki-fetch-time 0
+  "The time at which an emacswiki URL was last requested.
+This is used to avoid exceeding the rate limit of 1 request per 2
+seconds; the server cuts off after 10 requests in 20 seconds.")
+
+(defvar quelpa-build--wiki-min-request-interval 3
+  "The shortest permissible interval between successive requests for Emacswiki URLs.")
+
+(defmacro quelpa-build--with-wiki-rate-limit (&rest body)
+  "Rate-limit BODY code passed to this macro to match EmacsWiki's rate limiting."
+  (let ((elapsed (cl-gensym)))
+    `(let ((,elapsed (- (float-time) quelpa-build--last-wiki-fetch-time)))
+       (when (< ,elapsed quelpa-build--wiki-min-request-interval)
+         (let ((wait (- quelpa-build--wiki-min-request-interval ,elapsed)))
+           (quelpa-build--message
+            "Waiting %.2f secs before hitting Emacswiki again" wait)
+           (sleep-for wait)))
+       (unwind-protect
+           (progn ,@body)
+         (setq quelpa-build--last-wiki-fetch-time (float-time))))))
+
+(require 'mm-decode)
+(defvar url-http-response-status)
+(defvar url-http-end-of-headers)
+
+(defun quelpa-build--url-copy-file (url newname &optional ok-if-already-exists)
+  "Copy URL to NEWNAME.  Both args must be strings.
+Returns the http request's header as a string.
+Like `url-copy-file', but it produces an error if the http response is not 200.
+Signals a `file-already-exists' error if file NEWNAME already exists,
+unless a third argument OK-IF-ALREADY-EXISTS is supplied and non-nil.
+A number as third arg means request confirmation if NEWNAME already exists."
+  (if (and (file-exists-p newname)
+           (not ok-if-already-exists))
+      (error "Opening output file: File already exists, %s" newname))
+  (let ((buffer (url-retrieve-synchronously url))
+        (headers nil)
+        (handle nil))
+    (if (not buffer)
+        (error "Opening input file: No such file or directory, %s" url))
+    (with-current-buffer buffer
+      (unless (= 200 url-http-response-status)
+        (error "HTTP error %s fetching %s" url-http-response-status url))
+      (setq handle (mm-dissect-buffer t))
+      (mail-narrow-to-head)
+      (setq headers (buffer-string)))
+    (mm-save-part-to-file handle newname)
+    (kill-buffer buffer)
+    (mm-destroy-parts handle)
+    headers))
+
+(defun quelpa-build--grab-wiki-file (filename)
+  "Download FILENAME from emacswiki, returning its last-modified time."
+  (let ((download-url
+         (format "https://www.emacswiki.org/emacs/download/%s" filename))
+        headers)
+    (quelpa-build--with-wiki-rate-limit
+     (setq headers (quelpa-build--url-copy-file download-url filename t)))
+    (when (zerop (nth 7 (file-attributes filename)))
+      (error "Wiki file %s was empty - has it been removed?" filename))
+    (quelpa-build--parse-time
+     (with-temp-buffer
+       (insert headers)
+       (mail-fetch-field "last-modified")))))
+
+(defun quelpa-build--checkout-wiki (name config dir)
+  "Checkout package NAME with config CONFIG from the EmacsWiki into DIR."
+  (unless quelpa-build-stable
+    (with-current-buffer (get-buffer-create "*quelpa-build-checkout*")
+      (unless (file-exists-p dir)
+        (make-directory dir))
+      (let ((files (or (plist-get config :files)
+                       (list (format "%s.el" name))))
+            (default-directory dir))
+        (car (nreverse (sort (mapcar 'quelpa-build--grab-wiki-file files)
+                             'string-lessp)))))))
+
+;;;; Darcs
+
+(defun quelpa-build--darcs-repo (dir)
+  "Get the current darcs repo for DIR."
+  (quelpa-build--run-process-match "Default Remote: \\(.*\\)"
+                                   dir "darcs" "show" "repo"))
+
+(defun quelpa-build--checkout-darcs (name config dir)
+  "Check package NAME with config CONFIG out of darcs into DIR."
+  (let ((repo (plist-get config :url)))
+    (with-current-buffer (get-buffer-create "*quelpa-build-checkout*")
+      (cond
+       ((and (file-exists-p (expand-file-name "_darcs" dir))
+             (string-equal (quelpa-build--darcs-repo dir) repo))
+        (quelpa-build--princ-exists dir)
+        (quelpa-build--run-process dir "darcs" "pull" "--all"))
+       (t
+        (when (file-exists-p dir)
+          (delete-directory dir t))
+        (quelpa-build--princ-checkout repo dir)
+        (quelpa-build--run-process nil "darcs" "get" repo dir)))
+      (if quelpa-build-stable
+          (let* ((min-bound (goto-char (point-max)))
+                 (tag-version
+                  (and (quelpa-build--run-process dir "darcs" "show" "tags")
+                       (or (quelpa-build--find-version-newest
+                            (or (plist-get config :version-regexp)
+                                quelpa-build-version-regexp)
+                            min-bound)
+                           (error "No valid stable versions found for %s" name)))))
+            (quelpa-build--run-process dir "darcs" "obliterate"
+                                       "--all" "--from-tag"
+                                       (cadr tag-version))
+            ;; Return the parsed version as a string
+            (package-version-join (car tag-version)))
+        (apply 'quelpa-build--run-process
+               dir "darcs" "changes" "--max-count" "1"
+               (quelpa-build--expand-source-file-list dir config))
+        (quelpa-build--find-parse-time "\
+\\([a-zA-Z]\\{3\\} [a-zA-Z]\\{3\\} \
+\\( \\|[0-9]\\)[0-9] [0-9]\\{2\\}:[0-9]\\{2\\}:[0-9]\\{2\\} \
+[A-Za-z]\\{3\\} [0-9]\\{4\\}\\)")))))
+
+;;;; Fossil
+
+(defun quelpa-build--fossil-repo (dir)
+  "Get the current fossil repo for DIR."
+  (quelpa-build--run-process-match "\\(.*\\)" dir "fossil" "remote-url"))
+
+(defun quelpa-build--checkout-fossil (name config dir)
+  "Check package NAME with config CONFIG out of fossil into DIR."
+  (unless quelpa-build-stable
+    (let ((repo (plist-get config :url)))
+      (with-current-buffer (get-buffer-create "*quelpa-build-checkout*")
+        (cond
+         ((and (or (file-exists-p (expand-file-name ".fslckout" dir))
+                   (file-exists-p (expand-file-name "_FOSSIL_" dir)))
+               (string-equal (quelpa-build--fossil-repo dir) repo))
+          (quelpa-build--princ-exists dir)
+          (quelpa-build--run-process dir "fossil" "update"))
+         (t
+          (when (file-exists-p dir)
+            (delete-directory dir t))
+          (quelpa-build--princ-checkout repo dir)
+          (make-directory dir)
+          (quelpa-build--run-process dir "fossil" "clone" repo "repo.fossil")
+          (quelpa-build--run-process dir "fossil" "open" "repo.fossil")))
+        (quelpa-build--run-process dir "fossil" "timeline" "-n" "1" "-t" "ci")
+        (or (quelpa-build--find-parse-time "\
+=== \\([0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\} ===\n\
+[0-9]\\{2\\}:[0-9]\\{2\\}:[0-9]\\{2\\}\\) ")
+            (error "No valid timestamps found!"))))))
+
+;;;; Svn
+
+(defun quelpa-build--svn-repo (dir)
+  "Get the current svn repo for DIR."
+  (quelpa-build--run-process-match "URL: \\(.*\\)" dir "svn" "info"))
+
+(defun quelpa-build--checkout-svn (name config dir)
+  "Check package NAME with config CONFIG out of svn into DIR."
+  (unless quelpa-build-stable
+    (with-current-buffer (get-buffer-create "*quelpa-build-checkout*")
+      (let ((repo (quelpa-build--trim (plist-get config :url) ?/))
+            (bound (goto-char (point-max))))
+        (cond
+         ((and (file-exists-p (expand-file-name ".svn" dir))
+               (string-equal (quelpa-build--svn-repo dir) repo))
+          (quelpa-build--princ-exists dir)
+          (quelpa-build--run-process dir "svn" "up"))
+         (t
+          (when (file-exists-p dir)
+            (delete-directory dir t))
+          (quelpa-build--princ-checkout repo dir)
+          (quelpa-build--run-process nil "svn" "checkout" repo dir)))
+        (apply 'quelpa-build--run-process dir "svn" "info"
+               (quelpa-build--expand-source-file-list dir config))
+        (or (quelpa-build--find-parse-time-newest "\
+Last Changed Date: \\([0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\} \
+[0-9]\\{2\\}:[0-9]\\{2\\}:[0-9]\\{2\\}\\( [+-][0-9]\\{4\\}\\)?\\)"
+                                                  bound)
+            (error "No valid timestamps found!"))))))
+
+;;;; Cvs
+
+(defun quelpa-build--cvs-repo (dir)
+  "Get the current CVS root and repository for DIR.
+
+Return a cons cell whose `car' is the root and whose `cdr' is the repository."
+  (apply 'cons
+         (mapcar (lambda (file)
+                   (quelpa-build--string-rtrim
+                    (quelpa-build--slurp-file (expand-file-name file dir))))
+                 '("CVS/Root" "CVS/Repository"))))
+
+(defun quelpa-build--checkout-cvs (name config dir)
+  "Check package NAME with config CONFIG out of cvs into DIR."
+  (unless quelpa-build-stable
+    (with-current-buffer (get-buffer-create "*quelpa-build-checkout*")
+      (let ((root (quelpa-build--trim (plist-get config :url) ?/))
+            (repo (or (plist-get config :module) (symbol-name name)))
+            (bound (goto-char (point-max)))
+            latest)
+        (cond
+         ((and (file-exists-p (expand-file-name "CVS" dir))
+               (equal (quelpa-build--cvs-repo dir) (cons root repo)))
+          (quelpa-build--princ-exists dir)
+          (quelpa-build--run-process dir "cvs" "update" "-dP"))
+         (t
+          (when (file-exists-p dir)
+            (delete-directory dir t))
+          (quelpa-build--princ-checkout (format "%s from %s" repo root) dir)
+          ;; CVS insists on relative paths as target directory for checkout (for
+          ;; whatever reason), and puts "CVS" directories into every subdirectory
+          ;; of the current working directory given in the target path. To get CVS
+          ;; to just write to DIR, we need to execute CVS from the parent
+          ;; directory of DIR, and specific DIR as relative path.  Hence all the
+          ;; following mucking around with paths.  CVS is really horrid.
+          (let ((dir (directory-file-name dir)))
+            (quelpa-build--run-process (file-name-directory dir)
+                                       "env" "TZ=UTC" "cvs" "-z3"
+                                       "-d" root "checkout"
+                                       "-d" (file-name-nondirectory dir)
+                                       repo))))
+        (apply 'quelpa-build--run-process dir "cvs" "log"
+               (quelpa-build--expand-source-file-list dir config))
+
+        ;; `cvs log` does not provide a way to view the previous N
+        ;; revisions, so instead of parsing the entire log we examine
+        ;; the Entries file, which looks like this:
+        ;;
+        ;; /.cvsignore/1.2/Thu Sep  1 12:42:02 2005//
+        ;; /CHANGES/1.1/Tue Oct  4 11:47:54 2005//
+        ;; /GNUmakefile/1.8/Tue Oct  4 11:47:54 2005//
+        ;; /Makefile/1.14/Tue Oct  4 11:47:54 2005//
+        ;;
+        (insert-file-contents (concat dir "/CVS/Entries"))
+        (setq latest
+              (car
+               (sort
+                (split-string (buffer-substring-no-properties (point) (point-max)) "\n")
+                (lambda (x y)
+                  (when (string-match "^\\/[^\\/]*\\/[^\\/]*\\/\\([^\\/]*\\)\\/\\/$" x)
+                    (setq x (quelpa-build--parse-time (match-string 1 x))))
+                  (when (string-match "^\\/[^\\/]*\\/[^\\/]*\\/\\([^\\/]*\\)\\/\\/$" y)
+                    (setq y (quelpa-build--parse-time (match-string 1 y))))
+                  (version-list-<= (quelpa-build--valid-version y)
+                                   (quelpa-build--valid-version x))))))
+        (when (string-match "^\\/[^\\/]*\\/[^\\/]*\\/\\([^\\/]*\\)\\/\\/$" latest)
+          (setq latest (match-string 1 latest)))
+        (or (quelpa-build--parse-time latest)
+            (error "No valid timestamps found!"))))))
+
+;;;; Git
+
+(defun quelpa-build--git-repo (dir)
+  "Get the current git repo for DIR."
+  (quelpa-build--run-process-match
+   "Fetch URL: \\(.*\\)" dir "git" "remote" "show" "-n" "origin"))
+
+(defun quelpa-build--checkout-git (name config dir)
+  "Check package NAME with config CONFIG out of git into DIR."
+  (let ((repo (plist-get config :url))
+        (commit (or (plist-get config :commit)
+                    (let ((branch (plist-get config :branch)))
+                      (when branch
+                        (concat "origin/" branch))))))
+    (with-current-buffer (get-buffer-create "*quelpa-build-checkout*")
+      (goto-char (point-max))
+      (cond
+       ((and (file-exists-p (expand-file-name ".git" dir))
+             (string-equal (quelpa-build--git-repo dir) repo))
+        (quelpa-build--princ-exists dir)
+        (quelpa-build--run-process dir "git" "fetch" "--all" "--tags"))
+       (t
+        (when (file-exists-p dir)
+          (delete-directory dir t))
+        (quelpa-build--princ-checkout repo dir)
+        (quelpa-build--run-process nil "git" "clone" repo dir)))
+      (if quelpa-build-stable
+          (let* ((min-bound (goto-char (point-max)))
+                 (tag-version
+                  (and (quelpa-build--run-process dir "git" "tag")
+                       (or (quelpa-build--find-version-newest
+                            (or (plist-get config :version-regexp)
+                                quelpa-build-version-regexp)
+                            min-bound)
+                           (error "No valid stable versions found for %s" name)))))
+            ;; Using reset --hard here to comply with what's used for
+            ;; unstable, but maybe this should be a checkout?
+            (quelpa-build--update-git-to-ref
+             dir (concat "tags/" (cadr tag-version)))
+            ;; Return the parsed version as a string
+            (package-version-join (car tag-version)))
+        (quelpa-build--update-git-to-ref
+         dir (or commit (concat "origin/" (quelpa-build--git-head-branch dir))))
+        (apply 'quelpa-build--run-process
+               dir "git" "log" "--first-parent" "-n1" "--pretty=format:'\%ci'"
+               (quelpa-build--expand-source-file-list dir config))
+        (quelpa-build--find-parse-time "\
+\\([0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\} \
+[0-9]\\{2\\}:[0-9]\\{2\\}:[0-9]\\{2\\}\\( [+-][0-9]\\{4\\}\\)?\\)")))))
+
+(defun quelpa-build--git-head-branch (dir)
+  "Get the current git repo for DIR."
+  (or (ignore-errors
+        (quelpa-build--run-process-match
+         "HEAD branch: \\(.*\\)" dir "git" "remote" "show" "origin"))
+      "master"))
+
+(defun quelpa-build--git-head-sha (dir)
+  "Get the current head SHA for DIR."
+  (ignore-errors
+    (quelpa-build--run-process-match
+     "\\(.*\\)" dir "git" "rev-parse" "HEAD")))
+
+(defun quelpa-build--update-git-to-ref (dir ref)
+  "Update the git repo in DIR so that HEAD is REF."
+  (quelpa-build--run-process dir "git" "reset" "--hard" ref)
+  (quelpa-build--run-process dir "git" "submodule" "sync" "--recursive")
+  (quelpa-build--run-process dir "git" "submodule" "update" "--init" "--recursive"))
+
+(defun quelpa-build--checkout-github (name config dir)
+  "Check package NAME with config CONFIG out of github into DIR."
+  (let ((url (format "https://github.com/%s.git" (plist-get config :repo))))
+    (quelpa-build--checkout-git name (plist-put (copy-sequence config) :url url) dir)))
+
+(defun quelpa-build--checkout-gitlab (name config dir)
+  "Check package NAME with config CONFIG out of gitlab into DIR."
+  (let ((url (format "https://gitlab.com/%s.git" (plist-get config :repo))))
+    (quelpa-build--checkout-git name (plist-put (copy-sequence config) :url url) dir)))
+
+;;;; Bzr
+
+(defun quelpa-build--bzr-repo (dir)
+  "Get the current bzr repo for DIR."
+  (quelpa-build--run-process-match "parent branch: \\(.*\\)" dir "bzr" "info"))
+
+(defun quelpa-build--checkout-bzr (name config dir)
+  "Check package NAME with config CONFIG out of bzr into DIR."
+  (let ((repo (quelpa-build--run-process-match
+               "\\(?:branch root\\|repository branch\\): \\(.*\\)"
+               nil "bzr" "info" (plist-get config :url))))
+    (with-current-buffer (get-buffer-create "*quelpa-build-checkout*")
+      (goto-char (point-max))
+      (cond
+       ((and (file-exists-p (expand-file-name ".bzr" dir))
+             (string-equal (quelpa-build--bzr-repo dir) repo))
+        (quelpa-build--princ-exists dir)
+        (quelpa-build--run-process dir "bzr" "merge" "--force"))
+       (t
+        (when (file-exists-p dir)
+          (delete-directory dir t))
+        (quelpa-build--princ-checkout repo dir)
+        (quelpa-build--run-process nil "bzr" "branch" repo dir)))
+      (if quelpa-build-stable
+          (let ((bound (goto-char (point-max)))
+                (regexp (or (plist-get config :version-regexp)
+                            quelpa-build-version-regexp))
+                tag-version)
+            (quelpa-build--run-process dir "bzr" "tags")
+            (goto-char bound)
+            (ignore-errors (while (re-search-forward "\\ +.*")
+                             (replace-match "")))
+            (setq tag-version
+                  (or (quelpa-build--find-version-newest regexp bound)
+                      (error "No valid stable versions found for %s" name)))
+            (quelpa-build--run-process dir
+                                       "bzr" "revert" "-r"
+                                       (concat "tag:" (cadr tag-version)))
+            ;; Return the parsed version as a string
+            (package-version-join (car tag-version)))
+        (apply 'quelpa-build--run-process dir "bzr" "log" "-l1"
+               (quelpa-build--expand-source-file-list dir config))
+        (quelpa-build--find-parse-time "\
+\\([0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\} \
+[0-9]\\{2\\}:[0-9]\\{2\\}:[0-9]\\{2\\}\\( [+-][0-9]\\{4\\}\\)?\\)")))))
+
+;;;; Hg
+
+(defun quelpa-build--hg-repo (dir)
+  "Get the current hg repo for DIR."
+  (quelpa-build--run-process-match "default = \\(.*\\)" dir "hg" "paths"))
+
+(defun quelpa-build--checkout-hg (name config dir)
+  "Check package NAME with config CONFIG out of hg into DIR."
+  (let ((repo (plist-get config :url)))
+    (with-current-buffer (get-buffer-create "*quelpa-build-checkout*")
+      (goto-char (point-max))
+      (cond
+       ((and (file-exists-p (expand-file-name ".hg" dir))
+             (string-equal (quelpa-build--hg-repo dir) repo))
+        (quelpa-build--princ-exists dir)
+        (quelpa-build--run-process dir "hg" "pull")
+        (quelpa-build--run-process dir "hg" "update"))
+       (t
+        (when (file-exists-p dir)
+          (delete-directory dir t))
+        (quelpa-build--princ-checkout repo dir)
+        (quelpa-build--run-process nil "hg" "clone" repo dir)))
+      (if quelpa-build-stable
+          (let ((min-bound (goto-char (point-max)))
+                (regexp (or (plist-get config :version-regexp)
+                            quelpa-build-version-regexp))
+                tag-version)
+            (quelpa-build--run-process dir "hg" "tags")
+            ;; The output of `hg tags` shows the ref of the tag as well
+            ;; as the tag itself, e.g.:
+            ;;
+            ;; tip                             1696:73ad80e8fea1
+            ;; 1.2.8                           1691:464af57fd2b7
+            ;;
+            ;; So here we remove that second column before passing the
+            ;; buffer contents to `quelpa-build--find-version-newest'.
+            ;; This isn't strictly necessary for Mercurial since the
+            ;; colon in "1691:464af57fd2b7" means that won't be parsed
+            ;; as a valid version-string, but it's an example of how to
+            ;; do it in case it's necessary elsewhere.
+            (goto-char min-bound)
+            (ignore-errors (while (re-search-forward "\\ +.*")
+                             (replace-match "")))
+            (setq tag-version
+                  (or (quelpa-build--find-version-newest regexp min-bound)
+                      (error "No valid stable versions found for %s" name)))
+            (quelpa-build--run-process dir "hg" "update" (cadr tag-version))
+            ;; Return the parsed version as a string
+            (package-version-join (car tag-version)))
+        (apply 'quelpa-build--run-process
+               dir "hg" "log" "--style" "compact" "-l1"
+               (quelpa-build--expand-source-file-list dir config))
+        (quelpa-build--find-parse-time "\
+\\([0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\} \
+[0-9]\\{2\\}:[0-9]\\{2\\}\\( [+-][0-9]\\{4\\}\\)?\\)")))))
+
+(defun quelpa-build--checkout-bitbucket (name config dir)
+  "Check package NAME with config CONFIG out of bitbucket into DIR."
+  (let ((url (format "https://bitbucket.com/%s" (plist-get config :repo))))
+    (quelpa-build--checkout-hg name (plist-put (copy-sequence config) :url url) dir)))
+
+;;; Utilities
+
+(defun quelpa-build--dump (data file &optional pretty-print)
+  "Write DATA to FILE as a Lisp sexp.
+Optionally PRETTY-PRINT the data."
+  (with-temp-file file
+    (quelpa-build--message "File: %s" file)
+    (if pretty-print
+        (pp data (current-buffer))
+      (print data (current-buffer)))))
+
+(defun quelpa-build--write-pkg-file (pkg-file pkg-info)
+  "Write PKG-FILE containing PKG-INFO."
+  (with-temp-file pkg-file
+    (pp
+     `(define-package
+        ,(aref pkg-info 0)
+        ,(aref pkg-info 3)
+        ,(aref pkg-info 2)
+        ',(mapcar
+           (lambda (elt)
+             (list (car elt)
+                   (package-version-join (cadr elt))))
+           (aref pkg-info 1))
+        ;; Append our extra information
+        ,@(cl-mapcan (lambda (entry)
+                       (let ((value (cdr entry)))
+                         (when (or (symbolp value) (listp value))
+                           ;; We must quote lists and symbols,
+                           ;; because Emacs 24.3 and earlier evaluate
+                           ;; the package information, which would
+                           ;; break for unquoted symbols or lists
+                           (setq value (list 'quote value)))
+                         (list (car entry) value)))
+                     (when (> (length pkg-info) 4)
+                       (aref pkg-info 4))))
+     (current-buffer))
+    (princ ";; Local Variables:\n;; no-byte-compile: t\n;; End:\n"
+           (current-buffer))))
+
+(defun quelpa-build--read-from-file (file)
+  "Read and return the Lisp data stored in FILE, or nil if no such file exists."
+  (when (file-exists-p file)
+    (car (read-from-string (quelpa-build--slurp-file file)))))
+
+(defun quelpa-build--create-tar (file dir &optional files)
+  "Create a tar FILE containing the contents of DIR, or just FILES if non-nil."
+  (when (eq system-type 'windows-nt)
+    (setq file (replace-regexp-in-string "^\\([a-z]\\):" "/\\1" file)))
+  (apply 'process-file
+         quelpa-build-tar-executable nil
+         (get-buffer-create "*quelpa-build-checkout*")
+         nil "-cvf"
+         file
+         "--exclude=.svn"
+         "--exclude=CVS"
+         "--exclude=.git"
+         "--exclude=_darcs"
+         "--exclude=.fslckout"
+         "--exclude=_FOSSIL_"
+         "--exclude=.bzr"
+         "--exclude=.hg"
+         (or (mapcar (lambda (fn) (concat dir "/" fn)) files) (list dir))))
+
+(defun quelpa-build--find-package-commentary (file-path)
+  "Get commentary section from FILE-PATH."
+  (when (file-exists-p file-path)
+    (with-temp-buffer
+      (insert-file-contents file-path)
+      (lm-commentary))))
+
+(defun quelpa-build--write-pkg-readme (target-dir commentary file-name)
+  "In TARGET-DIR, write COMMENTARY to a -readme.txt file prefixed with FILE-NAME."
+  (when commentary
+    (with-temp-buffer
+      (insert commentary)
+      ;; Adapted from `describe-package-1'.
+      (goto-char (point-min))
+      (save-excursion
+        (when (re-search-forward "^;;; Commentary:\n" nil t)
+          (replace-match ""))
+        (while (re-search-forward "^\\(;+ ?\\)" nil t)
+          (replace-match ""))
+        (goto-char (point-min))
+        (when (re-search-forward "\\`\\( *\n\\)+" nil t)
+          (replace-match "")))
+      (delete-trailing-whitespace)
+      (let ((coding-system-for-write buffer-file-coding-system))
+        (write-region nil nil
+                      (quelpa-build--readme-file-name target-dir file-name))))))
+
+(defun quelpa-build--readme-file-name (target-dir file-name)
+  "Name of the readme file in TARGET-DIR for the package FILE-NAME."
+  (expand-file-name (concat file-name "-readme.txt")
+                    target-dir))
+
+(defun quelpa-build--update-or-insert-version (version)
+  "Ensure current buffer has a \"Package-Version: VERSION\" header."
+  (goto-char (point-min))
+  (if (let ((case-fold-search t))
+        (re-search-forward "^;+* *Package-Version *: *" nil t))
+      (progn
+        (move-beginning-of-line nil)
+        (search-forward "V" nil t)
+        (backward-char)
+        (insert "X-Original-")
+        (move-beginning-of-line nil))
+    ;; Put the new header in a sensible place if we can
+    (re-search-forward "^;+* *\\(Version\\|Package-Requires\\|Keywords\\|URL\\) *:"
+                       nil t)
+    (forward-line))
+  (insert (format ";; Package-Version: %s" version))
+  (newline))
+
+(defun quelpa-build--ensure-ends-here-line (file-path)
+  "Add a 'FILE-PATH ends here' trailing line if missing."
+  (save-excursion
+    (goto-char (point-min))
+    (let ((trailer (concat ";;; "
+                           (file-name-nondirectory file-path)
+                           " ends here")))
+      (unless (search-forward trailer nil t)
+        (goto-char (point-max))
+        (newline)
+        (insert trailer)
+        (newline)))))
+
+(defun quelpa-build--get-package-info (file-path)
+  "Get a vector of package info from the docstrings in FILE-PATH."
+  (when (file-exists-p file-path)
+    (ignore-errors
+      (with-temp-buffer
+        (insert-file-contents file-path)
+        ;; next few lines are a hack for some packages that aren't
+        ;; commented properly.
+        (quelpa-build--update-or-insert-version "0")
+        (quelpa-build--ensure-ends-here-line file-path)
+        (cl-flet ((package-strip-rcs-id (str) "0"))
+          (quelpa-build--package-buffer-info-vec))))))
+
+(defun quelpa-build--get-pkg-file-info (file-path)
+  "Get a vector of package info from \"-pkg.el\" file FILE-PATH."
+  (when (file-exists-p file-path)
+    (let ((package-def (quelpa-build--read-from-file file-path)))
+      (if (eq 'define-package (car package-def))
+          (let* ((pkgfile-info (cdr package-def))
+                 (descr (nth 2 pkgfile-info))
+                 (rest-plist (cl-subseq pkgfile-info (min 4 (length pkgfile-info))))
+                 (extras (let (alist)
+                           (while rest-plist
+                             (unless (memq (car rest-plist) '(:kind :archive))
+                               (let ((value (cadr rest-plist)))
+                                 (when value
+                                   (push (cons (car rest-plist)
+                                               (if (eq (car-safe value) 'quote)
+                                                   (cadr value)
+                                                 value))
+                                         alist))))
+                             (setq rest-plist (cddr rest-plist)))
+                           alist)))
+            (when (string-match "[\r\n]" descr)
+              (error "Illegal multi-line package description in %s" file-path))
+            (vector
+             (nth 0 pkgfile-info)
+             (mapcar
+              (lambda (elt)
+                (unless (symbolp (car elt))
+                  (error "Invalid package name in dependency: %S" (car elt)))
+                (list (car elt) (version-to-list (cadr elt))))
+              (eval (nth 3 pkgfile-info)))
+             descr
+             (nth 1 pkgfile-info)
+             extras))
+        (error "No define-package found in %s" file-path)))))
+
+(defun quelpa-build--merge-package-info (pkg-info name version)
+  "Return a version of PKG-INFO updated with NAME, VERSION and info from CONFIG.
+If PKG-INFO is nil, an empty one is created."
+  (let ((merged (or (copy-sequence pkg-info)
+                    (vector name nil "No description available." version))))
+    (aset merged 0 name)
+    (aset merged 3 version)
+    merged))
+
+(defun quelpa-build--archive-entry (pkg-info type)
+  "Return the archive-contents cons cell for PKG-INFO and TYPE."
+  (let ((name (intern (aref pkg-info 0)))
+        (requires (aref pkg-info 1))
+        (desc (or (aref pkg-info 2) "No description available."))
+        (version (aref pkg-info 3))
+        (extras (and (> (length pkg-info) 4)
+                     (aref pkg-info 4))))
+    (cons name
+          (vector (version-to-list version)
+                  requires
+                  desc
+                  type
+                  extras))))
+
+;;; Recipes
+
+(defun quelpa-build-expand-file-specs (dir specs &optional subdir allow-empty)
+  "In DIR, expand SPECS, optionally under SUBDIR.
+The result is a list of (SOURCE . DEST), where SOURCE is a source
+file path and DEST is the relative path to which it should be copied.
+
+If the resulting list is empty, an error will be reported.  Pass t
+for ALLOW-EMPTY to prevent this error."
+  (let ((default-directory dir)
+        (prefix (if subdir (format "%s/" subdir) ""))
+        (lst))
+    (dolist (entry specs lst)
+      (setq lst
+            (if (consp entry)
+                (if (eq :exclude (car entry))
+                    (cl-nset-difference lst
+                                        (quelpa-build-expand-file-specs
+                                         dir (cdr entry) nil t)
+                                        :key 'car
+                                        :test 'equal)
+                  (nconc lst
+                         (quelpa-build-expand-file-specs
+                          dir
+                          (cdr entry)
+                          (concat prefix (car entry))
+                          t)))
+              (nconc
+               lst (mapcar (lambda (f)
+                             (let ((destname)))
+                             (cons f
+                                   (concat prefix
+                                           (replace-regexp-in-string
+                                            "\\.in\\'"
+                                            ""
+                                            (file-name-nondirectory f)))))
+                           (file-expand-wildcards entry))))))
+    (when (and (null lst) (not allow-empty))
+      (error "No matching file(s) found in %s: %s" dir specs))
+    lst))
+
+(defun quelpa-build--config-file-list (config)
+  "Get the :files spec from CONFIG, or return `quelpa-build-default-files-spec'."
+  (let ((file-list (plist-get config :files)))
+    (cond
+     ((null file-list)
+      quelpa-build-default-files-spec)
+     ((eq :defaults (car file-list))
+      (append quelpa-build-default-files-spec (cdr file-list)))
+     (t
+      file-list))))
+
+(defun quelpa-build--expand-source-file-list (dir config)
+  "Shorthand way to expand paths in DIR for source files listed in CONFIG."
+  (mapcar 'car
+          (quelpa-build-expand-file-specs
+           dir (quelpa-build--config-file-list config))))
+
+(defun quelpa-build--generate-info-files (files source-dir target-dir)
+  "Create .info files from any .texi files listed in FILES.
+
+The source and destination file paths are expanded in SOURCE-DIR
+and TARGET-DIR respectively.
+
+Any of the original .texi(nfo) files found in TARGET-DIR are
+deleted."
+  (dolist (spec files)
+    (let* ((source-file (car spec))
+           (source-path (expand-file-name source-file source-dir))
+           (dest-file (cdr spec))
+           (info-path (expand-file-name
+                       (concat (file-name-sans-extension dest-file) ".info")
+                       target-dir)))
+      (when (string-match ".texi\\(nfo\\)?$" source-file)
+        (when (not (file-exists-p info-path))
+          (with-current-buffer (get-buffer-create "*quelpa-build-info*")
+            (ignore-errors
+              (quelpa-build--run-process
+               (file-name-directory source-path)
+               "makeinfo"
+               source-path
+               "-o"
+               info-path)
+              (quelpa-build--message "Created %s" info-path))))
+        (quelpa-build--message "Removing %s"
+                               (expand-file-name dest-file target-dir))
+        (delete-file (expand-file-name dest-file target-dir))))))
+
+;;; Info Manuals
+
+(defun quelpa-build--generate-dir-file (files target-dir)
+  "Create dir file from any .info files listed in FILES in TARGET-DIR."
+  (dolist (spec files)
+    (let* ((source-file (car spec))
+           (dest-file (cdr spec))
+           (info-path (expand-file-name
+                       (concat (file-name-sans-extension dest-file) ".info")
+                       target-dir)))
+      (when (and (or (string-match ".info$" source-file)
+                     (string-match ".texi\\(nfo\\)?$" source-file))
+                 (file-exists-p info-path))
+        (with-current-buffer (get-buffer-create "*quelpa-build-info*")
+          (ignore-errors
+            (quelpa-build--run-process
+             nil
+             "install-info"
+             (concat "--dir=" (expand-file-name "dir" target-dir))
+             info-path)))))))
+
+;;; Utilities
+
+(defun quelpa-build--copy-package-files (files source-dir target-dir)
+  "Copy FILES from SOURCE-DIR to TARGET-DIR.
+FILES is a list of (SOURCE . DEST) relative filepath pairs."
+  (cl-loop for (source-file . dest-file) in files
+           do (quelpa-build--copy-file
+               (expand-file-name source-file source-dir)
+               (expand-file-name dest-file target-dir))))
+
+(defun quelpa-build--copy-file (file newname)
+  "Copy FILE to NEWNAME and create parent directories for NEWNAME if they don't exist."
+  (let ((newdir (file-name-directory newname)))
+    (unless (file-exists-p newdir)
+      (make-directory newdir t)))
+  (cond
+   ((file-regular-p file)
+    (quelpa-build--message "%s -> %s" file newname)
+    (copy-file file newname))
+   ((file-directory-p file)
+    (quelpa-build--message "%s => %s" file newname)
+    (copy-directory file newname))))
+
+(defun quelpa-build--find-source-file (target files)
+  "Search for source of TARGET in FILES."
+  (car (rassoc target files)))
+
+(defun quelpa-build--package-buffer-info-vec ()
+  "Return a vector of package info.
+`package-buffer-info' returns a vector in older Emacs versions,
+and a cl struct in Emacs HEAD.  This wrapper normalises the results."
+  (let ((desc (package-buffer-info))
+        (keywords (lm-keywords-list)))
+    (if (fboundp 'package-desc-create)
+        (let ((extras (package-desc-extras desc)))
+          (when (and keywords (not (assq :keywords extras)))
+            ;; Add keywords to package properties, if not already present
+            (push (cons :keywords keywords) extras))
+          (vector (package-desc-name desc)
+                  (package-desc-reqs desc)
+                  (package-desc-summary desc)
+                  (package-desc-version desc)
+                  extras))
+      ;; The regexp and the processing is taken from `lm-homepage' in Emacs 24.4
+      (let* ((page (lm-header "\\(?:x-\\)?\\(?:homepage\\|url\\)"))
+             (homepage (if (and page (string-match "^<.+>$" page))
+                           (substring page 1 -1)
+                         page))
+             extras)
+        (when keywords (push (cons :keywords keywords) extras))
+        (when homepage (push (cons :url homepage) extras))
+        (vector  (aref desc 0)
+                 (aref desc 1)
+                 (aref desc 2)
+                 (aref desc 3)
+                 extras)))))
+
+;;; Building
+
+;;;###autoload
+(defun quelpa-build-package (package-name version file-specs source-dir target-dir)
+  "Create PACKAGE-NAME with VERSION.
+
+The information in FILE-SPECS is used to gather files from
+SOURCE-DIR.
+
+The resulting package will be stored as a .el or .tar file in
+TARGET-DIR, depending on whether there are multiple files.
+
+Argument FILE-SPECS is a list of specs for source files, which
+should be relative to SOURCE-DIR.  The specs can be wildcards,
+and optionally specify different target paths.  They extended
+syntax is currently only documented in the MELPA README.  You can
+simply pass `quelpa-build-default-files-spec' in most cases.
+
+Returns the archive entry for the package."
+  (when (symbolp package-name)
+    (setq package-name (symbol-name package-name)))
+  (let ((files (quelpa-build-expand-file-specs source-dir file-specs)))
+    (unless (equal file-specs quelpa-build-default-files-spec)
+      (when (equal files (quelpa-build-expand-file-specs
+                          source-dir quelpa-build-default-files-spec nil t))
+        (quelpa-build--message "Note: %s :files spec is equivalent to the default."
+                               package-name)))
+    (cond
+     ((not version)
+      (error "Unable to check out repository for %s" package-name))
+     ((= 1 (length files))
+      (quelpa-build--build-single-file-package
+       package-name version (caar files) source-dir target-dir))
+     ((< 1 (length  files))
+      (quelpa-build--build-multi-file-package
+       package-name version files source-dir target-dir))
+     (t (error "Unable to find files matching recipe patterns")))))
+
+(defun quelpa-build--build-single-file-package
+    (package-name version file source-dir target-dir)
+  (let* ((pkg-source (expand-file-name file source-dir))
+         (pkg-target (expand-file-name
+                      (concat package-name "-" version ".el")
+                      target-dir))
+         (pkg-info (quelpa-build--merge-package-info
+                    (quelpa-build--get-package-info pkg-source)
+                    package-name
+                    version)))
+    (unless (string-equal (downcase (concat package-name ".el"))
+                          (downcase (file-name-nondirectory pkg-source)))
+      (error "Single file %s does not match package name %s"
+             (file-name-nondirectory pkg-source) package-name))
+    (if (file-exists-p pkg-target)
+        (quelpa-build--message "Skipping rebuild of %s" pkg-target)
+      (copy-file pkg-source pkg-target)
+      (let ((enable-local-variables nil)
+            (make-backup-files nil))
+        (with-temp-buffer
+          (insert-file-contents pkg-target)
+          (quelpa-build--update-or-insert-version version)
+          (quelpa-build--ensure-ends-here-line pkg-source)
+          (write-file pkg-target nil)
+          (condition-case err
+              (quelpa-build--package-buffer-info-vec)
+            (error
+             (quelpa-build--message "Warning: %S" err)))))
+
+      (quelpa-build--write-pkg-readme
+       target-dir
+       (quelpa-build--find-package-commentary pkg-source)
+       package-name))
+    (quelpa-build--archive-entry pkg-info 'single)))
+
+(defun quelpa-build--build-multi-file-package
+    (package-name version files source-dir target-dir)
+  (let ((tmp-dir (file-name-as-directory (make-temp-file package-name t))))
+    (unwind-protect
+        (let* ((pkg-dir-name (concat package-name "-" version))
+               (pkg-tmp-dir (expand-file-name pkg-dir-name tmp-dir))
+               (pkg-file (concat package-name "-pkg.el"))
+               (pkg-file-source (or (quelpa-build--find-source-file pkg-file files)
+                                    pkg-file))
+               (file-source (concat package-name ".el"))
+               (pkg-source (or (quelpa-build--find-source-file file-source files)
+                               file-source))
+               (pkg-info (quelpa-build--merge-package-info
+                          (let ((default-directory source-dir))
+                            (or (quelpa-build--get-pkg-file-info pkg-file-source)
+                                ;; some packages (like magit) provide name-pkg.el.in
+                                (quelpa-build--get-pkg-file-info
+                                 (expand-file-name (concat pkg-file ".in")
+                                                   (file-name-directory pkg-source)))
+                                (quelpa-build--get-package-info pkg-source)))
+                          package-name
+                          version)))
+          (quelpa-build--copy-package-files files source-dir pkg-tmp-dir)
+          (quelpa-build--write-pkg-file (expand-file-name
+                                         pkg-file
+                                         (file-name-as-directory pkg-tmp-dir))
+                                        pkg-info)
+
+          (quelpa-build--generate-info-files files source-dir pkg-tmp-dir)
+          (quelpa-build--generate-dir-file files pkg-tmp-dir)
+
+          (let ((default-directory tmp-dir))
+            (quelpa-build--create-tar
+             (expand-file-name (concat package-name "-" version ".tar")
+                               target-dir)
+             pkg-dir-name))
+
+          (let ((default-directory source-dir))
+            (quelpa-build--write-pkg-readme
+             target-dir
+             (quelpa-build--find-package-commentary pkg-source)
+             package-name))
+          (quelpa-build--archive-entry pkg-info 'tar))
+      (delete-directory tmp-dir t nil))))
+
+(defun quelpa-build--checkout-file (name config dir)
+  "Build according to a PATH with config CONFIG into DIR as NAME.
+Generic local file handler for package-build.el.
+
+Handles the following cases:
+
+local file:
+
+Installs a single-file package from a local file.  Use the :path
+attribute with a PATH like \"/path/to/file.el\".
+
+local directory:
+
+Installs a multi-file package from a local directory.  Use
+the :path attribute with a PATH like \"/path/to/dir\"."
+  (quelpa-check-hash name config (expand-file-name (plist-get config :path)) dir))
+
+(defun quelpa-build--checkout-url (name config dir)
+  "Build according to an URL with config CONFIG into DIR as NAME.
+Generic URL handler for package-build.el.
+
+Handles the following cases:
+
+local file:
+
+Installs a single-file package from a local file.  Use the :url
+attribute with an URL like \"file:///path/to/file.el\".
+
+remote file:
+
+Installs a single-file package from a remote file.  Use the :url
+attribute with an URL like \"http://domain.tld/path/to/file.el\"."
+  (let* ((url (plist-get config :url))
+         (remote-file-name (file-name-nondirectory
+                            (url-filename (url-generic-parse-url url))))
+         (local-path (expand-file-name remote-file-name dir))
+         (mm-attachment-file-modes (default-file-modes)))
+    (unless (string= (file-name-extension url) "el")
+      (error "<%s> does not end in .el" url))
+    (unless (file-directory-p dir)
+      (make-directory dir))
+    (url-copy-file url local-path t)
+    (quelpa-check-hash name config local-path dir 'url)))
+
+;; --- helpers ---------------------------------------------------------------
+
+(defun quelpa-message (wait format-string &rest args)
+  "Log a message with FORMAT-STRING and ARGS when `quelpa-verbose' is non-nil.
+If WAIT is nil don't wait after showing the message. If it is a
+number, wait so many seconds. If WAIT is t wait the default time.
+Return t in each case."
+  (when quelpa-verbose
+    (message "Quelpa: %s" (apply 'format format-string args))
+    (when (or (not noninteractive) wait) ; no wait if emacs is noninteractive
+      (sit-for (or (and (numberp wait) wait) 1.5) t)))
+  t)
+
+(defun quelpa-read-cache ()
+  "Read from `quelpa-persistent-cache-file' in `quelpa-cache'."
+  (when (and quelpa-persistent-cache-p
+             (file-exists-p quelpa-persistent-cache-file))
+    (with-temp-buffer
+      (insert-file-contents-literally quelpa-persistent-cache-file)
+      (setq quelpa-cache
+            (read (buffer-substring-no-properties (point-min) (point-max)))))))
+
+(defun quelpa-save-cache ()
+  "Write `quelpa-cache' to `quelpa-persistent-cache-file'."
+  (when quelpa-persistent-cache-p
+    (let (print-level print-length)
+      (with-temp-file quelpa-persistent-cache-file
+        (insert (prin1-to-string quelpa-cache))))))
+
+(defun quelpa-update-cache (cache-item)
+  ;; try removing existing recipes by name
+  (setq quelpa-cache (cl-remove (car cache-item)
+                                quelpa-cache :key #'car))
+  (push cache-item quelpa-cache)
+  (setq quelpa-cache
+        (cl-sort quelpa-cache #'string<
+                 :key (lambda (item) (symbol-name (car item))))))
+
+(defun quelpa-parse-stable (cache-item)
+  ;; in case :stable doesn't originate from PLIST, shadow the
+  ;; default value anyways
+  (when (plist-member (cdr cache-item) :stable)
+    (setq quelpa-stable-p (plist-get (cdr cache-item) :stable)))
+  (when (and quelpa-stable-p (not (plist-get (cdr cache-item) :stable)))
+    (setf (cdr (last cache-item)) '(:stable t))))
+
+(defun quelpa-checkout-melpa ()
+  "Fetch or update the melpa source code from Github.
+If there is no error return non-nil.
+If there is an error but melpa is already checked out return non-nil.
+If there is an error and no existing checkout return nil."
+  (or (and (null quelpa-update-melpa-p)
+           (file-exists-p (expand-file-name ".git" quelpa-melpa-dir)))
+      (condition-case err
+          (quelpa-build--checkout-git
+           'package-build
+           `(:url ,quelpa-melpa-repo-url :files ("*"))
+           quelpa-melpa-dir)
+        (error "failed to checkout melpa git repo: `%s'" (error-message-string err)))))
+
+(defun quelpa-get-melpa-recipe (name)
+  "Read recipe with NAME for melpa git checkout.
+Return the recipe if it exists, otherwise nil."
+  (cl-loop for store in quelpa-melpa-recipe-stores
+           if (stringp store)
+           for file = (assoc-string name (directory-files store nil "^[^\.]+"))
+           when file
+           return (with-temp-buffer
+                    (insert-file-contents-literally
+                     (expand-file-name file store))
+                    (read (buffer-string)))
+           else
+           for rcp = (assoc-string name store)
+           when rcp
+           return rcp))
+
+(defun quelpa-setup-p ()
+  "Setup what we need for quelpa.
+Return non-nil if quelpa has been initialized properly."
+  (catch 'quit
+    (dolist (dir (list quelpa-packages-dir quelpa-build-dir))
+      (unless (file-exists-p dir) (make-directory dir t)))
+    (unless quelpa-initialized-p
+      (quelpa-read-cache)
+      (quelpa-setup-package-structs)
+      (if quelpa-checkout-melpa-p
+          (unless (quelpa-checkout-melpa) (throw 'quit nil)))
+      (setq quelpa-initialized-p t))
+    t))
+
+(defun quelpa-shutdown ()
+  "Do things that need to be done after running quelpa."
+  (quelpa-save-cache)
+  ;; remove the packages dir because we are done with the built pkgs
+  (ignore-errors (delete-directory quelpa-packages-dir t)))
+
+(defun quelpa-arg-rcp (arg)
+  "Given recipe or package name, return an alist '(NAME . RCP).
+If RCP cannot be found it will be set to nil"
+  (pcase arg
+    (`(,a . nil) (quelpa-get-melpa-recipe (car arg)))
+    (`(,a . ,_) arg)
+    ((pred symbolp) (quelpa-get-melpa-recipe arg))))
+
+(defun quelpa-parse-plist (plist)
+  "Parse the optional PLIST argument of `quelpa'.
+Recognized keywords are:
+
+:upgrade
+
+If t, `quelpa' tries to do an upgrade.
+
+:stable
+
+If t, `quelpa' tries building the stable version of a package."
+  (while plist
+    (let ((key (car plist))
+          (value (cadr plist)))
+      (pcase key
+        (:upgrade (setq quelpa-upgrade-p value))
+        (:stable (setq quelpa-stable-p value))))
+    (setq plist (cddr plist))))
+
+(defun quelpa-package-install-file (file)
+  "Workaround problem with `package-install-file'.
+`package-install-file' uses `insert-file-contents-literally'
+which causes problems when the file inserted has crlf line
+endings (Windows). So here we replace that with
+`insert-file-contents' for non-tar files."
+  (if (eq system-type 'windows-nt)
+      (cl-letf* ((insert-file-contents-literally-orig
+                  (symbol-function 'insert-file-contents-literally))
+                 ((symbol-function 'insert-file-contents-literally)
+                  (lambda (file)
+                    (if (string-match "\\.tar\\'" file)
+                        (funcall insert-file-contents-literally-orig file)
+                      (insert-file-contents file)))))
+        (package-install-file file))
+    (package-install-file file)))
+
+(defun quelpa-package-install (arg)
+  "Build and install package from ARG (a recipe or package name).
+If the package has dependencies recursively call this function to
+install them."
+  (let* ((rcp (quelpa-arg-rcp arg))
+         (file (and rcp (quelpa-build rcp))))
+    (when file
+      (let* ((pkg-desc (quelpa-get-package-desc file))
+             (requires (package-desc-reqs pkg-desc)))
+        (when requires
+          (mapc (lambda (req)
+                  (unless (or (equal 'emacs (car req))
+                              (package-installed-p (car req) (cadr req)))
+                    (quelpa-package-install (car req))))
+                requires))
+        (quelpa-package-install-file file)))))
+
+(defun quelpa-interactive-candidate ()
+  "Query the user for a recipe and return the name."
+  (when (quelpa-setup-p)
+    (let  ((recipes (cl-loop
+                     for store in quelpa-melpa-recipe-stores
+                     if (stringp store)
+                     ;; this regexp matches all files except dotfiles
+                     append (directory-files store nil "^[^.].+$")
+                     else if (listp store)
+                     append store)))
+      (intern (completing-read "Choose MELPA recipe: "
+                               recipes nil t)))))
+
+;; --- public interface ------------------------------------------------------
+
+;;;###autoload
+(defun quelpa-expand-recipe (recipe-name)
+  "Expand a given recipe name into full recipe.
+If called interactively, let the user choose a recipe name and
+insert the result into the current buffer."
+  (interactive (list (quelpa-interactive-candidate)))
+  (when (quelpa-setup-p)
+    (let* ((recipe (quelpa-get-melpa-recipe recipe-name)))
+      (when recipe
+        (if (called-interactively-p 'any)
+            (prin1 recipe (current-buffer)))
+        recipe))))
+
+;;;###autoload
+(defun quelpa-self-upgrade (&optional args)
+  "Upgrade quelpa itself.
+ARGS are additional options for the quelpa recipe."
+  (interactive)
+  (when (quelpa-setup-p)
+    (quelpa (append quelpa-recipe args) :upgrade t)))
+
+;;;###autoload
+(defun quelpa-upgrade ()
+  "Upgrade all packages found in `quelpa-cache'.
+This provides an easy way to upgrade all the packages for which
+the `quelpa' command has been run in the current Emacs session."
+  (interactive)
+  (when (quelpa-setup-p)
+    (let ((quelpa-upgrade-p t))
+      (when quelpa-self-upgrade-p
+        (quelpa-self-upgrade))
+      (setq quelpa-cache
+            (cl-remove-if-not #'package-installed-p quelpa-cache :key #'car))
+      (mapc (lambda (item)
+              (when (package-installed-p (car (quelpa-arg-rcp item)))
+                (quelpa item)))
+            quelpa-cache))))
+
+;;;###autoload
+(defun quelpa (arg &rest plist)
+  "Build and install a package with quelpa.
+ARG can be a package name (symbol) or a melpa recipe (list).
+PLIST is a plist that may modify the build and/or fetch process.
+If called interactively, `quelpa' will prompt for a MELPA package
+to install.
+
+When `quelpa' is called interactively with a prefix argument (e.g
+C-u M-x quelpa) it will try to upgrade the given package even if
+the global var `quelpa-upgrade-p' is set to nil."
+
+  (interactive (list (quelpa-interactive-candidate)))
+  (run-hooks 'quelpa-before-hook)
+  (when (quelpa-setup-p) ;if init fails we do nothing
+    (let* ((quelpa-upgrade-p (if current-prefix-arg t quelpa-upgrade-p)) ;shadow `quelpa-upgrade-p'
+           (quelpa-stable-p quelpa-stable-p) ;shadow `quelpa-stable-p'
+           (cache-item (if (symbolp arg) (list arg) arg)))
+      (quelpa-parse-plist plist)
+      (quelpa-parse-stable cache-item)
+      (quelpa-package-install arg)
+      (quelpa-update-cache cache-item)))
+  (quelpa-shutdown)
+  (run-hooks 'quelpa-after-hook))
+
+(provide 'quelpa)
+
+;;; quelpa.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/quelpa-20180907.1832/quelpa.elc b/configs/shared/emacs/.emacs.d/elpa/quelpa-20180907.1832/quelpa.elc
new file mode 100644
index 0000000000..010c585bb8
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/quelpa-20180907.1832/quelpa.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/queue-0.2.signed b/configs/shared/emacs/.emacs.d/elpa/queue-0.2.signed
new file mode 100644
index 0000000000..44f0a5f8a6
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/queue-0.2.signed
@@ -0,0 +1 @@
+Good signature from 474F05837FBDEF9B GNU ELPA Signing Agent <elpasign@elpa.gnu.org> (trust undefined) created at 2017-08-16T17:10:01-0400 using DSA
\ No newline at end of file
diff --git a/configs/shared/emacs/.emacs.d/elpa/queue-0.2/queue-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/queue-0.2/queue-autoloads.el
new file mode 100644
index 0000000000..e70d42a32e
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/queue-0.2/queue-autoloads.el
@@ -0,0 +1,19 @@
+;;; queue-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "queue" "queue.el" (23377 61663 838924 577000))
+;;; Generated autoloads from queue.el
+
+(defalias 'make-queue 'queue-create "\
+Create an empty queue data structure.")
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; queue-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/queue-0.2/queue-pkg.el b/configs/shared/emacs/.emacs.d/elpa/queue-0.2/queue-pkg.el
new file mode 100644
index 0000000000..0bf617c2b2
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/queue-0.2/queue-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "queue" "0.2" "Queue data structure" 'nil :url "http://www.dr-qubit.org/emacs.php" :keywords '("extensions" "data structures" "queue"))
diff --git a/configs/shared/emacs/.emacs.d/elpa/queue-0.2/queue.el b/configs/shared/emacs/.emacs.d/elpa/queue-0.2/queue.el
new file mode 100644
index 0000000000..5c9a88bd7a
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/queue-0.2/queue.el
@@ -0,0 +1,192 @@
+;;; queue.el --- Queue data structure  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 1991-1995, 2008-2009, 2012, 2017  Free Software Foundation, Inc
+
+;; Author: Inge Wallin <inge@lysator.liu.se>
+;;         Toby Cubitt <toby-predictive@dr-qubit.org>
+;; Maintainer: Toby Cubitt <toby-predictive@dr-qubit.org>
+;; Version: 0.2
+;; Keywords: extensions, data structures, queue
+;; URL: http://www.dr-qubit.org/emacs.php
+;; Repository: http://www.dr-qubit.org/git/predictive.git
+
+;; This file is part of 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:
+;;
+;; These queues can be used both as a first-in last-out (FILO) and as a
+;; first-in first-out (FIFO) stack, i.e. elements can be added to the front or
+;; back of the queue, and can be removed from the front. (This type of data
+;; structure is sometimes called an "output-restricted deque".)
+;;
+;; You create a queue using `make-queue', add an element to the end of the
+;; queue using `queue-enqueue', and push an element onto the front of the
+;; queue using `queue-prepend'. To remove the first element from a queue, use
+;; `queue-dequeue'. A number of other queue convenience functions are also
+;; provided, all starting with the prefix `queue-'.  Functions with prefix
+;; `queue--' are for internal use only, and should never be used outside this
+;; package.
+
+
+;;; Code:
+
+(eval-when-compile (require 'cl))
+
+(defmacro queue--when-generators (then)
+  "Evaluate THEN if `generator' library is available."
+  (declare (debug t))
+  (if (require 'generator nil 'noerror) then))
+
+
+(defstruct (queue
+            ;; A tagged list is the pre-defstruct representation.
+            ;; (:type list)
+	    :named
+	    (:constructor nil)
+	    (:constructor queue-create ())
+	    (:copier nil))
+  head tail)
+
+
+;;;###autoload
+(defalias 'make-queue 'queue-create
+  "Create an empty queue data structure.")
+
+
+(defun queue-enqueue (queue element)
+  "Append an ELEMENT to the end of the QUEUE."
+  (if (queue-head queue)
+      (setcdr (queue-tail queue)
+	      (setf (queue-tail queue) (cons element nil)))
+    (setf (queue-head queue)
+	  (setf (queue-tail queue) (cons element nil)))))
+
+(defalias 'queue-append 'queue-enqueue)
+
+
+(defun queue-prepend (queue element)
+  "Prepend an ELEMENT to the front of the QUEUE."
+  (if (queue-head queue)
+      (push element (queue-head queue))
+    (setf (queue-head queue)
+	  (setf (queue-tail queue) (cons element nil)))))
+
+
+(defun queue-dequeue (queue)
+  "Remove the first element of QUEUE and return it.
+Returns nil if the queue is empty."
+  (unless (cdr (queue-head queue)) (setf (queue-tail queue) nil))
+  (pop (queue-head queue)))
+
+
+(defun queue-empty (queue)
+  "Return t if QUEUE is empty, otherwise return nil."
+  (null (queue-head queue)))
+
+
+(defun queue-first (queue)
+  "Return the first element of QUEUE or nil if it is empty,
+without removing it from the QUEUE."
+  (car (queue-head queue)))
+
+
+(defun queue-nth (queue n)
+  "Return the nth element of a queue, without removing it.
+If the length of the queue is less than N, return nil. The first
+element in the queue has index 0."
+  (nth n (queue-head queue)))
+
+
+(defun queue-last (queue)
+  "Return the last element of QUEUE, without removing it.
+Returns nil if the QUEUE is empty."
+  (car (queue-tail queue)))
+
+
+(defun queue-all (queue)
+  "Return a list of all elements of QUEUE or nil if it is empty.
+The oldest element in the queue is the first in the list."
+  (queue-head queue))
+
+
+(defun queue-copy (queue)
+  "Return a copy of QUEUE.
+The new queue contains the elements of QUEUE in the same
+order. The elements themselves are *not* copied."
+  (let ((q (queue-create))
+	(list (queue-head queue)))
+    (when (queue-head queue)
+      (setf (queue-head q) (cons (car (queue-head queue)) nil)
+	    (queue-tail q) (queue-head q))
+      (while (setq list (cdr list))
+	(setf (queue-tail q)
+	      (setcdr (queue-tail q) (cons (car list) nil)))))
+    q))
+
+
+(defun queue-length (queue)
+  "Return the number of elements in QUEUE."
+  (length (queue-head queue)))
+
+
+(defun queue-clear (queue)
+  "Remove all elements from QUEUE."
+  (setf (queue-head queue) nil
+	(queue-tail queue) nil))
+
+
+(queue--when-generators
+ (iter-defun queue-iter (queue)
+   "Return a queue iterator object.
+
+Calling `iter-next' on this object will retrieve the next element
+from the queue. The queue itself is not modified."
+   (let ((list (queue-head queue)))
+     (while list (iter-yield (pop list))))))
+
+;;;; ChangeLog:
+
+;; 2017-08-16  Toby S. Cubitt  <tsc25@cantab.net>
+;; 
+;; 	Upgrade data structure packages to latest versions.
+;; 
+;; 2014-05-15  Toby S. Cubitt  <tsc25@cantab.net>
+;; 
+;; 	queue.el: fix buggy queue-first and queue-empty definitions.
+;; 
+;; 2012-04-30  Toby S. Cubitt  <tsc25@cantab.net>
+;; 
+;; 	Minor fixes to commentaries, package headers, and whitespace
+;; 
+;; 	* queue.el: fix description of data structure in Commentary; add
+;; 	Maintainer
+;; 	 header.
+;; 
+;; 	* queue.el, heap.el, tNFA.el, trie.el, dict-tree.el: trivial whitespace
+;; 	fixes.
+;; 
+;; 2012-04-29  Toby S. Cubitt  <tsc25@cantab.net>
+;; 
+;; 	Add queue.el
+;; 
+
+
+
+(provide 'queue)
+
+
+;;; queue.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/queue-0.2/queue.elc b/configs/shared/emacs/.emacs.d/elpa/queue-0.2/queue.elc
new file mode 100644
index 0000000000..335814861b
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/queue-0.2/queue.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/request-20170131.1747/request-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/request-20170131.1747/request-autoloads.el
new file mode 100644
index 0000000000..df484ac09e
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/request-20170131.1747/request-autoloads.el
@@ -0,0 +1,15 @@
+;;; request-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil nil ("request.el") (23377 61591 51185 699000))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; request-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/request-20170131.1747/request-pkg.el b/configs/shared/emacs/.emacs.d/elpa/request-20170131.1747/request-pkg.el
new file mode 100644
index 0000000000..6ce938789f
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/request-20170131.1747/request-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "request" "20170131.1747" "Compatible layer for URL request in Emacs" '((emacs "24.4")))
diff --git a/configs/shared/emacs/.emacs.d/elpa/request-20170131.1747/request.el b/configs/shared/emacs/.emacs.d/elpa/request-20170131.1747/request.el
new file mode 100644
index 0000000000..815745fecf
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/request-20170131.1747/request.el
@@ -0,0 +1,1224 @@
+;;; request.el --- Compatible layer for URL request in Emacs -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2012 Takafumi Arakaki
+;; Copyright (C) 1985-1986, 1992, 1994-1995, 1999-2012
+;;   Free Software Foundation, Inc.
+
+;; Author: Takafumi Arakaki <aka.tkf at gmail.com>
+;; Package-Requires: ((emacs "24.4"))
+;; Package-Version: 20170131.1747
+;; Version: 0.3.0
+
+;; This file is NOT part of GNU Emacs.
+
+;; request.el 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.
+
+;; request.el 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 request.el.
+;; If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Request.el is a HTTP request library with multiple backends.  It
+;; supports url.el which is shipped with Emacs and curl command line
+;; program.  User can use curl when s/he has it, as curl is more reliable
+;; than url.el.  Library author can use request.el to avoid imposing
+;; external dependencies such as curl to users while giving richer
+;; experience for users who have curl.
+
+;; Following functions are adapted from GNU Emacs source code.
+;; Free Software Foundation holds the copyright of them.
+;; * `request--process-live-p'
+;; * `request--url-default-expander'
+
+;;; Code:
+
+(eval-when-compile
+  (defvar url-http-method)
+  (defvar url-http-response-status))
+
+(require 'cl-lib)
+(require 'url)
+(require 'mail-utils)
+
+(defgroup request nil
+  "Compatible layer for URL request in Emacs."
+  :group 'comm
+  :prefix "request-")
+
+(defconst request-version "0.3.0")
+
+
+;;; Customize variables
+
+(defcustom request-storage-directory
+  (concat (file-name-as-directory user-emacs-directory) "request")
+  "Directory to store data related to request.el."
+  :type 'directory)
+
+(defcustom request-curl "curl"
+  "Executable for curl command."
+  :type 'string)
+
+(defcustom request-curl-options nil
+  "curl command options.
+
+List of strings that will be passed to every curl invocation. You can pass
+extra options here, like setting the proxy."
+  :type '(repeat string))
+
+(defcustom request-backend (if (executable-find request-curl)
+                               'curl
+                             'url-retrieve)
+  "Backend to be used for HTTP request.
+Automatically set to `curl' if curl command is found."
+  :type '(choice (const :tag "cURL backend" curl)
+                 (const :tag "url-retrieve backend" url-retrieve)))
+
+(defcustom request-timeout nil
+  "Default request timeout in second.
+`nil' means no timeout."
+  :type '(choice (integer :tag "Request timeout seconds")
+                 (boolean :tag "No timeout" nil)))
+
+(defcustom request-temp-prefix "emacs-request"
+  "Prefix for temporary files created by Request."
+  :type 'string
+  :risky t)
+
+(defcustom request-log-level -1
+  "Logging level for request.
+One of `error'/`warn'/`info'/`verbose'/`debug'.
+-1 means no logging."
+  :type '(choice (integer :tag "No logging" -1)
+                 (const :tag "Level error" error)
+                 (const :tag "Level warn" warn)
+                 (const :tag "Level info" info)
+                 (const :tag "Level Verbose" verbose)
+                 (const :tag "Level DEBUG" debug)))
+
+(defcustom request-message-level 'warn
+  "Logging level for request.
+See `request-log-level'."
+  :type '(choice (integer :tag "No logging" -1)
+                 (const :tag "Level error" error)
+                 (const :tag "Level warn" warn)
+                 (const :tag "Level info" info)
+                 (const :tag "Level Verbose" verbose)
+                 (const :tag "Level DEBUG" debug)))
+
+
+;;; Utilities
+
+(defun request--safe-apply (function &rest arguments)
+  (condition-case err
+      (apply #'apply function arguments)
+    ((debug error))))
+
+(defun request--safe-call (function &rest arguments)
+  (request--safe-apply function arguments))
+
+;; (defun request--url-no-cache (url)
+;;   "Imitate `cache=false' of `jQuery.ajax'.
+;; See: http://api.jquery.com/jQuery.ajax/"
+;;   ;; FIXME: parse URL before adding ?_=TIME.
+;;   (concat url (format-time-string "?_=%s")))
+
+(defmacro request--document-function (function docstring)
+  "Document FUNCTION with DOCSTRING.  Use this for defstruct accessor etc."
+  (declare (indent defun)
+           (doc-string 2))
+  `(put ',function 'function-documentation ,docstring))
+
+(defun request--process-live-p (process)
+  "Copied from `process-live-p' for backward compatibility (Emacs < 24).
+Adapted from lisp/subr.el.
+FSF holds the copyright of this function:
+  Copyright (C) 1985-1986, 1992, 1994-1995, 1999-2012
+    Free Software Foundation, Inc."
+  (memq (process-status process) '(run open listen connect stop)))
+
+
+;;; Logging
+
+(defconst request--log-level-def
+  '(;; debugging
+    (blather . 60) (trace . 50) (debug . 40)
+    ;; information
+    (verbose . 30) (info . 20)
+    ;; errors
+    (warn . 10) (error . 0))
+  "Named logging levels.")
+
+(defun request--log-level-as-int (level)
+  (if (integerp level)
+      level
+    (or (cdr (assq level request--log-level-def))
+        0)))
+
+(defvar request-log-buffer-name " *request-log*")
+
+(defun request--log-buffer ()
+  (get-buffer-create request-log-buffer-name))
+
+(defmacro request-log (level fmt &rest args)
+  (declare (indent 1))
+  `(let ((level (request--log-level-as-int ,level))
+         (log-level (request--log-level-as-int request-log-level))
+         (msg-level (request--log-level-as-int request-message-level)))
+     (when (<= level (max log-level msg-level))
+       (let ((msg (format "[%s] %s" ,level
+                          (condition-case err
+                              (format ,fmt ,@args)
+                            (error (format "
+!!! Logging error while executing:
+%S
+!!! Error:
+%S"
+                                           ',args err))))))
+         (when (<= level log-level)
+           (with-current-buffer (request--log-buffer)
+             (setq buffer-read-only t)
+             (let ((inhibit-read-only t))
+               (goto-char (point-max))
+               (insert msg "\n"))))
+         (when (<= level msg-level)
+           (message "REQUEST %s" msg))))))
+
+
+;;; HTTP specific utilities
+
+(defconst request--url-unreserved-chars
+  '(?a ?b ?c ?d ?e ?f ?g ?h ?i ?j ?k ?l ?m ?n ?o ?p ?q ?r ?s ?t ?u ?v ?w ?x ?y ?z
+    ?A ?B ?C ?D ?E ?F ?G ?H ?I ?J ?K ?L ?M ?N ?O ?P ?Q ?R ?S ?T ?U ?V ?W ?X ?Y ?Z
+    ?0 ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9
+    ?- ?_ ?. ?~)
+  "`url-unreserved-chars' copied from Emacs 24.3 release candidate.
+This is used for making `request--urlencode-alist' RFC 3986 compliant
+for older Emacs versions.")
+
+(defun request--urlencode-alist (alist)
+  ;; FIXME: make monkey patching `url-unreserved-chars' optional
+  (let ((url-unreserved-chars request--url-unreserved-chars))
+    (cl-loop for sep = "" then "&"
+             for (k . v) in alist
+             concat sep
+             concat (url-hexify-string (format "%s" k))
+             concat "="
+             concat (url-hexify-string (format "%s" v)))))
+
+
+;;; Header parser
+
+(defun request--parse-response-at-point ()
+  "Parse the first header line such as \"HTTP/1.1 200 OK\"."
+  (when (re-search-forward "\\=[ \t\n]*HTTP/\\([0-9\\.]+\\) +\\([0-9]+\\)" nil t)
+    (list :version (match-string 1)
+          :code (string-to-number (match-string 2)))))
+
+(defun request--goto-next-body ()
+  (re-search-forward "^\r\n"))
+
+
+;;; Response object
+
+(cl-defstruct request-response
+  "A structure holding all relevant information of a request."
+  status-code history data error-thrown symbol-status url
+  done-p settings
+  ;; internal variables
+  -buffer -raw-header -timer -backend -tempfiles)
+
+(defmacro request--document-response (function docstring)
+  (declare (indent defun)
+           (doc-string 2))
+  `(request--document-function ,function ,(concat docstring "
+
+.. This is an accessor for `request-response' object.
+
+\(fn RESPONSE)")))
+
+(request--document-response request-response-status-code
+  "Integer HTTP response code (e.g., 200).")
+
+(request--document-response request-response-history
+  "Redirection history (a list of response object).
+The first element is the oldest redirection.
+
+You can use restricted portion of functions for the response
+objects in the history slot.  It also depends on backend.  Here
+is the table showing what functions you can use for the response
+objects in the history slot.
+
+==================================== ============== ==============
+Slots                                          Backends
+------------------------------------ -----------------------------
+\\                                    curl           url-retrieve
+==================================== ============== ==============
+request-response-url                  yes            yes
+request-response-header               yes            no
+other functions                       no             no
+==================================== ============== ==============
+")
+
+(request--document-response request-response-data
+  "Response parsed by the given parser.")
+
+(request--document-response request-response-error-thrown
+  "Error thrown during request.
+It takes the form of ``(ERROR-SYMBOL . DATA)``, which can be
+re-raised (`signal'ed) by ``(signal ERROR-SYMBOL DATA)``.")
+
+(request--document-response request-response-symbol-status
+  "A symbol representing the status of request (not HTTP response code).
+One of success/error/timeout/abort/parse-error.")
+
+(request--document-response request-response-url
+  "Final URL location of response.")
+
+(request--document-response request-response-done-p
+  "Return t when the request is finished or aborted.")
+
+(request--document-response request-response-settings
+  "Keyword arguments passed to `request' function.
+Some arguments such as HEADERS is changed to the one actually
+passed to the backend.  Also, it has additional keywords such
+as URL which is the requested URL.")
+
+(defun request-response-header (response field-name)
+  "Fetch the values of RESPONSE header field named FIELD-NAME.
+
+It returns comma separated values when the header has multiple
+field with the same name, as :RFC:`2616` specifies.
+
+Examples::
+
+  (request-response-header response
+                           \"content-type\") ; => \"text/html; charset=utf-8\"
+  (request-response-header response
+                           \"unknown-field\") ; => nil
+"
+  (let ((raw-header (request-response--raw-header response)))
+    (when raw-header
+      (with-temp-buffer
+        (erase-buffer)
+        (insert raw-header)
+        ;; ALL=t to fetch all fields with the same name to get comma
+        ;; separated value [#rfc2616-sec4]_.
+        (mail-fetch-field field-name nil t)))))
+;; .. [#rfc2616-sec4] RFC2616 says this is the right thing to do
+;;    (see http://tools.ietf.org/html/rfc2616.html#section-4.2).
+;;    Python's requests module does this too.
+
+
+;;; Backend dispatcher
+
+(defconst request--backend-alist
+  '((url-retrieve
+     . ((request             . request--url-retrieve)
+        (request-sync        . request--url-retrieve-sync)
+        (terminate-process   . delete-process)
+        (get-cookies         . request--url-retrieve-get-cookies)))
+    (curl
+     . ((request             . request--curl)
+        (request-sync        . request--curl-sync)
+        (terminate-process   . interrupt-process)
+        (get-cookies         . request--curl-get-cookies))))
+  "Map backend and method name to actual method (symbol).
+
+It's alist of alist, of the following form::
+
+    ((BACKEND . ((METHOD . FUNCTION) ...)) ...)
+
+It would be nicer if I can use EIEIO.  But as CEDET is included
+in Emacs by 23.2, using EIEIO means abandon older Emacs versions.
+It is probably necessary if I need to support more backends.  But
+let's stick to manual dispatch for now.")
+;; See: (view-emacs-news "23.2")
+
+(defun request--choose-backend (method)
+  "Return `fucall'able object for METHOD of current `request-backend'."
+  (assoc-default
+   method
+   (or (assoc-default request-backend request--backend-alist)
+       (error "%S is not valid `request-backend'." request-backend))))
+
+
+;;; Cookie
+
+(defun request-cookie-string (host &optional localpart secure)
+  "Return cookie string (like `document.cookie').
+
+Example::
+
+ (request-cookie-string \"127.0.0.1\" \"/\")  ; => \"key=value; key2=value2\"
+"
+  (mapconcat (lambda (nv) (concat (car nv) "=" (cdr nv)))
+             (request-cookie-alist host localpart secure)
+             "; "))
+
+(defun request-cookie-alist (host &optional localpart secure)
+  "Return cookies as an alist.
+
+Example::
+
+ (request-cookie-alist \"127.0.0.1\" \"/\")  ; => ((\"key\" . \"value\") ...)
+"
+  (funcall (request--choose-backend 'get-cookies) host localpart secure))
+
+
+;;; Main
+
+(cl-defun request-default-error-callback (url &key symbol-status
+                                              &allow-other-keys)
+  (request-log 'error
+    "Error (%s) while connecting to %s." symbol-status url))
+
+(cl-defun request (url &rest settings
+                       &key
+                       (type "GET")
+                       (params nil)
+                       (data nil)
+                       (files nil)
+                       (parser nil)
+                       (headers nil)
+                       (success nil)
+                       (error nil)
+                       (complete nil)
+                       (timeout request-timeout)
+                       (status-code nil)
+                       (sync nil)
+                       (response (make-request-response))
+                       (unix-socket nil))
+  "Send request to URL.
+
+Request.el has a single entry point.  It is `request'.
+
+==================== ========================================================
+Keyword argument      Explanation
+==================== ========================================================
+TYPE       (string)   type of request to make: POST/GET/PUT/DELETE
+PARAMS      (alist)   set \"?key=val\" part in URL
+DATA (string/alist)   data to be sent to the server
+FILES       (alist)   files to be sent to the server (see below)
+PARSER     (symbol)   a function that reads current buffer and return data
+HEADERS     (alist)   additional headers to send with the request
+SUCCESS  (function)   called on success
+ERROR    (function)   called on error
+COMPLETE (function)   called on both success and error
+TIMEOUT    (number)   timeout in second
+STATUS-CODE (alist)   map status code (int) to callback
+SYNC         (bool)   If `t', wait until request is done.  Default is `nil'.
+==================== ========================================================
+
+
+* Callback functions
+
+Callback functions STATUS, ERROR, COMPLETE and `cdr's in element of
+the alist STATUS-CODE take same keyword arguments listed below.  For
+forward compatibility, these functions must ignore unused keyword
+arguments (i.e., it's better to use `&allow-other-keys' [#]_).::
+
+    (CALLBACK                      ; SUCCESS/ERROR/COMPLETE/STATUS-CODE
+     :data          data           ; whatever PARSER function returns, or nil
+     :error-thrown  error-thrown   ; (ERROR-SYMBOL . DATA), or nil
+     :symbol-status symbol-status  ; success/error/timeout/abort/parse-error
+     :response      response       ; request-response object
+     ...)
+
+.. [#] `&allow-other-keys' is a special \"markers\" available in macros
+   in the CL library for function definition such as `cl-defun' and
+   `cl-function'.  Without this marker, you need to specify all arguments
+   to be passed.  This becomes problem when request.el adds new arguments
+   when calling callback functions.  If you use `&allow-other-keys'
+   (or manually ignore other arguments), your code is free from this
+   problem.  See info node `(cl) Argument Lists' for more information.
+
+Arguments data, error-thrown, symbol-status can be accessed by
+`request-response-data', `request-response-error-thrown',
+`request-response-symbol-status' accessors, i.e.::
+
+    (request-response-data RESPONSE)  ; same as data
+
+Response object holds other information which can be accessed by
+the following accessors:
+`request-response-status-code',
+`request-response-url' and
+`request-response-settings'
+
+* STATUS-CODE callback
+
+STATUS-CODE is an alist of the following format::
+
+    ((N-1 . CALLBACK-1)
+     (N-2 . CALLBACK-2)
+     ...)
+
+Here, N-1, N-2,... are integer status codes such as 200.
+
+
+* FILES
+
+FILES is an alist of the following format::
+
+    ((NAME-1 . FILE-1)
+     (NAME-2 . FILE-2)
+     ...)
+
+where FILE-N is a list of the form::
+
+    (FILENAME &key PATH BUFFER STRING MIME-TYPE)
+
+FILE-N can also be a string (path to the file) or a buffer object.
+In that case, FILENAME is set to the file name or buffer name.
+
+Example FILES argument::
+
+    `((\"passwd\"   . \"/etc/passwd\")                ; filename = passwd
+      (\"scratch\"  . ,(get-buffer \"*scratch*\"))    ; filename = *scratch*
+      (\"passwd2\"  . (\"password.txt\" :file \"/etc/passwd\"))
+      (\"scratch2\" . (\"scratch.txt\"  :buffer ,(get-buffer \"*scratch*\")))
+      (\"data\"     . (\"data.csv\"     :data \"1,2,3\\n4,5,6\\n\")))
+
+.. note:: FILES is implemented only for curl backend for now.
+   As furl.el_ supports multipart POST, it should be possible to
+   support FILES in pure elisp by making furl.el_ another backend.
+   Contributions are welcome.
+
+   .. _furl.el: http://code.google.com/p/furl-el/
+
+
+* PARSER function
+
+PARSER function takes no argument and it is executed in the
+buffer with HTTP response body.  The current position in the HTTP
+response buffer is at the beginning of the buffer.  As the HTTP
+header is stripped off, the cursor is actually at the beginning
+of the response body.  So, for example, you can pass `json-read'
+to parse JSON object in the buffer.  To fetch whole response as a
+string, pass `buffer-string'.
+
+When using `json-read', it is useful to know that the returned
+type can be modified by `json-object-type', `json-array-type',
+`json-key-type', `json-false' and `json-null'.  See docstring of
+each function for what it does.  For example, to convert JSON
+objects to plist instead of alist, wrap `json-read' by `lambda'
+like this.::
+
+    (request
+     \"http://...\"
+     :parser (lambda ()
+               (let ((json-object-type 'plist))
+                 (json-read)))
+     ...)
+
+This is analogous to the `dataType' argument of jQuery.ajax_.
+Only this function can access to the process buffer, which
+is killed immediately after the execution of this function.
+
+* SYNC
+
+Synchronous request is functional, but *please* don't use it
+other than testing or debugging.  Emacs users have better things
+to do rather than waiting for HTTP request.  If you want a better
+way to write callback chains, use `request-deferred'.
+
+If you can't avoid using it (e.g., you are inside of some hook
+which must return some value), make sure to set TIMEOUT to
+relatively small value.
+
+Due to limitation of `url-retrieve-synchronously', response slots
+`request-response-error-thrown', `request-response-history' and
+`request-response-url' are unknown (always `nil') when using
+synchronous request with `url-retrieve' backend.
+
+* Note
+
+API of `request' is somewhat mixture of jQuery.ajax_ (Javascript)
+and requests.request_ (Python).
+
+.. _jQuery.ajax: http://api.jquery.com/jQuery.ajax/
+.. _requests.request: http://docs.python-requests.org
+"
+  (request-log 'debug "REQUEST")
+  ;; FIXME: support CACHE argument (if possible)
+  ;; (unless cache
+  ;;   (setq url (request--url-no-cache url)))
+  (unless error
+    (setq error (apply-partially #'request-default-error-callback url))
+    (setq settings (plist-put settings :error error)))
+  (unless (or (stringp data)
+              (null data)
+              (assoc-string "Content-Type" headers t))
+    (setq data (request--urlencode-alist data))
+    (setq settings (plist-put settings :data data)))
+  (when params
+    (cl-assert (listp params) nil "PARAMS must be an alist.  Given: %S" params)
+    (setq url (concat url (if (string-match-p "\\?" url) "&" "?")
+                      (request--urlencode-alist params))))
+  (setq settings (plist-put settings :url url))
+  (setq settings (plist-put settings :response response))
+  (setf (request-response-settings response) settings)
+  (setf (request-response-url      response) url)
+  (setf (request-response--backend response) request-backend)
+  ;; Call `request--url-retrieve'(`-sync') or `request--curl'(`-sync').
+  (apply (if sync
+             (request--choose-backend 'request-sync)
+           (request--choose-backend 'request))
+         url settings)
+  (when timeout
+    (request-log 'debug "Start timer: timeout=%s sec" timeout)
+    (setf (request-response--timer response)
+          (run-at-time timeout nil
+                       #'request-response--timeout-callback response)))
+  response)
+
+(defun request--clean-header (response)
+  "Strip off carriage returns in the header of REQUEST."
+  (request-log 'debug "-CLEAN-HEADER")
+  (let ((buffer       (request-response--buffer      response))
+        (backend      (request-response--backend     response))
+        sep-regexp)
+    (if (eq backend 'url-retrieve)
+        ;; FIXME: make this workaround optional.
+        ;; But it looks like sometimes `url-http-clean-headers'
+        ;; fails to cleanup.  So, let's be bit permissive here...
+        (setq sep-regexp "^\r?$")
+      (setq sep-regexp "^\r$"))
+    (when (buffer-live-p buffer)
+      (with-current-buffer buffer
+        (request-log 'trace
+          "(buffer-string) at %S =\n%s" buffer (buffer-string))
+        (goto-char (point-min))
+        (when (and (re-search-forward sep-regexp nil t)
+                   ;; Are \r characters stripped off already?:
+                   (not (equal (match-string 0) "")))
+          (while (re-search-backward "\r$" (point-min) t)
+            (replace-match "")))))))
+
+(defun request--cut-header (response)
+  "Cut the first header part in the buffer of RESPONSE and move it to
+raw-header slot."
+  (request-log 'debug "-CUT-HEADER")
+  (let ((buffer (request-response--buffer response)))
+    (when (buffer-live-p buffer)
+      (with-current-buffer buffer
+        (goto-char (point-min))
+        (when (re-search-forward "^$" nil t)
+          (setf (request-response--raw-header response)
+                (buffer-substring (point-min) (point)))
+          (delete-region (point-min) (min (1+ (point)) (point-max))))))))
+
+(defun request-untrampify-filename (file)
+  "Return FILE as the local file name."
+  (or (file-remote-p file 'localname) file))
+
+(defun request--parse-data (response parser)
+  "Run PARSER in current buffer if ERROR-THROWN is nil,
+then kill the current buffer."
+  (request-log 'debug "-PARSE-DATA")
+  (let ((buffer (request-response--buffer response)))
+    (request-log 'debug "parser = %s" parser)
+    (when (and (buffer-live-p buffer) parser)
+      (with-current-buffer buffer
+        (request-log 'trace
+          "(buffer-string) at %S =\n%s" buffer (buffer-string))
+        (when (/= (request-response-status-code response) 204)
+          (goto-char (point-min))
+          (setf (request-response-data response) (funcall parser)))))))
+
+(cl-defun request--callback (buffer &key parser success error complete
+                                    timeout status-code response
+                                    &allow-other-keys)
+  (request-log 'debug "REQUEST--CALLBACK")
+  (request-log 'debug "(buffer-string) =\n%s"
+               (when (buffer-live-p buffer)
+                 (with-current-buffer buffer (buffer-string))))
+
+  ;; Sometimes BUFFER given as the argument is different from the
+  ;; buffer already set in RESPONSE.  That's why it is reset here.
+  ;; FIXME: Refactor how BUFFER is passed around.
+  (setf (request-response--buffer response) buffer)
+  (request-response--cancel-timer response)
+  (cl-symbol-macrolet
+      ((error-thrown (request-response-error-thrown response))
+       (symbol-status (request-response-symbol-status response))
+       (data (request-response-data response))
+       (done-p (request-response-done-p response)))
+
+    ;; Parse response header
+    (request--clean-header response)
+    (request--cut-header response)
+    ;; Note: Try to do this even `error-thrown' is set.  For example,
+    ;; timeout error can occur while downloading response body and
+    ;; header is there in that case.
+
+    ;; Parse response body
+    (request-log 'debug "error-thrown = %S" error-thrown)
+    (condition-case err
+        (request--parse-data response parser)
+      (error
+       ;; If there was already an error (e.g. server timeout) do not set the
+       ;; status to `parse-error'.
+       (unless error-thrown
+         (setq symbol-status 'parse-error)
+         (setq error-thrown err)
+         (request-log 'error "Error from parser %S: %S" parser err))))
+    (kill-buffer buffer)
+    (request-log 'debug "data = %s" data)
+
+    ;; Determine `symbol-status'
+    (unless symbol-status
+      (setq symbol-status (if error-thrown 'error 'success)))
+    (request-log 'debug "symbol-status = %s" symbol-status)
+
+    ;; Call callbacks
+    (let ((args (list :data data
+                      :symbol-status symbol-status
+                      :error-thrown error-thrown
+                      :response response)))
+      (let* ((success-p (eq symbol-status 'success))
+             (cb (if success-p success error))
+             (name (if success-p "success" "error")))
+        (when cb
+          (request-log 'debug "Executing %s callback." name)
+          (request--safe-apply cb args)))
+
+      (let ((cb (cdr (assq (request-response-status-code response)
+                           status-code))))
+        (when cb
+          (request-log 'debug "Executing status-code callback.")
+          (request--safe-apply cb args)))
+
+      (when complete
+        (request-log 'debug "Executing complete callback.")
+        (request--safe-apply complete args)))
+
+    (setq done-p t)
+
+    ;; Remove temporary files
+    ;; FIXME: Make tempfile cleanup more reliable.  It is possible
+    ;;        callback is never called.
+    (request--safe-delete-files (request-response--tempfiles response))))
+
+(cl-defun request-response--timeout-callback (response)
+  (request-log 'debug "-TIMEOUT-CALLBACK")
+  (setf (request-response-symbol-status response) 'timeout)
+  (setf (request-response-error-thrown response)  '(error . ("Timeout")))
+  (let* ((buffer (request-response--buffer response))
+         (proc (and (buffer-live-p buffer) (get-buffer-process buffer))))
+    (when proc
+      ;; This will call `request--callback':
+      (funcall (request--choose-backend 'terminate-process) proc))
+
+    (cl-symbol-macrolet ((done-p (request-response-done-p response)))
+      (unless done-p
+        ;; This code should never be executed.  However, it occurs
+        ;; sometimes with `url-retrieve' backend.
+        ;; FIXME: In Emacs 24.3.50 or later, this is always executed in
+        ;;        request-get-timeout test.  Find out if it is fine.
+        (request-log 'error "Callback is not called when stopping process! \
+Explicitly calling from timer.")
+        (when (buffer-live-p buffer)
+          (cl-destructuring-bind (&key code &allow-other-keys)
+              (with-current-buffer buffer
+                (goto-char (point-min))
+                (request--parse-response-at-point))
+            (setf (request-response-status-code response) code)))
+        (apply #'request--callback
+               buffer
+               (request-response-settings response))
+        (setq done-p t)))))
+
+(defun request-response--cancel-timer (response)
+  (request-log 'debug "REQUEST-RESPONSE--CANCEL-TIMER")
+  (cl-symbol-macrolet ((timer (request-response--timer response)))
+    (when timer
+      (cancel-timer timer)
+      (setq timer nil))))
+
+
+(defun request-abort (response)
+  "Abort request for RESPONSE (the object returned by `request').
+Note that this function invoke ERROR and COMPLETE callbacks.
+Callbacks may not be called immediately but called later when
+associated process is exited."
+  (cl-symbol-macrolet ((buffer (request-response--buffer response))
+                       (symbol-status (request-response-symbol-status response))
+                       (done-p (request-response-done-p response)))
+    (let ((process (get-buffer-process buffer)))
+      (unless symbol-status             ; should I use done-p here?
+        (setq symbol-status 'abort)
+        (setq done-p t)
+        (when (and
+               (processp process) ; process can be nil when buffer is killed
+               (request--process-live-p process))
+          (funcall (request--choose-backend 'terminate-process) process))))))
+
+
+;;; Backend: `url-retrieve'
+
+(cl-defun request--url-retrieve-preprocess-settings
+    (&rest settings &key type data files headers &allow-other-keys)
+  (when files
+    (error "`url-retrieve' backend does not support FILES."))
+  (when (and (equal type "POST")
+             data
+             (not (assoc-string "Content-Type" headers t)))
+    (push '("Content-Type" . "application/x-www-form-urlencoded") headers)
+    (setq settings (plist-put settings :headers headers)))
+  settings)
+
+(cl-defun request--url-retrieve (url &rest settings
+                                     &key type data timeout response
+                                     &allow-other-keys
+                                     &aux headers)
+  (setq settings (apply #'request--url-retrieve-preprocess-settings settings))
+  (setq headers (plist-get settings :headers))
+  (let* ((url-request-extra-headers headers)
+         (url-request-method type)
+         (url-request-data data)
+         (buffer (url-retrieve url #'request--url-retrieve-callback
+                               (nconc (list :response response) settings)))
+         (proc (get-buffer-process buffer)))
+    (setf (request-response--buffer response) buffer)
+    (process-put proc :request-response response)
+    (request-log 'debug "Start querying: %s" url)
+    (set-process-query-on-exit-flag proc nil)))
+
+(cl-defun request--url-retrieve-callback (status &rest settings
+                                                 &key response url
+                                                 &allow-other-keys)
+  (declare (special url-http-method
+                    url-http-response-status))
+  (request-log 'debug "-URL-RETRIEVE-CALLBACK")
+  (request-log 'debug "status = %S" status)
+  (request-log 'debug "url-http-method = %s" url-http-method)
+  (request-log 'debug "url-http-response-status = %s" url-http-response-status)
+
+  (setf (request-response-status-code response) url-http-response-status)
+  (let ((redirect (plist-get status :redirect)))
+    (when redirect
+      (setf (request-response-url response) redirect)))
+  ;; Construct history slot
+  (cl-loop for v in
+           (cl-loop with first = t
+                    with l = nil
+                    for (k v) on status by 'cddr
+                    when (eq k :redirect)
+                    if first
+                    do (setq first nil)
+                    else
+                    do (push v l)
+                    finally do (cons url l))
+           do (let ((r (make-request-response :-backend 'url-retrieve)))
+                (setf (request-response-url r) v)
+                (push r (request-response-history response))))
+
+  (cl-symbol-macrolet ((error-thrown (request-response-error-thrown response))
+                       (status-error (plist-get status :error)))
+    (when (and error-thrown status-error)
+      (request-log 'warn
+        "Error %S thrown already but got another error %S from \
+`url-retrieve'.  Ignoring it..." error-thrown status-error))
+    (unless error-thrown
+      (setq error-thrown status-error)))
+
+  (apply #'request--callback (current-buffer) settings))
+
+(cl-defun request--url-retrieve-sync (url &rest settings
+                                          &key type data timeout response
+                                          &allow-other-keys
+                                          &aux headers)
+  (setq settings (apply #'request--url-retrieve-preprocess-settings settings))
+  (setq headers (plist-get settings :headers))
+  (let* ((url-request-extra-headers headers)
+         (url-request-method type)
+         (url-request-data data)
+         (buffer (if timeout
+                     (with-timeout
+                         (timeout
+                          (setf (request-response-symbol-status response)
+                                'timeout)
+                          (setf (request-response-done-p response) t)
+                          nil)
+                       (url-retrieve-synchronously url))
+                   (url-retrieve-synchronously url))))
+    (setf (request-response--buffer response) buffer)
+    ;; It seems there is no way to get redirects and URL here...
+    (when buffer
+      ;; Fetch HTTP response code
+      (with-current-buffer buffer
+        (goto-char (point-min))
+        (cl-destructuring-bind (&key version code)
+            (request--parse-response-at-point)
+          (setf (request-response-status-code response) code)))
+      ;; Parse response body, etc.
+      (apply #'request--callback buffer settings)))
+  response)
+
+(defun request--url-retrieve-get-cookies (host localpart secure)
+  (mapcar
+   (lambda (c) (cons (url-cookie-name c) (url-cookie-value c)))
+   (url-cookie-retrieve host localpart secure)))
+
+
+;;; Backend: curl
+
+(defvar request--curl-cookie-jar nil
+  "Override what the function `request--curl-cookie-jar' returns.
+Currently it is used only for testing.")
+
+(defun request--curl-cookie-jar ()
+  "Cookie storage for curl backend."
+  (or request--curl-cookie-jar
+      (expand-file-name "curl-cookie-jar" request-storage-directory)))
+
+(defconst request--curl-write-out-template
+  (if (eq system-type 'windows-nt)
+      "\\n(:num-redirects %{num_redirects} :url-effective %{url_effective})"
+    "\\n(:num-redirects %{num_redirects} :url-effective \"%{url_effective}\")"))
+
+(defun request--curl-mkdir-for-cookie-jar ()
+  (ignore-errors
+    (make-directory (file-name-directory (request--curl-cookie-jar)) t)))
+
+(cl-defun request--curl-command
+    (url &key type data headers timeout response files* unix-socket
+         &allow-other-keys
+         &aux
+         (cookie-jar (convert-standard-filename
+                      (expand-file-name (request--curl-cookie-jar)))))
+  (append
+   (list request-curl "--silent" "--include"
+         "--location"
+         ;; FIXME: test automatic decompression
+         "--compressed"
+         ;; FIMXE: this way of using cookie might be problem when
+         ;;        running multiple requests.
+         "--cookie" cookie-jar "--cookie-jar" cookie-jar
+         "--write-out" request--curl-write-out-template)
+   request-curl-options
+   (when unix-socket (list "--unix-socket" unix-socket))
+   (cl-loop for (name filename path mime-type) in files*
+            collect "--form"
+            collect (format "%s=@%s;filename=%s%s" name
+                            (request-untrampify-filename path) filename
+                            (if mime-type
+                                (format ";type=%s" mime-type)
+                              "")))
+   (when data
+     (let ((tempfile (request--make-temp-file)))
+       (push tempfile (request-response--tempfiles response))
+       (let ((file-coding-system-alist nil)
+             (coding-system-for-write 'binary))
+         (with-temp-file tempfile
+           (setq buffer-file-coding-system 'binary)
+           (set-buffer-multibyte nil)
+           (insert data)))
+       (list "--data-binary" (concat  "@" (request-untrampify-filename tempfile)))))
+   (when type (list "--request" type))
+   (cl-loop for (k . v) in headers
+            collect "--header"
+            collect (format "%s: %s" k v))
+   (list url)))
+
+(defun request--curl-normalize-files-1 (files get-temp-file)
+  (cl-loop for (name . item) in files
+           collect
+           (cl-destructuring-bind
+               (filename &key file buffer data mime-type)
+               (cond
+                ((stringp item) (list (file-name-nondirectory item) :file item))
+                ((bufferp item) (list (buffer-name item) :buffer item))
+                (t item))
+             (unless (= (cl-loop for v in (list file buffer data) if v sum 1) 1)
+               (error "Only one of :file/:buffer/:data must be given.  Got: %S"
+                      (cons name item)))
+             (cond
+              (file
+               (list name filename file mime-type))
+              (buffer
+               (let ((tf (funcall get-temp-file)))
+                 (with-current-buffer buffer
+                   (write-region (point-min) (point-max) tf nil 'silent))
+                 (list name filename tf mime-type)))
+              (data
+               (let ((tf (funcall get-temp-file)))
+                 (with-temp-buffer
+                   (erase-buffer)
+                   (insert data)
+                   (write-region (point-min) (point-max) tf nil 'silent))
+                 (list name filename tf mime-type)))))))
+
+(defun request--make-temp-file ()
+  "Create a temporary file."
+  (if (file-remote-p default-directory)
+      (let ((tramp-temp-name-prefix request-temp-prefix)
+            (vec (tramp-dissect-file-name default-directory)))
+        (tramp-make-tramp-file-name
+         (tramp-file-name-method vec)
+         (tramp-file-name-user vec)
+         (tramp-file-name-host vec)
+         (tramp-make-tramp-temp-file vec)
+         (tramp-file-name-hop vec)))
+    (make-temp-file request-temp-prefix)))
+
+(defun request--curl-normalize-files (files)
+  "Change FILES into a list of (NAME FILENAME PATH MIME-TYPE).
+This is to make `request--curl-command' cleaner by converting
+FILES to a homogeneous list.  It returns a list (FILES* TEMPFILES)
+where FILES* is a converted FILES and TEMPFILES is a list of
+temporary file paths."
+  (let (tempfiles noerror)
+    (unwind-protect
+        (let* ((get-temp-file (lambda ()
+                                (let ((tf (request--make-temp-file)))
+                                  (push tf tempfiles)
+                                  tf)))
+               (files* (request--curl-normalize-files-1 files get-temp-file)))
+          (setq noerror t)
+          (list files* tempfiles))
+      (unless noerror
+        ;; Remove temporary files only when an error occurs
+        (request--safe-delete-files tempfiles)))))
+
+(defun request--safe-delete-files (files)
+  "Remove FILES but do not raise error when failed to do so."
+  (mapc (lambda (f) (condition-case err
+                        (delete-file f)
+                      (error (request-log 'error
+                               "Failed delete file %s. Got: %S" f err))))
+        files))
+
+(cl-defun request--curl (url &rest settings
+                             &key type data files headers timeout response
+                             &allow-other-keys)
+  "cURL-based request backend.
+
+Redirection handling strategy
+-----------------------------
+
+curl follows redirection when --location is given.  However,
+all headers are printed when it is used with --include option.
+Number of redirects is printed out sexp-based message using
+--write-out option (see `request--curl-write-out-template').
+This number is used for removing extra headers and parse
+location header from the last redirection header.
+
+Sexp at the end of buffer and extra headers for redirects are
+removed from the buffer before it is shown to the parser function.
+"
+  (request--curl-mkdir-for-cookie-jar)
+  (let* (;; Use pipe instead of pty.  Otherwise, curl process hangs.
+         (process-connection-type nil)
+         ;; Avoid starting program in non-existing directory.
+         (home-directory (if (file-remote-p default-directory)
+                             (let ((vec (tramp-dissect-file-name default-directory)))
+                               (tramp-make-tramp-file-name
+                                (tramp-file-name-method vec)
+                                (tramp-file-name-user vec)
+                                (tramp-file-name-host vec)
+                                "~/"
+                                (tramp-file-name-hop vec)))
+                           "~/"))
+         (default-directory (expand-file-name home-directory))
+         (buffer (generate-new-buffer " *request curl*"))
+         (command (cl-destructuring-bind
+                      (files* tempfiles)
+                      (request--curl-normalize-files files)
+                    (setf (request-response--tempfiles response) tempfiles)
+                    (apply #'request--curl-command url :files* files*
+                           :response response settings)))
+         (proc (apply #'start-file-process "request curl" buffer command)))
+    (request-log 'debug "Run: %s" (mapconcat 'identity command " "))
+    (setf (request-response--buffer response) buffer)
+    (process-put proc :request-response response)
+    (set-process-coding-system proc 'binary 'binary)
+    (set-process-query-on-exit-flag proc nil)
+    (set-process-sentinel proc #'request--curl-callback)))
+
+(defun request--curl-read-and-delete-tail-info ()
+  "Read a sexp at the end of buffer and remove it and preceding character.
+This function moves the point at the end of buffer by side effect.
+See also `request--curl-write-out-template'."
+  (let (forward-sexp-function)
+    (goto-char (point-max))
+    (forward-sexp -1)
+    (let ((beg (1- (point))))
+      (prog1
+          (read (current-buffer))
+        (delete-region beg (point-max))))))
+
+(defconst request--cookie-reserved-re
+  (mapconcat
+   (lambda (x) (concat "\\(^" x "\\'\\)"))
+   '("comment" "commenturl" "discard" "domain" "max-age" "path" "port"
+     "secure" "version" "expires")
+   "\\|")
+  "Uninterested keys in cookie.
+See \"set-cookie-av\" in http://www.ietf.org/rfc/rfc2965.txt")
+
+(defun request--consume-100-continue ()
+  "Remove \"HTTP/* 100 Continue\" header at the point."
+  (cl-destructuring-bind (&key code &allow-other-keys)
+      (save-excursion (request--parse-response-at-point))
+    (when (equal code 100)
+      (delete-region (point) (progn (request--goto-next-body) (point)))
+      ;; FIXME: Does this make sense?  Is it possible to have multiple 100?
+      (request--consume-100-continue))))
+
+(defun request--consume-200-connection-established ()
+  "Remove \"HTTP/* 200 Connection established\" header at the point."
+  (when (looking-at-p "HTTP/1\\.[0-1] 200 Connection established")
+    (delete-region (point) (progn (request--goto-next-body) (point)))))
+
+(defun request--curl-preprocess ()
+  "Pre-process current buffer before showing it to user."
+  (let (history)
+    (cl-destructuring-bind (&key num-redirects url-effective)
+        (request--curl-read-and-delete-tail-info)
+      (goto-char (point-min))
+      (request--consume-100-continue)
+      (request--consume-200-connection-established)
+      (when (> num-redirects 0)
+        (cl-loop with case-fold-search = t
+                 repeat num-redirects
+                 ;; Do not store code=100 headers:
+                 do (request--consume-100-continue)
+                 do (let ((response (make-request-response
+                                     :-buffer (current-buffer)
+                                     :-backend 'curl)))
+                      (request--clean-header response)
+                      (request--cut-header response)
+                      (push response history))))
+
+      (goto-char (point-min))
+      (nconc (list :num-redirects num-redirects :url-effective url-effective
+                   :history (nreverse history))
+             (request--parse-response-at-point)))))
+
+(defun request--curl-absolutify-redirects (start-url redirects)
+  "Convert relative paths in REDIRECTS to absolute URLs.
+START-URL is the URL requested."
+  (cl-loop for prev-url = start-url then url
+           for url in redirects
+           unless (string-match url-nonrelative-link url)
+           do (setq url (url-expand-file-name url prev-url))
+           collect url))
+
+(defun request--curl-absolutify-location-history (start-url history)
+  "Convert relative paths in HISTORY to absolute URLs.
+START-URL is the URL requested."
+  (when history
+    (setf (request-response-url (car history)) start-url))
+  (cl-loop for url in (request--curl-absolutify-redirects
+                       start-url
+                       (mapcar (lambda (response)
+                                 (request-response-header response "location"))
+                               history))
+           for response in (cdr history)
+           do (setf (request-response-url response) url)))
+
+(defun request--curl-callback (proc event)
+  (let* ((buffer (process-buffer proc))
+         (response (process-get proc :request-response))
+         (symbol-status (request-response-symbol-status response))
+         (settings (request-response-settings response)))
+    (request-log 'debug "REQUEST--CURL-CALLBACK event = %s" event)
+    (request-log 'debug "REQUEST--CURL-CALLBACK proc = %S" proc)
+    (request-log 'debug "REQUEST--CURL-CALLBACK buffer = %S" buffer)
+    (request-log 'debug "REQUEST--CURL-CALLBACK symbol-status = %S"
+                 symbol-status)
+    (cond
+     ((and (memq (process-status proc) '(exit signal))
+           (/= (process-exit-status proc) 0))
+      (setf (request-response-error-thrown response) (cons 'error event))
+      (apply #'request--callback buffer settings))
+     ((equal event "finished\n")
+      (cl-destructuring-bind (&key version code num-redirects history error
+                                   url-effective)
+          (condition-case err
+              (with-current-buffer buffer
+                (request--curl-preprocess))
+            ((debug error)
+             (list :error err)))
+        (request--curl-absolutify-location-history (plist-get settings :url)
+                                                   history)
+        (setf (request-response-status-code  response) code)
+        (setf (request-response-url          response) url-effective)
+        (setf (request-response-history      response) history)
+        (setf (request-response-error-thrown response)
+              (or error (when (>= code 400) `(error . (http ,code)))))
+        (apply #'request--callback buffer settings))))))
+
+(cl-defun request--curl-sync (url &rest settings &key response &allow-other-keys)
+  ;; To make timeout work, use polling approach rather than using
+  ;; `call-process'.
+  (let (finished)
+    (prog1 (apply #'request--curl url
+                  :complete (lambda (&rest _) (setq finished t))
+                  settings)
+      (let ((proc (get-buffer-process (request-response--buffer response))))
+        (while (and (not finished) (request--process-live-p proc))
+          (accept-process-output proc))))))
+
+(defun request--curl-get-cookies (host localpart secure)
+  (request--netscape-get-cookies (request--curl-cookie-jar)
+                                 host localpart secure))
+
+
+;;; Netscape cookie.txt parser
+
+(defun request--netscape-cookie-parse ()
+  "Parse Netscape/Mozilla cookie format."
+  (goto-char (point-min))
+  (let ((tsv-re (concat "^\\(#HttpOnly_\\)?"
+                        (cl-loop repeat 6 concat "\\([^\t\n]+\\)\t")
+                        "\\(.*\\)"))
+        cookies)
+    (while (not (eobp))
+      ;; HttpOnly cookie starts with '#' but its line is not comment line(#60)
+      (cond ((and (looking-at-p "^#") (not (looking-at-p "^#HttpOnly_"))) t)
+            ((looking-at-p "^$") t)
+            ((looking-at tsv-re)
+             (let ((cookie (cl-loop for i from 1 to 8 collect (match-string i))))
+               (push cookie cookies))))
+      (forward-line 1))
+    (setq cookies (nreverse cookies))
+    (cl-loop for (http-only domain flag path secure expiration name value) in cookies
+             collect (list domain
+                           (equal flag "TRUE")
+                           path
+                           (equal secure "TRUE")
+                           (null (not http-only))
+                           (string-to-number expiration)
+                           name
+                           value))))
+
+(defun request--netscape-filter-cookies (cookies host localpart secure)
+  (cl-loop for (domain flag path secure-1 http-only expiration name value) in cookies
+           when (and (equal domain host)
+                     (equal path localpart)
+                     (or secure (not secure-1)))
+           collect (cons name value)))
+
+(defun request--netscape-get-cookies (filename host localpart secure)
+  (when (file-readable-p filename)
+    (with-temp-buffer
+      (erase-buffer)
+      (insert-file-contents filename)
+      (request--netscape-filter-cookies (request--netscape-cookie-parse)
+                                        host localpart secure))))
+
+(provide 'request)
+
+;;; request.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/request-20170131.1747/request.elc b/configs/shared/emacs/.emacs.d/elpa/request-20170131.1747/request.elc
new file mode 100644
index 0000000000..c9249e874a
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/request-20170131.1747/request.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/rjsx-mode-20180624.1758/rjsx-mode-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/rjsx-mode-20180624.1758/rjsx-mode-autoloads.el
new file mode 100644
index 0000000000..512f2a0d41
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/rjsx-mode-20180624.1758/rjsx-mode-autoloads.el
@@ -0,0 +1,29 @@
+;;; rjsx-mode-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "rjsx-mode" "rjsx-mode.el" (23377 61676 764289
+;;;;;;  452000))
+;;; Generated autoloads from rjsx-mode.el
+
+(autoload 'rjsx-mode "rjsx-mode" "\
+Major mode for editing JSX files.
+
+\(fn)" t nil)
+
+(autoload 'rjsx-minor-mode "rjsx-mode" "\
+Minor mode for parsing JSX syntax into an AST.
+
+\(fn &optional ARG)" t nil)
+
+(add-to-list 'auto-mode-alist '("\\.jsx\\'" . rjsx-mode))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; rjsx-mode-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/rjsx-mode-20180624.1758/rjsx-mode-pkg.el b/configs/shared/emacs/.emacs.d/elpa/rjsx-mode-20180624.1758/rjsx-mode-pkg.el
new file mode 100644
index 0000000000..a80463f8cb
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/rjsx-mode-20180624.1758/rjsx-mode-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "rjsx-mode" "20180624.1758" "Real support for JSX" '((emacs "24.4") (js2-mode "20170504")))
diff --git a/configs/shared/emacs/.emacs.d/elpa/rjsx-mode-20180624.1758/rjsx-mode.el b/configs/shared/emacs/.emacs.d/elpa/rjsx-mode-20180624.1758/rjsx-mode.el
new file mode 100644
index 0000000000..75fd5f7c1c
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/rjsx-mode-20180624.1758/rjsx-mode.el
@@ -0,0 +1,964 @@
+;;; rjsx-mode.el --- Real support for JSX    -*- lexical-binding: t -*-
+
+;; Copyright (C) 2016 Felipe Ochoa
+
+;; Author: Felipe Ochoa <felipe@fov.space>
+;; URL: https://github.com/felipeochoa/rjsx-mode/
+;; Package-Version: 20180624.1758
+;; Package-Requires: ((emacs "24.4") (js2-mode "20170504"))
+;; Version: 1.1
+;; Keywords: languages
+
+;;; Commentary:
+;; Defines a major mode `rjsx-mode' based on `js2-mode' for editing
+;; JSX files.  `rjsx-mode' extends the parser in `js2-mode' to support
+;; the full JSX syntax.  This means you get all of the `js2' features
+;; plus proper syntax checking and highlighting of JSX code blocks.
+;;
+;; Some features that this mode adds to js2:
+;;
+;; - Highlighting JSX tag names and attributes (using the rjsx-tag and
+;;   rjsx-attr faces)
+;; - Highlight undeclared JSX components
+;; - Parsing the spread operator {...otherProps}
+;; - Parsing && and || in child expressions {cond && <BigComponent/>}
+;; - Parsing ternary expressions {toggle ? <ToggleOn /> : <ToggleOff />}
+;;
+;; Additionally, since rjsx-mode extends the js2 AST, utilities using
+;; the parse tree gain access to the JSX structure.
+
+;;; Code:
+
+;;;; Basic mode definitions
+
+(require 'cl-lib)
+(require 'js2-mode)
+
+(defgroup rjsx-mode nil
+  "Support for JSX."
+  :group 'js2-mode)
+
+(defcustom rjsx-max-size-for-frequent-reparse 100000
+  "Buffers with fewer than this many characters will be parsed more frequently.
+Set this to 0 to disable the reparsing altogether.  The frequent
+parsing supports the magic `rjsx-electric-lt' and
+`rjsx-delete-creates-full-tag' behaviors."
+  :group 'rjsx-mode
+  :type 'integer)
+
+;;;###autoload
+(define-derived-mode rjsx-mode js2-jsx-mode "RJSX"
+  "Major mode for editing JSX files."
+  :lighter ":RJSX"
+  :group 'rjsx-mode)
+
+;;;###autoload
+(define-minor-mode rjsx-minor-mode
+  "Minor mode for parsing JSX syntax into an AST."
+  :lighter " rjsx"
+  (if rjsx-minor-mode
+      (js2-minor-mode 1)
+    (js2-minor-mode 0)))
+
+;;;###autoload
+(add-to-list 'auto-mode-alist '("\\.jsx\\'" . rjsx-mode))
+
+(defun rjsx-parse-xml-initializer (orig-fun)
+  "Dispatch the xml parser based on variable `rjsx-mode' being active or not.
+This function is used to advise `js2-parse-xml-initializer' (ORIG-FUN) using
+the `:around' combinator.  JS2-PARSER is the original XML parser."
+  (if (or (eq major-mode 'rjsx-mode) rjsx-minor-mode)
+      (rjsx-parse-top-xml)
+    (apply orig-fun nil)))
+
+(advice-add 'js2-parse-xml-initializer :around #'rjsx-parse-xml-initializer)
+
+(defun rjsx-unadvice-js2 ()
+  "Remove the rjsx advice on the js2 parser.  This will cause rjsx to stop working globally."
+  (advice-remove 'js2-parse-xml-initializer #'rjsx-parse-xml-initializer))
+
+
+(defface rjsx-tag
+  '((t . (:inherit font-lock-function-name-face)))
+  "`rjsx-mode' face used to highlight JSX tag names."
+  :group 'rjsx-mode)
+
+(defface rjsx-attr
+  '((t . (:inherit font-lock-variable-name-face)))
+  "`rjsx-mode' face used to highlight JSX attribute names."
+  :group 'rjsx-mode)
+
+(defface rjsx-text
+  '((t . (:inherit font-lock-string-face)))
+  "`rjsx-mode' face used to highlight JSX text."
+  :group 'rjsx-mode)
+
+(defface rjsx-tag-bracket-face
+  '((t . (:inherit default)))
+  "`rjsx-mode' face used to highlight `<', `/', and `>'."
+  :group 'rjsx-mode)
+
+
+;;;; Parser constants struct definitions
+
+;; Token types for XML nodes. We need to re-use some unused values to
+;; not mess up the vectors that js2 has set up
+(defvar rjsx-JSX            js2-ENUM_INIT_KEYS)
+(defvar rjsx-JSX-CLOSE      js2-ENUM_INIT_VALUES)
+(defvar rjsx-JSX-IDENT      js2-ENUM_INIT_ARRAY)
+(defvar rjsx-JSX-MEMBER     js2-ENUM_NEXT)
+(defvar rjsx-JSX-ATTR       js2-ENUM_ID)
+(defvar rjsx-JSX-SPREAD     js2-REF_NS_MEMBER)
+(defvar rjsx-JSX-TEXT       js2-ESCXMLTEXT)
+(defvar rjsx-JSX-EXPRESSION js2-ESCXMLATTR)
+
+(dolist (sym '(rjsx-JSX rjsx-JSX-CLOSE rjsx-JSX-IDENT rjsx-JSX-MEMBER rjsx-JSX-ATTR
+                        rjsx-JSX-SPREAD rjsx-JSX-TEXT rjsx-JSX-EXPRESSION))
+  (aset js2-token-names (symbol-value sym) (downcase (substring (symbol-name sym) 5)))
+  (puthash sym (symbol-value sym) js2-token-codes))
+
+(js2-msg "msg.bad.jsx.ident" "invalid JSX identifier")
+(js2-msg "msg.invalid.jsx.string" "invalid JSX string (cannot contain delimiter in string body)")
+(js2-msg "msg.mismatched.close.tag" "mismatched closing JSX tag; expected `%s'")
+(js2-msg "msg.no.gt.in.opener" "missing `>' in opening tag")
+(js2-msg "msg.no.gt.in.closer" "missing `>' in closing tag")
+(js2-msg "msg.no.gt.after.slash" "missing `>' after `/' in self-closing tag")
+(js2-msg "msg.no.rc.after.spread" "missing `}' after spread-prop")
+(js2-msg "msg.no.value.after.jsx.prop" "missing value after prop `%s'")
+(js2-msg "msg.no.dots.in.prop.spread" "missing `...' in spread prop")
+(js2-msg "msg.no.rc.after.expr" "missing `}' after expression")
+(js2-msg "msg.empty.expr" "empty `{}' expression")
+
+
+(cl-defstruct (rjsx-node
+               (:include js2-node (type rjsx-JSX))
+               (:constructor nil)
+               (:constructor make-rjsx-node
+                             (&key (pos (js2-current-token-beg))
+                                   len
+                                   name
+                                   rjsx-props
+                                   kids)))
+  name         ; AST node containing the parsed xml name or nil for fragments
+  rjsx-props   ; linked list of AST nodes (both attributes and spreads)
+  kids         ; linked list of child xml nodes
+  closing-tag) ; AST node with the tag closer
+
+
+(js2--struct-put 'rjsx-node 'js2-visitor 'rjsx-node-visit)
+(js2--struct-put 'rjsx-node 'js2-printer 'rjsx-node-print)
+(defun rjsx-node-visit (ast callback)
+  "Visit the `rjsx-node' children of AST, invoking CALLBACK on them."
+  (let ((name (rjsx-node-name ast)))
+    (when name (js2-visit-ast name callback)))
+  (dolist (prop (rjsx-node-rjsx-props ast))
+    (js2-visit-ast prop callback))
+  (dolist (prop (rjsx-node-kids ast))
+    (js2-visit-ast prop callback))
+  (when (rjsx-node-closing-tag ast)
+    (js2-visit-ast (rjsx-node-closing-tag ast) callback)))
+
+(defun rjsx-node-print (node indent-level)
+  "Print the `rjsx-node' NODE at indent level INDENT-LEVEL."
+  (insert (js2-make-pad indent-level) "<")
+  (let ((name-n (rjsx-node-name node)))
+   (when name-n (js2-print-ast name-n 0)))
+  (dolist (attr (rjsx-node-rjsx-props node))
+    (insert " ")
+    (js2-print-ast attr 0))
+  (let ((closer (rjsx-node-closing-tag node)))
+    (if (null closer)
+        (insert "/>")
+      (insert ">")
+      (dolist (child (rjsx-node-kids node))
+          (js2-print-ast child 0))
+      (js2-print-ast closer indent-level))))
+
+(defun rjsx-node-opening-tag-name (node)
+  "Return a string with NODE's opening tag including any namespace and member operations."
+  (let ((name-n (rjsx-node-name node)))
+    (cond
+     ((null name-n) "")                 ; fragment
+     ((rjsx-member-p name-n) (rjsx-member-full-name name-n))
+     ((rjsx-identifier-p name-n) (rjsx-identifier-full-name name-n))
+     (t ""))))                          ; js2-error-node
+
+(defun rjsx-node-push-prop (n rjsx-prop)
+  "Extend rjsx-node N's rjsx-props with js2-node RJSX-PROP.
+Sets JSX-PROPS's parent to N."
+  (let ((rjsx-props (rjsx-node-rjsx-props n)))
+    (if rjsx-props
+        (setcdr rjsx-props (nconc (cdr rjsx-props) (list rjsx-prop)))
+      (setf (rjsx-node-rjsx-props n) (list rjsx-prop))))
+  (js2-node-add-children n rjsx-prop))
+
+(defun rjsx-node-push-child (n kid)
+  "Extend rjsx-node N's children with js2-node KID.
+Sets KID's parent to N."
+  (let ((kids (rjsx-node-kids n)))
+    (if kids
+        (setcdr kids (nconc (cdr kids) (list kid)))
+      (setf (rjsx-node-kids n) (list kid))))
+  (js2-node-add-children n kid))
+
+
+(cl-defstruct (rjsx-closing-tag
+               (:include js2-node (type rjsx-JSX-CLOSE))
+               (:constructor nil)
+               (:constructor make-rjsx-closing-tag (&key pos len name)))
+  name) ; An rjsx-identifier or rjsx-member node or nil for fragments
+
+(js2--struct-put 'rjsx-closing-tag 'js2-visitor 'rjsx-closing-tag-visit)
+(js2--struct-put 'rjsx-closing-tag 'js2-printer 'rjsx-closing-tag-print)
+
+(defun rjsx-closing-tag-visit (ast callback)
+  "Visit the `rjsx-closing-tag' children of AST, invoking CALLBACK on them."
+  (js2-visit-ast (rjsx-closing-tag-name ast) callback))
+
+(defun rjsx-closing-tag-print (node indent-level)
+  "Print the `rjsx-closing-tag' NODE at INDENT-LEVEL."
+  (insert (js2-make-pad indent-level) "</" (rjsx-closing-tag-full-name node) ">"))
+
+(defun rjsx-closing-tag-full-name (n)
+  "Return the string with N's fully-namespaced name, or just name if it's not namespaced."
+  (let ((child (rjsx-closing-tag-name n)))
+    (cond
+     ((null child) "")                  ; fragment
+     ((rjsx-member-p child) (rjsx-member-full-name child))
+     ((rjsx-identifier-p child) (rjsx-identifier-full-name child))
+     (t ""))))
+
+(cl-defstruct (rjsx-identifier
+               (:include js2-node (type rjsx-JSX-IDENT))
+               (:constructor nil)
+               (:constructor make-rjsx-identifier (&key (pos (js2-current-token-beg))
+                                                           len namespace name)))
+  (namespace nil)
+  name)  ; js2-name-node
+
+(js2--struct-put 'rjsx-identifier 'js2-visitor 'rjsx-identifier-visit)
+(js2--struct-put 'rjsx-identifier 'js2-printer 'rjsx-identifier-print)
+
+(defun rjsx-identifier-visit (n callback)
+  "Visit N's children can call CALLBACK on them."
+  (js2-visit-ast (rjsx-identifier-name n) callback))
+
+(defun rjsx-identifier-print (node indent-level)
+  "Print the `rjsx-identifier' NODE at INDENT-LEVEL."
+  (insert (js2-make-pad indent-level) (rjsx-identifier-full-name node)))
+
+(defun rjsx-identifier-full-name (n)
+  "Return the string with N's fully-namespaced name, or just name if it's not namespaced."
+  (if (rjsx-identifier-namespace n)
+      (format "%s:%s" (rjsx-identifier-namespace n) (js2-name-node-name (rjsx-identifier-name n)))
+    (js2-name-node-name (rjsx-identifier-name n))))
+
+(cl-defstruct (rjsx-member
+               (:include js2-node (type rjsx-JSX-MEMBER))
+               (:constructor nil)
+               (:constructor make-rjsx-member (&key pos len dots-pos idents)))
+  dots-pos  ; List of positions of each dot
+  idents)   ; List of rjsx-identifier nodes
+
+(js2--struct-put 'rjsx-member 'js2-visitor 'rjsx-member-visit)
+(js2--struct-put 'rjsx-member 'js2-printer 'rjsx-member-print)
+
+(defun rjsx-member-visit (n callback)
+  "Visit N's children and call CALLBACK on them."
+  (dolist (ident (rjsx-member-idents n))
+    (js2-visit-ast ident callback)))
+
+(defun rjsx-member-print (node indent-level)
+  "Print the `rjsx-member' NODE at INDENT-LEVEL."
+  (insert (js2-make-pad indent-level) (rjsx-member-full-name node)))
+
+(defun rjsx-member-full-name (n)
+  "Return the string with N's combined names together."
+  (mapconcat 'rjsx-identifier-full-name (rjsx-member-idents n) "."))
+
+(cl-defstruct (rjsx-attr
+               (:include js2-node (type rjsx-JSX-ATTR))
+               (:constructor nil)
+               (:constructor make-rjsx-attr (&key (pos (js2-current-token-beg))
+                                                     len name value)))
+  name    ; a rjsx-identifier
+  value)  ; a js2-expression
+
+(js2--struct-put 'rjsx-attr 'js2-visitor 'rjsx-attr-visit)
+(js2--struct-put 'rjsx-attr 'js2-printer 'rjsx-attr-print)
+
+(defun rjsx-attr-visit (ast callback)
+  "Visit the `rjsx-attr' children of AST, invoking CALLBACK on them."
+  (js2-visit-ast (rjsx-attr-name ast) callback)
+  (js2-visit-ast (rjsx-attr-value ast) callback))
+
+(defun rjsx-attr-print (node indent-level)
+  "Print the `rjsx-attr' NODE at INDENT-LEVEL."
+  (js2-print-ast (rjsx-attr-name node) indent-level)
+  (unless (js2-empty-expr-node-p (rjsx-attr-value node))
+    (insert "=")
+    (js2-print-ast (rjsx-attr-value node) 0)))
+
+(cl-defstruct (rjsx-spread
+               (:include js2-node (type rjsx-JSX-SPREAD))
+               (:constructor nil)
+               (:constructor make-rjsx-spread (&key pos len expr)))
+  expr)  ; a js2-expression
+
+(js2--struct-put 'rjsx-spread 'js2-visitor 'rjsx-spread-visit)
+(js2--struct-put 'rjsx-spread 'js2-printer 'rjsx-spread-print)
+
+(defun rjsx-spread-visit (ast callback)
+  "Visit the `rjsx-spread' children of AST, invoking CALLBACK on them."
+  (js2-visit-ast (rjsx-spread-expr ast) callback))
+
+(defun rjsx-spread-print (node indent-level)
+  "Print the `rjsx-spread' NODE at INDENT-LEVEL."
+  (insert (js2-make-pad indent-level) "{...")
+  (js2-print-ast (rjsx-spread-expr node) 0)
+  (insert "}"))
+
+(cl-defstruct (rjsx-wrapped-expr
+               (:include js2-node (type rjsx-JSX-TEXT))
+               (:constructor nil)
+               (:constructor make-rjsx-wrapped-expr (&key pos len child)))
+  child)
+
+(js2--struct-put 'rjsx-wrapped-expr 'js2-visitor 'rjsx-wrapped-expr-visit)
+(js2--struct-put 'rjsx-wrapped-expr 'js2-printer 'rjsx-wrapped-expr-print)
+
+(defun rjsx-wrapped-expr-visit (ast callback)
+  "Visit the `rjsx-wrapped-expr' child of AST, invoking CALLBACK on them."
+  (js2-visit-ast (rjsx-wrapped-expr-child ast) callback))
+
+(defun rjsx-wrapped-expr-print (node indent-level)
+  "Print the `rjsx-wrapped-expr' NODE at INDENT-LEVEL."
+  (insert (js2-make-pad indent-level) "{")
+  (js2-print-ast (rjsx-wrapped-expr-child node) indent-level)
+  (insert "}"))
+
+(cl-defstruct (rjsx-text
+               (:include js2-node (type rjsx-JSX-TEXT))
+               (:constructor nil)
+               (:constructor make-rjsx-text (&key (pos (js2-current-token-beg))
+                                                     (len (js2-current-token-len))
+                                                     value)))
+  value)  ; a string
+
+(js2--struct-put 'rjsx-text 'js2-visitor 'js2-visit-none)
+(js2--struct-put 'rjsx-text 'js2-printer 'rjsx-text-print)
+
+(defun rjsx-text-print (node _indent-level)
+  "Print the `rjsx-text' NODE at INDENT-LEVEL."
+  ;; Text nodes include whitespace
+  (insert (rjsx-text-value node)))
+
+
+;;;; Recursive descent parsing
+(defvar rjsx-print-debug-message nil "If t will print out debug messages.")
+;(setq rjsx-print-debug-message t)
+(defmacro rjsx-maybe-message (&rest args)
+  "If debug is enabled, call `message' with ARGS."
+  `(when rjsx-print-debug-message
+     (message ,@args)))
+
+
+(defvar rjsx-text-syntax-table
+  (let ((table (make-syntax-table (standard-syntax-table))))
+    ;; `js-indent-line' assumes that \n is not whitespace
+    ;; Since it's not a comment delimiter in JSX text, punctuation
+    ;; is the only other (semi) logical choice
+    (modify-syntax-entry ?\n "." table)
+    table))
+
+(js2-deflocal rjsx-in-xml nil "Variable used to track which xml parsing function is the outermost one.")
+
+(define-error 'rjsx-eof-while-parsing "RJSX: EOF while parsing")
+
+(defmacro rjsx-handling-eof (&rest body)
+  "Execute BODY and return the result of the last form.
+If BODY signals `rjsx-eof-while-parsing', instead report a syntax
+error and return a `js2-error-node'."
+  `(let ((beg (js2-current-token-beg)))
+     (condition-case nil
+         (progn ,@body)
+       (rjsx-eof-while-parsing
+        (let ((len (- js2-ts-cursor beg)))
+          (rjsx-maybe-message (format "Handling eof from %d" beg))
+          (js2-report-error "msg.syntax" nil beg len)
+          (make-js2-error-node :pos beg :len len))))))
+
+(defsubst rjsx-record-tag-bracket-face ()
+  "Fontify the current token with `rjsx-tag-bracket-face'."
+  (js2-set-face (js2-current-token-beg) (js2-current-token-end) 'rjsx-tag-bracket-face 'record))
+
+(defun rjsx-parse-top-xml ()
+  "Parse a top level XML fragment.
+This is the entry point when ‘js2-parse-unary-expr’ finds a '<' character"
+  (if rjsx-in-xml
+      (rjsx-parse-xml)
+    (let ((rjsx-in-xml t))
+      (rjsx-handling-eof (rjsx-parse-xml)))))
+
+(defun rjsx-parse-xml ()
+  "Parse a complete xml node from start to end tag."
+  (rjsx-record-tag-bracket-face)
+  (let ((pn (make-rjsx-node)) self-closing name-n name-str child child-name-str is-fragment)
+    (rjsx-maybe-message "Starting rjsx-parse-xml after <")
+    (if (setq child (rjsx-parse-empty-tag))
+        child
+      (if (eq (js2-peek-token) js2-GT)
+          (setq is-fragment t)
+        (setf (rjsx-node-name pn) (setq name-n (rjsx-parse-member-or-ns 'rjsx-tag)))
+        (if (js2-error-node-p name-n)
+            (progn (rjsx-maybe-message "could not parse tag name")
+                   (make-js2-error-node :pos (js2-node-pos pn) :len (1+ (js2-node-len name-n))))
+          (js2-node-add-children pn name-n)
+          (if js2-highlight-external-variables
+              (let ((name-node (rjsx-identifier-name
+                                (if (rjsx-member-p name-n)
+                                    (car (rjsx-member-idents name-n))
+                                  name-n)))
+                    (case-fold-search nil))
+                (when (string-match-p "^[[:upper:]]" (js2-name-node-name name-node))
+                  (js2-record-name-node name-node)))))
+        (rjsx-maybe-message "cleared tag name: '%s'" name-str)
+        ;; Now parse the attributes
+        (rjsx-parse-attributes pn)
+        (rjsx-maybe-message "cleared attributes"))
+      (setq name-str (rjsx-node-opening-tag-name pn))
+      (progn
+        ;; Now parse either a self closing tag or the end of the opening tag
+        (rjsx-maybe-message "next type: `%s'" (js2-peek-token))
+        (if (setq self-closing (js2-match-token js2-DIV))
+            (progn
+              (js2-record-text-property (js2-current-token-beg) (js2-current-token-end)
+                                        'rjsx-class 'self-closing-slash)
+              (rjsx-record-tag-bracket-face)
+              ;; TODO: How do we un-mark old slashes?
+              (when (js2-must-match js2-GT "msg.no.gt.after.slash"
+                                    (js2-node-pos pn) (- (js2-current-token-end) (js2-node-pos pn)))
+                (rjsx-record-tag-bracket-face)))
+          (when (js2-must-match js2-GT "msg.no.gt.in.opener" (js2-node-pos pn) (js2-node-len pn))
+            (rjsx-record-tag-bracket-face)))
+        (rjsx-maybe-message "cleared opener closer, self-closing: %s" self-closing)
+        (if self-closing
+            (setf (js2-node-len pn) (- (js2-current-token-end) (js2-node-pos pn)))
+          (while (not (rjsx-closing-tag-p (setq child (rjsx-parse-child is-fragment))))
+            ;; rjsx-parse-child calls our scanner, which always moves
+            ;; forward at least one character. If it hits EOF, it
+            ;; signals to our caller, so we don't have to worry about infinite loops here
+            (rjsx-maybe-message "parsed child")
+            (rjsx-node-push-child pn child)
+            (if (= 0 (js2-node-len child)) ; TODO: Does this ever happen?
+                (js2-get-token)))
+          (setq child-name-str (rjsx-closing-tag-full-name child))
+          (unless (string= name-str child-name-str)
+            (js2-report-error "msg.mismatched.close.tag" name-str (js2-node-pos child) (js2-node-len child)))
+          (rjsx-maybe-message "cleared children for `%s'" name-str)
+          (js2-node-add-children pn child)
+          (setf (rjsx-node-closing-tag pn) child))
+        (rjsx-maybe-message "Returning completed XML node")
+        (setf (js2-node-len pn) (- (js2-current-token-end) (js2-node-pos pn)))
+        pn))))
+
+(defun rjsx-parse-empty-tag ()
+  "Check if we are in an empty tag of the form `</>' and consume it if so.
+Returns a `js2-error-node' if we are in one or nil if not."
+  (let ((beg (js2-current-token-beg)))
+    (when (js2-match-token js2-DIV)
+        (if (js2-match-token js2-GT)
+            (progn ; We're in a </> block, likely created by us in `rjsx-electric-lt'
+              ;; We only highlight the < to reduce the visual impact
+              (js2-report-error "msg.syntax" nil beg 1)
+              (make-js2-error-node :pos beg :len (- (js2-current-token-end) beg)))
+          ;; TODO: This is probably an unmatched closing tag. We should
+          ;; consume it, mark it an error, and move on
+          (js2-unget-token)
+          nil))))
+
+(defun rjsx-parse-attributes (parent)
+  "Parse all attributes, including key=value and {...spread}, and add them to PARENT."
+  ;; Getting this function to not hang in the loop proved tricky. The
+  ;; key is that `rjsx-parse-spread' and `rjsx-parse-single-attr' both
+  ;; return `js2-error-node's if they fail to consume any tokens,
+  ;; which signals to us that we just need to discard one token and
+  ;; keep going.
+  (let (attr
+        (loop-terminators (list js2-DIV js2-GT js2-EOF js2-ERROR)))
+    (while (not (memql (js2-peek-token) loop-terminators))
+      (rjsx-maybe-message "Starting loop. Next token type: %s\nToken pos: %s" (js2-peek-token) (js2-current-token-beg))
+      (setq attr
+            (if (js2-match-token js2-LC)
+                (or (rjsx-check-for-empty-curlies t)
+                    (prog1 (rjsx-parse-spread)
+                      (rjsx-maybe-message "Parsed spread")))
+              (rjsx-maybe-message "Parsing single attr")
+              (rjsx-parse-single-attr)))
+      (when (js2-error-node-p attr) (js2-get-token))
+                                        ; TODO: We should make this conditional on
+                                        ; `js2-recover-from-parse-errors'
+      (rjsx-node-push-prop parent attr))))
+
+
+(cl-defun rjsx-check-for-empty-curlies (&optional dont-consume-rc &key check-for-comments warning)
+  "If the following token is '}' set empty curly errors.
+If DONT-CONSUME-RC is non-nil, the matched right curly token
+won't be consumed.  Returns a `js2-error-node' if the curlies are
+empty or nil otherwise.  If CHECK-FOR-COMMENTS (a &KEY argument)
+is non-nil, this will check for comments inside the curlies and
+returns a `js2-empty-expr-node' if any are found.  If WARNING (a
+&key argument) is non-nil, reports the empty curlies as a warning
+and not an error and also returns a `js2-empty-expr-node'.
+Assumes the current token is a '{'."
+  (let ((beg (js2-current-token-beg)) end len)
+    (when (js2-match-token js2-RC)
+      (setq end (js2-current-token-end))
+      (setq len (- end beg))
+      (when dont-consume-rc
+        (js2-unget-token))
+      (if check-for-comments (rjsx-maybe-message "Checking for comments between %d and %d" beg end))
+      (unless (and check-for-comments
+                   (dolist (comment js2-scanned-comments)
+                     (rjsx-maybe-message "Comment at %d, length=%d"
+                                         (js2-node-pos comment)
+                                         (js2-node-len comment))
+                     ;; TODO: IF comments are in reverse document order, we should be able to
+                     ;; bail out early and know we didn't find one
+                     (when (and (>= (js2-node-pos comment) beg)
+                                (<= (+ (js2-node-pos comment) (js2-node-len comment)) end))
+                       (cl-return-from rjsx-check-for-empty-curlies
+                         (make-js2-empty-expr-node :pos beg :len (- end beg))))))
+        (if warning
+            (progn (js2-report-warning "msg.empty.expr" nil beg len)
+                   (make-js2-empty-expr-node :pos beg :len (- end beg)))
+          (js2-report-error "msg.empty.expr" nil beg len)
+          (make-js2-error-node :pos beg :len len))))))
+
+
+(defun rjsx-parse-spread ()
+  "Parse an {...props} attribute."
+  (let ((pn (make-rjsx-spread :pos (js2-current-token-beg)))
+        (beg (js2-current-token-beg))
+        missing-dots expr)
+    (setq missing-dots (not (js2-match-token js2-TRIPLEDOT)))
+    ;; parse-assign-expr will go crazy if we're looking at `} /', so we
+    ;; check for an empty spread first
+    (if (js2-match-token js2-RC)
+        (setq expr (make-js2-error-node :len 1))
+      (setq expr (js2-parse-assign-expr))
+      (when (js2-error-node-p expr)
+        (pop js2-parsed-errors)))       ; We'll add our own error
+    (unless (or (js2-match-token js2-RC) (js2-error-node-p expr))
+      (js2-report-error "msg.no.rc.after.spread" nil
+                        beg (- (js2-current-token-end) beg)))
+    (setf (rjsx-spread-expr pn) expr)
+    (setf (js2-node-len pn) (- (js2-current-token-end) (js2-node-pos pn)))
+    (js2-node-add-children pn expr)
+    (if (js2-error-node-p expr)
+        (js2-report-error "msg.syntax" nil beg (- (js2-current-token-end) beg))
+      (when missing-dots
+        (js2-report-error "msg.no.dots.in.prop.spread" nil beg (js2-node-len pn))))
+    (if (= 0 (js2-node-len pn))  ; TODO: Is this ever possible?
+        (make-js2-error-node :pos beg :len 0)
+      pn)))
+
+(defun rjsx-parse-single-attr ()
+  "Parse an 'a=b' JSX attribute and return the corresponding XML node."
+  (let ((pn (make-rjsx-attr)) name value beg)
+    (setq name (rjsx-parse-identifier 'rjsx-attr)) ; Won't consume token on error
+    (if (js2-error-node-p name)
+        name
+      (setf (rjsx-attr-name pn) name)
+      (setq beg (js2-node-pos name))
+      (setf (js2-node-pos pn) beg)
+      (js2-node-add-children pn name)
+      (rjsx-maybe-message "Got the name for the attr: `%s'" (rjsx-identifier-full-name name))
+      (if (js2-match-token js2-ASSIGN)  ; Won't consume on error
+          (progn
+            (rjsx-maybe-message "Matched the equals sign")
+            (if (js2-match-token js2-LC)
+                (setq value (rjsx-parse-wrapped-expr nil t))
+              (if (js2-match-token js2-STRING)
+                  (setq value (rjsx-parse-string))
+                (js2-report-error "msg.no.value.after.jsx.prop" (rjsx-identifier-full-name name)
+                                  beg (- (js2-current-token-end) beg))
+                (setq value (make-js2-error-node :pos beg :len (js2-current-token-len))))))
+        (setq value (make-js2-empty-expr-node :pos (js2-current-token-end) :len 0)))
+      (rjsx-maybe-message "value type: `%s'" (js2-node-type value))
+      (setf (rjsx-attr-value pn) value)
+      (setf (js2-node-len pn) (- (js2-node-end value) (js2-node-pos pn)))
+      (js2-node-add-children pn value)
+      (rjsx-maybe-message "Finished single attribute.")
+      pn)))
+
+(defun rjsx-parse-wrapped-expr (allow-empty skip-to-rc)
+  "Parse a curly-brace-wrapped JS expression.
+If ALLOW-EMPTY is non-nil, will warn for empty braces, otherwise
+will signal a syntax error.  If it does not find a right curly
+and SKIP-TO-RC is non-nil, after the expression, consumes tokens
+until the end of the JSX node"
+  (rjsx-maybe-message "parsing wrapped expression")
+  (let (pn
+        (beg (js2-current-token-beg))
+        (child (rjsx-check-for-empty-curlies nil
+                                             :check-for-comments allow-empty
+                                             :warning allow-empty)))
+    (if child
+        (if allow-empty
+            (make-rjsx-wrapped-expr :pos beg :len (js2-node-len child) :child child)
+          child) ;; Will be an error node in this case
+      (setq child (js2-parse-assign-expr))
+      (rjsx-maybe-message "parsed expression, type: `%s'" (js2-node-type child))
+      (setq pn (make-rjsx-wrapped-expr :pos beg :child child))
+      (js2-node-add-children pn child)
+      (when (js2-error-node-p child)
+        (pop js2-parsed-errors)) ; We'll record our own message after checking for RC
+      (if (js2-match-token js2-RC)
+          (rjsx-maybe-message "matched } after expression")
+        (rjsx-maybe-message "did not match } after expression")
+        (when skip-to-rc
+          (while (not (memql (js2-get-token) (list js2-RC js2-EOF js2-DIV js2-GT)))
+            (rjsx-maybe-message "Skipped over `%s'" (js2-current-token-string)))
+          (when (memq (js2-current-token-type) (list js2-DIV js2-GT))
+            (js2-unget-token)))
+        (unless (js2-error-node-p child)
+          (js2-report-error "msg.no.rc.after.expr" nil beg
+                            (- (js2-current-token-beg) beg))))
+      (when (js2-error-node-p child)
+        (js2-report-error "msg.syntax" nil beg (- (js2-current-token-end) beg)))
+      (setf (js2-node-len pn) (- (js2-current-token-end) beg))
+      pn)))
+
+(defun rjsx-parse-string ()
+  "Verify that current token is a valid JSX string.
+Returns a `js2-error-node' if TOKEN-STRING is not a valid JSX
+string, otherwise returns a `js2-string-node'.  (Strings are
+invalid if they contain the delimiting quote character inside)"
+  (rjsx-maybe-message "Parsing string")
+  (let* ((token (js2-current-token))
+         (beg (js2-token-beg token))
+         (len (- (js2-token-end token) beg))
+         (token-string (js2-token-string token)) ;; JS2 does not include the quote-chars
+         (quote-char (char-before (js2-token-end token))))
+    (if (cl-position quote-char token-string)
+        (progn
+          (js2-report-error "msg.invalid.jsx.string" nil beg len)
+          (make-js2-error-node :pos beg :len len))
+      (make-js2-string-node :pos beg :len len :value token-string))))
+
+(cl-defun rjsx-parse-identifier (&optional face &key (allow-ns t))
+  "Parse a possibly namespaced identifier and fontify with FACE if given.
+Returns a `js2-error-node' if unable to parse.  If the &key
+argument ALLOW-NS is nil, does not allow namespaced names."
+  (if (js2-must-match-name "msg.bad.jsx.ident")
+      (let ((pn (make-rjsx-identifier))
+            (beg (js2-current-token-beg))
+            (name-parts (list (js2-current-token-string)))
+            (allow-colon allow-ns)
+            (continue t)
+            (prev-token-end (js2-current-token-end))
+            (name-start (js2-current-token-beg))
+            matched-colon)
+        (while (and continue
+                    (or (and (memq (js2-peek-token) (list js2-SUB js2-ASSIGN_SUB))
+                             (prog2  ; Ensure no whitespace between previous name and this dash
+                                 (js2-get-token)
+                                 (eq prev-token-end (js2-current-token-beg))
+                               (js2-unget-token)))
+                        (and allow-colon (= (js2-peek-token) js2-COLON))))
+          (if (setq matched-colon (js2-match-token js2-COLON))
+              (setf (rjsx-identifier-namespace pn) (apply #'concat (nreverse name-parts))
+                    allow-colon nil
+                    name-parts (list)
+                    name-start nil)
+            (when (= (js2-get-token) js2-ASSIGN_SUB) ; Otherwise it's a js2-SUB
+              (setf (js2-token-end (js2-current-token)) (1- (js2-current-token-end))
+                    (js2-token-type (js2-current-token)) js2-SUB
+                    (js2-token-string (js2-current-token)) "-"
+                    js2-ts-cursor (1+ (js2-current-token-beg))
+                    js2-ti-lookahead 0))
+            (push "-" name-parts))
+          (setq prev-token-end (js2-current-token-end))
+          (if (js2-match-token js2-NAME)
+              (if (eq prev-token-end (js2-current-token-beg))
+                  (progn (push (js2-current-token-string) name-parts)
+                         (setq prev-token-end (js2-current-token-end)
+                               name-start (or name-start (js2-current-token-beg))))
+                (js2-unget-token)
+                (setq continue nil))
+            (when (= js2-COLON (js2-current-token-type))
+              (js2-report-error "msg.bad.jsx.ident" nil beg (- (js2-current-token-end) beg)))
+            ;; We only keep going if this is an `ident-ending-with-dash-colon:'
+            (setq continue (and (not matched-colon) (= (js2-peek-token) js2-COLON)))))
+        (when face
+          (js2-set-face beg (js2-current-token-end) face 'record))
+        (let ((name-node (if name-start
+                             (make-js2-name-node :pos name-start
+                                                 :len (- (js2-current-token-end) name-start)
+                                                 :name (apply #'concat (nreverse name-parts)))
+                           (make-js2-name-node :pos (js2-current-token-end) :len 0 :name ""))))
+          (setf (js2-node-len pn) (- (js2-current-token-end) beg)
+                (rjsx-identifier-name pn) name-node)
+          (js2-node-add-children pn name-node))
+        pn)
+    (make-js2-error-node :len (js2-current-token-len))))
+
+(defun rjsx-parse-member-or-ns (&optional face)
+  "Parse a dotted expression or a namespaced identifier and fontify with FACE if given."
+  (let ((ident (rjsx-parse-identifier face)))
+    (cond
+     ((js2-error-node-p ident) ident)
+     ((rjsx-identifier-namespace ident) ident)
+     (t (rjsx-parse-member ident face)))))
+
+(defun rjsx-parse-member (ident &optional face)
+  "Parse a dotted member expression starting with IDENT and fontify with FACE.
+IDENT is the `rjsx-identifier' node for the first item in the
+member expression.  Returns a `js2-error-node' if unable to
+parse."
+  (let (idents dots-pos pn end)
+    (setq pn (make-rjsx-member :pos (js2-node-pos ident)))
+    (setq end (js2-current-token-end))
+    (push ident idents)
+    (while (and (js2-match-token js2-DOT) (not (js2-error-node-p ident)))
+      (push (js2-current-token-beg) dots-pos)
+      (setq end (js2-current-token-end))
+      (setq ident (rjsx-parse-identifier nil :allow-ns nil))
+      (push ident idents)
+      (unless (js2-error-node-p ident)
+        (setq end (js2-current-token-end)))
+      (js2-node-add-children pn ident))
+    (apply 'js2-node-add-children pn idents)
+    (setf (rjsx-member-idents pn) (nreverse idents)
+          (rjsx-member-dots-pos pn) (nreverse dots-pos)
+          (js2-node-len pn) (- end (js2-node-pos pn)))
+    (when face
+      (js2-set-face (js2-node-pos pn) end face 'record))
+    pn))
+
+
+(defun rjsx-parse-child (expect-fragment)
+  "Parse an XML child node.
+Child nodes include plain (unquoted) text, other XML elements,
+and {}-bracketed expressions.  Return the parsed child.
+
+EXPECT-FRAGMENT if t, indicates that `</>' should be parsed
+as a fragment closing node, and not as an empty tag."
+  (let ((tt (rjsx-get-next-xml-token)))
+    (rjsx-maybe-message "child type `%s'" tt)
+    (cond
+     ((= tt js2-LT)
+      (rjsx-maybe-message "xml-or-close")
+      (rjsx-parse-xml-or-closing-tag expect-fragment))
+
+     ((= tt js2-LC)
+      (rjsx-maybe-message "parsing expression { %s" (js2-peek-token))
+      (rjsx-parse-wrapped-expr t nil))
+
+     ((= tt rjsx-JSX-TEXT)
+      (rjsx-maybe-message "text node: '%s'" (js2-current-token-string))
+      (js2-set-face (js2-current-token-beg) (js2-current-token-end) 'rjsx-text 'record)
+      (js2-record-text-property (js2-current-token-beg) (js2-current-token-end)
+                                'syntax-table rjsx-text-syntax-table)
+      (make-rjsx-text :value (js2-current-token-string)))
+
+     ((= tt js2-ERROR)
+      (make-js2-error-node :len (js2-current-token-len)))
+
+     (t (error "Unexpected token type: %s" (js2-peek-token))))))
+
+(defun rjsx-parse-xml-or-closing-tag (expect-fragment)
+  "Parse a JSX tag, which could be a child or a closing tag.
+Return the parsed child, which is a `rjsx-closing-tag' if a
+closing tag was parsed.
+
+EXPECT-FRAGMENT if t, indicates that `</>' should be parsed
+as a fragment closing node, and not as an empty tag."
+  (let ((beg (js2-current-token-beg)) pn)
+    (rjsx-record-tag-bracket-face)
+    (if (and (not expect-fragment) (setq pn (rjsx-parse-empty-tag)))
+        pn
+      (if (js2-match-token js2-DIV)
+          (progn (rjsx-record-tag-bracket-face)
+                 (if (and expect-fragment (eq (js2-peek-token) js2-GT))
+                     (setq pn (make-rjsx-closing-tag :pos beg))
+                   (setq pn (make-rjsx-closing-tag :pos beg
+                                                   :name (rjsx-parse-member-or-ns 'rjsx-tag)))
+                   (js2-node-add-children pn (rjsx-closing-tag-name pn)))
+                 (if (js2-must-match js2-GT "msg.no.gt.in.closer" beg (- (js2-current-token-end) beg))
+                     (rjsx-record-tag-bracket-face)
+                   (rjsx-maybe-message "missing closing `>'"))
+                 (setf (js2-node-len pn) (- (js2-current-token-end) beg))
+                 pn)
+        (rjsx-maybe-message "parsing a child XML item")
+        (rjsx-parse-xml)))))
+
+(defun rjsx-get-next-xml-token ()
+  "Scan through the XML text and push one token onto the stack."
+  (setq js2-ts-string-buffer nil)  ; for recording the text
+  (when (> js2-ti-lookahead 0)
+    (setq js2-ts-cursor (js2-current-token-end))
+    (setq js2-ti-lookahead 0))
+
+  (let ((token (js2-new-token 0))
+        c)
+    (rjsx-maybe-message "Running the xml scanner")
+    (catch 'return
+      (while t
+        (setq c (js2-get-char))
+        (rjsx-maybe-message "'%s' (%s)" (if (= c js2-EOF_CHAR) "EOF" (char-to-string c)) c)
+        (cond
+         ((or (= c ?}) (= c ?>))
+          (js2-set-string-from-buffer token)
+          (setf (js2-token-type token) js2-ERROR)
+          (js2-report-scan-error "msg.syntax" t)
+          (throw 'return js2-ERROR))
+
+         ((or (= c ?<) (= c ?{))
+          (js2-unget-char)
+          (if js2-ts-string-buffer
+              (progn
+                (js2-set-string-from-buffer token)
+                (setf (js2-token-type token) rjsx-JSX-TEXT)
+                (rjsx-maybe-message "created rjsx-JSX-TEXT token: `%s'" (js2-token-string token))
+                (throw 'return rjsx-JSX-TEXT))
+            (js2-get-char)
+            (js2-set-string-from-buffer token)
+            (setf (js2-token-type token) (if (= c ?<) js2-LT js2-LC))
+            (setf (js2-token-string token) (string c))
+            (throw 'return (js2-token-type token))))
+
+         ((= c js2-EOF_CHAR)
+          (js2-set-string-from-buffer token)
+          (rjsx-maybe-message "Hit EOF. Current buffer: `%s'" (js2-token-string token))
+          (setf (js2-token-type token) js2-ERROR)
+          (rjsx-maybe-message "Scanner hit EOF. Panic!")
+          (signal 'rjsx-eof-while-parsing nil))
+         (t (js2-add-to-string c)))))))
+
+(js2-deflocal rjsx-buffer-chars-modified-tick 0 "Variable holding the last per-buffer value of `buffer-chars-modified-tick'.")
+
+(defun rjsx-maybe-reparse ()
+  "Called before accessing the parse tree.
+For small buffers, will do an immediate reparse to ensure the
+parse tree is up to date."
+  (when (and (<= (point-max) rjsx-max-size-for-frequent-reparse)
+             (/= rjsx-buffer-chars-modified-tick (buffer-chars-modified-tick)))
+    (js2-reparse)
+    (setq rjsx-buffer-chars-modified-tick (buffer-chars-modified-tick))))
+
+(defun rjsx--tag-at-point ()
+  "Return the JSX tag at point, if any, or nil."
+  (rjsx-maybe-reparse)
+  (let ((node (js2-node-at-point (point) t)))
+    (while (and node (not (rjsx-node-p node)))
+      (setq node (js2-node-parent node)))
+    node))
+
+
+;;;; Interactive commands and keybindings
+(defun rjsx-electric-lt (n)
+  "Insert a context-sensitive less-than sign.
+Optional prefix argument N indicates how many signs to insert.
+If N is greater than one, no special handling takes place.
+Otherwise, if the less-than sign would start a JSX block, it
+inserts `</>' and places the cursor inside the new tag."
+    (interactive "p")
+    (if (/= n 1)
+        (insert (make-string n ?<))
+      (if (save-excursion
+            (forward-comment most-negative-fixnum)
+            (skip-chars-backward "\n\r")
+            (or (= (point) (point-min))
+                (memq (char-before) (append "=(?:>}&|{," nil))
+                (let ((start (- (point) 6)))
+                  (and (>= start (point-min))
+                       (string= (buffer-substring start (point)) "return")))))
+          (progn (insert "</>")
+                 (backward-char 2))
+        (insert "<"))))
+
+(define-key rjsx-mode-map "<" 'rjsx-electric-lt)
+
+(defun rjsx-expand-self-closing-tag (node)
+  "Expand NODE into a balanced tag.
+Assumes NODE is self-closing `rjsx-node', and that point is at
+the self-closing slash."
+  (delete-char 1)
+  (search-forward ">")
+  (save-excursion
+    (insert "</" (rjsx-node-opening-tag-name node) ">")))
+
+(defun rjsx-electric-gt (n)
+  "Insert a context-sensitive greater-than sign.
+Optional prefix argument N indicates how many signs to insert.
+If N is greater than one, no special handling takes place.
+Otherwise, if point is in a self-closing JSX tag just before the
+slash, it creates a matching end-tag and places point just inside
+the tags."
+  (interactive "p")
+  (if (or (/= n 1)
+          (not (eq (get-char-property (point) 'rjsx-class) 'self-closing-slash)))
+      (insert (make-string n ?>))
+    (let ((node (rjsx--tag-at-point)))
+      (if node
+          (rjsx-expand-self-closing-tag node)
+        (insert (make-string n ?>))))))
+
+(define-key rjsx-mode-map ">" 'rjsx-electric-gt)
+
+(defun rjsx-delete-creates-full-tag (n &optional killflag)
+  "N and KILLFLAG are as in `delete-char'.
+If N is 1 and KILLFLAG nil, checks to see if we're in a
+self-closing tag about to delete the slash.  If so, deletes the
+slash and inserts a matching end-tag."
+  (interactive "p")
+  (if (or killflag (/= 1 n) (not (eq (get-char-property (point) 'rjsx-class) 'self-closing-slash)))
+      (if (called-interactively-p 'any)
+	  (call-interactively 'delete-forward-char)
+	(delete-char n killflag))
+    (let ((node (rjsx--tag-at-point)))
+      (if node
+          (rjsx-expand-self-closing-tag node)
+        (delete-char 1)))))
+
+(define-key rjsx-mode-map (kbd "C-d") 'rjsx-delete-creates-full-tag)
+
+(defun rjsx-rename-tag-at-point (new-name)
+  "Prompt for a new name and modify the tag at point.
+NEW-NAME is the name to give the tag."
+  (interactive "sNew tag name: ")
+  (let* ((tag (rjsx--tag-at-point))
+         (closer (and tag (rjsx-node-closing-tag tag))))
+    (cond
+     ((null tag) (message "No JSX tag found at point"))
+     ((null (rjsx-node-name tag))       ; fragment
+      (cl-assert closer nil "Fragment has no closing-tag")
+      (save-excursion
+        (goto-char (+ 2 (js2-node-abs-pos closer)))
+        (insert new-name)
+        (goto-char (1+ (js2-node-abs-pos tag)))
+        (insert new-name))
+      (js2-reparse))
+     (t
+      (let* ((head (rjsx-node-name tag))
+             (tail (when closer (rjsx-closing-tag-name closer)))
+             beg end)
+        (dolist (part (if tail (list tail head) (list head)))
+          (setq beg (js2-node-abs-pos part)
+                end (+ beg (js2-node-len part)))
+          (delete-region beg end)
+          (save-excursion (goto-char beg) (insert new-name)))
+        (js2-reparse))))))
+
+(define-key rjsx-mode-map (kbd "C-c C-r") 'rjsx-rename-tag-at-point)
+
+
+(provide 'rjsx-mode)
+;;; rjsx-mode.el ends here
+
+;; Local Variables:
+;; outline-regexp: ";;;\\(;* [^
+;; ]\\|###autoload\\)\\|(....."
+;; End:
diff --git a/configs/shared/emacs/.emacs.d/elpa/rjsx-mode-20180624.1758/rjsx-mode.elc b/configs/shared/emacs/.emacs.d/elpa/rjsx-mode-20180624.1758/rjsx-mode.elc
new file mode 100644
index 0000000000..aaedd00808
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/rjsx-mode-20180624.1758/rjsx-mode.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/s-20180406.108/s-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/s-20180406.108/s-autoloads.el
new file mode 100644
index 0000000000..1c0faed4fa
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/s-20180406.108/s-autoloads.el
@@ -0,0 +1,15 @@
+;;; s-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil nil ("s.el") (23377 60758 778636 293000))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; s-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/s-20180406.108/s-pkg.el b/configs/shared/emacs/.emacs.d/elpa/s-20180406.108/s-pkg.el
new file mode 100644
index 0000000000..7c6cf3a88c
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/s-20180406.108/s-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "s" "20180406.108" "The long lost Emacs string manipulation library." 'nil)
diff --git a/configs/shared/emacs/.emacs.d/elpa/s-20180406.108/s.el b/configs/shared/emacs/.emacs.d/elpa/s-20180406.108/s.el
new file mode 100644
index 0000000000..a5d640aa86
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/s-20180406.108/s.el
@@ -0,0 +1,747 @@
+;;; s.el --- The long lost Emacs string manipulation library.
+
+;; Copyright (C) 2012-2015 Magnar Sveen
+
+;; Author: Magnar Sveen <magnars@gmail.com>
+;; Version: 1.12.0
+;; Package-Version: 20180406.108
+;; Keywords: strings
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; The long lost Emacs string manipulation library.
+;;
+;; See documentation on https://github.com/magnars/s.el#functions
+
+;;; Code:
+
+;; Silence byte-compiler
+(defvar ucs-normalize-combining-chars)  ; Defined in `ucs-normalize'
+(autoload 'slot-value "eieio")
+
+(defun s-trim-left (s)
+  "Remove whitespace at the beginning of S."
+  (declare (pure t) (side-effect-free t))
+  (save-match-data
+    (if (string-match "\\`[ \t\n\r]+" s)
+        (replace-match "" t t s)
+      s)))
+
+(defun s-trim-right (s)
+  "Remove whitespace at the end of S."
+  (save-match-data
+    (declare (pure t) (side-effect-free t))
+    (if (string-match "[ \t\n\r]+\\'" s)
+        (replace-match "" t t s)
+      s)))
+
+(defun s-trim (s)
+  "Remove whitespace at the beginning and end of S."
+  (declare (pure t) (side-effect-free t))
+  (s-trim-left (s-trim-right s)))
+
+(defun s-collapse-whitespace (s)
+  "Convert all adjacent whitespace characters to a single space."
+  (declare (pure t) (side-effect-free t))
+  (replace-regexp-in-string "[ \t\n\r]+" " " s))
+
+(defun s-split (separator s &optional omit-nulls)
+  "Split S into substrings bounded by matches for regexp SEPARATOR.
+If OMIT-NULLS is non-nil, zero-length substrings are omitted.
+
+This is a simple wrapper around the built-in `split-string'."
+  (declare (side-effect-free t))
+  (save-match-data
+    (split-string s separator omit-nulls)))
+
+(defun s-split-up-to (separator s n &optional omit-nulls)
+  "Split S up to N times into substrings bounded by matches for regexp SEPARATOR.
+
+If OMIT-NULLS is non-nil, zero-length substrings are omitted.
+
+See also `s-split'."
+  (declare (side-effect-free t))
+  (save-match-data
+    (let ((op 0)
+          (r nil))
+      (with-temp-buffer
+        (insert s)
+        (setq op (goto-char (point-min)))
+        (while (and (re-search-forward separator nil t)
+                    (< 0 n))
+          (let ((sub (buffer-substring op (match-beginning 0))))
+            (unless (and omit-nulls
+                         (equal sub ""))
+              (push sub r)))
+          (setq op (goto-char (match-end 0)))
+          (setq n (1- n)))
+        (let ((sub (buffer-substring op (point-max))))
+          (unless (and omit-nulls
+                       (equal sub ""))
+            (push sub r))))
+      (nreverse r))))
+
+(defun s-lines (s)
+  "Splits S into a list of strings on newline characters."
+  (declare (pure t) (side-effect-free t))
+  (s-split "\\(\r\n\\|[\n\r]\\)" s))
+
+(defun s-join (separator strings)
+  "Join all the strings in STRINGS with SEPARATOR in between."
+  (declare (pure t) (side-effect-free t))
+  (mapconcat 'identity strings separator))
+
+(defun s-concat (&rest strings)
+  "Join all the string arguments into one string."
+  (declare (pure t) (side-effect-free t))
+  (apply 'concat strings))
+
+(defun s-prepend (prefix s)
+  "Concatenate PREFIX and S."
+  (declare (pure t) (side-effect-free t))
+  (concat prefix s))
+
+(defun s-append (suffix s)
+  "Concatenate S and SUFFIX."
+  (declare (pure t) (side-effect-free t))
+  (concat s suffix))
+
+(defun s-repeat (num s)
+  "Make a string of S repeated NUM times."
+  (declare (pure t) (side-effect-free t))
+  (let (ss)
+    (while (> num 0)
+      (setq ss (cons s ss))
+      (setq num (1- num)))
+    (apply 'concat ss)))
+
+(defun s-chop-suffix (suffix s)
+  "Remove SUFFIX if it is at end of S."
+  (declare (pure t) (side-effect-free t))
+  (let ((pos (- (length suffix))))
+    (if (and (>= (length s) (length suffix))
+             (string= suffix (substring s pos)))
+        (substring s 0 pos)
+      s)))
+
+(defun s-chop-suffixes (suffixes s)
+  "Remove SUFFIXES one by one in order, if they are at the end of S."
+  (declare (pure t) (side-effect-free t))
+  (while suffixes
+    (setq s (s-chop-suffix (car suffixes) s))
+    (setq suffixes (cdr suffixes)))
+  s)
+
+(defun s-chop-prefix (prefix s)
+  "Remove PREFIX if it is at the start of S."
+  (declare (pure t) (side-effect-free t))
+  (let ((pos (length prefix)))
+    (if (and (>= (length s) (length prefix))
+             (string= prefix (substring s 0 pos)))
+        (substring s pos)
+      s)))
+
+(defun s-chop-prefixes (prefixes s)
+  "Remove PREFIXES one by one in order, if they are at the start of S."
+  (declare (pure t) (side-effect-free t))
+  (while prefixes
+    (setq s (s-chop-prefix (car prefixes) s))
+    (setq prefixes (cdr prefixes)))
+  s)
+
+(defun s-shared-start (s1 s2)
+  "Returns the longest prefix S1 and S2 have in common."
+  (declare (pure t) (side-effect-free t))
+  (let ((search-length (min (length s1) (length s2)))
+        (i 0))
+    (while (and (< i search-length)
+                (= (aref s1 i) (aref s2 i)))
+      (setq i (1+ i)))
+    (substring s1 0 i)))
+
+(defun s-shared-end (s1 s2)
+  "Returns the longest suffix S1 and S2 have in common."
+  (declare (pure t) (side-effect-free t))
+  (let* ((l1 (length s1))
+         (l2 (length s2))
+         (search-length (min l1 l2))
+         (i 0))
+    (while (and (< i search-length)
+                (= (aref s1 (- l1 i 1)) (aref s2 (- l2 i 1))))
+      (setq i (1+ i)))
+    ;; If I is 0, then it means that there's no common suffix between
+    ;; S1 and S2.
+    ;;
+    ;; However, since (substring s (- 0)) will return the whole
+    ;; string, `s-shared-end' should simply return the empty string
+    ;; when I is 0.
+    (if (zerop i)
+        ""
+      (substring s1 (- i)))))
+
+(defun s-chomp (s)
+  "Remove one trailing `\\n`, `\\r` or `\\r\\n` from S."
+  (declare (pure t) (side-effect-free t))
+  (s-chop-suffixes '("\n" "\r") s))
+
+(defun s-truncate (len s &optional ellipsis)
+  "If S is longer than LEN, cut it down and add ELLIPSIS to the end.
+
+The resulting string, including ellipsis, will be LEN characters
+long.
+
+When not specified, ELLIPSIS defaults to ‘...’."
+  (declare (pure t) (side-effect-free t))
+  (unless ellipsis
+    (setq ellipsis "..."))
+  (if (> (length s) len)
+      (format "%s%s" (substring s 0 (- len (length ellipsis))) ellipsis)
+    s))
+
+(defun s-word-wrap (len s)
+  "If S is longer than LEN, wrap the words with newlines."
+  (declare (side-effect-free t))
+  (save-match-data
+    (with-temp-buffer
+      (insert s)
+      (let ((fill-column len))
+        (fill-region (point-min) (point-max)))
+      (buffer-substring (point-min) (point-max)))))
+
+(defun s-center (len s)
+  "If S is shorter than LEN, pad it with spaces so it is centered."
+  (declare (pure t) (side-effect-free t))
+  (let ((extra (max 0 (- len (length s)))))
+    (concat
+     (make-string (ceiling extra 2) ? )
+     s
+     (make-string (floor extra 2) ? ))))
+
+(defun s-pad-left (len padding s)
+  "If S is shorter than LEN, pad it with PADDING on the left."
+  (declare (pure t) (side-effect-free t))
+  (let ((extra (max 0 (- len (length s)))))
+    (concat (make-string extra (string-to-char padding))
+            s)))
+
+(defun s-pad-right (len padding s)
+  "If S is shorter than LEN, pad it with PADDING on the right."
+  (declare (pure t) (side-effect-free t))
+  (let ((extra (max 0 (- len (length s)))))
+    (concat s
+            (make-string extra (string-to-char padding)))))
+
+(defun s-left (len s)
+  "Returns up to the LEN first chars of S."
+  (declare (pure t) (side-effect-free t))
+  (if (> (length s) len)
+      (substring s 0 len)
+    s))
+
+(defun s-right (len s)
+  "Returns up to the LEN last chars of S."
+  (declare (pure t) (side-effect-free t))
+  (let ((l (length s)))
+    (if (> l len)
+        (substring s (- l len) l)
+      s)))
+
+(defun s-ends-with? (suffix s &optional ignore-case)
+  "Does S end with SUFFIX?
+
+If IGNORE-CASE is non-nil, the comparison is done without paying
+attention to case differences.
+
+Alias: `s-suffix?'"
+  (declare (pure t) (side-effect-free t))
+  (let ((start-pos (- (length s) (length suffix))))
+    (and (>= start-pos 0)
+         (eq t (compare-strings suffix nil nil
+                                s start-pos nil ignore-case)))))
+
+(defun s-starts-with? (prefix s &optional ignore-case)
+  "Does S start with PREFIX?
+
+If IGNORE-CASE is non-nil, the comparison is done without paying
+attention to case differences.
+
+Alias: `s-prefix?'. This is a simple wrapper around the built-in
+`string-prefix-p'."
+  (declare (pure t) (side-effect-free t))
+  (string-prefix-p prefix s ignore-case))
+
+(defun s--truthy? (val)
+  (declare (pure t) (side-effect-free t))
+  (not (null val)))
+
+(defun s-contains? (needle s &optional ignore-case)
+  "Does S contain NEEDLE?
+
+If IGNORE-CASE is non-nil, the comparison is done without paying
+attention to case differences."
+  (declare (pure t) (side-effect-free t))
+  (let ((case-fold-search ignore-case))
+    (s--truthy? (string-match-p (regexp-quote needle) s))))
+
+(defun s-equals? (s1 s2)
+  "Is S1 equal to S2?
+
+This is a simple wrapper around the built-in `string-equal'."
+  (declare (pure t) (side-effect-free t))
+  (string-equal s1 s2))
+
+(defun s-less? (s1 s2)
+  "Is S1 less than S2?
+
+This is a simple wrapper around the built-in `string-lessp'."
+  (declare (pure t) (side-effect-free t))
+  (string-lessp s1 s2))
+
+(defun s-matches? (regexp s &optional start)
+  "Does REGEXP match S?
+If START is non-nil the search starts at that index.
+
+This is a simple wrapper around the built-in `string-match-p'."
+  (declare (side-effect-free t))
+  (s--truthy? (string-match-p regexp s start)))
+
+(defun s-blank? (s)
+  "Is S nil or the empty string?"
+  (declare (pure t) (side-effect-free t))
+  (or (null s) (string= "" s)))
+
+(defun s-blank-str? (s)
+  "Is S nil or the empty string or string only contains whitespace?"
+  (declare (pure t) (side-effect-free t))
+  (or (s-blank? s) (s-blank? (s-trim s))))
+
+(defun s-present? (s)
+  "Is S anything but nil or the empty string?"
+  (declare (pure t) (side-effect-free t))
+  (not (s-blank? s)))
+
+(defun s-presence (s)
+  "Return S if it's `s-present?', otherwise return nil."
+  (declare (pure t) (side-effect-free t))
+  (and (s-present? s) s))
+
+(defun s-lowercase? (s)
+  "Are all the letters in S in lower case?"
+  (declare (side-effect-free t))
+  (let ((case-fold-search nil))
+    (not (string-match-p "[[:upper:]]" s))))
+
+(defun s-uppercase? (s)
+  "Are all the letters in S in upper case?"
+  (declare (side-effect-free t))
+  (let ((case-fold-search nil))
+    (not (string-match-p "[[:lower:]]" s))))
+
+(defun s-mixedcase? (s)
+  "Are there both lower case and upper case letters in S?"
+  (let ((case-fold-search nil))
+    (s--truthy?
+     (and (string-match-p "[[:lower:]]" s)
+          (string-match-p "[[:upper:]]" s)))))
+
+(defun s-capitalized? (s)
+  "In S, is the first letter upper case, and all other letters lower case?"
+  (declare (side-effect-free t))
+  (let ((case-fold-search nil))
+    (s--truthy?
+     (string-match-p "^[[:upper:]][^[:upper:]]*$" s))))
+
+(defun s-numeric? (s)
+  "Is S a number?"
+  (declare (pure t) (side-effect-free t))
+  (s--truthy?
+   (string-match-p "^[0-9]+$" s)))
+
+(defun s-replace (old new s)
+  "Replaces OLD with NEW in S."
+  (declare (pure t) (side-effect-free t))
+  (replace-regexp-in-string (regexp-quote old) new s t t))
+
+(defalias 's-replace-regexp 'replace-regexp-in-string)
+
+(defun s--aget (alist key)
+  (declare (pure t) (side-effect-free t))
+  (cdr (assoc-string key alist)))
+
+(defun s-replace-all (replacements s)
+  "REPLACEMENTS is a list of cons-cells. Each `car` is replaced with `cdr` in S."
+  (declare (pure t) (side-effect-free t))
+  (replace-regexp-in-string (regexp-opt (mapcar 'car replacements))
+                            (lambda (it) (s--aget replacements it))
+                            s t t))
+
+(defun s-downcase (s)
+  "Convert S to lower case.
+
+This is a simple wrapper around the built-in `downcase'."
+  (declare (side-effect-free t))
+  (downcase s))
+
+(defun s-upcase (s)
+  "Convert S to upper case.
+
+This is a simple wrapper around the built-in `upcase'."
+  (declare (side-effect-free t))
+  (upcase s))
+
+(defun s-capitalize (s)
+  "Convert the first word's first character to upper case and the rest to lower case in S."
+  (declare (side-effect-free t))
+  (concat (upcase (substring s 0 1)) (downcase (substring s 1))))
+
+(defun s-titleize (s)
+  "Convert each word's first character to upper case and the rest to lower case in S.
+
+This is a simple wrapper around the built-in `capitalize'."
+  (declare (side-effect-free t))
+  (capitalize s))
+
+(defmacro s-with (s form &rest more)
+  "Threads S through the forms. Inserts S as the last item
+in the first form, making a list of it if it is not a list
+already. If there are more forms, inserts the first form as the
+last item in second form, etc."
+  (declare (debug (form &rest [&or (function &rest form) fboundp])))
+  (if (null more)
+      (if (listp form)
+          `(,(car form) ,@(cdr form) ,s)
+        (list form s))
+    `(s-with (s-with ,s ,form) ,@more)))
+
+(put 's-with 'lisp-indent-function 1)
+
+(defun s-index-of (needle s &optional ignore-case)
+  "Returns first index of NEEDLE in S, or nil.
+
+If IGNORE-CASE is non-nil, the comparison is done without paying
+attention to case differences."
+  (declare (pure t) (side-effect-free t))
+  (let ((case-fold-search ignore-case))
+    (string-match-p (regexp-quote needle) s)))
+
+(defun s-reverse (s)
+  "Return the reverse of S."
+  (declare (pure t) (side-effect-free t))
+  (save-match-data
+    (if (multibyte-string-p s)
+        (let ((input (string-to-list s))
+              output)
+          (require 'ucs-normalize)
+          (while input
+            ;; Handle entire grapheme cluster as a single unit
+            (let ((grapheme (list (pop input))))
+              (while (memql (car input) ucs-normalize-combining-chars)
+                (push (pop input) grapheme))
+              (setq output (nconc (nreverse grapheme) output))))
+          (concat output))
+      (concat (nreverse (string-to-list s))))))
+
+(defun s-match-strings-all (regex string)
+  "Return a list of matches for REGEX in STRING.
+
+Each element itself is a list of matches, as per
+`match-string'. Multiple matches at the same position will be
+ignored after the first."
+  (declare (side-effect-free t))
+  (save-match-data
+    (let ((all-strings ())
+          (i 0))
+      (while (and (< i (length string))
+                  (string-match regex string i))
+        (setq i (1+ (match-beginning 0)))
+        (let (strings
+              (num-matches (/ (length (match-data)) 2))
+              (match 0))
+          (while (/= match num-matches)
+            (push (match-string match string) strings)
+            (setq match (1+ match)))
+          (push (nreverse strings) all-strings)))
+      (nreverse all-strings))))
+
+(defun s-matched-positions-all (regexp string &optional subexp-depth)
+  "Return a list of matched positions for REGEXP in STRING.
+SUBEXP-DEPTH is 0 by default."
+  (declare (side-effect-free t))
+  (if (null subexp-depth)
+      (setq subexp-depth 0))
+  (save-match-data
+    (let ((pos 0) result)
+      (while (and (string-match regexp string pos)
+                  (< pos (length string)))
+        (let ((m (match-end subexp-depth)))
+          (push (cons (match-beginning subexp-depth) (match-end subexp-depth)) result)
+          (setq pos (match-end 0))))
+      (nreverse result))))
+
+(defun s-match (regexp s &optional start)
+  "When the given expression matches the string, this function returns a list
+of the whole matching string and a string for each matched subexpressions.
+If it did not match the returned value is an empty list (nil).
+
+When START is non-nil the search will start at that index."
+  (declare (side-effect-free t))
+  (save-match-data
+    (if (string-match regexp s start)
+        (let ((match-data-list (match-data))
+              result)
+          (while match-data-list
+            (let* ((beg (car match-data-list))
+                   (end (cadr match-data-list))
+                   (subs (if (and beg end) (substring s beg end) nil)))
+              (setq result (cons subs result))
+              (setq match-data-list
+                    (cddr match-data-list))))
+          (nreverse result)))))
+
+(defun s-slice-at (regexp s)
+  "Slices S up at every index matching REGEXP."
+  (declare (side-effect-free t))
+  (if (= 0 (length s)) (list "")
+    (save-match-data
+      (let (i)
+        (setq i (string-match regexp s 1))
+        (if i
+            (cons (substring s 0 i)
+                  (s-slice-at regexp (substring s i)))
+          (list s))))))
+
+(defun s-split-words (s)
+  "Split S into list of words."
+  (declare (side-effect-free t))
+  (s-split
+   "[^[:word:]0-9]+"
+   (let ((case-fold-search nil))
+     (replace-regexp-in-string
+      "\\([[:lower:]]\\)\\([[:upper:]]\\)" "\\1 \\2"
+      (replace-regexp-in-string "\\([[:upper:]]\\)\\([[:upper:]][0-9[:lower:]]\\)" "\\1 \\2" s)))
+   t))
+
+(defun s--mapcar-head (fn-head fn-rest list)
+  "Like MAPCAR, but applies a different function to the first element."
+  (if list
+      (cons (funcall fn-head (car list)) (mapcar fn-rest (cdr list)))))
+
+(defun s-lower-camel-case (s)
+  "Convert S to lowerCamelCase."
+  (declare (side-effect-free t))
+  (s-join "" (s--mapcar-head 'downcase 'capitalize (s-split-words s))))
+
+(defun s-upper-camel-case (s)
+  "Convert S to UpperCamelCase."
+  (declare (side-effect-free t))
+  (s-join "" (mapcar 'capitalize (s-split-words s))))
+
+(defun s-snake-case (s)
+  "Convert S to snake_case."
+  (declare (side-effect-free t))
+  (s-join "_" (mapcar 'downcase (s-split-words s))))
+
+(defun s-dashed-words (s)
+  "Convert S to dashed-words."
+  (declare (side-effect-free t))
+  (s-join "-" (mapcar 'downcase (s-split-words s))))
+
+(defun s-capitalized-words (s)
+  "Convert S to Capitalized words."
+  (declare (side-effect-free t))
+  (let ((words (s-split-words s)))
+    (s-join " " (cons (capitalize (car words)) (mapcar 'downcase (cdr words))))))
+
+(defun s-titleized-words (s)
+  "Convert S to Titleized Words."
+  (declare (side-effect-free t))
+  (s-join " " (mapcar 's-titleize (s-split-words s))))
+
+(defun s-word-initials (s)
+  "Convert S to its initials."
+  (declare (side-effect-free t))
+  (s-join "" (mapcar (lambda (ss) (substring ss 0 1))
+                     (s-split-words s))))
+
+;; Errors for s-format
+(progn
+  (put 's-format-resolve
+       'error-conditions
+       '(error s-format s-format-resolve))
+  (put 's-format-resolve
+       'error-message
+       "Cannot resolve a template to values"))
+
+(defun s-format (template replacer &optional extra)
+  "Format TEMPLATE with the function REPLACER.
+
+REPLACER takes an argument of the format variable and optionally
+an extra argument which is the EXTRA value from the call to
+`s-format'.
+
+Several standard `s-format' helper functions are recognized and
+adapted for this:
+
+    (s-format \"${name}\" 'gethash hash-table)
+    (s-format \"${name}\" 'aget alist)
+    (s-format \"$0\" 'elt sequence)
+
+The REPLACER function may be used to do any other kind of
+transformation."
+  (let ((saved-match-data (match-data)))
+    (unwind-protect
+        (replace-regexp-in-string
+         "\\$\\({\\([^}]+\\)}\\|[0-9]+\\)"
+         (lambda (md)
+           (let ((var
+                  (let ((m (match-string 2 md)))
+                    (if m m
+                      (string-to-number (match-string 1 md)))))
+                 (replacer-match-data (match-data)))
+             (unwind-protect
+                 (let ((v
+                        (cond
+                         ((eq replacer 'gethash)
+                          (funcall replacer var extra))
+                         ((eq replacer 'aget)
+                          (funcall 's--aget extra var))
+                         ((eq replacer 'elt)
+                          (funcall replacer extra var))
+                         ((eq replacer 'oref)
+                          (funcall #'slot-value extra (intern var)))
+                         (t
+                          (set-match-data saved-match-data)
+                          (if extra
+                              (funcall replacer var extra)
+                            (funcall replacer var))))))
+                   (if v (format "%s" v) (signal 's-format-resolve md)))
+               (set-match-data replacer-match-data)))) template
+               ;; Need literal to make sure it works
+               t t)
+      (set-match-data saved-match-data))))
+
+(defvar s-lex-value-as-lisp nil
+  "If `t' interpolate lisp values as lisp.
+
+`s-lex-format' inserts values with (format \"%S\").")
+
+(defun s-lex-fmt|expand (fmt)
+  "Expand FMT into lisp."
+  (declare (side-effect-free t))
+  (list 's-format fmt (quote 'aget)
+        (append '(list)
+                (mapcar
+                 (lambda (matches)
+                   (list
+                    'cons
+                    (cadr matches)
+                    `(format
+                      (if s-lex-value-as-lisp "%S" "%s")
+                      ,(intern (cadr matches)))))
+                 (s-match-strings-all "${\\([^}]+\\)}" fmt)))))
+
+(defmacro s-lex-format (format-str)
+  "`s-format` with the current environment.
+
+FORMAT-STR may use the `s-format' variable reference to refer to
+any variable:
+
+ (let ((x 1))
+   (s-lex-format \"x is: ${x}\"))
+
+The values of the variables are interpolated with \"%s\" unless
+the variable `s-lex-value-as-lisp' is `t' and then they are
+interpolated with \"%S\"."
+  (declare (debug (form)))
+  (s-lex-fmt|expand format-str))
+
+(defun s-count-matches (regexp s &optional start end)
+  "Count occurrences of `regexp' in `s'.
+
+`start', inclusive, and `end', exclusive, delimit the part of `s' to
+match.  `start' and `end' are both indexed starting at 1; the initial
+character in `s' is index 1.
+
+This function starts looking for the next match from the end of the
+previous match.  Hence, it ignores matches that overlap a previously
+found match.  To count overlapping matches, use
+`s-count-matches-all'."
+  (declare (side-effect-free t))
+  (save-match-data
+    (with-temp-buffer
+      (insert s)
+      (goto-char (point-min))
+      (count-matches regexp (or start 1) (or end (point-max))))))
+
+(defun s-count-matches-all (regexp s &optional start end)
+  "Count occurrences of `regexp' in `s'.
+
+`start', inclusive, and `end', exclusive, delimit the part of `s' to
+match.  `start' and `end' are both indexed starting at 1; the initial
+character in `s' is index 1.
+
+This function starts looking for the next match from the second
+character of the previous match.  Hence, it counts matches that
+overlap a previously found match.  To ignore matches that overlap a
+previously found match, use `s-count-matches'."
+  (declare (side-effect-free t))
+  (let* ((anchored-regexp (format "^%s" regexp))
+         (match-count 0)
+         (i 0)
+         (narrowed-s (substring s
+                                (when start (1- start))
+                                (when end (1- end)))))
+    (save-match-data
+      (while (< i (length narrowed-s))
+        (when (s-matches? anchored-regexp (substring narrowed-s i))
+          (setq match-count (1+ match-count)))
+        (setq i (1+ i))))
+    match-count))
+
+(defun s-wrap (s prefix &optional suffix)
+  "Wrap string S with PREFIX and optionally SUFFIX.
+
+Return string S with PREFIX prepended.  If SUFFIX is present, it
+is appended, otherwise PREFIX is used as both prefix and
+suffix."
+  (declare (pure t) (side-effect-free t))
+  (concat prefix s (or suffix prefix)))
+
+
+;;; Aliases
+
+(defalias 's-blank-p 's-blank?)
+(defalias 's-blank-str-p 's-blank-str?)
+(defalias 's-capitalized-p 's-capitalized?)
+(defalias 's-contains-p 's-contains?)
+(defalias 's-ends-with-p 's-ends-with?)
+(defalias 's-equals-p 's-equals?)
+(defalias 's-less-p 's-less?)
+(defalias 's-lowercase-p 's-lowercase?)
+(defalias 's-matches-p 's-matches?)
+(defalias 's-mixedcase-p 's-mixedcase?)
+(defalias 's-numeric-p 's-numeric?)
+(defalias 's-prefix-p 's-starts-with?)
+(defalias 's-prefix? 's-starts-with?)
+(defalias 's-present-p 's-present?)
+(defalias 's-starts-with-p 's-starts-with?)
+(defalias 's-suffix-p 's-ends-with?)
+(defalias 's-suffix? 's-ends-with?)
+(defalias 's-uppercase-p 's-uppercase?)
+
+
+(provide 's)
+;;; s.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/s-20180406.108/s.elc b/configs/shared/emacs/.emacs.d/elpa/s-20180406.108/s.elc
new file mode 100644
index 0000000000..ab34a2d9ee
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/s-20180406.108/s.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/seq-2.20.signed b/configs/shared/emacs/.emacs.d/elpa/seq-2.20.signed
new file mode 100644
index 0000000000..dd7b458ae0
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/seq-2.20.signed
@@ -0,0 +1 @@
+Good signature from 474F05837FBDEF9B GNU ELPA Signing Agent <elpasign@elpa.gnu.org> (trust undefined) created at 2017-05-04T17:05:02-0400 using DSA
\ No newline at end of file
diff --git a/configs/shared/emacs/.emacs.d/elpa/seq-2.20/ChangeLog b/configs/shared/emacs/.emacs.d/elpa/seq-2.20/ChangeLog
new file mode 100644
index 0000000000..07f4988ecb
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/seq-2.20/ChangeLog
@@ -0,0 +1,195 @@
+2017-05-04  Nicolas Petton  <nicolas@petton.fr>
+
+	Update seq.el to 2.20
+
+2016-12-16  Nicolas Petton  <nicolas@petton.fr>
+
+	Backport the latest changes to seq.el from Emacs master
+
+	* packages/seq/seq-24.el:
+	* packages/seq/seq-25.el (seq-into): Do not convert the sequence if not
+	needed.
+	* packages/seq/tests/seq-tests.el: Add a regression test.
+
+2016-12-15  Nicolas Petton  <nicolas@petton.fr>
+
+	Backport seq-mapn fix from Emacs master
+
+	* packages/seq/seq-24.el (seq-mapn):
+	* packages/seq/seq-25.el (seq-mapn): Fix for circular lists.
+	* packages/seq/tests/seq-tests.el: Add a regression test.
+
+2016-11-16  Nicolas Petton  <nicolas@petton.fr>
+
+	Do not use map.el in seq-tests.el
+
+	* packages/seq/tests/seq-tests.el: Do not use map.el.  map.el was 
+	introduced in Emacs 25.1, but seq.el is also available in GNU ELPA for 
+	Emacs 24.5.
+
+2016-10-25  Nicolas Petton  <nicolas@petton.fr>
+
+	Fix seq-random-elt docstring
+
+	* packages/seq/seq-24.el:
+	* packages/seq/seq-25.el (seq-random-elt): Fix the docstring.
+
+2016-10-25  Nicolas Petton  <nicolas@petton.fr>
+
+	Backport seq.el changes from Emacs master
+
+	* packages/seq/seq-24.el:
+	* packages/seq/seq-25.el (seq-random-elt): New function.
+	* packages/seq/seq.el: Bump version to 2.19.
+	* packages/seq/tests/seq-tests.el: Add tests for seq-random-elt.
+
+2016-09-02  Clément Pit--Claudel	 <clement.pitclaudel@live.com>
+
+	; Fix documentation of seq-subseq
+
+2016-08-28  Nicolas Petton  <nicolas@petton.fr>
+
+	* packages/seq/seq-24.el: Rename seq-p to seqp
+
+2016-06-12  Nicolas Petton  <nicolas@petton.fr>
+
+	Update seq.el to 2.16
+
+	* packages/seq/seq-24.el:
+	* packages/seq/seq-25.el: Better implementation of seq-drop for lists.
+	* packages/seq/seq.el: Bump version number.
+
+2016-04-22  Stefan Monnier  <monnier@iro.umontreal.ca>
+
+	* seq-24.el (seq-concatenate,seq-into,seq--make-bindings): Use _
+
+	rather than t as catch-all for pcase.
+
+2016-03-31  Nicolas Petton  <nicolas@petton.fr>
+
+	Update seq to version 2.15
+
+	* packages/seq/seq-25.el: Require cl-lib.
+	* packages/seq/seq.el: Bump version number.
+
+2016-03-29  Nicolas Petton  <nicolas@petton.fr>
+
+	Update seq.el to version 2.14
+
+	* packages/seq/seq.el: Bump version number.
+	* packages/seq/seq-24.el (seq-sort-by): New function.
+	* packages/seq/seq-25.el (seq-sort-by): New function.
+	* packages/seq/tests/seq-tests.el: Add a test for seq-sort-by.
+
+2016-03-25  Nicolas Petton  <nicolas@petton.fr>
+
+	* packages/seq/seq-25.el: Better declarations for seq--when-emacs-25-p
+
+2016-03-25  Nicolas Petton  <nicolas@petton.fr>
+
+	Split seq.el into separate files for different versions of Emacs
+
+	All functions in seq-25.el are wrapped in a `seq--when-emacs-25-p' to 
+	make sure that the byte compiler won't emit warnings or errors when the 
+	file is byte compiled in Emacs < 25.
+
+	* packages/seq/seq-24.el:
+	* packages/seq/seq-25.el: New files.
+	* packages/seq/seq.el: Load seq-VERSION.el based on the version of
+	Emacs.
+	* packages/seq/test/seq.el-test.el: Backport a test from seq.el in Emacs
+	 master.
+
+2015-11-30  Stefan Monnier  <monnier@iro.umontreal.ca>
+
+	* packages/seq: Don't define it as a :core package
+
+	Revert the removal of packages/seq/seq.el since it's different from the
+	one in lisp/emacs-lisp.
+	* .gitignore: Remove packages/seq.
+	* externals-list: Remove "seq" entry.
+
+2015-11-29  Stefan Monnier  <monnier@iro.umontreal.ca>
+
+	* externals-list: Add seq and python as :core packages
+
+	* .gitignore: Add packages/{seq,python}.
+	* packages/seq: Remove.
+
+2015-10-20  Nicolas Petton  <nicolas@petton.fr>
+
+	Update seq.el to version 1.11
+
+	* packages/seq/seq.el:
+	* packages/seq/tests/seq-tests.el: Update.
+
+2015-09-18  Nicolas Petton  <nicolas@petton.fr>
+
+	Update seq.el to version 1.9
+
+	* packages/seq/seq.el: Update to version 1.9.
+	* packages/seq/tests/seq-tests.el: Update to version 1.9.
+
+2015-07-09  Nicolas Petton  <nicolas@petton.fr>
+
+	Update seq.el to version 1.8
+
+	* packages/seq/seq.el: Update to version 1.8.
+	* packages/seq/tests/seq-tests.el: Update to version 1.8.
+
+2015-05-15  Nicolas Petton  <nicolas@petton.fr>
+
+	Update seq.el to version 1.7
+
+	* packages/seq/seq.el: Update to version 1.7.
+	* packages/seq/tests/seq-tests.el: Update to version 1.7.
+
+2015-04-27  Nicolas Petton  <nicolas@petton.fr>
+
+	* packages/seq/seq.el: Update seq.el to version 1.5.
+
+2015-04-15  Nicolas Petton  <nicolas@petton.fr>
+
+	seq.el update
+
+	* packages/seq/seq.el: Update seq.el to version 1.4
+	* packages/seq/tests/seq-tests.el: Update seq.el to version 1.4
+
+2015-03-25  Nicolas Petton  <nicolas@petton.fr>
+
+	Rephrases a comment in seq.el about the order of the arguments
+
+	* packages/seq/seq.el: Better comment about the order of the arguments
+
+2015-03-09  Nicolas Petton  <nicolas@petton.fr>
+
+	Update seq.el to version 1.3
+
+	* packages/seq/seq.el: update to version 1.3
+	* packages/seq/tests/seq-tests.el: update to version 1.3
+
+2015-02-11  Nicolas Petton  <nicolas@petton.fr>
+
+	Update seq.el to version 1.2
+
+	* package/seq/seq.el: Update to version 1.2
+	* packages/seq/tests/seq-tests.el: Update to version 1.2
+
+2015-02-09  Nicolas Petton  <nicolas@petton.fr>
+
+	Update seq.el to version 1.1.1
+
+	* package/seq/seq.el: Update to version 1.1.1
+	* packages/seq/tests/seq-tests.el: Update to version 1.1.1
+
+2015-02-06  Nicolas Petton  <nicolas@petton.fr>
+
+	Update seq.el to version 1.1
+
+	* packages/seq/seq.el: Update to version 1.1
+	* packages/seq/tests/seq-tests.el: Update to version 1.1
+
+2015-01-14  Nicolas Petton  <nicolas@petton.fr>
+
+	packages/seq: New package
+
diff --git a/configs/shared/emacs/.emacs.d/elpa/seq-2.20/seq-24.el b/configs/shared/emacs/.emacs.d/elpa/seq-2.20/seq-24.el
new file mode 100644
index 0000000000..d7ea729e8c
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/seq-2.20/seq-24.el
@@ -0,0 +1,496 @@
+;;; seq-24.el --- seq.el implementation for Emacs 24.x -*- lexical-binding: t -*-
+
+;; Copyright (C) 2014-2016 Free Software Foundation, Inc.
+
+;; Author: Nicolas Petton <nicolas@petton.fr>
+;; Keywords: sequences
+
+;; Maintainer: emacs-devel@gnu.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:
+
+;; Sequence-manipulation functions that complement basic functions
+;; provided by subr.el.
+;;
+;; All functions are prefixed with "seq-".
+;;
+;; All provided functions work on lists, strings and vectors.
+;;
+;; Functions taking a predicate or iterating over a sequence using a
+;; function as argument take the function as their first argument and
+;; the sequence as their second argument.  All other functions take
+;; the sequence as their first argument.
+
+;;; Code:
+
+(defmacro seq-doseq (spec &rest body)
+  "Loop over a sequence.
+Similar to `dolist' but can be applied to lists, strings, and vectors.
+
+Evaluate BODY with VAR bound to each element of SEQ, in turn.
+
+\(fn (VAR SEQ) BODY...)"
+  (declare (indent 1) (debug ((symbolp form &optional form) body)))
+  (let ((length (make-symbol "length"))
+        (seq (make-symbol "seq"))
+        (index (make-symbol "index")))
+    `(let* ((,seq ,(cadr spec))
+            (,length (if (listp ,seq) nil (seq-length ,seq)))
+            (,index (if ,length 0 ,seq)))
+       (while (if ,length
+                  (< ,index ,length)
+                (consp ,index))
+         (let ((,(car spec) (if ,length
+                                (prog1 (seq-elt ,seq ,index)
+                                  (setq ,index (+ ,index 1)))
+                              (pop ,index))))
+           ,@body)))))
+
+;; Implementation of `seq-let' compatible with Emacs<25.1.
+(defmacro seq-let (args sequence &rest body)
+  "Bind the variables in ARGS to the elements of SEQUENCE then evaluate BODY.
+
+ARGS can also include the `&rest' marker followed by a variable
+name to be bound to the rest of SEQUENCE."
+  (declare (indent 2) (debug t))
+  (let ((seq-var (make-symbol "seq")))
+    `(let* ((,seq-var ,sequence)
+            ,@(seq--make-bindings args seq-var))
+       ,@body)))
+
+(defun seq-drop (sequence n)
+  "Return a subsequence of SEQUENCE without its first N elements.
+The result is a sequence of the same type as SEQUENCE.
+
+If N is a negative integer or zero, SEQUENCE is returned."
+  (if (<= n 0)
+      sequence
+    (if (listp sequence)
+        (seq--drop-list sequence n)
+      (let ((length (seq-length sequence)))
+        (seq-subseq sequence (min n length) length)))))
+
+(defun seq-take (sequence n)
+  "Return a subsequence of SEQUENCE with its first N elements.
+The result is a sequence of the same type as SEQUENCE.
+
+If N is a negative integer or zero, an empty sequence is
+returned."
+  (if (listp sequence)
+      (seq--take-list sequence n)
+    (seq-subseq sequence 0 (min (max n 0) (seq-length sequence)))))
+
+(defun seq-drop-while (predicate sequence)
+  "Return a sequence from the first element for which (PREDICATE element) is nil in SEQUENCE.
+The result is a sequence of the same type as SEQUENCE."
+  (if (listp sequence)
+      (seq--drop-while-list predicate sequence)
+    (seq-drop sequence (seq--count-successive predicate sequence))))
+
+(defun seq-take-while (predicate sequence)
+  "Return the successive elements for which (PREDICATE element) is non-nil in SEQUENCE.
+The result is a sequence of the same type as SEQUENCE."
+  (if (listp sequence)
+      (seq--take-while-list predicate sequence)
+    (seq-take sequence (seq--count-successive predicate sequence))))
+
+(defun seq-filter (predicate sequence)
+  "Return a list of all the elements for which (PREDICATE element) is non-nil in SEQUENCE."
+  (let ((exclude (make-symbol "exclude")))
+    (delq exclude (seq-map (lambda (elt)
+                             (if (funcall predicate elt)
+                                 elt
+                               exclude))
+                           sequence))))
+
+(defun seq-map-indexed (function sequence)
+  "Return the result of applying FUNCTION to each element of SEQUENCE.
+Unlike `seq-map', FUNCTION takes two arguments: the element of
+the sequence, and its index within the sequence."
+  (let ((index 0))
+    (seq-map (lambda (elt)
+               (prog1
+                   (funcall function elt index)
+                 (setq index (1+ index))))
+             sequence)))
+
+(defun seq-remove (predicate sequence)
+  "Return a list of all the elements for which (PREDICATE element) is nil in SEQUENCE."
+  (seq-filter (lambda (elt) (not (funcall predicate elt)))
+              sequence))
+
+(defun seq-reduce (function sequence initial-value)
+  "Reduce the function FUNCTION across SEQUENCE, starting with INITIAL-VALUE.
+
+Return the result of calling FUNCTION with INITIAL-VALUE and the
+first element of SEQUENCE, then calling FUNCTION with that result and
+the second element of SEQUENCE, then with that result and the third
+element of SEQUENCE, etc.
+
+If SEQUENCE is empty, return INITIAL-VALUE and FUNCTION is not called."
+  (if (seq-empty-p sequence)
+      initial-value
+    (let ((acc initial-value))
+      (seq-doseq (elt sequence)
+        (setq acc (funcall function acc elt)))
+      acc)))
+
+(defun seq-some (predicate sequence)
+  "Return the first value for which if (PREDICATE element) is non-nil for in SEQUENCE."
+  (catch 'seq--break
+    (seq-doseq (elt sequence)
+      (let ((result (funcall predicate elt)))
+        (when result
+          (throw 'seq--break result))))
+    nil))
+
+(defun seq-find (predicate sequence &optional default)
+  "Return the first element for which (PREDICATE element) is non-nil in SEQUENCE.
+If no element is found, return DEFAULT.
+
+Note that `seq-find' has an ambiguity if the found element is
+identical to DEFAULT, as it cannot be known if an element was
+found or not."
+  (catch 'seq--break
+    (seq-doseq (elt sequence)
+      (when (funcall predicate elt)
+        (throw 'seq--break elt)))
+    default))
+
+(defun seq-every-p (predicate sequence)
+  "Return non-nil if (PREDICATE element) is non-nil for all elements of the sequence SEQUENCE."
+  (catch 'seq--break
+    (seq-doseq (elt sequence)
+      (or (funcall predicate elt)
+          (throw 'seq--break nil)))
+    t))
+
+(defun seq-count (predicate sequence)
+  "Return the number of elements for which (PREDICATE element) is non-nil in SEQUENCE."
+  (let ((count 0))
+    (seq-doseq (elt sequence)
+      (when (funcall predicate elt)
+        (setq count (+ 1 count))))
+    count))
+
+(defun seq-empty-p (sequence)
+  "Return non-nil if the sequence SEQUENCE is empty, nil otherwise."
+  (if (listp sequence)
+      (null sequence)
+    (= 0 (seq-length sequence))))
+
+(defun seq-sort (predicate sequence)
+  "Return a sorted sequence comparing using PREDICATE the elements of SEQUENCE.
+The result is a sequence of the same type as SEQUENCE."
+  (if (listp sequence)
+      (sort (seq-copy sequence) predicate)
+    (let ((result (seq-sort predicate (append sequence nil))))
+      (seq-into result (type-of sequence)))))
+
+(defun seq-sort-by (function pred sequence)
+  "Sort SEQUENCE using PRED as a comparison function.
+Elements of SEQUENCE are transformed by FUNCTION before being
+sorted.  FUNCTION must be a function of one argument."
+  (seq-sort (lambda (a b)
+              (funcall pred
+                       (funcall function a)
+                       (funcall function b)))
+            sequence))
+
+(defun seq-contains (sequence elt &optional testfn)
+  "Return the first element in SEQUENCE that equals to ELT.
+Equality is defined by TESTFN if non-nil or by `equal' if nil."
+  (seq-some (lambda (e)
+                (funcall (or testfn #'equal) elt e))
+              sequence))
+
+(defun seq-set-equal-p (sequence1 sequence2 &optional testfn)
+  "Return non-nil if SEQUENCE1 and SEQUENCE2 contain the same elements, regardless of order.
+Equality is defined by TESTFN if non-nil or by `equal' if nil."
+  (and (seq-every-p (lambda (item1) (seq-contains sequence2 item1 testfn)) sequence1)
+       (seq-every-p (lambda (item2) (seq-contains sequence1 item2 testfn)) sequence2)))
+
+(defun seq-position (sequence elt &optional testfn)
+  "Return the index of the first element in SEQUENCE that is equal to ELT.
+Equality is defined by TESTFN if non-nil or by `equal' if nil."
+  (let ((index 0))
+    (catch 'seq--break
+      (seq-doseq (e sequence)
+        (when (funcall (or testfn #'equal) e elt)
+          (throw 'seq--break index))
+        (setq index (1+ index)))
+      nil)))
+
+(defun seq-uniq (sequence &optional testfn)
+  "Return a list of the elements of SEQUENCE with duplicates removed.
+TESTFN is used to compare elements, or `equal' if TESTFN is nil."
+  (let ((result '()))
+    (seq-doseq (elt sequence)
+      (unless (seq-contains result elt testfn)
+        (setq result (cons elt result))))
+    (nreverse result)))
+
+(defun seq-subseq (sequence start &optional end)
+  "Return the subsequence of SEQUENCE from START to END.
+If END is omitted, it defaults to the length of the sequence.
+If START or END is negative, it counts from the end."
+  (cond ((or (stringp sequence) (vectorp sequence)) (substring sequence start end))
+        ((listp sequence)
+         (let (len (errtext (format "Bad bounding indices: %s, %s" start end)))
+           (and end (< end 0) (setq end (+ end (setq len (seq-length sequence)))))
+           (if (< start 0) (setq start (+ start (or len (setq len (seq-length sequence))))))
+           (when (> start 0)
+             (setq sequence (nthcdr (1- start) sequence))
+             (or sequence (error "%s" errtext))
+             (setq sequence (cdr sequence)))
+           (if end
+               (let ((res nil))
+                 (while (and (>= (setq end (1- end)) start) sequence)
+                   (push (pop sequence) res))
+                 (or (= (1+ end) start) (error "%s" errtext))
+                 (nreverse res))
+             (seq-copy sequence))))
+        (t (error "Unsupported sequence: %s" sequence))))
+
+(defun seq-concatenate (type &rest seqs)
+  "Concatenate, into a sequence of type TYPE, the sequences SEQS.
+TYPE must be one of following symbols: vector, string or list.
+
+\n(fn TYPE SEQUENCE...)"
+  (pcase type
+    (`vector (apply #'vconcat seqs))
+    (`string (apply #'concat seqs))
+    (`list (apply #'append (append seqs '(nil))))
+    (_ (error "Not a sequence type name: %S" type))))
+
+(defun seq-mapcat (function sequence &optional type)
+  "Concatenate the result of applying FUNCTION to each element of SEQUENCE.
+The result is a sequence of type TYPE, or a list if TYPE is nil."
+  (apply #'seq-concatenate (or type 'list)
+         (seq-map function sequence)))
+
+(defun seq-mapn (function sequence &rest seqs)
+  "Like `seq-map' but FUNCTION is mapped over all SEQS.
+The arity of FUNCTION must match the number of SEQS, and the
+mapping stops on the shortest sequence.
+Return a list of the results.
+
+\(fn FUNCTION SEQS...)"
+  (let ((result nil)
+        (seqs (seq-map (lambda (s)
+                         (seq-into s 'list))
+                       (cons sequence seqs))))
+    (while (not (memq nil seqs))
+      (push (apply function (seq-map #'car seqs)) result)
+      (setq seqs (seq-map #'cdr seqs)))
+    (nreverse result)))
+
+(defun seq-partition (sequence n)
+  "Return a list of the elements of SEQUENCE grouped into sub-sequences of length N.
+The last sequence may contain less than N elements.  If N is a
+negative integer or 0, nil is returned."
+  (unless (< n 1)
+    (let ((result '()))
+      (while (not (seq-empty-p sequence))
+        (push (seq-take sequence n) result)
+        (setq sequence (seq-drop sequence n)))
+      (nreverse result))))
+
+(defun seq-intersection (seq1 seq2 &optional testfn)
+  "Return a list of the elements that appear in both SEQ1 and SEQ2.
+Equality is defined by TESTFN if non-nil or by `equal' if nil."
+  (seq-reduce (lambda (acc elt)
+                (if (seq-contains seq2 elt testfn)
+                    (cons elt acc)
+                  acc))
+              (seq-reverse seq1)
+              '()))
+
+(defun seq-difference (seq1 seq2 &optional testfn)
+  "Return a list of the elements that appear in SEQ1 but not in SEQ2.
+Equality is defined by TESTFN if non-nil or by `equal' if nil."
+  (seq-reduce (lambda (acc elt)
+                (if (not (seq-contains seq2 elt testfn))
+                    (cons elt acc)
+                  acc))
+              (seq-reverse seq1)
+              '()))
+
+(defun seq-group-by (function sequence)
+  "Apply FUNCTION to each element of SEQUENCE.
+Separate the elements of SEQUENCE into an alist using the results as
+keys.  Keys are compared using `equal'."
+  (seq-reduce
+   (lambda (acc elt)
+     (let* ((key (funcall function elt))
+            (cell (assoc key acc)))
+       (if cell
+           (setcdr cell (push elt (cdr cell)))
+         (push (list key elt) acc))
+       acc))
+   (seq-reverse sequence)
+   nil))
+
+(defalias 'seq-reverse
+  (if (ignore-errors (reverse [1 2]))
+      #'reverse
+    (lambda (sequence)
+      "Return the reversed copy of list, vector, or string SEQUENCE.
+See also the function `nreverse', which is used more often."
+      (let ((result '()))
+        (seq-map (lambda (elt) (push elt result))
+                 sequence)
+        (if (listp sequence)
+            result
+          (seq-into result (type-of sequence)))))))
+
+(defun seq-into (sequence type)
+  "Convert the sequence SEQUENCE into a sequence of type TYPE.
+TYPE can be one of the following symbols: vector, string or list."
+  (pcase type
+    (`vector (seq--into-vector sequence))
+    (`string (seq--into-string sequence))
+    (`list (seq--into-list sequence))
+    (_ (error "Not a sequence type name: %S" type))))
+
+(defun seq-min (sequence)
+  "Return the smallest element of SEQUENCE.
+SEQUENCE must be a sequence of numbers or markers."
+  (apply #'min (seq-into sequence 'list)))
+
+(defun seq-max (sequence)
+    "Return the largest element of SEQUENCE.
+SEQUENCE must be a sequence of numbers or markers."
+  (apply #'max (seq-into sequence 'list)))
+
+(defun seq-random-elt (sequence)
+  "Return a random element from SEQUENCE.
+Signal an error if SEQUENCE is empty."
+  (if (seq-empty-p sequence)
+      (error "Sequence cannot be empty")
+    (seq-elt sequence (random (seq-length sequence)))))
+
+(defun seq--drop-list (list n)
+  "Return a list from LIST without its first N elements.
+This is an optimization for lists in `seq-drop'."
+  (nthcdr n list))
+
+(defun seq--take-list (list n)
+  "Return a list from LIST made of its first N elements.
+This is an optimization for lists in `seq-take'."
+  (let ((result '()))
+    (while (and list (> n 0))
+      (setq n (1- n))
+      (push (pop list) result))
+    (nreverse result)))
+
+(defun seq--drop-while-list (predicate list)
+  "Return a list from the first element for which (PREDICATE element) is nil in LIST.
+This is an optimization for lists in `seq-drop-while'."
+  (while (and list (funcall predicate (car list)))
+    (setq list (cdr list)))
+  list)
+
+(defun seq--take-while-list (predicate list)
+  "Return the successive elements for which (PREDICATE element) is non-nil in LIST.
+This is an optimization for lists in `seq-take-while'."
+  (let ((result '()))
+    (while (and list (funcall predicate (car list)))
+      (push (pop list) result))
+    (nreverse result)))
+
+(defun seq--count-successive (predicate sequence)
+  "Return the number of successive elements for which (PREDICATE element) is non-nil in SEQUENCE."
+  (let ((n 0)
+        (len (seq-length sequence)))
+    (while (and (< n len)
+                (funcall predicate (seq-elt sequence n)))
+      (setq n (+ 1 n)))
+    n))
+
+;; Helper function for the Backward-compatible version of `seq-let'
+;; for Emacs<25.1.
+(defun seq--make-bindings (args sequence &optional bindings)
+  "Return a list of bindings of the variables in ARGS to the elements of a sequence.
+if BINDINGS is non-nil, append new bindings to it, and return
+BINDINGS."
+  (let ((index 0)
+        (rest-marker nil))
+    (seq-doseq (name args)
+      (unless rest-marker
+        (pcase name
+          ((pred seqp)
+           (setq bindings (seq--make-bindings (seq--elt-safe args index)
+                                              `(seq--elt-safe ,sequence ,index)
+                                              bindings)))
+          (`&rest
+           (progn (push `(,(seq--elt-safe args (1+ index))
+                          (seq-drop ,sequence ,index))
+                        bindings)
+                  (setq rest-marker t)))
+          (_
+           (push `(,name (seq--elt-safe ,sequence ,index)) bindings))))
+      (setq index (1+ index)))
+    bindings))
+
+(defun seq--elt-safe (sequence n)
+  "Return element of SEQUENCE at the index N.
+If no element is found, return nil."
+  (when (or (listp sequence)
+            (and (sequencep sequence)
+                 (> (seq-length sequence) n)))
+    (seq-elt sequence n)))
+
+(defun seq--activate-font-lock-keywords ()
+  "Activate font-lock keywords for some symbols defined in seq."
+  (font-lock-add-keywords 'emacs-lisp-mode
+                          '("\\<seq-doseq\\>" "\\<seq-let\\>")))
+
+(defalias 'seq-copy #'copy-sequence)
+(defalias 'seq-elt #'elt)
+(defalias 'seq-length #'length)
+(defalias 'seq-do #'mapc)
+(defalias 'seq-each #'seq-do)
+(defalias 'seq-map #'mapcar)
+(defalias 'seqp #'sequencep)
+
+(defun seq--into-list (sequence)
+  "Concatenate the elements of SEQUENCE into a list."
+  (if (listp sequence)
+      sequence
+    (append sequence nil)))
+
+(defun seq--into-vector (sequence)
+  "Concatenate the elements of SEQUENCE into a vector."
+  (if (vectorp sequence)
+      sequence
+    (vconcat sequence)))
+
+(defun seq--into-string (sequence)
+  "Concatenate the elements of SEQUENCE into a string."
+  (if (stringp sequence)
+      sequence
+    (concat sequence)))
+
+(unless (fboundp 'elisp--font-lock-flush-elisp-buffers)
+  ;; In Emacs≥25, (via elisp--font-lock-flush-elisp-buffers and a few others)
+  ;; we automatically highlight macros.
+  (add-hook 'emacs-lisp-mode-hook #'seq--activate-font-lock-keywords))
+
+(provide 'seq-24)
+;;; seq-24.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/seq-2.20/seq-24.elc b/configs/shared/emacs/.emacs.d/elpa/seq-2.20/seq-24.elc
new file mode 100644
index 0000000000..e81a167aa8
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/seq-2.20/seq-24.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/seq-2.20/seq-25.el b/configs/shared/emacs/.emacs.d/elpa/seq-2.20/seq-25.el
new file mode 100644
index 0000000000..d26bde6ec4
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/seq-2.20/seq-25.el
@@ -0,0 +1,530 @@
+;;; seq-25.el --- seq.el implementation for Emacs 25.x -*- lexical-binding: t -*-
+
+;; Copyright (C) 2014-2016 Free Software Foundation, Inc.
+
+;; Author: Nicolas Petton <nicolas@petton.fr>
+;; Keywords: sequences
+
+;; Maintainer: emacs-devel@gnu.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:
+
+;; Sequence-manipulation functions that complement basic functions
+;; provided by subr.el.
+;;
+;; All functions are prefixed with "seq-".
+;;
+;; All provided functions work on lists, strings and vectors.
+;;
+;; Functions taking a predicate or iterating over a sequence using a
+;; function as argument take the function as their first argument and
+;; the sequence as their second argument.  All other functions take
+;; the sequence as their first argument.
+;;
+;; seq.el can be extended to support new type of sequences.  Here are
+;; the generic functions that must be implemented by new seq types:
+;; - `seq-elt'
+;; - `seq-length'
+;; - `seq-do'
+;; - `seqp'
+;; - `seq-subseq'
+;; - `seq-into-sequence'
+;; - `seq-copy'
+;; - `seq-into'
+
+;;; Code:
+
+;; When loading seq.el in Emacs 24.x, this file gets byte-compiled, even if
+;; never used.  This takes care of byte-compilation warnings is emitted, by
+;; emitting nil in the macro expansion in Emacs 24.x.
+(defmacro seq--when-emacs-25-p (&rest body)
+  "Execute BODY if in Emacs>=25.x."
+  (declare (indent (lambda (&rest x) 0)) (debug t))
+  (when (version<= "25" emacs-version)
+    `(progn ,@body)))
+
+(seq--when-emacs-25-p
+
+(require 'cl-generic)
+(require 'cl-lib) ;; for cl-subseq
+
+(defmacro seq-doseq (spec &rest body)
+  "Loop over a sequence.
+Evaluate BODY with VAR bound to each element of SEQUENCE, in turn.
+
+Similar to `dolist' but can be applied to lists, strings, and vectors.
+
+\(fn (VAR SEQUENCE) BODY...)"
+  (declare (indent 1) (debug ((symbolp form &optional form) body)))
+  `(seq-do (lambda (,(car spec))
+             ,@body)
+           ,(cadr spec)))
+
+(pcase-defmacro seq (&rest patterns)
+  "Build a `pcase' pattern that matches elements of SEQUENCE.
+
+The `pcase' pattern will match each element of PATTERNS against the
+corresponding element of SEQUENCE.
+
+Extra elements of the sequence are ignored if fewer PATTERNS are
+given, and the match does not fail."
+  `(and (pred seqp)
+        ,@(seq--make-pcase-bindings patterns)))
+
+(defmacro seq-let (args sequence &rest body)
+  "Bind the variables in ARGS to the elements of SEQUENCE, then evaluate BODY.
+
+ARGS can also include the `&rest' marker followed by a variable
+name to be bound to the rest of SEQUENCE."
+  (declare (indent 2) (debug (sexp form body)))
+  `(pcase-let ((,(seq--make-pcase-patterns args) ,sequence))
+     ,@body))
+
+
+;;; Basic seq functions that have to be implemented by new sequence types
+(cl-defgeneric seq-elt (sequence n)
+  "Return Nth element of SEQUENCE."
+  (elt sequence n))
+
+;; Default gv setters for `seq-elt'.
+;; It can be a good idea for new sequence implementations to provide a
+;; "gv-setter" for `seq-elt'.
+(cl-defmethod (setf seq-elt) (store (sequence array) n)
+  (aset sequence n store))
+
+(cl-defmethod (setf seq-elt) (store (sequence cons) n)
+  (setcar (nthcdr n sequence) store))
+
+(cl-defgeneric seq-length (sequence)
+  "Return the number of elements of SEQUENCE."
+  (length sequence))
+
+(cl-defgeneric seq-do (function sequence)
+  "Apply FUNCTION to each element of SEQUENCE, presumably for side effects.
+Return SEQUENCE."
+  (mapc function sequence))
+
+(defalias 'seq-each #'seq-do)
+
+(cl-defgeneric seqp (sequence)
+  "Return non-nil if SEQUENCE is a sequence, nil otherwise."
+  (sequencep sequence))
+
+(cl-defgeneric seq-copy (sequence)
+  "Return a shallow copy of SEQUENCE."
+  (copy-sequence sequence))
+
+(cl-defgeneric seq-subseq (sequence start &optional end)
+  "Return the sequence of elements of SEQUENCE from START to END.
+END is exclusive.
+
+If END is omitted, it defaults to the length of the sequence.  If
+START or END is negative, it counts from the end.  Signal an
+error if START or END are outside of the sequence (i.e too large
+if positive or too small if negative)."
+  (cl-subseq sequence start end))
+
+
+(cl-defgeneric seq-map (function sequence)
+  "Return the result of applying FUNCTION to each element of SEQUENCE."
+  (let (result)
+    (seq-do (lambda (elt)
+              (push (funcall function elt) result))
+            sequence)
+    (nreverse result)))
+
+(defun seq-map-indexed (function sequence)
+  "Return the result of applying FUNCTION to each element of SEQUENCE.
+Unlike `seq-map', FUNCTION takes two arguments: the element of
+the sequence, and its index within the sequence."
+  (let ((index 0))
+    (seq-map (lambda (elt)
+               (prog1
+                   (funcall function elt index)
+                 (setq index (1+ index))))
+             sequence)))
+
+;; faster implementation for sequences (sequencep)
+(cl-defmethod seq-map (function (sequence sequence))
+  (mapcar function sequence))
+
+(cl-defgeneric seq-mapn (function sequence &rest sequences)
+  "Like `seq-map' but FUNCTION is mapped over all SEQUENCES.
+The arity of FUNCTION must match the number of SEQUENCES, and the
+mapping stops on the shortest sequence.
+Return a list of the results.
+
+\(fn FUNCTION SEQUENCES...)"
+  (let ((result nil)
+        (sequences (seq-map (lambda (s)
+                              (seq-into s 'list))
+                            (cons sequence sequences))))
+    (while (not (memq nil sequences))
+      (push (apply function (seq-map #'car sequences)) result)
+      (setq sequences (seq-map #'cdr sequences)))
+    (nreverse result)))
+
+(cl-defgeneric seq-drop (sequence n)
+  "Remove the first N elements of SEQUENCE and return the result.
+The result is a sequence of the same type as SEQUENCE.
+
+If N is a negative integer or zero, SEQUENCE is returned."
+  (if (<= n 0)
+      sequence
+    (let ((length (seq-length sequence)))
+      (seq-subseq sequence (min n length) length))))
+
+(cl-defgeneric seq-take (sequence n)
+  "Take the first N elements of SEQUENCE and return the result.
+The result is a sequence of the same type as SEQUENCE.
+
+If N is a negative integer or zero, an empty sequence is
+returned."
+  (seq-subseq sequence 0 (min (max n 0) (seq-length sequence))))
+
+(cl-defgeneric seq-drop-while (pred sequence)
+  "Remove the successive elements of SEQUENCE for which PRED returns non-nil.
+PRED is a function of one argument.  The result is a sequence of
+the same type as SEQUENCE."
+  (seq-drop sequence (seq--count-successive pred sequence)))
+
+(cl-defgeneric seq-take-while (pred sequence)
+  "Take the successive elements of SEQUENCE for which PRED returns non-nil.
+PRED is a function of one argument.  The result is a sequence of
+the same type as SEQUENCE."
+  (seq-take sequence (seq--count-successive pred sequence)))
+
+(cl-defgeneric seq-empty-p (sequence)
+  "Return non-nil if the SEQUENCE is empty, nil otherwise."
+  (= 0 (seq-length sequence)))
+
+(cl-defgeneric seq-sort (pred sequence)
+  "Sort SEQUENCE using PRED as comparison function.
+The result is a sequence of the same type as SEQUENCE."
+  (let ((result (seq-sort pred (append sequence nil))))
+    (seq-into result (type-of sequence))))
+
+(defun seq-sort-by (function pred sequence)
+  "Sort SEQUENCE using PRED as a comparison function.
+Elements of SEQUENCE are transformed by FUNCTION before being
+sorted.  FUNCTION must be a function of one argument."
+  (seq-sort (lambda (a b)
+              (funcall pred
+                       (funcall function a)
+                       (funcall function b)))
+            sequence))
+
+(cl-defmethod seq-sort (pred (list list))
+  (sort (seq-copy list) pred))
+
+(cl-defgeneric seq-reverse (sequence)
+  "Return a sequence with elements of SEQUENCE in reverse order."
+  (let ((result '()))
+    (seq-map (lambda (elt)
+               (push elt result))
+             sequence)
+    (seq-into result (type-of sequence))))
+
+;; faster implementation for sequences (sequencep)
+(cl-defmethod seq-reverse ((sequence sequence))
+  (reverse sequence))
+
+(cl-defgeneric seq-concatenate (type &rest sequences)
+  "Concatenate SEQUENCES into a single sequence of type TYPE.
+TYPE must be one of following symbols: vector, string or list.
+
+\n(fn TYPE SEQUENCE...)"
+  (apply #'cl-concatenate type (seq-map #'seq-into-sequence sequences)))
+
+(cl-defgeneric seq-into-sequence (sequence)
+  "Convert SEQUENCE into a sequence.
+
+The default implementation is to signal an error if SEQUENCE is not a
+sequence, specific functions should be implemented for new types
+of sequence."
+  (unless (sequencep sequence)
+    (error "Cannot convert %S into a sequence" sequence))
+  sequence)
+
+(cl-defgeneric seq-into (sequence type)
+  "Concatenate the elements of SEQUENCE into a sequence of type TYPE.
+TYPE can be one of the following symbols: vector, string or
+list."
+  (pcase type
+    (`vector (seq--into-vector sequence))
+    (`string (seq--into-string sequence))
+    (`list (seq--into-list sequence))
+    (_ (error "Not a sequence type name: %S" type))))
+
+(cl-defgeneric seq-filter (pred sequence)
+  "Return a list of all the elements for which (PRED element) is non-nil in SEQUENCE."
+  (let ((exclude (make-symbol "exclude")))
+    (delq exclude (seq-map (lambda (elt)
+                             (if (funcall pred elt)
+                                 elt
+                               exclude))
+                           sequence))))
+
+(cl-defgeneric seq-remove (pred sequence)
+  "Return a list of all the elements for which (PRED element) is nil in SEQUENCE."
+  (seq-filter (lambda (elt) (not (funcall pred elt)))
+              sequence))
+
+(cl-defgeneric seq-reduce (function sequence initial-value)
+  "Reduce the function FUNCTION across SEQUENCE, starting with INITIAL-VALUE.
+
+Return the result of calling FUNCTION with INITIAL-VALUE and the
+first element of SEQUENCE, then calling FUNCTION with that result and
+the second element of SEQUENCE, then with that result and the third
+element of SEQUENCE, etc.
+
+If SEQUENCE is empty, return INITIAL-VALUE and FUNCTION is not called."
+  (if (seq-empty-p sequence)
+      initial-value
+    (let ((acc initial-value))
+      (seq-doseq (elt sequence)
+        (setq acc (funcall function acc elt)))
+      acc)))
+
+(cl-defgeneric seq-every-p (pred sequence)
+  "Return non-nil if (PRED element) is non-nil for all elements of SEQUENCE."
+  (catch 'seq--break
+    (seq-doseq (elt sequence)
+      (or (funcall pred elt)
+          (throw 'seq--break nil)))
+    t))
+
+(cl-defgeneric seq-some (pred sequence)
+  "Return the first value for which if (PRED element) is non-nil for in SEQUENCE."
+  (catch 'seq--break
+    (seq-doseq (elt sequence)
+      (let ((result (funcall pred elt)))
+        (when result
+          (throw 'seq--break result))))
+    nil))
+
+(cl-defgeneric seq-find (pred sequence &optional default)
+  "Return the first element for which (PRED element) is non-nil in SEQUENCE.
+If no element is found, return DEFAULT.
+
+Note that `seq-find' has an ambiguity if the found element is
+identical to DEFAULT, as it cannot be known if an element was
+found or not."
+  (catch 'seq--break
+    (seq-doseq (elt sequence)
+      (when (funcall pred elt)
+        (throw 'seq--break elt)))
+    default))
+
+(cl-defgeneric seq-count (pred sequence)
+  "Return the number of elements for which (PRED element) is non-nil in SEQUENCE."
+  (let ((count 0))
+    (seq-doseq (elt sequence)
+      (when (funcall pred elt)
+        (setq count (+ 1 count))))
+    count))
+
+(cl-defgeneric seq-contains (sequence elt &optional testfn)
+  "Return the first element in SEQUENCE that is equal to ELT.
+Equality is defined by TESTFN if non-nil or by `equal' if nil."
+  (seq-some (lambda (e)
+              (funcall (or testfn #'equal) elt e))
+            sequence))
+
+(cl-defgeneric seq-set-equal-p (sequence1 sequence2 &optional testfn)
+  "Return non-nil if SEQUENCE1 and SEQUENCE2 contain the same elements, regardless of order.
+Equality is defined by TESTFN if non-nil or by `equal' if nil."
+  (and (seq-every-p (lambda (item1) (seq-contains sequence2 item1 testfn)) sequence1)
+       (seq-every-p (lambda (item2) (seq-contains sequence1 item2 testfn)) sequence2)))
+
+(cl-defgeneric seq-position (sequence elt &optional testfn)
+  "Return the index of the first element in SEQUENCE that is equal to ELT.
+Equality is defined by TESTFN if non-nil or by `equal' if nil."
+  (let ((index 0))
+    (catch 'seq--break
+      (seq-doseq (e sequence)
+        (when (funcall (or testfn #'equal) e elt)
+          (throw 'seq--break index))
+        (setq index (1+ index)))
+      nil)))
+
+(cl-defgeneric seq-uniq (sequence &optional testfn)
+  "Return a list of the elements of SEQUENCE with duplicates removed.
+TESTFN is used to compare elements, or `equal' if TESTFN is nil."
+  (let ((result '()))
+    (seq-doseq (elt sequence)
+      (unless (seq-contains result elt testfn)
+        (setq result (cons elt result))))
+    (nreverse result)))
+
+(cl-defgeneric seq-mapcat (function sequence &optional type)
+  "Concatenate the result of applying FUNCTION to each element of SEQUENCE.
+The result is a sequence of type TYPE, or a list if TYPE is nil."
+  (apply #'seq-concatenate (or type 'list)
+         (seq-map function sequence)))
+
+(cl-defgeneric seq-partition (sequence n)
+  "Return a list of the elements of SEQUENCE grouped into sub-sequences of length N.
+The last sequence may contain less than N elements.  If N is a
+negative integer or 0, nil is returned."
+  (unless (< n 1)
+    (let ((result '()))
+      (while (not (seq-empty-p sequence))
+        (push (seq-take sequence n) result)
+        (setq sequence (seq-drop sequence n)))
+      (nreverse result))))
+
+(cl-defgeneric seq-intersection (sequence1 sequence2 &optional testfn)
+  "Return a list of the elements that appear in both SEQUENCE1 and SEQUENCE2.
+Equality is defined by TESTFN if non-nil or by `equal' if nil."
+  (seq-reduce (lambda (acc elt)
+                (if (seq-contains sequence2 elt testfn)
+                    (cons elt acc)
+                  acc))
+              (seq-reverse sequence1)
+              '()))
+
+(cl-defgeneric seq-difference (sequence1 sequence2 &optional testfn)
+  "Return a list of the elements that appear in SEQUENCE1 but not in SEQUENCE2.
+Equality is defined by TESTFN if non-nil or by `equal' if nil."
+  (seq-reduce (lambda (acc elt)
+                (if (not (seq-contains sequence2 elt testfn))
+                    (cons elt acc)
+                  acc))
+              (seq-reverse sequence1)
+              '()))
+
+(cl-defgeneric seq-group-by (function sequence)
+  "Apply FUNCTION to each element of SEQUENCE.
+Separate the elements of SEQUENCE into an alist using the results as
+keys.  Keys are compared using `equal'."
+  (seq-reduce
+   (lambda (acc elt)
+     (let* ((key (funcall function elt))
+            (cell (assoc key acc)))
+       (if cell
+           (setcdr cell (push elt (cdr cell)))
+         (push (list key elt) acc))
+       acc))
+   (seq-reverse sequence)
+   nil))
+
+(cl-defgeneric seq-min (sequence)
+  "Return the smallest element of SEQUENCE.
+SEQUENCE must be a sequence of numbers or markers."
+  (apply #'min (seq-into sequence 'list)))
+
+(cl-defgeneric seq-max (sequence)
+  "Return the largest element of SEQUENCE.
+SEQUENCE must be a sequence of numbers or markers."
+  (apply #'max (seq-into sequence 'list)))
+
+(defun seq--count-successive (pred sequence)
+  "Return the number of successive elements for which (PRED element) is non-nil in SEQUENCE."
+  (let ((n 0)
+        (len (seq-length sequence)))
+    (while (and (< n len)
+                (funcall pred (seq-elt sequence n)))
+      (setq n (+ 1 n)))
+    n))
+
+;;; Optimized implementations for lists
+
+(cl-defmethod seq-drop ((list list) n)
+  "Optimized implementation of `seq-drop' for lists."
+  (nthcdr n list))
+
+(cl-defmethod seq-take ((list list) n)
+  "Optimized implementation of `seq-take' for lists."
+  (let ((result '()))
+    (while (and list (> n 0))
+      (setq n (1- n))
+      (push (pop list) result))
+    (nreverse result)))
+
+(cl-defmethod seq-drop-while (pred (list list))
+  "Optimized implementation of `seq-drop-while' for lists."
+  (while (and list (funcall pred (car list)))
+    (setq list (cdr list)))
+  list)
+
+(cl-defmethod seq-empty-p ((list list))
+  "Optimized implementation of `seq-empty-p' for lists."
+  (null list))
+
+
+(defun seq--into-list (sequence)
+  "Concatenate the elements of SEQUENCE into a list."
+  (if (listp sequence)
+      sequence
+    (append sequence nil)))
+
+(defun seq--into-vector (sequence)
+  "Concatenate the elements of SEQUENCE into a vector."
+  (if (vectorp sequence)
+      sequence
+    (vconcat sequence)))
+
+(defun seq--into-string (sequence)
+  "Concatenate the elements of SEQUENCE into a string."
+  (if (stringp sequence)
+      sequence
+    (concat sequence)))
+
+(defun seq--make-pcase-bindings (args)
+  "Return a list of bindings of the variables in ARGS to the elements of a sequence."
+  (let ((bindings '())
+        (index 0)
+        (rest-marker nil))
+    (seq-doseq (name args)
+      (unless rest-marker
+        (pcase name
+          (`&rest
+           (progn (push `(app (pcase--flip seq-drop ,index)
+                              ,(seq--elt-safe args (1+ index)))
+                        bindings)
+                  (setq rest-marker t)))
+          (_
+           (push `(app (pcase--flip seq--elt-safe ,index) ,name) bindings))))
+      (setq index (1+ index)))
+    bindings))
+
+(defun seq--make-pcase-patterns (args)
+  "Return a list of `(seq ...)' pcase patterns from the argument list ARGS."
+  (cons 'seq
+        (seq-map (lambda (elt)
+                   (if (seqp elt)
+                       (seq--make-pcase-patterns elt)
+                     elt))
+                 args)))
+
+;; TODO: make public?
+(defun seq--elt-safe (sequence n)
+  "Return element of SEQUENCE at the index N.
+If no element is found, return nil."
+  (ignore-errors (seq-elt sequence n))))
+
+(cl-defgeneric seq-random-elt (sequence)
+  "Return a random element from SEQUENCE.
+Signal an error if SEQUENCE is empty."
+  (if (seq-empty-p sequence)
+      (error "Sequence cannot be empty")
+    (seq-elt sequence (random (seq-length sequence)))))
+
+(provide 'seq-25)
+;;; seq-25.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/seq-2.20/seq-25.elc b/configs/shared/emacs/.emacs.d/elpa/seq-2.20/seq-25.elc
new file mode 100644
index 0000000000..375e7f95f3
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/seq-2.20/seq-25.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/seq-2.20/seq-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/seq-2.20/seq-autoloads.el
new file mode 100644
index 0000000000..b1f2f15c25
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/seq-2.20/seq-autoloads.el
@@ -0,0 +1,16 @@
+;;; seq-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil nil ("seq-24.el" "seq-25.el" "seq-pkg.el" "seq.el")
+;;;;;;  (23377 61662 587262 877000))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; seq-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/seq-2.20/seq-pkg.el b/configs/shared/emacs/.emacs.d/elpa/seq-2.20/seq-pkg.el
new file mode 100644
index 0000000000..0ce35877de
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/seq-2.20/seq-pkg.el
@@ -0,0 +1,2 @@
+;; Generated package description from seq.el
+(define-package "seq" "2.20" "Sequence manipulation functions" 'nil :url "http://elpa.gnu.org/packages/seq.html" :keywords '("sequences"))
diff --git a/configs/shared/emacs/.emacs.d/elpa/seq-2.20/seq-pkg.elc b/configs/shared/emacs/.emacs.d/elpa/seq-2.20/seq-pkg.elc
new file mode 100644
index 0000000000..1297641188
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/seq-2.20/seq-pkg.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/seq-2.20/seq.el b/configs/shared/emacs/.emacs.d/elpa/seq-2.20/seq.el
new file mode 100644
index 0000000000..83d43929a7
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/seq-2.20/seq.el
@@ -0,0 +1,48 @@
+;;; seq.el --- Sequence manipulation functions  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2014-2016 Free Software Foundation, Inc.
+
+;; Author: Nicolas Petton <nicolas@petton.fr>
+;; Keywords: sequences
+;; Version: 2.20
+;; Package: seq
+
+;; Maintainer: emacs-devel@gnu.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:
+
+;; Sequence-manipulation functions that complement basic functions
+;; provided by subr.el.
+;;
+;; All functions are prefixed with "seq-".
+;;
+;; All provided functions work on lists, strings and vectors.
+;;
+;; Functions taking a predicate or iterating over a sequence using a
+;; function as argument take the function as their first argument and
+;; the sequence as their second argument.  All other functions take
+;; the sequence as their first argument.
+
+;;; Code:
+
+(if (version< emacs-version "25")
+    (require 'seq-24)
+  (require 'seq-25))
+
+(provide 'seq)
+;;; seq.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/seq-2.20/seq.elc b/configs/shared/emacs/.emacs.d/elpa/seq-2.20/seq.elc
new file mode 100644
index 0000000000..f729935243
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/seq-2.20/seq.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/seq-2.20/tests/seq-tests.el b/configs/shared/emacs/.emacs.d/elpa/seq-2.20/tests/seq-tests.el
new file mode 100644
index 0000000000..d53fa36fe7
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/seq-2.20/tests/seq-tests.el
@@ -0,0 +1,382 @@
+;;; seq-tests.el --- Tests for sequences.el
+
+;; Copyright (C) 2014-2015 Free Software Foundation, Inc.
+
+;; Author: Nicolas Petton <nicolas@petton.fr>
+;; Maintainer: emacs-devel@gnu.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:
+
+;; Tests for seq.el
+
+;;; Code:
+
+(require 'ert)
+(require 'seq)
+
+(defmacro with-test-sequences (spec &rest body)
+  "Successively bind VAR to a list, vector, and string built from SEQ.
+Evaluate BODY for each created sequence.
+
+\(fn (var seq) body)"
+  (declare (indent 1) (debug ((symbolp form) body)))
+  (let ((initial-seq (make-symbol "initial-seq")))
+    `(let ((,initial-seq ,(cadr spec)))
+       ,@(mapcar (lambda (s)
+                   `(let ((,(car spec) (apply (function ,s) ,initial-seq)))
+                      ,@body))
+                 '(list vector string)))))
+
+(defun same-contents-p (seq1 seq2)
+  "Return t if SEQ1 and SEQ2 have the same contents, nil otherwise."
+  (equal (append seq1 '()) (append seq2 '())))
+
+(defun test-sequences-evenp (integer)
+  "Return t if INTEGER is even."
+  (eq (logand integer 1) 0))
+
+(defun test-sequences-oddp (integer)
+  "Return t if INTEGER is odd."
+  (not (test-sequences-evenp integer)))
+
+(ert-deftest test-seq-drop ()
+  (with-test-sequences (seq '(1 2 3 4))
+    (should (equal (seq-drop seq 0) seq))
+    (should (equal (seq-drop seq 1) (seq-subseq seq 1)))
+    (should (equal (seq-drop seq 2) (seq-subseq seq 2)))
+    (should (seq-empty-p (seq-drop seq 4)))
+    (should (seq-empty-p (seq-drop seq 10))))
+  (with-test-sequences (seq '())
+    (should (seq-empty-p (seq-drop seq 0)))
+    (should (seq-empty-p (seq-drop seq 1)))))
+
+(ert-deftest test-seq-take ()
+  (with-test-sequences (seq '(2 3 4 5))
+    (should (seq-empty-p (seq-take seq 0)))
+    (should (= (seq-length (seq-take seq 1)) 1))
+    (should (= (seq-elt (seq-take seq 1) 0) 2))
+    (should (same-contents-p (seq-take seq 3) '(2 3 4)))
+    (should (equal (seq-take seq 10) seq))))
+
+(ert-deftest test-seq-drop-while ()
+  (with-test-sequences (seq '(1 3 2 4))
+    (should (equal (seq-drop-while #'test-sequences-oddp seq)
+                   (seq-drop seq 2)))
+    (should (equal (seq-drop-while #'test-sequences-evenp seq)
+                   seq))
+    (should (seq-empty-p (seq-drop-while #'numberp seq))))
+  (with-test-sequences (seq '())
+    (should (seq-empty-p (seq-drop-while #'test-sequences-oddp seq)))))
+
+(ert-deftest test-seq-take-while ()
+  (with-test-sequences (seq '(1 3 2 4))
+    (should (equal (seq-take-while #'test-sequences-oddp seq)
+                   (seq-take seq 2)))
+    (should (seq-empty-p (seq-take-while #'test-sequences-evenp seq)))
+    (should (equal (seq-take-while #'numberp seq) seq)))
+  (with-test-sequences (seq '())
+    (should (seq-empty-p (seq-take-while #'test-sequences-oddp seq)))))
+
+(ert-deftest test-seq-map-indexed ()
+  (should (equal (seq-map-indexed (lambda (elt i)
+                                    (list elt i))
+                                  nil)
+                 nil))
+  (should (equal (seq-map-indexed (lambda (elt i)
+                                    (list elt i))
+                                  '(a b c d))
+                 '((a 0) (b 1) (c 2) (d 3)))))
+
+(ert-deftest test-seq-filter ()
+  (with-test-sequences (seq '(6 7 8 9 10))
+    (should (equal (seq-filter #'test-sequences-evenp seq) '(6 8 10)))
+    (should (equal (seq-filter #'test-sequences-oddp seq) '(7 9)))
+    (should (equal (seq-filter (lambda (elt) nil) seq) '())))
+  (with-test-sequences (seq '())
+    (should (equal (seq-filter #'test-sequences-evenp seq) '()))))
+
+(ert-deftest test-seq-remove ()
+  (with-test-sequences (seq '(6 7 8 9 10))
+    (should (equal (seq-remove #'test-sequences-evenp seq) '(7 9)))
+    (should (equal (seq-remove #'test-sequences-oddp seq) '(6 8 10)))
+    (should (same-contents-p (seq-remove (lambda (elt) nil) seq) seq)))
+  (with-test-sequences (seq '())
+    (should (equal (seq-remove #'test-sequences-evenp seq) '()))))
+
+(ert-deftest test-seq-count ()
+  (with-test-sequences (seq '(6 7 8 9 10))
+    (should (equal (seq-count #'test-sequences-evenp seq) 3))
+    (should (equal (seq-count #'test-sequences-oddp seq) 2))
+    (should (equal (seq-count (lambda (elt) nil) seq) 0)))
+  (with-test-sequences (seq '())
+    (should (equal (seq-count #'test-sequences-evenp seq) 0))))
+
+(ert-deftest test-seq-reduce ()
+  (with-test-sequences (seq '(1 2 3 4))
+    (should (= (seq-reduce #'+ seq 0) 10))
+    (should (= (seq-reduce #'+ seq 5) 15)))
+  (with-test-sequences (seq '())
+    (should (eq (seq-reduce #'+ seq 0) 0))
+    (should (eq (seq-reduce #'+ seq 7) 7))))
+
+(ert-deftest test-seq-some ()
+  (with-test-sequences (seq '(4 3 2 1))
+    (should (seq-some #'test-sequences-evenp seq))
+    (should (seq-some #'test-sequences-oddp seq))
+    (should-not (seq-some (lambda (elt) (> elt 10)) seq)))
+  (with-test-sequences (seq '())
+    (should-not (seq-some #'test-sequences-oddp seq)))
+  (should (seq-some #'null '(1 nil 2))))
+
+(ert-deftest test-seq-find ()
+  (with-test-sequences (seq '(4 3 2 1))
+    (should (= 4 (seq-find #'test-sequences-evenp seq)))
+    (should (= 3 (seq-find #'test-sequences-oddp seq)))
+    (should-not (seq-find (lambda (elt) (> elt 10)) seq)))
+  (should-not (seq-find #'null '(1 nil 2)))
+  (should-not (seq-find #'null '(1 nil 2) t))
+  (should-not (seq-find #'null '(1 2 3)))
+  (should (seq-find #'null '(1 2 3) 'sentinel)))
+
+(ert-deftest test-seq-contains ()
+  (with-test-sequences (seq '(3 4 5 6))
+    (should (seq-contains seq 3))
+    (should-not (seq-contains seq 7)))
+  (with-test-sequences (seq '())
+    (should-not (seq-contains seq 3))
+    (should-not (seq-contains seq nil))))
+
+(ert-deftest test-seq-every-p ()
+  (with-test-sequences (seq '(43 54 22 1))
+    (should (seq-every-p (lambda (elt) t) seq))
+    (should-not (seq-every-p #'test-sequences-oddp seq))
+    (should-not (seq-every-p #'test-sequences-evenp seq)))
+  (with-test-sequences (seq '(42 54 22 2))
+    (should (seq-every-p #'test-sequences-evenp seq))
+    (should-not (seq-every-p #'test-sequences-oddp seq)))
+  (with-test-sequences (seq '())
+    (should (seq-every-p #'identity seq))
+    (should (seq-every-p #'test-sequences-evenp seq))))
+
+(ert-deftest test-seq-empty-p ()
+  (with-test-sequences (seq '(0))
+    (should-not (seq-empty-p seq)))
+  (with-test-sequences (seq '(0 1 2))
+    (should-not (seq-empty-p seq)))
+  (with-test-sequences (seq '())
+    (should (seq-empty-p seq))))
+
+(ert-deftest test-seq-sort ()
+  (should (equal (seq-sort #'< "cbaf") "abcf"))
+  (should (equal (seq-sort #'< '(2 1 9 4)) '(1 2 4 9)))
+  (should (equal (seq-sort #'< [2 1 9 4]) [1 2 4 9]))
+  (should (equal (seq-sort #'< "") "")))
+
+(ert-deftest test-seq-uniq ()
+  (with-test-sequences (seq '(2 4 6 8 6 4 3))
+    (should (equal (seq-uniq seq) '(2 4 6 8 3))))
+  (with-test-sequences (seq '(3 3 3 3 3))
+    (should (equal (seq-uniq seq) '(3))))
+  (with-test-sequences (seq '())
+    (should (equal (seq-uniq seq) '()))))
+
+(ert-deftest test-seq-subseq ()
+  (with-test-sequences (seq '(2 3 4 5))
+    (should (equal (seq-subseq seq 0 4) seq))
+    (should (same-contents-p (seq-subseq seq 2 4) '(4 5)))
+    (should (same-contents-p (seq-subseq seq 1 3) '(3 4)))
+    (should (same-contents-p (seq-subseq seq 1 -1) '(3 4))))
+  (should (vectorp (seq-subseq [2 3 4 5] 2)))
+  (should (stringp (seq-subseq "foo" 2 3)))
+  (should (listp (seq-subseq '(2 3 4 4) 2 3)))
+  (should-error (seq-subseq '(1 2 3) 4))
+  (should-not   (seq-subseq '(1 2 3) 3))
+  (should       (seq-subseq '(1 2 3) -3))
+  (should-error (seq-subseq '(1 2 3) 1 4))
+  (should       (seq-subseq '(1 2 3) 1 3)))
+
+(ert-deftest test-seq-concatenate ()
+  (with-test-sequences (seq '(2 4 6))
+    (should (equal (seq-concatenate 'string seq [8]) (string 2 4 6 8)))
+    (should (equal (seq-concatenate 'list seq '(8 10)) '(2 4 6 8 10)))
+    (should (equal (seq-concatenate 'vector seq '(8 10)) [2 4 6 8 10]))
+    (should (equal (seq-concatenate 'vector nil '(8 10)) [8 10]))
+    (should (equal (seq-concatenate 'vector seq nil) [2 4 6]))))
+
+(ert-deftest test-seq-mapcat ()
+  (should (equal (seq-mapcat #'seq-reverse '((3 2 1) (6 5 4)))
+                 '(1 2 3 4 5 6)))
+  (should (equal (seq-mapcat #'seq-reverse '[(3 2 1) (6 5 4)])
+                 '(1 2 3 4 5 6)))
+  (should (equal (seq-mapcat #'seq-reverse '((3 2 1) (6 5 4)) 'vector)
+                 '[1 2 3 4 5 6])))
+
+(ert-deftest test-seq-partition ()
+  (should (same-contents-p (seq-partition '(0 1 2 3 4 5 6 7) 3)
+                           '((0 1 2) (3 4 5) (6 7))))
+  (should (same-contents-p (seq-partition '[0 1 2 3 4 5 6 7] 3)
+                           '([0 1 2] [3 4 5] [6 7])))
+  (should (same-contents-p (seq-partition "Hello world" 2)
+                           '("He" "ll" "o " "wo" "rl" "d")))
+  (should (equal (seq-partition '() 2) '()))
+  (should (equal (seq-partition '(1 2 3) -1) '())))
+
+(ert-deftest test-seq-group-by ()
+  (with-test-sequences (seq '(1 2 3 4))
+   (should (equal (seq-group-by #'test-sequences-oddp seq)
+                  '((t 1 3) (nil 2 4)))))
+  (should (equal (seq-group-by #'car '((a 1) (b 3) (c 4) (a 2)))
+                 '((b (b 3)) (c (c 4)) (a (a 1) (a 2))))))
+
+(ert-deftest test-seq-reverse ()
+  (with-test-sequences (seq '(1 2 3 4))
+    (should (same-contents-p (seq-reverse seq) '(4 3 2 1)))
+    (should (equal (type-of (seq-reverse seq))
+                   (type-of seq)))))
+
+(ert-deftest test-seq-into ()
+  (let* ((vector [1 2 3])
+         (list (seq-into vector 'list)))
+    (should (same-contents-p vector list))
+    (should (listp list)))
+  (let* ((list '(hello world))
+         (vector (seq-into list 'vector)))
+    (should (same-contents-p vector list))
+    (should (vectorp vector)))
+  (let* ((string "hello")
+         (list (seq-into string 'list)))
+    (should (same-contents-p string list))
+    (should (stringp string)))
+  (let* ((string "hello")
+         (vector (seq-into string 'vector)))
+    (should (same-contents-p string vector))
+    (should (stringp string)))
+  (let* ((list nil)
+         (vector (seq-into list 'vector)))
+    (should (same-contents-p list vector))
+    (should (vectorp vector))))
+
+(ert-deftest test-seq-intersection ()
+  (let ((v1 [2 3 4 5])
+        (v2 [1 3 5 6 7]))
+    (should (same-contents-p (seq-intersection v1 v2)
+                             '(3 5))))
+  (let ((l1 '(2 3 4 5))
+        (l2 '(1 3 5 6 7)))
+    (should (same-contents-p (seq-intersection l1 l2)
+                             '(3 5))))
+  (let ((v1 [2 4 6])
+        (v2 [1 3 5]))
+    (should (seq-empty-p (seq-intersection v1 v2)))))
+
+(ert-deftest test-seq-difference ()
+  (let ((v1 [2 3 4 5])
+        (v2 [1 3 5 6 7]))
+    (should (same-contents-p (seq-difference v1 v2)
+                             '(2 4))))
+  (let ((l1 '(2 3 4 5))
+        (l2 '(1 3 5 6 7)))
+    (should (same-contents-p (seq-difference l1 l2)
+                             '(2 4))))
+  (let ((v1 [2 4 6])
+        (v2 [2 4 6]))
+    (should (seq-empty-p (seq-difference v1 v2)))))
+
+(ert-deftest test-seq-let ()
+  (with-test-sequences (seq '(1 2 3 4))
+    (seq-let (a b c d e) seq
+      (should (= a 1))
+      (should (= b 2))
+      (should (= c 3))
+      (should (= d 4))
+      (should (null e)))
+    (seq-let (a b &rest others) seq
+      (should (= a 1))
+      (should (= b 2))
+      (should (same-contents-p others (seq-drop seq 2)))))
+  (let ((seq '(1 (2 (3 (4))))))
+    (seq-let (_ (_ (_ (a)))) seq
+      (should (= a 4))))
+  (let (seq)
+    (seq-let (a b c) seq
+      (should (null a))
+      (should (null b))
+      (should (null c)))))
+
+(ert-deftest test-seq-min-max ()
+  (with-test-sequences (seq '(4 5 3 2 0 4))
+    (should (= (seq-min seq) 0))
+    (should (= (seq-max seq) 5))))
+
+(ert-deftest test-seq-position ()
+  (with-test-sequences (seq '(2 4 6))
+    (should (null (seq-position seq 1)))
+    (should (= (seq-position seq 4) 1)))
+  (let ((seq '(a b c)))
+    (should (null (seq-position seq 'd #'eq)))
+    (should (= (seq-position seq 'a #'eq) 0))
+    (should (null (seq-position seq (make-symbol "a") #'eq)))))
+
+(ert-deftest test-seq-mapn ()
+  (should-error (seq-mapn #'identity))
+  (with-test-sequences (seq '(1 2 3 4 5 6 7))
+    (should (equal (append seq nil)
+                   (seq-mapn #'identity seq)))
+    (should (equal (seq-mapn #'1+ seq)
+                   (seq-map #'1+ seq)))
+
+    (with-test-sequences (seq-2 '(10 20 30 40 50))
+      (should (equal (seq-mapn #'+ seq seq-2)
+                     '(11 22 33 44 55)))
+      (should (equal (seq-mapn #'+ seq seq-2 nil) nil)))))
+
+(ert-deftest test-seq-sort-by ()
+  (let ((seq ["x" "xx" "xxx"]))
+    (should (equal (seq-sort-by #'seq-length #'> seq)
+                   ["xxx" "xx" "x"]))))
+
+(ert-deftest test-seq-random-elt-take-all ()
+  (let ((seq '(a b c d e))
+        (elts '()))
+    (should (= 0 (length elts)))
+    (dotimes (_ 1000)
+      (let ((random-elt (seq-random-elt seq)))
+        (add-to-list 'elts
+                     random-elt)))
+    (should (= 5 (length elts)))))
+
+(ert-deftest test-seq-random-elt-signal-on-empty ()
+  (should-error (seq-random-elt nil))
+  (should-error (seq-random-elt []))
+  (should-error (seq-random-elt "")))
+
+(ert-deftest test-seq-mapn-circular-lists ()
+  (let ((l1 '#1=(1 . #1#)))
+    (should (equal (seq-mapn #'+ '(3 4 5 7) l1)
+                   '(4 5 6 8)))))
+
+(ert-deftest test-seq-into-and-identity ()
+  (let ((lst '(1 2 3))
+        (vec [1 2 3])
+        (str "foo bar"))
+    (should (eq (seq-into lst 'list) lst))
+    (should (eq (seq-into vec 'vector) vec))
+    (should (eq (seq-into str 'string) str))))
+
+(provide 'seq-tests)
+;;; seq-tests.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/seq-2.20/tests/seq-tests.elc b/configs/shared/emacs/.emacs.d/elpa/seq-2.20/tests/seq-tests.elc
new file mode 100644
index 0000000000..d9fa268ab9
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/seq-2.20/tests/seq-tests.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/sesman-20180719.213/sesman-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/sesman-20180719.213/sesman-autoloads.el
new file mode 100644
index 0000000000..fccb79b173
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/sesman-20180719.213/sesman-autoloads.el
@@ -0,0 +1,67 @@
+;;; sesman-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "sesman" "sesman.el" (23377 61661 977956 44000))
+;;; Generated autoloads from sesman.el
+
+(autoload 'sesman-start "sesman" "\
+Start sesman session.
+
+\(fn)" t nil)
+
+(autoload 'sesman-restart "sesman" "\
+Restart sesman session.
+
+\(fn)" t nil)
+
+(autoload 'sesman-quit "sesman" "\
+Terminate sesman session.
+When WHICH is nil, kill only the current session; when a single universal
+argument or 'linked, kill all linked session; when a double universal argument,
+t or 'all, kill all sessions.
+
+\(fn WHICH)" t nil)
+
+(autoload 'sesman-show-session-info "sesman" "\
+Display session(s) info.
+When WHICH is nil, show info for current session; when a single universal
+argument or 'linked, show info for all linked sessions; when a double universal
+argument or 'all, show info for all sessions.
+
+\(fn WHICH)" t nil)
+
+(autoload 'sesman-show-links "sesman" "\
+Display links active in the current context.
+
+\(fn)" t nil)
+
+(autoload 'sesman-link-with-buffer "sesman" "\
+Associate a session with current buffer.
+
+\(fn)" t nil)
+
+(autoload 'sesman-link-with-directory "sesman" "\
+Associate a session with current directory.
+
+\(fn)" t nil)
+
+(autoload 'sesman-link-with-project "sesman" "\
+Associate a session with current project.
+
+\(fn)" t nil)
+
+(autoload 'sesman-unlink "sesman" "\
+Break any of the previously created links.
+
+\(fn)" t nil)
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; sesman-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/sesman-20180719.213/sesman-pkg.el b/configs/shared/emacs/.emacs.d/elpa/sesman-20180719.213/sesman-pkg.el
new file mode 100644
index 0000000000..67ee10b235
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/sesman-20180719.213/sesman-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "sesman" "20180719.213" "Generic Session Manager" '((emacs "25")))
diff --git a/configs/shared/emacs/.emacs.d/elpa/sesman-20180719.213/sesman.el b/configs/shared/emacs/.emacs.d/elpa/sesman-20180719.213/sesman.el
new file mode 100644
index 0000000000..9279300d05
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/sesman-20180719.213/sesman.el
@@ -0,0 +1,728 @@
+;;; sesman.el --- Generic Session Manager -*- lexical-binding: t -*-
+;;
+;; Copyright (C) 2018, Vitalie Spinu
+;; Author: Vitalie Spinu
+;; URL: https://github.com/vspinu/sesman
+;; Package-Version: 20180719.213
+;; Keywords: process
+;; Version: 0.1.1-snapshot
+;; Package-Requires: ((emacs "25"))
+;; Keywords: processes, tools, vc
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; This file is *NOT* part of GNU Emacs.
+;;
+;; This program 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, or
+;; (at your option) any later version.
+;;
+;; This program 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 this program; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+;; Floor, Boston, MA 02110-1301, USA.
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Commentary:
+;;
+;; Sesman provides facilities for session management and interactive session
+;; association with the current contexts (project, directory, buffers etc).  See
+;; project's readme for more details.
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Code:
+
+(require 'cl-generic)
+(require 'project)
+(require 'seq)
+(require 'subr-x)
+
+(defgroup sesman nil
+  "Generic Session Manager."
+  :prefix "sesman-"
+  :group 'tools)
+
+;; (defcustom sesman-disambiguate-by-relevance t
+;;   "If t choose most relevant session in ambiguous situations, otherwise ask.
+;; Ambiguity arises when multiple sessions are associated with current context.  By
+;; default only projects could be associated with multiple sessions.  See
+;; `sesman-single-link-contexts' in order to change that.  Relevance is decided by
+;; system's implementation, see `sesman-more-relevant-p'."
+;;   :group 'sesman
+;;   :type 'boolean)
+
+(defcustom sesman-single-link-context-types '(buffer)
+  "List of context types to which at most one session can be linked."
+  :group 'sesman
+  :type '(repeat symbol))
+
+;; fixme;
+;; (defcustom sesman-abbreviate-paths 2
+;;   "Abbreviate paths to that many parents.
+;; When set to nil, don't abbreviate directories."
+;;   :group 'sesman
+;;   :type '(choice number
+;;                  (const :tag "Don't abbreviate" nil)))
+
+(defvar sesman-sessions-hashmap (make-hash-table :test #'equal)
+  "Hash-table of all sesman sessions.
+Key is a cons (system-name . session-name).")
+
+(defvar sesman-links-alist nil
+  "An alist of all sesman links.
+Each element is of the form (key cxt-type cxt-value) where
+\"key\" is of the form (system-name . session-name). system-name
+and cxt-type must be symbols.")
+
+(defvar-local sesman-system nil
+  "Name of the system managed by `sesman'.
+Can be either a symbol, or a function returning a symbol.")
+
+
+;; Internal Utilities
+
+(defun sesman--on-C-u-u-sessions (system which)
+  (cond
+   ((null which)
+    (let ((ses (sesman-current-session system)))
+      (when ses
+        (list ses))))
+   ((or (equal which '(4)) (eq which 'linked))
+    (sesman-linked-sessions system))
+   ((or (equal which '(16)) (eq which 'all) (eq which t))
+    (sesman--all-system-sessions system))
+   (t (error "Invalid which argument (%s)" which))))
+
+(defun sesman--cap-system-name (system)
+  (let ((name (symbol-name system)))
+    (if (string-match-p "^[[:upper:]]" name)
+        name
+      (capitalize name))))
+
+(defun sesman--link-session (system session &optional cxt-type)
+  (let* ((ses-name (or (car-safe session)
+                       (error "SESSION must be a headed list")))
+         (cxt-val (sesman--expand-path-maybe
+                   (or (if cxt-type
+                           (sesman-context cxt-type)
+                         ;; use the lest specific context-type available
+                         (seq-some (lambda (ctype)
+                                     (let ((val (sesman-context ctype)))
+                                       (setq cxt-type ctype)
+                                       val))
+                                   (reverse (sesman-context-types system))))
+                       (error "No local context of type %s" cxt-type))))
+         (key (cons system ses-name))
+         (link (list key cxt-type cxt-val)))
+    (if (member cxt-type sesman-single-link-context-types)
+        (thread-last sesman-links-alist
+          (seq-remove (sesman--link-lookup-fn system nil cxt-type cxt-val))
+          (cons link)
+          (setq sesman-links-alist))
+      (unless (seq-filter (sesman--link-lookup-fn system ses-name cxt-type cxt-val)
+                          sesman-links-alist)
+        (setq sesman-links-alist (cons link sesman-links-alist))))
+    key))
+
+(defmacro sesman--link-session-interactively (cxt-type)
+  (declare (indent 1)
+           (debug (symbolp &rest)))
+  (let ((cxt-name (symbol-name cxt-type)))
+    `(let ((system (sesman--system)))
+       (if (member ',cxt-type (sesman-context-types system))
+           (let ((session (sesman-ask-for-session
+                           system
+                           (format "Link with %s %s: "
+                                   ,cxt-name (sesman--abbrev-path-maybe
+                                              (sesman-context ',cxt-type)))
+                           (sesman--all-system-sessions system)
+                           'ask-new)))
+             (sesman--link-session system session ',cxt-type))
+         (error (format "%s association not allowed for this system (%s)"
+                        ,(capitalize (symbol-name cxt-type))
+                        system))))))
+
+(defun sesman--expand-path-maybe (obj)
+  (cond
+   ((stringp obj) (expand-file-name obj))
+   ((and (consp obj) (stringp (cdr obj)))
+    (cons (car obj) (expand-file-name (cdr obj))))
+   (t obj)))
+
+;; FIXME: incorporate `sesman-abbreviate-paths'
+(defun sesman--abbrev-path-maybe (obj)
+  (cond
+   ((stringp obj) (abbreviate-file-name obj))
+   ((and (consp obj) (stringp (cdr obj)))
+    (cons (car obj) (abbreviate-file-name (cdr obj))))
+   (t obj)))
+
+(defun sesman--system ()
+  (if sesman-system
+      (if (functionp sesman-system)
+          (funcall sesman-system)
+        sesman-system)
+    (error "No `sesman-system' in buffer `%s'" (current-buffer))))
+
+(defun sesman--all-system-sessions (&optional system)
+  "Return a list of sessions registered with SYSTEM."
+  (let ((system (or system (sesman--system)))
+        sessions)
+    (maphash
+     (lambda (k s)
+       (when (eql (car k) system)
+         (push s sessions)))
+     sesman-sessions-hashmap)
+    (sesman--sort-sessions system sessions)))
+
+;; FIXME: make this a macro
+(defun sesman--link-lookup-fn (&optional system ses-name cxt-type cxt-val x)
+  (let ((system (or system (caar x)))
+        (ses-name (or ses-name (cdar x)))
+        (cxt-type (or cxt-type (nth 1 x)))
+        (cxt-val (or cxt-val (nth 2 x))))
+    (lambda (el)
+      (and (or (null system) (eq (caar el) system))
+           (or (null ses-name) (equal (cdar el) ses-name))
+           (or (null cxt-type)
+               (if (listp cxt-type)
+                   (member (nth 1 el) cxt-type)
+                 (eq (nth 1 el) cxt-type)))
+           (or (null cxt-val) (equal (nth 2 el) cxt-val))))))
+
+(defun sesman--unlink (x)
+  (setq sesman-links-alist
+        (seq-remove (sesman--link-lookup-fn nil nil nil nil x)
+                    sesman-links-alist)))
+
+(defun sesman--clear-links ()
+  (setq sesman-links-alist
+        (seq-filter (lambda (x)
+                      (gethash (car x) sesman-sessions-hashmap))
+                    sesman-links-alist)))
+
+(defun sesman--format-link (link)
+  (let ((val (sesman--abbrev-path-maybe
+              (sesman--lnk-value link))))
+    (format "%s(%s)->%s"
+            (sesman--lnk-context-type link)
+            (if (listp val) (cdr val) val)
+            (propertize (sesman--lnk-session-name link) 'face 'bold))))
+
+(defun sesman--ask-for-link (prompt links &optional ask-all)
+  (let* ((name.keys (mapcar (lambda (link)
+                              (cons (sesman--format-link link) link))
+                            links))
+         (name.keys (append name.keys
+                            (when (and ask-all (> (length name.keys) 1))
+                              '(("*all*")))))
+         (nms (mapcar #'car name.keys))
+         (sel (completing-read prompt nms nil t nil nil (car nms))))
+    (cond ((string= sel "*all*")
+           links)
+          (ask-all
+           (list (cdr (assoc sel name.keys))))
+          (t
+           (cdr (assoc sel name.keys))))))
+
+(defun sesman--sort-sessions (system sessions)
+  (seq-sort (lambda (x1 x2)
+              (sesman-more-relevant-p system x1 x2))
+            sessions))
+
+(defun sesman--sort-links (system links)
+  (seq-sort (lambda (x1 x2)
+              (sesman-more-relevant-p system
+                                      (gethash (car x1) sesman-sessions-hashmap)
+                                      (gethash (car x2) sesman-sessions-hashmap)))
+            links))
+
+;; link data structure accessors
+(defun sesman--lnk-system-name (lnk)
+  (caar lnk))
+(defun sesman--lnk-session-name (lnk)
+  (cdar lnk))
+(defun sesman--lnk-context-type (lnk)
+  (cadr lnk))
+(defun sesman--lnk-value (lnk)
+  (nth 2 lnk))
+
+
+;;; User Interface
+
+ ;;;###autoload
+(defun sesman-start ()
+  "Start sesman session."
+  (interactive)
+  (let* ((system (sesman--system)))
+    (message "Starting new %s session ..." system)
+    (sesman-start-session system)))
+
+ ;;;###autoload
+(defun sesman-restart ()
+  "Restart sesman session."
+  (interactive)
+  (let* ((system (sesman--system))
+         (old-session (sesman-ensure-session system "Restart session: ")))
+    (message "Restarting %s '%s' session" system (car old-session))
+    (sesman-restart-session system old-session)))
+
+ ;;;###autoload
+(defun sesman-quit (which)
+  "Terminate sesman session.
+When WHICH is nil, kill only the current session; when a single universal
+argument or 'linked, kill all linked session; when a double universal argument,
+t or 'all, kill all sessions."
+  (interactive "P")
+  (let* ((system (sesman--system))
+         (sessions (sesman--on-C-u-u-sessions system which)))
+    (if (null sessions)
+        (message "No more %s sessions" system)
+      (mapc (lambda (s)
+              (sesman-unregister system s)
+              (sesman-quit-session system s))
+            sessions)
+      (message
+       "Killed %s %s %s"  system
+       (if (= 1 (length sessions)) "session" "sessions")
+       (mapcar #'car sessions)))))
+
+ ;;;###autoload
+(defun sesman-show-session-info (which)
+  "Display session(s) info.
+When WHICH is nil, show info for current session; when a single universal
+argument or 'linked, show info for all linked sessions; when a double universal
+argument or 'all, show info for all sessions."
+  (interactive "P")
+  (let* ((system (sesman--system))
+         (sessions (sesman--on-C-u-u-sessions system which)))
+    (if sessions
+        (message (mapconcat
+                  (lambda (ses)
+                    (format "%s [linked: %s]\n%s"
+                            (propertize (car ses) 'face 'bold)
+                            (sesman-session-links system ses t)
+                            (sesman-session-info system ses)))
+                  (delete-consecutive-dups sessions)
+                  "\n"))
+      (message "No %s sessions" system))))
+
+ ;;;###autoload
+(defun sesman-show-links ()
+  "Display links active in the current context."
+  (interactive)
+  (let* ((system (sesman--system))
+         (links (sesman-current-links system)))
+    (if links
+        (message (mapconcat #'sesman--format-link links "\n"))
+      (message "No %s links in the current context" system))))
+
+ ;;;###autoload
+(defun sesman-link-with-buffer ()
+  "Associate a session with current buffer."
+  (interactive)
+  (sesman--link-session-interactively buffer))
+
+ ;;;###autoload
+(defun sesman-link-with-directory ()
+  "Associate a session with current directory."
+  (interactive)
+  (sesman--link-session-interactively directory))
+
+ ;;;###autoload
+(defun sesman-link-with-project ()
+  "Associate a session with current project."
+  (interactive)
+  (sesman--link-session-interactively project))
+
+ ;;;###autoload
+(defun sesman-unlink ()
+  "Break any of the previously created links."
+  (interactive)
+  (let* ((system (sesman--system))
+         (links (or (sesman-current-links system)
+                    (user-error "No %s links found" system))))
+    (mapc #'sesman--unlink
+          (sesman--ask-for-link "Unlink: " links 'ask-all))))
+
+(defvar sesman-map
+  (let (sesman-map)
+    (define-prefix-command 'sesman-map)
+    (define-key sesman-map (kbd "C-i") 'sesman-show-session-info)
+    (define-key sesman-map (kbd   "i") 'sesman-show-session-info)
+    (define-key sesman-map (kbd "C-l") 'sesman-show-links)
+    (define-key sesman-map (kbd   "l") 'sesman-show-links)
+    (define-key sesman-map (kbd "C-s") 'sesman-start)
+    (define-key sesman-map (kbd   "s") 'sesman-start)
+    (define-key sesman-map (kbd "C-r") 'sesman-restart)
+    (define-key sesman-map (kbd   "r") 'sesman-restart)
+    (define-key sesman-map (kbd "C-q") 'sesman-quit)
+    (define-key sesman-map (kbd   "q") 'sesman-quit)
+    (define-key sesman-map (kbd "C-b") 'sesman-link-with-buffer)
+    (define-key sesman-map (kbd   "b") 'sesman-link-with-buffer)
+    (define-key sesman-map (kbd "C-d") 'sesman-link-with-directory)
+    (define-key sesman-map (kbd   "d") 'sesman-link-with-directory)
+    (define-key sesman-map (kbd "C-p") 'sesman-link-with-project)
+    (define-key sesman-map (kbd   "p") 'sesman-link-with-project)
+    (define-key sesman-map (kbd "C-u") 'sesman-unlink)
+    (define-key sesman-map (kbd "  u") 'sesman-unlink)
+    sesman-map)
+  "Session management prefix keymap.")
+
+(defvar sesman-menu
+  '("Sesman"
+    ["Show Session Info" sesman-show-session-info]
+    ["Show Links" sesman-show-links]
+    "--"
+    ["Start" sesman-start]
+    ["Restart" sesman-restart :active (sesman-connected-p)]
+    ["Quit" sesman-quit :active (sesman-connected-p)]
+    "--"
+    ["Link with Buffer" sesman-link-with-buffer :active (sesman-connected-p)]
+    ["Link with Directory" sesman-link-with-directory :active (sesman-connected-p)]
+    ["Link with Project" sesman-link-with-project :active (sesman-connected-p)]
+    "--"
+    ["Unlink" sesman-unlink :active (sesman-connected-p)])
+  "Sesman Menu.")
+
+(defun sesman-install-menu (map)
+  "Install `sesman-menu' into MAP."
+  (easy-menu-do-define 'seman-menu-open
+                       map
+                       (get 'sesman-menu 'variable-documentation)
+                       sesman-menu))
+
+
+;;; System Generic
+
+(cl-defgeneric sesman-start-session (system)
+  "Start and return SYSTEM SESSION.")
+
+(cl-defgeneric sesman-quit-session (system session)
+  "Terminate SYSTEM SESSION.")
+
+(cl-defgeneric sesman-restart-session (system session)
+  "Restart SYSTEM SESSION.
+By default, calls `sesman-quit-session' and then
+`sesman-start-session'."
+  (let ((old-name (car session)))
+    (sesman-quit-session system session)
+    (let ((new-session (sesman-start-session system)))
+      (setcar new-session old-name))))
+
+(cl-defgeneric sesman-session-info (_system session)
+  (cdr session))
+
+(cl-defgeneric sesman-context-types (_system)
+  "Return a list of context types understood by SYSTEM."
+  '(buffer directory project))
+
+(cl-defgeneric sesman-more-relevant-p (_system session1 session2)
+  "Return non-nil if SESSION1 should be sorted before SESSION2.
+By default, sort by session name. Systems should overwrite this method to
+provide a more meaningful ordering. If your system objects are buffers you
+can use `sesman-more-relevant-p' utility in this method."
+  (not (string-greaterp (car session1) (car session2))))
+
+
+;;; System API
+
+(defun sesman-session (system session-name)
+  "Retrieve SYSTEM's session with SESSION-NAME from global hash."
+  (let ((system (or system (sesman--system))))
+    (gethash (cons system session-name) sesman-sessions-hashmap)))
+
+(defun sesman-sessions (system)
+  "Return a list of all sessions registered with SYSTEM.
+`sesman-linked-sessions' lead the list."
+  (let ((system (or system (sesman--system))))
+    (delete-dups
+     (append (sesman-linked-sessions system)
+             ;; (sesman-friendly-sessions system)
+             (sesman--all-system-sessions system)))))
+
+(defun sesman-has-sessions-p (system)
+  "Return t if there is at least one session registered with SYSTEM."
+  (let ((system (or system (sesman--system)))
+        (found))
+    (condition-case nil
+        (maphash (lambda (k _)
+                   (when (eq (car k) system)
+                     (setq found t)
+                     (throw 'found nil)))
+                 sesman-sessions-hashmap)
+      (error))
+    found))
+
+(defvar sesman--select-session-history nil)
+(defun sesman-ask-for-session (system prompt &optional sessions ask-new ask-all)
+  "Ask for a SYSTEM session with PROMPT.
+SESSIONS defaults to value returned from `sesman-sessions'.  If
+ASK-NEW is non-nil, offer *new* option to start a new session.  If
+ASK-ALL is non-nil offer *all* option.  If ASK-ALL is non-nil,
+return a list of sessions, otherwise a single session."
+  (let* ((sessions (or sessions (sesman-sessions system)))
+         (name.syms (mapcar (lambda (s)
+                              (let ((name (car s)))
+                                (cons (if (symbolp name) (symbol-name name) name)
+                                      name)))
+                            sessions))
+         (nr (length name.syms))
+         (syms (if (and (not ask-new) (= nr 0))
+                   (error "No %s sessions found" system)
+                 (append name.syms
+                         (when ask-new '(("*new*")))
+                         (when (and ask-all (> nr 1))
+                           '(("*all*"))))))
+         (def (caar syms))
+         ;; (def (if (assoc (car sesman--select-session-history) syms)
+         ;;          (car sesman--select-session-history)
+         ;;        (caar syms)))
+         (sel (completing-read
+               prompt (mapcar #'car syms) nil t nil 'sesman--select-session-history def)))
+    (cond
+     ((string= sel "*new*")
+      (let ((ses (sesman-start-session system)))
+        (message "Started %s" (car ses))
+        (if ask-all (list ses) ses)))
+     ((string= sel "*all*")
+      sessions)
+     (t
+      (let* ((sym (cdr (assoc sel syms)))
+             (ses (assoc sym sessions)))
+        (if ask-all (list ses) ses))))))
+
+(defun sesman-current-session (system &optional cxt-types)
+  "Get the most relevant linked session for SYSTEM.
+CXT-TYPES is as in `sesman-linked-sessions'."
+  (car (sesman-linked-sessions system cxt-types)))
+
+(defun sesman-ensure-session (system &optional cxt-types)
+  "Get the most relevant linked session for SYSTEM or throw if none exists.
+CXT-TYPES is as in `sesman-linked-sessions'."
+  (or (car (sesman-linked-sessions system))
+      (user-error "No linked %s sessions" system)))
+
+(defun sesman-linked-sessions (system &optional cxt-types)
+  "Return a list of SYSTEM sessions linked in current context.
+CXT-TYPES is a list of context types to consider.  Defaults to the
+list returned from `sesman-context-types'."
+  (let* ((system (or system (sesman--system)))
+         (cxt-types (or cxt-types (sesman-context-types system))))
+    ;; just in case some links are lingering due to user errors
+    (sesman--clear-links)
+    (mapcar (lambda (assoc)
+              (gethash (car assoc) sesman-sessions-hashmap))
+            (sesman-current-links system cxt-types))))
+
+(defun sesman-session-links (system session &optional as-string)
+  "Retrieve all links for SYSTEM's SESSION from the global `SESSION-LINKS'.
+Return an alist of the form
+   ((buffer buffers..)
+    (directory directories...)
+    (project projects...)).
+If AS-STRING is non-nil, return an equivalent string representation."
+  (let* ((system (or system (sesman--system)))
+         (session (or session (sesman-current-session system)))
+         (ses-name (car session))
+         (links (thread-last sesman-links-alist
+                  (seq-filter (sesman--link-lookup-fn system ses-name))
+                  (sesman--sort-links system)
+                  (reverse)))
+         (out (mapcar (lambda (x) (list x))
+                      (sesman-context-types system))))
+    (mapc (lambda (link)
+            (let* ((type (sesman--lnk-context-type link))
+                   (val (sesman--lnk-value link))
+                   (entry (assoc type out)))
+              (when entry
+                (setcdr entry (cons val (cdr entry))))))
+          links)
+    (let ((out (delq nil (mapcar (lambda (el) (and (cdr el) el)) out))))
+      (if as-string
+          (mapconcat (lambda (link-vals)
+                       (let ((type (car link-vals)))
+                         (mapconcat (lambda (l)
+                                      (let ((l (if (listp l) (cdr l) l)))
+                                        (format "%s(%s)" type l)))
+                                    (cdr link-vals)
+                                    " ")))
+                     out
+                     " ")
+        out))))
+
+(defun sesman-links (system &optional session-name cxt-types)
+  "Retrieve all links for SYSTEM, SESSION-NAME and CXT-TYPES."
+  (let ((lfn (sesman--link-lookup-fn system session-name cxt-types)))
+    (seq-filter lfn sesman-links-alist)))
+
+(defun sesman-current-links (system &optional cxt-types)
+  "Retrieve all active links in current context for SYSTEM.
+CXT-TYPES is a list of context types to consider.  Returned links
+are a subset of `sesman-links-alist' sorted in order of relevance."
+  ;; mapcan is a built-in in 26.1; don't want to require cl-lib for one function
+  (seq-mapcat
+   (lambda (cxt-type)
+     (let ((lfn (sesman--link-lookup-fn system nil cxt-type)))
+       (sesman--sort-links
+        system
+        (seq-filter (lambda (l)
+                      (and (funcall lfn l)
+                           (sesman-relevant-context-p cxt-type (nth 2 l))))
+                    sesman-links-alist))))
+   (or cxt-types (sesman-context-types system))))
+
+(defun sesman-has-links-p (system &optional cxt-types)
+  "Return t if there is at least one linked session.
+CXT-TYPES defaults to `sesman-context-types' for current SYSTEM."
+  (let ((cxt-types (or cxt-types (sesman-context-types system)))
+        (found))
+    (condition-case nil
+        (mapc (lambda (l)
+                (when (eq system (sesman--lnk-system-name l))
+                  (let ((cxt (sesman--lnk-context-type l)))
+                    (when (and (member cxt cxt-types)
+                               (sesman-relevant-context-p cxt (sesman--lnk-value l)))
+                      (setq found t)
+                      (throw 'found nil)))))
+              sesman-links-alist)
+      (error))
+    found))
+
+(defun sesman-register (system session)
+  "Register SESSION into `sesman-sessions-hashmap' and `sesman-links-alist'.
+SYSTEM defaults to current system.  If a session with same name is already
+registered in `sesman-sessions-hashmap', change the name by appending \"#1\",
+\"#2\" ... to the name.  This function should be called by system-specific
+connection initializers (\"run-xyz\", \"xyz-jack-in\" etc.)."
+  (let* ((system (or system (sesman--system)))
+         (ses-name (car session))
+         (ses-name0 (car session))
+         (i 1))
+    (while (sesman-session system ses-name)
+      (setq ses-name (format "%s#%d" ses-name0 i)))
+    (setq session (cons ses-name (cdr session)))
+    (puthash (cons system ses-name) session sesman-sessions-hashmap)
+    (sesman--link-session system session)
+    session))
+
+(defun sesman-unregister (system session)
+  "Unregister SESSION.
+SYSTEM defaults to current system.  Remove session from
+`sesman-sessions-hashmap' and `sesman-links-alist'."
+  (let ((ses-key (cons system (car session))))
+    (remhash ses-key sesman-sessions-hashmap)
+    (sesman--clear-links)
+    session))
+
+(defun sesman-add-object (system session-name object &optional allow-new)
+  "Add (destructively) OBJECT to session SESSION-NAME of SYSTEM.
+If ALLOW-NEW is nil and session with SESSION-NAME does not exist
+throw an error, otherwise register a new session with
+session (list SESSION-NAME OBJECT)."
+  (let* ((system (or system (sesman--system)))
+         (session (sesman-session system session-name)))
+    (if session
+        (setcdr session (cons object (cdr session)))
+      (if allow-new
+          (sesman-register system (list session-name object))
+        (error "%s session '%s' does not exist"
+               (sesman--cap-system-name system) session-name)))))
+
+(defun sesman-remove-object (system session-name object &optional auto-unregister no-error)
+  "Remove (destructively) OBJECT from session SESSION-NAME of SYSTEM.
+If SESSION-NAME is nil, retrieve the session with
+`sesman-session-for-object'.  If OBJECT is the last object in sesman
+session, `sesman-unregister' the session.  If AUTO-UNREGISTER is non-nil
+unregister sessions of length 0 and remove all the links with the session.
+If NO-ERROR is non-nil, don't throw an error if OBJECT is not found in any
+session.  This is useful if there are several \"concurrent\" parties which
+can remove the object."
+  (let* ((system (or system (sesman--system)))
+         (session (if session-name
+                      (sesman-session system session-name)
+                    (sesman-session-for-object system object no-error)))
+         (new-session (delete object session)))
+    (cond ((null new-session))
+          ((= (length new-session) 1)
+           (when auto-unregister
+             (sesman-unregister system session)))
+          (t
+           (puthash (cons system (car session)) new-session sesman-sessions-hashmap)))))
+
+(defun sesman-session-for-object (system object &optional no-error)
+  "Retrieve SYSTEM session which contains OBJECT.
+When NO-ERROR is non-nil, don't throw an error if OBJECT is not part of any
+session.  In such case, return nil."
+  (let* ((system (or system (sesman--system)))
+         (sessions (sesman--all-system-sessions system)))
+    (or (seq-find (lambda (ses)
+                    (seq-find (lambda (x) (equal object x)) (cdr ses)))
+                  sessions)
+        (unless no-error
+          (error "%s is not part of any %s sessions"
+                 object system)))))
+
+(defun sesman-session-name-for-object (system object &optional no-error)
+  "Retrieve the name of the SYSTEM's session containing OBJECT.
+When NO-ERROR is non-nil, don't throw an error if OBJCECT is not part of
+any session.  In such case, return nil."
+  (car (sesman-session-for-object system object no-error)))
+
+(defun sesman-more-recent-p (bufs1 bufs2)
+  "Return t if BUFS1 is more recent than BUFS2.
+BUFS1 and BUFS2 are either buffers or lists of buffers.  When lists of
+buffers, most recent buffers from each list are considered.  To be used
+primarily in `sesman-more-relevant-p' methods when session objects are
+buffers."
+  (let ((bufs1 (if (bufferp bufs1) (list bufs1) bufs1))
+        (bufs2 (if (bufferp bufs2) (list bufs2) bufs2)))
+    (eq 1 (seq-some (lambda (b)
+                      (if (member b bufs1)
+                          1
+                        (when (member b bufs2)
+                          -1)))
+                    (buffer-list)))))
+
+
+;;; Contexts
+
+(cl-defgeneric sesman-context (_cxt-type)
+  "Given context type CXT-TYPE return the context.")
+(cl-defmethod sesman-context ((_cxt-type (eql buffer)))
+  "Return current buffer."
+  (current-buffer))
+(cl-defmethod sesman-context ((_cxt-type (eql directory)))
+  "Return current directory."
+  default-directory)
+(cl-defmethod sesman-context ((_cxt-type (eql project)))
+  "Return current project."
+  (project-current))
+
+(cl-defgeneric sesman-relevant-context-p (_cxt-type cxt)
+  "Non-nil if context CXT is relevant to current context of type CXT-TYPE.")
+(cl-defmethod sesman-relevant-context-p ((_cxt-type (eql buffer)) buf)
+  "Non-nil if BUF is `current-buffer'."
+  (eq (current-buffer) buf))
+(cl-defmethod sesman-relevant-context-p ((_cxt-type (eql directory)) dir)
+  "Non-nil if DIR is the parent or equals the `default-directory'."
+  (when (and dir default-directory)
+    (string-match-p (concat "^" dir) (expand-file-name default-directory))))
+(cl-defmethod sesman-relevant-context-p ((_cxt-type (eql project)) proj)
+  "Non-nil if PROJ is the parent or equals the `default-directory'."
+  (when (and proj default-directory)
+    (string-match-p (concat "^" (cdr proj))
+                    (expand-file-name default-directory))))
+
+
+(provide 'sesman)
+
+;;; sesman.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/sesman-20180719.213/sesman.elc b/configs/shared/emacs/.emacs.d/elpa/sesman-20180719.213/sesman.elc
new file mode 100644
index 0000000000..1eb7fb0476
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/sesman-20180719.213/sesman.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-attachment.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-attachment.el
new file mode 100644
index 0000000000..7d423e97b1
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-attachment.el
@@ -0,0 +1,127 @@
+;;; slack-attachment.el ---                          -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2017  南優也
+
+;; Author: 南優也 <yuyaminami@minamiyuuya-no-MacBook.local>
+;; Keywords:
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+(require 'eieio)
+
+(defclass slack-attachment ()
+  ((fallback :initarg :fallback :initform nil)
+   (title :initarg :title :initform nil)
+   (title-link :initarg :title_link :initform nil)
+   (pretext :initarg :pretext :initform nil)
+   (text :initarg :text :initform nil)
+   (author-name :initarg :author_name :initform nil)
+   (author-link :initarg :author_link)
+   (author-icon :initarg :author_icon)
+   (fields :initarg :fields :initform '())
+   (image-url :initarg :image_url :initform nil)
+   (image-width :initarg :image_width :initform nil)
+   (image-height :initarg :image_height :initform nil)
+   (thumb-url :initarg :thumb_url)
+   (is-share :initarg :is_share :initform nil)
+   (footer :initarg :footer :initform nil)
+   (color :initarg :color :initform nil)
+   (ts :initarg :ts :initform nil)
+   (author-subname :initarg :author_subname :initform nil)))
+
+(defclass slack-shared-message (slack-attachment)
+  ((channel-id :initarg :channel_id :initform nil)
+   (channel-name :initarg :channel_name :initform nil)
+   (from-url :initarg :from_url :initform nil)))
+
+(defmethod slack-image-spec ((this slack-attachment))
+  (with-slots (image-url image-height image-width) this
+    (when image-url
+      (list image-url image-width image-height slack-image-max-height))))
+
+(defmethod slack-message-to-string ((attachment slack-attachment) team)
+  (with-slots
+      (fallback text ts color from-url footer fields pretext) attachment
+    (let* ((pad-raw (propertize "|" 'face 'slack-attachment-pad))
+           (pad (or (and color (propertize pad-raw 'face (list :foreground (concat "#" color))))
+                    pad-raw))
+           (header-raw (slack-attachment-header attachment))
+           (header (and (not (slack-string-blankp header-raw))
+                        (format "%s\t%s" pad
+                                (propertize header-raw
+                                            'face 'slack-attachment-header))))
+           (pretext (and pretext (format "%s\t%s" pad pretext)))
+           (body (and text (format "%s\t%s" pad (mapconcat #'identity
+                                                           (split-string text "\n")
+                                                           (format "\n\t%s\t" pad)))))
+           (fields (if fields (mapconcat #'(lambda (field)
+                                             (slack-attachment-field-to-string field
+                                                                               (format "\t%s" pad)))
+                                         fields
+                                         (format "\n\t%s\n" pad))))
+           (footer (if footer
+                       (format "%s\t%s"
+                               pad
+                               (propertize
+                                (format "%s%s" footer
+                                        (or (and ts (format "|%s" (slack-message-time-to-string ts)))
+                                            ""))
+                                'face 'slack-attachment-footer))))
+           (image (slack-image-string (slack-image-spec attachment))))
+      (slack-message-unescape-string
+       (if (and (slack-string-blankp header)
+                (slack-string-blankp pretext)
+                (slack-string-blankp body)
+                (slack-string-blankp fields)
+                (slack-string-blankp footer))
+           fallback
+         (format "%s%s%s%s%s%s"
+                 (or (and header (format "\t%s\n" header)) "")
+                 (or (and pretext (format "\t%s\n" pretext)) "")
+                 (or (and body (format "\t%s" body)) "")
+                 (or (and fields fields) "")
+                 (or (and footer (format "\n\t%s" footer)) "")
+                 (or (and image (format "\n%s" image)) "")))
+       team))))
+
+(defmethod slack-attachment-header ((attachment slack-attachment))
+  (with-slots (title title-link author-name author-subname) attachment
+    (concat (or (and title title-link (slack-linkfy title title-link))
+                title
+                "")
+            (or author-name author-subname ""))))
+
+(defmethod slack-attachment-field-to-string ((field slack-attachment-field) &optional pad)
+  (unless pad (setq pad ""))
+  (let ((title (propertize (or (oref field title) "") 'face 'slack-attachment-field-title))
+        (value (mapconcat #'(lambda (e) (format "\t%s" e))
+                          (split-string (or (oref field value) "") "\n")
+                          (format "\n%s\t" pad))))
+    (format "%s\t%s\n%s\t%s" pad title pad value)))
+
+(defmethod slack-attachment-to-alert ((a slack-attachment))
+  (with-slots (title fallback pretext) a
+    (if (and title (< 0 (length title)))
+        title
+      (if (and pretext (< 0 (length pretext)))
+          (format "%s\n%s" pretext fallback)
+        fallback))))
+
+(provide 'slack-attachment)
+;;; slack-attachment.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-attachment.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-attachment.elc
new file mode 100644
index 0000000000..9fb4d122e2
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-attachment.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-autoloads.el
new file mode 100644
index 0000000000..d01812edfd
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-autoloads.el
@@ -0,0 +1,57 @@
+;;; slack-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "slack" "slack.el" (23377 61597 242468 217000))
+;;; Generated autoloads from slack.el
+
+(autoload 'slack-start "slack" "\
+
+
+\(fn &optional TEAM)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "slack-team" "slack-team.el" (23377 61597 250858
+;;;;;;  449000))
+;;; Generated autoloads from slack-team.el
+
+(autoload 'slack-register-team "slack-team" "\
+PLIST must contain :name :client-id :client-secret with value.
+setting :token will reduce your configuration step.
+you will notified when receive message with channel included in subscribed-channels.
+if :default is t and `slack-prefer-current-team' is t, skip selecting team when channels listed.
+you can change current-team with `slack-change-current-team'
+
+\(fn &rest PLIST)" t nil)
+
+;;;***
+
+;;;### (autoloads nil nil ("slack-attachment.el" "slack-bot-message.el"
+;;;;;;  "slack-buffer.el" "slack-channel.el" "slack-edit-file-comment-buffer.el"
+;;;;;;  "slack-emoji.el" "slack-file-comment-compose-buffer.el" "slack-file-comment.el"
+;;;;;;  "slack-file-info-buffer.el" "slack-file-list-buffer.el" "slack-file-share-message.el"
+;;;;;;  "slack-file.el" "slack-group.el" "slack-im.el" "slack-message-buffer.el"
+;;;;;;  "slack-message-compose-buffer.el" "slack-message-edit-buffer.el"
+;;;;;;  "slack-message-editor.el" "slack-message-formatter.el" "slack-message-notification.el"
+;;;;;;  "slack-message-reaction.el" "slack-message-sender.el" "slack-message-share-buffer.el"
+;;;;;;  "slack-message.el" "slack-pinned-item.el" "slack-pinned-items-buffer.el"
+;;;;;;  "slack-pkg.el" "slack-reaction.el" "slack-reminder.el" "slack-reply.el"
+;;;;;;  "slack-request-worker.el" "slack-request.el" "slack-room-buffer.el"
+;;;;;;  "slack-room-message-compose-buffer.el" "slack-room.el" "slack-search-result-buffer.el"
+;;;;;;  "slack-search.el" "slack-slash-commands.el" "slack-star.el"
+;;;;;;  "slack-stars-buffer.el" "slack-thread-message-buffer.el"
+;;;;;;  "slack-thread-message-compose-buffer.el" "slack-thread.el"
+;;;;;;  "slack-user-message.el" "slack-user-profile-buffer.el" "slack-user.el"
+;;;;;;  "slack-util.el" "slack-websocket.el") (23377 61597 269324
+;;;;;;  648000))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; slack-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-bot-message.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-bot-message.el
new file mode 100644
index 0000000000..92f62bfe3d
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-bot-message.el
@@ -0,0 +1,93 @@
+;;; slack-bot-message.el --- bot message class        -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2015  yuya.minami
+
+;; Author: yuya.minami <yuya.minami@yuyaminami-no-MacBook-Pro.local>
+;; Keywords:
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'eieio)
+(require 'slack-message)
+(require 'slack-message-formatter)
+(require 'slack-util)
+
+(defun slack-find-bot (id team)
+  (with-slots (bots) team
+    (cl-find-if (lambda (bot)
+                  (string= id (plist-get bot :id)))
+                bots)))
+
+(defmethod slack-bot-name ((m slack-bot-message) team)
+  (or (unless (slack-string-blankp (oref m username))
+        (oref m username))
+      (when (slot-boundp m 'bot-id)
+        (let ((bot (slack-find-bot (oref m bot-id) team)))
+          (plist-get bot :name)))
+      "Unknown Bot"))
+
+(defmethod slack-message-to-alert ((m slack-bot-message) team)
+  (let ((text (if (slot-boundp m 'text)
+                  (oref m text))))
+    (with-slots (attachments) m
+      (if (and text (< 0 (length text)))
+          (slack-message-unescape-string text team)
+        (let ((attachment-string (mapconcat #'slack-attachment-to-alert attachments " ")))
+          (slack-message-unescape-string attachment-string team))))))
+
+(defmethod slack-message-sender-name ((m slack-bot-message) team)
+  (slack-bot-name m team))
+
+(defmethod slack-message-sender-id ((m slack-bot-message))
+  (oref m bot-id))
+
+(defun slack-bot-image-url (bot size)
+  (let ((icons (plist-get bot :icons)))
+    (cond
+     ((eq size 36) (plist-get icons :image_36))
+     ((eq size 48) (plist-get icons :image_48))
+     ((eq size 72) (plist-get icons :image_72))
+     (t (plist-get icons :image_36)))))
+
+(defun slack-bot-fetch-image (bot size team)
+  (let* ((image-url (slack-bot-image-url bot size))
+         (file-path (and image-url (slack-profile-image-path image-url team))))
+    (when file-path
+      (if (file-exists-p file-path) file-path
+        (slack-url-copy-file image-url file-path))
+      file-path)))
+
+(cl-defun slack-bot-image (bot team &optional (size 36))
+  (when bot
+    (let ((image (slack-bot-fetch-image bot size team)))
+      (when image
+        (create-image image nil nil :ascent 80)))))
+
+(defmethod slack-bot-find ((m slack-bot-message) team)
+  (or (and (slot-boundp m 'bot-id)
+           (slack-find-bot (slack-message-sender-id m) team))
+      (slack-user-find-by-name (oref m username) team)))
+
+(defmethod slack-message-profile-image ((m slack-bot-message) team)
+  (let ((bot (slack-bot-find m team)))
+    (slack-bot-image bot team)))
+
+(provide 'slack-bot-message)
+;;; slack-bot-message.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-bot-message.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-bot-message.elc
new file mode 100644
index 0000000000..3a52179676
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-bot-message.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-buffer.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-buffer.el
new file mode 100644
index 0000000000..e0a1eb2f91
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-buffer.el
@@ -0,0 +1,439 @@
+;;; slack-buffer.el --- slack buffer                  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2015  南優也
+
+;; Author: 南優也 <yuyaminami@minamiyuunari-no-MacBook-Pro.local>
+;; Keywords:
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'eieio)
+(require 'lui)
+(require 'slack-util)
+(require 'slack-room)
+
+(define-derived-mode slack-buffer-mode lui-mode "Slack Buffer"
+  (setq-local default-directory slack-default-directory)
+  (add-hook 'lui-pre-output-hook 'slack-buffer-buttonize-link nil t)
+  (add-hook 'lui-pre-output-hook 'slack-add-face-lazy nil t)
+  (add-hook 'lui-post-output-hook 'slack-display-image t t)
+  (lui-set-prompt " "))
+
+(defvar-local slack-current-buffer nil)
+
+(defclass slack-buffer ()
+  ((team :initarg :team :type slack-team)))
+
+(defun slack-buffer-push-new-3 (class a team)
+  (let ((buf (get-buffer (slack-buffer-name class a team))))
+    (unless (slack-buffer-find class a team)
+      (push buf
+            (slot-value team class)))
+    buf))
+
+(defun slack-buffer-push-new-4 (class a b team)
+  (let ((buf (get-buffer (slack-buffer-name class a b team))))
+    (unless (slack-buffer-find class a b team)
+      (push buf (slot-value team class)))
+    buf))
+
+(defmethod slack-buffer-find :static ((class slack-buffer) room team)
+  (slack-if-let* ((buf (cl-find-if
+                  #'(lambda (buf)
+                      (string= (buffer-name buf)
+                               (slack-buffer-name class room team)))
+                  (slot-value team class))))
+      (with-current-buffer buf slack-current-buffer)))
+
+(defmethod slack-buffer-buffer ((this slack-buffer))
+  (or (get-buffer (slack-buffer-name this))
+      (slack-buffer-init-buffer this)))
+
+(defmethod slack-buffer-display ((this slack-buffer))
+  (condition-case err
+      (funcall slack-buffer-function (slack-buffer-buffer this))
+    (error (progn
+             (slack-if-let* ((buf (get-buffer (slack-buffer-name this))))
+                 (kill-buffer buf))
+             (signal (car err) (cdr err))))))
+
+(defmethod slack-buffer-name ((this slack-buffer))
+  "*Slack*")
+
+(defun slack-message-buffer-on-killed ()
+  (slack-if-let* ((buf slack-current-buffer)
+            (class (eieio-object-class-name buf))
+            (cb (current-buffer)))
+      (set-slot-value (oref buf team) class
+                      (cl-remove-if #'(lambda (e) (equal e cb))
+                                    (slot-value (oref buf team) class)))))
+
+(defun slack-buffer-replace-image (buffer ts)
+  (and (buffer-live-p buffer)
+       (with-current-buffer buffer
+         (slack-buffer--replace slack-current-buffer ts))))
+
+(defun slack-display-image ()
+  (goto-char (point-min))
+  (while (re-search-forward "\\[Image\\]" (point-max) t)
+    (slack-if-let* ((spec (get-text-property (1- (point)) 'slack-image-spec))
+                    (end (point))
+                    (beg (previous-single-property-change end 'slack-image-spec))
+                    (cur-buffer (current-buffer))
+                    (url (car spec))
+                    (ts (get-text-property beg 'ts))
+                    (path (slack-image-path url))
+                    (token (oref (oref slack-current-buffer team) token)))
+        (cl-labels
+            ((on-success ()
+                         (slack-buffer-replace-image cur-buffer ts)))
+          (unless (file-exists-p path)
+            (slack-url-copy-file url
+                                 path
+                                 :success #'on-success
+                                 :token token))))))
+
+(defmethod slack-buffer-init-buffer :after (this)
+  (slack-if-let* ((buf (get-buffer (slack-buffer-name this))))
+      (progn
+        (with-current-buffer buf
+          (slack-buffer-enable-emojify)
+          (add-hook 'kill-buffer-hook 'slack-message-buffer-on-killed nil t))
+        buf)))
+
+(defmethod slack-buffer-set-current-buffer ((this slack-buffer))
+  (setq-local slack-current-buffer this))
+
+
+(defmethod slack-buffer-init-buffer ((this slack-buffer))
+  (generate-new-buffer (slack-buffer-name this)))
+
+(defmethod slack-buffer-replace ((this slack-buffer) message)
+  (with-slots (team) this
+    (with-current-buffer (slack-buffer-buffer this)
+      (lui-replace (slack-message-to-string message team)
+                   (lambda ()
+                     (equal (get-text-property (point) 'ts)
+                            (oref message ts)))))))
+
+(defun slack-buffer-subscribe-cursor-event (window prev-point type)
+  (slack-if-let* ((buffer slack-current-buffer))
+      (progn
+        (slack-log (format "CURSOR-EVENT: BUFFER: %s, PREV-POINT: %s, POINT: %s, TYPE: %s"
+                           (buffer-name (window-buffer window))
+                           prev-point
+                           (point)
+                           type)
+                   (oref buffer team)
+                   :level 'trace)
+
+        (when (eq type 'entered)
+          (unless (slack-team-mark-as-read-immediatelyp (oref buffer team))
+            (slack-buffer-update-mark buffer))
+          (add-hook 'post-command-hook 'slack-reaction-echo-description t t))
+
+        (when (eq type 'left)
+          (remove-hook 'post-command-hook 'slack-reaction-echo-description t)))))
+
+(defmethod slack-buffer-insert ((this slack-buffer) message &optional not-tracked-p)
+  (let ((lui-time-stamp-time (slack-message-time-stamp message))
+        (team (oref this team)))
+    (lui-insert-with-text-properties
+     (slack-message-to-string message team)
+     'not-tracked-p not-tracked-p
+     'ts (slack-ts message)
+     'slack-last-ts lui-time-stamp-last
+     'cursor-sensor-functions '(slack-buffer-subscribe-cursor-event))
+    (lui-insert "" t)
+    ))
+
+(defmethod slack-buffer-insert-load-more ((this slack-buffer))
+  (let ((str (propertize "(load more)\n"
+                         'face '(:underline t :weight bold)
+                         'keymap (let ((map (make-sparse-keymap)))
+                                   (define-key map (kbd "RET")
+                                     #'(lambda ()
+                                         (interactive)
+                                         (slack-buffer-load-more this)))
+                                   map)
+                         'loading-message t)))
+    (let ((lui-time-stamp-position nil))
+      (lui-insert str))))
+
+(defmethod slack-buffer-loading-message-end-point ((this slack-buffer))
+  (next-single-property-change (point-min) 'loading-message))
+
+(defmethod slack-buffer-delete-load-more-string ((this slack-buffer))
+  (let ((loading-message-end
+         (slack-buffer-loading-message-end-point this)))
+    (delete-region (point-min) loading-message-end)))
+
+(defmethod slack-buffer-prepare-marker-for-history ((_this slack-buffer))
+  (set-marker lui-output-marker (point-min)))
+
+(defmethod slack-buffer-insert--history ((this slack-buffer))
+  (if (slack-buffer-has-next-page-p this)
+      (slack-buffer-insert-load-more this)
+    (let ((lui-time-stamp-position nil))
+      (lui-insert "(no more messages)\n")))
+
+  (slack-buffer-insert-history this))
+
+(defmethod slack-buffer-load-more ((this slack-buffer))
+  (with-slots (team) this
+    (let ((cur-point (point)))
+      (if (slack-buffer-has-next-page-p this)
+          (cl-labels
+              ((after-success
+                ()
+                (with-current-buffer (slack-buffer-buffer this)
+                  (let ((inhibit-read-only t))
+                    (slack-buffer-delete-load-more-string this)
+                    (slack-buffer-prepare-marker-for-history this)
+                    (slack-buffer-insert--history this)
+                    (lui-recover-output-marker)))))
+            (slack-buffer-request-history this #'after-success))
+        (message "No more items.")))))
+
+(defmethod slack-buffer-display-file ((this slack-buffer) file-id)
+  (with-slots (team) this
+    (cl-labels
+        ((open (file _)
+               (slack-buffer-display
+                (slack-create-file-info-buffer team file))))
+      (slack-file-request-info file-id 1 team #'open))))
+
+(defmethod slack-buffer-cant-execute ((this slack-buffer))
+  (message "Can't execute this command from %s" (eieio-object-class-name this)))
+
+(defmethod slack-buffer-display-pins-list ((this slack-buffer))
+  (slack-buffer-cant-execute this))
+(defmethod slack-buffer-pins-add ((this slack-buffer) ts)
+  (slack-buffer-cant-execute this))
+(defmethod slack-buffer-pins-remove ((this slack-buffer) ts)
+  (slack-buffer-cant-execute this))
+(defmethod slack-buffer-display-user-profile ((this slack-buffer))
+  (slack-buffer-cant-execute this))
+(defmethod slack-buffer-copy-link ((this slack-buffer) ts)
+  (slack-buffer-cant-execute this))
+
+(defvar lui-prompt-string "> ")
+
+(defvar slack-mode-map
+  (let ((map (make-sparse-keymap)))
+    ;; (define-key map (kbd "C-s C-r") #'slack-room-update-messages)
+    ;; (define-key map (kbd "C-s C-b") #'slack-message-write-another-buffer)
+    map))
+
+(defcustom slack-default-directory
+  (expand-file-name (concat (or (getenv "HOME") "~") "/"))
+  "default directory at Slack Buffer.")
+
+(define-derived-mode slack-mode lui-mode "Slack"
+  ""
+  (setq-local default-directory slack-default-directory)
+  (lui-set-prompt lui-prompt-string)
+  (setq lui-input-function 'slack-message--send))
+
+(define-derived-mode slack-info-mode lui-mode "Slack Info"
+  ""
+  (setq-local default-directory slack-default-directory)
+  (lui-set-prompt lui-prompt-string))
+
+(defcustom slack-buffer-emojify nil
+  "Show emoji with `emojify' if true."
+  :group 'slack)
+
+(defcustom slack-buffer-create-on-notify nil
+  "Create a room buffer when notification received if it does not yet exist"
+  :group 'slack)
+
+(defmacro slack-buffer-widen (&rest body)
+  `(save-excursion
+     (save-restriction
+       (widen)
+       ,@body)))
+
+(defun slack-buffer-enable-emojify ()
+  (if slack-buffer-emojify
+      (let ((emojify (require 'emojify nil t)))
+        (unless emojify
+          (error "Emojify is not installed"))
+        (emojify-mode t))))
+
+(defun slack-buffer-goto (ts)
+  (let ((point (slack-buffer-ts-eq (point-min) (point-max) ts)))
+    (when point
+      (goto-char point))))
+
+(defface slack-preview-face
+  (let* ((default-bg (or (face-background 'default) "unspecified-bg"))
+         (light-bg (if (equal default-bg "unspecified-bg")
+                       "unspecified-bg"
+                     (color-darken-name default-bg 3)))
+         (dark-bg (if (equal default-bg "unspecified-bg")
+                      "unspecified-bg"
+                    (color-lighten-name default-bg 3))))
+    `((default :inherit (fixed-pitch shadow) :slant normal :weight normal)
+      (((type graphic) (class color) (background dark)) (:background ,dark-bg))
+      (((type graphic) (class color) (background light)) (:background ,light-bg))))
+  "Used preview text and code blocks"
+  :group 'slack)
+
+(defun slack-put-preview-overlay (start end)
+  (let ((overlay (make-overlay start end)))
+    (overlay-put overlay 'face 'slack-preview-face)))
+
+(defalias 'slack-put-email-body-overlay 'slack-put-preview-overlay)
+(defalias 'slack-put-code-block-overlay 'slack-put-preview-overlay)
+
+(defun slack-search-code-block ()
+  (while (re-search-forward "`\\([^`]\\|\n\\)" (point-max) t)
+    (let* ((block-begin (- (point) 4))
+           (block-p (and (<= (point-min) block-begin)
+                         (string= (buffer-substring-no-properties block-begin
+                                                                  (+ block-begin 3))
+                                  "```")))
+           (beg (or (and block-p block-begin) (- (point) 2)))
+           (end-regex (or (and block-p "```") "[^`]`[^`]")))
+
+      (goto-char (+ beg (or (and block-p 3) 1)))
+
+      (if (re-search-forward end-regex (point-max) t)
+          (let* ((end (or (and block-p (1+ (point))) (- (point) 1))))
+            (slack-put-code-block-overlay beg end)
+            (goto-char end))))))
+
+
+(defun slack-add-face-lazy ()
+  (let* ((start (or (get-text-property (point-min) 'slack-defer-face)
+                    (next-single-property-change (point-min) 'slack-defer-face)))
+         (end (and start (next-single-property-change start 'slack-defer-face))))
+    (when (and start end)
+      (let ((face-or-func (get-text-property start 'slack-defer-face)))
+        (if (functionp face-or-func)
+            (funcall face-or-func start end)
+          (add-text-properties start end (list 'face face)))))))
+
+(defun slack-buffer-buttonize-link ()
+  (let ((regex "<\\(http://\\|https://\\)\\(.*?\\)|\\([[:ascii:][:nonascii:]]*?\\)>"))
+    (ignore-errors
+      (goto-char (point-min))
+      (while (re-search-forward regex nil t)
+        (let* ((url-begin (match-beginning 1))
+               (cur-point (point))
+               (disabled (get-text-property cur-point 'slack-disable-buttonize)))
+          (unless disabled
+            (let ((url (concat (match-string 1) (match-string 2)))
+                  (replace (match-string 3)))
+              (replace-match replace nil)
+              (make-button (1- url-begin)
+                           (+ (1- url-begin) (length replace))
+                           'type 'lui-button
+                           'action 'lui-button-activate
+                           'lui-button-function 'browse-url
+                           'lui-button-arguments (list url)))))))))
+
+(defun slack-buffer-show-typing-p (buffer)
+  (cl-case slack-typing-visibility
+    ('frame (slack-buffer-in-current-frame buffer))
+    ('buffer (slack-buffer-current-p buffer))
+    ('never nil)))
+
+(defun slack-buffer-current-p (buffer)
+  (if buffer
+      (string= (buffer-name buffer)
+               (buffer-name (current-buffer)))))
+
+(defun slack-buffer-in-current-frame (buffer)
+  (if buffer
+      (cl-member (buffer-name buffer)
+                 (mapcar #'buffer-name
+                         (mapcar #'window-buffer (window-list)))
+                 :test #'string=)))
+
+(defmacro slack-buffer-goto-char (find-point &rest else)
+  `(let* ((cur-point (point))
+          (ts (get-text-property cur-point 'ts)))
+     (let ((next-point ,find-point))
+       (if next-point
+           (goto-char next-point)
+         (if (< 0 (length ',else))
+             ,@else)))))
+
+(defun slack-buffer-goto-next-message ()
+  (interactive)
+  (slack-buffer-goto-char
+   (slack-buffer-next-point cur-point (point-max) ts)
+   (message "You are on Last Message.")))
+
+(defun slack-buffer-goto-prev-message ()
+  (interactive)
+  (slack-buffer-goto-char
+   (slack-buffer-prev-point cur-point (point-min) ts)
+   (message "You are on First Message.")))
+
+(defun slack-buffer-goto-first-message ()
+  (interactive)
+  (goto-char
+   (slack-buffer-next-point (point-min) (point-max) "0")))
+
+(defun slack-buffer-goto-last-message ()
+  (interactive)
+  (goto-char
+   (slack-buffer-prev-point (point-max) (point-min) (format-time-string "%s"))))
+
+(defun slack-buffer-header-p (point)
+  (let ((face (get-text-property point 'face)))
+    (string= (format "%s" face) "slack-message-output-header")))
+
+(defun slack-buffer-next-point (start end ts)
+  (cl-loop for i from start to end
+           if (and (string< ts
+                            (get-text-property i 'ts))
+                   (slack-buffer-header-p i))
+           return i))
+
+(defun slack-buffer-prev-point (start end ts)
+  (cl-loop for i from start downto end
+           if (and (string< (get-text-property i 'ts)
+                            ts)
+                   (slack-buffer-header-p i))
+           return i))
+
+(defun slack-buffer-ts-eq (start end ts)
+  (if (and start end)
+      (cl-loop for i from start to end
+               if (string= (get-text-property i 'ts)
+                           ts)
+               return i)))
+
+(defun slack--get-channel-id ()
+  (interactive)
+  (with-current-buffer (current-buffer)
+    (slack-if-let* ((buffer slack-current-buffer)
+                    (boundp (slot-boundp buffer 'room))
+                    (room (oref buffer room)))
+        (progn
+          (kill-new (oref room id))
+          (message "%s" (oref room id))))))
+
+(provide 'slack-buffer)
+;;; slack-buffer.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-buffer.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-buffer.elc
new file mode 100644
index 0000000000..3bc9fb9f7d
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-buffer.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-channel.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-channel.el
new file mode 100644
index 0000000000..3868b6444c
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-channel.el
@@ -0,0 +1,275 @@
+;;; slack-channel.el ---slack channel implement      -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2015  yuya.minami
+
+;; Author: yuya.minami <yuya.minami@yuyaminami-no-MacBook-Pro.local>
+;; Keywords:
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'eieio)
+(require 'slack-room)
+(require 'slack-group)
+(require 'slack-buffer)
+(require 'slack-util)
+(require 'slack-request)
+
+(defvar slack-buffer-function)
+
+(defconst slack-channel-history-url "https://slack.com/api/channels.history")
+(defconst slack-channel-list-url "https://slack.com/api/channels.list")
+(defconst slack-channel-buffer-name "*Slack - Channel*")
+(defconst slack-channel-update-mark-url "https://slack.com/api/channels.mark")
+(defconst slack-create-channel-url "https://slack.com/api/channels.create")
+(defconst slack-channel-rename-url "https://slack.com/api/channels.rename")
+(defconst slack-channel-invite-url "https://slack.com/api/channels.invite")
+(defconst slack-channel-leave-url "https://slack.com/api/channels.leave")
+(defconst slack-channel-join-url "https://slack.com/api/channels.join")
+(defconst slack-channel-info-url "https://slack.com/api/channels.info")
+(defconst slack-channel-archive-url "https://slack.com/api/channels.archive")
+(defconst slack-channel-unarchive-url "https://slack.com/api/channels.unarchive")
+(defconst slack-channel-info-url "https://slack.com/api/channels.info")
+
+(defclass slack-channel (slack-group)
+  ((is-member :initarg :is_member :initform nil)
+   (num-members :initarg :num_members :initform 0)))
+
+(defmethod slack-merge ((this slack-channel) other)
+  (call-next-method)
+  (with-slots (is-member num-members) this
+    (setq is-member (oref other is-member))
+    (setq num-members (oref other num-members))))
+
+(defmethod slack-room-buffer-name ((room slack-channel))
+  (concat slack-channel-buffer-name
+          " : "
+          (slack-room-display-name room)))
+
+(defun slack-channel-names (team &optional filter)
+  (with-slots (channels) team
+    (slack-room-names channels filter)))
+
+(defmethod slack-room-member-p ((room slack-channel))
+  (oref room is-member))
+
+(defun slack-channel-select ()
+  (interactive)
+  (let* ((team (slack-team-select))
+         (room (slack-room-select
+                (cl-loop for team in (list team)
+                         for channels = (oref team channels)
+                         nconc channels))))
+    (slack-room-display room team)))
+
+(defun slack-channel-list-update (&optional team after-success)
+  (interactive)
+  (let ((team (or team (slack-team-select))))
+    (cl-labels ((on-list-update
+                 (&key data &allow-other-keys)
+                 (slack-request-handle-error
+                  (data "slack-channel-list-update")
+                  (slack-merge-list (oref team channels)
+                                    (mapcar #'(lambda (d)
+                                                (slack-room-create d
+                                                                   team
+                                                                   'slack-channel))
+                                            (plist-get data :channels)))
+
+                  (if after-success
+                      (funcall after-success team))
+                  (mapc #'(lambda (room)
+                            (slack-request-worker-push
+                             (slack-room-create-info-request room team)))
+                        (oref team channels))
+                  (slack-log "Slack Channel List Updated" team :level 'info))))
+      (slack-room-list-update slack-channel-list-url
+                              #'on-list-update
+                              team
+                              :sync nil))))
+
+(defmethod slack-room-update-mark-url ((_room slack-channel))
+  slack-channel-update-mark-url)
+
+(defun slack-create-channel ()
+  (interactive)
+  (let ((team (slack-team-select)))
+    (cl-labels
+        ((on-create-channel (&key data &allow-other-keys)
+                            (slack-request-handle-error
+                             (data "slack-channel-create"))))
+      (slack-create-room slack-create-channel-url
+                         team
+                         #'on-create-channel))))
+
+(defun slack-channel-rename ()
+  (interactive)
+  (slack-room-rename slack-channel-rename-url
+                     #'slack-channel-names))
+
+(defun slack-channel-invite ()
+  (interactive)
+  (slack-room-invite slack-channel-invite-url
+                     #'slack-channel-names))
+
+(defun slack-channel-leave (&optional team select)
+  (interactive)
+  (let* ((team (or team (slack-team-select)))
+         (channel (slack-current-room-or-select
+                   #'(lambda ()
+                       (slack-channel-names
+                        team
+                        #'(lambda (channels)
+                            (cl-remove-if-not #'slack-room-member-p
+                                              channels))))
+                   select)))
+    (slack-channel-request-leave channel team)))
+
+(defun slack-channel-request-leave (channel team)
+  (cl-labels
+      ((on-channel-leave (&key data &allow-other-keys)
+                         (slack-request-handle-error
+                          (data "slack-channel-leave")
+                          (oset channel is-member nil)
+                          (message "Left Channel: %s"
+                                   (slack-room-name channel)))))
+    (slack-room-request-with-id slack-channel-leave-url
+                                (oref channel id)
+                                team
+                                #'on-channel-leave)))
+
+(defun slack-channel-join (&optional team select)
+  (interactive)
+  (cl-labels
+      ((filter-channel (channels)
+                       (cl-remove-if
+                        #'(lambda (c)
+                            (or (slack-room-member-p c)
+                                (slack-room-archived-p c)))
+                        channels)))
+    (let* ((team (or team (slack-team-select)))
+           (channel (slack-current-room-or-select
+                     #'(lambda ()
+                         (slack-channel-names team
+                                              #'filter-channel))
+                     select)))
+      (slack-channel-request-join channel team))))
+
+(defun slack-channel-request-join (channel team)
+  (cl-labels
+      ((on-channel-join (&key data &allow-other-keys)
+                        (slack-request-handle-error
+                         (data "slack-channel-join"))))
+    (slack-request
+     (slack-request-create
+      slack-channel-join-url
+      team
+      :params (list (cons "name" (slack-room-name channel)))
+      :success #'on-channel-join))))
+
+(defun slack-channel-create-from-info (id team)
+  (cl-labels
+      ((on-create-from-info
+        (&key data &allow-other-keys)
+        (slack-request-handle-error
+         (data "slack-channel-create-from-info")
+         (let* ((c-data (plist-get data :channel)))
+           (if (plist-get c-data :is_channel)
+               (let ((channel (slack-room-create c-data team 'slack-channel)))
+                 (with-slots (channels) team (push channel channels))
+                 (message "Channel: %s created"
+                          (slack-room-display-name channel))))))))
+    (slack-channel-fetch-info id team #'on-create-from-info)))
+
+(defun slack-channel-fetch-info (id team success)
+  (slack-request
+   (slack-request-create
+    slack-channel-info-url
+    team
+    :params (list (cons "channel" id))
+    :success success)))
+
+(defun slack-channel-archive ()
+  (interactive)
+  (let* ((team (slack-team-select))
+         (channel (slack-current-room-or-select
+                   #'(lambda ()
+                       (slack-channel-names
+                        team
+                        #'(lambda (channels)
+                            (cl-remove-if #'slack-room-archived-p
+                                          channels)))))))
+    (cl-labels
+        ((on-channel-archive (&key data &allow-other-keys)
+                             (slack-request-handle-error
+                              (data "slack-channel-archive"))))
+      (slack-room-request-with-id slack-channel-archive-url
+                                  (oref channel id)
+                                  team
+                                  #'on-channel-archive))))
+
+(defun slack-channel-unarchive ()
+  (interactive)
+  (let* ((team (slack-team-select))
+         (channel (slack-current-room-or-select
+                   #'(lambda ()
+                       (slack-channel-names
+                        team
+                        #'(lambda (channels)
+                            (cl-remove-if-not #'slack-room-archived-p
+                                              channels)))))))
+    (cl-labels
+        ((on-channel-unarchive (&key data &allow-other-keys)
+                               (slack-request-handle-error
+                                (data "slack-channel-unarchive"))))
+      (slack-room-request-with-id slack-channel-unarchive-url
+                                  (oref channel id)
+                                  team
+                                  #'on-channel-unarchive))))
+
+(defmethod slack-room-subscribedp ((room slack-channel) team)
+  (with-slots (subscribed-channels) team
+    (let ((name (slack-room-name room)))
+      (and name
+           (memq (intern name) subscribed-channels)))))
+
+(defmethod slack-room-get-info-url ((_room slack-channel))
+  slack-channel-info-url)
+
+(defmethod slack-room-update-info ((room slack-channel) data team)
+  (let ((new-room (slack-room-create (plist-get data :channel)
+                                     team
+                                     'slack-channel)))
+
+    (slack-merge room new-room)))
+
+(defmethod slack-room-history-url ((_room slack-channel))
+  slack-channel-history-url)
+
+(defmethod slack-room-replies-url ((_room slack-channel))
+  "https://slack.com/api/channels.replies")
+
+(defmethod slack-room-hidden-p ((room slack-channel))
+  (slack-room-archived-p room))
+
+(defmethod slack-room-member-p ((this slack-channel))
+  (oref this is-member))
+
+(provide 'slack-channel)
+;;; slack-channel.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-channel.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-channel.elc
new file mode 100644
index 0000000000..8be793b9d5
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-channel.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-edit-file-comment-buffer.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-edit-file-comment-buffer.el
new file mode 100644
index 0000000000..45b7e562d3
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-edit-file-comment-buffer.el
@@ -0,0 +1,89 @@
+;;; slack-edit-file-comment-buffer.el ---            -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2017
+
+;; Author:  <yuya373@yuya373>
+;; Keywords:
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'eieio)
+(require 'slack-util)
+(require 'slack-message)
+(require 'slack-message-compose-buffer)
+
+(define-derived-mode slack-edit-file-comment-buffer-mode
+  slack-message-edit-buffer-mode
+  "Slack Edit File Comment")
+
+(defclass slack-edit-file-comment-buffer
+  (slack-message-compose-buffer)
+  ((file :initarg :file :type slack-file)
+   (file-comment-id :initarg :file-comment-id :type string)))
+
+(defun slack-create-edit-file-comment-buffer (file file-comment-id team)
+  (slack-if-let* ((buf (slack-buffer-find 'slack-edit-file-comment-buffer
+                                    file
+                                    file-comment-id
+                                    team)))
+      buf
+    (slack-edit-file-comment-buffer :file file
+                                    :file-comment-id file-comment-id
+                                    :team team)))
+
+(defmethod slack-buffer-name :static ((_class slack-edit-file-comment-buffer) file file-comment-id team)
+  (format "*Slack - %s : %s Edit File Comment: %s"
+          (oref team name)
+          (with-slots (title name id) file
+            (or title name id))
+          file-comment-id))
+
+(defmethod slack-buffer-name ((this slack-edit-file-comment-buffer))
+  (with-slots (file file-comment-id team) this
+    (slack-buffer-name (eieio-object-class-name this)
+                       file file-comment-id team)))
+
+(defmethod slack-buffer-find :static ((class slack-edit-file-comment-buffer) file file-comment-id team)
+  (slack-buffer-find-4 class file file-comment-id team))
+
+(defmethod slack-buffer-init-buffer ((this slack-edit-file-comment-buffer))
+  (let ((buf (generate-new-buffer (slack-buffer-name this))))
+    (with-current-buffer buf
+      (slack-edit-file-comment-buffer-mode)
+      (slack-buffer-set-current-buffer this)
+      (setq buffer-read-only nil)
+      (erase-buffer)
+      (with-slots (file file-comment-id) this
+        (slack-with-file-comment file-comment-id file
+          (insert (slack-message-unescape-string
+                   (oref file-comment comment)
+                   (oref this team))))))
+    buf))
+
+(defmethod slack-buffer-send-message ((this slack-edit-file-comment-buffer) message)
+  (with-slots (file file-comment-id team) this
+    (slack-file-comment-edit-request (oref file id)
+                                     file-comment-id
+                                     message
+                                     team))
+  (call-next-method))
+
+(provide 'slack-edit-file-comment-buffer)
+;;; slack-edit-file-comment-buffer.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-edit-file-comment-buffer.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-edit-file-comment-buffer.elc
new file mode 100644
index 0000000000..1b70b90c3d
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-edit-file-comment-buffer.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-emoji.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-emoji.el
new file mode 100644
index 0000000000..baec1b03b8
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-emoji.el
@@ -0,0 +1,93 @@
+;;; slack-emoji.el ---                               -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2017  南優也
+
+;; Author: 南優也 <yuyaminami@minamiyuuya-no-MacBook.local>
+;; Keywords:
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+(require 'slack-request)
+
+(defconst slack-emoji-list "https://slack.com/api/emoji.list")
+
+(defun slack-emoji-watch-download-complete (team paths)
+  (if (eq (length (cl-remove-if #'identity (mapcar #'file-exists-p paths)))
+          0)
+      (when (timerp (oref team emoji-download-watch-timer))
+        (cancel-timer (oref team emoji-download-watch-timer))
+        (oset team emoji-download-watch-timer nil)
+        (emojify-create-emojify-emojis t))))
+
+(defun slack-request-emoji (team)
+  (if (require 'emojify nil t)
+      (cl-labels
+          ((handle-alias (name emojis)
+                         (let* ((raw-url (plist-get emojis name))
+                                (alias (if (string-prefix-p "alias:" raw-url)
+                                           (intern (format ":%s" (cadr (split-string raw-url ":")))))))
+                           (or (and alias (or (plist-get emojis alias)
+                                              (let ((emoji (emojify-get-emoji (format "%s:" alias))))
+                                                (if emoji
+                                                    (concat (emojify-image-dir) "/" (gethash "image" emoji))))))
+                               raw-url)))
+           (push-new-emoji (emoji)
+                           (cl-pushnew emoji emojify-user-emojis
+                                       :test #'string=
+                                       :key #'car))
+           (on-success
+            (&key data &allow-other-keys)
+            (slack-request-handle-error
+             (data "slack-request-emoji")
+             (emojify-create-emojify-emojis)
+             (let* ((emojis (plist-get data :emoji))
+                    (names (cl-remove-if
+                            #'(lambda (key) (not (plist-member emojis key)))
+                            emojis))
+                    (paths
+                     (mapcar
+                      #'(lambda (name)
+                          (let* ((url (handle-alias name emojis))
+                                 (path (if (file-exists-p url) url
+                                         (slack-image-path url)))
+                                 (emoji (cons (format "%s:" name)
+                                              (list (cons "name" (substring (symbol-name name) 1))
+                                                    (cons "image" path)
+                                                    (cons "style" "github")))))
+                            (if (file-exists-p path)
+                                (push-new-emoji emoji)
+                              (slack-url-copy-file
+                               url
+                               path
+                               :success #'(lambda () (push-new-emoji emoji))))
+
+                            path))
+                      names)))
+
+               (oset team
+                     emoji-download-watch-timer
+                     (run-with-idle-timer 5 t #'slack-emoji-watch-download-complete team paths))))))
+        (slack-request
+         (slack-request-create
+          slack-emoji-list
+          team
+          :success #'on-success)))))
+
+(provide 'slack-emoji)
+;;; slack-emoji.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-emoji.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-emoji.elc
new file mode 100644
index 0000000000..1330302ab4
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-emoji.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-file-comment-compose-buffer.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-file-comment-compose-buffer.el
new file mode 100644
index 0000000000..2cb2c9f16f
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-file-comment-compose-buffer.el
@@ -0,0 +1,74 @@
+;;; slack-file-comment-compose-buffer.el ---         -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2017  南優也
+
+;; Author: 南優也 <yuyaminami@minamiyuuya-no-MacBook.local>
+;; Keywords:
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+(require 'eieio)
+(require 'slack-util)
+(require 'slack-message-compose-buffer)
+
+(defclass slack-file-comment-compose-buffer
+  (slack-message-compose-buffer)
+  ((file :initarg :file :type slack-file)))
+
+(defmethod slack-buffer-name :static ((class slack-file-comment-compose-buffer) file team)
+  (format "*Slack -  %s : Compose %s Comment*"
+          (oref team name)
+          (with-slots (title name id) file
+            (or title name id))))
+
+(defmethod slack-buffer-name ((this slack-file-comment-compose-buffer))
+  (with-slots (file team) this
+    (slack-buffer-name 'slack-file-comment-compose-buffer
+                       file team)))
+
+(defmethod slack-buffer-init-buffer ((this slack-file-comment-compose-buffer))
+  (let ((buf (call-next-method)))
+    (with-current-buffer buf
+      (slack-message-compose-buffer)
+      (slack-buffer-set-current-buffer this)
+      (setq buffer-read-only nil)
+      (erase-buffer))
+    (with-slots (file team) this
+      (slack-buffer-push-new-3 'slack-file-comment-compose-buffer
+                               file team))
+    buf))
+
+(defmethod slack-buffer-send-message
+  ((this slack-file-comment-compose-buffer) message)
+  (with-slots (file team) this
+    (slack-file-comment-add-request (oref file id)
+                                    message
+                                    team))
+  (call-next-method))
+
+(defun slack-create-file-comment-compose-buffer (file team)
+  (slack-if-let* ((buf (slack-buffer-find
+                        'slack-file-comment-compose-buffer
+                        file team)))
+      buf
+    (slack-file-comment-compose-buffer :file file
+                                       :team team)))
+
+(provide 'slack-file-comment-compose-buffer)
+;;; slack-file-comment-compose-buffer.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-file-comment-compose-buffer.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-file-comment-compose-buffer.elc
new file mode 100644
index 0000000000..188aeb4544
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-file-comment-compose-buffer.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-file-comment.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-file-comment.el
new file mode 100644
index 0000000000..faeba0cdcd
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-file-comment.el
@@ -0,0 +1,210 @@
+;;; slack-file-comment.el ---                        -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2017
+
+;; Author:  <yuya373@yuya373>
+;; Keywords:
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+(require 'slack-util)
+(require 'slack-message)
+(require 'slack-file)
+
+(define-derived-mode slack-edit-file-comment-mode
+  fundamental-mode
+  "Slack Edit File Comment"
+  ""
+  (slack-buffer-enable-emojify))
+
+(defvar slack-edit-file-comment-mode-map
+  (let ((keymap (make-sparse-keymap)))
+    (define-key keymap (kbd "C-c C-c") #'slack-file-comment-edit-commit)
+    keymap))
+
+(defclass slack-file-comment (slack-user-message)
+  ((id :initarg :id)
+   (file-id :initarg :file_id :type string)
+   (created :initarg :created)
+   (timestamp :initarg :timestamp)
+   (user :initarg :user)
+   (is-intro :initarg :is_intro)
+   (comment :initarg :comment)
+   (channel :initarg :channel)
+   (reactions :initarg :reactions type list)
+   (is-starred :initarg :is_starred :type boolean :initform nil)))
+
+(defclass slack-file-comment-message (slack-file-message)
+  ((comment :initarg :comment :initform nil)))
+
+(defclass slack-file-mention-message (slack-file-message)
+  ((user :initarg :user :initform nil)))
+
+(defmethod slack-reaction-delete ((this slack-file-comment) reaction)
+  (with-slots (reactions) this
+    (setq reactions
+          (slack-reaction--delete reactions reaction))))
+
+(defmethod slack-reaction-push ((this slack-file-comment) reaction)
+  (push reaction (oref this reactions)))
+
+(defmethod slack-reaction-find ((this slack-file-comment) reaction)
+  (slack-reaction--find (oref this reactions) reaction))
+
+(defmethod slack-message-reactions ((this slack-file-comment))
+  (oref this reactions))
+
+(defmethod slack-message-reaction-to-string ((m slack-file-comment) team)
+  (let ((reactions (oref m reactions)))
+    (when reactions
+      (slack-format-reactions reactions team))))
+
+(defmethod slack-equalp ((c slack-file-comment) other)
+  (string= (oref c id) (oref other id)))
+
+(defmethod slack-merge ((old slack-file-comment) new)
+  (slack-merge-list (oref old reactions) (oref new reactions))
+  (oset old comment (oref new comment)))
+
+(defmethod slack-message-body ((comment slack-file-comment) team)
+  (slack-message-unescape-string (oref comment comment) team))
+
+(defmethod slack-message-to-string ((comment slack-file-comment) team)
+  (let ((header (slack-message-header-to-string comment team))
+        (body (slack-message-body-to-string comment team))
+        (reactions (slack-message-reaction-to-string comment team)))
+    (propertize (slack-format-message header body reactions)
+                'file-comment-id (oref comment id))))
+
+(defmethod slack-file-id ((file-comment slack-file-comment))
+  (oref file-comment file-id))
+
+(defmethod slack-message-star-added ((this slack-file-comment))
+  (oset this is-starred t))
+
+(defmethod slack-message-star-removed ((this slack-file-comment))
+  (oset this is-starred nil))
+
+(defmethod slack-message-star-api-params ((this slack-file-comment))
+  (cons "file_comment" (oref this id)))
+
+(defun slack-file-comment-edit-commit ()
+  (interactive)
+  (slack-if-let* ((buf slack-current-buffer)
+            (message (buffer-substring-no-properties (point-min) (point-max))))
+      (slack-buffer-send-message buf message)))
+
+(defun slack-file-comment-process-star-api (url team)
+  (slack-if-let* ((file-id slack-current-file-id)
+            (file-comment-id (slack-get-file-comment-id)))
+      (slack-with-file file-id team
+        (slack-with-file-comment file-comment-id file
+          (slack-message-star-api-request url
+                                          (list (slack-message-star-api-params file-comment))
+                                          team)))))
+
+(defmethod slack-message-set-file-comment ((m slack-file-comment-message) payload)
+  (let* ((file-id (plist-get (plist-get payload :file) :id))
+         (comment (plist-get payload :comment))
+         (file-comment (slack-file-comment-create comment file-id)))
+    (oset m comment file-comment)
+    m))
+
+(defmethod slack-message-sender-name ((m slack-file-comment-message) team)
+  (slack-user-name (oref (oref m comment) user) team))
+
+(defmethod slack-message-sender-id ((m slack-file-comment-message))
+  (oref (oref m comment) user))
+
+(defmethod slack-message-star-added ((m slack-file-comment-message))
+  (slack-message-star-added (oref m comment)))
+
+(defmethod slack-message-star-removed ((m slack-file-comment-message))
+  (slack-message-star-removed (oref m comment)))
+
+(defmethod slack-message-star-api-params ((m slack-file-comment-message))
+  (slack-message-star-api-params (oref m comment)))
+
+(defmethod slack-reaction-delete ((this slack-file-comment-message) reaction)
+  (slack-reaction-delete (oref this comment) reaction))
+
+(defmethod slack-reaction-push ((this slack-file-comment-message) reaction)
+  (slack-reaction-push (oref this comment) reaction))
+
+(defmethod slack-reaction-find ((this slack-file-comment-message) reaction)
+  (slack-reaction-find (oref this comment) reaction))
+
+(defmethod slack-message-reactions ((this slack-file-comment-message))
+  (slack-message-reactions (oref this comment)))
+
+(defmethod slack-message-get-param-for-reaction ((m slack-file-comment-message))
+  (cons "file_comment" (oref (oref m comment) id)))
+
+(defmethod slack-file-id ((m slack-file-comment-message))
+  (slack-file-id (oref m comment)))
+
+(defmethod slack-message-starred-p ((m slack-file-comment-message))
+  (oref (oref m comment) is-starred))
+
+(defmethod slack-message-to-string ((this slack-file-comment-message) team)
+  (with-slots (permalink name id page) (oref this file)
+    (with-slots (comment) (oref this comment)
+      (let* ((face '(:underline t))
+             (text (format "commented on %s <%s|open in browser>\n%s"
+                           (slack-file-link-info (oref (oref this file) id) name)
+                           permalink
+                           (format "“ %s" (slack-message-unescape-string comment
+                                                                          team))))
+             (header (slack-message-header-to-string this team))
+             (reactions (slack-message-reaction-to-string this team)))
+        (slack-format-message header text reactions)))))
+
+(defmethod slack-message-get-user-id ((m slack-file-comment-message))
+  (oref (oref m comment) user))
+
+(defmethod slack-message-edit-type ((_m slack-file-comment-message))
+  'edit-file-comment)
+
+(defmethod slack-message-get-text ((m slack-file-comment-message))
+  (oref (oref m comment) comment))
+
+(defmethod slack-message-changed--copy ((this slack-file-comment-message) other)
+  (when (slack-file-comment-message-p other)
+    (let ((changed (call-next-method)))
+      (with-slots ((old-comment comment) text) this
+        (let ((new-comment (oref other comment)))
+          (oset old-comment reactions (oref new-comment reactions))
+          (unless (string= (oref old-comment comment) (oref new-comment comment))
+            (oset old-comment comment (oref new-comment comment))
+            (setq changed t))))
+      changed)))
+
+(defmethod slack-ts ((this slack-file-comment))
+  (number-to-string (oref this timestamp)))
+
+(defmethod slack-message-update ((this slack-file-comment) file team)
+  (slack-if-let* ((buffer (slack-buffer-find 'slack-file-info-buffer
+                                             file
+                                             team)))
+      (progn
+        (oset buffer file file)
+        (slack-buffer-update buffer (oref this id)))))
+
+(provide 'slack-file-comment)
+;;; slack-file-comment.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-file-comment.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-file-comment.elc
new file mode 100644
index 0000000000..a8b1516b86
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-file-comment.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-file-info-buffer.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-file-info-buffer.el
new file mode 100644
index 0000000000..8adfb04365
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-file-info-buffer.el
@@ -0,0 +1,235 @@
+;;; slack-file-info-buffer.el ---                    -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2017
+
+;; Author:  <yuya373@yuya373>
+;; Keywords:
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'eieio)
+(require 'slack-util)
+(require 'slack-buffer)
+(require 'slack-message)
+
+(define-derived-mode slack-file-info-buffer-mode slack-buffer-mode  "Slack File Info"
+  (lui-set-prompt (format "Add Comment %s" lui-prompt-string))
+  (add-hook 'lui-post-output-hook 'slack-display-image t t)
+  (setq lui-input-function 'slack-file-comment--add))
+
+(defclass slack-file-info-buffer (slack-buffer)
+  ((file :initarg :file :type slack-file)))
+
+(defmethod slack-buffer-name :static ((class slack-file-info-buffer) file team)
+  (format "*Slack - %s File: %s"
+          (oref team name)
+          (or (oref file title)
+              (oref file name)
+              (oref file id))))
+
+(defun slack-create-file-info-buffer (team file)
+  (slack-if-let* ((buffer (slack-buffer-find 'slack-file-info-buffer
+                                             file
+                                             team)))
+      (progn
+        (oset buffer file file)
+        buffer)
+    (slack-file-info-buffer :team team :file file)))
+
+(defmethod slack-buffer-init-buffer :after ((this slack-file-info-buffer))
+  (with-slots (file team) this
+    (let ((class (eieio-object-class-name this)))
+      (slack-buffer-push-new-3 class file team))))
+
+(defmethod slack-buffer-name ((this slack-file-info-buffer))
+  (with-slots (file team) this
+    (slack-buffer-name (eieio-object-class-name this)
+                       file
+                       team)))
+
+(defmethod slack-buffer-buffer ((this slack-file-info-buffer))
+  (slack-if-let* ((buf (get-buffer (slack-buffer-name this))))
+      (progn
+        (with-current-buffer buf
+          (slack-buffer-insert this))
+        buf)
+    (slack-buffer-init-buffer this)))
+
+(defmethod slack-buffer-init-buffer ((this slack-file-info-buffer))
+  (let ((buf (call-next-method)))
+    (with-current-buffer buf
+      (slack-file-info-buffer-mode)
+      (slack-buffer-set-current-buffer this)
+      (slack-buffer-insert this))
+    buf))
+
+(defmethod slack-buffer-file-to-string ((this slack-file-info-buffer))
+  (with-slots (file team) this
+    (let* ((header (slack-message-header-to-string file team))
+           (body (slack-message-body-to-string file team))
+           (thumb (or (and (slack-file-image-p file)
+                           (slack-message-large-image-to-string file))
+                      (slack-message-image-to-string file)))
+           (reactions (slack-message-reaction-to-string file team))
+
+           (comments-count
+            (slack-file-comments-count-to-string file)))
+      (propertize (slack-format-message header
+                                        body
+                                        thumb
+                                        reactions
+                                        comments-count)
+                  'file-id (oref file id)))))
+
+(defmethod slack-buffer-insert ((this slack-file-info-buffer))
+  (delete-region (point-min) lui-output-marker)
+  (with-slots (file team) this
+    (let ((lui-time-stamp-position nil))
+      (lui-insert "" t))
+
+    (lui-insert-with-text-properties
+     (slack-buffer-file-to-string this)
+     ;; saved-text-properties not working??
+     'file-id (oref file id)
+     'ts (slack-ts file))
+
+    (lui-insert "" t)
+
+    (let ((comments (slack-file-comments-to-string file team)))
+      (mapc #'(lambda (comment)
+                (lui-insert-with-text-properties
+                 (slack-message-to-string comment team)
+                 'file-comment-id (oref comment id)
+                 'ts (slack-ts comment))
+                (lui-insert "" t))
+            (oref file comments)))))
+
+(defmethod slack-buffer-send-message ((this slack-file-info-buffer) message)
+  (with-slots (file team) this
+    (slack-file-comment-add-request (oref file id) message team)))
+
+(defmethod slack-buffer-display-message-compose-buffer ((this slack-file-info-buffer))
+  (with-slots (file team) this
+    (let ((buffer (slack-create-file-comment-compose-buffer file team)))
+      (slack-buffer-display buffer))))
+
+(defmethod slack-buffer-add-reaction-to-message
+  ((this slack-file-info-buffer) reaction _ts)
+  (with-slots (file team) this
+    (slack-file-add-reaction (oref file id) reaction team)))
+
+(defmethod slack-buffer-add-reaction-to-file-comment
+  ((this slack-file-info-buffer) reaction id)
+  (with-slots (team) this
+    (slack-file-comment-add-reaction id reaction team)))
+
+(defmethod slack-buffer-remove-reaction-from-message
+  ((this slack-file-info-buffer) _ts &optional file-comment-id)
+  (with-slots (file team) this
+    (if file-comment-id
+        (slack-file-comment-remove-reaction file-comment-id
+                                            (oref file id)
+                                            team)
+      (slack-file-remove-reaction (oref file id) team))))
+
+(defmethod slack-buffer-add-star ((this slack-file-info-buffer) _ts)
+  (let ((url slack-message-stars-add-url)
+        (file-comment-id (slack-get-file-comment-id)))
+    (with-slots (file team) this
+      (if file-comment-id
+          (slack-with-file-comment file-comment-id file
+            (slack-message-star-api-request
+             url
+             (list (slack-message-star-api-params file-comment))
+             team))
+        (slack-message-star-api-request url
+                                        (list (slack-message-star-api-params file))
+                                        team)))))
+
+(defmethod slack-buffer-remove-star ((this slack-file-info-buffer) _ts)
+  (let ((url slack-message-stars-remove-url)
+        (file-comment-id (slack-get-file-comment-id)))
+    (with-slots (file team) this
+      (if file-comment-id
+          (slack-with-file-comment file-comment-id file
+            (slack-message-star-api-request url
+                                            (list (slack-message-star-api-params
+                                                   file-comment))
+                                            team))
+        (slack-message-star-api-request url
+                                        (list (slack-message-star-api-params
+                                               file))
+                                        team)))))
+
+(defmethod slack-buffer-display-edit-message-buffer ((this slack-file-info-buffer) _ts)
+  (with-slots (file team) this
+    (slack-if-let* ((file-comment-id (slack-get-file-comment-id)))
+        (let ((buf (slack-create-edit-file-comment-buffer
+                    file
+                    (slack-get-file-comment-id)
+                    team)))
+          (slack-buffer-display buf)))))
+
+(defmethod slack-buffer-delete-message ((this slack-file-info-buffer) _ts)
+  (with-slots (file team) this
+    (slack-if-let* ((file-comment-id (slack-get-file-comment-id)))
+        (if (yes-or-no-p "Are you sure want to delete this comment?")
+            (slack-with-file-comment file-comment-id file
+              (slack-file-comment-delete-request (oref file id)
+                                                 file-comment-id
+                                                 team))
+          (message "Canceled")))))
+
+(defmethod slack-buffer--replace ((this slack-file-info-buffer) _ts)
+  (slack-if-let* ((buffer (get-buffer (slack-buffer-name this))))
+      (with-current-buffer buffer
+        (let ((inhibit-read-only t))
+          (slack-buffer-insert this)))))
+
+(defmethod slack-buffer-update ((this slack-file-info-buffer)
+                                &optional file-comment-id)
+  (with-slots (file team) this
+    (let ((buffer (get-buffer (slack-buffer-name this))))
+      (with-current-buffer buffer
+        (if file-comment-id
+            (let* ((comment (slack-find-file-comment file file-comment-id)))
+              (cl-labels
+                  ((pred () (let ((id (get-text-property (point) 'file-comment-id)))
+                              (equal id file-comment-id))))
+                (if comment
+                    (lui-replace (slack-message-to-string comment team) #'pred)
+                  (lui-delete #'pred))))
+          (lui-replace
+           (slack-buffer-file-to-string this)
+           #'(lambda () (let ((id (get-text-property (point) 'file-id)))
+                          (equal id (oref file id))))))))))
+
+(defmethod slack-buffer-insert-file-comment ((this slack-file-info-buffer) comment-id)
+  (with-slots (file team) this
+    (let ((buffer (get-buffer (slack-buffer-name this)))
+          (comment (slack-find-file-comment file comment-id)))
+      (with-current-buffer buffer
+        (lui-insert-with-text-properties
+         (slack-message-to-string comment team)
+         'file-comment-id (oref comment id)
+         'ts (slack-ts comment))))))
+
+(provide 'slack-file-info-buffer)
+;;; slack-file-info-buffer.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-file-info-buffer.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-file-info-buffer.elc
new file mode 100644
index 0000000000..df8eef0f4b
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-file-info-buffer.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-file-list-buffer.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-file-list-buffer.el
new file mode 100644
index 0000000000..596bf7ef65
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-file-list-buffer.el
@@ -0,0 +1,56 @@
+;;; slack-file-list-buffer.el ---                    -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2017  南優也
+
+;; Author: 南優也 <yuyaminami@minamiyuuya-no-MacBook.local>
+;; Keywords:
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'eieio)
+(require 'slack-util)
+(require 'slack-room-buffer)
+
+(define-derived-mode slack-file-list-buffer-mode slack-buffer-mode "Slack File List Buffer")
+
+(defclass slack-file-list-buffer (slack-message-buffer) ())
+
+(defmethod slack-buffer-name ((_this slack-file-list-buffer))
+  (format "%s" (call-next-method)))
+
+(defmethod slack-buffer-major-mode ((this slack-file-list-buffer))
+  'slack-file-list-buffer-mode)
+
+(defmethod slack-create-message-buffer ((room slack-file-room) team)
+  (slack-if-let* ((buffer (slack-buffer-find 'slack-file-list-buffer
+                                             room
+                                             team)))
+      buffer
+    (slack-file-list-buffer :room room :team team)))
+
+(cl-defmethod slack-buffer-update ((this slack-file-list-buffer) message &key replace)
+  (with-slots (room team) this
+    (let ((buffer (get-buffer (slack-buffer-name this))))
+      (if replace (slack-buffer-replace this message)
+        (with-current-buffer buffer
+          (slack-buffer-insert this message))))))
+
+(provide 'slack-file-list-buffer)
+;;; slack-file-list-buffer.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-file-list-buffer.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-file-list-buffer.elc
new file mode 100644
index 0000000000..626b592c2d
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-file-list-buffer.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-file-share-message.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-file-share-message.el
new file mode 100644
index 0000000000..931601d16c
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-file-share-message.el
@@ -0,0 +1,118 @@
+;;; slack-file-share-message.el ---                  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2017  南優也
+
+;; Author: 南優也 <yuyaminami@minamiyuuya-no-MacBook.local>
+;; Keywords:
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+(require 'eieio)
+(require 'slack-util)
+(require 'slack-team)
+(require 'slack-message)
+
+(defclass slack-file-share-message (slack-file-message)
+  ((upload :initarg :upload)
+   (user :initarg :user :initform nil)))
+
+
+(defmethod slack-message-image-to-string ((m slack-file-share-message))
+  (slack-image-string (slack-file-thumb-image-spec (oref m file))))
+
+(defmethod slack-team-display-image-inlinep ((m slack-file-share-message) team)
+  (slack-team-display-image-inlinep (oref m file) team))
+
+(defmethod slack-message-to-string ((m slack-file-share-message) team)
+  (cl-labels
+      ((redisplay () (slack-message-redisplay m (slack-room-find (oref m channel) team))))
+    (let* ((header (slack-message-header-to-string m team))
+           (attachment-body (slack-message-attachment-body m team))
+           (body (slack-file-summary (oref m file) (slack-ts m) team))
+           (thumb (slack-message-image-to-string m))
+           (reactions (slack-message-reaction-to-string m team))
+           (thread (slack-thread-to-string m team))
+           (initial-comment (slack-if-let* ((initial-comment
+                                             (oref (oref m file) initial-comment)))
+                                (propertize
+                                 (format "\n“ %s%s"
+                                         (slack-message-body initial-comment team)
+                                         (let ((str (slack-message-reaction-to-string
+                                                     initial-comment
+                                                     team)))
+                                           (if (slack-string-blankp str)
+                                               ""
+                                             (format "\n%s" str))))
+                                 'file-comment-id (oref initial-comment id))
+                              "")))
+      (slack-format-message header body attachment-body
+                            thumb reactions initial-comment thread))))
+
+(defun slack-get-file-comment-id ()
+  (get-text-property 0 'file-comment-id (thing-at-point 'line)))
+
+(defmethod slack-message-get-param-for-reaction ((m slack-file-share-message))
+  (slack-if-let* ((file-comment-id (slack-get-file-comment-id)))
+      (cons "file_comment" file-comment-id)
+    (cons "file" (oref (oref m file) id))))
+
+(defmethod slack-message-star-added ((m slack-file-share-message))
+  (slack-message-star-added (oref m file)))
+
+(defmethod slack-message-star-removed ((m slack-file-share-message))
+  (slack-message-star-removed (oref m file)))
+
+(defmethod slack-message-star-api-params ((m slack-file-share-message))
+  (slack-message-star-api-params (oref m file)))
+
+(defmethod slack-reaction-find ((this slack-file-share-message) reaction)
+  (slack-reaction-find (oref this file) reaction))
+
+(defmethod slack-reaction-delete ((this slack-file-share-message) reaction)
+  (slack-reaction-delete (oref this file) reaction))
+
+(defmethod slack-reaction-push ((this slack-file-share-message) reaction)
+  (slack-reaction-push (oref this file) reaction))
+
+(defmethod slack-message-append-reaction ((m slack-file-share-message) reaction
+                                          &optional type)
+  (if (string= type "file_comment")
+      (slack-if-let* ((old-reaction (slack-reaction-find (oref (oref m file) initial-comment)
+                                                         reaction)))
+          (slack-reaction-join old-reaction reaction)
+        (slack-reaction-push (oref (oref m file) initial-comment) reaction))
+    (slack-if-let* ((old-reaction (slack-reaction-find m reaction)))
+        (slack-reaction-join old-reaction reaction)
+      (slack-reaction-push m reaction))))
+
+(defmethod slack-message-pop-reaction ((m slack-file-share-message) reaction
+                                       &optional type)
+  (if (string= type "file_comment")
+      (slack-message--pop-reaction (oref (oref m file) initial-comment)
+                                   reaction)
+    (slack-message--pop-reaction m reaction)))
+
+(defmethod slack-message-changed--copy ((this slack-file-share-message) other)
+  (let ((changed (call-next-method)))
+    (let ((new-file (oref other file)))
+      (oset this file new-file))
+    changed))
+
+(provide 'slack-file-share-message)
+;;; slack-file-share-message.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-file-share-message.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-file-share-message.elc
new file mode 100644
index 0000000000..8b7328fb21
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-file-share-message.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-file.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-file.el
new file mode 100644
index 0000000000..bf57856084
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-file.el
@@ -0,0 +1,779 @@
+;;; slack-file.el ---  handle files                  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2016  南優也
+
+;; Author: 南優也 <yuyaminami@minamiyuunari-no-MacBook-Pro.local>
+;; Keywords:
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'eieio)
+(require 'slack-util)
+(require 'slack-room)
+(require 'slack-request)
+
+(defconst slack-file-history-url "https://slack.com/api/files.list")
+(defconst slack-file-list-url "https://slack.com/api/files.list")
+(defconst slack-file-upload-url "https://slack.com/api/files.upload")
+(defconst slack-file-delete-url "https://slack.com/api/files.delete")
+(defconst slack-file-comment-delete-url "https://slack.com/api/files.comments.delete")
+
+(defclass slack-file (slack-message)
+  ((id :initarg :id)
+   (created :initarg :created)
+   (name :initarg :name)
+   (size :initarg :size)
+   (public :initarg :public)
+   (filetype :initarg :filetype)
+   (user :initarg :user)
+   (preview :initarg :preview)
+   (initial-comment :initarg :initial_comment :initform nil)
+   (permalink :initarg :permalink)
+   (channels :initarg :channels :type list)
+   (groups :initarg :groups :type list)
+   (ims :initarg :ims :type list)
+   (username :initarg :username)
+   (comments-count :initarg :comments_count)
+   (comments :initarg :comments :initform nil)
+   (page :initarg :page :initform 1)
+   (pages :initarg :pages :initform nil)
+   (thumb-64 :initarg :thumb_64 :initform nil)
+   (thumb-80 :initarg :thumb_80 :initform nil)
+   (thumb-360 :initarg :thumb_360 :initform nil)
+   (thumb-360-w :initarg :thumb_360_w :initform nil)
+   (thumb-360-h :initarg :thumb_360_h :initform nil)
+   (thumb-160 :initarg :thumb_160 :initform nil)
+   (thumb-pdf :initarg :thumb_pdf :initform nil)
+   (thumb-pdf-w :initarg :thumb_pdf_w :initform nil)
+   (thumb-pdf-h :initarg :thumb_pdf_h :initform nil)
+   (original-w :initarg :original_w :initform nil)
+   (original-h :initarg :original_h :initform nil)
+   (is-starred :initarg :is_starred :initform nil)
+   (mimetype :initarg :mimetype :type string :initform "")
+   (title :initarg :title :type (or null string) :initform nil)
+   (pretty-type :initarg :pretty_type :type (or null string) :initform nil)
+   (is-public :initarg :is_public :initform nil)
+   (url :initarg :url :initform "" :type string)
+   (url-download :initarg :url_download :initform "" :type string)
+   (url-private :initarg :url_private :initform "" :type string)
+   (url-private-download :initarg :url_private_download :initform "" :type string)
+   ))
+
+(defclass slack-file-email (slack-file)
+  ((from :initarg :from :type (or null list) :initform nil)
+   (to :initarg :to :type (or null list) :initform nil)
+   ;; TODO verify type
+   (cc :initarg :cc :type (or null list) :initform nil)
+   (subject :initarg :subject :type string)
+   (plain-text :initarg :plain_text :type string)
+   (preview-plain-text :initarg :preview_plain_text :type string)
+   (is-expanded :initform nil :type boolean)))
+
+(defclass slack-file-email-from ()
+  ((address :initarg :address :type string)
+   (name :initarg :name :type string)
+   (original :initarg :original :type string)))
+
+(defclass slack-file-email-to (slack-file-email-from) ())
+(defclass slack-file-email-cc (slack-file-email-from) ())
+
+(defmethod slack-merge ((old slack-reaction) new)
+  (with-slots (count users) old
+    (setq count (oref new count))
+    (setq users (cl-remove-duplicates (append users (oref new users))
+                                      :test #'string=))))
+
+(defmethod slack-merge ((old string) _new) old)
+(defmethod slack-equalp ((old string) new) (string= old new))
+
+(defmethod slack-merge ((old slack-file) new)
+  (cl-labels
+      ((slack-merge-string-list
+        (new old)
+        (cl-remove-duplicates (append new old) :test #'string=)))
+
+    (slack-merge-list (oref old reactions) (oref new reactions))
+    (slack-merge-list (oref old comments) (oref new comments))
+    (slack-merge-list (oref old channels) (oref new channels))
+    (slack-merge-list (oref old groups) (oref new groups))
+    (slack-merge-list (oref old ims) (oref new ims))
+    (with-slots (comments-count initial-comment) old
+      (setq comments-count (oref new comments-count))
+      (setq initial-comment (oref new initial-comment)))))
+
+(defmethod slack-file-set-channel ((f slack-file) id)
+  (cond
+   ((string-prefix-p "G" id)
+    (oset f groups (list id)))
+   ((string-prefix-p "C" id)
+    (oset f channels (list id)))
+   ((string-prefix-p "D" id)
+    (oset f ims (list id)))))
+
+(defclass slack-file-room (slack-room) ())
+
+(defun slack-file-find (id team)
+  (let ((files (oref (slack-file-room-obj team) messages)))
+    (cl-find-if #'(lambda (file) (string= (oref file id) id))
+                files)))
+
+(defun slack-file-room-obj (team)
+  (with-slots (file-room) team
+    (if file-room
+        file-room
+      (setq file-room (slack-file-room "file-room"
+                                       :name "Files"
+                                       :id "F"
+                                       :team-id (oref team id)
+                                       :created (format-time-string "%s")
+                                       :latest nil
+                                       :unread_count 0
+                                       :unread_count_display 0
+                                       :messages '())))))
+
+(defun slack-file-comment-create (payload file-id)
+  (let* ((reactions (mapcar #'slack-reaction-create
+                            (append (plist-get payload :reactions) nil)))
+         (comment (apply #'make-instance
+                         'slack-file-comment
+                         (slack-collect-slots 'slack-file-comment
+                                              (plist-put payload
+                                                         :reactions
+                                                         reactions)))))
+    (oset comment file-id file-id)
+    (oset comment reactions reactions)
+    comment))
+
+(defun slack-file-create-email-from (payload &optional type)
+  (and payload
+       (make-instance (or (and (eq type 'to) 'slack-file-email-to)
+                          (and (eq type 'cc) 'slack-file-email-cc)
+                          'slack-file-email-from)
+                      :original (plist-get payload :original)
+                      :name (plist-get payload :name)
+                      :address (plist-get payload :address))))
+
+(defun slack-file-create (payload)
+  (setq payload (append payload nil))
+  (plist-put payload :channels (append (plist-get payload :channels) nil))
+  (plist-put payload :groups (append (plist-get payload :groups) nil))
+  (plist-put payload :ims (append (plist-get payload :ims) nil))
+  (plist-put payload :reactions (append (plist-get payload :reactions) nil))
+  (plist-put payload :pinned_to (append (plist-get payload :pinned_to) nil))
+  (plist-put payload :ts (number-to-string (plist-get payload :timestamp)))
+  (plist-put payload :channel "F")
+  (let* ((file (if (string= "email" (plist-get payload :filetype))
+                   (progn
+                     (plist-put payload :from
+                                (mapcar #'slack-file-create-email-from
+                                        (plist-get payload :from)))
+                     (plist-put payload :to
+                                (mapcar #'(lambda (e)
+                                            (slack-file-create-email-from e 'to))
+                                        (plist-get payload :to)))
+                     (plist-put payload :cc
+                                (mapcar #'(lambda (e)
+                                            (slack-file-create-email-from e 'cc))
+                                        (plist-get payload :cc)))
+                     (apply #'slack-file-email "file-email"
+                            (slack-collect-slots 'slack-file-email
+                                                 payload)))
+
+                 (apply #'slack-file "file"
+                        (slack-collect-slots 'slack-file payload))))
+         (initial-comment (if (plist-get payload :initial_comment)
+                              (slack-file-comment-create (plist-get payload :initial_comment)
+                                                         (oref file id))
+                            nil))
+         (comments (mapcar #'(lambda (e) (slack-file-comment-create e (oref file id)))
+                           (plist-get payload :comments))))
+    (oset file reactions
+          (mapcar #'slack-reaction-create (plist-get payload :reactions)))
+    (oset file comments comments)
+    (oset file initial-comment initial-comment)
+    file))
+
+(defmethod slack-message-equal ((f slack-file) other)
+  (string= (oref f id) (oref other id)))
+
+(defmethod slack-equalp ((old slack-file) new)
+  (string= (oref old id) (oref new id)))
+
+(defmethod slack-file-pushnew ((f slack-file) team)
+  (let ((room (slack-file-room-obj team)))
+    (slack-merge-list (oref room messages) (list f))
+    (oset room messages (slack-room-sort-messages (oref room messages)))
+    (slack-room-update-latest room (car (last (oref room messages))))))
+
+(defmethod slack-message-body ((file slack-file) team)
+  (with-slots (initial-comment) file
+    (let ((body (plist-get initial-comment :comment)))
+      (slack-message-unescape-string body team))))
+
+(defun slack-file-more-comments-string (file)
+  (let ((count (oref file comments-count))
+        (page (oref file page))
+        (comments (oref file comments)))
+    (propertize (format "%s more comments" (- count 1))
+                'face '(:underline t)
+                'page page
+                'file (oref file id)
+                'keymap (let ((map (make-sparse-keymap)))
+                          (define-key map (kbd "RET")
+                            #'slack-file-update)
+                          map))))
+
+(defconst slack-file-info-url "https://slack.com/api/files.info")
+
+(defun slack-file-update ()
+  (interactive)
+  (slack-if-let* ((buf slack-current-buffer))
+      (with-slots (file team) buf
+        (slack-if-let* ((page (oref file page)))
+            (slack-file-request-info
+             file page team
+             #'(lambda (file team)
+                 (slack-redisplay file team)))))))
+
+(defun slack-file-request-info (file-id page team &optional after-success)
+  (cl-labels
+      ((on-file-info (&key data &allow-other-keys)
+                     (slack-request-handle-error
+                      (data "slack-file-info"))
+                     (let* ((paging (plist-get data :paging))
+                            (comments (plist-get data :comments))
+                            (file (slack-file-create (plist-put (plist-get data :file)
+                                                                :comments comments))))
+                       (slack-file-pushnew file team)
+                       (if after-success
+                           (funcall after-success file team)))))
+    (slack-request
+     (slack-request-create
+      slack-file-info-url
+      team
+      :params (list (cons "file" file-id)
+                    (cons "page" (number-to-string page)))
+      :success #'on-file-info))))
+
+(defmethod slack-file-comments-count-to-string ((this slack-file))
+  (format "%s comment%s"
+          (oref this comments-count)
+          (if (< 1 (oref this comments-count))
+              "s" "")))
+
+(defmethod slack-file-gdoc-p ((this slack-file))
+  (string= (oref this filetype) "gdoc"))
+
+(defmethod slack-file-gdoc-to-string ((this slack-file))
+  (with-slots (pretty-type name title url-private permalink) this
+    (let ((title (propertize (format "<%s|%s>" permalink (or title name))
+                             'face '(:weight bold)))
+          (description (format "<%s|%s>" url-private pretty-type)))
+      (slack-format-message title description))))
+
+(defmethod slack-message-body-to-string ((file slack-file) team)
+  (cond
+   ((slack-file-gdoc-p file) (slack-file-gdoc-to-string file))
+   (t (with-slots (name title size filetype permalink) file
+        (slack-message-put-text-property
+         (format "name: %s\nsize: %s\ntype: %s\n%s\n"
+                 (or title name) size filetype permalink))))))
+
+(defmethod slack-file-comments-to-string ((file slack-file) team)
+  (with-slots (comments) file
+    (and (< 0 (length comments))
+         (format "\n%s"
+                 (mapconcat #'(lambda (e)
+                                (slack-message-to-string e team))
+                            comments "\n")))))
+
+(defmethod slack-file-initial-comment-to-string ((file slack-file) team)
+  (with-slots (initial-comment) file
+    (and initial-comment
+         (format "comment:\n%s"
+                 (slack-message-to-string initial-comment team )))))
+
+;; (defmethod slack-file-comments-count-to-string ((file slack-file))
+;;   (with-slots (comments-count comments) file
+;;     (if (> comments-count (length comments))
+;;         (slack-file-more-comments-string file)
+;;       "")))
+
+(defmethod slack-team-display-image-inlinep ((_file slack-file) team)
+  (slack-team-display-file-image-inlinep team))
+
+(defmethod slack-message-image-to-string ((file slack-file))
+  (slack-image-string (slack-file-thumb-image-spec file)))
+
+(defmethod slack-file-image-p ((this slack-file))
+  (string= (car (split-string (oref this mimetype) "/"))
+           "image"))
+
+(defmethod slack-message-large-image-to-string ((file slack-file))
+  (slack-image-string (slack-file-image-spec file)))
+
+(defmethod slack-message-to-string ((this slack-file-email) team)
+  (with-slots (preview-plain-text from subject) this
+    (slack-format-message (slack-message-header-to-string this team)
+                          (format "Subject: %s" subject)
+                          (format "From: %s" (mapconcat #'identity
+                                                        (mapcar #'(lambda (e) (oref e original))
+                                                                from)
+                                                        ", "))
+                          (propertize preview-plain-text
+                                      'slack-defer-face #'slack-put-preview-overlay)
+                          (slack-file-comments-count-to-string this)
+                          (slack-message-reaction-to-string this team)
+                          (slack-file-link-info (oref this id) "\n(more info)"))))
+
+(defmethod slack-message-to-string ((file slack-file) team)
+  (with-slots (title name pretty-type mimetype) file
+    (slack-format-message (slack-message-header-to-string file team)
+                          (format "%s%s"
+                                  (or title name)
+                                  (or (and pretty-type
+                                           (format ": %s" pretty-type))
+                                      (format ": %s" mimetype)))
+                          (slack-file-comments-count-to-string file)
+                          (slack-message-image-to-string file)
+                          (slack-message-reaction-to-string file team)
+                          (slack-file-link-info (oref file id) "\n(more info)"))))
+
+(defun slack-file-list ()
+  (interactive)
+  (let* ((team (slack-team-select))
+         (room (slack-file-room-obj team)))
+    (slack-room-display room team)))
+
+(cl-defmethod slack-room-history-request ((room slack-file-room) team &key oldest after-success async)
+  (cl-labels
+      ((on-file-list
+        (&key data &allow-other-keys)
+        (slack-request-handle-error
+         (data "slack-file-list")
+         (let ((files (cl-loop for e in (plist-get data :files)
+                               collect (slack-file-create e))))
+           (if oldest
+               (slack-room-set-prev-messages room files)
+             (slack-room-set-messages room files)))
+         (if after-success
+             (funcall after-success)))))
+    (slack-request
+     (slack-request-create
+      slack-file-list-url
+      team
+      :params (list (if oldest
+                        (cons "ts_to" oldest)))
+      :success #'on-file-list))))
+
+(defun slack-file-upload ()
+  (interactive)
+  (cl-labels
+      ((on-file-upload (&key data &allow-other-keys)
+                       (slack-request-handle-error
+                        (data "slack-file-upload")))
+       (select-channels (channels acc)
+                        (let ((selected (apply slack-completing-read-function
+                                               (if acc
+                                                   (list "Select another channel (or leave empty): "
+                                                         (cons "" channels) nil t)
+                                                 (list "Select channel: " channels nil t)))))
+                          (if (< 0 (length selected))
+                              (select-channels (cl-remove-if (lambda (x) (equal selected (car-safe x))) channels)
+                                               (cons selected acc))
+                            acc)))
+       (channel-id (selected channels)
+                   (oref (cdr (cl-assoc selected channels :test #'string=))
+                         id)))
+    (let* ((team (slack-team-select))
+           (channels (slack-room-names
+                      (append (oref team ims)
+                              (oref team channels)
+                              (oref team groups))))
+           (target-channels (select-channels channels '()))
+           (channel-ids (mapconcat #'(lambda (selected)
+                                       (channel-id selected channels))
+                                   (cl-delete-if #'null target-channels)
+                                   ","))
+           (buf (find-file-noselect
+                 (car (find-file-read-args
+                       "Select File: "
+                       (confirm-nonexistent-file-or-buffer)))
+                 t t))
+           (filename (read-from-minibuffer "Filename: "
+                                           (file-name-nondirectory
+                                            (buffer-file-name buf))))
+           (filetype (read-from-minibuffer "Filetype: "
+                                           (file-name-extension
+                                            (buffer-file-name buf))))
+           (initial-comment (read-from-minibuffer "Message: ")))
+      (slack-request
+       (slack-request-create
+        slack-file-upload-url
+        team
+        :type "POST"
+        :params (list (cons "filename" filename)
+                      (cons "channels" channel-ids)
+                      (cons "filetype" filetype)
+                      (if initial-comment
+                          (cons "initial_comment" initial-comment)))
+        :files (list (cons "file" buf))
+        :headers (list (cons "Content-Type" "multipart/form-data"))
+        :success #'on-file-upload)))))
+
+(defun slack-file-delete ()
+  (interactive)
+  (cl-labels
+      ((on-file-delete (&key data &allow-other-keys)
+                       (slack-request-handle-error
+                        (data "slack-file-delete"))))
+    (let* ((team (slack-team-select))
+           (files (oref (slack-file-room-obj team) messages))
+           (your-files (cl-remove-if #'(lambda (f)
+                                         (not (string= (oref f user)
+                                                       (oref team self-id))))
+                                     files))
+           (candidates (mapcar #'(lambda (f)
+                                   (cons (concat
+                                          (slack-message-time-to-string (oref f ts))
+                                          " "
+                                          (oref f (or title name)))
+                                         f))
+                               your-files))
+           (selected (funcall slack-completing-read-function "Select File: " candidates))
+           (deleting-file (cdr (cl-assoc selected candidates :test #'string=))))
+      (slack-request
+       (slack-request-create
+        slack-file-delete-url
+        team
+        :params (list (cons "file" (oref deleting-file id)))
+        :success #'on-file-delete)))))
+
+(defconst slack-file-comment-add-url "https://slack.com/api/files.comments.add")
+
+(defmethod slack-file-id ((m slack-file-message))
+  (slack-file-id (oref m file)))
+
+(defmethod slack-file-id ((file slack-file))
+  (oref file id))
+
+(defmethod slack-file-channel ((m slack-file-message))
+  (oref m channel))
+
+(defmethod slack-file-channel ((_file slack-file))
+  nil)
+
+(defmethod slack-file-comment-id ((m slack-file-message))
+  (slack-file-comment-id (oref m comment)))
+
+(defmethod slack-file-comment-id ((file-comment))
+  (oref file-comment id))
+
+(defun slack-file-comment-add-request (id comment team
+                                          &optional channel after-success)
+  (cl-labels
+      ((on-file-comment-add (&key data &allow-other-keys)
+                            (slack-request-handle-error
+                             (data "slack-file-comment-add")
+                             (when after-success
+                               (funcall after-success)))))
+    (slack-request
+     (slack-request-create
+      slack-file-comment-add-url
+      team
+      :params (list (cons "file" id)
+                    (cons "comment" (slack-message-prepare-links
+                                     (slack-escape-message comment)
+                                     team))
+                    (if channel
+                        (cons "channel" channel)))
+      :success #'on-file-comment-add))))
+
+(defun slack-file-comment-delete-request (file-id file-comment-id team)
+  (cl-labels
+      ((on-file-comment-delete (&key data &allow-other-keys)
+                               (slack-request-handle-error
+                                (data "slack-file-comment-delete"))))
+    (slack-request
+     (slack-request-create
+      slack-file-comment-delete-url
+      team
+      :params (list (cons "id" file-comment-id)
+                    (cons "file" file-id))
+      :success #'on-file-comment-delete))))
+
+(defconst slack-file-comment-edit-url "https://slack.com/api/files.comments.edit")
+
+(defun slack-file-comment--edit (room-id team-id ts comment)
+  (let* ((team (slack-team-find team-id))
+         (room (slack-room-find room-id team))
+         (message (slack-room-find-message room ts))
+         (file-id (slack-file-id message))
+         (comment-id (slack-file-comment-id message)))
+    (slack-file-comment-edit-request file-id
+                                     comment-id
+                                     comment
+                                     team)))
+
+(defun slack-file-comment-edit-request (file-id file-comment-id comment team)
+  (cl-labels
+      ((on-file-comment-edit (&key data &allow-other-keys)
+                             (slack-request-handle-error
+                              (data "slack-file-comment-edit-request"))))
+    (slack-request
+     (slack-request-create
+      slack-file-comment-edit-url
+      team
+      :params (list (cons "id" file-comment-id)
+                    (cons "file" file-id)
+                    (cons "comment" (slack-message-prepare-links
+                                     (slack-escape-message comment)
+                                     team)))
+      :success #'on-file-comment-edit))))
+
+
+(defmethod slack-file-thumb-image-spec ((file slack-file))
+  (with-slots (thumb-360 thumb-360-w thumb-360-h thumb-160 thumb-80 thumb-64 thumb-pdf thumb-pdf-w thumb-pdf-h) file
+    (or (and thumb-360 (list thumb-360 thumb-360-w thumb-360-h))
+        (and thumb-160 (list thumb-160 nil nil))
+        (and thumb-80 (list thumb-80 nil nil))
+        (and thumb-64 (list thumb-64 nil nil))
+        (and thumb-pdf (list thumb-pdf thumb-pdf-w thumb-pdf-h))
+        (list nil nil nil))))
+
+(defmethod slack-file-image-spec ((this slack-file))
+  (with-slots (is-public url-download url-private-download) this
+    (list url-private-download
+          nil
+          nil
+          nil
+          (floor (* 0.9 (frame-pixel-width))))))
+
+(defmethod slack-file-channel-ids ((file slack-file))
+  (append (oref file channels)
+          (oref file ims)
+          (oref file groups)))
+
+(defun slack-file-link-info (file-id text)
+  (propertize text
+              'file file-id
+              'face '(:underline t :weight bold)
+              'keymap (let ((map (make-sparse-keymap)))
+                        (define-key map (kbd "RET")
+                          #'slack-file-display)
+                        map)))
+
+(defmethod slack-file-summary ((file slack-file) _ts team)
+  (with-slots (initial-comment pretty-type mimetype permalink name title) file
+    (format "uploaded%s this %s: %s <%s|open in browser>"
+            (if initial-comment
+                " and commented on"
+              "")
+            (or pretty-type mimetype)
+            (slack-file-link-info (oref file id)
+                                  (slack-message-unescape-string (or title name)
+                                                                 team))
+            permalink)))
+
+(defmethod slack-file-summary ((this slack-file-email) ts team)
+  (with-slots (preview-plain-text plain-text is-expanded) this
+    (let* ((has-more (< (length preview-plain-text)
+                        (length plain-text)))
+           (body (slack-message-unescape-string
+                  (or (and is-expanded plain-text)
+                      (or (and has-more (format "%s…" preview-plain-text))
+                          preview-plain-text))
+                  team)))
+      (format "%s\n\n%s\n\n%s"
+              (call-next-method)
+              (propertize body
+                          'slack-defer-face #'slack-put-preview-overlay)
+              (propertize (or (and is-expanded "Collapse ↑")
+                              "+ Click to expand inline")
+                          'face '(:underline t)
+                          'keymap (let ((map (make-sparse-keymap)))
+                                    (define-key map (kbd "RET")
+                                      #'(lambda ()
+                                          (interactive)
+                                          (slack-buffer-toggle-email-expand
+                                           slack-current-buffer
+                                           ts)))
+                                    map))))))
+
+(defmethod slack-file-update-comment ((file slack-file) comment team
+                                      &optional edited-at)
+  (when (oref comment is-intro)
+    (oset file initial-comment comment))
+  (slack-merge-list (oref file comments) (list comment))
+  ;; (cl-loop for channel in (slack-file-channel-ids file)
+  ;;          do (let* ((room (slack-room-find channel team))
+  ;;                    (message (if (oref comment is-intro)
+  ;;                                 (slack-room-find-file-share-message
+  ;;                                  room (oref file id))
+  ;;                               (slack-room-find-file-comment-message
+  ;;                                room (oref comment id)))))
+  ;;               (when message
+  ;;                 (oset message file file)
+  ;;                 (oset message edited-at edited-at)
+  ;;                 (if (oref comment is-intro)
+  ;;                     (oset message text (slack-file-summary file))
+  ;;                   (oset message comment comment))
+  ;;                 (slack-message-update message team t))))
+  )
+
+(defmethod slack-reaction-find ((this slack-file) reaction)
+  (slack-reaction--find (oref this reactions) reaction))
+
+(defmethod slack-reaction-delete ((this slack-file) reaction)
+  (oset this reactions
+        (slack-reaction--delete (oref this reactions) reaction)))
+
+(defmethod slack-reaction-push ((this slack-file) reaction)
+  (push reaction (oref this reactions)))
+
+(defmethod slack-message-reactions ((this slack-file))
+  (oref this reactions))
+
+(defmethod slack-reaction-find ((this slack-file) reaction)
+  (slack-reaction--find (oref this reactions) reaction))
+
+(defun slack-reorder-comments (comments)
+  (cl-remove-duplicates (cl-sort comments
+                                 #'<
+                                 :key #'(lambda (e) (oref e timestamp)))
+                        :test #'string= :key #'(lambda (e) (oref e id))))
+
+(defmacro slack-with-file (id team &rest body)
+  (declare (indent 2) (debug t))
+  `(cl-loop for file in (oref (slack-file-room-obj ,team) messages)
+            do (when (string= (oref file id) ,id)
+                 ,@body)))
+
+(defmethod slack-add-comment ((this slack-file) comment)
+  (with-slots (comments comments-count) this
+    (setq comments (slack-reorder-comments (cons comment comments)))
+    (cl-incf comments-count)))
+
+(defmethod slack-delete-comment ((this slack-file) comment-id)
+  (with-slots (comments comments-count) this
+    (setq comments (slack-reorder-comments (cl-remove-if #'(lambda (e) (string= comment-id (oref e id)))
+                                                         comments)))
+    (cl-decf comments-count)))
+
+(defmethod slack-room-buffer-name ((this slack-file))
+  (with-slots (name) this
+    (format "*Slack File - %s*" name)))
+
+(define-derived-mode slack-file-info-mode lui-mode "Slack File Info"
+  ""
+  (setq-local default-directory slack-default-directory)
+  (lui-set-prompt (format "Add Comment %s" lui-prompt-string))
+  (setq lui-input-function 'slack-file-comment--add))
+
+(defun slack-file-comment--add (message)
+  (slack-if-let* ((buf slack-current-buffer))
+      (slack-buffer-send-message buf message)))
+
+(defun slack-file-display ()
+  (interactive)
+  (let ((id (get-text-property (- (point) (line-beginning-position)) 'file (thing-at-point 'line))))
+    (slack-if-let* ((buf slack-current-buffer))
+        (slack-buffer-display-file buf id))))
+
+(defmethod slack-message-star-added ((this slack-file))
+  (oset this is-starred t))
+
+(defmethod slack-message-star-removed ((this slack-file))
+  (oset this is-starred nil))
+
+(defmethod slack-message-star-api-params ((this slack-file))
+  (cons "file" (oref this id)))
+
+(defun slack-file-process-star-api (url team file-id)
+  (slack-with-file file-id team
+    (slack-message-star-api-request url
+                                    (list (slack-message-star-api-params file))
+                                    team)))
+
+(defmethod slack-file-comments-loaded-p ((this slack-file))
+  (with-slots (comments comments-count) this
+    (<= comments-count (length comments))))
+
+(defmethod slack-message-body-to-string ((this slack-file-email) _team)
+  (let ((from (format "From: %s" (mapconcat #'(lambda (e) (oref e original))
+                                            (oref this from)
+                                            ", ")))
+        (to (format "To: %s" (mapconcat #'(lambda (e) (oref e original))
+                                        (oref this to)
+                                        ", ")))
+        (cc (format "CC: %s" (mapconcat #'(lambda (e) (oref e original))
+                                        (oref this cc)
+                                        ", ")))
+        (subject (format "Subject: %s" (oref this subject)))
+        (body (propertize (format "\n%s" (oref this plain-text))
+                          'slack-defer-face #'slack-put-email-body-overlay))
+        (date (format "Date: %s" (slack-message-time-to-string (oref this created)))))
+    (mapconcat #'identity
+               (list from to cc subject date body)
+               "\n")))
+
+(defun slack-redisplay (file team)
+  ;; (slack-if-let* ((buffer (slack-buffer-find 'slack-file-info-buffer file team)))
+  ;;     (slack-buffer--replace buffer nil))
+  (slack-if-let* ((buffer (slack-buffer-find 'slack-file-list-buffer
+                                             (slack-file-room-obj team)
+                                             team)))
+      (slack-buffer-replace buffer file)))
+
+(defmethod slack-find-file-comment ((this slack-file) file-comment-id)
+  (cl-find-if #'(lambda (e) (string= (oref e id) file-comment-id))
+              (cl-remove-if #'null
+                            (append (oref this comments)
+                                    (list (oref this initial-comment))))))
+
+
+(defmethod slack-message-update ((this slack-file) team &rest _args)
+  (slack-if-let* ((buffer (slack-buffer-find 'slack-file-info-buffer
+                                             this
+                                             team)))
+      (progn
+        (oset buffer file this)
+        (slack-buffer-update buffer))))
+
+(defmethod slack-file-insert-comment ((this slack-file) file-comment-id team)
+  (slack-if-let* ((buffer (slack-buffer-find 'slack-file-info-buffer
+                                             this
+                                             team)))
+      (progn
+        (oset buffer file this)
+        (slack-buffer-insert-file-comment buffer file-comment-id))))
+
+(defmethod slack-file-delete-comment ((this slack-file) file-comment-id team)
+  (slack-if-let* ((buffer (slack-buffer-find 'slack-file-info-buffer
+                                             this
+                                             team)))
+      (progn
+        (oset buffer file this)
+        (slack-buffer-update buffer file-comment-id))))
+
+(provide 'slack-file)
+;;; slack-file.el ends here
+
+;; [2017-11-11 20:58:38] (:type file_comment_added :comment (:id Fc7ZJJ8N86 :created 1510401518 :timestamp 1510401518 :user U1013370U :is_intro :json-false :comment jaja) :file_id F7YJYDFV1 :user_id U1013370U :file (:id F7YJYDFV1) :event_ts 1510401518.000012 :ts 1510401518.000012)
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-file.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-file.elc
new file mode 100644
index 0000000000..5fdc7e8bf0
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-file.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-group.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-group.el
new file mode 100644
index 0000000000..8e588c79be
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-group.el
@@ -0,0 +1,293 @@
+;;; slack-group.el --- slack private group interface  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2015  Yuya Minami
+
+;; Author: Yuya Minami
+;; Keywords:
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'eieio)
+(require 'slack-room)
+(require 'slack-util)
+(require 'slack-buffer)
+(require 'slack-request)
+
+(defconst slack-group-history-url "https://slack.com/api/groups.history")
+(defconst slack--group-open-url "https://slack.com/api/groups.open")
+(defconst slack-group-buffer-name "*Slack - Private Group*")
+(defconst slack-group-list-url "https://slack.com/api/groups.list")
+(defconst slack-group-update-mark-url "https://slack.com/api/groups.mark")
+(defconst slack-create-group-url "https://slack.com/api/groups.create")
+(defconst slack-group-rename-url "https://slack.com/api/groups.rename")
+(defconst slack-group-invite-url "https://slack.com/api/groups.invite")
+(defconst slack-group-leave-url "https://slack.com/api/groups.leave")
+(defconst slack-group-archive-url "https://slack.com/api/groups.archive")
+(defconst slack-group-unarchive-url "https://slack.com/api/groups.unarchive")
+(defconst slack-mpim-close-url "https://slack.com/api/mpim.close")
+(defconst slack-mpim-open-url "https://slack.com/api/mpim.open")
+(defconst slack-group-info-url "https://slack.com/api/groups.info")
+
+(defvar slack-buffer-function)
+
+(defclass slack-group (slack-room)
+  ((is-group :initarg :is_group :initform nil)
+   (creator :initarg :creator :initform "")
+   (is-archived :initarg :is_archived :initform nil)
+   (is-mpim :initarg :is_mpim :initform nil)
+   (members :initarg :members :type list :initform '())
+   (topic :initarg :topic :initform nil)
+   (purpose :initarg :purpose :initform nil)))
+
+(defmethod slack-merge ((this slack-group) other)
+  (call-next-method)
+  (with-slots (is-group creator is-archived is-mpim members topic purpose) this
+    (setq is-group (oref other is-group))
+    (setq creator (oref other creator))
+    (setq is-archived (oref other is-archived))
+    (setq is-mpim (oref other is-mpim))
+    (setq members (oref other members))
+    (setq topic (oref other topic))
+    (setq purpose (oref other purpose))))
+
+(defun slack-group-names (team &optional filter)
+  (with-slots (groups) team
+    (slack-room-names groups filter)))
+
+(defmethod slack-room-subscribedp ((room slack-group) team)
+  (with-slots (subscribed-channels) team
+    (let ((name (slack-room-name room)))
+      (and name
+           (memq (intern name) subscribed-channels)))))
+
+(defmethod slack-room-buffer-name ((room slack-group))
+  (concat slack-group-buffer-name
+          " : "
+          (slack-room-display-name room)))
+
+(defun slack-group-select ()
+  (interactive)
+  (let* ((team (slack-team-select))
+         (room (slack-room-select
+                (cl-loop for team in (list team)
+                         for groups = (oref team groups)
+                         nconc groups))))
+    (slack-room-display room team)))
+
+(defun slack-group-list-update (&optional team after-success)
+  (interactive)
+  (let ((team (or team (slack-team-select))))
+    (cl-labels ((on-list-update
+                 (&key data &allow-other-keys)
+                 (slack-request-handle-error
+                  (data "slack-group-list-update")
+                  (slack-merge-list (oref team groups)
+                                    (mapcar #'(lambda (g)
+                                                (slack-room-create
+                                                 g team 'slack-group))
+                                            (plist-get data :groups)))
+                  (if after-success
+                      (funcall after-success team))
+                  (mapc #'(lambda (room)
+                            (slack-room-info-request room team))
+                        (oref team groups))
+                  (slack-log "Slack Group List Updated" team :level 'info))))
+      (slack-room-list-update slack-group-list-url
+                              #'on-list-update
+                              team
+                              :sync nil))))
+
+
+(defmethod slack-room-update-mark-url ((_room slack-group))
+  slack-group-update-mark-url)
+
+(defun slack-create-group ()
+  (interactive)
+  (let ((team (slack-team-select)))
+    (cl-labels
+        ((on-create-group (&key data &allow-other-keys)
+                          (slack-request-handle-error
+                           (data "slack-create-group"))))
+      (slack-create-room slack-create-group-url
+                         team
+                         #'on-create-group))))
+
+(defun slack-group-rename ()
+  (interactive)
+  (slack-room-rename slack-group-rename-url
+                     #'slack-group-names))
+
+(defun slack-group-invite ()
+  (interactive)
+  (slack-room-invite slack-group-invite-url
+                     #'slack-group-names))
+
+(defun slack-group-leave ()
+  (interactive)
+  (let* ((team (slack-team-select))
+         (group (slack-current-room-or-select
+                 #'(lambda ()
+                     (slack-group-names team)))))
+    (cl-labels
+        ((on-group-leave
+          (&key data &allow-other-keys)
+          (slack-request-handle-error
+           (data "slack-group-leave")
+           (with-slots (groups) team
+             (setq groups
+                   (cl-delete-if #'(lambda (g)
+                                     (slack-room-equal-p group g))
+                                 groups)))
+           (message "Left Group: %s"
+                    (slack-room-display-name group)))))
+      (slack-room-request-with-id slack-group-leave-url
+                                  (oref group id)
+                                  team
+                                  #'on-group-leave))))
+
+(defmethod slack-room-archived-p ((room slack-group))
+  (oref room is-archived))
+
+(defun slack-group-archive ()
+  (interactive)
+  (let* ((team (slack-team-select))
+         (group (slack-current-room-or-select
+                 #'(lambda ()
+                     (slack-group-names
+                      team
+                      #'(lambda (groups)
+                          (cl-remove-if #'slack-room-archived-p
+                                        groups)))))))
+    (cl-labels
+        ((on-group-archive (&key data &allow-other-keys)
+                           (slack-request-handle-error
+                            (data "slack-group-archive"))))
+      (slack-room-request-with-id slack-group-archive-url
+                                  (oref group id)
+                                  team
+                                  #'on-group-archive))))
+
+(defun slack-group-unarchive ()
+  (interactive)
+  (let* ((team (slack-team-select))
+         (group (slack-current-room-or-select
+                 #'(lambda ()
+                     (slack-group-names
+                      team
+                      #'(lambda (groups)
+                          (cl-remove-if-not #'slack-room-archived-p
+                                            groups)))))))
+    (cl-labels
+        ((on-group-unarchive (&key _data &allow-other-keys)
+                             (data "slack-group-unarchive")))
+      (slack-room-request-with-id slack-group-unarchive-url
+                                  (oref group id)
+                                  team
+                                  #'on-group-unarchive))))
+
+
+(defun slack-group-members-s (group)
+  (with-slots (members team-id) group
+    (mapconcat #'(lambda (user) (slack-user-name user
+                                                 (slack-team-find team-id)))
+               members ", ")))
+
+
+(defun slack-group-mpim-open ()
+  (interactive)
+  (let* ((team (slack-team-select))
+         (users (slack-user-names team)))
+    (cl-labels
+        ((select-users (users acc)
+                       (let ((selected (funcall slack-completing-read-function "Select User: "
+                                                        users nil t)))
+                         (if (< 0 (length selected))
+                             (select-users users
+                                           (push (cdr (cl-assoc selected users :test #'string=)) acc))
+                           acc)))
+         (on-success
+          (&key data &allow-other-keys)
+          (slack-request-handle-error
+           (data "slack-group-mpim-open")
+           (if (plist-get data :already_open)
+               (message "Direct Message Channel with %s Already Open"
+                        (slack-group-members-s (slack-room-find (oref selected id) team)))
+             (oset team groups
+                   (cons (slack-room-create (plist-get data :group) team 'slack-group)
+                         (oref team groups)))))))
+      (slack-request
+       (slack-request-create
+        slack-mpim-open-url
+        team
+        :type "POST"
+        :params (list (cons "users" (mapconcat (lambda (u) (plist-get u :id)) (select-users users '()) ",")))
+        :success #'on-success)))))
+
+(defun slack-group-mpim-close ()
+  (interactive)
+  (let* ((team (slack-team-select)))
+    (slack-select-from-list
+        ((slack-group-names team #'(lambda (groups)
+                                     (cl-remove-if-not #'slack-mpim-p
+                                                       groups)))
+         "Select MPIM: ")
+        (cl-labels
+            ((on-success
+              (&key data &allow-other-keys)
+              (slack-request-handle-error
+               (data "slack-group-mpim-close")
+               (let ((group (slack-room-find (oref selected id) team)))
+                 (with-slots (groups) team
+                   (setq groups
+                         (cl-delete-if #'(lambda (g)
+                                           (slack-room-equal-p group g))
+                                       groups)))
+                 (if (plist-get data :already_closed)
+                     (message "Direct Message Channel with %s Already Closed"
+                              (slack-group-members-s group)))))))
+          (slack-request
+           (slack-request-create
+            slack-mpim-close-url
+            team
+            :type "POST"
+            :params (list (cons "channel" (oref selected id)))
+            :success #'on-success))))))
+
+
+(defmethod slack-mpim-p ((room slack-group))
+  (oref room is-mpim))
+
+(defmethod slack-room-get-info-url ((_room slack-group))
+  slack-group-info-url)
+
+(defmethod slack-room-update-info ((room slack-group) data team)
+  (let ((new-room (slack-room-create (plist-get data :group)
+                                     team
+                                     'slack-group)))
+    (slack-merge room new-room)))
+
+(defmethod slack-room-history-url ((_room slack-group))
+  slack-group-history-url)
+
+(defmethod slack-room-replies-url ((_room slack-group))
+  "https://slack.com/api/groups.replies")
+
+(provide 'slack-group)
+;;; slack-group.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-group.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-group.elc
new file mode 100644
index 0000000000..f3d12443de
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-group.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-im.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-im.el
new file mode 100644
index 0000000000..ac11d5fae6
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-im.el
@@ -0,0 +1,252 @@
+;;; slack-im.el ---slack direct message interface    -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2015  南優也
+
+;; Author: 南優也 <yuyaminami@minamiyuunari-no-MacBook-Pro.local>
+;; Keywords:
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'eieio)
+(require 'slack-util)
+(require 'slack-room)
+(require 'slack-buffer)
+(require 'slack-user)
+(require 'slack-request)
+
+(defvar slack-buffer-function)
+
+(defconst slack-im-history-url "https://slack.com/api/im.history")
+(defconst slack-im-buffer-name "*Slack - Direct Messages*")
+(defconst slack-user-list-url "https://slack.com/api/users.list")
+(defconst slack-im-list-url "https://slack.com/api/im.list")
+(defconst slack-im-close-url "https://slack.com/api/im.close")
+(defconst slack-im-open-url "https://slack.com/api/im.open")
+(defconst slack-im-update-mark-url "https://slack.com/api/im.mark")
+
+(defclass slack-im (slack-room)
+  ((user :initarg :user :initform "")
+   (is-open :initarg :is_open :initform t)
+   (is-user-deleted :initarg :is_user_deleted :initform nil)))
+
+(defmethod slack-merge ((this slack-im) other)
+  (call-next-method)
+  (with-slots (user is-open) this
+    (setq user (oref other user))
+    (setq is-open (oref other is-open))))
+
+(defmethod slack-room-open-p ((room slack-im))
+  (oref room is-open)
+  (not (oref room is-user-deleted)))
+
+(defmethod slack-im-user-presence ((room slack-im))
+  (with-slots (team-id) room
+    (let ((team (slack-team-find team-id)))
+      (slack-user-presence-to-string (slack-user-find room team)))))
+
+(defmethod slack-im-user-dnd-status ((room slack-im))
+  (with-slots (team-id) room
+    (slack-user-dnd-status-to-string (slack-user-find room
+                                                      (slack-team-find team-id)))))
+
+(defmethod slack-room-name ((room slack-im))
+  (with-slots (user team-id) room
+    (slack-user-name user (slack-team-find team-id))))
+
+(defmethod slack-room-display-name ((room slack-im))
+  "To Display emoji in minibuffer configure `emojify-inhibit-in-buffer-functions'"
+  (let* ((team (slack-team-find (oref room team-id)))
+         (status (slack-user-status (oref room user) team))
+         (room-name (or (and status
+                             (format "%s %s"
+                                     (slack-room-name room)
+                                     status))
+                        (slack-room-name room))))
+    (if slack-display-team-name
+        (format "%s - %s"
+                (oref (slack-room-team room) name)
+                room-name)
+      room-name)))
+
+(defun slack-im-user-name (im team)
+  (with-slots (user) im
+    (slack-user-name user team)))
+
+(defun slack-im-names (team)
+  (with-slots (ims) team
+    (slack-room-names ims
+                      #'(lambda (ims)
+                          (cl-remove-if #'(lambda (im) (not (oref im is-open)))
+                                        ims)))))
+
+(defmethod slack-room-buffer-name ((room slack-im))
+  (concat slack-im-buffer-name
+          " : "
+          (slack-room-display-name room)))
+
+(defun slack-im-select ()
+  (interactive)
+  (let* ((team (slack-team-select))
+         (candidates (cl-loop for team in (list team)
+                              for ims = (cl-remove-if #'(lambda (im)
+                                                          (not (oref im is-open)))
+                                                      (oref team ims))
+                              nconc ims))
+         (room (slack-room-select candidates)))
+    (slack-room-display room team)))
+
+(defun slack-user-equal-p (a b)
+  (string= (plist-get a :id) (plist-get b :id)))
+
+(defun slack-user-pushnew (user team)
+  (with-slots (users) team
+    (cl-pushnew user users :test #'slack-user-equal-p)))
+
+(defun slack-im-update-room-list (users team &optional after-success)
+  (cl-labels ((on-update-room-list
+               (&key data &allow-other-keys)
+               (slack-request-handle-error
+                (data "slack-im-update-room-list")
+                (mapc #'(lambda (u) (slack-user-pushnew u team))
+                      (append users nil))
+                (slack-merge-list (oref team ims)
+                                  (mapcar #'(lambda (d)
+                                              (slack-room-create d team 'slack-im))
+                                          (plist-get data :ims)))
+                (if after-success
+                    (funcall after-success team))
+                (slack-request-dnd-team-info team)
+                (mapc #'(lambda (room)
+                          (slack-room-info-request room team))
+                      (oref team ims))
+                (slack-log "Slack Im List Updated" team :level 'info))))
+    (slack-room-list-update slack-im-list-url
+                            #'on-update-room-list
+                            team
+                            :sync nil)))
+
+(defun slack-im-list-update (&optional team after-success)
+  (interactive)
+  (let ((team (or team (slack-team-select))))
+    (cl-labels
+        ((on-list-update
+          (&key data &allow-other-keys)
+          (slack-request-handle-error
+           (data "slack-im-list-update")
+           (let* ((members (append (plist-get data :members) nil)))
+             (slack-im-update-room-list members team after-success)))))
+      (slack-request
+       (slack-request-create
+        slack-user-list-url
+        team
+        :success #'on-list-update)))))
+
+(defmethod slack-room-update-mark-url ((_room slack-im))
+  slack-im-update-mark-url)
+
+(defun slack-im-close ()
+  (interactive)
+  (let* ((team (slack-team-select))
+         (alist (cl-remove-if #'(lambda (im-names)
+                                  (not (oref (cdr im-names) is-open)))
+                              (slack-im-names team))))
+    (slack-select-from-list
+        (alist "Select User: ")
+        (cl-labels
+            ((on-success
+              (&key data &allow-other-keys)
+              (slack-request-handle-error
+               (data "slack-im-close")
+               (if (plist-get data :already_closed)
+                   (let ((im (slack-room-find (oref selected id) team)))
+                     (oset im is-open nil)
+                     (message "Direct Message Channel with %s Already Closed"
+                              (slack-user-name (oref im user) team)))))))
+          (slack-request
+           (slack-request-create
+            slack-im-close-url
+            team
+            :type "POST"
+            :params (list (cons "channel" (oref selected id)))
+            :success #'on-success))))))
+
+(defun slack-im-open (&optional user after-success)
+  (interactive)
+  (let* ((team (slack-team-select))
+         (user (or user (slack-select-from-list
+                            ((slack-user-name-alist
+                              team
+                              :filter #'(lambda (users) (cl-remove-if #'slack-user-hidden-p users)))
+                             "Select User: ")))))
+    (cl-labels
+        ((on-success
+          (&key data &allow-other-keys)
+          (slack-request-handle-error
+           (data "slack-im-open")
+           (if (plist-get data :already_open)
+               (let ((im (slack-room-find (plist-get (plist-get data :channel) :id) team)))
+                 (oset im is-open t)
+                 (message "Direct Message Channel with %s Already Open"
+                          (slack-user-name (oref im user) team))))
+           (when (functionp after-success)
+             (funcall after-success)))))
+      (slack-request
+       (slack-request-create
+        slack-im-open-url
+        team
+        :type "POST"
+        :params (list (cons "user" (plist-get user :id)))
+        :success #'on-success)))))
+
+(defmethod slack-room-label-prefix ((room slack-im))
+  (format "%s "
+          (or
+           (slack-im-user-dnd-status room)
+           (slack-im-user-presence room))))
+
+(defmethod slack-room-get-info-url ((_room slack-im))
+  slack-im-open-url)
+
+(defmethod slack-room-update-info ((room slack-im) data team)
+  (let ((new-room (slack-room-create (plist-get data :channel)
+                                     team
+                                     'slack-im)))
+
+    (slack-merge room new-room)))
+
+(defmethod slack-room-info-request-params ((room slack-im))
+  (list (cons "user" (oref room user))
+        (cons "return_im" "true")))
+
+(defmethod slack-room-get-members ((room slack-im))
+  (list (oref room user)))
+
+(defun slack-im-find-by-user-id (user-id team)
+  (cl-find-if #'(lambda (im) (string= user-id (oref im user)))
+              (oref team ims)))
+
+(defmethod slack-room-history-url ((_room slack-im))
+  slack-im-history-url)
+
+(defmethod slack-room-replies-url ((_room slack-im))
+  "https://slack.com/api/im.replies")
+
+(provide 'slack-im)
+;;; slack-im.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-im.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-im.elc
new file mode 100644
index 0000000000..56aa21371c
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-im.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message-buffer.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message-buffer.el
new file mode 100644
index 0000000000..3b5d58c34f
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message-buffer.el
@@ -0,0 +1,434 @@
+;;; slack-message-buffer.el ---                      -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2017
+
+;; Author:  <yuya373@yuya373>
+;; Keywords:
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'eieio)
+(require 'slack-room)
+(require 'slack-util)
+(require 'slack-room-buffer)
+(require 'slack-buffer)
+(require 'slack-request)
+
+(defface slack-new-message-marker-face
+  '((t (:foreground "#d33682"
+                    :weight bold
+                    :height 0.8)))
+  "Face used to New Message Marker."
+  :group 'slack)
+
+(define-derived-mode slack-message-buffer-mode slack-mode "Slack Message Buffer"
+  (add-hook 'lui-pre-output-hook 'slack-buffer-buttonize-link nil t)
+  (add-hook 'lui-pre-output-hook 'slack-add-face-lazy nil t)
+  (add-hook 'lui-pre-output-hook 'slack-search-code-block nil t)
+  (add-hook 'lui-post-output-hook 'slack-display-image t t)
+  ;; TODO move to `slack-room-buffer' ?
+  (cursor-sensor-mode)
+  (setq-local lui-max-buffer-size nil)
+  )
+
+(defclass slack-message-buffer (slack-room-buffer)
+  ((oldest :initform nil :type (or null string))
+   (latest :initform nil :type (or null string))
+   (marker-overlay :initform nil)
+   (update-mark-timer :initform '(nil . nil)) ;; (timestamp . timer)
+   ))
+
+(defmethod slack-buffer-last-read ((this slack-message-buffer))
+  (with-slots (room) this
+    (oref room last-read)))
+
+(cl-defmethod slack-buffer-update-mark ((this slack-message-buffer) &key (force nil))
+  (with-slots (room update-mark-timer) this
+    (let* ((ts (slack-get-ts))
+           (timer-timeout-sec (or (and force 0) 5))
+           (prev-mark (or (car update-mark-timer)
+                          (slack-buffer-last-read this)))
+           (prev-timer (cdr update-mark-timer)))
+      (when (or force (or (string< prev-mark ts)
+                          (string= prev-mark ts)))
+        (slack-log (format "%s: update mark to %s"
+                           (slack-room-name room)
+                           ts)
+                   (oref this team))
+        (when (timerp prev-timer)
+          (cancel-timer prev-timer))
+        (cl-labels
+            ((update-mark ()
+                          (slack-buffer-update-mark-request this ts)))
+          (setq update-mark-timer
+                (cons ts (run-at-time timer-timeout-sec nil #'update-mark))))))))
+
+(defmethod slack-buffer-update-mark-request ((this slack-message-buffer) ts &optional after-success)
+  (with-slots (room team) this
+    (when (slack-room-member-p room)
+      (cl-labels ((on-update-mark (&key data &allow-other-keys)
+                                  (slack-request-handle-error
+                                   (data "slack-buffer-update-mark-request")
+                                   (oset room last-read ts)
+                                   (slack-buffer-update-marker-overlay this)
+                                   (when (functionp after-success)
+                                     (funcall after-success)))))
+        (with-slots (id) room
+          (slack-request
+           (slack-request-create
+            (slack-room-update-mark-url room)
+            team
+            :type "POST"
+            :params (list (cons "channel"  id)
+                          (cons "ts"  ts))
+            :success #'on-update-mark)))))))
+
+(defmethod slack-buffer-send-message ((this slack-message-buffer) message)
+  (with-slots (room team) this
+    (slack-message-send-internal message (oref room id) team)))
+
+(defmethod slack-buffer-latest-ts ((this slack-message-buffer))
+  (with-slots (room) this
+    (slack-if-let* ((latest (oref room latest)))
+        (oref latest ts))))
+
+(defmethod slack-buffer-buffer ((this slack-message-buffer))
+  (let ((buffer-already-exists-p (get-buffer (slack-buffer-name this)))
+        (buffer (call-next-method))
+        (last-read (slack-buffer-last-read this)))
+    (with-current-buffer buffer
+      (if (slack-team-mark-as-read-immediatelyp (oref this team))
+          (progn
+            (unless buffer-already-exists-p
+              (goto-char (marker-position lui-input-marker)))
+            (and (slack-buffer-latest-ts this)
+                 (slack-buffer-update-mark-request this
+                                                   (slack-buffer-latest-ts this))))
+        (unless (string= "0" last-read)
+          (unless buffer-already-exists-p
+            (slack-buffer-goto last-read))
+          (slack-buffer-update-marker-overlay this))))
+
+    buffer))
+
+(defmethod slack-buffer-display-unread-threads ((this slack-message-buffer))
+  (with-slots (room team) this
+    (let* ((threads (mapcar #'(lambda (m) (oref m thread))
+                            (cl-remove-if
+                             #'(lambda (m)
+                                 (or (not (slack-message-thread-parentp m))
+                                     (not (< 0 (oref (oref m thread) unread-count)))))
+                             (oref room messages))))
+           (alist (mapcar #'(lambda (thread)
+                              (cons (slack-thread-title thread team) thread))
+                          (cl-sort threads
+                                   #'string>
+                                   :key #'(lambda (thread) (oref thread thread-ts)))))
+           (selected (slack-select-from-list (alist "Select Thread: "))))
+      (slack-thread-show-messages selected room team))))
+
+(defmethod slack-buffer-start-thread ((this slack-message-buffer) ts)
+  (with-slots (room team) this
+    (let* ((message (slack-room-find-message room ts))
+           (buf (slack-create-thread-message-buffer room team ts)))
+      (when (slack-reply-broadcast-message-p message)
+        (error "Can't start thread from broadcasted message"))
+      (when (slack-file-comment-message-p message)
+        (error "Can't start thread from file comment message"))
+      (when (slack-file-share-message-p message)
+        (error "Can't start thread from file share message"))
+      (slack-buffer-display buf))))
+
+(defmethod slack-buffer-major-mode ((this slack-message-buffer))
+  'slack-message-buffer-mode)
+
+(defmethod slack-buffer-init-buffer ((this slack-message-buffer))
+  (let ((buf (call-next-method)))
+    (with-current-buffer buf
+      (funcall (slack-buffer-major-mode this))
+      (slack-buffer-set-current-buffer this)
+      (goto-char (point-min))
+
+      (slack-buffer-insert-load-more this)
+
+      (with-slots (room team latest) this
+        (let* ((messages (slack-room-sorted-messages room))
+               (latest-message (car (last messages)))
+               (oldest-message (car messages)))
+          (cl-loop for m in messages
+                   do (if (and (or (null latest)
+                                   (string< latest (oref m ts)))
+                               (not (slack-thread-message-p m)))
+                          (slack-buffer-insert this m t)))
+          (when latest-message
+            (slack-buffer-update-lastest this (oref latest-message ts)))
+          (when oldest-message
+            (slack-buffer-update-oldest this oldest-message))))
+      )
+    (with-slots (room team) this
+      (let* ((class (eieio-object-class-name this)))
+        (slack-buffer-push-new-3 class room team)))
+    buf))
+
+
+(cl-defmethod slack-buffer-update ((this slack-message-buffer) message &key replace)
+  (with-slots (room team) this
+    (let ((buffer (get-buffer (slack-buffer-name this))))
+      (when (and (slack-team-mark-as-read-immediatelyp team)
+                 (slack-buffer-in-current-frame buffer))
+        (slack-buffer-update-mark-request this (oref message ts)))
+
+      (if replace (slack-buffer-replace this message)
+        (slack-buffer-update-lastest this (oref message ts))
+        (with-current-buffer buffer
+          (slack-buffer-insert this message))))))
+
+(defmethod slack-buffer-display-message-compose-buffer ((this slack-message-buffer))
+  (with-slots (room team) this
+    (let ((buf (slack-create-room-message-compose-buffer room team)))
+      (slack-buffer-display buf))))
+
+(defmethod slack-buffer-update-lastest ((this slack-message-buffer) latest)
+  (with-slots ((prev-latest latest)) this
+    (if (or (null prev-latest)
+            (string< prev-latest latest))
+        (setq prev-latest latest))))
+
+(defmethod slack-buffer-display-thread ((this slack-message-buffer) ts)
+  (with-slots (room team) this
+    (let ((thread (slack-room-find-thread room ts)))
+      (if thread (slack-thread-show-messages thread room team)
+        (slack-thread-start)))))
+
+(defmethod slack-buffer-display-edit-message-buffer ((this slack-message-buffer) ts)
+  (with-slots (room team) this
+    (let ((buf (slack-create-edit-message-buffer room team ts)))
+      (slack-buffer-display buf))))
+
+(defmethod slack-create-message-buffer ((room slack-room) team)
+  (slack-if-let* ((buffer (slack-buffer-find 'slack-message-buffer
+                                             room
+                                             team)))
+      buffer
+    (slack-message-buffer :room room :team team)))
+
+
+(defmethod slack-buffer-share-message ((this slack-message-buffer) ts)
+  (with-slots (room team) this
+    (let ((buf (slack-create-message-share-buffer room team ts)))
+      (slack-buffer-display buf))))
+
+(defmethod slack-buffer-add-reaction-to-message
+  ((this slack-message-buffer) reaction ts)
+  (with-slots (room team) this
+    (slack-message-reaction-add reaction ts room team)))
+
+(defmethod slack-buffer-add-reaction-to-file-comment
+  ((this slack-message-buffer) reaction id)
+  (with-slots (team) this
+    (slack-file-comment-add-reaction id reaction team)))
+
+(defmethod slack-buffer-remove-reaction-from-message
+  ((this slack-message-buffer) ts &optional file-comment-id)
+  (with-slots (room team) this
+    (let* ((message (slack-room-find-message room ts))
+           ;; TODO
+           (reactions (if file-comment-id
+                          (slack-message-reactions
+                           (oref (oref message file) initial-comment))
+                        (slack-message-reactions message)))
+           (reaction (slack-message-reaction-select reactions)))
+      (slack-message-reaction-remove reaction ts room team))))
+
+(defmethod slack-buffer-pins-remove ((this slack-message-buffer) ts)
+  (with-slots (room team) this
+    (slack-message-pins-request slack-message-pins-remove-url
+                                room team ts)))
+
+(defmethod slack-buffer-pins-add ((this slack-message-buffer) ts)
+  (with-slots (room team) this
+    (slack-message-pins-request slack-message-pins-add-url
+                                room team ts)))
+(defmethod slack-buffer-remove-star ((this slack-message-buffer) ts)
+  (with-slots (room team) this
+    (slack-if-let* ((message (slack-room-find-message room ts)))
+        (slack-message-star-api-request slack-message-stars-remove-url
+                                        (list (cons "channel" (oref room id))
+                                              (slack-message-star-api-params message))
+                                        team))))
+
+(defmethod slack-buffer-add-star ((this slack-message-buffer) ts)
+  (with-slots (room team) this
+    (slack-if-let* ((message (slack-room-find-message room ts)))
+        (slack-message-star-api-request slack-message-stars-add-url
+                                        (list (cons "channel" (oref room id))
+                                              (slack-message-star-api-params message))
+                                        team))))
+
+(defmethod slack-buffer-update-oldest ((this slack-message-buffer) message)
+  (when (and message (or (null (oref this oldest))
+                         (string< (oref message ts) (oref this oldest))))
+    (oset this oldest (oref message ts))))
+
+(defmethod slack-buffer-load-missing-messages ((this slack-message-buffer))
+  (with-slots (room team) this
+    (cl-labels
+        ((request-messages (latest)
+                           (slack-room-history-request room team
+                                                       :latest latest
+                                                       :count 100
+                                                       :after-success #'after-success))
+         (after-success (has-more)
+                        (let* ((messages (slack-room-sorted-messages room))
+                               (oldest-message (car messages))
+                               (latest-message (car (last messages))))
+                          (if has-more
+                              (request-messages (oref latest-message ts))
+                            (progn
+                              (with-current-buffer (slack-buffer-buffer this)
+                                (let ((inhibit-read-only t))
+                                  (slack-buffer-delete-overlay this)
+                                  (delete-region (point-min)
+                                                 (marker-position lui-output-marker)))
+                                (slack-buffer-prepare-marker-for-history this)
+                                (slack-buffer-insert-load-more this)
+                                (cl-loop for m in messages
+                                         do (slack-buffer-insert this m t))
+                                (slack-buffer-goto (slack-buffer-last-read this))
+                                (slack-buffer-update-marker-overlay this))
+                              (when oldest-message
+                                (slack-buffer-update-oldest this
+                                                            oldest-message)))))))
+      (oset room messages nil)
+      (request-messages nil))))
+
+(defmethod slack-buffer-load-more ((this slack-message-buffer))
+  (with-slots (room team oldest) this
+    (let ((current-ts (let ((change (next-single-property-change (point) 'ts)))
+                        (when change
+                          (get-text-property change 'ts))))
+          (cur-point (point)))
+      (cl-labels
+          ((update-buffer
+            (messages)
+            (with-current-buffer (slack-buffer-buffer this)
+              (slack-buffer-widen
+               (let ((inhibit-read-only t))
+                 (goto-char (point-min))
+
+                 (slack-if-let* ((loading-message-end
+                                  (slack-buffer-loading-message-end-point this)))
+                     (progn
+                       (slack-buffer-delete-overlay this)
+                       (delete-region (point-min) loading-message-end))
+                   (message "loading-message-end not found, oldest: %s" oldest))
+
+                 (set-marker lui-output-marker (point-min))
+                 (if (and messages (< 0 (length messages)))
+                     (slack-buffer-insert-load-more this)
+                   (let ((lui-time-stamp-position nil))
+                     (lui-insert "(no more messages)\n")))
+
+                 (cl-loop for m in messages
+                          do (slack-buffer-insert this m t))
+                 (lui-recover-output-marker)
+                 (slack-buffer-update-marker-overlay this)
+                 ))
+              (if current-ts
+                  (slack-buffer-goto current-ts)
+                (goto-char cur-point))))
+           (after-success (&rest _ignore)
+                          (let ((messages (cl-remove-if #'(lambda (e)
+                                                            (or (string< oldest e)
+                                                                (string= oldest e)))
+                                                        (slack-room-sorted-messages room)
+                                                        :key #'(lambda (e) (oref e ts)))))
+                            (update-buffer messages)
+                            (slack-buffer-update-oldest this (car messages)))))
+        (slack-room-history-request room team
+                                    :oldest oldest
+                                    :after-success #'after-success)))))
+
+(defmethod slack-buffer-display-pins-list ((this slack-message-buffer))
+  (with-slots (room team) this
+    (cl-labels
+        ((on-pins-list (&key data &allow-other-keys)
+                       (slack-request-handle-error
+                        (data "slack-room-pins-list")
+                        (let* ((buf (slack-create-pinned-items-buffer
+                                     room team (plist-get data :items))))
+                          (slack-buffer-display buf)))))
+      (slack-request
+       (slack-request-create
+        slack-room-pins-list-url
+        team
+        :params (list (cons "channel" (oref room id)))
+        :success #'on-pins-list)))))
+
+(defmethod slack-buffer-display-user-profile ((this slack-message-buffer))
+  (with-slots (room team) this
+    (let* ((members (cl-remove-if
+                     #'(lambda (e)
+                         (or (slack-user-self-p e team)
+                             (slack-user-hidden-p
+                              (slack-user--find e team))))
+                     (slack-room-get-members room)))
+           (user-alist (mapcar #'(lambda (u) (cons (slack-user-name u team) u))
+                               members))
+           (user-id (if (eq 1 (length members))
+                        (car members)
+                      (slack-select-from-list (user-alist "Select User: ")))))
+      (let ((buf (slack-create-user-profile-buffer team user-id)))
+        (slack-buffer-display buf)))))
+
+(defmethod slack-buffer-execute-slash-command ((this slack-message-buffer) command)
+  (with-slots (team) this
+    (slack-slash-commands-execute command team)))
+
+(defmethod slack-buffer-delete-overlay ((this slack-message-buffer))
+  (when (oref this marker-overlay)
+    (delete-overlay (oref this marker-overlay))))
+
+(defmethod slack-buffer-update-marker-overlay ((this slack-message-buffer))
+  (let ((buf (get-buffer (slack-buffer-name this))))
+    (and buf (with-current-buffer buf
+               (let* ((last-read (slack-buffer-last-read this))
+                      (beg (slack-buffer-ts-eq (point-min) (point-max) last-read))
+                      (end (and beg (next-single-property-change beg 'ts))))
+                 (when (and beg end)
+                   (if (oref this marker-overlay)
+                       (move-overlay (oref this marker-overlay)
+                                     beg end)
+                     (progn
+                       (oset this marker-overlay (make-overlay beg end))
+                       (let ((after-string
+                              (propertize "New Message"
+                                          'face
+                                          'slack-new-message-marker-face)))
+                         (overlay-put (oref this marker-overlay)
+                                      'after-string
+                                      (format "\n%s" after-string)))))))))))
+
+(defmethod slack-buffer-replace ((this slack-message-buffer) message)
+  (call-next-method)
+  (slack-buffer-update-marker-overlay this))
+
+(provide 'slack-message-buffer)
+;;; slack-message-buffer.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message-buffer.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message-buffer.elc
new file mode 100644
index 0000000000..638b400c8c
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message-buffer.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message-compose-buffer.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message-compose-buffer.el
new file mode 100644
index 0000000000..7bf5810861
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message-compose-buffer.el
@@ -0,0 +1,51 @@
+;;; slack-message-compose-buffer.el ---              -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2017
+
+;; Author:  <yuya373@yuya373>
+;; Keywords:
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'eieio)
+(require 'slack-buffer)
+
+(define-derived-mode slack-message-compose-buffer-mode
+  slack-edit-message-mode
+  "Slack Compose Message")
+
+(defclass slack-message-compose-buffer (slack-buffer) ())
+
+(defmethod slack-buffer-send-message ((this slack-message-compose-buffer) _message)
+  (let ((buffer (slack-buffer-buffer this)))
+    (with-current-buffer buffer
+      (kill-buffer)
+      (if (> (count-windows) 1) (delete-window)))))
+
+(defmethod slack-buffer-init-buffer ((this slack-message-compose-buffer))
+  (let ((buf (call-next-method)))
+    (with-current-buffer buf
+      (slack-message-compose-buffer-mode)
+      (slack-buffer-set-current-buffer this))
+    buf))
+
+
+(provide 'slack-message-compose-buffer)
+;;; slack-message-compose-buffer.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message-compose-buffer.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message-compose-buffer.elc
new file mode 100644
index 0000000000..4b5fe10abf
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message-compose-buffer.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message-edit-buffer.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message-edit-buffer.el
new file mode 100644
index 0000000000..8f86731eca
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message-edit-buffer.el
@@ -0,0 +1,96 @@
+;;; slack-message-edit-buffer.el ---                 -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2017
+
+;; Author:  <yuya373@yuya373>
+;; Keywords:
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'eieio)
+(require 'slack-util)
+(require 'slack-message-compose-buffer)
+
+(define-derived-mode slack-message-edit-buffer-mode
+  slack-edit-message-mode
+  "Slack Edit Message")
+
+(defclass slack-message-edit-buffer (slack-message-compose-buffer)
+  ((room :initarg :room :type slack-room)
+   (ts :initarg :ts :type string)))
+
+(defun slack-buffer-find-4 (class a b team)
+  (slack-if-let* ((buf (cl-find-if #'(lambda (buf)
+                                 (string= (buffer-name buf)
+                                          (slack-buffer-name class a b team)))
+                             (slot-value team class))))
+      (with-current-buffer buf slack-current-buffer)))
+
+(defun slack-create-edit-message-buffer (room team ts)
+  (slack-if-let* ((buffer (slack-buffer-find 'slack-message-edit-buffer
+                                       room ts team)))
+      buffer
+    (slack-message-edit-buffer :room room :team team :ts ts)))
+
+(defmethod slack-buffer-find :static
+  ((class slack-message-edit-buffer) room ts team)
+  (slack-buffer-find-4 class room ts team))
+
+(defmethod slack-buffer-name :static
+  ((class slack-message-edit-buffer) room  ts team)
+  (format "*Slack - %s : %s Edit Message %s"
+          (oref team name)
+          (slack-room-name room)
+          ts))
+
+(defmethod slack-buffer-name ((this slack-message-edit-buffer))
+  (with-slots (room team ts) this
+    (slack-buffer-name (eieio-object-class-name this)
+                       room ts team)))
+
+(defmethod slack-buffer-init-buffer ((this slack-message-edit-buffer))
+  (with-slots (room team ts) this
+    (let* ((buf (call-next-method))
+           (message (slack-room-find-message room ts)))
+      (with-current-buffer buf
+        (slack-message-edit-buffer-mode)
+        (slack-buffer-set-current-buffer this)
+        (insert (slack-message-unescape-string
+                 (slack-message-get-text message)
+                 team)))
+      (with-slots (room ts team) this
+        (slack-buffer-push-new-4 (eieio-object-class-name this)
+                                 room
+                                 ts
+                                 team))
+      buf)))
+
+(defmethod slack-buffer-send-message ((this slack-message-edit-buffer) message)
+  (with-slots (room team ts) this
+    (slack-if-let* ((m (slack-room-find-message room ts)))
+        (progn
+          (if (object-of-class-p m 'slack-file-comment-message)
+              (slack-file-comment--edit (oref room id) (oref team id) ts message)
+            (slack-message--edit (oref room id) team ts message))
+          (call-next-method)))))
+
+
+(provide 'slack-message-edit-buffer)
+;;; slack-message-edit-buffer.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message-edit-buffer.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message-edit-buffer.elc
new file mode 100644
index 0000000000..1a7d68ed43
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message-edit-buffer.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message-editor.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message-editor.el
new file mode 100644
index 0000000000..a1f8eb5ca0
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message-editor.el
@@ -0,0 +1,130 @@
+;;; slack-message-editor.el ---  edit message interface  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2015  南優也
+
+;; Author: 南優也 <yuyaminami@minamiyuunari-no-MacBook-Pro.local>
+;; Keywords:
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+(require 'slack-util)
+(require 'slack-room)
+(require 'slack-message-sender)
+
+(defconst slack-message-edit-url "https://slack.com/api/chat.update")
+(defconst slack-message-edit-buffer-name "*Slack - Edit message*")
+(defconst slack-message-write-buffer-name "*Slack - Write message*")
+(defconst slack-message-share-buffer-name "*Slack - Share message*")
+(defconst slack-share-url "https://slack.com/api/chat.shareMessage")
+(defvar slack-buffer-function)
+(defvar slack-target-ts)
+(make-local-variable 'slack-target-ts)
+(defvar slack-message-edit-buffer-type)
+(make-local-variable 'slack-message-edit-buffer-type)
+
+(defvar slack-edit-message-mode-map
+  (let ((keymap (make-sparse-keymap)))
+    (define-key keymap (kbd "C-s C-m") #'slack-message-embed-mention)
+    (define-key keymap (kbd "C-s C-c") #'slack-message-embed-channel)
+    (define-key keymap (kbd "C-c C-k") #'slack-message-cancel-edit)
+    (define-key keymap (kbd "C-c C-c") #'slack-message-send-from-buffer)
+    keymap))
+
+(define-derived-mode slack-edit-message-mode fundamental-mode "Slack Edit Msg"
+  ""
+  (slack-buffer-enable-emojify))
+
+(defun slack-message-share ()
+  (interactive)
+  (slack-if-let* ((buf slack-current-buffer))
+      (slack-buffer-share-message buf (slack-get-ts))))
+
+(defun slack-message-share--send (team room ts msg)
+  (let* ((slack-room-list (or (and (object-of-class-p room 'slack-channel)
+                                   (slack-message-room-list team))
+                              (list (cons (slack-room-display-name room)
+                                          room))))
+         (share-channel-id (oref (slack-select-from-list
+                                     (slack-room-list
+                                      "Select Channel: "
+                                      :initial
+                                      (slack-room-name room)))
+                                 id)))
+    (cl-labels
+        ((on-success (&key data &allow-other-keys)
+                     (slack-request-handle-error
+                      (data "slack-message-share"))))
+      (slack-request
+       (slack-request-create
+        slack-share-url
+        team
+        :type "POST"
+        :params (list (cons "channel" (oref room id))
+                      (cons "timestamp" ts)
+                      (cons "text" (slack-message-prepare-links
+                                    (slack-escape-message msg)
+                                    team))
+                      (cons "share_channel" share-channel-id))
+        :success #'on-success)))))
+
+(defun slack-message-write-another-buffer ()
+  (interactive)
+  (slack-if-let* ((buf slack-current-buffer))
+      (slack-buffer-display-message-compose-buffer buf)))
+
+(defmethod slack-message-get-user-id ((m slack-user-message))
+  (oref m user))
+
+(defun slack-message-edit ()
+  (interactive)
+  (slack-if-let* ((buf slack-current-buffer))
+      (slack-buffer-display-edit-message-buffer buf (slack-get-ts))))
+
+
+(defun slack-message-cancel-edit ()
+  (interactive)
+  (let ((buffer (slack-buffer-buffer slack-current-buffer)))
+    (with-current-buffer buffer
+      (erase-buffer)
+      (if (> (count-windows) 1) (delete-window)))))
+
+(defun slack-message-send-from-buffer ()
+  (interactive)
+  (slack-if-let* ((buf slack-current-buffer)
+            (text (buffer-substring-no-properties (point-min) (point-max))))
+      (slack-buffer-send-message buf text)))
+
+(defun slack-message--edit (channel team ts text)
+  (cl-labels ((on-edit (&key data &allow-other-keys)
+                       (slack-request-handle-error
+                        (data "slack-message--edit"))))
+    (slack-request
+     (slack-request-create
+      slack-message-edit-url
+      team
+      :type "POST"
+      :params (list (cons "channel" channel)
+                    (cons "ts" ts)
+                    (cons "text" (slack-message-prepare-links
+                                  (slack-escape-message text)
+                                  team)))
+      :success #'on-edit))))
+
+(provide 'slack-message-editor)
+;;; slack-message-editor.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message-editor.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message-editor.elc
new file mode 100644
index 0000000000..6f0ad60cee
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message-editor.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message-formatter.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message-formatter.el
new file mode 100644
index 0000000000..558e802cd2
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message-formatter.el
@@ -0,0 +1,306 @@
+;;; slack-message-formatter.el --- format message text  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2015  yuya.minami
+
+;; Author: yuya.minami <yuya.minami@yuyaminami-no-MacBook-Pro.local>
+;; Keywords:
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'eieio)
+(require 'slack-user)
+(require 'slack-room)
+
+(defface slack-profile-image-face
+  '((t (:background "#fff")))
+  "Face used to profile image."
+  :group 'slack)
+
+(defface slack-message-output-text
+  '((t (:weight normal :height 0.9)))
+  "Face used to text message."
+  :group 'slack)
+
+(defface slack-message-output-header
+  '((t (:foreground "#FFA000"
+                    :weight bold
+                    :height 1.0
+                    :underline t)))
+  "Face used to text message."
+  :group 'slack)
+
+(defface slack-message-output-reaction
+  '((t (:box (:line-width 1 :style released-button))))
+  "Face used to reactions."
+  :group 'slack)
+
+(defface slack-message-deleted-face
+  '((t (:strike-through t)))
+  "Face used to deleted message."
+  :group 'slack)
+
+(defface slack-attachment-header
+  '((t (:weight bold)))
+  "Face used to shared message header."
+  :group 'slack)
+
+(defface slack-attachment-footer
+  '((t (:height 0.8)))
+  "Face used to shared message footer."
+  :group 'slack)
+
+(defface slack-attachment-pad
+  '((t (:weight ultra-bold)))
+  "Face used to shared message pad."
+  :group 'slack)
+
+(defface slack-attachment-field-title
+  '((t (:weight bold :height 1.0)))
+  "Face used to attachment field title."
+  :group 'slack)
+
+(defcustom slack-date-formats
+  '((date_num . "%Y-%m-%d")
+    (date . "%B %d,%Y")
+    (date_short . "%b %d,%Y")
+    (date_long . "%A %B %d,%Y")
+    (date_pretty . "%B %d,%Y")
+    (date_short_pretty . "%b %d,%Y")
+    (date_long_pretty . "%A %B %d,%Y")
+    (time . "%H:%M")
+    (time_secs . "%H:%M:%S"))
+  "Date formats for Slack's date token.
+this format string passed to `format-time-string' function.
+see \"Formatting dates\" section in https://api.slack.com/docs/message-formatting"
+  :group 'slack)
+
+(defun slack-message-put-header-property (header)
+  (if header
+      (propertize header 'face 'slack-message-output-header)))
+
+(defun slack-message-put-text-property (text)
+  (if text
+      (propertize text 'face 'slack-message-output-text)))
+
+(defun slack-message-put-hard (text)
+  (if text
+      (propertize text 'hard t)))
+
+(defun slack-message-put-deleted-property (text)
+  (if text
+      (propertize text 'face 'slack-message-deleted-face)))
+
+(defun slack-message-time-to-string (ts)
+  (when ts
+    (when (stringp ts)
+      (setf ts (string-to-number ts)))
+    (format-time-string "%Y-%m-%d %H:%M:%S"
+                        (seconds-to-time ts))))
+
+(defmethod slack-message-header ((m slack-message) team)
+  (slack-message-sender-name m team))
+
+(defmethod slack-message-starred-p ((m slack-message))
+  (oref m is-starred))
+
+(defmethod slack-message-starred-p ((m slack-file-message))
+  (oref (oref m file) is-starred))
+
+(defmethod slack-message-starred-str ((m slack-message))
+  (if (slack-message-starred-p m)
+      ":star:"
+    ""))
+
+(defun slack-format-message (&rest args)
+  (let ((messages args))
+    (mapconcat #'identity
+               (cl-remove-if #'(lambda (e) (< (length e) 1)) messages)
+               "\n")))
+
+(defmethod slack-message-profile-image ((m slack-message) team)
+  (slack-user-image (slack-user-find m team) team))
+
+(defmethod slack-message-header-with-image ((m slack-message) header team)
+  (let ((image (slack-message-profile-image m team)))
+    (if image
+        (format "%s %s" (propertize "image"
+                                    'display image
+                                    'face 'slack-profile-image-face)
+                header)
+      header)))
+
+(defun slack-message-header-to-string (m team)
+  (let ((header (format "%s %s"
+                        (slack-message-put-header-property
+                         (slack-message-header m team))
+                        (slack-message-starred-str m))))
+    (if (slack-team-display-profile-imagep team)
+        (slack-message-header-with-image m header team)
+      header)))
+
+(defmethod slack-message-body-to-string ((m slack-message) team)
+  (let ((raw-body (slack-message-body m team)))
+    (if (oref m deleted-at)
+        (slack-message-put-deleted-property raw-body)
+      (slack-message-put-text-property raw-body))))
+
+
+(defun slack-format-reactions (reactions team)
+  (concat "\n"
+          (mapconcat #'(lambda (r) (slack-reaction-to-string r team))
+                     reactions
+                     " ")))
+
+(defmethod slack-message-reaction-to-string ((m slack-message) team)
+  (let ((reactions (slack-message-reactions m)))
+    (when reactions
+      (slack-format-reactions reactions team))))
+
+(defmethod slack-message-to-string ((m slack-message) team)
+  (let ((text (if (slot-boundp m 'text) (oref m text))))
+    (let* ((header (slack-message-header-to-string m team))
+           (attachment-body (slack-message-attachment-body m team))
+           (body (slack-message-body-to-string m team))
+           (reactions (slack-message-reaction-to-string m team))
+           (thread (slack-thread-to-string m team)))
+      (slack-format-message header body attachment-body reactions thread))))
+
+(defmethod slack-message-body ((m slack-message) team)
+  (with-slots (text) m
+    (slack-message-unescape-string text team)))
+
+(defmethod slack-message-body ((m slack-reply-broadcast-message) team)
+  (format "Replied to a thread: \n%s"
+          (slack-message-unescape-string (oref m text) team)))
+
+(defmethod slack-team-display-image-inlinep ((_m slack-message) team)
+  (slack-team-display-attachment-image-inlinep team))
+
+(defmethod slack-message-attachment-body ((m slack-message) team)
+  (with-slots (attachments) m
+    (let ((body (mapconcat #'(lambda (attachment)
+                               (slack-message-to-string attachment team))
+                           attachments "\n\t-\n")))
+      (if (< 0 (length body))
+          (slack-message-unescape-string (format "\n%s" body) team)))))
+
+(defmethod slack-message-to-alert ((m slack-message) team)
+  (with-slots (text attachments) m
+    (if (and text (< 0 (length text)))
+        (slack-message-unescape-string text team)
+      (let ((attachment-string (mapconcat #'slack-attachment-to-alert
+                                          attachments " ")))
+        (slack-message-unescape-string attachment-string team)))))
+
+(defun slack-message-unescape-string (text team)
+  (when text
+    (let* ((and-unescpaed
+            (replace-regexp-in-string "&amp;" "&" text))
+           (lt-unescaped
+            (replace-regexp-in-string "&lt;" "<" and-unescpaed))
+           (gt-unescaped
+            (replace-regexp-in-string "&gt;" ">" lt-unescaped)))
+      (slack-message-unescape-date-format
+       (slack-message-unescape-command
+        (slack-message-unescape-user-id
+         (slack-message-unescape-channel gt-unescaped team)
+         team))))))
+
+(defun slack-message-unescape-user-id (text team)
+  (let ((user-regexp "<@\\(U.*?\\)>"))
+    (cl-labels ((unescape-user-id
+                 (text)
+                 (concat "@" (or
+                              (slack-message-replace-user-name text)
+                              (let ((user (slack-user--find (match-string 1 text) team)))
+                                (plist-get user :name))
+                              (match-string 1 text)))))
+      (replace-regexp-in-string user-regexp
+                                #'unescape-user-id
+                                text t t))))
+
+(defun slack-message-replace-user-name (text)
+  (let ((user-name-regexp "<@U.*?|\\(.*?\\)>"))
+    (cl-labels ((replace-user-id-with-name (text)
+                                           (match-string 1 text)))
+      (if (string-match-p user-name-regexp text)
+          (replace-regexp-in-string user-name-regexp
+                                    #'replace-user-id-with-name
+                                    text nil t)))))
+
+(defun slack-message-unescape-date-format (text)
+  (let ((date-regexp "<!date^\\([[:digit:]]*\\)^\\(.*?\\)\\(\\^.*\\)?|\\(.*\\)>")
+        (time-format-regexp "{\\(.*?\\)}"))
+    (cl-labels
+        ((unescape-date-string
+          (text)
+          (let* ((time (match-string 1 text))
+                 (format-string (match-string 2 text))
+                 (link (match-string 3 text))
+                 (fallback (match-string 4 text)))
+            (replace-regexp-in-string time-format-regexp
+                                      #'(lambda (text)
+                                          (unescape-datetime-format time
+                                                                    link
+                                                                    text
+                                                                    fallback))
+                                      format-string)))
+         (unescape-datetime-format
+          (unix-time link text fallback)
+          (let* ((match (match-string 1 text))
+                 (template (cl-assoc (intern match) slack-date-formats)))
+            (if template
+                (slack-linkfy
+                 (format-time-string (cdr template)
+                                     (float-time (string-to-number unix-time)))
+                 (and link (substring link 1 (length link))))
+              fallback))))
+      (replace-regexp-in-string date-regexp
+                                #'unescape-date-string
+                                text nil t))))
+
+(defun slack-message-unescape-command (text)
+  (let ((command-regexp "<!\\(.*?\\)>"))
+    (cl-labels ((unescape-command
+                 (text)
+                 (let ((match (match-string 1 text)))
+                   (if (string-prefix-p "date" match)
+                       (format "<!%s>" match)
+                     (concat "@" match)))))
+      (replace-regexp-in-string command-regexp
+                                #'unescape-command
+                                text nil t))))
+
+(defun slack-message-unescape-channel (text team)
+  (let ((channel-regexp "<#\\(C.*?\\)\\(|.*?\\)?>"))
+    (cl-labels ((unescape-channel
+                 (text)
+                 (let ((name (match-string 2 text))
+                       (id (match-string 1 text)))
+                   (concat "#" (or (and name (substring name 1))
+                                   (slack-if-let* ((room (slack-room-find id team)))
+                                       (oref room name)
+                                     id))))))
+      (replace-regexp-in-string channel-regexp
+                                #'unescape-channel
+                                text t))))
+
+(provide 'slack-message-formatter)
+;;; slack-message-formatter.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message-formatter.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message-formatter.elc
new file mode 100644
index 0000000000..c968d61580
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message-formatter.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message-notification.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message-notification.el
new file mode 100644
index 0000000000..179d820bff
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message-notification.el
@@ -0,0 +1,145 @@
+;;; slack-message-notification.el --- message notification  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2015  yuya.minami
+
+;; Author: yuya.minami <yuya.minami@yuyaminami-no-MacBook-Pro.local>
+;; Keywords:
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+(require 'eieio)
+(require 'slack-room)
+(require 'slack-message)
+(require 'slack-message-formatter)
+(require 'slack-buffer)
+(require 'slack-im)
+(require 'alert)
+
+(defvar alert-default-style)
+
+(defcustom slack-message-custom-notifier nil
+  "Custom notification function.\ntake 3 Arguments.\n(lambda (MESSAGE ROOM TEAM) ...)."
+  :group 'slack)
+
+(defcustom slack-message-im-notification-title-format-function
+  #'(lambda (team-name room-name thread-messagep)
+      (format "%s - %s" team-name (if thread-messagep
+                                      (format "Thread in %s" room-name)
+                                    room-name)))
+  "Function to format notification title for IM message.\ntake 3 Arguments.\n(lambda (TEAM-NAME ROOM-NAME THREAD-MESSAGEP) ...)."
+  :type 'function
+  :group 'slack)
+
+(defcustom slack-message-notification-title-format-function
+  #'(lambda (team-name room-name thread-messagep)
+      (format "%s - %s" team-name (if thread-messagep
+                                      (format "Thread in #%s" room-name)
+                                    (format "#%s" room-name))))
+  "Function to format notification title for non-IM message.\ntake 3 Arguments.\n(lambda (TEAM-NAME ROOM-NAME THREAD-MESSAGEP) ...)."
+  :type 'function
+  :group 'slack)
+
+(defcustom slack-alert-icon nil
+  "String passed as the :icon argument to `alert'."
+  :type '(choice file (const :tag "Stock alert icon" nil))
+  :group 'slack)
+
+(defvar slack-modeline nil)
+
+(defcustom slack-modeline-formatter #'slack-default-modeline-formatter
+  "Format modeline with Arg '((team-name . unread-count))."
+  :group 'slack)
+
+(defun slack-message-notify (message room team)
+  (if slack-message-custom-notifier
+      (funcall slack-message-custom-notifier message room team)
+    (slack-message-notify-alert message room team)))
+
+(defun slack-message-notify-alert (message room team)
+  (if (and (not (slack-message-minep message team))
+           (or (slack-im-p room)
+               (and (slack-group-p room) (slack-mpim-p room))
+               (slack-room-subscribedp room team)
+               (string-match (format "@%s" (plist-get (oref team self) :name))
+                             (or (slack-message-body message team) ""))))
+      (let ((team-name (oref team name))
+            (room-name (slack-room-name room))
+            (text (with-temp-buffer
+                    (goto-char (point-min))
+                    (insert (slack-message-to-alert message team))
+                    (slack-buffer-buttonize-link)
+                    (buffer-substring-no-properties (point-min)
+                                                    (point-max))))
+            (user-name (slack-message-sender-name message team)))
+        (if (and (eq alert-default-style 'notifier)
+                 (slack-im-p room)
+                 (or (eq (aref text 0) ?\[)
+                     (eq (aref text 0) ?\{)
+                     (eq (aref text 0) ?\<)
+                     (eq (aref text 0) ?\()))
+            (setq text (concat "\\" text)))
+        (alert (if (slack-im-p room) text (format "%s: %s" user-name text))
+               :icon slack-alert-icon
+               :title (if (slack-im-p room)
+                          (funcall slack-message-im-notification-title-format-function
+                                   team-name room-name (slack-thread-messagep message))
+                        (funcall slack-message-notification-title-format-function
+                                 team-name room-name (slack-thread-messagep message)))
+               :category 'slack))))
+
+(defmethod slack-message-sender-equalp ((_m slack-message) _sender-id)
+  nil)
+
+(defmethod slack-message-minep ((m slack-message) team)
+  (if team
+      (with-slots (self-id) team
+        (slack-message-sender-equalp m self-id))
+    (slack-message-sender-equalp m (oref team self-id))))
+
+(defun slack-default-modeline-formatter (alist)
+  "Arg is alist of '((team-name . unread-count))"
+  (if (= 1 (length alist))
+      (format "[ %s: %s ]" (caar alist) (cdar alist))
+    (mapconcat #'(lambda (e) (format "[ %s: %s ]" (car e) (cdr e)))
+               alist " ")))
+
+(defun slack-enable-modeline ()
+  (add-to-list 'global-mode-string '(:eval slack-modeline) t))
+
+(defun slack-update-modeline ()
+  (let ((teams (cl-remove-if-not #'slack-team-modeline-enabledp slack-teams)))
+    (when (< 0 (length teams))
+      (setq slack-modeline
+            (funcall slack-modeline-formatter
+                     (mapcar #'(lambda (e) (cons (or (oref e modeline-name) (slack-team-name e))
+                                                 (slack-team-get-unread-messages e)))
+                             teams)))
+      (force-mode-line-update))))
+
+(defun slack-message-test-notification ()
+  "Debug notification.
+Execute this function when cursor is on some message."
+  (interactive)
+  (let ((ts (slack-get-ts)))
+    (with-slots (room team) slack-current-buffer
+      (let ((message (slack-room-find-message room ts)))
+        (slack-message-notify message room team)))))
+
+(provide 'slack-message-notification)
+;;; slack-message-notification.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message-notification.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message-notification.elc
new file mode 100644
index 0000000000..c20a708afd
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message-notification.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message-reaction.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message-reaction.el
new file mode 100644
index 0000000000..0fa0d14aa6
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message-reaction.el
@@ -0,0 +1,168 @@
+;;; slack-message-reaction.el --- adding, removing reaction from message  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2015  yuya.minami
+
+;; Author: yuya.minami <yuya.minami@yuyaminami-no-MacBook-Pro.local>
+;; Keywords:
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'slack-util)
+(require 'slack-message)
+(require 'slack-reaction)
+(require 'slack-room)
+(require 'slack-file)
+(require 'slack-request)
+
+(defconst slack-message-reaction-add-url "https://slack.com/api/reactions.add")
+(defconst slack-message-reaction-remove-url "https://slack.com/api/reactions.remove")
+(defcustom slack-invalid-emojis '("^:flag_" "tone[[:digit:]]:$" "-" "^[^:].*[^:]$" "\\Ca")
+  "Invalid emoji regex. Slack server treated some emojis as Invalid."
+  :group 'slack)
+
+(defun slack-file-comment-add-reaction (file-comment-id reaction team)
+  (slack-message-reaction-add-request (list (cons "name" reaction)
+                                            (cons "file_comment" file-comment-id))
+                                      team))
+
+(defun slack-get-file-comment-id ()
+  (get-text-property 0 'file-comment-id (thing-at-point 'line)))
+
+(defun slack-get-file-id ()
+  (get-text-property 0 'file-id (thing-at-point 'line)))
+
+(defun slack-file-add-reaction (file-id reaction team)
+  (slack-message-reaction-add-request (list (cons "name" reaction)
+                                            (cons "file" file-id))
+                                      team))
+
+(defun slack-message--add-reaction (buf reaction)
+  (slack-if-let* ((file-comment-id (slack-get-file-comment-id)))
+      (slack-buffer-add-reaction-to-file-comment buf reaction file-comment-id)
+    (slack-buffer-add-reaction-to-message buf reaction (slack-get-ts))))
+
+(defun slack-message-add-reaction ()
+  (interactive)
+  (slack-if-let* ((buf slack-current-buffer)
+                  (reaction (slack-message-reaction-input)))
+      (slack-message--add-reaction buf reaction)))
+
+(defun slack-file-comment-remove-reaction (file-comment-id file-id team)
+  (slack-with-file file-id team
+    (slack-with-file-comment file-comment-id file
+      (let ((reaction (slack-message-reaction-select
+                       (slack-message-reactions file-comment))))
+        (slack-message-reaction-remove-request
+         (list (cons "file_comment" file-comment-id)
+               (cons "name" reaction))
+         team)))))
+
+(defun slack-file-remove-reaction (file-id team)
+  (slack-with-file file-id team
+    (let ((reaction (slack-message-reaction-select
+                     (slack-message-reactions file))))
+      (slack-message-reaction-remove-request
+       (list (cons "file" file-id)
+             (cons "name" reaction))
+       team))))
+
+(defun slack-message-remove-reaction ()
+  (interactive)
+  (slack-buffer-remove-reaction-from-message
+   slack-current-buffer
+   (slack-get-ts)
+   (slack-get-file-comment-id)))
+
+(defun slack-message-show-reaction-users ()
+  (interactive)
+  (slack-if-let* ((buf slack-current-buffer))
+      (with-slots (team) buf
+        (slack-if-let* ((reaction (ignore-errors
+                                    (get-text-property (point)
+                                                       'reaction))))
+            (let ((user-names (slack-reaction-user-names reaction
+                                                         team)))
+              (message "reacted users: %s"
+                       (mapconcat #'identity user-names ", ")))
+          (message "Can't get reaction:")))))
+
+(defun slack-message-reaction-select (reactions)
+  (let ((list (mapcar #'(lambda (r)
+                          (cons (oref r name)
+                                (oref r name)))
+                      reactions)))
+    (slack-select-from-list
+        (list "Select Reaction: ")
+        selected)))
+
+(defun slack-select-emoji ()
+  (if (fboundp 'emojify-completing-read)
+      (emojify-completing-read "Select Emoji: ")
+    (read-from-minibuffer "Emoji: ")))
+
+(defun slack-message-reaction-input ()
+  (let ((reaction (slack-select-emoji)))
+    (if (and (string-prefix-p ":" reaction)
+             (string-suffix-p ":" reaction))
+        (substring reaction 1 -1)
+      reaction)))
+
+(defun slack-message-reaction-add (reaction ts room team)
+  (slack-if-let* ((message (slack-room-find-message room ts)))
+      (let ((params (list (cons "channel" (oref room id))
+                          (slack-message-get-param-for-reaction message)
+                          (cons "name" reaction))))
+        (slack-message-reaction-add-request params team))))
+
+(defun slack-message-reaction-add-request (params team)
+  (cl-labels ((on-reaction-add
+               (&key data &allow-other-keys)
+               (slack-request-handle-error
+                (data "slack-message-reaction-add-request"))))
+    (slack-request
+     (slack-request-create
+      slack-message-reaction-add-url
+      team
+      :type "POST"
+      :params params
+      :success #'on-reaction-add))))
+
+(defun slack-message-reaction-remove (reaction ts room team)
+  (slack-if-let* ((message (slack-room-find-message room ts)))
+      (let ((params (list (cons "channel" (oref room id))
+                          (slack-message-get-param-for-reaction message)
+                          (cons "name" reaction))))
+        (slack-message-reaction-remove-request params team))))
+
+(defun slack-message-reaction-remove-request (params team)
+  (cl-labels ((on-reaction-remove
+               (&key data &allow-other-keys)
+               (slack-request-handle-error
+                (data "slack-message-reaction-remove-request"))))
+    (slack-request
+     (slack-request-create
+      slack-message-reaction-remove-url
+      team
+      :type "POST"
+      :params params
+      :success #'on-reaction-remove))))
+
+(provide 'slack-message-reaction)
+;;; slack-message-reaction.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message-reaction.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message-reaction.elc
new file mode 100644
index 0000000000..72e989ac22
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message-reaction.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message-sender.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message-sender.el
new file mode 100644
index 0000000000..9896c43165
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message-sender.el
@@ -0,0 +1,169 @@
+;;; slack-message-sender.el --- slack message concern message sending  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2015  yuya.minami
+
+;; Author: yuya.minami <yuya.minami@yuyaminami-no-MacBook-Pro.local>
+;; Keywords:
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'eieio)
+(require 'json)
+(require 'slack-util)
+(require 'slack-websocket)
+(require 'slack-room)
+(require 'slack-im)
+(require 'slack-group)
+(require 'slack-message)
+(require 'slack-channel)
+(require 'slack-slash-commands)
+
+(defvar slack-message-minibuffer-local-map nil)
+(defvar slack-buffer-function)
+
+(defun slack-message-send ()
+  (interactive)
+  (slack-message--send (slack-message-read-from-minibuffer)))
+
+(defun slack-message-inc-id (team)
+  (with-slots (message-id) team
+    (if (eq message-id (1- most-positive-fixnum))
+        (setq message-id 1)
+      (cl-incf message-id))))
+
+(defun slack-escape-message (message)
+  "Escape '<,' '>' & '&' in MESSAGE."
+  (replace-regexp-in-string
+   ">" "&gt;"
+   (replace-regexp-in-string
+    "<" "&lt;"
+    (replace-regexp-in-string "&" "&amp;" message))))
+
+(defun slack-link-users (message team)
+  "Add links to all references to valid users in MESSAGE."
+  (replace-regexp-in-string
+   "@\\<\\([A-Za-z0-9._\-]+\\)\\>"
+   #'(lambda (text)
+       (let* ((username (match-string 1 text))
+              (id (slack-user-get-id username team)))
+         (if id
+             (format "<@%s|%s>" id username)
+           (cond
+            ((string= username "here") "<!here|here>")
+            ((cl-find username '("channel" "group") :test #'string=) "<!channel>")
+            ((string= username "everyone") "<!everyone>")
+            (t text)))))
+   message t))
+
+(defun slack-link-channels (message team)
+  "Add links to all references to valid channels in MESSAGE."
+  (let ((channel-ids
+         (mapcar #'(lambda (x)
+                     (let ((channel (cdr x)))
+                       (cons (slack-room-name channel) (slot-value channel 'id))))
+                 (slack-channel-names team))))
+    (replace-regexp-in-string
+     "#\\<\\([A-Za-z0-9_\-]+\\)\\>"
+     #'(lambda (text)
+         (let* ((channel (match-string 1 text))
+                (id (cdr (assoc channel channel-ids))))
+           (if id
+               (format "<#%s|%s>" id channel)
+             text)))
+     message t)))
+
+(defun slack-message-prepare-links (message team)
+  (slack-link-channels (slack-link-users message team) team))
+
+(defun slack-message--send (message)
+  (slack-if-let* ((buf slack-current-buffer))
+      (slack-if-let* ((command (slack-slash-commands-parse message)))
+          (slack-buffer-execute-slash-command buf command)
+        (slack-buffer-send-message buf message))))
+
+(defun slack-message-send-internal (message channel-id team)
+  (slack-message-inc-id team)
+  (with-slots (message-id sent-message self-id) team
+    (let* ((m (list :id message-id
+                    :channel channel-id
+                    :type "message"
+                    :user self-id
+                    :text (slack-message-prepare-links
+                           (slack-escape-message message)
+                           team)))
+           (json (json-encode m))
+           (obj (slack-message-create m team)))
+      (slack-ws-send json team)
+      (puthash message-id obj sent-message))))
+
+(defun slack-message-read-room (team)
+  (let* ((list (slack-message-room-list team))
+         (choices (mapcar #'car list))
+         (room-name (slack-message-read-room-list "Select Room: " choices))
+         (room (cdr (cl-assoc room-name list :test #'string=))))
+    room))
+
+(defun slack-message-read-room-list (prompt choices)
+  (let ((completion-ignore-case t))
+    (funcall slack-completing-read-function (format "%s" prompt)
+             choices nil t nil nil choices)))
+
+(defun slack-message-room-list (team)
+  (append (slack-group-names team)
+          (slack-im-names team)
+          (slack-channel-names team)))
+
+(defun slack-message-read-from-minibuffer ()
+  (let ((prompt "Message: "))
+    (slack-message-setup-minibuffer-keymap)
+    (read-from-minibuffer
+     prompt
+     nil
+     slack-message-minibuffer-local-map)))
+
+(defun slack-message-setup-minibuffer-keymap ()
+  (unless slack-message-minibuffer-local-map
+    (setq slack-message-minibuffer-local-map
+          (let ((map (make-sparse-keymap)))
+            (define-key map (kbd "RET") 'newline)
+            (set-keymap-parent map minibuffer-local-map)
+            map))))
+
+(defun slack-message-embed-channel ()
+  (interactive)
+  (slack-if-let* ((buf slack-current-buffer))
+      (with-slots (team) buf
+        (slack-select-from-list
+            ((slack-channel-names team) "Select Channel: ")
+            (insert (concat "#" (slack-room-name selected)))))))
+
+(defun slack-message-embed-mention ()
+  (interactive)
+  (slack-if-let* ((buf slack-current-buffer))
+      (with-slots (team) buf
+        (let* ((pre-defined (list (list "here" :name "here")
+                                  (list "channel" :name "channel")))
+               (alist (append pre-defined (slack-user-names team))))
+          (slack-select-from-list
+              (alist "Select User: ")
+              (insert (concat "@" (plist-get selected :name))))))))
+
+(provide 'slack-message-sender)
+;;; slack-message-sender.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message-sender.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message-sender.elc
new file mode 100644
index 0000000000..fd7d3bf17e
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message-sender.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message-share-buffer.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message-share-buffer.el
new file mode 100644
index 0000000000..8856debce1
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message-share-buffer.el
@@ -0,0 +1,75 @@
+;;; slack-message-share-buffer.el ---                -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2017
+
+;; Author:  <yuya373@yuya373>
+;; Keywords:
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'eieio)
+(require 'slack-util)
+(require 'slack-room-buffer)
+
+(define-derived-mode slack-message-share-buffer-mode
+  slack-message-compose-buffer-mode
+  "Slack Share Message")
+
+(defclass slack-message-share-buffer (slack-message-compose-buffer)
+  ((ts :initarg :ts :type string)
+   (room :initarg :room :type slack-room)))
+
+(defun slack-create-message-share-buffer (room team ts)
+  (slack-if-let* ((buf (slack-buffer-find 'slack-message-share-buffer
+                                    room ts team)))
+      buf
+    (slack-message-share-buffer :room room :team team :ts ts)))
+
+(defmethod slack-buffer-find :static ((class slack-message-share-buffer) room ts team)
+  (slack-buffer-find-4 class room ts team))
+
+(defmethod slack-buffer-name :static ((class slack-message-share-buffer) room ts team)
+  (format "*Slack - %s : %s  Share Message - %s"
+          (oref team name)
+          (slack-room-name room)
+          ts))
+
+(defmethod slack-buffer-name ((this slack-message-share-buffer))
+  (with-slots (room ts team) this
+    (slack-buffer-name 'slack-message-share-buffer
+                       room ts team)))
+
+(defmethod slack-buffer-init-buffer ((this slack-message-share-buffer))
+  (let* ((buf (call-next-method)))
+    (with-current-buffer buf
+      (slack-message-share-buffer-mode)
+      (slack-buffer-set-current-buffer this))
+    (with-slots (room ts team) this
+      (slack-buffer-push-new-4 'slack-message-share-buffer
+                               room ts team))
+    buf))
+
+(defmethod slack-buffer-send-message ((this slack-message-share-buffer) message)
+  (with-slots (room team ts) this
+    (slack-message-share--send team room ts message)
+    (call-next-method)))
+
+(provide 'slack-message-share-buffer)
+;;; slack-message-share-buffer.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message-share-buffer.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message-share-buffer.elc
new file mode 100644
index 0000000000..20eef1b5ca
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message-share-buffer.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message.el
new file mode 100644
index 0000000000..972372b9fd
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message.el
@@ -0,0 +1,445 @@
+;;; slack-message.el --- slack-message                -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2015  yuya.minami
+
+;; Author: yuya.minami <yuya.minami@yuyaminami-no-MacBook-Pro.local>
+;; Keywords:
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'eieio)
+(require 'subr-x)
+(require 'slack-util)
+(require 'slack-reaction)
+(require 'slack-request)
+
+(defcustom slack-message-custom-delete-notifier nil
+  "Custom notification function for deleted message.\ntake 3 Arguments.\n(lambda (MESSAGE ROOM TEAM) ...)."
+  :group 'slack)
+
+(defconst slack-message-pins-add-url "https://slack.com/api/pins.add")
+(defconst slack-message-pins-remove-url "https://slack.com/api/pins.remove")
+(defconst slack-message-stars-add-url "https://slack.com/api/stars.add")
+(defconst slack-message-stars-remove-url "https://slack.com/api/stars.remove")
+
+(defclass slack-message ()
+  ((type :initarg :type :type string)
+   (subtype :initarg :subtype)
+   (channel :initarg :channel :initform nil)
+   (ts :initarg :ts :type string :initform "")
+   (text :initarg :text :type (or null string) :initform nil)
+   (item-type :initarg :item_type)
+   (attachments :initarg :attachments :type (or null list) :initform nil)
+   (reactions :initarg :reactions :type (or null list))
+   (is-starred :initarg :is_starred :type boolean :initform nil)
+   (pinned-to :initarg :pinned_to :type (or null list))
+   (edited-at :initarg :edited-at :initform nil)
+   (deleted-at :initarg :deleted-at :initform nil)
+   (thread :initarg :thread :initform nil)
+   (thread-ts :initarg :thread_ts :initform nil)
+   (hide :initarg :hide :initform nil)))
+
+(defclass slack-file-message (slack-message)
+  ((file :initarg :file)))
+
+(defclass slack-reply (slack-message)
+  ((user :initarg :user :initform nil)
+   (reply-to :initarg :reply_to :type integer)
+   (id :initarg :id :type integer)))
+
+(defclass slack-user-message (slack-message)
+  ((user :initarg :user :type string)
+   (edited :initarg :edited)
+   (id :initarg :id)
+   (inviter :initarg :inviter)))
+
+(defclass slack-reply-broadcast-message (slack-user-message)
+  ((broadcast-thread-ts :initarg :broadcast_thread_ts :initform nil)))
+
+(defclass slack-bot-message (slack-message)
+  ((bot-id :initarg :bot_id :type string)
+   (username :initarg :username :type string :initform "")
+   (icons :initarg :icons)))
+
+(defclass slack-attachment-field ()
+  ((title :initarg :title :initform nil)
+   (value :initarg :value :initform nil)
+   (short :initarg :short :initform nil)))
+
+(defgeneric slack-message-sender-name  (slack-message team))
+(defgeneric slack-message-to-string (slack-message))
+(defgeneric slack-message-to-alert (slack-message))
+
+(defgeneric slack-room-buffer-name (room))
+
+(defun slack-room-find (id team)
+  (if (and id team)
+      (cl-labels ((find-room (room)
+                             (string= id (oref room id))))
+        (cond
+         ((string-prefix-p "F" id) (slack-file-room-obj team))
+         ((string-prefix-p "C" id) (cl-find-if #'find-room
+                                               (oref team channels)))
+         ((string-prefix-p "G" id) (cl-find-if #'find-room
+                                               (oref team groups)))
+         ((string-prefix-p "D" id) (cl-find-if #'find-room
+                                               (oref team ims)))
+         ((string-prefix-p "Q" id) (cl-find-if #'find-room
+                                               (oref team search-results)))))))
+
+(defun slack-reaction-create (payload)
+  (apply #'slack-reaction "reaction"
+         (slack-collect-slots 'slack-reaction payload)))
+
+(defun slack-attachment-create (payload)
+  (plist-put payload :fields
+             (mapcar #'(lambda (field) (apply #'slack-attachment-field
+                                              (slack-collect-slots 'slack-attachment-field field)))
+                     (append (plist-get payload :fields) nil)))
+  (if (numberp (plist-get payload :ts))
+      (plist-put payload :ts (number-to-string (plist-get payload :ts))))
+
+  (if (plist-get payload :is_share)
+      (apply #'slack-shared-message "shared-attachment"
+             (slack-collect-slots 'slack-shared-message payload))
+    (apply #'slack-attachment "attachment"
+           (slack-collect-slots 'slack-attachment payload))))
+
+(defmethod slack-message-set-attachments ((m slack-message) payload)
+  (let ((attachments (append (plist-get payload :attachments) nil)))
+    (if (< 0 (length attachments))
+        (oset m attachments
+              (mapcar #'slack-attachment-create attachments))))
+  m)
+
+(defmethod slack-message-set-file ((m slack-message) _payload _team)
+  m)
+
+(defmethod slack-message-set-file ((m slack-file-message) payload team)
+  (let ((file (slack-file-create (plist-get payload :file))))
+    (oset m file file)
+    (slack-file-set-channel file (plist-get payload :channel))
+    m))
+
+(defmethod slack-message-set-file-comment ((m slack-message) _payload)
+  m)
+
+(defmethod slack-message-set-thread ((m slack-message) team payload)
+  (when (slack-message-thread-parentp m)
+    (oset m thread (slack-thread-create m team payload))))
+
+(defun slack-reply-broadcast-message-create (payload)
+  (let ((parent (cl-first (plist-get payload :attachments))))
+    (plist-put payload :broadcast_thread_ts (plist-get parent :ts))
+    (apply #'slack-reply-broadcast-message "reply-broadcast"
+           (slack-collect-slots 'slack-reply-broadcast-message payload))))
+
+(cl-defun slack-message-create (payload team &key room)
+  (when payload
+    (plist-put payload :reactions (append (plist-get payload :reactions) nil))
+    (plist-put payload :attachments (append (plist-get payload :attachments) nil))
+    (plist-put payload :pinned_to (append (plist-get payload :pinned_to) nil))
+    (if room
+        (plist-put payload :channel (oref room id)))
+    (cl-labels
+        ((create-message
+          (payload)
+          (let ((subtype (plist-get payload :subtype)))
+            (cond
+             ((plist-member payload :reply_to)
+              (apply #'slack-reply "reply"
+                     (slack-collect-slots 'slack-reply payload)))
+             ((and subtype (string-equal "file_share" subtype))
+              (apply #'slack-file-share-message "file-share"
+                     (slack-collect-slots 'slack-file-share-message payload)))
+             ((and subtype (string-equal "file_comment" subtype))
+              (apply #'slack-file-comment-message "file-comment"
+                     (slack-collect-slots 'slack-file-comment-message payload)))
+             ((and subtype (string-equal "file_mention" subtype))
+              (apply #'slack-file-mention-message "file-mention"
+                     (slack-collect-slots 'slack-file-mention-message payload)))
+             ((or (and subtype (or (string-equal "reply_broadcast" subtype)
+                                   (string= "thread_broadcast" subtype)))
+                  (plist-get payload :reply_broadcast))
+              (slack-reply-broadcast-message-create payload))
+             ((and (plist-member payload :user) (plist-get payload :user))
+              (apply #'slack-user-message "user-msg"
+                     (slack-collect-slots 'slack-user-message payload)))
+             ((and subtype (string= "bot_message" subtype))
+              (apply #'slack-bot-message "bot-msg"
+                     (slack-collect-slots 'slack-bot-message payload)))))))
+
+      (let ((message (create-message payload)))
+        (when message
+          (slack-message-set-attachments message payload)
+          (oset message reactions
+                (mapcar #'slack-reaction-create (plist-get payload :reactions)))
+          (slack-message-set-file message payload team)
+          (slack-message-set-file-comment message payload)
+          (slack-message-set-thread message team payload)
+          message)))))
+
+(defmethod slack-message-equal ((m slack-message) n)
+  (string= (oref m ts) (oref n ts)))
+
+(defmethod slack-message-get-thread ((parent slack-message) team)
+  (let ((thread (oref parent thread)))
+    (unless thread
+      (oset parent thread (slack-thread-create parent team)))
+    (oref parent thread)))
+
+(defmethod slack-message-sender-name ((m slack-message) team)
+  (slack-user-name (oref m user) team))
+
+(defmethod slack-message-sender-id ((m slack-message))
+  (oref m user))
+
+(defun slack-message-pins-add ()
+  (interactive)
+  (slack-if-let* ((buf slack-current-buffer))
+      (slack-buffer-pins-add buf (slack-get-ts))))
+
+(defun slack-message-pins-remove ()
+  (interactive)
+  (slack-if-let* ((buf slack-current-buffer))
+      (slack-buffer-pins-remove buf (slack-get-ts))))
+
+(defun slack-message-pins-request (url room team ts)
+  (cl-labels ((on-pins-add
+               (&key data &allow-other-keys)
+               (slack-request-handle-error
+                (data "slack-message-pins-request"))))
+    (slack-request
+     (slack-request-create
+      url
+      team
+      :params (list (cons "channel" (oref room id))
+                    (cons "timestamp" ts))
+      :success #'on-pins-add
+      ))))
+
+(defmethod slack-ts ((this slack-message))
+  (oref this ts))
+
+(defun slack-ts-to-time (ts)
+  (seconds-to-time (string-to-number ts)))
+
+(defun slack-message-time-stamp (message)
+  (slack-ts-to-time (slack-ts message)))
+
+(defmethod slack-user-find ((m slack-message) team)
+  (slack-user--find (slack-message-sender-id m) team))
+
+(defun slack-message-copy-link ()
+  (interactive)
+  (slack-buffer-copy-link slack-current-buffer (slack-get-ts)))
+
+(defmethod slack-message-star-added ((m slack-message))
+  (oset m is-starred t))
+
+(defmethod slack-message-star-removed ((m slack-message))
+  (oset m is-starred nil))
+
+(defun slack-message-star-api-request (url params team)
+  (cl-labels
+      ((on-success (&key data &allow-other-keys)
+                   (slack-request-handle-error
+                    (data url))))
+    (slack-request
+     (slack-request-create
+      url
+      team
+      :params params
+      :success #'on-success))))
+
+(defun slack-message-remove-star ()
+  (interactive)
+  (slack-buffer-remove-star slack-current-buffer (slack-get-ts)))
+
+(defun slack-message-add-star ()
+  (interactive)
+  (slack-buffer-add-star slack-current-buffer (slack-get-ts)))
+
+(defmethod slack-message-star-api-params ((m slack-message))
+  (cons "timestamp" (oref m ts)))
+
+(defmethod slack-reaction-delete ((this slack-message) reaction)
+  (with-slots (reactions) this
+    (setq reactions (slack-reaction--delete reactions reaction))))
+
+(defmethod slack-reaction-push ((this slack-message) reaction)
+  (push reaction (oref this reactions)))
+
+(defmethod slack-reaction-find ((m slack-message) reaction)
+  (slack-reaction--find (oref m reactions) reaction))
+
+(defmethod slack-reaction-find ((m slack-file-message) reaction)
+  (slack-reaction-find (oref m file) reaction))
+
+(defmethod slack-message-reactions ((this slack-message))
+  (oref this reactions))
+
+(defmethod slack-message-reactions ((this slack-file-message))
+  (slack-message-reactions (oref this file)))
+
+(defmethod slack-message-get-param-for-reaction ((m slack-message))
+  (cons "timestamp" (oref m ts)))
+
+(defmethod slack-message-append-reaction ((m slack-message) reaction &optional _type)
+  (slack-if-let* ((old-reaction (slack-reaction-find m reaction)))
+      (slack-reaction-join old-reaction reaction)
+    (slack-reaction-push m reaction)))
+
+(defmethod slack-message-pop-reaction ((m slack-message) reaction &optional _type)
+  (slack-message--pop-reaction m reaction))
+
+(defun slack-message--pop-reaction (message reaction)
+  (let* ((old-reaction (slack-reaction-find message reaction))
+         (decl-p (< 1 (oref old-reaction count))))
+    (if decl-p
+        (with-slots (count users) old-reaction
+          (cl-decf count)
+          (setq users (cl-remove-if
+                       #'(lambda (old-user)
+                           (cl-find old-user
+                                    (oref reaction users)
+                                    :test #'string=))
+                       users)))
+      (slack-reaction-delete message reaction))))
+
+(defmacro slack-with-file-comment (id file &rest body)
+  (declare (indent 2) (debug t))
+  `(cl-loop for file-comment in (oref ,file comments)
+            do (when (string= ,id (oref file-comment id))
+                 ,@body)))
+
+(defmethod slack-message-get-text ((m slack-message))
+  (oref m text))
+
+(defmethod slack-thread-message-update-buffer ((message slack-message)
+                                               room team replace)
+  (slack-if-let* ((parent (slack-room-find-thread-parent room message)))
+      (progn
+        (slack-room-update-buffer room team parent t)
+        (if (slack-reply-broadcast-message-p message)
+            (slack-room-update-buffer room team message replace))
+        (slack-if-let* ((thread (slack-message-get-thread parent team)))
+            (progn
+              (slack-if-let* ((buf (slack-buffer-find 'slack-thread-message-buffer
+                                                      room
+                                                      (oref thread thread-ts)
+                                                      team)))
+                  (slack-buffer-update buf message :replace replace)))))))
+
+(defmethod slack-message-update ((message slack-message) team &optional replace no-notify)
+  (slack-if-let* ((room (slack-room-find (oref message channel) team)))
+      (progn
+        (slack-room-push-message room message)
+        (slack-room-update-latest room message)
+        (if (slack-thread-message-p message)
+            (slack-thread-message-update-buffer message room team replace)
+          (slack-room-update-buffer room team message replace)
+          (slack-room-inc-unread-count room))
+
+        (unless no-notify
+          (slack-message-notify message room team))
+        (slack-update-modeline))))
+
+(defun slack-message-delete ()
+  (interactive)
+  (slack-if-let* ((buf slack-current-buffer))
+      (slack-buffer-delete-message buf (slack-get-ts))))
+
+(defmethod slack-message-deleted ((message slack-message) room team)
+  (if (slack-thread-message-p message)
+      (slack-if-let* ((parent (slack-room-find-thread-parent room message))
+                      (thread (slack-message-get-thread parent team)))
+          (progn
+            (slack-thread-delete-message thread message)
+            (slack-if-let* ((buffer (slack-buffer-find 'slack-thread-message-buffer
+                                                       room
+                                                       (oref thread thread-ts)
+                                                       team)))
+                (slack-buffer-message-delete buffer (oref message ts)))
+            (slack-message-update parent team t)))
+    (slack-if-let* ((buf (slack-buffer-find 'slack-message-buffer
+                                            room
+                                            team)))
+        (slack-buffer-message-delete buf (oref message ts))))
+
+  (if slack-message-custom-delete-notifier
+      (funcall slack-message-custom-delete-notifier message room team)
+    (alert "message deleted"
+           :icon slack-alert-icon
+           :title (format "\\[%s] from %s"
+                          (slack-room-display-name room)
+                          (slack-message-sender-name message team))
+           :category 'slack)))
+
+(defmethod slack-message-changed--copy ((this slack-message) other)
+  (let ((changed nil))
+    (with-slots (text attachments edited-at) this
+      (unless (string= text (oref other text))
+        (setq text (oref other text))
+        (setq changed t))
+      (setq attachments (oref other attachments))
+      (setq edited-at (oref other edited-at)))
+    changed))
+
+(defmethod slack-thread-message-p ((this slack-message))
+  (and (oref this thread-ts)
+       (not (string= (oref this ts) (oref this thread-ts)))))
+
+(defmethod slack-thread-message-p ((this slack-reply-broadcast-message))
+  nil)
+
+(defmethod slack-message-thread-parentp ((m slack-message))
+  (let* ((thread (oref m thread))
+         (thread-ts (or (and thread (oref thread thread-ts))
+                        (oref m thread-ts))))
+    (and thread-ts (string= (oref m ts) thread-ts))))
+
+(defun slack-message-update-mark ()
+  "Update Channel's last-read marker to this message."
+  (interactive)
+  (slack-if-let* ((buffer slack-current-buffer))
+      (slack-buffer-update-mark buffer :force t)))
+
+(defun slack-message-inspect ()
+  (interactive)
+  (slack-if-let* ((ts (slack-get-ts))
+                  (buffer slack-current-buffer))
+      (with-slots (room team) buffer
+        (slack-if-let* ((message (slack-room-find-message room ts)))
+            (message "ROOM: %s\nMESSAGE: %s\nATTACHMENTS: %s - %s"
+                     (oref room id)
+                     (eieio-object-class message)
+                     (length (oref message attachments))
+                     (mapcar (lambda (e) (format "\n(TITLE: %s\nPRETEXT: %s\nTEXT: %s)"
+                                                 (slack-message-unescape-channel
+                                                  (oref e title)
+                                                  team)
+                                                 (oref e pretext)
+                                                 (oref e text)))
+                             (oref message attachments))
+                     )))))
+
+(provide 'slack-message)
+;;; slack-message.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message.elc
new file mode 100644
index 0000000000..a5c5b74d8d
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-message.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-pinned-item.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-pinned-item.el
new file mode 100644
index 0000000000..5b4f05e63e
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-pinned-item.el
@@ -0,0 +1,49 @@
+;;; slack-pinned-item.el ---                         -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2017
+
+;; Author:  <yuya373@yuya373>
+;; Keywords:
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'eieio)
+
+(defclass slack-pinned-item ()
+  ((message :initarg :message)))
+
+(defun slack-pinned-item-create (message)
+  (slack-pinned-item :message message))
+
+(defmethod slack-ts ((this slack-pinned-item))
+  (slack-ts (oref this message)))
+
+(defmethod slack-message-to-string ((this slack-pinned-item) team)
+  (with-slots (message) this
+    (cond
+     ((object-of-class-p message 'slack-file-comment)
+      (format "%s%s"
+              (slack-message-to-string message team)
+              (slack-file-link-info (oref message file-id) "\n(more info)\n")))
+     (t
+      (slack-message-to-string message team)))))
+
+(provide 'slack-pinned-item)
+;;; slack-pinned-item.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-pinned-item.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-pinned-item.elc
new file mode 100644
index 0000000000..5d51081dca
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-pinned-item.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-pinned-items-buffer.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-pinned-items-buffer.el
new file mode 100644
index 0000000000..e938e6a7dc
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-pinned-items-buffer.el
@@ -0,0 +1,105 @@
+;;; slack-pinned-items-buffer.el ---                 -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2017
+
+;; Author:  <yuya373@yuya373>
+;; Keywords:
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'eieio)
+(require 'slack-util)
+(require 'slack-room-buffer)
+
+(define-derived-mode slack-pinned-items-buffer-mode slack-buffer-mode "Slack Pinned Items")
+
+(defclass slack-pinned-items-buffer (slack-room-buffer)
+  ((items :initarg :items :type list)))
+
+(defmethod slack-buffer-name :static ((class slack-pinned-items-buffer) room team)
+  (format "%s %s" (call-next-method) "Pinned Items"))
+
+(defmethod slack-buffer-name ((this slack-pinned-items-buffer))
+  (with-slots (room team) this
+    (slack-buffer-name 'slack-pinned-items-buffer
+                       room team)))
+
+(defmethod slack-buffer-buffer ((this slack-pinned-items-buffer))
+  (slack-if-let* ((buf (get-buffer (slack-buffer-name this))))
+      (progn
+        (slack-pinned-items-buffer-insert-items this)
+        buf)
+    (slack-buffer-init-buffer this)))
+
+(defmethod slack-pinned-items-buffer-insert-items ((this slack-pinned-items-buffer))
+  (let* ((buf (get-buffer (slack-buffer-name this)))
+         (header-face '(:underline t :weight bold))
+         (buf-header (propertize "Pinned Items\n" 'face header-face)))
+    (with-current-buffer buf
+      (let ((inhibit-read-only t))
+        (delete-region (point-min) lui-output-marker))
+      (let ((lui-time-stamp-position nil))
+        (lui-insert buf-header t))
+      (with-slots (team items) this
+        (if (< 0 (length items))
+            (cl-loop for m in items
+                     do (slack-buffer-insert this m t))
+          (let ((inhibit-read-only t))
+            (insert "No Pinned Items")))))))
+
+(defmethod slack-buffer-init-buffer ((this slack-pinned-items-buffer))
+  (let* ((buf (call-next-method)))
+    (with-current-buffer buf
+      (slack-pinned-items-buffer-mode)
+      (slack-buffer-set-current-buffer this))
+    (slack-pinned-items-buffer-insert-items this)
+    (with-slots (room team) this
+      (slack-buffer-push-new-3 'slack-pinned-items-buffer room team))
+    buf))
+
+(defun slack-create-pinned-items-buffer (room team items)
+
+  (cl-labels
+      ((create-item
+        (item)
+        (let ((type (plist-get item :type)))
+          (slack-pinned-item-create
+           (cond
+            ((string= type "message")
+             (slack-message-create (plist-get item :message)
+                                   team :room room))
+            ((string= type "file")
+             (or (slack-file-find (plist-get (plist-get item :file) :id) team)
+                 (slack-file-create (plist-get item :file))))
+            ((string= type "file_comment")
+             (slack-file-comment-create (plist-get item :comment)
+                                        (plist-get (plist-get item :file) :id))))))))
+    (slack-if-let* ((buf (slack-buffer-find 'slack-pinned-items-buffer room team)))
+        (progn
+          (oset buf items (mapcar #'create-item items))
+          buf)
+      (slack-pinned-items-buffer :room room
+                                 :team team
+                                 :items (mapcar #'create-item items)))))
+
+
+
+(provide 'slack-pinned-items-buffer)
+;;; slack-pinned-items-buffer.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-pinned-items-buffer.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-pinned-items-buffer.elc
new file mode 100644
index 0000000000..4fbf431d5a
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-pinned-items-buffer.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-pkg.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-pkg.el
new file mode 100644
index 0000000000..ca6b444c4b
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-pkg.el
@@ -0,0 +1,11 @@
+(define-package "slack" "20180712.2222" "Slack client for Emacs"
+  '((websocket "1.8")
+    (request "0.2.0")
+    (oauth2 "0.10")
+    (circe "2.2")
+    (alert "1.2")
+    (emojify "0.2"))
+  :url "https://github.com/yuya373/emacs-slack")
+;; Local Variables:
+;; no-byte-compile: t
+;; End:
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-reaction.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-reaction.el
new file mode 100644
index 0000000000..d0cff1a803
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-reaction.el
@@ -0,0 +1,117 @@
+;;; slack-reaction.el ---  deal with reactions       -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2015  yuya.minami
+
+;; Author: yuya.minami <yuya.minami@yuyaminami-no-MacBook-Pro.local>
+;; Keywords:
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'eieio)
+
+(defclass slack-reaction ()
+  ((name :initarg :name :type string)
+   (count :initarg :count :type integer)
+   (users :initarg :users :initform ())))
+
+(defmethod slack-reaction-join ((r slack-reaction) other)
+  (if (string= (oref r name) (oref other name))
+      (progn
+        (cl-incf (oref r count))
+        (oset r users (append (oref other users) (oref r users)))
+        r)))
+
+(defmethod slack-reaction-user-names ((r slack-reaction) team)
+  (with-slots (users) r
+    (mapcar #'(lambda (u) (slack-user-name u team))
+            users)))
+
+(defmethod slack-equalp ((r slack-reaction) other)
+  (slack-reaction-equalp r other))
+
+(defmethod slack-reaction-equalp ((r slack-reaction) other)
+  (string= (oref r name) (oref other name)))
+
+(defmethod slack-reaction-help-text ((r slack-reaction) team)
+  (let ((user-names (slack-reaction-user-names r team)))
+    (format "%s reacted with :%s:"
+            (mapconcat #'identity user-names ", ")
+            (oref r name))))
+
+(defvar slack-reaction-keymap
+  (let ((keymap (make-sparse-keymap)))
+    (define-key keymap (kbd "RET") #'slack-reaction-toggle)
+    (define-key keymap [mouse-1] #'slack-reaction-toggle)
+    keymap))
+
+(defun slack-reaction-toggle ()
+  (interactive)
+  (slack-if-let* ((buffer slack-current-buffer)
+                  (reaction (get-text-property (point) 'reaction))
+                  (reaction-name (oref reaction name))
+                  (reaction-users (oref reaction users))
+                  (team (oref buffer team))
+                  (self-id (oref team self-id)))
+      (if (cl-find-if #'(lambda (id) (string= id self-id)) reaction-users)
+          (slack-message-reaction-remove reaction-name
+                                         (slack-get-ts)
+                                         (oref buffer room)
+                                         team)
+        (slack-message--add-reaction buffer reaction-name))))
+
+(defun slack-reaction-help-echo (_window _string pos)
+  (slack-if-let* ((buffer slack-current-buffer)
+                  (reaction (get-text-property pos 'reaction))
+                  (team (oref buffer team)))
+      (slack-reaction-help-text reaction team)))
+
+(defmethod slack-reaction-to-string ((r slack-reaction) team)
+  (propertize (format " :%s: %d " (oref r name) (oref r count))
+              'face 'slack-message-output-reaction
+              'mouse-face 'highlight
+              'keymap slack-reaction-keymap
+              'reaction r
+              'help-echo #'slack-reaction-help-echo))
+
+(defun slack-reaction-echo-description ()
+  (slack-if-let* ((buffer slack-current-buffer)
+                  (reaction (get-text-property (point) 'reaction))
+                  (team (oref buffer team)))
+      (message (slack-reaction-help-text reaction team))))
+
+(defun slack-reaction-notify (payload team room)
+  (let* ((user-id (plist-get payload :user))
+         (reaction (plist-get payload :reaction))
+         (msg (slack-user-message "msg"
+                                  :text (format "added reaction %s" reaction)
+                                  :user user-id)))
+    (slack-message-notify msg room team)))
+
+(defun slack-reaction--find (reactions reaction)
+  (cl-find-if #'(lambda (e) (slack-reaction-equalp e reaction))
+              reactions))
+
+(defun slack-reaction--delete (reactions reaction)
+  (cl-delete-if #'(lambda (e) (slack-reaction-equalp e reaction))
+                reactions))
+
+(provide 'slack-reaction)
+;;; slack-reaction.el ends here
+
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-reaction.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-reaction.elc
new file mode 100644
index 0000000000..220b289a5b
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-reaction.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-reminder.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-reminder.el
new file mode 100644
index 0000000000..9f8a8a49fa
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-reminder.el
@@ -0,0 +1,272 @@
+;;; slack-reminder.el ---                            -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2016  南優也
+
+;; Author: 南優也 <yuyaminami@minamiyuuya-no-MacBook.local>
+;; Keywords:
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'eieio)
+(require 'slack-room)
+(require 'slack-team)
+(require 'slack-request)
+
+(defconst slack-reminder-list-url "https://slack.com/api/reminders.list")
+(defconst slack-reminder-add-url "https://slack.com/api/reminders.add")
+(defconst slack-reminder-delete-url "https://slack.com/api/reminders.delete")
+(defconst slack-reminder-complete-url "https://slack.com/api/reminders.complete")
+(defconst slack-reminder-info-url "https://slack.com/api/reminders.info")
+
+(defclass slack-reminder-base ()
+  ((id :initarg :id :type string)
+   (creator :initarg :creator :type string)
+   (user :initarg :user :type string)
+   (text :initarg :text :type string)))
+
+(defclass slack-recurring-reminder (slack-reminder-base)
+  ())
+
+(defclass slack-reminder (slack-reminder-base)
+  ((time :initarg :time :type integer)
+   (complete-ts :initarg :complete_ts :type integer)))
+
+(defmethod slack-reminder-user ((r slack-reminder-base) team)
+  (slack-user-find r team))
+
+(defmethod slack-reminder-creator ((r slack-reminder-base) team)
+  (slack-user--find (oref r creator) team))
+
+(defmethod slack-team-add-reminder ((team slack-team) reminder)
+  (with-slots (reminders) team
+    (cl-pushnew reminder reminders
+                :test #'(lambda (a b) (string= (oref a id) (oref b id))))))
+
+(defmethod slack-reminder-completedp ((r slack-reminder))
+  (not (eq 0 (oref r complete-ts))))
+
+(defmethod slack-reminder-completedp ((_r slack-recurring-reminder))
+  nil)
+
+(defun slack-reminder-create (payload)
+  (let ((klass (if (eq :json-false (plist-get payload :recurring))
+                   'slack-reminder
+                 'slack-recurring-reminder)))
+    (apply #'make-instance klass
+           (slack-collect-slots klass payload))))
+
+(defun slack-reminder-add (&optional team)
+  (interactive)
+  (let* ((team (or team (slack-team-select)))
+         (user (slack-select-from-list
+                   ((slack-user-names team) "Select Target User: ")))
+         (time (read-from-minibuffer
+                "Time (Ex. \"in 15 minutes,\" or \"every Thursday\"): "))
+         (text (read-from-minibuffer "Text: ")))
+    (slack-reminder-request-add time text team user)))
+
+(defun slack-reminder-request-add (time text team &optional user)
+  (cl-labels
+      ((on-reminder-add (&key data &allow-other-keys)
+                        (slack-request-handle-error
+                         (data "slack-reminder-add")
+                         (let ((reminder (slack-reminder-create
+                                          (slack-decode
+                                           (plist-get data :reminder)))))
+                           (slack-team-add-reminder team reminder)
+                           (message "Reminder Created!")))))
+    (slack-request
+     (slack-request-create
+      slack-reminder-add-url
+      team
+      :params (list (cons "text" text)
+                    (cons "time" time)
+                    (and user (cons "user" (plist-get user :id))))
+      :success #'on-reminder-add))))
+
+(defmethod slack-reminder-to-body ((r slack-reminder))
+  (with-slots (text time complete-ts) r
+    (let ((time-str (format "Remind At: %s"
+                            (slack-message-time-to-string
+                             (number-to-string time))))
+          (completed (format "Completed: %s"
+                             (if (eq complete-ts 0)
+                                 "Not Yet"
+                               (slack-message-time-to-string
+                                (number-to-string complete-ts))))))
+      (format "%s\n%s\n\n%s" time-str completed text))))
+
+(defmethod slack-reminder-to-body ((r slack-recurring-reminder))
+  (oref r text))
+
+(defmethod slack-reminder-to-string ((r slack-reminder-base) team)
+  (with-slots (creator user) r
+    (let* ((header (slack-message-put-header-property
+                    (format "From: %s To: %s"
+                            (slack-user-name creator team)
+                            (slack-user-name user team))))
+           (body (slack-reminder-to-body r)))
+      (format "%s\n%s\n\n" header body))))
+
+(defmethod slack-create-reminder-buffer ((team slack-team))
+  (let* ((buf-name "*Slack - Reminders*")
+         (buf (get-buffer-create buf-name)))
+    (with-current-buffer buf
+      (setq buffer-read-only nil)
+      (erase-buffer)
+      (goto-char (point-min))
+      (with-slots (reminders) team
+        (cl-loop for reminder in reminders
+                 do (insert (slack-reminder-to-string reminder team))))
+      (setq buffer-read-only t))
+    buf))
+
+(defmethod slack-reminder-sort-key ((r slack-reminder))
+  (oref r time))
+
+(defmethod slack-reminder-sort-key ((r slack-recurring-reminder))
+  0)
+
+(defun slack-reminder-sort (team)
+  (with-slots (reminders) team
+    (setq reminders
+          (cl-sort reminders #'<
+                   :key #'(lambda (r) (slack-reminder-sort-key r))))))
+
+(defun slack-reminder-list ()
+  (interactive)
+  (let ((team (slack-team-select)))
+    (cl-labels
+        ((on-reminder-list
+          (&key data &allow-other-keys)
+          (slack-request-handle-error
+           (data "slack-reminder-list")
+           (oset team reminders
+                 (cl-loop
+                  for payload in (slack-decode
+                                  (append (plist-get data :reminders)
+                                          nil))
+                  collect (slack-reminder-create payload)))
+           (slack-reminder-sort team)
+           (if (< 0 (length (oref team reminders)))
+               (funcall
+                slack-buffer-function
+                (slack-create-reminder-buffer team))
+             (message "No Reminders!")))))
+      (slack-request
+       (slack-request-create
+        slack-reminder-list-url
+        team
+        :success #'on-reminder-list)))))
+
+(defmethod slack-reminders-alist ((team slack-team) &optional filter)
+  (cl-labels ((text (r)
+                    (with-slots (creator user text) r
+                      (format "Creator: %s Target: %s Content: %s"
+                              (slack-user-name creator team)
+                              (slack-user-name user team)
+                              text))))
+    (with-slots (reminders) team
+      (mapcar #'(lambda (r) (cons (text r) r))
+              (if filter
+                  (cl-remove-if-not #'(lambda (r) (funcall filter r))
+                                    reminders)
+                reminders)))))
+
+(defmethod slack-team-delete-reminder ((team slack-team) r)
+  (with-slots (reminders) team
+    (setq reminders
+          (cl-remove-if #'(lambda (e)
+                            (string= (oref e id) (oref r id)))
+                        reminders))))
+
+(defun slack-reminder-select (team &optional filter)
+  (slack-select-from-list
+      ((slack-reminders-alist team filter) "Select: ")))
+
+(defun slack-reminder-delete ()
+  (interactive)
+  (let* ((team (slack-team-select))
+         (reminder (slack-reminder-select team)))
+    (cl-labels
+        ((on-reminder-delete (&key data &allow-other-keys)
+                             (slack-request-handle-error
+                              (data "slack-reminder-delete")
+                              (slack-team-delete-reminder team reminder)
+                              (message "Reminder Deleted!"))))
+      (slack-request
+       (slack-request-create
+        slack-reminder-delete-url
+        team
+        :params (list (cons "reminder" (oref reminder id)))
+        :success #'on-reminder-delete)))))
+
+(defmethod slack-reminder-info ((r slack-reminder-base) team callback)
+  (cl-labels
+      ((on-reminder-info (&key data &allow-other-keys)
+                         (slack-request-handle-error
+                          (data "slack-reminder-info")
+                          (let ((reminder (slack-reminder-create
+                                           (plist-get (slack-decode data)
+                                                      :reminder))))
+                            (funcall callback reminder)))))
+    (slack-request
+     (slack-request-create
+      slack-reminder-info-url
+      team
+      :params (list (cons "reminder" (oref r id)))
+      :success #'on-reminder-info))))
+
+(defmethod slack-reminder-refresh ((r slack-reminder-base) team)
+  (slack-reminder-info
+   r team
+   #'(lambda (reminder)
+       (with-slots (reminders) team
+         (setq reminders
+               (cl-remove-if #'(lambda (e) (string= (oref e id)
+                                                    (oref reminder id)))
+                             reminders))
+         (push reminder reminders))
+       (message "Reminder Updated!"))))
+
+(defun slack-reminder-complete ()
+  (interactive)
+  (let* ((team (slack-team-select))
+         (reminder (slack-reminder-select
+                    team
+                    #'(lambda (r)
+                        (not (slack-reminder-completedp r))))))
+    (cl-labels
+        ((on-reminder-complete (&key data &allow-other-keys)
+                               (slack-request-handle-error
+                                (data "slack-reminder-complete")
+                                (slack-reminder-refresh reminder team))))
+      (slack-request
+       (slack-request-create
+        slack-reminder-complete-url
+        team
+        :params (list (cons "reminder" (oref reminder id)))
+        :success #'on-reminder-complete)))))
+
+(defmethod slack-user-find ((r slack-reminder-base) team)
+  (slack-user--find (oref r user) team))
+
+(provide 'slack-reminder)
+;;; slack-reminder.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-reminder.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-reminder.elc
new file mode 100644
index 0000000000..8f3f22c890
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-reminder.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-reply.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-reply.el
new file mode 100644
index 0000000000..27ae6533fe
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-reply.el
@@ -0,0 +1,49 @@
+;;; slack-reply.el ---handle reply from slack        -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2015  yuya.minami
+
+;; Author: yuya.minami <yuya.minami@yuyaminami-no-MacBook-Pro.local>
+;; Keywords:
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+(require 'eieio)
+(require 'slack-message)
+
+(defmethod slack-message-handle-reply ((m slack-reply) team)
+  (with-slots (reply-to) m
+    (let ((sent-msg (slack-message-find-sent m team)))
+      (if sent-msg
+          (progn
+            (oset sent-msg ts (oref m ts))
+            (slack-message-update sent-msg team))))))
+
+(defmethod slack-message-find-sent ((m slack-reply) team)
+  (with-slots (reply-to) m
+    (with-slots (sent-message) team
+      (let ((found (gethash reply-to sent-message)))
+        (remhash reply-to sent-message)
+        found))))
+
+(defmethod slack-message-sender-equalp ((m slack-reply) sender-id)
+  (string= (oref m user) sender-id))
+
+
+(provide 'slack-reply)
+;;; slack-reply.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-reply.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-reply.elc
new file mode 100644
index 0000000000..8f122a959b
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-reply.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-request-worker.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-request-worker.el
new file mode 100644
index 0000000000..13068f9480
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-request-worker.el
@@ -0,0 +1,143 @@
+;;; slack-request-worker.el ---                      -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2018  南優也
+
+;; Author: 南優也 <yuyaminami@minamiyuuya-no-MacBook.local>
+;; Keywords:
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'eieio)
+(require 'slack-util)
+(require 'slack-request)
+(require 'slack-team)
+
+(defcustom slack-request-worker-max-request-limit 30
+  "Max request count perform simultaneously."
+  :group 'slack)
+
+(defvar slack-request-worker-instance nil)
+
+(defclass slack-request-worker ()
+  ((queue :initform '() :type list)
+   (timer :initform nil)
+   (current-request-count :initform 0 :type integer)
+   ))
+
+(defun slack-request-worker-create ()
+  "Create `slack-request-worker' instance."
+  (make-instance 'slack-request-worker))
+
+(defmethod slack-request-worker-push ((this slack-request-worker) req)
+  (let ((l '()))
+    (cl-pushnew req (oref this queue)
+                :test #'slack-equalp)))
+
+(defun slack-request-worker-set-timer ()
+  (cl-labels
+      ((on-timeout ()
+                   (slack-request-worker-execute)
+                   (when (timerp slack-request-worker-instance)
+                     (cancel-timer slack-request-worker-instance))
+                   (slack-request-worker-set-timer)))
+    (oset slack-request-worker-instance timer
+          (run-at-time 1 nil #'on-timeout))))
+
+(defun slack-request-worker-execute ()
+  "Pop request from queue until `slack-request-worker-max-request-limit', and execute."
+  (when slack-request-worker-instance
+    (let ((do '())
+          (skip '())
+          (current (time-to-seconds))
+          (limit (- slack-request-worker-max-request-limit
+                    (oref slack-request-worker-instance
+                          current-request-count))))
+
+      (cl-loop for req in (reverse (oref slack-request-worker-instance queue))
+               do (if (and (< (oref req execute-at) current)
+                           (< (length do) limit))
+                      (push req do)
+                    (push req skip)))
+
+      ;; (message "[WORKER] QUEUE: %s, LIMIT: %s, CURRENT: %s, DO: %s, SKIP: %s"
+      ;;          (length (oref slack-request-worker-instance queue))
+      ;;          slack-request-worker-max-request-limit
+      ;;          (oref slack-request-worker-instance current-request-count)
+      ;;          (length do)
+      ;;          (length skip))
+
+      (oset slack-request-worker-instance queue skip)
+
+      (cl-labels
+          ((decl-request-count
+            ()
+            (cl-decf (oref slack-request-worker-instance
+                           current-request-count))))
+        (cl-loop for req in do
+                 do (progn
+                      (cl-incf (oref slack-request-worker-instance
+                                     current-request-count))
+                      (slack-request req
+                                     :on-success #'decl-request-count
+                                     :on-error #'decl-request-count
+                                     )))))))
+
+(defmethod slack-request-worker-push ((req slack-request-request))
+  (unless slack-request-worker-instance
+    (setq slack-request-worker-instance
+          (slack-request-worker-create)))
+  (slack-request-worker-push slack-request-worker-instance req)
+  (unless (oref slack-request-worker-instance timer)
+    (slack-request-worker-set-timer)))
+
+(defun slack-request-worker-quit ()
+  "Cancel timer and remove `slack-request-worker-instance'."
+  (when (and slack-request-worker-instance
+             (timerp (oref slack-request-worker-instance timer)))
+    (cancel-timer (oref slack-request-worker-instance timer)))
+  (setq slack-request-worker-instance nil))
+
+(defmethod slack-request-worker-remove-request ((team slack-team))
+  "Remove request from TEAM in queue."
+  (when slack-request-worker-instance
+    (let ((to-remove '())
+          (new-queue '())
+          (all (oref slack-request-worker-instance queue)))
+
+      (dolist (req all)
+        (if (string= (oref (oref req team) id)
+                     (oref team id))
+            (push req to-remove)
+          (push req new-queue)))
+
+      (dolist (req to-remove)
+        (when (and (oref req response)
+                   (not (request-response-done-p (oref req response))))
+          (request-abort (oref req response))))
+
+      (oset slack-request-worker-instance queue new-queue)
+      (slack-log (format "Remove Request from Worker, ALL: %s, REMOVED: %s, NEW-QUEUE: %s"
+                         (length all)
+                         (length to-remove)
+                         (length new-queue))
+                 team :level 'debug))))
+
+(provide 'slack-request-worker)
+;;; slack-request-worker.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-request-worker.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-request-worker.elc
new file mode 100644
index 0000000000..069a00cf3a
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-request-worker.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-request.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-request.el
new file mode 100644
index 0000000000..43c97face3
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-request.el
@@ -0,0 +1,162 @@
+;;; slack-request.el ---slack request function       -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2015  南優也
+
+;; Author: 南優也 <yuyaminami@minamiyuunari-no-MacBook-Pro.local>
+;; Keywords:
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'eieio)
+(require 'json)
+(require 'request)
+(require 'slack-util)
+
+(defcustom slack-request-timeout 10
+  "Request Timeout in seconds."
+  :group 'slack)
+
+(defun slack-parse ()
+  (let ((json-object-type 'plist)
+        (json-array-type 'list))
+    (json-read)))
+
+(defun slack-request-parse-payload (payload)
+  (let ((json-object-type 'plist)
+        (json-array-type 'list))
+    (condition-case err-var
+        (json-read-from-string payload)
+      (json-end-of-file nil))))
+
+(defclass slack-request-request ()
+  ((response :initform nil)
+   (url :initarg :url)
+   (team :initarg :team)
+   (type :initarg :type :initform "GET")
+   (success :initarg :success)
+   (error :initarg :error :initform nil)
+   (params :initarg :params :initform nil)
+   (data :initarg :data :initform nil)
+   (parser :initarg :parser :initform #'slack-parse)
+   (sync :initarg :sync :initform nil)
+   (files :initarg :files :initform nil)
+   (headers :initarg :headers :initform nil)
+   (timeout :initarg :timeout :initform `,slack-request-timeout)
+   (execute-at :initform 0.0 :type float)))
+
+(cl-defun slack-request-create
+    (url team &key type success error params data parser sync files headers timeout)
+  (let ((args (list
+               :url url :team team :type type
+               :success success :error error
+               :params params :data data :parser parser
+               :sync sync :files files :headers headers
+               :timeout timeout))
+        (ret nil))
+    (mapc #'(lambda (maybe-key)
+              (let ((value (plist-get args maybe-key)))
+                (when value
+                  (setq ret (plist-put ret maybe-key value)))))
+          args)
+    (apply #'make-instance 'slack-request-request ret)))
+
+(defmethod slack-equalp ((this slack-request-request) other)
+  (and (string= (oref (oref this team) id)
+                (oref (oref other team) id))
+       (string= "GET" (oref this type))
+       (string= "GET" (oref other type))
+       (string= (oref this url)
+                (oref other url))
+       (equalp (oref this params)
+               (oref other params))))
+
+(defmethod slack-request-retry-request ((req slack-request-request) retry-after team)
+  (oset req execute-at (+ retry-after (time-to-seconds)))
+  (slack-request-worker-push req))
+
+(cl-defmethod slack-request ((req slack-request-request)
+                             &key (on-success nil) (on-error nil))
+  (let ((team (oref req team)))
+    (with-slots (url type success error params data parser sync files headers timeout) req
+      (cl-labels
+          ((on-success (&key data &allow-other-keys)
+                       (funcall success :data data)
+                       (slack-log
+                        (format "Request Finished. URL: %s, PARAMS: %s"
+                                url
+                                params)
+                        team :level 'trace)
+                       (when (functionp on-success)
+                         (funcall on-success)))
+           (on-error (&key error-thrown symbol-status response data)
+                     (slack-if-let* ((retry-after (request-response-header response "retry-after"))
+                                     (retry-after-sec (string-to-number retry-after)))
+                         (progn
+                           (slack-request-retry-request req retry-after-sec team)
+                           (slack-log (format "Retrying Request After: %s second, URL: %s, PARAMS: %s"
+                                              retry-after-sec
+                                              url
+                                              params)
+                                      team))
+                       (slack-log (format "Request Failed. URL: %s, PARAMS: %s, ERROR-THROWN: %s, SYMBOL-STATUS: %s, DATA: %s"
+                                          url
+                                          params
+                                          error-thrown
+                                          symbol-status
+                                          data)
+                                  team
+                                  :level 'error)
+                       (when (functionp error)
+                         (funcall error
+                                  :error-thrown error-thrown
+                                  :symbol-status symbol-status
+                                  :response response
+                                  :data data))
+                       (when (functionp on-error)
+                         (funcall on-error)))))
+        (oset req response
+              (request
+               url
+               :type type
+               :sync sync
+               :params (cons (cons "token" (oref team token))
+                             params)
+               :data data
+               :files files
+               :headers headers
+               :parser parser
+               :success #'on-success
+               :error #'on-error
+               :timeout timeout))))))
+
+
+(cl-defmacro slack-request-handle-error ((data req-name &optional handler) &body body)
+  "Bind error to e if present in DATA."
+  `(if (eq (plist-get ,data :ok) :json-false)
+       (if ,handler
+           (funcall ,handler (plist-get ,data :error))
+         (message "Failed to request %s: %s"
+                  ,req-name
+                  (plist-get ,data :error)))
+     (progn
+       ,@body)))
+
+(provide 'slack-request)
+;;; slack-request.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-request.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-request.elc
new file mode 100644
index 0000000000..9779eb7746
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-request.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-room-buffer.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-room-buffer.el
new file mode 100644
index 0000000000..ab03be7ea1
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-room-buffer.el
@@ -0,0 +1,107 @@
+;;; slack-room-buffer.el ---                         -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2017
+
+;; Author:  <yuya373@yuya373>
+;; Keywords:
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'eieio)
+(require 'slack-util)
+(require 'slack-buffer)
+(require 'slack-request)
+
+(defconst slack-message-delete-url "https://slack.com/api/chat.delete")
+(defconst slack-get-permalink-url "https://slack.com/api/chat.getPermalink")
+
+(defclass slack-room-buffer (slack-buffer)
+  ((room :initarg :room :type slack-room)))
+
+(defmethod slack-buffer-name :static ((class slack-room-buffer) room team)
+  (slack-if-let* ((room-name (slack-room-name room)))
+      (format  "*Slack - %s : %s"
+               (oref team name)
+               room-name)))
+
+(defmethod slack-buffer-name ((this slack-room-buffer))
+  (with-slots (room team) this
+    (slack-buffer-name (eieio-object-class-name this) room team)))
+
+(defmethod slack-buffer-delete-message ((this slack-room-buffer) ts)
+  (with-slots (room team) this
+    (slack-if-let* ((message (slack-room-find-message room ts)))
+        (cl-labels
+            ((on-delete
+              (&key data &allow-other-keys)
+              (slack-request-handle-error
+               (data "slack-message-delete"))))
+          (if (yes-or-no-p "Are you sure you want to delete this message?")
+              (slack-request
+               (slack-request-create
+                slack-message-delete-url
+                team
+                :type "POST"
+                :params (list (cons "ts" (oref message ts))
+                              (cons "channel" (oref room id)))
+                :success #'on-delete))
+            (message "Canceled"))))))
+
+(defmethod slack-buffer-message-delete ((this slack-room-buffer) ts)
+  (let ((buffer (slack-buffer-buffer this)))
+    (with-current-buffer buffer
+      (lui-delete #'(lambda () (equal (get-text-property (point) 'ts)
+                                      ts))))))
+
+(defmethod slack-buffer-copy-link ((this slack-room-buffer) ts)
+  (with-slots (room team) this
+    (slack-if-let* ((message (slack-room-find-message room ts))
+                    (template "https://%s.slack.com/archives/%s/p%s%s"))
+        (cl-labels
+            ((on-success (&key data &allow-other-keys)
+                         (slack-request-handle-error
+                          (data "slack-get-permalink")
+                          (let ((permalink (plist-get data :permalink)))
+                            (kill-new permalink)
+                            (message "Link Copied to Clipboard")))))
+          (slack-request
+           (slack-request-create
+            slack-get-permalink-url
+            team
+            :type "POST"
+            :params (list (cons "channel" (oref room id))
+                          (cons "message_ts" ts))
+            :success #'on-success))))))
+
+(defmethod slack-buffer--replace ((this slack-room-buffer) ts)
+  (with-slots (room) this
+    (slack-if-let* ((message (slack-room-find-message room ts)))
+        (slack-buffer-replace this message))))
+
+(defmethod slack-buffer-toggle-email-expand ((this slack-room-buffer) ts)
+  (with-slots (room) this
+    (slack-if-let* ((message (slack-room-find-message room ts)))
+        (progn
+          (with-slots (file) message
+            (oset file is-expanded (not (oref file is-expanded))))
+          (slack-buffer-update this message :replace t)))))
+
+(provide 'slack-room-buffer)
+;;; slack-room-buffer.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-room-buffer.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-room-buffer.elc
new file mode 100644
index 0000000000..e424d8bfb1
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-room-buffer.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-room-message-compose-buffer.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-room-message-compose-buffer.el
new file mode 100644
index 0000000000..b826b2b83a
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-room-message-compose-buffer.el
@@ -0,0 +1,69 @@
+;;; slack-room-message-compose-buffer.el ---              -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2017
+
+;; Author:  <yuya373@yuya373>
+;; Keywords:
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'eieio)
+(require 'slack-util)
+(require 'slack-message-compose-buffer)
+
+(defclass slack-room-message-compose-buffer (slack-message-compose-buffer)
+  ((room :initarg :room type slack-room)))
+
+(defun slack-create-room-message-compose-buffer (room team)
+  (slack-if-let* ((buf (slack-buffer-find 'slack-room-message-compose-buffer
+                                    room team)))
+      buf
+    (slack-room-message-compose-buffer :room room :team team)))
+
+(defmethod slack-buffer-name :static ((class slack-room-message-compose-buffer) room team)
+  (format "*Slack - %s : %s Compose Message"
+          (oref team name)
+          (slack-room-name room)))
+
+(defmethod slack-buffer-name ((this slack-room-message-compose-buffer))
+  (with-slots (room team) this
+    (slack-buffer-name (eieio-object-class-name this)
+                       room team)))
+
+(defmethod slack-buffer-init-buffer ((this slack-room-message-compose-buffer))
+  (let* ((buf (call-next-method)))
+    (with-current-buffer buf
+      (setq buffer-read-only nil)
+      (erase-buffer)
+      (message "C-c C-c to send edited msg"))
+    (with-slots (room team) this
+      (slack-buffer-push-new-3 'slack-room-message-compose-buffer
+                               room team))
+    buf))
+
+(defmethod slack-buffer-send-message ((this slack-room-message-compose-buffer) message)
+  (let ((buffer (slack-buffer-buffer this)))
+    (with-slots (room team) this
+      (slack-message-send-internal message (oref room id) team)
+      (call-next-method))))
+
+
+(provide 'slack-room-message-compose-buffer)
+;;; slack-room-message-compose-buffer.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-room-message-compose-buffer.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-room-message-compose-buffer.elc
new file mode 100644
index 0000000000..0d4d2f7761
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-room-message-compose-buffer.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-room.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-room.el
new file mode 100644
index 0000000000..b547fe4b7f
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-room.el
@@ -0,0 +1,501 @@
+;;; slack-room.el --- slack generic room interface    -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2015  南優也
+
+;; Author: 南優也 <yuyaminami@minamiyuunari-no-MacBook-Pro.local>
+;; Keywords:
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'eieio)
+(require 'lui)
+(require 'slack-util)
+(require 'slack-request)
+(require 'slack-message)
+(require 'slack-pinned-item)
+
+(defvar slack-buffer-function)
+(defconst slack-room-pins-list-url "https://slack.com/api/pins.list")
+
+(defclass slack-room ()
+  ((name :initarg :name :type (or null string) :initform nil)
+   (id :initarg :id)
+   (created :initarg :created)
+   (latest :initarg :latest)
+   (unread-count :initarg :unread_count :initform 0 :type integer)
+   (unread-count-display :initarg :unread_count_display :initform 0 :type integer)
+   (messages :initarg :messages :initform ())
+   (team-id :initarg :team-id)
+   (last-read :initarg :last_read :type string :initform "0")))
+
+(defgeneric slack-room-name (room))
+(defgeneric slack-room-history (room team &optional oldest after-success sync))
+(defgeneric slack-room-update-mark-url (room))
+
+(defmethod slack-equalp ((this slack-room) other)
+  (string= (oref this id)
+           (oref other id)))
+
+(defmethod slack-merge ((this slack-room) other)
+  "except MESSAGES"
+  (oset this name (oref other name))
+  (oset this id (oref other id))
+  (oset this created (oref other created))
+  (oset this latest (oref other latest))
+  (oset this unread-count (oref other unread-count))
+  (oset this unread-count-display (oref other unread-count-display))
+  (oset this team-id (oref other team-id))
+  (unless (string= "0" (oref other last-read))
+    (oset this last-read (oref other last-read))))
+
+(defun slack-room-create (payload team class)
+  (cl-labels
+      ((prepare (p)
+                (plist-put p :members
+                           (append (plist-get p :members) nil))
+                (plist-put p :team-id (oref team id))
+                p))
+    (let* ((attributes (slack-collect-slots class (prepare payload)))
+           (room (apply #'make-instance class attributes)))
+      (oset room latest (slack-message-create (plist-get payload :latest) team :room room))
+      room)))
+
+(defmethod slack-room-subscribedp ((_room slack-room) _team)
+  nil)
+
+(defmethod slack-room-buffer-name ((room slack-room))
+  (concat "*Slack*"
+          " : "
+          (slack-room-display-name room)))
+
+(cl-defmacro slack-select-from-list ((alist prompt &key initial) &body body)
+  "Bind candidates from selected."
+  (declare (indent 2) (debug t))
+  (let ((key (cl-gensym)))
+    `(let* ((,key (let ((completion-ignore-case t))
+                    (funcall slack-completing-read-function (format "%s" ,prompt)
+                             ,alist nil t ,initial)))
+            (selected (cdr (cl-assoc ,key ,alist :test #'string=))))
+       ,@body
+       selected)))
+
+(defmethod slack-room-hidden-p ((room slack-room))
+  (slack-room-hiddenp room))
+
+(defun slack-room-hiddenp (room)
+  (or (not (slack-room-member-p room))
+      (slack-room-archived-p room)
+      (not (slack-room-open-p room))))
+
+(defmacro slack-room-names (rooms &optional filter)
+  `(cl-labels
+       ((latest-ts (room)
+                   (with-slots (latest) room
+                     (if latest (oref latest ts) "0")))
+        (sort-rooms (rooms)
+                    (nreverse
+                     (cl-sort rooms #'string<
+                              :key #'(lambda (name-with-room) (latest-ts (cdr name-with-room)))))))
+     (sort-rooms
+      (cl-loop for room in (if ,filter
+                               (funcall ,filter ,rooms)
+                             ,rooms)
+               collect (cons (slack-room-label room) room)))))
+
+(defun slack-room-select (rooms)
+  (let* ((alist (slack-room-names
+                 rooms #'(lambda (rs) (cl-remove-if #'slack-room-hidden-p rs)))))
+    (slack-select-from-list (alist "Select Channel: "))))
+
+(cl-defun slack-room-list-update (url success team &key (sync t))
+  (slack-request
+   (slack-request-create
+    url
+    team
+    :success success)))
+
+(defun slack-room-find-message (room ts)
+  (cl-find-if #'(lambda (m) (string= ts (oref m ts)))
+              (oref room messages)
+              :from-end t))
+
+(defun slack-room-find-thread-parent (room thread-message)
+  (slack-room-find-message room (oref thread-message thread-ts)))
+
+(defmethod slack-message-thread ((this slack-message) _room)
+  (oref this thread))
+
+(defmethod slack-message-thread ((this slack-reply-broadcast-message) room)
+  (let ((message (slack-room-find-message room
+                                          (or (oref this broadcast-thread-ts)
+                                              (oref this thread-ts)))))
+    (slack-message-thread message room)))
+
+(defun slack-room-find-thread (room ts)
+  (let ((message (slack-room-find-message room ts)))
+    (when message
+      (slack-message-thread message room))))
+
+(defmethod slack-room-team ((room slack-room))
+  (slack-team-find (oref room team-id)))
+
+(defmethod slack-room-display-name ((room slack-room))
+  (let ((room-name (slack-room-name room)))
+    (if slack-display-team-name
+        (format "%s - %s"
+                (oref (slack-room-team room) name)
+                room-name)
+      room-name)))
+
+(defmethod slack-room-label-prefix ((_room slack-room))
+  "  ")
+
+(defmethod slack-room-unread-count-str ((room slack-room))
+  (with-slots (unread-count-display) room
+    (if (< 0 unread-count-display)
+        (concat " ("
+                (number-to-string unread-count-display)
+                ")")
+      "")))
+
+(defmethod slack-room-label ((room slack-room))
+  (format "%s%s%s"
+          (slack-room-label-prefix room)
+          (slack-room-display-name room)
+          (slack-room-unread-count-str room)))
+
+(defmethod slack-room-name ((room slack-room))
+  (oref room name))
+
+(defun slack-room-sort-messages (messages)
+  (cl-sort messages
+           #'string<
+           :key #'(lambda (m) (oref m ts))))
+
+(defun slack-room-reject-thread-message (messages)
+  (cl-remove-if #'(lambda (m) (and (not (eq (eieio-object-class-name m)
+                                            'slack-reply-broadcast-message))
+                                   (slack-thread-message-p m)))
+                messages))
+
+(defmethod slack-room-sorted-messages ((room slack-room))
+  (with-slots (messages) room
+    (slack-room-sort-messages (copy-sequence messages))))
+
+(defmethod slack-room-set-prev-messages ((room slack-room) prev-messages)
+  (slack-room-set-messages room
+                           (append (oref room messages)
+                                   prev-messages)))
+
+(defmethod slack-room-append-messages ((room slack-room) messages)
+  (slack-room-set-messages room
+                           (append messages (oref room messages))))
+
+(defmethod slack-room-update-latest ((room slack-room) message)
+  (when (and message
+             (not (slack-thread-message-p message)))
+    (with-slots (latest) room
+      (if (or (null latest)
+              (string< (oref latest ts) (oref message ts)))
+          (setq latest message)))))
+
+(defmethod slack-room-push-message ((room slack-room) message)
+  (with-slots (messages) room
+    (setq messages
+          (cl-remove-if #'(lambda (n) (slack-message-equal message n))
+                        messages))
+    (push message messages)))
+
+(defmethod slack-room-set-messages ((room slack-room) messages)
+  (let* ((sorted (slack-room-sort-messages
+                  (cl-delete-duplicates messages
+                                        :test #'slack-message-equal)))
+         (oldest (car sorted))
+         (latest (car (last sorted))))
+    (oset room messages sorted)
+    (slack-room-update-latest room latest)))
+
+(defmethod slack-room-prev-messages ((room slack-room) from)
+  (with-slots (messages) room
+    (cl-remove-if #'(lambda (m)
+                      (or (string< from (oref m ts))
+                          (string= from (oref m ts))))
+                  (slack-room-sort-messages (copy-sequence messages)))))
+
+(defmethod slack-room-update-mark ((room slack-room) team ts)
+  (cl-labels ((on-update-mark (&key data &allow-other-keys)
+                              (slack-request-handle-error
+                               (data "slack-room-update-mark"))))
+    (with-slots (id) room
+      (slack-request
+       (slack-request-create
+        (slack-room-update-mark-url room)
+        team
+        :type "POST"
+        :params (list (cons "channel"  id)
+                      (cons "ts"  ts))
+        :success #'on-update-mark)))))
+
+(defun slack-room-pins-list ()
+  (interactive)
+  (slack-if-let* ((buf slack-current-buffer))
+      (slack-buffer-display-pins-list buf)))
+
+(defun slack-select-rooms ()
+  (interactive)
+  (let* ((team (slack-team-select))
+         (room (slack-room-select
+                (cl-loop for team in (list team)
+                         append (with-slots (groups ims channels) team
+                                  (append ims groups channels))))))
+    (slack-room-display room team)))
+
+(defun slack-create-room (url team success)
+  (slack-request
+   (slack-request-create
+    url
+    team
+    :type "POST"
+    :params (list (cons "name" (read-from-minibuffer "Name: ")))
+    :success success)))
+
+(defun slack-room-rename (url room-alist-func)
+  (cl-labels
+      ((on-rename-success (&key data &allow-other-keys)
+                          (slack-request-handle-error
+                           (data "slack-room-rename"))))
+    (let* ((team (slack-team-select))
+           (room-alist (funcall room-alist-func team))
+           (room (slack-select-from-list
+                     (room-alist "Select Channel: ")))
+           (name (read-from-minibuffer "New Name: ")))
+      (slack-request
+       (slack-request-create
+        url
+        team
+        :params (list (cons "channel" (oref room id))
+                      (cons "name" name))
+        :success #'on-rename-success)))))
+
+(defmacro slack-current-room-or-select (room-alist-func &optional select)
+  `(if (and (not ,select)
+            (bound-and-true-p slack-current-buffer)
+            (slot-boundp slack-current-buffer 'room))
+       (oref slack-current-buffer room)
+     (let* ((room-alist (funcall ,room-alist-func)))
+       (slack-select-from-list
+           (room-alist "Select Channel: ")))))
+
+(defmacro slack-room-invite (url room-alist-func)
+  `(cl-labels
+       ((on-group-invite (&key data &allow-other-keys)
+                         (slack-request-handle-error
+                          (data "slack-room-invite")
+                          (if (plist-get data :already_in_group)
+                              (message "User already in group")
+                            (message "Invited!")))))
+     (let* ((team (slack-team-select))
+            (room (slack-current-room-or-select
+                   #'(lambda ()
+                       (funcall ,room-alist-func team
+                                #'(lambda (rooms)
+                                    (cl-remove-if #'slack-room-archived-p
+                                                  rooms))))))
+            (user-id (plist-get (slack-select-from-list
+                                    ((slack-user-names team)
+                                     "Select User: ")) :id)))
+       (slack-request
+        (slack-request-create
+         ,url
+         team
+         :params (list (cons "channel" (oref room id))
+                       (cons "user" user-id))
+         :success #'on-group-invite)))))
+
+(defmethod slack-room-member-p ((_room slack-room)) t)
+
+(defmethod slack-room-archived-p ((_room slack-room)) nil)
+
+(defmethod slack-room-open-p ((_room slack-room)) t)
+
+(defmethod slack-room-equal-p ((room slack-room) other)
+  (string= (oref room id) (oref other id)))
+
+(defun slack-room-deleted (id team)
+  (let ((room (slack-room-find id team)))
+    (cond
+     ((object-of-class-p room 'slack-channel)
+      (with-slots (channels) team
+        (setq channels (cl-delete-if #'(lambda (c) (slack-room-equal-p room c))
+                                     channels)))
+      (message "Channel: %s deleted"
+               (slack-room-display-name room))))))
+
+(cl-defun slack-room-request-with-id (url id team success)
+  (slack-request
+   (slack-request-create
+    url
+    team
+    :params (list (cons "channel" id))
+    :success success)))
+
+(defmethod slack-room-inc-unread-count ((room slack-room))
+  (cl-incf (oref room unread-count-display)))
+
+(defun slack-room-find-by-name (name team)
+  (cl-labels
+      ((find-by-name (rooms name)
+                     (cl-find-if #'(lambda (e) (string= name
+                                                        (slack-room-name e)))
+                                 rooms)))
+    (or (find-by-name (oref team groups) name)
+        (find-by-name (oref team channels) name)
+        (find-by-name (oref team ims) name))))
+
+(defmethod slack-room-info-request-params ((room slack-room))
+  (list (cons "channel" (oref room id))))
+
+(defmethod slack-room-create-info-request ((room slack-room) team)
+  (cl-labels
+      ((on-success
+        (&key data &allow-other-keys)
+        (slack-request-handle-error
+         (data "slack-room-info-request"
+               #'(lambda (e)
+                   (if (not (string= e "user_disabled"))
+                       (message "Failed to request slack-room-info-request: %s" e))))
+         (slack-room-update-info room data team))))
+    (slack-request-create
+     (slack-room-get-info-url room)
+     team
+     :params (slack-room-info-request-params room)
+     :success #'on-success)))
+
+(defmethod slack-room-info-request ((room slack-room) team)
+  (slack-request
+   (slack-room-create-info-request room team)))
+
+(defmethod slack-room-get-members ((room slack-room))
+  (oref room members))
+
+(defun slack-room-user-select ()
+  (interactive)
+  (slack-if-let* ((buf slack-current-buffer))
+      (slack-buffer-display-user-profile buf)))
+
+(defun slack-select-unread-rooms ()
+  (interactive)
+  (let* ((team (slack-team-select))
+         (room (slack-room-select
+                (cl-loop for team in (list team)
+                         append (with-slots (groups ims channels) team
+                                  (cl-remove-if
+                                   #'(lambda (room)
+                                       (not (< 0 (oref room
+                                                       unread-count-display))))
+                                   (append ims groups channels)))))))
+    (slack-room-display room team)))
+
+(defmethod slack-user-find ((room slack-room) team)
+  (slack-user--find (oref room user) team))
+
+(defun slack-room-find-file-comment-message (room comment-id)
+  (let ((messages (oref room messages)))
+    (cl-find-if #'(lambda (m) (and
+                               (object-of-class-p m 'slack-file-message)
+                               (or
+                                (and (slack-file-share-message-p m)
+                                     (oref (oref m file) initial-comment)
+                                     (string= comment-id
+                                              (oref (oref
+                                                     (oref m file)
+                                                     initial-comment)
+                                                    id)))
+                                (and
+                                 (slot-exists-p m 'comment)
+                                 (slot-boundp m 'comment)
+                                 (string= comment-id (oref (oref m comment) id))))))
+                messages)))
+
+(defun slack-room-find-file-share-message (room file-id)
+  (let ((messages (oref room messages)))
+    (cl-find-if #'(lambda (m) (and (slack-file-share-message-p m)
+                                   (slot-exists-p m 'file)
+                                   (slot-boundp m 'file)
+                                   (string= file-id (oref (oref m file) id))))
+                messages)))
+
+(defun slack-room-display (room team)
+  (cl-labels
+      ((open (buf)
+             (slack-buffer-display buf)))
+    (let* ((buf (slack-buffer-find (or (and (eq (eieio-object-class-name room)
+                                                'slack-file-room)
+                                            'slack-file-list-buffer)
+                                       'slack-message-buffer)
+                                   room team)))
+      (if buf (open buf)
+        (message "No Message in %s, fetching from server..." (slack-room-name room))
+        (slack-room-history-request
+         room team
+         :after-success #'(lambda (&rest _ignore)
+                            (open (slack-create-message-buffer room team))))))))
+
+(defmethod slack-room-update-buffer ((this slack-room) team message replace)
+  (slack-if-let* ((buffer (slack-buffer-find 'slack-message-buffer this team)))
+      (slack-buffer-update buffer message :replace replace)
+    (and slack-buffer-create-on-notify
+         (slack-room-history-request
+          this team
+          :after-success #'(lambda (&rest _ignore)
+                             (tracking-add-buffer
+                              (slack-buffer-buffer
+                               (slack-create-message-buffer this team))))))))
+
+(cl-defmethod slack-room-history-request ((room slack-room) team &key oldest latest count after-success async)
+  (cl-labels
+      ((on-request-update
+        (&key data &allow-other-keys)
+        (slack-request-handle-error
+         (data "slack-room-request-update")
+         (let ((messages
+                 (cl-loop for message in (plist-get data :messages)
+                          collect (slack-message-create message team :room room)))
+               (has-more (not (eq :json-false (plist-get data :has_more)))))
+           (if oldest (slack-room-set-prev-messages room messages)
+             (if latest (slack-room-append-messages room messages)
+               (slack-room-set-messages room messages)))
+           (if (and after-success (functionp after-success))
+               (funcall after-success has-more))))))
+    (slack-request
+     (slack-request-create
+      (slack-room-history-url room)
+      team
+      :params (list (cons "channel" (oref room id))
+                    (if oldest (cons "latest" oldest))
+                    (if latest (cons "oldest" latest))
+                    (cons "count" (number-to-string (or count 100))))
+      :success #'on-request-update))))
+
+(defmethod slack-room-member-p ((this slack-room))
+  t)
+
+(provide 'slack-room)
+;;; slack-room.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-room.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-room.elc
new file mode 100644
index 0000000000..88dc36049b
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-room.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-search-result-buffer.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-search-result-buffer.el
new file mode 100644
index 0000000000..a24792ff25
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-search-result-buffer.el
@@ -0,0 +1,129 @@
+;;; slack-search-result-buffer.el ---                -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2017
+
+;; Author:  <yuya373@yuya373>
+;; Keywords:
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'eieio)
+(require 'slack-util)
+(require 'slack-buffer)
+
+(define-derived-mode slack-search-result-buffer-mode slack-buffer-mode "Slack Search Result"
+  (remove-hook 'lui-post-output-hook 'slack-display-image t))
+
+(defclass slack-search-result-buffer (slack-buffer)
+  ((search-result :initarg :search-result :type slack-search-result)))
+
+(defmethod slack-buffer-name :static ((class slack-search-result-buffer) search-result team)
+  (with-slots (query sort sort-dir) search-result
+    (format "*Slack - %s : Search Result - QUERY: %s, ORDER BY: %s %s"
+            (oref team name)
+            query
+            sort
+            (upcase sort-dir))))
+
+(defmethod slack-buffer-name ((this slack-search-result-buffer))
+  (with-slots (search-result team) this
+    (slack-buffer-name (eieio-object-class-name this) search-result team)))
+
+(defun slack-create-search-result-buffer (search-result team)
+  (slack-if-let* ((buffer (slack-buffer-find 'slack-search-result-buffer
+                                             search-result
+                                             team)))
+      buffer
+    (make-instance 'slack-search-result-buffer
+                   :team team
+                   :search-result search-result)))
+
+(defmethod slack-buffer-insert ((this slack-search-result-buffer) match)
+  (with-slots (team) this
+    (let* ((time (slack-ts-to-time (slack-ts match)))
+           (lui-time-stamp-time time)
+           (lui-time-stamp-format "[%Y-%m-%d %H:%M:%S]"))
+      (lui-insert (slack-message-to-string match team) t)
+      (lui-insert "" t))))
+
+(defmethod slack-buffer-has-next-page-p ((this slack-search-result-buffer))
+  (with-slots (search-result) this
+    (slack-search-has-next-page-p search-result)))
+
+(defmethod slack-buffer-insert-history ((this slack-search-result-buffer))
+  (with-slots (team search-result) this
+    (let* ((paging (oref search-result paging))
+           (per-page (oref paging count))
+           (matches (last (oref search-result matches) per-page))
+           (cur-point (point)))
+      (cl-loop for match in matches
+               do (slack-buffer-insert this match))
+      (goto-char cur-point))))
+
+(defmethod slack-buffer-request-history ((this slack-search-result-buffer) after-success)
+  (with-slots (team search-result) this
+    (slack-search-request search-result after-success team
+                          (slack-search-paging-next-page
+                           (oref search-result paging)))))
+
+(defmethod slack-buffer-init-buffer ((this slack-search-result-buffer))
+  (let ((buffer (generate-new-buffer (slack-buffer-name this))))
+    (with-current-buffer buffer
+      (slack-search-result-buffer-mode)
+      (slack-buffer-set-current-buffer this)
+      (with-slots (search-result) this
+        (let* ((messages (oref search-result matches)))
+          (cl-loop for m in messages
+                   do (slack-buffer-insert this m)))
+        (let ((lui-time-stamp-position nil))
+          (if (slack-search-has-next-page-p search-result)
+              (slack-buffer-insert-load-more this)))))
+
+    (with-slots (search-result team) this
+      (slack-buffer-push-new-3 'slack-search-result-buffer
+                               search-result
+                               team))
+    buffer))
+
+(defmethod slack-buffer-loading-message-end-point ((this slack-search-result-buffer))
+  (previous-single-property-change (point-max)
+                                   'loading-message))
+
+(defmethod slack-buffer-delete-load-more-string ((this slack-search-result-buffer))
+  (let* ((inhibit-read-only t)
+         (loading-message-end
+          (slack-buffer-loading-message-end-point this))
+         (loading-message-start
+          (previous-single-property-change loading-message-end
+                                           'loading-message)))
+    (delete-region loading-message-start
+                   loading-message-end)))
+
+(defmethod slack-buffer-prepare-marker-for-history ((_this slack-search-result-buffer)))
+
+(defmethod slack-buffer-insert--history ((this slack-search-result-buffer))
+  (slack-buffer-insert-history this)
+  (if (slack-buffer-has-next-page-p this)
+      (slack-buffer-insert-load-more this)
+    (let ((lui-time-stamp-position nil))
+      (lui-insert "(no more messages)\n"))))
+
+(provide 'slack-search-result-buffer)
+;;; slack-search-result-buffer.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-search-result-buffer.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-search-result-buffer.elc
new file mode 100644
index 0000000000..ea38b58bc3
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-search-result-buffer.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-search.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-search.el
new file mode 100644
index 0000000000..2bea54ccc9
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-search.el
@@ -0,0 +1,418 @@
+;;; slack-search.el ---                              -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2016  南優也
+
+;; Author: 南優也 <yuyaminami@minamiyuunari-no-MacBook-Pro.local>
+;; Keywords:
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'eieio)
+(require 'slack-room)
+(require 'slack-request)
+
+(defface slack-search-result-message-header-face
+  '((t (:weight bold :height 1.1 :underline t)))
+  "Face used to search message header."
+  :group 'slack)
+;; (:inherit (markdown-code-face font-lock-constant-face))
+(defface slack-search-result-message-username-face
+  '((t (:inherit slack-message-output-header :underline nil)))
+  ""
+  :group 'slack)
+
+(defclass slack-search-paging ()
+  ((count :initarg :count :type number)
+   (total :initarg :total :type number)
+   (page :initarg :page :type number)
+   (pages :initarg :pages :type number)))
+
+(defclass slack-search-result (slack-room)
+  ((query :initarg :query :type string)
+   (sort :initarg :sort :type string)
+   (sort-dir :initarg :sort-dir :type string)
+   (total :initarg :total :type number)
+   (matches :initarg :matches :initform nil :type (or null list))
+   (paging :initarg :paging :type slack-search-paging)))
+
+(defclass slack-file-search-result (slack-search-result) ())
+
+(defclass slack-search-message ()
+  ((message :initarg :message :type slack-message)
+
+   (channel :initarg :channel :type slack-search-message-channel)
+   (user :initarg :user :type string)
+   (username :initarg :username :type string)
+   (permalink :initarg :permalink :type string)
+
+   (previous-2 :initarg :previous-2 :type (or null slack-search-message-around-message) :initform nil)
+   (previous :initarg :previous :type (or null slack-search-message-around-message) :initform nil)
+   (next :initarg :next :type (or null slack-search-message-around-message) :initform nil)
+   (next-2 :initarg :next-2 :type (or null slack-search-message-around-message) :initform nil)))
+
+(defclass slack-search-message-channel ()
+  ((id :initarg :id :type string)
+   (name :initarg :name :type string)))
+
+(defclass slack-search-message-around-message ()
+  ((user :initarg :user :type string)
+   (username :initarg :username :type string)
+   (text :initarg :text :type string)
+   (ts :initarg :ts :type string)
+   (type :initarg :type :type string)))
+
+(defmethod slack-merge ((this slack-search-result) other)
+  (oset this query (oref other query))
+  (oset this sort (oref other sort))
+  (oset this sort-dir (oref other sort-dir))
+  (oset this total (oref other total))
+  (oset this matches (append (oref this matches) (oref other matches)))
+  (oset this paging (oref other paging)))
+
+(defmethod slack-message-to-string ((this slack-search-message) team)
+  (with-slots (channel username) this
+    (let* ((room (slack-room-find (oref channel id) team))
+           (header (propertize (format "%s%s"
+                                       (if (slack-channel-p room)
+                                           "#" "@")
+                                       (slack-room-name room))
+                               'face 'slack-search-result-message-header-face)))
+      (propertize (format "%s\n%s"
+                          header
+                          (slack-message-to-string (oref this message) team))
+                  'ts (slack-ts this)))))
+
+(defmethod slack-ts ((this slack-search-message))
+  (slack-ts (oref this message)))
+
+(defmethod slack-search-has-next-page-p ((this slack-search-result))
+  (slack-search-paging-next-page (oref this paging)))
+
+(defmethod slack-search-paging-next-page ((this slack-search-paging))
+  (with-slots (pages page) this
+    (unless (< pages (1+ page))
+      (1+ page))))
+
+(defun slack-search-create-message-channel (payload)
+  (and payload
+       (make-instance 'slack-search-message-channel
+                      :id (plist-get payload :id)
+                      :name (plist-get payload :name))))
+
+(defun slack-search-create-around-message (payload)
+  (and payload
+       (make-instance 'slack-search-message-around-message
+                      :user (plist-get payload :user)
+                      :username (plist-get payload :username)
+                      :text (plist-get payload :text)
+                      :ts (plist-get payload :ts)
+                      :type (plist-get payload :type))))
+
+(defun slack-search-create-message (payload team)
+  (setq payload (append payload nil))
+  (let* ((channel (slack-search-create-message-channel
+                   (plist-get payload :channel)))
+         (previous-2 (slack-search-create-around-message
+                      (plist-get payload :previous_2)))
+         (previous (slack-search-create-around-message
+                    (plist-get payload :previous)))
+         (next (slack-search-create-around-message
+                (plist-get payload :next)))
+         (next-2 (slack-search-create-around-message
+                  (plist-get payload :next_2)))
+         (room (slack-room-find (oref channel id) team)))
+
+    (unless (< 0 (length (plist-get payload :user)))
+      (plist-put payload :user nil)
+      (plist-put payload :subtype "bot_message"))
+
+    (make-instance 'slack-search-message
+                   :message (slack-message-create payload team :room room)
+                   :channel channel
+                   :previous-2 previous-2
+                   :previous previous
+                   :next next
+                   :next-2 next-2)))
+
+(defun slack-search-create-paging (payload)
+  (and payload
+       (make-instance 'slack-search-paging
+                      :count (plist-get payload :count)
+                      :total (plist-get payload :total)
+                      :page (plist-get payload :page)
+                      :pages (plist-get payload :pages))))
+
+(defun slack-search-create-result (payload sort sort-dir team)
+  (let* ((messages (plist-get payload :messages))
+         (matches (mapcar #'(lambda (e) (slack-search-create-message e team))
+                          (plist-get messages :matches)))
+         (paging (slack-search-create-paging
+                  (plist-get messages :paging))))
+    (make-instance 'slack-search-result
+                   :query (plist-get payload :query)
+                   :total (plist-get messages :total)
+                   :paging paging
+                   :matches matches
+                   :sort sort
+                   :sort-dir sort-dir)))
+
+(defun slack-search-create-file-result (payload sort sort-dir)
+  (let* ((files (plist-get payload :files))
+         (matches (mapcar #'slack-file-create
+                          (plist-get files :matches)))
+         (paging (slack-search-create-paging
+                  (plist-get files :paging))))
+    (make-instance 'slack-search-result
+                   :query (plist-get payload :query)
+                   :total (plist-get files :total)
+                   :paging paging
+                   :matches matches
+                   :sort sort
+                   :sort-dir sort-dir)))
+
+(defun slack-search-query-params ()
+  (let ((team (slack-team-select))
+        (query (read-from-minibuffer "Query: "))
+        (sort (funcall slack-completing-read-function "Sort: " `("score" "timestamp")
+                       nil t))
+        (sort-dir (funcall slack-completing-read-function "Direction: " `("desc" "asc")
+                           nil t)))
+    (list team query sort sort-dir)))
+
+(defun slack-search-from-messages ()
+  (interactive)
+  (cl-destructuring-bind (team query sort sort-dir) (slack-search-query-params)
+    (let ((instance (make-instance 'slack-search-result
+                                   :sort sort
+                                   :sort-dir sort-dir
+                                   :query query)))
+      (cl-labels
+          ((after-success ()
+                          (let ((buffer (slack-create-search-result-buffer instance team)))
+                            (slack-buffer-display buffer))))
+        (slack-search-request instance #'after-success team)))))
+
+(defun slack-search-from-files ()
+  (interactive)
+  (cl-destructuring-bind (team query sort sort-dir) (slack-search-query-params)
+    (let ((instance (make-instance 'slack-file-search-result
+                                   :sort sort
+                                   :sort-dir sort-dir
+                                   :query query)))
+      (cl-labels
+          ((after-success ()
+                          (let ((buffer (slack-create-search-result-buffer instance team)))
+                            (slack-buffer-display buffer))))
+        (slack-search-request instance #'after-success team)))))
+
+(defmethod slack-search-request-url ((_this slack-search-result))
+  "https://slack.com/api/search.messages")
+
+(defmethod slack-search-request-url ((_this slack-file-search-result))
+  "https://slack.com/api/search.files")
+
+(cl-defmethod slack-search-request ((this slack-search-result)
+                                    after-success team &optional (page 1))
+  (cl-labels
+      ((on-success (&key data &allow-other-keys)
+                   (slack-request-handle-error
+                    (data "slack-search-request")
+                    (let ((search-result
+                           (if (slack-file-search-result-p this)
+                               (slack-search-create-file-result data
+                                                                (oref this sort)
+                                                                (oref this sort-dir))
+                             (slack-search-create-result data
+                                                         (oref this sort)
+                                                         (oref this sort-dir)
+                                                         team))))
+                      (slack-merge this search-result)
+                      (funcall after-success)))))
+    (with-slots (query sort sort-dir) this
+      (if (< 0 (length query))
+          (slack-request
+           (slack-request-create
+            (slack-search-request-url this)
+            team
+            :type "POST"
+            :params (list (cons "query" query)
+                          (cons "sort" sort)
+                          (cons "sort_dir" sort-dir)
+                          (cons "page" (number-to-string page)))
+            :success #'on-success))))))
+
+;; (defun slack-search-alist (team)
+;;   (with-slots (search-results) team
+;;     (cl-loop for s in search-results
+;;              collect (cons (slack-room-buffer-name s) s))))
+
+;; (defun slack-search-select ()
+;;   (interactive)
+;;   (let* ((team (slack-team-select))
+;;          (alist (slack-search-alist team)))
+;;     (slack-select-from-list
+;;         (alist "Select Search: ")
+;;         (funcall slack-buffer-function (slack-buffer-create selected team)))))
+
+;; protocols
+;; (defmethod slack-room-sorted-messages ((room slack-search-result))
+;;   (copy-sequence (oref room messages)))
+
+;; (defmethod slack-room-update-last-read ((room slack-search-result) msg)
+;;   (if (not (slot-exists-p msg 'info))
+;;       (progn
+;;         (oset room last-read (oref msg ts))
+;;         (oset room last-channel-id ""))
+;;     (with-slots (ts info) msg
+;;       (with-slots (channel-id) info
+;;         (when (slack-room-update-last-read-p room ts)
+;;           (oset room last-read ts)
+;;           (oset room last-channel-id channel-id))))))
+
+;; (defmethod slack-search-get-index ((_search-result slack-file-search-result)
+;;                                    messages last-read &optional _last-chanel-id)
+;;   (cl-loop for i from 0 upto (1- (length messages))
+;;            for m = (nth i messages)
+;;            if (string= (oref m ts) last-read)
+;;            return i))
+
+;; (defmethod slack-search-get-index ((_search-result slack-search-result)
+;;                                    messages last-read &optional last-channel-id)
+;;   (cl-loop for i from 0 upto (1- (length messages))
+;;            for m = (nth i messages)
+;;            if (and (string= (oref m ts) last-read)
+;;                    (string= (oref (oref m info) channel-id)
+;;                             last-channel-id))
+;;            return i))
+
+;; (defmethod slack-room-latest-messages ((room slack-search-result) messages)
+;;   (with-slots (type last-read last-channel-id) room
+;;     (let* ((r-messages (reverse messages))
+;;            (nth (slack-search-get-index room r-messages
+;;                                         last-read last-channel-id)))
+;;       (if nth
+;;           (nreverse
+;;            (nthcdr (1+ nth) r-messages))
+;;         (copy-sequence messages)))))
+
+;; (defmethod slack-room-prev-messages ((room slack-file-search-result) oldest)
+;;   (let* ((messages (reverse (oref room messages)))
+;;          (nth (slack-search-get-index room messages oldest)))
+;;     (if nth
+;;         (nreverse (nthcdr (1+ nth) messages)))))
+
+;; (defmethod slack-room-prev-messages ((room slack-search-result) param)
+;;   (let* ((oldest (car param))
+;;          (channel-id (cdr param))
+;;          (messages (reverse (oref room messages)))
+;;          (nth (slack-search-get-index room messages
+;;                                       oldest channel-id)))
+;;     (if nth
+;;         (nreverse (nthcdr (1+ nth) messages)))))
+
+;; (defmethod slack-message-equal ((m slack-search-message) n)
+;;   (with-slots ((m-info info) (m-ts ts)) m
+;;     (with-slots ((m-channel-id channel-id)) m-info
+;;       (with-slots ((n-info info) (n-ts ts)) n
+;;         (with-slots ((n-channel-id channel-id)) n-info
+;;           (and (string= m-channel-id n-channel-id)
+;;                (string= m-ts n-ts)))))))
+
+;; (defmethod slack-room-buffer-name ((room slack-search-result))
+;;   (with-slots (query sort sort-dir team-id type) room
+;;     (let ((team (slack-team-find team-id)))
+;;       (format "%s - %s Query: %s Sort: %s Order: %s"
+;;               (oref team name)
+;;               (eieio-object-class room)
+;;               query sort sort-dir))))
+
+;; (defmethod slack-message-to-string ((message slack-search-message) team)
+;;   (with-slots (info text username) message
+;;     (with-slots (channel-id permalink) info
+;;       (let* ((header (format "%s" username))
+;;              (channel (slack-room-find channel-id team))
+;;              (body (slack-message-unescape-string
+;;                     (format "%s\n\n------------\nChanel: %s\nPermalink: %s"
+;;                             text
+;;                             (slack-room-name channel)
+;;                             permalink)
+;;                     team)))
+;;         (slack-message-put-header-property header)
+;;         (slack-message-put-text-property body)
+;;         (format "%s\n%s\n" header body)))))
+
+;; (defmethod slack-room-set-prev-messages ((room slack-search-result) prev)
+;;   (slack-room-set-messages room (nreverse
+;;                                  (nconc (nreverse prev) (oref room messages)))))
+
+;; (defmethod slack-room-set-messages ((room slack-search-result) messages)
+;;   (let ((msgs (nreverse messages)))
+;;     (oset room messages msgs)
+;;     (oset room latest (car (last msgs)))
+;;     (oset room oldest (car msgs))))
+
+;; (cl-defmethod slack-room-history-request ((room slack-search-result) team
+;;                                           &key
+;;                                           oldest after-success async)
+;;   (cl-labels
+;;       ((on-history
+;;         (&key data &allow-other-keys)
+;;         (slack-request-handle-error
+;;          (data "slack-room-history")
+;;          (let* ((matches (cl-case (eieio-object-class room)
+;;                            ('slack-search-result (plist-get data :messages))
+;;                            ('slack-file-search-result (plist-get data :files))))
+;;                 (messages (cl-loop
+;;                            for match in (plist-get matches :matches)
+;;                            collect (slack-search-create-message room match))))
+;;            (oset room current-page
+;;                  (plist-get (plist-get matches :paging) :page))
+;;            (if oldest
+;;                (slack-room-set-prev-messages room messages)
+;;              (slack-room-reset-last-read room)
+;;              (slack-room-set-messages room messages))
+;;            (if after-success
+;;                (funcall after-success))))))
+;;     (let* ((current-page (oref room current-page))
+;;            (total-page (oref room total-page))
+;;            (next-page (if oldest
+;;                           (1+ current-page)
+;;                         1)))
+;;       (with-slots (query sort sort-dir) room
+;;         (cl-case (eieio-object-class room)
+;;           ('slack-search-result
+;;            (slack-search-request-message team
+;;                                          query
+;;                                          sort
+;;                                          sort-dir
+;;                                          #'on-history
+;;                                          next-page
+;;                                          async))
+;;           ('slack-file-search-result
+;;            (slack-search-request-file team
+;;                                       query
+;;                                       sort
+;;                                       sort-dir
+;;                                       #'on-history
+;;                                       next-page
+;;                                       async)))))))
+
+(provide 'slack-search)
+;;; slack-search.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-search.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-search.elc
new file mode 100644
index 0000000000..e962bd7408
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-search.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-slash-commands.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-slash-commands.el
new file mode 100644
index 0000000000..ed554fe2b2
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-slash-commands.el
@@ -0,0 +1,122 @@
+;;; slack-slash-commands.el ---                      -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2017
+
+;; Author:  <yuya373@yuya373>
+;; Keywords:
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+(defvar slack-slash-commands-map
+  '(("active" . slack-slash-commands-active)
+    ("away" . slack-slash-commands-away)
+    ("dnd" . slack-slash-commands-dnd)
+    ("leave" . slack-slash-commands-leave)
+    ("join" . slack-slash-commands-join)
+    ("remind" . slack-slash-commands-remind)
+    ("shrug" . slack-slash-commands-shrug)
+    ("status" . slack-slash-commands-status)
+    ("who" . slack-slash-commands-who)
+    ("dm" . slack-slash-commands-dm)))
+
+(defvar slack-slash-commands-available
+  (mapcar #'car slack-slash-commands-map))
+
+(defun slack-slash-commands-parse (text)
+  (if (string-prefix-p "/" text)
+      (let* ((maybe-command (car (split-string (substring text 1) " ")))
+             (command (cl-find maybe-command slack-slash-commands-available
+                               :test #'string=)))
+        (when command
+          (cons command (cdr (split-string text " ")))))))
+
+(defun slack-slash-commands-find (command)
+  (cdr (cl-assoc command slack-slash-commands-map :test #'string=)))
+
+(defun slack-slash-commands-execute (command team)
+  (let ((command (car command))
+        (args (cdr command)))
+    (funcall (slack-slash-commands-find command) team args)))
+
+(defun slack-slash-commands-active (team _args)
+  ;; https://api.slack.com/docs/presence-and-status#user_presence
+  ;; Setting presence back to auto indicates that the automatic status should be used instead. There's no way to force a user status to active.
+  (slack-request-set-presence team "auto"))
+
+(defun slack-slash-commands-away (team _args)
+  (slack-request-set-presence team))
+
+(defun slack-slash-commands-leave (team _args)
+  (slack-channel-leave team t))
+
+(defun slack-slash-commands-join (team _args)
+  (slack-channel-join team t))
+
+(defun slack-slash-commands-remind (team _args)
+  (slack-reminder-add team))
+
+(defun slack-slash-commands-dnd (team args)
+  "[some description of time, see `slack-parse-time-string']"
+  (let ((time (car args))
+        (user (slack-user--find (oref team self-id) team)))
+    (if (or (not (slack-user-dnd-in-range-p user))
+            time)
+        (slack-request-dnd-set-snooze team time)
+      (slack-request-dnd-end-dnd team))))
+;; ¯\_(ツ)_/¯
+(defun slack-slash-commands-shrug (_team messages)
+  "[your message]"
+  (slack-message--send (format "%s ¯\\_(ツ)_/¯"
+                               (mapconcat #'identity messages " "))))
+
+(defun slack-slash-commands-status (team args)
+  "[clear] or [:your_new_status_emoji:] [your new status message]"
+  (let ((emoji (car args))
+        (text (cdr args)))
+    (if (string= emoji "clear")
+        (slack-user-set-status-request team "" "")
+      (if (string-prefix-p ":" emoji)
+          (slack-user-set-status-request team emoji (mapconcat #'identity text " "))
+        (slack-user-set-status-request team "" (mapconcat #'identity args " "))))))
+
+(defun slack-slash-commands-who (_team _args)
+  (slack-room-user-select))
+
+(defun slack-slash-commands-dm (team args)
+  "@user [your message]"
+  (let* ((user-name (substring (car args) 1))
+         (text (mapconcat #'identity (cdr args) " "))
+         (user (slack-user-find-by-name user-name team)))
+    (unless user
+      (error "Invalid user name: %s" (car args)))
+    (cl-labels
+        ((send-message
+          ()
+          (slack-message-send-internal
+           text
+           (oref (slack-im-find-by-user-id (plist-get user :id)
+                                           team)
+                 id)
+           team)))
+      (if (slack-im-find-by-user-id (plist-get user :id) team)
+          (send-message)
+        (slack-im-open user #'send-message)))))
+
+(provide 'slack-slash-commands)
+;;; slack-slash-commands.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-slash-commands.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-slash-commands.elc
new file mode 100644
index 0000000000..57961b2c64
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-slash-commands.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-star.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-star.el
new file mode 100644
index 0000000000..4c1227e4e8
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-star.el
@@ -0,0 +1,264 @@
+;;; slack-stars.el ---                               -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2017  南優也
+
+;; Author: 南優也 <yuyaminami@minamiyuuya-no-MacBook.local>
+;; Keywords:
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+(require 'eieio)
+(require 'slack-util)
+(require 'slack-request)
+
+(defconst slack-stars-list-url "https://slack.com/api/stars.list")
+
+(defclass slack-star ()
+  ((paging :initarg :paging :type slack-star-paging)
+   (items :initarg :items :type (or null list) :initform nil)))
+
+(defclass slack-star-paging ()
+  ((per-page :initarg :per-page :type number)
+   (spill :initarg :spill :type number) ;; ??
+   (total :initarg :total :type number)
+   (page :initarg :page :type number)
+   (pages :initarg :pages :type number)))
+
+(defclass slack-star-item ()
+  ((date-create :initarg :date-create :type string)))
+
+(defclass slack-star-message (slack-star-item)
+  ((channel :initarg :channel :type string)
+   (message :initarg :message :type slack-message)))
+
+(defclass slack-star-file (slack-star-item)
+  ((file :initarg :file :type slack-file)))
+
+(defclass slack-star-file-comment (slack-star-file)
+  ((file-comment :initarg :file-comment :type slack-file-comment)))
+
+(defclass slack-star-channel (slack-star-item) ;; Ch ??
+  ((channel :initarg :channel :type string))) ;; ID
+
+(defclass slack-star-group (slack-star-item) ;; Gh ??
+  ((group :initarg :group :type string))) ;; ID
+
+(defclass slack-star-im (slack-star-item) ;; Dh ??
+  ((channel :initarg :channel :type string))) ;; ID
+
+(defmethod slack-star-item-message ((this slack-star-message))
+  (oref this message))
+
+(defmethod slack-star-item-message ((this slack-star-file))
+  (oref this file))
+
+(defmethod slack-star-item-message ((this slack-star-file-comment))
+  (oref this file-comment))
+
+(defmethod slack-ts ((this slack-star-item))
+  (oref this date-create))
+
+(defmethod slack-next-page ((this slack-star-paging))
+  (with-slots (pages page) this
+    (unless (< pages (1+ page))
+      (1+ page))))
+
+(defmethod slack-star-has-next-page-p ((this slack-star))
+  (slack-next-page (oref this paging)))
+
+(defmethod slack-per-page ((this slack-star-paging))
+  (oref this per-page))
+
+(defmethod slack-star-per-page ((this slack-star))
+  (slack-per-page (oref this paging)))
+
+(defmethod slack-star-items ((this slack-star))
+  (oref this items))
+
+(defmethod slack-merge ((old slack-star) new)
+  (with-slots (paging items) old
+    (setq paging (oref new paging))
+    (setq items (append (oref new items) items))))
+
+(defmethod slack-to-string ((this slack-star-message) team)
+  (slack-message-to-string (oref this message) team))
+
+(defmethod slack-to-string ((this slack-star-file-comment) team)
+  (slack-message-to-string (oref this file-comment) team))
+
+(defmethod slack-to-string ((this slack-star-file) team)
+  (slack-message-to-string (oref this file) team))
+
+(defun slack-create-star-paging (payload)
+  ;; (:per_page 20 :spill 0 :page 1 :total 61 :pages 4)
+  (make-instance 'slack-star-paging
+                 :per-page (plist-get payload :per_page)
+                 :spill (plist-get payload :spill)
+                 :page (plist-get payload :page)
+                 :total (plist-get payload :total)
+                 :pages (plist-get payload :pages)
+                 ))
+
+(defun slack-create-star-items (payload team)
+  (mapcar #'(lambda (e) (slack-create-star-item e team))
+          payload))
+
+(defun slack-create-star-item (payload team)
+  (let* ((type (plist-get payload :type))
+         (date-create (format "%s" (plist-get payload :date_create)))
+         (file-payload (plist-get payload :file))
+         (file (and file-payload
+                    (if (or (slack-file-p file-payload)
+                            (slack-file-email-p file-payload))
+                        file-payload
+                      (slack-file-create file-payload))))
+         (file-id (and file (oref file id))))
+    (cond
+     ((string= type "message")
+      (make-instance 'slack-star-message
+                     :date-create date-create
+                     :channel (plist-get payload :channel)
+                     :message (slack-message-create (plist-get payload :message)
+                                                    team)))
+     ((string= type "file")
+      (make-instance 'slack-star-file
+                     :date-create date-create
+                     :file file))
+     ((string= type "file_comment")
+      (make-instance 'slack-star-file-comment
+                     :date-create date-create
+                     :file file
+                     :file-comment (slack-file-comment-create
+                                    (plist-get payload :comment)
+                                    file-id)))
+     ((string= type "channel")
+      (make-instance 'slack-star-channel
+                     :date-create date-create
+                     :channel (plist-get payload :channel)))
+     ((string= type "im")
+      (make-instance 'slack-star-im
+                     :date-create date-create
+                     :channel (plist-get payload :channel)))
+     ((string= type "group")
+      (make-instance 'slack-star-group
+                     :date-create date-create
+                     :group (plist-get payload :group))))))
+
+;; (:per_page 20 :spill 0 :page 1 :total 61 :pages 4)
+(defun slack-create-star-paging (payload)
+  (make-instance 'slack-star-paging
+                 :per-page (plist-get payload :per_page)
+                 :spill (plist-get payload :spill)
+                 :page (plist-get payload :page)
+                 :total (plist-get payload :total)
+                 :pages (plist-get payload :pages)))
+
+(defun slack-create-star (payload team)
+  (let ((items (slack-create-star-items (plist-get payload :items)
+                                        team))
+        (paging (slack-create-star-paging (plist-get payload :paging))))
+    (make-instance 'slack-star
+                   :items (reverse items)
+                   :paging paging)))
+
+(defun slack-stars-list-request (team &optional page after-success)
+  (cl-labels
+      ((on-success (&key data &allow-other-keys)
+                   (slack-request-handle-error
+                    (data "slack-stars-list-request")
+                    (let ((star (slack-create-star data team)))
+                      (if (oref team star)
+                          (if page
+                              (slack-merge (oref team star) star)
+                            (oset team star star))
+                        (oset team star star)))
+                    (if after-success
+                        (funcall after-success)))))
+    (slack-request
+     (slack-request-create
+      slack-stars-list-url
+      team
+      :type "POST"
+      :data (list (cons "exclude" "Ch,Gh,Dh")
+                  (cons "count" "20")
+                  (cons "page" (number-to-string (or page 1))))
+      :success #'on-success))))
+
+
+(defun slack-stars-list ()
+  (interactive)
+  (let* ((team (slack-team-select))
+         (buf (slack-buffer-find 'slack-stars-buffer team)))
+    (if buf (slack-buffer-display buf)
+      (slack-stars-list-request
+       team nil
+       #'(lambda () (slack-buffer-display (slack-create-stars-buffer team)))))))
+
+(defmethod slack-message-star-api-params ((this slack-star-item))
+  (list (slack-message-star-api-params (slack-star-item-message this))))
+
+(defmethod slack-message-star-api-params ((this slack-star-message))
+  (append (list (cons "channel" (oref this channel)))
+          (call-next-method)))
+
+(defmethod slack-star-remove-star ((this slack-star) ts team)
+  (slack-if-let* ((item (cl-find-if #'(lambda (e) (string= (oref e date-create) ts))
+                              (oref this items))))
+      (slack-message-star-api-request slack-message-stars-remove-url
+                                      (slack-message-star-api-params item)
+                                      team)))
+
+(defmethod slack-star-remove ((this slack-star) payload team)
+  (let ((date-create (format "%s" (plist-get payload :date_create))))
+    (oset this items (cl-remove-if #'(lambda (e) (string= (slack-ts e)
+                                                          date-create))
+                                   (oref this items)))
+    (slack-if-let* ((buffer (slack-buffer-find 'slack-stars-buffer team)))
+        (slack-buffer-message-delete buffer date-create))))
+
+(defmethod slack-star-add ((this slack-star) payload team)
+  (setq payload (append payload nil))
+  (cl-labels
+      ((create-star (payload)
+                    (slack-create-star-item payload team))
+       (append-star-item (item)
+                         (oset this items (append (oref this items) (list item))))
+       (insert-to-buffer (item)
+                         (slack-if-let* ((buffer (slack-buffer-find 'slack-stars-buffer
+                                                                    team)))
+                             (with-current-buffer (slack-buffer-buffer buffer)
+                               (slack-buffer-insert buffer item)))))
+    (if (plist-get payload :file)
+        (cl-labels
+            ((insert-star (payload file)
+                          (let ((item (create-star (plist-put payload :file file))))
+                            (append-star-item item)
+                            (insert-to-buffer item))))
+          (let ((file-id (plist-get (plist-get payload :file) :id)))
+            (slack-if-let* ((file (slack-file-find file-id team)))
+                (insert-star payload file)
+              (slack-file-request-info file-id 1 team
+                                       #'(lambda (file _team)
+                                           (insert-star payload file))))))
+      (let ((item (create-star payload)))
+        (append-star-item item)
+        (insert-to-buffer item)))))
+
+(provide 'slack-star)
+;;; slack-stars.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-star.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-star.elc
new file mode 100644
index 0000000000..5aa37131e3
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-star.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-stars-buffer.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-stars-buffer.el
new file mode 100644
index 0000000000..3d36db90c4
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-stars-buffer.el
@@ -0,0 +1,128 @@
+;;; slack-stars-buffer.el ---                        -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2017  南優也
+
+;; Author: 南優也 <yuyaminami@minamiyuuya-no-MacBook.local>
+;; Keywords:
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'eieio)
+(require 'slack-util)
+(require 'slack-team)
+(require 'slack-buffer)
+
+(define-derived-mode slack-stars-buffer-mode slack-buffer-mode "Slack Stars Buffer")
+
+(defclass slack-stars-buffer (slack-buffer)
+  ((oldest :type string :initform "")))
+
+(defmethod slack-buffer-name :static ((_class slack-stars-buffer) team)
+  (format "*Slack - %s : Stars*" (oref team name)))
+
+(defmethod slack-buffer-name ((this slack-stars-buffer))
+  (slack-buffer-name 'slack-stars-buffer (oref this team)))
+
+(defmethod slack-buffer-find :static ((class slack-stars-buffer) team)
+  (slack-if-let* ((buf (cl-find-if #'(lambda (e) (string= (buffer-name e)
+                                                    (slack-buffer-name class team)))
+                             (slot-value team class))))
+      (with-current-buffer buf slack-current-buffer)))
+
+(defmethod slack-buffer-insert ((this slack-stars-buffer) item &optional not-tracked-p)
+  (let ((lui-time-stamp-time (seconds-to-time
+                              (string-to-number
+                               (slack-ts
+                                (slack-star-item-message item))))))
+    (lui-insert-with-text-properties
+     (slack-to-string item (oref this team))
+     'ts (slack-ts item)
+     'not-tracked-p not-tracked-p)
+    (lui-insert "" t)))
+
+(defmethod slack-buffer-has-next-page-p ((this slack-stars-buffer))
+  (with-slots (team) this
+    (slack-star-has-next-page-p (oref team star))))
+
+(defmethod slack-buffer-insert-history ((this slack-stars-buffer))
+  (with-slots (team) this
+    (let ((items (slack-star-items (oref team star)))
+          (before-oldest (oref this oldest)))
+      (oset this oldest (slack-ts (car items)))
+      (cl-loop for item in items
+               do (and (string< (slack-ts item) before-oldest)
+                       (slack-buffer-insert this item t)))
+
+      (slack-if-let* ((point (slack-buffer-ts-eq (point-min)
+                                           (point-max)
+                                           before-oldest)))
+          (goto-char point)))))
+
+(defmethod slack-buffer-request-history ((this slack-stars-buffer) after-success)
+  (with-slots (team) this
+    (slack-stars-list-request team
+                              (slack-next-page (oref (oref team star) paging))
+                              after-success)))
+
+
+(defmethod slack-buffer-update-oldest ((this slack-stars-buffer) item)
+  (when (string< (oref this oldest) (slack-ts item))
+    (oset this oldest (slack-ts item))))
+
+(defmethod slack-buffer-init-buffer ((this slack-stars-buffer))
+  (let* ((buf (generate-new-buffer (slack-buffer-name this)))
+         (star (oref (oref this team) star))
+         (items (slack-star-items star))
+         (oldest-message (car items)))
+    (when oldest-message
+      (slack-buffer-update-oldest this oldest-message))
+    (with-current-buffer buf
+      (slack-stars-buffer-mode)
+      (slack-buffer-set-current-buffer this)
+      (slack-buffer-insert-load-more this)
+      (with-slots (star) (oref this team)
+        (cl-loop for m in (oref star items)
+                 do (slack-buffer-insert this m)))
+      (goto-char (point-max)))
+    (unless (oref (oref this team) slack-stars-buffer)
+      (push buf (oref (oref this team) slack-stars-buffer)))
+    buf))
+
+(defun slack-create-stars-buffer (team)
+  (slack-if-let* ((buf (slack-buffer-find 'slack-stars-buffer team)))
+      buf
+    (make-instance 'slack-stars-buffer
+                   :team team)))
+
+(defmethod slack-buffer-remove-star ((this slack-stars-buffer) ts)
+  (with-slots (team) this
+    (with-slots (star) team
+      (slack-star-remove-star star ts team))))
+
+(defmethod slack-buffer-message-delete ((this slack-stars-buffer) ts)
+  (let ((buffer (slack-buffer-buffer this))
+        (inhibit-read-only t))
+    (with-current-buffer buffer
+      (slack-if-let* ((beg (slack-buffer-ts-eq (point-min) (point-max) ts))
+                      (end (next-single-property-change beg 'ts)))
+          (delete-region beg end)))))
+
+(provide 'slack-stars-buffer)
+;;; slack-stars-buffer.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-stars-buffer.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-stars-buffer.elc
new file mode 100644
index 0000000000..34752995ff
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-stars-buffer.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-team.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-team.el
new file mode 100644
index 0000000000..1d831eb06d
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-team.el
@@ -0,0 +1,308 @@
+;;; slack-team.el ---  team class                    -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2016  南優也
+
+;; Author: 南優也 <yuyaminami@minamiyuunari-no-MacBook-Pro.local>
+;; Keywords:
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+(require 'eieio)
+(require 'slack-util)
+
+(defvar slack-teams nil)
+(defvar slack-current-team nil)
+(defcustom slack-prefer-current-team nil
+  "If set to t, using `slack-current-team' for interactive function.
+use `slack-change-current-team' to change `slack-current-team'"
+  :group 'slack)
+
+(defcustom slack-modeline-count-only-subscribed-channel t
+  "Count unread only subscribed channel."
+  :group 'slack)
+
+(defclass slack-team-threads ()
+  ((initializedp :initform nil)
+   (has-more :initform t)
+   (total-unread-replies :initform 0 :type number)
+   (new-threads-count :initform 0 :type number)))
+
+(defclass slack-team ()
+  ((id :initarg :id)
+   (token :initarg :token :initform nil)
+   (client-id :initarg :client-id)
+   (client-secret :initarg :client-secret)
+   (name :initarg :name :initform nil)
+   (domain :initarg :domain)
+   (self :initarg :self)
+   (self-id :initarg :self-id)
+   (self-name :initarg :self-name)
+   (channels :initarg :channels :initform nil)
+   (groups :initarg :groups :initform nil)
+   (ims :initarg :ims :initform nil)
+   (file-room :initform nil)
+   (search-results :initform nil)
+   (users :initarg :users :initform nil)
+   (bots :initarg :bots :initform nil)
+   (ws-url :initarg :ws-url)
+   (ws-conn :initarg :ws-conn :initform nil)
+   (ping-timer :initform nil)
+   (check-ping-timeout-timer :initform nil)
+   (check-ping-timeout-sec :initarg :check-ping-timeout-sec :initform 20)
+   (reconnect-auto :initarg :reconnect-auto :initform t)
+   (reconnect-timer :initform nil)
+   (reconnect-after-sec :initform 10)
+   (reconnect-count :initform 0)
+   (reconnect-count-max :initform 360)
+   (last-pong :initform nil)
+   (waiting-send :initform nil)
+   (sent-message :initform (make-hash-table))
+   (message-id :initform 0)
+   (connected :initform nil)
+   (subscribed-channels :initarg :subscribed-channels
+                        :type list :initform nil)
+   (typing :initform nil)
+   (typing-timer :initform nil)
+   (reminders :initform nil :type list)
+   (ping-check-timers :initform (make-hash-table :test 'equal))
+   (threads :type slack-team-threads :initform (make-instance 'slack-team-threads))
+   (modeline-enabled :initarg :modeline-enabled :initform nil)
+   (modeline-name :initarg :modeline-name :initform nil)
+   (websocket-event-log-enabled :initarg :websocket-event-log-enabled :initform nil)
+   (display-profile-image :initarg :display-profile-image :initform nil)
+   (display-attachment-image-inline :initarg :display-attachment-image-inline :initform nil)
+   (display-file-image-inline :initarg :display-file-image-inline :initform nil)
+   (waiting-requests :initform nil)
+   (authorize-request :initform nil)
+   (emoji-download-watch-timer :initform nil)
+   (websocket-nowait :initarg :websocket-nowait :initform nil)
+   (star :initform nil)
+   (slack-message-buffer :initform nil :type (or null list))
+   (slack-file-info-buffer :initform nil :type (or null list))
+   (slack-file-list-buffer :initform nil :type (or null list))
+   (slack-message-edit-buffer :initform nil :type (or null list))
+   (slack-pinned-items-buffer :initform nil :type (or null list))
+   (slack-user-profile-buffer :initform nil :type (or null list))
+   (slack-thread-message-buffer :initform nil :type (or null list))
+   (slack-message-share-buffer :initform nil :type (or null list))
+   (slack-room-message-compose-buffer :initform nil :type (or null list))
+   (slack-thread-message-compose-buffer :initform nil :type (or null list))
+   (slack-edit-file-comment-buffer :initform nil :type (or null list))
+   (slack-stars-buffer :initform nil :type (or null list))
+   (slack-search-result-buffer :initform nil :type (or null list))
+   (slack-file-comment-compose-buffer :initform nil :type (or null list))
+   (reconnect-url :initform "" :type string)
+   (full-and-display-names :initarg :full-and-display-names :initform nil)
+   (websocket-connect-timeout-timer :initform nil)
+   (websocket-connect-timeout-sec :type number :initform 20) ;; websocket url is valid for 30 seconds.
+   (mark-as-read-immediately :initarg :mark-as-read-immediately :initform t)
+   (inhibit-reconnection :initform nil)
+   ))
+
+(cl-defmethod slack-team-kill-buffers ((this slack-team) &key (except nil))
+  (let* ((l (list 'slack-message-buffer
+                  'slack-file-info-buffer
+                  'slack-file-list-buffer
+                  'slack-message-edit-buffer
+                  'slack-pinned-items-buffer
+                  'slack-user-profile-buffer
+                  'slack-thread-message-buffer
+                  'slack-message-share-buffer
+                  'slack-room-message-compose-buffer
+                  'slack-thread-message-compose-buffer
+                  'slack-edit-file-comment-buffer
+                  'slack-search-result-buffer
+                  'slack-stars-buffer
+                  'slack-file-comment-compose-buffer))
+         (slots (cl-remove-if #'(lambda (e) (cl-find e except)) l)))
+    (cl-loop for slot in slots
+             do (cl-loop for buffer in (slot-value this slot)
+                         do (kill-buffer buffer)))))
+
+(defun slack-team-find (id)
+  (cl-find-if #'(lambda (team) (string= id (oref team id)))
+              slack-teams))
+
+(defmethod slack-team-disconnect ((team slack-team))
+  (slack-ws-close team))
+
+(defmethod slack-team-equalp ((team slack-team) other)
+  (with-slots (token) team
+    (string= token (oref other token))))
+
+(defmethod slack-team-name ((team slack-team))
+  (oref team name))
+
+;;;###autoload
+(defun slack-register-team (&rest plist)
+  "PLIST must contain :name :client-id :client-secret with value.
+setting :token will reduce your configuration step.
+you will notified when receive message with channel included in subscribed-channels.
+if :default is t and `slack-prefer-current-team' is t, skip selecting team when channels listed.
+you can change current-team with `slack-change-current-team'"
+  (interactive
+   (let ((name (read-from-minibuffer "Team Name: "))
+         (client-id (read-from-minibuffer "Client Id: "))
+         (client-secret (read-from-minibuffer "Client Secret: "))
+         (token (read-from-minibuffer "Token: ")))
+     (list :name name :client-id client-id :client-secret client-secret
+           :token token)))
+  (cl-labels ((same-client-id
+               (client-id)
+               (cl-find-if #'(lambda (team)
+                               (string= client-id (oref team client-id)))
+                           slack-teams))
+              (missing (plist)
+                       (cl-remove-if
+                        #'null
+                        (mapcar #'(lambda (key)
+                                    (unless (plist-member plist key)
+                                      key))
+                                '(:name :client-id :client-secret)))))
+    (let ((missing (missing plist)))
+      (if missing
+          (error "Missing Keyword: %s" missing)))
+    (let ((team (apply #'slack-team "team"
+                       (slack-collect-slots 'slack-team plist))))
+      (let ((same-team (cl-find-if
+                        #'(lambda (o) (slack-team-equalp team o))
+                        slack-teams)))
+        (if same-team
+            (progn
+              (slack-team-disconnect same-team)
+              (slack-start team))))
+
+      (setq slack-teams
+            (cons team
+                  (cl-remove-if #'(lambda (other)
+                                    (slack-team-equalp team other))
+                                slack-teams)))
+      (if (plist-get plist :default)
+          (setq slack-current-team team)))))
+
+(defun slack-team-find-by-name (name)
+  (if name
+      (cl-find-if #'(lambda (team) (string= name (oref team name)))
+                  slack-teams)))
+
+(cl-defun slack-team-select (&optional no-default include-not-connected)
+  (cl-labels ((select-team ()
+                           (slack-team-find-by-name
+                            (funcall slack-completing-read-function
+                                     "Select Team: "
+                                     (mapcar #'(lambda (team) (oref team name))
+                                             (if include-not-connected
+                                                 slack-teams
+                                               (slack-team-connected-list)))))))
+    (let ((team (if (and slack-prefer-current-team
+                         slack-current-team
+                         (not no-default))
+                    slack-current-team
+                  (select-team))))
+      ;; (if (and slack-prefer-current-team
+      ;;          (not slack-current-team)
+      ;;          (not no-default))
+      ;;     (if (yes-or-no-p (format "Set %s to current-team?"
+      ;;                              (oref team name)))
+      ;;         (setq slack-current-team team)))
+      team)))
+
+(defmethod slack-team-connectedp ((team slack-team))
+  (oref team connected))
+
+(defun slack-team-connected-list ()
+  (cl-remove-if #'null
+                (mapcar #'(lambda (team)
+                            (if (slack-team-connectedp team) team))
+                        slack-teams)))
+
+(defun slack-change-current-team ()
+  (interactive)
+  (let ((team (slack-team-find-by-name
+               (funcall slack-completing-read-function
+                        "Select Team: "
+                        (mapcar #'(lambda (team) (oref team name))
+                                slack-teams)))))
+    (setq slack-current-team team)
+    (message "Set slack-current-team to %s" (or (and team (oref team name))
+                                                "nil"))
+    (if team
+        (slack-team-connect team))))
+
+(defmethod slack-team-connect ((team slack-team))
+  (unless (slack-team-connectedp team)
+    (slack-start team)))
+
+(defun slack-team-delete ()
+  (interactive)
+  (let ((selected (slack-team-select t t)))
+    (if (yes-or-no-p (format "Delete %s from `slack-teams'?"
+                             (oref selected name)))
+        (progn
+          (setq slack-teams
+                (cl-remove-if #'(lambda (team)
+                                  (slack-team-equalp selected team))
+                              slack-teams))
+          (slack-team-disconnect selected)
+          (message "Delete %s from `slack-teams'" (oref selected name))))))
+
+(defmethod slack-team-init-ping-check-timers ((team slack-team))
+  (oset team ping-check-timers (make-hash-table :test 'equal)))
+
+(defmethod slack-team-get-ping-check-timers ((team slack-team))
+  (if (not (slot-boundp team 'ping-check-timers))
+      (slack-team-init-ping-check-timers team))
+  (oref team ping-check-timers))
+
+(defmethod slack-team-need-token-p ((team slack-team))
+  (with-slots (token) team
+    (or (not token) (< (length token) 1))))
+
+(defun slack-team-get-unread-messages (team)
+  (cl-labels
+      ((count-unread (rooms)
+                     (cl-reduce #'(lambda (a e) (+ a (oref e unread-count-display)))
+                                rooms :initial-value 0)))
+    (with-slots (ims channels groups) team
+      (let ((rooms (append ims channels groups)))
+        (+ (count-unread (if slack-modeline-count-only-subscribed-channel
+                             (cl-remove-if-not #'(lambda (e) (slack-room-subscribedp e team))
+                                               rooms)
+                           rooms)))))))
+
+(defun slack-team-modeline-enabledp (team)
+  (oref team modeline-enabled))
+
+(defmethod slack-team-event-log-enabledp ((team slack-team))
+  (oref team websocket-event-log-enabled))
+
+(defmethod slack-team-display-profile-imagep ((team slack-team))
+  (oref team display-profile-image))
+
+(defmethod slack-team-display-attachment-image-inlinep ((team slack-team))
+  (oref team display-attachment-image-inline))
+
+(defmethod slack-team-display-file-image-inlinep ((team slack-team))
+  (oref team display-file-image-inline))
+
+(defmethod slack-team-mark-as-read-immediatelyp ((team slack-team))
+  (oref team mark-as-read-immediately))
+
+(provide 'slack-team)
+;;; slack-team.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-team.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-team.elc
new file mode 100644
index 0000000000..0dae6fb070
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-team.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-thread-message-buffer.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-thread-message-buffer.el
new file mode 100644
index 0000000000..8873fd7716
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-thread-message-buffer.el
@@ -0,0 +1,145 @@
+;;; slack-thread-message-buffer.el ---               -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2017
+
+;; Author:  <yuya373@yuya373>
+;; Keywords:
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'eieio)
+(require 'slack-util)
+(require 'slack-room-buffer)
+
+(define-derived-mode slack-thread-message-buffer-mode
+  slack-buffer-mode
+  "Slack Thread Message"
+  (lui-set-prompt lui-prompt-string)
+  (setq lui-input-function 'slack-thread-message--send))
+
+(defclass slack-thread-message-buffer (slack-room-buffer)
+  ((thread-ts :initarg :thread-ts :type string)))
+
+(defmethod slack-buffer-find :static ((class slack-thread-message-buffer) room ts team)
+  (slack-buffer-find-4 class room ts team))
+
+(defun slack-create-thread-message-buffer (room team thread-ts)
+  (slack-if-let* ((buf (slack-buffer-find 'slack-thread-message-buffer
+                                          room thread-ts team)))
+      buf
+    (slack-thread-message-buffer :room room
+                                 :team team
+                                 :thread-ts thread-ts)))
+
+(defmethod slack-buffer-name :static ((class slack-thread-message-buffer) room ts team)
+  (format "*Slack - %s : %s Thread - %s"
+          (oref team name)
+          (slack-room-name room)
+          ts))
+
+(defmethod slack-buffer-name ((this slack-thread-message-buffer))
+  (with-slots (room thread-ts team) this
+    (slack-buffer-name 'slack-thread-message-buffer
+                       room thread-ts team)))
+
+(defmethod slack-buffer-init-buffer ((this slack-thread-message-buffer))
+  (let* ((buf (generate-new-buffer (slack-buffer-name this))))
+    (with-current-buffer buf
+      (slack-thread-message-buffer-mode)
+      (slack-buffer-set-current-buffer this)
+      (goto-char lui-input-marker)
+      (with-slots (room thread-ts team) this
+        (slack-if-let* ((message (slack-room-find-message room thread-ts)))
+            (progn
+              (slack-buffer-insert this message t)
+              (let ((lui-time-stamp-position nil))
+                (lui-insert (format "%s\n" (make-string lui-fill-column ?=)) t))
+              (let ((thread (slack-message-thread message room)))
+                (and thread
+                     (cl-loop for m in (oref thread messages)
+                              do (slack-buffer-insert this m))))))))
+
+    (with-slots (room thread-ts team) this
+      (slack-buffer-push-new-4 (eieio-object-class-name this)
+                               room
+                               thread-ts
+                               team))
+
+    buf))
+
+(defmethod slack-buffer-display-message-compose-buffer
+  ((this slack-thread-message-buffer))
+  (with-slots (room team thread-ts) this
+    (let ((buf (slack-create-thread-message-compose-buffer
+                room thread-ts team)))
+      (slack-buffer-display buf))))
+
+
+(defmethod slack-buffer-send-message ((this slack-thread-message-buffer) message)
+  (with-slots (room team thread-ts) this
+    (slack-thread-send-message room team message thread-ts)))
+
+(defmethod slack-buffer-add-reaction-to-message
+  ((this slack-thread-message-buffer) reaction ts)
+  (with-slots (room team) this
+    (slack-message-reaction-add reaction ts room team)))
+
+(defmethod slack-buffer-remove-reaction-from-message
+  ((this slack-thread-message-buffer) ts &optional _file-comment-id)
+  (with-slots (room team) this
+    (let* ((message (slack-room-find-message room ts))
+           (reaction (slack-message-reaction-select
+                      (slack-message-reactions message))))
+      (slack-message-reaction-remove reaction ts room team))))
+
+(defmethod slack-buffer-add-star ((this slack-thread-message-buffer) ts)
+  (with-slots (room team) this
+    (slack-if-let* ((message (slack-room-find-message room ts)))
+        (slack-message-star-api-request slack-message-stars-add-url
+                                        (list (cons "channel" (oref room id))
+                                              (slack-message-star-api-params message))
+                                        team))))
+
+(defmethod slack-buffer-remove-star ((this slack-thread-message-buffer) ts)
+  (with-slots (room team) this
+    (slack-if-let* ((message (slack-room-find-message room ts)))
+        (slack-message-star-api-request slack-message-stars-remove-url
+                                        (list (cons "channel" (oref room id))
+                                              (slack-message-star-api-params message))
+                                        team))))
+
+(cl-defmethod slack-buffer-update ((this slack-thread-message-buffer) message &key replace)
+  (if replace (slack-buffer-replace this message)
+    (with-current-buffer (slack-buffer-buffer this)
+      (slack-buffer-insert this message))))
+
+(defmethod slack-buffer-display-edit-message-buffer ((this slack-thread-message-buffer) ts)
+  (with-slots (room team) this
+    (let ((buf (slack-create-edit-message-buffer room team ts)))
+      (slack-buffer-display buf))))
+
+(defmethod slack-buffer-share-message ((this slack-thread-message-buffer) ts)
+  (with-slots (room team) this
+    (let ((buf (slack-create-message-share-buffer room team ts)))
+      (slack-buffer-display buf))))
+
+
+(provide 'slack-thread-message-buffer)
+;;; slack-thread-message-buffer.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-thread-message-buffer.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-thread-message-buffer.elc
new file mode 100644
index 0000000000..c62c7d5240
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-thread-message-buffer.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-thread-message-compose-buffer.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-thread-message-compose-buffer.el
new file mode 100644
index 0000000000..46362a2a39
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-thread-message-compose-buffer.el
@@ -0,0 +1,79 @@
+;;; slack-thread-message-compose-buffer.el ---       -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2017
+
+;; Author:  <yuya373@yuya373>
+;; Keywords:
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'eieio)
+(require 'slack-util)
+(require 'slack-message-compose-buffer)
+
+(defclass slack-thread-message-compose-buffer (slack-message-compose-buffer)
+  ((room :initarg :room :type slack-room)
+   (thread-ts :initarg :thread-ts :type string)))
+
+(defmethod slack-buffer-find :static ((class slack-thread-message-compose-buffer) room ts team)
+  (slack-buffer-find-4 class room ts team))
+
+(defmethod slack-buffer-name :static
+  ((class slack-thread-message-compose-buffer) room ts team)
+  (format "*Slack - %s : %s Compose Thread Message - %s*"
+          (oref team name)
+          (slack-room-name room)
+          ts))
+
+(defmethod slack-buffer-name ((this slack-thread-message-compose-buffer))
+  (with-slots (room thread-ts team) this
+    (slack-buffer-name 'slack-thread-message-compose-buffer
+                       room thread-ts team)))
+
+(defmethod slack-buffer-init-buffer ((this slack-thread-message-compose-buffer))
+  (let ((buf (call-next-method)))
+    (with-current-buffer buf
+      (slack-message-compose-buffer-mode)
+      (slack-buffer-set-current-buffer this)
+      (setq buffer-read-only nil)
+      (erase-buffer))
+    (with-slots (room thread-ts team) this
+      (slack-buffer-push-new-4 'slack-thread-message-compose-buffer
+                               room thread-ts team))
+    buf))
+
+(defun slack-create-thread-message-compose-buffer (room ts team)
+  (slack-if-let* ((buf (slack-buffer-find 'slack-thread-message-compose-buffer
+                                    room ts team)))
+      buf
+    (slack-thread-message-compose-buffer :room room
+                                         :team team
+                                         :thread-ts ts)))
+
+(defmethod slack-buffer-send-message
+  ((this slack-thread-message-compose-buffer) message)
+  (let ((buffer (slack-buffer-buffer this)))
+    (with-slots (room team thread-ts) this
+      (slack-thread-send-message room team message thread-ts)))
+  (call-next-method))
+
+
+(provide 'slack-thread-message-compose-buffer)
+;;; slack-thread-message-compose-buffer.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-thread-message-compose-buffer.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-thread-message-compose-buffer.elc
new file mode 100644
index 0000000000..2e3ca583dd
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-thread-message-compose-buffer.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-thread.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-thread.el
new file mode 100644
index 0000000000..86ed77b6b9
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-thread.el
@@ -0,0 +1,332 @@
+;;; slack-thread.el ---                              -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2017  南優也
+
+;; Author: 南優也 <yuyaminami@minamiyuuya-no-MacBook.local>
+;; Keywords:
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'eieio)
+(require 'lui)
+(require 'slack-util)
+(require 'slack-room)
+(require 'slack-channel)
+(require 'slack-im)
+(require 'slack-message)
+(require 'slack-request)
+
+(defvar lui-prompt-string "> ")
+(defconst all-threads-url "https://slack.com/api/subscriptions.thread.getView")
+(defconst thread-mark-url "https://slack.com/api/subscriptions.thread.mark")
+
+(defcustom slack-thread-also-send-to-room 'ask
+  "Whether a thread message should also be sent to its room.
+If nil: don't send to the room.
+If `ask': ask the user every time.
+Any other non-nil value: send to the room."
+  :type '(choice (const :tag "Never send message to the room." nil)
+                 (const :tag "Ask the user every time." ask)
+                 (const :tag "Always send message to the room." t)))
+
+(define-derived-mode slack-thread-mode slack-mode "Slack - Thread"
+  ""
+  (lui-set-prompt lui-prompt-string)
+  (setq lui-input-function 'slack-thread-message--send))
+
+(defclass slack-thread ()
+  ((thread-ts :initarg :thread_ts :initform "")
+   (messages :initarg :messages :initform '())
+   (has-unreads :initarg :has_unreads :initform nil)
+   (mention-count :initarg :mention_count :initform 0)
+   (reply-count :initarg :reply_count :initform 0)
+   (replies :initarg :replies :initform '())
+   (active :initarg :active :initform t)
+   (root :initarg :root :type slack-message)
+   (unread-count :initarg :unread_count :initform 0)
+   (last-read :initarg :last_read :initform "0")))
+
+(defmethod slack-thread-messagep ((m slack-message))
+  (if (and (oref m thread-ts) (not (slack-message-thread-parentp m)))
+      t
+    nil))
+
+(defun slack-thread-start ()
+  (interactive)
+  (slack-if-let* ((buf slack-current-buffer))
+      (slack-buffer-start-thread buf (slack-get-ts))))
+
+(defun slack-thread-message--send (message)
+  (slack-if-let* ((buf slack-current-buffer))
+      (slack-buffer-send-message buf message)))
+
+(defun slack-thread-send-message (room team message thread-ts)
+  (let ((message (slack-message-prepare-links
+                  (slack-escape-message message)
+                  team))
+        (broadcast (if (eq slack-thread-also-send-to-room 'ask)
+                       (y-or-n-p (format "Also send to %s ? "
+                                         (slack-room-name room)))
+                     slack-thread-also-send-to-room)))
+    (progn
+      (slack-message-inc-id team)
+      (with-slots (message-id sent-message self-id) team
+        (let* ((payload (list :id message-id
+                              :channel (oref room id)
+                              :reply_broadcast broadcast
+                              :thread_ts thread-ts
+                              :type "message"
+                              :user self-id
+                              :text message))
+               (json (json-encode payload))
+               (obj (slack-message-create payload team :room room)))
+          (slack-ws-send json team)
+          (puthash message-id obj sent-message))))))
+
+(defun slack-thread-show-or-create ()
+  (interactive)
+  (slack-if-let* ((buf slack-current-buffer))
+      (if (slack-thread-message-buffer-p buf)
+          (error "Already in thread")
+        (slack-buffer-display-thread buf (slack-get-ts)))))
+
+(cl-defmethod slack-thread-request-messages ((thread slack-thread) room team &key after-success)
+  (cl-labels
+      ((on-success (&key data &allow-other-keys)
+                   (slack-request-handle-error
+                    (data "slack-thread-request-messages")
+                    (let ((messages (mapcar #'(lambda (payload)
+                                                (slack-message-create payload
+                                                                      team
+                                                                      :room room))
+                                            (plist-get data :messages))))
+                      (oset thread messages
+                            (slack-room-sort-messages
+                             (cl-remove-if #'slack-message-thread-parentp
+                                           messages)))))
+                   (if after-success
+                       (funcall after-success))))
+
+    (slack-request
+     (slack-request-create
+      (slack-room-replies-url room)
+      team
+      :params (list (cons "thread_ts" (oref thread thread-ts))
+                    (cons "channel" (oref room id)))
+      :success #'on-success))))
+
+(defmethod slack-thread-show-messages ((thread slack-thread) room team)
+  (cl-labels
+      ((after-success ()
+                      (let ((buf (slack-create-thread-message-buffer
+                                  room team (oref thread thread-ts))))
+                        (slack-buffer-display buf))))
+    (slack-thread-request-messages thread room team
+                                   :after-success #'after-success)))
+
+(defmethod slack-thread-to-string ((m slack-message) team)
+  (with-slots (thread) m
+    (if thread
+        (let* ((usernames (mapconcat #'identity
+                                     (cl-remove-duplicates
+                                      (mapcar #'(lambda (reply)
+                                                  (slack-user-name
+                                                   (plist-get reply :user)
+                                                   team))
+                                              (oref thread replies))
+                                      :test #'string=)
+                                     " "))
+               (text (format "\n%s reply from %s"
+                             (oref thread reply-count)
+                             usernames)))
+          (propertize text
+                      'face '(:underline t)
+                      'keymap (let ((map (make-sparse-keymap)))
+                                (define-key map [mouse-1] #'slack-thread-show-or-create)
+                                (define-key map (kbd "RET") #'slack-thread-show-or-create)
+                                map)))
+      "")))
+
+(defmethod slack-thread-create ((m slack-message) team &optional payload)
+  (if payload
+      (let ((replies (plist-get payload :replies))
+            (reply-count (plist-get payload :reply_count))
+            (unread-count (plist-get payload :unread_count))
+            (last-read (plist-get payload :last_read)))
+        (make-instance 'slack-thread
+                       :thread_ts (oref m ts)
+                       :root m
+                       :replies replies
+                       :reply_count (or reply-count 0)
+                       :unread_count (or unread-count 1)
+                       :last_read last-read))
+    (make-instance 'slack-thread
+                   :thread_ts (oref m ts)
+                   :root m)))
+
+(defmethod slack-merge ((old slack-thread) new)
+  (oset old replies (oref new replies))
+  (oset old reply-count (oref new reply-count))
+  (oset old unread-count (oref new unread-count)))
+
+(defun slack-thread-update-state (payload team)
+  (slack-if-let* ((message-payload (plist-get payload :message))
+                  (thread-ts (plist-get message-payload :thread_ts))
+                  (room (slack-room-find (plist-get payload :channel) team))
+                  (message (slack-room-find-message room thread-ts))
+                  (thread (slack-message-get-thread message team))
+                  (new-thread (slack-thread-create message team message-payload)))
+      (progn
+        (slack-merge thread new-thread)
+        (slack-message-update message team t t))
+    (message "THREAD_TS: %s, ROOM: %s, MESSAGE: %s THREAD: %s, NEW_THREAD:%s"
+             thread-ts
+             (not (null room))
+             (not (null message))
+             (not (null thread))
+             (not (null new-thread)))))
+
+(defmethod slack-thread-equal ((thread slack-thread) other)
+  (and (string-equal (oref thread thread-ts)
+                     (oref other thread-ts))
+       (string-equal (oref (oref thread root) channel)
+                     (oref (oref other root) channel))))
+
+(cl-defun slack-thread-get-all (&key (sync nil) (ts nil))
+  (let ((team (slack-team-select)))
+    (cl-labels
+        ((on-success (&key data &allow-other-keys)
+                     (slack-request-handle-error
+                      (data "slack-thread-get-all")
+                      (let ((threads-data (append (plist-get data :threads) nil))
+                            (total-unread (plist-get data :total_unread_replies))
+                            (more (if (eq :json-false (plist-get data :has_more)) nil t))
+                            (new-count (plist-get data :new_threads_count)))
+                        (with-slots (threads) team
+                          (with-slots
+                              (initializedp total-unread-replies new-threads-count has-more) threads
+                            (setq has-more more)
+                            (setq initializedp t)
+                            (setq total-unread-replies total-unread)
+                            (setq new-threads-count new-count)
+                            (let ((parents (cl-loop for thread in threads-data
+                                                    collect (slack-message-create
+                                                             (plist-get thread :root_msg) team))))
+                              (mapc #'(lambda (parent) (slack-message-update parent team nil t))
+                                    parents))))))))
+      (slack-request
+       (slack-request-create
+        all-threads-url
+        team
+        :type "POST"
+        :params (list (cons "limit" "10")
+                      (cons "current_ts" (or ts (format-time-string "%s"))))
+        :success #'on-success)))))
+
+(defmethod slack-thread-title ((thread slack-thread) team)
+  (with-slots (root) thread
+    (let ((room (slack-room-find (oref root channel) team))
+          (body (slack-message-body root team)))
+      (when room
+        (format "%s - %s" (slack-room-name room)
+                (concat (substring body 0 (min 50 (length body))) "..."))))))
+
+(defun slack-thread-select (&optional reload)
+  (interactive)
+  (cl-labels
+      ((load-threads (threads)
+                     (slack-thread-get-all :sync t
+                                           :ts (cl-first
+                                                (cl-sort
+                                                 (mapcar #'(lambda (thread) (oref thread thread-ts)) threads)
+                                                 #'string<))))
+       (select-thread (threads team has-more)
+                      (let* ((alist (cl-remove-if-not
+                                     #'(lambda (cons) (car cons))
+                                     (mapcar #'(lambda (thread)
+                                                 (let ((title (slack-thread-title thread team)))
+                                                   (and title (cons title thread))))
+                                             threads)))
+                             (maybe-has-more (if has-more
+                                                 (append alist (list (cons "(load more)" 'load-more))) alist))
+                             (selected (slack-select-from-list (maybe-has-more "Select Thread: "))))
+                        selected))
+       (collect-thread-parents (messages)
+                               (mapcar #'(lambda (m) (oref m thread))
+                                       (cl-remove-if #'(lambda (m) (not (slack-message-thread-parentp m)))
+                                                     messages)))
+       (collect-threads (team)
+                        (cl-loop for room in (with-slots (groups ims channels) team
+                                               (append ims groups channels))
+                                 append (collect-thread-parents (oref room messages)))))
+
+    (let* ((team (slack-team-select)))
+
+      (with-slots (initializedp has-more) (oref team threads)
+        (if (or (not initializedp) has-more) (load-threads (collect-threads team))))
+
+      (let ((selected (select-thread (collect-threads team) team nil)))
+        (if (eq selected 'load-more)
+            (slack-thread-select t)
+          (slack-thread-show-messages selected
+                                      (slack-room-find (oref (oref selected root) channel) team)
+                                      team))))))
+
+(defmethod slack-thread-delete-message ((thread slack-thread) message)
+  (with-slots (messages reply-count) thread
+    (setq messages (cl-remove-if #'(lambda (e) (string= (oref e ts) (oref message ts)))
+                                 messages))
+    (setq reply-count (length messages))))
+
+(defmethod slack-thread-update-mark ((thread slack-thread) room msg team)
+  (with-slots (thread-ts) thread
+    (with-slots (id) room
+      (with-slots (ts) msg
+        (cl-labels
+            ((on-success (&key data &allow-other-keys)
+                         (slack-request-handle-error
+                          (data "slack-thread-mark"))))
+
+          (slack-request
+           (slack-request-create
+            thread-mark-url
+            team
+            :params (list (cons "channel" id)
+                          (cons "thread_ts" thread-ts)
+                          (cons "ts" ts))
+            :success #'on-success)))))))
+
+(defmethod slack-thread-marked ((thread slack-thread) payload)
+  (let ((unread-count (plist-get payload :unread_count))
+        (last-read (plist-get payload :last_read)))
+    (oset thread unread-count unread-count)
+    (oset thread last-read last-read)))
+
+(defun slack-room-unread-threads ()
+  (interactive)
+  (slack-if-let* ((buf slack-current-buffer))
+      (slack-buffer-display-unread-threads buf)))
+
+(defmethod slack-thread-update-last-read ((thread slack-thread) msg)
+  (with-slots (ts) msg
+    (oset thread last-read ts)))
+
+(provide 'slack-thread)
+;;; slack-thread.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-thread.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-thread.elc
new file mode 100644
index 0000000000..0913d37a5e
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-thread.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-user-message.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-user-message.el
new file mode 100644
index 0000000000..53077a17bd
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-user-message.el
@@ -0,0 +1,35 @@
+;;; package --- Summary
+;;; Commentary:
+
+;;; Code:
+
+(require 'eieio)
+(require 'slack-message-formatter)
+(require 'slack-message-reaction)
+(require 'slack-message-editor)
+
+(defvar slack-user-message-keymap
+  (let ((keymap (make-sparse-keymap)))
+    keymap))
+
+(defmethod slack-message-sender-equalp ((m slack-user-message) sender-id)
+  (string= (oref m user) sender-id))
+
+(defmethod slack-message-header ((m slack-user-message) team)
+  (with-slots (ts edited-at deleted-at) m
+    (let* ((name (slack-message-sender-name m team))
+           (status (slack-user-status (slack-message-sender-id m) team))
+           (time (slack-message-time-to-string ts))
+           (edited-at (slack-message-time-to-string edited-at))
+           (deleted-at (slack-message-time-to-string deleted-at))
+           (header (or (and status (< 0 (length status))
+                            (format "%s %s" name status))
+                       (format "%s" name))))
+      (if deleted-at
+          (format "%s deleted_at: %s" header deleted-at)
+        (if edited-at
+            (format "%s edited_at: %s" header edited-at)
+          header)))))
+
+(provide 'slack-user-message)
+;;; slack-user-message.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-user-message.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-user-message.elc
new file mode 100644
index 0000000000..b755d2fda3
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-user-message.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-user-profile-buffer.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-user-profile-buffer.el
new file mode 100644
index 0000000000..cbc06d2593
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-user-profile-buffer.el
@@ -0,0 +1,88 @@
+;;; slack-user-profile-buffer.el ---                 -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2017
+
+;; Author:  <yuya373@yuya373>
+;; Keywords:
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'eieio)
+(require 'slack-util)
+(require 'slack-buffer)
+
+(define-derived-mode slack-user-profile-buffer-mode slack-buffer-mode "Slack User Profile")
+
+(defclass slack-user-profile-buffer (slack-buffer)
+  ((user-id :initarg :user-id :type string)))
+
+(defun slack-create-user-profile-buffer (team user-id)
+  (slack-if-let* ((buf (slack-buffer-find 'slack-user-profile-buffer
+                                    user-id team)))
+      buf
+    (slack-user-profile-buffer :team team
+                               :user-id user-id)))
+
+(defmethod slack-buffer-buffer ((this slack-user-profile-buffer))
+  (slack-if-let* ((buf (get-buffer (slack-buffer-name this))))
+      (progn
+        (slack-buffer--insert this)
+        buf)
+    (slack-buffer-init-buffer this)))
+
+(defmethod slack-buffer-name :static ((class slack-user-profile-buffer) user-id team)
+  (format "*Slack - %s : Profile - %s*" (oref team name) (slack-user-name user-id team)))
+
+(defmethod slack-buffer-name ((this slack-user-profile-buffer))
+  (with-slots (user-id team) this
+    (slack-buffer-name 'slack-user-profile-buffer
+                       user-id
+                       team)))
+
+(defmethod slack-buffer--insert ((this slack-user-profile-buffer))
+  (let ((buf (get-buffer (slack-buffer-name this))))
+    (with-current-buffer buf
+      (let ((inhibit-read-only t))
+        (setq buffer-read-only nil)
+        (erase-buffer)
+        (goto-char (point-min))
+        (with-slots (user-id team) this
+          (insert (slack-user-profile-to-string user-id team)))
+        (setq buffer-read-only t)
+        (slack-buffer-enable-emojify)
+        (goto-char (point-min))))))
+
+(defmethod slack-buffer-init-buffer ((this slack-user-profile-buffer))
+  (let ((buf (call-next-method)))
+    (with-current-buffer buf
+      (slack-user-profile-buffer-mode)
+      (slack-buffer-set-current-buffer this))
+    (slack-buffer--insert this)
+    buf))
+
+(defmethod slack-buffer-display-im ((this slack-user-profile-buffer))
+  (with-slots (user-id team) this
+    (let ((im (slack-im-find-by-user-id user-id team)))
+      (slack-room-display im team))))
+
+
+
+(provide 'slack-user-profile-buffer)
+;;; slack-user-profile-buffer.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-user-profile-buffer.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-user-profile-buffer.elc
new file mode 100644
index 0000000000..874ba45b8d
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-user-profile-buffer.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-user.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-user.el
new file mode 100644
index 0000000000..0a1fae7c1d
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-user.el
@@ -0,0 +1,385 @@
+;;; slack-user.el ---slack user interface            -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2015  南優也
+
+;; Author: 南優也 <yuyaminami@minamiyuunari-no-MacBook-Pro.local>
+;; Keywords:
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'slack-util)
+(require 'slack-request)
+(require 'slack-room)
+
+(defconst slack-dnd-team-info-url "https://slack.com/api/dnd.teamInfo")
+(defconst slack-dnd-end-dnd-url "https://slack.com/api/dnd.endDnd")
+(defconst slack-dnd-set-snooze-url "https://slack.com/api/dnd.setSnooze")
+(defconst slack-set-presence-url "https://slack.com/api/users.setPresence")
+(defconst slack-user-info-url "https://slack.com/api/users.info")
+(defconst slack-user-profile-set-url "https://slack.com/api/users.profile.set")
+(defconst slack-bot-info-url "https://slack.com/api/bots.info")
+(defconst slack-bot-list-url "https://slack.com/api/bots.list")
+(defvar slack-current-user-id nil)
+
+(defun slack-user--find (id team)
+  (with-slots (users) team
+    (cl-find-if (lambda (user)
+                  (string= id (plist-get user :id)))
+                users)))
+
+(defun slack-user-find-by-name (name team)
+  (with-slots (users) team
+    (cl-find-if (lambda (user)
+                  (string= name (plist-get user :name)))
+                users)))
+
+(defun slack-user-get-id (name team)
+  (let ((user (slack-user-find-by-name name team)))
+    (if user
+        (plist-get user :id))))
+
+(defun slack-user-name (id team)
+  (slack-if-let* ((user (slack-user--find id team)))
+      (if (oref team full-and-display-names)
+          (plist-get user :real_name)
+        (plist-get user :name))))
+
+(defun slack-user-status (id team)
+  (let* ((user (slack-user--find id team))
+         (profile (and user (plist-get user :profile)))
+         (emoji (and profile (plist-get profile :status_emoji)))
+         (text (and profile (plist-get profile :status_text))))
+    (mapconcat #'identity (cl-remove-if #'null (list emoji text))
+               " ")))
+
+(defun slack-user-names (team)
+  (with-slots (users) team
+    (mapcar (lambda (u) (cons (plist-get u :name) u))
+            users)))
+
+(defun slack-user-dnd-in-range-p (user)
+  (let ((current (time-to-seconds))
+        (dnd-start (plist-get (plist-get user :dnd_status) :next_dnd_start_ts))
+        (dnd-end (plist-get (plist-get user :dnd_status) :next_dnd_end_ts)))
+    (and dnd-start dnd-end
+         (<= dnd-start current)
+         (<= current dnd-end))))
+
+(defun slack-user-dnd-status-to-string (user)
+  (if (slack-user-dnd-in-range-p user)
+      "Z"
+    nil))
+
+(defun slack-user-presence-to-string (user)
+  (if (string= (plist-get user :presence) "active")
+      "*"
+    " "))
+
+(defun slack-user-set-status ()
+  (interactive)
+  (let ((team (slack-team-select))
+        (emoji (slack-select-emoji))
+        (text (read-from-minibuffer "Text: ")))
+    (slack-user-set-status-request  team emoji text)))
+
+(defun slack-user-set-status-request (team emoji text)
+  (cl-labels ((on-success
+               (&key data &allow-other-keys)
+               (slack-request-handle-error
+                (data "slack-user-set-status-request"))))
+    (slack-request
+     (slack-request-create
+      slack-user-profile-set-url
+      team
+      :type "POST"
+      :data (list (cons "id" (oref team self-id))
+                  (cons "profile"
+                        (json-encode (list (cons "status_text" text)
+                                           (cons "status_emoji" emoji)))))
+      :success #'on-success))))
+
+(defun slack-bot-info-request (bot_id team &optional after-success)
+  (cl-labels
+      ((on-success (&key data &allow-other-keys)
+                   (slack-request-handle-error
+                    (data "slack-bot-info-request")
+                    (push (plist-get data :bot) (oref team bots))
+                    (if after-success
+                        (funcall after-success team)))))
+    (slack-request
+     (slack-request-create
+      slack-bot-info-url
+      team
+      :params (list (cons "bot" bot_id))
+      :success #'on-success))))
+
+(defun slack-bot-list-update (&optional team)
+  (interactive)
+  (let ((team (or team (slack-team-select))))
+    (cl-labels
+        ((on-success
+          (&key data &allow-other-keys)
+          (slack-request-handle-error
+           (data "slack-bot-list-update")
+           (oset team bots (append (plist-get data :bots) nil)))))
+      (slack-request
+       (slack-request-create
+        slack-bot-list-url
+        team
+        :success #'on-success)))))
+
+(defface slack-user-profile-header-face
+  '((t (:foreground "#FFA000"
+                    :weight bold
+                    :height 1.5)))
+  "Face used to user profile header."
+  :group 'slack)
+
+(defface slack-user-profile-property-name-face
+  '((t (:weight bold :height 1.2)))
+  "Face used to user property."
+  :group 'slack)
+
+(define-derived-mode slack-user-profile-mode fundamental-mode "Slack User"
+  ""
+  (setq-local default-directory slack-default-directory))
+
+(defun slack-user-profile (user)
+  (plist-get user :profile))
+
+(defun slack-user-fname (user)
+  (plist-get (slack-user-profile user) :first_name))
+
+(defun slack-user-lname (user)
+  (plist-get (slack-user-profile user) :last_name))
+
+(defun slack-user-header (user)
+  (let* ((fname (slack-user-fname user))
+         (lname (slack-user-lname user))
+         (name (plist-get user :name)))
+    (or (and fname lname
+             (format "%s %s - @%s"
+                     (slack-user-fname user)
+                     (slack-user-lname user)
+                     (plist-get user :name)))
+        name)))
+
+(defun slack-user-timezone (user)
+  (let ((offset (/ (plist-get user :tz_offset) (* 60 60))))
+    (format "%s, %s"
+            (or (plist-get user :tz)
+                (plist-get user :tz_label))
+            (if (<= 0 offset)
+                (format "+%s hour" offset)
+              (format "%s hour" offset)))))
+
+(defun slack-user-property-to-str (value title)
+  (and value (< 0 (length value))
+       (format "%s\n\t%s"
+               (propertize title 'face 'slack-user-profile-property-name-face)
+               value)))
+
+(defun slack-user-profile-to-string (id team)
+  (let* ((user (slack-user--find id team))
+         (profile (slack-user-profile user))
+         (header (propertize (slack-user-header user)
+                             'face 'slack-user-profile-header-face))
+         (presence (slack-user-property-to-str (plist-get user :presence) "Presence"))
+         (status (slack-user-property-to-str (slack-user-status id team) "Status"))
+         (timezone (slack-user-property-to-str (slack-user-timezone user) "Timezone"))
+         (email (slack-user-property-to-str (plist-get profile :email) "Email"))
+         (phone (slack-user-property-to-str (plist-get profile :phone) "Phone"))
+         (skype (slack-user-property-to-str (plist-get profile :skype) "Skype"))
+         (body (mapconcat #'identity
+                          (cl-remove-if #'null
+                                        (list presence status timezone email phone skype))
+                          "\n"))
+         (dm-button (propertize "[Open Direct Message]"
+                                'face '(:underline t)
+                                'keymap (let ((map (make-sparse-keymap)))
+                                          (define-key map (kbd "RET")
+                                            #'(lambda ()
+                                                (interactive)
+                                                (slack-if-let* ((buf slack-current-buffer))
+                                                  (slack-buffer-display-im buf))))
+                                          map))))
+    (format "%s\n%s\n\n%s" header body dm-button)))
+
+(defun slack-user-self-p (user-id team)
+  (string= user-id (oref team self-id)))
+
+(defun slack-user-name-alist (team &key filter)
+  (let ((users (oref team users)))
+    (mapcar #'(lambda (e) (cons (slack-user-name (plist-get e :id) team) e))
+            (if filter (funcall filter users)
+              users))))
+
+(defun slack-user-hidden-p (user)
+  (not (eq (plist-get user :deleted) :json-false)))
+
+(defun slack-user-select ()
+  (interactive)
+  (let* ((team (slack-team-select))
+         (alist (slack-user-name-alist
+                 team
+                 :filter #'(lambda (users)
+                             (cl-remove-if #'slack-user-hidden-p users)))))
+    (slack-select-from-list (alist "Select User: ")
+        (let ((buf (slack-create-user-profile-buffer team (plist-get selected :id))))
+          (slack-buffer-display buf)))))
+
+(cl-defun slack-user-info-request (user-id team &key after-success)
+  (cl-labels
+      ((on-success
+        (&key data &allow-other-keys)
+        (slack-request-handle-error
+         (data "slack-user-info-request")
+         (oset team users (cons (plist-get data :user)
+                                (cl-remove-if #'(lambda (user)
+                                                  (string= (plist-get user :id) user-id))
+                                              (oref team users))))
+         (slack-im-open (plist-get data :user))
+         (when after-success (funcall after-success)))))
+    (slack-request
+     (slack-request-create
+      slack-user-info-url
+      team
+      :params (list (cons "user" user-id))
+      :success #'on-success))))
+
+(defun slack-user-image-url-24 (user)
+  (plist-get (slack-user-profile user) :image_24))
+
+(defun slack-user-image-url-32 (user)
+  (plist-get (slack-user-profile user) :image_32))
+
+(defun slack-user-image-url-48 (user)
+  (plist-get (slack-user-profile user) :image_48))
+
+(defun slack-user-image-url-72 (user)
+  (plist-get (slack-user-profile user) :image_72))
+
+(defun slack-user-image-url (user size)
+  (cond
+   ((eq size 24) (slack-user-image-url-24 user))
+   ((eq size 32) (slack-user-image-url-32 user))
+   ((eq size 48) (slack-user-image-url-48 user))
+   ((eq size 72) (slack-user-image-url-72 user))
+   (t (slack-user-image-url-32 user))))
+
+(defun slack-user-fetch-image (user size team)
+  (let* ((image-url (slack-user-image-url user size))
+         (file-path (and image-url (slack-profile-image-path image-url team))))
+    (when file-path
+      (if (file-exists-p file-path) file-path
+        (slack-url-copy-file image-url file-path
+                             :success (lambda ()
+                                        (slack-log (format "Success download Image: %s"
+                                                           file-path)
+                                                   team)))))
+    file-path))
+
+(cl-defun slack-user-image (user team &optional (size 32))
+  (when user
+    (let ((image (slack-user-fetch-image user size team)))
+      (when image
+        (create-image image nil nil :ascent 80)))))
+
+(defun slack-user-presence (user)
+  (plist-get user :presence))
+
+(defun slack-request-set-presence (team &optional presence)
+  (unless presence
+    (let ((current-presence (slack-user-presence (slack-user--find (oref team self-id)
+                                                                   team))))
+
+      (setq presence (or (and (string= current-presence "away") "auto")
+                         "away"))
+      ))
+  (cl-labels
+      ((on-success (&key data &allow-other-keys)
+                   (slack-request-handle-error
+                    (data "slack-request-set-presence"))))
+    (slack-request
+     (slack-request-create
+      slack-set-presence-url
+      team
+      :success #'on-success
+      :params (list (cons "presence" presence))))))
+
+(defun slack-request-dnd-set-snooze (team time)
+  (cl-labels
+      ((on-success (&key data &allow-other-keys)
+                   (slack-request-handle-error
+                    (data "slack-request-dnd-set-snooze")
+                    (message "setSnooze: %s" data))))
+    (let* ((input (slack-parse-time-string time))
+           (num-minutes (and time (/ (- (time-to-seconds input) (time-to-seconds))
+                                     60))))
+      (unless num-minutes
+        (error "Invalid time string %s" time))
+      (slack-request
+       (slack-request-create
+        slack-dnd-set-snooze-url
+        team
+        :success #'on-success
+        :params (list (cons "num_minutes" (format "%s" num-minutes))))))))
+
+(defun slack-request-dnd-end-dnd (team)
+  (cl-labels
+      ((on-success (&key data &allow-other-keys)
+                   (slack-request-handle-error
+                    (data "slack-request-dnd-end-dnd")
+                    (message "endDnd: %s" data))))
+    (slack-request
+     (slack-request-create
+      slack-dnd-end-dnd-url
+      team
+      :success #'on-success
+      ))))
+
+(defun slack-user-update-dnd-status (user dnd-status)
+  (plist-put user :dnd_status dnd-status))
+
+(defun slack-request-dnd-team-info (team &optional after-success)
+  (cl-labels
+      ((on-success
+        (&key data &allow-other-keys)
+        (slack-request-handle-error
+         (data "slack-request-dnd-team-info")
+         (let ((users (plist-get data :users)))
+           (oset team users
+                 (cl-loop for user in (oref team users)
+                          collect (plist-put
+                                   user
+                                   :dnd_status
+                                   (plist-get users
+                                              (intern (format ":%s"
+                                                              (plist-get user :id)))))))))
+        (when (functionp after-success)
+          (funcall after-success team))))
+    (slack-request
+     (slack-request-create
+      slack-dnd-team-info-url
+      team
+      :success #'on-success))))
+
+(provide 'slack-user)
+;;; slack-user.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-user.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-user.elc
new file mode 100644
index 0000000000..1a2db9be4c
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-user.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-util.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-util.el
new file mode 100644
index 0000000000..37c154d988
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-util.el
@@ -0,0 +1,471 @@
+;;; slack-util.el ---utility functions               -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2015  yuya.minami
+
+;; Author: yuya.minami <yuya.minami@yuyaminami-no-MacBook-Pro.local>
+;; Keywords:
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'eieio)
+(require 'timer)
+(require 'diary-lib)
+
+(defcustom slack-profile-image-file-directory temporary-file-directory
+  "Default directory for slack profile images."
+  :group 'slack)
+
+(defcustom slack-image-file-directory temporary-file-directory
+  "Default directory for slack images."
+  :group 'slack)
+
+(defcustom slack-image-max-height 300
+  "Max Height of image.  nil is unlimited.  integer."
+  :group 'slack)
+
+(defconst slack-log-levels
+  '(;; debugging
+    (trace . 40) (debug . 30)
+    ;; information
+    (info . 20)
+    ;; errors
+    (warn . 10) (error . 0))
+  "Named logging levels.")
+
+(defcustom slack-log-level 'info
+  "Used in `slack-message-logger'.
+One of 'info, 'debug"
+  :group 'slack)
+
+(defcustom slack-log-time-format
+  "[%Y-%m-%d %H:%M:%S]"
+  "Time format for log."
+  :group 'slack)
+
+(defalias 'slack-if-let*
+  (if (fboundp 'if-let*)
+      'if-let*
+    'if-let))
+
+(defun slack-seq-to-list (seq)
+  (if (listp seq) seq (append seq nil)))
+
+(defun slack-decode (seq)
+  (cl-loop for e in (slack-seq-to-list seq)
+           collect (if (stringp e)
+                       (decode-coding-string e 'utf-8)
+                     (if (listp e)
+                         (slack-decode e)
+                       e))))
+
+(defun slack-class-have-slot-p (class slot)
+  (and (symbolp slot)
+       (let* ((stripped (substring (symbol-name slot) 1))
+              (replaced (replace-regexp-in-string "_" "-"
+                                                  stripped))
+              (symbolized (intern replaced)))
+         (slot-exists-p class symbolized))))
+
+(defun slack-collect-slots (class seq)
+  (let ((plist (slack-seq-to-list seq)))
+    (cl-loop for p in plist
+             if (and (slack-class-have-slot-p class p)
+                     (plist-member plist p))
+             nconc (let ((value (plist-get plist p)))
+                     (list p (if (stringp value)
+                                 (decode-coding-string value 'utf-8)
+                               (if (eq :json-false value)
+                                   nil
+                                 value)))))))
+(defun slack-log-level-to-int (level)
+  (slack-if-let* ((cell (cl-assoc level slack-log-levels)))
+      (cdr cell)
+    20))
+
+
+(defun slack-message-logger (message level team)
+  "Display message using `message'."
+  (let ((user-level (slack-log-level-to-int slack-log-level))
+        (current-level (slack-log-level-to-int level)))
+    (when (<= current-level user-level)
+      (message (format "%s [%s] [%s] %s"
+                       (format-time-string slack-log-time-format)
+                       level
+                       (oref team name)
+                       message)))))
+
+(cl-defun slack-log (msg team &key
+                         (logger #'slack-message-logger)
+                         (level 'debug))
+  (let ((log (format "%s [%s] %s - %s"
+                     (format-time-string slack-log-time-format)
+                     level
+                     msg
+                     (oref team name)))
+        (buf (get-buffer-create (slack-log-buffer-name team))))
+    (when (functionp logger)
+      (funcall logger msg level team))
+    (with-current-buffer buf
+      (setq buffer-read-only nil)
+      (save-excursion
+        (goto-char (point-max))
+        (insert log)
+        (insert "\n"))
+      (setq buffer-read-only t))))
+
+(defun company-slack-backend (command &optional arg &rest ignored)
+  "Completion backend for slack chats.  It currently understands
+@USER; adding #CHANNEL should be a simple matter of programming."
+  (interactive (list 'interactive))
+  (cl-labels
+      ((start-from-line-beginning (str)
+                                  (let ((prompt-length (length lui-prompt-string)))
+                                    (>= 0 (- (current-column) prompt-length (length str)))))
+       (prefix-type (str) (cond
+                           ((string-prefix-p "@" str) 'user)
+                           ((string-prefix-p "#" str) 'channel)
+                           ((and (string-prefix-p "/" str)
+                                 (start-from-line-beginning str))
+                            'slash)))
+       (content (str) (substring str 1 nil)))
+    (cl-case command
+      (interactive (company-begin-backend 'company-slack-backend))
+      (prefix (when (string= "slack" (car (split-string (format "%s" major-mode) "-")))
+                  ;; (cl-find major-mode '(slack-mode
+                  ;;                         slack-edit-message-mode
+                  ;;                         slack-thread-mode))
+                (company-grab-line "\\(\\W\\|^\\)\\(@\\w*\\|#\\w*\\|/\\w*\\)"
+                                   2)))
+      (candidates (let ((content (content arg)))
+                    (cl-case (prefix-type arg)
+                      (user
+                       (cl-loop for user in (oref slack-current-team users)
+                                if (and (not (eq (plist-get user :deleted) t))
+                                        (string-prefix-p content
+                                                         (plist-get user :name)))
+                                collect (concat "@" (plist-get user :name))))
+                      (channel
+                       (cl-loop for team in (oref slack-current-team channels)
+                                if (string-prefix-p content
+                                                    (oref team name))
+                                collect (concat "#" (oref team name))))
+                      (slash
+                       (cl-loop for com in slack-slash-commands-available
+                                if (string-prefix-p content com)
+                                collect (concat "/" com))
+                       ))))
+      (doc-buffer
+       (cl-case (prefix-type arg)
+         (slash
+          (company-doc-buffer
+           (documentation
+            (slack-slash-commands-find (substring arg 1))
+            t)))))
+      )))
+
+(defun slack-get-ts ()
+  (get-text-property 0 'ts (thing-at-point 'line)))
+
+(defun slack-linkfy (text link)
+  (if (not (slack-string-blankp link))
+      (format "<%s|%s>" link text)
+    text))
+
+(defun slack-string-blankp (str)
+  (if str
+      (> 1 (length str))
+    t))
+
+(defun slack-log-buffer-name (team)
+  (format "*Slack Log - %s*" (slack-team-name team)))
+
+(defun slack-log-open-buffer ()
+  (interactive)
+  (let ((team (slack-team-select)))
+    (funcall slack-buffer-function (get-buffer-create (slack-log-buffer-name team)))))
+
+(defun slack-event-log-buffer-name (team)
+  (format "*Slack Event Log - %s*" (slack-team-name team)))
+
+(defun slack-log-websocket-payload (payload team)
+  (let* ((bufname (slack-event-log-buffer-name team))
+         (buf (get-buffer-create bufname)))
+    (when buf
+      (with-current-buffer buf
+        (setq buffer-read-only nil)
+        (save-excursion
+          (goto-char (point-max))
+          (insert (format "[%s] %s\n"
+                          (format-time-string "%Y-%m-%d %H:%M:%S")
+                          payload)))
+        (setq buffer-read-only t)))))
+
+(defun slack-log-open-websocket-buffer ()
+  (interactive)
+  (if websocket-debug
+      (progn
+        (let* ((team (slack-team-select))
+               (websocket (oref team ws-conn)))
+          (if websocket
+              (funcall slack-buffer-function
+                       (websocket-get-debug-buffer-create websocket))
+            (error "Websocket is not connected"))))
+    (error "`websocket-debug` is not t")))
+
+(defun slack-log-open-event-buffer ()
+  (interactive)
+  (let* ((team (slack-team-select))
+         (bufname (slack-event-log-buffer-name team))
+         (buf (get-buffer bufname)))
+    (if buf
+        (funcall slack-buffer-function buf)
+      (error "No Event Log Buffer"))))
+
+(defun slack-profile-image-path (image-url team)
+  (expand-file-name
+   (concat (md5 (concat (slack-team-name team) "-" image-url))
+           "."
+           (file-name-extension image-url))
+   slack-profile-image-file-directory))
+
+(cl-defun slack-image--create (path &key (width nil) (height nil) (max-height nil) (max-width nil))
+  (let* ((imagemagick-available-p (image-type-available-p 'imagemagick))
+         (image (apply #'create-image (append (list path (and imagemagick-available-p 'imagemagick) nil)
+                                              (if height (list :height height))
+                                              (if width (list :width width))
+                                              (if max-height
+                                                  (list :max-height max-height))
+                                              (if max-width
+                                                  (list :max-width max-width))))))
+    (if imagemagick-available-p
+        (slack-image-shrink image max-height)
+      image)))
+
+(defun slack-image-exists-p (image-spec)
+  (file-exists-p (slack-image-path (car image-spec))))
+
+(defun slack-image-string (spec)
+  "SPEC: (list URL WIDTH HEIGHT MAX-HEIGHT MAX-WIDTH)"
+  (if spec
+      (slack-if-let* ((path (slack-image-path (car spec))))
+          (if (file-exists-p path)
+              (slack-mapconcat-images
+               (slack-image-slice
+                (slack-image--create path
+                                     :width (cadr spec)
+                                     :height (caddr spec)
+                                     :max-height (cadddr spec)
+                                     :max-width (cadr (cdddr spec)))))
+            (propertize "[Image]" 'slack-image-spec spec))
+        "")
+    ""))
+
+(defun slack-image-path (image-url)
+  (and image-url
+       (expand-file-name
+        (concat (md5 image-url)
+                "."
+                (file-name-extension image-url))
+        slack-image-file-directory)))
+
+(defun slack-image-slice (image)
+  (when image
+    (let* ((line-height 50.0)
+           (height (or (plist-get (cdr image) :height)
+                       (cdr (image-size image t))))
+           (line-count (/ height line-height))
+           (line (/ 1.0 line-count)))
+      (if (< line-height height)
+          (cl-loop for i from 0 to (- line-count 1)
+                   collect (list (list 'slice 0 (* line i) 1.0 line)
+                                 image))
+        (list image)))))
+
+(defun slack-image-shrink (image &optional max-height)
+  (unless (image-type-available-p 'imagemagick)
+    (error "Need Imagemagick"))
+  (if max-height
+      (let* ((data (plist-get (cdr image) :data))
+             (file (plist-get (cdr image) :file))
+             (size (image-size image t))
+             (height (cdr size))
+             (width (car size))
+             (h (min height max-height))
+             (w (if (< max-height height)
+                    (ceiling
+                     (* (/ (float max-height) height)
+                        width))
+                  width)))
+        (create-image (or file data) 'imagemagick data :height h :width w))
+    image))
+
+(defun slack-mapconcat-images (images)
+  (when images
+    (cl-labels ((sort-images (images)
+                             (let ((compare (if (or (and (eq system-type 'darwin) (< emacs-major-version 26))
+						    (< emacs-major-version 25))
+                                                #'>
+                                              #'<)))
+                               (cl-sort images compare :key #'(lambda (image) (caddr (car image))))))
+                (propertize-image (image)
+                                  (propertize "image"
+                                              'display image
+                                              'face 'slack-profile-image-face)))
+      (mapconcat #'propertize-image (sort-images images) "\n"))))
+
+(cl-defun slack-url-copy-file (url newname &key (success nil) (error nil) (sync nil) (token nil))
+  (if (executable-find "curl")
+      (slack-curl-downloader url newname
+                             :success success
+                             :error error
+                             :token token)
+    (cl-labels
+        ((on-success (&key data &allow-other-keys)
+                     (when (functionp success) (funcall success)))
+         (on-error (&key error-thrown symbol-status response data)
+                   (message "Error Fetching Image: %s %s %s, url: %s"
+                            (request-response-status-code response)
+                            error-thrown symbol-status url)
+                   (if (file-exists-p newname)
+                       (delete-file newname))
+                   (case (request-response-status-code response)
+                     (403 nil)
+                     (404 nil)
+                     (t (when (functionp error)
+                          (funcall error
+                                   (request-response-status-code response)
+                                   error-thrown
+                                   symbol-status
+                                   url)))))
+         (parser () (mm-write-region (point-min) (point-max)
+                                     newname nil nil nil 'binary t)))
+      (let* ((url-obj (url-generic-parse-url url))
+             (need-token-p (and url-obj
+                                (string-match-p "slack"
+                                                (url-host url-obj))))
+             (use-https-p (and url-obj
+                               (string= "https" (url-type url-obj)))))
+        (request
+         url
+         :success #'on-success
+         :error #'on-error
+         :parser #'parser
+         :sync sync
+         :headers (if (and token use-https-p need-token-p)
+                      (list (cons "Authorization" (format "Bearer %s" token)))))))))
+
+(defun slack-render-image (image team)
+  (let ((buf (get-buffer-create
+              (format "*Slack - %s Image*" (slack-team-name team)))))
+    (with-current-buffer buf
+      (setq buffer-read-only nil)
+      (erase-buffer)
+      (if image
+          (insert (slack-mapconcat-images (slack-image-slice image)))
+        (insert "Loading Image..."))
+      (setq buffer-read-only t)
+      (goto-char (point-min)))
+
+    buf))
+
+(defun slack-parse-time-string (time)
+  "TIME should be one of:
+- a string giving today’s time like \"11:23pm\"
+  (the acceptable formats are HHMM, H:MM, HH:MM, HHam, HHAM,
+  HHpm, HHPM, HH:MMam, HH:MMAM, HH:MMpm, or HH:MMPM;
+  a period ‘.’ can be used instead of a colon ‘:’ to separate
+  the hour and minute parts);
+- a string giving specific date and time like \"1991/03/23 03:00\";
+- a string giving a relative time like \"90\" or \"2 hours 35 minutes\"
+  (the acceptable forms are a number of seconds without units
+  or some combination of values using units in ‘timer-duration-words’);
+- a number of seconds from now;"
+  (if (numberp time)
+      (setq time (timer-relative-time nil time)))
+  (if (stringp time)
+      (let ((secs (timer-duration time)))
+        (if secs
+            (setq time (timer-relative-time nil secs)))))
+  (if (stringp time)
+      (progn
+        (let* ((date-and-time (split-string time " "))
+               (date (and (eq (length date-and-time) 2) (split-string (car date-and-time) "/")))
+               (time-str (or (and (eq (length date-and-time) 2) (cadr date-and-time))
+                             (car date-and-time)))
+               (hhmm (diary-entry-time time-str))
+               (now (or (and date (decode-time
+                                   (encode-time 0 0 0
+                                                (string-to-number (nth 2 date))
+                                                (string-to-number (nth 1 date))
+                                                (string-to-number (nth 0 date))
+                                                )))
+                        (decode-time))))
+          (if (>= hhmm 0)
+              (setq time
+                    (encode-time 0 (% hhmm 100) (/ hhmm 100) (nth 3 now)
+                                 (nth 4 now) (nth 5 now) (nth 8 now)))))))
+  time)
+
+(defmacro slack-merge-list (old-list new-list)
+  `(cl-loop for n in ,new-list
+            do (let ((o (cl-find-if #'(lambda (e) (slack-equalp n e))
+                                    ,old-list)))
+                 (if o (slack-merge o n)
+                   (push n ,old-list)))))
+
+(cl-defun slack-curl-downloader (url name &key (success nil) (error nil) (token nil))
+  (cl-labels
+      ((sentinel (proc event)
+                 (cond
+                  ((string-equal "finished\n" event)
+                   (when (functionp success) (funcall success)))
+                  (t
+                   (let ((status (process-status proc))
+                         (output (with-current-buffer (process-buffer proc)
+                                   (buffer-substring-no-properties (point-min)
+                                                                   (point-max)))))
+                     (if (functionp error)
+                         (funcall error status output url name)
+                       (message "Download Failed. STATUS: %s, EVENT: %s, URL: %s, NAME: %s, OUTPUT: %s"
+                                status
+                                event
+                                url
+                                name
+                                output))
+                     (if (file-exists-p name)
+                         (delete-file name))
+                     (delete-process proc))))))
+    (let* ((url-obj (url-generic-parse-url url))
+           (need-token-p (and url-obj
+                              (string-match-p "slack" (url-host url-obj))))
+           (header (or (and token
+                            need-token-p
+                            (string-prefix-p "https" url)
+                            (format "-H 'Authorization: Bearer %s'" token))
+                       ""))
+           (output (format "--output '%s'" name))
+           (command (format "curl --silent --show-error --fail --location %s %s '%s'" output header url))
+           (proc (start-process-shell-command "slack-curl-downloader"
+                                              "slack-curl-downloader"
+                                              command)))
+      (set-process-sentinel proc #'sentinel))))
+
+(provide 'slack-util)
+;;; slack-util.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-util.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-util.elc
new file mode 100644
index 0000000000..6763ac0ffc
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-util.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-websocket.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-websocket.el
new file mode 100644
index 0000000000..37e395d820
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-websocket.el
@@ -0,0 +1,1018 @@
+;;; slack-websocket.el --- slack websocket interface  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2015  南優也
+
+;; Author: 南優也 <yuyaminami@minamiyuunari-no-MacBook-Pro.local>
+;; Keywords:
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+(require 'websocket)
+(require 'slack-util)
+(require 'slack-request)
+(require 'slack-message)
+(require 'slack-team)
+(require 'slack-reply)
+(require 'slack-file)
+(defconst slack-api-test-url "https://slack.com/api/api.test")
+
+(defclass slack-typing ()
+  ((room :initarg :room :initform nil)
+   (limit :initarg :limit :initform nil)
+   (users :initarg :users :initform nil)))
+
+(defclass slack-typing-user ()
+  ((limit :initarg :limit :initform nil)
+   (user-name :initarg :user-name :initform nil)))
+
+(defun slack-ws-set-connect-timeout-timer (team)
+  (slack-ws-cancel-connect-timeout-timer team)
+  (cl-labels
+      ((on-timeout ()
+                   (slack-log (format "websocket open timeout")
+                              team)
+                   (slack-ws-close team)
+                   (slack-ws-set-reconnect-timer team)))
+    (oset team websocket-connect-timeout-timer
+          (run-at-time (oref team websocket-connect-timeout-sec)
+                       nil
+                       #'on-timeout))))
+
+(defun slack-ws-cancel-connect-timeout-timer (team)
+  (when (timerp (oref team websocket-connect-timeout-timer))
+    (cancel-timer (oref team websocket-connect-timeout-timer))
+    (oset team websocket-connect-timeout-timer nil)))
+
+(cl-defun slack-ws-open (team &key (on-open nil) (ws-url nil))
+  (slack-if-let* ((conn (oref team ws-conn))
+                  (state (websocket-ready-state conn)))
+      (cond ((websocket-openp conn)
+             (slack-log "Websocket is Already Open" team))
+            ((eq state 'connecting)
+             (slack-log "Websocket is connecting" team))
+            ((eq state 'closed)
+             (slack-log "Websocket is closed" team)))
+
+    (progn
+      (slack-ws-set-connect-timeout-timer team)
+      (cl-labels
+          ((on-message (websocket frame)
+                       (slack-ws-on-message websocket frame team))
+           (handle-on-open (_websocket)
+                           (oset team reconnect-count 0)
+                           (oset team connected t)
+                           (slack-log "WebSocket on-open"
+                                      team :level 'debug)
+                           (when (functionp on-open)
+                             (funcall on-open)))
+           (on-close (websocket)
+                     (oset team ws-conn nil)
+                     (oset team connected nil)
+                     (slack-log (format "Websocket on-close: STATE: %s"
+                                        (websocket-ready-state websocket))
+                                team :level 'debug)
+                     (unwind-protect
+                         (progn
+                           (unless (oref team inhibit-reconnection)
+                             (slack-ws-set-reconnect-timer team)))
+                       (oset team inhibit-reconnection nil)))
+           (on-error (_websocket type err)
+                     (slack-log (format "Error on `websocket-open'. TYPE: %s, ERR: %s"
+                                        type err)
+                                team
+                                :level 'error)))
+        (oset team ws-conn
+              (condition-case error-var
+                  (websocket-open (or ws-url (oref team ws-url))
+                                  :on-message #'on-message
+                                  :on-open #'handle-on-open
+                                  :on-close #'on-close
+                                  :on-error #'on-error
+                                  :nowait (oref team websocket-nowait))
+                (error
+                 (slack-log (format "An Error occured while opening websocket connection: %s"
+                                    error-var)
+                            team
+                            :level 'error)
+                 ;; (slack-ws-close team)
+                 ;; (slack-ws-set-reconnect-timer team)
+                 nil)))))))
+
+(cl-defun slack-ws-close (&optional team (close-reconnection nil))
+  (interactive)
+  (unless team
+    (setq team slack-teams))
+  (let ((called-interactively (called-interactively-p 'any)))
+    (cl-labels
+        ((close (team)
+                (slack-ws-cancel-ping-timer team)
+                (slack-ws-cancel-ping-check-timers team)
+                (when (or close-reconnection
+                          called-interactively)
+                  (slack-ws-cancel-reconnect-timer team)
+                  (oset team inhibit-reconnection t))
+                (with-slots (connected ws-conn last-pong) team
+                  (when ws-conn
+                    (websocket-close ws-conn)
+                    (slack-log "Slack Websocket Closed" team)))))
+      (if (listp team)
+          (progn
+            (mapc #'close team)
+            (slack-request-worker-quit))
+        (close team)
+        (slack-request-worker-remove-request team)
+        )
+      )))
+
+(defun slack-ws-send (payload team)
+  (with-slots (waiting-send ws-conn) team
+    (push payload waiting-send)
+    (cl-labels
+        ((reconnect ()
+                    (slack-ws-close team)
+                    (slack-ws-set-reconnect-timer team)))
+      (if (websocket-openp ws-conn)
+          (condition-case err
+              (progn
+                (websocket-send-text ws-conn payload)
+                (setq waiting-send
+                      (cl-remove-if #'(lambda (p) (string= payload p))
+                                    waiting-send)))
+            (error
+             (slack-log (format "Error in `slack-ws-send`: %s" err)
+                        team :level 'debug)
+             (reconnect)))
+        (reconnect)))))
+
+(defun slack-ws-resend (team)
+  (with-slots (waiting-send) team
+    (let ((candidate waiting-send))
+      (setq waiting-send nil)
+      (cl-loop for msg in candidate
+               do (sleep-for 1) (slack-ws-send msg team)))))
+
+;; (:type error :error (:msg Socket URL has expired :code 1))
+(defun slack-ws-handle-error (payload team)
+  (let* ((err (plist-get payload :error))
+         (code (plist-get err :code)))
+    (cond
+     ((eq 1 code)
+      (slack-ws-close team)
+      (slack-ws-set-reconnect-timer team))
+     (t (slack-log (format "Unknown Error: %s, MSG: %s"
+                           code (plist-get err :msg))
+                   team)))))
+
+(defun slack-ws-on-message (_websocket frame team)
+  ;; (message "%s" (slack-request-parse-payload
+  ;;                (websocket-frame-payload frame)))
+  (when (websocket-frame-completep frame)
+    (let* ((payload (slack-request-parse-payload
+                     (websocket-frame-payload frame)))
+           (decoded-payload (and payload (slack-decode payload)))
+           (type (and decoded-payload
+                      (plist-get decoded-payload :type))))
+      ;; (message "%s" decoded-payload)
+      (when (slack-team-event-log-enabledp team)
+        (slack-log-websocket-payload decoded-payload team))
+      (when decoded-payload
+        (cond
+         ((string= type "error")
+          (slack-ws-handle-error decoded-payload team))
+         ((string= type "pong")
+          (slack-ws-handle-pong decoded-payload team))
+         ((string= type "hello")
+          (slack-ws-cancel-connect-timeout-timer team)
+          (slack-ws-cancel-reconnect-timer team)
+          (slack-cancel-notify-adandon-reconnect)
+          (slack-ws-set-ping-timer team)
+          (slack-ws-resend team)
+          (slack-log "Slack Websocket Is Ready!" team :level 'info))
+         ((plist-get decoded-payload :reply_to)
+          (slack-ws-handle-reply decoded-payload team))
+         ((string= type "message")
+          (slack-ws-handle-message decoded-payload team))
+         ((string= type "reaction_added")
+          (slack-ws-handle-reaction-added decoded-payload team))
+         ((string= type "reaction_removed")
+          (slack-ws-handle-reaction-removed decoded-payload team))
+         ((string= type "channel_created")
+          (slack-ws-handle-channel-created decoded-payload team))
+         ((or (string= type "channel_archive")
+              (string= type "group_archive"))
+          (slack-ws-handle-room-archive decoded-payload team))
+         ((or (string= type "channel_unarchive")
+              (string= type "group_unarchive"))
+          (slack-ws-handle-room-unarchive decoded-payload team))
+         ((string= type "channel_deleted")
+          (slack-ws-handle-channel-deleted decoded-payload team))
+         ((or (string= type "channel_rename")
+              (string= type "group_rename"))
+          (slack-ws-handle-room-rename decoded-payload team))
+         ((string= type "channel_joined")
+          (slack-ws-handle-channel-joined decoded-payload team))
+         ((string= type "group_joined")
+          (slack-ws-handle-group-joined decoded-payload team))
+         ((string= type "presence_change")
+          (slack-ws-handle-presence-change decoded-payload team))
+         ((or (string= type "bot_added")
+              (string= type "bot_changed"))
+          (slack-ws-handle-bot decoded-payload team))
+         ((string= type "file_created")
+          (slack-ws-handle-file-created decoded-payload team))
+         ((or (string= type "file_deleted")
+              (string= type "file_unshared"))
+          (slack-ws-handle-file-deleted decoded-payload team))
+         ((string= type "file_comment_added")
+          (slack-ws-handle-file-comment-added decoded-payload team))
+         ((string= type "file_comment_deleted")
+          (slack-ws-handle-file-comment-deleted decoded-payload team))
+         ((string= type "file_comment_edited")
+          (slack-ws-handle-file-comment-edited decoded-payload team))
+         ((or (string= type "im_marked")
+              (string= type "channel_marked")
+              (string= type "group_marked"))
+          (slack-ws-handle-room-marked decoded-payload team))
+         ((string= type "thread_marked")
+          (slack-ws-handle-thread-marked decoded-payload team))
+         ((string= type "thread_subscribed")
+          (slack-ws-handle-thread-subscribed decoded-payload team))
+         ((string= type "im_open")
+          (slack-ws-handle-im-open decoded-payload team))
+         ((string= type "im_close")
+          (slack-ws-handle-im-close decoded-payload team))
+         ((string= type "team_join")
+          (slack-ws-handle-team-join decoded-payload team))
+         ((string= type "user_typing")
+          (slack-ws-handle-user-typing decoded-payload team))
+         ((string= type "user_change")
+          (slack-ws-handle-user-change decoded-payload team))
+         ((string= type "member_joined_channel")
+          (slack-ws-handle-member-joined-channel decoded-payload team))
+         ((string= type "member_left_channel")
+          (slack-ws-handle-member-left_channel decoded-payload team))
+         ((or (string= type "dnd_updated")
+              (string= type "dnd_updated_user"))
+          (slack-ws-handle-dnd-updated decoded-payload team))
+         ((string= type "star_added")
+          (slack-ws-handle-star-added decoded-payload team))
+         ((string= type "star_removed")
+          (slack-ws-handle-star-removed decoded-payload team))
+         ((string= type "reconnect_url")
+          (slack-ws-handle-reconnect-url decoded-payload team)
+          )
+         )))))
+
+(defun slack-ws-handle-reconnect-url (payload team)
+  (oset team reconnect-url (plist-get payload :url)))
+
+(defun slack-user-typing (team)
+  (with-slots (typing typing-timer) team
+    (with-slots (limit users room) typing
+      (let ((current (float-time)))
+        (if (and typing-timer (timerp typing-timer)
+                 (< limit current))
+            (progn
+              (cancel-timer typing-timer)
+              (setq typing-timer nil)
+              (setq typing nil))
+          (if (slack-buffer-show-typing-p
+               (get-buffer (slack-room-buffer-name room)))
+              (let ((team-name (slack-team-name team))
+                    (room-name (slack-room-name room))
+                    (visible-users (cl-remove-if
+                                    #'(lambda (u) (< (oref u limit) current))
+                                    users)))
+                (slack-log
+                 (format "Slack [%s - %s] %s is typing..."
+                         team-name room-name
+                         (mapconcat #'(lambda (u) (oref u user-name))
+                                    visible-users
+                                    ", "))
+                 team
+                 :level 'info))))))))
+
+(defun slack-ws-handle-user-typing (payload team)
+  (let* ((user (slack-user-name (plist-get payload :user) team))
+         (room (slack-room-find (plist-get payload :channel) team)))
+    (if (and user room
+             (slack-buffer-show-typing-p (get-buffer (slack-room-buffer-name room))))
+        (let ((limit (+ 3 (float-time))))
+          (with-slots (typing typing-timer) team
+            (if (and typing (equal room (oref typing room)))
+                (with-slots ((typing-limit limit)
+                             (typing-room room) users) typing
+                  (setq typing-limit limit)
+                  (let ((typing-user (make-instance 'slack-typing-user
+                                                    :limit limit
+                                                    :user-name user)))
+                    (setq users
+                          (cons typing-user
+                                (cl-remove-if #'(lambda (u)
+                                                  (string= (oref u user-name)
+                                                           user))
+                                              users))))))
+            (unless typing
+              (let ((new-typing (make-instance 'slack-typing
+                                               :room room :limit limit))
+                    (typing-user (make-instance 'slack-typing-user
+                                                :limit limit :user-name user)))
+                (oset new-typing users (list typing-user))
+                (setq typing new-typing))
+              (setq typing-timer
+                    (run-with-timer t 1 #'slack-user-typing team))))))))
+
+(defun slack-ws-handle-team-join (payload team)
+  (let ((user (slack-decode (plist-get payload :user))))
+    (slack-user-info-request
+     (plist-get user :id) team
+     :after-success #'(lambda ()
+                        (slack-log (format "User %s Joind Team: %s"
+                                           (plist-get (slack-user--find (plist-get user :id)
+                                                                        team)
+                                                      :name)
+                                           (slack-team-name team))
+                                   team
+                                   :level 'info)))))
+
+(defun slack-ws-handle-im-open (payload team)
+  (cl-labels
+      ((notify
+        (im)
+        (slack-room-history-request
+         im team
+         :after-success #'(lambda (&rest _ignore)
+                            (slack-log (format "Direct Message Channel with %s is Open"
+                                               (slack-user-name (oref im user) team))
+                                       team :level 'info))
+         :async t)))
+    (let ((exist (slack-room-find (plist-get payload :channel) team)))
+      (if exist
+          (progn
+            (oset exist is-open t)
+            (notify exist))
+        (with-slots (ims) team
+          (let ((im (slack-room-create
+                     (list :id (plist-get payload :channel)
+                           :user (plist-get payload :user))
+                     team 'slack-im)))
+            (setq ims (cons im ims))
+            (notify im)))))))
+
+(defun slack-ws-handle-im-close (payload team)
+  (let ((im (slack-room-find (plist-get payload :channel) team)))
+    (when im
+      (oset im is-open nil)
+      (slack-log (format "Direct Message Channel with %s is Closed"
+                         (slack-user-name (oref im user) team))
+                 team :level 'info))))
+
+(defun slack-ws-handle-message (payload team)
+  (let ((subtype (plist-get payload :subtype)))
+    (cond
+     ((and subtype (string= subtype "message_changed"))
+      (slack-ws-change-message payload team))
+     ((and subtype (string= subtype "message_deleted"))
+      (slack-ws-delete-message payload team))
+     ((and subtype (string= subtype "message_replied"))
+      (slack-thread-update-state payload team))
+     (t
+      (slack-ws-update-message payload team)))))
+
+(defun slack-ws-change-message (payload team)
+  (slack-if-let* ((room-id (plist-get payload :channel))
+                  (room (slack-room-find room-id team))
+                  (message-payload (plist-get payload :message))
+                  (ts (plist-get message-payload :ts))
+                  (base (slack-room-find-message room ts))
+                  (new-message-payload (plist-put message-payload :edited-at ts))
+                  (new-message (slack-message-create new-message-payload
+                                                     team
+                                                     :room room)))
+      (slack-message-update base team t
+                            (not (slack-message-changed--copy base new-message)))))
+
+
+(defun slack-ws-delete-message (payload team)
+  (slack-if-let* ((room-id (plist-get payload :channel))
+                  (room (slack-room-find room-id team))
+                  (ts (plist-get payload :deleted_ts))
+                  (message (slack-room-find-message room ts)))
+      (slack-message-deleted message room team)))
+
+(defun slack-ws-update-message (payload team)
+  (let ((m (slack-message-create payload team))
+        (bot_id (plist-get payload :bot_id)))
+    (when m
+      (if (and bot_id (not (slack-find-bot bot_id team)))
+          (slack-bot-info-request bot_id team #'(lambda (team) (slack-message-update m team)))
+        (slack-message-update m team)))))
+
+(defun slack-ws-handle-reply (payload team)
+  (let ((ok (plist-get payload :ok)))
+    (if (eq ok :json-false)
+        (let ((err (plist-get payload :error)))
+          (slack-log (format "Error code: %s msg: %s"
+                             (plist-get err :code)
+                             (plist-get err :msg))
+                     team))
+      (let ((message-id (plist-get payload :reply_to)))
+        (if (integerp message-id)
+            (slack-message-handle-reply
+             (slack-message-create payload team)
+             team))))))
+
+(defun slack-ws-handle-reaction-added (payload team)
+  (let* ((item (plist-get payload :item))
+         (item-type (plist-get item :type))
+         (reaction (make-instance 'slack-reaction
+                                  :name (plist-get payload :reaction)
+                                  :count 1
+                                  :users (list (plist-get payload :user)))))
+    (cl-labels
+        ((update-message (message)
+                         (slack-message-append-reaction message reaction item-type)
+                         (slack-message-update message team t t)))
+      (cond
+       ((string= item-type "file_comment")
+        (let* ((file-id (plist-get item :file))
+               (file (slack-file-find file-id team))
+               (comment-id (plist-get item :file_comment)))
+          (cl-labels
+              ((update (&rest _args)
+                       (slack-with-file file-id team
+                         (slack-with-file-comment comment-id file
+                           (slack-message-append-reaction file-comment reaction)
+                           (slack-message-update file-comment file team)
+                           (cl-loop for room in (append (oref team channels)
+                                                        (oref team ims)
+                                                        (oref team groups))
+                                    do (slack-if-let*
+                                           ((message
+                                             (if (oref file-comment is-intro)
+                                                 (slack-room-find-file-share-message
+                                                  room file-id)
+                                               (slack-room-find-file-comment-message
+                                                room comment-id))))
+                                           (update-message message)))))))
+            (if file (update)
+              (slack-file-request-info file-id 1 team #'update)))))
+       ((string= item-type "file")
+        (let* ((file-id (plist-get item :file))
+               (file (slack-file-find file-id team)))
+          (cl-labels
+              ((update (&rest _args)
+                       (slack-with-file file-id team
+                         (slack-message-append-reaction file reaction)
+                         (slack-message-update file team)
+                         (cl-loop for channel in (slack-file-channel-ids file)
+                                  do (slack-if-let*
+                                         ((channel (slack-room-find channel team))
+                                          (message (slack-room-find-file-share-message
+                                                    channel (oref file id))))
+                                         (update-message message))))))
+            (if file (update)
+              (slack-file-request-info file-id 1 team #'update)))))
+       ((string= item-type "message")
+        (slack-if-let* ((room (slack-room-find (plist-get item :channel) team))
+                        (message (slack-room-find-message room (plist-get item :ts))))
+            (progn
+              (update-message message)
+              (slack-reaction-notify payload team room))))))))
+
+(defun slack-ws-handle-reaction-removed (payload team)
+  (let* ((item (plist-get payload :item))
+         (item-type (plist-get item :type))
+         (reaction (make-instance 'slack-reaction
+                                  :name (plist-get payload :reaction)
+                                  :count 1
+                                  :users (list (plist-get payload :user)))))
+    (cl-labels
+        ((update-message (message)
+                         (slack-message-pop-reaction message reaction item-type)
+                         (slack-message-update message team t t)))
+      (cond
+       ((string= item-type "file_comment")
+        (let* ((file-id (plist-get item :file))
+               (file (slack-file-find file-id team))
+               (comment-id (plist-get item :file_comment)))
+
+          (cl-labels
+              ((update (&rest _args)
+                       (slack-with-file file-id team
+                         (slack-with-file-comment comment-id file
+                           (slack-message-pop-reaction file-comment reaction)
+                           (slack-message-update file-comment file team)
+                           (cl-loop for room in (append (oref team channels)
+                                                        (oref team ims)
+                                                        (oref team groups))
+                                    do (slack-if-let*
+                                           ((message
+                                             (if (oref file-comment is-intro)
+                                                 (slack-room-find-file-share-message
+                                                  room file-id)
+                                               (slack-room-find-file-comment-message
+                                                room comment-id))))
+                                           (update-message message)))))))
+            (if file (update)
+              (slack-file-request-info file-id 1 team #'update)))))
+       ((string= item-type "file")
+        (let* ((file-id (plist-get item :file))
+               (file (slack-file-find file-id team)))
+          (cl-labels
+              ((update (&rest _args)
+                       (slack-with-file file-id team
+                         (slack-message-pop-reaction file reaction)
+                         (slack-message-update file team)
+                         (cl-loop for channel in (slack-file-channel-ids file)
+                                  do (slack-if-let*
+                                         ((channel (slack-room-find channel team))
+                                          (message (slack-room-find-file-share-message
+                                                    channel (oref file id))))
+                                         (update-message message))))))
+            (if file (update)
+              (slack-file-request-info file-id 1 team #'update)))))
+       ((string= item-type "message")
+        (slack-if-let* ((room (slack-room-find (plist-get item :channel) team))
+                        (message (slack-room-find-message room (plist-get item :ts))))
+            (progn
+              (update-message message)
+              (slack-reaction-notify payload team room))))))))
+
+(defun slack-ws-handle-channel-created (payload team)
+  (let ((channel (slack-room-create (plist-get payload :channel)
+                                    team 'slack-channel)))
+    (push channel (oref team channels))
+    (slack-room-info-request channel team)
+    (slack-log (format "Created channel %s"
+                       (slack-room-display-name channel))
+               team :level 'info)))
+
+(defun slack-ws-handle-room-archive (payload team)
+  (let* ((id (plist-get payload :channel))
+         (room (slack-room-find id team)))
+    (oset room is-archived t)
+    (slack-log (format "Channel: %s is archived"
+                       (slack-room-display-name room))
+               team :level 'info)))
+
+(defun slack-ws-handle-room-unarchive (payload team)
+  (let* ((id (plist-get payload :channel))
+         (room (slack-room-find id team)))
+    (oset room is-archived nil)
+    (slack-log (format "Channel: %s is unarchived"
+                       (slack-room-display-name room))
+               team :level 'info)))
+
+(defun slack-ws-handle-channel-deleted (payload team)
+  (let ((id (plist-get payload :channel)))
+    (slack-room-deleted id team)))
+
+(defun slack-ws-handle-room-rename (payload team)
+  (let* ((c (plist-get payload :channel))
+         (room (slack-room-find (plist-get c :id) team))
+         (old-name (slack-room-name room))
+         (new-name (plist-get c :name)))
+    (oset room name new-name)
+    (slack-log (format "Renamed channel from %s to %s"
+                       old-name
+                       new-name)
+               team :level 'info)))
+(defun slack-ws-handle-group-joined (payload team)
+  (let ((group (slack-room-create (plist-get payload :channel) team 'slack-group)))
+    (push group (oref team groups))
+    (slack-room-info-request group team)
+    (slack-log (format "Joined group %s"
+                       (slack-room-display-name group))
+               team :level 'info)))
+
+(defun slack-ws-handle-channel-joined (payload team)
+  (let ((channel (slack-room-find (plist-get (plist-get payload :channel) :id) team)))
+    (slack-room-info-request channel team)
+    (slack-log (format "Joined channel %s"
+                       (slack-room-display-name channel))
+               team :level 'info)))
+
+(defun slack-ws-handle-presence-change (payload team)
+  (let* ((id (plist-get payload :user))
+         (user (slack-user--find id team))
+         (presence (plist-get payload :presence)))
+    (plist-put user :presence presence)))
+
+(defun slack-ws-handle-bot (payload team)
+  (let ((bot (plist-get payload :bot)))
+    (with-slots (bots) team
+      (push bot bots))))
+
+(defun slack-ws-handle-file-created (payload team)
+  (slack-if-let* ((file-id (plist-get (plist-get payload :file) :id))
+                  (room (slack-file-room-obj team))
+                  (buffer (slack-buffer-find 'slack-file-list-buffer
+                                             room
+                                             team)))
+      (slack-file-request-info file-id 1 team
+                               #'(lambda (file _team)
+                                   (slack-buffer-update buffer file)))))
+
+(defun slack-ws-handle-file-deleted (payload team)
+  (let ((file-id (plist-get payload :file_id))
+        (room (slack-file-room-obj team)))
+    (with-slots (messages) room
+      (setq messages (cl-remove-if #'(lambda (f)
+                                       (string= file-id (oref f id)))
+                                   messages)))))
+
+(defun slack-ws-cancel-ping-timer (team)
+  (with-slots (ping-timer) team
+    (if (timerp ping-timer)
+        (cancel-timer ping-timer))
+    (setq ping-timer nil)))
+
+(defun slack-ws-set-ping-timer (team)
+  (slack-ws-cancel-ping-timer team)
+  (cl-labels ((ping ()
+                    (slack-ws-ping team)))
+    (oset team ping-timer (run-at-time 10 nil #'ping))))
+
+(defun slack-ws-current-time-str ()
+  (number-to-string (time-to-seconds (current-time))))
+
+(defun slack-ws-ping (team)
+  (slack-message-inc-id team)
+  (with-slots (message-id) team
+    (let* ((time (slack-ws-current-time-str))
+           (m (list :id message-id
+                    :type "ping"
+                    :time time))
+           (json (json-encode m)))
+      (slack-ws-set-check-ping-timer team time)
+      (slack-ws-send json team)
+      (slack-log (format "Send PING: %s" time)
+                 team :level 'trace))))
+
+(defun slack-ws-set-check-ping-timer (team time)
+  (puthash time (run-at-time (oref team check-ping-timeout-sec)
+                             nil #'slack-ws-ping-timeout team)
+           (oref team ping-check-timers)))
+
+
+(defun slack-ws-ping-timeout (team)
+  (slack-log "Slack Websocket PING Timeout." team :level 'warn)
+  (slack-ws-close team)
+  (slack-ws-set-reconnect-timer team))
+
+(defun slack-ws-cancel-ping-check-timers (team)
+  (maphash #'(lambda (key value)
+               (if (timerp value)
+                   (cancel-timer value)))
+           (oref team ping-check-timers))
+  (slack-team-init-ping-check-timers team))
+
+(defvar slack-disconnected-timer nil)
+(defun slack-notify-abandon-reconnect (team)
+  (unless slack-disconnected-timer
+    (setq slack-disconnected-timer
+          (run-with-idle-timer 5 t
+                               #'(lambda ()
+                                   (slack-log
+                                    "Reconnect Count Exceeded. Manually invoke `slack-start'."
+                                    team :level 'error))))))
+
+(defun slack-cancel-notify-adandon-reconnect ()
+  (if (and slack-disconnected-timer
+           (timerp slack-disconnected-timer))
+      (progn
+        (cancel-timer slack-disconnected-timer)
+        (setq slack-disconnected-timer nil))))
+
+(defun slack-request-api-test (team &optional after-success)
+  (cl-labels
+      ((on-success (&key data &allow-other-keys)
+                   (slack-request-handle-error
+                    (data "slack-request-api-test")
+                    (if after-success
+                        (funcall after-success)))))
+    (slack-request
+     (slack-request-create
+      slack-api-test-url
+      team
+      :type "POST"
+      :success #'on-success))))
+
+(defun slack-on-authorize-for-reconnect (data team)
+  (let ((team-data (plist-get data :team))
+        (self-data (plist-get data :self)))
+    (oset team ws-url (plist-get data :url))
+    (oset team domain (plist-get team-data :domain))
+    (oset team id (plist-get team-data :id))
+    (oset team name (plist-get team-data :name))
+    (oset team self self-data)
+    (oset team self-id (plist-get self-data :id))
+    (oset team self-name (plist-get self-data :name))
+    (cl-labels
+        ((on-open ()
+                  (slack-channel-list-update team)
+                  (slack-group-list-update team)
+                  (slack-im-list-update team)
+                  (slack-bot-list-update team)
+                  (cl-loop for buffer in (oref team slack-message-buffer)
+                           do (slack-if-let*
+                                  ((live-p (buffer-live-p buffer))
+                                   (slack-buffer (with-current-buffer buffer
+                                                   (and (bound-and-true-p
+                                                         slack-current-buffer)
+                                                        slack-current-buffer))))
+                                  (slack-buffer-load-missing-messages
+                                   slack-buffer)))
+                  (slack-team-kill-buffers
+                   team :except '(slack-message-buffer
+                                  slack-message-edit-buffer
+                                  slack-message-share-buffer
+                                  slack-room-message-compose-buffer))))
+      (slack-ws-open team :on-open #'on-open))))
+
+(defun slack-authorize-for-reconnect (team)
+  (cl-labels
+      ((on-error (&key error-thrown symbol-status &allow-other-keys)
+                 (slack-log (format "Slack Reconnect Failed: %s, %s"
+                                    error-thrown
+                                    symbol-status)
+                            team)
+                 (slack-ws-set-reconnect-timer team))
+       (on-success (data)
+                   (slack-on-authorize-for-reconnect data team)))
+    (slack-authorize team #'on-error #'on-success)))
+
+(defun slack-ws-reconnect (team &optional force)
+  "Reconnect if `reconnect-count' is not exceed `reconnect-count-max'.
+if FORCE is t, ignore `reconnect-count-max'.
+TEAM is one of `slack-teams'"
+  (cl-labels ((abort (team)
+                     (slack-notify-abandon-reconnect team)
+                     (slack-ws-close team t))
+              (use-reconnect-url ()
+                                 (slack-log "Reconnect with reconnect-url" team)
+                                 (slack-ws-open team
+                                                :ws-url (oref team reconnect-url)))
+              (do-reconnect (team)
+                            (cl-incf (oref team reconnect-count))
+                            (slack-ws-close team)
+                            (if (< 0 (length (oref team reconnect-url)))
+                                (slack-request-api-test team
+                                                        #'use-reconnect-url)
+                              (slack-authorize-for-reconnect team))))
+    (with-slots
+        (reconnect-count (reconnect-max reconnect-count-max)) team
+      (if (and (not force) reconnect-max (< reconnect-max reconnect-count))
+          (abort team)
+        (do-reconnect team)
+        (slack-log (format "Slack Websocket Try To Reconnect %s/%s"
+                           reconnect-count
+                           reconnect-max)
+                   team
+                   :level 'warn
+                   )))))
+
+(defun slack-ws-set-reconnect-timer (team)
+  (slack-ws-cancel-reconnect-timer team)
+  (cl-labels
+      ((on-timeout ()
+                   (slack-ws-reconnect team)))
+    (oset team reconnect-timer
+          (run-at-time (oref team reconnect-after-sec)
+                       nil
+                       #'on-timeout))))
+
+(defun slack-ws-cancel-reconnect-timer (team)
+  (with-slots (reconnect-timer) team
+    (if (timerp reconnect-timer)
+        (cancel-timer reconnect-timer))
+    (setq reconnect-timer nil)))
+
+(defun slack-ws-handle-pong (payload team)
+  (let* ((key (plist-get payload :time))
+         (timer (gethash key (oref team ping-check-timers))))
+    (slack-log (format "Receive PONG: %s" key)
+               team :level 'trace)
+    (slack-ws-set-ping-timer team)
+    (when timer
+      (cancel-timer timer)
+      (remhash key (oref team ping-check-timers))
+      (slack-log (format "Remove PING Check Timer: %s" key)
+                 team :level 'trace))))
+
+(defun slack-ws-handle-room-marked (payload team)
+  (let* ((room (slack-room-find (plist-get payload :channel) team))
+         (ts (plist-get payload :ts))
+         (message (and room (slack-room-find-message room ts))))
+    (when room
+      (with-slots (unread-count-display last-read) room
+        (setq unread-count-display
+              (plist-get payload :unread_count_display))
+        (when (and message
+                   (not (slack-thread-message-p message)))
+          (setq last-read ts)))
+      (slack-update-modeline))))
+
+(defun slack-ws-handle-file-comment-added (payload team)
+  (let* ((file-id (plist-get payload :file_id))
+         (file (slack-file-find file-id team))
+         (comment (slack-file-comment-create (plist-get payload :comment)
+                                             file-id)))
+    (slack-with-file file-id team
+      (slack-add-comment file comment)
+      (slack-file-insert-comment file (oref comment id) team))))
+
+(defun slack-ws-handle-file-comment-deleted (payload team)
+  (let* ((file-id (plist-get (plist-get payload :file)
+                             :id))
+         (comment-id (plist-get payload :comment)))
+    (slack-with-file file-id team
+      (slack-delete-comment file comment-id)
+      (slack-file-delete-comment file comment-id team))))
+
+(defun slack-ws-handle-thread-marked (payload team)
+  (let* ((subscription (plist-get payload :subscription))
+         (thread-ts (plist-get subscription :thread_ts))
+         (channel (plist-get subscription :channel))
+         (room (slack-room-find channel team))
+         (parent (and room (slack-room-find-message room thread-ts))))
+    (when (and parent (oref parent thread))
+      (slack-thread-marked (oref parent thread) subscription))))
+
+(defun slack-ws-handle-thread-subscribed (payload team)
+  (let* ((thread-data (plist-get payload :subscription))
+         (room (slack-room-find (plist-get thread-data :channel) team))
+         (message (and (slack-room-find-message room (plist-get thread-data :thread_ts))))
+         (thread (and message (oref message thread))))
+    (when thread
+      (slack-thread-marked thread thread-data))))
+
+(defun slack-ws-handle-user-change (payload team)
+  (let* ((user (plist-get payload :user))
+         (id (plist-get user :id)))
+    (with-slots (users) team
+      (setq users
+            (cons user
+                  (cl-remove-if #'(lambda (u)
+                                    (string= id (plist-get u :id)))
+                                users))))))
+
+(defun slack-ws-handle-member-joined-channel (payload team)
+  (let ((user (plist-get payload :user))
+        (channel (slack-room-find (plist-get payload :channel) team)))
+    (when channel
+      (cl-pushnew user (oref channel members)
+                  :test #'string=))))
+
+(defun slack-ws-handle-member-left_channel (payload team)
+  (let ((user (plist-get payload :user))
+        (channel (slack-room-find (plist-get payload :channel) team)))
+    (when channel
+      (oset channel members
+            (cl-remove-if #'(lambda (e) (string= e user))
+                          (oref channel members))))))
+
+(defun slack-ws-handle-dnd-updated (payload team)
+  (let* ((user (slack-user--find (plist-get payload :user) team))
+         (updated (slack-user-update-dnd-status user (plist-get payload :dnd_status))))
+    (oset team users
+          (cons updated (cl-remove-if #'(lambda (user) (string= (plist-get user :id)
+                                                                (plist-get updated :id)))
+                                      (oref team users))))))
+
+;; [star_added event | Slack](https://api.slack.com/events/star_added)
+(defun slack-ws-handle-star-added (payload team)
+  (let* ((item (plist-get payload :item))
+         (item-type (plist-get item :type)))
+    (cl-labels
+        ((update-message (message)
+                         (slack-message-star-added message)
+                         (slack-message-update message team t t)))
+      (cond
+       ((string= item-type "file_comment")
+        (let* ((file-id (plist-get (plist-get item :file) :id))
+               (comment-id (plist-get (plist-get item :comment) :id))
+               (file (slack-file-find file-id team)))
+          (cl-labels
+              ((update (&rest _args)
+                       (slack-with-file file-id team
+                         (slack-with-file-comment comment-id file
+                           (slack-message-star-added file-comment)
+                           (slack-message-update file-comment file team))
+
+                         (cl-loop for channel in (slack-file-channel-ids file)
+                                  do (slack-if-let* ((channel (slack-room-find channel team))
+                                                     (message (slack-room-find-file-comment-message
+                                                               channel comment-id)))
+                                         (update-message message))))))
+            (if file (update)
+              (slack-file-request-info file-id 1 team #'update)))))
+       ((string= item-type "file")
+        (let* ((file-id (plist-get (plist-get item :file) :id))
+               (file (slack-file-find file-id team)))
+          (cl-labels
+              ((update (&rest _args)
+                       (slack-with-file file-id team
+                         (slack-message-star-added file)
+                         (slack-message-update file team)
+
+                         (cl-loop for channel in (slack-file-channel-ids file)
+                                  do (slack-if-let* ((channel (slack-room-find channel team))
+                                                     (message (slack-room-find-file-share-message
+                                                               channel (oref file id))))
+                                         (update-message message))))))
+            (if file (update)
+              (slack-file-request-info file-id 1 team #'update)))))
+       ((string= item-type "message")
+        (slack-if-let* ((room (slack-room-find (plist-get item :channel) team))
+                        (ts (plist-get (plist-get item :message) :ts))
+                        (message (slack-room-find-message room ts)))
+            (update-message message)))))
+    (slack-if-let* ((star (oref team star)))
+        (slack-star-add star item team))))
+
+
+(defun slack-ws-handle-star-removed (payload team)
+  (let* ((item (plist-get payload :item))
+         (item-type (plist-get item :type)))
+    (cl-labels
+        ((update-message (message)
+                         (slack-message-star-removed message)
+                         (slack-message-update message team t t)))
+      (cond
+       ((string= item-type "file_comment")
+        (let* ((file-id (plist-get (plist-get item :file) :id))
+               (comment-id (plist-get (plist-get item :comment) :id))
+               (file (slack-file-find file-id team)))
+          (cl-labels
+              ((update (&rest _args)
+                       (slack-with-file file-id team
+                         (slack-with-file-comment comment-id file
+                           (slack-message-star-removed file-comment)
+                           (slack-message-update file-comment file team))
+
+                         (cl-loop for channel in (slack-file-channel-ids file)
+                                  do (slack-if-let* ((channel (slack-room-find channel team))
+                                                     (message (slack-room-find-file-comment-message
+                                                               channel comment-id)))
+                                         (update-message message))))))
+            (if file (update)
+              (slack-file-request-info file-id 1 team #'update)))))
+       ((string= item-type "file")
+        (let* ((file-id (plist-get (plist-get item :file) :id))
+               (file (slack-file-find file-id team)))
+          (cl-labels
+              ((update (&rest _args)
+                       (slack-with-file file-id team
+                         (slack-message-star-removed file)
+                         (slack-message-update file team)
+
+                         (cl-loop for channel in (slack-file-channel-ids file)
+                                  do (slack-if-let* ((channel (slack-room-find channel team))
+                                                     (message (slack-room-find-file-share-message
+                                                               channel (oref file id))))
+                                         (update-message message))))))
+            (if file (update)
+              (slack-file-request-info file-id 1 team #'update)))))
+       ((string= item-type "message")
+        (slack-if-let* ((room (slack-room-find (plist-get item :channel) team))
+                        (ts (plist-get (plist-get item :message) :ts))
+                        (message (slack-room-find-message room ts)))
+            (update-message message)))))
+
+    (slack-if-let* ((star (oref team star)))
+        (slack-star-remove star item team))))
+
+(defun slack-ws-handle-file-comment-edited (payload team)
+  (let* ((file-id (plist-get (plist-get payload :file) :id))
+         (comment (slack-file-comment-create (plist-get payload :comment) file-id))
+         (file (slack-file-find file-id team))
+         (edited-at (plist-get payload :event_ts)))
+    (cl-labels
+        ((update (file)
+                 (slack-file-update-comment file comment team edited-at)
+                 (slack-with-file-comment (oref comment id) file
+                   (slack-message-update file-comment file team))))
+      (if file (update file)
+        (slack-file-request-info file-id 1 team #'update)))))
+
+(provide 'slack-websocket)
+;;; slack-websocket.el ends here
+
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-websocket.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-websocket.elc
new file mode 100644
index 0000000000..96bb135f14
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack-websocket.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack.el b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack.el
new file mode 100644
index 0000000000..e6184f83a1
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack.el
@@ -0,0 +1,227 @@
+;;; slack.el --- slack client for emacs              -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2015  yuya.minami
+
+;; Author: yuya.minami <yuya.minami@yuyaminami-no-MacBook-Pro.local>
+;; Keywords: tools
+;; Version: 0.0.2
+;; Package-Requires: ((websocket "1.8") (request "0.2.0") (oauth2 "0.10") (circe "2.3") (alert "1.2") (emojify "0.4") (emacs "24.4"))
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+(require 'cl-lib)
+(require 'subr-x)
+(require 'oauth2)
+(require 'color)
+
+(require 'slack-util)
+(require 'slack-team)
+(require 'slack-channel)
+(require 'slack-im)
+(require 'slack-file)
+(require 'slack-message-notification)
+(require 'slack-message-sender)
+(require 'slack-message-editor)
+(require 'slack-message-reaction)
+(require 'slack-user-message)
+(require 'slack-bot-message)
+(require 'slack-search)
+(require 'slack-reminder)
+(require 'slack-thread)
+(require 'slack-file-share-message)
+(require 'slack-file-comment)
+(require 'slack-attachment)
+(require 'slack-emoji)
+(require 'slack-star)
+
+(require 'slack-buffer)
+(require 'slack-message-buffer)
+(require 'slack-message-edit-buffer)
+(require 'slack-message-share-buffer)
+(require 'slack-thread-message-buffer)
+(require 'slack-room-message-compose-buffer)
+(require 'slack-pinned-items-buffer)
+(require 'slack-user-profile-buffer)
+(require 'slack-file-list-buffer)
+(require 'slack-file-info-buffer)
+(require 'slack-thread-message-compose-buffer)
+(require 'slack-edit-file-comment-buffer)
+(require 'slack-search-result-buffer)
+(require 'slack-stars-buffer)
+(require 'slack-file-comment-compose-buffer)
+
+(require 'slack-websocket)
+(require 'slack-request)
+(require 'slack-request-worker)
+
+(defgroup slack nil
+  "Emacs Slack Client"
+  :prefix "slack-"
+  :group 'tools)
+
+(defcustom slack-redirect-url "http://localhost:8080"
+  "Redirect url registered for Slack.")
+(defcustom slack-buffer-function #'switch-to-buffer-other-window
+  "Function to print buffer.")
+
+(defvar slack-use-register-team-string
+  "use `slack-register-team' instead.")
+
+(defcustom slack-client-id nil
+  "Client ID provided by Slack.")
+(make-obsolete-variable
+ 'slack-client-id slack-use-register-team-string
+ "0.0.2")
+(defcustom slack-client-secret nil
+  "Client Secret Provided by Slack.")
+(make-obsolete-variable
+ 'slack-client-secret slack-use-register-team-string
+ "0.0.2")
+(defcustom slack-token nil
+  "Slack token provided by Slack.
+set this to save request to Slack if already have.")
+(make-obsolete-variable
+ 'slack-token slack-use-register-team-string
+ "0.0.2")
+(defcustom slack-room-subscription '()
+  "Group or Channel list to subscribe notification."
+  :group 'slack)
+(make-obsolete-variable
+ 'slack-room-subscription slack-use-register-team-string
+ "0.0.2")
+(defcustom slack-typing-visibility 'frame
+  "When to show typing indicator.
+frame means typing slack buffer is in the current frame, show typing indicator.
+buffer means typing slack buffer is the current buffer, show typing indicator.
+never means never show typing indicator."
+  :type '(choice (const frame)
+                 (const buffer)
+                 (const never)))
+
+(defcustom slack-display-team-name t
+  "If nil, only display channel, im, group name."
+  :group 'slack)
+
+(defcustom slack-completing-read-function #'completing-read
+  "Require same argument with `completing-read'."
+  :group 'slack)
+
+(defconst slack-oauth2-authorize "https://slack.com/oauth/authorize")
+(defconst slack-oauth2-access "https://slack.com/api/oauth.access")
+(defconst slack-authorize-url "https://slack.com/api/rtm.start")
+(defconst slack-rtm-connect-url "https://slack.com/api/rtm.connect")
+
+(defun slack-authorize (team &optional error-callback success-callback)
+  (let ((authorize-request (oref team authorize-request)))
+    (if (and authorize-request (not (request-response-done-p authorize-request)))
+        (slack-log "Authorize Already Requested" team)
+      (cl-labels
+          ((on-error (&key error-thrown symbol-status response data)
+                     (oset team authorize-request nil)
+                     (slack-log (format "Slack Authorize Failed: %s" error-thrown)
+                                team)
+                     (when (functionp error-callback)
+                       (funcall error-callback
+                                :error-thrown error-thrown
+                                :symbol-status symbol-status
+                                :response response
+                                :data data)))
+           (on-success (&key data &allow-other-keys)
+                       (oset team authorize-request nil)
+                       (if success-callback
+                           (funcall success-callback data)
+                         (slack-on-authorize data team))))
+        (let ((request (slack-request
+                        (slack-request-create
+                         slack-rtm-connect-url
+                         team
+                         :params (list (cons "mpim_aware" "1"))
+                         :success #'on-success
+                         :error #'on-error))))
+          (oset team authorize-request request))))))
+
+(defun slack-update-team (data team)
+  (let ((self (plist-get data :self))
+        (team-data (plist-get data :team)))
+    (oset team id (plist-get team-data :id))
+    (oset team name (plist-get team-data :name))
+    (oset team self self)
+    (oset team self-id (plist-get self :id))
+    (oset team self-name (plist-get self :name))
+    (oset team ws-url (plist-get data :url))
+    (oset team domain (plist-get team-data :domain))
+    team))
+
+(cl-defun slack-on-authorize (data team)
+  (slack-request-handle-error
+   (data "slack-authorize")
+   (slack-log (format "Slack Authorization Finished" (oref team name)) team)
+   (let ((team (slack-update-team data team)))
+     (cl-labels
+         ((on-open ()
+                   (slack-channel-list-update team)
+                   (slack-group-list-update team)
+                   (slack-im-list-update team)
+                   (slack-bot-list-update team)
+                   (slack-request-emoji team)
+                   (slack-update-modeline)))
+       (slack-ws-open team :on-open #'on-open)))))
+
+(defun slack-on-authorize-e
+    (&key error-thrown &allow-other-keys &rest_)
+  (error "slack-authorize: %s" error-thrown))
+
+(defun slack-oauth2-auth (team)
+  (with-slots (client-id client-secret) team
+    (oauth2-auth
+     slack-oauth2-authorize
+     slack-oauth2-access
+     client-id
+     client-secret
+     "client"
+     nil
+     slack-redirect-url)))
+
+(defun slack-request-token (team)
+  (with-slots (token) team
+    (setq token
+          (oauth2-token-access-token
+           (slack-oauth2-auth team)))))
+
+;;;###autoload
+(defun slack-start (&optional team)
+  (interactive)
+  (cl-labels ((start
+               (team)
+               (slack-team-kill-buffers team)
+               (slack-ws-close team)
+               (when (slack-team-need-token-p team)
+                 (slack-request-token team)
+                 (kill-new (oref team token))
+                 (message "Your Token is added to kill ring."))
+               (slack-authorize team)))
+    (if team
+        (start team)
+      (if slack-teams
+          (cl-loop for team in slack-teams
+                   do (start team))
+        (slack-start (call-interactively #'slack-register-team))))
+    (slack-enable-modeline)))
+
+(provide 'slack)
+;;; slack.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack.elc b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack.elc
new file mode 100644
index 0000000000..da35aeb8a8
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/slack-20180712.2222/slack.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/smex-20151212.1409/smex-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/smex-20151212.1409/smex-autoloads.el
new file mode 100644
index 0000000000..9a11388f31
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/smex-20151212.1409/smex-autoloads.el
@@ -0,0 +1,31 @@
+;;; smex-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "smex" "smex.el" (23377 60989 394126 794000))
+;;; Generated autoloads from smex.el
+
+(autoload 'smex "smex" "\
+
+
+\(fn)" t nil)
+
+(autoload 'smex-major-mode-commands "smex" "\
+Like `smex', but limited to commands that are relevant to the active major mode.
+
+\(fn)" t nil)
+
+(autoload 'smex-initialize "smex" "\
+
+
+\(fn)" t nil)
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; smex-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/smex-20151212.1409/smex-pkg.el b/configs/shared/emacs/.emacs.d/elpa/smex-20151212.1409/smex-pkg.el
new file mode 100644
index 0000000000..1cf7424908
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/smex-20151212.1409/smex-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "smex" "20151212.1409" "M-x interface with Ido-style fuzzy matching." '((emacs "24")))
diff --git a/configs/shared/emacs/.emacs.d/elpa/smex-20151212.1409/smex.el b/configs/shared/emacs/.emacs.d/elpa/smex-20151212.1409/smex.el
new file mode 100644
index 0000000000..b9c2b41e86
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/smex-20151212.1409/smex.el
@@ -0,0 +1,484 @@
+;;; smex.el --- M-x interface with Ido-style fuzzy matching. -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2009-2014 Cornelius Mika and contributors
+;;
+;; Author: Cornelius Mika <cornelius.mika@gmail.com> and contributors
+;; URL: http://github.com/nonsequitur/smex/
+;; Package-Version: 20151212.1409
+;; Package-Requires: ((emacs "24"))
+;; Version: 3.0
+;; Keywords: convenience, usability
+
+;; This file is not part of GNU Emacs.
+
+;;; License:
+
+;; Licensed under the same terms as Emacs.
+
+;;; Commentary:
+
+;; Quick start:
+;; run (smex-initialize)
+;;
+;; Bind the following commands:
+;; smex, smex-major-mode-commands
+;;
+;; For a detailed introduction see:
+;; http://github.com/nonsequitur/smex/blob/master/README.markdown
+
+;;; Code:
+
+(require 'ido)
+
+(defgroup smex nil
+  "M-x interface with Ido-style fuzzy matching and ranking heuristics."
+  :group 'extensions
+  :group 'convenience
+  :link '(emacs-library-link :tag "Lisp File" "smex.el"))
+
+(defcustom smex-auto-update t
+  "If non-nil, `Smex' checks for new commands each time it is run.
+Turn it off for minor speed improvements on older systems."
+  :type 'boolean
+  :group 'smex)
+
+(defcustom smex-save-file (locate-user-emacs-file "smex-items" ".smex-items")
+  "File in which the smex state is saved between Emacs sessions.
+Variables stored are: `smex-data', `smex-history'.
+Must be set before initializing Smex."
+  :type 'string
+  :group 'smex)
+
+(defcustom smex-history-length 7
+  "Determines on how many recently executed commands
+Smex should keep a record.
+Must be set before initializing Smex."
+  :type 'integer
+  :group 'smex)
+
+(defcustom smex-prompt-string "M-x "
+  "String to display in the Smex prompt."
+  :type 'string
+  :group 'smex)
+
+(defcustom smex-flex-matching t
+  "Enables Ido flex matching. On by default.
+Set this to nil to disable fuzzy matching."
+  :type 'boolean
+  :group 'smex)
+
+(defvar smex-initialized-p nil)
+(defvar smex-cache)
+(defvar smex-ido-cache)
+(defvar smex-data)
+(defvar smex-history)
+(defvar smex-command-count 0)
+(defvar smex-custom-action nil)
+
+;; Check if Smex is supported
+(when (equal (cons 1 1)
+             (ignore-errors
+               (subr-arity (symbol-function 'execute-extended-command))))
+  (error "Your Emacs has a non-elisp version of `execute-extended-command', which is incompatible with Smex"))
+
+;;--------------------------------------------------------------------------------
+;; Smex Interface
+
+;;;###autoload
+(defun smex ()
+  (interactive)
+  (unless smex-initialized-p
+    (smex-initialize))
+  (if (smex-already-running)
+      (smex-update-and-rerun)
+    (and smex-auto-update
+         (smex-detect-new-commands)
+         (smex-update))
+    (smex-read-and-run smex-ido-cache)))
+
+(defun smex-already-running ()
+  (and (boundp 'ido-choice-list)
+       (eql ido-choice-list smex-ido-cache)
+       (minibuffer-window-active-p (selected-window))))
+
+(defun smex-update-and-rerun ()
+  (smex-do-with-selected-item
+   (lambda (_) (smex-update) (smex-read-and-run smex-ido-cache ido-text))))
+
+(defun smex-read-and-run (commands &optional initial-input)
+  (let* ((chosen-item-name (smex-completing-read commands initial-input))
+         (chosen-item (intern chosen-item-name)))
+    (if smex-custom-action
+        (let ((action smex-custom-action))
+          (setq smex-custom-action nil)
+          (funcall action chosen-item))
+      (unwind-protect
+          (with-no-warnings ; Don't warn about interactive use of `execute-extended-command'
+            (execute-extended-command current-prefix-arg chosen-item-name))
+        (smex-rank chosen-item)))))
+
+;;;###autoload
+(defun smex-major-mode-commands ()
+  "Like `smex', but limited to commands that are relevant to the active major mode."
+  (interactive)
+  (unless smex-initialized-p
+    (smex-initialize))
+  (let ((commands (delete-dups (append (smex-extract-commands-from-keymap (current-local-map))
+                                       (smex-extract-commands-from-features major-mode)))))
+    (setq commands (smex-sort-according-to-cache commands))
+    (setq commands (mapcar #'symbol-name commands))
+    (smex-read-and-run commands)))
+
+(defun smex-completing-read (choices initial-input)
+  (let ((ido-completion-map ido-completion-map)
+        (ido-setup-hook (cons 'smex-prepare-ido-bindings ido-setup-hook))
+        (ido-enable-prefix nil)
+        (ido-enable-flex-matching smex-flex-matching)
+        (ido-max-prospects 10)
+        (minibuffer-completion-table choices))
+    (ido-completing-read (smex-prompt-with-prefix-arg) choices nil nil
+                         initial-input 'extended-command-history (car choices))))
+
+(defun smex-prompt-with-prefix-arg ()
+  (if (not current-prefix-arg)
+      smex-prompt-string
+    (concat
+     (if (eq current-prefix-arg '-)
+         "- "
+       (if (integerp current-prefix-arg)
+           (format "%d " current-prefix-arg)
+         (if (= (car current-prefix-arg) 4)
+             "C-u "
+           (format "%d " (car current-prefix-arg)))))
+     smex-prompt-string)))
+
+(defun smex-prepare-ido-bindings ()
+  (define-key ido-completion-map (kbd "TAB") 'minibuffer-complete)
+  (define-key ido-completion-map (kbd "C-h f") 'smex-describe-function)
+  (define-key ido-completion-map (kbd "C-h w") 'smex-where-is)
+  (define-key ido-completion-map (kbd "M-.") 'smex-find-function)
+  (define-key ido-completion-map (kbd "C-a") 'move-beginning-of-line))
+
+;;--------------------------------------------------------------------------------
+;; Cache and Maintenance
+
+(defun smex-rebuild-cache ()
+  (interactive)
+  (setq smex-cache nil)
+
+  ;; Build up list 'new-commands' and later put it at the end of 'smex-cache'.
+  ;; This speeds up sorting.
+  (let (new-commands)
+    (mapatoms (lambda (symbol)
+                (when (commandp symbol)
+                  (let ((known-command (assq symbol smex-data)))
+                    (if known-command
+                        (setq smex-cache (cons known-command smex-cache))
+                      (setq new-commands (cons (list symbol) new-commands)))))))
+    (if (eq (length smex-cache) 0)
+        (setq smex-cache new-commands)
+      (setcdr (last smex-cache) new-commands)))
+
+  (setq smex-cache (sort smex-cache 'smex-sorting-rules))
+  (smex-restore-history)
+  (setq smex-ido-cache (smex-convert-for-ido smex-cache)))
+
+(defun smex-convert-for-ido (command-items)
+  (mapcar (lambda (command-item) (symbol-name (car command-item))) command-items))
+
+(defun smex-restore-history ()
+  "Rearranges `smex-cache' according to `smex-history'"
+  (if (> (length smex-history) smex-history-length)
+      (setcdr (nthcdr (- smex-history-length 1) smex-history) nil))
+  (mapc (lambda (command)
+          (unless (eq command (caar smex-cache))
+            (let ((command-cell-position (smex-detect-position
+                                          smex-cache
+                                          (lambda (cell)
+                                            (eq command (caar cell))))))
+              (when command-cell-position
+                (let ((command-cell (smex-remove-nth-cell
+                                     command-cell-position smex-cache)))
+                  (setcdr command-cell smex-cache)
+                  (setq smex-cache command-cell))))))
+        (reverse smex-history)))
+
+(defun smex-sort-according-to-cache (list)
+  "Sorts a list of commands by their order in `smex-cache'"
+  (let (sorted)
+    (dolist (command-item smex-cache)
+      (let ((command (car command-item)))
+        (when (memq command list)
+          (setq sorted (cons command sorted))
+          (setq list (delq command list)))))
+    (nreverse (append list sorted))))
+
+(defun smex-update ()
+  (interactive)
+  (smex-save-history)
+  (smex-rebuild-cache))
+
+(defun smex-detect-new-commands ()
+  (let ((i 0))
+    (mapatoms (lambda (symbol) (if (commandp symbol) (setq i (1+ i)))))
+    (unless (= i smex-command-count)
+      (setq smex-command-count i))))
+
+(defun smex-auto-update (&optional idle-time)
+  "Update Smex when Emacs has been idle for IDLE-TIME."
+  (unless idle-time (setq idle-time 60))
+  (run-with-idle-timer idle-time t
+                       '(lambda () (if (smex-detect-new-commands) (smex-update)))))
+
+;;;###autoload
+(defun smex-initialize ()
+  (interactive)
+  (unless ido-mode (smex-initialize-ido))
+  (smex-load-save-file)
+  (smex-detect-new-commands)
+  (smex-rebuild-cache)
+  (add-hook 'kill-emacs-hook 'smex-save-to-file)
+  (setq smex-initialized-p t))
+
+(defun smex-initialize-ido ()
+  "Sets up a minimal Ido environment for `ido-completing-read'."
+  (with-no-warnings ; `ido-init-completion-maps' is deprecated in Emacs 25
+    (ido-init-completion-maps))
+  (add-hook 'minibuffer-setup-hook 'ido-minibuffer-setup))
+
+(defsubst smex-save-file-not-empty-p ()
+  (string-match-p "\[^[:space:]\]" (buffer-string)))
+
+(defun smex-load-save-file ()
+  "Loads `smex-history' and `smex-data' from `smex-save-file'"
+  (let ((save-file (expand-file-name smex-save-file)))
+    (if (file-readable-p save-file)
+        (with-temp-buffer
+          (insert-file-contents save-file)
+          (condition-case nil
+              (setq smex-history (read (current-buffer))
+                    smex-data    (read (current-buffer)))
+            (error (if (smex-save-file-not-empty-p)
+                       (error "Invalid data in smex-save-file (%s). Can't restore history."
+                              smex-save-file)
+                     (unless (boundp 'smex-history) (setq smex-history nil))
+                     (unless (boundp 'smex-data)    (setq smex-data nil))))))
+      (setq smex-history nil smex-data nil))))
+
+(defun smex-save-history ()
+  "Updates `smex-history'"
+  (setq smex-history nil)
+  (let ((cell smex-cache))
+    (dotimes (_ smex-history-length)
+      (setq smex-history (cons (caar cell) smex-history))
+      (setq cell (cdr cell))))
+  (setq smex-history (nreverse smex-history)))
+
+(defmacro smex-pp (list-var)
+  `(smex-pp* ,list-var ,(symbol-name list-var)))
+
+(defun smex-save-to-file ()
+  (interactive)
+  (smex-save-history)
+  (with-temp-file (expand-file-name smex-save-file)
+    (smex-pp smex-history)
+    (smex-pp smex-data)))
+
+;;--------------------------------------------------------------------------------
+;; Ranking
+
+(defun smex-sorting-rules (command-item other-command-item)
+  "Returns true if COMMAND-ITEM should sort before OTHER-COMMAND-ITEM."
+  (let* ((count        (or (cdr command-item      ) 0))
+         (other-count  (or (cdr other-command-item) 0))
+         (name         (car command-item))
+         (other-name   (car other-command-item))
+         (length       (length (symbol-name name)))
+         (other-length (length (symbol-name other-name))))
+    (or (> count other-count)                         ; 1. Frequency of use
+        (and (= count other-count)
+             (or (< length other-length)              ; 2. Command length
+                 (and (= length other-length)
+                      (string< name other-name))))))) ; 3. Alphabetical order
+
+(defun smex-rank (command)
+  (let ((command-item (or (assq command smex-cache)
+                          ;; Update caches and try again if not found.
+                          (progn (smex-update)
+                                 (assq command smex-cache)))))
+    (when command-item
+      (smex-update-counter command-item)
+
+      ;; Don't touch the cache order if the chosen command
+      ;; has just been execucted previously.
+      (unless (eq command-item (car smex-cache))
+        (let (command-cell
+              (pos (smex-detect-position smex-cache (lambda (cell)
+                                                      (eq command-item (car cell))))))
+          ;; Remove the just executed command.
+          (setq command-cell (smex-remove-nth-cell pos smex-cache))
+          ;; And put it on top of the cache.
+          (setcdr command-cell smex-cache)
+          (setq smex-cache command-cell)
+
+          ;; Repeat the same for the ido cache. Should this be DRYed?
+          (setq command-cell (smex-remove-nth-cell pos smex-ido-cache))
+          (setcdr command-cell smex-ido-cache)
+          (setq smex-ido-cache command-cell)
+
+          ;; Now put the last history item back to its normal place.
+          (smex-sort-item-at smex-history-length))))))
+
+(defun smex-update-counter (command-item)
+  (let ((count (cdr command-item)))
+    (setcdr command-item
+            (if count
+                (1+ count)
+              ;; Else: Command has just been executed for the first time.
+              ;; Add it to `smex-data'.
+              (if smex-data
+                  (setcdr (last smex-data) (list command-item))
+                (setq smex-data (list command-item)))
+              1))))
+
+(defun smex-sort-item-at (n)
+  "Sorts item at position N in `smex-cache'."
+  (let* ((command-cell (nthcdr n smex-cache))
+         (command-item (car command-cell)))
+    (let ((insert-at (smex-detect-position
+                      command-cell
+                      (lambda (cell)
+                        (smex-sorting-rules command-item (car cell))))))
+      ;; TODO: Should we handle the case of 'insert-at' being nil?
+      ;; This will never happen in practice.
+      (when (> insert-at 1)
+        (setq command-cell (smex-remove-nth-cell n smex-cache))
+        ;; smex-cache just got shorter by one element, so subtract '1' from insert-at.
+        (setq insert-at (+ n (- insert-at 1)))
+        (smex-insert-cell command-cell insert-at smex-cache)
+
+        ;; Repeat the same for the ido cache. DRY?
+        (setq command-cell (smex-remove-nth-cell n smex-ido-cache))
+        (smex-insert-cell command-cell insert-at smex-ido-cache)))))
+
+(defun smex-detect-position (cell function)
+  "Detects, relatively to CELL, the position of the cell
+on which FUNCTION returns true.
+Only checks cells after CELL, starting with the cell right after CELL.
+Returns nil when reaching the end of the list."
+  (let ((pos 1))
+    (catch 'break
+      (while t
+        (setq cell (cdr cell))
+        (if (not cell)
+            (throw 'break nil)
+          (if (funcall function cell) (throw 'break pos))
+          (setq pos (1+ pos)))))))
+
+(defun smex-remove-nth-cell (n list)
+  "Removes and returns the Nth cell in LIST."
+  (let* ((previous-cell (nthcdr (- n 1) list))
+         (result (cdr previous-cell)))
+    (setcdr previous-cell (cdr result))
+    result))
+
+(defun smex-insert-cell (new-cell n list)
+  "Inserts cell at position N in LIST."
+  (let* ((cell (nthcdr (- n 1) list))
+         (next-cell (cdr cell)))
+    (setcdr (setcdr cell new-cell) next-cell)))
+
+;;--------------------------------------------------------------------------------
+;; Help and Reference
+
+(defun smex-do-with-selected-item (fn)
+  (setq smex-custom-action fn)
+  (ido-exit-minibuffer))
+
+(defun smex-describe-function ()
+  (interactive)
+  (smex-do-with-selected-item (lambda (chosen)
+                                (describe-function chosen)
+                                (pop-to-buffer "*Help*"))))
+
+(defun smex-where-is ()
+  (interactive)
+  (smex-do-with-selected-item 'where-is))
+
+(defun smex-find-function ()
+  (interactive)
+  (smex-do-with-selected-item 'find-function))
+
+(defun smex-extract-commands-from-keymap (map)
+  (let (commands)
+    (smex-parse-keymap map commands)
+    commands))
+
+(defun smex-parse-keymap (map commands)
+  (map-keymap (lambda (_binding element)
+                (if (and (listp element) (eq 'keymap (car element)))
+                    (smex-parse-keymap element commands)
+                  ;; Strings are commands, too. Reject them.
+                  (if (and (symbolp element) (commandp element))
+                      (push element commands))))
+              map))
+
+(defun smex-extract-commands-from-features (mode)
+  (let ((library-path (symbol-file mode))
+        (mode-name (symbol-name mode))
+        commands)
+
+    (string-match "\\(.+?\\)\\(-mode\\)?$" mode-name)
+    ;; 'lisp-mode' -> 'lisp'
+    (setq mode-name (match-string 1 mode-name))
+    (if (string= mode-name "c") (setq mode-name "cc"))
+    (setq mode-name (regexp-quote mode-name))
+
+    (dolist (feature load-history)
+      (let ((feature-path (car feature)))
+        (when (and feature-path (or (equal feature-path library-path)
+                                    (string-match mode-name (file-name-nondirectory
+                                                             feature-path))))
+          (dolist (item (cdr feature))
+            (if (and (listp item) (eq 'defun (car item)))
+                (let ((function (cdr item)))
+                  (when (commandp function)
+                    (setq commands (append commands (list function))))))))))
+    commands))
+
+(defun smex-show-unbound-commands ()
+  "Shows unbound commands in a new buffer,
+sorted by frequency of use."
+  (interactive)
+  (setq smex-data (sort smex-data 'smex-sorting-rules))
+  (let ((unbound-commands (delq nil
+                                (mapcar (lambda (command-item)
+                                          (unless (where-is-internal (car command-item))
+                                            command-item))
+                                        smex-data))))
+    (view-buffer-other-window "*Smex: Unbound Commands*")
+    (setq buffer-read-only t)
+    (let ((inhibit-read-only t))
+      (erase-buffer)
+      (smex-pp unbound-commands))
+    (set-buffer-modified-p nil)
+    (goto-char (point-min))))
+
+;; A copy of `ido-pp' that's compatible with lexical bindings
+(defun smex-pp* (list list-name)
+  (let ((print-level nil) (eval-expression-print-level nil)
+        (print-length nil) (eval-expression-print-length nil))
+    (insert "\n;; ----- " list-name " -----\n(\n ")
+    (while list
+      (let* ((elt (car list))
+             (s (if (consp elt) (car elt) elt)))
+        (if (and (stringp s) (= (length s) 0))
+            (setq s nil))
+        (if s
+            (prin1 elt (current-buffer)))
+        (if (and (setq list (cdr list)) s)
+            (insert "\n "))))
+    (insert "\n)\n")))
+
+(provide 'smex)
+;;; smex.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/smex-20151212.1409/smex.elc b/configs/shared/emacs/.emacs.d/elpa/smex-20151212.1409/smex.elc
new file mode 100644
index 0000000000..42d50ebca0
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/smex-20151212.1409/smex.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/spinner-1.7.3.signed b/configs/shared/emacs/.emacs.d/elpa/spinner-1.7.3.signed
new file mode 100644
index 0000000000..0b6a055ab1
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/spinner-1.7.3.signed
@@ -0,0 +1 @@
+Good signature from 474F05837FBDEF9B GNU ELPA Signing Agent <elpasign@elpa.gnu.org> (trust undefined) created at 2016-11-17T17:05:02-0500 using DSA
\ No newline at end of file
diff --git a/configs/shared/emacs/.emacs.d/elpa/spinner-1.7.3/spinner-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/spinner-1.7.3/spinner-autoloads.el
new file mode 100644
index 0000000000..35a55d2dbe
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/spinner-1.7.3/spinner-autoloads.el
@@ -0,0 +1,68 @@
+;;; spinner-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "spinner" "spinner.el" (23377 61663 472434
+;;;;;;  608000))
+;;; Generated autoloads from spinner.el
+
+(autoload 'spinner-create "spinner" "\
+Create a spinner of the given TYPE.
+The possible TYPEs are described in `spinner--type-to-frames'.
+
+FPS, if given, is the number of desired frames per second.
+Default is `spinner-frames-per-second'.
+
+If BUFFER-LOCAL is non-nil, the spinner will be automatically
+deactivated if the buffer is killed.  If BUFFER-LOCAL is a
+buffer, use that instead of current buffer.
+
+When started, in order to function properly, the spinner runs a
+timer which periodically calls `force-mode-line-update' in the
+curent buffer.  If BUFFER-LOCAL was set at creation time, then
+`force-mode-line-update' is called in that buffer instead.  When
+the spinner is stopped, the timer is deactivated.
+
+DELAY, if given, is the number of seconds to wait after starting
+the spinner before actually displaying it. It is safe to cancel
+the spinner before this time, in which case it won't display at
+all.
+
+\(fn &optional TYPE BUFFER-LOCAL FPS DELAY)" nil nil)
+
+(autoload 'spinner-start "spinner" "\
+Start a mode-line spinner of given TYPE-OR-OBJECT.
+If TYPE-OR-OBJECT is an object created with `make-spinner',
+simply activate it.  This method is designed for minor modes, so
+they can use the spinner as part of their lighter by doing:
+    \\='(:eval (spinner-print THE-SPINNER))
+To stop this spinner, call `spinner-stop' on it.
+
+If TYPE-OR-OBJECT is anything else, a buffer-local spinner is
+created with this type, and it is displayed in the
+`mode-line-process' of the buffer it was created it.  Both
+TYPE-OR-OBJECT and FPS are passed to `make-spinner' (which see).
+To stop this spinner, call `spinner-stop' in the same buffer.
+
+Either way, the return value is a function which can be called
+anywhere to stop this spinner.  You can also call `spinner-stop'
+in the same buffer where the spinner was created.
+
+FPS, if given, is the number of desired frames per second.
+Default is `spinner-frames-per-second'.
+
+DELAY, if given, is the number of seconds to wait until actually
+displaying the spinner. It is safe to cancel the spinner before
+this time, in which case it won't display at all.
+
+\(fn &optional TYPE-OR-OBJECT FPS DELAY)" nil nil)
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; spinner-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/spinner-1.7.3/spinner-pkg.el b/configs/shared/emacs/.emacs.d/elpa/spinner-1.7.3/spinner-pkg.el
new file mode 100644
index 0000000000..19522bcaa7
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/spinner-1.7.3/spinner-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "spinner" "1.7.3" "Add spinners and progress-bars to the mode-line for ongoing operations" 'nil :url "https://github.com/Malabarba/spinner.el" :keywords '("processes" "mode-line"))
diff --git a/configs/shared/emacs/.emacs.d/elpa/spinner-1.7.3/spinner.el b/configs/shared/emacs/.emacs.d/elpa/spinner-1.7.3/spinner.el
new file mode 100644
index 0000000000..90aec8f4a7
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/spinner-1.7.3/spinner.el
@@ -0,0 +1,406 @@
+;;; spinner.el --- Add spinners and progress-bars to the mode-line for ongoing operations -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2015 Free Software Foundation, Inc.
+
+;; Author: Artur Malabarba <emacs@endlessparentheses.com>
+;; Version: 1.7.3
+;; URL: https://github.com/Malabarba/spinner.el
+;; Keywords: processes mode-line
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;
+;; 1 Usage
+;; ═══════
+;;
+;;   First of all, don’t forget to add `(spinner "VERSION")' to your
+;;   package’s dependencies.
+;;
+;;
+;; 1.1 Major-modes
+;; ───────────────
+;;
+;;   1. Just call `(spinner-start)' and a spinner will be added to the
+;;      mode-line.
+;;   2. Call `(spinner-stop)' on the same buffer when you want to remove
+;;      it.
+;;
+;;   The default spinner is a line drawing that rotates. You can pass an
+;;   argument to `spinner-start' to specify which spinner you want. All
+;;   possibilities are listed in the `spinner-types' variable, but here are
+;;   a few examples for you to try:
+;;
+;;   • `(spinner-start 'vertical-breathing 10)'
+;;   • `(spinner-start 'minibox)'
+;;   • `(spinner-start 'moon)'
+;;   • `(spinner-start 'triangle)'
+;;
+;;   You can also define your own as a vector of strings (see the examples
+;;   in `spinner-types').
+;;
+;;
+;; 1.2 Minor-modes
+;; ───────────────
+;;
+;;   Minor-modes can create a spinner with `spinner-create' and then add it
+;;   to their mode-line lighter. They can then start the spinner by setting
+;;   a variable and calling `spinner-start-timer'. Finally, they can stop
+;;   the spinner (and the timer) by just setting the same variable to nil.
+;;
+;;   Here’s an example for a minor-mode named `foo'. Assuming that
+;;   `foo--lighter' is used as the mode-line lighter, the following code
+;;   will add an *inactive* global spinner to the mode-line.
+;;   ┌────
+;;   │ (defvar foo--spinner (spinner-create 'rotating-line))
+;;   │ (defconst foo--lighter
+;;   │   '(" foo" (:eval (spinner-print foo--spinner))))
+;;   └────
+;;
+;;   1. To activate the spinner, just call `(spinner-start foo--spinner)'.
+;;      It will show up on the mode-line and start animating.
+;;   2. To get rid of it, call `(spinner-stop foo--spinner)'. It will then
+;;      disappear again.
+;;
+;;   Some minor-modes will need spinners to be buffer-local. To achieve
+;;   that, just make the `foo--spinner' variable buffer-local and use the
+;;   third argument of the `spinner-create' function. The snippet below is an
+;;   example.
+;;
+;;   ┌────
+;;   │ (defvar-local foo--spinner nil)
+;;   │ (defconst foo--lighter
+;;   │   '(" foo" (:eval (spinner-print foo--spinner))))
+;;   │ (defun foo--start-spinner ()
+;;   │   "Create and start a spinner on this buffer."
+;;   │   (unless foo--spinner
+;;   │     (setq foo--spinner (spinner-create 'moon t)))
+;;   │   (spinner-start foo--spinner))
+;;   └────
+;;
+;;   1. To activate the spinner, just call `(foo--start-spinner)'.
+;;   2. To get rid of it, call `(spinner-stop foo--spinner)'.
+;;
+;;   This will use the `moon' spinner, but you can use any of the names
+;;   defined in the `spinner-types' variable or even define your own.
+
+
+;;; Code:
+(eval-when-compile
+  (require 'cl))
+
+(defconst spinner-types
+  '((3-line-clock . ["┤" "┘" "┴" "└" "├" "┌" "┬" "┐"])
+    (2-line-clock . ["┘" "└" "┌" "┐"])
+    (flipping-line . ["_" "\\" "|" "/"])
+    (rotating-line . ["-" "\\" "|" "/"])
+    (progress-bar . ["[    ]" "[=   ]" "[==  ]" "[=== ]" "[====]" "[ ===]" "[  ==]" "[   =]"])
+    (progress-bar-filled . ["|    |" "|█   |" "|██  |" "|███ |" "|████|" "| ███|" "|  ██|" "|   █|"])
+    (vertical-breathing . ["▁" "▂" "▃" "▄" "▅" "▆" "▇" "█" "▇" "▆" "▅" "▄" "▃" "▂" "▁" " "])
+    (vertical-rising . ["▁" "▄" "█" "▀" "▔"])
+    (horizontal-breathing . [" " "▏" "▎" "▍" "▌" "▋" "▊" "▉" "▉" "▊" "▋" "▌" "▍" "▎" "▏"])
+    (horizontal-breathing-long
+     . ["  " "▎ " "▌ " "▊ " "█ " "█▎" "█▌" "█▊" "██" "█▊" "█▌" "█▎" "█ " "▊ " "▋ " "▌ " "▍ " "▎ " "▏ "])
+    (horizontal-moving . ["  " "▌ " "█ " "▐▌" " █" " ▐"])
+    (minibox . ["▖" "▘" "▝" "▗"])
+    (triangle . ["◢" "◣" "◤" "◥"])
+    (box-in-box . ["◰" "◳" "◲" "◱"])
+    (box-in-circle . ["◴" "◷" "◶" "◵"])
+    (half-circle . ["◐" "◓" "◑" "◒"])
+    (moon . ["🌑" "🌘" "🌖" "🌕" "🌔" "🌒"]))
+  "Predefined alist of spinners.
+Each car is a symbol identifying the spinner, and each cdr is a
+vector, the spinner itself.")
+
+(defun spinner-make-progress-bar (width &optional char)
+  "Return a vector of strings of the given WIDTH.
+The vector is a valid spinner type and is similar to the
+`progress-bar' spinner, except without the sorrounding brackets.
+CHAR is the character to use for the moving bar (defaults to =)."
+  (let ((whole-string (concat (make-string (1- width) ?\s)
+                              (make-string 4 (or char ?=))
+                              (make-string width ?\s))))
+    (apply #'vector (mapcar (lambda (n) (substring whole-string n (+ n width)))
+                            (number-sequence (+ width 3) 0 -1)))))
+
+(defvar spinner-current nil
+  "Spinner curently being displayed on the `mode-line-process'.")
+(make-variable-buffer-local 'spinner-current)
+
+(defconst spinner--mode-line-construct
+  '(:eval (spinner-print spinner-current))
+  "Construct used to display a spinner in `mode-line-process'.")
+(put 'spinner--mode-line-construct 'risky-local-variable t)
+
+(defvar spinner-frames-per-second 10
+  "Default speed at which spinners spin, in frames per second.
+Each spinner can override this value.")
+
+
+;;; The spinner object.
+(defun spinner--type-to-frames (type)
+  "Return a vector of frames corresponding to TYPE.
+The list of possible built-in spinner types is given by the
+`spinner-types' variable, but you can also use your own (see
+below).
+
+If TYPE is nil, the frames of this spinner are given by the first
+element of `spinner-types'.
+If TYPE is a symbol, it specifies an element of `spinner-types'.
+If TYPE is `random', use a random element of `spinner-types'.
+If TYPE is a list, it should be a list of symbols, and a random
+one is chosen as the spinner type.
+If TYPE is a vector, it should be a vector of strings and these
+are used as the spinner's frames.  This allows you to make your
+own spinner animations."
+  (cond
+   ((vectorp type) type)
+   ((not type) (cdr (car spinner-types)))
+   ((eq type 'random)
+    (cdr (elt spinner-types
+              (random (length spinner-types)))))
+   ((listp type)
+    (cdr (assq (elt type (random (length type)))
+               spinner-types)))
+   ((symbolp type) (cdr (assq type spinner-types)))
+   (t (error "Unknown spinner type: %s" type))))
+
+(defstruct (spinner
+            (:copier nil)
+            (:conc-name spinner--)
+            (:constructor make-spinner (&optional type buffer-local frames-per-second delay-before-start)))
+  (frames (spinner--type-to-frames type))
+  (counter 0)
+  (fps (or frames-per-second spinner-frames-per-second))
+  (timer (timer-create))
+  (active-p nil)
+  (buffer (when buffer-local
+            (if (bufferp buffer-local)
+                buffer-local
+              (current-buffer))))
+  (delay (or delay-before-start 0)))
+
+;;;###autoload
+(defun spinner-create (&optional type buffer-local fps delay)
+  "Create a spinner of the given TYPE.
+The possible TYPEs are described in `spinner--type-to-frames'.
+
+FPS, if given, is the number of desired frames per second.
+Default is `spinner-frames-per-second'.
+
+If BUFFER-LOCAL is non-nil, the spinner will be automatically
+deactivated if the buffer is killed.  If BUFFER-LOCAL is a
+buffer, use that instead of current buffer.
+
+When started, in order to function properly, the spinner runs a
+timer which periodically calls `force-mode-line-update' in the
+curent buffer.  If BUFFER-LOCAL was set at creation time, then
+`force-mode-line-update' is called in that buffer instead.  When
+the spinner is stopped, the timer is deactivated.
+
+DELAY, if given, is the number of seconds to wait after starting
+the spinner before actually displaying it. It is safe to cancel
+the spinner before this time, in which case it won't display at
+all."
+  (make-spinner type buffer-local fps delay))
+
+(defun spinner-print (spinner)
+  "Return a string of the current frame of SPINNER.
+If SPINNER is nil, just return nil.
+Designed to be used in the mode-line with:
+    (:eval (spinner-print some-spinner))"
+  (when (and spinner (spinner--active-p spinner))
+    (let ((frame (spinner--counter spinner)))
+      (when (>= frame 0)
+        (elt (spinner--frames spinner) frame)))))
+
+(defun spinner--timer-function (spinner)
+  "Function called to update SPINNER.
+If SPINNER is no longer active, or if its buffer has been killed,
+stop the SPINNER's timer."
+  (let ((buffer (spinner--buffer spinner)))
+    (if (or (not (spinner--active-p spinner))
+            (and buffer (not (buffer-live-p buffer))))
+        (spinner-stop spinner)
+      ;; Increment
+      (callf (lambda (x) (if (< x 0)
+                        (1+ x)
+                      (% (1+ x) (length (spinner--frames spinner)))))
+          (spinner--counter spinner))
+      ;; Update mode-line.
+      (if (buffer-live-p buffer)
+          (with-current-buffer buffer
+            (force-mode-line-update))
+        (force-mode-line-update)))))
+
+(defun spinner--start-timer (spinner)
+  "Start a SPINNER's timer."
+  (let ((old-timer (spinner--timer spinner)))
+    (when (timerp old-timer)
+      (cancel-timer old-timer))
+
+    (setf (spinner--active-p spinner) t)
+
+    (unless (ignore-errors (> (spinner--fps spinner) 0))
+      (error "A spinner's FPS must be a positive number"))
+    (setf (spinner--counter spinner) (round (- (* (or (spinner--delay spinner) 0)
+                                           (spinner--fps spinner)))))
+    ;; Create timer.
+    (let* ((repeat (/ 1.0 (spinner--fps spinner)))
+           (time (timer-next-integral-multiple-of-time (current-time) repeat))
+           ;; Create the timer as a lex variable so it can cancel itself.
+           (timer (spinner--timer spinner)))
+      (timer-set-time timer time repeat)
+      (timer-set-function timer #'spinner--timer-function (list spinner))
+      (timer-activate timer)
+      ;; Return a stopping function.
+      (lambda () (spinner-stop spinner)))))
+
+
+;;; The main functions
+;;;###autoload
+(defun spinner-start (&optional type-or-object fps delay)
+  "Start a mode-line spinner of given TYPE-OR-OBJECT.
+If TYPE-OR-OBJECT is an object created with `make-spinner',
+simply activate it.  This method is designed for minor modes, so
+they can use the spinner as part of their lighter by doing:
+    \\='(:eval (spinner-print THE-SPINNER))
+To stop this spinner, call `spinner-stop' on it.
+
+If TYPE-OR-OBJECT is anything else, a buffer-local spinner is
+created with this type, and it is displayed in the
+`mode-line-process' of the buffer it was created it.  Both
+TYPE-OR-OBJECT and FPS are passed to `make-spinner' (which see).
+To stop this spinner, call `spinner-stop' in the same buffer.
+
+Either way, the return value is a function which can be called
+anywhere to stop this spinner.  You can also call `spinner-stop'
+in the same buffer where the spinner was created.
+
+FPS, if given, is the number of desired frames per second.
+Default is `spinner-frames-per-second'.
+
+DELAY, if given, is the number of seconds to wait until actually
+displaying the spinner. It is safe to cancel the spinner before
+this time, in which case it won't display at all."
+  (unless (spinner-p type-or-object)
+    ;; Choose type.
+    (if (spinner-p spinner-current)
+        (setf (spinner--frames spinner-current) (spinner--type-to-frames type-or-object))
+      (setq spinner-current (make-spinner type-or-object (current-buffer) fps delay)))
+    (setq type-or-object spinner-current)
+    ;; Maybe add to mode-line.
+    (unless (memq 'spinner--mode-line-construct mode-line-process)
+      (setq mode-line-process
+            (list (or mode-line-process "")
+                  'spinner--mode-line-construct))))
+
+  ;; Create timer.
+  (when fps (setf (spinner--fps type-or-object) fps))
+  (when delay (setf (spinner--delay type-or-object) delay))
+  (spinner--start-timer type-or-object))
+
+(defun spinner-start-print (spinner)
+  "Like `spinner-print', but also start SPINNER if it's not active."
+  (unless (spinner--active-p spinner)
+    (spinner-start spinner))
+  (spinner-print spinner))
+
+(defun spinner-stop (&optional spinner)
+  "Stop SPINNER, defaulting to the current buffer's spinner.
+It is always safe to call this function, even if there is no
+active spinner."
+  (let ((spinner (or spinner spinner-current)))
+    (when (spinner-p spinner)
+      (let ((timer (spinner--timer spinner)))
+        (when (timerp timer)
+          (cancel-timer timer)))
+      (setf (spinner--active-p spinner) nil)
+      (force-mode-line-update))))
+
+;;;; ChangeLog:
+
+;; 2016-11-17  Artur Malabarba  <bruce.connor.am@gmail.com>
+;; 
+;; 	Merge commit '0637791f005f747532b4439439a81c3415961377'
+;; 
+;; 2016-07-11  Paul Eggert	 <eggert@cs.ucla.edu>
+;; 
+;; 	Fix some quoting problems in doc strings
+;; 
+;; 	Most of these are minor issues involving, e.g., quoting `like this' 
+;; 	instead of 'like this'.	 A few involve escaping ` and ' with a preceding
+;; 	\= when the characters should not be turned into curved single quotes.
+;; 
+;; 2016-04-01  Artur Malabarba  <bruce.connor.am@gmail.com>
+;; 
+;; 	Remove reference to thread-last
+;; 
+;; 2016-02-08  Artur Malabarba  <bruce.connor.am@gmail.com>
+;; 
+;; 	Spinner version 1.7
+;; 
+;; 	Offer a spinner-make-progress-bar function. Make spinner-stop never
+;; 	signal. Allow floating-point delays.
+;; 
+;; 2016-02-07  Artur Malabarba  <bruce.connor.am@gmail.com>
+;; 
+;; 	Update the mode-line after spinner-stop
+;; 
+;; 2015-08-11  Artur Malabarba  <bruce.connor.am@gmail.com>
+;; 
+;; 	Merge commit '8d8c459d7757cf5774f11be9147d7a54f5f9bbd7'
+;; 
+;; 2015-05-02  Artur Malabarba  <bruce.connor.am@gmail.com>
+;; 
+;; 	* spinner: Rename constructor.
+;; 
+;; 2015-04-30  Artur Malabarba  <bruce.connor.am@gmail.com>
+;; 
+;; 	* spinner/spinner.el: Rewrite spinners as structures
+;; 
+;; 2015-04-09  Artur Malabarba  <bruce.connor.am@gmail.com>
+;; 
+;; 	spinner: Fix readme
+;; 
+;; 2015-04-09  Artur Malabarba  <bruce.connor.am@gmail.com>
+;; 
+;; 	spinner: Fix leftover mode-line-format code
+;; 
+;; 2015-04-09  Artur Malabarba  <bruce.connor.am@gmail.com>
+;; 
+;; 	Merge commit 'c44ef65515f50bd38304a6f50adebc984fb8e431'
+;; 
+;; 2015-03-07  Artur Malabarba  <bruce.connor.am@gmail.com>
+;; 
+;; 	Merge commit '7eca7d023c95bc21c7838467b3a58d549afaf68d'
+;; 
+;; 2015-03-07  Artur Malabarba  <bruce.connor.am@gmail.com>
+;; 
+;; 	Merge commit 'a7b4e52766977b58c6b9899305e962a2b5235bda'
+;; 
+;; 2015-03-07  Artur Malabarba  <bruce.connor.am@gmail.com>
+;; 
+;; 	Add 'packages/spinner/' from commit
+;; 	'9477ee899d62259d4b946f243cdcdd9cdeb1e910'
+;; 
+;; 	git-subtree-dir: packages/spinner git-subtree-mainline:
+;; 	5736e852fd48a0f1ba1c328dd4d03e3fa008a406 git-subtree-split:
+;; 	9477ee899d62259d4b946f243cdcdd9cdeb1e910
+;; 
+
+
+(provide 'spinner)
+
+;;; spinner.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/spinner-1.7.3/spinner.elc b/configs/shared/emacs/.emacs.d/elpa/spinner-1.7.3/spinner.elc
new file mode 100644
index 0000000000..215de12082
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/spinner-1.7.3/spinner.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/swiper-20180713.946/swiper-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/swiper-20180713.946/swiper-autoloads.el
new file mode 100644
index 0000000000..aaaa5503f4
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/swiper-20180713.946/swiper-autoloads.el
@@ -0,0 +1,32 @@
+;;; swiper-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "swiper" "swiper.el" (23377 60990 394949 440000))
+;;; Generated autoloads from swiper.el
+
+(autoload 'swiper-avy "swiper" "\
+Jump to one of the current swiper candidates.
+
+\(fn)" t nil)
+
+(autoload 'swiper "swiper" "\
+`isearch' with an overview.
+When non-nil, INITIAL-INPUT is the initial search pattern.
+
+\(fn &optional INITIAL-INPUT)" t nil)
+
+(autoload 'swiper-all "swiper" "\
+Run `swiper' for all open buffers.
+
+\(fn &optional INITIAL-INPUT)" t nil)
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; swiper-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/swiper-20180713.946/swiper-pkg.el b/configs/shared/emacs/.emacs.d/elpa/swiper-20180713.946/swiper-pkg.el
new file mode 100644
index 0000000000..ae0810f5f6
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/swiper-20180713.946/swiper-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "swiper" "20180713.946" "Isearch with an overview. Oh, man!" '((emacs "24.1") (ivy "0.9.0")))
diff --git a/configs/shared/emacs/.emacs.d/elpa/swiper-20180713.946/swiper.el b/configs/shared/emacs/.emacs.d/elpa/swiper-20180713.946/swiper.el
new file mode 100644
index 0000000000..80b9fffe1a
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/swiper-20180713.946/swiper.el
@@ -0,0 +1,1040 @@
+;;; swiper.el --- Isearch with an overview. Oh, man! -*- lexical-binding: t -*-
+
+;; Copyright (C) 2015-2018  Free Software Foundation, Inc.
+
+;; Author: Oleh Krehel <ohwoeowho@gmail.com>
+;; URL: https://github.com/abo-abo/swiper
+;; Package-Version: 20180713.946
+;; Version: 0.10.0
+;; Package-Requires: ((emacs "24.1") (ivy "0.9.0"))
+;; Keywords: matching
+
+;; This file is part of GNU Emacs.
+
+;; This file 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, or (at your option)
+;; any later version.
+
+;; This program 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.
+
+;; For a full copy of the GNU General Public License
+;; see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This package gives an overview of the current regex search
+;; candidates.  The search regex can be split into groups with a
+;; space.  Each group is highlighted with a different face.
+;;
+;; It can double as a quick `regex-builder', although only single
+;; lines will be matched.
+
+;;; Code:
+
+(require 'ivy)
+
+(defgroup swiper nil
+  "`isearch' with an overview."
+  :group 'matching
+  :prefix "swiper-")
+
+(defface swiper-match-face-1
+  '((t (:inherit lazy-highlight)))
+  "The background face for `swiper' matches.")
+
+(defface swiper-match-face-2
+  '((t (:inherit isearch)))
+  "Face for `swiper' matches modulo 1.")
+
+(defface swiper-match-face-3
+  '((t (:inherit match)))
+  "Face for `swiper' matches modulo 2.")
+
+(defface swiper-match-face-4
+  '((t (:inherit isearch-fail)))
+  "Face for `swiper' matches modulo 3.")
+
+(defface swiper-line-face
+  '((t (:inherit highlight)))
+  "Face for current `swiper' line.")
+
+(defcustom swiper-faces '(swiper-match-face-1
+                          swiper-match-face-2
+                          swiper-match-face-3
+                          swiper-match-face-4)
+  "List of `swiper' faces for group matches."
+  :group 'ivy-faces
+  :type '(repeat face))
+
+(defcustom swiper-min-highlight 2
+  "Only highlight matches for regexps at least this long."
+  :type 'integer)
+
+(defcustom swiper-include-line-number-in-search nil
+  "Include line number in text of search candidates."
+  :type 'boolean
+  :group 'swiper)
+
+(defcustom swiper-goto-start-of-match nil
+  "When non-nil, go to the start of the match, not its end."
+  :type 'boolean
+  :group 'swiper)
+
+(defvar swiper-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "M-q") 'swiper-query-replace)
+    (define-key map (kbd "C-l") 'swiper-recenter-top-bottom)
+    (define-key map (kbd "C-'") 'swiper-avy)
+    (define-key map (kbd "C-7") 'swiper-mc)
+    (define-key map (kbd "C-c C-f") 'swiper-toggle-face-matching)
+    map)
+  "Keymap for swiper.")
+
+(defun swiper-query-replace ()
+  "Start `query-replace' with string to replace from last search string."
+  (interactive)
+  (if (null (window-minibuffer-p))
+      (user-error "Should only be called in the minibuffer through `swiper-map'")
+    (let* ((enable-recursive-minibuffers t)
+           (from (ivy--regex ivy-text))
+           (to (minibuffer-with-setup-hook
+                   (lambda ()
+                     (setq minibuffer-default
+                           (if (string-match "\\`\\\\_<\\(.*\\)\\\\_>\\'" ivy-text)
+                               (match-string 1 ivy-text)
+                             ivy-text)))
+                 (read-from-minibuffer (format "Query replace %s with: " from)))))
+      (swiper--cleanup)
+      (ivy-exit-with-action
+       (lambda (_)
+         (with-ivy-window
+           (move-beginning-of-line 1)
+           (let ((inhibit-read-only t))
+             (perform-replace from to
+                              t t nil))))))))
+
+(defun swiper-all-query-replace ()
+  "Start `query-replace' with string to replace from last search string."
+  (interactive)
+  (if (null (window-minibuffer-p))
+      (user-error
+       "Should only be called in the minibuffer through `swiper-all-map'")
+    (let* ((enable-recursive-minibuffers t)
+           (from (ivy--regex ivy-text))
+           (to (query-replace-read-to from "Query replace" t)))
+      (swiper--cleanup)
+      (ivy-exit-with-action
+       (lambda (_)
+         (let ((wnd-conf (current-window-configuration))
+               (inhibit-message t))
+           (unwind-protect
+                (dolist (cand ivy--old-cands)
+                  (let ((buffer (get-text-property 0 'buffer cand)))
+                    (switch-to-buffer buffer)
+                    (goto-char (point-min))
+                    (perform-replace from to t t nil)))
+             (set-window-configuration wnd-conf))))))))
+
+(defvar avy-background)
+(defvar avy-all-windows)
+(defvar avy-style)
+(defvar avy-keys)
+(declare-function avy--regex-candidates "ext:avy")
+(declare-function avy--process "ext:avy")
+(declare-function avy--overlay-post "ext:avy")
+(declare-function avy-action-goto "ext:avy")
+(declare-function avy-candidate-beg "ext:avy")
+(declare-function avy--done "ext:avy")
+(declare-function avy--make-backgrounds "ext:avy")
+(declare-function avy-window-list "ext:avy")
+(declare-function avy-read "ext:avy")
+(declare-function avy-read-de-bruijn "ext:avy")
+(declare-function avy-tree "ext:avy")
+(declare-function avy-push-mark "ext:avy")
+(declare-function avy--remove-leading-chars "ext:avy")
+
+;;;###autoload
+(defun swiper-avy ()
+  "Jump to one of the current swiper candidates."
+  (interactive)
+  (unless (require 'avy nil 'noerror)
+    (error "Package avy isn't installed"))
+  (unless (string= ivy-text "")
+    (let* ((avy-all-windows nil)
+           ;; We'll have overlapping overlays, so we sort all the
+           ;; overlays in the visible region by their start, and then
+           ;; throw out non-Swiper overlays or overlapping Swiper
+           ;; overlays.
+           (visible-overlays (cl-sort (with-ivy-window
+                                        (overlays-in (window-start)
+                                                     (window-end)))
+                                      #'< :key #'overlay-start))
+           (min-overlay-start 0)
+           (overlays-for-avy (cl-remove-if-not
+                              (lambda (ov)
+                                (when (and (>= (overlay-start ov)
+                                               min-overlay-start)
+                                           (memq (overlay-get ov 'face)
+                                                 swiper-faces))
+                                  (setq min-overlay-start (overlay-start ov))))
+                              visible-overlays))
+           (candidates (append
+                        (mapcar (lambda (ov)
+                                  (cons (overlay-start ov)
+                                        (overlay-get ov 'window)))
+                                overlays-for-avy)
+                        (save-excursion
+                          (save-restriction
+                            (narrow-to-region (window-start) (window-end))
+                            (goto-char (point-min))
+                            (forward-line)
+                            (let ((cands))
+                              (while (< (point) (point-max))
+                                (push (cons (1+ (point))
+                                            (selected-window))
+                                      cands)
+                                (forward-line))
+                              cands)))))
+           (candidate (unwind-protect
+                           (prog2
+                               (avy--make-backgrounds
+                                (append (avy-window-list)
+                                        (list (ivy-state-window ivy-last))))
+                               (if (eq avy-style 'de-bruijn)
+                                   (avy-read-de-bruijn
+                                    candidates avy-keys)
+                                 (avy-read (avy-tree candidates avy-keys)
+                                           #'avy--overlay-post
+                                           #'avy--remove-leading-chars))
+                             (avy-push-mark))
+                        (avy--done))))
+      (if (window-minibuffer-p (cdr candidate))
+          (progn
+            (ivy-set-index (- (line-number-at-pos (car candidate)) 2))
+            (ivy--exhibit)
+            (ivy-done)
+            (ivy-call))
+        (ivy-quit-and-run
+          (avy-action-goto (avy-candidate-beg candidate)))))))
+
+(declare-function mc/create-fake-cursor-at-point "ext:multiple-cursors-core")
+(declare-function multiple-cursors-mode "ext:multiple-cursors-core")
+
+(defun swiper-mc ()
+  "Create a fake cursor for each `swiper' candidate."
+  (interactive)
+  (unless (require 'multiple-cursors nil t)
+    (error "Multiple-cursors isn't installed"))
+  (unless (window-minibuffer-p)
+    (error "Call me only from `swiper'"))
+  (let ((cands (nreverse ivy--old-cands)))
+    (unless (string= ivy-text "")
+      (ivy-exit-with-action
+       (lambda (_)
+         (let (cand)
+           (while (setq cand (pop cands))
+             (swiper--action cand)
+             (when cands
+               (mc/create-fake-cursor-at-point))))
+         (multiple-cursors-mode 1))))))
+
+(defun swiper-recenter-top-bottom (&optional arg)
+  "Call (`recenter-top-bottom' ARG)."
+  (interactive "P")
+  (with-ivy-window
+    (recenter-top-bottom arg)))
+
+(defvar swiper-font-lock-exclude
+  '(bbdb-mode
+    bookmark-bmenu-mode
+    package-menu-mode
+    gnus-summary-mode
+    gnus-article-mode
+    gnus-group-mode
+    emms-playlist-mode
+    emms-stream-mode
+    eshell-mode
+    erc-mode
+    forth-mode
+    forth-block-mode
+    helpful-mode
+    nix-mode
+    org-agenda-mode
+    dired-mode
+    jabber-chat-mode
+    elfeed-search-mode
+    elfeed-show-mode
+    fundamental-mode
+    Man-mode
+    woman-mode
+    mu4e-view-mode
+    mu4e-headers-mode
+    notmuch-tree-mode
+    notmuch-search-mode
+    help-mode
+    debbugs-gnu-mode
+    occur-mode
+    occur-edit-mode
+    bongo-mode
+    bongo-library-mode
+    magit-popup-mode
+    adoc-mode
+    bongo-playlist-mode
+    eww-mode
+    treemacs-mode
+    twittering-mode
+    vc-dir-mode
+    rcirc-mode
+    circe-channel-mode
+    circe-server-mode
+    circe-query-mode
+    sauron-mode
+    w3m-mode)
+  "List of major-modes that are incompatible with `font-lock-ensure'.")
+
+(defun swiper-font-lock-ensure-p ()
+  "Return non-nil if we should `font-lock-ensure'."
+  (or (derived-mode-p 'magit-mode)
+      (bound-and-true-p magit-blame-mode)
+      (memq major-mode swiper-font-lock-exclude)))
+
+(defun swiper-font-lock-ensure ()
+  "Ensure the entired buffer is highlighted."
+  (unless (swiper-font-lock-ensure-p)
+    (unless (or (> (buffer-size) 100000) (null font-lock-mode))
+      (if (fboundp 'font-lock-ensure)
+          (font-lock-ensure)
+        (with-no-warnings (font-lock-fontify-buffer))))))
+
+(defvar swiper--format-spec ""
+  "Store the current candidates format spec.")
+
+(defvar swiper--width nil
+  "Store the number of digits needed for the longest line nubmer.")
+
+(defvar swiper-use-visual-line nil
+  "When non-nil, use `line-move' instead of `forward-line'.")
+
+(defvar dired-isearch-filenames)
+(declare-function dired-move-to-filename "dired")
+
+(defun swiper--line ()
+  (let* ((beg (cond ((and (eq major-mode 'dired-mode)
+                          (bound-and-true-p dired-isearch-filenames))
+                     (dired-move-to-filename)
+                     (point))
+                    (swiper-use-visual-line
+                     (save-excursion
+                       (beginning-of-visual-line)
+                       (point)))
+                    (t
+                     (point))))
+         (end (if swiper-use-visual-line
+                  (save-excursion
+                    (end-of-visual-line)
+                    (point))
+                (line-end-position))))
+
+    (concat
+     " "
+     (buffer-substring beg end))))
+
+(declare-function outline-show-all "outline")
+
+(defun swiper--candidates (&optional numbers-width)
+  "Return a list of this buffer lines.
+
+NUMBERS-WIDTH, when specified, is used for width spec of line
+numbers; replaces calculating the width from buffer line count."
+  (if (and visual-line-mode
+           ;; super-slow otherwise
+           (< (buffer-size) 20000))
+      (progn
+        (when (eq major-mode 'org-mode)
+          (require 'outline)
+          (if (fboundp 'outline-show-all)
+              (outline-show-all)
+            (with-no-warnings
+              (show-all))))
+        (setq swiper-use-visual-line t))
+    (setq swiper-use-visual-line nil))
+  (let ((n-lines (count-lines (point-min) (point-max))))
+    (unless (zerop n-lines)
+      (setq swiper--width (or numbers-width
+                              (1+ (floor (log n-lines 10)))))
+      (setq swiper--format-spec
+            (format "%%-%dd " swiper--width))
+      (let ((line-number 0)
+            (advancer (if swiper-use-visual-line
+                          (lambda (arg) (line-move arg t))
+                        #'forward-line))
+            candidates)
+        (save-excursion
+          (goto-char (point-min))
+          (swiper-font-lock-ensure)
+          (while (< (point) (point-max))
+            (let ((str (swiper--line)))
+              (setq str (ivy-cleanup-string str))
+              (let ((line-number-str
+                     (format swiper--format-spec (cl-incf line-number))))
+                (if swiper-include-line-number-in-search
+                    (setq str (concat line-number-str str))
+                  (put-text-property
+                   0 1 'display line-number-str str))
+                (put-text-property
+                 0 1 'swiper-line-number line-number-str str))
+              (push str candidates))
+            (funcall advancer 1))
+          (nreverse candidates))))))
+
+(defvar swiper--opoint 1
+  "The point when `swiper' starts.")
+
+;;;###autoload
+(defun swiper (&optional initial-input)
+  "`isearch' with an overview.
+When non-nil, INITIAL-INPUT is the initial search pattern."
+  (interactive)
+  (swiper--ivy (swiper--candidates) initial-input))
+
+(defvar swiper--current-window-start nil)
+
+(defun swiper--extract-matches (regex cands)
+  "Extract captured REGEX groups from CANDS."
+  (let (res)
+    (dolist (cand cands)
+      (setq cand (substring cand 1))
+      (when (string-match regex cand)
+        (push (mapconcat (lambda (n) (match-string-no-properties n cand))
+                         (number-sequence
+                          1
+                          (/ (- (length (match-data)) 2) 2))
+                         " ")
+              res)))
+    (nreverse res)))
+
+(defun swiper-occur (&optional revert)
+  "Generate a custom occur buffer for `swiper'.
+When REVERT is non-nil, regenerate the current *ivy-occur* buffer.
+When capture groups are present in the input, print them instead of lines."
+  (let* ((buffer (ivy-state-buffer ivy-last))
+         (fname (propertize
+                 (with-ivy-window
+                   (if (buffer-file-name buffer)
+                       (file-name-nondirectory
+                        (buffer-file-name buffer))
+                     (buffer-name buffer)))
+                 'face
+                 'compilation-info))
+         (re (progn (string-match "\"\\(.*\\)\"" (buffer-name))
+                    (match-string 1 (buffer-name))))
+         (re (mapconcat #'identity (ivy--split re) ".*?"))
+         (cands
+          (mapcar
+           (lambda (s)
+             (let* ((n (get-text-property 0 'swiper-line-number s))
+                    (i (string-match-p "[ \t\n\r]+\\'" n)))
+               (when i (setq n (substring n 0 i)))
+               (put-text-property 0 (length n) 'face 'compilation-line-number n)
+               (format "%s:%s:%s" fname n (substring s 1))))
+           (if (not revert)
+               ivy--old-cands
+             (setq ivy--old-re nil)
+             (let ((ivy--regex-function 'swiper--re-builder))
+               (ivy--filter re (with-current-buffer buffer
+                                 (swiper--candidates))))))))
+    (if (string-match-p "\\\\(" re)
+        (insert
+         (mapconcat #'identity
+                    (swiper--extract-matches
+                     re (with-current-buffer buffer
+                          (swiper--candidates)))
+                    "\n"))
+      (unless (eq major-mode 'ivy-occur-grep-mode)
+        (ivy-occur-grep-mode)
+        (font-lock-mode -1))
+      (setq swiper--current-window-start nil)
+      (insert (format "-*- mode:grep; default-directory: %S -*-\n\n\n"
+                      default-directory))
+      (insert (format "%d candidates:\n" (length cands)))
+      (ivy--occur-insert-lines
+       (mapcar
+        (lambda (cand) (concat "./" cand))
+        cands))
+      (goto-char (point-min))
+      (forward-line 4))))
+
+(ivy-set-occur 'swiper 'swiper-occur)
+
+(declare-function evil-set-jump "ext:evil-jumps")
+
+(defvar swiper--current-line nil)
+(defvar swiper--current-match-start nil)
+(defvar swiper--point-min nil)
+(defvar swiper--point-max nil)
+(defvar swiper--reveal-mode nil)
+
+(defun swiper--init ()
+  "Perform initialization common to both completion methods."
+  (setq swiper--current-line nil)
+  (setq swiper--current-match-start nil)
+  (setq swiper--current-window-start nil)
+  (setq swiper--opoint (point))
+  (setq swiper--point-min (point-min))
+  (setq swiper--point-max (point-max))
+  (when (setq swiper--reveal-mode
+              (bound-and-true-p reveal-mode))
+    (reveal-mode -1))
+  (when (bound-and-true-p evil-mode)
+    (evil-set-jump)))
+
+(declare-function char-fold-to-regexp "char-fold")
+
+(defun swiper--re-builder (str)
+  "Transform STR into a swiper regex.
+This is the regex used in the minibuffer where candidates have
+line numbers.  For the buffer, use `ivy--regex' instead."
+  (let* ((re-builder (ivy-alist-setting ivy-re-builders-alist))
+         (re (cond
+               ((equal str "")
+                "")
+               ((equal str "^")
+                (setq ivy--subexps 0)
+                ".")
+               ((string-match "^\\^" str)
+                (let ((re (funcall re-builder (substring str 1))))
+                  (if (zerop ivy--subexps)
+                      (prog1 (format "^ ?\\(%s\\)" re)
+                        (setq ivy--subexps 1))
+                    (format "^ %s" re))))
+               ((eq (bound-and-true-p search-default-mode) 'char-fold-to-regexp)
+                (mapconcat #'char-fold-to-regexp (ivy--split str) ".*"))
+               (t
+                (funcall re-builder str)))))
+    re))
+
+(defvar swiper-history nil
+  "History for `swiper'.")
+
+(defvar swiper-invocation-face nil
+  "The face at the point of invocation of `swiper'.")
+
+(defcustom swiper-stay-on-quit nil
+  "When non-nil don't go back to search start on abort."
+  :type 'boolean)
+
+(defun swiper--ivy (candidates &optional initial-input)
+  "Select one of CANDIDATES and move there.
+When non-nil, INITIAL-INPUT is the initial search pattern."
+  (swiper--init)
+  (setq swiper-invocation-face
+        (plist-get (text-properties-at (point)) 'face))
+  (let ((preselect
+         (if swiper-use-visual-line
+             (count-screen-lines
+              (point-min)
+              (save-excursion (beginning-of-visual-line) (point)))
+           (1- (line-number-at-pos))))
+        (minibuffer-allow-text-properties t)
+        res)
+    (unwind-protect
+         (and
+          (setq res
+                (ivy-read
+                 "Swiper: "
+                 candidates
+                 :initial-input initial-input
+                 :keymap swiper-map
+                 :preselect preselect
+                 :require-match t
+                 :update-fn #'swiper--update-input-ivy
+                 :unwind #'swiper--cleanup
+                 :action #'swiper--action
+                 :re-builder #'swiper--re-builder
+                 :history 'swiper-history
+                 :caller 'swiper))
+          (point))
+      (unless (or res swiper-stay-on-quit)
+        (goto-char swiper--opoint))
+      (when (and (null res) (> (length ivy-text) 0))
+        (cl-pushnew ivy-text swiper-history))
+      (when swiper--reveal-mode
+        (reveal-mode 1)))))
+
+(defun swiper-toggle-face-matching ()
+  "Toggle matching only the candidates with `swiper-invocation-face'."
+  (interactive)
+  (setf (ivy-state-matcher ivy-last)
+        (if (ivy-state-matcher ivy-last)
+            nil
+          #'swiper--face-matcher))
+  (setq ivy--old-re nil))
+
+(defun swiper--face-matcher (regexp candidates)
+  "Return REGEXP matching CANDIDATES.
+Matched candidates should have `swiper-invocation-face'."
+  (cl-remove-if-not
+   (lambda (x)
+     (and
+      (string-match regexp x)
+      (let ((s (match-string 0 x))
+            (i 0))
+        (while (and (< i (length s))
+                    (text-property-any
+                     i (1+ i)
+                     'face swiper-invocation-face
+                     s))
+          (cl-incf i))
+        (eq i (length s)))))
+   candidates))
+
+(defun swiper--ensure-visible ()
+  "Remove overlays hiding point."
+  (let ((overlays (overlays-at (1- (point))))
+        ov expose)
+    (while (setq ov (pop overlays))
+      (if (and (invisible-p (overlay-get ov 'invisible))
+               (setq expose (overlay-get ov 'isearch-open-invisible)))
+          (funcall expose ov)))))
+
+(defvar swiper--overlays nil
+  "Store overlays.")
+
+(defun swiper--cleanup ()
+  "Clean up the overlays."
+  (while swiper--overlays
+    (delete-overlay (pop swiper--overlays)))
+  (save-excursion
+    (goto-char (point-min))
+    (isearch-clean-overlays)))
+
+(defun swiper--update-input-ivy ()
+  "Called when `ivy' input is updated."
+  (with-ivy-window
+    (swiper--cleanup)
+    (when (> (length (ivy-state-current ivy-last)) 0)
+      (let* ((regexp-or-regexps (funcall ivy--regex-function ivy-text))
+             (regexps
+              (if (listp regexp-or-regexps)
+                  (mapcar #'car (cl-remove-if-not #'cdr regexp-or-regexps))
+                (list regexp-or-regexps))))
+        (dolist (re regexps)
+          (let* ((re (replace-regexp-in-string
+                      "    " "\t"
+                      re))
+                 (str (get-text-property 0 'swiper-line-number (ivy-state-current ivy-last)))
+                 (num (if (string-match "^[0-9]+" str)
+                          (string-to-number (match-string 0 str))
+                        0)))
+            (unless (memq this-command '(ivy-yank-word
+                                         ivy-yank-symbol
+                                         ivy-yank-char
+                                         scroll-other-window))
+              (when (cl-plusp num)
+                (unless (if swiper--current-line
+                            (eq swiper--current-line num)
+                          (eq (line-number-at-pos) num))
+                  (goto-char swiper--point-min)
+                  (if swiper-use-visual-line
+                      (line-move (1- num))
+                    (forward-line (1- num))))
+                (if (and (equal ivy-text "")
+                         (>= swiper--opoint (line-beginning-position))
+                         (<= swiper--opoint (line-end-position)))
+                    (goto-char swiper--opoint)
+                  (if (eq swiper--current-line num)
+                      (when swiper--current-match-start
+                        (goto-char swiper--current-match-start))
+                    (setq swiper--current-line num))
+                  (when (re-search-forward re (line-end-position) t)
+                    (setq swiper--current-match-start (match-beginning 0))))
+                (isearch-range-invisible (line-beginning-position)
+                                         (line-end-position))
+                (unless (and (>= (point) (window-start))
+                             (<= (point) (window-end (ivy-state-window ivy-last) t)))
+                  (recenter))
+                (setq swiper--current-window-start (window-start))))
+            (swiper--add-overlays
+             re
+             (max (window-start) swiper--point-min)
+             (min (window-end (selected-window) t) swiper--point-max))))))))
+
+(defun swiper--add-overlays (re &optional beg end wnd)
+  "Add overlays for RE regexp in visible part of the current buffer.
+BEG and END, when specified, are the point bounds.
+WND, when specified is the window."
+  (setq wnd (or wnd (ivy-state-window ivy-last)))
+  (let ((ov (if visual-line-mode
+                (make-overlay
+                 (save-excursion
+                   (beginning-of-visual-line)
+                   (point))
+                 (save-excursion
+                   (end-of-visual-line)
+                   (point)))
+              (make-overlay
+               (line-beginning-position)
+               (1+ (line-end-position))))))
+    (overlay-put ov 'face 'swiper-line-face)
+    (overlay-put ov 'window wnd)
+    (push ov swiper--overlays)
+    (let* ((wh (window-height))
+           (beg (or beg (save-excursion
+                          (forward-line (- wh))
+                          (point))))
+           (end (or end (save-excursion
+                          (forward-line wh)
+                          (point))))
+           (case-fold-search (ivy--case-fold-p re)))
+      (when (>= (length re) swiper-min-highlight)
+        (save-excursion
+          (goto-char beg)
+          ;; RE can become an invalid regexp
+          (while (and (ignore-errors (re-search-forward re end t))
+                      (> (- (match-end 0) (match-beginning 0)) 0))
+            ;; Don't highlight a match if it spans multiple
+            ;; lines. `count-lines' returns 1 if the match is within a
+            ;; single line, even if it includes the newline, and 2 or
+            ;; greater otherwise. We hope that the inclusion of the
+            ;; newline will not ever be a problem in practice.
+            (when (< (count-lines (match-beginning 0) (match-end 0)) 2)
+              (unless (and (consp ivy--old-re)
+                           (null
+                            (save-match-data
+                              (ivy--re-filter ivy--old-re
+                                              (list
+                                               (buffer-substring-no-properties
+                                                (line-beginning-position)
+                                                (line-end-position)))))))
+                (let ((mb (match-beginning 0))
+                      (me (match-end 0)))
+                  (unless (> (- me mb) 2017)
+                    (swiper--add-overlay mb me
+                                         (if (zerop ivy--subexps)
+                                             (cadr swiper-faces)
+                                           (car swiper-faces))
+                                         wnd 0))))
+              (let ((i 1)
+                    (j 0))
+                (while (<= (cl-incf j) ivy--subexps)
+                  (let ((bm (match-beginning j))
+                        (em (match-end j)))
+                    (when (and (integerp em)
+                               (integerp bm))
+                      (while (and (< j ivy--subexps)
+                                  (integerp (match-beginning (+ j 1)))
+                                  (= em (match-beginning (+ j 1))))
+                        (setq em (match-end (cl-incf j))))
+                      (swiper--add-overlay
+                       bm em
+                       (nth (1+ (mod (+ i 2) (1- (length swiper-faces))))
+                            swiper-faces)
+                       wnd i)
+                      (cl-incf i))))))))))))
+
+(defun swiper--add-overlay (beg end face wnd priority)
+  "Add overlay bound by BEG and END to `swiper--overlays'.
+FACE, WND and PRIORITY are properties corresponding to
+the face, window and priority of the overlay."
+  (let ((overlay (make-overlay beg end)))
+    (push overlay swiper--overlays)
+    (overlay-put overlay 'face face)
+    (overlay-put overlay 'window wnd)
+    (overlay-put overlay 'priority priority)))
+
+(defcustom swiper-action-recenter nil
+  "When non-nil, recenter after exiting `swiper'."
+  :type 'boolean)
+(defvar evil-search-module)
+(defvar evil-ex-search-pattern)
+(defvar evil-ex-search-persistent-highlight)
+(defvar evil-ex-search-direction)
+(declare-function evil-ex-search-activate-highlight "evil-ex")
+
+
+(defun swiper--action (x)
+  "Goto line X."
+  (let ((ln (1- (read (or (get-text-property 0 'swiper-line-number x)
+                          (and (string-match ":\\([0-9]+\\):.*\\'" x)
+                               (match-string-no-properties 1 x))))))
+        (re (ivy--regex ivy-text)))
+    (if (null x)
+        (user-error "No candidates")
+      (with-ivy-window
+        (unless (equal (current-buffer)
+                       (ivy-state-buffer ivy-last))
+          (switch-to-buffer (ivy-state-buffer ivy-last)))
+        (goto-char swiper--point-min)
+        (funcall (if swiper-use-visual-line
+                     #'line-move
+                   #'forward-line)
+                 ln)
+        (when (and (re-search-forward re (line-end-position) t) swiper-goto-start-of-match)
+          (goto-char (match-beginning 0)))
+        (swiper--ensure-visible)
+        (cond (swiper-action-recenter
+               (recenter))
+              (swiper--current-window-start
+               (set-window-start (selected-window) swiper--current-window-start)))
+        (when (/= (point) swiper--opoint)
+          (unless (and transient-mark-mode mark-active)
+            (when (eq ivy-exit 'done)
+              (push-mark swiper--opoint t)
+              (message "Mark saved where search started"))))
+        (add-to-history
+         'regexp-search-ring
+         re
+         regexp-search-ring-max)
+        ;; integration with evil-mode's search
+        (when (bound-and-true-p evil-mode)
+          (when (eq evil-search-module 'isearch)
+            (setq isearch-string ivy-text))
+          (when (eq evil-search-module 'evil-search)
+            (add-to-history 'evil-ex-search-history re)
+            (setq evil-ex-search-pattern (list re t t))
+            (setq evil-ex-search-direction 'forward)
+            (when evil-ex-search-persistent-highlight
+              (evil-ex-search-activate-highlight evil-ex-search-pattern))))))))
+
+(defun swiper-from-isearch ()
+  "Invoke `swiper' from isearch."
+  (interactive)
+  (let ((query (if isearch-regexp
+                   isearch-string
+                 (regexp-quote isearch-string))))
+    (isearch-exit)
+    (swiper query)))
+
+(defvar swiper-multi-buffers nil
+  "Store the current list of buffers.")
+
+(defvar swiper-multi-candidates nil
+  "Store the list of candidates for `swiper-multi'.")
+
+(defun swiper-multi-prompt ()
+  "Return prompt for `swiper-multi'."
+  (format "Buffers (%s): "
+          (mapconcat #'identity swiper-multi-buffers ", ")))
+
+(defun swiper-multi ()
+  "Select one or more buffers.
+Run `swiper' for those buffers."
+  (interactive)
+  (setq swiper-multi-buffers nil)
+  (let ((ivy-use-virtual-buffers nil))
+    (ivy-read (swiper-multi-prompt)
+              'internal-complete-buffer
+              :action 'swiper-multi-action-1))
+  (ivy-read "Swiper: " swiper-multi-candidates
+            :action 'swiper-multi-action-2
+            :unwind #'swiper--cleanup
+            :caller 'swiper-multi))
+
+(defun swiper-multi-action-1 (x)
+  "Add X to list of selected buffers `swiper-multi-buffers'.
+If X is already part of the list, remove it instead.  Quit the selection if
+X is selected by either `ivy-done', `ivy-alt-done' or `ivy-immediate-done',
+otherwise continue prompting for buffers."
+  (if (member x swiper-multi-buffers)
+      (progn
+        (setq swiper-multi-buffers (delete x swiper-multi-buffers)))
+    (unless (equal x "")
+      (setq swiper-multi-buffers (append swiper-multi-buffers (list x)))))
+  (let ((prompt (swiper-multi-prompt)))
+    (setf (ivy-state-prompt ivy-last) prompt)
+    (setq ivy--prompt (concat "%-4d " prompt)))
+  (cond ((memq this-command '(ivy-done
+                              ivy-alt-done
+                              ivy-immediate-done))
+         (setq swiper-multi-candidates
+               (swiper--multi-candidates
+                (mapcar #'get-buffer swiper-multi-buffers))))
+        ((eq this-command 'ivy-call)
+         (with-selected-window (active-minibuffer-window)
+           (delete-minibuffer-contents)))))
+
+(defun swiper-multi-action-2 (x)
+  "Move to candidate X from `swiper-multi'."
+  (when (> (length x) 0)
+    (let ((buffer-name (get-text-property 0 'buffer x)))
+      (when buffer-name
+        (with-ivy-window
+          (switch-to-buffer buffer-name)
+          (goto-char (point-min))
+          (forward-line (1- (read (get-text-property 0 'swiper-line-number x))))
+          (re-search-forward
+           (ivy--regex ivy-text)
+           (line-end-position) t)
+          (isearch-range-invisible (line-beginning-position)
+                                   (line-end-position))
+          (unless (eq ivy-exit 'done)
+            (swiper--cleanup)
+            (swiper--add-overlays (ivy--regex ivy-text))))))))
+
+(defun swiper-all-buffer-p (buffer)
+  "Return non-nil if BUFFER should be considered by `swiper-all'."
+  (let ((mode (buffer-local-value 'major-mode (get-buffer buffer))))
+    (cond
+      ;; Ignore TAGS buffers, they tend to add duplicate results.
+      ((eq mode #'tags-table-mode) nil)
+      ;; Always consider dired buffers, even though they're not backed
+      ;; by a file.
+      ((eq mode #'dired-mode) t)
+      ;; Always consider stash buffers too, as they may have
+      ;; interesting content not present in any buffers. We don't #'
+      ;; quote to satisfy the byte-compiler.
+      ((eq mode 'magit-stash-mode) t)
+      ;; Email buffers have no file, but are useful to search
+      ((eq mode 'gnus-article-mode) t)
+      ;; Otherwise, only consider the file if it's backed by a file.
+      (t (buffer-file-name buffer)))))
+
+;;* `swiper-all'
+(defun swiper-all-function (str)
+  "Search in all open buffers for STR."
+  (if (and (< (length str) 3))
+      (list "" (format "%d chars more" (- 3 (length ivy-text))))
+    (let* ((buffers (cl-remove-if-not #'swiper-all-buffer-p (buffer-list)))
+           (re-full (funcall ivy--regex-function str))
+           re re-tail
+           cands match
+           (case-fold-search (ivy--case-fold-p str)))
+      (if (stringp re-full)
+          (setq re re-full)
+        (setq re (caar re-full))
+        (setq re-tail (cdr re-full)))
+      (dolist (buffer buffers)
+        (with-current-buffer buffer
+          (save-excursion
+            (goto-char (point-min))
+            (while (re-search-forward re nil t)
+              (setq match (if (memq major-mode '(org-mode dired-mode))
+                              (buffer-substring-no-properties
+                               (line-beginning-position)
+                               (line-end-position))
+                            (buffer-substring
+                             (line-beginning-position)
+                             (line-end-position))))
+              (put-text-property
+               0 1 'buffer
+               (buffer-name)
+               match)
+              (put-text-property 0 1 'point (point) match)
+              (when (or (null re-tail) (ivy-re-match re-tail match))
+                (push match cands))))))
+      (setq ivy--old-re re-full)
+      (if (null cands)
+          (list "")
+        (setq ivy--old-cands (nreverse cands))))))
+
+(defvar swiper-window-width 80)
+
+(defun swiper--all-format-function (cands)
+  "Format CANDS for `swiper-all'.
+See `ivy-format-function' for further information."
+  (let* ((ww swiper-window-width)
+         (col2 1)
+         (cands-with-buffer
+          (mapcar (lambda (s)
+                    (let ((buffer (get-text-property 0 'buffer s)))
+                      (setq col2 (max col2 (length buffer)))
+                      (cons s buffer))) cands))
+         (col1 (- ww 4 col2)))
+    (setq cands
+          (mapcar (lambda (x)
+                    (if (cdr x)
+                        (let ((s (ivy--truncate-string (car x) col1)))
+                          (concat
+                           s
+                           (make-string
+                            (max 0
+                                 (- ww (string-width s) (length (cdr x))))
+                            ?\ )
+                           (cdr x)))
+                      (car x)))
+                  cands-with-buffer))
+    (ivy--format-function-generic
+     (lambda (str)
+       (ivy--add-face str 'ivy-current-match))
+     (lambda (str)
+       str)
+     cands
+     "\n")))
+
+(defvar swiper-all-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "M-q") 'swiper-all-query-replace)
+    map)
+  "Keymap for `swiper-all'.")
+
+;;;###autoload
+(defun swiper-all (&optional initial-input)
+  "Run `swiper' for all open buffers."
+  (interactive)
+  (let* ((swiper-window-width (- (frame-width) (if (display-graphic-p) 0 1)))
+         (ivy-format-function #'swiper--all-format-function))
+    (ivy-read "swiper-all: " 'swiper-all-function
+              :action 'swiper-all-action
+              :unwind #'swiper--cleanup
+              :update-fn (lambda ()
+                           (swiper-all-action (ivy-state-current ivy-last)))
+              :dynamic-collection t
+              :keymap swiper-all-map
+              :initial-input initial-input
+              :caller 'swiper-multi)))
+
+(defun swiper-all-action (x)
+  "Move to candidate X from `swiper-all'."
+  (when (> (length x) 0)
+    (let ((buffer-name (get-text-property 0 'buffer x)))
+      (when buffer-name
+        (with-ivy-window
+          (switch-to-buffer buffer-name)
+          (goto-char (get-text-property 0 'point x))
+          (isearch-range-invisible (line-beginning-position)
+                                   (line-end-position))
+          (unless (eq ivy-exit 'done)
+            (swiper--cleanup)
+            (swiper--add-overlays (ivy--regex ivy-text))))))))
+
+(defun swiper--multi-candidates (buffers)
+  "Extract candidates from BUFFERS."
+  (let* ((ww (window-width))
+         (res nil)
+         (column-2 (apply #'max
+                          (mapcar
+                           (lambda (b)
+                             (length (buffer-name b)))
+                           buffers)))
+         (column-1 (- ww 4 column-2 1)))
+    (dolist (buf buffers)
+      (with-current-buffer buf
+        (setq res
+              (append
+               (mapcar
+                (lambda (s)
+                  (setq s (concat (ivy--truncate-string s column-1) " "))
+                  (let ((len (length s)))
+                    (put-text-property
+                     (1- len) len 'display
+                     (concat
+                      (make-string
+                       (max 0
+                            (- ww (string-width s) (length (buffer-name)) 3))
+                       ?\ )
+                      (buffer-name))
+                     s)
+                    (put-text-property 0 len 'buffer buf s)
+                    s))
+                (swiper--candidates 4))
+               res))
+        nil))
+    res))
+
+(provide 'swiper)
+
+;;; swiper.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/swiper-20180713.946/swiper.elc b/configs/shared/emacs/.emacs.d/elpa/swiper-20180713.946/swiper.elc
new file mode 100644
index 0000000000..c3fe584d94
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/swiper-20180713.946/swiper.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/tablist-20170219.1935/tablist-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/tablist-20170219.1935/tablist-autoloads.el
new file mode 100644
index 0000000000..794ac3e0ba
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/tablist-20170219.1935/tablist-autoloads.el
@@ -0,0 +1,36 @@
+;;; tablist-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "tablist" "tablist.el" (23377 61611 767748
+;;;;;;  290000))
+;;; Generated autoloads from tablist.el
+
+(autoload 'tablist-minor-mode "tablist" "\
+Toggle Tablist minor mode on or off.
+With a prefix argument ARG, enable Tablist minor mode if ARG is
+positive, and disable it otherwise.  If called from Lisp, enable
+the mode if ARG is omitted or nil, and toggle it if ARG is `toggle'.
+\\{tablist-minor-mode-map}
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'tablist-mode "tablist" "\
+
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads nil nil ("tablist-filter.el" "tablist-pkg.el")
+;;;;;;  (23377 61611 766418 540000))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; tablist-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/tablist-20170219.1935/tablist-filter.el b/configs/shared/emacs/.emacs.d/elpa/tablist-20170219.1935/tablist-filter.el
new file mode 100644
index 0000000000..0ea7e2c713
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/tablist-20170219.1935/tablist-filter.el
@@ -0,0 +1,448 @@
+;;; tablist-filter.el --- Filter expressions for tablists.  -*- lexical-binding:t -*-
+
+;; Copyright (C) 2013, 2014  Andreas Politz
+
+;; Author: Andreas Politz <politza@fh-trier.de>
+;; Keywords: extensions, lisp
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+(defvar python-mode-hook)
+(let (python-mode-hook)                 ;FIXME: Why?
+(require 'semantic/wisent/comp)
+(require 'semantic/wisent/wisent))
+
+;;; Code:
+
+(defvar wisent-eoi-term)
+(declare-function wisent-parse "semantic/wisent/wisent.el")
+
+(defvar tablist-filter-binary-operator
+  '((== . tablist-filter-op-equal)
+    (=~ . tablist-filter-op-regexp)
+    (< . tablist-filter-op-<)
+    (> . tablist-filter-op->)
+    (<= . tablist-filter-op-<=)
+    (>= . tablist-filter-op->=)
+    (= . tablist-filter-op-=)))
+
+(defvar tablist-filter-unary-operator nil)
+
+(defvar tablist-filter-wisent-parser nil)
+
+(defvar tablist-filter-lexer-regexps nil)
+
+(defvar tablist-filter-wisent-grammar
+  '(
+    ;; terminals
+    ;; Use lowercase for better looking error messages.
+    (operand unary-operator binary-operator or and not)
+
+    ;; terminal associativity & precedence
+    ((left binary-operator)
+     (left unary-operator)
+     (left or)
+     (left and)
+     (left not))
+
+    ;; rules
+    (filter-or-empty
+     ((nil))
+     ((?\( ?\)) nil)
+     ((filter) $1))
+    (filter
+     ((operand) $1) ;;Named filter
+     ((operand binary-operator operand) `(,(intern $2) ,$1 ,$3))
+     ((unary-operator operand) `(,(intern $1) ,$2))
+     ((not filter) `(not ,$2))
+     ((filter and filter) `(and ,$1 ,$3))
+     ((filter or filter) `(or ,$1 ,$3))
+     ((?( filter ?)) $2))))
+
+(defun tablist-filter-parser-init (&optional reinitialize interactive)
+  (interactive (list t t))
+  (unless (and tablist-filter-lexer-regexps
+               (not reinitialize))
+    (let ((re (mapcar
+               (lambda (l)
+                 (let ((re (regexp-opt
+                            (mapcar 'symbol-name
+                                    (mapcar 'car l)) t)))
+                   (if (= (length re) 0)
+                       ".\\`" ;;matches nothing
+                     re)))
+               (list tablist-filter-binary-operator
+                     tablist-filter-unary-operator))))
+      (setq tablist-filter-lexer-regexps
+            (nreverse
+             (cons (concat "\\(?:" (car re) "\\|" (cadr re)
+                           "\\|[ \t\f\r\n\"!()]\\|&&\\|||\\)")
+                   re)))))
+  (unless (and tablist-filter-wisent-parser
+               (not reinitialize))
+    (let ((wisent-compile-grammar*
+           (symbol-function
+            'wisent-compile-grammar)))
+      (setq tablist-filter-wisent-parser
+            ;; Trick the byte-compile into not using the byte-compile
+            ;; handler in semantic/wisent/comp.el, since it does not
+            ;; always work (wisent-context-compile-grammar n/a).
+            (funcall wisent-compile-grammar*
+                     tablist-filter-wisent-grammar))))
+  (when interactive
+    (message "Parser reinitialized."))
+  nil)
+
+(defun tablist-filter-wisent-lexer ()
+  (cl-destructuring-bind (unary-op binary-op keywords)
+      tablist-filter-lexer-regexps
+    (skip-chars-forward " \t\f\r\n")
+    (cond
+     ((eobp) (list wisent-eoi-term))
+     ((= ?\" (char-after))
+      `(operand , (condition-case err
+                    (read (current-buffer))
+                  (error (signal (car err) (cons
+                                            "invalid lisp string"
+                                            (cdr err)))))))
+     ((looking-at unary-op)
+      (goto-char (match-end 0))
+      `(unary-operator ,(match-string-no-properties 0)))
+     ((looking-at binary-op)
+      (goto-char (match-end 0))
+      `(binary-operator ,(match-string-no-properties 0)))
+     ((looking-at "&&")
+      (forward-char 2)
+      `(and "&&"))
+     ((looking-at "||")
+      (forward-char 2)
+      `(or "||"))
+     ((= ?! (char-after))
+      (forward-char)
+      `(not "!"))
+     ((= ?\( (char-after))
+      (forward-char)
+      `(?\( "("))
+     ((= ?\) (char-after))
+      (forward-char)
+      `(?\) ")"))
+     (t
+      (let ((beg (point)))
+        (when (re-search-forward keywords nil 'move)
+          (goto-char (match-beginning 0)))
+        `(operand ,(buffer-substring-no-properties
+                  beg
+                  (point))))))))
+
+(defun tablist-filter-parse (filter)
+  (interactive "sFilter: ")
+  (tablist-filter-parser-init)
+  (with-temp-buffer
+    (save-excursion (insert filter))
+    (condition-case error
+        (wisent-parse tablist-filter-wisent-parser
+                      'tablist-filter-wisent-lexer
+                      (lambda (msg)
+                        (signal 'error
+                                (replace-regexp-in-string
+                                 "\\$EOI" "end of input"
+                                 msg t t))))
+      (error
+       (signal 'error
+               (append (if (consp (cdr error))
+                           (cdr error)
+                         (list (cdr error)))
+                       (list (point))))))))
+
+(defun tablist-filter-unparse (filter &optional noerror)
+  (cl-labels
+    ((unparse (filter &optional noerror)
+       (cond
+        ((stringp filter)
+         (if (or (string-match (nth 2 tablist-filter-lexer-regexps)
+                               filter)
+                 (= 0 (length filter)))
+             (format "%S" filter)
+           filter))
+        ((and (eq (car-safe filter) 'not)
+              (= (length filter) 2))
+         (let ((paren (memq (car-safe (nth 1 filter)) '(or and))))
+           (format "!%s%s%s"
+                   (if paren "(" "")
+                   (unparse (cadr filter) noerror)
+                   (if paren ")" ""))))
+        ((and (memq (car-safe filter) '(and or))
+              (= (length filter) 3))
+         (let ((lparen (and (eq (car filter) 'and)
+                            (eq 'or (car-safe (car-safe (cdr filter))))))
+               (rparen (and (eq (car filter) 'and)
+                            (eq 'or (car-safe (car-safe (cddr filter)))))))
+           (format "%s%s%s %s %s%s%s"
+                   (if lparen "(" "")
+                   (unparse (cadr filter) noerror)
+                   (if lparen ")" "")
+                   (cl-case (car filter)
+                     (and "&&") (or "||"))
+                   (if rparen "(" "")
+                   (unparse (car (cddr filter)) noerror)
+                   (if rparen ")" ""))))
+        ((and (assq (car-safe filter) tablist-filter-binary-operator)
+              (= (length filter) 3))
+         (format "%s %s %s"
+                 (unparse (cadr filter) noerror)
+                 (car filter)
+                 (unparse (car (cddr filter)) noerror)))
+        ((and (assq (car-safe filter) tablist-filter-unary-operator)
+              (= (length filter) 2))
+         (format "%s %s"
+                 (car filter)
+                 (unparse (cadr filter) noerror)))
+        ((not filter) "")
+        (t (funcall (if noerror 'format 'error)
+                    "Invalid filter: %s" filter)))))
+    (tablist-filter-parser-init)
+    (unparse filter noerror)))
+
+(defun tablist-filter-eval (filter id entry &optional named-alist)
+  (cl-labels
+    ((feval (filter)
+       (pcase filter
+         (`(not . ,(and operand (guard (not (cdr operand)))))
+          (not (feval (car operand))))
+         (`(and . ,(and operands (guard (= 2 (length operands)))))
+          (and
+           (feval (nth 0 operands))
+           (feval (nth 1 operands))))
+         (`(or . ,(and operands (guard (= 2 (length operands)))))
+          (or
+           (feval (nth 0 operands))
+           (feval (nth 1 operands))))
+         (`(,op . ,(and operands (guard (= (length operands) 1))))
+          (let ((fn (assq op tablist-filter-unary-operator)))
+            (unless fn
+              (error "Undefined unary operator: %s" op))
+            (funcall fn id entry (car operands))))
+         (`(,op . ,(and operands (guard (= (length operands) 2))))
+          (let ((fn (cdr (assq op tablist-filter-binary-operator))))
+            (unless fn
+              (error "Undefined binary operator: %s" op))
+            (funcall fn id entry (car operands)
+                     (cadr operands))))
+         ((guard (stringp filter))
+          (let ((fn (cdr (assoc filter named-alist))))
+            (unless fn
+              (error "Undefined named filter: %s" filter))
+            (if (functionp fn)
+                (funcall fn id entry))
+            (feval
+             (if (stringp fn) (tablist-filter-unparse fn) fn))))
+         (`nil t)
+         (_ (error "Invalid filter: %s" filter)))))
+    (feval filter)))
+
+(defun tablist-filter-get-item-by-name (entry col-name)
+  (let* ((col (cl-position col-name tabulated-list-format
+                           :key 'car
+                           :test
+                           (lambda (s1 s2)
+                             (eq t (compare-strings
+                                    s1 nil nil s2 nil nil t)))))
+         (item (and col (elt entry col))))
+    (unless col
+      (error "No such column: %s" col-name))
+    (if (consp item)                  ;(LABEL . PROPS)
+        (car item)
+      item)))
+
+(defun tablist-filter-op-equal (_id entry op1 op2)
+  "COLUMN == STRING : Matches if COLUMN's entry is equal to STRING."
+  (let ((item (tablist-filter-get-item-by-name entry op1)))
+    (string= item op2)))
+
+(defun tablist-filter-op-regexp (_id entry op1 op2)
+  "COLUMN =~ REGEXP : Matches if COLUMN's entry matches REGEXP."
+  (let ((item (tablist-filter-get-item-by-name entry op1)))
+    (string-match op2 item)))
+
+(defun tablist-filter-op-< (id entry op1 op2)
+  "COLUMN < NUMBER : Matches if COLUMN's entry is less than NUMBER."
+  (tablist-filter-op-numeric '< id entry op1 op2))
+
+(defun tablist-filter-op-> (id entry op1 op2)
+  "COLUMN > NUMBER : Matches if COLUMN's entry is greater than NUMBER."
+  (tablist-filter-op-numeric '> id entry op1 op2))
+
+(defun tablist-filter-op-<= (id entry op1 op2)
+  "COLUMN <= NUMBER : Matches if COLUMN's entry is less than or equal to NUMBER."
+  (tablist-filter-op-numeric '<= id entry op1 op2))
+
+(defun tablist-filter-op->= (id entry op1 op2)
+  "COLUMN >= NUMBER : Matches if COLUMN's entry is greater than or equal to NUMBER."
+  (tablist-filter-op-numeric '>= id entry op1 op2))
+
+(defun tablist-filter-op-= (id entry op1 op2)
+  "COLUMN = NUMBER : Matches if COLUMN's entry as a number is equal to NUMBER."
+  (tablist-filter-op-numeric '= id entry op1 op2))
+
+(defun tablist-filter-op-numeric (op _id entry op1 op2)
+  (let ((item (tablist-filter-get-item-by-name entry op1)))
+    (funcall op (string-to-number item)
+             (string-to-number op2))))
+
+(defun tablist-filter-help (&optional temporary)
+  (interactive)
+  (cl-labels
+    ((princ-op (op)
+       (princ (car op))
+       (princ (concat (make-string (max 0 (- 4 (length (symbol-name (car op)))))
+                                   ?\s)
+                      "- "
+                      (car (split-string
+                            (or (documentation (cdr op))
+                                (format "FIXME: Not documented: %s"
+                                        (cdr op)))
+                            "\n" t))
+                      "\n"))))
+    (with-temp-buffer-window
+     "*Help*"
+     (if temporary
+         '((lambda (buf alist)
+             (let ((win
+                    (or (display-buffer-reuse-window buf alist)
+                        (display-buffer-in-side-window buf alist))))
+               (fit-window-to-buffer win)
+               win))
+           (side . bottom)))
+     nil
+     (princ "Filter entries with the following operators.\n\n")
+     (princ "&&  - FILTER1 && FILTER2 : Locical and.\n")
+     (princ "||  - FILTER1 || FILTER2 : Locical or.\n")
+     (dolist (op tablist-filter-binary-operator)
+       (princ-op op))
+     (princ "!  - ! FILTER : Locical not.\n\n")
+     (dolist (op tablist-filter-unary-operator)
+       (princ-op op))
+     (princ "\"...\" may be used to quote names and values if necessary,
+and \(...\) to group expressions.")
+     (with-current-buffer standard-output
+       (help-mode)))))
+
+;;
+;; **Filter Functions
+;;
+
+;; filter ::= nil | named | fn | (OP OP1 [OP2])
+
+(defun tablist-filter-negate (filter)
+  "Return a filter not matching filter."
+  (cond
+   ((eq (car-safe filter) 'not)
+    (cadr filter))
+   (filter
+    (list 'not filter))))
+
+(defun tablist-filter-push (filter new-filter &optional or-p)
+  "Return a filter combining FILTER and NEW-FILTER.
+
+By default the filters are and'ed, unless OR-P is non-nil."
+  (if (or (null filter)
+          (null new-filter))
+      (or filter
+          new-filter)
+    (list (if or-p 'or 'and)
+          filter new-filter)))
+
+(defun tablist-filter-pop (filter)
+  "Remove the first operator or operand from filter.
+
+If filter starts with a negation, return filter unnegated,
+if filter starts with a dis- or conjuction, remove the first operand,
+if filter is nil, raise an error,
+else return nil."
+  (pcase filter
+    (`(,(or `and `or) . ,tail)
+     (car (cdr tail)))
+    (`(not . ,op1)
+     (car op1))
+    (_ (unless filter
+         (error "Filter is empty")))))
+
+(defun tablist-filter-map (fn filter)
+  (pcase filter
+    (`(,(or `and `or `not) . ,tail)
+     (cons (car filter)
+           (mapcar (lambda (f)
+                     (tablist-filter-map fn f))
+                   tail)))
+    (_ (funcall fn filter))))
+
+;;
+;; Reading filter
+;;
+
+(defvar tablist-filter-edit-history nil)
+(defvar tablist-filter-edit-display-help t)
+
+(defun tablist-filter-edit-filter (prompt &optional
+                                          initial-filter history
+                                          validate-fn)
+  (let* ((str (tablist-filter-unparse initial-filter))
+         (filter initial-filter)
+         (validate-fn (or validate-fn 'identity))
+         error done)
+    (save-window-excursion
+      (when tablist-filter-edit-display-help
+        (tablist-filter-help t))
+      (while (not done)
+        (minibuffer-with-setup-hook
+            (lambda ()
+              (when error
+                (when (car error)
+                  (goto-char (+ (field-beginning)
+                                (car error)))
+                  (skip-chars-backward " \t\n"))
+                (minibuffer-message "%s" (cdr error))
+                (setq error nil)))
+          (setq str (propertize
+                     (read-string prompt str
+                                  (or history 'tablist-filter-edit-history)))
+                done t))
+        (condition-case err
+            (progn
+              (setq filter (tablist-filter-parse str))
+              (funcall validate-fn filter))
+          (error
+           (setq done nil)
+           (setq error (cons (car-safe (cddr err)) nil))
+           (when (car error)
+             (setq str (with-temp-buffer
+                         (insert str)
+                         (goto-char (car error))
+                         (set-text-properties
+                          (progn
+                            (skip-chars-backward " \t\n")
+                            (backward-char)
+                            (point))
+                          (min (car error) (point-max))
+                          '(face error rear-nonsticky t))
+                         (buffer-string))))
+           (setcdr error (error-message-string err)))))
+      filter)))
+
+(provide 'tablist-filter)
+;;; tablist-filter.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/tablist-20170219.1935/tablist-filter.elc b/configs/shared/emacs/.emacs.d/elpa/tablist-20170219.1935/tablist-filter.elc
new file mode 100644
index 0000000000..e079d7b518
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/tablist-20170219.1935/tablist-filter.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/tablist-20170219.1935/tablist-pkg.el b/configs/shared/emacs/.emacs.d/elpa/tablist-20170219.1935/tablist-pkg.el
new file mode 100644
index 0000000000..178baddf96
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/tablist-20170219.1935/tablist-pkg.el
@@ -0,0 +1,7 @@
+(define-package "tablist" "20170219.1935" "Extended tabulated-list-mode"
+  '((emacs "24.3"))
+  :keywords
+  '("extensions" "lisp"))
+;; Local Variables:
+;; no-byte-compile: t
+;; End:
diff --git a/configs/shared/emacs/.emacs.d/elpa/tablist-20170219.1935/tablist.el b/configs/shared/emacs/.emacs.d/elpa/tablist-20170219.1935/tablist.el
new file mode 100644
index 0000000000..1fbfb31352
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/tablist-20170219.1935/tablist.el
@@ -0,0 +1,1941 @@
+;;; tablist.el --- Extended tabulated-list-mode -*- lexical-binding: t -*-
+
+;; Copyright (C) 2013, 2014  Andreas Politz
+
+;; Author: Andreas Politz <politza@fh-trier.de>
+;; Keywords: extensions, lisp
+;; Package: tablist
+;; Version: 0.70
+;; Package-Requires: ((emacs "24.3"))
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;
+;; This package adds marks and filters to tabulated-list-mode.  It
+;; also kind of puts a dired face on tabulated list buffers.
+;;
+;; It can be used by deriving from tablist-mode and some features by
+;; using tablist-minor-mode inside a tabulated-list-mode buffer.
+;;
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'ring)
+(require 'tabulated-list)
+(require 'dired)
+(require 'tablist-filter)
+
+;;
+;; *Macros
+;;
+
+(defmacro tablist-save-marks (&rest body)
+  "Eval body, while preserving all marks."
+  (let ((marks (make-symbol "marks")))
+    `(let (,marks)
+       (save-excursion
+         (goto-char (point-min))
+         (let ((re "^\\([^ ]\\)"))
+           (while (re-search-forward re nil t)
+             (push (cons (tabulated-list-get-id)
+                         (tablist-get-mark-state))
+                   ,marks))))
+       (unwind-protect
+           (progn ,@body)
+         (save-excursion
+           (dolist (m ,marks)
+             (let ((id (pop m)))
+               (goto-char (point-min))
+               (while (and id (not (eobp)))
+                 (when (equal id (tabulated-list-get-id))
+                   (tablist-put-mark-state m)
+                   (setq id nil))
+                 (forward-line)))))))))
+
+(defmacro tablist-with-remembering-entry (&rest body)
+  "Remember where body left of and restore previous position.
+
+If the current entry is still visible, move to it. Otherwise move
+to the next visible one after it.  If that also fails, goto to
+the beginning of the buffer.  Finally move point to the major
+column."
+  (declare (indent 0) (debug t))
+  (let ((re (make-symbol "re"))
+        (id (make-symbol "id"))
+        (col (make-symbol "col")))
+    `(let ((,re
+            (replace-regexp-in-string
+             "[\t ]+" "[\t ]*" (regexp-quote
+                                (or (thing-at-point 'line) ""))
+             t t))
+           (,id (tabulated-list-get-id))
+           (,col (tablist-current-column)))
+       (progn
+         ,@body
+         (let (success pos)
+           (goto-char (point-min))
+           (setq pos (point))
+           (while (and (setq success (re-search-forward ,re nil t))
+                       (> (point) (prog1 pos (setq pos (point))))
+                       (forward-line -1)
+                       (not (equal ,id (tabulated-list-get-id))))
+             (forward-line))
+           (unless success
+             (goto-char (point-min))
+             (while (and (not (eobp))
+                         (not success))
+               (if (equal (tabulated-list-get-id) ,id)
+                   (setq success t)
+                 (forward-line))))
+           (unless (and success (not (invisible-p (point))))
+             (goto-char (point-min)))
+           (tablist-skip-invisible-entries)
+           (tablist-move-to-column
+            (or ,col (car (tablist-major-columns))))
+           (dolist (win (get-buffer-window-list))
+             (set-window-point win (point))))))))
+
+(defmacro tablist-with-filter-displayed (&rest body)
+  "Display the current filter in the mode while evalling BODY."
+  (let ((state (make-symbol "state")))
+    `(let ((,state (tablist-display-filter 'state)))
+       (tablist-display-filter t)
+       (unwind-protect
+           (progn ,@body)
+         (tablist-display-filter ,state)))))
+
+;;
+;; *Mode Maps
+;;
+
+(defvar tablist-mode-filter-map
+  (let ((kmap (make-sparse-keymap)))
+    (define-key kmap "p" 'tablist-pop-filter)
+    (define-key kmap "r" 'tablist-push-regexp-filter)
+    (define-key kmap "=" 'tablist-push-equal-filter)
+    (define-key kmap "n" 'tablist-push-numeric-filter)
+    (define-key kmap "!" 'tablist-negate-filter)
+    (define-key kmap "t" 'tablist-toggle-first-filter-logic)
+    (define-key kmap "/" 'tablist-display-filter)
+    (define-key kmap "z" 'tablist-suspend-filter)
+
+    (define-key kmap "a" 'tablist-push-named-filter)
+    (define-key kmap "s" 'tablist-name-current-filter)
+    (define-key kmap "D" 'tablist-delete-named-filter)
+    (define-key kmap "d" 'tablist-deconstruct-named-filter)
+    (define-key kmap "e" 'tablist-edit-filter)
+    (define-key kmap "C" 'tablist-clear-filter)
+    kmap))
+
+(defvar tablist-mode-mark-map
+  (let ((kmap (make-sparse-keymap)))
+    (define-key kmap "c" 'tablist-change-marks)
+    (define-key kmap "!" 'tablist-unmark-all-marks)
+    (define-key kmap "r" 'tablist-mark-items-regexp)
+    (define-key kmap "n" 'tablist-mark-items-numeric)
+    (define-key kmap "m" 'tablist-mark-forward)
+    kmap))
+
+(defvar tablist-mode-regexp-map
+  (let ((kmap (make-sparse-keymap)))
+    ;; (define-key kmap "&" 'tablist-flag-gargabe-items)
+    (define-key kmap "m" 'tablist-mark-items-regexp)
+    kmap))
+
+(defvar tablist-minor-mode-map
+  (let ((kmap (make-sparse-keymap)))
+    (define-key kmap "m" 'tablist-mark-forward)
+    (define-key kmap (kbd "DEL") 'tablist-unmark-backward)
+    (define-key kmap "k" 'tablist-do-kill-lines)
+    (define-key kmap "U" 'tablist-unmark-all-marks)
+    (define-key kmap "u" 'tablist-unmark-forward)
+    (define-key kmap "t" 'tablist-toggle-marks)
+
+    (define-key kmap (kbd "TAB") 'tablist-forward-column)
+    (define-key kmap "\t" 'tablist-forward-column)
+    (define-key kmap [backtab] 'tablist-backward-column)
+
+    (define-key kmap "%" tablist-mode-regexp-map)
+    (define-key kmap "*" tablist-mode-mark-map)
+    (define-key kmap "/" tablist-mode-filter-map)
+
+    ;; (define-key kmap "e" 'tablist-edit-column)
+    ;; (define-key kmap "i" 'tablist-insert-entry)
+    (define-key kmap "s" 'tablist-sort)
+    (define-key kmap [remap back-to-indentation] 'tablist-move-to-major-column)
+    (define-key kmap [remap next-line] 'tablist-next-line)
+    (define-key kmap [remap previous-line] 'tablist-previous-line)
+    (define-key kmap "<" 'tablist-shrink-column)
+    (define-key kmap ">" 'tablist-enlarge-column)
+    (define-key kmap "q" 'tablist-quit)
+    (define-key kmap "G" 'tablist-revert)
+    (define-key kmap (kbd "C-c C-e") 'tablist-export-csv)
+    kmap))
+
+(defvar tablist-mode-map
+  (let ((kmap (copy-keymap tablist-minor-mode-map)))
+    (set-keymap-parent kmap tabulated-list-mode-map)
+    (define-key kmap "d" 'tablist-flag-forward)
+    (define-key kmap (kbd "RET") 'tablist-find-entry)
+    (define-key kmap "f" 'tablist-find-entry)
+    ;; (define-key kmap "~" 'tablist-flag-gargabe-items)
+    (define-key kmap "D" 'tablist-do-delete)
+    (define-key kmap "C" 'tablist-do-copy)
+    (define-key kmap "R" 'tablist-do-rename)
+    (define-key kmap "x" 'tablist-do-flagged-delete)
+    ;; (define-key kmap "F" 'tablist-find-marked-items)
+    ;; (define-key kmap (kbd "C-o") 'tablist-display-item)
+    kmap))
+
+;;
+;; *Variables
+;;
+
+;; Marking
+(defvar tablist-umark-filtered-entries t)
+(defvar tablist-marker-char dired-marker-char
+  "The character used for marking.")
+(defvar tablist-marker-face 'dired-mark
+  "The face used for the mark character.")
+(defvar tablist-marked-face  'dired-marked
+  "The face used for marked major columns.")
+
+;; Operations
+(defvar-local tablist-operations-function nil
+  "A function for handling operations on the entries.
+
+The function is called with varying number of arguments, while
+the first one is always a symbol describing one of the following
+operations.
+
+`supported-operations'
+
+This is the only mandatory operation. There are no other
+arguments and the function should return a list of symbols of
+supported operations.
+
+`delete'
+
+The 2nd argument will be a list of entry ID's.  The function
+should somehow delete these entries and update
+`tabulated-list-entries'.
+
+`find-entry'
+
+The 2nd argument is the ID of an entry.  The function should
+somehow find/display this entry, i.e. a kind of default
+operation.
+
+`edit-column'
+
+The function is called with 3 further arguments: ID, INDEX and
+NEW-COLUMN, where ID represents the entry to edit, INDEX is the index
+of the column and NEW-COLUMN is the proposed new value for this
+column.  It should either
+
+i.  return a new edited complete entry and update
+`tabulated-list-entries', or
+
+ii. throw an error, if NEW-COLUMN is not a valid value for this
+column.
+
+`complete'
+
+The function is called with 4 further arguments: ID, INDEX,
+STRING and POS, where ID represents an entry, INDEX is the index
+of the column to complete, STRING it's current value and POS an
+offset of the current position of point into STRING.
+
+The function should return a collection for this column, suitable
+as argument for the function `completion-in-region'.")
+
+;; Differentiating columns
+(defvar-local tablist-major-columns nil
+  "Columns used to mark and when querying.")
+
+;; Filter
+(defvar-local tablist-current-filter nil)
+(defvar-local tablist-filter-suspended nil)
+(defvar tablist-named-filter nil)
+
+;; History variables
+(defvar tablist-column-name-history nil)
+
+;; Hooks
+(defvar tablist-selection-changed-functions nil
+  "A hook run when ever point moves to a different entry.")
+
+;; Context Window
+(defvar-local tablist-context-window nil)
+(defvar-local tablist-context-window-function nil)
+(defvar tablist-context-window-display-action
+  `((display-buffer-reuse-window
+     tablist-display-buffer-split-below-and-attach)
+    (window-height . 0.25)
+    (inhibit-same-window . t)))
+
+;;
+;; *Setup
+;;
+
+(defvar savehist-additional-variables)
+(add-hook 'savehist-save-hook
+          (lambda nil
+            (add-to-list 'savehist-additional-variables 'tablist-named-filter)))
+
+;;;###autoload
+(define-minor-mode tablist-minor-mode
+  nil nil nil nil
+  (unless (derived-mode-p 'tabulated-list-mode)
+    (error "Buffer is not in Tabulated List Mode"))
+  (tablist-init (not tablist-minor-mode)))
+
+;;;###autoload
+(define-derived-mode tablist-mode tabulated-list-mode "TL"
+  (tablist-init))
+
+(defun tablist-init (&optional disable)
+  (let ((cleaned-misc (cl-remove 'tablist-current-filter
+                                 mode-line-misc-info :key 'car)))
+    (cond
+     ((not disable)
+      (set (make-local-variable 'mode-line-misc-info)
+           (append
+            (list
+             (list 'tablist-current-filter
+                   '(:eval (format " [%s]"
+                                   (if tablist-filter-suspended
+                                       "suspended"
+                                     "filtered")))))))
+      (add-hook 'post-command-hook
+                'tablist-selection-changed-handler nil t)
+      (add-hook 'tablist-selection-changed-functions
+                'tablist-context-window-update nil t))
+     (t
+      (setq mode-line-misc-info cleaned-misc)
+      (remove-hook 'post-command-hook
+                   'tablist-selection-changed-handler t)
+      (remove-hook 'tablist-selection-changed-functions
+                   'tablist-context-window-update t)))))
+
+(defun tablist-quit ()
+  (interactive)
+  (tablist-hide-context-window)
+  (quit-window))
+
+(defvar-local tablist-selected-id nil)
+(defvar tablist-edit-column-minor-mode)
+
+(defun tablist-selection-changed-handler ()
+  (unless tablist-edit-column-minor-mode
+    (let ((id tablist-selected-id)
+          (selected (tabulated-list-get-id)))
+      (unless (eq selected id)
+        (setq tablist-selected-id selected)
+        (run-hook-with-args
+         'tablist-selection-changed-functions
+         tablist-selected-id)))))
+
+(defvar tablist-context-window-update--timer nil)
+
+(defun tablist-context-window-update (&optional id)
+  (when (and tablist-context-window-function
+             (window-live-p tablist-context-window)
+             (not tablist-edit-column-minor-mode))
+    (unless id
+      (setq id (tabulated-list-get-id)))
+    (when (timerp tablist-context-window-update--timer)
+      (cancel-timer tablist-context-window-update--timer))
+    (setq tablist-context-window-update--timer
+          (run-with-idle-timer 0.1 nil
+                               (lambda (fn window)
+                                 (when (window-live-p window)
+                                   (with-selected-window window
+                                     (set-window-dedicated-p nil nil)
+                                     (save-selected-window
+                                       (funcall fn id))
+                                     (when (window-live-p (selected-window))
+                                       (set-window-dedicated-p nil t)))))
+                               tablist-context-window-function
+                               tablist-context-window))))
+
+(defun tablist-display-context-window ()
+  (interactive)
+  (unless tablist-context-window-function
+    (error "No function for handling a context is defined"))
+  (unless (window-live-p tablist-context-window)
+    (setq tablist-context-window
+          (display-buffer
+           (current-buffer)
+           tablist-context-window-display-action)))
+  (prog1
+      tablist-context-window
+    (tablist-context-window-update)))
+
+(defun tablist-hide-context-window ()
+  (interactive)
+  (when (window-live-p tablist-context-window)
+    (let ((ignore-window-parameters t))
+      (delete-window tablist-context-window)))
+  (setq tablist-context-window nil))
+
+(defun tablist-toggle-context-window ()
+  (interactive)
+  (if (window-live-p tablist-context-window)
+      (tablist-hide-context-window)
+    (tablist-display-context-window)))
+
+;;
+;; *Marking
+;;
+
+(defun tablist-revert ()
+  "Revert the list with marks preserved, position kept."
+  (interactive)
+  (tablist-save-marks
+   (tablist-with-remembering-entry
+     (tabulated-list-revert))))
+
+(defun tablist-major-columns ()
+  (if (null tablist-major-columns)
+      (number-sequence 0 (1- (length tabulated-list-format)))
+    (if (numberp tablist-major-columns)
+        (list tablist-major-columns)
+      tablist-major-columns)))
+
+(defun tablist-put-mark (&optional pos)
+  "Put a mark before the entry at POS.
+
+POS defaults to point. Use `tablist-marker-char',
+`tablist-marker-face', `tablist-marked-face' and
+`tablist-major-columns' to determine how to mark and what to put
+a face on."
+  (when (or (null tabulated-list-padding)
+            (< tabulated-list-padding 1))
+    (setq tabulated-list-padding 1)
+    (tabulated-list-revert))
+  (save-excursion
+    (and pos (goto-char pos))
+    (unless (tabulated-list-get-id)
+      (error "No entry at this position"))
+    (let ((inhibit-read-only t))
+      (tabulated-list-put-tag
+       (string tablist-marker-char))
+      (put-text-property
+       (point-at-bol)
+       (1+ (point-at-bol))
+       'face tablist-marker-face)
+      (let ((columns (tablist-column-offsets)))
+        (dolist (c (tablist-major-columns))
+          (when (and (>= c 0)
+                     (< c (length columns)))
+            (let ((beg (+ (point-at-bol)
+                          (nth c columns)))
+                  (end (if (= c (1- (length columns)))
+                           (point-at-eol)
+                         (+ (point-at-bol)
+                            (nth (1+ c) columns)))))
+              (cond
+               ((and tablist-marked-face
+                     (not (eq tablist-marker-char ?\s)))
+                (tablist--save-face-property beg end)
+                (put-text-property
+                 beg end 'face tablist-marked-face))
+               (t (tablist--restore-face-property beg end))))))))))
+
+(defun tablist-mark-forward (&optional arg interactive)
+  "Mark ARG entries forward.
+
+ARG is interpreted as a prefix-arg.  If interactive is non-nil,
+maybe use the active region instead of ARG.
+
+See `tablist-put-mark' for how entries are marked."
+  (interactive (list current-prefix-arg t))
+  (cond
+   ;; Mark files in the active region.
+   ((and interactive (use-region-p))
+    (save-excursion
+      (goto-char (region-beginning))
+      (beginning-of-line)
+      (tablist-repeat-over-lines
+       (1+ (count-lines
+            (point)
+            (save-excursion
+              (goto-char (region-end))
+              (beginning-of-line)
+              (point))))
+       'tablist-put-mark)))
+   ;; Mark the current (or next ARG) files.
+   (t
+    (tablist-repeat-over-lines
+     (prefix-numeric-value arg)
+     'tablist-put-mark))))
+
+(defun tablist-mark-backward (&optional arg interactive)
+  "Mark ARG entries backward.
+
+See `tablist-mark-forward'."
+  (interactive (list current-prefix-arg t))
+  (tablist-mark-forward (- (prefix-numeric-value arg))
+                        interactive))
+
+(defun tablist-unmark-forward (&optional arg interactive)
+  "Unmark ARG entries forward.
+
+See `tablist-mark-forward'."
+  (interactive (list current-prefix-arg t))
+  (let ((tablist-marker-char ?\s)
+        tablist-marked-face)
+    (tablist-mark-forward arg interactive)))
+
+(defun tablist-unmark-backward (&optional arg interactive)
+  "Unmark ARG entries backward.
+
+See `tablist-mark-forward'."
+  (interactive (list current-prefix-arg t))
+  (let ((tablist-marker-char ?\s)
+        tablist-marked-face)
+    (tablist-mark-backward arg interactive)))
+
+(defun tablist-flag-forward (&optional arg interactive)
+  "Flag ARG entries forward.
+
+See `tablist-mark-forward'."
+  (interactive (list current-prefix-arg t))
+  (let ((tablist-marker-char ?D)
+        (tablist-marked-face 'dired-flagged))
+    (tablist-mark-forward arg interactive)))
+
+(defun tablist-change-marks (old new)
+  "Change all OLD marks to NEW marks.
+
+OLD and NEW are both characters used to mark files."
+  (interactive
+   (let* ((cursor-in-echo-area t)
+          (old (progn (message "Change (old mark): ") (read-char)))
+          (new (progn (message  "Change %c marks to (new mark): " old)
+                      (read-char))))
+     (list old new)))
+  (when (eq new ?\n)
+    (error "Mark character \\n is not allowed"))
+  (let ((default-mark-p (equal tablist-marker-char new))
+        (tablist-marker-char old))
+    (save-excursion
+      (tablist-map-over-marks
+       (lambda nil
+         (pcase new
+           (?D
+            (tablist-flag-forward 1))
+           (_
+            (let ((tablist-marker-char new)
+                  (tablist-marked-face
+                   (and default-mark-p
+                        tablist-marked-face)))
+              (tablist-put-mark)))))))))
+
+(defun tablist-unmark-all-marks (&optional marks interactive)
+  "Remove alls marks in MARKS.
+
+MARKS should be a string of mark characters to match and defaults
+to all marks.  Interactively, remove all marks, unless a prefix
+arg was given, in which case ask about which ones to remove.
+Give a message, if interactive is non-nil.
+
+Returns the number of unmarked marks."
+  (interactive
+   (list (if current-prefix-arg
+             (read-string "Remove marks: ")) t))
+  (let ((re (if marks
+                (tablist-marker-regexp marks)
+              "^[^ ]"))
+        (removed 0))
+    (save-excursion
+      (goto-char (point-min))
+      (while (re-search-forward re nil t)
+        (let ((tablist-marker-char ?\s)
+              tablist-marker-face
+              tablist-marked-face)
+          (tablist-put-mark))
+        (cl-incf removed)))
+    (when interactive
+      (message "Removed %d marks" removed))
+    removed))
+
+(defun tablist-toggle-marks ()
+  "Unmark all marked and mark all unmarked entries.
+
+See `tablist-put-mark'."
+  (interactive)
+  (let ((marked-re (tablist-marker-regexp))
+        (not-marked-re
+         (let ((tablist-marker-char ?\s))
+           (tablist-marker-regexp))))
+    (save-excursion
+      (goto-char (point-min))
+      (tablist-skip-invisible-entries)
+      (while (not (eobp))
+        (cond
+         ((looking-at marked-re)
+          (save-excursion (tablist-unmark-backward -1)))
+         ((looking-at not-marked-re)
+          (tablist-put-mark)))
+        (tablist-forward-entry)))
+    (tablist-move-to-major-column)))
+
+(defun tablist-get-marked-items (&optional arg distinguish-one-marked)
+  "Return marked or ARG entries."
+  (let ((items (save-excursion
+                 (tablist-map-over-marks
+                  (lambda () (cons (tabulated-list-get-id)
+                                   (tabulated-list-get-entry)))
+                  arg nil distinguish-one-marked))))
+    (if (and distinguish-one-marked
+             (eq (car items) t))
+        items
+      (nreverse items))))
+
+(defun tablist-mark-items-regexp (column-name regexp)
+  "Mark entries matching REGEXP in column COLUMN-NAME."
+  (interactive
+   (tablist-read-regexp-filter "Mark" current-prefix-arg ))
+  (tablist-map-with-filter
+   'tablist-put-mark
+   `(=~  ,column-name ,regexp)))
+
+(defun tablist-mark-items-numeric (binop column-name operand)
+  "Mark items fulfilling BINOP with arg OPERAND in column COLUMN-NAME.
+
+First the column's value is coerced to a number N.  Then the test
+proceeds as \(BINOP N OPERAND\)."
+  (interactive
+   (tablist-read-numeric-filter "Mark" current-prefix-arg))
+  (tablist-map-with-filter
+   'tablist-put-mark
+   `(,binop ,column-name ,operand)))
+
+(defun tablist-map-over-marks (fn &optional arg show-progress
+                                  distinguish-one-marked)
+  (prog1
+      (cond
+       ((and arg (integerp arg))
+        (let (results)
+          (tablist-repeat-over-lines
+           arg
+           (lambda ()
+             (if show-progress (sit-for 0))
+             (push (funcall fn) results)))
+          (if (< arg 0)
+              (nreverse results)
+            results)))
+       (arg
+        ;; non-nil, non-integer ARG means use current item:
+        (tablist-skip-invisible-entries)
+        (unless (eobp)
+          (list (funcall fn))))
+       (t
+        (cl-labels ((search (re)
+                            (let (sucess)
+                              (tablist-skip-invisible-entries)
+                              (while (and (setq sucess
+                                                (re-search-forward re nil t))
+                                          (invisible-p (point)))
+                                (tablist-forward-entry))
+                              sucess)))
+          (let ((regexp (tablist-marker-regexp))
+                next-position results found)
+            (save-excursion
+              (goto-char (point-min))
+              ;; remember position of next marked file before BODY
+              ;; can insert lines before the just found file,
+              ;; confusing us by finding the same marked file again
+              ;; and again and...
+              (setq next-position (and (search regexp)
+                                       (point-marker))
+                    found (not (null next-position)))
+              (while next-position
+                (goto-char next-position)
+                (if show-progress (sit-for 0))
+                (push (funcall fn) results)
+                ;; move after last match
+                (goto-char next-position)
+                (forward-line 1)
+                (set-marker next-position nil)
+                (setq next-position (and (search regexp)
+                                         (point-marker)))))
+            (if (and distinguish-one-marked (= (length results) 1))
+                (setq results (cons t results)))
+            (if found
+                results
+              (unless (or (eobp) (invisible-p (point)))
+                (list (funcall fn))))))))
+    (tablist-move-to-major-column)))
+
+(defun tablist-marker-regexp (&optional marks)
+  "Return a regexp matching marks in MARKS.
+
+MARKS should be a string of mark characters to match and defaults
+to the current value of `tablist-marker-char' as a string."
+  (concat (format "^[%s]"
+                  (or marks (string tablist-marker-char)))))
+
+(defun tablist-get-mark-state ()
+  "Return the mark state of the entry at point."
+  (save-excursion
+    (beginning-of-line)
+    (when (looking-at "^\\([^ ]\\)")
+      (let ((mark (buffer-substring
+                   (match-beginning 1)
+                   (match-end 1))))
+        (tablist-move-to-major-column)
+        (list (aref mark 0)
+              (get-text-property 0 'face mark)
+              (get-text-property (point) 'face))))))
+
+(defun tablist-put-mark-state (state)
+  "Set the mark of the entry at point according to STATE.
+
+STATE is a return value of `tablist-get-mark-state'."
+  (cl-destructuring-bind (tablist-marker-char
+                          tablist-marker-face
+                          tablist-marked-face)
+      state
+    (tablist-put-mark)))
+
+(defun tablist-mark-prompt (arg items)
+  "Return a string suitable for use in a tablist prompt."
+  ;; distinguish-one-marked can cause the first element to be just t.
+  (if (eq (car items) t) (setq items (cdr items)))
+  (let ((count (length items)))
+    (if (= count 1)
+        (car items)
+      ;; more than 1 item:
+      (if (integerp arg)
+          ;; abs(arg) = count
+          ;; Perhaps this is nicer, but it also takes more screen space:
+          ;;(format "[%s %d items]" (if (> arg 0) "next" "previous")
+          ;;                        count)
+          (format "[next %d item%s]"
+                  arg (dired-plural-s arg))
+        (format "%c [%d item%s]" dired-marker-char count
+                (dired-plural-s count))))))
+
+;;
+;; *Movement
+;;
+
+(defun tablist-forward-entry (&optional n)
+  "Move past the next N unfiltered entries."
+  (unless n (setq n 1))
+  (while (and (> n 0)
+              (not (eobp)))
+    (forward-line)
+    (when (invisible-p (point))
+      (tablist-skip-invisible-entries))
+    (cl-decf n))
+  (while (and (< n 0)
+              (not (bobp)))
+    (forward-line -1)
+    (when (invisible-p (point))
+      (tablist-skip-invisible-entries t))
+    (cl-incf n))
+  n)
+
+(defun tablist-next-line (&optional n)
+  (interactive "p")
+  (when (and (< n 0)
+             (save-excursion
+               (end-of-line 0)
+               (tablist-skip-invisible-entries t)
+               (bobp)))
+    (signal 'beginning-of-buffer nil))
+  (when (and (> n 0)
+             (save-excursion
+               (tablist-forward-entry)
+               (eobp)))
+    (signal 'end-of-buffer nil))
+
+  (let ((col (tablist-current-column)))
+    (tablist-forward-entry (or n 1))
+    (if col
+        (tablist-move-to-column col)
+      (tablist-move-to-major-column))))
+
+(defun tablist-previous-line (&optional n)
+  (interactive "p")
+  (tablist-next-line (- (or n 1))))
+
+(defun tablist-repeat-over-lines (arg function)
+  "Call FUNCTION for the next ARG entries."
+  ;; Move out of potentially invisble area.
+  (tablist-skip-invisible-entries)
+  (let ((pos (make-marker)))
+    (while (and (> arg 0)
+                (not (eobp)))
+      (cl-decf arg)
+      (save-excursion
+        (tablist-forward-entry)
+        (move-marker pos (1+ (point))))
+      (unless (eobp)
+        (save-excursion (funcall function)))
+      ;; Advance to the next line--actually, to the line that *was* next.
+      ;; (If FUNCTION inserted some new lines in between, skip them.)
+      (goto-char pos))
+    (while (and (< arg 0) (not (bobp)))
+      (cl-incf arg)
+      (tablist-forward-entry -1)
+      (save-excursion (funcall function)))
+    (move-marker pos nil)
+    (tablist-move-to-major-column)))
+
+(defun tablist-move-to-column (n)
+  "Move to the N'th list column."
+  (interactive "p")
+  (when (tabulated-list-get-id)
+    (let ((columns (tablist-column-offsets)))
+      (when (or (< n 0)
+                (>= n (length columns)))
+        (error "No such column: %s" n))
+      (beginning-of-line)
+      (forward-char (nth n columns))
+      (when (and (plist-get (nthcdr 3 (elt tabulated-list-format n))
+                            :right-align)
+                 (not (= n (1- (length columns)))))
+        (forward-char (1- (car (cdr (elt tabulated-list-format n)))))))))
+
+(defun tablist-move-to-major-column (&optional first-skip-invisible-p)
+  "Move to the first major column."
+  (interactive (list t))
+  (when first-skip-invisible-p
+    (tablist-skip-invisible-entries))
+  (tablist-move-to-column (car (tablist-major-columns))))
+
+(defun tablist-forward-column (n)
+  "Move n columns forward, while wrapping around."
+  (interactive "p")
+  (unless (tabulated-list-get-id)
+    (error "No entry on this line"))
+  (let* ((columns (tablist-column-offsets))
+         (current (1- (length columns))))
+    ;; find current column
+    (while (and (>= current 0)
+                (> (nth current columns)
+                   (current-column)))
+      (cl-decf current))
+    ;; there may be an invisible spec here
+    (when (bolp)
+      (forward-char))
+    ;; before any columns
+    (when (< current 0)
+      (goto-char (+ (point-at-bol) (if (> n 0)
+                                       (car columns)
+                                     (car (last columns)))))
+      (setq n (* (cl-signum n) (1- (abs n)))))
+    (when (/= n 0)
+      (tablist-move-to-column
+       (mod (+ current n) (length columns))))))
+
+(defun tablist-backward-column (n)
+  "Move n columns backward, while wrapping around."
+  (interactive "p")
+  (tablist-forward-column (- n)))
+
+;;
+(defun tablist-skip-invisible-entries (&optional backward)
+  "Skip invisible entries BACKWARD or forward.
+
+Do nothing, if the entry at point is visible.  Otherwise move to
+the beginning of the next visible entry in the direction
+determined by BACKWARD.
+
+Return t, if point is now in a visible area."
+
+  (cond
+   ((and backward
+         (not (bobp))
+         (get-text-property (point) 'invisible))
+    (when (get-text-property (1- (point)) 'invisible)
+      (goto-char (previous-single-property-change
+                  (point)
+                  'invisible nil (point-min))))
+    (forward-line -1))
+   ((and (not backward)
+         (not (eobp))
+         (get-text-property (point) 'invisible))
+    (goto-char (next-single-property-change
+                (point)
+                'invisible nil (point-max)))))
+  (not (invisible-p (point))))
+
+;;
+;; *Operations
+;;
+
+(defun tablist-yes-or-no-p (operation arg items)
+  "Query the user whether to proceed with some operation.
+
+Operation should be a symbol or string describing the operation,
+ARG the prefix-arg of the command used in
+`tablist-get-marked-items' or elsewhere, to get the ITEMS."
+
+  (let ((pp-items (mapcar 'tablist-pretty-print-entry
+                          (mapcar 'cdr items)))
+        dired-no-confirm
+        (op-str (upcase-initials
+                 (if (stringp operation)
+                     operation
+                   (symbol-name operation)))))
+    (dired-mark-pop-up
+     (format " *%s*" op-str) nil
+     pp-items
+     dired-deletion-confirmer
+     (format "%s %s "
+             op-str
+             (tablist-mark-prompt arg pp-items)))))
+
+(defun tablist-operation-available-p (op)
+  (and (functionp tablist-operations-function)
+       (memq op (funcall tablist-operations-function
+                         'supported-operations))))
+
+(defun tablist-do-delete (&optional arg)
+  "Delete ARG entries."
+  (interactive "P")
+  (unless (tablist-operation-available-p 'delete)
+    (error "Deleting entries is not available in this buffer"))
+  (let ((items (tablist-get-marked-items arg)))
+    (when (tablist-yes-or-no-p 'delete arg items)
+      (tablist-do-kill-lines arg)
+      (funcall tablist-operations-function
+               'delete (mapcar 'car items))
+      (tablist-move-to-major-column))))
+
+(defun tablist-do-flagged-delete (&optional interactive)
+  "Delete all entries marked with a D."
+  (interactive "p")
+  (let* ((tablist-marker-char ?D))
+    (if (save-excursion
+          (goto-char (point-min))
+          (re-search-forward (tablist-marker-regexp) nil t))
+        (tablist-do-delete)
+      (or (not interactive)
+          (message "(No deletions requested)")))))
+
+(defun tablist-do-kill-lines (&optional arg interactive)
+  "Remove ARG lines from the display."
+  (interactive (list current-prefix-arg t))
+  (save-excursion
+    (let ((positions
+           (tablist-map-over-marks 'point arg))
+          (inhibit-read-only t))
+      (dolist (pos positions)
+        (goto-char pos)
+        (tabulated-list-delete-entry))
+      (when interactive
+        (message (format "Killed %d line%s"
+                         (length positions)
+                         (dired-plural-s (length positions))))))))
+
+(defun tablist-do-operation (arg fn operation &optional delete-p revert-p)
+  "Operate on marked items.
+
+ARG should be the `current-prefix-arg', FN is a function of two
+arguments \(ID ENTRY\) handling the operation.  It gets called
+repeatly with all marked items.  OPERATION is a symbol or string
+describing the operation, it is used for display.
+
+Optional non-nil DELETE-P means, remove the items from the display.
+Optional REVERT-P means, revert the display afterwards."
+  (let ((items (tablist-get-marked-items arg)))
+    (unless items
+      (error "No items marked"))
+    (when (tablist-yes-or-no-p operation arg items)
+      (when delete-p
+        (tablist-do-kill-lines arg))
+      (dolist (item items)
+        (funcall fn (car item)))
+      (when revert-p
+        (tablist-revert))
+      (tablist-move-to-major-column))))
+
+;;
+;; *Editing
+;;
+(defvar tablist-edit-column-minor-mode-map
+  (let ((kmap (make-sparse-keymap)))
+    (set-keymap-parent kmap (current-global-map))
+    (define-key kmap [remap self-insert-command] 'self-insert-command)
+    (define-key kmap "\r" 'tablist-edit-column-commit)
+    (define-key kmap (kbd "C-g") 'tablist-edit-column-quit)
+    (define-key kmap (kbd "C-c C-c") 'tablist-edit-column-commit)
+    (define-key kmap (kbd "C-c C-q") 'tablist-edit-column-quit)
+    (define-key kmap "\t" 'tablist-edit-column-complete)
+    (define-key kmap (kbd "TAB") 'tablist-edit-column-complete)
+    (define-key kmap [remap end-of-buffer] 'end-of-line)
+    (define-key kmap [remap beginning-of-buffer] 'beginning-of-line)
+    (define-key kmap [remap mark-whole-buffer] 'tablist-edit-column-mark-field)
+    kmap))
+
+(define-minor-mode tablist-edit-column-minor-mode
+  "" nil nil nil
+  (unless (or tablist-minor-mode
+              (derived-mode-p 'tablist-mode))
+    (error "Not in a tablist buffer"))
+  (cond
+   (tablist-edit-column-minor-mode
+    (add-to-list 'mode-line-misc-info
+                 '(tablist-edit-column-minor-mode "[edit]"))
+    (add-hook 'post-command-hook 'tablist-edit-column-constrain-point nil t)
+    (read-only-mode -1))
+   (t
+    (remove-hook 'post-command-hook 'tablist-edit-column-constrain-point t)
+    (read-only-mode 1))))
+
+(defun tablist-edit-column (&optional n)
+  (interactive "P")
+  (unless n (setq n (tablist-current-column)))
+  (tablist-assert-column-editable n)
+  (let* ((offsets (append (tablist-column-offsets)
+                          (list (- (point-at-eol)
+                                   (point-at-bol)))))
+         (beg (+ (point-at-bol)
+                 (nth n offsets)))
+         (end (+ (point-at-bol)
+                 (nth (1+ n) offsets)))
+         (entry (tabulated-list-get-entry beg))
+         (inhibit-read-only t)
+         (inhibit-field-text-motion t)
+         (alist `((entry . ,entry)
+                  (column . ,n)
+                  (id . ,(tabulated-list-get-id beg))))
+         ov)
+    (goto-char beg)
+    (delete-region beg end)
+    (add-text-properties
+     (point-at-bol) (point-at-eol)
+     '(read-only t field t))
+    (unless (= beg (point-at-bol))
+      (put-text-property (1- beg) beg 'rear-nonsticky t))
+    (save-excursion
+      ;; Keep one read-only space at the end for keeping text
+      ;; properties.
+      (insert
+       (propertize
+        (concat
+         (tablist-nth-entry n entry)
+         (propertize " "
+                     'display `(space :align-to ,(- end (point-at-bol)))))
+        'field nil
+        'front-sticky '(tablist-edit)
+        'rear-nonsticky '(read-only field)
+        'tablist-edit alist))
+      (setq end (point)))
+    (add-text-properties
+     (1- end) end '(read-only t field 'tablist-edit-end))
+    (setq ov (make-overlay beg end))
+    (overlay-put ov 'priority 9999)
+    (overlay-put ov 'face '(:background "deep sky blue" :foreground "white"))
+    (overlay-put ov 'evaporate t)
+    (overlay-put ov 'tablist-edit t)
+    (tablist-edit-column-minor-mode 1)))
+
+(defun tablist-edit-column-quit ()
+  (interactive)
+  (tablist-edit-column-commit t))
+
+(defun tablist-edit-column-commit (&optional abandon-edit)
+  (interactive (list current-prefix-arg))
+  (let ((inhibit-read-only t)
+        (inhibit-field-text-motion t)
+        bounds)
+    (condition-case nil
+        (setq bounds (tablist-edit-column-bounds))
+      (error
+       (tablist-edit-column-minor-mode -1)
+       (tabulated-list-revert)
+       (put-text-property (point-min) (point-max)
+                          'tablist-edit nil)
+       (error "Unable to complete the edit")))
+    (let* ((beg (car bounds))
+           (end (cdr bounds))
+           (alist (get-text-property beg 'tablist-edit))
+           (column (cdr (assq 'column alist)))
+           (id (cdr (assq 'id alist)))
+           (entry (cdr (assq 'entry alist)))
+           (item (buffer-substring-no-properties beg (1- end))))
+
+      (unless abandon-edit
+        ;; Throws an error, if item is invalid.
+        (setq entry (funcall tablist-operations-function
+                             'edit-column id column item)))
+      (tablist-edit-column-minor-mode -1)
+      (remove-overlays beg end 'tablist-edit t)
+      (put-text-property beg end 'tablist-edit nil)
+      (delete-region (point-at-bol) (1+ (point-at-eol)))
+      (save-excursion
+        (tabulated-list-print-entry id entry))
+      (forward-char (nth column (tablist-column-offsets))))))
+
+(defun tablist-edit-column-complete ()
+  (interactive)
+  (unless (tablist-operation-available-p 'complete)
+    (error "Completion not available"))
+  (cl-destructuring-bind (beg &rest end)
+      (tablist-edit-column-bounds t)
+    (let* ((string (buffer-substring-no-properties
+                    beg end))
+           (alist (get-text-property beg 'tablist-edit))
+           (completions (funcall tablist-operations-function
+                                 'complete
+                                 (cdr (assq 'id alist))
+                                 (cdr (assq 'column alist))
+                                 string
+                                 (- (point) beg))))
+      (unless completions
+        (error "No completions available"))
+      (completion-in-region beg end completions))))
+
+(defun tablist-column-editable (n)
+  (and (tablist-operation-available-p 'edit-column)
+       (not (tablist-column-property n :read-only))))
+
+(defun tablist-assert-column-editable (n)
+  (unless (and (>= n 0)
+               (< n (length tabulated-list-format)))
+    (error "Invalid column number: %s" n))
+  (unless (tablist-operation-available-p 'edit-column)
+    (error "Editing columns not enabled in this buffer"))
+  (when (tablist-column-property n :read-only)
+    (error "This column is read-only")))
+
+(defun tablist-edit-column-constrain-point ()
+  (unless tablist-edit-column-minor-mode
+    (error "Not editing a column"))
+  (unless (get-text-property (point) 'tablist-edit)
+    (let ((bounds (tablist-edit-column-bounds)))
+      (when bounds
+        (if (> (point) (cdr bounds))
+            (goto-char (1- (cdr bounds)))
+          (goto-char (car bounds)))
+        (point)))))
+
+(defun tablist-edit-column-bounds (&optional skip-final-space)
+  (unless tablist-edit-column-minor-mode
+    (error "Not editing a column"))
+  (let ((pos (next-single-property-change
+              (point) 'tablist-edit))
+        beg end)
+    (cond
+     ((null pos)
+      (setq end (previous-single-property-change
+                 (point-max) 'tablist-edit)
+            beg (previous-single-property-change
+                 end 'tablist-edit)))
+     ((get-text-property pos 'tablist-edit)
+      (setq beg pos
+            end (next-single-property-change
+                 pos 'tablist-edit)))
+     (pos
+      (setq end pos
+            beg (previous-single-property-change
+                 pos 'tablist-edit))))
+
+    (unless (and beg end (get-text-property beg 'tablist-edit))
+      (error "Unable to locate edited text"))
+    (cons beg (if skip-final-space (1- end) end))))
+
+(defun tablist-edit-column-mark-field ()
+  (interactive)
+  (push-mark (field-beginning))
+  (push-mark (field-end) nil t)
+  (goto-char (field-beginning)))
+
+(defun tablist-find-entry (&optional id)
+  (interactive)
+  (unless (tablist-operation-available-p 'find-entry)
+    (error "Finding entries not supported in this buffer"))
+  (funcall tablist-operations-function
+           'find-entry
+           (or id (tabulated-list-get-id))))
+
+;;
+;; *Utility
+;;
+
+(defun tablist-column-property (n prop)
+  (plist-get
+   (nthcdr 3 (aref tabulated-list-format n))
+   prop))
+
+(defun tablist-current-column ()
+  "Return the column number at point.
+
+Returns nil, if point is before the first column."
+  (let ((column
+         (1- (cl-position
+              (current-column)
+              (append (tablist-column-offsets)
+                      (list most-positive-fixnum))
+              :test (lambda (column offset) (> offset column))))))
+    (when (>= column 0)
+      column)))
+
+(defun tablist-column-offsets ()
+  "Return a list of column positions.
+
+This is a list of offsets from the beginning of the line."
+  (let ((cc tabulated-list-padding)
+        columns)
+    (dotimes (i (length tabulated-list-format))
+      (let* ((c (aref tabulated-list-format i))
+             (len (nth 1 c))
+             (pad (or (plist-get (nthcdr 3 c) :pad-right)
+                      1)))
+        (push cc columns)
+        (when (numberp len)
+          (cl-incf cc len))
+        (when pad
+          (cl-incf cc pad))))
+    (nreverse columns)))
+
+(defun tablist-pretty-print-entry (item)
+  (mapconcat (lambda (i)
+               (tablist-nth-entry i item))
+             (tablist-major-columns) " "))
+
+(defun tablist--save-face-property (beg end)
+  ;; We need to distinguish ,,not set'' from ''no face''.
+  (unless (and (text-property-not-all beg end 'face nil)
+               (< beg end))
+    (put-text-property beg (1+ beg) 'face 'default))
+  (unless (text-property-not-all beg end 'tablist-saved-face nil)
+    (tablist-copy-text-property beg end 'face 'tablist-saved-face)))
+
+(defun tablist--restore-face-property (beg end)
+  (when (text-property-not-all beg end 'tablist-saved-face nil)
+    (tablist-copy-text-property beg end 'tablist-saved-face 'face)))
+
+(defun tablist-copy-text-property (beg end from to)
+  "Copy text property FROM to TO in region BEG to END."
+  (let ((inhibit-read-only t))
+    (save-excursion
+      (while (< beg end)
+        (goto-char beg)
+        (put-text-property
+         (point)
+         (setq beg (next-single-property-change
+                    (point) from nil end))
+         to
+         (get-text-property (point) from))))))
+
+;;
+(defun tablist-read-column-name (arg &optional prompt default)
+  "Read the name of a column using ARG.
+
+If ARG is a number, return column ARG.
+If ARG is nil, return DEFAULT or the current column.
+Else ask the user, using PROMPT and DEFAULT."
+  (cond
+   ((numberp arg)
+    (or (tablist-column-name
+         (prefix-numeric-value arg))
+        (error "No such column: %d" (prefix-numeric-value arg))))
+   ((null arg)
+    (or default
+        (tablist-column-name
+         (or (tablist-current-column)
+             (car (tablist-major-columns))
+             0))))
+   (t
+    (let* ((default (or default
+                        (tablist-column-name
+                         (car (tablist-major-columns)))))
+           (result
+            (completing-read
+             (format "%s %s: "
+                     (or prompt "Use column")
+                     (if default
+                         (format "(default %s)"
+                                 default)
+                       ""))
+             (tablist-column-names)
+             nil t nil 'tablist-column-name-history)))
+      (if (> (length result) 0)
+          result
+        (if (not default)
+            (error "No column selected")
+          default))))))
+
+(defun tablist-column-name (n)
+  "Return the name of column N."
+  (when (and n
+             (>= n 0)
+             (< n (length tabulated-list-format)))
+    (substring-no-properties
+     (car (elt tabulated-list-format n)) 0)))
+
+(defun tablist-column-names ()
+  "Return a list of all column-names."
+  (mapcar 'tablist-column-name
+          (number-sequence 0 (1- (length tabulated-list-format)))))
+
+(defun tablist-nth-entry (n &optional entry)
+  (unless entry (setq entry (tabulated-list-get-entry)))
+  (when (and entry
+             (>= n 0)
+             (< n (length entry)))
+    (let ((str (elt entry n)))
+      (if (stringp str)
+          str
+        (car str)))))
+
+(defun tablist-major-column-name ()
+  "Return a list of the major column names."
+  (tablist-column-name (car (tablist-major-columns))))
+
+(defun tablist-export-csv (&optional separator always-quote-p
+                                     invisible-p out-buffer display-p)
+  "Export a tabulated list to a CSV format.
+
+Use SEPARATOR (or ;) and quote if necessary (or always if
+ALWAYS-QUOTE-P is non-nil).  Only consider non-filtered entries,
+unless invisible-p is non-nil.  Create a buffer for the output or
+insert it after point in OUT-BUFFER.  Finally if DISPLAY-P is
+non-nil, display this buffer.
+
+Return the output buffer."
+
+  (interactive (list nil t nil nil t))
+  (unless (derived-mode-p 'tabulated-list-mode)
+    (error "Not in Tabulated List Mode"))
+  (unless (stringp separator)
+    (setq separator (string (or separator ?\;))))
+  (let* ((outb (or out-buffer
+                   (get-buffer-create
+                    (format "%s.csv" (buffer-name)))))
+         (escape-re (format "[%s\"\n]" separator))
+         (header (tablist-column-names)))
+    (unless (buffer-live-p outb)
+      (error "Expected a live buffer: %s" outb))
+    (cl-labels
+        ((printit (entry)
+                  (insert
+                   (mapconcat
+                    (lambda (e)
+                      (unless (stringp e)
+                        (setq e (car e)))
+                      (if (or always-quote-p
+                              (string-match escape-re e))
+                          (concat "\""
+                                  (replace-regexp-in-string "\"" "\"\"" e t t)
+                                  "\"")
+                        e))
+                    entry separator))
+                  (insert ?\n)))
+      (with-current-buffer outb
+        (let ((inhibit-read-only t))
+          (erase-buffer)
+          (printit header)))
+      (save-excursion
+        (goto-char (point-min))
+        (unless invisible-p
+          (tablist-skip-invisible-entries))
+        (while (not (eobp))
+          (let* ((entry (tabulated-list-get-entry)))
+            (with-current-buffer outb
+              (let ((inhibit-read-only t))
+                (printit entry)))
+            (if invisible-p
+                (forward-line)
+              (tablist-forward-entry)))))
+      (if display-p
+          (display-buffer outb))
+      outb)))
+
+;;
+
+(defun tablist-enlarge-column (&optional column width)
+  "Enlarge column COLUMN by WIDTH.
+
+This function is lazy and therfore pretty slow."
+  (interactive
+   (list nil (* (prefix-numeric-value current-prefix-arg)
+                3)))
+  (unless column (setq column (tablist-current-column)))
+  (unless column
+    (error "No column given and no entry at point"))
+  (unless width (setq width 1))
+  (when (or (not (numberp column))
+            (< column 0)
+            (>= column (length tabulated-list-format)))
+    (error "No such column: %d" column))
+  (when (= column (1- (length tabulated-list-format)))
+    (error "Can't resize last column"))
+
+  (let* ((cur-width (cadr (elt tabulated-list-format column))))
+    (setcar (cdr (elt tabulated-list-format column))
+            (max 3 (+ cur-width width)))
+    (tablist-with-remembering-entry
+      (tablist-save-marks
+       (tabulated-list-init-header)
+       (tabulated-list-print)))))
+
+(defun tablist-shrink-column (&optional column width)
+  (interactive
+   (list nil (* (prefix-numeric-value current-prefix-arg)
+                3)))
+  (tablist-enlarge-column column (- (or width 1))))
+
+;; *Sorting
+;;
+
+(defun tablist-sort (&optional column)
+  "Sort the tabulated-list by COLUMN.
+
+COLUMN may be either a name or an index.  The default compare
+function is given by the `tabulated-list-format', which see.
+
+This function saves the current sort column and the inverse
+sort-direction in the variable `tabulated-list-sort-key', which
+also determines the default COLUMN and direction.
+
+The main difference to `tabulated-list-sort' is, that this
+function sorts the buffer in-place and it ignores a nil sort
+entry in `tabulated-list-format' and sorts on the column
+anyway (why not ?)."
+
+  (interactive
+   (list
+    (if (null current-prefix-arg)
+        (tablist-column-name
+         (or (tablist-current-column)
+             (car (tablist-major-columns))
+             0))
+      (tablist-read-column-name
+       '(4) "Sort by column"
+       (tablist-column-name (car (tablist-major-columns)))))))
+
+  (unless column
+    (setq column (or (car tabulated-list-sort-key)
+                     (tablist-column-name (car (tablist-major-columns)))
+                     (tablist-column-name 0))))
+  (when (numberp column)
+    (let ((column-name (tablist-column-name column)))
+      (unless column-name
+        (error "No such column: %d" column))
+      (setq column column-name)))
+
+  (setq tabulated-list-sort-key
+        (cons column
+              (if (equal column (car tabulated-list-sort-key))
+                  (cdr tabulated-list-sort-key))))
+
+  (let* ((entries (if (functionp tabulated-list-entries)
+                      (funcall tabulated-list-entries)
+                    tabulated-list-entries))
+         (reverse (cdr tabulated-list-sort-key))
+         (n (tabulated-list--column-number ;;errors if column is n/a
+             (car tabulated-list-sort-key)))
+         (compare-fn (nth 2 (aref tabulated-list-format n))))
+
+    (when (or (null compare-fn)
+              (eq compare-fn t))
+      (setq compare-fn
+            (lambda (a b)
+              (setq a (aref (cadr a) n))
+              (setq b (aref (cadr b) n))
+              (string< (if (stringp a) a (car a))
+                       (if (stringp b) b (car b))))))
+
+    (unless compare-fn
+      (error "This column cannot be sorted: %s" column))
+
+    (setcdr tabulated-list-sort-key (not reverse))
+    ;; Presort the entries and hash the result and sort the buffer.
+    (setq entries (sort (copy-sequence entries) compare-fn))
+    (let ((hash (make-hash-table :test 'equal)))
+      (dotimes (i (length entries))
+        (puthash (caar entries) i hash)
+        (setq entries (cdr entries)))
+      (tablist-with-remembering-entry
+        (goto-char (point-min))
+        (tablist-skip-invisible-entries)
+        (let ((inhibit-read-only t))
+          (sort-subr
+           nil 'tablist-forward-entry 'end-of-line
+           (lambda ()
+             (gethash (tabulated-list-get-id) hash 0))
+           nil (if reverse '< '>))))
+      (tablist-move-to-column n)
+      ;; Make the sort arrows display.
+      (tabulated-list-init-header))))
+
+;;
+;; *Filter
+;;
+
+(defun tablist-read-filter-name (prompt)
+  (let ((filter (cdr (assq major-mode tablist-named-filter))))
+    (unless filter
+      (error "No filter defined for %s mode" mode-name))
+    (let ((name (completing-read
+                 (format "%s: " prompt)
+                 filter
+                 nil t)))
+      (unless (> (length name) 0)
+        (error "No filter selected"))
+      name)))
+
+(defun tablist-apply-filter (&optional filter)
+  "Apply FILTER to the current tabulated list.
+
+FILTER defaults to `tablist-current-filter'."
+  (unless filter (setq filter tablist-current-filter))
+  (tablist-filter-unhide-buffer)
+  (when (and filter
+             (null tablist-filter-suspended))
+    (tablist-with-remembering-entry
+      (tablist-map-with-filter
+       (lambda nil
+         (if tablist-umark-filtered-entries
+             (save-excursion (tablist-unmark-forward)))
+         (tablist-filter-hide-entry))
+       (tablist-filter-negate filter))))
+  (force-mode-line-update))
+
+(defadvice tabulated-list-print (after tabulated-list activate)
+  "Reapply the filter."
+  (when (or tablist-minor-mode
+            (derived-mode-p 'tablist-mode))
+    (tablist-apply-filter)))
+
+(defun tablist-eval-filter (filter)
+  (tablist-filter-eval
+   filter
+   (tabulated-list-get-id)
+   (tabulated-list-get-entry)
+   (cdr (assq major-mode tablist-named-filter))))
+
+(defun tablist-map-with-filter (fn filter &optional show-progress
+                                   distinguish-one-marked)
+  "Call FN for every unfiltered entry matching FILTER."
+  (prog1
+      (cl-labels ((search ()
+                          (tablist-skip-invisible-entries)
+                          (while (and (not (eobp))
+                                      (not (tablist-eval-filter filter)))
+                            (tablist-forward-entry))
+                          (unless (eobp)
+                            (point-marker))))
+        (let (next-position results)
+          (save-excursion
+            (goto-char (point-min))
+            (setq next-position (search))
+            (while next-position
+              (goto-char next-position)
+              (if show-progress (sit-for 0))
+              (push (funcall fn) results)
+              ;; move after last match
+              (goto-char next-position)
+              (forward-line 1)
+              (set-marker next-position nil)
+              (setq next-position (search)))
+            (if (and distinguish-one-marked (= (length results) 1))
+                (setq results (cons t results))))))))
+
+;;
+;; **Filter Commands
+;;
+(defun tablist-push-filter (filter &optional interactive or-p)
+  (setq tablist-current-filter
+        (tablist-filter-push
+         tablist-current-filter
+         filter or-p))
+  (tablist-apply-filter)
+  (when interactive
+    (tablist-display-filter-temporarily)))
+
+(defun tablist-pop-filter (&optional n interactive)
+  "Remove the first N filter components."
+  (interactive (list (prefix-numeric-value current-prefix-arg) t))
+  (while (and tablist-current-filter
+              (> n 0))
+    (setq tablist-current-filter
+          (tablist-filter-pop
+           tablist-current-filter))
+    (cl-decf n))
+  (tablist-apply-filter)
+  (when interactive
+    (when (> n 0)
+      (message "The filter is empty."))
+    (tablist-display-filter-temporarily))
+  n)
+
+(defun tablist-negate-filter (&optional interactive)
+  "Negate the current filter."
+  (interactive (list t))
+  (setq tablist-current-filter
+        (tablist-filter-negate
+         tablist-current-filter))
+  (tablist-apply-filter)
+  (when interactive
+    (tablist-display-filter-temporarily)))
+
+(defun tablist-toggle-first-filter-logic ()
+  "Toggle between and/or for the first filter operand."
+  (interactive)
+  (setq tablist-current-filter
+        (pcase tablist-current-filter
+          (`(or ,x1 ,x2)
+           `(and ,x1 ,x2))
+          (`(and ,x1 ,x2)
+           `(or ,x1 ,x2))
+          (`(not ,x) x)
+          (x `(not ,x))))
+  (tablist-apply-filter)
+  (tablist-display-filter-temporarily))
+
+(defun tablist-suspend-filter (&optional flag)
+  "Temporarily disable filtering according to FLAG.
+
+Interactively, this command toggles filtering."
+  (interactive
+   (list (not tablist-filter-suspended)))
+  (let ((state tablist-filter-suspended))
+    (unless (eq (not (not state))
+                (not (not flag)))
+      (set (make-local-variable 'tablist-filter-suspended) flag)
+      (tablist-apply-filter))))
+
+(defun tablist-read-regexp-filter (operation arg)
+  (let ((column-name (tablist-read-column-name arg)))
+    (list
+     column-name
+     (let ((re
+            (read-regexp (format "%s where %s matches: " operation column-name))))
+       (unless (> (length re) 0)
+         (error "No regexp given"))
+       re))))
+
+(defun tablist-read-equal-filter (operation arg)
+  (let ((column-name (tablist-read-column-name arg)))
+    (list
+     column-name
+     (read-string (format "%s where %s equals: " operation column-name)))))
+
+(defun tablist-read-numeric-filter (operation arg)
+  (let* ((entry (tabulated-list-get-entry 1))
+         (default (cl-some
+                   (lambda (idx)
+                     (let ((value (tablist-nth-entry idx entry)))
+                       (when (or (not (eq 0 (string-to-number value)))
+                                 (equal "0" value))
+                         (tablist-column-name idx))))
+                   (number-sequence 0 (length entry))))
+         (column-name (tablist-read-column-name arg nil default))
+         (op (completing-read
+              (format "%s %s matching binary op: " operation column-name)
+              '("=" "<" ">" "<=" ">=") nil t))
+         oper)
+
+    (when (equal "" op)
+      (error "No operation selected"))
+    (setq op (intern op))
+    (setq oper (number-to-string
+                (read-number
+                 (format "%s where %s %s " operation column-name op))))
+
+    (list op column-name oper)))
+
+(defun tablist-push-regexp-filter (column-name regexp)
+  "Add a new filter matching REGEXP in COLUMN-NAME.
+
+The filter is and'ed with the current filter.  Use
+`tablist-toggle-first-filter-logic' to change this."
+  (interactive
+   (tablist-with-filter-displayed
+    (tablist-read-regexp-filter "Filter" current-prefix-arg)))
+  (tablist-push-filter
+   `(=~ ,column-name ,regexp)
+   (called-interactively-p 'any)))
+
+(defun tablist-push-equal-filter (column-name string)
+  "Add a new filter whre string equals COLUMN-NAME's value.
+
+The filter is and'ed with the current filter.  Use
+`tablist-toggle-first-filter-logic' to change this."
+  (interactive
+   (tablist-with-filter-displayed
+    (tablist-read-equal-filter "Filter" current-prefix-arg)))
+  (tablist-push-filter
+   `(== ,column-name ,string)
+   (called-interactively-p 'any)))
+
+(defun tablist-push-numeric-filter (op column-name 2nd-arg)
+  "Add a new filter matching a numeric predicate.
+
+The filter is and'ed with the current filter.  Use
+`tablist-toggle-first-filter-logic' to change this."
+  (interactive
+   (tablist-with-filter-displayed
+    (tablist-read-numeric-filter "Filter" current-prefix-arg)))
+  (tablist-push-filter
+   `(,op ,column-name ,2nd-arg)
+   (called-interactively-p 'any)))
+
+(defun tablist-push-named-filter (name)
+  "Add a named filter called NAME.
+
+Named filter are saved in the variable `tablist-named-filter'."
+  (interactive
+   (tablist-with-filter-displayed
+    (list
+     (tablist-read-filter-name "Add filter"))))
+  (when (and name (symbolp name))
+    (setq name (symbol-name name)))
+  (tablist-push-filter name (called-interactively-p 'any)))
+
+(defun tablist-delete-named-filter (name &optional mode)
+  (interactive
+   (tablist-with-filter-displayed
+    (list
+     (tablist-read-filter-name "Delete filter"))))
+  (setq tablist-current-filter
+        (tablist-filter-map
+         (lambda (f)
+           (when (equal f name)
+             (setq f (tablist-get-named-filter f)))
+           f)
+         tablist-current-filter))
+  (unless mode (setq mode major-mode))
+  (let ((mode-filter
+         (assq mode tablist-named-filter)))
+    (when mode-filter
+      (setcdr mode-filter
+              (cl-remove name (cdr mode-filter)
+                         :test 'equal :key 'car)))))
+
+(defun tablist-name-current-filter (name)
+  (interactive
+   (list (tablist-with-filter-displayed
+          (read-string
+           "Add name for current filter: "))))
+  (unless tablist-current-filter
+    (error "Filter is empty"))
+  (unless (> (length name) 0)
+    (error "No name given"))
+  (tablist-put-named-filter
+   name (if (stringp tablist-current-filter)
+            (tablist-get-named-filter
+             tablist-current-filter)
+          tablist-current-filter))
+  (setq tablist-current-filter name)
+  (force-mode-line-update))
+
+(defun tablist-deconstruct-named-filter ()
+  (interactive)
+  (let (found)
+    (setq tablist-current-filter
+          (tablist-filter-map
+           (lambda (f)
+             (when (and (not found)
+                        (stringp f))
+               (setq found t)
+               (let ((df (tablist-get-named-filter f)))
+                 (unless df
+                   (error "Filter is not defined: %s" f))
+                 (setq f df)))
+             f)
+           tablist-current-filter))
+    (unless found
+      (error "No named filter found"))
+    (force-mode-line-update)))
+
+(defun tablist-filter-names (&optional mode)
+  (mapcar 'car (cdr (assq (or mode major-mode)
+                          tablist-named-filter))))
+
+(defun tablist-get-named-filter (name &optional mode)
+  (cdr (assoc name
+              (cdr (assq (or mode major-mode)
+                         tablist-named-filter)))))
+
+(defun tablist-put-named-filter (name filter &optional mode)
+  (unless mode (setq mode major-mode))
+  (let ((mode-filter
+         (assq mode tablist-named-filter)))
+    (unless mode-filter
+      (setq mode-filter (cons mode nil))
+      (push mode-filter tablist-named-filter))
+    (let ((entry (assoc name mode-filter)))
+      (if entry
+          (setcdr entry filter)
+        (setcdr mode-filter
+                (list (cons name filter)))))))
+
+(defun tablist-validate-named-filter (filter)
+  (tablist-filter-map
+   (lambda (f)
+     (when (and (stringp f)
+                (null (tablist-get-named-filter f)))
+       (error "Undefined named filter: %s (defined: %s)" f
+              (mapconcat 'identity (tablist-filter-names) ","))))
+   filter))
+
+(defun tablist-edit-filter ()
+  (interactive)
+  (setq tablist-current-filter
+        (tablist-with-filter-displayed
+         (tablist-filter-edit-filter
+          "Edit filter: "
+          tablist-current-filter
+          nil
+          'tablist-validate-named-filter)))
+  (tablist-apply-filter))
+
+(defun tablist-clear-filter ()
+  (interactive)
+  (setq tablist-current-filter nil)
+  (tablist-apply-filter))
+
+;; **Displaying filter
+;;
+
+(defconst tablist-display-filter-mode-line-tag nil)
+
+(defun tablist-display-filter (&optional flag)
+  "Display the current filter according to FLAG.
+
+If FLAG has the value 'toggle, toggle it's visibility.
+If FLAG has the 'state, then do nothing but return the current
+visibility."
+  (interactive (list 'toggle))
+  (let* ((tag 'tablist-display-filter-mode-line-tag)
+         (displayed-p (not (not (assq tag mode-line-format)))))
+    (if (eq flag 'state)
+        displayed-p
+      (let ((display-p (not (not (if (eq flag 'toggle)
+                                     (not displayed-p)
+                                   flag)))))
+        (unless (eq displayed-p display-p)
+          (setq mode-line-format
+                (if display-p
+                    (list (cons tag mode-line-format)
+                          '(:eval
+                            (replace-regexp-in-string
+                             "%" "%%"
+                             (concat
+                              (propertize "Filter: " 'face 'minibuffer-prompt)
+                              (and tablist-filter-suspended
+                                   "[suspended] ")
+                              (if tablist-current-filter
+                                  (tablist-filter-unparse
+                                   tablist-current-filter t)
+                                "[none]")))))
+                  (cdr (assq tag mode-line-format)))))
+        (force-mode-line-update)
+        display-p))))
+
+(defun tablist-display-filter-temporarily ()
+  (tablist-with-filter-displayed
+   (sit-for 9999)))
+
+;;
+;; **Hiding/Unhiding Entries
+;;
+(defun tablist-filter-set-entry-hidden (flag &optional pos)
+  (save-excursion
+    (when pos (goto-char pos))
+    (beginning-of-line)
+    (let ((inhibit-read-only t))
+      (add-text-properties
+       (point-at-bol)
+       (1+ (point-at-eol))
+       `(invisible ,flag)))))
+
+(defun tablist-filter-hide-entry (&optional pos)
+  (interactive)
+  (tablist-filter-set-entry-hidden t pos))
+
+(defun tablist-filter-unhide-entry (&optional pos)
+  (tablist-filter-set-entry-hidden nil pos))
+
+(defun tablist-filter-unhide-buffer ()
+  (let ((inhibit-read-only t))
+    (remove-text-properties
+     (point-min) (point-max)
+     '(invisible))))
+
+(defun tablist-window-attach (awindow &optional window)
+  "Attach AWINDOW to WINDOW.
+
+This has the following effect.  Whenever WINDOW, defaulting to
+the selected window, stops displaying the buffer it currently
+displays (e.g., by switching buffers or because it was deleted)
+AWINDOW is deleted."
+  (unless window (setq window (selected-window)))
+  (let ((buffer (window-buffer window))
+        (hook (make-symbol "window-attach-hook")))
+    (fset hook
+          (lambda ()
+            (when (or (not (window-live-p window))
+                      (not (eq buffer (window-buffer window))))
+              (remove-hook 'window-configuration-change-hook
+                           hook)
+              ;; Deleting windows inside wcch may cause errors in
+              ;; windows.el .
+              (run-with-timer
+               0 nil (lambda (win)
+                       (when (and (window-live-p win)
+                                  (not (eq win (selected-window))))
+                         (delete-window win)))
+               awindow))))
+    (add-hook 'window-configuration-change-hook hook)))
+
+(defun tablist-display-buffer-split-below-and-attach (buf alist)
+  "Display buffer action using `tablist-window-attach'."
+  (let ((window (selected-window))
+        (height (cdr (assq 'window-height alist)))
+        newwin)
+    (when height
+      (when (floatp height)
+        (setq height (round (* height (frame-height)))))
+      (setq height (- (max height window-min-height))))
+    (setq newwin (window--display-buffer
+                  buf
+                  (split-window-below height)
+                  'window alist display-buffer-mark-dedicated))
+    (tablist-window-attach newwin window)
+    newwin))
+
+(defun tablist-generate-sorter (column compare-fn &optional read-fn)
+  "Generate a sort function for `tabulated-list' entries.
+
+Example:
+
+     \(tablist-generate-sorter 0 '< 'string-to-number\)
+
+would create a sort function sorting `tabulated-list-entries' on
+the 0-th column as numbers by the less-than relation."
+
+  (lambda (e1 e2)
+    (funcall compare-fn
+             (funcall (or read-fn 'identity)
+                      (aref (cadr e1) column))
+             (funcall read-fn
+                      (aref (cadr e2) column)))))
+
+(provide 'tablist)
+;;; tablist.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/tablist-20170219.1935/tablist.elc b/configs/shared/emacs/.emacs.d/elpa/tablist-20170219.1935/tablist.elc
new file mode 100644
index 0000000000..796b5c1876
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/tablist-20170219.1935/tablist.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/undo-tree-0.6.5.signed b/configs/shared/emacs/.emacs.d/elpa/undo-tree-0.6.5.signed
new file mode 100644
index 0000000000..71229bfb91
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/undo-tree-0.6.5.signed
@@ -0,0 +1 @@
+Good signature from 474F05837FBDEF9B GNU ELPA Signing Agent <elpasign@elpa.gnu.org> (trust undefined) created at 2014-09-24T10:20:09-0400 using DSA
\ No newline at end of file
diff --git a/configs/shared/emacs/.emacs.d/elpa/undo-tree-0.6.5/undo-tree-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/undo-tree-0.6.5/undo-tree-autoloads.el
new file mode 100644
index 0000000000..67d5f94543
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/undo-tree-0.6.5/undo-tree-autoloads.el
@@ -0,0 +1,59 @@
+;;; undo-tree-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "undo-tree" "undo-tree.el" (23377 61205 755941
+;;;;;;  924000))
+;;; Generated autoloads from undo-tree.el
+
+(autoload 'undo-tree-mode "undo-tree" "\
+Toggle undo-tree mode.
+With no argument, this command toggles the mode.
+A positive prefix argument turns the mode on.
+A negative prefix argument turns it off.
+
+Undo-tree-mode replaces Emacs' standard undo feature with a more
+powerful yet easier to use version, that treats the undo history
+as what it is: a tree.
+
+The following keys are available in `undo-tree-mode':
+
+  \\{undo-tree-map}
+
+Within the undo-tree visualizer, the following keys are available:
+
+  \\{undo-tree-visualizer-mode-map}
+
+\(fn &optional ARG)" t nil)
+
+(defvar global-undo-tree-mode nil "\
+Non-nil if Global Undo-Tree mode is enabled.
+See the `global-undo-tree-mode' command
+for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `global-undo-tree-mode'.")
+
+(custom-autoload 'global-undo-tree-mode "undo-tree" nil)
+
+(autoload 'global-undo-tree-mode "undo-tree" "\
+Toggle Undo-Tree mode in all buffers.
+With prefix ARG, enable Global Undo-Tree mode if ARG is positive;
+otherwise, disable it.  If called from Lisp, enable the mode if
+ARG is omitted or nil.
+
+Undo-Tree mode is enabled in all buffers where
+`turn-on-undo-tree-mode' would do it.
+See `undo-tree-mode' for more information on Undo-Tree mode.
+
+\(fn &optional ARG)" t nil)
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; undo-tree-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/undo-tree-0.6.5/undo-tree-pkg.el b/configs/shared/emacs/.emacs.d/elpa/undo-tree-0.6.5/undo-tree-pkg.el
new file mode 100644
index 0000000000..d9081a7681
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/undo-tree-0.6.5/undo-tree-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "undo-tree" "0.6.5" "Treat undo history as a tree" 'nil :url "http://www.dr-qubit.org/emacs.php" :keywords '("convenience" "files" "undo" "redo" "history" "tree"))
diff --git a/configs/shared/emacs/.emacs.d/elpa/undo-tree-0.6.5/undo-tree.el b/configs/shared/emacs/.emacs.d/elpa/undo-tree-0.6.5/undo-tree.el
new file mode 100644
index 0000000000..3e45b84e13
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/undo-tree-0.6.5/undo-tree.el
@@ -0,0 +1,4418 @@
+;;; undo-tree.el --- Treat undo history as a tree  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2009-2013  Free Software Foundation, Inc
+
+;; Author: Toby Cubitt <toby-undo-tree@dr-qubit.org>
+;; Version: 0.6.5
+;; Keywords: convenience, files, undo, redo, history, tree
+;; URL: http://www.dr-qubit.org/emacs.php
+;; Repository: http://www.dr-qubit.org/git/undo-tree.git
+
+;; This file is part of Emacs.
+;;
+;; This file 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.
+;;
+;; This program 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:
+;;
+;; Emacs has a powerful undo system. Unlike the standard undo/redo system in
+;; most software, it allows you to recover *any* past state of a buffer
+;; (whereas the standard undo/redo system can lose past states as soon as you
+;; redo). However, this power comes at a price: many people find Emacs' undo
+;; system confusing and difficult to use, spawning a number of packages that
+;; replace it with the less powerful but more intuitive undo/redo system.
+;;
+;; Both the loss of data with standard undo/redo, and the confusion of Emacs'
+;; undo, stem from trying to treat undo history as a linear sequence of
+;; changes. It's not. The `undo-tree-mode' provided by this package replaces
+;; Emacs' undo system with a system that treats undo history as what it is: a
+;; branching tree of changes. This simple idea allows the more intuitive
+;; behaviour of the standard undo/redo system to be combined with the power of
+;; never losing any history. An added side bonus is that undo history can in
+;; some cases be stored more efficiently, allowing more changes to accumulate
+;; before Emacs starts discarding history.
+;;
+;; The only downside to this more advanced yet simpler undo system is that it
+;; was inspired by Vim. But, after all, most successful religions steal the
+;; best ideas from their competitors!
+;;
+;;
+;; Installation
+;; ============
+;;
+;; This package has only been tested with Emacs versions 24 and CVS. It should
+;; work in Emacs versions 22 and 23 too, but will not work without
+;; modifications in earlier versions of Emacs.
+;;
+;; To install `undo-tree-mode', make sure this file is saved in a directory in
+;; your `load-path', and add the line:
+;;
+;;   (require 'undo-tree)
+;;
+;; to your .emacs file. Byte-compiling undo-tree.el is recommended (e.g. using
+;; "M-x byte-compile-file" from within emacs).
+;;
+;; If you want to replace the standard Emacs' undo system with the
+;; `undo-tree-mode' system in all buffers, you can enable it globally by
+;; adding:
+;;
+;;   (global-undo-tree-mode)
+;;
+;; to your .emacs file.
+;;
+;;
+;; Quick-Start
+;; ===========
+;;
+;; If you're the kind of person who likes to jump in the car and drive,
+;; without bothering to first figure out whether the button on the left dips
+;; the headlights or operates the ejector seat (after all, you'll soon figure
+;; it out when you push it), then here's the minimum you need to know:
+;;
+;; `undo-tree-mode' and `global-undo-tree-mode'
+;;   Enable undo-tree mode (either in the current buffer or globally).
+;;
+;; C-_  C-/  (`undo-tree-undo')
+;;   Undo changes.
+;;
+;; M-_  C-?  (`undo-tree-redo')
+;;   Redo changes.
+;;
+;; `undo-tree-switch-branch'
+;;   Switch undo-tree branch.
+;;   (What does this mean? Better press the button and see!)
+;;
+;; C-x u  (`undo-tree-visualize')
+;;   Visualize the undo tree.
+;;   (Better try pressing this button too!)
+;;
+;; C-x r u  (`undo-tree-save-state-to-register')
+;;   Save current buffer state to register.
+;;
+;; C-x r U  (`undo-tree-restore-state-from-register')
+;;   Restore buffer state from register.
+;;
+;;
+;;
+;; In the undo-tree visualizer:
+;;
+;; <up>  p  C-p  (`undo-tree-visualize-undo')
+;;   Undo changes.
+;;
+;; <down>  n  C-n  (`undo-tree-visualize-redo')
+;;   Redo changes.
+;;
+;; <left>  b  C-b  (`undo-tree-visualize-switch-branch-left')
+;;   Switch to previous undo-tree branch.
+;;
+;; <right>  f  C-f  (`undo-tree-visualize-switch-branch-right')
+;;   Switch to next undo-tree branch.
+;;
+;; C-<up>  M-{  (`undo-tree-visualize-undo-to-x')
+;;   Undo changes up to last branch point.
+;;
+;; C-<down>  M-}  (`undo-tree-visualize-redo-to-x')
+;;   Redo changes down to next branch point.
+;;
+;; <down>  n  C-n  (`undo-tree-visualize-redo')
+;;   Redo changes.
+;;
+;; <mouse-1>  (`undo-tree-visualizer-mouse-set')
+;;   Set state to node at mouse click.
+;;
+;; t  (`undo-tree-visualizer-toggle-timestamps')
+;;   Toggle display of time-stamps.
+;;
+;; d  (`undo-tree-visualizer-toggle-diff')
+;;   Toggle diff display.
+;;
+;; s  (`undo-tree-visualizer-selection-mode')
+;;   Toggle keyboard selection mode.
+;;
+;; q  (`undo-tree-visualizer-quit')
+;;   Quit undo-tree-visualizer.
+;;
+;; C-q  (`undo-tree-visualizer-abort')
+;;   Abort undo-tree-visualizer.
+;;
+;; ,  <
+;;   Scroll left.
+;;
+;; .  >
+;;   Scroll right.
+;;
+;; <pgup>  M-v
+;;   Scroll up.
+;;
+;; <pgdown>  C-v
+;;   Scroll down.
+;;
+;;
+;;
+;; In visualizer selection mode:
+;;
+;; <up>  p  C-p  (`undo-tree-visualizer-select-previous')
+;;   Select previous node.
+;;
+;; <down>  n  C-n  (`undo-tree-visualizer-select-next')
+;;   Select next node.
+;;
+;; <left>  b  C-b  (`undo-tree-visualizer-select-left')
+;;   Select left sibling node.
+;;
+;; <right>  f  C-f  (`undo-tree-visualizer-select-right')
+;;   Select right sibling node.
+;;
+;; <pgup>  M-v
+;;   Select node 10 above.
+;;
+;; <pgdown>  C-v
+;;   Select node 10 below.
+;;
+;; <enter>  (`undo-tree-visualizer-set')
+;;   Set state to selected node and exit selection mode.
+;;
+;; s  (`undo-tree-visualizer-mode')
+;;   Exit selection mode.
+;;
+;; t  (`undo-tree-visualizer-toggle-timestamps')
+;;   Toggle display of time-stamps.
+;;
+;; d  (`undo-tree-visualizer-toggle-diff')
+;;   Toggle diff display.
+;;
+;; q  (`undo-tree-visualizer-quit')
+;;   Quit undo-tree-visualizer.
+;;
+;; C-q  (`undo-tree-visualizer-abort')
+;;   Abort undo-tree-visualizer.
+;;
+;; ,  <
+;;   Scroll left.
+;;
+;; .  >
+;;   Scroll right.
+;;
+;;
+;;
+;; Persistent undo history:
+;;
+;; Note: Requires Emacs version 24.3 or higher.
+;;
+;; `undo-tree-auto-save-history' (variable)
+;;    automatically save and restore undo-tree history along with buffer
+;;    (disabled by default)
+;;
+;; `undo-tree-save-history' (command)
+;;    manually save undo history to file
+;;
+;; `undo-tree-load-history' (command)
+;;    manually load undo history from file
+;;
+;;
+;;
+;; Compressing undo history:
+;;
+;;   Undo history files cannot grow beyond the maximum undo tree size, which
+;;   is limited by `undo-limit', `undo-strong-limit' and
+;;   `undo-outer-limit'. Nevertheless, undo history files can grow quite
+;;   large. If you want to automatically compress undo history, add the
+;;   following advice to your .emacs file (replacing ".gz" with the filename
+;;   extension of your favourite compression algorithm):
+;;
+;;   (defadvice undo-tree-make-history-save-file-name
+;;     (after undo-tree activate)
+;;     (setq ad-return-value (concat ad-return-value ".gz")))
+;;
+;;
+;;
+;;
+;; Undo Systems
+;; ============
+;;
+;; To understand the different undo systems, it's easiest to consider an
+;; example. Imagine you make a few edits in a buffer. As you edit, you
+;; accumulate a history of changes, which we might visualize as a string of
+;; past buffer states, growing downwards:
+;;
+;;                                o  (initial buffer state)
+;;                                |
+;;                                |
+;;                                o  (first edit)
+;;                                |
+;;                                |
+;;                                o  (second edit)
+;;                                |
+;;                                |
+;;                                x  (current buffer state)
+;;
+;;
+;; Now imagine that you undo the last two changes. We can visualize this as
+;; rewinding the current state back two steps:
+;;
+;;                                o  (initial buffer state)
+;;                                |
+;;                                |
+;;                                x  (current buffer state)
+;;                                |
+;;                                |
+;;                                o
+;;                                |
+;;                                |
+;;                                o
+;;
+;;
+;; However, this isn't a good representation of what Emacs' undo system
+;; does. Instead, it treats the undos as *new* changes to the buffer, and adds
+;; them to the history:
+;;
+;;                                o  (initial buffer state)
+;;                                |
+;;                                |
+;;                                o  (first edit)
+;;                                |
+;;                                |
+;;                                o  (second edit)
+;;                                |
+;;                                |
+;;                                x  (buffer state before undo)
+;;                                |
+;;                                |
+;;                                o  (first undo)
+;;                                |
+;;                                |
+;;                                x  (second undo)
+;;
+;;
+;; Actually, since the buffer returns to a previous state after an undo,
+;; perhaps a better way to visualize it is to imagine the string of changes
+;; turning back on itself:
+;;
+;;        (initial buffer state)  o
+;;                                |
+;;                                |
+;;                  (first edit)  o  x  (second undo)
+;;                                |  |
+;;                                |  |
+;;                 (second edit)  o  o  (first undo)
+;;                                | /
+;;                                |/
+;;                                o  (buffer state before undo)
+;;
+;; Treating undos as new changes might seem a strange thing to do. But the
+;; advantage becomes clear as soon as we imagine what happens when you edit
+;; the buffer again. Since you've undone a couple of changes, new edits will
+;; branch off from the buffer state that you've rewound to. Conceptually, it
+;; looks like this:
+;;
+;;                                o  (initial buffer state)
+;;                                |
+;;                                |
+;;                                o
+;;                                |\
+;;                                | \
+;;                                o  x  (new edit)
+;;                                |
+;;                                |
+;;                                o
+;;
+;; The standard undo/redo system only lets you go backwards and forwards
+;; linearly. So as soon as you make that new edit, it discards the old
+;; branch. Emacs' undo just keeps adding changes to the end of the string. So
+;; the undo history in the two systems now looks like this:
+;;
+;;            Undo/Redo:                      Emacs' undo
+;;
+;;               o                                o
+;;               |                                |
+;;               |                                |
+;;               o                                o  o
+;;               .\                               |  |\
+;;               . \                              |  | \
+;;               .  x  (new edit)                 o  o  |
+;;   (discarded  .                                | /   |
+;;     branch)   .                                |/    |
+;;               .                                o     |
+;;                                                      |
+;;                                                      |
+;;                                                      x  (new edit)
+;;
+;; Now, what if you change your mind about those undos, and decide you did
+;; like those other changes you'd made after all? With the standard undo/redo
+;; system, you're lost. There's no way to recover them, because that branch
+;; was discarded when you made the new edit.
+;;
+;; However, in Emacs' undo system, those old buffer states are still there in
+;; the undo history. You just have to rewind back through the new edit, and
+;; back through the changes made by the undos, until you reach them. Of
+;; course, since Emacs treats undos (even undos of undos!) as new changes,
+;; you're really weaving backwards and forwards through the history, all the
+;; time adding new changes to the end of the string as you go:
+;;
+;;                       o
+;;                       |
+;;                       |
+;;                       o  o     o  (undo new edit)
+;;                       |  |\    |\
+;;                       |  | \   | \
+;;                       o  o  |  |  o  (undo the undo)
+;;                       | /   |  |  |
+;;                       |/    |  |  |
+;;      (trying to get   o     |  |  x  (undo the undo)
+;;       to this state)        | /
+;;                             |/
+;;                             o
+;;
+;; So far, this is still reasonably intuitive to use. It doesn't behave so
+;; differently to standard undo/redo, except that by going back far enough you
+;; can access changes that would be lost in standard undo/redo.
+;;
+;; However, imagine that after undoing as just described, you decide you
+;; actually want to rewind right back to the initial state. If you're lucky,
+;; and haven't invoked any command since the last undo, you can just keep on
+;; undoing until you get back to the start:
+;;
+;;      (trying to get   o              x  (got there!)
+;;       to this state)  |              |
+;;                       |              |
+;;                       o  o     o     o  (keep undoing)
+;;                       |  |\    |\    |
+;;                       |  | \   | \   |
+;;                       o  o  |  |  o  o  (keep undoing)
+;;                       | /   |  |  | /
+;;                       |/    |  |  |/
+;;      (already undid   o     |  |  o  (got this far)
+;;       to this state)        | /
+;;                             |/
+;;                             o
+;;
+;; But if you're unlucky, and you happen to have moved the point (say) after
+;; getting to the state labelled "got this far", then you've "broken the undo
+;; chain". Hold on to something solid, because things are about to get
+;; hairy. If you try to undo now, Emacs thinks you're trying to undo the
+;; undos! So to get back to the initial state you now have to rewind through
+;; *all* the changes, including the undos you just did:
+;;
+;;      (trying to get   o                          x  (finally got there!)
+;;       to this state)  |                          |
+;;                       |                          |
+;;                       o  o     o     o     o     o
+;;                       |  |\    |\    |\    |\    |
+;;                       |  | \   | \   | \   | \   |
+;;                       o  o  |  |  o  o  o  |  o  o
+;;                       | /   |  |  | /   |  |  | /
+;;                       |/    |  |  |/    |  |  |/
+;;      (already undid   o     |  |  o<.   |  |  o
+;;       to this state)        | /     :   | /
+;;                             |/      :   |/
+;;                             o       :   o
+;;                                     :
+;;                             (got this far, but
+;;                              broke the undo chain)
+;;
+;; Confused?
+;;
+;; In practice you can just hold down the undo key until you reach the buffer
+;; state that you want. But whatever you do, don't move around in the buffer
+;; to *check* that you've got back to where you want! Because you'll break the
+;; undo chain, and then you'll have to traverse the entire string of undos
+;; again, just to get back to the point at which you broke the
+;; chain. Undo-in-region and commands such as `undo-only' help to make using
+;; Emacs' undo a little easier, but nonetheless it remains confusing for many
+;; people.
+;;
+;;
+;; So what does `undo-tree-mode' do? Remember the diagram we drew to represent
+;; the history we've been discussing (make a few edits, undo a couple of them,
+;; and edit again)? The diagram that conceptually represented our undo
+;; history, before we started discussing specific undo systems? It looked like
+;; this:
+;;
+;;                                o  (initial buffer state)
+;;                                |
+;;                                |
+;;                                o
+;;                                |\
+;;                                | \
+;;                                o  x  (current state)
+;;                                |
+;;                                |
+;;                                o
+;;
+;; Well, that's *exactly* what the undo history looks like to
+;; `undo-tree-mode'.  It doesn't discard the old branch (as standard undo/redo
+;; does), nor does it treat undos as new changes to be added to the end of a
+;; linear string of buffer states (as Emacs' undo does). It just keeps track
+;; of the tree of branching changes that make up the entire undo history.
+;;
+;; If you undo from this point, you'll rewind back up the tree to the previous
+;; state:
+;;
+;;                                o
+;;                                |
+;;                                |
+;;                                x  (undo)
+;;                                |\
+;;                                | \
+;;                                o  o
+;;                                |
+;;                                |
+;;                                o
+;;
+;; If you were to undo again, you'd rewind back to the initial state. If on
+;; the other hand you redo the change, you'll end up back at the bottom of the
+;; most recent branch:
+;;
+;;                                o  (undo takes you here)
+;;                                |
+;;                                |
+;;                                o  (start here)
+;;                                |\
+;;                                | \
+;;                                o  x  (redo takes you here)
+;;                                |
+;;                                |
+;;                                o
+;;
+;; So far, this is just like the standard undo/redo system. But what if you
+;; want to return to a buffer state located on a previous branch of the
+;; history? Since `undo-tree-mode' keeps the entire history, you simply need
+;; to tell it to switch to a different branch, and then redo the changes you
+;; want:
+;;
+;;                                o
+;;                                |
+;;                                |
+;;                                o  (start here, but switch
+;;                                |\  to the other branch)
+;;                                | \
+;;                        (redo)  o  o
+;;                                |
+;;                                |
+;;                        (redo)  x
+;;
+;; Now you're on the other branch, if you undo and redo changes you'll stay on
+;; that branch, moving up and down through the buffer states located on that
+;; branch. Until you decide to switch branches again, of course.
+;;
+;; Real undo trees might have multiple branches and sub-branches:
+;;
+;;                                o
+;;                            ____|______
+;;                           /           \
+;;                          o             o
+;;                      ____|__         __|
+;;                     /    |  \       /   \
+;;                    o     o   o     o     x
+;;                    |               |
+;;                   / \             / \
+;;                  o   o           o   o
+;;
+;; Trying to imagine what Emacs' undo would do as you move about such a tree
+;; will likely frazzle your brain circuits! But in `undo-tree-mode', you're
+;; just moving around this undo history tree. Most of the time, you'll
+;; probably only need to stay on the most recent branch, in which case it
+;; behaves like standard undo/redo, and is just as simple to understand. But
+;; if you ever need to recover a buffer state on a different branch, the
+;; possibility of switching between branches and accessing the full undo
+;; history is still there.
+;;
+;;
+;;
+;; The Undo-Tree Visualizer
+;; ========================
+;;
+;; Actually, it gets better. You don't have to imagine all these tree
+;; diagrams, because `undo-tree-mode' includes an undo-tree visualizer which
+;; draws them for you! In fact, it draws even better diagrams: it highlights
+;; the node representing the current buffer state, it highlights the current
+;; branch, and you can toggle the display of time-stamps (by hitting "t") and
+;; a diff of the undo changes (by hitting "d"). (There's one other tiny
+;; difference: the visualizer puts the most recent branch on the left rather
+;; than the right.)
+;;
+;; Bring up the undo tree visualizer whenever you want by hitting "C-x u".
+;;
+;; In the visualizer, the usual keys for moving up and down a buffer instead
+;; move up and down the undo history tree (e.g. the up and down arrow keys, or
+;; "C-n" and "C-p"). The state of the "parent" buffer (the buffer whose undo
+;; history you are visualizing) is updated as you move around the undo tree in
+;; the visualizer. If you reach a branch point in the visualizer, the usual
+;; keys for moving forward and backward in a buffer instead switch branch
+;; (e.g. the left and right arrow keys, or "C-f" and "C-b").
+;;
+;; Clicking with the mouse on any node in the visualizer will take you
+;; directly to that node, resetting the state of the parent buffer to the
+;; state represented by that node.
+;;
+;; You can also select nodes directly using the keyboard, by hitting "s" to
+;; toggle selection mode. The usual motion keys now allow you to move around
+;; the tree without changing the parent buffer. Hitting <enter> will reset the
+;; state of the parent buffer to the state represented by the currently
+;; selected node.
+;;
+;; It can be useful to see how long ago the parent buffer was in the state
+;; represented by a particular node in the visualizer. Hitting "t" in the
+;; visualizer toggles the display of time-stamps for all the nodes. (Note
+;; that, because of the way `undo-tree-mode' works, these time-stamps may be
+;; somewhat later than the true times, especially if it's been a long time
+;; since you last undid any changes.)
+;;
+;; To get some idea of what changes are represented by a given node in the
+;; tree, it can be useful to see a diff of the changes. Hit "d" in the
+;; visualizer to toggle a diff display. This normally displays a diff between
+;; the current state and the previous one, i.e. it shows you the changes that
+;; will be applied if you undo (move up the tree). However, the diff display
+;; really comes into its own in the visualizer's selection mode (see above),
+;; where it instead shows a diff between the current state and the currently
+;; selected state, i.e. it shows you the changes that will be applied if you
+;; reset to the selected state.
+;;
+;; (Note that the diff is generated by the Emacs `diff' command, and is
+;; displayed using `diff-mode'. See the corresponding customization groups if
+;; you want to customize the diff display.)
+;;
+;; Finally, hitting "q" will quit the visualizer, leaving the parent buffer in
+;; whatever state you ended at. Hitting "C-q" will abort the visualizer,
+;; returning the parent buffer to whatever state it was originally in when the
+;; visualizer was .
+;;
+;;
+;;
+;; Undo-in-Region
+;; ==============
+;;
+;; Emacs allows a very useful and powerful method of undoing only selected
+;; changes: when a region is active, only changes that affect the text within
+;; that region will be undone. With the standard Emacs undo system, changes
+;; produced by undoing-in-region naturally get added onto the end of the
+;; linear undo history:
+;;
+;;                       o
+;;                       |
+;;                       |  x  (second undo-in-region)
+;;                       o  |
+;;                       |  |
+;;                       |  o  (first undo-in-region)
+;;                       o  |
+;;                       | /
+;;                       |/
+;;                       o
+;;
+;; You can of course redo these undos-in-region as usual, by undoing the
+;; undos:
+;;
+;;                       o
+;;                       |
+;;                       |  o_
+;;                       o  | \
+;;                       |  |  |
+;;                       |  o  o  (undo the undo-in-region)
+;;                       o  |  |
+;;                       | /   |
+;;                       |/    |
+;;                       o     x  (undo the undo-in-region)
+;;
+;;
+;; In `undo-tree-mode', undo-in-region works similarly: when there's an active
+;; region, undoing only undoes changes that affect that region. However, the
+;; way these undos-in-region are recorded in the undo history is quite
+;; different. In `undo-tree-mode', undo-in-region creates a new branch in the
+;; undo history. The new branch consists of an undo step that undoes some of
+;; the changes that affect the current region, and another step that undoes
+;; the remaining changes needed to rejoin the previous undo history.
+;;
+;;      Previous undo history                Undo-in-region
+;;
+;;               o                                o
+;;               |                                |
+;;               |                                |
+;;               o                                o
+;;               |                                |\
+;;               |                                | \
+;;               o                                o  x  (undo-in-region)
+;;               |                                |  |
+;;               |                                |  |
+;;               x                                o  o
+;;
+;; As long as you don't change the active region after undoing-in-region,
+;; continuing to undo-in-region extends the new branch, pulling more changes
+;; that affect the current region into an undo step immediately above your
+;; current location in the undo tree, and pushing the point at which the new
+;; branch is attached further up the tree:
+;;
+;;      First undo-in-region                 Second undo-in-region
+;;
+;;               o                                o
+;;               |                                |\
+;;               |                                | \
+;;               o                                o  x  (undo-in-region)
+;;               |\                               |  |
+;;               | \                              |  |
+;;               o  x                             o  o
+;;               |  |                             |  |
+;;               |  |                             |  |
+;;               o  o                             o  o
+;;
+;; Redoing takes you back down the undo tree, as usual (as long as you haven't
+;; changed the active region after undoing-in-region, it doesn't matter if it
+;; is still active):
+;;
+;;                       o
+;;			 |\
+;;			 | \
+;;			 o  o
+;;			 |  |
+;;			 |  |
+;;			 o  o  (redo)
+;;			 |  |
+;;			 |  |
+;;			 o  x  (redo)
+;;
+;;
+;; What about redo-in-region? Obviously, this only makes sense if you have
+;; already undone some changes, so that there are some changes to redo!
+;; Redoing-in-region splits off a new branch of the undo history below your
+;; current location in the undo tree. This time, the new branch consists of a
+;; redo step that redoes some of the redo changes that affect the current
+;; region, followed by all the remaining redo changes.
+;;
+;;      Previous undo history                Redo-in-region
+;;
+;;               o                                o
+;;               |                                |
+;;               |                                |
+;;               x                                o
+;;               |                                |\
+;;               |                                | \
+;;               o                                o  x  (redo-in-region)
+;;               |                                |  |
+;;               |                                |  |
+;;               o                                o  o
+;;
+;; As long as you don't change the active region after redoing-in-region,
+;; continuing to redo-in-region extends the new branch, pulling more redo
+;; changes into a redo step immediately below your current location in the
+;; undo tree.
+;;
+;;      First redo-in-region                 Second redo-in-region
+;;
+;;          o                                     o
+;;          |                                     |
+;;          |                                     |
+;;          o                                     o
+;;          |\                                    |\
+;;          | \                                   | \
+;;          o  x  (redo-in-region)                o  o
+;;          |  |                                  |  |
+;;          |  |                                  |  |
+;;          o  o                                  o  x  (redo-in-region)
+;;                                                   |
+;;                                                   |
+;;                                                   o
+;;
+;; Note that undo-in-region and redo-in-region only ever add new changes to
+;; the undo tree, they *never* modify existing undo history. So you can always
+;; return to previous buffer states by switching to a previous branch of the
+;; tree.
+
+
+
+;;; Code:
+
+(eval-when-compile (require 'cl))
+(require 'diff)
+
+
+
+;;; =====================================================================
+;;;              Compatibility hacks for older Emacsen
+
+;; `characterp' isn't defined in Emacs versions < 23
+(unless (fboundp 'characterp)
+  (defalias 'characterp 'char-valid-p))
+
+;; `region-active-p' isn't defined in Emacs versions < 23
+(unless (fboundp 'region-active-p)
+  (defun region-active-p () (and transient-mark-mode mark-active)))
+
+
+;; `registerv' defstruct isn't defined in Emacs versions < 24
+(unless (fboundp 'registerv-make)
+  (defmacro registerv-make (data &rest _dummy) data))
+
+(unless (fboundp 'registerv-data)
+  (defmacro registerv-data (data) data))
+
+
+;; `diff-no-select' and `diff-file-local-copy' aren't defined in Emacs
+;; versions < 24 (copied and adapted from Emacs 24)
+(unless (fboundp 'diff-no-select)
+  (defun diff-no-select (old new &optional switches no-async buf)
+    ;; Noninteractive helper for creating and reverting diff buffers
+    (unless (bufferp new) (setq new (expand-file-name new)))
+    (unless (bufferp old) (setq old (expand-file-name old)))
+    (or switches (setq switches diff-switches)) ; If not specified, use default.
+    (unless (listp switches) (setq switches (list switches)))
+    (or buf (setq buf (get-buffer-create "*Diff*")))
+    (let* ((old-alt (diff-file-local-copy old))
+	   (new-alt (diff-file-local-copy new))
+	   (command
+	    (mapconcat 'identity
+		       `(,diff-command
+			 ;; Use explicitly specified switches
+			 ,@switches
+			 ,@(mapcar #'shell-quote-argument
+				   (nconc
+				    (when (or old-alt new-alt)
+				      (list "-L" (if (stringp old)
+						     old (prin1-to-string old))
+					    "-L" (if (stringp new)
+						     new (prin1-to-string new))))
+				    (list (or old-alt old)
+					  (or new-alt new)))))
+		       " "))
+	   (thisdir default-directory))
+      (with-current-buffer buf
+	(setq buffer-read-only t)
+	(buffer-disable-undo (current-buffer))
+	(let ((inhibit-read-only t))
+	  (erase-buffer))
+	(buffer-enable-undo (current-buffer))
+	(diff-mode)
+	(set (make-local-variable 'revert-buffer-function)
+	     (lambda (_ignore-auto _noconfirm)
+	       (diff-no-select old new switches no-async (current-buffer))))
+	(setq default-directory thisdir)
+	(let ((inhibit-read-only t))
+	  (insert command "\n"))
+	(if (and (not no-async) (fboundp 'start-process))
+	    (let ((proc (start-process "Diff" buf shell-file-name
+				       shell-command-switch command)))
+	      (set-process-filter proc 'diff-process-filter)
+	      (set-process-sentinel
+	       proc (lambda (proc _msg)
+		      (with-current-buffer (process-buffer proc)
+			(diff-sentinel (process-exit-status proc))
+			(if old-alt (delete-file old-alt))
+			(if new-alt (delete-file new-alt))))))
+	  ;; Async processes aren't available.
+	  (let ((inhibit-read-only t))
+	    (diff-sentinel
+	     (call-process shell-file-name nil buf nil
+			   shell-command-switch command))
+	    (if old-alt (delete-file old-alt))
+	    (if new-alt (delete-file new-alt)))))
+      buf)))
+
+(unless (fboundp 'diff-file-local-copy)
+  (defun diff-file-local-copy (file-or-buf)
+    (if (bufferp file-or-buf)
+	(with-current-buffer file-or-buf
+	  (let ((tempfile (make-temp-file "buffer-content-")))
+	    (write-region nil nil tempfile nil 'nomessage)
+	    tempfile))
+      (file-local-copy file-or-buf))))
+
+
+;; `user-error' isn't defined in Emacs < 24.3
+(unless (fboundp 'user-error)
+  (defalias 'user-error 'error)
+  ;; prevent debugger being called on user errors
+  (add-to-list 'debug-ignored-errors "^No further undo information")
+  (add-to-list 'debug-ignored-errors "^No further redo information")
+  (add-to-list 'debug-ignored-errors "^No further redo information for region"))
+
+
+
+
+
+;;; =====================================================================
+;;;              Global variables and customization options
+
+(defvar buffer-undo-tree nil
+  "Tree of undo entries in current buffer.")
+(put 'buffer-undo-tree 'permanent-local t)
+(make-variable-buffer-local 'buffer-undo-tree)
+
+
+(defgroup undo-tree nil
+  "Tree undo/redo."
+  :group 'undo)
+
+(defcustom undo-tree-mode-lighter " Undo-Tree"
+  "Lighter displayed in mode line
+when `undo-tree-mode' is enabled."
+  :group 'undo-tree
+  :type 'string)
+
+
+(defcustom undo-tree-incompatible-major-modes '(term-mode)
+  "List of major-modes in which `undo-tree-mode' should not be enabled.
+\(See `turn-on-undo-tree-mode'.\)"
+  :group 'undo-tree
+  :type '(repeat symbol))
+
+
+(defcustom undo-tree-enable-undo-in-region t
+  "When non-nil, enable undo-in-region.
+
+When undo-in-region is enabled, undoing or redoing when the
+region is active (in `transient-mark-mode') or with a prefix
+argument (not in `transient-mark-mode') only undoes changes
+within the current region."
+  :group 'undo-tree
+  :type 'boolean)
+
+
+(defcustom undo-tree-auto-save-history nil
+  "When non-nil, `undo-tree-mode' will save undo history to file
+when a buffer is saved to file.
+
+It will automatically load undo history when a buffer is loaded
+from file, if an undo save file exists.
+
+By default, undo-tree history is saved to a file called
+\".<buffer-file-name>.~undo-tree~\" in the same directory as the
+file itself. To save under a different directory, customize
+`undo-tree-history-directory-alist' (see the documentation for
+that variable for details).
+
+WARNING! `undo-tree-auto-save-history' will not work properly in
+Emacs versions prior to 24.3, so it cannot be enabled via
+the customization interface in versions earlier than that one. To
+ignore this warning and enable it regardless, set
+`undo-tree-auto-save-history' to a non-nil value outside of
+customize."
+  :group 'undo-tree
+  :type (if (version-list-< (version-to-list emacs-version) '(24 3))
+	    '(choice (const :tag "<disabled>" nil))
+	  'boolean))
+
+
+(defcustom undo-tree-history-directory-alist nil
+  "Alist of filename patterns and undo history directory names.
+Each element looks like (REGEXP . DIRECTORY).  Undo history for
+files with names matching REGEXP will be saved in DIRECTORY.
+DIRECTORY may be relative or absolute.  If it is absolute, so
+that all matching files are backed up into the same directory,
+the file names in this directory will be the full name of the
+file backed up with all directory separators changed to `!' to
+prevent clashes.  This will not work correctly if your filesystem
+truncates the resulting name.
+
+For the common case of all backups going into one directory, the
+alist should contain a single element pairing \".\" with the
+appropriate directory name.
+
+If this variable is nil, or it fails to match a filename, the
+backup is made in the original file's directory.
+
+On MS-DOS filesystems without long names this variable is always
+ignored."
+  :group 'undo-tree
+  :type '(repeat (cons (regexp :tag "Regexp matching filename")
+		       (directory :tag "Undo history directory name"))))
+
+
+
+(defcustom undo-tree-visualizer-relative-timestamps t
+  "When non-nil, display times relative to current time
+when displaying time stamps in visualizer.
+
+Otherwise, display absolute times."
+  :group 'undo-tree
+  :type 'boolean)
+
+
+(defcustom undo-tree-visualizer-timestamps nil
+  "When non-nil, display time-stamps by default
+in undo-tree visualizer.
+
+\\<undo-tree-visualizer-mode-map>You can always toggle time-stamps on and off \
+using \\[undo-tree-visualizer-toggle-timestamps], regardless of the
+setting of this variable."
+  :group 'undo-tree
+  :type 'boolean)
+
+
+(defcustom undo-tree-visualizer-diff nil
+  "When non-nil, display diff by default in undo-tree visualizer.
+
+\\<undo-tree-visualizer-mode-map>You can always toggle the diff display \
+using \\[undo-tree-visualizer-toggle-diff], regardless of the
+setting of this variable."
+  :group 'undo-tree
+  :type 'boolean)
+
+
+(defcustom undo-tree-visualizer-lazy-drawing 100
+  "When non-nil, use lazy undo-tree drawing in visualizer.
+
+Setting this to a number causes the visualizer to switch to lazy
+drawing when the number of nodes in the tree is larger than this
+value.
+
+Lazy drawing means that only the visible portion of the tree will
+be drawn initially, and the tree will be extended later as
+needed. For the most part, the only visible effect of this is to
+significantly speed up displaying the visualizer for very large
+trees.
+
+There is one potential negative effect of lazy drawing. Other
+branches of the tree will only be drawn once the node from which
+they branch off becomes visible. So it can happen that certain
+portions of the tree that would be shown with lazy drawing
+disabled, will not be drawn immediately when it is
+enabled. However, this effect is quite rare in practice."
+  :group 'undo-tree
+  :type '(choice (const :tag "never" nil)
+		 (const :tag "always" t)
+		 (integer :tag "> size")))
+
+
+(defface undo-tree-visualizer-default-face
+  '((((class color)) :foreground "gray"))
+  "Face used to draw undo-tree in visualizer."
+  :group 'undo-tree)
+
+(defface undo-tree-visualizer-current-face
+  '((((class color)) :foreground "red"))
+  "Face used to highlight current undo-tree node in visualizer."
+  :group 'undo-tree)
+
+(defface undo-tree-visualizer-active-branch-face
+  '((((class color) (background dark))
+     (:foreground "white" :weight bold))
+    (((class color) (background light))
+     (:foreground "black" :weight bold)))
+  "Face used to highlight active undo-tree branch in visualizer."
+  :group 'undo-tree)
+
+(defface undo-tree-visualizer-register-face
+  '((((class color)) :foreground "yellow"))
+  "Face used to highlight undo-tree nodes saved to a register
+in visualizer."
+  :group 'undo-tree)
+
+(defface undo-tree-visualizer-unmodified-face
+  '((((class color)) :foreground "cyan"))
+  "Face used to highlight nodes corresponding to unmodified buffers
+in visualizer."
+  :group 'undo-tree)
+
+
+(defvar undo-tree-visualizer-parent-buffer nil
+  "Parent buffer in visualizer.")
+(put 'undo-tree-visualizer-parent-buffer 'permanent-local t)
+(make-variable-buffer-local 'undo-tree-visualizer-parent-buffer)
+
+;; stores modification time of parent buffer's file, if any
+(defvar undo-tree-visualizer-parent-mtime nil)
+(put 'undo-tree-visualizer-parent-mtime 'permanent-local t)
+(make-variable-buffer-local 'undo-tree-visualizer-parent-mtime)
+
+;; stores current horizontal spacing needed for drawing undo-tree
+(defvar undo-tree-visualizer-spacing nil)
+(put 'undo-tree-visualizer-spacing 'permanent-local t)
+(make-variable-buffer-local 'undo-tree-visualizer-spacing)
+
+;; calculate horizontal spacing required for drawing tree with current
+;; settings
+(defsubst undo-tree-visualizer-calculate-spacing ()
+  (if undo-tree-visualizer-timestamps
+      (if undo-tree-visualizer-relative-timestamps 9 13)
+    3))
+
+;; holds node that was current when visualizer was invoked
+(defvar undo-tree-visualizer-initial-node nil)
+(put 'undo-tree-visualizer-initial-node 'permanent-local t)
+(make-variable-buffer-local 'undo-tree-visualizer-initial-node)
+
+;; holds currently selected node in visualizer selection mode
+(defvar undo-tree-visualizer-selected-node nil)
+(put 'undo-tree-visualizer-selected-node 'permanent-local t)
+(make-variable-buffer-local 'undo-tree-visualizer-selected)
+
+;; used to store nodes at edge of currently drawn portion of tree
+(defvar undo-tree-visualizer-needs-extending-down nil)
+(put 'undo-tree-visualizer-needs-extending-down 'permanent-local t)
+(make-variable-buffer-local 'undo-tree-visualizer-needs-extending-down)
+(defvar undo-tree-visualizer-needs-extending-up nil)
+(put 'undo-tree-visualizer-needs-extending-up 'permanent-local t)
+(make-variable-buffer-local 'undo-tree-visualizer-needs-extending-up)
+
+;; dynamically bound to t when undoing from visualizer, to inhibit
+;; `undo-tree-kill-visualizer' hook function in parent buffer
+(defvar undo-tree-inhibit-kill-visualizer nil)
+
+;; can be let-bound to a face name, used in drawing functions
+(defvar undo-tree-insert-face nil)
+
+;; visualizer buffer names
+(defconst undo-tree-visualizer-buffer-name " *undo-tree*")
+(defconst undo-tree-diff-buffer-name "*undo-tree Diff*")
+
+;; install history-auto-save hooks
+(add-hook 'write-file-functions 'undo-tree-save-history-hook)
+(add-hook 'find-file-hook 'undo-tree-load-history-hook)
+
+
+
+
+;;; =================================================================
+;;;                          Default keymaps
+
+(defvar undo-tree-map nil
+  "Keymap used in undo-tree-mode.")
+
+(unless undo-tree-map
+  (let ((map (make-sparse-keymap)))
+    ;; remap `undo' and `undo-only' to `undo-tree-undo'
+    (define-key map [remap undo] 'undo-tree-undo)
+    (define-key map [remap undo-only] 'undo-tree-undo)
+    ;; bind standard undo bindings (since these match redo counterparts)
+    (define-key map (kbd "C-/") 'undo-tree-undo)
+    (define-key map "\C-_" 'undo-tree-undo)
+    ;; redo doesn't exist normally, so define our own keybindings
+    (define-key map (kbd "C-?") 'undo-tree-redo)
+    (define-key map (kbd "M-_") 'undo-tree-redo)
+    ;; just in case something has defined `redo'...
+    (define-key map [remap redo] 'undo-tree-redo)
+    ;; we use "C-x u" for the undo-tree visualizer
+    (define-key map (kbd "\C-x u") 'undo-tree-visualize)
+    ;; bind register commands
+    (define-key map (kbd "C-x r u") 'undo-tree-save-state-to-register)
+    (define-key map (kbd "C-x r U") 'undo-tree-restore-state-from-register)
+    ;; set keymap
+    (setq undo-tree-map map)))
+
+
+(defvar undo-tree-visualizer-mode-map nil
+  "Keymap used in undo-tree visualizer.")
+
+(unless undo-tree-visualizer-mode-map
+  (let ((map (make-sparse-keymap)))
+    ;; vertical motion keys undo/redo
+    (define-key map [remap previous-line] 'undo-tree-visualize-undo)
+    (define-key map [remap next-line] 'undo-tree-visualize-redo)
+    (define-key map [up] 'undo-tree-visualize-undo)
+    (define-key map "p" 'undo-tree-visualize-undo)
+    (define-key map "\C-p" 'undo-tree-visualize-undo)
+    (define-key map [down] 'undo-tree-visualize-redo)
+    (define-key map "n" 'undo-tree-visualize-redo)
+    (define-key map "\C-n" 'undo-tree-visualize-redo)
+    ;; horizontal motion keys switch branch
+    (define-key map [remap forward-char]
+      'undo-tree-visualize-switch-branch-right)
+    (define-key map [remap backward-char]
+      'undo-tree-visualize-switch-branch-left)
+    (define-key map [right] 'undo-tree-visualize-switch-branch-right)
+    (define-key map "f" 'undo-tree-visualize-switch-branch-right)
+    (define-key map "\C-f" 'undo-tree-visualize-switch-branch-right)
+    (define-key map [left] 'undo-tree-visualize-switch-branch-left)
+    (define-key map "b" 'undo-tree-visualize-switch-branch-left)
+    (define-key map "\C-b" 'undo-tree-visualize-switch-branch-left)
+    ;; paragraph motion keys undo/redo to significant points in tree
+    (define-key map [remap backward-paragraph] 'undo-tree-visualize-undo-to-x)
+    (define-key map [remap forward-paragraph] 'undo-tree-visualize-redo-to-x)
+    (define-key map "\M-{" 'undo-tree-visualize-undo-to-x)
+    (define-key map "\M-}" 'undo-tree-visualize-redo-to-x)
+    (define-key map [C-up] 'undo-tree-visualize-undo-to-x)
+    (define-key map [C-down] 'undo-tree-visualize-redo-to-x)
+    ;; mouse sets buffer state to node at click
+    (define-key map [mouse-1] 'undo-tree-visualizer-mouse-set)
+    ;; toggle timestamps
+    (define-key map "t" 'undo-tree-visualizer-toggle-timestamps)
+    ;; toggle diff
+    (define-key map "d" 'undo-tree-visualizer-toggle-diff)
+    ;; toggle selection mode
+    (define-key map "s" 'undo-tree-visualizer-selection-mode)
+    ;; horizontal scrolling may be needed if the tree is very wide
+    (define-key map "," 'undo-tree-visualizer-scroll-left)
+    (define-key map "." 'undo-tree-visualizer-scroll-right)
+    (define-key map "<" 'undo-tree-visualizer-scroll-left)
+    (define-key map ">" 'undo-tree-visualizer-scroll-right)
+    ;; vertical scrolling may be needed if the tree is very tall
+    (define-key map [next] 'undo-tree-visualizer-scroll-up)
+    (define-key map [prior] 'undo-tree-visualizer-scroll-down)
+    ;; quit/abort visualizer
+    (define-key map "q" 'undo-tree-visualizer-quit)
+    (define-key map "\C-q" 'undo-tree-visualizer-abort)
+    ;; set keymap
+    (setq undo-tree-visualizer-mode-map map)))
+
+
+(defvar undo-tree-visualizer-selection-mode-map nil
+  "Keymap used in undo-tree visualizer selection mode.")
+
+(unless undo-tree-visualizer-selection-mode-map
+  (let ((map (make-sparse-keymap)))
+    ;; vertical motion keys move up and down tree
+    (define-key map [remap previous-line]
+      'undo-tree-visualizer-select-previous)
+    (define-key map [remap next-line]
+      'undo-tree-visualizer-select-next)
+    (define-key map [up] 'undo-tree-visualizer-select-previous)
+    (define-key map "p" 'undo-tree-visualizer-select-previous)
+    (define-key map "\C-p" 'undo-tree-visualizer-select-previous)
+    (define-key map [down] 'undo-tree-visualizer-select-next)
+    (define-key map "n" 'undo-tree-visualizer-select-next)
+    (define-key map "\C-n" 'undo-tree-visualizer-select-next)
+    ;; vertical scroll keys move up and down quickly
+    (define-key map [next]
+      (lambda () (interactive) (undo-tree-visualizer-select-next 10)))
+    (define-key map [prior]
+      (lambda () (interactive) (undo-tree-visualizer-select-previous 10)))
+    ;; horizontal motion keys move to left and right siblings
+    (define-key map [remap forward-char] 'undo-tree-visualizer-select-right)
+    (define-key map [remap backward-char] 'undo-tree-visualizer-select-left)
+    (define-key map [right] 'undo-tree-visualizer-select-right)
+    (define-key map "f" 'undo-tree-visualizer-select-right)
+    (define-key map "\C-f" 'undo-tree-visualizer-select-right)
+    (define-key map [left] 'undo-tree-visualizer-select-left)
+    (define-key map "b" 'undo-tree-visualizer-select-left)
+    (define-key map "\C-b" 'undo-tree-visualizer-select-left)
+    ;; horizontal scroll keys move left or right quickly
+    (define-key map ","
+      (lambda () (interactive) (undo-tree-visualizer-select-left 10)))
+    (define-key map "."
+      (lambda () (interactive) (undo-tree-visualizer-select-right 10)))
+    (define-key map "<"
+      (lambda () (interactive) (undo-tree-visualizer-select-left 10)))
+    (define-key map ">"
+      (lambda () (interactive) (undo-tree-visualizer-select-right 10)))
+    ;; <enter> sets buffer state to node at point
+    (define-key map "\r" 'undo-tree-visualizer-set)
+    ;; mouse selects node at click
+    (define-key map [mouse-1] 'undo-tree-visualizer-mouse-select)
+    ;; toggle diff
+    (define-key map "d" 'undo-tree-visualizer-selection-toggle-diff)
+    ;; set keymap
+    (setq undo-tree-visualizer-selection-mode-map map)))
+
+
+(defvar undo-tree-old-undo-menu-item nil)
+
+(defun undo-tree-update-menu-bar ()
+  "Update `undo-tree-mode' Edit menu items."
+  (if undo-tree-mode
+      (progn
+	;; save old undo menu item, and install undo/redo menu items
+	(setq undo-tree-old-undo-menu-item
+	      (cdr (assq 'undo (lookup-key global-map [menu-bar edit]))))
+	(define-key (lookup-key global-map [menu-bar edit])
+	  [undo] '(menu-item "Undo" undo-tree-undo
+			     :enable (and undo-tree-mode
+					  (not buffer-read-only)
+					  (not (eq t buffer-undo-list))
+					  (undo-tree-node-previous
+					   (undo-tree-current buffer-undo-tree)))
+			     :help "Undo last operation"))
+	(define-key-after (lookup-key global-map [menu-bar edit])
+	  [redo] '(menu-item "Redo" undo-tree-redo
+			     :enable (and undo-tree-mode
+					  (not buffer-read-only)
+					  (not (eq t buffer-undo-list))
+					  (undo-tree-node-next
+					   (undo-tree-current buffer-undo-tree)))
+			     :help "Redo last operation")
+	  'undo))
+    ;; uninstall undo/redo menu items
+    (define-key (lookup-key global-map [menu-bar edit])
+      [undo] undo-tree-old-undo-menu-item)
+    (define-key (lookup-key global-map [menu-bar edit])
+      [redo] nil)))
+
+(add-hook 'menu-bar-update-hook 'undo-tree-update-menu-bar)
+
+
+
+
+
+;;; =====================================================================
+;;;                     Undo-tree data structure
+
+(defstruct
+  (undo-tree
+   :named
+   (:constructor nil)
+   (:constructor make-undo-tree
+                 (&aux
+                  (root (undo-tree-make-node nil nil))
+                  (current root)
+                  (size 0)
+		  (count 0)
+		  (object-pool (make-hash-table :test 'eq :weakness 'value))))
+   ;;(:copier nil)
+   )
+  root current size count object-pool)
+
+
+
+(defstruct
+  (undo-tree-node
+   (:type vector)   ; create unnamed struct
+   (:constructor nil)
+   (:constructor undo-tree-make-node
+                 (previous undo
+		  &optional redo
+                  &aux
+                  (timestamp (current-time))
+                  (branch 0)))
+   (:constructor undo-tree-make-node-backwards
+                 (next-node undo
+		  &optional redo
+                  &aux
+                  (next (list next-node))
+                  (timestamp (current-time))
+                  (branch 0)))
+   (:copier nil))
+  previous next undo redo timestamp branch meta-data)
+
+
+(defmacro undo-tree-node-p (n)
+  (let ((len (length (undo-tree-make-node nil nil))))
+    `(and (vectorp ,n) (= (length ,n) ,len))))
+
+
+
+(defstruct
+  (undo-tree-region-data
+   (:type vector)   ; create unnamed struct
+   (:constructor nil)
+   (:constructor undo-tree-make-region-data
+		 (&optional undo-beginning undo-end
+			     redo-beginning redo-end))
+   (:constructor undo-tree-make-undo-region-data
+		 (undo-beginning undo-end))
+   (:constructor undo-tree-make-redo-region-data
+		 (redo-beginning redo-end))
+   (:copier nil))
+  undo-beginning undo-end redo-beginning redo-end)
+
+
+(defmacro undo-tree-region-data-p (r)
+  (let ((len (length (undo-tree-make-region-data))))
+    `(and (vectorp ,r) (= (length ,r) ,len))))
+
+(defmacro undo-tree-node-clear-region-data (node)
+  `(setf (undo-tree-node-meta-data ,node)
+	 (delq nil
+	       (delq :region
+		     (plist-put (undo-tree-node-meta-data ,node)
+				:region nil)))))
+
+
+(defmacro undo-tree-node-undo-beginning (node)
+  `(let ((r (plist-get (undo-tree-node-meta-data ,node) :region)))
+     (when (undo-tree-region-data-p r)
+       (undo-tree-region-data-undo-beginning r))))
+
+(defmacro undo-tree-node-undo-end (node)
+  `(let ((r (plist-get (undo-tree-node-meta-data ,node) :region)))
+     (when (undo-tree-region-data-p r)
+       (undo-tree-region-data-undo-end r))))
+
+(defmacro undo-tree-node-redo-beginning (node)
+  `(let ((r (plist-get (undo-tree-node-meta-data ,node) :region)))
+     (when (undo-tree-region-data-p r)
+       (undo-tree-region-data-redo-beginning r))))
+
+(defmacro undo-tree-node-redo-end (node)
+  `(let ((r (plist-get (undo-tree-node-meta-data ,node) :region)))
+     (when (undo-tree-region-data-p r)
+       (undo-tree-region-data-redo-end r))))
+
+
+(defsetf undo-tree-node-undo-beginning (node) (val)
+  `(let ((r (plist-get (undo-tree-node-meta-data ,node) :region)))
+     (unless (undo-tree-region-data-p r)
+       (setf (undo-tree-node-meta-data ,node)
+	     (plist-put (undo-tree-node-meta-data ,node) :region
+			(setq r (undo-tree-make-region-data)))))
+     (setf (undo-tree-region-data-undo-beginning r) ,val)))
+
+(defsetf undo-tree-node-undo-end (node) (val)
+  `(let ((r (plist-get (undo-tree-node-meta-data ,node) :region)))
+     (unless (undo-tree-region-data-p r)
+       (setf (undo-tree-node-meta-data ,node)
+	     (plist-put (undo-tree-node-meta-data ,node) :region
+			(setq r (undo-tree-make-region-data)))))
+     (setf (undo-tree-region-data-undo-end r) ,val)))
+
+(defsetf undo-tree-node-redo-beginning (node) (val)
+  `(let ((r (plist-get (undo-tree-node-meta-data ,node) :region)))
+     (unless (undo-tree-region-data-p r)
+       (setf (undo-tree-node-meta-data ,node)
+	     (plist-put (undo-tree-node-meta-data ,node) :region
+			(setq r (undo-tree-make-region-data)))))
+     (setf (undo-tree-region-data-redo-beginning r) ,val)))
+
+(defsetf undo-tree-node-redo-end (node) (val)
+  `(let ((r (plist-get (undo-tree-node-meta-data ,node) :region)))
+     (unless (undo-tree-region-data-p r)
+       (setf (undo-tree-node-meta-data ,node)
+	     (plist-put (undo-tree-node-meta-data ,node) :region
+			(setq r (undo-tree-make-region-data)))))
+     (setf (undo-tree-region-data-redo-end r) ,val)))
+
+
+
+(defstruct
+  (undo-tree-visualizer-data
+   (:type vector)   ; create unnamed struct
+   (:constructor nil)
+   (:constructor undo-tree-make-visualizer-data
+		 (&optional lwidth cwidth rwidth marker))
+   (:copier nil))
+  lwidth cwidth rwidth marker)
+
+
+(defmacro undo-tree-visualizer-data-p (v)
+  (let ((len (length (undo-tree-make-visualizer-data))))
+    `(and (vectorp ,v) (= (length ,v) ,len))))
+
+(defun undo-tree-node-clear-visualizer-data (node)
+  (let ((plist (undo-tree-node-meta-data node)))
+    (if (eq (car plist) :visualizer)
+	(setf (undo-tree-node-meta-data node) (nthcdr 2 plist))
+      (while (and plist (not (eq (cadr plist) :visualizer)))
+	(setq plist (cdr plist)))
+      (if plist (setcdr plist (nthcdr 3 plist))))))
+
+(defmacro undo-tree-node-lwidth (node)
+  `(let ((v (plist-get (undo-tree-node-meta-data ,node) :visualizer)))
+     (when (undo-tree-visualizer-data-p v)
+       (undo-tree-visualizer-data-lwidth v))))
+
+(defmacro undo-tree-node-cwidth (node)
+  `(let ((v (plist-get (undo-tree-node-meta-data ,node) :visualizer)))
+     (when (undo-tree-visualizer-data-p v)
+       (undo-tree-visualizer-data-cwidth v))))
+
+(defmacro undo-tree-node-rwidth (node)
+  `(let ((v (plist-get (undo-tree-node-meta-data ,node) :visualizer)))
+     (when (undo-tree-visualizer-data-p v)
+       (undo-tree-visualizer-data-rwidth v))))
+
+(defmacro undo-tree-node-marker (node)
+  `(let ((v (plist-get (undo-tree-node-meta-data ,node) :visualizer)))
+     (when (undo-tree-visualizer-data-p v)
+       (undo-tree-visualizer-data-marker v))))
+
+
+(defsetf undo-tree-node-lwidth (node) (val)
+  `(let ((v (plist-get (undo-tree-node-meta-data ,node) :visualizer)))
+     (unless (undo-tree-visualizer-data-p v)
+       (setf (undo-tree-node-meta-data ,node)
+	     (plist-put (undo-tree-node-meta-data ,node) :visualizer
+			(setq v (undo-tree-make-visualizer-data)))))
+     (setf (undo-tree-visualizer-data-lwidth v) ,val)))
+
+(defsetf undo-tree-node-cwidth (node) (val)
+  `(let ((v (plist-get (undo-tree-node-meta-data ,node) :visualizer)))
+     (unless (undo-tree-visualizer-data-p v)
+       (setf (undo-tree-node-meta-data ,node)
+	     (plist-put (undo-tree-node-meta-data ,node) :visualizer
+			(setq v (undo-tree-make-visualizer-data)))))
+     (setf (undo-tree-visualizer-data-cwidth v) ,val)))
+
+(defsetf undo-tree-node-rwidth (node) (val)
+  `(let ((v (plist-get (undo-tree-node-meta-data ,node) :visualizer)))
+     (unless (undo-tree-visualizer-data-p v)
+       (setf (undo-tree-node-meta-data ,node)
+	     (plist-put (undo-tree-node-meta-data ,node) :visualizer
+			(setq v (undo-tree-make-visualizer-data)))))
+     (setf (undo-tree-visualizer-data-rwidth v) ,val)))
+
+(defsetf undo-tree-node-marker (node) (val)
+  `(let ((v (plist-get (undo-tree-node-meta-data ,node) :visualizer)))
+     (unless (undo-tree-visualizer-data-p v)
+       (setf (undo-tree-node-meta-data ,node)
+	     (plist-put (undo-tree-node-meta-data ,node) :visualizer
+			(setq v (undo-tree-make-visualizer-data)))))
+     (setf (undo-tree-visualizer-data-marker v) ,val)))
+
+
+
+(defstruct
+  (undo-tree-register-data
+   (:type vector)
+   (:constructor nil)
+   (:constructor undo-tree-make-register-data (buffer node)))
+  buffer node)
+
+(defun undo-tree-register-data-p (data)
+  (and (vectorp data)
+       (= (length data) 2)
+       (undo-tree-node-p (undo-tree-register-data-node data))))
+
+(defun undo-tree-register-data-print-func (data)
+  (princ (format "an undo-tree state for buffer %s"
+		 (undo-tree-register-data-buffer data))))
+
+(defmacro undo-tree-node-register (node)
+  `(plist-get (undo-tree-node-meta-data ,node) :register))
+
+(defsetf undo-tree-node-register (node) (val)
+  `(setf (undo-tree-node-meta-data ,node)
+	 (plist-put (undo-tree-node-meta-data ,node) :register ,val)))
+
+
+
+
+;;; =====================================================================
+;;;              Basic undo-tree data structure functions
+
+(defun undo-tree-grow (undo)
+  "Add an UNDO node to current branch of `buffer-undo-tree'."
+  (let* ((current (undo-tree-current buffer-undo-tree))
+         (new (undo-tree-make-node current undo)))
+    (push new (undo-tree-node-next current))
+    (setf (undo-tree-current buffer-undo-tree) new)))
+
+
+(defun undo-tree-grow-backwards (node undo &optional redo)
+  "Add new node *above* undo-tree NODE, and return new node.
+Note that this will overwrite NODE's \"previous\" link, so should
+only be used on a detached NODE, never on nodes that are already
+part of `buffer-undo-tree'."
+  (let ((new (undo-tree-make-node-backwards node undo redo)))
+    (setf (undo-tree-node-previous node) new)
+    new))
+
+
+(defun undo-tree-splice-node (node splice)
+  "Splice NODE into undo tree, below node SPLICE.
+Note that this will overwrite NODE's \"next\" and \"previous\"
+links, so should only be used on a detached NODE, never on nodes
+that are already part of `buffer-undo-tree'."
+  (setf (undo-tree-node-next node) (undo-tree-node-next splice)
+	(undo-tree-node-branch node) (undo-tree-node-branch splice)
+	(undo-tree-node-previous node) splice
+	(undo-tree-node-next splice) (list node)
+	(undo-tree-node-branch splice) 0)
+  (dolist (n (undo-tree-node-next node))
+    (setf (undo-tree-node-previous n) node)))
+
+
+(defun undo-tree-snip-node (node)
+  "Snip NODE out of undo tree."
+  (let* ((parent (undo-tree-node-previous node))
+	 position p)
+    ;; if NODE is only child, replace parent's next links with NODE's
+    (if (= (length (undo-tree-node-next parent)) 0)
+	(setf (undo-tree-node-next parent) (undo-tree-node-next node)
+	      (undo-tree-node-branch parent) (undo-tree-node-branch node))
+      ;; otherwise...
+      (setq position (undo-tree-position node (undo-tree-node-next parent)))
+      (cond
+       ;; if active branch used do go via NODE, set parent's branch to active
+       ;; branch of NODE
+       ((= (undo-tree-node-branch parent) position)
+	(setf (undo-tree-node-branch parent)
+	      (+ position (undo-tree-node-branch node))))
+       ;; if active branch didn't go via NODE, update parent's branch to point
+       ;; to same node as before
+       ((> (undo-tree-node-branch parent) position)
+	(incf (undo-tree-node-branch parent)
+	      (1- (length (undo-tree-node-next node))))))
+      ;; replace NODE in parent's next list with NODE's entire next list
+      (if (= position 0)
+	  (setf (undo-tree-node-next parent)
+		(nconc (undo-tree-node-next node)
+		       (cdr (undo-tree-node-next parent))))
+	(setq p (nthcdr (1- position) (undo-tree-node-next parent)))
+	(setcdr p (nconc (undo-tree-node-next node) (cddr p)))))
+    ;; update previous links of NODE's children
+    (dolist (n (undo-tree-node-next node))
+      (setf (undo-tree-node-previous n) parent))))
+
+
+(defun undo-tree-mapc (--undo-tree-mapc-function-- node)
+  ;; Apply FUNCTION to NODE and to each node below it.
+  (let ((stack (list node))
+	n)
+    (while stack
+      (setq n (pop stack))
+      (funcall --undo-tree-mapc-function-- n)
+      (setq stack (append (undo-tree-node-next n) stack)))))
+
+
+(defmacro undo-tree-num-branches ()
+  "Return number of branches at current undo tree node."
+  '(length (undo-tree-node-next (undo-tree-current buffer-undo-tree))))
+
+
+(defun undo-tree-position (node list)
+  "Find the first occurrence of NODE in LIST.
+Return the index of the matching item, or nil of not found.
+Comparison is done with `eq'."
+  (let ((i 0))
+    (catch 'found
+      (while (progn
+               (when (eq node (car list)) (throw 'found i))
+               (incf i)
+               (setq list (cdr list))))
+      nil)))
+
+
+(defvar *undo-tree-id-counter* 0)
+(make-variable-buffer-local '*undo-tree-id-counter*)
+
+(defmacro undo-tree-generate-id ()
+  ;; Generate a new, unique id (uninterned symbol).
+  ;; The name is made by appending a number to "undo-tree-id".
+  ;; (Copied from CL package `gensym'.)
+  `(let ((num (prog1 *undo-tree-id-counter* (incf *undo-tree-id-counter*))))
+     (make-symbol (format "undo-tree-id%d" num))))
+
+
+(defun undo-tree-decircle (undo-tree)
+  ;; Nullify PREVIOUS links of UNDO-TREE nodes, to make UNDO-TREE data
+  ;; structure non-circular.
+  (undo-tree-mapc
+   (lambda (node)
+     (dolist (n (undo-tree-node-next node))
+       (setf (undo-tree-node-previous n) nil)))
+   (undo-tree-root undo-tree)))
+
+
+(defun undo-tree-recircle (undo-tree)
+  ;; Recreate PREVIOUS links of UNDO-TREE nodes, to restore circular UNDO-TREE
+  ;; data structure.
+  (undo-tree-mapc
+   (lambda (node)
+     (dolist (n (undo-tree-node-next node))
+       (setf (undo-tree-node-previous n) node)))
+   (undo-tree-root undo-tree)))
+
+
+
+
+;;; =====================================================================
+;;;             Undo list and undo changeset utility functions
+
+(defmacro undo-list-marker-elt-p (elt)
+  `(markerp (car-safe ,elt)))
+
+(defmacro undo-list-GCd-marker-elt-p (elt)
+  ;; Return t if ELT is a marker element whose marker has been moved to the
+  ;; object-pool, so may potentially have been garbage-collected.
+  ;; Note: Valid marker undo elements should be uniquely identified as cons
+  ;; cells with a symbol in the car (replacing the marker), and a number in
+  ;; the cdr. However, to guard against future changes to undo element
+  ;; formats, we perform an additional redundant check on the symbol name.
+  `(and (car-safe ,elt)
+	(symbolp (car ,elt))
+	(let ((str (symbol-name (car ,elt))))
+	  (and (> (length str) 12)
+	       (string= (substring str 0 12) "undo-tree-id")))
+	(numberp (cdr-safe ,elt))))
+
+
+(defun undo-tree-move-GC-elts-to-pool (elt)
+  ;; Move elements that can be garbage-collected into `buffer-undo-tree'
+  ;; object pool, substituting a unique id that can be used to retrieve them
+  ;; later. (Only markers require this treatment currently.)
+  (when (undo-list-marker-elt-p elt)
+    (let ((id (undo-tree-generate-id)))
+      (puthash id (car elt) (undo-tree-object-pool buffer-undo-tree))
+      (setcar elt id))))
+
+
+(defun undo-tree-restore-GC-elts-from-pool (elt)
+  ;; Replace object id's in ELT with corresponding objects from
+  ;; `buffer-undo-tree' object pool and return modified ELT, or return nil if
+  ;; any object in ELT has been garbage-collected.
+  (if (undo-list-GCd-marker-elt-p elt)
+      (when (setcar elt (gethash (car elt)
+				 (undo-tree-object-pool buffer-undo-tree)))
+	elt)
+    elt))
+
+
+(defun undo-list-clean-GCd-elts (undo-list)
+  ;; Remove object id's from UNDO-LIST that refer to elements that have been
+  ;; garbage-collected. UNDO-LIST is modified by side-effect.
+  (while (undo-list-GCd-marker-elt-p (car undo-list))
+    (unless (gethash (caar undo-list)
+		     (undo-tree-object-pool buffer-undo-tree))
+      (setq undo-list (cdr undo-list))))
+  (let ((p undo-list))
+    (while (cdr p)
+      (when (and (undo-list-GCd-marker-elt-p (cadr p))
+		 (null (gethash (car (cadr p))
+				(undo-tree-object-pool buffer-undo-tree))))
+	(setcdr p (cddr p)))
+      (setq p (cdr p))))
+  undo-list)
+
+
+(defun undo-list-pop-changeset (&optional discard-pos)
+  ;; Pop changeset from `buffer-undo-list'. If DISCARD-POS is non-nil, discard
+  ;; any position entries from changeset.
+
+  ;; discard undo boundaries and (if DISCARD-POS is non-nil) position entries
+  ;; at head of undo list
+  (while (or (null (car buffer-undo-list))
+	     (and discard-pos (integerp (car buffer-undo-list))))
+    (setq buffer-undo-list (cdr buffer-undo-list)))
+  ;; pop elements up to next undo boundary, discarding position entries if
+  ;; DISCARD-POS is non-nil
+  (if (eq (car buffer-undo-list) 'undo-tree-canary)
+      (push nil buffer-undo-list)
+    (let* ((changeset (list (pop buffer-undo-list)))
+           (p changeset))
+      (while (progn
+	       (undo-tree-move-GC-elts-to-pool (car p))
+	       (while (and discard-pos (integerp (car buffer-undo-list)))
+		 (setq buffer-undo-list (cdr buffer-undo-list)))
+	       (and (car buffer-undo-list)
+		    (not (eq (car buffer-undo-list) 'undo-tree-canary))))
+        (setcdr p (list (pop buffer-undo-list)))
+	(setq p (cdr p)))
+      changeset)))
+
+
+(defun undo-tree-copy-list (undo-list)
+  ;; Return a deep copy of first changeset in `undo-list'. Object id's are
+  ;; replaced by corresponding objects from `buffer-undo-tree' object-pool.
+  (when undo-list
+    (let (copy p)
+      ;; if first element contains an object id, replace it with object from
+      ;; pool, discarding element entirely if it's been GC'd
+      (while (null copy)
+	(setq copy
+	      (undo-tree-restore-GC-elts-from-pool (pop undo-list))))
+      (setq copy (list copy)
+	    p copy)
+      ;; copy remaining elements, replacing object id's with objects from
+      ;; pool, or discarding them entirely if they've been GC'd
+      (while undo-list
+	(when (setcdr p (undo-tree-restore-GC-elts-from-pool
+			 (undo-copy-list-1 (pop undo-list))))
+	  (setcdr p (list (cdr p)))
+	  (setq p (cdr p))))
+      copy)))
+
+
+
+(defun undo-list-transfer-to-tree ()
+  ;; Transfer entries accumulated in `buffer-undo-list' to `buffer-undo-tree'.
+
+  ;; `undo-list-transfer-to-tree' should never be called when undo is disabled
+  ;; (i.e. `buffer-undo-tree' is t)
+  (assert (not (eq buffer-undo-tree t)))
+
+  ;; if `buffer-undo-tree' is empty, create initial undo-tree
+  (when (null buffer-undo-tree) (setq buffer-undo-tree (make-undo-tree)))
+  ;; make sure there's a canary at end of `buffer-undo-list'
+  (when (null buffer-undo-list)
+    (setq buffer-undo-list '(nil undo-tree-canary)))
+
+  (unless (or (eq (cadr buffer-undo-list) 'undo-tree-canary)
+	      (eq (car buffer-undo-list) 'undo-tree-canary))
+    ;; create new node from first changeset in `buffer-undo-list', save old
+    ;; `buffer-undo-tree' current node, and make new node the current node
+    (let* ((node (undo-tree-make-node nil (undo-list-pop-changeset)))
+	   (splice (undo-tree-current buffer-undo-tree))
+	   (size (undo-list-byte-size (undo-tree-node-undo node)))
+	   (count 1))
+      (setf (undo-tree-current buffer-undo-tree) node)
+      ;; grow tree fragment backwards using `buffer-undo-list' changesets
+      (while (and buffer-undo-list
+		  (not (eq (cadr buffer-undo-list) 'undo-tree-canary)))
+	(setq node
+	      (undo-tree-grow-backwards node (undo-list-pop-changeset)))
+	(incf size (undo-list-byte-size (undo-tree-node-undo node)))
+	(incf count))
+      ;; if no undo history has been discarded from `buffer-undo-list' since
+      ;; last transfer, splice new tree fragment onto end of old
+      ;; `buffer-undo-tree' current node
+      (if (or (eq (cadr buffer-undo-list) 'undo-tree-canary)
+	      (eq (car buffer-undo-list) 'undo-tree-canary))
+	  (progn
+	    (setf (undo-tree-node-previous node) splice)
+	    (push node (undo-tree-node-next splice))
+	    (setf (undo-tree-node-branch splice) 0)
+	    (incf (undo-tree-size buffer-undo-tree) size)
+	    (incf (undo-tree-count buffer-undo-tree) count))
+	;; if undo history has been discarded, replace entire
+	;; `buffer-undo-tree' with new tree fragment
+	(setq node (undo-tree-grow-backwards node nil))
+	(setf (undo-tree-root buffer-undo-tree) node)
+	(setq buffer-undo-list '(nil undo-tree-canary))
+	(setf (undo-tree-size buffer-undo-tree) size)
+	(setf (undo-tree-count buffer-undo-tree) count)
+	(setq buffer-undo-list '(nil undo-tree-canary))))
+    ;; discard undo history if necessary
+    (undo-tree-discard-history)))
+
+
+(defun undo-list-byte-size (undo-list)
+  ;; Return size (in bytes) of UNDO-LIST
+  (let ((size 0) (p undo-list))
+    (while p
+      (incf size 8)  ; cons cells use up 8 bytes
+      (when (and (consp (car p)) (stringp (caar p)))
+        (incf size (string-bytes (caar p))))
+      (setq p (cdr p)))
+    size))
+
+
+
+(defun undo-list-rebuild-from-tree ()
+  "Rebuild `buffer-undo-list' from information in `buffer-undo-tree'."
+  (unless (eq buffer-undo-list t)
+    (undo-list-transfer-to-tree)
+    (setq buffer-undo-list nil)
+    (when buffer-undo-tree
+      (let ((stack (list (list (undo-tree-root buffer-undo-tree)))))
+	(push (sort (mapcar 'identity (undo-tree-node-next (caar stack)))
+		    (lambda (a b)
+		      (time-less-p (undo-tree-node-timestamp a)
+				   (undo-tree-node-timestamp b))))
+	      stack)
+	;; Traverse tree in depth-and-oldest-first order, but add undo records
+	;; on the way down, and redo records on the way up.
+	(while (or (car stack)
+		   (not (eq (car (nth 1 stack))
+			    (undo-tree-current buffer-undo-tree))))
+	  (if (car stack)
+	      (progn
+		(setq buffer-undo-list
+		      (append (undo-tree-node-undo (caar stack))
+			      buffer-undo-list))
+		(undo-boundary)
+		(push (sort (mapcar 'identity
+				    (undo-tree-node-next (caar stack)))
+			    (lambda (a b)
+			      (time-less-p (undo-tree-node-timestamp a)
+					   (undo-tree-node-timestamp b))))
+		      stack))
+	    (pop stack)
+	    (setq buffer-undo-list
+		  (append (undo-tree-node-redo (caar stack))
+			  buffer-undo-list))
+	    (undo-boundary)
+	    (pop (car stack))))))))
+
+
+
+
+;;; =====================================================================
+;;;                History discarding utility functions
+
+(defun undo-tree-oldest-leaf (node)
+  ;; Return oldest leaf node below NODE.
+  (while (undo-tree-node-next node)
+    (setq node
+          (car (sort (mapcar 'identity (undo-tree-node-next node))
+                     (lambda (a b)
+                       (time-less-p (undo-tree-node-timestamp a)
+                                    (undo-tree-node-timestamp b)))))))
+  node)
+
+
+(defun undo-tree-discard-node (node)
+  ;; Discard NODE from `buffer-undo-tree', and return next in line for
+  ;; discarding.
+
+  ;; don't discard current node
+  (unless (eq node (undo-tree-current buffer-undo-tree))
+
+    ;; discarding root node...
+    (if (eq node (undo-tree-root buffer-undo-tree))
+        (cond
+         ;; should always discard branches before root
+         ((> (length (undo-tree-node-next node)) 1)
+          (error "Trying to discard undo-tree root which still\
+ has multiple branches"))
+         ;; don't discard root if current node is only child
+         ((eq (car (undo-tree-node-next node))
+              (undo-tree-current buffer-undo-tree))
+	  nil)
+	 ;; discard root
+         (t
+	  ;; clear any register referring to root
+	  (let ((r (undo-tree-node-register node)))
+	    (when (and r (eq (get-register r) node))
+	      (set-register r nil)))
+          ;; make child of root into new root
+          (setq node (setf (undo-tree-root buffer-undo-tree)
+                           (car (undo-tree-node-next node))))
+	  ;; update undo-tree size
+	  (decf (undo-tree-size buffer-undo-tree)
+		(+ (undo-list-byte-size (undo-tree-node-undo node))
+		   (undo-list-byte-size (undo-tree-node-redo node))))
+	  (decf (undo-tree-count buffer-undo-tree))
+	  ;; discard new root's undo data and PREVIOUS link
+	  (setf (undo-tree-node-undo node) nil
+		(undo-tree-node-redo node) nil
+		(undo-tree-node-previous node) nil)
+          ;; if new root has branches, or new root is current node, next node
+          ;; to discard is oldest leaf, otherwise it's new root
+          (if (or (> (length (undo-tree-node-next node)) 1)
+                  (eq (car (undo-tree-node-next node))
+                      (undo-tree-current buffer-undo-tree)))
+              (undo-tree-oldest-leaf node)
+            node)))
+
+      ;; discarding leaf node...
+      (let* ((parent (undo-tree-node-previous node))
+             (current (nth (undo-tree-node-branch parent)
+                           (undo-tree-node-next parent))))
+	;; clear any register referring to the discarded node
+	(let ((r (undo-tree-node-register node)))
+	  (when (and r (eq (get-register r) node))
+	    (set-register r nil)))
+	;; update undo-tree size
+	(decf (undo-tree-size buffer-undo-tree)
+	      (+ (undo-list-byte-size (undo-tree-node-undo node))
+		 (undo-list-byte-size (undo-tree-node-redo node))))
+	(decf (undo-tree-count buffer-undo-tree))
+	;; discard leaf
+        (setf (undo-tree-node-next parent)
+                (delq node (undo-tree-node-next parent))
+              (undo-tree-node-branch parent)
+                (undo-tree-position current (undo-tree-node-next parent)))
+        ;; if parent has branches, or parent is current node, next node to
+        ;; discard is oldest leaf, otherwise it's the parent itself
+        (if (or (eq parent (undo-tree-current buffer-undo-tree))
+                (and (undo-tree-node-next parent)
+                     (or (not (eq parent (undo-tree-root buffer-undo-tree)))
+                         (> (length (undo-tree-node-next parent)) 1))))
+            (undo-tree-oldest-leaf parent)
+          parent)))))
+
+
+
+(defun undo-tree-discard-history ()
+  "Discard undo history until we're within memory usage limits
+set by `undo-limit', `undo-strong-limit' and `undo-outer-limit'."
+
+  (when (> (undo-tree-size buffer-undo-tree) undo-limit)
+    ;; if there are no branches off root, first node to discard is root;
+    ;; otherwise it's leaf node at botom of oldest branch
+    (let ((node (if (> (length (undo-tree-node-next
+                                (undo-tree-root buffer-undo-tree))) 1)
+                    (undo-tree-oldest-leaf (undo-tree-root buffer-undo-tree))
+                  (undo-tree-root buffer-undo-tree))))
+
+      ;; discard nodes until memory use is within `undo-strong-limit'
+      (while (and node
+                  (> (undo-tree-size buffer-undo-tree) undo-strong-limit))
+        (setq node (undo-tree-discard-node node)))
+
+      ;; discard nodes until next node to discard would bring memory use
+      ;; within `undo-limit'
+      (while (and node
+		  ;; check first if last discard has brought us within
+		  ;; `undo-limit', in case we can avoid more expensive
+		  ;; `undo-strong-limit' calculation
+		  ;; Note: this assumes undo-strong-limit > undo-limit;
+		  ;;       if not, effectively undo-strong-limit = undo-limit
+		  (> (undo-tree-size buffer-undo-tree) undo-limit)
+                  (> (- (undo-tree-size buffer-undo-tree)
+			;; if next node to discard is root, the memory we
+			;; free-up comes from discarding changesets from its
+			;; only child...
+			(if (eq node (undo-tree-root buffer-undo-tree))
+			    (+ (undo-list-byte-size
+				(undo-tree-node-undo
+				 (car (undo-tree-node-next node))))
+			       (undo-list-byte-size
+				(undo-tree-node-redo
+				 (car (undo-tree-node-next node)))))
+			  ;; ...otherwise, it comes from discarding changesets
+			  ;; from along with the node itself
+			  (+ (undo-list-byte-size (undo-tree-node-undo node))
+			     (undo-list-byte-size (undo-tree-node-redo node)))
+			  ))
+                     undo-limit))
+        (setq node (undo-tree-discard-node node)))
+
+      ;; if we're still over the `undo-outer-limit', discard entire history
+      (when (> (undo-tree-size buffer-undo-tree) undo-outer-limit)
+        ;; query first if `undo-ask-before-discard' is set
+        (if undo-ask-before-discard
+            (when (yes-or-no-p
+                   (format
+                    "Buffer `%s' undo info is %d bytes long;  discard it? "
+                    (buffer-name) (undo-tree-size buffer-undo-tree)))
+              (setq buffer-undo-tree nil))
+          ;; otherwise, discard and display warning
+          (display-warning
+           '(undo discard-info)
+           (concat
+            (format "Buffer `%s' undo info was %d bytes long.\n"
+                    (buffer-name) (undo-tree-size buffer-undo-tree))
+            "The undo info was discarded because it exceeded\
+ `undo-outer-limit'.
+
+This is normal if you executed a command that made a huge change
+to the buffer. In that case, to prevent similar problems in the
+future, set `undo-outer-limit' to a value that is large enough to
+cover the maximum size of normal changes you expect a single
+command to make, but not so large that it might exceed the
+maximum memory allotted to Emacs.
+
+If you did not execute any such command, the situation is
+probably due to a bug and you should report it.
+
+You can disable the popping up of this buffer by adding the entry
+\(undo discard-info) to the user option `warning-suppress-types',
+which is defined in the `warnings' library.\n")
+           :warning)
+          (setq buffer-undo-tree nil)))
+      )))
+
+
+
+
+;;; =====================================================================
+;;;                   Visualizer utility functions
+
+(defun undo-tree-compute-widths (node)
+  "Recursively compute widths for nodes below NODE."
+  (let ((stack (list node))
+        res)
+    (while stack
+      ;; try to compute widths for node at top of stack
+      (if (undo-tree-node-p
+           (setq res (undo-tree-node-compute-widths (car stack))))
+          ;; if computation fails, it returns a node whose widths still need
+          ;; computing, which we push onto the stack
+          (push res stack)
+        ;; otherwise, store widths and remove it from stack
+        (setf (undo-tree-node-lwidth (car stack)) (aref res 0)
+              (undo-tree-node-cwidth (car stack)) (aref res 1)
+              (undo-tree-node-rwidth (car stack)) (aref res 2))
+        (pop stack)))))
+
+
+(defun undo-tree-node-compute-widths (node)
+  ;; Compute NODE's left-, centre-, and right-subtree widths. Returns widths
+  ;; (in a vector) if successful. Otherwise, returns a node whose widths need
+  ;; calculating before NODE's can be calculated.
+  (let ((num-children (length (undo-tree-node-next node)))
+        (lwidth 0) (cwidth 0) (rwidth 0) p)
+    (catch 'need-widths
+      (cond
+       ;; leaf nodes have 0 width
+       ((= 0 num-children)
+        (setf cwidth 1
+              (undo-tree-node-lwidth node) 0
+              (undo-tree-node-cwidth node) 1
+              (undo-tree-node-rwidth node) 0))
+
+       ;; odd number of children
+       ((= (mod num-children 2) 1)
+        (setq p (undo-tree-node-next node))
+        ;; compute left-width
+        (dotimes (i (/ num-children 2))
+          (if (undo-tree-node-lwidth (car p))
+              (incf lwidth (+ (undo-tree-node-lwidth (car p))
+                              (undo-tree-node-cwidth (car p))
+                              (undo-tree-node-rwidth (car p))))
+            ;; if child's widths haven't been computed, return that child
+            (throw 'need-widths (car p)))
+          (setq p (cdr p)))
+        (if (undo-tree-node-lwidth (car p))
+            (incf lwidth (undo-tree-node-lwidth (car p)))
+          (throw 'need-widths (car p)))
+        ;; centre-width is inherited from middle child
+        (setf cwidth (undo-tree-node-cwidth (car p)))
+        ;; compute right-width
+        (incf rwidth (undo-tree-node-rwidth (car p)))
+        (setq p (cdr p))
+        (dotimes (i (/ num-children 2))
+          (if (undo-tree-node-lwidth (car p))
+              (incf rwidth (+ (undo-tree-node-lwidth (car p))
+                              (undo-tree-node-cwidth (car p))
+                              (undo-tree-node-rwidth (car p))))
+            (throw 'need-widths (car p)))
+          (setq p (cdr p))))
+
+       ;; even number of children
+       (t
+        (setq p (undo-tree-node-next node))
+        ;; compute left-width
+        (dotimes (i (/ num-children 2))
+          (if (undo-tree-node-lwidth (car p))
+              (incf lwidth (+ (undo-tree-node-lwidth (car p))
+                              (undo-tree-node-cwidth (car p))
+                              (undo-tree-node-rwidth (car p))))
+            (throw 'need-widths (car p)))
+          (setq p (cdr p)))
+        ;; centre-width is 0 when number of children is even
+        (setq cwidth 0)
+        ;; compute right-width
+        (dotimes (i (/ num-children 2))
+          (if (undo-tree-node-lwidth (car p))
+              (incf rwidth (+ (undo-tree-node-lwidth (car p))
+                              (undo-tree-node-cwidth (car p))
+                              (undo-tree-node-rwidth (car p))))
+            (throw 'need-widths (car p)))
+          (setq p (cdr p)))))
+
+      ;; return left-, centre- and right-widths
+      (vector lwidth cwidth rwidth))))
+
+
+(defun undo-tree-clear-visualizer-data (tree)
+  ;; Clear visualizer data below NODE.
+  (undo-tree-mapc
+   (lambda (n) (undo-tree-node-clear-visualizer-data n))
+   (undo-tree-root tree)))
+
+
+(defun undo-tree-node-unmodified-p (node &optional mtime)
+  ;; Return non-nil if NODE corresponds to a buffer state that once upon a
+  ;; time was unmodified. If a file modification time MTIME is specified,
+  ;; return non-nil if the corresponding buffer state really is unmodified.
+  (let (changeset ntime)
+    (setq changeset
+	  (or (undo-tree-node-redo node)
+	      (and (setq changeset (car (undo-tree-node-next node)))
+		   (undo-tree-node-undo changeset)))
+	  ntime
+	  (catch 'found
+	    (dolist (elt changeset)
+	      (when (and (consp elt) (eq (car elt) t) (consp (cdr elt))
+			 (throw 'found (cdr elt)))))))
+    (and ntime
+	 (or (null mtime)
+	     ;; high-precision timestamps
+	     (if (listp (cdr ntime))
+		 (equal ntime mtime)
+	       ;; old-style timestamps
+	       (and (= (car ntime) (car mtime))
+		    (= (cdr ntime) (cadr mtime))))))))
+
+
+
+
+;;; =====================================================================
+;;;                  Undo-in-region utility functions
+
+;; `undo-elt-in-region' uses this as a dynamically-scoped variable
+(defvar undo-adjusted-markers nil)
+
+
+(defun undo-tree-pull-undo-in-region-branch (start end)
+  ;; Pull out entries from undo changesets to create a new undo-in-region
+  ;; branch, which undoes changeset entries lying between START and END first,
+  ;; followed by remaining entries from the changesets, before rejoining the
+  ;; existing undo tree history. Repeated calls will, if appropriate, extend
+  ;; the current undo-in-region branch rather than creating a new one.
+
+  ;; if we're just reverting the last redo-in-region, we don't need to
+  ;; manipulate the undo tree at all
+  (if (undo-tree-reverting-redo-in-region-p start end)
+      t  ; return t to indicate success
+
+    ;; We build the `region-changeset' and `delta-list' lists forwards, using
+    ;; pointers `r' and `d' to the penultimate element of the list. So that we
+    ;; don't have to treat the first element differently, we prepend a dummy
+    ;; leading nil to the lists, and have the pointers point to that
+    ;; initially.
+    ;; Note: using '(nil) instead of (list nil) in the `let*' results in
+    ;;       bizarre errors when the code is byte-compiled, where parts of the
+    ;;       lists appear to survive across different calls to this function.
+    ;;       An obscure byte-compiler bug, perhaps?
+    (let* ((region-changeset (list nil))
+	   (r region-changeset)
+	   (delta-list (list nil))
+	   (d delta-list)
+	   (node (undo-tree-current buffer-undo-tree))
+	   (repeated-undo-in-region
+	    (undo-tree-repeated-undo-in-region-p start end))
+	   undo-adjusted-markers  ; `undo-elt-in-region' expects this
+	   fragment splice original-fragment original-splice original-current
+	   got-visible-elt undo-list elt)
+
+      ;; --- initialisation ---
+      (cond
+       ;; if this is a repeated undo in the same region, start pulling changes
+       ;; from NODE at which undo-in-region branch iss attached, and detatch
+       ;; the branch, using it as initial FRAGMENT of branch being constructed
+       (repeated-undo-in-region
+	(setq original-current node
+	      fragment (car (undo-tree-node-next node))
+	      splice node)
+	;; undo up to node at which undo-in-region branch is attached
+	;; (recognizable as first node with more than one branch)
+	(let ((mark-active nil))
+	  (while (= (length (undo-tree-node-next node)) 1)
+	    (undo-tree-undo-1)
+	    (setq fragment node
+		  node (undo-tree-current buffer-undo-tree))))
+	(when (eq splice node) (setq splice nil))
+	;; detatch undo-in-region branch
+	(setf (undo-tree-node-next node)
+	      (delq fragment (undo-tree-node-next node))
+	      (undo-tree-node-previous fragment) nil
+	      original-fragment fragment
+	      original-splice node))
+
+       ;; if this is a new undo-in-region, initial FRAGMENT is a copy of all
+       ;; nodes below the current one in the active branch
+       ((undo-tree-node-next node)
+	(setq fragment (undo-tree-make-node nil nil)
+	      splice fragment)
+	(while (setq node (nth (undo-tree-node-branch node)
+			       (undo-tree-node-next node)))
+	  (push (undo-tree-make-node
+		 splice
+		 (undo-copy-list (undo-tree-node-undo node))
+		 (undo-copy-list (undo-tree-node-redo node)))
+		(undo-tree-node-next splice))
+	  (setq splice (car (undo-tree-node-next splice))))
+	(setq fragment (car (undo-tree-node-next fragment))
+	      splice nil
+	      node (undo-tree-current buffer-undo-tree))))
+
+
+      ;; --- pull undo-in-region elements into branch ---
+      ;; work backwards up tree, pulling out undo elements within region until
+      ;; we've got one that undoes a visible change (insertion or deletion)
+      (catch 'abort
+	(while (and (not got-visible-elt) node (undo-tree-node-undo node))
+	  ;; we cons a dummy nil element on the front of the changeset so that
+	  ;; we can conveniently remove the first (real) element from the
+	  ;; changeset if we need to; the leading nil is removed once we're
+	  ;; done with this changeset
+	  (setq undo-list (cons nil (undo-copy-list (undo-tree-node-undo node)))
+		elt (cadr undo-list))
+	  (if fragment
+	      (progn
+		(setq fragment (undo-tree-grow-backwards fragment undo-list))
+		(unless splice (setq splice fragment)))
+	    (setq fragment (undo-tree-make-node nil undo-list))
+	    (setq splice fragment))
+
+	  (while elt
+	    (cond
+	     ;; keep elements within region
+	     ((undo-elt-in-region elt start end)
+	      ;; set flag if kept element is visible (insertion or deletion)
+	      (when (and (consp elt)
+			 (or (stringp (car elt)) (integerp (car elt))))
+		(setq got-visible-elt t))
+	      ;; adjust buffer positions in elements previously undone before
+	      ;; kept element, as kept element will now be undone first
+	      (undo-tree-adjust-elements-to-elt splice elt)
+	      ;; move kept element to undo-in-region changeset, adjusting its
+	      ;; buffer position as it will now be undone first
+	      (setcdr r (list (undo-tree-apply-deltas elt (cdr delta-list))))
+	      (setq r (cdr r))
+	      (setcdr undo-list (cddr undo-list)))
+
+	     ;; discard "was unmodified" elements
+	     ;; FIXME: deal properly with these
+	     ((and (consp elt) (eq (car elt) t))
+	      (setcdr undo-list (cddr undo-list)))
+
+	     ;; if element crosses region, we can't pull any more elements
+	     ((undo-elt-crosses-region elt start end)
+	      ;; if we've found a visible element, it must be earlier in
+	      ;; current node's changeset; stop pulling elements (null
+	      ;; `undo-list' and non-nil `got-visible-elt' cause loop to exit)
+	      (if got-visible-elt
+		  (setq undo-list nil)
+		;; if we haven't found a visible element yet, pulling
+		;; undo-in-region branch has failed
+		(setq region-changeset nil)
+		(throw 'abort t)))
+
+	     ;; if rejecting element, add its delta (if any) to the list
+	     (t
+	      (let ((delta (undo-delta elt)))
+		(when (/= 0 (cdr delta))
+		  (setcdr d (list delta))
+		  (setq d (cdr d))))
+	      (setq undo-list (cdr undo-list))))
+
+	    ;; process next element of current changeset
+	    (setq elt (cadr undo-list)))
+
+	  ;; if there are remaining elements in changeset, remove dummy nil
+	  ;; from front
+	  (if (cadr (undo-tree-node-undo fragment))
+	      (pop (undo-tree-node-undo fragment))
+	    ;; otherwise, if we've kept all elements in changeset, discard
+	    ;; empty changeset
+	    (when (eq splice fragment) (setq splice nil))
+	    (setq fragment (car (undo-tree-node-next fragment))))
+	  ;; process changeset from next node up the tree
+	  (setq node (undo-tree-node-previous node))))
+
+      ;; pop dummy nil from front of `region-changeset'
+      (setq region-changeset (cdr region-changeset))
+
+
+      ;; --- integrate branch into tree ---
+      ;; if no undo-in-region elements were found, restore undo tree
+      (if (null region-changeset)
+	  (when original-current
+	    (push original-fragment (undo-tree-node-next original-splice))
+	    (setf (undo-tree-node-branch original-splice) 0
+		  (undo-tree-node-previous original-fragment) original-splice)
+	    (let ((mark-active nil))
+	      (while (not (eq (undo-tree-current buffer-undo-tree)
+			      original-current))
+		(undo-tree-redo-1)))
+	    nil)  ; return nil to indicate failure
+
+	;; otherwise...
+	;; need to undo up to node where new branch will be attached, to
+	;; ensure redo entries are populated, and then redo back to where we
+	;; started
+	(let ((mark-active nil)
+	      (current (undo-tree-current buffer-undo-tree)))
+	  (while (not (eq (undo-tree-current buffer-undo-tree) node))
+	    (undo-tree-undo-1))
+	  (while (not (eq (undo-tree-current buffer-undo-tree) current))
+	    (undo-tree-redo-1)))
+
+	(cond
+	 ;; if there's no remaining fragment, just create undo-in-region node
+	 ;; and attach it to parent of last node from which elements were
+	 ;; pulled
+	 ((null fragment)
+	  (setq fragment (undo-tree-make-node node region-changeset))
+	  (push fragment (undo-tree-node-next node))
+	  (setf (undo-tree-node-branch node) 0)
+	  ;; set current node to undo-in-region node
+	  (setf (undo-tree-current buffer-undo-tree) fragment))
+
+	 ;; if no splice point has been set, add undo-in-region node to top of
+	 ;; fragment and attach it to parent of last node from which elements
+	 ;; were pulled
+	 ((null splice)
+	  (setq fragment (undo-tree-grow-backwards fragment region-changeset))
+	  (push fragment (undo-tree-node-next node))
+	  (setf (undo-tree-node-branch node) 0
+		(undo-tree-node-previous fragment) node)
+	  ;; set current node to undo-in-region node
+	  (setf (undo-tree-current buffer-undo-tree) fragment))
+
+	 ;; if fragment contains nodes, attach fragment to parent of last node
+	 ;; from which elements were pulled, and splice in undo-in-region node
+	 (t
+	  (setf (undo-tree-node-previous fragment) node)
+	  (push fragment (undo-tree-node-next node))
+	  (setf (undo-tree-node-branch node) 0)
+	  ;; if this is a repeated undo-in-region, then we've left the current
+	  ;; node at the original splice-point; we need to set the current
+	  ;; node to the equivalent node on the undo-in-region branch and redo
+	  ;; back to where we started
+	  (when repeated-undo-in-region
+	    (setf (undo-tree-current buffer-undo-tree)
+		  (undo-tree-node-previous original-fragment))
+	    (let ((mark-active nil))
+	      (while (not (eq (undo-tree-current buffer-undo-tree) splice))
+		(undo-tree-redo-1 nil 'preserve-undo))))
+	  ;; splice new undo-in-region node into fragment
+	  (setq node (undo-tree-make-node nil region-changeset))
+	  (undo-tree-splice-node node splice)
+	  ;; set current node to undo-in-region node
+	  (setf (undo-tree-current buffer-undo-tree) node)))
+
+	;; update undo-tree size
+	(setq node (undo-tree-node-previous fragment))
+	(while (progn
+		 (and (setq node (car (undo-tree-node-next node)))
+		      (not (eq node original-fragment))
+		      (incf (undo-tree-count buffer-undo-tree))
+		      (incf (undo-tree-size buffer-undo-tree)
+			    (+ (undo-list-byte-size (undo-tree-node-undo node))
+			       (undo-list-byte-size (undo-tree-node-redo node)))))))
+	t)  ; indicate undo-in-region branch was successfully pulled
+      )))
+
+
+
+(defun undo-tree-pull-redo-in-region-branch (start end)
+  ;; Pull out entries from redo changesets to create a new redo-in-region
+  ;; branch, which redoes changeset entries lying between START and END first,
+  ;; followed by remaining entries from the changesets. Repeated calls will,
+  ;; if appropriate, extend the current redo-in-region branch rather than
+  ;; creating a new one.
+
+  ;; if we're just reverting the last undo-in-region, we don't need to
+  ;; manipulate the undo tree at all
+  (if (undo-tree-reverting-undo-in-region-p start end)
+      t  ; return t to indicate success
+
+    ;; We build the `region-changeset' and `delta-list' lists forwards, using
+    ;; pointers `r' and `d' to the penultimate element of the list. So that we
+    ;; don't have to treat the first element differently, we prepend a dummy
+    ;; leading nil to the lists, and have the pointers point to that
+    ;; initially.
+    ;; Note: using '(nil) instead of (list nil) in the `let*' causes bizarre
+    ;;       errors when the code is byte-compiled, where parts of the lists
+    ;;       appear to survive across different calls to this function.  An
+    ;;       obscure byte-compiler bug, perhaps?
+    (let* ((region-changeset (list nil))
+	   (r region-changeset)
+	   (delta-list (list nil))
+	   (d delta-list)
+	   (node (undo-tree-current buffer-undo-tree))
+	   (repeated-redo-in-region
+	    (undo-tree-repeated-redo-in-region-p start end))
+	   undo-adjusted-markers  ; `undo-elt-in-region' expects this
+	   fragment splice got-visible-elt redo-list elt)
+
+      ;; --- inisitalisation ---
+      (cond
+       ;; if this is a repeated redo-in-region, detach fragment below current
+       ;; node
+       (repeated-redo-in-region
+	(when (setq fragment (car (undo-tree-node-next node)))
+	  (setf (undo-tree-node-previous fragment) nil
+		(undo-tree-node-next node)
+		(delq fragment (undo-tree-node-next node)))))
+       ;; if this is a new redo-in-region, initial fragment is a copy of all
+       ;; nodes below the current one in the active branch
+       ((undo-tree-node-next node)
+	(setq fragment (undo-tree-make-node nil nil)
+	      splice fragment)
+	(while (setq node (nth (undo-tree-node-branch node)
+			       (undo-tree-node-next node)))
+	  (push (undo-tree-make-node
+		 splice nil
+		 (undo-copy-list (undo-tree-node-redo node)))
+		(undo-tree-node-next splice))
+	  (setq splice (car (undo-tree-node-next splice))))
+	(setq fragment (car (undo-tree-node-next fragment)))))
+
+
+      ;; --- pull redo-in-region elements into branch ---
+      ;; work down fragment, pulling out redo elements within region until
+      ;; we've got one that redoes a visible change (insertion or deletion)
+      (setq node fragment)
+      (catch 'abort
+	(while (and (not got-visible-elt) node (undo-tree-node-redo node))
+	  ;; we cons a dummy nil element on the front of the changeset so that
+	  ;; we can conveniently remove the first (real) element from the
+	  ;; changeset if we need to; the leading nil is removed once we're
+	  ;; done with this changeset
+	  (setq redo-list (push nil (undo-tree-node-redo node))
+		elt (cadr redo-list))
+	  (while elt
+	    (cond
+	     ;; keep elements within region
+	     ((undo-elt-in-region elt start end)
+	      ;; set flag if kept element is visible (insertion or deletion)
+	      (when (and (consp elt)
+			 (or (stringp (car elt)) (integerp (car elt))))
+		(setq got-visible-elt t))
+	      ;; adjust buffer positions in elements previously redone before
+	      ;; kept element, as kept element will now be redone first
+	      (undo-tree-adjust-elements-to-elt fragment elt t)
+	      ;; move kept element to redo-in-region changeset, adjusting its
+	      ;; buffer position as it will now be redone first
+	      (setcdr r (list (undo-tree-apply-deltas elt (cdr delta-list) -1)))
+	      (setq r (cdr r))
+	      (setcdr redo-list (cddr redo-list)))
+
+	     ;; discard "was unmodified" elements
+	     ;; FIXME: deal properly with these
+	     ((and (consp elt) (eq (car elt) t))
+	      (setcdr redo-list (cddr redo-list)))
+
+	     ;; if element crosses region, we can't pull any more elements
+	     ((undo-elt-crosses-region elt start end)
+	      ;; if we've found a visible element, it must be earlier in
+	      ;; current node's changeset; stop pulling elements (null
+	      ;; `redo-list' and non-nil `got-visible-elt' cause loop to exit)
+	      (if got-visible-elt
+		  (setq redo-list nil)
+		;; if we haven't found a visible element yet, pulling
+		;; redo-in-region branch has failed
+		(setq region-changeset nil)
+		(throw 'abort t)))
+
+	     ;; if rejecting element, add its delta (if any) to the list
+	     (t
+	      (let ((delta (undo-delta elt)))
+		(when (/= 0 (cdr delta))
+		  (setcdr d (list delta))
+		  (setq d (cdr d))))
+	      (setq redo-list (cdr redo-list))))
+
+	    ;; process next element of current changeset
+	    (setq elt (cadr redo-list)))
+
+	  ;; if there are remaining elements in changeset, remove dummy nil
+	  ;; from front
+	  (if (cadr (undo-tree-node-redo node))
+	      (pop (undo-tree-node-undo node))
+	    ;; otherwise, if we've kept all elements in changeset, discard
+	    ;; empty changeset
+	    (if (eq fragment node)
+		(setq fragment (car (undo-tree-node-next fragment)))
+	      (undo-tree-snip-node node)))
+	  ;; process changeset from next node in fragment
+	  (setq node (car (undo-tree-node-next node)))))
+
+      ;; pop dummy nil from front of `region-changeset'
+      (setq region-changeset (cdr region-changeset))
+
+
+      ;; --- integrate branch into tree ---
+      (setq node (undo-tree-current buffer-undo-tree))
+      ;; if no redo-in-region elements were found, restore undo tree
+      (if (null (car region-changeset))
+	  (when (and repeated-redo-in-region fragment)
+	    (push fragment (undo-tree-node-next node))
+	    (setf (undo-tree-node-branch node) 0
+		  (undo-tree-node-previous fragment) node)
+	    nil)  ; return nil to indicate failure
+
+	;; otherwise, add redo-in-region node to top of fragment, and attach
+	;; it below current node
+	(setq fragment
+	      (if fragment
+		  (undo-tree-grow-backwards fragment nil region-changeset)
+		(undo-tree-make-node nil nil region-changeset)))
+	(push fragment (undo-tree-node-next node))
+	(setf (undo-tree-node-branch node) 0
+	      (undo-tree-node-previous fragment) node)
+	;; update undo-tree size
+	(unless repeated-redo-in-region
+	  (setq node fragment)
+	  (while (and (setq node (car (undo-tree-node-next node)))
+		      (incf (undo-tree-count buffer-undo-tree))
+		      (incf (undo-tree-size buffer-undo-tree)
+			    (undo-list-byte-size
+			     (undo-tree-node-redo node))))))
+	(incf (undo-tree-size buffer-undo-tree)
+	      (undo-list-byte-size (undo-tree-node-redo fragment)))
+	t)  ; indicate redo-in-region branch was successfully pulled
+      )))
+
+
+
+(defun undo-tree-adjust-elements-to-elt (node undo-elt &optional below)
+  "Adjust buffer positions of undo elements, starting at NODE's
+and going up the tree (or down the active branch if BELOW is
+non-nil) and through the nodes' undo elements until we reach
+UNDO-ELT.  UNDO-ELT must appear somewhere in the undo changeset
+of either NODE itself or some node above it in the tree."
+  (let ((delta (list (undo-delta undo-elt)))
+	(undo-list (undo-tree-node-undo node)))
+    ;; adjust elements until we reach UNDO-ELT
+    (while (and (car undo-list)
+		(not (eq (car undo-list) undo-elt)))
+      (setcar undo-list
+	      (undo-tree-apply-deltas (car undo-list) delta -1))
+      ;; move to next undo element in list, or to next node if we've run out
+      ;; of elements
+      (unless (car (setq undo-list (cdr undo-list)))
+	(if below
+	    (setq node (nth (undo-tree-node-branch node)
+			    (undo-tree-node-next node)))
+	  (setq node (undo-tree-node-previous node)))
+	(setq undo-list (undo-tree-node-undo node))))))
+
+
+
+(defun undo-tree-apply-deltas (undo-elt deltas &optional sgn)
+  ;; Apply DELTAS in order to UNDO-ELT, multiplying deltas by SGN
+  ;; (only useful value for SGN is -1).
+  (let (position offset)
+    (dolist (delta deltas)
+      (setq position (car delta)
+	    offset (* (cdr delta) (or sgn 1)))
+      (cond
+       ;; POSITION
+       ((integerp undo-elt)
+	(when (>= undo-elt position)
+	  (setq undo-elt (- undo-elt offset))))
+       ;; nil (or any other atom)
+       ((atom undo-elt))
+       ;; (TEXT . POSITION)
+       ((stringp (car undo-elt))
+	(let ((text-pos (abs (cdr undo-elt)))
+	      (point-at-end (< (cdr undo-elt) 0)))
+	  (if (>= text-pos position)
+	      (setcdr undo-elt (* (if point-at-end -1 1)
+				  (- text-pos offset))))))
+       ;; (BEGIN . END)
+       ((integerp (car undo-elt))
+	(when (>= (car undo-elt) position)
+	  (setcar undo-elt (- (car undo-elt) offset))
+	  (setcdr undo-elt (- (cdr undo-elt) offset))))
+       ;; (nil PROPERTY VALUE BEG . END)
+       ((null (car undo-elt))
+	(let ((tail (nthcdr 3 undo-elt)))
+	  (when (>= (car tail) position)
+	    (setcar tail (- (car tail) offset))
+	    (setcdr tail (- (cdr tail) offset)))))
+       ))
+    undo-elt))
+
+
+
+(defun undo-tree-repeated-undo-in-region-p (start end)
+  ;; Return non-nil if undo-in-region between START and END is a repeated
+  ;; undo-in-region
+  (let ((node (undo-tree-current buffer-undo-tree)))
+    (and (setq node
+	       (nth (undo-tree-node-branch node) (undo-tree-node-next node)))
+	 (eq (undo-tree-node-undo-beginning node) start)
+	 (eq (undo-tree-node-undo-end node) end))))
+
+
+(defun undo-tree-repeated-redo-in-region-p (start end)
+  ;; Return non-nil if undo-in-region between START and END is a repeated
+  ;; undo-in-region
+  (let ((node (undo-tree-current buffer-undo-tree)))
+    (and (eq (undo-tree-node-redo-beginning node) start)
+	 (eq (undo-tree-node-redo-end node) end))))
+
+
+;; Return non-nil if undo-in-region between START and END is simply
+;; reverting the last redo-in-region
+(defalias 'undo-tree-reverting-undo-in-region-p
+  'undo-tree-repeated-undo-in-region-p)
+
+
+;; Return non-nil if redo-in-region between START and END is simply
+;; reverting the last undo-in-region
+(defalias 'undo-tree-reverting-redo-in-region-p
+  'undo-tree-repeated-redo-in-region-p)
+
+
+
+
+;;; =====================================================================
+;;;                        Undo-tree commands
+
+;;;###autoload
+(define-minor-mode undo-tree-mode
+  "Toggle undo-tree mode.
+With no argument, this command toggles the mode.
+A positive prefix argument turns the mode on.
+A negative prefix argument turns it off.
+
+Undo-tree-mode replaces Emacs' standard undo feature with a more
+powerful yet easier to use version, that treats the undo history
+as what it is: a tree.
+
+The following keys are available in `undo-tree-mode':
+
+  \\{undo-tree-map}
+
+Within the undo-tree visualizer, the following keys are available:
+
+  \\{undo-tree-visualizer-mode-map}"
+
+  nil                       ; init value
+  undo-tree-mode-lighter    ; lighter
+  undo-tree-map             ; keymap
+
+  ;; if disabling `undo-tree-mode', rebuild `buffer-undo-list' from tree so
+  ;; Emacs undo can work
+  (when (not undo-tree-mode)
+    (undo-list-rebuild-from-tree)
+    (setq buffer-undo-tree nil)))
+
+
+(defun turn-on-undo-tree-mode (&optional print-message)
+  "Enable `undo-tree-mode' in the current buffer, when appropriate.
+Some major modes implement their own undo system, which should
+not normally be overridden by `undo-tree-mode'. This command does
+not enable `undo-tree-mode' in such buffers. If you want to force
+`undo-tree-mode' to be enabled regardless, use (undo-tree-mode 1)
+instead.
+
+The heuristic used to detect major modes in which
+`undo-tree-mode' should not be used is to check whether either
+the `undo' command has been remapped, or the default undo
+keybindings (C-/ and C-_) have been overridden somewhere other
+than in the global map. In addition, `undo-tree-mode' will not be
+enabled if the buffer's `major-mode' appears in
+`undo-tree-incompatible-major-modes'."
+  (interactive "p")
+  (if (or (key-binding [remap undo])
+	  (undo-tree-overridden-undo-bindings-p)
+	  (memq major-mode undo-tree-incompatible-major-modes))
+      (when print-message
+	(message "Buffer does not support undo-tree-mode;\
+ undo-tree-mode NOT enabled"))
+    (undo-tree-mode 1)))
+
+
+(defun undo-tree-overridden-undo-bindings-p ()
+  "Returns t if default undo bindings are overridden, nil otherwise.
+Checks if either of the default undo key bindings (\"C-/\" or
+\"C-_\") are overridden in the current buffer by any keymap other
+than the global one. (So global redefinitions of the default undo
+key bindings do not count.)"
+  (let ((binding1 (lookup-key (current-global-map) [?\C-/]))
+	(binding2 (lookup-key (current-global-map) [?\C-_])))
+    (global-set-key [?\C-/] 'undo)
+    (global-set-key [?\C-_] 'undo)
+    (unwind-protect
+	(or (and (key-binding [?\C-/])
+		 (not (eq (key-binding [?\C-/]) 'undo)))
+	    (and (key-binding [?\C-_])
+		 (not (eq (key-binding [?\C-_]) 'undo))))
+      (global-set-key [?\C-/] binding1)
+      (global-set-key [?\C-_] binding2))))
+
+
+;;;###autoload
+(define-globalized-minor-mode global-undo-tree-mode
+  undo-tree-mode turn-on-undo-tree-mode)
+
+
+
+(defun undo-tree-undo (&optional arg)
+  "Undo changes.
+Repeat this command to undo more changes.
+A numeric ARG serves as a repeat count.
+
+In Transient Mark mode when the mark is active, only undo changes
+within the current region. Similarly, when not in Transient Mark
+mode, just \\[universal-argument] as an argument limits undo to
+changes within the current region."
+  (interactive "*P")
+  ;; throw error if undo is disabled in buffer
+  (when (eq buffer-undo-list t)
+    (user-error "No undo information in this buffer"))
+  (undo-tree-undo-1 arg)
+  ;; inform user if at branch point
+  (when (> (undo-tree-num-branches) 1) (message "Undo branch point!")))
+
+
+(defun undo-tree-undo-1 (&optional arg preserve-redo preserve-timestamps)
+  ;; Internal undo function. An active mark in `transient-mark-mode', or
+  ;; non-nil ARG otherwise, enables undo-in-region. Non-nil PRESERVE-REDO
+  ;; causes the existing redo record to be preserved, rather than replacing it
+  ;; with the new one generated by undoing. Non-nil PRESERVE-TIMESTAMPS
+  ;; disables updating of timestamps in visited undo-tree nodes. (This latter
+  ;; should *only* be used when temporarily visiting another undo state and
+  ;; immediately returning to the original state afterwards. Otherwise, it
+  ;; could cause history-discarding errors.)
+  (let ((undo-in-progress t)
+	(undo-in-region (and undo-tree-enable-undo-in-region
+			     (or (region-active-p)
+				 (and arg (not (numberp arg))))))
+	pos current)
+    ;; transfer entries accumulated in `buffer-undo-list' to
+    ;; `buffer-undo-tree'
+    (undo-list-transfer-to-tree)
+
+    (dotimes (i (or (and (numberp arg) (prefix-numeric-value arg)) 1))
+      ;; check if at top of undo tree
+      (unless (undo-tree-node-previous (undo-tree-current buffer-undo-tree))
+	(user-error "No further undo information"))
+
+      ;; if region is active, or a non-numeric prefix argument was supplied,
+      ;; try to pull out a new branch of changes affecting the region
+      (when (and undo-in-region
+		 (not (undo-tree-pull-undo-in-region-branch
+		       (region-beginning) (region-end))))
+	(user-error "No further undo information for region"))
+
+      ;; remove any GC'd elements from node's undo list
+      (setq current (undo-tree-current buffer-undo-tree))
+      (decf (undo-tree-size buffer-undo-tree)
+	    (undo-list-byte-size (undo-tree-node-undo current)))
+      (setf (undo-tree-node-undo current)
+	    (undo-list-clean-GCd-elts (undo-tree-node-undo current)))
+      (incf (undo-tree-size buffer-undo-tree)
+	    (undo-list-byte-size (undo-tree-node-undo current)))
+      ;; undo one record from undo tree
+      (when undo-in-region
+	(setq pos (set-marker (make-marker) (point)))
+	(set-marker-insertion-type pos t))
+      (primitive-undo 1 (undo-tree-copy-list (undo-tree-node-undo current)))
+      (undo-boundary)
+
+      ;; if preserving old redo record, discard new redo entries that
+      ;; `primitive-undo' has added to `buffer-undo-list', and remove any GC'd
+      ;; elements from node's redo list
+      (if preserve-redo
+	  (progn
+	    (undo-list-pop-changeset)
+	    (decf (undo-tree-size buffer-undo-tree)
+		  (undo-list-byte-size (undo-tree-node-redo current)))
+	    (setf (undo-tree-node-redo current)
+		  (undo-list-clean-GCd-elts (undo-tree-node-redo current)))
+	    (incf (undo-tree-size buffer-undo-tree)
+		  (undo-list-byte-size (undo-tree-node-redo current))))
+	;; otherwise, record redo entries that `primitive-undo' has added to
+	;; `buffer-undo-list' in current node's redo record, replacing
+	;; existing entry if one already exists
+	(decf (undo-tree-size buffer-undo-tree)
+	      (undo-list-byte-size (undo-tree-node-redo current)))
+	(setf (undo-tree-node-redo current)
+	      (undo-list-pop-changeset 'discard-pos))
+	(incf (undo-tree-size buffer-undo-tree)
+	      (undo-list-byte-size (undo-tree-node-redo current))))
+
+      ;; rewind current node and update timestamp
+      (setf (undo-tree-current buffer-undo-tree)
+	    (undo-tree-node-previous (undo-tree-current buffer-undo-tree)))
+      (unless preserve-timestamps
+	(setf (undo-tree-node-timestamp (undo-tree-current buffer-undo-tree))
+	      (current-time)))
+
+      ;; if undoing-in-region, record current node, region and direction so we
+      ;; can tell if undo-in-region is repeated, and re-activate mark if in
+      ;; `transient-mark-mode'; if not, erase any leftover data
+      (if (not undo-in-region)
+	  (undo-tree-node-clear-region-data current)
+	(goto-char pos)
+	;; note: we deliberately want to store the region information in the
+	;; node *below* the now current one
+	(setf (undo-tree-node-undo-beginning current) (region-beginning)
+	      (undo-tree-node-undo-end current) (region-end))
+	(set-marker pos nil)))
+
+    ;; undo deactivates mark unless undoing-in-region
+    (setq deactivate-mark (not undo-in-region))))
+
+
+
+(defun undo-tree-redo (&optional arg)
+  "Redo changes. A numeric ARG serves as a repeat count.
+
+In Transient Mark mode when the mark is active, only redo changes
+within the current region. Similarly, when not in Transient Mark
+mode, just \\[universal-argument] as an argument limits redo to
+changes within the current region."
+  (interactive "*P")
+  ;; throw error if undo is disabled in buffer
+  (when (eq buffer-undo-list t)
+    (user-error "No undo information in this buffer"))
+  (undo-tree-redo-1 arg)
+  ;; inform user if at branch point
+  (when (> (undo-tree-num-branches) 1) (message "Undo branch point!")))
+
+
+(defun undo-tree-redo-1 (&optional arg preserve-undo preserve-timestamps)
+  ;; Internal redo function. An active mark in `transient-mark-mode', or
+  ;; non-nil ARG otherwise, enables undo-in-region. Non-nil PRESERVE-UNDO
+  ;; causes the existing redo record to be preserved, rather than replacing it
+  ;; with the new one generated by undoing. Non-nil PRESERVE-TIMESTAMPS
+  ;; disables updating of timestamps in visited undo-tree nodes. (This latter
+  ;; should *only* be used when temporarily visiting another undo state and
+  ;; immediately returning to the original state afterwards. Otherwise, it
+  ;; could cause history-discarding errors.)
+  (let ((undo-in-progress t)
+	(redo-in-region (and undo-tree-enable-undo-in-region
+			     (or (region-active-p)
+				 (and arg (not (numberp arg))))))
+	pos current)
+    ;; transfer entries accumulated in `buffer-undo-list' to
+    ;; `buffer-undo-tree'
+    (undo-list-transfer-to-tree)
+
+    (dotimes (i (or (and (numberp arg) (prefix-numeric-value arg)) 1))
+      ;; check if at bottom of undo tree
+      (when (null (undo-tree-node-next (undo-tree-current buffer-undo-tree)))
+	(user-error "No further redo information"))
+
+      ;; if region is active, or a non-numeric prefix argument was supplied,
+      ;; try to pull out a new branch of changes affecting the region
+      (when (and redo-in-region
+		 (not (undo-tree-pull-redo-in-region-branch
+		       (region-beginning) (region-end))))
+	(user-error "No further redo information for region"))
+
+      ;; get next node (but DON'T advance current node in tree yet, in case
+      ;; redoing fails)
+      (setq current (undo-tree-current buffer-undo-tree)
+	    current (nth (undo-tree-node-branch current)
+			 (undo-tree-node-next current)))
+      ;; remove any GC'd elements from node's redo list
+      (decf (undo-tree-size buffer-undo-tree)
+	    (undo-list-byte-size (undo-tree-node-redo current)))
+      (setf (undo-tree-node-redo current)
+	    (undo-list-clean-GCd-elts (undo-tree-node-redo current)))
+      (incf (undo-tree-size buffer-undo-tree)
+	    (undo-list-byte-size (undo-tree-node-redo current)))
+      ;; redo one record from undo tree
+      (when redo-in-region
+	(setq pos (set-marker (make-marker) (point)))
+	(set-marker-insertion-type pos t))
+      (primitive-undo 1 (undo-tree-copy-list (undo-tree-node-redo current)))
+      (undo-boundary)
+      ;; advance current node in tree
+      (setf (undo-tree-current buffer-undo-tree) current)
+
+      ;; if preserving old undo record, discard new undo entries that
+      ;; `primitive-undo' has added to `buffer-undo-list', and remove any GC'd
+      ;; elements from node's redo list
+      (if preserve-undo
+	  (progn
+	    (undo-list-pop-changeset)
+	    (decf (undo-tree-size buffer-undo-tree)
+		  (undo-list-byte-size (undo-tree-node-undo current)))
+	    (setf (undo-tree-node-undo current)
+		  (undo-list-clean-GCd-elts (undo-tree-node-undo current)))
+	    (incf (undo-tree-size buffer-undo-tree)
+		  (undo-list-byte-size (undo-tree-node-undo current))))
+	;; otherwise, record undo entries that `primitive-undo' has added to
+	;; `buffer-undo-list' in current node's undo record, replacing
+	;; existing entry if one already exists
+	(decf (undo-tree-size buffer-undo-tree)
+	      (undo-list-byte-size (undo-tree-node-undo current)))
+	(setf (undo-tree-node-undo current)
+	      (undo-list-pop-changeset 'discard-pos))
+	(incf (undo-tree-size buffer-undo-tree)
+	      (undo-list-byte-size (undo-tree-node-undo current))))
+
+      ;; update timestamp
+      (unless preserve-timestamps
+	(setf (undo-tree-node-timestamp current) (current-time)))
+
+      ;; if redoing-in-region, record current node, region and direction so we
+      ;; can tell if redo-in-region is repeated, and re-activate mark if in
+      ;; `transient-mark-mode'
+      (if (not redo-in-region)
+	  (undo-tree-node-clear-region-data current)
+	(goto-char pos)
+	(setf (undo-tree-node-redo-beginning current) (region-beginning)
+	      (undo-tree-node-redo-end current) (region-end))
+	(set-marker pos nil)))
+
+    ;; redo deactivates the mark unless redoing-in-region
+    (setq deactivate-mark (not redo-in-region))))
+
+
+
+(defun undo-tree-switch-branch (branch)
+  "Switch to a different BRANCH of the undo tree.
+This will affect which branch to descend when *redoing* changes
+using `undo-tree-redo'."
+  (interactive (list (or (and prefix-arg (prefix-numeric-value prefix-arg))
+                         (and (not (eq buffer-undo-list t))
+			      (or (undo-list-transfer-to-tree) t)
+			      (let ((b (undo-tree-node-branch
+					(undo-tree-current
+					 buffer-undo-tree))))
+				(cond
+				 ;; switch to other branch if only 2
+				 ((= (undo-tree-num-branches) 2) (- 1 b))
+				 ;; prompt if more than 2
+				 ((> (undo-tree-num-branches) 2)
+				  (read-number
+				   (format "Branch (0-%d, on %d): "
+					   (1- (undo-tree-num-branches)) b)))
+				 ))))))
+  ;; throw error if undo is disabled in buffer
+  (when (eq buffer-undo-list t)
+    (user-error "No undo information in this buffer"))
+  ;; sanity check branch number
+  (when (<= (undo-tree-num-branches) 1)
+    (user-error "Not at undo branch point"))
+  (when (or (< branch 0) (> branch (1- (undo-tree-num-branches))))
+    (user-error "Invalid branch number"))
+  ;; transfer entries accumulated in `buffer-undo-list' to `buffer-undo-tree'
+  (undo-list-transfer-to-tree)
+  ;; switch branch
+  (setf (undo-tree-node-branch (undo-tree-current buffer-undo-tree))
+	branch)
+  (message "Switched to branch %d" branch))
+
+
+(defun undo-tree-set (node &optional preserve-timestamps)
+  ;; Set buffer to state corresponding to NODE. Returns intersection point
+  ;; between path back from current node and path back from selected NODE.
+  ;; Non-nil PRESERVE-TIMESTAMPS disables updating of timestamps in visited
+  ;; undo-tree nodes. (This should *only* be used when temporarily visiting
+  ;; another undo state and immediately returning to the original state
+  ;; afterwards. Otherwise, it could cause history-discarding errors.)
+  (let ((path (make-hash-table :test 'eq))
+        (n node))
+    (puthash (undo-tree-root buffer-undo-tree) t path)
+    ;; build list of nodes leading back from selected node to root, updating
+    ;; branches as we go to point down to selected node
+    (while (progn
+             (puthash n t path)
+             (when (undo-tree-node-previous n)
+               (setf (undo-tree-node-branch (undo-tree-node-previous n))
+                     (undo-tree-position
+                      n (undo-tree-node-next (undo-tree-node-previous n))))
+               (setq n (undo-tree-node-previous n)))))
+    ;; work backwards from current node until we intersect path back from
+    ;; selected node
+    (setq n (undo-tree-current buffer-undo-tree))
+    (while (not (gethash n path))
+      (setq n (undo-tree-node-previous n)))
+    ;; ascend tree until intersection node
+    (while (not (eq (undo-tree-current buffer-undo-tree) n))
+      (undo-tree-undo-1 nil nil preserve-timestamps))
+    ;; descend tree until selected node
+    (while (not (eq (undo-tree-current buffer-undo-tree) node))
+      (undo-tree-redo-1 nil nil preserve-timestamps))
+    n))  ; return intersection node
+
+
+
+(defun undo-tree-save-state-to-register (register)
+  "Store current undo-tree state to REGISTER.
+The saved state can be restored using
+`undo-tree-restore-state-from-register'.
+Argument is a character, naming the register."
+  (interactive "cUndo-tree state to register: ")
+  ;; throw error if undo is disabled in buffer
+  (when (eq buffer-undo-list t)
+    (user-error "No undo information in this buffer"))
+  ;; transfer entries accumulated in `buffer-undo-list' to `buffer-undo-tree'
+  (undo-list-transfer-to-tree)
+  ;; save current node to REGISTER
+  (set-register
+   register (registerv-make
+	     (undo-tree-make-register-data
+	      (current-buffer) (undo-tree-current buffer-undo-tree))
+	     :print-func 'undo-tree-register-data-print-func))
+  ;; record REGISTER in current node, for visualizer
+  (setf (undo-tree-node-register (undo-tree-current buffer-undo-tree))
+	register))
+
+
+
+(defun undo-tree-restore-state-from-register (register)
+  "Restore undo-tree state from REGISTER.
+The state must be saved using `undo-tree-save-state-to-register'.
+Argument is a character, naming the register."
+  (interactive "*cRestore undo-tree state from register: ")
+  ;; throw error if undo is disabled in buffer, or if register doesn't contain
+  ;; an undo-tree node
+  (let ((data (registerv-data (get-register register))))
+    (cond
+     ((eq buffer-undo-list t)
+      (user-error "No undo information in this buffer"))
+     ((not (undo-tree-register-data-p data))
+      (user-error "Register doesn't contain undo-tree state"))
+     ((not (eq (current-buffer) (undo-tree-register-data-buffer data)))
+      (user-error "Register contains undo-tree state for a different buffer")))
+    ;; transfer entries accumulated in `buffer-undo-list' to `buffer-undo-tree'
+    (undo-list-transfer-to-tree)
+    ;; restore buffer state corresponding to saved node
+    (undo-tree-set (undo-tree-register-data-node data))))
+
+
+
+
+;;; =====================================================================
+;;;                    Persistent storage commands
+
+(defun undo-tree-make-history-save-file-name (file)
+  "Create the undo history file name for FILE.
+Normally this is the file's name with \".\" prepended and
+\".~undo-tree~\" appended.
+
+A match for FILE is sought in `undo-tree-history-directory-alist'
+\(see the documentation of that variable for details\). If the
+directory for the backup doesn't exist, it is created."
+  (let* ((backup-directory-alist undo-tree-history-directory-alist)
+	 (name (make-backup-file-name-1 file)))
+    (concat (file-name-directory name) "." (file-name-nondirectory name)
+	    ".~undo-tree~")))
+
+
+(defun undo-tree-save-history (&optional filename overwrite)
+  "Store undo-tree history to file.
+
+If optional argument FILENAME is omitted, default save file is
+\".<buffer-file-name>.~undo-tree\" if buffer is visiting a file.
+Otherwise, prompt for one.
+
+If OVERWRITE is non-nil, any existing file will be overwritten
+without asking for confirmation."
+  (interactive)
+  (when (eq buffer-undo-list t)
+    (user-error "No undo information in this buffer"))
+  (undo-list-transfer-to-tree)
+  (when (and buffer-undo-tree (not (eq buffer-undo-tree t)))
+    (condition-case nil
+	(undo-tree-kill-visualizer)
+      (error (undo-tree-clear-visualizer-data buffer-undo-tree)))
+    (let ((buff (current-buffer))
+	  tree)
+      ;; get filename
+      (unless filename
+	(setq filename
+	      (if buffer-file-name
+		  (undo-tree-make-history-save-file-name buffer-file-name)
+		(expand-file-name (read-file-name "File to save in: ") nil))))
+      (when (or (not (file-exists-p filename))
+		overwrite
+		(yes-or-no-p (format "Overwrite \"%s\"? " filename)))
+	(unwind-protect
+	    (progn
+	      ;; transform undo-tree into non-circular structure, and make
+	      ;; temporary copy
+	      (undo-tree-decircle buffer-undo-tree)
+	      (setq tree (copy-undo-tree buffer-undo-tree))
+	      ;; discard undo-tree object pool before saving
+	      (setf (undo-tree-object-pool tree) nil)
+	      ;; print undo-tree to file
+	      ;; NOTE: We use `with-temp-buffer' instead of `with-temp-file'
+	      ;;       to allow `auto-compression-mode' to take effect, in
+	      ;;       case user has overridden or advised the default
+	      ;;       `undo-tree-make-history-save-file-name' to add a
+	      ;;       compressed file extension.
+	      (with-auto-compression-mode
+		(with-temp-buffer
+		  (prin1 (sha1 buff) (current-buffer))
+		  (terpri (current-buffer))
+		  (let ((print-circle t)) (prin1 tree (current-buffer)))
+		  (write-region nil nil filename))))
+	  ;; restore circular undo-tree data structure
+	  (undo-tree-recircle buffer-undo-tree))
+	))))
+
+
+
+(defun undo-tree-load-history (&optional filename noerror)
+  "Load undo-tree history from file.
+
+If optional argument FILENAME is null, default load file is
+\".<buffer-file-name>.~undo-tree\" if buffer is visiting a file.
+Otherwise, prompt for one.
+
+If optional argument NOERROR is non-nil, return nil instead of
+signaling an error if file is not found."
+  (interactive)
+  ;; get filename
+  (unless filename
+    (setq filename
+	  (if buffer-file-name
+	      (undo-tree-make-history-save-file-name buffer-file-name)
+	    (expand-file-name (read-file-name "File to load from: ") nil))))
+
+  ;; attempt to read undo-tree from FILENAME
+  (catch 'load-error
+    (unless (file-exists-p filename)
+      (if noerror
+	  (throw 'load-error nil)
+	(error "File \"%s\" does not exist; could not load undo-tree history"
+	       filename)))
+    (let (buff hash tree)
+      (setq buff (current-buffer))
+      (with-auto-compression-mode
+	(with-temp-buffer
+	  (insert-file-contents filename)
+	  (goto-char (point-min))
+	  (condition-case nil
+	      (setq hash (read (current-buffer)))
+	    (error
+	     (kill-buffer nil)
+	     (funcall (if noerror 'message 'user-error)
+		      "Error reading undo-tree history from \"%s\"" filename)
+	     (throw 'load-error nil)))
+	  (unless (string= (sha1 buff) hash)
+	    (kill-buffer nil)
+	    (funcall (if noerror 'message 'user-error)
+		     "Buffer has been modified; could not load undo-tree history")
+	    (throw 'load-error nil))
+	  (condition-case nil
+	      (setq tree (read (current-buffer)))
+	    (error
+	     (kill-buffer nil)
+	     (funcall (if noerror 'message 'error)
+		      "Error reading undo-tree history from \"%s\"" filename)
+	     (throw 'load-error nil)))
+	  (kill-buffer nil)))
+      ;; initialise empty undo-tree object pool
+      (setf (undo-tree-object-pool tree)
+	    (make-hash-table :test 'eq :weakness 'value))
+      ;; restore circular undo-tree data structure
+      (undo-tree-recircle tree)
+      (setq buffer-undo-tree tree))))
+
+
+
+;; Versions of save/load functions for use in hooks
+(defun undo-tree-save-history-hook ()
+  (when (and undo-tree-mode undo-tree-auto-save-history
+	     (not (eq buffer-undo-list t)))
+    (undo-tree-save-history nil t) nil))
+
+(defun undo-tree-load-history-hook ()
+  (when (and undo-tree-mode undo-tree-auto-save-history
+	     (not (eq buffer-undo-list t))
+	     (not revert-buffer-in-progress-p))
+    (undo-tree-load-history nil t)))
+
+
+
+
+;;; =====================================================================
+;;;                    Visualizer drawing functions
+
+(defun undo-tree-visualize ()
+  "Visualize the current buffer's undo tree."
+  (interactive "*")
+  (deactivate-mark)
+  ;; throw error if undo is disabled in buffer
+  (when (eq buffer-undo-list t)
+    (user-error "No undo information in this buffer"))
+  ;; transfer entries accumulated in `buffer-undo-list' to `buffer-undo-tree'
+  (undo-list-transfer-to-tree)
+  ;; add hook to kill visualizer buffer if original buffer is changed
+  (add-hook 'before-change-functions 'undo-tree-kill-visualizer nil t)
+  ;; prepare *undo-tree* buffer, then draw tree in it
+  (let ((undo-tree buffer-undo-tree)
+        (buff (current-buffer))
+	(display-buffer-mark-dedicated 'soft))
+    (switch-to-buffer-other-window
+     (get-buffer-create undo-tree-visualizer-buffer-name))
+    (setq undo-tree-visualizer-parent-buffer buff)
+    (setq undo-tree-visualizer-parent-mtime
+	  (and (buffer-file-name buff)
+	       (nth 5 (file-attributes (buffer-file-name buff)))))
+    (setq undo-tree-visualizer-initial-node (undo-tree-current undo-tree))
+    (setq undo-tree-visualizer-spacing
+	  (undo-tree-visualizer-calculate-spacing))
+    (make-local-variable 'undo-tree-visualizer-timestamps)
+    (make-local-variable 'undo-tree-visualizer-diff)
+    (setq buffer-undo-tree undo-tree)
+    (undo-tree-visualizer-mode)
+    ;; FIXME; don't know why `undo-tree-visualizer-mode' clears this
+    (setq buffer-undo-tree undo-tree)
+    (set (make-local-variable 'undo-tree-visualizer-lazy-drawing)
+	 (or (eq undo-tree-visualizer-lazy-drawing t)
+	     (and (numberp undo-tree-visualizer-lazy-drawing)
+		  (>= (undo-tree-count undo-tree)
+		      undo-tree-visualizer-lazy-drawing))))
+    (when undo-tree-visualizer-diff (undo-tree-visualizer-show-diff))
+    (let ((inhibit-read-only t)) (undo-tree-draw-tree undo-tree))))
+
+
+(defun undo-tree-kill-visualizer (&rest _dummy)
+  ;; Kill visualizer. Added to `before-change-functions' hook of original
+  ;; buffer when visualizer is invoked.
+  (unless (or undo-tree-inhibit-kill-visualizer
+	      (null (get-buffer undo-tree-visualizer-buffer-name)))
+    (with-current-buffer undo-tree-visualizer-buffer-name
+      (undo-tree-visualizer-quit))))
+
+
+
+(defun undo-tree-draw-tree (undo-tree)
+  ;; Draw undo-tree in current buffer starting from NODE (or root if nil).
+  (let ((node (if undo-tree-visualizer-lazy-drawing
+		  (undo-tree-current undo-tree)
+		(undo-tree-root undo-tree))))
+    (erase-buffer)
+    (setq undo-tree-visualizer-needs-extending-down nil
+	  undo-tree-visualizer-needs-extending-up nil)
+    (undo-tree-clear-visualizer-data undo-tree)
+    (undo-tree-compute-widths node)
+    ;; lazy drawing starts vertically centred and displaced horizontally to
+    ;; the left (window-width/4), since trees will typically grow right
+    (if undo-tree-visualizer-lazy-drawing
+	(progn
+	  (undo-tree-move-down (/ (window-height) 2))
+	  (undo-tree-move-forward (max 2 (/ (window-width) 4)))) ; left margin
+      ;; non-lazy drawing starts in centre at top of buffer
+      (undo-tree-move-down 1)  ; top margin
+      (undo-tree-move-forward
+       (max (/ (window-width) 2)
+	    (+ (undo-tree-node-char-lwidth node)
+	       ;; add space for left part of left-most time-stamp
+	       (if undo-tree-visualizer-timestamps
+		   (/ (- undo-tree-visualizer-spacing 4) 2)
+		 0)
+	       2))))  ; left margin
+    ;; link starting node to its representation in visualizer
+    (setf (undo-tree-node-marker node) (make-marker))
+    (set-marker-insertion-type (undo-tree-node-marker node) nil)
+    (move-marker (undo-tree-node-marker node) (point))
+    ;; draw undo-tree
+    (let ((undo-tree-insert-face 'undo-tree-visualizer-default-face)
+	  node-list)
+      (if (not undo-tree-visualizer-lazy-drawing)
+	  (undo-tree-extend-down node t)
+	(undo-tree-extend-down node)
+	(undo-tree-extend-up node)
+	(setq node-list undo-tree-visualizer-needs-extending-down
+	      undo-tree-visualizer-needs-extending-down nil)
+	(while node-list (undo-tree-extend-down (pop node-list)))))
+    ;; highlight active branch
+    (let ((undo-tree-insert-face 'undo-tree-visualizer-active-branch-face))
+      (undo-tree-highlight-active-branch
+       (or undo-tree-visualizer-needs-extending-up
+	   (undo-tree-root undo-tree))))
+    ;; highlight current node
+    (undo-tree-draw-node (undo-tree-current undo-tree) 'current)))
+
+
+(defun undo-tree-extend-down (node &optional bottom)
+  ;; Extend tree downwards starting from NODE and point. If BOTTOM is t,
+  ;; extend all the way down to the leaves. If BOTTOM is a node, extend down
+  ;; as far as that node. If BOTTOM is an integer, extend down as far as that
+  ;; line. Otherwise, only extend visible portion of tree. NODE is assumed to
+  ;; already have a node marker. Returns non-nil if anything was actually
+  ;; extended.
+  (let ((extended nil)
+	(cur-stack (list node))
+	next-stack)
+    ;; don't bother extending if BOTTOM specifies an already-drawn node
+    (unless (and (undo-tree-node-p bottom) (undo-tree-node-marker bottom))
+      ;; draw nodes layer by layer
+      (while (or cur-stack
+		 (prog1 (setq cur-stack next-stack)
+		   (setq next-stack nil)))
+	(setq node (pop cur-stack))
+	;; if node is within range being drawn...
+	(if (or (eq bottom t)
+		(and (undo-tree-node-p bottom)
+		     (not (eq (undo-tree-node-previous node) bottom)))
+		(and (integerp bottom)
+		     (>= bottom (line-number-at-pos
+				 (undo-tree-node-marker node))))
+		(and (null bottom)
+		     (pos-visible-in-window-p (undo-tree-node-marker node)
+					      nil t)))
+	    ;; ...draw one layer of node's subtree (if not already drawn)
+	    (progn
+	      (unless (and (undo-tree-node-next node)
+			   (undo-tree-node-marker
+			    (nth (undo-tree-node-branch node)
+				 (undo-tree-node-next node))))
+		(goto-char (undo-tree-node-marker node))
+		(undo-tree-draw-subtree node)
+		(setq extended t))
+	      (setq next-stack
+		    (append (undo-tree-node-next node) next-stack)))
+	  ;; ...otherwise, postpone drawing until later
+	  (push node undo-tree-visualizer-needs-extending-down))))
+    extended))
+
+
+(defun undo-tree-extend-up (node &optional top)
+  ;; Extend tree upwards starting from NODE. If TOP is t, extend all the way
+  ;; to root. If TOP is a node, extend up as far as that node. If TOP is an
+  ;; integer, extend up as far as that line. Otherwise, only extend visible
+  ;; portion of tree. NODE is assumed to already have a node marker. Returns
+  ;; non-nil if anything was actually extended.
+  (let ((extended nil) parent)
+    ;; don't bother extending if TOP specifies an already-drawn node
+    (unless (and (undo-tree-node-p top) (undo-tree-node-marker top))
+      (while node
+	(setq parent (undo-tree-node-previous node))
+	;; if we haven't reached root...
+	(if parent
+	    ;; ...and node is within range being drawn...
+	    (if (or (eq top t)
+		    (and (undo-tree-node-p top) (not (eq node top)))
+		    (and (integerp top)
+			 (< top (line-number-at-pos
+				 (undo-tree-node-marker node))))
+		    (and (null top)
+			 ;; NOTE: we check point in case window-start is outdated
+			 (< (min (line-number-at-pos (point))
+				 (line-number-at-pos (window-start)))
+			    (line-number-at-pos
+			     (undo-tree-node-marker node)))))
+		;; ...and it hasn't already been drawn
+		(when (not (undo-tree-node-marker parent))
+		  ;; link parent node to its representation in visualizer
+		  (undo-tree-compute-widths parent)
+		  (undo-tree-move-to-parent node)
+		  (setf (undo-tree-node-marker parent) (make-marker))
+		  (set-marker-insertion-type
+		   (undo-tree-node-marker parent) nil)
+		  (move-marker (undo-tree-node-marker parent) (point))
+		  ;; draw subtree beneath parent
+		  (setq undo-tree-visualizer-needs-extending-down
+			(nconc (delq node (undo-tree-draw-subtree parent))
+			       undo-tree-visualizer-needs-extending-down))
+		  (setq extended t))
+	      ;; ...otherwise, postpone drawing for later and exit
+	      (setq undo-tree-visualizer-needs-extending-up (when parent node)
+		    parent nil))
+
+	  ;; if we've reached root, stop extending and add top margin
+	  (setq undo-tree-visualizer-needs-extending-up nil)
+	  (goto-char (undo-tree-node-marker node))
+	  (undo-tree-move-up 1)  ; top margin
+	  (delete-region (point-min) (line-beginning-position)))
+	;; next iteration
+	(setq node parent)))
+    extended))
+
+
+(defun undo-tree-expand-down (from &optional to)
+  ;; Expand tree downwards. FROM is the node to start expanding from. Stop
+  ;; expanding at TO if specified. Otherwise, just expand visible portion of
+  ;; tree and highlight active branch from FROM.
+  (when undo-tree-visualizer-needs-extending-down
+    (let ((inhibit-read-only t)
+	  node-list extended)
+      ;; extend down as far as TO node
+      (when to
+	(setq extended (undo-tree-extend-down from to))
+	(goto-char (undo-tree-node-marker to))
+	(redisplay t))  ; force redisplay to scroll buffer if necessary
+      ;; extend visible portion of tree downwards
+      (setq node-list undo-tree-visualizer-needs-extending-down
+	    undo-tree-visualizer-needs-extending-down nil)
+      (when node-list
+	(dolist (n node-list)
+	  (when (undo-tree-extend-down n) (setq extended t)))
+	;; highlight active branch in newly-extended-down portion, if any
+	(when extended
+	  (let ((undo-tree-insert-face
+		 'undo-tree-visualizer-active-branch-face))
+	    (undo-tree-highlight-active-branch from)))))))
+
+
+(defun undo-tree-expand-up (from &optional to)
+  ;; Expand tree upwards. FROM is the node to start expanding from, TO is the
+  ;; node to stop expanding at. If TO node isn't specified, just expand visible
+  ;; portion of tree and highlight active branch down to FROM.
+  (when undo-tree-visualizer-needs-extending-up
+    (let ((inhibit-read-only t)
+	  extended node-list)
+      ;; extend up as far as TO node
+      (when to
+	(setq extended (undo-tree-extend-up from to))
+	(goto-char (undo-tree-node-marker to))
+	;; simulate auto-scrolling if close to top of buffer
+	(when (<= (line-number-at-pos (point)) scroll-margin)
+	  (undo-tree-move-up (if (= scroll-conservatively 0)
+				 (/ (window-height) 2) 3))
+	  (when (undo-tree-extend-up to) (setq extended t))
+	  (goto-char (undo-tree-node-marker to))
+	  (unless (= scroll-conservatively 0) (recenter scroll-margin))))
+      ;; extend visible portion of tree upwards
+      (and undo-tree-visualizer-needs-extending-up
+	   (undo-tree-extend-up undo-tree-visualizer-needs-extending-up)
+	   (setq extended t))
+      ;; extend visible portion of tree downwards
+      (setq node-list undo-tree-visualizer-needs-extending-down
+	    undo-tree-visualizer-needs-extending-down nil)
+      (dolist (n node-list) (undo-tree-extend-down n))
+      ;; highlight active branch in newly-extended-up portion, if any
+      (when extended
+	(let ((undo-tree-insert-face
+	       'undo-tree-visualizer-active-branch-face))
+	  (undo-tree-highlight-active-branch
+	   (or undo-tree-visualizer-needs-extending-up
+	       (undo-tree-root buffer-undo-tree))
+	   from))))))
+
+
+
+(defun undo-tree-highlight-active-branch (node &optional end)
+  ;; Draw highlighted active branch below NODE in current buffer. Stop
+  ;; highlighting at END node if specified.
+  (let ((stack (list node)))
+    ;; draw active branch
+    (while stack
+      (setq node (pop stack))
+      (unless (or (eq node end)
+		  (memq node undo-tree-visualizer-needs-extending-down))
+	(goto-char (undo-tree-node-marker node))
+	(setq node (undo-tree-draw-subtree node 'active)
+	      stack (nconc stack node))))))
+
+
+(defun undo-tree-draw-node (node &optional current)
+  ;; Draw symbol representing NODE in visualizer. If CURRENT is non-nil, node
+  ;; is current node.
+  (goto-char (undo-tree-node-marker node))
+  (when undo-tree-visualizer-timestamps
+    (undo-tree-move-backward (/ undo-tree-visualizer-spacing 2)))
+
+  (let* ((undo-tree-insert-face (and undo-tree-insert-face
+				     (or (and (consp undo-tree-insert-face)
+					      undo-tree-insert-face)
+					 (list undo-tree-insert-face))))
+	 (register (undo-tree-node-register node))
+	 (unmodified (if undo-tree-visualizer-parent-mtime
+			 (undo-tree-node-unmodified-p
+			  node undo-tree-visualizer-parent-mtime)
+		       (undo-tree-node-unmodified-p node)))
+	node-string)
+    ;; check node's register (if any) still stores appropriate undo-tree state
+    (unless (and register
+		 (undo-tree-register-data-p
+		  (registerv-data (get-register register)))
+		 (eq node (undo-tree-register-data-node
+			   (registerv-data (get-register register)))))
+      (setq register nil))
+    ;; represent node by different symbols, depending on whether it's the
+    ;; current node, is saved in a register, or corresponds to an unmodified
+    ;; buffer
+    (setq node-string
+	    (cond
+	     (undo-tree-visualizer-timestamps
+	        (undo-tree-timestamp-to-string
+	         (undo-tree-node-timestamp node)
+		 undo-tree-visualizer-relative-timestamps
+		 current register))
+	     (register (char-to-string register))
+	     (unmodified "s")
+	     (current "x")
+	     (t "o"))
+	  undo-tree-insert-face
+	    (nconc
+	     (cond
+	      (current    '(undo-tree-visualizer-current-face))
+	      (unmodified '(undo-tree-visualizer-unmodified-face))
+	      (register   '(undo-tree-visualizer-register-face)))
+	     undo-tree-insert-face))
+    ;; draw node and link it to its representation in visualizer
+    (undo-tree-insert node-string)
+    (undo-tree-move-backward (if undo-tree-visualizer-timestamps
+				 (1+ (/ undo-tree-visualizer-spacing 2))
+			       1))
+    (move-marker (undo-tree-node-marker node) (point))
+    (put-text-property (point) (1+ (point)) 'undo-tree-node node)))
+
+
+(defun undo-tree-draw-subtree (node &optional active-branch)
+  ;; Draw subtree rooted at NODE. The subtree will start from point.
+  ;; If ACTIVE-BRANCH is non-nil, just draw active branch below NODE. Returns
+  ;; list of nodes below NODE.
+  (let ((num-children (length (undo-tree-node-next node)))
+        node-list pos trunk-pos n)
+    ;; draw node itself
+    (undo-tree-draw-node node)
+
+    (cond
+     ;; if we're at a leaf node, we're done
+     ((= num-children 0))
+
+     ;; if node has only one child, draw it (not strictly necessary to deal
+     ;; with this case separately, but as it's by far the most common case
+     ;; this makes the code clearer and more efficient)
+     ((= num-children 1)
+      (undo-tree-move-down 1)
+      (undo-tree-insert ?|)
+      (undo-tree-move-backward 1)
+      (undo-tree-move-down 1)
+      (undo-tree-insert ?|)
+      (undo-tree-move-backward 1)
+      (undo-tree-move-down 1)
+      (setq n (car (undo-tree-node-next node)))
+      ;; link next node to its representation in visualizer
+      (unless (markerp (undo-tree-node-marker n))
+        (setf (undo-tree-node-marker n) (make-marker))
+        (set-marker-insertion-type (undo-tree-node-marker n) nil))
+      (move-marker (undo-tree-node-marker n) (point))
+      ;; add next node to list of nodes to draw next
+      (push n node-list))
+
+     ;; if node has multiple children, draw branches
+     (t
+      (undo-tree-move-down 1)
+      (undo-tree-insert ?|)
+      (undo-tree-move-backward 1)
+      (move-marker (setq trunk-pos (make-marker)) (point))
+      ;; left subtrees
+      (undo-tree-move-backward
+       (- (undo-tree-node-char-lwidth node)
+          (undo-tree-node-char-lwidth
+           (car (undo-tree-node-next node)))))
+      (move-marker (setq pos (make-marker)) (point))
+      (setq n (cons nil (undo-tree-node-next node)))
+      (dotimes (i (/ num-children 2))
+        (setq n (cdr n))
+        (when (or (null active-branch)
+                  (eq (car n)
+                      (nth (undo-tree-node-branch node)
+                           (undo-tree-node-next node))))
+          (undo-tree-move-forward 2)
+          (undo-tree-insert ?_ (- trunk-pos pos 2))
+          (goto-char pos)
+          (undo-tree-move-forward 1)
+          (undo-tree-move-down 1)
+          (undo-tree-insert ?/)
+          (undo-tree-move-backward 2)
+          (undo-tree-move-down 1)
+          ;; link node to its representation in visualizer
+          (unless (markerp (undo-tree-node-marker (car n)))
+            (setf (undo-tree-node-marker (car n)) (make-marker))
+            (set-marker-insertion-type (undo-tree-node-marker (car n)) nil))
+          (move-marker (undo-tree-node-marker (car n)) (point))
+          ;; add node to list of nodes to draw next
+          (push (car n) node-list))
+        (goto-char pos)
+        (undo-tree-move-forward
+         (+ (undo-tree-node-char-rwidth (car n))
+            (undo-tree-node-char-lwidth (cadr n))
+            undo-tree-visualizer-spacing 1))
+        (move-marker pos (point)))
+      ;; middle subtree (only when number of children is odd)
+      (when (= (mod num-children 2) 1)
+        (setq n (cdr n))
+        (when (or (null active-branch)
+                  (eq (car n)
+                      (nth (undo-tree-node-branch node)
+                           (undo-tree-node-next node))))
+          (undo-tree-move-down 1)
+          (undo-tree-insert ?|)
+          (undo-tree-move-backward 1)
+          (undo-tree-move-down 1)
+          ;; link node to its representation in visualizer
+          (unless (markerp (undo-tree-node-marker (car n)))
+            (setf (undo-tree-node-marker (car n)) (make-marker))
+            (set-marker-insertion-type (undo-tree-node-marker (car n)) nil))
+          (move-marker (undo-tree-node-marker (car n)) (point))
+          ;; add node to list of nodes to draw next
+          (push (car n) node-list))
+        (goto-char pos)
+        (undo-tree-move-forward
+         (+ (undo-tree-node-char-rwidth (car n))
+            (if (cadr n) (undo-tree-node-char-lwidth (cadr n)) 0)
+            undo-tree-visualizer-spacing 1))
+        (move-marker pos (point)))
+      ;; right subtrees
+      (move-marker trunk-pos (1+ trunk-pos))
+      (dotimes (i (/ num-children 2))
+        (setq n (cdr n))
+        (when (or (null active-branch)
+                  (eq (car n)
+                      (nth (undo-tree-node-branch node)
+                           (undo-tree-node-next node))))
+          (goto-char trunk-pos)
+          (undo-tree-insert ?_ (- pos trunk-pos 1))
+          (goto-char pos)
+          (undo-tree-move-backward 1)
+          (undo-tree-move-down 1)
+          (undo-tree-insert ?\\)
+          (undo-tree-move-down 1)
+          ;; link node to its representation in visualizer
+          (unless (markerp (undo-tree-node-marker (car n)))
+            (setf (undo-tree-node-marker (car n)) (make-marker))
+            (set-marker-insertion-type (undo-tree-node-marker (car n)) nil))
+          (move-marker (undo-tree-node-marker (car n)) (point))
+          ;; add node to list of nodes to draw next
+          (push (car n) node-list))
+        (when (cdr n)
+          (goto-char pos)
+          (undo-tree-move-forward
+           (+ (undo-tree-node-char-rwidth (car n))
+              (if (cadr n) (undo-tree-node-char-lwidth (cadr n)) 0)
+              undo-tree-visualizer-spacing 1))
+          (move-marker pos (point))))
+      ))
+    ;; return list of nodes to draw next
+    (nreverse node-list)))
+
+
+(defun undo-tree-node-char-lwidth (node)
+  ;; Return left-width of NODE measured in characters.
+  (if (= (length (undo-tree-node-next node)) 0) 0
+    (- (* (+ undo-tree-visualizer-spacing 1) (undo-tree-node-lwidth node))
+       (if (= (undo-tree-node-cwidth node) 0)
+           (1+ (/ undo-tree-visualizer-spacing 2)) 0))))
+
+
+(defun undo-tree-node-char-rwidth (node)
+  ;; Return right-width of NODE measured in characters.
+  (if (= (length (undo-tree-node-next node)) 0) 0
+    (- (* (+ undo-tree-visualizer-spacing 1) (undo-tree-node-rwidth node))
+       (if (= (undo-tree-node-cwidth node) 0)
+           (1+ (/ undo-tree-visualizer-spacing 2)) 0))))
+
+
+(defun undo-tree-insert (str &optional arg)
+  ;; Insert character or string STR ARG times, overwriting, and using
+  ;; `undo-tree-insert-face'.
+  (unless arg (setq arg 1))
+  (when (characterp str)
+    (setq str (make-string arg str))
+    (setq arg 1))
+  (dotimes (i arg) (insert str))
+  (setq arg (* arg (length str)))
+  (undo-tree-move-forward arg)
+  ;; make sure mark isn't active, otherwise `backward-delete-char' might
+  ;; delete region instead of single char if transient-mark-mode is enabled
+  (setq mark-active nil)
+  (backward-delete-char arg)
+  (when undo-tree-insert-face
+    (put-text-property (- (point) arg) (point) 'face undo-tree-insert-face)))
+
+
+(defun undo-tree-move-down (&optional arg)
+  ;; Move down, extending buffer if necessary.
+  (let ((row (line-number-at-pos))
+        (col (current-column))
+        line)
+    (unless arg (setq arg 1))
+    (forward-line arg)
+    (setq line (line-number-at-pos))
+    ;; if buffer doesn't have enough lines, add some
+    (when (/= line (+ row arg))
+      (cond
+       ((< arg 0)
+	(insert (make-string (- line row arg) ?\n))
+	(forward-line (+ arg (- row line))))
+       (t (insert (make-string (- arg (- line row)) ?\n)))))
+    (undo-tree-move-forward col)))
+
+
+(defun undo-tree-move-up (&optional arg)
+  ;; Move up, extending buffer if necessary.
+  (unless arg (setq arg 1))
+  (undo-tree-move-down (- arg)))
+
+
+(defun undo-tree-move-forward (&optional arg)
+  ;; Move forward, extending buffer if necessary.
+  (unless arg (setq arg 1))
+  (let (n)
+    (cond
+     ((>= arg 0)
+      (setq n (- (line-end-position) (point)))
+      (if (> n arg)
+	  (forward-char arg)
+	(end-of-line)
+	(insert (make-string (- arg n) ? ))))
+     ((< arg 0)
+      (setq arg (- arg))
+      (setq n (- (point) (line-beginning-position)))
+      (when (< (- n 2) arg)  ; -2 to create left-margin
+	;; no space left - shift entire buffer contents right!
+	(let ((pos (move-marker (make-marker) (point))))
+	  (set-marker-insertion-type pos t)
+	  (goto-char (point-min))
+	  (while (not (eobp))
+	    (insert-before-markers (make-string (- arg -2 n) ? ))
+	    (forward-line 1))
+	  (goto-char pos)))
+      (backward-char arg)))))
+
+
+(defun undo-tree-move-backward (&optional arg)
+  ;; Move backward, extending buffer if necessary.
+  (unless arg (setq arg 1))
+  (undo-tree-move-forward (- arg)))
+
+
+(defun undo-tree-move-to-parent (node)
+  ;; Move to position of parent of NODE, extending buffer if necessary.
+  (let* ((parent (undo-tree-node-previous node))
+	 (n (undo-tree-node-next parent))
+	 (l (length n)) p)
+    (goto-char (undo-tree-node-marker node))
+    (unless (= l 1)
+      ;; move horizontally
+      (setq p (undo-tree-position node n))
+      (cond
+       ;; node in centre subtree: no horizontal movement
+       ((and (= (mod l 2) 1) (= p (/ l 2))))
+       ;; node in left subtree: move right
+       ((< p (/ l 2))
+	(setq n (nthcdr p n))
+	(undo-tree-move-forward
+	 (+ (undo-tree-node-char-rwidth (car n))
+	    (/ undo-tree-visualizer-spacing 2) 1))
+	(dotimes (i (- (/ l 2) p 1))
+	  (setq n (cdr n))
+	  (undo-tree-move-forward
+	   (+ (undo-tree-node-char-lwidth (car n))
+	      (undo-tree-node-char-rwidth (car n))
+	      undo-tree-visualizer-spacing 1)))
+	(when (= (mod l 2) 1)
+	  (setq n (cdr n))
+	  (undo-tree-move-forward
+	   (+ (undo-tree-node-char-lwidth (car n))
+	      (/ undo-tree-visualizer-spacing 2) 1))))
+       (t ;; node in right subtree: move left
+	(setq n (nthcdr (/ l 2) n))
+	(when (= (mod l 2) 1)
+	  (undo-tree-move-backward
+	   (+ (undo-tree-node-char-rwidth (car n))
+	      (/ undo-tree-visualizer-spacing 2) 1))
+	  (setq n (cdr n)))
+	(dotimes (i (- p (/ l 2) (mod l 2)))
+	  (undo-tree-move-backward
+	   (+ (undo-tree-node-char-lwidth (car n))
+	      (undo-tree-node-char-rwidth (car n))
+	      undo-tree-visualizer-spacing 1))
+	  (setq n (cdr n)))
+	(undo-tree-move-backward
+	 (+ (undo-tree-node-char-lwidth (car n))
+	    (/ undo-tree-visualizer-spacing 2) 1)))))
+    ;; move vertically
+    (undo-tree-move-up 3)))
+
+
+(defun undo-tree-timestamp-to-string
+  (timestamp &optional relative current register)
+  ;; Convert TIMESTAMP to string (either absolute or RELATVE time), indicating
+  ;; if it's the CURRENT node and/or has an associated REGISTER.
+  (if relative
+      ;; relative time
+      (let ((time (floor (float-time
+			  (subtract-time (current-time) timestamp))))
+	    n)
+	(setq time
+	      ;; years
+	      (if (> (setq n (/ time 315360000)) 0)
+		  (if (> n 999) "-ages" (format "-%dy" n))
+		(setq time (% time 315360000))
+		;; days
+		(if (> (setq n (/ time 86400)) 0)
+		    (format "-%dd" n)
+		  (setq time (% time 86400))
+		  ;; hours
+		  (if (> (setq n (/ time 3600)) 0)
+		      (format "-%dh" n)
+		    (setq time (% time 3600))
+		    ;; mins
+		    (if (> (setq n (/ time 60)) 0)
+			(format "-%dm" n)
+		      ;; secs
+		      (format "-%ds" (% time 60)))))))
+	(setq time (concat
+		    (if current "*" " ")
+		    time
+		    (if register (concat "[" (char-to-string register) "]")
+		      "   ")))
+	(setq n (length time))
+	(if (< n 9)
+	    (concat (make-string (- 9 n) ? ) time)
+	  time))
+    ;; absolute time
+    (concat (if current " *" "  ")
+	    (format-time-string "%H:%M:%S" timestamp)
+	    (if register
+		(concat "[" (char-to-string register) "]")
+	      "   "))))
+
+
+
+
+;;; =====================================================================
+;;;                        Visualizer commands
+
+(define-derived-mode
+  undo-tree-visualizer-mode special-mode "undo-tree-visualizer"
+  "Major mode used in undo-tree visualizer.
+
+The undo-tree visualizer can only be invoked from a buffer in
+which `undo-tree-mode' is enabled. The visualizer displays the
+undo history tree graphically, and allows you to browse around
+the undo history, undoing or redoing the corresponding changes in
+the parent buffer.
+
+Within the undo-tree visualizer, the following keys are available:
+
+  \\{undo-tree-visualizer-mode-map}"
+  :syntax-table nil
+  :abbrev-table nil
+  (setq truncate-lines t)
+  (setq cursor-type nil)
+  (setq undo-tree-visualizer-selected-node nil))
+
+
+
+(defun undo-tree-visualize-undo (&optional arg)
+  "Undo changes. A numeric ARG serves as a repeat count."
+  (interactive "p")
+  (let ((old (undo-tree-current buffer-undo-tree))
+	current)
+    ;; unhighlight old current node
+    (let ((undo-tree-insert-face 'undo-tree-visualizer-active-branch-face)
+	  (inhibit-read-only t))
+      (undo-tree-draw-node old))
+    ;; undo in parent buffer
+    (switch-to-buffer-other-window undo-tree-visualizer-parent-buffer)
+    (deactivate-mark)
+    (unwind-protect
+	(let ((undo-tree-inhibit-kill-visualizer t)) (undo-tree-undo-1 arg))
+      (setq current (undo-tree-current buffer-undo-tree))
+      (switch-to-buffer-other-window undo-tree-visualizer-buffer-name)
+      ;; when using lazy drawing, extend tree upwards as required
+      (when undo-tree-visualizer-lazy-drawing
+	(undo-tree-expand-up old current))
+      ;; highlight new current node
+      (let ((inhibit-read-only t)) (undo-tree-draw-node current 'current))
+      ;; update diff display, if any
+      (when undo-tree-visualizer-diff (undo-tree-visualizer-update-diff)))))
+
+
+(defun undo-tree-visualize-redo (&optional arg)
+  "Redo changes. A numeric ARG serves as a repeat count."
+  (interactive "p")
+  (let ((old (undo-tree-current buffer-undo-tree))
+	current)
+    ;; unhighlight old current node
+    (let ((undo-tree-insert-face 'undo-tree-visualizer-active-branch-face)
+	  (inhibit-read-only t))
+      (undo-tree-draw-node (undo-tree-current buffer-undo-tree)))
+    ;; redo in parent buffer
+    (switch-to-buffer-other-window undo-tree-visualizer-parent-buffer)
+    (deactivate-mark)
+    (unwind-protect
+	(let ((undo-tree-inhibit-kill-visualizer t)) (undo-tree-redo-1 arg))
+      (setq current (undo-tree-current buffer-undo-tree))
+      (switch-to-buffer-other-window undo-tree-visualizer-buffer-name)
+      ;; when using lazy drawing, extend tree downwards as required
+      (when undo-tree-visualizer-lazy-drawing
+	(undo-tree-expand-down old current))
+      ;; highlight new current node
+      (let ((inhibit-read-only t)) (undo-tree-draw-node current 'current))
+      ;; update diff display, if any
+      (when undo-tree-visualizer-diff (undo-tree-visualizer-update-diff)))))
+
+
+(defun undo-tree-visualize-switch-branch-right (arg)
+  "Switch to next branch of the undo tree.
+This will affect which branch to descend when *redoing* changes
+using `undo-tree-redo' or `undo-tree-visualizer-redo'."
+  (interactive "p")
+  ;; un-highlight old active branch below current node
+  (goto-char (undo-tree-node-marker (undo-tree-current buffer-undo-tree)))
+  (let ((undo-tree-insert-face 'undo-tree-visualizer-default-face)
+	(inhibit-read-only t))
+    (undo-tree-highlight-active-branch (undo-tree-current buffer-undo-tree)))
+  ;; increment branch
+  (let ((branch (undo-tree-node-branch (undo-tree-current buffer-undo-tree))))
+  (setf (undo-tree-node-branch (undo-tree-current buffer-undo-tree))
+        (cond
+         ((>= (+ branch arg) (undo-tree-num-branches))
+          (1- (undo-tree-num-branches)))
+         ((<= (+ branch arg) 0) 0)
+         (t (+ branch arg))))
+  (let ((inhibit-read-only t))
+    ;; highlight new active branch below current node
+    (goto-char (undo-tree-node-marker (undo-tree-current buffer-undo-tree)))
+    (let ((undo-tree-insert-face 'undo-tree-visualizer-active-branch-face))
+      (undo-tree-highlight-active-branch (undo-tree-current buffer-undo-tree)))
+    ;; re-highlight current node
+    (undo-tree-draw-node (undo-tree-current buffer-undo-tree) 'current))))
+
+
+(defun undo-tree-visualize-switch-branch-left (arg)
+  "Switch to previous branch of the undo tree.
+This will affect which branch to descend when *redoing* changes
+using `undo-tree-redo' or `undo-tree-visualizer-redo'."
+  (interactive "p")
+  (undo-tree-visualize-switch-branch-right (- arg)))
+
+
+(defun undo-tree-visualizer-quit ()
+  "Quit the undo-tree visualizer."
+  (interactive)
+  (undo-tree-clear-visualizer-data buffer-undo-tree)
+  ;; remove kill visualizer hook from parent buffer
+  (unwind-protect
+      (with-current-buffer undo-tree-visualizer-parent-buffer
+	(remove-hook 'before-change-functions 'undo-tree-kill-visualizer t))
+    ;; kill diff buffer, if any
+    (when undo-tree-visualizer-diff (undo-tree-visualizer-hide-diff))
+    (let ((parent undo-tree-visualizer-parent-buffer)
+	  window)
+      ;; kill visualizer buffer
+      (kill-buffer nil)
+      ;; switch back to parent buffer
+      (unwind-protect
+	  (if (setq window (get-buffer-window parent))
+	      (select-window window)
+	    (switch-to-buffer parent))))))
+
+
+(defun undo-tree-visualizer-abort ()
+  "Quit the undo-tree visualizer and return buffer to original state."
+  (interactive)
+  (let ((node undo-tree-visualizer-initial-node))
+    (undo-tree-visualizer-quit)
+    (undo-tree-set node)))
+
+
+(defun undo-tree-visualizer-set (&optional pos)
+  "Set buffer to state corresponding to undo tree node
+at POS, or point if POS is nil."
+  (interactive)
+  (unless pos (setq pos (point)))
+  (let ((node (get-text-property pos 'undo-tree-node)))
+    (when node
+      ;; set parent buffer to state corresponding to node at POS
+      (switch-to-buffer-other-window undo-tree-visualizer-parent-buffer)
+      (let ((undo-tree-inhibit-kill-visualizer t)) (undo-tree-set node))
+      (switch-to-buffer-other-window undo-tree-visualizer-buffer-name)
+      ;; re-draw undo tree
+      (let ((inhibit-read-only t)) (undo-tree-draw-tree buffer-undo-tree))
+      (when undo-tree-visualizer-diff (undo-tree-visualizer-update-diff)))))
+
+
+(defun undo-tree-visualizer-mouse-set (pos)
+  "Set buffer to state corresponding to undo tree node
+at mouse event POS."
+  (interactive "@e")
+  (undo-tree-visualizer-set (event-start (nth 1 pos))))
+
+
+(defun undo-tree-visualize-undo-to-x (&optional x)
+  "Undo to last branch point, register, or saved state.
+If X is the symbol `branch', undo to last branch point. If X is
+the symbol `register', undo to last register. If X is the sumbol
+`saved', undo to last saved state. If X is null, undo to first of
+these that's encountered.
+
+Interactively, a single \\[universal-argument] specifies
+`branch', a double \\[universal-argument] \\[universal-argument]
+specifies `saved', and a negative prefix argument specifies
+`register'."
+  (interactive "P")
+  (when (and (called-interactively-p 'any) x)
+    (setq x (prefix-numeric-value x)
+	  x (cond
+	     ((< x 0)  'register)
+	     ((<= x 4) 'branch)
+	     (t        'saved))))
+  (let ((current (if undo-tree-visualizer-selection-mode
+		     undo-tree-visualizer-selected-node
+		   (undo-tree-current buffer-undo-tree)))
+	(diff undo-tree-visualizer-diff)
+	r)
+    (undo-tree-visualizer-hide-diff)
+    (while (and (undo-tree-node-previous current)
+		(or (if undo-tree-visualizer-selection-mode
+			(progn
+			  (undo-tree-visualizer-select-previous)
+			  (setq current undo-tree-visualizer-selected-node))
+		      (undo-tree-visualize-undo)
+		      (setq current (undo-tree-current buffer-undo-tree)))
+		    t)
+		         ;; branch point
+		(not (or (and (or (null x) (eq x 'branch))
+			      (> (undo-tree-num-branches) 1))
+			 ;; register
+			 (and (or (null x) (eq x 'register))
+			      (setq r (undo-tree-node-register current))
+			      (undo-tree-register-data-p
+			       (setq r (registerv-data (get-register r))))
+			      (eq current (undo-tree-register-data-node r)))
+			 ;; saved state
+			 (and (or (null x) (eq x 'saved))
+			      (undo-tree-node-unmodified-p current))
+			 ))))
+    ;; update diff display, if any
+    (when diff
+      (undo-tree-visualizer-show-diff
+       (when undo-tree-visualizer-selection-mode
+	 undo-tree-visualizer-selected-node)))))
+
+
+(defun undo-tree-visualize-redo-to-x (&optional x)
+  "Redo to last branch point, register, or saved state.
+If X is the symbol `branch', redo to last branch point. If X is
+the symbol `register', redo to last register. If X is the sumbol
+`saved', redo to last saved state. If X is null, redo to first of
+these that's encountered.
+
+Interactively, a single \\[universal-argument] specifies
+`branch', a double \\[universal-argument] \\[universal-argument]
+specifies `saved', and a negative prefix argument specifies
+`register'."
+  (interactive "P")
+  (when (and (called-interactively-p 'any) x)
+    (setq x (prefix-numeric-value x)
+	  x (cond
+	     ((< x 0)  'register)
+	     ((<= x 4) 'branch)
+	     (t        'saved))))
+  (let ((current (if undo-tree-visualizer-selection-mode
+		     undo-tree-visualizer-selected-node
+		   (undo-tree-current buffer-undo-tree)))
+	(diff undo-tree-visualizer-diff)
+	r)
+    (undo-tree-visualizer-hide-diff)
+    (while (and (undo-tree-node-next current)
+		(or (if undo-tree-visualizer-selection-mode
+			(progn
+			  (undo-tree-visualizer-select-next)
+			  (setq current undo-tree-visualizer-selected-node))
+		      (undo-tree-visualize-redo)
+		      (setq current (undo-tree-current buffer-undo-tree)))
+		    t)
+		         ;; branch point
+		(not (or (and (or (null x) (eq x 'branch))
+			      (> (undo-tree-num-branches) 1))
+			 ;; register
+			 (and (or (null x) (eq x 'register))
+			      (setq r (undo-tree-node-register current))
+			      (undo-tree-register-data-p
+			       (setq r (registerv-data (get-register r))))
+			      (eq current (undo-tree-register-data-node r)))
+			 ;; saved state
+			 (and (or (null x) (eq x 'saved))
+			      (undo-tree-node-unmodified-p current))
+			 ))))
+    ;; update diff display, if any
+    (when diff
+      (undo-tree-visualizer-show-diff
+       (when undo-tree-visualizer-selection-mode
+	 undo-tree-visualizer-selected-node)))))
+
+
+(defun undo-tree-visualizer-toggle-timestamps ()
+  "Toggle display of time-stamps."
+  (interactive)
+  (setq undo-tree-visualizer-timestamps (not undo-tree-visualizer-timestamps))
+  (setq undo-tree-visualizer-spacing (undo-tree-visualizer-calculate-spacing))
+  ;; redraw tree
+  (let ((inhibit-read-only t)) (undo-tree-draw-tree buffer-undo-tree)))
+
+
+(defun undo-tree-visualizer-scroll-left (&optional arg)
+  (interactive "p")
+  (scroll-left (or arg 1) t))
+
+
+(defun undo-tree-visualizer-scroll-right (&optional arg)
+  (interactive "p")
+  (scroll-right (or arg 1) t))
+
+
+(defun undo-tree-visualizer-scroll-up (&optional arg)
+  (interactive "P")
+  (if (or (and (numberp arg) (< arg 0)) (eq arg '-))
+      (undo-tree-visualizer-scroll-down arg)
+    ;; scroll up and expand newly-visible portion of tree
+    (unwind-protect
+	(scroll-up-command arg)
+      (undo-tree-expand-down
+       (nth (undo-tree-node-branch (undo-tree-current buffer-undo-tree))
+	    (undo-tree-node-next (undo-tree-current buffer-undo-tree)))))
+    ;; signal error if at eob
+    (when (and (not undo-tree-visualizer-needs-extending-down) (eobp))
+      (scroll-up))))
+
+
+(defun undo-tree-visualizer-scroll-down (&optional arg)
+  (interactive "P")
+  (if (or (and (numberp arg) (< arg 0)) (eq arg '-))
+      (undo-tree-visualizer-scroll-up arg)
+    ;; ensure there's enough room at top of buffer to scroll
+    (let ((scroll-lines
+	   (or arg (- (window-height) next-screen-context-lines)))
+	  (window-line (1- (line-number-at-pos (window-start)))))
+      (when (and undo-tree-visualizer-needs-extending-up
+		 (< window-line scroll-lines))
+	(let ((inhibit-read-only t))
+	  (goto-char (point-min))
+	  (undo-tree-move-up (- scroll-lines window-line)))))
+    ;; scroll down and expand newly-visible portion of tree
+    (unwind-protect
+	(scroll-down-command arg)
+      (undo-tree-expand-up
+       (undo-tree-node-previous (undo-tree-current buffer-undo-tree))))
+    ;; signal error if at bob
+    (when (and (not undo-tree-visualizer-needs-extending-down) (bobp))
+      (scroll-down))))
+
+
+
+
+;;; =====================================================================
+;;;                    Visualizer selection mode
+
+(define-minor-mode undo-tree-visualizer-selection-mode
+  "Toggle mode to select nodes in undo-tree visualizer."
+  :lighter "Select"
+  :keymap undo-tree-visualizer-selection-mode-map
+  :group undo-tree
+  (cond
+   ;; enable selection mode
+   (undo-tree-visualizer-selection-mode
+    (setq cursor-type 'box)
+    (setq undo-tree-visualizer-selected-node
+	  (undo-tree-current buffer-undo-tree))
+    ;; erase diff (if any), as initially selected node is identical to current
+    (when undo-tree-visualizer-diff
+      (let ((buff (get-buffer undo-tree-diff-buffer-name))
+	    (inhibit-read-only t))
+	(when buff (with-current-buffer buff (erase-buffer))))))
+   (t ;; disable selection mode
+    (setq cursor-type nil)
+    (setq undo-tree-visualizer-selected-node nil)
+    (goto-char (undo-tree-node-marker (undo-tree-current buffer-undo-tree)))
+    (when undo-tree-visualizer-diff (undo-tree-visualizer-update-diff)))
+   ))
+
+
+(defun undo-tree-visualizer-select-previous (&optional arg)
+  "Move to previous node."
+  (interactive "p")
+  (let ((node undo-tree-visualizer-selected-node))
+    (catch 'top
+      (dotimes (i (or arg 1))
+	(unless (undo-tree-node-previous node) (throw 'top t))
+	(setq node (undo-tree-node-previous node))))
+    ;; when using lazy drawing, extend tree upwards as required
+    (when undo-tree-visualizer-lazy-drawing
+      (undo-tree-expand-up undo-tree-visualizer-selected-node node))
+    ;; update diff display, if any
+    (when (and undo-tree-visualizer-diff
+	       (not (eq node undo-tree-visualizer-selected-node)))
+      (undo-tree-visualizer-update-diff node))
+    ;; move to selected node
+    (goto-char (undo-tree-node-marker node))
+    (setq undo-tree-visualizer-selected-node node)))
+
+
+(defun undo-tree-visualizer-select-next (&optional arg)
+  "Move to next node."
+  (interactive "p")
+  (let ((node undo-tree-visualizer-selected-node))
+    (catch 'bottom
+      (dotimes (i (or arg 1))
+	(unless (nth (undo-tree-node-branch node) (undo-tree-node-next node))
+	  (throw 'bottom t))
+	(setq node
+	      (nth (undo-tree-node-branch node) (undo-tree-node-next node)))))
+    ;; when using lazy drawing, extend tree downwards as required
+    (when undo-tree-visualizer-lazy-drawing
+      (undo-tree-expand-down undo-tree-visualizer-selected-node node))
+    ;; update diff display, if any
+    (when (and undo-tree-visualizer-diff
+	       (not (eq node undo-tree-visualizer-selected-node)))
+      (undo-tree-visualizer-update-diff node))
+    ;; move to selected node
+    (goto-char (undo-tree-node-marker node))
+    (setq undo-tree-visualizer-selected-node node)))
+
+
+(defun undo-tree-visualizer-select-right (&optional arg)
+  "Move right to a sibling node."
+  (interactive "p")
+  (let ((node undo-tree-visualizer-selected-node)
+	end)
+    (goto-char (undo-tree-node-marker undo-tree-visualizer-selected-node))
+    (setq end (line-end-position))
+    (catch 'end
+      (dotimes (i arg)
+	(while (or (null node) (eq node undo-tree-visualizer-selected-node))
+	  (forward-char)
+	  (setq node (get-text-property (point) 'undo-tree-node))
+	  (when (= (point) end) (throw 'end t)))))
+    (goto-char (undo-tree-node-marker
+		(or node undo-tree-visualizer-selected-node)))
+    (when (and undo-tree-visualizer-diff node
+	       (not (eq node undo-tree-visualizer-selected-node)))
+      (undo-tree-visualizer-update-diff node))
+    (when node (setq undo-tree-visualizer-selected-node node))))
+
+
+(defun undo-tree-visualizer-select-left (&optional arg)
+  "Move left to a sibling node."
+  (interactive "p")
+  (let ((node (get-text-property (point) 'undo-tree-node))
+	beg)
+    (goto-char (undo-tree-node-marker undo-tree-visualizer-selected-node))
+    (setq beg (line-beginning-position))
+    (catch 'beg
+      (dotimes (i arg)
+	(while (or (null node) (eq node undo-tree-visualizer-selected-node))
+	  (backward-char)
+	  (setq node (get-text-property (point) 'undo-tree-node))
+	  (when (= (point) beg) (throw 'beg t)))))
+    (goto-char (undo-tree-node-marker
+		(or node undo-tree-visualizer-selected-node)))
+    (when (and undo-tree-visualizer-diff node
+	       (not (eq node undo-tree-visualizer-selected-node)))
+      (undo-tree-visualizer-update-diff node))
+    (when node (setq undo-tree-visualizer-selected-node node))))
+
+
+(defun undo-tree-visualizer-select (pos)
+  (let ((node (get-text-property pos 'undo-tree-node)))
+    (when node
+      ;; select node at POS
+      (goto-char (undo-tree-node-marker node))
+      ;; when using lazy drawing, extend tree up and down as required
+      (when undo-tree-visualizer-lazy-drawing
+	(undo-tree-expand-up undo-tree-visualizer-selected-node node)
+	(undo-tree-expand-down undo-tree-visualizer-selected-node node))
+      ;; update diff display, if any
+      (when (and undo-tree-visualizer-diff
+		 (not (eq node undo-tree-visualizer-selected-node)))
+	(undo-tree-visualizer-update-diff node))
+      ;; update selected node
+      (setq undo-tree-visualizer-selected-node node)
+      )))
+
+
+(defun undo-tree-visualizer-mouse-select (pos)
+  "Select undo tree node at mouse event POS."
+  (interactive "@e")
+  (undo-tree-visualizer-select (event-start (nth 1 pos))))
+
+
+
+
+;;; =====================================================================
+;;;                      Visualizer diff display
+
+(defun undo-tree-visualizer-toggle-diff ()
+  "Toggle diff display in undo-tree visualizer."
+  (interactive)
+  (if undo-tree-visualizer-diff
+      (undo-tree-visualizer-hide-diff)
+    (undo-tree-visualizer-show-diff)))
+
+
+(defun undo-tree-visualizer-selection-toggle-diff ()
+  "Toggle diff display in undo-tree visualizer selection mode."
+  (interactive)
+  (if undo-tree-visualizer-diff
+      (undo-tree-visualizer-hide-diff)
+    (let ((node (get-text-property (point) 'undo-tree-node)))
+      (when node (undo-tree-visualizer-show-diff node)))))
+
+
+(defun undo-tree-visualizer-show-diff (&optional node)
+  ;; show visualizer diff display
+  (setq undo-tree-visualizer-diff t)
+  (let ((buff (with-current-buffer undo-tree-visualizer-parent-buffer
+		(undo-tree-diff node)))
+	(display-buffer-mark-dedicated 'soft)
+	win)
+    (setq win (split-window))
+    (set-window-buffer win buff)
+    (shrink-window-if-larger-than-buffer win)))
+
+
+(defun undo-tree-visualizer-hide-diff ()
+  ;; hide visualizer diff display
+  (setq undo-tree-visualizer-diff nil)
+  (let ((win (get-buffer-window undo-tree-diff-buffer-name)))
+    (when win (with-selected-window win (kill-buffer-and-window)))))
+
+
+(defun undo-tree-diff (&optional node)
+  ;; Create diff between NODE and current state (or previous state and current
+  ;; state, if NODE is null). Returns buffer containing diff.
+  (let (tmpfile buff)
+    ;; generate diff
+    (let ((undo-tree-inhibit-kill-visualizer t)
+	  (current (undo-tree-current buffer-undo-tree)))
+      (undo-tree-set (or node (undo-tree-node-previous current) current)
+		     'preserve-timestamps)
+      (setq tmpfile (diff-file-local-copy (current-buffer)))
+      (undo-tree-set current 'preserve-timestamps))
+    (setq buff (diff-no-select
+		tmpfile (current-buffer) nil 'noasync
+		(get-buffer-create undo-tree-diff-buffer-name)))
+    ;; delete process messages and useless headers from diff buffer
+    (let ((inhibit-read-only t))
+      (with-current-buffer buff
+	(goto-char (point-min))
+	(delete-region (point) (1+ (line-end-position 3)))
+	(goto-char (point-max))
+	(forward-line -2)
+	(delete-region (point) (point-max))
+	(setq cursor-type nil)
+	(setq buffer-read-only t)))
+    buff))
+
+
+(defun undo-tree-visualizer-update-diff (&optional node)
+  ;; update visualizer diff display to show diff between current state and
+  ;; NODE (or previous state, if NODE is null)
+  (with-current-buffer undo-tree-visualizer-parent-buffer
+    (undo-tree-diff node))
+  (let ((win (get-buffer-window undo-tree-diff-buffer-name)))
+    (when win
+      (balance-windows)
+      (shrink-window-if-larger-than-buffer win))))
+
+;;;; ChangeLog:
+
+;; 2013-12-28  Toby S. Cubitt  <tsc25@cantab.net>
+;; 
+;; 	* undo-tree: Update to version 0.6.5.
+;; 
+;; 2012-12-05  Toby S. Cubitt  <tsc25@cantab.net>
+;; 
+;; 	Update undo-tree to version 0.6.3
+;; 
+;; 	* undo-tree.el: Implement lazy tree drawing to significantly speed up 
+;; 	visualization of large trees + various more minor improvements.
+;; 
+;; 2012-09-25  Toby S. Cubitt  <tsc25@cantab.net>
+;; 
+;; 	Updated undo-tree package to version 0.5.5.
+;; 
+;; 	Small bug-fix to avoid hooks triggering an error when trying to save
+;; 	undo history in a buffer where undo is disabled.
+;; 
+;; 2012-09-11  Toby S. Cubitt  <tsc25@cantab.net>
+;; 
+;; 	Updated undo-tree package to version 0.5.4
+;; 
+;; 	Bug-fixes and improvements to persistent history storage.
+;; 
+;; 2012-07-18  Toby S. Cubitt  <tsc25@cantab.net>
+;; 
+;; 	Update undo-tree to version 0.5.3
+;; 
+;; 	* undo-tree.el: Cope gracefully with undo boundaries being deleted
+;; 	 (cf. bug#11774). Allow customization of directory to which undo
+;; 	history is
+;; 	 saved.
+;; 
+;; 2012-05-24  Toby S. Cubitt  <tsc25@cantab.net>
+;; 
+;; 	updated undo-tree package to version 0.5.2
+;; 
+;; 	* undo-tree.el: add diff view feature in undo-tree visualizer.
+;; 
+;; 2012-05-02  Toby S. Cubitt  <tsc25@cantab.net>
+;; 
+;; 	undo-tree.el: Update package to version 0.4
+;; 
+;; 2012-04-20  Toby S. Cubitt  <tsc25@cantab.net>
+;; 
+;; 	undo-tree.el: Update package to version 0.3.4
+;; 
+;; 	* undo-tree.el (undo-list-pop-changeset): fix pernicious bug causing
+;; 	undo history to be lost.
+;; 	(buffer-undo-tree): set permanent-local property.
+;; 	(undo-tree-enable-undo-in-region): add new customization option
+;; 	allowing undo-in-region to be disabled.
+;; 
+;; 2012-01-26  Toby S. Cubitt  <tsc25@cantab.net>
+;; 
+;; 	undo-tree.el: Fixed copyright attribution and Emacs status.
+;; 
+;; 2012-01-26  Toby S. Cubitt  <tsc25@cantab.net>
+;; 
+;; 	undo-tree.el: Update package to version 0.3.3
+;; 
+;; 2011-09-17  Stefan Monnier  <monnier@iro.umontreal.ca>
+;; 
+;; 	Add undo-tree.el
+;; 
+
+
+
+
+(provide 'undo-tree)
+
+;;; undo-tree.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/undo-tree-0.6.5/undo-tree.elc b/configs/shared/emacs/.emacs.d/elpa/undo-tree-0.6.5/undo-tree.elc
new file mode 100644
index 0000000000..590aa72f52
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/undo-tree-0.6.5/undo-tree.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/dir b/configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/dir
new file mode 100644
index 0000000000..0bb7c7c750
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/dir
@@ -0,0 +1,18 @@
+This is the file .../info/dir, which contains the
+topmost node of the Info hierarchy, called (dir)Top.
+The first time you invoke Info you start off looking at this node.
+
+File: dir,	Node: Top	This is the top of the INFO tree
+
+  This (the Directory node) gives a menu of major topics.
+  Typing "q" exits, "?" lists all Info commands, "d" returns here,
+  "h" gives a primer for first-timers,
+  "mEmacs<Return>" visits the Emacs manual, etc.
+
+  In Emacs, you can click mouse button 2 on a menu item or cross reference
+  to select it.
+
+* Menu:
+
+Emacs
+* use-package: (use-package).   Declarative package configuration for Emacs.
diff --git a/configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package-autoloads.el
new file mode 100644
index 0000000000..6cf7ce5393
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package-autoloads.el
@@ -0,0 +1,209 @@
+;;; use-package-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "use-package-bind-key" "use-package-bind-key.el"
+;;;;;;  (23377 60538 906053 766000))
+;;; Generated autoloads from use-package-bind-key.el
+
+(autoload 'use-package-autoload-keymap "use-package-bind-key" "\
+Loads PACKAGE and then binds the key sequence used to invoke
+this function to KEYMAP-SYMBOL. It then simulates pressing the
+same key sequence a again, so that the next key pressed is routed
+to the newly loaded keymap.
+
+This function supports use-package's :bind-keymap keyword. It
+works by binding the given key sequence to an invocation of this
+function for a particular keymap. The keymap is expected to be
+defined by the package. In this way, loading the package is
+deferred until the prefix key sequence is pressed.
+
+\(fn KEYMAP-SYMBOL PACKAGE OVERRIDE)" nil nil)
+
+(autoload 'use-package-normalize-binder "use-package-bind-key" "\
+
+
+\(fn NAME KEYWORD ARGS)" nil nil)
+
+(defalias 'use-package-normalize/:bind 'use-package-normalize-binder)
+
+(defalias 'use-package-normalize/:bind* 'use-package-normalize-binder)
+
+(defalias 'use-package-autoloads/:bind 'use-package-autoloads-mode)
+
+(defalias 'use-package-autoloads/:bind* 'use-package-autoloads-mode)
+
+(autoload 'use-package-handler/:bind "use-package-bind-key" "\
+
+
+\(fn NAME KEYWORD ARGS REST STATE &optional BIND-MACRO)" nil nil)
+
+(defalias 'use-package-normalize/:bind-keymap 'use-package-normalize-binder)
+
+(defalias 'use-package-normalize/:bind-keymap* 'use-package-normalize-binder)
+
+(autoload 'use-package-handler/:bind-keymap "use-package-bind-key" "\
+
+
+\(fn NAME KEYWORD ARGS REST STATE &optional OVERRIDE)" nil nil)
+
+(autoload 'use-package-handler/:bind-keymap* "use-package-bind-key" "\
+
+
+\(fn NAME KEYWORD ARG REST STATE)" nil nil)
+
+;;;***
+
+;;;### (autoloads nil "use-package-core" "use-package-core.el" (23377
+;;;;;;  60538 889977 228000))
+;;; Generated autoloads from use-package-core.el
+
+(autoload 'use-package "use-package-core" "\
+Declare an Emacs package by specifying a group of configuration options.
+
+For full documentation, please see the README file that came with
+this file.  Usage:
+
+  (use-package package-name
+     [:keyword [option]]...)
+
+:init            Code to run before PACKAGE-NAME has been loaded.
+:config          Code to run after PACKAGE-NAME has been loaded.  Note that
+                 if loading is deferred for any reason, this code does not
+                 execute until the lazy load has occurred.
+:preface         Code to be run before everything except `:disabled'; this
+                 can be used to define functions for use in `:if', or that
+                 should be seen by the byte-compiler.
+
+:mode            Form to be added to `auto-mode-alist'.
+:magic           Form to be added to `magic-mode-alist'.
+:magic-fallback  Form to be added to `magic-fallback-mode-alist'.
+:interpreter     Form to be added to `interpreter-mode-alist'.
+
+:commands        Define autoloads for commands that will be defined by the
+                 package.  This is useful if the package is being lazily
+                 loaded, and you wish to conditionally call functions in your
+                 `:init' block that are defined in the package.
+
+:bind            Bind keys, and define autoloads for the bound commands.
+:bind*           Bind keys, and define autoloads for the bound commands,
+                 *overriding all minor mode bindings*.
+:bind-keymap     Bind a key prefix to an auto-loaded keymap defined in the
+                 package.  This is like `:bind', but for keymaps.
+:bind-keymap*    Like `:bind-keymap', but overrides all minor mode bindings
+
+:defer           Defer loading of a package -- this is implied when using
+                 `:commands', `:bind', `:bind*', `:mode', `:magic',
+                 `:magic-fallback', or `:interpreter'.  This can be an integer,
+                 to force loading after N seconds of idle time, if the package
+                 has not already been loaded.
+:after           Defer loading of a package until after any of the named
+                 features are loaded.
+:demand          Prevent deferred loading in all cases.
+
+:if EXPR         Initialize and load only if EXPR evaluates to a non-nil value.
+:disabled        The package is ignored completely if this keyword is present.
+:defines         Declare certain variables to silence the byte-compiler.
+:functions       Declare certain functions to silence the byte-compiler.
+:load-path       Add to the `load-path' before attempting to load the package.
+:diminish        Support for diminish.el (if installed).
+:delight         Support for delight.el (if installed).
+:custom          Call `customize-set-variable' with each variable definition.
+:custom-face     Call `customize-set-faces' with each face definition.
+:ensure          Loads the package using package.el if necessary.
+:pin             Pin the package to an archive.
+
+\(fn NAME &rest ARGS)" nil t)
+
+(function-put 'use-package 'lisp-indent-function '1)
+
+;;;***
+
+;;;### (autoloads nil "use-package-delight" "use-package-delight.el"
+;;;;;;  (23377 60538 896080 255000))
+;;; Generated autoloads from use-package-delight.el
+
+(autoload 'use-package-normalize/:delight "use-package-delight" "\
+Normalize arguments to delight.
+
+\(fn NAME KEYWORD ARGS)" nil nil)
+
+(autoload 'use-package-handler/:delight "use-package-delight" "\
+
+
+\(fn NAME KEYWORD ARGS REST STATE)" nil nil)
+
+;;;***
+
+;;;### (autoloads nil "use-package-diminish" "use-package-diminish.el"
+;;;;;;  (23377 60538 901745 880000))
+;;; Generated autoloads from use-package-diminish.el
+
+(autoload 'use-package-normalize/:diminish "use-package-diminish" "\
+
+
+\(fn NAME KEYWORD ARGS)" nil nil)
+
+(autoload 'use-package-handler/:diminish "use-package-diminish" "\
+
+
+\(fn NAME KEYWORD ARG REST STATE)" nil nil)
+
+;;;***
+
+;;;### (autoloads nil "use-package-ensure" "use-package-ensure.el"
+;;;;;;  (23377 60538 894186 46000))
+;;; Generated autoloads from use-package-ensure.el
+
+(autoload 'use-package-normalize/:ensure "use-package-ensure" "\
+
+
+\(fn NAME KEYWORD ARGS)" nil nil)
+
+(autoload 'use-package-handler/:ensure "use-package-ensure" "\
+
+
+\(fn NAME KEYWORD ENSURE REST STATE)" nil nil)
+
+;;;***
+
+;;;### (autoloads nil "use-package-jump" "use-package-jump.el" (23377
+;;;;;;  60538 904640 947000))
+;;; Generated autoloads from use-package-jump.el
+
+(autoload 'use-package-jump-to-package-form "use-package-jump" "\
+Attempt to find and jump to the `use-package' form that loaded
+PACKAGE. This will only find the form if that form actually
+required PACKAGE. If PACKAGE was previously required then this
+function will jump to the file that originally required PACKAGE
+instead.
+
+\(fn PACKAGE)" t nil)
+
+;;;***
+
+;;;### (autoloads nil "use-package-lint" "use-package-lint.el" (23377
+;;;;;;  60538 897482 478000))
+;;; Generated autoloads from use-package-lint.el
+
+(autoload 'use-package-lint "use-package-lint" "\
+Check for errors in use-package declarations.
+For example, if the module's `:if' condition is met, but even
+with the specified `:load-path' the module cannot be found.
+
+\(fn)" t nil)
+
+;;;***
+
+;;;### (autoloads nil nil ("use-package-pkg.el" "use-package.el")
+;;;;;;  (23377 60538 903152 452000))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; use-package-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package-bind-key.el b/configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package-bind-key.el
new file mode 100644
index 0000000000..e476b060ad
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package-bind-key.el
@@ -0,0 +1,172 @@
+;;; use-package-bind-key.el --- Support for the :bind/:bind-keymap keywords  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2012-2017 John Wiegley
+
+;; Author: John Wiegley <johnw@newartisans.com>
+;; Maintainer: John Wiegley <johnw@newartisans.com>
+;; Created: 17 Jun 2012
+;; Modified: 4 Dec 2017
+;; Version: 1.0
+;; Package-Requires: ((emacs "24.3") (use-package "2.4")  (bind-key "2.4"))
+;; Keywords: dotemacs startup speed config package
+;; URL: https://github.com/jwiegley/use-package
+
+;; This program 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, or (at
+;; your option) any later version.
+
+;; This program 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; see the file COPYING.  If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+
+;; Provides support for the :bind, :bind*, :bind-keymap and :bind-keymap*
+;; keywords. Note that these are currently still baked into
+;; `use-package-keywords' and `use-package-deferring-keywords', although this
+;; is harmless if they are never used.
+
+;;; Code:
+
+(require 'use-package-core)
+(require 'bind-key)
+
+;;;###autoload
+(defun use-package-autoload-keymap (keymap-symbol package override)
+  "Loads PACKAGE and then binds the key sequence used to invoke
+this function to KEYMAP-SYMBOL. It then simulates pressing the
+same key sequence a again, so that the next key pressed is routed
+to the newly loaded keymap.
+
+This function supports use-package's :bind-keymap keyword. It
+works by binding the given key sequence to an invocation of this
+function for a particular keymap. The keymap is expected to be
+defined by the package. In this way, loading the package is
+deferred until the prefix key sequence is pressed."
+  (if (not (require package nil t))
+      (use-package-error (format "Cannot load package.el: %s" package))
+    (if (and (boundp keymap-symbol)
+             (keymapp (symbol-value keymap-symbol)))
+        (let* ((kv (this-command-keys-vector))
+               (key (key-description kv))
+               (keymap (symbol-value keymap-symbol)))
+          (if override
+              (bind-key* key keymap)
+            (bind-key key keymap))
+          (setq unread-command-events
+                (mapcar (lambda (ev) (cons t ev))
+                        (listify-key-sequence kv))))
+      (use-package-error
+       (format "package.el %s failed to define keymap %s"
+               package keymap-symbol)))))
+
+;;;###autoload
+(defun use-package-normalize-binder (name keyword args)
+  (let ((arg args)
+        args*)
+    (while arg
+      (let ((x (car arg)))
+        (cond
+         ;; (KEY . COMMAND)
+         ((and (consp x)
+               (or (stringp (car x))
+                   (vectorp (car x)))
+               (or (use-package-recognize-function (cdr x) t #'stringp)))
+          (setq args* (nconc args* (list x)))
+          (setq arg (cdr arg)))
+         ;; KEYWORD
+         ;;   :map KEYMAP
+         ;;   :prefix-docstring STRING
+         ;;   :prefix-map SYMBOL
+         ;;   :prefix STRING
+         ;;   :filter SEXP
+         ;;   :menu-name STRING
+         ;;   :package SYMBOL
+         ((or (and (eq x :map) (symbolp (cadr arg)))
+              (and (eq x :prefix) (stringp (cadr arg)))
+              (and (eq x :prefix-map) (symbolp (cadr arg)))
+              (and (eq x :prefix-docstring) (stringp (cadr arg)))
+              (eq x :filter)
+              (and (eq x :menu-name) (stringp (cadr arg)))
+              (and (eq x :package) (symbolp (cadr arg))))
+          (setq args* (nconc args* (list x (cadr arg))))
+          (setq arg (cddr arg)))
+         ((listp x)
+          (setq args*
+                (nconc args* (use-package-normalize-binder name keyword x)))
+          (setq arg (cdr arg)))
+         (t
+          ;; Error!
+          (use-package-error
+           (concat (symbol-name name)
+                   " wants arguments acceptable to the `bind-keys' macro,"
+                   " or a list of such values"))))))
+    args*))
+
+;;;; :bind, :bind*
+
+;;;###autoload
+(defalias 'use-package-normalize/:bind 'use-package-normalize-binder)
+;;;###autoload
+(defalias 'use-package-normalize/:bind* 'use-package-normalize-binder)
+
+;; jww (2017-12-07): This is too simplistic. It will fail to determine
+;; autoloads in this situation:
+;;   (use-package foo
+;;     :bind (:map foo-map (("C-a" . func))))
+;;;###autoload
+(defalias 'use-package-autoloads/:bind 'use-package-autoloads-mode)
+;;;###autoload
+(defalias 'use-package-autoloads/:bind* 'use-package-autoloads-mode)
+
+;;;###autoload
+(defun use-package-handler/:bind
+    (name _keyword args rest state &optional bind-macro)
+  (use-package-concat
+   (use-package-process-keywords name rest state)
+   `(,@(mapcar
+        #'(lambda (xs)
+            `(,(if bind-macro bind-macro 'bind-keys)
+              :package ,name ,@(use-package-normalize-commands xs)))
+        (use-package-split-list-at-keys :break args)))))
+
+(defun use-package-handler/:bind* (name keyword arg rest state)
+  (use-package-handler/:bind name keyword arg rest state 'bind-keys*))
+
+;;;; :bind-keymap, :bind-keymap*
+
+;;;###autoload
+(defalias 'use-package-normalize/:bind-keymap 'use-package-normalize-binder)
+;;;###autoload
+(defalias 'use-package-normalize/:bind-keymap* 'use-package-normalize-binder)
+
+;;;###autoload
+(defun use-package-handler/:bind-keymap
+    (name _keyword args rest state &optional override)
+  (use-package-concat
+   (use-package-process-keywords name rest state)
+   (mapcar
+    #'(lambda (binding)
+        `(,(if override 'bind-key* 'bind-key)
+          ,(car binding)
+          #'(lambda ()
+              (interactive)
+              (use-package-autoload-keymap
+               ',(cdr binding) ',(use-package-as-symbol name)
+               ,override))))
+    args)))
+
+;;;###autoload
+(defun use-package-handler/:bind-keymap* (name keyword arg rest state)
+  (use-package-handler/:bind-keymap name keyword arg rest state t))
+
+(provide 'use-package-bind-key)
+
+;;; use-package-bind-key.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package-bind-key.elc b/configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package-bind-key.elc
new file mode 100644
index 0000000000..dae7a16c66
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package-bind-key.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package-core.el b/configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package-core.el
new file mode 100644
index 0000000000..525b478313
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package-core.el
@@ -0,0 +1,1591 @@
+;;; use-package-core.el --- A configuration macro for simplifying your .emacs  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2012-2017 John Wiegley
+
+;; Author: John Wiegley <johnw@newartisans.com>
+;; Maintainer: John Wiegley <johnw@newartisans.com>
+;; Created: 17 Jun 2012
+;; Modified: 29 Nov 2017
+;; Version: 2.4
+;; Package-Requires: ((emacs "24.3"))
+;; Keywords: dotemacs startup speed config package
+;; URL: https://github.com/jwiegley/use-package
+
+;; This program 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, or (at
+;; your option) any later version.
+
+;; This program 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; see the file COPYING.  If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+
+;; The `use-package' declaration macro allows you to isolate package
+;; configuration in your ".emacs" in a way that is performance-oriented and,
+;; well, just tidy.  I created it because I have over 80 packages that I use
+;; in Emacs, and things were getting difficult to manage.  Yet with this
+;; utility my total load time is just under 1 second, with no loss of
+;; functionality!
+;;
+;; Please see README.md from the same repository for documentation.
+
+;;; Code:
+
+(require 'bytecomp)
+(require 'cl-lib)
+(require 'tabulated-list)
+
+(if (and (eq emacs-major-version 24) (eq emacs-minor-version 3))
+    (defsubst hash-table-keys (hash-table)
+      "Return a list of keys in HASH-TABLE."
+      (cl-loop for k being the hash-keys of hash-table collect k))
+  (eval-when-compile (require 'subr-x)))
+
+(eval-when-compile
+  (require 'regexp-opt))
+
+(defgroup use-package nil
+  "A use-package declaration for simplifying your `.emacs'."
+  :group 'startup)
+
+(defconst use-package-version "2.4"
+  "This version of use-package.")
+
+(defcustom use-package-keywords
+  '(:disabled
+    :load-path
+    :requires
+    :defines
+    :functions
+    :preface
+    :if :when :unless
+    :no-require
+    :catch
+    :after
+    :custom
+    :custom-face
+    :bind
+    :bind*
+    :bind-keymap
+    :bind-keymap*
+    :interpreter
+    :mode
+    :magic
+    :magic-fallback
+    :hook
+    ;; Any other keyword that also declares commands to be autoloaded (such as
+    ;; :bind) must appear before this keyword.
+    :commands
+    :init
+    :defer
+    :demand
+    :load
+    ;; This must occur almost last; the only forms which should appear after
+    ;; are those that must happen directly after the config forms.
+    :config)
+  "The set of valid keywords, in the order they are processed in.
+The order of this list is *very important*, so it is only
+advisable to insert new keywords, never to delete or reorder
+them. Further, attention should be paid to the NEWS.md if the
+default order ever changes, as they may have subtle effects on
+the semantics of use-package declarations and may necessitate
+changing where you had inserted a new keyword earlier.
+
+Note that `:disabled' is special in this list, as it causes
+nothing at all to happen, even if the rest of the use-package
+declaration is incorrect."
+  :type '(repeat symbol)
+  :group 'use-package)
+
+(defcustom use-package-deferring-keywords
+  '(:bind-keymap
+    :bind-keymap*
+    :commands)
+  "Unless `:demand' is used, keywords in this list imply deferred loading.
+The reason keywords like `:hook' are not in this list is that
+they only imply deferred loading if they reference actual
+function symbols that can be autoloaded from the module; whereas
+the default keywords provided here always defer loading unless
+otherwise requested."
+  :type '(repeat symbol)
+  :group 'use-package)
+
+(defcustom use-package-ignore-unknown-keywords nil
+  "If non-nil, issue warning instead of error when unknown
+keyword is encountered. The unknown keyword and its associated
+arguments will be ignored in the `use-package' expansion."
+  :type 'boolean
+  :group 'use-package)
+
+(defcustom use-package-verbose nil
+  "Whether to report about loading and configuration details.
+If you customize this, then you should require the `use-package'
+feature in files that use `use-package', even if these files only
+contain compiled expansions of the macros. If you don't do so,
+then the expanded macros do their job silently."
+  :type '(choice (const :tag "Quiet, without catching errors" errors)
+                 (const :tag "Quiet" nil)
+                 (const :tag "Verbose" t)
+                 (const :tag "Debug" debug))
+  :group 'use-package)
+
+(defcustom use-package-check-before-init nil
+  "If non-nil, check that package exists before executing its `:init' block.
+This check is performed by calling `locate-library'."
+  :type 'boolean
+  :group 'use-package)
+
+(defcustom use-package-always-defer nil
+  "If non-nil, assume `:defer t' unless `:demand' is used.
+See also `use-package-defaults', which uses this value."
+  :type 'boolean
+  :group 'use-package)
+
+(defcustom use-package-always-demand nil
+  "If non-nil, assume `:demand t' unless `:defer' is used.
+See also `use-package-defaults', which uses this value."
+  :type 'boolean
+  :group 'use-package)
+
+(defcustom use-package-defaults
+  '(;; this '(t) has special meaning; see `use-package-handler/:config'
+    (:config '(t) t)
+    (:init nil t)
+    (:catch t (lambda (name args)
+                (not use-package-expand-minimally)))
+    (:defer use-package-always-defer
+            (lambda (name args)
+              (and use-package-always-defer
+                   (not (plist-member args :defer))
+                   (not (plist-member args :demand)))))
+    (:demand use-package-always-demand
+             (lambda (name args)
+               (and use-package-always-demand
+                    (not (plist-member args :defer))
+                    (not (plist-member args :demand))))))
+  "Default values for specified `use-package' keywords.
+Each entry in the alist is a list of three elements:
+The first element is the `use-package' keyword.
+
+The second is a form that can be evaluated to get the default
+value. It can also be a function that will receive the name of
+the use-package declaration and the keyword plist given to
+`use-package', in normalized form. The value it returns should
+also be in normalized form (which is sometimes *not* what one
+would normally write in a `use-package' declaration, so use
+caution).
+
+The third element is a form that can be evaluated to determine
+whether or not to assign a default value; if it evaluates to nil,
+then the default value is not assigned even if the keyword is not
+present in the `use-package' form. This third element may also be
+a function, in which case it receives the name of the package (as
+a symbol) and a list of keywords (in normalized form). It should
+return nil or non-nil depending on whether defaulting should be
+attempted."
+  :type `(repeat
+          (list (choice :tag "Keyword"
+                        ,@(mapcar #'(lambda (k) (list 'const k))
+                                  use-package-keywords))
+                (choice :tag "Default value" sexp function)
+                (choice :tag "Enable if non-nil" sexp function)))
+  :group 'use-package)
+
+(defcustom use-package-merge-key-alist
+  '((:if    . (lambda (new old) `(and ,new ,old)))
+    (:after . (lambda (new old) `(:all ,new ,old)))
+    (:defer . (lambda (new old) old))
+    (:bind  . (lambda (new old) (append new (list :break) old))))
+  "Alist of keys and the functions used to merge multiple values.
+For example, if the following form is provided:
+
+  (use-package foo :if pred1 :if pred2)
+
+Then based on the above defaults, the merged result will be:
+
+  (use-package foo :if (and pred1 pred2))
+
+This is done so that, at the stage of invoking handlers, each
+handler is called only once."
+  :type `(repeat
+          (cons (choice :tag "Keyword"
+                        ,@(mapcar #'(lambda (k) (list 'const k))
+                                  use-package-keywords)
+                        (const :tag "Any" t))
+                function))
+  :group 'use-package)
+
+(defcustom use-package-hook-name-suffix "-hook"
+  "Text append to the name of hooks mentioned by :hook.
+Set to nil if you don't want this to happen; it's only a
+convenience."
+  :type '(choice string (const :tag "No suffix" nil))
+  :group 'use-package)
+
+(defcustom use-package-minimum-reported-time 0.1
+  "Minimal load time that will be reported.
+Note that `use-package-verbose' has to be set to a non-nil value
+for anything to be reported at all."
+  :type 'number
+  :group 'use-package)
+
+(defcustom use-package-inject-hooks nil
+  "If non-nil, add hooks to the `:init' and `:config' sections.
+In particular, for a given package `foo', the following hooks
+become available:
+
+  `use-package--foo--pre-init-hook'
+  `use-package--foo--post-init-hook'
+  `use-package--foo--pre-config-hook'
+  `use-package--foo--post-config-hook'
+
+This way, you can add to these hooks before evaluation of a
+`use-package` declaration, and exercise some control over what
+happens.
+
+NOTE: These hooks are run even if the user does not specify an
+`:init' or `:config' block, and they will happen at the regular
+time when initialization and configuration would have been
+performed.
+
+NOTE: If the `pre-init' hook return a nil value, that block's
+user-supplied configuration is not evaluated, so be certain to
+return t if you only wish to add behavior to what the user had
+specified."
+  :type 'boolean
+  :group 'use-package)
+
+(defcustom use-package-expand-minimally nil
+  "If non-nil, make the expanded code as minimal as possible.
+This disables:
+
+  - Printing to the *Messages* buffer of slowly-evaluating forms
+  - Capturing of load errors (normally redisplayed as warnings)
+  - Conditional loading of packages (load failures become errors)
+
+The main advantage to this variable is that, if you know your
+configuration works, it will make the byte-compiled file as
+minimal as possible. It can also help with reading macro-expanded
+definitions, to understand the main intent of what's happening."
+  :type 'boolean
+  :group 'use-package)
+
+(defcustom use-package-form-regexp-eval
+  `(concat ,(eval-when-compile
+              (concat "^\\s-*("
+                      (regexp-opt '("use-package" "require") t)
+                      "\\s-+\\("))
+           (or (bound-and-true-p lisp-mode-symbol-regexp)
+               "\\(?:\\sw\\|\\s_\\|\\\\.\\)+") "\\)")
+  "Sexp providing regexp for finding use-package forms in user files.
+This is used by `use-package-jump-to-package-form' and
+`use-package-enable-imenu-support'."
+  :type 'sexp
+  :group 'use-package)
+
+(defcustom use-package-enable-imenu-support nil
+  "If non-nil, cause imenu to see `use-package' declarations.
+This is done by adjusting `lisp-imenu-generic-expression' to
+include support for finding `use-package' and `require' forms.
+
+Must be set before loading use-package."
+  :type 'boolean
+  :set
+  #'(lambda (_sym value)
+      (eval-after-load 'lisp-mode
+        (if value
+            `(add-to-list 'lisp-imenu-generic-expression
+                          (list "Packages" ,use-package-form-regexp-eval 2))
+          `(setq lisp-imenu-generic-expression
+                 (remove (list "Packages" ,use-package-form-regexp-eval 2)
+                         lisp-imenu-generic-expression)))))
+  :group 'use-package)
+
+(defconst use-package-font-lock-keywords
+  '(("(\\(use-package\\)\\_>[ \t']*\\(\\(?:\\sw\\|\\s_\\)+\\)?"
+     (1 font-lock-keyword-face)
+     (2 font-lock-constant-face nil t))))
+
+(font-lock-add-keywords 'emacs-lisp-mode use-package-font-lock-keywords)
+
+(defcustom use-package-compute-statistics nil
+  "If non-nil, compute statistics concerned use-package declarations.
+View the statistical report using `use-package-report'. Note that
+if this option is enabled, you must require `use-package' in your
+user init file at loadup time, or you will see errors concerning
+undefined variables."
+  :type 'boolean
+  :group 'use-package)
+
+(defvar use-package-statistics (make-hash-table))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Utility functions
+;;
+
+(defsubst use-package-error (msg)
+  "Report MSG as an error, so the user knows it came from this package."
+  (error "use-package: %s" msg))
+
+(defsubst use-package-concat (&rest elems)
+  "Delete all empty lists from ELEMS (nil or (list nil)), and append them."
+  (apply #'append (delete nil (delete (list nil) elems))))
+
+(defsubst use-package-non-nil-symbolp (sym)
+  (and sym (symbolp sym)))
+
+(defsubst use-package-as-symbol (string-or-symbol)
+  "If STRING-OR-SYMBOL is already a symbol, return it.  Otherwise
+convert it to a symbol and return that."
+  (if (symbolp string-or-symbol) string-or-symbol
+    (intern string-or-symbol)))
+
+(defsubst use-package-as-string (string-or-symbol)
+  "If STRING-OR-SYMBOL is already a string, return it.  Otherwise
+convert it to a string and return that."
+  (if (stringp string-or-symbol) string-or-symbol
+    (symbol-name string-or-symbol)))
+
+(defsubst use-package-regex-p (re)
+  "Return t if RE is some regexp-like thing."
+  (or (and (listp re) (eq (car re) 'rx))
+      (stringp re)))
+
+(defun use-package-normalize-regex (re)
+  "Given some regexp-like thing in RE, resolve to a regular expression."
+  (cond
+   ((and (listp re) (eq (car re) 'rx)) (eval re))
+   ((stringp re) re)
+   (t (error "Not recognized as regular expression: %s" re))))
+
+(defsubst use-package-is-pair (x car-pred cdr-pred)
+  "Return non-nil if X is a cons satisfying the given predicates.
+CAR-PRED and CDR-PRED are applied to X's `car' and `cdr',
+respectively."
+  (and (consp x)
+       (funcall car-pred (car x))
+       (funcall cdr-pred (cdr x))))
+
+(defun use-package-as-mode (string-or-symbol)
+  "If STRING-OR-SYMBOL ends in `-mode' (or its name does), return
+it as a symbol.  Otherwise, return it as a symbol with `-mode'
+appended."
+  (let ((string (use-package-as-string string-or-symbol)))
+    (intern (if (string-match "-mode\\'" string)
+                string
+              (concat string "-mode")))))
+
+(defsubst use-package-load-name (name &optional noerror)
+  "Return a form which will load or require NAME.
+It does the right thing no matter if NAME is a string or symbol.
+Argument NOERROR means to indicate load failures as a warning."
+  (if (stringp name)
+      `(load ,name ,noerror)
+    `(require ',name nil ,noerror)))
+
+(defun use-package-hook-injector (name-string keyword body)
+  "Wrap pre/post hook injections around the given BODY for KEYWORD.
+The BODY is a list of forms, so `((foo))' if only `foo' is being called."
+  (if (not use-package-inject-hooks)
+      body
+    (let ((keyword-name (substring (format "%s" keyword) 1)))
+      `((when (run-hook-with-args-until-failure
+               ',(intern (concat "use-package--" name-string
+                                 "--pre-" keyword-name "-hook")))
+          ,@body
+          (run-hooks
+           ',(intern (concat "use-package--" name-string
+                             "--post-" keyword-name "-hook"))))))))
+
+(defun use-package-with-elapsed-timer (text body)
+  "BODY is a list of forms, so `((foo))' if only `foo' is being called."
+  (declare (indent 1))
+  (if use-package-expand-minimally
+      body
+    (let ((nowvar (make-symbol "now")))
+      (if (bound-and-true-p use-package-verbose)
+          `((let ((,nowvar (current-time)))
+              (message "%s..." ,text)
+              (prog1
+                  ,(macroexp-progn body)
+                (let ((elapsed
+                       (float-time (time-subtract (current-time) ,nowvar))))
+                  (if (> elapsed ,use-package-minimum-reported-time)
+                      (message "%s...done (%.3fs)" ,text elapsed)
+                    (message "%s...done" ,text))))))
+        body))))
+
+(put 'use-package-with-elapsed-timer 'lisp-indent-function 1)
+
+(defun use-package-require (name &optional no-require body)
+  (if use-package-expand-minimally
+      (use-package-concat
+       (unless no-require
+         (list (use-package-load-name name)))
+       body)
+    (if no-require
+        body
+      (use-package-with-elapsed-timer
+          (format "Loading package %s" name)
+        `((if (not ,(use-package-load-name name t))
+              (display-warning 'use-package
+                               (format "Cannot load %s" ',name)
+                               :error)
+            ,@body))))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Property lists
+;;
+
+(defun use-package-plist-delete (plist property)
+  "Delete PROPERTY from PLIST.
+This is in contrast to merely setting it to 0."
+  (let (p)
+    (while plist
+      (if (not (eq property (car plist)))
+          (setq p (plist-put p (car plist) (nth 1 plist))))
+      (setq plist (cddr plist)))
+    p))
+
+(defun use-package-plist-delete-first (plist property)
+  "Delete PROPERTY from PLIST.
+This is in contrast to merely setting it to 0."
+  (let (p)
+    (while plist
+      (if (eq property (car plist))
+          (setq p (nconc p (cddr plist))
+                plist nil)
+        (setq p (nconc p (list (car plist) (cadr plist)))
+              plist (cddr plist))))
+    p))
+
+(defsubst use-package-plist-maybe-put (plist property value)
+  "Add a VALUE for PROPERTY to PLIST, if it does not already exist."
+  (if (plist-member plist property)
+      plist
+    (plist-put plist property value)))
+
+(defsubst use-package-plist-cons (plist property value)
+  "Cons VALUE onto the head of the list at PROPERTY in PLIST."
+  (plist-put plist property (cons value (plist-get plist property))))
+
+(defsubst use-package-plist-append (plist property value)
+  "Append VALUE onto the front of the list at PROPERTY in PLIST."
+  (plist-put plist property (append value (plist-get plist property))))
+
+(defun use-package-split-list (pred xs)
+  (let ((ys (list nil)) (zs (list nil)) flip)
+    (cl-dolist (x xs)
+      (if flip
+          (nconc zs (list x))
+        (if (funcall pred x)
+            (progn
+              (setq flip t)
+              (nconc zs (list x)))
+          (nconc ys (list x)))))
+    (cons (cdr ys) (cdr zs))))
+
+(defun use-package-split-list-at-keys (key lst)
+  (and lst
+       (let ((xs (use-package-split-list (apply-partially #'eq key) lst)))
+         (cons (car xs) (use-package-split-list-at-keys key (cddr xs))))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Keywords
+;;
+
+(defun use-package-keyword-index (keyword)
+  (cl-loop named outer
+           with index = 0
+           for k in use-package-keywords do
+           (if (eq k keyword)
+               (cl-return-from outer index))
+           (cl-incf index)))
+
+(defun use-package-normalize-plist (name input &optional plist merge-function)
+  "Given a pseudo-plist, normalize it to a regular plist.
+The normalized key/value pairs from input are added to PLIST,
+extending any keys already present."
+  (if (null input)
+      plist
+    (let* ((keyword (car input))
+           (xs (use-package-split-list #'keywordp (cdr input)))
+           (args (car xs))
+           (tail (cdr xs))
+           (normalizer
+            (intern-soft (concat "use-package-normalize/"
+                                 (symbol-name keyword))))
+           (arg (and (functionp normalizer)
+                     (funcall normalizer name keyword args)))
+           (error-string (format "Unrecognized keyword: %s" keyword)))
+      (if (memq keyword use-package-keywords)
+          (progn
+            (setq plist (use-package-normalize-plist
+                         name tail plist merge-function))
+            (plist-put plist keyword
+                       (if (plist-member plist keyword)
+                           (funcall merge-function keyword arg
+                                    (plist-get plist keyword))
+                         arg)))
+        (if use-package-ignore-unknown-keywords
+            (progn
+              (display-warning 'use-package error-string)
+              (use-package-normalize-plist
+               name tail plist merge-function))
+          (use-package-error error-string))))))
+
+(defun use-package-unalias-keywords (_name args)
+  (setq args (cl-nsubstitute :if :when args))
+  (let (temp)
+    (while (setq temp (plist-get args :unless))
+      (setq args (use-package-plist-delete-first args :unless)
+            args (append args `(:if (not ,temp))))))
+  args)
+
+(defun use-package-merge-keys (key new old)
+  (let ((merger (assq key use-package-merge-key-alist)))
+    (if merger
+        (funcall (cdr merger) new old)
+      (append new old))))
+
+(defun use-package-sort-keywords (plist)
+  (let (plist-grouped)
+    (while plist
+      (push (cons (car plist) (cadr plist))
+            plist-grouped)
+      (setq plist (cddr plist)))
+    (let (result)
+      (cl-dolist
+          (x
+           (nreverse
+            (sort plist-grouped
+                  #'(lambda (l r) (< (use-package-keyword-index (car l))
+                                (use-package-keyword-index (car r)))))))
+        (setq result (cons (car x) (cons (cdr x) result))))
+      result)))
+
+(defun use-package-normalize-keywords (name args)
+  (let* ((name-symbol (if (stringp name) (intern name) name))
+         (name-string (symbol-name name-symbol)))
+
+    ;; The function `elisp--local-variables' inserts this unbound variable into
+    ;; macro forms to determine the locally bound variables for
+    ;; `elisp-completion-at-point'. It ends up throwing a lot of errors since it
+    ;; can occupy the position of a keyword (or look like a second argument to a
+    ;; keyword that takes one). Deleting it when it's at the top level should be
+    ;; harmless since there should be no locally bound variables to discover
+    ;; here anyway.
+    (setq args (delq 'elisp--witness--lisp args))
+
+    ;; Reduce the set of keywords down to its most fundamental expression.
+    (setq args (use-package-unalias-keywords name-symbol args))
+
+    ;; Normalize keyword values, coalescing multiple occurrences.
+    (setq args (use-package-normalize-plist name-symbol args nil
+                                            #'use-package-merge-keys))
+
+    ;; Add default values for keywords not specified, when applicable.
+    (cl-dolist (spec use-package-defaults)
+      (when (let ((func (nth 2 spec)))
+              (if (and func (functionp func))
+                  (funcall func name args)
+                (eval func)))
+        (setq args (use-package-plist-maybe-put
+                    args (nth 0 spec)
+                    (let ((func (nth 1 spec)))
+                      (if (and func (functionp func))
+                          (funcall func name args)
+                        (eval func)))))))
+
+    ;; Determine any autoloads implied by the keywords used.
+    (let ((iargs args)
+          commands)
+      (while iargs
+        (when (keywordp (car iargs))
+          (let ((autoloads
+                 (intern-soft (concat "use-package-autoloads/"
+                                      (symbol-name (car iargs))))))
+            (when (functionp autoloads)
+              (setq commands
+                    ;; jww (2017-12-07): Right now we just ignored the type of
+                    ;; the autoload being requested, and assume they are all
+                    ;; `command'.
+                    (append (mapcar
+                             #'car
+                             (funcall autoloads name-symbol (car iargs)
+                                      (cadr iargs)))
+                            commands)))))
+        (setq iargs (cddr iargs)))
+      (when commands
+        (setq args
+              ;; Like `use-package-plist-append', but removing duplicates.
+              (plist-put args :commands
+                         (delete-dups
+                          (append commands (plist-get args :commands)))))))
+
+    ;; If byte-compiling, pre-load the package so all its symbols are in
+    ;; scope. This is done by prepending statements to the :preface.
+    (when (bound-and-true-p byte-compile-current-file)
+      (setq args
+            (use-package-plist-append
+             args :preface
+             (use-package-concat
+              (mapcar #'(lambda (var) `(defvar ,var))
+                      (plist-get args :defines))
+              (mapcar #'(lambda (fn) `(declare-function ,fn ,name-string))
+                      (plist-get args :functions))
+              `((eval-when-compile
+                  (with-demoted-errors
+                      ,(format "Cannot load %s: %%S" name-string)
+                    ,(when (eq use-package-verbose 'debug)
+                       `(message ,(format "Compiling package %s" name-string)))
+                    ,(unless (plist-get args :no-require)
+                       `(load ,name-string nil t)))))))))
+
+    ;; Certain keywords imply :defer, if :demand was not specified.
+    (when (and (not (plist-member args :demand))
+               (not (plist-member args :defer))
+               (not (or (equal '(t) (plist-get args :load))
+                        (equal (list (use-package-as-string name))
+                               (mapcar #'use-package-as-string
+                                       (plist-get args :load)))))
+               (cl-some #'identity
+                        (mapcar (apply-partially #'plist-member args)
+                                use-package-deferring-keywords)))
+      (setq args (append args '(:defer t))))
+
+    ;; The :load keyword overrides :no-require
+    (when (and (plist-member args :load)
+               (plist-member args :no-require))
+      (setq args (use-package-plist-delete args :no-require)))
+
+    ;; If at this point no :load, :defer or :no-require has been seen, then
+    ;; :load the package itself.
+    (when (and (not (plist-member args :load))
+               (not (plist-member args :defer))
+               (not (plist-member args :no-require)))
+      (setq args (append args `(:load (,name)))))
+
+    ;; Sort the list of keywords based on the order of `use-package-keywords'.
+    (use-package-sort-keywords args)))
+
+(defun use-package-process-keywords (name plist &optional state)
+  "Process the next keyword in the free-form property list PLIST.
+The values in the PLIST have each been normalized by the function
+use-package-normalize/KEYWORD (minus the colon).
+
+STATE is a property list that the function may modify and/or
+query.  This is useful if a package defines multiple keywords and
+wishes them to have some kind of stateful interaction.
+
+Unless the KEYWORD being processed intends to ignore remaining
+keywords, it must call this function recursively, passing in the
+plist with its keyword and argument removed, and passing in the
+next value for the STATE."
+  (declare (indent 1))
+  (unless (null plist)
+    (let* ((keyword (car plist))
+           (arg (cadr plist))
+           (rest (cddr plist)))
+      (unless (keywordp keyword)
+        (use-package-error (format "%s is not a keyword" keyword)))
+      (let* ((handler (concat "use-package-handler/" (symbol-name keyword)))
+             (handler-sym (intern handler)))
+        (if (functionp handler-sym)
+            (funcall handler-sym name keyword arg rest state)
+          (use-package-error
+           (format "Keyword handler not defined: %s" handler)))))))
+
+(put 'use-package-process-keywords 'lisp-indent-function 'defun)
+
+(defun use-package-list-insert (elem xs &optional anchor after test)
+  "Insert ELEM into the list XS.
+If ANCHOR is also a keyword, place the new KEYWORD before that
+one.
+If AFTER is non-nil, insert KEYWORD either at the end of the
+keywords list, or after the ANCHOR if one has been provided.
+If TEST is non-nil, it is the test used to compare ELEM to list
+elements. The default is `eq'.
+The modified list is returned. The original list is not modified."
+  (let (result)
+    (dolist (k xs)
+      (if (funcall (or test #'eq) k anchor)
+          (if after
+              (setq result (cons k result)
+                    result (cons elem result))
+            (setq result (cons elem result)
+                  result (cons k result)))
+        (setq result (cons k result))))
+    (if anchor
+        (nreverse result)
+      (if after
+          (nreverse (cons elem result))
+        (cons elem (nreverse result))))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Argument Processing
+;;
+
+(defun use-package-only-one (label args f)
+  "Call F on the first member of ARGS if it has exactly one element."
+  (declare (indent 1))
+  (cond
+   ((and (listp args) (listp (cdr args))
+         (= (length args) 1))
+    (funcall f label (car args)))
+   (t
+    (use-package-error
+     (concat label " wants exactly one argument")))))
+
+(put 'use-package-only-one 'lisp-indent-function 'defun)
+
+(defun use-package-as-one (label args f &optional allow-empty)
+  "Call F on the first element of ARGS if it has one element, or all of ARGS.
+If ALLOW-EMPTY is non-nil, it's OK for ARGS to be an empty list."
+  (declare (indent 1))
+  (if (if args
+          (and (listp args) (listp (cdr args)))
+        allow-empty)
+      (if (= (length args) 1)
+          (funcall f label (car args))
+        (funcall f label args))
+    (use-package-error
+     (concat label " wants a non-empty list"))))
+
+(put 'use-package-as-one 'lisp-indent-function 'defun)
+
+(defun use-package-memoize (f arg)
+  "Ensure the macro-expansion of F applied to ARG evaluates ARG
+no more than once."
+  (let ((loaded (cl-gentemp "use-package--loaded"))
+        (result (cl-gentemp "use-package--result"))
+        (next   (cl-gentemp "use-package--next")))
+    `((defvar ,loaded nil)
+      (defvar ,result nil)
+      (defvar ,next #'(lambda () (if ,loaded ,result
+                              (setq ,loaded t ,result ,arg))))
+      ,@(funcall f `((funcall ,next))))))
+
+(defsubst use-package-normalize-value (_label arg)
+  "Normalize the Lisp value given by ARG.
+The argument LABEL is ignored."
+  (cond ((null arg) nil)
+        ((eq t arg) t)
+        ((use-package-non-nil-symbolp arg)
+         `(symbol-value ',arg))
+        ((functionp arg)
+         `(funcall #',arg))
+        (t arg)))
+
+(defun use-package-normalize-symbols (label arg &optional recursed)
+  "Normalize a list of symbols."
+  (cond
+   ((use-package-non-nil-symbolp arg)
+    (list arg))
+   ((and (not recursed) (listp arg) (listp (cdr arg)))
+    (mapcar #'(lambda (x) (car (use-package-normalize-symbols label x t))) arg))
+   (t
+    (use-package-error
+     (concat label " wants a symbol, or list of symbols")))))
+
+(defun use-package-normalize-symlist (_name keyword args)
+  (use-package-as-one (symbol-name keyword) args
+    #'use-package-normalize-symbols))
+
+(defun use-package-normalize-recursive-symbols (label arg)
+  "Normalize a list of symbols."
+  (cond
+   ((use-package-non-nil-symbolp arg)
+    arg)
+   ((and (listp arg) (listp (cdr arg)))
+    (mapcar #'(lambda (x) (use-package-normalize-recursive-symbols label x))
+            arg))
+   (t
+    (use-package-error
+     (concat label " wants a symbol, or nested list of symbols")))))
+
+(defun use-package-normalize-recursive-symlist (_name keyword args)
+  (use-package-as-one (symbol-name keyword) args
+    #'use-package-normalize-recursive-symbols))
+
+(defun use-package-normalize-paths (label arg &optional recursed)
+  "Normalize a list of filesystem paths."
+  (cond
+   ((and arg (or (use-package-non-nil-symbolp arg) (functionp arg)))
+    (let ((value (use-package-normalize-value label arg)))
+      (use-package-normalize-paths label (eval value))))
+   ((stringp arg)
+    (let ((path (if (file-name-absolute-p arg)
+                    arg
+                  (expand-file-name arg user-emacs-directory))))
+      (list path)))
+   ((and (not recursed) (listp arg) (listp (cdr arg)))
+    (mapcar #'(lambda (x)
+                (car (use-package-normalize-paths label x t))) arg))
+   (t
+    (use-package-error
+     (concat label " wants a directory path, or list of paths")))))
+
+(defun use-package-normalize-predicate (_name keyword args)
+  (if (null args)
+      t
+    (use-package-only-one (symbol-name keyword) args
+      #'use-package-normalize-value)))
+
+(defun use-package-normalize-form (label args)
+  "Given a list of forms, return it wrapped in `progn'."
+  (unless (listp (car args))
+    (use-package-error (concat label " wants a sexp or list of sexps")))
+  (mapcar #'(lambda (form)
+              (if (and (consp form)
+                       (memq (car form)
+                             '(use-package bind-key bind-key*
+                                unbind-key bind-keys bind-keys*)))
+                  (macroexpand form)
+                form)) args))
+
+(defun use-package-normalize-forms (_name keyword args)
+  (use-package-normalize-form (symbol-name keyword) args))
+
+(defun use-package-normalize-pairs
+    (key-pred val-pred name label arg &optional recursed)
+  "Normalize a list of pairs.
+KEY-PRED and VAL-PRED are predicates recognizing valid keys and
+values, respectively.
+If RECURSED is non-nil, recurse into sublists."
+  (cond
+   ((funcall key-pred arg)
+    (list (cons arg (use-package-as-symbol name))))
+   ((use-package-is-pair arg key-pred val-pred)
+    (list arg))
+   ((and (not recursed) (listp arg) (listp (cdr arg)))
+    (let (last-item)
+      (mapcar
+       #'(lambda (x)
+           (prog1
+               (let ((ret (use-package-normalize-pairs
+                           key-pred val-pred name label x t)))
+                 (if (and (listp ret)
+                          (not (keywordp last-item)))
+                     (car ret)
+                   ret))
+             (setq last-item x))) arg)))
+   (t arg)))
+
+(defun use-package-recognize-function (v &optional binding additional-pred)
+  "A predicate that recognizes functional constructions:
+  nil
+  sym
+  'sym
+  (quote sym)
+  #'sym
+  (function sym)
+  (lambda () ...)
+  '(lambda () ...)
+  (quote (lambda () ...))
+  #'(lambda () ...)
+  (function (lambda () ...))"
+  (or (if binding
+          (symbolp v)
+        (use-package-non-nil-symbolp v))
+      (and (listp v)
+           (memq (car v) '(quote function))
+           (use-package-non-nil-symbolp (cadr v)))
+      (if binding (commandp v) (functionp v))
+      (and additional-pred
+           (funcall additional-pred v))))
+
+(defun use-package-normalize-function (v)
+  "Reduce functional constructions to one of two normal forms:
+  sym
+  #'(lambda () ...)"
+  (cond ((symbolp v) v)
+        ((and (listp v)
+              (memq (car v) '(quote function))
+              (use-package-non-nil-symbolp (cadr v)))
+         (cadr v))
+        ((and (consp v)
+              (eq 'lambda (car v)))
+         v)
+        ((and (listp v)
+              (memq (car v) '(quote function))
+              (eq 'lambda (car (cadr v))))
+         (cadr v))
+        (t v)))
+
+(defun use-package-normalize-commands (args)
+  "Map over ARGS of the form ((_ . F) ...), normalizing functional F's."
+  (mapcar #'(lambda (x)
+              (if (consp x)
+                  (cons (car x) (use-package-normalize-function (cdr x)))
+                x))
+          args))
+
+(defun use-package-normalize-mode (name keyword args)
+  "Normalize arguments for keywords which add regexp/mode pairs to an alist."
+  (use-package-as-one (symbol-name keyword) args
+    (apply-partially #'use-package-normalize-pairs
+                     #'use-package-regex-p
+                     #'use-package-recognize-function
+                     name)))
+
+(defun use-package-autoloads-mode (_name _keyword args)
+  (mapcar
+   #'(lambda (x) (cons (cdr x) 'command))
+   (cl-remove-if-not #'(lambda (x)
+                         (and (consp x)
+                              (use-package-non-nil-symbolp (cdr x))))
+                     args)))
+
+(defun use-package-handle-mode (name alist args rest state)
+  "Handle keywords which add regexp/mode pairs to an alist."
+  (use-package-concat
+   (use-package-process-keywords name rest state)
+   (mapcar
+    #'(lambda (thing)
+        `(add-to-list
+          ',alist
+          ',(cons (use-package-normalize-regex (car thing))
+                  (cdr thing))))
+    (use-package-normalize-commands args))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Statistics
+;;
+
+(defun use-package-reset-statistics ()
+  (interactive)
+  (setq use-package-statistics (make-hash-table)))
+
+(defun use-package-statistics-status (package)
+  "Return loading configuration status of PACKAGE statistics."
+  (cond ((gethash :config package)      "Configured")
+        ((gethash :init package)        "Initialized")
+        ((gethash :preface package)     "Prefaced")
+        ((gethash :use-package package) "Declared")))
+
+(defun use-package-statistics-last-event (package)
+  "Return the date when PACKAGE's status last changed.
+The date is returned as a string."
+  (format-time-string "%Y-%m-%d %a %H:%M"
+                      (or (gethash :config package)
+                          (gethash :init package)
+                          (gethash :preface package)
+                          (gethash :use-package package))))
+
+(defun use-package-statistics-time (package)
+  "Return the time is took for PACKAGE to load."
+  (+ (float-time (gethash :config-secs package 0))
+     (float-time (gethash :init-secs package 0))
+     (float-time (gethash :preface-secs package 0))
+     (float-time (gethash :use-package-secs package 0))))
+
+(defun use-package-statistics-convert (package)
+  "Return information about PACKAGE.
+
+The information is formatted in a way suitable for
+`use-package-statistics-mode'."
+  (let ((statistics (gethash package use-package-statistics)))
+    (list
+     package
+     (vector
+      (symbol-name package)
+      (use-package-statistics-status statistics)
+      (use-package-statistics-last-event statistics)
+      (format "%.2f" (use-package-statistics-time statistics))))))
+
+(defun use-package-report ()
+  "Show current statistics gathered about use-package declarations.
+In the table that's generated, the status field has the following
+meaning:
+  Configured        :config has been processed (the package is loaded!)
+  Initialized       :init has been processed (load status unknown)
+  Prefaced          :preface has been processed
+  Declared          the use-package declaration was seen"
+  (interactive)
+  (with-current-buffer (get-buffer-create "*use-package statistics*")
+    (setq tabulated-list-entries
+          (mapcar #'use-package-statistics-convert
+                  (hash-table-keys use-package-statistics)))
+    (use-package-statistics-mode)
+    (tabulated-list-print)
+    (display-buffer (current-buffer))))
+
+(define-derived-mode use-package-statistics-mode tabulated-list-mode
+  "use-package statistics"
+  "Show current statistics gathered about use-package declarations."
+  (setq tabulated-list-format
+        ;; The sum of column width is 80 caracters:
+        #[("Package" 25 t)
+          ("Status" 13 t)
+          ("Last Event" 23 t)
+          ("Time" 10 t)])
+  (tabulated-list-init-header))
+
+(defun use-package-statistics-gather (keyword name after)
+  (let* ((hash (gethash name use-package-statistics
+                        (make-hash-table)))
+         (before (and after (gethash keyword hash (current-time)))))
+    (puthash keyword (current-time) hash)
+    (when after
+      (puthash (intern (concat (symbol-name keyword) "-secs"))
+               (time-subtract (current-time) before) hash))
+    (puthash name hash use-package-statistics)))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; Handlers
+;;
+
+;;;; :disabled
+
+;; Don't alias this to `ignore', as that will cause the resulting
+;; function to be interactive.
+(defun use-package-normalize/:disabled (_name _keyword _arg)
+  "Do nothing, return nil.")
+
+(defun use-package-handler/:disabled (name _keyword _arg rest state)
+  (use-package-process-keywords name rest state))
+
+;;;; :if, :when and :unless
+
+(defun use-package-normalize-test (_name keyword args)
+  (use-package-only-one (symbol-name keyword) args
+    #'use-package-normalize-value))
+
+(defalias 'use-package-normalize/:if 'use-package-normalize-test)
+
+(defun use-package-handler/:if (name _keyword pred rest state)
+  (let ((body (use-package-process-keywords name rest state)))
+    `((when ,pred ,@body))))
+
+(defalias 'use-package-normalize/:when 'use-package-normalize-test)
+
+(defalias 'use-package-handler/:when 'use-package-handler/:if)
+
+(defalias 'use-package-normalize/:unless 'use-package-normalize-test)
+
+(defun use-package-handler/:unless (name _keyword pred rest state)
+  (let ((body (use-package-process-keywords name rest state)))
+    `((unless ,pred ,@body))))
+
+;;;; :requires
+
+(defalias 'use-package-normalize/:requires 'use-package-normalize-symlist)
+
+(defun use-package-handler/:requires (name _keyword requires rest state)
+  (let ((body (use-package-process-keywords name rest state)))
+    (if (null requires)
+        body
+      `((when ,(if (> (length requires) 1)
+                   `(not (member nil (mapcar #'featurep ',requires)))
+                 `(featurep ',(car requires)))
+          ,@body)))))
+
+;;;; :load-path
+
+(defun use-package-normalize/:load-path (_name keyword args)
+  (use-package-as-one (symbol-name keyword) args
+    #'use-package-normalize-paths))
+
+(defun use-package-handler/:load-path (name _keyword arg rest state)
+  (let ((body (use-package-process-keywords name rest state)))
+    (use-package-concat
+     (mapcar #'(lambda (path)
+                 `(eval-and-compile (add-to-list 'load-path ,path)))
+             arg)
+     body)))
+
+;;;; :no-require
+
+(defalias 'use-package-normalize/:no-require 'use-package-normalize-predicate)
+
+(defun use-package-handler/:no-require (name _keyword _arg rest state)
+  (use-package-process-keywords name rest state))
+
+;;;; :defines
+
+(defalias 'use-package-normalize/:defines 'use-package-normalize-symlist)
+
+(defun use-package-handler/:defines (name _keyword _arg rest state)
+  (use-package-process-keywords name rest state))
+
+;;;; :functions
+
+(defalias 'use-package-normalize/:functions 'use-package-normalize-symlist)
+
+(defun use-package-handler/:functions (name _keyword _arg rest state)
+  (use-package-process-keywords name rest state))
+
+;;;; :preface
+
+(defalias 'use-package-normalize/:preface 'use-package-normalize-forms)
+
+(defun use-package-handler/:preface (name _keyword arg rest state)
+  (let ((body (use-package-process-keywords name rest state)))
+    (use-package-concat
+     (when use-package-compute-statistics
+       `((use-package-statistics-gather :preface ',name nil)))
+     (when arg
+       `((eval-and-compile ,@arg)))
+     body
+     (when use-package-compute-statistics
+       `((use-package-statistics-gather :preface ',name t))))))
+
+;;;; :catch
+
+(defvar use-package--form)
+(defvar use-package--hush-function #'(lambda (_keyword body) body))
+
+(defsubst use-package-hush (context keyword body)
+  `((condition-case-unless-debug err
+        ,(macroexp-progn body)
+      (error (funcall ,context ,keyword err)))))
+
+(defun use-package-normalize/:catch (_name keyword args)
+  (if (null args)
+      t
+    (use-package-only-one (symbol-name keyword) args
+      use-package--hush-function)))
+
+(defun use-package-handler/:catch (name keyword arg rest state)
+  (let* ((context (cl-gentemp "use-package--warning")))
+    (cond
+     ((not arg)
+      (use-package-process-keywords name rest state))
+     ((eq arg t)
+      `((defvar ,context
+          #'(lambda (keyword err)
+              (let ((msg (format "%s/%s: %s" ',name keyword
+                                 (error-message-string err))))
+                ,@(when (eq use-package-verbose 'debug)
+                    `((with-current-buffer
+                          (get-buffer-create "*use-package*")
+                        (goto-char (point-max))
+                        (insert "-----\n" msg ,use-package--form)
+                        (emacs-lisp-mode))
+                      (setq msg
+                            (concat msg
+                                    " (see the *use-package* buffer)"))))
+                (display-warning 'use-package msg :error))))
+        ,@(let ((use-package--hush-function
+                 (apply-partially #'use-package-hush context)))
+            (funcall use-package--hush-function keyword
+                     (use-package-process-keywords name rest state)))))
+     ((functionp arg)
+      `((defvar ,context ,arg)
+        ,@(let ((use-package--hush-function
+                 (apply-partially #'use-package-hush context)))
+            (funcall use-package--hush-function keyword
+                     (use-package-process-keywords name rest state)))))
+     (t
+      (use-package-error "The :catch keyword expects 't' or a function")))))
+
+;;;; :interpreter
+
+(defalias 'use-package-normalize/:interpreter 'use-package-normalize-mode)
+(defalias 'use-package-autoloads/:interpreter 'use-package-autoloads-mode)
+
+(defun use-package-handler/:interpreter (name _keyword arg rest state)
+  (use-package-handle-mode name 'interpreter-mode-alist arg rest state))
+
+;;;; :mode
+
+(defalias 'use-package-normalize/:mode 'use-package-normalize-mode)
+(defalias 'use-package-autoloads/:mode 'use-package-autoloads-mode)
+
+(defun use-package-handler/:mode (name _keyword arg rest state)
+  (use-package-handle-mode name 'auto-mode-alist arg rest state))
+
+;;;; :magic
+
+(defalias 'use-package-normalize/:magic 'use-package-normalize-mode)
+(defalias 'use-package-autoloads/:magic 'use-package-autoloads-mode)
+
+(defun use-package-handler/:magic (name _keyword arg rest state)
+  (use-package-handle-mode name 'magic-mode-alist arg rest state))
+
+;;;; :magic-fallback
+
+(defalias 'use-package-normalize/:magic-fallback 'use-package-normalize-mode)
+(defalias 'use-package-autoloads/:magic-fallback 'use-package-autoloads-mode)
+
+(defun use-package-handler/:magic-fallback (name _keyword arg rest state)
+  (use-package-handle-mode name 'magic-fallback-mode-alist arg rest state))
+
+;;;; :hook
+
+(defun use-package-normalize/:hook (name keyword args)
+  (use-package-as-one (symbol-name keyword) args
+    #'(lambda (label arg)
+        (unless (or (use-package-non-nil-symbolp arg) (consp arg))
+          (use-package-error
+           (concat label " a <symbol> or (<symbol or list of symbols> . <symbol or function>)"
+                   " or list of these")))
+        (use-package-normalize-pairs
+         #'(lambda (k)
+             (or (use-package-non-nil-symbolp k)
+                 (and k (let ((every t))
+                          (while (and every k)
+                            (if (and (consp k)
+                                     (use-package-non-nil-symbolp (car k)))
+                                (setq k (cdr k))
+                              (setq every nil)))
+                          every))))
+         #'use-package-recognize-function
+         name label arg))))
+
+(defalias 'use-package-autoloads/:hook 'use-package-autoloads-mode)
+
+(defun use-package-handler/:hook (name _keyword args rest state)
+  "Generate use-package custom keyword code."
+  (use-package-concat
+   (use-package-process-keywords name rest state)
+   (cl-mapcan
+    #'(lambda (def)
+        (let ((syms (car def))
+              (fun (cdr def)))
+          (when fun
+            (mapcar
+             #'(lambda (sym)
+                 `(add-hook
+                   (quote ,(intern
+                            (concat (symbol-name sym)
+                                    use-package-hook-name-suffix)))
+                   (function ,fun)))
+             (if (use-package-non-nil-symbolp syms) (list syms) syms)))))
+    (use-package-normalize-commands args))))
+
+;;;; :commands
+
+(defalias 'use-package-normalize/:commands 'use-package-normalize-symlist)
+
+(defun use-package-handler/:commands (name _keyword arg rest state)
+  (use-package-concat
+   ;; Since we deferring load, establish any necessary autoloads, and also
+   ;; keep the byte-compiler happy.
+   (let ((name-string (use-package-as-string name)))
+     (cl-mapcan
+      #'(lambda (command)
+          (when (symbolp command)
+            (append
+             (unless (plist-get state :demand)
+               `((unless (fboundp ',command)
+                   (autoload #',command ,name-string nil t))))
+             (when (bound-and-true-p byte-compile-current-file)
+               `((eval-when-compile
+                   (declare-function ,command ,name-string)))))))
+      (delete-dups arg)))
+   (use-package-process-keywords name rest state)))
+
+;;;; :defer
+
+(defalias 'use-package-normalize/:defer 'use-package-normalize-predicate)
+
+(defun use-package-handler/:defer (name _keyword arg rest state)
+  (let ((body (use-package-process-keywords name rest state)))
+    (use-package-concat
+     ;; Load the package after a set amount of idle time, if the argument to
+     ;; `:defer' was a number.
+     (when (numberp arg)
+       `((run-with-idle-timer ,arg nil #'require
+                              ',(use-package-as-symbol name) nil t)))
+     (if (or (not arg) (null body))
+         body
+       `((eval-after-load ',name ',(macroexp-progn body)))))))
+
+;;;; :after
+
+(defun use-package-normalize/:after (name keyword args)
+  (setq args (use-package-normalize-recursive-symlist name keyword args))
+  (if (consp args)
+      args
+    (list args)))
+
+(defun use-package-after-count-uses (features)
+  "Count the number of time the body would appear in the result."
+  (cond ((use-package-non-nil-symbolp features)
+         1)
+        ((and (consp features)
+              (memq (car features) '(:or :any)))
+         (let ((num 0))
+           (cl-dolist (next (cdr features))
+             (setq num (+ num (use-package-after-count-uses next))))
+           num))
+        ((and (consp features)
+              (memq (car features) '(:and :all)))
+         (apply #'max (mapcar #'use-package-after-count-uses
+                              (cdr features))))
+        ((listp features)
+         (use-package-after-count-uses (cons :all features)))))
+
+(defun use-package-require-after-load (features body)
+  "Generate `eval-after-load' statements to represents FEATURES.
+FEATURES is a list containing keywords `:and' and `:all', where
+no keyword implies `:all'."
+  (cond
+   ((use-package-non-nil-symbolp features)
+    `((eval-after-load ',features ',(macroexp-progn body))))
+   ((and (consp features)
+         (memq (car features) '(:or :any)))
+    (cl-mapcan #'(lambda (x) (use-package-require-after-load x body))
+               (cdr features)))
+   ((and (consp features)
+         (memq (car features) '(:and :all)))
+    (cl-dolist (next (cdr features))
+      (setq body (use-package-require-after-load next body)))
+    body)
+   ((listp features)
+    (use-package-require-after-load (cons :all features) body))))
+
+(defun use-package-handler/:after (name _keyword arg rest state)
+  (let ((body (use-package-process-keywords name rest state))
+        (uses (use-package-after-count-uses arg)))
+    (if (or (null uses) (null body))
+        body
+      (if (<= uses 1)
+          (use-package-require-after-load arg body)
+        (use-package-memoize
+         (apply-partially #'use-package-require-after-load arg)
+         (macroexp-progn body))))))
+
+;;;; :demand
+
+(defalias 'use-package-normalize/:demand 'use-package-normalize-predicate)
+
+(defun use-package-handler/:demand (name _keyword _arg rest state)
+  (use-package-process-keywords name rest state))
+
+;;;; :custom
+
+(defun use-package-normalize/:custom (_name keyword args)
+  "Normalize use-package custom keyword."
+  (use-package-as-one (symbol-name keyword) args
+    #'(lambda (label arg)
+        (unless (listp arg)
+          (use-package-error
+           (concat label " a (<symbol> <value> [comment])"
+                   " or list of these")))
+        (if (use-package-non-nil-symbolp (car arg))
+            (list arg)
+          arg))))
+
+(defun use-package-handler/:custom (name _keyword args rest state)
+  "Generate use-package custom keyword code."
+  (use-package-concat
+   (mapcar
+    #'(lambda (def)
+        (let ((variable (nth 0 def))
+              (value (nth 1 def))
+              (comment (nth 2 def)))
+          (unless (and comment (stringp comment))
+            (setq comment (format "Customized with use-package %s" name)))
+          `(customize-set-variable (quote ,variable) ,value ,comment)))
+    args)
+   (use-package-process-keywords name rest state)))
+
+;;;; :custom-face
+
+(defun use-package-normalize/:custom-face (name-symbol _keyword arg)
+  "Normalize use-package custom-face keyword."
+  (let ((error-msg
+         (format "%s wants a (<symbol> <face-spec>) or list of these"
+                 name-symbol)))
+    (unless (listp arg)
+      (use-package-error error-msg))
+    (cl-dolist (def arg arg)
+      (unless (listp def)
+        (use-package-error error-msg))
+      (let ((face (nth 0 def))
+            (spec (nth 1 def)))
+        (when (or (not face)
+                  (not spec)
+                  (> (length def) 2))
+          (use-package-error error-msg))))))
+
+(defun use-package-handler/:custom-face (name _keyword args rest state)
+  "Generate use-package custom-face keyword code."
+  (use-package-concat
+   (mapcar #'(lambda (def) `(custom-set-faces (quote ,def))) args)
+   (use-package-process-keywords name rest state)))
+
+;;;; :init
+
+(defalias 'use-package-normalize/:init 'use-package-normalize-forms)
+
+(defun use-package-handler/:init (name _keyword arg rest state)
+  (use-package-concat
+   (when use-package-compute-statistics
+     `((use-package-statistics-gather :init ',name nil)))
+   (let ((init-body
+          (use-package-hook-injector (use-package-as-string name)
+                                     :init arg)))
+     (when init-body
+       (funcall use-package--hush-function :init
+                (if use-package-check-before-init
+                    `((when (locate-library ,(use-package-as-string name))
+                        ,@init-body))
+                  init-body))))
+   (use-package-process-keywords name rest state)
+   (when use-package-compute-statistics
+     `((use-package-statistics-gather :init ',name t)))))
+
+;;;; :load
+
+(defun use-package-normalize/:load (name keyword args)
+  (setq args (use-package-normalize-recursive-symlist name keyword args))
+  (if (consp args)
+      args
+    (list args)))
+
+(defun use-package-handler/:load (name _keyword arg rest state)
+  (let ((body (use-package-process-keywords name rest state)))
+    (cl-dolist (pkg arg)
+      (setq body (use-package-require (if (eq t pkg) name pkg) nil body)))
+    body))
+
+;;;; :config
+
+(defalias 'use-package-normalize/:config 'use-package-normalize-forms)
+
+(defun use-package-handler/:config (name _keyword arg rest state)
+  (let* ((body (use-package-process-keywords name rest state))
+         (name-symbol (use-package-as-symbol name)))
+    (use-package-concat
+     (when use-package-compute-statistics
+       `((use-package-statistics-gather :config ',name nil)))
+     (if (or (null arg) (equal arg '(t)))
+         body
+       (use-package-with-elapsed-timer
+           (format "Configuring package %s" name-symbol)
+         (funcall use-package--hush-function :config
+                  (use-package-concat
+                   (use-package-hook-injector
+                    (symbol-name name-symbol) :config arg)
+                   body
+                   (list t)))))
+     (when use-package-compute-statistics
+       `((use-package-statistics-gather :config ',name t))))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;; The main macro
+;;
+
+(defmacro use-package-core (name args)
+  `(let* ((args* (use-package-normalize-keywords ,name ,args))
+          (use-package--form
+           (if (eq use-package-verbose 'debug)
+               (concat "\n\n"
+                       (pp-to-string `(use-package ,name ,@,args))
+                       "\n  -->\n\n"
+                       (pp-to-string `(use-package ,name ,@args*))
+                       "\n  ==>\n\n"
+                       (pp-to-string
+                        (macroexp-progn
+                         (let ((use-package-verbose 'errors)
+                               (use-package-expand-minimally t))
+                           (use-package-process-keywords name args*
+                             (and (plist-get args* :demand)
+                                  (list :demand t)))))))
+             "")))
+     (use-package-process-keywords name args*
+       (and (plist-get args* :demand)
+            (list :demand t)))))
+
+;;;###autoload
+(defmacro use-package (name &rest args)
+  "Declare an Emacs package by specifying a group of configuration options.
+
+For full documentation, please see the README file that came with
+this file.  Usage:
+
+  (use-package package-name
+     [:keyword [option]]...)
+
+:init            Code to run before PACKAGE-NAME has been loaded.
+:config          Code to run after PACKAGE-NAME has been loaded.  Note that
+                 if loading is deferred for any reason, this code does not
+                 execute until the lazy load has occurred.
+:preface         Code to be run before everything except `:disabled'; this
+                 can be used to define functions for use in `:if', or that
+                 should be seen by the byte-compiler.
+
+:mode            Form to be added to `auto-mode-alist'.
+:magic           Form to be added to `magic-mode-alist'.
+:magic-fallback  Form to be added to `magic-fallback-mode-alist'.
+:interpreter     Form to be added to `interpreter-mode-alist'.
+
+:commands        Define autoloads for commands that will be defined by the
+                 package.  This is useful if the package is being lazily
+                 loaded, and you wish to conditionally call functions in your
+                 `:init' block that are defined in the package.
+
+:bind            Bind keys, and define autoloads for the bound commands.
+:bind*           Bind keys, and define autoloads for the bound commands,
+                 *overriding all minor mode bindings*.
+:bind-keymap     Bind a key prefix to an auto-loaded keymap defined in the
+                 package.  This is like `:bind', but for keymaps.
+:bind-keymap*    Like `:bind-keymap', but overrides all minor mode bindings
+
+:defer           Defer loading of a package -- this is implied when using
+                 `:commands', `:bind', `:bind*', `:mode', `:magic',
+                 `:magic-fallback', or `:interpreter'.  This can be an integer,
+                 to force loading after N seconds of idle time, if the package
+                 has not already been loaded.
+:after           Defer loading of a package until after any of the named
+                 features are loaded.
+:demand          Prevent deferred loading in all cases.
+
+:if EXPR         Initialize and load only if EXPR evaluates to a non-nil value.
+:disabled        The package is ignored completely if this keyword is present.
+:defines         Declare certain variables to silence the byte-compiler.
+:functions       Declare certain functions to silence the byte-compiler.
+:load-path       Add to the `load-path' before attempting to load the package.
+:diminish        Support for diminish.el (if installed).
+:delight         Support for delight.el (if installed).
+:custom          Call `customize-set-variable' with each variable definition.
+:custom-face     Call `customize-set-faces' with each face definition.
+:ensure          Loads the package using package.el if necessary.
+:pin             Pin the package to an archive."
+  (declare (indent 1))
+  (unless (memq :disabled args)
+    (macroexp-progn
+     (use-package-concat
+      (when use-package-compute-statistics
+        `((use-package-statistics-gather :use-package ',name nil)))
+      (if (eq use-package-verbose 'errors)
+          (use-package-core name args)
+        (condition-case-unless-debug err
+            (use-package-core name args)
+          (error
+           (ignore
+            (display-warning
+             'use-package
+             (format "Failed to parse package %s: %s"
+                     name (error-message-string err)) :error)))))
+      (when use-package-compute-statistics
+        `((use-package-statistics-gather :use-package ',name t)))))))
+
+(put 'use-package 'lisp-indent-function 'defun)
+
+(provide 'use-package-core)
+
+;; Local Variables:
+;; indent-tabs-mode: nil
+;; End:
+
+;;; use-package-core.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package-core.elc b/configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package-core.elc
new file mode 100644
index 0000000000..40a1092bc9
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package-core.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package-delight.el b/configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package-delight.el
new file mode 100644
index 0000000000..85d5c7cb4d
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package-delight.el
@@ -0,0 +1,91 @@
+;;; use-package-delight.el --- Support for the :delight keyword  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2012-2017 John Wiegley
+
+;; Author: John Wiegley <johnw@newartisans.com>
+;; Maintainer: John Wiegley <johnw@newartisans.com>
+;; Created: 17 Jun 2012
+;; Modified: 3 Dec 2017
+;; Version: 1.0
+;; Package-Requires: ((emacs "24.3") (use-package "2.4"))
+;; Keywords: dotemacs startup speed config package
+;; URL: https://github.com/jwiegley/use-package
+
+;; This program 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, or (at
+;; your option) any later version.
+
+;; This program 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; see the file COPYING.  If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+
+;; Provides support for the :delight keyword, which is made available by
+;; default by requiring `use-package'.
+
+;;; Code:
+
+(require 'use-package-core)
+
+(defun use-package-normalize-delight (name args)
+  "Normalize ARGS for a single call to `delight'."
+  (when (eq :eval (car args))
+    ;; Handle likely common mistake.
+    (use-package-error ":delight mode line constructs must be quoted"))
+  (cond ((and (= (length args) 1)
+              (use-package-non-nil-symbolp (car args)))
+         `(,(nth 0 args) nil ,name))
+        ((= (length args) 2)
+         `(,(nth 0 args) ,(nth 1 args) ,name))
+        ((= (length args) 3)
+         args)
+        (t
+         (use-package-error
+          ":delight expects `delight' arguments or a list of them"))))
+
+;;;###autoload
+(defun use-package-normalize/:delight (name _keyword args)
+  "Normalize arguments to delight."
+  (cond ((null args)
+         `((,(use-package-as-mode name) nil ,name)))
+        ((and (= (length args) 1)
+              (use-package-non-nil-symbolp (car args)))
+         `((,(car args) nil ,name)))
+        ((and (= (length args) 1)
+              (stringp (car args)))
+         `((,(use-package-as-mode name) ,(car args) ,name)))
+        ((and (= (length args) 1)
+              (listp (car args))
+              (eq 'quote (caar args)))
+         `((,(use-package-as-mode name) ,@(cdar args) ,name)))
+        ((and (= (length args) 2)
+              (listp (nth 1 args))
+              (eq 'quote (car (nth 1 args))))
+         `((,(car args) ,@(cdr (nth 1 args)) ,name)))
+        (t (mapcar
+            (apply-partially #'use-package-normalize-delight name)
+            (if (use-package-non-nil-symbolp (car args))
+                (list args)
+              args)))))
+
+;;;###autoload
+(defun use-package-handler/:delight (name _keyword args rest state)
+  (let ((body (use-package-process-keywords name rest state)))
+    (use-package-concat
+     body
+     `((if (fboundp 'delight)
+           (delight '(,@args)))))))
+
+(add-to-list 'use-package-keywords :delight t)
+
+(provide 'use-package-delight)
+
+;;; use-package-delight.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package-delight.elc b/configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package-delight.elc
new file mode 100644
index 0000000000..42b40054f7
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package-delight.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package-diminish.el b/configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package-diminish.el
new file mode 100644
index 0000000000..1f3895f42c
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package-diminish.el
@@ -0,0 +1,80 @@
+;;; use-package-diminish.el --- Support for the :diminish keyword  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2012-2017 John Wiegley
+
+;; Author: John Wiegley <johnw@newartisans.com>
+;; Maintainer: John Wiegley <johnw@newartisans.com>
+;; Created: 17 Jun 2012
+;; Modified: 3 Dec 2017
+;; Version: 1.0
+;; Package-Requires: ((emacs "24.3") (use-package "2.4"))
+;; Keywords: dotemacs startup speed config package
+;; URL: https://github.com/jwiegley/use-package
+
+;; This program 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, or (at
+;; your option) any later version.
+
+;; This program 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; see the file COPYING.  If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+
+;; Provides support for the :diminish keyword, which is made available by
+;; default by requiring `use-package'.
+
+;;; Code:
+
+(require 'use-package-core)
+
+(defun use-package-normalize-diminish (name label arg &optional recursed)
+  "Normalize the arguments to diminish down to a list of one of two forms:
+     SYMBOL
+     (SYMBOL . STRING)"
+  (cond
+   ((not arg)
+    (list (use-package-as-mode name)))
+   ((use-package-non-nil-symbolp arg)
+    (list arg))
+   ((stringp arg)
+    (list (cons (use-package-as-mode name) arg)))
+   ((and (consp arg) (stringp (cdr arg)))
+    (list arg))
+   ((and (not recursed) (listp arg) (listp (cdr arg)))
+    (mapcar #'(lambda (x) (car (use-package-normalize-diminish
+                           name label x t))) arg))
+   (t
+    (use-package-error
+     (concat label " wants a string, symbol, "
+             "(symbol . string) or list of these")))))
+
+;;;###autoload
+(defun use-package-normalize/:diminish (name keyword args)
+  (use-package-as-one (symbol-name keyword) args
+    (apply-partially #'use-package-normalize-diminish name) t))
+
+;;;###autoload
+(defun use-package-handler/:diminish (name _keyword arg rest state)
+  (let ((body (use-package-process-keywords name rest state)))
+    (use-package-concat
+     (mapcar #'(lambda (var)
+                 `(if (fboundp 'diminish)
+                      ,(if (consp var)
+                           `(diminish ',(car var) ,(cdr var))
+                         `(diminish ',var))))
+             arg)
+     body)))
+
+(add-to-list 'use-package-keywords :diminish t)
+
+(provide 'use-package-diminish)
+
+;;; use-package-diminish.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package-diminish.elc b/configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package-diminish.elc
new file mode 100644
index 0000000000..409e54218a
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package-diminish.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package-ensure.el b/configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package-ensure.el
new file mode 100644
index 0000000000..50005a9e99
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package-ensure.el
@@ -0,0 +1,214 @@
+;;; use-package-ensure.el --- Support for the :ensure and :pin keywords  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2012-2017 John Wiegley
+
+;; Author: John Wiegley <johnw@newartisans.com>
+;; Maintainer: John Wiegley <johnw@newartisans.com>
+;; Created: 17 Jun 2012
+;; Modified: 3 Dec 2017
+;; Version: 1.0
+;; Package-Requires: ((emacs "24.3") (use-package "2.4"))
+;; Keywords: dotemacs startup speed config package
+;; URL: https://github.com/jwiegley/use-package
+
+;; This program 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, or (at
+;; your option) any later version.
+
+;; This program 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; see the file COPYING.  If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+
+;; Provides support for the :ensure and :pin keywords, which is made available
+;; by default by requiring `use-package'.
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'use-package-core)
+
+(defgroup use-package-ensure nil
+  "Support for :ensure and :pin keywords in use-package declarations."
+  :group 'use-package)
+
+(eval-when-compile
+  (declare-function package-installed-p "package")
+  (declare-function package-read-all-archive-contents "package" ()))
+
+(defcustom use-package-always-ensure nil
+  "Treat every package as though it had specified using `:ensure SEXP'.
+See also `use-package-defaults', which uses this value."
+  :type 'sexp
+  :group 'use-package-ensure)
+
+(defcustom use-package-always-pin nil
+  "Treat every package as though it had specified using `:pin SYM'.
+See also `use-package-defaults', which uses this value."
+  :type 'symbol
+  :group 'use-package-ensure)
+
+(defcustom use-package-ensure-function 'use-package-ensure-elpa
+  "Function that ensures a package is installed.
+This function is called with three arguments: the name of the
+package declared in the `use-package' form; the arguments passed
+to all `:ensure' keywords (always a list, even if only one); and
+the current `state' plist created by previous handlers.
+
+Note that this function is called whenever `:ensure' is provided,
+even if it is nil. It is up to the function to decide on the
+semantics of the various values for `:ensure'.
+
+This function should return non-nil if the package is installed.
+
+The default value uses package.el to install the package."
+  :type '(choice (const :tag "package.el" use-package-ensure-elpa)
+                 (function :tag "Custom"))
+  :group 'use-package-ensure)
+
+;;;; :pin
+
+(defun use-package-normalize/:pin (_name keyword args)
+  (use-package-only-one (symbol-name keyword) args
+    #'(lambda (_label arg)
+        (cond
+         ((stringp arg) arg)
+         ((use-package-non-nil-symbolp arg) (symbol-name arg))
+         (t
+          (use-package-error
+           ":pin wants an archive name (a string)"))))))
+
+(eval-when-compile
+  (defvar package-pinned-packages)
+  (defvar package-archives))
+
+(defun use-package-archive-exists-p (archive)
+  "Check if a given ARCHIVE is enabled.
+
+ARCHIVE can be a string or a symbol or 'manual to indicate a
+manually updated package."
+  (if (member archive '(manual "manual"))
+      't
+    (let ((valid nil))
+      (dolist (pa package-archives)
+        (when (member archive (list (car pa) (intern (car pa))))
+          (setq valid 't)))
+      valid)))
+
+(defun use-package-pin-package (package archive)
+  "Pin PACKAGE to ARCHIVE."
+  (unless (boundp 'package-pinned-packages)
+    (setq package-pinned-packages ()))
+  (let ((archive-symbol (if (symbolp archive) archive (intern archive)))
+        (archive-name   (if (stringp archive) archive (symbol-name archive))))
+    (if (use-package-archive-exists-p archive-symbol)
+        (add-to-list 'package-pinned-packages (cons package archive-name))
+      (error "Archive '%s' requested for package '%s' is not available."
+             archive-name package))
+    (unless (bound-and-true-p package--initialized)
+      (package-initialize t))))
+
+(defun use-package-handler/:pin (name _keyword archive-name rest state)
+  (let ((body (use-package-process-keywords name rest state))
+        (pin-form (if archive-name
+                      `(use-package-pin-package ',(use-package-as-symbol name)
+                                                ,archive-name))))
+    ;; Pinning should occur just before ensuring
+    ;; See `use-package-handler/:ensure'.
+    (if (bound-and-true-p byte-compile-current-file)
+        (eval pin-form)              ; Eval when byte-compiling,
+      (push pin-form body))          ; or else wait until runtime.
+    body))
+
+;;;; :ensure
+
+(defvar package-archive-contents)
+
+;;;###autoload
+(defun use-package-normalize/:ensure (_name keyword args)
+  (if (null args)
+      (list t)
+    (use-package-only-one (symbol-name keyword) args
+      #'(lambda (_label arg)
+          (cond
+           ((symbolp arg)
+            (list arg))
+           ((and (listp arg) (= 3 (length arg))
+                 (symbolp (nth 0 arg))
+                 (eq :pin (nth 1 arg))
+                 (or (stringp (nth 2 arg))
+                     (symbolp (nth 2 arg))))
+            (list (cons (nth 0 arg) (nth 2 arg))))
+           (t
+            (use-package-error
+             (concat ":ensure wants an optional package name "
+                     "(an unquoted symbol name), or (<symbol> :pin <string>)"))))))))
+
+(defun use-package-ensure-elpa (name args _state &optional _no-refresh)
+  (dolist (ensure args)
+    (let ((package
+           (or (and (eq ensure t) (use-package-as-symbol name))
+               ensure)))
+      (when package
+        (require 'package)
+        (when (consp package)
+          (use-package-pin-package (car package) (cdr package))
+          (setq package (car package)))
+        (unless (package-installed-p package)
+          (condition-case-unless-debug err
+              (progn
+                (when (assoc package (bound-and-true-p
+                                      package-pinned-packages))
+                  (package-read-all-archive-contents))
+                (if (assoc package package-archive-contents)
+                    (package-install package)
+                  (package-refresh-contents)
+                  (when (assoc package (bound-and-true-p
+                                        package-pinned-packages))
+                    (package-read-all-archive-contents))
+                  (package-install package))
+                t)
+            (error
+             (display-warning 'use-package
+                              (format "Failed to install %s: %s"
+                                      name (error-message-string err))
+                              :error))))))))
+
+;;;###autoload
+(defun use-package-handler/:ensure (name _keyword ensure rest state)
+  (let* ((body (use-package-process-keywords name rest state)))
+    ;; We want to avoid installing packages when the `use-package' macro is
+    ;; being macro-expanded by elisp completion (see `lisp--local-variables'),
+    ;; but still install packages when byte-compiling, to avoid requiring
+    ;; `package' at runtime.
+    (if (bound-and-true-p byte-compile-current-file)
+        ;; Eval when byte-compiling,
+        (funcall use-package-ensure-function name ensure state)
+      ;;  or else wait until runtime.
+      (push `(,use-package-ensure-function ',name ',ensure ',state)
+            body))
+    body))
+
+(add-to-list 'use-package-defaults
+             '(:ensure (list use-package-always-ensure)
+                       (lambda (name args)
+                         (and use-package-always-ensure
+                              (not (plist-member args :load-path))))) t)
+
+(add-to-list 'use-package-defaults
+             '(:pin use-package-always-pin use-package-always-pin) t)
+
+(add-to-list 'use-package-keywords :ensure)
+(add-to-list 'use-package-keywords :pin)
+
+(provide 'use-package-ensure)
+
+;;; use-package-ensure.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package-ensure.elc b/configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package-ensure.elc
new file mode 100644
index 0000000000..88128c9779
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package-ensure.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package-jump.el b/configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package-jump.el
new file mode 100644
index 0000000000..4044ad1656
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package-jump.el
@@ -0,0 +1,79 @@
+;;; use-package-jump.el --- Attempt to jump to a use-package declaration  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2012-2017 John Wiegley
+
+;; Author: John Wiegley <johnw@newartisans.com>
+;; Maintainer: John Wiegley <johnw@newartisans.com>
+;; Created: 17 Jun 2012
+;; Modified: 3 Dec 2017
+;; Version: 1.0
+;; Package-Requires: ((emacs "24.3") (use-package "2.4"))
+;; Keywords: dotemacs startup speed config package
+;; URL: https://github.com/jwiegley/use-package
+
+;; This program 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, or (at
+;; your option) any later version.
+
+;; This program 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; see the file COPYING.  If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+
+;; Provides the command `M-x use-package-jump-to-package-form', however it
+;; only works if the package being jumped to was required during
+;; initialization. If it was delay-loaded, it will not work. Improvements are
+;; needed.
+
+;;; Code:
+
+(require 'use-package-core)
+
+(defun use-package-find-require (package)
+  "Find file that required PACKAGE by searching `load-history'.
+Returns an absolute file path or nil if none is found."
+  (catch 'suspect
+    (dolist (filespec load-history)
+      (dolist (entry (cdr filespec))
+        (when (equal entry (cons 'require package))
+          (throw 'suspect (car filespec)))))))
+
+;;;###autoload
+(defun use-package-jump-to-package-form (package)
+  "Attempt to find and jump to the `use-package' form that loaded
+PACKAGE. This will only find the form if that form actually
+required PACKAGE. If PACKAGE was previously required then this
+function will jump to the file that originally required PACKAGE
+instead."
+  (interactive (list (completing-read "Package: " features)))
+  (let* ((package (if (stringp package) (intern package) package))
+         (requiring-file (use-package-find-require package))
+         file location)
+    (if (null requiring-file)
+        (user-error "Can't find file requiring file; may have been autoloaded")
+      (setq file (if (string= (file-name-extension requiring-file) "elc")
+                     (concat (file-name-sans-extension requiring-file) ".el")
+                   requiring-file))
+      (when (file-exists-p file)
+        (find-file-other-window file)
+        (save-excursion
+          (goto-char (point-min))
+          (setq location
+                (re-search-forward
+                 (format (eval use-package-form-regexp-eval) package) nil t)))
+        (if (null location)
+            (message "No use-package form found.")
+          (goto-char location)
+          (beginning-of-line))))))
+
+(provide 'use-package-jump)
+
+;;; use-package-jump.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package-jump.elc b/configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package-jump.elc
new file mode 100644
index 0000000000..8bc753c56c
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package-jump.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package-lint.el b/configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package-lint.el
new file mode 100644
index 0000000000..c6e7c3c0ce
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package-lint.el
@@ -0,0 +1,84 @@
+;;; use-package-lint.el --- Attempt to find errors in use-package declarations  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2012-2017 John Wiegley
+
+;; Author: John Wiegley <johnw@newartisans.com>
+;; Maintainer: John Wiegley <johnw@newartisans.com>
+;; Created: 17 Jun 2012
+;; Modified: 3 Dec 2017
+;; Version: 1.0
+;; Package-Requires: ((emacs "24.3") (use-package "2.4"))
+;; Keywords: dotemacs startup speed config package
+;; URL: https://github.com/jwiegley/use-package
+
+;; This program 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, or (at
+;; your option) any later version.
+
+;; This program 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; see the file COPYING.  If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+
+;; Provides the command `M-x use-package-lint'.
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'use-package-core)
+
+(defun use-package-lint-declaration (name plist)
+  (dolist (path (plist-get plist :load-path))
+    (unless (file-exists-p path)
+      (display-warning
+       'use-package
+       (format "%s :load-path does not exist: %s"
+               name path) :error)))
+
+  (unless (or (plist-member plist :disabled)
+              (plist-get plist :no-require)
+              (locate-library (use-package-as-string name) nil
+                              (plist-get plist :load-path)))
+    (display-warning
+     'use-package
+     (format "%s module cannot be located" name) :error))
+
+  ;; (dolist (command (plist-get plist :commands))
+  ;;   (unless (string= (find-lisp-object-file-name command nil)
+  ;;                    (locate-library (use-package-as-string name) nil
+  ;;                                    (plist-get plist :load-path)))
+  ;;     (display-warning
+  ;;      'use-package
+  ;;      (format "%s :command is from different path: %s"
+  ;;              name (symbol-name command)) :error)))
+  )
+
+;;;###autoload
+(defun use-package-lint ()
+  "Check for errors in use-package declarations.
+For example, if the module's `:if' condition is met, but even
+with the specified `:load-path' the module cannot be found."
+  (interactive)
+  (save-excursion
+    (goto-char (point-min))
+    (let ((re (eval use-package-form-regexp-eval)))
+      (while (re-search-forward re nil t)
+        (goto-char (match-beginning 0))
+        (let ((decl (read (current-buffer))))
+          (when (eq (car decl) 'use-package)
+            (use-package-lint-declaration
+             (use-package-as-string (cadr decl))
+             (use-package-normalize-keywords
+              (cadr decl) (cddr decl)))))))))
+
+(provide 'use-package-lint)
+
+;;; use-package-lint.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package-lint.elc b/configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package-lint.elc
new file mode 100644
index 0000000000..cc86871608
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package-lint.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package-pkg.el b/configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package-pkg.el
new file mode 100644
index 0000000000..f8b66a5070
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package-pkg.el
@@ -0,0 +1,9 @@
+(define-package "use-package" "20180715.1101" "A configuration macro for simplifying your .emacs"
+  '((emacs "24.3")
+    (bind-key "2.4"))
+  :keywords
+  '("dotemacs" "startup" "speed" "config" "package")
+  :url "https://github.com/jwiegley/use-package")
+;; Local Variables:
+;; no-byte-compile: t
+;; End:
diff --git a/configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package.el b/configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package.el
new file mode 100644
index 0000000000..1a8fff895f
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package.el
@@ -0,0 +1,54 @@
+;;; use-package.el --- A configuration macro for simplifying your .emacs  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2012-2017 John Wiegley
+
+;; Author: John Wiegley <johnw@newartisans.com>
+;; Maintainer: John Wiegley <johnw@newartisans.com>
+;; Created: 17 Jun 2012
+;; Modified: 29 Nov 2017
+;; Version: 2.4
+;; Package-Requires: ((emacs "24.3") (bind-key "2.4"))
+;; Keywords: dotemacs startup speed config package
+;; URL: https://github.com/jwiegley/use-package
+
+;; This program 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, or (at
+;; your option) any later version.
+
+;; This program 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; see the file COPYING.  If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+
+;; The `use-package' declaration macro allows you to isolate package
+;; configuration in your ".emacs" in a way that is performance-oriented and,
+;; well, just tidy.  I created it because I have over 80 packages that I use
+;; in Emacs, and things were getting difficult to manage.  Yet with this
+;; utility my total load time is just under 1 second, with no loss of
+;; functionality!
+;;
+;; Please see README.md from the same repository for documentation.
+
+;;; Code:
+
+(require 'use-package-core)
+
+(require 'use-package-bind-key)
+(require 'use-package-diminish)
+(require 'use-package-delight)
+(require 'use-package-ensure)
+
+(declare-function use-package-jump-to-package-form "use-package-jump")
+(autoload #'use-package-jump-to-package-form "use-package-jump" nil t)
+
+(provide 'use-package)
+
+;;; use-package.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package.elc b/configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package.elc
new file mode 100644
index 0000000000..bcd624cfac
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package.info b/configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package.info
new file mode 100644
index 0000000000..f80f1fd84f
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/use-package-20180715.1101/use-package.info
@@ -0,0 +1,1048 @@
+This is use-package.info, produced by makeinfo version 6.1 from
+use-package.texi.
+
+     Copyright (C) 2012-2017 John Wiegley <johnw@newartisans.com>
+
+     You can redistribute this document 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.
+
+     This document 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.
+INFO-DIR-SECTION Emacs
+START-INFO-DIR-ENTRY
+* use-package: (use-package). Declarative package configuration for Emacs.
+END-INFO-DIR-ENTRY
+
+
+File: use-package.info,  Node: Top,  Next: Introduction,  Up: (dir)
+
+use-package User Manual
+***********************
+
+use-package is...
+
+     Copyright (C) 2012-2017 John Wiegley <johnw@newartisans.com>
+
+     You can redistribute this document 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.
+
+     This document 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.
+
+* Menu:
+
+* Introduction::
+* Installation::
+* Getting Started::
+* Keywords::
+* FAQ::
+* Debugging Tools::
+* Command Index::
+* Function Index::
+* Variable Index::
+
+— The Detailed Node Listing —
+
+
+Installation
+
+* Installing from an Elpa Archive::
+* Installing from the Git Repository::
+* Post-Installation Tasks::
+
+
+
+
+Keywords
+
+* ‘:after’: after. 
+* ‘:bind-keymap’, ‘:bind-keymap*’: bind-keymap bind-keymap*. 
+* ‘:bind’, ‘:bind*’: bind bind*. 
+* ‘:commands’: commands. 
+* ‘:preface’, ‘:init’, ‘:config’: preface init config. 
+* ‘:custom’: custom. 
+* ‘:custom-face’: custom-face. 
+* ‘:defer’, ‘:demand’: defer demand. 
+* ‘:defines’, ‘:functions’: defines functions. 
+* ‘:diminish’, ‘:delight’: diminish delight. 
+* ‘:disabled’: disabled. 
+* ‘:ensure’, ‘:pin’: ensure pin. 
+* ‘:hook’: hook. 
+* ‘:if’, ‘:when’, ‘:unless’: if when unless. 
+* ‘:load-path’: load-path. 
+* ‘:mode’, ‘:interpreter’: mode interpreter. 
+* ‘:magic’, ‘:magic-fallback’: magic magic-fallback. 
+* ‘:no-require’: no-require. 
+* ‘:requires’: requires. 
+
+
+
+‘:bind’, ‘:bind*’
+
+* Binding to local keymaps::
+
+FAQ
+
+* FAQ - How to ...?::
+* FAQ - Issues and Errors::
+
+FAQ - How to ...?
+
+* This is a question::
+
+
+FAQ - Issues and Errors
+
+* This is an issues::
+
+
+File: use-package.info,  Node: Introduction,  Next: Installation,  Prev: Top,  Up: Top
+
+1 Introduction
+**************
+
+The ‘use-package’ macro allows you to isolate package configuration in
+your ‘.emacs’ file in a way that is both performance-oriented and, well,
+tidy.  I created it because I have over 400 packages that I use in
+Emacs, and things were getting difficult to manage.  Yet with this
+utility my total load time is around 2 seconds, with no loss of
+functionality!
+
+
+File: use-package.info,  Node: Installation,  Next: Getting Started,  Prev: Introduction,  Up: Top
+
+2 Installation
+**************
+
+use-package can be installed using Emacs’ package manager or manually
+from its development repository.
+
+* Menu:
+
+* Installing from an Elpa Archive::
+* Installing from the Git Repository::
+* Post-Installation Tasks::
+
+
+File: use-package.info,  Node: Installing from an Elpa Archive,  Next: Installing from the Git Repository,  Up: Installation
+
+2.1 Installing from an Elpa Archive
+===================================
+
+use-package is available from Melpa and Melpa-Stable.  If you haven’t
+used Emacs’ package manager before, then it is high time you familiarize
+yourself with it by reading the documentation in the Emacs manual, see
+*note (emacs)Packages::.  Then add one of the archives to
+‘package-archives’:
+
+   • To use Melpa:
+
+     (require 'package)
+     (add-to-list 'package-archives
+     	     '("melpa" . "https://melpa.org/packages/") t)
+
+   • To use Melpa-Stable:
+
+     (require 'package)
+     (add-to-list 'package-archives
+     	     '("melpa-stable" . "https://stable.melpa.org/packages/") t)
+
+   Once you have added your preferred archive, you need to update the
+local package list using:
+
+     M-x package-refresh-contents RET
+
+   Once you have done that, you can install use-package and its
+dependencies using:
+
+     M-x package-install RET use-package RET
+
+   Now see *note Post-Installation Tasks::.
+
+
+File: use-package.info,  Node: Installing from the Git Repository,  Next: Post-Installation Tasks,  Prev: Installing from an Elpa Archive,  Up: Installation
+
+2.2 Installing from the Git Repository
+======================================
+
+First, use Git to clone the use-package repository:
+
+     $ git clone https://github.com/jwiegley/use-package.git ~/.emacs.d/site-lisp/use-package
+     $ cd ~/.emacs.d/site-lisp/use-package
+
+   Then compile the libraries and generate the info manuals:
+
+     $ make
+
+   You may need to create ‘/path/to/use-package/config.mk’ with the
+following content before running ‘make’:
+
+     LOAD_PATH  = -L /path/to/use-package
+
+   Finally add this to your init file:
+
+     (add-to-list 'load-path "~/.emacs.d/site-lisp/use-package")
+     (require 'use-package)
+
+     (with-eval-after-load 'info
+       (info-initialize)
+       (add-to-list 'Info-directory-list
+     	       "~/.emacs.d/site-lisp/use-package/"))
+
+   Note that elements of ‘load-path’ should not end with a slash, while
+those of ‘Info-directory-list’ should.
+
+   Instead of running use-package directly from the repository by adding
+it to the ‘load-path’, you might want to instead install it in some
+other directory using ‘sudo make install’ and setting ‘load-path’
+accordingly.
+
+   To update use-package use:
+
+     $ git pull
+     $ make
+
+   At times it might be necessary to run ‘make clean all’ instead.
+
+   To view all available targets use ‘make help’.
+
+   Now see *note Post-Installation Tasks::.
+
+
+File: use-package.info,  Node: Post-Installation Tasks,  Prev: Installing from the Git Repository,  Up: Installation
+
+2.3 Post-Installation Tasks
+===========================
+
+After installing use-package you should verify that you are indeed using
+the use-package release you think you are using.  It’s best to restart
+Emacs before doing so, to make sure you are not using an outdated value
+for ‘load-path’.
+
+     C-h v use-package-version RET
+
+   should display something like
+
+     use-package-version’s value is "2.4"
+
+   If you are completely new to use-package then see *note Getting
+Started::.
+
+   If you run into problems, then please see the *note FAQ::.  Also see
+the *note Debugging Tools::.
+
+
+File: use-package.info,  Node: Getting Started,  Next: Keywords,  Prev: Installation,  Up: Top
+
+3 Getting Started
+*****************
+
+TODO. For now, see ‘README.md’.
+
+
+File: use-package.info,  Node: Keywords,  Next: FAQ,  Prev: Getting Started,  Up: Top
+
+4 Keywords
+**********
+
+* Menu:
+
+* ‘:after’: after. 
+* ‘:bind-keymap’, ‘:bind-keymap*’: bind-keymap bind-keymap*. 
+* ‘:bind’, ‘:bind*’: bind bind*. 
+* ‘:commands’: commands. 
+* ‘:preface’, ‘:init’, ‘:config’: preface init config. 
+* ‘:custom’: custom. 
+* ‘:custom-face’: custom-face. 
+* ‘:defer’, ‘:demand’: defer demand. 
+* ‘:defines’, ‘:functions’: defines functions. 
+* ‘:diminish’, ‘:delight’: diminish delight. 
+* ‘:disabled’: disabled. 
+* ‘:ensure’, ‘:pin’: ensure pin. 
+* ‘:hook’: hook. 
+* ‘:if’, ‘:when’, ‘:unless’: if when unless. 
+* ‘:load-path’: load-path. 
+* ‘:mode’, ‘:interpreter’: mode interpreter. 
+* ‘:magic’, ‘:magic-fallback’: magic magic-fallback. 
+* ‘:no-require’: no-require. 
+* ‘:requires’: requires. 
+
+
+File: use-package.info,  Node: after,  Next: bind-keymap bind-keymap*,  Up: Keywords
+
+4.1 ‘:after’
+============
+
+Sometimes it only makes sense to configure a package after another has
+been loaded, because certain variables or functions are not in scope
+until that time.  This can achieved using an ‘:after’ keyword that
+allows a fairly rich description of the exact conditions when loading
+should occur.  Here is an example:
+
+     (use-package hydra
+       :load-path "site-lisp/hydra")
+
+     (use-package ivy
+       :load-path "site-lisp/swiper")
+
+     (use-package ivy-hydra
+       :after (ivy hydra))
+
+   In this case, because all of these packages are demand-loaded in the
+order they occur, the use of ‘:after’ is not strictly necessary.  By
+using it, however, the above code becomes order-independent, without an
+implicit depedence on the nature of your init file.
+
+   By default, ‘:after (foo bar)’ is the same as ‘:after (:all foo
+bar)’, meaning that loading of the given package will not happen until
+both ‘foo’ and ‘bar’ have been loaded.  Here are some of the other
+possibilities:
+
+     :after (foo bar)
+     :after (:all foo bar)
+     :after (:any foo bar)
+     :after (:all (:any foo bar) (:any baz quux))
+     :after (:any (:all foo bar) (:all baz quux))
+
+   When you nest selectors, such as ‘(:any (:all foo bar) (:all baz
+quux))’, it means that the package will be loaded when either both ‘foo’
+and ‘bar’ have been loaded, or both ‘baz’ and ‘quux’ have been loaded.
+
+
+File: use-package.info,  Node: bind-keymap bind-keymap*,  Next: bind bind*,  Prev: after,  Up: Keywords
+
+4.2 ‘:bind-keymap’, ‘:bind-keymap*’
+===================================
+
+Normally ‘:bind’ expects that commands are functions that will be
+autoloaded from the given package.  However, this does not work if one
+of those commands is actually a keymap, since keymaps are not functions,
+and cannot be autoloaded using Emacs’ ‘autoload’ mechanism.
+
+   To handle this case, ‘use-package’ offers a special, limited variant
+of ‘:bind’ called ‘:bind-keymap’.  The only difference is that the
+"commands" bound to by ‘:bind-keymap’ must be keymaps defined in the
+package, rather than command functions.  This is handled behind the
+scenes by generating custom code that loads the package containing the
+keymap, and then re-executes your keypress after the first load, to
+reinterpret that keypress as a prefix key.
+
+   For example:
+
+     (use-package projectile
+       :bind-keymap
+       ("C-c p" . projectile-command-map)
+
+
+File: use-package.info,  Node: bind bind*,  Next: commands,  Prev: bind-keymap bind-keymap*,  Up: Keywords
+
+4.3 ‘:bind’, ‘:bind*’
+=====================
+
+Another common thing to do when loading a module is to bind a key to
+primary commands within that module:
+
+     (use-package ace-jump-mode
+       :bind ("C-." . ace-jump-mode))
+
+   This does two things: first, it creates an autoload for the
+‘ace-jump-mode’ command and defers loading of ‘ace-jump-mode’ until you
+actually use it.  Second, it binds the key ‘C-.’ to that command.  After
+loading, you can use ‘M-x describe-personal-keybindings’ to see all such
+keybindings you’ve set throughout your ‘.emacs’ file.
+
+   A more literal way to do the exact same thing is:
+
+     (use-package ace-jump-mode
+       :commands ace-jump-mode
+       :init
+       (bind-key "C-." 'ace-jump-mode))
+
+   When you use the ‘:commands’ keyword, it creates autoloads for those
+commands and defers loading of the module until they are used.  Since
+the ‘:init’ form is always run—even if ‘ace-jump-mode’ might not be on
+your system—remember to restrict ‘:init’ code to only what would succeed
+either way.
+
+   The ‘:bind’ keyword takes either a cons or a list of conses:
+
+     (use-package hi-lock
+       :bind (("M-o l" . highlight-lines-matching-regexp)
+     	 ("M-o r" . highlight-regexp)
+     	 ("M-o w" . highlight-phrase)))
+
+   The ‘:commands’ keyword likewise takes either a symbol or a list of
+symbols.
+
+   NOTE: Special keys like ‘tab’ or ‘F1’-‘Fn’ can be written in square
+brackets, i.e.  ‘[tab]’ instead of ‘"tab"’.  The syntax for the
+keybindings is similar to the "kbd" syntax: see the Emacs Manual
+(https://www.gnu.org/software/emacs/manual/html_node/emacs/Init-Rebinding.html)
+for more information.
+
+   Examples:
+
+     (use-package helm
+       :bind (("M-x" . helm-M-x)
+     	 ("M-<f5>" . helm-find-files)
+     	 ([f10] . helm-buffers-list)
+     	 ([S-f10] . helm-recentf)))
+
+* Menu:
+
+* Binding to local keymaps::
+
+
+File: use-package.info,  Node: Binding to local keymaps,  Up: bind bind*
+
+4.3.1 Binding to local keymaps
+------------------------------
+
+Slightly different from binding a key to a keymap, is binding a key
+*within* a local keymap that only exists after the package is loaded.
+‘use-package’ supports this with a ‘:map’ modifier, taking the local
+keymap to bind to:
+
+     (use-package helm
+       :bind (:map helm-command-map
+     	 ("C-c h" . helm-execute-persistent-action)))
+
+   The effect of this statement is to wait until ‘helm’ has loaded, and
+then to bind the key ‘C-c h’ to ‘helm-execute-persistent-action’ within
+Helm’s local keymap, ‘helm-mode-map’.
+
+   Multiple uses of ‘:map’ may be specified.  Any binding occurring
+before the first use of ‘:map’ are applied to the global keymap:
+
+     (use-package term
+       :bind (("C-c t" . term)
+     	 :map term-mode-map
+     	 ("M-p" . term-send-up)
+     	 ("M-n" . term-send-down)
+     	 :map term-raw-map
+     	 ("M-o" . other-window)
+     	 ("M-p" . term-send-up)
+     	 ("M-n" . term-send-down)))
+
+
+File: use-package.info,  Node: commands,  Next: preface init config,  Prev: bind bind*,  Up: Keywords
+
+4.4 ‘:commands’
+===============
+
+
+File: use-package.info,  Node: preface init config,  Next: custom,  Prev: commands,  Up: Keywords
+
+4.5 ‘:preface’, ‘:init’, ‘:config’
+==================================
+
+Here is the simplest ‘use-package’ declaration:
+
+     ;; This is only needed once, near the top of the file
+     (eval-when-compile
+       ;; Following line is not needed if use-package.el is in ~/.emacs.d
+       (add-to-list 'load-path "<path where use-package is installed>")
+       (require 'use-package))
+
+     (use-package foo)
+
+   This loads in the package ‘foo’, but only if ‘foo’ is available on
+your system.  If not, a warning is logged to the ‘*Messages*’ buffer.
+If it succeeds, a message about ‘"Loading foo"’ is logged, along with
+the time it took to load, if it took over 0.1 seconds.
+
+   Use the ‘:init’ keyword to execute code before a package is loaded.
+It accepts one or more forms, up until the next keyword:
+
+     (use-package foo
+       :init
+       (setq foo-variable t))
+
+   Similarly, ‘:config’ can be used to execute code after a package is
+loaded.  In cases where loading is done lazily (see more about
+autoloading below), this execution is deferred until after the autoload
+occurs:
+
+     (use-package foo
+       :init
+       (setq foo-variable t)
+       :config
+       (foo-mode 1))
+
+   As you might expect, you can use ‘:init’ and ‘:config’ together:
+
+     (use-package color-moccur
+       :commands (isearch-moccur isearch-all)
+       :bind (("M-s O" . moccur)
+     	 :map isearch-mode-map
+     	 ("M-o" . isearch-moccur)
+     	 ("M-O" . isearch-moccur-all))
+       :init
+       (setq isearch-lazy-highlight t)
+       :config
+       (use-package moccur-edit))
+
+   In this case, I want to autoload the commands ‘isearch-moccur’ and
+‘isearch-all’ from ‘color-moccur.el’, and bind keys both at the global
+level and within the ‘isearch-mode-map’ (see next section).  When the
+package is actually loaded (by using one of these commands),
+‘moccur-edit’ is also loaded, to allow editing of the ‘moccur’ buffer.
+
+
+File: use-package.info,  Node: custom,  Next: custom-face,  Prev: preface init config,  Up: Keywords
+
+4.6 ‘:custom’
+=============
+
+The ‘:custom’ keyword allows customization of package custom variables.
+
+     (use-package comint
+       :custom
+       (comint-buffer-maximum-size 20000 "Increase comint buffer size.")
+       (comint-prompt-read-only t "Make the prompt read only."))
+
+   The documentation string is not mandatory.
+
+
+File: use-package.info,  Node: custom-face,  Next: defer demand,  Prev: custom,  Up: Keywords
+
+4.7 ‘:custom-face’
+==================
+
+The ‘:custom-face’ keyword allows customization of package custom faces.
+
+     (use-package eruby-mode
+       :custom-face
+       (eruby-standard-face ((t (:slant italic)))))
+
+
+File: use-package.info,  Node: defer demand,  Next: defines functions,  Prev: custom-face,  Up: Keywords
+
+4.8 ‘:defer’, ‘:demand’
+=======================
+
+In almost all cases you don’t need to manually specify ‘:defer t’.  This
+is implied whenever ‘:bind’ or ‘:mode’ or ‘:interpreter’ is used.
+Typically, you only need to specify ‘:defer’ if you know for a fact that
+some other package will do something to cause your package to load at
+the appropriate time, and thus you would like to defer loading even
+though use-package isn’t creating any autoloads for you.
+
+   You can override package deferral with the ‘:demand’ keyword.  Thus,
+even if you use ‘:bind’, using ‘:demand’ will force loading to occur
+immediately and not establish an autoload for the bound key.
+
+
+File: use-package.info,  Node: defines functions,  Next: diminish delight,  Prev: defer demand,  Up: Keywords
+
+4.9 ‘:defines’, ‘:functions’
+============================
+
+Another feature of ‘use-package’ is that it always loads every file that
+it can when ‘.emacs’ is being byte-compiled.  This helps to silence
+spurious warnings about unknown variables and functions.
+
+   However, there are times when this is just not enough.  For those
+times, use the ‘:defines’ and ‘:functions’ keywords to introduce dummy
+variable and function declarations solely for the sake of the
+byte-compiler:
+
+     (use-package texinfo
+       :defines texinfo-section-list
+       :commands texinfo-mode
+       :init
+       (add-to-list 'auto-mode-alist '("\\.texi$" . texinfo-mode)))
+
+   If you need to silence a missing function warning, you can use
+‘:functions’:
+
+     (use-package ruby-mode
+       :mode "\\.rb\\'"
+       :interpreter "ruby"
+       :functions inf-ruby-keys
+       :config
+       (defun my-ruby-mode-hook ()
+         (require 'inf-ruby)
+         (inf-ruby-keys))
+
+       (add-hook 'ruby-mode-hook 'my-ruby-mode-hook))
+
+
+File: use-package.info,  Node: diminish delight,  Next: disabled,  Prev: defines functions,  Up: Keywords
+
+4.10 ‘:diminish’, ‘:delight’
+============================
+
+‘use-package’ also provides built-in support for the diminish and
+delight utilities—if you have them installed.  Their purpose is to
+remove or change minor mode strings in your mode-line.
+
+   diminish (https://github.com/myrjola/diminish.el) is invoked with the
+‘:diminish’ keyword, which is passed either a minor mode symbol, a cons
+of the symbol and its replacement string, or just a replacement string,
+in which case the minor mode symbol is guessed to be the package name
+with "-mode" appended at the end:
+
+     (use-package abbrev
+       :diminish abbrev-mode
+       :config
+       (if (file-exists-p abbrev-file-name)
+           (quietly-read-abbrev-file)))
+
+   delight (https://elpa.gnu.org/packages/delight.html) is invoked with
+the ‘:delight’ keyword, which is passed a minor mode symbol, a
+replacement string or quoted mode-line data
+(https://www.gnu.org/software/emacs/manual/html_node/elisp/Mode-Line-Data.html)
+(in which case the minor mode symbol is guessed to be the package name
+with "-mode" appended at the end), both of these, or several lists of
+both.  If no arguments are provided, the default mode name is hidden
+completely.
+
+     ;; Don't show anything for rainbow-mode.
+     (use-package rainbow-mode
+       :delight)
+
+     ;; Don't show anything for auto-revert-mode, which doesn't match
+     ;; its package name.
+     (use-package autorevert
+       :delight auto-revert-mode)
+
+     ;; Remove the mode name for projectile-mode, but show the project name.
+     (use-package projectile
+       :delight '(:eval (concat " " (projectile-project-name))))
+
+     ;; Completely hide visual-line-mode and change auto-fill-mode to " AF".
+     (use-package emacs
+       :delight
+       (auto-fill-function " AF")
+       (visual-line-mode))
+
+
+File: use-package.info,  Node: disabled,  Next: ensure pin,  Prev: diminish delight,  Up: Keywords
+
+4.11 ‘:disabled’
+================
+
+The ‘:disabled’ keyword can turn off a module you’re having difficulties
+with, or stop loading something you’re not using at the present time:
+
+     (use-package ess-site
+       :disabled
+       :commands R)
+
+   When byte-compiling your ‘.emacs’ file, disabled declarations are
+omitted from the output entirely, to accelerate startup times.
+
+
+File: use-package.info,  Node: ensure pin,  Next: hook,  Prev: disabled,  Up: Keywords
+
+4.12 ‘:ensure’, ‘:pin’
+======================
+
+You can use ‘use-package’ to load packages from ELPA with ‘package.el’.
+This is particularly useful if you share your ‘.emacs’ among several
+machines; the relevant packages are downloaded automatically once
+declared in your ‘.emacs’.  The ‘:ensure’ keyword causes the package(s)
+to be installed automatically if not already present on your system (set
+‘(setq use-package-always-ensure t)’ if you wish this behavior to be
+global for all packages):
+
+     (use-package magit
+       :ensure t)
+
+   If you need to install a different package from the one named by
+‘use-package’, you can specify it like this:
+
+     (use-package tex
+       :ensure auctex)
+
+   Lastly, when running on Emacs 24.4 or later, use-package can pin a
+package to a specific archive, allowing you to mix and match packages
+from different archives.  The primary use-case for this is preferring
+packages from the ‘melpa-stable’ and ‘gnu’ archives, but using specific
+packages from ‘melpa’ when you need to track newer versions than what is
+available in the ‘stable’ archives is also a valid use-case.
+
+   By default ‘package.el’ prefers ‘melpa’ over ‘melpa-stable’ due to
+the versioning ‘(> evil-20141208.623 evil-1.0.9)’, so even if you are
+tracking only a single package from ‘melpa’, you will need to tag all
+the non-‘melpa’ packages with the appropriate archive.  If this really
+annoys you, then you can set ‘use-package-always-pin’ to set a default.
+
+   If you want to manually keep a package updated and ignore upstream
+updates, you can pin it to ‘manual’, which as long as there is no
+repository by that name, will Just Work(tm).
+
+   ‘use-package’ throws an error if you try to pin a package to an
+archive that has not been configured using ‘package-archives’ (apart
+from the magic ‘manual’ archive mentioned above):
+
+     Archive 'foo' requested for package 'bar' is not available.
+
+   Example:
+
+     (use-package company
+       :ensure t
+       :pin melpa-stable)
+
+     (use-package evil
+       :ensure t)
+       ;; no :pin needed, as package.el will choose the version in melpa
+
+     (use-package adaptive-wrap
+       :ensure t
+       ;; as this package is available only in the gnu archive, this is
+       ;; technically not needed, but it helps to highlight where it
+       ;; comes from
+       :pin gnu)
+
+     (use-package org
+       :ensure t
+       ;; ignore org-mode from upstream and use a manually installed version
+       :pin manual)
+
+   *NOTE*: the ‘:pin’ argument has no effect on emacs versions < 24.4.
+
+
+File: use-package.info,  Node: hook,  Next: if when unless,  Prev: ensure pin,  Up: Keywords
+
+4.13 ‘:hook’
+============
+
+The ‘:hook’ keyword allows adding functions onto hooks, here only the
+basename of the hook is required.  Thus, all of the following are
+equivalent:
+
+     (use-package ace-jump-mode
+       :hook prog-mode)
+
+     (use-package ace-jump-mode
+       :hook (prog-mode . ace-jump-mode))
+
+     (use-package ace-jump-mode
+       :commands ace-jump-mode
+       :init
+       (add-hook 'prog-mode-hook #'ace-jump-mode))
+
+   And likewise, when multiple hooks should be applied, the following
+are also equivalent:
+
+     (use-package ace-jump-mode
+       :hook (prog-mode text-mode))
+
+     (use-package ace-jump-mode
+       :hook ((prog-mode text-mode) . ace-jump-mode))
+
+     (use-package ace-jump-mode
+       :hook ((prog-mode . ace-jump-mode)
+     	 (text-mode . ace-jump-mode)))
+
+     (use-package ace-jump-mode
+       :commands ace-jump-mode
+       :init
+       (add-hook 'prog-mode-hook #'ace-jump-mode)
+       (add-hook 'text-mode-hook #'ace-jump-mode))
+
+   The use of ‘:hook’, as with ‘:bind’, ‘:mode’, ‘:interpreter’, etc.,
+causes the functions being hooked to implicitly be read as ‘:commands’
+(meaning they will establish interactive ‘autoload’ definitions for that
+module, if not already defined as functions), and so ‘:defer t’ is also
+implied by ‘:hook’.
+
+
+File: use-package.info,  Node: if when unless,  Next: load-path,  Prev: hook,  Up: Keywords
+
+4.14 ‘:if’, ‘:when’, ‘:unless’
+==============================
+
+You can use the ‘:if’ keyword to predicate the loading and
+initialization of modules.
+
+   For example, I only want ‘edit-server’ running for my main, graphical
+Emacs, not for other Emacsen I may start at the command line:
+
+     (use-package edit-server
+       :if window-system
+       :init
+       (add-hook 'after-init-hook 'server-start t)
+       (add-hook 'after-init-hook 'edit-server-start t))
+
+   In another example, we can load things conditional on the operating
+system:
+
+     (use-package exec-path-from-shell
+       :if (memq window-system '(mac ns))
+       :ensure t
+       :config
+       (exec-path-from-shell-initialize))
+
+   Note that ‘:when’ is provided as an alias for ‘:if’, and ‘:unless
+foo’ means the same thing as ‘:if (not foo)’.
+
+
+File: use-package.info,  Node: load-path,  Next: mode interpreter,  Prev: if when unless,  Up: Keywords
+
+4.15 ‘:load-path’
+=================
+
+If your package needs a directory added to the ‘load-path’ in order to
+load, use ‘:load-path’.  This takes a symbol, a function, a string or a
+list of strings.  If the path is relative, it is expanded within
+‘user-emacs-directory’:
+
+     (use-package ess-site
+       :load-path "site-lisp/ess/lisp/"
+       :commands R)
+
+   Note that when using a symbol or a function to provide a dynamically
+generated list of paths, you must inform the byte-compiler of this
+definition so the value is available at byte-compilation time.  This is
+done by using the special form ‘eval-and-compile’ (as opposed to
+‘eval-when-compile’).  Further, this value is fixed at whatever was
+determined during compilation, to avoid looking up the same information
+again on each startup:
+
+     (eval-and-compile
+       (defun ess-site-load-path ()
+         (shell-command "find ~ -path ess/lisp")))
+
+     (use-package ess-site
+       :load-path (lambda () (list (ess-site-load-path)))
+       :commands R)
+
+
+File: use-package.info,  Node: mode interpreter,  Next: magic magic-fallback,  Prev: load-path,  Up: Keywords
+
+4.16 ‘:mode’, ‘:interpreter’
+============================
+
+Similar to ‘:bind’, you can use ‘:mode’ and ‘:interpreter’ to establish
+a deferred binding within the ‘auto-mode-alist’ and
+‘interpreter-mode-alist’ variables.  The specifier to either keyword can
+be a cons cell, a list of cons cells, or a string or regexp:
+
+     (use-package ruby-mode
+       :mode "\\.rb\\'"
+       :interpreter "ruby")
+
+     ;; The package is "python" but the mode is "python-mode":
+     (use-package python
+       :mode ("\\.py\\'" . python-mode)
+       :interpreter ("python" . python-mode))
+
+   If you aren’t using ‘:commands’, ‘:bind’, ‘:bind*’, ‘:bind-keymap’,
+‘:bind-keymap*’, ‘:mode’, or ‘:interpreter’ (all of which imply
+‘:defer’; see the docstring for ‘use-package’ for a brief description of
+each), you can still defer loading with the ‘:defer’ keyword:
+
+     (use-package ace-jump-mode
+       :defer t
+       :init
+       (autoload 'ace-jump-mode "ace-jump-mode" nil t)
+       (bind-key "C-." 'ace-jump-mode))
+
+   This does exactly the same thing as the following:
+
+     (use-package ace-jump-mode
+       :bind ("C-." . ace-jump-mode))
+
+
+File: use-package.info,  Node: magic magic-fallback,  Next: no-require,  Prev: mode interpreter,  Up: Keywords
+
+4.17 ‘:magic’, ‘:magic-fallback’
+================================
+
+Similar to ‘:mode‘ and ‘:interpreter‘, you can also use ‘:magic‘ and
+‘:magic-fallback‘ to cause certain function to be run if the beginning
+of a file matches a given regular expression.  The difference between
+the two is that ‘:magic-fallback‘ has a lower priority than ‘:mode‘.
+For example:
+
+   “‘ elisp (use-package pdf-tools :load-path "site-lisp/pdf-tools/lisp"
+:magic ("%PDF" .  pdf-view-mode) :config (pdf-tools-install)) “‘
+
+   This registers an autoloaded command for ‘pdf-view-mode‘, defers
+loading of ‘pdf-tools‘, and runs ‘pdf-view-mode‘ if the beginning of a
+buffer matches the string ‘"%PDF"‘.
+
+
+File: use-package.info,  Node: no-require,  Next: requires,  Prev: magic magic-fallback,  Up: Keywords
+
+4.18 ‘:no-require’
+==================
+
+Normally, ‘use-package’ will load each package at compile time before
+compiling the configuration, to ensure that any necessary symbols are in
+scope to satisfy the byte-compiler.  At times this can cause problems,
+since a package may have special loading requirements, and all that you
+want to use ‘use-package’ for is to add a configuration to the
+‘eval-after-load’ hook.  In such cases, use the ‘:no-require’ keyword:
+
+     (use-package foo
+       :no-require t
+       :config
+       (message "This is evaluated when `foo' is loaded"))
+
+
+File: use-package.info,  Node: requires,  Prev: no-require,  Up: Keywords
+
+4.19 ‘:requires’
+================
+
+While the ‘:after’ keyword delays loading until the dependencies are
+loaded, the somewhat simpler ‘:requires’ keyword simply never loads the
+package if the dependencies are not available at the time the
+‘use-package’ declaration is encountered.  By "available" in this
+context it means that ‘foo’ is available of ‘(featurep 'foo)’ evaulates
+to a non-nil value.  For example:
+
+     (use-package abbrev
+       :requires foo)
+
+   This is the same as:
+
+     (use-package abbrev
+       :if (featurep 'foo))
+
+   As a convenience, a list of such packages may be specified:
+
+     (use-package abbrev
+       :requires (foo bar baz))
+
+   For more complex logic, such as that supported by ‘:after’, simply
+use ‘:if’ and the appropriate Lisp expression.
+
+
+File: use-package.info,  Node: FAQ,  Next: Debugging Tools,  Prev: Keywords,  Up: Top
+
+Appendix A FAQ
+**************
+
+The next two nodes lists frequently asked questions.
+
+   Please also use the *note Debugging Tools::.
+
+* Menu:
+
+* FAQ - How to ...?::
+* FAQ - Issues and Errors::
+
+
+File: use-package.info,  Node: FAQ - How to ...?,  Next: FAQ - Issues and Errors,  Up: FAQ
+
+A.1 FAQ - How to ...?
+=====================
+
+* Menu:
+
+* This is a question::
+
+
+File: use-package.info,  Node: This is a question,  Up: FAQ - How to ...?
+
+A.1.1 This is a question
+------------------------
+
+This is an answer.
+
+
+File: use-package.info,  Node: FAQ - Issues and Errors,  Prev: FAQ - How to ...?,  Up: FAQ
+
+A.2 FAQ - Issues and Errors
+===========================
+
+* Menu:
+
+* This is an issues::
+
+
+File: use-package.info,  Node: This is an issues,  Up: FAQ - Issues and Errors
+
+A.2.1 This is an issues
+-----------------------
+
+This is a description.
+
+
+File: use-package.info,  Node: Debugging Tools,  Next: Command Index,  Prev: FAQ,  Up: Top
+
+B Debugging Tools
+*****************
+
+TODO
+
+   Please also see the *note FAQ::.
+
+
+File: use-package.info,  Node: Command Index,  Next: Function Index,  Prev: Debugging Tools,  Up: Top
+
+Appendix C Command Index
+************************
+
+
+File: use-package.info,  Node: Function Index,  Next: Variable Index,  Prev: Command Index,  Up: Top
+
+Appendix D Function Index
+*************************
+
+
+File: use-package.info,  Node: Variable Index,  Prev: Function Index,  Up: Top
+
+Appendix E Variable Index
+*************************
+
+
+
+Tag Table:
+Node: Top784
+Node: Introduction2838
+Node: Installation3325
+Node: Installing from an Elpa Archive3677
+Node: Installing from the Git Repository4792
+Node: Post-Installation Tasks6328
+Node: Getting Started7041
+Node: Keywords7213
+Node: after8151
+Node: bind-keymap bind-keymap*9683
+Node: bind bind*10736
+Node: Binding to local keymaps12776
+Node: commands13867
+Node: preface init config14009
+Node: custom16087
+Node: custom-face16527
+Node: defer demand16847
+Node: defines functions17659
+Node: diminish delight18804
+Node: disabled20747
+Node: ensure pin21242
+Node: hook23972
+Node: if when unless25390
+Node: load-path26336
+Node: mode interpreter27482
+Node: magic magic-fallback28793
+Node: no-require29638
+Node: requires30342
+Node: FAQ31229
+Node: FAQ - How to ...?31512
+Node: This is a question31684
+Node: FAQ - Issues and Errors31832
+Node: This is an issues32015
+Node: Debugging Tools32170
+Node: Command Index32344
+Node: Function Index32500
+Node: Variable Index32657
+
+End Tag Table
+
+
+Local Variables:
+coding: utf-8
+End:
diff --git a/configs/shared/emacs/.emacs.d/elpa/visual-fill-column-20180511.211/visual-fill-column-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/visual-fill-column-20180511.211/visual-fill-column-autoloads.el
new file mode 100644
index 0000000000..02f37a1a26
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/visual-fill-column-20180511.211/visual-fill-column-autoloads.el
@@ -0,0 +1,57 @@
+;;; visual-fill-column-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "visual-fill-column" "visual-fill-column.el"
+;;;;;;  (23377 61298 883879 641000))
+;;; Generated autoloads from visual-fill-column.el
+
+(autoload 'visual-fill-column-mode "visual-fill-column" "\
+Wrap lines according to `fill-column' in `visual-line-mode'.
+
+\(fn &optional ARG)" t nil)
+
+(defvar global-visual-fill-column-mode nil "\
+Non-nil if Global Visual-Fill-Column mode is enabled.
+See the `global-visual-fill-column-mode' command
+for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `global-visual-fill-column-mode'.")
+
+(custom-autoload 'global-visual-fill-column-mode "visual-fill-column" nil)
+
+(autoload 'global-visual-fill-column-mode "visual-fill-column" "\
+Toggle Visual-Fill-Column mode in all buffers.
+With prefix ARG, enable Global Visual-Fill-Column mode if ARG is positive;
+otherwise, disable it.  If called from Lisp, enable the mode if
+ARG is omitted or nil.
+
+Visual-Fill-Column mode is enabled in all buffers where
+`turn-on-visual-fill-column-mode' would do it.
+See `visual-fill-column-mode' for more information on Visual-Fill-Column mode.
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'visual-fill-column-split-window-sensibly "visual-fill-column" "\
+Split WINDOW sensibly, unsetting its margins first.
+This function unsets the window margins and calls
+`split-window-sensibly'.
+
+By default, `split-window-sensibly' does not split a window
+vertically if it has wide margins, even if there is enough space
+for a vertical split.  This function can be used as the value of
+`split-window-preferred-function' to enable vertically splitting
+windows with wide margins.
+
+\(fn &optional WINDOW)" nil nil)
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; visual-fill-column-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/visual-fill-column-20180511.211/visual-fill-column-pkg.el b/configs/shared/emacs/.emacs.d/elpa/visual-fill-column-20180511.211/visual-fill-column-pkg.el
new file mode 100644
index 0000000000..df537073dc
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/visual-fill-column-20180511.211/visual-fill-column-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "visual-fill-column" "20180511.211" "fill-column for visual-line-mode" '((emacs "24.3")))
diff --git a/configs/shared/emacs/.emacs.d/elpa/visual-fill-column-20180511.211/visual-fill-column.el b/configs/shared/emacs/.emacs.d/elpa/visual-fill-column-20180511.211/visual-fill-column.el
new file mode 100644
index 0000000000..aa1ff21e58
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/visual-fill-column-20180511.211/visual-fill-column.el
@@ -0,0 +1,205 @@
+;;; visual-fill-column.el --- fill-column for visual-line-mode  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2015-2018 Joost Kremers
+;; Copyright (C) 2016 Martin Rudalics
+;; All rights reserved.
+
+;; Author: Joost Kremers <joostkremers@fastmail.fm>
+;; Maintainer: Joost Kremers <joostkremers@fastmail.fm>
+;; Created: 2015
+;; Version: 1.9
+;; Package-Version: 20180511.211
+;; Package-Requires: ((emacs "24.3"))
+
+;; This file is NOT part of GNU Emacs.
+
+;; visual-fill-column 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.
+
+;; visual-fill-column 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:
+
+;; `visual-fill-column-mode' is a small Emacs minor mode that mimics the effect of `fill-column'
+;; in `visual-line-mode'.  Instead of wrapping lines at the window edge, which
+;; is the standard behaviour of `visual-line-mode', it wraps lines at
+;; `fill-column'.  If `fill-column' is too large for the window, the text is
+;; wrapped at the window edge.
+
+;;; Code:
+
+(defgroup visual-fill-column nil "Wrap lines according to `fill-column' in `visual-line-mode'."
+  :group 'wp
+  :prefix "visual-fill-column-")
+
+(defcustom visual-fill-column-width nil
+  "Width of the text area.
+By default, the global value of `fill-column' is used, but if
+this option is set to a value, it is used instead."
+  :group 'visual-fill-column
+  :type '(choice (const :tag "Use `fill-column'" :value nil)
+                 (integer :tag "Specify width" :value 70)))
+(make-variable-buffer-local 'visual-fill-column-width)
+(put 'visual-fill-column-width 'safe-local-variable 'numberp)
+
+(defcustom visual-fill-column-fringes-outside-margins t
+  "Put the fringes outside the margins."
+  :group 'visual-fill-column
+  :type '(choice (const :tag "Put fringes outside the margins" t)
+                 (const :tag "Keep the fringes inside the margins" nil)))
+(make-variable-buffer-local 'visual-fill-column-fringes-outside-margins)
+(put 'visual-fill-column-fringes-outside-margins 'safe-local-variable 'symbolp)
+
+(defcustom visual-fill-column-center-text nil
+  "If set, center the text area in the window."
+  :group 'visual-fill-column
+  :type '(choice (const :tag "Display text area at window margin" nil)
+                 (const :tag "Center text area" t)))
+(make-variable-buffer-local 'visual-fill-column-center-text)
+(put 'visual-fill-column-center-text 'safe-local-variable 'symbolp)
+
+;;;###autoload
+(define-minor-mode visual-fill-column-mode
+  "Wrap lines according to `fill-column' in `visual-line-mode'."
+  :init-value nil :lighter nil :global nil
+  (if visual-fill-column-mode
+      (visual-fill-column-mode--enable)
+    (visual-fill-column-mode--disable)))
+
+;;;###autoload
+(define-globalized-minor-mode global-visual-fill-column-mode visual-fill-column-mode turn-on-visual-fill-column-mode
+  :require 'visual-fill-column-mode
+  :group 'visual-fill-column)
+
+(defun turn-on-visual-fill-column-mode ()
+  "Turn on `visual-fill-column-mode'.
+Note that `visual-fill-column-mode' is only turned on in buffers
+in which Visual Line mode is active as well."
+  (when visual-line-mode
+    (visual-fill-column-mode 1)))
+
+(defun visual-fill-column-mode--enable ()
+  "Set up `visual-fill-column-mode' for the current buffer."
+  (add-hook 'window-configuration-change-hook #'visual-fill-column--adjust-window 'append 'local)
+  (visual-fill-column--adjust-window))
+
+(defun visual-fill-column-mode--disable ()
+  "Disable `visual-fill-column-mode' for the current buffer."
+  (remove-hook 'window-configuration-change-hook #'visual-fill-column--adjust-window 'local)
+  (set-window-fringes (get-buffer-window (current-buffer)) nil)
+  (set-window-margins (get-buffer-window (current-buffer)) nil))
+
+(defun visual-fill-column-split-window (&optional window size side pixelwise)
+  "Split WINDOW, unsetting its margins first.
+SIZE, SIDE, and PIXELWISE are passed on to `split-window'.  This
+function is for use in the window parameter `split-window'."
+  (let ((horizontal (memq side '(t left right)))
+	margins new)
+    (when horizontal
+      ;; Reset margins.
+      (setq margins (window-margins window))
+      (set-window-margins window nil))
+    ;; Now try to split the window.
+    (set-window-parameter window 'split-window nil)
+    (unwind-protect
+	(setq new (split-window window size side pixelwise))
+      (set-window-parameter window 'split-window #'visual-fill-column-split-window)
+      ;; Restore old margins if we failed.
+      (when (and horizontal (not new))
+	(set-window-margins window (car margins) (cdr margins))))))
+
+;;;###autoload
+(defun visual-fill-column-split-window-sensibly (&optional window)
+  "Split WINDOW sensibly, unsetting its margins first.
+This function unsets the window margins and calls
+`split-window-sensibly'.
+
+By default, `split-window-sensibly' does not split a window
+vertically if it has wide margins, even if there is enough space
+for a vertical split.  This function can be used as the value of
+`split-window-preferred-function' to enable vertically splitting
+windows with wide margins."
+  (let ((margins (window-margins window))
+        new)
+    ;; unset the margins and try to split the window
+    (when (buffer-local-value 'visual-fill-column-mode (window-buffer window))
+      (set-window-margins window nil))
+    (unwind-protect
+        (setq new (split-window-sensibly window))
+      (when (not new)
+        (set-window-margins window (car margins) (cdr margins))))))
+
+(defun visual-fill-column--adjust-window ()
+  "Adjust the window margins and fringes."
+  ;; Only run when we're really looking at a buffer that has v-f-c-mode enabled. See #22.
+  (when (buffer-local-value 'visual-fill-column-mode (window-buffer (selected-window)))
+    (set-window-fringes (get-buffer-window (current-buffer)) nil nil visual-fill-column-fringes-outside-margins)
+    (if (>= emacs-major-version 25)
+        (set-window-parameter (get-buffer-window (current-buffer)) 'split-window #'visual-fill-column-split-window))
+    (visual-fill-column--set-margins)))
+
+(defun visual-fill-column-adjust (&optional _inc)
+  "Adjust the window margins and fringes.
+This function is for use as advice to `text-scale-adjust'.  It
+calls `visual-fill-column--adjust-window', but only if
+`visual-fill-column' is active."
+  (if visual-fill-column-mode
+      (visual-fill-column--adjust-window)))
+
+(defun visual-fill-column--window-max-text-width (&optional window)
+  "Return the maximum possible text width of WINDOW.
+The maximum possible text width is the width of the current text
+area plus the margins, but excluding the fringes, scroll bar and
+right divider.  WINDOW defaults to the selected window.  The
+return value is scaled to account for `text-scale-mode-amount'
+and `text-scale-mode-step'."
+  (or window (setq window (get-buffer-window (current-buffer))))
+  (let* ((margins (window-margins window))
+         (buffer (window-buffer window))
+         (scale (if (and (boundp 'text-scale-mode-step)
+                         (boundp 'text-scale-mode-amount))
+                    (with-current-buffer buffer
+                      (expt text-scale-mode-step
+                            text-scale-mode-amount))
+                  1.0)))
+    (truncate (/ (+ (window-width window)
+                    (or (car margins) 0)
+                    (or (cdr margins) 0))
+                 (float scale)))))
+
+(defun visual-fill-column--set-margins ()
+  "Set window margins for the current window."
+  ;; calculate left & right margins
+  (let* ((window (get-buffer-window (current-buffer)))
+         (total-width (visual-fill-column--window-max-text-width window))
+         (width (or visual-fill-column-width
+                    fill-column))
+         (margins (if (< (- total-width width) 0) ; margins must be >= 0
+                      0
+                    (- total-width width)))
+         (left (if visual-fill-column-center-text
+                   (/ margins 2)
+                 0))
+         (right (if visual-fill-column-center-text
+                    (/ margins 2)
+                  margins)))
+
+    ;; put an explicitly R2L buffer on the right side of the window
+    (when (and (eq bidi-paragraph-direction 'right-to-left)
+               (= left 0))
+      (setq left right)
+      (setq right 0))
+
+    (set-window-margins window left right)))
+
+(provide 'visual-fill-column)
+
+;;; visual-fill-column.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/visual-fill-column-20180511.211/visual-fill-column.elc b/configs/shared/emacs/.emacs.d/elpa/visual-fill-column-20180511.211/visual-fill-column.elc
new file mode 100644
index 0000000000..0ac0f3761a
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/visual-fill-column-20180511.211/visual-fill-column.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/websocket-20180422.1716/websocket-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/websocket-20180422.1716/websocket-autoloads.el
new file mode 100644
index 0000000000..15bf251bd1
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/websocket-20180422.1716/websocket-autoloads.el
@@ -0,0 +1,15 @@
+;;; websocket-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil nil ("websocket.el") (23377 61596 702320 923000))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; websocket-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/websocket-20180422.1716/websocket-pkg.el b/configs/shared/emacs/.emacs.d/elpa/websocket-20180422.1716/websocket-pkg.el
new file mode 100644
index 0000000000..e4554a5e69
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/websocket-20180422.1716/websocket-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "websocket" "20180422.1716" "Emacs WebSocket client and server" '((cl-lib "0.5")))
diff --git a/configs/shared/emacs/.emacs.d/elpa/websocket-20180422.1716/websocket.el b/configs/shared/emacs/.emacs.d/elpa/websocket-20180422.1716/websocket.el
new file mode 100644
index 0000000000..31c80dbbcd
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/websocket-20180422.1716/websocket.el
@@ -0,0 +1,1070 @@
+;;; websocket.el --- Emacs WebSocket client and server  -*- lexical-binding:t -*-
+
+;; Copyright (c) 2013, 2016-2017  Free Software Foundation, Inc.
+
+;; Author: Andrew Hyatt <ahyatt@gmail.com>
+;; Keywords: Communication, Websocket, Server
+;; Package-Version: 20180422.1716
+;; Version: 1.9
+;; Package-Requires: ((cl-lib "0.5"))
+;;
+;; This program 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.
+;;
+;; This program 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:
+;; This implements RFC 6455, which can be found at
+;; http://tools.ietf.org/html/rfc6455.
+;;
+;; This library contains code to connect Emacs as a client to a
+;; websocket server, and for Emacs to act as a server for websocket
+;; connections.
+;;
+;; Websockets clients are created by calling `websocket-open', which
+;; returns a `websocket' struct.  Users of this library use the
+;; websocket struct, and can call methods `websocket-send-text', which
+;; sends text over the websocket, or `websocket-send', which sends a
+;; `websocket-frame' struct, enabling finer control of what is sent.
+;; A callback is passed to `websocket-open' that will retrieve
+;; websocket frames called from the websocket.  Websockets are
+;; eventually closed with `websocket-close'.
+;;
+;; Server functionality is similar.  A server is started with
+;; `websocket-server' called with a port and the callbacks to use,
+;; which returns a process.  The process can later be closed with
+;; `websocket-server-close'.  A `websocket' struct is also created
+;; for every connection, and is exposed through the callbacks.
+
+(require 'bindat)
+(require 'url-parse)
+(require 'url-cookie)
+(eval-when-compile (require 'cl-lib))
+
+;;; Code:
+
+(cl-defstruct (websocket
+            (:constructor nil)
+            (:constructor websocket-inner-create))
+  "A websocket structure.
+This follows the W3C Websocket API, except translated to elisp
+idioms.  The API is implemented in both the websocket struct and
+additional methods.  Due to how defstruct slots are accessed, all
+API methods are prefixed with \"websocket-\" and take a websocket
+as an argument, so the distrinction between the struct API and
+the additional helper APIs are not visible to the caller.
+
+A websocket struct is created with `websocket-open'.
+
+`ready-state' contains one of `connecting', `open', or
+`closed', depending on the state of the websocket.
+
+The W3C API \"bufferedAmount\" call is not currently implemented,
+since there is no elisp API to get the buffered amount from the
+subprocess.  There may, in fact, be output data buffered,
+however, when the `on-message' or `on-close' callbacks are
+called.
+
+`on-open', `on-message', `on-close', and `on-error' are described
+in `websocket-open'.
+
+The `negotiated-extensions' slot lists the extensions accepted by
+both the client and server, and `negotiated-protocols' does the
+same for the protocols."
+  ;; API
+  (ready-state 'connecting)
+  client-data
+  on-open
+  on-message
+  on-close
+  on-error
+  negotiated-protocols
+  negotiated-extensions
+  (server-p nil :read-only t)
+
+  ;; Other data - clients should not have to access this.
+  (url (cl-assert nil) :read-only t)
+  (protocols nil :read-only t)
+  (extensions nil :read-only t)
+  (conn (cl-assert nil) :read-only t)
+  ;; Only populated for servers, this is the server connection.
+  server-conn
+  accept-string
+  (inflight-input nil))
+
+(defvar websocket-version "1.9"
+  "Version numbers of this version of websocket.el.")
+
+(defvar websocket-debug nil
+  "Set to true to output debugging info to a per-websocket buffer.
+The buffer is ` *websocket URL debug*' where URL is the
+URL of the connection.")
+
+(defconst websocket-guid "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
+  "The websocket GUID as defined in RFC 6455.
+Do not change unless the RFC changes.")
+
+(defvar websocket-callback-debug-on-error nil
+  "If true, when an error happens in a client callback, invoke the debugger.
+Having this on can cause issues with missing frames if the debugger is
+exited by quitting instead of continuing, so it's best to have this set
+to nil unless it is especially needed.")
+
+(defmacro websocket-document-function (function docstring)
+  "Document FUNCTION with DOCSTRING.  Use this for defstruct accessor etc."
+  (declare (indent defun)
+           (doc-string 2))
+  `(put ',function 'function-documentation ,docstring))
+
+(websocket-document-function websocket-on-open
+  "Accessor for websocket on-open callback.
+See `websocket-open' for details.
+
+\(fn WEBSOCKET)")
+
+(websocket-document-function websocket-on-message
+  "Accessor for websocket on-message callback.
+See `websocket-open' for details.
+
+\(fn WEBSOCKET)")
+
+(websocket-document-function websocket-on-close
+  "Accessor for websocket on-close callback.
+See `websocket-open' for details.
+
+\(fn WEBSOCKET)")
+
+(websocket-document-function websocket-on-error
+  "Accessor for websocket on-error callback.
+See `websocket-open' for details.
+
+\(fn WEBSOCKET)")
+
+(defun websocket-genbytes (nbytes)
+  "Generate NBYTES random bytes."
+  (let ((s (make-string nbytes ?\s)))
+    (dotimes (i nbytes)
+      (aset s i (random 256)))
+    s))
+
+(defun websocket-try-callback (websocket-callback callback-type websocket
+                                                  &rest rest)
+  "Invoke function WEBSOCKET-CALLBACK with WEBSOCKET and REST args.
+If an error happens, it is handled according to
+`websocket-callback-debug-on-error'."
+  ;; This looks like it should be able to done more efficiently, but
+  ;; I'm not sure that's the case.  We can't do it as a macro, since
+  ;; we want it to change whenever websocket-callback-debug-on-error
+  ;; changes.
+  (let ((args rest)
+        (debug-on-error websocket-callback-debug-on-error))
+    (push websocket args)
+    (if websocket-callback-debug-on-error
+        (condition-case err
+            (apply (funcall websocket-callback websocket) args)
+          ((debug error) (funcall (websocket-on-error websocket)
+                                  websocket callback-type err)))
+      (condition-case err
+          (apply (funcall websocket-callback websocket) args)
+        (error (funcall (websocket-on-error websocket) websocket
+                        callback-type err))))))
+
+(defun websocket-genkey ()
+  "Generate a key suitable for the websocket handshake."
+  (base64-encode-string (websocket-genbytes 16)))
+
+(defun websocket-calculate-accept (key)
+  "Calculate the expect value of the accept header.
+This is based on the KEY from the Sec-WebSocket-Key header."
+  (base64-encode-string
+   (sha1 (concat key websocket-guid) nil nil t)))
+
+(defun websocket-get-bytes (s n)
+  "From string S, retrieve the value of N bytes.
+Return the value as an unsigned integer.  The value N must be a
+power of 2, up to 8.
+
+We support getting frames up to 536870911 bytes (2^29 - 1),
+approximately 537M long."
+  (if (= n 8)
+    (let* ((32-bit-parts
+            (bindat-get-field (bindat-unpack '((:val vec 2 u32)) s) :val))
+           (cval
+            (logior (lsh (aref 32-bit-parts 0) 32) (aref 32-bit-parts 1))))
+      (if (and (= (aref 32-bit-parts 0) 0)
+               (= (lsh (aref 32-bit-parts 1) -29) 0))
+          cval
+        (signal 'websocket-unparseable-frame
+                "Frame value found too large to parse!")))
+    ;; n is not 8
+    (bindat-get-field
+     (condition-case _
+         (bindat-unpack
+          `((:val
+             ,(cond ((= n 1) 'u8)
+                    ((= n 2) 'u16)
+                    ((= n 4) 'u32)
+                    ;; This is an error with the library,
+                    ;; not a user-facing, meaningful error.
+                    (t (error
+                        "websocket-get-bytes: Unknown N: %S" n)))))
+          s)
+       (args-out-of-range (signal 'websocket-unparseable-frame
+                                  (format "Frame unexpectedly shortly: %s" s))))
+     :val)))
+
+(defun websocket-to-bytes (val nbytes)
+  "Encode the integer VAL in NBYTES of data.
+NBYTES much be a power of 2, up to 8.
+
+This supports encoding values up to 536870911 bytes (2^29 - 1),
+approximately 537M long."
+  (when (and (< nbytes 8)
+             (> val (expt 2 (* 8 nbytes))))
+    ;; not a user-facing error, this must be caused from an error in
+    ;; this library
+    (error "websocket-to-bytes: Value %d could not be expressed in %d bytes"
+           val nbytes))
+  (if (= nbytes 8)
+      (progn
+        (let* ((hi-32bits (lsh val -32))
+               ;; This is just VAL on systems that don't have >= 32 bits.
+               (low-32bits (- val (lsh hi-32bits 32))))
+          (when (or (> hi-32bits 0) (> (lsh low-32bits -29) 0))
+            (signal 'websocket-frame-too-large val))
+          (bindat-pack `((:val vec 2 u32))
+                       `((:val . [,hi-32bits ,low-32bits])))))
+    (bindat-pack
+     `((:val ,(cond ((= nbytes 1) 'u8)
+                    ((= nbytes 2) 'u16)
+                    ((= nbytes 4) 'u32)
+                    ;; Library error, not system error
+                    (t (error "websocket-to-bytes: Unknown NBYTES: %S" nbytes)))))
+     `((:val . ,val)))))
+
+(defun websocket-get-opcode (s)
+  "Retrieve the opcode from first byte of string S."
+  (websocket-ensure-length s 1)
+  (let ((opcode (logand #xf (websocket-get-bytes s 1))))
+    (cond ((= opcode 0) 'continuation)
+          ((= opcode 1) 'text)
+          ((= opcode 2) 'binary)
+          ((= opcode 8) 'close)
+          ((= opcode 9) 'ping)
+          ((= opcode 10) 'pong))))
+
+(defun websocket-get-payload-len (s)
+  "Parse out the payload length from the string S.
+We start at position 0, and return a cons of the payload length and how
+many bytes were consumed from the string."
+  (websocket-ensure-length s 1)
+  (let* ((initial-val (logand 127 (websocket-get-bytes s 1))))
+    (cond ((= initial-val 127)
+           (websocket-ensure-length s 9)
+           (cons (websocket-get-bytes (substring s 1) 8) 9))
+          ((= initial-val 126)
+           (websocket-ensure-length s 3)
+           (cons (websocket-get-bytes (substring s 1) 2) 3))
+          (t (cons initial-val 1)))))
+
+(cl-defstruct websocket-frame opcode payload length completep)
+
+(defun websocket-frame-text (frame)
+  "Given FRAME, return the payload as a utf-8 encoded string."
+  (cl-assert (websocket-frame-p frame))
+  (decode-coding-string (websocket-frame-payload frame) 'utf-8))
+
+(defun websocket-mask (key data)
+  "Using string KEY, mask string DATA according to the RFC.
+This is used to both mask and unmask data."
+  ;; If we don't make the string unibyte here, a string of bytes that should be
+  ;; interpreted as a unibyte string will instead be interpreted as a multibyte
+  ;; string of the same length (for example, 6 multibyte chars for 你好 instead
+  ;; of the correct 6 unibyte chars, which would convert into 2 multibyte
+  ;; chars).
+  (apply
+   #'unibyte-string
+   (cl-loop for b across data
+            for i from 0 to (length data)
+            collect
+            (logxor (websocket-get-bytes (substring key (mod i 4)) 1) b))))
+
+(defun websocket-ensure-length (s n)
+  "Ensure the string S has at most N bytes.
+Otherwise we throw the error `websocket-incomplete-frame'."
+  (when (< (length s) n)
+    (throw 'websocket-incomplete-frame nil)))
+
+(defun websocket-encode-frame (frame should-mask)
+  "Encode the FRAME struct to the binary representation.
+We mask the frame or not, depending on SHOULD-MASK."
+  (let* ((opcode (websocket-frame-opcode frame))
+         (payload (websocket-frame-payload frame))
+         (fin (websocket-frame-completep frame))
+         (payloadp (and payload
+                        (memq opcode '(continuation ping pong text binary))))
+         (mask-key (when should-mask (websocket-genbytes 4))))
+    (apply #'unibyte-string
+           (let ((val (append (list
+                               (logior (pcase opcode
+                                         (`continuation 0)
+                                         (`text         1)
+                                         (`binary       2)
+                                         (`close        8)
+                                         (`ping         9)
+                                         (`pong         10))
+                                       (if fin 128 0)))
+                           (when payloadp
+                             (list
+                              (logior
+                               (if should-mask 128 0)
+                               (cond ((< (length payload) 126) (length payload))
+                                     ((< (length payload) 65536) 126)
+                                     (t 127)))))
+                           (when (and payloadp (>= (length payload) 126))
+                             (append (websocket-to-bytes
+                                      (length payload)
+                                      (cond ((< (length payload) 126) 1)
+                                            ((< (length payload) 65536) 2)
+                                            (t 8))) nil))
+                           (when (and payloadp should-mask)
+                             (append mask-key nil))
+                           (when payloadp
+                             (append (if should-mask (websocket-mask mask-key payload)
+                                       payload)
+                                     nil)))))
+             ;; We have to make sure the non-payload data is a full 32-bit frame
+             (if (= 1 (length val))
+                 (append val '(0)) val)))))
+
+(defun websocket-read-frame (s)
+  "Read from string S a `websocket-frame' struct with the contents.
+This only gets complete frames.  Partial frames need to wait until
+the frame finishes.  If the frame is not completed, return NIL."
+  (catch 'websocket-incomplete-frame
+    (websocket-ensure-length s 1)
+    (let* ((opcode (websocket-get-opcode s))
+           (fin (logand 128 (websocket-get-bytes s 1)))
+           (payloadp (memq opcode '(continuation text binary ping pong)))
+           (payload-len (when payloadp
+                          (websocket-get-payload-len (substring s 1))))
+           (maskp (and
+                   payloadp
+                   (= 128 (logand 128 (websocket-get-bytes (substring s 1) 1)))))
+           (payload-start (when payloadp (+ (if maskp 5 1) (cdr payload-len))))
+           (payload-end (when payloadp (+ payload-start (car payload-len))))
+           (unmasked-payload (when payloadp
+                               (websocket-ensure-length s payload-end)
+                               (substring s payload-start payload-end))))
+      (make-websocket-frame
+       :opcode opcode
+       :payload
+       (if maskp
+           (let ((masking-key (substring s (+ 1 (cdr payload-len))
+                                         (+ 5 (cdr payload-len)))))
+             (websocket-mask masking-key unmasked-payload))
+         unmasked-payload)
+       :length (if payloadp payload-end 1)
+       :completep (> fin 0)))))
+
+(defun websocket-format-error (err)
+  "Format an error message like command level does.
+ERR should be a cons of error symbol and error data."
+
+  ;; Formatting code adapted from `edebug-report-error'
+  (concat (or (get (car err) 'error-message)
+              (format "peculiar error (%s)" (car err)))
+          (when (cdr err)
+            (format ": %s"
+                    (mapconcat #'prin1-to-string
+                               (cdr err) ", ")))))
+
+(defun websocket-default-error-handler (_websocket type err)
+  "The default error handler used to handle errors in callbacks."
+  (display-warning 'websocket
+                   (format "in callback `%S': %s"
+                           type
+                           (websocket-format-error err))
+                   :error))
+
+;; Error symbols in use by the library
+(put 'websocket-unsupported-protocol 'error-conditions
+     '(error websocket-error websocket-unsupported-protocol))
+(put 'websocket-unsupported-protocol 'error-message "Unsupported websocket protocol")
+(put 'websocket-wss-needs-emacs-24 'error-conditions
+     '(error websocket-error websocket-unsupported-protocol
+             websocket-wss-needs-emacs-24))
+(put 'websocket-wss-needs-emacs-24 'error-message
+     "wss protocol is not supported for Emacs before version 24.")
+(put 'websocket-received-error-http-response 'error-conditions
+     '(error websocket-error websocket-received-error-http-response))
+(put 'websocket-received-error-http-response 'error-message
+     "Error response received from websocket server")
+(put 'websocket-invalid-header 'error-conditions
+     '(error websocket-error websocket-invalid-header))
+(put 'websocket-invalid-header 'error-message
+     "Invalid HTTP header sent")
+(put 'websocket-illegal-frame 'error-conditions
+     '(error websocket-error websocket-illegal-frame))
+(put 'websocket-illegal-frame 'error-message
+     "Cannot send illegal frame to websocket")
+(put 'websocket-closed 'error-conditions
+     '(error websocket-error websocket-closed))
+(put 'websocket-closed 'error-message
+     "Cannot send message to a closed websocket")
+(put 'websocket-unparseable-frame 'error-conditions
+     '(error websocket-error websocket-unparseable-frame))
+(put 'websocket-unparseable-frame 'error-message
+     "Received an unparseable frame")
+(put 'websocket-frame-too-large 'error-conditions
+     '(error websocket-error websocket-frame-too-large))
+(put 'websocket-frame-too-large 'error-message
+     "The frame being sent is too large for this emacs to handle")
+
+(defun websocket-intersect (a b)
+  "Simple list intersection, should function like Common Lisp's `intersection'."
+  (let ((result))
+    (dolist (elem a (nreverse result))
+      (when (member elem b)
+        (push elem result)))))
+
+(defun websocket-get-debug-buffer-create (websocket)
+  "Get or create the buffer corresponding to WEBSOCKET."
+  (let ((buf (get-buffer-create (format "*websocket %s debug*"
+                                    (websocket-url websocket)))))
+    (when (= 0 (buffer-size buf))
+      (buffer-disable-undo buf))
+    buf))
+
+(defun websocket-debug (websocket msg &rest args)
+  "In the WEBSOCKET's debug buffer, send MSG, with format ARGS."
+  (when websocket-debug
+    (let ((buf (websocket-get-debug-buffer-create websocket)))
+      (save-excursion
+        (with-current-buffer buf
+          (goto-char (point-max))
+          (insert "[WS] ")
+          (insert (apply #'format (append (list msg) args)))
+          (insert "\n"))))))
+
+(defun websocket-verify-response-code (output)
+  "Verify that OUTPUT contains a valid HTTP response code.
+The only acceptable one to websocket is responce code 101.
+A t value will be returned on success, and an error thrown
+if not."
+  (unless (string-match "^HTTP/1.1 \\([[:digit:]]+\\)" output)
+    (signal 'websocket-invalid-header "Invalid HTTP status line"))
+  (unless (equal "101" (match-string 1 output))
+    (signal 'websocket-received-error-http-response
+	    (string-to-number (match-string 1 output))))
+  t)
+
+(defun websocket-parse-repeated-field (output field)
+  "From header-containing OUTPUT, parse out the list from a
+possibly repeated field."
+  (let ((pos 0)
+        (extensions))
+    (while (and pos
+                (string-match (format "\r\n%s: \\(.*\\)\r\n" field)
+                              output pos))
+      (when (setq pos (match-end 1))
+        (setq extensions (append extensions (split-string
+                                             (match-string 1 output) ", ?")))))
+    extensions))
+
+(defun websocket-process-frame (websocket frame)
+  "Using the WEBSOCKET's filter and connection, process the FRAME.
+This returns a lambda that should be executed when all frames have
+been processed.  If the frame has a payload, the lambda has the frame
+passed to the filter slot of WEBSOCKET.  If the frame is a ping,
+the lambda has a reply with a pong.  If the frame is a close, the lambda
+has connection termination."
+  (let ((opcode (websocket-frame-opcode frame)))
+    (cond ((memq opcode '(continuation text binary))
+           (lambda () (websocket-try-callback 'websocket-on-message 'on-message
+                                         websocket frame)))
+          ((eq opcode 'ping)
+           (lambda () (websocket-send websocket
+                                 (make-websocket-frame
+                                  :opcode 'pong
+                                  :payload (websocket-frame-payload frame)
+                                  :completep t))))
+          ((eq opcode 'close)
+           (lambda () (delete-process (websocket-conn websocket))))
+          (t (lambda ())))))
+
+(defun websocket-process-input-on-open-ws (websocket text)
+  "This handles input processing for both the client and server filters."
+  (let ((current-frame)
+        (processing-queue)
+        (start-point 0))
+    (while (setq current-frame (websocket-read-frame
+                                (substring text start-point)))
+      (push (websocket-process-frame websocket current-frame) processing-queue)
+      (cl-incf start-point (websocket-frame-length current-frame)))
+    (when (> (length text) start-point)
+      (setf (websocket-inflight-input websocket)
+            (substring text start-point)))
+    (dolist (to-process (nreverse processing-queue))
+      (funcall to-process))))
+
+(defun websocket-send-text (websocket text)
+  "To the WEBSOCKET, send TEXT as a complete frame."
+  (websocket-send
+   websocket
+   (make-websocket-frame :opcode 'text
+                         :payload (encode-coding-string
+                                   text 'raw-text)
+                         :completep t)))
+
+(defun websocket-check (frame)
+  "Check FRAME for correctness, returning true if correct."
+  (or
+   ;; Text, binary, and continuation frames need payloads
+   (and (memq (websocket-frame-opcode frame) '(text binary continuation))
+        (websocket-frame-payload frame))
+   ;; Pings and pongs may optionally have them
+   (memq (websocket-frame-opcode frame) '(ping pong))
+   ;; And close shouldn't have any payload, and should always be complete.
+   (and (eq (websocket-frame-opcode frame) 'close)
+        (not (websocket-frame-payload frame))
+        (websocket-frame-completep frame))))
+
+(defun websocket-send (websocket frame)
+  "To the WEBSOCKET server, send the FRAME.
+This will raise an error if the frame is illegal.
+
+The error signaled may be of type `websocket-illegal-frame' if
+the frame is malformed in some way, also having the condition
+type of `websocket-error'.  The data associated with the signal
+is the frame being sent.
+
+If the websocket is closed a signal `websocket-closed' is sent,
+also with `websocket-error' condition.  The data in the signal is
+also the frame.
+
+The frame may be too large for this buid of Emacs, in which case
+`websocket-frame-too-large' is returned, with the data of the
+size of the frame which was too large to process.  This also has
+the `websocket-error' condition."
+  (unless (websocket-check frame)
+    (signal 'websocket-illegal-frame frame))
+  (websocket-debug websocket "Sending frame, opcode: %s payload: %s"
+                   (websocket-frame-opcode frame)
+                   (websocket-frame-payload frame))
+  (websocket-ensure-connected websocket)
+  (unless (websocket-openp websocket)
+    (signal 'websocket-closed frame))
+  (process-send-string (websocket-conn websocket)
+                       ;; We mask only when we're a client, following the spec.
+                       (websocket-encode-frame frame (not (websocket-server-p websocket)))))
+
+(defun websocket-openp (websocket)
+  ;; FIXME: "open and either connecting or open"?  I don't understand.  --Stef
+  "Check WEBSOCKET and return non-nil if it is open, and either
+connecting or open."
+  (and websocket
+       (not (eq 'close (websocket-ready-state websocket)))
+       (member (process-status (websocket-conn websocket)) '(open run))))
+
+(defun websocket-close (websocket)
+  "Close WEBSOCKET and erase all the old websocket data."
+  (websocket-debug websocket "Closing websocket")
+  (websocket-try-callback 'websocket-on-close 'on-close websocket)
+  (when (websocket-openp websocket)
+    (websocket-send websocket
+                    (make-websocket-frame :opcode 'close
+                                          :completep t))
+    (setf (websocket-ready-state websocket) 'closed))
+  (delete-process (websocket-conn websocket)))
+
+(defun websocket-ensure-connected (websocket)
+  "If the WEBSOCKET connection is closed, open it."
+  (unless (and (websocket-conn websocket)
+               (cl-ecase (process-status (websocket-conn websocket))
+                 ((run open listen) t)
+                 ((stop exit signal closed connect failed nil) nil)))
+    (websocket-close websocket)
+    (websocket-open (websocket-url websocket)
+                    :protocols (websocket-protocols websocket)
+                    :extensions (websocket-extensions websocket)
+                    :on-open (websocket-on-open websocket)
+                    :on-message (websocket-on-message websocket)
+                    :on-close (websocket-on-close websocket)
+                    :on-error (websocket-on-error websocket))))
+
+;;;;;;;;;;;;;;;;;;;;;;
+;; Websocket client ;;
+;;;;;;;;;;;;;;;;;;;;;;
+
+(cl-defun websocket-open (url &key protocols extensions (on-open 'identity)
+                            (on-message (lambda (_w _f))) (on-close 'identity)
+                            (on-error 'websocket-default-error-handler)
+                            (nowait nil) (custom-header-alist nil))
+  "Open a websocket connection to URL, returning the `websocket' struct.
+The PROTOCOL argument is optional, and setting it will declare to
+the server that this client supports the protocols in the list
+given.  We will require that the server also has to support that
+protocols.
+
+Similar logic applies to EXTENSIONS, which is a list of conses,
+the car of which is a string naming the extension, and the cdr of
+which is the list of parameter strings to use for that extension.
+The parameter strings are of the form \"key=value\" or \"value\".
+EXTENSIONS can be NIL if none are in use.  An example value would
+be (\"deflate-stream\" . (\"mux\" \"max-channels=4\")).
+
+Cookies that are set via `url-cookie-store' will be used during
+communication with the server, and cookies received from the
+server will be stored in the same cookie storage that the
+`url-cookie' package uses.
+
+Optionally you can specify
+ON-OPEN, ON-MESSAGE and ON-CLOSE callbacks as well.
+
+The ON-OPEN callback is called after the connection is
+established with the websocket as the only argument.  The return
+value is unused.
+
+The ON-MESSAGE callback is called after receiving a frame, and is
+called with the websocket as the first argument and
+`websocket-frame' struct as the second.  The return value is
+unused.
+
+The ON-CLOSE callback is called after the connection is closed, or
+failed to open.  It is called with the websocket as the only
+argument, and the return value is unused.
+
+The ON-ERROR callback is called when any of the other callbacks
+have an error.  It takes the websocket as the first argument, and
+a symbol as the second argument either `on-open', `on-message',
+or `on-close', and the error as the third argument. Do NOT
+rethrow the error, or else you may miss some websocket messages.
+You similarly must not generate any other errors in this method.
+If you want to debug errors, set
+`websocket-callback-debug-on-error' to t, but this also can be
+dangerous is the debugger is quit out of.  If not specified,
+`websocket-default-error-handler' is used.
+
+For each of these event handlers, the client code can store
+arbitrary data in the `client-data' slot in the returned
+websocket.
+
+The following errors might be thrown in this method or in
+websocket processing, all of them having the error-condition
+`websocket-error' in addition to their own symbol:
+
+`websocket-unsupported-protocol': Data in the error signal is the
+protocol that is unsupported.  For example, giving a URL starting
+with http by mistake raises this error.
+
+`websocket-wss-needs-emacs-24': Trying to connect wss protocol
+using Emacs < 24 raises this error.  You can catch this error
+also by `websocket-unsupported-protocol'.
+
+`websocket-received-error-http-response': Data in the error
+signal is the integer error number.
+
+`websocket-invalid-header': Data in the error is a string
+describing the invalid header received from the server.
+
+`websocket-unparseable-frame': Data in the error is a string
+describing the problem with the frame.
+
+`nowait': If NOWAIT is true, return without waiting for the
+connection to complete.
+
+`custom-headers-alist': An alist of custom headers to pass to the
+server. The car is the header name, the cdr is the header value.
+These are different from the extensions because it is not related
+to the websocket protocol.
+"
+  (let* ((name (format "websocket to %s" url))
+         (url-struct (url-generic-parse-url url))
+         (key (websocket-genkey))
+         (coding-system-for-read 'binary)
+         (coding-system-for-write 'binary)
+         (conn (if (member (url-type url-struct) '("ws" "wss"))
+                   (let* ((type (if (equal (url-type url-struct) "ws")
+                                    'plain 'tls))
+                          (port (if (= 0 (url-port url-struct))
+                                    (if (eq type 'tls) 443 80)
+                                  (url-port url-struct)))
+                          (host (url-host url-struct)))
+                       (if (eq type 'plain)
+                           (make-network-process :name name :buffer nil :host host
+                                                 :service port :nowait nowait)
+                         (condition-case-unless-debug nil
+                             (open-network-stream name nil host port :type type :nowait nowait)
+                           (wrong-number-of-arguments
+                            (signal 'websocket-wss-needs-emacs-24 "wss")))))
+                 (signal 'websocket-unsupported-protocol (url-type url-struct))))
+         (websocket (websocket-inner-create
+                     :conn conn
+                     :url url
+                     :on-open on-open
+                     :on-message on-message
+                     :on-close on-close
+                     :on-error on-error
+                     :protocols protocols
+                     :extensions (mapcar 'car extensions)
+                     :accept-string
+                     (websocket-calculate-accept key))))
+    (unless conn (error "Could not establish the websocket connection to %s" url))
+    (process-put conn :websocket websocket)
+    (set-process-filter conn
+                        (lambda (process output)
+                          (let ((websocket (process-get process :websocket)))
+                            (websocket-outer-filter websocket output))))
+    (set-process-sentinel
+     conn
+     (websocket-sentinel url conn key protocols extensions custom-header-alist nowait))
+    (set-process-query-on-exit-flag conn nil)
+    (websocket-ensure-handshake url conn key protocols extensions custom-header-alist)
+    websocket))
+
+(defun websocket-sentinel (url conn key protocols extensions custom-header-alist nowait)
+  #'(lambda (process change)
+      (let ((websocket (process-get process :websocket)))
+        (websocket-debug websocket "State change to %s" change)
+        (let ((status (process-status process)))
+          (when (and nowait (eq status 'open))
+            (websocket-ensure-handshake url conn key protocols extensions custom-header-alist))
+
+          (when (and (member status '(closed failed exit signal))
+                     (not (eq 'closed (websocket-ready-state websocket))))
+            (websocket-try-callback 'websocket-on-close 'on-close websocket))))))
+
+(defun websocket-ensure-handshake (url conn key protocols extensions custom-header-alist)
+  (let ((url-struct (url-generic-parse-url url))
+        (websocket (process-get conn :websocket)))
+    (when (and (eq 'connecting (websocket-ready-state websocket))
+               (eq 'open (process-status conn)))
+      (process-send-string conn
+                           (format "GET %s HTTP/1.1\r\n"
+                                   (let ((path (url-filename url-struct)))
+                                     (if (> (length path) 0) path "/"))))
+      (websocket-debug websocket "Sending handshake, key: %s, acceptance: %s"
+                       key (websocket-accept-string websocket))
+      (process-send-string conn
+                           (websocket-create-headers
+                            url key protocols extensions custom-header-alist)))))
+
+(defun websocket-process-headers (url headers)
+  "On opening URL, process the HEADERS sent from the server."
+  (when (string-match "Set-Cookie: \(.*\)\r\n" headers)
+    ;; The url-current-object is assumed to be set by
+    ;; url-cookie-handle-set-cookie.
+    (let ((url-current-object (url-generic-parse-url url)))
+      (url-cookie-handle-set-cookie (match-string 1 headers)))))
+
+(defun websocket-outer-filter (websocket output)
+  "Filter the WEBSOCKET server's OUTPUT.
+This will parse headers and process frames repeatedly until there
+is no more output or the connection closes.  If the websocket
+connection is invalid, the connection will be closed."
+  (websocket-debug websocket "Received: %s" output)
+  (let ((start-point)
+        (text (concat (websocket-inflight-input websocket) output))
+        (header-end-pos))
+    (setf (websocket-inflight-input websocket) nil)
+    ;; If we've received the complete header, check to see if we've
+    ;; received the desired handshake.
+    (when (and (eq 'connecting (websocket-ready-state websocket)))
+      (if (and (setq header-end-pos (string-match "\r\n\r\n" text))
+               (setq start-point (+ 4 header-end-pos)))
+          (progn
+            (condition-case err
+                (progn
+                  (websocket-verify-response-code text)
+                  (websocket-verify-headers websocket text)
+                  (websocket-process-headers (websocket-url websocket) text))
+              (error
+               (websocket-close websocket)
+               (signal (car err) (cdr err))))
+            (setf (websocket-ready-state websocket) 'open)
+            (websocket-try-callback 'websocket-on-open 'on-open websocket))
+        (setf (websocket-inflight-input websocket) text)))
+    (when (eq 'open (websocket-ready-state websocket))
+      (websocket-process-input-on-open-ws
+       websocket (substring text (or start-point 0))))))
+
+(defun websocket-verify-headers (websocket output)
+  "Based on WEBSOCKET's data, ensure the headers in OUTPUT are valid.
+The output is assumed to have complete headers.  This function
+will either return t or call `error'.  This has the side-effect
+of populating the list of server extensions to WEBSOCKET."
+  (let ((accept-string
+         (concat "Sec-WebSocket-Accept: " (websocket-accept-string websocket))))
+    (websocket-debug websocket "Checking for accept header: %s" accept-string)
+    (unless (string-match (regexp-quote accept-string) output)
+      (signal 'websocket-invalid-header
+              "Incorrect handshake from websocket: is this really a websocket connection?")))
+  (let ((case-fold-search t))
+    (websocket-debug websocket "Checking for upgrade header")
+    (unless (string-match "\r\nUpgrade: websocket\r\n" output)
+      (signal 'websocket-invalid-header
+              "No 'Upgrade: websocket' header found"))
+    (websocket-debug websocket "Checking for connection header")
+    (unless (string-match "\r\nConnection: upgrade\r\n" output)
+      (signal 'websocket-invalid-header
+              "No 'Connection: upgrade' header found"))
+    (when (websocket-protocols websocket)
+      (dolist (protocol (websocket-protocols websocket))
+        (websocket-debug websocket "Checking for protocol match: %s"
+                         protocol)
+        (let ((protocols
+               (if (string-match (format "\r\nSec-Websocket-Protocol: %s\r\n"
+                                         protocol)
+                                 output)
+                   (list protocol)
+                 (signal 'websocket-invalid-header
+                         "Incorrect or missing protocol returned by the server."))))
+          (setf (websocket-negotiated-protocols websocket) protocols))))
+    (let* ((extensions (websocket-parse-repeated-field
+                        output
+                        "Sec-WebSocket-Extensions"))
+           (extra-extensions))
+      (dolist (ext extensions)
+        (let ((x (cl-first (split-string ext "; ?"))))
+          (unless (or (member x (websocket-extensions websocket))
+                      (member x extra-extensions))
+            (push x extra-extensions))))
+      (when extra-extensions
+        (signal 'websocket-invalid-header
+                (format "Non-requested extensions returned by server: %S"
+                        extra-extensions)))
+      (setf (websocket-negotiated-extensions websocket) extensions)))
+  t)
+
+;;;;;;;;;;;;;;;;;;;;;;
+;; Websocket server ;;
+;;;;;;;;;;;;;;;;;;;;;;
+
+(defvar websocket-server-websockets nil
+  "A list of current websockets live on any server.")
+
+(cl-defun websocket-server (port &rest plist)
+  "Open a websocket server on PORT.
+If the plist contains a `:host' HOST pair, this value will be
+used to configure the addresses the socket listens on. The symbol
+`local' specifies the local host. If unspecified or nil, the
+socket will listen on all addresses.
+
+This also takes a plist of callbacks: `:on-open', `:on-message',
+`:on-close' and `:on-error', which operate exactly as documented
+in the websocket client function `websocket-open'.  Returns the
+connection, which should be kept in order to pass to
+`websocket-server-close'."
+  (let* ((conn (make-network-process
+                :name (format "websocket server on port %s" port)
+                :server t
+                :family 'ipv4
+                :noquery t
+                :filter 'websocket-server-filter
+                :log 'websocket-server-accept
+                :filter-multibyte nil
+                :plist plist
+                :host (plist-get plist :host)
+                :service port)))
+    conn))
+
+(defun websocket-server-close (conn)
+  "Closes the websocket, as well as all open websockets for this server."
+  (let ((to-delete))
+    (dolist (ws websocket-server-websockets)
+      (when (eq (websocket-server-conn ws) conn)
+        (if (eq (websocket-ready-state ws) 'closed)
+            (unless (member ws to-delete)
+              (push ws to-delete))
+          (websocket-close ws))))
+    (dolist (ws to-delete)
+      (setq websocket-server-websockets (remove ws websocket-server-websockets))))
+  (delete-process conn))
+
+(defun websocket-server-accept (server client _message)
+  "Accept a new websocket connection from a client."
+  (let ((ws (websocket-inner-create
+             :server-conn server
+             :conn client
+             :url client
+             :server-p t
+             :on-open (or (process-get server :on-open) 'identity)
+             :on-message (or (process-get server :on-message) (lambda (_ws _frame)))
+             :on-close (let ((user-method
+                              (or (process-get server :on-close) 'identity)))
+                         (lambda (ws)
+                           (setq websocket-server-websockets
+                                 (remove ws websocket-server-websockets))
+                           (funcall user-method ws)))
+             :on-error (or (process-get server :on-error)
+                           'websocket-default-error-handler)
+             :protocols (process-get server :protocol)
+             :extensions (mapcar 'car (process-get server :extensions)))))
+    (unless (member ws websocket-server-websockets)
+      (push ws websocket-server-websockets))
+    (process-put client :websocket ws)
+    (set-process-coding-system client 'binary 'binary)
+    (set-process-sentinel client
+     (lambda (process change)
+       (let ((websocket (process-get process :websocket)))
+         (websocket-debug websocket "State change to %s" change)
+         (when (and
+                (member (process-status process) '(closed failed exit signal))
+                (not (eq 'closed (websocket-ready-state websocket))))
+           (websocket-try-callback 'websocket-on-close 'on-close websocket)))))))
+
+(defun websocket-create-headers (url key protocol extensions custom-headers-alist)
+  "Create connections headers for the given URL, KEY, PROTOCOL, and EXTENSIONS.
+Additionally, the CUSTOM-HEADERS-ALIST is passed from the client.
+All these parameters are defined as in `websocket-open'."
+  (let* ((parsed-url (url-generic-parse-url url))
+         (host-port (if (url-port-if-non-default parsed-url)
+                        (format "%s:%s" (url-host parsed-url) (url-port parsed-url))
+                      (url-host parsed-url)))
+         (cookie-header (url-cookie-generate-header-lines
+                         host-port (car (url-path-and-query parsed-url))
+                         (equal (url-type parsed-url) "wss"))))
+    (format (concat "Host: %s\r\n"
+                    "Upgrade: websocket\r\n"
+                    "Connection: Upgrade\r\n"
+                    "Sec-WebSocket-Key: %s\r\n"
+                    "Sec-WebSocket-Version: 13\r\n"
+                    (when protocol
+                      (concat
+                       (mapconcat
+                        (lambda (protocol)
+                          (format "Sec-WebSocket-Protocol: %s" protocol))
+                        protocol "\r\n")
+                       "\r\n"))
+                    (when extensions
+                      (format "Sec-WebSocket-Extensions: %s\r\n"
+                              (mapconcat
+                               (lambda (ext)
+                                 (concat
+                                  (car ext)
+                                  (when (cdr ext) "; ")
+                                  (when (cdr ext)
+                                    (mapconcat 'identity (cdr ext) "; "))))
+                               extensions ", ")))
+                    (when cookie-header cookie-header)
+                    (concat (mapconcat (lambda (cons) (format "%s: %s" (car cons) (cdr cons)))
+                                       custom-headers-alist "\r\n")
+                            (when custom-headers-alist "\r\n"))
+                    "\r\n")
+            host-port
+            key
+            protocol)))
+
+(defun websocket-get-server-response (websocket client-protocols client-extensions)
+  "Get the websocket response from client WEBSOCKET."
+  (let ((separator "\r\n"))
+      (concat "HTTP/1.1 101 Switching Protocols" separator
+              "Upgrade: websocket" separator
+              "Connection: Upgrade" separator
+              "Sec-WebSocket-Accept: "
+              (websocket-accept-string websocket) separator
+              (let ((protocols
+                         (websocket-intersect client-protocols
+                                              (websocket-protocols websocket))))
+                    (when protocols
+                      (concat
+                       (mapconcat
+                        (lambda (protocol) (format "Sec-WebSocket-Protocol: %s"
+                                              protocol)) protocols separator)
+                       separator)))
+              (let ((extensions (websocket-intersect
+                                   client-extensions
+                                   (websocket-extensions websocket))))
+                  (when extensions
+                    (concat
+                     (mapconcat
+                      (lambda (extension) (format "Sec-Websocket-Extensions: %s"
+                                             extension)) extensions separator)
+                     separator)))
+              separator)))
+
+(defun websocket-server-filter (process output)
+  "This acts on all OUTPUT from websocket clients PROCESS."
+  (let* ((ws (process-get process :websocket))
+         (text (concat (websocket-inflight-input ws) output)))
+    (setf (websocket-inflight-input ws) nil)
+    (cond ((eq (websocket-ready-state ws) 'connecting)
+           ;; check for connection string
+           (let ((end-of-header-pos
+                  (let ((pos (string-match "\r\n\r\n" text)))
+                    (when pos (+ 4 pos)))))
+               (if end-of-header-pos
+                   (progn
+                     (let ((header-info (websocket-verify-client-headers text)))
+                       (if header-info
+                           (progn (setf (websocket-accept-string ws)
+                                        (websocket-calculate-accept
+                                         (plist-get header-info :key)))
+                                  (process-send-string
+                                   process
+                                   (websocket-get-server-response
+                                    ws (plist-get header-info :protocols)
+                                    (plist-get header-info :extensions)))
+                                  (setf (websocket-ready-state ws) 'open)
+                                  (websocket-try-callback 'websocket-on-open
+                                                          'on-open ws))
+                         (message "Invalid client headers found in: %s" output)
+                         (process-send-string process "HTTP/1.1 400 Bad Request\r\n\r\n")
+                         (websocket-close ws)))
+                     (when (> (length text) (+ 1 end-of-header-pos))
+                       (websocket-server-filter process (substring
+                                                           text
+                                                           end-of-header-pos))))
+                 (setf (websocket-inflight-input ws) text))))
+          ((eq (websocket-ready-state ws) 'open)
+           (websocket-process-input-on-open-ws ws text))
+          ((eq (websocket-ready-state ws) 'closed)
+           (message "WARNING: Should not have received further input on closed websocket")))))
+
+(defun websocket-verify-client-headers (output)
+  "Verify the headers from the WEBSOCKET client connection in OUTPUT.
+Unlike `websocket-verify-headers', this is a quieter routine.  We
+don't want to error due to a bad client, so we just print out
+messages and a plist containing `:key', the websocket key,
+`:protocols' and `:extensions'."
+  (cl-block nil
+    (let ((case-fold-search t)
+          (plist))
+      (unless (string-match "HTTP/1.1" output)
+        (message "Websocket client connection: HTTP/1.1 not found")
+        (cl-return nil))
+      (unless (string-match "^Host: " output)
+        (message "Websocket client connection: Host header not found")
+        (cl-return nil))
+      (unless (string-match "^Upgrade: websocket\r\n" output)
+        (message "Websocket client connection: Upgrade: websocket not found")
+        (cl-return nil))
+      (if (string-match "^Sec-WebSocket-Key: \\([[:graph:]]+\\)\r\n" output)
+          (setq plist (plist-put plist :key (match-string 1 output)))
+        (message "Websocket client connect: No key sent")
+        (cl-return nil))
+      (unless (string-match "^Sec-WebSocket-Version: 13" output)
+        (message "Websocket client connect: Websocket version 13 not found")
+        (cl-return nil))
+      (when (string-match "^Sec-WebSocket-Protocol:" output)
+        (setq plist (plist-put plist :protocols (websocket-parse-repeated-field
+                                                 output
+                                                 "Sec-Websocket-Protocol"))))
+      (when (string-match "^Sec-WebSocket-Extensions:" output)
+        (setq plist (plist-put plist :extensions (websocket-parse-repeated-field
+                                                  output
+                                                  "Sec-Websocket-Extensions"))))
+      plist)))
+
+(provide 'websocket)
+
+;;; websocket.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/websocket-20180422.1716/websocket.elc b/configs/shared/emacs/.emacs.d/elpa/websocket-20180422.1716/websocket.elc
new file mode 100644
index 0000000000..7a443d3604
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/websocket-20180422.1716/websocket.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/which-key-20180621.1238/which-key-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/which-key-20180621.1238/which-key-autoloads.el
new file mode 100644
index 0000000000..08b03bb475
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/which-key-20180621.1238/which-key-autoloads.el
@@ -0,0 +1,172 @@
+;;; which-key-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "which-key" "which-key.el" (23377 61296 573355
+;;;;;;  771000))
+;;; Generated autoloads from which-key.el
+
+(defvar which-key-mode nil "\
+Non-nil if Which-Key mode is enabled.
+See the `which-key-mode' command
+for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `which-key-mode'.")
+
+(custom-autoload 'which-key-mode "which-key" nil)
+
+(autoload 'which-key-mode "which-key" "\
+Toggle which-key-mode.
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'which-key-setup-side-window-right "which-key" "\
+Apply suggested settings for side-window that opens on right.
+
+\(fn)" t nil)
+
+(autoload 'which-key-setup-side-window-right-bottom "which-key" "\
+Apply suggested settings for side-window that opens on right
+if there is space and the bottom otherwise.
+
+\(fn)" t nil)
+
+(autoload 'which-key-setup-side-window-bottom "which-key" "\
+Apply suggested settings for side-window that opens on
+bottom.
+
+\(fn)" t nil)
+
+(autoload 'which-key-setup-minibuffer "which-key" "\
+Apply suggested settings for minibuffer.
+Do not use this setup if you use the paging commands. Instead use
+`which-key-setup-side-window-bottom', which is nearly identical
+but more functional.
+
+\(fn)" t nil)
+
+(autoload 'which-key-add-key-based-replacements "which-key" "\
+Replace the description of KEY-SEQUENCE with REPLACEMENT.
+KEY-SEQUENCE is a string suitable for use in `kbd'. REPLACEMENT
+may either be a string, as in
+
+\(which-key-add-key-based-replacements \"C-x 1\" \"maximize\")
+
+a cons of two strings as in
+
+\(which-key-add-key-based-replacements \"C-x 8\"
+                                        '(\"unicode\" . \"Unicode keys\"))
+
+or a function that takes a (KEY . BINDING) cons and returns a
+replacement.
+
+In the second case, the second string is used to provide a longer
+name for the keys under a prefix.
+
+MORE allows you to specifcy additional KEY REPLACEMENT pairs.  All
+replacements are added to
+`which-key-key-based-description-replacement-alist'.
+
+\(fn KEY-SEQUENCE REPLACEMENT &rest MORE)" nil nil)
+
+(autoload 'which-key-add-major-mode-key-based-replacements "which-key" "\
+Functions like `which-key-add-key-based-replacements'.
+The difference is that MODE specifies the `major-mode' that must
+be active for KEY-SEQUENCE and REPLACEMENT (MORE contains
+addition KEY-SEQUENCE REPLACEMENT pairs) to apply.
+
+\(fn MODE KEY-SEQUENCE REPLACEMENT &rest MORE)" nil nil)
+
+(autoload 'which-key-reload-key-sequence "which-key" "\
+Simulate entering the key sequence KEY-SEQ.
+KEY-SEQ should be a list of events as produced by
+`listify-key-sequence'. If nil, KEY-SEQ defaults to
+`which-key--current-key-list'. Any prefix arguments that were
+used are reapplied to the new key sequence.
+
+\(fn &optional KEY-SEQ)" nil nil)
+
+(autoload 'which-key-show-standard-help "which-key" "\
+Call the command in `which-key--prefix-help-cmd-backup'.
+Usually this is `describe-prefix-bindings'.
+
+\(fn &optional _)" t nil)
+
+(autoload 'which-key-show-next-page-no-cycle "which-key" "\
+Show next page of keys unless on the last page, in which case
+call `which-key-show-standard-help'.
+
+\(fn)" t nil)
+
+(autoload 'which-key-show-previous-page-no-cycle "which-key" "\
+Show previous page of keys unless on the first page, in which
+case do nothing.
+
+\(fn)" t nil)
+
+(autoload 'which-key-show-next-page-cycle "which-key" "\
+Show the next page of keys, cycling from end to beginning
+after last page.
+
+\(fn &optional _)" t nil)
+
+(autoload 'which-key-show-previous-page-cycle "which-key" "\
+Show the previous page of keys, cycling from beginning to end
+after first page.
+
+\(fn &optional _)" t nil)
+
+(autoload 'which-key-show-top-level "which-key" "\
+Show top-level bindings.
+
+\(fn &optional _)" t nil)
+
+(autoload 'which-key-show-major-mode "which-key" "\
+Show top-level bindings in the map of the current major mode.
+
+This function will also detect evil bindings made using
+`evil-define-key' in this map. These bindings will depend on the
+current evil state.
+
+\(fn)" t nil)
+
+(autoload 'which-key-undo-key "which-key" "\
+Undo last keypress and force which-key update.
+
+\(fn &optional _)" t nil)
+
+(autoload 'which-key-C-h-dispatch "which-key" "\
+Dispatch C-h commands by looking up key in
+`which-key-C-h-map'. This command is always accessible (from any
+prefix) if `which-key-use-C-h-commands' is non nil.
+
+\(fn)" t nil)
+
+(autoload 'which-key-show-keymap "which-key" "\
+Show the top-level bindings in KEYMAP using which-key. KEYMAP
+is selected interactively from all available keymaps.
+
+\(fn KEYMAP)" t nil)
+
+(autoload 'which-key-show-full-keymap "which-key" "\
+Show all bindings in KEYMAP using which-key. KEYMAP is
+selected interactively from all available keymaps.
+
+\(fn KEYMAP)" t nil)
+
+(autoload 'which-key-show-minor-mode-keymap "which-key" "\
+Show the top-level bindings in KEYMAP using which-key. KEYMAP
+is selected interactively by mode in `minor-mode-map-alist'.
+
+\(fn)" t nil)
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; which-key-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/which-key-20180621.1238/which-key-pkg.el b/configs/shared/emacs/.emacs.d/elpa/which-key-20180621.1238/which-key-pkg.el
new file mode 100644
index 0000000000..d5dd538456
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/which-key-20180621.1238/which-key-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "which-key" "20180621.1238" "Display available keybindings in popup" '((emacs "24.4")))
diff --git a/configs/shared/emacs/.emacs.d/elpa/which-key-20180621.1238/which-key.el b/configs/shared/emacs/.emacs.d/elpa/which-key-20180621.1238/which-key.el
new file mode 100644
index 0000000000..a3eaebdcf7
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/which-key-20180621.1238/which-key.el
@@ -0,0 +1,2632 @@
+;;; which-key.el --- Display available keybindings in popup  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2017  Free Software Foundation, Inc.
+
+;; Author: Justin Burkett <justin@burkett.cc>
+;; Maintainer: Justin Burkett <justin@burkett.cc>
+;; URL: https://github.com/justbur/emacs-which-key
+;; Package-Version: 20180621.1238
+;; Version: 3.3.0
+;; Keywords:
+;; Package-Requires: ((emacs "24.4"))
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; which-key provides the minor mode which-key-mode for Emacs. The mode displays
+;; the key bindings following your currently entered incomplete command (a
+;; prefix) in a popup. For example, after enabling the minor mode if you enter
+;; C-x and wait for the default of 1 second the minibuffer will expand with all
+;; of the available key bindings that follow C-x (or as many as space allows
+;; given your settings). This includes prefixes like C-x 8 which are shown in a
+;; different face. Screenshots of what the popup will look like along with
+;; information about additional features can be found at
+;; https://github.com/justbur/emacs-which-key.
+;;
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'button)
+(require 'regexp-opt)
+
+;; For compiler
+(defvar evil-operator-shortcut-map)
+(defvar evil-operator-state-map)
+(defvar evil-motion-state-map)
+(defvar golden-ratio-mode)
+(declare-function evil-get-command-property "ext:evil-common.el")
+
+;;; Options
+
+(defgroup which-key nil
+  "Customization options for which-key-mode"
+  :group 'help
+  :prefix "which-key-")
+
+(defcustom which-key-idle-delay 1.0
+  "Delay (in seconds) for which-key buffer to popup. A value of zero
+might lead to issues, so a non-zero value is recommended
+(see https://github.com/justbur/emacs-which-key/issues/134)."
+  :group 'which-key
+  :type 'float)
+
+(defcustom which-key-idle-secondary-delay nil
+  "Once the which-key buffer shows once for a key sequence reduce
+the idle time to this amount (in seconds). This makes it possible
+to shorten the delay for subsequent popups in the same key
+sequence. The default is for this value to be nil, which disables
+this behavior."
+  :group 'which-key
+  :type '(choice float (const :tag "Disabled" nil)))
+
+(defcustom which-key-echo-keystrokes (if (and echo-keystrokes
+                                              (> (+ echo-keystrokes 0.01)
+                                                 which-key-idle-delay))
+                                         (/ (float which-key-idle-delay) 4)
+                                       echo-keystrokes)
+  "Value to use for `echo-keystrokes'.
+This only applies if `which-key-popup-type' is minibuffer or
+`which-key-show-prefix' is echo. It needs to be less than
+`which-key-idle-delay' or else the keystroke echo will erase the
+which-key popup."
+  :group 'which-key
+  :type 'float)
+
+(defcustom which-key-max-description-length 27
+  "Truncate the description of keys to this length.
+Also adds \"..\". If nil, disable any truncation."
+  :group 'which-key
+  :type '(choice integer (const :tag "Disable truncation" nil)))
+
+(defcustom which-key-add-column-padding 0
+  "Additional padding (number of spaces) to add to the left of
+each key column."
+  :group 'which-key
+  :type 'integer)
+
+(defcustom which-key-unicode-correction 3
+  "Correction for wide unicode characters.
+Since we measure width in terms of the number of characters,
+Unicode characters that are wider than ASCII characters throw off
+the calculation for available width in the which-key buffer.  This
+variable allows you to adjust for the wide unicode characters by
+artificially reducing the available width in the buffer.
+
+The default of 3 means allow for the total extra width
+contributed by any wide unicode characters to be up to one
+additional ASCII character in the which-key buffer.  Increase this
+number if you are seeing charaters get cutoff on the right side
+of the which-key popup."
+  :group 'which-key
+  :type 'integer)
+
+(defcustom which-key-dont-use-unicode nil
+  "If non-nil, don't use any unicode characters in default setup."
+  :group 'which-key
+  :type 'boolean)
+
+(defcustom which-key-separator
+  (if which-key-dont-use-unicode " : " " → ")
+  "Separator to use between key and description. Default is \" →
+\", unless `which-key-dont-use-unicode' is non nil, in which case
+the default is \" : \"."
+  :group 'which-key
+  :type 'string)
+
+(defcustom which-key-prefix-prefix "+"
+  "String to insert in front of prefix commands (i.e., commands
+that represent a sub-map). Default is \"+\"."
+  :group 'which-key
+  :type 'string)
+
+(defcustom which-key-compute-remaps nil
+  "If non-nil, show remapped command if a command has been
+remapped given the currently active keymaps."
+  :group 'which-key
+  :type 'boolean)
+
+(defvar which-key-key-replacement-alist nil)
+(make-obsolete-variable 'which-key-key-replacement-alist
+                        'which-key-replacement-alist "2016-11-21")
+(defvar which-key-description-replacement-alist nil)
+(make-obsolete-variable 'which-key-description-replacement-alist
+                        'which-key-replacement-alist "2016-11-21")
+(defvar which-key-key-based-description-replacement-alist nil)
+(make-obsolete-variable 'which-key-key-based-description-replacement-alist
+                        'which-key-replacement-alist "2016-11-21")
+
+(defcustom which-key-replacement-alist
+  (delq nil
+        `(((nil . "Prefix Command") . (nil . "prefix"))
+          ((nil . "\\`\\?\\?\\'") . (nil . "lambda"))
+          ((nil . "which-key-show-next-page-no-cycle") . (nil . "wk next pg"))
+          ,@(unless which-key-dont-use-unicode
+              '((("<left>") . ("←"))
+                (("<right>") . ("→"))))
+          (("<\\([[:alnum:]-]+\\)>") . ("\\1"))))
+  "Association list to determine how to manipulate descriptions
+of key bindings in the which-key popup. Each element of the list
+is a nested cons cell with the format
+
+\(MATCH CONS . REPLACEMENT\).
+
+The MATCH CONS determines when a replacement should occur and
+REPLACEMENT determines how the replacement should occur. Each may
+have the format \(KEY REGEXP . BINDING REGEXP\). For the
+replacement to apply the key binding must match both the KEY
+REGEXP and the BINDING REGEXP. A value of nil in either position
+can be used to match every possibility. The replacement is
+performed by using `replace-regexp-in-string' on the KEY REGEXP
+from the MATCH CONS and REPLACEMENT when it is a cons cell, and
+then similarly for the BINDING REGEXP. A nil value in the BINDING
+REGEXP position cancels the replacement. For example, the entry
+
+\(\(nil . \"Prefix Command\"\) . \(nil . \"prefix\"\)\)
+
+matches any binding with the descriptions \"Prefix Command\" and
+replaces the description with \"prefix\", ignoring the
+corresponding key.
+
+REPLACEMENT may also be a function taking a cons cell
+\(KEY . BINDING\) and producing a new corresponding cons cell.
+
+If REPLACEMENT is anything other than a cons cell \(and non nil\)
+the key binding is ignored by which-key.
+
+Finally, you can multiple replacements to occur for a given key
+binding by setting `which-key-allow-multiple-replacements' to a
+non-nil value."
+  :group 'which-key
+  :type '(alist :key-type (cons (choice regexp (const nil))
+                                (choice regexp (const nil)))
+                :value-type (cons (choice string (const nil))
+                                  (choice string (const nil)))))
+
+(when (bound-and-true-p which-key-key-replacement-alist)
+  (mapc
+   (lambda (repl)
+     (push (cons (cons (car repl) nil) (cons (cdr repl) nil))
+           which-key-replacement-alist))
+   which-key-key-replacement-alist))
+(when (bound-and-true-p which-key-description-replacement-alist)
+  (mapc
+   (lambda (repl)
+     (push (cons (cons nil (car repl)) (cons nil (cdr repl)))
+           which-key-replacement-alist))
+   which-key-description-replacement-alist))
+
+(defcustom which-key-allow-multiple-replacements nil
+  "Allow a key binding to match and be modified by multiple
+elements in `which-key-replacement-alist' if non-nil. When nil,
+only the first match is used to perform replacements from
+`which-key-replacement-alist'."
+  :group 'which-key
+  :type 'boolean)
+
+(defcustom which-key-show-docstrings nil
+  "If non-nil, show each command's docstring next to the command
+in the which-key buffer. This will only display the docstring up
+to the first line break. If you set this variable to the symbol
+docstring-only, then the command's name with be omitted. You
+probably also want to adjust `which-key-max-description-length'
+at the same time if you use this feature."
+  :group 'which-key
+  :type '(radio
+          (const :tag "Do not show docstrings" nil)
+          (const :tag "Add docstring to command names" t)
+          (const :tag "Replace command name with docstring" docstring-only)))
+
+(defcustom which-key-highlighted-command-list '()
+  "A list of strings and/or cons cells used to highlight certain
+commands. If the element is a string, assume it is a regexp
+pattern for matching command names and use
+`which-key-highlighted-command-face' for any matching names. If
+the element is a cons cell, it should take the form (regexp .
+face to apply)."
+  :group 'which-key
+  :type  '(repeat (choice string (cons regexp face))))
+
+(defcustom which-key-special-keys '()
+  "These keys will automatically be truncated to one character
+and have `which-key-special-key-face' applied to them. This is
+disabled by default. Try this to see the effect.
+
+\(setq which-key-special-keys '(\"SPC\" \"TAB\" \"RET\" \"ESC\" \"DEL\")\)"
+  :group 'which-key
+  :type '(repeat string))
+
+(defcustom which-key-buffer-name " *which-key*"
+  "Name of which-key buffer."
+  :group 'which-key
+  :type 'string)
+
+(defcustom which-key-show-prefix 'echo
+  "Whether to and where to display the current prefix sequence.
+Possible choices are echo for echo area (the default), left, top
+and nil. Nil turns the feature off."
+  :group 'which-key
+  :type '(radio (const :tag "Left of the keys" left)
+                (const :tag "In the first line" top)
+                (const :tag "In the last line" bottom)
+                (const :tag "In the echo area" echo)
+                (const :tag "In the mode-line" mode-line)
+                (const :tag "Hide" nil)))
+
+(defcustom which-key-popup-type 'side-window
+  "Supported types are minibuffer, side-window, frame, and custom."
+  :group 'which-key
+  :type '(radio (const :tag "Show in minibuffer" minibuffer)
+                (const :tag "Show in side window" side-window)
+                (const :tag "Show in popup frame" frame)
+                (const :tag "Use your custom display functions" custom)))
+
+(defcustom which-key-min-display-lines 1
+  "The minimum number of horizontal lines to display in the
+  which-key buffer."
+  :group 'which-key
+  :type 'integer)
+
+(defcustom which-key-max-display-columns nil
+  "The maximum number of columns to display in the which-key
+buffer. nil means don't impose a maximum."
+  :group 'which-key
+  :type '(choice integer (const :tag "Unbounded" nil)))
+
+(defcustom which-key-side-window-location 'bottom
+  "Location of which-key popup when `which-key-popup-type' is side-window.
+Should be one of top, bottom, left or right. You can also specify
+a list of two locations, like (right bottom). In this case, the
+first location is tried. If there is not enough room, the second
+location is tried."
+  :group 'which-key
+  :type '(radio (const right)
+                (const bottom)
+                (const left)
+                (const top)
+                (const (right bottom))
+                (const (bottom right))))
+
+(defcustom which-key-side-window-slot 0
+  "The `slot' to use for `display-buffer-in-side-window' when
+`which-key-popup-type' is 'side-window. Quoting from the
+docstring of `display-buffer-in-side-window',
+
+‘slot’ if non-nil, specifies the window slot where to display
+  BUFFER.  A value of zero or nil means use the middle slot on
+  the specified side.  A negative value means use a slot
+  preceding (that is, above or on the left of) the middle slot.
+  A positive value means use a slot following (that is, below or
+  on the right of) the middle slot.  The default is zero."
+  :group 'which-key
+  :type 'integer)
+
+(defcustom which-key-side-window-max-width 0.333
+  "Maximum width of which-key popup when type is side-window and
+location is left or right.
+This variable can also be a number between 0 and 1. In that case, it denotes
+a percentage out of the frame's width."
+  :group 'which-key
+  :type 'float)
+
+(defcustom which-key-side-window-max-height 0.25
+  "Maximum height of which-key popup when type is side-window and
+location is top or bottom.
+This variable can also be a number between 0 and 1. In that case, it denotes
+a percentage out of the frame's height."
+  :group 'which-key
+  :type 'float)
+
+(defcustom which-key-frame-max-width 60
+  "Maximum width of which-key popup when type is frame."
+  :group 'which-key
+  :type 'integer)
+
+(defcustom which-key-frame-max-height 20
+  "Maximum height of which-key popup when type is frame."
+  :group 'which-key
+  :type 'integer)
+
+(defcustom which-key-allow-imprecise-window-fit nil
+  "If non-nil allow which-key to use a less intensive method of
+fitting the popup window to the buffer. If you are noticing lag
+when the which-key popup displays turning this on may help.
+
+See https://github.com/justbur/emacs-which-key/issues/130"
+  :group 'which-key
+  :type 'boolean)
+
+(defcustom which-key-show-remaining-keys nil
+  "Show remaining keys in last slot, when keys are hidden."
+  :group 'which-key
+  :type '(radio (const :tag "Yes" t)
+                (const :tag "No" nil)))
+
+(defcustom which-key-sort-order 'which-key-key-order
+  "If nil, do not resort the output from
+`describe-buffer-bindings' which groups by mode. Ordering options
+are
+
+1. `which-key-key-order': by key (default)
+2. `which-key-key-order-alpha': by key using alphabetical order
+3. `which-key-description-order': by description
+4. `which-key-prefix-then-key-order': prefix (no prefix first) then key
+5. `which-key-local-then-key-order': local binding then key
+
+See the README and the docstrings for those functions for more
+information."
+  :group 'which-key
+  :type '(choice (function-item which-key-key-order)
+                 (function-item which-key-key-order-alpha)
+                 (function-item which-key-description-order)
+                 (function-item which-key-prefix-then-key-order)
+                 (function-item which-key-local-then-key-order)))
+
+(defcustom which-key-sort-uppercase-first t
+  "If non-nil, uppercase comes before lowercase in sorting
+function chosen in `which-key-sort-order'. Otherwise, the order
+is reversed."
+  :group 'which-key
+  :type 'boolean)
+
+(defcustom which-key-paging-prefixes '()
+  "Enable paging for these prefixes."
+  :group 'which-key
+  :type '(repeat string))
+
+(defcustom which-key-paging-key "<f5>"
+  "Key to use for changing pages. Bound after each of the
+prefixes in `which-key-paging-prefixes'"
+  :group 'which-key
+  :type 'string)
+
+;; (defcustom which-key-undo-key nil
+;;   "Key (string) to use for undoing keypresses. Bound recursively
+;; in each of the maps in `which-key-undo-keymaps'."
+;;   :group 'which-key
+;;   :type 'string)
+
+;; (defcustom which-key-undo-keymaps '()
+;;   "Keymaps in which to bind `which-key-undo-key'"
+;;   :group 'which-key
+;;   :type '(repeat symbol))
+
+(defcustom which-key-use-C-h-commands t
+  "Use C-h for paging if non-nil. Normally C-h after a prefix
+  calls `describe-prefix-bindings'. This changes that command to
+  a which-key paging command when which-key-mode is active."
+  :group 'which-key
+  :type 'boolean)
+
+(defcustom which-key-is-verbose nil
+  "Whether to warn about potential mistakes in configuration."
+  :group 'which-key
+  :type 'boolean)
+
+(defvar which-key-C-h-map
+  (let ((map (make-sparse-keymap)))
+    (dolist (bind '(("\C-a" . which-key-abort)
+                    ("a" . which-key-abort)
+                    ("\C-d" . which-key-toggle-docstrings)
+                    ("d" . which-key-toggle-docstrings)
+                    ("\C-h" . which-key-show-standard-help)
+                    ("h" . which-key-show-standard-help)
+                    ("\C-n" . which-key-show-next-page-cycle)
+                    ("n" . which-key-show-next-page-cycle)
+                    ("\C-p" . which-key-show-previous-page-cycle)
+                    ("p" . which-key-show-previous-page-cycle)
+                    ("\C-u" . which-key-undo-key)
+                    ("u" . which-key-undo-key)
+                    ("1" . which-key-digit-argument)
+                    ("2" . which-key-digit-argument)
+                    ("3" . which-key-digit-argument)
+                    ("4" . which-key-digit-argument)
+                    ("5" . which-key-digit-argument)
+                    ("6" . which-key-digit-argument)
+                    ("7" . which-key-digit-argument)
+                    ("8" . which-key-digit-argument)
+                    ("9" . which-key-digit-argument)))
+      (define-key map (car bind) (cdr bind)))
+    map)
+  "Keymap for C-h commands.")
+
+(defvar which-key--paging-functions '(which-key-C-h-dispatch
+                                      which-key-turn-page
+                                      which-key-show-next-page-cycle
+                                      which-key-show-next-page-no-cycle
+                                      which-key-show-previous-page-cycle
+                                      which-key-show-previous-page-no-cycle
+                                      which-key-undo-key
+                                      which-key-undo))
+
+(defcustom which-key-hide-alt-key-translations t
+  "Hide key translations using Alt key if non nil.
+These translations are not relevant most of the times since a lot
+of terminals issue META modifier for the Alt key.
+
+See http://www.gnu.org/software/emacs/manual/html_node/emacs/Modifier-Keys.html"
+  :group 'which-key
+  :type 'boolean)
+
+(defcustom which-key-delay-functions nil
+  "A list of functions that may decide whether to delay the
+which-key popup based on the current incomplete key
+sequence. Each function in the list is run with two arguments,
+the current key sequence as produced by `key-description' and the
+length of the key sequence. If the popup should be delayed based
+on that key sequence, the function should return the delay time
+in seconds. Returning nil means no delay. The first function in
+this list to return a value is the value that is used.
+
+The delay time is effectively added to the normal
+`which-key-idle-delay'."
+  :group 'which-key
+  :type '(repeat function))
+
+(defcustom which-key-allow-regexps nil
+  "A list of regexp strings to use to filter key sequences. When
+non-nil, for a key sequence to trigger the which-key popup it
+must match one of the regexps in this list. The format of the key
+sequences is what is produced by `key-description'."
+  :group 'which-key
+  :type '(repeat regexp))
+
+(defcustom which-key-inhibit-regexps nil
+  "Similar to `which-key-allow-regexps', a list of regexp strings
+to use to filter key sequences. When non-nil, for a key sequence
+to trigger the which-key popup it cannot match one of the regexps
+in this list. The format of the key sequences is what is produced
+by `key-description'."
+  :group 'which-key
+  :type '(repeat regexp))
+
+(defcustom which-key-show-transient-maps nil
+  "Show keymaps created by `set-transient-map' when applicable.
+
+More specifically, detect when `overriding-terminal-local-map' is
+set (this is the keymap used by `set-transient-map') and display
+it."
+  :group 'which-key
+  :type 'boolean)
+
+(defcustom which-key-enable-extended-define-key nil
+  "Advise `define-key' to make which-key aware of definitions of the form
+
+  \(define-key KEYMAP KEY '(\"DESCRIPTION\" . DEF))
+
+With the advice, this definition will have the side effect of
+creating a replacement in `which-key-replacement-alist' that
+replaces DEF with DESCRIPTION when the key sequence ends in
+KEY. Using a cons cell like this is a valid definition for
+`define-key'. All this does is to make which-key aware of it.
+
+Since many higher level keybinding functions use `define-key'
+internally, this will affect most if not all of those as well.
+
+This variable must be set before loading which-key."
+  :group 'which-key
+  :type 'boolean)
+
+;; Hooks
+(defcustom which-key-init-buffer-hook '()
+  "Hook run when which-key buffer is initialized."
+  :group 'which-key
+  :type 'hook)
+
+;;;; Faces
+
+(defgroup which-key-faces nil
+  "Faces for which-key-mode"
+  :group 'which-key
+  :prefix "which-key-")
+
+(defface which-key-key-face
+  '((t . (:inherit font-lock-constant-face)))
+  "Face for which-key keys"
+  :group 'which-key-faces)
+
+(defface which-key-separator-face
+  '((t . (:inherit font-lock-comment-face)))
+  "Face for the separator (default separator is an arrow)"
+  :group 'which-key-faces)
+
+(defface which-key-note-face
+  '((t . (:inherit which-key-separator-face)))
+  "Face for notes or hints occasionally provided"
+  :group 'which-key-faces)
+
+(defface which-key-command-description-face
+  '((t . (:inherit font-lock-function-name-face)))
+  "Face for the key description when it is a command"
+  :group 'which-key-faces)
+
+(defface which-key-local-map-description-face
+  '((t . (:inherit which-key-command-description-face)))
+  "Face for the key description when it is found in `current-local-map'"
+  :group 'which-key-faces)
+
+(defface which-key-highlighted-command-face
+  '((t . (:inherit which-key-command-description-face :underline t)))
+  "Default face for the command description when it is a command
+and it matches a string in `which-key-highlighted-command-list'."
+  :group 'which-key-faces)
+
+(defface which-key-group-description-face
+  '((t . (:inherit font-lock-keyword-face)))
+  "Face for the key description when it is a group or prefix"
+  :group 'which-key-faces)
+
+(defface which-key-special-key-face
+  '((t . (:inherit which-key-key-face :inverse-video t :weight bold)))
+  "Face for special keys (SPC, TAB, RET)"
+  :group 'which-key-faces)
+
+(defface which-key-docstring-face
+  '((t . (:inherit which-key-note-face)))
+  "Face for docstrings"
+  :group 'which-key-faces)
+
+;;;; Custom popup
+
+(defcustom which-key-custom-popup-max-dimensions-function nil
+  "Variable to hold a custom max-dimensions function.
+Will be passed the width of the active window and is expected to
+return the maximum height in lines and width in characters of the
+which-key popup in the form a cons cell (height . width)."
+  :group 'which-key
+  :type '(choice function (const nil)))
+
+(defcustom which-key-custom-hide-popup-function nil
+  "Variable to hold a custom hide-popup function.
+It takes no arguments and the return value is ignored."
+  :group 'which-key
+  :type '(choice function (const nil)))
+
+(defcustom which-key-custom-show-popup-function nil
+  "Variable to hold a custom show-popup function.
+Will be passed the required dimensions in the form (height .
+width) in lines and characters respectively.  The return value is
+ignored."
+  :group 'which-key
+  :type '(choice function (const nil)))
+
+(defcustom which-key-lighter " WK"
+  "Minor mode lighter to use in the mode-line."
+  :group 'which-key
+  :type 'string)
+
+(defvar which-key-inhibit nil
+  "Prevent which-key from popping up momentarily by setting this
+to a non-nil value for the execution of a command. Like this
+
+\(let \(\(which-key-inhibit t\)\)
+...\)")
+
+(defvar which-key-keymap-history nil
+  "History of keymap selections in functions like
+`which-key-show-keymap'.")
+
+;;; Internal Vars
+
+(defvar which-key--buffer nil
+  "Internal: Holds reference to which-key buffer.")
+(defvar which-key--timer nil
+  "Internal: Holds reference to open window timer.")
+(defvar which-key--secondary-timer-active nil
+  "Internal: Non-nil if the secondary timer is active.")
+(defvar which-key--paging-timer nil
+  "Internal: Holds reference to timer for paging.")
+(defvar which-key--frame nil
+  "Internal: Holds reference to which-key frame.
+Used when `which-key-popup-type' is frame.")
+(defvar which-key--echo-keystrokes-backup nil
+  "Internal: Backup the initial value of `echo-keystrokes'.")
+(defvar which-key--prefix-help-cmd-backup nil
+  "Internal: Backup the value of `prefix-help-command'.")
+(defvar which-key--last-try-2-loc nil
+  "Internal: Last location of side-window when two locations
+used.")
+(defvar which-key--automatic-display nil
+  "Internal: Non-nil if popup was triggered with automatic
+update.")
+(defvar which-key--multiple-locations nil)
+(defvar which-key--inhibit-next-operator-popup nil)
+(defvar which-key--prior-show-keymap-args nil)
+(defvar which-key--previous-frame-size nil)
+(defvar which-key--prefix-title-alist nil)
+(defvar which-key--debug nil)
+(defvar which-key--evil-keys-regexp (eval-when-compile
+                                      (regexp-opt '("-state"))))
+(defvar which-key--ignore-non-evil-keys-regexp
+  (eval-when-compile
+    (regexp-opt '("mouse-" "wheel-" "remap" "drag-" "scroll-bar"
+                  "select-window" "switch-frame" "which-key-"))))
+(defvar which-key--ignore-keys-regexp
+  (eval-when-compile
+    (regexp-opt '("mouse-" "wheel-" "remap" "drag-" "scroll-bar"
+                  "select-window" "switch-frame" "-state"
+                  "which-key-"))))
+
+(make-obsolete-variable 'which-key-prefix-name-alist nil "2016-10-05")
+(make-obsolete-variable 'which-key-prefix-title-alist nil "2016-10-05")
+
+(defvar which-key--pages-obj nil)
+(cl-defstruct which-key--pages
+  pages
+  height
+  widths
+  keys/page
+  page-nums
+  num-pages
+  total-keys
+  prefix
+  prefix-title)
+
+(defun which-key--rotate (list n)
+  (let* ((len (length list))
+         (n (if (< n 0) (+ len n) n))
+         (n (mod n len)))
+    (append (last list (- len n)) (butlast list (- len n)))))
+
+(defun which-key--pages-set-current-page (pages-obj n)
+  (setf (which-key--pages-pages pages-obj)
+        (which-key--rotate (which-key--pages-pages pages-obj) n))
+  (setf (which-key--pages-widths pages-obj)
+        (which-key--rotate (which-key--pages-widths pages-obj) n))
+  (setf (which-key--pages-keys/page pages-obj)
+        (which-key--rotate (which-key--pages-keys/page pages-obj) n))
+  (setf (which-key--pages-page-nums pages-obj)
+        (which-key--rotate (which-key--pages-page-nums pages-obj) n))
+  pages-obj)
+
+(defsubst which-key--on-first-page ()
+  (= (which-key--pages-page-nums which-key--pages-obj) 1))
+
+(defsubst which-key--on-last-page ()
+  (= (which-key--pages-page-nums which-key--pages-obj)
+     (which-key--pages-num-pages which-key--pages-obj)))
+
+(defsubst which-key--current-prefix ()
+  (when which-key--pages-obj
+    (which-key--pages-prefix which-key--pages-obj)))
+
+;;; Third-party library support
+;;;; Evil
+
+(defcustom which-key-allow-evil-operators (boundp 'evil-this-operator)
+  "Allow popup to show for evil operators. The popup is normally
+  inhibited in the middle of commands, but setting this to
+  non-nil will override this behavior for evil operators."
+  :group 'which-key
+  :type 'boolean)
+
+(defcustom which-key-show-operator-state-maps nil
+  "Experimental: Try to show the right keys following an evil
+command that reads a motion, such as \"y\", \"d\" and \"c\" from
+normal state. This is experimental, because there might be some
+valid keys missing and it might be showing some invalid keys."
+  :group 'which-key
+  :type 'boolean)
+
+;;;;; God-mode
+
+(defvar which-key--god-mode-support-enabled nil
+  "Support god-mode if non-nil. This is experimental,
+so you need to explicitly opt-in for now. Please report any
+problems at github.")
+
+(defvar which-key--god-mode-key-string nil
+  "Holds key string to use for god-mode support.")
+
+(defadvice god-mode-lookup-command
+    (around which-key--god-mode-lookup-command-advice disable)
+  (setq which-key--god-mode-key-string (ad-get-arg 0))
+  (unwind-protect
+      ad-do-it
+    (when (bound-and-true-p which-key-mode)
+      (which-key--hide-popup))))
+
+(defun which-key-enable-god-mode-support (&optional disable)
+  "Enable support for god-mode if non-nil. This is experimental,
+so you need to explicitly opt-in for now. Please report any
+problems at github. If DISABLE is non-nil disable support."
+  (interactive "P")
+  (setq which-key--god-mode-support-enabled (null disable))
+  (if disable
+      (ad-disable-advice
+       'god-mode-lookup-command
+       'around 'which-key--god-mode-lookup-command-advice)
+    (ad-enable-advice
+     'god-mode-lookup-command
+     'around 'which-key--god-mode-lookup-command-advice))
+  (ad-activate 'god-mode-lookup-command))
+
+;;; Mode
+
+;;;###autoload
+(define-minor-mode which-key-mode
+  "Toggle which-key-mode."
+  :global t
+  :lighter which-key-lighter
+  :keymap (let ((map (make-sparse-keymap)))
+            (mapc
+             (lambda (prefix)
+               (define-key map
+                 (kbd (concat prefix " " which-key-paging-key))
+                 #'which-key-C-h-dispatch))
+             which-key-paging-prefixes)
+            map)
+  (if which-key-mode
+      (progn
+        (setq which-key--echo-keystrokes-backup echo-keystrokes)
+        (when (or (eq which-key-show-prefix 'echo)
+                  (eq which-key-popup-type 'minibuffer))
+          (which-key--setup-echo-keystrokes))
+        (unless (member prefix-help-command which-key--paging-functions)
+          (setq which-key--prefix-help-cmd-backup prefix-help-command))
+        (when which-key-use-C-h-commands
+          (setq prefix-help-command #'which-key-C-h-dispatch))
+        (when which-key-show-remaining-keys
+          (add-hook 'pre-command-hook #'which-key--lighter-restore))
+        (add-hook 'pre-command-hook #'which-key--hide-popup)
+        (add-hook 'focus-out-hook #'which-key--stop-timer)
+        (add-hook 'focus-in-hook #'which-key--start-timer)
+        (add-hook 'window-size-change-functions
+                  'which-key--hide-popup-on-frame-size-change)
+        (which-key--start-timer))
+    (setq echo-keystrokes which-key--echo-keystrokes-backup)
+    (when which-key--prefix-help-cmd-backup
+      (setq prefix-help-command which-key--prefix-help-cmd-backup))
+    (when which-key-show-remaining-keys
+      (remove-hook 'pre-command-hook #'which-key--lighter-restore))
+    (remove-hook 'pre-command-hook #'which-key--hide-popup)
+    (remove-hook 'focus-out-hook #'which-key--stop-timer)
+    (remove-hook 'focus-in-hook #'which-key--start-timer)
+    (remove-hook 'window-size-change-functions
+                 'which-key--hide-popup-on-frame-size-change)
+    (which-key--stop-timer)))
+
+(defun which-key--init-buffer ()
+  "Initialize which-key buffer"
+  (unless (buffer-live-p which-key--buffer)
+    (setq which-key--buffer (get-buffer-create which-key-buffer-name))
+    (with-current-buffer which-key--buffer
+      ;; suppress confusing minibuffer message
+      (let (message-log-max)
+        (toggle-truncate-lines 1)
+        (message ""))
+      (setq-local cursor-type nil)
+      (setq-local cursor-in-non-selected-windows nil)
+      (setq-local mode-line-format nil)
+      (setq-local word-wrap nil)
+      (setq-local show-trailing-whitespace nil)
+      (run-hooks 'which-key-init-buffer-hook))))
+
+(defun which-key--setup-echo-keystrokes ()
+  "Reduce `echo-keystrokes' if necessary (it will interfere if
+it's set too high)."
+  (when (and echo-keystrokes
+             (> (abs (- echo-keystrokes which-key-echo-keystrokes)) 0.000001))
+    (if (> which-key-idle-delay which-key-echo-keystrokes)
+        (setq echo-keystrokes which-key-echo-keystrokes)
+      (setq which-key-echo-keystrokes (/ (float which-key-idle-delay) 4)
+            echo-keystrokes which-key-echo-keystrokes))))
+
+(defun which-key-remove-default-unicode-chars ()
+  "Use of `which-key-dont-use-unicode' is preferred to this
+function, but it's included here in case someone cannot set that
+variable early enough in their configuration, if they are using a
+starter kit for example."
+  (when (string-equal which-key-separator " → ")
+    (setq which-key-separator " : "))
+  (setq which-key-key-replacement-alist
+        (delete '("left" . "←") which-key-key-replacement-alist))
+  (setq which-key-key-replacement-alist
+        (delete '("right" . "→") which-key-key-replacement-alist)))
+
+;;; Default configuration functions for use by users.
+
+;;;###autoload
+(defun which-key-setup-side-window-right ()
+  "Apply suggested settings for side-window that opens on right."
+  (interactive)
+  (setq which-key-popup-type 'side-window
+        which-key-side-window-location 'right
+        which-key-show-prefix 'top))
+
+;;;###autoload
+(defun which-key-setup-side-window-right-bottom ()
+  "Apply suggested settings for side-window that opens on right
+if there is space and the bottom otherwise."
+  (interactive)
+  (setq which-key-popup-type 'side-window
+        which-key-side-window-location '(right bottom)
+        which-key-show-prefix 'top))
+
+;;;###autoload
+(defun which-key-setup-side-window-bottom ()
+  "Apply suggested settings for side-window that opens on
+bottom."
+  (interactive)
+  (which-key--setup-echo-keystrokes)
+  (setq which-key-popup-type 'side-window
+        which-key-side-window-location 'bottom
+        which-key-show-prefix 'echo))
+
+;;;###autoload
+(defun which-key-setup-minibuffer ()
+  "Apply suggested settings for minibuffer.
+Do not use this setup if you use the paging commands. Instead use
+`which-key-setup-side-window-bottom', which is nearly identical
+but more functional."
+  (interactive)
+  (which-key--setup-echo-keystrokes)
+  (setq which-key-popup-type 'minibuffer
+        which-key-show-prefix 'left))
+
+;;; Helper functions to modify replacement lists.
+
+;;;###autoload
+(defun which-key-add-key-based-replacements
+    (key-sequence replacement &rest more)
+  "Replace the description of KEY-SEQUENCE with REPLACEMENT.
+KEY-SEQUENCE is a string suitable for use in `kbd'. REPLACEMENT
+may either be a string, as in
+
+\(which-key-add-key-based-replacements \"C-x 1\" \"maximize\"\)
+
+a cons of two strings as in
+
+\(which-key-add-key-based-replacements \"C-x 8\"
+                                        '(\"unicode\" . \"Unicode keys\")\)
+
+or a function that takes a \(KEY . BINDING\) cons and returns a
+replacement.
+
+In the second case, the second string is used to provide a longer
+name for the keys under a prefix.
+
+MORE allows you to specifcy additional KEY REPLACEMENT pairs.  All
+replacements are added to
+`which-key-key-based-description-replacement-alist'."
+  ;; TODO: Make interactive
+  (while key-sequence
+    ;; normalize key sequences before adding
+    (let ((key-seq (key-description (kbd key-sequence)))
+          (replace (or (and (functionp replacement) replacement)
+                       (car-safe replacement)
+                       replacement)))
+      (push (cons (cons (concat "\\`" (regexp-quote key-seq) "\\'") nil)
+                  (if (functionp replace) replace (cons nil replace)))
+            which-key-replacement-alist)
+      (when (and (not (functionp replacement)) (consp replacement))
+        (push (cons key-seq (cdr-safe replacement))
+              which-key--prefix-title-alist)))
+    (setq key-sequence (pop more) replacement (pop more))))
+(put 'which-key-add-key-based-replacements 'lisp-indent-function 'defun)
+
+;;;###autoload
+(defun which-key-add-major-mode-key-based-replacements
+    (mode key-sequence replacement &rest more)
+  "Functions like `which-key-add-key-based-replacements'.
+The difference is that MODE specifies the `major-mode' that must
+be active for KEY-SEQUENCE and REPLACEMENT (MORE contains
+addition KEY-SEQUENCE REPLACEMENT pairs) to apply."
+  ;; TODO: Make interactive
+  (when (not (symbolp mode))
+    (error "MODE should be a symbol corresponding to a value of major-mode"))
+  (let ((mode-alist
+         (or (cdr-safe (assq mode which-key-replacement-alist)) (list)))
+        (title-mode-alist
+         (or (cdr-safe (assq mode which-key--prefix-title-alist)) (list))))
+    (while key-sequence
+    ;; normalize key sequences before adding
+      (let ((key-seq (key-description (kbd key-sequence)))
+            (replace (or (and (functionp replacement) replacement)
+                         (car-safe replacement)
+                         replacement)))
+        (push (cons (cons (concat "\\`" (regexp-quote key-seq) "\\'") nil)
+                    (if (functionp replace) replace (cons nil replace)))
+              mode-alist)
+        (when (and (not (functionp replacement)) (consp replacement))
+          (push (cons key-seq (cdr-safe replacement))
+                title-mode-alist)))
+      (setq key-sequence (pop more) replacement (pop more)))
+    (if (assq mode which-key-replacement-alist)
+        (setcdr (assq mode which-key-replacement-alist) mode-alist)
+      (push (cons mode mode-alist) which-key-replacement-alist))
+    (if (assq mode which-key--prefix-title-alist)
+        (setcdr (assq mode which-key--prefix-title-alist) title-mode-alist)
+      (push (cons mode title-mode-alist) which-key--prefix-title-alist))))
+(put 'which-key-add-major-mode-key-based-replacements
+     'lisp-indent-function 'defun)
+
+(defalias 'which-key-add-prefix-title 'which-key-add-key-based-replacements)
+(make-obsolete 'which-key-add-prefix-title
+               'which-key-add-key-based-replacements
+               "2016-10-05")
+
+(defalias 'which-key-declare-prefixes 'which-key-add-key-based-replacements)
+(make-obsolete 'which-key-declare-prefixes
+               'which-key-add-key-based-replacements
+               "2016-10-05")
+
+(defalias 'which-key-declare-prefixes-for-mode
+  'which-key-add-major-mode-key-based-replacements)
+(make-obsolete 'which-key-declare-prefixes-for-mode
+               'which-key-add-major-mode-key-based-replacements
+               "2016-10-05")
+
+(defun which-key-define-key-recursively (map key def &optional at-root)
+  "Recursively bind KEY in MAP to DEF on every level of MAP except the first.
+If AT-ROOT is non-nil the binding is also placed at the root of MAP."
+  (when at-root (define-key map key def))
+  (map-keymap
+   (lambda (_ev df)
+     (when (keymapp df)
+       (which-key-define-key-recursively df key def t)))
+   map))
+
+(defun which-key--process-define-key-args (keymap key def)
+  "When DEF takes the form (\"DESCRIPTION\". DEF), make sure
+which-key uses \"DESCRIPTION\" for this binding. This function is
+meant to be used as :before advice for `define-key'."
+  (with-demoted-errors "Which-key extended define-key error: %s"
+    (when (and (consp def)
+               (stringp (car def))
+               (symbolp (cdr def)))
+      (define-key keymap (which-key--pseudo-key key) `(which-key ,def)))))
+
+(when which-key-enable-extended-define-key
+  (advice-add #'define-key :before #'which-key--process-define-key-args))
+
+;;; Functions for computing window sizes
+
+(defun which-key--text-width-to-total (text-width)
+  "Convert window text-width to window total-width.
+TEXT-WIDTH is the desired text width of the window.  The function
+calculates what total width is required for a window in the
+selected to have a text-width of TEXT-WIDTH columns.  The
+calculation considers possible fringes and scroll bars.  This
+function assumes that the desired window has the same character
+width as the frame."
+  (let ((char-width (frame-char-width)))
+    (+ text-width
+       (/ (frame-fringe-width) char-width)
+       (/ (frame-scroll-bar-width) char-width)
+       (if (which-key--char-enlarged-p) 1 0)
+       ;; add padding to account for possible wide (unicode) characters
+       3)))
+
+(defun which-key--total-width-to-text (total-width)
+  "Convert window total-width to window text-width.
+TOTAL-WIDTH is the desired total width of the window.  The function calculates
+what text width fits such a window.  The calculation considers possible fringes
+and scroll bars.  This function assumes that the desired window has the same
+character width as the frame."
+  (let ((char-width (frame-char-width)))
+    (- total-width
+       (/ (frame-fringe-width) char-width)
+       (/ (frame-scroll-bar-width) char-width)
+       (if (which-key--char-enlarged-p) 1 0)
+       ;; add padding to account for possible wide (unicode) characters
+       3)))
+
+(defun which-key--char-enlarged-p (&optional _frame)
+  (> (frame-char-width)
+     (/ (float (frame-pixel-width)) (window-total-width (frame-root-window)))))
+
+(defun which-key--char-reduced-p (&optional _frame)
+  (< (frame-char-width)
+     (/ (float (frame-pixel-width)) (window-total-width (frame-root-window)))))
+
+(defun which-key--char-exact-p (&optional _frame)
+  (= (frame-char-width)
+     (/ (float (frame-pixel-width)) (window-total-width (frame-root-window)))))
+
+(defun which-key--width-or-percentage-to-width (width-or-percentage)
+  "Return window total width.
+If WIDTH-OR-PERCENTAGE is a whole number, return it unchanged.  Otherwise, it
+should be a percentage (a number between 0 and 1) out of the frame's width.
+More precisely, it should be a percentage out of the frame's root window's
+total width."
+  (if (wholenump width-or-percentage)
+      width-or-percentage
+    (round (* width-or-percentage (window-total-width (frame-root-window))))))
+
+(defun which-key--height-or-percentage-to-height (height-or-percentage)
+  "Return window total height.
+If HEIGHT-OR-PERCENTAGE is a whole number, return it unchanged.  Otherwise, it
+should be a percentage (a number between 0 and 1) out of the frame's height.
+More precisely, it should be a percentage out of the frame's root window's
+total height."
+  (if (wholenump height-or-percentage)
+      height-or-percentage
+    (round (* height-or-percentage (window-total-height (frame-root-window))))))
+
+(defun which-key--frame-size-changed-p ()
+  "Non-nil if a change in frame size is detected."
+  (let ((new-size (cons (frame-width) (frame-height))))
+    (cond ((null which-key--previous-frame-size)
+           (setq which-key--previous-frame-size new-size)
+           nil)
+          ((not (equal which-key--previous-frame-size new-size))
+           (setq which-key--previous-frame-size new-size)))))
+
+;;; Show/hide which-key buffer
+
+(defun which-key--hide-popup ()
+  "This function is called to hide the which-key buffer."
+  (unless (member real-this-command which-key--paging-functions)
+    (setq which-key--last-try-2-loc nil)
+    (setq which-key--pages-obj nil)
+    (setq which-key--automatic-display nil)
+    (setq which-key--prior-show-keymap-args nil)
+    (when (and which-key-idle-secondary-delay
+               which-key--secondary-timer-active)
+      (which-key--start-timer))
+    (which-key--lighter-restore)
+    (cl-case which-key-popup-type
+      ;; Not necessary to hide minibuffer
+      ;; (minibuffer (which-key--hide-buffer-minibuffer))
+      (side-window (which-key--hide-buffer-side-window))
+      (frame (which-key--hide-buffer-frame))
+      (custom (funcall which-key-custom-hide-popup-function)))))
+
+(defun which-key--hide-popup-ignore-command ()
+  "Version of `which-key--hide-popup' without the check of
+`real-this-command'."
+  (cl-case which-key-popup-type
+    (side-window (which-key--hide-buffer-side-window))
+    (frame (which-key--hide-buffer-frame))
+    (custom (funcall which-key-custom-hide-popup-function))))
+
+(defun which-key--hide-popup-on-frame-size-change (&optional _)
+  "Hide which-key popup if the frame is resized (to trigger a new
+popup)."
+  (when (which-key--frame-size-changed-p)
+    (which-key--hide-popup)))
+
+(defun which-key--hide-buffer-side-window ()
+  "Hide which-key buffer when side-window popup is used."
+  (when (buffer-live-p which-key--buffer)
+    ;; in case which-key buffer was shown in an existing window, `quit-window'
+    ;; will re-show the previous buffer, instead of closing the window
+    (quit-windows-on which-key--buffer)))
+
+(defun which-key--hide-buffer-frame ()
+  "Hide which-key buffer when frame popup is used."
+  (when (frame-live-p which-key--frame)
+    (delete-frame which-key--frame)))
+
+(defun which-key--popup-showing-p ()
+  (window-live-p (get-buffer-window which-key--buffer)))
+
+(defun which-key--show-popup (act-popup-dim)
+  "Show the which-key buffer.
+ACT-POPUP-DIM includes the dimensions, (height . width) of the
+buffer text to be displayed in the popup.  Return nil if no window
+is shown, or if there is no need to start the closing timer."
+  (when (and (> (car act-popup-dim) 0) (> (cdr act-popup-dim) 0))
+    (cl-case which-key-popup-type
+      ;; Not called for minibuffer
+      ;; (minibuffer (which-key--show-buffer-minibuffer act-popup-dim))
+      (side-window (which-key--show-buffer-side-window act-popup-dim))
+      (frame (which-key--show-buffer-frame act-popup-dim))
+      (custom (funcall which-key-custom-show-popup-function act-popup-dim)))))
+
+(defun which-key--fit-buffer-to-window-horizontally
+    (&optional window &rest params)
+  "Slightly modified version of `fit-buffer-to-window'.
+Use &rest params because `fit-buffer-to-window' has a different
+call signature in different emacs versions"
+  (let ((fit-window-to-buffer-horizontally t))
+    (apply #'fit-window-to-buffer window params)))
+
+(defun which-key--show-buffer-side-window (act-popup-dim)
+  "Show which-key buffer when popup type is side-window."
+  (let* ((height (car act-popup-dim))
+         (width (cdr act-popup-dim))
+         (alist
+          (if which-key-allow-imprecise-window-fit
+              `((window-width .  ,(which-key--text-width-to-total width))
+                (window-height . ,height)
+                (side . ,which-key-side-window-location)
+                (slot . ,which-key-side-window-slot))
+            `((window-width . which-key--fit-buffer-to-window-horizontally)
+              (window-height . (lambda (w) (fit-window-to-buffer w nil 1)))
+              (side . ,which-key-side-window-location)
+              (slot . ,which-key-side-window-slot)))))
+    ;; Previously used `display-buffer-in-major-side-window' here, but
+    ;; apparently that is meant to be an internal function. See emacs bug #24828
+    ;; and advice given there.
+    (cond
+     ((eq which-key--multiple-locations t)
+      ;; possibly want to switch sides in this case so we can't reuse the window
+      (delete-windows-on which-key--buffer)
+      (display-buffer-in-side-window which-key--buffer alist))
+     ((get-buffer-window which-key--buffer)
+      (display-buffer-reuse-window which-key--buffer alist))
+     (t
+      (display-buffer-in-side-window which-key--buffer alist)))))
+
+(defun which-key--show-buffer-frame (act-popup-dim)
+  "Show which-key buffer when popup type is frame."
+  (let* (;(orig-window (selected-window))
+         (frame-height (+ (car act-popup-dim)
+                          (if (with-current-buffer which-key--buffer
+                                mode-line-format)
+                              1
+                            0)))
+         ;; without adding 2, frame sometimes isn't wide enough for the buffer.
+         ;; this is probably because of the fringes. however, setting fringes
+         ;; sizes to 0 (instead of adding 2) didn't always make the frame wide
+         ;; enough. don't know why it is so.
+         (frame-width (+ (cdr act-popup-dim) 2))
+         (new-window (if (and (frame-live-p which-key--frame)
+                              (eq which-key--buffer
+                                  (window-buffer
+                                   (frame-root-window which-key--frame))))
+                         (which-key--show-buffer-reuse-frame
+                          frame-height frame-width)
+                       (which-key--show-buffer-new-frame
+                        frame-height frame-width))))
+    (when new-window
+      ;; display successful
+      (setq which-key--frame (window-frame new-window))
+      new-window)))
+
+(defun which-key--show-buffer-new-frame (frame-height frame-width)
+  "Helper for `which-key--show-buffer-frame'."
+  (let* ((frame-params `((height . ,frame-height)
+                         (width . ,frame-width)
+                         ;; tell the window manager to respect the given sizes
+                         (user-size . t)
+                         ;; which-key frame doesn't need a minibuffer
+                         (minibuffer . nil)
+                         (name . "which-key")
+                         ;; no need for scroll bars in which-key frame
+                         (vertical-scroll-bars . nil)
+                         ;; (left-fringe . 0)
+                         ;; (right-fringe . 0)
+                         ;; (right-divider-width . 0)
+                         ;; make sure frame is visible
+                         (visibility . t)))
+         (alist `((pop-up-frame-parameters . ,frame-params)))
+         (orig-frame (selected-frame))
+         (new-window (display-buffer-pop-up-frame which-key--buffer alist)))
+    (when new-window
+      ;; display successful
+      (redirect-frame-focus (window-frame new-window) orig-frame)
+      new-window)))
+
+(defun which-key--show-buffer-reuse-frame (frame-height frame-width)
+  "Helper for `which-key--show-buffer-frame'."
+  (let ((window
+         (display-buffer-reuse-window
+          which-key--buffer `((reusable-frames . ,which-key--frame)))))
+    (when window
+      ;; display successful
+      (set-frame-size (window-frame window) frame-width frame-height)
+      window)))
+
+;;; Max dimension of available window functions
+
+(defun which-key--popup-max-dimensions ()
+  "Dimesion functions should return the maximum possible (height
+. width) of the intended popup. SELECTED-WINDOW-WIDTH is the
+width of currently active window, not the which-key buffer
+window."
+  (cl-case which-key-popup-type
+    (minibuffer (which-key--minibuffer-max-dimensions))
+    (side-window (which-key--side-window-max-dimensions))
+    (frame (which-key--frame-max-dimensions))
+    (custom (funcall which-key-custom-popup-max-dimensions-function
+                     (window-width)))))
+
+(defun which-key--minibuffer-max-dimensions ()
+  "Return max-dimensions of minibuffer (height . width).
+Measured in lines and characters respectively."
+  (cons
+   ;; height
+   (if (floatp max-mini-window-height)
+       (floor (* (frame-text-lines)
+                 max-mini-window-height))
+     max-mini-window-height)
+   ;; width
+   (max 0 (- (frame-text-cols) which-key-unicode-correction))))
+
+(defun which-key--side-window-max-dimensions ()
+  "Return max-dimensions of the side-window popup (height .
+width) in lines and characters respectively."
+  (cons
+   ;; height
+   (if (member which-key-side-window-location '(left right))
+       ;; 1 is a kludge to make sure there is no overlap
+       (- (frame-height) (window-text-height (minibuffer-window)) 1)
+     ;; (window-mode-line-height which-key--window))
+     ;; FIXME: change to something like
+     ;; (min which-*-height (calculate-max-height))
+     (which-key--height-or-percentage-to-height
+      which-key-side-window-max-height))
+   ;; width
+   (max 0
+        (- (if (member which-key-side-window-location '(left right))
+               (which-key--total-width-to-text
+                (which-key--width-or-percentage-to-width
+                 which-key-side-window-max-width))
+             (which-key--total-width-to-text
+              (which-key--width-or-percentage-to-width
+               1.0)))
+           which-key-unicode-correction))))
+
+(defun which-key--frame-max-dimensions ()
+  "Return max-dimensions of the frame popup (height .
+width) in lines and characters respectively."
+  (cons which-key-frame-max-height which-key-frame-max-width))
+
+;;; Sorting functions
+
+(defun which-key--string< (a b &optional alpha)
+  (let* ((da (downcase a))
+         (db (downcase b)))
+    (cond ((string-equal da db)
+           (if which-key-sort-uppercase-first
+               (string-lessp a b)
+             (not (string-lessp a b))))
+          (alpha (string-lessp da db))
+          (t (string-lessp a b)))))
+
+(defun which-key--key-description< (a b &optional alpha)
+  "Sorting function used for `which-key-key-order' and
+`which-key-key-order-alpha'."
+  (save-match-data
+    (let* ((rngrgxp "^\\([^ ]+\\) \\.\\. [^ ]+")
+           (a (if (string-match rngrgxp a) (match-string 1 a) a))
+           (b (if (string-match rngrgxp b) (match-string 1 b) b))
+           (aem? (string-equal a ""))
+           (bem? (string-equal b ""))
+           (a1? (= 1 (length a)))
+           (b1? (= 1 (length b)))
+           (srgxp "^\\(RET\\|SPC\\|TAB\\|DEL\\|LFD\\|ESC\\|NUL\\)")
+           (asp? (string-match-p srgxp a))
+           (bsp? (string-match-p srgxp b))
+           (prrgxp "^\\(M\\|C\\|S\\|A\\|H\\|s\\)-")
+           (apr? (string-match-p prrgxp a))
+           (bpr? (string-match-p prrgxp b))
+           (afn? (string-match-p "<f[0-9]+>" a))
+           (bfn? (string-match-p "<f[0-9]+>" b)))
+      (cond ((or aem? bem?) (and aem? (not bem?)))
+            ((and asp? bsp?)
+             (if (string-equal (substring a 0 3) (substring b 0 3))
+                 (which-key--key-description<
+                  (substring a 3) (substring b 3) alpha)
+               (which-key--string< a b alpha)))
+            ((or asp? bsp?) asp?)
+            ((and a1? b1?) (which-key--string< a b alpha))
+            ((or a1? b1?) a1?)
+            ((and afn? bfn?)
+             (< (string-to-number
+                 (replace-regexp-in-string "<f\\([0-9]+\\)>" "\\1" a))
+                (string-to-number
+                 (replace-regexp-in-string "<f\\([0-9]+\\)>" "\\1" b))))
+            ((or afn? bfn?) afn?)
+            ((and apr? bpr?)
+             (if (string-equal (substring a 0 2) (substring b 0 2))
+                 (which-key--key-description<
+                  (substring a 2) (substring b 2) alpha)
+               (which-key--string< a b alpha)))
+            ((or apr? bpr?) apr?)
+            (t (which-key--string< a b alpha))))))
+
+(defsubst which-key-key-order-alpha (acons bcons)
+  "Order key descriptions A and B.
+Order is lexicographic within a \"class\", where the classes and
+the ordering of classes are listed below.
+
+special (SPC,TAB,...) < single char < mod (C-,M-,...) < other.
+Sorts single characters alphabetically with lowercase coming
+before upper."
+  (which-key--key-description< (car acons) (car bcons) t))
+
+(defsubst which-key-key-order (acons bcons)
+  "Order key descriptions A and B.
+Order is lexicographic within a \"class\", where the classes and
+the ordering of classes are listed below.
+
+special (SPC,TAB,...) < single char < mod (C-,M-,...) < other."
+  (which-key--key-description< (car acons) (car bcons)))
+
+(defsubst which-key-description-order (acons bcons)
+  "Order descriptions of A and B.
+Uses `string-lessp' after applying lowercase."
+  (string-lessp (downcase (cdr acons)) (downcase (cdr bcons))))
+
+(defsubst which-key--group-p (description)
+  (or (string-match-p "^\\(group:\\|Prefix\\)" description)
+      (keymapp (intern description))))
+
+(defun which-key-prefix-then-key-order (acons bcons)
+  "Order first by whether A and/or B is a prefix with no prefix
+coming before a prefix. Within these categories order using
+`which-key-key-order'."
+  (let ((apref? (which-key--group-p (cdr acons)))
+        (bpref? (which-key--group-p (cdr bcons))))
+    (if (not (eq apref? bpref?))
+        (and (not apref?) bpref?)
+      (which-key-key-order acons bcons))))
+
+(defun which-key-prefix-then-key-order-reverse (acons bcons)
+  "Order first by whether A and/or B is a prefix with prefix
+coming before a prefix. Within these categories order using
+`which-key-key-order'."
+  (let ((apref? (which-key--group-p (cdr acons)))
+        (bpref? (which-key--group-p (cdr bcons))))
+    (if (not (eq apref? bpref?))
+        (and apref? (not bpref?))
+      (which-key-key-order acons bcons))))
+
+(defun which-key-local-then-key-order (acons bcons)
+  "Order first by whether A and/or B is a local binding with
+local bindings coming first. Within these categories order using
+`which-key-key-order'."
+  (let ((aloc? (which-key--local-binding-p acons))
+        (bloc? (which-key--local-binding-p bcons)))
+    (if (not (eq aloc? bloc?))
+        (and aloc? (not bloc?))
+      (which-key-key-order acons bcons))))
+
+;;; Functions for retrieving and formatting keys
+
+(defsubst which-key--string-width (maybe-string)
+  "If MAYBE-STRING is a string use `which-key--string-width' o/w return 0."
+  (if (stringp maybe-string) (string-width maybe-string) 0))
+
+(defsubst which-key--safe-lookup-key (keymap key)
+  "Version of `lookup-key' that allows KEYMAP to be nil. KEY is not checked."
+  (when (keymapp keymap) (lookup-key keymap key)))
+
+(defsubst which-key--butlast-string (str)
+  (mapconcat #'identity (butlast (split-string str)) " "))
+
+(defun which-key--get-replacements (key-binding &optional use-major-mode)
+  (let ((alist (or (and use-major-mode
+                        (cdr-safe
+                         (assq major-mode which-key-replacement-alist)))
+                   which-key-replacement-alist))
+        res case-fold-search)
+    (catch 'res
+      (dolist (replacement alist)
+        ;; these are mode specific ones to ignore. The mode specific case is
+        ;; handled in the selection of alist
+        (unless (symbolp (car replacement))
+          (let ((key-regexp (caar replacement))
+                (binding-regexp (cdar replacement)))
+            (when (and (or (null key-regexp)
+                           (string-match-p key-regexp
+                                           (car key-binding)))
+                       (or (null binding-regexp)
+                           (string-match-p binding-regexp
+                                           (cdr key-binding))))
+              (push replacement res)
+              (when (not which-key-allow-multiple-replacements)
+                (throw 'res res)))))))
+    (nreverse res)))
+
+(defun which-key--get-pseudo-binding (key-binding &optional prefix)
+  (let* ((pseudo-binding
+          (key-binding (which-key--pseudo-key (kbd (car key-binding)) prefix)))
+         (pseudo-binding (when pseudo-binding (cadr pseudo-binding)))
+         (pseudo-desc (when pseudo-binding (car pseudo-binding)))
+         (pseudo-def (when pseudo-binding (cdr pseudo-binding)))
+         (real-def (key-binding (kbd (car key-binding))))
+         ;; treat keymaps as if they're nil bindings. This creates the
+         ;; possibility that we rename the wrong binding but this seems
+         ;; unlikely.
+         (real-def (unless (keymapp real-def) real-def)))
+    (when (and pseudo-binding
+               (eq pseudo-def real-def))
+      (cons (car key-binding) pseudo-desc))))
+
+(defun which-key--maybe-replace (key-binding &optional prefix)
+  "Use `which-key--replacement-alist' to maybe replace KEY-BINDING.
+KEY-BINDING is a cons cell of the form \(KEY . BINDING\) each of
+which are strings. KEY is of the form produced by `key-binding'."
+  (let* ((pseudo-binding (which-key--get-pseudo-binding key-binding prefix)))
+    (if pseudo-binding
+        pseudo-binding
+      (let* ((mode-res (which-key--get-replacements key-binding t))
+             (all-repls (or mode-res
+                            (which-key--get-replacements key-binding))))
+        (dolist (repl all-repls key-binding)
+          (setq key-binding
+                (cond ((or (not (consp repl)) (null (cdr repl)))
+                       key-binding)
+                      ((functionp (cdr repl))
+                       (funcall (cdr repl) key-binding))
+                      ((consp (cdr repl))
+                       (cons
+                        (cond ((and (caar repl) (cadr repl))
+                               (replace-regexp-in-string
+                                (caar repl) (cadr repl) (car key-binding) t))
+                              ((cadr repl) (cadr repl))
+                              (t (car key-binding)))
+                        (cond ((and (cdar repl) (cddr repl))
+                               (replace-regexp-in-string
+                                (cdar repl) (cddr repl) (cdr key-binding) t))
+                              ((cddr repl) (cddr repl))
+                              (t (cdr key-binding))))))))))))
+
+(defsubst which-key--current-key-list (&optional key-str)
+  (append (listify-key-sequence (which-key--current-prefix))
+          (when key-str
+            (listify-key-sequence (kbd key-str)))))
+
+(defsubst which-key--current-key-string (&optional key-str)
+  (key-description (which-key--current-key-list key-str)))
+
+(defun which-key--local-binding-p (keydesc)
+  (eq (which-key--safe-lookup-key
+       (current-local-map) (kbd (which-key--current-key-string (car keydesc))))
+      (intern (cdr keydesc))))
+
+(defun which-key--map-binding-p (map keydesc)
+  "Does MAP contain KEYDESC = (key . binding)?"
+  (or
+   (when (bound-and-true-p evil-state)
+     (let ((lookup
+            (which-key--safe-lookup-key
+             map
+             (kbd (which-key--current-key-string
+                   (format "<%s-state> %s" evil-state (car keydesc)))))))
+       (or (eq lookup (intern (cdr keydesc)))
+           (and (keymapp lookup) (string= (cdr keydesc) "Prefix Command")))))
+   (let ((lookup
+          (which-key--safe-lookup-key
+           map (kbd (which-key--current-key-string (car keydesc))))))
+     (or (eq lookup (intern (cdr keydesc)))
+         (and (keymapp lookup) (string= (cdr keydesc) "Prefix Command"))))))
+
+(defun which-key--pseudo-key (key &optional prefix)
+  "Replace the last key in the sequence KEY by a special symbol
+in order for which-key to allow looking up a description for the key."
+  (let* ((seq (listify-key-sequence key))
+         (final (intern (format "which-key-%s" (key-description (last seq))))))
+    (if prefix
+        (vconcat prefix (list final))
+      (vconcat (butlast seq) (list final)))))
+
+(defun which-key--maybe-get-prefix-title (keys)
+  "KEYS is a string produced by `key-description'.
+A title is possibly returned using
+`which-key--prefix-title-alist'.  An empty stiring is returned if
+no title exists."
+  (cond
+   ((not (string-equal keys ""))
+    (let* ((title-res
+            (cdr-safe (assoc-string keys which-key--prefix-title-alist)))
+           (repl-res
+            (cdr-safe (which-key--maybe-replace (cons keys ""))))
+           (binding (key-binding (kbd keys)))
+           (alternate (when (and binding (symbolp binding))
+                        (symbol-name binding))))
+      (cond (title-res title-res)
+            ((not (string-equal repl-res "")) repl-res)
+            ((and (eq which-key-show-prefix 'echo) alternate)
+             alternate)
+            ((and (member which-key-show-prefix '(bottom top))
+                  (eq which-key-side-window-location 'bottom)
+                  echo-keystrokes)
+             (if alternate alternate
+               (concat "Following " keys)))
+            (t ""))))
+   (t "")))
+
+(defun which-key--propertize (string &rest properties)
+  "Version of `propertize' that checks type of STRING."
+  (when (stringp string)
+    (apply #'propertize string properties)))
+
+(defun which-key--propertize-key (key)
+  "Add a face to KEY.
+If KEY contains any \"special keys\" defined in
+`which-key-special-keys' then truncate and add the corresponding
+`which-key-special-key-face'."
+  (let ((key-w-face (which-key--propertize key 'face 'which-key-key-face))
+        (regexp (concat "\\("
+                        (mapconcat 'identity which-key-special-keys
+                                   "\\|") "\\)"))
+        case-fold-search)
+    (save-match-data
+      (if (and which-key-special-keys
+               (string-match regexp key))
+          (let ((beg (match-beginning 0)) (end (match-end 0)))
+            (concat (substring key-w-face 0 beg)
+                    (which-key--propertize (substring key-w-face beg (1+ beg))
+                                'face 'which-key-special-key-face)
+                    (substring key-w-face end
+                               (which-key--string-width key-w-face))))
+        key-w-face))))
+
+(defsubst which-key--truncate-description (desc)
+  "Truncate DESC description to `which-key-max-description-length'."
+  (let* ((last-face (get-text-property (1- (length desc)) 'face desc))
+         (dots (which-key--propertize ".." 'face last-face)))
+    (if (and which-key-max-description-length
+             (> (length desc) which-key-max-description-length))
+        (concat (substring desc 0 which-key-max-description-length) dots)
+      desc)))
+
+(defun which-key--highlight-face (description)
+  "Return the highlight face for DESCRIPTION if it has one."
+  (let (face)
+    (dolist (el which-key-highlighted-command-list)
+      (unless face
+        (cond ((consp el)
+               (when (string-match-p (car el) description)
+                 (setq face (cdr el))))
+              ((stringp el)
+               (when (string-match-p el description)
+                 (setq face 'which-key-highlighted-command-face)))
+              (t
+               (message "which-key: warning: element %s of \
+which-key-highlighted-command-list is not a string or a cons
+cell" el)))))
+    face))
+
+(defun which-key--propertize-description
+    (description group local hl-face &optional original-description)
+  "Add face to DESCRIPTION where the face chosen depends on
+whether the description represents a group or a command. Also
+make some minor adjustments to the description string, like
+removing a \"group:\" prefix.
+
+ORIGINAL-DESCRIPTION is the description given by
+`describe-buffer-bindings'."
+  (when description
+    (let* ((desc description)
+           (desc (if (string-match-p "^group:" desc)
+                     (substring desc 6) desc))
+           (desc (if group (concat which-key-prefix-prefix desc) desc)))
+      (make-text-button
+       desc nil
+       'face (cond (hl-face hl-face)
+                   (group 'which-key-group-description-face)
+                   (local 'which-key-local-map-description-face)
+                   (t 'which-key-command-description-face))
+       'help-echo (cond
+                   ((and original-description
+                         (fboundp (intern original-description))
+                         (documentation (intern original-description))
+                         ;; tooltip-mode doesn't exist in emacs-nox
+                         (boundp 'tooltip-mode) tooltip-mode)
+                    (documentation (intern original-description)))
+                   ((and original-description
+                         (fboundp (intern original-description))
+                         (documentation (intern original-description))
+                         (let* ((doc (documentation
+                                      (intern original-description)))
+                                (str (replace-regexp-in-string "\n" " " doc))
+                                (max (floor (* (frame-width) 0.8))))
+                           (if (> (length str) max)
+                               (concat (substring str 0 max) "...")
+                             str))))))
+      desc)))
+
+(defun which-key--extract-key (key-str)
+  "Pull the last key (or key range) out of KEY-STR."
+  (save-match-data
+    (let ((key-range-regexp "\\`.*\\([^ \t]+ \\.\\. [^ \t]+\\)\\'"))
+      (if (string-match key-range-regexp key-str)
+          (match-string 1 key-str)
+        (car (last (split-string key-str " ")))))))
+
+(defun which-key--maybe-add-docstring (current original)
+  "Maybe concat a docstring to CURRENT and return result.
+Specifically, do this if ORIGINAL is a command with a docstring
+and `which-key-show-docstrings' is non-nil. If
+`which-key-show-docstrings' is the symbol docstring-only, just
+return the docstring."
+  (let* ((orig-sym (intern original))
+         (doc (when (commandp orig-sym)
+                (documentation orig-sym)))
+         (docstring (when doc
+                      (which-key--propertize (car (split-string doc "\n"))
+                                             'face 'which-key-docstring-face))))
+    (cond ((not (and which-key-show-docstrings docstring))
+           current)
+          ((eq which-key-show-docstrings 'docstring-only)
+           docstring)
+          (t
+           (format "%s %s" current docstring)))))
+
+(defun which-key--format-and-replace (unformatted &optional prefix preserve-full-key)
+  "Take a list of (key . desc) cons cells in UNFORMATTED, add
+faces and perform replacements according to the three replacement
+alists. Returns a list (key separator description)."
+  (let ((sep-w-face
+         (which-key--propertize which-key-separator
+                                'face 'which-key-separator-face))
+        (local-map (current-local-map))
+        new-list)
+    (dolist (key-binding unformatted)
+      (let* ((key (car key-binding))
+             (orig-desc (cdr key-binding))
+             (group (which-key--group-p orig-desc))
+             ;; At top-level prefix is nil
+             (keys (if prefix
+                       (concat (key-description prefix) " " key)
+                     key))
+             (local (eq (which-key--safe-lookup-key local-map (kbd keys))
+                        (intern orig-desc)))
+             (hl-face (which-key--highlight-face orig-desc))
+             (key-binding (which-key--maybe-replace (cons keys orig-desc) prefix))
+             (final-desc (which-key--propertize-description
+                          (cdr key-binding) group local hl-face orig-desc)))
+        (when final-desc
+          (setq final-desc
+                (which-key--truncate-description
+                 (which-key--maybe-add-docstring final-desc orig-desc))))
+        (when (consp key-binding)
+          (push
+           (list (which-key--propertize-key
+                  (if preserve-full-key
+                      (car key-binding)
+                    (which-key--extract-key (car key-binding))))
+                 sep-w-face
+                 final-desc)
+           new-list))))
+    (nreverse new-list)))
+
+(defun which-key--get-keymap-bindings (keymap &optional all prefix)
+  "Retrieve top-level bindings from KEYMAP.
+If ALL is non-nil, get all bindings, not just the top-level
+ones. PREFIX is for internal use and should not be used."
+  (let (bindings)
+    (map-keymap
+     (lambda (ev def)
+       (let* ((key (append prefix (list ev)))
+              (key-desc (key-description key)))
+         (cond ((or (string-match-p
+                     which-key--ignore-non-evil-keys-regexp key-desc)
+                    (eq ev 'menu-bar)))
+               ;; extract evil keys corresponding to current state
+               ((and (keymapp def)
+                     (boundp 'evil-state)
+                     (bound-and-true-p evil-local-mode)
+                     (string-match-p (format "<%s-state>$" evil-state) key-desc))
+                (setq bindings
+                      ;; this function keeps the latter of the two duplicates
+                      ;; which will be the evil binding
+                      (cl-remove-duplicates
+                       (append bindings
+                               (which-key--get-keymap-bindings def all prefix))
+                       :test (lambda (a b) (string= (car a) (car b))))))
+               ((and (keymapp def)
+                     (string-match-p which-key--evil-keys-regexp key-desc)))
+               ((and (keymapp def)
+                     (or all
+                         ;; event 27 is escape, so this will pick up meta
+                         ;; bindings and hopefully not too much more
+                         (and (numberp ev) (= ev 27))))
+                (setq bindings
+                      (append bindings
+                              (which-key--get-keymap-bindings def t key))))
+               (t
+                (when def
+                  (cl-pushnew
+                   (cons key-desc
+                         (cond
+                          ((keymapp def) "Prefix Command")
+                          ((symbolp def) (copy-sequence (symbol-name def)))
+                          ((eq 'lambda (car-safe def)) "lambda")
+                          ((eq 'menu-item (car-safe def)) "menu-item")
+                          ((stringp def) def)
+                          (t "unknown")))
+                   bindings :test (lambda (a b) (string= (car a) (car b)))))))))
+     keymap)
+    bindings))
+
+(defun which-key--compute-binding (binding)
+  "Replace BINDING with remapped binding if it exists.
+
+Requires `which-key-compute-remaps' to be non-nil"
+  (let (remap)
+    (if (and which-key-compute-remaps
+             (setq remap (command-remapping (intern binding))))
+        (copy-sequence (symbol-name remap))
+      binding)))
+
+(defun which-key--get-current-bindings (&optional prefix)
+  "Generate a list of current active bindings."
+  (let ((key-str-qt (regexp-quote (key-description prefix)))
+        (buffer (current-buffer))
+        (ignore-bindings '("self-insert-command" "ignore"
+                           "ignore-event" "company-ignore"))
+        (ignore-sections-regexp
+         (eval-when-compile
+           (regexp-opt '("Key translations" "Function key map translations"
+                         "Input decoding map translations")))))
+    (with-temp-buffer
+      (setq-local indent-tabs-mode t)
+      (setq-local tab-width 8)
+      (describe-buffer-bindings buffer prefix)
+      (goto-char (point-min))
+      (let ((header-p (not (= (char-after) ?\f)))
+            bindings header)
+        (while (not (eobp))
+          (cond
+           (header-p
+            (setq header (buffer-substring-no-properties
+                          (point)
+                          (line-end-position)))
+            (setq header-p nil)
+            (forward-line 3))
+           ((= (char-after) ?\f)
+            (setq header-p t))
+           ((looking-at "^[ \t]*$"))
+           ((or (not (string-match-p ignore-sections-regexp header)) prefix)
+            (let ((binding-start (save-excursion
+                                   (and (re-search-forward "\t+" nil t)
+                                        (match-end 0))))
+                  key binding)
+              (when binding-start
+                (setq key (buffer-substring-no-properties
+                           (point) binding-start))
+                (setq binding (buffer-substring-no-properties
+                               binding-start
+                               (line-end-position)))
+                (save-match-data
+                  (cond
+                   ((member binding ignore-bindings))
+                   ((string-match-p which-key--ignore-keys-regexp key))
+                   ((and prefix
+                         (string-match (format "^%s[ \t]\\([^ \t]+\\)[ \t]+$"
+                                               key-str-qt) key))
+                    (unless (assoc-string (match-string 1 key) bindings)
+                      (push (cons (match-string 1 key)
+                                  (which-key--compute-binding binding))
+                            bindings)))
+                   ((and prefix
+                         (string-match
+                          (format
+                           "^%s[ \t]\\([^ \t]+\\) \\.\\. %s[ \t]\\([^ \t]+\\)[ \t]+$"
+                           key-str-qt key-str-qt) key))
+                    (let ((stripped-key (concat (match-string 1 key)
+                                                " \.\. "
+                                                (match-string 2 key))))
+                      (unless (assoc-string stripped-key bindings)
+                        (push (cons stripped-key
+                                    (which-key--compute-binding binding))
+                              bindings))))
+                   ((string-match
+                     "^\\([^ \t]+\\|[^ \t]+ \\.\\. [^ \t]+\\)[ \t]+$" key)
+                    (unless (assoc-string (match-string 1 key) bindings)
+                      (push (cons (match-string 1 key)
+                                  (which-key--compute-binding binding))
+                            bindings)))))))))
+          (forward-line))
+        (nreverse bindings)))))
+
+(defun which-key--get-bindings (&optional prefix keymap filter recursive)
+  "Collect key bindings.
+If KEYMAP is nil, collect from current buffer using the current
+key sequence as a prefix. Otherwise, collect from KEYMAP. FILTER
+is a function to use to filter the bindings. If RECURSIVE is
+non-nil, then bindings are collected recursively for all prefixes."
+  (let* ((unformatted
+          (cond ((keymapp keymap)
+                 (which-key--get-keymap-bindings keymap recursive))
+                (keymap
+                 (error "%s is not a keymap" keymap))
+                (t
+                 (which-key--get-current-bindings prefix)))))
+    (when filter
+      (setq unformatted (cl-remove-if-not filter unformatted)))
+    (when which-key-sort-order
+      (setq unformatted
+            (sort unformatted which-key-sort-order)))
+    (which-key--format-and-replace unformatted prefix recursive)))
+
+;;; Functions for laying out which-key buffer pages
+
+(defun which-key--normalize-columns (columns)
+  "Pad COLUMNS to the same length using empty strings."
+  (let ((max-len (cl-reduce (lambda (a x) (max a (length x))) columns
+                            :initial-value 0)))
+    (mapcar
+     (lambda (c)
+       (if (< (length c) max-len)
+           (append c (make-list (- max-len (length c)) ""))
+         c))
+     columns)))
+
+(defsubst which-key--join-columns (columns)
+  "Transpose columns into rows, concat rows into lines and rows into page."
+  (let* ((padded (which-key--normalize-columns (nreverse columns)))
+         (rows (apply #'cl-mapcar #'list padded)))
+    (mapconcat (lambda (row) (mapconcat #'identity row " ")) rows "\n")))
+
+(defsubst which-key--max-len (keys index)
+  "Internal function for finding the max length of the INDEX
+element in each list element of KEYS."
+  (cl-reduce
+   (lambda (x y) (max x (which-key--string-width (nth index y))))
+   keys :initial-value 0))
+
+(defun which-key--pad-column (col-keys)
+  "Take a column of (key separator description) COL-KEYS,
+calculate the max width in the column and pad all cells out to
+that width."
+  (let* ((col-key-width  (+ which-key-add-column-padding
+                            (which-key--max-len col-keys 0)))
+         (col-sep-width  (which-key--max-len col-keys 1))
+         (col-desc-width (which-key--max-len col-keys 2))
+         (col-width      (+ 1 col-key-width col-sep-width col-desc-width)))
+    (cons col-width
+          (mapcar (lambda (k)
+                    (format (concat "%" (int-to-string col-key-width)
+                                    "s%s%-" (int-to-string col-desc-width) "s")
+                            (nth 0 k) (nth 1 k) (nth 2 k)))
+                  col-keys))))
+
+(defun which-key--partition-list (n list)
+  "Partition LIST into N-sized sublists."
+  (let (res)
+    (while list
+      (setq res (cons (cl-subseq list 0 (min n (length list))) res)
+            list (nthcdr n list)))
+    (nreverse res)))
+
+(defun which-key--list-to-pages (keys avl-lines avl-width)
+  "Convert list of KEYS to columns based on dimensions AVL-LINES and AVL-WIDTH.
+Returns a `which-key--pages' object that holds the page strings,
+as well as metadata."
+  (let ((cols-w-widths (mapcar #'which-key--pad-column
+                               (which-key--partition-list avl-lines keys)))
+        (page-width 0) (n-pages 0) (n-keys 0) (n-columns 0)
+        page-cols pages page-widths keys/page col)
+    (if (> (apply #'max (mapcar #'car cols-w-widths)) avl-width)
+        ;; give up if no columns fit
+        nil
+      (while cols-w-widths
+        ;; start new page
+        (cl-incf n-pages)
+        (setq col (pop cols-w-widths))
+        (setq page-cols (list (cdr col)))
+        (setq page-width (car col))
+        (setq n-keys (length (cdr col)))
+        (setq n-columns 1)
+        ;; add additional columns as long as they fit
+        (while (and cols-w-widths
+                    (or (null which-key-max-display-columns)
+                        (< n-columns which-key-max-display-columns))
+                    (<= (+ (caar cols-w-widths) page-width) avl-width))
+          (setq col (pop cols-w-widths))
+          (push (cdr col) page-cols)
+          (cl-incf page-width (car col))
+          (cl-incf n-keys (length (cdr col)))
+          (cl-incf n-columns))
+        (push (which-key--join-columns page-cols) pages)
+        (push n-keys keys/page)
+        (push page-width page-widths))
+      (make-which-key--pages
+       :pages (nreverse pages)
+       :height avl-lines
+       :widths (nreverse page-widths)
+       :keys/page (reverse keys/page)
+       :page-nums (number-sequence 1 n-pages)
+       :num-pages n-pages
+       :total-keys (apply #'+ keys/page)))))
+
+(defun which-key--create-pages-1
+    (keys available-lines available-width &optional min-lines vertical)
+  "Create page strings using `which-key--list-to-pages'.
+Will try to find the best number of rows and columns using the
+given dimensions and the length and widths of ITEMS. Use VERTICAL
+if the ITEMS are laid out vertically and the number of columns
+should be minimized."
+  (let ((result (which-key--list-to-pages
+                 keys available-lines available-width))
+        (min-lines (or min-lines 0))
+        found prev-result)
+    (if (or (null result)
+            vertical
+            (> (which-key--pages-num-pages result) 1)
+            (= 1 available-lines))
+        result
+      ;; simple search for a fitting page
+      (while (and (> available-lines min-lines)
+                  (not found))
+        (setq available-lines (- available-lines 1)
+              prev-result result
+              result (which-key--list-to-pages
+                      keys available-lines available-width)
+              found (> (which-key--pages-num-pages result) 1)))
+      (if found prev-result result))))
+
+(defun which-key--create-pages (keys &optional prefix-keys prefix-title)
+  "Create page strings using `which-key--list-to-pages'.
+Will try to find the best number of rows and columns using the
+given dimensions and the length and wdiths of KEYS. SEL-WIN-WIDTH
+is the width of the live window."
+  (let* ((max-dims (which-key--popup-max-dimensions))
+         (max-lines (car max-dims))
+         (max-width (cdr max-dims))
+         (prefix-desc (key-description prefix-keys))
+         (full-prefix (which-key--full-prefix prefix-desc))
+         (prefix (when (eq which-key-show-prefix 'left)
+                   (+ 2 (which-key--string-width full-prefix))))
+         (prefix-top-bottom (member which-key-show-prefix '(bottom top)))
+         (avl-lines (if prefix-top-bottom (- max-lines 1) max-lines))
+         (min-lines (min avl-lines which-key-min-display-lines))
+         (avl-width (if prefix (- max-width prefix) max-width))
+         (vertical (and (eq which-key-popup-type 'side-window)
+                        (member which-key-side-window-location '(left right))))
+         result)
+    (setq result
+          (which-key--create-pages-1
+           keys avl-lines avl-width min-lines vertical))
+    (when (and result
+               (> (which-key--pages-num-pages result) 0))
+      (setf (which-key--pages-prefix result) prefix-keys)
+      (setf (which-key--pages-prefix-title result)
+            (or prefix-title
+                (which-key--maybe-get-prefix-title
+                 (key-description prefix-keys))))
+      result)))
+
+(defun which-key--lighter-status ()
+  "Possibly show number of keys and total in the mode line."
+  (when which-key-show-remaining-keys
+    (let ((n-shown (car (which-key--pages-keys/page which-key--pages-obj)))
+          (n-tot (which-key--pages-total-keys which-key--pages-obj)))
+      (setcar (cdr (assq 'which-key-mode minor-mode-alist))
+              (format " WK: %s/%s keys" n-shown n-tot)))))
+
+(defun which-key--lighter-restore ()
+  "Restore the lighter for which-key."
+  (when which-key-show-remaining-keys
+    (setcar (cdr (assq 'which-key-mode minor-mode-alist))
+            which-key-lighter)))
+
+(defun which-key--echo (text)
+  "Echo TEXT to minibuffer without logging."
+  (let (message-log-max)
+    (message "%s" text)))
+
+(defun which-key--next-page-hint (prefix-keys)
+  "Return string for next page hint."
+  (let* ((paging-key (concat prefix-keys " " which-key-paging-key))
+         (paging-key-bound (eq 'which-key-C-h-dispatch
+                               (key-binding (kbd paging-key))))
+         (key (if paging-key-bound which-key-paging-key "C-h")))
+    (when which-key-use-C-h-commands
+      (which-key--propertize (format "[%s paging/help]" key)
+                             'face 'which-key-note-face))))
+
+(eval-and-compile
+  (if (fboundp 'universal-argument--description)
+      (defalias 'which-key--universal-argument--description
+        'universal-argument--description)
+    (defun which-key--universal-argument--description ()
+      ;; Backport of the definition of universal-argument--description in
+      ;; emacs25 on 2015-12-04
+      (when prefix-arg
+        (concat "C-u"
+                (pcase prefix-arg
+                  (`(-) " -")
+                  (`(,(and (pred integerp) n))
+                   (let ((str ""))
+                     (while (and (> n 4) (= (mod n 4) 0))
+                       (setq str (concat str " C-u"))
+                       (setq n (/ n 4)))
+                     (if (= n 4) str (format " %s" prefix-arg))))
+                  (_ (format " %s" prefix-arg))))))))
+
+(defun which-key--full-prefix (prefix-keys &optional -prefix-arg dont-prop-keys)
+  "Return a description of the full key sequence up to now,
+including prefix arguments."
+  (let* ((left (eq which-key-show-prefix 'left))
+         (prefix-arg (if -prefix-arg -prefix-arg prefix-arg))
+         (str (concat
+               (which-key--universal-argument--description)
+               (when prefix-arg " ")
+               prefix-keys))
+         (dash (if (and (not (string= prefix-keys ""))
+                        (null left)) "-" "")))
+    (if (or (eq which-key-show-prefix 'echo) dont-prop-keys)
+        (concat str dash)
+      (concat (which-key--propertize-key str)
+              (which-key--propertize dash 'face 'which-key-key-face)))))
+
+(defun which-key--get-popup-map ()
+  "Generate transient-map for use in the top level binding display."
+  (unless which-key--automatic-display
+    (let ((map (make-sparse-keymap)))
+      (define-key map (kbd which-key-paging-key) #'which-key-C-h-dispatch)
+      (when which-key-use-C-h-commands
+        ;; Show next page even when C-h is pressed
+        (define-key map (kbd "C-h") #'which-key-C-h-dispatch))
+      map)))
+
+(defun which-key--process-page (pages-obj)
+  "Add information to the basic list of key bindings, including
+if applicable the current prefix, the name of the current prefix,
+and a page count."
+  (let* ((page (car (which-key--pages-pages pages-obj)))
+         (height (which-key--pages-height pages-obj))
+         (n-pages (which-key--pages-num-pages pages-obj))
+         (page-n (car (which-key--pages-page-nums pages-obj)))
+         (prefix-desc (key-description (which-key--pages-prefix pages-obj)))
+         (prefix-title (which-key--pages-prefix-title pages-obj))
+         (full-prefix (which-key--full-prefix prefix-desc))
+         (nxt-pg-hint (which-key--next-page-hint prefix-desc))
+         ;; not used in left case
+         (status-line
+          (concat (which-key--propertize prefix-title 'face 'which-key-note-face)
+                  (when (< 1 n-pages)
+                    (which-key--propertize (format " (%s of %s)" page-n n-pages)
+                                           'face 'which-key-note-face)))))
+    (pcase which-key-show-prefix
+      (`left
+       (let* ((page-cnt (which-key--propertize (format "%s/%s" page-n n-pages)
+                                               'face 'which-key-separator-face))
+              (first-col-width (+ 2 (max (which-key--string-width full-prefix)
+                                         (which-key--string-width page-cnt))))
+              (prefix (format (concat "%-" (int-to-string first-col-width) "s")
+                              full-prefix))
+              (page-cnt (if (> n-pages 1)
+                            (format
+                             (concat "%-" (int-to-string first-col-width) "s")
+                             page-cnt)
+                          (make-string first-col-width 32)))
+              lines first-line new-end)
+         (if (= 1 height)
+             (cons (concat prefix page) nil)
+           (setq lines (split-string page "\n")
+                 first-line (concat prefix (car lines) "\n" page-cnt)
+                 new-end (concat "\n" (make-string first-col-width 32)))
+           (cons
+            (concat first-line (mapconcat #'identity (cdr lines) new-end))
+            nil))))
+      (`top
+       (cons
+        (concat (when (or (= 0 echo-keystrokes)
+                          (not (eq which-key-side-window-location 'bottom)))
+                  (concat full-prefix " "))
+                status-line " " nxt-pg-hint "\n" page)
+        nil))
+      (`bottom
+       (cons
+        (concat page "\n"
+                (when (or (= 0 echo-keystrokes)
+                          (not (eq which-key-side-window-location 'bottom)))
+                  (concat full-prefix " "))
+                status-line " " nxt-pg-hint)
+        nil))
+      (`echo
+       (cons page
+             (lambda ()
+               (which-key--echo
+                (concat full-prefix (when prefix-desc " ")
+                        status-line (when status-line " ")
+                        nxt-pg-hint)))))
+      (`mode-line
+       (cons page
+             (lambda ()
+               (with-current-buffer which-key--buffer
+                 (setq-local mode-line-format
+                             (concat " " full-prefix
+                                     " " status-line
+                                     " " nxt-pg-hint))))))
+      (_ (cons page nil)))))
+
+(defun which-key--show-page (&optional n)
+  "Show current page. N changes the current page to the Nth page
+relative to the current one."
+  (which-key--init-buffer) ;; in case it was killed
+  (let ((prefix-keys (which-key--current-key-string))
+        golden-ratio-mode)
+    (if (null which-key--pages-obj)
+        (message "%s- which-key can't show keys: There is not \
+enough space based on your settings and frame size." prefix-keys)
+      (when n
+        (setq which-key--pages-obj
+              (which-key--pages-set-current-page which-key--pages-obj n)))
+      (let ((page-echo (which-key--process-page which-key--pages-obj))
+            (height (which-key--pages-height which-key--pages-obj))
+            (width (car (which-key--pages-widths which-key--pages-obj))))
+        (which-key--lighter-status)
+        (if (eq which-key-popup-type 'minibuffer)
+            (which-key--echo (car page-echo))
+          (with-current-buffer which-key--buffer
+            (erase-buffer)
+            (insert (car page-echo))
+            (goto-char (point-min)))
+          (when (cdr page-echo) (funcall (cdr page-echo)))
+          (which-key--show-popup (cons height width)))))
+    ;; used for paging at top-level
+    (if (fboundp 'set-transient-map)
+        (set-transient-map (which-key--get-popup-map))
+      (with-no-warnings
+        (set-temporary-overlay-map (which-key--get-popup-map))))))
+
+;;; Paging functions
+
+;;;###autoload
+(defun which-key-reload-key-sequence (&optional key-seq)
+  "Simulate entering the key sequence KEY-SEQ.
+KEY-SEQ should be a list of events as produced by
+`listify-key-sequence'. If nil, KEY-SEQ defaults to
+`which-key--current-key-list'. Any prefix arguments that were
+used are reapplied to the new key sequence."
+  (let* ((key-seq (or key-seq (which-key--current-key-list)))
+         (next-event (mapcar (lambda (ev) (cons t ev)) key-seq)))
+    (setq prefix-arg current-prefix-arg
+          unread-command-events next-event)))
+
+(defun which-key-turn-page (delta)
+  "Show the next page of keys."
+  (which-key-reload-key-sequence)
+  (if which-key--last-try-2-loc
+      (let ((which-key-side-window-location which-key--last-try-2-loc)
+            (which-key--multiple-locations t))
+        (which-key--show-page delta))
+    (which-key--show-page delta))
+  (which-key--start-paging-timer))
+
+;;;###autoload
+(defun which-key-show-standard-help (&optional _)
+  "Call the command in `which-key--prefix-help-cmd-backup'.
+Usually this is `describe-prefix-bindings'."
+  (interactive)
+  (let ((which-key-inhibit t))
+    (which-key--hide-popup-ignore-command)
+    (cond ((eq which-key--prefix-help-cmd-backup
+               'describe-prefix-bindings)
+           ;; This is essentially what `describe-prefix-bindings' does
+           (describe-bindings
+            (kbd (which-key--current-key-string))))
+          ((functionp which-key--prefix-help-cmd-backup)
+           (funcall which-key--prefix-help-cmd-backup)))))
+
+;;;###autoload
+(defun which-key-show-next-page-no-cycle ()
+  "Show next page of keys unless on the last page, in which case
+call `which-key-show-standard-help'."
+  (interactive)
+  (let ((which-key-inhibit t))
+    (if (which-key--on-last-page)
+        (which-key-show-standard-help)
+      (which-key-turn-page 1))))
+
+;;;###autoload
+(defun which-key-show-previous-page-no-cycle ()
+  "Show previous page of keys unless on the first page, in which
+case do nothing."
+  (interactive)
+  (let ((which-key-inhibit t))
+    (unless (which-key--on-first-page)
+      (which-key-turn-page -1))))
+
+;;;###autoload
+(defun which-key-show-next-page-cycle (&optional _)
+  "Show the next page of keys, cycling from end to beginning
+after last page."
+  (interactive)
+  (let ((which-key-inhibit t))
+    (which-key-turn-page 1)))
+
+;;;###autoload
+(defun which-key-show-previous-page-cycle (&optional _)
+  "Show the previous page of keys, cycling from beginning to end
+after first page."
+  (interactive)
+  (let ((which-key-inhibit t))
+    (which-key-turn-page -1)))
+
+;;;###autoload
+(defun which-key-show-top-level (&optional _)
+  "Show top-level bindings."
+  (interactive)
+  (which-key--create-buffer-and-show nil nil nil "Top-level bindings"))
+
+;;;###autoload
+(defun which-key-show-major-mode ()
+  "Show top-level bindings in the map of the current major mode.
+
+This function will also detect evil bindings made using
+`evil-define-key' in this map. These bindings will depend on the
+current evil state. "
+  (interactive)
+  (let ((map-sym (intern (format "%s-map" major-mode))))
+    (if (and (boundp map-sym) (keymapp (symbol-value map-sym)))
+        (which-key--create-buffer-and-show
+         nil nil
+         (apply-partially #'which-key--map-binding-p (symbol-value map-sym))
+         "Major-mode bindings")
+      (message "which-key: No map named %s" map-sym))))
+
+;;;###autoload
+(defun which-key-undo-key (&optional _)
+  "Undo last keypress and force which-key update."
+  (interactive)
+  (let* ((key-lst (butlast (which-key--current-key-list)))
+         (which-key-inhibit t))
+    (cond (which-key--prior-show-keymap-args
+           (if (keymapp (cdr (car-safe which-key--prior-show-keymap-args)))
+               (let ((args (pop which-key--prior-show-keymap-args)))
+                 (which-key--show-keymap (car args) (cdr args)))
+             (which-key--hide-popup)))
+          (key-lst
+           (which-key-reload-key-sequence key-lst)
+           (which-key--create-buffer-and-show (apply #'vector key-lst)))
+          (t (setq which-key--automatic-display nil)
+             (which-key-show-top-level)))))
+(defalias 'which-key-undo 'which-key-undo-key)
+
+(defun which-key-abort (&optional _)
+  "Abort key sequence."
+  (interactive)
+  (let ((which-key-inhibit t))
+    (which-key--hide-popup-ignore-command)
+    (keyboard-quit)))
+
+(defun which-key-digit-argument (key)
+  "Version of `digit-argument' for use in `which-key-C-h-map'."
+  (interactive)
+  (let ((last-command-event (string-to-char key)))
+    (digit-argument key))
+  (let ((current-prefix-arg prefix-arg))
+    (which-key-reload-key-sequence)))
+
+(defun which-key-toggle-docstrings (&optional _)
+  "Toggle the display of docstrings."
+  (interactive)
+  (unless (eq which-key-show-docstrings 'docstring-only)
+    (setq which-key-show-docstrings (null which-key-show-docstrings)))
+  (which-key-reload-key-sequence)
+  (which-key--create-buffer-and-show (which-key--current-prefix)))
+
+;;;###autoload
+(defun which-key-C-h-dispatch ()
+  "Dispatch C-h commands by looking up key in
+`which-key-C-h-map'. This command is always accessible (from any
+prefix) if `which-key-use-C-h-commands' is non nil."
+  (interactive)
+  (if (not (which-key--popup-showing-p))
+      (which-key-show-standard-help)
+    (let* ((prefix-keys (which-key--current-key-string))
+           (full-prefix (which-key--full-prefix prefix-keys current-prefix-arg t))
+           (prompt (concat (when (string-equal prefix-keys "")
+                             (which-key--propertize
+                              (concat " "
+                                      (which-key--pages-prefix-title
+                                       which-key--pages-obj))
+                              'face 'which-key-note-face))
+                           full-prefix
+                           (which-key--propertize
+                            (substitute-command-keys
+                             (concat
+                              " \\<which-key-C-h-map>"
+                              " \\[which-key-show-next-page-cycle]"
+                              which-key-separator "next-page,"
+                              " \\[which-key-show-previous-page-cycle]"
+                              which-key-separator "previous-page,"
+                              " \\[which-key-undo-key]"
+                              which-key-separator "undo-key,"
+                              " \\[which-key-toggle-docstrings]"
+                              which-key-separator "toggle-docstrings,"
+                              " \\[which-key-show-standard-help]"
+                              which-key-separator "help,"
+                              " \\[which-key-abort]"
+                              which-key-separator "abort"
+                              " 1..9"
+                              which-key-separator "digit-arg"))
+                            'face 'which-key-note-face)))
+           (key (string (read-key prompt)))
+           (cmd (lookup-key which-key-C-h-map key))
+           (which-key-inhibit t))
+      (if cmd (funcall cmd key) (which-key-turn-page 0)))))
+
+;;; Update
+
+(defun which-key--any-match-p (regexps string)
+  "Non-nil if any of REGEXPS match STRING."
+  (catch 'match
+    (dolist (regexp regexps)
+      (when (string-match-p regexp string)
+        (throw 'match t)))))
+
+(defun which-key--try-2-side-windows
+    (bindings prefix-keys prefix-title loc1 loc2 &rest _ignore)
+  "Try to show BINDINGS (PAGE-N) in LOC1 first.
+
+Only if no bindings fit fallback to LOC2."
+  (let (pages1)
+    (let ((which-key-side-window-location loc1)
+          (which-key--multiple-locations t))
+      (setq pages1 (which-key--create-pages
+                    bindings prefix-keys prefix-title)))
+    (if pages1
+        (progn
+          (setq which-key--pages-obj pages1)
+          (let ((which-key-side-window-location loc1)
+                (which-key--multiple-locations t))
+            (which-key--show-page))
+          loc1)
+      (let ((which-key-side-window-location loc2)
+            (which-key--multiple-locations t))
+        (setq which-key--pages-obj
+              (which-key--create-pages bindings prefix-keys prefix-title))
+        (which-key--show-page)
+        loc2))))
+
+(defun which-key--read-keymap ()
+  "Read keymap symbol from minibuffer."
+  (intern
+   (completing-read "Keymap: " obarray
+                    (lambda (m)
+                      (and (boundp m)
+                           (keymapp (symbol-value m))
+                           (not (equal (symbol-value m)
+                                       (make-sparse-keymap)))))
+                    t
+                    (let ((sym (symbol-at-point)))
+                      (and (boundp sym)
+                           (keymapp (symbol-value sym))
+                           (symbol-name sym)))
+                    'which-key-keymap-history)))
+
+;;;###autoload
+(defun which-key-show-keymap (keymap)
+  "Show the top-level bindings in KEYMAP using which-key. KEYMAP
+is selected interactively from all available keymaps."
+  (interactive (list (which-key--read-keymap)))
+  (which-key--show-keymap (symbol-name keymap)
+                          (symbol-value keymap)))
+
+;;;###autoload
+(defun which-key-show-full-keymap (keymap)
+  "Show all bindings in KEYMAP using which-key. KEYMAP is
+selected interactively from all available keymaps."
+  (interactive (list (which-key--read-keymap)))
+  (which-key--show-keymap (symbol-name keymap)
+                          (symbol-value keymap)
+                          nil t))
+
+;;;###autoload
+(defun which-key-show-minor-mode-keymap ()
+  "Show the top-level bindings in KEYMAP using which-key. KEYMAP
+is selected interactively by mode in `minor-mode-map-alist'."
+  (interactive)
+  (let ((mode-sym
+         (intern
+          (completing-read
+           "Minor Mode: "
+           (mapcar 'car
+                   (cl-remove-if-not
+                    (lambda (entry)
+                      (and (symbol-value (car entry))
+                           (not (equal (cdr entry) (make-sparse-keymap)))))
+                    minor-mode-map-alist))
+           nil t nil 'which-key-keymap-history))))
+    (which-key--show-keymap (symbol-name mode-sym)
+                            (cdr (assq mode-sym minor-mode-map-alist)))))
+
+(defun which-key--show-keymap (keymap-name keymap &optional prior-args all)
+  (when prior-args (push prior-args which-key--prior-show-keymap-args))
+  (let ((bindings (which-key--get-bindings nil keymap nil all)))
+    (if (= (length bindings) 0)
+        (message "which-key: No bindings found in %s" keymap-name)
+      (cond ((listp which-key-side-window-location)
+             (setq which-key--last-try-2-loc
+                   (apply #'which-key--try-2-side-windows
+                          bindings nil keymap-name
+                          which-key-side-window-location)))
+            (t (setq which-key--pages-obj
+                     (which-key--create-pages bindings nil keymap-name))
+               (which-key--show-page)))
+      (let* ((key (key-description (list (read-key))))
+             (next-def (lookup-key keymap (kbd key))))
+        (cond ((and which-key-use-C-h-commands (string= "C-h" key))
+               (which-key-C-h-dispatch))
+              ((keymapp next-def)
+               (which-key--hide-popup-ignore-command)
+               (which-key--show-keymap (concat keymap-name " " key) next-def
+                                       (cons keymap-name keymap)))
+              (t (which-key--hide-popup)))))))
+
+(defun which-key--evil-operator-filter (binding)
+  (let ((def (intern (cdr binding))))
+    (and (functionp def)
+         (not (evil-get-command-property def :suppress-operator)))))
+
+(defun which-key--show-evil-operator-keymap ()
+  (if which-key--inhibit-next-operator-popup
+      (setq which-key--inhibit-next-operator-popup nil)
+    (let ((keymap
+           (make-composed-keymap (list evil-operator-shortcut-map
+                                       evil-operator-state-map
+                                       evil-motion-state-map))))
+      (when (keymapp keymap)
+        (let ((formatted-keys
+               (which-key--get-bindings
+                nil keymap #'which-key--evil-operator-filter)))
+          (cond ((= (length formatted-keys) 0)
+                 (message "which-key: Keymap empty"))
+                ((listp which-key-side-window-location)
+                 (setq which-key--last-try-2-loc
+                       (apply #'which-key--try-2-side-windows
+                              formatted-keys nil "evil operator/motion keys"
+                              which-key-side-window-location)))
+                (t (setq which-key--pages-obj
+                         (which-key--create-pages
+                          formatted-keys
+                          nil "evil operator/motion keys"))
+                   (which-key--show-page)))))
+      (let* ((key (key-description (list (read-key)))))
+        (when (member key '("f" "F" "t" "T" "`"))
+          ;; these keys trigger commands that read the next char manually
+          (setq which-key--inhibit-next-operator-popup t))
+        (cond ((and which-key-use-C-h-commands (string= "C-h" key))
+               (which-key-C-h-dispatch))
+              ((string= key "ESC")
+               (which-key--hide-popup)
+               (keyboard-quit))
+              (t
+               (which-key--hide-popup)
+               (setq unread-command-events (listify-key-sequence key))))))))
+
+(defun which-key--create-buffer-and-show
+    (&optional prefix-keys from-keymap filter prefix-title)
+  "Fill `which-key--buffer' with key descriptions and reformat.
+Finally, show the buffer."
+  (let ((start-time (when which-key--debug (current-time)))
+        (formatted-keys (which-key--get-bindings
+                         prefix-keys from-keymap filter))
+        (prefix-desc (key-description prefix-keys)))
+    (cond ((= (length formatted-keys) 0)
+           (message "%s-  which-key: There are no keys to show" prefix-desc))
+          ((listp which-key-side-window-location)
+           (setq which-key--last-try-2-loc
+                 (apply #'which-key--try-2-side-windows
+                        formatted-keys prefix-keys prefix-title
+                        which-key-side-window-location)))
+          (t (setq which-key--pages-obj
+                   (which-key--create-pages
+                    formatted-keys prefix-keys prefix-title))
+             (which-key--show-page)))
+    (when which-key--debug
+      (message "On prefix \"%s\" which-key took %.0f ms." prefix-desc
+               (* 1000 (float-time (time-since start-time)))))))
+
+(defun which-key--this-command-keys ()
+  "Version of `this-single-command-keys' corrected for key-chords and god-mode."
+  (let ((this-command-keys (this-single-command-keys)))
+    (when (and (equal this-command-keys [key-chord])
+               (bound-and-true-p key-chord-mode))
+      (setq this-command-keys
+            (condition-case nil
+                (let ((rkeys (recent-keys)))
+                  (vector 'key-chord
+                          ;; Take the two preceding the last one, because the
+                          ;; read-event call in key-chord seems to add a
+                          ;; spurious key press to this list. Note this is
+                          ;; different from guide-key's method which didn't work
+                          ;; for me.
+                          (aref rkeys (- (length rkeys) 3))
+                          (aref rkeys (- (length rkeys) 2))))
+              (error (progn
+                       (message "which-key error in key-chord handling")
+                       [key-chord])))))
+    (when (and which-key--god-mode-support-enabled
+               (bound-and-true-p god-local-mode)
+               (eq this-command 'god-mode-self-insert))
+      (setq this-command-keys (when which-key--god-mode-key-string
+                          (kbd which-key--god-mode-key-string))))
+    this-command-keys))
+
+(defun which-key--update ()
+  "Function run by timer to possibly trigger
+`which-key--create-buffer-and-show'."
+  (let ((prefix-keys (which-key--this-command-keys))
+        delay-time)
+    (cond ((and (> (length prefix-keys) 0)
+                (or (keymapp (key-binding prefix-keys))
+                    ;; Some keymaps are stored here like iso-transl-ctl-x-8-map
+                    (keymapp (which-key--safe-lookup-key
+                              key-translation-map prefix-keys))
+                    ;; just in case someone uses one of these
+                    (keymapp (which-key--safe-lookup-key
+                              function-key-map prefix-keys)))
+                (not which-key-inhibit)
+                (or (null which-key-allow-regexps)
+                    (which-key--any-match-p
+                     which-key-allow-regexps (key-description prefix-keys)))
+                (or (null which-key-inhibit-regexps)
+                    (not
+                     (which-key--any-match-p
+                      which-key-inhibit-regexps (key-description prefix-keys))))
+                ;; Do not display the popup if a command is currently being
+                ;; executed
+                (or (and which-key-allow-evil-operators
+                         (bound-and-true-p evil-this-operator))
+                    (and which-key--god-mode-support-enabled
+                         (bound-and-true-p god-local-mode)
+                         (eq this-command 'god-mode-self-insert))
+                    (null this-command)))
+           (when (and (not (equal prefix-keys (which-key--current-prefix)))
+                      (or (null which-key-delay-functions)
+                          (null (setq delay-time
+                                      (run-hook-with-args-until-success
+                                       'which-key-delay-functions
+                                       (key-description prefix-keys)
+                                       (length prefix-keys))))
+                          (sit-for delay-time)))
+             (setq which-key--automatic-display t)
+             (which-key--create-buffer-and-show prefix-keys)
+             (when (and which-key-idle-secondary-delay
+                        (not which-key--secondary-timer-active))
+               (which-key--start-timer which-key-idle-secondary-delay t))))
+          ((and which-key-show-transient-maps
+                (keymapp overriding-terminal-local-map)
+                ;; basic test for it being a hydra
+                (not (eq (lookup-key overriding-terminal-local-map "\C-u")
+                         'hydra--universal-argument)))
+           (which-key--create-buffer-and-show
+            nil overriding-terminal-local-map))
+          ((and which-key-show-operator-state-maps
+                (bound-and-true-p evil-state)
+                (eq evil-state 'operator)
+                (not (which-key--popup-showing-p)))
+           (which-key--show-evil-operator-keymap))
+          (which-key--automatic-display
+           (which-key--hide-popup)))))
+
+;;; Timers
+
+(defun which-key--start-timer (&optional delay secondary)
+  "Activate idle timer to trigger `which-key--update'."
+  (which-key--stop-timer)
+  (setq which-key--secondary-timer-active secondary)
+  (setq which-key--timer
+        (run-with-idle-timer
+         (if delay
+             delay
+           which-key-idle-delay) t #'which-key--update)))
+
+(defun which-key--stop-timer ()
+  "Deactivate idle timer for `which-key--update'."
+  (when which-key--timer (cancel-timer which-key--timer)))
+
+(defun which-key--start-paging-timer ()
+  "Activate timer to restart which-key after paging."
+  (when which-key--paging-timer (cancel-timer which-key--paging-timer))
+  (which-key--stop-timer)
+  (setq which-key--paging-timer
+        (run-with-idle-timer
+         0.2 t (lambda ()
+                 (when (or (not (member real-last-command
+                                        which-key--paging-functions))
+                           (and (< 0 (length (this-single-command-keys)))
+                                (not (equal (which-key--current-prefix)
+                                            (which-key--this-command-keys)))))
+                   (cancel-timer which-key--paging-timer)
+                   (which-key--start-timer))))))
+
+(provide 'which-key)
+;;; which-key.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/which-key-20180621.1238/which-key.elc b/configs/shared/emacs/.emacs.d/elpa/which-key-20180621.1238/which-key.elc
new file mode 100644
index 0000000000..23f43f466c
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/which-key-20180621.1238/which-key.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/with-editor-20180618.1602/dir b/configs/shared/emacs/.emacs.d/elpa/with-editor-20180618.1602/dir
new file mode 100644
index 0000000000..93a7ef74ad
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/with-editor-20180618.1602/dir
@@ -0,0 +1,18 @@
+This is the file .../info/dir, which contains the
+topmost node of the Info hierarchy, called (dir)Top.
+The first time you invoke Info you start off looking at this node.
+
+File: dir,	Node: Top	This is the top of the INFO tree
+
+  This (the Directory node) gives a menu of major topics.
+  Typing "q" exits, "?" lists all Info commands, "d" returns here,
+  "h" gives a primer for first-timers,
+  "mEmacs<Return>" visits the Emacs manual, etc.
+
+  In Emacs, you can click mouse button 2 on a menu item or cross reference
+  to select it.
+
+* Menu:
+
+Emacs
+* With-Editor: (with-editor).   Using the Emacsclient as $EDITOR.
diff --git a/configs/shared/emacs/.emacs.d/elpa/with-editor-20180618.1602/with-editor-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/with-editor-20180618.1602/with-editor-autoloads.el
new file mode 100644
index 0000000000..f5b73f57de
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/with-editor-20180618.1602/with-editor-autoloads.el
@@ -0,0 +1,95 @@
+;;; with-editor-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "with-editor" "with-editor.el" (23377 61606
+;;;;;;  271047 151000))
+;;; Generated autoloads from with-editor.el
+
+(autoload 'with-editor-export-editor "with-editor" "\
+Teach subsequent commands to use current Emacs instance as editor.
+
+Set and export the environment variable ENVVAR, by default
+\"EDITOR\".  The value is automatically generated to teach
+commands to use the current Emacs instance as \"the editor\".
+
+This works in `shell-mode', `term-mode' and `eshell-mode'.
+
+\(fn &optional (ENVVAR \"EDITOR\"))" t nil)
+
+(autoload 'with-editor-export-git-editor "with-editor" "\
+Like `with-editor-export-editor' but always set `$GIT_EDITOR'.
+
+\(fn)" t nil)
+
+(autoload 'with-editor-export-hg-editor "with-editor" "\
+Like `with-editor-export-editor' but always set `$HG_EDITOR'.
+
+\(fn)" t nil)
+
+(defvar shell-command-with-editor-mode nil "\
+Non-nil if Shell-Command-With-Editor mode is enabled.
+See the `shell-command-with-editor-mode' command
+for a description of this minor mode.")
+
+(custom-autoload 'shell-command-with-editor-mode "with-editor" nil)
+
+(autoload 'shell-command-with-editor-mode "with-editor" "\
+Teach `shell-command' to use current Emacs instance as editor.
+
+Teach `shell-command', and all commands that ultimately call that
+command, to use the current Emacs instance as editor by executing
+\"EDITOR=CLIENT COMMAND&\" instead of just \"COMMAND&\".
+
+CLIENT is automatically generated; EDITOR=CLIENT instructs
+COMMAND to use to the current Emacs instance as \"the editor\",
+assuming no other variable overrides the effect of \"$EDITOR\".
+CLIENT may be the path to an appropriate emacsclient executable
+with arguments, or a script which also works over Tramp.
+
+Alternatively you can use the `with-editor-async-shell-command',
+which also allows the use of another variable instead of
+\"EDITOR\".
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'with-editor-async-shell-command "with-editor" "\
+Like `async-shell-command' but with `$EDITOR' set.
+
+Execute string \"ENVVAR=CLIENT COMMAND\" in an inferior shell;
+display output, if any.  With a prefix argument prompt for an
+environment variable, otherwise the default \"EDITOR\" variable
+is used.  With a negative prefix argument additionally insert
+the COMMAND's output at point.
+
+CLIENT is automatically generated; ENVVAR=CLIENT instructs
+COMMAND to use to the current Emacs instance as \"the editor\",
+assuming it respects ENVVAR as an \"EDITOR\"-like variable.
+CLIENT may be the path to an appropriate emacsclient executable
+with arguments, or a script which also works over Tramp.
+
+Also see `async-shell-command' and `shell-command'.
+
+\(fn COMMAND &optional OUTPUT-BUFFER ERROR-BUFFER ENVVAR)" t nil)
+
+(autoload 'with-editor-shell-command "with-editor" "\
+Like `shell-command' or `with-editor-async-shell-command'.
+If COMMAND ends with \"&\" behave like the latter,
+else like the former.
+
+\(fn COMMAND &optional OUTPUT-BUFFER ERROR-BUFFER ENVVAR)" t nil)
+
+;;;***
+
+;;;### (autoloads nil nil ("with-editor-pkg.el") (23377 61606 269709
+;;;;;;  49000))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; with-editor-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/with-editor-20180618.1602/with-editor-pkg.el b/configs/shared/emacs/.emacs.d/elpa/with-editor-20180618.1602/with-editor-pkg.el
new file mode 100644
index 0000000000..9a0e2a2b1f
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/with-editor-20180618.1602/with-editor-pkg.el
@@ -0,0 +1,9 @@
+(define-package "with-editor" "20180618.1602" "Use the Emacsclient as $EDITOR"
+  '((emacs "24.4")
+    (async "1.9"))
+  :keywords
+  '("tools")
+  :url "https://github.com/magit/with-editor")
+;; Local Variables:
+;; no-byte-compile: t
+;; End:
diff --git a/configs/shared/emacs/.emacs.d/elpa/with-editor-20180618.1602/with-editor.el b/configs/shared/emacs/.emacs.d/elpa/with-editor-20180618.1602/with-editor.el
new file mode 100644
index 0000000000..b61104a541
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/with-editor-20180618.1602/with-editor.el
@@ -0,0 +1,822 @@
+;;; with-editor.el --- Use the Emacsclient as $EDITOR -*- lexical-binding: t -*-
+
+;; Copyright (C) 2014-2018  The Magit Project Contributors
+;;
+;; You should have received a copy of the AUTHORS.md file.  If not,
+;; see https://github.com/magit/with-editor/blob/master/AUTHORS.md.
+
+;; Author: Jonas Bernoulli <jonas@bernoul.li>
+;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
+
+;; Package-Requires: ((emacs "24.4") (async "1.9"))
+;; Keywords: tools
+;; Homepage: https://github.com/magit/with-editor
+
+;; This file is not part of GNU Emacs.
+
+;; This file 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, or (at your option)
+;; any later version.
+
+;; This file 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 Magit.  If not, see http://www.gnu.org/licenses.
+
+;;; Commentary:
+
+;; This library makes it possible to reliably use the Emacsclient as
+;; the `$EDITOR' of child processes.  It makes sure that they know how
+;; to call home.  For remote processes a substitute is provided, which
+;; communicates with Emacs on standard output/input instead of using a
+;; socket as the Emacsclient does.
+
+;; It provides the commands `with-editor-async-shell-command' and
+;; `with-editor-shell-command', which are intended as replacements
+;; for `async-shell-command' and `shell-command'.  They automatically
+;; export `$EDITOR' making sure the executed command uses the current
+;; Emacs instance as "the editor".  With a prefix argument these
+;; commands prompt for an alternative environment variable such as
+;; `$GIT_EDITOR'.  To always use these variants add this to your init
+;; file:
+;;
+;;   (define-key (current-global-map)
+;;     [remap async-shell-command] 'with-editor-async-shell-command)
+;;   (define-key (current-global-map)
+;;     [remap shell-command] 'with-editor-shell-command)
+
+;; Alternatively use the global `shell-command-with-editor-mode',
+;; which always sets `$EDITOR' for all Emacs commands which ultimately
+;; use `shell-command' to asynchronously run some shell command.
+
+;; The command `with-editor-export-editor' exports `$EDITOR' or
+;; another such environment variable in `shell-mode', `term-mode' and
+;; `eshell-mode' buffers.  Use this Emacs command before executing a
+;; shell command which needs the editor set, or always arrange for the
+;; current Emacs instance to be used as editor by adding it to the
+;; appropriate mode hooks:
+;;
+;;   (add-hook 'shell-mode-hook  'with-editor-export-editor)
+;;   (add-hook 'term-exec-hook   'with-editor-export-editor)
+;;   (add-hook 'eshell-mode-hook 'with-editor-export-editor)
+
+;; Some variants of this function exist, these two forms are
+;; equivalent:
+;;
+;;   (add-hook 'shell-mode-hook
+;;             (apply-partially 'with-editor-export-editor "GIT_EDITOR"))
+;;   (add-hook 'shell-mode-hook 'with-editor-export-git-editor)
+
+;; This library can also be used by other packages which need to use
+;; the current Emacs instance as editor.  In fact this library was
+;; written for Magit and its `git-commit-mode' and `git-rebase-mode'.
+;; Consult `git-rebase.el' and the related code in `magit-sequence.el'
+;; for a simple example.
+
+;;; Code:
+
+(require 'cl-lib)
+;; `pcase-dolist' is not autoloaded on Emacs 24.
+(eval-when-compile (require 'pcase))
+(require 'server)
+(require 'shell)
+
+(and (require 'async-bytecomp nil t)
+     (memq 'magit (bound-and-true-p async-bytecomp-allowed-packages))
+     (fboundp 'async-bytecomp-package-mode)
+     (async-bytecomp-package-mode 1))
+
+(eval-when-compile
+  (progn (require 'dired nil t)
+         (require 'eshell nil t)
+         (require 'term nil t)
+         (require 'warnings nil t)))
+(declare-function dired-get-filename 'dired)
+(declare-function term-emulate-terminal 'term)
+(defvar eshell-preoutput-filter-functions)
+
+;;; Options
+
+(defgroup with-editor nil
+  "Use the Emacsclient as $EDITOR."
+  :group 'external
+  :group 'server)
+
+(defun with-editor-locate-emacsclient ()
+  "Search for a suitable Emacsclient executable."
+  (or (with-editor-locate-emacsclient-1
+       (with-editor-emacsclient-path)
+       (length (split-string emacs-version "\\.")))
+      (prog1 nil (display-warning 'with-editor "\
+Cannot determine a suitable Emacsclient
+
+Determining an Emacsclient executable suitable for the
+current Emacs instance failed.  For more information
+please see https://github.com/magit/magit/wiki/Emacsclient."))))
+
+(defun with-editor-locate-emacsclient-1 (path depth)
+  (let* ((version-lst (cl-subseq (split-string emacs-version "\\.") 0 depth))
+         (version-reg (concat "^" (mapconcat #'identity version-lst "\\."))))
+    (or (locate-file-internal
+         (if (equal (downcase invocation-name) "remacs")
+             "remacsclient"
+           "emacsclient")
+         path
+         (cl-mapcan
+          (lambda (v) (cl-mapcar (lambda (e) (concat v e)) exec-suffixes))
+          (nconc (and (boundp 'debian-emacs-flavor)
+                      (list (format ".%s" debian-emacs-flavor)))
+                 (cl-mapcon (lambda (v)
+                              (setq v (mapconcat #'identity (reverse v) "."))
+                              (list v (concat "-" v) (concat ".emacs" v)))
+                            (reverse version-lst))
+                 (list "" "-snapshot" ".emacs-snapshot")))
+         (lambda (exec)
+           (ignore-errors
+             (string-match-p version-reg
+                             (with-editor-emacsclient-version exec)))))
+        (and (> depth 1)
+             (with-editor-locate-emacsclient-1 path (1- depth))))))
+
+(defun with-editor-emacsclient-version (exec)
+  (let ((default-directory (file-name-directory exec)))
+    (ignore-errors
+      (cadr (split-string (car (process-lines exec "--version")))))))
+
+(defun with-editor-emacsclient-path ()
+  (let ((path exec-path))
+    (when invocation-directory
+      (push (directory-file-name invocation-directory) path)
+      (let* ((linkname (expand-file-name invocation-name invocation-directory))
+             (truename (file-chase-links linkname)))
+        (unless (equal truename linkname)
+          (push (directory-file-name (file-name-directory truename)) path)))
+      (when (eq system-type 'darwin)
+        (let ((dir (expand-file-name "bin" invocation-directory)))
+          (when (file-directory-p dir)
+            (push dir path)))
+        (when (string-match-p "Cellar" invocation-directory)
+          (let ((dir (expand-file-name "../../../bin" invocation-directory)))
+            (when (file-directory-p dir)
+              (push dir path))))))
+    (cl-remove-duplicates path :test 'equal)))
+
+(defcustom with-editor-emacsclient-executable (with-editor-locate-emacsclient)
+  "The Emacsclient executable used by the `with-editor' macro."
+  :group 'with-editor
+  :type '(choice (string :tag "Executable")
+                 (const  :tag "Don't use Emacsclient" nil)))
+
+(defcustom with-editor-sleeping-editor "\
+sh -c '\
+echo \"WITH-EDITOR: $$ OPEN $0\"; \
+sleep 604800 & sleep=$!; \
+trap \"kill $sleep; exit 0\" USR1; \
+trap \"kill $sleep; exit 1\" USR2; \
+wait $sleep'"
+  "The sleeping editor, used when the Emacsclient cannot be used.
+
+This fallback is used for asynchronous processes started inside
+the macro `with-editor', when the process runs on a remote machine
+or for local processes when `with-editor-emacsclient-executable'
+is nil (i.e. when no suitable Emacsclient was found, or the user
+decided not to use it).
+
+Where the latter uses a socket to communicate with Emacs' server,
+this substitute prints edit requests to its standard output on
+which a process filter listens for such requests.  As such it is
+not a complete substitute for a proper Emacsclient, it can only
+be used as $EDITOR of child process of the current Emacs instance.
+
+Some shells do not execute traps immediately when waiting for a
+child process, but by default we do use such a blocking child
+process.
+
+If you use such a shell (e.g. `csh' on FreeBSD, but not Debian),
+then you have to edit this option.  You can either replace \"sh\"
+with \"bash\" (and install that), or you can use the older, less
+performant implementation:
+
+  \"sh -c '\\
+  echo \\\"WITH-EDITOR: $$ OPEN $0\\\"; \\
+  trap \\\"exit 0\\\" USR1; \\
+  trap \\\"exit 1\" USR2; \\
+  while true; do sleep 1; done'\"
+
+Note that this leads to a delay of up to a second.  The delay can
+be shortened by replacing \"sleep 1\" with \"sleep 0.01\", or if your
+implementation does not support floats, then by using `nanosleep'
+instead."
+  :group 'with-editor
+  :type 'string)
+
+(defcustom with-editor-finish-query-functions nil
+  "List of functions called to query before finishing session.
+
+The buffer in question is current while the functions are called.
+If any of them returns nil, then the session is not finished and
+the buffer is not killed.  The user should then fix the issue and
+try again.  The functions are called with one argument.  If it is
+non-nil then that indicates that the user used a prefix argument
+to force finishing the session despite issues.  Functions should
+usually honor that and return non-nil."
+  :group 'with-editor
+  :type 'hook)
+(put 'with-editor-finish-query-functions 'permanent-local t)
+
+(defcustom with-editor-cancel-query-functions nil
+  "List of functions called to query before canceling session.
+
+The buffer in question is current while the functions are called.
+If any of them returns nil, then the session is not canceled and
+the buffer is not killed.  The user should then fix the issue and
+try again.  The functions are called with one argument.  If it is
+non-nil then that indicates that the user used a prefix argument
+to force canceling the session despite issues.  Functions should
+usually honor that and return non-nil."
+  :group 'with-editor
+  :type 'hook)
+(put 'with-editor-cancel-query-functions 'permanent-local t)
+
+(defcustom with-editor-mode-lighter " WE"
+  "The mode-line lighter of the With-Editor mode."
+  :group 'with-editor
+  :type '(choice (const :tag "No lighter" "") string))
+
+(defvar with-editor-server-window-alist nil
+  "Alist of filename patterns vs corresponding `server-window'.
+
+Each element looks like (REGEXP . FUNCTION).  Files matching
+REGEXP are selected using FUNCTION instead of the default in
+`server-window'.
+
+Note that when a package adds an entry here then it probably
+has a reason to disrespect `server-window' and it likely is
+not a good idea to change such entries.")
+
+(defvar with-editor-file-name-history-exclude nil
+  "List of regexps for filenames `server-visit' should not remember.
+When a filename matches any of the regexps, then `server-visit'
+does not add it to the variable `file-name-history', which is
+used when reading a filename in the minibuffer.")
+
+(defcustom with-editor-shell-command-use-emacsclient t
+  "Whether to use the emacsclient when running shell commands.
+
+This affects `with-editor-shell-command-async' and, if the input
+ends with \"&\" `with-editor-shell-command' .
+
+If `shell-command-with-editor-mode' is enabled, then it also
+affects `shell-command-async' and, if the input ends with \"&\"
+`shell-command'.
+
+This is a temporary kludge that lets you choose between two
+possible defects, the ones described in the issues #23 and #40.
+
+When t, then use the emacsclient.  This has the disadvantage that
+`with-editor-mode' won't be enabled because we don't know whether
+this package was involved at all in the call to the emacsclient,
+and when it is not, then we really should.  The problem is that
+the emacsclient doesn't pass a long any environment variables to
+the server.  This will hopefully be fixed in Emacs eventually.
+
+When nil, then use the sleeping editor.  Because in this case we
+know that this package is involved, we can enable the mode.  But
+this makes it necessary that you invoke $EDITOR in shell scripts
+like so:
+
+  eval \"$EDITOR\" file
+
+And some tools that do not handle $EDITOR properly also break."
+  :package-version '(with-editor . "2.8.0")
+  :group 'with-editor
+  :type 'boolean)
+
+;;; Mode Commands
+
+(defvar with-editor-pre-finish-hook nil)
+(defvar with-editor-pre-cancel-hook nil)
+(defvar with-editor-post-finish-hook nil)
+(defvar with-editor-post-finish-hook-1 nil)
+(defvar with-editor-post-cancel-hook nil)
+(defvar with-editor-post-cancel-hook-1 nil)
+(defvar with-editor-cancel-alist nil)
+(put 'with-editor-pre-finish-hook 'permanent-local t)
+(put 'with-editor-pre-cancel-hook 'permanent-local t)
+(put 'with-editor-post-finish-hook 'permanent-local t)
+(put 'with-editor-post-cancel-hook 'permanent-local t)
+
+(defvar with-editor-show-usage t)
+(defvar with-editor-cancel-message nil)
+(defvar with-editor-previous-winconf nil)
+(make-variable-buffer-local 'with-editor-show-usage)
+(make-variable-buffer-local 'with-editor-cancel-message)
+(make-variable-buffer-local 'with-editor-previous-winconf)
+(put 'with-editor-cancel-message 'permanent-local t)
+(put 'with-editor-previous-winconf 'permanent-local t)
+
+(defvar-local with-editor--pid nil "For internal use.")
+(put 'with-editor--pid 'permanent-local t)
+
+(defun with-editor-finish (force)
+  "Finish the current edit session."
+  (interactive "P")
+  (when (run-hook-with-args-until-failure
+         'with-editor-finish-query-functions force)
+    (let ((with-editor-post-finish-hook-1
+           (ignore-errors (delq t with-editor-post-finish-hook))))
+      (run-hooks 'with-editor-pre-finish-hook)
+      (with-editor-return nil)
+      (accept-process-output nil 0.1)
+      (run-hooks 'with-editor-post-finish-hook-1))))
+
+(defun with-editor-cancel (force)
+  "Cancel the current edit session."
+  (interactive "P")
+  (when (run-hook-with-args-until-failure
+         'with-editor-cancel-query-functions force)
+    (let ((message with-editor-cancel-message))
+      (when (functionp message)
+        (setq message (funcall message)))
+      (let ((with-editor-post-cancel-hook-1
+             (ignore-errors (delq t with-editor-post-cancel-hook)))
+            (with-editor-cancel-alist nil))
+        (run-hooks 'with-editor-pre-cancel-hook)
+        (with-editor-return t)
+        (accept-process-output nil 0.1)
+        (run-hooks 'with-editor-post-cancel-hook-1))
+      (message (or message "Canceled by user")))))
+
+(defun with-editor-return (cancel)
+  (let ((winconf with-editor-previous-winconf)
+        (clients server-buffer-clients)
+        (dir default-directory)
+        (pid with-editor--pid))
+    (remove-hook 'kill-buffer-query-functions
+                 'with-editor-kill-buffer-noop t)
+    (cond (cancel
+           (save-buffer)
+           (if clients
+               (dolist (client clients)
+                 (ignore-errors
+                   (server-send-string client "-error Canceled by user"))
+                 (delete-process client))
+             ;; Fallback for when emacs was used as $EDITOR
+             ;; instead of emacsclient or the sleeping editor.
+             ;; See https://github.com/magit/magit/issues/2258.
+             (ignore-errors (delete-file buffer-file-name))
+             (kill-buffer)))
+          (t
+           (save-buffer)
+           (if clients
+               ;; Don't use `server-edit' because we do not want to
+               ;; show another buffer belonging to another client.
+               ;; See https://github.com/magit/magit/issues/2197.
+               (server-done)
+             (kill-buffer))))
+    (when pid
+      (let ((default-directory dir))
+        (process-file "kill" nil nil nil
+                      "-s" (if cancel "USR2" "USR1") pid)))
+    (when (and winconf (eq (window-configuration-frame winconf)
+                           (selected-frame)))
+      (set-window-configuration winconf))))
+
+;;; Mode
+
+(defvar with-editor-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map "\C-c\C-c"                           'with-editor-finish)
+    (define-key map [remap server-edit]                  'with-editor-finish)
+    (define-key map [remap evil-save-and-close]          'with-editor-finish)
+    (define-key map [remap evil-save-modified-and-close] 'with-editor-finish)
+    (define-key map "\C-c\C-k"                           'with-editor-cancel)
+    (define-key map [remap kill-buffer]                  'with-editor-cancel)
+    (define-key map [remap ido-kill-buffer]              'with-editor-cancel)
+    (define-key map [remap iswitchb-kill-buffer]         'with-editor-cancel)
+    (define-key map [remap evil-quit]                    'with-editor-cancel)
+    map))
+
+(define-minor-mode with-editor-mode
+  "Edit a file as the $EDITOR of an external process."
+  :lighter with-editor-mode-lighter
+  ;; Protect the user from killing the buffer without using
+  ;; either `with-editor-finish' or `with-editor-cancel',
+  ;; and from removing the key bindings for these commands.
+  (unless with-editor-mode
+    (user-error "With-Editor mode cannot be turned off"))
+  (add-hook 'kill-buffer-query-functions
+            'with-editor-kill-buffer-noop nil t)
+  ;; `server-execute' displays a message which is not
+  ;; correct when using this mode.
+  (when with-editor-show-usage
+    (with-editor-usage-message)))
+
+(put 'with-editor-mode 'permanent-local t)
+
+(defun with-editor-kill-buffer-noop ()
+  (user-error (substitute-command-keys "\
+Don't kill this buffer.  Instead cancel using \\[with-editor-cancel]")))
+
+(defun with-editor-usage-message ()
+  ;; Run after `server-execute', which is run using
+  ;; a timer which starts immediately.
+  (run-with-timer
+   0.01 nil `(lambda ()
+               (with-current-buffer ,(current-buffer)
+                 (message (substitute-command-keys "\
+Type \\[with-editor-finish] to finish, \
+or \\[with-editor-cancel] to cancel"))))))
+
+;;; Wrappers
+
+(defvar with-editor--envvar nil "For internal use.")
+
+(defmacro with-editor (&rest body)
+  "Use the Emacsclient as $EDITOR while evaluating BODY.
+Modify the `process-environment' for processes started in BODY,
+instructing them to use the Emacsclient as $EDITOR.  If optional
+ENVVAR is provided then bind that environment variable instead.
+\n(fn [ENVVAR] BODY...)"
+  (declare (indent defun) (debug (body)))
+  `(let ((with-editor--envvar ,(if (stringp (car body))
+                                   (pop body)
+                                 '(or with-editor--envvar "EDITOR")))
+         (process-environment process-environment))
+     (with-editor--setup)
+     ,@body))
+
+(defun with-editor--setup ()
+  (if (or (not with-editor-emacsclient-executable)
+          (file-remote-p default-directory))
+      (push (concat with-editor--envvar "=" with-editor-sleeping-editor)
+            process-environment)
+    ;; Make sure server-use-tcp's value is valid.
+    (unless (featurep 'make-network-process '(:family local))
+      (setq server-use-tcp t))
+    ;; Make sure the server is running.
+    (unless (process-live-p server-process)
+      (when (server-running-p server-name)
+        (setq server-name (format "server%s" (emacs-pid)))
+        (when (server-running-p server-name)
+          (server-force-delete server-name)))
+      (server-start))
+    ;; Tell $EDITOR to use the Emacsclient.
+    (push (concat with-editor--envvar "="
+                  (shell-quote-argument with-editor-emacsclient-executable)
+                  ;; Tell the process where the server file is.
+                  (and (not server-use-tcp)
+                       (concat " --socket-name="
+                               (shell-quote-argument
+                                (expand-file-name server-name
+                                                  server-socket-dir)))))
+          process-environment)
+    (when server-use-tcp
+      (push (concat "EMACS_SERVER_FILE="
+                    (expand-file-name server-name server-auth-dir))
+            process-environment))
+    ;; As last resort fallback to the sleeping editor.
+    (push (concat "ALTERNATE_EDITOR=" with-editor-sleeping-editor)
+          process-environment)))
+
+(defun with-editor-server-window ()
+  (or (and buffer-file-name
+           (cdr (cl-find-if (lambda (cons)
+                              (string-match-p (car cons) buffer-file-name))
+                            with-editor-server-window-alist)))
+      server-window))
+
+(defun server-switch-buffer--with-editor-server-window-alist
+    (fn &optional next-buffer killed-one filepos)
+  "Honor `with-editor-server-window-alist' (which see)."
+  (let ((server-window (with-current-buffer
+                           (or next-buffer (current-buffer))
+                         (when with-editor-mode
+                           (setq with-editor-previous-winconf
+                                 (current-window-configuration)))
+                         (with-editor-server-window))))
+    (funcall fn next-buffer killed-one filepos)))
+
+(advice-add 'server-switch-buffer :around
+            'server-switch-buffer--with-editor-server-window-alist)
+
+(defun start-file-process--with-editor-process-filter
+    (fn name buffer program &rest program-args)
+  "When called inside a `with-editor' form and the Emacsclient
+cannot be used, then give the process the filter function
+`with-editor-process-filter'.  To avoid overriding the filter
+being added here you should use `with-editor-set-process-filter'
+instead of `set-process-filter' inside `with-editor' forms.
+
+When the `default-directory' is located on a remote machine,
+then also manipulate PROGRAM and PROGRAM-ARGS in order to set
+the appropriate editor environment variable."
+  (if (not with-editor--envvar)
+      (apply fn name buffer program program-args)
+    (when (file-remote-p default-directory)
+      (unless (equal program "env")
+        (push program program-args)
+        (setq program "env"))
+      (push (concat with-editor--envvar "=" with-editor-sleeping-editor)
+            program-args))
+    (let ((process (apply fn name buffer program program-args)))
+      (set-process-filter process 'with-editor-process-filter)
+      (process-put process 'default-dir default-directory)
+      process)))
+
+(advice-add 'start-file-process :around
+            'start-file-process--with-editor-process-filter)
+
+(defun with-editor-set-process-filter (process filter)
+  "Like `set-process-filter' but keep `with-editor-process-filter'.
+Give PROCESS the new FILTER but keep `with-editor-process-filter'
+if that was added earlier by the adviced `start-file-process'.
+
+Do so by wrapping the two filter functions using a lambda, which
+becomes the actual filter.  It calls `with-editor-process-filter'
+first, passing t as NO-STANDARD-FILTER.  Then it calls FILTER,
+which may or may not insert the text into the PROCESS' buffer."
+  (set-process-filter
+   process
+   (if (eq (process-filter process) 'with-editor-process-filter)
+       `(lambda (proc str)
+          (,filter proc str)
+          (with-editor-process-filter proc str t))
+     filter)))
+
+(defvar with-editor-filter-visit-hook nil)
+
+(defun with-editor-output-filter (string)
+  (save-match-data
+    (if (string-match "^WITH-EDITOR: \\([0-9]+\\) OPEN \\(.+?\\)\r?$" string)
+        (let ((pid  (match-string 1 string))
+              (file (match-string 2 string)))
+          (with-current-buffer
+              (find-file-noselect
+               (if (and (file-name-absolute-p file) default-directory)
+                   (concat (file-remote-p default-directory) file)
+                 (expand-file-name file)))
+            (with-editor-mode 1)
+            (setq with-editor--pid pid)
+            (run-hooks 'with-editor-filter-visit-hook)
+            (funcall (or (with-editor-server-window) 'switch-to-buffer)
+                     (current-buffer))
+            (kill-local-variable 'server-window))
+          nil)
+      string)))
+
+(defun with-editor-process-filter
+    (process string &optional no-default-filter)
+  "Listen for edit requests by child processes."
+  (let ((default-directory (process-get process 'default-dir)))
+    (with-editor-output-filter string))
+  (unless no-default-filter
+    (internal-default-process-filter process string)))
+
+(advice-add 'server-visit-files :after
+            'server-visit-files--with-editor-file-name-history-exclude)
+
+(defun server-visit-files--with-editor-file-name-history-exclude
+    (files _proc &optional _nowait)
+  (pcase-dolist (`(,file . ,_) files)
+    (when (cl-find-if (lambda (regexp)
+                        (string-match-p regexp file))
+                      with-editor-file-name-history-exclude)
+      (setq file-name-history (delete file file-name-history)))))
+
+;;; Augmentations
+
+;;;###autoload
+(cl-defun with-editor-export-editor (&optional (envvar "EDITOR"))
+  "Teach subsequent commands to use current Emacs instance as editor.
+
+Set and export the environment variable ENVVAR, by default
+\"EDITOR\".  The value is automatically generated to teach
+commands to use the current Emacs instance as \"the editor\".
+
+This works in `shell-mode', `term-mode' and `eshell-mode'."
+  (interactive (list (with-editor-read-envvar)))
+  (cond
+   ((derived-mode-p 'comint-mode 'term-mode)
+    (let ((process (get-buffer-process (current-buffer))))
+      (goto-char (process-mark process))
+      (process-send-string
+       process (format " export %s=%s\n" envvar
+                       (shell-quote-argument with-editor-sleeping-editor)))
+      (while (accept-process-output process 0.1))
+      (if (derived-mode-p 'term-mode)
+          (with-editor-set-process-filter process 'with-editor-emulate-terminal)
+        (add-hook 'comint-output-filter-functions 'with-editor-output-filter
+                  nil t))))
+   ((derived-mode-p 'eshell-mode)
+    (add-to-list 'eshell-preoutput-filter-functions
+                 'with-editor-output-filter)
+    (setenv envvar with-editor-sleeping-editor))
+   (t
+    (error "Cannot export environment variables in this buffer")))
+  (message "Successfully exported %s" envvar))
+
+;;;###autoload
+(defun with-editor-export-git-editor ()
+  "Like `with-editor-export-editor' but always set `$GIT_EDITOR'."
+  (interactive)
+  (with-editor-export-editor "GIT_EDITOR"))
+
+;;;###autoload
+(defun with-editor-export-hg-editor ()
+  "Like `with-editor-export-editor' but always set `$HG_EDITOR'."
+  (interactive)
+  (with-editor-export-editor "HG_EDITOR"))
+
+(defun with-editor-emulate-terminal (process string)
+  "Like `term-emulate-terminal' but also handle edit requests."
+  (when (with-editor-output-filter string)
+    (term-emulate-terminal process string)))
+
+(defvar with-editor-envvars '("EDITOR" "GIT_EDITOR" "HG_EDITOR"))
+
+(cl-defun with-editor-read-envvar
+    (&optional (prompt  "Set environment variable")
+               (default "EDITOR"))
+  (let ((reply (completing-read (if default
+                                    (format "%s (%s): " prompt default)
+                                  (concat prompt ": "))
+                                with-editor-envvars nil nil nil nil default)))
+    (if (string= reply "") (user-error "Nothing selected") reply)))
+
+;;;###autoload
+(define-minor-mode shell-command-with-editor-mode
+  "Teach `shell-command' to use current Emacs instance as editor.
+
+Teach `shell-command', and all commands that ultimately call that
+command, to use the current Emacs instance as editor by executing
+\"EDITOR=CLIENT COMMAND&\" instead of just \"COMMAND&\".
+
+CLIENT is automatically generated; EDITOR=CLIENT instructs
+COMMAND to use to the current Emacs instance as \"the editor\",
+assuming no other variable overrides the effect of \"$EDITOR\".
+CLIENT may be the path to an appropriate emacsclient executable
+with arguments, or a script which also works over Tramp.
+
+Alternatively you can use the `with-editor-async-shell-command',
+which also allows the use of another variable instead of
+\"EDITOR\"."
+  :global t)
+
+;;;###autoload
+(defun with-editor-async-shell-command
+    (command &optional output-buffer error-buffer envvar)
+  "Like `async-shell-command' but with `$EDITOR' set.
+
+Execute string \"ENVVAR=CLIENT COMMAND\" in an inferior shell;
+display output, if any.  With a prefix argument prompt for an
+environment variable, otherwise the default \"EDITOR\" variable
+is used.  With a negative prefix argument additionally insert
+the COMMAND's output at point.
+
+CLIENT is automatically generated; ENVVAR=CLIENT instructs
+COMMAND to use to the current Emacs instance as \"the editor\",
+assuming it respects ENVVAR as an \"EDITOR\"-like variable.
+CLIENT may be the path to an appropriate emacsclient executable
+with arguments, or a script which also works over Tramp.
+
+Also see `async-shell-command' and `shell-command'."
+  (interactive (with-editor-shell-command-read-args "Async shell command: " t))
+  (let ((with-editor--envvar envvar))
+    (with-editor
+      (async-shell-command command output-buffer error-buffer))))
+
+;;;###autoload
+(defun with-editor-shell-command
+    (command &optional output-buffer error-buffer envvar)
+  "Like `shell-command' or `with-editor-async-shell-command'.
+If COMMAND ends with \"&\" behave like the latter,
+else like the former."
+  (interactive (with-editor-shell-command-read-args "Shell command: "))
+  (if (string-match "&[ \t]*\\'" command)
+      (with-editor-async-shell-command
+       command output-buffer error-buffer envvar)
+    (shell-command command output-buffer error-buffer)))
+
+(defun with-editor-shell-command-read-args (prompt &optional async)
+  (let ((command (read-shell-command
+                  prompt nil nil
+                  (let ((filename (or buffer-file-name
+                                      (and (eq major-mode 'dired-mode)
+                                           (dired-get-filename nil t)))))
+                    (and filename (file-relative-name filename))))))
+    (list command
+          (if (or async (setq async (string-match-p "&[ \t]*\\'" command)))
+              (< (prefix-numeric-value current-prefix-arg) 0)
+            current-prefix-arg)
+          shell-command-default-error-buffer
+          (and async current-prefix-arg (with-editor-read-envvar)))))
+
+(defun shell-command--shell-command-with-editor-mode
+    (fn command &optional output-buffer error-buffer)
+  ;; `shell-mode' and its hook are intended for buffers in which an
+  ;; interactive shell is running, but `shell-command' also turns on
+  ;; that mode, even though it only runs the shell to run a single
+  ;; command.  The `with-editor-export-editor' hook function is only
+  ;; intended to be used in buffers in which an interactive shell is
+  ;; running, so it has to be remove here.
+  (let ((shell-mode-hook (remove 'with-editor-export-editor shell-mode-hook)))
+    (cond ((or (not (or with-editor--envvar shell-command-with-editor-mode))
+               (not (string-match-p "&\\'" command)))
+           (funcall fn command output-buffer error-buffer))
+          ((and with-editor-shell-command-use-emacsclient
+                with-editor-emacsclient-executable
+                (not (file-remote-p default-directory)))
+           (with-editor (funcall fn command output-buffer error-buffer)))
+          (t
+           (apply fn (format "%s=%s %s"
+                             (or with-editor--envvar "EDITOR")
+                             (shell-quote-argument with-editor-sleeping-editor)
+                             command)
+                  output-buffer error-buffer)
+           (ignore-errors
+             (let ((process (get-buffer-process
+                             (or output-buffer
+                                 (get-buffer "*Async Shell Command*")))))
+               (set-process-filter
+                process (lambda (proc str)
+                          (comint-output-filter proc str)
+                          (with-editor-process-filter proc str t)))
+               process))))))
+
+(advice-add 'shell-command :around
+            'shell-command--shell-command-with-editor-mode)
+
+;;; _
+
+(defun with-editor-debug ()
+  "Debug configuration issues.
+See info node `(with-editor)Debugging' for instructions."
+  (interactive)
+  (with-current-buffer (get-buffer-create "*with-editor-debug*")
+    (pop-to-buffer (current-buffer))
+    (erase-buffer)
+    (ignore-errors (with-editor))
+    (insert
+     (format "with-editor: %s\n" (locate-library "with-editor.el"))
+     (format "emacs: %s (%s)\n"
+             (expand-file-name invocation-name invocation-directory)
+             emacs-version)
+     "system:\n"
+     (format "  system-type: %s\n" system-type)
+     (format "  system-configuration: %s\n" system-configuration)
+     (format "  system-configuration-options: %s\n" system-configuration-options)
+     "server:\n"
+     (format "  server-running-p: %s\n" (server-running-p))
+     (format "  server-process: %S\n" server-process)
+     (format "  server-use-tcp: %s\n" server-use-tcp)
+     (format "  server-name: %s\n" server-name)
+     (format "  server-socket-dir: %s\n" server-socket-dir))
+    (if (and server-socket-dir (file-accessible-directory-p server-socket-dir))
+        (dolist (file (directory-files server-socket-dir nil "^[^.]"))
+          (insert (format "    %s\n" file)))
+      (insert (format "    %s: not an accessible directory\n"
+                      (if server-use-tcp "WARNING" "ERROR"))))
+    (insert (format "  server-auth-dir: %s\n" server-auth-dir))
+    (if (file-accessible-directory-p server-auth-dir)
+        (dolist (file (directory-files server-auth-dir nil "^[^.]"))
+          (insert (format "    %s\n" file)))
+      (insert (format "    %s: not an accessible directory\n"
+                      (if server-use-tcp "ERROR" "WARNING"))))
+    (let ((val with-editor-emacsclient-executable)
+          (def (default-value 'with-editor-emacsclient-executable))
+          (fun (let ((warning-minimum-level :error)
+                     (warning-minimum-log-level :error))
+                 (with-editor-locate-emacsclient))))
+      (insert "with-editor-emacsclient-executable:\n"
+              (format " value:   %s (%s)\n" val
+                      (and val (with-editor-emacsclient-version val)))
+              (format " default: %s (%s)\n" def
+                      (and def (with-editor-emacsclient-version def)))
+              (format " funcall: %s (%s)\n" fun
+                      (and fun (with-editor-emacsclient-version fun)))))
+    (insert "path:\n"
+            (format "  $PATH: %S\n" (getenv "PATH"))
+            (format "  exec-path: %s\n" exec-path))
+    (insert (format "  with-editor-emacsclient-path:\n"))
+    (dolist (dir (with-editor-emacsclient-path))
+      (insert (format "    %s (%s)\n" dir (car (file-attributes dir))))
+      (when (file-directory-p dir)
+        ;; Don't match emacsclientw.exe, it makes popup windows.
+        (dolist (exec (directory-files dir t "emacsclient\\(?:[^w]\\|\\'\\)"))
+          (insert (format "      %s (%s)\n" exec
+                          (with-editor-emacsclient-version exec))))))))
+
+(defconst with-editor-font-lock-keywords
+  '(("(\\(with-\\(?:git-\\)?editor\\)\\_>" (1 'font-lock-keyword-face))))
+(font-lock-add-keywords 'emacs-lisp-mode with-editor-font-lock-keywords)
+
+(provide 'with-editor)
+;; Local Variables:
+;; indent-tabs-mode: nil
+;; End:
+;;; with-editor.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/with-editor-20180618.1602/with-editor.elc b/configs/shared/emacs/.emacs.d/elpa/with-editor-20180618.1602/with-editor.elc
new file mode 100644
index 0000000000..180bccf939
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/with-editor-20180618.1602/with-editor.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/with-editor-20180618.1602/with-editor.info b/configs/shared/emacs/.emacs.d/elpa/with-editor-20180618.1602/with-editor.info
new file mode 100644
index 0000000000..5611d5a8c9
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/with-editor-20180618.1602/with-editor.info
@@ -0,0 +1,331 @@
+This is with-editor.info, produced by makeinfo version 6.1 from
+with-editor.texi.
+
+     Copyright (C) 2015-2018 Jonas Bernoulli <jonas@bernoul.li>
+
+     You can redistribute this document 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.
+
+     This document 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.
+INFO-DIR-SECTION Emacs
+START-INFO-DIR-ENTRY
+* With-Editor: (with-editor). Using the Emacsclient as $EDITOR.
+END-INFO-DIR-ENTRY
+
+
+File: with-editor.info,  Node: Top,  Next: Using the With-Editor package,  Up: (dir)
+
+With-Editor User Manual
+***********************
+
+The library ‘with-editor’ makes it easy to use the Emacsclient as the
+‘$EDITOR’ of child processes, making sure they know how to call home.
+For remote processes a substitute is provided, which communicates with
+Emacs on standard output instead of using a socket as the Emacsclient
+does.
+
+   This library was written because Magit has to be able to do the above
+to allow the user to edit commit messages gracefully and to edit rebase
+sequences, which wouldn’t be possible at all otherwise.
+
+   Because other packages can benefit from such functionality, this
+library is made available as a separate package.  It also defines some
+additional functionality which makes it useful even for end-users, who
+don’t use Magit or another package which uses it internally.
+
+This manual is for With-Editor version 2.7.3 (v2.7.3+1).
+
+     Copyright (C) 2015-2018 Jonas Bernoulli <jonas@bernoul.li>
+
+     You can redistribute this document 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.
+
+     This document 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.
+
+* Menu:
+
+* Using the With-Editor package::
+* Using With-Editor as a library::
+* Debugging::
+
+— The Detailed Node Listing —
+
+Using the With-Editor package
+
+* Configuring With-Editor::
+* Using With-Editor commands::
+
+
+
+File: with-editor.info,  Node: Using the With-Editor package,  Next: Using With-Editor as a library,  Prev: Top,  Up: Top
+
+1 Using the With-Editor package
+*******************************
+
+The ‘With-Editor’ package is used internally by Magit when editing
+commit messages and rebase sequences.  It also provides some commands
+and features which are useful by themselves, even if you don’t use
+Magit.
+
+   For information about using this library in you own package, see
+*note Using With-Editor as a library::.
+
+* Menu:
+
+* Configuring With-Editor::
+* Using With-Editor commands::
+
+
+File: with-editor.info,  Node: Configuring With-Editor,  Next: Using With-Editor commands,  Up: Using the With-Editor package
+
+1.1 Configuring With-Editor
+===========================
+
+With-Editor tries very hard to locate a suitable ‘emacsclient’
+executable, so ideally you should never have to customize the option
+‘with-editor-emacsclient-executable’.  When it fails to do so, then the
+most likely reason is that someone found yet another way to package
+Emacs (most likely on macOS) without putting the executable on ‘$PATH’,
+and we have to add another kludge to find it anyway.
+
+ -- User Option: with-editor-emacsclient-executable
+
+     The ‘emacsclient’ executable used as the editor by child process of
+     this Emacs instance.  By using this executable, child processes can
+     call home to their parent process.
+
+     This option is automatically set at startup by looking in
+     ‘exec-path’, and other places where the executable could be
+     installed, to find the ‘emacsclient’ executable most suitable for
+     the current Emacs instance.
+
+     You should *not* customize this option permanently.  If you have to
+     do it, then you should consider that a temporary kludge and inform
+     the Magit maintainer as described in *note Debugging::.
+
+     If With-Editor fails to find a suitable ‘emacsclient’ on you
+     system, then this should be fixed for all users at once, by
+     teaching ‘with-editor-locate-emacsclient’ how to do so on your
+     system and system like yours.  Doing it this way has the advantage,
+     that you won’t have do it again every time you update Emacs, and
+     that other users who have installed Emacs the same way as you have,
+     won’t have to go through the same trouble.
+
+     Note that there also is a nuclear option; setting this variable to
+     ‘nil’ causes the "sleeping editor" described below to be used even
+     for local child processes.  Obviously we don’t recommend that you
+     use this except in "emergencies", i.e.  before we had a change to
+     add a kludge appropriate for you setup.
+
+ -- Function: with-editor-locate-emacsclient
+
+     The function used to set the initial value of the option
+     ‘with-editor-emacsclient-executable’.  There’s a lot of voodoo
+     here.
+
+   The ‘emacsclient’ cannot be used when using Tramp to run a process on
+a remote machine.  (Theoretically it could, but that would be hard to
+setup, very fragile, and rather insecure).
+
+   With-Editor provides an alternative "editor" which can be used by
+remote processes in much the same way as local processes use an
+‘emacsclient’ executable.  This alternative is known as the "sleeping
+editor" because it is implemented as a shell script which sleeps until
+it receives a signal.
+
+ -- User Option: with-editor-sleeping-editor
+
+     The sleeping editor is a shell script used as the editor of child
+     processes when the ‘emacsclient’ executable cannot be used.
+
+     This fallback is used for asynchronous process started inside the
+     macro ‘with-editor’, when the process runs on a remote machine or
+     for local processes when ‘with-editor-emacsclient-executable’ is
+     ‘nil’.
+
+     Where the latter uses a socket to communicate with Emacs’ server,
+     this substitute prints edit requests to its standard output on
+     which a process filter listens for such requests.  As such it is
+     not a complete substitute for a proper ‘emacsclient’, it can only
+     be used as ‘$EDITOR’ of child process of the current Emacs
+     instance.
+
+     Some shells do not execute traps immediately when waiting for a
+     child process, but by default we do use such a blocking child
+     process.
+
+     If you use such a shell (e.g.  ‘csh’ on FreeBSD, but not Debian),
+     then you have to edit this option.  You can either replace ‘sh’
+     with ‘bash’ (and install that), or you can use the older, less
+     performant implementation:
+
+          "sh -c '\
+          echo \"WITH-EDITOR: $$ OPEN $0\"; \
+          trap \"exit 0\" USR1; \
+          trap \"exit 1\" USR2; \
+          while true; do sleep 1; done'"
+
+     This leads to a delay of up to a second.  The delay can be
+     shortened by replacing ‘sleep 1’ with ‘sleep 0.01’, or if your
+     implementation does not support floats, then by using ‘nanosleep
+     0.01’ instead.
+
+
+File: with-editor.info,  Node: Using With-Editor commands,  Prev: Configuring With-Editor,  Up: Using the With-Editor package
+
+1.2 Using With-Editor commands
+==============================
+
+This section describes how to use the ‘with-editor’ library _outside_ of
+Magit.  You don’t need to know any of this just to create commits using
+Magit.
+
+   The commands ‘with-editor-async-shell-command’ and
+‘with-editor-shell-command’ are intended as drop in replacements for
+‘async-shell-command’ and ‘shell-command’.  They automatically export
+‘$EDITOR’ making sure the executed command uses the current Emacs
+instance as "the editor".  With a prefix argument these commands prompt
+for an alternative environment variable such as ‘$GIT_EDITOR’.
+
+ -- Command: with-editor-async-shell-command
+
+     This command is like ‘async-shell-command’, but it runs the shell
+     command with the current Emacs instance exported as ‘$EDITOR’.
+
+ -- Command: with-editor-shell-command
+
+     This command is like ‘async-shell-command’, but it runs the shell
+     command with the current Emacs instance exported as ‘$EDITOR’.
+     This only has an effect if the shell command is run asynchronously,
+     i.e.  when the command ends with ‘&’.
+
+   To always use these variants add this to you init file:
+
+     (define-key (current-global-map)
+       [remap async-shell-command] 'with-editor-async-shell-command)
+     (define-key (current-global-map)
+       [remap shell-command] 'with-editor-shell-command)
+
+   Alternatively use the global ‘shell-command-with-editor-mode’.
+
+ -- Variable: shell-command-with-editor-mode
+
+     When this mode is active, then ‘$EDITOR’ is exported whenever
+     ultimately ‘shell-command’ is called to asynchronously run some
+     shell command.  This affects most variants of that command, whether
+     they are defined in Emacs or in some third-party package.
+
+   The command ‘with-editor-export-editor’ exports ‘$EDITOR’ or another
+such environment variable in ‘shell-mode’, ‘term-mode’ and ‘eshell-mode’
+buffers.  Use this Emacs command before executing a shell command which
+needs the editor set, or always arrange for the current Emacs instance
+to be used as editor by adding it to the appropriate mode hooks:
+
+     (add-hook 'shell-mode-hook  'with-editor-export-editor)
+     (add-hook 'term-exec-hook   'with-editor-export-editor)
+     (add-hook 'eshell-mode-hook 'with-editor-export-editor)
+
+   Some variants of this function exist; these two forms are equivalent:
+
+     (add-hook 'shell-mode-hook
+               (apply-partially 'with-editor-export-editor "GIT_EDITOR"))
+     (add-hook 'shell-mode-hook 'with-editor-export-git-editor)
+
+ -- Command: with-editor-export-editor
+
+     When invoked in a ‘shell-mode’, ‘term-mode’, or ‘eshell-mode’
+     buffer, this command teaches shell commands to use the current
+     Emacs instance as the editor, by exporting ‘$EDITOR’.
+
+ -- Command: with-editor-export-git-editor
+
+     This command is like ‘with-editor-export-editor’ but exports
+     ‘$GIT_EDITOR’.
+
+ -- Command: with-editor-export-hg-editor
+
+     This command is like ‘with-editor-export-editor’ but exports
+     ‘$HG_EDITOR’.
+
+
+File: with-editor.info,  Node: Using With-Editor as a library,  Next: Debugging,  Prev: Using the With-Editor package,  Up: Top
+
+2 Using With-Editor as a library
+********************************
+
+This section describes how to use the ‘with-editor’ library _outside_ of
+Magit to teach another package how to have its child processes call
+home, just like Magit does.  You don’t need to know any of this just to
+create commits using Magit.  You can also ignore this if you use
+‘with-editor’ outside of Magit, but only as an end-user.
+
+   For information about interactive use and options that affect both
+interactive and non-interactive use, see *note Using the With-Editor
+package::.
+
+ -- Macro: with-editor &rest body
+
+     This macro arranges for the ‘emacsclient’ or the sleeping editor to
+     be used as the editor of child processes, effectively teaching them
+     to call home to the current Emacs instance when they require that
+     the user edits a file.
+
+     This is essentially done by establishing a local binding for
+     ‘process-environment’ and changing the value of the ‘$EDITOR’
+     environment variable in that scope.  This affects all asynchronous
+     processes started by forms (dynamically) inside BODY.
+
+ -- Function: with-editor-set-process-filter process filter
+
+     This function is like ‘set-process-filter’ but ensures that adding
+     the new FILTER does not remove the ‘with-editor-process-filter’.
+     This is done by wrapping the two filter functions using a lambda,
+     which becomes the actual filter.  It calls
+     ‘with-editor-process-filter’ first, passing ‘t’ as
+     NO-STANDARD-FILTER.  Then it calls FILTER.
+
+
+File: with-editor.info,  Node: Debugging,  Prev: Using With-Editor as a library,  Up: Top
+
+3 Debugging
+***********
+
+With-Editor tries very hard to locate a suitable ‘emacsclient’
+executable, and then sets option ‘with-editor-emacsclient-executable’
+accordingly.  In very rare cases this fails.  When it does fail, then
+the most likely reason is that someone found yet another way to package
+Emacs (most likely on macOS) without putting the executable on ‘$PATH’,
+and we have to add another kludge to find it anyway.
+
+   If you are having problems using ‘with-editor’, e.g.  you cannot
+commit in Magit, then please open a new issue at
+<https://github.com/magit/with-editor/issues> and provide information
+about your Emacs installation.  Most importantly how did you install
+Emacs and what is the output of ‘M-x with-editor-debug RET’.
+
+
+
+Tag Table:
+Node: Top772
+Node: Using the With-Editor package2523
+Node: Configuring With-Editor3109
+Node: Using With-Editor commands7506
+Node: Using With-Editor as a library10769
+Node: Debugging12465
+
+End Tag Table
+
+
+Local Variables:
+coding: utf-8
+End:
diff --git a/configs/shared/emacs/.emacs.d/elpa/writeroom-mode-20170623.327/dir b/configs/shared/emacs/.emacs.d/elpa/writeroom-mode-20170623.327/dir
new file mode 100644
index 0000000000..2de9818729
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/writeroom-mode-20170623.327/dir
@@ -0,0 +1,19 @@
+This is the file .../info/dir, which contains the
+topmost node of the Info hierarchy, called (dir)Top.
+The first time you invoke Info you start off looking at this node.
+
+File: dir,	Node: Top	This is the top of the INFO tree
+
+  This (the Directory node) gives a menu of major topics.
+  Typing "q" exits, "?" lists all Info commands, "d" returns here,
+  "h" gives a primer for first-timers,
+  "mEmacs<Return>" visits the Emacs manual, etc.
+
+  In Emacs, you can click mouse button 2 on a menu item or cross reference
+  to select it.
+
+* Menu:
+
+Emacs
+* Writeroom Mode: (writeroom-mode).
+                                Distraction-free writing.
diff --git a/configs/shared/emacs/.emacs.d/elpa/writeroom-mode-20170623.327/writeroom-mode-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/writeroom-mode-20170623.327/writeroom-mode-autoloads.el
new file mode 100644
index 0000000000..882680e581
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/writeroom-mode-20170623.327/writeroom-mode-autoloads.el
@@ -0,0 +1,49 @@
+;;; writeroom-mode-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "writeroom-mode" "writeroom-mode.el" (23377
+;;;;;;  61299 67614 851000))
+;;; Generated autoloads from writeroom-mode.el
+
+(autoload 'writeroom-mode "writeroom-mode" "\
+Minor mode for distraction-free writing.
+
+\(fn &optional ARG)" t nil)
+
+(defvar global-writeroom-mode nil "\
+Non-nil if Global Writeroom mode is enabled.
+See the `global-writeroom-mode' command
+for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `global-writeroom-mode'.")
+
+(custom-autoload 'global-writeroom-mode "writeroom-mode" nil)
+
+(autoload 'global-writeroom-mode "writeroom-mode" "\
+Toggle Writeroom mode in all buffers.
+With prefix ARG, enable Global Writeroom mode if ARG is positive;
+otherwise, disable it.  If called from Lisp, enable the mode if
+ARG is omitted or nil.
+
+Writeroom mode is enabled in all buffers where
+`turn-on-writeroom-mode' would do it.
+See `writeroom-mode' for more information on Writeroom mode.
+
+\(fn &optional ARG)" t nil)
+
+;;;***
+
+;;;### (autoloads nil nil ("writeroom-mode-pkg.el") (23377 61299
+;;;;;;  73576 375000))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; writeroom-mode-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/writeroom-mode-20170623.327/writeroom-mode-pkg.el b/configs/shared/emacs/.emacs.d/elpa/writeroom-mode-20170623.327/writeroom-mode-pkg.el
new file mode 100644
index 0000000000..861e49ac6b
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/writeroom-mode-20170623.327/writeroom-mode-pkg.el
@@ -0,0 +1,8 @@
+(define-package "writeroom-mode" "20170623.327" "Minor mode for distraction-free writing"
+  '((emacs "24.1")
+    (visual-fill-column "1.9"))
+  :keywords
+  '("text"))
+;; Local Variables:
+;; no-byte-compile: t
+;; End:
diff --git a/configs/shared/emacs/.emacs.d/elpa/writeroom-mode-20170623.327/writeroom-mode.el b/configs/shared/emacs/.emacs.d/elpa/writeroom-mode-20170623.327/writeroom-mode.el
new file mode 100644
index 0000000000..777b37233e
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/writeroom-mode-20170623.327/writeroom-mode.el
@@ -0,0 +1,468 @@
+;;; writeroom-mode.el --- Minor mode for distraction-free writing  -*- lexical-binding: t -*-
+
+;; Copyright (c) 2012-2017 Joost Kremers
+
+;; Author: Joost Kremers <joostkremers@fastmail.fm>
+;; Maintainer: Joost Kremers <joostkremers@fastmail.fm>
+;; Created: 11 July 2012
+;; Package-Requires: ((emacs "24.1") (visual-fill-column "1.9"))
+;; Version: 3.7
+;; Keywords: text
+
+;; Redistribution and use in source and binary forms, with or without
+;; modification, are permitted provided that the following conditions
+;; are met:
+;;
+;; 1. Redistributions of source code must retain the above copyright
+;;    notice, this list of conditions and the following disclaimer.
+;; 2. Redistributions in binary form must reproduce the above copyright
+;;    notice, this list of conditions and the following disclaimer in the
+;;    documentation and/or other materials provided with the distribution.
+;; 3. The name of the author may not be used to endorse or promote products
+;;    derived from this software without specific prior written permission.
+;;
+;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+;; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+;; OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+;; IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+;; INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+;; NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ; LOSS OF USE,
+;; DATA, OR PROFITS ; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+;; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+;; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+;; THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+;;; Commentary:
+
+;; writeroom-mode is a minor mode for Emacs that implements a
+;; distraction-free writing mode similar to the famous Writeroom editor for
+;; OS X. writeroom-mode is meant for GNU Emacs 24 and isn't tested on older
+;; versions.
+;;
+;; See the README or info manual for usage instructions.
+;;
+;;; Code:
+
+(require 'visual-fill-column)
+
+(defvar writeroom--frame nil
+  "The frame in which `writeroom-mode' is activated.
+The global effects only apply to this frame.")
+
+(defvar writeroom--buffers nil
+  "List of buffers in which `writeroom-mode' is activated.")
+
+(defvar writeroom--local-variables '(mode-line-format
+                            header-line-format
+                            line-spacing)
+  "Local variables whose values need to be saved when `writeroom-mode' is activated.")
+
+(defvar writeroom--saved-data nil
+  "Buffer-local data to be stored when `writeroom-mode' is activated.
+These settings are restored when `writeroom-mode' is
+deactivated.")
+(make-variable-buffer-local 'writeroom--saved-data)
+
+(defvar writeroom--saved-visual-fill-column nil
+  "Status of `visual-fill-column-mode' before activating `writeroom-mode'.")
+(make-variable-buffer-local 'writeroom--saved-visual-fill-column)
+
+(defvar writeroom--saved-window-config nil
+  "Window configuration active before `writeroom-mode' is activated.")
+
+(defgroup writeroom nil "Minor mode for distraction-free writing."
+  :group 'wp
+  :prefix "writeroom-")
+
+(defcustom writeroom-width 80
+  "Width of the writeroom writing area.
+This can be specified as an absolute width (the number of
+characters in a line), or as a fraction of the total window
+width, in the latter it should be a number between 0 and 1."
+  :group 'writeroom
+  :type '(choice (integer :tag "Absolute width:")
+                 (float :tag "Relative width:" :value 0.5)))
+
+(defcustom writeroom-mode-line nil
+  "The mode line format to use with `writeroom-mode'.
+By default, this option is set to nil, which disables the mode
+line when `writeroom-mode' is activated.  By setting this option
+to t, the standard mode line is retained.  Alternatively, it is
+possible to specify a special mode line for `writeroom-mode'
+buffers.  If this option is chosen, the default is to only show
+the buffer's modification status and the buffer name, but the
+format can be customized.  See the documentation for the variable
+`mode-line-format' for further information.  Note that if you set
+this option, it may be more visually pleasing to set
+`writeroom-bottom-divider-width' to 0."
+  :group 'writeroom
+  :type '(choice (const :tag "Disable the mode line" nil)
+                 (const :tag "Use default mode line" t)
+                 (sexp :tag "Customize mode line"
+                       :value ("   " mode-line-modified "   " mode-line-buffer-identification))))
+
+(defcustom writeroom-mode-line-toggle-position 'header-line-format
+  "Position to temporarily show the mode line.
+When the mode line is disabled, the function
+`writeroom-toggle-mode-line' makes the mode line visible.  This
+option determines whether it is shown as the mode line or as the
+header line."
+  :group 'writeroom
+  :type '(choice (const :tag "Use the mode line" 'mode-line-format)
+                 (const :tag "Use the header line" 'header-line-format)))
+
+(defcustom writeroom-bottom-divider-width 1
+  "Width of the bottom window divider in pixels."
+  :group 'writeroom
+  :type '(integer :tag "Width"))
+
+(make-obsolete-variable 'writeroom-disable-fringe
+                        "The variable `writeroom-disable-fringe' is no longer used."
+                        "`writeroom-mode' version 2.9")
+
+(defcustom writeroom-maximize-window t
+  "Whether to maximize the current window in its frame.
+When set to t, `writeroom-mode' deletes all other windows in
+the current frame."
+  :group 'writeroom
+  :type '(choice (const :tag "Maximize window" t)
+                 (const :tag "Do not maximize window" nil)))
+
+(defcustom writeroom-fullscreen-effect 'fullboth
+  "Effect applied when enabling fullscreen.
+The value can be `fullboth', in which case fullscreen is
+activated, or `maximized', in which case the relevant frame is
+maximized but window decorations are still available."
+  :group 'writeroom
+  :type '(choice (const :tag "Fullscreen" fullboth)
+                 (const :tag "Maximized" maximized)))
+
+(defcustom writeroom-border-width 30
+  "Width in pixels of the border.
+To use this option, select the option \"Add border\" in `Global
+Effects'. This adds a border around the text area."
+  :group 'writeroom
+  :type '(integer :tag "Border width"))
+
+(defcustom writeroom-fringes-outside-margins t
+  "If set, place the fringes outside the margins."
+  :group 'writeroom
+  :type '(choice (const :tag "Place fringes outside margins" t)
+                 (const :tag "Place fringes inside margins" nil)))
+
+(defcustom writeroom-major-modes '(text-mode)
+  "List of major modes in which writeroom-mode is activated.
+The command `global-writeroom-mode' activates `writeroom-mode' in
+every buffer that has one of the major modes listed in this
+option.  Modes can be specified as symbols or as regular
+expressions.  If a buffer has one of the specified major modes or
+if its major mode name matches one of the regular expressions,
+`writeroom-mode' is activated."
+  :group 'writeroom
+  :type '(repeat (choice (symbol :tag "Major mode")
+                         (string :tag "Regular expression"))))
+
+(defcustom writeroom-use-derived-modes t
+  "Activate `writeroom-mode' in derived modes as well.'.
+If this option is set, the command `global-writeroom-mode'
+activates `writeroom-mode' in modes that are derived from those
+listed in `writeroom-major-modes'.  Note that this option applies
+only to symbols in `writeroom-major-modes'.  Regular expressions
+are ignored."
+  :group 'writeroom
+  :type '(choice (const :tag "Use derived modes" t)
+                 (const :tag "Do not use derived modes" nil)))
+
+(defcustom writeroom-major-modes-exceptions nil
+  "List of major modes in which `writeroom-mode' should not be activated.
+This option lists exceptions to `writeroom-major-modes'.  Modes
+can be specified as symbols or as regular expressions."
+  :group 'writeroom
+  :type '(repeat (choice (symbol :tag "Major mode exception")
+                         (string :tag "Regular expression"))))
+
+(defcustom writeroom-restore-window-config nil
+  "If set, restore window configuration after disabling `writeroom-mode'.
+Setting this option makes sense primarily if `writeroom-mode' is
+used in one buffer only.  The window configuration that is stored
+is the one that exists when `writeroom-mode' is first called, and
+it is restored when `writeroom-mode' is deactivated in the last
+buffer."
+  :group 'writeroom
+  :type '(choice (const :tag "Do not restore window configuration" nil)
+                 (const :tag "Restore window configuration" t)))
+
+(defcustom writeroom-extra-line-spacing nil
+  "Additional line spacing for `writeroom-mode`."
+  :group 'writeroom
+  :type '(choice (const :tag "Do not add extra line spacing" :value nil)
+                 (integer :tag "Absolute height" :value 5)
+                 (float :tag "Relative height" :value 0.8)))
+
+(defcustom writeroom-global-effects '(writeroom-set-fullscreen
+                             writeroom-set-alpha
+                             writeroom-set-menu-bar-lines
+                             writeroom-set-tool-bar-lines
+                             writeroom-set-vertical-scroll-bars
+                             writeroom-set-bottom-divider-width)
+  "List of global effects for `writeroom-mode'.
+These effects are enabled when `writeroom-mode' is activated in
+the first buffer and disabled when it is deactivated in the last
+buffer."
+  :group 'writeroom
+  :type '(set (const :tag "Fullscreen" writeroom-set-fullscreen)
+              (const :tag "Disable transparency" writeroom-set-alpha)
+              (const :tag "Disable menu bar" writeroom-set-menu-bar-lines)
+              (const :tag "Disable tool bar" writeroom-set-tool-bar-lines)
+              (const :tag "Disable scroll bar" writeroom-set-vertical-scroll-bars)
+              (const :tag "Enable bottom window divider" writeroom-set-bottom-divider-width)
+              (const :tag "Add border" writeroom-set-internal-border-width)
+              (const :tag "Display frame on all workspaces" writeroom-set-sticky)
+              (repeat :inline t :tag "Custom effects" function)))
+
+(define-obsolete-variable-alias 'writeroom-global-functions 'writeroom-global-effects "`writeroom-mode' version 2.0")
+
+(defmacro define-writeroom-global-effect (fp value)
+  "Define a global effect for `writeroom-mode'.
+The effect is activated by setting frame parameter FP to VALUE.
+FP should be an unquoted symbol, the name of a frame parameter;
+VALUE must be quoted (unless it is a string or a number, of
+course).  It can also be an unquoted symbol, in which case it
+should be the name of a global variable whose value is then
+assigned to FP.
+
+This macro defines a function `writeroom-set-<FP>' that takes one
+argument and activates the effect if this argument is 1 and
+deactivates it if it is -1.  When the effect is activated, the
+original value of frame parameter FP is stored in a frame
+parameter `writeroom-<FP>', so that it can be restored when the
+effect is deactivated."
+  (declare (indent defun))
+  (let ((wfp (intern (format "writeroom-%s" fp))))
+    `(fset (quote ,(intern (format "writeroom-set-%s" fp)))
+           (lambda (&optional arg)
+             (when (frame-live-p writeroom--frame)
+               (cond
+                ((= arg 1)         ; activate
+                 (set-frame-parameter writeroom--frame (quote ,wfp) (frame-parameter writeroom--frame (quote ,fp)))
+                 (set-frame-parameter writeroom--frame (quote ,fp) ,value))
+                ((= arg -1)        ; deactivate
+                 (set-frame-parameter writeroom--frame (quote ,fp) (frame-parameter writeroom--frame (quote ,wfp)))
+                 (set-frame-parameter writeroom--frame (quote ,wfp) nil))))))))
+
+(define-writeroom-global-effect fullscreen writeroom-fullscreen-effect)
+(define-writeroom-global-effect alpha '(100 100))
+(define-writeroom-global-effect vertical-scroll-bars nil)
+(define-writeroom-global-effect menu-bar-lines 0)
+(define-writeroom-global-effect tool-bar-lines 0)
+(define-writeroom-global-effect internal-border-width writeroom-border-width)
+(define-writeroom-global-effect sticky t)
+(define-writeroom-global-effect bottom-divider-width writeroom-bottom-divider-width)
+
+(defun turn-on-writeroom-mode ()
+  "Turn on `writeroom-mode'.
+This function activates `writeroom-mode' in a buffer if that
+buffer's major mode matchs against one of `writeroom-major-modes'."
+  (unless (writeroom--match-major-mode writeroom-major-modes-exceptions)
+    (if (writeroom--match-major-mode writeroom-major-modes writeroom-use-derived-modes)
+        (writeroom-mode 1))))
+
+(defun writeroom--match-major-mode (modes &optional derived)
+  "Match the current buffer's major mode against MODES.
+MODES a list of mode names (symbols) or regular expressions.
+Return t if the current major mode matches one of the elements of
+MODES, nil otherwise.  Comparison is done with `eq` (for symbols
+in MODES) or with `string-match-p' (for strings in MODES).  That
+is, if the major mode is e.g., `emacs-lisp-mode', it will not
+match the symbol `lisp-mode', but it will match the string
+\"lisp-mode\".
+
+If DERIVED is non-nil, also return t if the current buffer's
+major mode is a derived mode of one of the major mode symbols in
+MODES."
+  (catch 'match
+    (dolist (elem modes)
+      (if (cond ((symbolp elem)
+                 (or (eq elem major-mode)
+                     (and derived (derived-mode-p elem))))
+                ((string-match-p elem (symbol-name major-mode))))
+          (throw 'match t)))))
+
+(defvar writeroom-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "s-?") #'writeroom-toggle-mode-line)
+    map)
+  "Keymap for writeroom-mode.")
+
+;;;###autoload
+(define-minor-mode writeroom-mode
+  "Minor mode for distraction-free writing."
+  :init-value nil :lighter nil :global nil
+  (if writeroom-mode
+      (writeroom--enable)
+    (writeroom--disable)))
+
+;;;###autoload
+(define-globalized-minor-mode global-writeroom-mode writeroom-mode turn-on-writeroom-mode
+  :require 'writeroom-mode
+  :group 'writeroom)
+
+(defun writeroom--kill-buffer-function ()
+  "Disable `writeroom-mode' before killing a buffer, if necessary.
+This function is for use in `kill-buffer-hook'.  It checks whether
+`writeroom-mode' is enabled in the buffer to be killed and
+adjusts `writeroom--buffers' and the global effects accordingly."
+  (when writeroom-mode
+    (setq writeroom--buffers (delq (current-buffer) writeroom--buffers))
+    (when (not writeroom--buffers)
+      (writeroom--set-global-effects -1)
+      (setq writeroom--frame nil))))
+
+(add-hook 'kill-buffer-hook #'writeroom--kill-buffer-function)
+
+(defun writeroom--set-global-effects (arg)
+  "Activate or deactivate global effects.
+The effects are activated if ARG is 1, deactivated if it is -1."
+  (mapc (lambda (fn)
+          (funcall fn arg))
+        writeroom-global-effects))
+
+(defun writeroom--calculate-width ()
+  "Calculate the width of the writing area."
+  (if (floatp writeroom-width)
+      (truncate (* (window-total-width) writeroom-width))
+    writeroom-width))
+
+(defvar writeroom--mode-line-showing nil
+  "Flag indicating whether the original mode line is displayed.")
+(make-variable-buffer-local 'writeroom--mode-line-showing)
+
+(defvar writeroom--orig-header-line nil
+  "Original format of the header line.
+When the header line is used to temporarily display the mode
+line, its original format is saved here.")
+(make-variable-buffer-local 'writeroom--orig-header-line)
+
+(defun writeroom-toggle-mode-line ()
+  "Toggle display of the original mode."
+  (interactive)
+  (unless (eq writeroom-mode-line t) ; This means the original mode-line is displayed already.
+    (cond
+     ((not writeroom--mode-line-showing)
+      (setq writeroom--orig-header-line header-line-format)
+      (set writeroom-mode-line-toggle-position (or (cdr (assq 'mode-line-format writeroom--saved-data))
+                                          (default-value 'mode-line-format)))
+      (setq writeroom--mode-line-showing t))
+     (writeroom--mode-line-showing
+      (if (eq writeroom-mode-line-toggle-position 'header-line-format)
+          (setq header-line-format writeroom--orig-header-line)
+        (setq mode-line-format writeroom-mode-line))
+      (setq writeroom--mode-line-showing nil)))
+    (force-mode-line-update)))
+
+(defun writeroom-adjust-width (amount)
+  "Adjust the width of the writing area on the fly by AMOUNT.
+A numeric prefix argument can be used to specify the adjustment.
+When called without a prefix, this will reset the width to the default value."
+  (interactive "P")
+  (if amount
+      (setq visual-fill-column-width (max 1 (+ visual-fill-column-width amount)))
+    (setq visual-fill-column-width (writeroom--calculate-width)))
+  (visual-fill-column--adjust-window)
+  (message "Writing area is now %d characters wide" visual-fill-column-width))
+
+(defun writeroom-increase-width ()
+  "Increase the width of the writing area by 2 characters."
+  (interactive)
+  (writeroom-adjust-width 2))
+
+(defun writeroom-decrease-width ()
+  "Decrease the width of the writing area by 2 characters."
+  (interactive)
+  (writeroom-adjust-width -2))
+
+(defun writeroom--enable ()
+  "Set up writeroom-mode for the current buffer.
+Also run the functions in `writeroom-global-effects' if the
+current buffer is the first buffer in which `writeroom-mode' is
+activated."
+  ;; save buffer-local variables, if they have a buffer-local binding
+  (setq writeroom--saved-data (mapcar (lambda (sym)
+                               (if (local-variable-p sym)
+                                   (cons sym (buffer-local-value sym (current-buffer)))
+                                 sym))
+                             writeroom--local-variables))
+  (setq writeroom--saved-visual-fill-column visual-fill-column-mode)
+
+  ;; activate global effects
+  (when (not writeroom--buffers)
+    (setq writeroom--frame (selected-frame))
+    (writeroom--set-global-effects 1)
+    (if writeroom-restore-window-config
+        (setq writeroom--saved-window-config (current-window-configuration))))
+
+  (push (current-buffer) writeroom--buffers)
+
+  (when writeroom-maximize-window
+    (delete-other-windows))
+
+  (when writeroom-extra-line-spacing
+    (setq line-spacing writeroom-extra-line-spacing))
+
+  (unless (eq writeroom-mode-line t) ; if t, use standard mode line
+    (setq mode-line-format writeroom-mode-line))
+
+  (setq visual-fill-column-width (writeroom--calculate-width)
+        visual-fill-column-center-text t
+        visual-fill-column-fringes-outside-margins writeroom-fringes-outside-margins)
+  (visual-fill-column-mode 1)
+
+  ;; if the current buffer is displayed in some window, the windows'
+  ;; margins and fringes must be adjusted.
+  (mapc (lambda (w)
+          (with-selected-window w
+            (visual-fill-column--adjust-window)))
+        (get-buffer-window-list (current-buffer) nil)))
+
+(defun writeroom--disable ()
+  "Reset the current buffer to its normal appearance.
+Also run the functions in `writeroom-global-effects' to undo
+their effects if `writeroom-mode' is deactivated in the last
+buffer in which it was active."
+  ;; disable visual-fill-column-mode
+  (visual-fill-column-mode -1)
+  (kill-local-variable 'visual-fill-column-width)
+  (kill-local-variable 'visual-fill-column-center-text)
+  (kill-local-variable 'visual-fill-column-fringes-outside-margins)
+
+  ;; restore global effects if necessary
+  (setq writeroom--buffers (delq (current-buffer) writeroom--buffers))
+  (when (not writeroom--buffers)
+    (writeroom--set-global-effects -1)
+    (setq writeroom--frame nil)
+    (if writeroom-restore-window-config
+        (set-window-configuration writeroom--saved-window-config)))
+
+  ;; restore local variables
+  (mapc (lambda (val)
+          (if (symbolp val)
+              (kill-local-variable val)
+            (set (car val) (cdr val))))
+        writeroom--saved-data)
+
+  ;; if the current buffer is displayed in some window, the windows'
+  ;; margins and fringes must be adjusted.
+  (mapc (lambda (w)
+          (with-selected-window w
+            (set-window-margins (selected-window) 0 0)
+            (set-window-fringes (selected-window) nil)))
+        (get-buffer-window-list (current-buffer) nil))
+
+  ;; reenable `visual-fill-colummn-mode' with original settings if it was
+  ;; active before activating `writeroom-mode'.
+  (if writeroom--saved-visual-fill-column
+      (visual-fill-column-mode 1)))
+
+(provide 'writeroom-mode)
+
+;;; writeroom-mode.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/writeroom-mode-20170623.327/writeroom-mode.elc b/configs/shared/emacs/.emacs.d/elpa/writeroom-mode-20170623.327/writeroom-mode.elc
new file mode 100644
index 0000000000..ea68c32bd5
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/writeroom-mode-20170623.327/writeroom-mode.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/writeroom-mode-20170623.327/writeroom-mode.info b/configs/shared/emacs/.emacs.d/elpa/writeroom-mode-20170623.327/writeroom-mode.info
new file mode 100644
index 0000000000..56947bd9bd
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/writeroom-mode-20170623.327/writeroom-mode.info
@@ -0,0 +1,543 @@
+This is writeroom-mode.info, produced by makeinfo version 6.1 from
+writeroom-mode.texi.
+
+INFO-DIR-SECTION Emacs
+START-INFO-DIR-ENTRY
+* Writeroom Mode: (writeroom-mode).        Distraction-free writing.
+END-INFO-DIR-ENTRY
+
+
+File: writeroom-mode.info,  Node: Top,  Next: Writeroom-mode,  Up: (dir)
+
+Top
+***
+
+* Menu:
+
+* Writeroom-mode::
+
+
+File: writeroom-mode.info,  Node: Writeroom-mode,  Prev: Top,  Up: Top
+
+1 Writeroom-mode
+****************
+
+‘writeroom-mode’ is a minor mode for Emacs that implements a
+distraction-free writing mode similar to the famous Writeroom editor for
+OS X. ‘writeroom-mode’ is meant for GNU Emacs 24, lower versions are not
+actively supported.
+* Menu:
+
+* Installation::
+* Usage::
+* Multiple writeroom-mode buffers::
+* Frame effects::
+* Customisation::
+* Changing the width interactively::
+* Text size adjustments::
+* Displaying the mode line::
+* Adding global effects::
+* Other similar modes::
+
+
+File: writeroom-mode.info,  Node: Installation,  Next: Usage,  Up: Writeroom-mode
+
+1.1 Installation
+================
+
+‘writeroom-mode’ can be installed through the package manager from Melpa
+(http://melpa.org/).  If installing manually, make sure to also install
+its dependency ‘visual-fill-column’
+(https://github.com/joostkremers/visual-fill-column).
+
+
+File: writeroom-mode.info,  Node: Usage,  Next: Multiple writeroom-mode buffers,  Prev: Installation,  Up: Writeroom-mode
+
+1.2 Usage
+=========
+
+‘writeroom-mode’ can be activated in a buffer by calling ‘M-x
+writeroom-mode RET’.  By default, ‘writeroom-mode’ does the following
+things:
+
+   • activate fullscreen
+   • disable transparency
+   • disable the menu bar
+   • disable the tool bar
+   • disable the scroll bar
+   • enable a bottom window divider of 1 pixel
+   • maximise the current window (i.e., delete all other windows in the
+     frame)
+   • place the fringes outside the margins
+   • disable the mode line
+   • add window margins to the current buffer so that the text is 80
+     characters wide
+
+The last three effects are buffer-local.  The other effects apply to the
+current frame.  Because ‘writeroom-mode’ is a minor mode, this isn’t
+entirely on the up and up, since minor modes aren’t supposed to have
+such global effects.  But ‘writeroom-mode’ is meant for distraction-free
+writing, so these effects do make sense.
+
+All these effects can be disabled or customised.  In addition, there are
+several more options that are disabled by default but can be enabled in
+the customisation buffer.
+
+
+File: writeroom-mode.info,  Node: Multiple writeroom-mode buffers,  Next: Frame effects,  Prev: Usage,  Up: Writeroom-mode
+
+1.3 Multiple writeroom-mode buffers
+===================================
+
+It is possible to activate ‘writeroom-mode’ in more than one buffer.
+The global effects are of course activated only once and they remain
+active until ‘writeroom-mode’ is deactivated in _all_ buffers.
+Alternatively, if you wish to use ‘writeroom-mode’ in all buffers that
+have a particular major mode (e.g., ‘text-mode’, ‘markdown-mode’), you
+can use the global minor mode ‘global-writeroom-mode’.  This function
+enables the global effects and activates the buffer-local effects in all
+(current and future) buffers that have a major mode listed in the user
+option ‘writeroom-major-modes’ (by default only ‘text-mode’).
+
+When ‘global-writeroom-mode’ is active, the function ‘writeroom-mode’
+can still be called to enable or disable ‘writeroom-mode’ in individual
+buffers (regardless of their major mode, of course).  Calling
+‘global-writeroom-mode’ again disables ‘writeroom-mode’ in all buffers
+in which it is active, also those in which it was activated manually.
+
+
+File: writeroom-mode.info,  Node: Frame effects,  Next: Customisation,  Prev: Multiple writeroom-mode buffers,  Up: Writeroom-mode
+
+1.4 Frame effects
+=================
+
+Most of the global effects that ‘writeroom-mode’ enables are handled by
+setting specific frame parameters.  This means that they apply to the
+current frame.  If you switch to another frame and display a
+‘writeroom-mode’ buffer, only the buffer-local effects will be visible.
+
+‘writeroom-mode’ tries to make sure that it only affects one frame, and
+that it restores that particular frame when it is deactivated in the
+last buffer.  This means it should be safe to activate ‘writeroom-mode’
+in one frame and deactivate it in another.  Killing the ‘writeroom-mode’
+frame should also be safe.
+
+The affected frame is always restored to its original state, before
+‘writeroom-mode’ was activated, even if you change any of the frame
+parameters manually while ‘writeroom-mode’ is active.
+
+
+File: writeroom-mode.info,  Node: Customisation,  Next: Changing the width interactively,  Prev: Frame effects,  Up: Writeroom-mode
+
+1.5 Customisation
+=================
+
+* Menu:
+
+* Global Writeroom Mode::
+* Border Width::
+* Extra Line Spacing::
+* Fringes Outside Margins::
+* Fullscreen Effect::
+* Bottom Divider Width::
+* Global Effects::
+* Major Modes::
+* Use Derived Modes::
+* Major Modes Exceptions::
+* Maximize Window::
+* Mode Line::
+* Mode Line Toggle Position::
+* Restore Window Config::
+* Width::
+
+
+File: writeroom-mode.info,  Node: Global Writeroom Mode,  Next: Border Width,  Up: Customisation
+
+1.5.1 Global Writeroom Mode
+---------------------------
+
+Activate this option to automatically turn on ‘writeroom-mode’ in any
+buffer that has one of the major modes matched any mask listed in
+‘writeroom-major-modes’ and not in ‘writeroom-major-modes’.
+
+
+File: writeroom-mode.info,  Node: Border Width,  Next: Extra Line Spacing,  Prev: Global Writeroom Mode,  Up: Customisation
+
+1.5.2 Border Width
+------------------
+
+Width of the border around the text area.  Disabled by default, see
+‘writeroom-global-effects’ to enable the border.
+
+
+File: writeroom-mode.info,  Node: Extra Line Spacing,  Next: Fringes Outside Margins,  Prev: Border Width,  Up: Customisation
+
+1.5.3 Extra Line Spacing
+------------------------
+
+Increase the line spacing.  Can be an absolute value (the number of
+pixels to add to the line) or a number relative to the default line
+height.  Disabled by default.
+
+
+File: writeroom-mode.info,  Node: Fringes Outside Margins,  Next: Fullscreen Effect,  Prev: Extra Line Spacing,  Up: Customisation
+
+1.5.4 Fringes Outside Margins
+-----------------------------
+
+If set, place the fringes outside the margins.  ‘writeroom-mode’ expands
+the window margins, causing the fringes to be pushed inside, which may
+be visually distracting.  This option keeps the fringes at the window’s
+edges.  Unset it if you prefer to have the fringes close to the text.
+
+
+File: writeroom-mode.info,  Node: Fullscreen Effect,  Next: Bottom Divider Width,  Prev: Fringes Outside Margins,  Up: Customisation
+
+1.5.5 Fullscreen Effect
+-----------------------
+
+Effect to apply when ‘writeroom-mode’ activates fullscreen.  Can be
+‘fullboth’, which uses the entire screen (i.e., window decorations are
+disabled and the window manager’s panel or task bar is covered by the
+Emacs frame) or ‘maximized’, in which case the Emacs frame is maximised
+but keeps its window decorations and does not cover the panel.
+
+
+File: writeroom-mode.info,  Node: Bottom Divider Width,  Next: Global Effects,  Prev: Fullscreen Effect,  Up: Customisation
+
+1.5.6 Bottom Divider Width
+--------------------------
+
+Width in pixels of the bottom window divider.  Default value is 1.  The
+bottom window divider helps in distinguishing the minibuffer from the
+text area, and also in distinguishing two windows split top-to-bottom.
+
+
+File: writeroom-mode.info,  Node: Global Effects,  Next: Major Modes,  Prev: Bottom Divider Width,  Up: Customisation
+
+1.5.7 Global Effects
+--------------------
+
+List of global effects:
+
+   • fullscreen
+   • transparency
+   • scroll bar
+   • menu bar
+   • tool bar
+   • bottom window divider
+   • border (add a border around the text area; disabled by default)
+   • sticky (display the window on all virtual workspaces; disabled by
+     default)
+
+Each option can be enabled or disabled individually.
+
+
+File: writeroom-mode.info,  Node: Major Modes,  Next: Use Derived Modes,  Prev: Global Effects,  Up: Customisation
+
+1.5.8 Major Modes
+-----------------
+
+List of major modes in which ‘writeroom-mode’ should be activated
+automatically.  Use in conjunction with ‘global-writeroom-mode’.
+
+The elements in this list can be major-mode symbols, or regular
+expressions (in which case they must of course be strings).
+
+
+File: writeroom-mode.info,  Node: Use Derived Modes,  Next: Major Modes Exceptions,  Prev: Major Modes,  Up: Customisation
+
+1.5.9 Use Derived Modes
+-----------------------
+
+If this option is set, ‘global-writeroom-mode’ also activates
+‘writeroom-mode’ in buffers whose major mode is a derived mode of one of
+the modes in ‘writeroom-major-modes’.  (Only the major mode symbols in
+‘writeroom-major-modes’ are relevant.)
+
+
+File: writeroom-mode.info,  Node: Major Modes Exceptions,  Next: Maximize Window,  Prev: Use Derived Modes,  Up: Customisation
+
+1.5.10 Major Modes Exceptions
+-----------------------------
+
+List of major modes in which ‘writeroom-mode’ should not be activated by
+‘global-writeroom-mode’.  (It is still possible to activate
+‘writeroom-mode’ manually).  This can also be a mixed list of major-mode
+symbols and regular expressions.
+
+
+File: writeroom-mode.info,  Node: Maximize Window,  Next: Mode Line,  Prev: Major Modes Exceptions,  Up: Customisation
+
+1.5.11 Maximize Window
+----------------------
+
+Maximise the current window in its frame, i.e., delete all other
+windows.
+
+
+File: writeroom-mode.info,  Node: Mode Line,  Next: Mode Line Toggle Position,  Prev: Maximize Window,  Up: Customisation
+
+1.5.12 Mode Line
+----------------
+
+The mode line format to use.  This option can be ‘nil’, which disables
+the mode line altogether (which is the default), it can be ‘t’, which
+retains the mode line, or it can be set to a customised format to only
+show some information.  If the latter option is chosen, the mode line
+shows only the file name and the file modification status, but the
+format can be customised.  See the documentation for the variable
+‘mode-line-format’ for details.  If you set this option, it may be more
+visually pleasing to set the option Bottom Divider Width to 0.
+
+
+File: writeroom-mode.info,  Node: Mode Line Toggle Position,  Next: Restore Window Config,  Prev: Mode Line,  Up: Customisation
+
+1.5.13 Mode Line Toggle Position
+--------------------------------
+
+If you disable or customise the mode line, you may sometimes want to see
+the entire mode line.  ‘writeroom-mode’ provides the function
+‘writeroom-toggle-mode-line’ (see below) to do this.  You can specify
+where you want to make the mode line visible when using this function:
+in the mode line itself, or in the header line.
+
+Note that the default value of this option is to display the mode line
+in the header line, because for some reason that is more reliable.
+(Toggling the mode line multiple times in a row does not always work
+very well.)
+
+
+File: writeroom-mode.info,  Node: Restore Window Config,  Next: Width,  Prev: Mode Line Toggle Position,  Up: Customisation
+
+1.5.14 Restore Window Config
+----------------------------
+
+Restore the window configuration that existed before ‘writeroom-mode’
+was activated.  This is primarily useful if you use ‘writeroom-mode’ in
+only a single buffer, since the window configuration that is restored is
+the one that existed at the moment when ‘writeroom-mode’ is called for
+the first time.  Disabled by default.
+
+
+File: writeroom-mode.info,  Node: Width,  Prev: Restore Window Config,  Up: Customisation
+
+1.5.15 Width
+------------
+
+Width of the text area.  Can be specified as an absolute value (number
+of characters) or as a fraction of the total window width (in which case
+it should be a number between 0 and 1).
+
+
+File: writeroom-mode.info,  Node: Changing the width interactively,  Next: Text size adjustments,  Prev: Customisation,  Up: Writeroom-mode
+
+1.6 Changing the width interactively
+====================================
+
+The width of the text area in the current buffer can be changed
+interactively with the commands ‘writeroom-increase-width’ and
+‘writeroom-decrease-width’, which increase and decrease the text width
+by 2 characters.  There is also a more general command
+‘writeroom-adjust-width’, which adjusts the width of the text area by
+the amount passed as prefix argument.  That is, calling it with ‘M-5 M-x
+writeroom-adjust-width’ increases the text width by 5 characters.
+Calling ‘writeroom-adjust-width’ without prefix argument resets the
+width to the default value.
+
+These commands are not bound to any keys, but you can bind them in the
+following manner (the actual keys are just examples, of course; choose
+any keys you like):
+
+(with-eval-after-load 'writeroom-mode
+  (define-key writeroom-mode-map (kbd "C-M-<") #'writeroom-decrease-width)
+  (define-key writeroom-mode-map (kbd "C-M->") #'writeroom-increase-width)
+  (define-key writeroom-mode-map (kbd "C-M-=") #'writeroom-adjust-width))
+
+
+File: writeroom-mode.info,  Node: Text size adjustments,  Next: Displaying the mode line,  Prev: Changing the width interactively,  Up: Writeroom-mode
+
+1.7 Text size adjustments
+=========================
+
+Text size adjustments are taken into account in calculating the margins,
+which means that if the text size is increased, the margins are
+decreased, so that the number of characters on the line remains more or
+less the same.  Since it is not possible to detect interactive text size
+adjustments (e.g., with ‘text-size-adjust’), the adjustments of the
+margins cannot be made automatically.  You need to force a redisplay,
+e.g., with the command ‘redraw-display’.
+
+Alternatively, you can advise the command you use for adjusting the text
+size (most likely ‘text-size-adjust’):
+
+(advice-add 'text-scale-adjust :after
+  #'visual-fill-column-adjust)
+
+
+File: writeroom-mode.info,  Node: Displaying the mode line,  Next: Adding global effects,  Prev: Text size adjustments,  Up: Writeroom-mode
+
+1.8 Displaying the mode line
+============================
+
+By default, ‘writeroom-mode’ disables the mode line.  If you
+occasionally need to see the full mode line, you can use the command
+‘writeroom-toggle-mode-line’, which makes the mode line visible.
+Calling it again hides the mode line.  This command is bound to ‘s-?’
+(‘s’ is the super key, i.e., the Windows key on PCs, the ⌘ key on Macs),
+but it can be rebound by putting something like the following in your
+‘init.el’:
+
+(with-eval-after-load 'writeroom-mode
+  (define-key writeroom-mode-map (kbd "s-?") nil)
+  (define-key writeroom-mode-map (kbd "<some-key>") #’writeroom-toggle-mode-line))
+
+The first ‘define-key’ disables the binding for ‘s-?’.  Substitute your
+preferred key binding in the second line to bind
+‘writeroom-toggle-mode-line’ to it.
+
+
+File: writeroom-mode.info,  Node: Adding global effects,  Next: Other similar modes,  Prev: Displaying the mode line,  Up: Writeroom-mode
+
+1.9 Adding global effects
+=========================
+
+It is possible to add your own global effects to ‘writeroom-mode’.  If
+there is a global minor mode that you want turned on when
+‘writeroom-mode’ is activated for the first time, you can simply add it
+to the user option ‘writeroom-global-effects’ by checking the box
+"Custom effects", clicking the [INS] button and adding the function to
+the list.
+
+Alternatively, you can also write your own function.  This function
+should take one argument and enable the effect if the argument is ‘1’
+and disable it if the argument is ‘-1’.  To give an example, if you want
+to activate a minimalist colour theme in ‘writeroom-mode’, you can write
+the following function:
+
+(defun my-writeroom-theme (arg)
+  (cond
+   ((= arg 1)
+    (enable-theme 'minimalist-dark))
+   ((= arg -1)
+    (disable-theme 'minimalist-dark))))
+
+If your function affects the frame, you should make sure that it only
+affects the ‘writeroom-mode’ frame by passing the variable
+‘writeroom--frame’ to all frame-changing functions.  If your frame
+effect involves changing the value of a frame parameter, you may be able
+to use the macro ‘define-writeroom-global-effect’; see its doc string
+for details.
+
+In principle, it is not a good idea to define a custom global effect
+function as a toggle, but if you are sure you’ll only ever use a single
+frame, it should be safe enough.  For example, sometimes setting the
+‘fullscreen’ frame parameter does not work.  In this case, if you’re on
+Linux, you could send an X client message directly:
+
+(defun my-toggle-fullscreen (_)
+  (x-send-client-message nil 0 nil "_NET_WM_STATE" 32
+                         '(2 "_NET_WM_STATE_FULLSCREEN" 0)))
+
+
+File: writeroom-mode.info,  Node: Other similar modes,  Prev: Adding global effects,  Up: Writeroom-mode
+
+1.10 Other similar modes
+========================
+
+There are two other modes that I know of that also implement a
+distraction-free writing environment: Darkroom
+(https://github.com/joaotavora/darkroom) and Olivetti
+(https://github.com/rnkn/olivetti).  Both are narrower in scope than
+‘writeroom-mode’.
+
+In particular, both Darkroom and Olivetti only affect the buffer (or
+more precisely, its window), not the frame.  They centre the text by
+adding window margins, and optionally resize the text and hide the mode
+line.  They do not make Emacs fullscreen and do not remove the menu and
+tool bars, the scroll bar or the window decorations.  This is a
+conscious choice (see, e.g., this pull request
+(https://github.com/joaotavora/darkroom/pull/2) and this issue
+(https://github.com/rnkn/olivetti/issues/6)), motivated by the fact that
+affecting the frame in this way may lead to problems when using multiple
+Emacs frames.
+
+It is true that changing the appearance of the current frame (the global
+effects, as ‘writeroom-mode’ calls them) is risky if you use multiple
+frames.  ‘writeroom-mode’ applies its global effects to the frame that
+is current when it is first activated and tries to make sure that _only_
+this frame is ever affected.  Therefore, it should be safe to use
+‘writeroom-mode’, even if you use multiple frames.  (If you do run into
+issues, however, I would welcome a bug report.)  Alternatively, you can
+turn off all global effects and use ‘writeroom-mode’ in much the same
+way as Darkroom or Olivetti.
+
+Another difference with Darkroom and Olivetti is that ‘writeroom-mode’
+tries to be as customisable as possible.  It has a larger number of
+customisation options than either of the other modes and also provides a
+way to add custom global effects.  This may or may not be what you need,
+of course.
+
+
+
+Tag Table:
+Node: Top222
+Node: Writeroom-mode336
+Ref: #writeroom-mode445
+Node: Installation931
+Ref: #installation1051
+Node: Usage1295
+Ref: #usage1441
+Node: Multiple writeroom-mode buffers2547
+Ref: #multiple-writeroom-mode-buffers2746
+Node: Frame effects3764
+Ref: #frame-effects3935
+Node: Customisation4744
+Ref: #customisation4916
+Node: Global Writeroom Mode5251
+Ref: #global-writeroom-mode5408
+Node: Border Width5617
+Ref: #border-width5783
+Node: Extra Line Spacing5905
+Ref: #extra-line-spacing6085
+Node: Fringes Outside Margins6252
+Ref: #fringes-outside-margins6447
+Node: Fullscreen Effect6740
+Ref: #fullscreen-effect6925
+Node: Bottom Divider Width7284
+Ref: #bottom-divider-width7466
+Node: Global Effects7680
+Ref: #global-effects7844
+Node: Major Modes8199
+Ref: #major-modes8354
+Node: Use Derived Modes8619
+Ref: #use-derived-modes8794
+Node: Major Modes Exceptions9056
+Ref: #major-modes-exceptions9247
+Node: Maximize Window9499
+Ref: #maximize-window9668
+Node: Mode Line9743
+Ref: #mode-line9903
+Node: Mode Line Toggle Position10466
+Ref: #mode-line-toggle-position10664
+Node: Restore Window Config11217
+Ref: #restore-window-config11403
+Node: Width11740
+Ref: #width11860
+Node: Changing the width interactively12045
+Ref: #changing-the-width-interactively12263
+Node: Text size adjustments13268
+Ref: #text-size-adjustments13475
+Node: Displaying the mode line14132
+Ref: #displaying-the-mode-line14334
+Node: Adding global effects15120
+Ref: #adding-global-effects15314
+Node: Other similar modes16999
+Ref: #other-similar-modes17158
+
+End Tag Table
+
+
+Local Variables:
+coding: utf-8
+End:
diff --git a/configs/shared/emacs/.emacs.d/elpa/xterm-color-20180202.1518/xterm-color-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/xterm-color-20180202.1518/xterm-color-autoloads.el
new file mode 100644
index 0000000000..d90d6ecaab
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/xterm-color-20180202.1518/xterm-color-autoloads.el
@@ -0,0 +1,43 @@
+;;; xterm-color-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "xterm-color" "xterm-color.el" (23377 61305
+;;;;;;  461603 642000))
+;;; Generated autoloads from xterm-color.el
+
+(autoload 'xterm-color-filter "xterm-color" "\
+Translate ANSI color sequences in STRING into text properties.
+Returns new STRING with text properties applied.
+
+This function will check if `xterm-color-preserve-properties' is
+set to T and only call `xterm-color-filter-real' on substrings
+that do not have text properties applied (passing through the rest
+unmodified).  Preserving properties in this fashion is really a hack
+and not very robust as there may be situations where text properties
+are applied on ANSI data, which will mess up the state machine.
+It works fine with and is really meant for eshell though.
+
+This can be inserted into `comint-preoutput-filter-functions'.
+
+\(fn STRING)" nil nil)
+
+(autoload 'xterm-color-colorize-buffer "xterm-color" "\
+Apply `xterm-color-filter' to current buffer, and replace its contents.
+
+\(fn)" t nil)
+
+(autoload 'xterm-color-test "xterm-color" "\
+Create and display a new buffer that contains ANSI control sequences.
+
+\(fn)" t nil)
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; xterm-color-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/xterm-color-20180202.1518/xterm-color-pkg.el b/configs/shared/emacs/.emacs.d/elpa/xterm-color-20180202.1518/xterm-color-pkg.el
new file mode 100644
index 0000000000..67ad1d86c7
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/xterm-color-20180202.1518/xterm-color-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "xterm-color" "20180202.1518" "ANSI & XTERM 256 color support" '((cl-lib "0.5")))
diff --git a/configs/shared/emacs/.emacs.d/elpa/xterm-color-20180202.1518/xterm-color.el b/configs/shared/emacs/.emacs.d/elpa/xterm-color-20180202.1518/xterm-color.el
new file mode 100644
index 0000000000..a5e9befda0
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/xterm-color-20180202.1518/xterm-color.el
@@ -0,0 +1,699 @@
+;;; xterm-color.el --- ANSI & XTERM 256 color support -*- lexical-binding: t -*-
+;;
+;; Copyright (C) 2010-2018 xristos@sdf.lonestar.org
+;; All rights reserved
+;;
+;; Version: 1.7 - 2018-2-2
+;; Package-Version: 20180202.1518
+;; Author: xristos@sdf.lonestar.org
+;; URL: https://github.com/atomontage/xterm-color
+;; Package-Requires: ((cl-lib "0.5"))
+;; Keywords: faces
+;;
+;; Redistribution and use in source and binary forms, with or without
+;; modification, are permitted provided that the following conditions
+;; are met:
+;;
+;;   * Redistributions of source code must retain the above copyright
+;;     notice, this list of conditions and the following disclaimer.
+;;
+;;   * Redistributions in binary form must reproduce the above
+;;     copyright notice, this list of conditions and the following
+;;     disclaimer in the documentation and/or other materials
+;;     provided with the distribution.
+;;
+;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED
+;; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+;; ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+;; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+;; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+;;; Commentary:
+;;
+;; Translates ANSI control sequences into text properties.
+;;
+;; * Regular ANSI colors
+;;
+;; * XTERM 256 colors
+;;
+;; * Works with compilation-mode
+;;
+;; * Works with eshell
+;;
+;; * More accurate than ansi-color.el
+;;
+;; * Should perform much better than ansi-color.el
+;;
+;;; Usage:
+;;
+;; Call xterm-color-filter to propertize strings that you can then insert into
+;; a buffer. All state is kept in buffer-local variables which means that
+;; control sequences can span xterm-color-filter call boundaries.
+;;
+;; Example:
+;;
+;; (xterm-color-filter "[0;1;3;4")
+;; (xterm-color-filter ";35")
+;; (xterm-color-filter ";mThis is only a test")
+;; (xterm-color-filter "")
+;;
+;;
+;; You may also use xterm-color-colorize-buffer, interactively or from elisp,
+;; to colorize an entire buffer.
+;;
+;;
+;; * You can replace ansi-color.el with xterm-color for all comint buffers,
+;;   but this may create problems with modes that propertize strings
+;;   and feed them through comint-preoutput-filter-functions since xterm-color-filter
+;;   will strip all text properties.
+;;
+;;   The recommended configuration is to remove ansi-color-process-output from
+;;   comint-output-filter-functions and add xterm-color-filter as the *first*
+;;   hook in the buffer-local comint-preoutput-filter-functions for any comint-based
+;;   mode that you would like it to affect (e.g. shell-mode).
+;;
+;;   An example configuration for shell-mode (M-x shell) is shown below:
+;;
+;; (setq comint-output-filter-functions
+;;       (remove 'ansi-color-process-output comint-output-filter-functions))
+;;
+;; (add-hook 'shell-mode-hook
+;;           (lambda () (add-hook 'comint-preoutput-filter-functions 'xterm-color-filter nil t)))
+;;
+;; Also set TERM accordingly (xterm-256color)
+;;
+;; * You can also use it with eshell (and thus get color output from system ls):
+;;
+;; (require 'eshell)
+;;
+;; (add-hook 'eshell-before-prompt-hook
+;;           (lambda ()
+;;             (setq xterm-color-preserve-properties t)))
+;;
+;;  (add-to-list 'eshell-preoutput-filter-functions 'xterm-color-filter)
+;;  (setq eshell-output-filter-functions (remove 'eshell-handle-ansi-color eshell-output-filter-functions))
+;;
+;;  Don't forget to setenv TERM xterm-256color
+;;
+;;
+;; * Compilation buffers
+;;
+;;
+;; You may use `compilation-shell-minor-mode' with shell-mode buffers
+;; and the configuration previously described.
+;;
+;; For standalone compilation-mode buffers, you may use the following
+;; configuration:
+;;
+;; (setq compilation-environment '("TERM=xterm-256color"))
+;;
+;; (add-hook 'compilation-start-hook
+;;           (lambda (proc)
+;;             ;; We need to differentiate between compilation-mode buffers
+;;             ;; and running as part of comint (which at this point we assume
+;;             ;; has been configured separately for xterm-color)
+;;             (when (eq (process-filter proc) 'compilation-filter)
+;;               ;; This is a process associated with a compilation-mode buffer.
+;;               ;; We may call `xterm-color-filter' before its own filter function.
+;;               (set-process-filter
+;;                proc
+;;                (lambda (proc string)
+;;                  (funcall 'compilation-filter proc (xterm-color-filter string)))))))
+;;
+;;
+;;; Test:
+;;
+;; M-x xterm-color-test
+;;
+;; For shell or eshell:
+;;
+;; M-x shell || M-x eshell
+;;
+;; perl tests/xterm-colortest && perl tests/256colors2.pl
+;;
+;;
+;;; Code:
+
+(require 'cl-lib)
+
+(defgroup xterm-color nil
+  "Translates ANSI control sequences to text properties."
+  :prefix "xterm-color-"
+  :group 'processes)
+
+;;
+;; CUSTOM
+;;
+
+(defcustom xterm-color-debug nil
+  "Print ANSI state machine debug information in *Messages* if T."
+  :type 'boolean
+  :group 'xterm-color)
+
+(defcustom xterm-color-names
+  ["#192033"    ; black
+   "#A93F43"    ; red
+   "#59963A"    ; green
+   "#BE8A2D"    ; yellow
+   "#4068A3"    ; blue
+   "#7F60A7"    ; magenta
+   "#4E9B9B"    ; cyan
+   "#7E8A90"]   ; white
+  "The default colors to use as regular ANSI colors."
+  :type '(vector string string string string string string string string)
+  :group 'xterm-color)
+
+(defcustom xterm-color-names-bright
+  ["#666666"    ; black
+   "#EC6261"    ; red
+   "#ADCF44"    ; green
+   "#F0C649"    ; yellow
+   "#63B4F6"    ; blue
+   "#CB77F9"    ; magenta
+   "#86D7DB"    ; cyan
+   "#D3D2D1"]   ; white
+  "The default colors to use as bright ANSI colors."
+  :type '(vector string string string string string string string string)
+  :group 'xterm-color)
+
+;;
+;; Buffer locals, used by state machine
+;;
+
+(defvar xterm-color--current nil
+  "Hash table with current ANSI color.")
+
+(make-variable-buffer-local 'xterm-color--current)
+
+(defvar xterm-color-preserve-properties nil
+  "If T, preserve existing text properties on input about to be filtered.
+This should be NIL most of the time as it can mess up the internal state
+machine if it encounters ANSI data with text properties applied.  It is
+really meant for and works fine with eshell.")
+
+(make-variable-buffer-local 'xterm-color-preserve-properties)
+
+(defvar xterm-color-ignore-movement nil
+  "If T, ignore CSI sequences that move the cursor.")
+
+(make-variable-buffer-local 'xterm-color-ignore-movement)
+
+(defvar xterm-color--char-buffer ""
+  "Buffer with characters that the current ANSI color applies to.
+In order to avoid having per-character text properties, we grow this
+buffer dynamically until we encounter an ANSI reset sequence.
+
+Once that happens, we generate a single text property for the entire string.")
+
+(make-variable-buffer-local 'xterm-color--char-buffer)
+
+(defvar xterm-color--CSI-buffer ""
+  "Buffer with current ANSI CSI sequence bytes.")
+
+(make-variable-buffer-local 'xterm-color--CSI-buffer)
+
+(defvar xterm-color--osc-buffer ""
+  "Buffer with current ANSI OSC sequence bytes.")
+
+(make-variable-buffer-local 'xterm-color--osc-buffer)
+
+(defvar xterm-color--state :char
+  "The current state of the ANSI sequence state machine.")
+
+(make-variable-buffer-local 'xterm-color--state)
+
+(defvar xterm-color--attributes 0)
+
+(make-variable-buffer-local 'xterm-color--attributes)
+
+
+(defconst +xterm-color--bright+    1)
+(defconst +xterm-color--italic+    2)
+(defconst +xterm-color--underline+ 4)
+(defconst +xterm-color--strike+    8)
+(defconst +xterm-color--negative+  16)
+(defconst +xterm-color--frame+     32)
+(defconst +xterm-color--overline+  64)
+
+;;
+;; Functions
+;;
+
+(cl-defun xterm-color--string-properties (string)
+  (cl-loop
+   with res = '()
+   with pos = 0
+   do
+   (let ((next-pos (next-property-change pos string)))
+     (if next-pos
+         (progn
+           (push (list pos (text-properties-at pos string) (substring string pos next-pos)) res)
+           (setq pos next-pos))
+       (push (list pos (text-properties-at pos string) (substring string pos)) res)
+       (cl-return-from xterm-color--string-properties (nreverse res))))))
+
+(defun xterm-color--message (format-string &rest args)
+  "Call `message' with FORMAT-STRING and ARGS if `xterm-color-debug' is T."
+  (when xterm-color-debug
+    (let ((message-truncate-lines t))
+      (apply 'message format-string args)
+      (message nil))))
+
+(defun xterm-color--dispatch-SGR (elems)
+  (cl-loop
+   for elem = (cl-first elems)
+   while elem do
+   (cond
+    ;; Reset
+    ((= 0 elem)
+     (clrhash xterm-color--current)
+     (setq xterm-color--attributes 0)
+     (setq elems (cdr elems)))
+    ;; ANSI FG color
+    ((and (>= elem 30)
+          (<= elem 37))
+     (setf (gethash 'foreground-color xterm-color--current)
+           (- elem 30))
+     (setq elems (cdr elems)))
+    ;; ANSI BG color
+    ((and (>= elem 40)
+          (<= elem 47))
+     (setf (gethash 'background-color xterm-color--current)
+           (- elem 40))
+     (setq elems (cdr elems)))
+    ;; XTERM 256 FG color
+    ((= 38 elem)
+     (setf (gethash 'foreground-color xterm-color--current)
+           (xterm-color-256 (cl-third elems)))
+     (setq elems (cl-cdddr elems)))
+    ;; XTERM 256 BG color
+    ((= 48 elem)
+     (setf (gethash 'background-color xterm-color--current)
+           (xterm-color-256 (cl-third elems)))
+     (setq elems (cl-cdddr elems)))
+    ;; Reset to default FG color
+    ((= 39 elem)
+     (remhash 'foreground-color xterm-color--current)
+     (setq elems (cdr elems)))
+    ;; Reset to default BG color
+    ((= 49 elem)
+     (remhash 'background-color xterm-color--current)
+     (setq elems (cdr elems)))
+    ;; Bright color
+    ((= 1 elem)
+     (setq xterm-color--attributes
+           (logior xterm-color--attributes
+                   +xterm-color--bright+))
+     (setq elems (cdr elems)))
+    ;; Faint color, emulated as normal intensity
+    ((= 2 elem)
+     (setq xterm-color--attributes
+           (logand xterm-color--attributes
+                   (lognot +xterm-color--bright+)))
+     (setq elems (cdr elems)))
+    ;; Italic
+    ((= 3 elem)
+     (setq xterm-color--attributes
+           (logior xterm-color--attributes
+                   +xterm-color--italic+))
+     (setq elems (cdr elems)))
+    ;; Underline
+    ((= 4 elem)
+     (setq xterm-color--attributes
+           (logior xterm-color--attributes
+                   +xterm-color--underline+))
+     (setq elems (cdr elems)))
+    ;; Negative
+    ((= 7 elem)
+     (setq xterm-color--attributes
+           (logior xterm-color--attributes
+                   +xterm-color--negative+))
+     (setq elems (cdr elems)))
+    ;; Strike through
+    ((= 9 elem)
+     (setq xterm-color--attributes
+           (logior xterm-color--attributes
+                   +xterm-color--strike+))
+     (setq elems (cdr elems)))
+    ;; Normal intensity
+    ((= 22 elem)
+     (setq xterm-color--attributes
+           (logand xterm-color--attributes
+                   (lognot +xterm-color--bright+)))
+     (setq elems (cdr elems)))
+    ;; No italic
+    ((= 23 elem)
+     (setq xterm-color--attributes
+           (logand xterm-color--attributes
+                   (lognot +xterm-color--italic+)))
+     (setq elems (cdr elems)))
+    ;; No underline
+    ((= 24 elem)
+     (setq xterm-color--attributes
+           (logand xterm-color--attributes
+                   (lognot +xterm-color--underline+)))
+     (setq elems (cdr elems)))
+    ;; No negative
+    ((= 27 elem)
+     (setq xterm-color--attributes
+           (logand xterm-color--attributes
+                   (lognot +xterm-color--negative+)))
+     (setq elems (cdr elems)))
+    ;; No strike through
+    ((= 29 elem)
+     (setq xterm-color--attributes
+           (logand xterm-color--attributes
+                   (lognot +xterm-color--strike+)))
+     (setq elems (cdr elems)))
+    ;; Frame
+    ((= 51 elem)
+     (setq xterm-color--attributes
+           (logior xterm-color--attributes
+                   +xterm-color--frame+))
+     (setq elems (cdr elems)))
+    ;; Overline
+    ((= 53 elem)
+     (setq xterm-color--attributes
+           (logior xterm-color--attributes
+                   +xterm-color--overline+))
+     (setq elems (cdr elems)))
+    ;; No frame
+    ((= 54 elem)
+     (setq xterm-color--attributes
+           (logand xterm-color--attributes
+                   (lognot +xterm-color--frame+)))
+     (setq elems (cdr elems)))
+    ;; No overline
+    ((= 55 elem)
+     (setq xterm-color--attributes
+           (logand xterm-color--attributes
+                   (lognot +xterm-color--overline+)))
+     (setq elems (cdr elems)))
+    ;; AIXTERM hi-intensity FG color
+    ((and (>= elem 90)
+          (<= elem 97))
+     (setf (gethash 'foreground-color xterm-color--current)
+           (- elem 90))
+     (setq xterm-color--attributes
+           (logior xterm-color--attributes
+                   +xterm-color--bright+))
+     (setq elems (cdr elems)))
+    ;; Fallback
+    (t (xterm-color--message "xterm-color: not implemented SGR attribute %s" elem)
+       (setq elems (cdr elems))))))
+
+
+(defun xterm-color--dispatch-CSI (csi)
+  (let* ((len (1- (length csi)))
+         (term (aref csi len)))
+    (cl-macrolet ((maybe-ignore-CSI
+                   (&rest body)
+                   `(if xterm-color-ignore-movement
+                        (xterm-color--message "xterm-color: ignoring %s CSI since xterm-color-ignore-movement is set" csi)
+                      ,@body)))
+      (cond ((= ?m term)
+             ;; SGR
+             (if (= len 0)
+                 (xterm-color--dispatch-SGR '(0))
+               (let ((len (1- len)))              ; Don't need the ?m character
+                 (subst-char-in-string 59 ? csi t)
+                 (xterm-color--dispatch-SGR
+                  ;; The following is somewhat faster than
+                  ;; (mapcar 'string-to-number (split-string csi))
+                  (cl-loop with idx = 0
+                           while (<= idx len)
+                           for (num . end) = (read-from-string csi idx (1+ len))
+                           do (progn (cl-assert (integerp num))
+                                     (setf idx end))
+                           collect num)))))
+            ((= ?J term)
+             ;; Clear screen
+             (xterm-color--message "xterm-color: %s CSI not implemented (clear screen)" csi))
+            ((= ?C term)
+             (maybe-ignore-CSI
+              (let ((num (string-to-number (substring csi 0 len))))
+                (setq xterm-color--char-buffer
+                      (concat xterm-color--char-buffer
+                              (make-string num 32))))))
+            (t
+             (xterm-color--message "xterm-color: %s CSI not implemented" csi))))))
+
+
+(defun xterm-color-256 (color)
+  (cond ((and (>= color 232)
+              (<= color 255))
+         ;; Grayscale
+         (let ((val (+ 8 (* (- color 232) 10))))
+           (format "#%02x%02x%02x"
+                   val val val)))
+        ((<= color 7)
+         ;; Normal ANSI color
+         (aref xterm-color-names color))
+        ((and (>= color 8)
+              (<= color 15))
+         ;; Bright ANSI color
+         (aref xterm-color-names-bright (- color 8)))
+        (t (let* ((color-table [0 #x5f #x87 #xaf #xd7 #xff])
+                  (color (- color 16))
+                  (red (/ color 36))
+                  (color (mod color 36))
+                  (green (/ color 6))
+                  (color (mod color 6))
+                  (blue color))
+             ;; XTERM 256 color
+             (format "#%02x%02x%02x"
+                     (aref color-table red)
+                     (aref color-table green)
+                     (aref color-table blue))))))
+
+(defun xterm-color--make-property ()
+  (let ((ret nil)
+        (fg (gethash 'foreground-color xterm-color--current))
+        (bg (gethash 'background-color xterm-color--current)))
+    (cl-macrolet ((is-set? (attrib) `(> (logand ,attrib xterm-color--attributes) 0)))
+      (when (is-set? +xterm-color--italic+)
+        (push `(:slant italic) ret))
+      (when (is-set? +xterm-color--underline+)
+        (push `(:underline t) ret))
+      (when (is-set? +xterm-color--strike+)
+        (push `(:strike-through t) ret))
+      (when (is-set? +xterm-color--negative+)
+        (push `(:inverse-video t) ret))
+      (when (is-set? +xterm-color--overline+)
+        (push `(:overline t) ret))
+      (when (is-set? +xterm-color--frame+)
+        (push `(:box t) ret))
+      (when fg
+        (push `(:foreground ,(if (stringp fg)
+                                 fg
+                               (if (is-set? +xterm-color--bright+)
+                                   (aref xterm-color-names-bright fg)
+                                 (aref xterm-color-names fg))))
+              ret))
+      (when bg
+        (push `(:background ,(if (stringp bg) bg (aref xterm-color-names bg)))
+              ret)))
+    ret))
+
+(defun xterm-color-filter-real (string)
+  "Translate ANSI color sequences in STRING into text properties.
+Returns new STRING with text properties applied.
+
+This function strips text properties that may be present in STRING."
+  ;; It is *a lot* faster to keep track of propertized strings in a list
+  ;; and mapconcat at the end, than using a temporary buffer to insert them.
+  (let ((result nil))
+    (cl-macrolet ((output (x) `(push ,x result))
+                  (update (x place) `(setq ,place (concat ,place (string ,x))))
+                  (new-state (state) `(setq xterm-color--state ,state))
+                  (has-color? () `(or (> (hash-table-count xterm-color--current) 0)
+                                      (not (= xterm-color--attributes 0))))
+                  (maybe-fontify ()
+                                 `(when (> (length xterm-color--char-buffer) 0)
+                                    (if (has-color?)
+                                        (output (propertize xterm-color--char-buffer 'xterm-color t
+                                                            (if font-lock-mode 'font-lock-face 'face) (xterm-color--make-property)))
+                                      (output xterm-color--char-buffer))
+                                    (setq xterm-color--char-buffer ""))))
+      (cl-loop for char across string do
+	       (cl-case xterm-color--state
+		 (:char
+		  (cond
+		   ((= char 27)		; ESC
+		    (maybe-fontify)
+		    (new-state :ansi-esc))
+		   (t
+		    (if (has-color?)
+			(update char xterm-color--char-buffer)
+		      (output (string char))))))
+		 (:ansi-esc
+		  (cond ((= char ?\[)
+			 (new-state :ansi-csi))
+			((= char ?\])
+			 (new-state :ansi-osc))
+			(t
+			 (update char xterm-color--char-buffer)
+			 (new-state :char))))
+		 (:ansi-csi
+		  (update char xterm-color--CSI-buffer)
+		  (when (and (>= char #x40)
+			     (<= char #x7e))
+		    ;; Dispatch
+		    (xterm-color--dispatch-CSI xterm-color--CSI-buffer)
+		    (setq xterm-color--CSI-buffer "")
+		    (new-state :char)))
+		 (:ansi-osc
+		  ;; Read entire sequence
+		  (update char xterm-color--osc-buffer)
+		  (cond ((= char 7)
+			 ;; BEL
+					;(xterm-color--dispatch-osc xterm-color--osc-buffer)
+			 (setq xterm-color--osc-buffer "")
+			 (new-state :char))
+			((= char 27)
+			 ;; ESC
+			 (new-state :ansi-osc-esc))))
+		 (:ansi-osc-esc
+		  (update char xterm-color--osc-buffer)
+		  (cond ((= char ?\\)
+					;(xterm-color--dispatch-osc xterm-color--osc-buffer)
+			 (setq xterm-color--osc-buffer "")
+			 (new-state :char))
+			(t (new-state :ansi-osc))))))
+      (when (eq xterm-color--state :char) (maybe-fontify)))
+    (mapconcat 'identity (nreverse result) "")))
+
+
+;;;###autoload
+(defun xterm-color-filter (string)
+  "Translate ANSI color sequences in STRING into text properties.
+Returns new STRING with text properties applied.
+
+This function will check if `xterm-color-preserve-properties' is
+set to T and only call `xterm-color-filter-real' on substrings
+that do not have text properties applied (passing through the rest
+unmodified).  Preserving properties in this fashion is really a hack
+and not very robust as there may be situations where text properties
+are applied on ANSI data, which will mess up the state machine.
+It works fine with and is really meant for eshell though.
+
+This can be inserted into `comint-preoutput-filter-functions'."
+  (when (null xterm-color--current)
+    (setq xterm-color--current (make-hash-table)))
+  (if (not xterm-color-preserve-properties)
+      (xterm-color-filter-real string)
+    (cl-loop with res = nil
+	     for (_ props substring) in (xterm-color--string-properties string) do
+	     (push (if props substring (xterm-color-filter-real substring))
+		   res)
+	     finally return (mapconcat 'identity (nreverse res) ""))))
+
+;; This will be removed in 2.0, it's here so as not to break existing configs
+;; for 1.0 -> 1.6 transition.
+(defalias 'xterm-color-unfontify-region 'font-lock-default-unfontify-region)
+
+;;
+;; Interactive
+;;
+
+;;;###autoload
+(cl-defun xterm-color-colorize-buffer ()
+  "Apply `xterm-color-filter' to current buffer, and replace its contents."
+  (interactive)
+  (let ((read-only-p buffer-read-only))
+    (when read-only-p
+      (unless (y-or-n-p "Buffer is read only, continue colorizing? ")
+        (cl-return-from xterm-color-colorize-buffer))
+      (read-only-mode -1))
+    (insert (xterm-color-filter (delete-and-extract-region (point-min) (point-max))))
+    (goto-char (point-min))
+    (when read-only-p (read-only-mode 1))))
+
+
+;;
+;; Tests
+;;
+
+(let ((test-attributes
+       '((1  . "bright")
+         (51 . "frame")
+         (3  . "italic")
+         (4  . "underline")
+         (7  . "negative")
+         (9  . "strike through")
+         (53 . "overline"))))
+
+  (defun xterm-color--test-ansi ()
+    ;; System colors
+    (insert "* ANSI system colors\n\n")
+    (cl-loop for color from 40 to 47 do
+	     (insert (xterm-color-filter (format "[0;%sm  " color)))
+	     finally (insert (xterm-color-filter "\n\n")))
+
+    ;; Attributes (no color)
+    (insert "* ANSI attributes (default colors)\n\n")
+    (cl-loop for (attrib . name) in test-attributes do
+	     (insert (xterm-color-filter (format "[0;%smThis is only a test!\t --[ %s ]\n" attrib name)))
+	     finally (insert "\n"))
+
+    ;; Attributes (blue fg)
+    (insert "* ANSI attributes (blue foreground)\n\n")
+    (cl-loop for (attrib . name) in test-attributes do
+	     (insert (xterm-color-filter (format "[0;34;%smThis is only a test!\t --[ %s ]\n" attrib name)))
+	     finally (insert "\n"))
+
+    ;; Attributes (blue bg)
+    (insert "* ANSI attributes (blue background)\n\n")
+    (cl-loop for (attrib . name) in test-attributes do
+	     (insert (xterm-color-filter (format "[0;44;%smThis is only a test!\t --[ %s ]\n" attrib name)))
+	     finally (insert "\n"))))
+
+(defun xterm-color--test-xterm ()
+  ;; Normal ANSI colors mapped to XTERM
+  (insert "* ANSI colors mapped to XTERM\n\n")
+  (cl-loop for color from 0 to 7 do
+	   (insert (xterm-color-filter (format "[48;5;%sm  " color)))
+	   finally (insert (xterm-color-filter "\n\n")))
+
+  ;; Bright ANSI colors mapped to XTERM
+  (insert "* ANSI bright colors mapped to XTERM\n\n")
+  (cl-loop for color from 8 to 15 do
+	   (insert (xterm-color-filter (format "[48;5;%sm  " color)))
+	   finally (insert (xterm-color-filter "\n\n")))
+
+  ;; XTERM 256 color cubes
+  (insert "*  XTERM 256 color cubes\n\n")
+  (cl-loop for green from 0 to 5 do
+	   (cl-loop for red from 0 to 5 do
+		    (cl-loop for blue from 0 to 5
+			     for color = (+ 16 (* 36 red) (* green 6) blue) do
+			     (insert (xterm-color-filter (format "[48;5;%sm  " color))))
+		    (insert (xterm-color-filter " ")))
+	   (insert "\n"))
+  (insert "\n")
+
+  (insert "*  XTERM color grayscale ramp\n\n")
+  (cl-loop for color from 232 to 255 do
+	   (insert (xterm-color-filter (format "[48;5;%sm  " color)))
+	   finally (insert (xterm-color-filter "\n\n"))))
+
+;;;###autoload
+(defun xterm-color-test ()
+  "Create and display a new buffer that contains ANSI control sequences."
+  (interactive)
+  (let* ((name (generate-new-buffer-name "xterm-color-test"))
+         (buf (get-buffer-create name)))
+    (switch-to-buffer buf))
+  (xterm-color--test-ansi)
+  (xterm-color--test-xterm)
+  (setq buffer-read-only t))
+
+
+(provide 'xterm-color)
+;;; xterm-color.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/xterm-color-20180202.1518/xterm-color.elc b/configs/shared/emacs/.emacs.d/elpa/xterm-color-20180202.1518/xterm-color.elc
new file mode 100644
index 0000000000..66286ccb97
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/xterm-color-20180202.1518/xterm-color.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/yaml-mode-20180408.2307/yaml-mode-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/yaml-mode-20180408.2307/yaml-mode-autoloads.el
new file mode 100644
index 0000000000..72f41bd594
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/yaml-mode-20180408.2307/yaml-mode-autoloads.el
@@ -0,0 +1,28 @@
+;;; yaml-mode-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "yaml-mode" "yaml-mode.el" (23377 60994 457868
+;;;;;;  712000))
+;;; Generated autoloads from yaml-mode.el
+
+(let ((loads (get 'yaml 'custom-loads))) (if (member '"yaml-mode" loads) nil (put 'yaml 'custom-loads (cons '"yaml-mode" loads))))
+
+(autoload 'yaml-mode "yaml-mode" "\
+Simple mode to edit YAML.
+
+\\{yaml-mode-map}
+
+\(fn)" t nil)
+
+(add-to-list 'auto-mode-alist '("\\.\\(e?ya?\\|ra\\)ml\\'" . yaml-mode))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; yaml-mode-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/yaml-mode-20180408.2307/yaml-mode-pkg.el b/configs/shared/emacs/.emacs.d/elpa/yaml-mode-20180408.2307/yaml-mode-pkg.el
new file mode 100644
index 0000000000..d1474062e3
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/yaml-mode-20180408.2307/yaml-mode-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "yaml-mode" "20180408.2307" "Major mode for editing YAML files" '((emacs "24.1")))
diff --git a/configs/shared/emacs/.emacs.d/elpa/yaml-mode-20180408.2307/yaml-mode.el b/configs/shared/emacs/.emacs.d/elpa/yaml-mode-20180408.2307/yaml-mode.el
new file mode 100644
index 0000000000..01fba62b88
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/yaml-mode-20180408.2307/yaml-mode.el
@@ -0,0 +1,472 @@
+;;; yaml-mode.el --- Major mode for editing YAML files
+
+;; Copyright (C) 2010-2014 Yoshiki Kurihara
+
+;; Author: Yoshiki Kurihara <clouder@gmail.com>
+;;         Marshall T. Vandegrift <llasram@gmail.com>
+;; Maintainer: Vasilij Schneidermann <v.schneidermann@gmail.com>
+;; Package-Requires: ((emacs "24.1"))
+;; Package-Version: 20180408.2307
+;; Keywords: data yaml
+;; Version: 0.0.13
+
+;; This file is not part of Emacs
+
+;; This file 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 2, or (at your option)
+;; any later version.
+
+;; This file 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 this program; if not, write to the Free Software Foundation, Inc.,
+;; 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+;;; Commentary:
+
+;; This is a major mode for editing files in the YAML data
+;; serialization format.  It was initially developed by Yoshiki
+;; Kurihara and many features were added by Marshall Vandegrift.  As
+;; YAML and Python share the fact that indentation determines
+;; structure, this mode provides indentation and indentation command
+;; behavior very similar to that of python-mode.
+
+;;; Installation:
+
+;; To install, just drop this file into a directory in your
+;; `load-path' and (optionally) byte-compile it.  To automatically
+;; handle files ending in '.yml', add something like:
+;;
+;;    (require 'yaml-mode)
+;;    (add-to-list 'auto-mode-alist '("\\.yml\\'" . yaml-mode))
+;;
+;; to your .emacs file.
+;;
+;; Unlike python-mode, this mode follows the Emacs convention of not
+;; binding the ENTER key to `newline-and-indent'.  To get this
+;; behavior, add the key definition to `yaml-mode-hook':
+;;
+;;    (add-hook 'yaml-mode-hook
+;;     '(lambda ()
+;;        (define-key yaml-mode-map "\C-m" 'newline-and-indent)))
+
+;;; Known Bugs:
+
+;; YAML is easy to write but complex to parse, and this mode doesn't
+;; even really try.  Indentation and highlighting will break on
+;; abnormally complicated structures.
+
+;;; Code:
+
+
+;; User definable variables
+
+;;;###autoload
+(defgroup yaml nil
+  "Support for the YAML serialization format"
+  :group 'languages
+  :prefix "yaml-")
+
+(defcustom yaml-mode-hook nil
+  "*Hook run by `yaml-mode'."
+  :type 'hook
+  :group 'yaml)
+
+(defcustom yaml-indent-offset 2
+  "*Amount of offset per level of indentation."
+  :type 'integer
+  :safe 'natnump
+  :group 'yaml)
+
+(defcustom yaml-backspace-function 'backward-delete-char-untabify
+  "*Function called by `yaml-electric-backspace' when deleting backwards.
+It will receive one argument, the numeric prefix value."
+  :type 'function
+  :group 'yaml)
+
+(defcustom yaml-block-literal-search-lines 100
+  "*Maximum number of lines to search for start of block literals."
+  :type 'integer
+  :group 'yaml)
+
+(defcustom yaml-block-literal-electric-alist
+  '((?| . "") (?> . "-"))
+  "*Characters for which to provide electric behavior.
+The association list key should be a key code and the associated value
+should be a string containing additional characters to insert when
+that key is pressed to begin a block literal."
+  :type 'alist
+  :group 'yaml)
+
+(defface yaml-tab-face
+   '((((class color)) (:background "red" :foreground "red" :bold t))
+     (t (:reverse-video t)))
+  "Face to use for highlighting tabs in YAML files."
+  :group 'faces
+  :group 'yaml)
+
+(defcustom yaml-imenu-generic-expression
+  '((nil  "^\\(:?[a-zA-Z_-]+\\):"          1))
+  "The imenu regex to parse an outline of the yaml file."
+  :type 'string
+  :group 'yaml)
+
+
+;; Constants
+
+(defconst yaml-mode-version "0.0.13" "Version of `yaml-mode'.")
+
+(defconst yaml-blank-line-re "^ *$"
+  "Regexp matching a line containing only (valid) whitespace.")
+
+(defconst yaml-directive-re "^\\(?:--- \\)? *%\\(\\w+\\)"
+  "Regexp matching a line contatining a YAML directive.")
+
+(defconst yaml-document-delimiter-re "^\\(?:---\\|[.][.][.]\\)"
+  "Rexexp matching a YAML document delimiter line.")
+
+(defconst yaml-node-anchor-alias-re "[&*][a-zA-Z0-9_-]+"
+  "Regexp matching a YAML node anchor or alias.")
+
+(defconst yaml-tag-re "!!?[^ \n]+"
+  "Rexexp matching a YAML tag.")
+
+(defconst yaml-bare-scalar-re
+  "\\(?:[^-:,#!\n{\\[ ]\\|[^#!\n{\\[ ]\\S-\\)[^#\n]*?"
+  "Rexexp matching a YAML bare scalar.")
+
+(defconst yaml-hash-key-re
+  (concat "\\(?:^\\(?:--- \\)?\\|{\\|\\(?:[-,] +\\)+\\) *"
+          "\\(?:" yaml-tag-re " +\\)?"
+          "\\(" yaml-bare-scalar-re "\\) *:"
+          "\\(?: +\\|$\\)")
+  "Regexp matching a single YAML hash key.")
+
+(defconst yaml-scalar-context-re
+  (concat "\\(?:^\\(?:--- \\)?\\|{\\|\\(?: *[-,] +\\)+\\) *"
+          "\\(?:" yaml-bare-scalar-re " *: \\)?")
+  "Regexp indicating the beginning of a scalar context.")
+
+(defconst yaml-nested-map-re
+  (concat ".*: *\\(?:&.*\\|{ *\\|" yaml-tag-re " *\\)?$")
+  "Regexp matching a line beginning a YAML nested structure.")
+
+(defconst yaml-block-literal-base-re " *[>|][-+0-9]* *\\(?:\n\\|\\'\\)"
+  "Regexp matching the substring start of a block literal.")
+
+(defconst yaml-block-literal-re
+  (concat yaml-scalar-context-re
+          "\\(?:" yaml-tag-re "\\)?"
+          yaml-block-literal-base-re)
+  "Regexp matching a line beginning a YAML block literal.")
+
+(defconst yaml-nested-sequence-re
+  (concat "^\\(?:\\(?: *- +\\)+\\|\\(:? *-$\\)\\)"
+          "\\(?:" yaml-bare-scalar-re " *:\\(?: +.*\\)?\\)?$")
+  "Regexp matching a line containing one or more nested YAML sequences.")
+
+(defconst yaml-constant-scalars-re
+  (concat "\\(?:^\\|\\(?::\\|-\\|,\\|{\\|\\[\\) +\\) *"
+          (regexp-opt
+           '("~" "null" "Null" "NULL"
+             ".nan" ".NaN" ".NAN"
+             ".inf" ".Inf" ".INF"
+             "-.inf" "-.Inf" "-.INF"
+             "y" "Y" "yes" "Yes" "YES" "n" "N" "no" "No" "NO"
+             "true" "True" "TRUE" "false" "False" "FALSE"
+             "on" "On" "ON" "off" "Off" "OFF") t)
+          " *$")
+  "Regexp matching certain scalar constants in scalar context.")
+
+
+;; Mode setup
+
+(defvar yaml-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map "|" 'yaml-electric-bar-and-angle)
+    (define-key map ">" 'yaml-electric-bar-and-angle)
+    (define-key map "-" 'yaml-electric-dash-and-dot)
+    (define-key map "." 'yaml-electric-dash-and-dot)
+    (define-key map (kbd "DEL") 'yaml-electric-backspace)
+    map)
+  "Keymap used in `yaml-mode' buffers.")
+
+(defvar yaml-mode-syntax-table
+  (let ((syntax-table (make-syntax-table)))
+    (modify-syntax-entry ?\' "\"" syntax-table)
+    (modify-syntax-entry ?\" "\"" syntax-table)
+    (modify-syntax-entry ?# "<" syntax-table)
+    (modify-syntax-entry ?\n ">" syntax-table)
+    (modify-syntax-entry ?\\ "\\" syntax-table)
+    (modify-syntax-entry ?- "_" syntax-table)
+    (modify-syntax-entry ?_ "_" syntax-table)
+    (modify-syntax-entry ?& "." syntax-table)
+    (modify-syntax-entry ?* "." syntax-table)
+    (modify-syntax-entry ?\( "." syntax-table)
+    (modify-syntax-entry ?\) "." syntax-table)
+    (modify-syntax-entry ?\{ "(}" syntax-table)
+    (modify-syntax-entry ?\} "){" syntax-table)
+    (modify-syntax-entry ?\[ "(]" syntax-table)
+    (modify-syntax-entry ?\] ")[" syntax-table)
+    syntax-table)
+  "Syntax table in use in `yaml-mode' buffers.")
+
+;;;###autoload
+(define-derived-mode yaml-mode text-mode "YAML"
+  "Simple mode to edit YAML.
+
+\\{yaml-mode-map}"
+  :syntax-table yaml-mode-syntax-table
+  (set (make-local-variable 'comment-start) "# ")
+  (set (make-local-variable 'comment-start-skip) "#+ *")
+  (set (make-local-variable 'indent-line-function) 'yaml-indent-line)
+  (set (make-local-variable 'indent-tabs-mode) nil)
+  (set (make-local-variable 'fill-paragraph-function) 'yaml-fill-paragraph)
+
+  (set (make-local-variable 'syntax-propertize-function)
+       'yaml-mode-syntax-propertize-function)
+  (setq font-lock-defaults '(yaml-font-lock-keywords)))
+
+
+;; Font-lock support
+
+(defvar yaml-font-lock-keywords
+  `((yaml-font-lock-block-literals 0 font-lock-string-face)
+    (,yaml-constant-scalars-re . (1 font-lock-constant-face))
+    (,yaml-tag-re . (0 font-lock-type-face))
+    (,yaml-node-anchor-alias-re . (0 font-lock-function-name-face))
+    (,yaml-hash-key-re . (1 font-lock-variable-name-face))
+    (,yaml-document-delimiter-re . (0 font-lock-comment-face))
+    (,yaml-directive-re . (1 font-lock-builtin-face))
+    ("^[\t]+" 0 'yaml-tab-face t))
+   "Additional expressions to highlight in YAML mode.")
+
+(defun yaml-mode-syntax-propertize-function (beg end)
+  "Override buffer's syntax table for special syntactic constructs."
+  ;; Unhighlight foo#bar tokens between BEG and END.
+  (save-excursion
+    (goto-char beg)
+    (while (search-forward "#" end t)
+      (save-excursion
+        (forward-char -1)
+        ;; both ^# and [ \t]# are comments
+        (when (and (not (bolp))
+                   (not (memq (preceding-char) '(?\s ?\t))))
+          (put-text-property (point) (1+ (point))
+                             'syntax-table (string-to-syntax "_"))))))
+
+  ;; If quote is detected as a syntactic string start but appeared
+  ;; after a non-whitespace character, then mark it as syntactic word.
+  (save-excursion
+    (goto-char beg)
+    (while (re-search-forward "['\"]" end t)
+      (when (get-text-property (point) 'yaml-block-literal)
+        (put-text-property (1- (point)) (point)
+                           'syntax-table (string-to-syntax "w")))
+      (when (nth 8 (syntax-ppss))
+        (save-excursion
+          (forward-char -1)
+          (cond ((and (char-equal ?' (char-before (point)))
+                      (char-equal ?' (char-after (point)))
+                      (put-text-property (1- (point)) (1+ (point))
+                                         'syntax-table (string-to-syntax "w"))))
+                ((and (not (bolp))
+                      (char-equal ?w (char-syntax (char-before (point)))))
+                 (put-text-property (point) (1+ (point))
+                                    'syntax-table (string-to-syntax "w")))))))))
+
+(defun yaml-font-lock-block-literals (bound)
+  "Find lines within block literals.
+Find the next line of the first (if any) block literal after point and
+prior to BOUND.  Returns the beginning and end of the block literal
+line in the match data, as consumed by `font-lock-keywords' matcher
+functions.  The function begins by searching backwards to determine
+whether or not the current line is within a block literal.  This could
+be time-consuming in large buffers, so the number of lines searched is
+artificially limitted to the value of
+`yaml-block-literal-search-lines'."
+  (if (eolp) (goto-char (1+ (point))))
+  (unless (or (eobp) (>= (point) bound))
+    (let ((begin (point))
+          (end (min (1+ (point-at-eol)) bound)))
+      (goto-char (point-at-bol))
+      (while (and (looking-at yaml-blank-line-re)
+                  (not (bobp)))
+        (forward-line -1))
+      (let ((nlines yaml-block-literal-search-lines)
+            (min-level (current-indentation)))
+        (forward-line -1)
+        (while (and (/= nlines 0)
+                    (/= min-level 0)
+                    (not (looking-at yaml-block-literal-re))
+                    (not (bobp)))
+          (setq nlines (1- nlines))
+          (unless (looking-at yaml-blank-line-re)
+            (setq min-level (min min-level (current-indentation))))
+          (forward-line -1))
+        (cond
+         ((and (< (current-indentation) min-level)
+               (looking-at yaml-block-literal-re))
+          (goto-char end)
+          (put-text-property begin end 'yaml-block-literal t)
+          (set-match-data (list begin end))
+          t)
+         ((progn
+            (goto-char begin)
+            (re-search-forward (concat yaml-block-literal-re
+                                       " *\\(.*\\)\n")
+                               bound t))
+          (let ((range (nthcdr 2 (match-data))))
+            (put-text-property (car range) (cadr range) 'yaml-block-literal t)
+            (set-match-data range))
+          t))))))
+
+
+;; Indentation and electric keys
+
+(defun yaml-compute-indentation ()
+  "Calculate the maximum sensible indentation for the current line."
+  (save-excursion
+    (beginning-of-line)
+    (if (looking-at yaml-document-delimiter-re) 0
+      (forward-line -1)
+      (while (and (looking-at yaml-blank-line-re)
+                  (> (point) (point-min)))
+        (forward-line -1))
+      (+ (current-indentation)
+         (if (looking-at yaml-nested-map-re) yaml-indent-offset 0)
+         (if (looking-at yaml-nested-sequence-re) yaml-indent-offset 0)
+         (if (looking-at yaml-block-literal-re) yaml-indent-offset 0)))))
+
+(defun yaml-indent-line ()
+  "Indent the current line.
+The first time this command is used, the line will be indented to the
+maximum sensible indentation.  Each immediately subsequent usage will
+back-dent the line by `yaml-indent-offset' spaces.  On reaching column
+0, it will cycle back to the maximum sensible indentation."
+  (interactive "*")
+  (let ((ci (current-indentation))
+        (cc (current-column))
+        (need (yaml-compute-indentation)))
+    (save-excursion
+      (beginning-of-line)
+      (delete-horizontal-space)
+      (if (and (equal last-command this-command) (/= ci 0))
+          (indent-to (* (/ (- ci 1) yaml-indent-offset) yaml-indent-offset))
+        (indent-to need)))
+    (if (< (current-column) (current-indentation))
+        (forward-to-indentation 0))))
+
+(defun yaml-electric-backspace (arg)
+  "Delete characters or back-dent the current line.
+If invoked following only whitespace on a line, will back-dent to the
+immediately previous multiple of `yaml-indent-offset' spaces."
+  (interactive "*p")
+  (if (or (/= (current-indentation) (current-column)) (bolp))
+      (funcall yaml-backspace-function arg)
+    (let ((ci (current-column)))
+      (beginning-of-line)
+      (delete-horizontal-space)
+      (indent-to (* (/ (- ci (* arg yaml-indent-offset))
+                       yaml-indent-offset)
+                    yaml-indent-offset)))))
+
+(defun yaml-electric-bar-and-angle (arg)
+  "Insert the bound key and possibly begin a block literal.
+Inserts the bound key.  If inserting the bound key causes the current
+line to match the initial line of a block literal, then inserts the
+matching string from `yaml-block-literal-electric-alist', a newline,
+and indents appropriately."
+  (interactive "*P")
+  (self-insert-command (prefix-numeric-value arg))
+  (let ((extra-chars
+         (assoc last-command-event
+                yaml-block-literal-electric-alist)))
+    (cond
+     ((and extra-chars (not arg) (eolp)
+           (save-excursion
+             (beginning-of-line)
+             (looking-at yaml-block-literal-re)))
+      (insert (cdr extra-chars))
+      (newline-and-indent)))))
+
+(defun yaml-electric-dash-and-dot (arg)
+  "Insert the bound key and possibly de-dent line.
+Inserts the bound key.  If inserting the bound key causes the current
+line to match a document delimiter, de-dent the line to the left
+margin."
+  (interactive "*P")
+  (self-insert-command (prefix-numeric-value arg))
+  (save-excursion
+    (beginning-of-line)
+    (when (and (not arg) (looking-at yaml-document-delimiter-re))
+      (delete-horizontal-space))))
+
+(defun yaml-narrow-to-block-literal ()
+  "Narrow the buffer to block literal if the point is in it,
+otherwise do nothing."
+  (interactive)
+  (save-excursion
+    (goto-char (point-at-bol))
+    (while (and (looking-at-p yaml-blank-line-re) (not (bobp)))
+      (forward-line -1))
+    (let ((nlines yaml-block-literal-search-lines)
+	  (min-level (current-indentation))
+	  beg)
+      (forward-line -1)
+      (while (and (/= nlines 0)
+		  (/= min-level 0)
+		  (not (looking-at-p yaml-block-literal-re))
+		  (not (bobp)))
+	(setq nlines (1- nlines))
+	(unless (looking-at-p yaml-blank-line-re)
+	  (setq min-level (min min-level (current-indentation))))
+	(forward-line -1))
+      (when (and (< (current-indentation) min-level)
+                 (looking-at-p yaml-block-literal-re))
+	(setq min-level (current-indentation))
+	(forward-line)
+	(setq beg (point))
+	(while (and (not (eobp))
+		    (or (looking-at-p yaml-blank-line-re)
+			(> (current-indentation) min-level)))
+	  (forward-line))
+	(narrow-to-region beg (point))))))
+
+(defun yaml-fill-paragraph (&optional justify region)
+  "Fill paragraph.
+Outside of comments, this behaves as `fill-paragraph' except that
+filling does not cross boundaries of block literals.  Inside comments,
+this will do usual adaptive fill behaviors."
+  (interactive "*P")
+  (save-restriction
+    (yaml-narrow-to-block-literal)
+    (let ((fill-paragraph-function nil))
+      (or (fill-comment-paragraph justify)
+          (fill-paragraph justify region)))))
+
+(defun yaml-set-imenu-generic-expression ()
+  (make-local-variable 'imenu-generic-expression)
+  (make-local-variable 'imenu-create-index-function)
+  (setq imenu-create-index-function 'imenu-default-create-index-function)
+  (setq imenu-generic-expression yaml-imenu-generic-expression))
+
+(add-hook 'yaml-mode-hook 'yaml-set-imenu-generic-expression)
+
+
+(defun yaml-mode-version ()
+  "Display version of `yaml-mode'."
+  (interactive)
+  (message "yaml-mode %s" yaml-mode-version)
+  yaml-mode-version)
+
+;;;###autoload
+(add-to-list 'auto-mode-alist '("\\.\\(e?ya?\\|ra\\)ml\\'" . yaml-mode))
+
+(provide 'yaml-mode)
+
+;;; yaml-mode.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/yaml-mode-20180408.2307/yaml-mode.elc b/configs/shared/emacs/.emacs.d/elpa/yaml-mode-20180408.2307/yaml-mode.elc
new file mode 100644
index 0000000000..b62cca71fc
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/yaml-mode-20180408.2307/yaml-mode.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/yasnippet-20180620.1750/yasnippet-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/yasnippet-20180620.1750/yasnippet-autoloads.el
new file mode 100644
index 0000000000..5947244c56
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/yasnippet-20180620.1750/yasnippet-autoloads.el
@@ -0,0 +1,56 @@
+;;; yasnippet-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "yasnippet" "yasnippet.el" (23377 60990 666793
+;;;;;;  174000))
+;;; Generated autoloads from yasnippet.el
+
+(autoload 'yas-minor-mode "yasnippet" "\
+Toggle YASnippet mode.
+
+When YASnippet mode is enabled, `yas-expand', normally bound to
+the TAB key, expands snippets of code depending on the major
+mode.
+
+With no argument, this command toggles the mode.
+positive prefix argument turns on the mode.
+Negative prefix argument turns off the mode.
+
+Key bindings:
+\\{yas-minor-mode-map}
+
+\(fn &optional ARG)" t nil)
+
+(defvar yas-global-mode nil "\
+Non-nil if Yas-Global mode is enabled.
+See the `yas-global-mode' command
+for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `yas-global-mode'.")
+
+(custom-autoload 'yas-global-mode "yasnippet" nil)
+
+(autoload 'yas-global-mode "yasnippet" "\
+Toggle Yas minor mode in all buffers.
+With prefix ARG, enable Yas-Global mode if ARG is positive;
+otherwise, disable it.  If called from Lisp, enable the mode if
+ARG is omitted or nil.
+
+Yas minor mode is enabled in all buffers where
+`yas-minor-mode-on' would do it.
+See `yas-minor-mode' for more information on Yas minor mode.
+
+\(fn &optional ARG)" t nil)
+(autoload 'snippet-mode "yasnippet" "A mode for editing yasnippets" t nil)
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; yasnippet-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/yasnippet-20180620.1750/yasnippet-pkg.el b/configs/shared/emacs/.emacs.d/elpa/yasnippet-20180620.1750/yasnippet-pkg.el
new file mode 100644
index 0000000000..6c0a73d771
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/yasnippet-20180620.1750/yasnippet-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "yasnippet" "20180620.1750" "Yet another snippet extension for Emacs." '((cl-lib "0.5")))
diff --git a/configs/shared/emacs/.emacs.d/elpa/yasnippet-20180620.1750/yasnippet.el b/configs/shared/emacs/.emacs.d/elpa/yasnippet-20180620.1750/yasnippet.el
new file mode 100644
index 0000000000..f1e5fe643a
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/yasnippet-20180620.1750/yasnippet.el
@@ -0,0 +1,5106 @@
+;;; yasnippet.el --- Yet another snippet extension for Emacs.
+
+;; Copyright (C) 2008-2018 Free Software Foundation, Inc.
+;; Authors: pluskid <pluskid@gmail.com>,
+;;          João Távora <joaotavora@gmail.com>,
+;;          Noam Postavsky <npostavs@gmail.com>
+;; Maintainer: Noam Postavsky <npostavs@gmail.com>
+;; Version: 0.13.0
+;; Package-Version: 20180620.1750
+;; X-URL: http://github.com/joaotavora/yasnippet
+;; Keywords: convenience, emulation
+;; URL: http://github.com/joaotavora/yasnippet
+;; Package-Requires: ((cl-lib "0.5"))
+;; EmacsWiki: YaSnippetMode
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;
+;;   Basic steps to setup:
+;;
+;;    (add-to-list 'load-path
+;;                 "~/path-to-yasnippet")
+;;    (require 'yasnippet)
+;;    (yas-global-mode 1)
+;;
+;;
+;;   Interesting variables are:
+;;
+;;       `yas-snippet-dirs'
+;;
+;;           The directory where user-created snippets are to be
+;;           stored.  Can also be a list of directories.  In that case,
+;;           when used for bulk (re)loading of snippets (at startup or
+;;           via `yas-reload-all'), directories appearing earlier in
+;;           the list override other dir's snippets.  Also, the first
+;;           directory is taken as the default for storing the user's
+;;           new snippets.
+;;
+;;           The deprecated `yas/root-directory' aliases this variable
+;;           for backward-compatibility.
+;;
+;;
+;;   Major commands are:
+;;
+;;       M-x yas-expand
+;;
+;;           Try to expand snippets before point.  In `yas-minor-mode',
+;;           this is normally bound to TAB, but you can customize it in
+;;           `yas-minor-mode-map'.
+;;
+;;       M-x yas-load-directory
+;;
+;;           Prompts you for a directory hierarchy of snippets to load.
+;;
+;;       M-x yas-activate-extra-mode
+;;
+;;           Prompts you for an extra mode to add snippets for in the
+;;           current buffer.
+;;
+;;       M-x yas-insert-snippet
+;;
+;;           Prompts you for possible snippet expansion if that is
+;;           possible according to buffer-local and snippet-local
+;;           expansion conditions.  With prefix argument, ignore these
+;;           conditions.
+;;
+;;       M-x yas-visit-snippet-file
+;;
+;;           Prompts you for possible snippet expansions like
+;;           `yas-insert-snippet', but instead of expanding it, takes
+;;           you directly to the snippet definition's file, if it
+;;           exists.
+;;
+;;       M-x yas-new-snippet
+;;
+;;           Lets you create a new snippet file in the correct
+;;           subdirectory of `yas-snippet-dirs', according to the
+;;           active major mode.
+;;
+;;       M-x yas-load-snippet-buffer
+;;
+;;           When editing a snippet, this loads the snippet.  This is
+;;           bound to "C-c C-c" while in the `snippet-mode' editing
+;;           mode.
+;;
+;;       M-x yas-tryout-snippet
+;;
+;;           When editing a snippet, this opens a new empty buffer,
+;;           sets it to the appropriate major mode and inserts the
+;;           snippet there, so you can see what it looks like.  This is
+;;           bound to "C-c C-t" while in `snippet-mode'.
+;;
+;;       M-x yas-describe-tables
+;;
+;;           Lists known snippets in a separate buffer.  User is
+;;           prompted as to whether only the currently active tables
+;;           are to be displayed, or all the tables for all major
+;;           modes.
+;;
+;;   If you have `dropdown-list' installed, you can optionally use it
+;;   as the preferred "prompting method", putting in your .emacs file,
+;;   for example:
+;;
+;;       (require 'dropdown-list)
+;;       (setq yas-prompt-functions '(yas-dropdown-prompt
+;;                                    yas-ido-prompt
+;;                                    yas-completing-prompt))
+;;
+;;   Also check out the customization group
+;;
+;;        M-x customize-group RET yasnippet RET
+;;
+;;   If you use the customization group to set variables
+;;   `yas-snippet-dirs' or `yas-global-mode', make sure the path to
+;;   "yasnippet.el" is present in the `load-path' *before* the
+;;   `custom-set-variables' is executed in your .emacs file.
+;;
+;;   For more information and detailed usage, refer to the project page:
+;;      http://github.com/joaotavora/yasnippet
+
+;;; Code:
+
+(require 'cl-lib)
+(declare-function cl-progv-after "cl-extra") ; Needed for 23.4.
+(require 'easymenu)
+(require 'help-mode)
+
+(defvar yas--editing-template)
+(defvar yas--guessed-modes)
+(defvar yas--indent-original-column)
+(defvar yas--scheduled-jit-loads)
+(defvar yas-keymap)
+(defvar yas-selected-text)
+(defvar yas-verbosity)
+(defvar yas--current-template)
+
+
+;;; User customizable variables
+
+(defgroup yasnippet nil
+  "Yet Another Snippet extension"
+  :prefix "yas-"
+  :group 'editing)
+
+(defconst yas--loaddir
+  (file-name-directory (or load-file-name buffer-file-name))
+  "Directory that yasnippet was loaded from.")
+
+(defconst yas-installed-snippets-dir (expand-file-name "snippets" yas--loaddir))
+(make-obsolete-variable 'yas-installed-snippets-dir "\
+Yasnippet no longer comes with installed snippets" "0.13")
+
+(defconst yas--default-user-snippets-dir
+  (expand-file-name "snippets" user-emacs-directory))
+
+(defcustom yas-snippet-dirs (list yas--default-user-snippets-dir)
+  "List of top-level snippet directories.
+
+Each element, a string or a symbol whose value is a string,
+designates a top-level directory where per-mode snippet
+directories can be found.
+
+Elements appearing earlier in the list override later elements'
+snippets.
+
+The first directory is taken as the default for storing snippet's
+created with `yas-new-snippet'. "
+  :type '(choice (directory :tag "Single directory")
+                 (repeat :tag "List of directories"
+                         (choice (directory) (variable))))
+  :set #'(lambda (symbol new)
+           (let ((old (and (boundp symbol)
+                           (symbol-value symbol))))
+             (set-default symbol new)
+             (unless (or (not (fboundp 'yas-reload-all))
+                         (equal old new))
+               (yas-reload-all)))))
+
+(defun yas-snippet-dirs ()
+  "Return variable `yas-snippet-dirs' as list of strings."
+  (cl-loop for e in (if (listp yas-snippet-dirs)
+                        yas-snippet-dirs
+                      (list yas-snippet-dirs))
+           collect
+           (cond ((stringp e) e)
+                 ((and (symbolp e)
+                       (boundp e)
+                       (stringp (symbol-value e)))
+                  (symbol-value e))
+                 (t
+                  (error "[yas] invalid element %s in `yas-snippet-dirs'" e)))))
+
+(defcustom yas-new-snippet-default "\
+# -*- mode: snippet -*-
+# name: $1
+# key: ${2:${1:$(yas--key-from-desc yas-text)}}
+# --
+$0`(yas-escape-text yas-selected-text)`"
+  "Default snippet to use when creating a new snippet.
+If nil, don't use any snippet."
+  :type 'string)
+
+(defcustom yas-prompt-functions '(yas-dropdown-prompt
+                                  yas-completing-prompt
+                                  yas-maybe-ido-prompt
+                                  yas-no-prompt)
+  "Functions to prompt for keys, templates, etc interactively.
+
+These functions are called with the following arguments:
+
+- PROMPT: A string to prompt the user
+
+- CHOICES: a list of strings or objects.
+
+- optional DISPLAY-FN : A function that, when applied to each of
+the objects in CHOICES will return a string.
+
+The return value of any function you put here should be one of
+the objects in CHOICES, properly formatted with DISPLAY-FN (if
+that is passed).
+
+- To signal that your particular style of prompting is
+unavailable at the moment, you can also have the function return
+nil.
+
+- To signal that the user quit the prompting process, you can
+signal `quit' with
+
+    (signal \\='quit \"user quit!\")"
+  :type '(repeat function))
+
+(defcustom yas-indent-line 'auto
+  "Controls indenting applied to a recent snippet expansion.
+
+The following values are possible:
+
+- `fixed' Indent the snippet to the current column;
+
+- `auto' Indent each line of the snippet with `indent-according-to-mode'
+
+Every other value means don't apply any snippet-side indentation
+after expansion (the manual per-line \"$>\" indentation still
+applies)."
+  :type '(choice (const :tag "Nothing"  nothing)
+                 (const :tag "Fixed"    fixed)
+                 (const :tag "Auto"     auto)))
+
+(defcustom yas-also-auto-indent-first-line nil
+  "Non-nil means also auto indent first line according to mode.
+
+Naturally this is only valid when `yas-indent-line' is `auto'."
+  :type 'boolean)
+
+(defcustom yas-also-indent-empty-lines nil
+  "Non-nil means also indent empty lines according to mode."
+  :type 'boolean)
+
+(defcustom yas-snippet-revival t
+  "Non-nil means re-activate snippet fields after undo/redo."
+  :type 'boolean)
+
+(defcustom yas-triggers-in-field nil
+  "If non-nil, allow stacked expansions (snippets inside snippets).
+
+Otherwise `yas-next-field-or-maybe-expand' just moves on to the
+next field"
+  :type 'boolean)
+
+(defcustom yas-fallback-behavior 'return-nil
+  "This option is obsolete.
+Now that the conditional keybinding `yas-maybe-expand' is
+available, there's no more need for it."
+  :type '(choice (const :tag "Call previous command"  call-other-command)
+                 (const :tag "Do nothing"             return-nil)))
+
+(make-obsolete-variable
+ 'yas-fallback-behavior
+ "For `call-other-command' behavior bind to the conditional
+command value `yas-maybe-expand', for `return-nil' behavior bind
+directly to `yas-expand'."
+ "0.12")
+
+(defcustom yas-choose-keys-first nil
+  "If non-nil, prompt for snippet key first, then for template.
+
+Otherwise prompts for all possible snippet names.
+
+This affects `yas-insert-snippet' and `yas-visit-snippet-file'."
+  :type 'boolean)
+
+(defcustom yas-choose-tables-first nil
+  "If non-nil, and multiple eligible snippet tables, prompts user for tables first.
+
+Otherwise, user chooses between the merging together of all
+eligible tables.
+
+This affects `yas-insert-snippet', `yas-visit-snippet-file'"
+  :type 'boolean)
+
+(defcustom yas-use-menu 'abbreviate
+  "Display a YASnippet menu in the menu bar.
+
+When non-nil, submenus for each snippet table will be listed
+under the menu \"Yasnippet\".
+
+- If set to `abbreviate', only the current major-mode
+menu and the modes set in `yas--extra-modes' are listed.
+
+- If set to `full', every submenu is listed
+
+- If set to nil, hide the menu.
+
+Any other non-nil value, every submenu is listed."
+  :type '(choice (const :tag "Full"  full)
+                 (const :tag "Abbreviate" abbreviate)
+                 (const :tag "No menu" nil)))
+
+(defcustom yas-trigger-symbol (or (and (eq window-system 'mac)
+                                       (ignore-errors
+                                         (char-to-string ?\x21E5))) ;; little ->| sign
+                                  " =>")
+  "The text that will be used in menu to represent the trigger."
+  :type 'string)
+
+(defcustom yas-wrap-around-region nil
+  "What to insert for snippet's $0 field.
+
+If set to a character, insert contents of corresponding register.
+If non-nil insert region contents.  This can be overridden on a
+per-snippet basis.  A value of `cua' is considered equivalent to
+`?0' for backwards compatibility."
+  :type '(choice (character :tag "Insert from register")
+                 (const t :tag "Insert region contents")
+                 (const nil :tag "Don't insert anything")
+                 (const cua))) ; backwards compat
+
+(defcustom yas-good-grace t
+  "If non-nil, don't raise errors in elisp evaluation.
+
+This affects both the inline elisp in snippets and the hook
+variables such as `yas-after-exit-snippet-hook'.
+
+If this variable's value is `inline', an error string \"[yas]
+error\" is returned instead of raising the error.  If this
+variable's value is `hooks', a message is output to according to
+`yas-verbosity-level'.  If this variable's value is t, both are
+active."
+  :type 'boolean)
+
+(defcustom yas-visit-from-menu nil
+  "If non-nil visit snippets's files from menu, instead of expanding them.
+
+This can only work when snippets are loaded from files."
+  :type 'boolean)
+
+(defcustom yas-expand-only-for-last-commands nil
+  "List of `last-command' values to restrict tab-triggering to, or nil.
+
+Leave this set at nil (the default) to be able to trigger an
+expansion simply by placing the cursor after a valid tab trigger,
+using whichever commands.
+
+Optionally, set this to something like (self-insert-command) if
+you to wish restrict expansion to only happen when the last
+letter of the snippet tab trigger was typed immediately before
+the trigger key itself."
+  :type '(repeat function))
+
+(defcustom yas-alias-to-yas/prefix-p t
+  "If non-nil make aliases for the old style yas/ prefixed symbols.
+It must be set to nil before loading yasnippet to take effect."
+  :type 'boolean
+  :group 'yasnippet)
+
+;; Only two faces, and one of them shouldn't even be used...
+;;
+(defface yas-field-highlight-face
+  '((t (:inherit 'region)))
+  "The face used to highlight the currently active field of a snippet")
+
+(defface yas--field-debug-face
+  '()
+  "The face used for debugging some overlays normally hidden")
+
+
+;;; User-visible variables
+
+(defconst yas-maybe-skip-and-clear-field
+  '(menu-item "" yas-skip-and-clear-field
+              :filter yas--maybe-clear-field-filter)
+  "A conditional key definition.
+This can be used as a key definition in keymaps to bind a key to
+`yas-skip-and-clear-field' only when at the beginning of an
+unmodified snippey field.")
+
+(defvar yas-keymap  (let ((map (make-sparse-keymap)))
+                      (define-key map [(tab)]       'yas-next-field-or-maybe-expand)
+                      (define-key map (kbd "TAB")   'yas-next-field-or-maybe-expand)
+                      (define-key map [(shift tab)] 'yas-prev-field)
+                      (define-key map [backtab]     'yas-prev-field)
+                      (define-key map (kbd "C-g")   'yas-abort-snippet)
+                      (define-key map (kbd "C-d")   yas-maybe-skip-and-clear-field)
+                      map)
+  "The active keymap while a snippet expansion is in progress.")
+
+(defvar yas-key-syntaxes (list #'yas-try-key-from-whitespace
+                               "w_.()" "w_." "w_" "w")
+  "Syntaxes and functions to help look for trigger keys before point.
+
+Each element in this list specifies how to skip buffer positions
+backwards and look for the start of a trigger key.
+
+Each element can be either a string or a function receiving the
+original point as an argument. A string element is simply passed
+to `skip-syntax-backward' whereas a function element is called
+with no arguments and should also place point before the original
+position.
+
+The string between the resulting buffer position and the original
+point is matched against the trigger keys in the active snippet
+tables.
+
+If no expandable snippets are found, the next element is the list
+is tried, unless a function element returned the symbol `again',
+in which case it is called again from the previous position and
+may once more reposition point.
+
+For example, if `yas-key-syntaxes' has the value (\"w\" \"w_\"),
+trigger keys composed exclusively of \"word\"-syntax characters
+are looked for first. Failing that, longer keys composed of
+\"word\" or \"symbol\" syntax are looked for. Therefore,
+triggering after
+
+foo-bar
+
+will, according to the \"w\" element first try \"barbaz\". If
+that isn't a trigger key, \"foo-barbaz\" is tried, respecting the
+second \"w_\" element. Notice that even if \"baz\" is a trigger
+key for an active snippet, it won't be expanded, unless a
+function is added to `yas-key-syntaxes' that eventually places
+point between \"bar\" and \"baz\".
+
+See also Info node `(elisp) Syntax Descriptors'.")
+
+(defvar yas-after-exit-snippet-hook
+  '()
+  "Hooks to run after a snippet exited.
+
+The hooks will be run in an environment where some variables bound to
+proper values:
+
+`yas-snippet-beg' : The beginning of the region of the snippet.
+
+`yas-snippet-end' : Similar to beg.
+
+Attention: These hooks are not run when exiting nested/stacked snippet expansion!")
+
+(defvar yas-before-expand-snippet-hook
+  '()
+  "Hooks to run just before expanding a snippet.")
+
+(defconst yas-not-string-or-comment-condition
+  '(if (and (let ((ppss (syntax-ppss)))
+              (or (nth 3 ppss) (nth 4 ppss)))
+            (memq this-command '(yas-expand yas-expand-from-trigger-key
+                                            yas-expand-from-keymap)))
+       '(require-snippet-condition . force-in-comment)
+     t)
+  "Disables snippet expansion in strings and comments.
+To use, set `yas-buffer-local-condition' to this value.")
+
+(defcustom yas-buffer-local-condition t
+  "Snippet expanding condition.
+
+This variable is a Lisp form which is evaluated every time a
+snippet expansion is attempted:
+
+    * If it evaluates to nil, no snippets can be expanded.
+
+    * If it evaluates to the a cons (require-snippet-condition
+      . REQUIREMENT)
+
+       * Snippets bearing no \"# condition:\" directive are not
+         considered
+
+       * Snippets bearing conditions that evaluate to nil (or
+         produce an error) won't be considered.
+
+       * If the snippet has a condition that evaluates to non-nil
+         RESULT:
+
+          * If REQUIREMENT is t, the snippet is considered
+
+          * If REQUIREMENT is `eq' RESULT, the snippet is
+            considered
+
+          * Otherwise, the snippet is not considered.
+
+    * If it evaluates to the symbol `always', all snippets are
+      considered for expansion, regardless of any conditions.
+
+    * If it evaluates to t or some other non-nil value
+
+       * Snippet bearing no conditions, or conditions that
+         evaluate to non-nil, are considered for expansion.
+
+       * Otherwise, the snippet is not considered.
+
+Here's an example preventing snippets from being expanded from
+inside comments, in `python-mode' only, with the exception of
+snippets returning the symbol `force-in-comment' in their
+conditions.
+
+ (add-hook \\='python-mode-hook
+           (lambda ()
+              (setq yas-buffer-local-condition
+                    \\='(if (python-syntax-comment-or-string-p)
+                         \\='(require-snippet-condition . force-in-comment)
+                       t))))"
+  :type
+  `(choice
+    (const :tag "Disable snippet expansion inside strings and comments"
+           ,yas-not-string-or-comment-condition)
+    (const :tag "Expand all snippets regardless of conditions" always)
+    (const :tag "Expand snippets unless their condition is nil" t)
+    (const :tag "Disable all snippet expansion" nil)
+    sexp))
+
+(defcustom yas-overlay-priority 100
+  "Priority to use for yasnippets overlays.
+This is useful to control whether snippet navigation bindings
+override bindings from other packages (e.g., `company-mode')."
+  :type 'integer)
+
+
+;;; Internal variables
+
+(defconst yas--version "0.13.0")
+
+(defvar yas--menu-table (make-hash-table)
+  "A hash table of MAJOR-MODE symbols to menu keymaps.")
+
+(defvar yas--escaped-characters
+  '(?\\ ?` ?\" ?' ?$ ?} ?{ ?\( ?\))
+  "List of characters which *might* need to be escaped.")
+
+(defconst yas--field-regexp
+  "${\\([0-9]+:\\)?\\([^}]*\\)}"
+  "A regexp to *almost* recognize a field.")
+
+(defconst yas--multi-dollar-lisp-expression-regexp
+  "$+[ \t\n]*\\(([^)]*)\\)"
+  "A regexp to *almost* recognize a \"$(...)\" expression.")
+
+(defconst yas--backquote-lisp-expression-regexp
+  "`\\([^`]*\\)`"
+  "A regexp to recognize a \"\\=`lisp-expression\\=`\" expression." )
+
+(defconst yas--transform-mirror-regexp
+  "${\\(?:\\([0-9]+\\):\\)?$\\([ \t\n]*([^}]*\\)"
+  "A regexp to *almost* recognize a mirror with a transform.")
+
+(defconst yas--simple-mirror-regexp
+  "$\\([0-9]+\\)"
+  "A regexp to recognize a simple mirror.")
+
+(defvar yas--snippet-id-seed 0
+  "Contains the next id for a snippet.")
+
+(defvar yas--original-auto-fill-function nil
+  "The original value of `auto-fill-function'.")
+(make-variable-buffer-local 'yas--original-auto-fill-function)
+
+(defvar yas--watch-auto-fill-backtrace nil)
+
+(defun yas--watch-auto-fill (sym newval op _where)
+  (when (and (or (and (eq sym 'yas--original-auto-fill-function)
+                      (null newval)
+                      (eq auto-fill-function 'yas--auto-fill))
+                 (and (eq sym 'auto-fill-function)
+                      (eq newval 'yas--auto-fill)
+                      (null yas--original-auto-fill-function)))
+             (null yas--watch-auto-fill-backtrace)
+             (fboundp 'backtrace-frames) ; Suppress compiler warning.
+             ;; If we're about to change `auto-fill-function' too,
+             ;; it's okay (probably).
+             (not (and (eq op 'makunbound)
+                       (not (eq (default-value 'auto-fill-function) 'yas--auto-fill))
+                       (cl-member 'kill-all-local-variables
+                                  (backtrace-frames 'yas--watch-auto-fill)
+                                  :key (lambda (frame) (nth 1 frame))))))
+    (setq yas--watch-auto-fill-backtrace
+          (backtrace-frames 'yas--watch-auto-fill))))
+
+;; Try to get more info on #873/919 (this only works for Emacs 26+).
+(when (fboundp 'add-variable-watcher)
+  (add-variable-watcher 'yas--original-auto-fill-function
+                        #'yas--watch-auto-fill)
+  (add-variable-watcher 'auto-fill-function
+                        #'yas--watch-auto-fill))
+
+(defun yas--snippet-next-id ()
+  (let ((id yas--snippet-id-seed))
+    (cl-incf yas--snippet-id-seed)
+    id))
+
+
+;;; Minor mode stuff
+
+(defvar yas--minor-mode-menu nil
+  "Holds the YASnippet menu.")
+
+(defvar yas--condition-cache-timestamp nil)
+
+(defun yas--maybe-expand-key-filter (cmd)
+  (when (let ((yas--condition-cache-timestamp (current-time)))
+          (yas--templates-for-key-at-point))
+    cmd))
+
+(defconst yas-maybe-expand
+  '(menu-item "" yas-expand :filter yas--maybe-expand-key-filter)
+  "A conditional key definition.
+This can be used as a key definition in keymaps to bind a key to
+`yas-expand' only when there is a snippet available to be
+expanded.")
+
+(defvar yas-minor-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map [(tab)]     yas-maybe-expand)
+    (define-key map (kbd "TAB") yas-maybe-expand)
+    (define-key map "\C-c&\C-s" 'yas-insert-snippet)
+    (define-key map "\C-c&\C-n" 'yas-new-snippet)
+    (define-key map "\C-c&\C-v" 'yas-visit-snippet-file)
+    map)
+  "The keymap used when `yas-minor-mode' is active.")
+
+(easy-menu-define yas--minor-mode-menu
+      yas-minor-mode-map
+      "Menu used when `yas-minor-mode' is active."
+  '("YASnippet" :visible yas-use-menu
+    "----"
+    ["Expand trigger" yas-expand
+     :help "Possibly expand tab trigger before point"]
+    ["Insert at point..." yas-insert-snippet
+     :help "Prompt for an expandable snippet and expand it at point"]
+    ["New snippet..." yas-new-snippet
+     :help "Create a new snippet in an appropriate directory"]
+    ["Visit snippet file..." yas-visit-snippet-file
+     :help "Prompt for an expandable snippet and find its file"]
+    "----"
+    ("Snippet menu behaviour"
+     ["Visit snippets" (setq yas-visit-from-menu t)
+      :help "Visit snippets from the menu"
+      :active t :style radio   :selected yas-visit-from-menu]
+     ["Expand snippets" (setq yas-visit-from-menu nil)
+      :help "Expand snippets from the menu"
+      :active t :style radio :selected (not yas-visit-from-menu)]
+     "----"
+     ["Show all known modes" (setq yas-use-menu 'full)
+      :help "Show one snippet submenu for each loaded table"
+      :active t :style radio   :selected (eq yas-use-menu 'full)]
+     ["Abbreviate according to current mode" (setq yas-use-menu 'abbreviate)
+      :help "Show only snippet submenus for the current active modes"
+      :active t :style radio   :selected (eq yas-use-menu 'abbreviate)])
+    ("Indenting"
+     ["Auto" (setq yas-indent-line 'auto)
+      :help "Indent each line of the snippet with `indent-according-to-mode'"
+      :active t :style radio   :selected (eq yas-indent-line 'auto)]
+     ["Fixed" (setq yas-indent-line 'fixed)
+      :help "Indent the snippet to the current column"
+      :active t :style radio   :selected (eq yas-indent-line 'fixed)]
+     ["None" (setq yas-indent-line 'none)
+      :help "Don't apply any particular snippet indentation after expansion"
+      :active t :style radio   :selected (not (member yas-indent-line '(fixed auto)))]
+     "----"
+     ["Also auto indent first line" (setq yas-also-auto-indent-first-line
+                                          (not yas-also-auto-indent-first-line))
+      :help "When auto-indenting also, auto indent the first line menu"
+      :active (eq yas-indent-line 'auto)
+      :style toggle :selected yas-also-auto-indent-first-line]
+     )
+    ("Prompting method"
+     ["System X-widget" (setq yas-prompt-functions
+                              (cons #'yas-x-prompt
+                                    (remove #'yas-x-prompt
+                                            yas-prompt-functions)))
+      :help "Use your windowing system's (gtk, mac, windows, etc...) default menu"
+      :active t :style radio   :selected (eq (car yas-prompt-functions)
+                                             #'yas-x-prompt)]
+     ["Dropdown-list" (setq yas-prompt-functions
+                            (cons #'yas-dropdown-prompt
+                                  (remove #'yas-dropdown-prompt
+                                          yas-prompt-functions)))
+      :help "Use a special dropdown list"
+      :active t :style radio   :selected (eq (car yas-prompt-functions)
+                                             #'yas-dropdown-prompt)]
+     ["Ido" (setq yas-prompt-functions
+                  (cons #'yas-ido-prompt
+                        (remove #'yas-ido-prompt
+                                yas-prompt-functions)))
+      :help "Use an ido-style minibuffer prompt"
+      :active t :style radio   :selected (eq (car yas-prompt-functions)
+                                             #'yas-ido-prompt)]
+     ["Completing read" (setq yas-prompt-functions
+                              (cons #'yas-completing-prompt
+                                    (remove #'yas-completing-prompt
+                                            yas-prompt-functions)))
+      :help "Use a normal minibuffer prompt"
+      :active t :style radio   :selected (eq (car yas-prompt-functions)
+                                             #'yas-completing-prompt)]
+     )
+    ("Misc"
+     ["Wrap region in exit marker"
+      (setq yas-wrap-around-region
+            (not yas-wrap-around-region))
+      :help "If non-nil automatically wrap the selected text in the $0 snippet exit"
+      :style toggle :selected yas-wrap-around-region]
+     ["Allow stacked expansions "
+      (setq yas-triggers-in-field
+            (not yas-triggers-in-field))
+      :help "If non-nil allow snippets to be triggered inside other snippet fields"
+      :style toggle :selected yas-triggers-in-field]
+     ["Revive snippets on undo "
+      (setq yas-snippet-revival
+            (not yas-snippet-revival))
+      :help "If non-nil allow snippets to become active again after undo"
+      :style toggle :selected yas-snippet-revival]
+     ["Good grace "
+      (setq yas-good-grace
+            (not yas-good-grace))
+      :help "If non-nil don't raise errors in bad embedded elisp in snippets"
+      :style toggle :selected yas-good-grace]
+     )
+    "----"
+    ["Load snippets..."  yas-load-directory
+     :help "Load snippets from a specific directory"]
+    ["Reload everything" yas-reload-all
+     :help "Cleanup stuff, reload snippets, rebuild menus"]
+    ["About"            yas-about
+     :help "Display some information about YASnippet"]))
+
+(defvar yas--extra-modes nil
+  "An internal list of modes for which to also lookup snippets.
+
+This variable probably makes more sense as buffer-local, so
+ensure your use `make-local-variable' when you set it.")
+(define-obsolete-variable-alias 'yas-extra-modes 'yas--extra-modes "0.9.1")
+
+(defvar yas--tables (make-hash-table)
+  "A hash table of mode symbols to `yas--table' objects.")
+
+(defvar yas--parents (make-hash-table)
+  "A hash table of mode symbols do lists of direct parent mode symbols.
+
+This list is populated when reading the \".yas-parents\" files
+found when traversing snippet directories with
+`yas-load-directory'.
+
+There might be additional parenting information stored in the
+`derived-mode-parent' property of some mode symbols, but that is
+not recorded here.")
+
+(defvar yas--direct-keymaps (list)
+  "Keymap alist supporting direct snippet keybindings.
+
+This variable is placed in `emulation-mode-map-alists'.
+
+Its elements looks like (TABLE-NAME . KEYMAP).  They're
+instantiated on `yas-reload-all' but KEYMAP is added to only when
+loading snippets.  `yas--direct-TABLE-NAME' is then a variable
+set buffer-locally when entering `yas-minor-mode'.  KEYMAP binds
+all defined direct keybindings to `yas-maybe-expand-from-keymap'
+which decides on the snippet to expand.")
+
+(defun yas-direct-keymaps-reload ()
+  "Force reload the direct keybinding for active snippet tables."
+  (interactive)
+  (setq yas--direct-keymaps nil)
+  (maphash #'(lambda (name table)
+               (push (cons (intern (format "yas--direct-%s" name))
+                           (yas--table-direct-keymap table))
+                     yas--direct-keymaps))
+           yas--tables))
+
+(defun yas--modes-to-activate (&optional mode)
+  "Compute list of mode symbols that are active for `yas-expand' and friends."
+  (defvar yas--dfs)        ;We rely on dynbind.  We could use `letrec' instead!
+  (let* ((explored (if mode (list mode) ; Building up list in reverse.
+                     (cons major-mode (reverse yas--extra-modes))))
+         (yas--dfs
+          (lambda (mode)
+            (cl-loop for neighbour
+                     in (cl-list* (get mode 'derived-mode-parent)
+                                  ;; NOTE: `fboundp' check is redundant
+                                  ;; since Emacs 24.4.
+                                  (and (fboundp mode) (symbol-function mode))
+                                  (gethash mode yas--parents))
+                     when (and neighbour
+                               (not (memq neighbour explored))
+                               (symbolp neighbour))
+                     do (push neighbour explored)
+                     (funcall yas--dfs neighbour)))))
+    (mapc yas--dfs explored)
+    (nreverse explored)))
+
+(defvar yas-minor-mode-hook nil
+  "Hook run when `yas-minor-mode' is turned on.")
+
+(defun yas--auto-fill-wrapper ()
+  (when (and auto-fill-function
+             (not (eq auto-fill-function #'yas--auto-fill)))
+    (setq yas--original-auto-fill-function auto-fill-function)
+    (setq auto-fill-function #'yas--auto-fill)))
+
+;;;###autoload
+(define-minor-mode yas-minor-mode
+  "Toggle YASnippet mode.
+
+When YASnippet mode is enabled, `yas-expand', normally bound to
+the TAB key, expands snippets of code depending on the major
+mode.
+
+With no argument, this command toggles the mode.
+positive prefix argument turns on the mode.
+Negative prefix argument turns off the mode.
+
+Key bindings:
+\\{yas-minor-mode-map}"
+  :lighter " yas" ;; The indicator for the mode line.
+  (cond ((and yas-minor-mode (featurep 'yasnippet))
+         ;; Install the direct keymaps in `emulation-mode-map-alists'
+         ;; (we use `add-hook' even though it's not technically a hook,
+         ;; but it works). Then define variables named after modes to
+         ;; index `yas--direct-keymaps'.
+         ;;
+         ;; Also install the post-command-hook.
+         ;;
+         (cl-pushnew 'yas--direct-keymaps emulation-mode-map-alists)
+         (add-hook 'post-command-hook #'yas--post-command-handler nil t)
+         ;; Set the `yas--direct-%s' vars for direct keymap expansion
+         ;;
+         (dolist (mode (yas--modes-to-activate))
+           (let ((name (intern (format "yas--direct-%s" mode))))
+             (set-default name nil)
+             (set (make-local-variable name) t)))
+         ;; Perform JIT loads
+         (yas--load-pending-jits)
+         ;; Install auto-fill handler.
+         (yas--auto-fill-wrapper)       ; Now...
+         (add-hook 'auto-fill-mode-hook #'yas--auto-fill-wrapper)) ; or later.
+        (t
+         ;; Uninstall the direct keymaps, post-command hook, and
+         ;; auto-fill handler.
+         (remove-hook 'post-command-hook #'yas--post-command-handler t)
+         (remove-hook 'auto-fill-mode-hook #'yas--auto-fill-wrapper)
+         (when (local-variable-p 'yas--original-auto-fill-function)
+           (setq auto-fill-function yas--original-auto-fill-function))
+         (setq emulation-mode-map-alists
+               (remove 'yas--direct-keymaps emulation-mode-map-alists)))))
+
+(defun yas-activate-extra-mode (mode)
+  "Activates the snippets for the given `mode' in the buffer.
+
+The function can be called in the hook of a minor mode to
+activate snippets associated with that mode."
+  (interactive
+   (let (modes
+         symbol)
+     (maphash (lambda (k _)
+                (setq modes (cons (list k) modes)))
+              yas--parents)
+     (setq symbol (completing-read
+                   "Activate mode: " modes nil t))
+     (list
+      (when (not (string= "" symbol))
+        (intern symbol)))))
+  (when mode
+    (add-to-list (make-local-variable 'yas--extra-modes) mode)
+    (yas--load-pending-jits)))
+
+(defun yas-deactivate-extra-mode (mode)
+  "Deactivates the snippets for the given `mode' in the buffer."
+  (interactive
+   (list (intern
+          (completing-read
+           "Deactivate mode: " (mapcar #'list yas--extra-modes) nil t))))
+  (set (make-local-variable 'yas--extra-modes)
+       (remove mode
+               yas--extra-modes)))
+
+(define-obsolete-variable-alias 'yas-dont-activate
+  'yas-dont-activate-functions "0.9.2")
+(defvar yas-dont-activate-functions (list #'minibufferp)
+  "Special hook to control which buffers `yas-global-mode' affects.
+Functions are called with no argument, and should return non-nil to prevent
+`yas-global-mode' from enabling yasnippet in this buffer.
+
+In Emacsen < 24, this variable is buffer-local.  Because
+`yas-minor-mode-on' is called by `yas-global-mode' after
+executing the buffer's major mode hook, setting this variable
+there is an effective way to define exceptions to the \"global\"
+activation behaviour.
+
+In Emacsen >= 24, only the global value is used.  To define
+per-mode exceptions to the \"global\" activation behaviour, call
+`yas-minor-mode' with a negative argument directily in the major
+mode's hook.")
+(unless (> emacs-major-version 23)
+  (with-no-warnings
+    (make-variable-buffer-local 'yas-dont-activate)))
+
+
+(defun yas-minor-mode-on ()
+  "Turn on YASnippet minor mode.
+
+Honour `yas-dont-activate-functions', which see."
+  (interactive)
+  (unless (or
+           ;; The old behavior used for Emacs<24 was to set
+           ;; `yas-dont-activate-functions' to t buffer-locally.
+           (not (or (listp yas-dont-activate-functions)
+                    (functionp yas-dont-activate-functions)))
+           (run-hook-with-args-until-success 'yas-dont-activate-functions))
+    (yas-minor-mode 1)))
+
+;;;###autoload
+(define-globalized-minor-mode yas-global-mode yas-minor-mode yas-minor-mode-on)
+
+(defun yas--global-mode-reload-with-jit-maybe ()
+  "Run `yas-reload-all' when `yas-global-mode' is on."
+  (when yas-global-mode (yas-reload-all)))
+
+(add-hook 'yas-global-mode-hook #'yas--global-mode-reload-with-jit-maybe)
+
+
+;;; Major mode stuff
+
+(defvar yas--font-lock-keywords
+  (append '(("^#.*$" . font-lock-comment-face))
+          (with-temp-buffer
+            (let ((prog-mode-hook nil)
+                  (emacs-lisp-mode-hook nil))
+              (ignore-errors (emacs-lisp-mode)))
+            (font-lock-set-defaults)
+            (if (eq t (car-safe font-lock-keywords))
+                ;; They're "compiled", so extract the source.
+                (cadr font-lock-keywords)
+              font-lock-keywords))
+          '(("\\$\\([0-9]+\\)"
+             (0 font-lock-keyword-face)
+             (1 font-lock-string-face t))
+            ("\\${\\([0-9]+\\):?"
+             (0 font-lock-keyword-face)
+             (1 font-lock-warning-face t))
+            ("\\(\\$(\\)" 1 font-lock-preprocessor-face)
+            ("}"
+             (0 font-lock-keyword-face)))))
+
+(defvar snippet-mode-map
+  (let ((map (make-sparse-keymap)))
+    (easy-menu-define nil
+      map
+      "Menu used when snippet-mode is active."
+      (cons "Snippet"
+            (mapcar #'(lambda (ent)
+                        (when (nth 2 ent)
+                          (define-key map (nth 2 ent) (nth 1 ent)))
+                        (vector (nth 0 ent) (nth 1 ent) t))
+                    '(("Load this snippet" yas-load-snippet-buffer "\C-c\C-l")
+                      ("Load and quit window" yas-load-snippet-buffer-and-close "\C-c\C-c")
+                      ("Try out this snippet" yas-tryout-snippet "\C-c\C-t")))))
+    map)
+  "The keymap used when `snippet-mode' is active.")
+
+
+
+;;;###autoload(autoload 'snippet-mode "yasnippet" "A mode for editing yasnippets" t nil)
+(eval-and-compile
+  (if (fboundp 'prog-mode)
+      ;; `prog-mode' is new in 24.1.
+      (define-derived-mode snippet-mode prog-mode "Snippet"
+        "A mode for editing yasnippets"
+        (setq font-lock-defaults '(yas--font-lock-keywords))
+        (set (make-local-variable 'require-final-newline) nil)
+        (set (make-local-variable 'comment-start) "#")
+        (set (make-local-variable 'comment-start-skip) "#+[\t ]*")
+        (add-hook 'after-save-hook #'yas-maybe-load-snippet-buffer nil t))
+    (define-derived-mode snippet-mode fundamental-mode "Snippet"
+      "A mode for editing yasnippets"
+      (setq font-lock-defaults '(yas--font-lock-keywords))
+      (set (make-local-variable 'require-final-newline) nil)
+      (set (make-local-variable 'comment-start) "#")
+      (set (make-local-variable 'comment-start-skip) "#+[\t ]*")
+      (add-hook 'after-save-hook #'yas-maybe-load-snippet-buffer nil t))))
+
+(defun yas-snippet-mode-buffer-p ()
+  "Return non-nil if current buffer should be in `snippet-mode'.
+Meaning it's visiting a file under one of the mode directories in
+`yas-snippet-dirs'."
+  (when buffer-file-name
+    (cl-member buffer-file-name (yas-snippet-dirs)
+               :test #'file-in-directory-p)))
+
+;; We're abusing `magic-fallback-mode-alist' here because
+;; `auto-mode-alist' doesn't support function matchers.
+(add-to-list 'magic-fallback-mode-alist
+             `(yas-snippet-mode-buffer-p . snippet-mode))
+
+
+;;; Internal structs for template management
+
+(cl-defstruct (yas--template
+               (:constructor yas--make-template)
+               ;; Handles `yas-define-snippets' format, plus the
+               ;; initial TABLE argument.
+               (:constructor
+                yas--define-snippets-2
+                (table
+                 key content
+                 &optional xname condition group
+                 expand-env load-file xkeybinding xuuid save-file
+                 &aux
+                 (name (or xname
+                           ;; A little redundant: we always get a name
+                           ;; from `yas--parse-template' except when
+                           ;; there isn't a file.
+                           (and load-file (file-name-nondirectory load-file))
+                           (and save-file (file-name-nondirectory save-file))
+                           key))
+                 (keybinding (yas--read-keybinding xkeybinding))
+                 (uuid (or xuuid name))
+                 (old (gethash uuid (yas--table-uuidhash table)))
+                 (menu-binding-pair
+                  (and old (yas--template-menu-binding-pair old)))
+                 (perm-group
+                  (and old (yas--template-perm-group old))))))
+  "A template for a snippet."
+  key
+  content
+  name
+  condition
+  expand-env
+  load-file
+  save-file
+  keybinding
+  uuid
+  menu-binding-pair
+  group      ;; as dictated by the #group: directive or .yas-make-groups
+  perm-group ;; as dictated by `yas-define-menu'
+  table
+  )
+
+(cl-defstruct (yas--table (:constructor yas--make-snippet-table (name)))
+  "A table to store snippets for a particular mode.
+
+Has the following fields:
+
+`yas--table-name'
+
+  A symbol name normally corresponding to a major mode, but can
+  also be a pseudo major-mode to be used in
+  `yas-activate-extra-mode', for example.
+
+`yas--table-hash'
+
+  A hash table (KEY . NAMEHASH), known as the \"keyhash\". KEY is
+  a string or a vector, where the former is the snippet's trigger
+  and the latter means it's a direct keybinding. NAMEHASH is yet
+  another hash of (NAME . TEMPLATE) where NAME is the snippet's
+  name and TEMPLATE is a `yas--template' object.
+
+`yas--table-direct-keymap'
+
+  A keymap for the snippets in this table that have direct
+  keybindings. This is kept in sync with the keyhash, i.e., all
+  the elements of the keyhash that are vectors appear here as
+  bindings to `yas-maybe-expand-from-keymap'.
+
+`yas--table-uuidhash'
+
+  A hash table mapping snippets uuid's to the same `yas--template'
+  objects. A snippet uuid defaults to the snippet's name."
+  name
+  (hash (make-hash-table :test 'equal))
+  (uuidhash (make-hash-table :test 'equal))
+  (parents nil)
+  (direct-keymap (make-sparse-keymap)))
+
+(defun yas--get-template-by-uuid (mode uuid)
+  "Find the snippet template in MODE by its UUID."
+  (let* ((table (gethash mode yas--tables mode)))
+    (when table
+      (gethash uuid (yas--table-uuidhash table)))))
+
+;; Apropos storing/updating in TABLE, this works in two steps:
+;;
+;; 1. `yas--remove-template-by-uuid' removes any
+;;    keyhash-namehash-template mappings from TABLE, grabbing the
+;;    snippet by its uuid. Also removes mappings from TABLE's
+;;    `yas--table-direct-keymap' (FIXME: and should probably take care
+;;    of potentially stale menu bindings right?.)
+;;
+;; 2. `yas--add-template' adds this all over again.
+;;
+;;    Create a new or add to an existing keyhash-namehash mapping.
+;;
+;;  For reference on understanding this, consider three snippet
+;;  definitions:
+;;
+;;  A:   # name: The Foo
+;;       # key: foo
+;;       # binding: C-c M-l
+;;
+;;  B:   # name: Mrs Foo
+;;       # key: foo
+;;
+;;  C:   # name: The Bar
+;;       # binding: C-c M-l
+;;
+;;  D:   # name: Baz
+;;       # key: baz
+;;
+;;  keyhash       namehashes(3)      yas--template structs(4)
+;;  -----------------------------------------------------
+;;                                            __________
+;;                                           /          \
+;;  "foo"      --->  "The Foo" --->  [yas--template A]   |
+;;                   "Mrs Foo" --->  [yas--template B]   |
+;;                                                      |
+;;  [C-c M-l]  --->  "The Foo" -------------------------/
+;;                   "The Bar" --->  [yas--template C]
+;;
+;;  "baz"      --->  "Baz"     --->  [yas--template D]
+;;
+;; Additionally, since uuid defaults to the name, we have a
+;; `yas--table-uuidhash' for TABLE
+;;
+;; uuidhash       yas--template structs
+;; -------------------------------
+;; "The Foo" ---> [yas--template A]
+;; "Mrs Foo" ---> [yas--template B]
+;; "The Bar" ---> [yas--template C]
+;; "Baz"     ---> [yas--template D]
+;;
+;; FIXME: the more I look at this data-structure the more I think I'm
+;; stupid. There has to be an easier way (but beware lots of code
+;; depends on this).
+;;
+(defun yas--remove-template-by-uuid (table uuid)
+  "Remove from TABLE a template identified by UUID."
+  (let ((template (gethash uuid (yas--table-uuidhash table))))
+    (when template
+      (let* ((name                (yas--template-name template))
+             (empty-keys          nil))
+        ;; Remove the name from each of the targeted namehashes
+        ;;
+        (maphash #'(lambda (k v)
+                     (let ((template (gethash name v)))
+                       (when (and template
+                                  (equal uuid (yas--template-uuid template)))
+                         (remhash name v)
+                         (when (zerop (hash-table-count v))
+                           (push k empty-keys)))))
+                 (yas--table-hash table))
+        ;; Remove the namehash themselves if they've become empty
+        ;;
+        (dolist (key empty-keys)
+          (when (vectorp key)
+            (define-key (yas--table-direct-keymap table) key nil))
+          (remhash key (yas--table-hash table)))
+
+        ;; Finally, remove the uuid from the uuidhash
+        ;;
+        (remhash uuid (yas--table-uuidhash table))))))
+
+(defconst yas-maybe-expand-from-keymap
+  '(menu-item "" yas-expand-from-keymap
+              :filter yas--maybe-expand-from-keymap-filter))
+
+(defun yas--add-template (table template)
+  "Store in TABLE the snippet template TEMPLATE.
+
+KEY can be a string (trigger key) of a vector (direct
+keybinding)."
+  (let ((name (yas--template-name template))
+        (key (yas--template-key template))
+        (keybinding (yas--template-keybinding template))
+        (_menu-binding-pair (yas--template-menu-binding-pair-get-create template)))
+    (dolist (k (remove nil (list key keybinding)))
+      (puthash name
+               template
+               (or (gethash k
+                            (yas--table-hash table))
+                   (puthash k
+                            (make-hash-table :test 'equal)
+                            (yas--table-hash table))))
+      (when (vectorp k)
+        (define-key (yas--table-direct-keymap table) k yas-maybe-expand-from-keymap)))
+
+    ;; Update TABLE's `yas--table-uuidhash'
+    (puthash (yas--template-uuid template)
+             template
+             (yas--table-uuidhash table))))
+
+(defun yas--update-template (table template)
+  "Add or update TEMPLATE in TABLE.
+
+Also takes care of adding and updating to the associated menu.
+Return TEMPLATE."
+  ;; Remove from table by uuid
+  ;;
+  (yas--remove-template-by-uuid table (yas--template-uuid template))
+  ;; Add to table again
+  ;;
+  (yas--add-template table template)
+  ;; Take care of the menu
+  ;;
+  (yas--update-template-menu table template)
+  template)
+
+(defun yas--update-template-menu (table template)
+  "Update every menu-related for TEMPLATE."
+  (let ((menu-binding-pair (yas--template-menu-binding-pair-get-create template))
+        (key (yas--template-key template))
+        (keybinding (yas--template-keybinding template)))
+    ;; The snippet might have changed name or keys, so update
+    ;; user-visible strings
+    ;;
+    (unless (eq (cdr menu-binding-pair) :none)
+      ;; the menu item name
+      ;;
+      (setf (cl-cadar menu-binding-pair) (yas--template-name template))
+      ;; the :keys information (also visible to the user)
+      (setf (cl-getf (cdr (car menu-binding-pair)) :keys)
+            (or (and keybinding (key-description keybinding))
+                (and key (concat key yas-trigger-symbol))))))
+  (unless (yas--template-menu-managed-by-yas-define-menu template)
+    (let ((menu-keymap
+           (yas--menu-keymap-get-create (yas--table-mode table)
+                                        (mapcar #'yas--table-mode
+                                                (yas--table-parents table))))
+          (group (yas--template-group template)))
+      ;; Remove from menu keymap
+      ;;
+      (cl-assert menu-keymap)
+      (yas--delete-from-keymap menu-keymap (yas--template-uuid template))
+
+      ;; Add necessary subgroups as necessary.
+      ;;
+      (dolist (subgroup group)
+        (let ((subgroup-keymap (lookup-key menu-keymap (vector (make-symbol subgroup)))))
+          (unless (and subgroup-keymap
+                       (keymapp subgroup-keymap))
+            (setq subgroup-keymap (make-sparse-keymap))
+            (define-key menu-keymap (vector (make-symbol subgroup))
+              `(menu-item ,subgroup ,subgroup-keymap)))
+          (setq menu-keymap subgroup-keymap)))
+
+      ;; Add this entry to the keymap
+      ;;
+      (define-key menu-keymap
+        (vector (make-symbol (yas--template-uuid template)))
+        (car (yas--template-menu-binding-pair template))))))
+
+(defun yas--namehash-templates-alist (namehash)
+  "Return NAMEHASH as an alist."
+  (let (alist)
+    (maphash #'(lambda (k v)
+                 (push (cons k v) alist))
+             namehash)
+    alist))
+
+(defun yas--fetch (table key)
+  "Fetch templates in TABLE by KEY.
+
+Return a list of cons (NAME . TEMPLATE) where NAME is a
+string and TEMPLATE is a `yas--template' structure."
+  (let* ((keyhash (yas--table-hash table))
+         (namehash (and keyhash (gethash key keyhash))))
+    (when namehash
+      (yas--filter-templates-by-condition (yas--namehash-templates-alist namehash)))))
+
+
+;;; Filtering/condition logic
+
+(defun yas--eval-condition (condition)
+  (condition-case err
+      (save-excursion
+        (save-restriction
+          (save-match-data
+            (eval condition))))
+    (error (progn
+             (yas--message 1 "Error in condition evaluation: %s" (error-message-string err))
+             nil))))
+
+
+(defun yas--filter-templates-by-condition (templates)
+  "Filter the templates using the applicable condition.
+
+TEMPLATES is a list of cons (NAME . TEMPLATE) where NAME is a
+string and TEMPLATE is a `yas--template' structure.
+
+This function implements the rules described in
+`yas-buffer-local-condition'.  See that variables documentation."
+  (let ((requirement (yas--require-template-specific-condition-p)))
+    (if (eq requirement 'always)
+        templates
+      (cl-remove-if-not (lambda (pair)
+                          (yas--template-can-expand-p
+                           (yas--template-condition (cdr pair)) requirement))
+                        templates))))
+
+(defun yas--require-template-specific-condition-p ()
+  "Decide if this buffer requests/requires snippet-specific
+conditions to filter out potential expansions."
+  (if (eq 'always yas-buffer-local-condition)
+      'always
+    (let ((local-condition (or (and (consp yas-buffer-local-condition)
+                                    (yas--eval-condition yas-buffer-local-condition))
+                               yas-buffer-local-condition)))
+      (when local-condition
+        (if (eq local-condition t)
+            t
+          (and (consp local-condition)
+               (eq 'require-snippet-condition (car local-condition))
+               (symbolp (cdr local-condition))
+               (cdr local-condition)))))))
+
+(defun yas--template-can-expand-p (condition requirement)
+  "Evaluate CONDITION and REQUIREMENT and return a boolean."
+  (let* ((result (or (null condition)
+                     (yas--eval-condition condition))))
+    (cond ((eq requirement t)
+           result)
+          (t
+           (eq requirement result)))))
+
+(defun yas--table-templates (table)
+  (when table
+    (let ((acc (list)))
+      (maphash #'(lambda (_key namehash)
+                   (maphash #'(lambda (name template)
+                                (push (cons name template) acc))
+                            namehash))
+               (yas--table-hash table))
+      (yas--filter-templates-by-condition acc))))
+
+(defun yas--templates-for-key-at-point ()
+  "Find `yas--template' objects for any trigger keys preceding point.
+Returns (TEMPLATES START END). This function respects
+`yas-key-syntaxes', which see."
+  (save-excursion
+    (let ((original (point))
+          (methods yas-key-syntaxes)
+          (templates)
+          (method))
+      (while (and methods
+                  (not templates))
+        (unless (eq method (car methods))
+          ;; TRICKY: `eq'-ness test means we can only be here if
+          ;; `method' is a function that returned `again', and hence
+          ;; don't revert back to original position as per
+          ;; `yas-key-syntaxes'.
+          (goto-char original))
+        (setq method (car methods))
+        (cond ((stringp method)
+               (skip-syntax-backward method)
+               (setq methods (cdr methods)))
+              ((functionp method)
+               (unless (eq (funcall method original)
+                           'again)
+                 (setq methods (cdr methods))))
+              (t
+               (setq methods (cdr methods))
+               (yas--warning "Invalid element `%s' in `yas-key-syntaxes'" method)))
+        (let ((possible-key (buffer-substring-no-properties (point) original)))
+          (save-excursion
+            (goto-char original)
+            (setq templates
+                  (cl-mapcan (lambda (table)
+                               (yas--fetch table possible-key))
+                             (yas--get-snippet-tables))))))
+      (when templates
+        (list templates (point) original)))))
+
+(defun yas--table-all-keys (table)
+  "Get trigger keys of all active snippets in TABLE."
+  (let ((acc))
+    (maphash #'(lambda (key namehash)
+                 (when (yas--filter-templates-by-condition (yas--namehash-templates-alist namehash))
+                   (push key acc)))
+             (yas--table-hash table))
+    acc))
+
+(defun yas--table-mode (table)
+  (intern (yas--table-name table)))
+
+
+;;; Internal functions and macros:
+
+(defun yas--remove-misc-free-from-undo (old-undo-list)
+  "Tries to work around Emacs Bug#30931.
+Helper function for `yas--save-restriction-and-widen'."
+  ;; If Bug#30931 is unfixed, we get (#<Lisp_Misc_Free> . INTEGER)
+  ;; entries in the undo list.  If we call `type-of' on the
+  ;; Lisp_Misc_Free object then Emacs aborts, so try to find it by
+  ;; checking that its type is none of the expected ones.
+  (when (consp buffer-undo-list)
+    (let* ((prev buffer-undo-list)
+           (undo-list prev))
+      (while (and (consp undo-list)
+                  ;; Only check new entries.
+                  (not (eq undo-list old-undo-list)))
+        (let ((entry (pop undo-list)))
+          (when (consp entry)
+            (let ((head (car entry)))
+              (unless (or (stringp head)
+                          (markerp head)
+                          (integerp head)
+                          (symbolp head)
+                          (not (integerp (cdr entry))))
+                ;; (message "removing misc free %S" entry)
+                (setcdr prev undo-list)))))
+        (setq prev undo-list)))))
+
+(defmacro yas--save-restriction-and-widen (&rest body)
+  "Equivalent to (save-restriction (widen) BODY).
+Also tries to work around Emacs Bug#30931."
+  (declare (debug (body)) (indent 0))
+  ;; Disable garbage collection, since it could cause an abort.
+  `(let ((gc-cons-threshold most-positive-fixnum)
+         (old-undo-list buffer-undo-list))
+     (prog1 (save-restriction
+              (widen)
+              ,@body)
+       (yas--remove-misc-free-from-undo old-undo-list))))
+
+(defun yas--eval-for-string (form)
+  "Evaluate FORM and convert the result to string."
+  (let ((debug-on-error (and (not (memq yas-good-grace '(t inline)))
+                             debug-on-error)))
+    (condition-case oops
+        (save-excursion
+          (yas--save-restriction-and-widen
+            (save-match-data
+              (let ((result (eval form)))
+                (when result
+                  (format "%s" result))))))
+      ((debug error) (cdr oops)))))
+
+(defun yas--eval-for-effect (form)
+  (yas--safely-call-fun (apply-partially #'eval form)))
+
+(defun yas--read-lisp (string &optional nil-on-error)
+  "Read STRING as a elisp expression and return it.
+
+In case STRING in an invalid expression and NIL-ON-ERROR is nil,
+return an expression that when evaluated will issue an error."
+  (condition-case err
+      (read string)
+    (error (and (not nil-on-error)
+                `(error (error-message-string ,err))))))
+
+(defun yas--read-keybinding (keybinding)
+  "Read KEYBINDING as a snippet keybinding, return a vector."
+  (when (and keybinding
+             (not (string-match "keybinding" keybinding)))
+    (condition-case err
+        (let ((res (or (and (string-match "^\\[.*\\]$" keybinding)
+                            (read keybinding))
+                       (read-kbd-macro keybinding 'need-vector))))
+          res)
+      (error
+       (yas--message 2 "warning: keybinding \"%s\" invalid since %s."
+                keybinding (error-message-string err))
+       nil))))
+
+(defun yas--table-get-create (mode)
+  "Get or create the snippet table corresponding to MODE."
+  (let ((table (gethash mode
+                        yas--tables)))
+    (unless table
+      (setq table (yas--make-snippet-table (symbol-name mode)))
+      (puthash mode table yas--tables)
+      (push (cons (intern (format "yas--direct-%s" mode))
+                  (yas--table-direct-keymap table))
+            yas--direct-keymaps))
+    table))
+
+(defun yas--get-snippet-tables (&optional mode)
+  "Get snippet tables for MODE.
+
+MODE defaults to the current buffer's `major-mode'.
+
+Return a list of `yas--table' objects.  The list of modes to
+consider is returned by `yas--modes-to-activate'"
+  (remove nil
+          (mapcar #'(lambda (name)
+                      (gethash name yas--tables))
+                  (yas--modes-to-activate mode))))
+
+(defun yas--menu-keymap-get-create (mode &optional parents)
+  "Get or create the menu keymap for MODE and its PARENTS.
+
+This may very well create a plethora of menu keymaps and arrange
+them all in `yas--menu-table'"
+  (let* ((menu-keymap (or (gethash mode yas--menu-table)
+                          (puthash mode (make-sparse-keymap) yas--menu-table))))
+    (mapc #'yas--menu-keymap-get-create parents)
+    (define-key yas--minor-mode-menu (vector mode)
+        `(menu-item ,(symbol-name mode) ,menu-keymap
+                    :visible (yas--show-menu-p ',mode)))
+    menu-keymap))
+
+
+;;; Template-related and snippet loading functions
+
+(defun yas--parse-template (&optional file)
+  "Parse the template in the current buffer.
+
+Optional FILE is the absolute file name of the file being
+parsed.
+
+Optional GROUP is the group where the template is to go,
+otherwise we attempt to calculate it from FILE.
+
+Return a snippet-definition, i.e. a list
+
+ (KEY TEMPLATE NAME CONDITION GROUP VARS LOAD-FILE KEYBINDING UUID)
+
+If the buffer contains a line of \"# --\" then the contents above
+this line are ignored. Directives can set most of these with the syntax:
+
+# directive-name : directive-value
+
+Here's a list of currently recognized directives:
+
+ * type
+ * name
+ * contributor
+ * condition
+ * group
+ * key
+ * expand-env
+ * binding
+ * uuid"
+  (goto-char (point-min))
+  (let* ((type 'snippet)
+         (name (and file
+                    (file-name-nondirectory file)))
+         (key nil)
+         template
+         bound
+         condition
+         (group (and file
+                     (yas--calculate-group file)))
+         expand-env
+         binding
+         uuid)
+    (if (re-search-forward "^# --\\s-*\n" nil t)
+        (progn (setq template
+                     (buffer-substring-no-properties (point)
+                                                     (point-max)))
+               (setq bound (point))
+               (goto-char (point-min))
+               (while (re-search-forward "^# *\\([^ ]+?\\) *: *\\(.*?\\)[[:space:]]*$" bound t)
+                 (when (string= "uuid" (match-string-no-properties 1))
+                   (setq uuid (match-string-no-properties 2)))
+                 (when (string= "type" (match-string-no-properties 1))
+                   (setq type (if (string= "command" (match-string-no-properties 2))
+                                  'command
+                                'snippet)))
+                 (when (string= "key" (match-string-no-properties 1))
+                   (setq key (match-string-no-properties 2)))
+                 (when (string= "name" (match-string-no-properties 1))
+                   (setq name (match-string-no-properties 2)))
+                 (when (string= "condition" (match-string-no-properties 1))
+                   (setq condition (yas--read-lisp (match-string-no-properties 2))))
+                 (when (string= "group" (match-string-no-properties 1))
+                   (setq group (match-string-no-properties 2)))
+                 (when (string= "expand-env" (match-string-no-properties 1))
+                   (setq expand-env (yas--read-lisp (match-string-no-properties 2)
+                                                   'nil-on-error)))
+                 (when (string= "binding" (match-string-no-properties 1))
+                   (setq binding (match-string-no-properties 2)))))
+      (setq template
+            (buffer-substring-no-properties (point-min) (point-max))))
+    (unless (or key binding)
+      (setq key (and file (file-name-nondirectory file))))
+    (when (eq type 'command)
+      (setq template (yas--read-lisp (concat "(progn" template ")"))))
+    (when group
+      (setq group (split-string group "\\.")))
+    (list key template name condition group expand-env file binding uuid)))
+
+(defun yas--calculate-group (file)
+  "Calculate the group for snippet file path FILE."
+  (let* ((dominating-dir (locate-dominating-file file
+                                                 ".yas-make-groups"))
+         (extra-path (and dominating-dir
+                          (file-relative-name file dominating-dir)))
+         (extra-dir (and extra-path
+                         (file-name-directory extra-path)))
+         (group (and extra-dir
+                     (replace-regexp-in-string "/"
+                                               "."
+                                               (directory-file-name extra-dir)))))
+    group))
+
+(defun yas--subdirs (directory &optional filep)
+  "Return subdirs or files of DIRECTORY according to FILEP."
+  (cl-remove-if (lambda (file)
+                  (or (string-match "\\`\\."
+                                    (file-name-nondirectory file))
+                      (string-match "\\`#.*#\\'"
+                                    (file-name-nondirectory file))
+                      (string-match "~\\'"
+                                    (file-name-nondirectory file))
+                      (if filep
+                          (file-directory-p file)
+                        (not (file-directory-p file)))))
+                (directory-files directory t)))
+
+(defun yas--make-menu-binding (template)
+  (let ((mode (yas--table-mode (yas--template-table template))))
+    `(lambda () (interactive) (yas--expand-or-visit-from-menu ',mode ,(yas--template-uuid template)))))
+
+(defun yas--expand-or-visit-from-menu (mode uuid)
+  (let* ((table (yas--table-get-create mode))
+         (yas--current-template (and table
+                                    (gethash uuid (yas--table-uuidhash table)))))
+    (when yas--current-template
+      (if yas-visit-from-menu
+          (yas--visit-snippet-file-1 yas--current-template)
+        (let ((where (if (region-active-p)
+                         (cons (region-beginning) (region-end))
+                       (cons (point) (point)))))
+          (yas-expand-snippet (yas--template-content yas--current-template)
+                              (car where)
+                              (cdr where)
+                              (yas--template-expand-env yas--current-template)))))))
+
+(defun yas--key-from-desc (text)
+  "Return a yasnippet key from a description string TEXT."
+  (replace-regexp-in-string "\\(\\w+\\).*" "\\1" text))
+
+
+;;; Popping up for keys and templates
+
+(defun yas--prompt-for-template (templates &optional prompt)
+  "Interactively choose a template from the list TEMPLATES.
+
+TEMPLATES is a list of `yas--template'.
+
+Optional PROMPT sets the prompt to use."
+  (when templates
+    (setq templates
+          (sort templates #'(lambda (t1 t2)
+                              (< (length (yas--template-name t1))
+                                 (length (yas--template-name t2))))))
+    (cl-some (lambda (fn)
+               (funcall fn (or prompt "Choose a snippet: ")
+                        templates
+                        #'yas--template-name))
+             yas-prompt-functions)))
+
+(defun yas--prompt-for-keys (keys &optional prompt)
+  "Interactively choose a template key from the list KEYS.
+
+Optional PROMPT sets the prompt to use."
+  (when keys
+    (cl-some (lambda (fn)
+               (funcall fn (or prompt "Choose a snippet key: ") keys))
+             yas-prompt-functions)))
+
+(defun yas--prompt-for-table (tables &optional prompt)
+  "Interactively choose a table from the list TABLES.
+
+Optional PROMPT sets the prompt to use."
+  (when tables
+    (cl-some (lambda (fn)
+               (funcall fn (or prompt "Choose a snippet table: ")
+                        tables
+                        #'yas--table-name))
+             yas-prompt-functions)))
+
+(defun yas-x-prompt (prompt choices &optional display-fn)
+  "Display choices in a x-window prompt."
+  (when (and window-system choices)
+    ;; Let window position be recalculated to ensure that
+    ;; `posn-at-point' returns non-nil.
+    (redisplay)
+    (or
+     (x-popup-menu
+      (if (fboundp 'posn-at-point)
+          (let ((x-y (posn-x-y (posn-at-point (point)))))
+            (list (list (+ (car x-y) 10)
+                        (+ (cdr x-y) 20))
+                  (selected-window)))
+        t)
+      `(,prompt ("title"
+                 ,@(cl-mapcar (lambda (c d) `(,(concat "   " d) . ,c))
+                              choices
+                              (if display-fn (mapcar display-fn choices)
+                                choices)))))
+     (keyboard-quit))))
+
+(defun yas-maybe-ido-prompt (prompt choices &optional display-fn)
+  (when (bound-and-true-p ido-mode)
+    (yas-ido-prompt prompt choices display-fn)))
+
+(defun yas-ido-prompt (prompt choices &optional display-fn)
+  (require 'ido)
+  (yas-completing-prompt prompt choices display-fn #'ido-completing-read))
+
+(defun yas-dropdown-prompt (_prompt choices &optional display-fn)
+  (when (fboundp 'dropdown-list)
+    (let* ((formatted-choices
+            (if display-fn (mapcar display-fn choices) choices))
+           (n (dropdown-list formatted-choices)))
+      (if n (nth n choices)
+        (keyboard-quit)))))
+
+(defun yas-completing-prompt (prompt choices &optional display-fn completion-fn)
+  (let* ((formatted-choices
+          (if display-fn (mapcar display-fn choices) choices))
+         (chosen (funcall (or completion-fn #'completing-read)
+                          prompt formatted-choices
+                          nil 'require-match nil nil)))
+    (if (eq choices formatted-choices)
+        chosen
+      (nth (or (cl-position chosen formatted-choices :test #'string=) 0)
+           choices))))
+
+(defun yas-no-prompt (_prompt choices &optional _display-fn)
+  (cl-first choices))
+
+
+;;; Defining snippets
+;; This consists of creating and registering `yas--template' objects in the
+;; correct tables.
+;;
+
+(defvar yas--creating-compiled-snippets nil)
+
+(defun yas--define-snippets-1 (snippet snippet-table)
+  "Helper for `yas-define-snippets'."
+  ;; Update the appropriate table.  Also takes care of adding the
+  ;; key indicators in the templates menu entry, if any.
+  (yas--update-template
+   snippet-table (apply #'yas--define-snippets-2 snippet-table snippet)))
+
+(defun yas-define-snippets (mode snippets)
+  "Define SNIPPETS for MODE.
+
+SNIPPETS is a list of snippet definitions, each taking the
+following form
+
+ (KEY TEMPLATE NAME CONDITION GROUP EXPAND-ENV LOAD-FILE KEYBINDING UUID SAVE-FILE)
+
+Within these, only KEY and TEMPLATE are actually mandatory.
+
+TEMPLATE might be a Lisp form or a string, depending on whether
+this is a snippet or a snippet-command.
+
+CONDITION, EXPAND-ENV and KEYBINDING are Lisp forms, they have
+been `yas--read-lisp'-ed and will eventually be
+`yas--eval-for-string'-ed.
+
+The remaining elements are strings.
+
+FILE is probably of very little use if you're programatically
+defining snippets.
+
+UUID is the snippet's \"unique-id\". Loading a second snippet
+file with the same uuid would replace the previous snippet.
+
+You can use `yas--parse-template' to return such lists based on
+the current buffers contents."
+  (if yas--creating-compiled-snippets
+      (let ((print-length nil))
+        (insert ";;; Snippet definitions:\n;;;\n")
+        (dolist (snippet snippets)
+          ;; Fill in missing elements with nil.
+          (setq snippet (append snippet (make-list (- 10 (length snippet)) nil)))
+          ;; Move LOAD-FILE to SAVE-FILE because we will load from the
+          ;; compiled file, not LOAD-FILE.
+          (let ((load-file (nth 6 snippet)))
+            (setcar (nthcdr 6 snippet) nil)
+            (setcar (nthcdr 9 snippet) load-file)))
+        (insert (pp-to-string
+                 `(yas-define-snippets ',mode ',snippets)))
+        (insert "\n\n"))
+    ;; Normal case.
+    (let ((snippet-table (yas--table-get-create mode))
+          (template nil))
+      (dolist (snippet snippets)
+        (setq template (yas--define-snippets-1 snippet
+                                               snippet-table)))
+      template)))
+
+
+;;; Loading snippets from files
+
+(defun yas--template-get-file (template)
+  "Return TEMPLATE's LOAD-FILE or SAVE-FILE."
+  (or (yas--template-load-file template)
+      (let ((file (yas--template-save-file template)))
+        (when file
+          (yas--message 3 "%s has no load file, using save file, %s, instead."
+                        (yas--template-name template) file))
+        file)))
+
+(defun yas--load-yas-setup-file (file)
+  (if (not yas--creating-compiled-snippets)
+      ;; Normal case.
+      (load file 'noerror (<= yas-verbosity 4))
+    (let ((elfile (concat file ".el")))
+      (when (file-exists-p elfile)
+        (insert ";;; contents of the .yas-setup.el support file:\n;;;\n")
+        (insert-file-contents elfile)
+        (goto-char (point-max))))))
+
+(defun yas--define-parents (mode parents)
+  "Add PARENTS to the list of MODE's parents."
+  (puthash mode (cl-remove-duplicates
+                 (append parents
+                         (gethash mode yas--parents)))
+           yas--parents))
+
+(defun yas-load-directory (top-level-dir &optional use-jit interactive)
+  "Load snippets in directory hierarchy TOP-LEVEL-DIR.
+
+Below TOP-LEVEL-DIR each directory should be a mode name.
+
+With prefix argument USE-JIT do jit-loading of snippets."
+  (interactive
+   (list (read-directory-name "Select the root directory: " nil nil t)
+         current-prefix-arg t))
+  (unless yas-snippet-dirs
+    (setq yas-snippet-dirs top-level-dir))
+  (let ((impatient-buffers))
+    (dolist (dir (yas--subdirs top-level-dir))
+      (let* ((major-mode-and-parents (yas--compute-major-mode-and-parents
+                                      (concat dir "/dummy")))
+             (mode-sym (car major-mode-and-parents))
+             (parents (cdr major-mode-and-parents)))
+        ;; Attention: The parents and the menus are already defined
+        ;; here, even if the snippets are later jit-loaded.
+        ;;
+        ;; * We need to know the parents at this point since entering a
+        ;;   given mode should jit load for its parents
+        ;;   immediately. This could be reviewed, the parents could be
+        ;;   discovered just-in-time-as well
+        ;;
+        ;; * We need to create the menus here to support the `full'
+        ;;   option to `yas-use-menu' (all known snippet menus are shown to the user)
+        ;;
+        (yas--define-parents mode-sym parents)
+        (yas--menu-keymap-get-create mode-sym)
+        (let ((fun (apply-partially #'yas--load-directory-1 dir mode-sym)))
+          (if use-jit
+              (yas--schedule-jit mode-sym fun)
+            (funcall fun)))
+        ;; Look for buffers that are already in `mode-sym', and so
+        ;; need the new snippets immediately...
+        ;;
+        (when use-jit
+          (cl-loop for buffer in (buffer-list)
+                   do (with-current-buffer buffer
+                        (when (eq major-mode mode-sym)
+                          (yas--message 4 "Discovered there was already %s in %s" buffer mode-sym)
+                          (push buffer impatient-buffers)))))))
+    ;; ...after TOP-LEVEL-DIR has been completely loaded, call
+    ;; `yas--load-pending-jits' in these impatient buffers.
+    ;;
+    (cl-loop for buffer in impatient-buffers
+             do (with-current-buffer buffer (yas--load-pending-jits))))
+  (when interactive
+    (yas--message 3 "Loaded snippets from %s." top-level-dir)))
+
+(defun yas--load-directory-1 (directory mode-sym)
+  "Recursively load snippet templates from DIRECTORY."
+  (if yas--creating-compiled-snippets
+      (let ((output-file (expand-file-name ".yas-compiled-snippets.el"
+                                           directory)))
+        (with-temp-file output-file
+          (insert (format ";;; Compiled snippets and support files for `%s'\n"
+                          mode-sym))
+          (yas--load-directory-2 directory mode-sym)
+          (insert (format ";;; Do not edit! File generated at %s\n"
+                          (current-time-string)))))
+    ;; Normal case.
+    (unless (file-exists-p (expand-file-name ".yas-skip" directory))
+      (unless (and (load (expand-file-name ".yas-compiled-snippets" directory) 'noerror (<= yas-verbosity 3))
+                   (progn (yas--message 4 "Loaded compiled snippets from %s" directory) t))
+        (yas--message 4 "Loading snippet files from %s" directory)
+        (yas--load-directory-2 directory mode-sym)))))
+
+(defun yas--load-directory-2 (directory mode-sym)
+  ;; Load .yas-setup.el files wherever we find them
+  ;;
+  (yas--load-yas-setup-file (expand-file-name ".yas-setup" directory))
+  (let* ((default-directory directory)
+         (snippet-defs nil))
+    ;; load the snippet files
+    ;;
+    (with-temp-buffer
+      (dolist (file (yas--subdirs directory 'no-subdirs-just-files))
+        (when (file-readable-p file)
+          ;; Erase the buffer instead of passing non-nil REPLACE to
+          ;; `insert-file-contents' (avoids Emacs bug #23659).
+          (erase-buffer)
+          (insert-file-contents file)
+          (push (yas--parse-template file)
+                snippet-defs))))
+    (when snippet-defs
+      (yas-define-snippets mode-sym
+                           snippet-defs))
+    ;; now recurse to a lower level
+    ;;
+    (dolist (subdir (yas--subdirs directory))
+      (yas--load-directory-2 subdir
+                            mode-sym))))
+
+(defun yas--load-snippet-dirs (&optional nojit)
+  "Reload the directories listed in `yas-snippet-dirs' or
+prompt the user to select one."
+  (let (errors)
+    (if (null yas-snippet-dirs)
+        (call-interactively 'yas-load-directory)
+      (when (member yas--default-user-snippets-dir yas-snippet-dirs)
+        (make-directory yas--default-user-snippets-dir t))
+      (dolist (directory (reverse (yas-snippet-dirs)))
+        (cond ((file-directory-p directory)
+               (yas-load-directory directory (not nojit))
+               (if nojit
+                   (yas--message 4 "Loaded %s" directory)
+                 (yas--message 4 "Prepared just-in-time loading for %s" directory)))
+              (t
+               (push (yas--message 1 "Check your `yas-snippet-dirs': %s is not a directory" directory) errors)))))
+    errors))
+
+(defun yas-reload-all (&optional no-jit interactive)
+  "Reload all snippets and rebuild the YASnippet menu.
+
+When NO-JIT is non-nil force immediate reload of all known
+snippets under `yas-snippet-dirs', otherwise use just-in-time
+loading.
+
+When called interactively, use just-in-time loading when given a
+prefix argument."
+  (interactive (list (not current-prefix-arg) t))
+  (catch 'abort
+    (let ((errors)
+          (snippet-editing-buffers
+           (cl-remove-if-not (lambda (buffer)
+                               (with-current-buffer buffer
+                                 yas--editing-template))
+                             (buffer-list))))
+      ;; Warn if there are buffers visiting snippets, since reloading will break
+      ;; any on-line editing of those buffers.
+      ;;
+      (when snippet-editing-buffers
+          (if interactive
+              (if (y-or-n-p "Some buffers editing live snippets, close them and proceed with reload? ")
+                  (mapc #'kill-buffer snippet-editing-buffers)
+                (yas--message 1 "Aborted reload...")
+                (throw 'abort nil))
+            ;; in a non-interactive use, at least set
+            ;; `yas--editing-template' to nil, make it guess it next time around
+            (mapc #'(lambda (buffer)
+                      (with-current-buffer buffer
+                        (kill-local-variable 'yas--editing-template)))
+                  (buffer-list))))
+
+      ;; Empty all snippet tables and parenting info
+      ;;
+      (setq yas--tables (make-hash-table))
+      (setq yas--parents (make-hash-table))
+
+      ;; Before killing `yas--menu-table' use its keys to cleanup the
+      ;; mode menu parts of `yas--minor-mode-menu' (thus also cleaning
+      ;; up `yas-minor-mode-map', which points to it)
+      ;;
+      (maphash #'(lambda (menu-symbol _keymap)
+                   (define-key yas--minor-mode-menu (vector menu-symbol) nil))
+               yas--menu-table)
+      ;; Now empty `yas--menu-table' as well
+      (setq yas--menu-table (make-hash-table))
+
+      ;; Cancel all pending 'yas--scheduled-jit-loads'
+      ;;
+      (setq yas--scheduled-jit-loads (make-hash-table))
+
+      ;; Reload the directories listed in `yas-snippet-dirs' or prompt
+      ;; the user to select one.
+      ;;
+      (setq errors (yas--load-snippet-dirs no-jit))
+      ;; Reload the direct keybindings
+      ;;
+      (yas-direct-keymaps-reload)
+
+      (run-hooks 'yas-after-reload-hook)
+      (let ((no-snippets
+             (cl-every (lambda (table) (= (hash-table-count table) 0))
+                       (list yas--scheduled-jit-loads
+                             yas--parents yas--tables))))
+        (yas--message (if (or no-snippets errors) 2 3)
+                      (if no-jit "Snippets loaded %s."
+                        "Prepared just-in-time loading of snippets %s.")
+                      (cond (errors
+                             "with some errors.  Check *Messages*")
+                            (no-snippets
+                             "(but no snippets found)")
+                            (t
+                             "successfully")))))))
+
+(defvar yas-after-reload-hook nil
+  "Hooks run after `yas-reload-all'.")
+
+(defun yas--load-pending-jits ()
+  (dolist (mode (yas--modes-to-activate))
+    (let ((funs (reverse (gethash mode yas--scheduled-jit-loads))))
+      ;; must reverse to maintain coherence with `yas-snippet-dirs'
+      (dolist (fun funs)
+        (yas--message 4 "Loading for `%s', just-in-time: %s!" mode fun)
+        (funcall fun))
+      (remhash mode yas--scheduled-jit-loads))))
+
+(defun yas-escape-text (text)
+  "Escape TEXT for snippet."
+  (when text
+    (replace-regexp-in-string "[\\$]" "\\\\\\&" text)))
+
+
+;;; Snippet compilation function
+
+(defun yas-compile-directory (top-level-dir)
+  "Create .yas-compiled-snippets.el files under subdirs of TOP-LEVEL-DIR.
+
+This works by stubbing a few functions, then calling
+`yas-load-directory'."
+  (interactive "DTop level snippet directory?")
+  (let ((yas--creating-compiled-snippets t))
+    (yas-load-directory top-level-dir nil)))
+
+(defun yas-recompile-all ()
+  "Compile every dir in `yas-snippet-dirs'."
+  (interactive)
+  (mapc #'yas-compile-directory (yas-snippet-dirs)))
+
+
+;;; JIT loading
+;;;
+
+(defvar yas--scheduled-jit-loads (make-hash-table)
+  "Alist of mode-symbols to forms to be evaled when `yas-minor-mode' kicks in.")
+
+(defun yas--schedule-jit (mode fun)
+  (push fun (gethash mode yas--scheduled-jit-loads)))
+
+
+
+;;; Some user level functions
+
+(defun yas-about ()
+  (interactive)
+  (message "yasnippet (version %s) -- pluskid/joaotavora/npostavs"
+           (or (ignore-errors (car (let ((default-directory yas--loaddir))
+                                     (process-lines "git" "describe"
+                                                    "--tags" "--dirty"))))
+               (when (and (featurep 'package)
+                          (fboundp 'package-desc-version)
+                          (fboundp 'package-version-join))
+                 (defvar package-alist)
+                 (ignore-errors
+                   (let* ((yas-pkg (cdr (assq 'yasnippet package-alist)))
+                          (version (package-version-join
+                                    (package-desc-version (car yas-pkg)))))
+                     ;; Special case for MELPA's bogus version numbers.
+                     (if (string-match "\\`20..[01][0-9][0-3][0-9][.][0-9]\\{3,4\\}\\'"
+                                       version)
+                         (concat yas--version "-snapshot" version)
+                       version))))
+               yas--version)))
+
+
+;;; Apropos snippet menu:
+;;
+;; The snippet menu keymaps are stored by mode in hash table called
+;; `yas--menu-table'. They are linked to the main menu in
+;; `yas--menu-keymap-get-create' and are initially created empty,
+;; reflecting the table hierarchy.
+;;
+;; They can be populated in two mutually exclusive ways: (1) by
+;; reading `yas--template-group', which in turn is populated by the "#
+;; group:" directives of the snippets or the ".yas-make-groups" file
+;; or (2) by using a separate `yas-define-menu' call, which declares a
+;; menu structure based on snippets uuids.
+;;
+;; Both situations are handled in `yas--update-template-menu', which
+;; uses the predicate `yas--template-menu-managed-by-yas-define-menu'
+;; that can tell between the two situations.
+;;
+;; Note:
+;;
+;; * if `yas-define-menu' is used it must run before
+;;   `yas-define-snippets' and the UUIDS must match, otherwise we get
+;;   duplicate entries. The `yas--template' objects are created in
+;;   `yas-define-menu', holding nothing but the menu entry,
+;;   represented by a pair of ((menu-item NAME :keys KEYS) TYPE) and
+;;   stored in `yas--template-menu-binding-pair'.  The (menu-item ...)
+;;   part is then stored in the menu keymap itself which make the item
+;;   appear to the user.  These limitations could probably be revised.
+;;
+;; * The `yas--template-perm-group' slot is only used in
+;;   `yas-describe-tables'.
+;;
+(defun yas--template-menu-binding-pair-get-create (template &optional type)
+  "Get TEMPLATE's menu binding or assign it a new one.
+
+TYPE may be `:stay', signaling this menu binding should be
+static in the menu."
+  (or (yas--template-menu-binding-pair template)
+      (let (;; (key (yas--template-key template))
+            ;; (keybinding (yas--template-keybinding template))
+            )
+        (setf (yas--template-menu-binding-pair template)
+              (cons `(menu-item ,(or (yas--template-name template)
+                                     (yas--template-uuid template))
+                                ,(yas--make-menu-binding template)
+                                :keys ,nil)
+                    type)))))
+(defun yas--template-menu-managed-by-yas-define-menu (template)
+  "Non-nil if TEMPLATE's menu entry was included in a `yas-define-menu' call."
+  (cdr (yas--template-menu-binding-pair template)))
+
+
+(defun yas--show-menu-p (mode)
+  (cond ((eq yas-use-menu 'abbreviate)
+         (cl-find mode
+                  (mapcar #'yas--table-mode
+                          (yas--get-snippet-tables))))
+        (yas-use-menu t)))
+
+(defun yas--delete-from-keymap (keymap uuid)
+  "Recursively delete items with UUID from KEYMAP and its submenus."
+
+  ;; XXX: This used to skip any submenus named \"parent mode\"
+  ;;
+  ;; First of all, recursively enter submenus, i.e. the tree is
+  ;; searched depth first so that stale submenus can be found in the
+  ;; higher passes.
+  ;;
+  (mapc #'(lambda (item)
+            (when (and (consp (cdr-safe item))
+                       (keymapp (nth 2 (cdr item))))
+              (yas--delete-from-keymap (nth 2 (cdr item)) uuid)))
+        (cdr keymap))
+  ;; Set the uuid entry to nil
+  ;;
+  (define-key keymap (vector (make-symbol uuid)) nil)
+  ;; Destructively modify keymap
+  ;;
+  (setcdr keymap (cl-delete-if (lambda (item)
+                                 (cond ((not (listp item)) nil)
+                                       ((null (cdr item)))
+                                       ((and (keymapp (nth 2 (cdr item)))
+                                             (null (cdr (nth 2 (cdr item))))))))
+                               (cdr keymap))))
+
+(defun yas-define-menu (mode menu &optional omit-items)
+  "Define a snippet menu for MODE according to MENU, omitting OMIT-ITEMS.
+
+MENU is a list, its elements can be:
+
+- (yas-item UUID) : Creates an entry the snippet identified with
+  UUID.  The menu entry for a snippet thus identified is
+  permanent, i.e. it will never move (be reordered) in the menu.
+
+- (yas-separator) : Creates a separator
+
+- (yas-submenu NAME SUBMENU) : Creates a submenu with NAME,
+  SUBMENU has the same form as MENU.  NAME is also added to the
+  list of groups of the snippets defined thereafter.
+
+OMIT-ITEMS is a list of snippet uuids that will always be
+omitted from MODE's menu, even if they're manually loaded."
+  (let* ((table (yas--table-get-create mode))
+         (hash (yas--table-uuidhash table)))
+    (yas--define-menu-1 table
+                        (yas--menu-keymap-get-create mode)
+                        menu
+                        hash)
+    (dolist (uuid omit-items)
+      (let ((template (or (gethash uuid hash)
+                          (puthash uuid
+                                   (yas--make-template :table table
+                                                       :uuid uuid)
+                                   hash))))
+        (setf (yas--template-menu-binding-pair template) (cons nil :none))))))
+
+(defun yas--define-menu-1 (table menu-keymap menu uuidhash &optional group-list)
+  "Helper for `yas-define-menu'."
+  (cl-loop
+   for (type name submenu) in (reverse menu)
+   collect (cond
+            ((or (eq type 'yas-item)
+                 (and yas-alias-to-yas/prefix-p
+                      (eq type 'yas/item)))
+             (let ((template (or (gethash name uuidhash)
+                                 (puthash name
+                                          (yas--make-template
+                                           :table table
+                                           :perm-group group-list
+                                           :uuid name)
+                                          uuidhash))))
+               (car (yas--template-menu-binding-pair-get-create
+                     template :stay))))
+            ((or (eq type 'yas-submenu)
+                 (and yas-alias-to-yas/prefix-p
+                      (eq type 'yas/submenu)))
+             (let ((subkeymap (make-sparse-keymap)))
+               (yas--define-menu-1 table subkeymap submenu uuidhash
+                                   (append group-list (list name)))
+               `(menu-item ,name ,subkeymap)))
+            ((or (eq type 'yas-separator)
+                 (and yas-alias-to-yas/prefix-p
+                      (eq type 'yas/separator)))
+             '(menu-item "----"))
+            (t (yas--message 1 "Don't know anything about menu entry %s" type)
+               nil))
+   into menu-entries
+   finally do (push (apply #'vector menu-entries) (cdr menu-keymap))))
+
+(defun yas--define (mode key template &optional name condition group)
+  "Define a snippet.  Expanding KEY into TEMPLATE.
+
+NAME is a description to this template.  Also update the menu if
+`yas-use-menu' is t.  CONDITION is the condition attached to
+this snippet.  If you attach a condition to a snippet, then it
+will only be expanded when the condition evaluated to non-nil."
+  (yas-define-snippets mode
+                       (list (list key template name condition group))))
+
+(defun yas-hippie-try-expand (first-time?)
+  "Integrate with hippie expand.
+
+Just put this function in `hippie-expand-try-functions-list'."
+  (when yas-minor-mode
+    (if (not first-time?)
+        (let ((yas-fallback-behavior 'return-nil))
+          (yas-expand))
+      (undo 1)
+      nil)))
+
+
+;;; Apropos condition-cache:
+;;;
+;;;
+;;;
+;;;
+(defmacro yas-define-condition-cache (func doc &rest body)
+  "Define a function FUNC with doc DOC and body BODY.
+BODY is executed at most once every snippet expansion attempt, to check
+expansion conditions.
+
+It doesn't make any sense to call FUNC programatically."
+  `(defun ,func () ,(if (and doc
+                             (stringp doc))
+                        (concat doc
+"\n\nFor use in snippets' conditions. Within each
+snippet-expansion routine like `yas-expand', computes actual
+value for the first time then always returns a cached value.")
+                      (setq body (cons doc body))
+                      nil)
+     (let ((timestamp-and-value (get ',func 'yas--condition-cache)))
+       (if (equal (car timestamp-and-value) yas--condition-cache-timestamp)
+           (cdr timestamp-and-value)
+         (let ((new-value (progn
+                            ,@body
+                            )))
+           (put ',func 'yas--condition-cache (cons yas--condition-cache-timestamp new-value))
+           new-value)))))
+
+(defalias 'yas-expand 'yas-expand-from-trigger-key)
+(defun yas-expand-from-trigger-key (&optional field)
+  "Expand a snippet before point.
+
+If no snippet expansion is possible, fall back to the behaviour
+defined in `yas-fallback-behavior'.
+
+Optional argument FIELD is for non-interactive use and is an
+object satisfying `yas--field-p' to restrict the expansion to."
+  (interactive)
+  (setq yas--condition-cache-timestamp (current-time))
+  (let (templates-and-pos)
+    (unless (and yas-expand-only-for-last-commands
+                 (not (member last-command yas-expand-only-for-last-commands)))
+      (setq templates-and-pos (if field
+                                  (save-restriction
+                                    (narrow-to-region (yas--field-start field)
+                                                      (yas--field-end field))
+                                    (yas--templates-for-key-at-point))
+                                (yas--templates-for-key-at-point))))
+    (if templates-and-pos
+        (yas--expand-or-prompt-for-template
+         (nth 0 templates-and-pos)
+         ;; Delete snippet key and active region when expanding.
+         (min (if (use-region-p) (region-beginning) most-positive-fixnum)
+              (nth 1 templates-and-pos))
+         (max (if (use-region-p) (region-end) most-negative-fixnum)
+              (nth 2 templates-and-pos)))
+      (yas--fallback))))
+
+(defun yas--maybe-expand-from-keymap-filter (cmd)
+  (let* ((yas--condition-cache-timestamp (current-time))
+         (vec (cl-subseq (this-command-keys-vector)
+                         (if current-prefix-arg
+                             (length (this-command-keys))
+                           0)))
+         (templates (cl-mapcan (lambda (table)
+                                 (yas--fetch table vec))
+                               (yas--get-snippet-tables))))
+    (if templates (or cmd templates))))
+
+(defun yas-expand-from-keymap ()
+  "Directly expand some snippets, searching `yas--direct-keymaps'."
+  (interactive)
+  (setq yas--condition-cache-timestamp (current-time))
+  (let* ((templates (yas--maybe-expand-from-keymap-filter nil)))
+    (when templates
+      (yas--expand-or-prompt-for-template templates))))
+
+(defun yas--expand-or-prompt-for-template (templates &optional start end)
+  "Expand one of TEMPLATES from START to END.
+
+Prompt the user if TEMPLATES has more than one element, else
+expand immediately.  Common gateway for
+`yas-expand-from-trigger-key' and `yas-expand-from-keymap'."
+  (let ((yas--current-template (or (and (cl-rest templates) ;; more than one
+                                        (yas--prompt-for-template (mapcar #'cdr templates)))
+                                   (cdar templates))))
+    (when yas--current-template
+      (yas-expand-snippet (yas--template-content yas--current-template)
+                          start
+                          end
+                          (yas--template-expand-env yas--current-template)))))
+
+;; Apropos the trigger key and the fallback binding:
+;;
+;; When `yas-minor-mode-map' binds <tab>, that correctly overrides
+;; org-mode's <tab>, for example and searching for fallbacks correctly
+;; returns `org-cycle'. However, most other modes bind "TAB". TODO,
+;; improve this explanation.
+;;
+(defun yas--fallback ()
+  "Fallback after expansion has failed.
+
+Common gateway for `yas-expand-from-trigger-key' and
+`yas-expand-from-keymap'."
+  (cond ((eq yas-fallback-behavior 'return-nil)
+         ;; return nil
+         nil)
+        ((eq yas-fallback-behavior 'yas--fallback)
+         (error (concat "yasnippet fallback loop!\n"
+                        "This can happen when you bind `yas-expand' "
+                        "outside of the `yas-minor-mode-map'.")))
+        ((eq yas-fallback-behavior 'call-other-command)
+         (let* ((yas-fallback-behavior 'yas--fallback)
+                ;; Also bind `yas-minor-mode' to prevent fallback
+                ;; loops when other extensions use mechanisms similar
+                ;; to `yas--keybinding-beyond-yasnippet'. (github #525
+                ;; and #526)
+                ;;
+                (yas-minor-mode nil)
+                (beyond-yasnippet (yas--keybinding-beyond-yasnippet)))
+           (yas--message 4 "Falling back to %s"  beyond-yasnippet)
+           (cl-assert (or (null beyond-yasnippet) (commandp beyond-yasnippet)))
+           (setq this-command beyond-yasnippet)
+           (when beyond-yasnippet
+             (call-interactively beyond-yasnippet))))
+        ((and (listp yas-fallback-behavior)
+              (cdr yas-fallback-behavior)
+              (eq 'apply (car yas-fallback-behavior)))
+         (let ((command-or-fn (cadr yas-fallback-behavior))
+               (args (cddr yas-fallback-behavior))
+               (yas-fallback-behavior 'yas--fallback)
+               (yas-minor-mode nil))
+           (if args
+               (apply command-or-fn args)
+             (when (commandp command-or-fn)
+               (setq this-command command-or-fn)
+               (call-interactively command-or-fn)))))
+        (t
+         ;; also return nil if all the other fallbacks have failed
+         nil)))
+
+(defun yas--keybinding-beyond-yasnippet ()
+  "Get current keys's binding as if YASsnippet didn't exist."
+  (let* ((yas-minor-mode nil)
+         (yas--direct-keymaps nil)
+         (keys (this-single-command-keys)))
+    (or (key-binding keys t)
+        (key-binding (yas--fallback-translate-input keys) t))))
+
+(defun yas--fallback-translate-input (keys)
+  "Emulate `read-key-sequence', at least what I think it does.
+
+Keys should be an untranslated key vector.  Returns a translated
+vector of keys.  FIXME not thoroughly tested."
+  (let ((retval [])
+        (i 0))
+    (while (< i (length keys))
+      (let ((j i)
+            (translated local-function-key-map))
+        (while (and (< j (length keys))
+                    translated
+                    (keymapp translated))
+          (setq translated (cdr (assoc (aref keys j) (remove 'keymap translated)))
+                j (1+ j)))
+        (setq retval (vconcat retval (cond ((symbolp translated)
+                                            `[,translated])
+                                           ((vectorp translated)
+                                            translated)
+                                           (t
+                                            (substring keys i j)))))
+        (setq i j)))
+    retval))
+
+
+;;; Utils for snippet development:
+
+(defun yas--all-templates (tables)
+  "Get `yas--template' objects in TABLES, applicable for buffer and point.
+
+Honours `yas-choose-tables-first', `yas-choose-keys-first' and
+`yas-buffer-local-condition'"
+  (when yas-choose-tables-first
+    (setq tables (list (yas--prompt-for-table tables))))
+  (mapcar #'cdr
+          (if yas-choose-keys-first
+              (let ((key (yas--prompt-for-keys
+                          (cl-mapcan #'yas--table-all-keys tables))))
+                (when key
+                  (cl-mapcan (lambda (table)
+                               (yas--fetch table key))
+                             tables)))
+            (cl-remove-duplicates (cl-mapcan #'yas--table-templates tables)
+                                  :test #'equal))))
+
+(defun yas--lookup-snippet-1 (name mode)
+  "Get the snippet called NAME in MODE's tables."
+  (let ((yas-choose-tables-first nil)   ; avoid prompts
+        (yas-choose-keys-first nil))
+    (cl-find name (yas--all-templates
+                   (yas--get-snippet-tables mode))
+             :key #'yas--template-name :test #'string=)))
+
+(defun yas-lookup-snippet (name &optional mode noerror)
+  "Get the snippet named NAME in MODE's tables.
+
+MODE defaults to the current buffer's `major-mode'.  If NOERROR
+is non-nil, then don't signal an error if there isn't any snippet
+called NAME.
+
+Honours `yas-buffer-local-condition'."
+  (cond
+   ((yas--lookup-snippet-1 name mode))
+   (noerror nil)
+   (t (error "No snippet named: %s" name))))
+
+(defun yas-insert-snippet (&optional no-condition)
+  "Choose a snippet to expand, pop-up a list of choices according
+to `yas-prompt-functions'.
+
+With prefix argument NO-CONDITION, bypass filtering of snippets
+by condition."
+  (interactive "P")
+  (setq yas--condition-cache-timestamp (current-time))
+  (let* ((yas-buffer-local-condition (or (and no-condition
+                                              'always)
+                                         yas-buffer-local-condition))
+         (templates (yas--all-templates (yas--get-snippet-tables)))
+         (yas--current-template (and templates
+                                    (or (and (cl-rest templates) ;; more than one template for same key
+                                             (yas--prompt-for-template templates))
+                                        (car templates))))
+         (where (if (region-active-p)
+                    (cons (region-beginning) (region-end))
+                  (cons (point) (point)))))
+    (if yas--current-template
+        (yas-expand-snippet (yas--template-content yas--current-template)
+                            (car where)
+                            (cdr where)
+                            (yas--template-expand-env yas--current-template))
+      (yas--message 1 "No snippets can be inserted here!"))))
+
+(defun yas-visit-snippet-file ()
+  "Choose a snippet to edit, selection like `yas-insert-snippet'.
+
+Only success if selected snippet was loaded from a file.  Put the
+visited file in `snippet-mode'."
+  (interactive)
+  (let* ((yas-buffer-local-condition 'always)
+         (templates (yas--all-templates (yas--get-snippet-tables)))
+         (template (and templates
+                        (or (yas--prompt-for-template templates
+                                                     "Choose a snippet template to edit: ")
+                            (car templates)))))
+
+    (if template
+        (yas--visit-snippet-file-1 template)
+      (message "No snippets tables active!"))))
+
+(defun yas--visit-snippet-file-1 (template)
+  "Helper for `yas-visit-snippet-file'."
+  (let ((file (yas--template-get-file template)))
+    (cond ((and file (file-readable-p file))
+           (find-file-other-window file)
+           (snippet-mode)
+           (set (make-local-variable 'yas--editing-template) template))
+          (file
+           (message "Original file %s no longer exists!" file))
+          (t
+           (switch-to-buffer (format "*%s*"(yas--template-name template)))
+           (let ((type 'snippet))
+             (when (listp (yas--template-content template))
+               (insert (format "# type: command\n"))
+               (setq type 'command))
+             (insert (format "# key: %s\n" (yas--template-key template)))
+             (insert (format "# name: %s\n" (yas--template-name template)))
+             (when (yas--template-keybinding template)
+               (insert (format "# binding: %s\n" (yas--template-keybinding template))))
+             (when (yas--template-expand-env template)
+               (insert (format "# expand-env: %s\n" (yas--template-expand-env template))))
+             (when (yas--template-condition template)
+               (insert (format "# condition: %s\n" (yas--template-condition template))))
+             (insert "# --\n")
+             (insert (if (eq type 'command)
+                         (pp-to-string (yas--template-content template))
+                       (yas--template-content template))))
+           (snippet-mode)
+           (set (make-local-variable 'yas--editing-template) template)
+           (set (make-local-variable 'default-directory)
+                (car (cdr (car (yas--guess-snippet-directories (yas--template-table template))))))))))
+
+(defun yas--guess-snippet-directories-1 (table)
+  "Guess possible snippet subdirectories for TABLE."
+  (cons (file-name-as-directory (yas--table-name table))
+        (cl-mapcan #'yas--guess-snippet-directories-1
+                   (yas--table-parents table))))
+
+(defun yas--guess-snippet-directories (&optional table)
+  "Try to guess suitable directories based on the current active
+tables (or optional TABLE).
+
+Returns a list of elements (TABLE . DIRS) where TABLE is a
+`yas--table' object and DIRS is a list of all possible directories
+where snippets of table might exist."
+  (let ((main-dir (car (or (yas-snippet-dirs)
+                           (setq yas-snippet-dirs
+                                 (list yas--default-user-snippets-dir)))))
+        (tables (if table (list table)
+                  (yas--get-snippet-tables))))
+    ;; HACK! the snippet table created here is actually registered!
+    (unless table
+      ;; The major mode is probably the best guess, put it first.
+      (let ((major-mode-table (yas--table-get-create major-mode)))
+        (cl-callf2 delq major-mode-table tables)
+        (push major-mode-table tables)))
+
+    (mapcar #'(lambda (table)
+                (cons table
+                      (mapcar #'(lambda (subdir)
+                                  (expand-file-name subdir main-dir))
+                              (yas--guess-snippet-directories-1 table))))
+            tables)))
+
+(defun yas--make-directory-maybe (table-and-dirs &optional main-table-string)
+  "Return a dir inside TABLE-AND-DIRS, prompts for creation if none exists."
+  (or (cl-some (lambda (dir) (when (file-directory-p dir) dir))
+               (cdr table-and-dirs))
+      (let ((candidate (cl-first (cdr table-and-dirs))))
+        (unless (file-writable-p (file-name-directory candidate))
+          (error (yas--format "%s is not writable." candidate)))
+        (if (y-or-n-p (format "Guessed directory (%s) for%s%s table \"%s\" does not exist! Create? "
+                              candidate
+                              (if (gethash (yas--table-mode (car table-and-dirs))
+                                           yas--tables)
+                                  ""
+                                " brand new")
+                              (or main-table-string
+                                  "")
+                              (yas--table-name (car table-and-dirs))))
+            (progn
+              (make-directory candidate 'also-make-parents)
+              ;; create the .yas-parents file here...
+              candidate)))))
+
+;; NOTE: Using the traditional "*new snippet*" stops whitespace mode
+;; from activating (it doesn't like the leading "*").
+(defconst yas-new-snippet-buffer-name "+new-snippet+")
+
+(defun yas-new-snippet (&optional no-template)
+  "Pops a new buffer for writing a snippet.
+
+Expands a snippet-writing snippet, unless the optional prefix arg
+NO-TEMPLATE is non-nil."
+  (interactive "P")
+  (let ((guessed-directories (yas--guess-snippet-directories))
+        (yas-selected-text (or yas-selected-text
+                               (and (region-active-p)
+                                    (buffer-substring-no-properties
+                                     (region-beginning) (region-end))))))
+
+    (switch-to-buffer yas-new-snippet-buffer-name)
+    (erase-buffer)
+    (kill-all-local-variables)
+    (snippet-mode)
+    (yas-minor-mode 1)
+    (set (make-local-variable 'yas--guessed-modes)
+         (mapcar (lambda (d) (yas--table-mode (car d)))
+                 guessed-directories))
+    (set (make-local-variable 'default-directory)
+         (car (cdr (car guessed-directories))))
+    (if (and (not no-template) yas-new-snippet-default)
+        (yas-expand-snippet yas-new-snippet-default))))
+
+(defun yas--compute-major-mode-and-parents (file)
+  "Given FILE, find the nearest snippet directory for a given mode.
+
+Returns a list (MODE-SYM PARENTS), the mode's symbol and a list
+representing one or more of the mode's parents.
+
+Note that MODE-SYM need not be the symbol of a real major mode,
+neither do the elements of PARENTS."
+  (let* ((file-dir (and file
+                        (directory-file-name
+                         (or (cl-some (lambda (special)
+                                        (locate-dominating-file file special))
+                                      '(".yas-setup.el"
+                                        ".yas-make-groups"
+                                        ".yas-parents"))
+                             (directory-file-name (file-name-directory file))))))
+         (parents-file-name (concat file-dir "/.yas-parents"))
+         (major-mode-name (and file-dir
+                               (file-name-nondirectory file-dir)))
+         (major-mode-sym (or (and major-mode-name
+                                  (intern major-mode-name))))
+         (parents (when (file-readable-p parents-file-name)
+                         (mapcar #'intern
+                                 (split-string
+                                  (with-temp-buffer
+                                    (insert-file-contents parents-file-name)
+                                    (buffer-substring-no-properties (point-min)
+                                                                    (point-max))))))))
+    (when major-mode-sym
+      (cons major-mode-sym (remove major-mode-sym parents)))))
+
+(defvar yas--editing-template nil
+  "Supporting variable for `yas-load-snippet-buffer' and `yas--visit-snippet'.")
+
+(defvar yas--current-template nil
+  "Holds the current template being expanded into a snippet.")
+
+(defvar yas--guessed-modes nil
+  "List of guessed modes supporting `yas-load-snippet-buffer'.")
+
+(defun yas--read-table ()
+  "Ask user for a snippet table, help with some guessing."
+  (let ((prompt (if (and (featurep 'ido)
+                         ido-mode)
+                    'ido-completing-read 'completing-read)))
+    (unless yas--guessed-modes
+      (set (make-local-variable 'yas--guessed-modes)
+           (or (yas--compute-major-mode-and-parents buffer-file-name))))
+    (intern
+     (funcall prompt (format "Choose or enter a table (yas guesses %s): "
+                             (if yas--guessed-modes
+                                 (cl-first yas--guessed-modes)
+                               "nothing"))
+              (mapcar #'symbol-name yas--guessed-modes)
+              nil
+              nil
+              nil
+              nil
+              (if (cl-first yas--guessed-modes)
+                  (symbol-name (cl-first yas--guessed-modes)))))))
+
+(defun yas-load-snippet-buffer (table &optional interactive)
+  "Parse and load current buffer's snippet definition into TABLE.
+TABLE is a symbol name passed to `yas--table-get-create'.  When
+called interactively, prompt for the table name.
+Return the `yas--template' object created"
+  (interactive (list (yas--read-table) t))
+  (cond
+   ;;  We have `yas--editing-template', this buffer's content comes from a
+   ;;  template which is already loaded and neatly positioned,...
+   ;;
+   (yas--editing-template
+    (yas--define-snippets-1 (yas--parse-template (yas--template-load-file yas--editing-template))
+                           (yas--template-table yas--editing-template)))
+   ;; Try to use `yas--guessed-modes'. If we don't have that use the
+   ;; value from `yas--compute-major-mode-and-parents'
+   ;;
+   (t
+    (unless yas--guessed-modes
+      (set (make-local-variable 'yas--guessed-modes) (or (yas--compute-major-mode-and-parents buffer-file-name))))
+    (let* ((table (yas--table-get-create table)))
+      (set (make-local-variable 'yas--editing-template)
+           (yas--define-snippets-1 (yas--parse-template buffer-file-name)
+                                  table)))))
+  (when interactive
+    (yas--message 3 "Snippet \"%s\" loaded for %s."
+                  (yas--template-name yas--editing-template)
+                  (yas--table-name (yas--template-table yas--editing-template))))
+  yas--editing-template)
+
+(defun yas-maybe-load-snippet-buffer ()
+  "Added to `after-save-hook' in `snippet-mode'."
+  (let* ((mode (intern (file-name-sans-extension
+                        (file-name-nondirectory
+                         (directory-file-name default-directory)))))
+         (current-snippet
+          (apply #'yas--define-snippets-2 (yas--table-get-create mode)
+                 (yas--parse-template buffer-file-name)))
+         (uuid (yas--template-uuid current-snippet)))
+    (unless (equal current-snippet
+                   (if uuid (yas--get-template-by-uuid mode uuid)
+                     (yas--lookup-snippet-1
+                      (yas--template-name current-snippet) mode)))
+      (yas-load-snippet-buffer mode t))))
+
+(defun yas-load-snippet-buffer-and-close (table &optional kill)
+  "Load and save the snippet, then `quit-window' if saved.
+Loading is performed by `yas-load-snippet-buffer'.  If the
+snippet is new, ask the user whether (and where) to save it.  If
+the snippet already has a file, just save it.
+
+The prefix argument KILL is passed to `quit-window'.
+
+Don't use this from a Lisp program, call `yas-load-snippet-buffer'
+and `kill-buffer' instead."
+  (interactive (list (yas--read-table) current-prefix-arg))
+  (let ((template (yas-load-snippet-buffer table t)))
+    (when (and (buffer-modified-p)
+               (y-or-n-p
+                (format "[yas] Loaded for %s. Also save snippet buffer?"
+                        (yas--table-name (yas--template-table template)))))
+      (let ((default-directory (car (cdr (car (yas--guess-snippet-directories
+                                               (yas--template-table template))))))
+            (default-file-name (yas--template-name template)))
+        (unless (or buffer-file-name (not default-file-name))
+          (setq buffer-file-name
+                (read-file-name "File to save snippet in: "
+                                nil nil nil default-file-name))
+          (rename-buffer (file-name-nondirectory buffer-file-name) t))
+        (save-buffer)))
+    (quit-window kill)))
+
+(declare-function yas-debug-snippets "yasnippet-debug")
+
+(defun yas-tryout-snippet (&optional debug)
+  "Test current buffer's snippet template in other buffer.
+DEBUG is for debugging the YASnippet engine itself."
+  (interactive "P")
+  (let* ((major-mode-and-parent (yas--compute-major-mode-and-parents buffer-file-name))
+         (parsed (yas--parse-template))
+         (test-mode (or (and (car major-mode-and-parent)
+                             (fboundp (car major-mode-and-parent))
+                             (car major-mode-and-parent))
+                        (cl-first yas--guessed-modes)
+                        (intern (read-from-minibuffer (yas--format "Please input a mode: ")))))
+         (yas--current-template
+          (and parsed
+               (fboundp test-mode)
+               (yas--make-template :table       nil ;; no tables for ephemeral snippets
+                                   :key         (nth 0 parsed)
+                                   :content     (nth 1 parsed)
+                                   :name        (nth 2 parsed)
+                                   :expand-env  (nth 5 parsed)))))
+    (cond (yas--current-template
+           (let ((buffer-name (format "*testing snippet: %s*" (yas--template-name yas--current-template))))
+             (kill-buffer (get-buffer-create buffer-name))
+             (switch-to-buffer (get-buffer-create buffer-name))
+             (setq buffer-undo-list nil)
+             (condition-case nil (funcall test-mode) (error nil))
+	     (yas-minor-mode 1)
+             (setq buffer-read-only nil)
+             (yas-expand-snippet (yas--template-content yas--current-template)
+                                 (point-min)
+                                 (point-max)
+                                 (yas--template-expand-env yas--current-template))
+             (when (and debug
+                        (require 'yasnippet-debug nil t))
+               (yas-debug-snippets "*YASnippet trace*" 'snippet-navigation)
+               (display-buffer "*YASnippet trace*"))))
+          (t
+           (yas--message 1 "Cannot test snippet for unknown major mode")))))
+
+(defun yas-active-keys ()
+  "Return all active trigger keys for current buffer and point."
+  (cl-remove-duplicates
+   (cl-remove-if-not #'stringp (cl-mapcan #'yas--table-all-keys
+                                          (yas--get-snippet-tables)))
+   :test #'string=))
+
+(defun yas--template-fine-group (template)
+  (car (last (or (yas--template-group template)
+                 (yas--template-perm-group template)))))
+
+(defun yas-describe-table-by-namehash ()
+  "Display snippet tables by NAMEHASH."
+  (interactive)
+  (with-current-buffer (get-buffer-create "*YASnippet Tables by NAMEHASH*")
+    (let ((inhibit-read-only t))
+      (erase-buffer)
+      (insert "YASnippet tables by NAMEHASH: \n")
+      (maphash
+       (lambda (_mode table)
+         (insert (format "\nSnippet table `%s':\n\n" (yas--table-name table)))
+         (maphash
+          (lambda (key _v)
+            (insert (format "   key %s maps snippets: %s\n" key
+                            (let ((names))
+                              (maphash #'(lambda (k _v)
+                                           (push k names))
+                                       (gethash key (yas--table-hash table)))
+                              names))))
+          (yas--table-hash table)))
+       yas--tables))
+    (view-mode +1)
+    (goto-char 1)
+    (display-buffer (current-buffer))))
+
+(defun yas-describe-tables (&optional with-nonactive)
+  "Display snippets for each table."
+  (interactive "P")
+  (let ((original-buffer (current-buffer))
+        (tables (yas--get-snippet-tables)))
+   (with-current-buffer (get-buffer-create "*YASnippet Tables*")
+     (let ((inhibit-read-only t))
+       (when with-nonactive
+         (maphash #'(lambda (_k v)
+                      (cl-pushnew v tables))
+                  yas--tables))
+       (erase-buffer)
+       (insert "YASnippet tables:\n")
+       (dolist (table tables)
+         (yas--describe-pretty-table table original-buffer))
+       (yas--create-snippet-xrefs))
+     (help-mode)
+     (goto-char 1)
+     (display-buffer (current-buffer)))))
+
+(defun yas--describe-pretty-table (table &optional original-buffer)
+  (insert (format "\nSnippet table `%s'"
+                  (yas--table-name table)))
+  (if (yas--table-parents table)
+      (insert (format " parents: %s\n"
+                      (mapcar #'yas--table-name
+                              (yas--table-parents table))))
+    (insert "\n"))
+  (insert (make-string 100 ?-) "\n")
+  (insert "group                   state name                                    key             binding\n")
+  (let ((groups-hash (make-hash-table :test #'equal)))
+    (maphash #'(lambda (_k v)
+                 (let ((group (or (yas--template-fine-group v)
+                                  "(top level)")))
+                   (when (yas--template-name v)
+                     (puthash group
+                              (cons v (gethash group groups-hash))
+                              groups-hash))))
+             (yas--table-uuidhash table))
+    (maphash
+     #'(lambda (group templates)
+         (setq group (truncate-string-to-width group 25 0 ?  "..."))
+         (insert (make-string 100 ?-) "\n")
+         (dolist (p templates)
+           (let* ((name (truncate-string-to-width (propertize (format "\\\\snippet `%s'" (yas--template-name p))
+                                                              'yasnippet p)
+                                                  50 0 ? "..."))
+                  (group (prog1 group
+                           (setq group (make-string (length group) ? ))))
+                  (condition-string (let ((condition (yas--template-condition p)))
+                                      (if (and condition
+                                               original-buffer)
+                                          (with-current-buffer original-buffer
+                                            (if (yas--eval-condition condition)
+                                                "(y)"
+                                              "(s)"))
+                                        "(a)")))
+                  (key-description-string (key-description (yas--template-keybinding p)))
+                  (template-key-padding (if (string= key-description-string "") nil ? )))
+             (insert group " "
+                     condition-string " "
+                     name (if (string-match "\\.\\.\\.$" name)
+                              "'" " ")
+                     " "
+                     (truncate-string-to-width (or (yas--template-key p) "")
+                                               15 0 template-key-padding "...")
+                     (or template-key-padding "")
+                     (truncate-string-to-width key-description-string
+                                               15 0 nil "...")
+                     "\n"))))
+     groups-hash)))
+
+
+
+;;; User convenience functions, for using in `yas-key-syntaxes'
+
+(defun yas-try-key-from-whitespace (_start-point)
+  "As `yas-key-syntaxes' element, look for whitespace delimited key.
+
+A newline will be considered whitespace even if the mode syntax
+marks it as something else (typically comment ender)."
+  (skip-chars-backward "^[:space:]\n"))
+
+(defun yas-shortest-key-until-whitespace (_start-point)
+  "Like `yas-longest-key-from-whitespace' but take the shortest key."
+  (when (/= (skip-chars-backward "^[:space:]\n" (1- (point))) 0)
+    'again))
+
+(defun yas-longest-key-from-whitespace (start-point)
+  "As `yas-key-syntaxes' element, look for longest key between point and whitespace.
+
+A newline will be considered whitespace even if the mode syntax
+marks it as something else (typically comment ender)."
+  (if (= (point) start-point)
+      (yas-try-key-from-whitespace start-point)
+    (forward-char))
+  (unless (<= start-point (1+ (point)))
+    'again))
+
+
+
+;;; User convenience functions, for using in snippet definitions
+
+(defvar yas-modified-p nil
+  "Non-nil if field has been modified by user or transformation.")
+
+(defvar yas-moving-away-p nil
+  "Non-nil if user is about to exit field.")
+
+(defvar yas-text nil
+  "Contains current field text.")
+
+(defun yas-substr (str pattern &optional subexp)
+  "Search PATTERN in STR and return SUBEXPth match.
+
+If found, the content of subexp group SUBEXP (default 0) is
+  returned, or else the original STR will be returned."
+  (let ((grp (or subexp 0)))
+    (save-match-data
+      (if (string-match pattern str)
+          (match-string-no-properties grp str)
+        str))))
+
+(defun yas-choose-value (&rest possibilities)
+  "Prompt for a string in POSSIBILITIES and return it.
+
+The last element of POSSIBILITIES may be a list of strings."
+  (unless (or yas-moving-away-p
+              yas-modified-p)
+    (let* ((last-link (last possibilities))
+           (last-elem (car last-link)))
+      (when (listp last-elem)
+        (setcar last-link (car last-elem))
+        (setcdr last-link (cdr last-elem))))
+    (cl-some (lambda (fn)
+               (funcall fn "Choose: " possibilities))
+             yas-prompt-functions)))
+
+(defun yas--auto-next ()
+  "Helper for `yas-auto-next'."
+  (remove-hook 'post-command-hook #'yas--auto-next t)
+  (yas-next-field))
+
+(defmacro yas-auto-next (&rest body)
+  "Automatically advance to next field after eval'ing BODY."
+  (declare (indent 0) (debug t))
+  `(unless yas-moving-away-p
+     (prog1 ,@body
+       (add-hook 'post-command-hook #'yas--auto-next nil t))))
+
+(defun yas-key-to-value (alist)
+  (unless (or yas-moving-away-p
+              yas-modified-p)
+    (let ((key (read-key-sequence "")))
+      (when (stringp key)
+        (or (cdr (cl-find key alist :key #'car :test #'string=))
+            key)))))
+
+(defun yas-throw (text)
+  "Signal `yas-exception' with TEXT as the reason."
+  (signal 'yas-exception (list text)))
+(put 'yas-exception 'error-conditions '(error yas-exception))
+(put 'yas-exception 'error-message "[yas] Exception")
+
+(defun yas-verify-value (possibilities)
+  "Verify that the current field value is in POSSIBILITIES.
+Otherwise signal `yas-exception'."
+  (when (and yas-moving-away-p (cl-notany (lambda (pos) (string= pos yas-text)) possibilities))
+    (yas-throw (format "Field only allows %s" possibilities))))
+
+(defun yas-field-value (number)
+  "Get the string for field with NUMBER.
+
+Use this in primary and mirror transformations to get the text of
+other fields."
+  (let* ((snippet (car (yas-active-snippets)))
+         (field (and snippet
+                     (yas--snippet-find-field snippet number))))
+    (when field
+      (yas--field-text-for-display field))))
+
+(defun yas-text ()
+  "Return `yas-text' if that exists and is non-empty, else nil."
+  (if (and yas-text
+           (not (string= "" yas-text)))
+      yas-text))
+
+(defun yas-selected-text ()
+  "Return `yas-selected-text' if that exists and is non-empty, else nil."
+  (if (and yas-selected-text
+           (not (string= "" yas-selected-text)))
+      yas-selected-text))
+
+(defun yas--get-field-once (number &optional transform-fn)
+  (unless yas-modified-p
+    (if transform-fn
+        (funcall transform-fn (yas-field-value number))
+      (yas-field-value number))))
+
+(defun yas-default-from-field (number)
+  (unless yas-modified-p
+    (yas-field-value number)))
+
+(defun yas-inside-string ()
+  "Return non-nil if the point is inside a string according to font-lock."
+  (equal 'font-lock-string-face (get-char-property (1- (point)) 'face)))
+
+(defun yas-unimplemented (&optional missing-feature)
+  (if yas--current-template
+      (if (y-or-n-p (format "This snippet is unimplemented (missing %s) Visit the snippet definition? "
+                            (or missing-feature
+                                "something")))
+          (yas--visit-snippet-file-1 yas--current-template))
+    (message "No implementation. Missing %s" (or missing-feature "something"))))
+
+
+;;; Snippet expansion and field management
+
+(defvar yas--active-field-overlay nil
+  "Overlays the currently active field.")
+
+(defvar yas--active-snippets nil
+  "List of currently active snippets")
+(make-variable-buffer-local 'yas--active-snippets)
+
+(defvar yas--field-protection-overlays nil
+  "Two overlays protect the current active field.")
+
+(defvar yas-selected-text nil
+  "The selected region deleted on the last snippet expansion.")
+
+(defvar yas--start-column nil
+  "The column where the snippet expansion started.")
+
+(make-variable-buffer-local 'yas--active-field-overlay)
+(make-variable-buffer-local 'yas--field-protection-overlays)
+(put 'yas--active-field-overlay 'permanent-local t)
+(put 'yas--field-protection-overlays 'permanent-local t)
+
+(cl-defstruct (yas--snippet (:constructor yas--make-snippet (expand-env)))
+  "A snippet.
+
+..."
+  expand-env
+  (fields '())
+  (exit nil)
+  (id (yas--snippet-next-id) :read-only t)
+  (control-overlay nil)
+  active-field
+  ;; stacked expansion: the `previous-active-field' slot saves the
+  ;; active field where the child expansion took place
+  previous-active-field
+  force-exit)
+
+(cl-defstruct (yas--field (:constructor yas--make-field (number start end parent-field)))
+  "A field.
+
+NUMBER is the field number.
+START and END are mostly buffer markers, but see \"apropos markers-to-points\".
+PARENT-FIELD is a `yas--field' this field is nested under, or nil.
+MIRRORS is a list of `yas--mirror's
+TRANSFORM is a lisp form.
+MODIFIED-P is a boolean set to true once user inputs text.
+NEXT is another `yas--field' or `yas--mirror' or `yas--exit'.
+"
+  number
+  start end
+  parent-field
+  (mirrors '())
+  (transform nil)
+  (modified-p nil)
+  next)
+
+
+(cl-defstruct (yas--mirror (:constructor yas--make-mirror (start end transform)))
+  "A mirror.
+
+START and END are mostly buffer markers, but see \"apropos markers-to-points\".
+TRANSFORM is a lisp form.
+PARENT-FIELD is a `yas--field' this mirror is nested under, or nil.
+NEXT is another `yas--field' or `yas--mirror' or `yas--exit'
+DEPTH is a count of how many nested mirrors can affect this mirror"
+  start end
+  (transform nil)
+  parent-field
+  next
+  depth)
+
+(cl-defstruct (yas--exit (:constructor yas--make-exit (marker)))
+  marker
+  next)
+
+(defmacro yas--letenv (env &rest body)
+  "Evaluate BODY with bindings from ENV.
+ENV is a lisp expression that evaluates to list of elements with
+the form (VAR FORM), where VAR is a symbol and FORM is a lisp
+expression that evaluates to its value."
+  (declare (debug (form body)) (indent 1))
+  (let ((envvar (make-symbol "envvar")))
+    `(let ((,envvar ,env))
+       (cl-progv
+           (mapcar #'car ,envvar)
+           (mapcar (lambda (v-f) (eval (cadr v-f))) ,envvar)
+         ,@body))))
+
+(defun yas--snippet-map-markers (fun snippet)
+  "Apply FUN to all marker (sub)fields in SNIPPET.
+Update each field with the result of calling FUN."
+  (dolist (field (yas--snippet-fields snippet))
+    (setf (yas--field-start field) (funcall fun (yas--field-start field)))
+    (setf (yas--field-end field)   (funcall fun (yas--field-end field)))
+    (dolist (mirror (yas--field-mirrors field))
+      (setf (yas--mirror-start mirror) (funcall fun (yas--mirror-start mirror)))
+      (setf (yas--mirror-end mirror)   (funcall fun (yas--mirror-end mirror)))))
+  (let ((snippet-exit (yas--snippet-exit snippet)))
+    (when snippet-exit
+      (setf (yas--exit-marker snippet-exit)
+            (funcall fun (yas--exit-marker snippet-exit))))))
+
+(defun yas--snippet-live-p (snippet)
+  "Return non-nil if SNIPPET hasn't been committed."
+  (catch 'live
+    (yas--snippet-map-markers (lambda (m)
+                                (if (markerp m) m
+                                  (throw 'live nil)))
+                              snippet)
+    t))
+
+(defun yas--apply-transform (field-or-mirror field &optional empty-on-nil-p)
+  "Calculate transformed string for FIELD-OR-MIRROR from FIELD.
+
+If there is no transform for ht field, return nil.
+
+If there is a transform but it returns nil, return the empty
+string iff EMPTY-ON-NIL-P is true."
+  (let* ((yas-text (yas--field-text-for-display field))
+         (yas-modified-p (yas--field-modified-p field))
+         (transform (if (yas--mirror-p field-or-mirror)
+                        (yas--mirror-transform field-or-mirror)
+                      (yas--field-transform field-or-mirror)))
+         (start-point (if (yas--mirror-p field-or-mirror)
+                          (yas--mirror-start field-or-mirror)
+                        (yas--field-start field-or-mirror)))
+         (transformed (and transform
+                           (save-excursion
+                             (goto-char start-point)
+                             (let ((ret (yas--eval-for-string transform)))
+                               (or ret (and empty-on-nil-p "")))))))
+    transformed))
+
+(defsubst yas--replace-all (from to &optional text)
+  "Replace all occurrences from FROM to TO.
+
+With optional string TEXT do it in that string."
+  (if text
+      (replace-regexp-in-string (regexp-quote from) to text t t)
+    (goto-char (point-min))
+    (while (search-forward from nil t)
+      (replace-match to t t text))))
+
+(defun yas--snippet-find-field (snippet number)
+  (cl-find-if (lambda (field)
+                (eq number (yas--field-number field)))
+              (yas--snippet-fields snippet)))
+
+(defun yas--snippet-sort-fields (snippet)
+  "Sort the fields of SNIPPET in navigation order."
+  (setf (yas--snippet-fields snippet)
+        (sort (yas--snippet-fields snippet)
+              #'yas--snippet-field-compare)))
+
+(defun yas--snippet-field-compare (field1 field2)
+  "Compare FIELD1 and FIELD2.
+
+The field with a number is sorted first.  If they both have a
+number, compare through the number.  If neither have, compare
+through the field's start point"
+  (let ((n1 (yas--field-number field1))
+        (n2 (yas--field-number field2)))
+    (if n1
+        (if n2
+            (or (zerop n2) (and (not (zerop n1))
+                                (< n1 n2)))
+          (not (zerop n1)))
+      (if n2
+          (zerop n2)
+        (< (yas--field-start field1)
+           (yas--field-start field2))))))
+
+(defun yas--field-probably-deleted-p (snippet field)
+  "Guess if SNIPPET's FIELD should be skipped."
+  (and
+   ;; field must be zero length
+   ;;
+   (zerop (- (yas--field-start field) (yas--field-end field)))
+   ;; field must have been modified
+   ;;
+   (yas--field-modified-p field)
+   ;; either:
+   (or
+    ;;  1) it's a nested field
+    ;;
+    (yas--field-parent-field field)
+    ;;  2) ends just before the snippet end
+    ;;
+    (and (eq field (car (last (yas--snippet-fields snippet))))
+         (= (yas--field-start field) (overlay-end (yas--snippet-control-overlay snippet)))))
+   ;; the field numbered 0, just before the exit marker, should
+   ;; never be skipped
+   ;;
+   (not (and (yas--field-number field)
+             (zerop (yas--field-number field))))))
+
+(defun yas-active-snippets (&optional beg end)
+  "Return a sorted list of active snippets.
+The most recently-inserted snippets are returned first.
+
+Only snippets overlapping the region BEG ... END are returned.
+Overlapping has the same meaning as described in `overlays-in'.
+If END is omitted, it defaults to (1+ BEG).  If BEG is omitted,
+it defaults to point.  A non-nil, non-buffer position BEG is
+equivalent to a range covering the whole buffer."
+  (unless beg
+    (setq beg (point)))
+  (cond ((not (or (integerp beg) (markerp beg)))
+         (setq beg (point-min) end (point-max)))
+        ((not end)
+         (setq end (1+ beg))))
+  (if (and (eq beg (point-min))
+           (eq end (point-max)))
+      yas--active-snippets
+    ;; Note: don't use `mapcar' here, since it would allocate in
+    ;; proportion to the amount of overlays, even though the list of
+    ;; active snippets should be very small.
+    (let ((snippets nil))
+      (dolist (ov (overlays-in beg end))
+        (let ((snippet (overlay-get ov 'yas--snippet)))
+          ;; Snippets have multiple overlays, so check for dups.
+          (when (and snippet (not (memq snippet snippets)))
+            (push snippet snippets))))
+      (cl-sort snippets #'>= :key #'yas--snippet-id))))
+
+(define-obsolete-function-alias 'yas--snippets-at-point
+  'yas-active-snippets "0.12")
+
+(defun yas-next-field-or-maybe-expand ()
+  "Try to expand a snippet at a key before point.
+
+Otherwise delegate to `yas-next-field'."
+  (interactive)
+  (if yas-triggers-in-field
+      (let ((yas-fallback-behavior 'return-nil)
+            (active-field (overlay-get yas--active-field-overlay 'yas--field)))
+        (when active-field
+          (unless (yas-expand-from-trigger-key active-field)
+            (yas-next-field))))
+    (yas-next-field)))
+
+(defun yas-next-field-will-exit-p (&optional arg)
+  "Return non-nil if (yas-next-field ARG) would exit the current snippet."
+  (let ((snippet (car (yas-active-snippets)))
+        (active (overlay-get yas--active-field-overlay 'yas--field)))
+    (when snippet
+      (not (yas--find-next-field arg snippet active)))))
+
+(defun yas--find-next-field (n snippet active)
+  "Return the Nth field after the ACTIVE one in SNIPPET."
+  (let ((live-fields (cl-remove-if
+                      (lambda (field)
+                        (and (not (eq field active))
+                             (yas--field-probably-deleted-p snippet field)))
+                      (yas--snippet-fields snippet))))
+    (nth (abs n) (memq active (if (>= n 0) live-fields (reverse live-fields))))))
+
+(defun yas-next-field (&optional arg)
+  "Navigate to the ARGth next field.
+
+If there's none, exit the snippet."
+  (interactive)
+  (unless arg (setq arg 1))
+  (let* ((snippet (car (yas-active-snippets)))
+         (active-field (overlay-get yas--active-field-overlay 'yas--field))
+         (target-field (yas--find-next-field arg snippet active-field)))
+    (yas--letenv (yas--snippet-expand-env snippet)
+      ;; Apply transform to active field.
+      (when active-field
+        (let ((yas-moving-away-p t))
+          (when (yas--field-update-display active-field)
+            (yas--update-mirrors snippet))))
+      ;; Now actually move...
+      (if target-field
+          (yas--move-to-field snippet target-field)
+        (yas-exit-snippet snippet)))))
+
+(defun yas--place-overlays (snippet field)
+  "Correctly place overlays for SNIPPET's FIELD."
+  (yas--make-move-field-protection-overlays snippet field)
+  ;; Only move active field overlays if this is field is from the
+  ;; innermost snippet.
+  (when (eq snippet (car (yas-active-snippets (1- (yas--field-start field))
+                                              (1+ (yas--field-end field)))))
+    (yas--make-move-active-field-overlay snippet field)))
+
+(defun yas--move-to-field (snippet field)
+  "Update SNIPPET to move to field FIELD.
+
+Also create some protection overlays"
+  (goto-char (yas--field-start field))
+  (yas--place-overlays snippet field)
+  (overlay-put yas--active-field-overlay 'yas--snippet snippet)
+  (overlay-put yas--active-field-overlay 'yas--field field)
+  (let ((number (yas--field-number field)))
+    ;; check for the special ${0: ...} field
+    (if (and number (zerop number))
+        (progn
+          (set-mark (yas--field-end field))
+          (setf (yas--snippet-force-exit snippet)
+                (or (yas--field-transform field)
+                    t)))
+      ;; make this field active
+      (setf (yas--snippet-active-field snippet) field)
+      ;; primary field transform: first call to snippet transform
+      (unless (yas--field-modified-p field)
+        (if (yas--field-update-display field)
+            (yas--update-mirrors snippet)
+          (setf (yas--field-modified-p field) nil))))))
+
+(defun yas-prev-field ()
+  "Navigate to prev field.  If there's none, exit the snippet."
+  (interactive)
+  (yas-next-field -1))
+
+(defun yas-abort-snippet (&optional snippet)
+  (interactive)
+  (let ((snippet (or snippet
+                     (car (yas-active-snippets)))))
+    (when snippet
+      (setf (yas--snippet-force-exit snippet) t))))
+
+(defun yas-exit-snippet (snippet)
+  "Goto exit-marker of SNIPPET."
+  (interactive (list (cl-first (yas-active-snippets))))
+  (when snippet
+    (setf (yas--snippet-force-exit snippet) t)
+    (goto-char (if (yas--snippet-exit snippet)
+                   (yas--exit-marker (yas--snippet-exit snippet))
+                 (overlay-end (yas--snippet-control-overlay snippet))))))
+
+(defun yas-exit-all-snippets ()
+  "Exit all snippets."
+  (interactive)
+  (mapc #'(lambda (snippet)
+            (yas-exit-snippet snippet)
+            (yas--check-commit-snippet))
+        (yas-active-snippets 'all)))
+
+
+;;; Some low level snippet-routines:
+
+(defvar yas--inhibit-overlay-hooks nil
+  "Bind this temporarily to non-nil to prevent running `yas--on-*-modification'.")
+
+(defvar yas-snippet-beg nil "Beginning position of the last snippet committed.")
+(defvar yas-snippet-end nil "End position of the last snippet committed.")
+
+(defun yas--commit-snippet (snippet)
+  "Commit SNIPPET, but leave point as it is.
+
+This renders the snippet as ordinary text."
+
+  (let ((control-overlay (yas--snippet-control-overlay snippet)))
+    ;;
+    ;; Save the end of the moribund snippet in case we need to revive it
+    ;; its original expansion.
+    ;;
+    (when (and control-overlay
+               (overlay-buffer control-overlay))
+      (setq yas-snippet-beg (overlay-start control-overlay))
+      (setq yas-snippet-end (overlay-end control-overlay))
+      (delete-overlay control-overlay)
+      (setf (yas--snippet-control-overlay snippet) nil))
+
+    (let ((yas--inhibit-overlay-hooks t))
+      (when yas--active-field-overlay
+        (delete-overlay yas--active-field-overlay))
+      (when yas--field-protection-overlays
+        (mapc #'delete-overlay yas--field-protection-overlays)))
+
+    ;; stacked expansion: if the original expansion took place from a
+    ;; field, make sure we advance it here at least to
+    ;; `yas-snippet-end'...
+    ;;
+    (let ((previous-field (yas--snippet-previous-active-field snippet)))
+      (when (and yas-snippet-end previous-field)
+        (yas--advance-end-maybe previous-field yas-snippet-end)))
+
+    ;; Convert all markers to points,
+    ;;
+    (yas--markers-to-points snippet)
+
+    ;; It's no longer an active snippet.
+    (cl-callf2 delq snippet yas--active-snippets)
+
+    ;; Take care of snippet revival on undo.
+    (if (and yas-snippet-revival (listp buffer-undo-list))
+        (push `(apply yas--snippet-revive ,yas-snippet-beg ,yas-snippet-end ,snippet)
+              buffer-undo-list)
+      ;; Dismember the snippet... this is useful if we get called
+      ;; again from `yas--take-care-of-redo'....
+      (setf (yas--snippet-fields snippet) nil)))
+
+  (yas--message 4 "Snippet %s exited." (yas--snippet-id snippet)))
+
+(defvar yas--snippets-to-move nil)
+(make-variable-buffer-local 'yas--snippets-to-move)
+
+(defun yas--prepare-snippets-for-move (beg end buf pos)
+  "Gather snippets in BEG..END for moving to POS in BUF."
+  (let ((to-move nil)
+        (snippets (yas-active-snippets beg end))
+        (dst-base-line (with-current-buffer buf
+                         (count-lines (point-min) pos))))
+    (when snippets
+      (dolist (snippet snippets)
+        (yas--snippet-map-markers
+         (lambda (m)
+           (goto-char m)
+           (beginning-of-line)
+           (prog1 (cons (count-lines (point-min) (point))
+                        (yas--snapshot-marker-location m))
+             (set-marker m nil)))
+         snippet)
+        (let ((ctrl-ov (yas--snapshot-overlay-line-location
+                        (yas--snippet-control-overlay snippet))))
+          (push (list ctrl-ov dst-base-line snippet) to-move)
+          (delete-overlay (car ctrl-ov))))
+      (with-current-buffer buf
+        (setq yas--snippets-to-move (nconc to-move yas--snippets-to-move))))))
+
+(defun yas--on-buffer-kill ()
+  ;; Org mode uses temp buffers for fontification and "native tab",
+  ;; move all the snippets to the original org-mode buffer when it's
+  ;; killed.
+  (let ((org-marker nil))
+    (when (and yas-minor-mode
+               (or (bound-and-true-p org-edit-src-from-org-mode)
+                   (bound-and-true-p org-src--from-org-mode))
+               (markerp
+                (setq org-marker
+                      (or (bound-and-true-p org-edit-src-beg-marker)
+                          (bound-and-true-p org-src--beg-marker)))))
+      (yas--prepare-snippets-for-move
+       (point-min) (point-max)
+       (marker-buffer org-marker) org-marker))))
+
+(add-hook 'kill-buffer-hook #'yas--on-buffer-kill)
+
+(defun yas--finish-moving-snippets ()
+  "Finish job started in `yas--prepare-snippets-for-move'."
+  (cl-loop for (ctrl-ov base-line snippet) in yas--snippets-to-move
+           for base-pos = (progn (goto-char (point-min))
+                                 (forward-line base-line) (point))
+           do (yas--snippet-map-markers
+               (lambda (l-m-r-w)
+                 (goto-char base-pos)
+                 (forward-line (nth 0 l-m-r-w))
+                 (save-restriction
+                   (narrow-to-region (line-beginning-position)
+                                     (line-end-position))
+                   (yas--restore-marker-location (cdr l-m-r-w)))
+                 (nth 1 l-m-r-w))
+               snippet)
+           (goto-char base-pos)
+           (yas--restore-overlay-location ctrl-ov)
+           (yas--maybe-move-to-active-field snippet))
+  (setq yas--snippets-to-move nil))
+
+(defun yas--safely-call-fun (fun)
+  "Call FUN and catch any errors."
+  (condition-case error
+      (funcall fun)
+    ((debug error)
+     (yas--message 2 "Error running %s: %s" fun
+                   (error-message-string error)))))
+
+(defun yas--safely-run-hook (hook)
+  "Call HOOK's functions.
+HOOK should be a symbol, a hook variable, as in `run-hooks'."
+  (let ((debug-on-error (and (not (memq yas-good-grace '(t hooks)))
+                             debug-on-error)))
+    (yas--safely-call-fun (apply-partially #'run-hooks hook))))
+
+(defun yas--check-commit-snippet ()
+  "Check if point exited the currently active field of the snippet.
+
+If so cleans up the whole snippet up."
+  (let* ((snippet-exit-transform nil)
+         (exited-snippets-p nil)
+         ;; Record the custom snippet `yas-after-exit-snippet-hook'
+         ;; set in the expand-env field.
+         (snippet-exit-hook yas-after-exit-snippet-hook))
+    (dolist (snippet yas--active-snippets)
+      (let ((active-field (yas--snippet-active-field snippet)))
+        (yas--letenv (yas--snippet-expand-env snippet)
+          ;; Note: the `force-exit' field could be a transform in case of
+          ;; ${0: ...}, see `yas--move-to-field'.
+          (setq snippet-exit-transform (yas--snippet-force-exit snippet))
+          (cond ((or snippet-exit-transform
+                     (not (and active-field (yas--field-contains-point-p active-field))))
+                 (setf (yas--snippet-force-exit snippet) nil)
+                 (setq snippet-exit-hook yas-after-exit-snippet-hook)
+                 (yas--commit-snippet snippet)
+                 (setq exited-snippets-p t))
+                ((and active-field
+                      (or (not yas--active-field-overlay)
+                          (not (overlay-buffer yas--active-field-overlay))))
+                 ;;
+                 ;; stacked expansion: this case is mainly for recent
+                 ;; snippet exits that place us back int the field of
+                 ;; another snippet
+                 ;;
+                 (save-excursion
+                   (yas--move-to-field snippet active-field)
+                   (yas--update-mirrors snippet)))
+                (t
+                 nil)))))
+    (unless (or yas--active-snippets (not exited-snippets-p))
+      (when snippet-exit-transform
+        (yas--eval-for-effect snippet-exit-transform))
+      (let ((yas-after-exit-snippet-hook snippet-exit-hook))
+        (yas--safely-run-hook 'yas-after-exit-snippet-hook)))))
+
+;; Apropos markers-to-points:
+;;
+;; This was found useful for performance reasons, so that an excessive
+;; number of live markers aren't kept around in the
+;; `buffer-undo-list'.  We don't reuse the original marker object
+;; because that leaves an unreadable object in the history list and
+;; undo-tree persistence has trouble with that.
+;;
+;; This shouldn't bring horrible problems with undo/redo, but you
+;; never know.
+;;
+(defun yas--markers-to-points (snippet)
+  "Save all markers of SNIPPET as positions."
+  (yas--snippet-map-markers (lambda (m)
+                              (prog1 (marker-position m)
+                                (set-marker m nil)))
+                            snippet))
+
+(defun yas--points-to-markers (snippet)
+  "Restore SNIPPET's marker positions, saved by `yas--markers-to-points'."
+  (yas--snippet-map-markers #'copy-marker snippet))
+
+(defun yas--maybe-move-to-active-field (snippet)
+  "Try to move to SNIPPET's active (or first) field and return it if found."
+  (let ((target-field (or (yas--snippet-active-field snippet)
+                          (car (yas--snippet-fields snippet)))))
+    (when target-field
+      (yas--move-to-field snippet target-field)
+      target-field)))
+
+(defun yas--field-contains-point-p (field &optional point)
+  (let ((point (or point
+                   (point))))
+    (and (>= point (yas--field-start field))
+         (<= point (yas--field-end field)))))
+
+(defun yas--field-text-for-display (field)
+  "Return the propertized display text for field FIELD."
+  (buffer-substring (yas--field-start field) (yas--field-end field)))
+
+(defun yas--undo-in-progress ()
+  "True if some kind of undo is in progress."
+  (or undo-in-progress
+      (eq this-command 'undo)
+      (eq this-command 'redo)))
+
+(defun yas--make-control-overlay (snippet start end)
+  "Create the control overlay that surrounds the snippet and
+holds the keymap."
+  (let ((overlay (make-overlay start
+                               end
+                               nil
+                               nil
+                               t)))
+    (overlay-put overlay 'keymap yas-keymap)
+    (overlay-put overlay 'priority yas-overlay-priority)
+    (overlay-put overlay 'yas--snippet snippet)
+    overlay))
+
+(defun yas-current-field ()
+  "Return the currently active field."
+  (and yas--active-field-overlay
+       (overlay-buffer yas--active-field-overlay)
+       (overlay-get yas--active-field-overlay 'yas--field)))
+
+(defun yas--maybe-clear-field-filter (cmd)
+  "Return CMD if at start of unmodified snippet field.
+Use as a `:filter' argument for a conditional keybinding."
+  (let ((field (yas-current-field)))
+    (when (and field
+               (not (yas--field-modified-p field))
+               (eq (point) (marker-position (yas--field-start field))))
+      cmd)))
+
+(defun yas-skip-and-clear-field (&optional field)
+  "Clears unmodified FIELD if at field start, skips to next tab."
+  (interactive)
+  (yas--skip-and-clear (or field (yas-current-field)))
+  (yas-next-field 1))
+
+(defun yas-skip-and-clear-or-delete-char (&optional field)
+  "Clears unmodified field if at field start, skips to next tab.
+
+Otherwise deletes a character normally by calling `delete-char'."
+  (interactive)
+  (declare (obsolete "Bind to `yas-maybe-skip-and-clear-field' instead." "0.13"))
+  (cond ((yas--maybe-clear-field-filter t)
+         (yas--skip-and-clear (or field (yas-current-field)))
+         (yas-next-field 1))
+        (t (call-interactively 'delete-char))))
+
+(defun yas--skip-and-clear (field &optional from)
+  "Deletes the region of FIELD and sets it's modified state to t.
+If given, FROM indicates position to start at instead of FIELD's beginning."
+  ;; Just before skipping-and-clearing the field, mark its children
+  ;; fields as modified, too. If the children have mirrors-in-fields
+  ;; this prevents them from updating erroneously (we're skipping and
+  ;; deleting!).
+  ;;
+  (yas--mark-this-and-children-modified field)
+  (unless (= (yas--field-start field) (yas--field-end field))
+    (delete-region (or from (yas--field-start field)) (yas--field-end field))))
+
+(defun yas--mark-this-and-children-modified (field)
+  (setf (yas--field-modified-p field) t)
+  (let ((fom (yas--field-next field)))
+    (while (and fom
+                (yas--fom-parent-field fom))
+      (when (and (eq (yas--fom-parent-field fom) field)
+                 (yas--field-p fom))
+        (yas--mark-this-and-children-modified fom))
+      (setq fom (yas--fom-next fom)))))
+
+(defun yas--make-move-active-field-overlay (snippet field)
+  "Place the active field overlay in SNIPPET's FIELD.
+
+Move the overlay, or create it if it does not exit."
+  (if (and yas--active-field-overlay
+           (overlay-buffer yas--active-field-overlay))
+      (move-overlay yas--active-field-overlay
+                    (yas--field-start field)
+                    (yas--field-end field))
+    (setq yas--active-field-overlay
+          (make-overlay (yas--field-start field)
+                        (yas--field-end field)
+                        nil nil t))
+    (overlay-put yas--active-field-overlay 'priority yas-overlay-priority)
+    (overlay-put yas--active-field-overlay 'face 'yas-field-highlight-face)
+    (overlay-put yas--active-field-overlay 'yas--snippet snippet)
+    (overlay-put yas--active-field-overlay 'modification-hooks '(yas--on-field-overlay-modification))
+    (overlay-put yas--active-field-overlay 'insert-in-front-hooks
+                 '(yas--on-field-overlay-modification))
+    (overlay-put yas--active-field-overlay 'insert-behind-hooks
+                 '(yas--on-field-overlay-modification))))
+
+(defun yas--skip-and-clear-field-p (field beg _end length)
+  "Tell if newly modified FIELD should be cleared and skipped.
+BEG, END and LENGTH like overlay modification hooks."
+  (and (= length 0) ; A 0 pre-change length indicates insertion.
+       (= beg (yas--field-start field)) ; Insertion at field start?
+       (not (yas--field-modified-p field))))
+
+(defun yas--on-field-overlay-modification (overlay after? beg end &optional length)
+  "Clears the field and updates mirrors, conditionally.
+
+Only clears the field if it hasn't been modified and point is at
+field start.  This hook does nothing if an undo is in progress."
+  (unless (or (not after?)
+              yas--inhibit-overlay-hooks
+              (not (overlayp yas--active-field-overlay)) ; Avoid Emacs bug #21824.
+              ;; If a single change hits multiple overlays of the same
+              ;; snippet, then we delete the snippet the first time,
+              ;; and then subsequent calls get a deleted overlay.
+              ;; Don't delete the snippet again!
+              (not (overlay-buffer overlay))
+              (yas--undo-in-progress))
+    (let* ((inhibit-modification-hooks nil)
+           (yas--inhibit-overlay-hooks t)
+           (field (overlay-get overlay 'yas--field))
+           (snippet (overlay-get yas--active-field-overlay 'yas--snippet)))
+      (if (yas--snippet-live-p snippet)
+          (save-match-data
+            (yas--letenv (yas--snippet-expand-env snippet)
+              (when (yas--skip-and-clear-field-p field beg end length)
+                ;; We delete text starting from the END of insertion.
+                (yas--skip-and-clear field end))
+              (setf (yas--field-modified-p field) t)
+              (yas--advance-end-maybe field (overlay-end overlay))
+              (save-excursion
+                (yas--field-update-display field))
+              (yas--update-mirrors snippet)))
+        (lwarn '(yasnippet zombie) :warning "Killing zombie snippet!")
+        (delete-overlay overlay)))))
+
+(defun yas--auto-fill ()
+  (let* ((orig-point (point))
+         (end (progn (forward-paragraph) (point)))
+         (beg (progn (backward-paragraph) (point)))
+         (snippets (yas-active-snippets beg end))
+         (remarkers nil)
+         (reoverlays nil))
+    (dolist (snippet snippets)
+      (dolist (m (yas--collect-snippet-markers snippet))
+        (when (and (<= beg m) (<= m end))
+          (push (yas--snapshot-marker-location m beg end) remarkers)))
+      (push (yas--snapshot-overlay-location
+             (yas--snippet-control-overlay snippet) beg end)
+            reoverlays))
+    (goto-char orig-point)
+    (let ((yas--inhibit-overlay-hooks t))
+      (if (null yas--original-auto-fill-function)
+          ;; Try to get more info on #873/919.
+          (let ((yas--fill-fun-values `((t ,(default-value 'yas--original-auto-fill-function))))
+                (fill-fun-values `((t ,(default-value 'auto-fill-function))))
+                ;; Listing 2 buffers with the same value is enough
+                (print-length 3))
+            (save-current-buffer
+              (dolist (buf (let ((bufs (buffer-list)))
+                             ;; List the current buffer first.
+                             (setq bufs (cons (current-buffer)
+                                              (remq (current-buffer) bufs)))))
+                (set-buffer buf)
+                (let* ((yf-cell (assq yas--original-auto-fill-function
+                                      yas--fill-fun-values))
+                       (af-cell (assq auto-fill-function fill-fun-values)))
+                  (when (local-variable-p 'yas--original-auto-fill-function)
+                    (if yf-cell (setcdr yf-cell (cons buf (cdr yf-cell)))
+                      (push (list yas--original-auto-fill-function buf) yas--fill-fun-values)))
+                  (when (local-variable-p 'auto-fill-function)
+                    (if af-cell (setcdr af-cell (cons buf (cdr af-cell)))
+                      (push (list auto-fill-function buf) fill-fun-values))))))
+                 (lwarn '(yasnippet auto-fill bug) :error
+                        "`yas--original-auto-fill-function' unexpectedly nil in %S!  Disabling auto-fill.
+  %S
+  `auto-fill-function': %S\n%s"
+                        (current-buffer) yas--fill-fun-values fill-fun-values
+                        (if (fboundp 'backtrace--print-frame)
+                            (with-output-to-string
+                              (mapc (lambda (frame)
+                                      (apply #'backtrace--print-frame frame))
+                                    yas--watch-auto-fill-backtrace))
+                          ""))
+                 ;; Try to avoid repeated triggering of this bug.
+                 (auto-fill-mode -1)
+                 ;; Don't pop up more than once in a session (still log though).
+                 (defvar warning-suppress-types) ; `warnings' is autoloaded by `lwarn'.
+                 (add-to-list 'warning-suppress-types '(yasnippet auto-fill bug)))
+        (funcall yas--original-auto-fill-function)))
+    (save-excursion
+      (setq end (progn (forward-paragraph) (point)))
+      (setq beg (progn (backward-paragraph) (point))))
+    (save-excursion
+      (save-restriction
+        (narrow-to-region beg end)
+        (mapc #'yas--restore-marker-location remarkers)
+        (mapc #'yas--restore-overlay-location reoverlays))
+      (mapc (lambda (snippet)
+              (yas--letenv (yas--snippet-expand-env snippet)
+                (yas--update-mirrors snippet)))
+            snippets))))
+
+
+;;; Apropos protection overlays:
+;;
+;; These exist for nasty users who will try to delete parts of the
+;; snippet outside the active field. Actual protection happens in
+;; `yas--on-protection-overlay-modification'.
+;;
+;; As of github #537 this no longer inhibits the command by issuing an
+;; error: all the snippets at point, including nested snippets, are
+;; automatically commited and the current command can proceed.
+;;
+(defun yas--make-move-field-protection-overlays (snippet field)
+  "Place protection overlays surrounding SNIPPET's FIELD.
+
+Move the overlays, or create them if they do not exit."
+  (let ((start (yas--field-start field))
+        (end (yas--field-end field)))
+    ;; First check if the (1+ end) is contained in the buffer,
+    ;; otherwise we'll have to do a bit of cheating and silently
+    ;; insert a newline. the `(1+ (buffer-size))' should prevent this
+    ;; when using stacked expansion
+    ;;
+    (when (< (buffer-size) end)
+      (save-excursion
+        (let ((yas--inhibit-overlay-hooks t))
+          (goto-char (point-max))
+          (newline))))
+    ;; go on to normal overlay creation/moving
+    ;;
+    (cond ((and yas--field-protection-overlays
+                (cl-every #'overlay-buffer yas--field-protection-overlays))
+           (move-overlay (nth 0 yas--field-protection-overlays)
+                         (1- start) start)
+           (move-overlay (nth 1 yas--field-protection-overlays) end (1+ end)))
+          (t
+           (setq yas--field-protection-overlays
+                 (list (make-overlay (1- start) start nil t nil)
+                       (make-overlay end (1+ end) nil t nil)))
+           (dolist (ov yas--field-protection-overlays)
+             (overlay-put ov 'face 'yas--field-debug-face)
+             (overlay-put ov 'yas--snippet snippet)
+             ;; (overlay-put ov 'evaporate t)
+             (overlay-put ov 'modification-hooks '(yas--on-protection-overlay-modification)))))))
+
+(defun yas--on-protection-overlay-modification (_overlay after? beg end &optional length)
+  "Commit the snippet if the protection overlay is being killed."
+  (unless (or yas--inhibit-overlay-hooks
+              (not after?)
+              (= length (- end beg)) ; deletion or insertion
+              (yas--undo-in-progress))
+    (let ((snippets (yas-active-snippets)))
+      (yas--message 2 "Committing snippets. Action would destroy a protection overlay.")
+      (cl-loop for snippet in snippets
+               do (yas--commit-snippet snippet)))))
+
+(add-to-list 'debug-ignored-errors "^Exit the snippet first!$")
+
+
+;;; Snippet expansion and "stacked" expansion:
+;;
+;; Stacked expansion is when you try to expand a snippet when already
+;; inside a snippet expansion.
+;;
+;; The parent snippet does not run its fields modification hooks
+;; (`yas--on-field-overlay-modification' and
+;; `yas--on-protection-overlay-modification') while the child snippet
+;; is active. This means, among other things, that the mirrors of the
+;; parent snippet are not updated, this only happening when one exits
+;; the child snippet.
+;;
+;; Unfortunately, this also puts some ugly (and not fully-tested)
+;; bits of code in `yas-expand-snippet' and
+;; `yas--commit-snippet'. I've tried to mark them with "stacked
+;; expansion:".
+;;
+;; This was thought to be safer in an undo/redo perspective, but
+;; maybe the correct implementation is to make the globals
+;; `yas--active-field-overlay' and `yas--field-protection-overlays' be
+;; snippet-local and be active even while the child snippet is
+;; running. This would mean a lot of overlay modification hooks
+;; running, but if managed correctly (including overlay priorities)
+;; they should account for all situations...
+
+(defun yas-expand-snippet (snippet &optional start end expand-env)
+  "Expand SNIPPET at current point.
+
+Text between START and END will be deleted before inserting
+template.  EXPAND-ENV is a list of (SYM VALUE) let-style dynamic
+bindings considered when expanding the snippet.  If omitted, use
+SNIPPET's expand-env field.
+
+SNIPPET may be a snippet structure (e.g., as returned by
+`yas-lookup-snippet'), or just a snippet body (which is a string
+for normal snippets, and a list for command snippets)."
+  (cl-assert (and yas-minor-mode
+                  (memq 'yas--post-command-handler post-command-hook))
+             nil
+             "[yas] `yas-expand-snippet' needs properly setup `yas-minor-mode'")
+  (run-hooks 'yas-before-expand-snippet-hook)
+
+  (let* ((clear-field
+          (let ((field (and yas--active-field-overlay
+                            (overlay-buffer yas--active-field-overlay)
+                            (overlay-get yas--active-field-overlay 'yas--field))))
+            (and field (yas--skip-and-clear-field-p
+                        field (point) (point) 0)
+                 field)))
+         (start (cond (start)
+                      ((region-active-p)
+                       (region-beginning))
+                      (clear-field
+                       (yas--field-start clear-field))
+                      (t (point))))
+         (end (cond (end)
+                    ((region-active-p)
+                     (region-end))
+                    (clear-field
+                     (yas--field-end clear-field))
+                    (t (point))))
+         (to-delete (and (> end start)
+                         (buffer-substring-no-properties start end)))
+         (yas-selected-text
+          (cond (yas-selected-text)
+                ((and (region-active-p)
+                      (not clear-field))
+                 to-delete))))
+    (goto-char start)
+    (setq yas--indent-original-column (current-column))
+    ;; Delete the region to delete, this *does* get undo-recorded.
+    (when to-delete
+      (delete-region start end))
+
+    (let ((content (if (yas--template-p snippet)
+                       (yas--template-content snippet)
+                     snippet)))
+      (when (and (not expand-env) (yas--template-p snippet))
+        (setq expand-env (yas--template-expand-env snippet)))
+      (cond ((listp content)
+             ;; x) This is a snippet-command.
+             (yas--eval-for-effect content))
+            (t
+             ;; x) This is a snippet-snippet :-)
+             (setq yas--start-column (current-column))
+             ;; Stacked expansion: also shoosh the overlay modification hooks.
+             (let ((yas--inhibit-overlay-hooks t))
+               (setq snippet
+                     (yas--snippet-create content expand-env start (point))))
+
+             ;; Stacked-expansion: This checks for stacked expansion, save the
+             ;; `yas--previous-active-field' and advance its boundary.
+             (let ((existing-field (and yas--active-field-overlay
+                                        (overlay-buffer yas--active-field-overlay)
+                                        (overlay-get yas--active-field-overlay 'yas--field))))
+               (when existing-field
+                 (setf (yas--snippet-previous-active-field snippet) existing-field)
+                 (yas--advance-end-maybe existing-field (overlay-end yas--active-field-overlay))))
+
+             ;; Exit the snippet immediately if no fields.
+             (unless (yas--snippet-fields snippet)
+               (yas-exit-snippet snippet))
+
+             ;; Now, schedule a move to the first field.
+             (let ((first-field (car (yas--snippet-fields snippet))))
+               (when first-field
+                 (sit-for 0) ;; fix issue 125
+                 (yas--letenv (yas--snippet-expand-env snippet)
+                   (yas--move-to-field snippet first-field))
+                 (when (and (eq (yas--field-number first-field) 0)
+                            (> (length (yas--field-text-for-display
+                                        first-field))
+                               0))
+                   ;; Keep region for ${0:exit text}.
+                   (setq deactivate-mark nil))))
+             (yas--message 4 "snippet %d expanded." (yas--snippet-id snippet))
+             t)))))
+
+(defun yas--take-care-of-redo (snippet)
+  "Commits SNIPPET, which in turn pushes an undo action for reviving it.
+
+Meant to exit in the `buffer-undo-list'."
+  ;; slightly optimize: this action is only needed for snippets with
+  ;; at least one field
+  (when (yas--snippet-fields snippet)
+    (yas--commit-snippet snippet)))
+
+(defun yas--snippet-revive (beg end snippet)
+  "Revives SNIPPET and creates a control overlay from BEG to END.
+
+BEG and END are, we hope, the original snippets boundaries.
+All the markers/points exiting existing inside SNIPPET should point
+to their correct locations *at the time the snippet is revived*.
+
+After revival, push the `yas--take-care-of-redo' in the
+`buffer-undo-list'"
+  ;; Reconvert all the points to markers
+  (yas--points-to-markers snippet)
+  ;; When at least one editable field existed in the zombie snippet,
+  ;; try to revive the whole thing...
+  (when (yas--maybe-move-to-active-field snippet)
+    (setf (yas--snippet-control-overlay snippet) (yas--make-control-overlay snippet beg end))
+    (overlay-put (yas--snippet-control-overlay snippet) 'yas--snippet snippet)
+    (when (listp buffer-undo-list)
+      (push `(apply yas--take-care-of-redo ,snippet)
+            buffer-undo-list))))
+
+(defun yas--snippet-create (content expand-env begin end)
+  "Create a snippet from a template inserted at BEGIN to END.
+
+Returns the newly created snippet."
+  (save-restriction
+    (let ((snippet (yas--make-snippet expand-env)))
+      (yas--letenv expand-env
+        ;; Put a single undo action for the expanded snippet's
+        ;; content.
+        (let ((buffer-undo-list t))
+          ;; Some versions of cc-mode fail when inserting snippet
+          ;; content in a narrowed buffer.
+          (goto-char begin)
+          (insert content)
+          (setq end (+ end (length content)))
+          (narrow-to-region begin end)
+          (goto-char (point-min))
+          (yas--snippet-parse-create snippet))
+        (when (listp buffer-undo-list)
+          (push (cons (point-min) (point-max))
+                buffer-undo-list))
+
+        ;; Indent, collecting undo information normally.
+        (yas--indent snippet)
+
+        ;; Follow up with `yas--take-care-of-redo' on the newly
+        ;; inserted snippet boundaries.
+        (when (listp buffer-undo-list)
+          (push `(apply yas--take-care-of-redo ,snippet)
+                buffer-undo-list))
+
+        ;; Sort and link each field
+        (yas--snippet-sort-fields snippet)
+
+        ;; Create keymap overlay for snippet
+        (setf (yas--snippet-control-overlay snippet)
+              (yas--make-control-overlay snippet (point-min) (point-max)))
+
+        ;; Move to end
+        (goto-char (point-max))
+
+        (push snippet yas--active-snippets)
+        snippet))))
+
+
+;;; Apropos adjacencies and "fom's":
+;;
+;; Once the $-constructs bits like "$n" and "${:n" are deleted in the
+;; recently expanded snippet, we might actually have many fields,
+;; mirrors (and the snippet exit) in the very same position in the
+;; buffer. Therefore we need to single-link the
+;; fields-or-mirrors-or-exit (which I have abbreviated to "fom")
+;; according to their original positions in the buffer.
+;;
+;; Then we have operation `yas--advance-end-maybe' and
+;; `yas--advance-start-maybe', which conditionally push the starts and
+;; ends of these foms down the chain.
+;;
+;; This allows for like the printf with the magic ",":
+;;
+;;   printf ("${1:%s}\\n"${1:$(if (string-match "%" text) "," "\);")}  \
+;;   $2${1:$(if (string-match "%" text) "\);" "")}$0
+;;
+(defun yas--fom-start (fom)
+  (cond ((yas--field-p fom)
+         (yas--field-start fom))
+        ((yas--mirror-p fom)
+         (yas--mirror-start fom))
+        (t
+         (yas--exit-marker fom))))
+
+(defun yas--fom-end (fom)
+  (cond ((yas--field-p fom)
+         (yas--field-end fom))
+        ((yas--mirror-p fom)
+         (yas--mirror-end fom))
+        (t
+         (yas--exit-marker fom))))
+
+(defun yas--fom-next (fom)
+  (cond ((yas--field-p fom)
+         (yas--field-next fom))
+        ((yas--mirror-p fom)
+         (yas--mirror-next fom))
+        (t
+         (yas--exit-next fom))))
+
+(defun yas--fom-parent-field (fom)
+  (cond ((yas--field-p fom)
+         (yas--field-parent-field fom))
+        ((yas--mirror-p fom)
+         (yas--mirror-parent-field fom))
+        (t
+         nil)))
+
+(defun yas--calculate-adjacencies (snippet)
+  "Calculate adjacencies for fields or mirrors of SNIPPET.
+
+This is according to their relative positions in the buffer, and
+has to be called before the $-constructs are deleted."
+  (let* ((fom-set-next-fom
+         (lambda (fom nextfom)
+           (cond ((yas--field-p fom)
+                  (setf (yas--field-next fom) nextfom))
+                 ((yas--mirror-p fom)
+                  (setf (yas--mirror-next fom) nextfom))
+                 (t
+                  (setf (yas--exit-next fom) nextfom)))))
+        (compare-fom-begs
+         (lambda (fom1 fom2)
+           (if (= (yas--fom-start fom2) (yas--fom-start fom1))
+               (yas--mirror-p fom2)
+             (>= (yas--fom-start fom2) (yas--fom-start fom1)))))
+        (link-foms fom-set-next-fom))
+    ;; make some yas--field, yas--mirror and yas--exit soup
+    (let ((soup))
+      (when (yas--snippet-exit snippet)
+        (push (yas--snippet-exit snippet) soup))
+      (dolist (field (yas--snippet-fields snippet))
+        (push field soup)
+        (dolist (mirror (yas--field-mirrors field))
+          (push mirror soup)))
+      (setq soup
+            (sort soup compare-fom-begs))
+      (when soup
+        (cl-reduce link-foms soup)))))
+
+(defun yas--calculate-simple-fom-parentage (snippet fom)
+  "Discover if FOM is parented by some field in SNIPPET.
+
+Use the tightest containing field if more than one field contains
+the mirror.  Intended to be called *before* the dollar-regions are
+deleted."
+  (let ((min (point-min))
+        (max (point-max)))
+    (dolist (field (remq fom (yas--snippet-fields snippet)))
+      (when (and (<= (yas--field-start field) (yas--fom-start fom))
+                 (<= (yas--fom-end fom) (yas--field-end field))
+               (< min (yas--field-start field))
+               (< (yas--field-end field) max))
+          (setq min (yas--field-start field)
+                max (yas--field-end field))
+          (cond ((yas--field-p fom)
+                 (setf (yas--field-parent-field fom) field))
+                ((yas--mirror-p fom)
+                 (setf (yas--mirror-parent-field fom) field))
+                (t ; it's an exit, so noop
+                 nil ))))))
+
+(defun yas--advance-end-maybe (fom newend)
+  "Maybe advance FOM's end to NEWEND if it needs it.
+
+If it does, also:
+
+* call `yas--advance-start-maybe' on FOM's next fom.
+
+* in case FOM is field call `yas--advance-end-maybe' on its parent
+  field
+
+Also, if FOM is an exit-marker, always call
+`yas--advance-start-maybe' on its next fom.  This is because
+exit-marker have identical start and end markers."
+  (cond ((and fom (< (yas--fom-end fom) newend))
+         (set-marker (yas--fom-end fom) newend)
+         (yas--advance-start-maybe (yas--fom-next fom) newend)
+         (yas--advance-end-of-parents-maybe (yas--fom-parent-field fom) newend))
+        ((yas--exit-p fom)
+         (yas--advance-start-maybe (yas--fom-next fom) newend))))
+
+(defun yas--advance-start-maybe (fom newstart)
+  "Maybe advance FOM's start to NEWSTART if it needs it.
+
+If it does, also call `yas--advance-end-maybe' on FOM."
+  (when (and fom (< (yas--fom-start fom) newstart))
+    (set-marker (yas--fom-start fom) newstart)
+    (yas--advance-end-maybe fom newstart)))
+
+(defun yas--advance-end-of-parents-maybe (field newend)
+  "Like `yas--advance-end-maybe' but for parent fields.
+
+Only works for fields and doesn't care about the start of the
+next FOM.  Works its way up recursively for parents of parents."
+  (when (and field
+             (< (yas--field-end field) newend))
+    (set-marker (yas--field-end field) newend)
+    (yas--advance-end-of-parents-maybe (yas--field-parent-field field) newend)))
+
+(defvar yas--dollar-regions nil
+  "When expanding the snippet the \"parse-create\" functions add
+cons cells to this var.")
+
+(defvar yas--indent-markers nil
+  "List of markers for manual indentation.")
+
+(defun yas--snippet-parse-create (snippet)
+  "Parse a recently inserted snippet template, creating all
+necessary fields, mirrors and exit points.
+
+Meant to be called in a narrowed buffer, does various passes"
+  (let ((saved-quotes nil)
+        (parse-start (point)))
+    ;; Avoid major-mode's syntax propertizing function, since we
+    ;; change the syntax-table while calling `scan-sexps'.
+    (let ((syntax-propertize-function nil))
+      (setq yas--dollar-regions nil)  ; Reset the yas--dollar-regions.
+      (yas--protect-escapes nil '(?`))  ; Protect just the backquotes.
+      (goto-char parse-start)
+      (setq saved-quotes (yas--save-backquotes)) ; `expressions`.
+      (yas--protect-escapes)            ; Protect escaped characters.
+      (goto-char parse-start)
+      (yas--indent-parse-create)        ; Parse indent markers: `$>'.
+      (goto-char parse-start)
+      (yas--field-parse-create snippet) ; Parse fields with {}.
+      (goto-char parse-start)
+      (yas--simple-fom-create snippet) ; Parse simple mirrors & fields.
+      (goto-char parse-start)
+      (yas--transform-mirror-parse-create snippet) ; Parse mirror transforms.
+      ;; Invalidate any syntax-propertizing done while
+      ;; `syntax-propertize-function' was nil.
+      (syntax-ppss-flush-cache parse-start))
+    ;; Set "next" links of fields & mirrors.
+    (yas--calculate-adjacencies snippet)
+    (yas--save-restriction-and-widen    ; Delete $-constructs.
+      (yas--delete-regions yas--dollar-regions))
+    ;; Make sure to do this insertion *after* deleting the dollar
+    ;; regions, otherwise we invalidate the calculated positions of
+    ;; all the fields following $0.
+    (let ((exit (yas--snippet-exit snippet)))
+      (goto-char (if exit (yas--exit-marker exit) (point-max))))
+    (when (eq yas-wrap-around-region 'cua)
+      (setq yas-wrap-around-region ?0))
+    (cond ((and yas-wrap-around-region yas-selected-text)
+           (insert yas-selected-text))
+          ((and (characterp yas-wrap-around-region)
+                (get-register yas-wrap-around-region))
+           (insert (prog1 (get-register yas-wrap-around-region)
+                     (set-register yas-wrap-around-region nil)))))
+    (yas--restore-backquotes saved-quotes)  ; Restore `expression` values.
+    (goto-char parse-start)
+    (yas--restore-escapes)        ; Restore escapes.
+    (yas--update-mirrors snippet) ; Update mirrors for the first time.
+    (goto-char parse-start)))
+
+;; HACK: Some implementations of `indent-line-function' (called via
+;; `indent-according-to-mode') delete text before they insert (like
+;; cc-mode), some make complicated regexp replacements (looking at
+;; you, org-mode).  To find place where the marker "should" go after
+;; indentation, we create a regexp based on what the line looks like
+;; before, putting a capture group where the marker is.  The regexp
+;; matches any whitespace with [[:space:]]* to allow for the
+;; indentation changing whitespace.  Additionally, we try to preserve
+;; the amount of whitespace *following* the marker, because
+;; indentation generally affects whitespace at the beginning, not the
+;; end.
+;;
+;; Two other cases where we apply a similar strategy:
+;;
+;; 1. Handling `auto-fill-mode', in this case we need to use the
+;; current paragraph instead of line.
+;;
+;; 2. Moving snippets from an `org-src' temp buffer into the main org
+;; buffer, in this case we need to count the line offsets (because org
+;; may add indentation on each line making character positions
+;; unreliable).
+;;
+;; This is all best-effort heuristic stuff, but it should cover 99% of
+;; use-cases.
+
+(defun yas--snapshot-marker-location (marker &optional beg end)
+  "Returns info for restoring MARKER's location after indent.
+The returned value is a list of the form (MARKER REGEXP WS-COUNT)."
+  (unless beg (setq beg (line-beginning-position)))
+  (unless end (setq end (line-end-position)))
+  (let ((before (split-string (buffer-substring-no-properties beg marker)
+                              "[[:space:]\n]+" t))
+        (after (split-string (buffer-substring-no-properties marker end)
+                             "[[:space:]\n]+" t)))
+    (list marker
+          (concat "[[:space:]\n]*"
+                  (mapconcat (lambda (s)
+                               (if (eq s marker) "\\(\\)"
+                                 (regexp-quote s)))
+                             (nconc before (list marker) after)
+                             "[[:space:]\n]*"))
+          (progn (goto-char marker)
+                 (skip-chars-forward "[:space:]\n" end)
+                 (- (point) marker)))))
+
+(defun yas--snapshot-overlay-location (overlay beg end)
+  "Like `yas--snapshot-marker-location' for overlays.
+The returned format is (OVERLAY (RE WS) (RE WS)).  Either of
+the (RE WS) lists may be nil if the start or end, respectively,
+of the overlay is outside the range BEG .. END."
+  (let ((obeg (overlay-start overlay))
+        (oend (overlay-end overlay)))
+    (list overlay
+          (when (and (<= beg obeg) (< obeg end))
+            (cdr (yas--snapshot-marker-location obeg beg end)))
+          (when (and (<= beg oend) (< oend end))
+            (cdr (yas--snapshot-marker-location oend beg end))))))
+
+(defun yas--snapshot-overlay-line-location (overlay)
+  "Return info for restoring OVERLAY's line based location.
+The returned format is (OVERLAY (LINE RE WS) (LINE RE WS))."
+  (let ((loc-beg (progn (goto-char (overlay-start overlay))
+                        (yas--snapshot-marker-location (point))))
+        (loc-end (progn (goto-char (overlay-end overlay))
+                        (yas--snapshot-marker-location (point)))))
+    (setcar loc-beg (count-lines (point-min) (progn (goto-char (car loc-beg))
+                                                    (line-beginning-position))))
+    (setcar loc-end (count-lines (point-min) (progn (goto-char (car loc-end))
+                                                    (line-beginning-position))))
+    (list overlay loc-beg loc-end)))
+
+(defun yas--goto-saved-location (regexp ws-count)
+  "Move point to location saved by `yas--snapshot-marker-location'.
+Buffer must be narrowed to BEG..END used to create the snapshot info."
+  (goto-char (point-min))
+  (if (not (looking-at regexp))
+      (lwarn '(yasnippet re-marker) :warning
+             "Couldn't find: %S" regexp)
+    (goto-char (match-beginning 1))
+    (skip-chars-forward "[:space:]\n")
+    (skip-chars-backward "[:space:]\n" (- (point) ws-count))))
+
+(defun yas--restore-marker-location (re-marker)
+  "Restores marker based on info from `yas--snapshot-marker-location'.
+Buffer must be narrowed to BEG..END used to create the snapshot info."
+  (apply #'yas--goto-saved-location (cdr re-marker))
+  (set-marker (car re-marker) (point)))
+
+(defun yas--restore-overlay-location (ov-locations)
+  "Restores marker based on info from `yas--snapshot-marker-location'.
+Buffer must be narrowed to BEG..END used to create the snapshot info."
+  (cl-destructuring-bind (overlay loc-beg loc-end) ov-locations
+    (move-overlay overlay
+                  (if (not loc-beg) (overlay-start overlay)
+                    (apply #'yas--goto-saved-location loc-beg)
+                    (point))
+                  (if (not loc-end) (overlay-end overlay)
+                    (apply #'yas--goto-saved-location loc-end)
+                    (point)))))
+
+
+(defun yas--restore-overlay-line-location (ov-locations)
+  "Restores overlay based on info from `yas--snapshot-overlay-line-location'."
+  (save-restriction
+    (move-overlay (car ov-locations)
+                  (save-excursion
+                    (forward-line (car (nth 1 ov-locations)))
+                    (narrow-to-region (line-beginning-position) (line-end-position))
+                    (apply #'yas--goto-saved-location (cdr (nth 1 ov-locations)))
+                    (point))
+                  (save-excursion
+                    (forward-line (car (nth 2 ov-locations)))
+                    (narrow-to-region (line-beginning-position) (line-end-position))
+                    (apply #'yas--goto-saved-location (cdr (nth 2 ov-locations)))
+                    (point)))))
+
+(defun yas--indent-region (from to snippet)
+  "Indent the lines between FROM and TO with `indent-according-to-mode'.
+The SNIPPET's markers are preserved."
+  (save-excursion
+    (yas--save-restriction-and-widen
+      (let* ((snippet-markers (yas--collect-snippet-markers snippet))
+             (to (set-marker (make-marker) to)))
+        (goto-char from)
+        (cl-loop for bol = (line-beginning-position)
+                 for eol = (line-end-position)
+                 if (or yas-also-indent-empty-lines
+                        (/= bol eol))
+                 do
+                 ;; Indent each non-empty line.
+                 (let ((remarkers nil))
+                   (dolist (m snippet-markers)
+                     (when (and (<= bol m) (<= m eol))
+                       (push (yas--snapshot-marker-location m bol eol)
+                             remarkers)))
+                   (unwind-protect
+                       (progn (back-to-indentation)
+                              (indent-according-to-mode))
+                     (save-restriction
+                       (narrow-to-region bol (line-end-position))
+                       (mapc #'yas--restore-marker-location remarkers))))
+                 while (and (zerop (forward-line 1))
+                            (< (point) to)))))))
+
+(defvar yas--indent-original-column nil)
+(defun yas--indent (snippet)
+  ;; Indent lines that had indent markers (`$>') on them.
+  (save-excursion
+    (dolist (marker yas--indent-markers)
+      (unless (eq yas-indent-line 'auto)
+        (goto-char marker)
+        (yas--indent-region (line-beginning-position)
+                            (line-end-position)
+                            snippet))
+      ;; Finished with this marker.
+      (set-marker marker nil))
+    (setq yas--indent-markers nil))
+  ;; Now do stuff for `fixed' and `auto'.
+  (save-excursion
+    ;; We need to be at end of line, so that `forward-line' will only
+    ;; report 0 if it actually moves over a newline.
+    (end-of-line)
+    (cond ((eq yas-indent-line 'fixed)
+           (when (= (forward-line 1) 0)
+             (let ((indent-line-function
+                    (lambda ()
+                      ;; We need to be at beginning of line in order to
+                      ;; indent existing whitespace correctly.
+                      (beginning-of-line)
+                      (indent-to-column yas--indent-original-column))))
+               (yas--indent-region (line-beginning-position)
+                                   (point-max)
+                                   snippet))))
+          ((eq yas-indent-line 'auto)
+           (when (or yas-also-auto-indent-first-line
+                     (= (forward-line 1) 0))
+             (yas--indent-region (line-beginning-position)
+                                 (point-max)
+                                 snippet))))))
+
+(defun yas--collect-snippet-markers (snippet)
+  "Make a list of all the markers used by SNIPPET."
+  (let (markers)
+    (yas--snippet-map-markers (lambda (m) (push m markers) m) snippet)
+    markers))
+
+(defun yas--escape-string (escaped)
+  (concat "YASESCAPE" (format "%d" escaped) "PROTECTGUARD"))
+
+(defun yas--protect-escapes (&optional text escaped)
+  "Protect all escaped characters with their numeric ASCII value.
+
+With optional string TEXT do it in string instead of buffer."
+  (let ((changed-text text)
+        (text-provided-p text))
+    (mapc #'(lambda (escaped)
+              (setq changed-text
+                    (yas--replace-all (concat "\\" (char-to-string escaped))
+                                     (yas--escape-string escaped)
+                                     (when text-provided-p changed-text))))
+          (or escaped yas--escaped-characters))
+    changed-text))
+
+(defun yas--restore-escapes (&optional text escaped)
+  "Restore all escaped characters from their numeric ASCII value.
+
+With optional string TEXT do it in string instead of the buffer."
+  (let ((changed-text text)
+        (text-provided-p text))
+    (mapc #'(lambda (escaped)
+              (setq changed-text
+                    (yas--replace-all (yas--escape-string escaped)
+                                     (char-to-string escaped)
+                                     (when text-provided-p changed-text))))
+          (or escaped yas--escaped-characters))
+    changed-text))
+
+(defun yas--save-backquotes ()
+  "Save all \"\\=`(lisp-expression)\\=`\"-style expressions.
+Return a list of (MARKER . STRING) entires for each backquoted
+Lisp expression."
+  (let* ((saved-quotes nil)
+         (yas--snippet-buffer (current-buffer))
+         (yas--change-detected nil)
+         (detect-change (lambda (_beg _end)
+                          (when (eq (current-buffer) yas--snippet-buffer)
+                            (setq yas--change-detected t)))))
+    (while (re-search-forward yas--backquote-lisp-expression-regexp nil t)
+      (let ((current-string (match-string-no-properties 1)) transformed)
+        (yas--save-restriction-and-widen
+          (delete-region (match-beginning 0) (match-end 0)))
+        (let ((before-change-functions
+               (cons detect-change before-change-functions)))
+          (setq transformed (yas--eval-for-string (yas--read-lisp
+                                                   (yas--restore-escapes
+                                                    current-string '(?`))))))
+        (goto-char (match-beginning 0))
+        (when transformed
+          (let ((marker (make-marker))
+                (before-change-functions (cdr before-change-functions)))
+            (yas--save-restriction-and-widen
+              (insert "Y") ;; quite horrendous, I love it :)
+              (set-marker marker (point))
+              (insert "Y"))
+            (push (cons marker transformed) saved-quotes)))))
+    (when yas--change-detected
+      (lwarn '(yasnippet backquote-change) :warning
+             "`%s' modified buffer in a backquote expression.
+  To hide this warning, add (yasnippet backquote-change) to `warning-suppress-types'."
+             (if yas--current-template
+                 (yas--template-name yas--current-template)
+               "Snippet")))
+    saved-quotes))
+
+(defun yas--restore-backquotes (saved-quotes)
+  "Replace markers in SAVED-QUOTES with their values.
+SAVED-QUOTES is the in format returned by `yas--save-backquotes'."
+  (cl-loop for (marker . string) in saved-quotes do
+           (save-excursion
+             (goto-char marker)
+             (yas--save-restriction-and-widen
+               (delete-char -1)
+               (insert string)
+               (delete-char 1))
+             (set-marker marker nil))))
+
+(defun yas--scan-sexps (from count)
+  (ignore-errors
+    (save-match-data ; `scan-sexps' may modify match data.
+      (with-syntax-table (standard-syntax-table)
+        (let ((parse-sexp-lookup-properties nil))
+          (scan-sexps from count))))))
+
+(defun yas--make-marker (pos)
+  "Create a marker at POS with nil `marker-insertion-type'."
+  (let ((marker (set-marker (make-marker) pos)))
+    (set-marker-insertion-type marker nil)
+    marker))
+
+(defun yas--indent-parse-create ()
+  "Parse the \"$>\" indentation markers just inserted."
+  (setq yas--indent-markers ())
+  (while (search-forward "$>" nil t)
+    (delete-region (match-beginning 0) (match-end 0))
+    ;; Mark the beginning of the line.
+    (push (yas--make-marker (line-beginning-position))
+          yas--indent-markers))
+  (setq yas--indent-markers (nreverse yas--indent-markers)))
+
+(defun yas--field-parse-create (snippet &optional parent-field)
+  "Parse most field expressions in SNIPPET, except for the simple one \"$n\".
+
+The following count as a field:
+
+* \"${n: text}\", for a numbered field with default text, as long as N is not 0;
+
+* \"${n: text$(expression)}, the same with a Lisp expression;
+  this is caught with the curiously named `yas--multi-dollar-lisp-expression-regexp'
+
+* the same as above but unnumbered, (no N:) and number is calculated automatically.
+
+When multiple expressions are found, only the last one counts."
+  ;;
+  (save-excursion
+    (while (re-search-forward yas--field-regexp nil t)
+      (let* ((real-match-end-0 (yas--scan-sexps (1+ (match-beginning 0)) 1))
+             (number (and (match-string-no-properties 1)
+                          (string-to-number (match-string-no-properties 1))))
+             (brand-new-field (and real-match-end-0
+                                   ;; break if on "$(" immediately
+                                   ;; after the ":", this will be
+                                   ;; caught as a mirror with
+                                   ;; transform later.
+                                   (not (string-match-p "\\`\\$[ \t\n]*("
+                                                        (match-string-no-properties 2)))
+                                   ;; allow ${0: some exit text}
+                                   ;; (not (and number (zerop number)))
+                                   (yas--make-field number
+                                                   (yas--make-marker (match-beginning 2))
+                                                   (yas--make-marker (1- real-match-end-0))
+                                                   parent-field))))
+        (when brand-new-field
+          (goto-char real-match-end-0)
+          (push (cons (1- real-match-end-0) real-match-end-0)
+                yas--dollar-regions)
+          (push (cons (match-beginning 0) (match-beginning 2))
+                yas--dollar-regions)
+          (push brand-new-field (yas--snippet-fields snippet))
+          (save-excursion
+            (save-restriction
+              (narrow-to-region (yas--field-start brand-new-field) (yas--field-end brand-new-field))
+              (goto-char (point-min))
+              (yas--field-parse-create snippet brand-new-field)))))))
+  ;; if we entered from a parent field, now search for the
+  ;; `yas--multi-dollar-lisp-expression-regexp'. This is used for
+  ;; primary field transformations
+  ;;
+  (when parent-field
+    (save-excursion
+      (while (re-search-forward yas--multi-dollar-lisp-expression-regexp nil t)
+        (let* ((real-match-end-1 (yas--scan-sexps (match-beginning 1) 1)))
+          ;; commit the primary field transformation if:
+          ;;
+          ;; 1. we don't find it in yas--dollar-regions (a subnested
+          ;; field) might have already caught it.
+          ;;
+          ;; 2. we really make sure we have either two '$' or some
+          ;; text and a '$' after the colon ':'. This is a FIXME: work
+          ;; my regular expressions and end these ugly hacks.
+          ;;
+          (when (and real-match-end-1
+                     (not (member (cons (match-beginning 0)
+                                        real-match-end-1)
+                                  yas--dollar-regions))
+                     (not (eq ?:
+                              (char-before (1- (match-beginning 1))))))
+            (let ((lisp-expression-string (buffer-substring-no-properties (match-beginning 1)
+                                                                          real-match-end-1)))
+              (setf (yas--field-transform parent-field)
+                    (yas--read-lisp (yas--restore-escapes lisp-expression-string))))
+            (push (cons (match-beginning 0) real-match-end-1)
+                  yas--dollar-regions)))))))
+
+(defun yas--transform-mirror-parse-create (snippet)
+  "Parse the \"${n:$(lisp-expression)}\" mirror transformations in SNIPPET."
+  (while (re-search-forward yas--transform-mirror-regexp nil t)
+    (let* ((real-match-end-0 (yas--scan-sexps (1+ (match-beginning 0)) 1))
+           (number (string-to-number (match-string-no-properties 1)))
+           (field (and number
+                       (not (zerop number))
+                       (yas--snippet-find-field snippet number)))
+           (brand-new-mirror
+            (and real-match-end-0
+                 field
+                 (yas--make-mirror (yas--make-marker (match-beginning 0))
+                                  (yas--make-marker (match-beginning 0))
+                                  (yas--read-lisp
+                                   (yas--restore-escapes
+                                    (buffer-substring-no-properties (match-beginning 2)
+                                                                    (1- real-match-end-0))))))))
+      (when brand-new-mirror
+        (push brand-new-mirror
+              (yas--field-mirrors field))
+        (yas--calculate-simple-fom-parentage snippet brand-new-mirror)
+        (push (cons (match-beginning 0) real-match-end-0) yas--dollar-regions)))))
+
+(defun yas--simple-fom-create (snippet)
+  "Parse the simple \"$n\" fields/mirrors/exitmarkers in SNIPPET."
+  (while (re-search-forward yas--simple-mirror-regexp nil t)
+    (let ((number (string-to-number (match-string-no-properties 1))))
+      (cond ((zerop number)
+             (setf (yas--snippet-exit snippet)
+                   (yas--make-exit (yas--make-marker (match-end 0))))
+             (push (cons (match-beginning 0) (yas--exit-marker (yas--snippet-exit snippet)))
+                   yas--dollar-regions))
+            (t
+             (let ((field (yas--snippet-find-field snippet number))
+                   (fom))
+               (if field
+                   (push
+                    (setq fom (yas--make-mirror
+                               (yas--make-marker (match-beginning 0))
+                               (yas--make-marker (match-beginning 0))
+                               nil))
+                    (yas--field-mirrors field))
+                 (push
+                  (setq fom (yas--make-field number
+                                             (yas--make-marker (match-beginning 0))
+                                             (yas--make-marker (match-beginning 0))
+                                             nil))
+                  (yas--snippet-fields snippet)))
+               (yas--calculate-simple-fom-parentage snippet fom))
+             (push (cons (match-beginning 0) (match-end 0))
+                   yas--dollar-regions))))))
+
+(defun yas--delete-regions (regions)
+  "Sort disjuct REGIONS by start point, then delete from the back."
+  (mapc #'(lambda (reg)
+            (delete-region (car reg) (cdr reg)))
+        (sort regions
+              #'(lambda (r1 r2)
+                  (>= (car r1) (car r2))))))
+
+(defun yas--calculate-mirror-depth (mirror &optional traversed)
+  (let* ((parent (yas--mirror-parent-field mirror))
+         (parents-mirrors (and parent
+                               (yas--field-mirrors parent))))
+    (or (yas--mirror-depth mirror)
+        (setf (yas--mirror-depth mirror)
+              (cond ((memq mirror traversed) 0)
+                    ((and parent parents-mirrors)
+                     (1+ (cl-reduce
+                          #'max parents-mirrors
+                          :key (lambda (m)
+                                 (yas--calculate-mirror-depth
+                                  m (cons mirror traversed))))))
+                    (parent 1)
+                    (t 0))))))
+
+(defun yas--update-mirrors (snippet)
+  "Update all the mirrors of SNIPPET."
+  (yas--save-restriction-and-widen
+    (save-excursion
+      (cl-loop
+       for (field . mirror)
+       in (cl-sort
+           ;; Make a list of (FIELD . MIRROR).
+           (cl-mapcan (lambda (field)
+                        (mapcar (lambda (mirror)
+                                  (cons field mirror))
+                                (yas--field-mirrors field)))
+                      (yas--snippet-fields snippet))
+           ;; Then sort this list so that entries with mirrors with
+           ;; parent fields appear before.  This was important for
+           ;; fixing #290, and also handles the case where a mirror in
+           ;; a field causes another mirror to need reupdating.
+           #'> :key (lambda (fm) (yas--calculate-mirror-depth (cdr fm))))
+       ;; Before updating a mirror with a parent-field, maybe advance
+       ;; its start (#290).
+       do (let ((parent-field (yas--mirror-parent-field mirror)))
+            (when parent-field
+              (yas--advance-start-maybe mirror (yas--fom-start parent-field))))
+       ;; Update this mirror.
+       do (yas--mirror-update-display mirror field)
+       ;; Delay indenting until we're done all mirrors.  We must do
+       ;; this to avoid losing whitespace between fields that are
+       ;; still empty (i.e., they will be non-empty after updating).
+       when (eq yas-indent-line 'auto)
+       collect (cons (yas--mirror-start mirror) (yas--mirror-end mirror))
+       into indent-regions
+       ;; `yas--place-overlays' is needed since the active field and
+       ;; protected overlays might have been changed because of insertions
+       ;; in `yas--mirror-update-display'.
+       do (let ((active-field (yas--snippet-active-field snippet)))
+            (when active-field (yas--place-overlays snippet active-field)))
+       finally do
+       (let ((yas--inhibit-overlay-hooks t))
+         (cl-loop for (beg . end) in (cl-sort indent-regions #'< :key #'car)
+                  do (yas--indent-region beg end snippet)))))))
+
+(defun yas--mirror-update-display (mirror field)
+  "Update MIRROR according to FIELD (and mirror transform)."
+
+  (let* ((mirror-parent-field (yas--mirror-parent-field mirror))
+         (reflection (and (not (and mirror-parent-field
+                                    (yas--field-modified-p mirror-parent-field)))
+                          (or (yas--apply-transform mirror field 'empty-on-nil)
+                              (yas--field-text-for-display field)))))
+    (when (and reflection
+               (not (string= reflection (buffer-substring-no-properties (yas--mirror-start mirror)
+                                                                        (yas--mirror-end mirror)))))
+      (goto-char (yas--mirror-start mirror))
+      (let ((yas--inhibit-overlay-hooks t))
+        (insert reflection))
+      (if (> (yas--mirror-end mirror) (point))
+          (delete-region (point) (yas--mirror-end mirror))
+        (set-marker (yas--mirror-end mirror) (point))
+        (yas--advance-start-maybe (yas--mirror-next mirror) (point))
+        ;; super-special advance
+        (yas--advance-end-of-parents-maybe mirror-parent-field (point))))))
+
+(defun yas--field-update-display (field)
+  "Much like `yas--mirror-update-display', but for fields."
+  (when (yas--field-transform field)
+    (let ((transformed (and (not (eq (yas--field-number field) 0))
+                            (yas--apply-transform field field))))
+      (when (and transformed
+                 (not (string= transformed (buffer-substring-no-properties (yas--field-start field)
+                                                                           (yas--field-end field)))))
+        (setf (yas--field-modified-p field) t)
+        (goto-char (yas--field-start field))
+        (let ((yas--inhibit-overlay-hooks t))
+          (insert transformed)
+          (if (> (yas--field-end field) (point))
+              (delete-region (point) (yas--field-end field))
+            (set-marker (yas--field-end field) (point))
+            (yas--advance-start-maybe (yas--field-next field) (point)))
+          t)))))
+
+
+;;; Post-command hook:
+;;
+(defun yas--post-command-handler ()
+  "Handles various yasnippet conditions after each command."
+  (when (and yas--watch-auto-fill-backtrace
+             (fboundp 'backtrace--print-frame)
+             (null yas--original-auto-fill-function)
+             (eq auto-fill-function 'yas--auto-fill))
+    (lwarn '(yasnippet auto-fill bug) :error
+           "`yas--original-auto-fill-function' unexpectedly nil! Please report this backtrace\n%S"
+           (with-output-to-string
+             (mapc #'backtrace--print-frame
+                     yas--watch-auto-fill-backtrace)))
+    ;; Don't pop up more than once in a session (still log though).
+    (defvar warning-suppress-types) ; `warnings' is autoloaded by `lwarn'.
+    (add-to-list 'warning-suppress-types '(yasnippet auto-fill bug)))
+  (condition-case err
+      (progn (yas--finish-moving-snippets)
+             (cond ((eq 'undo this-command)
+                    ;;
+                    ;; After undo revival the correct field is sometimes not
+                    ;; restored correctly, this condition handles that
+                    ;;
+                    (let* ((snippet (car (yas-active-snippets)))
+                           (target-field
+                            (and snippet
+                                 (cl-find-if-not
+                                  (lambda (field)
+                                    (yas--field-probably-deleted-p snippet field))
+                                  (remq nil
+                                        (cons (yas--snippet-active-field snippet)
+                                              (yas--snippet-fields snippet)))))))
+                      (when target-field
+                        (yas--move-to-field snippet target-field))))
+                   ((not (yas--undo-in-progress))
+                    ;; When not in an undo, check if we must commit the snippet
+                    ;; (user exited it).
+                    (yas--check-commit-snippet))))
+    ((debug error) (signal (car err) (cdr err)))))
+
+;;; Fancy docs:
+;;
+;; The docstrings for some functions are generated dynamically
+;; depending on the context.
+;;
+(put 'yas-expand  'function-documentation
+     '(yas--expand-from-trigger-key-doc t))
+(defun yas--expand-from-trigger-key-doc (context)
+  "A doc synthesizer for `yas--expand-from-trigger-key-doc'."
+  (let* ((yas-fallback-behavior (and context yas-fallback-behavior))
+         (fallback-description
+          (cond ((eq yas-fallback-behavior 'call-other-command)
+                 (let* ((fallback (yas--keybinding-beyond-yasnippet)))
+                   (or (and fallback
+                            (format "call command `%s'."
+                                    (pp-to-string fallback)))
+                       "do nothing (`yas-expand' doesn't override\nanything).")))
+                ((eq yas-fallback-behavior 'return-nil)
+                 "do nothing.")
+                (t "defer to `yas-fallback-behavior' (which see)."))))
+    (concat "Expand a snippet before point. If no snippet
+expansion is possible, "
+            fallback-description
+            "\n\nOptional argument FIELD is for non-interactive use and is an
+object satisfying `yas--field-p' to restrict the expansion to.")))
+
+(put 'yas-expand-from-keymap 'function-documentation
+     '(yas--expand-from-keymap-doc t))
+(defun yas--expand-from-keymap-doc (context)
+  "A doc synthesizer for `yas--expand-from-keymap-doc'."
+  (add-hook 'temp-buffer-show-hook #'yas--snippet-description-finish-runonce)
+  (concat "Expand/run snippets from keymaps, possibly falling back to original binding.\n"
+          (when (and context (eq this-command 'describe-key))
+            (let* ((vec (this-single-command-keys))
+                   (templates (cl-mapcan (lambda (table)
+                                           (yas--fetch table vec))
+                                         (yas--get-snippet-tables)))
+                   (yas--direct-keymaps nil)
+                   (fallback (key-binding vec)))
+              (concat "In this case, "
+                      (when templates
+                        (concat "these snippets are bound to this key:\n"
+                                (yas--template-pretty-list templates)
+                                "\n\nIf none of these expands, "))
+                      (or (and fallback
+                               (format "fallback `%s' will be called." (pp-to-string fallback)))
+                          "no fallback keybinding is called."))))))
+
+(defun yas--template-pretty-list (templates)
+  (let ((acc)
+        (yas-buffer-local-condition 'always))
+    (dolist (plate templates)
+      (setq acc (concat acc "\n*) "
+                        (propertize (concat "\\\\snippet `" (car plate) "'")
+                                    'yasnippet (cdr plate)))))
+    acc))
+
+(define-button-type 'help-snippet-def
+  :supertype 'help-xref
+  'help-function (lambda (template) (yas--visit-snippet-file-1 template))
+  'help-echo (purecopy "mouse-2, RET: find snippets's definition"))
+
+(defun yas--snippet-description-finish-runonce ()
+  "Final adjustments for the help buffer when snippets are concerned."
+  (yas--create-snippet-xrefs)
+  (remove-hook 'temp-buffer-show-hook
+               #'yas--snippet-description-finish-runonce))
+
+(defun yas--create-snippet-xrefs ()
+  (save-excursion
+    (goto-char (point-min))
+    (while (search-forward-regexp "\\\\\\\\snippet[ \s\t]+`\\([^']+\\)'" nil t)
+      (let ((template (get-text-property (match-beginning 1)
+                                         'yasnippet)))
+        (when template
+          (help-xref-button 1 'help-snippet-def template)
+          (delete-region (match-end 1) (match-end 0))
+          (delete-region (match-beginning 0) (match-beginning 1)))))))
+
+;;; Utils
+
+(defvar yas-verbosity 3
+  "Log level for `yas--message' 4 means trace most anything, 0 means nothing.")
+
+(defun yas--message (level message &rest args)
+  "When LEVEL is at or below `yas-verbosity', log MESSAGE and ARGS."
+  (when (>= yas-verbosity level)
+    (message "%s" (apply #'yas--format message args))))
+
+(defun yas--warning (format-control &rest format-args)
+  (let ((msg (apply #'format format-control format-args)))
+    (display-warning 'yasnippet msg :warning)
+    (yas--message 1 msg)))
+
+(defun yas--format (format-control &rest format-args)
+  (apply #'format (concat "[yas] " format-control) format-args))
+
+
+;;; Unloading
+
+(defvar unload-function-defs-list) ; loadhist.el
+
+(defun yasnippet-unload-function ()
+  "Disable minor modes when calling `unload-feature'."
+  ;; Disable `yas-minor-mode' everywhere it's enabled.
+  (yas-global-mode -1)
+  (save-current-buffer
+    (dolist (buffer (buffer-list))
+      (set-buffer buffer)
+      (when yas-minor-mode
+        (yas-minor-mode -1))))
+  ;; Remove symbol properties of all our functions, this avoids
+  ;; Bug#25088 in Emacs 25.1, where the compiler macro on
+  ;; `cl-defstruct' created functions hang around in the symbol plist
+  ;; and cause errors when loading again (we don't *need* to clean
+  ;; *all* symbol plists, but it's easier than being precise).
+  (dolist (def unload-function-defs-list)
+    (when (eq (car-safe def) 'defun)
+      (setplist (cdr def) nil)))
+  ;; Return nil so that `unload-feature' will take of undefining
+  ;; functions, and changing any buffers using `snippet-mode'.
+  nil)
+
+
+;;; Backward compatibility to yasnippet <= 0.7
+
+(defun yas-initialize ()
+  "For backward compatibility, enable `yas-minor-mode' globally."
+  (declare (obsolete "Use (yas-global-mode 1) instead." "0.8"))
+  (yas-global-mode 1))
+
+(defvar yas--backported-syms '(;; `defcustom's
+                             ;;
+                             yas-snippet-dirs
+                             yas-prompt-functions
+                             yas-indent-line
+                             yas-also-auto-indent-first-line
+                             yas-snippet-revival
+                             yas-triggers-in-field
+                             yas-fallback-behavior
+                             yas-choose-keys-first
+                             yas-choose-tables-first
+                             yas-use-menu
+                             yas-trigger-symbol
+                             yas-wrap-around-region
+                             yas-good-grace
+                             yas-visit-from-menu
+                             yas-expand-only-for-last-commands
+                             yas-field-highlight-face
+
+                             ;; these vars can be customized as well
+                             ;;
+                             yas-keymap
+                             yas-verbosity
+                             yas-extra-modes
+                             yas-key-syntaxes
+                             yas-after-exit-snippet-hook
+                             yas-before-expand-snippet-hook
+                             yas-buffer-local-condition
+                             yas-dont-activate
+
+                             ;; prompting functions
+                             ;;
+                             yas-x-prompt
+                             yas-ido-prompt
+                             yas-no-prompt
+                             yas-completing-prompt
+                             yas-dropdown-prompt
+
+                             ;; interactive functions
+                             ;;
+                             yas-expand
+                             yas-minor-mode
+                             yas-global-mode
+                             yas-direct-keymaps-reload
+                             yas-minor-mode-on
+                             yas-load-directory
+                             yas-reload-all
+                             yas-compile-directory
+                             yas-recompile-all
+                             yas-about
+                             yas-expand-from-trigger-key
+                             yas-expand-from-keymap
+                             yas-insert-snippet
+                             yas-visit-snippet-file
+                             yas-new-snippet
+                             yas-load-snippet-buffer
+                             yas-tryout-snippet
+                             yas-describe-tables
+                             yas-next-field-or-maybe-expand
+                             yas-next-field
+                             yas-prev-field
+                             yas-abort-snippet
+                             yas-exit-snippet
+                             yas-exit-all-snippets
+                             yas-skip-and-clear-or-delete-char
+                             yas-initialize
+
+                             ;; symbols that I "exported" for use
+                             ;; in snippets and hookage
+                             ;;
+                             yas-expand-snippet
+                             yas-define-snippets
+                             yas-define-menu
+                             yas-snippet-beg
+                             yas-snippet-end
+                             yas-modified-p
+                             yas-moving-away-p
+                             yas-substr
+                             yas-choose-value
+                             yas-key-to-value
+                             yas-throw
+                             yas-verify-value
+                             yas-field-value
+                             yas-text
+                             yas-selected-text
+                             yas-default-from-field
+                             yas-inside-string
+                             yas-unimplemented
+                             yas-define-condition-cache
+                             yas-hippie-try-expand
+
+                             ;; debug definitions
+                             ;; yas-debug-snippet-vars
+                             ;; yas-exterminate-package
+                             ;; yas-debug-test
+
+                             ;; testing definitions
+                             ;; yas-should-expand
+                             ;; yas-should-not-expand
+                             ;; yas-mock-insert
+                             ;; yas-make-file-or-dirs
+                             ;; yas-variables
+                             ;; yas-saving-variables
+                             ;; yas-call-with-snippet-dirs
+                             ;; yas-with-snippet-dirs
+)
+  "Backported yasnippet symbols.
+
+They are mapped to \"yas/*\" variants.")
+
+(when yas-alias-to-yas/prefix-p
+  (dolist (sym yas--backported-syms)
+    (let ((backported (intern (replace-regexp-in-string "\\`yas-" "yas/" (symbol-name sym)))))
+      (when (boundp sym)
+        (make-obsolete-variable backported sym "yasnippet 0.8")
+        (defvaralias backported sym))
+      (when (fboundp sym)
+        (make-obsolete backported sym "yasnippet 0.8")
+        (defalias backported sym))))
+  (make-obsolete 'yas/root-directory 'yas-snippet-dirs "yasnippet 0.8")
+  (defvaralias 'yas/root-directory 'yas-snippet-dirs))
+
+(defvar yas--exported-syms
+  (let (exported)
+    (mapatoms (lambda (atom)
+                (if (and (or (and (boundp atom)
+                                  (not (get atom 'byte-obsolete-variable)))
+                             (and (fboundp atom)
+                                  (not (get atom 'byte-obsolete-info))))
+                         (string-match-p "\\`yas-[^-]" (symbol-name atom)))
+                    (push atom exported))))
+    exported)
+  "Exported yasnippet symbols.
+
+i.e. the ones with \"yas-\" single dash prefix. I will try to
+keep them in future yasnippet versions and other elisp libraries
+can more or less safely rely upon them.")
+
+
+(provide 'yasnippet)
+;; Local Variables:
+;; coding: utf-8
+;; indent-tabs-mode: nil
+;; End:
+;;; yasnippet.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/yasnippet-20180620.1750/yasnippet.elc b/configs/shared/emacs/.emacs.d/elpa/yasnippet-20180620.1750/yasnippet.elc
new file mode 100644
index 0000000000..e05ac0bba8
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/yasnippet-20180620.1750/yasnippet.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/elpa/zen-mode-20170723.139/zen-mode-autoloads.el b/configs/shared/emacs/.emacs.d/elpa/zen-mode-20170723.139/zen-mode-autoloads.el
new file mode 100644
index 0000000000..c7788fa844
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/zen-mode-20170723.139/zen-mode-autoloads.el
@@ -0,0 +1,22 @@
+;;; zen-mode-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
+
+;;;### (autoloads nil "zen-mode" "zen-mode.el" (23377 61298 712071
+;;;;;;  54000))
+;;; Generated autoloads from zen-mode.el
+
+(autoload 'zen-mode "zen-mode" "\
+zen-mode is a distraction free editing mode for Emacs
+
+\(fn &optional ARG)" t nil)
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; End:
+;;; zen-mode-autoloads.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/zen-mode-20170723.139/zen-mode-pkg.el b/configs/shared/emacs/.emacs.d/elpa/zen-mode-20170723.139/zen-mode-pkg.el
new file mode 100644
index 0000000000..71436ec337
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/zen-mode-20170723.139/zen-mode-pkg.el
@@ -0,0 +1,2 @@
+;;; -*- no-byte-compile: t -*-
+(define-package "zen-mode" "20170723.139" "Zen Editing Mode" '((emacs "24.3")) :authors '(("Akilan Elango <akilan1997 [at] gmail.com>")) :maintainer '("Akilan Elango <akilan1997 [at] gmail.com>") :url "https://github.com/aki237/zen-mode")
diff --git a/configs/shared/emacs/.emacs.d/elpa/zen-mode-20170723.139/zen-mode.el b/configs/shared/emacs/.emacs.d/elpa/zen-mode-20170723.139/zen-mode.el
new file mode 100644
index 0000000000..ed9acb7ea0
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/zen-mode-20170723.139/zen-mode.el
@@ -0,0 +1,203 @@
+;;; zen-mode.el --- Zen Editing Mode
+
+;; Copyright (C) 2017 Akilan Elango
+
+;; Author: Akilan Elango <akilan1997 [at] gmail.com>
+;; Keywords: convenience
+;; Package-Version: 20170723.139
+;; X-URL: https://github.com/aki237/zen-mode
+;; URL: https://github.com/aki237/zen-mode
+;; Version: 0.0.1
+;; Package-Requires: ((emacs "24.3"))
+
+;; This program 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.
+
+;; This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;; Zen mode for Emacs is a distraction free editing mode for Emacs.
+;;
+;;; Installation:
+;;
+;;   (require 'zen-mode)
+;;
+;;; Use:
+;; This is used to start a distraction free editing session in Emacs like in
+;; Sublime Text.
+;;
+;;; Code:
+
+;; require
+
+
+;; variables
+(defvar zen-mode-disable-mode-line t
+  "Zen mode option to hide the mode line.  Set true to hide the mode line in Zen-mode.")
+
+;; local variables
+(defvar-local zen-run-mode nil
+  "zen-run-mode variable is to set state of whether zen mode is enabled in the current buffer"
+  )
+
+(defvar-local zen-mode-margin-width (/ (/ (display-pixel-width) (/ (window-pixel-width) (window-width))) 5)
+  "Zen mode option to specify the margin width."
+  )
+
+(defvar-local zen-mode-line-cache nil
+  "zen-mode-line-cache variable is used to save the modeline format content for future when it is disabled"
+  )
+
+(defvar-local zen-menubar-state nil
+  "zen-menubar-state variable is used to save whether menu-bar-mode is enabled before entering the zen mode"
+  )
+
+(defvar-local zen-toolbar-state nil
+  "zen-toolbar-state variable is used to save whether tool-bar-mode is enabled before entering the zen mode"
+  )
+
+(defvar-local zen-linum-state nil
+  "zen-linum-state variable is used to save whether linum-mode is enabled before entering the zen mode"
+  )
+
+(defvar-local zen-blink-cursor-state nil
+  "zen-blink-cursor-state variable is used to save whether blink-cursor-mode is enabled before entering the zen mode"
+  )
+
+(defvar-local zen-lm-state 0
+  "zm-lm-state variable is used to store the left margin width before the activation of zen-mode"
+  )
+
+(defvar-local zen-rm-state 0
+  "zm-rm-state variable is used to store the right margin width before the activation of zen-mode"
+  )
+
+
+(defvar-local zen-lf-state 0
+  "zm-lf-state variable is used to store the left fringe width before the activation of zen-mode"
+  )
+
+(defvar-local zen-rf-state 0
+  "zm-rf-state variable is used to store the right fringe width before the activation of zen-mode"
+  )
+
+(defvar-local zen-fullscreen-state nil
+  "zm-fullscreen-state variable is used to store fullscreen state before the activation of zen-mode"
+  )
+
+;;;###autoload
+(define-minor-mode zen-mode
+  "zen-mode is a distraction free editing mode for Emacs"
+  :lighter " Zen"
+  :keymap (let ((map (make-sparse-keymap)))
+            (define-key map (kbd "C-c C-<") 'zen-mode-increase-margin-width)
+            (define-key map (kbd "C-c C->") 'zen-mode-decrease-margin-width)
+            map)
+  (zen-run)
+  )
+
+;; functions
+(defun zen-run()
+  "zen-run is a lisp function which activates and deactivates the zen-mode"
+  (if zen-run-mode
+      (progn
+        (message "Distraction free disabled")
+        (setq window-size-change-functions (remove 'zen-mode-refresh-buffer 'window-size-change-functions))
+	(if zen-linum-state
+	    (linum-mode 1))
+
+	(if zen-blink-cursor-state
+          (blink-cursor-mode 1))
+
+	(if zen-mode-disable-mode-line
+          (progn
+            (setq mode-line-format zen-mode-line-cache)))
+
+	(if zen-toolbar-state
+	    (tool-bar-mode 1))
+
+	(if zen-menubar-state
+	    (menu-bar-mode 1))
+	(setq left-fringe-width zen-lf-state)
+	(setq right-fringe-width zen-rf-state)
+	(setq left-margin-width zen-lm-state)
+        (setq right-margin-width zen-rm-state)
+        (set-frame-parameter nil 'fullscreen 'zen-fullscreen-state)
+        (set-window-buffer nil (current-buffer))
+        (setq zen-run-mode nil))
+    (progn
+      (if zen-mode-disable-mode-line
+          (progn
+            (setq zen-mode-line-cache mode-line-format)
+            (setq mode-line-format nil)))
+
+      (setq zen-menubar-state (and (boundp 'menu-bar-mode) menu-bar-mode))
+
+      (setq zen-toolbar-state (and (boundp 'tool-bar-mode) tool-bar-mode))
+
+      (setq zen-linum-state (and (boundp 'linum-mode) linum-mode))
+
+      (setq zen-blink-cursor-state (and (boundp 'blink-cursor-mode) blink-cursor-mode))
+
+      (setq zen-lm-state left-margin-width)
+
+      (setq zen-rm-state right-margin-width)
+
+      (setq zen-lf-state left-fringe-width)
+
+      (setq zen-rf-state right-fringe-width)
+
+      (setq zen-fullscreen-state (frame-parameter (selected-frame) 'fullscreen))
+
+      (message "Distraction free enabled")
+      (add-to-list 'window-size-change-functions 'zen-mode-refresh-buffer)
+      (set-frame-parameter nil 'fullscreen 'fullboth)
+      (linum-mode -1)
+      (setq right-fringe-width 0)
+      (setq left-fringe-width 0)
+      (menu-bar-mode -1)
+      (tool-bar-mode -1)
+      (blink-cursor-mode -1)
+      (zen-mode-set-margins)
+      (setq zen-run-mode t))))
+
+(defun zen-mode-increase-margin-width()
+  "zen-mode-increase-margin-width is a interactive lisp function to increase the margin width in zen-mode (by 5 units)."
+  (interactive)
+  (setq zen-mode-margin-width (+ zen-mode-margin-width 5))
+  (zen-mode-set-margins)
+  )
+
+(defun zen-mode-decrease-margin-width()
+  "zen-mode-increase-margin-width is a interactive lisp function to increase the margin width in zen-mode (by 5 units)."
+  (interactive)
+  (setq zen-mode-margin-width (+ zen-mode-margin-width -5))
+  (zen-mode-set-margins)
+  )
+
+(defun zen-mode-set-margins()
+  "zen-mode-set-margins is a lisp function to set the margin width (both left and right)."
+  (setq left-margin-width zen-mode-margin-width)
+  (setq right-margin-width zen-mode-margin-width)
+  (set-window-buffer nil (current-buffer))
+  )
+
+(defun zen-mode-refresh-buffer(frame)
+  "zen-mode-refresh-buffer is a lisp function to refresh the buffer's margin width when window is resized"
+  (setq zen-mode-margin-width (/ (/ (display-pixel-width) (/ (window-pixel-width) (window-width))) 5))
+  (zen-mode-set-margins)
+  )
+
+(provide 'zen-mode)
+
+;; coding: utf-8
+;; End:
+;;; zen-mode.el ends here
diff --git a/configs/shared/emacs/.emacs.d/elpa/zen-mode-20170723.139/zen-mode.elc b/configs/shared/emacs/.emacs.d/elpa/zen-mode-20170723.139/zen-mode.elc
new file mode 100644
index 0000000000..98647682ac
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/elpa/zen-mode-20170723.139/zen-mode.elc
Binary files differdiff --git a/configs/shared/emacs/.emacs.d/init.el b/configs/shared/emacs/.emacs.d/init.el
new file mode 100644
index 0000000000..8f0deff079
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/init.el
@@ -0,0 +1,42 @@
+
+;; Added by Package.el.  This must come before configurations of
+;; installed packages.  Don't delete this line.  If you don't want it,
+;; just comment it out by adding a semicolon to the start of the line.
+;; You may delete these explanatory comments.
+(package-initialize)
+
+(require 'wpc-package "~/.emacs.d/wpc/packages/wpc-package.el")
+
+;; third-party libraries
+(use-package dash)
+(use-package dash-functional)
+(use-package s)
+(use-package f)
+(use-package request)
+(use-package pcre2el)
+
+;; load order is intentional
+(require 'variables)
+(require 'wpc-misc)
+
+;; my libraries
+(require 'functions)
+(require 'string-functions)
+(require 'macros)
+(require 'casing)
+
+(require 'wpc-ui)
+(require 'wpc-keybindings)
+(require 'wpc-dired)
+(require 'wpc-terminal)
+(require 'wpc-org)
+(require 'wpc-slack)
+(require 'wpc-company)
+(require 'wpc-flycheck)
+(require 'wpc-git)
+(require 'wpc-docker)
+(require 'wpc-lisp)
+(require 'wpc-haskell)
+(require 'wpc-nix)
+(require 'wpc-clojure)
+(require 'wpc-javascript)
diff --git a/configs/shared/emacs/.emacs.d/network-security.data b/configs/shared/emacs/.emacs.d/network-security.data
new file mode 100644
index 0000000000..e1fd47754e
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/network-security.data
@@ -0,0 +1,6 @@
+(
+ (:id "sha1:85b31c268009209a8d3c5387033b219264f7e62b" :fingerprint "sha1:1f:8f:9d:5a:d6:fb:04:c1:1f:5d:2a:00:3c:31:90:36:9f:2a:bd:56" :host "melpa.org:443" :conditions (:insecure :unknown-ca :invalid))
+ (:id "sha1:dac7e9a2956c9d53e34b09415e2a7fa64d572971" :fingerprint "sha1:55:9f:fc:f0:dc:0e:3a:f2:cb:36:e9:f4:58:38:6c:0e:90:45:a5:f6" :host "framagit.org:443" :conditions (:insecure :unknown-ca :invalid))
+ (:id "sha1:5cce342a9a99ff6632dc081a41f5f4a28e8e10fc" :fingerprint "sha1:c9:4f:05:0e:50:48:da:fd:71:ee:ca:36:bf:ab:10:0a:52:70:16:99" :host "raw.githubusercontent.com:443" :conditions (:insecure :unknown-ca :invalid))
+ (:id "sha1:4fb4a286e3aa473246ce0c62c400926f660802d7" :fingerprint "sha1:c9:4f:05:0e:50:48:da:fd:71:ee:ca:36:bf:ab:10:0a:52:70:16:99" :host "raw.github.com:443" :conditions (:insecure :unknown-ca :invalid))
+)
diff --git a/configs/shared/emacs/.emacs.d/open-from-iterm.sh b/configs/shared/emacs/.emacs.d/open-from-iterm.sh
new file mode 100755
index 0000000000..fdb4257965
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/open-from-iterm.sh
@@ -0,0 +1,37 @@
+#!/bin/bash
+
+# To set this up, open iTerm2 -> Preferences -> Profiles -> Advanced
+# In the "Semantic History" section, choose "Always run command..." from the
+# dropdown and set the input text to:
+# `~/dotfiles/emacs.d/open-from-iterm.sh \1`
+
+# Alias applications since $PATH is unavailable
+emacs=/usr/local/bin/emacsclient
+grep=/usr/local/bin/ggrep
+tmux=/usr/local/bin/tmux
+realpath=/Users/wpcarro/.nix-profile/bin/realpath
+
+e() {
+  # Useful debugger when paired with `tail -f /tmp/debug.log`
+  echo "$@" >>/tmp/debug.log
+}
+
+# Need to query Tmux since iTerm's \5 variable doesn't work as expected with
+# Tmux.
+pwd=$($tmux display -pF '#{pane_current_path}')
+cd "$pwd" || exit
+path=$($realpath "$1")
+
+# This is a bit of a hack, but we cannot rely on iTerm to regex our paths
+file=$($grep -P -o '^[^:]+' <<<"$path")
+number=$($grep -P -o '(?<=:)[0-9]+(?=:[0-9]+:$)' <<<"$path")
+
+# Debugging
+e "file:   $file"
+e "number: $number"
+
+if ! [ -z "$number" ]; then
+  $emacs -n -e "(find-file \"$file\")" "(goto-line $number)" "(call-interactively #'evil-scroll-line-to-center)"
+else
+  $emacs -n -e "(find-file \"$file\")"
+fi
diff --git a/configs/shared/emacs/.emacs.d/projectile-bookmarks.eld b/configs/shared/emacs/.emacs.d/projectile-bookmarks.eld
new file mode 100644
index 0000000000..d727fa9b78
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/projectile-bookmarks.eld
@@ -0,0 +1 @@
+("~/programming/nixify/" "~/urbint/grid/" "~/Dropbox/dotfiles/" "~/programming/nixpkgs/" "~/programming/nix-config/" "~/urbint/meta/")
\ No newline at end of file
diff --git a/configs/shared/emacs/.emacs.d/quelpa/build/evil-text-objects-haskell b/configs/shared/emacs/.emacs.d/quelpa/build/evil-text-objects-haskell
new file mode 160000
+Subproject 82a7a42a10dcb04b2962793848034499d2ef144
diff --git a/configs/shared/emacs/.emacs.d/quelpa/build/evil-text-objects-javascript b/configs/shared/emacs/.emacs.d/quelpa/build/evil-text-objects-javascript
new file mode 160000
+Subproject 227edcca3eb32fefdb8415c0f3b4eee368f167f
diff --git a/configs/shared/emacs/.emacs.d/quelpa/build/quelpa b/configs/shared/emacs/.emacs.d/quelpa/build/quelpa
new file mode 160000
+Subproject 571ee896e00fd0b90373b94bf2689e1b9741a60
diff --git a/configs/shared/emacs/.emacs.d/quelpa/build/zen-mode b/configs/shared/emacs/.emacs.d/quelpa/build/zen-mode
new file mode 160000
+Subproject 1ce451577eb62a41ec243b7e29a63393ee4530e
diff --git a/configs/shared/emacs/.emacs.d/quelpa/cache b/configs/shared/emacs/.emacs.d/quelpa/cache
new file mode 100644
index 0000000000..f94d271852
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/quelpa/cache
@@ -0,0 +1 @@
+((evil-text-objects-haskell :fetcher github :repo "urbint/evil-text-objects-haskell") (evil-text-objects-javascript :fetcher github :repo "urbint/evil-text-objects-javascript") (general :repo "noctuid/general.el" :fetcher github) (quelpa :url "https://framagit.org/steckerhalter/quelpa.git" :fetcher git) (zen-mode :fetcher github :repo "aki237/zen-mode"))
\ No newline at end of file
diff --git a/configs/shared/emacs/.emacs.d/quelpa/melpa b/configs/shared/emacs/.emacs.d/quelpa/melpa
new file mode 160000
+Subproject de20db067590624bbd2ca5a7a537b7f11ada84f
diff --git a/configs/shared/emacs/.emacs.d/smex-items b/configs/shared/emacs/.emacs.d/smex-items
new file mode 100644
index 0000000000..60e49e9700
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/smex-items
@@ -0,0 +1,69 @@
+
+;; ----- smex-history -----
+(
+ magit-blame
+ find-file-literally
+ find-file
+ rename-file
+ mkdir
+ prettier-js-mode
+ lsp-rename
+)
+
+;; ----- smex-data -----
+(
+ (package-install . 8)
+ (magit-blame . 20)
+ (smerge-keep-all . 5)
+ (haskell-mode-stylish-buffer . 2)
+ (git-timemachine . 6)
+ (org-next-link . 2)
+ (calc . 2)
+ (intero-mode . 9)
+ (package-refresh-contents . 4)
+ (flymd-flyit . 1)
+ (package-delete . 2)
+ (git-timemachine-mode . 4)
+ (intero-targets . 3)
+ (disable-theme . 7)
+ (enable-theme . 1)
+ (load-theme . 7)
+ (prog-mode . 2)
+ (haskell-mode . 4)
+ (company-mode . 1)
+ (auto-fill-mode . 2)
+ (magit-blame-quit . 1)
+ (intero-restart . 1)
+ (lsp-mode . 11)
+ (lsp-ui-mode . 10)
+ (xref-find-definitions . 12)
+ (xref-find-references . 4)
+ (lsp-ui-imenu . 1)
+ (lsp-rename . 4)
+ (describe-mode . 3)
+ (lsp-haskell-enable . 3)
+ (flycheck-mode . 4)
+ (lsp-ui-peek-find-references . 1)
+ (lsp-ui-peek-find-definitions . 1)
+ (xref-find-definitions-other-window . 1)
+ (find-file . 26)
+ (nix-mode . 15)
+ (erc-spelling-mode . 2)
+ (flyspell-mode . 1)
+ (lsp-info-under-point . 1)
+ (lsp-restart-workspace . 2)
+ (flycheck-list-errors . 1)
+ (lsp-javascript-flow-enable . 4)
+ (xref-find-apropos . 1)
+ (prettier-js-mode . 4)
+ (mkdir . 4)
+ (nix-instantiate . 1)
+ (rename-file . 2)
+ (find-file-literally . 4)
+ (smerge-keep-mine . 1)
+ (smerge-keep-other . 1)
+ (add-node-modules-path . 1)
+ (lsp-ui-find-next-reference . 1)
+ (lsp-goto-type-definition . 1)
+ (flow-minor-jump-to-definition . 1)
+)
diff --git a/configs/shared/emacs/.emacs.d/snippets/emacs-lisp-mode/elisp-module-docs b/configs/shared/emacs/.emacs.d/snippets/emacs-lisp-mode/elisp-module-docs
new file mode 100644
index 0000000000..8ea7b8f077
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/snippets/emacs-lisp-mode/elisp-module-docs
@@ -0,0 +1,11 @@
+# -*- mode: snippet -*-
+# name: Elisp module docs
+# key: emd
+# --
+;;; `(-> (buffer-file-name) f-filename)` --- $2 -*- lexical-binding: t -*-
+;; Author: William Carroll <wpcarro@gmail.com>
+
+;;; Commentary:
+;; $3
+
+;;; Code:
\ No newline at end of file
diff --git a/configs/shared/emacs/.emacs.d/snippets/emacs-lisp-mode/provide-footer b/configs/shared/emacs/.emacs.d/snippets/emacs-lisp-mode/provide-footer
new file mode 100644
index 0000000000..2a0bcc33f7
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/snippets/emacs-lisp-mode/provide-footer
@@ -0,0 +1,6 @@
+# -*- mode: snippet -*-
+# name: Provide footer
+# key: elf
+# --
+(provide '`(-> (buffer-file-name) f-filename f-no-ext)`)
+;;; `(-> (buffer-file-name) f-filename)` ends here
\ No newline at end of file
diff --git a/configs/shared/emacs/.emacs.d/snippets/haskell-mode/derive-safe-copy b/configs/shared/emacs/.emacs.d/snippets/haskell-mode/derive-safe-copy
new file mode 100644
index 0000000000..95f7d9deec
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/snippets/haskell-mode/derive-safe-copy
@@ -0,0 +1,5 @@
+# -*- mode: snippet -*-
+# name: Derive Safe Copy
+# key: dsc
+# --
+deriveSafeCopy 0 'base ''$1
\ No newline at end of file
diff --git a/configs/shared/emacs/.emacs.d/snippets/haskell-mode/import-qualified b/configs/shared/emacs/.emacs.d/snippets/haskell-mode/import-qualified
new file mode 100644
index 0000000000..4c4db62a8a
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/snippets/haskell-mode/import-qualified
@@ -0,0 +1,5 @@
+# -*- mode: snippet -*-
+# name: Import qualified
+# key: iq
+# --
+import qualified $1 as $2
\ No newline at end of file
diff --git a/configs/shared/emacs/.emacs.d/snippets/haskell-mode/instance-defn b/configs/shared/emacs/.emacs.d/snippets/haskell-mode/instance-defn
new file mode 100644
index 0000000000..10d194ce41
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/snippets/haskell-mode/instance-defn
@@ -0,0 +1,6 @@
+# -*- mode: snippet -*-
+# name: Instance
+# key: inst
+# --
+instance $1 where
+  $2 = $3
\ No newline at end of file
diff --git a/configs/shared/emacs/.emacs.d/snippets/haskell-mode/language-extension b/configs/shared/emacs/.emacs.d/snippets/haskell-mode/language-extension
new file mode 100644
index 0000000000..9d6084acb4
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/snippets/haskell-mode/language-extension
@@ -0,0 +1,5 @@
+# -*- mode: snippet -*-
+# name: language extension
+# key: lang
+# --
+{-# LANGUAGE $1 #-}
\ No newline at end of file
diff --git a/configs/shared/emacs/.emacs.d/snippets/haskell-mode/separator b/configs/shared/emacs/.emacs.d/snippets/haskell-mode/separator
new file mode 100644
index 0000000000..1ab0d762b6
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/snippets/haskell-mode/separator
@@ -0,0 +1,5 @@
+# -*- mode: snippet -*-
+# name: Separator
+# key: -
+# --
+--------------------------------------------------------------------------------
\ No newline at end of file
diff --git a/configs/shared/emacs/.emacs.d/snippets/haskell-mode/undefined b/configs/shared/emacs/.emacs.d/snippets/haskell-mode/undefined
new file mode 100644
index 0000000000..7609f801f2
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/snippets/haskell-mode/undefined
@@ -0,0 +1,5 @@
+# -*- mode: snippet -*-
+# name: Undefiend
+# key: nd
+# --
+undefined
\ No newline at end of file
diff --git a/configs/shared/emacs/.emacs.d/snippets/org-mode/code-snippet b/configs/shared/emacs/.emacs.d/snippets/org-mode/code-snippet
new file mode 100644
index 0000000000..4215b15992
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/snippets/org-mode/code-snippet
@@ -0,0 +1,7 @@
+# -*- mode: snippet -*-
+# name: Code Snippet
+# key: src
+# --
+#+BEGIN_SRC $1
+$2
+#+END_SRC
\ No newline at end of file
diff --git a/configs/shared/emacs/.emacs.d/snippets/org-mode/href b/configs/shared/emacs/.emacs.d/snippets/org-mode/href
new file mode 100644
index 0000000000..ac65ea2e49
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/snippets/org-mode/href
@@ -0,0 +1,5 @@
+# -*- mode: snippet -*-
+# name: Org mode URL
+# key: href
+# --
+[[$1][$2]]
\ No newline at end of file
diff --git a/configs/shared/emacs/.emacs.d/snippets/rjsx-mode/action-extractor b/configs/shared/emacs/.emacs.d/snippets/rjsx-mode/action-extractor
new file mode 100644
index 0000000000..62834a29ab
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/snippets/rjsx-mode/action-extractor
@@ -0,0 +1,5 @@
+# -*- mode: snippet -*-
+# name: exactness
+# key: $x
+# --
+$Exact<$Call<typeof $1>>
\ No newline at end of file
diff --git a/configs/shared/emacs/.emacs.d/snippets/rjsx-mode/console-log b/configs/shared/emacs/.emacs.d/snippets/rjsx-mode/console-log
new file mode 100644
index 0000000000..82ec3fd8e3
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/snippets/rjsx-mode/console-log
@@ -0,0 +1,5 @@
+# -*- mode: snippet -*-
+# name: Console.log helper
+# key: clg
+# --
+console.log($1)
\ No newline at end of file
diff --git a/configs/shared/emacs/.emacs.d/snippets/rjsx-mode/const-defn b/configs/shared/emacs/.emacs.d/snippets/rjsx-mode/const-defn
new file mode 100644
index 0000000000..8e35e61fc2
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/snippets/rjsx-mode/const-defn
@@ -0,0 +1,5 @@
+# -*- mode: snippet -*-
+# name: const definition
+# key: cn
+# --
+const $1 = '$2'
\ No newline at end of file
diff --git a/configs/shared/emacs/.emacs.d/snippets/rjsx-mode/const-function b/configs/shared/emacs/.emacs.d/snippets/rjsx-mode/const-function
new file mode 100644
index 0000000000..13f2018f22
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/snippets/rjsx-mode/const-function
@@ -0,0 +1,7 @@
+# -*- mode: snippet -*-
+# name: const function
+# key: cfn
+# --
+const $1 = ($2) => {
+  $3
+}
\ No newline at end of file
diff --git a/configs/shared/emacs/.emacs.d/snippets/rjsx-mode/destructure-const b/configs/shared/emacs/.emacs.d/snippets/rjsx-mode/destructure-const
new file mode 100644
index 0000000000..2a52c57c75
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/snippets/rjsx-mode/destructure-const
@@ -0,0 +1,5 @@
+# -*- mode: snippet -*-
+# name: Destructuring a const
+# key: cds
+# --
+const { $1 } = $2
\ No newline at end of file
diff --git a/configs/shared/emacs/.emacs.d/snippets/rjsx-mode/fat-arrow b/configs/shared/emacs/.emacs.d/snippets/rjsx-mode/fat-arrow
new file mode 100644
index 0000000000..187a2efc5a
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/snippets/rjsx-mode/fat-arrow
@@ -0,0 +1,5 @@
+# -*- mode: snippet -*-
+# name: Fat arrow function
+# key: fa
+# --
+=>
\ No newline at end of file
diff --git a/configs/shared/emacs/.emacs.d/snippets/rjsx-mode/fat-arrow-function b/configs/shared/emacs/.emacs.d/snippets/rjsx-mode/fat-arrow-function
new file mode 100644
index 0000000000..694914a83c
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/snippets/rjsx-mode/fat-arrow-function
@@ -0,0 +1,7 @@
+# -*- mode: snippet -*-
+# name: Fat arrow function
+# key: faf
+# --
+() => {
+  $1
+}
\ No newline at end of file
diff --git a/configs/shared/emacs/.emacs.d/snippets/rjsx-mode/import-destructured b/configs/shared/emacs/.emacs.d/snippets/rjsx-mode/import-destructured
new file mode 100644
index 0000000000..ded3ce163a
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/snippets/rjsx-mode/import-destructured
@@ -0,0 +1,5 @@
+# -*- mode: snippet -*-
+# name: Import destructured
+# key: ids
+# --
+import { $1 } from '$2'
\ No newline at end of file
diff --git a/configs/shared/emacs/.emacs.d/snippets/rjsx-mode/import-react b/configs/shared/emacs/.emacs.d/snippets/rjsx-mode/import-react
new file mode 100644
index 0000000000..0463f5cd55
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/snippets/rjsx-mode/import-react
@@ -0,0 +1,5 @@
+# -*- mode: snippet -*-
+# name: Import React dependency (ES6)
+# key: ir
+# --
+import React from 'react'
diff --git a/configs/shared/emacs/.emacs.d/snippets/rjsx-mode/import-type b/configs/shared/emacs/.emacs.d/snippets/rjsx-mode/import-type
new file mode 100644
index 0000000000..fcd51f687b
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/snippets/rjsx-mode/import-type
@@ -0,0 +1,5 @@
+# -*- mode: snippet -*-
+# name: import type
+# key: ixt
+# --
+import type { $1 } from '$2'
\ No newline at end of file
diff --git a/configs/shared/emacs/.emacs.d/snippets/rjsx-mode/import-x-from-y b/configs/shared/emacs/.emacs.d/snippets/rjsx-mode/import-x-from-y
new file mode 100644
index 0000000000..09fa6df505
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/snippets/rjsx-mode/import-x-from-y
@@ -0,0 +1,5 @@
+# -*- mode: snippet -*-
+# name: import x from y
+# key: ix
+# --
+import $1 from '$2'
\ No newline at end of file
diff --git a/configs/shared/emacs/.emacs.d/snippets/rjsx-mode/import-y b/configs/shared/emacs/.emacs.d/snippets/rjsx-mode/import-y
new file mode 100644
index 0000000000..9f550e300d
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/snippets/rjsx-mode/import-y
@@ -0,0 +1,5 @@
+# -*- mode: snippet -*-
+# name: import y
+# key: iy
+# --
+import '$1'
\ No newline at end of file
diff --git a/configs/shared/emacs/.emacs.d/snippets/rjsx-mode/jest-describe-test b/configs/shared/emacs/.emacs.d/snippets/rjsx-mode/jest-describe-test
new file mode 100644
index 0000000000..ed382d4f74
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/snippets/rjsx-mode/jest-describe-test
@@ -0,0 +1,10 @@
+# -*- mode: snippet -*-
+# name: Jest describe/test block
+# key: dsc
+# --
+describe('$1', () => {
+  test('$2', () => {
+
+    expect($3).toEqual($4)
+  })
+})
\ No newline at end of file
diff --git a/configs/shared/emacs/.emacs.d/snippets/rjsx-mode/jest-test b/configs/shared/emacs/.emacs.d/snippets/rjsx-mode/jest-test
new file mode 100644
index 0000000000..12ca2e786d
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/snippets/rjsx-mode/jest-test
@@ -0,0 +1,7 @@
+# -*- mode: snippet -*-
+# name: Jest / Jasmine test
+# key: tst
+# --
+test('$1', () => {
+  expect($2).toBe($3)
+})
\ No newline at end of file
diff --git a/configs/shared/emacs/.emacs.d/snippets/rjsx-mode/react-class-component b/configs/shared/emacs/.emacs.d/snippets/rjsx-mode/react-class-component
new file mode 100644
index 0000000000..f2a93a31d9
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/snippets/rjsx-mode/react-class-component
@@ -0,0 +1,11 @@
+# -*- mode: snippet -*-
+# name: React class extends
+# key: clz
+# --
+class $1 extends React.Component {
+  render() {
+    $2
+  }
+}
+
+export default $1
\ No newline at end of file
diff --git a/configs/shared/emacs/.emacs.d/snippets/rjsx-mode/redux-action b/configs/shared/emacs/.emacs.d/snippets/rjsx-mode/redux-action
new file mode 100644
index 0000000000..d196f8ee80
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/snippets/rjsx-mode/redux-action
@@ -0,0 +1,5 @@
+# -*- mode: snippet -*-
+# name: redux-action
+# key: rax
+# --
+export const ${1:$$(lower->caps yas-text)} = '`(downcase (buffer-dirname))`/${1:$(caps->kebab yas-text)}'
\ No newline at end of file
diff --git a/configs/shared/emacs/.emacs.d/snippets/rjsx-mode/typed-redux-action b/configs/shared/emacs/.emacs.d/snippets/rjsx-mode/typed-redux-action
new file mode 100644
index 0000000000..a4ef0181cd
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/snippets/rjsx-mode/typed-redux-action
@@ -0,0 +1,5 @@
+# -*- mode: snippet -*-
+# name: typed-redux-action
+# key: trax
+# --
+export const ${1:$$(lower->caps yas-text)}: '`(downcase (buffer-dirname))`/${1:$(caps->kebab yas-text)}' = '`(downcase (buffer-dirname))`/${1:$(caps->kebab yas-text)}'
\ No newline at end of file
diff --git a/configs/shared/emacs/.emacs.d/vendor/org-clubhouse.el b/configs/shared/emacs/.emacs.d/vendor/org-clubhouse.el
new file mode 100644
index 0000000000..ba1f004a24
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/vendor/org-clubhouse.el
@@ -0,0 +1,365 @@
+;;; private/grfn/org-clubhouse.el
+
+(require 'dash)
+(require 'dash-functional)
+(require 's)
+(require 'org)
+(require 'org-element)
+(require 'cl)
+
+;;;
+;;; Configuration
+;;;
+
+(defvar org-clubhouse-auth-token nil
+  "Authorization token for the Clubhouse API")
+
+(defvar org-clubhouse-team-name nil
+  "Team name to use in links to Clubhouse
+ie https://app.clubhouse.io/<TEAM_NAME>/stories")
+
+(defvar org-clubhouse-project-ids nil
+  "Specific list of project IDs to synchronize with clubhouse.
+If unset all projects will be synchronized")
+
+(defvar org-clubhouse-workflow-name "Default")
+
+(defvar org-clubhouse-state-alist
+  '(("LATER"  . "Unscheduled")
+    ("[ ]"    . "Ready for Development")
+    ("TODO"   . "Ready for Development")
+    ("OPEN"   . "Ready for Development")
+    ("ACTIVE" . "In Development")
+    ("PR"     . "Review")
+    ("DONE"   . "Merged")
+    ("[X]"    . "Merged")
+    ("CLOSED" . "Merged")))
+
+;;;
+;;; Utilities
+;;;
+
+(defun ->list (vec) (append vec nil))
+
+(defun reject-archived (item-list)
+  (-filter (lambda (item) (equal :json-false (alist-get 'archived item))) item-list))
+
+(defun alist->plist (key-map alist)
+  (->> key-map
+       (-map (lambda (key-pair)
+               (let ((alist-key (car key-pair))
+                     (plist-key (cdr key-pair)))
+                 (list plist-key (alist-get alist-key alist)))))
+       (-flatten-n 1)))
+
+(defun alist-get-equal (key alist)
+  "Like `alist-get', but uses `equal' instead of `eq' for comparing keys"
+  (->> alist
+       (-find (lambda (pair) (equal key (car pair))))
+       (cdr)))
+
+;;;
+;;; Org-element interaction
+;;;
+
+;; (defun org-element-find-headline ()
+;;   (let ((current-elt (org-element-at-point)))
+;;     (if (equal 'headline (car current-elt))
+;;         current-elt
+;;       (let* ((elt-attrs (cadr current-elt))
+;;              (parent (plist-get elt-attrs :post-affiliated)))
+;;         (goto-char parent)
+;;         (org-element-find-headline)))))
+
+(defun org-element-find-headline ()
+  (let ((current-elt (org-element-at-point)))
+    (when (equal 'headline (car current-elt))
+      (cadr current-elt))))
+
+(defun org-element-extract-clubhouse-id (elt)
+  (when-let ((clubhouse-id-link (plist-get elt :CLUBHOUSE-ID)))
+    (string-match
+     (rx "[[" (one-or-more anything) "]"
+         "[" (group (one-or-more digit)) "]]")
+     clubhouse-id-link)
+    (string-to-int (match-string 1 clubhouse-id-link))))
+
+
+
+(defun org-element-clubhouse-id ()
+  (org-element-extract-clubhouse-id
+   (org-element-find-headline)))
+
+;;;
+;;; API integration
+;;;
+
+(defvar org-clubhouse-base-url* "https://api.clubhouse.io/api/v2")
+
+(defun org-clubhouse-auth-url (url)
+  (concat url
+          "?"
+          (url-build-query-string
+           `(("token" ,org-clubhouse-auth-token)))))
+
+(defun org-clubhouse-baseify-url (url)
+  (if (s-starts-with? org-clubhouse-base-url* url) url
+    (concat org-clubhouse-base-url*
+            (if (s-starts-with? "/" url) url
+              (concat "/" url)))))
+
+(defun org-clubhouse-request (method url &optional data)
+  (message "%s %s %s" method url (prin1-to-string data))
+  (let* ((url-request-method method)
+         (url-request-extra-headers
+          '(("Content-Type" . "application/json")))
+         (url-request-data data)
+         (buf))
+
+    (setq url (-> url
+                  org-clubhouse-baseify-url
+                  org-clubhouse-auth-url))
+
+    (setq buf (url-retrieve-synchronously url))
+
+    (with-current-buffer buf
+      (goto-char url-http-end-of-headers)
+      (prog1 (json-read) (kill-buffer)))))
+
+(cl-defun to-id-name-pairs
+    (seq &optional (id-attr 'id) (name-attr 'name))
+  (->> seq
+       ->list
+       (-map (lambda (resource)
+          (cons (alist-get id-attr   resource)
+                (alist-get name-attr resource))))))
+
+(cl-defun org-clubhouse-fetch-as-id-name-pairs
+    (resource &optional
+              (id-attr 'id)
+              (name-attr 'name))
+  "Returns the given resource from clubhouse as (id . name) pairs"
+  (let ((resp-json (org-clubhouse-request "GET" resource)))
+    (-> resp-json
+        ->list
+        reject-archived
+        (to-id-name-pairs id-attr name-attr))))
+
+(defun org-clubhouse-link-to-story (story-id)
+  (format "https://app.clubhouse.io/%s/story/%d"
+          org-clubhouse-team-name
+          story-id))
+
+(defun org-clubhouse-link-to-epic (epic-id)
+  (format "https://app.clubhouse.io/%s/epic/%d"
+          org-clubhouse-team-name
+          epic-id))
+
+(defun org-clubhouse-link-to-project (project-id)
+  (format "https://app.clubhouse.io/%s/project/%d"
+          org-clubhouse-team-name
+          project-id))
+
+;;;
+;;; Caching
+;;;
+
+
+
+(defvar org-clubhouse-cache-clear-functions ())
+
+(defmacro defcache (name &optional docstring &rest body)
+  (let* ((doc (when docstring (list docstring)))
+         (cache-var-name (intern (concat (symbol-name name)
+                                         "-cache")))
+         (clear-cache-function-name
+          (intern (concat "clear-" (symbol-name cache-var-name)))))
+    `(progn
+       (defvar ,cache-var-name :no-cache)
+       (defun ,name ()
+         ,@doc
+         (when (equal :no-cache ,cache-var-name)
+           (setq ,cache-var-name (progn ,@body)))
+         ,cache-var-name)
+       (defun ,clear-cache-function-name ()
+         (interactive)
+         (setq ,cache-var-name :no-cache))
+
+       (push (quote ,clear-cache-function-name)
+             org-clubhouse-cache-clear-functions))))
+
+(defun org-clubhouse-clear-cache ()
+  (interactive)
+  (-map #'funcall org-clubhouse-cache-clear-functions))
+
+;;;
+;;; API resource functions
+;;;
+
+(defcache org-clubhouse-projects
+  "Returns projects as (project-id . name)"
+  (org-clubhouse-fetch-as-id-name-pairs "projects"))
+
+(defcache org-clubhouse-epics
+  "Returns projects as (project-id . name)"
+  (org-clubhouse-fetch-as-id-name-pairs "epics"))
+
+(defcache org-clubhouse-workflow-states
+  "Returns worflow states as (name . id) pairs"
+  (let* ((resp-json (org-clubhouse-request "GET" "workflows"))
+         (workflows (->list resp-json))
+         ;; just assume it exists, for now
+         (workflow  (-find (lambda (workflow)
+                             (equal org-clubhouse-workflow-name
+                                    (alist-get 'name workflow)))
+                           workflows))
+         (states    (->list (alist-get 'states workflow))))
+    (to-id-name-pairs states
+                      'name
+                      'id)))
+
+(defun org-clubhouse-stories-in-project (project-id)
+  "Returns the stories in the given project as org bugs"
+  (let ((resp-json (org-clubhouse-request "GET" (format "/projects/%d/stories" project-id))))
+    (->> resp-json ->list reject-archived
+         (-reject (lambda (story) (equal :json-true (alist-get 'completed story))))
+         (-map (lambda (story)
+                 (cons
+                  (cons 'status
+                        (cond
+                         ((equal :json-true (alist-get 'started story))
+                          'started)
+                         ((equal :json-true (alist-get 'completed story))
+                          'completed)
+                         ('t
+                          'open)))
+                  story)))
+         (-map (-partial #'alist->plist
+                         '((name . :title)
+                           (id . :id)
+                           (status . :status)))))))
+
+;;;
+;;; Story creation
+;;;
+
+(cl-defun org-clubhouse-create-story-internal
+    (title &key project-id epic-id)
+  (assert (and (stringp title)
+               (integerp project-id)
+               (or (null epic-id) (integerp epic-id))))
+  (org-clubhouse-request
+   "POST"
+   "stories"
+   (json-encode
+    `((name . ,title)
+      (project_id . ,project-id)
+      (epic_id . ,epic-id)))))
+
+(defun org-clubhouse-prompt-for-project (cb)
+  (ivy-read
+   "Select a project: "
+   (-map #'cdr (org-clubhouse-projects))
+   :require-match t
+   :history 'org-clubhouse-project-history
+   :action (lambda (selected)
+             (let ((project-id
+                    (->> (org-clubhouse-projects)
+                         (-find (lambda (proj)
+                                    (string-equal (cdr proj) selected)))
+                         car)))
+               (message "%d" project-id)
+               (funcall cb project-id)))))
+
+(defun org-clubhouse-prompt-for-epic (cb)
+  (ivy-read
+   "Select an epic: "
+   (-map #'cdr (org-clubhouse-epics))
+   :history 'org-clubhouse-epic-history
+   :action (lambda (selected)
+             (let ((epic-id
+                    (->> (org-clubhouse-epics)
+                         (-find (lambda (proj)
+                                    (string-equal (cdr proj) selected)))
+                         car)))
+               (message "%d" epic-id)
+               (funcall cb epic-id)))))
+
+(defun org-clubhouse-populate-created-story (story)
+  (let ((elt        (org-element-find-headline))
+        (story-id   (alist-get 'id story))
+        (epic-id    (alist-get 'epic_id story))
+        (project-id (alist-get 'project_id story)))
+
+    (org-set-property "clubhouse-id"
+                      (org-make-link-string
+                       (org-clubhouse-link-to-story story-id)
+                       (number-to-string story-id)))
+
+    (org-set-property "clubhouse-epic"
+                      (org-make-link-string
+                       (org-clubhouse-link-to-epic epic-id)
+                       (alist-get epic-id (org-clubhouse-epics))))
+
+    (org-set-property "clubhouse-project"
+                      (org-make-link-string
+                       (org-clubhouse-link-to-project project-id)
+                       (alist-get project-id (org-clubhouse-projects))))
+
+    (org-todo "TODO")))
+
+(defun org-clubhouse-create-story ()
+  (interactive)
+  ;; (message (org-element-find-headline))
+  (when-let ((elt (org-element-find-headline))
+             (title (plist-get elt :title)))
+    (if (plist-get elt :CLUBHOUSE-ID)
+        (message "This headline is already a clubhouse story!")
+      (org-clubhouse-prompt-for-project
+       (lambda (project-id)
+         (when project-id
+           (org-clubhouse-prompt-for-epic
+            (lambda (epic-id)
+              (let* ((story (org-clubhouse-create-story-internal
+                             title
+                             :project-id project-id
+                             :epic-id epic-id)))
+                (org-clubhouse-populate-created-story story))))))))))
+
+;;;
+;;; Story updates
+;;;
+
+(cl-defun org-clubhouse-update-story-internal
+    (story-id &rest attrs)
+  (assert (and (integerp story-id)
+               (listp attrs)))
+  (org-clubhouse-request
+   "PUT"
+   (format "stories/%d" story-id)
+   (json-encode attrs)))
+
+(defun org-clubhouse-update-status ()
+  (when-let (clubhouse-id (org-element-clubhouse-id))
+    (let* ((elt (org-element-find-headline))
+           (todo-keyword (-> elt (plist-get :todo-keyword) (substring-no-properties))))
+      (message todo-keyword)
+      (when-let ((clubhouse-workflow-state
+                  (alist-get-equal todo-keyword org-clubhouse-state-alist))
+                 (workflow-state-id
+                  (alist-get-equal clubhouse-workflow-state (org-clubhouse-workflow-states))))
+        (org-clubhouse-update-story-internal
+         clubhouse-id
+         :workflow_state_id workflow-state-id)
+        (message "Successfully updated clubhouse status to \"%s\""
+                 clubhouse-workflow-state)))))
+
+(define-minor-mode org-clubhouse-mode
+  :init-value nil
+  :group 'org
+  :lighter "Org-Clubhouse"
+  :keymap '()
+  (add-hook 'org-after-todo-state-change-hook
+            'org-clubhouse-update-status
+            nil
+            t))
diff --git a/configs/shared/emacs/.emacs.d/vendor/reason-indent.el b/configs/shared/emacs/.emacs.d/vendor/reason-indent.el
new file mode 100644
index 0000000000..8fd3c94258
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/vendor/reason-indent.el
@@ -0,0 +1,304 @@
+;;; reason-indent.el --- Indentation functions for ReasonML -*-lexical-binding: t-*-
+
+;; Portions Copyright (c) 2015-present, Facebook, Inc. All rights reserved.
+
+;;; Commentary:
+
+;; Indentation functions for Reason.
+
+;;; Code:
+
+(defconst reason-re-ident "[[:word:][:multibyte:]_][[:word:][:multibyte:]_[:digit:]]*")
+
+(defcustom reason-indent-offset 2
+  "Indent Reason code by this number of spaces."
+  :type 'integer
+  :group 'reason-mode
+  :safe #'integerp)
+
+(defun reason-looking-back-str (str)
+  "Like `looking-back' but for fixed strings rather than regexps.
+Works around some regexp slowness.
+Argument STR string to search for."
+  (let ((len (length str)))
+    (and (> (point) len)
+         (equal str (buffer-substring-no-properties (- (point) len) (point))))))
+
+(defun reason-paren-level ()
+  "Get the level of nesting inside parentheses."
+  (nth 0 (syntax-ppss)))
+
+(defun reason-in-str-or-cmnt ()
+  "Return whether point is currently inside a string or a comment."
+  (nth 8 (syntax-ppss)))
+
+(defun reason-rewind-past-str-cmnt ()
+  "Rewind past string or comment."
+  (goto-char (nth 8 (syntax-ppss))))
+
+(defun reason-rewind-irrelevant ()
+  "Rewind past irrelevant characters (whitespace of inside comments)."
+  (interactive)
+  (let ((starting (point)))
+    (skip-chars-backward "[:space:]\n")
+    (if (reason-looking-back-str "*/") (backward-char))
+    (if (reason-in-str-or-cmnt)
+        (reason-rewind-past-str-cmnt))
+    (if (/= starting (point))
+        (reason-rewind-irrelevant))))
+
+(defun reason-align-to-expr-after-brace ()
+  "Align the expression at point to the expression after the previous brace."
+  (save-excursion
+    (forward-char)
+    ;; We don't want to indent out to the open bracket if the
+    ;; open bracket ends the line
+    (when (not (looking-at "[[:blank:]]*\\(?://.*\\)?$"))
+      (when (looking-at "[[:space:]]")
+        (forward-word 1)
+        (backward-word 1))
+      (current-column))))
+
+(defun reason-align-to-prev-expr ()
+  "Align the expression at point to the previous expression."
+  (let ((alignment (save-excursion
+                     (forward-char)
+                     ;; We don't want to indent out to the open bracket if the
+                     ;; open bracket ends the line
+                     (when (not (looking-at "[[:blank:]]*\\(?://.*\\)?$"))
+                       (if (looking-at "[[:space:]]")
+                           (progn
+                             (forward-word 1)
+                             (backward-word 1))
+                         (backward-char))
+                       (current-column)))))
+    (if (not alignment)
+        (save-excursion
+          (forward-char)
+          (forward-line)
+          (back-to-indentation)
+          (current-column))
+      alignment)))
+
+;;; Start of a reason binding
+(defvar reason-binding
+  (regexp-opt '("let" "type" "module" "fun")))
+
+(defun reason-beginning-of-defun (&optional arg)
+  "Move backward to the beginning of the current defun.
+
+With ARG, move backward multiple defuns.  Negative ARG means
+move forward.
+
+This is written mainly to be used as `beginning-of-defun-function'.
+Don't move to the beginning of the line.  `beginning-of-defun',
+which calls this, does that afterwards."
+  (interactive "p")
+  (re-search-backward (concat "^\\(" reason-binding "\\)\\_>")
+                      nil 'move (or arg 1)))
+
+(defun reason-end-of-defun ()
+  "Move forward to the next end of defun.
+
+With argument, do it that many times.
+Negative argument -N means move back to Nth preceding end of defun.
+
+Assume that this is called after ‘beginning-of-defun’.  So point is
+at the beginning of the defun body.
+
+This is written mainly to be used as `end-of-defun-function' for Reason."
+  (interactive)
+  ;; Find the opening brace
+  (if (re-search-forward "[{]" nil t)
+      (progn
+        (goto-char (match-beginning 0))
+        ;; Go to the closing brace
+        (condition-case nil
+            (forward-sexp)
+          (scan-error
+           ;; The parentheses are unbalanced; instead of being unable to fontify, just jump to the end of the buffer
+           (goto-char (point-max)))))
+    ;; There is no opening brace, so consider the whole buffer to be one "defun"
+    (goto-char (point-max))))
+
+(defun reason-rewind-to-beginning-of-current-level-expr ()
+  "Rewind to the beginning of the expression on the current level of nesting."
+  (interactive)
+  (let ((current-level (reason-paren-level)))
+    (back-to-indentation)
+    (when (looking-at "=>")
+      (reason-rewind-irrelevant)
+      (back-to-indentation))
+    (while (> (reason-paren-level) current-level)
+      (backward-up-list)
+      (back-to-indentation))))
+
+(defun reason-mode-indent-line ()
+  "Indent current line."
+  (interactive)
+  (let ((indent
+         (save-excursion
+           (back-to-indentation)
+           ;; Point is now at beginning of current line
+           (let* ((level (reason-paren-level))
+                  (baseline
+                   ;; Our "baseline" is one level out from the indentation of the expression
+                   ;; containing the innermost enclosing opening bracket. That
+                   ;; way if we are within a block that has a different
+                   ;; indentation than this mode would give it, we still indent
+                   ;; the inside of it correctly relative to the outside.
+                   (if (= 0 level)
+                       0
+                     (save-excursion
+                       (reason-rewind-irrelevant)
+                       (if (save-excursion
+                             (reason-rewind-to-beginning-of-current-level-expr)
+                             (looking-at "<"))
+                           (progn
+                             (reason-rewind-to-beginning-of-current-level-expr)
+                             (current-column))
+                           (progn
+                             (backward-up-list)
+                             (reason-rewind-to-beginning-of-current-level-expr)
+
+                             (cond
+                              ((looking-at "switch")
+                               (current-column))
+
+                              ((looking-at "|")
+                               (+ (current-column) (* reason-indent-offset 2)))
+
+                              (t
+                               (let ((current-level (reason-paren-level)))
+                                 (save-excursion
+                                   (while (and (= current-level (reason-paren-level))
+                                               (not (looking-at reason-binding)))
+                                     (reason-rewind-irrelevant)
+                                     (reason-rewind-to-beginning-of-current-level-expr))
+                                   (+ (current-column) reason-indent-offset)))))))))))
+             (cond
+              ;; A function return type is indented to the corresponding function arguments
+              ((looking-at "=>")
+               (+ baseline reason-indent-offset))
+
+              ((reason-in-str-or-cmnt)
+               (cond
+                ;; In the end of the block -- align with star
+                ((looking-at "*/") (+ baseline 1))
+                ;; Indent to the following shape:
+                ;; /* abcd
+                ;;  * asdf
+                ;;  */
+                ;;
+                ((looking-at "*") (+ baseline 1))
+                ;; Indent to the following shape:
+                ;; /* abcd
+                ;;    asdf
+                ;;  */
+                ;;
+                (t (+ baseline (+ reason-indent-offset 1)))))
+
+              ((looking-at "</") (- baseline reason-indent-offset))
+
+              ;; A closing brace is 1 level unindented
+              ((looking-at "}\\|)\\|\\]")
+               (save-excursion
+                 (reason-rewind-irrelevant)
+                 (let ((jsx? (reason-looking-back-str ">")))
+                   (backward-up-list)
+                   (reason-rewind-to-beginning-of-current-level-expr)
+                   (cond
+                    ((looking-at "switch") baseline)
+
+                    (jsx? (current-column))
+
+                    (t (- baseline reason-indent-offset))))))
+
+              ;; Doc comments in /** style with leading * indent to line up the *s
+              ((and (nth 4 (syntax-ppss)) (looking-at "*"))
+               (+ 1 baseline))
+
+              ;; If we're in any other token-tree / sexp, then:
+              (t
+               (or
+                ;; If we are inside a pair of braces, with something after the
+                ;; open brace on the same line and ending with a comma, treat
+                ;; it as fields and align them.
+                (when (> level 0)
+                  (save-excursion
+                    (reason-rewind-irrelevant)
+                    (backward-up-list)
+                    ;; Point is now at the beginning of the containing set of braces
+                    (reason-align-to-expr-after-brace)))
+
+                (progn
+                  (back-to-indentation)
+                  (cond ((looking-at (regexp-opt '("and" "type")))
+                         baseline)
+                        ((save-excursion
+                           (reason-rewind-irrelevant)
+                           (= (point) 1))
+                         baseline)
+                        ((save-excursion
+                           (while (looking-at "|")
+                             (reason-rewind-irrelevant)
+                             (back-to-indentation))
+                           (looking-at (regexp-opt '("type"))))
+                         (+ baseline reason-indent-offset))
+                        ((looking-at "|\\|/[/*]")
+                         baseline)
+                        ((and (> level 0)
+                              (save-excursion
+                                (reason-rewind-irrelevant)
+                                (backward-up-list)
+                                (reason-rewind-to-beginning-of-current-level-expr)
+                                (looking-at "switch")))
+                         (+ baseline reason-indent-offset))
+                        ((save-excursion
+                           (reason-rewind-irrelevant)
+                           (looking-back "[{;,\\[(]" (- (point) 2)))
+                         baseline)
+                        ((and
+                          (save-excursion
+                            (reason-rewind-irrelevant)
+                            (reason-rewind-to-beginning-of-current-level-expr)
+                            (and (looking-at reason-binding)
+                                 (not (progn
+                                        (forward-sexp)
+                                        (forward-sexp)
+                                        (skip-chars-forward "[:space:]\n")
+                                        (looking-at "=")))))
+                          (not (save-excursion
+                                 (skip-chars-backward "[:space:]\n")
+                                 (reason-looking-back-str "=>"))))
+                         (save-excursion
+                           (reason-rewind-irrelevant)
+                           (backward-sexp)
+                           (reason-align-to-prev-expr)))
+                        ((save-excursion
+                           (reason-rewind-irrelevant)
+                           (looking-back "<\/.*?>" (- (point) 30)))
+                         baseline)
+                        (t
+                         (save-excursion
+                           (reason-rewind-irrelevant)
+                           (reason-rewind-to-beginning-of-current-level-expr)
+
+                           (if (looking-at "|")
+                               baseline
+                             (+ baseline reason-indent-offset)))))
+                  ;; Point is now at the beginning of the current line
+                  ))))))))
+
+    (when indent
+      ;; If we're at the beginning of the line (before or at the current
+      ;; indentation), jump with the indentation change.  Otherwise, save the
+      ;; excursion so that adding the indentations will leave us at the
+      ;; equivalent position within the line to where we were before.
+      (if (<= (current-column) (current-indentation))
+          (indent-line-to indent)
+        (save-excursion (indent-line-to indent))))))
+
+(provide 'reason-indent)
+
+;;; reason-indent.el ends here
diff --git a/configs/shared/emacs/.emacs.d/vendor/reason-interaction.el b/configs/shared/emacs/.emacs.d/vendor/reason-interaction.el
new file mode 100644
index 0000000000..6ceaed1e93
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/vendor/reason-interaction.el
@@ -0,0 +1,216 @@
+;;; reason-interaction.el --- Phrase navitagion for rtop -*-lexical-binding: t-*-
+
+;; Portions Copyright (c) 2015-present, Facebook, Inc. All rights reserved.
+
+;;; Commentary:
+
+;; Phrase navigation for utop and maybe other REPLs.
+
+;; The utop compatibility layer for Reason was mainly taken from:
+;; https://github.com/ocaml/tuareg/blob/master/tuareg-light.el (big thanks!)
+
+;;; Code:
+
+(defun reason-backward-char (&optional step)
+  "Go back one char.
+Similar to `backward-char` but it does not signal errors
+`beginning-of-buffer` and `end-of-buffer`.  It optionally takes a
+STEP parameter for jumping back more than one character."
+  (when step (goto-char (- (point) step))
+        (goto-char (1- (point)))))
+
+(defun reason-forward-char (&optional step)
+  "Go forward one char.
+Similar to `forward-char` but it does not signal errors
+`beginning-of-buffer` and `end-of-buffer`.  It optionally takes a
+STEP parameter for jumping back more than one character."
+  (when step (goto-char (+ (point) step))
+    (goto-char (1+ (point)))))
+
+(defun reason-in-literal-p ()
+  "Return non-nil if point is inside an Reason literal."
+  (nth 3 (syntax-ppss)))
+
+(defconst reason-comment-delimiter-regexp "\\*/\\|/\\*"
+  "Regex for identify either open or close comment delimiters.")
+
+(defun reason-in-between-comment-chars-p ()
+  "Return non-nil iff point is in between the comment delimiter chars.
+It returns non-nil if point is between the chars only (*|/ or /|*
+where | is point)."
+  (and (not (bobp)) (not (eobp))
+       (or (and (char-equal ?/ (char-before)) (char-equal ?* (char-after)))
+           (and (char-equal ?* (char-before)) (char-equal ?/ (char-after))))))
+
+(defun reason-looking-at-comment-delimiters-p ()
+  "Return non-nil iff point in between comment delimiters."
+  (looking-at-p reason-comment-delimiter-regexp))
+
+(defun reason-in-between-comment-delimiters-p ()
+  "Return non-nil if inside /* and */."
+  (nth 4 (syntax-ppss)))
+
+(defun reason-in-comment-p ()
+  "Return non-nil iff point is inside or right before a comment."
+  (or (reason-in-between-comment-delimiters-p)
+      (reason-in-between-comment-chars-p)
+      (reason-looking-at-comment-delimiters-p)))
+
+(defun reason-beginning-of-literal-or-comment ()
+  "Skip to the beginning of the current literal or comment (or buffer)."
+  (interactive)
+  (goto-char (or (nth 8 (syntax-ppss)) (point))))
+
+(defun reason-inside-block-scope-p ()
+  "Skip to the beginning of the current literal or comment (or buffer)."
+  (and (> (nth 0 (syntax-ppss)) 0)
+       (let ((delim-start (nth 1 (syntax-ppss))))
+         (save-excursion
+           (goto-char delim-start)
+           (char-equal ?{ (following-char))))))
+
+(defun reason-at-phrase-break-p ()
+  "Is the underlying `;' a phrase break?"
+  ;; Difference from OCaml, the phrase separator is a single semi-colon
+  (and (not (eobp))
+       (char-equal ?\; (following-char))))
+
+(defun reason-skip-to-close-delimiter (&optional limit)
+  "Skip to the end of a Reason block.
+It basically calls `re-search-forward` in order to go to any
+closing delimiter, not concerning itself with balancing of any
+sort.  Client code needs to check that.
+LIMIT is passed to `re-search-forward` directly."
+  (re-search-forward "\\s)" limit 'move))
+
+(defun reason-skip-back-to-open-delimiter (&optional limit)
+  "Skip to the beginning of a Reason block backwards.
+It basically calls `re-search-backward` in order to go to any
+opening delimiter, not concerning itself with balancing of any
+sort.  Client code needs to check that.
+LIMIT is passed to `re-search-backward` directly."
+  (re-search-backward "\\s(" limit 'move))
+
+(defun reason-find-phrase-end ()
+  "Skip to the end of a phrase."
+  (while (and (not (eobp))
+              (not (reason-at-phrase-break-p)))
+    (if (re-search-forward ";" nil 'move)
+        (progn (when (reason-inside-block-scope-p)
+                 (reason-skip-to-close-delimiter))
+               (goto-char (1- (point))))
+      ;; avoid infinite loop at the end of the buffer
+      (re-search-forward "[[:space:]\\|\n]+" nil 'move)))
+  (min (goto-char (1+ (point))) (point-max)))
+
+(defun reason-skip-blank-and-comments ()
+  "Skip blank spaces and comments."
+  (cond
+   ((eobp) (point))
+   ((or (reason-in-between-comment-chars-p)
+        (reason-looking-at-comment-delimiters-p)) (progn
+                                                    (reason-forward-char 1)
+                                                    (reason-skip-blank-and-comments)))
+   ((reason-in-between-comment-delimiters-p) (progn
+                                               (search-forward "*/" nil t)
+                                               (reason-skip-blank-and-comments)))
+   ((eolp) (progn
+             (reason-forward-char 1)
+             (reason-skip-blank-and-comments)))
+   (t (progn (skip-syntax-forward " ")
+             (point)))))
+
+(defun reason-skip-back-blank-and-comments ()
+  "Skip blank spaces and comments backwards."
+  (cond
+   ((bobp) (point))
+   ((looking-back reason-comment-delimiter-regexp) (progn
+                                                     (reason-backward-char 1)
+                                                     (reason-skip-back-blank-and-comments)))
+   ((reason-in-between-comment-delimiters-p) (progn
+                                               (search-backward "/*" nil t)
+                                               (reason-backward-char 1)
+                                               (reason-skip-back-blank-and-comments)))
+   ((or (reason-in-between-comment-chars-p)
+        (reason-looking-at-comment-delimiters-p)) (progn
+                                                    (reason-backward-char 1)
+                                                    (reason-skip-back-blank-and-comments)))
+   ((bolp) (progn
+             (reason-backward-char 1)
+             (reason-skip-back-blank-and-comments)))
+   (t (progn (skip-syntax-backward " ")
+             (point)))))
+
+(defun reason-ro (&rest words)
+  "Build a regex matching iff at least a word in WORDS is present."
+  (concat "\\<" (regexp-opt words t) "\\>"))
+
+(defconst reason-find-phrase-beginning-regexp
+  (concat (reason-ro "end" "type" "module" "sig" "struct" "class"
+                     "exception" "open" "let")
+          "\\|^#[ \t]*[a-z][_a-z]*\\>\\|;"))
+
+(defun reason-at-phrase-start-p ()
+  "Return t if is looking at the beginning of a phrase.
+A phrase starts when a toplevel keyword is at the beginning of a line."
+  (or (looking-at "#")
+      (looking-at reason-find-phrase-beginning-regexp)))
+
+(defun reason-find-phrase-beginning-backward ()
+  "Find the beginning of a phrase and return point.
+It scans code backwards, therefore the caller can assume that the
+beginning of the phrase (if found) is always before the starting
+point.  No error is signalled and (point-min) is returned when a
+phrease cannot be found."
+  (beginning-of-line)
+  (while (and (not (bobp)) (not (reason-at-phrase-start-p)))
+    (if (reason-inside-block-scope-p)
+        (reason-skip-back-to-open-delimiter)
+      (re-search-backward reason-find-phrase-beginning-regexp nil 'move)))
+  (point))
+
+(defun reason-discover-phrase ()
+  "Discover a Reason phrase in the buffer."
+  ;; TODO reason-with-internal-syntax ;; tuareg2 modifies the syntax table (removed for now)
+  ;; TODO stop-at-and feature for phrase detection (do we need it?)
+  ;; TODO tuareg2 has some custom logic for module and class (do we need it?)
+  (save-excursion
+    (let ((case-fold-search nil))
+      (reason-skip-blank-and-comments)
+      (list (reason-find-phrase-beginning-backward) ;; beginning
+            (reason-find-phrase-end)                ;; end
+            (save-excursion                         ;; end-with-comment
+              (reason-skip-blank-and-comments)
+              (point))))))
+
+(defun reason-discover-phrase-debug ()
+  "Discover a Reason phrase in the buffer (debug mode)."
+  (let ((triple (reason-discover-phrase)))
+    (message (concat "Evaluating: \"" (reason-fetch-phrase triple) "\""))
+    triple))
+
+(defun reason-fetch-phrase (triple)
+  "Fetch the phrase text given a TRIPLE."
+  (let* ((start (nth 0 triple))
+         (end (nth 1 triple))) ;; we don't need end-with-comment
+    (buffer-substring-no-properties start end)))
+
+(defun reason-next-phrase ()
+  "Skip to the beginning of the next phrase."
+  (cond
+   ((reason-at-phrase-start-p) (point))
+   ((eolp) (progn
+             (forward-char 1)
+             (reason-skip-blank-and-comments)
+             (reason-next-phrase)))
+   ((reason-inside-block-scope-p) (progn (reason-skip-to-close-delimiter)
+                                         (reason-next-phrase)))
+   ((looking-at ";") (progn
+                       (forward-char 1)
+                       (reason-next-phrase)))
+   (t (progn (end-of-line)
+             (reason-next-phrase)))))
+
+(provide 'reason-interaction)
+
+;;; reason-interaction.el ends here
diff --git a/configs/shared/emacs/.emacs.d/vendor/reason-mode.el b/configs/shared/emacs/.emacs.d/vendor/reason-mode.el
new file mode 100644
index 0000000000..789735955d
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/vendor/reason-mode.el
@@ -0,0 +1,242 @@
+;;; reason-mode.el --- A major mode for editing ReasonML -*-lexical-binding: t-*-
+;; Portions Copyright (c) 2015-present, Facebook, Inc. All rights reserved.
+
+;; Version: 0.4.0
+;; Author: Mozilla
+;; Url: https://github.com/reasonml-editor/reason-mode
+;; Keywords: languages, ocaml
+;; Package-Requires: ((emacs "24.3"))
+
+;; This file is NOT part of GNU Emacs.
+
+;; This file is distributed under the terms of both the MIT license and the
+;; Apache License (version 2.0).
+
+;;; Commentary:
+;; This project provides useful functions and helpers for developing code
+;; using the Reason programming language (https://facebook.github.io/reason).
+;;
+;; Reason is an umbrella project that provides a curated layer for OCaml.
+;;
+;; It offers:
+;;  - A new, familiar syntax for the battle-tested language that is OCaml.
+;;  - A workflow for compiling to JavaScript and native code.
+;;  - A set of friendly documentations, libraries and utilities.
+;;
+;; See the README.md for more details.
+
+;;; Code:
+
+(require 'reason-indent)
+(require 'refmt)
+(require 'reason-interaction)
+
+(eval-when-compile (require 'rx)
+                   (require 'compile)
+                   (require 'url-vars))
+
+;; Syntax definitions and helpers
+(defvar reason-mode-syntax-table
+  (let ((table (make-syntax-table)))
+
+    ;; Operators
+    (dolist (i '(?+ ?- ?* ?/ ?& ?| ?^ ?! ?< ?> ?~ ?@))
+      (modify-syntax-entry i "." table))
+
+    ;; Strings
+    (modify-syntax-entry ?\" "\"" table)
+    (modify-syntax-entry ?\\ "\\" table)
+    (modify-syntax-entry ?\' "_"  table)
+
+    ;; Comments
+    (modify-syntax-entry ?/  ". 124b" table)
+    (modify-syntax-entry ?*  ". 23n"  table)
+    (modify-syntax-entry ?\n "> b"    table)
+    (modify-syntax-entry ?\^m "> b"   table)
+
+    table))
+
+(defgroup reason nil
+  "Support for Reason code."
+  :link '(url-link "http://facebook.github.io/reason/")
+  :group 'languages)
+
+(defcustom reason-mode-hook nil
+  "Hook called by `reason-mode'."
+  :type 'hook
+  :group 'reason)
+
+;; Font-locking definitions and helpers
+(defconst reason-mode-keywords
+  '("and" "as"
+    "else" "external"
+    "fun" "for"
+    "if" "impl" "in" "include"
+    "let"
+    "module" "match" "mod" "move" "mutable"
+    "open"
+    "priv" "pub"
+    "rec" "ref" "return"
+    "self" "static" "switch" "struct" "super"
+    "trait" "type"
+    "use"
+    "virtual"
+    "where" "when" "while"))
+
+(defconst reason-mode-consts
+  '("true" "false"))
+
+(defconst reason-special-types
+  '("int" "float" "string" "char"
+    "bool" "unit" "list" "array" "exn"
+    "option" "ref"))
+
+(defconst reason-camel-case
+  (rx symbol-start
+      (group upper (0+ (any word nonascii digit "_")))
+      symbol-end))
+
+(eval-and-compile
+  (defconst reason--char-literal-rx
+    (rx (seq (group "'")
+             (or (seq "\\" anything)
+                 (not (any "'\\")))
+             (group "'")))))
+
+(defun reason-re-word (inner)
+  "Build a word regexp given INNER."
+  (concat "\\<" inner "\\>"))
+
+(defun reason-re-grab (inner)
+  "Build a grab regexp given INNER."
+  (concat "\\(" inner "\\)"))
+
+(defun reason-regexp-opt-symbols (words)
+  "Like `(regexp-opt words 'symbols)`, but will work on Emacs 23.
+See rust-mode PR #42.
+Argument WORDS argument to pass to `regexp-opt`."
+  (concat "\\_<" (regexp-opt words t) "\\_>"))
+
+;;; Syntax highlighting for Reason
+(defvar reason-font-lock-keywords
+  `((,(reason-regexp-opt-symbols reason-mode-keywords) . font-lock-keyword-face)
+    (,(reason-regexp-opt-symbols reason-special-types) . font-lock-builtin-face)
+    (,(reason-regexp-opt-symbols reason-mode-consts) . font-lock-constant-face)
+
+    (,reason-camel-case 1 font-lock-type-face)
+
+    ;; Field names like `foo:`, highlight excluding the :
+    (,(concat (reason-re-grab reason-re-ident) ":[^:]") 1 font-lock-variable-name-face)
+    ;; Module names like `foo::`, highlight including the ::
+    (,(reason-re-grab (concat reason-re-ident "::")) 1 font-lock-type-face)
+    ;; Name punned labeled args like ::foo
+    (,(concat "[[:space:]]+" (reason-re-grab (concat "::" reason-re-ident))) 1 font-lock-type-face)
+
+    ;; TODO jsx attribs?
+    (,
+     (concat "<[/]?" (reason-re-grab reason-re-ident) "[^>]*" ">")
+     1 font-lock-type-face)))
+
+(defun reason-mode-try-find-alternate-file (mod-name extension)
+  "Switch to the file given by MOD-NAME and EXTENSION."
+  (let* ((filename (concat mod-name extension))
+         (buffer (get-file-buffer filename)))
+    (if buffer (switch-to-buffer buffer)
+      (find-file filename))))
+
+(defun reason-mode-find-alternate-file ()
+  "Switch to implementation/interface file."
+  (interactive)
+  (let ((name buffer-file-name))
+    (when (string-match "\\`\\(.*\\)\\.re\\([il]\\)?\\'" name)
+      (let ((mod-name (match-string 1 name))
+            (e (match-string 2 name)))
+        (cond
+         ((string= e "i")
+          (reason-mode-try-find-alternate-file mod-name ".re"))
+         (t
+          (reason-mode-try-find-alternate-file mod-name ".rei")))))))
+
+(defun reason--syntax-propertize-multiline-string (end)
+  "Propertize Reason multiline string.
+Argument END marks the end of the string."
+  (let ((ppss (syntax-ppss)))
+    (when (eq t (nth 3 ppss))
+      (let ((key (save-excursion
+                   (goto-char (nth 8 ppss))
+                   (and (looking-at "{\\([a-z]*\\)|")
+                        (match-string 1)))))
+        (when (search-forward (format "|%s}" key) end 'move)
+          (put-text-property (1- (match-end 0)) (match-end 0)
+                             'syntax-table (string-to-syntax "|")))))))
+
+(defun reason-syntax-propertize-function (start end)
+  "Propertize Reason function.
+Argument START marks the beginning of the function.
+Argument END marks the end of the function."
+  (goto-char start)
+  (reason--syntax-propertize-multiline-string end)
+  (funcall
+   (syntax-propertize-rules
+    (reason--char-literal-rx (1 "\"") (2 "\""))
+    ;; multi line strings
+    ("\\({\\)[a-z]*|"
+     (1 (prog1 "|"
+          (goto-char (match-end 0))
+          (reason--syntax-propertize-multiline-string end)))))
+   (point) end))
+
+(defvar reason-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map "\C-c\C-a" #'reason-mode-find-alternate-file)
+    (define-key map "\C-c\C-r" #'refmt-region-ocaml-to-reason)
+    (define-key map "\C-c\C-o" #'refmt-region-reason-to-ocaml)
+    map))
+
+;;;###autoload
+(define-derived-mode reason-mode prog-mode "Reason"
+  "Major mode for Reason code.
+
+\\{reason-mode-map}"
+  :group 'reason
+  :syntax-table reason-mode-syntax-table
+  :keymap reason-mode-map
+
+  ;; Syntax
+  (setq-local syntax-propertize-function #'reason-syntax-propertize-function)
+  ;; Indentation
+  (setq-local indent-line-function 'reason-mode-indent-line)
+  ;; Fonts
+  (setq-local font-lock-defaults '(reason-font-lock-keywords))
+  ;; Misc
+  (setq-local comment-start "/*")
+  (setq-local comment-end   "*/")
+  (setq-local indent-tabs-mode nil)
+  ;; Allow paragraph fills for comments
+  (setq-local comment-start-skip "/\\*+[ \t]*")
+  (setq-local paragraph-start
+              (concat "^[ \t]*$\\|\\*)$\\|" page-delimiter))
+  (setq-local paragraph-separate paragraph-start)
+  (setq-local require-final-newline t)
+  (setq-local normal-auto-fill-function nil)
+  (setq-local comment-multi-line t)
+
+  (setq-local beginning-of-defun-function 'reason-beginning-of-defun)
+  (setq-local end-of-defun-function 'reason-end-of-defun)
+  (setq-local parse-sexp-lookup-properties t))
+
+;;;###autoload
+(add-to-list 'auto-mode-alist '("\\.rei?\\'" . reason-mode))
+
+(defun reason-mode-reload ()
+  "Reload Reason mode."
+  (interactive)
+  (unload-feature 'reason-mode)
+  (unload-feature 'reason-indent)
+  (unload-feature 'reason-interaction)
+  (require 'reason-mode)
+  (reason-mode))
+
+(provide 'reason-mode)
+
+;;; reason-mode.el ends here
diff --git a/configs/shared/emacs/.emacs.d/vendor/refmt.el b/configs/shared/emacs/.emacs.d/vendor/refmt.el
new file mode 100644
index 0000000000..b9ea2b43f0
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/vendor/refmt.el
@@ -0,0 +1,231 @@
+;;; refmt.el --- utility functions to format reason code
+
+;; Copyright (c) 2014 The go-mode Authors. All rights reserved.
+;; Portions Copyright (c) 2015-present, Facebook, Inc. All rights reserved.
+
+;; Redistribution and use in source and binary forms, with or without
+;; modification, are permitted provided that the following conditions are
+;; met:
+
+;; * Redistributions of source code must retain the above copyright
+;; notice, this list of conditions and the following disclaimer.
+;; * Redistributions in binary form must reproduce the above
+;; copyright notice, this list of conditions and the following disclaimer
+;; in the documentation and/or other materials provided with the
+;; distribution.
+;; * Neither the name of the copyright holder nor the names of its
+;; contributors may be used to endorse or promote products derived from
+;; this software without specific prior written permission.
+
+;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+;; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+;; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+;; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+;; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+;; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+;; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+;; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+;; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+;; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+;; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.)
+
+;;; Commentary:
+;;
+
+;;; Code:
+
+(require 'cl-lib)
+
+(defcustom refmt-command "refmt"
+  "The 'refmt' command."
+  :type 'string
+  :group 're-fmt)
+
+(defcustom refmt-show-errors 'buffer
+    "Where to display refmt error output.
+It can either be displayed in its own buffer, in the echo area, or not at all.
+Please note that Emacs outputs to the echo area when writing
+files and will overwrite refmt's echo output if used from inside
+a `before-save-hook'."
+    :type '(choice
+            (const :tag "Own buffer" buffer)
+            (const :tag "Echo area" echo)
+            (const :tag "None" nil))
+      :group 're-fmt)
+
+(defcustom refmt-width-mode nil
+  "Specify width when formatting buffer contents."
+  :type '(choice
+          (const :tag "Window width" window)
+          (const :tag "Fill column" fill)
+          (const :tag "None" nil))
+  :group 're-fmt)
+
+;;;###autoload
+(defun refmt-before-save ()
+  "Add this to .emacs to run refmt on the current buffer when saving:
+ (add-hook 'before-save-hook 'refmt-before-save)."
+    (interactive)
+      (when (eq major-mode 'reason-mode) (refmt)))
+
+(defun reason--goto-line (line)
+  (goto-char (point-min))
+    (forward-line (1- line)))
+
+(defun reason--delete-whole-line (&optional arg)
+    "Delete the current line without putting it in the `kill-ring'.
+Derived from function `kill-whole-line'.  ARG is defined as for that
+function."
+    (setq arg (or arg 1))
+    (if (and (> arg 0)
+             (eobp)
+             (save-excursion (forward-visible-line 0) (eobp)))
+        (signal 'end-of-buffer nil))
+    (if (and (< arg 0)
+             (bobp)
+             (save-excursion (end-of-visible-line) (bobp)))
+        (signal 'beginning-of-buffer nil))
+    (cond ((zerop arg)
+           (delete-region (progn (forward-visible-line 0) (point))
+                          (progn (end-of-visible-line) (point))))
+          ((< arg 0)
+           (delete-region (progn (end-of-visible-line) (point))
+                          (progn (forward-visible-line (1+ arg))
+                                 (unless (bobp)
+                                   (backward-char))
+                                 (point))))
+          (t
+           (delete-region (progn (forward-visible-line 0) (point))
+                                                  (progn (forward-visible-line arg) (point))))))
+
+(defun reason--apply-rcs-patch (patch-buffer &optional start-pos)
+  "Apply an RCS-formatted diff from PATCH-BUFFER to the current buffer."
+  (setq start-pos (or start-pos (point-min)))
+  (let ((first-line (line-number-at-pos start-pos))
+        (target-buffer (current-buffer))
+        ;; Relative offset between buffer line numbers and line numbers
+        ;; in patch.
+        ;;
+        ;; Line numbers in the patch are based on the source file, so
+        ;; we have to keep an offset when making changes to the
+        ;; buffer.
+        ;;
+        ;; Appending lines decrements the offset (possibly making it
+        ;; negative), deleting lines increments it. This order
+        ;; simplifies the forward-line invocations.
+        (line-offset 0))
+    (save-excursion
+      (with-current-buffer patch-buffer
+        (goto-char (point-min))
+        (while (not (eobp))
+          (unless (looking-at "^\\([ad]\\)\\([0-9]+\\) \\([0-9]+\\)")
+            (error "invalid rcs patch or internal error in reason--apply-rcs-patch"))
+          (forward-line)
+          (let ((action (match-string 1))
+                (from (string-to-number (match-string 2)))
+                (len  (string-to-number (match-string 3))))
+            (cond
+             ((equal action "a")
+              (let ((start (point)))
+                (forward-line len)
+                (let ((text (buffer-substring start (point))))
+                  (with-current-buffer target-buffer
+                    (cl-decf line-offset len)
+                    (goto-char start-pos)
+                    (forward-line (- from len line-offset))
+                    (insert text)))))
+             ((equal action "d")
+              (with-current-buffer target-buffer
+                (reason--goto-line (- (1- (+ first-line from)) line-offset))
+                (cl-incf line-offset len)
+                (reason--delete-whole-line len)))
+             (t
+              (error "invalid rcs patch or internal error in reason--apply-rcs-patch")))))))))
+
+(defun refmt--process-errors (filename tmpfile errorfile errbuf)
+  (with-current-buffer errbuf
+    (if (eq refmt-show-errors 'echo)
+        (progn
+          (message "%s" (buffer-string))
+          (refmt--kill-error-buffer errbuf))
+      (insert-file-contents errorfile nil nil nil)
+      ;; Convert the refmt stderr to something understood by the compilation mode.
+      (goto-char (point-min))
+      (insert "refmt errors:\n")
+      (while (search-forward-regexp (regexp-quote tmpfile) nil t)
+        (replace-match (file-name-nondirectory filename)))
+      (compilation-mode)
+      (display-buffer errbuf))))
+
+(defun refmt--kill-error-buffer (errbuf)
+  (let ((win (get-buffer-window errbuf)))
+    (if win
+        (quit-window t win)
+      (with-current-buffer errbuf
+        (erase-buffer))
+      (kill-buffer errbuf))))
+
+(defun apply-refmt (&optional start end from to)
+  (setq start (or start (point-min))
+        end (or end (point-max))
+        from (or from "re")
+        to (or to "re"))
+   (let* ((ext (file-name-extension buffer-file-name t))
+          (bufferfile (make-temp-file "refmt" nil ext))
+          (outputfile (make-temp-file "refmt" nil ext))
+          (errorfile (make-temp-file "refmt" nil ext))
+          (errbuf (if refmt-show-errors (get-buffer-create "*Refmt Errors*")))
+          (patchbuf (get-buffer-create "*Refmt patch*"))
+          (coding-system-for-read 'utf-8)
+          (coding-system-for-write 'utf-8)
+          (width-args
+           (cond
+            ((equal refmt-width-mode 'window)
+             (list "--print-width" (number-to-string (window-body-width))))
+            ((equal refmt-width-mode 'fill)
+             (list "--print-width" (number-to-string fill-column)))
+            (t
+             '()))))
+     (unwind-protect
+         (save-restriction
+           (widen)
+           (write-region start end bufferfile)
+           (if errbuf
+               (with-current-buffer errbuf
+                 (setq buffer-read-only nil)
+                 (erase-buffer)))
+           (with-current-buffer patchbuf
+             (erase-buffer))
+           (if (zerop (apply 'call-process
+                             refmt-command nil (list (list :file outputfile) errorfile)
+                             nil (append width-args (list "--parse" from "--print" to bufferfile))))
+               (progn
+                 (call-process-region start end "diff" nil patchbuf nil "-n" "-"
+                                      outputfile)
+                 (reason--apply-rcs-patch patchbuf start)
+                 (message "Applied refmt")
+                 (if errbuf (refmt--kill-error-buffer errbuf)))
+             (message "Could not apply refmt")
+             (if errbuf
+                 (refmt--process-errors (buffer-file-name) bufferfile errorfile errbuf)))))
+     (kill-buffer patchbuf)
+     (delete-file errorfile)
+     (delete-file bufferfile)
+     (delete-file outputfile)))
+
+(defun refmt ()
+  "Format the current buffer according to the refmt tool."
+  (interactive)
+  (apply-refmt))
+
+(defun refmt-region-ocaml-to-reason (start end)
+  (interactive "r")
+  (apply-refmt start end "ml"))
+
+(defun refmt-region-reason-to-ocaml (start end)
+  (interactive "r")
+  (apply-refmt start end "re" "ml"))
+
+(provide 'refmt)
+
+;;; refmt.el ends here
diff --git a/configs/shared/emacs/.emacs.d/vendor/slack-snippets.el b/configs/shared/emacs/.emacs.d/vendor/slack-snippets.el
new file mode 100644
index 0000000000..6bf933cfb8
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/vendor/slack-snippets.el
@@ -0,0 +1,228 @@
+;;; private/grfn/slack-snippets.el -*- lexical-binding: t; -*-
+
+(require 's)
+(require 'json)
+(require 'dash)
+(require 'dash-functional)
+(require 'request)
+(require 'subr-x)
+
+;;;
+;;; Configuration
+;;;
+
+(defvar slack/token nil
+  "Legacy (https://api.slack.com/custom-integrations/legacy-tokens) access token")
+
+(defvar slack/include-public-channels 't
+  "Whether or not to inclue public channels in the list of conversations")
+
+(defvar slack/include-private-channels 't
+  "Whether or not to inclue public channels in the list of conversations")
+
+(defvar slack/include-im 't
+  "Whether or not to inclue IMs (private messages) in the list of conversations")
+
+(defvar slack/include-mpim nil
+  "Whether or not to inclue multi-person IMs (multi-person private messages) in
+  the list of conversations")
+
+;;;
+;;; Utilities
+;;;
+
+(defmacro comment (&rest _body)
+  "Comment out one or more s-expressions"
+  nil)
+
+(defun ->list (vec) (append vec nil))
+
+(defun json-truthy? (x) (and x (not (equal :json-false x))))
+
+;;;
+;;; Generic API integration
+;;;
+
+(defvar slack/base-url "https://slack.com/api")
+
+(defun slack/get (path params &optional callback)
+  "params is an alist of query parameters"
+  (let* ((params-callback (if (functionp params) `(() . ,params) (cons params callback)))
+         (params (car params-callback)) (callback (cdr params-callback))
+         (params (append `(("token" . ,slack/token)) params))
+         (url (concat (file-name-as-directory slack/base-url) path)))
+    (request url
+             :type "GET"
+             :params params
+             :parser 'json-read
+             :success (cl-function
+                       (lambda (&key data &allow-other-keys)
+                         (funcall callback data))))))
+
+(defun slack/post (path params &optional callback)
+  (let* ((params-callback (if (functionp params) `(() . ,params) (cons params callback)))
+         (params (car params-callback)) (callback (cdr params-callback))
+         (url (concat (file-name-as-directory slack/base-url) path)))
+    (request url
+             :type "POST"
+             :data (json-encode params)
+             :headers `(("Content-Type"  . "application/json")
+                        ("Authorization" . ,(format "Bearer %s" slack/token)))
+             :success (cl-function
+                       (lambda (&key data &allow-other-keys)
+                         (funcall callback data))))))
+
+
+;;;
+;;; Specific API endpoints
+;;;
+
+;; Users
+
+(defun slack/users (cb)
+  "Returns users as (id . name) pairs"
+  (slack/get
+   "users.list"
+   (lambda (data)
+     (->> data
+          (assoc-default 'members)
+          ->list
+          (-map (lambda (user)
+                  (cons (assoc-default 'id user)
+                        (assoc-default 'real_name user))))
+          (-filter #'cdr)
+          (funcall cb)))))
+
+(comment
+ (slack/get
+  "users.list"
+  (lambda (data) (setq response-data data)))
+
+ (slack/users (lambda (data) (setq --users data)))
+
+ )
+
+;; Conversations
+
+(defun slack/conversation-types ()
+  (->>
+   (list (when slack/include-public-channels  "public_channel")
+         (when slack/include-private-channels "private_channel")
+         (when slack/include-im               "im")
+         (when slack/include-mpim             "mpim"))
+   (-filter #'identity)
+   (s-join ",")))
+
+(defun channel-label (chan users-alist)
+  (cond
+   ((json-truthy? (assoc-default 'is_channel chan))
+    (format "#%s" (assoc-default 'name chan)))
+   ((json-truthy? (assoc-default 'is_im chan))
+    (let ((user-id (assoc-default 'user chan)))
+      (format "Private message with %s" (assoc-default user-id users-alist))))
+   ((json-truthy? (assoc-default 'is_mpim chan))
+    (->> chan
+         (assoc-default 'purpose)
+         (assoc-default 'value)))))
+
+(defun slack/conversations (cb)
+  "Calls `cb' with (id . '((label . \"label\") '(topic . \"topic\") '(purpose . \"purpose\"))) pairs"
+  (slack/get
+   "conversations.list"
+   `(("types"            . ,(slack/conversation-types))
+     ("exclude-archived" . "true"))
+   (lambda (data)
+     (setq --data data)
+     (slack/users
+      (lambda (users)
+        (->> data
+             (assoc-default 'channels)
+             ->list
+             (-filter
+              (lambda (chan) (channel-label chan users)))
+             (-map
+              (lambda (chan)
+                (cons (assoc-default 'id chan)
+                      `((label   . ,(channel-label chan users))
+                        (topic   . ,(->> chan
+                                         (assoc-default 'topic)
+                                         (assoc-default 'value)))
+                        (purpose . ,(->> chan
+                                         (assoc-default 'purpose)
+                                         (assoc-default 'value)))))))
+             (funcall cb)))))))
+
+(comment
+ (slack/get
+  "conversations.list"
+  '(("types" . "public_channel,private_channel,im,mpim"))
+  (lambda (data) (setq response-data data)))
+
+ (slack/get
+  "conversations.list"
+  '(("types" . "im"))
+  (lambda (data) (setq response-data data)))
+
+ (slack/conversations
+  (lambda (convos) (setq --conversations convos)))
+
+ )
+
+;; Messages
+
+(cl-defun slack/post-message
+    (&key text channel-id (on-success #'identity))
+  (slack/post "chat.postMessage"
+              `((text    . ,text)
+                (channel . ,channel-id)
+                (as_user . t))
+              on-success))
+
+(comment
+
+ (slack/post-message
+  :text "hi slackbot"
+  :channel-id slackbot-channel-id
+  :on-success (lambda (data) (setq resp data)))
+
+ (-map (lambda (chan) (let ((label (assoc-default 'label (cdr chan)))
+                            (id (car chan)))
+                        (propertize label 'channel-id id)))
+            --conversations)
+
+ )
+
+;;;
+;;; Posting code snippets to slack
+;;;
+
+(defun prompt-for-channel (cb)
+  (slack/conversations
+   (lambda (conversations)
+     (setq testing (-map (lambda (chan) (let ((label (assoc-default 'label (cdr chan)))
+                            (id (car chan)))
+                        (propertize label 'channel-id id)))
+            conversations))
+     (ivy-read
+      "Select channel: "
+      ;; TODO want to potentially use purpose / topic stuff here
+      (-map (lambda (chan) (let ((label (assoc-default 'label (cdr chan)))
+                            (id (car chan)))
+                        (propertize label 'channel-id id)))
+            conversations)
+      :history 'slack/channel-history
+      :action (lambda (selected)
+                (let ((channel-id (get-text-property 0 'channel-id selected)))
+                  (funcall cb channel-id)
+                  (message "Sent message to %s" selected))))))
+  nil)
+
+(defun slack-send-code-snippet (&optional snippet-text)
+  (interactive)
+  (when-let ((snippet-text (or snippet-text
+                               (buffer-substring-no-properties (mark) (point)))))
+    (prompt-for-channel
+     (lambda (channel-id)
+       (slack/post-message
+        :text       (format "```\n%s```" snippet-text)
+        :channel-id channel-id)))))
diff --git a/configs/shared/emacs/.emacs.d/wpc/casing.el b/configs/shared/emacs/.emacs.d/wpc/casing.el
new file mode 100644
index 0000000000..598833a9f6
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/wpc/casing.el
@@ -0,0 +1,49 @@
+;; casing.el --- Helper functions for formatting text -*- lexical-binding: t -*-
+;; Author: William Carroll <wpcarro@gmail.com>
+
+;;; Commentary:
+;; These functions are intended to be bound to KBDs for daily use and
+;; refactoring.
+
+;;; Code:
+
+(require 's)
+(require 'dash)
+
+;; todo - grab the string at point and replace it with the output of
+;; each fn
+
+(defun caps->kebab (x)
+  "Change the casing of X from CAP_CASE to kebab-case."
+  (->> x
+       s-downcase
+       (s-replace "_" "-")))
+
+(defun kebab->caps (x)
+  "Change the casing of X from CAP_CASE to kebab-case."
+  (->> x
+       s-upcase
+       (s-replace "-" "_")))
+
+(defun lower->caps (x)
+  "Change the casing of X from lowercase to CAPS_CASE."
+  (->> x
+       s-upcase
+       (s-replace " " "_")))
+
+(defun lower->kebab (x)
+  "Change the casing of X from lowercase to kebab-case"
+  (s-replace " " "-" x))
+
+;;; Tests:
+
+(ert-deftest caps->kebab-test ()
+  (should (string= (caps->kebab "CAPS_CASE_STRING")
+                   "caps-case-string")))
+
+(ert-deftest kebab->caps-test ()
+  (should (string= (kebab->caps "kebab-case-string")
+                   "KEBAB_CASE_STRING")))
+
+(provide 'casing)
+;;; casing.el ends here
diff --git a/configs/shared/emacs/.emacs.d/wpc/fs-functions.el b/configs/shared/emacs/.emacs.d/wpc/fs-functions.el
new file mode 100644
index 0000000000..1ceacfaed2
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/wpc/fs-functions.el
@@ -0,0 +1,28 @@
+;;; fs-functions.el --- Functions to make working with the filesystem easier. -*- lexical-binding: t -*-
+;; Author: William Carroll <wpcarro@gmail.com>
+
+;;; Commentary:
+;; Hosts ergonomic functions for working with a filesystem.
+
+;;; Code:
+
+(require 'dash)
+(require 'f)
+
+(defun ensure-file-path (path)
+  "Ensure that a file and its directories in PATH exist.
+Will error for inputs with a trailing slash."
+  (when (s-ends-with? "/" path)
+    (error (format "Input path has trailing slash: %s" path)))
+  (let ((dirs (->> path f-dirname f-split)))
+    (apply #'f-mkdir dirs)
+    (f-touch path)))
+
+(defun ensure-dir-path (path)
+  "Ensures that a directory and its ancestor directories in PATH exist."
+  (->> path
+       f-split
+       (apply #'f-mkdir)))
+
+(provide 'fs-functions)
+;;; fs-functions.el ends here
diff --git a/configs/shared/emacs/.emacs.d/wpc/functions.el b/configs/shared/emacs/.emacs.d/wpc/functions.el
new file mode 100644
index 0000000000..d9c4a79605
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/wpc/functions.el
@@ -0,0 +1,222 @@
+;; 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/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)))
+
+(defun buffer-dirname ()
+  "Return the directory name of the current buffer as a string."
+  (->> buffer-file-name
+       f-dirname
+       f-filename))
+
+(provide 'functions)
+;;; functions.el ends here
diff --git a/configs/shared/emacs/.emacs.d/wpc/macros.el b/configs/shared/emacs/.emacs.d/wpc/macros.el
new file mode 100644
index 0000000000..aedd6f5b3c
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/wpc/macros.el
@@ -0,0 +1,33 @@
+;;; macros.el --- Helpful variables for making my ELisp life more enjoyable -*- lexical-binding: t -*-
+;; Authpr: William Carroll <wpcarro@gmail.com>
+
+;;; Commentary:
+;; This file contains helpful variables that I use in my ELisp development.
+
+;;; Code:
+
+(require 'dash)
+(require 's)
+(require 'string-functions)
+
+(defmacro xi (&rest FORMS)
+  `(lambda ,(--filter (s-contains? (symbol-name it)
+                                   (prin1-to-string FORMS))
+                      '(x1 x2 x3 x4 x5))
+     ,FORMS))
+
+(defmacro enable (mode)
+  "Helper for enabling MODE. Useful in `add-hook' calls."
+  `#'(lambda nil (,mode 1)))
+
+(defmacro disable (mode)
+  "Helper for disabling MODE. Useful in `add-hook' calls."
+  `#'(lambda nil (,mode -1)))
+
+(defmacro add-hooks (modes)
+  "Add multiple MODES for the CALLBACK."
+  `(dolist (mode ,modes)
+     (add-hook (symbol/ensure-hookified mode) ,callback)))
+
+(provide 'macros)
+;;; macros.el ends here
diff --git a/configs/shared/emacs/.emacs.d/wpc/packages/wpc-clojure.el b/configs/shared/emacs/.emacs.d/wpc/packages/wpc-clojure.el
new file mode 100644
index 0000000000..611e9bf5ef
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/wpc/packages/wpc-clojure.el
@@ -0,0 +1,61 @@
+;;; clojure.el --- My Clojure preferences -*- lexical-binding: t -*-
+;; Author: William Carroll <wpcarro@gmail.com>
+
+;;; Commentary:
+;; Hosting my Clojure tooling preferences
+
+;;; Code:
+
+;; Helper functions
+(defun wpc/buffer-name-for-clojure-mode (mode)
+  (let* ((project-name (projectile-project-name))
+         (cljs-name (concat "*cider-repl CLJS " project-name "*"))
+         (clj-name  (concat "*cider-repl " project-name "*")))
+    (cond ((eq mode 'clojurescript-mode) cljs-name)
+          ((eq mode 'clojure-mode) clj-name)
+          ((eq mode 'clojurec-mode) cljs-name))))
+
+(defun wpc/repl-function-for-clojure-mode (mode)
+  (let ((project-name (projectile-project-name))
+        (cljs-fn #'cider-jack-in-clojurescript)
+        (clj-fn  #'cider-jack-in))
+    (cond ((eq mode 'clojurescript-mode) cljs-fn)
+          ((eq mode 'clojure-mode) clj-fn)
+          ((eq mode 'clojurec-mode) cljs-fn))))
+
+(defun wpc/find-or-create-clojure-or-clojurescript-repl ()
+  (interactive)
+  (with-current-buffer (current-buffer)
+    (let ((buffer-name   (wpc/buffer-name-for-clojure-mode major-mode))
+          (repl-function (wpc/repl-function-for-clojure-mode major-mode)))
+      (if (get-buffer buffer-name)
+          (switch-to-buffer buffer-name)
+        (funcall repl-function)))))
+
+;; (defun wpc/evil-leader/set-key-for-clojure-modes (kbd callback)
+;;   (evil-leader/set-key-for-mode 'clojure-mode kbd callback)
+;;   (evil-leader/set-key-for-mode 'clojurec-mode kbd callback)
+;;   (evil-leader/set-key-for-mode 'clojurescript-mode kbd callback))
+
+;; ;; clojure
+;; (wpc/evil-leader/set-key-for-clojure-modes "d" #'cider-doc)
+;; (wpc/evil-leader/set-key-for-clojure-modes "e" #'cider-eval-defun-at-point)
+;; (wpc/evil-leader/set-key-for-clojure-modes "r" #'wpc/find-or-create-clojure-or-clojurescript-repl)
+
+(use-package cider
+  :general
+  (cider-repl-mode-map
+   "C-l"    'cider-repl-clear-buffer
+   "C-u"    'kill-whole-line
+   "<up>"   'cider-repl-previous-input
+   "<down>" 'cider-repl-next-input
+   "C-c 'j" 'wpc/find-or-create-clojure-or-clojurescript-repl)
+  :config
+  (setq cider-cljs-lein-repl
+        "(do (require 'figwheel-sidecar.repl-api)
+             (figwheel-sidecar.repl-api/start-figwheel!)
+             (figwheel-sidecar.repl-api/cljs-repl))"
+        cider-prompt-for-symbol nil))
+
+(provide 'wpc-clojure)
+;;; wpc-clojure.el ends here
diff --git a/configs/shared/emacs/.emacs.d/wpc/packages/wpc-company.el b/configs/shared/emacs/.emacs.d/wpc/packages/wpc-company.el
new file mode 100644
index 0000000000..ec96bdf90b
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/wpc/packages/wpc-company.el
@@ -0,0 +1,24 @@
+;;; company.el --- Autocompletion package, company, preferences -*- lexical-binding: t -*-
+;; Author: William Carroll <wpcarro@gmail.com>
+
+;;; Commentary:
+;; Hosts my company mode preferences
+
+;;; Code:
+
+;; autocompletion client
+(use-package company
+  :general
+  (company-active-map
+   "C-j" 'company-select-next
+   "C-n" 'company-select-next
+   "C-k" 'company-select-previous
+   "C-p" 'company-select-previous
+   "C-d" 'company-show-doc-buffer)
+  :config
+  (setq company-idle-delay 0)
+  (setq company-minimum-prefix-length 2)
+  (global-company-mode))
+
+(provide 'wpc-company)
+;;; company.el ends here
diff --git a/configs/shared/emacs/.emacs.d/wpc/packages/wpc-dired.el b/configs/shared/emacs/.emacs.d/wpc/packages/wpc-dired.el
new file mode 100644
index 0000000000..1c45ec35e2
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/wpc/packages/wpc-dired.el
@@ -0,0 +1,18 @@
+;;; dired.el --- My dired preferences -*- lexical-binding: t -*-
+;; Author: William Carroll <wpcarro@gmail.com>
+
+;;; Commentary:
+;; Hosts my attempts at configuring dired
+
+;;; Code:
+
+(require 'dired)
+(general-def 'dired-mode-map
+    "c" 'find-file
+    "f" 'wpc/find-file
+    "-" 'dired-up-directory)
+(general-add-hook 'dired-mode-hook (list (enable dired-hide-details-mode)
+                                         #'auto-revert-mode))
+
+(provide 'wpc-dired)
+;;; dired.el ends here
diff --git a/configs/shared/emacs/.emacs.d/wpc/packages/wpc-docker.el b/configs/shared/emacs/.emacs.d/wpc/packages/wpc-docker.el
new file mode 100644
index 0000000000..586878fdea
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/wpc/packages/wpc-docker.el
@@ -0,0 +1,18 @@
+;;; docker.el --- Docker preferences -*- lexical-binding: t -*-
+;; Author: William Carroll <wpcarro@gmail.com>
+
+;;; Commentary:
+;; My Docker preferences and configuration
+
+;;; Code:
+
+(use-package docker
+  :config
+  (setenv "DOCKER_TLS_VERIFY" "1")
+  (setenv "DOCKER_HOST" "tcp://10.11.12.13:2376")
+  (setenv "DOCKER_MACHINE_NAME" "name"))
+
+(use-package dockerfile-mode)
+
+(provide 'wpc-docker)
+;;; docker.el ends here
diff --git a/configs/shared/emacs/.emacs.d/wpc/packages/wpc-flycheck.el b/configs/shared/emacs/.emacs.d/wpc/packages/wpc-flycheck.el
new file mode 100644
index 0000000000..66314af987
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/wpc/packages/wpc-flycheck.el
@@ -0,0 +1,14 @@
+;;; flycheck.el --- My flycheck configuration -*- lexical-binding: t -*-
+;; Author: William Carroll <wpcarro@gmail.com>
+
+;;; Commentary:
+;; Hosts my Flycheck preferences
+
+;;; Code:
+
+(use-package flycheck
+  :config
+  (global-flycheck-mode))
+
+(provide 'wpc-flycheck)
+;;; flycheck.el ends here
diff --git a/configs/shared/emacs/.emacs.d/wpc/packages/wpc-git.el b/configs/shared/emacs/.emacs.d/wpc/packages/wpc-git.el
new file mode 100644
index 0000000000..80dbedf786
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/wpc/packages/wpc-git.el
@@ -0,0 +1,14 @@
+;;; git.el --- My version control preferences -*- lexical-binding: t -*-
+;; Author: William Carroll <wpcarro@gmail.com>
+
+;;; Commentary:
+;; Things related to git, magit, etc belong here
+
+;;; Code:
+
+(use-package git-timemachine)
+
+(use-package magit)
+
+(provide 'wpc-git)
+;;; git.el ends here
diff --git a/configs/shared/emacs/.emacs.d/wpc/packages/wpc-graphql.el b/configs/shared/emacs/.emacs.d/wpc/packages/wpc-graphql.el
new file mode 100644
index 0000000000..ea19e130ce
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/wpc/packages/wpc-graphql.el
@@ -0,0 +1,17 @@
+;;; wpc-graphql.el --- Packages related to GraphQL -*- lexical-binding: t -*-
+;; Author: William Carroll <wpcarro@gmail.com>
+
+;;; Commentary:
+;; Hosts various packages and functions to make working with GraphQL more
+;; enjoyable.
+
+;;; Code:
+
+(quelpa '(graphql.el
+          :fetcher github
+          :repo "vermiculus/graphql.el"))
+(require 'graphql.el)
+
+
+(provide 'wpc-graphql)
+;;; wpc-graphql.el ends here
diff --git a/configs/shared/emacs/.emacs.d/wpc/packages/wpc-haskell.el b/configs/shared/emacs/.emacs.d/wpc/packages/wpc-haskell.el
new file mode 100644
index 0000000000..8e5dccfeaa
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/wpc/packages/wpc-haskell.el
@@ -0,0 +1,56 @@
+;;; haskell.el --- My Haskell preferences -*- lexical-binding: t -*-
+;; Author: William Carroll <wpcarro@gmail.com>
+
+;;; 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-hook #'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 empire/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 empire/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 empire/haskell/test<->module ()
+  "Toggle between test and module in Haskell."
+  (interactive)
+  (if (s-contains? "/src/" buffer-file-name)
+      (empire/haskell/module->test)
+    (empire/haskell/test->module)))
+
+(provide 'wpc-haskell)
+;;; wpc-haskell.el ends here
diff --git a/configs/shared/emacs/.emacs.d/wpc/packages/wpc-javascript.el b/configs/shared/emacs/.emacs.d/wpc/packages/wpc-javascript.el
new file mode 100644
index 0000000000..717f1d9f9a
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/wpc/packages/wpc-javascript.el
@@ -0,0 +1,95 @@
+;;; wpc-javascript.el --- My Javascript preferences -*- lexical-binding: t -*-
+;; Author: William Carroll <wpcarro@gmail.com>
+
+;;; Commentary:
+;; This module hosts my Javascript tooling preferences
+
+;;; 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.")
+
+
+;; Helper functions
+(defun wpc/insert-flow-annotation ()
+  "Insert a flow type annotation to the beginning of a buffer."
+  (interactive)
+  (save-excursion
+    (goto-char (point-min))
+    (insert "// @flow\n")))
+
+;; 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)
+
+;; javascript text objects
+(quelpa '(evil-text-objects-javascript
+          :fetcher github
+          :repo "urbint/evil-text-objects-javascript"))
+(require 'evil-text-objects-javascript)
+
+;; Flow for Javascript
+(use-package add-node-modules-path
+  :config
+  (general-add-hook wpc/js-hooks #'add-node-modules-path))
+
+(use-package flow-minor-mode
+  :general
+  (n "gd" 'flow-minor-jump-to-definition)
+  :requires evil-leader
+  :config
+  (general-add-hook wpc/js-hooks #'flow-minor-mode)
+  (evil-leader/set-key-for-mode 'rjsx-mode "F" #'wpc/insert-flow-annotation))
+
+;; Shouldn't need this once LSP is setup properly
+;; (use-package company-flow
+;;   :after (company)
+;;   :config
+;;   (add-to-list 'company-flow-modes 'rjsx-mode)
+;;   (add-to-list 'company-backends 'company-flow))
+
+;; Shouldn't need this once LSP is setup properly
+;; (use-package flycheck-flow
+;;   :after (flycheck)
+;;   :config
+;;   (flycheck-add-mode 'javascript-flow 'rjsx-mode)
+;;   (flycheck-add-mode 'javascript-flow 'flow-minor-mode)
+;;   (flycheck-add-mode 'javascript-eslint 'flow-minor-mode)
+;;   (flycheck-add-next-checker 'javascript-flow 'javascript-eslint))
+
+;; JSX highlighting
+(use-package rjsx-mode
+  :after (evil-text-objects-javascript)
+  :general
+  (general-unbind rjsx-mode-map "<" ">" "C-d")
+  (n rjsx-mode-map
+     "K" 'flow-minor-type-at-pos)
+  :mode "\\.js\\'"
+  :config
+  (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))
+
+;; LSP support
+(use-package lsp-javascript-flow
+  :config
+  (general-add-hook wpc/js-hooks #'lsp-javascript-flow-enable))
+
+(provide 'wpc-javascript)
+;;; wpc-javascript.el ends here
diff --git a/configs/shared/emacs/.emacs.d/wpc/packages/wpc-keybindings.el b/configs/shared/emacs/.emacs.d/wpc/packages/wpc-keybindings.el
new file mode 100644
index 0000000000..a20a803a43
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/wpc/packages/wpc-keybindings.el
@@ -0,0 +1,134 @@
+;;; keybindings.el --- My Evil preferences -*- lexical-binding: t -*-
+;; Author: William Carroll <wpcarro@gmail.com>
+
+;;; Commentary:
+;; This module hosts my Evil preferences
+
+;;; Code:
+
+(quelpa
+ '(general
+   :repo "noctuid/general.el"
+   :fetcher github))
+(general-evil-setup t)
+
+;; vim...
+(use-package evil
+  :general
+  (m
+   "RET" 'evil-goto-line
+   "H"   'evil-first-non-blank
+   "L"   'evil-end-of-line
+   "-"   'dired-jump
+   "sl"  'wpc/evil-window-vsplit-right
+   "sh"  'evil-window-vsplit
+   "sk"  'evil-window-split
+   "sj"  'wpc/evil-window-split-down
+   "sj"  'wpc/evil-window-split-down)
+  (n
+   "gd"  'xref-find-definitions)
+  (general-unbind m "M-." "C-p")
+  (general-unbind n "s" "M-.")
+  (general-unbind i "C-d" "C-a" "C-e" "C-n" "C-p" "C-k")
+  (evil-ex-map
+   "M-p" 'previous-complete-history-element
+   "M-n" 'next-complete-history-element)
+  :init
+  (setq evil-want-integration nil)
+  :config
+  (setq evil-symbol-word-search t)
+  (evil-mode 1))
+
+;; evil keybindings
+(use-package evil-collection
+  :after evil
+  :config
+  (evil-collection-init))
+
+;; expose a leader key
+(use-package evil-leader
+  :after (evil counsel)
+  :config
+  (global-evil-leader-mode)
+  (evil-leader/set-leader "<SPC>")
+  ;; global
+  (evil-leader/set-key
+    "i"  #'counsel-semantic-or-imenu
+    "j"  #'jump-to-register
+    "h"  #'help
+    "a"  #'wpc/toggle-terminal
+    "p"  #'flycheck-previous-error
+    "P"  #'counsel-git-grep
+    "f"  #'wpc/find-file
+    "n"  #'flycheck-next-error
+    "N"  #'smerge-next
+    "P"  #'smerge-prev
+    "s"  #'slack-send-code-snippet
+    "S"  #'slack-select-unread-rooms
+    "b"  #'ivy-switch-buffer
+    "gs" #'magit-status
+    "es" #'wpc/create-snippet
+    "ev" #'wpc/edit-init-el
+    "B"  #'magit-blame
+    "w"  #'save-buffer
+    "x"  #'evil-save-and-close
+    "W"  #'save-all-buffers
+    "r"  #'wpc/evil-replace-under-point
+    ))
+
+;; create comments easily
+(use-package evil-commentary
+  :after (evil)
+  :config
+  (evil-commentary-mode))
+
+;; evil surround
+(use-package evil-surround
+  :after (evil)
+  :config
+  (global-evil-surround-mode 1))
+
+;; Custom minor mode that ensures that my kbds are available no matter which major
+;; or minor modes are active.
+(add-hook 'after-load-functions #'ensure-william-carroll-kbds)
+
+(defun ensure-william-carroll-kbds (_ignore)
+  "Try to ensure that my keybindings retain priority over other minor modes."
+  (unless (eq (caar minor-mode-map-alist) 'wpc/kbds-minor-mode)
+    (let ((mykbds (assq 'wpc/kbds-minor-mode minor-mode-map-alist)))
+      (assq-delete-all 'wpc/kbds-minor-mode minor-mode-map-alist)
+      (add-to-list 'minor-mode-map-alist mykbds))))
+
+(defvar wpc/kbds
+  (let ((map (make-sparse-keymap)))
+    (bind-keys :map map
+               ("M-q" . delete-window)
+               ("C-x C-;" . comment-or-uncomment-region)
+               ("C-x h" . help)
+               ("<s-return>" . toggle-frame-fullscreen)
+               ("<down-mouse-1>" . ffap-other-window)
+               ("M-h"  . wpc/tmux-emacs-windmove-left)
+               ("M-l"  . wpc/tmux-emacs-windmove-right)
+               ("M-k"  . wpc/tmux-emacs-windmove-up)
+               ("M-j"  . wpc/tmux-emacs-windmove-down)
+               ("M--"  . split-window-below)
+               ("M-\\" . split-window-right)
+               ("M-q"  . delete-window))
+    map)
+  "William Carroll's keybindings that should have the highest precedence.")
+
+(define-minor-mode wpc/kbds-minor-mode
+  "A minor mode so that my key settings override annoying major modes."
+  :init-value t
+  :lighter " wpc/kbds"
+  :keymap wpc/kbds)
+
+;; allow jk to escape
+(use-package key-chord
+  :after (evil)
+  :config
+  (key-chord-mode 1)
+  (key-chord-define evil-insert-state-map "jk" 'evil-normal-state))
+
+(provide 'wpc-keybindings)
+;;; wpc-keybindings.el ends here
diff --git a/configs/shared/emacs/.emacs.d/wpc/packages/wpc-lisp.el b/configs/shared/emacs/.emacs.d/wpc/packages/wpc-lisp.el
new file mode 100644
index 0000000000..c15c4526c2
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/wpc/packages/wpc-lisp.el
@@ -0,0 +1,45 @@
+;;; lisp.el --- Generic LISP preferences -*- lexical-binding: t -*-
+;; Author: William Carroll <wpcarro@gmail.com>
+
+;;; Commentary:
+;; This hosts things like Paredit settings
+
+;;; Code:
+
+(defconst wpc/lisp-mode-hooks
+  '(emacs-lisp-mode-hook
+    clojure-mode-hook
+    clojurescript-mode-hook))
+
+;; Elisp
+(use-package elisp-slime-nav
+  :ghook
+  'emacs-lisp-mode
+  'ielm-mode)
+
+;; Here is some of the thinking behind some of the keybindings:
+;;
+;; slurp    s
+;; barf     S
+;; forward  )
+;; backward (
+;;
+;; Known concession: s and S eclipse Vim bindings. There is a precedent already
+;; for eclipsing the s binding for window splitting. Shift-s feel appropriate
+;; for barfing, since eclisping the b KBD feels less acceptable than eclisping
+;; the s KBD.
+
+;; paredit LISP editing
+(use-package paredit
+  :general
+  (general-unbind paredit-mode-map "C-j" "M-q")
+  (n paredit-mode-map
+     "s)" 'paredit-forward-slurp-sexp
+     "s(" 'paredit-backward-slurp-sexp
+     "S)" 'paredit-forward-barf-sexp
+     "S(" 'paredit-backward-barf-sexp
+     "gr" 'paredit-raise-sexp)
+  :ghook (wpc/lisp-mode-hooks #'enable-paredit-mode))
+
+(provide 'wpc-lisp)
+;;; lisp.el ends here
diff --git a/configs/shared/emacs/.emacs.d/wpc/packages/wpc-misc.el b/configs/shared/emacs/.emacs.d/wpc/packages/wpc-misc.el
new file mode 100644
index 0000000000..533de61f95
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/wpc/packages/wpc-misc.el
@@ -0,0 +1,168 @@
+;;; misc.el --- Hosting miscellaneous configuration -*- lexical-binding: t -*-
+;; Author: William Carroll <wpcarro@gmail.com>
+
+;;; Commentary:
+;; This is the home of any configuration that couldn't find a better home.
+
+;;; Code:
+
+;; disable custom variable entries from being written to ~/.emacs.d/init.el
+(setq custom-file "~/.emacs.d/custom.el")
+(load custom-file 'noerror)
+
+;; start emacs server so `emacsclient' can work
+(server-start)
+
+;; transparently edit compressed files
+(auto-compression-mode t)
+
+;; change emacs prompts from "yes or no" -> "y or n"
+(fset 'yes-or-no-p 'y-or-n-p)
+
+;; open photos in Emacs
+(auto-image-file-mode 1)
+
+;; disable line-wrapping
+(setq-default truncate-lines 1)
+
+;; shell file indentation
+(setq sh-basic-offset 2)
+(setq sh-indentation 2)
+
+;; create file bookmarks
+(set-register ?e '(file . "~/.emacs.d/wpc/packages"))
+(set-register ?u '(file . "~/urbint"))
+(set-register ?d '(file . "~/dotfiles"))
+(set-register ?s '(file . "~/.slate.js"))
+(set-register ?D '(file . "~/Dropbox"))
+(set-register ?o '(file . "~/Dropbox/org/"))
+(set-register ?c '(file . "~/Dropbox/org/chains.org"))
+(set-register ?b '(file . "~/Dropbox/org/backlog.org"))
+(set-register ?p `(file . ,wpc/current-project))
+
+;; 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 wpc/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
+(setq ns-use-native-fullscreen nil)
+
+;; auto-close parens, brackets, quotes
+(electric-pair-mode 1)
+
+(use-package oauth2
+  :init
+  ;; necessary to remove warnings: https://emacs.stackexchange.com/questions/37036/where-are-these-variables-defined-bytecomp-warnings
+  (defvar url-http-extra-headers ())
+  (defvar oauth--token-data ())
+  (defvar url-callback-function ())
+  (defvar url-callback-arguments ()))
+
+(use-package smex
+  :general
+  ("M-x" 'smex)
+  :ghook ('ido-setup-hook #'wpc/bind-ido-keys)
+  :config
+  (smex-initialize))
+
+(use-package flx-ido
+  :after (smex)
+  :config
+  (flx-ido-mode 1)
+  (setq ido-enable-flex-matching t
+        ido-use-faces nil))
+
+(use-package swiper
+  :general
+  ("C-s" 'swiper
+   "C-r" 'swiper))
+
+(use-package yasnippet
+  :config
+  (yas-global-mode 1))
+
+(use-package ace-window
+  :general
+  ("C-x o" 'ace-window)
+  :config
+  (setq aw-keys '(?a ?s ?d ?f ?j ?k ?k ?\;)))
+
+(use-package projectile
+  :config
+  (projectile-mode t))
+
+(use-package counsel
+  :config
+  (defun wpc/counsel-git-grep ()
+    (interactive)
+    (let ((maybe-symbol (wpc/string-symbol-at-point)))
+      (if (string= maybe-symbol "nil")
+          (counsel-git-grep)
+        (counsel-git-grep nil maybe-symbol)))))
+
+;; projectile intergration with ivy
+(use-package counsel-projectile)
+
+;; search Google, Stackoverflow from within Emacs
+(use-package engine-mode
+  :config
+  (defengine google
+    "http://www.google.com/search?ie=utf-8&oe=utf-8&q=%s"
+    :keybinding "g")
+  (defengine stack-overflow
+    "https://stackoverflow.com/search?q=%s"
+    :keybinding "s"))
+
+(use-package markdown-mode)
+(use-package yaml-mode)
+
+;; Microsoft's Language Server Protocol (LSP)
+(use-package lsp-mode)
+(use-package lsp-ui
+  :config
+  (add-hook 'lsp-mode-hook #'lsp-ui-mode))
+(use-package company-lsp
+  :config
+  (push 'company-lsp company-backends))
+
+(provide 'wpc-misc)
+;;; wpc-misc.el ends here
diff --git a/configs/shared/emacs/.emacs.d/wpc/packages/wpc-nix.el b/configs/shared/emacs/.emacs.d/wpc/packages/wpc-nix.el
new file mode 100644
index 0000000000..af439c442d
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/wpc/packages/wpc-nix.el
@@ -0,0 +1,12 @@
+;;; wpc-nix.el --- Nix support -*- lexical-binding: t -*-
+;; Author: William Carroll <wpcarro@gmail.com>
+
+;;; 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/.emacs.d/wpc/packages/wpc-org.el b/configs/shared/emacs/.emacs.d/wpc/packages/wpc-org.el
new file mode 100644
index 0000000000..28f1f9308d
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/wpc/packages/wpc-org.el
@@ -0,0 +1,45 @@
+;;; org.el --- My org preferences -*- lexical-binding: t -*-
+;; Author: William Carroll <wpcarro@gmail.com>
+
+;;; Commentary:
+;; Hosts my org mode preferences
+
+;;; Code:
+
+;; Griffin's org clubhouse integration
+;;(load-file "~/.emacs.d/vendor/org-clubhouse.el")
+;;(setq org-clubhouse-auth-token (wpc/read-file-as-string "~/dotfiles/configs/secrets/clubhouse_token.txt")
+;;      org-clubhouse-team-name "urbint")
+;;(add-hook 'org-mode-hook #'org-clubhouse-mode)
+
+(use-package org
+  :ghook (nil (disable linum-mode))
+  :general
+  (:prefix "C-c"
+           "l" 'org-store-link
+           "a" 'org-agenda
+           "c" 'org-capture)
+  :preface
+  (defconst wpc-org-directory
+    "~/Dropbox/org")
+  (defconst ub-org-directory
+    "~/Dropbox/sprint-planning-staging")
+  (defun wpc/org-file (file)
+    (f-join wpc-org-directory (f-swap-ext file "org")))
+  (defun ub/org-file (file)
+    (f-join ub-org-directory (f-swap-ext file "org")))
+  :config
+  (setq org-default-notes-file (wpc/org-file "notes"))
+  (setq org-log-done 'time)
+  (setq org-agenda-files (list (wpc/org-file "work")
+                               (wpc/org-file "personal")))
+  (setq org-capture-templates
+        `(("t" "Todo" entry (file+heading ,(ub/org-file "index") "Ideas")
+           "* TODO %?\n  %i"))))
+
+(use-package org-bullets
+  :after (org)
+  :ghook ('org-mode-hook (enable org-bullets-mode)))
+
+(provide 'wpc-org)
+;;; org.el ends here
diff --git a/configs/shared/emacs/.emacs.d/wpc/packages/wpc-package.el b/configs/shared/emacs/.emacs.d/wpc/packages/wpc-package.el
new file mode 100644
index 0000000000..844ad83d53
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/wpc/packages/wpc-package.el
@@ -0,0 +1,32 @@
+;;; package.el --- My package configuration -*- lexical-binding: t -*-
+;; Author: William Carroll <wpcarro@gmail.com>
+
+;;; Commentary:
+;; This module hosts all of the settings required to work with ELPA,
+;; MELPA, QUELPA, and co.
+
+;;; Code:
+
+(require 'package)
+(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t)
+(add-to-list 'package-archives '("gnu" . "http://elpa.gnu.org/packages/") t)
+(package-initialize)
+
+(if (require 'quelpa nil t)
+    (quelpa-self-upgrade)
+  (with-temp-buffer
+    (url-insert-file-contents "https://raw.github.com/quelpa/quelpa/master/bootstrap.el")
+    (eval-buffer)))
+
+(require 'use-package)
+(setq use-package-always-ensure t)
+;; Remove this line once general integration with use-package calls
+;; with-eval-after-load 'use-package-core instead of 'use-package
+(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)
+;;; package.el ends here
diff --git a/configs/shared/emacs/.emacs.d/wpc/packages/wpc-slack.el b/configs/shared/emacs/.emacs.d/wpc/packages/wpc-slack.el
new file mode 100644
index 0000000000..912cd14572
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/wpc/packages/wpc-slack.el
@@ -0,0 +1,65 @@
+;;; slack.el --- Slack settings -*- lexical-binding: t -*-
+;; Author: William Carroll <wpcarro@gmail.com>
+
+;;; Commentary:
+;; Wrangling the Slack client in Emacs
+
+;;; Code:
+
+;; Griffin's Slack plugin
+;;(defconst slack/token (wpc/read-file-as-string "~/dotfiles/configs/secrets/slack_token.txt"))
+;;(defconst wpc/slack-client-secret (wpc/read-file-as-string "~/dotfiles/configs/secrets/slack-client-secret"))
+(defconst wpc/slack-client-secret "uncomment above line one day")
+(load-file "~/.emacs.d/vendor/slack-snippets.el")
+
+;; Slack client
+(use-package slack
+  :general
+  (n slack-info-mode-map
+     :prefix ","
+     "u" 'slack-room-update-messages)
+  (n slack-mode-map
+     :prefix ","
+     "c"  'slack-buffer-kill
+     "ra" 'slack-message-add-reaction
+     "rr" 'slack-message-remove-reaction
+     "rs" 'slack-message-show-reaction-users
+     "pl" 'slack-room-pins-list
+     "pa" 'slack-message-pins-add
+     "pr" 'slack-message-pins-remove
+     "mm" 'slack-message-write-another-buffer
+     "me" 'slack-message-edit
+     "md" 'slack-message-delete
+     "u"  'slack-room-update-messages
+     "2"  'slack-message-embed-mention
+     "3"  'slack-message-embed-channel)
+  (n slack-mode-map
+     "C-n" 'slack-buffer-goto-next-message
+     "C-p" 'slack-buffer-goto-prev-message)
+  (n slack-edit-message-mode-map
+     :prefix ","
+     "k" 'slack-message-cancel-edit
+     "s" 'slack-message-send-from-buffer
+     "2" 'slack-message-embed-mention
+     "3" 'slack-message-embed-channel)
+  :commands (slack-start)
+  :init
+  (setq slack-buffer-emojify t) ;; if you want to enable emoji, default nil
+  (setq slack-prefer-current-team t)
+  :config
+  (add-hook 'slack-mode-hook (disable company-mode))
+  (setq slack-buffer-function #'switch-to-buffer)
+  (slack-register-team
+   :name "urbint"
+   :default t
+   :client-id "william@urbint.com"
+   :client-secret wpc/slack-client-secret
+   :token slack-token
+   :subscribed-channels '(dev dev_questions general random recruiting)
+   :full-and-display-names t))
+
+(use-package circe)
+(use-package emojify)
+
+(provide 'wpc-slack)
+;;; wpc-slack.el ends here
diff --git a/configs/shared/emacs/.emacs.d/wpc/packages/wpc-terminal.el b/configs/shared/emacs/.emacs.d/wpc/packages/wpc-terminal.el
new file mode 100644
index 0000000000..36a24bbb3c
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/wpc/packages/wpc-terminal.el
@@ -0,0 +1,19 @@
+;;; terminal.el --- My cobbled together terminal -*- lexical-binding: t -*-
+;; Author: William Carroll <wpcarro@gmail.com>
+
+;;; Commentary:
+;; My attempts at creating a sane Emacs terminal
+
+;;; Code:
+
+(setq wpc/terminal-name "wpc/terminal")
+
+;; 256 color support in term (instead of 8)
+(use-package xterm-color)
+
+(use-package term
+  :config
+  (setq explicit-shell-file-name "/bin/zsh"))
+
+(provide 'wpc-terminal)
+;;; terminal.el ends here
diff --git a/configs/shared/emacs/.emacs.d/wpc/packages/wpc-ui.el b/configs/shared/emacs/.emacs.d/wpc/packages/wpc-ui.el
new file mode 100644
index 0000000000..87705cd6c6
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/wpc/packages/wpc-ui.el
@@ -0,0 +1,172 @@
+;;; ui.el --- Any related to the UI/UX goes here -*- lexical-binding: t -*-
+;; Author: William Carroll <wpcarro@gmail.com>
+
+;;; Commentary:
+;; Hosts font settings, scrolling, color schemes.
+
+;;; Code:
+
+;; increase line height
+(setq-default line-spacing 4)
+
+;; change font
+(add-to-list 'default-frame-alist '(font . "Operator Mono-10"))
+
+(defconst wpc/font-size-step 10
+  "The amount (%) by which to increase or decrease a font.")
+
+(defun wpc/increase-font ()
+  "Increase font size."
+  (interactive)
+  (->> (face-attribute 'default :height)
+       (+ wpc/font-size-step)
+       (set-face-attribute 'default (selected-frame) :height)))
+
+(defun wpc/decrease-font ()
+  "Decrease font size."
+  (interactive)
+  (->> (face-attribute 'default :height)
+       (+ (- wpc/font-size-step))
+       (set-face-attribute 'default (selected-frame) :height)))
+
+(general-def "s-j" #'wpc/decrease-font)
+(general-def "s-k" #'wpc/increase-font)
+
+;; smooth scrolling settings
+(setq scroll-step 1
+      scroll-conservatively 10000)
+
+;; theme mgt
+(use-package cycle-themes
+  :after (doom-themes)
+  :config
+  ;; NOTE: may want to use `defconst' here
+  (setq wpc/doom-themes
+        (->> (custom-available-themes)
+             (-map #'symbol-name)
+             (-filter (-partial #'s-starts-with? "doom-"))
+             (-map #'intern)))
+  (setq cycle-themes-theme-list wpc/doom-themes))
+
+;; clean up modeline
+(use-package diminish
+  :after (yasnippet ivy which-key)
+  :config
+  (diminish 'evil-commentary-mode)
+  (diminish 'flycheck-mode "Flycheck")
+  (diminish 'company-mode "Company")
+  (diminish 'auto-revert-mode)
+  (diminish 'which-key-mode)
+  (diminish 'yas-minor-mode)
+  (diminish 'ivy-mode))
+
+;; disable startup screen
+(setq inhibit-startup-screen t)
+
+;; disable toolbar
+(tool-bar-mode -1)
+
+;; enable line numbers
+(general-add-hook '(prog-mode-hook
+                    text-mode-hook
+                    conf-mode-hook)
+                  (enable linum-mode))
+;;(add-hook 'after-init-hook (lambda () (set-face-foreground 'linum "#da5468")))
+
+;; set default buffer for Emacs
+(setq initial-buffer-choice wpc/current-project)
+
+;; transparent Emacs
+(set-frame-parameter (selected-frame) 'alpha '(90 . 90))
+(setq frame-transparent? t)
+
+(defun wpc/toggle-transparency ()
+  "Toggle the frame transparency."
+  (interactive)
+  (set-frame-parameter (selected-frame) 'alpha '(90 . 90))
+  (let ((alpha (if frame-transparent? 100 90)))
+    (set-frame-parameter (selected-frame) 'alpha `(,alpha . ,alpha)))
+  (setq frame-transparent? (not frame-transparent?)))
+
+(general-def "s-u" #'wpc/toggle-transparency)
+
+;; premium Emacs themes
+(use-package doom-themes
+  :config
+  (setq doom-themes-enable-bold t
+        doom-themes-enable-italic t)
+  (load-theme 'doom-one-light t)
+  (doom-themes-visual-bell-config)
+  (doom-themes-org-config))
+
+;; kbd discovery
+(use-package which-key
+  :config
+  (setq which-key-idle-delay 0.25)
+  (which-key-mode))
+
+;; completion framework
+(use-package ivy
+  :config
+  (ivy-mode t))
+
+;; icons for Ivy
+(use-package all-the-icons-ivy
+  :after (ivy)
+  :config
+  (all-the-icons-ivy-setup))
+
+;; disable menubar
+(menu-bar-mode -1)
+(when (string-equal system-type "darwin")
+  (setq ns-auto-hide-menu-bar t))
+
+;; 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 wpc/fill-column)
+  (setq whitespace-style '(face lines-tail))
+  (add-hook 'prog-mode-hook #'whitespace-mode))
+
+
+
+;; disable GUI scrollbars
+(when (display-graphic-p)
+  (scroll-bar-mode -1))
+
+;; rebalance emacs windows after splits are created
+(defadvice split-window-below (after rebalance-windows activate)
+  (balance-windows))
+
+(defadvice split-window-right (after rebalance-windows activate)
+  (balance-windows))
+
+(defadvice delete-window (after rebalance-window activate)
+  (balance-windows))
+
+;; dirname/filename instead of filename<dirname>
+(setq uniquify-buffer-name-style 'forward)
+
+;; highlight matching parens, brackets, etc
+(show-paren-mode 1)
+
+;; GUI alerts in emacs
+(use-package alert
+  :commands (alert)
+  :config
+  (setq alert-default-style 'notifier))
+
+;; focus mode
+(quelpa '(zen-mode
+          :fetcher github
+          :repo "aki237/zen-mode"))
+(require 'zen-mode)
+
+;; focus mode
+(use-package writeroom-mode)
+
+(provide 'wpc-ui)
+;;; ui.el ends here
diff --git a/configs/shared/emacs/.emacs.d/wpc/string-functions.el b/configs/shared/emacs/.emacs.d/wpc/string-functions.el
new file mode 100644
index 0000000000..a7c4a39c63
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/wpc/string-functions.el
@@ -0,0 +1,51 @@
+;; functions.el --- String helper functions for my Emacs development -*- lexical-binding: t -*-
+;; Author: William Carroll <wpcarro@gmail.com>
+
+;;; Commentary:
+;; String & Symbol helpers!
+
+;;; Code:
+
+(require 'dash)
+(require 's)
+
+;; Strings
+(defun string/hookify (x)
+  "Append \"-hook\" to X."
+  (s-append "-hook" x))
+
+(defun symbol->string (symbol)
+  "Alias for `symbol-name' with SYMBOL, since I can never remember that
+function's name."
+  (symbol-name symbol))
+
+(defun string->symbol (string)
+  "Alias for `intern' for STRING since I can never remember that function's
+  name."
+  (intern string))
+
+(defun string/ensure-hookified (x)
+  "Ensure that X has \"-hook\" appended to it."
+  (if (s-ends-with? "-hook" x)
+      x
+    (string/hookify x)))
+
+;; Symbols
+(defun symbol/as-string (callback x)
+  "Treat the symbol, X, as a string while applying CALLBACK to it.
+Coerce back to a symbol on the way out."
+  (->> x
+       symbol-name
+       callback
+       intern))
+
+(defun symbol/hookify (x)
+  "Append \"-hook\" to X when X is a symbol."
+  (symbol/as-string #'string/hookify x))
+
+(defun symbol/ensure-hookified (x)
+  "Ensure that X has \"-hook\" appended to it when X is a symbol."
+  (symbol/as-string #'string/ensure-hookified x))
+
+(provide 'string-functions)
+;;; string-functions.el ends here
diff --git a/configs/shared/emacs/.emacs.d/wpc/variables.el b/configs/shared/emacs/.emacs.d/wpc/variables.el
new file mode 100644
index 0000000000..d0bba26159
--- /dev/null
+++ b/configs/shared/emacs/.emacs.d/wpc/variables.el
@@ -0,0 +1,26 @@
+;;; variables.el --- Helpful variables for making my ELisp life more enjoyable -*- lexical-binding: t -*-
+;; Authpr: William Carroll <wpcarro@gmail.com>
+
+;;; Commentary:
+;; This file contains helpful variables that I use in my ELisp development.
+
+;;; Code:
+
+(defconst wpc/current-project
+  "~/urbint/grid/"
+  "Variable holding the directory for my currently active project.")
+
+(defvar wpc/mouse-kbds
+  '([mouse-1] [down-mouse-1] [drag-mouse-1] [double-mouse-1] [triple-mouse-1]
+    [mouse-2] [down-mouse-2] [drag-mouse-2] [double-mouse-2] [triple-mouse-2]
+    [mouse-3] [down-mouse-3] [drag-mouse-3] [double-mouse-3] [triple-mouse-3]
+    [mouse-4] [down-mouse-4] [drag-mouse-4] [double-mouse-4] [triple-mouse-4]
+    [mouse-5] [down-mouse-5] [drag-mouse-5] [double-mouse-5] [triple-mouse-5])
+  "This variable stores all of the mouse-related keybindings that Emacs recognizes.")
+
+(defconst wpc/fill-column
+  80
+  "Variable used to set the defaults for wrapping, highlighting, etc.")
+
+(provide 'variables)
+;;; variables.el ends here